summaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authornobody <>2002-06-15 12:26:33 +0000
committernobody <>2002-06-15 12:26:33 +0000
commit2c830de8f260ebb1feb0b13c17eefdf12722d9f7 (patch)
tree5d09e3d1de5fadbc55de87767b0a9eed41d4636f /gdb
parent554e81cff7bca83fe562cd2c841cb7562a95b6db (diff)
downloadbinutils-gdb-2c830de8f260ebb1feb0b13c17eefdf12722d9f7.tar.gz
This commit was manufactured by cvs2svn to create branch
'kseitz_interps-20020528-branch'. Cherrypick from cagney_regbuf-20020515-branch 2002-06-15 12:26:32 UTC nobody 'This commit was manufactured by cvs2svn to create branch': .cvsignore COPYING COPYING.LIB COPYING.NEWLIB MAINTAINERS README README-maintainer-mode bfd/COPYING bfd/ChangeLog-0001 bfd/ChangeLog-9193 bfd/ChangeLog-9495 bfd/ChangeLog-9697 bfd/ChangeLog-9899 bfd/MAINTAINERS bfd/PORTING bfd/README bfd/TODO bfd/aix386-core.c bfd/aout-arm.c bfd/aout-cris.c bfd/aout-encap.c bfd/aout-ns32k.c bfd/aout-sparcle.c bfd/aout0.c bfd/aout32.c bfd/aout64.c bfd/aoutf1.h bfd/aoutx.h bfd/archive.c bfd/archive64.c bfd/armnetbsd.c bfd/bfd-in.h bfd/cache.c bfd/cf-i386lynx.c bfd/cf-m68klynx.c bfd/cf-sparclynx.c bfd/cisco-core.c bfd/coff-a29k.c bfd/coff-alpha.c bfd/coff-apollo.c bfd/coff-aux.c bfd/coff-go32.c bfd/coff-h8300.c bfd/coff-h8500.c bfd/coff-i386.c bfd/coff-i860.c bfd/coff-i960.c bfd/coff-ia64.c bfd/coff-m68k.c bfd/coff-m88k.c bfd/coff-mcore.c bfd/coff-mips.c bfd/coff-or32.c bfd/coff-pmac.c bfd/coff-ppc.c bfd/coff-sparc.c bfd/coff-stgo32.c bfd/coff-svm68k.c bfd/coff-tic30.c bfd/coff-tic54x.c bfd/coff-tic80.c bfd/coff-u68k.c bfd/coff-w65.c bfd/coff-we32k.c bfd/coff-z8k.c bfd/coffgen.c bfd/cofflink.c bfd/coffswap.h bfd/configure.com bfd/configure.host bfd/corefile.c bfd/cpu-a29k.c bfd/cpu-alpha.c bfd/cpu-arc.c bfd/cpu-arm.c bfd/cpu-avr.c bfd/cpu-cris.c bfd/cpu-d10v.c bfd/cpu-d30v.c bfd/cpu-fr30.c bfd/cpu-h8300.c bfd/cpu-h8500.c bfd/cpu-hppa.c bfd/cpu-i370.c bfd/cpu-i386.c bfd/cpu-i860.c bfd/cpu-i960.c bfd/cpu-ia64-opc.c bfd/cpu-ia64.c bfd/cpu-m10200.c bfd/cpu-m10300.c bfd/cpu-m32r.c bfd/cpu-m68hc11.c bfd/cpu-m68hc12.c bfd/cpu-m68k.c bfd/cpu-m88k.c bfd/cpu-mcore.c bfd/cpu-mmix.c bfd/cpu-ns32k.c bfd/cpu-openrisc.c bfd/cpu-or32.c bfd/cpu-pdp11.c bfd/cpu-pj.c bfd/cpu-powerpc.c bfd/cpu-rs6000.c bfd/cpu-s390.c bfd/cpu-sh.c bfd/cpu-sparc.c bfd/cpu-tic30.c bfd/cpu-tic54x.c bfd/cpu-tic80.c bfd/cpu-v850.c bfd/cpu-vax.c bfd/cpu-w65.c bfd/cpu-we32k.c bfd/cpu-xstormy16.c bfd/cpu-z8k.c bfd/demo64.c bfd/dep-in.sed bfd/doc/Makefile.am bfd/doc/bfd.texinfo bfd/doc/bfdint.texi bfd/doc/bfdsumm.texi bfd/doc/doc.str bfd/doc/header.sed bfd/doc/makefile.vms bfd/doc/proto.str bfd/dwarf1.c bfd/dwarf2.c bfd/ecoff.c bfd/ecofflink.c bfd/ecoffswap.h bfd/efi-app-ia32.c bfd/efi-app-ia64.c bfd/elf-hppa.h bfd/elf-m10200.c bfd/elf-m10300.c bfd/elf-strtab.c bfd/elf32-arc.c bfd/elf32-avr.c bfd/elf32-cris.c bfd/elf32-d10v.c bfd/elf32-d30v.c bfd/elf32-fr30.c bfd/elf32-gen.c bfd/elf32-h8300.c bfd/elf32-hppa.c bfd/elf32-hppa.h bfd/elf32-i370.c bfd/elf32-i386qnx.c bfd/elf32-i860.c bfd/elf32-i960.c bfd/elf32-m32r.c bfd/elf32-m68hc11.c bfd/elf32-m68hc12.c bfd/elf32-m88k.c bfd/elf32-mcore.c bfd/elf32-openrisc.c bfd/elf32-or32.c bfd/elf32-pj.c bfd/elf32-ppc.c bfd/elf32-s390.c bfd/elf32-sh-lin.c bfd/elf32-sh-nbsd.c bfd/elf32-sh.c bfd/elf32-sh64-com.c bfd/elf32-sh64-nbsd.c bfd/elf32-sh64.c bfd/elf32-sparc.c bfd/elf32-v850.c bfd/elf32-vax.c bfd/elf32-xstormy16.c bfd/elf32.c bfd/elf64-alpha.c bfd/elf64-gen.c bfd/elf64-hppa.c bfd/elf64-hppa.h bfd/elf64-mips.c bfd/elf64-mmix.c bfd/elf64-ppc.h bfd/elf64-s390.c bfd/elf64-sh64-nbsd.c bfd/elf64-sh64.c bfd/elf64-sparc.c bfd/elf64.c bfd/elfarm-nabi.c bfd/elfarm-oabi.c bfd/elfcode.h bfd/elfcore.h bfd/elflink.c bfd/elfxx-mips.h bfd/epoc-pe-arm.c bfd/epoc-pei-arm.c bfd/format.c bfd/freebsd.h bfd/gen-aout.c bfd/genlink.h bfd/go32stub.h bfd/host-aout.c bfd/hosts/alphalinux.h bfd/hosts/alphavms.h bfd/hosts/decstation.h bfd/hosts/delta68.h bfd/hosts/dpx2.h bfd/hosts/hp300bsd.h bfd/hosts/i386bsd.h bfd/hosts/i386linux.h bfd/hosts/i386mach3.h bfd/hosts/i386sco.h bfd/hosts/i860mach3.h bfd/hosts/m68kaux.h bfd/hosts/m68klinux.h bfd/hosts/m88kmach3.h bfd/hosts/mipsbsd.h bfd/hosts/mipsmach3.h bfd/hosts/news-mips.h bfd/hosts/news.h bfd/hosts/pc532mach.h bfd/hosts/riscos.h bfd/hosts/symmetry.h bfd/hosts/tahoe.h bfd/hosts/vaxbsd.h bfd/hosts/vaxult.h bfd/hosts/vaxult2.h bfd/hp300bsd.c bfd/hp300hpux.c bfd/hppabsd-core.c bfd/hpux-core.c bfd/i386aout.c bfd/i386bsd.c bfd/i386dynix.c bfd/i386freebsd.c bfd/i386linux.c bfd/i386lynx.c bfd/i386mach3.c bfd/i386netbsd.c bfd/init.c bfd/irix-core.c bfd/libaout.h bfd/libbfd.c bfd/libcoff-in.h bfd/libcoff.h bfd/libhppa.h bfd/libieee.h bfd/libnlm.h bfd/liboasys.h bfd/libpei.h bfd/libxcoff.h bfd/lynx-core.c bfd/m68k4knetbsd.c bfd/m68klinux.c bfd/m68klynx.c bfd/m68knetbsd.c bfd/m88kmach3.c bfd/makefile.vms bfd/merge.c bfd/mipsbsd.c bfd/mpw-config.in bfd/mpw-make.sed bfd/netbsd-core.c bfd/netbsd.h bfd/newsos3.c bfd/nlm.c bfd/nlm32-alpha.c bfd/nlm32-i386.c bfd/nlm32-ppc.c bfd/nlm32-sparc.c bfd/nlm32.c bfd/nlm64.c bfd/nlmcode.h bfd/nlmswap.h bfd/ns32k.h bfd/ns32knetbsd.c bfd/opncls.c bfd/osf-core.c bfd/pc532-mach.c bfd/pdp11.c bfd/pe-arm.c bfd/pe-i386.c bfd/pe-mcore.c bfd/pe-mips.c bfd/pe-ppc.c bfd/pe-sh.c bfd/pei-arm.c bfd/pei-i386.c bfd/pei-mcore.c bfd/pei-mips.c bfd/pei-ppc.c bfd/pei-sh.c bfd/peicode.h bfd/po/.cvsignore bfd/po/BLD-POTFILES.in bfd/po/Make-in bfd/po/SRC-POTFILES.in bfd/po/bfd.pot bfd/po/es.po bfd/po/fr.po bfd/po/ja.po bfd/po/sv.po bfd/po/tr.po bfd/ptrace-core.c bfd/reloc16.c bfd/riscix.c bfd/sco5-core.c bfd/som.h bfd/sparclinux.c bfd/sparclynx.c bfd/sparcnetbsd.c bfd/stab-syms.c bfd/stabs.c bfd/stamp-h.in bfd/sunos.c bfd/sysdep.h bfd/targmatch.sed bfd/trad-core.c bfd/vax1knetbsd.c bfd/vaxnetbsd.c bfd/vms-gsd.c bfd/vms-hdr.c bfd/vms-misc.c bfd/vms-tir.c bfd/vms.h bfd/xcoff-target.h bfd/xcofflink.c config.if config/mh-a68bsd config/mh-aix386 config/mh-armpic config/mh-cxux config/mh-cygwin config/mh-decstation config/mh-delta88 config/mh-djgpp config/mh-elfalphapic config/mh-hp300 config/mh-hpux config/mh-hpux8 config/mh-i370pic config/mh-ia64pic config/mh-interix config/mh-irix5 config/mh-irix6 config/mh-lynxrs6k config/mh-m68kpic config/mh-mingw32 config/mh-ncr3000 config/mh-ncrsvr43 config/mh-necv4 config/mh-openedition config/mh-papic config/mh-ppcpic config/mh-riscos config/mh-s390pic config/mh-sco config/mh-solaris config/mh-sparcpic config/mh-sysv config/mh-sysv4 config/mh-sysv5 config/mh-x86pic config/mpw-mh-mpw config/mpw/ChangeLog config/mpw/MoveIfChange config/mpw/README config/mpw/forward-include config/mpw/g-mpw-make.sed config/mpw/mpw-touch config/mpw/mpw-true config/mpw/null-command config/mpw/open-brace config/mpw/tr-7to8-src config/mpw/true config/mt-aix43 config/mt-alphaieee config/mt-d30v config/mt-linux config/mt-netware config/mt-ospace config/mt-v810 config/mt-wince djunpack.bat etc/ChangeLog etc/Makefile.in etc/add-log.el etc/add-log.vi etc/configbuild.ein etc/configbuild.fig etc/configbuild.jin etc/configbuild.tin etc/configdev.ein etc/configdev.fig etc/configdev.jin etc/configdev.tin etc/configure etc/configure.in etc/configure.texi etc/fdl.texi etc/make-stds.texi etc/standards.texi etc/texi2pod.pl gdb/29k-share/README gdb/29k-share/udi/udi2go32.c gdb/29k-share/udi/udiids.h gdb/29k-share/udi/udip2soc.c gdb/29k-share/udi/udiphcfg.h gdb/29k-share/udi/udiphunix.h gdb/29k-share/udi/udiproc.h gdb/29k-share/udi/udipt29k.h gdb/29k-share/udi/udiptcfg.h gdb/29k-share/udi/udisoc.h gdb/29k-share/udi/udr.c gdb/29k-share/udi_soc gdb/CONTRIBUTE gdb/COPYING gdb/ChangeLog-1990 gdb/ChangeLog-1991 gdb/ChangeLog-1992 gdb/ChangeLog-1993 gdb/ChangeLog-1994 gdb/ChangeLog-1995 gdb/ChangeLog-1996 gdb/ChangeLog-1997 gdb/ChangeLog-1998 gdb/ChangeLog-1999 gdb/ChangeLog-2000 gdb/ChangeLog-2001 gdb/ChangeLog-3.x gdb/README gdb/TODO gdb/a68v-nat.c gdb/abug-rom.c gdb/acconfig.h gdb/acinclude.m4 gdb/aclocal.m4 gdb/ada-exp.tab.c gdb/ada-exp.y gdb/ada-lang.h gdb/ada-lex.c gdb/ada-lex.l gdb/ada-tasks.c gdb/ada-typeprint.c gdb/ada-valprint.c gdb/alpha-nat.c gdb/alphabsd-nat.c gdb/alphabsd-tdep.c gdb/alphabsd-tdep.h gdb/annotate.c gdb/annotate.h gdb/arc-tdep.c gdb/arch-utils.c gdb/arch-utils.h gdb/arm-linux-nat.c gdb/armnbsd-nat.c gdb/avr-tdep.c gdb/ax-gdb.c gdb/ax-gdb.h gdb/ax-general.c gdb/ax.h gdb/bcache.c gdb/bcache.h gdb/breakpoint.c gdb/breakpoint.h gdb/buildsym.c gdb/buildsym.h gdb/builtin-regs.c gdb/builtin-regs.h gdb/c-typeprint.c gdb/c-valprint.c gdb/call-cmds.h gdb/ch-exp.c gdb/ch-lang.c gdb/ch-lang.h gdb/ch-typeprint.c gdb/ch-valprint.c gdb/cli-out.c gdb/cli-out.h gdb/cli/cli-cmds.c gdb/cli/cli-cmds.h gdb/cli/cli-decode.c gdb/cli/cli-decode.h gdb/cli/cli-dump.h gdb/cli/cli-script.c gdb/cli/cli-script.h gdb/cli/cli-setshow.c gdb/cli/cli-setshow.h gdb/cli/cli-utils.c gdb/cli/cli-utils.h gdb/coff-solib.c gdb/coff-solib.h gdb/coffread.c gdb/command.h gdb/complaints.c gdb/complaints.h gdb/completer.c gdb/completer.h gdb/config.in gdb/config/alpha/alpha-linux.mh gdb/config/alpha/alpha-linux.mt gdb/config/alpha/alpha-osf1.mh gdb/config/alpha/alpha-osf1.mt gdb/config/alpha/alpha-osf2.mh gdb/config/alpha/alpha-osf3.mh gdb/config/alpha/fbsd.mh gdb/config/alpha/fbsd.mt gdb/config/alpha/nbsd.mh gdb/config/alpha/nbsd.mt gdb/config/alpha/nm-fbsd.h gdb/config/alpha/nm-linux.h gdb/config/alpha/nm-osf.h gdb/config/alpha/nm-osf2.h gdb/config/alpha/nm-osf3.h gdb/config/alpha/tm-alpha.h gdb/config/alpha/tm-alphalinux.h gdb/config/alpha/tm-fbsd.h gdb/config/alpha/xm-alphalinux.h gdb/config/alpha/xm-alphaosf.h gdb/config/arc/arc.mt gdb/config/arc/tm-arc.h gdb/config/arm/embed.mt gdb/config/arm/linux.mh gdb/config/arm/linux.mt gdb/config/arm/nm-linux.h gdb/config/arm/tm-arm.h gdb/config/arm/tm-embed.h gdb/config/arm/tm-linux.h gdb/config/arm/tm-wince.h gdb/config/arm/wince.mt gdb/config/arm/xm-linux.h gdb/config/arm/xm-nbsd.h gdb/config/cris/cris.mt gdb/config/cris/tm-cris.h gdb/config/d10v/d10v.mt gdb/config/d30v/d30v.mt gdb/config/d30v/tm-d30v.h gdb/config/djgpp/README gdb/config/djgpp/config.sed gdb/config/djgpp/djcheck.sh gdb/config/djgpp/djconfig.sh gdb/config/fr30/fr30.mt gdb/config/fr30/tm-fr30.h gdb/config/h8300/h8300.mt gdb/config/h8500/h8500.mt gdb/config/h8500/tm-h8500.h gdb/config/i386/cygwin.mh gdb/config/i386/cygwin.mt gdb/config/i386/embed.mt gdb/config/i386/fbsd.mh gdb/config/i386/fbsd.mt gdb/config/i386/gdbserve.mt gdb/config/i386/go32.mh gdb/config/i386/go32.mt gdb/config/i386/i386aix.mh gdb/config/i386/i386aix.mt gdb/config/i386/i386aout.mt gdb/config/i386/i386bsd.mh gdb/config/i386/i386bsd.mt gdb/config/i386/i386dgux.mh gdb/config/i386/i386gnu.mh gdb/config/i386/i386gnu.mt gdb/config/i386/i386lynx.mh gdb/config/i386/i386lynx.mt gdb/config/i386/i386m3.mh gdb/config/i386/i386m3.mt gdb/config/i386/i386mach.mh gdb/config/i386/i386mk.mh gdb/config/i386/i386mk.mt gdb/config/i386/i386nw.mt gdb/config/i386/i386os9k.mt gdb/config/i386/i386sco.mh gdb/config/i386/i386sco4.mh gdb/config/i386/i386sco5.mh gdb/config/i386/i386sco5.mt gdb/config/i386/i386sol2.mh gdb/config/i386/i386sol2.mt gdb/config/i386/i386v.mh gdb/config/i386/i386v.mt gdb/config/i386/i386v32.mh gdb/config/i386/i386v4.mh gdb/config/i386/i386v4.mt gdb/config/i386/i386v42mp.mh gdb/config/i386/i386v42mp.mt gdb/config/i386/linux.mh gdb/config/i386/linux.mt gdb/config/i386/ncr3000.mh gdb/config/i386/ncr3000.mt gdb/config/i386/nm-fbsd.h gdb/config/i386/nm-gnu.h gdb/config/i386/nm-i386.h gdb/config/i386/nm-i386aix.h gdb/config/i386/nm-i386bsd.h gdb/config/i386/nm-i386lynx.h gdb/config/i386/nm-i386mach.h gdb/config/i386/nm-i386sco.h gdb/config/i386/nm-i386sco4.h gdb/config/i386/nm-i386sco5.h gdb/config/i386/nm-i386sol2.h gdb/config/i386/nm-i386v.h gdb/config/i386/nm-i386v4.h gdb/config/i386/nm-i386v42mp.h gdb/config/i386/nm-linux.h gdb/config/i386/nm-m3.h gdb/config/i386/nm-obsd.h gdb/config/i386/nm-ptx4.h gdb/config/i386/nm-symmetry.h gdb/config/i386/nm-x86-64.h gdb/config/i386/obsd.mh gdb/config/i386/obsd.mt gdb/config/i386/ptx.mh gdb/config/i386/ptx.mt gdb/config/i386/ptx4.mh gdb/config/i386/ptx4.mt gdb/config/i386/symmetry.mh gdb/config/i386/symmetry.mt gdb/config/i386/tm-cygwin.h gdb/config/i386/tm-fbsd.h gdb/config/i386/tm-go32.h gdb/config/i386/tm-i386.h gdb/config/i386/tm-i386aix.h gdb/config/i386/tm-i386bsd.h gdb/config/i386/tm-i386gnu.h gdb/config/i386/tm-i386lynx.h gdb/config/i386/tm-i386m3.h gdb/config/i386/tm-i386mk.h gdb/config/i386/tm-i386nw.h gdb/config/i386/tm-i386os9k.h gdb/config/i386/tm-i386sco5.h gdb/config/i386/tm-i386sol2.h gdb/config/i386/tm-i386v.h gdb/config/i386/tm-i386v4.h gdb/config/i386/tm-i386v42mp.h gdb/config/i386/tm-linux.h gdb/config/i386/tm-obsd.h gdb/config/i386/tm-ptx.h gdb/config/i386/tm-ptx4.h gdb/config/i386/tm-symmetry.h gdb/config/i386/tm-vxworks.h gdb/config/i386/vxworks.mt gdb/config/i386/x86-64linux.mh gdb/config/i386/x86-64linux.mt gdb/config/i386/xm-cygwin.h gdb/config/i386/xm-go32.h gdb/config/i386/xm-i386.h gdb/config/i386/xm-i386aix.h gdb/config/i386/xm-i386bsd.h gdb/config/i386/xm-i386gnu.h gdb/config/i386/xm-i386m3.h gdb/config/i386/xm-i386mach.h gdb/config/i386/xm-i386mk.h gdb/config/i386/xm-i386sco.h gdb/config/i386/xm-i386v.h gdb/config/i386/xm-i386v32.h gdb/config/i386/xm-i386v4.h gdb/config/i386/xm-nbsd.h gdb/config/i386/xm-ptx.h gdb/config/i386/xm-ptx4.h gdb/config/i386/xm-symmetry.h gdb/config/i960/mon960.mt gdb/config/i960/nindy960.mt gdb/config/i960/tm-i960.h gdb/config/i960/tm-mon960.h gdb/config/i960/tm-nindy960.h gdb/config/i960/tm-vx960.h gdb/config/i960/vxworks960.mt gdb/config/ia64/aix.mh gdb/config/ia64/aix.mt gdb/config/ia64/linux.mh gdb/config/ia64/linux.mt gdb/config/ia64/nm-aix.h gdb/config/ia64/nm-linux.h gdb/config/ia64/tm-aix.h gdb/config/ia64/tm-ia64.h gdb/config/ia64/tm-linux.h gdb/config/ia64/xm-aix.h gdb/config/ia64/xm-linux.h gdb/config/m32r/m32r.mt gdb/config/m32r/tm-m32r.h gdb/config/m68hc11/m68hc11.mt gdb/config/m68k/3b1.mh gdb/config/m68k/3b1.mt gdb/config/m68k/apollo68b.mh gdb/config/m68k/apollo68b.mt gdb/config/m68k/apollo68v.mh gdb/config/m68k/cisco.mt gdb/config/m68k/delta68.mh gdb/config/m68k/delta68.mt gdb/config/m68k/dpx2.mh gdb/config/m68k/dpx2.mt gdb/config/m68k/es1800.mt gdb/config/m68k/hp300bsd.mh gdb/config/m68k/hp300bsd.mt gdb/config/m68k/hp300hpux.mh gdb/config/m68k/hp300hpux.mt gdb/config/m68k/linux.mh gdb/config/m68k/linux.mt gdb/config/m68k/m68klynx.mh gdb/config/m68k/m68klynx.mt gdb/config/m68k/m68kv4.mh gdb/config/m68k/m68kv4.mt gdb/config/m68k/monitor.mt gdb/config/m68k/nm-apollo68b.h gdb/config/m68k/nm-apollo68v.h gdb/config/m68k/nm-delta68.h gdb/config/m68k/nm-dpx2.h gdb/config/m68k/nm-hp300bsd.h gdb/config/m68k/nm-hp300hpux.h gdb/config/m68k/nm-linux.h gdb/config/m68k/nm-m68klynx.h gdb/config/m68k/nm-sun2.h gdb/config/m68k/nm-sun3.h gdb/config/m68k/nm-sysv4.h gdb/config/m68k/os68k.mt gdb/config/m68k/st2000.mt gdb/config/m68k/sun2os3.mh gdb/config/m68k/sun2os3.mt gdb/config/m68k/sun2os4.mh gdb/config/m68k/sun2os4.mt gdb/config/m68k/sun3os3.mh gdb/config/m68k/sun3os3.mt gdb/config/m68k/sun3os4.mh gdb/config/m68k/sun3os4.mt gdb/config/m68k/tm-3b1.h gdb/config/m68k/tm-apollo68b.h gdb/config/m68k/tm-cisco.h gdb/config/m68k/tm-delta68.h gdb/config/m68k/tm-dpx2.h gdb/config/m68k/tm-es1800.h gdb/config/m68k/tm-hp300bsd.h gdb/config/m68k/tm-hp300hpux.h gdb/config/m68k/tm-linux.h gdb/config/m68k/tm-m68k.h gdb/config/m68k/tm-m68klynx.h gdb/config/m68k/tm-m68kv4.h gdb/config/m68k/tm-mac.h gdb/config/m68k/tm-monitor.h gdb/config/m68k/tm-os68k.h gdb/config/m68k/tm-st2000.h gdb/config/m68k/tm-sun2.h gdb/config/m68k/tm-sun2os4.h gdb/config/m68k/tm-sun3.h gdb/config/m68k/tm-sun3os4.h gdb/config/m68k/tm-vx68.h gdb/config/m68k/vxworks68.mt gdb/config/m68k/xm-3b1.h gdb/config/m68k/xm-apollo68b.h gdb/config/m68k/xm-apollo68v.h gdb/config/m68k/xm-delta68.h gdb/config/m68k/xm-dpx2.h gdb/config/m68k/xm-hp300bsd.h gdb/config/m68k/xm-hp300hpux.h gdb/config/m68k/xm-linux.h gdb/config/m68k/xm-m68k.h gdb/config/m68k/xm-m68kv4.h gdb/config/m68k/xm-nbsd.h gdb/config/m68k/xm-sun2.h gdb/config/m68k/xm-sun3.h gdb/config/m68k/xm-sun3os4.h gdb/config/m88k/delta88.mh gdb/config/m88k/delta88.mt gdb/config/m88k/delta88v4.mh gdb/config/m88k/delta88v4.mt gdb/config/m88k/m88k.mh gdb/config/m88k/m88k.mt gdb/config/m88k/nm-delta88v4.h gdb/config/m88k/nm-m88k.h gdb/config/m88k/tm-delta88.h gdb/config/m88k/tm-delta88v4.h gdb/config/m88k/tm-m88k.h gdb/config/m88k/xm-delta88.h gdb/config/m88k/xm-delta88v4.h gdb/config/m88k/xm-dgux.h gdb/config/mcore/mcore.mt gdb/config/mcore/tm-mcore.h gdb/config/mips/bigmips.mt gdb/config/mips/bigmips64.mt gdb/config/mips/decstation.mh gdb/config/mips/decstation.mt gdb/config/mips/embed.mt gdb/config/mips/embed64.mt gdb/config/mips/embedl.mt gdb/config/mips/embedl64.mt gdb/config/mips/irix3.mh gdb/config/mips/irix3.mt gdb/config/mips/irix4.mh gdb/config/mips/irix5.mh gdb/config/mips/irix5.mt gdb/config/mips/irix6.mh gdb/config/mips/irix6.mt gdb/config/mips/linux.mh gdb/config/mips/linux.mt gdb/config/mips/littlemips.mh gdb/config/mips/littlemips.mt gdb/config/mips/mipsm3.mh gdb/config/mips/mipsm3.mt gdb/config/mips/mipsv4.mh gdb/config/mips/mipsv4.mt gdb/config/mips/news-mips.mh gdb/config/mips/nm-irix3.h gdb/config/mips/nm-irix4.h gdb/config/mips/nm-irix5.h gdb/config/mips/nm-irix6.h gdb/config/mips/nm-linux.h gdb/config/mips/nm-mips.h gdb/config/mips/nm-news-mips.h gdb/config/mips/nm-riscos.h gdb/config/mips/riscos.mh gdb/config/mips/tm-bigmips.h gdb/config/mips/tm-bigmips64.h gdb/config/mips/tm-embed.h gdb/config/mips/tm-embed64.h gdb/config/mips/tm-embedl.h gdb/config/mips/tm-embedl64.h gdb/config/mips/tm-irix3.h gdb/config/mips/tm-irix5.h gdb/config/mips/tm-irix6.h gdb/config/mips/tm-linux.h gdb/config/mips/tm-mips.h gdb/config/mips/tm-mips64.h gdb/config/mips/tm-mipsm3.h gdb/config/mips/tm-mipsv4.h gdb/config/mips/tm-tx39.h gdb/config/mips/tm-tx39l.h gdb/config/mips/tm-vr4100.h gdb/config/mips/tm-vr4300.h gdb/config/mips/tm-vr4300el.h gdb/config/mips/tm-vr4xxx.h gdb/config/mips/tm-vr4xxxel.h gdb/config/mips/tm-vr5000.h gdb/config/mips/tm-vr5000el.h gdb/config/mips/tm-vxmips.h gdb/config/mips/tm-wince.h gdb/config/mips/tx39.mt gdb/config/mips/tx39l.mt gdb/config/mips/vr4100.mt gdb/config/mips/vr4300.mt gdb/config/mips/vr4300el.mt gdb/config/mips/vr4xxx.mt gdb/config/mips/vr4xxxel.mt gdb/config/mips/vr5000.mt gdb/config/mips/vr5000el.mt gdb/config/mips/vxmips.mt gdb/config/mips/wince.mt gdb/config/mips/xm-irix3.h gdb/config/mips/xm-irix4.h gdb/config/mips/xm-irix5.h gdb/config/mips/xm-irix6.h gdb/config/mips/xm-linux.h gdb/config/mips/xm-mips.h gdb/config/mips/xm-mipsm3.h gdb/config/mips/xm-mipsv4.h gdb/config/mips/xm-riscos.h gdb/config/mn10200/mn10200.mt gdb/config/mn10200/tm-mn10200.h gdb/config/mn10300/mn10300.mt gdb/config/nm-gnu.h gdb/config/nm-linux.h gdb/config/nm-lynx.h gdb/config/nm-m3.h gdb/config/nm-sysv4.h gdb/config/none/nm-none.h gdb/config/none/none.mh gdb/config/none/none.mt gdb/config/none/tm-none.h gdb/config/none/xm-none.h gdb/config/ns32k/xm-nbsd.h gdb/config/pa/hppa64.mt gdb/config/pa/hppabsd.mh gdb/config/pa/hppabsd.mt gdb/config/pa/hppahpux.mh gdb/config/pa/hppahpux.mt gdb/config/pa/hppaosf.mh gdb/config/pa/hppaosf.mt gdb/config/pa/hppapro.mt gdb/config/pa/hpux1020.mh gdb/config/pa/hpux1020.mt gdb/config/pa/hpux11.mh gdb/config/pa/hpux11.mt gdb/config/pa/hpux11w.mt gdb/config/pa/nm-hppab.h gdb/config/pa/nm-hppah.h gdb/config/pa/nm-hppah11.h gdb/config/pa/nm-hppao.h gdb/config/pa/tm-hppa.h gdb/config/pa/tm-hppa64.h gdb/config/pa/tm-hppab.h gdb/config/pa/tm-hppah.h gdb/config/pa/tm-hppao.h gdb/config/pa/tm-pro.h gdb/config/pa/xm-hppab.h gdb/config/pa/xm-hppah.h gdb/config/pa/xm-pa.h gdb/config/powerpc/aix.mh gdb/config/powerpc/aix.mt gdb/config/powerpc/gdbserve.mt gdb/config/powerpc/linux.mh gdb/config/powerpc/linux.mt gdb/config/powerpc/nm-aix.h gdb/config/powerpc/nm-linux.h gdb/config/powerpc/ppc-eabi.mt gdb/config/powerpc/ppc-sim.mt gdb/config/powerpc/ppcle-eabi.mt gdb/config/powerpc/ppcle-sim.mt gdb/config/powerpc/tm-linux.h gdb/config/powerpc/tm-ppc-aix.h gdb/config/powerpc/tm-ppc-eabi.h gdb/config/powerpc/tm-ppc-sim.h gdb/config/powerpc/tm-ppcle-eabi.h gdb/config/powerpc/tm-ppcle-sim.h gdb/config/powerpc/tm-vxworks.h gdb/config/powerpc/vxworks.mt gdb/config/powerpc/xm-aix.h gdb/config/powerpc/xm-linux.h gdb/config/romp/rtbsd.mh gdb/config/romp/xm-rtbsd.h gdb/config/rs6000/aix4.mh gdb/config/rs6000/aix4.mt gdb/config/rs6000/nm-rs6000.h gdb/config/rs6000/nm-rs6000ly.h gdb/config/rs6000/rs6000.mh gdb/config/rs6000/rs6000.mt gdb/config/rs6000/rs6000lynx.mh gdb/config/rs6000/rs6000lynx.mt gdb/config/rs6000/tm-rs6000-aix4.h gdb/config/rs6000/tm-rs6000.h gdb/config/rs6000/tm-rs6000ly.h gdb/config/rs6000/xm-aix4.h gdb/config/rs6000/xm-rs6000.h gdb/config/s390/nm-linux.h gdb/config/s390/s390.mh gdb/config/s390/s390.mt gdb/config/s390/s390x.mt gdb/config/s390/tm-linux.h gdb/config/s390/tm-s390.h gdb/config/s390/xm-linux.h gdb/config/sh/embed.mt gdb/config/sh/linux.mt gdb/config/sh/nbsd.mh gdb/config/sh/nbsd.mt gdb/config/sh/nm-nbsd.h gdb/config/sh/tm-linux.h gdb/config/sh/tm-nbsd.h gdb/config/sh/tm-wince.h gdb/config/sh/wince.mt gdb/config/sparc/fbsd.mh gdb/config/sparc/fbsd.mt gdb/config/sparc/linux.mh gdb/config/sparc/linux.mt gdb/config/sparc/nbsd64.mh gdb/config/sparc/nbsd64.mt gdb/config/sparc/nm-fbsd.h gdb/config/sparc/nm-linux.h gdb/config/sparc/nm-nbsd.h gdb/config/sparc/nm-sparclynx.h gdb/config/sparc/nm-sun4os4.h gdb/config/sparc/nm-sun4sol2.h gdb/config/sparc/sp64.mt gdb/config/sparc/sp64linux.mt gdb/config/sparc/sp64sim.mt gdb/config/sparc/sp64sol2.mt gdb/config/sparc/sparc-em.mt gdb/config/sparc/sparclet.mt gdb/config/sparc/sparclite.mt gdb/config/sparc/sparclynx.mh gdb/config/sparc/sparclynx.mt gdb/config/sparc/sun4os4.mh gdb/config/sparc/sun4os4.mt gdb/config/sparc/sun4sol2.mh gdb/config/sparc/sun4sol2.mt gdb/config/sparc/tm-fbsd.h gdb/config/sparc/tm-linux.h gdb/config/sparc/tm-nbsd64.h gdb/config/sparc/tm-sp64.h gdb/config/sparc/tm-sp64linux.h gdb/config/sparc/tm-sp64sim.h gdb/config/sparc/tm-sparc.h gdb/config/sparc/tm-sparclet.h gdb/config/sparc/tm-sparclite.h gdb/config/sparc/tm-sparclynx.h gdb/config/sparc/tm-spc-em.h gdb/config/sparc/tm-sun4os4.h gdb/config/sparc/tm-sun4sol2.h gdb/config/sparc/tm-vxsparc.h gdb/config/sparc/vxsparc.mt gdb/config/sparc/xm-linux.h gdb/config/sparc/xm-nbsd.h gdb/config/sparc/xm-sun4sol2.h gdb/config/tm-linux.h gdb/config/tm-lynx.h gdb/config/tm-sunos.h gdb/config/tm-sysv4.h gdb/config/tm-vxworks.h gdb/config/vax/nm-vax.h gdb/config/vax/tm-vax.h gdb/config/vax/vax.mt gdb/config/vax/vaxbsd.mh gdb/config/vax/vaxult.mh gdb/config/vax/vaxult2.mh gdb/config/vax/xm-vax.h gdb/config/vax/xm-vaxbsd.h gdb/config/vax/xm-vaxult.h gdb/config/vax/xm-vaxult2.h gdb/config/xm-aix4.h gdb/config/xm-nbsd.h gdb/config/xm-sysv4.h gdb/config/xstormy16/xstormy16.mt gdb/config/z8k/tm-z8k.h gdb/config/z8k/z8k.mt gdb/configure gdb/configure.in gdb/copying.awk gdb/copying.c gdb/core-aout.c gdb/core-regset.c gdb/core-sol2.c gdb/corefile.c gdb/cp-abi.c gdb/cp-abi.h gdb/cp-valprint.c gdb/cpu32bug-rom.c gdb/cris-tdep.c gdb/cxux-nat.c gdb/d30v-tdep.c gdb/dbug-rom.c gdb/dbxread.c gdb/dcache.c gdb/dcache.h gdb/delta68-nat.c gdb/demangle.c gdb/dink32-rom.c gdb/doc/LRS gdb/doc/Makefile.in gdb/doc/a4rc.sed gdb/doc/agentexpr.texi gdb/doc/all-cfg.texi gdb/doc/annotate.texi gdb/doc/configure gdb/doc/configure.in gdb/doc/fdl.texi gdb/doc/gpl.texi gdb/doc/lpsrc.sed gdb/doc/psrc.sed gdb/doc/refcard.tex gdb/doc/stabs.texinfo gdb/doublest.c gdb/doublest.h gdb/dpx2-nat.c gdb/dsrec.c gdb/dst.h gdb/dstread.c gdb/dve3900-rom.c gdb/dwarf2cfi.h gdb/dwarfread.c gdb/elfread.c gdb/environ.c gdb/environ.h gdb/eval.c gdb/event-loop.h gdb/exc_request.defs gdb/exec.c gdb/expprint.c gdb/expression.h gdb/f-exp.y gdb/f-lang.c gdb/f-lang.h gdb/f-typeprint.c gdb/f-valprint.c gdb/fbsd-proc.c gdb/findvar.c gdb/fork-child.c gdb/fr30-tdep.c gdb/frame.c gdb/gcore.c gdb/gdb-events.c gdb/gdb-events.h gdb/gdb-events.sh gdb/gdb-stabs.h gdb/gdb.1 gdb/gdb.gdb gdb/gdb.h gdb/gdb_assert.h gdb/gdb_dirent.h gdb/gdb_proc_service.h gdb/gdb_regex.h gdb/gdb_stat.h gdb/gdb_string.h gdb/gdb_thread_db.h gdb/gdb_vfork.h gdb/gdb_wait.h gdb/gdbcmd.h gdb/gdbcore.h gdb/gdbinit.in gdb/gdbserver/Makefile.in gdb/gdbserver/README gdb/gdbserver/acconfig.h gdb/gdbserver/acinclude.m4 gdb/gdbserver/aclocal.m4 gdb/gdbserver/config.in gdb/gdbserver/configure gdb/gdbserver/configure.in gdb/gdbserver/configure.srv gdb/gdbserver/gdbreplay.c gdb/gdbserver/gdbserver.1 gdb/gdbserver/i387-fp.c gdb/gdbserver/i387-fp.h gdb/gdbserver/inferiors.c gdb/gdbserver/linux-arm-low.c gdb/gdbserver/linux-i386-low.c gdb/gdbserver/linux-ia64-low.c gdb/gdbserver/linux-low.c gdb/gdbserver/linux-low.h gdb/gdbserver/linux-m68k-low.c gdb/gdbserver/linux-mips-low.c gdb/gdbserver/linux-ppc-low.c gdb/gdbserver/linux-s390-low.c gdb/gdbserver/linux-sh-low.c gdb/gdbserver/linux-x86-64-low.c gdb/gdbserver/low-hppabsd.c gdb/gdbserver/low-lynx.c gdb/gdbserver/low-nbsd.c gdb/gdbserver/low-sim.c gdb/gdbserver/low-sparc.c gdb/gdbserver/low-sun3.c gdb/gdbserver/mem-break.c gdb/gdbserver/mem-break.h gdb/gdbserver/proc-service.c gdb/gdbserver/regcache.c gdb/gdbserver/regcache.h gdb/gdbserver/remote-utils.c gdb/gdbserver/server.h gdb/gdbserver/target.c gdb/gdbserver/target.h gdb/gdbserver/terminal.h gdb/gdbserver/thread-db.c gdb/gdbserver/utils.c gdb/gdbthread.h gdb/gnu-nat.c gdb/gnu-nat.h gdb/gnu-v2-abi.c gdb/gnu-v3-abi.c gdb/go32-nat.c gdb/gregset.h gdb/h8500-tdep.c gdb/hp300ux-nat.c gdb/hpacc-abi.c gdb/hppa-tdep.c gdb/hppab-nat.c gdb/hppah-nat.c gdb/hppam3-nat.c gdb/hpux-thread.c gdb/i386-linux-nat.c gdb/i386-linux-tdep.c gdb/i386-linux-tdep.h gdb/i386-nat.c gdb/i386-stub.c gdb/i386-tdep.h gdb/i386aix-nat.c gdb/i386b-nat.c gdb/i386bsd-nat.c gdb/i386bsd-tdep.c gdb/i386fbsd-nat.c gdb/i386gnu-nat.c gdb/i386ly-tdep.c gdb/i386m3-nat.c gdb/i386mach-nat.c gdb/i386nbsd-tdep.c gdb/i386v-nat.c gdb/i386v4-nat.c gdb/i387-tdep.c gdb/i387-tdep.h gdb/i960-tdep.c gdb/ia64-aix-nat.c gdb/ia64-aix-tdep.c gdb/ia64-linux-nat.c gdb/ia64-linux-tdep.c gdb/ia64-tdep.c gdb/inf-loop.c gdb/inf-loop.h gdb/inflow.c gdb/infptrace.c gdb/inftarg.c gdb/infttrace.c gdb/irix4-nat.c gdb/irix5-nat.c gdb/jv-exp.y gdb/jv-lang.c gdb/jv-lang.h gdb/jv-typeprint.c gdb/jv-valprint.c gdb/kod-cisco.c gdb/kod.c gdb/kod.h gdb/language.c gdb/language.h gdb/lin-lwp.c gdb/linespec.c gdb/linespec.h gdb/linux-proc.c gdb/lynx-nat.c gdb/m2-exp.y gdb/m2-lang.c gdb/m2-lang.h gdb/m2-typeprint.c gdb/m2-valprint.c gdb/m3-nat.c gdb/m32r-rom.c gdb/m32r-stub.c gdb/m32r-tdep.c gdb/m68hc11-tdep.c gdb/m68k-stub.c gdb/m68k-tdep.c gdb/m68klinux-nat.c gdb/m68knbsd-nat.c gdb/m68knbsd-tdep.c gdb/m88k-nat.c gdb/m88k-tdep.c gdb/macroexp.c gdb/macroexp.h gdb/macrotab.h gdb/maint.c gdb/mcore-rom.c gdb/mcore-tdep.c gdb/mdebugread.c gdb/mem-break.c gdb/memattr.c gdb/memattr.h gdb/mi/gdbmi.texinfo gdb/mi/mi-cmd-break.c gdb/mi/mi-cmd-disas.c gdb/mi/mi-cmd-stack.c gdb/mi/mi-cmd-var.c gdb/mi/mi-console.c gdb/mi/mi-console.h gdb/mi/mi-getopt.c gdb/mi/mi-getopt.h gdb/mi/mi-out.c gdb/mi/mi-out.h gdb/mi/mi-parse.c gdb/mi/mi-parse.h gdb/minimon.h gdb/minsyms.c gdb/mips-linux-nat.c gdb/mips-linux-tdep.c gdb/mips-nat.c gdb/mipsm3-nat.c gdb/mipsread.c gdb/mipsv4-nat.c gdb/mn10200-tdep.c gdb/mn10300-tdep.c gdb/mon960-rom.c gdb/monitor.c gdb/monitor.h gdb/msg.defs gdb/msg_reply.defs gdb/nbsd-tdep.c gdb/nbsd-tdep.h gdb/nindy-share/Makefile gdb/nindy-share/Onindy.c gdb/nindy-share/README gdb/nindy-share/VERSION gdb/nindy-share/b.out.h gdb/nindy-share/block_io.h gdb/nindy-share/coff.h gdb/nindy-share/env.h gdb/nindy-share/nindy.c gdb/nindy-share/stop.h gdb/nindy-share/ttyflush.c gdb/nindy-tdep.c gdb/nlm/Makefile.in gdb/nlm/configure gdb/nlm/configure.in gdb/nlm/gdbserve.c gdb/nlm/gdbserve.def gdb/nlm/i386.c gdb/nlm/i386.h gdb/nlm/ppc.c gdb/nlm/ppc.h gdb/nlm/prelude.c gdb/nlmread.c gdb/notify.defs gdb/ns32knbsd-nat.c gdb/objfiles.c gdb/objfiles.h gdb/ocd.c gdb/ocd.h gdb/op50-rom.c gdb/os9kread.c gdb/osf-share/AT386/cma_thread_io.h gdb/osf-share/HP800/cma_thread_io.h gdb/osf-share/README gdb/osf-share/RIOS/cma_thread_io.h gdb/osf-share/cma_attr.h gdb/osf-share/cma_deb_core.h gdb/osf-share/cma_debug_client.h gdb/osf-share/cma_errors.h gdb/osf-share/cma_handle.h gdb/osf-share/cma_init.h gdb/osf-share/cma_list.h gdb/osf-share/cma_mutex.h gdb/osf-share/cma_sched.h gdb/osf-share/cma_semaphore_defs.h gdb/osf-share/cma_sequence.h gdb/osf-share/cma_stack.h gdb/osf-share/cma_stack_int.h gdb/osf-share/cma_tcb_defs.h gdb/osf-share/cma_util.h gdb/osfsolib.c gdb/p-lang.c gdb/p-lang.h gdb/p-typeprint.c gdb/p-valprint.c gdb/pa64solib.c gdb/pa64solib.h gdb/ppc-bdm.c gdb/ppc-linux-nat.c gdb/ppc-linux-tdep.c gdb/ppc-sysv-tdep.c gdb/ppc-tdep.h gdb/ppcbug-rom.c gdb/printcmd.c gdb/proc-api.c gdb/proc-events.c gdb/proc-flags.c gdb/proc-service.c gdb/proc-utils.h gdb/proc-why.c gdb/process_reply.defs gdb/procfs.c gdb/ptx4-nat.c gdb/rdi-share/Makefile.am gdb/rdi-share/Makefile.in gdb/rdi-share/README.CYGNUS gdb/rdi-share/aclocal.m4 gdb/rdi-share/adp.h gdb/rdi-share/adperr.h gdb/rdi-share/angel.h gdb/rdi-share/angel_bytesex.c gdb/rdi-share/angel_bytesex.h gdb/rdi-share/angel_endian.h gdb/rdi-share/ardi.c gdb/rdi-share/ardi.h gdb/rdi-share/armdbg.h gdb/rdi-share/buffers.h gdb/rdi-share/chandefs.h gdb/rdi-share/channels.h gdb/rdi-share/chanpriv.h gdb/rdi-share/configure gdb/rdi-share/configure.in gdb/rdi-share/crc.c gdb/rdi-share/crc.h gdb/rdi-share/dbg_conf.h gdb/rdi-share/dbg_cp.h gdb/rdi-share/dbg_hif.h gdb/rdi-share/dbg_rdi.h gdb/rdi-share/devclnt.h gdb/rdi-share/devices.h gdb/rdi-share/devsw.c gdb/rdi-share/devsw.h gdb/rdi-share/drivers.c gdb/rdi-share/drivers.h gdb/rdi-share/etherdrv.c gdb/rdi-share/ethernet.h gdb/rdi-share/host.h gdb/rdi-share/hostchan.c gdb/rdi-share/hostchan.h gdb/rdi-share/hsys.c gdb/rdi-share/hsys.h gdb/rdi-share/logging.c gdb/rdi-share/logging.h gdb/rdi-share/msgbuild.c gdb/rdi-share/msgbuild.h gdb/rdi-share/params.c gdb/rdi-share/params.h gdb/rdi-share/rx.c gdb/rdi-share/rxtx.h gdb/rdi-share/serdrv.c gdb/rdi-share/serpardr.c gdb/rdi-share/sys.h gdb/rdi-share/tx.c gdb/rdi-share/unixcomm.c gdb/rdi-share/unixcomm.h gdb/regformats/reg-arm.dat gdb/regformats/reg-i386-linux.dat gdb/regformats/reg-i386.dat gdb/regformats/reg-ia64.dat gdb/regformats/reg-m68k.dat gdb/regformats/reg-mips.dat gdb/regformats/reg-ppc.dat gdb/regformats/reg-s390.dat gdb/regformats/reg-s390x.dat gdb/regformats/reg-sh.dat gdb/regformats/reg-x86-64.dat gdb/regformats/regdat.sh gdb/regformats/regdef.h gdb/remote-array.c gdb/remote-bug.c gdb/remote-e7000.c gdb/remote-es.c gdb/remote-est.c gdb/remote-hms.c gdb/remote-mips.c gdb/remote-nindy.c gdb/remote-nrom.c gdb/remote-os9k.c gdb/remote-rdi.c gdb/remote-rdp.c gdb/remote-sds.c gdb/remote-sim.c gdb/remote-st.c gdb/remote-utils.c gdb/remote-utils.h gdb/remote-vx.c gdb/remote-vx29k.c gdb/remote-vx68.c gdb/remote-vx960.c gdb/remote-vxmips.c gdb/remote-vxsparc.c gdb/remote.h gdb/reply_mig_hack.awk gdb/rom68k-rom.c gdb/rs6000-nat.c gdb/s390-nat.c gdb/s390-tdep.c gdb/saber.suppress gdb/scm-exp.c gdb/scm-lang.c gdb/scm-lang.h gdb/scm-tags.h gdb/scm-valprint.c gdb/ser-e7kpc.c gdb/ser-go32.c gdb/ser-pipe.c gdb/ser-unix.c gdb/ser-unix.h gdb/serial.c gdb/serial.h gdb/sh-stub.c gdb/shnbsd-nat.c gdb/shnbsd-tdep.h gdb/signals/signals.c gdb/sim-regno.h gdb/sol-thread.c gdb/solib-aix5.c gdb/solib-legacy.c gdb/solib-osf.c gdb/solib-sunos.c gdb/solib-svr4.c gdb/solib-svr4.h gdb/solib.c gdb/solib.h gdb/solist.h gdb/somread.c gdb/somsolib.c gdb/somsolib.h gdb/source.c gdb/source.h gdb/sparc-linux-nat.c gdb/sparc-nat.c gdb/sparc-stub.c gdb/sparc-tdep.c gdb/sparc64nbsd-nat.c gdb/sparcl-stub.c gdb/sparcl-tdep.c gdb/sparclet-rom.c gdb/sparclet-stub.c gdb/sparcnbsd-nat.c gdb/sparcnbsd-tdep.c gdb/sparcnbsd-tdep.h gdb/srec.h gdb/stabsread.c gdb/stabsread.h gdb/stack.c gdb/standalone.c gdb/std-regs.c gdb/stop-gdb.c gdb/sun3-nat.c gdb/symfile.c gdb/symfile.h gdb/symm-nat.c gdb/symm-tdep.c gdb/symmisc.c gdb/symtab.c gdb/symtab.h gdb/target.c gdb/target.h gdb/terminal.h gdb/testsuite/.gdbinit gdb/testsuite/Makefile.in gdb/testsuite/TODO gdb/testsuite/aclocal.m4 gdb/testsuite/config/abug.exp gdb/testsuite/config/arm-ice.exp gdb/testsuite/config/cfdbug.exp gdb/testsuite/config/cpu32bug.exp gdb/testsuite/config/cygmon.exp gdb/testsuite/config/d10v.exp gdb/testsuite/config/dve.exp gdb/testsuite/config/est.exp gdb/testsuite/config/gdbserver.exp gdb/testsuite/config/h8300.exp gdb/testsuite/config/hmsirom.exp gdb/testsuite/config/hppro.exp gdb/testsuite/config/i386-bozo.exp gdb/testsuite/config/i960.exp gdb/testsuite/config/m32r-stub.exp gdb/testsuite/config/m32r.exp gdb/testsuite/config/m68k-emc.exp gdb/testsuite/config/mips-idt.exp gdb/testsuite/config/mips.exp gdb/testsuite/config/mn10300-eval.exp gdb/testsuite/config/monitor.exp gdb/testsuite/config/netware.exp gdb/testsuite/config/nind.exp gdb/testsuite/config/proelf.exp gdb/testsuite/config/rom68k.exp gdb/testsuite/config/sh.exp gdb/testsuite/config/sid.exp gdb/testsuite/config/sim.exp gdb/testsuite/config/slite.exp gdb/testsuite/config/sparclet.exp gdb/testsuite/config/udi.exp gdb/testsuite/config/unix.exp gdb/testsuite/config/unknown.exp gdb/testsuite/config/vr4300.exp gdb/testsuite/config/vr5000.exp gdb/testsuite/config/vx.exp gdb/testsuite/config/vxworks.exp gdb/testsuite/config/vxworks29k.exp gdb/testsuite/gdb.asm/Makefile.in gdb/testsuite/gdb.asm/arm.inc gdb/testsuite/gdb.asm/asm-source.exp gdb/testsuite/gdb.asm/asmsrc1.s gdb/testsuite/gdb.asm/asmsrc2.s gdb/testsuite/gdb.asm/common.inc gdb/testsuite/gdb.asm/configure gdb/testsuite/gdb.asm/configure.in gdb/testsuite/gdb.asm/d10v.inc gdb/testsuite/gdb.asm/i386.inc gdb/testsuite/gdb.asm/m32r.inc gdb/testsuite/gdb.asm/powerpc.inc gdb/testsuite/gdb.asm/s390.inc gdb/testsuite/gdb.asm/sparc.inc gdb/testsuite/gdb.asm/sparc64.inc gdb/testsuite/gdb.asm/v850.inc gdb/testsuite/gdb.asm/x86_64.inc gdb/testsuite/gdb.asm/xstormy16.inc gdb/testsuite/gdb.base/Makefile.in gdb/testsuite/gdb.base/a2-run.exp gdb/testsuite/gdb.base/all-types.c gdb/testsuite/gdb.base/annota1.c gdb/testsuite/gdb.base/annota1.exp gdb/testsuite/gdb.base/arithmet.exp gdb/testsuite/gdb.base/assign.exp gdb/testsuite/gdb.base/async.c gdb/testsuite/gdb.base/async.exp gdb/testsuite/gdb.base/attach.c gdb/testsuite/gdb.base/attach.exp gdb/testsuite/gdb.base/attach2.c gdb/testsuite/gdb.base/average.c gdb/testsuite/gdb.base/bar.c gdb/testsuite/gdb.base/baz.c gdb/testsuite/gdb.base/bitfields.c gdb/testsuite/gdb.base/bitfields.exp gdb/testsuite/gdb.base/bitops.exp gdb/testsuite/gdb.base/branches.c gdb/testsuite/gdb.base/break.c gdb/testsuite/gdb.base/break.exp gdb/testsuite/gdb.base/call-ar-st.c gdb/testsuite/gdb.base/call-ar-st.exp gdb/testsuite/gdb.base/call-rt-st.c gdb/testsuite/gdb.base/call-strs.c gdb/testsuite/gdb.base/call-strs.exp gdb/testsuite/gdb.base/callfuncs.c gdb/testsuite/gdb.base/callfuncs.exp gdb/testsuite/gdb.base/code-expr.exp gdb/testsuite/gdb.base/commands.exp gdb/testsuite/gdb.base/cond-expr.exp gdb/testsuite/gdb.base/condbreak.exp gdb/testsuite/gdb.base/configure gdb/testsuite/gdb.base/configure.in gdb/testsuite/gdb.base/consecutive.c gdb/testsuite/gdb.base/consecutive.exp gdb/testsuite/gdb.base/constvars.c gdb/testsuite/gdb.base/constvars.exp gdb/testsuite/gdb.base/corefile.exp gdb/testsuite/gdb.base/coremaker.c gdb/testsuite/gdb.base/coremaker2.c gdb/testsuite/gdb.base/cvexpr.c gdb/testsuite/gdb.base/cvexpr.exp gdb/testsuite/gdb.base/d10v.ld gdb/testsuite/gdb.base/d10vovly.c gdb/testsuite/gdb.base/dbx.exp gdb/testsuite/gdb.base/default.exp gdb/testsuite/gdb.base/define.exp gdb/testsuite/gdb.base/display.c gdb/testsuite/gdb.base/display.exp gdb/testsuite/gdb.base/dump.c gdb/testsuite/gdb.base/dump.exp gdb/testsuite/gdb.base/echo.exp gdb/testsuite/gdb.base/ena-dis-br.exp gdb/testsuite/gdb.base/ending-run.c gdb/testsuite/gdb.base/ending-run.exp gdb/testsuite/gdb.base/environ.exp gdb/testsuite/gdb.base/eval-skip.exp gdb/testsuite/gdb.base/execd-prog.c gdb/testsuite/gdb.base/exprs.c gdb/testsuite/gdb.base/exprs.exp gdb/testsuite/gdb.base/finish.exp gdb/testsuite/gdb.base/foll-exec.c gdb/testsuite/gdb.base/foll-exec.exp gdb/testsuite/gdb.base/foll-fork.c gdb/testsuite/gdb.base/foll-fork.exp gdb/testsuite/gdb.base/foll-vfork.c gdb/testsuite/gdb.base/foll-vfork.exp gdb/testsuite/gdb.base/foo.c gdb/testsuite/gdb.base/funcargs.c gdb/testsuite/gdb.base/funcargs.exp gdb/testsuite/gdb.base/gcore.c gdb/testsuite/gdb.base/gcore.exp gdb/testsuite/gdb.base/gdbvars.exp gdb/testsuite/gdb.base/grbx.c gdb/testsuite/gdb.base/help.exp gdb/testsuite/gdb.base/huge.c gdb/testsuite/gdb.base/huge.exp gdb/testsuite/gdb.base/info-proc.exp gdb/testsuite/gdb.base/int-type.c gdb/testsuite/gdb.base/interrupt.c gdb/testsuite/gdb.base/interrupt.exp gdb/testsuite/gdb.base/jump.c gdb/testsuite/gdb.base/jump.exp gdb/testsuite/gdb.base/langs.exp gdb/testsuite/gdb.base/langs0.c gdb/testsuite/gdb.base/langs1.c gdb/testsuite/gdb.base/langs1.f gdb/testsuite/gdb.base/langs2.c gdb/testsuite/gdb.base/langs2.cxx gdb/testsuite/gdb.base/list.exp gdb/testsuite/gdb.base/list0.c gdb/testsuite/gdb.base/list0.h gdb/testsuite/gdb.base/list1.c gdb/testsuite/gdb.base/logical.exp gdb/testsuite/gdb.base/long_long.c gdb/testsuite/gdb.base/long_long.exp gdb/testsuite/gdb.base/m32r.ld gdb/testsuite/gdb.base/m32rovly.c gdb/testsuite/gdb.base/macscp.exp gdb/testsuite/gdb.base/macscp1.c gdb/testsuite/gdb.base/macscp2.h gdb/testsuite/gdb.base/macscp3.h gdb/testsuite/gdb.base/macscp4.h gdb/testsuite/gdb.base/maint.exp gdb/testsuite/gdb.base/mips_pro.c gdb/testsuite/gdb.base/mips_pro.exp gdb/testsuite/gdb.base/miscexprs.c gdb/testsuite/gdb.base/miscexprs.exp gdb/testsuite/gdb.base/nodebug.c gdb/testsuite/gdb.base/nodebug.exp gdb/testsuite/gdb.base/opaque.exp gdb/testsuite/gdb.base/opaque0.c gdb/testsuite/gdb.base/opaque1.c gdb/testsuite/gdb.base/overlays.c gdb/testsuite/gdb.base/overlays.exp gdb/testsuite/gdb.base/ovlymgr.c gdb/testsuite/gdb.base/ovlymgr.h gdb/testsuite/gdb.base/page.exp gdb/testsuite/gdb.base/pointers.c gdb/testsuite/gdb.base/pointers.exp gdb/testsuite/gdb.base/printcmds.c gdb/testsuite/gdb.base/printcmds.exp gdb/testsuite/gdb.base/ptype.c gdb/testsuite/gdb.base/ptype.exp gdb/testsuite/gdb.base/radix.exp gdb/testsuite/gdb.base/recurse.c gdb/testsuite/gdb.base/recurse.exp gdb/testsuite/gdb.base/regs.exp gdb/testsuite/gdb.base/relational.exp gdb/testsuite/gdb.base/relocate.c gdb/testsuite/gdb.base/relocate.exp gdb/testsuite/gdb.base/remote.c gdb/testsuite/gdb.base/remote.exp gdb/testsuite/gdb.base/reread.exp gdb/testsuite/gdb.base/reread1.c gdb/testsuite/gdb.base/reread2.c gdb/testsuite/gdb.base/restore.c gdb/testsuite/gdb.base/restore.exp gdb/testsuite/gdb.base/return.c gdb/testsuite/gdb.base/return.exp gdb/testsuite/gdb.base/return2.c gdb/testsuite/gdb.base/return2.exp gdb/testsuite/gdb.base/run.c gdb/testsuite/gdb.base/scope.exp gdb/testsuite/gdb.base/scope0.c gdb/testsuite/gdb.base/scope1.c gdb/testsuite/gdb.base/sect-cmd.exp gdb/testsuite/gdb.base/selftest.exp gdb/testsuite/gdb.base/setshow.c gdb/testsuite/gdb.base/setshow.exp gdb/testsuite/gdb.base/setvar.c gdb/testsuite/gdb.base/setvar.exp gdb/testsuite/gdb.base/shlib-call.exp gdb/testsuite/gdb.base/shmain.c gdb/testsuite/gdb.base/shr1.c gdb/testsuite/gdb.base/shr2.c gdb/testsuite/gdb.base/sigall.c gdb/testsuite/gdb.base/sigall.exp gdb/testsuite/gdb.base/signals.c gdb/testsuite/gdb.base/signals.exp gdb/testsuite/gdb.base/sizeof.c gdb/testsuite/gdb.base/sizeof.exp gdb/testsuite/gdb.base/so-impl-ld.c gdb/testsuite/gdb.base/so-impl-ld.exp gdb/testsuite/gdb.base/so-indr-cl.c gdb/testsuite/gdb.base/so-indr-cl.exp gdb/testsuite/gdb.base/solib.c gdb/testsuite/gdb.base/solib.exp gdb/testsuite/gdb.base/solib1.c gdb/testsuite/gdb.base/solib2.c gdb/testsuite/gdb.base/ss.h gdb/testsuite/gdb.base/step-line.c gdb/testsuite/gdb.base/step-line.exp gdb/testsuite/gdb.base/step-line.inp gdb/testsuite/gdb.base/step-test.c gdb/testsuite/gdb.base/step-test.exp gdb/testsuite/gdb.base/structs.c gdb/testsuite/gdb.base/structs.exp gdb/testsuite/gdb.base/structs2.c gdb/testsuite/gdb.base/structs2.exp gdb/testsuite/gdb.base/sum.c gdb/testsuite/gdb.base/term.exp gdb/testsuite/gdb.base/twice.c gdb/testsuite/gdb.base/twice.exp gdb/testsuite/gdb.base/varargs.c gdb/testsuite/gdb.base/varargs.exp gdb/testsuite/gdb.base/vforked-prog.c gdb/testsuite/gdb.base/volatile.exp gdb/testsuite/gdb.base/watchpoint.c gdb/testsuite/gdb.base/watchpoint.exp gdb/testsuite/gdb.base/whatis-exp.exp gdb/testsuite/gdb.base/whatis.c gdb/testsuite/gdb.base/whatis.exp gdb/testsuite/gdb.c++/Makefile.in gdb/testsuite/gdb.c++/ambiguous.cc gdb/testsuite/gdb.c++/ambiguous.exp gdb/testsuite/gdb.c++/annota2.cc gdb/testsuite/gdb.c++/annota2.exp gdb/testsuite/gdb.c++/anon-union.cc gdb/testsuite/gdb.c++/anon-union.exp gdb/testsuite/gdb.c++/classes.exp gdb/testsuite/gdb.c++/configure gdb/testsuite/gdb.c++/configure.in gdb/testsuite/gdb.c++/cplusfuncs.cc gdb/testsuite/gdb.c++/cplusfuncs.exp gdb/testsuite/gdb.c++/ctti.exp gdb/testsuite/gdb.c++/cttiadd.cc gdb/testsuite/gdb.c++/cttiadd1.cc gdb/testsuite/gdb.c++/cttiadd2.cc gdb/testsuite/gdb.c++/cttiadd3.cc gdb/testsuite/gdb.c++/demangle.exp gdb/testsuite/gdb.c++/derivation.cc gdb/testsuite/gdb.c++/derivation.exp gdb/testsuite/gdb.c++/hang.H gdb/testsuite/gdb.c++/hang.exp gdb/testsuite/gdb.c++/hang1.C gdb/testsuite/gdb.c++/hang2.C gdb/testsuite/gdb.c++/hang3.C gdb/testsuite/gdb.c++/local.cc gdb/testsuite/gdb.c++/m-static.cc gdb/testsuite/gdb.c++/m-static.exp gdb/testsuite/gdb.c++/member-ptr.cc gdb/testsuite/gdb.c++/member-ptr.exp gdb/testsuite/gdb.c++/method.cc gdb/testsuite/gdb.c++/method.exp gdb/testsuite/gdb.c++/misc.cc gdb/testsuite/gdb.c++/misc.exp gdb/testsuite/gdb.c++/namespace.cc gdb/testsuite/gdb.c++/namespace.exp gdb/testsuite/gdb.c++/overload.cc gdb/testsuite/gdb.c++/overload.exp gdb/testsuite/gdb.c++/ovldbreak.cc gdb/testsuite/gdb.c++/ovldbreak.exp gdb/testsuite/gdb.c++/ref-types.cc gdb/testsuite/gdb.c++/ref-types.exp gdb/testsuite/gdb.c++/templates.cc gdb/testsuite/gdb.c++/templates.exp gdb/testsuite/gdb.c++/userdef.cc gdb/testsuite/gdb.c++/userdef.exp gdb/testsuite/gdb.c++/virtfunc.cc gdb/testsuite/gdb.c++/virtfunc.exp gdb/testsuite/gdb.chill/ChangeLog gdb/testsuite/gdb.chill/Makefile.in gdb/testsuite/gdb.chill/builtins.ch gdb/testsuite/gdb.chill/builtins.exp gdb/testsuite/gdb.chill/callch.ch gdb/testsuite/gdb.chill/callch.exp gdb/testsuite/gdb.chill/chexp.exp gdb/testsuite/gdb.chill/chillvars.ch gdb/testsuite/gdb.chill/chillvars.exp gdb/testsuite/gdb.chill/configure gdb/testsuite/gdb.chill/configure.in gdb/testsuite/gdb.chill/enum.ch gdb/testsuite/gdb.chill/enum.exp gdb/testsuite/gdb.chill/func1.ch gdb/testsuite/gdb.chill/gch1041.ch gdb/testsuite/gdb.chill/gch1041.exp gdb/testsuite/gdb.chill/gch1272.ch gdb/testsuite/gdb.chill/gch1272.exp gdb/testsuite/gdb.chill/gch1280.ch gdb/testsuite/gdb.chill/gch1280.exp gdb/testsuite/gdb.chill/gch922.ch gdb/testsuite/gdb.chill/gch922.exp gdb/testsuite/gdb.chill/gch981.ch gdb/testsuite/gdb.chill/gch981.exp gdb/testsuite/gdb.chill/misc.ch gdb/testsuite/gdb.chill/misc.exp gdb/testsuite/gdb.chill/powerset.ch gdb/testsuite/gdb.chill/powerset.exp gdb/testsuite/gdb.chill/pr-4975-grt.ch gdb/testsuite/gdb.chill/pr-4975.ch gdb/testsuite/gdb.chill/pr-4975.exp gdb/testsuite/gdb.chill/pr-5016.ch gdb/testsuite/gdb.chill/pr-5016.exp gdb/testsuite/gdb.chill/pr-5020.ch gdb/testsuite/gdb.chill/pr-5020.exp gdb/testsuite/gdb.chill/pr-5022.ch gdb/testsuite/gdb.chill/pr-5022.exp gdb/testsuite/gdb.chill/pr-5646-grt.ch gdb/testsuite/gdb.chill/pr-5646.ch gdb/testsuite/gdb.chill/pr-5646.exp gdb/testsuite/gdb.chill/pr-5984.ch gdb/testsuite/gdb.chill/pr-5984.exp gdb/testsuite/gdb.chill/pr-6292.ch gdb/testsuite/gdb.chill/pr-6292.exp gdb/testsuite/gdb.chill/pr-6632-grt.ch gdb/testsuite/gdb.chill/pr-6632.ch gdb/testsuite/gdb.chill/pr-6632.exp gdb/testsuite/gdb.chill/pr-8134.exp gdb/testsuite/gdb.chill/pr-8136.ch gdb/testsuite/gdb.chill/pr-8136.exp gdb/testsuite/gdb.chill/pr-8405.ch gdb/testsuite/gdb.chill/pr-8405.exp gdb/testsuite/gdb.chill/pr-8742.ch gdb/testsuite/gdb.chill/pr-8742.exp gdb/testsuite/gdb.chill/pr-8894-grt.ch gdb/testsuite/gdb.chill/pr-8894.ch gdb/testsuite/gdb.chill/pr-8894.exp gdb/testsuite/gdb.chill/pr-9095.ch gdb/testsuite/gdb.chill/pr-9095.exp gdb/testsuite/gdb.chill/pr-9946.ch gdb/testsuite/gdb.chill/pr-9946.exp gdb/testsuite/gdb.chill/result.ch gdb/testsuite/gdb.chill/result.exp gdb/testsuite/gdb.chill/string.ch gdb/testsuite/gdb.chill/string.exp gdb/testsuite/gdb.chill/tests1.ch gdb/testsuite/gdb.chill/tests1.exp gdb/testsuite/gdb.chill/tests2.ch gdb/testsuite/gdb.chill/tests2.exp gdb/testsuite/gdb.chill/tuples.ch gdb/testsuite/gdb.chill/tuples.exp gdb/testsuite/gdb.chill/xstruct-grt.ch gdb/testsuite/gdb.chill/xstruct.ch gdb/testsuite/gdb.chill/xstruct.exp gdb/testsuite/gdb.disasm/Makefile.in gdb/testsuite/gdb.disasm/am33.exp gdb/testsuite/gdb.disasm/am33.s gdb/testsuite/gdb.disasm/configure gdb/testsuite/gdb.disasm/configure.in gdb/testsuite/gdb.disasm/h8300s.exp gdb/testsuite/gdb.disasm/h8300s.s gdb/testsuite/gdb.disasm/hppa.exp gdb/testsuite/gdb.disasm/hppa.s gdb/testsuite/gdb.disasm/mn10200.exp gdb/testsuite/gdb.disasm/mn10200.s gdb/testsuite/gdb.disasm/mn10300.exp gdb/testsuite/gdb.disasm/mn10300.s gdb/testsuite/gdb.disasm/sh3.exp gdb/testsuite/gdb.disasm/sh3.s gdb/testsuite/gdb.fortran/exprs.exp gdb/testsuite/gdb.fortran/types.exp gdb/testsuite/gdb.gdb/xfullpath.exp gdb/testsuite/gdb.hp/Makefile.in gdb/testsuite/gdb.hp/configure gdb/testsuite/gdb.hp/configure.in gdb/testsuite/gdb.hp/gdb.aCC/Makefile.in gdb/testsuite/gdb.hp/gdb.aCC/configure gdb/testsuite/gdb.hp/gdb.aCC/configure.in gdb/testsuite/gdb.hp/gdb.aCC/exception.cc gdb/testsuite/gdb.hp/gdb.aCC/exception.exp gdb/testsuite/gdb.hp/gdb.aCC/optimize.c gdb/testsuite/gdb.hp/gdb.aCC/optimize.exp gdb/testsuite/gdb.hp/gdb.aCC/run.c gdb/testsuite/gdb.hp/gdb.aCC/watch-cmd.exp gdb/testsuite/gdb.hp/gdb.base-hp/Makefile.in gdb/testsuite/gdb.hp/gdb.base-hp/callfwmall.c gdb/testsuite/gdb.hp/gdb.base-hp/callfwmall.exp gdb/testsuite/gdb.hp/gdb.base-hp/configure gdb/testsuite/gdb.hp/gdb.base-hp/configure.in gdb/testsuite/gdb.hp/gdb.base-hp/dollar.c gdb/testsuite/gdb.hp/gdb.base-hp/dollar.exp gdb/testsuite/gdb.hp/gdb.base-hp/genso-thresh.c gdb/testsuite/gdb.hp/gdb.base-hp/hwwatchbus.c gdb/testsuite/gdb.hp/gdb.base-hp/hwwatchbus.exp gdb/testsuite/gdb.hp/gdb.base-hp/pxdb.c gdb/testsuite/gdb.hp/gdb.base-hp/pxdb.exp gdb/testsuite/gdb.hp/gdb.base-hp/reg-pa64.exp gdb/testsuite/gdb.hp/gdb.base-hp/reg-pa64.s gdb/testsuite/gdb.hp/gdb.base-hp/reg.exp gdb/testsuite/gdb.hp/gdb.base-hp/reg.s gdb/testsuite/gdb.hp/gdb.base-hp/sized-enum.c gdb/testsuite/gdb.hp/gdb.base-hp/sized-enum.exp gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.exp gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.mk gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.sh gdb/testsuite/gdb.hp/gdb.compat/Makefile.in gdb/testsuite/gdb.hp/gdb.compat/average.c gdb/testsuite/gdb.hp/gdb.compat/configure gdb/testsuite/gdb.hp/gdb.compat/configure.in gdb/testsuite/gdb.hp/gdb.compat/sum.c gdb/testsuite/gdb.hp/gdb.compat/xdb.c gdb/testsuite/gdb.hp/gdb.compat/xdb0.c gdb/testsuite/gdb.hp/gdb.compat/xdb0.h gdb/testsuite/gdb.hp/gdb.compat/xdb1.c gdb/testsuite/gdb.hp/gdb.compat/xdb1.exp gdb/testsuite/gdb.hp/gdb.compat/xdb2.exp gdb/testsuite/gdb.hp/gdb.compat/xdb3.exp gdb/testsuite/gdb.hp/gdb.defects/Makefile.in gdb/testsuite/gdb.hp/gdb.defects/bs14602.c gdb/testsuite/gdb.hp/gdb.defects/bs14602.exp gdb/testsuite/gdb.hp/gdb.defects/bs15503.cc gdb/testsuite/gdb.hp/gdb.defects/bs15503.exp gdb/testsuite/gdb.hp/gdb.defects/configure gdb/testsuite/gdb.hp/gdb.defects/configure.in gdb/testsuite/gdb.hp/gdb.defects/solib-d.c gdb/testsuite/gdb.hp/gdb.defects/solib-d.exp gdb/testsuite/gdb.hp/gdb.defects/solib-d1.c gdb/testsuite/gdb.hp/gdb.defects/solib-d2.c gdb/testsuite/gdb.hp/gdb.objdbg/Makefile.in gdb/testsuite/gdb.hp/gdb.objdbg/configure gdb/testsuite/gdb.hp/gdb.objdbg/configure.in gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01.exp gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x1.cc gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x2.cc gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x3.cc gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x3.h gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02.exp gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x1.cc gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x2.cc gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x3.cc gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03.exp gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x1.cc gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x2.cc gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x3.cc gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04.exp gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x.h gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x1.cc gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x2.cc gdb/testsuite/gdb.hp/gdb.objdbg/tools/symaddr gdb/testsuite/gdb.hp/gdb.objdbg/tools/symaddr.pa64 gdb/testsuite/gdb.hp/gdb.objdbg/tools/test-objdbg.cc gdb/testsuite/gdb.hp/gdb.threads-hp/Makefile.in gdb/testsuite/gdb.hp/gdb.threads-hp/configure gdb/testsuite/gdb.hp/gdb.threads-hp/configure.in gdb/testsuite/gdb.hp/tools/odump gdb/testsuite/gdb.java/Makefile.in gdb/testsuite/gdb.java/configure gdb/testsuite/gdb.java/configure.in gdb/testsuite/gdb.java/jmisc.exp gdb/testsuite/gdb.java/jmisc.java gdb/testsuite/gdb.java/jmisc1.exp gdb/testsuite/gdb.java/jmisc2.exp gdb/testsuite/gdb.java/jv-exp.exp gdb/testsuite/gdb.java/jv-print.exp gdb/testsuite/gdb.mi/ChangeLog gdb/testsuite/gdb.mi/Makefile.in gdb/testsuite/gdb.mi/basics.c gdb/testsuite/gdb.mi/configure gdb/testsuite/gdb.mi/configure.in gdb/testsuite/gdb.mi/mi-basics.exp gdb/testsuite/gdb.mi/mi-break.exp gdb/testsuite/gdb.mi/mi-console.c gdb/testsuite/gdb.mi/mi-console.exp gdb/testsuite/gdb.mi/mi-disassemble.exp gdb/testsuite/gdb.mi/mi-eval.exp gdb/testsuite/gdb.mi/mi-hack-cli.exp gdb/testsuite/gdb.mi/mi-read-memory.c gdb/testsuite/gdb.mi/mi-read-memory.exp gdb/testsuite/gdb.mi/mi-regs.exp gdb/testsuite/gdb.mi/mi-return.exp gdb/testsuite/gdb.mi/mi-simplerun.exp gdb/testsuite/gdb.mi/mi-stack.exp gdb/testsuite/gdb.mi/mi-stepi.exp gdb/testsuite/gdb.mi/mi-until.exp gdb/testsuite/gdb.mi/mi-var-block.exp gdb/testsuite/gdb.mi/mi-var-child.exp gdb/testsuite/gdb.mi/mi-var-cmd.exp gdb/testsuite/gdb.mi/mi-var-display.exp gdb/testsuite/gdb.mi/mi-watch.exp gdb/testsuite/gdb.mi/mi0-basics.exp gdb/testsuite/gdb.mi/mi0-break.exp gdb/testsuite/gdb.mi/mi0-console.exp gdb/testsuite/gdb.mi/mi0-disassemble.exp gdb/testsuite/gdb.mi/mi0-eval.exp gdb/testsuite/gdb.mi/mi0-hack-cli.exp gdb/testsuite/gdb.mi/mi0-read-memory.exp gdb/testsuite/gdb.mi/mi0-regs.exp gdb/testsuite/gdb.mi/mi0-return.exp gdb/testsuite/gdb.mi/mi0-simplerun.exp gdb/testsuite/gdb.mi/mi0-stack.exp gdb/testsuite/gdb.mi/mi0-stepi.exp gdb/testsuite/gdb.mi/mi0-until.exp gdb/testsuite/gdb.mi/mi0-var-block.exp gdb/testsuite/gdb.mi/mi0-var-child.exp gdb/testsuite/gdb.mi/mi0-var-cmd.exp gdb/testsuite/gdb.mi/mi0-var-display.exp gdb/testsuite/gdb.mi/mi0-watch.exp gdb/testsuite/gdb.mi/testcmds gdb/testsuite/gdb.mi/until.c gdb/testsuite/gdb.mi/var-cmd.c gdb/testsuite/gdb.stabs/Makefile.in gdb/testsuite/gdb.stabs/aout.sed gdb/testsuite/gdb.stabs/configure gdb/testsuite/gdb.stabs/configure.in gdb/testsuite/gdb.stabs/ecoff.sed gdb/testsuite/gdb.stabs/hppa.sed gdb/testsuite/gdb.stabs/weird.def gdb/testsuite/gdb.stabs/weird.exp gdb/testsuite/gdb.stabs/xcoff.sed gdb/testsuite/gdb.threads/Makefile.in gdb/testsuite/gdb.threads/config.in gdb/testsuite/gdb.threads/configure gdb/testsuite/gdb.threads/configure.in gdb/testsuite/gdb.threads/gcore-thread.exp gdb/testsuite/gdb.threads/linux-dp.c gdb/testsuite/gdb.threads/linux-dp.exp gdb/testsuite/gdb.threads/pthreads.c gdb/testsuite/gdb.threads/pthreads.exp gdb/testsuite/gdb.threads/step.c gdb/testsuite/gdb.threads/step.exp gdb/testsuite/gdb.threads/step2.exp gdb/testsuite/gdb.trace/Makefile.in gdb/testsuite/gdb.trace/actions.c gdb/testsuite/gdb.trace/actions.exp gdb/testsuite/gdb.trace/backtrace.exp gdb/testsuite/gdb.trace/circ.c gdb/testsuite/gdb.trace/circ.exp gdb/testsuite/gdb.trace/collection.c gdb/testsuite/gdb.trace/collection.exp gdb/testsuite/gdb.trace/configure gdb/testsuite/gdb.trace/configure.in gdb/testsuite/gdb.trace/deltrace.exp gdb/testsuite/gdb.trace/gdb_c_test.c gdb/testsuite/gdb.trace/infotrace.exp gdb/testsuite/gdb.trace/limits.c gdb/testsuite/gdb.trace/limits.exp gdb/testsuite/gdb.trace/packetlen.exp gdb/testsuite/gdb.trace/passc-dyn.exp gdb/testsuite/gdb.trace/passcount.exp gdb/testsuite/gdb.trace/report.exp gdb/testsuite/gdb.trace/save-trace.exp gdb/testsuite/gdb.trace/tfind.exp gdb/testsuite/gdb.trace/tracecmd.exp gdb/testsuite/gdb.trace/while-dyn.exp gdb/testsuite/gdb.trace/while-stepping.exp gdb/testsuite/lib/compiler.c gdb/testsuite/lib/compiler.cc gdb/testsuite/lib/emc-support.exp gdb/testsuite/lib/insight-support.exp gdb/testsuite/lib/java.exp gdb/testsuite/lib/mi-support.exp gdb/testsuite/lib/trace-support.exp gdb/thread-db.c gdb/thread.c gdb/top.h gdb/tracepoint.c gdb/tracepoint.h gdb/tui/ChangeLog gdb/tui/tui-file.c gdb/tui/tui-file.h gdb/tui/tui-hooks.c gdb/tui/tui-out.c gdb/tui/tui.c gdb/tui/tui.h gdb/tui/tuiCommand.c gdb/tui/tuiCommand.h gdb/tui/tuiData.c gdb/tui/tuiData.h gdb/tui/tuiDataWin.c gdb/tui/tuiDataWin.h gdb/tui/tuiDisassem.c gdb/tui/tuiDisassem.h gdb/tui/tuiGeneralWin.c gdb/tui/tuiGeneralWin.h gdb/tui/tuiIO.c gdb/tui/tuiIO.h gdb/tui/tuiLayout.c gdb/tui/tuiLayout.h gdb/tui/tuiRegs.c gdb/tui/tuiRegs.h gdb/tui/tuiSource.c gdb/tui/tuiSource.h gdb/tui/tuiSourceWin.c gdb/tui/tuiSourceWin.h gdb/tui/tuiStack.c gdb/tui/tuiStack.h gdb/tui/tuiWin.c gdb/tui/tuiWin.h gdb/typeprint.c gdb/typeprint.h gdb/ui-file.c gdb/ui-file.h gdb/ui-out.c gdb/ui-out.h gdb/utils.c gdb/uw-thread.c gdb/v850ice.c gdb/valarith.c gdb/valprint.c gdb/valprint.h gdb/varobj.c gdb/varobj.h gdb/vax-tdep.c gdb/vax-tdep.h gdb/version.h gdb/vx-share/README gdb/vx-share/dbgRpcLib.h gdb/vx-share/ptrace.h gdb/vx-share/regPacket.h gdb/vx-share/vxTypes.h gdb/vx-share/vxWorks.h gdb/vx-share/wait.h gdb/vx-share/xdr_ld.c gdb/vx-share/xdr_ld.h gdb/vx-share/xdr_ptrace.c gdb/vx-share/xdr_ptrace.h gdb/vx-share/xdr_rdb.c gdb/vx-share/xdr_rdb.h gdb/w89k-rom.c gdb/win32-nat.c gdb/wince-stub.c gdb/wince-stub.h gdb/wince.c gdb/x86-64-linux-nat.c gdb/x86-64-linux-tdep.c gdb/x86-64-tdep.h gdb/xcoffread.c gdb/xcoffsolib.c gdb/xcoffsolib.h gdb/xmodem.c gdb/xmodem.h gdb/xstormy16-tdep.c gdb/z8k-tdep.c gettext.m4 include/COPYING include/MAINTAINERS include/alloca-conf.h include/ansidecl.h include/aout/ChangeLog include/aout/adobe.h include/aout/aout64.h include/aout/ar.h include/aout/dynix3.h include/aout/encap.h include/aout/host.h include/aout/hp.h include/aout/hp300hpux.h include/aout/hppa.h include/aout/ranlib.h include/aout/reloc.h include/aout/stab.def include/aout/stab_gnu.h include/aout/sun4.h include/bin-bugs.h include/bout.h include/callback.h include/coff/ChangeLog include/coff/a29k.h include/coff/alpha.h include/coff/apollo.h include/coff/arm.h include/coff/aux-coff.h include/coff/ecoff.h include/coff/external.h include/coff/go32exe.h include/coff/h8300.h include/coff/h8500.h include/coff/i386.h include/coff/i860.h include/coff/i960.h include/coff/ia64.h include/coff/internal.h include/coff/m68k.h include/coff/m88k.h include/coff/mcore.h include/coff/mips.h include/coff/mipspe.h include/coff/or32.h include/coff/pe.h include/coff/powerpc.h include/coff/rs6000.h include/coff/rs6k64.h include/coff/sh.h include/coff/sparc.h include/coff/sym.h include/coff/symconst.h include/coff/ti.h include/coff/tic30.h include/coff/tic54x.h include/coff/tic80.h include/coff/w65.h include/coff/we32k.h include/coff/xcoff.h include/coff/z8k.h include/demangle.h include/dyn-string.h include/elf/alpha.h include/elf/arc.h include/elf/arm.h include/elf/avr.h include/elf/cris.h include/elf/d10v.h include/elf/d30v.h include/elf/dwarf.h include/elf/dwarf2.h include/elf/external.h include/elf/fr30.h include/elf/h8.h include/elf/hppa.h include/elf/i370.h include/elf/i860.h include/elf/i960.h include/elf/internal.h include/elf/m32r.h include/elf/m68hc11.h include/elf/m68k.h include/elf/mcore.h include/elf/mips.h include/elf/mmix.h include/elf/mn10200.h include/elf/mn10300.h include/elf/openrisc.h include/elf/or32.h include/elf/pj.h include/elf/ppc.h include/elf/reloc-macros.h include/elf/s390.h include/elf/sh.h include/elf/sparc.h include/elf/v850.h include/elf/vax.h include/elf/x86-64.h include/elf/xstormy16.h include/fibheap.h include/filenames.h include/floatformat.h include/fnmatch.h include/fopen-bin.h include/fopen-same.h include/fopen-vms.h include/gdb/callback.h include/gdb/remote-sim.h include/gdb/signals.h include/gdb/sim-sh.h include/gdbm.h include/getopt.h include/hashtab.h include/hp-symtab.h include/ieee.h include/libiberty.h include/md5.h include/mpw/ChangeLog include/mpw/README include/mpw/dir.h include/mpw/dirent.h include/mpw/fcntl.h include/mpw/grp.h include/mpw/mpw.h include/mpw/pwd.h include/mpw/spin.h include/mpw/stat.h include/mpw/sys/file.h include/mpw/sys/param.h include/mpw/sys/resource.h include/mpw/sys/stat.h include/mpw/sys/time.h include/mpw/sys/types.h include/mpw/utime.h include/mpw/varargs.h include/nlm/ChangeLog include/nlm/alpha-ext.h include/nlm/common.h include/nlm/external.h include/nlm/i386-ext.h include/nlm/internal.h include/nlm/ppc-ext.h include/nlm/sparc32-ext.h include/oasys.h include/objalloc.h include/obstack.h include/opcode/a29k.h include/opcode/alpha.h include/opcode/arc.h include/opcode/arm.h include/opcode/avr.h include/opcode/cgen.h include/opcode/convex.h include/opcode/cris.h include/opcode/d10v.h include/opcode/d30v.h include/opcode/hppa.h include/opcode/i370.h include/opcode/i386.h include/opcode/i860.h include/opcode/i960.h include/opcode/m68hc11.h include/opcode/m68k.h include/opcode/m88k.h include/opcode/mmix.h include/opcode/mn10200.h include/opcode/mn10300.h include/opcode/np1.h include/opcode/ns32k.h include/opcode/or32.h include/opcode/pdp11.h include/opcode/pj.h include/opcode/pn.h include/opcode/ppc.h include/opcode/pyr.h include/opcode/s390.h include/opcode/tahoe.h include/opcode/tic30.h include/opcode/tic54x.h include/opcode/tic80.h include/opcode/v850.h include/opcode/vax.h include/os9k.h include/partition.h include/progress.h include/regs/ChangeLog include/remote-sim.h include/safe-ctype.h include/sort.h include/splay-tree.h include/symcat.h include/ternary.h include/xregex.h include/xregex2.h install-sh intl/ChangeLog intl/Makefile.in intl/acconfig.h intl/aclocal.m4 intl/bindtextdom.c intl/cat-compat.c intl/config.in intl/configure intl/configure.in intl/dcgettext.c intl/dgettext.c intl/explodename.c intl/finddomain.c intl/gettext.c intl/gettext.h intl/gettextP.h intl/hash-string.h intl/intl-compat.c intl/intlh.inst.in intl/l10nflist.c intl/libgettext.h intl/libintl.glibc intl/linux-msg.sed intl/loadinfo.h intl/loadmsgcat.c intl/localealias.c intl/po2tbl.sed.in intl/textdomain.c intl/xopen-msg.sed libiberty/COPYING.LIB libiberty/Makefile.in libiberty/README libiberty/_doprnt.c libiberty/aclocal.m4 libiberty/alloca.c libiberty/argv.c libiberty/asprintf.c libiberty/atexit.c libiberty/basename.c libiberty/bcmp.c libiberty/bcopy.c libiberty/bsearch.c libiberty/bzero.c libiberty/calloc.c libiberty/choose-temp.c libiberty/clock.c libiberty/concat.c libiberty/config.h-vms libiberty/config.in libiberty/config/mh-aix libiberty/config/mh-cxux7 libiberty/config/mh-fbsd21 libiberty/config/mh-openedition libiberty/config/mh-windows libiberty/configure libiberty/configure.in libiberty/copying-lib.texi libiberty/copysign.c libiberty/cp-demangle.c libiberty/cplus-dem.c libiberty/dyn-string.c libiberty/fdmatch.c libiberty/ffs.c libiberty/fibheap.c libiberty/floatformat.c libiberty/fnmatch.c libiberty/fnmatch.txh libiberty/functions.texi libiberty/gather-docs libiberty/getcwd.c libiberty/getopt.c libiberty/getopt1.c libiberty/getpagesize.c libiberty/getpwd.c libiberty/getruntime.c libiberty/hashtab.c libiberty/hex.c libiberty/index.c libiberty/insque.c libiberty/lbasename.c libiberty/libiberty.texi libiberty/maint-tool libiberty/make-temp-file.c libiberty/makefile.vms libiberty/md5.c libiberty/memchr.c libiberty/memcmp.c libiberty/memcpy.c libiberty/memmove.c libiberty/memset.c libiberty/mkstemps.c libiberty/mpw-config.in libiberty/mpw-make.sed libiberty/mpw.c libiberty/msdos.c libiberty/objalloc.c libiberty/obstack.c libiberty/obstacks.texi libiberty/partition.c libiberty/pexecute.c libiberty/putenv.c libiberty/random.c libiberty/regex.c libiberty/rename.c libiberty/rindex.c libiberty/safe-ctype.c libiberty/setenv.c libiberty/sigsetmask.c libiberty/sort.c libiberty/spaces.c libiberty/splay-tree.c libiberty/strcasecmp.c libiberty/strchr.c libiberty/strdup.c libiberty/strerror.c libiberty/strncasecmp.c libiberty/strncmp.c libiberty/strrchr.c libiberty/strsignal.c libiberty/strstr.c libiberty/strtod.c libiberty/strtol.c libiberty/strtoul.c libiberty/ternary.c libiberty/testsuite/Makefile.in libiberty/testsuite/demangle-expected libiberty/testsuite/regress-demangle libiberty/tmpnam.c libiberty/vasprintf.c libiberty/vfork.c libiberty/vfprintf.c libiberty/vmsbuild.com libiberty/vprintf.c libiberty/vsprintf.c libiberty/waitpid.c libiberty/xatexit.c libiberty/xexit.c libiberty/xmalloc.c libiberty/xmemdup.c libiberty/xstrdup.c libiberty/xstrerror.c libtool.m4 ltcf-c.sh ltcf-cxx.sh ltcf-gcj.sh ltconfig ltmain.sh makefile.vms missing mkdep mkinstalldirs mmalloc/COPYING.LIB mmalloc/ChangeLog mmalloc/MAINTAINERS mmalloc/Makefile.in mmalloc/TODO mmalloc/acinclude.m4 mmalloc/aclocal.m4 mmalloc/attach.c mmalloc/configure mmalloc/configure.in mmalloc/detach.c mmalloc/keys.c mmalloc/mcalloc.c mmalloc/mfree.c mmalloc/mm.c mmalloc/mmalloc.c mmalloc/mmalloc.h mmalloc/mmalloc.texi mmalloc/mmap-sup.c mmalloc/mmcheck.c mmalloc/mmemalign.c mmalloc/mmprivate.h mmalloc/mmstats.c mmalloc/mmtrace.awk mmalloc/mmtrace.c mmalloc/mrealloc.c mmalloc/mvalloc.c mmalloc/sbrk-sup.c move-if-change mpw-README mpw-build.in mpw-config.in mpw-configure mpw-install opcodes/ChangeLog-9297 opcodes/ChangeLog-9899 opcodes/MAINTAINERS opcodes/a29k-dis.c opcodes/alpha-dis.c opcodes/alpha-opc.c opcodes/arc-dis.h opcodes/arc-ext.c opcodes/arc-ext.h opcodes/arc-opc.c opcodes/arm-opc.h opcodes/avr-dis.c opcodes/cgen-asm.c opcodes/cgen-asm.in opcodes/cgen-dis.c opcodes/cgen-dis.in opcodes/cgen-ibld.in opcodes/cgen-opc.c opcodes/cgen.sh opcodes/config.in opcodes/cris-dis.c opcodes/cris-opc.c opcodes/d10v-dis.c opcodes/d10v-opc.c opcodes/d30v-dis.c opcodes/d30v-opc.c opcodes/dep-in.sed opcodes/dis-buf.c opcodes/fr30-desc.h opcodes/fr30-ibld.c opcodes/fr30-opc.c opcodes/fr30-opc.h opcodes/h8300-dis.c opcodes/h8500-dis.c opcodes/h8500-opc.h opcodes/hppa-dis.c opcodes/i370-dis.c opcodes/i370-opc.c opcodes/i386-dis.c opcodes/i860-dis.c opcodes/i960-dis.c opcodes/ia64-asmtab.c opcodes/ia64-asmtab.h opcodes/ia64-dis.c opcodes/ia64-gen.c opcodes/ia64-ic.tbl opcodes/ia64-opc-a.c opcodes/ia64-opc-b.c opcodes/ia64-opc-d.c opcodes/ia64-opc-f.c opcodes/ia64-opc-i.c opcodes/ia64-opc-m.c opcodes/ia64-opc-x.c opcodes/ia64-opc.c opcodes/ia64-opc.h opcodes/ia64-raw.tbl opcodes/ia64-war.tbl opcodes/ia64-waw.tbl opcodes/m10200-dis.c opcodes/m10200-opc.c opcodes/m10300-dis.c opcodes/m10300-opc.c opcodes/m32r-desc.h opcodes/m32r-ibld.c opcodes/m32r-opc.c opcodes/m32r-opc.h opcodes/m32r-opinst.c opcodes/m68hc11-dis.c opcodes/m68hc11-opc.c opcodes/m68k-opc.c opcodes/m88k-dis.c opcodes/makefile.vms opcodes/mcore-dis.c opcodes/mcore-opc.h opcodes/mips16-opc.c opcodes/mmix-dis.c opcodes/mmix-opc.c opcodes/mpw-config.in opcodes/mpw-make.sed opcodes/ns32k-dis.c opcodes/openrisc-desc.h opcodes/openrisc-ibld.c opcodes/openrisc-opc.c opcodes/openrisc-opc.h opcodes/opintl.h opcodes/or32-dis.c opcodes/or32-opc.c opcodes/pdp11-dis.c opcodes/pdp11-opc.c opcodes/pj-dis.c opcodes/pj-opc.c opcodes/po/.cvsignore opcodes/po/Make-in opcodes/po/POTFILES.in opcodes/po/da.po opcodes/po/de.po opcodes/po/es.po opcodes/po/fr.po opcodes/po/id.po opcodes/po/opcodes.pot opcodes/po/sv.po opcodes/po/tr.po opcodes/ppc-dis.c opcodes/ppc-opc.c opcodes/s390-dis.c opcodes/s390-mkopc.c opcodes/s390-opc.c opcodes/s390-opc.txt opcodes/sh-opc.h opcodes/sh64-opc.c opcodes/sh64-opc.h opcodes/sparc-dis.c opcodes/sparc-opc.c opcodes/stamp-h.in opcodes/sysdep.h opcodes/tic30-dis.c opcodes/tic54x-dis.c opcodes/tic54x-opc.c opcodes/tic80-dis.c opcodes/tic80-opc.c opcodes/v850-dis.c opcodes/v850-opc.c opcodes/vax-dis.c opcodes/w65-dis.c opcodes/w65-opc.h opcodes/xstormy16-desc.h opcodes/xstormy16-ibld.c opcodes/xstormy16-opc.c opcodes/xstormy16-opc.h opcodes/z8k-dis.c opcodes/z8k-opc.h opcodes/z8kgen.c readline/CHANGELOG readline/CHANGES readline/COPYING readline/ChangeLog.gdb readline/INSTALL readline/MANIFEST readline/Makefile.in readline/README readline/USAGE readline/acconfig.h readline/aclocal.m4 readline/ansi_stdlib.h readline/bind.c readline/callback.c readline/chardefs.h readline/complete.c readline/config.h.bot readline/config.h.in readline/configure readline/configure.in readline/cross-build/cygwin.cache readline/display.c readline/doc/ChangeLog.gdb readline/doc/Makefile.in readline/doc/hist.texinfo readline/doc/hstech.texinfo readline/doc/hsuser.texinfo readline/doc/inc-hist.texinfo readline/doc/manvers.texinfo readline/doc/readline.3 readline/doc/rlman.texinfo readline/doc/rltech.texinfo readline/doc/rluser.texinfo readline/doc/rluserman.texinfo readline/doc/texi2dvi readline/doc/texi2html readline/emacs_keymap.c readline/examples/ChangeLog.gdb readline/examples/Inputrc readline/examples/Makefile.in readline/examples/excallback.c readline/examples/fileman.c readline/examples/histexamp.c readline/examples/manexamp.c readline/examples/rl.c readline/examples/rlfe.c readline/examples/rltest.c readline/examples/rlversion.c readline/funmap.c readline/histexpand.c readline/histfile.c readline/histlib.h readline/history.c readline/history.h readline/histsearch.c readline/input.c readline/isearch.c readline/keymaps.c readline/keymaps.h readline/kill.c readline/macro.c readline/nls.c readline/parens.c readline/posixdir.h readline/posixjmp.h readline/posixstat.h readline/readline.c readline/readline.h readline/rlconf.h readline/rldefs.h readline/rlprivate.h readline/rlshell.h readline/rlstdc.h readline/rltty.c readline/rltty.h readline/rlwinsize.h readline/savestring.c readline/search.c readline/shell.c readline/shlib/Makefile.in readline/signals.c readline/support/config.guess readline/support/config.sub readline/support/install.sh readline/support/mkdirs readline/support/mkdist readline/support/shlib-install readline/support/shobj-conf readline/tcap.h readline/terminal.c readline/tilde.c readline/tilde.h readline/undo.c readline/util.c readline/vi_keymap.c readline/vi_mode.c readline/xmalloc.c readline/xmalloc.h setup.com sim/Makefile.in sim/README-HACKING sim/arm/COPYING sim/arm/README.Cygnus sim/arm/acconfig.h sim/arm/armdefs.h sim/arm/armemu.h sim/arm/armfpe.h sim/arm/arminit.c sim/arm/armopts.h sim/arm/armos.h sim/arm/armrdi.c sim/arm/bag.c sim/arm/bag.h sim/arm/communicate.c sim/arm/communicate.h sim/arm/config.in sim/arm/configure sim/arm/configure.in sim/arm/dbg_conf.h sim/arm/dbg_cp.h sim/arm/dbg_hif.h sim/arm/gdbhost.c sim/arm/gdbhost.h sim/arm/kid.c sim/arm/main.c sim/arm/parent.c sim/arm/tconfig.in sim/common/Make-common.in sim/common/Makefile.in sim/common/acconfig.h sim/common/aclocal.m4 sim/common/callback.c sim/common/cgen-accfp.c sim/common/cgen-cpu.h sim/common/cgen-defs.h sim/common/cgen-engine.h sim/common/cgen-fpu.c sim/common/cgen-fpu.h sim/common/cgen-mem.h sim/common/cgen-ops.h sim/common/cgen-par.c sim/common/cgen-par.h sim/common/cgen-run.c sim/common/cgen-scache.c sim/common/cgen-scache.h sim/common/cgen-sim.h sim/common/cgen-trace.c sim/common/cgen-trace.h sim/common/cgen-types.h sim/common/cgen-utils.c sim/common/cgen.sh sim/common/config.in sim/common/configure sim/common/configure.in sim/common/dv-core.c sim/common/dv-glue.c sim/common/dv-pal.c sim/common/dv-sockser.c sim/common/dv-sockser.h sim/common/gdbinit.in sim/common/genmloop.sh sim/common/gennltvals.sh sim/common/gentmap.c sim/common/gentvals.sh sim/common/hw-alloc.c sim/common/hw-alloc.h sim/common/hw-base.c sim/common/hw-base.h sim/common/hw-device.c sim/common/hw-device.h sim/common/hw-events.c sim/common/hw-events.h sim/common/hw-handles.c sim/common/hw-handles.h sim/common/hw-instances.c sim/common/hw-instances.h sim/common/hw-main.h sim/common/hw-ports.c sim/common/hw-ports.h sim/common/hw-properties.c sim/common/hw-properties.h sim/common/hw-tree.c sim/common/hw-tree.h sim/common/nltvals.def sim/common/nrun.c sim/common/run.1 sim/common/sim-abort.c sim/common/sim-alu.h sim/common/sim-arange.c sim/common/sim-arange.h sim/common/sim-assert.h sim/common/sim-base.h sim/common/sim-basics.h sim/common/sim-bits.c sim/common/sim-bits.h sim/common/sim-break.c sim/common/sim-break.h sim/common/sim-config.c sim/common/sim-config.h sim/common/sim-core.c sim/common/sim-core.h sim/common/sim-cpu.c sim/common/sim-cpu.h sim/common/sim-endian.c sim/common/sim-endian.h sim/common/sim-engine.c sim/common/sim-engine.h sim/common/sim-events.c sim/common/sim-events.h sim/common/sim-fpu.c sim/common/sim-fpu.h sim/common/sim-hload.c sim/common/sim-hrw.c sim/common/sim-hw.c sim/common/sim-hw.h sim/common/sim-info.c sim/common/sim-inline.c sim/common/sim-inline.h sim/common/sim-io.c sim/common/sim-io.h sim/common/sim-load.c sim/common/sim-memopt.c sim/common/sim-memopt.h sim/common/sim-model.c sim/common/sim-model.h sim/common/sim-module.c sim/common/sim-module.h sim/common/sim-n-bits.h sim/common/sim-n-core.h sim/common/sim-n-endian.h sim/common/sim-options.h sim/common/sim-profile.c sim/common/sim-profile.h sim/common/sim-reason.c sim/common/sim-reg.c sim/common/sim-resume.c sim/common/sim-run.c sim/common/sim-signal.c sim/common/sim-signal.h sim/common/sim-stop.c sim/common/sim-trace.c sim/common/sim-trace.h sim/common/sim-types.h sim/common/sim-utils.c sim/common/sim-utils.h sim/common/sim-watch.c sim/common/sim-watch.h sim/common/syscall.c sim/common/tconfig.in sim/configure sim/configure.in sim/d10v/acconfig.h sim/d10v/config.in sim/d10v/configure sim/d10v/configure.in sim/d10v/d10v_sim.h sim/d10v/endian.c sim/d10v/gencode.c sim/d30v/ChangeLog sim/d30v/Makefile.in sim/d30v/acconfig.h sim/d30v/alu.h sim/d30v/config.in sim/d30v/configure sim/d30v/configure.in sim/d30v/cpu.c sim/d30v/cpu.h sim/d30v/d30v-insns sim/d30v/dc-short sim/d30v/engine.c sim/d30v/ic-d30v sim/d30v/sim-calls.c sim/d30v/sim-main.h sim/d30v/tconfig.in sim/erc32/ChangeLog sim/erc32/Makefile.in sim/erc32/NEWS sim/erc32/README.erc32 sim/erc32/README.gdb sim/erc32/README.sis sim/erc32/acconfig.h sim/erc32/config.in sim/erc32/configure sim/erc32/configure.in sim/erc32/end.c sim/erc32/erc32.c sim/erc32/exec.c sim/erc32/float.c sim/erc32/func.c sim/erc32/help.c sim/erc32/interf.c sim/erc32/sis.c sim/erc32/sis.h sim/erc32/startsim sim/fr30/ChangeLog sim/fr30/Makefile.in sim/fr30/README sim/fr30/TODO sim/fr30/arch.c sim/fr30/arch.h sim/fr30/config.in sim/fr30/configure sim/fr30/configure.in sim/fr30/cpu.c sim/fr30/cpu.h sim/fr30/cpuall.h sim/fr30/decode.c sim/fr30/decode.h sim/fr30/devices.c sim/fr30/fr30-sim.h sim/fr30/fr30.c sim/fr30/mloop.in sim/fr30/model.c sim/fr30/sem-switch.c sim/fr30/sem.c sim/fr30/sim-if.c sim/fr30/sim-main.h sim/fr30/tconfig.in sim/fr30/traps.c sim/h8300/Makefile.in sim/h8300/acconfig.h sim/h8300/config.in sim/h8300/configure sim/h8300/configure.in sim/h8300/tconfig.in sim/h8300/writecode.c sim/h8500/ChangeLog sim/h8500/Makefile.in sim/h8500/acconfig.h sim/h8500/compile.c sim/h8500/config.in sim/h8500/configure sim/h8500/configure.in sim/h8500/inst.h sim/h8500/tconfig.in sim/i960/ChangeLog sim/i960/Makefile.in sim/i960/README sim/i960/TODO sim/i960/acconfig.h sim/i960/arch.c sim/i960/arch.h sim/i960/config.in sim/i960/configure sim/i960/configure.in sim/i960/cpu.c sim/i960/cpu.h sim/i960/cpuall.h sim/i960/decode.c sim/i960/decode.h sim/i960/devices.c sim/i960/i960-desc.c sim/i960/i960-desc.h sim/i960/i960-opc.h sim/i960/i960-sim.h sim/i960/i960.c sim/i960/mloop.in sim/i960/model.c sim/i960/sem-switch.c sim/i960/sem.c sim/i960/sim-if.c sim/i960/sim-main.h sim/i960/tconfig.in sim/i960/traps.c sim/igen/ChangeLog sim/igen/Makefile.in sim/igen/acconfig.h sim/igen/config.in sim/igen/configure sim/igen/configure.in sim/igen/filter.c sim/igen/filter.h sim/igen/filter_host.c sim/igen/filter_host.h sim/igen/gen-engine.c sim/igen/gen-engine.h sim/igen/gen-icache.c sim/igen/gen-icache.h sim/igen/gen-idecode.c sim/igen/gen-idecode.h sim/igen/gen-itable.c sim/igen/gen-itable.h sim/igen/gen-model.c sim/igen/gen-model.h sim/igen/gen-semantics.c sim/igen/gen-semantics.h sim/igen/gen-support.c sim/igen/gen-support.h sim/igen/gen.c sim/igen/gen.h sim/igen/igen.c sim/igen/igen.h sim/igen/ld-cache.c sim/igen/ld-cache.h sim/igen/ld-decode.c sim/igen/ld-decode.h sim/igen/ld-insn.c sim/igen/ld-insn.h sim/igen/lf.c sim/igen/lf.h sim/igen/misc.c sim/igen/misc.h sim/igen/table.c sim/igen/table.h sim/m32r/ChangeLog sim/m32r/Makefile.in sim/m32r/README sim/m32r/TODO sim/m32r/acconfig.h sim/m32r/arch.c sim/m32r/arch.h sim/m32r/config.in sim/m32r/configure sim/m32r/configure.in sim/m32r/cpu.c sim/m32r/cpu.h sim/m32r/cpuall.h sim/m32r/cpux.c sim/m32r/cpux.h sim/m32r/decode.c sim/m32r/decode.h sim/m32r/decodex.c sim/m32r/decodex.h sim/m32r/devices.c sim/m32r/m32r-sim.h sim/m32r/m32r.c sim/m32r/m32rx.c sim/m32r/mloop.in sim/m32r/mloopx.in sim/m32r/model.c sim/m32r/modelx.c sim/m32r/sem-switch.c sim/m32r/sem.c sim/m32r/semx-switch.c sim/m32r/sim-if.c sim/m32r/sim-main.h sim/m32r/tconfig.in sim/m32r/traps.c sim/m68hc11/ChangeLog sim/m68hc11/Makefile.in sim/m68hc11/config.in sim/m68hc11/configure sim/m68hc11/configure.in sim/m68hc11/dv-m68hc11.c sim/m68hc11/dv-m68hc11eepr.c sim/m68hc11/dv-m68hc11sio.c sim/m68hc11/dv-m68hc11spi.c sim/m68hc11/dv-m68hc11tim.c sim/m68hc11/dv-nvram.c sim/m68hc11/emulos.c sim/m68hc11/gencode.c sim/m68hc11/interp.c sim/m68hc11/interrupts.c sim/m68hc11/interrupts.h sim/m68hc11/m68hc11_sim.c sim/m68hc11/sim-main.h sim/mcore/ChangeLog sim/mcore/Makefile.in sim/mcore/config.in sim/mcore/configure sim/mcore/configure.in sim/mcore/interp.c sim/mcore/sysdep.h sim/mips/ChangeLog sim/mips/Makefile.in sim/mips/acconfig.h sim/mips/config.in sim/mips/configure sim/mips/configure.in sim/mips/cp1.c sim/mips/cp1.h sim/mips/dv-tx3904cpu.c sim/mips/dv-tx3904irc.c sim/mips/dv-tx3904sio.c sim/mips/dv-tx3904tmr.c sim/mips/interp.c sim/mips/m16.dc sim/mips/m16.igen sim/mips/m16run.c sim/mips/mdmx.igen sim/mips/mips.dc sim/mips/mips.igen sim/mips/mips3d.igen sim/mips/sb1.igen sim/mips/sim-main.c sim/mips/sim-main.h sim/mips/tconfig.in sim/mips/tx.igen sim/mips/vr.igen sim/mn10200/ChangeLog sim/mn10200/Makefile.in sim/mn10200/acconfig.h sim/mn10200/config.in sim/mn10200/configure sim/mn10200/configure.in sim/mn10200/gencode.c sim/mn10200/interp.c sim/mn10200/mn10200_sim.h sim/mn10200/simops.c sim/mn10300/ChangeLog sim/mn10300/Makefile.in sim/mn10300/acconfig.h sim/mn10300/am33.igen sim/mn10300/config.in sim/mn10300/configure sim/mn10300/configure.in sim/mn10300/dv-mn103cpu.c sim/mn10300/dv-mn103int.c sim/mn10300/dv-mn103iop.c sim/mn10300/dv-mn103ser.c sim/mn10300/dv-mn103tim.c sim/mn10300/gencode.c sim/mn10300/interp.c sim/mn10300/mn10300.dc sim/mn10300/mn10300.igen sim/mn10300/mn10300_sim.h sim/mn10300/op_utils.c sim/mn10300/sim-main.c sim/mn10300/sim-main.h sim/mn10300/simops.c sim/mn10300/tconfig.in sim/ppc/.gdbinit sim/ppc/BUGS sim/ppc/COPYING sim/ppc/COPYING.LIB sim/ppc/ChangeLog sim/ppc/ChangeLog.00 sim/ppc/INSTALL sim/ppc/Makefile.in sim/ppc/README sim/ppc/RUN sim/ppc/acconfig.h sim/ppc/aclocal.m4 sim/ppc/basics.h sim/ppc/bits.c sim/ppc/bits.h sim/ppc/cap.c sim/ppc/cap.h sim/ppc/config.in sim/ppc/configure sim/ppc/configure.in sim/ppc/corefile-n.h sim/ppc/corefile.c sim/ppc/corefile.h sim/ppc/cpu.c sim/ppc/cpu.h sim/ppc/dc-complex sim/ppc/dc-simple sim/ppc/dc-stupid sim/ppc/dc-test.01 sim/ppc/dc-test.02 sim/ppc/debug.c sim/ppc/debug.h sim/ppc/device.c sim/ppc/device.h sim/ppc/device_table.c sim/ppc/device_table.h sim/ppc/dgen.c sim/ppc/double.c sim/ppc/dp-bit.c sim/ppc/emul_bugapi.c sim/ppc/emul_bugapi.h sim/ppc/emul_chirp.c sim/ppc/emul_chirp.h sim/ppc/emul_generic.c sim/ppc/emul_generic.h sim/ppc/emul_netbsd.c sim/ppc/emul_netbsd.h sim/ppc/emul_unix.c sim/ppc/emul_unix.h sim/ppc/events.c sim/ppc/events.h sim/ppc/filter.c sim/ppc/filter.h sim/ppc/filter_filename.c sim/ppc/filter_filename.h sim/ppc/gen-icache.c sim/ppc/gen-icache.h sim/ppc/gen-idecode.c sim/ppc/gen-idecode.h sim/ppc/gen-itable.c sim/ppc/gen-itable.h sim/ppc/gen-model.c sim/ppc/gen-model.h sim/ppc/gen-semantics.c sim/ppc/gen-semantics.h sim/ppc/gen-support.c sim/ppc/gen-support.h sim/ppc/hw_com.c sim/ppc/hw_core.c sim/ppc/hw_cpu.c sim/ppc/hw_cpu.h sim/ppc/hw_disk.c sim/ppc/hw_eeprom.c sim/ppc/hw_glue.c sim/ppc/hw_htab.c sim/ppc/hw_ide.c sim/ppc/hw_init.c sim/ppc/hw_iobus.c sim/ppc/hw_memory.c sim/ppc/hw_nvram.c sim/ppc/hw_opic.c sim/ppc/hw_pal.c sim/ppc/hw_phb.c sim/ppc/hw_phb.h sim/ppc/hw_register.c sim/ppc/hw_trace.c sim/ppc/hw_vm.c sim/ppc/idecode_branch.h sim/ppc/idecode_expression.h sim/ppc/idecode_fields.h sim/ppc/igen.c sim/ppc/igen.h sim/ppc/inline.c sim/ppc/inline.h sim/ppc/interrupts.c sim/ppc/interrupts.h sim/ppc/ld-cache.c sim/ppc/ld-cache.h sim/ppc/ld-decode.c sim/ppc/ld-decode.h sim/ppc/ld-insn.c sim/ppc/ld-insn.h sim/ppc/lf.c sim/ppc/lf.h sim/ppc/main.c sim/ppc/misc.c sim/ppc/misc.h sim/ppc/mon.c sim/ppc/mon.h sim/ppc/options.c sim/ppc/options.h sim/ppc/os_emul.c sim/ppc/os_emul.h sim/ppc/pk_disklabel.c sim/ppc/ppc-cache-rules sim/ppc/ppc-instructions sim/ppc/ppc-spr-table sim/ppc/ppc.mt sim/ppc/psim.c sim/ppc/psim.h sim/ppc/psim.texinfo sim/ppc/registers.c sim/ppc/registers.h sim/ppc/sim-endian-n.h sim/ppc/sim-endian.c sim/ppc/sim-endian.h sim/ppc/sim-main.h sim/ppc/sim_callbacks.h sim/ppc/sim_calls.c sim/ppc/std-config.h sim/ppc/table.c sim/ppc/table.h sim/ppc/tree.c sim/ppc/tree.h sim/ppc/vm.c sim/ppc/vm.h sim/ppc/vm_n.h sim/ppc/words.h sim/sh/ChangeLog sim/sh/Makefile.in sim/sh/acconfig.h sim/sh/config.in sim/sh/configure sim/sh/configure.in sim/sh/gencode.c sim/sh/interp.c sim/sh/syscall.h sim/sh/tconfig.in sim/testsuite/ChangeLog sim/testsuite/Makefile.in sim/testsuite/common/Make-common.in sim/testsuite/common/Makefile.in sim/testsuite/common/alu-n-tst.h sim/testsuite/common/alu-tst.c sim/testsuite/common/bits-gen.c sim/testsuite/common/bits-tst.c sim/testsuite/common/fpu-tst.c sim/testsuite/config/default.exp sim/testsuite/configure sim/testsuite/configure.in sim/testsuite/d10v-elf/ChangeLog sim/testsuite/d10v-elf/Makefile.in sim/testsuite/d10v-elf/configure sim/testsuite/d10v-elf/configure.in sim/testsuite/d10v-elf/exit47.s sim/testsuite/d10v-elf/hello.s sim/testsuite/d10v-elf/loop.s sim/testsuite/d10v-elf/t-ae-ld-d.s sim/testsuite/d10v-elf/t-ae-ld-i.s sim/testsuite/d10v-elf/t-ae-ld-id.s sim/testsuite/d10v-elf/t-ae-ld-im.s sim/testsuite/d10v-elf/t-ae-ld-ip.s sim/testsuite/d10v-elf/t-ae-ld2w-d.s sim/testsuite/d10v-elf/t-ae-ld2w-i.s sim/testsuite/d10v-elf/t-ae-ld2w-id.s sim/testsuite/d10v-elf/t-ae-ld2w-im.s sim/testsuite/d10v-elf/t-ae-ld2w-ip.s sim/testsuite/d10v-elf/t-ae-st-d.s sim/testsuite/d10v-elf/t-ae-st-i.s sim/testsuite/d10v-elf/t-ae-st-id.s sim/testsuite/d10v-elf/t-ae-st-im.s sim/testsuite/d10v-elf/t-ae-st-ip.s sim/testsuite/d10v-elf/t-ae-st-is.s sim/testsuite/d10v-elf/t-ae-st2w-d.s sim/testsuite/d10v-elf/t-ae-st2w-i.s sim/testsuite/d10v-elf/t-ae-st2w-id.s sim/testsuite/d10v-elf/t-ae-st2w-im.s sim/testsuite/d10v-elf/t-ae-st2w-ip.s sim/testsuite/d10v-elf/t-ae-st2w-is.s sim/testsuite/d10v-elf/t-dbt.s sim/testsuite/d10v-elf/t-ld-st.s sim/testsuite/d10v-elf/t-mac.s sim/testsuite/d10v-elf/t-macros.i sim/testsuite/d10v-elf/t-mod-ld-pre.s sim/testsuite/d10v-elf/t-msbu.s sim/testsuite/d10v-elf/t-mulxu.s sim/testsuite/d10v-elf/t-mvtac.s sim/testsuite/d10v-elf/t-mvtc.s sim/testsuite/d10v-elf/t-rac.s sim/testsuite/d10v-elf/t-rachi.s sim/testsuite/d10v-elf/t-rdt.s sim/testsuite/d10v-elf/t-rep.s sim/testsuite/d10v-elf/t-rie-xx.s sim/testsuite/d10v-elf/t-rte.s sim/testsuite/d10v-elf/t-sac.s sim/testsuite/d10v-elf/t-sachi.s sim/testsuite/d10v-elf/t-sadd.s sim/testsuite/d10v-elf/t-slae.s sim/testsuite/d10v-elf/t-sp.s sim/testsuite/d10v-elf/t-sub.s sim/testsuite/d10v-elf/t-sub2w.s sim/testsuite/d10v-elf/t-subi.s sim/testsuite/d10v-elf/t-trap.s sim/testsuite/d30v-elf/ChangeLog sim/testsuite/d30v-elf/Makefile.in sim/testsuite/d30v-elf/br-bra.S sim/testsuite/d30v-elf/br-bratnz.S sim/testsuite/d30v-elf/br-bratzr.S sim/testsuite/d30v-elf/br-bsr.S sim/testsuite/d30v-elf/br-dbra.S sim/testsuite/d30v-elf/br-djmp.S sim/testsuite/d30v-elf/br-djsr.S sim/testsuite/d30v-elf/configure sim/testsuite/d30v-elf/configure.in sim/testsuite/d30v-elf/do-2wordops.S sim/testsuite/d30v-elf/do-flags.S sim/testsuite/d30v-elf/do-shifts.S sim/testsuite/d30v-elf/em-e0.S sim/testsuite/d30v-elf/em-e47.S sim/testsuite/d30v-elf/em-pchr.S sim/testsuite/d30v-elf/em-pstr.S sim/testsuite/d30v-elf/exit47.s sim/testsuite/d30v-elf/hello.s sim/testsuite/d30v-elf/loop.s sim/testsuite/d30v-elf/ls-ld2h.S sim/testsuite/d30v-elf/ls-ld2w.S sim/testsuite/d30v-elf/ls-ld4bh.S sim/testsuite/d30v-elf/ls-ld4bhu.S sim/testsuite/d30v-elf/ls-ldb.S sim/testsuite/d30v-elf/ls-ldbu.S sim/testsuite/d30v-elf/ls-ldh.S sim/testsuite/d30v-elf/ls-ldhh.S sim/testsuite/d30v-elf/ls-ldhu.S sim/testsuite/d30v-elf/ls-ldw.S sim/testsuite/d30v-elf/ls-modaddr.S sim/testsuite/d30v-elf/ls-moddec.S sim/testsuite/d30v-elf/ls-modinc.S sim/testsuite/d30v-elf/ls-st2h.S sim/testsuite/d30v-elf/ls-st2w.S sim/testsuite/d30v-elf/ls-st4hb.S sim/testsuite/d30v-elf/ls-stb.S sim/testsuite/d30v-elf/ls-sth.S sim/testsuite/d30v-elf/ls-sthh.S sim/testsuite/d30v-elf/ls-stw.S sim/testsuite/d30v-elf/os-dbt.S sim/testsuite/d30v-elf/tick.s sim/testsuite/d30v-elf/trap.S sim/testsuite/fr30-elf/ChangeLog sim/testsuite/fr30-elf/Makefile.in sim/testsuite/fr30-elf/configure sim/testsuite/fr30-elf/configure.in sim/testsuite/fr30-elf/exit47.s sim/testsuite/fr30-elf/hello.s sim/testsuite/fr30-elf/loop.s sim/testsuite/lib/sim-defs.exp sim/testsuite/m32r-elf/ChangeLog sim/testsuite/m32r-elf/Makefile.in sim/testsuite/m32r-elf/configure sim/testsuite/m32r-elf/configure.in sim/testsuite/m32r-elf/exit47.s sim/testsuite/m32r-elf/hello.s sim/testsuite/m32r-elf/loop.s sim/testsuite/mips64el-elf/ChangeLog sim/testsuite/mips64el-elf/Makefile.in sim/testsuite/mips64el-elf/configure sim/testsuite/mips64el-elf/configure.in sim/testsuite/sim/fr30/add.cgs sim/testsuite/sim/fr30/add.ms sim/testsuite/sim/fr30/add2.cgs sim/testsuite/sim/fr30/addc.cgs sim/testsuite/sim/fr30/addn.cgs sim/testsuite/sim/fr30/addn2.cgs sim/testsuite/sim/fr30/addsp.cgs sim/testsuite/sim/fr30/allinsn.exp sim/testsuite/sim/fr30/and.cgs sim/testsuite/sim/fr30/andb.cgs sim/testsuite/sim/fr30/andccr.cgs sim/testsuite/sim/fr30/andh.cgs sim/testsuite/sim/fr30/asr.cgs sim/testsuite/sim/fr30/asr2.cgs sim/testsuite/sim/fr30/bandh.cgs sim/testsuite/sim/fr30/bandl.cgs sim/testsuite/sim/fr30/bc.cgs sim/testsuite/sim/fr30/beorh.cgs sim/testsuite/sim/fr30/beorl.cgs sim/testsuite/sim/fr30/beq.cgs sim/testsuite/sim/fr30/bge.cgs sim/testsuite/sim/fr30/bgt.cgs sim/testsuite/sim/fr30/bhi.cgs sim/testsuite/sim/fr30/ble.cgs sim/testsuite/sim/fr30/bls.cgs sim/testsuite/sim/fr30/blt.cgs sim/testsuite/sim/fr30/bn.cgs sim/testsuite/sim/fr30/bnc.cgs sim/testsuite/sim/fr30/bne.cgs sim/testsuite/sim/fr30/bno.cgs sim/testsuite/sim/fr30/bnv.cgs sim/testsuite/sim/fr30/borh.cgs sim/testsuite/sim/fr30/borl.cgs sim/testsuite/sim/fr30/bp.cgs sim/testsuite/sim/fr30/bra.cgs sim/testsuite/sim/fr30/btsth.cgs sim/testsuite/sim/fr30/btstl.cgs sim/testsuite/sim/fr30/bv.cgs sim/testsuite/sim/fr30/call.cgs sim/testsuite/sim/fr30/cmp.cgs sim/testsuite/sim/fr30/cmp2.cgs sim/testsuite/sim/fr30/copld.cgs sim/testsuite/sim/fr30/copop.cgs sim/testsuite/sim/fr30/copst.cgs sim/testsuite/sim/fr30/copsv.cgs sim/testsuite/sim/fr30/div.ms sim/testsuite/sim/fr30/div0s.cgs sim/testsuite/sim/fr30/div0u.cgs sim/testsuite/sim/fr30/div1.cgs sim/testsuite/sim/fr30/div2.cgs sim/testsuite/sim/fr30/div3.cgs sim/testsuite/sim/fr30/div4s.cgs sim/testsuite/sim/fr30/dmov.cgs sim/testsuite/sim/fr30/dmovb.cgs sim/testsuite/sim/fr30/dmovh.cgs sim/testsuite/sim/fr30/enter.cgs sim/testsuite/sim/fr30/eor.cgs sim/testsuite/sim/fr30/eorb.cgs sim/testsuite/sim/fr30/eorh.cgs sim/testsuite/sim/fr30/extsb.cgs sim/testsuite/sim/fr30/extsh.cgs sim/testsuite/sim/fr30/extub.cgs sim/testsuite/sim/fr30/extuh.cgs sim/testsuite/sim/fr30/hello.ms sim/testsuite/sim/fr30/int.cgs sim/testsuite/sim/fr30/inte.cgs sim/testsuite/sim/fr30/jmp.cgs sim/testsuite/sim/fr30/ld.cgs sim/testsuite/sim/fr30/ldi20.cgs sim/testsuite/sim/fr30/ldi32.cgs sim/testsuite/sim/fr30/ldi8.cgs sim/testsuite/sim/fr30/ldm0.cgs sim/testsuite/sim/fr30/ldm1.cgs sim/testsuite/sim/fr30/ldres.cgs sim/testsuite/sim/fr30/ldub.cgs sim/testsuite/sim/fr30/lduh.cgs sim/testsuite/sim/fr30/leave.cgs sim/testsuite/sim/fr30/lsl.cgs sim/testsuite/sim/fr30/lsl2.cgs sim/testsuite/sim/fr30/lsr.cgs sim/testsuite/sim/fr30/lsr2.cgs sim/testsuite/sim/fr30/misc.exp sim/testsuite/sim/fr30/mov.cgs sim/testsuite/sim/fr30/mul.cgs sim/testsuite/sim/fr30/mulh.cgs sim/testsuite/sim/fr30/mulu.cgs sim/testsuite/sim/fr30/muluh.cgs sim/testsuite/sim/fr30/nop.cgs sim/testsuite/sim/fr30/or.cgs sim/testsuite/sim/fr30/orb.cgs sim/testsuite/sim/fr30/orccr.cgs sim/testsuite/sim/fr30/orh.cgs sim/testsuite/sim/fr30/ret.cgs sim/testsuite/sim/fr30/reti.cgs sim/testsuite/sim/fr30/st.cgs sim/testsuite/sim/fr30/stb.cgs sim/testsuite/sim/fr30/sth.cgs sim/testsuite/sim/fr30/stilm.cgs sim/testsuite/sim/fr30/stm0.cgs sim/testsuite/sim/fr30/stm1.cgs sim/testsuite/sim/fr30/stres.cgs sim/testsuite/sim/fr30/sub.cgs sim/testsuite/sim/fr30/subc.cgs sim/testsuite/sim/fr30/subn.cgs sim/testsuite/sim/fr30/testutils.inc sim/testsuite/sim/fr30/xchb.cgs sim/testsuite/sim/m32r/add.cgs sim/testsuite/sim/m32r/add3.cgs sim/testsuite/sim/m32r/addi.cgs sim/testsuite/sim/m32r/addv.cgs sim/testsuite/sim/m32r/addv3.cgs sim/testsuite/sim/m32r/addx.cgs sim/testsuite/sim/m32r/allinsn.exp sim/testsuite/sim/m32r/and.cgs sim/testsuite/sim/m32r/and3.cgs sim/testsuite/sim/m32r/bc24.cgs sim/testsuite/sim/m32r/bc8.cgs sim/testsuite/sim/m32r/beq.cgs sim/testsuite/sim/m32r/beqz.cgs sim/testsuite/sim/m32r/bgez.cgs sim/testsuite/sim/m32r/bgtz.cgs sim/testsuite/sim/m32r/bl24.cgs sim/testsuite/sim/m32r/bl8.cgs sim/testsuite/sim/m32r/blez.cgs sim/testsuite/sim/m32r/bltz.cgs sim/testsuite/sim/m32r/bnc24.cgs sim/testsuite/sim/m32r/bnc8.cgs sim/testsuite/sim/m32r/bne.cgs sim/testsuite/sim/m32r/bnez.cgs sim/testsuite/sim/m32r/bra24.cgs sim/testsuite/sim/m32r/bra8.cgs sim/testsuite/sim/m32r/cmp.cgs sim/testsuite/sim/m32r/cmpi.cgs sim/testsuite/sim/m32r/cmpu.cgs sim/testsuite/sim/m32r/cmpui.cgs sim/testsuite/sim/m32r/div.cgs sim/testsuite/sim/m32r/divu.cgs sim/testsuite/sim/m32r/hello.ms sim/testsuite/sim/m32r/hw-trap.ms sim/testsuite/sim/m32r/jl.cgs sim/testsuite/sim/m32r/jmp.cgs sim/testsuite/sim/m32r/ld-d.cgs sim/testsuite/sim/m32r/ld-plus.cgs sim/testsuite/sim/m32r/ld.cgs sim/testsuite/sim/m32r/ld24.cgs sim/testsuite/sim/m32r/ldb-d.cgs sim/testsuite/sim/m32r/ldb.cgs sim/testsuite/sim/m32r/ldh-d.cgs sim/testsuite/sim/m32r/ldh.cgs sim/testsuite/sim/m32r/ldi16.cgs sim/testsuite/sim/m32r/ldi8.cgs sim/testsuite/sim/m32r/ldub-d.cgs sim/testsuite/sim/m32r/ldub.cgs sim/testsuite/sim/m32r/lduh-d.cgs sim/testsuite/sim/m32r/lduh.cgs sim/testsuite/sim/m32r/lock.cgs sim/testsuite/sim/m32r/machi.cgs sim/testsuite/sim/m32r/maclo.cgs sim/testsuite/sim/m32r/macwhi.cgs sim/testsuite/sim/m32r/macwlo.cgs sim/testsuite/sim/m32r/misc.exp sim/testsuite/sim/m32r/mul.cgs sim/testsuite/sim/m32r/mulhi.cgs sim/testsuite/sim/m32r/mullo.cgs sim/testsuite/sim/m32r/mulwhi.cgs sim/testsuite/sim/m32r/mulwlo.cgs sim/testsuite/sim/m32r/mv.cgs sim/testsuite/sim/m32r/mvfachi.cgs sim/testsuite/sim/m32r/mvfaclo.cgs sim/testsuite/sim/m32r/mvfacmi.cgs sim/testsuite/sim/m32r/mvfc.cgs sim/testsuite/sim/m32r/mvtachi.cgs sim/testsuite/sim/m32r/mvtaclo.cgs sim/testsuite/sim/m32r/mvtc.cgs sim/testsuite/sim/m32r/neg.cgs sim/testsuite/sim/m32r/nop.cgs sim/testsuite/sim/m32r/not.cgs sim/testsuite/sim/m32r/or.cgs sim/testsuite/sim/m32r/or3.cgs sim/testsuite/sim/m32r/rac.cgs sim/testsuite/sim/m32r/rach.cgs sim/testsuite/sim/m32r/rem.cgs sim/testsuite/sim/m32r/remu.cgs sim/testsuite/sim/m32r/rte.cgs sim/testsuite/sim/m32r/seth.cgs sim/testsuite/sim/m32r/sll.cgs sim/testsuite/sim/m32r/sll3.cgs sim/testsuite/sim/m32r/slli.cgs sim/testsuite/sim/m32r/sra.cgs sim/testsuite/sim/m32r/sra3.cgs sim/testsuite/sim/m32r/srai.cgs sim/testsuite/sim/m32r/srl.cgs sim/testsuite/sim/m32r/srl3.cgs sim/testsuite/sim/m32r/srli.cgs sim/testsuite/sim/m32r/st-d.cgs sim/testsuite/sim/m32r/st-minus.cgs sim/testsuite/sim/m32r/st-plus.cgs sim/testsuite/sim/m32r/st.cgs sim/testsuite/sim/m32r/stb-d.cgs sim/testsuite/sim/m32r/stb.cgs sim/testsuite/sim/m32r/sth-d.cgs sim/testsuite/sim/m32r/sth.cgs sim/testsuite/sim/m32r/sub.cgs sim/testsuite/sim/m32r/subv.cgs sim/testsuite/sim/m32r/subx.cgs sim/testsuite/sim/m32r/testutils.inc sim/testsuite/sim/m32r/trap.cgs sim/testsuite/sim/m32r/unlock.cgs sim/testsuite/sim/m32r/uread16.ms sim/testsuite/sim/m32r/uread32.ms sim/testsuite/sim/m32r/uwrite16.ms sim/testsuite/sim/m32r/uwrite32.ms sim/testsuite/sim/m32r/xor.cgs sim/testsuite/sim/m32r/xor3.cgs sim/tic80/ChangeLog sim/tic80/Makefile.in sim/tic80/acconfig.h sim/tic80/alu.h sim/tic80/config.in sim/tic80/configure sim/tic80/configure.in sim/tic80/cpu.h sim/tic80/interp.c sim/tic80/misc.c sim/tic80/sim-calls.c sim/tic80/sim-main.h sim/tic80/tic80.dc sim/tic80/tic80.ic sim/tic80/tic80.igen sim/v850/ChangeLog sim/v850/Makefile.in sim/v850/acconfig.h sim/v850/config.in sim/v850/configure sim/v850/configure.in sim/v850/interp.c sim/v850/sim-main.h sim/v850/simops.c sim/v850/simops.h sim/v850/v850-dc sim/v850/v850.igen sim/v850/v850_sim.h sim/w65/ChangeLog sim/w65/Makefile.in sim/w65/acconfig.h sim/w65/config.in sim/w65/configure sim/w65/configure.in sim/w65/gencode.c sim/w65/interp.c sim/w65/interp.h sim/w65/run.c sim/z8k/ChangeLog sim/z8k/Makefile.in sim/z8k/acconfig.h sim/z8k/comped1.c sim/z8k/comped2.c sim/z8k/comped3.c sim/z8k/compedb3.c sim/z8k/config.in sim/z8k/configure sim/z8k/configure.in sim/z8k/iface.c sim/z8k/inlines.h sim/z8k/list.c sim/z8k/mem.c sim/z8k/mem.h sim/z8k/quick.c sim/z8k/sim.h sim/z8k/support.c sim/z8k/syscall.h sim/z8k/tconfig.in sim/z8k/tm.h sim/z8k/writecode.c symlink-tree texinfo/texinfo.tex ylwrap Cherrypick from cagney_regbuf-20020515-branch 2002-05-15 21:19:22 UTC nobody 'This commit was manufactured by cvs2svn to create branch': gdb/blockframe.c gdb/frame.h gdb/gdbarch.c gdb/gdbarch.h gdb/gdbarch.sh gdb/infcmd.c gdb/inferior.h gdb/infrun.c gdb/regcache.c gdb/regcache.h gdb/valops.c gdb/value.h gdb/values.c Cherrypick from master 2002-05-28 20:06:27 UTC Marek Michalkiewicz <marekm@amelek.gda.pl> '2002-05-28 Marek Michalkiewicz <marekm@amelek.gda.pl>': ChangeLog Makefile.in bfd/ChangeLog bfd/Makefile.am bfd/Makefile.in bfd/acinclude.m4 bfd/aclocal.m4 bfd/aix5ppc-core.c bfd/aout-adobe.c bfd/aout-target.h bfd/aout-tic30.c bfd/archures.c bfd/bfd-in2.h bfd/bfd.c bfd/binary.c bfd/bout.c bfd/coff-arm.c bfd/coff-rs6000.c bfd/coff-sh.c bfd/coff64-rs6000.c bfd/coffcode.h bfd/config.bfd bfd/config.in bfd/configure bfd/configure.in bfd/cpu-dlx.c bfd/cpu-mips.c bfd/doc/ChangeLog bfd/doc/Makefile.in bfd/doc/chew.c bfd/elf-bfd.h bfd/elf-eh-frame.c bfd/elf.c bfd/elf32-arm.h bfd/elf32-dlx.c bfd/elf32-i386.c bfd/elf32-m68k.c bfd/elf32-mips.c bfd/elf64-ppc.c bfd/elf64-x86-64.c bfd/elflink.h bfd/elfxx-ia64.c bfd/elfxx-mips.c bfd/elfxx-target.h bfd/hash.c bfd/i386msdos.c bfd/i386os9k.c bfd/ieee.c bfd/ihex.c bfd/libbfd-in.h bfd/libbfd.h bfd/libecoff.h bfd/linker.c bfd/mmo.c bfd/nlm-target.h bfd/oasys.c bfd/peXXigen.c bfd/ppcboot.c bfd/reloc.c bfd/rs6000-core.c bfd/section.c bfd/som.c bfd/srec.c bfd/syms.c bfd/targets.c bfd/tekhex.c bfd/versados.c bfd/version.h bfd/vms.c config-ml.in config.guess config.sub config/ChangeLog config/acinclude.m4 config/mh-apollo68 config/mh-dgux config/mh-dgux386 configure configure.in gdb/MAINTAINERS gdb/NEWS gdb/PROBLEMS gdb/alpha-linux-tdep.c gdb/alpha-osf1-tdep.c gdb/alpha-tdep.c gdb/alpha-tdep.h gdb/alphafbsd-tdep.c gdb/alphanbsd-tdep.c gdb/arm-linux-tdep.c gdb/arm-tdep.c gdb/arm-tdep.h gdb/armnbsd-tdep.c gdb/c-exp.y gdb/c-lang.c gdb/c-lang.h gdb/cli/cli-dump.c gdb/config/alpha/nm-nbsd.h gdb/config/alpha/tm-nbsd.h gdb/config/arm/nbsd.mt gdb/config/arm/nbsdaout.mh gdb/config/arm/nbsdelf.mh gdb/config/arm/nm-nbsd.h gdb/config/arm/nm-nbsdaout.h gdb/config/avr/avr.mt gdb/config/djgpp/fnchange.lst gdb/config/h8300/tm-h8300.h gdb/config/i386/nbsdaout.mh gdb/config/i386/nbsdaout.mt gdb/config/i386/nbsdelf.mh gdb/config/i386/nbsdelf.mt gdb/config/i386/nm-cygwin.h gdb/config/i386/nm-go32.h gdb/config/i386/nm-nbsd.h gdb/config/i386/nm-nbsdaout.h gdb/config/i386/tm-nbsd.h gdb/config/i386/tm-nbsdaout.h gdb/config/m68k/nbsdaout.mh gdb/config/m68k/nbsdaout.mt gdb/config/m68k/nm-nbsd.h gdb/config/m68k/nm-nbsdaout.h gdb/config/m68k/tm-nbsd.h gdb/config/mips/nbsd.mh gdb/config/mips/nbsd.mt gdb/config/mips/nm-nbsd.h gdb/config/mips/tm-nbsd.h gdb/config/nm-nbsd.h gdb/config/nm-nbsdaout.h gdb/config/ns32k/nbsdaout.mh gdb/config/ns32k/nbsdaout.mt gdb/config/ns32k/nm-nbsd.h gdb/config/ns32k/nm-nbsdaout.h gdb/config/ns32k/tm-nbsd.h gdb/config/ns32k/tm-ns32k.h gdb/config/pa/hpux11w.mh gdb/config/powerpc/nbsd.mh gdb/config/powerpc/nbsd.mt gdb/config/powerpc/nm-nbsd.h gdb/config/powerpc/tm-nbsd.h gdb/config/sh/tm-sh.h gdb/config/sparc/nbsdaout.mh gdb/config/sparc/nbsdaout.mt gdb/config/sparc/nbsdelf.mh gdb/config/sparc/nbsdelf.mt gdb/config/sparc/nm-nbsdaout.h gdb/config/sparc/tm-nbsd.h gdb/config/sparc/tm-nbsdaout.h gdb/config/v850/v850.mt gdb/configure.host gdb/configure.tgt gdb/corelow.c gdb/d10v-tdep.c gdb/doc/ChangeLog gdb/doc/gdb.texinfo gdb/doc/gdbint.texinfo gdb/dwarf2cfi.c gdb/dwarf2read.c gdb/gdb_indent.sh gdb/gdbserver/server.c gdb/gdbtypes.c gdb/gdbtypes.h gdb/h8300-tdep.c gdb/hpread.c gdb/i386-tdep.c gdb/macrocmd.c gdb/macroscope.c gdb/macroscope.h gdb/macrotab.c gdb/mi/ChangeLog gdb/mips-tdep.c gdb/mipsnbsd-nat.c gdb/mipsnbsd-tdep.c gdb/mipsnbsd-tdep.h gdb/ns32k-tdep.c gdb/ns32k-tdep.h gdb/ns32knbsd-tdep.c gdb/osabi.c gdb/osabi.h gdb/p-exp.y gdb/parse.c gdb/parser-defs.h gdb/ppcnbsd-nat.c gdb/ppcnbsd-tdep.c gdb/ppcnbsd-tdep.h gdb/remote.c gdb/rs6000-tdep.c gdb/ser-tcp.c gdb/sh-tdep.c gdb/sh-tdep.h gdb/sh3-rom.c gdb/shnbsd-tdep.c gdb/testsuite/ChangeLog gdb/testsuite/configure gdb/testsuite/configure.in gdb/testsuite/gdb.arch/Makefile.in gdb/testsuite/gdb.arch/altivec-abi.c gdb/testsuite/gdb.arch/altivec-abi.exp gdb/testsuite/gdb.arch/altivec-regs.c gdb/testsuite/gdb.arch/altivec-regs.exp gdb/testsuite/gdb.arch/configure gdb/testsuite/gdb.arch/configure.in gdb/testsuite/gdb.base/all-bin.exp gdb/testsuite/gdb.base/call-rt-st.exp gdb/testsuite/gdb.base/completion.exp gdb/testsuite/gdb.c++/inherit.exp gdb/testsuite/gdb.c++/local.exp gdb/testsuite/gdb.c++/m-data.cc gdb/testsuite/gdb.c++/m-data.exp gdb/testsuite/gdb.c++/try_catch.cc gdb/testsuite/gdb.c++/try_catch.exp gdb/testsuite/lib/gdb.exp gdb/v850-tdep.c gdb/version.in gdb/x86-64-tdep.c include/ChangeLog include/bfdlink.h include/dis-asm.h include/elf/ChangeLog include/elf/common.h include/elf/dlx.h include/elf/i386.h include/elf/ia64.h include/gdb/ChangeLog include/gdb/sim-d10v.h include/opcode/ChangeLog include/opcode/dlx.h include/opcode/h8300.h include/opcode/ia64.h include/opcode/mips.h include/opcode/sparc.h libiberty/ChangeLog libiberty/config.table opcodes/ChangeLog opcodes/Makefile.am opcodes/Makefile.in opcodes/acinclude.m4 opcodes/aclocal.m4 opcodes/arc-dis.c opcodes/arm-dis.c opcodes/configure opcodes/configure.in opcodes/disassemble.c opcodes/dlx-dis.c opcodes/fr30-asm.c opcodes/fr30-desc.c opcodes/fr30-dis.c opcodes/m32r-asm.c opcodes/m32r-desc.c opcodes/m32r-dis.c opcodes/m68k-dis.c opcodes/mips-dis.c opcodes/mips-opc.c opcodes/openrisc-asm.c opcodes/openrisc-desc.c opcodes/openrisc-dis.c opcodes/sh-dis.c opcodes/sh64-dis.c opcodes/xstormy16-asm.c opcodes/xstormy16-desc.c opcodes/xstormy16-dis.c sim/ChangeLog sim/MAINTAINERS sim/arm/ChangeLog sim/arm/Makefile.in sim/arm/armcopro.c sim/arm/armemu.c sim/arm/armos.c sim/arm/armsupp.c sim/arm/armvirt.c sim/arm/dbg_rdi.h sim/arm/thumbemu.c sim/arm/wrapper.c sim/common/ChangeLog sim/common/run-sim.h sim/common/run.c sim/common/sim-options.c sim/d10v/ChangeLog sim/d10v/Makefile.in sim/d10v/interp.c sim/d10v/simops.c sim/h8300/ChangeLog sim/h8300/compile.c sim/h8300/inst.h
Diffstat (limited to 'gdb')
-rw-r--r--gdb/29k-share/README9
-rw-r--r--gdb/29k-share/udi/udi2go32.c607
-rw-r--r--gdb/29k-share/udi/udiids.h48
-rw-r--r--gdb/29k-share/udi/udip2soc.c1250
-rw-r--r--gdb/29k-share/udi/udiphcfg.h44
-rw-r--r--gdb/29k-share/udi/udiphunix.h81
-rw-r--r--gdb/29k-share/udi/udiproc.h308
-rw-r--r--gdb/29k-share/udi/udipt29k.h87
-rw-r--r--gdb/29k-share/udi/udiptcfg.h19
-rw-r--r--gdb/29k-share/udi/udisoc.h184
-rw-r--r--gdb/29k-share/udi/udr.c427
-rw-r--r--gdb/29k-share/udi_soc9
-rw-r--r--gdb/CONTRIBUTE143
-rw-r--r--gdb/COPYING340
-rw-r--r--gdb/ChangeLog-19903155
-rw-r--r--gdb/ChangeLog-19915175
-rw-r--r--gdb/ChangeLog-19926285
-rw-r--r--gdb/ChangeLog-19937597
-rw-r--r--gdb/ChangeLog-19945705
-rw-r--r--gdb/ChangeLog-19954915
-rw-r--r--gdb/ChangeLog-19965116
-rw-r--r--gdb/ChangeLog-19972909
-rw-r--r--gdb/ChangeLog-19987220
-rw-r--r--gdb/ChangeLog-19999296
-rw-r--r--gdb/ChangeLog-20008204
-rw-r--r--gdb/ChangeLog-20019895
-rw-r--r--gdb/ChangeLog-3.x4838
-rw-r--r--gdb/MAINTAINERS437
-rw-r--r--gdb/NEWS2120
-rw-r--r--gdb/PROBLEMS32
-rw-r--r--gdb/README578
-rw-r--r--gdb/TODO347
-rw-r--r--gdb/a68v-nat.c122
-rw-r--r--gdb/abug-rom.c167
-rw-r--r--gdb/acconfig.h178
-rw-r--r--gdb/acinclude.m4978
-rw-r--r--gdb/aclocal.m41020
-rw-r--r--gdb/ada-exp.tab.c2389
-rw-r--r--gdb/ada-exp.y962
-rw-r--r--gdb/ada-lang.h365
-rw-r--r--gdb/ada-lex.c3174
-rw-r--r--gdb/ada-lex.l928
-rw-r--r--gdb/ada-tasks.c806
-rw-r--r--gdb/ada-typeprint.c896
-rw-r--r--gdb/ada-valprint.c1058
-rw-r--r--gdb/alpha-linux-tdep.c121
-rw-r--r--gdb/alpha-nat.c278
-rw-r--r--gdb/alpha-osf1-tdep.c73
-rw-r--r--gdb/alpha-tdep.c1988
-rw-r--r--gdb/alpha-tdep.h109
-rw-r--r--gdb/alphabsd-nat.c157
-rw-r--r--gdb/alphabsd-tdep.c102
-rw-r--r--gdb/alphabsd-tdep.h33
-rw-r--r--gdb/alphafbsd-tdep.c83
-rw-r--r--gdb/alphanbsd-tdep.c213
-rw-r--r--gdb/annotate.c585
-rw-r--r--gdb/annotate.h106
-rw-r--r--gdb/arc-tdep.c737
-rw-r--r--gdb/arch-utils.c889
-rw-r--r--gdb/arch-utils.h173
-rw-r--r--gdb/arm-linux-nat.c698
-rw-r--r--gdb/arm-linux-tdep.c547
-rw-r--r--gdb/arm-tdep.c3079
-rw-r--r--gdb/arm-tdep.h156
-rw-r--r--gdb/armnbsd-nat.c464
-rw-r--r--gdb/armnbsd-tdep.c104
-rw-r--r--gdb/avr-tdep.c1374
-rw-r--r--gdb/ax-gdb.c1859
-rw-r--r--gdb/ax-gdb.h112
-rw-r--r--gdb/ax-general.c541
-rw-r--r--gdb/ax.h292
-rw-r--r--gdb/bcache.c293
-rw-r--r--gdb/bcache.h130
-rw-r--r--gdb/blockframe.c1369
-rw-r--r--gdb/breakpoint.c7741
-rw-r--r--gdb/breakpoint.h709
-rw-r--r--gdb/buildsym.c1133
-rw-r--r--gdb/buildsym.h305
-rw-r--r--gdb/builtin-regs.c77
-rw-r--r--gdb/builtin-regs.h35
-rw-r--r--gdb/c-exp.y1801
-rw-r--r--gdb/c-lang.c673
-rw-r--r--gdb/c-lang.h92
-rw-r--r--gdb/c-typeprint.c1190
-rw-r--r--gdb/c-valprint.c598
-rw-r--r--gdb/call-cmds.h35
-rw-r--r--gdb/ch-exp.c2233
-rw-r--r--gdb/ch-lang.c663
-rw-r--r--gdb/ch-lang.h41
-rw-r--r--gdb/ch-typeprint.c340
-rw-r--r--gdb/ch-valprint.c605
-rw-r--r--gdb/cli-out.c373
-rw-r--r--gdb/cli-out.h27
-rw-r--r--gdb/cli/cli-cmds.c838
-rw-r--r--gdb/cli/cli-cmds.h125
-rw-r--r--gdb/cli/cli-decode.c1447
-rw-r--r--gdb/cli/cli-decode.h334
-rw-r--r--gdb/cli/cli-dump.c821
-rw-r--r--gdb/cli/cli-dump.h40
-rw-r--r--gdb/cli/cli-script.c1279
-rw-r--r--gdb/cli/cli-script.h48
-rw-r--r--gdb/cli/cli-setshow.c382
-rw-r--r--gdb/cli/cli-setshow.h36
-rw-r--r--gdb/cli/cli-utils.c21
-rw-r--r--gdb/cli/cli-utils.h22
-rw-r--r--gdb/coff-solib.c134
-rw-r--r--gdb/coff-solib.h186
-rw-r--r--gdb/coffread.c2149
-rw-r--r--gdb/command.h262
-rw-r--r--gdb/complaints.c168
-rw-r--r--gdb/complaints.h53
-rw-r--r--gdb/completer.c715
-rw-r--r--gdb/completer.h44
-rw-r--r--gdb/config.in507
-rw-r--r--gdb/config/alpha/alpha-linux.mh10
-rw-r--r--gdb/config/alpha/alpha-linux.mt3
-rw-r--r--gdb/config/alpha/alpha-osf1.mh5
-rw-r--r--gdb/config/alpha/alpha-osf1.mt3
-rw-r--r--gdb/config/alpha/alpha-osf2.mh6
-rw-r--r--gdb/config/alpha/alpha-osf3.mh6
-rw-r--r--gdb/config/alpha/fbsd.mh5
-rw-r--r--gdb/config/alpha/fbsd.mt3
-rw-r--r--gdb/config/alpha/nbsd.mh4
-rw-r--r--gdb/config/alpha/nbsd.mt4
-rw-r--r--gdb/config/alpha/nm-fbsd.h45
-rw-r--r--gdb/config/alpha/nm-linux.h48
-rw-r--r--gdb/config/alpha/nm-nbsd.h31
-rw-r--r--gdb/config/alpha/nm-osf.h43
-rw-r--r--gdb/config/alpha/nm-osf2.h55
-rw-r--r--gdb/config/alpha/nm-osf3.h27
-rw-r--r--gdb/config/alpha/tm-alpha.h86
-rw-r--r--gdb/config/alpha/tm-alphalinux.h45
-rw-r--r--gdb/config/alpha/tm-fbsd.h32
-rw-r--r--gdb/config/alpha/tm-nbsd.h33
-rw-r--r--gdb/config/alpha/xm-alphalinux.h26
-rw-r--r--gdb/config/alpha/xm-alphaosf.h24
-rw-r--r--gdb/config/arc/arc.mt3
-rw-r--r--gdb/config/arc/tm-arc.h336
-rw-r--r--gdb/config/arm/embed.mt7
-rw-r--r--gdb/config/arm/linux.mh11
-rw-r--r--gdb/config/arm/linux.mt5
-rw-r--r--gdb/config/arm/nbsd.mt2
-rw-r--r--gdb/config/arm/nbsdaout.mh5
-rw-r--r--gdb/config/arm/nbsdelf.mh4
-rw-r--r--gdb/config/arm/nm-linux.h42
-rw-r--r--gdb/config/arm/nm-nbsd.h27
-rw-r--r--gdb/config/arm/nm-nbsdaout.h29
-rw-r--r--gdb/config/arm/tm-arm.h34
-rw-r--r--gdb/config/arm/tm-embed.h52
-rw-r--r--gdb/config/arm/tm-linux.h94
-rw-r--r--gdb/config/arm/tm-wince.h34
-rw-r--r--gdb/config/arm/wince.mt5
-rw-r--r--gdb/config/arm/xm-linux.h28
-rw-r--r--gdb/config/arm/xm-nbsd.h22
-rw-r--r--gdb/config/avr/avr.mt12
-rw-r--r--gdb/config/cris/cris.mt2
-rw-r--r--gdb/config/cris/tm-cris.h2
-rw-r--r--gdb/config/d10v/d10v.mt4
-rw-r--r--gdb/config/d30v/d30v.mt5
-rw-r--r--gdb/config/d30v/tm-d30v.h323
-rw-r--r--gdb/config/djgpp/README189
-rw-r--r--gdb/config/djgpp/config.sed34
-rw-r--r--gdb/config/djgpp/djcheck.sh33
-rw-r--r--gdb/config/djgpp/djconfig.sh163
-rw-r--r--gdb/config/djgpp/fnchange.lst446
-rw-r--r--gdb/config/fr30/fr30.mt5
-rw-r--r--gdb/config/fr30/tm-fr30.h233
-rw-r--r--gdb/config/h8300/h8300.mt6
-rw-r--r--gdb/config/h8300/tm-h8300.h314
-rw-r--r--gdb/config/h8500/h8500.mt6
-rw-r--r--gdb/config/h8500/tm-h8500.h288
-rw-r--r--gdb/config/i386/cygwin.mh5
-rw-r--r--gdb/config/i386/cygwin.mt6
-rw-r--r--gdb/config/i386/embed.mt3
-rw-r--r--gdb/config/i386/fbsd.mh7
-rw-r--r--gdb/config/i386/fbsd.mt3
-rw-r--r--gdb/config/i386/gdbserve.mt3
-rw-r--r--gdb/config/i386/go32.mh17
-rw-r--r--gdb/config/i386/go32.mt3
-rw-r--r--gdb/config/i386/i386aix.mh9
-rw-r--r--gdb/config/i386/i386aix.mt7
-rw-r--r--gdb/config/i386/i386aout.mt3
-rw-r--r--gdb/config/i386/i386bsd.mh6
-rw-r--r--gdb/config/i386/i386bsd.mt3
-rw-r--r--gdb/config/i386/i386dgux.mh10
-rw-r--r--gdb/config/i386/i386gnu.mh33
-rw-r--r--gdb/config/i386/i386gnu.mt3
-rw-r--r--gdb/config/i386/i386lynx.mh6
-rw-r--r--gdb/config/i386/i386lynx.mt3
-rw-r--r--gdb/config/i386/i386m3.mh6
-rw-r--r--gdb/config/i386/i386m3.mt3
-rw-r--r--gdb/config/i386/i386mach.mh9
-rw-r--r--gdb/config/i386/i386mk.mh4
-rw-r--r--gdb/config/i386/i386mk.mt6
-rw-r--r--gdb/config/i386/i386nw.mt3
-rw-r--r--gdb/config/i386/i386os9k.mt3
-rw-r--r--gdb/config/i386/i386sco.mh12
-rw-r--r--gdb/config/i386/i386sco4.mh11
-rw-r--r--gdb/config/i386/i386sco5.mh16
-rw-r--r--gdb/config/i386/i386sco5.mt3
-rw-r--r--gdb/config/i386/i386sol2.mh8
-rw-r--r--gdb/config/i386/i386sol2.mt3
-rw-r--r--gdb/config/i386/i386v.mh7
-rw-r--r--gdb/config/i386/i386v.mt3
-rw-r--r--gdb/config/i386/i386v32.mh8
-rw-r--r--gdb/config/i386/i386v4.mh10
-rw-r--r--gdb/config/i386/i386v4.mt3
-rw-r--r--gdb/config/i386/i386v42mp.mh20
-rw-r--r--gdb/config/i386/i386v42mp.mt3
-rw-r--r--gdb/config/i386/linux.mh12
-rw-r--r--gdb/config/i386/linux.mt6
-rw-r--r--gdb/config/i386/nbsdaout.mh6
-rw-r--r--gdb/config/i386/nbsdaout.mt3
-rw-r--r--gdb/config/i386/nbsdelf.mh5
-rw-r--r--gdb/config/i386/nbsdelf.mt3
-rw-r--r--gdb/config/i386/ncr3000.mh16
-rw-r--r--gdb/config/i386/ncr3000.mt3
-rw-r--r--gdb/config/i386/nm-cygwin.h36
-rw-r--r--gdb/config/i386/nm-fbsd.h155
-rw-r--r--gdb/config/i386/nm-gnu.h23
-rw-r--r--gdb/config/i386/nm-go32.h36
-rw-r--r--gdb/config/i386/nm-i386.h120
-rw-r--r--gdb/config/i386/nm-i386aix.h43
-rw-r--r--gdb/config/i386/nm-i386bsd.h40
-rw-r--r--gdb/config/i386/nm-i386lynx.h26
-rw-r--r--gdb/config/i386/nm-i386mach.h30
-rw-r--r--gdb/config/i386/nm-i386sco.h42
-rw-r--r--gdb/config/i386/nm-i386sco4.h33
-rw-r--r--gdb/config/i386/nm-i386sco5.h38
-rw-r--r--gdb/config/i386/nm-i386sol2.h60
-rw-r--r--gdb/config/i386/nm-i386v.h37
-rw-r--r--gdb/config/i386/nm-i386v4.h26
-rw-r--r--gdb/config/i386/nm-i386v42mp.h23
-rw-r--r--gdb/config/i386/nm-linux.h83
-rw-r--r--gdb/config/i386/nm-m3.h23
-rw-r--r--gdb/config/i386/nm-nbsd.h28
-rw-r--r--gdb/config/i386/nm-nbsdaout.h30
-rw-r--r--gdb/config/i386/nm-obsd.h110
-rw-r--r--gdb/config/i386/nm-ptx4.h66
-rw-r--r--gdb/config/i386/nm-symmetry.h50
-rw-r--r--gdb/config/i386/nm-x86-64.h90
-rw-r--r--gdb/config/i386/obsd.mh7
-rw-r--r--gdb/config/i386/obsd.mt3
-rw-r--r--gdb/config/i386/ptx.mh7
-rw-r--r--gdb/config/i386/ptx.mt3
-rw-r--r--gdb/config/i386/ptx4.mh8
-rw-r--r--gdb/config/i386/ptx4.mt3
-rw-r--r--gdb/config/i386/symmetry.mh4
-rw-r--r--gdb/config/i386/symmetry.mt3
-rw-r--r--gdb/config/i386/tm-cygwin.h49
-rw-r--r--gdb/config/i386/tm-fbsd.h89
-rw-r--r--gdb/config/i386/tm-go32.h68
-rw-r--r--gdb/config/i386/tm-i386.h379
-rw-r--r--gdb/config/i386/tm-i386aix.h48
-rw-r--r--gdb/config/i386/tm-i386bsd.h45
-rw-r--r--gdb/config/i386/tm-i386gnu.h56
-rw-r--r--gdb/config/i386/tm-i386lynx.h34
-rw-r--r--gdb/config/i386/tm-i386m3.h56
-rw-r--r--gdb/config/i386/tm-i386mk.h38
-rw-r--r--gdb/config/i386/tm-i386nw.h49
-rw-r--r--gdb/config/i386/tm-i386os9k.h65
-rw-r--r--gdb/config/i386/tm-i386sco5.h63
-rw-r--r--gdb/config/i386/tm-i386sol2.h59
-rw-r--r--gdb/config/i386/tm-i386v.h36
-rw-r--r--gdb/config/i386/tm-i386v4.h79
-rw-r--r--gdb/config/i386/tm-i386v42mp.h93
-rw-r--r--gdb/config/i386/tm-linux.h131
-rw-r--r--gdb/config/i386/tm-nbsd.h64
-rw-r--r--gdb/config/i386/tm-nbsdaout.h34
-rw-r--r--gdb/config/i386/tm-obsd.h77
-rw-r--r--gdb/config/i386/tm-ptx.h233
-rw-r--r--gdb/config/i386/tm-ptx4.h26
-rw-r--r--gdb/config/i386/tm-symmetry.h325
-rw-r--r--gdb/config/i386/tm-vxworks.h28
-rw-r--r--gdb/config/i386/vxworks.mt3
-rw-r--r--gdb/config/i386/x86-64linux.mh11
-rw-r--r--gdb/config/i386/x86-64linux.mt3
-rw-r--r--gdb/config/i386/xm-cygwin.h24
-rw-r--r--gdb/config/i386/xm-go32.h26
-rw-r--r--gdb/config/i386/xm-i386.h30
-rw-r--r--gdb/config/i386/xm-i386aix.h29
-rw-r--r--gdb/config/i386/xm-i386bsd.h22
-rw-r--r--gdb/config/i386/xm-i386gnu.h25
-rw-r--r--gdb/config/i386/xm-i386m3.h33
-rw-r--r--gdb/config/i386/xm-i386mach.h28
-rw-r--r--gdb/config/i386/xm-i386mk.h26
-rw-r--r--gdb/config/i386/xm-i386sco.h40
-rw-r--r--gdb/config/i386/xm-i386v.h43
-rw-r--r--gdb/config/i386/xm-i386v32.h25
-rw-r--r--gdb/config/i386/xm-i386v4.h28
-rw-r--r--gdb/config/i386/xm-nbsd.h24
-rw-r--r--gdb/config/i386/xm-ptx.h38
-rw-r--r--gdb/config/i386/xm-ptx4.h27
-rw-r--r--gdb/config/i386/xm-symmetry.h28
-rw-r--r--gdb/config/i960/mon960.mt6
-rw-r--r--gdb/config/i960/nindy960.mt3
-rw-r--r--gdb/config/i960/tm-i960.h345
-rw-r--r--gdb/config/i960/tm-mon960.h69
-rw-r--r--gdb/config/i960/tm-nindy960.h106
-rw-r--r--gdb/config/i960/tm-vx960.h52
-rw-r--r--gdb/config/i960/vxworks960.mt6
-rw-r--r--gdb/config/ia64/aix.mh8
-rw-r--r--gdb/config/ia64/aix.mt4
-rw-r--r--gdb/config/ia64/linux.mh10
-rw-r--r--gdb/config/ia64/linux.mt6
-rw-r--r--gdb/config/ia64/nm-aix.h37
-rw-r--r--gdb/config/ia64/nm-linux.h79
-rw-r--r--gdb/config/ia64/tm-aix.h32
-rw-r--r--gdb/config/ia64/tm-ia64.h252
-rw-r--r--gdb/config/ia64/tm-linux.h34
-rw-r--r--gdb/config/ia64/xm-aix.h28
-rw-r--r--gdb/config/ia64/xm-linux.h28
-rw-r--r--gdb/config/m32r/m32r.mt5
-rw-r--r--gdb/config/m32r/tm-m32r.h234
-rw-r--r--gdb/config/m68hc11/m68hc11.mt6
-rw-r--r--gdb/config/m68k/3b1.mh12
-rw-r--r--gdb/config/m68k/3b1.mt3
-rw-r--r--gdb/config/m68k/apollo68b.mh5
-rw-r--r--gdb/config/m68k/apollo68b.mt3
-rw-r--r--gdb/config/m68k/apollo68v.mh10
-rw-r--r--gdb/config/m68k/cisco.mt3
-rw-r--r--gdb/config/m68k/delta68.mh5
-rw-r--r--gdb/config/m68k/delta68.mt3
-rw-r--r--gdb/config/m68k/dpx2.mh6
-rw-r--r--gdb/config/m68k/dpx2.mt3
-rw-r--r--gdb/config/m68k/es1800.mt9
-rw-r--r--gdb/config/m68k/hp300bsd.mh6
-rw-r--r--gdb/config/m68k/hp300bsd.mt3
-rw-r--r--gdb/config/m68k/hp300hpux.mh8
-rw-r--r--gdb/config/m68k/hp300hpux.mt8
-rw-r--r--gdb/config/m68k/linux.mh14
-rw-r--r--gdb/config/m68k/linux.mt3
-rw-r--r--gdb/config/m68k/m68klynx.mh6
-rw-r--r--gdb/config/m68k/m68klynx.mt4
-rw-r--r--gdb/config/m68k/m68kv4.mh7
-rw-r--r--gdb/config/m68k/m68kv4.mt3
-rw-r--r--gdb/config/m68k/monitor.mt3
-rw-r--r--gdb/config/m68k/nbsdaout.mh5
-rw-r--r--gdb/config/m68k/nbsdaout.mt3
-rw-r--r--gdb/config/m68k/nm-apollo68b.h42
-rw-r--r--gdb/config/m68k/nm-apollo68v.h21
-rw-r--r--gdb/config/m68k/nm-delta68.h22
-rw-r--r--gdb/config/m68k/nm-dpx2.h29
-rw-r--r--gdb/config/m68k/nm-hp300bsd.h90
-rw-r--r--gdb/config/m68k/nm-hp300hpux.h55
-rw-r--r--gdb/config/m68k/nm-linux.h41
-rw-r--r--gdb/config/m68k/nm-m68klynx.h26
-rw-r--r--gdb/config/m68k/nm-nbsd.h27
-rw-r--r--gdb/config/m68k/nm-nbsdaout.h29
-rw-r--r--gdb/config/m68k/nm-sun2.h34
-rw-r--r--gdb/config/m68k/nm-sun3.h34
-rw-r--r--gdb/config/m68k/nm-sysv4.h23
-rw-r--r--gdb/config/m68k/os68k.mt3
-rw-r--r--gdb/config/m68k/st2000.mt3
-rw-r--r--gdb/config/m68k/sun2os3.mh4
-rw-r--r--gdb/config/m68k/sun2os3.mt7
-rw-r--r--gdb/config/m68k/sun2os4.mh4
-rw-r--r--gdb/config/m68k/sun2os4.mt3
-rw-r--r--gdb/config/m68k/sun3os3.mh4
-rw-r--r--gdb/config/m68k/sun3os3.mt8
-rw-r--r--gdb/config/m68k/sun3os4.mh4
-rw-r--r--gdb/config/m68k/sun3os4.mt3
-rw-r--r--gdb/config/m68k/tm-3b1.h33
-rw-r--r--gdb/config/m68k/tm-apollo68b.h61
-rw-r--r--gdb/config/m68k/tm-cisco.h55
-rw-r--r--gdb/config/m68k/tm-delta68.h107
-rw-r--r--gdb/config/m68k/tm-dpx2.h35
-rw-r--r--gdb/config/m68k/tm-es1800.h60
-rw-r--r--gdb/config/m68k/tm-hp300bsd.h64
-rw-r--r--gdb/config/m68k/tm-hp300hpux.h33
-rw-r--r--gdb/config/m68k/tm-linux.h107
-rw-r--r--gdb/config/m68k/tm-m68k.h368
-rw-r--r--gdb/config/m68k/tm-m68klynx.h39
-rw-r--r--gdb/config/m68k/tm-m68kv4.h71
-rw-r--r--gdb/config/m68k/tm-mac.h21
-rw-r--r--gdb/config/m68k/tm-monitor.h46
-rw-r--r--gdb/config/m68k/tm-nbsd.h49
-rw-r--r--gdb/config/m68k/tm-os68k.h47
-rw-r--r--gdb/config/m68k/tm-st2000.h21
-rw-r--r--gdb/config/m68k/tm-sun2.h24
-rw-r--r--gdb/config/m68k/tm-sun2os4.h21
-rw-r--r--gdb/config/m68k/tm-sun3.h108
-rw-r--r--gdb/config/m68k/tm-sun3os4.h22
-rw-r--r--gdb/config/m68k/tm-vx68.h89
-rw-r--r--gdb/config/m68k/vxworks68.mt3
-rw-r--r--gdb/config/m68k/xm-3b1.h82
-rw-r--r--gdb/config/m68k/xm-apollo68b.h21
-rw-r--r--gdb/config/m68k/xm-apollo68v.h42
-rw-r--r--gdb/config/m68k/xm-delta68.h35
-rw-r--r--gdb/config/m68k/xm-dpx2.h22
-rw-r--r--gdb/config/m68k/xm-hp300bsd.h83
-rw-r--r--gdb/config/m68k/xm-hp300hpux.h150
-rw-r--r--gdb/config/m68k/xm-linux.h34
-rw-r--r--gdb/config/m68k/xm-m68k.h21
-rw-r--r--gdb/config/m68k/xm-m68kv4.h29
-rw-r--r--gdb/config/m68k/xm-nbsd.h22
-rw-r--r--gdb/config/m68k/xm-sun2.h77
-rw-r--r--gdb/config/m68k/xm-sun3.h71
-rw-r--r--gdb/config/m68k/xm-sun3os4.h22
-rw-r--r--gdb/config/m88k/delta88.mh6
-rw-r--r--gdb/config/m88k/delta88.mt3
-rw-r--r--gdb/config/m88k/delta88v4.mh8
-rw-r--r--gdb/config/m88k/delta88v4.mt3
-rw-r--r--gdb/config/m88k/m88k.mh4
-rw-r--r--gdb/config/m88k/m88k.mt3
-rw-r--r--gdb/config/m88k/nm-delta88v4.h23
-rw-r--r--gdb/config/m88k/nm-m88k.h25
-rw-r--r--gdb/config/m88k/tm-delta88.h28
-rw-r--r--gdb/config/m88k/tm-delta88v4.h32
-rw-r--r--gdb/config/m88k/tm-m88k.h587
-rw-r--r--gdb/config/m88k/xm-delta88.h44
-rw-r--r--gdb/config/m88k/xm-delta88v4.h22
-rw-r--r--gdb/config/m88k/xm-dgux.h55
-rw-r--r--gdb/config/mcore/mcore.mt5
-rw-r--r--gdb/config/mcore/tm-mcore.h161
-rw-r--r--gdb/config/mips/bigmips.mt3
-rw-r--r--gdb/config/mips/bigmips64.mt3
-rw-r--r--gdb/config/mips/decstation.mh4
-rw-r--r--gdb/config/mips/decstation.mt3
-rw-r--r--gdb/config/mips/embed.mt5
-rw-r--r--gdb/config/mips/embed64.mt5
-rw-r--r--gdb/config/mips/embedl.mt5
-rw-r--r--gdb/config/mips/embedl64.mt5
-rw-r--r--gdb/config/mips/irix3.mh5
-rw-r--r--gdb/config/mips/irix3.mt3
-rw-r--r--gdb/config/mips/irix4.mh10
-rw-r--r--gdb/config/mips/irix5.mh7
-rw-r--r--gdb/config/mips/irix5.mt3
-rw-r--r--gdb/config/mips/irix6.mh7
-rw-r--r--gdb/config/mips/irix6.mt3
-rw-r--r--gdb/config/mips/linux.mh7
-rw-r--r--gdb/config/mips/linux.mt9
-rw-r--r--gdb/config/mips/littlemips.mh3
-rw-r--r--gdb/config/mips/littlemips.mt3
-rw-r--r--gdb/config/mips/mipsm3.mh6
-rw-r--r--gdb/config/mips/mipsm3.mt4
-rw-r--r--gdb/config/mips/mipsv4.mh6
-rw-r--r--gdb/config/mips/mipsv4.mt3
-rw-r--r--gdb/config/mips/nbsd.mh4
-rw-r--r--gdb/config/mips/nbsd.mt6
-rw-r--r--gdb/config/mips/news-mips.mh3
-rw-r--r--gdb/config/mips/nm-irix3.h38
-rw-r--r--gdb/config/mips/nm-irix4.h67
-rw-r--r--gdb/config/mips/nm-irix5.h47
-rw-r--r--gdb/config/mips/nm-irix6.h22
-rw-r--r--gdb/config/mips/nm-linux.h51
-rw-r--r--gdb/config/mips/nm-mips.h34
-rw-r--r--gdb/config/mips/nm-nbsd.h28
-rw-r--r--gdb/config/mips/nm-news-mips.h43
-rw-r--r--gdb/config/mips/nm-riscos.h60
-rw-r--r--gdb/config/mips/riscos.mh16
-rw-r--r--gdb/config/mips/tm-bigmips.h20
-rw-r--r--gdb/config/mips/tm-bigmips64.h22
-rw-r--r--gdb/config/mips/tm-embed.h49
-rw-r--r--gdb/config/mips/tm-embed64.h20
-rw-r--r--gdb/config/mips/tm-embedl.h20
-rw-r--r--gdb/config/mips/tm-embedl64.h20
-rw-r--r--gdb/config/mips/tm-irix3.h82
-rw-r--r--gdb/config/mips/tm-irix5.h85
-rw-r--r--gdb/config/mips/tm-irix6.h139
-rw-r--r--gdb/config/mips/tm-linux.h75
-rw-r--r--gdb/config/mips/tm-mips.h493
-rw-r--r--gdb/config/mips/tm-mips64.h37
-rw-r--r--gdb/config/mips/tm-mipsm3.h67
-rw-r--r--gdb/config/mips/tm-mipsv4.h40
-rw-r--r--gdb/config/mips/tm-nbsd.h45
-rw-r--r--gdb/config/mips/tm-tx39.h36
-rw-r--r--gdb/config/mips/tm-tx39l.h36
-rw-r--r--gdb/config/mips/tm-vr4100.h20
-rw-r--r--gdb/config/mips/tm-vr4300.h20
-rw-r--r--gdb/config/mips/tm-vr4300el.h20
-rw-r--r--gdb/config/mips/tm-vr4xxx.h20
-rw-r--r--gdb/config/mips/tm-vr4xxxel.h20
-rw-r--r--gdb/config/mips/tm-vr5000.h20
-rw-r--r--gdb/config/mips/tm-vr5000el.h20
-rw-r--r--gdb/config/mips/tm-vxmips.h29
-rw-r--r--gdb/config/mips/tm-wince.h33
-rw-r--r--gdb/config/mips/tx39.mt5
-rw-r--r--gdb/config/mips/tx39l.mt5
-rw-r--r--gdb/config/mips/vr4100.mt5
-rw-r--r--gdb/config/mips/vr4300.mt5
-rw-r--r--gdb/config/mips/vr4300el.mt5
-rw-r--r--gdb/config/mips/vr4xxx.mt5
-rw-r--r--gdb/config/mips/vr4xxxel.mt5
-rw-r--r--gdb/config/mips/vr5000.mt5
-rw-r--r--gdb/config/mips/vr5000el.mt5
-rw-r--r--gdb/config/mips/vxmips.mt3
-rw-r--r--gdb/config/mips/wince.mt5
-rw-r--r--gdb/config/mips/xm-irix3.h30
-rw-r--r--gdb/config/mips/xm-irix4.h34
-rw-r--r--gdb/config/mips/xm-irix5.h34
-rw-r--r--gdb/config/mips/xm-irix6.h22
-rw-r--r--gdb/config/mips/xm-linux.h25
-rw-r--r--gdb/config/mips/xm-mips.h59
-rw-r--r--gdb/config/mips/xm-mipsm3.h29
-rw-r--r--gdb/config/mips/xm-mipsv4.h22
-rw-r--r--gdb/config/mips/xm-riscos.h25
-rw-r--r--gdb/config/mn10200/mn10200.mt6
-rw-r--r--gdb/config/mn10200/tm-mn10200.h220
-rw-r--r--gdb/config/mn10300/mn10300.mt4
-rw-r--r--gdb/config/nm-gnu.h43
-rw-r--r--gdb/config/nm-linux.h74
-rw-r--r--gdb/config/nm-lynx.h85
-rw-r--r--gdb/config/nm-m3.h126
-rw-r--r--gdb/config/nm-nbsd.h27
-rw-r--r--gdb/config/nm-nbsdaout.h72
-rw-r--r--gdb/config/nm-sysv4.h34
-rw-r--r--gdb/config/none/nm-none.h19
-rw-r--r--gdb/config/none/none.mh5
-rw-r--r--gdb/config/none/none.mt4
-rw-r--r--gdb/config/none/tm-none.h24
-rw-r--r--gdb/config/none/xm-none.h19
-rw-r--r--gdb/config/ns32k/nbsdaout.mh5
-rw-r--r--gdb/config/ns32k/nbsdaout.mt3
-rw-r--r--gdb/config/ns32k/nm-nbsd.h37
-rw-r--r--gdb/config/ns32k/nm-nbsdaout.h30
-rw-r--r--gdb/config/ns32k/tm-nbsd.h37
-rw-r--r--gdb/config/ns32k/tm-ns32k.h39
-rw-r--r--gdb/config/ns32k/xm-nbsd.h22
-rw-r--r--gdb/config/pa/hppa64.mt4
-rw-r--r--gdb/config/pa/hppabsd.mh4
-rw-r--r--gdb/config/pa/hppabsd.mt3
-rw-r--r--gdb/config/pa/hppahpux.mh8
-rw-r--r--gdb/config/pa/hppahpux.mt3
-rw-r--r--gdb/config/pa/hppaosf.mh5
-rw-r--r--gdb/config/pa/hppaosf.mt3
-rw-r--r--gdb/config/pa/hppapro.mt3
-rw-r--r--gdb/config/pa/hpux1020.mh14
-rw-r--r--gdb/config/pa/hpux1020.mt3
-rw-r--r--gdb/config/pa/hpux11.mh14
-rw-r--r--gdb/config/pa/hpux11.mt3
-rw-r--r--gdb/config/pa/hpux11w.mh14
-rw-r--r--gdb/config/pa/hpux11w.mt3
-rw-r--r--gdb/config/pa/nm-hppab.h137
-rw-r--r--gdb/config/pa/nm-hppah.h287
-rw-r--r--gdb/config/pa/nm-hppah11.h23
-rw-r--r--gdb/config/pa/nm-hppao.h57
-rw-r--r--gdb/config/pa/tm-hppa.h762
-rw-r--r--gdb/config/pa/tm-hppa64.h333
-rw-r--r--gdb/config/pa/tm-hppab.h47
-rw-r--r--gdb/config/pa/tm-hppah.h90
-rw-r--r--gdb/config/pa/tm-hppao.h98
-rw-r--r--gdb/config/pa/tm-pro.h14
-rw-r--r--gdb/config/pa/xm-hppab.h24
-rw-r--r--gdb/config/pa/xm-hppah.h29
-rw-r--r--gdb/config/pa/xm-pa.h5
-rw-r--r--gdb/config/powerpc/aix.mh16
-rw-r--r--gdb/config/powerpc/aix.mt3
-rw-r--r--gdb/config/powerpc/gdbserve.mt3
-rw-r--r--gdb/config/powerpc/linux.mh13
-rw-r--r--gdb/config/powerpc/linux.mt6
-rw-r--r--gdb/config/powerpc/nbsd.mh3
-rw-r--r--gdb/config/powerpc/nbsd.mt7
-rw-r--r--gdb/config/powerpc/nm-aix.h23
-rw-r--r--gdb/config/powerpc/nm-linux.h33
-rw-r--r--gdb/config/powerpc/nm-nbsd.h27
-rw-r--r--gdb/config/powerpc/ppc-eabi.mt3
-rw-r--r--gdb/config/powerpc/ppc-sim.mt6
-rw-r--r--gdb/config/powerpc/ppcle-eabi.mt3
-rw-r--r--gdb/config/powerpc/ppcle-sim.mt6
-rw-r--r--gdb/config/powerpc/tm-linux.h70
-rw-r--r--gdb/config/powerpc/tm-nbsd.h26
-rw-r--r--gdb/config/powerpc/tm-ppc-aix.h27
-rw-r--r--gdb/config/powerpc/tm-ppc-eabi.h43
-rw-r--r--gdb/config/powerpc/tm-ppc-sim.h26
-rw-r--r--gdb/config/powerpc/tm-ppcle-eabi.h28
-rw-r--r--gdb/config/powerpc/tm-ppcle-sim.h26
-rw-r--r--gdb/config/powerpc/tm-vxworks.h28
-rw-r--r--gdb/config/powerpc/vxworks.mt3
-rw-r--r--gdb/config/powerpc/xm-aix.h31
-rw-r--r--gdb/config/powerpc/xm-linux.h38
-rw-r--r--gdb/config/romp/rtbsd.mh8
-rw-r--r--gdb/config/romp/xm-rtbsd.h37
-rw-r--r--gdb/config/rs6000/aix4.mh11
-rw-r--r--gdb/config/rs6000/aix4.mt3
-rw-r--r--gdb/config/rs6000/nm-rs6000.h66
-rw-r--r--gdb/config/rs6000/nm-rs6000ly.h26
-rw-r--r--gdb/config/rs6000/rs6000.mh11
-rw-r--r--gdb/config/rs6000/rs6000.mt3
-rw-r--r--gdb/config/rs6000/rs6000lynx.mh6
-rw-r--r--gdb/config/rs6000/rs6000lynx.mt3
-rw-r--r--gdb/config/rs6000/tm-rs6000-aix4.h27
-rw-r--r--gdb/config/rs6000/tm-rs6000.h125
-rw-r--r--gdb/config/rs6000/tm-rs6000ly.h31
-rw-r--r--gdb/config/rs6000/xm-aix4.h27
-rw-r--r--gdb/config/rs6000/xm-rs6000.h94
-rw-r--r--gdb/config/s390/nm-linux.h84
-rw-r--r--gdb/config/s390/s390.mh13
-rw-r--r--gdb/config/s390/s390.mt6
-rw-r--r--gdb/config/s390/s390x.mt9
-rw-r--r--gdb/config/s390/tm-linux.h44
-rw-r--r--gdb/config/s390/tm-s390.h115
-rw-r--r--gdb/config/s390/xm-linux.h30
-rw-r--r--gdb/config/sh/embed.mt6
-rw-r--r--gdb/config/sh/linux.mt8
-rw-r--r--gdb/config/sh/nbsd.mh4
-rw-r--r--gdb/config/sh/nbsd.mt6
-rw-r--r--gdb/config/sh/nm-nbsd.h28
-rw-r--r--gdb/config/sh/tm-linux.h32
-rw-r--r--gdb/config/sh/tm-nbsd.h28
-rw-r--r--gdb/config/sh/tm-sh.h33
-rw-r--r--gdb/config/sh/tm-wince.h32
-rw-r--r--gdb/config/sh/wince.mt5
-rw-r--r--gdb/config/sparc/fbsd.mh25
-rw-r--r--gdb/config/sparc/fbsd.mt23
-rw-r--r--gdb/config/sparc/linux.mh14
-rw-r--r--gdb/config/sparc/linux.mt3
-rw-r--r--gdb/config/sparc/nbsd64.mh3
-rw-r--r--gdb/config/sparc/nbsd64.mt4
-rw-r--r--gdb/config/sparc/nbsdaout.mh6
-rw-r--r--gdb/config/sparc/nbsdaout.mt3
-rw-r--r--gdb/config/sparc/nbsdelf.mh6
-rw-r--r--gdb/config/sparc/nbsdelf.mt3
-rw-r--r--gdb/config/sparc/nm-fbsd.h67
-rw-r--r--gdb/config/sparc/nm-linux.h32
-rw-r--r--gdb/config/sparc/nm-nbsd.h61
-rw-r--r--gdb/config/sparc/nm-nbsdaout.h30
-rw-r--r--gdb/config/sparc/nm-sparclynx.h26
-rw-r--r--gdb/config/sparc/nm-sun4os4.h42
-rw-r--r--gdb/config/sparc/nm-sun4sol2.h69
-rw-r--r--gdb/config/sparc/sp64.mt9
-rw-r--r--gdb/config/sparc/sp64linux.mt3
-rw-r--r--gdb/config/sparc/sp64sim.mt13
-rw-r--r--gdb/config/sparc/sp64sol2.mt3
-rw-r--r--gdb/config/sparc/sparc-em.mt3
-rw-r--r--gdb/config/sparc/sparclet.mt3
-rw-r--r--gdb/config/sparc/sparclite.mt5
-rw-r--r--gdb/config/sparc/sparclynx.mh6
-rw-r--r--gdb/config/sparc/sparclynx.mt3
-rw-r--r--gdb/config/sparc/sun4os4.mh9
-rw-r--r--gdb/config/sparc/sun4os4.mt3
-rw-r--r--gdb/config/sparc/sun4sol2.mh22
-rw-r--r--gdb/config/sparc/sun4sol2.mt3
-rw-r--r--gdb/config/sparc/tm-fbsd.h34
-rw-r--r--gdb/config/sparc/tm-linux.h34
-rw-r--r--gdb/config/sparc/tm-nbsd.h26
-rw-r--r--gdb/config/sparc/tm-nbsd64.h27
-rw-r--r--gdb/config/sparc/tm-nbsdaout.h30
-rw-r--r--gdb/config/sparc/tm-sp64.h467
-rw-r--r--gdb/config/sparc/tm-sp64linux.h36
-rw-r--r--gdb/config/sparc/tm-sp64sim.h50
-rw-r--r--gdb/config/sparc/tm-sparc.h766
-rw-r--r--gdb/config/sparc/tm-sparclet.h156
-rw-r--r--gdb/config/sparc/tm-sparclite.h126
-rw-r--r--gdb/config/sparc/tm-sparclynx.h37
-rw-r--r--gdb/config/sparc/tm-spc-em.h46
-rw-r--r--gdb/config/sparc/tm-sun4os4.h59
-rw-r--r--gdb/config/sparc/tm-sun4sol2.h82
-rw-r--r--gdb/config/sparc/tm-vxsparc.h33
-rw-r--r--gdb/config/sparc/vxsparc.mt3
-rw-r--r--gdb/config/sparc/xm-linux.h42
-rw-r--r--gdb/config/sparc/xm-nbsd.h22
-rw-r--r--gdb/config/sparc/xm-sun4sol2.h37
-rw-r--r--gdb/config/tm-linux.h42
-rw-r--r--gdb/config/tm-lynx.h35
-rw-r--r--gdb/config/tm-sunos.h32
-rw-r--r--gdb/config/tm-sysv4.h47
-rw-r--r--gdb/config/tm-vxworks.h23
-rw-r--r--gdb/config/v850/v850.mt5
-rw-r--r--gdb/config/vax/nm-vax.h27
-rw-r--r--gdb/config/vax/tm-vax.h48
-rw-r--r--gdb/config/vax/vax.mt3
-rw-r--r--gdb/config/vax/vaxbsd.mh13
-rw-r--r--gdb/config/vax/vaxult.mh6
-rw-r--r--gdb/config/vax/vaxult2.mh6
-rw-r--r--gdb/config/vax/xm-vax.h80
-rw-r--r--gdb/config/vax/xm-vaxbsd.h7
-rw-r--r--gdb/config/vax/xm-vaxult.h10
-rw-r--r--gdb/config/vax/xm-vaxult2.h9
-rw-r--r--gdb/config/xm-aix4.h91
-rw-r--r--gdb/config/xm-nbsd.h26
-rw-r--r--gdb/config/xm-sysv4.h29
-rw-r--r--gdb/config/xstormy16/xstormy16.mt5
-rw-r--r--gdb/config/z8k/tm-z8k.h287
-rw-r--r--gdb/config/z8k/z8k.mt7
-rwxr-xr-xgdb/configure9468
-rw-r--r--gdb/configure.host167
-rw-r--r--gdb/configure.in1395
-rw-r--r--gdb/configure.tgt317
-rw-r--r--gdb/copying.awk77
-rw-r--r--gdb/copying.c323
-rw-r--r--gdb/core-aout.c146
-rw-r--r--gdb/core-regset.c134
-rw-r--r--gdb/core-sol2.c194
-rw-r--r--gdb/corefile.c458
-rw-r--r--gdb/corelow.c545
-rw-r--r--gdb/cp-abi.c109
-rw-r--r--gdb/cp-abi.h173
-rw-r--r--gdb/cp-valprint.c853
-rw-r--r--gdb/cpu32bug-rom.c165
-rw-r--r--gdb/cris-tdep.c4347
-rw-r--r--gdb/cxux-nat.c537
-rw-r--r--gdb/d10v-tdep.c1657
-rw-r--r--gdb/d30v-tdep.c1365
-rw-r--r--gdb/dbug-rom.c161
-rw-r--r--gdb/dbxread.c3624
-rw-r--r--gdb/dcache.c603
-rw-r--r--gdb/dcache.h43
-rw-r--r--gdb/delta68-nat.c90
-rw-r--r--gdb/demangle.c208
-rw-r--r--gdb/dink32-rom.c192
-rw-r--r--gdb/doc/ChangeLog2709
-rw-r--r--gdb/doc/LRS197
-rw-r--r--gdb/doc/Makefile.in415
-rw-r--r--gdb/doc/a4rc.sed11
-rw-r--r--gdb/doc/agentexpr.texi839
-rw-r--r--gdb/doc/all-cfg.texi45
-rw-r--r--gdb/doc/annotate.texi741
-rwxr-xr-xgdb/doc/configure888
-rw-r--r--gdb/doc/configure.in5
-rw-r--r--gdb/doc/fdl.texi368
-rw-r--r--gdb/doc/gdb.texinfo15053
-rw-r--r--gdb/doc/gdbint.texinfo6095
-rw-r--r--gdb/doc/gpl.texi409
-rw-r--r--gdb/doc/lpsrc.sed13
-rw-r--r--gdb/doc/psrc.sed13
-rw-r--r--gdb/doc/refcard.tex647
-rw-r--r--gdb/doc/stabs.texinfo4037
-rw-r--r--gdb/doublest.c788
-rw-r--r--gdb/doublest.h83
-rw-r--r--gdb/dpx2-nat.c83
-rw-r--r--gdb/dsrec.c311
-rw-r--r--gdb/dst.h1671
-rw-r--r--gdb/dstread.c1596
-rw-r--r--gdb/dve3900-rom.c1063
-rw-r--r--gdb/dwarf2cfi.c1784
-rw-r--r--gdb/dwarf2cfi.h66
-rw-r--r--gdb/dwarf2read.c6813
-rw-r--r--gdb/dwarfread.c3788
-rw-r--r--gdb/elfread.c790
-rw-r--r--gdb/environ.c185
-rw-r--r--gdb/environ.h51
-rw-r--r--gdb/eval.c1979
-rw-r--r--gdb/event-loop.h95
-rw-r--r--gdb/exc_request.defs51
-rw-r--r--gdb/exec.c775
-rw-r--r--gdb/expprint.c985
-rw-r--r--gdb/expression.h381
-rw-r--r--gdb/f-exp.y1180
-rw-r--r--gdb/f-lang.c957
-rw-r--r--gdb/f-lang.h98
-rw-r--r--gdb/f-typeprint.c400
-rw-r--r--gdb/f-valprint.c739
-rw-r--r--gdb/fbsd-proc.c173
-rw-r--r--gdb/findvar.c903
-rw-r--r--gdb/fork-child.c573
-rw-r--r--gdb/fr30-tdep.c601
-rw-r--r--gdb/frame.c171
-rw-r--r--gdb/frame.h293
-rw-r--r--gdb/gcore.c508
-rw-r--r--gdb/gdb-events.c351
-rw-r--r--gdb/gdb-events.h114
-rwxr-xr-xgdb/gdb-events.sh605
-rw-r--r--gdb/gdb-stabs.h87
-rw-r--r--gdb/gdb.1375
-rw-r--r--gdb/gdb.gdb35
-rw-r--r--gdb/gdb.h60
-rw-r--r--gdb/gdb_assert.h55
-rw-r--r--gdb/gdb_dirent.h40
-rwxr-xr-xgdb/gdb_indent.sh63
-rw-r--r--gdb/gdb_proc_service.h86
-rw-r--r--gdb/gdb_regex.h30
-rw-r--r--gdb/gdb_stat.h74
-rw-r--r--gdb/gdb_string.h67
-rw-r--r--gdb/gdb_thread_db.h450
-rw-r--r--gdb/gdb_vfork.h28
-rw-r--r--gdb/gdb_wait.h121
-rw-r--r--gdb/gdbarch.c5348
-rw-r--r--gdb/gdbarch.h2711
-rwxr-xr-xgdb/gdbarch.sh2330
-rw-r--r--gdb/gdbcmd.h122
-rw-r--r--gdb/gdbcore.h201
-rw-r--r--gdb/gdbinit.in18
-rw-r--r--gdb/gdbserver/Makefile.in299
-rw-r--r--gdb/gdbserver/README138
-rw-r--r--gdb/gdbserver/acconfig.h9
-rw-r--r--gdb/gdbserver/acinclude.m441
-rw-r--r--gdb/gdbserver/aclocal.m4100
-rw-r--r--gdb/gdbserver/config.in29
-rwxr-xr-xgdb/gdbserver/configure1606
-rw-r--r--gdb/gdbserver/configure.in74
-rw-r--r--gdb/gdbserver/configure.srv65
-rw-r--r--gdb/gdbserver/gdbreplay.c324
-rw-r--r--gdb/gdbserver/gdbserver.1116
-rw-r--r--gdb/gdbserver/i387-fp.c290
-rw-r--r--gdb/gdbserver/i387-fp.h33
-rw-r--r--gdb/gdbserver/inferiors.c105
-rw-r--r--gdb/gdbserver/linux-arm-low.c53
-rw-r--r--gdb/gdbserver/linux-i386-low.c157
-rw-r--r--gdb/gdbserver/linux-ia64-low.c303
-rw-r--r--gdb/gdbserver/linux-low.c590
-rw-r--r--gdb/gdbserver/linux-low.h49
-rw-r--r--gdb/gdbserver/linux-m68k-low.c72
-rw-r--r--gdb/gdbserver/linux-mips-low.c104
-rw-r--r--gdb/gdbserver/linux-ppc-low.c72
-rw-r--r--gdb/gdbserver/linux-s390-low.c88
-rw-r--r--gdb/gdbserver/linux-sh-low.c65
-rw-r--r--gdb/gdbserver/linux-x86-64-low.c85
-rw-r--r--gdb/gdbserver/low-hppabsd.c355
-rw-r--r--gdb/gdbserver/low-lynx.c745
-rw-r--r--gdb/gdbserver/low-nbsd.c599
-rw-r--r--gdb/gdbserver/low-sim.c269
-rw-r--r--gdb/gdbserver/low-sparc.c314
-rw-r--r--gdb/gdbserver/low-sun3.c291
-rw-r--r--gdb/gdbserver/mem-break.c280
-rw-r--r--gdb/gdbserver/mem-break.h71
-rw-r--r--gdb/gdbserver/proc-service.c256
-rw-r--r--gdb/gdbserver/regcache.c188
-rw-r--r--gdb/gdbserver/regcache.h67
-rw-r--r--gdb/gdbserver/remote-utils.c639
-rw-r--r--gdb/gdbserver/server.c359
-rw-r--r--gdb/gdbserver/server.h144
-rw-r--r--gdb/gdbserver/target.c47
-rw-r--r--gdb/gdbserver/target.h141
-rw-r--r--gdb/gdbserver/terminal.h51
-rw-r--r--gdb/gdbserver/thread-db.c342
-rw-r--r--gdb/gdbserver/utils.c99
-rw-r--r--gdb/gdbthread.h155
-rw-r--r--gdb/gdbtypes.c3518
-rw-r--r--gdb/gdbtypes.h1257
-rw-r--r--gdb/gnu-nat.c3439
-rw-r--r--gdb/gnu-nat.h101
-rw-r--r--gdb/gnu-v2-abi.c429
-rw-r--r--gdb/gnu-v3-abi.c450
-rw-r--r--gdb/go32-nat.c1963
-rw-r--r--gdb/gregset.h69
-rw-r--r--gdb/h8300-tdep.c890
-rw-r--r--gdb/h8500-tdep.c628
-rw-r--r--gdb/hp300ux-nat.c226
-rw-r--r--gdb/hpacc-abi.c328
-rw-r--r--gdb/hppa-tdep.c4773
-rw-r--r--gdb/hppab-nat.c214
-rw-r--r--gdb/hppah-nat.c1140
-rw-r--r--gdb/hppam3-nat.c141
-rw-r--r--gdb/hpread.c6339
-rw-r--r--gdb/hpux-thread.c585
-rw-r--r--gdb/i386-linux-nat.c955
-rw-r--r--gdb/i386-linux-tdep.c530
-rw-r--r--gdb/i386-linux-tdep.h36
-rw-r--r--gdb/i386-nat.c635
-rw-r--r--gdb/i386-stub.c952
-rw-r--r--gdb/i386-tdep.c1547
-rw-r--r--gdb/i386-tdep.h136
-rw-r--r--gdb/i386aix-nat.c377
-rw-r--r--gdb/i386b-nat.c291
-rw-r--r--gdb/i386bsd-nat.c400
-rw-r--r--gdb/i386bsd-tdep.c84
-rw-r--r--gdb/i386fbsd-nat.c102
-rw-r--r--gdb/i386gnu-nat.c293
-rw-r--r--gdb/i386ly-tdep.c45
-rw-r--r--gdb/i386m3-nat.c426
-rw-r--r--gdb/i386mach-nat.c172
-rw-r--r--gdb/i386nbsd-tdep.c155
-rw-r--r--gdb/i386v-nat.c289
-rw-r--r--gdb/i386v4-nat.c184
-rw-r--r--gdb/i387-tdep.c704
-rw-r--r--gdb/i387-tdep.h56
-rw-r--r--gdb/i960-tdep.c1055
-rw-r--r--gdb/ia64-aix-nat.c161
-rw-r--r--gdb/ia64-aix-tdep.c107
-rw-r--r--gdb/ia64-linux-nat.c644
-rw-r--r--gdb/ia64-linux-tdep.c87
-rw-r--r--gdb/ia64-tdep.c2259
-rw-r--r--gdb/inf-loop.c132
-rw-r--r--gdb/inf-loop.h29
-rw-r--r--gdb/infcmd.c2047
-rw-r--r--gdb/inferior.h549
-rw-r--r--gdb/inflow.c771
-rw-r--r--gdb/infptrace.c654
-rw-r--r--gdb/infrun.c4382
-rw-r--r--gdb/inftarg.c856
-rw-r--r--gdb/infttrace.c5754
-rw-r--r--gdb/irix4-nat.c207
-rw-r--r--gdb/irix5-nat.c1320
-rw-r--r--gdb/jv-exp.y1476
-rw-r--r--gdb/jv-lang.c1097
-rw-r--r--gdb/jv-lang.h73
-rw-r--r--gdb/jv-typeprint.c343
-rw-r--r--gdb/jv-valprint.c526
-rw-r--r--gdb/kod-cisco.c317
-rw-r--r--gdb/kod.c239
-rw-r--r--gdb/kod.h61
-rw-r--r--gdb/language.c1568
-rw-r--r--gdb/language.h466
-rw-r--r--gdb/lin-lwp.c1549
-rw-r--r--gdb/linespec.c1270
-rw-r--r--gdb/linespec.h27
-rw-r--r--gdb/linux-proc.c574
-rw-r--r--gdb/lynx-nat.c829
-rw-r--r--gdb/m2-exp.y1099
-rw-r--r--gdb/m2-lang.c468
-rw-r--r--gdb/m2-lang.h31
-rw-r--r--gdb/m2-typeprint.c41
-rw-r--r--gdb/m2-valprint.c39
-rw-r--r--gdb/m3-nat.c4565
-rw-r--r--gdb/m32r-rom.c626
-rw-r--r--gdb/m32r-stub.c1711
-rw-r--r--gdb/m32r-tdep.c705
-rw-r--r--gdb/m68hc11-tdep.c1172
-rw-r--r--gdb/m68k-stub.c1098
-rw-r--r--gdb/m68k-tdep.c685
-rw-r--r--gdb/m68klinux-nat.c710
-rw-r--r--gdb/m68knbsd-nat.c103
-rw-r--r--gdb/m68knbsd-tdep.c33
-rw-r--r--gdb/m88k-nat.c290
-rw-r--r--gdb/m88k-tdep.c661
-rw-r--r--gdb/macrocmd.c287
-rw-r--r--gdb/macroexp.c1169
-rw-r--r--gdb/macroexp.h90
-rw-r--r--gdb/macroscope.c107
-rw-r--r--gdb/macroscope.h63
-rw-r--r--gdb/macrotab.c905
-rw-r--r--gdb/macrotab.h295
-rw-r--r--gdb/maint.c798
-rw-r--r--gdb/mcore-rom.c208
-rw-r--r--gdb/mcore-tdep.c996
-rw-r--r--gdb/mdebugread.c5036
-rw-r--r--gdb/mem-break.c135
-rw-r--r--gdb/memattr.c536
-rw-r--r--gdb/memattr.h91
-rw-r--r--gdb/mi/ChangeLog1818
-rw-r--r--gdb/mi/gdbmi.texinfo3810
-rw-r--r--gdb/mi/mi-cmd-break.c240
-rw-r--r--gdb/mi/mi-cmd-disas.c499
-rw-r--r--gdb/mi/mi-cmd-stack.c309
-rw-r--r--gdb/mi/mi-cmd-var.c498
-rw-r--r--gdb/mi/mi-console.c115
-rw-r--r--gdb/mi/mi-console.h27
-rw-r--r--gdb/mi/mi-getopt.c76
-rw-r--r--gdb/mi/mi-getopt.h60
-rw-r--r--gdb/mi/mi-out.c452
-rw-r--r--gdb/mi/mi-out.h33
-rw-r--r--gdb/mi/mi-parse.c238
-rw-r--r--gdb/mi/mi-parse.h55
-rw-r--r--gdb/minimon.h601
-rw-r--r--gdb/minsyms.c987
-rw-r--r--gdb/mips-linux-nat.c58
-rw-r--r--gdb/mips-linux-tdep.c344
-rw-r--r--gdb/mips-nat.c246
-rw-r--r--gdb/mips-tdep.c5002
-rw-r--r--gdb/mipsm3-nat.c386
-rw-r--r--gdb/mipsnbsd-nat.c101
-rw-r--r--gdb/mipsnbsd-tdep.c367
-rw-r--r--gdb/mipsnbsd-tdep.h33
-rw-r--r--gdb/mipsread.c445
-rw-r--r--gdb/mipsv4-nat.c160
-rw-r--r--gdb/mn10200-tdep.c892
-rw-r--r--gdb/mn10300-tdep.c1223
-rw-r--r--gdb/mon960-rom.c260
-rw-r--r--gdb/monitor.c2386
-rw-r--r--gdb/monitor.h254
-rw-r--r--gdb/msg.defs1
-rw-r--r--gdb/msg_reply.defs1
-rw-r--r--gdb/nbsd-tdep.c98
-rw-r--r--gdb/nbsd-tdep.h28
-rw-r--r--gdb/nindy-share/Makefile117
-rw-r--r--gdb/nindy-share/Onindy.c743
-rw-r--r--gdb/nindy-share/README3
-rw-r--r--gdb/nindy-share/VERSION1
-rw-r--r--gdb/nindy-share/b.out.h158
-rw-r--r--gdb/nindy-share/block_io.h68
-rw-r--r--gdb/nindy-share/coff.h336
-rw-r--r--gdb/nindy-share/env.h12
-rw-r--r--gdb/nindy-share/nindy.c1154
-rw-r--r--gdb/nindy-share/stop.h86
-rw-r--r--gdb/nindy-share/ttyflush.c48
-rw-r--r--gdb/nindy-tdep.c78
-rw-r--r--gdb/nlm/Makefile.in176
-rwxr-xr-xgdb/nlm/configure1074
-rw-r--r--gdb/nlm/configure.in55
-rw-r--r--gdb/nlm/gdbserve.c1033
-rw-r--r--gdb/nlm/gdbserve.def42
-rw-r--r--gdb/nlm/i386.c100
-rw-r--r--gdb/nlm/i386.h13
-rw-r--r--gdb/nlm/ppc.c244
-rw-r--r--gdb/nlm/ppc.h165
-rw-r--r--gdb/nlm/prelude.c67
-rw-r--r--gdb/nlmread.c248
-rw-r--r--gdb/notify.defs1
-rw-r--r--gdb/ns32k-tdep.c673
-rw-r--r--gdb/ns32k-tdep.h66
-rw-r--r--gdb/ns32knbsd-nat.c364
-rw-r--r--gdb/ns32knbsd-tdep.c70
-rw-r--r--gdb/objfiles.c1010
-rw-r--r--gdb/objfiles.h610
-rw-r--r--gdb/ocd.c1388
-rw-r--r--gdb/ocd.h139
-rw-r--r--gdb/op50-rom.c142
-rw-r--r--gdb/os9kread.c1621
-rw-r--r--gdb/osabi.c424
-rw-r--r--gdb/osabi.h78
-rw-r--r--gdb/osf-share/AT386/cma_thread_io.h457
-rw-r--r--gdb/osf-share/HP800/cma_thread_io.h432
-rw-r--r--gdb/osf-share/README8
-rw-r--r--gdb/osf-share/RIOS/cma_thread_io.h434
-rw-r--r--gdb/osf-share/cma_attr.h341
-rw-r--r--gdb/osf-share/cma_deb_core.h164
-rw-r--r--gdb/osf-share/cma_debug_client.h195
-rw-r--r--gdb/osf-share/cma_errors.h55
-rw-r--r--gdb/osf-share/cma_handle.h182
-rw-r--r--gdb/osf-share/cma_init.h114
-rw-r--r--gdb/osf-share/cma_list.h84
-rw-r--r--gdb/osf-share/cma_mutex.h230
-rw-r--r--gdb/osf-share/cma_sched.h279
-rw-r--r--gdb/osf-share/cma_semaphore_defs.h46
-rw-r--r--gdb/osf-share/cma_sequence.h56
-rw-r--r--gdb/osf-share/cma_stack.h83
-rw-r--r--gdb/osf-share/cma_stack_int.h136
-rw-r--r--gdb/osf-share/cma_tcb_defs.h269
-rw-r--r--gdb/osf-share/cma_util.h125
-rw-r--r--gdb/osfsolib.c938
-rw-r--r--gdb/p-exp.y1610
-rw-r--r--gdb/p-lang.c478
-rw-r--r--gdb/p-lang.h76
-rw-r--r--gdb/p-typeprint.c817
-rw-r--r--gdb/p-valprint.c1117
-rw-r--r--gdb/pa64solib.c1244
-rw-r--r--gdb/pa64solib.h149
-rw-r--r--gdb/parse.c1395
-rw-r--r--gdb/parser-defs.h219
-rw-r--r--gdb/ppc-bdm.c388
-rw-r--r--gdb/ppc-linux-nat.c553
-rw-r--r--gdb/ppc-linux-tdep.c888
-rw-r--r--gdb/ppc-sysv-tdep.c312
-rw-r--r--gdb/ppc-tdep.h75
-rw-r--r--gdb/ppcbug-rom.c223
-rw-r--r--gdb/ppcnbsd-nat.c123
-rw-r--r--gdb/ppcnbsd-tdep.c222
-rw-r--r--gdb/ppcnbsd-tdep.h30
-rw-r--r--gdb/printcmd.c2567
-rw-r--r--gdb/proc-api.c789
-rw-r--r--gdb/proc-events.c1777
-rw-r--r--gdb/proc-flags.c291
-rw-r--r--gdb/proc-service.c312
-rw-r--r--gdb/proc-utils.h102
-rw-r--r--gdb/proc-why.c175
-rw-r--r--gdb/process_reply.defs1
-rw-r--r--gdb/procfs.c5857
-rw-r--r--gdb/ptx4-nat.c211
-rw-r--r--gdb/rdi-share/Makefile.am19
-rw-r--r--gdb/rdi-share/Makefile.in296
-rw-r--r--gdb/rdi-share/README.CYGNUS6
-rw-r--r--gdb/rdi-share/aclocal.m4202
-rw-r--r--gdb/rdi-share/adp.h2528
-rw-r--r--gdb/rdi-share/adperr.h74
-rw-r--r--gdb/rdi-share/angel.h177
-rw-r--r--gdb/rdi-share/angel_bytesex.c57
-rw-r--r--gdb/rdi-share/angel_bytesex.h42
-rw-r--r--gdb/rdi-share/angel_endian.h125
-rw-r--r--gdb/rdi-share/ardi.c2693
-rw-r--r--gdb/rdi-share/ardi.h87
-rw-r--r--gdb/rdi-share/armdbg.h1452
-rw-r--r--gdb/rdi-share/buffers.h111
-rw-r--r--gdb/rdi-share/chandefs.h50
-rw-r--r--gdb/rdi-share/channels.h384
-rw-r--r--gdb/rdi-share/chanpriv.h57
-rwxr-xr-xgdb/rdi-share/configure2115
-rw-r--r--gdb/rdi-share/configure.in36
-rw-r--r--gdb/rdi-share/crc.c257
-rw-r--r--gdb/rdi-share/crc.h90
-rw-r--r--gdb/rdi-share/dbg_conf.h54
-rw-r--r--gdb/rdi-share/dbg_cp.h62
-rw-r--r--gdb/rdi-share/dbg_hif.h56
-rw-r--r--gdb/rdi-share/dbg_rdi.h511
-rw-r--r--gdb/rdi-share/devclnt.h260
-rw-r--r--gdb/rdi-share/devices.h104
-rw-r--r--gdb/rdi-share/devsw.c612
-rw-r--r--gdb/rdi-share/devsw.h275
-rw-r--r--gdb/rdi-share/drivers.c34
-rw-r--r--gdb/rdi-share/drivers.h193
-rw-r--r--gdb/rdi-share/etherdrv.c737
-rw-r--r--gdb/rdi-share/ethernet.h99
-rw-r--r--gdb/rdi-share/host.h225
-rw-r--r--gdb/rdi-share/hostchan.c1067
-rw-r--r--gdb/rdi-share/hostchan.h322
-rw-r--r--gdb/rdi-share/hsys.c917
-rw-r--r--gdb/rdi-share/hsys.h101
-rw-r--r--gdb/rdi-share/logging.c369
-rw-r--r--gdb/rdi-share/logging.h121
-rw-r--r--gdb/rdi-share/msgbuild.c282
-rw-r--r--gdb/rdi-share/msgbuild.h75
-rw-r--r--gdb/rdi-share/params.c325
-rw-r--r--gdb/rdi-share/params.h181
-rw-r--r--gdb/rdi-share/rx.c361
-rw-r--r--gdb/rdi-share/rxtx.h263
-rw-r--r--gdb/rdi-share/serdrv.c667
-rw-r--r--gdb/rdi-share/serpardr.c730
-rw-r--r--gdb/rdi-share/sys.h319
-rw-r--r--gdb/rdi-share/tx.c176
-rw-r--r--gdb/rdi-share/unixcomm.c563
-rw-r--r--gdb/rdi-share/unixcomm.h212
-rw-r--r--gdb/regcache.c799
-rw-r--r--gdb/regcache.h82
-rw-r--r--gdb/regformats/reg-arm.dat28
-rw-r--r--gdb/regformats/reg-i386-linux.dat44
-rw-r--r--gdb/regformats/reg-i386.dat43
-rw-r--r--gdb/regformats/reg-ia64.dat603
-rw-r--r--gdb/regformats/reg-m68k.dat35
-rw-r--r--gdb/regformats/reg-mips.dat112
-rw-r--r--gdb/regformats/reg-ppc.dat76
-rw-r--r--gdb/regformats/reg-s390.dat69
-rw-r--r--gdb/regformats/reg-s390x.dat69
-rw-r--r--gdb/regformats/reg-sh.dat62
-rw-r--r--gdb/regformats/reg-x86-64.dat57
-rwxr-xr-xgdb/regformats/regdat.sh169
-rw-r--r--gdb/regformats/regdef.h46
-rw-r--r--gdb/remote-array.c1460
-rw-r--r--gdb/remote-bug.c1027
-rw-r--r--gdb/remote-e7000.c2227
-rw-r--r--gdb/remote-es.c2127
-rw-r--r--gdb/remote-est.c169
-rw-r--r--gdb/remote-hms.c157
-rw-r--r--gdb/remote-mips.c3599
-rw-r--r--gdb/remote-nindy.c762
-rw-r--r--gdb/remote-nrom.c351
-rw-r--r--gdb/remote-os9k.c1234
-rw-r--r--gdb/remote-rdi.c1070
-rw-r--r--gdb/remote-rdp.c1449
-rw-r--r--gdb/remote-sds.c1145
-rw-r--r--gdb/remote-sim.c941
-rw-r--r--gdb/remote-st.c839
-rw-r--r--gdb/remote-utils.c609
-rw-r--r--gdb/remote-utils.h133
-rw-r--r--gdb/remote-vx.c1410
-rw-r--r--gdb/remote-vx29k.c182
-rw-r--r--gdb/remote-vx68.c156
-rw-r--r--gdb/remote-vx960.c160
-rw-r--r--gdb/remote-vxmips.c199
-rw-r--r--gdb/remote-vxsparc.c194
-rw-r--r--gdb/remote.c6218
-rw-r--r--gdb/remote.h57
-rw-r--r--gdb/reply_mig_hack.awk123
-rw-r--r--gdb/rom68k-rom.c246
-rw-r--r--gdb/rs6000-nat.c1172
-rw-r--r--gdb/rs6000-tdep.c2823
-rw-r--r--gdb/s390-nat.c310
-rw-r--r--gdb/s390-tdep.c1886
-rw-r--r--gdb/saber.suppress451
-rw-r--r--gdb/scm-exp.c495
-rw-r--r--gdb/scm-lang.c267
-rw-r--r--gdb/scm-lang.h70
-rw-r--r--gdb/scm-tags.h379
-rw-r--r--gdb/scm-valprint.c395
-rw-r--r--gdb/ser-e7kpc.c438
-rw-r--r--gdb/ser-go32.c964
-rw-r--r--gdb/ser-pipe.c161
-rw-r--r--gdb/ser-tcp.c231
-rw-r--r--gdb/ser-unix.c1363
-rw-r--r--gdb/ser-unix.h51
-rw-r--r--gdb/serial.c712
-rw-r--r--gdb/serial.h241
-rw-r--r--gdb/sh-stub.c1583
-rw-r--r--gdb/sh-tdep.c4600
-rw-r--r--gdb/sh-tdep.h111
-rw-r--r--gdb/sh3-rom.c384
-rw-r--r--gdb/shnbsd-nat.c76
-rw-r--r--gdb/shnbsd-tdep.c183
-rw-r--r--gdb/shnbsd-tdep.h28
-rw-r--r--gdb/signals/signals.c844
-rw-r--r--gdb/sim-regno.h45
-rw-r--r--gdb/sol-thread.c1706
-rw-r--r--gdb/solib-aix5.c958
-rw-r--r--gdb/solib-legacy.c151
-rw-r--r--gdb/solib-osf.c616
-rw-r--r--gdb/solib-sunos.c897
-rw-r--r--gdb/solib-svr4.c1360
-rw-r--r--gdb/solib-svr4.h78
-rw-r--r--gdb/solib.c884
-rw-r--r--gdb/solib.h204
-rw-r--r--gdb/solist.h126
-rw-r--r--gdb/somread.c734
-rw-r--r--gdb/somsolib.c1616
-rw-r--r--gdb/somsolib.h165
-rw-r--r--gdb/source.c1692
-rw-r--r--gdb/source.h34
-rw-r--r--gdb/sparc-linux-nat.c100
-rw-r--r--gdb/sparc-nat.c349
-rw-r--r--gdb/sparc-stub.c778
-rw-r--r--gdb/sparc-tdep.c3286
-rw-r--r--gdb/sparc64nbsd-nat.c207
-rw-r--r--gdb/sparcl-stub.c946
-rw-r--r--gdb/sparcl-tdep.c869
-rw-r--r--gdb/sparclet-rom.c316
-rw-r--r--gdb/sparclet-stub.c1167
-rw-r--r--gdb/sparcnbsd-nat.c154
-rw-r--r--gdb/sparcnbsd-tdep.c531
-rw-r--r--gdb/sparcnbsd-tdep.h34
-rw-r--r--gdb/srec.h37
-rw-r--r--gdb/stabsread.c5403
-rw-r--r--gdb/stabsread.h226
-rw-r--r--gdb/stack.c1973
-rw-r--r--gdb/standalone.c579
-rw-r--r--gdb/std-regs.c150
-rw-r--r--gdb/stop-gdb.c109
-rw-r--r--gdb/sun3-nat.c165
-rw-r--r--gdb/symfile.c3353
-rw-r--r--gdb/symfile.h328
-rw-r--r--gdb/symm-nat.c902
-rw-r--r--gdb/symm-tdep.c102
-rw-r--r--gdb/symmisc.c1073
-rw-r--r--gdb/symtab.c3985
-rw-r--r--gdb/symtab.h1396
-rw-r--r--gdb/target.c2317
-rw-r--r--gdb/target.h1269
-rw-r--r--gdb/terminal.h91
-rw-r--r--gdb/testsuite/.gdbinit1
-rw-r--r--gdb/testsuite/ChangeLog9078
-rw-r--r--gdb/testsuite/Makefile.in192
-rw-r--r--gdb/testsuite/TODO202
-rw-r--r--gdb/testsuite/aclocal.m4583
-rw-r--r--gdb/testsuite/config/abug.exp20
-rw-r--r--gdb/testsuite/config/arm-ice.exp1
-rw-r--r--gdb/testsuite/config/cfdbug.exp20
-rw-r--r--gdb/testsuite/config/cpu32bug.exp20
-rw-r--r--gdb/testsuite/config/cygmon.exp1
-rw-r--r--gdb/testsuite/config/d10v.exp20
-rw-r--r--gdb/testsuite/config/dve.exp23
-rw-r--r--gdb/testsuite/config/est.exp20
-rw-r--r--gdb/testsuite/config/gdbserver.exp212
-rw-r--r--gdb/testsuite/config/h8300.exp1
-rw-r--r--gdb/testsuite/config/hmsirom.exp22
-rw-r--r--gdb/testsuite/config/hppro.exp24
-rw-r--r--gdb/testsuite/config/i386-bozo.exp1
-rw-r--r--gdb/testsuite/config/i960.exp20
-rw-r--r--gdb/testsuite/config/m32r-stub.exp1
-rw-r--r--gdb/testsuite/config/m32r.exp23
-rw-r--r--gdb/testsuite/config/m68k-emc.exp17
-rw-r--r--gdb/testsuite/config/mips-idt.exp22
-rw-r--r--gdb/testsuite/config/mips.exp22
-rw-r--r--gdb/testsuite/config/mn10300-eval.exp23
-rw-r--r--gdb/testsuite/config/monitor.exp271
-rw-r--r--gdb/testsuite/config/netware.exp218
-rw-r--r--gdb/testsuite/config/nind.exp49
-rw-r--r--gdb/testsuite/config/proelf.exp20
-rw-r--r--gdb/testsuite/config/rom68k.exp20
-rw-r--r--gdb/testsuite/config/sh.exp20
-rw-r--r--gdb/testsuite/config/sid.exp216
-rw-r--r--gdb/testsuite/config/sim.exp85
-rw-r--r--gdb/testsuite/config/slite.exp183
-rw-r--r--gdb/testsuite/config/sparclet.exp391
-rw-r--r--gdb/testsuite/config/udi.exp113
-rw-r--r--gdb/testsuite/config/unix.exp29
-rw-r--r--gdb/testsuite/config/unknown.exp21
-rw-r--r--gdb/testsuite/config/vr4300.exp20
-rw-r--r--gdb/testsuite/config/vr5000.exp20
-rw-r--r--gdb/testsuite/config/vx.exp131
-rw-r--r--gdb/testsuite/config/vxworks.exp20
-rw-r--r--gdb/testsuite/config/vxworks29k.exp27
-rwxr-xr-xgdb/testsuite/configure1214
-rw-r--r--gdb/testsuite/configure.in117
-rw-r--r--gdb/testsuite/gdb.arch/Makefile.in31
-rw-r--r--gdb/testsuite/gdb.arch/altivec-abi.c141
-rw-r--r--gdb/testsuite/gdb.arch/altivec-abi.exp113
-rw-r--r--gdb/testsuite/gdb.arch/altivec-regs.c41
-rw-r--r--gdb/testsuite/gdb.arch/altivec-regs.exp220
-rwxr-xr-xgdb/testsuite/gdb.arch/configure913
-rw-r--r--gdb/testsuite/gdb.arch/configure.in15
-rw-r--r--gdb/testsuite/gdb.asm/Makefile.in36
-rw-r--r--gdb/testsuite/gdb.asm/arm.inc34
-rw-r--r--gdb/testsuite/gdb.asm/asm-source.exp288
-rw-r--r--gdb/testsuite/gdb.asm/asmsrc1.s63
-rw-r--r--gdb/testsuite/gdb.asm/asmsrc2.s17
-rw-r--r--gdb/testsuite/gdb.asm/common.inc28
-rwxr-xr-xgdb/testsuite/gdb.asm/configure913
-rw-r--r--gdb/testsuite/gdb.asm/configure.in15
-rw-r--r--gdb/testsuite/gdb.asm/d10v.inc55
-rw-r--r--gdb/testsuite/gdb.asm/i386.inc39
-rw-r--r--gdb/testsuite/gdb.asm/m32r.inc35
-rw-r--r--gdb/testsuite/gdb.asm/powerpc.inc46
-rw-r--r--gdb/testsuite/gdb.asm/s390.inc75
-rw-r--r--gdb/testsuite/gdb.asm/sparc.inc34
-rw-r--r--gdb/testsuite/gdb.asm/sparc64.inc34
-rw-r--r--gdb/testsuite/gdb.asm/v850.inc41
-rw-r--r--gdb/testsuite/gdb.asm/x86_64.inc39
-rw-r--r--gdb/testsuite/gdb.asm/xstormy16.inc34
-rw-r--r--gdb/testsuite/gdb.base/Makefile.in43
-rw-r--r--gdb/testsuite/gdb.base/a2-run.exp257
-rw-r--r--gdb/testsuite/gdb.base/all-bin.exp471
-rw-r--r--gdb/testsuite/gdb.base/all-types.c62
-rw-r--r--gdb/testsuite/gdb.base/annota1.c51
-rw-r--r--gdb/testsuite/gdb.base/annota1.exp463
-rw-r--r--gdb/testsuite/gdb.base/arithmet.exp117
-rw-r--r--gdb/testsuite/gdb.base/assign.exp446
-rw-r--r--gdb/testsuite/gdb.base/async.c48
-rw-r--r--gdb/testsuite/gdb.base/async.exp153
-rw-r--r--gdb/testsuite/gdb.base/attach.c20
-rw-r--r--gdb/testsuite/gdb.base/attach.exp432
-rw-r--r--gdb/testsuite/gdb.base/attach2.c24
-rw-r--r--gdb/testsuite/gdb.base/average.c46
-rw-r--r--gdb/testsuite/gdb.base/bar.c9
-rw-r--r--gdb/testsuite/gdb.base/baz.c9
-rw-r--r--gdb/testsuite/gdb.base/bitfields.c194
-rw-r--r--gdb/testsuite/gdb.base/bitfields.exp268
-rw-r--r--gdb/testsuite/gdb.base/bitops.exp365
-rw-r--r--gdb/testsuite/gdb.base/branches.c113
-rw-r--r--gdb/testsuite/gdb.base/break.c131
-rw-r--r--gdb/testsuite/gdb.base/break.exp949
-rw-r--r--gdb/testsuite/gdb.base/call-ar-st.c1339
-rw-r--r--gdb/testsuite/gdb.base/call-ar-st.exp705
-rw-r--r--gdb/testsuite/gdb.base/call-rt-st.c633
-rw-r--r--gdb/testsuite/gdb.base/call-rt-st.exp213
-rw-r--r--gdb/testsuite/gdb.base/call-strs.c78
-rw-r--r--gdb/testsuite/gdb.base/call-strs.exp268
-rw-r--r--gdb/testsuite/gdb.base/callfuncs.c371
-rw-r--r--gdb/testsuite/gdb.base/callfuncs.exp441
-rw-r--r--gdb/testsuite/gdb.base/code-expr.exp395
-rw-r--r--gdb/testsuite/gdb.base/commands.exp456
-rw-r--r--gdb/testsuite/gdb.base/completion.exp749
-rw-r--r--gdb/testsuite/gdb.base/cond-expr.exp122
-rw-r--r--gdb/testsuite/gdb.base/condbreak.exp207
-rw-r--r--gdb/testsuite/gdb.base/configure902
-rw-r--r--gdb/testsuite/gdb.base/configure.in15
-rw-r--r--gdb/testsuite/gdb.base/consecutive.c20
-rw-r--r--gdb/testsuite/gdb.base/consecutive.exp111
-rw-r--r--gdb/testsuite/gdb.base/constvars.c183
-rw-r--r--gdb/testsuite/gdb.base/constvars.exp283
-rw-r--r--gdb/testsuite/gdb.base/corefile.exp232
-rw-r--r--gdb/testsuite/gdb.base/coremaker.c122
-rw-r--r--gdb/testsuite/gdb.base/coremaker2.c58
-rw-r--r--gdb/testsuite/gdb.base/cvexpr.c434
-rw-r--r--gdb/testsuite/gdb.base/cvexpr.exp510
-rw-r--r--gdb/testsuite/gdb.base/d10v.ld155
-rw-r--r--gdb/testsuite/gdb.base/d10vovly.c225
-rw-r--r--gdb/testsuite/gdb.base/dbx.exp340
-rw-r--r--gdb/testsuite/gdb.base/default.exp818
-rw-r--r--gdb/testsuite/gdb.base/define.exp304
-rw-r--r--gdb/testsuite/gdb.base/display.c52
-rw-r--r--gdb/testsuite/gdb.base/display.exp215
-rw-r--r--gdb/testsuite/gdb.base/dump.c44
-rw-r--r--gdb/testsuite/gdb.base/dump.exp442
-rw-r--r--gdb/testsuite/gdb.base/echo.exp44
-rw-r--r--gdb/testsuite/gdb.base/ena-dis-br.exp493
-rw-r--r--gdb/testsuite/gdb.base/ending-run.c33
-rw-r--r--gdb/testsuite/gdb.base/ending-run.exp289
-rw-r--r--gdb/testsuite/gdb.base/environ.exp329
-rw-r--r--gdb/testsuite/gdb.base/eval-skip.exp352
-rw-r--r--gdb/testsuite/gdb.base/execd-prog.c34
-rw-r--r--gdb/testsuite/gdb.base/exprs.c254
-rw-r--r--gdb/testsuite/gdb.base/exprs.exp259
-rw-r--r--gdb/testsuite/gdb.base/finish.exp125
-rw-r--r--gdb/testsuite/gdb.base/foll-exec.c43
-rw-r--r--gdb/testsuite/gdb.base/foll-exec.exp400
-rw-r--r--gdb/testsuite/gdb.base/foll-fork.c34
-rw-r--r--gdb/testsuite/gdb.base/foll-fork.exp367
-rw-r--r--gdb/testsuite/gdb.base/foll-vfork.c20
-rw-r--r--gdb/testsuite/gdb.base/foll-vfork.exp369
-rw-r--r--gdb/testsuite/gdb.base/foo.c9
-rw-r--r--gdb/testsuite/gdb.base/funcargs.c792
-rw-r--r--gdb/testsuite/gdb.base/funcargs.exp1262
-rw-r--r--gdb/testsuite/gdb.base/gcore.c52
-rw-r--r--gdb/testsuite/gdb.base/gcore.exp220
-rw-r--r--gdb/testsuite/gdb.base/gdbvars.exp117
-rw-r--r--gdb/testsuite/gdb.base/grbx.c10
-rw-r--r--gdb/testsuite/gdb.base/help.exp597
-rw-r--r--gdb/testsuite/gdb.base/huge.c17
-rw-r--r--gdb/testsuite/gdb.base/huge.exp57
-rw-r--r--gdb/testsuite/gdb.base/info-proc.exp75
-rw-r--r--gdb/testsuite/gdb.base/int-type.c25
-rw-r--r--gdb/testsuite/gdb.base/interrupt.c40
-rw-r--r--gdb/testsuite/gdb.base/interrupt.exp185
-rw-r--r--gdb/testsuite/gdb.base/jump.c24
-rw-r--r--gdb/testsuite/gdb.base/jump.exp187
-rw-r--r--gdb/testsuite/gdb.base/langs.exp149
-rw-r--r--gdb/testsuite/gdb.base/langs0.c34
-rw-r--r--gdb/testsuite/gdb.base/langs1.c41
-rw-r--r--gdb/testsuite/gdb.base/langs1.f7
-rw-r--r--gdb/testsuite/gdb.base/langs2.c32
-rw-r--r--gdb/testsuite/gdb.base/langs2.cxx13
-rw-r--r--gdb/testsuite/gdb.base/list.exp559
-rw-r--r--gdb/testsuite/gdb.base/list0.c43
-rw-r--r--gdb/testsuite/gdb.base/list0.h37
-rw-r--r--gdb/testsuite/gdb.base/list1.c39
-rw-r--r--gdb/testsuite/gdb.base/logical.exp577
-rw-r--r--gdb/testsuite/gdb.base/long_long.c61
-rw-r--r--gdb/testsuite/gdb.base/long_long.exp304
-rw-r--r--gdb/testsuite/gdb.base/m32r.ld160
-rw-r--r--gdb/testsuite/gdb.base/m32rovly.c225
-rw-r--r--gdb/testsuite/gdb.base/macscp.exp403
-rw-r--r--gdb/testsuite/gdb.base/macscp1.c80
-rw-r--r--gdb/testsuite/gdb.base/macscp2.h25
-rw-r--r--gdb/testsuite/gdb.base/macscp3.h25
-rw-r--r--gdb/testsuite/gdb.base/macscp4.h44
-rw-r--r--gdb/testsuite/gdb.base/maint.exp678
-rw-r--r--gdb/testsuite/gdb.base/mips_pro.c57
-rw-r--r--gdb/testsuite/gdb.base/mips_pro.exp67
-rw-r--r--gdb/testsuite/gdb.base/miscexprs.c49
-rw-r--r--gdb/testsuite/gdb.base/miscexprs.exp311
-rw-r--r--gdb/testsuite/gdb.base/nodebug.c81
-rw-r--r--gdb/testsuite/gdb.base/nodebug.exp181
-rw-r--r--gdb/testsuite/gdb.base/opaque.exp267
-rw-r--r--gdb/testsuite/gdb.base/opaque0.c23
-rw-r--r--gdb/testsuite/gdb.base/opaque1.c18
-rw-r--r--gdb/testsuite/gdb.base/overlays.c34
-rw-r--r--gdb/testsuite/gdb.base/overlays.exp282
-rw-r--r--gdb/testsuite/gdb.base/ovlymgr.c233
-rw-r--r--gdb/testsuite/gdb.base/ovlymgr.h17
-rw-r--r--gdb/testsuite/gdb.base/page.exp40
-rw-r--r--gdb/testsuite/gdb.base/pointers.c216
-rw-r--r--gdb/testsuite/gdb.base/pointers.exp596
-rw-r--r--gdb/testsuite/gdb.base/printcmds.c107
-rw-r--r--gdb/testsuite/gdb.base/printcmds.exp715
-rw-r--r--gdb/testsuite/gdb.base/ptype.c346
-rw-r--r--gdb/testsuite/gdb.base/ptype.exp609
-rw-r--r--gdb/testsuite/gdb.base/radix.exp201
-rw-r--r--gdb/testsuite/gdb.base/recurse.c31
-rw-r--r--gdb/testsuite/gdb.base/recurse.exp168
-rw-r--r--gdb/testsuite/gdb.base/regs.exp86
-rw-r--r--gdb/testsuite/gdb.base/relational.exp484
-rw-r--r--gdb/testsuite/gdb.base/relocate.c17
-rw-r--r--gdb/testsuite/gdb.base/relocate.exp108
-rw-r--r--gdb/testsuite/gdb.base/remote.c6194
-rw-r--r--gdb/testsuite/gdb.base/remote.exp195
-rw-r--r--gdb/testsuite/gdb.base/reread.exp189
-rw-r--r--gdb/testsuite/gdb.base/reread1.c26
-rw-r--r--gdb/testsuite/gdb.base/reread2.c21
-rw-r--r--gdb/testsuite/gdb.base/restore.c260
-rw-r--r--gdb/testsuite/gdb.base/restore.exp113
-rw-r--r--gdb/testsuite/gdb.base/return.c36
-rw-r--r--gdb/testsuite/gdb.base/return.exp129
-rw-r--r--gdb/testsuite/gdb.base/return2.c110
-rw-r--r--gdb/testsuite/gdb.base/return2.exp129
-rw-r--r--gdb/testsuite/gdb.base/run.c82
-rw-r--r--gdb/testsuite/gdb.base/scope.exp608
-rw-r--r--gdb/testsuite/gdb.base/scope0.c208
-rw-r--r--gdb/testsuite/gdb.base/scope1.c54
-rw-r--r--gdb/testsuite/gdb.base/sect-cmd.exp125
-rw-r--r--gdb/testsuite/gdb.base/selftest.exp446
-rw-r--r--gdb/testsuite/gdb.base/setshow.c27
-rw-r--r--gdb/testsuite/gdb.base/setshow.exp243
-rw-r--r--gdb/testsuite/gdb.base/setvar.c278
-rw-r--r--gdb/testsuite/gdb.base/setvar.exp434
-rw-r--r--gdb/testsuite/gdb.base/shlib-call.exp296
-rw-r--r--gdb/testsuite/gdb.base/shmain.c56
-rw-r--r--gdb/testsuite/gdb.base/shr1.c63
-rw-r--r--gdb/testsuite/gdb.base/shr2.c17
-rw-r--r--gdb/testsuite/gdb.base/sigall.c1810
-rw-r--r--gdb/testsuite/gdb.base/sigall.exp210
-rw-r--r--gdb/testsuite/gdb.base/signals.c59
-rw-r--r--gdb/testsuite/gdb.base/signals.exp639
-rw-r--r--gdb/testsuite/gdb.base/sizeof.c122
-rw-r--r--gdb/testsuite/gdb.base/sizeof.exp208
-rw-r--r--gdb/testsuite/gdb.base/so-impl-ld.c23
-rw-r--r--gdb/testsuite/gdb.base/so-impl-ld.exp172
-rw-r--r--gdb/testsuite/gdb.base/so-indr-cl.c30
-rw-r--r--gdb/testsuite/gdb.base/so-indr-cl.exp139
-rw-r--r--gdb/testsuite/gdb.base/solib.c60
-rw-r--r--gdb/testsuite/gdb.base/solib.exp360
-rw-r--r--gdb/testsuite/gdb.base/solib1.c18
-rw-r--r--gdb/testsuite/gdb.base/solib2.c19
-rw-r--r--gdb/testsuite/gdb.base/ss.h4
-rw-r--r--gdb/testsuite/gdb.base/step-line.c84
-rw-r--r--gdb/testsuite/gdb.base/step-line.exp95
-rw-r--r--gdb/testsuite/gdb.base/step-line.inp41
-rw-r--r--gdb/testsuite/gdb.base/step-test.c61
-rw-r--r--gdb/testsuite/gdb.base/step-test.exp241
-rw-r--r--gdb/testsuite/gdb.base/structs.c263
-rw-r--r--gdb/testsuite/gdb.base/structs.exp167
-rw-r--r--gdb/testsuite/gdb.base/structs2.c38
-rw-r--r--gdb/testsuite/gdb.base/structs2.exp79
-rw-r--r--gdb/testsuite/gdb.base/sum.c15
-rw-r--r--gdb/testsuite/gdb.base/term.exp76
-rw-r--r--gdb/testsuite/gdb.base/twice.c21
-rw-r--r--gdb/testsuite/gdb.base/twice.exp64
-rw-r--r--gdb/testsuite/gdb.base/varargs.c111
-rw-r--r--gdb/testsuite/gdb.base/varargs.exp148
-rw-r--r--gdb/testsuite/gdb.base/vforked-prog.c11
-rw-r--r--gdb/testsuite/gdb.base/volatile.exp268
-rw-r--r--gdb/testsuite/gdb.base/watchpoint.c174
-rw-r--r--gdb/testsuite/gdb.base/watchpoint.exp806
-rw-r--r--gdb/testsuite/gdb.base/whatis-exp.exp217
-rw-r--r--gdb/testsuite/gdb.base/whatis.c269
-rw-r--r--gdb/testsuite/gdb.base/whatis.exp419
-rw-r--r--gdb/testsuite/gdb.c++/Makefile.in27
-rw-r--r--gdb/testsuite/gdb.c++/ambiguous.cc110
-rw-r--r--gdb/testsuite/gdb.c++/ambiguous.exp237
-rw-r--r--gdb/testsuite/gdb.c++/annota2.cc28
-rw-r--r--gdb/testsuite/gdb.c++/annota2.exp231
-rw-r--r--gdb/testsuite/gdb.c++/anon-union.cc55
-rw-r--r--gdb/testsuite/gdb.c++/anon-union.exp347
-rw-r--r--gdb/testsuite/gdb.c++/classes.exp929
-rw-r--r--gdb/testsuite/gdb.c++/configure899
-rw-r--r--gdb/testsuite/gdb.c++/configure.in15
-rw-r--r--gdb/testsuite/gdb.c++/cplusfuncs.cc196
-rw-r--r--gdb/testsuite/gdb.c++/cplusfuncs.exp542
-rw-r--r--gdb/testsuite/gdb.c++/ctti.exp269
-rw-r--r--gdb/testsuite/gdb.c++/cttiadd.cc29
-rw-r--r--gdb/testsuite/gdb.c++/cttiadd1.cc16
-rw-r--r--gdb/testsuite/gdb.c++/cttiadd2.cc22
-rw-r--r--gdb/testsuite/gdb.c++/cttiadd3.cc33
-rw-r--r--gdb/testsuite/gdb.c++/demangle.exp1579
-rw-r--r--gdb/testsuite/gdb.c++/derivation.cc240
-rw-r--r--gdb/testsuite/gdb.c++/derivation.exp319
-rw-r--r--gdb/testsuite/gdb.c++/hang.H12
-rw-r--r--gdb/testsuite/gdb.c++/hang.exp128
-rw-r--r--gdb/testsuite/gdb.c++/hang1.C3
-rw-r--r--gdb/testsuite/gdb.c++/hang2.C8
-rw-r--r--gdb/testsuite/gdb.c++/hang3.C4
-rw-r--r--gdb/testsuite/gdb.c++/inherit.exp1062
-rw-r--r--gdb/testsuite/gdb.c++/local.cc61
-rw-r--r--gdb/testsuite/gdb.c++/local.exp199
-rw-r--r--gdb/testsuite/gdb.c++/m-data.cc53
-rw-r--r--gdb/testsuite/gdb.c++/m-data.exp112
-rw-r--r--gdb/testsuite/gdb.c++/m-static.cc72
-rw-r--r--gdb/testsuite/gdb.c++/m-static.exp112
-rw-r--r--gdb/testsuite/gdb.c++/member-ptr.cc106
-rw-r--r--gdb/testsuite/gdb.c++/member-ptr.exp549
-rw-r--r--gdb/testsuite/gdb.c++/method.cc80
-rw-r--r--gdb/testsuite/gdb.c++/method.exp194
-rw-r--r--gdb/testsuite/gdb.c++/misc.cc587
-rw-r--r--gdb/testsuite/gdb.c++/misc.exp159
-rw-r--r--gdb/testsuite/gdb.c++/namespace.cc103
-rw-r--r--gdb/testsuite/gdb.c++/namespace.exp188
-rw-r--r--gdb/testsuite/gdb.c++/overload.cc161
-rw-r--r--gdb/testsuite/gdb.c++/overload.exp393
-rw-r--r--gdb/testsuite/gdb.c++/ovldbreak.cc177
-rw-r--r--gdb/testsuite/gdb.c++/ovldbreak.exp349
-rw-r--r--gdb/testsuite/gdb.c++/ref-types.cc79
-rw-r--r--gdb/testsuite/gdb.c++/ref-types.exp663
-rw-r--r--gdb/testsuite/gdb.c++/templates.cc785
-rw-r--r--gdb/testsuite/gdb.c++/templates.exp455
-rw-r--r--gdb/testsuite/gdb.c++/try_catch.cc126
-rw-r--r--gdb/testsuite/gdb.c++/try_catch.exp84
-rw-r--r--gdb/testsuite/gdb.c++/userdef.cc341
-rw-r--r--gdb/testsuite/gdb.c++/userdef.exp131
-rw-r--r--gdb/testsuite/gdb.c++/virtfunc.cc201
-rw-r--r--gdb/testsuite/gdb.c++/virtfunc.exp967
-rw-r--r--gdb/testsuite/gdb.chill/ChangeLog331
-rw-r--r--gdb/testsuite/gdb.chill/Makefile.in26
-rw-r--r--gdb/testsuite/gdb.chill/builtins.ch83
-rw-r--r--gdb/testsuite/gdb.chill/builtins.exp441
-rw-r--r--gdb/testsuite/gdb.chill/callch.ch50
-rw-r--r--gdb/testsuite/gdb.chill/callch.exp69
-rw-r--r--gdb/testsuite/gdb.chill/chexp.exp450
-rw-r--r--gdb/testsuite/gdb.chill/chillvars.ch204
-rw-r--r--gdb/testsuite/gdb.chill/chillvars.exp316
-rwxr-xr-xgdb/testsuite/gdb.chill/configure899
-rw-r--r--gdb/testsuite/gdb.chill/configure.in11
-rw-r--r--gdb/testsuite/gdb.chill/enum.ch9
-rw-r--r--gdb/testsuite/gdb.chill/enum.exp85
-rw-r--r--gdb/testsuite/gdb.chill/func1.ch9
-rw-r--r--gdb/testsuite/gdb.chill/gch1041.ch17
-rw-r--r--gdb/testsuite/gdb.chill/gch1041.exp76
-rw-r--r--gdb/testsuite/gdb.chill/gch1272.ch21
-rw-r--r--gdb/testsuite/gdb.chill/gch1272.exp86
-rw-r--r--gdb/testsuite/gdb.chill/gch1280.ch13
-rw-r--r--gdb/testsuite/gdb.chill/gch1280.exp76
-rw-r--r--gdb/testsuite/gdb.chill/gch922.ch23
-rw-r--r--gdb/testsuite/gdb.chill/gch922.exp183
-rw-r--r--gdb/testsuite/gdb.chill/gch981.ch60
-rw-r--r--gdb/testsuite/gdb.chill/gch981.exp249
-rw-r--r--gdb/testsuite/gdb.chill/misc.ch12
-rw-r--r--gdb/testsuite/gdb.chill/misc.exp100
-rw-r--r--gdb/testsuite/gdb.chill/powerset.ch33
-rw-r--r--gdb/testsuite/gdb.chill/powerset.exp187
-rw-r--r--gdb/testsuite/gdb.chill/pr-4975-grt.ch13
-rw-r--r--gdb/testsuite/gdb.chill/pr-4975.ch43
-rw-r--r--gdb/testsuite/gdb.chill/pr-4975.exp67
-rw-r--r--gdb/testsuite/gdb.chill/pr-5016.ch24
-rw-r--r--gdb/testsuite/gdb.chill/pr-5016.exp62
-rw-r--r--gdb/testsuite/gdb.chill/pr-5020.ch19
-rw-r--r--gdb/testsuite/gdb.chill/pr-5020.exp85
-rw-r--r--gdb/testsuite/gdb.chill/pr-5022.ch12
-rw-r--r--gdb/testsuite/gdb.chill/pr-5022.exp70
-rw-r--r--gdb/testsuite/gdb.chill/pr-5646-grt.ch5
-rw-r--r--gdb/testsuite/gdb.chill/pr-5646.ch15
-rw-r--r--gdb/testsuite/gdb.chill/pr-5646.exp64
-rw-r--r--gdb/testsuite/gdb.chill/pr-5984.ch8
-rw-r--r--gdb/testsuite/gdb.chill/pr-5984.exp57
-rw-r--r--gdb/testsuite/gdb.chill/pr-6292.ch17
-rw-r--r--gdb/testsuite/gdb.chill/pr-6292.exp58
-rw-r--r--gdb/testsuite/gdb.chill/pr-6632-grt.ch34
-rw-r--r--gdb/testsuite/gdb.chill/pr-6632.ch31
-rw-r--r--gdb/testsuite/gdb.chill/pr-6632.exp66
-rw-r--r--gdb/testsuite/gdb.chill/pr-8134.exp65
-rw-r--r--gdb/testsuite/gdb.chill/pr-8136.ch34
-rw-r--r--gdb/testsuite/gdb.chill/pr-8136.exp63
-rw-r--r--gdb/testsuite/gdb.chill/pr-8405.ch19
-rw-r--r--gdb/testsuite/gdb.chill/pr-8405.exp61
-rw-r--r--gdb/testsuite/gdb.chill/pr-8742.ch32
-rw-r--r--gdb/testsuite/gdb.chill/pr-8742.exp64
-rw-r--r--gdb/testsuite/gdb.chill/pr-8894-grt.ch6
-rw-r--r--gdb/testsuite/gdb.chill/pr-8894.ch12
-rw-r--r--gdb/testsuite/gdb.chill/pr-8894.exp61
-rw-r--r--gdb/testsuite/gdb.chill/pr-9095.ch13
-rw-r--r--gdb/testsuite/gdb.chill/pr-9095.exp62
-rw-r--r--gdb/testsuite/gdb.chill/pr-9946.ch10
-rw-r--r--gdb/testsuite/gdb.chill/pr-9946.exp79
-rw-r--r--gdb/testsuite/gdb.chill/result.ch29
-rw-r--r--gdb/testsuite/gdb.chill/result.exp77
-rw-r--r--gdb/testsuite/gdb.chill/string.ch24
-rw-r--r--gdb/testsuite/gdb.chill/string.exp73
-rw-r--r--gdb/testsuite/gdb.chill/tests1.ch240
-rw-r--r--gdb/testsuite/gdb.chill/tests1.exp822
-rw-r--r--gdb/testsuite/gdb.chill/tests2.ch193
-rw-r--r--gdb/testsuite/gdb.chill/tests2.exp271
-rw-r--r--gdb/testsuite/gdb.chill/tuples.ch86
-rw-r--r--gdb/testsuite/gdb.chill/tuples.exp161
-rw-r--r--gdb/testsuite/gdb.chill/xstruct-grt.ch12
-rw-r--r--gdb/testsuite/gdb.chill/xstruct.ch16
-rw-r--r--gdb/testsuite/gdb.chill/xstruct.exp66
-rw-r--r--gdb/testsuite/gdb.disasm/Makefile.in18
-rw-r--r--gdb/testsuite/gdb.disasm/am33.exp838
-rw-r--r--gdb/testsuite/gdb.disasm/am33.s524
-rw-r--r--gdb/testsuite/gdb.disasm/configure899
-rw-r--r--gdb/testsuite/gdb.disasm/configure.in15
-rw-r--r--gdb/testsuite/gdb.disasm/h8300s.exp698
-rw-r--r--gdb/testsuite/gdb.disasm/h8300s.s356
-rw-r--r--gdb/testsuite/gdb.disasm/hppa.exp1404
-rw-r--r--gdb/testsuite/gdb.disasm/hppa.s1738
-rw-r--r--gdb/testsuite/gdb.disasm/mn10200.exp478
-rw-r--r--gdb/testsuite/gdb.disasm/mn10200.s217
-rw-r--r--gdb/testsuite/gdb.disasm/mn10300.exp569
-rw-r--r--gdb/testsuite/gdb.disasm/mn10300.s300
-rw-r--r--gdb/testsuite/gdb.disasm/sh3.exp123
-rw-r--r--gdb/testsuite/gdb.disasm/sh3.s54
-rw-r--r--gdb/testsuite/gdb.fortran/exprs.exp273
-rw-r--r--gdb/testsuite/gdb.fortran/types.exp114
-rw-r--r--gdb/testsuite/gdb.gdb/xfullpath.exp198
-rw-r--r--gdb/testsuite/gdb.hp/Makefile.in44
-rwxr-xr-xgdb/testsuite/gdb.hp/configure1008
-rw-r--r--gdb/testsuite/gdb.hp/configure.in17
-rw-r--r--gdb/testsuite/gdb.hp/gdb.aCC/Makefile.in27
-rwxr-xr-xgdb/testsuite/gdb.hp/gdb.aCC/configure899
-rw-r--r--gdb/testsuite/gdb.hp/gdb.aCC/configure.in15
-rw-r--r--gdb/testsuite/gdb.hp/gdb.aCC/exception.cc48
-rw-r--r--gdb/testsuite/gdb.hp/gdb.aCC/exception.exp439
-rw-r--r--gdb/testsuite/gdb.hp/gdb.aCC/optimize.c76
-rw-r--r--gdb/testsuite/gdb.hp/gdb.aCC/optimize.exp149
-rw-r--r--gdb/testsuite/gdb.hp/gdb.aCC/run.c72
-rw-r--r--gdb/testsuite/gdb.hp/gdb.aCC/watch-cmd.exp157
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/Makefile.in32
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/callfwmall.c362
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/callfwmall.exp346
-rwxr-xr-xgdb/testsuite/gdb.hp/gdb.base-hp/configure899
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/configure.in15
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/dollar.c10
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/dollar.exp155
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/genso-thresh.c229
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/hwwatchbus.c9
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/hwwatchbus.exp83
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/pxdb.c37
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/pxdb.exp128
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/reg-pa64.exp189
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/reg-pa64.s104
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/reg.exp192
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/reg.s96
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/sized-enum.c43
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/sized-enum.exp165
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.exp341
-rw-r--r--gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.mk74
-rwxr-xr-xgdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.sh34
-rw-r--r--gdb/testsuite/gdb.hp/gdb.compat/Makefile.in27
-rw-r--r--gdb/testsuite/gdb.hp/gdb.compat/average.c46
-rwxr-xr-xgdb/testsuite/gdb.hp/gdb.compat/configure899
-rw-r--r--gdb/testsuite/gdb.hp/gdb.compat/configure.in15
-rw-r--r--gdb/testsuite/gdb.hp/gdb.compat/sum.c15
-rw-r--r--gdb/testsuite/gdb.hp/gdb.compat/xdb.c20
-rw-r--r--gdb/testsuite/gdb.hp/gdb.compat/xdb0.c42
-rw-r--r--gdb/testsuite/gdb.hp/gdb.compat/xdb0.h36
-rw-r--r--gdb/testsuite/gdb.hp/gdb.compat/xdb1.c33
-rw-r--r--gdb/testsuite/gdb.hp/gdb.compat/xdb1.exp78
-rw-r--r--gdb/testsuite/gdb.hp/gdb.compat/xdb2.exp105
-rw-r--r--gdb/testsuite/gdb.hp/gdb.compat/xdb3.exp321
-rw-r--r--gdb/testsuite/gdb.hp/gdb.defects/Makefile.in27
-rw-r--r--gdb/testsuite/gdb.hp/gdb.defects/bs14602.c9
-rw-r--r--gdb/testsuite/gdb.hp/gdb.defects/bs14602.exp117
-rw-r--r--gdb/testsuite/gdb.hp/gdb.defects/bs15503.cc52
-rw-r--r--gdb/testsuite/gdb.hp/gdb.defects/bs15503.exp88
-rwxr-xr-xgdb/testsuite/gdb.hp/gdb.defects/configure899
-rw-r--r--gdb/testsuite/gdb.hp/gdb.defects/configure.in15
-rw-r--r--gdb/testsuite/gdb.hp/gdb.defects/solib-d.c6
-rw-r--r--gdb/testsuite/gdb.hp/gdb.defects/solib-d.exp278
-rw-r--r--gdb/testsuite/gdb.hp/gdb.defects/solib-d1.c12
-rw-r--r--gdb/testsuite/gdb.hp/gdb.defects/solib-d2.c11
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/Makefile.in28
-rwxr-xr-xgdb/testsuite/gdb.hp/gdb.objdbg/configure992
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/configure.in16
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01.exp222
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x1.cc25
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x2.cc14
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x3.cc7
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x3.h22
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02.exp85
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x1.cc16
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x2.cc17
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x3.cc6
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03.exp164
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x1.cc15
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x2.cc7
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x3.cc21
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04.exp65
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x.h30
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x1.cc15
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x2.cc3
-rwxr-xr-xgdb/testsuite/gdb.hp/gdb.objdbg/tools/symaddr8
-rwxr-xr-xgdb/testsuite/gdb.hp/gdb.objdbg/tools/symaddr.pa648
-rw-r--r--gdb/testsuite/gdb.hp/gdb.objdbg/tools/test-objdbg.cc4
-rw-r--r--gdb/testsuite/gdb.hp/gdb.threads-hp/Makefile.in27
-rwxr-xr-xgdb/testsuite/gdb.hp/gdb.threads-hp/configure899
-rw-r--r--gdb/testsuite/gdb.hp/gdb.threads-hp/configure.in15
-rwxr-xr-xgdb/testsuite/gdb.hp/tools/odump7
-rw-r--r--gdb/testsuite/gdb.java/Makefile.in26
-rwxr-xr-xgdb/testsuite/gdb.java/configure913
-rw-r--r--gdb/testsuite/gdb.java/configure.in11
-rw-r--r--gdb/testsuite/gdb.java/jmisc.exp91
-rw-r--r--gdb/testsuite/gdb.java/jmisc.java7
-rw-r--r--gdb/testsuite/gdb.java/jmisc1.exp91
-rw-r--r--gdb/testsuite/gdb.java/jmisc2.exp91
-rw-r--r--gdb/testsuite/gdb.java/jv-exp.exp66
-rw-r--r--gdb/testsuite/gdb.java/jv-print.exp141
-rw-r--r--gdb/testsuite/gdb.mi/ChangeLog624
-rw-r--r--gdb/testsuite/gdb.mi/Makefile.in24
-rw-r--r--gdb/testsuite/gdb.mi/basics.c45
-rwxr-xr-xgdb/testsuite/gdb.mi/configure902
-rw-r--r--gdb/testsuite/gdb.mi/configure.in15
-rw-r--r--gdb/testsuite/gdb.mi/mi-basics.exp174
-rw-r--r--gdb/testsuite/gdb.mi/mi-break.exp138
-rw-r--r--gdb/testsuite/gdb.mi/mi-console.c20
-rw-r--r--gdb/testsuite/gdb.mi/mi-console.exp112
-rw-r--r--gdb/testsuite/gdb.mi/mi-disassemble.exp224
-rw-r--r--gdb/testsuite/gdb.mi/mi-eval.exp101
-rw-r--r--gdb/testsuite/gdb.mi/mi-hack-cli.exp40
-rw-r--r--gdb/testsuite/gdb.mi/mi-read-memory.c20
-rw-r--r--gdb/testsuite/gdb.mi/mi-read-memory.exp100
-rw-r--r--gdb/testsuite/gdb.mi/mi-regs.exp175
-rw-r--r--gdb/testsuite/gdb.mi/mi-return.exp94
-rw-r--r--gdb/testsuite/gdb.mi/mi-simplerun.exp199
-rw-r--r--gdb/testsuite/gdb.mi/mi-stack.exp218
-rw-r--r--gdb/testsuite/gdb.mi/mi-stepi.exp109
-rw-r--r--gdb/testsuite/gdb.mi/mi-until.exp127
-rw-r--r--gdb/testsuite/gdb.mi/mi-var-block.exp228
-rw-r--r--gdb/testsuite/gdb.mi/mi-var-child.exp1333
-rw-r--r--gdb/testsuite/gdb.mi/mi-var-cmd.exp523
-rw-r--r--gdb/testsuite/gdb.mi/mi-var-display.exp627
-rw-r--r--gdb/testsuite/gdb.mi/mi-watch.exp191
-rw-r--r--gdb/testsuite/gdb.mi/mi0-basics.exp174
-rw-r--r--gdb/testsuite/gdb.mi/mi0-break.exp138
-rw-r--r--gdb/testsuite/gdb.mi/mi0-console.exp112
-rw-r--r--gdb/testsuite/gdb.mi/mi0-disassemble.exp224
-rw-r--r--gdb/testsuite/gdb.mi/mi0-eval.exp101
-rw-r--r--gdb/testsuite/gdb.mi/mi0-hack-cli.exp40
-rw-r--r--gdb/testsuite/gdb.mi/mi0-read-memory.exp100
-rw-r--r--gdb/testsuite/gdb.mi/mi0-regs.exp177
-rw-r--r--gdb/testsuite/gdb.mi/mi0-return.exp94
-rw-r--r--gdb/testsuite/gdb.mi/mi0-simplerun.exp201
-rw-r--r--gdb/testsuite/gdb.mi/mi0-stack.exp218
-rw-r--r--gdb/testsuite/gdb.mi/mi0-stepi.exp109
-rw-r--r--gdb/testsuite/gdb.mi/mi0-until.exp127
-rw-r--r--gdb/testsuite/gdb.mi/mi0-var-block.exp228
-rw-r--r--gdb/testsuite/gdb.mi/mi0-var-child.exp1333
-rw-r--r--gdb/testsuite/gdb.mi/mi0-var-cmd.exp523
-rw-r--r--gdb/testsuite/gdb.mi/mi0-var-display.exp627
-rw-r--r--gdb/testsuite/gdb.mi/mi0-watch.exp191
-rw-r--r--gdb/testsuite/gdb.mi/testcmds25
-rw-r--r--gdb/testsuite/gdb.mi/until.c26
-rw-r--r--gdb/testsuite/gdb.mi/var-cmd.c296
-rw-r--r--gdb/testsuite/gdb.stabs/Makefile.in16
-rw-r--r--gdb/testsuite/gdb.stabs/aout.sed16
-rwxr-xr-xgdb/testsuite/gdb.stabs/configure899
-rw-r--r--gdb/testsuite/gdb.stabs/configure.in15
-rw-r--r--gdb/testsuite/gdb.stabs/ecoff.sed17
-rw-r--r--gdb/testsuite/gdb.stabs/hppa.sed20
-rw-r--r--gdb/testsuite/gdb.stabs/weird.def882
-rw-r--r--gdb/testsuite/gdb.stabs/weird.exp328
-rw-r--r--gdb/testsuite/gdb.stabs/xcoff.sed17
-rw-r--r--gdb/testsuite/gdb.threads/Makefile.in31
-rw-r--r--gdb/testsuite/gdb.threads/config.in4
-rwxr-xr-xgdb/testsuite/gdb.threads/configure1098
-rw-r--r--gdb/testsuite/gdb.threads/configure.in18
-rw-r--r--gdb/testsuite/gdb.threads/gcore-thread.exp186
-rw-r--r--gdb/testsuite/gdb.threads/linux-dp.c207
-rw-r--r--gdb/testsuite/gdb.threads/linux-dp.exp229
-rw-r--r--gdb/testsuite/gdb.threads/pthreads.c171
-rw-r--r--gdb/testsuite/gdb.threads/pthreads.exp358
-rw-r--r--gdb/testsuite/gdb.threads/step.c221
-rw-r--r--gdb/testsuite/gdb.threads/step.exp200
-rw-r--r--gdb/testsuite/gdb.threads/step2.exp150
-rw-r--r--gdb/testsuite/gdb.trace/Makefile.in21
-rw-r--r--gdb/testsuite/gdb.trace/actions.c134
-rw-r--r--gdb/testsuite/gdb.trace/actions.exp207
-rw-r--r--gdb/testsuite/gdb.trace/backtrace.exp376
-rw-r--r--gdb/testsuite/gdb.trace/circ.c90
-rw-r--r--gdb/testsuite/gdb.trace/circ.exp215
-rw-r--r--gdb/testsuite/gdb.trace/collection.c280
-rw-r--r--gdb/testsuite/gdb.trace/collection.exp623
-rwxr-xr-xgdb/testsuite/gdb.trace/configure899
-rw-r--r--gdb/testsuite/gdb.trace/configure.in15
-rw-r--r--gdb/testsuite/gdb.trace/deltrace.exp269
-rw-r--r--gdb/testsuite/gdb.trace/gdb_c_test.c3792
-rw-r--r--gdb/testsuite/gdb.trace/infotrace.exp99
-rw-r--r--gdb/testsuite/gdb.trace/limits.c51
-rw-r--r--gdb/testsuite/gdb.trace/limits.exp316
-rw-r--r--gdb/testsuite/gdb.trace/packetlen.exp100
-rw-r--r--gdb/testsuite/gdb.trace/passc-dyn.exp181
-rw-r--r--gdb/testsuite/gdb.trace/passcount.exp178
-rw-r--r--gdb/testsuite/gdb.trace/report.exp421
-rw-r--r--gdb/testsuite/gdb.trace/save-trace.exp171
-rw-r--r--gdb/testsuite/gdb.trace/tfind.exp405
-rw-r--r--gdb/testsuite/gdb.trace/tracecmd.exp269
-rw-r--r--gdb/testsuite/gdb.trace/while-dyn.exp124
-rw-r--r--gdb/testsuite/gdb.trace/while-stepping.exp116
-rw-r--r--gdb/testsuite/lib/compiler.c31
-rw-r--r--gdb/testsuite/lib/compiler.cc34
-rw-r--r--gdb/testsuite/lib/emc-support.exp223
-rw-r--r--gdb/testsuite/lib/gdb.exp1684
-rw-r--r--gdb/testsuite/lib/insight-support.exp310
-rw-r--r--gdb/testsuite/lib/java.exp105
-rw-r--r--gdb/testsuite/lib/mi-support.exp788
-rw-r--r--gdb/testsuite/lib/trace-support.exp307
-rw-r--r--gdb/thread-db.c1044
-rw-r--r--gdb/thread.c754
-rw-r--r--gdb/top.h74
-rw-r--r--gdb/tracepoint.c2810
-rw-r--r--gdb/tracepoint.h134
-rw-r--r--gdb/tui/ChangeLog626
-rw-r--r--gdb/tui/tui-file.c238
-rw-r--r--gdb/tui/tui-file.h29
-rw-r--r--gdb/tui/tui-hooks.c408
-rw-r--r--gdb/tui/tui-out.c410
-rw-r--r--gdb/tui/tui.c456
-rw-r--r--gdb/tui/tui.h141
-rw-r--r--gdb/tui/tuiCommand.c147
-rw-r--r--gdb/tui/tuiCommand.h42
-rw-r--r--gdb/tui/tuiData.c1357
-rw-r--r--gdb/tui/tuiData.h373
-rw-r--r--gdb/tui/tuiDataWin.c358
-rw-r--r--gdb/tui/tuiDataWin.h47
-rw-r--r--gdb/tui/tuiDisassem.c325
-rw-r--r--gdb/tui/tuiDisassem.h41
-rw-r--r--gdb/tui/tuiGeneralWin.c419
-rw-r--r--gdb/tui/tuiGeneralWin.h52
-rw-r--r--gdb/tui/tuiIO.c463
-rw-r--r--gdb/tui/tuiIO.h62
-rw-r--r--gdb/tui/tuiLayout.c1179
-rw-r--r--gdb/tui/tuiLayout.h31
-rw-r--r--gdb/tui/tuiRegs.c1074
-rw-r--r--gdb/tui/tuiRegs.h47
-rw-r--r--gdb/tui/tuiSource.c448
-rw-r--r--gdb/tui/tuiSource.h41
-rw-r--r--gdb/tui/tuiSourceWin.c915
-rw-r--r--gdb/tui/tuiSourceWin.h68
-rw-r--r--gdb/tui/tuiStack.c451
-rw-r--r--gdb/tui/tuiStack.h44
-rw-r--r--gdb/tui/tuiWin.c1627
-rw-r--r--gdb/tui/tuiWin.h58
-rw-r--r--gdb/typeprint.c379
-rw-r--r--gdb/typeprint.h29
-rw-r--r--gdb/ui-file.c485
-rw-r--r--gdb/ui-file.h93
-rw-r--r--gdb/ui-out.c1149
-rw-r--r--gdb/ui-out.h275
-rw-r--r--gdb/utils.c2610
-rw-r--r--gdb/uw-thread.c1059
-rw-r--r--gdb/v850-tdep.c1198
-rw-r--r--gdb/v850ice.c956
-rw-r--r--gdb/valarith.c1428
-rw-r--r--gdb/valops.c3455
-rw-r--r--gdb/valprint.c1425
-rw-r--r--gdb/valprint.h60
-rw-r--r--gdb/value.h566
-rw-r--r--gdb/values.c1335
-rw-r--r--gdb/varobj.c2492
-rw-r--r--gdb/varobj.h100
-rw-r--r--gdb/vax-tdep.c709
-rw-r--r--gdb/vax-tdep.h55
-rw-r--r--gdb/version.h33
-rw-r--r--gdb/version.in1
-rw-r--r--gdb/vx-share/README7
-rw-r--r--gdb/vx-share/dbgRpcLib.h32
-rw-r--r--gdb/vx-share/ptrace.h44
-rw-r--r--gdb/vx-share/regPacket.h160
-rw-r--r--gdb/vx-share/vxTypes.h72
-rw-r--r--gdb/vx-share/vxWorks.h172
-rw-r--r--gdb/vx-share/wait.h46
-rw-r--r--gdb/vx-share/xdr_ld.c85
-rw-r--r--gdb/vx-share/xdr_ld.h45
-rw-r--r--gdb/vx-share/xdr_ptrace.c119
-rw-r--r--gdb/vx-share/xdr_ptrace.h72
-rw-r--r--gdb/vx-share/xdr_rdb.c212
-rw-r--r--gdb/vx-share/xdr_rdb.h137
-rw-r--r--gdb/w89k-rom.c311
-rw-r--r--gdb/win32-nat.c2194
-rw-r--r--gdb/wince-stub.c592
-rw-r--r--gdb/wince-stub.h48
-rw-r--r--gdb/wince.c2047
-rw-r--r--gdb/x86-64-linux-nat.c442
-rw-r--r--gdb/x86-64-linux-tdep.c136
-rw-r--r--gdb/x86-64-tdep.c1150
-rw-r--r--gdb/x86-64-tdep.h34
-rw-r--r--gdb/xcoffread.c3048
-rw-r--r--gdb/xcoffsolib.c196
-rw-r--r--gdb/xcoffsolib.h66
-rw-r--r--gdb/xmodem.c275
-rw-r--r--gdb/xmodem.h30
-rw-r--r--gdb/xstormy16-tdep.c1145
-rw-r--r--gdb/z8k-tdep.c430
1896 files changed, 741009 insertions, 0 deletions
diff --git a/gdb/29k-share/README b/gdb/29k-share/README
new file mode 100644
index 00000000000..5e19715ffad
--- /dev/null
+++ b/gdb/29k-share/README
@@ -0,0 +1,9 @@
+The files in this directory are shared with other debuggers and
+debug interfaces that use Advanced Micro Devices' UDI (universal debug
+interface) protocol. The protocol provides a common interface among
+debuggers, logic analyzers, emulators, and embedded systems that use
+AMD 29000 family processors.
+
+Do not change these files without coordinating with Advanced Micro
+Devices, Embedded Processor Division, 5204 E. Ben White Blvd, Austin, TX 78741.
+Maybe postmaster@cayman.amd.com can direct you to the current maintainers.
diff --git a/gdb/29k-share/udi/udi2go32.c b/gdb/29k-share/udi/udi2go32.c
new file mode 100644
index 00000000000..63d98ae4017
--- /dev/null
+++ b/gdb/29k-share/udi/udi2go32.c
@@ -0,0 +1,607 @@
+/*
+
+Interface from UDI calls in 32-bit mode to go32 in 16-bit mode.
+Communication is done through a single interrupt vector, which passes
+data through two linear buffers.
+
+Call:
+ AH = 0xfe
+ AL = UDI function number
+ ECX = IN length
+ ESI = pointer to IN buffer
+ EDI = pointer to OUT buffer
+
+Return:
+ EAX = return value of UDI function
+
+Vector:
+ 0x21
+
+*/
+#ifdef __GO32__
+
+#include <stdlib.h>
+#include "udiproc.h"
+#include "udisoc.h"
+
+char dfe_errmsg[500];
+
+static char in_buffer[4096];
+static char out_buffer[4096];
+static char *in_ptr;
+static char *out_ptr;
+
+#define IN_INIT() in_ptr = in_buffer
+#define IN_VAL(t,v) *((t *)in_ptr)++ = v
+#define IN_DATA(ptr, cnt) memcpy(in_ptr, ptr, cnt), in_ptr += cnt
+
+#define OUT_INIT() out_ptr = out_buffer
+#define OUT_VAL(t) (*((t *)out_ptr)++)
+#define OUT_DATA(ptr, cnt) memcpy(ptr, out_ptr, cnt), out_ptr += cnt
+
+static int DO_CALL(int function)
+{
+ asm("pushl %esi");
+ asm("pushl %edi");
+ asm("movb %0, %%al" : : "g" (function));
+ asm("movl _in_ptr, %ecx");
+ asm("movl $_in_buffer, %esi");
+ asm("subl %esi, %ecx");
+ asm("movl $_out_buffer, %edi");
+ asm("movb $0xfe, %ah");
+ asm("int $0x21");
+ asm("popl %edi");
+ asm("popl %esi");
+}
+
+/*----------------------------------------------------------------------*/
+
+#ifdef TEST_UDI
+int main()
+{
+ int r;
+ long p2;
+ short p1;
+ IN_INIT();
+ IN_VAL(long, 11111111);
+ IN_VAL(short, 2222);
+ IN_DATA("Hello, world\n", 17);
+
+ r = DO_CALL(42);
+
+ OUT_INIT();
+ p1 = OUT_VAL(short);
+ p2 = OUT_VAL(long);
+ printf("main: p1=%d p2=%d rv=%d\n", p1, p2, r);
+ return r;
+}
+#endif
+
+/*----------------------------------------------------------------------*/
+
+unsupported(char *s)
+{
+ printf("unsupported UDI host call %s\n", s);
+ abort();
+}
+
+UDIError UDIConnect (
+ char *Configuration, /* In */
+ UDISessionId *Session /* Out */
+ )
+{
+ int r;
+ out_buffer[0] = 0; /* DJ - test */
+ IN_INIT();
+ IN_DATA(Configuration, strlen(Configuration)+1);
+
+ r = DO_CALL(UDIConnect_c);
+
+ OUT_INIT();
+ *Session = OUT_VAL(UDISessionId);
+ return r;
+}
+
+UDIError UDIDisconnect (
+ UDISessionId Session, /* In */
+ UDIBool Terminate /* In */
+ )
+{
+ int r;
+ IN_INIT();
+ IN_VAL(UDISessionId, Session);
+ IN_VAL(UDIBool, Terminate);
+
+ return DO_CALL(UDIDisconnect_c);
+}
+
+UDIError UDISetCurrentConnection (
+ UDISessionId Session /* In */
+ )
+{
+ IN_INIT();
+ IN_VAL(UDISessionId, Session);
+
+ return DO_CALL(UDISetCurrentConnection_c);
+}
+
+UDIError UDICapabilities (
+ UDIUInt32 *TIPId, /* Out */
+ UDIUInt32 *TargetId, /* Out */
+ UDIUInt32 DFEId, /* In */
+ UDIUInt32 DFE, /* In */
+ UDIUInt32 *TIP, /* Out */
+ UDIUInt32 *DFEIPCId, /* Out */
+ UDIUInt32 *TIPIPCId, /* Out */
+ char *TIPString /* Out */
+ )
+{
+ int r;
+ IN_INIT();
+ IN_VAL(UDIUInt32, DFEId);
+ IN_VAL(UDIUInt32, DFE);
+ r = DO_CALL(UDICapabilities_c);
+ OUT_INIT();
+ *TIPId = OUT_VAL(UDIUInt32);
+ *TargetId = OUT_VAL(UDIUInt32);
+ *TIP = OUT_VAL(UDIUInt32);
+ *DFEIPCId = OUT_VAL(UDIUInt32);
+ *TIPIPCId = OUT_VAL(UDIUInt32);
+ strcpy(TIPString, out_ptr);
+ return r;
+}
+
+UDIError UDIEnumerateTIPs (
+ UDIInt (*UDIETCallback) /* In */
+ ( char *Configuration ) /* In to callback() */
+ )
+{
+ UDIETCallback("montip.exe");
+}
+
+UDIError UDIGetErrorMsg (
+ UDIError ErrorCode, /* In */
+ UDISizeT MsgSize, /* In */
+ char *Msg, /* Out */
+ UDISizeT *CountDone /* Out */
+ )
+{
+ int r;
+ if (MsgSize > 4000)
+ MsgSize = 4000;
+ IN_INIT();
+ IN_VAL(UDIError, ErrorCode);
+ IN_VAL(UDISizeT, MsgSize);
+
+ r = DO_CALL(UDIGetErrorMsg_c);
+
+ OUT_INIT();
+ *CountDone = OUT_VAL(UDISizeT);
+ OUT_DATA(Msg, *CountDone);
+ return r;
+}
+
+UDIError UDIGetTargetConfig (
+ UDIMemoryRange KnownMemory[], /* Out */
+ UDIInt *NumberOfRanges, /* In/Out */
+ UDIUInt32 ChipVersions[], /* Out */
+ UDIInt *NumberOfChips /* In/Out */
+ )
+{
+ int r, i;
+ int nr = *NumberOfRanges;
+ int nc = *NumberOfChips;
+ IN_INIT();
+ IN_VAL(UDIInt, *NumberOfRanges);
+ IN_VAL(UDIInt, *NumberOfChips);
+ r = DO_CALL(UDIGetTargetConfig_c);
+ if (r == UDIErrorIncomplete)
+ return r;
+ OUT_INIT();
+ *NumberOfRanges = OUT_VAL(UDIInt);
+ *NumberOfChips = OUT_VAL(UDIInt);
+ for (i=0; i<nr; i++)
+ {
+ KnownMemory[i].Space = OUT_VAL(short);
+ KnownMemory[i].Offset = OUT_VAL(CPUOffset);
+ KnownMemory[i].Size = OUT_VAL(CPUSizeT);
+ }
+ for (i=0; i<nc; i++)
+ {
+ ChipVersions[i] = OUT_VAL(UDIUInt32);
+ }
+ return r;
+}
+
+UDIError UDICreateProcess (
+ UDIPId *PId /* Out */
+ )
+{
+ int r = DO_CALL(UDICreateProcess_c);
+
+ OUT_INIT();
+ *PId = OUT_VAL(UDIPId);
+
+ return r;
+}
+
+UDIError UDISetCurrentProcess (
+ UDIPId PId /* In */
+ )
+{
+ IN_INIT();
+ IN_VAL(UDIPId, PId);
+
+ return DO_CALL(UDISetCurrentProcess_c);
+}
+
+UDIError UDIDestroyProcess (
+ UDIPId PId /* In */
+ )
+{
+ IN_INIT();
+ IN_VAL(UDIPId, PId);
+
+ return DO_CALL(UDIDestroyProcess_c);
+}
+
+UDIError UDIInitializeProcess (
+ UDIMemoryRange ProcessMemory[], /* In */
+ UDIInt NumberOfRanges, /* In */
+ UDIResource EntryPoint, /* In */
+ CPUSizeT StackSizes[], /* In */
+ UDIInt NumberOfStacks, /* In */
+ char *ArgString /* In */
+ )
+{
+ int i, r;
+ IN_INIT();
+ IN_VAL(UDIInt, NumberOfRanges);
+ for (i=0; i<NumberOfRanges; i++)
+ {
+ IN_VAL(short, ProcessMemory[i].Space);
+ IN_VAL(CPUOffset, ProcessMemory[i].Offset);
+ IN_VAL(CPUSizeT, ProcessMemory[i].Size);
+ }
+ IN_VAL(short, EntryPoint.Space);
+ IN_VAL(CPUOffset, EntryPoint.Offset);
+ IN_VAL(UDIInt, NumberOfStacks);
+ for (i=0; i<NumberOfStacks; i++)
+ IN_VAL(CPUSizeT, StackSizes[i]);
+ IN_DATA(ArgString, strlen(ArgString)+1);
+
+ return DO_CALL(UDIInitializeProcess_c);
+}
+
+UDIError UDIRead (
+ UDIResource From, /* In */
+ UDIHostMemPtr To, /* Out */
+ UDICount Count, /* In */
+ UDISizeT Size, /* In */
+ UDICount *CountDone, /* Out */
+ UDIBool HostEndian /* In */
+ )
+{
+ int cleft = Count, cthis, dthis;
+ int cdone = 0, r, bsize=2048/Size;
+
+ while (cleft)
+ {
+ cthis = (cleft<bsize) ? cleft : bsize;
+ IN_INIT();
+ IN_VAL(short, From.Space);
+ IN_VAL(CPUOffset, From.Offset);
+ IN_VAL(UDICount, cthis);
+ IN_VAL(UDISizeT, Size);
+ IN_VAL(UDIBool, HostEndian);
+
+ r = DO_CALL(UDIRead_c);
+
+ OUT_INIT();
+ dthis = OUT_VAL(UDICount);
+ OUT_DATA(To, dthis*Size);
+ cdone += dthis;
+ To += dthis*Size;
+
+ if (r != UDINoError)
+ {
+ *CountDone = cdone;
+ return r;
+ }
+ cleft -= cthis;
+ }
+ *CountDone = cdone;
+ return UDINoError;
+}
+
+UDIError UDIWrite (
+ UDIHostMemPtr From, /* In */
+ UDIResource To, /* In */
+ UDICount Count, /* In */
+ UDISizeT Size, /* In */
+ UDICount *CountDone, /* Out */
+ UDIBool HostEndian /* In */
+ )
+{
+ int cleft = Count, cthis, dthis;
+ int cdone = 0, r, bsize=2048/Size;
+
+ while (cleft)
+ {
+ cthis = (cleft<bsize) ? cleft : bsize;
+ IN_INIT();
+ IN_VAL(short, To.Space);
+ IN_VAL(CPUOffset, To.Offset);
+ IN_VAL(UDICount, cthis);
+ IN_VAL(UDISizeT, Size);
+ IN_VAL(UDIBool, HostEndian);
+ IN_DATA(From, cthis*Size);
+ From += cthis*Size;
+
+ r = DO_CALL(UDIWrite_c);
+
+ OUT_INIT();
+ cdone += OUT_VAL(UDICount);
+
+ if (r != UDINoError)
+ {
+ *CountDone = cdone;
+ return r;
+ }
+ cleft -= cthis;
+ }
+ *CountDone = cdone;
+ return UDINoError;
+}
+
+UDIError UDICopy (
+ UDIResource From, /* In */
+ UDIResource To, /* In */
+ UDICount Count, /* In */
+ UDISizeT Size, /* In */
+ UDICount *CountDone, /* Out */
+ UDIBool Direction /* In */
+ )
+{
+ int r;
+ IN_INIT();
+ IN_VAL(short, From.Space);
+ IN_VAL(CPUOffset, From.Offset);
+ IN_VAL(short, To.Space);
+ IN_VAL(CPUOffset, To.Offset);
+ IN_VAL(UDICount, Count);
+ IN_VAL(UDISizeT, Size);
+ IN_VAL(UDIBool, Direction);
+
+ r = DO_CALL(UDICopy_c);
+
+ OUT_INIT();
+ *CountDone = OUT_VAL(UDICount);
+
+ return r;
+}
+
+UDIError UDIExecute (
+ void
+ )
+{
+ return DO_CALL(UDIExecute_c);
+}
+
+UDIError UDIStep (
+ UDIUInt32 Steps, /* In */
+ UDIStepType StepType, /* In */
+ UDIRange Range /* In */
+ )
+{
+ IN_INIT();
+ IN_VAL(UDIUInt32, Steps);
+ IN_VAL(UDIStepType, StepType);
+ IN_VAL(UDIRange, Range);
+
+ return DO_CALL(UDIStep_c);
+}
+
+UDIVoid UDIStop (
+ void
+ )
+{
+ DO_CALL(UDIStop_c);
+}
+
+UDIError UDIWait (
+ UDIInt32 MaxTime, /* In */
+ UDIPId *PId, /* Out */
+ UDIUInt32 *StopReason /* Out */
+ )
+{
+ int r;
+ IN_INIT();
+ IN_VAL(UDIInt32, MaxTime);
+ r = DO_CALL(UDIWait_c);
+ OUT_INIT();
+ *PId = OUT_VAL(UDIPId);
+ *StopReason = OUT_VAL(UDIUInt32);
+ return r;
+}
+
+UDIError UDISetBreakpoint (
+ UDIResource Addr, /* In */
+ UDIInt32 PassCount, /* In */
+ UDIBreakType Type, /* In */
+ UDIBreakId *BreakId /* Out */
+ )
+{
+ int r;
+ IN_INIT();
+ IN_VAL(short, Addr.Space);
+ IN_VAL(CPUOffset, Addr.Offset);
+ IN_VAL(UDIInt32, PassCount);
+ IN_VAL(UDIBreakType, Type);
+
+ r = DO_CALL(UDISetBreakpoint_c);
+
+ OUT_INIT();
+ *BreakId = OUT_VAL(UDIBreakId);
+ return r;
+}
+
+UDIError UDIQueryBreakpoint (
+ UDIBreakId BreakId, /* In */
+ UDIResource *Addr, /* Out */
+ UDIInt32 *PassCount, /* Out */
+ UDIBreakType *Type, /* Out */
+ UDIInt32 *CurrentCount /* Out */
+ )
+{
+ int r;
+ IN_INIT();
+ IN_VAL(UDIBreakId, BreakId);
+
+ r = DO_CALL(UDIQueryBreakpoint_c);
+
+ OUT_INIT();
+ Addr->Space = OUT_VAL(short);
+ Addr->Offset = OUT_VAL(CPUOffset);
+ *PassCount = OUT_VAL(UDIInt32);
+ *Type = OUT_VAL(UDIBreakType);
+ *CurrentCount = OUT_VAL(UDIInt32);
+
+ return r;
+}
+
+UDIError UDIClearBreakpoint (
+ UDIBreakId BreakId /* In */
+ )
+{
+ IN_INIT();
+ IN_VAL(UDIBreakId, BreakId);
+
+ return DO_CALL(UDIClearBreakpoint_c);
+}
+
+UDIError UDIGetStdout (
+ UDIHostMemPtr Buf, /* Out */
+ UDISizeT BufSize, /* In */
+ UDISizeT *CountDone /* Out */
+ )
+{
+ int r;
+ IN_INIT();
+ if (BufSize > 4000)
+ BufSize = 4000;
+ IN_VAL(UDISizeT,BufSize);
+ r = DO_CALL(UDIGetStdout_c);
+ OUT_INIT();
+ *CountDone = OUT_VAL(UDISizeT);
+ if (*CountDone <= BufSize)
+ OUT_DATA(Buf, *CountDone);
+ return r;
+}
+
+UDIError UDIGetStderr (
+ UDIHostMemPtr Buf, /* Out */
+ UDISizeT BufSize, /* In */
+ UDISizeT *CountDone /* Out */
+ )
+{
+ int r;
+ IN_INIT();
+ if (BufSize > 4000)
+ BufSize = 4000;
+ IN_VAL(UDISizeT,BufSize);
+ r = DO_CALL(UDIGetStderr_c);
+ OUT_INIT();
+ *CountDone = OUT_VAL(UDISizeT);
+ OUT_DATA(Buf, *CountDone);
+ return r;
+}
+
+UDIError UDIPutStdin (
+ UDIHostMemPtr Buf, /* In */
+ UDISizeT Count, /* In */
+ UDISizeT *CountDone /* Out */
+ )
+{
+ int r;
+ IN_INIT();
+ if (Count > 4000)
+ Count = 4000;
+ IN_VAL(UDISizeT,Count);
+ IN_DATA(Buf, Count);
+ r = DO_CALL(UDIPutStdin_c);
+ OUT_INIT();
+ *CountDone = OUT_VAL(UDISizeT);
+ return r;
+}
+
+UDIError UDIStdinMode (
+ UDIMode *Mode /* Out */
+ )
+{
+ int r;
+ IN_INIT();
+ r = DO_CALL(UDIStdinMode_c);
+ OUT_INIT();
+ *Mode = OUT_VAL(UDIMode);
+ return r;
+}
+
+UDIError UDIPutTrans (
+ UDIHostMemPtr Buf, /* In */
+ UDISizeT Count, /* In */
+ UDISizeT *CountDone /* Out */
+ )
+{
+ int r;
+ IN_INIT();
+ if (Count > 4000)
+ Count = 4000;
+ IN_VAL(UDISizeT,Count);
+ IN_DATA(Buf, Count);
+ r = DO_CALL(UDIPutTrans_c);
+ OUT_INIT();
+ *CountDone = OUT_VAL(UDISizeT);
+ return r;
+}
+
+UDIError UDIGetTrans (
+ UDIHostMemPtr Buf, /* Out */
+ UDISizeT BufSize, /* In */
+ UDISizeT *CountDone /* Out */
+ )
+{
+ int r;
+ IN_INIT();
+ if (BufSize > 4000)
+ BufSize = 4000;
+ IN_VAL(UDISizeT,BufSize);
+ r = DO_CALL(UDIGetTrans_c);
+ OUT_INIT();
+ *CountDone = OUT_VAL(UDISizeT);
+ OUT_DATA(Buf, *CountDone);
+ return r;
+}
+
+UDIError UDITransMode (
+ UDIMode *Mode /* Out */
+ )
+{
+ int r;
+ IN_INIT();
+ r = DO_CALL(UDITransMode_c);
+ OUT_INIT();
+ *Mode = OUT_VAL(UDIMode);
+ return r;
+}
+
+#define DFEIPCIdCompany 0x0001 /* Company ID AMD */
+#define DFEIPCIdProduct 0x1 /* Product ID 0 */
+#define DFEIPCIdVersion 0x125 /* 1.2.5 */
+
+unsigned UDIGetDFEIPCId ()
+{
+ return((((UDIUInt32)DFEIPCIdCompany) << 16) |(DFEIPCIdProduct << 12) | DFEIPCIdVersion);
+}
+
+#endif /* __GO32__ */
diff --git a/gdb/29k-share/udi/udiids.h b/gdb/29k-share/udi/udiids.h
new file mode 100644
index 00000000000..5f805e46905
--- /dev/null
+++ b/gdb/29k-share/udi/udiids.h
@@ -0,0 +1,48 @@
+/* This file contains the DFE and TIP IDs to be used by AMD products for
+ the UDICapabilities call.
+
+ Copyright 1993 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. */
+
+ /* Company Codes -- AMD assigns these */
+#define UDICompanyCode_AMD 1
+
+ /* Build a UDIID given a CompanyProdCode and 3 version pieces */
+#define UDIID(CompanyProdCode, v1,v2,v3) ((((CompanyProdCode) & 0xfffff)<<12)+\
+ (((v1)&0xf)<<8) + (((v2)&0xf)<<4) + ((v3)&0xf))
+
+
+ /* Extract a CompanyProdCode or a Version from a UDIID */
+#define UDIID_CompanyProdCode(id) (((id)>>12) & 0xfffff)
+#define UDIID_Version(id) ((id)&0xfff)
+
+
+#define UDIAMDProduct(ProdCode) ((UDICompanyCode_AMD<<4) + (ProdCode&0xf))
+
+ /* AMD DFE Product Codes */
+#define UDIProductCode_Mondfe UDIAMDProduct(0)
+#define UDIProductCode_XRAY UDIAMDProduct(1)
+#define UDIProductCode_TIPTester UDIAMDProduct(2)
+
+ /* AMD TIP Product Codes (need not be distinct from DFE Product Codes) */
+#define UDIProductCode_Montip UDIAMDProduct(0)
+#define UDIProductCode_Isstip UDIAMDProduct(1)
+
+
+#define UDILatestVersion 0x120 /* UDI 1.2.0, can be used in DFE and TIP desired UDI params */
+
diff --git a/gdb/29k-share/udi/udip2soc.c b/gdb/29k-share/udi/udip2soc.c
new file mode 100644
index 00000000000..c8af3fee285
--- /dev/null
+++ b/gdb/29k-share/udi/udip2soc.c
@@ -0,0 +1,1250 @@
+/* Copyright 1993, 1998 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. */
+
+static char udip2soc_c[]="@(#)udip2soc.c 2.11 Daniel Mann";
+static char udip2soc_c_AMD[]="@(#)udip2soc.c 2.8, AMD";
+/*
+* This module converts UDI Procedural calls into
+* UDI socket messages for UNIX.
+* It is used by DFE client processes
+********************************************************************** HISTORY
+*/
+/* This is all unneeded on DOS machines. */
+#ifndef __GO32__
+
+#include <stdio.h>
+#include <string.h>
+
+/* Before sys/file.h for Unixware. */
+#include <sys/types.h>
+
+#include <sys/file.h>
+
+/* This used to say sys/fcntl.h, but the only systems I know of that
+ require that are old (pre-4.3, at least) BSD systems, which we
+ probably don't need to worry about. */
+#include <fcntl.h>
+
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sys/errno.h>
+#include "udiproc.h"
+#include "udisoc.h"
+
+extern int errno;
+extern int sys_nerr;
+extern int udr_errno;
+extern char* getenv();
+
+/* local type decs. and macro defs. not in a .h file ************* MACRO/TYPE
+*/
+#define version_c 0x121 /* DFE-IPC version id */
+#define TRUE -1
+#define FALSE 0
+#define PORT_NUM 7000
+#define MAX_SESSIONS 5 /* maximum DFE-TIP connections */
+#define SOC_BUF_SIZE 4* 1024 /* size of socket comms buffer */
+#define SBUF_SIZE 500 /* size of string buffer */
+#define ERRMSG_SIZE 500 /* size of error message buffer */
+
+typedef struct connection_str /* record of connect session */
+{
+ int in_use;
+ char connect_id[20]; /* connection identifier */
+ char domain_string[20]; /* dommaing for conection */
+ char tip_string[30]; /* TIP host name for AF_INET */
+ char tip_exe[80]; /* TIP exe name */
+ int dfe_sd; /* associated DFE socket */
+ int tip_pid; /* pid of TIP process */
+ struct sockaddr_in dfe_sockaddr;
+ struct sockaddr_in tip_sockaddr_in;
+ struct sockaddr tip_sockaddr;
+} connection_t;
+
+typedef struct session_str
+{
+ int in_use;
+ connection_t* soc_con_p; /* associated connection */
+ UDISessionId tip_id; /* associated TIP session ID */
+} session_t;
+
+/* global dec/defs. which are not in a .h file ************* EXPORT DEC/DEFS
+*/
+UDIError dfe_errno;
+char dfe_errmsg[ERRMSG_SIZE];/* error string */
+
+/* local dec/defs. which are not in a .h file *************** LOCAL DEC/DEFS
+*/
+LOCAL connection_t soc_con[MAX_SESSIONS];
+LOCAL session_t session[MAX_SESSIONS];
+LOCAL UDR udr;
+LOCAL UDR* udrs = &udr; /* UDR for current session */
+LOCAL int current; /* int-id for current session */
+LOCAL char sbuf[SBUF_SIZE]; /* String handler buffer */
+LOCAL char config_file[80]; /* path/name for config file */
+
+/***************************************************************** UDI_CONNECT
+* Establish a new FDE to TIP conection. The file "./udi_soc" or
+* "/etc/udi_soc" may be examined to obtain the conection information
+* if the "Config" parameter is not a completd "line entry".
+*
+* NOTE: the Session string must not start whith white-space characters.
+* Format of string is:
+* <session> <domain> <soc_name|host_name> <tip_exe|port> <pass to UDIconnect>
+* soc2cayman AF_INET cayman 7000 <not supported>
+* soc2tip AF_UNIX astring tip.exe ...
+*/
+UDIError
+UDIConnect(Config, Session)
+ char *Config; /* in -- identification string */
+ UDISessionId *Session; /* out -- session ID */
+{
+ UDIInt32 service_id = UDIConnect_c;
+ int domain;
+ int cnt=0;
+ int rcnt, pos, params_pos=0;
+ char *tip_main_string;
+ char *env_p;
+ struct hostent *tip_info_p;
+ FILE *fd;
+#if 0
+ FILE *f_p;
+#endif
+ UDIUInt32 TIPIPCId;
+ UDIUInt32 DFEIPCId;
+
+#if 0 /* This is crap. It assumes that udi_soc is executable! */
+ sprintf(sbuf, "which udi_soc");
+ f_p = popen(sbuf, "r");
+ if(f_p)
+ { while( (sbuf[cnt++]=getc(f_p)) != EOF);
+ sbuf[cnt-2]=0;
+ }
+ pclose(f_p);
+#endif
+
+ for (rcnt=0;
+ rcnt < MAX_SESSIONS && session[rcnt].in_use;
+ rcnt++);
+
+ if (rcnt >= MAX_SESSIONS)
+ {
+ sprintf(dfe_errmsg, "DFE-ipc ERROR: Too many sessions already open");
+ return UDIErrorIPCLimitation;
+ }
+
+ /* One connection can be multiplexed between several sessions. */
+
+ for (cnt=0;
+ cnt < MAX_SESSIONS && soc_con[cnt].in_use;
+ cnt++);
+
+ if (cnt >= MAX_SESSIONS)
+ {
+ sprintf(dfe_errmsg,
+ "DFE-ipc ERROR: Too many connections already open");
+ return UDIErrorIPCLimitation;
+ }
+
+ *Session = rcnt;
+ session[rcnt].soc_con_p = &soc_con[cnt];
+
+ if (strchr(Config, ' ')) /* test if file entry given */
+ {
+ soc_con[cnt].in_use = TRUE;
+ sscanf(Config, "%s %s %s %s %n",
+ soc_con[cnt].connect_id,
+ soc_con[cnt].domain_string,
+ soc_con[cnt].tip_string,
+ soc_con[cnt].tip_exe,
+ &params_pos);
+ tip_main_string = Config + params_pos;
+ }
+ else /* here if need to read udi_soc file */
+ {
+ strcpy(config_file, "udi_soc");
+ env_p = getenv("UDICONF");
+ if (env_p)
+ strcpy(config_file, env_p);
+
+ fd = fopen(config_file, "r");
+
+ if (!fd)
+ {
+ sprintf(dfe_errmsg, "UDIConnect, can't open udi_soc file:\n%s ",
+ strerror(errno));
+ dfe_errno = UDIErrorCantOpenConfigFile;
+ goto tip_failure;
+ }
+
+ while (1)
+ {
+ if (fscanf(fd, "%s %s %s %s %[^\n]\n",
+ soc_con[cnt].connect_id,
+ soc_con[cnt].domain_string,
+ soc_con[cnt].tip_string,
+ soc_con[cnt].tip_exe,
+ sbuf) == EOF)
+ break;
+
+ if (strcmp(Config, soc_con[cnt].connect_id) != 0)
+ continue;
+
+ soc_con[cnt].in_use = TRUE; /* here if entry found */
+
+ tip_main_string = sbuf;
+ break;
+ }
+
+ fclose(fd);
+ if (!soc_con[cnt].in_use)
+ {
+ sprintf(dfe_errmsg,
+ "UDIConnect, can't find `%s' entry in udi_soc file",
+ Config);
+ dfe_errno = UDIErrorNoSuchConfiguration;
+ goto tip_failure;
+ }
+ }
+/*----------------------------------------------------------- SELECT DOMAIN */
+ if (strcmp(soc_con[cnt].domain_string, "AF_UNIX") == 0)
+ domain = AF_UNIX;
+ else if (strcmp(soc_con[cnt].domain_string, "AF_INET") == 0)
+ domain = AF_INET;
+ else
+ {
+ sprintf(dfe_errmsg, "DFE-ipc ERROR: socket address family not known");
+ dfe_errno = UDIErrorBadConfigFileEntry;
+ goto tip_failure;
+ }
+
+/*---------------------------------------------------- MULTIPLEXED SOCKET ? */
+/* If the requested session requires communication with
+ a TIP which already has a socket connection established,
+ then we do not create a new socket but multiplex the
+ existing one. A TIP is said to use the same socket if
+ socket-name/host-name and the domain are the same.
+ */
+ for (rcnt=0; rcnt < MAX_SESSIONS; rcnt++)
+ {
+ if (soc_con[rcnt].in_use
+ && rcnt != cnt
+ && strcmp(soc_con[cnt].domain_string,
+ soc_con[rcnt].domain_string) == 0
+ && strcmp(soc_con[cnt].tip_string,
+ soc_con[rcnt].tip_string) == 0)
+ {
+ session[*Session].soc_con_p = &soc_con[rcnt];
+ soc_con[cnt].in_use = FALSE; /* don't need new connect */
+ goto tip_connect;
+ }
+ }
+/*------------------------------------------------------------------ SOCKET */
+ soc_con[cnt].dfe_sd = socket(domain, SOCK_STREAM, 0);
+ if (soc_con[cnt].dfe_sd == -1)
+ {
+ sprintf(dfe_errmsg, "DFE-ipc ERROR, socket() call failed %s ",
+ strerror (errno));
+ dfe_errno = UDIErrorUnknownError;
+ goto tip_failure;
+ }
+
+/*--------------------------------------------------------- AF_UNIX CONNECT */
+ if (domain == AF_UNIX)
+ {
+ if (strcmp(soc_con[cnt].tip_string, "*") == 0)
+ {
+ for (pos = 0; pos < 20; pos++)
+ {
+ int f;
+
+ sprintf(soc_con[cnt].tip_string,"/tmp/U%d", getpid() + pos);
+ f = open(soc_con[cnt].tip_string, O_CREAT);
+ if (f == -1)
+ continue;
+
+ close(f);
+ unlink(soc_con[cnt].tip_string);
+ break;
+ }
+
+ if (pos >= 20)
+ {
+ sprintf(dfe_errmsg,
+ "DFE-ipc ERROR, can't create random socket name");
+ dfe_errno = UDIErrorCantConnect;
+ goto tip_failure;
+ }
+ }
+
+ soc_con[cnt].tip_sockaddr.sa_family = domain;
+ memcpy(soc_con[cnt].tip_sockaddr.sa_data,
+ soc_con[cnt].tip_string,
+ sizeof(soc_con[cnt].tip_sockaddr.sa_data));
+ if (connect(soc_con[cnt].dfe_sd,
+ &soc_con[cnt].tip_sockaddr,
+ sizeof(soc_con[cnt].tip_sockaddr)))
+ { /* if connect() fails assume TIP not yet started */
+/*------------------------------------------------------------ AF_UNIX EXEC */
+ int pid;
+ int statusp;
+ char *arg0;
+
+ arg0 = strrchr(soc_con[cnt].tip_exe,'/');
+
+ if (arg0)
+ arg0++;
+ else
+ arg0 = soc_con[cnt].tip_exe;
+
+ pid = vfork();
+
+ if (pid == 0) /* Child */
+ {
+ execlp(soc_con[cnt].tip_exe,
+ arg0,
+ soc_con[cnt].domain_string,
+ soc_con[cnt].tip_string,
+ NULL);
+ _exit(1);
+ }
+
+ if (waitpid(pid, &statusp, WNOHANG))
+ {
+ sprintf(dfe_errmsg, "DFE-ipc ERROR: can't exec the TIP");
+ dfe_errno = UDIErrorCantStartTIP;
+ goto tip_failure;
+ }
+
+ pos = 3;
+ for (pos = 3; pos > 0; pos--)
+ {
+ if (!connect(soc_con[cnt].dfe_sd,
+ &soc_con[cnt].tip_sockaddr,
+ sizeof(soc_con[cnt].tip_sockaddr)))
+ break;
+ sleep(1);
+ }
+
+ if (pos == 0)
+ {
+ sprintf(dfe_errmsg, "DFE-ipc ERROR, connect() call failed: %s",
+ strerror (errno));
+ dfe_errno = UDIErrorCantConnect;
+ goto tip_failure;
+ }
+ }
+ }
+/*--------------------------------------------------------- AF_INET CONNECT */
+ else if (domain == AF_INET)
+ {
+ fprintf(stderr,
+ "DFE-ipc WARNING, need to have first started remote TIP");
+
+ soc_con[cnt].tip_sockaddr_in.sin_family = domain;
+ soc_con[cnt].tip_sockaddr_in.sin_addr.s_addr =
+ inet_addr(soc_con[cnt].tip_string);
+ if (soc_con[cnt].tip_sockaddr_in.sin_addr.s_addr == -1)
+ {
+ tip_info_p = gethostbyname(soc_con[cnt].tip_string);
+ if (tip_info_p == NULL)
+ {
+ sprintf(dfe_errmsg,"DFE-ipc ERROR, No such host %s",
+ soc_con[cnt].tip_string);
+ dfe_errno = UDIErrorNoSuchConnection;
+ goto tip_failure;
+ }
+ memcpy((char *)&soc_con[cnt].tip_sockaddr_in.sin_addr,
+ tip_info_p->h_addr,
+ tip_info_p->h_length);
+ }
+ soc_con[cnt].tip_sockaddr_in.sin_port
+ = htons(atoi(soc_con[cnt].tip_exe));
+
+ if (connect(soc_con[cnt].dfe_sd,
+ (struct sockaddr *) &soc_con[cnt].tip_sockaddr_in,
+ sizeof(soc_con[cnt].tip_sockaddr_in)))
+ {
+ sprintf(dfe_errmsg, "DFE-ipc ERROR, connect() call failed %s ",
+ strerror (errno));
+ dfe_errno = UDIErrorCantConnect;
+ goto tip_failure;
+ }
+ }
+/*------------------------------------------------------------- TIP CONNECT */
+ if (cnt == 0) udr_create(udrs, soc_con[cnt].dfe_sd, SOC_BUF_SIZE);
+
+tip_connect:
+ current = cnt;
+ session[*Session].in_use = TRUE; /* session id is now in use */
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+
+ DFEIPCId = (company_c << 16) + (product_c << 12) + version_c;
+ udr_UDIUInt32(udrs, &DFEIPCId);
+
+ udr_string(udrs, tip_main_string);
+
+ udr_sendnow(udrs);
+
+ udrs->udr_op = UDR_DECODE; /* recv all "out" parameters */
+ udr_UDIUInt32(udrs, &TIPIPCId);
+ if ((TIPIPCId & 0xfff) < version_c)
+ sprintf(dfe_errmsg, "DFE-ipc: Obsolete TIP Specified");
+
+ udr_UDIInt32(udrs, &soc_con[cnt].tip_pid);
+
+ udr_UDISessionId(udrs, &session[*Session].tip_id);
+
+ udr_UDIError(udrs, &dfe_errno);
+ if (dfe_errno > 0) UDIKill(*Session, 0);
+
+ return dfe_errno;
+
+tip_failure:
+
+ soc_con[cnt].in_use = FALSE;
+ session[*Session].in_use = FALSE;
+/* XXX - Should also close dfe_sd, but not sure what to do if muxed */
+ return dfe_errno;
+}
+
+/************************************************************** UDI_Disconnect
+* UDIDisconnect() should be called before exiting the
+* DFE to ensure proper shut down of the TIP.
+*/
+UDIError UDIDisconnect(Session, Terminate)
+UDISessionId Session;
+UDIBool Terminate;
+{
+ int cnt;
+ UDIInt32 service_id = UDIDisconnect_c;
+ if(Session < 0 || Session > MAX_SESSIONS)
+ {
+ sprintf(dfe_errmsg," SessionId not valid (%d)", Session);
+ return UDIErrorNoSuchConfiguration;
+ }
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDISessionId(udrs, &session[Session].tip_id);
+ udr_UDIBool(udrs, &Terminate);
+ udr_sendnow(udrs);
+
+ session[Session].in_use = FALSE; /* session id is now free */
+ for (cnt=0; cnt < MAX_SESSIONS; cnt++)
+ if(session[cnt].in_use
+ && session[cnt].soc_con_p == session[Session].soc_con_p
+ ) break;
+ if(cnt >= MAX_SESSIONS) /* test if socket not multiplexed */
+ if(shutdown(session[Session].soc_con_p->dfe_sd, 2))
+ {
+ sprintf(dfe_errmsg, "DFE-ipc WARNING: socket shutdown failed");
+ return UDIErrorIPCInternal;
+ }
+ else
+ session[Session].soc_con_p->in_use = 0;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/******************************************************************** UDI_KILL
+* UDIKill() is used to send a signal to the TIP.
+* This is a private IPC call.
+*/
+UDIError UDIKill(Session, Signal)
+UDISessionId Session;
+UDIInt32 Signal;
+{
+ int cnt;
+ UDIInt32 service_id = UDIKill_c;
+ if(Session < 0 || Session > MAX_SESSIONS)
+ {
+ sprintf(dfe_errmsg," SessionId not valid (%d)", Session);
+ return UDIErrorNoSuchConfiguration;
+ }
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDISessionId(udrs, &session[Session].tip_id);
+ udr_UDIInt32(udrs, &Signal);
+ udr_sendnow(udrs);
+
+ session[Session].in_use = FALSE; /* session id is now free */
+ for (cnt=0; cnt < MAX_SESSIONS; cnt++)
+ if(session[cnt].in_use
+ && session[cnt].soc_con_p == session[Session].soc_con_p
+ ) break;
+ if(cnt < MAX_SESSIONS) /* test if socket not multiplexed */
+ if(shutdown(session[Session].soc_con_p->dfe_sd, 2))
+ {
+ sprintf(dfe_errmsg, "DFE-ipc WARNING: socket shutdown failed");
+ return UDIErrorIPCInternal;
+ }
+ else
+ session[Session].soc_con_p->in_use = 0;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/************************************************** UDI_Set_Current_Connection
+* If you are connected to multiple TIPs, you can change
+* TIPs using UDISetCurrentConnection().
+*/
+UDIError UDISetCurrentConnection(Session)
+UDISessionId Session;
+{
+ UDIInt32 service_id = UDISetCurrentConnection_c;
+
+ if(Session < 0 || Session > MAX_SESSIONS)
+ return UDIErrorNoSuchConfiguration;
+ if(!session[Session].in_use) /* test if not in use yet */
+ return UDIErrorNoSuchConnection;
+
+ current = Session;
+ /* change socket or multiplex the same socket */
+ udrs->sd = session[Session].soc_con_p->dfe_sd;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDISessionId(udrs, &session[Session].tip_id);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/************************************************************ UDI_Capabilities
+* The DFE uses UDICapabilities() to both inform the TIP
+* of what services the DFE offers and to inquire of the
+* TIP what services the TIP offers.
+*/
+UDIError UDICapabilities(TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId,
+ TIPIPCId, TIPString)
+UDIUInt32 *TIPId; /* out */
+UDIUInt32 *TargetId; /* out */
+UDIUInt32 DFEId; /* in */
+UDIUInt32 DFE; /* in */
+UDIUInt32 *TIP; /* out */
+UDIUInt32 *DFEIPCId; /* out */
+UDIUInt32 *TIPIPCId; /* out */
+char *TIPString; /* out */
+{
+ UDIInt32 service_id = UDICapabilities_c;
+ int size;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIInt32(udrs, &DFEId);
+ udr_UDIInt32(udrs, &DFE);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" paramters */
+ udr_UDIInt32(udrs, TIPId);
+ udr_UDIInt32(udrs, TargetId);
+ udr_UDIInt32(udrs, TIP);
+ udr_UDIInt32(udrs, DFEIPCId);
+ *DFEIPCId = (company_c << 16) + (product_c << 12) + version_c;
+ udr_UDIInt32(udrs, TIPIPCId);
+ udr_string(udrs, sbuf);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ size = strlen(sbuf);
+ if(size +1 > 80) return -1; /* test if sufficient space */
+ strcpy(TIPString, sbuf);
+ return dfe_errno;
+}
+
+/********************************************************** UDI_Enumerate_TIPs
+* Used by the DFE to enquire about available TIP
+* connections.
+*/
+UDIError UDIEnumerateTIPs(UDIETCallback)
+ int (*UDIETCallback)(); /* In -- function to callback */
+{
+ FILE *fp;
+
+ fp = fopen(config_file, "r");
+ if(fp == NULL)
+ return UDIErrorCantOpenConfigFile;
+ while(fgets( sbuf, SBUF_SIZE, fp))
+ if(UDIETCallback( sbuf) == UDITerminateEnumeration)
+ break;
+ fclose( fp);
+ return UDINoError; /* return success */
+}
+
+/*********************************************************** UDI_GET_ERROR_MSG
+* Some errors are target specific. They are indicated
+* by a negative error return value. The DFE uses
+* UDIGetErrorMsg() to get the descriptive text for
+* the error message which can then be displayed to
+* the user.
+*/
+UDIError UDIGetErrorMsg(error_code, msg_len, msg, CountDone)
+UDIError error_code; /* In */
+UDISizeT msg_len; /* In -- allowed message space */
+char* msg; /* Out -- length of message*/
+UDISizeT *CountDone; /* Out -- number of characters */
+{
+ UDIInt32 service_id = UDIGetErrorMsg_c;
+ int size;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIError(udrs, &error_code);
+ udr_UDISizeT(udrs, &msg_len);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_string(udrs, sbuf);
+ udr_UDISizeT(udrs, CountDone);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ size = strlen(sbuf);
+ if(size +1 > msg_len) return -1; /* test if sufficient space */
+ strcpy(msg, sbuf);
+ return dfe_errno;
+}
+
+/******************************************************* UDI_GET_TARGET_CONFIG
+* UDIGetTargetConfig() gets information about the target.
+*/
+UDIError UDIGetTargetConfig(KnownMemory, NumberOfRanges, ChipVersions,
+ NumberOfChips)
+UDIMemoryRange KnownMemory[]; /* Out */
+UDIInt *NumberOfRanges; /* In and Out */
+UDIUInt32 ChipVersions[]; /* Out */
+UDIInt *NumberOfChips; /* In and Out */
+{
+ UDIInt32 service_id = UDIGetTargetConfig_c;
+ int cnt;
+ int MaxOfRanges = *NumberOfRanges;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIInt(udrs, NumberOfRanges);
+ udr_UDIInt(udrs, NumberOfChips);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" paramters */
+ for(cnt=1; cnt <= MaxOfRanges; cnt++)
+ udr_UDIMemoryRange(udrs, &KnownMemory[cnt-1]);
+ udr_UDIInt(udrs, NumberOfRanges);
+ udr_UDIInt(udrs, NumberOfChips);
+ for(cnt=1; cnt <= *NumberOfChips; cnt++)
+ udr_UDIUInt32(udrs, &ChipVersions[cnt -1]);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/********************************************************** UDI_CREATE_PRCOESS
+* UDICreateProcess() tells the target OS that a
+* process is to be created and gets a PID back unless
+* there is some error.
+*/
+UDIError UDICreateProcess(pid)
+UDIPId *pid; /* out */
+{
+ UDIInt32 service_id = UDICreateProcess_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIPId(udrs, pid);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/***************************************************** UDI_Set_Current_Process
+* UDISetCurrentProcess uses a pid supplied by
+* UDICreateProcess and sets it as the default for all
+* udi calls until a new one is set. A user of a
+*/
+UDIError UDISetCurrentProcess (pid)
+UDIPId pid; /* In */
+{
+ UDIInt32 service_id = UDISetCurrentProcess_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIPId(udrs, &pid);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/****************************************************** UDI_INITIALISE_PROCESS
+* UDIInitializeProcess() prepare process for
+* execution. (Reset processor if process os processor).
+*/
+UDIError UDIInitializeProcess( ProcessMemory, NumberOfRanges, EntryPoint,
+ StackSizes, NumberOfStacks, ArgString)
+UDIMemoryRange ProcessMemory[]; /* In */
+UDIInt NumberOfRanges; /* In */
+UDIResource EntryPoint; /* In */
+CPUSizeT *StackSizes; /* In */
+UDIInt NumberOfStacks; /* In */
+char *ArgString; /* In */
+{
+ UDIInt32 service_id = UDIInitializeProcess_c;
+ int cnt;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIInt(udrs, &NumberOfRanges);
+ for(cnt = 0; cnt < NumberOfRanges; cnt++)
+ udr_UDIMemoryRange(udrs, &ProcessMemory[cnt] );
+ udr_UDIResource(udrs, &EntryPoint);
+ udr_UDIInt(udrs, &NumberOfStacks);
+ for(cnt = 0; cnt < NumberOfStacks; cnt++)
+ udr_CPUSizeT(udrs, &StackSizes[cnt]);
+ udr_string(udrs, ArgString);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/********************************************************* UDI_DESTROY_PROCESS
+* UDIDestroyProcess() frees a process resource
+* previously created by UDICreateProcess().
+*/
+UDIError UDIDestroyProcess(pid)
+UDIPId pid; /* in */
+{
+ UDIInt32 service_id = UDIDestroyProcess_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIPId(udrs, &pid);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/****************************************************************** UDI_READ
+* UDIRead() reads a block of objects from a target
+* address space to host space.
+*/
+
+UDIError UDIRead (from, to, count, size, count_done, host_endian)
+UDIResource from; /* in - source address on target */
+UDIHostMemPtr to; /* out - destination address on host */
+UDICount count; /* in -- count of objects to be transferred */
+UDISizeT size; /* in -- size of each object */
+UDICount *count_done; /* out - count actually transferred */
+UDIBool host_endian; /* in -- flag for endian information */
+{
+ UDIInt32 service_id = UDIRead_c;
+ int byte_count;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIResource(udrs, &from);
+ udr_UDICount(udrs, &count);
+ udr_UDISizeT(udrs, &size);
+ udr_UDIBool(udrs, &host_endian);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" paramters */
+ udr_UDICount(udrs, count_done);
+ byte_count = (*count_done) * size;
+ if(*count_done > 0 && *count_done <= count)
+ udr_bytes(udrs, to, byte_count);
+ if(udr_errno) return udr_errno;
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/****************************************************************** UDI_WRITE
+* UDIWrite() writes a block of objects from host
+* space to a target address+space.
+*/
+UDIError UDIWrite( from, to, count, size, count_done, host_endian )
+UDIHostMemPtr from; /* in -- source address on host */
+UDIResource to; /* in -- destination address on target */
+UDICount count; /* in -- count of objects to be transferred */
+UDISizeT size; /* in -- size of each object */
+UDICount *count_done; /* out - count actually transferred */
+UDIBool host_endian; /* in -- flag for endian information */
+{
+ UDIInt32 service_id = UDIWrite_c;
+ int byte_count = count * size;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIResource(udrs, &to);
+ udr_UDICount(udrs, &count);
+ udr_UDISizeT(udrs, &size);
+ udr_UDIBool(udrs, &host_endian);
+ udr_bytes(udrs, from, byte_count);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" paramters */
+ udr_UDICount(udrs, count_done);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/******************************************************************** UDI_COPY
+* UDICopy() copies a block of objects from one target
+* get address/space to another target address/space.
+*/
+UDIError UDICopy(from, to, count, size, count_done, direction )
+UDIResource from; /* in -- destination address on target */
+UDIResource to; /* in -- source address on target */
+UDICount count; /* in -- count of objects to be transferred */
+UDISizeT size; /* in -- size of each object */
+UDICount *count_done; /* out - count actually transferred */
+UDIBool direction; /* in -- high-to-low or reverse */
+{
+ UDIInt32 service_id = UDICopy_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIResource(udrs, &from);
+ udr_UDIResource(udrs, &to);
+ udr_UDICount(udrs, &count);
+ udr_UDISizeT(udrs, &size);
+ udr_UDIBool(udrs, &direction);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDICount(udrs, count_done);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/***************************************************************** UDI_EXECUTE
+* UDIExecute() continues execution of the default
+* process from the current PC.
+*/
+UDIError UDIExecute()
+{
+ UDIInt32 service_id = UDIExecute_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/******************************************************************** UDI_STEP
+* UDIStep() specifies a number of "instruction"
+* steps to make.
+*/
+UDIError UDIStep(steps, steptype, range)
+UDIUInt32 steps; /* in -- number of steps */
+UDIStepType steptype; /* in -- type of stepping to be done */
+UDIRange range; /* in -- range if StepInRange is TRUE */
+{
+ UDIInt32 service_id = UDIStep_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIInt32(udrs, &steps);
+ udr_UDIStepType(udrs, &steptype);
+ udr_UDIRange(udrs, &range);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/******************************************************************** UDI_STOP
+* UDIStop() stops the default process
+*/
+UDIVoid UDIStop()
+{
+ if (strcmp(session[current].soc_con_p->domain_string, "AF_UNIX") == 0)
+ kill(session[current].soc_con_p->tip_pid, SIGINT);
+ else
+ udr_signal(udrs);
+
+/* XXX - should clean up session[] and soc_con[] structs here as well... */
+
+ return;
+}
+
+/******************************************************************** UDI_WAIT
+* UDIWait() returns the state of the target procesor.
+*/
+UDIError UDIWait(maxtime, pid, stop_reason)
+UDIInt32 maxtime; /* in -- maximum time to wait for completion */
+UDIPId *pid; /* out -- pid of process which stopped if any */
+UDIUInt32 *stop_reason; /* out -- PC where process stopped */
+{
+ UDIInt32 service_id = UDIWait_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIInt32(udrs, &maxtime);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIPId(udrs, pid);
+ udr_UDIUInt32(udrs, stop_reason);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/********************************************************** UDI_SET_BREAKPOINT
+* UDISetBreakpoint() sets a breakpoint at an adress
+* and uses the passcount to state how many
+* times that instruction should be hit before the
+* break occurs.
+*/
+UDIError UDISetBreakpoint (addr, passcount, type, break_id)
+UDIResource addr; /* in -- where breakpoint gets set */
+UDIInt32 passcount; /* in -- passcount for breakpoint */
+UDIBreakType type; /* in -- breakpoint type */
+UDIBreakId *break_id; /* out - assigned break id */
+{
+ UDIInt32 service_id = UDISetBreakpoint_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIResource(udrs, &addr);
+ udr_UDIInt32(udrs, &passcount);
+ udr_UDIBreakType(udrs, &type);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIBreakId(udrs, break_id);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/******************************************************** UDI_QUERY_BREAKPOINT
+*/
+UDIError UDIQueryBreakpoint (break_id, addr, passcount, type, current_count)
+UDIBreakId break_id; /* in -- assigned break id */
+UDIResource *addr; /* out - where breakpoint was set */
+UDIInt32 *passcount; /* out - trigger passcount for breakpoint */
+UDIBreakType *type; /* out - breakpoint type */
+UDIInt32 *current_count; /* out - current count for breakpoint */
+{
+ UDIInt32 service_id = UDIQueryBreakpoint_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIBreakId(udrs, &break_id);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIResource(udrs, addr);
+ udr_UDIInt32(udrs, passcount);
+ udr_UDIBreakType(udrs, type);
+ udr_UDIInt32(udrs, current_count);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/******************************************************** UDI_CLEAR_BREAKPOINT
+* UDIClearBreakpoint() is used to clear a breakpoint.
+*/
+UDIError UDIClearBreakpoint (break_id)
+UDIBreakId break_id; /* in -- assigned break id */
+{
+ UDIInt32 service_id = UDIClearBreakpoint_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIBreakId(udrs, &break_id);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/************************************************************** UDI_GET_STDOUT
+* UDIGetStdout() is called when a call to
+* UDIWait() indicates there is STD output data ready.
+*/
+UDIError UDIGetStdout(buf, bufsize, count_done)
+UDIHostMemPtr buf; /* out -- buffer to be filled */
+UDISizeT bufsize; /* in -- buffer size in bytes */
+UDISizeT *count_done; /* out -- number of bytes written to buf */
+{
+ UDIInt32 service_id = UDIGetStdout_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDISizeT(udrs, &bufsize);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDISizeT(udrs, count_done);
+ udr_bytes(udrs, buf, *count_done);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/************************************************************** UDI_GET_STDERR
+* UDIGetStderr() is called when a call to
+* UDIWait() indicates there is STDERR output data ready
+*/
+UDIError UDIGetStderr(buf, bufsize, count_done)
+UDIHostMemPtr buf; /* out -- buffer to be filled */
+UDISizeT bufsize; /* in -- buffer size in bytes */
+UDISizeT *count_done; /* out -- number of bytes written to buf */
+{
+ UDIInt32 service_id = UDIGetStderr_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDISizeT(udrs, &bufsize);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDISizeT(udrs, count_done);
+ udr_bytes(udrs, buf, *count_done);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/*************************************************************** UDI_PUT_STDIN
+* UDIPutStdin() is called whenever the DFE wants to
+* deliver an input character to the TIP.
+*/
+UDIError UDIPutStdin (buf, count, count_done)
+UDIHostMemPtr buf; /* in -- buffer to be filled */
+UDISizeT count; /* in -- buffer size in bytes */
+UDISizeT *count_done; /* out - number of bytes written to buf */
+{
+ UDIInt32 service_id = UDIPutStdin_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDISizeT(udrs, &count);
+ udr_bytes(udrs, buf, count);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDISizeT(udrs, count_done);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/************************************************************** UDI_STDIN_MODE
+* UDIStdinMode() is used to change the mode that chazcters
+* are fetched from the user.
+*/
+UDIError UDIStdinMode(mode)
+UDIMode *mode; /* out - */
+{
+ UDIInt32 service_id = UDIStdinMode_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIMode(udrs, mode);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/*************************************************************** UDI_PUT_TRANS
+* UDIPutTrans() is used to feed input to the passthru mode.
+*/
+UDIError UDIPutTrans (buf, count, count_done)
+UDIHostMemPtr buf; /* in -- buffer address containing input data */
+UDISizeT count; /* in -- number of bytes in buf */
+UDISizeT *count_done; /* out-- number of bytes transfered */
+{
+ UDIInt32 service_id = UDIPutTrans_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDISizeT(udrs, &count);
+ udr_bytes(udrs, buf, count);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDISizeT(udrs, count_done);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/*************************************************************** UDI_GET_TRANS
+* UDIGetTrans() is used to get output lines from the
+* passthru mode.
+*/
+UDIError UDIGetTrans (buf, bufsize, count_done)
+UDIHostMemPtr buf; /* out -- buffer to be filled */
+UDISizeT bufsize; /* in -- size of buf */
+UDISizeT *count_done; /* out -- number of bytes in buf */
+{
+ UDIInt32 service_id = UDIGetTrans_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDISizeT(udrs, &bufsize);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDISizeT(udrs, count_done);
+ udr_bytes(udrs, buf, *count_done);
+ udr_UDIError(udrs, &dfe_errno); /* get any TIP error */
+ return dfe_errno;
+}
+
+/************************************************************** UDI_Trans_Mode
+* UDITransMode() is used to change the mode that the
+* transparent routines operate in.
+*/
+UDIError UDITransMode(mode)
+UDIMode *mode; /* out -- selected mode */
+{
+ UDIInt32 service_id = UDITransMode_c;
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+ udr_UDIMode(udrs, mode);
+ udr_sendnow(udrs);
+ if(udr_errno) return udr_errno;
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ udr_UDIError(udrs, &dfe_errno);
+ return dfe_errno;
+}
+
+/******************************************************************** UDI_TEST
+*/
+UDIError UDITest( cnt, str_p, array)
+UDISizeT cnt;
+UDIHostMemPtr str_p;
+UDIInt32 array[];
+{
+ UDIInt32 service_id = UDITest_c;
+ UDIInt16 scnt = cnt;
+ UDISizeT r_cnt;
+ char buf[256];
+
+ udr_errno = 0;
+ udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */
+ udr_UDIInt32(udrs, &service_id);
+
+ printf("send cnt=%d scnt=%d\n", cnt, scnt);
+ udr_UDISizeT(udrs, &cnt);
+ udr_UDIInt16(udrs, &scnt);
+ printf(" array[0]=0x%x array[1]=0x%x array[2]=0x%x array[3]=0x%x\n",
+ array[0], array[1], array[2], array[3]);
+ udr_bytes(udrs, (char*)array, 4*sizeof(UDIInt32));
+ printf(" string=%s\n", str_p);
+ udr_string(udrs, str_p);
+ udr_sendnow(udrs);
+ if(udr_errno)
+ { fprintf(stderr, " DFE-ipc Send ERROR\n");
+ return udr_errno;
+ }
+
+ udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */
+ printf("recv ");
+ udr_UDISizeT(udrs, &r_cnt);
+ udr_UDIInt16(udrs, &scnt);
+ printf(" rcnt=%d scnt=%d\n", r_cnt, scnt);
+ udr_bytes(udrs, (char*)array, 4*sizeof(UDIInt32));
+
+ printf(" array[0]=0x%x array[1]=0x%x array[2]=0x%x array[3]=0x%x\n",
+ array[0], array[1], array[2], array[3]);
+ udr_string(udrs, str_p);
+ printf(" string=%s\n", str_p);
+
+ udr_UDIError(udrs, &dfe_errno);
+ return dfe_errno;
+}
+
+
+
+UDIUInt32 UDIGetDFEIPCId()
+{
+ return ((company_c << 16) + (product_c << 12) + version_c);
+}
+#endif /* __GO32__ */
diff --git a/gdb/29k-share/udi/udiphcfg.h b/gdb/29k-share/udi/udiphcfg.h
new file mode 100644
index 00000000000..e9eff0a3c86
--- /dev/null
+++ b/gdb/29k-share/udi/udiphcfg.h
@@ -0,0 +1,44 @@
+/* This file just picks the correct udiphxxx.h depending on the host.
+ The two hosts that are now defined are UNIX and MSDOS.
+
+ Copyright 1993 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. */
+
+/*
+ * For the moment, we will default to BSD_IPC; this might change if/when
+ * another type of IPC (Mach? SysV?) is implemented.
+ */
+
+#if 0
+
+/* We don't seem to have a copy of udiphdos.h. Furthermore, all the
+ things in udiphunix.h are pretty much generic 32-bit machine defines
+ which don't have anything to do with IPC. */
+
+#ifdef DOS_IPC
+#include "udiphdos.h"
+#else
+/*#ifdef BSD_IPC */
+#include "udiphunix.h"
+#endif
+
+#else
+
+#include "udiphunix.h"
+
+#endif
diff --git a/gdb/29k-share/udi/udiphunix.h b/gdb/29k-share/udi/udiphunix.h
new file mode 100644
index 00000000000..172fbbfd85b
--- /dev/null
+++ b/gdb/29k-share/udi/udiphunix.h
@@ -0,0 +1,81 @@
+/* Originally called "udiphsun.h", however it was not very
+ Sun-specific; now it is used for generic-unix-with-bsd-ipc.
+
+ Copyright 1993 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. */
+
+/* This file is to be used to reconfigure the UDI Procedural interface
+ for a given host. This file should be placed so that it will be
+ included from udiproc.h. Everything in here may need to be changed
+ when you change either the host CPU or its compiler. Nothing in
+ here should change to support different targets. There are multiple
+ versions of this file, one for each of the different host/compiler
+ combinations in use.
+*/
+
+#define UDIStruct struct /* _packed not needed on unix */
+/* First, we need some types */
+/* Types with at least the specified number of bits */
+typedef double UDIReal64; /* 64-bit real value */
+typedef float UDIReal32; /* 32-bit real value */
+
+typedef unsigned long UDIUInt32; /* unsigned integers */
+typedef unsigned short UDIUInt16;
+typedef unsigned char UDIUInt8;
+
+typedef long UDIInt32; /* 32-bit integer */
+typedef short UDIInt16; /* 16-bit integer */
+typedef char UDIInt8; /* unreliable signedness */
+
+/* To aid in supporting environments where the DFE and TIP use
+different compilers or hosts (like DOS 386 on one side, 286 on the
+other, or different Unix machines connected by sockets), we define
+two abstract types - UDIInt and UDISizeT.
+UDIInt should be defined to be int except for host/compiler combinations
+that are intended to talk to existing UDI components that have a different
+sized int. Similarly for UDISizeT.
+*/
+typedef int UDIInt;
+typedef unsigned int UDIUInt;
+
+typedef unsigned int UDISizeT;
+
+/* Now two void types. The first is for function return types,
+the other for pointers to no particular type. Since these types
+are used solely for documentational clarity, if your host/compiler
+doesn't support either one, replace them with int and char *
+respectively.
+*/
+typedef void UDIVoid; /* void type */
+typedef void * UDIVoidPtr; /* void pointer type */
+typedef void * UDIHostMemPtr; /* Arbitrary memory pointer */
+
+/* Now we want a type optimized for boolean values. Normally this
+ would be int, but on some machines (Z80s, 8051s, etc) it might
+ be better to map it onto a char
+*/
+typedef int UDIBool;
+
+/* Now indicate whether your compiler support full ANSI style
+ prototypes. If so, use #if 1. If not use #if 0.
+*/
+#if 0
+#define UDIParams(x) x
+#else
+#define UDIParams(x) ()
+#endif
diff --git a/gdb/29k-share/udi/udiproc.h b/gdb/29k-share/udi/udiproc.h
new file mode 100644
index 00000000000..0cc1c2049c1
--- /dev/null
+++ b/gdb/29k-share/udi/udiproc.h
@@ -0,0 +1,308 @@
+/* local type decs. and macro defs.
+
+ Copyright 1993 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 "udiphcfg.h" /* Get host specific configuration */
+#include "udiptcfg.h" /* Get target specific configuration */
+
+/* Here are all of the CPU Families for which UDI is currently defined */
+#define Am29K 1 /* AMD's Am290xx and Am292xx parts */
+
+typedef UDIInt UDIError;
+typedef UDIInt UDISessionId;
+typedef UDIInt UDIPId;
+typedef UDIInt UDIStepType;
+typedef UDIInt UDIBreakType;
+typedef UDIUInt UDIBreakId;
+typedef UDIUInt UDIMode;
+
+typedef UDIStruct
+{
+ CPUSpace Space;
+ CPUOffset Offset;
+} UDIResource;
+
+typedef UDIStruct
+{
+ CPUOffset Low;
+ CPUOffset High;
+} UDIRange;
+
+typedef UDIStruct
+{
+ CPUSpace Space;
+ CPUOffset Offset;
+ CPUSizeT Size;
+ } UDIMemoryRange;
+
+/* Values for UDIStepType parameters */
+#define UDIStepNatural 0x0000
+#define UDIStepOverTraps 0x0001
+#define UDIStepOverCalls 0x0002
+#define UDIStepInRange 0x0004
+#define UDIStepNatural 0x0000
+
+/* Values for UDIBreakType parameters */
+#define UDIBreakFlagExecute 0x0001
+#define UDIBreakFlagRead 0x0002
+#define UDIBreakFlagWrite 0x0004
+#define UDIBreakFlagFetch 0x0008
+
+/* Special values for UDIWait MaxTime parameter */
+#define UDIWaitForever (UDIInt32) -1 /* Infinite time delay */
+
+/* Special values for PId */
+#define UDIProcessProcessor -1 /* Raw Hardware, if possible */
+
+/* Values for UDIWait StopReason */
+#define UDIGrossState 0xff
+#define UDITrapped 0 /* Fine state - which trap */
+#define UDINotExecuting 1
+#define UDIRunning 2
+#define UDIStopped 3
+#define UDIWarned 4
+#define UDIStepped 5
+#define UDIWaiting 6
+#define UDIHalted 7
+#define UDIStdoutReady 8 /* fine state - size */
+#define UDIStderrReady 9 /* fine state - size */
+#define UDIStdinNeeded 10 /* fine state - size */
+#define UDIStdinModeX 11 /* fine state - mode */
+#define UDIBreak 12 /* Fine state - Breakpoint Id */
+#define UDIExited 13 /* Fine state - exit code */
+
+/* Enumerate the return values from the callback function
+ for UDIEnumerateTIPs.
+*/
+#define UDITerminateEnumeration 0
+#define UDIContinueEnumeration 1
+
+/* Enumerate values for Terminate parameter to UDIDisconnect */
+#define UDITerminateSession 1
+#define UDIContinueSession 0
+
+/* Error codes */
+#define UDINoError 0 /* No error occured */
+#define UDIErrorNoSuchConfiguration 1
+#define UDIErrorCantHappen 2
+#define UDIErrorCantConnect 3
+#define UDIErrorNoSuchConnection 4
+#define UDIErrorNoConnection 5
+#define UDIErrorCantOpenConfigFile 6
+#define UDIErrorCantStartTIP 7
+#define UDIErrorConnectionUnavailable 8
+#define UDIErrorTryAnotherTIP 9
+#define UDIErrorExecutableNotTIP 10
+#define UDIErrorInvalidTIPOption 11
+#define UDIErrorCantDisconnect 12
+#define UDIErrorUnknownError 13
+#define UDIErrorCantCreateProcess 14
+#define UDIErrorNoSuchProcess 15
+#define UDIErrorUnknownResourceSpace 16
+#define UDIErrorInvalidResource 17
+#define UDIErrorUnsupportedStepType 18
+#define UDIErrorCantSetBreakpoint 19
+#define UDIErrorTooManyBreakpoints 20
+#define UDIErrorInvalidBreakId 21
+#define UDIErrorNoMoreBreakIds 22
+#define UDIErrorUnsupportedService 23
+#define UDIErrorTryAgain 24
+#define UDIErrorIPCLimitation 25
+#define UDIErrorIncomplete 26
+#define UDIErrorAborted 27
+#define UDIErrorTransDone 28
+#define UDIErrorCantAccept 29
+#define UDIErrorTransInputNeeded 30
+#define UDIErrorTransModeX 31
+#define UDIErrorInvalidSize 32
+#define UDIErrorBadConfigFileEntry 33
+#define UDIErrorIPCInternal 34
+/* TBD */
+
+/****************************************************************** PROCEDURES
+*/
+
+UDIError UDIConnect UDIParams((
+ char *Configuration, /* In */
+ UDISessionId *Session /* Out */
+ ));
+
+UDIError UDIDisconnect UDIParams((
+ UDISessionId Session, /* In */
+ UDIBool Terminate /* In */
+ ));
+
+UDIError UDISetCurrentConnection UDIParams((
+ UDISessionId Session /* In */
+ ));
+
+UDIError UDICapabilities UDIParams((
+ UDIUInt32 *TIPId, /* Out */
+ UDIUInt32 *TargetId, /* Out */
+ UDIUInt32 DFEId, /* In */
+ UDIUInt32 DFE, /* In */
+ UDIUInt32 *TIP, /* Out */
+ UDIUInt32 *DFEIPCId, /* Out */
+ UDIUInt32 *TIPIPCId, /* Out */
+ char *TIPString /* Out */
+ ));
+
+UDIError UDIEnumerateTIPs UDIParams((
+ UDIInt (*UDIETCallback) /* In */
+ UDIParams(( char *Configuration )) /* In to callback() */
+ ));
+
+UDIError UDIGetErrorMsg UDIParams((
+ UDIError ErrorCode, /* In */
+ UDISizeT MsgSize, /* In */
+ char *Msg, /* Out */
+ UDISizeT *CountDone /* Out */
+ ));
+
+UDIError UDIGetTargetConfig UDIParams((
+ UDIMemoryRange KnownMemory[], /* Out */
+ UDIInt *NumberOfRanges, /* In/Out */
+ UDIUInt32 ChipVersions[], /* Out */
+ UDIInt *NumberOfChips /* In/Out */
+ ));
+
+UDIError UDICreateProcess UDIParams((
+ UDIPId *PId /* Out */
+ ));
+
+UDIError UDISetCurrentProcess UDIParams((
+ UDIPId PId /* In */
+ ));
+
+UDIError UDIDestroyProcess UDIParams((
+ UDIPId PId /* In */
+ ));
+
+UDIError UDIInitializeProcess UDIParams((
+ UDIMemoryRange ProcessMemory[], /* In */
+ UDIInt NumberOfRanges, /* In */
+ UDIResource EntryPoint, /* In */
+ CPUSizeT StackSizes[], /* In */
+ UDIInt NumberOfStacks, /* In */
+ char *ArgString /* In */
+ ));
+
+UDIError UDIRead UDIParams((
+ UDIResource From, /* In */
+ UDIHostMemPtr To, /* Out */
+ UDICount Count, /* In */
+ UDISizeT Size, /* In */
+ UDICount *CountDone, /* Out */
+ UDIBool HostEndian /* In */
+ ));
+
+UDIError UDIWrite UDIParams((
+ UDIHostMemPtr From, /* In */
+ UDIResource To, /* In */
+ UDICount Count, /* In */
+ UDISizeT Size, /* In */
+ UDICount *CountDone, /* Out */
+ UDIBool HostEndian /* In */
+ ));
+
+UDIError UDICopy UDIParams((
+ UDIResource From, /* In */
+ UDIResource To, /* In */
+ UDICount Count, /* In */
+ UDISizeT Size, /* In */
+ UDICount *CountDone, /* Out */
+ UDIBool Direction /* In */
+ ));
+
+UDIError UDIExecute UDIParams((
+ void
+ ));
+
+UDIError UDIStep UDIParams((
+ UDIUInt32 Steps, /* In */
+ UDIStepType StepType, /* In */
+ UDIRange Range /* In */
+ ));
+
+UDIVoid UDIStop UDIParams((
+ void
+ ));
+
+UDIError UDIWait UDIParams((
+ UDIInt32 MaxTime, /* In */
+ UDIPId *PId, /* Out */
+ UDIUInt32 *StopReason /* Out */
+ ));
+
+UDIError UDISetBreakpoint UDIParams((
+ UDIResource Addr, /* In */
+ UDIInt32 PassCount, /* In */
+ UDIBreakType Type, /* In */
+ UDIBreakId *BreakId /* Out */
+ ));
+
+UDIError UDIQueryBreakpoint UDIParams((
+ UDIBreakId BreakId, /* In */
+ UDIResource *Addr, /* Out */
+ UDIInt32 *PassCount, /* Out */
+ UDIBreakType *Type, /* Out */
+ UDIInt32 *CurrentCount /* Out */
+ ));
+
+UDIError UDIClearBreakpoint UDIParams((
+ UDIBreakId BreakId /* In */
+ ));
+
+UDIError UDIGetStdout UDIParams((
+ UDIHostMemPtr Buf, /* Out */
+ UDISizeT BufSize, /* In */
+ UDISizeT *CountDone /* Out */
+ ));
+
+UDIError UDIGetStderr UDIParams((
+ UDIHostMemPtr Buf, /* Out */
+ UDISizeT BufSize, /* In */
+ UDISizeT *CountDone /* Out */
+ ));
+
+UDIError UDIPutStdin UDIParams((
+ UDIHostMemPtr Buf, /* In */
+ UDISizeT Count, /* In */
+ UDISizeT *CountDone /* Out */
+ ));
+
+UDIError UDIStdinMode UDIParams((
+ UDIMode *Mode /* Out */
+ ));
+
+UDIError UDIPutTrans UDIParams((
+ UDIHostMemPtr Buf, /* In */
+ UDISizeT Count, /* In */
+ UDISizeT *CountDone /* Out */
+ ));
+
+UDIError UDIGetTrans UDIParams((
+ UDIHostMemPtr Buf, /* Out */
+ UDISizeT BufSize, /* In */
+ UDISizeT *CountDone /* Out */
+ ));
+
+UDIError UDITransMode UDIParams((
+ UDIMode *Mode /* Out */
+ ));
diff --git a/gdb/29k-share/udi/udipt29k.h b/gdb/29k-share/udi/udipt29k.h
new file mode 100644
index 00000000000..5de2f3ff860
--- /dev/null
+++ b/gdb/29k-share/udi/udipt29k.h
@@ -0,0 +1,87 @@
+/* This file is to be used to reconfigure the UDI Procedural interface
+ for a given target.
+
+ Copyright 1993 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. */
+
+/* This file should be placed so that it will be
+ included from udiproc.h. Everything in here will probably need to
+ be changed when you change the target processor. Nothing in here
+ should need to change when you change hosts or compilers.
+*/
+
+/* Select a target CPU Family */
+#define TargetCPUFamily Am29K
+
+/* Enumerate the processor specific values for Space in a resource */
+#define UDI29KDRAMSpace 0
+#define UDI29KIOSpace 1
+#define UDI29KCPSpace0 2
+#define UDI29KCPSpace1 3
+#define UDI29KIROMSpace 4
+#define UDI29KIRAMSpace 5
+#define UDI29KLocalRegs 8
+#define UDI29KGlobalRegs 9
+#define UDI29KRealRegs 10
+#define UDI29KSpecialRegs 11
+#define UDI29KTLBRegs 12 /* Not Am29005 */
+#define UDI29KACCRegs 13 /* Am29050 only */
+#define UDI29KICacheSpace 14 /* Am2903x only */
+#define UDI29KAm29027Regs 15 /* When available */
+#define UDI29KPC 16
+#define UDI29KDCacheSpace 17 /* When available */
+
+/* Enumerate the Co-processor registers */
+#define UDI29KCP_F 0
+#define UDI29KCP_Flag 8
+#define UDI29KCP_I 12
+#define UDI29KCP_ITmp 16
+#define UDI29KCP_R 20
+#define UDI29KCP_S 28
+#define UDI29KCP_RTmp 36
+#define UDI29KCP_STmp 44
+#define UDI29KCP_Stat 52
+#define UDI29KCP_Prec 56
+#define UDI29KCP_Reg0 60
+#define UDI29KCP_Reg1 68
+#define UDI29KCP_Reg2 76
+#define UDI29KCP_Reg3 84
+#define UDI29KCP_Reg4 92
+#define UDI29KCP_Reg5 100
+#define UDI29KCP_Reg6 108
+#define UDI29KCP_Reg7 116
+#define UDI29KCP_Mode 124
+
+/* Enumerate the stacks in StackSizes array */
+#define UDI29KMemoryStack 0
+#define UDI29KRegisterStack 1
+
+/* Enumerate the chips for ChipVersions array */
+#define UDI29K29KVersion 0
+#define UDI29K29027Version 1
+
+/* Define special value for elements of ChipVersions array for
+ * chips not present */
+#define UDI29KChipNotPresent -1
+
+typedef UDIInt32 UDICount;
+typedef UDIUInt32 UDISize;
+
+typedef UDIInt CPUSpace;
+typedef UDIUInt32 CPUOffset;
+typedef UDIUInt32 CPUSizeT;
diff --git a/gdb/29k-share/udi/udiptcfg.h b/gdb/29k-share/udi/udiptcfg.h
new file mode 100644
index 00000000000..1641a53bcd4
--- /dev/null
+++ b/gdb/29k-share/udi/udiptcfg.h
@@ -0,0 +1,19 @@
+/* Copyright 1993 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 "udipt29k.h"
diff --git a/gdb/29k-share/udi/udisoc.h b/gdb/29k-share/udi/udisoc.h
new file mode 100644
index 00000000000..bc68b3944ec
--- /dev/null
+++ b/gdb/29k-share/udi/udisoc.h
@@ -0,0 +1,184 @@
+/* This module defines constants used in the UDI IPC modules.
+
+ Copyright 1993 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. */
+
+static char udisoc_h[]="@(#)udisoc.h 2.6 Daniel Mann";
+static char udisoc_h_AMD[]="@(#)udisoc.h 2.4, AMD";
+
+#define LOCAL static
+#define company_c 1 /* AMD Company id */
+#define product_c 1 /* socket IPC id */
+
+/* Enumerate the UDI procedure services
+*/
+#define UDIConnect_c 0
+#define UDIDisconnect_c 1
+#define UDISetCurrentConnection_c 2
+#define UDICapabilities_c 3
+#define UDIEnumerateTIPs_c 4
+#define UDIGetErrorMsg_c 5
+#define UDIGetTargetConfig_c 6
+#define UDICreateProcess_c 7
+#define UDISetCurrentProcess_c 8
+#define UDIDestroyProcess_c 9
+#define UDIInitializeProcess_c 10
+#define UDIRead_c 11
+#define UDIWrite_c 12
+#define UDICopy_c 13
+#define UDIExecute_c 14
+#define UDIStep_c 15
+#define UDIStop_c 16
+#define UDIWait_c 17
+#define UDISetBreakpoint_c 18
+#define UDIQueryBreakpoint_c 19
+#define UDIClearBreakpoint_c 20
+#define UDIGetStdout_c 21
+#define UDIGetStderr_c 22
+#define UDIPutStdin_c 23
+#define UDIStdinMode_c 24
+#define UDIPutTrans_c 25
+#define UDIGetTrans_c 26
+#define UDITransMode_c 27
+#define UDITest_c 28
+#define UDIKill_c 29
+
+#define udr_UDIInt8(udrs, obj) udr_work(udrs, obj, 1)
+#define udr_UDIInt16(udrs, obj) udr_work(udrs, obj, 2)
+#define udr_UDIInt32(udrs, obj) udr_work(udrs, obj, 4)
+#define udr_UDIInt(udrs, obj) udr_work(udrs, obj, 4)
+
+#define udr_UDIUInt8(udrs, obj) udr_work(udrs, obj, 1)
+#define udr_UDIUInt16(udrs, obj) udr_work(udrs, obj, 2)
+#define udr_UDIUInt32(udrs, obj) udr_work(udrs, obj, 4)
+#define udr_UDIUInt(udrs, obj) udr_work(udrs, obj, 4)
+
+#define udr_UDIBool(udrs, obj) udr_UDIInt32(udrs, obj)
+#define udr_UDICount(udrs, obj) udr_UDIInt32(udrs, obj)
+#define udr_UDISize(udrs, obj) udr_UDIUInt32(udrs, obj)
+#define udr_CPUSpace(udrs, obj) udr_UDIInt32(udrs, obj)
+#define udr_CPUOffset(udrs, obj) udr_UDIUInt32(udrs, obj)
+#define udr_CPUSizeT(udrs, obj) udr_UDIUInt32(udrs, obj)
+#define udr_UDIBreakId(udrs,obj) udr_UDIUInt(udrs, obj)
+#define udr_UDISizeT(udrs, obj) udr_UDIUInt(udrs, obj)
+#define udr_UDIMode(udrs, obj) udr_UDIUInt(udrs, obj)
+
+#define udr_UDIHostMemPtr(udrs, obj) udr_UDIUInt32(udrs, obj)
+#define udr_UDIVoidPtr(udrs, obj) udr_UDIUInt32(udrs, obj)
+#define udr_UDIPId(udrs, obj) udr_UDIUInt(udrs, obj)
+#define udr_UDISessionId(udrs, obj) udr_UDIInt32(udrs, obj)
+#define udr_UDIError(udrs, obj) udr_UDIInt32(udrs, obj)
+#define udr_UDIStepType(udrs, obj) udr_UDIInt32(udrs, obj)
+#define udr_UDIBreakType(udrs, obj) udr_UDIInt32(udrs, obj)
+
+
+#define UDR_ENCODE 1
+#define UDR_DECODE 2
+
+typedef struct UDR_str
+{
+ int udr_op; /* UDR operation */
+ int previous_op;
+ int sd;
+ int bufsize;
+ char* buff;
+ char* getbytes;
+ char* putbytes;
+ char* putend;
+ int domain;
+ char* soc_name;
+} UDR;
+
+/******************************************* Declare UDR suport functions */
+int udr_create UDIParams((
+ UDR* udrs,
+ int sd,
+ int size
+ ));
+
+int udr_free UDIParams((
+ UDR* udrs,
+ ));
+
+int udr_signal UDIParams((
+ UDR* udrs,
+ ));
+
+int udr_sendnow UDIParams((
+ UDR* udrs
+ ));
+
+int udr_work UDIParams((
+ UDR* udrs,
+ void* object_p,
+ int size
+ ));
+
+int udr_UDIResource UDIParams((
+ UDR* udrs,
+ UDIResource* object_p
+ ));
+
+int udr_UDIRange UDIParams((
+ UDR* udrs,
+ UDIRange* object_p
+ ));
+
+int udr_UDIMemoryRange UDIParams((
+ UDR* udrs,
+ UDIMemoryRange* object_p
+ ));
+
+int udr_UDIMemoryRange UDIParams((
+ UDR* udrs,
+ UDIMemoryRange* object_p
+ ));
+
+int udr_int UDIParams((
+ UDR* udrs,
+ int* int_p
+ ));
+
+int udr_bytes UDIParams((
+ UDR* udrs,
+ char* ptr,
+ int len
+ ));
+
+char* udr_inline UDIParams((
+ UDR* udrs,
+ int size
+ ));
+
+char* udr_getpos UDIParams((
+ UDR* udrs
+ ));
+int udr_setpos UDIParams((
+ UDR* udrs,
+ char* pos
+ ));
+
+int udr_readnow UDIParams((
+ UDR* udrs,
+ int size
+ ));
+
+int udr_align UDIParams((
+ UDR* udrs,
+ int size,
+ ));
diff --git a/gdb/29k-share/udi/udr.c b/gdb/29k-share/udi/udr.c
new file mode 100644
index 00000000000..10a9f38c6ae
--- /dev/null
+++ b/gdb/29k-share/udi/udr.c
@@ -0,0 +1,427 @@
+/* This module supports sending and receiving data objects over a
+ socket conection.
+
+ Copyright 1993 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. */
+
+static char udr_c[]="@(#)udr.c 2.8 Daniel Mann";
+static char udr_c_AMD[]="@(#)udr.c 2.3, AMD";
+/*
+* All data is serialised into a character stream,
+* and de-serialised back into the approproiate objects.
+********************************************************************** HISTORY
+*/
+/* This is all unneeded on DOS machines. */
+#ifndef __GO32__
+
+#include <stdio.h>
+#include <sys/types.h>
+
+/* This used to say sys/fcntl.h, but the only systems I know of that
+ require that are old (pre-4.3, at least) BSD systems, which we
+ probably don't need to worry about. */
+#include <fcntl.h>
+
+#include <sys/socket.h>
+#include "udiproc.h"
+#include "udisoc.h"
+
+extern int errno;
+extern char* malloc();
+
+/* local type decs. and macro defs. not in a .h file ************* MACRO/TYPE
+*/
+
+/* global dec/defs. which are not in a .h file ************* EXPORT DEC/DEFS
+*/
+int udr_errno; /* error occurs during UDR service */
+
+/* local dec/defs. which are not in a .h file *************** LOCAL DEC/DEFS
+*/
+
+/****************************************************************** UDR_CREATE
+* Build UDR structure for character stream processing.
+*/
+int udr_create(udrs, sd, size)
+UDR* udrs;
+int sd;
+int size;
+{
+ udrs->sd = sd;
+ if(!udrs->buff) udrs->buff = malloc(size);
+ udrs->getbytes = udrs->buff; /* set the buffer to the start */
+ udrs->putbytes = udrs->buff;
+ udrs->putend = udrs->buff;
+ udrs->udr_op = -1; /* don't know the direction */
+ udrs->previous_op = -1; /* don't know the direction */
+ udrs->bufsize = size;
+ return 0;
+}
+
+/******************************************************************** UDR_FREE
+* Free USR structure and close socket.
+*/
+int udr_free(udrs)
+UDR* udrs;
+{
+ close(udrs->sd);
+ free(udrs->buff);
+ return 0;
+}
+
+/****************************************************************** UDR_SIGNAL
+* Send a signal to the process at the other end of the socket,
+* indicating that it should expect to recieve a new message shortly.
+*/
+int udr_signal(udrs)
+UDR* udrs;
+{
+ if(send(udrs->sd, "I", 1, MSG_OOB) == -1)
+ { perror("ERROR, udr_signal(), send(...MSG_OOB)");
+ udr_errno = UDIErrorIPCInternal;
+ return -1; /* return error code */
+ }
+ return 0;
+}
+
+/***************************************************************** UDR_SENDNOW
+* used to flush the current character stream buffer to
+* the associated socket. */
+int udr_sendnow(udrs)
+UDR* udrs;
+{
+ int size = (UDIUInt32)(udrs->putend) - (UDIUInt32)(udrs->buff);
+ if(udrs->previous_op == 0)
+ { udr_errno = UDIErrorIPCInternal;
+ return -1;
+ }
+ udrs->putbytes = udrs->buff;
+ udrs->putend = udrs->buff;
+ if (write(udrs->sd, udrs->buff, size) == -1)
+ { perror("ERROR, udr_sendnow(), write() call: ");
+ udr_errno = UDIErrorIPCInternal;
+ return -1; /* return error code */
+ }
+ return 0;
+}
+
+/******************************************************************** UDR_WORK
+* Function to send or recieve data from the buffers supporting
+* socket communication. The buffer contains serialised objects
+* sent/recieved over a socket connection.
+*/
+int udr_work(udrs, object_p, size)
+UDR* udrs;
+void* object_p;
+int size;
+{
+ int cnt, remain;
+
+ if(udrs->udr_op != udrs->previous_op)
+ { if(udrs->previous_op == 0)
+ { udr_errno = UDIErrorIPCInternal;
+ return -1;
+ }
+ udrs->previous_op= udrs->udr_op;
+ udrs->putbytes = udrs->buff;
+ udrs->getbytes = udrs->buff;
+ }
+
+ if(udrs->udr_op == UDR_ENCODE)
+ { /* write data into character stream buffer */
+ if( (UDIUInt32)(udrs->putbytes) + size >
+ (UDIUInt32)(udrs->buff) + (UDIUInt32)(udrs->bufsize) )
+ { udr_errno = UDIErrorIPCInternal;
+ return -1;
+ }
+ memcpy(udrs->putbytes, (char*)object_p, size);
+ udrs->putbytes += size;
+ if(udrs->putbytes > udrs->putend) udrs->putend = udrs->putbytes;
+ }
+ else if(udrs->udr_op == UDR_DECODE)
+ {
+ if( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->getbytes) < size )
+ { /* need more data in character stream buffer */
+ remain = (UDIUInt32)(udrs->bufsize) -
+ ( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->buff) );
+ if( ((UDIUInt32)(udrs->bufsize) + (UDIUInt32)(udrs->buff)
+ - (UDIUInt32)(udrs->getbytes)) < size)
+ { udr_errno = UDIErrorIPCInternal;
+ return -1;
+ }
+ cnt = read(udrs->sd, (char*)udrs->putbytes, remain);
+ if(cnt == -1) perror("ERROR udr_work(), read() failure: ");
+ udrs->putbytes += cnt;
+ if( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->getbytes) < size )
+ { udr_errno = UDIErrorIPCInternal;
+ return -1; /* return error code */
+ }
+ } /* read data from character stream buffer */
+ memcpy((char*)object_p, udrs->getbytes, size);
+ udrs->getbytes += size;
+ }
+ else
+ { udr_errno = UDIErrorIPCInternal;
+ return -1;
+ }
+ return 0;
+}
+
+/************************************************************* UDR_UDIResource
+*/
+int udr_UDIResource(udrs, object_p)
+UDR* udrs;
+UDIResource* object_p;
+{
+ int retval;
+
+ retval = udr_CPUSpace(udrs, &object_p->Space);
+ retval = retval | udr_CPUOffset(udrs, &object_p->Offset);
+ return retval;
+}
+
+/**************************************************************** UDR_UDIRange
+*/
+int udr_UDIRange(udrs, object_p)
+UDR* udrs;
+UDIRange* object_p;
+{
+ int retval;
+
+ retval = udr_CPUOffset(udrs, &object_p->Low);
+ retval = retval | udr_CPUOffset(udrs, &object_p->High);
+ return retval;
+}
+
+/********************************************************** UDR_UDIMemoryRange
+*/
+int udr_UDIMemoryRange(udrs, object_p)
+UDR* udrs;
+UDIMemoryRange* object_p;
+{
+ int retval;
+
+ retval = udr_CPUSpace(udrs, &object_p->Space);
+ retval = retval | udr_CPUOffset(udrs, &object_p->Offset);
+ retval = retval | udr_CPUSizeT(udrs, &object_p->Size);
+ return retval;
+}
+
+/****************************************************************** UDR_string
+*/
+int udr_string(udrs, sp)
+UDR* udrs;
+char* sp;
+{
+ int len, retval;
+
+ if(udrs->udr_op == UDR_ENCODE)
+ {
+ if(sp)
+ { len = strlen(sp) + 1;
+ retval = udr_UDIInt32(udrs, &len);
+ retval = retval | udr_work(udrs, sp, len);
+ }
+ else /* deal with NULL pointer */
+ { len = 0;
+ retval = udr_UDIInt32(udrs, &len);
+ }
+ }
+ else if(udrs->udr_op == UDR_DECODE)
+ {
+ retval = udr_UDIInt32(udrs, &len);
+ if(len)
+ retval = retval | udr_work(udrs, sp, len);
+ else *sp = '\0'; /* terminate string */
+ }
+ else
+ { udr_errno = UDIErrorIPCInternal;
+ return -1;
+ }
+ return retval;
+}
+
+/******************************************************************* UDR_BYTES
+*/
+int udr_bytes(udrs, ptr, len)
+UDR* udrs;
+char* ptr;
+int len;
+{
+ return udr_work(udrs, ptr, len);
+}
+
+/********************************************************************* UDR_INT
+*/
+int udr_int(udrs, int_p)
+UDR* udrs;
+int* int_p;
+{
+ int ret_val;
+ UDIInt32 udr_obj; /* object of know size */
+
+ if(udrs->udr_op == UDR_ENCODE)
+ {
+ udr_obj = *int_p; /* copy into know object size */
+ return udr_UDIInt32(udrs, &udr_obj);
+ }
+ else if(udrs->udr_op == UDR_DECODE)
+ {
+ ret_val = udr_UDIInt32(udrs, &udr_obj); /* get object of known size */
+ *int_p = udr_obj;
+ return ret_val;
+ }
+ else
+ { udr_errno = UDIErrorIPCInternal;
+ return -1;
+ }
+}
+
+/****************************************************************** UDR_INLINE
+*/
+char* udr_inline(udrs, size)
+UDR* udrs;
+int size;
+{
+ if(udrs->udr_op != udrs->previous_op)
+ { if(udrs->previous_op == 0)
+ { udr_errno = UDIErrorIPCInternal;
+ return 0;
+ }
+ udrs->previous_op= udrs->udr_op;
+ udrs->putbytes = udrs->buff;
+ udrs->getbytes = udrs->buff;
+ }
+ if(udrs->udr_op == UDR_ENCODE)
+ {
+ if(udrs->putbytes + size > udrs->bufsize + udrs->buff)
+ return 0;
+ udrs->putbytes += size;
+ return udrs->putbytes - size;
+ }
+ else if(udrs->udr_op == UDR_DECODE)
+ {
+ if(udrs->getbytes + size > udrs->bufsize + udrs->buff)
+ return 0;
+ udrs->getbytes += size;
+ return udrs->getbytes - size;
+ }
+ else
+ { udr_errno = UDIErrorIPCInternal;
+ return 0;
+ }
+}
+
+/****************************************************************** UDR_GETPOS
+*/
+char* udr_getpos(udrs)
+UDR* udrs;
+{
+ if(udrs->udr_op == UDR_ENCODE)
+ {
+ return udrs->putbytes;
+ }
+ else if(udrs->udr_op == UDR_DECODE)
+ {
+ return udrs->getbytes;
+ }
+ else
+ { udr_errno = UDIErrorIPCInternal;
+ return 0;
+ }
+}
+
+/****************************************************************** UDR_SETPOS
+*/
+int udr_setpos(udrs, pos)
+UDR* udrs;
+char* pos;
+{
+ if( ((UDIUInt32)pos > (UDIUInt32)(udrs->buff) + (UDIUInt32)(udrs->bufsize))
+ || ((UDIUInt32)pos < (UDIUInt32)(udrs->buff) ) )
+ { udr_errno = UDIErrorIPCInternal;
+ return 0;
+ }
+ if(udrs->udr_op == UDR_ENCODE)
+ {
+ udrs->putbytes = pos;
+ return 1;
+ }
+ else if(udrs->udr_op == UDR_DECODE)
+ {
+ udrs->getbytes = pos;
+ return 1;
+ }
+ else
+ { udr_errno = UDIErrorIPCInternal;
+ return 0;
+ }
+}
+
+/***************************************************************** UDR_READNOW
+* Try and ensure "size" bytes are available in the
+* receive buffer character stream.
+*/
+int udr_readnow(udrs, size)
+UDR* udrs;
+int size;
+{
+ int cnt, remain;
+
+ if(udrs->udr_op == UDR_ENCODE)
+ {
+ udr_errno = UDIErrorIPCInternal;
+ return -1;
+ }
+ else if(udrs->udr_op == UDR_DECODE)
+ {
+ if( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->getbytes) < size )
+ { /* need more data in character stream buffer */
+ remain = (UDIUInt32)(udrs->bufsize) -
+ ( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->buff) );
+ cnt = read(udrs->sd, (char*)udrs->putbytes, remain);
+ if(cnt == -1) perror("ERROR udr_work(), read() failure: ");
+ udrs->putbytes += cnt;
+ if( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->getbytes) < size )
+ { fprintf(stderr,"ERROR, udr_readnow() too few bytes in stream\n");
+ return -1; /* return error code */
+ }
+ }
+ }
+ else
+ { udr_errno = UDIErrorIPCInternal;
+ return -1;
+ }
+ return 0;
+}
+
+/******************************************************************* UDR_ALIGN
+*/
+int udr_align(udrs, size)
+UDR* udrs;
+int size;
+{
+ char* align;
+ int offset;
+
+ align = udr_getpos(udrs);
+ offset = size - ((int)align & (size -1));
+ offset = offset & (size -1);
+ if(offset) udr_setpos(udrs, align + offset);
+}
+#endif /* __GO32__ */
diff --git a/gdb/29k-share/udi_soc b/gdb/29k-share/udi_soc
new file mode 100644
index 00000000000..343317f255f
--- /dev/null
+++ b/gdb/29k-share/udi_soc
@@ -0,0 +1,9 @@
+# @(#)udi_soc 2.1 Daniel Mann
+# NOTE: the Session string must not start whith white-space characters.
+# Format of string is:
+# <session> <domain> <soc_name|host_name> <tip_exe> <pass to UDIconnect>
+soc2cayman AF_INET cayman /bin/udi_tip ...
+soc2tip AF_UNIX astring tip.exe ...
+cuba AF_UNIX soc_name ../bin.68020/udi_tip stuff to pass
+cayman AF_INET cayman this_entry_not_matter stuff to pass
+iss AF_UNIX * sun4/isstip -r osboot
diff --git a/gdb/CONTRIBUTE b/gdb/CONTRIBUTE
new file mode 100644
index 00000000000..96c943cff94
--- /dev/null
+++ b/gdb/CONTRIBUTE
@@ -0,0 +1,143 @@
+
+ Contributing to GDB
+
+GDB is a collaborative project and one which wants to encourage new
+development. You may wish to fix GDB bugs, improve testing, port GDB
+to a new platform, update documentation, add new GDB features, and the
+like. To help with this, there is a lot of documentation
+available.. In addition to the user guide and internals manual
+included in the GDB distribution, the GDB web pages also contain much
+information.
+
+You may also want to submit your change so that can be considered for
+conclusion in a future version of GDB (see below). Regardless, we
+encourage you to distribute the change yourself.
+
+If you don't feel up to hacking GDB, there are still plenty of ways to
+help! You can answer questions on the mailing lists, write
+documentation, find bugs, create a GDB related website (contribute to
+the official GDB web site), or create a GDB related software
+package. We welcome all of the above and feel free to ask on the GDB
+mailing lists if you are looking for feedback or for people to review
+a work in progress.
+
+Ref: http://www.gnu.org/software/gdb/
+
+Finally, there are certain legal requirements and style issues which
+all contributors need to be aware of.
+
+o Coding Standards
+
+ All contributions must conform to the GNU Coding Standard.
+ Submissions which do not conform to the standards will be
+ returned with a request to reformat the changes.
+
+ GDB has certain additional coding requirements. Those
+ requirements are explained in the GDB internals documentation
+ in the gdb/doc directory.
+
+ Ref: http://www.gnu.org/prep/standards_toc.html
+
+
+o Copyright Assignment
+
+ Before we can accept code contributions from you, we need a
+ copyright assignment form filled out and filed with the FSF.
+
+ See some documentation by the FSF for details and contact us
+ (either via the GDB mailing list or the GDB maintainer that is
+ taking care of your contributions) to obtain the relevant
+ forms.
+
+ Small changes can be accepted without a copyright assignment form on file.
+
+ Ref: http://www.gnu.org/prep/maintain.html#SEC6
+
+
+o Submitting Patches
+
+ Every patch must have several pieces of information before we
+ can properly evaluate it.
+
+ A description of the bug and how your patch fixes this
+ bug. A reference to a testsuite failure is very helpful. For
+ new features a description of the feature and your
+ implementation.
+
+ A ChangeLog entry as plaintext (separate from the patch); see
+ the various ChangeLog files for format and content. Note that,
+ unlike some other projects, we do require ChangeLogs also for
+ documentation (i.e., .texi files).
+
+ The patch itself. If you are accessing the CVS repository use
+ "cvs update; cvs diff -cp"; else, use "diff -cp OLD NEW" or
+ "diff -up OLD NEW". If your version of diff does not support
+ these options, then get the latest version of GNU diff.
+
+ We accept patches as plain text (preferred for the compilers
+ themselves), MIME attachments (preferred for the web pages),
+ or as uuencoded gzipped text.
+
+ When you have all these pieces, bundle them up in a mail
+ message and send it to gdb-patches@sources.redhat.com. All
+ patches and related discussion should be sent to the
+ gdb-patches mailinglist. For further information on the GDB
+ CVS repository, see the Anonymous read-only CVS access and
+ Read-write CVS access page.
+
+--
+
+Supplemental information for GDB:
+
+o Please try to run the relevant testsuite before and after
+ committing a patch
+
+ If the contributor doesn't do it then the maintainer will. A
+ contributor might include before/after test results in their
+ contribution.
+
+
+o For bug fixes, please try to include a way of
+ demonstrating that the patch actually fixes something.
+
+ The best way of doing this is to ensure that the
+ testsuite contains one or more test cases that
+ fail without the fix but pass with the fix.
+
+ People are encouraged to submit patches that extend
+ the testsuite.
+
+
+o Please read your patch before submitting it.
+
+ A patch containing several unrelated changes or
+ arbitrary reformats will be returned with a request
+ to re-formatting / split it.
+
+
+o If ``gdb/configure.in'' is modified then you don't
+ need to include patches to the regenerated file
+ ``configure''.
+
+ The maintainer will re-generate those files
+ using autoconf (2.13 as of 2000-02-29).
+
+
+o If ``gdb/gdbarch.sh'' is modified, you don't
+ need to include patches to the generated files
+ ``gdbarch.h'' and ``gdbarch.c''.
+
+ See ``gdb/configure.in'' above.
+
+
+o When submitting a patch that fixes a bug
+ in GDB's bug database a brief reference
+ to the bug can be included in the ChangeLog
+ vis
+
+ * CONTRIBUTE: Mention PR convention.
+ Fix PR gdb/4705.
+
+ The text ``PR gdb/4705'' should also be included
+ in the CVS commit message. That causes the
+ patch to automatically be archived with the PR.
diff --git a/gdb/COPYING b/gdb/COPYING
new file mode 100644
index 00000000000..60549be514a
--- /dev/null
+++ b/gdb/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/gdb/ChangeLog-1990 b/gdb/ChangeLog-1990
new file mode 100644
index 00000000000..25cf860c0c0
--- /dev/null
+++ b/gdb/ChangeLog-1990
@@ -0,0 +1,3155 @@
+Fri Dec 28 00:13:42 1990 John Gilmore (gnu at cygint)
+
+ Further stabilization for the Intel 960.
+
+ * Makefile.dist: Parameterize the location of the "include"
+ and "bfd" directories, as well as "getopt". Add symfile.c.
+ Link in both dbxread and coffread. Fix up "make depend" to
+ rewack the locations of include, bfd, and getopt in its output.
+
+ * README: Document moving include files, improve some of
+ the other doc.
+
+ * coffread.c: Move common code out to symfile.c. Change
+ symbol_file_command style interface to use new *_symfile_init
+ and *_symfile_read interface under BFD. Use BFD internal
+ info to locate line table, symbols, etc.
+
+ * core.c (core_fetch_registers): Rename to get_core_registers
+ to avoid confusion with fetch_core_registers.
+ (register_addr): Move to coredep.c, which is already machine
+ dependent. This leaves core.c pretty clean of dependencies.
+
+ * coredep.c (register_addr): Accept this routine from core.c.
+
+ * dbxread.c: Move common code (with coffread.c, etc) into new
+ symfile.c. Each psymtab now contains a pointer to the
+ format-dependent function that knows how to read it in. Make
+ some things static.
+ (dbx_psymtab_to_symtab): Renamed from psymtab_to_symtab_2.
+ (process_one_symbol): Add code to complain about a "compiler bug
+ we muzzle here", if we actually see it.
+
+ * eval.c (evaluate_subexp): Insert missing "break" statements
+ in code that determines whether a variable is an lvalue in
+ memory, register, or whatever. I detected this via a compiler
+ bug in which it *almost* mashed out the whole switch statement.
+
+ * gdb-int.texinfo: Add minor sections on configuring gdb for
+ release, and about the README file.
+
+ * infcmd.c (registers_info): Fix formatting somewhat. Still
+ not as pretty as before, but it handles byte swapping.
+
+ * remote-nindy.c: If data cache routines are interrupted while
+ waiting for the remote end, be sure that any uninitialized cache
+ blocks are on the free list, not on the valid list!
+
+ * symfile.h: Flesh out this header file with all the various
+ routines and variables that have been merged in from dbxread.c
+ coffread.c, and symtab.c to symfile.c.
+
+ * symfile.c: New file, containing code common to dbxread.c,
+ coffread.c, and some code from symtab.c. All generic code for
+ reading symbol files should be in here now.
+ (unrecord_misc_function): Remove unused function.
+
+ * symtab.h: Remove file-reading things to symfile.h.
+
+ * symtab.c: Remove file-reading things to symfile.c.
+
+ * tm-i960.h: Fix FRAME_CHAIN types; define PRINT_RANDOM_SIGNAL
+ to decode i960 fault types.
+
+ * target.h, remote.c, remote-eb.c, remote-vx.c, remote-nindy.c,
+ target.c: Change type of the "resume" function from int to void,
+ since its result was never used.
+
+Sat Dec 22 02:51:40 1990 John Gilmore (gnu at cygint)
+
+ * main.c: Replace "stupid" with "caution"; you now "set caution
+ on or off".
+
+ * printcmd.c (print_scalar_formatted): Fix typo in 'g' format
+
+ * infcmd.c (do_registers_info): Call val_print to deal with the
+ byte order of the registers being printed. FIXME, this makes
+ the formatting of the output uglier.
+
+ * infcmd.c (wait_for_inferior): If PRINT_RANDOM_SIGNAL is
+ defined, call it for signals the debugger doesn't itself use.
+ The i960 uses this for more detailed fault information.
+
+ * remote.c (remote_open): If arg is null, print help rather than
+ dumping core.
+
+ * sparc-xdep.c (register_valid): Avoid declaring size, since
+ various modules will think of various sizes depending on the
+ architecture of their tm-file. FIXME, we need protection against
+ actually entering one of those modules, which would clobber
+ storage if not for the target architecture compiled into gdb.
+
+ * stack.c (up_command, down_command): Always print the frame
+ you arrive at.
+ (up_silently_command, down_silently_command): New commands
+ for use in scripts.
+
+ * i960-pinsn.c (reg), i960-tdep.c: Lint.
+
+ * i960-tdep.c (i960_frame_chain_valid): Lookup_symbol now takes
+ more parameters than it used to.
+
+ * findvar.c (registers): Increase slop to 256 bytes, which should
+ protect us against even most RISC machines with large register
+ sets.
+ (locate_var_value): Move declaration inside related ifdef.
+
+ * remote-nindy.c (): Use TIOCSETN rather than TIOCSETP
+ throughout, to avoid throwing away buffered input from the board.
+ (nindy_wait): Supply_register takes addr_of_value, not value.
+ (i960_print_fault): Renamed from i80960_fault.
+ (nindy_fetch_registers): Avoid have_regs stuff, just get them.
+ (nindy_store_registers): Avoid regs_changed stuff, just stuff
+ them.
+ (nindy_create_inferior): Don't bother to write PC_REGNUM since
+ we can set the PC in the call to proceed(). Unpush nindy_ops
+ before pushing it on top, to avoid message to user. Eliminate
+ commentary from Unix machines that just misleads here.
+ (reset_command): Fix error message to suggest target command.
+
+Wed Dec 19 11:03:56 1990 John Gilmore (gnu at cygint)
+
+ Release 3.92.5 as frozen.
+
+ Stabilize the merged release...with help from lint, Saber C,
+ gcc -W, etc.
+
+ Everywhere: Add include files needed to declare return types
+ of functions called.
+
+ * gdb.texinfo: Roland Pesch is documenting gdb, glory be!
+
+ * breakpoint.h: Add undeclared breakpoint functions, and some
+ functions for display handling since I couldn't think of a better
+ .h to put them in.
+
+ * breakpoint.c (insert_breakpoints): Make code for disabling
+ shared library bkpts more likely to work. It's used when we
+ rerun a program and stop before the shared library has been
+ mapped in.
+ (breakpoint_cond_eval, bpstat_stop_status): Pass arg as int,
+ cast from pointer, so it squeezes through catch_errors.
+ (bpstat_stop_status): Fix logic broken some time ago. We now
+ always create a bpstat if the stop address matches a breakpoint,
+ even if we don't stop there -- just like the old code used to do
+ before I got my fingers into it (sigh).
+ (breakpoint_1): Print "ignore count" after "stop only if"
+ condition, since that's how it actually works.
+ (mention): Handle watchpoints as well as breakpoints.
+ (watch_command): use set_raw_breakpoint and mention to do most
+ of the work (and initialize all the fields!). Only pass one
+ arg to parse_c_expression, since that's all it takes.
+
+ * command.c (not_just_help_class_command): Rename arg to args
+ since we ignore "unused argument" warnings on vars named "args".
+ inflow.c (child_terminal_info): ditto.
+ infptrace.c (kill_inferior): ditto
+ main.c (catch_errors, version_info, quit_command, pwd_command,
+ source_command, dump_me_command, editing_info,
+ set_history_size_command, set_history, show_history,
+ set_verbose): ditto
+ stack.c (locals_info): ditto
+ target.c (target_files_info): ditto
+ valprint.c (set_input_radix, set_output_radix): ditto
+
+ * core.c: Remove old variables for handling core and exec file
+ sections (data_start, data_end, stack_start, stack_end,
+ reg_stack_start, reg_stack_end, reg_stack_offset, text_start,
+ text_end, exec_data_start, exec_data_end, text_offset,
+ exec_data_offset, data_offset, stack_offset). They're
+ superseded the more general build_section_table and
+ xfer_memory.
+ (get_exec_file): Mention the `file' command.
+ (read_memory_check): Rename to memory_error, and only call it
+ in the case of an actual error.
+ (read_memory, write_memory): call memory_error.
+ (core_fetch_registers): Register section name is ".reg".
+
+ coredep.c: Remove a bunch of crud now that all this file does
+ is pull the registers out of a core file.
+ (fetch_core_registers): Rewrite to actually work, I hope.
+
+ dbxread.c: Use a.out.gnu.h, not system a.out, now.
+ Replace index() with strchr(). Remove all the pre-BFD macro
+ definitions for accessing the symbol file.
+ (struct dbx_symfile_info): Encapsulate the information that
+ dbx_symfile_init needs to pass to dbx_symfile_read in this
+ struct.
+
+ (dbx_new_init, dbx_symfile_init, dbx_symfile_read,
+ dbx_symfile_discard): Rearrange symbol file reading to divide
+ the format-specific part from the format-independent part,
+ leaving the format-independent part such as file name expansion
+ and opening in symtab.c. This replaces
+ partial_symbol_file_open and partial_symbol_file_read.
+ Symbol_file_read, add_file, add_file_target_command,
+ add_file_addr_command move to symtab.c. Pass an explicit
+ "mainline" flag for when reading the main symbol table, rather
+ than relying on the offset address to be zero or nonzero.
+
+ (dbx_symfile_read): Don't allow void *'s to be printed as
+ typedefs.
+ (SWAP_SYMBOL): Use bfd routines to byte-swap the symbols.
+ (ADD_PSYMBOL_TO_LIST): Make the "function call rather than
+ macro" debug version really work.
+ (read_dbx_symtab): Remove unref'd parameter inclink.
+ Avoid swapping N_SLINE symbols, for speed.
+ Merge N_TEXT!N_EXT case with the other external symbol
+ definitions' case. Add comments.
+ (start_psymtab): Allocate the symfile name in the psymtab on
+ the psymbol_obstack, rather than using the caller's storage.
+ (end_psymtab): Only allocate a dependencies list if there are
+ more than zero.
+ (psymtab_to_symtab_2): Use BFD when reopening file to read
+ its symbols for real.
+ (read_struct_type): Add FIXME comments where it needs work
+ for C++ bogosity.
+ (read_huge_number): Add FIXME about overflows.
+ (read_range_type): Add FIXME about comparing a long to 1<<32.
+
+ * coffread.c: Minor changes to move things closer to the new
+ regime with symtab.c and dbxread.c Major work is still needed
+ here.
+
+ * exec.c (exec_file_command): Remove old variables (see core.c
+ above).
+ (xfer_memory): If memory transfer is right at the end of a
+ section, don't lose.
+
+ * findvar.c (get_saved_register): If value is in a real
+ register, LVAL is lval_register, not lval_memory.
+
+ frame.h: Declare print_sel_frame and record_selected_frame.
+
+ gdb-int.texinfo: New file, for GDB internals documentation.
+ Very simple, unformatted doc of cleanups is there for now.
+
+ gdbcore.h: Remove obsolete variables that described a.out
+ section addresses and offsets. (See core.c above.)
+ Declare fetch_core_registers and registers_fetched.
+
+ getopt.c: Declare char *alloca(); even on SPARC.
+
+ infcmd.c (run_command): Call target_kill rather than
+ kill_inferior.
+ (step_command, next_command, stepi_command, nexti_command):
+ Declare from_tty parameter even though we don't use it.
+ (run_stack_dummy): argument BUFFER is a char array, not
+ a pointer to REGISTER_TYPE.
+ (finish_command): using_struct_return needed a value *,
+ not a struct symbol *.
+
+ * infptrace.c (child_xfer_memory): To avoid dependency on
+ where sections are in memory, try PT_WRITE_D and if that fails,
+ try PT_WRITE_I. Most Unixes don't care which you use.
+
+ * infrun.c (step_resume_break_shadow): Change to array to
+ match other breakpoint shadow storage.
+ (clear_proceed_status): Pass address of bpstat to
+ bpstat_clear, not the bpstat itself.
+ (child_create_inferior): FIXME comment about if the child
+ exits.
+ (start_inferior): Remove old function.
+ (child_open): Use target_kill rather than kill_inferior.
+ (wait_for_inferior): Ditto.
+ (insert_step_breakpoint, remote_step_breakpoint): Use
+ new step_resume_break_shadow.
+
+ * inftarg.c (child_wait): If all child processes die,
+ pretend that the one being waited for exited with signal 42.
+
+ * main.c (command_line_input): When scanning for comments,
+ don't coredump on unclosed quotes.
+ (quit_command): Use target_kill rther than kill_inferior.
+ (_initialize_main): Rename class_user from "user" to
+ "user-defined".
+
+ * printcmd.c (print_command_1): Initialize "fmt" if no format
+ is specified by the user.
+ (print_frame_args): Only add to args_printed if we are
+ actually fetching args from the stack (avoiding undefined
+ arg_size).
+ (_initialize_printcmd): Remove bogus \{ from string.
+
+ * remote-eb.c (eb_open): Avoid coredump on no argument.
+
+ * remote-nindy.c: Bring out of Intel environment into new
+ target environment. Remove all conditional compilation on
+ I80960. Massive hacking throughout.
+ (nindy_xfer_inferior_memory): New routine stolen from
+ infptrace.c.
+ (nindy_create_inferior): New routine pieced together, probably
+ not quite working yet.
+ (nindy_ops): New target_ops struct for nindy.
+
+ * remote-vx.c: Use write_memory rather than target_write_memory
+ to get error checking.
+ (vx_add_file_command, vx_open): Use symbol_file_add rather than
+ add_file.
+ (vx_create_inferior): Use target_terminal_ours...
+
+ * signame.c (_initialize_signame): Always initialize, since
+ we need the table for things other than psignal.
+
+ * solib.c (solib_add): Use symbol_file_add, not add_file.
+ (solib_address): Return boolean result rather than struct
+ pointer which nobody else knows the type of.
+
+ * sparc-tdep.c, valops.c: Use write_memory rather than
+ target_write_memory, to get error checking.
+
+ * stack.c (locals_info, catch_info, args_info,
+ get_selected_block, frame_command, up_command): Use
+ target_has_stack, rather than have_inferior_p or
+ have_core_file_p.
+
+ * sun3-xdep.c (fetch_core_registers): Rewrite for new BFD regime.
+
+ * symfile.h: New file, defining the interface between the
+ generic and object-file-specific symbol reading code.
+
+ * symtab.c: Move generic symbol-reading interface to symtab.c,
+ from dbxread.c, coffread.c, mipsread.c, etc. Add symtab_fns
+ table to map BFD targets to symbol-reading modules in GDB.
+ Change index to strchr.
+ (lookup_struct_elt_type): Use error() rather than hand-made
+ simulations thereof.
+ (lookup_partial_symbol): Speedup slightly when length == 0.
+ (symbol_file_add): New function.
+ (symbol_file_command): Call it.
+ (symfile_open, symfile_init): New function.
+ (add_file_target_command, add_file_addr_command): moved from
+ dbxread.c.
+
+ * target.c (target_command): use target_kill.
+
+ * target.h (target_files_info): Don't declare, never called
+ from outside.
+
+ * tm-sun2.h, tm-sun3.h (STACK_END_ADDR): Use system include
+ files to determine stack end address.
+
+ * valarith.c (value_x_binop, value_x_unop): Change error message
+ to be more useful. Pass proper argument to value_struct_elt.
+
+ * valops.c (value_assign): FIXME comment that long long
+ bitfields will break here.
+
+ * Makefile.dist: Add symfile.h, remote-nindy.c, remote-eb.c.
+ Update `make saber_gdb' to work better.
+
+ * TODO: A woman's work is never done.
+
+ * cplus-dem.c, environ.c, inferior.h, infrun.c, inftarg.c,
+ main.c, obstack.c, printcmd.c, remote-eb.c, remote-nindy.c,
+ remote-vx.c, remote.c, solib.c, source.c, sparc-pinsn.c,
+ sparc-tdep.c, sparc-xdep.c, symmisc.c, symtab.c, symtab.h
+ target.c, terminal.h, tm-sparc.h, tm-sunos.h, utils.c,
+ valops.c, valprint.c, exec.c: Lint.
+
+
+Wed Dec 12 23:44:15 1990 John Gilmore (gnu at cygnus.com)
+
+ Continuing Intel 960 port merge of GDB.
+
+ * Makefile.dist: Merge i960 "nindy-share" files. Rename
+ malloc.h to gmalloc.h to avoid name conflicts in /usr/include.
+ Don't ship gdb.dvi in tar file. Link gdb with init.o, not init.c.
+ Wack over "make depend" so it handles files in subdirectories
+ vx-share, nindy-share, bfd, and in the current directory.
+
+ * blockframe.c (get_prev_frame_info): Remove fatal error
+ if stack not defined.
+
+ * core.c (core_open, core_detach): New functions that handle
+ the old "core-file" command as "target core" and "detach" instead.
+ (core_file_command): Call them.
+ (core_xfer_memory): Use common routine xfer_memory.
+
+ * dbxread.c: Include a.out.gnu.h, not system a.out.h.
+ dbxread now uses bfd for everything but symbol reading itself.
+ BFD internals are used to drag out the relevant file offsets.
+ (partial_symbol_file_open): Change args all around for BFD.
+
+ * symtab.c: Rename "value" to "val" everywhere, so we can
+ #include "value.h".
+ (symbol_file_command): New command, moved from dbxread.c
+ and coffread.c. It uses BFD to read the file, then vectors
+ based on its type, to dbx or coff symbol readers.
+ * symtab.h: Extern a few vars for symbol_file_command.
+
+ * target.h: Breakpoint takes a char * save area, not a char **.
+
+ * valprint.c (val_print): When unpacking bitfields, offset
+ the address in gdb of the value, if it is declared with a shorter
+ type. Remove the last "runtime kludge test" of host byte order.
+
+ * utils.c: Remove old my_bfd_read routine.
+
+ * stack.c (frame_info): Use target_has_stack. Print program counter
+ register's actual name rather than "pc", since it's called the
+ "ip" (instruction pointer) on the i960 (sigh).
+
+ * target.c (target_command): Add command for selecting a target
+ type and calling its open routine. This is used for initiating
+ communication with a particular target, in a generic way.
+
+ * tm-i960.h: Update for modern gdb. Remove semicolons from
+ various macros. Handle reading struct return convention, and
+ error-out attempts to return structs with the "return" command.
+ Be sure gdb doesn't think we know how to call functions in the
+ inferior.
+
+ * i960-tdep.c: Rename FRAME_CHAIN_VALID and FRAME_FIND_SAVED_REGS
+ to i960_xxx in lower case.
+ (arg_address): Circumvent errors due to LOC_ARG_BLOCK
+ not being defined yet.
+
+ * remote.c (remote_open): Call start_remote to initialize
+ wait_for_inferior during open.
+ (remote_xfer_inferior_memory): Return length written rather
+ than errno value.
+
+ * remote-vx.c (target_command -> vx_open): Use new generic
+ target command.
+ * remote-eb.c, inftarg.c, exec.c: ditto.
+
+ * infrun.c: Fix comments.
+ (attach_program -> child_open): Use new generic target command.
+ (wait_for_inferior): Clear saved register values before target_wait,
+ so target_wait can set some of them if convenient.
+
+ * infptrace.c (fetch_inferior_registers, store_inferior_registers):
+ Return success indicator, not void.
+ (child_xfer_memory): Avoid fetching initial word if we'll
+ overwrite it anyway.
+
+ * infcmd.c (attach_command): Use new generic target open routine.
+ (_initialize_infcmd): Update doc on attach and detach commands.
+ (do_registers_info): Merge in a byte-order problem as a FIXME
+ comment.
+
+ * findvar.c (find_saved_register): Avoid problem in current frame.
+ (read_relative_register): Ditto.
+ (write_register): Convert byte order on the way out.
+
+ * exec.c (file_command): Add.
+ (add_to_section_table, exec_command): Use new bfd_map_over_sections.
+ (xfer_memory): Common function between core_xfer_memory and
+ exec_xfer_memory.
+ (exec_xfer_memory): Use it.
+
+ * pn-opcode.h: Document that a "PN" is a Gould PowerNode.
+
+ * breakpoint.c, breakpoint.h, symtab.h, value.h, frame.h, utils.c,
+ valops.c, stack.c, target.c, sparc-xdep.c, source.c, printcmd.c,
+ infcmd.c, i960-pinsn.c, eval.c, defs.h: lint and gcc -Wall.
+
+Sun Dec 2 16:45:06 1990 John Gilmore (gnu at cygnus.com)
+
+ Merge Intel 960 port of gdb, continuing...
+
+ * dbxread.c (partial_symbol_file_open, partial_symbol_file_read,
+ symbol_file_command): Pass from_tty arg to hush 'em up.
+
+ * coffread.c (symbol_file_command): Avoid output if from_tty != 1.
+ Add magic numbers for 960 COFF format.
+
+Fri Nov 30 09:18:20 1990 John Gilmore (gnu at cygnus.com)
+
+ Merge Intel 960 port of gdb, from Intel "1.2" release.
+
+ CHANGE_LOG entries from their port, which was based on
+ gdb+-2.8.0:
+
+ Thu Sep 6 11:02:22 PDT 1990
+ Remove temp file if download is interrupted.
+
+ Wed Aug 1 09:08:33 PDT 1990
+ Now uses binary protocol to talk to NINDY.
+ Old hex protocol (NINDY 2.13 and older) supported with -O switch.
+ Times out after 5 seconds when trying to talk to NINDY.
+
+ Tue May 29 12:54:49 PDT 1990
+ Added variable baud rate (-b switch).
+ Source code reorganization.
+
+ Thu Apr 26 11:09:55 PDT 1990
+ More cleanup of batch mode; specifically, execute "-s", "-e", and
+ "-se" switches as soon as they are encountered on the invocation line.
+
+ Fri Apr 20 13:47:15 PDT 1990
+ Add -brk switch.
+
+ Thu Apr 19 09:54:28 PDT 1990
+ Add 'reset' command.
+
+ Wed Apr 18 09:48:07 PDT 1990
+ After opening remote tty, wait for 1 second to go by without input
+ from it before trying to talk to NINDY (fixes problems with the
+ Heurikon HK80/V960E).
+
+ Mon Apr 4 16:33:05 PDT 1990
+ Some output was not being suppressed in 'batch' mode.
+
+ Thu Mar 22 15:31:11 PST 1990
+ Ask user if old symbol table should be deleted when new file is
+ downloaded.
+
+ Allow user to run a program downloaded before gdb960 was brought up.
+
+ Correct "exec-file" help message for i80960 context.
+
+ Correct bug in calculating user space address: could occasionally
+ corrupt user program.
+
+ Make sure to zero low-order bits in rip's because of bug in 960CA
+ A-step part: could cause operation faults when "next"ing across
+ a function call.
+
+ Correct bug that made it impossible to get source line numbers for
+ code loaded at addresses higher than 0x7fffffff.
+
+ Wed Jan 10 12:43:22 PST 1990
+ Open remote tty for exclusive use.
+
+ Fri Jan 5 12:14:42 PST 1990
+ Correct disassembly (CA manual was right after all):
+ opcode for sysctl is 0x659
+
+ Mon Oct 23 12:03:04 PDT 1989
+ Use G960BASE and G960BIN environment variables to find 'sx' utility.
+
+ Mon Oct 16 14:15:09 PDT 1989
+ "sfr0"-"sfr31" should have been named "sf0"-"sf31"
+
+ Mon Oct 2 15:56:31 PDT 1989
+
+ Added 960CA disassembly support.
+
+ To simplify maintenance:
+ - eliminated use of symblic links on pinsn.c: use i960-pinsn.c
+ directly instead.
+ - eliminated opcode.h: incorporates tables into i960-pinsn.c
+ - moved 960-specific routines from i960-pinsn.c to i960-md.c
+ - made disassembly interface identical to that in gdmp960.
+
+
+
+Wed Nov 28 21:32:48 1990 John Gilmore (gnu at cygint)
+
+ * target.h: Allow targets to stack. Add target_has_memory,
+ _registers, etc. Restructure memory access and "info files"
+ to walk the target stack.
+ * exec.c, core.c, inftarg.c, remote.c, remote-vx.c, remote-eb.c,
+ target.c: Change tables to match target.h.
+ * inflow.c (child_mourn_inferior): pop child_ops.
+ (generic_mourn_inferior): Use new has_stack flag.
+ * infptrace.c (child_xfer_memory): New memory regime.
+ * inftarg.c (child_files_info): New "info files" regime.
+ * remote-eb.c: New memory regime, new info files.
+ * remote-vx.c: New memory regime, new info files. Now use
+ separate targets for VxWorks attachment to machine, and
+ actually running a process under VxWorks, since one has
+ stack & execution & regs and the other doesn't.
+ * remote.c: New memory regime, new info files.
+ * sparc-xdep.c (fetch_core-registers): New memory regime.
+ * target.c: New routines and support for stacked targets,
+ new memory regime, new info files regime.
+
+
+ Generalize section handling for an arbitrary number of sections,
+ including use of the new BFD (binary file) library.
+ * gdbcore.h: Add struct section_table.
+ * exec.c (build_section_table): Iterate all sections and
+ record what gdb needs to know about them.
+ (exec_command): Use it.
+ (exec_xfer_memory): Use the table.
+ (exec_files_info): Print the table.
+ * core.c (core_file_command, core_xfer_memory, core_files_info):
+ Likewise.
+ * source.c (find_source_lines): Use bfd_get_mtime.
+ * dbxread.c: Quick changes to make it compile with new BFD.
+ * utils.c (error): Avoid using bfd_error in generic routines.
+
+ * core.c (core_fetch_registers): Get from the ".regs" section of
+ the BFD core file.
+ * sparc-xdep.c (fetch_core_registers): Use the .regs info.
+
+ * inferior.h (attach_flag): Export.
+ * infcmd.c (run_command): use new target_create_inferior.
+ * infrun.c (child_create_inferior): Don't return result.
+ * Makefile.dist (VERSION): 3.91.4.
+
+Fri Nov 23 28:15:38 1990 John Gilmore (gnu at cygint)
+
+ * breakpoint.c (bpstat_num): Handle breakpoints which have
+ since been deleted, such as temporary breakpoints.
+ infcmd.c (program_info): ditto.
+
+ * core.c (core_file_command): Display the frame where the core
+ dump occurred.
+
+ * main.c: lint.
+
+ * remote-vx.c (target_command): Merge in target command from
+ targ-vx.c. A few other cleanups.
+
+ * TODO, Projects: Lots more stuff to do...
+
+Fri Nov 23 18:15:38 1990 John Gilmore (gnu at cygint)
+
+ Massive changes to wall off the remote-debugging interface
+ behind a function vector. The port to handle VxWorks targets
+ is also part of this.
+
+ All files: Replace references to renamed functions,
+ remove references to remote_debugging, remove references to
+ have_include_file, have_core_file in favor of target_has_stack,
+ target_has_memory, etc.
+
+ * Modularize the breakpoint interface.
+ breakpoint.h (BREAKPOINT_MAX): New define sets max length of
+ a breakpoint instruction.
+ breakpoint.c: struct breakpoint's shadow_contents now sized as
+ BREAKPOINT_MAX.
+ (insert_breakpoints): Vector to target to install breakpoints.
+ (remove_breakpoints): Vector to target here too.
+ Remove REMOTE_SA_SPARC kludges and other remote_debugging.
+ sparc-tdep.c (single_step): Use new breakpoint interface for
+ the single-step breakpoints.
+ mem-break.c (memory_insert_breakpoint, memory_remove_breakpoint):
+ New file, contains routines to insert and remove breakpoints by
+ reading out the old contents and later replacing them. This is
+ how ptrace breakpoints work, and many remote systems as well.
+
+ * tm-vxworks68.h: New config file, overrides a few things for
+ Wind River's preferences.
+
+ * target.h: New file, for transfer vector used to talk to the
+ inferior (child, attached, core, exec, remote, etc). All accesses
+ to the thing being debugged should come through these vectors.
+ target.c: New file, routines to handle transfer vector.
+ (various files): Add transfer vectors XXX_ops for the various
+ targets and pseudo-targets (core files, etc) we support.
+
+ * breakpoint.c (bpstat_stop_status): Further explorations of
+ watchpoints and why things don't work all the time.
+ (bpstat_alloc): New fn to allocate a bpstat and chain it.
+
+ * config.gdb: Only add "source ${srcdir}/.gdbinit" to
+ the local gdbinit if it doesn't already have it.
+
+ * core.c (core_ops): add and install.
+ Allow core debugging without exec file.
+
+ * dbxread.c (free_and_init_header_files): Merge two fns.
+ (end_symtab): Free named symbol table when a new version comes in.
+ (read_dbx_symtab): Relocate all kinds of symbols with base
+ address. First step toward handling different text, data, bss
+ reloc.
+ (add_file_addr_command): Renamed add_file_command.
+ (add_file_command): Vector to remote handler.
+ Add "load" as an alias for "add-file" command.
+
+ * defs.h: Allow "volatile" to be used in non-ANSI; use it for
+ non-returning functions.
+
+ * exec.c: Add exec_ops, and push it as a target when an exec
+ file is specified.
+
+ * infcmd.c (run_command): Pass executable file name and arg list
+ separately when starting an inferior. Permit "run" when no exec
+ file is specified, for VxWorks.
+ (detach_command): Move to child_detach in inftarg.c.
+
+ * inftarg.c: New file. Unix-child-specific routines, and the
+ child_ops structure.
+
+ * inferior.h (registers): Export "registers" as the way for
+ target dependent register handlers to find gdb's local copy of
+ the registers. Rename "stop_after_attach" to "stop_soon_quietly"
+ since it is now used by places that want wait_for_inferior to
+ handle the grunge but want to see every trap from the inferior.
+
+ * inflow.c (create_inferior): Pull out, and merge into infrun.c.
+ Eliminate remote_debugging hooks in terminal handling.
+
+ * infrun.c: Replace start_inferior with child_create_inferior.
+ Move all the hair of Unix shells and ptrace idiosyncracies into
+ child_create_inferior, so remote handlers don't have to deal.
+ Remove running_in_shell. Rename stop_after_attach to
+ stop_soon_quietly, and use it in a few other places where we want
+ to just call wait_for_inferior and get control back on the first
+ trap. trap_expected now never takes a value > 1.
+ (init_wait_for_inferior): Initialize static vars when a new
+ process is created.
+
+ main.c (gdbinit): Add new hook for .gdbinit file name, let
+ it be overridden by config files as GDBINIT_FILENAME.
+ (DEFAULT_PROMPT): Add new hook for overriding (gdb) prompt.
+ Both of these are used for VxWorks gdb.
+
+ mcheck.c: rename include file "gmalloc.c" to avoid problems
+ with system include file "malloc.c".
+
+ param-no-tm.h: New include file, same as param.h but does not
+ include the default "tm.h" file. This is used in files where
+ the target is known, e.g. remote-eb.c or sparc-xdep.c.
+
+ param.h: Now just a shell that includes tm.h and param-no-tm.h.
+
+ remote-vx.c: New file, VxWorks remote debugging support. Uses
+ RPC routines that are shared with the target system, in directory
+ ${srcdir}/vx-share.
+
+ remote.c: Vectorize remote interface.
+
+ source.c: Globalize source_path, and make an alias "l" for "list"
+ since we now have the "load" command.
+
+ sparc-xdep.c: Use new param-no-tm.h.
+
+ symmisc.c (free_named_symtab): Add new function from Wind River.
+ However, ifdef it out for now while we think about what it should
+ really be doing.
+
+ tm-sun3.h, xm-sparc.h, xm-sun3.h, xm-symmetry.h: Move
+ PREPARE_TO_STORE to
+ the xm- file, and change its name to CHILD_PREPARE_TO_STORE, since
+ non-Unix-children handle this with their own code in the target
+ transfer vector.
+
+ Makefile.dist: Roll version to 3.92.3. Add vx-share stuff to
+ source and target lists. Add vx-share to default list of include
+ directories. Add new files to src and target lists: mem-break,
+ target, inftarg, remote-eb, remote-vx, targ-vx. Be sure the
+ ${srcdir} versions of munch and createtags are used.
+
+ * valops.c (find_function_addr): Split out of call_function.
+ (call_function_by_hand): Rename call_function; this function
+ calls functions in the target by laboriously patching the target
+ word-by-word with the right stack, args, regs, etc.
+
+
+Mon Nov 5 17:29:10 1990 John Gilmore (gnu at cygint)
+
+ Handle AMD 29000 a bit better.
+
+ * remote-eb.c (readchar): Mask received char log to make it readable.
+ (remote_start): Pass arguments down to executing program.
+ Make startaddr unsigned.
+ infrun.c (start_inferior): Accept args, pass them to
+ remote_start.
+ infcmd.c (run_command): Pass args down to start_inferior.
+
+ * tconfig/am29k-aout, tconfig/am29k-coff: New files specifying
+ the target object file format.
+ tm-29k.h: Pay heed to COFF_ENCAPSULATE.
+
+ * am29k-pinsn.c (print_insn): Print 0x on hex numbers in disassembly.
+ am29k-tdep.c (examine_prologue): Better checking of function prefixes.
+
+Sun Oct 7 18:20:45 1990 John Gilmore (gnu at cygint)
+
+ * Makefile.dist (VERSION): Roll version to 3.91.9 and freeze.
+ * TODO: We did a few things, we have more to do though.
+
+ * xm-sparc.h (CLEAR_DEFERRED_STORES): Define.
+ * inflow.c (inferior_died): Clear deferred stores.
+
+ * Debug problems with dummy frames and calls to the inferior.
+ * tm-sparc.h (PUSH_DUMMY_FRAME, POP_FRAME): Move to sparc-tdep.c.
+ * sparc-tdep.c (do_restore_insn): Simplify.
+ (sparc_frame_find_saved_regs): Simplify and fix what we find.
+ (sparc_push_dummy_frame): Simplify and fix what we push.
+ (sparc_pop_frame): Slightly more hair here, deciding whether
+ we are restoring a saved PC or returning to a return address in %i7.
+ * sparc-xdep.c (read_inferior_registers): Debug if valid reg is read.
+
+ * utils.c (xmalloc, xrealloc): Return type depends on __STDC__.
+ * symtab.h (xmalloc): ditto, for obstack_chunk_alloc.
+ * obstack.h (chunkfun): ditto.
+ * defs.h (xmalloc, xrealloc): ditto
+
+ * utils.c (quit): Grab the terminal from the child if necessary.
+
+ * inflow.c (term_status_command): Rename to term_info, change
+ to "info terminal".
+
+ * sparc-pinsn.c (print_insn): Disassembly prefers real instructions.
+ (is_delayed_branch): Speed up.
+ * sparc-opcode.h: Add ALIAS bit to aliases. Fix up opcode tables.
+ Still missing some float ops, and needs testing.
+
+ * Support for input and output radixes other than base 10
+ * defs.h (input_radix, output_radix): Declare.
+ * expread.y (yyparse, parse_number): Handle changes of input
+ radix, and ambiguous names-or-numbers in radixes >10.
+ * printcmd.c (print_scalar_formatted): Print formatted hex
+ numbers in varying column widths.
+ * valprint.c (val_print): Use output_format to print scalar ints.
+ (set_input_radix, set_output_radix, set_radix): Create.
+ (set_output_radix): Set output_format from output_radix.
+ (_initialize_valprint): add `set radix' but leave the others off.
+
+ * main.c (execute_command): Let stupid questions be turned off.
+ (_initialize_main): Handle "set stupidity", etc.
+
+ * main.c, inflow.c, inferior.h, frame.h, command.c, defs.h,
+ sparc-pinsn.c, sparc-xdep.c, value.h, valops.c, values.c: Lint.
+
+Tue Oct 2 11:20:02 1990 John Gilmore (gnu at cygint)
+
+ * TODO, Makefile.dist, ChangeLog: Freeze for 3.91.8 release.
+ bfd stuff is still screwed up, but with some manual work, it
+ compiles.
+
+ * breakpoint.c (bpstat_do_actions): Start over if a command
+ proceeds the inferior, since the inferior will have stopped and
+ will need to have its new stop-actions taken care of.
+
+ * dbxread.c (read_struct_type): Expression gives Sun3 4.0.3
+ compiler fits, simplify it.
+
+ * gdb.texinfo (directory command): Doc new dir command.
+ source.c (directory_command): "dir" now puts things on the front
+ of the path, moves dups up front, and handles multiple names
+ on the command line, inserting each one in order. It also
+ blows away cached line and full_filename info.
+
+ * stack.c (backtrace_command): Skip "more stack frames follow"
+ unless interactive.
+
+ * Change #ifndef HAVE_VPRINTF to #define MISSING_VPRINTF in
+ xm-convex.h, xm-hp300bsd.h, xm-isi.h, xm-merlin.h, xm-news.h,
+ xm-np1.h, xm-pn.h, xm-pyr.h, xm-symmetry.h, xm-umax.h, xm-vax.h.
+ The only odd one was Gould NP1, which had defined vprintf to
+ "printf"!!!
+
+ * Merge Ted Goldstein <tedg@Eng.sun.com>'s changes for epoch.
+ printcmd.c (print_command_1): Pass 'inspect' flag down as a global
+ variable, inspect_it.
+ valprint.c (print_string, val_print): Use the global inspect_it
+ to indicate whether to print in Epoch style or normal style.
+
+Mon Oct 1 23:55:26 1990 John Gilmore (gnu at cygint)
+
+ * printcmd.c (call_command): add an alias for the "print" command
+ which runs expressions and doesn't print the result if void.
+ (print_command_1): implement it.
+
+ * command.c: Remove #if 0'd code. Initialize all the fields
+ in add_cmd (). Rename do_nothing_command to
+ not_just_help_class_command, and make it externally visible.
+ command.h: add user_commands to struct.
+ * main.c (define_command): Don't overload c->function with a char
+ string as well as a function pointer.
+
+ * eval.c (evaluate_subexp): Reinstall tiemann changes to
+ calling convention of value_struct_elt () that got dropped in
+ merge.
+
+ * tm-sparc.h (FRAME_FIND_SAVED_REGS): move to sparc-xdep.c.
+ sparc-tdep.c (sparc_frame_find_saved_regs): ditto.
+
+ * tm-sparc.h (POP_FRAME): replace some constants with defines.
+
+ * sparc-xdep.c (store_inferior_registers): defer stores to regs
+ until a good time (e.g. when we are about to run the child),
+ saving ptrace calls.
+ * infrun.c (proceed): handle DO_DEFERRED_STORES.
+ * tm-sparc.h: define DO_DEFERRED_STORES.
+
+ * sparc-xdep.c (store_inferior_registers): when storing float
+ registers, don't store stack regs too. When storing the SP,
+ however, DO store the stack regs too. This fixes a bug in which
+ the dummy frame is not recognized when a call_function finishes,
+ because its frame pointer (in the stack regs) was never
+ initialized.
+ (read_inferior_registers): Mark WIM and TBR and FPS and CPS valid
+ even though we don't know how to read them from an inferior.
+ valops.c (call_function): Comment about storing SP.
+
+ * infrun.c (save_inferior_status): Save away the original bpstat
+ chain so it can be restored later. Install the copied version for
+ use by whoever saved the status. It will be blow away by
+ restore_inferior_status, and the original chain restored. This is
+ important for people who have pointers into the original.
+
+ * breakpoint.c, command.h, copying.awk, dbxread.c, defs.h,
+ findvar.c, frame.h, obstack.h, obstack.c, inflow.c, value.h,
+ main.c, printcmd.c, sparc-tdep.c, symtab.c, valprint.c: lint
+
+
+Fri Sep 28 20:32:46 1990 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.dist: Roll version to 3.91.8. Add bfd.h and bfdconfig.h
+ temporarily to the makefile. Add am29k-opcode.h and WHATS.NEW.
+ Add stuff.c and kdb-start.c to the OTHERS list for tar files.
+
+Fri Sep 28 19:12:12 1990 John Gilmore (gnu at cygint)
+
+ * Merge Mike Tiemann's multiple inheritance changes from Sun.
+ Store the baseclasses in a type struct starting from array element
+ 0 rather than from the unusual array element 1.
+
+ dbxread.c: the above.
+ (virtual_context): Add
+ Read new debug information about which virtual function table
+ a virtual function is from, and store it in fn_field.fcontext.
+
+ symtab.h: Add fcontextt. Fix baseclass indices. Typo in
+ TYPE_FN_FIELD_STATIC_P.
+
+ symtab.c: the above.
+ valops.c: the above. Handle pointer casts of object *'s.
+ (search_struct_method): Add.
+ (value_struct_elt): First arg is now a pointer to a value, and is
+ modified on return.
+
+ valprint.c: the above.
+ values.c (value_virtual_fn_field): Add type arg. Handle
+ offsetting to the proper object when calling virtual fns.
+ The above.
+ (baseclass_addr): Add valuep arg.
+
+ * README: Document the current state of BFD config (missing).
+ * TODO, ChangeLog, Makefile.dist: Roll version.
+ * WHATS.NEW: Add summary of changes since 3.5.
+
+Thu Sep 27 16:23:12 1990 John Gilmore (gnu at cygint)
+
+ * dbxread.c (read_struct_type): Clear bit vectors whenever
+ we allocate one.
+ symtab.c (B_CLRALL): define.
+
+ * tm-sparc.h (STORE_RETURN_VALUE): Avoid clobbering types by
+ using == rather than =. Huh... This fixes the dreaded problem
+ wherein builtin_type_int becomes TYPE_CODE_FLT.
+
+ * core.c (info_files): Show the inferior pid.
+
+ * config.gdb: Avoid putting "dir" command into .gdbinit. GDB
+ already knows how to look in the source directory.
+
+ * Remove psymtab hair from many places. Remove duplicated code
+ for searching symbol tables. Hide psymtabs from most places.
+ Make it fast to get from a psymtab to its symtab.
+
+ blockframe.c (blockvector_for_pc): Remove psymtab hair.
+ coffread.c (psymtab_to_symtab): Rename to psymtab_to_symtab2.
+ mipsread.c (psymtab_to_symtab): Rename to psymtab_to_symtab2.
+ dbxread.c: export psymtab_to_symtab, make it work if called N times.
+ (psymtab_to_symtab): Rename to psymtab_to_symtab2. Initialize
+ new symtab completely. New psymtabs get symtab pointer
+ initialized to zero. Remove MI warning printf.
+ symtab.h: Comments. Add psymtab to symtab pointer.
+ (PSYMTAB_TO_SYMTAB): New macro.
+ symtab.c: use PSYMTAB_TO_SYMTAB. Add psymtab_to_symtab and export it.
+ source.c: use PSYMTAB_TO_SYMTAB. Remove symtab version and
+ compilation fields.
+ stack.c (backtrace_command): Avoid pre-pass to read symbols, if
+ verbose is not set.
+ (print_frame_info): Avoid special-casing symbols that have not yet
+ been read in.
+
+ * source.c (open_source_file): Quick path if we have already
+ located the source file by its full name.
+
+ * symtab.c (lookup_symbol): Use find_pc_symtab rather than
+ find_pc_psymtab. When a name is found in the misc function
+ vector, search the symbol table for its mangled name, not the
+ name that the user typed.
+
+ * bfd.h: Fix missing comment terminators, make #endifs match.
+
+ * valarith.c (value_less): Handle unsigned int comparisons.
+ Add FIXME about pointer compares, which assume host and target
+ pointers are the same.
+
+ * command.c (do_nothing_command): lint
+ dbxread.c: lint. Remove sort_syms. Document C++ visibility info,
+ fix comments on debug symbol format for visibility. Actually set
+ visibility of symbols.
+ main.c (echo_command): lint; use <readline/history.h>.
+ tm-sparc.h (FRAME_FIND_SAVED_REGS): lint
+ obstack.h (_obstack_blank): Rearrange pointer math to avoid
+ pointing past end of allocated memory; saber complains.
+ obstack.h: Declare the external functions that we use.
+ valarith.h: use <string.h>
+ solib.c (solib_add): lint.
+
+Fri Sep 21 17:05:19 1990 John Gilmore (gnu at cygint)
+
+ * main.c (initialize_main): Default info_verbose to off, now that
+ symbol reading is fast.
+ (quit_command): Avoid clobbering exec_bfd while quitting.
+
+ * Initial BFD (binary file diddling library) merger:
+ coffread.c: Change AOUTHDR to struct exe_hdr.
+ dbxread.c: ditto.
+ core.c: initialize initialized data at compile time.
+ (core_file_command): Move from coredep.c, convert to bfd.
+ (xfer_core_file): Convert to bfd.
+ exec.c (exec_file_command): use bfd routines.
+ gdbcore.h: BFD.
+ mips-tdep.c: Remove exec_file_command and friends.
+ source.c: bfd.
+
+ * coredep.c: (fetch_core_registers) Convert core_file_command to
+ fetch_core_registers.
+ mips-xdep.c, sparc-xdep.c, sun3-xdep.c: ditto.
+
+ * utils.c: (error): Bogus crap, FIXME, to print bfd errors.
+ (my_bfd_read): More bogosity, which I don't think we call.
+ (program_name): Remove this atrocity asap!
+
+Wed Sep 19 13:36:41 1990 John Gilmore (gnu at cygint)
+
+ * From Per Bothner:
+ values.c: allocate_repeat_value was not clearing the
+ optimized_out field.
+ (value_static_field): minor stylistic fix (wrong macro was used).
+ valops.c (value_struct_elt_for_address): didn't work for C++
+ static fields.
+
+ * signame.c (_initialize_signame): Initialize signal names once.
+
+ * breakpoint.h, command.c, copying.awk, defs.h, environ.c,
+ exec.c, frame.h, infcmd.c, inferior.h, main.c, munch, sun3-xdep.c,
+ symtab.h, tm-29k.h, valprint.c, value.h, values.c: Lint.
+
+ * remote-eb.c: Support user-settable baud rates on the serial port.
+
+ * tm-sun3.h (PREPARE_TO_STORE): fix typo.
+
+Fri Sep 14 13:28:29 1990 John Gilmore (gnu at cygint)
+
+ * tconfig/sun3os4: Remove warning about native assembler,
+ since it also occurs in the xconfig file.
+
+ * findvar.c (registers): Allocate some slop after `registers'
+ to prevent stray accesses from trashing the next variable.
+
+ * tm-68k.h (REGISTER_BYTES): Allocate the right number of bytes
+ on the sun-3, by changing the #ifdef from `sun3' (which is not
+ defined by cc) to `sun'. Symptom was trashed builtin_type_XXX
+ vars, which happened to follow `registers' in the executable.
+
+ * readline/history.c (history_search): Heed gcc-2's advice
+ and parenthesize && inside ||).
+
+ * am29k-opcode.h, am29k-pinsn.c, am29k-tdep.c, remote-eb.c,
+ tm-29k.c: Insert FSF copyright headers.
+
+ * remote-eb.c: Better comments.
+
+ * Makefile.dist: Update to 3.91.6.
+ * TODO: note PREPARE_TO_STORE problem.
+
+Thu Sep 13 09:52:33 1990 Jim Kingdon (kingdon at cygint)
+
+ * stack.c (frame_info): Only use FRAME_FIND_SAVED_REGS if defined.
+
+ * remote.c: Wrap the whole file in #if !defined (SPECIAL_REMOTE).
+
+ * infrun.c (wait_for_inferior, at end): Don't set up
+ prev_* if the inferior no longer exists.
+
+ * inferior.h (CALL_DUMMY_LOCATION): New macro, to replace
+ CANNOT_EXECUTE_STACK.
+ valops.c (call_function): Use it.
+
+ * tm-convex.h: Add CALL_DUMMY_LENGTH for use by PC_IN_CALL_DUMMY.
+
+ * inferior.h (PC_IN_CALL_DUMMY): New macro.
+ infrun.c (wait_for_inferior, 2 places): Use it.
+
+ * values.c (value_being_returned): Only use
+ EXTRACT_STRUCT_VALUE_ADDRESS if defined.
+
+ * Move PREPARE_TO_STORE from xm-sun3.h to tm-sun3.h to do the
+ right thing for remote-eb.c.
+
+ * sun3-xdep.c: Remove extraneous call to remote_store_registers.
+ * sun386-xdep.c, hp300hpux-xdep.c, sparc-xdep.c: Ditto.
+
+ * blockframe.c: Put get_frame_saved_regs inside #if !defined
+ (FRAME_FIND_SAVED_REGS).
+
+ * findvar.c ({fetch,store}_registers): Check for
+ REMOTE_{FETCH_STORE}_REGISTER macro.
+
+ * findvar.c (get_saved_register): Add argument lval and
+ change meaning of argument addr.
+ findvar.c: Change calls to get_saved_register to reflect
+ new calling convention.
+ valops.c (value_assign): Use get_saved_register instead of
+ find_saved_register.
+
+Sun Sep 2 12:40:20 1990 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * coffread.c (read_one_sym): Make temp_aux an AUXENT, not
+ an (uninitialized) pointer to one. Use "&" when passing it
+ to fread.
+
+Fri Aug 31 22:57:54 1990 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * coffread.c (getfilename): Use DGUX x_offset and x_name if
+ defined.
+
+ * coffread.c (symbol_file_command): Put semicolon after
+ "int from_tty".
+ Put safe_to_init_tdesc_context in #if defined (TDESC).
+ Put #ifdef TDESCs in 1st column for non-ANSI cpp's.
+ coffread.c: #include <sys/stat.h>.
+ (read_coff_symtab): Typo: in_source_files -> in_source_file.
+ Add missing ')' in check for "lc%" and friends. Remove
+ extraneous '}'.
+ Declare read_one_sym() at top of file.
+ (read_file_hdr): Put in extra #ifdefs so MC68MAGIC and
+ MC68WRMAGIC can have the same value without causing a duplicate
+ case.
+
+Thu Sep 13 15:55:36 1990 John Gilmore (gnu at cygint)
+
+ * Allow a Makefile to be built without building the
+ tm and xm file links that screw up builds in subdirectories.
+ This is done with `config.gdb none', then you can do things
+ like `make gdb.tar.Z'.
+ * tconfig/none: Config file for no target system
+ * xconfig/none: Config file for no host system
+ * config.gdb: If no TM or XM files are called out by the
+ host or target file, don't make links for them.
+
+ * cplus-dem.c: Add documentation.
+
+ * dbxread.c (read_ofile_symtab): Turn a fatal error into a
+ simple error, so the user's gdb doesn't crash due to some object
+ file problem (e.g. somebody is rebuilding the file out from under
+ gdb).
+
+ * printcmd.c (print_address_symbolic): demangle the symbol.
+
+ * Makefile.dist (OTHERS): Remove tdesc-lib because it has
+ Motorola copyrights in it. Make "make gdb.tar.Z" work.
+ (alldeps.mak): sort and uniq all results from this; duplicates
+ hose gdb.tar.Z link building. Remove RCS files from
+ tconfig and xconfig. Add config files for sun386. Add
+ a few odd files to OTHERS and HFILES.
+
+Mon Sep 10 21:20:24 1990 John Gilmore (gnu at cygint)
+
+ * Makefile.dist: Pull solib.c to tconfig/sun?os4.
+ Roll version number to 3.91.5. Make lint work in bindir.
+
+ * README: Document cross-debugging and new file structure.
+
+ * blockframe.c: Lint. Include "value.h" to declare read_register.
+ (find_pc_partial_function): remove duplicate line.
+
+ * command.h: Lint. Declare error_no_arg and dont_repeat.
+
+ * tm-news.h: Remove inadvertently duplicated stuff.
+
+ * mipsread.c: Remove cache_pc_function stuff, now done cleanly.
+ Clean up usage of misc_function_type. Declare some CORE_ADDRs.
+
+ * config.gdb: Allow `config.gdb host target' form. Clean
+ up previous change that printed bogus messages when you just said
+ `config.gdb'.
+
+ * core.c: #include "command.h" for lint.
+ * dbxread.c: lint
+ * eval.c: lint
+ * main.c: Remove some casts of enums. Lint.
+ * source.c: lint
+ * symtab.c: lint
+ * symtab.h: lint
+ * expread.y: lint
+ * valarith.c: lint
+
+ * printcmd.c (initialize_printcmd): Fix thinko in inspect cmd.
+
+ * sparc-tdep.c (isannulled): Take instruction as parameter, don't
+ read it from memory. This will allow us to save ptrace calls
+ eventually. Changed caller single_step too.
+
+ * sparc-xdep.c (fetch_inferior_registers): Avoid reading regs
+ that we aren't going to use, saving many ptrace calls, especially
+ when watchpointing or single stepping. Use some #define's for
+ constants.
+ (store_inferior_registers): Ditto.
+ (core_file_command): Use some #define's for constants.
+
+ * tm-sparc.h: Add #define's for some register numbers, so we
+ can eliminate the use of random constants in sparc-xdep.c.
+
+ * stack.c (frame_command, print_frame_info, up_command,
+ down_command) Remove frame_changed, since it
+ causes a bug and doesn't seem to do anything useful. In some
+ places it was used as a flag, in others as a stack level (?).
+
+ * utils.c: Use MISSING_VPRINTF rather than HAVE_VPRINTF, so the
+ default is to use the portable (vprintf) version rather than the
+ kludge version.
+ * xm-news.h (MISSING_VPRINTF): Add.
+
+ * valprint.c (val_print): Demangle fancy vtbl printouts. Lint.
+
+Sat Sep 8 00:24:12 1990 John Gilmore (gnu at cygint)
+
+ * Remove stuff that forces -Bstatic linking of gdb, and warnings
+ about linking debugged programs -Bstatic in the sun?os4 config
+ files in tconfig and xconfig subdirectories.
+
+ * main.c (main): Remove unreached exit(0) now that we exit
+ via quit_command().
+
+ * Create TODO file for online bug list. There are too many
+ "little" bugs to keep track of on paper.
+
+ * Change Projects file to refer to bug-gdb@cygnus.com
+ rather than kingdon@ai.
+
+Fri Sep 7 23:35:15 1990 John Gilmore (gnu at cygint)
+
+ * Makefile.dist (VERSION): 3.91.4 now.
+
+ * symtab.c (init_misc_bunches): Rename from init_misc_functions.
+ (condense_misc_bunches): Add sanity check that misc_count is
+ the same as the number of symbols in the bunch.
+
+ * coffread.c: rename init_misc_bunches. Pass an argument
+ to condense_misc_bunches (a zero).
+
+ * dbxread.c (partial_symbol_file_read): Call init_misc_bunches
+ every time we are called; don't rely on our caller to do it.
+ (add_file): Remove call to init_misc_bunches.
+
+ * mipsread.c: Only warn, don't error, if unknown symbol types.
+ This keeps an old gdb from falling on its face if it sees newly
+ extended symbol info. Rename init_misc_bunches.
+
+Fri Sep 7 22:58:15 1990 John Gilmore (gnu at cygint)
+
+ * Merge in changes from Per Bothner for DECstations and other
+ MIPS stuff. The rest is Bothner speaking:
+
+ The next message is a merger of Alessando Forin's mips port with
+ mine. I've tried to use my good if biased judgment to get
+ the best of both. It *does* need testing.
+
+ Some of the changes are general, *not* mips-specific.
+
+ param.h:
+ Didn't believe in little-endian bit order.
+ There are still inconsistencies about whether flags
+ like BITS_BIG_ENDIAN are integer (#if ...) or
+ boolean (#ifdef ...). I tried to paper over them.
+
+ dbxread.c,coffread.c,mipsread.c,symtab.c,symtab.h:
+ Moved some misc_function code that was common to
+ {dbx,coff,mips}read.c to symtab.c.
+ In the process, I think I cleaned things up a bit.
+ At the same time, moved obsavestring and obconcat to symtab.c.
+
+ dbxread.c:
+ Removed obsolete condense_addl_misc_bunches (use
+ condense_misc_bunches(1) instead).
+
+ exec.c:
+ Needed to include <sys/dir>, at least on DECstations.
+
+ valops.c, mips-tdep.c, tm-mips.h:
+ Added PUSH_ARGUMENTS macro to support funny argument-pushing
+ conventions (when STACK_ALIGN is insufficient).
+ Needed on mips, where doubles need 8-byte alignment,
+ but ints only need 4.
+
+ mips-opcode.h:
+ Removed cruft that was not being used.
+ Merged in many fixes (most from Frank Yellin, fy@lucid.com).
+
+ mips-pinsn.c:
+ Print $ before register-names (I think that makes things a little
+ more consistent).
+ Never print two instructions, even if one delays.
+ Removed hex-disassemble set_cmd. (This is not mips-specific,
+ so I think the argument is whether it is generally worthwhile or not.
+ I'm inclined to think not, given how easy it is to
+ convert between radixes in gdb.)
+
+ mipsread.c:
+ This is basically Alessando's code.
+ It doesn't use obstacks; I changed it to use obstacks
+ in a few minor places where using malloc causes a
+ memory leak. (Probably, more places could/should be changed.)
+ I added record_misc_function where it was missing.
+ In symbol_file_command and add_file_command, I tried
+ to make the code consistent with more recent versions.
+ Minor sylistic changes in parse_procedure.
+ Make a .gdbinfo. psuedo-symbol point back to the real
+ procedure symbol (using the isym field).
+
+ mips-tdep.c:
+ This is basically from my port, but with a lot of details
+ and a number of routines merged in from Alessando's version.
+ I basically used my code "raw" backtrace (use heuristics
+ from the actual code, rather than symbol table info) - though
+ the idea is Alessandro's. I feel my code is a little cleaner
+ here, particularly in being a little more flexible, such as being
+ able to handle gcc-produced code (which it now can).
+ It also doesn't do frame caching (which is not useful
+ more recent gdb versions).
+ I also used my code for push_/pop_dummy, more or less.
+ I tried to incorporate AF's code for testing sigtramp
+ while backtracing; I probably got it wrong.
+ Added mips_print_register, which tries to scrunch as much
+ information as possible on a screen...
+ Removed the skip-prologue set_cmd. As with hex-disassemble (see
+ under mips-pinsn.c), I don't see anything mips-specific here,
+ and I don't see it being all that useful anyway.
+
+ tm-mips.h:
+ Added a $fp psuedo-reg distinct from $fp (nice for gcc).
+ Use more register names (rather than hard-cases numbers).
+
+Thu Sep 6 18:33:15 1990 John Gilmore (gnu at cygint)
+
+ * Hack up 3.90.11 changes:
+
+ * Makefile.dist (depend): parameterize $(GCC).
+ Add solib.c and solib.o.
+ (readline): Fix vpath for both absolute or relative SRCDIR.
+
+ * blockframe.c: Fix from Schaefer@asc.slb.com for shared libs.
+ Also, let the part I didn't understand at least compile so
+ I can test the rest. FIXME.
+
+ * dbxread.c: Fix thinko using strcmp.
+ (init_psymbol_list): declare static.
+ (partial_symbol_file_open): Comment cleanups better, avoid
+ cleaning up the string table since the caller will do that.
+ Move the stat for mod time into symbol_file_command, temporarily.
+ (There should be a mod time for each symbol file, eventually,
+ to control its rereading. FIXME.)
+
+ * infptrace.c (PT_WRITE_D): use same value as PT_WRITE_I for
+ SunOS, which gives error for shared libs otherwise. (From
+ Schaefer, probably FIXME needs work for portability.)
+
+ * solib.c: Move #include "param.h" to work.
+ Lowercase all the Uppercase Letters In the Messages.
+ (find_solib): Clean up inferior_so_name for debug printouts.
+ Allow no argument, to mean all shared libraries.
+
+ * symmisc.c: include param.h to get CLEAR_SOLIB.
+
+Wed Sep 5 18:00:08 1990 John Gilmore (gnu at cygint)
+
+ * Merge in Kingdon's changes from FSF: the diffs from 3.90.9
+ to 3.90.11. ChangeLog entries below are from this.
+
+Wed Jun 13 09:17:39 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * Version 3.90.11.
+
+ * Makefile.dist (HFILES): Add tm-sunos.h.
+
+Tue Jun 12 16:15:26 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * Version 3.90.10.
+
+ * Makefile.dist (gdb.tar.Z): Change linking of config so it works.
+
+Thu Jun 7 16:22:27 EDT 1990 Jay Fenlason (hack@ai.mit.edu)
+
+ * sparc-opcode.h Added single-operand version of rett.
+
+Mon Jun 4 18:12:31 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * m-sparc.h (REG_STRUCT_HAS_ADDR, STRUCT_ARG_SYM_GARBAGE):
+ Put parens around gcc_p in expansion.
+
+Thu May 24 15:44:51 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * utils.c (lines_to_list): Return 10 if lines_per_page == 0.
+
+Wed May 23 16:36:04 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * Changes for Sun shared libraries:
+ blockframe.c (find_pc_partial_function): If a non-text symbol
+ is found, set *address = pc - FUNCTION_START_OFFSET.
+ breakpoint.c (insert_breakpoints) [DISABLE_UNSETTABLE_BREAK]:
+ Disable breakpoints instead of giving an error.
+ source.c (select_source_symtab): Initialize cs_pst.
+ symmisc.c: Call CLEAR_SOLIB if defined.
+ symtab.h: Make text{low,high} CORE_ADDR not int.
+ (psymtab): New field addr.
+ solib.c: New file.
+ dbxread.c: Move DECLARE_FILE_HEADERS outside functions.
+ (record_misc_function): Give correct type for N_DATA symbols.
+ (condense_misc_bunches): do "misc_function_count = j" regardless
+ of inclink.
+ Take code which is shared between symbol_file_command and
+ add_file_command and put it into partial_symbol_file_{open,read}.
+ Split add_file_command into add_file_command and add_file.
+ Make psymtab_to_symtab read in the string table if the file
+ is not symfile.
+ Two new parameters to read_dbx_symtab and start_psymtab.
+ tm-sunos.h: New file.
+
+Tue May 22 17:43:03 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * infcmd.c: Change cont_command to continue_command and "cont"
+ to "continue".
+
+Mon May 21 14:41:41 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * breakpoint.c (enable_breakpoint): Get value of watchpoint.
+
+ * defs.h [sparc]: Use <alloca.h> regardless of __GNUC__.
+
+ * values.c (USE_STRUCT_CONVENTION): Check for structures of
+ size 1,2,4,8 rather than size < 8.
+
+ * dbxread.c (dbx_lookup_type): Do f->length *= 2 as many times
+ as necessary, not just once.
+
+ * sparc-opcode.h: Add a bunch of new opcodes which Sun as supports.
+
+Thu May 17 15:04:09 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * {t,x}m-sun386.h, sun386-xdep.c, {x,t}config/sun386
+
+ * tm-news.h: Add CALL_DUMMY_*.
+
+ * tm-68k.h: Remove duplicate comment at FRAME_FIND_SAVED_REGS.
+
+ * config.gdb: In list_host, list_target, use ${i}, not $i.
+
+Tue May 15 21:27:12 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * source.c (find_source_lines) [BROKEN_LARGE_ALLOCA]: Use xmalloc.
+
+ * sparc-opcode.h: Change all store floating-point state register
+ instructions to have the right match & lose fields.
+
+Sat May 5 12:39:18 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * Makefile.dist: Move -I${srcdir} to GLOBAL_CFLAGS and pass
+ VPATH to readline.
+ config.gdb: If srcdir != ., create readline directory and
+ copy a makefile into it.
+
+ * wait.h, infrun.c: Change WRETCODE to WEXITSTATUS for
+ consistency with POSIX.
+
+ * breakpoint.c (bpstat_stop_status): Disable watchpoint
+ when we exit its exp_valid_block.
+
+Tue Sep 4 11:46:46 1990 John Gilmore (gnu at cygint)
+
+ * Makefile.dist: Bump version to 3.91.3.
+
+ * Clean up handling of breakpoint commands (somewhat).
+ Prompted by Tiemann bug report "cont 10" doesn't work any more.
+
+ inferior.h: Add breakpoint_proceeded to inferior status struct
+ and globals; save it and restore it.
+ (clear_breakpoint_commands): Cleanup, remove old #define.
+
+ infrun.c (clear_proceed_status): Set breakpoint_proceeded.
+ (save_inferior_status, restore_inferior_status): handle it also.
+ (proceed): Remove earlier code that set breakpoint_proceeded.
+ It is now set only in clear_proceed_status.
+ (clear_proceed_status): Cleanup, use bpstat_clear rather
+ than clear_breakpoint_commands. No callers need the stop_bpstat
+ between clear_proceed_status and proceed.
+
+ infcmd.c: Add breakpoint_proceeded definition and comment.
+ (cont_command, jump_command, signal_command): Move call to
+ clear_proceed_status right next to call to proceed.
+
+ breakpoint.c (bpstat_do_actions): Avoid clobbering our
+ caller's argument while running down the chain of breakpoints.
+ Use new variable "breakpoint_proceeded" to determine when
+ a command that it executes moves the inferior past the
+ breakpoint.
+ (bpstat_clear): Handle NULL argument.
+ (bpstat_clear_actions): Avoid useless call to
+ breakpoint_auto_delete.
+ (delete_breakpoint): Clean up bpstat's that are pointing to
+ the deleted breakpoint from the stop_bpstat chain.
+ (breakpoint_auto_delete): Simplify.
+
+ * Clean up handling of EOF, error on stdin, etc. This was
+ prompted by a network problem that caused gdb to go into an
+ infinite loop filling up its malloc'd memory.
+
+ main.c (return_to_top_level): Cleanup: call bpstat_clear_actions,
+ not clear_breakpoints_commands, which is now gone.
+ (main): If command_loop returns (e.g. from EOF on stdin), do
+ a quit_command (looping back to command_loop if quit_command
+ doesn't really quit).
+ (command_loop): check result from command_line_input and
+ exit if it returns NULL, rather than passing the NULL to
+ execute_command.
+ (gdb_readline): Free malloc'd result space before returning
+ NULL for EOF.
+
+ * utils.c (query): Handle C-d to mean "yes", just as if the
+ input was not a terminal. Also avoid infinite loop if EOF
+ occurs in mid-input-line before newline. This allows
+ query to be used at EOF on stdin with reasonable results.
+
+ * infrun.c (proceed): Set breakpoint_proceeded.
+
+ * values.c (value_as_long): Avoid infinite recursion for enums.
+ (_initialize_values): Fix typo in help msg (kingdon).
+
+ * Makefile.dist (RL_LIB): Use RL_LIB_DEP for dependencies,
+ RL_LIB for linking. This allows -lreadline for linking
+ and nothing for dependencies, once readline is a real library.
+
+ * config.gdb: Jim Kingdon: give useful error message if the
+ host or target type is not recognized.
+
+ * defs.h (alloca): SPARC <alloca.h> does not declare alloca,
+ it just defines it. Dumb, but deal with it.
+
+ * Jim Kingdon suggests:
+ in xconfig/sun3os4, CFLAGS should be XM_CFLAGS.
+
+Wed Aug 29 18:03:27 1990 John Gilmore (gnu at cygint)
+
+ * Makefile.dist (VERSION): Bump version # to 3.91.2.
+
+ * Clean up Bothner's changes.
+
+ * blockframe.c (clear_pc_function_cache): New function.
+ * blockframe.c: remake cache_pc_function_* static.
+ * dbxread.c (symbol_file_command): remove references to
+ cache_pc_function_* variables.
+ * dbxread.c (read_struct_type): Use VOFFSET_STATIC.
+ * printcmd.c: Avoid kludging a global variable (addressprint)
+ to avoid printing the address of a string twice. Instead,
+ pass the format letter 's' down low enough that it can be seen
+ to avoid this problem.
+ (print_formatted): Pass format arg to value_print.
+ (restore_addressprint): Remove function.
+ (do_examine): Avoid hacking addressprint, cleanups and such.
+ (print_frame_args): Add a comment to a Bothner change.
+ * symtab.h: define VOFFSET_STATIC and use it instead of "-1".
+ * symmisc.c (free_all_symtabs): Call clear_pc_function_cache
+ to wipe out the values cached in blockframe.c.
+ * symtab.c (find_method): Add comment saying how big you must
+ allocate to be "big enough". Per being terse again.
+ * valprint.c (val_print): Handle format letter "s" to print
+ strings without addresses. Add comment to vtbl printing code
+ which casts with wild abandon. Rearrange reference-printing
+ code so it prints:
+ @0xaddr: value (print w/addressprint)
+ value (print w/~addressprint)
+ @0xaddr (parameter lists w/addressprint)
+ or nothing (parameter lists w/o addressprint)
+
+Tue Aug 28 10:47:18 1990 John Gilmore (gnu at cygint)
+
+ * Merge more changes from Per Bothner:
+
+Gdb's handling of TYPE_CODE_REF was so counter-C++ (and otherwise
+annoying) that I tried to improve it. Here are my suggestions.
+
+ These patches all attempt to handle TYPE_CODE_REF (as in C++) better.
+
+ findvar.c:
+ Do automatic de-reference when taking the address of a reference.
+ printcmd.c:
+ Don't deref_ref when printing parameter lists.
+ valops.c:
+ More attempts at treating refernences properly.
+ valprint.c:
+ In val_print, if deref_ref==0, don't print dangling " = ".
+ value.h:
+ Add COERCE_REF macro, which de-references an REF.
+
+ * Merge changes from Per Bothner:
+
+* Fixed (Sony news)-specific configuration problems.
+* Fixed other problems with using vanilla pcc and libc (enum problems;
+assumption that vsprintf exists).
+* Some major speed-ups (finc_pc_partial_function now caches a match;
+parsing avoids duplicate symbol_lookup calls).
+* Changed handling of baseclasses (no longer use baseclasses field
+of struct type, use the first n_baseclasses fields instead).
+* Various minor changes/fixes, most C++-related.
+
+blockframe.c:
+Cache the most previous match from find_pc_partial_function.
+(Save both low and high ends of matching function's pc range.)
+This speeds up the loop of infrun.c:wait_for_inferior quite
+a bit, and makes step/next commands much zippier.
+command.c:
+Added an enum->int cast (otherwise, some compilers barf).
+dbxread.c:
+No longer set baseclass offset to 0, since multiple
+inheritance now mostly works.
+Added a number of casts, to shut up compiler warnings
+(after stabs where made enums, not ints).
+When discarding a symbol table (in symbol_file_command),
+must clear the cache introduced in blockframe.c.
+Don't convert $vtbl_ptr_type to vtbl any more.
+Get rid of TYPE_BASECLASEES and baseclass_vec (see also symtab.h).
+Mask off sign bit emitted by g++ for virtual table offset.
+Set voffset to -1 (not 1) for static member functions.
+expread.y:
+Changed parsing/lexing of names to avoid doing symbol lookup twice
+(once when lexing to determine symbol class, once for real).
+Now only call symbol_lookup once. Fields of 'this' win especially big.
+printcmd.c:
+Subpress printing addr twice in the case of 'x/s addr'.
+symtab.c:
+lookup_basetype_type is no longer used.
+Add find_methods as recursive helper function to decode_line_1.
+This allows multiple inheritance to work.
+Also, once one or more matches has been found, do not look in
+base-classes. (Baseclass methods would be overridden, anyway.)
+symtab.h:
+Removed baseclasses array in struct type.
+Instead of using baseclasses[i], use fields[i-1].
+Added virtual_field_bits[i] to indicate if the i'th baseclass is virtual.
+Changed sign convention of voffset (previous was inconsistent).
+tm-news.h:
+Some macros (CALL_DUMMY and relatives) were missing. Put them back.
+utils.c:
+Used to assume existence of vsprintf. Re-written to not need it
+if HAVE_VPRINTF is undefined.
+valops.c:
+typecmp was too pessimistic. Made it less so.
+valprint.c:
+Don't print space after address.
+If vtable points to a misc symbol (with 0 offset), print it,
+since that indicates the actual class of the object.
+Changed ype_print_derivation_info to use new inheritance
+scheme (without baseclasses vector).
+values.c:
+In value_primitive_field, fixed some bugs left over from previous set of fixes.
+Also, changes needed because TYPE_BASECLASSES were removed.
+xm-news.h:
+REGISTER_U_ADDR didn't work for PC. Rewrote to use an array.
+
+Tue Aug 21 20:08:54 1990 John Gilmore (gnu at cygint)
+
+ * source.c:
+ If there is no path set, and the symbols don't indicate what directory
+ a file was compiled in, look in the current directory. But either
+ a path or a known compilation directory will prevent this.
+
+ * dbxread.c:
+ Three independent bug fixes:
+ * Remove the #if 0 block that breaks some stuff.
+ * SunOS 4.1 fixed the promoted-parameter-wrong-addr bug in Sun C;
+ adapt gdb to either SunOS 4.0.* or 4.1.
+ * MAX_OF_TYPE and MIN_OF_TYPE thinko. By tedg@sun, I think.
+
+ * symtab.c:
+ Instantiate the class T when looking for methods in it. (Tiemann@sun)
+
+ * valprint.c:
+ (type_print) Demangle the name being printed.
+ (type_print_base) Handle botched demangling without coredump (tiemann).
+
+ * values.c:
+ (check_stub_method): Document routine.
+ (tiemann) fix bug for no-arg functions
+ Avoid clobbering beyond end of malloc'd storage.
+ Terminate the argument list properly.
+
+Sat Aug 18 01:29:59 1990 Per Bothner (bothner@cs.wisc.edu)
+
+ * Changes merged by John Gilmore:
+
+breakpoint.c:
+ In breakpoint_1, use new print_address_symbolic instead
+ of find_pc_partial_function. (This forces use of assembler-level
+ addresses, and avoids misleading non-mangled source-level names.)
+cplus-dem.c:
+ Generalize ansi argument such that -1 means skip arglist totally.
+ Removed global variable print_ansi_qualifiers (which made
+ code non-reentrant), in favor of extra explicit arguments
+ to internal routines.
+printcmd.c:
+ Add new helper function print_address_symbolic.
+ Use find_pc_misc_function instead of find_pc_partial_function
+ (since we want assembler-level symbols here).
+stack.c:
+ Print unknown function as just "f (...)", not "f (...) (...)".
+ Use new fputs_demangled explicitly.
+symtab.c:
+ Fixed a typing violation (problem: value.h cannot be imported
+ without renaming many variable in this file).
+ lookup_symbol: If no matching misc_func, look for a C++-mangled name.
+ decode_line_1: Moved forward some never-reached code.
+ Made decode_line_2 skip function prologues correctly.
+utils.c:
+ fputs_filtered should not demangle by default.
+ Add new fputs_demangled to demangle on demand..
+valops.c:
+ Change value_struct_elt to use value_primitive_field (using recursive
+ utility function search_struct_field). This allows foo.bar to work
+ for multiple inheritance (so far only for data fields).
+ Change check_field in the same way (recursive helper function
+ to support multiple inheritance).
+ (Note: there are more of these problems that I haven't fixed.
+ Any code that says TYPE_BASECLASS (t, 1) is probably wrong.)
+ value_of_this: 'this' symbol name is now just "this", note "$this".
+valprint.c:
+ Don't print static members.
+ Avoid printing "members of <type>" if there are none.
+ Simplified type_print_derivation_info by merging duplicate code.
+ Remove useless blank lines in type_print_base (ptype command).
+value.h:
+ Added declaration of new routine value_primitive_field.
+values.c:
+ Added value_primitive_field which is generalized version of
+ value_field that can handle multiple inheritance (non-zero offsets etc).
+ Re-implemented value_field to call value_primitive_field.
+
+Fri Aug 17 23:33:44 1990 John Gilmore (gnu at cygint)
+
+ * infcmd.c -- insert else to avoid 'delete env' coredump when you
+ delete the whole environment. Karl Berry reported the bug.
+ * source.c - fix openp to avoid //'s in filenames, which
+ trigger an Emacs bug causing it to not be able to find files
+ when running gdb in a window.
+ * dbxread.c - zap the #if 0 that botches the add-file code.
+ It seems to work a lot better without all the code commented out.
+
+Fri Jul 20 16:58:46 1990 John Gilmore (gnu at cygnus.com)
+
+ * Merge Tiemann's and Ted Goldstein's changes, detailed below,
+ into gdb-3.90.9.
+
+Tue Jul 17 19:34:33 1990 Ted Goldstein (tedg at golem)
+
+ * Makefile - added a ${CFLAGS} to a couple of entries,
+ added remote-sa.sparc.c
+ * added remote.sa-sparc.c, a modification of remote.c
+ which conducts a dialog directly with the SparcStation prom.
+ * breakpoint.c, infrun.c, sparcdep.c added
+ remote_insert_breakpoint(), and remote_remove_breakpoint()
+ to breakpoint.c instead of directly writing breakpoint instructions.
+ * sparcdep.c on remote_debugging,there is no need
+ to remove signle step breakpoint instructions.
+ * main.c added "-epoch" flag and "int epoch_interface" to main.c
+ global variable
+ * printcmd.c - epoch interface sends lisp expressions to open up
+ epoch windows on inspection.
+ * valprint.c - added arrayprint, and addressprint and made adding
+ format controls easier
+ * wait.h added a couple of undef's because we were getting
+ complaints about WSTOPSIG and WTERMSIG begin redefined.
+
+
+Wed Jul 4 05:27:51 1990 Michael Tiemann (tiemann at masham)
+
+ * symtab.c (decode_line_1): Add support for handling method stubs
+ in the type information.
+
+Tue Jul 3 09:39:18 1990 Michael Tiemann (tiemann at masham)
+
+ * values.c (baseclass_addr): Run loop from INDEX+1 to
+ N_BASECLASSES; otherwise, we can still get into a loop.
+ @@ This should be restructured to use a cleaner search strategy.
+
+Sun Jul 1 12:28:51 1990 Michael Tiemann (tiemann at masham)
+
+ * dbxread.c (define_symbol,read_type): Grok GNU C++'s new
+ abbreviation "Tt" for tags which have the same name as their
+ typedecls.
+
+Fri Jun 29 01:03:46 1990 Michael Tiemann (tiemann at masham)
+
+ * symtab.c (list_symbols): add ability to set breakpoints on all
+ the functions which match a particular regular expression.
+
+Tue Jun 26 04:26:29 1990 Michael Tiemann (tiemann at masham)
+
+ * cplus-dem.c (cplus_demangle): New parameter ANSI says whether we
+ should print ANSI qualifiers (such as `const' and `volatile').
+ All callers changed to call with ANSI == 1, except from
+ `check_method_stub', which uses old-style syntax.
+
+ * symseg.h (struct fn_field): Remove unneccessary `args' field.
+ * symtab.h (TYPE_FN_FIELD_ARGS): Redefined.
+
+ * values.c (check_stub_method): New function.
+
+ * cplus-dem.c (do_type): Handle "long long" (encoded as 'x').
+
+ * dbxread.c (read_type): Handle new GNU C++ method type stubs.
+ * valprint (type_print_base): Ditto.
+
+ * symtab.c (gdb_mangle_typename): New function.
+
+Tue Jun 5 00:18:43 1990 Michael Tiemann (tiemann at gzilla)
+
+ * breakpoint.c (catch_command): New function. Provides a
+ mechanism to set breakpoints based on catch clauses.
+ (disable_catch): Similar, but disables breakpoints on catch
+ clauses.
+ (delete_catch): Similar, but deleted breakpoints on catch clauses.
+
+Sun Jun 3 22:54:08 1990 Michael Tiemann (tiemann at gzilla)
+
+ * blockframe.c (blockvector_for_pc): New function.
+ * blockframe.c (block_for_pc): Changed to call
+ `blockvector_for_pc' and get the block itself.
+
+ * stack.c (catch_info): New function. Prints info about
+ exceptions which can be caught in the current frame.
+ * stack.c (print_frame_label_vars): New function. Similar to
+ `print_frame_local_vars'.
+ * stack.c (print_block_frame_labels): Prints out labels that are
+ defined in this frame. These labels are exceptions that can be
+ caught.
+
+ * dbxread.c: Updated to handle N_CATCH symtab types.
+
+Thu May 3 22:10:00 1990 Michael Tiemann (tiemann at teacake)
+
+ * valprint.c (everywhere): TYPE_NAME (TYPE) no longer comes in the
+ form "struct ..." for GNU C++. Don't flush any part of TYPE_NAME
+ when printing the type.
+
+Wed May 2 22:43:04 1990 Michael Tiemann (tiemann at teacake)
+
+ * valprint.c (val_print): Use `baseclass_addr' to access the
+ baseclasses pointed to via the derived class object at VALADDR.
+
+ * values.c (baseclass_addr): New function. Casts derived pointers
+ to baseclass pointers taking virtual baseclasses and multiple
+ inheritance into account.
+
+Sat May 5 12:39:18 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * Version 3.90.9.
+
+Fri May 4 12:12:55 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * breakpoint.c (watch_command, bpstat_stop_status): Deal with
+ exp_valid_block field correctly.
+
+ * infrun.c (wait_for_inferior): When checking "don't even think
+ about breakpoints" if stop_signal == SIGTRAP && trap_expected,
+ also check step_resume_breakpoint.
+ Insert breakpoints and continue (not step) if
+ step_resume_break_address != NULL, even if another_trap.
+ If trap_expected and we enter sigtramp, then set up a
+ step_resume_break.
+ If trap_expected is set when we hit the step_resume_break,
+ set another_trap.
+ When calling resume and trap_expected says tell resume to step
+ (2 places), also check step_resume_break_address.
+
+ * infrun.c (wait_for_inferior): Don't set
+ prev_{pc,sp,func_{start,name}} before calling wait ().
+ Do set them after exiting loop.
+ Move their declarations outside functions.
+ (start_inferior): Initialize them.
+
+Thu May 3 00:15:11 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * infrun.c (wait_for_inferior, after check for trap_expected > 1):
+ Restore old code which distinguishes between trap_expected and
+ running_in_shell, just make the latter take any non-TRAP signal,
+ not just SEGV.
+
+ * values.c (allocate_value): Zero VALUE_OPTIMIZED_OUT flag.
+
+ * Makefile.dist (pinsn.o): Use PINSN_CC to compile.
+ xconfig/3b1 (CC,PINSN_CC): Define.
+
+ * xconfig/altos, altos-dep.c: Rename altos-dep.c to altos-xdep.c.
+
+ * Version 3.90.8
+
+ * breakpoint.c (bpstat_stop_status),
+ infrun.c (wait_for_inferior) [SHIFT_INST_REGS]: New code.
+
+ * param.h, tm-88k.h: Define ADDR_BITS_*.
+ infcmd.c (jump_command, read_pc), infrun.c (wait_for_inferior),
+ printcmd.c (do_one_display): Use them.
+
+ * utils.c: Split #ifdef USG into a USG_UTILS and a QUEUE_MISSING.
+ xm-88k.h: Define USG_UTILS.
+
+Wed May 2 00:05:33 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * printcmd.c (printf_command) [__INT_VARARGS_H]: New code.
+ (printf_command): Add from_tty parameter.
+
+ * valprint.c (value_print): Check VALUE_OPTIMIZED_OUT flag.
+
+ * value.h: Add optimized_out field and change lazy field to
+ char. Add macro VALUE_OPTIMIZED_OUT.
+
+ * i386-pinsn.c: Change from Eirik Fuller to write to stream directly
+ instead of stuffing things in buffers (oappend, etc).
+
+ * breakpoint.c (bpstat_do_actions): If *BSP is set to NULL by
+ execute_command, exit both loops.
+
+ * Makefile.dist: Don't set TARGET_ARCH. Add .c.o rule.
+
+Tue May 1 17:07:23 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * Makefile.dist (RAPP_OBS, rapp),
+ rgdb.c, rserial.c, rudp.c, serial.c, udp.c, xdep.h,
+ remote.h: Added.
+ m68k-xdep.c, coredep.c: Wrap in #if !defined (RDB).
+
+ * valops.c (value_struct_elt), values.c (value_static_field):
+ Change error messages to remove references to `info methods'.
+
+Tue Apr 24 10:25:10 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * More 88k changes:
+ infrun.c (start_inferior): Add START_INFERIOR_HOOK.
+ infcmd.c [SHIFT_INST_REGS]: New code.
+ findvar.c (read_relative_register_raw_bytes): Return a value.
+ infcmd.c (do_registers_info): Check value from
+ read_relative_register_raw_bytes.
+
+ * command.c (delete_cmd): Free the struct cmd_list_element(s)
+ we are removing.
+
+Mon Apr 23 10:42:21 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * More 88k changes:
+ findvar.c (get_saved_register): New function.
+ findvar.c: Rewrite code which called find_saved_register to
+ call get_saved_register instead.
+
+Sun Apr 22 14:47:51 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * valprint.c (val_print): Change error message printed when
+ the type has TYPE_FLAG_STUB set.
+
+ * valprint.c (val_print): Check for TYPE_CODE_UNDEF.
+
+ * findvar.c (write_register): Set register_valid (regno).
+
+ * valops.c (call_function): Check for NULL return from block_for_pc.
+
+Fri Apr 20 11:31:23 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * findvar.c (write_register): Add PREPARE_TO_STORE.
+ {sun3,sparc,symmetry}-xdep.c (PREPARE_TO_STORE): Add.
+ infptrace.c, {mips,pyr,symmetry,sun3,arm,hp300hpux}-xdep.c
+ (store_inferior_registers): Don't call read_register_bytes.
+ symmetry-xdep.c (store_inferior_registers):
+ #if 0 out code to fetch registers.
+
+ * values.c (value_as_long): Call COERCE_ARRAY.
+
+ * tm-sun3.h: Include tm-68k.h not m-68k.h
+
+ * sparc-tdep.c (single_step): Set next_pc, npc4 within
+ if (!one_stepped), not outside it.
+
+ * Changes from Data General for 88k:
+ * coffread.c (read_file_hdr): Add *88*MAGIC.
+ * coffread.c (have_symbol_file_p): New function.
+ * coffread.c [COFF_CHECK_X_ZEROES] [TDESC]: New code.
+ * coffread.c (read_one_sym): If there is more than one
+ aux entry, don't give an error message, just ignore the
+ extra ones.
+ * coffread.c (process_coff_symbol): Replace clipper with
+ BELIEVE_PCC_PROMOTION in #ifdef's.
+ * coffread.c: Define L_LNNO32 if not defined.
+ (enter_linenos): Use it.
+ * blockframe.c: Add INIT_FRAME_PC hook and use it in
+ get_prev_frame_info.
+ m-m88k.h: Use INIT_{FRAME_PC,EXTRA_FRAME_INFO} to do tdesc stuff.
+ Use dummy versions of FRAME_CHAIN_*.
+ * Makefile.dist, xconfig/i386*: Rename M_CLIBS to XM_CLIBS and add
+ TM_CLIBS and CDEPS.
+ tdesc/libdc.o: New target.
+ tdesc.{c,h}, tdesc/*, {t,x}config/m88k: New files.
+
+Thu Apr 12 15:47:00 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * m68k-opcode.h (bras, bsrs): Use "Bw" not "Bg".
+
+Tue Apr 10 20:50:25 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * Version 3.90.7.
+
+ * xm-mips.h (BYTE_ORDER): If not defined, make it LITTLE_ENDIAN.
+
+ * mips-xdep.c ({fetch,store}_inferior_registers): Remove variable
+ offset and just use register_addr (regno, 1).
+ (core_file_command): Remove variable reg_offset and just use
+ register_addr (regno, 0).
+
+ * gdbcore.h [COFF_FORMAT]: #undef a_magic before redefining it.
+
+ * infrun.c ("if (trap_expected && stop_signal != SIGTRAP)", near end
+ of wait_for_inferior): Always pass 0 as first arg to resume.
+ #if 0 out "SIGSEGV in shell" test right above it (now redundant).
+
+ * i386-pinsn.c (oappend_address): New function.
+ (oappend): Make it "static void" and declare at top of file.
+ (OP_J, OP_DIR): Use oappend_address.
+
+Mon Apr 9 15:22:09 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * mips-xdep.c: Include <mips/inst.h> not "mips/inst.h".
+
+ * wait.h [HAVE_WAIT_STRUCT]: Put #defines in #if !defined so that
+ it's OK if they are defined in <sys/wait.h>.
+
+ * findvar.c (fetch_registers): Pass "registers", not "&registers",
+ to remote_fetch_registers.
+
+ * mips-tdep.c (_initialize_mipsdep): Remove hex_disassembler
+ and re-write skip_prologue to use add_set_cmd.
+
+ * Makefile.dist (alldeps.mak): Don't put \ after the last
+ filename in each list.
+
+Sun Apr 8 01:59:19 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * Version 3.90.6.
+
+ * Makefile.dist (alldeps.mak): "XM_FILE" -> "XM_FILE=".
+
+ * valarith.c (value_x_{un,bin}op): use "operator" not "operator "
+ to match dbxread.c change of 16 Mar 90.
+
+ * valarith.c (value_x_unop): Pass &static_memfuncp,
+ not static_memfuncp.
+
+ * breakpoint.c: Add watchpoint stuff.
+ breakpoint.h: Add bpstat_should_step.
+ infrun.c (proceed, wait_for_inferior): Use it.
+ breakpoint.h: Add bpstat_print (and rename old bpstat_print
+ to bpstat_should_print).
+ infrun.c (normal_stop): Use it.
+
+ * value.h: Add value_free. Declare a few functions.
+
+Sat Apr 7 21:43:43 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * dbxread.c (read_dbx_symtab): Remove PROFILE_TYPES code and
+ insert comment suggesting easy shell script equivalents.
+
+ * values.c (unpack_long): Give better error messages for
+ unrecognized sizes of ints and floats.
+
+Fri Apr 6 00:32:21 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * dbxread.c, gdbcore.h (IS_OBJECT_FILE): Check for a_drsize
+ nonzero as well as a_trsize.
+
+ * More places: Use SWAP_TARGET_AND_HOST.
+
+ * valops.c (destructor_name_p): Only skip "struct " if present.
+
+ * main.c (gdb_readline): Return NULL on end of file.
+
+ * sparc-opcode.h: Add jmp 1+2, jmp 1+i, jmp i+1.
+
+ * Makefile.dist: Make expread.tab.c unambiguously be in srcdir.
+
+ * main.c: Split source_command into source_command and
+ read_command_file.
+ (main): Accept "-" as arg to +command for stdin.
+
+ * dbxread.c (psymtab_to_symtab): Don't read string table.
+ (symbol_file_command): Save string table size.
+
+ * Version 3.90.5
+
+ * symtab.c: Remove declaration of lookup_misc_func.
+
+ * mips-pinsn.c: Add use_hex_p stuff (re-worked from Forin stuff).
+
+ * mips-opcode.h: Add bdelay field.
+ mips-pinsn.c: Various changes from Forin, I think to make it look
+ like the MIPS assembler format.
+ mips-tdep.c, mips-xdep.c, mipsread.c: Various changes from Forin.
+
+ * gdbcore.h: Declare register_addr.
+
+ * gdbcore.h: Include <a.out.h>, before trying to redefine N_TXTADDR
+ and friends.
+ various: Don't include both a.out.h and gdbcore.h.
+
+ * Makefile.dist (HFILES): Add param.h
+
+ * utils.c (init_malloc): Moved here from mcheck.c and modified
+ to use the standard mcheck.c
+ Makefile.dist: Modify to reflect new mcheck.
+
+Thu Apr 5 16:38:28 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * valprint.c (val_print, print_hex_chars): Print integers
+ larger than LONGEST.
+
+ * valarith.c (value_sub): Give error message if attempt to
+ subtract something of the wrong type from a pointer.
+
+ * breakpoint.c (bpstat_stop_status): Initialize retval to NULL.
+
+ * i386-tdep.c (i386_pop_frame): Change addr to adr.
+
+Wed Apr 4 05:21:50 1990 Jim Kingdon (kingdon at teenage-mutant)
+
+ * main.c (command_line_input): return NULL on end of file.
+ (execute_command): If p is NULL, return almost right away.
+ (read_command_lines): Treat end of file like "end".
+
+ * printcmd.c (print_frame_args): Change it so num is number
+ of ints of args, not number of args.
+
+ * xm-*.h: Make sure BYTE_ORDER is defined.
+ Also fix various #includes of old names of things.
+
+ * main.c (command_line_input): Fix comment code of 2 Apr.
+
+ * values.c (value_from_long, unpack_long): SWAP_TARGET_AND_HOST.
+ various: Replace {BYTES,WORDS}_BIG_ENDIAN with TARGET_BYTE_ORDER.
+ valarith.c various: SWAP_TARGET_AND_HOST.
+ dbxread.c (READ_FILE_HEADERS): SWAP_TARGET_AND_HOST.
+ (SWAP_SYMBOL): New macro. Use it wherever symbuf_idx is incremented.
+ exec.c (exec_file_command): SWAP_TARGET_AND_HOST.
+
+ * valarith.c (value_subscripted_rvalue): Just bcopy() the
+ appropriate bytes rather than playing strange games with
+ value_from_long.
+
+ * param.h (SWAP_TARGET_AND_HOST): New macro.
+
+ * tm-np1.h (V7_REGNUM): Change from 27 to 26.
+ (REGISTER_VIRTUAL_TYPE): Return correct result for vector regs.
+ gould-tdep.c: New file.
+
+ * Move reading of register before store from
+ findvar.c (write_register) to
+ infptrace.c, *-xdep.c (store_inferior_register).
+
+ * findvar.c (fetch_registers, store_registers): New functions.
+ write_register{,_bytes}: Use store_registers regardless of
+ have_inferior_p.
+ registers_valid: New variable.
+ (supply_register, read_register, etc.): Use it.
+ (read_register_gen): New variable.
+ various: Use read_register_gen rather than read_register_bytes
+ where appropriate.
+ *-xdep.c (fetch_inferior_registers): Remove remote_debugging check.
+ infrun.c (wait_for_inferior, start_inferior): Call registers_changed
+ not fetch_inferior_registers.
+ *-xdep.c (fetch_inferior_registers): Call registers_fetched if
+ not setting registers via supply_register, and if fetching
+ all registers.
+ infptrace.c, *-xdep.c (fetch_inferior_registers): Add param,
+ # of register to fetch (-1 for all).
+ infptrace.c, hp300hpux-xdep.c (fetch_inferior_registers):
+ Actually fetch only those registers needed.
+ value.h: Declare all the extern register functions from findvar.c.
+
+ * coffread.c (read_coff_symtab): Test for specific kinds of GCC
+ labels (LI%.*, LPB%.*, etc), not just ??%.*.
+
+ * coffread.c (record_misc_function): Use mf_text not mf_unknown.
+
+ * utils.c,defs.h (lines_to_list): New function.
+ source.c (select_source_symtab, list_command, forward_search_command,
+ reverse_search_command), stack.c (print_frame_info):
+ Use it instead of 10.
+
+ * munch: If MUNCH_NM variable exists, use it.
+
+ * main.c (initialize_main): Set rl_readline_name.
+ main.c: #include readline.h and #undef savestring.
+ Remove declarations of things declared in readline.h.
+
+ * main.c (gdb_readline): If instream == 0, read from stdin.
+
+ * main.c (main): Only call clearerr if ISATTY. Exit loop if
+ feof (instream).
+
+ * infcmd.c (detach_command): Set inferior_pid to 0 after
+ calling remote_close.
+
+ * main.c (main): If exec and sym files are the same, and there
+ is an error reading execfile, don't try to read sym file.
+
+ * infcmd.c (detach_command) [ATTACH_DETACH]: Don't try to detach
+ from inferior when remote debugging.
+
+ * source.c (reverse_search_command): Change while test from 1 to
+ line > 1.
+
+Tue Apr 3 18:14:14 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * Version 3.90.4.
+
+ * Makefile.dist (gdb.tar.Z): Use -z option to tar rather than
+ creating gdb.tar and calling compress separately.
+
+ * breakpoint.c (read_memory_nobpt): Do not treat bcopy as if it
+ returned an "errno" value.
+
+ * various: Make sure gdbcore.h is not included before a.out.h.
+
+ * Makefile.dist (OPCODES): Add mips-opcode.h.
+
+ * config.gdb: Print lists of {hosts,targets} after finding srcdir.
+ When parsing +{host,target}=, strip off +{host,target}=, not +{x,t}m=.
+
+ * Makefile.dist (gdb.tar): Do {t,x}config not just config.
+
+Mon Apr 2 02:42:23 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * sparc-opcode.h (inc): Fix incorrect lose field.
+
+ * valarith.c (value_subscripted_rvalue): Use TARGET_BYTE_ORDER,
+ rather than checking endianness at runtime.
+
+ * main.c (comand_line_input): Accept comments anywhere, not
+ just at starts of lines.
+
+Sat Mar 31 21:59:35 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * symtab.c (check_stub_type): Call lookup_symbol with 5 args.
+
+Fri Mar 30 15:23:52 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * frame.h: #include param.h.
+ param.h: Protect against multiple inclusion.
+
+ * i386-tdep.c (i386_get_frame_setup): Fix comment about what
+ opcode 0x55 is.
+ If 0x81 or 0x83 is followed by something besides 0xec,
+ put codestream back where it was and return 0.
+ [USE_MACHINE_REG_H]: Include <machine/reg.h> not <sys/reg.h>
+ Move include of a.out.h above <sys/user.h>.
+ (i386_frame_find_saved_regs): Make locals signed.
+ (i386_frame_find_saved_regs, i386_push_dummy_frame, i386_pop_frame):
+ Use REGISTER_BYTES, REGISTER_RAW_SIZE, etc. to deal with floating
+ point registers.
+
+Wed Mar 28 18:33:40 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * Makefile.dist (OTHERS): Add gdb.dvi.
+ (gdb.dvi): New rule.
+
+ * breakpoint.c (_initialize_breakpoint): Clean up docstrings so
+ as not to mention subcommands (e.g. auto-display).
+ Call add_cmd not add_abbrev_cmd for "disable breakpoint" and
+ put it in class_alias.
+
+ * breakpoint.c (set_breakpoint_count): New function.
+ (set_breakpoint, break_command_1): Use it.
+
+ * breakpoint.c (get_number): New function.
+ (*_command, map_breakpoint_numbers): Use it.
+
+ * infptrace.c (write_inferior_memory): Remove remote_debugging
+ stuff (is handled in core.c).
+ (read_inferior_memory): Remove #if 0'd out remote_debugging code.
+
+Tue Mar 27 16:51:27 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * inferior.h: Include frame.h.
+
+ * findvar.c (write_register): Replace sun4 #ifdef with
+ check of CANNOT_STORE_REGISTER.
+ xm-sparc.h: Define CANNOT_STORE_REGISTER.
+
+ * sparc-tdep.c: Remove superfluous declaration of
+ get_breakpoint_commands.
+
+ * breakpoint.{c,h}: Add bpstat stuff.
+ bpstat_do_action: Re-work do_breakpoint_commands into this.
+ main.c (command_loop): Call bpstat_do_action not
+ do_breakpoint_commands.
+ inferior.h, infrun.c, breakpoint.c, infcmd.c:
+ Rework breakpoint_commands and stop_breakpoint
+ stuff to use bpstat instead.
+
+ * infcmd.c (program_info): "info reg"->"info registers".
+
+ * np1-opcode.h: Renamed from npl-opcode.h.
+ gould-pinsn.c: Include np1-opcode.h.
+ Makefile.dist (OPCODES): Change npl-opcode.h to np1-opcode.h
+
+ * coffread.c (read_enum_type): Stop reading when we hit .eos.
+
+Mon Mar 26 15:52:35 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * Version 3.90.3.
+
+ * breakpoint.c (read_memory_nobpt): New function.
+ gdbcore.h: Declare read_memory_{nobpt,check}.
+ mips-tdep.c: Use read_memory_nobpt not breakpoint_shadow_val.
+
+Fri Mar 23 14:26:38 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * inflow.c (terminal_inferior): Reenable commented out
+ inferior_thisrun_terminal check.
+ (terminal_ours_1): If inferior_thisrun_terminal is nonzero,
+ return immediately.
+
+ * Makefile.dist: Rewrite DEPFILES, M_FILE, etc. stuff to deal
+ with host & target separation.
+
+ * config/*: Split into xconfig/* and tconfig/*.
+ *-dep.c: Split into *-xdep.c and *-tdep.c.
+
+ * main.c (main): Always pass two args to xrealloc.
+
+Thu Mar 22 20:29:25 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * Makefile.dist ({,dist}clean): rm {x,t}m.h not param.h
+ xgdb.o: Remove obsolete dependency (now in depend).
+
+ * arm-pinsn.c: Include arm-opcode.h not opcode.h.
+
+ * mips-pinsn.c, mips-opcode.h: New files from Bothner (from
+ release of 24 Jan 90 with mips-opcode.h patch from 1 Feb 90).
+
+ * utils.c (xmalloc): Return NULL on request for 0 bytes.
+
+Wed Mar 21 13:30:08 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * config.gdb: Re-write machine stuff to deal with host & target.
+
+ * xm-altos.h: Don't define HAVE_WAIT_STRUCT.
+
+ * m-*.h: Split into xm-*.h and tm-*.h.
+
+ * infrun.c (wait_for_inferior): Put #ifdef sony_news code
+ in regardless of machine.
+
+ * symtab.c (decode_line_1): Add quotes and capitalize error
+ message "no class, struct, or union named".
+
+ * Makefile.dist (cplus-dem.o): Compile with -Dnounderscore.
+
+ * stack.c (print_frame_info): Use print_symbol to print function name.
+
+ * symtab.c (output_source_filename): Don't print a comma if
+ we are skipping a filename already printed.
+
+Tue Mar 20 10:48:54 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * symtab.c (output_source_filename): Don't print a filename
+ more than once.
+
+ * utils.c (fprint_symbol): New function.
+ defs.h: Decalare it.
+ various: Use fprint_symbol to print symbol names.
+ Makefile.dist (SFILES, OBS): Add cplus-dem.{c,o}.
+
+Mon Mar 19 17:11:03 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * coffread.c (read_file_hdr): Add MC68K??MAGIC.
+
+ * coffread.c (read_coff_symtab): Ignore swbeg and string label
+ symbols.
+
+ * coffread.c (read_coff_symtab): Increment num_object_files
+ in case C_STAT not C_FILE.
+ New variable in_source_file. Set it in case C_FILE.
+ Check it in case C_STAT.
+
+ * coffread.c [FUNCTION_EPILOGUE_SIZE]: New code.
+ m-umax.h (FUNCTION_EPILOGUE_SIZE): Define.
+
+ * config/3b1: New file.
+
+ * config/sun*: Print message warning people to use GAS with GCC.
+
+Sun Mar 18 02:56:40 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * infcmd.c (run_stack_dummy): Change error message.
+
+ * m-68k.h (REGISTER_VIRTUAL_TYPE): Make pc, fp, sp char *.
+
+ * m-mips.h (LONGEST, BUILTIN_TYPE_LONGEST): Remove.
+
+Sat Mar 17 21:27:49 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * mips-dep.c: Remove infptrace.c stuff.
+
+ * m-bigmips.h: New file.
+ m-mips.h [MIPSEB]: Remove *_BIG_ENDIAN stuff.
+
+ * m-sparc.h (FIX_CALL_DUMMY): Do not insert unimp instruction
+ if function was compiled with gcc.
+
+ * m-mips.h: Remove FIX_CALL_DUMMY_ALIGNED and make FIX_CALL_DUMMY
+ use new args.
+
+ * valops.c (call_function): New args to FIX_CALL_DUMMY.
+ m-*.h (FIX_CALL_DUMMY): Take new args.
+
+ * values.c (using_struct_return): New parameter gcc_p.
+ valops.c (call_function): New variable using_gcc.
+ valops.c (call_function) [REG_STRUCT_HAS_ADDR]: New code.
+
+ * m-mips.h, mips-dep.c: New files from Forin.
+ m-mips.h: Replace RETURN_STRUCT_BY_REF with USE_STRUCT_CONVENTION.
+
+Fri Mar 16 13:17:19 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * Makefile.dist: Add some dependencies of m-*.h files.
+ (HFILES): Add m-68k.h.
+
+ * dbxread.c (read_struct_type): Put "operator+" not "operator +"
+ in symtab.
+
+ * core.c: Split read_memory into read_memory_check and read_memory.
+ breakpoint.c (insert_breakpoints): If can't read memory,
+ tell user that error was due to seting breakpoints.
+
+Thu Mar 15 11:47:19 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * infrun.c [COFF_ENCAPSULATE]: Include a.out.encap.h.
+
+ * blockframe.c (FRAMELESS_LOOK_FOR_PROLOGUE): Make it a function.
+ various m-*.h: Call function not macro.
+ frame.h: Declare the function.
+
+Wed Mar 14 02:44:51 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * sparc-dep.c: Include signame.h.
+
+ * sparc-pinsn.c (print_insn): When looking for sethi before
+ delayed branch, call read_memory_noerr not read_memory.
+
+ * m-isi.h, m-sun3.h, m-news.h, m-hp300bsd.h, m-altos.h,
+ m-hp300hpux.h, m-sun2.h: Merge machine stuff except inferior
+ function call stuff into new file m-68k.h. Create m-3b1.h.
+
+Tue Mar 13 21:34:33 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * inflow.c (new_tty): If can't open tty, print error message
+ before exiting.
+
+ * blockframe.c: Remove declaration of psymtab_to_symtab.
+ symtab.h: Declare psymtab_to_symtab.
+ blockframe.c: Remove declarations of block_for_pc and
+ find_pc_function_start.
+ frame.h: Add declarations of block_for_pc and find_pc_function_start.
+ Remove declaration of nonexistent function find_pc_function.
+ values.c: include frame.h instead of declaring block_for_pc.
+
+ * Version 3.90.2.
+
+Mon Mar 12 14:20:06 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * main.c (main): Delete superfluous "e" from long_options.
+
+Sat Mar 10 15:47:23 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * valprint.c (val_print): Print <%d bit integer> not just
+ <large integer>.
+
+ * dbxread.c (error_type): Fix loop that finds '\0' so that on
+ exit, *pp points to the '\0', not the character after.
+ (read_type): Make sure that places which call read_type and then
+ try to read more input stop immediately with another error
+ upon encountering '\0'.
+
+ * dbxread.c (read_range_type): Fix check for large signed
+ integral type to match comment and reality. Set TYPE_LENGTH based
+ on n2bits for signed, n3bits for unsigned.
+
+ * infcmd.c (cont_command): Print warning message if we
+ decide to ignore the argument.
+
+ * gdb.texinfo (attach): @xref{Attach} -> @xref{Remote}.
+
+Fri Mar 9 16:26:47 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * symtab.h (address_class): Reinstate LOC_EXTERNAL with rewritten
+ comment.
+
+ * expread.y (yyerror, parse_c_1): Make yyerror take a char * arg.
+
+ * main.c (symbol_completion_function): Don't call error() on
+ "info jkldskf".
+
+ * m-npl.h (USE_STRUCT_CONVENTION): Change >= to >.
+
+Thu Mar 8 00:19:01 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * symseg.h: Nuke more symseg references including LOC_EXTERNAL.
+ Put contents of symseg.h into symtab.h and remove symseg.h.
+
+Wed Mar 7 18:02:15 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * symtab.h (SYMBOL_LINE): New macro.
+ symtab.c (decode_line_1): Accept variable as well as function.
+ Lookup variable/function in selected block if no file specified.
+ printcmd.c: #if 0 out whereis_command.
+
+ * command.c (do_setshow_command): Call function with additional
+ argument C.
+ main.c (set_history_size_command): Take argument C.
+ (set_verbose): New function to set docstring.
+ (initialize_main): Put set_verbose in command list.
+ command.c (lookup_cmd_1): Accept result_list NULL.
+
+ * valprint.c (_initialize_valprint): Change docstring for
+ "set unionprint" to normal set/show form.
+
+ * command.c (add_show_from_set): Check that docstring starts with
+ "Set " before assuming it does.
+
+ * main.c (show_history): Call cmd_show_list.
+ command.{c,h} (cmd_show_list): New function.
+ command.h: Declare do_setshow_command.
+
+ * command.h (cmd_list_element): New field completer.
+ main.c (symbol_completion_function): Use it.
+ symtab.h: Declare make_symbol_completion_list.
+ command.c (add_cmd): Set completer.
+ main.c, gdbcmd.h (noop_completer): New function.
+ infcmd.c: Set completer for environment functions.
+
+ * symtab.c (types_info, _initialize_symtab): #if 0 out.
+ various: Use fputs_filtered, not fprintf_filtered(%s).
+
+ * valprint.c (type_print_base): Check for integers larger than
+ LONGEST.
+
+ * sun3-dep.c: Include "signame.h" instead of directly declaring
+ sys_siglist.
+
+Tue Mar 6 14:59:34 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * infrun.c (signals_info): Allow argument to be a signal name
+ as well as an expression.
+ (handle_command): Check for error from sig_number.
+
+ * main.c (float_handler): Change error message.
+
+ * inflow.c (create_inferior): If getenv ("SHELL") exists, use it
+ instead of /bin/sh.
+
+ * dbxread.c (read_dbx_symtab, case N_SO): New variable first_symnum.
+ Pass it to {start,end}_psymtab.
+
+ * dbxread.c (read_ofile_symtab): Increment symbuf_idx and symnum
+ when calling process_symbol_pair.
+
+ * symtab.c (sources_info, output_source_filename):
+ Re-write so output_source_filename takes a first parameter
+ instead of a next one.
+
+ * dbxread.c (read_dbx_symtab, case N_SO): When incrementing
+ symbuf_idx, increment symnum also.
+
+ * values.c (set_internalvar_component): Use VALUE_CONTENTS,
+ not VALUE_CONTENTS_RAW.
+
+ * symmisc.c (free_symtab): Don't free filename (now in symbol_obstack).
+
+ * environ.c (init_environ): Copy entire string, including
+ terminating '\0'.
+
+ * value.h, values.c: Rename value_lazy to value_fetch_lazy.
+ values.c (value_of_internalvar): Call value_fetch_lazy.
+
+ * dbxread.c (read_huge_number): Return an error on encountering
+ a large decimal number.
+
+ * dbxread.c (read_huge_number): Reverse sense of overflow test.
+
+ * valprint.c (val_print, case TYPE_CODE_INT): Check for integers
+ larger than LONGEST.
+
+ * dbxread.c (read_ofile_symtab): When calling process_one_symbol,
+ call it with desc and value rather than with bufp->n_{desc,value}.
+
+ * defs.h (LONG_MAX): Define.
+
+ * sun3-dep.c: Declare sys_siglist.
+
+ * infptrace.c: Move include of gdbcore.h after a.out.h
+
+ * Makefile.dist (expread.o, mcheck.o): Remove leading "./" not
+ leading ".".
+
+ * m-hp300hpux.h [!HPUX_VERSION_5]: Define KERNEL_U_ADDR_HPUX.
+ infptrace.c [KERNEL_U_ADDR_HPUX] [KERNEL_U_ADDR_BSD]:
+ Set kernel_u_addr using nlist().
+ m-hp300bsd.h: Define KERNEL_U_ADDR_BSD.
+
+Mon Mar 5 16:52:41 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * dbxread.c (read_dbx_symtab): If value of .o symbol is crazy,
+ don't end psymtab.
+
+ * dbxread.c (read_dbx_symtab): Ignore first of a pair of N_SO
+ when both appear.
+ (start_subfile, start_symtab): Extra parameter dirname.
+ (start_subfile): Use obsavestring, not savestring, for name.
+ various: Call start_{subfile,symtab} with extra argument.
+ (end_symtab): Set dirname field in symtab.
+ (read_ofile_symtab): Call process_symbol_pair on pair of N_SO.
+ (process_symbol_pair): New function.
+ symtab.h (symtab): New field dirname.
+ source.c (open_source_file): New function.
+ source.c: Use open_source_file instead of openp where appropriate.
+
+ * defs.h (TARGET_CHAR_BIT): Define.
+
+Sun Mar 4 13:11:48 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * dbxread.c (fill_symbuf): Print error messages nicely.
+
+ * Makefile.dist (SFILES): Put standalone.c at end.
+
+ * Makefile.dist (alldeps.mak): Put out backslash after arm-convert.s.
+
+ * symtab.{c,h} (builtin_type_error): New type.
+ symseg.h (type_code): Add TYPE_CODE_ERROR.
+ valprint.c (val_print, type_print_base),
+ values.c (using_struct_return, set_return_value):
+ Check for and deal with TYPE_CODE_ERROR.
+ dbxread.c (error_type): New function
+ (read_type and subroutines): Call error_type instead of error.
+
+ * dbxread.c (read_huge_number): New function.
+ (read_range_type): Use read_huge_number and check results
+ to see if it is a large integral type.
+
+ * symmisc.c: Remove symseg stuff.
+
+ * Gould NP1 changes from (or inspired by) chpmjd@gdr.bath.ac.uk
+ dbxread.c (read_dbx_symtab) [N_NBSTS]:
+ Treat this and N_NBLCS like N_LCSYM, etc.
+ (process_one_symbol) [BLOCK_ADDRESS_ABSOLUTE]: New code.
+ m-npl.h (USE_STRUCT_CONVENTION): Add.
+ (IGNORE_SYMBOL): Add 0xa4.
+ (END_OF_TEXT_DEFAULT): Remove.
+ (STRING_TABLE_OFFSET): don't add sizeof(int).
+ [!HAVE_VPRINTF]: Define vprintf to be doprnt, not printf.
+ (BLOCK_ADDRESS_ABSOLUTE): Define.
+ (BREAKPOINT): Pad to size of machine word.
+ (SAVED_PC_AFTER_CALL): Remove ` at start of line (!).
+ (R2_REGNUM): Define.
+ (SP_REGNUM, FP_REGNUM): Switch definitions.
+ (REGISTER_U_ADDR): Use FP_REGNUM in place of SP_REGNUM.
+ (STORE_STRUCT_RETURN, EXTACT_RETURN_VALUE, STORE_RETURN_VALUE,
+ call function stuff):
+ Replace bogus definitions with correct ones for NP1.
+ (CANNOT_EXECUTE_STACK): Define.
+ (FRAME_LOCALS_ADDRESS): Don't add 80.
+ (FRAME_FIND_SAVED_REGS): Also get SP.
+ gould-pinsn.c (findframe): Move framechain declaration outside #if 0.
+ infptrace.c (write_inferior_memory): Check addr against text_end
+ and use PT_WRITE_I or PT_WRITE_D as appropriate.
+ (store_inferior_registers): Don't try to write registers in
+ CANNOT_STORE_REGISTER.
+ m-npl.h (CANNOT_STORE_REGISTER): Define.
+ npl-opcode.h (lil): 0xf8080000 -> 0xf80b0000.
+
+ * munch: Distinguish between BSD and System V nm by actually
+ seeing what output from nm looks like.
+
+Fri Mar 2 13:43:36 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * printcmd.c (print_frame_args): Change highest_offset to point
+ to next unprinted arg.
+
+ * main.c (main): Print "type help for list of commands" along
+ with the version. Follow it with a blank line.
+
+Thu Mar 1 14:49:26 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * valprint.c: Move print_address for function from value_print
+ to val_print.
+
+Wed Feb 28 15:06:12 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * Makefile.dist (m-sun4os4.h): Depend on m-sparc.h
+
+ * Makefile.dist (version.c): Depend on Makefile.dist, not Makefile.
+
+ * Makefile.dist: Change MAKEFILES to Makefiles.
+
+ * symtab.h: Declare get_sym_file.
+ core.c: Include symtab.h.
+
+ * Move signal name stuff from utils.c to signame.c
+ Move signal name stuff from defs.h to signame.h.
+ Makefile.dist (SFILES, HFILES, OBS): Add signame.{c,h,o}.
+
+Mon Feb 26 12:03:12 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * command.c (add_cmd): Don't call savestring on name.
+
+Sun Feb 25 15:52:18 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * printcmd.c (print_frame_args): Make highest_offset an int.
+ New variable args_printed.
+ (print_frame_nameless_args): Remove parameter end and add num
+ and first.
+ (print_frame_args): Change call to print_frame_nameless_args.
+
+Fri Feb 23 21:40:15 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * stack.c (up_command, down_command):
+ Only print stack frame if from_tty.
+
+Thu Feb 22 12:01:36 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * expread.y: Inlcude value.h and don't cast return value from
+ lookup_internalvar.
+
+ * infrun.c: Remove code in #ifdef UMAX_PTRACE.
+
+ * values.c (convenience_info): Print in form "$foo = 5".
+ Don't print "Debugger convenience variables:" before first one.
+
+ * Makefile.dist: Remove ADD_FILES from CLIBS.
+ (gdb, kdb, xgdb): Put in ADD_FILES as well as CLIBS.
+
+ * m-pyr.h: #if 0 out call dummy stuff.
+ Put in POP_FRAME which just calls error().
+ valops.c: If CALL_DUMMY is not defined, put in dummy call_function
+ which just prints an error message.
+
+Tue Feb 20 22:11:40 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * breakpoint.c (commands_command): Add arg from_tty.
+
+ * main.c (main): Put if (!setjmp (to_top_level)) around calls
+ to *_command made in response to command line arguments.
+
+Mon Feb 19 13:58:28 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * main.c (main): Use getopt_long_only. Move one-character options
+ to long_options. Remove entries which are just unambiguous
+ abbreviations of other options.
+
+ * command.h: Add types cmd_types and var_types.
+ Add fields type, var_type, and var to struct cmd_list_element.
+ command.c (add_set_cmd, add_set_from_show): New functions.
+ (add_cmd): Set c->var_type.
+ (add_abbrev_cmd): Call add_cmd instead of duplicating code.
+ main.c: Add showlist.
+ Move parse_binary_operation from main.c to command.c.
+ command.c (do_setshow_command): New function.
+ gdbcmd.h: New file.
+ Makefile.dist: Add gdbcmd.h.
+ many files: Include gdbcmd.h, use add_set_cmd and add_show_from_set.
+ Replace info * with show * where appropriate.
+ utils.c (fputs_filtered): Use UINT_MAX in lines_per_page to mean
+ no paging.
+ defs.h: Define UINT_MAX.
+ infcmd.c (run_command): Use execute_command, not set_args_command.
+ main.c (execute_command): Call do_setshow_command if necessary.
+ main.c (show_command, show_history): New functions.
+ main.c (initialize_main): Call add_prefix_cmd
+ for show and show history.
+
+ * coffread.c (enter_linenos): Print error if
+ file_offset < linetab_offset.
+
+Sun Feb 18 15:37:05 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * convex-dep.c (comm_registers_info): Fix typo. ("argc"->"arg").
+
+Wed Feb 14 20:45:14 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * config.gdb: Create Makefile with make.
+
+ * Makefile.dist, config.gdb: Move "srcdir=" line from Makefile.dist
+ to new file Makefile.srcdir.
+
+ * valprint.c: Include <errno.h>.
+
+ * value.h: Declare value_coerce_function.
+
+ * findvar.c: Add missing " after #include "gdbcore.h
+
+ * main.c (main): Re-write command parsing to use getopt.
+ On "gdb +help" print options with '+' not '-'.
+ Makefile.dist: Add getopt.
+
+Tue Feb 13 00:08:27 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * Makefile.dist: Add "srcdir=."
+ config.gdb: Edit srcdir= rather than adding it to the beginning.
+
+ * pyr-dep.c: Make global_reg_offset, last_frame_offset not static.
+ Move definition of reg_stack_offset to core.c [REG_STACK_SEGMENT].
+
+ * config/pyramid: Print message about alloca.
+
+ * breakpoint.c (clear_command): When printing "no breakpoint"
+ error, only use arg if non-NULL.
+
+ * core.c (read_memory): Rename to read_memory_noerr.
+ (read_memory): New function which calls read_memory and checks for err.
+ gdbcore.h: Declare all extern core.c functions.
+ move myread from core.c to utils.c.
+ declare it in defs.h.
+ (read_memory_integer): move from infcmd.c to core.c.
+ gdbcore.h: Declare it.
+ Many places: Remove error checking on read_memory, or call
+ read_memory_noerr instead. Include "gdbcore.h" if calling either.
+
+ * value.h (COERCE_ARRAY): Coerce functions to function pointers.
+ valops.c (value_coerce_function): New function.
+
+ * core.c, convex-dep.c, arm-dep.c (xfer_core_file): Return EIO
+ if address out of bounds.
+
+ * m-arm.h, arm-dep.c arm-pinsn.c arm-opcode.h: New files.
+ dbxread.c, m-convex.h (VARIABLES_INSIDE_BLOCK): Add gcc_p parameter.
+ Makefile.dist (alldeps.mak): Special case for arm-convert.s.
+ dbxread.c (define_symbol): Check for local based on it not
+ being any one of the known deftypes.
+ values.c (using_struct_return): Use new macro USE_STRUCT_CONVENTION.
+
+ * Makefile.dist, config.gdb: Put in srcdir stuff.
+
+Mon Feb 12 22:46:16 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * breakpoint.c: Add addr_string and cond_string fields to
+ struct breakpoint.
+ (break_command_1): Set them. Use mention ().
+ (mention): Create with code from break_command_1.
+ (breakpoint_re_set): New function.
+ (breakpoint_clear): Remove.
+ (condition_command): Set cond_string.
+ (breakpoint_delete): Free cond_string and addr_string.
+ Declare parse_c_1's type and remove casts to struct expression *.
+ symmisc.c (free_all_symtabs): Don't call breakpoint_clear.
+ dbxread.c, coffread.c (reread_symbols): Call breakpoint_re_set,
+ Include breakpoint.h.
+ breakpoint.h: New file.
+ dbxread.c: Move declaration of symmisc.c functions to symtab.h.
+
+Sun Feb 11 17:29:23 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * symtab.c: Make lookup_block_symtab extern.
+ symtab.h: Declare it.
+ valops.c (value_of_this): Use it.
+
+Fri Feb 9 08:59:37 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * config/hp300hpux: Print message telling people to use gcc.
+
+ * value.h: Declare print_floating.
+ printcmd.c (print_scalar_formatted, case 'f'): Use print_floating.
+ valprint.c (val_print, case TYPE_CODE_FLT): Use print_floating.
+ valprint.c (print_floating): Make this function out of is_nan
+ and the code which was in val_print.
+ Put parentheses around high & 0xfffff.
+ Print sign and fraction for NaN's.
+ Print 17 digits not 16 for doubles.
+ (is_nan): Remove.
+ m-news.h, m-sun3.h: Define IEEE_FLOAT.
+
+ * Rename gld-pinsn.c to gould-pinsn.c.
+ config/{pn,npl}: Change name of gld-pinsn.c
+
+Tue Feb 6 00:25:36 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * infptrace.c: Define PT_ATTACH if not defined.
+ m-hp300hpux.h: Define ATTACH_DETACH.
+
+ * main.c (initialize_main): Change alias class to aliases.
+
+ * dbxread.c: Search and destroy references to symsegs.
+ Also remove some #if 0'd code.
+
+ * core.c: Remove reread_exec.
+ dbxread.c (reread_symbols): New function.
+ dbxread.c (symbol_file_command): Set symfile_mtime.
+ coffread.c: Same.
+ infcmd.c (run_command): Call reread_symbols not reread_exec.
+
+ * valprint.c (val_print): When printing string after char *, print
+ it for "" just like any other string.
+
+ * core.c (reread_exec): New procedure.
+ infcmd.c (run_command): Call reread_exec.
+
+ * coffread.c (symbol_file_command): Add from_tty.
+
+ * dbxread.c (symbol_file_command): Only ask about loading new
+ symbol table if from_tty.
+
+Mon Feb 5 02:25:25 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * inflow.c (inferior_died): Call breakpoint_clear_ignore_counts.
+
+ * Makefile.dist (OBS): Remove dbxread.o and coffread.o.
+
+ * config.gdb: Ignore files ending in '#' in config.
+
+ * stack.c (backtrace_command): Add QUIT to get_prev_frame loops.
+
+Sat Feb 3 22:25:09 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * Makefile.dist (YACC): Don't use -v.
+
+Fri Feb 2 19:26:50 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * createtags: Only change .o to .c at end of name.
+
+ * Makefile.dist (alldeps.mak): new target.
+ (Makefile): add alldeps.mak.
+ (SOURCES): remove PINSNS.
+ (TAGFILES: use ALLPARAM.
+ (gdb.tar): add config/.
+
+ * config.gdb: Check for M_FILE= not #param.h
+ config/*: Make sure M_FILE= exists with space after M_FILE=.
+ Makefile.dist (TAGS): Pass M_FILE and DEPFILES.
+ createtags: Change .o to .c. Remove special tests for dep.c etc.
+
+ * dbxread.c, coffread.c: Don't check COFF_FORMAT and READ_DBX_FORMAT.
+ Makefile.dist: Move {dbx,coff}read.c from SFILES to ALLDEPFILES.
+ config/*: add dbxread.o or coffread.o to depfiles.
+
+ * Makefile.dist (depend): Depend on $(SOURCES), not force.
+
+Thu Feb 1 17:43:54 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * symmisc.c (print_symbol): Print newline after label.
+
+Wed Jan 31 22:35:38 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * dbxread.c (read_addl_syms): Remove code that checks for
+ _etext.
+ Move end_of_text_addr into read_dbx_symtab.
+ (read_dbx_symtab): #if 0 out code which checks for _etext.
+
+Tue Jan 30 15:40:19 1990 Jim Kingdon (kingdon at albert.ai.mit.edu)
+
+ * Makefile.dist (gdb.tar): Use readline's "make readline.tar"
+ instead of having a list of readline files.
+
+ * infrun.c (normal_stop): #if 0 out "you have found a bug in sh".
+
+ * munch (-DSYSV): Check for .text at end of name.
+ Optionally allow extra underscore before initialize.
+ Remove space between #! and /bin/sh.
+
+ * m-merlin.h: Put in clarifying comments about SHELL_FILE.
+ Makefile.dist (install): Execute M_INSTALL.
+ config/merlin: Define M_INSTALL.
+
+Mon Jan 29 04:32:09 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * inflow.c: Change all references to signal handlers from
+ int (*)() to void (*)().
+
+ * main.c: Declare init_signals before use & make it void.
+ Declare initialize_all_files.
+
+ * Makefile.dist (config.status): New target.
+
+Sat Jan 27 00:19:50 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * defs.h (enum command_class): Remove comma after last element.
+
+ * Makefile.dist (gdb.tar.Z): Use compress <foo >bar rather
+ than deleting gdb.tar.Z before starting.
+
+ * dbxread.c (process_one_symbol): Compare context_stack_depth
+ with !VARIABLES_INSIDE_BLOCK, not VARIABLES_INSIDE_BLOCK.
+
+ * mcheck.c: Put whole file in #if defined MALLOC_RANGE_CHECK.
+
+ * mcheck.c (checkhdr): Call fatal_dump_core not abort.
+
+ * mcheck.c: Copy from malloc distribution.
+
+ * main.c (main): Call init_malloc ().
+
+ * main.c (initialize_signals): Rename to init_signals.
+
+Fri Jan 26 00:53:23 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * *dep.c: Make core_file_command return void.
+
+ * gdbcore.h [!KERNEL_U_ADDR]: Declare kernel_u_addr.
+ infptrace.c [!KERNEL_U_ADDR]: Make it extern.
+
+ * altos-dep.c (NBPG, UPAGES): Wrap #define in #if !defined.
+
+ * m-pn.h (GOULD_PN): Define.
+ *-pinsn.c: Include actual opcode table not just opcode.h
+
+ * main.c [ALIGN_STACK_ON_STARTUP]: New code.
+ m-i386.h: Define ALIGN_STACK_ON_STARTUP.
+
+ * m-merlin.h (NO_SIGINTERRUPT, SHELL_FILE): Define.
+
+ * Move code from infptrace [USE_PTRACE_GETREGS] to sun3-dep.c.
+ m-sun{2,3}.h, m-sparc.h: Define FETCH_INFERIOR_REGISTERS.
+
+ * Makefile.dist, config.gdb, config/*:
+ Re-write to use machine-dependent makefiles instead of cpp.
+
+ * m-hp300hpux.h: Define FETCH_INFERIOR_REGISTERS.
+ infptrace.c: Put {fetch,store}_inferior_registers inside
+ #if !defined FETCH_INFERIOR_REGISTERS.
+
+ * Split execcore.c into exec.c and coredep.c.
+ Move a bunch of stuff from coredep.c and *dep.c to gdbcore.h.
+
+ * infptrace.c ({fetch,store}_inferior_registers):
+ Use U_REGS_OFFSET to set offset.
+ m-umax.h: Define U_REGS_OFFSET.
+
+ * m-umax.h: Define PTRACE_{ATTACH,DETACH}.
+
+ * m-i386.h (N_SET_MAGIC): Define.
+ m-i386gas.h: add #undef N_SET_MAGIC.
+
+Thu Jan 25 18:39:45 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * m-hp300bsd.h: Remove KERNEL_U_ADDR.
+
+ * infptrace.c [!KERNEL_U_ADDR]: Get address of kernel u area
+ at runtime.
+
+ * infptrace.c: Replace numbers with PT_KILL, etc.
+ (store_inferior_registers): Loop for as many words are in the register.
+
+ * infptrace.c [NO_SINGLE_STEP]: Call single_step().
+
+ * kill_inferior{,_fast}: Declare as returning void.
+
+ * m-sun3.h (USE_PTRACE_GETREGS): Define.
+
+ * execcore.c: Add IS_OBJECT_FILE & related stuff.
+
+ * infptrace.c: Include <sys/ptrace.h>.
+ [ATTACH_DETACH] [USE_PTRACE_GETREGS]: New code.
+
+ * Split default-dep.c into infptrace.c and execcore.c.
+
+ * valprint.c [IEEE_FLOAT]: Change void * to char *.
+
+ * breakpoint.c: Change printf_filtered(%s) to fputs_filtered.
+
+Wed Jan 24 00:35:52 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * dbxread.c (symbol_file_command): When freeing everything, free
+ the string table too.
+
+ * Makefile.dist (gdb1): add "rm -f gdb1".
+
+ * printcmd.c (print_scalar_formatted): If size is 0, use 'b'
+ 'h', 'w', or 'g' depending on the type.
+
+ * stack.c (backtrace_command): Read in symbols for frames we'll
+ print before printing them.
+
+ * valops.c (value_at): Don't print "I/O error" on EIO from
+ ptrace. Don't print "out of bounds" for any ptrace error
+ except EIO.
+
+ * valprint.c (type_print_base, case TYPE_CODE_ENUM):
+ Print "FOO = 5" not "FOO : 5".
+
+ * symtab.{c,h}: Make lookup_misc_func extern.
+
+ * Makefile.dist: Define VERSION in makefile, and generate
+ version.c automatically.
+ (gdb.tar): Use gdb-$(VERSION), not dist-gdb.
+
+ * expread.y (yylex): Use lookup_primitive_typename to
+ cut down on calls to lookup_symbol.
+ symtab.{c,h} (lookup_primitive_typename): New function.
+ (lookup_typename): Use it.
+
+ * symtab.{c,h} (check_stub_type): New function.
+ valprint.c (type_print_base, val_print, type_print_derivation_info),
+ values.c (allocate_value): Call it.
+
+ * printcmd.c (whereis_command): New function.
+ symtab.c (lookup_symbol): Add symtab parameter.
+ various: Pass additional argument to lookup_symbol.
+ symseg.h (struct symbol): Add line field.
+ dbxread.c (define_symbol): Set sym->line.
+
+ * dbxread.c (symbol_file_command): Read string table into
+ malloc'd memory (symfile_string_table) and leave it there.
+ (psymtab_to_symtab): Use symfile_string_table.
+
+ * utils.c (sig_abbrev): Return NULL if not found.
+ infrun.c (sig_print_{header,info}): Consolidate duplicated
+ code from handle_command, signals_info.
+ (sig_print_info): Just print number if no name from sig_abbrev.
+
+ * Makefile.dist (OTHERS): Add ChangeLog-3.x
+
+ * infrun.c (restore_inferior_status): #if 0 out
+ "Unable to restore previously selected frame" error message.
+
+ * infrun.c (signals_info, handle_command): Print signal
+ abbrevs along with numbers.
+
+ * infrun.c (handle_command): Accept symbol signal names.
+
+ * utils.c (sig_{number,abbrev}, init_sig): New functions.
+ _initialize_utils: Call init_sig for each signal.
+ defs.h: Declare them.
+
+ * default-dep.c (read_inferior_memory): Check quit_flag in
+ fetch loop.
+
+ * Changes for lazy fetching (speeds things up for big objects):
+ value.h (struct value): New field lazy.
+ VALUE_CONTENTS_RAW, VALUE_LAZY, value_at_lazy: New.
+ findvar.c (read_var_value): Set lazy instead of fetching.
+ various: Copy into VALUE_CONTENTS_RAW, not VALUE_CONTENTS.
+ valops.c: Add value_at_lazy, value_lazy.
+ various: Call value_at_lazy instead of value_at.
+
+ * symtab.h (LONGEST): Define.
+
+ * m-*.h (LONGEST, BUILTIN_TYPE_LONGEST): Delete (in symtab.h).
+
+ * infrun.c (wait_for_inferior): #if 0 out stop if ABOUT_TO_RETURN
+
+ * version.c: Change version number to 4.0development
+
+For older changes see ChangeLog-3.x
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/ChangeLog-1991 b/gdb/ChangeLog-1991
new file mode 100644
index 00000000000..199b73f84b7
--- /dev/null
+++ b/gdb/ChangeLog-1991
@@ -0,0 +1,5175 @@
+Mon Dec 30 10:57:02 1991 Per Bothner (bothner at cygnus.com)
+
+ Mainly stuff to improve handling of TYPE_CODE_REF values.
+ * valops.c (value_addr): If taking the addres of a
+ TYPE_CODE_REF, just cast the object to the corresponding
+ TYPE_CODE_PTR. This yields correct C++ semantics, and
+ preserves the location information, which has the nice effect
+ that &(&R) given the location containing R.
+ * values.c (value_copy): Make non-static (used by value_addr).
+ * eval.c (evaluate_subexp_for_address): Use the default
+ scheme (with value_addr) for a variable if it has TYPE_CODE_REF.
+ * valops.c (value_addr), eval.c (evaluate_subexp_for_address,
+ evaluate_subexp_with_coercion): Factor out some common
+ expressions into variables, for easier reading.
+ * findvar.c (locate_var_value): Remove code to handle
+ TYPE_CODE_REF - it should no longer be needed.
+ * valops.c (value_assign): Do a COERCE_REF on the
+ destination operand, for correct C++ semantics.
+ * valarith.c (value_x_binop): Ditto: De-reference C++
+ references in the arguments.
+ * valops.c: ANSI-fy: bcopy->memcpy, bzero->memset.
+
+Sat Dec 28 11:30:26 1991 Per Bothner (bothner at cygnus.com)
+
+ * dwarfread.c, coffread.c: Use INIT_CPLUS_SPECIFIC.
+ * symtab.c (gdb_mangle_name): Recognize and handle
+ constructors specially.
+ * symtab.c (check_stub_method): Test for failure from
+ cplus-demangle by calling error() instead of seg-faulting ...
+
+Fri Dec 27 22:21:30 1991 Fred Fish (fnf at cygnus.com)
+
+ * defs.h: Add definition of null_cleanup()
+
+ * procfs.c: Many small changes to add base support for a new
+ "info proc" command (currently only printing of the address
+ space mapping is implemented) and allow iteration over the
+ address space mapping, calling an arbitrary function for each
+ mapping (used for shared library support).
+
+ * solib.c: Change all ifdefs that checked for "sun" to check
+ for "!SVR4_SHARED_LIBS" instead. Rewrite lookup_base() to
+ handle locating the debug base address even when not currently
+ stopped at the dynamic linker entry point.
+
+ * utils.c: Add null_cleanup() as a known function that does
+ nothing to serve as a base for possibly long cleanup chains
+ with no specific "first cleanup" to serve as an anchor.
+
+ * xm-sysv4.h: Add define of SVR4_SHARED_LIBS
+
+Fri Dec 27 10:11:33 1991 Per Bothner (bothner at cygnus.com)
+
+ * arm-opcode.h, m88k-opcode.h, pn-opcode.h, np1-opcode.h,
+ pyr-opcode.h, tahoe-opcode, vax-opcode.h: Removed -
+ these are all essentially the same as the versions
+ in ../include/opcode. The remaining *-opcode.h here
+ are not quite so obviously the same, and need study.
+ * arm-pinsn.c, gould-pinsn.c, m88k-pinsn.c, pyr-pinsn.c,
+ tahoe-pinsn.c, vax-pinsn.c: Change so these include
+ opcode/FOO.h (actually ../include/opcode/FOO.h)
+ instead of the recenntly departed opcode-FOO.h files.
+ * sparc-pinsn.c: Now that we're using the much tighter
+ opcode table in ../include/opcode/sparc.h, we shouldn't
+ need to sort the opcodes before dis-assembly.
+
+ * symtab.h, symmisc.c: Make cplus_struct_default be const.
+ * symtab.h, buildsym.c: Add and use INIT_CPLUS_SPECIFIC macro.
+ * symmisc.c: Remove unused 'nfields' variable.
+ * buildsym.h: Add extern decl of unknown_symtype_complaint,
+ since it used used by partial-stab.h (included two places).
+ * partial-stab.h: Re-arrange DBXREAD_ONLY #ifdefs so that
+ we should never hit the default case (until new stab codes
+ are added). Hence, we can leave the complaint in the
+ default case in even when DBXREAD_ONLY is off.
+ * partial_stab.h: Recognize a pair of N_SO stabs (one for the
+ directory, one for the filename proper) without peeking ahead.
+ * dbxread.c, mipsread.c: Because of previous change, don't need
+ ugly CHECK_SECOND_N_SO macro.
+ * buildsym.h, dbxread.c, mipsread.c: Make next_symbol_text a
+ macro that invokes a function pointer in next_symbol_text_func.
+ * mipsread.c: Added comments various places to
+ explain what is going on.
+ * mipsread.c (parse_symbol): Support the new (SGI-specific?)
+ symbol types stStruct, stUnion, and stEnum.
+ Also, some fixes in the code for dealing with tags.
+ * mipsread.c: Change handling of startup_file_start and _end
+ - now just use the textlow and texhigh of a psymtab
+ to check if we've found the startup-file.
+ * mipsread.c: Replace s_idx by global cur_sdx in many places.
+ This is so mips_next_symbol_text can get at it.
+
+Thu Dec 26 19:52:01 1991 Fred Fish (fnf at cygnus.com)
+
+ * dbxread.c, symmisc.c: Move add_psymbol_to_plist() from
+ dbxread.c to symmisc and change name to add_psymbol_to_list.
+ Ditto for add_psymbol_addr_to_plist(). Also expand their
+ body to not use ADD_PSYMBOL_VT_TO_LIST.
+
+ * dwarfread.c: Remove add_psymbol_to_list() and convert usages
+ to the ADD_PSYMBOL_TO_LIST macro.
+
+ * ieee-float.c: Change "#ifdef DEBUG" to "#ifdef IEEE_DEBUG"
+ to avoid collision with the DEBUG for ADD_PSYMBOL_VT_TO_LIST.
+
+ * partial-stab.h, symfile.h: Move definitions of the macros
+ ADD_PSYMBOL_TO_LIST and ADD_PSYMBOL_ADDR_TO_LIST from
+ partial-stab.h to symfile.h. They aren't stab specific.
+ Change ADD_PSYMBOL_VT_TO_LIST to use memcpy rather than strncpy.
+
+Tue Dec 24 11:38:08 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Roll VERSION to 4.3.2.
+
+Mon Dec 23 13:54:35 1991 Per Bothner (bothner at cygnus.com)
+
+ * m68k-opcode.h, mips-opcode.h, sparc-opcode.h: Deleted.
+ * m68k-pinsn.c, mips-pinsn.c, sparc-pinsn.c:
+ Include <opcode/FOO.h> instead of <FOO-opcode.h>.
+
+ * symtab.h, symtab.c, coffread.c, dwarfread.c, symmisc.c,
+ dbxread.c: The TYPE_CPLUS_SPECIFIC structure is now only
+ allocated when it is needed. Until it is needed, it points
+ to a shared statically allocated structure.
+
+ * buildsym.h, buildsym.c, dbxread.c: Remove the kludgy code
+ in read_ofile_symtab to recognize two initial N_SO stabs,
+ and let process_on_symbol handle it. This is cleaner, more
+ efficient, and lets mipsread.c share the same code.
+
+ * symfile.h, partial-stab.h: Move ADD_PSYMBOL_VT_TO_LIST
+ and related macros to here ...
+ * dbxread.c: ... from here.
+ * symmisc.c: Move the "overflow" handling from
+ ADD_PSYMBOL_VT_TO_LIST macro into new function extend_psymbol_list.
+ * dwarfread.c: Re-write add_psymbol_to_list to use
+ ADD_PSYMBOL_VT_TO_LIST macro.
+
+ * mipsread.c: Extend mipsread.c to handle stabs-style symbols
+ encapsulated in ecoff symbols. This enable full g++ debugging.
+ * partial-stab.h: Move the code for pre-scanning symbols
+ and building psymtabs to an include file, out from dbxread.c.
+ This way, the same code can also be used by mipsread.c.
+ * dbxread.c, buildsym.h: Various changes to allow some functions
+ to be used by mipsread.c (also some arguable stylistic changes).
+
+ * tm-mips.h: Define BLOCK_ADDRESS_ABSOLUTE, at least for now,
+ since mips-tfile puts relocatable addresses into LBRAC/RBRAC
+ stabs.
+
+ * mipsread.c: Replace code to handle ambiguous tag blocks.
+ Instead of allocating a TYPE_CODE_UNDEF, guess (by looking
+ at types and offsets) if a tag is a struct, union, or enum.
+ Still patch it later if we find out for sure.
+ * mipsread.c: In various ways, replace Forin's
+ ideo-syncratic code by code that fits better with the
+ rest of gdb, for both stabs-based and ecoff-based symtabs.
+ E.g. use end_psymtab; don't do extra passes over FDR table to
+ pre-partition global data; don't use external symbols to
+ create static/global symbols (just put them in the
+ misc_vector); use ADD_PSYMBOL_TO_LIST macro; don't
+ sort psymtabs or symtabs; use obstacks more.
+
+ * symtab.c, mipsread.c, dbxread.c, buildsym.c:
+ ANSIfy: Replace bcopy by memcpy, bzero by memset.
+
+Sun Dec 22 19:31:04 1991 Fred Fish (fnf at cygnus.com)
+
+ * solib.c (locate_base): Fix uninitialized variable that was
+ causing return of random value to callee.
+
+ * config/mh-amix, config/mh-i386v4: Change to find alloca by
+ compiling and linking alloca.c, even when it is not strictly
+ required. Also arrange to link with -ltermlib rather than
+ -ltermcap.
+
+ * Makefile.in: Move TERMCAP definition to prior to inclusion
+ of host makefile fragments so it can be overridden.
+
+Fri Dec 20 16:33:39 1991 John Gilmore (gnu at cygnus.com)
+
+ * xcoffread.c (read_symbol_lineno): Logic error in incrementing
+ symbol table entry number. (From Metin Ozisik.)
+
+Fri Dec 20 11:36:38 1991 Fred Fish (fnf at cygnus.com)
+
+ * config/mh-i386v4: Change XM_CLIBS to "-lc /usr/ucblib/libucb.a"
+ so compiles with native compilers (without builtin alloca) can
+ pick up the version from the bsd emulation library. However, we
+ search the standard C library first so we don't pick up lots of
+ other broken stuff from libucb.a, that we *don't* want.
+
+ * configure.in, tm-amix.h, tm-i386v4.h, xm-amix.h, xm-i386v4.h:
+ Change svr4 references to sysv4.
+
+ * source.c: Move declaration of external function index to
+ front of file so it is in scope for all references.
+
+ * utils.c (error, fatal): Make definitions consistent with
+ defs.h declarations (declared as "volatile void").
+
+Fri Dec 20 10:55:36 1991 John Gilmore (gnu at cygnus.com)
+
+ * rs6k-opcode.h: Bugfix sfe and stbrx. By Al Kossow.
+
+Wed Dec 18 17:09:06 1991 Stu Grossman (grossman at cygnus.com)
+
+ * command.h, defs.h, eval.h, expression.h, remote-sa.sparc.c,
+ sparc-tdep.c, symtab.h, target.h, value.h, vx-share/ptrace.h,
+ vx-share/xdr_ptrace.h, vx-share/xdr_rdb.h: ANSIfy enums.
+
+Mon Dec 16 12:31:46 1991 Fred Fish (fnf at cygnus.com)
+
+ * config/mt-amix, config/mt-i386v4: Add solib.o to TDEPFILES
+ for these SVR4 systems.
+
+ * symfile.c (symbol_file_add): When verbose is set, print
+ the names of files from which symbols are being loaded, as
+ when from_tty is true.
+
+ * solib.c: Completely reorganized (rewritten) to support
+ SVR4 shared libraries in a manner very close to the original
+ SunOS implementation. This support is expected to change and
+ become more general at some future time. The SVR4 version
+ does not yet work for attached processes, for example.
+
+ * dwarfread.c: Arrange in dwarf_build_psymtabs() for the
+ relocation address to be valid whether or not symbols are
+ being read from a shared library or an executable. Use the
+ relocation address recorded in the psymtab when reading
+ full symbol tables (in read_ofile_symtab). Ensure that the
+ relocated address ranges are recorded in partial symtabs.
+
+ * elfread.c: Add new function elf_interpreter() to return the
+ string from the ELF ".interp" section. This is the interpreter
+ that the kernel tries to run and feed the executable to.
+ Expand arguments to record_misc_function to include a type arg.
+ Modify elf_symtab_read() to supply the type arg, and to do symbol
+ relocations for symbols read in from shared libraries.
+
+ * procfs.c: Add new functions proc_base_address() and
+ proc_address_to_fd(), used by shared library support.
+
+ * tm-svr4.h: Add macros to support SVR4 shared libraries.
+ Definitions for SOLIB_ADD, SOLIB_CREATE_INFERIOR_HOOK,
+ CLEAR_SOLIB, and DISABLE_UNSETTABLE_BREAK.
+
+Fri Dec 13 20:11:26 1991 John Gilmore (gnu at cygnus.com)
+
+ * infrun.c, remote-eb.c, remote-nindy.c, remote-vx.c: Remove
+ unused START_INFERIOR_HOOK.
+
+ * remote-eb.c: Change timeout to 24 seconds (*10 fits in byte)
+ to account for slow loading from floppies.
+ (eb_create_inferior): New fn, from eb_start and
+ nindy_create_inferior.
+ (eb_close): Only use log_file if nonzero.
+ (eb_xfer_inferior_memory): If not writing, then read!
+ (eb_read_inferior_memory, eb_write_inferior_memory): Return length.
+ (eb_kill): A new no-op.
+ (eb_mourn_inferior): Remove breakpoints, then generically weep.
+
+Fri Dec 13 16:09:23 1991 Fred Fish (fnf at cygnus.com)
+
+ * breakpoint.c, findvar.c, infrun.c, putenv.c, stack.c: Fix
+ miscellaneous comparisons of integer with NULL that elicit
+ compiler warnings about comparison of integer with pointer, when
+ NULL is ((void *) 0) rather than just a bare 0.
+
+Wed Dec 11 13:02:58 1991 John Gilmore (gnu at cygnus.com)
+
+ * breakpoint.c (breakpoint_re_set_one): Disable each breakpoint
+ while we reset it, in case of problems. Print breakpoint number
+ in error messages.
+
+ * buildsym.c (read_struct_type): Avoid sun3 compiler bug with
+ foo[--n].
+
+ * source.c (find_source_lines): If getting file mod time fails,
+ don't warn.
+
+ * target.c (target_xfer_memory): If errno is set, return it,
+ rather than EIO.
+
+Tue Dec 10 04:07:22 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: infodir belongs in datadir.
+
+Sun Dec 8 21:13:33 1991 Michael Tiemann (tiemann at sphagnum.cygnus.com)
+
+ * symtab.h (struct fn_field): Add new fields `is_private',
+ `is_protected', `is_stub', making room by reducing the size of
+ `voffset'.
+ (struct fn_fieldlist): Delete the fields `private_fn_field_bits'
+ and `protected_fn_field_bits'.
+ (TYPE_FN_{PRIVATE,PROTECTED}_BITS): Deleted.
+ (SET_TYPE_FN_{PRIVATE,PROTECTED}): Deleted.
+ (TYPE_FN_{PRIVATE,PROTECTED}): Deleted.
+ (TYPE_FN_FIELD_{STUB,PRIVATE,PROTECTED}): New macros.
+ * valops.c, valprint.c, symtab.c: All callers updated.
+
+ * buildsym.c (read_struct_type): Delete the `visibility' field
+ from `struct next_fnfield', and rework code so that visibility
+ info is stored into the fn_field directly. Also, hacked to set
+ TYPE_FN_FIELD_STUB for both static and normal member functions.
+
+Sat Dec 7 18:13:11 1991 Fred Fish (fnf at cygnus.com)
+
+ * i386-tdep.c: Fix a problem on i386 systems where buffered code
+ stream access was failing to take into account the minimum size
+ granularity of the code section. For now, the buffering is simply
+ disabled. There is a similar problem in the i386 disassember code
+ that has not yet been fixed (FIXME).
+
+ * gmalloc.c: Use macros to hide some of the ugly casting required
+ in the previously applied fix for pointers with high bits set.
+
+Sat Dec 7 16:49:35 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Roll VERSION to 4.3.1.
+
+Sat Dec 7 04:12:35 1991 John Gilmore (gnu at cygnus.com)
+
+ GDB-4.3 release!
+
+ * Makefile.in: Roll VERSION to 4.3
+ * README, TODO, WHATS.NEW, depend: Update.
+
+ * inflow.c (terminal_inferior): Avoid error msg if attached.
+
+ * gmalloc.c: Fix bug that causes malloc & free to
+ fail on systems where pointers have the high bit set (0x800efcf0
+ for example). The problem is that the difference between two
+ pointers is a signed integer, so the computation
+
+ (char *) 0x800efcf0 - (char *) 0
+
+ yields a negative value. The sign of the result of the modulus
+ operator is machine dependent for negative operands, thus it is
+ possible for it to end up negative. From Fred Fish.
+
+Sat Dec 7 00:00:15 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: install using INSTALL_PROGRAM and INSTALL_DATA.
+ added clean-info. added some standards.text support and made it
+ look like our other Makefiles.
+
+ * configure.in: mark this directory target dependent. configure
+ now runs entirely in objdir so make existence tests and
+ references against ${srcdir}.
+
+Fri Dec 6 08:30:36 1991 Fred Fish (fnf at cygnus.com)
+
+ * dwarfread.c (enum_type, struct_type): Fixes for opaque and
+ anonymous enumerations, structures, and unions. Now passes all
+ the current gdb test suite tests.
+
+Thu Dec 5 22:46:13 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: idestdir and ddestdir go away. Added copyrights
+ and shift gpl to v2. Added ChangeLog if it didn't exist. docdir
+ and mandir now keyed off datadir by default.
+
+Thu Dec 5 21:53:21 1991 John Gilmore (gnu at cygnus.com)
+
+ * symtab.c (decode_line_1): If SKIP_PROLOGUE leaves us in
+ mid-line, be more careful about possibly advancing to the next line.
+
+Thu Dec 5 18:59:51 1991 Michael Tiemann (tiemann at cygnus.com)
+
+ * cplus-dem.c (cplus_demangle): Call `string_need' when
+ null-terminating a partially-computed string.
+
+Thu Dec 5 18:19:43 1991 Fred Fish (fnf at cygnus.com)
+
+ * dwarfread.c (enum_type): Build a correct TYPE_NAME, add a
+ symbol to the symbol table for each member of the enum.
+
+ * dwarfread.c (struct_type): Build a correct TYPE_NAME.
+
+ * dwarfread.c (add_enum_psymbol): New function to extract enum
+ member names and add them to the partial symbol table while
+ building partial symbol tables.
+
+Thu Dec 5 17:31:05 1991 John Gilmore (gnu at cygnus.com)
+
+ * symtab.c (check_stub_method): Must allocate two extra argument
+ slots (one for `this', one for arglist terminator).
+
+Thu Dec 5 10:51:05 1991 Fred Fish (fnf at cygnus.com)
+
+ * inflow.c (child_terminal_info): Supply missing '"' character.
+
+ * buildsym.c (define_symbol): Supply missing parenthesis.
+
+Thu Dec 5 03:34:21 1991 John Gilmore (gnu at cygnus.com)
+
+ * coredep.c (fetch_core_registers): Fencepost error. Fixed by
+ Jay Lepreau <lepreau@cs.utah.edu>.
+
+ * inflow.c: Remember whether GDB has a terminal. Avoid switching
+ terminals back and forth if we don't have one.
+
+ * c-exp.y (parse_number): Zero is not an unsigned int constant!
+ * dbxread.c (read_dbx_symtab): Enum type numbers can be in (1,2) form.
+
+ Improve type parsing.
+ * buildsym.c (define_symbol, read_range_type): Add
+ long_kludge_name that passes the names of range types being
+ defined, down to where we must choose between 'int' and 'long'
+ variants. This fails on Sun C anyway since the compiler itself is
+ confused between int and long.
+ (read_array_type, cleanup_undefined_types): Correct the size of
+ array type whose element-type size isn't immediately known.
+
+ Early preparation to blow away many builtin types, building them
+ on the fly as needed. Don't compare types to builtin types with
+ ==; examine the relevant fields instead.
+ * coffread.c (process_coff_symbol: C_ARG, C_REGPARM): Avoid ==.
+ * buildsym.c (define_symbol, case 'p'): Avoid ==.
+ * valops.c (value_arg_coerce): Avoid ==. Don't assume host and
+ target types are the same.
+ * valprint.c (val_print): I finally understand arrays, remove FIXME.
+
+ * symmisc.c (printpsyms_command): Reduce redundancy, and put all
+ addresses in GDB itself into parens for easy cleanup and diffing.
+
+Wed Dec 4 21:05:30 1991 Fred Fish (fnf at cygnus.com)
+
+ * dwarfread (enum_type): Arrange for the order of enumeration
+ members to match the source code order; not the order in the
+ Dwarf information, which is explicitly reverse order.
+
+Wed Dec 4 18:24:39 1991 John Gilmore (gnu at cygnus.com)
+
+ * main.c (input_from_terminal_p): Check whether GDB has a
+ terminal at all.
+ (initialize_main): Revise doc for `set editing'.
+
+Wed Dec 4 15:36:39 1991 Fred Fish (fnf at cygnus.com)
+
+ * dwarfread.c (struct_type): Handle structures and unions which
+ contain DIE's other than just member dies.
+
+Wed Dec 4 01:59:05 1991 John Gilmore (gnu at cygnus.com)
+
+ * symfile.c (reread_symbols): Avoid kludging mtime_set, now that
+ BFD is fixed.
+
+Tue Dec 3 17:24:57 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: VERSION 4.2.96.
+
+ * main.c (initialize_main): Revise command descriptions.
+ * command.c (show_user): `info user' -> `show user'.
+ * symtab.c (_initialize_symtab): Typo in `info types' desc.
+
+ * coffread.c (coff_symfile_read): Avoid select_source_symtab,
+ since it is not needed and can cause errors when examining ".o"s.
+ (read_coff_symtab, decode_base_type): Use complain, not printf.
+ Print symbol name, not its number.
+ Remove "#if defined(clipper) #define BELIEVE_PCC_PROMOTION", which
+ someday should go in a clipper target config file.
+
+ * symfile.c (compact_misc_function_vector): Handle empty vector.
+ (complain, clear_complaints, syms_from_objfile): Fix complaint
+ formatting.
+ * xcoffexec.c: Change syms_from_objfile caller.
+
+ * sparc-xdep.c: Force tm-file as tm-sparc.h, to make it compile
+ when configured for cross debugging. FIXME, this needs a more
+ general solution.
+
+Mon Dec 2 11:04:05 1991 Per Bothner (bothner at cygnus.com)
+
+ * mips-tdep.c (init_extra_frame_info): Float register
+ 'i' has gdb-internal number 'FP0+i', not '32+i'.
+ * mipsread.c (new_symbol): Translate g++ special
+ symbol "$t" to "this".
+
+Sat Nov 30 21:29:55 1991 Steve Chamberlain (sac at cygnus.com)
+ Changes due to include file renaming:
+
+ * xcoffread.c: internalcoff.h ->coff/internal.c,
+ coff-rs6000.h ->coff/rs6000.h
+ * mipsread.c: coff-mips.h ->coff/mips.h
+ * elfread.c: elf-common.h ->elf/common.h
+ elf-external.h ->elf/external.h,
+ elf-internal.h ->elf/internal.h
+ * dwarfread.c dwarf.h ->elf/dwarf.h
+ * dbxread.c: aout64.h ->aout/aout64.h
+ stab.gnu.h ->aout/stab_gnu.h
+
+ * coffread.c: internalcoff.h ->coff/internal.h
+ * buildsym.c: stab.gnu.h ->aout/stab_gnu.h
+ * depend Updated to take the above into account.
+
+Fri Nov 29 16:59:25 1991 Fred Fish (fnf at cygnus.com)
+
+ * configure.in: Add SVR4 i386 configurations.
+
+ * config/mh-i386v4, config/mt-i386v4, tm-i386v4.h, xm-i386v4.h:
+ New files for i386/SVR4.
+
+ * tm-i386v.h: Allow START_INFERIOR_TRAPS_EXPECTED and
+ DECR_PC_AFTER_BREAK to be predefined by files including
+ tm-i386v.h.
+
+ * i386-tdep.c: Add supply_gregset(), fill_gregset(),
+ supply_fpregset(), and fill_fpregset() functions, which are
+ target dependent support functions for the SVR4 /proc register
+ interface.
+
+ * dwarfread.c (enum_type, struct_type): Expand recognized
+ compiler generated tags to include symbols beginning with '.' as
+ well as '~'.
+
+ * symtab.c (sources_info): Change simple printf of error message
+ to call to error().
+
+Fri Nov 29 16:04:21 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * doc/gdb.texinfo: remove leading comments that survived M4 but
+ described its role in the doc; add one more font to colophon;
+ strengthen disclaimer about unsupported configs.
+
+Wed Nov 27 01:23:41 1991 John Gilmore (gnu at cygnus.com)
+
+ Fix bugs in C++ debugging.
+
+ * symtab.h: target_type is not used in record types.
+ Eliminate TYPE_MAIN_VARIANT and TYPE_NEXT_VARIANT. Eliminate
+ lookup_method_type. Add TYPE_TYPE_SPECIFIC macro.
+
+ * symtab.c (lookup_member_type): Don't chain them up, just
+ allocate one in symbol_obstack when we need one.
+ (allocate_stub_method): Build stub in symbol_obstack.
+ (check_stub_method): Move here from values.c. Don't deallocate
+ stub; overwrite it.
+ (lookup_method_type): Gone now.
+
+ * buildsym.c: Handle g++ v1 stabs a little bit better.
+ Change some C++ parsing error()s to complain()ts.
+ * buildsym.c, findvar.c, printcmd.c, symtab.c: Make unions and
+ structs have the same representation and work the same as far as
+ C++ is concerned.
+ * buildsym.c, symtab.c, values.c: Remove all references to
+ TYPE_MAIN_VARIANT and TYPE_NEXT_VARIANT.
+
+ * valops.c: Improve comments and indentation. Only call
+ check_stub_method when the stub flag is on.
+ * valprint.c: Fix or mark minor bugs and unportabilities.
+
+ * coffread.c (anonymous unions): Allocate a cplus structure.
+
+ * mipsread.c: Eliminate "template" types. Build new, real
+ types whenever we need them. Allocate cplus structures as needed.
+ Bulletproof the type parsing a bit more. Mark storage leaks.
+ (parse_type): Copy TYPE_TYPE_SPECIFIC when copying a real type
+ on top of a partial type.
+
+Fri Nov 22 16:39:57 1991 John Gilmore (gnu at cygnus.com)
+
+ * inflow.c (terminal_inferior): Check the results of ioctl's, and
+ print a message if any of them fail.
+ (terminal_ours_1): Store result of ioctl's for debugging, but
+ don't print (the terminal isn't ours...).
+
+ * tm-tahoe.h (FRAME_ARGS_ADDRESS): No need to offset from frame
+ pointer.
+
+ * m2-exp.y (MAX, MIN): Rename to MAX_FUNC, MIN_FUNC to avoid
+ conflicts with system header files.
+
+Fri Nov 22 08:27:40 1991 John Gilmore (gnu at cygnus.com)
+
+ * Roll VERSION to 4.2.95.
+
+ * buildsym.c, coredep.c, mem-break.c, xcoffread.c: Put <stdio.h>
+ first, before defs.h.
+ * config/mh-i386sco: Override compiler to gcc, print warning.
+ * configure.in: Handle i386-none-aout rather than i386-aout-none.
+ * infptrace.c, language.h, utils.c: Lint.
+ * m2-exp.y: #undef MAX and MIN in case system includes set them.
+ * xm-tahoe.h: Set HOST_BYTE_ORDER. Include system versions of
+ {BIG,LITTLE}_ENDIAN and the INT_MAX family first, to avoid
+ redefinition warnings.
+ * defs.h: Reorder things so that the xm-file gets first crack
+ at #define's, followed by defs.h and then the tm-file.
+ * Makefile.in: Remove spaces after 'ignore exit code' - flags.
+ Late-model BSD 'make's don't cope with them.
+
+Thu Nov 21 23:48:56 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Roll new files into various lists.
+
+Thu Nov 21 18:26:11 1991 Fred Fish (fnf at cygnus.com)
+
+ * dwarfread.c (struct_type): Must initialize the c++ specific
+ portion of union types as well as struct types, since gdb attempts
+ to reference the c++ specific info for both types.
+
+Thu Nov 21 10:23:52 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Roll VERSION to 4.2.90.
+
+ * defs.h: Incorporate param.h into defs.h. All users changed.
+ * param-no-tm.h: Change users to define TM_FILE_OVERRIDE instead.
+ * param.h, param-no-tm.h: Removed.
+ * Update copyrights in all changed files.
+ * dbxread.c, dwarfread.c, inflow.c, infrun.c, m2-exp.y, putenv.c,
+ solib.c, symtab.h, tm-umax.h, valprint.c: Lint.
+ * tm-convex.h, tm-hp300hpux.h, tm-merlin.h, tm-sparc.h,
+ xm-merlin.h: Avoid host include files in target descriptions.
+ * getpagesize.h: Removed, libiberty copes now.
+ * Makefile.in: Remove getpagesize.h, param.h, param-no-tm.h.
+
+ * exec.c (exec_files_info): If `verbose' is set, show file offset
+ as well.
+
+ * main.c: Use getcwd rather than getwd.
+ * standalone.c: Fake getcwd rather than getwd.
+ * xm-*.h: Remove fake values of MAXPATHLEN.
+
+ * xcoffexec.c: Add /* */ to #if 0'd thing to help ANSI.
+
+Wed Nov 20 18:35:56 1991 John Gilmore (gnu at cygnus.com)
+
+ * Remove gdb/hp-include. Support for HP a.out oddities should be
+ in BFD, not in GDB. Move gdb/hp-include/a.out.h to include/a.out.hp.h.
+
+ * infptrace.c, tm-sun386.h: Cashier <a.out.gnu.h>, remove refs.
+
+ * configure.in, xconfig, tconfig, Makefile.in, doc/gdbint.texinfo:
+ Makefile fragments for various hosts and targets now come from
+ gdb/config/mh-* and gdb/config/mt-*. This is for consistency with
+ other config setups.
+
+ * rs6000-pinsn.c, rs6k-opcode.h: Clean up.
+ * rs6k-opcode.def: Delete.
+
+Wed Nov 20 05:04:40 1991 Fred Fish (fnf at cygnus.com)
+
+ * dwarfread.c: Recognize obsolete form of AT_element_list
+ attribute still used by at least one AT&T compiler, and possibly
+ more.
+
+Tue Nov 19 07:53:55 1991 Fred Fish (fnf at cygnus.com)
+
+ * dwarfread.c (enum_type, struct_type): Ignore names invented by
+ helpful compilers for anonymous structs, unions, and enums.
+
+ * c-exp.y, m2-exp.y: Add defines for yymaxdepth, yy_yys, and
+ yy_yyv, so multiple parsers produced by SVR4 versions of yacc
+ can coexist in the same executable without collision.
+
+ * symtab.h: Add declaration for lookup_template_type() to kill
+ compiler warnings about conversions from int to pointer.
+
+Mon Nov 18 17:45:18 1991 Fred Fish (fnf at cygnus.com)
+
+ * procfs.c: Move inclusion of defs.h to before param.h, as in
+ all the other source files that include both. This is required
+ to supply some typedefs that are used in files included by param.h.
+
+ * m68k-tdep.c (m68k_skip_prologue): Add generic m68k support for
+ skipping function prologues, ala the other cpu families (i386,
+ mips, m88k, etc). Add the ability to skip movm and fmovm
+ instructions in the prologues. Still needs support for profile
+ (-p compiled) prologue sequences (FIXME).
+
+ * tm-68k.h: Change SKIP_PROLOGUE macro to use the new generic
+ m68k prologue skipping function by default.
+
+ * tm-altos.h, tm-isi.h: Continue to use the old definition of
+ SKIP_PROLOGUE.
+
+Mon Nov 18 15:12:45 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Remove tdesc stuff, and extra blanks before colons.
+ * blockframe.c: Remove tdesc-related code. Default
+ FRAME_CHAIN_COMBINE.
+ * infrun.c: Remove tdesc-related code.
+ * m88k-tdep.c (frame_chain_combine, init_frame_pc): Remove copies
+ of defaultable things.
+ * tm-m88k.h: New file, common to all Moto 88k target configs.
+ Derived from tm-delta88.h.
+ * tm-delta88.h: Use it.
+ * xm-m88k.h: Common file for 88K hosts. Remove obsolete stuff.
+ * xm-delta88.h: Use it.
+ * tm-*.h: Remove FRAME_CHAIN_COMBINE macros, since all are
+ default.
+ * coffread.c: Remove tdesc stuff.
+ * tconfig/delta88, tconfig/m88k: Remove tdesc stuff.
+ * xconfig/m88k: Rename tm-88k.h to tm-m88k.h.
+
+Mon Nov 18 13:51:37 1991 Per Bothner (bothner at cygnus.com)
+
+ * source.c (open_source_file): If openp fails, try again
+ using just the base (non-directory) part of the filename.
+ This solves various annoying problems, such as when the
+ source was compiled with an absolute pathname - and the
+ source files have moved. Or if the source was compiled
+ using a relative pathname, it can be more convenient
+ to just specific the source directory to the dir command.
+
+Mon Nov 18 00:04:41 1991 Fred Fish (fnf at cygnus.com)
+
+ * cplus-dem.c (munge_function_name): Add missing third arg to
+ instance of call to do_type().
+
+ * dwarfread.c: Changes to match new dwarf.h. Remove
+ AT_deriv_list, AT_loclist, AT_incomplete, AT_const_data,
+ and AT_is_external.
+
+Sun Nov 17 16:20:53 1991 Michael Tiemann (tiemann at rtl.cygnus.com)
+
+ * symtab.h (struct type): Moved C++-specific fields into new type
+ `struct cplus_struct_type'. Now takes 10% less memory. Many
+ macros changed.
+ * symtab.c (init_type): Don't set fields belonging to
+ TYPE_CPLUS_SPECIFIC unless TYPE is TYPE_CODE_STRUCT.
+ * buildsym.c (read_type): Allocate TYPE_CPLUS_SPECIFIC for
+ TYPE_CODE_STRUCT.
+ (read_struct_type): Ditto. Also, add comments about how we can
+ deduce TYPE_VPTR_FIELDNO from inheritance info and fieldname info.
+ * coffread.c (decode_base_type): Allocate TYPE_CPLUS_SPECIFIC for
+ TYPE_CODE_STRUCT.
+ (read_struct_type): Ditto.
+ * dwarfread.c (struct_type): Ditto.
+
+ * symtab.c (read_range_type): Don't set TYPE_MAIN_VARIANT.
+ (lookup_pointer_type): Don't use or set TYPE_MAIN_VARIANT.
+ (lookup_reference_type): Ditto.
+
+ * cplus-dem.c: Many changes made to handle decoding of
+ ANSI-mangled names.
+ * symtab.c (gdb_mangle_name): Mangle/demangle ANSI-mangled names
+ as well.
+
+Fri Nov 15 17:57:59 1991 Stu Grossman (grossman at cygnus.com)
+
+ * mipsread.c (parse_partial_symbols): patch to keep DEC C
+ compiler from making gdb bomb out. Thanks to Ed Santiago!
+
+Thu Nov 14 19:27:30 1991 Fred Fish (fnf at cygnus.com)
+
+ * symfile.c: Add function compact_misc_function_vector() to
+ remove duplicate misc function vector entries. See comments
+ in source for why this is necessary/desirable.
+
+ * dwarfread.c: Add misc function type parameter to internal
+ record_misc_function(). Remove calls to init_misc_bunches()
+ and condense_misc_bunches(), these are now done in elfread.c.
+
+ * elfread.c: Add support for reading bfd canonical symbol tables
+ and generating misc function vector entries for global and
+ absolute symbols. Do calls to init_misc_bunches() and
+ condense_misc_bunches() where they will enclose all calls to
+ record_misc_function(), including those in dwarfread.c.
+
+Thu Nov 14 17:02:11 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * doc/Makefile.in: new targets gdb.me, gdb.ms, gdb.mm
+ (roffable documentation).
+ * doc/gdb.texinfo: embedded hints (as comments) for better
+ texi2roff conversion.
+
+Thu Nov 14 13:18:25 1991 John Gilmore (gnu at cygnus.com)
+
+ * m88k-tdep.c (examine_prologue): Deal with OR instructions
+ that shuffle parameters into other regs.
+ * symtab.c (decode_line_1): Fix bug introduced in Per's change
+ of Nov 12th.
+
+Wed Nov 13 19:51:11 1991 Steve Chamberlain (sac at cygnus.com)
+
+ * Makefile.in, xconfig/delta88 made it install a sysV manual page;
+ gdb.z into the right place.
+
+Wed Nov 13 16:45:13 1991 John Gilmore (gnu at cygnus.com)
+
+ Motorola 88000 port without tears, I mean without tdescs.
+
+ * m88k-tdep.c: Blow away all tdesc stuff.
+ Provide functions for all the frame-related macros in
+ tm-delta88.h. Adopt i960-style EXTRA_FRAME_INFO.
+ (examine_prologue, frame_find_saved_regs, skip_prologue): borrow
+ from i960-tdep.c and adapt to the function prologues on the 88k.
+ (read_next_frame_reg): Borrow from mips-tdep.c.
+ FIXME: frame_locals_address should go away.
+
+ * tm-delta88.h: Dump all the tdesc stuff.
+ Macros for all frame-related stuff call fns of same name.
+ Remove duplicated definitions. FP_REGNUM becomes same as
+ SP_REGNUM.
+
+ * xm-88k.h: Eliminate lots of library dependencies, now handled
+ in libiberty. Eliminate KDB nonsupport.
+
+ * doc/gdbint.texinfo: Add rudiments on frames. FIXME, add more.
+
+
+ * stack.c (frame_info): Mark frameless functions.
+ Print locals address (FIXME, remove if same).
+ * blockframe.c: Comment changes, FIXME after.
+ * coffread.c: Even without TDESC, need to zap "@" symbols.
+ Don't register for wierd format names; change the names in BFD.
+
+ * alloca.c, language.c, tdesc.c: Lint.
+ * tdesc.c, tdesc-lib: FIXME: remove these.
+
+Tue Nov 12 19:30:22 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Add tdesc library support. Fixups to lint,
+ copying.c rules.
+
+Tue Nov 12 13:43:26 1991 Per Bothner (bothner at cygnus.com)
+
+ * symtab.c (decode_line_1): Remove spurious call to operator_chars.
+
+ Allow setting breakpoints on C++ destructors.
+ * valops.c (destructor_name_p): Don't check TYPE_HAS_DESTRUCTOR,
+ since it lies. Rely on callers to catch missing destructors.
+ * symtab.c (decode_line_1): For example (see above), here.
+ * buildsym.c, symtab.h: Remove TYPE_FLAGS_HAS{CON,DE}STRUCTOR
+ flags since they are no longer used.
+
+ Fixes to support C++ methods with functional parameters.
+ * c-exp.y (func_mod rule): Allow (and ignore) list of parameter
+ types in a function type.
+ * eval.c (parse_and_eval_type), value.h: New function,
+ parse_and_eval_type, is based on old code from check_stub_method.
+ But don't actually evaluate the cast, since that calls
+ value_cast(), whcih may fail. Just extract the type
+ from the parsed expression.
+ * values.c (check_stub_method): While looping through the
+ arguments, adjust depth *after* parameter has been handled.
+ Replace call and setup of parse_and_eval with new function
+ parse_and_eval_type.
+
+Tue Nov 12 09:40:07 1991 Fred Fish (fnf at cygnus.com)
+
+ * utils.c, rem-multi.shar: Remove fixed arg count version of
+ concat().
+
+ * altos-xdep.c, arm-xdep.c, coffread.c, command.c, convex-xdep.c,
+ core.c, dwarfread.c, gould-xdep.c, infcmd.c, language.c,
+ m88k-xdep.c, main.c, printcmd.c, pyr-xdep.c, source.c,
+ sun386-xdep.c, symm-xdep.c, umax-xdep.c, values.c, xcoffread.c:
+ Change all instances of use of fixed args concat() to variable
+ args concat() now located in libiberty.
+
+Tue Nov 12 07:23:46 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Add xcoffread.c, xcoffexec.c.
+ * xcoffread.c: New file for handling AIX mangled-coff files.
+ * xconfig/rs6000, tconfig/rs6000: New files.
+ * buildsym.c: Add hooks for xcoffread.c.
+ * rs6000-pinsn.c, rs6000-tdep.c, rs6000-xdep.c, tm-rs6000.h,
+ xm-rs6000.h, rs6k-opcode.def, rs6k-opcode.h: New files.
+ * xcoffexec.c: New file for handling AIX shared libraries.
+
+Mon Nov 11 19:14:31 1991 Fred Fish (fnf at cygnus.com)
+
+ * core.c: Minor rewording of message to user containing name of
+ (and possibly arguments to) the program that generated a core
+ file.
+
+ * elfread.c: Remove the register_addr() stub now that it is no
+ longer needed.
+
+ * procfs.c: Move misplaced #endif for ATTACH_DETACH. Add new
+ fetch_core_registers() function for core file support.
+
+Sat Nov 9 13:37:57 1991 Fred Fish (fnf at cygnus.com)
+
+ * dwarfread.c (dwarf_psymtab_to_symtab): Remove leftover call
+ to do_cleanups() which resulted from a previous change.
+
+ * elfread.c: Re-enable compilation of register_addr() stub
+ whenever it is not supplied by coredep.c
+
+Sat Nov 9 00:40:32 1991 John Gilmore (gnu at cygnus.com)
+
+ Add tracking of object files (that contain symbols) to gdb.
+ This includes a "struct objfile" that owns symtabs and psymtabs
+ that were read in from that binary file.
+
+ * symfile.h: Add struct objfile. Add pointer to the objfile
+ into the struct sym_fns.
+ Replace global `symfile' and `symfile_mtime' with
+ `symfile_objfile'. Add global object_files chain.
+
+ * symfile.c: Move param.h above symtab.h.
+ (sort_misc_function_vector): Add.
+ (syms_from_objfile): Was syms_from_bfd.
+ (symfile_open): Now returns objfile.
+ (allocate_objfile): New.
+ (free_objfile): New, replacing free_all_.*symtabs.
+ (symfile_init): Takes objfile arg, puts it in sym_fns result.
+ (reread_symbols): Searches whole chain of objfiles.
+ (allocate_symtab): Takes objfile as new parameter, chains them.
+ Handle INIT_EXTRA_SYMTAB_INFO.
+ (free_all_psymtabs, free_all_symtabs): Move here from symmisc.c.
+
+ * dbxread.c: Make more errors into complaints.
+ (push_subfile, pop_subfile): Move to buildsym.c.
+ (dbx_symfile_read, dbx_symfile_init, fill_symbuf, read_dbx_symtab,
+ start_psymtab, psymtab_to_symtab_1, read_ofile_symtab,
+ dbx_psymtab_to_symtab, ): Use bfd ops, don't use file descriptor.
+ Pass objfile. Change callers.
+ (fill_symbuf, SWAP_SYMBOL): Take bfd as arg.
+ (read_dbx_symtab): Just wipe out new symbols, not all, on error.
+ (end_psymtab): Blow away psymtab if empty.
+ (process_symbol_pair): Swallow into read_ofile_symtab.
+ (process_one_symbol): Use push_context and pop_context.
+ (virtual_context): Delete #if 0'd obsolete stuff.
+
+ * buildsym.c (end_symtab): Pass objfile.
+ (dbx_lookup_type): Handle null typevector.
+ (dbx_alloc_type): Check file number, not sym number, for -1.
+ (find_symbol_in_list): Add for xcoffread.
+ (start_symtab): Default typevector is empty. Keep reusing same
+ context_stack.
+ (end_symtab): Take objfile argument and pass it to
+ allocate_symtab. Don't make a symtab if no blocks or symbols.
+ Handle empty typevector.
+ (push_context): New function for context stack nesting.
+ (read_type): Mark FIXME where we need to reintroduce type smashing.
+
+ * buildsym.h (pop_context): Macro, paired with push_context.
+ (subfile_stack): Move here from dbxread.c.
+
+ * coffread.c (end_symtab, read_coff_symtab): Take and use objfile arg.
+ (read_coff_symtab): Cleanup by freeing objfile, not all symtabs.
+
+ * mipsread.c (read_mips_symtab, parse_partial_symbols, parse_fdr,
+ new_psymtab, new_symtab): Take and use objfile arg.
+
+ * dwarfread.c (scan_compilation_units, start_psymtab,
+ process_dies, end_symtab, dwarf_build_psymtabs,
+ read_lexical_block_scope, read_func_scope, read_file_scope): Take
+ and use objfile argument.
+ (psymtab_to_symtab_1, read_ofile_symtab): Don't take or use file
+ descriptor. Use BFD internal functions instead.
+ (end_symtab): Call global allocate_symtab.
+
+ * elfread.c, target.c: Minor changes to accommodate objfiles.
+ * symtab.h: partial_symbol_table has no symfile_name member now.
+ (fn_fieldlists voffset): avoid non-int bitfield.
+ (struct symtab): Add objfile * and objfile_chain * of symtabs.
+ (struct partial_symtab): Add objfile * and objfile_chain * of
+ psymtabs. Remove symfile_name.
+
+ * symmisc.c: Lose free_all_symtabs, free_all_psymtabs.
+ (printsyms_command): Rename from print_symtabs. Add selective
+ listing if 2nd argument given. Print objfile info.
+ (printpsyms_command): Rename from print_partial_symtabs. Ditto all.
+ (printobjfiles_command): New; prints objfiles lists, and checks
+ for consistency of symtab, psymtab, and objfile lists.
+
+ * symfile.h, symfile.c, symtab.h: Lint
+
+Fri Nov 8 23:38:48 1991 John Gilmore (gnu at cygnus.com)
+
+ * command.c: Include param.h.
+ * defs.h (warning_setup, warning): Declare.
+ * expprint.c (print_subexp, UNOP_MEMVAL case): Lint.
+ * inflow.c (new_tty): Use USE_O_NOCTTY #define.
+ * language.c, printcmd.c (print_scalar_formatted), signame.c,
+ stack.c: lint.
+
+Thu Nov 7 18:26:15 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * Makefile.in: link with libiberty after libreadline, since
+ readline might want something in libiberty.
+ * m88k-xdep.c: Fixed the register offsets in the ptrace_user
+ struct for BCS 88k machines.
+ * xm-m88k.h: don't define USIZE if already defined.
+ * configure.in: Added delta88 target.
+
+Thu Nov 7 04:51:19 1991 John Gilmore (gnu at cygnus.com)
+
+ * am29k-pinsn.c, am29k-opcode.h: Fix decoding of mtacc, dmac, fmac.
+
+ * tm-*.h: Remove READ_DBX_FORMAT, COFF_FORMAT, and
+ READ_MIPS_FORMAT, which have been unused since BFD. Still
+ remaining is COFF_NO_LONG_FILE_NAMES.
+ * tm-sun3.h, tm-altos.h: Remove detritus accidentally left from
+ function calling code moved to m68k-tdep.c.
+
+Wed Nov 6 17:21:59 1991 John Gilmore (gnu at cygnus.com)
+
+ * coffread.c: Eliminate c_nsyms in favor of c_naux.
+ Complain if no auxents on .bf and .ef FCN symbols, and assume
+ lots of line numbers.
+ (init_linenos, enter_linenos): Use a sentinel at the end of the
+ read-in linenos, to make for a fast, safe loop-end test.
+
+Wed Nov 6 02:54:08 1991 Steve Chamberlain (sac at cygnus.com)
+
+ * coffread.c (read_coff_symtab): coffread used to rely on the
+ x_sym.x_misc.x_lnsz.x_lnno field giving the # of linnos in a
+ function. Two of the formats I'm using (29k and 88k) don't seem to
+ set it. Ths patch to fcn_last_line and (enter_linenos) is an
+ attempt to use the actual size of the linno table in the file to set
+ the number of linenos to process.
+
+Tue Nov 5 22:47:46 1991 Steve Chamberlain (sac at cygnus.com)
+
+ * Makefile.in: put a - infront of the mv y.tab.c c-exp.tab.c and
+ mv y.tab.c m2-exp.tab.c, so that if bison is used, and the files
+ are created in place, so the mv fails, then the make continues.
+
+Tue Nov 5 16:47:47 1991 Per Bothner (bothner at cygnus.com)
+
+ Add C++ as a separate language.
+ * defs.h (enum language): Add language_cplus.
+ * dwarfread.c (end_symtab): Support language_cplus.
+ * c-exp.y: Add new struct language_defn cplus_language_defn.
+ Don't set c to be the default language (see main.c).
+ * c-exp.y (yylex): Only look for field of this if
+ language is C++. (First difference from C!)
+ * language.c: Add case branches for C++ (currently, all
+ the same as C). Also, add c++ to "usage" note for "set lang".
+ * valprint.c (typedef_print). Add case branches for C++.
+ * main.c (main): New way to set initial language: Look at
+ file extension of psymtab containing main(). (Same as we
+ do for symtabs, but avoid loading the symtab yet.)
+ * symtab.c: New routine find_main_psymtab(), used by main()
+ to set initial language.
+ * symfile.c (allocate_symtab): Move code for mapping file
+ extensions-> languages to new deduce_language_from_filename().
+
+ Fix a C++ problem when looking for methods in super-classes.
+ There was confusion between base and derived types.
+ * valops.c (value_fn_field): Change function interface.
+ * values.c: Use new value_fn_field interface.
+
+Mon Nov 4 10:49:33 1991 Per Bothner (bothner at cygnus.com)
+
+ * infrun.c: Fixed typo in comment.
+ * utils.c: All the v*fprintf emulation is now in libiberty,
+ so we can get rid of some junk.
+ * xm-sun3os4.h, xm-sun4os4.h, xconfig/decstation, xconfig/i386sco,
+ xconfig/sun3os4, xconfig/sun4os4: Don`t need HAVE_STRSTR any more.
+ * m68k-pinsn.c (print_insn_arg): Support BB/BW/BL
+ type operands, as used by branch instructions.
+ * gmalloc.c: Fix prototype of memcpy.
+ * elfread.c: Comment out register_addr, since it conflicts
+ with the one in coredep.c.
+ * buildsym.h: Remove extern declarations of two functions
+ that are really static in buildsym.c.
+ * tm-mips.h: Add symbolic names for more registers.
+ * mips-xdep.c (store_inferior_registers): Use new register names.
+ * xm-mips.h: Simplify REGISTER_U_ADDR, since it is now
+ only used for core files, not ptrace. Therefore,
+ the KERNEL_U_ADDR hack is no longer needed.
+ The mapping to ptrace number is now in in mips-xdep.c.
+ * mips-xdep.c: Define REGISTER_PTRACE_ADDR (using the
+ mapping from the old REGISTER_U_ADDR), and use it
+ in {fetch,store}_inferior_registers.
+ * mipsread.c: Rename #include ecoff.h to new name coff-mips.h.
+ * mips-tdep.c (mips_push_dummy_frame, mips_pop_frame):
+ Save/restore FP regs correctly (?).
+ * dbxread.c: Remove duplicate define_symbol and type_synonym_name
+ (these had been previously moved to buildsym.c).
+ Hence, define_symbol becomes extern instead of static.
+ * buildsym.c (read_struct_type): Comment out bogus handling
+ of C++ operator methods. Minor hacking of reading of class
+ contexts. Make define_symbol non-static, so dbxread.c can call it.
+
+Fri Nov 1 11:05:47 1991 John Gilmore (gnu at cygnus.com)
+
+ * mipsread.c (read_mips_symtab, read_the_mips_symtab): Use real
+ filename with error messages.
+ * stack.c (frame_select_command): Rename to select_frame_command
+ to avoid "fr" and "fra" having nonunique completions.
+ * symfile.c (sort_symtab_syms): Ignore sort of zero symtab *.
+ (symfile_init): Print file format name when unable to handle it.
+ (free_named_symtabs): Use BLOCKVECTOR rather than obsolete BLOCKLIST.
+ * symmisc.c (free_symtab): Only free linetable if nonzero.
+ * symtab.h: Remove obsolete BLOCKLIST macros.
+
+Thu Oct 31 18:12:43 1991 Stu Grossman (grossman at cygnus.com)
+
+ * infrun.c (wait_for_inferior): another stepi/nexti fix. Ensure
+ that stop_step is 1 at bottom of main loop. I don't know why this
+ needs to be done, but it helps me sleep better at night.
+
+Sun Oct 27 18:18:39 1991 Stu Grossman (grossman at cygnus.com)
+
+ * main.c (initialize_history): Read history after reading all
+ init files.
+
+Sun Oct 27 14:09:25 1991 John Gilmore (gnu at cygnus.com)
+
+ * buildsym.c: Break out initial malloc sizes.
+ (record_line): Record directly in a subfile. Alloc on demand.
+ (compare_line_numbers): Add from xcoffread.c.
+ (end_symtab): New params say whether to sort pendings and
+ linetable. Patch block stabs if defined. Shrink linetable before
+ allocating the symtab.
+ * buildsym.h: Delete line_vector* and prev_line_number. Add
+ global_stabs and file_stabs for xcoffread.
+ * dbxread.c (start_subfile): Move to buildsym. Change above calls.
+ * symtab.h: LINETABLE(symtab) can now be null. Zap LINELIST.
+ * symmisc.c, symtab.c: Cope with null LINETABLEs.
+
+ * blockframe.c: Pass fromleaf to INIT_EXTRA_FRAME_INFO.
+ * tm-29k.h, tm-88k.h, tm-i960.h, tm-irix3.h, tm-mips.h, tm-pyr.h,
+ tm-sparc.h: Accept fromleaf parameter.
+ * c-exp.y (yyerror): Pass error message if given.
+ * configure.in: Add rs6000 host and target.
+ * inflow.c (new_tty): O_NOCTTY kludge for RS/6000.
+ * symfile.h (entry_point): Add.
+
+Sat Oct 26 00:16:32 1991 John Gilmore (gnu at cygus.com)
+
+ * buildsym.c: New file. Breaks out symbol-table-building routines
+ from dbxread.c, so they can be shared with xcoffread.c.
+ * buildsym.h: New file. Declarations for buildsym.c users.
+ * dbxread.c: Remove large chunks into buildsym.c.
+ * Makefile.in: Add buildsym.c and buildsym.h.
+
+ * symfile.c (syms_from_bfd): New routine.
+ (add_symbol_file): Call it to do the real work.
+ (syms_from_bfd): Initialize entry_point before calling symfile_init.
+ * symtab.h, symfile.c, coffread.c, mipsread.c, dwarfread.c:
+ Avoid declaring or setting entry_point (symfile.h & symfile.c cope).
+
+Fri Oct 25 10:58:16 1991 Mark Eichin (eichin at cygnus.com)
+
+ * cplus-dem.c (cplus-demangle): added support for templates, static
+ data, and the new (correct) mangling for destructors.
+
+ * dwarfread.c: (dwarfwarn): created a varargs version of
+ dwarfwarn, for non __STDC__ compilers.
+
+ * c-exp.y: (yylex): added match for "template" token.
+ (typebase): added TEMPLATE name '<' type '>' clause, for explicit
+ specification of template types.
+
+ * symtab.c: (lookup_template_type): new function for finding
+ templates in symbol table.
+ (type_name_no_tag): changed to explicitly check for s/u/e at the
+ beginning of the symbol - if it is a template, none of these will
+ be there (but the name will still contain spaces.)
+
+Fri Oct 25 18:59:32 1991 Per Bothner (bothner at cygnus.com)
+
+ Various fixes to improve g++ debugging.
+ * symtab.h: Add is_const and is_volatile flags for each method.
+ These are bit fields - take their space from voffset,
+ which shrinks to 30 bits. Since voffset is now a bitfield,
+ make it unsigned for portability. This changes its interpretation
+ slightly: Static methods now have voffset 1 instead of -1,
+ and virtual offsets start at 2, not 1.
+ * symtab.c: Renamed gdb_mangle_typename to gdb_mangle_name,
+ since it now returns an entire magled method name, not just
+ the type part. This avoids some duplication.
+ It also allows us to correctly mangle const and volatile
+ methods (using the new is_const and is_volatile bit fields
+ mentioned above).
+ * valprint.c (type_print_base), values.c (check_stub_method):
+ Simplify by using new gdb_mangle_name.
+ * values.c (value_headof): Fix to correctly handle single
+ inheritance (actually two fixes, either of which suffices).
+ * dbxread.c (read_struct_type): Handle const and volatile
+ method specifiers.
+ * dbxread.c (read_struct_type): Yet one more place where
+ we must handle '\\' continuations.
+ * valprint.c (vtbl_ptr_name): Add final '\0'.
+
+Fri Oct 25 16:06:38 1991 Stu Grossman (grossman at cygnus.com)
+
+ * tm-sparc.h, tm-68k.h (EXTRACT_RETURN_VALUE): fix output of
+ short return values for sparc and 68k. Patch from Paul Eggert.
+
+ * coffread.c, coredep.c, i386-xdep.c: install patches for
+ SysV/386 3.2 from Mauro DePalma.
+
+Fri Oct 25 02:02:13 1991 John Gilmore (gnu at cygnus.com)
+
+ * core.c (core_file_info), exec.c (exec_file_info): Print file
+ type. Use printf_filtered.
+
+ * valops.c (value_fetch_lazy): Avoid 0-length fetches.
+
+Thu Oct 24 23:06:40 1991 Fred Fish (fnf at cygnus.com)
+
+ * dwarfread.c: Add casts to remove compiler warnings.
+
+ * tm-3b1.h, tm-68k.h, tm-altos.h, tm-amix.h, tm-hp300bsd.h,
+ tm-hp300hpux.h, tm-isi.h, tm-news.h, tm-pn.h, tm-sun2.h,
+ tm-sun3.h: Remove locally duplicated code for calling functions
+ in the inferior. The only differences were in the specific trap
+ vectors used and whether or not an fpu was present. These are
+ now handled by appropriate definitions of BPT_VECTOR and
+ HAVE_68881 respectively. Other minor obvious cleanups.
+
+ * valops.c: Correct a minor misspelling.
+
+ * utils.c: Remove local BSD/USG hacks that are now in libiberty.
+
+ * dwarfread.c: Remove prototype for dwarfwarn. Does not work
+ with <varargs.h>.
+
+Thu Oct 24 09:33:44 1991 John Gilmore (gnu at cygnus.com)
+
+ * stack.c (frame_command): Always print. Use new
+ frame_select_command to select a frame without printing.
+
+ * dwarfread.c: Use <varargs.h>, since <stdarg.h> is not portable.
+
+Thu Oct 24 01:32:51 1991 Fred Fish (fnf at cygnus.com)
+
+ * dwarfread.c: New file for DWARF debugging format support.
+
+ * elfread.c: New file for ELF object file format support.
+
+ * procfs.c: New file for SVR4 /proc (process file system) support.
+
+ * tm-amix.h, xm-amix.h, tconfig/amix, xconfig/amix: New files for
+ Amiga UNIX support.
+
+ * xm-svr4.h, tm-svr4.h: New files for SVR4 support.
+
+ * xm-m68k.h: New file for host machines with m68k cpu.
+
+ * Makefile.in: Add elfread.c and dwarfread.c to SFILES_MAINDIR.
+ Add elfread.o and dwarfread.o to OBS.
+
+ * symfile.h: Add "elf" to list of supported formats in comment.
+
+ * c-exp.y, defs.h, symtab.h, valprint.c: Add three new builtin
+ types to gdb, builtin_type_long_double, builtin_type_complex, and
+ builtin_type_double_complex. Add and use new TARGET_SHORT_BIT,
+ TARGET_INT_BIT, TARGET_LONG_BIT, TARGET_FLOAT_BIT,
+ TARGET_DOUBLE_BIT, TARGET_LONG_DOUBLE_BIT, TARGET_COMPLEX_BIT, and
+ TARGET_DOUBLE_COMPLEX_BIT, as the sizes in bits of the indicated
+ types on the target machine (ala the existing TARGET_LONG_LONG_BIT).
+
+ * infrun.c: When using SVR4 /proc interface instead of ptrace(),
+ call proc_set_exec_trap() to setup child to stop at first instruction.
+
+ * inftarg.c: When using SVR4 /proc interface, call proc_wait()
+ rather than wait().
+
+ * m68k-tdep.c: Add new routines supply_gregset(), fill_gregset(),
+ supply_fpregset(), and fill_fpregset(), which are machine
+ dependent support routines for SVR4 /proc interface.
+
+ * utils.c: Add warning_setup() and warning(). Warning() behaves
+ the same as error() except that it returns normally rather than
+ jumping back to command level. Modules that don't want to call
+ warning() for some reason, but want to produce their own warnings,
+ can call warning_setup() to ensure compatibility with the way
+ warning() and error() deal with the terminal.
+
+ * symtab.c: Make internal errors produce more useful messages.
+
+ * tm-68k.h: Move code that is duplicated in almost every single
+ m68k based machine's configuration files to this common file.
+ Duplications in the configuration files still need to be removed
+ (FIXME).
+
+ * infrun.c (child_create_inferior): System V versions must call
+ setpgrp() with no arguments, to comply with prototyping typically
+ in <unistd.h>.
+
+ * munch: Add support for SVR4 style nm output.
+
+ * dbxread.c, mipsread.c symmisc.c, symtab.c: Remove the object
+ file specific fields from the partial symbol table structure and
+ replace them with a pointer to private data for each different
+ flavor of object file reader to initialize appropriately.
+
+Wed Oct 23 09:38:20 1991 John Gilmore (gnu at cygnus.com)
+
+ * xconfig/sun[34]os4: Add note about strstr botch on sunos4.0.3c
+ and previous.
+
+ * mipsread.c (fixup_undef_type): New function. If a struct /
+ union / enum is defined in a header file but nowhere else used,
+ (by typedefing, pointer referencing or declaration) the mipsread code
+ builds the complete tree for the structure but leaves its code as
+ TYPE_CODE_UNDEF as it doesn't know what kind of aggregate it is.
+ Guess its type based on the details of the members.
+
+Tue Oct 22 18:04:32 1991 Stu Grossman (grossman at cygnus.com)
+
+ * infrun.c (wait_for_inferior): Check return value from
+ find_pc_line.
+
+Mon Oct 21 17:47:03 1991 Stu Grossman (grossman at cygnus.com)
+
+ * infrun.c (wait_for_inferior): fix stepi/nexti that was broken
+ by my last edit to this routine.
+
+Mon Oct 21 14:27:43 1991 John Gilmore (gnu at cygnus.com)
+
+ * tm-sun3.h (FIX_CALL_DUMMY): problem with cross debugging.
+ FIX_CALL_DUMMY does unaligned accesses and/or forgets to byte swap
+ the values before putting them into the dummy code. (From Peter
+ Schauer)
+
+Mon Oct 21 10:04:39 1991 Steve Chamberlain (steve at rtl.cygnus.com)
+
+ * configure.in: added ebmon target.
+
+Wed Oct 16 22:49:58 1991 John Gilmore (gnu at cygnus.com)
+
+ GDB-4.2 release!
+
+ * Makefile.in: Roll VERSION to 4.2.
+ * README, TODO, WHATS.NEW: Update.
+
+ * core.c (core_open): Improve error message for bad file.
+ Pass .reg virtual memory address to fetch_core_registers to help
+ it find the registers in the core-file header.
+ * coredep.c (fetch_core_registers): Take new argument, use it,
+ and pass it to register_addr to locate the block of registers.
+ * xm-mips.h: Update KERNEL_U_ADDR for new scheme. Cleanup a bit.
+
+ * dbxread.c (read_dbx_symtab, process_one_symbol): Handle
+ Sequent N_FN_SEQ like everybody else's N_FN.
+
+ * main.c: Circumvent SCO cc bug with #if !!defined(USG).
+ * tm-i386v.h: #endif guck.
+ * xconfig/i386*: Remove -Dgetpagesize()=4096 kludge.
+ * xconfig/i386sco: Add HAVE_STRSTR to avoid ANSI bdeath.
+ * xconfig/tahoe: Add REGEX, which seems to be missing.
+
+ * coredep.c: Add <sys/types.h> for SCOnix.
+ * dbxread.c (read_dbx_symntab): Avoid coredump on malformed file.
+ * printcmd.c (print_formatted): Flush output before disassembly.
+
+Tue Oct 15 20:12:32 1991 Roland H. Pesch (pesch at fowanton.cygnus.com)
+
+ * doc/refcard.tex (sec "Working Files"): consistent metavars and
+ other improvements, due to comments by François Pinard
+ (pinard@iro.umontreal.ca)
+
+ * doc/gdb.texinfo (appendix "Installing GDB"): changes in
+ configure, and improvenets related to Pinard's refcard comments
+
+Tue Oct 15 08:45:12 1991 John Gilmore (gnu at cygnus.com)
+
+ Changes from Fred Fish:
+ * tm-68k.h (FPI_REGNUM): Add.
+ * infrun.c (child_create_inferior): flush stdout and stderr
+ before forking.
+ * configure.in: Handle amigados, amix hosts and targets.
+ * inflow.c: Handle TIOCGLTC_BROKEN for Amiga.
+
+ From Andreas Schwab:
+ * values.c (show_convenience): Use printf_filtered.
+ * main.c (define_command): Check result of lookup_command for
+ exact match.
+ (echo_command): Use printf_filtered, and force output out.
+
+ * dbxread.c (read_enum_type): Avoid Modula-2 kludge that breaks C
+ programs.
+ * i387-tdep.c (double_to_i387): Fix typo for double_to_ieee_extended.
+ * utils.c (_initialize_utils): If !ISATTY, don't paginate.
+ * configure.in, tconfig/decstation, xconfig/decstation: Rename
+ dec3100 to decstation.
+
+Mon Oct 14 13:37:50 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * doc/gdb.texinfo: Catch up to changes recorded here in ChangeLog
+ (nodes Continuing and Stepping; Memory; Targets) clarifications
+ due to Larry Breed
+
+Fri Oct 11 23:27:06 1991 John Gilmore (gnu at cygnus.com)
+
+ * tm-{irix3,mips,nindy960,pn,symmetry,vx960}.h: Move
+ REGISTER_U_ADDR to corresponding xm- file. Sugg. by Peter Schauer.
+
+ * symmisc.c (print_partial_symtabs): Add printpsyms debug cmd.
+
+ * m68k-tdep.c (m68k_push_dummy_frame, m68k_pop_frame): Add
+ generic routines for calling inferior functions.
+
+ * blockframe.c (inside_main_scope, inside_entry_scope): New.
+
+ * copying.awk: Filter formfeeds out of copying & warrantee.
+ Make them available as `show copying' and `show warrantee' also.
+ * main.c (print_gnu_advertisement): Advt `show' commands.
+
+Thu Oct 10 17:25:47 1991 John Gilmore (gnu at cygnus.com)
+
+ * mach386-xdep.c: Even when cross-compiling, leave in the
+ core-file reading code.
+ * core.c (get_core_registers): Avoid coredump if no .reg section.
+
+Wed Oct 9 17:03:34 1991 John Gilmore (gnu at cygnus.com)
+
+ * mipsread.c, coffread.c: initialise TYPE_VPTR_FIELDNO to -1.
+ This avoids coredumps under `set print object on' in value_headof
+ (called erroneously by value_from_vtable_info) for `p &struct'
+ or `p *struct'. From Peter Schauer.
+
+Mon Oct 7 00:06:52 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Roll version to 4.1.2.
+ * dbxread.c: Use aout64.h, not a.out.gnu.h. Get external symbol entry
+ size from BFD (but, FIXME, we don't yet read external nlists's and
+ convert them to internal nlists's before handling them -- we still
+ assume they have the same size and alignment.) Use SET_NAMESTRING
+ everywhere useful.
+ * exec.c (exec_file_command): Move dead coff-encapsulation code
+ to BFD.
+ * m88k-tdep.c, m88k-xdep.c: Remove encap test and #inc <a.out.h>.
+
+Fri Oct 4 22:30:06 1991 John Gilmore (gnu at cygnus.com)
+
+ * configure.in, tm-i386v.h, xm-i386v.h: Intel 386 Mach host port.
+ * xm-i386mach.h, mach386-xdep.c, xconfig/i386mach: New files.
+
+Fri Oct 4 17:04:31 1991 Per Bothner (bothner at cygnus.com)
+
+ More patches from Peter Schauer <pes@regent.e-technik.tu-muenchen.de>:
+ * mips-xdep.c (store_inferior_registers): Don't try to
+ write the (pseudo) FP.
+ * mipsread.c (parse_partial_symbols): Improved algorithm for
+ setting pst->texthigh.
+
+Fri Oct 4 16:47:32 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * doc/Makefile: make TEXINPUTS include . everywhere
+
+Fri Oct 4 00:35:56 1991 John Gilmore (gnu at cygnus.com)
+
+ * coffread.c, dbxread.c, symfile.c, symmisc.c, symtab.h: Remove
+ vestiges of typevectors, which were for symsegs and are no longer
+ used. (From a question by Eliot Dresselhaus
+ <dresselh@RFT30.nas.nasa.gov>).
+
+Thu Oct 3 09:33:26 1991 John Gilmore (gnu at cygnus.com)
+
+ * dbxread.c, coffread.c: static-ize functions that were
+ gratuitiously external. (From Fred Fish.)
+
+ * c-exp.y: sym->class to SYMBOL_CLASS (sym).
+
+ * dbxread.c (dbx_lookup_type): Keep doubling size of typevector
+ until it is large enough.
+
+ * dbxread.c (read_type): Handle error case slightly better.
+ Make complaint message not C++-specific.
+
+Wed Oct 2 17:21:07 1991 Stu Grossman (grossman at cygnus.com)
+
+ * infrun.c (wait_for_inferior): Fix step/next so that you only
+ stop at the beginning of a new line. This fixes various problems
+ with for loops, nested if-else's and switch statements.
+
+Tue Oct 1 06:33:55 1991 John Gilmore (gnu at cygnus.com)
+
+ * symtab.c (lookup_symtab_1, lookup_symbol): "fatal" errors
+ between symtabs and psymtabs become ordinary error()s.
+
+ * dbxread.c (read_dbx_symtab): Relocate end_of_text_addr
+ properly, making "end pc" correct in shared lib psymtabs.
+ (From Guy Harris <guy@auspex.com>.)
+
+Mon Sep 30 13:15:31 1991 John Gilmore (gnu at cygnus.com)
+
+ * dbxread.c: Enable, but soften, const_vol_complaint.
+ (read_dbx_symtab): N_STSYM and N_LCSYM define static vars.
+ Ditto Gould N_NBSTS and N_NBLCS. Also, all types in the psymtab
+ should be file-scope, not global.
+ (read_struct_type): Remove ancient multiple-inheritance warning.
+ (read_range_type): Check base type, complain & patch if undefined.
+ * stack.c (frame_info): Demangle the function name in `info stack'.
+ (From Peter Schauer)
+
+Sat Sep 28 10:02:33 1991 John Gilmore (gnu at cygnus.com)
+
+ * eval.c (evaluate_subexp_for_address): Don't use
+ TYPE_POINTER_TYPE directly (it might be zero if this type has
+ never had a pointer created before); use lookup_pointer_type.
+ * symtab.c (lookup_method_type): Arguments were swapped in all
+ callers, so fix it here. I'm amazed this worked at all!
+
+Fri Sep 27 18:09:31 1991 John Gilmore (gnu at cygnus.com)
+
+ * c-exp.y, m2-exp.y: Define more yysymbols that happen to be
+ "bss" rather than "data" symbols, but which still conflict.
+ * m2-exp.y: Lint.
+
+ * coffread.c (coff_symfile_read): Use xmalloc, not malloc.
+ * core.c (core_files_info): Shorten output.
+ * exec.c (exec_files_info): Ditto.
+ (build_section_table): Ignore zero-length sections.
+ * language.c, printcmd.c: Lint.
+ * language.h (get_frame_language): Declare.
+ * saber.suppress: update.
+ * stack.c (find_relative_frame): Remove complex code that was
+ #if 0'd, stick with simple code. Lint.
+ * saber.suppress: Update a bit.
+ * symfile.c (add_symbol_file_command): Add "?" to question.
+ * utils.c (parse_escape): Avoid \a due to bdead compilers.
+ * value.h: Declare typedef_print.
+
+ * valprint.c (val_print, type_print_base): TYPE_CODE_RANGE less
+ kludgey.
+
+ * nindy-tdep.c (nindy_frame_chain_valid): Use lookup_misc_func.
+ (Reported by Mark Peek <mark@imagen.com>.)
+
+ * solib.c (solib_map_sections): Relocate all sections, even
+ though only the text section's size is tracked. Mark ld_text
+ for eventual elimination as we generalize to N sections.
+
+ * infrun.c (wait_for_inferior): Don't check if the PC is in a
+ call_dummy if we were stopped by a random signal that is being
+ passed to the program. This produced wierd results when calling
+ functions in the inferior and signals (e.g. SIGALRM) were in use.
+
+Tue Sep 24 18:05:30 1991 John Gilmore (gnu at cygnus.com)
+
+ * infrun.c (IN_SIGTRAMP): Not parenthesized properly.
+ Bugfix from Paul Eggert <eggert@twinsun.com>.
+ * tm-ultra3.h (IN_SIGTRAMP): Ditto.
+ * valprint.c (print_floating): Print 9 digits for IEEE floats.
+ From Paul Eggert.
+
+Mon Sep 23 15:50:07 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Roll VERSION to 4.1.1.
+ * source.c (line_info): Peter Schauer fixes a bug I introduced in
+ hex conversion.
+
+Fri Sep 20 16:10:52 1991 John Gilmore (gnu at cygnus.com)
+
+ GDB-4.1 release!
+
+ * Makefile.in (VERSION): Set to 4.1.
+ * language.c (set_language_command): Print useful help message,
+ and restore the language string after giving help.
+ * valprint.c (typedef_print): Print typedef in C or M2.
+ * symtab.c (list_symbols): Use it.
+ * main.c (main): Avoid any output before (gdb) prompt when -q.
+ * language.c (set_language_command): Handle errors by restoring
+ the language string to its current state (fix from A. Beers).
+ * doc/gdbint.texinfo: Roll in information from README. Rearrange
+ "how to install" and "how to print the doc" stuff so it drops
+ easier into README.
+ * configure.in: Rename rtpc CPU to romp to match config.sub.
+ * README, WHATS.NEW, TODO: Update for gdb-4.1.
+
+Fri Sep 20 17:39:14 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * doc/gdb.texinfo: Updates from ChangeLog. set/show write,
+ autoloading shared libs, copyright etc on GDB startup, clean up $_
+ and $__ index refs, set/show listsize and related updates to list
+ cmd. New host/target configs.
+
+Fri Sep 20 15:46:00 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * doc/Makefile: generate aux version-no file doc/gdbVN.m4
+ from main Makefile.in version definition
+ doc/gdb.texinfo: use version recorded in doc/gdbVN.m4 for current
+ GDB version no refs
+ Makefile.in (setup-to-dist): generate doc/gdbVN.m4
+
+ * doc/gdb.texinfo: merge new language-switching and lang-specific
+ doc by Andrew Beers
+
+Fri Sep 20 15:00:57 1991 Per Bothner (bothner at cygnus.com)
+
+ * mcheck.c: Add __ONEFILE kludge to allow compilation by non-ANSI
+ compilers (which may lack stddef.h).
+
+Fri Sep 20 13:29:42 1991 John Gilmore (gnu at cygnus.com)
+
+ * dbxread.c (read_dbx_symtab, process_one_symbol): N_FN and
+ N_WARNING are the same except for the N_EXT bit, so just use their
+ values alone, rather than OR-ing them with N_EXT.
+
+Fri Sep 20 12:27:55 1991 Stu Grossman (grossman at cygnus.com)
+
+ * mipsread.c (parse_lines): Deal with negative extended line
+ offsets correctly.
+
+ * c-exp.y, m2-exp.y: #define yyerrflag and yynerrs to avoid
+ global symbol conflicts.
+
+Fri Sep 20 02:28:15 1991 John Gilmore (gnu at cygnus.com)
+
+ * .gdbinit: Move 'set complaints' to top, so it runs even in
+ case we aren't debugging GDB.
+ * language.c (_initialize_language): Fix type check and range
+ check documentation strings.
+ * utils.c (!HAVE_VPRINTF): Define vfprintf as a function, so
+ language.c can use it. (Though language.c should really not be
+ handling warnings/errors the way it does, FIXME.)
+ * symtab.c (lookup_primitive_type): const lint.
+
+ Bugfix from Peter Schauer:
+ * source.c (lines_to_list): Make signed, to avoid comparison
+ going unsigned and complaining that -3 is too high for 21 lines.
+ * stack.c (lines_to_list): Ditto.
+
+Thu Sep 19 23:33:41 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in (HFILES): Add minimon.h.
+ (VERSION): Roll version number to 4.0.95.
+ (gdb.tar.Z, make-proto-gdb.dir, setup-to-dist, gdb-XXX.tar.Z):
+ New rules for building distributions. Normal distribution
+ is built by doing `make -f Makefile.in gdb.tar.Z' in the directory
+ one level up from here; it calls make-proto-gdb.dir to build a
+ directory `proto-gdb' which is an image of the release. The old
+ `gdb.tar.Z' rule still works too.
+ * config.sub, configure: Roll in latest from ..
+
+Thu Sep 19 17:41:24 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * doc/gdbint.texinfo: Reorder contents; reorganize new-host,
+ new-target, and new-config chapters; fix minor typos; come closer
+ to usual GNU markup conventions for @file @samp @code @var.
+
+Thu Sep 19 17:04:12 1991 Per Bothner (bothner at cygnus.com)
+
+ Patches from Peter Schauer <pes@regent.e-technik.tu-muenchen.de>:
+ * mipsread.c (parse_partial_symbols): Enter the name of all
+ structs/unions... into the psymtab so we can access them if the
+ symtab is not read in.
+ * mips-tdep.c: Remove some unneeded #includes.
+ * xconfig/dec3100: Add HAVE_STRSTR.
+
+Thu Sep 19 15:14:23 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Circumvent Sun Make bug on *-exp.tab.o.
+ * c-exp.y, m2-exp.y: Lint.
+ * m2-exp.y: Avoid using yytname[] which is a Bison-ism.
+ * valprint.c (val_print_fields): Check for stub type.
+ * mipsread.c (_initialize_mipsread): Avoid using
+ builtin_type_void at initialize time.
+ (mipscoff_symfile_read): use it now.
+
+Wed Sep 18 15:55:51 1991 John Gilmore (gnu at cygnus.com)
+
+ Merge multiple-language support, and partial Modula-2 support,
+ from Andrew Beers <beers@cs.buffalo.edu>.
+
+ * i387-tdep.c: New file, consolidates most 80387 support,
+ and eliminates host dependency on double<->extended conversions.
+ * i386-xdep.c, symm-xdep.c: Remove most 387 support.
+ * xconfig/i386{sco,v,v-g,v32,v32-g}: Now need i387-tdep.o.
+
+ * symfile.c (allocate_symtab): New fn, consolidates the work
+ of allocating and initializing a new struct symtab. Set the
+ language of the symtab based on its filename extension.
+ * symfile.h: Declare it.
+ * mipsread.c (new_symtab): Use it. Minor formatting changes.
+ * dbxread.c (end_symtab): Use it.
+
+ * mipsread.c (parse_symbol, case stParam and stProc): Add #if 0'd
+ code for saving types of parameters with each function definition.
+ * dbxread.c (define_symbol, function and parameter cases): Ditto.
+ (read_dbx_symtab, case N_DEFD): Ignore.
+ (read_enum_type): Recognize FALSE/TRUE enum as Modula-2 BOOLEAN.
+ (read_range_type): Rename MAX_OF_TYPE to MAX_OF_C_TYPE, etc.
+ #if 0 out its uses, though, since they set a dead value.
+ * coffread.c (end_symtab): Use allocate_symtab.
+ (process_coff_symbol): #if 0'd for functions and params as above.
+ (read_enum_type): Recognize Modula-2 BOOLEAN.
+ * symtab.c (add_param_to_type): #if 0'd function to add a
+ parameter type to a function type's field list.
+
+ * defs.h (local_hex_format, local_hex_string, *_custom): Add.
+ * i386-xdep.c, pyr-tdep.c, pyr-xdep.c, remote-vx.c, solib.c,
+ source.c, symfile.c, dbxread.c, breakpoint.c, core.c, exec.c,
+ i387-tdep.c, infcmd.c, mips-tdep.c, stack.c, printcmd.c: Output
+ hex with local_hex_string for Modula-2 support.
+
+ * breakpoint.c (breakpoint_cond_eval): Use new value_true to test
+ breakpoint condition language-independently.
+
+ * parse.c: New file with the common code remains of expread.y.
+ * parser-defs.h: New file with common declarations from expread.y.
+ * c-exp.y: New file with the C parser from expread.y, and other
+ language-specific information.
+ * m2-exp.y: New file with the Modula-2 parser and etc.
+ * expread.y, expread.tab.c: Remove.
+ * breakpoint.c, eval.c, printcmd.c, expression.h: Use
+ parse_expression and parse_exp_1 rather than parse_c_expression
+ and parse_c_1.
+
+ * symtab.h (enum languages): Move to defs.h.
+ (enum type_code): Add TYPE_CODE_CHAR and TYPE_CODE_BOOL.
+ Declare Modula-2 builtin types.
+ Add MAX_OF_TYPE and MIN_OF_TYPE macros.
+
+ * symtab.c (_initialize_symtab): Remove builtin type
+ definition and initialization to *-exp.y.
+ (lookup_primitive_typename): Use language-dependent vector.
+ (lookup_typename): Fix bug, make it work if primitive typename.
+ (lookup_unsigned_typename): Call above.
+ (create_array_type): Set up range type for array index.
+ (list_symbols): Call typedef_print to print typedefs.
+
+ * values.c (unpack_long, value_from_longest): Handle
+ TYPE_CODE_BOOL and TYPE_CODE_CHAR.
+
+ * expression.h (enum exp_opcode): Add Modula-2 specific opcodes.
+ * expprint.c: Look up expression opcodes in language-specific
+ table, based on expression's language. Handle some Modula-2
+ specific opcodes.
+
+ * stack.c (frame_info): Print language of stack frame.
+ (select_frame): Also select language, if in auto-mode.
+ (get_frame_language): New subroutine.
+ * main.c (execute_command): Warn as language changes automatically.
+
+ * printcmd.c (ptype_command): Parse types using the language
+ parser, both for language-independence, and so that scopes can
+ be specified.
+
+ * language.h, language.c: New files for language-specific macros,
+ declarations, and definitions.
+
+ Misc fixes:
+
+ * main.c (main): If error() is called during early
+ initialization, print its message and then exit(1) from GDB.
+
+ * valprint.c (type_print_base): Avoid printing garbage for ints
+ of unusual sizes.
+ (_initialize_valprint): Warn about host/target size assumption;
+ improve long long support slightly.
+
+ * convex-tdep.c (comm_registers_info): Avoid parsing decimal and
+ hex -- let parse_and_eval_address do it.
+
+ * doc/gdbint.texinfo (Languages): Doc how to add a language.
+
+ * Makefile.in: Cope with new files and removed files.
+
+Tue Sep 17 08:37:41 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Add Andrew Beers' changes for Modula-2 support. His ChangeLog
+ entries are enclosed herein. Not all of these changes
+ have been merged into the master GDB sources -- check the
+ ChangeLog above here for the merge log.
+
+Mon Jun 3 17:05:45 EDT 1991
+
+ m2-exp.y Created. Tested outside of GDB for a few days. Proper
+ operators were added, C specific operators and tokens
+ removed. yylex() revamped to some extent. Still things
+ missing from the grammar, such as sets.
+ Tested for two weeks in GDB v3.5.
+
+Tue Jun 11 17:23:48 EDT 1991
+
+ m2-exp.y Added boolean constants TRUE and FALSE to the grammar
+ so they are built-in. Sort of a hack.
+
+Fri Jun 14 12:53:51 EDT 1991
+
+ m2-exp.y Added range checking for numeric constants. Any numeric
+ constant is assumed to be of builtin type INTEGER unless:
+ (1) it is octal or hexadecimal, in which case it is a
+ CARDINAL; (2) it is too big to fit into an INTEGER, in
+ which case it is a CARDINAL.
+ eval.c Added simple range checking for +, -, and * on integers.
+ Doesn't work very well for *, since 6 * 1,000,000,000 =
+ 1,705,032,704, which fails the simple test of result >=
+ first_operand, no matter in what order the operands are.
+
+Tue Jun 18 14:11:30 EDT 1991
+
+ Broke the parser into parts, one containing the C grammar and the other
+ containing code to be shared by all of the grammars.
+
+ The following files no longer exist:
+
+ expread.y
+ expread.tab.c
+
+ The following files were added:
+
+ c-exp.y (The C grammar)
+ m2-exp.y (The Modula-2 grammar)
+ parser-code.c (Code that is shared by the above grammar)
+ parser-code.h
+ parser-defs.h
+
+ Makefile.dist Changed to reflect the above dependencies. NOTE: It is
+ now necessary to use the Bison compiler compiler, since it
+ will generate function/variable prefixes other than yy.
+
+Tue Jun 18 16:47:49 EDT 1991
+
+ symtab.[ch] Added the external variable working_lang, than holds the
+ value of the current working language.
+ Added the ennumerated type language_mode, with the values
+ language_auto and language_manual, the former meaning that
+ GDB sets working_lang as needed, and the latter meaning
+ that the value of working_lang is totally under user
+ control.
+ symtab.[ch] Added the Modula-2 pervasive types INTEGER, CARDINAL,
+ REAL, BOOLEAN and CHAR. Also added the type codes
+ TYPE_CODE_BOOL and TYPE_CODE_CHAR.
+ utils.c Added set_language_command and show_language_command to
+ implement the GDB support commands "set language" and
+ "show language".
+ expression.h A number of identifiers were added to the type exp_opcode
+ to facilitate Modula-2 builtin functions, integer
+ division, and array indexing.
+
+Wed Jun 19 13:25:58 EDT 1991
+
+ language.h Added the macro STRICT_TYPE, which evaluates to non-zero
+ if the language specified by working_lang requires the use
+ of strict typing of expressions. Eventually, even this
+ will be able to be changed by the user.
+ Added the macro RANGE_CHECK, which evaluates to non-zero
+ if the language specified by working_lang requires the
+ checking of a value against the domain of its type.
+ Eventually, even this will be able to be changed by the
+ user.
+ language.[ch] Predicates involving types (simple_type, ordered_type,
+ same_type, integral_type, numeric_type, character_type,
+ boolean_type, float_type) are added. These predicates are
+ based on the current value of working_lang, and are handy
+ in type-checking.
+
+Wed Jun 19 15:39:34 EDT 1991
+
+ eval.c Added the function type_array_rank which computes the rank
+ of an array type.
+ valarith.c Added the funtion value_bool, which when given a integer
+ value.h value (ie. struct value *) as an argument, it returns a
+ boolean value (ie. struct value *) true if that integer
+ is non-zero, and a boolean value false otherwise.
+ valprint.c Added cases for TYPE_CODE_BOOL, so Modula-2 BOOLEAN values
+ will print out properly.
+
+Wed Jun 19 16:36:34 EDT 1991
+
+ valops.c Added the function value_capitalize, which returns it
+ value.h argument capitalized if its argument is a lowercase
+ letter, or the argument unchanged if its argument is not a
+ letter.
+ valarith.c Added the function range_check_p, which returns non-zero
+ value.h if its value argument is between the integral bounds upper
+ and lower.
+ Added the function range_check_enum_p, which makes sure
+ that its value argument is a valid member of the domain of
+ its type argument.
+ Added the function range_check_range_p, which makes sure
+ its value argument lies between the upper and lower bounds
+ of its type argument, which must be a ranged type.
+ Added the function check_array_index, which range and type
+ checks an index of an array.
+ Added the function value_multi_subscript, which computes
+ array[idx1,idx2...idxN], given a value array and an array
+ of values representing indicies.
+ values.c Changed value_from_long to work with TYPE_CODE_CHAR and
+ unpack_long to work with TYPE_CODE_BOOL and
+ TYPE_CODE_CHAR.
+
+Wed Jun 19 18:04:08 EDT 1991
+
+ symtab.c Stored pervasive types in a structure and make
+ lookup_pervasive_type() a lookup function that was based
+ on working_lang. If lookup_pervasive_type() returned
+ non-zero, then that value was returned (a fix, since
+ before it simply wouldn't return the pervasive type.)
+ language.h Added the macro CAST_IS_CONVERSION, which evaluates to
+ non-zero if the language specified by working_lang means
+ "conversion" when it says "cast".
+ valops.c Added the function value_real_cast(), which performs a
+ value.h *cast*, not a *conversion*, which is what value_cast()
+ does when it can. In particular,
+ value_cast(<float_type>,4) = 4.0, while
+ value_real_cast(<float_type>,4) = some mess.
+ eval.c Modula-2 builtin functions implemented: ABS, CAP, CHR,
+ parser-code.c FLOAT, HIGH, MAX, MIN, ODD, ORD, TRUNC, and VAL.
+ expression.h Added macros MAX_OF_TYPE and MIN_OF_TYPE to work with MAX
+ and MIN on integral types. *NOTE*: These are currently
+ hardcoded to work only if there are 8 bits per storage
+ unit. FIXME.
+ eval.c Made logical functions call value_bool to return a
+ properly typed boolean value, based on working_lang.
+
+Thu Jun 20 11:55:27 EDT 1991
+
+ valprint.c Types now print out in a Modula-2 fashion. This works for
+ the cases when the type is printed out step-by-step, that
+ is, it doesn't work when the name of a structured type
+ (which includes the keyword "struct", etc.) is simply
+ displayed.
+ FIXME: Perhaps this is bad. Parts of it seem to kludgey,
+ since type specifications in C and Modula-2 are very
+ different. The C printing of a type is very recursive,
+ whereas in Modula-2 it is generally very simple. C has
+ type prefixes and suffixes, which have no real analogue in
+ Modula-2. Maybe type_print() should call a language
+ specific type printer. This is also advantageous if we
+ compile GDB to exclude some of the languages. We'll just
+ leave those functions out.
+
+Thu Jun 20 16:57:10 EDT 1991
+
+ dbxread.c When reading the complete symbol table in (via
+ psymtab_to_symtab()), the number and types of function
+ arguments are added to a function type. define_symbol()
+ calls add_param_to_type() to accomplish this.
+ Assumption: when we come across a function definition
+ (N_FUN symbol with an 'f' or 'F' in the name), its
+ arguments will appear before another function definition.
+ When a function is found, a pointer to its type is placed
+ in the global in_function_type. Changes that
+ add_param_to_type() makes are to this global.
+ valprint.c The type of a function now includes (for Modula-2) the
+ types of its parameters.
+ eval.c Type checking and a check for the proper number of
+ arguments is now done for function calls. Not sure of the
+ impact this has on C++ member function yet.
+
+Thu Jun 20 19:58:48 EDT 1991
+
+ valprint.c Rewrote the type printer. Broke it into two language
+ specific parts, adding the functions type_print_m2() and
+ type_print_m2_1().
+ An unfortunate consequence is this: if you debugging a C
+ program in Modula-2 mode (why?), info types does not work
+ well with regular expressions, since the types are printed
+ out in Modula-2 terminology, but stored in C terminology.
+ language.[ch] Added the functions new_type_last(), type_keyword(), and
+ type_sep() to aid in the printing of typedefs.
+ symtab.c Made the printing of typedefs as language independent as
+ possible through calls to new_type_last(), type_keyword(),
+ and type_sep().
+
+Fri Jun 21 11:50:26 EDT 1991
+
+ dbxread.c Check all incoming ennumerated types. If it looks like
+ Modula-2's BOOLEAN type, then change the type_code of the
+ type to TYPE_CODE_BOOL so we can process it as a boolean
+ variable.
+ valprint.c Replaced some of the 0x%x with calls to sprintf and
+ hexformat() in val_print().
+ language.[ch] Added the function hex_to_string(), which converts its
+ integral argument to a hexadecimal number (format is
+ language based) and returns the result as a string.
+
+Mon Jun 24 12:25:07 EDT 1991
+
+ valprint.c Some functions call type_print_1() directly, instead of
+ value.h using type_print(), so they can specify where (column) to
+ print things. Since type_print() takes care of language
+ dependence, that needs to be called first. Added a
+ parameter depth to type_print() (so it is now like
+ type_print_1). Changed type_print to type_print_at, and
+ made type_print a macro that passes a depth argument of
+ zero.
+ symmisc.c Changed all calls to type_print_1 to calls to
+ type_print_at.
+ Makefile.dist Made it possible to build GDB for a specific set of
+ depend languages. Do this by passing a definition for the macro
+ LANGS to make. LANGS should be a string containing a
+ space-separated list of language names (ie. LANGS="c m2").
+ The default is to build all languages. Note that grammar
+ files must follow the naming convention of <lang>-exp.y.
+ gdb.lang This holds the current value of the LANGS macro. It is
+ examined every time make is called, and is updated if
+ necessary.
+ eval.c Added #ifdef _LANG_<lang> to these files.
+ expread.c Still need to add them to dbxread.c and coffread.c.
+ main.c
+ source.c
+ symtab.c
+ utils.c
+ valarith.c
+ valprint.c
+
+Mon Jun 24 16:33:11 EDT 1991
+
+ language.[ch] Added the functions hexformat_pre() and
+ hex_to_string_pre(), which take a prefix argument to
+ include in the format string. Thus, hexformat_pre("08") will
+ return "0x08x" (if the working language is language_c).
+ Made hexformat() and hex_to_string() calls to the above
+ with "" as the prefix argument.
+
+ am29k-pinsn.c, arm-pinsn.c, breakpoint.c, convex-tdep.c, exec.c, core.c,
+ dbxread.c, i386-pinsn.c, i386-stub.c, i386-xdep.c, i960-pinsn.c,
+ infcmd.c, inflow.c, m68k-pinsn.c, m68k-stub.c, m88k-pinsn.c,
+ mips-pinsn.c, mips-tdep.c, ns32k-pinsn.c, printcmd.c, pyr-pinsn.c,
+ pyr-tdep.c, pyr-xdep.c, remote-vx.c, remote.c, solib.c, source.c,
+ stack.c, sun386-xdep.c, symfile.c, symm-xdep.c, symmisc.c, tahoe-pinsn.c,
+ valprint.c, vax-pinsn.c
+
+ Changed all occurences of 0x%[0-9]*l*x in printf format strings to
+ calls to hexformat() and hex_to_string(). Format strings without
+ the leading "0x" were ignored.
+
+ depend Updated to take the above into account.
+
+
+Tue Jun 25 15:27:18 EDT 1991
+
+ symtab.h Added the types range_mode_t, range_check_t, type_mode_t,
+ and type_check_t to keep track of the current state of
+ range and type checking.
+ main.c Added the variables range_mode, range_check, type_mode,
+ and type_check to record the current state of range and
+ type checking. Added initialization code to main().
+ language.h Changed the macros STRICT_TYPE and RANGE_CHECK to examine
+ the above variables.
+
+
+Tue Jun 25 17:57:08 EDT 1991
+
+ dbxread.c process_one_symbol() updates the variable (enum language)
+ source_lang based on the extension of the filename
+ contained in the N_SO sybmol that started this symtab.
+ When end_symtab() is called, the value of source_lang is
+ put into the language field.
+ stack.c select_frame() sets working_lang (and possibly type_check
+ and range_check) to the language field of the symtab
+ associated with the frame that is selected if working_mode
+ is language_auto. If working_mode is language_manual, a
+ warning is printed and working_lang is not set.
+ language.c Added the function set_type_range(), which sets the value of
+ type_check and range_check (if their modes call for
+ automatic setting) based on the current value of
+ working_lang. A non-zero argument will cause the current
+ settings to be output.
+
+
+Wed Jun 26 14:51:40 EDT 1991
+
+ eval.c Added range checks on assignment.
+ m2-exp.y Added the grammar for sets to the language. Currently,
+ these do not do anything except print an error message.
+
+Wed Jun 26 17:01:04 EDT 1991
+
+ m2-exp.y Added the ability for parse_number() to parse negative
+ numbers. A global flag is set upon encountering a unary
+ minus. This was done to make, for example, 1 parse as a
+ CARDINAL, and not as an integer, per Wirth's examples in
+ Programming in Modula-2 ed.4.
+ valprint.c Added support for "set radix 2" by then setting
+ output_format to 't'.
+ eval.c Implemented range checking on subrange types. Added calls
+ to range_check_range_p for BINOP_ASSIGN and BINOP_VAL.
+ Implemented MIN and MAX for ennumerated types. The
+ minimum value of an ennumerated type is defined by Wirth
+ as the first identifier, and the maximum as the last.
+ m2-exp.y Made octal numbers ending with "B" be characters and those
+ ending with "C" be numbers, per Wirth's book. (p. 34)
+
+Thu Jun 27 14:11:52 EDT 1991
+
+ stack.c select_frame() now only sets working_lang, it does not
+ notify the user. If working_mode is language_manual, then
+ a warning is issued once.
+ main.c At the end of each call to execute_command(), working_lang
+ is checked against the local static (enum language)
+ current. If they differ and working_mode is
+ language_auto, the new settings of language, type and
+ range checking are printed out.
+ stack.c Modified frame_info() to include the language of the
+ current frame in the output of "info frame".
+ language.[ch] Added the function language_str() which returns the name
+ of the current language.
+
+Fri Jun 28 15:33:14 EDT 1991
+
+ m2-exp.y Added the built-in procedures INC, INCL, DEC, and DECL to
+ the language. INCL and DECL currently cause an error,
+ since sets are not implemented yet. INC and DEC are
+ implemented as PREINCREMENT/PREDECREMENT with one
+ argument, and as ASSIGN_MODIFY with two arguments.
+ eval.c Added type checking to the above cases.
+ value.h Added not_lval_constant to the lval_type ennumerated type.
+ not_lval_constant means that the value is a constant
+ value; that is 3 or 'a' or TRUE, not as in a constant
+ identifier. This is used to help coerce numbers such as 3
+ to either signed or unsigned numbers.
+ valops.c Added the function value_coerce_constants() which coerces
+ constant integers as following: if one is a constant and
+ the other is not, the constant's type is set to the type
+ of the other argument. If both are constants and one is
+ signed, the other is converted to a signed constant.
+
+Sat Jun 29 17:26:29 EDT 1991
+
+ valarith.c Added a better range checker. It now checks range
+ (successfully) on integral operations [+-] (signed and
+ unsigned) for any C sized type. Still does not work well
+ for multiplication.)
+ int_in_size() returns an integer that is coerced to fit into
+ specified number of bytes.
+
+Mon Jul 1 13:04:14 EDT 1991
+
+ language.[ch] Added the function binop_result_type(), which returns the
+ builtin (struct type *) type that would be the result of a
+ binop on the two values V1 and V2.
+
+Wed Jul 3 19:22:53 EDT 1991
+
+ source.c Extended source_info() to include the source language in
+ the output from "info source".
+
+Fri Jul 5 13:48:52 EDT 1991
+
+ utils.c Moved the support functions for the GDB set/show commands
+ dealing with language into language.c.
+ language.c Added the function language_info(), which displays info
+ about the current working language, type and range check
+ settings. Called via the GDB command "info language".
+ Added an initialization routine _initialize_language(),
+ that sets defaults for the language, type and range
+ variables and sets up the new GDB commands.
+ main.c Language setup moved to language.c.
+ depend Rebuilt.
+
+Mon Jul 8 10:10:22 EDT 1991
+
+ valarith.c Debugged the range checker for arithmetic. Still does not
+ work for multiplication very well.
+
+Mon Jul 8 12:40:37 EDT 1991
+
+ language.[ch] Added the function value_true() which returns non-zero if
+ its argument represents a boolean true value.
+ breakpoint.c Changed breakpoint_cond_eval() to call value_true() to
+ check the truth of an expression.
+
+Thu Jul 11 12:51:34 EDT 1991
+
+ language.[ch] Added the predicate structured_type(), which returns
+ non-zero if the argument is a structured type.
+ Added the predicate pointer_type(), which returns non-zero
+ if the argument is a pointer type.
+ eval.c Added the ability to do addition and substraction on
+ pointers and integers. This case simply bypasses the
+ type checker.
+
+Thu Jul 11 14:41:42 EDT 1991
+
+ include/stab.def
+ Added the symbol N_DEFD (0x4a) which is a definition
+ module dependency that is used by the GNU Modula-2
+ compiler and the linker. It is not important to GDB,
+ except that [dbx|coff|mips]read.c should ignore these
+ symbols.
+
+Fri Jul 12 16:07:00 EDT 1991
+
+ valprint.c Changed the TYPE_LENGTH(type) >= 0 to TYPE_LENGTH(type) >
+ 0 in val_print(). Also added statements to the else part
+ to coerce type (argument to val_print) to a pointer type
+ if it is an "array of unspecified length".
+ valops.c Added the function value_m2_string(), which returns a
+ (value) value which is a constant string, whose type is
+ (ARRAY [0..n] OF CHAR). The length field of the type
+ structure is set to zero, so it will be interpreted as an
+ "array of unspecified length".
+ stack.c Moved the language/frame mismatch check to
+ main.c:execute_command().
+ main.c The working language is recorded each time
+ execute_command() is executed. If working lang has
+ changed during its execution, then the new
+ language/type/range info is printed out for the user. If
+ the working language does not match the language of the
+ frame, a warning is issued.
+
+Sat Jul 13 16:16:39 EDT 1991
+
+ eval.c Moved all the type-checking stuff for operators to
+ language.[ch] language.c. This is so we can keep language-specific
+ stuff (like for what type operators are defined) in
+ language.c.
+ language.[ch] Added the function binop_type_check(), which checks to see
+ if its two (value) arguments are type-compatible with its
+ opcode argument. The opcode should represent an operation
+ involving an operator. Also added the macro function
+ unop_type_check, which calls binop_type_check with a
+ NULL second argument.
+ expprint.c Added Modula-2 operators to the op_print_tab, so info
+ expression.h break works correctly. Also added "op_string", which
+ returns the string corresponding to the (enum exp_opcode)
+ opcode that is its argument.
+
+
+Sat Jul 13 18:26:18 EDT 1991
+
+ coffread.c Added code to record the type of function arguments with
+ each paricular function. Code is very similar to that
+ added to dbxread.c.
+ dbxread.c Moved add_param_to_type() to symtab.c
+ symtab.[ch] Added function add_param_to_type() from dbxread.c
+
+ *** NOTE: The above additions have not been tested.
+
+Mon Jul 15 12:50:47 EDT 1991
+
+ langauge.[ch] Added the functions type_error and range_error, which work
+ like error() except if the type/range mode is set to
+ *_mode_warn, then they do not do a return_to_top_level(),
+ but merely print a warning.
+ Also changed [set|show]_[type|range]_command() to support
+ the new "warn" feature.
+
+Thu Jul 18 17:50:54 EDT 1991
+
+ mipsread.c Added code to record the type of function arguments with
+ each particular function. Code is very similar to that
+ added to dbxread.c.
+
+ *** NOTE: The above additions have not been tested.
+
+Fri Jul 19 11:19:10 EDT 1991
+
+ defs.h Added macros MAX_OF_SIZE, MIN_OF_SIZE, UMAX_OF_SIZE, and
+ UMIN_OF_SIZE, which when given a size of a numeric type,
+ return the maximum and minimum value it can hold. UMAX...
+ and UMIN... return the result for unsigned types.
+ symtab.h Added the macros MAX_OF_TYPE and MIN_OF_TYPE to operate on
+ struct types. They call above macros.
+ dbxread.c Renamed the MAX and MIN_OF_TYPE macros to ..._OF_CTYPE to
+ avoid a name conlict with the above.
+ c-exp.y Added range checking on numeric constants in
+ parse_number() for completeness.
+ valarith.c Made binop_user_defined_p() and unop_user_defined_p()
+ return 0 if working_lang is not language_c.
+
+Thu Aug 8 14:17:22 EDT 1991
+
+ main.c
+ printcmd.c
+ breakpoint.c Documentation strings of some commands changed to
+ eliminate the references to the C language where
+ appropriate.
+
+Tue Aug 13 15:48:03 EDT 1991
+
+ m2-exp.y Added qualified identifiers to the grammar. The semantics
+ are slightly different from those of the GDB operator ::
+ c-exp.y
+ m2-exp.y Added a rule to each grammar of the form: start ::= exp |
+ type_exp, where type_exp is any valid type expression.
+ expression.h
+ eval.c Added the opcode OP_TYPE, and an error case in eval.c.
+ printcmd.c Modified ptype_command() so it actually parses the input
+ (necessary for type expressions with scope qualifiers).
+ Added the function ptype_eval() which expects an
+ expression composed of one OP_TYPE element.
+ *.[ch] Replaced all occurences of parse_c_expression with
+ parse_expression
+ *.[ch] Replaced all occurences of parse_c_1 with parse_exp_1
+
+[End of ChangeLog entries from Andrew Beers for Modula-2 support.]
+
+Mon Sep 16 17:19:46 1991 John Gilmore (gnu at cygnus.com)
+
+ Small fixes from Peter Schauer:
+
+ * infrun.c (child_attach): Lint.
+ * solib.c (find_solib): Handle shared libs version 2.
+
+ Small fixes from David Wood:
+
+ * xm-ultra3.h (SYS_SIGLIST_MISSING): Typo.
+
+ Small fixes:
+
+ * remote-vx.c: Move <stdio.h> to top, for FILE. Fix from
+ John S <basrai%kanga.dnet@c3po.sm-alc.af.mil>.
+
+ * utils.c (wrap_here): Avoid wrap action of fputs_filtered if
+ chars_per_line is at maximum (user typed `set width 0'). Fix
+ from Andreas Schwab <schwab@ls5.informatik.uni-dortmund.de>.
+
+Tue Sep 17 17:31:04 1991 Stu Grossman (grossman at cygnus.com)
+
+ * coredep.c: include ptrace.h where necessary.
+ * mipsread.c(parse_lines): fix unsigned char problem that was
+ messing up line numbers on SGI's and possibly other MIPS based
+ platforms.
+ * infrun.c (child_create_inferior): use better test to check
+ return val from setpgrp().
+ * tm-irix3.h, xm-irix3.h, tconfig/irix3, xconfig/irix3: add these
+ for sgi/irix support.
+
+Wed Sep 18 04:33:31 1991 Per Bothner (bothner at cygnus.com)
+
+ * mipsread.c (parse_symbol): Put non-static procedures
+ in the global block.
+
+Fri Sep 13 00:14:52 1991 John Gilmore (gnu at cygnus.com)
+
+ Patch together `text_start' and `text_end' for 29K port.
+
+ * exec.c (exec_command): If NEED_TEXT_START_END, define the
+ variables and set them based on the exec file.
+ * am29k-tdep.c: declare text_start.
+ * valops.c (call_function_by_hand): declare text_end.
+
+ * inferior.h: Eliminate CANNOT_EXECUTE_STACK in favor of
+ defining CALL_DUMMY_LOCATION as BEFORE_TEXT_END. This is
+ because machines that do this will also have to know to
+ set NEED_TEXT_START_END. Besides, it was a redundant way to
+ say the same thing.
+ * tm-29k.h, tm-convex.h, tm-np1.h: Eliminate
+ CANNOT_EXECUTE_STACK, define CALL_DUMMY_LOCATION and
+ NEED_TEXT_START_END.
+
+Thu Sep 12 00:22:24 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ AMD 29000 changes from David Wood <wood@david.ultra.nyu.edu>:
+
+ * Makefile.in (CLIBS): Put XM_CLIBS and TM_CLIBS at end.
+ Pass MUNCH_DEFINE to munch whenever we run it.
+ * am29k-pinsn.c (print_insn): Handle NOP specially. Avoid %#x
+ format string; use 0x%x instead.
+ * am29k-tdep.c: Use DUMMY_SAVE_GREGS and RETURN_REGNUM.
+ * ultra-xdep.c, xm-ultra.h: New files for Ultracomputer host system.
+ * xm-rtbsd.h: New host support for RT/PC running BSD Unix.
+ * inflow.c: Handle `short' process group IDs.
+ * infptrace.c (fetch_register): Support CANNOT_FETCH_REGISTER,
+ and check for ptrace errors.
+ * coffread.c (SDB_REG_TO_REGNUM): Define if not already.
+ (coff_symfile_init): Initialize text_bfd_scnum.
+ (read_coff_symtab): Use it to find the text [and absolute?] sections.
+ * ../config.sub: Add vendor nyu and os "sym[1-9]*".
+ * configure.in: Add hosts rtpc-*-* and a29k-*-*.
+ Merge target arm case with other "easy" cases. Add target
+ cases a29k-*-none (rehack of am29k), a29k-*-kern (remote to
+ Ultracomputer kernel), and a29k-*-sym1 (ultracomputer OS's user
+ process).
+ * minimon.h, remote-adapt.c, remote-mm.c: Add.
+ * munch: Cope with RT/PC putting fns in data segment.
+ Restore ability to override `nm' by specifying MUNCH_NM.
+ * xconfig/rtbsd, xconfig/ultra3: New host systems.
+ * tconfig/a29k: Rename from tconfig/am29k. Add remote-mm
+ and remote-adapt. Remove encapsulated coff #define's (the
+ support should go in BFD, and gdb shouldn't know or care).
+ * tconfig/a29k-kern: Same, but for remote kernel debugging.
+ * tconfig/ultra3: For debugging user processes on Ultra3/Sym1.
+ * tm-29k.h: Update BADMAG (though it should go away).
+ Allow the register definitions to be overridden in another
+ tm-file. Fix SR_REGNUM. Add a mess of _REGNUM's. Separate
+ RETURN_REGNUM from GR96_REGNUM and DUMMY_SAVE_GREGS from
+ DUMMY_SAVE_GR96, for handling kernel calling conventions
+ that use GR64+ rather than GR96+.
+ * tm-ultra3.h: New file, for use on Ultra3 Unix as well as for
+ remote debugging of Ultra3 kernel. Includes tm-29k.h and
+ overrides various things.
+
+ * remote-mm.c (mm_attach, mm_wait): Handle attach like
+ child_attach does, making a clean stop in the newly attached
+ program.
+ * remote-eb.c: Lint.
+
+ * coffread.c: Make coffread independent of any particular
+ variant of COFF. Avoid #include-ing any particular one except
+ internalcoff.h. BFD now passes key values for symbol reading
+ as part of its coff_data structure (LINESZ, SYMESZ, AUXESZ,
+ and the symbol masks and shifts); use them.
+ Remove obsolete end_of_text_addr.
+
+ * exec.c: Remove unused include files.
+
+Wed Sep 11 19:38:44 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * Makefile.in (documentation targets): Pass $(M4).
+ Bugfix from eggert@twinsun.com (Paul Eggert).
+
+ * stack.c (down_silently_command): Check for stack existence.
+
+Tue Sep 10 23:08:29 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * Makefile.in (VERSION): Update to 4.0.3.
+
+Tue Sep 10 09:19:29 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * core.c (core_file_command): Print frame at coredump with
+ its level number, by calling print_stack_frame.
+ * frame.h: Add selected_frame_level, print_stack_frame.
+ * frame.h, stack.c: Remove print_sel_frame, print_selected_frame.
+ * convex-tdep.c, convex-xdep.c, infcmd.c, inflow.c, infrun.c:
+ Change print_sel_frame and print_selected_frame callers to
+ print_stack_frame.
+
+ * dbxread.c (read_ofile_symtab): Avoid empty else clause.
+ * symfile.c (free_named_symtabs): Ditto.
+ * main.c (main): wrap_here needs an arg.
+ * solib.c (find_solib): Avoid memory access if _DYNAMIC is zero.
+ (solib_add): Avoid noise.
+ (solib_create_inferior_hook): Lint.
+ (sharedlibrary_command): Move dont_repeat to here.
+ * utils.c (error): Call wrap_here to force buffered output.
+
+ Small patches from Peter Schauer:
+
+ * coffread.c (start_symtab): Free any existing line_vector before
+ malloc-ing new one.
+ (read_coff_symtab): Ditto for type_vector.
+
+ * source.c (lines_to_list): New variable, replacing function.
+ (all uses): Use as variable.
+ (_initialize_source): Add 'set listsize' and 'show listsize'.
+ * utils.c (lines_to_list): Remove function.
+ * stack.c (print_frame_info): Use as variable.
+ * defs.h (lines_to_list): Remove declaration.
+
+Mon Sep 9 13:45:57 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * breakpoint.c (insert_breakpoints): Restore warning about
+ the program might be running in another process, but only for
+ systems with this brain death (#ifdef ONE_PROCESS_WRITETEXT).
+ * xm-hp300bsd.h, xm-mips.h, xm-vax.h: Define it.
+
+ * utils.c (error): if error_pre_print is set, print the string
+ first.
+ * main.c (main, print_gnu_advertisement, print_gdb_version):
+ Reformat legalese so it always prints, but acts as an "I'm here"
+ message while symbols are being read. If any errors occur,
+ print a few newlines to set off the message and start it at the
+ left margin. Remove mention of "help" command, and don't yak
+ about symbol reading.
+ (catch_errors): Error string is now printed first in case of
+ error, not last.
+ * command.c (undef_cmd_error, lookup_cmd): On undefined command,
+ suggest the "help" command.
+
+ * Makefile.in (VERSION): Set to 4.0.2.
+
+Thu Sep 5 23:49:48 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * .gdbinit: Remove useless "rr" command. Set complaints
+ to 1 for people debugging gdb.
+
+ * breakpoint.c, remote-vx.c: Reword strings printed by
+ catch_errors callers.
+
+Wed Sep 4 11:07:50 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * WHATS.NEW: "history write -> history save". Doc "write on/off".
+ (Fix from kenc@viewlogic.com.)
+
+ Fix some infrastructure to be able to cope with host and target
+ machines with different sized basic types (ints, ptrs, etc).
+ (Idea from pierre@la.tce.com (Pierre Willard).)
+
+ * values.c (value_from_longest): Rename from value_from_long.
+ Handle pointer types as well as integers, so that targets with
+ different pointer sizes from the host can be accomodated.
+ * breakpoint.c, convex-tdep.c, eval.c, expprint.c, printcmd.c,
+ valarith.c, valops.c, valprint.c, value.h, values.c: Rename
+ uses of value_from_long to value_from_longest.
+ * eval.c, findvar.c, printcmd.c, valarith.c, valops.c: Pass
+ the correct pointer type to value_from_long{est}.
+
+ * doc/gdb.texinfo ($_, $__): Describe types of these variables.
+
+ * remote-vx.c: Remove obsolete code for calling functions via
+ vxworks kludge interface (it referenced value_from_long).
+
+ * valops.c (value_string): Find malloc with lookup_misc_func, not
+ raw search.
+
+Tue Sep 3 18:37:46 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Make writing to files work properly. (Fixes to BFD are also needed.)
+
+ * core.c (core_open): Open file ourselves, read or r/w, depending on
+ write_files. Use bfd_fdopenr.
+ * gdbcore.h (write_files): New variable.
+ * exec.c (write_files): Define variable, add set&show for it.
+ (exec_file_command): Use write_files to open for read or r/write.
+
+ Make shared library reading happen automatically. These changes
+ are mostly from Peter Schauer <pes@regent.e-technik.tu-muenchen.de>.
+
+ * inferior.h (stop_soon_quietly): Add to exported variables.
+ * infrun.c (child_create_inferior): call solib hook, if defined.
+ (child_attach): call solib hook, if defined.
+ * solib.c: Include inferior.h. Add from_tty to so_list as kludge.
+ (find_solib): Use lookup_misc_func rather than hand-rolled.
+ (symbol_add_stub): New stub for catch_errors.
+ (solib_add): Avoid output if !from_tty. Catch errors rather
+ than just calling symbol_file_add and bombing.
+ (solib_create_inferior_hook): Interface with the target process
+ to let it read and alloc shared libs, then figure out what it did.
+
+ * core.c (validate_files): Fix typo, soften warning.
+ (Fix from Hiroto Kagotani <kagotani@cs.titech.ac.jp>.)
+
+ * utils.c (fputs_demangled): Avoid duplicate printing if
+ demangling is off. (Fix from J.T. Conklin <jtc@cayenne.com>.)
+
+ * infrun.c (proceed): Cast -1 to (CORE_ADDR) before comparing.
+ (Fix from pierre@la.tce.com (Pierre Willard).)
+
+ * main.c (catch_errors): Change argument to a char * from an int,
+ since a char * can point to a struct full of glop, but an int
+ is not guaranteed to be able to hold a pointer.
+ * breakpoint.c (breakpoint_cond_eval, bpstat_stop_status,
+ breakpoint_re_set_one, breakpoint_re_set): Adapt.
+ * core.c (core_open, solib_add_stub): Adapt.
+ * remote-vx.c (symbol_stub, add_symbol_stub, callers): Adapt.
+
+Wed Aug 28 18:18:05 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * Makefile.in: Update VERSION to 4.0.1. Evade GNU Make bug
+ by adding .NOEXPORT target.
+
+Fri Aug 23 17:14:25 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * GDB-4.0 release!
+ * Update README.
+ * Makefile.in (VERSION): Roll to 4.0.
+ (gdb.tar.Z): Make refcard.ps as well, for shipment.
+
+Fri Aug 23 14:07:09 1991 Roland H. Pesch (pesch at cygint.cygnus.com)
+
+ * doc/gdb.texinfo: minor rewordings, crossref to ptype from print,
+ more on printsyms.
+
+ * doc/Makefile, Makefile.in: generate "gdb-all.texi" rather than
+ "gdb-all.texinfo"
+
+ * doc/rdl-apps.texi: renamed from rdl-apps.texinfo
+
+ * Makefile.in, doc/Makefile, doc/gdb.texinfo:
+ reflect above name change
+
+ * WHATS.NEW: correct pointer to refcard.
+
+ * doc/gdb.texinfo: update New Features, Installing
+
+ * doc/gdbint.texinfo: add short description of configure +template
+
+Fri Aug 23 11:46:08 1991 Roland H. Pesch (pesch at cygint.cygnus.com)
+
+ * doc/gdb.texinfo: update, fix bugs in "Installing" appendix
+
+Fri Aug 23 01:02:00 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * Makefile.in: Add config.sub, make doc/rdl-apps.texinfo for
+ tar file, add dependencies for referenced doc files.
+
+Thu Aug 22 22:17:06 1991 Stu Grossman (grossman at cygint.cygnus.com)
+
+ * coffread.c, symfile.c, stack.c: saberized.
+
+Thu Aug 22 16:20:27 1991 Roland H. Pesch (pesch at cygint.cygnus.com)
+
+ * doc/refcard.tex: permuted Essential Commands sec
+
+ * doc/gdb.texinfo: new C++ chapter; revised installation appendix;
+ new doc for
+ set/show symbol-reloading
+ default set complaints 0
+ info all-registers
+ RET-repeat disabled after prompted long displays
+ processID (attach) interpretation of 2nd GDB cmdline arg
+
+Thu Aug 22 14:05:47 1991 Stu Grossman (grossman at cygint.cygnus.com)
+
+ * expread.y, coffread.c, dbxread.c, target.c, mem-break.c,
+ cplus-dem.c, values.c, valprint.c, symfile.c, remote.c,
+ breakpoint.c, main.c: lint.
+
+Thu Aug 22 02:02:26 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Install new configuration scheme for GDB and friends.
+
+ * config.sub: Translate ordinary names to three-part names.
+ * configure: Use three-part names internally.
+ * configure.in: Translate three-part names to filenames.
+
+ * README, WHATS.NEW: Update for gdb-4.0.
+ * Makefile.in: Roll VERSION to 3.99.
+
+Wed Aug 21 18:21:09 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * infptrace.c (KERNEL_U_ADDR_BSD): Include a.out.gnu.h.
+ * i960-tdep.c, m68k-tdep.c, sparc-tdep.c, tm-i960.h,
+ tm-m68k.h, remote-nindy.c: Change ext_format_XXX structs
+ to single structures rather than arrays; when passing
+ their address, use &. This avoids trouble with bdead compilers.
+ * mcheck.c: Don't include <stdlib.h>; just declare "void abort();"
+ instead. This avoids portability headaches.
+ * mips-tdep.c (mips_do_registers_info): Only print FP regs if
+ asked to.
+ * source.c (open_source_file): Avoid ANSI const bdeath by
+ skipping declaration and then casting result value.
+ * tm-hp300bsd.h: Clarify comment.
+ * utils.c (strstr): Result is const char *; ANSI bdeath.
+ * xm-hp300bsd.h: Define HOST_BYTE_ORDER. Redefine INT_MIN,
+ since system include file defines it differently from "defs.h",
+ though the two are equivalent for our purposes.
+ * tconfig/hp300bsd: Add m68k-tdep.o.
+
+Tue Aug 20 16:01:11 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * tconfig/sun*4: Remove warnings about system assembler.
+
+Mon Aug 19 13:44:46 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * mcheck.c: Avoid warning about undeclared abort fn.
+ * tm-sparc.h (PC_ADJUST): Avoid calling error() from this;
+ it causes recursive calls to error() when used in cleanups.
+ To do so requires that we make it a function, so we do.
+ * sparc-tdep.c (sparc_pc_adjust): New implem of PC_ADJUST.
+ * utils.c (do_cleanups): Remove the current cleanup from the
+ chain *before* calling it, in case error() is called from it.
+ The result won't be pretty, but won't be an infinite loop either.
+
+Mon Aug 19 00:41:04 1991 Michael Tiemann (tiemann at cygint.cygnus.com)
+
+ * dbxread.c (read_struct_type): Grok anon structs for C++.
+ (vb_name, vptr_name): Null terminate these strings.
+
+Fri Aug 16 08:31:03 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Minor bug fixes from BSD Net2 gdb:
+
+ * blockframe.c (get_prev_frame_info): If FRAME_CHAIN_COMBINE
+ returns 0, there is no previous frame.
+ * breakpoint.c (commands_command): If !from_tty, don't call
+ input_from_terminal_p().
+ * dbxread.c (record_misc_function): Speed up slightly.
+ (compare_psymbols): Ditto.
+ * infcmd.c (do_registers_info): Take a second argument to
+ determine whether to print float registers. "info registers"
+ does not do so anymore. "info all-registers" does, now.
+ * mips-tdep.c, pyr-tdep.c (xxx_do_registers_info): Take second
+ arg and ignore it.
+ * tm-mips.h, tm-pyr.h (DO_REGISTERS_INFO): Pass second arg.
+ * inflow.c (initialize_inflow): Set tflags_ours correctly.
+
+ Other fixes:
+
+ * breakpoint.c (bpstat_do_actions): Use a cleanup to restore
+ executing_breakpoint_commands if we are interrupted by error.
+ * coffread.c (init_lineno): Avoid problem with zero-sized linetab
+ versus malloc/free. From: john@labtam.labtam.oz.au (John Carey).
+ * core.c (solib_add_stub, core_open): Call SOLIB_ADD inside a
+ catch_errors() so we can setup the frame regardless of whether
+ the shared libs work.
+ * ieee-float.c (double_to_ieee_extended): Get exponent from
+ right place in little-endian systems. From John Carey.
+
+Thu Aug 15 18:43:57 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * main.c: Remove unused terminating_signals and catch_termination().
+ (long_options): Terminate with a zero element.
+ [Bugfix from Atsuo Kawaguchi <atsuo@hark86.harl.hitachi.co.jp>.]
+ (gdb_readline): Make call-compatible with readline.
+ (init_signals): Improve comments re vfork vs. signal.
+
+ * utils.c (prompt_for_continue): Use new gdb_readline().
+ If we prompt for continuation, we don't let CR repeat the previous
+ command, once we get back to a prompt. It's too easy to keep
+ hitting CR, expecting "--more--" prompts, and have some long
+ command start repeating on you.
+
+Tue Aug 13 16:17:56 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * blockframe.c (frameless_look_for_prologue): Speed up by
+ calling SKIP_PROLOGUE_FRAMELESS_P if it's defined.
+ * tm-sparc.h (SKIP_PROLOGUE, SKIP_PROLOGUE_FRAMELESS_P):
+ Define two variants, one faster.
+ * sparc-tdep.c (sparc_frame_chain): Use target_read_memory
+ and return zero, rather than giving an error.
+ (setup_arbitrary_frame): Initialize the PC in the new frame.
+ (skip_prologue): Add a second arg saying whether we're just
+ checking for a frameless function or not.
+
+ * core.c (core_open, core_close, core_xfer_memory): Move
+ section table pointers and bfd* into the target_ops.
+ (core_open): Allow errors in shared lib reading, etc.
+ (core_files_info): Describe shared library sections.
+
+ * exec.c (exec_open, exec_close, exec_xfer_memory, xfer_memory,
+ exec_files_info, set_section_command): Move section table
+ pointers and bfd* into the target_ops.
+ (add_to_section_table): Add BFD to section table.
+
+ * target.c (target_xfer_memory, target_info): Pass target to
+ xfer_memory and target_info functions.
+ * target.h: ''
+
+ * gdbcore.h: Move struct section_table.
+ * target.h: New home of struct section_table.
+
+ * solib.c (solib_add): New argument is the target_ops whose
+ section list is to be added to, if any. Reallocate the
+ sections in that target to add any that come from shared libs.
+ (throughout) so_sections renamed to sections.
+ (solib_xfer_memory): Deleted.
+ * tm-sunos.h (SOLIB_ADD): Add target argument.
+ (SOLIB_XFER_MEMORY): Delete.
+
+ * core.c, exec.c, inftarg.c, remote-eb.c, remote-nindy.c,
+ remote-vx.c, remote.c, target.c, target.h: Remove add_syms vector
+ from target_ops. It's the same on all targets. Add two section
+ pointers to target_ops.
+
+ * stack.c (find_relative_frame): Dump ancient algorithm for
+ "down", just use handy "next" pointers.
+ (frame_command): Don't error if there is no stack; let user
+ set one.
+
+ * inflow.c (new_tty_prefork, new_tty): New prefork routine
+ modifies static state in the parent process; new_tty itself
+ runs in the child and modifies the child's file descriptors
+ to match the saved static state.
+ * infrun.c (child_create_inferior): Call new_tty_prefork,
+ fork, then new_tty.
+
+ * infptrace.c (child_xfer_memory): Add ignored target arg.
+ * remote-eb.c (eb_xfer_inferior_memory): ''
+ * remote-nindy.c (nindy_xfer_inferior_memory): ''
+ * remote-vx.c (vx_xfer_memory): ''
+ * remote.c (remote_xfer_memory): ''. Rename from
+ remote_xfer_inferior_memory.
+
+ * main.c (main): Only try to attach "corefile" argument if
+ it starts with a digit.
+
+ * symfile.c (symbol_reloading): New "set/show" variable.
+ (symbol_file_add): Shorten message about symbol reading.
+ (add_symbol_file_command): Merge with add_syms_addr_command,
+ since this should work on all targets now.
+ (stop_whining): Default to zero, to shut up complaints
+ about bad symbol tables on many systems.
+ (free_named_symtabs): Just exit unless symbol_reloading.
+
+ * xm-sun3os4.h, xm-sun4os4.h: Define BROKEN_LARGE_ALLOCA,
+ and add comment explaining shared library screw.
+
+ * source.c: #if defined => #ifdef.
+
+Thu Aug 8 12:23:19 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * doc/gdbint.texinfo: Improve doc on porting to new OS's.
+
+Tue Aug 6 17:16:15 1991 Roland H. Pesch (pesch at cygint.cygnus.com)
+
+ * doc/rdl-apps.texinfo: provide default readline-appendix finder
+ (doc/Makefile knows how to make one for local config)
+
+ * Makefile.in: use doc/Makefile for doc targets
+
+ * doc/Makefile: GDB documentation now has its own Makefile
+ doc/refcard.tex: renamed from "gdbrc.tex"
+ doc/gdbint.texinfo: add markup in "Cleanups" chapter
+
+
+Fri Aug 2 00:13:06 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * values.c (baseclass_addr): When reading target memory, use the
+ length of the basetype, not the upper type. We've only malloc'd
+ enough space for the basetype, leading to errors in free().
+
+ * expprint.c (print_subexp): Print UNOP_MEMVAL of an OP_LONG that
+ ends up as a function specially, since we know the actual type of
+ the pointed-to address. This (somewhat) fixes display of
+ expressions that include misc_function_vector names. Try `cond 1
+ !strcmp("a","b")' then `i b'.
+
+ * infrun.c: Move DO_DEFERRED_STORES from proceed() to resume().
+ The child can be proceeded from inside wait_for_inferior in
+ evaluating breakpoint conditions, and DO_DEFERRED_STORES was
+ getting skipped in that case.
+
+ * expprint.c (print_subexp): Use filtered output, since the
+ subroutines we call use it, otherwise the output is horribly
+ mangled, since output of wrappable stuff comes out late.
+
+ * Makefile.in: Bump VERSION to 3.98.1
+
+ * infrun.c (child_create_process): Use execlp to find the
+ shell to exec our target program. This requires some fiddling
+ with `environ' since there is no execlpe().
+
+Thu Aug 1 15:35:17 1991 Roland H. Pesch (pesch at fowanton.cygnus.com)
+
+ * Makefile.in, doc/gdbrc.tex, doc/rc-* (new files):
+ Minor rearrangement of refcard permits two new make targets--
+ gdbrc.dvi DVI output for refcard, using CM fonts
+ gdbrc.ps PostScript refcard, using PS fonts
+
+Wed Jul 31 16:46:21 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * GDB-3.98 release.
+
+ * TODO, Projects, WHATS.NEW, README: Update for gdb-3.98.
+ * Makefile.in (gdb-all.texinfo): Avoid touching file if M4 dies.
+
+Wed Jul 31 16:35:58 1991 Roland H. Pesch (pesch at cygint.cygnus.com)
+
+ * doc/gdb.texinfo: last changes for release.
+ Minor typo and formatting fixes; incorporated most fixes remaining from
+ filed mail commenting on earlier drafts.
+
+ Added warnings: pipes don't work in run command;
+ conditions are converse of assertions;
+ step over fn without debug info goes to next fn;
+ vars may have "wrong" values near fn entrance, exit
+
+ Added example from Kingston on printing repeated nonadjacent values
+
+ Added explicit mention that in Emacs gdb mode C-c and C-z are like
+ shell mode for signals
+
+ Renamed "Stepping and Continuing" to "Continuing and Stepping" so it
+ doesn't sound so much like its parent "Stopping and Continuing"; also
+ moved entries on continue to top of section, so they don't get lost.
+
+ Improved installation directions in appendix, added manual formatting
+ instructions
+
+Tue Jul 30 17:26:39 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * configure.in: Remove xm.h and tm.h even if we aren't linking
+ new ones, so "./configure sun4; ./configure none" does the right
+ thing. Assume that alldeps.mak and depend are already built in
+ srcdir, and avoid running "make" (particularly "make depend",
+ which involves "gcc") from inside configure. Build Makefile
+ directly rather than building Makefile.conf first.
+ * configure: Regenerate with above changes.
+ * Makefile.in: Use $(BISON) to find bison. Roll VERSION
+ to 3.98. Revise gdb.tar.Z procedure to produce a file
+ called gdb-$(VERSION).tar.Z but which unpacks into a
+ directory called "gdb". Move non-source files out of
+ $(SFILES_SUBDIR). Pretty up alldeps.mak with comments.
+ (depend): Don't try to do "gcc expread.y".
+ (expread.o): Update dependencies by hand.
+
+Mon Jul 29 15:21:09 1991 Roland H. Pesch (pesch at cygint.cygnus.com)
+
+ * doc/gdb.texinfo:
+ Fixed a variety of small typos that prevented info from formatting
+ cleanly; altered too-long heading for GPL Appendix, as discussed
+ w/RMS; Changed date on cover to July 91.
+
+Fri Jul 26 13:20:02 1991 Roland H. Pesch (pesch at cygint.cygnus.com)
+
+ * doc/gdb.texinfo:
+ (1) Applied some fixes due to comments from Larry Breed (easier ones
+ through chapsec 5.2)
+ (2) Eliminated use of @footnote---had my doubts about it anyways, and
+ it's broken in latest texinfo
+ (3) Introduced *some* use of [] for optional arguments, where
+ explanation is not simpler by listing cmd w arg and cmd w/out arg
+ separately. Still not using @deffn.
+ (4) Dropped in GPL-2. NOTE: one of GPL-2 or texinfo is broken; a
+ couple of headings are too long. Need patches to texinfo or revision
+ to GPL-2.
+
+ * Partial update to README (which still needs work for this
+ release!): (1) use of configure corrected for new script,
+ (2) "make gdb.dvi" and "make gdb.info" mentioned.
+
+Wed Jul 24 06:44:02 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * symtab.c (lookup_symbol): Don't complain right off about
+ no debug symbols; use the misc function vector first.
+ (list_symbols): Use misc function vector to find symbols
+ that don't have debug info, and print them.
+ (find_pc_symtab): Temporarily avoid fatal() when psymtab
+ PC range doesn't match symtab PC range, as it does on the
+ MIPS because our symtab reading isn't perfect.
+
+ * dbxread.c (dbx_symfile_read): Make warning about
+ "no debug symbols" slightly nicer.
+
+ * source.c (select_source_symtab): If "main" symbol exists,
+ but decode_line_spec can't find line info, don't just return
+ a zero; try other source symtabs or give an error.
+
+ * mipsread.c (parse_partial_symbols): Sort the psymtabs by
+ their low addresses first, then rip through fixing high addrs.
+
+ * ns32k-opcode.h (sfsr): Bugfix from Rune Nerg}rd,
+ <runene@ifi.uio.no>.
+ (NS32K_SVC_IMMED_OPERANDS): Reverse the #ifndef.
+
+Tue Jul 23 18:52:43 1991 Roland H. Pesch (pesch at cygint.cygnus.com)
+
+ * Minor, mostly mechanical, cleanup of doc subdir for clean
+ makeinfo'ing and TeXing; also ensured gdb-all.texinfo (post-m4)
+ and gdb.info (post- texinfo2 makeinfo) generated for distribution.
+
+Sun Jul 21 03:54:52 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Mostly MIPS and general symbol-reading fixups.
+
+ * doc/gdbint.texinfo: Add documentation on symbol-reading
+ interface.
+
+ * mipsread.c: Remove kludges around #include "ecoff.h".
+ Remove redefinitions of a_magic, etc, no longer used.
+ (parse_symbol, ): Convert "Internal:" printfs to complain()ts.
+ Fix global overview comments to match symfile.c protocol.
+ (mipscoff_new_init): Eliminate cur_hdr if we have one.
+ (mipscoff_symfile_read): Eliminate unused code. Avoid
+ sorting all the symtabs, when all we have read here is psymtabs.
+ The symtabs are sorted as they are created anyway. Tell
+ condense_misc_bunches whether we're mainline.
+ (psymtab_to_symtab_1): Pass filename when recursing, to make
+ stack trace more informative.
+ (parse_partial_symbols): Assume cur_hdr as argument.
+ (read_mips_symtab): Don't clobber cur_hdr, so it can be freed.
+ Pass cur_hdr implicitly to parse_partial_symbols. Avoid checking
+ the TYPE_NAME of char *, since that's done in symfile.c.
+ (free_numargs, parse_symbol, add_symbol, add_block,
+ shrink_linetable): Declare these fns void.
+ (upgrade_type): Convert tree of if's to switch. Clean up
+ bogus "off == 0" handling with a complaint. Avoid setting
+ field bitpos and bitsize of array with lower and upper bounds.
+ Check specified bitsize of elements against their actual type's
+ bitsize, and complain if different. Complain about unknown
+ type qualifiers.
+ (parse_fdr): Don't assume sizeof(char *) == sizeof (struct *).
+ (psymtab_to_symtab_1): Print names of subsidiary files that
+ are being read in. FIXME, we read far too many files. This code
+ is not the problem, the problem is in parse_fdr where the psymtabs
+ are set up.
+ (cross_ref): Result should indicate that we used one aux entry
+ normally, or two if we encountered a "next" entry. This used
+ to leave the caller pointing at the wrong aux entry.
+ (add_symbol): If overflowed cur_block, reallocate it larger,
+ chase all pointers to it, and complain(), rather than clobber memory.
+ (shrink_block): Use xrealloc rather than xmalloc-and-copy.
+ (new_field): Only allocate one field initially, not two.
+ Pull ++ out of macro argument. Simplify.
+ (_initialize_mipsread): Avoid initialization of importd
+ global_psymbols and static_psymbols.
+
+ * symfile.c (psymtab_to_symtab): Depend on XXX_psymtab_to_symtab
+ to properly set pst->symtab; avoid searching for it.
+ (symfile_fns): Improve comments, add a FIXME.
+ * dbxread.c: Update comments to reflect symfile protocol.
+ (read_ofile_symtab, end_symtab): Return the symtab.
+ (psymtab_to_symtab_1): Set pst->symtab.
+
+ * coffread.c (coff_symfile_read): tell condense_misc_bunches
+ whether we're mainline.
+
+ * symfile.h (sym_fns): Remove unused sym_discard member.
+ * coffread.c, mipsread.c, dbxread.c: Remove XXX_symfile_discard.
+
+ * mtrace.c (mtrace): Take effect if mallwatch is set, even if
+ the environment variable is not.
+ * infcmd.c (finish_command): Use filtered printfs.
+ * cplus-dem.c: Add struct tags to a few unnamed structs.
+ * valops.c (value_coerce_array): Improve comments.
+ * valprint.c (type_print_varspec_suffix): Print array size only
+ if greater than zero.
+ * m88k-tdep.c: Shift some lines left by one space, that had
+ apparently been trashed at some point.
+ * TODO: More things to do, a few got done.
+
+Thu Jul 18 22:46:05 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * symtab.h (LOC_EXTERNAL): Eliminate in favor of LOC_STATIC.
+ (ldsymoff, ldsymlen, globals_offset, statics_offset): Improve
+ comments.
+ * dbxread.c (read_dbx_symtab): LOC_EXTERNAL -> LOC_STATIC.
+ * expread.y, findvar.c, symmisc.c: Ditto.
+ * printcmd.c (address_info): Update printed forms of LOC_
+ symbols. Elim LOC_EXTERNAL.
+ (print_frame_args): Keep track of param stack offsets before
+ re-looking up to find the local register param is kept in.
+
+ * mipsread.c: Use <symconst.h> and <sym.h> rather than <syms.h>.
+ Further integration of mipsread into gdb. Eliminate unused
+ routines, duplicate declarations. Handle static symbols in
+ psymtabs as well as external symbols. When reading symtabs,
+ insert symbols into the correct block (global, static, or a local
+ block).
+ (read_mips_symtab, parse_partial_symbols): Don't pass useless
+ "incremental" arg.
+ (mipscoff_symfile_read): Don't call select_source_symtab.
+ (parse_symbol): Use SYMBOL_VALUE_ADDRESS where appropriate,
+ rather than SYMBOL_VALUE.
+ (parse_external): Comment clobbering of top_stack.
+ (parse_partial_symbols): Update comments. Allocate and parse
+ static symbols as well as external symbols. FIXME, enum values
+ are not handled in this pass, but should be. Inline new_psymbol.
+ Use SYMBOL_VALUE_ADDRESS.
+ (psymtab_to_symtab_1): Read symbols into global static block
+ by default (until enter some function's local block context).
+ (sort_blocks): Clean up STATIC_BLOCK as well as GLOBAL_BLOCK.
+ (destroy_all_symtabs, new_psymbol): Eliminate, unused.
+
+ * source.c (select_source_symtab): Select a source symtab
+ from either the symtabs or, failing that, the psymtabs.
+ (list_command): Update error message.
+ (forward_search_command, reverse_search_command): Use getc, not
+ fgetc, for speed. FIXME, add comment about buffers that die if
+ overrun by long line.
+
+ * values.c (unpack_field_as_long, modify_field): Avoid shifting
+ by an entire word, which is not portable, if we have a 32-bit
+ field. (Code in dbxread.c already turns such bitfields, if
+ aligned, into ordinary ints, but fixing this will help for other
+ symbol formats and for future changes.)
+ * core.c (core_open): Handle ANSI const brain death.
+ * utils.c (vprintf): Fix varargs typo.
+
+Sun Jul 14 00:42:53 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * findvar.c (find_var_value): Handle &function better.
+ * TODO: Document work needed on &fn and &array.
+ * printcmd.c (print_address_symbolic): New arg is the prefix
+ to print if a name is printed.
+ (print_address_demangle): Honor "set print address" now.
+ Use new arg above to improve spacing of output.
+ * valprint.c (val_print): When printing function pointers,
+ print symbolic form too.
+ * breakpoint.c (breakpoint_1): Use new print_address_symbolic.
+
+Mon Jul 8 19:02:46 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * core.c (memory_error): Reword error msg to mislead less.
+
+ * mips-pinsn.c (print_insn_arg 'd'): Print $ with reg name.
+
+ * mipsread.c (read_mips_symtab, read_the_mips_symtab,
+ parse_partial_symbols): Use newer BFD internals (external_filehdr
+ and external_aouthdr), byte-swap the fields that we care about
+ before using them, and make the file header data local to
+ read_the_mips_symtab rather than global.
+
+Sat Jul 6 01:34:15 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * ns32k-opcode.h (movmw, movmd): Fix opcodes. Bug fix
+ from Rune Nerg}rd <runene@ifi.uio.no> on 5 Jul 1991.
+
+ * main.c (command_line_input): Flush stdout and stderr
+ before every call to readline. This reportedly fixes a bug
+ that comes up in Sys V running emacs-gdb and/or xxgdb,
+ when stdin/out are pipes or sockets.
+
+Thu Jul 4 14:47:06 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * configure.in, Makefile.in: Avoid rebuilding "depend" as much.
+ Avoid declaring Makefile dependencies, because GNU Make stupidly
+ tries to update it if we do.
+
+ * coffread.c: Revise for minor changes to bfd internal coff
+ indexes.
+
+ * configure: If -template= is given a relative path, make it
+ absolute before recurring in subdirectories.
+
+ * configure, configure.in, Makefile.in: Install "configure" script
+ as replacement for config.gdb.
+ * config.gdb, Makefile.dist, Makefile.sdir: Remove
+ * README: Update for configure, mostly. FIXME.
+
+ * Add dec3100 as equivalent to littlemips. Indicate in all host &
+ target config files that they are for the host. When the lines
+ get copied into the Makefile, this makes it more obvious what's
+ up.
+
+Mon Jun 24 23:49:07 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * sparc-opcode.h (trap opcodes): Avoid leading spaces or
+ tabs, which end up in the disassembler output inadvertently.
+
+Wed May 29 23:01:03 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Make it compile cleanly in an ANSI GCC2 environment.
+
+ * blockframe.c: <stdio.h>
+ * cplus-dem.c: free takes a void *, ifdef __STDC__
+ * dbxread.c (read_huge_number): avoid gcc2 bug hoisting calc of
+ LONG_MAX/radix.
+ * defs.h (alloca): Avoid doing anything if alloca already def'd.
+ * stddef.h, stdlib.h: Remove these files.
+ * symtab.c: Avoid declaring qsort, close.
+ * symfile.c: Avoid declaring close.
+ * utils.c (vprintf): Declare "ap" arg as proper va_alist.
+ * sparc-tdep.c: Avoid including lots of Sun-host-specific files.
+
+ Assorted other changes.
+ * dbxread.c: include "libaout.h", not "liba.out.h".
+ * printcmd.c (print_frame_args): Set recurse properly for
+ indentation of struct and array parameters.
+ * valops.c (value_cast): Allow cast to void.
+ * infrun.c (resume): If NO_SINGLE_STEP, call machine dependent
+ single_step() in a target-independent fashion.
+ * sparc-tdep.c (single_step): Don't call ptrace ourselves, just
+ set up to be ready to continue. This makes us target independent.
+ * infptrace.c (child_resume): Remove call to single_step; now
+ can single step a SPARC target of any kind.
+
+Wed May 22 18:18:24 1991 Roland H. Pesch (pesch at fowanton.cygnus.com)
+
+ * Makefile.dist, doc/gdb.texinfo, doc/*-m4.texinfo: split up GDB
+ docn into separate sections---basically chapters, plus two loose
+ pieces that can be configured to go in different places. This
+ allows GNU m4 to preprocess the manual without coredumping.
+
+ * Makefile.dist: tell TeX where to find texinfo.
+
+Mon May 20 12:15:04 1991 Roland H. Pesch (pesch at fowanton.cygnus.com)
+
+ * Makefile.dist, doc/gdb.texinfo: respectively create, and use,
+ the new target "rdl-apps.texinfo" which captures the Makefile
+ variable that records where to find the Readline libraries.
+
+Sun May 19 05:36:59 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * tahoe-pinsn.c: #include "tahoe-opcode.h", not "opcode.h".
+ * tm-tahoe.h (FIX_CALL_DUMMY): Ignore more parameters.
+ * defs.h (const, volatile): Only define if not already defined.
+ * Makefile.dist (gdb.tar.Z): Create doc subdir w/out CVS/RCS crud.
+
+ * README: Update for release 3.95.
+ * config.gdb: Don't create readline dir in subdir builds.
+ * main.c: Include with "..." form for non-system include files,
+ so "gcc -MM" for "make depend" works.
+ Include readline files with "...h" rather than <readline/...h>.
+ * mipsread.c: Include "ecoff.h" rather than "intel-coff.h".
+
+ * coffread.c: Undo minor damage done by Rich Pixley. Use
+ different internal and external representations of COFF
+ data structures. Use new BFD routines for swapping them in and
+ out.
+ * symfile.c (free_named_symtabs): Avoid freeing file names that
+ are null or empty. Old i960 tools seem to produce files that
+ claim to have empty names, causing each successive file read
+ to blow away the previous one.
+ * sparc-xdep.c (deferred_stores): Repair minor damage by Rich.
+ Move deferred_stores to top of file, but don't separate its
+ #define's from its variable. Add commentary.
+ * Makefile.dist: Fix Rich damage; undo "configure" changes in
+ favor of keeping the (working) config.gdb. Move readline
+ library up a notch.
+
+Fri May 17 12:49:56 1991 Per Bothner (via gnu at cygint.cygnus.com)
+
+ * dbxread.c (read_struct_type): Try to handle g++ version 1 MI
+ debug info.
+ * infptrace.c (fetch_registers): no result, since now void.
+ * tconfig/news: target depends on m68k-tdep too.
+
+Fri May 17 14:40:14 1991 Roland H. Pesch (pesch at fowanton.cygnus.com)
+
+ * Makefile.dist: added readline/inc-*.texinfo to dependencies for
+ gdb.dvi target
+
+ * readline/inc-history.texinfo, readline/inc-readline.texinfo:
+ applied various small fixes due to or inspired by RMS comments
+
+ * doc/gdb.texinfo: finished using all RMS comments, save those for
+ appendices on readline and cmd history (which are in other source
+ files)
+
+Thu May 16 18:06:05 1991 Roland H. Pesch (pesch at fowanton.cygnus.com)
+
+ * doc/gdb.texinfo: (1) Updated w/ref to RMS comments through
+ chapter 9; (2) documented 'break' command's menu mode for
+ overloaded names, in response to hgs problem report C++ p-31
+
+Wed May 15 11:02:48 1991 Roland H. Pesch (pesch at fowanton.cygnus.com)
+
+ * doc/gdb.texinfo: (1) better introductory example; (2) more
+ consistent use of @code, @samp, @file, @kbd throughout; small
+ cleanups to first three nodes; (3) new "Contributors" node;
+ (4) Appendix, Renamed Commands; (5) divert specialized startup
+ instructions to "Targets" chapter for generic manuals, while
+ leaving them up front for manuals specific to specialized
+ environments; (6) apply fixes from RMS comments through chapter 4.
+
+ * pretex.m4: modify explanatory text slightly (and redefine
+ "regexp") to keep GNU m4 from complaining. (It still crashes
+ later, but one step at a time...)
+
+Wed May 15 10:32:12 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * readline/readline.c (update_line): Avoid dereferencing a pointer
+ before comparing it to its bounds. Saber caught this.
+ (init_terminal_io): Don't set BC from the "pc=" termcap variable,
+ and only set PC if tgetstr returned non-null. Saber caught this.
+
+Tue May 14 16:29:53 PDT 1991 Roland Pesch (pesch at cygint.cygnus.com)
+
+ * Makefile.dist: put gdb.dvi stuff (updated to use M4 preprocessor
+ stuff for config manual) here where it counts; updated
+ to use new subdir structure (gdb/doc/).
+
+ * Makefile: generated from above via
+ config.gdb none
+ before checkin
+
+ * gdbint.texinfo: added instructions on generating gdb.info* files
+ locally for release. These are ordinary info
+ files, formatted from gdb.texinfo (via gdb-all.texinfo, see
+ Makefile)---but due to use of texinfo 2, can't count on makeinfo
+ to generate these, so we distribute them already formatted.
+
+ * gdb.texinfo: included full Info node and menu crud (as generated
+ by C-u M-x texinfo-master-menu using the texinfo-2 elisp code).
+
+ * Makefile: updated "gdb.dvi" target to use M4 preprocessor;
+ put in comments-for-future gdb.info target (one day makeinfo will
+ work again).
+
+Tue May 14 13:51:36 PDT 1991 Roland Pesch (pesch at cygint.cygnus.com)
+
+ * gdb.texinfo: Updated to include new or old undocumented
+ commands, at least the following (perhaps some others I forgot to
+ record): info f, info float, info path, info program, info s, info
+ set, info source, info terminal, info types, info user, set/show
+ print object.
+ Also covered all recent GDB command renames for v4.
+
+Mon May 13 14:57:46 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * mipsread.c: Rather than keeping count of how many symtabs
+ and psymtabs we have, for sorting purposes, count them when
+ we need to sort. This fixes bug in rereading of symbol tables.
+
+Fri May 10 15:43:33 PDT 1991 Roland Pesch (pesch at cygint.cygnus.com)
+
+ * infcmd.c: renamed "info path" to "show paths"
+ * gdbrc.tex: documented above.
+
+Wed May 8 04:51:11 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * remote.c: Fix comments.
+ * utils.c (error): Force out any pending wrap output.
+
+Sat May 4 11:11:07 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * Makefile.dist: Roll VERSION to 3.95.
+ Fix up "saber_gdb" to work again.
+ * saber.suppress: Update.
+
+ * coffread.c, exec.c, infptrace.c, inftarg.c, remote.c, solib.c,
+ symtab.h, target.c, target.h: Lint.
+ * core.c: setup and select frame after reading shared libs,
+ else reading shared libs will clobber them. Lint.
+ * utils.c (error): Force out any buffered wrap text.
+
+Fri May 3 22:01:56 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * remote.c: Remove decls of memory_insert_breakpoint
+ and memory_remove_breakpoint, no longer used. (Suggestion of
+ Jan Norden).
+
+ * Makefile.dist: use ${subdir} in paths of BFD and LIBIBERTY,
+ to make it easier to interface to "configure"'d libraries.
+
+Fri May 3 13:10:01 PDT 1991 Roland Pesch (pesch at fowanton.cygnus.com)
+
+ * valprint.c: introduce "set p", "set pr", "show p" and "show pr" as
+ aliases for set/show print.
+
+Thu May 2 11:22:02 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * coffread.c (coff_sym_fns) [TDESC]: Make the type be m88kbcs.
+
+ * m88k-tdep.c (IEEE_isNAN): New function.
+
+ * infrun.c, m88k-tdep.c, m88k-xdep.c: Change
+ initialize_{tdesc,dcontext} to init_{tdesc,dcontext}.
+
+ * infrun.c [TDESC]: Add a bunch of crud.
+
+ * xm-88k.h [__GNUC__]: Don't define memset.
+
+ * m88k-xdep.c: #if 0 out push_breakpoint.
+
+ * tm-88k.h: Define GET_SAVED_REGISTER.
+
+ * tm-88k.h: Define DGUX.
+
+ * m88k-opcode.h (UEXT, SEXT, MAKE): Put parentheses around arguments.
+
+ * m88k-pinsn.c (sprint_address): Declare at top of file.
+
+ * m88k-xdep.c: #if 0 out core_file_command.
+
+ * values.c ({unpack_,value_as_}pointer): Just call
+ {unpack_,value_as_}long (for now anyway).
+
+ * m88k-tdep.c (get_saved_register): Make get_reg a dc_word_t (*)().
+ (psr_register): Change return type to dc_word_t.
+
+ * m88k-tdep.c (tdesc_read_function): Comment out call to ptrace.
+
+ * m88k-tdep.c (get_saved_register): Add lvalp parameter.
+
+ * gdbcore.h (write_memory): Don't prototype it.
+
+ * tm-88k.h, m88k-tdep.c: Make stack_error, stack_jmp global.
+ m88k-xdep.c: Don't mention stack_error.
+
+ * {x,t}config/m88k ({X,T}DEPFILES): Add missing files.
+
+ * mtrace.c: Don't typedef things like size_t, just #define them.
+
+ * coffread.c [TDESC]: #if 0 out references to coffsyn.
+
+ * symtab.h (struct symtab): Include EXTRA_SYMTAB_INFO.
+ tm-88k.h: Define EXTRA_SYMTAB_INFO.
+
+ * coffread.c [TDESC]: Include "tdesc.h" and make tdesc_handle
+ dc_dcontext_t not int.
+
+ * coffread.c [TDESC]: Use system include files not <intel-coff.h>.
+
+ * coffread.c [TDESC]: Move setting of debug_info from
+ coff_symfile_read to find_linenos and make it work with BFD.
+
+ * cplus-dem.c [__STDC__]: Make x{m,re}alloc return void*.
+
+ * signame.c: Cast const char* to char* when assigning to sys_siglist.
+
+ * utils.c (strsave): Make arg const char* not char*.
+
+ * infrun.c (wait_for_inferior) [SHIFT_INSN_REGS]: Use
+ bpstat_explains_signal (stop_bpstat) not stop_breakpoint.
+
+ * tm-88k.h (START_INFERIOR_HOOK): Make tdesc_handle a dc_handle_t.
+
+ * tm-88k.h (EXTRACT_RETURN_VALUE): Use char * not void *.
+
+ * findvar.c (read_var_value, case LOC_CONST_BYTES): Put the address
+ in a char *, not a CORE_ADDR. Use SYMBOL_VALUE_BYTES.
+
+ * tm-88k.h (INIT_EXTRA_FRAME_INFO): Use fci not prev (fci is
+ prev except from create_new_frame). Make next_frame a
+ local variable.
+ Declare get_prev_context.
+ {x,t}m-88k.h: Enclose USG and BCS defines in #if !defined.
+ m88k-{opcode.h,pinsn.c,xdep.c,tdep.c}: New files (same contents as
+ before; they had just been left out of the distribution for a long
+ time).
+
+Thu May 2 17:53:56 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Mips bringup and general cleanup
+
+ * cplus-dem.c: Move CPLUS_MARKER define to after defs.h.
+ * infptrace.c (PT_WRITE_D, PT_READ_D): Use correct values.
+ (This still doesn't seem to make MIPS bkpts work.)
+ * mipsread.c: Remove dup "Reading symbol data..." msg.
+ (symbol_file_command, add_file_command): Remove, obsol.
+ * printcmd.c (ptype_command): Say "an enum" rather than "a enum".
+ Wrap output appropriately.
+ * stack.c (locals_info, catch_info, args_info): Check
+ selected_frame rather than target_has_stack or coredumping.
+ * valprint.c (type_print_varspec_suffix): Wrap "ptype" output of
+ enums appropriately.
+
+Wed May 1 14:10:22 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * signame.c: Include defs.h and param.h.
+
+ * cplus-dem.c: Include defs.h and param.h.
+ Makefile.dist: Don't hack in the "param.h".
+ param.h: Don't include defs.h.
+
+ * expread.y: Use a union to deal with the fact that type_stack
+ can have both ints and enum type_pieces in it.
+ ({push,pop}_type_int): New functions.
+
+Tue Apr 30 13:18:58 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * cplus-dem.c (cplus_mangle_opname): Don't call error.
+ values.c (check_stub_method): Call error if NULL return from
+ cplus_mangle_opname.
+
+ * blockframe.c, breakpoint.c, core.c, command.c, findvar.c,
+ eval.c, expprint.c, infcmd.c, infrun.c, main.c, printcmd.c,
+ remote.c, source.c, stack.c, dbxread.c, coffread.c, symfile.h,
+ symfile.c, utils.c, valarith.c, values.c, valops.c, tm-68k.h,
+ target.c, inftarg.c, ieee-float.c, environ.c, defs.h,
+ command.h, inferior.h, gdbcore.h, symtab.h, expression.h,
+ symtab.c, cplus-dem.c, value.h, expread.y, valprint.c,
+ copying.awk, solib.c, inflow.c, symmisc.c
+ : Lint. Use read_memory not read_memory_integer on CORE_ADDR's.
+ Use {value_as,unpack}_pointer (added to values.c)
+ not {value_as,unpack}_long on CORE_ADDR's.
+ Use longest_to_int (added to defs.h) instead of cast to int.
+ Remove from_tty arg to mod_path.
+ Put symfile_bfd in {coff,dbx}read.c not symfile.h.
+ Use OP_NULL instead of 0 where dummy enum exp_opcode needed.
+
+ * tm-sparc.h: Remove GET_RWINDOW_REG.
+ (FRAME_CHAIN): Call sparc_frame_chain.
+ sparc-tdep.c (sparc_frame_chain): New function.
+ tm-sparc.h (EXTRACT_STRUCT_VALUE_ADDRESS): call
+ sparc_extract_struct_value_address (added to sparc-tdep.c).
+
+ * xm-sun386.h: Don't define SET_STACK_LIMIT_HUGE.
+
+Tue Apr 30 13:13:33 1991 Michael Tiemann (tiemann at cygint.cygnus.com)
+
+ * valprint.c (type_print_base): If the type being printed is a
+ struct containing undefined types, print "<undefine type>"
+ as the type instead of crashing.
+ * values.c (value_headof): Get the vtable pointer taking
+ TYPE_VPTR_BASETYPE into account.
+ * symtab.c, symtab.h, dbxread.c: Fix various whitespace splotches.
+
+Mon Apr 29 13:22:51 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * Move BROKEN_LARGE_ALLOCA from tm-sun386.h to xm-sun386.h.
+
+ * sun386-xdep.c [!GDB_TARGET_IS_SUN386]: Just provide empty
+ functions which don't do anything.
+ tm-sun386.h: Define GDB_TARGET_IS_SUN386.
+
+ * Makefile.dist: Add comment about tm-sun3os4.h: tm-sun3.h, etc.
+
+ * sun3-xdep.c, tm-sun3.h, tm-68k.h: Change TARGET_SUN3 to
+ GDB_TARGET_IS_SUN3.
+
+ * infrun.c: Don't include sys/user.h and friends (wrong for
+ cross-debugging and not necessary anymore (see IN_SIGTRAMP in
+ xm-vax.h)).
+ [SET_STACK_LIMIT_HUGE]: Include <sys/{resource,time}.h>.
+ xm-tahoe.h: Don't define _DIRENT_.
+
+ * xm-tahoe.h: Remove USE_OLD_TTY (not needed now that terminal.h
+ includes sgtty.h before sys/ioctl.h).
+
+Sun Apr 28 22:04:47 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * param-no-tm.h: Make BITS_BIG_ENDIAN defined to 0/1, not defined
+ or not defined. Don't define it based on TARGET_BYTE_ORDER if
+ it's already defined (in the tm.h file).
+ mips-opcode.h (BIT_FIELDS_*),
+ values.c (modify_field, unpack_field_as_long):
+ Use #if BITS_BIG_ENDIAN not #ifdef BITS_BIG_ENDIAN.
+ {x,t}m-tahoe.h, tahoe-pinsn.c, tahoe-opcode.h: New files.
+
+Fri Apr 26 12:02:06 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * tm-sparc.h: Add comments about gcc version 2 and structure passing.
+
+ * xconfig/i386v{,32}{,-g}: Add XM_CFLAGS=-Dgetpagesize()=4096.
+ gmalloc.c: #if 0 out !HAVE_GETPAGESIZE code.
+
+ * expread.y (abs_decl): Accept '&' and '&' abs_decl.
+
+ * symtab.c, symtab.h: Have a builtin_type_{,unsigned_}long_long
+ regardless of LONG_LONG.
+ defs.h (TARGET_LONG_LONG_BIT): New macro.
+ expread.y (typebase): Add {unsigned,} long long {,int}.
+
+Thu Apr 25 12:31:22 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * valops.c (typecmp): If t2 == 0, return 1.
+
+Wed Apr 24 09:45:17 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+ Changes from Tiemann:
+ * cplus-dem.c (optable): Add "nw", "dl", "compound".
+ (cplus_mangle_opname): New function.
+ (do_type): Add case 'Q'.
+ * values.c (check_stub_method): Do lookup_method_type and stuff
+ rather than smash_to_method_type.
+ symtab.c, symtab.h (allocate_stub_method): New function.
+ dbxread.c (read_type): If we get "##", don't lookup_function_type
+ and start clobbering it; allocate_stub_method instead.
+ * printcmd.c (x_command): Dereference references.
+ * valprint.c (type_print_varspec_prefix, case TYPE_CODE_METHOD):
+ Don't print " " type_print_base (...) "::" if !passed_a_ptr.
+ * dbxread.c (read_struct_type): Put "op$" instead of "operator"
+ in the symbol table.
+ * values.c (check_stub_method): Deal with operator names.
+ * valprint.c (cplus_val_print): Check for error in baseclass_addr.
+ * values.c: Move declaration of cplus_demangle to top of file.
+ * values.c (baseclass_addr): If can't read memory, set *ERRP
+ rather than calling error().
+ * value.h: Remove redundant declaration of value_static_field.
+ * values.c (value_static_field): Recursively check all baseclasses.
+ Return NULL if not found.
+ * values.c, value.h: New functions value_{headof,from_vtable_info}.
+ * valprint.c (val_print): Print out first element of vtbl
+ specially.
+ * valprint.c: Move print controls to top and add objectprint.
+ Add command "set print object on/off".
+ * valprint.c (value_print, is_vtbl_member): Put things in local
+ variables rather than continually doing VALUE_TYPE (val), etc.
+ * valops.c (value_struct_elt_for_address): Call check_stub_method.
+ * valops.c (value_struct_elt): Remove found, arg1_as_ptr.
+ * valops.c (search_struct_method): Give error if j > 0 && args == 0.
+ * valops.c (search_struct_field): New argument looking_for_baseclass.
+ Give error if value_static_field or value_primitive_field
+ return NULL.
+ valops.c (various): Call search_struct_field with extra parameter.
+ * symtab.c (decode_line_1): Deal with operators specified as
+ "operator" <optional whitespace> <symbols for operator>.
+ (operator_chars): Help do it.
+ * symtab.c (lookup_struct_elt_type): Call check_stub_type.
+ Take additional argument noerr.
+ Don't dump core if TYPE_FIELD_NAME is NULL.
+ Check the baseclasses recursively.
+ * symfile.c (fill_in_vptr_fieldno): Don't call check_stub_type.
+ Return void not int. (also declarations in symfile.h and value.h).
+ Deal with multiple inheritance.
+ * printcmd.c (print_command_1): Add if (objectprint) code.
+ * expread.y (variable): Allow for destructor with foo::~name.
+ * eval.c (evaluate_subexp, case UNOP_LOGNOT): If following opcode
+ is OP_SCOPE, give an error.
+ * eval.c (evaluate_subexp): Pass third arg to lookup_struct_elt_type.
+ * eval.c (evaluate_subexp), values.c (value_virtual_fn_field):
+ Don't bother to do anything with
+ return value from fill_in_vptr_fieldno.
+ * eval.c (evaluate_subexp): If value_static_field returns NULL,
+ give an error.
+ * dbxread.c (read_struct_type): Set fcontext to 0 for normal member
+ function.
+ * dbxread.c (read_struct_type): Initialize name to 0.
+ * dbxread.c (read_ofile_symtab, N_CATCH): Add offset to bufp->n_value.
+ * dbxread.c (dbx_create_type): Zero TYPE_VPTR_BASETYPE.
+ (read_struct_type): Don't bother to set TYPE_VTPR_{BASETYPE,FIELDNO}
+ if it's just going to be {0,1}.
+
+ * dbxread.c (virtual_context): Use TYPE_BASECLASS starting at 0
+ (yes, it's #if 0, but just in case...).
+
+ * vax-opcode.h, expread.y, expprint.c, cplus-dem.c: Declare some
+ things "const".
+
+ * i386-stub.c: New file.
+
+ * WHATS.NEW: Remove mention of readline and more paging (in 3.5).
+ Try to keep command names up to date with renaming.
+
+ * gmalloc.c [!HAVE_GETPAGESIZE]: Try to figure out the pagesize.
+
+ * infun.c (resume, resume_cleanups): New functions.
+ (wait_for_inferior, proceed, child_create_inferior): Use resume
+ not target_resume.
+
+ * remote.c (getpkt): Don't set immediate_quit.
+
+ * blockframe.c, frame.h (reinit_frame_cache): New function.
+ solib.c (solib_add), symfile.c ({,add_}symbol_file_command):
+ Use it.
+
+Tue Apr 23 10:38:41 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * symtab.c (lookup_symbol): Add 3 more of those loops through
+ the symtabs which we all know and love: (1) Look in the
+ STATIC_BLOCK for mangled symbols right after we check the blocks,
+ (2, 3) Look in the STATIC_BLOCK for all the symtabs and psymtabs
+ at the end.
+
+ * main.c (cd_command): Call dont_repeat.
+
+ * dbxread.c (read_struct_type): If const/volatile character is
+ missing, don't complain, just continue.
+
+ * dbxread.c (read_struct_type): Only try to read the fcontext if
+ it is there. Also change "error_type " to "return error_type ".
+ values.c (value_virtual_fn_field): If there is no fcontext,
+ then do things the way GDB 3.x did.
+ valops.c (search_struct_method): Add type to value_virtual_fn_field
+ arguments.
+
+ * dbxread.c (read_struct_type): Fix typo: *pp != '\0' -> **pp != '\0'.
+
+Mon Apr 22 00:02:43 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * printcmd.c (print_scalar_formatted): Add 't' for binary.
+
+ * dbxread.c (end_psymtab): Initialize pst->symtab.
+
+ * core.c (core_open): Call ADD_SOLIB.
+
+ * tm-sparc.h: Include <sun4/reg.h> not <machine/reg.h>.
+ sparc-tdep.c: Don't include <machine/reg.h>.
+
+ * sun3-xdep.c [!TARGET_SUN3]: Just provide empty functions which
+ don't do anything.
+
+ * core.c (core_open): Add make_cleanup (unpush_target, &core_ops).
+
+ * Shared library/corefile changes from Peter Schauer:
+ core.c (core_close): Call CLEAR_SOLIB.
+ (core_open): Remove comment about "should deal with shared lib".
+ (core_xfer_memory): If we can't xfer the usual way, try the
+ shared libraries.
+ solib.c (so_list): New fields so_bfd and so_sections{,_end}.
+ (find_solib): Use solib_map_sections to get ld_text.
+ (solib_map_sections, solib_xfer_memory): New functions.
+ (clear_solib): Free so_sections and close so_bfd.
+ tm-sunos.h: Add solib_xfer_memory, solib_add.
+
+ * sparc-tdep.c (skip_prologue): Don't skip anything unless there
+ is a "save" instruction in there somewhere.
+
+ * symfile.c (symbol_file_add): Add comment.
+ solib.c (solib_add): Don't malloc name passed to symbol_file_add.
+
+ * exec.c (build_section_table): If *start isn't NULL, free it.
+
+ * stack.c (parse_frame_specification): Error if NULL selected_frame.
+ infcmd.c (finish_command): Error if NULL selected_frame.
+ inflow.c (kill_command): Deal with NULL selected_frame.
+ stack.c (record_selected_frame): Set *FRAMEP to NULL if there
+ is no selected frame.
+ infrun.c (restore_inferior_status): Add comment.
+ findvar.c (read_var_value): Check for NULL frame where we need
+ a frame.
+ breakpoint.c (get_catch_sals): Check for NULL selected_frame.
+
+ * breakpoint.c (bpstat_print): Try all elements on the bpstat
+ chain before giving up with an internal error.
+
+Sun Apr 21 21:43:10 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * value.h, values.c (value_{,free_to_}mark): New functions.
+ breakpoint.c (bpstat_stop_status): Use them.
+
+ * tm-i386v{,-g}.h: Remove N_SET_MAGIC define.
+
+Sat Apr 20 21:42:47 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * i386-tdep.c: Remove unnecessary #includes.
+
+ * symtab.c (various): Change error return of find_line_common to -1.
+
+ * coffread.c (find_linenos): Use LINESZ not sizeof (struct lineno).
+
+ * coffread.c (end_symtab): Initialize language, dirname, and
+ fullname fields.
+
+Fri Apr 19 18:18:31 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * mips-tdep.c (mips_frame_chain): Don't chain if saved_pc == 0.
+
+ * stddef.h (size_t): Let either _SIZE_T or _SIZE_T_ guard it.
+
+ * mipsread.c (parse_symbol): Set startup_file_{start,end} if
+ entry_point is in current file.
+
+ * findvar.c (read_register_gen): Add "target byte-order" comment.
+
+Wed Apr 17 17:09:48 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * i386-tdep.c (i386_get_frame_setup): Use SWAP_TARGET_AND_HOST
+ before returning locals or slocals.
+
+ * i386-tdep.c (i386_follow_jump): Do not add data16 to pos in
+ call to codestream_seek; add one to pos if (and only if)
+ we are dealing with a jump with data16 == 1 (i.e. 0x66, 0xe9).
+
+Mon Apr 15 12:04:32 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * valops.c (call_function_by_hand): Put dummy1 in target order
+ before FIX_CALL_DUMMY.
+
+ * tm-i386v.h (FIX_CALL_DUMMY): Don't depend on host byte order.
+
+Sun Apr 14 11:55:19 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * valops.c (push_word): Add SWAP_TARGET_AND_HOST.
+
+ * remote.c (remote_open): Send '+' before calling putpkt().
+
+ * tm-i386v.h (REGISTER_VIRTUAL_TYPE): Return pointer to void,
+ not int, for pc, fp, and sp.
+
+ * remote.c (remote_open): Call start_remote after putpkt("?");
+ infrun.c (start_remote): Also call wait_for_inferior & normal_stop.
+
+Sat Apr 13 22:11:42 1991 Jim Kingdon (kingdon at spiff.cygnus.com)
+
+ * exec.c: Include <ctype.h>.
+
+ * sun3-xdep.c (fetch_core_registers): Add #ifdef FP0_REGNUM.
+
+Fri Apr 19 09:36:50 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * tm-68k.h (NUM_REGS): Conditionalize on TARGET_SUN3 not sun.
+ tm-sun3.h: Define TARGET_SUN3.
+
+ * utils.c: Use CPLUS_MARKER not '$'.
+
+ * cplus-dem.c: Use CPLUS_MARKER not '$'. If CPLUS_MARKER isn't
+ defined, define it to '$'.
+
+ * arm-opcode.h: New file (same contents as before; it had
+ just been left out of the distribution for a long time).
+
+ * tm-68k.h: Put declaration of ext_format_68881 outside the macros.
+
+ * main.c: New HAVE_SIGSETMASK #ifdefs.
+
+ * coffread.c (read_coff_symtab): Check for "LF%" with all the
+ other L*% things.
+
+ * coffread.c (SDB_TYPE): New macro.
+ various: Use it instead of checking against T_NULL.
+
+ * Makefile.dist (cplus-dem.o): Hack in an #include "param.h"
+ before we compile it.
+ defs.h: Protect against multiple inclusion.
+ param.h: Include defs.h.
+ signame.c: Change #ifdef SYS_SIGLIST_MISSING to #if.
+ param-no-tm.h: Define SYS_SIGLIST_MISSING from USG.
+
+Thu Apr 18 19:49:10 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * i386-pinsn.c (OP_E): Change %d to 0x%x for consistency.
+
+ * putenv.c: New file
+ Makefile.dist: Add it to $(OBS).
+
+ * mipsread.c [!CMUCS]: #include <syms.h>.
+
+ * mips-xdep.c (fetch_core_registers): #if 0 out the whole function.
+
+ * Move read_memory_nobpt from mem-break.c to breakpoint.c.
+
+Mon Apr 15 21:45:35 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * utils.c (_initialize_utils): Rename "set demangle" to
+ "set print demangle", "set asm-demangle" to "set print
+ asm-demangle" and "set sevenbit-strings" to "set print
+ sevenbit-strings".
+
+ * main.c (initialize_main): Rename "set history write" to
+ "set history save".
+
+ * main.c (initialize_main): Rename "set caution" to
+ "set confirm".
+
+ * values.c (_initialize_values): Remove "info history" alias
+ for (what is now) "show values".
+
+ * infcmd.c, gdbcmd.h: Add unsetlist.
+ infcmd.c: Add unset_command.
+ (_initialize_infcmd): Add "unset" and use it for "unset env".
+
+ * breakpoint.c (_initialize_breakpoint): Remove "unset".
+
+ * valprint.c: Add "set/show print", {set,show}_print.
+ Rename "set addressprint" to "set print address".
+ Rename "set arrayprint" to "set print array".
+ Rename "set array-max" to "set print elements".
+ Rename "set prettyprint" to "set print pretty".
+ Rename "set unionprint" to "set print union".
+ Rename "set vtblprint" to "set print vtbl".
+
+ * main.c: Rename version_info to show_version.
+ (_initialize_main): Rename "info version" to "show version".
+
+ * values.c: Rename value_history_info to show_values.
+ (_initialize_values): Rename "info values" to "show values".
+
+Sun Apr 14 23:08:34 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * inftarg.c (child_open), remote-vx{,.68}.c (vx_proc_open):
+ New function to give correct error message.
+
+Thu Apr 11 17:19:41 1991 Jim Kingdon (kingdon at cygint.cygnus.com)
+
+ * target.h: Add to_doc and target_preopen.
+ target.c: Add target_preopen and target_command.
+ Remove target_info.
+ (add_target): Call add_cmd and mess with targetlist->doc.
+ core.c, exec.c, remote-eb.c, remote-nindy.c, remote-vx.c,
+ remote-vx.68.c, inftarg.c, remote.c: Add doc field to target struct.
+ Call target_preopen from open routine.
+
+ * main.c: Rename editing_info to show_commands.
+ (_initialize_main): Rename "info editing" to "show commands".
+
+ * source.c: Rename directories_info to show_directories.
+ (_initialize_values): Rename "info directories" to "show directories".
+
+ * values.c: Rename convenience_info to show_convenience.
+ (_initialize_values): Rename "info convenience" to "show convenience".
+
+ * copying.awk (_initialize_copying): Rename "info copying" to
+ "show copying" and "info warranty" to "show warranty".
+ Rename {copying,warranty}_info to show_{copying,warranty}.
+
+ * symfile.c: Rename add_syms_command to add_symbol_file_command.
+ (_initialize_symfile, add_syms_addr_command):
+ Rename add-syms to add-symbol-file.
+
+Thu Apr 18 18:08:30 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * symfile.h (free_named_symtabs): Rename from free_named_symtab.
+ * symfile.c (clear_symtab_users_once, cashier_psymtab,
+ free_named_symtabs): Move these routines from symmisc.c.
+ * symmisc.c (same): same.
+ (free_symtab): Make non-static.
+ * symtab.h (free_symtab): Declare as exported void fn now.
+ * dbxread.c (end_symtab, end_psymtab): Change comments.
+ (initialize_dbxread): Call dbx_new_init() in case the first
+ command is add-symbols.
+ * target.c (dummy_target): Permit add_syms_addr_command.
+
+Sat Apr 13 14:46:07 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Permit symbols to be superseded when new symbol files have
+ been read in, particularly for VxWorks.
+
+ * dbxread.c (read_dbx_symtab): Allow N_SOL to cleanly take us back
+ to the main file, as well as to include files. Also, put global
+ functions into the global psymtab, to make "i fun" work.
+ (end_psymtab): Free named symtabs and psymtabs for a file, once a
+ new psymtab for it has been read.
+ * coffread.c (end_psymtab): Free named symtabs and psymtabs for
+ a file, once a new symtab has been read for it.
+ * mipsread.c: FIXME. We need to do the same for MIPS, but it
+ looks harder to determine the top-level block before it's been
+ queued to the psymtab list.
+
+ * symfile.c (symbol_file_add): Use filtered printing and wrap it.
+ If we have wiped out any old symbol tables, clean up at end of
+ symbol reading.
+ (symbol_file_command): Don't reference symfile_fns if it's zero.
+
+ * symtab.h (GLOBAL_BLOCK, STATIC_BLOCK, FIRST_LOCAL_BLOCK): New
+ defines for the blocks of a blockvector that contain global and
+ file-static symbols and the first of the smaller scope contours.
+ * symtab.c (lookup_symbol, find_pc_symtab, find_pc_line,
+ decode_line_1, make_symbol_completion_list): Use the above.
+ * coffread.c (end_symtab, patch_opaque_types): Ditto.
+ * dbxread.c (end_symtab): Ditto.
+ * expread.y (block): Ditto.
+ * mipsread.c (throughout): Ditto.
+ * symmisc.c (free_named_symtabs): Ditto.
+
+ * symtab.c (list_symbols): Process the first symbol of the
+ static psymbols list.
+ (types_info): Restore this function from its untimely #if 0.
+ It's not perfect, but it is better than nothing.
+ (_initialize_symtab): Restore "info types".
+
+Thu Apr 11 05:23:19 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * m68k-stub.c: Remote stub for 680x0's, created from
+ rem-m68k.shar (which is removed).
+ * nindy-share/{Makefile,Onindy.c,blout.h,env.h,nindy.c,ttyflush.c}:
+ Remove RCS log stuff now that we use CVS and it blows our diffs.
+
+Wed Apr 10 14:18:06 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * symmisc.c (free_named_symtab): Make it work, in its current
+ kludgy fashion. Change result to indicate if we blew away bkpts.
+ * dbxread.c (end_symtab): Accumulate result from
+ free_named_symtab and print warning if we blew user's state.
+ * symfile.h: free_named_symtab now returns an int.
+
+Mon Apr 8 23:57:43 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * dbxread.c (dbx_symfile_read): Initialize psymbol list if this
+ is the first symbol read, even if not mainline.
+ (dbx_psymtab_to_symtab): symfile might be zero, cope.
+ * exec.c (exec_ops): Add_syms_addr is valid in our tvec.
+ (set_section_command): New command ("section xxx yyy" -- should
+ be renamed to "set section xxx yyy" FIXME) which sets the
+ base address of a section of the exec file, overriding the
+ virtual address that BFD reports.
+
+Fri Apr 5 17:14:39 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * exec.c: Add add_syms_addr_command to exec_ops, so you can
+ load symbols at any address while examining an exec file.
+
+Thu Apr 4 10:09:35 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * tm-i386v.h (FLOAT_INFO): Don't define it, since the code
+ for printing the float info is host-dependent, not
+ target-dependent. FIXME.
+ * i386-pinsn.c: Move #includes to top, remove useless ones.
+ * i386-tdep.c: Don't bother including <.../reg.h> since we
+ don't use it (and it doesn't exist on host systems).
+
+ * ieee-float.c (ieee_extended_to_double): Convert NaN to Inf.
+ Convert negative numbers properly.
+ (ieee_test): Make numbers really random; fix format arg.
+
+ * infcmd.c (attach_command, detach_command): Don't repeat on CR.
+ * core.c (core_detach): Unpush core_ops, which might not be on
+ top. We used to just pop the top, which broke things. Don't
+ need dont_repeat() any more.
+ (core_file_command): Psst! Don't repeat it.
+ * remote-nindy.c (nindy_detach): Don't need dont_repeat() now.
+ * expprint.c (print_subexp): Avoid switch fallthru on
+ BINOP_ASSIGN_MODIFY, so we can print += and such.
+ * frame.h: Fix typo.
+ * inflow.c (kill_command): After killing inferior, print our
+ current frame in the core file, if we have one.
+ (generic_mourn_inferior): When inferior dies, either select
+ the current frame (in the new target, e.g. core file), or
+ set both the current and selected frames to NULL.
+
+ Changes from Peter Schauer.
+
+ * infptrace.c: Avoid <sys/ptrace.h> on USG.
+
+ * Make all file names fit in 14 characters (sigh and damn!):
+ mv hp300hpux-xdep.c hp300ux-xdep.c
+ mv symmetry-xdep.c symm-xdep.c
+ mv symmetry-tdep.c symm-tdep.c
+ mv convex-opcode.h convx-opcode.h
+ mv tm-vxworks960.h tm-vx960.h
+ mv tm-vxworks68.h tm-vx68.h
+ mv Makefile.srcdir Makefile.sdir
+ mv gdb-int.texinfo gdbint.texinfo
+ mv remote-sa.m68k.shar rem-m68k.shar
+ mv remote-multi.shar rem-multi.shar
+ * Makefile.dist, README, config.gdb, convex-pinsn.c,
+ tconfig/symmetry, tconfig/vxworks960, tconfig/vxworks68,
+ xconfig/hp300hpux, xconfig/symmetry: Change names to shorter
+ names.
+
+ * command.c (user_info_1, user_info): New command for listing
+ the user-defined commands.
+
+Wed Apr 3 15:00:26 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * dbxread.c (really_free_pendings): Clear file_symbols
+ and global_symbols after freeing them; otherwise, running
+ this function twice (if it appears twice on the cleanup
+ chain), we try to free things twice.
+
+ * dbxread.c (read_dbx_symtab): Calculate end_of_text_addr
+ based on text_addr (the address of text in core), not on addr (the
+ offset between text in the .o file and in core). This change
+ is from Peter Schauer.
+
+ * main.c: Define ALL_CLEANUPS as a cast of zero.
+ (return_to_top_level): Use it.
+ (main): Do all cleanups after each command run as part
+ of the gdb startup sequence. Also do all cleanups before
+ entering the command loop, and every time we exit the command
+ loop and reenter. Before, the cleanups from the startup sequence
+ were being left undone until the first error!
+ (command_loop): Rename do_nothing cleanup to command_loop_marker
+ so we can see it easily when examining the cleanup chain.
+ (init_signals): Add another do_nothing for signal handling.
+ (quit_command): Only try to kill target if it has execution.
+ Problems in the target stack got us into a state where
+ inferior_pid was nonzero but none of the targets had execution.
+ In this state you couldn't exit gdb.
+
+ * dbxread.c: Two changes from Peter Schauer.
+ (echo_command): Fflush output after an echo command.
+ (show_history): Pass all args to cmd_show_list.
+
+ * utils.c (init_malloc): Call mtrace to turn on tracing
+ if the environment variable MALLOC_TRACE is set to a file name.
+ * mtrace.c: Add source file which provides a log of every malloc,
+ free, and realloc to a trace file.
+ * mtrace.awk: Add source file which analyzes the trace file.
+ * Makefile.dist (GNU_MALLOC, MALLOCSRC): Add mtrace.{c,o,awk}.
+ (VERSION): Roll to 3.94.3.
+
+ * breakpoint.c (breakpoint_1): Add a space to "i watch" output.
+ (check_duplicates): Don't bother with watchpoints.
+ (set_raw_breakpoint): Comment about danger of this routine.
+ (watch_command): Parse and eval all args before calling
+ set_raw_breakpoint.
+
+ * solib.c (find_solib): Avoid error in referencing memory to
+ see if any more shared libraries have been added. This is
+ particularly useful if the target has terminated. Bug reported
+ by Peter Schauer.
+
+ Changes from Peter Schauer <pesrem@regent.e-technik.tu-muenchen.de>
+ in bringing up 3.94.2 on the Sun-3.
+
+ * Makefile.dist: Include CFLAGS in rule for cplus-dem.o.
+ * breakpoint.c (enable_breakpoint): Check for valid watchpoint
+ expression (in scope) before reenabling watchpoint.
+ * signame.c (init_sigs): Add missing declaration of i, fix
+ sys_siglist declaration.
+ * source.c (list_command): Fixed range computation to use
+ lines_to_list ().
+ * stack.c (backtrace_command): Do not allow command if target has
+ no stack, print informative error message.
+ * target.c (target_command): Do not write into command line
+ because this fails if the target command is used in a user defined
+ command. [This change was enhanced by gnu to support any-
+ unique-prefix matching on target names.]
+ * valops.c (value_struct_elt): Avoid infinite loop on an
+ erroneous attempt to print the member of function (try p main.p).
+
+Mon Apr 1 17:05:45 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * expread.y (name_no_typename): Avoid reduce/reduce errors
+ caused by ambiguity in handling NAME_OR_INT and NAME_OR_UINT.
+ Since the GDB parser really doesn't use name_no_typename in a
+ name-only context, the parser can't tell the diff between
+ names and numbers here. Avoid allowing a name_no_typename
+ to be a NAME_OR_*INT to resolve the conflict.
+
+Sun Mar 31 20:12:07 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Bugfixes from Mark Fox (markf@wrs.com) (test=testField.c):
+
+ * valprint.c (val_print_fields): bitfield printing didn't handle
+ byte order. Indirect through a few more fns to cope.
+
+ * values.c (modify_field): also cope with byte order.
+
+Sat Mar 23 10:02:21 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Cleanup for release 3.94.2:
+
+ * Makefile.dist: Pull REMOTE_OBS. Fix saber includes for BFD
+ include files. Roll version to 3.94.2.
+
+ * coffread.c (init_stringtab): Read length into unsigned char
+ array before swapping; don't assume 32-bit longs.
+
+ * target.c (target_info): Don't bother with get_sym_file, just use
+ the symfile global variable.
+ * symtab.h, symfile.c (get_sym_file): Delete it.
+
+ * dbxread.c (dbx_symfile_init): Don't depend on long == 4 bytes.
+ (define_symbol): Set symbol line number to 0 if not gcc-compiled.
+ (read_type): Replace one more error() with complain().
+
+ * mipsread.c (parse_partial_symbols): Replace printf with complain.
+
+ * i960-tdep.c: Fix copyright attribution.
+
+ * config.gdb: Quote all backquotes in doublequotes. You can
+ quote me on that. BSD 4.4 shell found this one.
+
+ * infptrace.c (throughout): The third argument to ptrace is an
+ int *, not an int.
+
+ * infrun.c (wait_for_inferior): When program has terminated, we
+ have to call target_terminal_ours before we pop that target off
+ the stack (e.g. before a call to target_kill or
+ target_mourn_inferior). This fixes problem where a program
+ terminates, then GDB stops for (tty output) and you have to type
+ "fg" to the shell to resume it. FIXME: This code for what to
+ do after termination really should be in normal_stop instead.
+
+ * gdbcore.h (read_memory_check): Change declaration; it changed
+ names months ago.
+
+ * terminal.h: Include <sgtty.h> before <sys/ioctl.h>, since in BSD
+ 4.4 prereleases, this avoids a bug in their sgtty compatability
+ support.
+ * remote.c: Use terminal.h rather than hand-rolling the same.
+
+ * signame.c, signame.h (psignal): Arg is unsigned, not int.
+ * utils.c (strsave, strstr): Fix arg types.
+ * valprint.c (val_print): lint
+
+ MIPS symbol table support from Per Bothner:
+
+ * symfile.c (symtab_fns): Remove initializer table that needs to
+ be hacked for each new symbol file format supported.
+ (add_symtab_fns): New function, chains symbol table
+ handlers into the global list.
+ (symfile_init): Search this list.
+ * symfile.h: Add next pointer, declare add_symtab_fns.
+ * coffread.c (_initialize_coffread): Call add_symtab_fns.
+ * dbxread.c (_initialize_dbxread): Call add_symtab_fns.
+
+ * mipsread.c (psymtab_to_symtab_1): return void instead of (struct
+ symbol *). Thus, we no longer need the hack to trash
+ pst->filename. Good, since that hack confused code in symfile.c!
+
+ (reorder_symtabs, destroy_all_symtabs): Removed static
+ all_symtabs, which was used to qsort symtabs in reorder_symtabs.
+ Instead, the latter now uses a temporary array (stack-allocated
+ from an obstack, and then freed).
+
+ (parse_symbol): Added a hack to fix up BLOCK_{START,END} if they
+ haven't been set in the outermost stBlock of a procedure. This was
+ a problem with f77 binaries on Ultrix 4.?.
+
+ (new_symtab, new_symbol, new_type): Continue changing code to use
+ obstacks more and otherwise conform to dbxread internal style.
+ Made the free_code of symtabs be free_linetable (as in dbxread)
+ instead of free_contents. This implies memory leaks when reading
+ a new symbol table, until the conversion is finished. Did change
+ (struct symbol) and (struct type) to be allocated on the
+ symbol_obstack. Blocks and blockvectors are among the things
+ still "leaking."
+
+ * mipsread.c (parse_partial_symbols, parse_fdr): It hasn't been
+ tested much, but it solved one problem (reported by Meissner), and
+ cleans up some other things. The problem happened when an
+ included file contains actual code (functions) and not just
+ definitions. The mips coff is a little inconvenient there, since
+ it may cause a procedure to be mapped to the wrong psymtab.
+
+ * mips-tdep.c (heuristic_proc_desc): Minor cleanup.
+ * mips-xdep.c (fetch_core_registers): Minor cleanup. FIXME,
+ this will need work for the new core paradigm.
+
+ Opcode patches from the net:
+
+ * mips-opcode.h: fix incorrect disassembly of the mfc1, cfc1, and
+ ctc1 instructions. Also, the cvt.d.w and cvt.s.w instructions were
+ missing altogether - they are added here. From Bruce Bauman.
+ * mips-opcode.h: The low mask for C0 instructions was too small.
+ From Garrett Lau. I modified the fix to check the entire 32-bit
+ opcode.
+
+ * ns32k-opcode.h: Fix opcodes for deiw and deid. From Bruce
+ Bauman.
+
+Thu Mar 21 12:56:46 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Roll in changes from Per Bothner (Tue, 25 Sep 90 11:11:04):
+
+ * dbxread.c (read_type): Pointer subtraction (value_sub in
+ valarith.c) sometimes failed because the types of the
+ pointers being subtracted were not identical.
+ These differed because dbxread.c was allocating pointer types
+ using dbx_alloc_type+smash_to_pointer_type instead of
+ lookup_pointer_type. I failed to find a justification for the
+ former, so I changed it to use the latter. Similarly, I
+ replaced smash_to_function_type by lookup_function_type,
+ and smash_to_reference_type by lookup_reference_type.
+
+ * mipsread.c (parse_symbol, upgrade_type, parse_procedure,
+ _initialize_mipsread): corresponding changes.
+
+ * symtab.c (smash_to_{pointer,reference,function}_type): eliminate.
+
+ * source.c (mod_path): Do tilde_expand on each component of the path,
+ rather than on the (list of) paths as a whole.
+ (print_source_lines): Set first_line_listed in addition to
+ current_source_symtab and current_source_line. If the source was
+ not findable, after a "dir" command to fix the problem,
+ a "list" would get the wrong lines.
+
+ While I was there... (gnu):
+
+ * dbxread.c (read_type): Change error to complaint.
+
+Thu Mar 21 12:56:46 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ First attempt at detailed understanding of symbol table memory alloc.
+
+ * dbxread.c (dbx_symfile_read): Free our string table if we
+ aren't the mainline. Free the "info" struct since we're done with
+ it.
+ (init_psymbol_list): Free any previously allocated psymbol lists.
+ (): FIXME: Should realloc-down the psymbol lists when done reading
+ the main symbol file?
+
+ * symmisc.c (free_symtab): Free fullname field too.
+
+ * xm-hp300hpux.h (USG): #undef then #define so Makefile can -D.
+ (REGISTER_ADDR): Make result type unsigned int.
+
+ * xconfig/{i386*,hp300hpux,altosgas,altos}: All config files that
+ define REGEX must also define REGEX1 (its dependency).
+
+Tue Mar 19 21:28:57 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * tconfig/i960: No longer works, points you at vxworks960 or
+ nindy960.
+
+ * xgdb.c, XGDB-README: Remove file. Users can get the much
+ better xxgdb.
+ * Makefile.dist: Remove all trace of xgdb.
+
+ * breakpoint.c (breakpoint_1): Pass demangle arg to
+ print_address_symbolic.
+ (clear_breakpoints): Remove unused function.
+ (breakpoint_re_set_one): Guts of breakpoint_re_set.
+ (breakpoint_re_set): Use catch_errors to do them all anyway.
+
+ * gdb-int.texinfo (Host versus Target): Add section on what is
+ a "host" feature versus what is a "target" feature.
+
+ * infcmd.c (path_command, path_info): Handle the PATH variable
+ (object search path) as conveniently as the source search path.
+ * environ.c (set_in_environ): Set some vars in GDB's environment,
+ in addition to the child's. PATH, G960BASE, G960BIN for starters.
+ * source.c (mod_path): New function, from guts of
+ directory_command, modifies a path. Used by path_command.
+ (directory_command): Call it.
+ * defs.h (strsave): Declare.
+
+ * utils.c (sevenbit_strings): Add new printing option.
+ (printchar): Use it.
+ (strsave): Provide this handy helper routine.
+ (set_width_command): Rename set_screen_width_command.
+ (_initialize_utils): "set screen-width" => "set width";
+ "set screen-height" => "set height"; add sevenbit-strings.
+
+ * infcmd.c (do_registers_info): Print floating point registers
+ in raw hex as well as float format, regardless of whether it is
+ a "virtual" convertible register.
+ * tm-sparc.h (PRINT_REGISTER_HOOK): Print every pair of float
+ regs as a double, just in case it's being used that way.
+ * values.c (unpack_long): Comment on array/function coercion.
+ (unpack_double): Argument is in target byte order now. For
+ integer arguments, just call unpack_long and float the result.
+ * m68k-tdep.c: include defs.h for "const" handling.
+ * remote-nindy.c: Use ieee-float stuff.
+ (nindy_fetch_registers): Unpack double regs to host double, then
+ to extended.
+ (nindy_store_registers): Pack extendeds to host double, flip
+ around by misusing unpack_double, send as target double.
+
+ * tm-vxworks68.h (FRAME_CHAIN): Handle current frame pointer of
+ zero, as when stopped at the first instruction of a process.
+
+ * blockframe.c: Fix filename in comment (param.h => tm.h).
+ * sparc-tdep.c (skip_prologue): More explicit nudging comments.
+ * tm-68k.h: Fix typos.
+
+Fri Mar 15 01:09:34 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Changes from a bringup on the DEC Vax under Ultrix 4.0.
+
+ * coredep.c (fetch_core_registers): Pass end-address of register
+ section to register_addr as expected. Don't call supply_register
+ if we'd just pass it garbage.
+
+ * dbxread.c (read_dbx_symtab): Skip N_NSYMS on Ultrix.
+
+ * exec.c (xfer_memory): Use boolean xfer_fn result, not int.
+
+ * target.c (push_target, target_info): Cast enums to int for < or
+ > comparison.
+
+ * stack.c (print_frame_info): Identify source file & line
+ even if we can't print it.
+
+ * xm-vax.h (MISSING_VPRINTF): No longer missing in Ultrix V4.0.
+
+Sat Mar 9 10:08:20 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Clean up IEEE floating point support.
+
+ * ieee-float.h: New file.
+ * ieee-float.c: Write real routines to convert between host
+ doubles and various target IEEE extendeds.
+ * m68k-xdep.c: Eliminate assembler code for extended floats.
+ * xconfig/{3b1,altos,altosgas,hp300bsd,isi,news,news1000,sun2os3,
+ sun2os4,sun3,sun3os3,sun3os4}: Eliminate use of m68k-xdep.o.
+ * tm-i960.h, tm-68k.h (REGISTER_CONVERT_TO_VIRTUAL,
+ REGISTER_CONVERT_TO_RAW): Use ieee_extended_to_double and
+ double_to_ieee_extended.
+ * i960-tdep.c: Define ext_format_i960.
+ * m68k-tdep.c: Define ext_format_68881.
+ * sparc-tdep.c: Define ext_format_sparc, though unused.
+ * Makefile.dist (HFILES): Add ieee-float.h.
+ * inftarg.c: #include "ieee-float.h" for the REGISTER_CONVERT
+ macros.
+
+ Obsolete the "coffstrip" program in favor of using BFD's strip.
+
+ * nindy-share/coffstrip.c: Remove file.
+ * nindy-share/nindy.c (coffstrip): Routine to run bfd_strip.
+ * Makefile.dist: Remove references to nindy-share/coffstrip.c.
+ * tconfig/nindy960: Remove reference to coffstrip.o.
+
+ * Makefile.dist: Roll version number to 3.94.1 (not yet final).
+
+Wed Mar 6 09:56:45 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * symfile.h: Add symfile_bfd, common between dbxread and coffread.
+ * dbxread.c: Remove static symfile_bfd.
+ * infcmd.c (do_registers_info): Add PRINT_REGISTER_HOOK, though
+ it is not used yet.
+ * inftarg.c (child_detach): Pop the child_ops vector if the
+ detach is successful.
+ * remote-nindy.c (nindy_create_inferior): Don't push a new
+ nindy_ops since nindy uses the same one for execution and memory
+ examination anyway.
+ * core.c (core_ops): Use child_attach and child_create_inferior
+ rather than default attach and create_inferior functions.
+
+ Handle floating point registers in core files.
+
+ * sparc-xdep.c (fetch_core_registers): Rewrite for float support.
+ * sun3-xdep.c (fetch_core_registers): Rewrite for float support.
+ This version untested since BFD doesn't yet support sun3 core
+ files.
+ * hp300hpux-xdep.c: Rewrite fetch_core_registers to new calling
+ conventions. Fix comments and style. This version has not
+ been compiled yet, since we have no HP inhouse.
+ * core.c (get_core_registers): Look for two sections, ".reg"
+ and ".reg2", and pass both to fetch_core_registers sequentially.
+
+ Revise directory path yet again.
+
+ * source.c (forget_cached_source_info): Not static any more.
+ (init_source_path): New default source path is "$cdir:$cwd".
+ (dir_command): Handle variable arguments ($cdir, $cwd).
+ (source_info): Print "Compilation directory" rather than
+ "Originally compiled in" to remind people of $cdir.
+ (openp): If the path contains $cwd, use current directory.
+ (open_source_file): If compilation directory is known, replace
+ first $cdir in path with the compilation directory.
+ (print_source_lines): Even if we can't print the lines, set the
+ current symtab and line for future commands like "info source" or
+ "breakpoint". Also, error message now contains the file name,
+ line number, and file access error message.
+ (_initialize_source): Fix help text to describe changes.
+ * main.c (cd_command): Forget cached source info when we chdir.
+ * utils.c (strstr): Add simple implementation.
+
+Tue Mar 5 01:41:40 1991 John Gilmore (gnu at fowanton.cygnus.com)
+
+ * coffread.c (read_one_sym, init_linetable, init_stringtab):
+ Byte-swap COFF symbol tables if necessary when reading them in.
+ Use complain() to replace error message in one spot. Needs
+ corresponding change in bfd/coff-code.h to make some symbol
+ swapping routines non-static.
+
+Mon Mar 4 00:53:40 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Merge changes from Eirik Fuller, for UTek.
+
+ * defs.h (errno): Add declaration.
+ * altos-xdep.c, arm-xdep.c, convex-xdep.c, gould-xdep.c,
+ hp300hpux-xdep.c, infrun.c, inflow.c, infptrace.c, i386-tdep.c,
+ i386-xdep.c, pyr-xdep.c, mips-xdep.c, remote-eb.c, remote-nindy.c,
+ remote-vx.c, source.c, standalone.c, stuff.c, sun386-xdep.c,
+ symmetry-tdep.c, symmetry-xdep.c, umax-xdep.c, utils.c: Eliminate
+ declarations of errno.
+
+ * remote-eb.c: Define B19200 and B38400 as EXTA and EXTB.
+
+ * remote-vx.c: Include <sys/time.h> for UTek; Sun gets it via
+ <rpc/rpc.h> and <rpc/types.h>.
+
+Sat Mar 2 15:47:55 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * i960-tdep.c (examine_prologue): Add new argument limit,
+ which stops the scan at the end of the prologue, or at the PC.
+ This fixes a problem where it walks down into the code for the
+ user's statements if that code looks like function prologues.
+ Mark Fox and I have been bouncing this code back and forth, making
+ small changes to it. Callers changed to match.
+
+Tue Feb 26 01:47:07 1991 Cygnus John Gilmore (cygnus at yuba)
+
+ Cleanup for gdb-3.94 release final:
+
+ * Makefile.dist: Remove remote-vx.c, remote-nindy.c, and all
+ the .c files from vx-share and nindy-share, from the various
+ macros, since they are not found via ALLDEPFILES.
+ (SFILES): Add tm-i960.h.
+ (alldeps.mak rule): Break out ALLDEPFILES_MAINDIR and
+ ALLDEPFILES_SUBDIR. List all the nindy and vxworks subdir files
+ in the SUBDIR list.
+ (TAGFILES_MAINDIR): Change ALLDEPFILES to ALLDEPFILES_MAINDIR.
+ (gdb.tar.Z): Use ALLDEPFILES_SUBDIR as well as SFILES_SUBDIR.
+
+Mon Feb 25 16:02:35 1991 Cygnus John Gilmore (cygnus at oldman)
+
+ * am29k-tdep.c: Add contribution line.
+ (examine_prologue): Cache information about function prologues in
+ the misc-function-vector to avoid lots of references over the
+ serial line while examining instructions.
+
+ * core.c (core_close): New function made from cleanup_core.
+
+ * core.c, exec.c, inftarg.c, remote-eb.c, remote-nindy.c,
+ remote-vx.c, remote.c, target.c, target.h,
+ Update target_ops vector to add attach, close, and load entries.
+ Use add_syms_addr_command, not add_file_addr_command, for
+ add_file. Break out close routine from existing code.
+
+ * dbxread.c (really_free_pendings): Don't free pending_blocks;
+ they are in an obstack.
+ (read_dbx_symtab): Relocate end_of_text_addr in the psymtab.
+ Lint.
+ (define_symbol): Add symbol type parameter; change callers;
+ pass type parameter to DBX_PARM_SYMBOL_CLASS macro to allow
+ it to influence the symbol class on the i960.
+ (define_symbol): Swap LOC_CONST's into target byte order.
+
+ * exec.c (exec_close): New function.
+ (exec_file_command): Call it.
+
+ * findvar.c (read_relative_register_raw_bytes): Doc byte order,
+ Fix byte order of frame pointer.
+ (read_var_value): Result of 0 if var's value can't be found,
+ e.g. missing FRAME_ARGS_ADDRESS. Byte-swap LOC_CONST and
+ LOC_LABEL values to target order. Add LOC_LOCAL_ARG.
+ (locate_var_value): Use read_var_value and use its lazy address
+ as the location of the var's value. Lint.
+
+ * i960-pinsn.c (next_insn): Add routine from vxgdb for scanning
+ instructions.
+
+ * i960-tdep.c (arg_address, i960_frame_find_saved_regs): Remove
+ obsolete Intel versions in favor of vxgdb versions.
+ (check_host, byteswap, byteswap_val, reorder_val): Eliminate
+ code dealing with byte order of values, which Intel did in host byte
+ order rather than gdb-4's target byte order.
+ (i960_frame_chain_valid): Move to nindy-tdep.c.
+ (examine_prologue, skip_prologue, frame_find_saved_regs,
+ frame_args_address, leafproc_return, saved_pc_after_call,
+ pop_frame): Add vxgdb versions from Mark Fox.
+ (examine_prologue, frame_struct_result_address): Add code
+ to deal with the saved value of G13 (struct return address
+ pointer).
+ (frame_args_address): Modify Mark's version to prefer the
+ saved value over the current value in the topmost frame.
+ Cache result in the frame info to avoid performance hair in
+ callers.
+ (print_fault): Add gdb960 code for printing faults.
+ (_initialize_i960): Actually call check_host.
+
+ * ieee-float.c (ieee_extended_to_double, ieee_double_to_extended):
+ add stub routines. FIXME, these currently just return zero!
+
+ * infcmd.c (program_info): Use PRINT_RANDOM_SIGNAL.
+ (attach_command): Call target_attach, not target_open, now.
+
+ * infrun.c (normal_stop): Make global, not static, for vx_attach.
+ (child_attach): Rename from child_open.
+ (wait_for_inferior): Use PRINT_RANDOM_SIGNAL. If stop_pc is zero,
+ don't confuse it with a zero step_resume_break_address.
+
+ * inftarg.c (child_detach): Eliminate inferior_pid test.
+ (child_files_info): Clean up message a bit.
+ (child_ops): Use child_attach, not child_open, to attach.
+
+ * mem-break.c: #ifdef out the whole file if BREAKPOINT is not
+ set (e.g. on VxWorks or NINDY). Move read_memory_nobpt from
+ findvar.c to here, since it depends on the contents of the
+ shadow_contents of breakpoints, but keep if #if 0 since it is
+ never called.
+
+ * nindy-tdep.c: New file, contains nindy_frame_chain_valid, moved
+ from i960-tdep.c.
+
+ * printcmd.c (address_info): Handle LOC_LOCAL_ARG. Lint.
+ (ptype_command, display_command): Eliminate have_inferior_p and
+ have_core_file_p in favor of target_has_stack or
+ target_has_execution.
+ (print_frame_args): Handle LOC_LOCAL_ARG. Eliminate duplicate
+ code for actually finding the values of arguments, though we still
+ keep track of the maximum stack offset for use in printing unnamed
+ arguments. Handle missing FRAME_ARGS_ADDRESS.
+
+ * remote-nindy.c (i960_print_fault): Move to i960-tdep.c.
+ (struct nindy_regs): Define registers passed to/from nindy.
+ (nindy_fetch_registers, nindy_store-registers): Translate between
+ nindy and GDB formats for the registers.
+ (dcache_init): Statically allocate the cache, since it was being
+ allocated by a malloc that was never freed anyway.
+ (nindy_create_inferior): Error, not core dump, if no exec file.
+ (nindy_before_main_loop): Use target_load, not target_add_file.
+
+ * remote-vx.c (net_load): Specify large timeout for load
+ requests. Allow user to break out with INTERRUPT.
+ (net_break): Remove useless code, clean up. Change callers.
+ (parse-args, skip_white_space, find_white_space): Clean up arg
+ parsing to cope with quoted strings.
+ (net_wait, net_quit): Never call error, just return status.
+ (vx_read_register, vx_write_register): Cleanup status checking.
+ #ifdef the code based on which CPU we are using (960 or 68k),
+ FIXME, this should be completely general but it isn't yet.
+ (vx_xfer_memory, vx_resume): Cleanup status checking.
+ (vx_run_files_info): Improve message.
+ (vx_load_command): Renamed from vx_add_file_command. Allow load
+ to be interrupted.
+ (net_ptrace): Remove unused routine.
+ (vx_wait): Adopt code from vxgdb960 to cope with broken
+ connections to target machine and prompt to disconnect. Remove
+ debug printouts. Map some EVENT_'s to SIGnals.
+ (add_symbol_stub, vx_open): Print names of object files we found,
+ and "ok" if we read their symbols OK. Clarify output in general.
+ (vx_attach, vx_detach, vx_kill): Add these commands.
+ (vx_convert_from_virtual, vx_convert_to_virtual): Simplify.
+ (vx_run_ops): Turn off all_mem, to avoid spurious msg in the
+ "info files" output, and create_inferior, since we already have
+ an inferior.
+
+ * stack.c (frame_info): Replace Frame_unknown with 0.
+ (print_frame_arg_vars): Handle LOC_LOCAL_ARG.
+ (return_command): Pop until the PC matches as well as the FP,
+ so it works even if the FP is shared with another function,
+ as in "frameless" or "leaf" procedures.
+
+ * symfile.c (load_command): renamed from add_file_target_command.
+ (add_syms_addr_command): renamed from add_file_addr_command.
+ (add_syms_command): Stub to call target_add_syms.
+ (_initialize_symfile): Change command names and descriptions,
+ add-file => add-syms, and load from alias to its own command.
+
+ * target.c (kill_or_be_killed, maybe_kill_then_attach,
+ maybe_kill_then_create_inferior): Default for attempts to start
+ a process, if one is already running, is to ask about killing
+ it and retry if yes.
+ (upstack_create_inferior): #if-0 it, strata obsolete it.
+ (push_target, unpush_target, pop_target): to_close() a target
+ before unstacking it.
+ (target_info): Renamed from target_files_info.
+ (_initialize_targets): Rename "i files" as "i target", accessible
+ under both names.
+
+ * target.h: Improve comments about the target_ vectored routines.
+
+ * tm-i960.h: Remove NINDY-specific stuff to tm-nindy960.h.
+ Convert commenting style to standard GNU style.
+ (DBX_PARM_SYMBOL_CLASS): allow LOC_LOCAL_ARG's to be recognized.
+ (SKIP_PROLOGUE): No longer a no-op.
+ (SAVED_PC_AFTER_CALL): Now handles leaf procedures.
+ (*_REGNUM): Sort register numbers.
+ (REGISTER_BYTES, REGISTER_BYTE, REGISTER_RAW_SIZE,
+ MAX_REGISTER_RAW_SIZE, REGISTER_CONVERTIBLE,
+ REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW): Float regs
+ are now 10 byte extendeds, not 8 byte doubles.
+ (FRAME_CHAIN_VALID): Make this config-dependent, since it differs
+ for nindy versus vxworks targets. FIXME, this should possibly go
+ in the target vector.
+ (EXTRA_FRAME_INFO, INIT_EXTRA_FRAME_INFO): Cache both
+ frame_saved_regs and arg pointer with each frame.
+ (FRAMELESS_FUNCTION_INVOCATION): New leafproc support.
+ (FRAME_ARGS_ADDRESS): Use cached result.
+ (FRAME_ARGS_ADDRESS_CORRECT): New, avoids g14 guessing.
+ (FRAME_FIND_SAVED_REGS): Change arg to subsidiary fn.
+ (PRINT_RAMDON_SIGNAL): Call print_fault.
+ (POP_FRAME): Now works.
+
+ * tm-nindy960.h: Break this off tm-i960.h. NINDY-specific
+ option parsing and startup; STACK_END_ADDR, FRAME_CHAIN_VALID,
+ BREAKPOINT, and DECR_PC_AFTER_BREAK are here.
+ (ADDITIONAL_OPTION_HANDLER): use target_load, not
+ target_add_file.
+
+ * tm-vxworks960.h: Break this off tm-i960.h. VxGDB specific
+ startup; DECR_PC_AFTER_BREAK, and FRAME_CHAIN_VALID are here.
+
+ * valarith.c (value_subscripted_rvalue): Avoid handling
+ floats and doubles specially; it gave alignment errors. Lint.
+
+ * valops.c (value_of_variable, value_of_this): Error if unknown
+ value.
+
+ * valprint.c (print_floating): Bcopy rather than pointer-deref,
+ to avoid alignment problems.
+ (value_print): Handle unknown value address.
+ (cplus_val_print): Two args are ignored; remove them. Change caller.
+ (val_print): Use unpack_long rather than pointer-deref.
+
+ * values.c: Lint.
+ (unpack_long, unpack_double): Use bcopy rather than pointer-deref
+ to avoid alignment problems.
+ (value_being_returned): Error if return value unknown.
+ (set_return_value): Add bogosity warning, FIXME. *
+
+ * TODO: A woman's work is never done.
+
+ * Makefile.dist: Distribute REMOTE_OBS into tconfig files.
+ Separate INCLUDE_CFLAGS for use with lint. Add LINTFILES.
+ Add ieee-float.o to OBS.
+ * tconfig/{nindy960,vxworks68,vxworks960}: Include the desired
+ REMOTE_OBS remote-interface files in the TDEPFILES and TM_FILE.
+ * tconfig/i960: FIXME. Half-merge, produce warning if config'd.
+
+ Changes to generalize the VxWorks RPC protocol slightly, to handle
+ i960 as well as 68000.
+
+ * vx-share/dbgRpcLib.h (VX_SOURCE_STEP): Add.
+ * vx-share/reg.h: Produce i960 regs #ifdef I80960
+ * vx-share/xdr_ptrace.c: Skip FPA registers if 960.
+ * vx-share/xdr_rdb.h: Add SOURCE_STEP struct and xdr decl.
+ * vx-share/xdr_rdb.c: Add xdr_SOURCE_STEP routine.
+ * vx-share/xdr_regs.c: Add xdr_regs, xdr_fp_status, xdr_ext_fp
+ for i960. Change xdr_vectors to xdr_opaques for 68k registers,
+ so they will move in target byte order rather than network
+ byte order (happens to be the same).
+
+Mon Feb 25 03:41:44 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * tm-convex.h (END_OF_TEXT_DEFAULT): Remove #if 0'd block.
+
+Sun Feb 24 00:55:53 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * am29k-pinsn.c,
+ Add contribution lines to various files, showing where they
+ came from.
+
+ * breakpoint.c (break_insn, check_break_insn_size,
+ read_memory_nobpt): Remove to mem-break.c.
+
+ * xm-*.h, param-no-tm.h, tm-29k.h, valprint.c: Change BYTE_ORDER to
+ HOST_BYTE_ORDER.
+
+ * tm-29k.h (STAB_REG_TO_REGNUM): Warn user if symbol table
+ entry has bad register number. This change is not
+ tested in this release, FIXME.
+
+ * frame.h: Eliminate Frame_unknown in favor of a simple zero.
+ tm-vax.h: Ditto.
+
+ * value.h: Force value's contents field to be aligned to hold
+ at least a double or a long long (if supported). This avoids
+ doing bcopy's in and out of the contents field.
+
+ (step_1): Avoid coredump under obscure circumstances when we
+ have no frame.
+
+ * symtab.h (misc_info): Add field to misc function vector for
+ any kind of cached information the target code desires. AMD
+ 29000 uses this to avoid repeating examine_function_prologue's.
+
+ * coffread.c: Lint. Remove static symfile, read_section_header.
+ core.c (have_core_file_p): Lint: remove.
+ expprint.c (print_subexp): Lint.
+ infptrace.c, valops.c, valprint.c: lint.
+
+ Roll in changes from vxgdb-5.0.1:
+
+ * symtab.h: Comment byte order of each address class. Add
+ LOC_LOCAL_ARG for frame-relative args (960).
+ expread.y: Use LOC_LOCAL_ARG where LOC_ARG is used.
+ symtab.c, symmisc.c: ditto.
+
+ * infrun.c (init_wait_for_inferior): Clear stop_signal.
+
+ * remote.c (remote_resume): Error if resume with a signal.
+
+ * symfile.c (prim_record_misc_function): Clear misc_info.
+ (fill_in_vptr_fieldno): Check stub type of arg.
+
+ * valops.c (value_cast): Avoid looking up names of types whose
+ name we don't know, to prevent coredump. Sun CC produces typedef
+ rtx and the name of *rtx is zero...
+
+Mon Feb 18 21:16:25 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Roll in changes from final AMD 29000 port (Tiemann).
+
+ tconfig/am29k: Add COFF_ENCAPSULATE and TARGET=TARGET_AM29K
+ for ../include/a.out.encap.h. This might not work now that BFD
+ is separately compiled. Instead, BFD support for encap will have
+ to translate machine type 29k into the right COFF_MAGIC.
+
+ * infcmd.c: Remove references to inferior_pid that aren't used
+ in actual ptrace calls; use target_has_execution, etc.
+ (have_inferior_p): Remove function.
+ (program_info): Print target info rather than "process number";
+ avoid gratuitous messages unless from_tty.
+ (run_stack_dummy, finish_command): Set proceed_to_finish.
+ infrun.c: Remove inferior_pid refs. Decl & init proceed_to_finish.
+ main.c: Lint. Lose have_inferior_p().
+ inferior.h (have_inferior_p): Remove, lint.
+ (proceed_to_finish): Add flag to ask that all regs be saved
+ by normal_stop, for the few commands that need it, speeding up
+ serial I/O. Add comments to stop_registers.
+
+ * remote-eb.c: Remove newline from breakpoint message we grep
+ for. Never time out when running the user program.
+
+
+
+Wed Feb 13 15:34:40 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Roll in changes from vxgdb-5.0.1:
+
+ * dbxread.c (read_dbx_symtab): If we encounter a "FORTRAN COMMON"
+ symbol in its raw form, we are processing an unlinked ".o" file.
+ See if the target environment has assigned it an address, using
+ target_lookup_symbol (VxWorks does), and enter it into the symtab
+ that way.
+
+ * tm-vxworks.h (FRAME_CHAIN, FRAME_CHAIN_VALID): Override usual
+ 68k versions for a simpler version that assumes zero FP at bottom.
+ Fixes bug of truncated stack reports.
+
+ * target.h (target_lookup_symbol): Define this routine's args
+ and result, finally.
+
+ * target.c (nosymbol): Default routine for target_lookup_symbol.
+ (target_default): Default lookup_symbol and call_function too.
+ (files_info): Only print has_all_memory warning if a non-dummy
+ target follows.
+
+ * remote-vx.c (vx_read_register, vx_convert_to_virtual,
+ vx_convert_from_virtual): If target does not have floating point,
+ zero register "values", and avoid doing cross-net conversions.
+ (vx_lookup_symbol): Rename net_lookup_symbol, add to vectors.
+ (vx_open): Rearrange code that attaches to target and reads
+ symbols for all loaded modules, to work if some of the modules
+ are not accessible. Add symbol_stub() and add_symbol_stub()
+ as callbacks from catch_errors(). Allow connect attempt to be
+ interrupted painlessly with ^C (FIXME, there are still some bugs
+ if the interrupt happens during symbol reading.). Print
+ final message with puts_filtered, since symbol messages are
+ now filtered too.
+
+ Misc cleanup:
+
+ * main.c (catch_errors): Only print errstring if non-null.
+ (command_loop): Avoid an ioctl per command to test ISATTY.
+
+ * remote-vx.c (net_load): make static; avoid sophomoric msg.
+ (vx_xfer_memory): Return correct result!
+ (vx_files_info): Indicate whether target has float or not.
+ (vx_lookup_symbol): Complain, not error, if target gone.
+ (vx_open): Print "Connected" msg before disabling immediate-quit.
+ [FIXME: lookup_symbol and vx_open changes need testing.]
+
+ target.c, remote-eb.c, inftarg.c, am29k-opcode.h, target.h,
+ tm-29k.h, tmm-vxworks68.h, symfile.c, gdb-int.texinfo: Add
+ contributor lines and update copyrights to 1991.
+
+ Changes from an attempted H-PUX host port:
+
+ * infptrace.c (PT_ATTACH, PT_DETACH): Handle HP/UX, which
+ defines PT_ATTACH and PT_DETACH but not PT_KILL.
+ * remote-eb.c (eb_open): Misplaced endif kills sysv H/PUX.
+ * remote-vx.c: include <sys/time.h> for HPUX.
+ * hp300hpux-xdep.c (fetch_core_registers): Rewrite old
+ "core_file_command" routine to BFD regime. May not work yet.
+
+ Attempted port of "gdb-3.4 Van Jacobson xgdb" to modern gdb.
+
+ * xgdb.c: Replace X10 version with some VJ version.
+ (FIXME: Its copyright assignment is not on record.)
+ * xgdb.c: Update include files to X11R4 (Xaw crud).
+ (xgdb_display_source, create_text_widget): fix call to
+ get_filename_and_charpos. Rewack source window stuff for X11R4
+ (gleaned from include files, and "nm's" of binary libraries, since
+ I had no doc available).
+ (append_selection, append_selection_word): Disable with FIXME
+ since R4 changed interface here.
+ (create_buttons): Add back the old set of buttons.
+ (xgdb_create_window): Fix call to XtInitialize (&argc not argc).
+
+ * Makefile.dist (xgdb, xgdb-init.c): Update for X11R4 on Suns.
+ Roll VERSION to 3.94 (not yet final though).
+
+Sat Feb 9 09:46:25 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * obstack.h (obstack_ptr_grow, obstack_ptr_grow_fast,
+ obstack_int_grow, obstack_int_grow_fast): Eliminate
+ cast on left of assignment, which gives MIPS cc fits and is
+ not Standard C.
+
+ * sparc-pinsn.c (print_insn): Eliminate 'set' test, subsumed by
+ F_ALIAS. Use printf, not fprintf, when not passing a file
+ pointer...
+ (compare_opcodes): Check that identical instructions have
+ identical opcodes, complain otherwise.
+
+ * sparc-opcode.h (st %fsr): Fix opcode "lose" mask. This
+ was reported by Roland McGrath.
+ (unimp): Only match if exactly zero instruction. (Roland)
+ (branches and traps): Generate all variations of these
+ instructions with macros, based on a single call that defines
+ each condition name and its binary representation.
+ (set): Turn on alias bit, to avoid test in sparc-pinsn.c.
+
+ * valprint.c (val_print_fields): Take, and use, format parameter.
+ This means that "p/x struct" again prints the elements in the
+ desired format. Changed callers.
+
+ * stack.c (frame_info): Use filtered output, and indicate wrap
+ points. Remove kludgy formatting designed to avoid line wrap.
+
+ * utils.c (wrap_here): If the line is already full (because
+ we had printed a long indent or long wrapped string), do an
+ immediate newline-and-indent.
+
+ * m68k-pinsn.c (print_insn_arg): Bugfix from
+ ntmtv!thompson@ames.arc.nasa.gov (Mike Thompson): 'bkpt #0'
+ instruction is incorrectly disassembled as bkpt #8.
+
+ * dbxread.c (end_psymtab): Bugfix from Peter Schauer
+ <pesrem@regent.e-technik.tu-muenchen.de>: If you want to set a
+ breakpoint in a *.y file gdb will say Reading in symbols for *.y...
+ and then will dump core (sometimes). I traced it back to an
+ uninitialized symfile_name in psymtab_to_symtab.
+ (const_vol_complaint): Add quotes to message.
+ (define_symbol): Only believe line number if gcc_compiled.
+ Avoid allocating symbol if we will not return it.
+
+ Add target strata support so that newly established targets go
+ into their right place in the target stack (e.g. a new exec file
+ doesn't wipe out the ability to access the running process).
+
+ * target.h, core.c, exec.c, inftarg.c, remote-eb.c,
+ remote-nindy.c, remote-vx.c, remote.c, target.c: Add to_stratum
+ and initialize it properly in all the targets.
+
+ * target.h: Document strata. Change return type of push_target.
+
+ * target.c (nomemory): new function for dummy memory access.
+ (tcomplain): Rename complain, now also used in symfile.c.
+ (push_target): Push targets within strata. New return value shows
+ whether new target is on top of stack or not. Always keep dummy
+ target on stack.
+ (target_files_info): Ignore dummy target.
+
+ * core.c (core_open): Warn user, and skip accessing file, if the
+ core target is not the topmost target in the stack.
+ * remote-nindy.c (nindy_create_inferior): Avoid unpush_target, now
+ already handled.
+
+ * remote-vx.c: Remove vx_prepare_to_store from vxworks memory
+ target_ops, it doesn't belong there since we have no regs there.
+ Change name of target from machine => memory to clarify.
+
+Thu Feb 7 16:32:09 1991 John Gilmore (gnu at spiff.cygnus.com)
+
+ * Freeze version 3.93 for release.
+
+ * Makefile.dist: Handle vx-share and nindy-share subdirs
+ properly when building gdb.tar.Z.
+
+ * symtab.c: lint; add no_symtab_msg to consolidate the messages
+ printed in various places, so I could change just one copy.
+
+ * dbxread.c, coffread.c: Change references to bfd->iostream
+ to cast to FILE *, now that BFD avoids needing types defined
+ in other header files.
+
+Tue Feb 5 21:39:35 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * command.c, dbxread.c, expprint.c, infcmd.c, infptrace.c,
+ infrun.c, printcmd.c, remote-nindy.c, source.c, sparc-tdep.c,
+ sparc-xdep.c, symfile.h, symmisc.c, utils.c, valprint.c: Lint
+ (actually gcc -Wall).
+
+ * dbxread.c: Remove first_global_sym, last_global_sym, since
+ they are never referenced.
+
+ * defs.h (baud_rate): Declare.
+ main.c: Define it, and add the -b option to set it.
+
+ * gdb-int.texinfo: Add text on how to define a new host or target
+ architecture, prompted by Per Bothner's questions about MIPS
+ support.
+
+ * gdb.texinfo: Document "complaints". Change doc of -q since
+ gdb no longer prints the copyright and blurb if you specify a file
+ name to be debugged (just like Emacs). Add doc for Nindy-specific
+ command line flags for specifying target serial port and such.
+ Update copyright to 1991.
+
+ * gdbcore.h: Remove a large mass of now-useless crud, since BFD
+ has taken over for us the job of ripping up executable files. The
+ crud caused Per Bothner's port to not compile.
+
+ * infrun.c (normal_stop): Avoid printing "Program exited
+ normally" if we are in batch mode. This allows a GDB which
+ executes a program on a target system, to behave like a Unix
+ command (input from stdin, output to stdout, no extraneous
+ output).
+
+ * main.c (main): Allow additional machine-dependent command line
+ options to be specified with the ADDITIONAL_OPTIONS,
+ ADDITIONAL_OPTION_CASES, ADDITIONAL_OPTION_HELP, and
+ ADDITIONAL_OPTION_HANDLER macros. Also allow machine-dependent
+ processing to occur just before the main loop with
+ BEFORE_MAIN_LOOP_HOOK.
+ (main): If a "core file" argument is specified, and it is not a
+ core file, try it as a process ID to attach.
+ (symbol_completion_function): Attempt to cope with
+ "show screen-" TAB, not very successfully. This needs more work,
+ FIXME.
+ (batch_file): New function, returns whether we are reading
+ commands from an interactive tty on stdin, or from somewhere else.
+ Called by normal_stop since it doesn't get from_tty passed down
+ to it like many commands do.
+
+ * remote-nindy.c: Handle command line options for nindy
+ connection.
+ (nindy_before_main_loop): Prompt user for tty name if they
+ don't specify it before getting to the interactive command loop.
+
+ * tm-i960.c: Add ADDITIONAL_OPTIONS, etc, to handle -O, -brk,
+ and -r command line options. Also add hook before main loop
+ to make it easy to specify a tty.
+
+ * TODO: More things to do, one done.
+
+Mon Feb 4 23:57:39 1991 John Gilmore and Mike Tiemann (at cygint.cygnus.com)
+
+ * dbxread.c: Make complaint() calls pass pointer, not struct.
+ Add complaints about badly formatted C++ type information
+ (const/volatile indicator, and parse errors resulting in
+ error_type). Fix C++ virtual member fn comment.
+ (read_struct_type): Avoid bumping pointer if we got a parse
+ error; this prevents our walking beyond the end of a string.
+ Terminate loop on null char as well as semicolon.
+ (process_one_symbol): Fix the LBRAC fix so that it uses the
+ last previous SLINE, FUN, or SO record's PC address. C++ debug
+ symbols did not have SLINE records in a useful order compared
+ to the LBRAC records.
+ (define_symbol): Handle "catch" records.
+
+ * symtab.c (check_stub_type): Added new complain
+ `stub_noname_complain' and added a consistency check to
+ keep the debugger from crashing when finishing from an
+ exception frame. A real fix will be needed later.
+
+Sat Feb 2 10:43:05 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * infcmd.c (attach_command): Make global.
+
+ * Makefile.dist (REMOTE_OBS): Make these compile by default,
+ but make them easy to comment out. Perhaps later they should
+ be enabled by what CPU you configure for? FIXME.
+ (VERSION): Roll to 3.93.
+ (pinsn.o): Remove rule for obsolete file.
+ (dbxread.o,coffread.o,mipsread.o): Use ${srcdir} explicitly.
+
+ Run down a problem that manifested by printing the wrong function
+ name in stack traces of read_ofile_symtab. Turned out that the
+ problem was the SunOS 4.1.1 (and previous) C compiler outputs
+ the LBRAC symbol with an address in the *data* segment, which
+ blew our binary search through the blocks.
+
+ * dbxread.c: Use the complain() facility consistently to bitch
+ about problems in the symbol file we are reading.
+ (finish_block): Add code to check the nesting of the blocks;
+ complain and Procrust them to fit if wrong.
+ (make_blockvector): Check the order of the blocks, complain
+ [but don't cope] if wrong.
+ (process_one_symbol): ifndef SUN_FIXED_LBRAC_BUG, check LBRAC
+ symbols to be sure their PC value is greater than the last SLINE
+ (line number) symbol we've seen, complaining and adopting the
+ SLINE PC value if wrong.
+
+ * symfile.h (struct complaint, complaint_root, complain,
+ clear_complaints): Add.
+ * symfile.c (complain, complaint_root, clear_complaints): Add
+ facility to deal with non-fatal complaints and to regularize their
+ suppression.
+ (symbol_file_add): Clear complaint counters to allow new complaints.
+ (initialize_symfile): Add 'set complaints' and 'show complaints'.
+
+ * dbxread.c (dbx_symfile_read): Remember the address and size
+ of the string table for the main symbol file, so we won't read it
+ more than once.
+ (dbx_psymtab_to_symtab): Fix the check for main symbol file,
+ to avoid reading the string table yet again. Lint.
+ (throughout): Improve filtered output, including word wrap.
+ (read_range_type): Improve Bothner's fix to handle other types too.
+
+ * utils.c: Improve line wrap implementation. Handle unlimited
+ width by making chars_per_line unsigned.
+ (puts_filtered): New, easy, function.
+
+ * defs.h (puts_filtered): add.
+
+ * mipsread.c (compare_symbols, sort_symtab): Remove these fns,
+ call the identical sort_symtab_syms() in symfile.c instead.
+
+ * expread.y: Suggest the `file' command rather than `symbol-file'.
+
+ * command.h (enum var_types): Add zinteger for seroable
+ unsigned integer.
+ * command.c (do_setshow_command): Handle var_zinteger. Restructure
+ nested if's into a switch.
+
+ * breakpoint.c (bpstat_print): If bpstat "print" flag is not set,
+ we did not stop because of a breakpoint (it must have been for
+ some other reason, like a "stepi"), so don't print anything.
+
+ * symtab.c: Include <sys/types.h> all the time. Now that BFD
+ doesn't include <sys/types.h>, old SunOS's require it for
+ <sys/stat.h>.
+
+Sat Feb 2 10:39:15 1991 Per Bothner (bothner@cs.wisc.edu)
+
+ A test port of gdb-3.92.6 to the Sony NEWS.
+
+ * Makefile.dist
+ Don't normally link in remote- or vx stuff.
+ Some of it doesn't compile, and it wastes space for 99% of the users.
+ Remove reference to no-longer-used HAVE_VPRINTF.
+ Fixed BFD_DEP typo to BFD_DIR.
+ * dbxread.c
+ Fix cast in arg to bfd_h_getlong.
+ Make char *prefix be const.
+ Fix how certain range types are mapped into builtin unsigned int types.
+ * infrun.c
+ Remove 2 #includes. They cause errors (on Sony, at least),
+ and aren't needed (they wern't in earlier versions).
+ * printcmd.c
+ print_address_symbolic should never demangle labels
+ (since it prints *assembler-level* labels).
+
+ [This was superseded by the change to printcmd below.]
+
+ * utils.c
+ Add some "volatile" return types to avoid warnings.
+ If MISSING_VPRINTF add vprintf function and not just macro
+ (since vprintf is used in printcmd.c).
+ * valprint.c
+ Unless __GNUC__, use obstack_grow instead of obstack_ptr_grow.
+ (The latter isn't grokked by some PCC-based compilers.)
+
+ [This change is in abeyance, we prefer to fix obstack_ptr_grow.]
+
+ Make chunk size of dont_print_obstack 32*4 instead of default 4096.
+ * nindy-share/coffstrip.c
+ Added some forward declarations (otherwise, gcc complains
+ about implicit extern redefined as static).
+
+Sun Jan 20 02:38:19 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Changes inspired by Per Bothner:
+ * printcmd.c (print_address_symbolic): Take additional parameter
+ specifying whether to demangle.
+ (print_address): Pass in asm_demangle to control demangling.
+ (print_address_demangle): New fn, takes explicit arg to control
+ demangling.
+ * utils.c: Add new vars demangle and asm_demangle, and let them
+ be set and shown.
+ (fputs_demangled): If !demangle, just print the argument.
+ (fprint_symbol): If !demangle, just print raw symbol.
+ * valprint.c (val_print): Call print_address_demangle rather than
+ print_address, to cause demangling to depend on the global
+ rather than assembler-level demangling setting.
+ * WHATS.NEW, gdb.texinfo: Document.
+
+ * main.c (show_command): Show all settings if no arg.
+ (initialize_main): Make "info set" the same as naked "show".
+ * command.c (cmd_show_list): Handle prefix commands in the
+ list, and print the name of the setting as well as its English
+ description and value.
+
+ Allow gdb functions to specify where a line should wrap if it
+ exceeds the size of a terminal line. Use it to make the output
+ prettier.
+ * utils.c (set_screen_width_command): New fn, mallocs a buffer
+ of the right size when screen width changes.
+ (set_screensize_command, screensize_info): Remove #if 0'd fns.
+ (wrap_here): New fn, indicates a point in the output where we
+ should wrap the line rather than just letting it overflow at a
+ random place.
+ (fputs_filtered): Implement wrapping.
+ (n_spaces): New fn, returns a pointer to N spaces.
+ (print_spaces_filtered): Use n_spaces.
+ * defs.h (n_spaces): Declare.
+ * stack.c (print_frame_info): Wrap with 4-space indent after
+ fn name and before filename and line number.
+ * printcmd.c (print_frame_args): Wrap with 4-space indent
+ before each argument name is printed.
+ * valprint.c (value_print): Wrap with no indentation before
+ each repetition.
+ (val_print_fields): Wrap with indentation relative to nesting
+ level before each field name.
+ (val_print): Wrap with nesting indentation before array elements.
+ * command.c (do_setshow_command): Avoid extra newlines,
+ wrap with 4-space indent around values printed, end with period.
+ * WHATS.NEW, gdb.texinfo, gdb-int.texinfo: Document.
+
+ * breakpoint.c (breakpoint_1): Implement addressprint for
+ "info breakpoints" display. Change file name and line number
+ format to " at file:nnn" rather than " (file line nnn)".
+ * gdb.texinfo: Document.
+
+
+Fri Jan 18 07:21:25 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Frozen for gdb-3.92.6 release.
+
+ README, WHATS.NEW: Update for 3.92.6 release.
+
+ tconfig/{altos, i386v, i386v32, m88k, umax}: Eliminate
+ coffread.o from configs since it is now built by default.
+ tconfig/{3b1, altosgas, arm, convex, hp300bsd, hp300hpux,
+ i386v-g, i386v32-g, isi, merlin, news, news1000, np1, pn,
+ pyramid, symmetry, vax, vxworks68}: Eliminate dbxread.o
+ from configs since it is now built by default.
+
+ Makefile.dist: Update for release 3.92.6. Handle files that
+ have been moved to ../include, ../getopt, or ../bfd. Add
+ saber.suppress and tests directory. Add config.status to
+ the release (it will say "none").
+
+ coredep.c: Minor formatting fixes.
+
+ These changes were made in early December but only checked in now:
+ * nindy-share/Onindy.c, nindy-share/coffstrip.c,
+ nindy-share/nindy.c: lint
+ * nindy-share/nindy.c (ninStopWhy): Don't byteswap the
+ register values coming back from the target; we store values
+ in target byte order everywhere.
+
+Wed Jan 16 19:01:37 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * am29k-opcode.h, am29k-pinsn.c: Add 29050 opcodes.
+
+ * valprint.c (cplus_val_print, val_print_fields): New functions,
+ which print C++ objects. They conspire to avoid printing a
+ virtual base class more than once, following all the twists and
+ turns of C++ virtual base rules.
+ (val_print): Call the above rather than do it by hand.
+
+ * symfile.c (symbol_file_add): Only reset symfile_mtime for main
+ symbol file, not for added files like shared libs. This really
+ needs to be generalized to a timestamp per file.
+
+ * core.c (cleanup_core): Avoid coredump if no core file.
+
+ * config.gdb: Accept -host or -target in place of +host or
+ +target.
+
+ * coffread.c (find_linenos): Avoid desupported BFD interface
+ to line numbers. We still read them manually rather than using
+ BFD's "generic" features.
+
+ * gdbrc.tex, threecol.tex: Add GDB reference card and its
+ formatting code.
+ Makefile.dist: Add refcard to OTHERS list for creating tar files.
+
+ * Makefile.dist: Eliminate use of $< in explicit targets.
+
+ * readline/Makefile: Use $< rather than $*.c, which does not
+ include the VPATH in GNU Make.
+
+ * tconfig/i960-bout, tconfig/i960-coff: These are identical
+ copies of tconfig/i960, added for global configuration
+ compatability. All i960 versions can read both coff and b.out.
+
+ * tm-88k.h: Fix multiline macro that lacked \'s. Remove
+ COFF_FORMAT and COFF_CHECK_X_ZEROES since these are now handled
+ automaticaly.
+
+ * TODO: Think of more things to do.
+
+Wed Jan 2 19:09:29 1991 John Gilmore (gnu at spiff.cygnus.com)
+
+ tconfig/{am29k,i960,sun2*,sun3*,sun4*}: Eliminate config
+ of sdb versus dbx debug symbols. Add kludge for 68881 80-bit to
+ 64-bit float conversion.
+
+ tconfig/sun4, tconfig/sun3, xconfig/sun4, xconfig/sun3: Make
+ equivalent to sun?os4 so global config works.
+
+Wed Jan 2 18:20:51 1991 John Gilmore (gnu at spiff.cygnus.com)
+
+ Fix from Eberhard Mattes <mattes@azu.informatik.uni-stuttgart.de>
+
+ * main.c: Only declare linesize once; declare pagesize not at
+ all, since it is never used.
+ (main): Clear newly allocated line before it is used.
+
+For older changes see ChangeLog-1990
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/ChangeLog-1992 b/gdb/ChangeLog-1992
new file mode 100644
index 00000000000..8e89824af47
--- /dev/null
+++ b/gdb/ChangeLog-1992
@@ -0,0 +1,6285 @@
+Thu Dec 31 11:06:38 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (BISON): Add comment that when bison is used, it
+ must include the "-y" option.
+ * c-exp.y, m2-exp.y (yyrule, yyname, yyss, yyssp, yyvs, yyvsp):
+ Remove defines to remap non-yacc symbols, thus backing out of
+ previous recent changes. Standard policy is that non-yacc parser
+ generators get fixed, rather than adding bug workarounds in gdb
+ for each new one that pops up. Expand comment to note this.
+ * c-exp.y, m2-exp.y (YYDEBUG): Revert back to disabled by default.
+
+Thu Dec 31 09:03:02 1992 Stu Grossman (grossman at cygnus.com)
+
+ * partial-stab.h (near N_BINCL): Remove redundant code in N_BINCL
+ case. Use code in N_SOL.
+
+ * paread.c: New file that contains all HPPA/HPUX symbol reading
+ code.
+ * dbxread.c: Remove almost all HPPA/HPUX symbol reading code.
+ * (dbx_symfile_init): Use sizeof(long) instead of 4.
+ * (dbx_symfile_offsets): Make static.
+ * (pastab_build_psymtabs): New interface routine for paread to
+ send stabs into dbxread.
+ * gdb-stabs.h: Remove gobs of HPPA cruft.
+
+Wed Dec 30 19:47:13 1992 Fred Fish (fnf@cygnus.com)
+
+ * c-exp.y, m2-exp.y (yyrule, yyname): Remap like other yy* names
+ for byacc.
+ * ch-exp.y (yyrule, yyname): Remap like other yy* names for byacc.
+
+ * c-exp.y, m2-exp.y (yyreds, yytoks): Remap like other yy* names.
+ * c-exp.y, m2-exp.y (YYDEBUG): Define if MAINTENANCE_CMDS is defined
+ and YYDEBUG is not already defined.
+ * c-exp.y (strncmp): Replace throughout with STREQN, missed
+ them during the previous replacements.
+ * printcmd.c (_initialize_printcmd): Update internal documentation
+ for "set" command to note that the assignment syntax is language
+ dependent.
+ * ch-exp.y (yyreds, yytoks): Remap like other yy* names.
+ * ch-exp.y (YYDEBUG): Define if MAINTENANCE_CMDS is defined
+ and YYDEBUG is not already defined.
+ * ch-exp.y (GDB_REGNAME, GDB_LAST, GDB_VARIABLE, GDB_ASSIGNMENT,
+ single_assignment_action): New terminals and nonterminal for gdb
+ extensions to chill expression grammer.
+ * ch-exp.y (match_dollar_tokens): Lexer routine to match all
+ tokens that start with '$' (register names, convenience vars, etc).
+ * ch-exp.y (tokentab2): Add GDB_ASSIGNMENT.
+ * ch-exp.y (yylex): Call match_dollar_tokens.
+
+Mon Dec 28 15:00:01 1992 Stu Grossman (grossman at cygnus.com)
+
+ * hppah-tdep.c (skip_trampoline_code): Use new macros for
+ accessing minimal symbol data.
+ * infcmd.c (read_pc): Use #ifdef, not #if.
+ * symfile.c (syms_from_objfile): Add CONST to decl for targets.
+ * tm-hppa.h (FIX_CALL_DUMMY): Use new macros for accessing
+ minimal symbol data.
+
+ * hppah-tdep.c (frame_saved_pc): Use better test for outermost
+ frame. Use find_return_regnum to find the caller.
+ * (find_unwind_entry): New routine to locate stack frame info
+ associated with a procedure. This looks in the $UNWIND_START$
+ section in the SOM file.
+ * (find_return_regnum): New routine. Uses find_unwind_entry() to
+ figure out where the caller's return address is stored.
+ * (find_proc_framesize): New routine. Uses find_unwind_entry()
+ to figure out the frame size for a procedure.
+ * (saved_pc_after_call): New routine, moved from tm-hppa.h.
+ * (init_extra_frame_info): New routine. Corrects PC and FP for
+ outermost frame if necessary.
+ * (frame_chain): New routine, moved from tm-hppa.h.
+ * (skip_trampoline_code): Handle computed function calls (ie:
+ calls from $$dyncall).
+ * (unwind_command): Temporary support function to allow user
+ to control/observe aspects of the unwind (stack frame) info.
+ * infcmd.c (read_pc): (Temporary), put a hack in to see if the PC
+ was in a system call, if so, then read the PC from r31.
+ * tm-hppah.h (SKIP_TRAMPOLINE_CODE, IN_SOLIB_TRAMPOLINE): Deal
+ with extra arg for skip_trampoline_code().
+ * (INIT_EXTRA_FRAME_INFO): Define to point at subr (see above).
+ * (FRAME_CHAIN, FRAME_CHAIN_VALID): Turn into real subroutines.
+ * tm-hppa.h (SAVED_PC_AFTER_CALL): Turn into real subroutine.
+
+Sun Dec 27 17:34:15 1992 Fred Fish (fnf@cygnus.com)
+
+ * dbxread.c (dbx_symfile_init, elfstab_build_psymtabs):
+ Call new bfd_get_size() and verify that string table is no larger
+ than the file that is supposed to contain it.
+ * symfile.c (syms_from_objfile): Only complain about configured
+ NAMES_HAVE_UNDERSCORE differences between gdb and bfd if the
+ current target is the default BFD target.
+
+Sat Dec 26 20:51:41 1992 Fred Fish (fnf@cygnus.com)
+
+ * solib.c (BKPT_AT_MAIN): Change to BKPT_AT_SYMBOL.
+ * solib.c (bkpt_names): New array of symbol names to try to
+ use for the "mapping complete" breakpoint. Configurable
+ define SOLIB_BKPT_NAME is first one to try.
+ * solib.c (find_solib): Test debug_base for nonzero rather
+ than just greater than zero.
+ * solib.c (enable_break): Use bkpt_names to look up address
+ at which to set "mapping complete" breakpoint.
+
+Tue Dec 22 20:33:38 1992 Fred Fish (fnf@cygnus.com)
+
+ * defs.h (STRCMP, STREQ, STREQN): New macros.
+ * defs.h (demangle_and_match): Remove prototype.
+ * dwarfread.c (STREQ, STREQN): Remove macros, replaced with STREQ
+ and STREQN defined in defs.h.
+ * dwarfread.c (set_cu_language): For completely unknown languages,
+ try to deduce the language from the filename. Retain behavior
+ that for known languages we don't know how to handle, we use
+ language_unknown.
+ * dwarfread.c (enum_type, symthesize_typedef): Initialize language
+ and demangled name fields in symbol.
+ * dwarfread.c, mipsread.c, partial-stab.h: For all usages of
+ ADD_PSYMBOL_TO_LIST, add language and objfile parameters.
+ * dwarfread.c (new_symbol): Attempt to demangle C++ symbol names
+ and cache the results in SYMBOL_DEMANGLED_NAME for the symbol.
+ * elfread.c (STREQ): Remove macro, use STREQ defined in defs.h.
+ Replace usages throughout.
+ * elfread.c (demangle.h): Include.
+ * elfread.c (record_minimal_symbol): Remove prototype and function.
+ * gdbtypes.h, symtab.h (B_SET, B_CLR, B_TST, B_TYPE, B_BYTES,
+ B_CLRALL): Moved from symtab.h to gdbtypes.h.
+ * infcmd.c (jump_command): Remove code to demangle name and add
+ it to a cleanup list. Now just use SYMBOL_DEMANGLED_NAME.
+ * minsyms.c (demangle.h): Include.
+ * minsyms.c (lookup_minimal_symbol): Indent comment to match code.
+ * minsyms.c (install_minimal_symbols): Attempt to demangle symbol
+ names as C++ names, and cache them in SYMBOL_DEMANGLED_NAME.
+ * mipsread.c (psymtab_language): Add static variable.
+ * stabsread.c (demangle.h): Include.
+ * stabsread.c (define_symbol): Attempt to demangle C++ symbol
+ names and cache them in the SYMBOL_DEMANGLED_NAME field.
+ * stack.c (return_command): Remove explicit demangling of name
+ and use of cleanups. Just use SYMBOL_DEMANGLED_NAME.
+ * symfile.c (demangle.h): Include.
+ * symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list): Fix
+ to match macros in symfile.h and allow them to be compiled
+ if INLINE_ADD_PSYMBOL is not true.
+ * symfile.h (INLINE_ADD_PSYMBOL): Default to true if not set.
+ * symfile.h (ADD_PSYMBOL_*): Add language and objfile parameters.
+ Add code to demangle and cache C++ symbol names. Use macro form
+ if INLINE_ADD_PSYMBOL is true, otherwise use C function form.
+ * symmisc.c (add_psymbol_to_list, add_psymbol_addr_to_list):
+ Remove, also defined in symfile.c, which we already fixed.
+ * symtab.c (expensive_mangler): Remove prototype and function.
+ * symtab.c (find_methods): Remove physnames parameter and fix
+ prototype to match.
+ * symtab.c (completion_list_add_symbol): Name changed to
+ completion_list_add_name.
+ * symtab.c (COMPLETION_LIST_ADD_SYMBOL): New macro, adds both
+ the normal symbol name and the cached C++ demangled name.
+ * symtab.c (lookup_demangled_partial_symbol,
+ lookup_demangled_block_symbol): Remove prototypes and functions.
+ * symtab.c (lookup_symbol): Remove use of expensive_mangler,
+ use lookup_block_symbol instead of lookup_demangled_block_symbol.
+ Remove code to try demangling names and matching them.
+ * symtab.c (lookup_partial_symbol, lookup_block_symbol):
+ Fix to try matching the cached demangled name if no match is
+ found using the regular symbol name.
+ * symtab.c (find_methods): Remove unused physnames array.
+ * symtab.c (name_match, NAME_MATCH): Remove function and macro,
+ replaced with SYMBOL_MATCHES_REGEXP from symtab.h.
+ * symtab.c (completion_list_add_symbol): Rewrite to use cached
+ C++ demangled symbol names.
+ * symtab.h: Much reformatting of structures and such to add
+ whitespace to make them more readable, and make them more
+ consistent with other gdb structure definitions.
+ * symtab.h (general_symbol_info): New struct containing fields
+ common to all symbols.
+ * symtab.h (SYMBOL_LANGUAGE, SYMBOL_DEMANGLED_NAME,
+ SYMBOL_SOURCE_NAME, SYMBOL_LINKAGE_NAME, SYMBOL_MATCHES_NAME,
+ SYMBOL_MATCHES_REGEXP, MSYMBOL_INFO, MSYMBOL_TYPE): New macros.
+ * symtab. (struct minimal_symbol, struct partial_symbol, struct
+ symbol): Use general_symbol_info struct.
+ * utils.c (demangle_and_match): Remove, no longer used.
+ * valops.c (demangle.h): Include.
+ * xcoffexec.c (eq): Remove macro, replace usages with STREQ.
+ * blockframe.c, breakpoint.c, c-exp.y, c-valprint.c, dbxread.c,
+ infcmd.c, m2-exp.y, minsyms.c, objfiles.h, solib.c, stack.c,
+ symmisc.c, symtab.c, valops.c: Replace references to minimal
+ symbol fields with appropriate macros.
+ * breakpoint.c, buildsym.c, c-exp.y, c-typeprint.c, c-valprint.c,
+ coffread.c, command.c, convex-tdep.c, cp-valprint.c, dbxread.c,
+ demangle.c, elfread.c, energize.c, environ.c, exec.c,
+ gdbtypes.c, i960-tdep.c, infrun.c, infrun-hacked.c, language.c,
+ main.c, minsyms.c, mipsread.c, partial-stab.h, remote-es1800.c,
+ remote-nindy.c, remote-udi.c, rs6000-tdep.c, solib.c, source.c,
+ sparc-pinsn.c, stabsread.c, standalone.c, state.c, stuff.c,
+ symfile.c, symmisc.c, symtab.c, symtab.h, tm-sysv4.h,
+ tm-ultra3.h, values.c, xcoffexec.c, xcoffread.c: Replace strcmp
+ and strncmp usages with STREQ, STREQN, or STRCMP as appropriate.
+ * breakpoint.c, buildsym.c, c-typeprint.c, expprint.c, findvar.c,
+ mipsread.c, printcmd.c, source.c, stabsread.c, stack.c,
+ symmisc.c, tm-29k.h, valops.c, values.c: Replace SYMBOL_NAME
+ references with SYMBOL_SOURCE_NAME or SYMBOL_LINKAGE_NAME as
+ appropriate.
+ * buildsym.c (start_subfile, patch_subfile_names): Default the
+ source language to what can be deduced from the filename.
+ * buildsym.c (end_symtab): Update the source language in the
+ allocated symtab to match what we have been using.
+ * buildsym.h (struct subfile): Add a language field.
+ * c-typeprint.c (c_print_type): Remove code to do explicit
+ demangling.
+ * dbxread.c (psymtab_language): Add static variable.
+ * dbxread.c (start_psymtab): Initialize psymtab_language using
+ deduce_language_from_filename.
+
+Mon Dec 21 22:24:33 1992 Fred Fish (fnf@cygnus.com)
+
+ * valprint.c (val_print): Reorganize comment and add note
+ about dependency on target byte ordering.
+ * ch-exp.y (value_array_slice): Fix typo.
+ * ch-valprint.c (chill_val_print): Remove C'ism that arrays of
+ byte sized ints are assumed to be char strings and printed with
+ string syntax. In chill, arrays of chars and arrays of
+ bytes/ubytes are distinquishable, and printed appropriately.
+
+Mon Dec 21 18:02:35 1992 Stu Grossman (grossman at cygnus.com)
+
+ * tm-hppah.h: #define NEED_TEXT_START_END for target memory
+ read/write routines for HPUX.
+
+ * hppa-pinsn.c (print_insn): Improve handling of be and ble
+ branch targets to compute target address using const from previous
+ instruction if necessary.
+ * Add `Q' operator to print out bit position field various
+ instructions.
+ * hppah-nat.c: #include sys/param.h, and sys/user.h. General
+ cleanups, use new code from Utah.
+ * (store_inferior_registers): Update to new code from Utah.
+ * (initialize_kernel_u_addr): Re-enable decl of struct user u.
+ * (fetch_register): Clear out priv level when reading PCs.
+ * hppah-tdep.c: Get rid of gobs of KERNELDEBUG stuff.
+ * Remove decl of errno, #include wait.h and target.h.
+ * (frame_saved_pc): Check `flags' pseudo-register to see if we
+ were inside of a kernel call. If so, then PC is in a different
+ register. Also, mask out bottom two bits of all PCs so as not to
+ confuse higher level code.
+ * (push_dummy_frame): Create from #define in tm-hppa.h.
+ * (find_dummy_frame_regs): Update from Utah.
+ * (hp_pop_frame): Create from #define in tm-hppa.h.
+ * (hp_restore_pc_queue): New, from Utah.
+ * (hp_push_arguments): Big fixes from Utah.
+ * (pa_do_registers_info, pa_print_registers): Only print out fp
+ regs upon request.
+ * (skip_trampoline_code): New routine to deal with stubs that
+ live in nowhereland between callers and callees.
+ * i860-tdep.c: Remove decl of attach_flag.
+ * infrun.c (wait_for_inferior): Add new macro
+ INSTRUCTION_NULLIFIED, which can tell if the instruction pointed
+ at by PC will be nullified. If so, then step the target once more
+ so as to avoid confusing the user.
+ * (just before step_over_function:): Use stop_func_start, not
+ stop_pc when checking for the existance of line number info.
+ stop_func_start will reflect the proper address of the target
+ routine, not of the stub that we may be traversing to get there.
+ * tm-hppa.h: define SKIP_TRAMPOLINE_CODE and IN_SOLIB_TRAMPOLINE
+ to deal with the stubs that PA compilers sometimes stick between
+ callers and callees. Also, define FLAGS_REGNUM for access to the
+ `flags' pseudo-reg.
+ * (REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW): Use
+ memcpy, not bcopy.
+ * (CANNOT_STORE_REGISTER): New from Utah. Says that we can't
+ write gr0, PC regs, and PSW!
+ * (FRAME_FIND_SAVED_REGS): Bug fixes from Utah.
+ * (PUSH_DUMMY_FRAME, POP_FRAME): Make into real routines in
+ hppah-nat.c.
+ * (CALL_DUMMY, FIX_CALL_DUMMY): Fixes from Utah.
+ * Define struct unwind_table_entry.
+ * valops.c (call_function_by_hand): Add another arg to
+ FIX_CALL_DUMMY (under #ifdef GDB_TARGET_IS_HPPA). Why is this
+ necessary?
+
+Mon Dec 21 02:17:57 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * remote-vx.c: remove include of "symfile.h", replace it with "complaints.h"
+
+Fri Dec 18 10:32:25 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.7.4.
+ * Makefile.in (SFILES_MAINDIR): Add typeprint.c, c-typeprint.c,
+ m2-typeprint.c, c-valprint.c cp-valprint.c m2-valprint.c.
+ * Makefile.in (HFILES): Add valprint.h.
+ * Makefile.in (OBS): Add typeprint.o, c-typeprint.o,
+ m2-typeprint.o, c-valprint.o, cp-valprint.o m2-valprint.o.
+ * typeprint.c, typeprint.h: New files for language independent
+ type printing functions.
+ * c-typeprint.c, m2-typeprint.c: New files for language dependent
+ type printing functions and definitions.
+ * valprint.h: New include file for language independent value
+ printing definitions.
+ * c-valprint.c, cp-valprint.c, m2-valprint.c: New files for language
+ dependent value printing functions.
+ * c-exp.y (production ptype): Add range_type variable and use new
+ create_range_type function.
+ * c-exp.y (tokentab2, tokentab3), c-lang.c (c_op_print_tab),
+ infcmd.c (path_var_name), language.c (unk_op_print_tab),
+ m2-lang.c (m2_op_print_tab): Change from ANSI-obsolescent
+ "const static" to ANSI-conformant "static const".
+ * c-exp.y (c_create_fundamental_type): Remove unused nbytes.
+ * c-exp.y (c_language_defn, cplus_language_defn): Add c_print_type,
+ and c_val_print.
+ * c-lang.h (c_print_type, c_val_print): Add prototypes.
+ * coffread.c (decode_type): Add range_type variable and call to
+ new create_range_type function.
+ * complaints.c (complain): Remove unused val variable.
+ * complaints.c (_initialize_complaints): Make it void.
+ * convex-tdep.c (value_of_trapped_internalvar): Add range_type
+ variable and call new create_range_type function.
+ * defs.h (enum val_prettyprint): Move enum from value.h to here
+ so we can avoid having to include value.h just for prototypes that
+ need the enum (thanks ANSI).
+ * dwarfread.c (struct_type): Local anonymous_size variable is
+ only used if !BITS_BIG_ENDIAN.
+ * dwarfread.c (decode_subscript_data_item): Add rangetype
+ variable and call new create_range_type function.
+ * elfread.c (elf_symfile_read): Remove unused dbx and text_sect
+ variables.
+ * eval.c (evaluate_subexp): Remove unused local variable name
+ and the statement with no side effects that initializes it.
+ * expprint.c (print_subexp): Change local_printstr to
+ LA_PRINT_STRING.
+ * gdbtypes.c (create_range_type): New function that creates
+ a range type using code fragments from object file readers as
+ an example of what has to be initialized.
+ * gdbtypes.c (create_array_type): Removed index_type, low_bound,
+ and high_bound parameters, replaced with a single range_type
+ parameter. Change function body to use passed in range_type
+ rather than handcrafting one.
+ * gdbtypes.h (create_range_type): Add prototype.
+ * gdbtypes.h (create_array_type): Change prototype parameters.
+ * infrun.c (normal_stop): Remove unused local variables tem and c.
+ * infrun.c (hook_stop_stub): Return 0 rather than random value.
+ * language.c (unk_lang_print_type, unk_lang_val_print): Add
+ stub functions that call error if called.
+ * language.c (unknown_language_defn, auto_language_defn,
+ local_language_defn): Add initializers unk_lang_print_type and
+ unk_lang_val_print.
+ * language.h (struct language_defn): Reformat for larger
+ comments, add la_print_type and la_val_print members. Add
+ LA_PRINT_TYPE and LA_VAL_PRINT macros. Change local_printchar
+ to LA_PRINT_CHAR and local_printstr to LA_PRINT_STRING.
+ * m2-lang.c (m2_create_fundamental_type): Remove unused local
+ variable nbytes.
+ * m2-lang.c (m2_language_defn): Add initializers m2_print_type
+ and m2_val_print.
+ * m2-lang.h (m2_print_type, m2_val_print): Add prototypes.
+ * main.c (execute_command): Remove unused local variable cmdlines.
+ * main.c (echo_command), stabsread.c (read_type), printcmd.c
+ (clear_displays), symmisc.c (block_depth), values.c
+ (clear_value_history):
+ Make testing of truth value of assignment result explicit.
+ * mipsread.c (upgrade_type): Update FIXME to include future use
+ of create_range_type.
+ * printcmd.c (ptype_command, ptype_eval, whatis_command,
+ whatis_exp, maintenance_print_type): Move prototypes and functions
+ to new typeprint.c.
+ * printcmd.c (_initialize_printcmd): Move add_com calls for
+ ptype_command and whatis_command to new typeprint.c.
+ * ser-bsd.c (serial_open): Remove unused variable sgttyb.
+ * source.c (find_source_lines): Local variable c only used
+ when LSEEK_NOT_LINEAR is defined.
+ * stabsread.c (read_array_type): Use new create_range_type
+ function.
+ * stabsread.c (read_range_type): Add new index_type variable and
+ call new create_range_type function rather than handcrafting
+ range types.
+ * symmisc.c (type_print_1): Change usages to LA_PRINT_TYPE.
+ * symtab.c (typedef_print usages): Use c_typedef_print, renamed.
+ * symtab.c (type_print_base usages): Use c_type_print_base.
+ * symtab.c (type_print_varspec_prefix usages): Use
+ c_type_print_varspec_prefix.
+ * symtab.c (type_print_method_args usages): Use
+ cp_type_print_method_args.
+ * valprint.c: Completely ripped apart and the fragments used
+ to create c-valprint.c, cp-valprint.c, m2-valprint.c, and
+ valprint.h. Remaining stuff is language independent.
+ * value.h (struct fn_field): Forward declare for prototypes.
+ * value.h (type_print_1): Remove prototype.
+ * value.h (enum val_prettyprint): Moved to defs.h.
+ * value.h (typedef_print): Prototype renamed to c_typedef_print.
+ * value.h (baseclass_offset): Add prototype.
+ * Makefile.in (SFILES_MAINDIR): Add ch-typeprint.c, ch-valprint.c.
+ * Makefile.in (OBS): Add ch-typeprint.o, ch-valprint.o.
+ * ch-typeprint.c: New file for language dependent type printing.
+ * ch-valprint.c: New file for language dependent value printing.
+ * ch-exp.y (parse_number): Remove prototype and stub function.
+ * ch-exp.y (decode_integer_literal): Removed unused digits and
+ temp variables.
+ * ch-exp.y (convert_float): Completely ifdef out for now.
+ * ch-exp.y (tokentab2, tokentab3, tokentab4, tokentab5),
+ ch-lang.c (chill_op_print_tab):
+ Change from ANSI-obsolescent "const static" to ANSI-conformant
+ "static const".
+ * ch-exp.y (yylex): Add unhandled storage class enumeration
+ literals to switch statement for completeness.
+ * ch-lang.c (chill_create_fundamental_types): Remove unused
+ nbytes variable. Change dummy type to 2 bytes to match int.
+ Handle FT_VOID types gratuituously added to chill DWARF by
+ compiler. Change FT_CHAR case to generate an TYPE_CODE_CHAR
+ type rather than a one byte TYPE_CODE_INT type.
+ * ch-lang.c (chill_language_defn): Add chill_print_type and
+ chill_val_print.
+ * ch-lang.h (chill_print_type, chill_val_print): Add prototypes.
+
+Thu Dec 17 00:44:57 1992 John Gilmore (gnu@cygnus.com)
+
+ Eliminate uses of NAMES_HAVE_UNDERSCORE, using
+ bfd_get_symbol_leading_char instead.
+
+ * coffread.c (EXTERNAL_NAME): New macro for removing possible
+ leading character from names.
+ (read_coff_symtab): Use BFD's FILE *, don't open a second one.
+ (process_coff_symbol, coff_read_struct_type, coff_read_enum_type):
+ Replace NAMES_HAVE_UNDERSCORE with EXTERNAL_NAME.
+
+ * kdb-start.c (main): Remove NAMES_HAVE_UNDERSCORE.
+ * minsyms.c (install_minimal_symbols): Replace NAMES_HAVE_UNDERSCORE.
+ Remove SOME_NAMES_HAVE_DOT support (apparently unused).
+ * partial-stab.h: Replace NAMES_HAVE_UNDERSCORE.
+ * solib.c: Replace NAMES_HAVE_UNDERSCORE.
+ * stabsread.h: Remove NAMES_HAVE_UNDERSCORE and HASH_OFFSET.
+ * symfile.c (syms_from_objfile): Insert debugging check to test
+ NAMES_HAVE_UNDERSCORE setting against the BFD support.
+
+ * doc/gdbint.texinfo (Host Conditionals): Remove
+ NAMES_HAVE_UNDERSCORE, SOME_NAMES_HAVE_DOT, document
+ MEM_FNS_DECLARED.
+ (Target Conditionals): Remove all of the above.
+
+ * xm-rs6000.h (MEM_FNS_DECLARED): Update comments.
+
+ * coffread.c (read_coff_symtab, C_BLOCK): Use complain() rather
+ than error() for .bb/.eb. Bug found by Eddie Fung, <efung@cs.uq.oz.au>.
+
+Tue Dec 15 10:05:56 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * coffread.c (decode_type): catch negative tagndx fields generated
+ by SCO 3.2v4 cc.
+ * exec.c: comment out string following #endif.
+ * configure.in (i[34]86-*-sco3.2v4*): use host i386sco4.
+ * xm-i386sco.h: include <sys/types.h> and <sys/dir.h>, required by
+ <sys/user.h>.
+ * config/i386sco4.mh: new file; like i386sco.mh, but don't require
+ gcc, and define const to empty to avoid SCO 3.2v4 cc bug.
+
+Tue Dec 15 04:14:24 1992 Fred Fish (fnf@cygnus.com)
+
+ * complaints.c: New file, code moved from utils.c.
+ * complaints.c (complain): Made into a varargs function.
+ * complaints.h: New file, code moved from symfile.h.
+ * Makefile.in (SFILES_MAINDIR): Add complaints.c.
+ * Makefile.in (HFILES): Add complaints.h.
+ * Makefile.in (OBS): Add complaints.o.
+ * symfile.c (complaint_root, stop_whining, complaint_series,
+ complain, clear_complaints, add_show_from_set for stop_whining):
+ Moved to complaints.c.
+ * symfile.h (struct complaint, complaint_root decl, complain
+ prototype, clear_complaints prototype): Moved to complaints.h.
+ * buildsym.c, coffread.c, dbxread.c, dwarfread.c, elfread.c,
+ gdbtypes.c, mipsread.c, stbsread.c, symfile.c: Include
+ complaints.h. Remove casts from arguments to complain(),
+ which is now a varargs function, and remove unnecessary
+ placeholder zero args.
+ * defs.h (begin_line): Add prototype.
+ * defs.h (vprintf_filtered): Add prototype.
+ * dwarfread.c (varargs.h): Remove, no longer needed.
+ * dwarfread.c (dwarfwarn): Remove prototype and function.
+ * dwarfread.c (complaints): Define a bunch of complaints.
+ * dwarfread.c (SQUAWK): Remove macro defs, convert all
+ usages to standard complain() calls.
+ * utils.c (begin_line): New function that ensures that
+ whatever gets filter-printed next starts on its own line.
+ * utils.c (vprintf_filtered): New func, like vfprintf_filtered,
+ but to stdout (calls vfprintf_filtered internally).
+
+Tue Dec 15 02:01:00 1992 John Gilmore (gnu@cygnus.com)
+
+ * remote.c: Avoid printf_filtered line limit. Suggested by
+ Robert R. Henry, <rrh@tera.com>.
+ * infcmd.c (environment_info): Ditto, for Don Allen <allen@think.com>.
+
+ * main.c (main): Accept --silent as well as --quiet. Change +help
+ to --help. Suggested by Karl Berry, <karl@cs.umb.edu>.
+
+ * doc/gdbint.texinfo: SWAP_HOST_AND_TARGET => SWAP_TARGET_AND_HOST.
+ Noticed by Andy Jackson, <arj@cam-orl.co.uk>.
+
+Mon Dec 14 23:28:15 1992 John Gilmore (gnu@cygnus.com)
+
+ * tm-nindy960.h, remote-nindy.c: Lint.
+
+Mon Dec 14 18:48:52 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdbtypes.c (create_array_type): Complete rewrite. Now requires
+ a optional type to decorate as an array type, the type of the
+ index, and the bounds of the array. Records this additional info
+ in the array type for use with languages with nonzero array
+ bounds.
+ * gdbtypes.h (enum type_code): Update comment for TYPE_CODE_ARRAY
+ to note that arrays may have bounds.
+ * gdbtypes.h (create_array_type): Update prototype.
+ * c-exp.y (ptype production): Adjust for new create_array_type
+ calling conventions.
+ * coffread.c (decode_type): Call create_array_type rather than
+ handcrafting array types.
+ * convex-tdep.c (value_type): Remove, now use create_array_type.
+ * convex-tdep.c (value_of_trapped_internalvar): Convert calls to
+ vector_type into calls to create_array_type.
+ * dwarfread.c (decode_subscr_data): Name changed to
+ decode_subscript_data_item throughout.
+ * dwarfread.c (decode_subscript_data_item): Rewrite to use
+ create_array_type. Now records index type and range as well.
+ * dwarfread.c (dwarf_read_array_type): Rewrite as part of
+ change to use create_array_type.
+ * dwarfread.c (read_subroutine_type): Test existing user defined
+ types before decorating them, to ensure they are blank, and
+ complain about it if they are not.
+ * dwarfread.c (decode_fund_type): For unrecognized types, always
+ return some valid type (type integer). If the unrecognized type
+ cannot be an implementation defined type, complain as well.
+ * m88k-tdep.c (pushed_size): Update comment for TYPE_CODE_ARRAY.
+ * m88k-tdep.c (store_param): Update comment for TYPE_CODE_ARRAY.
+ * mipsread.c (upgrade_type): Add FIXME comment that code to
+ handcraft arrays should be replaced with call to create_array_type.
+ * stabsread.c (read_array_type): Replace code to handcraft
+ array types with call to create_array_type.
+ * valprint.c (type_print_varspec_prefix): Minor formatting
+ change, join lines that don't need to be split.
+
+Mon Dec 14 17:18:42 1992 Stu Grossman (grossman at cygnus.com)
+
+ * convex-xdep.c, hppab-nat.c, infptrace.c: Remove
+ decl for attach_flag, it now lives in inferior.h.
+ * hppa-pinsn.c: Reformat opcode tables. Add function prototypes.
+ Make most functions static.
+ * hppah-nat.c: General cleanups, remove BSD specific code (since
+ that all lives in hppab-nat.c).
+ * hppah-tdep.c (frame_chain_valid), tm-hppa.h (FRAME_CHAIN):
+ Change sense of test against inside_entry_file(). This fix is
+ from U. of Utah.
+ * tm-hppa.h (PUSH_DUMMY_FRAME, POP_FRAME): Use char * for 2nd arg
+ to read/write_register_bytes().
+ * gdbtypes.h: Remove const from decl for cplus_struct_default to
+ work around PA-GAS assembler bug. Also, add trailing */ to some
+ comments.
+ * gdbtypes.c: Remove const from decl for cplus_struct_default.
+ Same reason as above.
+
+Wed Dec 9 19:53:25 1992 John Gilmore (gnu@cygnus.com)
+
+ * mipsread.c (parse_symbol): When checking whether a structured
+ type is an enum, check qualifiers of its first member, as well as
+ the base type of the member. Bug found and fixed by John M.
+ Farrell, <farrell@fjord.reo.dec.com>.
+
+ * vx-share/{reg.h,xdr_regs.h,xdr_regs.c}: Remove, unused.
+ * remote-vx.c: Don't include vx-share/reg.h.
+ * vx-share/ptrace.h: Reproduce from scratch.
+ * config/{vxworks68,vxworks960}: Don't include xdr_regs.o.
+ * Makefile.in: Remove references to removed files, and to removed
+ 29k-share directories.
+
+Tue Dec 8 13:30:58 1992 Fred Fish (fnf@cygnus.com)
+
+ * c-lang.c (_initialize_c_language): Name changed from
+ _initialize_c_exp.
+ * m2-lang.c (_initialize_m2_language): Name changed from
+ _initialize_m2_exp.
+ * m2-lang.c (_initialize_m2_language): Change malloc to xmalloc since
+ it is no longer inside m2-exp.y, where it was remapped by Makefile.
+ * c-exp.y, m2-exp.y: Migrate code that has nothing to do with
+ expression parsing into c-lang.c and m2-lang.c respectively.
+ * c-lang.c, m2-lang.c: New files, code migrated from c-exp.y and
+ m2-exp.y respectively.
+ * c-lang.h, m2-lang.h: New files, internal interfaces between c-*
+ and m2-* files respectively.
+ * Makefile.in (SFILES_MAINDIR): Add c-lang.c, m2-lang.c.
+ * Makefile.in (HFILES): Add c-lang.h, m2-lang.h.
+ * Makefile.in (OBS): Add c-lang.o, m2-lang.o.
+ * expression.h (struct block): Forward declaration for prototypes.
+ * language.h (struct objfile): Forward declaration for prototypes.
+ * Makefile.in (SFILES_MAINDIR): Add ch-lang.c.
+ * Makefile.in (HFILES): Add ch-lang.h.
+ * Makefile.in (OBS): Add ch-lang.o.
+ * ch-exp.y: Migrate code that has nothing to do with expression
+ parsing into ch-lang.c.
+ * ch-lang.c: New file, code migrated from c-exp.y.
+ * ch-lang.h: New file, internal interface between ch-* files.
+ * ch-lang.c (_initialize_chill_language): Name changed from
+ _initialize_chill_exp.
+
+ Changes for Amiga Unix from rhealey@ub.d.umn.edu.
+ * config/amix.mh (NAT_FILE): Add, set to nm-sysv4.h.
+ * config/amix.mh (NATDEPFILES): Add.
+ * config/amix.mh (XDEPFILES): Move procfs.o and fork-child.o
+ to NATDEPFILES.
+
+ * dwarfread.c (decode_subscr_data): Remove spurious test that
+ accepted only integer subscript types. We don't do anything
+ with the type at the moment anyway.
+
+Fri Dec 4 06:56:56 1992 Fred Fish (fnf@cygnus.com)
+
+ * ch-exp.y (match_character_literal): Fix case where no
+ match at all is found.
+ * ch-exp.y (chill_create_fundamental_type): Chill uses fixed
+ width types. For example, "INT" is always 2 bytes regardless
+ of the values of any TARGET_*_BIT macros. So use explicit
+ numeric sizes for the types.
+
+Thu Dec 3 12:00:06 1992 Fred Fish (fnf@cygnus.com)
+
+ * c-exp.y (c_create_fundamental_type): New function to create
+ language specific fundamental types for C.
+ * m2-exp.y (m2_create_fundamental_type): New function to create
+ language specific fundamental types for Modula 2.
+ * c-exp.y (c_language_defn, cplus_language_defn): Add
+ c_create_fundamental_type to language struct initializers.
+ * m2-exp.y (m2_language_defn): Add m2_create_fundamental_type
+ to language struct initializers.
+ * dwarfread.c (expression.h, language.h): Include.
+ * dwarfread.c (ftypes): New array to hold fundamental types
+ for current compilation unit.
+ * dwarfread.c (cu_language_defn): New pointer to language
+ struct for language of current compilation unit.
+ * dwarfread.c (dwarf_fundamental_type): New function to
+ create/lookup fundamental types.
+ * dwarfread.c (set_cu_language): Initialize cu_language_defn.
+ * dwarfread.c (throughout): Replace lookup_fundamental_type
+ with dwarf_fundamental_type.
+ * dwarfread.c (read_file_scope): Zero out ftypes for each new
+ compilation unit (may be different language or different objfile).
+ * gdbtypes.c (lookup_fundamental_type): Move actual type
+ creations into language specific fundamental type creation
+ functions and call via create_fundamental_type. Add comment
+ about this function being obsolescent.
+ * gdbtypes.h (FT_BYTE, FT_UNSIGNED_BYTE): New types, true byte
+ sized signed and unsigned integers.
+ * gdbtypes.h (FT_NUM_MEMBERS): Increment, new types added.
+ * language.c (language_def): New function to lookup a language
+ struct given it's enumeration.
+ * language.h (struct language_defn): Add la_fund_type, a pointer
+ to a function that creates fundamental types for this language.
+ * language.h (create_fundamental_type): New macro to create
+ fundamental types based on the current language.
+ * language.h (language_def): Add prototype.
+ * language.c (unk_lang_create_fundamental_type): New function
+ for initializing language structs, calls error if called.
+ * language.c (unk_language_defn, auto_language_defn,
+ local_language_defn): Use unk_lang_create_fundamental_type.
+ ch-exp.y (chill_create_fundamental_type): New function.
+ ch-exp.y (chill_language_defn): Add chill_create_fundamental_type.
+ ch-exp.y (_initialize_chill_exp): BOOL types are only one byte.
+
+Tue Dec 1 17:07:31 1992 Fred Fish (fnf@cygnus.com)
+
+ * dwarfread.c (CHILL_PRODUCER): Add producer string for
+ GNU chill.
+ * dwarfread.c (handle_producer): Test CHILL_PRODUCER as well
+ as GCC_PRODUCER and GPLUS_PRODUCER.
+
+Mon Nov 30 18:46:58 1992 Stu Grossman (grossman at cygnus.com)
+
+ * remote-udi.c (udi_wait): Don't stop if TIP says that remote is
+ still running.
+
+Mon Nov 30 12:00:25 1992 Fred Fish (fnf@cygnus.com)
+
+ * tm-sun4sol2.h: Add CPLUS_MARKER. Solaris 2.0 requires '.'
+ rather than '$'. This particular piece of braindamage is
+ spreading like ooze. It's now infected libiberty, deja-gnu,
+ gdb, and gcc.
+ * values.c (baseclass_addr): Use CPLUS_MARKER rather than
+ hardwired '$' character.
+
+Sun Nov 29 15:22:42 1992 Fred Fish (fnf@cygnus.com)
+
+ (Changes to break incredibly ugly, unmaintainable 750 line
+ read_struct_type function up into managable pieces.)
+ * Makefile.in (VERSION): Bump to 4.7.3.
+ * stabsread.c (struct field_info): Local struct definition.
+ * stabsread.c (read_member_functions, read_struct_fields,
+ read_baseclasses, read_tilde_fields, attach_fn_fields_to_type,
+ attach_fields_to_type, read_cpp_abbrev): Prototypes and new
+ functions from fragmented read_struct_type.
+ * stabsread.c (stabs_general_complaint): Catchall complaint.
+ * stabsread.c (STABS_CONTINUE): Macro'ize cretinous stabs
+ symbol name continuation code. Use macro throughout.
+ * stabsread.c (various places): Replace add-one-to-pointer
+ with pointer increment.
+ * stabsread.c (read_type): Retain function local copy of type
+ descriptor. Rearrange code calling read_struct_type() to match
+ new conventions.
+ * stabsread.c (define_symbol): For the sake of dbx, gcc emits
+ a single blank as the name of nameless enumerations. Recognize
+ this special case and set nameless flag.
+ * ch-exp.y (GENERAL_PROCEDURE_NAME, LOCATION_NAME): New
+ terminal tokens.
+ * ch-exp.y (access_name): New non-terminal token and
+ production.
+ * ch-exp.y (general_procedure_name): Now a terminal token.
+ * ch-exp.y (location): Expand production.
+ * ch-exp.y (match_simple_name_string): New function.
+ * ch-exp.y (yylex): Call match_simple_name_string and return
+ GENERAL_PROCEDURE_NAME or LOCATION_NAME as appropriate.
+
+Wed Nov 25 07:17:13 1992 Fred Fish (fnf@cygnus.com)
+
+ * munch: Backslash escape vertical bar characters inside
+ grep patterns since they have special meaning for some greps.
+ * parse.c (write_exp_string): Complete rewrite to store string
+ contants as a leading explicit length, followed by the string data,
+ followed by a trailing explicit length.
+ * eval.c (evaluate_subexp), expprint.c (print_subexp),
+ parse.c (length_of_subexp), parse.c (prefixify_subexp):
+ Use recorded explicit length of strings in expression elements,
+ rather than strlen. Adjust code to skip over strings stored in
+ expression elements, and code to access strings, to account for
+ new leading explicit size expression element.
+ * parse.c (length_of_subexp): Test for minimum endpos of 1, not
+ 0, to avoid negative expression element indices.
+ * valops.c (search_struct_method): Minor whitespace change.
+
+Mon Nov 23 11:14:15 1992 Fred Fish (fnf@cygnus.com)
+
+ * c-exp.y (yylex): Add tempbuf, tempbufindex, and tempbufsize,
+ which together maintain a dynamically expandable static buffer
+ for the lexer to use when translating C strings to their internal
+ form (other future uses possible). Fix parsing of C style strings
+ to do the normal C style input conversions of escaped character
+ sequences.
+ * valops.c (value_string): Remove translation of escaped
+ character sequences, now done in C expression parser.
+ * language.h (PRINT_LITERAL_FORM): New macro that takes character
+ and decides if it should be printed in literal form or some other
+ form, based on it's ASCII value and setting of sevenbit_strings.
+ * {c-exp.y, m2-exp.y} (emit_char): Use new PRINT_LITERAL_FORM
+ macro, change indentation style.
+ * ch-exp.y (chill_printchar): Use new PRINT_LITERAL_FORM macro.
+ * ch-exp.y (chill_printstr): First cut at real function instead
+ of error stub.
+
+Sun Nov 22 16:21:41 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * nindy-share/stop.h: fixed bogus comment-end in copyright message
+
+ * i960-pinsn.c: fixed two calls of fputs_filtered that had 3 arguments
+
+Fri Nov 20 21:35:57 1992 Fred Fish (fnf@cygnus.com)
+
+ * defs.h (sevenbit_strings): Add declaration.
+ * defs.h (printchar): Replace with gdb_printchar.
+ * language.h (language_defn): Add new function pointers
+ la_printchar and la_printstr, to do language dependent
+ printing of characters and strings.
+ * language.h (local_printchar, local_printstr): New macros
+ to call language dependent functions pointed to by la_printchar
+ and la_printstr respectively.
+ * c-exp.y (emit_char, c_printchar, c_printstr): New language
+ dependent functions for printing characters and strings.
+ * c-exp.y (c_language_defn, cplus_language_defn): Add
+ c_printchar and c_printstr.
+ * command.c (do_setshow_command): Rename printchar use to
+ gdb_printchar.
+ * expprint.c (print_subexp): Replace C style string output
+ with call to local_printstr.
+ * language.c (unk_lang_printchar, unk_lang_printstr):
+ New stubs, currently errors.
+ * language.c (unknown_language_defn, auto_language_defn,
+ local_language_defn): Add unk_lang_printchar and
+ unk_lang_printstr.
+ * m2-exp.y (emit_char, m2_printchar, m2_printstr): New
+ language dependent functions to print characters and strings.
+ * m2-exp.y (m2_language_defn): Add m2_printchar and m2_printstr.
+ * utils.c (printchar): Renamed to gdb_printchar.
+ * valprint.c (print_string): Remove prototype, function moved
+ to c-exp.y, where it becomes c_printstr.
+ * valprint.c (print_max): Made global for reference from the
+ language dependent printing routines in *-exp.y.
+ * valprint.c (repeat_count_threshold): New variable with function
+ of old REPEAT_COUNT_THREHOLD define, but now settable by user.
+ Change all references to old macro to references to new variable.
+ * valprint.c (value_print, val_print): Replace calls to
+ print_string with calls to local_printstr.
+ * valprint.c (val_print): Replace C style character printing
+ with call to local_printchar.
+ * valprint.c (val_print): Add case for TYPE_CODE_CHAR.
+ * valprint.c (_initialize_valprint): Add add_show_from_set
+ call for setting up repeat_count_threshold as print variable.
+ * ch-exp.y (decode_integer_value): New function.
+ * ch-exp.y (decode_integer_literal): Use decode_integer_value.
+ * ch-exp.y (chill_printchar, chill_printstr): New language
+ dependent functions for printing characters and strings.
+ * ch-exp.y (chill_language_defn): Add chill_printchar and
+ chill_printstr.
+
+Thu Nov 19 21:22:21 1992 John Gilmore (gnu@cygnus.com)
+
+ * main.c (main): Print GDB version number in gdb -help; doc pid arg.
+ Suggested by Marty Leisner, <leisner@eso.mc.xerox.com>.
+ (print_gdb_version): New arg is stdout or stderr. Callers changed.
+
+Wed Nov 18 15:05:45 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * remote-vx.c (vx_kill): just warn if we can't contact the board,
+ and assume the process has been killed.
+
+Wed Nov 18 14:39:57 1992 Stu Grossman (grossman at cygnus.com)
+
+ * remote-udi.c (udi_open): Reset vars so that user can re-run
+ programs without leaving GDB.
+ * (many routines): Slightly improve error handling.
+ * (download): Zero out BSS by longs instead of bytes to avoid
+ timeouts in real hardware.
+ * 29k-share/udi/udip2soc.c (UDIDisconnect, UDIKill): Indicate
+ that connection is no longer in use after shutdown() of socket.
+ This keeps GDB from dying of a SIGPIPE when you issue multiple
+ `target udi' commands.
+
+Wed Nov 18 14:27:47 1992 Fred Fish (fnf@cygnus.com)
+
+ * language.h (language_format_info): New structure to bundle
+ local formatting information.
+ * language.h (language_defn): Replace individual format info
+ with language_format_info structs.
+ * language.h (local_*_format, local_*_format_prefix,
+ local_*_format_specifier, local_*_format_suffix): New macros
+ for binary/octal/decimal/hex formats to access info elements.
+ * c-exp.y (c_language_defn): Update for new format handling.
+ * m2-exp.y (m2_language_defn): Update for new format handling.
+ * dbxread.c (language.h): Include for partial-stab.h use.
+ * mipsread.c (expression.h, language.h): Include for
+ partial-stab.h use.
+ * defs.h (local_hex_format, local_hex_format_custom,
+ local_hex_string, local_hex_string_custom): Move to language.h.
+ * language.c (local_hex_format_custom, local_hex_string,
+ local_hex_string_custom, local_octal_format_custom): Use new
+ format handling.
+ * language.c (unknown_language_defn, auto_language_defn,
+ local_language_defn): Update for new format handling.
+ * printcmd.c (print_scalar_formatted): Use new macros
+ to access decimal and binary format info for printing.
+ * c-exp.y (chill_language_defn): Update for new format handling.
+ * ch-exp.y (CHARACTER_LITERAL): Add support to yylex.
+ * ch-exp.y (decode_integer_literal): Add function
+ * ch-exp.y (match_integer_literal): Use decode_integer_literal.
+ * ch-exp.y (builtin_type_chill_char): Add definition.
+ * gdbtypes.h (builtin_type_chill_char): Add declaration.
+
+Tue Nov 17 11:17:06 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * tm-rs6000.h (BELIEVE_PCC_PROMOTION): Define, since AIX cc gets
+ it right.
+ (aix_framedata): added nosavedpc field.
+ (SAVED_PC_AFTER_CALL): Don't try to optimize; just call
+ read_register.
+ (FRAMELESS_FUNCTION_INVOCATION): Pass second argument of 0.
+ (FRAME_SAVED_PC): If PC not saved, use SAVED_PC_AFTER_CALL.
+ * rs6000-tdep.c (skip_prologue): Handle gcc generated stfd
+ instructions as function_frame_info does. Expand special case of
+ st r31,-4(r1) to be st r31,NUM(r1), since gcc can generate offsets
+ other than -4.
+ (pop_frame): Add 4 rather than sizeof (int) to avoid host
+ dependence.
+ (function_frame_info): Set frameless if the function has no frame,
+ and set nosavedpc if the PC was not saved. Handle gcc generated
+ stfd 31,-4(31); st 31, -12(31) correctly.
+ (frameless_function_invocation): New second argument pcsaved; if 0
+ return whether the function has a frame, if 1 return whether the
+ function saved PC.
+ (frame_initial_stack_address): Correct typo: cache registers for
+ callee_fi, not for fi, (avoids reading garbage memory locations).
+
+Mon Nov 16 15:58:07 1992 Stu Grossman (grossman at cygnus.com)
+
+ * infrun.c (wait_for_inferior (just before step_over_function
+ label)): Change test for stepping into subroutine to check for the
+ presence of line number info. This makes stuff compiled with -g1
+ cause GDB to not lose control when stepping.
+
+ * symtab.c (find_pc_line): Improve code per gnu's suggestions.
+ Improve comments as well.
+
+Sun Nov 15 09:22:09 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.7.2
+ * symtab.c (find_pc_symtab): Fix return of random value
+ to caller.
+ * Makefile.in (c-exp.tab.c, m2-exp.tab.c): Add dependency on
+ Makefile since it contains sed patterns used in generation.
+ Add sed pattern to also delete #include of any malloc.h.
+ * c-exp.y, expr.c, expression.h, language.c, m2-exp.y,
+ parser-defs.h, valarith.c, valops.c, value.h: Remap macros and
+ function names to conform to K&R terminology with respect to
+ logical and bitwise operators:
+ UNOP_ZEROP => UNOP_LOGICAL_NOT
+ UNOP_LOGNOT => UNOP_COMPLEMENT
+ BINOP_LOGAND => BINOP_BITWISE_AND
+ BINOP_LOGXOR => BINOP_BITWISE_XOR
+ BINOP_LOGIOR => BINOP_BITWISE_IOR
+ BINOP_AND => BINOP_LOGICAL_AND
+ BINOP_OR => BINOP_LOGICAL_OR
+ PREC_OR => PREC_LOGICAL_OR
+ PREC_AND => PREC_LOGICAL_AND
+ PREC_LOGIOR => PREC_BITWISE_IOR
+ PREC_LOGXOR => PREC_BITWISE_XOR
+ PREC_LOGAND => PREC_BITWISE_AND
+ value_zerop() => value_logical_not()
+ value_lognot() => value_complement()
+ * c-exp.y (c_op_print_tab): Add explicit empty terminator.
+ * m2-exp.y (m2_op_print_tab): Add explicit empty terminator.
+ * i387-tdep.c (sys/dir.h): Remove, appears to be unnecessary
+ and is nonexistant in some SVR4 based systems.
+ * language.c (DEFAULT_ALLOCSIZE): Change from 3 => 4.
+ * m2-exp.y (number_sign, modblock): Make static, #ifdef out
+ unused modblock.
+ * m2-exp.y (ANDAND): Rename to LOGICAL_AND.
+ * source.c (source_info): Fix minor nits, print "1 line" rather
+ than "1 lines", and "language is <lang>".
+ * valarith.c (value_binop): Handle TYPE_CODE_BOOL as well
+ as TYPE_CODE_INT and TYPE_CODE_FLOAT.
+ * valprint.c (val_print): Print TYPE_CODE_BOOL type values as
+ "TRUE" or "FALSE".
+ * values.c (value_from_longest): Handle TYPE_CODE_BOOL.
+ * ch-exp.y: New expression parser, for GNU-Chill.
+ * defs.h (enum language): Add language_chill.
+ * dwarfread.c (set_cu_language): Add LANG_CHILL case and make
+ LANG_MODULA2 a recognized language.
+ * gdbtypes.h (enum_typecode): Note TYPE_CODE_BOOL used for
+ Chill as well as Modula-2.
+ * gdbtypes.y (builtin_type_chill_bool, builtin_type_chill_long,
+ builtin_type_chill_ulong, builtin_type_chill_real): Add.
+ * language.c (set_language_command): Add chill.
+ * language.c (binop_result_type, integral_type, character_type,
+ boolean_type, structured_type, value_true, binop_type_check):
+ Add language_chill cases.
+ * language.h (_LANG_chill): Define.
+ * symfile.c (deduce_language_from_filename): Recognize the
+ filename extensions ".chill", ".c186", and ".c286" for Chill.
+ * valprint.c (typedef_print): Add case for language_chill.
+ * Makefile.in (SFILES_MAINDIR): Add ch-exp.y.
+ * Makefile.in (YYFILES): Add ch-exp.tab.c.
+ * Makefile.in (YYOBJ): Add ch-exp.tab.o.
+ * Makefile.in (saber_gdb): Add unload of ch-exp.y and load
+ of ch-exp.tab.c.
+ * Makefile.in (distclean): Add target ch-exp.tab.c.
+ * Makefile.in (realclean): Add rm of ch-exp.tab.c.
+ * Makefile.in (ch-exp.tab.o, ch-exp.tab.c): New targets.
+ * eval.c (evaluate_subexp): Add OP_BOOL case.
+ * expprint.c (print_subexp): Add OP_BOOL case.
+
+Fri Nov 13 20:36:28 1992 John Gilmore (gnu@cygnus.com)
+
+ * infcmd.c (set_environment_command): Avoid skipping first
+ char of env value if an '=' appears in it. Bug report and fix
+ by Mark Jungerman, <maj@lucid.com>.
+
+Fri Nov 13 20:24:10 1992 Stu Grossman (grossman at cygnus.com)
+
+ * infcmd.c (step_over_calls): Improve comments.
+ * symtab.c (find_pc_psymtab): Clean up a bit.
+ * (find_pc_symtab): Fix comments, clean up code.
+ * (find_pc_line): General cleanups, efficiency improvements.
+ Also, don't return garbage when some line info exists, but there
+ was no good match.
+
+Thu Nov 5 23:04:38 1992 Rob Ryan (rr2b@andrew.cmu.edu)
+
+ * xcoffexec.c (vmap_symtab): fixed a bug where if a object has no
+ member, and the stat pointer passed to vmap_symtab was NULL, the
+ wrong vmap entries would be modified. Fixes behavior where
+ attempting to load symbols for a module with no member would mess
+ up already read in symbols.
+
+Wed Nov 11 17:09:17 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in: Remove dependancies for 29k-share/dfe/yank.o and
+ 29k-share/dfe/mini2udi.o.
+ * config/a29k-udi.mt: Remove yank.o and mini2udi.o.
+ * alldeps.mak, depend: Update to deal with removal of
+ aforementioned files.
+ * remote-udi.c: Major cleanups. Clean up udi_open and drop
+ requirement for useless 'program' argument. Clean up
+ udi_create_inferior, and udi_load to call common download()
+ routine. Create download routine to load remote hosts directly
+ (with the help of BFD) so that we don't need yank.c and
+ mini2udi.c.
+ Fix udi_detach to call UDIDisconnect with
+ the right arguments. Clean up udi_resume, don't assign tip_error
+ twice. Clean up udi_wait, straighten out status codes. Make
+ udi_kill really work.
+
+Fri Nov 6 10:26:01 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * c-exp.y: separated host/target idea of integer type size,
+ removed redundant parse rules. (YYSTYPE): added typed_val, removed
+ UINT and CHAR rules. (parse_number): work out the targetwise type
+ of a number based upon it's size and qualifiers. (yylex): chars
+ are now treated the same way as ints.
+
+ * source.c (indentify_source_line): don't core dump if wanted
+ line is larger than number of lines in source. (can happen when
+ coff gets confused about #included source).
+
+Fri Nov 6 03:00:39 1992 John Gilmore (gnu@cygnus.com)
+
+ Fix problems noticed by Allan Steel, <allan@maths.su.oz.au>,
+ when debugging a program with 100 shared libraries.
+
+ * solib.c (solib_map_sections): Always close the BFD we open.
+ Free all malloc'd storage we allocate, too, including error cases.
+ (struct so_list): Remove unused so_bfd member.
+ (clear_solib): Don't bother closing so_bfd.
+
+ * symfile.c (symfile_bfd_open): Mark newly opened BFD as
+ cacheable. `So many symbol files, so little file descriptors.'
+
+Fri Nov 6 00:14:38 1992 John Gilmore (gnu@cygnus.com)
+
+ * m68k-stub.c: Remove ansidecl.h and the few uses of it.
+ Stubs should stand alone as much as possible.
+
+ * source.c (show_directories): Avoid printf_filtered length prob
+ pointed out by Jonathan Stone.
+
+ * i960-pinsn.c (MEM_MAX, MEM_SIZ): Set upper limit properly to
+ avoid accesses beyond end of table. Fix by Lee W. Cooprider,
+ <Lee_Cooprider@vos.stratus.com>.
+
+Thu Nov 5 17:33:08 1992 Fred Fish (fnf@cygnus.com)
+
+ * {ser-bsd.c, ser-termios.c} (serial_close): Pass address of
+ struct, not struct itself.
+ * serial.h (serial_restore): Fix prototype, takes pointer not
+ struct.
+
+Thu Nov 5 17:12:42 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (depend): Add nm.h to the list of things to fixup.
+ * depend: Redo, to fixup nm.h problems with *-tab.c files.
+
+Thu Nov 5 00:19:51 1992 John Gilmore (gnu@cygnus.com)
+
+ * i386-stub.c: Remove ansidecl.h and the few uses of it.
+ Stubs should stand alone as much as possible.
+
+ * README: Add remote-es1800.c and remote-st2000.c to table.
+ * go32-nat.c: Remove, there is no native go32 support.
+ * go32-xdep.c: Remove unused fork, fvork, wait, execlp, kill_inferior.
+
+Wed Nov 4 15:27:31 1992 Stu Grossman (grossman at cygnus.com)
+
+ * inflow.c (pass_signal, set_sigint_trap, clear_sigint_trap): Add
+ new routines to deal with sending SIGINTs to attached processes
+ when the user interrupts the controlling GDB.
+ * inftarg.c (child_wait), procfs.c (procfs_wait): Add calls to
+ the aforementioned routines when waiting for the attached process.
+
+ * elfread.c, mipsread.c: Include <string.h>.
+ * i386-stub.c: Include "ansidecl.h" to deal with prototypes.
+ * serial.h: Add prototype for serial_restore().
+
+Wed Nov 4 11:13:25 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * minsyms.c (lookup_minimal_symbol_by_pc): subtract 1, not 2, from
+ minimal_symbol_count, because the NULL symbol is not included in
+ the count. This prevented this function from finding the last
+ symbol in the table.
+
+Tue Nov 3 11:29:17 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * dbxread.c (process_one_symbol): if not defined
+ (BLOCK_ADDRESS_FUNCTION_RELATIVE), set function_start_offset at
+ the start of the function, not just after N_FUN.
+
+Fri Oct 30 16:33:02 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (c-exp.tab.c, m2-exp.tab.c): Add sed patterns to
+ remap all malloc's to xmalloc's and all realloc's to xrealloc's.
+ * c-exp.y, m2-exp.y: Add comment about how malloc/realloc are
+ remapped to xmalloc/xrealloc, use only malloc/realloc in grammer
+ file. Remove preprocessor defines that previously did remapping.
+
+Fri Oct 30 00:58:18 1992 John Gilmore (gnu@cygnus.com)
+
+ * infcmd.c (run_command): Avoid long calls to printf_filtered.
+ Bug fix courtesy of Alexander Klaiber.
+
+Tue Oct 27 17:08:45 1992 K. Richard Pixley (rich@cygnus.com)
+
+ hp300 native support (hp300hpux untested).
+
+ * hp300ux-xdep.c: removed.
+ * xm-hp300bsd.h (REGISTER_U_ADDR): removed.
+ * xm-hp300hpux.h: updated copyright.
+ (ATTACH_DETACH, FETCH_INFERIOR_REGISTERS): removed.
+ * nm-hp300bsd.h, nm-hp300hpux.h, hp300ux-nat.c: new files.
+ * Makefile.in (HFILES): added nm-hp300bsd.h and nm-hp300hpux.h.
+ * config/hp300bsd.mh (XDEPFILES): removed infptrace.o inftarg.o
+ fork-child.o coredep.o corelow.o.
+ (NAT_FILE, NATDEPFILES): new macros.
+ * config/hp300bsd.mt (TDEPFILES): removed exec.o.
+ * config/hp300hpux.mh (XDEPFILES): removed infptrace.o inftarg.o
+ fork-child.o.
+ (NAT_FILE, NATDEPFILES): new macros.
+ * config/hp300hpux.mt (TDEPFILES): removed exec.o.
+
+ Vax ultrix native support.
+
+ * nm-vax.h: new file.
+ * Makefile.in (HFILES): added nm-vax.h.
+ * config/vaxult.mh (XDEPFILES): infptrace.o inftarg.o fork-child.o
+ coredep.o corelow.o removed.
+ (NAT_FILE, NATDEPFILES): new macros.
+ * xm-vax.h: updated copyright.
+ (REGISTER_U_ADDR): removed.
+
+ Apollo native support (untested).
+
+ * Makefile.in (HFILES): added nm-apollo68[bv].h.
+ * a68v-nat.c, nm-apollo68[bv].h: new files.
+ * xm-apollo68[bv].h (FETCH_INFERIOR_REGISTERS): removed.
+ * xm-apollo68b.h (PTRACE_IN_WRONG_PLACE): removed.
+ * a68v-xdep.c: removed.
+ * config/apollo68[bv].mh (XDEPFILES): removed infptrace.o
+ inftarg.o fork-child.o a68v-xdep.o.
+ (NAT_FILE, NATDEPFILES): new macros.
+
+ * defs.h: include nm.h.
+ * coredep.c, infptrace.c, procfs.c, rs6000-nat.c, sparc-nat.c,
+ sparc-tdep.c, : do not include nm.h.
+ * doc/gdbint.texinfo: nm.h now included in defs.h.
+
+Fri Oct 23 04:47:17 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (VERSION): 4.7.1 post release!
+
+ * config/hppahpux.mh (NATDEPFILES): Add hppah-nat.o.
+
+Fri Oct 23 00:48:08 1992 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (VERSION): gdb-4.7 release.
+ * README: Update for gdb-4.7.
+
+Thu Oct 22 11:24:18 1992 Stu Grossman (grossman at cygnus.com)
+
+ * sparc-tdep.c: include nm.h (for now) so that we get USE_PROC_FS
+ when necessary.
+
+ * alldeps.mak, depend: Update.
+
+Thu Oct 22 03:14:36 1992 John Gilmore (gnu@cygnus.com)
+
+ * partial-stab.h ('f', 'F'): Don't reference pst->textlow if pst
+ is null.
+ * tm-sun4sol2.h (PROLOGUE_FIRSTLINE_OVERLAP): Remove -- it
+ causes problems in setting breakpoint in the right place in
+ functions with `float' args which are passed as doubles.
+ * xm-vaxbsd.h (MEM_FNS_DECLARED): Avoid erroneous redecl's.
+ * config/rs6000.mh (NATDEPFILES): Add corelow.o.
+
+Thu Oct 22 01:01:24 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (HFILES): Add nm-i386sco.h.
+ * dwarfread.c: include <sys/types.h> for SCO.
+ * infptrace.c: Don't include ptrace.h under SCO.
+ * config/i386sco.mh: Use -D_POSIX_SOURCE instead of -posix for
+ gcc.
+ * config/i386v.mt: Add exec.o to TDEPFILES.
+
+Wed Oct 21 19:08:20 1992 Stu Grossman (grossman at cygnus.com)
+
+ * i386v-nat.c: Remove space from front of #endif.
+ * irix4-nat.c: Remove externs of registers[], include inferior.h
+ instead.
+ * mips-nat.c: Explicitly initialize zerobuf to 0!
+ * mips-tdep.c (init_extra_frame_info): Undo John's last change.
+ Always setup fci->frame, even if it's non-zero. Too many places
+ depend upon this behavior (and I have to get a release out the
+ door)!
+ * mipsread.c (parse_partial_symbols, psymtab_to_symtab_1): Set
+ processing_gcc_compilation if we find the embedded stabs marker.
+ This fixes several bugs with finding the location of short or char
+ function parameters passed on the stack.
+
+Wed Oct 21 17:46:07 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ Native support for sun4sol2.
+
+ * xm-sysv4.h (USE_PROC_FS, ATTACH_DETACH): removed to nm-sysv4.h.
+ * nm-sysv4.h: new file.
+ * Makefile.in (HFILES): added nm-sysv4.h.
+ * config/sun4sol2.mh (XDEPFILES): removed procfs.o fork-child.o.
+ (NAT_FILE, NATDEPFILES): new macros.
+ * config/sun4sol2.mt (TDEPFILES): removed exec.o and solib.o.
+
+Wed Oct 21 03:51:01 1992 John Gilmore (gnu@cygnus.com)
+
+ * coredep.c: Include "nm.h" to get REGISTER_U_ADDR.
+ * doc/gdbint.texinfo: Improve REGISTER_U_ADDR and USE_PROC_FS doc.
+
+ * Makefile.in (VERSION): Tick to 4.6.9.
+
+Tue Oct 20 23:27:56 1992 John Gilmore (gnu@cygnus.com)
+
+ * mipsread.c (UNSAFE_DATA_ADDR): Remove MIPS-host-specific
+ definition, replace with portable one.
+ * remote-nindy.c: Lint.
+ (nindy_wait): Return type is int, result is inferior_pid.
+ * symmisc.c (dump_psymtab): Only print section_offsets if set.
+ (initialize_symmisc): Remove empty function.
+ * tm-spc-noun.h, tm-sun4os4.h, tm-sun4sol2.h (STACK_END_ADDRESS):
+ Remove obsolete, misspelled macro.
+ * doc/gdbint.texinfo: Document obsolete STACK_END_ADDR.
+ (all @node commands): Use new form to avoid nitpicking errors.
+ * doc/gdbint.texinfo: Document host/native/target split.
+
+Wed Oct 21 00:14:34 1992 Stu Grossman (grossman at cygnus.com)
+
+ * mips-nat.c (zerobuf): Get rid of const to avoid gcc warnings.
+
+ * xm-mips.h (offsetof): Don't define this if __STDC__.
+
+Tue Oct 20 21:32:18 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ umax native support (untested).
+
+ * config/umax.mh (XDEPFILES): removed infptrace.o inftarg.o
+ fork-child.o.
+ (NAT_FILE, NATDEPFILES): new macros.
+ * config/umax.mt (TDEPFILES): removed exec.o.
+ * xm-umax.h (U_REGS_OFFSET, ATTACH_DETACH, REGISTER_U_ADDR):
+ removed to nm-umax.h.
+ * nm-umax.h: new file.
+ * Makefile.in (HFILES): added nm-umax.h.
+
+ hppa native support (untested).
+
+ * config/hppahpux.mh, config/hppabsd.mh (XDEPFILES): now empty.
+ (NAT_FILE, NATDEPFILES): new macros.
+ * config/hppabsd.mt (TDEPFILES): removed exec.o and hppab-core.o.
+ * config/hppahpux.mt (TDEPFILES): removed exec.o.
+ * xm-hppa[bh].h (REGISTER_U_ADDR, U_REGS_OFFSET): removed.
+ * nm-hppa[bh].h, hppa[bh]-nat.c: new files.
+ * hppa[bh]-xdep.c: removed.
+ * hppa[bh]h-tdep.c: do not include ptrace.h.
+ * Makefile.in (HFILES): added nm-hppa[bh].h.
+
+ * doc/gdbint.texinfo: add PUSH_DUMMY_FRAME, POP_FRAME.
+
+Tue Oct 20 00:01:46 1992 Stu Grossman (grossman at cygnus.com)
+
+ * mips-nat.c: Straighten out include files. Work around
+ conflicting defs of JB_xxx syms in <setjmp.h> and <machine/pcb.h>
+ for Ultrix-4.2.
+
+Mon Oct 19 15:09:57 1992 Stu Grossman (grossman at cygnus.com)
+
+ * mips-nat.c (fetch_core_registers, register_addr): Copy from
+ coredep.c, but zero out FP_REGNUM & ZERO_REGNUM so that stack
+ backtraces from core files work.
+ * config/decstation.mh, config/irix3.mh: Remove coredep.o.
+ Functions are now defined in mips-nat.c.
+
+ * tm-irix3.h: Put MIPS_EFI_SYMBOL_NAME in here too.
+
+ * remote-hms.c: Disable all uses of serial_nextbaudrate and
+ serial_default_name().
+
+ * remote-hms.c, ser-go32.c, serial.h: Change from
+ serial_timedreadchar() to new serial_readchar().
+
+ * Makefile.in (HFILES): Fixup list of nm-*.h files. Add missing ones.
+
+Mon Oct 19 12:45:23 1992 Per Bothner (bothner@cygnus.com)
+
+ * c-exp.y: Moved handling of 'const' and 'volatile' from
+ <type> to <typebase>. This removes 2 conflicts.
+
+Sun Oct 18 00:36:30 1992 Fred Fish (fnf@cygnus.com)
+
+ * breakpoint.c (breakpoint_re_set_one): Don't delete watchpoints
+ from breakpoint table when reseting breakpoints.
+
+Sat Oct 17 00:59:23 1992 Fred Fish (fnf@cygnus.com)
+
+ Native support cleanup and corefile fixes for i386 SVR4 systems.
+
+ * i386-tdep.c (supply_gregset, fill_gregset, supply_fpregset,
+ fill_fpregset): Moved to i386v4-nat.c
+ * i386v4-nat.c, nm-i386v4.h, : New files.
+ * i386sol2.mh, i386v4.mh, ncr3000.mh (NAT_FILE): Use nm-i386v4.h.
+ * i386sol2.mh, i386v4.mh, ncr3000.mh (NATDEPFILES): Add corelow.o,
+ change i386v-nat.o to i386v4-nat.o.
+
+Fri Oct 16 13:06:08 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ Miscellaneous 386 configs updated.
+
+ * config/i386aout.mt (TDEPFILES): removed exec.o.
+ * config/i386sol2.mh, config/ncr3000.mh, config/i386v4.mh
+ (XDEPFILES): removed procfs.o fork-child.o i386-xdep.o.
+ (NAT_FILE, NATDEPFILES): new macros.
+ * config/i386aout.mt, config/i386sol2.mt, config/ncr3000.mt,
+ config/i386v4.mt (TDEPFILES): removed exec.o.
+ * config/i386v32.mh (XDEPFILES): removed infptrace.o inftarg.o
+ fork-child.o coredep.o corelow.o i386-xdep.o i387-tdep.o.
+ (NAT_FILE, NATDEPFILES): new macros.
+ * config/i386sco.mh (XDEPFILES): removed infptrace.o inftarg.o
+ fork-child.o coredep.o corelow.o i386-xdep.o.
+ (NAT_FILE, NATDEPFILES): new macros.
+
+ Native support cleanup for i386bsd (untested).
+
+ * config/i386bsd.mt (NATDEPFILES): exec.o removed.
+ * config/i386bsd.mh (NATDEPFILES): added exec.o
+ * tm-i386bsd.h (FLOAT_INFO): removed.
+ * nm-i386bsd.h (FLOAT_INFO): added.
+
+ Native support for i386v (untested).
+
+ * config/i386v.mh (XDEPFILES): removed infptrace.o inftarg.o
+ fork-child.o coredep.o corelow.o i386-xdep.o i387-tdep.o.
+ (NAT_FILE, NATDEPFILES): new macros.
+ * config/i386v.mt (TDEPFILES): removed exec.o, added i387-tdep.o.
+ * i386-xdep.c: removed.
+ * Makefile.in (HFILES): added nm-i386v.h
+ * i386v-nat.c, nm-i386v.h: new file.
+ * xm-i386v.h: (REGISTER_U_ADDR, i386_register_u_addr): removed to
+ nm-i386v.h.
+ * tm-i386v.h (FLOAT_INFO): removed.
+
+ Native support for linux (untested).
+
+ * config/linux.mh (XDEPFILES): removed infptrace.o inftarg.o
+ fork-child.o coredep.o corelow.o i387-tdep.o i386-xdep.o.
+ (NAT_FILE, NATDEPFILES): new macros.
+ * config/linux.mt (TDEPFILES): removed exec.o, added i387-tdep.o.
+ * Makefile.in (HFILES): added nm-linux.h.
+ * nm-linux.h: new file.
+ * xm-linux.h: updated copyright. cleaned up formatting.
+ (ATTACH_DETACH, U_REGS_OFFSET): removed to nm-linux.h.
+
+ Native support for sun386 (untested).
+
+ * config/sun386.mh (XDEPFILES): removed infptrace.o inftarg.o
+ fork-child.o sun386-xdep.o.
+ (NAT_FILE, NATDEPFILES): new macros.
+ * config/sun386.mt (TDEPFILES): removed exec.o.
+ * Makefile.in (HFILES): added nm-sun386.h.
+ * sun386-nat.c, nm-sun386.h: new file.
+ * sun386-xdep.c: removed.
+ * xm-sun386.h: updated comment and copyright.
+ (ATTACH_DETACH, FETCH_INFERIOR_REGISTERS): removed to
+ nm-sun386.h.
+
+ Native support for i386mach (untested).
+
+ * config/i386mach.mh (XDEPFILES): removed infptrace.o inftarg.o
+ fork-child.o mach386-xdep.o.
+ (NAT_FILE, NATDEPFILES): new macros.
+ * Makefile.in (HFILES): added nm-i386mach.h.
+ * nm-i386mach.h, i386mach-nat.c: new files.
+ * mach386-xdep.c: removed.
+ * xm-i386mach.h: updated copyright.
+ (ATTACH_DETACH, FETCH_INFERIOR_REGISTERS): removed to
+ nm-i386mach.h.
+
+ Native separation for go32 (untested).
+
+ * config/go32.mh (NAT_FILE, NATDEPFILES): new macros.
+ * go32-nat.c: new file.
+ * go32-xdep.c (call_ptrace, child_resume,
+ fetch_inferior_registers, store_inferior_registers,
+ child_xfer_memory, fetch_core_registers): removed to go32-nat.c.
+
+ Native support for m88k (untested).
+
+ * Makefile.in (HFILES): added nm-m88k.h
+ * xm-delta88.h, xm-m88k.h (REGISTER_U_ADDR,
+ FETCH_INFERIOR_REGISTERS): removed.
+ * config/m88k.mh, config/delta88.mh (XDEPFILES): infptrace.o
+ inftarg.o fork-child.o m88k-xdep.o removed to NATDEPFILES.
+ (NAT_FILE, NATDEPFILES): new macros.
+ * config/m88k.mt, config/delta88.mt (TDEPFILES): removed exec.o.
+ * m88k-nat.c, nm-m88k.h, nm-delta88.h: new files.o.
+ * m88k-xdep.c: removed.
+
+Fri Oct 16 04:16:30 1992 John Gilmore (gnu@cygnus.com)
+
+ * i386b-nat.c: Comment changes.
+ * nm-i386bsd.h, xm-i386bsd.h: Split native dependent pieces out
+ into new nm-file.
+ * config/i386bsd.mh (NAT_FILE): Point to new nm-file.
+
+Fri Oct 16 03:34:01 1992 John Gilmore (gnu@cygnus.com)
+
+ Avoid longjmp()-catching compilation errors in cross-ports.
+
+ * doc/gdbint.texinfo: Update GET_LONGJMP_TARGET, L_SET doc.
+ * irix4-nat.c, mips-nat.c (JB_ELEMENT_SIZE, get_longjmp_target):
+ Move from mips-tdep.c and tm-{irix3,mips}.h.
+ * mips-nat.c: Remove a bunch of code that was ifdef'd out of
+ native MIPS ports.
+ * nm-irix3.h, nm-mips.h (GET_LONGJMP_TARGET): Move from tm-irix3.h
+ and tm-mips.h.
+
+ * ultra3-nat.c (register_addr): Move from ultra3-xdep.c.
+ (fetch_core_registers): Fix bfd_seek arguments.
+
+Fri Oct 16 03:02:28 1992 John Gilmore (gnu@cygnus.com)
+
+ Make core files work again (add back the `core' target).
+
+ * config/decstation.mh, news.mh, sun2os3.mh, sun2os4.mh
+ (NATDEPFILES): Add corelow.o.
+ * config/delta88.mt, m88k.mt (TDEPFILES): Remove coredep.o, it's
+ native dependent.
+
+ * config/3b1.mh, bigmips.mh, hp300bsd.mh, hppabsd.mh, hppahpux.mh,
+ i386sco.mh, i386v.mh, i386v32.mh, irix3.mh, isi.mh, linux.mh,
+ littlemips.mh, merlin.mh, news1000.mh, pn.mh, rtbsd.mh, tahoe.mh,
+ vaxbsd.mh, vaxult.mh (XDEPFILES): Add corelow.o whenever coredep.o
+ appears. FIXME, these should be moved to NATDEPFILES for native
+ use only.
+
+Thu Oct 15 21:53:53 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ Ultra3 host/target/native split. (untested).
+
+ * ultra3-xdep.c: updated copyright. Do not include sys/ptrace.h.
+ (fetch_register, fetch_inferior_registers,
+ store_inferior_registers, fetch_core_registers): removed to
+ ultra3-nat.c.
+ * xm-ultra3.h (FETCH_INFERIOR_REGISTERS, U_REGS_OFFSET): removed
+ to nm-ultra3.h.
+ * Makefile.in (HFILES): added nm-ultra3.h.
+ * nm-ultra3.h, ultra3-nat.c: new files for native support.
+ * config/ultra3.mh (XDEPFILES): removed infptrace.o inftarg.o
+ fork-child.o.
+ (NAT_FILE, NATDEPFILES): new macros for native support.
+ * config/ultra3.mt (TDEPFILES): exec.o removed.
+
+ * xm-vaxult.h: add MEM_FNS_DECLARED.
+
+Thu Oct 15 02:59:30 1992 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (VERSION): Roll to 4.6.8.
+ (OBS): Put version.o first, so Makefile rebuild happens early.
+
+ * command.h: Publicize prototype for not_just_help_class_command.
+ * command.c: Remove proto.
+ * maint.c: Mark "mt" as an abbrev, to avoid duplicated help
+ output. Move "maint info" from class info to class maintenance,
+ and improve text.
+ * infrun.c: Move "stop" to class_obscure, and give it a
+ function so it will not be seen as a global help topic. FIXME,
+ it should be possible to set these attributes independently.
+
+ * core.c (core_command): Make nicer error message for no core support.
+
+ Lint around file_ptr's (bfd's off_t's) and bfd_seek.
+
+ * dbxread.c (read_dbx_symtab): Use L_SET as bfd_seek arg.
+ (elfstab_build_psymtabs): staboffset and stabstroffset args are
+ file_ptr's.
+ * dwarfread.c (struct dwfinfo): Convert dbfoff, lnfoff to file_ptr.
+ (scan_compilation_units): Punt unused filename arg. dbfoff,
+ lnoffset, and curlnoffset are file_ptr's now.
+ (dwarf_build_psymtabs): Drop desc and filename args; use
+ objfile. dbfoff and lnoffset are file_ptr's now.
+ (read_ofile_symtab): foffset is now file_ptr. Use L_SET in bfd_seek.
+ * elfread.c (struct elfinfo): dboffset and lnoffset are file_ptr's.
+ (elf_symfile_read): Skip desc and filename args to
+ dwarf_build_psymtabs. Pass file_ptr's to elfstab_build_psymtabs.
+ * gdb-stabs.h: Use file_ptr rather than off_t.
+ * mipsread.c (fixup_symtab): f_ptr is a file_ptr. Re-enable
+ compile-time debug check that someone turned off as "unused".
+ (read_the_mips_symtab): st_filptr is a file_ptr. Fix bfd_seek call.
+ * symfile.h: Update dwarf_build_psymtabs and
+ elfstab_build_psymtabs prototypes.
+ * xcoffread.c (init_stringtab, init_lineno, xcoff_symfile_read):
+ Use file_ptr offsets. bfd_seeks use L_SET.
+
+Thu Oct 15 01:27:32 1992 Stu Grossman (grossman at cygnus.com)
+
+ * mips-tdep.c, mipsread.c, tm-mips.h: Get rid of ".gdbinfo."
+ symbol. #define MIPS_EFI_SYMBOL_NAME instead. Use different
+ value so that demangler won't be invoked. This greatly speeds up
+ stepping.
+ * mips-tdep.c (mips_pop_frame): Rewrite handling of
+ linked_proc_info so that it properly deallocates the appropriate
+ item after it is done with it instead of before.
+ * Don't pass bogus frame pointer to create_new_frame(). Just
+ leave it as zero so that lower level code will figure out the
+ correct value.
+
+Wed Oct 14 18:56:28 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ Sony News native support.
+
+ * Makefile.in (HFILES): added nm-news.h.
+ * nm-news.h: new file.
+ * config/news.mh (XDEPFILES): removed infptrace.o inftarg.o
+ fork-child.o coredep.o to NATDEPFILES.
+ (NAT_FILE, NATDEPFILES): new macros for native support.
+ * config/news.mt (TDEPFILES): removed exec.o.
+
+ * remote-vx.c: remove redundant include of sys/time.h.
+
+ * infrun.c: include ctype.h. Otherwise some machines result in
+ undefined for isdigit.
+
+Tue Oct 13 01:27:14 1992 John Gilmore (gnu@cygnus.com)
+
+ * configure.in: Convert m68k entries to m68* entries to handle
+ all the various m68xxx hosts and targets.
+ * config/news1000.mt: No longer needed, same as news.mt.
+
+Fri Oct 9 18:54:37 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config/sun3os[34].mh (NATDEPFILES): remove duplicate inftarg.o.
+
+Fri Oct 9 14:20:08 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (HFILES): Add all nm-irix3.h, nm-irix4.h,
+ nm-sun2.h, nm-mips.h.
+
+ * config/irix3.mh (NATDEPFILES): nat-mips.o => mips-nat.o.
+
+ * Makefile.in (alldeps.mak): Add = sign after NATDEPFILES.
+
+ * config/bigmips.mh config/littlemips.mh: Remove mips-xdep.o.
+
+Fri Oct 9 08:41:11 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * xm-hppah.h: if __STDC__ is not defined, define
+ HPPA_COMPILER_BUG.
+ symtab.c (decode_line_1): avoid a bug in the HP9000/700 native
+ compiler; see the comment in the file.
+
+Fri Oct 9 04:43:43 1992 John Gilmore (gnu@cygnus.com)
+
+ First cut at support for all BSD variants on 386.
+
+ * tm-i386bsd.h, xm-i386bsd.h: New config files.
+ * i386b-nat.c: New native support file.
+ * configure.in: Add host and target for i[34]86-*-bsd*.
+ * config/i386bsd.mh, config/i386bsd.mt: New config files.
+
+Fri Oct 9 00:31:33 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ Sun2 native support (untested).
+
+ * xm-sun2.h (ATTACH_DETACH, FETCH_INFERIOR_REGISTERS,
+ REGISTER_U_ADDR): removed to nm-sun2.h.
+ * nm-sun2.h: new file.
+ * config/sun2os[34].mh (XDEPFILES): infptrace.o inftarg.o
+ fork-child.o sun3-xdep.o removed.
+ (NAT_FILE, NATDEPFILES): new macros.
+
+ Mips native support. Decstation and iris4 have been tested.
+ Iris3 has not.
+
+ * mips-tdep.c (supply_gregset, fill_gregset, supply_fpregset,
+ fill_fpregset): removed to irix4-nat.c
+ * mips-xdep.c: removed.
+ * irix4-nat.c, mips-nat.c, nm-irix3.h, nm-irix4.h, nm-mips.h: new
+ files.
+ * procfs.c: include nm.h.
+ * xm-irix3.h (U_REGS_OFFSET, FETCH_INFERIOR_REGISTERS): removed.
+ * xm-irix4.h: bump copyright.
+ (U_REGS_OFFSET, FETCH_INFERIOR_REGISTERS, USE_PROC_FS,
+ PROC_NAME_FMT): removed.
+ * xm-mips.h (FETCH_INFERIOR_REGISTERS): removed.
+ * config/irix4.mh (XDEPFILES): removed procfs.o fork-child.o.
+ (NAT_FILE, NATDEPFILES): new macros for native support.
+ (CC): supply default compiler switches.
+ * config/irix3.mh (XDEPFILES): removed infptrace.o inftarg.o
+ fork-child.o coredep.o.
+ (NAT_FILE, NATDEPFILES): new macros for native support. Note that
+ irix3 is untested.
+ * config/decstation.mh (XDEPFILES): removed infptrace.o inftarg.o
+ fork-child.o mips-xdep.o coredep.o.
+ (NAT_FILE, NATDEPFILES): new macros for native support.
+
+Thu Oct 8 23:50:51 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config/rs6000.mh (XDEPFILES): removed fork-child.o.
+ (NATDEPFILES): added fork-child.o
+ * config/sun3os3.mh (XDEPFILES): removed fork-child.o.
+ (NATDEPFILES): added fork-child.o
+ * config/sun3os4.mh (XDEPFILES): removed fork-child.o.
+ (NATDEPFILES): added fork-child.o
+
+Thu Oct 8 23:19:25 1992 John Gilmore (gnu@cygnus.com)
+
+ * infcmd.c (path_info): Avoid 250-char limit on printf_filtered,
+ by using puts_filtered instead.
+
+Fri Oct 9 00:28:25 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * remote-nindy.c (nindy_load): Replacement version from Steve
+ Chamberlain, doesn't require forking to run "strip" or "sx".
+
+Thu Oct 8 18:27:35 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (HFILES): Add nm-*.h files.
+
+Thu Oct 8 16:27:45 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config/sun4os4.mh (XDEPFILES): fork-child.o removed.
+ (NATDEPFILES): added fork-child.o.
+
+ * doc/gdbint.texinfo: document a few more macros, create new
+ section for native macros.
+
+Thu Oct 8 13:52:46 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in alldeps.mak depend: Rip out 29k/udi pending
+ resolution of copyright issues.
+
+Wed Oct 7 20:08:53 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (setup-to-dist): Remove -norecursion so that doc
+ subdir gets configured.
+
+Wed Oct 7 12:24:01 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * Makefile.in (nindy.o): Define "STRIP" as pathname of strip
+ program.
+ * nindy-share/nindy.c (coffstrip): Use that pathname, instead of
+ searching for a "bfd_strip" program. Also, fixed up arguments
+ passed to that program.
+
+ * tm-nindy960.h (ADDITIONAL_OPTIONS): Use "-ser" rather than "-r",
+ which is now used for something else. Rewrite description of
+ associated parameters to match how gdb does it now.
+ (ADDITIONAL_OPTION_HELP): Fix message accordingly.
+
+ * m68k-pinsn.c (print_insn_arg): Handle new "`" operand type.
+
+Tue Oct 6 14:47:11 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ NOTICE_SIGNAL_HANDLING_CHANGE macro added to the target vector as
+ to_notice_signals.
+
+ * inferior.h (proc_signal_handling_change): prototype removed.
+ * infrun.c (NOTICE_SIGNAL_HANDLING_CHANGE): default removed.
+ (handle_command): now calls target_notice_signals.
+ * procfs.c (proc_signal_handling_change): renamed to
+ procfs_notice_signals. Now static. Add prototype. All callers
+ changed.
+ * target.h (struct target_ops): new field, to_notice_signals.
+ (target_notice_signals): new macro to cover new field.
+ * target.c (cleanup_target): default to_notice_signals to ignore.
+ * corelow.c (core_ops),
+ exec.c (exec_ops),
+ inftarg.c (child_ops),
+ procfs.c (procfs_ops),
+ remote-adapt.c (adapt-ops),
+ remote-eb.c (eb_ops),
+ remote-es1800.c (es1800_ops, es1800_child_ops),
+ remote-hms.c (hms_ops),
+ remote-mm.c (mm_ops),
+ remote-nindy.c (nindy_ops),
+ remote-st2000.c (st2000_ops),
+ remote-udi.c (udi_ops),
+ remote-vx.c (vx_ops, vx_run_ops),
+ remote.c (remote_ops),
+ target.c (dummy_target),
+ xcoffexec.c (exec_ops): added static initializer for
+ to_notice_signals.
+ * xm-irix4.h, xm-sysv4.h (NOTICE_SIGNAL_HANDLING_CHANGE): removed.
+
+Tue Oct 6 12:13:08 1992 John Gilmore (gnu@cygnus.com)
+
+ * main.c (define_command): Add forgotten initializer.
+
+Tue Oct 6 02:23:17 1992 John Gilmore (gnu@cygnus.com)
+
+ * language.c, language.h: Move saved_language out to global
+ expected_language. Set expected_language when user expectation
+ changes.
+ * language.c (language_info): Don't print type/range checking gub.
+ * main.c (main): Set expected language.
+ (execute_command): Check against expected language.
+ * symfile.c (set_initial_language): Set expected language.
+
+ * configure.in, config/i386sol2.{mh,mt}: Preliminary Solaris-x86 conf.
+
+Fri Sep 4 00:34:30 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ A bunch of changes mostly to improve debugging of C++ programs.
+ Specifically, the calling of inferiors methods is improved.
+
+ * value.h: New macros METHOD_PTR_IS_VIRTUAL,
+ METHOD_PTR_FROM_VOFFSET, METHOD_PTR_TO_VOFFSET to partially
+ hide the implementation details of pointer-to-method objects.
+ How to tell if the pointer points to a virtual method is
+ still very dependent on the particular compiler, but this
+ should make it easier to find the places to change.
+ * eval.c (evaluate_subexp [case OP_FUNCALL]), valprint.c
+ (val_print [case TYPE_CODE_PTR]): Use the new METHOD_PTR_*
+ macros, instead of a hard-wired-in code that incorrectly
+ assumed a no-longerused representation of pointer-to-method
+ values. And otherwise fix the relevant bit-rotted code.
+
+ * valprint.c (type_print_base [case TYPE_CODE_STRUCT]):
+ If there are both fields and methods, put a space between.
+
+ * stabsread.c (read_struct_type): Fix bug in handling of
+ GNU C++ anonymous type (indicated by CPLUS_MARKER followed
+ by '_'). (It used to prematurely exit the loop reading in
+ the fields, so it would think it should start reading
+ methods while still in the fields. This could crash gdb
+ given a gcc that can emit nested type information.)
+
+ * valops.c (search_struct_method): Pass 'this' value by
+ reference instead of by value. This provides a more
+ consistent interface through a recursive search where the
+ "bottom" functions may need to adjust offsets (due to multiple
+ inheritance).
+ * valops.c, value.h, values.c: Pass extra parameters to
+ value_fn_field and value_virtual_fn_field so we can
+ correctly adjust offset for multiple inheritance.
+ * eval.c (evaluate_subexp [case OP_FUNCALL]): Simplify
+ virtual function calls by using value_virtual_fn_field().
+ * values.c: New function baseclass_offset, derived from
+ baseclass_addr (which perhaps can be made obsolete?).
+ It returns an offset rather than an address. This is a
+ cleaner interface since it doesn't mess around allocating
+ new values.
+ * valops.c (search_struct_method): Use baseclass_offset
+ rather than baseclass_addr.
+
+Mon Oct 5 16:02:04 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in: Re-install 29K/UDI stuff.
+ * remote-udi.c (udi_resume): Clean up.
+ * (udi_wait): Rewrite, leave out bugs.
+ * Add debugging code to print out all register fetches and stores.
+ * Straighten out target_ops.
+ * tm-29k.h (DUMMY_FRAME_RSIZE): Pad out to doubleword.
+
+Mon Oct 5 09:46:44 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * remote-udi.c (udi_create_inferior): run with no arguments should
+ not pass the program name as an argument, since the UDI code
+ already handles that.
+ (udi_load): get the symbols from prog_name, not arg_string (the
+ load command should really use arg_string as the program name, not
+ prog_name, but at least the run command works now).
+
+ * munch: HP9000/300 nm puts an extra space between T and symbol
+ name.
+
+ * config/irix4.mh: added -lsun to XM_CLIBS to get RPC functions
+ needed for vxworks targets.
+
+Fri Oct 2 22:04:42 1992 John Gilmore (gnu@cygnus.com)
+
+ * am29k-tdep.c (_initialize_29k): Make it possible for the
+ user to set and query the address where function calls into the
+ inferior write a small scratch routine. `set call_scratch_address'
+ * inferior.h (PC_IN_CALL_DUMMY): Fix fencepost error.
+ * remote.c (remote_prepare_to_store): Only fetch regs if they are
+ not already cached validly.
+
+Thu Oct 1 14:36:42 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ Rs6000 native support.
+
+ * infptrace.c: remove #ifdef USG from around include ptrace.h.
+ machines without this header should not be compiling this file.
+ * nm-rs6000.h, rs6000-nat.c: new files for native support.
+ * rs6000-tdep.c: do not include sys/ptrace.h or sys/reg.h.
+ * rs6000-xdep.c: removed. all code now in rs6000-nat.c.
+ * xm-rs6000.h: do not include ptrace.h.
+ (ATTACH_DETACH, FETCH_INFERIOR_REGISTERS): moved to nm-rs6000.h.
+ * config/rs6000.mh (XDEPFILES): removed rs6000-xdep.o.
+ infptrace.o and inftarg.o move to NATDEPFIES.
+ (NAT_FILE, NATDEPFILES): new macro for native support.
+
+ Sun3 native support.
+
+ * config/sun3os3.mh, config/sun3os4.mh (NAT_FILE, NATDEPFILES):
+ new macros for native support.
+ (XDEPFILES): moved infptrace.o and inftarg.o to NATDEPFILES,
+ removed sun3-xdep.o.
+ * xm-sun3.h (ATTACH_DETACH, FETCH_INFERIOR_REGISTERS): moved to
+ nm-sun3.h.
+ * sun3-xdep.c: removed. All code is now in sun3-nat.c.
+ * sun3-nat.c, nm-sun3.h: new files for native support.
+
+Thu Oct 1 10:30:54 1992 Fred Fish (fnf@cygnus.com)
+
+ * dwarfread.c (dbsize): New variable to hold size of dwarf info.
+ * dwarfread.c (dwarf_build_psymtabs): Rename dbsize parameter to
+ dbfsize and use it to initialize new local file scope dbsize.
+ * dwarfread.c (read_ofile_symtab): Initialize dbsize and use it.
+ * dwarfread.c (basicdieinfo): Use dbsize to check for oversize
+ DIEs as well as the current check for undersize DIEs. This helps
+ to gracefully detect and reject corrupted DIE information.
+
+Thu Oct 1 01:57:56 1992 John Gilmore (gnu@cygnus.com)
+
+ Add `command hooks' and a hook for inferior program stopping.
+
+ * command.h (struct cmd_list_element): Remove unused `aux'
+ field. Add new `hook', `hookee', and `cmd_pointer' fields.
+ * command.c (add_cmd): Initialize new fields, elim old.
+ (add_alias_cmd): Clone new fields.
+ (delete_cmd): Un-hook hookee if we're deleting hook.
+ (help_cmd): Tell user the command is hooked, if it is.
+ (lookup_cmd_1): Abbreviations return the original command
+ instead of themselves, so that hooks on the original cmd will be
+ run.
+ * defs.h (enum command_class): Add class_pseudo and comments.
+ * gdbcmd.h (execute_user_command): Add prototype.
+ * infrun.c (normal_stop): If the stop command is hooked,
+ run the hook whenever we stop.
+ (hook_stop_stub): Stub for catch_errors.
+ (_initialize_infrun): Set up pseudo "stop" command.
+ * main.c (execute_user_command): Code extracted from execute_command.
+ (execute_command): If hooked, run the hook before the command.
+ (define_command): If defining a new hook, check the command it
+ is hooking, and warn if none. Install the hook.
+ * source.c (_initialize_source): "l" is an abbrev for "list".
+ * doc/gdb.texinfo: Document command hooks.
+
+ * Makefile.in (VERSION): Roll to 4.6.7.
+ * config/sun4os4.mh: Remove dup inftarg.o from NATDEPFILES.
+ * infrun.c (breakpoints_inserted): Make it static again.
+ * tm-symmetry.h (FLOAT_INFO): #if 0 it for cross-ptrace abuse.
+
+Wed Sep 30 15:33:22 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ Native file renaming.
+
+ * nat-sparc.c -> sparc-nat.c
+ * nat-sun4os4.h -> nm-sun4os4.h
+ * nat-trash.h -> nm-trash.h
+ * config/sun4os4.mh: track file renaming.
+ * configure.in: link to nm.h rather than nat.h.
+ * infptrace.c: include nm.h rather than nat.h.
+
+Tue Sep 29 14:35:00 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ Host/target/native split for sun4.
+
+ * Makefile.in (TSOBS): removed corelow.o.
+ * infptrace.c: included nat.h.
+ * nat-trash.h: temporary header file. This should be removed once
+ all hosts have the native/host/target split.
+ * configure.in: add a symlink from nat-trash.h to nat.h if no
+ other nat file exists for this configuration.
+ * sparc-tdep.c: no longer include sys/ptrace.h.
+ * sparc-xdep.c: removed. contents have been moved to nat-sparc.c.
+ * xm-sparc.h (ATTACH_DETACH, FETCH_INFERIOR_REGISTERS): moved to
+ nat-sun4os4.h.
+ * nat-sparc.c, nat-sun4os4.h: new files for sun4 native support.
+ * config/sun4os4.mh (XDEPFILES): moved infptrace.o and inftarg.o
+ to NATDEPFILES. removed sparc-xdep.o.
+ (NATDEPFILES, NAT_FILE): new macros for native support.
+
+ Break the direct connection from core_file_command to any
+ particular type of core file support.
+
+ * target.h (find_core_target): new prototype.
+ * target.c (find_core_target): new function. Walks the target
+ list looking for the core target.
+ * core.c (core_file_command): replace calls to core_detach and
+ core_open with find_core_target and direct calls.
+
+Tue Sep 29 10:19:00 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * xm-hp300hpux.h: define MEM_FNS_DECLARED; include <sys/ptrace.h>
+ for infptrace.c.
+ config/hp300hpux.mh: ALLOCA1 was not defined.
+
+Mon Sep 28 22:03:41 1992 Stu Grossman (grossman at cygnus.com)
+
+ * breakpoint.c, exec.c, language.c, main.c, printcmd.c, symfile.c,
+ target.c, valprint.c: Use unfiltered forms of f/printf, et. al.
+ until we can figure out a better way to do paging.
+
+Sat Sep 26 02:07:31 1992 John Gilmore (gnu@cygnus.com)
+
+ * findvar.c (supply_register): Add CLEAN_UP_REGISTER_VALUE hook.
+ * tm-hppa.h (CLEAN_UP_REGISTER_VALUE): Use it.
+ * hppa-coredep.c: Remove, now that we use the hook.
+ * config/hppab.mh, config/hppah.mh: Use standard coredep.o.
+ * hppab-xdep.c, hppah-xdep.c: Remove custom code, use hook.
+
+ * dbxread.c, partial-stab.h: Replace all #ifdef hp9000s800's with
+ GDB_TARGET_IS_HPPA's. This is a SERIOUS KLUDGE. The code needs to all
+ be ripped out and reimplemented right (see elfread.c).
+ * tm-hppa.h (GDB_TARGET_IS_HPPA): Define.
+
+ Rename all HPPA files to fit into unique DOS filenames:
+ * *hppabsd* => *hppab*
+ * *hppahpux* => *hppah*
+
+Sat Sep 26 00:25:15 1992 John Gilmore (gnu@cygnus.com)
+
+ Make the /proc support a target-struct in its own right.
+
+ * Makefile.in: Remove inftarg.[co], since it is now included via
+ config/*.mh files.
+ * config/*.mh: Add inftarg.o and fork-child.o to all *.mh that
+ reference infptrace.o. Add fork-child.o to all *.mh that
+ reference procfs.o.
+
+ * inferior.h (proc_wait, inferior_proc_init, proc_set_exec_trap):
+ No longer global functions.
+ (fork_inferior): New global function from fork-child.c.
+ * inftarg.c (child_wait): Remove USE_PROC_FS conditional.
+ (ptrace_me, ptrace_him): New stub functions for fork_inferior().
+ (child_create_inferior): Moved to fork-child.c as fork_inferior.
+ (child_create_inferior): New tiny function that calls fork_inferior.
+ * fork-child.c: New file, containing fork_inferior, which is
+ built from slight mods to inftarg.c's child_create_inferior.
+
+ * procfs.c (procfs_ops): Add target vector.
+ (attach): Rename as static do_attach.
+ (procfs_create_inferior): New tiny function that calls fork_inferior.
+ (child_xfer_memory): Rename to static procfs_xfer_memory.
+ (store_inferior_registers): Rename to static procfs_store_registers.
+ (inferior_proc_init): Rename to static procfs_init_inferior.
+ (procfs_attach, procfs_detach, procfs_prepare_to_store,
+ procfs_files_info, procfs_open, procfs_mourn_inferior,
+ procfs_can_run): Slightly mangled copies of the corresponding
+ child_XXX routines from inftarg.c.
+ (proc_wait): Renamed to static procfs_wait.
+ (child_resume): Rename to static procfs_resume.
+ (fetch_inferior_registers): Rename to static procfs_fetch_registers.
+ (initialize_proc_fs): Rename to initialize_procfs. Set up
+ procfs_ops, too.
+
+ * putenv.c: index -> strchr.
+ * regex.c: Always rename bcopy to memcpy, etc.
+ FIXME: Eventually do the renames rather than use #define's.
+ * sparc-tdep.c (deferred_stores): Moved from sparc-xdep.c.
+ Fix bcopy->memcpy.
+ * sparc-xdep.c: Move deferred_stores to target dependent.
+ * xm-irix4.h, xm-sysv4.h (CREATE_INFERIOR_HOOK): No longer needed.
+
+Fri Sep 25 21:59:27 1992 John Gilmore (gnu@cygnus.com)
+
+ Split non-target-dependent code out of target_attach routines.
+
+ * target.h: Comments on target_attach args and results.
+ * infcmd.c (attach_command): Check for existing execution, call
+ target_attach, set up terminal status and wait_for_inferior, wait
+ for the attach status, and do normal_stop.
+ * inftarg.c (child_attach): Remove target independent stuff.
+ * remote-adapt.c (adapt_attach): Ditto.
+ * remote-mm.c (mm_attach): Ditto.
+ * remote-udi.c (udi_attach): Ditto.
+ * remote-vx.c (vx_attach): Ditto.
+
+ Cleanup.
+
+ * remote-hms.c (hms_attach): Remove completely, it was useless.
+ * remote-mm.c, remote-hms.c, remote-udi.c, remote-adapt.c: Remove
+ commented-out start_remote calls.
+ * remote-hms.c, remote-adapt.c, remote-mm.c, remote-udi.c: Remove
+ DENTER and DEXIT macros and their calls. Use a real debugger --
+ like gdb -- to see what functions are being called when.
+ * utils.c (strcmp_iw): Make nonstatic, for lint.
+
+Fri Sep 25 18:48:20 1992 John Gilmore (gnu@cygnus.com)
+
+ * infrun.c, inftarg.c, inferior.h: Comment and lint cleanups.
+
+Fri Sep 25 15:13:44 1992 Stu Grossman (grossman at cygnus.com)
+
+ * tm-sparc.h, dbxread.c (read_ofile_symtab): Install Jim Wilson's
+ fix to differentiate between gcc1 & gcc2 compiled files so that we
+ can debug calls that pass structs as args correctly.
+ * symmisc.c (dump_symtab): If block was compiled with gcc, say
+ so, and what version.
+
+ * remote.c (remote_wait): Make regs be char to avoid picayune
+ ANSI compiler warnings.
+
+ * energize.h: Move all external struct decls to inside of
+ __STDC__, add prototype for energize_shell_wait().
+ * energize.c (getpty): Clean up, make us really get a controlling
+ terminal.
+ * (energize_initialize): Disable SIGIO prior to setting up for
+ I/O interrupts. Move setsid(), et. al. to getpty().
+ * (energize_shell_wait): New routine to wait for things started
+ via the shell command, uses wait() instead of /dev/proc.
+ * Also, add prototype for execute_command_1().
+
+Fri Sep 25 12:09:33 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * inftarg.c (child_create_inferior, child_attach,
+ child_mourn_inferior): collect unix child process stratum
+ functions which live below the target vector into this file to
+ facilitate host/target/native split. Also, make them static.
+ * inflow.c (child_mourn_inferior): removed.
+ * infrun.c (child_create_inferior, child_attach): removed.
+ (resume): becomes global so that functions below the
+ target vector can find it.
+ * inferior.h (resume): add prototype.
+ (child_mourn_inferior, child_create_inferior, child_attach):
+ remove prototypes.
+
+ * xcoffexec.c (exec_ops): child_attach and child_create_inferior
+ replaced with find_default_attach and
+ find_default_create_inferior.
+
+Fri Sep 25 10:21:04 1992 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * i960-pinsn.c: Use _filtered routines for printing, so symbolic
+ addresses don't get displayed in the wrong positions.
+
+Fri Sep 25 09:52:47 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ Separate core functions along target vector in preparation for
+ native support. Functions above vector now live in core.c. Those
+ below in corelow.c.
+
+ * core.c (solib_add_stub, core_close, core_open, core_detach,
+ get_core_registers, core_files_info, core_ops): moved to corelow.c
+ (_initialize_core): removed addition of core_ops target.
+ * corelow.c: new file.
+ (solib_add_stub, core_close, core_open, core_detach,
+ get_core_registers, core_files_info, core_ops): moved from core.c
+ (_initialize_corelow): new function.
+ * gdbcore.h (core_open, core_detach): added prototypes.
+ (core_ops): add forward declaration.
+ * Makefile.in (SFILES_MAINDIR): add core.c
+ (OBS): add core.o
+ (TSOBS): change core.o to corelow.o
+
+Wed Sep 23 11:14:53 1992 Stu Grossman (grossman at cygnus.com)
+
+ * m68k-tdep.c (m68k_saved_pc_after_call): Use 'GDB_TARGET_IS_SUN3'
+ instead of 'sun' predefined symbol so that trap analysis code is
+ enabled only when the TARGET is a sun3.
+
+Tue Sep 22 17:13:19 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * tm-i960.h (ext_format_i960): Add top-level declaration.
+ (REGISTER_CONVERT_TO_{VIRTUAL,RAW}): Don't declare it in nested
+ blocks, else Sun4 compiler complains.
+
+Tue Sep 22 00:43:51 1992 John Gilmore (gnu@cygnus.com)
+
+ * mips-pinsn.c (print_insn_arg, case 'B'): Disassemble `break'
+ instruction's argument. Patch from jonathan@cs.stanford.edu
+ (Jonathan Stone).
+
+Mon Sep 21 18:16:30 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ Break the thread of control that implies that a unix child
+ process will be the default target.
+
+ * target.c (find_default_run_target, find_default_attach,
+ find_default_create_inferior, return_zero): new functions.
+ (cleanup_target): Make return_zero the default for to_can_run.
+
+ * exec.c (exec_ops), core.c (core_ops): Replace child_attach and
+ child_create_inferior references with find_default_XXX instead.
+
+ * target.h (struct target_ops): new field, to_can_run.
+ (find_default_attach, find_default_create_inferior): new prototypes.
+ (target_can_run): new macro.
+
+ * Also added a zero (default) to_can_run element to all static
+ struct target_ops initializations throughout GDB, except:
+ * inftarg.c (child_ops): Use new child_can_run() to enable child runs.
+
+ * infrun.c (child_create_inferior): Clean up error handling when
+ no exec file is specified.
+ (child_attach): Don't require exec file.
+
+Mon Sep 21 19:43:13 1992 John Gilmore and K. Richard Pixley (gnu@cygnus.com)
+
+ Remove kill_inferior_fast, in favor of target_kill, which goes
+ through the target vector.
+
+ * inferior.h (kill_inferior_fast): remove declaration.
+
+ * main.c (disconnect): call quit_cover using catch_errors rather
+ than calling kill_inferior_fast directly. New way goes through
+ the target vector, handles attached processes, and writes
+ command history if appropriate.
+ (quit_cover): new function, wrapper for quit_command.
+
+ * convex-xdep.c, go32-xdep.c, hppabsd-xdep.c, hppahpux-xdep.c,
+ infptrace.c, procfs.c: Removed all instances of kill_inferior_fast,
+ inlining them into the local kill_inferior when needed.
+
+Mon Sep 21 19:23:05 1992 John Gilmore (gnu@cygnus.com)
+
+ * infrun.c (_initialize_infrun): Alias `i handle' == `i signals'.
+ * stabsread.c (read_struct_type): Simplify complicated expression
+ for dumb DECstation compiler.
+
+Mon Sep 21 14:54:35 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * m68k-pinsn (print_insn_arg, fetch_arg): added support for
+ operands to memory management instructions, from WRS.
+
+Sep 20 08:42:12 1992 Fred Fish (fnf@cygnus.com)
+
+ * main.c (main): Back out previous language setting changes.
+ Replace with simple default to C before processing any init
+ files. There MUST be a language set, even in the absence of
+ init files or executables, or expression parsing fails.
+
+Sat Sep 19 09:52:26 1992 Fred Fish (fnf@cygnus.com)
+
+ * main.c (main): Move code that sets initial language to
+ symfile.c. Fixup places where command files are processed to
+ be consistent in setting a default language if none has been
+ previously set.
+ * symfile.c (set_initial_language): Add code moved from
+ main() that sets an initial default language when a new
+ symbol file is read.
+ * symfile.c (symbol_file_command): Call set_initial_language.
+ * symtab.c (find_main_psymtab): Add FIXME comment.
+
+Wed Sep 16 22:31:55 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * breakpoint.c, sparc-tdep.c: comment changes.
+ * configure.in: removed target_dependent line.
+
+ * remote-mm.c (mm_attach): change printf to error to prevent
+ fallthrough bug.
+ * remote-udi.c (udi_attach): change printf to error to prevent
+ fallthrough bug.
+
+ * rs6000-tdep.c (push_dummy_frame, pop_dummy_frame): replace
+ calls to {fetch|store}_inferior_registers with calls to
+ target_{fetch|store}_registers, for remote-target independence.
+
+Sat Sep 19 04:23:54 1992 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in: Fix bug I introduced in merging Rich's change.
+ * infrun.c (child_create_inferior): Use proceed() rather than
+ doing all the same stuff by hand.
+
+Thu Sep 17 17:35:37 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * Makefile.in, configure.in: add support for files used only when
+ configured native, that is, when host = target.
+
+Wed Sep 16 23:03:23 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * tm-sparc.h, xm-sparc.h: externs and macros relating to deferred
+ stores are target dependent and were moved from xm to tm.
+
+Sat Sep 19 03:14:37 1992 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (gdb-all.texi): Build in objdir, not $srcdir.
+
+ * config/decstation.mh: Add MMALLOC_LIB and MMALLOC_DISABLE
+ overrides, to avoid problem in xdr_bytes with malloc(0) => 0.
+
+Wed Sep 16 20:04:54 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * target.h (struct target_ops): removed to_convert_to_virtual and
+ to_convert_from_virtual elements. Initializations removed from
+ all static initializations.
+ (target_convert_to_virtual, target_convert_from_virtual):
+ removed.
+ (host_convert_to_virtual, host_convert_from_virtual): Removed
+ forward declarations.
+ * target.c (cleanup_target): removed default assignments for
+ to_convert_to_virtual and to_convert_from_virtual.
+ * inftarg.c (host_convert_to_virtual, host_convert_from_virtual):
+ removed.
+ * findvar.c (value_of_register, value_from_register):
+ target_convert_to_virtual inlined.
+ * infcmd.c (do_registers_info): target_convert_to_virtual inlined.
+ * valops.c (value_assign): target_convert_from_virtual inlined.
+
+Fri Sep 18 02:07:39 1992 John Gilmore (gnu@cygnus.com)
+
+ * main.c (gdb_readline): Avoid printf_filtered, which sets char
+ position wrong if used for the prompt.
+ * utils.c (puts_filtered): Comment: NOT a puts() replacement!
+
+ Support for accessing arbitrary MIPS stack frames in memory.
+
+ * blockframe.c (get_prev_frame_info): If INIT_FRAME_PC_FIRST is
+ set, run it before INIT_EXTRA_FRAME_INFO.
+ * stack.c (frame_info): If PRINT_EXTRA_FRAME_INFO defined, call it.
+
+ * mips-tdep.c (init_extra_frame_info): Only clobber the `frame'
+ (FP) value in the frame_info struct if it is zero (as from top of
+ execution stack).
+ (setup_arbitrary_frame): Implement FRAME_SPECIFICATION_DYADIC.
+
+ * mips-xdep.c (fetch_inferior_registers): ZERO_REGNUM always
+ comes back as zero. So does FP_REGNUM, as a trigger for
+ init_extra_frame_info.
+
+ * tm-mips.h (INIT_FRAME_PC_FIRST): Kludge, FIXME, defined to get
+ the program counter set before INIT_EXTRA_FRAME_INFO is run.
+ (INIT_FRAME_PC): Defined to null.
+ (PRINT_EXTRA_FRAME_INFO): print frame pointer location via symtab.
+ (FRAME_SPECIFICATION_DYADIC): Ask for two args in frame command.
+ Briefly explain MIPS stacks in GDB.
+
+Thu Sep 17 03:49:59 1992 John Gilmore (gnu@cygnus.com)
+
+ * copying.awk, copying.c (show_copying_command,
+ show_warranty_command): Rename from copying_info, warranty_info,
+ to match command function conventions.
+
+ * utils.c (prompt_for_continue): Reinitialize more-counts
+ before printing anything, and again afterward. Fix comments.
+ (vfprintf_filtered): Eliminate static buffer; use auto buffer,
+ or alloca() if needed.
+
+ * rs6000-xdep.c: Use correct conditional (IBM6000_TARGET) to
+ detect native versus cross-host.
+
+Wed Sep 16 21:57:14 1992 Stu Grossman (grossman at cygnus.com)
+
+ * m68k-tdep.c (sun3_saved_pc_after_call): Only do trap check for
+ Suns. Rename to m68k_saved_pc_after_call.
+ * tm-68k-noun.h, tm-sun3.h (SAVED_PC_AFTER_CALL): Use
+ m68k_saved... instead of sun3_saved...
+
+Wed Sep 16 17:00:07 1992 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (update-depend, update-alldeps): Split out of
+ setup-to-dist, for convenience in rebuilding the depend and
+ alldeps.mak files.
+ (assorted): Update to catch straggler files when building gdb.tar.Z.
+
+Tue Sep 15 01:18:50 1992 John Gilmore (gnu@cygnus.com)
+
+ Preliminary cleanup for splitting host/native/target.
+
+ * infptrace.c (child_resume): Don't deal with NO_SINGLE_STEP
+ here; it is dealt with at a gdb-target-independent level.
+ * rs6000-tdep.c (single_step): Don't call ptrace, we are a
+ high toned routine. Fix return type to void.
+ * tm-rs6000.h (AIX_BUGGY_PTRACE_CALL): Zap, we think we fixed it.
+ Rich and I believe the "real problem" was that both single_step
+ and target_resume were issuing PT_CONTINUE calls. This would
+ cause the second PT_CONTINUE to sometimes fail because the process
+ was already running.
+ * infptrace.c (child_resume): Remove AIX_BUGGY_PTRACE_CALL kludge.
+
+Mon Sep 14 19:20:43 1992 Stu Grossman (grossman at cygnus.com)
+
+ * energize.c (pty_to_kernel): Must check for EAGAIN as
+ termination condition.
+ (full_filename): Don't prepend dirname if filename begins with /.
+ (breakpoint_notify, kernel_dispatch): Deal with DynamicLoad
+ messages properly!!
+ (getpty (NCR)): Lotsa bug fixes...
+ (kernel_dispatch (case StopRType)): Use kill() instead of
+ killpg() so we can deal with losing systems...
+ (wait_for_events): Work around NCR select() lossage. It doesn't
+ zero out readfds when select() returns zero.
+ (energize_initialize): Use I_SETSIG to get SIGIO interrupts. Use
+ getcwd() instead of getwd() (NCR getwd() seg faults).
+ (energize_wait): Use sigaction() for NCR. Their version of signal()
+ is unreliable by default.
+
+ * procfs.c (proc_wait): Call print_sys_errmsg() if we get an
+ error from PIOCSWSTOP.
+
+ * breakpoint.c, core.c, exec.c, language.c, main.c, printcmd.c,
+ symfile.c, target.c, valprint.c: Use _filtered form of *printf.
+ defs.h, utils.c: Make vfprintf_filtered global.
+
+ * energize.c (send_location): New routine to consolidate all
+ places where we must notify kernel of where the given pc is.
+ (cplus_demangle): Put single-quotes around demangled names.
+ (energize_call_command): Call send_location() after doing up,
+ down, and frame commands.
+
+Fri Sep 11 18:28:28 1992 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * doc/gdb.texinfo, doc/gdbinv-m.m4.in, doc/gdbinv-s.m4.in: first
+ pass at doc for two new remote targets---29K using UDI, and Tandem
+ ST2000 using STDBUG.
+
+ * doc/all.m4, doc/none.m4: new m4 switch, _ST2000__
+
+ * doc/all.m4: turn on H8/300 stuff for generic manual
+
+ * doc/gdbinv-s.m4.in: remove text on special procedures to continue
+ after explicit call to breakpoint() in serial stubs.
+
+Fri Sep 11 01:34:25 1992 John Gilmore (gnu@sphagnum.cygnus.com)
+
+ * mipsread.c: Clean up some white space.
+ (parse_symbol): Handle stEnd of stFile.
+ (parse_partial_symbols): Remove old #if 0'd code. Handle stLocal.
+
+ * mips-xdep.c (REGISTER_PTRACE_ADDR, fetch_inferior_registers,
+ store_inferior_registers): Replace unexplained numbers
+ with manifest constants from a DECstation header file.
+ * xm-mips.h (KERNEL_U_ADDR): Get from <machine/param.h>.
+ (REGISTER_U_ADDR): Fix up for Ultrix 4.2.
+
+ * tm-tahoe.h, xm-tahoe.h (KERNEL_U_ADDR): Move macro to xm-tahoe.h.
+
+ * stack.c (_initialize_stack): "dow" should be a valid abbreviation
+ for "down". Suggested by Richard Stallman.
+
+Thu Sep 10 15:26:07 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * remote-vx.c: Rename realloc for inclusion of rpc/rpc.h, to avoid
+ redeclaration bug on SunOS 4.
+
+Wed Sep 9 17:36:53 1992 John Gilmore (gnu@cygnus.com)
+
+ * i386-stub.c, sparc-stub.c (getpacket): Actually check checksums.
+ * m68k-stub.c: Remove a few extraneous ANSI-isms.
+ * remote-nindy.c (nindy_prepare_to_store): Only fetch regs if
+ they aren't already there.
+ * remote-vx.c (vx_prepare_to_store): Ditto.
+ * xcoffread.c: Surround forward struct defns with #ifdef __STDC__.
+
+Wed Sep 9 16:50:22 1992 John Gilmore (gnu@cygnus.com)
+
+ Removed a large number of changes inserted by Per Bothner
+ for C++ support. These will go back in when they've been
+ examined.
+
+Tue Sep 8 21:05:18 1992 Stu Grossman (grossman at cygnus.com)
+
+ * serial.h: Fix prototye for serial_raw().
+ * ser-bsd.c, ser-termios.c: Fix args for serial_open() &
+ serial_write() to match prototypes.
+ * remote-st2000.c (get_reg_name): Make *p be const.
+
+Tue Sep 8 17:24:52 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * remote-nindy.c (nindy_fetch_registers): Make return type void,
+ to agree with target structure field type.
+ (nindy_store_registers): Ditto.
+
+ * Makefile (OPCODES): New var, pointing to opcodes library.
+ (CLIBS, CDEPS): Include it.
+ (saber_gdb): Load opcodes library.
+
+Tue Sep 8 15:22:06 1992 Stu Grossman (grossman at cygnus.com)
+
+ * a68v-xdep.c (store_inferior_registers): declare as void.
+ * infptrace.c: HP/Apollos have ptrace.h in the wrong place.
+ * remote-st2000.c: Massive changes to use new serial package.
+ Also added 'connect' command to transparantly connect to serial
+ port.
+ * ser-termios.c: Big cleanup, use nicer coding conventions.
+ * ser-bsd.c: New module, serial stuff for BSD systems.
+ * serial.h: Define struct ttystate properly using HAVE_TERMIO.
+ * xm-apollo68b.h: #define PTRACE_IN_WRONG_PLACE...
+
+Fri Sep 4 18:53:57 1992 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * doc/gdb.texinfo: fix shameful error of agreement reported by
+ jimb@occs.cs.oberlin.edu (Jim Blandy)
+ * doc/gdb.texinfo: remove old partial discussion of remote serial
+ protocol (via serial debug stubs)
+ * doc/gdbinv-m.m4.in, doc/gdbinv-s.m4.in: new section discussing
+ use of serial debug stubs
+
+Fri Sep 4 00:34:30 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * symfile.h: Declaration of set_demangling_style() moved
+ here from demangle.h (which is now in ../include).
+ * i386-xdep.c: Update comment.
+
+Thu Sep 3 13:44:46 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * symtab.c (completion_list_add_symbol): restructured to optimize
+ for time. First clip names that cannot match. Then clip any
+ names we've already considered. Drop a redundant strncpy. Drop
+ a redundant malloc and associated free for demangled names.
+
+Thu Sep 3 09:17:05 1992 Stu Grossman (grossman at cygnus.com)
+
+ * a68v-xdep.c (store_inferior_registers): Define as type void.
+ * configure.in: Add host m68k-apollo*-bsd*.
+ * demangle.c (struct demanglers): Use enum instead of constant
+ value to keep braindamaged HP/Apollo compiler happy.
+
+Wed Sep 2 20:45:31 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * utils.c (strcmp_iw): Add a hack to allow "FOO(ARGS)" to
+ match "FOO". This allows 'break Foo' to work when Foo is
+ a mangled C++ function. (See comment before function.)
+
+Wed Sep 2 13:45:27 1992 John Gilmore (gnu@cygnus.com)
+
+ * config/rs6000.mh (MH_CFLAGS): Circumvent IBM <rpc/rpc.h> bug,
+ for files in vx-share/*.c.
+ * xm-rs6000.h (fd_set): Circumvent the rs6000.mh circumvention,
+ for normal GDB source files.
+
+ * Makefile.in (VERSION): Roll to 4.6.6.
+
+ * tm-vx68.h, tm-es1800.h: Use tm-68k.h rather than tm-sun3.h.
+ * tm-sun3.h: Remove STACK_END_ADDR, no longer used.
+ * tm-sun3os4.h: Update comments.
+ * xm-delta88.h: Remove STACK_END_ADDR.
+
+Wed Sep 2 01:18:31 1992 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (VERSION): Roll to 4.6.5.
+
+ * infrun.c: Lint for recent `handle' changes.
+
+ * ser-termios.c, ser-go32.c: Remove DEFUN crap, clean up.
+ * serial.h (EXFUN): Remove all uses, convert to PARAMS.
+ * config/sun4os4.mh: Include ser-termios.o. FIXME, all .mh files
+ should include a ser-XXX.o module.
+
+ * dbxread.c (elfstab_build_psymtabs): Remove DEFUN crap.
+ * defs.h, i960-pinsn.c, remote-hms.c: Replace CONST with simple const.
+
+ * configure.in: Map unrecognized sun 68k's, sun sparcs, into
+ known suns in configure.in, rather than mapping them to unique
+ config files that happen to duplicate other config files.
+ * config/sun3.{mh,mt}: Remove (use identical sun3os4.*).
+ * config/sun4.{mh,mt}: Remove (use identical sun4os4.*).
+
+Wed Sep 2 00:10:43 1992 John Gilmore (gnu@cygnus.com)
+
+ * configure.in (*-*-sunos*): Use trailing * to match all
+ sub-variants of SunOS, e.g. sunos4* to match sunos4.1.1.
+ (sparc-*-sunos3): Remove host & target. Sunos3 never shipped
+ in production on Sun-4.
+ ({a29k,i[34]86,i960}-*-elf): Add targets, equivalent to coff.
+ (m68k-*-{aout,coff,elf}): Add targets, w/new config and tm files.
+ (sparc-*-{aout,coff,elf}): Add targets, w/new config and tm files.
+
+ * config/m68k-un.mt, config/m68k-noun.mt, config/sparc-un.mt,
+ config/sparc-noun.mt: New target configs for embedded.
+ * config/sun4os3.{mh,mt}: Remove, never existed in production.
+
+ * tm-68k-un.h, tm-68k-noun.h, tm-spc-un.h, tm-spc-noun.h: New
+ target definitions for embedded with and without underlines on
+ identifiers.
+
+ * tm-sparc.h, tm-sun2.h, tm-sun3.h: Delete NAMES_HAVE_UNDERSCORE:
+ not a parameter of the CPU, but of the development environment.
+ * tm-es1800.h, tm-sunos.h, tm-vx68.h: Add NAMES_HAVE_UNDERSCORE.
+
+Tue Sep 1 17:31:45 1992 John Gilmore (gnu@cygnus.com)
+
+ * breakpoint.c (breakpoint_re_set): Avoid setting source symtab
+ (which involves reading in main's symtab) if we have no breakpoints.
+
+Mon Aug 31 13:47:45 1992 Fred Fish (fnf@cygnus.com)
+
+ * dwarfread.c (cu_language): New local variable to record
+ language for current compilation unit being processed.
+ * dwarfread.c (set_cu_language): New local function to decode
+ and record language for current compilation unit being processed.
+ * dwarfread.c (synthesize_typedef): Add local function to
+ synthesize a typedef for C++ classes, structs, unions, and
+ enumerations.
+ * dwarfread.c (read_structure_scope): Synthesize typedefs
+ for C++ classes, structs and unions.
+ * dwarfread.c (read_enumeration): Synthesize typedefs for
+ C++ enumerations.
+ * dwarfread.c (read_file_scope): Call set_cu_language to
+ record language for current compilation unit. After symtab
+ is built, save this recorded language.
+ * dwarfread.c (process_dies, add_partial_symbol, struct_type,
+ scan_partial_symbols, new_symbol): Recognize TAG_class_type.
+ * dwarfread.c (add_partial_symbol): Synthesize partial symbol
+ typedefs for C++ classes, structs, unions, and enumerations.
+ * dwarfread.c (scan_compilation_units): Call set_cu_language
+ to record language for current compilation unit.
+ * dwarfread.c (scan_partial_symbols): Call add_enum_psymbol here
+ for TAG_enumeration_types, rather than in add_partial_symbol.
+ * dwarfread.c (add_partial_symbol): Combine TAG_enumeration_type
+ case with class, struct, and union type cases, now that they are
+ the same. Remove tests for non-NULL name attributes, now done
+ by callers.
+ * gdbtypes.h (TYPE_CODE_CLASS): Add type for C++ classes, but
+ treat as alias for TYPE_CODE_STRUCT for now.
+
+Sun Aug 30 21:32:17 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: map "gdb" through program_transform_name when
+ installing.
+
+Sun Aug 30 21:18:51 1992 Fred Fish (fnf@cygnus.com)
+
+ * {i386-tdep.c, m68k-tdep.c, mips-tdep.c, sparc-tdep.c}
+ (supply_gregset, fill_gregset, supply_fpregset, fill_fpregset):
+ Use "regi" for local indexing through register numbers, reserving
+ "regno" for the name of a specific register passed as an input
+ parameter. Fix bug propagated through all versions that sometimes
+ used regno as an index when it should have been regi, thus using
+ -1 as an index in some cases.
+
+Sun Aug 30 18:15:17 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * cplus-dem.c, demangle.h: Moved to ../libiberty and ../include,
+ respectively, so same demangler can be used by other programs.
+ * Makefile.in: Remove demangler stuff.
+ * Makefile.in (depend): Pass -I../readline (needed for main.c).
+ * demangle.c (_initialize_demangler): Tell demangler which
+ CPLUS_MARKER to assume.
+
+Fri Aug 28 13:13:33 1992 John Gilmore (gnu@cygnus.com)
+
+ RS/6000 portability changes (for hosting cross-debuggers).
+
+ * breakpoint.c (fixup_breakpoints): Re-kludge to IBM6000_TARGET.
+ * buildsym.c, rs6000-xdep.c, rs6000-tdep.c, tm-rs6000.h,
+ xcoffexec.c, xcoffread.c: Rename aixcoff to xcoff everywhere.
+ * printcmd.c (print_frame_args): Remove an RS/6000 dependency.
+ * stabsread.c (define_symbol): Remove RS/6000 dependencies.
+ * tm-rs6000.h (ATTACH_DETACH): Remove: host-dependent.
+ (PTRACE_ATTACH, PTRACE_DETACH): Remove: host-dep.
+ (NO_SINGLE_STEP): Add, target-dependent.
+ (loadinfotextindex): Lowercase, remove "aix_".
+ * xm-rs6000.h: Add <sys/ptrace.h> for infptrace.c.
+ (NO_SINGLE_STEP): Remove, target-dependent.
+ * xcoffexec.c (vmap_symtab): Cleanup #if 0'd code.
+ * xcoffread.c: Only build file if RS/6000 native GDB.
+ (build_function_symbol): Remove #if 0'd code.
+ * rs6000-tdep.c: Cleanup. Add static fn protos.
+ Use CORE_ADDR for addresses throughout. Make void fns void.
+ (pop_dummy_frame): Add FIXME about bogosity of design here.
+ (rs6000_struct_return_address): Ditto.
+ (frameless_function_invocation, frame_get_cache_fsr,
+ frame_initial_stack_address, xcoff_relocate_symtab,
+ xcoff_init_loadinfo, free_loadinfo, xcoff_add_toc_to_loadinfo,
+ add_text_to_loadinfo, find_toc_address): Move from xdep file.
+ Use CORE_ADDRs. Change identifiers to lowercase.
+
+ * rs6000-xdep.c: Make whole file conditional on native RS/6000,
+ supplying dummy routines if non-native. Add prototype for
+ static exec_one_dummy_insn. Move a mess of functions to
+ rs6000-tdep.c (as above). Remove #if 0'd code.
+
+ * config/rs6000.mh (XDEPFILES): Move xcoffexec.o to target side.
+ (XM_CLIBS): Add -lm to circumvent AIX 3.2 libc ldexp bug.
+ * config/rs6000.mt (TDEPFILES): Adopt xcoffexec.o.
+
+ * gdbtypes.h (TYPE_ALLOC): Parenthesize result to avoid problems
+ for callers.
+
+ * vx-share/README, nindy-share/README: New files describing
+ how these directories' code is shared, and with whom.
+
+Thu Aug 27 20:04:56 1992 John Gilmore (gnu@cygnus.com)
+
+ * configure.in (target configurations): Reformat into table.
+ Remove unsupp. Amigados host and target. Ditto Mach 386 target.
+
+ * tm-altosgas.h, tm-i386v-g.h: Remove ancient coff encap configs.
+ * config/{altosgas.mt, i386v-g.mt, i386v32-g.mt}: Ditto.
+ * config/{i386sco.mt,i386v32.mt}: Remove; identical to i386v.mt.
+ * config/{go32.mt,i960.mt}: Remove; they only printed error msgs.
+ * config/nindy960.mt: Remove useless MT_CFLAGS setting.
+ * config/i386aout.mt: Use tm-i386v.h, not tm-i386v-g.h.
+
+ * Makefile.in (config-check): Add command to check whether
+ configure.in is consistent with config/*.
+
+Wed Aug 26 21:10:52 1992 John Gilmore (gnu@cygnus.com)
+
+ * configure.in (host configurations): Reformat nested cases into
+ easy-to-maintain table.
+ (m68k-altos-*, i386v*): We don't care whether coff encap is used.
+ config/{altosgas.mh, i386v-g.mh, i386v32-g.mh}: Remove.
+
+Wed Aug 26 16:02:01 1992 Fred Fish (fnf@cygnus.com)
+
+ * cplus-dem.c: Reorder args to most local functions to make them
+ follow the consistent pattern of struct work_stuff pointer first,
+ followed by pointer into string being demangled, followed by
+ pointer to the string where the result is being stored, followed
+ by other args. Also generally replace most variables of name
+ "type" with "mangled" for consistency. They all pointed to the
+ same string but half were one name and half the other.
+ * cplus-dem.c (LONGERNAMES): Remove #ifndef's.
+ * cplus-dem.c (demangle_qualified): Rewrite to clean up and allow
+ use whenever a qualified name is being demangled.
+ * cplus-dem.c (do_type): Qualified names are treated similarly
+ to fundamental types, not as modifiers of fundamental types.
+
+Mon Aug 24 20:44:38 1992 Stu Grossman (grossman at cygnus.com)
+
+ * configure.in: Add sparclite as a target.
+
+ * sparc-stub.c (handle_exception): Flush instruction cache just
+ before returning to the user. (hexToInt): Fix overzealous cleanup.
+
+Mon Aug 24 11:57:13 1992 Fred Fish (fnf@cygnus.com)
+
+ * infrun.c (handle_command): Rewrite to allow multiple signal
+ numbers, signal number ranges, and to recognize "all" to mean all
+ signals except those used by the debugger.
+ * infrun.c (SET_SIGS, UNSET_SIGS): Macros used in handle_command
+ to set or reset actions for specific signals.
+
+Sun Aug 23 17:10:07 1992 Fred Fish (fnf@cygnus.com)
+
+ * coffread.c (decode_type): Call alloc_type to alloc new
+ types.
+ * stabsread.c (read_array_type, read_range_type, define_symbol):
+ Call alloc_type to alloc new types.
+ * stabsread.c (define_symbol): Move dbl_valu symbol field data
+ from type_obstack to symbol_obstack.
+ * stabsread.c (define_symbol): Move typedef_sym from type_obstack
+ to symbol_obstack.
+ * gdbtypes.h (TYPE_ALLOC): New macro to allocate space for data
+ associated with a type, using the same mechanism as was used to
+ allocate space for the type structure itself.
+ * coffread.c (patch_type, coff_read_struct_type,
+ coff_read_enum_type): Use TYPE_ALLOC.
+ * dwarfread.c (struct_type): Use TYPE_ALLOC.
+ * gdbtypes.c (create_array_type, check_stub_method,
+ allocate_cplus_struct_type): Use TYPE_ALLOC.
+ * mipsread.c (parse_symbol, parse_type): Use TYPE_ALLOC.
+ * stabsread.c (read_struct_type, read_array_type, read_enum_type,
+ read_range_type): Use TYPE_ALLOC.
+
+Sun Aug 23 11:04:08 1992 Fred Fish (fnf@cygnus.com)
+
+ * breakpoint.c (breakpoint_re_set): Select a default source
+ symtab if one is not currently selected.
+ * utils.c (query): Call wrap_here before building the output
+ query string, to turn off wrapping and flush any buffered output.
+ Otherwise our query may end up in the wrap buffer and never be
+ seen by the user.
+ * eval.c (evaluate_subexp): Report error when attempting to
+ evaluate subscript for types without a target type, rather
+ than dumping core by using the NULL pointer.
+ * symfile.c (symbol_file_command): Forget current_source_symtab
+ and current_source_line when discarding symbol table.
+
+Sat Aug 22 22:33:20 1992 John Gilmore (gnu@cygnus.com)
+
+ Bug fixes from Andrew Heybey <ath@lcs.mit.edu>.
+
+ * tm-mips.h (REGISTER_VIRTUAL_TYPE): Float regs are float type.
+ * mips-tdep.c (mips_print_register): Alloc enough space for two regs.
+
+Fri Aug 21 15:17:03 1992 Stu Grossman (grossman at cygnus.com)
+
+ * remote.c (remote_open): Fix baud rate setting to make -b flag
+ work. (remote_wait): Change 'T' message parser to deal with new
+ improved format which allows stub to send an arbitrary bunch of
+ registers.
+ * sparc-stub.c: General cleanups. (trap_low, handle_exception):
+ make all this re-entrant by storing all state on the stack. Clean
+ up memory error trapping. (computeSignal, set_debug_traps):
+ make it all table driven. Make a start at a baud rate setting command.
+
+Wed Aug 19 10:23:27 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * m68k-pinsn.c: handle new operand type 'r', introduced for cas2.
+
+ * remote-vx.c: redefine malloc to avoid buggy declaration on
+ RS/6000 <rpc/types.h>.
+ xm-rs6000.h: include <sys/select.h> to define fd_set for
+ <rpc/svc.h> on RS/6000.
+
+Tue Aug 18 14:48:24 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: added FLAGS_TO_PASS variable, and passed it to
+ recursive invocations of make. Always create installation
+ directories.
+
+Mon Aug 17 18:29:58 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * m68k-pinsn.c: Minor fix in style of output (don't use
+ range to indicate floating point control registers).
+
+Sat Aug 15 02:58:03 1992 John Gilmore (gnu@cygnus.com)
+
+ * m68k-pinsn.c: Surround extended support with #ifdef HAVE_68881.
+
+ * infcmd.c (registers_info): Handle multiple register names.
+ Changes inspired by Roland McGrath.
+
+Sat Aug 15 02:28:52 1992 Stu Grossman (grossman at cygnus.com)
+
+ * sparc-stub.c: New file. Mix it with your SPARClite
+ application, and it will speak GDB remote protocol!
+ * remote.c (remote_wait): Change 'T' (expedited reply) message to
+ deal with arbitrary registers. Needed for sparc-stub.
+
+Fri Aug 14 12:11:25 1992 Fred Fish (fnf@cygnus.com)
+
+ * cplus-dem.c (cplus_markers): Add table for gnu style and
+ use throughout, in place of compile time constant CPLUS_MARKER.
+ * cplus-dem.c (ARM_VTABLE_STRING, ARM_VTABLE_STRLEN): Add.
+ * cplus-dem.c (cfront_special): New function, as suggested
+ by pfieland@stratus.com.
+ * cplus-dem.c (forget_types): New function.
+ * cplus-dem.c (cplus_demangle): Call gnu_special, moved from
+ demangle_prefix().
+ * cplus-dem.c (mop_up): Call forget_types().
+ * cplus-dem.c (AUTO_DEMANGLING, GNU_DEMANGLING, LUCID_DEMANGLING):
+ Use throughout, instead of checking current_demangling_style.
+ * cplus-dem.c (demangle_signature): When finding an explicit
+ start of function args, forget all remembered types for
+ lucid/cfront style demangling.
+ * cplus-dem.c (demangle_prefix): In a sequence of two or more
+ underbar characters, use last pair as the delimiter. Hoist
+ gnu_special() call up to cplus_demangle(). Call cfront_special()
+ when appropriate.
+ * cplus-dem.c (cplus_special): Fix virtual table name demangling
+ for inherited classes.
+ * cplus-dem.c (demangle_args): Document quirks of numbered
+ references to previously seen types.
+ * dbxread.c (read_ofile_symtab, process_one_symbol):
+ Use AUTO_DEMANGLING rather than explicitly checking
+ current_demangling_style.
+ * demangle.h: Add some comments.
+ * demangle.h (AUTO_DEMANGLING, GNU_DEMANGLING, LUCID_DEMANGLING,
+ CFRONT_DEMANGLING): New macros.
+ * dwarfread.c (LCC_PRODUCER): Remove trailing space, which is
+ not found in the actual producer string produced by lcc.
+ * dwarfread.c (handle_producer): Use AUTO_DEMANGLING rather
+ than explicitly checking current_demangling_style.
+
+Thu Aug 13 11:54:46 1992 John Gilmore (gnu at cygnus.com)
+
+ * breakpoint.c (enable_longjmp_breakpoint,
+ disable_longjmp_breakpoint, set_longjmp_resume_breakpoint):
+ Check for duplicate breakpoints at the same address. Bug report
+ and preliminary fix from Dave Morrison, <drmorris@us.oracle.com>.
+
+Wed Aug 12 11:14:58 1992 Fred Fish (fnf@cygnus.com)
+
+ * buildsym.c (end_symtab): Document that end_symtab can return
+ NULL under non-error conditions.
+ * dwarfread.c (read_file_scope): Guard against dereferencing NULL
+ returned from end_symtab for empty compilation units.
+
+Tue Aug 11 02:49:39 1992 John Gilmore (gnu at cygnus.com)
+
+ * am29k-tdep.c: Lint from DECstation compiler.
+ * mem-break.c: Restore test of BREAKPOINT size that Fred removed.
+ As the man page says, "Sometimes you just can't get lint to shut
+ up". That doesn't mean you should blow away the code it won't
+ shut up about.
+ * mips-xdep.c: Revise stubbing-out of code until Rich cleans
+ it up over the next few weeks. Make mips x 29k build.
+ * tm-29k.h (CALL_DUMMY): Make it work on cross-endian hosts.
+ (FIX_CALL_DUMMY): Comment in the patching of the breakpoint,
+ but leave it as a comment because the breakpoint instruction
+ is not easily accessible at this moment (it's static, and if
+ we define one here, it goes into every file compiled).
+
+Mon Aug 10 22:27:19 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.6.3.
+ * dwarfread.c (scan_partial_symbols): Skip over DIE's within
+ function scopes when building partial symbol tables.
+ * objfiles.c (open_existing_mapped_file): Make it clear in
+ warning message that out of date mapped files are ignored.
+ * symtab.c (lookup_symtab_1, lookup_symbol): Print compilation
+ unit source file name in error message.
+
+Sat Aug 8 23:12:22 1992 Fred Fish (fnf@cygnus.com)
+
+ * dwarfread.c (struct dieinfo): Add has_at_byte_size.
+ * dwarfread.c (struct_type): In absence of AT_byte_size for
+ bitfield, use size of object of member's type for the size of
+ the anonymous object containing the bit field.
+ * dwarfread.c (completedieinfo): Set has_at_byte_size when
+ an AT_byte_size attribute is seen.
+ * mipsread.c (psymtab_to_symtab_1): Fix misspelled cast to
+ union aux_ext (was aux_ent).
+ * i386-pinsn.c (print_insn): Cast 2'nd arg to read_memory from
+ unsigned char* to char*, for Lucid compiler.
+ * i386-tdep.c (codestream_fill): Fix cast of 2'nd arg to read_memory
+ to be correct type (from unsigned char* to char*).
+ * valprint.c (type_print_derivation_info): Minor tweak to placement
+ of commas in derived class printing.
+ * xcoffread.c (builtin_type): Fix misspelling in fatal message.
+
+Fri Aug 7 11:18:23 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * xm-go32.h: Define LSEEK_NOT_LINEAR
+ * source.c (find_source_lines): if LSEEK_NOT_LINEAR is defined
+ then work out the lseek positions of newlines by running through
+ the file and `tell'ing. This makes source file listing work on
+ OS's where the relationship between physical position in file and
+ canonical position is indeterminate, eg VMS and DOS.
+
+Thu Aug 6 10:56:01 1992 Fred Fish (fnf@cygnus.com)
+
+ * stabsread.c: Ensure that all members of all allocated structures
+ are initialized to known state to avoid hard to find bugs with gdb
+ using fields containing random data.
+ * buildsym.c (start_subfile): Compact dirname initialization.
+ * buildsym.c (patch_subfile_names): New function.
+ * buildsym.c (end_symtab): Make copy of dirname on symbol obstack.
+ * buildsym.c (end_symtab): Free all malloc'd subfile fields.
+ * buildsym.h (patch_subfile_names): Add prototype.
+ * dbxread.c (process_one_symbol): Call patch_subfile_names.
+
+Wed Aug 5 01:42:40 1992 John Gilmore (gnu at cygnus.com)
+
+ * remote-udi.c: Update comments.
+
+ * remote.c (getpkt): Only force retransmission ten times;
+ after that, assume bug in target code, and handle pkt anyway.
+
+Mon Aug 3 17:06:20 1992 Stu Grossman (grossman at cygnus.com)
+
+ * configure.in: Add support for apollo 68k under BSD environment.
+ * xm-apollo68b.h: New file to support above.
+
+Mon Aug 3 00:25:56 1992 Fred Fish (fnf@cygnus.com)
+
+ * configure.in: Recognize i486 host cpu.
+ * valprint.c (type_print_derivation_info): Print derivation info
+ in same form as class declarations in source.
+ * valprint.c (type_print_varspec_suffix): Split arg printing
+ code out to type_print_args function.
+
+Sat Aug 1 13:32:58 1992 Fred Fish (fnf@cygnus.com)
+
+ * dwarfread.c (struct dieinfo): Remove obsolete at_visibility,
+ at_import, at_frame_base.
+ * dwarfread.c (completedieinfo): Remove cases for obsolete
+ AT_visibility, AT_import, and AT_frame_base attributes.
+ * breakpoint.h (BREAKPOINT_MAX): Increase from 10 to 16 for
+ i860, which can keep up to 4 shadow breakpoints.
+ * tm-stratus.h (USG): Define.
+ * tm-stratus.h (TARGET_BYTE_ORDER): Define to BIG_ENDIAN.
+ * xm-stratus.h (HOST_BYTE_ORDER): Define to BIG_ENDIAN.
+ * xm-stratus.h (xm-sysv4.h): Include, name changed from xm-svr4.h.
+ * xm-stratus.h (NO_JOB_CONTROL): Remove define.
+ * config/stratus.mt (TDEPFILES): Include files available from
+ stratus that are not yet in release pending receipt of paperwork
+ at FSF.
+ * buildsym.c (finish_block): Minor code format change.
+ * gdbtypes.h (struct field): Add to comments.
+ * gdbtypes.h (virtual_field_bits): Add to comments.
+ * objfiles.c (allocate_objfile): Change obstack interface to
+ match FSF merging efforts.
+
+Mon Jul 27 21:14:44 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.6.2.
+ * Makefile.in (SFILES_MAINDIR): Add stabsread.c
+ * Makefile.in (OBS): Add stabsread.o
+ * Makefile.in (stabsread.o): Add build rule.
+ * stabsread.c, stabsread.h: New files.
+ * buildsym.c: Split out stabs specific support to stabsread.c.
+ * buildsym.h: Split out stabs specific support to stabsread.h.
+ * dbxread.c (stabsread.h): Include
+ * dbxread.c (dbx_new_init): Call stabsread_new_init.
+ * dbxread.c (dbx_psymtab_to_symtab_1): Call stabsread_init.
+ * dbxread.c (read_ofile_symtab): Call end_stabs.
+ * dbxread.c (process_one_symbol): Call end_stabs and start_stabs.
+ * dbxread.c (elfstab_build_psymtabs): Call stabsread_new_init.
+ * dwarfread.c (psymtab_to_symtab_1): Call buildsym_init, add
+ really_free_pendings to cleanups.
+ * elfread.c (elf_new_init): Call stabsread_new_init.
+ * gdbtypes.c: Small changes to maintenance commands.
+ * mipsread.c (stabsread.h): Include.
+ * mipsread.c (psymtab_to_symtab_1): Call end_stabs.
+ * xcoffread.c (stabsread.h): Include.
+ * xcoffread.c (global_stabs): Remove redundant def.
+ * xcoffread.c (read_xcoff_symtab): Call start_stabs and end_stabs.
+
+Wed Jul 22 21:39:33 1992 Fred Fish (fnf@cygnus.com)
+
+ * lmode_inferior_valid, lmode_ours_valid: New static vars.
+ * inflow.c (terminal_init_inferior, terminal_inferior,
+ terminal_ours_1, initialize_inflow): Record and use state
+ of lmode_inferior_valid and lmode_ours_valid.
+
+Wed Jul 22 04:23:03 1992 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * es1800.c: use FREAD|FWRITE rather than _FREAD|_FWRITE.
+ include <sgtty.h> on USG. (from sef).
+
+ * depend: es1800 dependency needed here.
+
+Mon Jul 20 21:09:53 1992 Fred Fish (fnf@cygnus.com)
+
+ * buildsym.c (read_struct_type): Initialize structs allocated
+ with alloca, to avoid using random values from stack later on.
+ * defs.h (fprintf_filtered): Add prototype.
+ * gdbtypes.c (check_stub_method): Fix misleading comments.
+ * gdbtypes.c (print_arg_types, dump_fn_fieldlists): New maint
+ support functions.
+ * gdbtypes.c (print_cplus_stuff, recursive_dump_type): Many
+ small changes to maint support functions.
+ * gdbtypes.h (cplus_struct_type): Reorganize member ordering
+ for some fields and expand comments.
+ * objfiles.c (allocate_objfile): Use new obstack_alloc_arg
+ macro and track change to obstack_full_begin macro.
+ * utils.c (fprintfi_filtered): New function.
+ * valprint.c (type_print_base): Fixup field printing to not
+ print extraneous lines and not print bogus "no data fields"
+ messages for C++ classes with no data members. Also use new
+ fprintfi_filtered function.
+
+Mon Jul 20 11:25:18 1992 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * configure.in: es1800 ok for 68000 too.
+
+Sat Jul 18 15:48:58 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: echo error messages to stderr, not stdout
+
+Fri Jul 17 17:07:24 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: recognize hppa* instead of hppa
+
+Fri Jul 17 16:52:04 1992 Stu Grossman (grossman at cygnus.com)
+
+ * energize.c: Second cut at DynamicLoad message handling.
+
+ * energize.c: Relativize pathnames in #include statements.
+ * (kernel_dispatch): Better error messages for unknown protocol
+ messages.
+ * (kernel_dispatch): First cut at DynamicLoad message handling.
+
+ * Makefile.in: Remove -I../readline from all compilations,
+ include a special case for main.o instead.
+
+Fri Jul 17 10:14:56 1992 Fred Fish (fnf@cygnus.com)
+
+ * eval.c (evaluate_subexp): Ask lookup_struct_elt_type to call
+ error if it fails to find a member type, rather than return NULL
+ and trigger a coredump.
+ * symtab.c (lookup_symbol, lookup_demangled_block_symbol,
+ lookup_demangled_partial_symbol,): Ask demangle_and_match to
+ match on complete demanglings, including argument lists for member
+ functions, rather than just accepting the first demangling that
+ matches the class and function name.
+ * dwarfread.c (read_file_scope): Pass contents of AT_comp_dir
+ to start_symtab as the directory name.
+ * dwarfread.c (completedieinfo): Strip off any leading hostname
+ portion of the AT_comp_dir attribute string. Gdb doesn't know
+ what to do with them (FIXME).
+
+Thu Jul 16 13:37:09 1992 Stu Grossman (grossman at cygnus.com)
+
+ * breakpoint.c (commands_command): Simplify code a bit, remove
+ unnecessary fflush().
+
+ * Makefile.in (OTHERS): Add gcc.patch.
+ * partial-stab.h (N_SO): Fix handling of redundant SOs (again...)
+
+Thu Jul 16 12:07:40 1992 Fred Fish (fnf@cygnus.com)
+
+ * dwarfread.c (LCC_PRODUCER): Change to match current NCR
+ lcc producer string.
+
+Thu Jul 16 11:40:55 1992 Stu Grossman (grossman at cygnus.com)
+
+ * WHATS.NEW renamed to NEWS.
+
+Wed Jul 15 11:37:31 1992 Fred Fish (fnf@cygnus.com)
+
+ * dbxread.c, dwarfread.c: Re-enable experimental code to
+ automatically select demangling style.
+ * demangle.c (DEFAULT_DEMANGLING_STYLE): Rename from simply
+ DEMANGLING_STYLE, to make more descriptive. Revert back to
+ "auto" as default. Comment use.
+ * Makefile.in (DEMANGLING_STYLE, DEMANGLE_OPTS): Remove.
+ * Makefile.in (${DEMANGLER}.o) Remove target and special
+ compilation rule.
+
+Tue Jul 14 23:05:14 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.6.1 (post-release versions).
+
+Tue Jul 14 19:26:54 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in, demangle.c: Change default demangling style to
+ gnu.
+ * Makefile.in: Update version to 4.6 !!!
+ * README, WHATS.NEW: Update for 4.6.
+
+Tue Jul 14 16:59:46 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * i960-tdep.c (frame_args_address): If arg pointer can't be found,
+ use frame address.
+
+ * buildsym.c (read_struct_type): Don't die on TYPE_CODE_UNDEF
+ nodes as base classes.
+
+Tue Jul 14 00:12:30 1992 Stu Grossman (grossman at cygnus.com)
+
+ * alldeps.mak, depend: Update.
+
+ * xcoffread.c: Add decl for section_offset to keep prototype happy.
+
+ * Makefile.in (VERSION): 4.5.9.
+
+ * xm-hp300bsd.h: Add decl for strdup().
+ * mips-tdep.c (heuristic_proc_desc): Fill in proc start addr in
+ PDR. Cleanup a few things, fix compilation warnings.
+
+Mon Jul 13 19:06:54 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (DEMANGLING_STYLE): New define to set default
+ demangling style for C++. Defaults to "auto".
+ * Makefile.in (DEMANGLE_OPTS): Use DEMANGLING_STYLE.
+ * Makefile.in (SFILES_MAINDIR): Add demangle.c
+ * Makefile.in (OBS): Add demangle.o
+ * cplus-dem.c (GNU_DEMANGLING, ARM_DEMANGLING, LUCID_DEMANGLING):
+ Remove compile time decisions about demangling style and replace
+ with runtime decisions using current_demangling_style.
+ * cplus-dem.c (main): Expand code included during building of
+ standalone demangler to recognize demangling style options.
+ * dbxread.c (demangle.h): Include.
+ * dbxread.c (read_ofile_symtab, process_one_symbol): Set GNU C++
+ demangling style if processing g++ code and current demangling style
+ is auto (Note: this feature currently disabled.)
+ * demangle.c: New file, generic demangling control.
+ * demangle.h (demangling_styles): New enumeration to select one
+ of several demangling styles. Also define string names for each
+ style.
+ * demangle.h (set_demangling_style): Add prototype.
+ * dwarfread.c (demangle.h): Include.
+ * dwarfread.c (GPLUS_PRODUCER, LCC_PRODUCER, CFRONT_PRODUCER):
+ New producer string prefixes to recognize.
+ * dwarfread.c (handle_producer): Consolidate actions for specific
+ producers. Set demangling style based on producer string if
+ current style is auto. (Note: this feature currently disabled.)
+ * config/ncr3000.mt (DEMANGLE_OPTS): Remove.
+
+Sat Jul 11 18:23:58 1992 John Gilmore (gnu at cygnus.com)
+
+ * config/sun4sol2.mh: Remove -xs flag, default INSTALL to cp.
+
+Fri Jul 10 13:58:34 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * gdbtypes.c, gdbtypes.h: New function lookup_signed_typename.
+ * c-exp.y: Call lookup_signed_typename() after seeing
+ "signed". This handles "signed char" correctly.
+ * c-exp.y: Recognize (but ignore) 'const' and 'volatile'
+ keywords before a type specifier.
+
+Fri Jul 10 10:19:52 1992 Fred Fish (fnf@cygnus.com)
+
+ * command.c (lookup_cmd_1): Clarify descriptive comments.
+ * gdbcmd.h (maintenanceprintlist): Add declaration.
+ * main.c (maintenanceprintlist): Add definition.
+ * main.c (gdb_completer_command_word_break_characters): Add.
+ * main.c (symbol_completion_function): Switch completer word
+ break character sets dynamically, based on whether completion is
+ being done on commands or on something else.
+ * main.c (initialize_cmd_lists): Init maintenanceprintlist.
+ * maint.c: Include demangle.h.
+ * maint.c (maintenance_demangle): New function.
+ * maint.c (maintenance_print_command): New function.
+ * maint.c (_initialize_maint_cmds): Reorganize some commands
+ under new maintenance print subcommand.
+
+Thu Jul 9 19:05:27 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * gdbtypes.c (lookup_struct_elt_type): If the input type is
+ TYPE_CODE_PTR or TYPE_CODE_REF, dereference it to get the
+ target type. Otherwise, 'whatis this.field' wouldn't work,
+ which would be inconsistent, since 'print this.field' works.
+ * buildsym.c (read_struct_type, read_enum_type): Clear
+ TYPE_FLAG_STUB flag.
+ * buildsym.c (cleanup_undefined_types): Don't rely on a
+ flawed "Reasonable test to see if" a type has been defined
+ since it was referred to; now we can just see if the
+ TYPE_FLAG_STUB flag has been cleared.
+ * valprint.c (print_type_base): Emit public/protected/private
+ labels for methods as well as fields. Also, indent these labels
+ 2 spaces instead of 4, for a more conventional "look".
+ * symtab.c (gdb_mangle_name): Undo Fred's change, unless
+ GCC_MANGLE_BUG is defined. Also, handle destructors specially.
+ * gcc.patch: New file. Contains patch for gcc (so people
+ with gdb-2.2.x won't have to wait for a new gcc release).
+
+Thu Jul 9 18:44:26 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * i960-pinsn.c (mem): Variables reg[123] should point to CONST.
+ (print_addr): Call print_address to show symbolic version as well.
+
+ * remote-vx.c (vx_kill): Don't look for arguments; they aren't
+ being passed.
+ (vx_read_register): Declare inferior_fp_regs. Delete code for
+ copying "inferior_registers" around; the values are already in var
+ "registers". Use correct size for register set.
+
+ * remote-vx.c (vx_write_register): Don't try writing FP regs; the
+ target doesn't support it.
+ (vx_read_register): Don't try reading them either.
+
+ * tm-i960.h (IP_REGNUM): Move to end of non-FP list, since the
+ VxWorks back end reads them in one contiguous set except for this
+ one.
+ (register_names): Change "pc" to "pcw" to avoid confusion printing
+ "$pc".
+ * tm-vx960.h (PC_REGNUM): Use RIP_REGNUM, since that's where we
+ find the PC under VxWorks.
+
+Wed Jul 8 21:34:30 1992 Fred Fish (fnf@cygnus.com)
+
+ * dwarfread.c (alloc_utype, decode_subscr_data): Call alloc_type
+ to create new blank types, instead of handcrafting them.
+ * defs.h (printfi_filtered): Add prototype.
+ * utils.c (printfi_filtered): New function.
+ * gdbtypes.c (recursive_dump_type): Use printfi_filtered to
+ to simplify the code. Other cleanups.
+ * gdbtypes.c (check_stub_method): Demangle using DMGL_ANSI.
+ * gdbtypes.h (struct cplus_struct_type): Add comments describing
+ use of various fields.
+ * gdbtypes.c (print_bit_vector, print_cplus_stuff): New functions.
+ * c-exp.y (%token): Add CLASS as a token for C++, add grammar
+ production that currently treats it exactly the same as STRUCT.
+ * c-exp.y (yylex): Recognize "class" as token CLASS.
+ * symtab.c (gdb_mangle_name): Rewrite to match current g++ stabs.
+ * symtab.c (decode_line_1): Fix to pass quoted args on down to
+ general symbol handling code. Call cplus_mangle_opname with
+ DMGL_ANSI.
+ * symtab.c (decode_line_2): Print demangled function names in
+ breakpoint menus, instead of just file and line number.
+ * symtab.c (name_match): Call cplus_demangle with DMGL_ANSI.
+ * valprint.c (type_print_base): Print "class" for C++ classes,
+ rather than "struct". Print section labels for public, protected
+ and private members of C++ classes.
+ * values.c: Include demangle.h.
+ * values.c (value_headof): Call cplus_demangle with DMGL_ANSI.
+
+Wed Jul 8 17:23:07 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (VERSION): Update to 4.5.8.
+
+ Wed Jul 8 00:11:02 1992 Stu Grossman (grossman at cygnus.com)
+
+ * dbxread.c (dbx_symfile_init): Init stab_section_info to NULL to
+ prevent crashes when examining cross-targets.
+ * dbxread.c (process_one_symbol): Include directory name when
+ calling start_subfile for SOL & BINCL symbols. This allows gdb to
+ find include files, and yacc/lex sources when the cwd doesn't match
+ that in which the object was compiled.
+ * objfiles.h (ALL_MSYMBOLS): Don't seg fault when there are no
+ msymbols.
+ * symtab.c (lookup_symtab_1): Rewrite. It now handles include
+ files.
+
+Tue Jul 7 09:00:42 1992 Fred Fish (fnf@cygnus.com)
+
+ * maint.c (maintenance_command, maintenance_info_command):
+ Install with allow_unknown as 0 and call help_list to show
+ list of possibilities when no subcommand is specified.
+
+Tue Jul 7 00:20:29 1992 Fred Fish (fnf@cygnus.com)
+
+ * configure.in: Add m68k-ericsson-*.
+ * remote-es1800.c, tm-es1800.h, config/es1800.mt: New files.
+
+Sun Jul 5 17:17:16 1992 Fred Fish (fnf@cygnus.com)
+
+ * maint.c: New file.
+ * Makefile.in (SFILES_MAINDIR): Add new file maint.c.
+ * Makefile.in (OBS): Add new file maint.o.
+ * defs.h (command_class): Add class_maintenance.
+ * defs.h (MAINTENANCE_CMDS): Default to including maintenance
+ commands. Allow for them (and other nonessential parts of gdb)
+ to be selectively left out under special circumstances.
+ * gdbtypes.c (recursive_dump_type): New function; supports
+ maintenance print-type command.
+ * gdbtypes.h (recursive_dump_type, maintenance_print_type):
+ Add prototypes.
+ * main.c (maintenancelist, maintenanceinfolist): Add maintenance
+ command lists.
+ * main.c (initialize_cmd_lists): Eliminate unnecessary casts on
+ initializers. Add initializations for setprintlist, showprintlist,
+ setchecklist, showchecklist, maintenancelist, and maintenanceinfolist.
+ * printcmd.c (maintenance_print_type): New maintenance cmd.
+ * valprint.c (setprintlist, showprintlist): Move to main.c, as
+ implied by comment that all cmd lists are owned by main.c.
+ * infcmd.c (unsetlist): Move to main.c, as implied by comment
+ that all cmd lists are owned by main.c.
+ * language.c (setchecklist, showchecklist): Move to main.c, as
+ implied by comment that all cmd lists are owned by main.c
+ * breakpoint.c (enablelist, enablebreaklist, disablelist, cmdlist,
+ deletelist): Remove redundant declarations (also in gdbcmd.h).
+ * symmisc.c (printsyms_command): Now maintenance_print_symbols.
+ * symmisc.c (printmsyms_command): Now maintenance_print_msymbols.
+ * symmisc.c (printpsyms_command): Now maintenance_print_psymbols.
+ * symmisc.c (printobjfiles_command): Now maintenance_print_objfiles.
+ * symtab.h (maintenance_print_symbols, maintenance_print_psymbols,
+ maintenance_print_msymbols, maintenance_print_objfiles):
+ Add prototypes.
+ * symmisc.c (printsyms_command, printpsyms_command,
+ printmsyms_command, printobjfiles_command): Removed from
+ _initialize_symmisc.
+ * main.c (dump_me_command): Moved to maint.c and renamed to
+ maintenance_dump_me.
+ * breakpoint.c (all_breakpoints_info): Rename to
+ maintenance_info_breakpoints.
+ * breakpoint.c (_initialize_breakpoint): Convert add_info of
+ all_breakpoints_info to add maintenance_info_breakpoints to the
+ maintenanceinfolist instead.
+ main.c (initialize_main): Set up maintenance class commands.
+
+Sun Jul 5 11:03:53 1992 Stu Grossman (grossman at cygnus.com)
+
+ * energize-patches: Fix minor problems with building energize lib.
+
+ * energize-patches: Change names of all cadillac procedure calls
+ to be energize procedure calls. Simplify many hooks by moving
+ tests energize.c. Configure energize, and build it automatically now.
+
+Sun Jul 5 09:43:28 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.5.7.
+ * cplus-dem.c (demangle_args): Validate index for previously
+ seen type to guard against bogus values from malformed manglings.
+ * valops.c (value_struct_elt_for_reference): Guard against
+ blindly using NULL return value from lookup_symbol.
+
+Sun Jul 5 09:46:43 1992 Stu Grossman (grossman at cygnus.com)
+
+ * cadillac.c, cadillac-patches: Rename to energize.c and
+ energize-patches. Change all routines and variables named
+ 'cadillac*' to 'energize*'. Create new file called energize.h to
+ hold all interface declarations.
+
+ * deblib/connection/*: Move all of this stuff into energize/, but
+ delete unneeded files.
+
+Sun Jul 5 03:06:39 1992 John Gilmore (gnu at cygnus.com)
+
+ * tm-sysv4.h (NAMES_HAVE_UNDERSCORE): SVR4 systems don't.
+
+ * buildsym.c (finish_block): Fix thinko `inner block' complaints.
+ * dbxread.c (process_one_symbol): Parse N_OPT "gcc2_compiled.".
+ * procfs.c (proc_set_exec_trap): Set run-on-last-close flag on
+ child processes, to avoid dead ones "hanging around" after GDB exits.
+ (attach): Always stop the process if it needs it. Set RLC flag
+ when attaching running processes, so it will continue if we detach
+ it, quit, or are killed.
+ (detach): Clear faults and set RLC flag to make process run
+ when we close it.
+ (open_proc_file): New `mode' argument for O_RDONLY or O_RDWR.
+ Callers changed.
+ (info_proc): Open process O_RDONLY, so we can see any process,
+ even those controlled by debuggers.
+ * tm-sun4sol2.h (SUN_FIXED_LBRAC_BUG): They did (in Sol 2).
+
+Sat Jul 4 03:43:38 1992 John Gilmore (gnu at cygnus.com)
+
+ Relocate symbols using an array of section_offsets, rather than a
+ single `addr' or `offset'. This makes Solaris-2 support work, and
+ permits better VxWorks (and maybe xcoff) support later.
+
+ * symtab.h (struct section_offsets): New structure for keeping
+ a set of offsets, rather than a single one.
+ (struct objfile): Replace addr with section_offsets member.
+ * symfile.h: Add sym_offsets to struct sym_fns. Conforming changes.
+ * gdb-stabs.h: New include file with `symbol type specific'
+ parameters for psymtabs and objfiles.
+ * Makefile.in (HFILES): Add gdb-stabs.h.
+ * buildsym.h (start_psymtab, process_one_symbol): Fix prototypes.
+ * coffread.c: Conforming changes. Fake offset array always 0.
+ * dbxread.c: Conforming changes.
+ (struct dbx_symfile_info): Move to gdb-stabs.h.
+ (start_psymtab): Call elfstab_offset_sections to calculate good
+ offsets for this source file, based on the ELF symbol table info.
+ (read_ofile_symtab): Yank N_CATCH, which is dead.
+ (process_one_symbol, N_CATCH): Yank.
+ (", N_FUN, N_FNAME, N_FN, N_FN_SEQ, N_SO, N_SOL, N_ENTRY):
+ Relocate with SECT_OFF_TEXT.
+ (", N_STSYM, N_LCSYM, N_ROSYM): Grope around in the stab string
+ to distinguish relocatable from absolute symbols. Then, if not
+ absolute, do:
+ (", N_STSYM, N_DSLINE): SECT_OFF_DATA.
+ (", N_LCSYM, N_BSLINE): SECT_OFF_BSS.
+ (", N_ROSYM): SECT_OFF_RODATA.
+ (elfstab_build_psymtabs): Caller has allocated dbx_symfile_info.
+ (dbx_symfile_offsets): Add to translate addr to offset.
+ * dwarfread.c: Conforming changes. Single offset currently used.
+ * elfread.c: Add various complaints about elf/stab stuff.
+ #include gdb-stabs.h. Conforming changes, using a single offset.
+ (elf_symtab_read): Record info from BSF_FILE symbols, and local
+ variables called "Bbss.bss", "Ddata.data", and "Drodata.rodata",
+ for later use in building psymtabs.
+ (elf_symfile_read): Allocate dbx_symfile_info here, to keep
+ the info collected in elf_symtab_read. Cleanup calls free_elfinfo.
+ (free_elfinfo): New fn, frees all chained stab_section_infos
+ in an objfile, and zaps the start-of-chain pointer.
+ (elfstab_offset_sections): New fn, looks in stab_section_info
+ chain to determine section bases to relocate a psymtab's worth
+ of symbols, as they are being read.
+ * mipsread.c: Conforming changes. Stabs-reading will relocate
+ using one offset. MIPS-reading will not relocate at all.
+ * partial-stab.h: Relocate different symbol types using different
+ offsets from section_offsets.
+ * symfile.c: Conforming changes.
+ (find_lowest_section): Unused function to use later
+ to free us from the Tyranny of the Text Section.
+ (syms_from_objfile): Translate absolute arg ADDR to offsets used
+ in all lower layers of symbol reading. Call format-specific
+ sym_offsets function to initialize offsets for high speed symbol
+ reading.
+ (symbol_file_add): Call reinit_frame_cache so callers don't have to.
+ (symbol_file_command, add_symbol_file_command): Callers changed.
+ * symmisc.c (dump_psymtab): Print new relocation parameters.
+ * xcoffread.c: Corresponding changes.
+
+ * buildsym.c: Tidy innerblock_complaint and blockvector_complaint.
+ * main.c (main): Read the $HOME/.gdbinit file before processing
+ the argv arguments (e.g. reading symbol files or core
+ files). This allows global parameters to be set, which will apply
+ during the symbol reading. The ./.gdbinit is still read after
+ argv processing.
+ * symtab.c (list_symbols): `i variables' shouldn't show enum values.
+ * xcoffexec.c: Clean up quote inside comment.
+
+Fri Jul 3 20:18:26 1992 Fred Fish (fnf@cygnus.com)
+
+ * breakpoint.c, buildsym.c, c-exp.y, coffread.c, command.c,
+ core.c, cplus-dem.c, dbxread.c, dwarfread.c, elfread.c, environ.c,
+ eval.c, findvar.c, gdbtypes.c, hppabsd-tdep.c, hppahpux-tdep.c,
+ i386-tdep.c, ieee-float.c, infcmd.c, inflow.c, infptrace.c,
+ infrun.c, m2-exp.y, mipsread.c, objfiles.c, parse.c, procfs.c,
+ putenv.c, remote-mm.c, remote-vx.c, solib.c, sparc-tdep.c,
+ sparc-xdep.c, stack.c, symfile.c, symtab.c, symtab.h, target.c,
+ tm-i386v.h, tm-sparc.h, utils.c, valarith.c, valops.c, valprint.c,
+ values.c, xcoffread.c:
+ Remove "(void)" casts from function calls where the return value
+ is ignored, in accordance with GNU coding standards.
+
+Fri Jul 3 00:00:49 1992 John Gilmore (gnu at cygnus.com)
+
+ * dbxread.c (process_one_symbol): Ignore N_MAIN, N_ENDM for Solaris.
+ * partial-stab.h: Ignore N_ENDM.
+ * elfread.c (elf_symtab_read): Ignore symbols that don't have a
+ CODE or DATA section attachment. This eliminates a lot of random
+ values from shared libraries, which screw up the ordinary symbols
+ in the address ranges they happen to overlap.
+ * buildsym.c (define_symbol): Eliminate special tests
+ for function types; move into "function" cases in switch statement.
+ (define_symbol: 'f', 'F', 'P'): Process all parameter types
+ in case they define new type numbers. But ignore them (FIXME).
+ ('k', 'B'): Ignore const and volatile if we see them (FIXME).
+ (read_sun_builtin_type): Add commentary.
+
+Wed Jul 1 00:47:02 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * xm-rs6000.h: define MEM_FNS_DECLARED
+
+Tue Jun 30 02:25:10 1992 John Gilmore (gnu at cygnus.com)
+
+ * tm-mips.h (GDB_TARGET_IS_MIPS): Define for mips-xdep.c.
+ (READ_MIPS_FORMAT, COFF_FORMAT): Remove, unused now.
+ * mips-xdep.c: Remove most include files (unused, caused errs).
+ (fetch_core_registers): Use right parameters in dummy fn.
+
+Mon Jun 29 18:30:57 1992 John Gilmore (gnu at cygnus.com)
+
+ * buildsym.c (scan_file_globals): Beware the null file.
+ Fix from Jim Williams.
+
+ * stack.c (return_command): Evaluate expression *before* popping
+ off the stack frames! Fix inspired by Jim Williams.
+ (up_silently_command, down_silently_command): No sel frame is error.
+
+ * defs.h (memcpy, memset): Conditionalize decls on
+ #ifndef MEM_FNS_DECLARED, since DECstation differs.
+ (alloca): Break out the STDC and non-STDC alloca cases, to make
+ it work on old preprocessors as well as "picky ANSI" ones.
+ * xm-mips.h (memcpy, memset): Declare, and set MEM_FNS_DECLARED.
+
+ * mips-tdep.c (heuristic_proc_start): Zero arg produces zero.
+ * utils.c (fputs_demangled): Rename SLOP since DECstation system
+ header files define it!
+
+ * tm-29k.h (BREAKPOINT): Allow it to be overridden with -D.
+
+Mon Jun 29 16:30:25 1992 Fred Fish (fnf@cygnus.com)
+
+ * dbxread.c, i386-pinsn.c, i386-tdep.c, regex.c, solib.c, symmisc.c,
+ symtab.h, tm-i386v4.h, valprint.c, values.c: Lint.
+ * breakpoint.c, c-exp.y, coffread.c, command.c, environ.c, eval.c,
+ findvar.c, infcmd.c, infptrace.c, infrun.c, m2-exp.y, parse.c,
+ putenv.c, solib.c, sparc-xdep.c, symtab.c, tm-i386v.h, tm-sparc.h,
+ utils.c, valarith.c, valops.c, valprint.c, values.c:
+ Replace bcopy() use with memcpy(), which is more standard and can
+ take advantage of gcc's builtin functions for increased performance.
+ * breakpoint.c, buildsym.c, coffread.c, dbxread.c, i386-tdep.c,
+ ieee-float.c, infcmd.c, sparc-tdep.c, stack.c, symtab.c, symtab.h,
+ target.c, values.c:
+ Replace bzero() use with memset(), which is more standard and can
+ take advantage of gcc's builtin functions for increased performance.
+ * i386-tdep.c, main.c, valprint.c:
+ Replace bcmp() use with memcmp(), which is more standard and can
+ take advantage of gcc's builtin functions for increased performance.
+
+Sun Jun 28 13:30:22 1992 Fred Fish (fnf@cygnus.com)
+
+ * remote.c (remote_wait): Fix cast on signal() call.
+ * defs.h (alloca): More diddling with alloca. Have to ensure
+ that it has a prototype, so that if alloca is defined as a macro
+ that takes an arg, the definition is seen as a use of a macro
+ that takes an arg, to satisfy picky ANSI preprocessors.
+
+Sat Jun 27 12:12:20 1992 Fred Fish (fnf@cygnus.com)
+
+ * sparc-pinsn.c: Use <string.h> rather than "string.h", for
+ consistency with all other gdb files.
+ * cadillac.c: Use <string.h> rather than <strings.h>.
+ * cadillac.c (kernel_dispatch): Convert rindex usage to strrchr.
+ * Makefile.in (MAKE): Remove definition for consistency with
+ other Makefile.in files and to fix problem with recursive makes.
+
+Fri Jun 26 19:03:23 1992 John Gilmore (gnu at cygnus.com)
+
+ * hppahpux-xdep.c (child_xfer_memory): Avoid PT_WDUSER because it
+ crashes H-PUX.
+
+Fri Jun 26 11:09:10 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * source.c (print_source_lines): for DOS interoperability; don't
+ print CR (013) as ^M.
+
+Thu Jun 25 15:18:42 1992 Stu Grossman (grossman at cygnus.com)
+
+ * dbxread.c (dbx_symfile_init): Move more code under hp9000s800
+ conditional.
+ * hppabsd-core.c: Don't include "param.h", include <sys/param.h>
+ instead.
+ * remote.c (remote_wait): Cast signal to void * to avoid warning
+ from busted HP compiler.
+
+ * partial-stab.h (N_SO): Rearrange code a little so that all SO
+ stabs cause end_psymtab to be called.
+
+ * buildsym.c (read_sun_builtin_type): Handle new FCS Sun CC
+ compiler feature of putting 'c' into basic type descriptors for
+ all forms of char.
+
+ * procfs.c (child_resume): Work around Solaris (on Sparc) lossage
+ where there is no place for nPC in prrun struct.
+
+Thu Jun 25 12:06:00 1992 Fred Fish (fnf@cygnus.com)
+
+ * mipsread.c: Pass NULL name pointer to init_type, not 0.
+ * gdbtypes.c (init_type): Use copy of typename on type_obstack.
+ * dwarfread.c (enum_type): Save enum names on type_obstack.
+ * dwarfread.c (struct_type): Save member name on type_obstack.
+ * symtab.c (_initialize_symtab): Fix misspelling.
+ * regex.c (store_jump, insert_jump): Return void.
+
+Thu Jun 25 04:00:10 1992 John Gilmore (gnu at cygnus.com)
+
+ * defs.h (PARAMS): Move to ../include/ansidecl.h.
+ (alloca): Declare return type on SPARC, since Sun doesn't.
+ (*_BYTE_ORDER): Improve comment: *must* be defined.
+
+ * tm-hppa.h: New file, architectural definition of HP PA.
+ * tm-hppabsd.h, tm-hppahpux.h: Shrink to deltas from tm-hppa.h.
+
+ * am29k-pinsn.c, am29k-tdep.c, copying.awk, copying.c,
+ hppa-coredep.c, hppa-pinsn.c, hppabsd-core.c, hppabsd-tdep.c,
+ hppabsd-xdep.c, hppahpux-tdep.c, hppahpux-xdep.c, remote-udi.c,
+ ser-go32.c, xcoffsolib.c: Remove <stdio.h> which is already in
+ "defs.h".
+
+ * hppa-coredep.c, hppa-pinsn.c, hppabsd-core.c, hppabsd-tdep.c,
+ hppabsd-xdep.c, hppahpux-tdep.c, hppahpux-xdep.c, xcoffsolib.c,
+ xcoffsolib.h, xm-go32.h, xm-hppabsd.h, xm-hppahpux.h: Copyrights.
+
+Wed Jun 24 12:53:20 1992 John Gilmore (gnu at cygnus.com)
+
+ * printcmd.c (output_command): Thinko.
+ (x_command): Only set remembered size/format if cmd succeeds.
+
+ * dbxread.c (read_ofile_symtab): Remove N_CATCH special case,
+ since it is no longer used and burns time for every symbol read.
+ (process_one_symbol): Treat N_CATCH like default (complain).
+
+Wed Jun 24 00:26:56 1992 Stu Grossman (grossman at cygnus.com)
+
+ * partial-stab.h (case N_TEXT): Fix fencepost error when
+ detecting start of new symbol info after reading symtab for a
+ module with a zero length TEXT segment.
+
+Tue Jun 23 21:46:26 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.5.6.
+ * coffread.c (coff_end_symtab): Cast 2nd arg of complain() to
+ correct type.
+ * defs.h (NORETURN): Define away for Lucid compiler.
+ * remote.c (remote_timer, remote_interrupt): Signal handlers
+ take one int arg.
+ * ser-termios.c (serial_write, serial_close): Return whatever
+ value the write/close call returns, rather than falling off end.
+ * inferior.h (PTRACE_ARG3_TYPE): Third arg to ptrace is int on
+ more systems than it is "char *". Define PTRACE_ARG3_TYPE to
+ default to int.
+ * infptrace.c, hppabsd-xdep.c, hppahpux-xdep.c, i386-xdep.c,
+ inferior.h (call_ptrace): Use PTRACE_ARG3_TYPE to declare type
+ of third arg.
+ * a68v-xdep.c, arm-xdep.c, convex-xdep.c, hp300ux-xdep.c, infrun.c,
+ m88k-xdep.c, mach386-xdep.c, mips-xdep.c, os68k-xdep.c, pyr-tdep.c,
+ pyr-xdep.c, rs6000-xdep.c, sparc-xdep.c, sun3-xdep.c, sun386-xdep.c,
+ symm-xdep.c, ultra3-xdep.c: Use PTRACE_ARG3_TYPE to cast ptrace
+ argument 3.
+ * sparc-xdep.c, a68v-xdep.c (fetch_inferior_registers,
+ store_inferior_registers): Supply missing fourth argument to
+ ptrace().
+ * cadillac.c (kernel_dispatch): Make return type void.
+ * cadillac.c (iosig): Signal handlers take one int arg.
+ * valprint.c (val_print_fields): Call fprint_symbol to get
+ automatic C++ demangling for mangled field names.
+
+Mon Jun 22 20:18:06 1992 Fred Fish (fnf@cygnus.com)
+
+ * command.c (add_abbrev_prefix_cmd): Fix misspelling in comment.
+ * dwarfread.c (enum_type): Fix misspelling in comment.
+ * valprint.c (val_print_fields, cplus_val_print): Minor
+ adjustment to printing of C++ class structures to more closely
+ match format for printing C structures, with and without setting
+ pretty print.
+
+Mon Jun 22 17:19:02 1992 Per Bothner (bothner@cygnus.com)
+
+ * infrun.c (wait_for_inferior): Don't test for SIGEMT
+ (which is not a Posix signal) if it isn't defined.
+ * tm-linux.h, xm-linux.h, config/linux.m[ht], configure.in:
+ New port to Linux (a free Unix clone for 386 machines).
+
+Sat Jun 20 19:19:52 1992 John Gilmore (gnu at cygnus.com)
+
+ COFF changes for dealing better with EPI 29K C compiler output.
+
+ * coffread.c (record_minimal_symbol): Pass the minsym type to it.
+ Callers changed.
+ (coff_end_symtab): Sort blocks if needed. Complain if misordered.
+ (read_coff_symtab): Move patch_opaque_types call from
+ coff_symfile_read. Restrict it to symtabs from this objfile.
+ (process_coff_symbol: C_TPDEF): Don't put ordinary foward
+ references on opaque type chain; just let coff_lookup_type handle 'em.
+ (decode_type): Complain about tagndx values on
+ non-struct/union/enum types, which the EPI compiler tends to produce.
+
+ * symtab.c (list_symbols): Make minimal symbol variable-finding work.
+
+ * tm-68k.h (FIX_CALL_DUMMY): Avoid alignment and byte order
+ dependency.
+
+ * elfread.c (elf_symfile_read): Update bfd_elf_find_section
+ usage to match new prototype. Include libbfd.h to get prototype.
+
+ * source.c (find_source_lines): Handle large st_size fields.
+
+Sat Jun 20 16:28:39 1992 Fred Fish (fnf@cygnus.com)
+
+ * infcmd.c (jump_command): Use cleanups to avoid memory leaks.
+ * stack.c (return_command): Use cleanups to avoid memory leaks.
+
+Fri Jun 19 19:06:41 1992 John Gilmore (gnu at cygnus.com)
+
+ * remote-adapt.c, remote-eb.c, remote-mm.c: Lint. Fix
+ INT_REGNUM to INTE_REGNUM.
+
+ * tm-29k.h (SDB_REG_TO_REGNUM): Add for EPI 29K C compiler.
+
+Fri Jun 19 15:30:15 1992 Stu Grossman (grossman at cygnus.com)
+
+ * configure.in, dbxread.c, hppa-coredep.c, hppa-pinsn.c,
+ hppabsd-core.c, hppabsd-tdep.c, hppabsd-xdep.c, hppahpux-tdep.c,
+ hppahpux-xdep.c, munch, partial-stab.h, tm-hppabsd.h,
+ tm-hppahpux.h, xm-hppabsd.h, xm-hppahpux.h: HPPA merge.
+
+ * Makefile.in (c-exp.tab.c, m2-exp.tab.c): Filter out bogus extern
+ declarations of malloc/realloc/free that are inserted by some
+ versions of yacc.
+ * m2-exp.y: Prevent conflicts with TRUE and FALSE tokens by
+ #undeffing them.
+ * xm-rs6000.h: Declare malloc/realloc/free appropriately. Yet
+ another decl of strdup (this really ought to come from libiberty.h!).
+
+Fri Jun 19 10:28:05 1992 John Gilmore (gnu at cygnus.com)
+
+ * remote.c (getpkt): Error if input exceeds buffer size.
+ (_initialize_remote): `set remotedebug' enables packet trace.
+
+ * dbxread.c (process_one_symbol:N_FUN): GCC now produces relative
+ N_SLINE's, etc, just like Sun cc on Solaris2.
+
+ * am29k-tdep.c (read_register_stack, write_register_stack):
+ Change RSTACK_HIGH_ADDR to rstack_high_address, a user-settable
+ variable. Add `set' and `show' commands for it.
+ * doc/gdb.texinfo: Document it.
+
+Thu Jun 18 19:35:22 1992 Fred Fish (fnf@cygnus.com)
+
+ * valprint.c (type_print_1): Plug memory leak. Print all
+ C++ syms as demangled, not just functions.
+ * buildsym.c (read_range_type): When we find a signed char
+ type, do a lookup of signed char, not plain char. Plain char's
+ still get looked up as plain char's elsewhere.
+
+Thu Jun 18 18:59:04 1992 John Gilmore (gnu at cygnus.com)
+
+ * eval.c: Avoid residue-by-zero when evaluating without side effects.
+ (Bug and fix found by Pierre Willard.)
+
+Wed Jun 17 13:08:33 1992 Stu Grossman (grossman at cygnus.com)
+
+ * xm-rs6000.h: Fix decls for malloc, realloc, and free.
+
+ * xm-rs6000.h: Add decl for strdup().
+
+ * tm-rs6000.h: Remove #include of inferior.h. Fixes many
+ compilation errors.
+
+ * breakpoint.c (enable_command, disable_command): Without args,
+ should only affect normal breakpoints and watchpoints.
+
+ * m68k-pinsn.c (print_insn_arg): Make register be const.
+ * xcoffexec.c: Remove ' from comment.
+ * xm-sun3os4.h: Define MALLOC_INCOMPATIBLE to avoid conflicts
+ with decls of malloc in c-exp.tab.c (as produced by yacc).
+ There's got to be a better way to do this...
+
+Wed Jun 17 11:10:40 1992 Fred Fish (fnf@cygnus.com)
+
+ * partial-stab.h: Convert single rindex use to strrchr.
+ * mipsread.c, dbxread.c: Remove troublesome inclusion of non-
+ standard <strings.h> file, now that the only single use of
+ rindex in the gdb source files is gone.
+
+Tue Jun 16 22:17:49 1992 Fred Fish (fnf@cygnus.com)
+
+ * mipsread.c: Undo ill effects from including <strings.h>,
+ which #defines index to be strchr. Unfortunately, index is
+ a member of a symbol table structure that can't be changed.
+ * mipsread.c: tm-mips.h includes coff/symconst.h and coff/sym.h,
+ remove redundant #include's.
+
+Tue Jun 16 14:15:51 1992 Stu Grossman (grossman at cygnus.com)
+
+ * mipsread.c: #include <strings.h> for rindex().
+
+Tue Jun 16 09:01:49 1992 Fred Fish (fnf@cygnus.com)
+
+ * xcoffexec.c (map_vmap): Turn comment into a real C comment.
+
+Mon Jun 15 18:41:23 1992 Stu Grossman (grossman at cygnus.com)
+
+ * dbxread.c (process_one_symbol), partial-stab.h: Ignore
+ extraneous SO stabs from busted C++ compilers.
+
+Mon Jun 15 12:21:45 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.5.5.
+ * symtab.c (decode_line_1): Until C++ support stabilizes, when
+ C++ lookups fail, print possibly helpful hint about completion.
+ * cplus-dem.c (demangle_signature): Fix ARM style demangling
+ for static data members.
+ * dbxread.c (dbx_psymtab_to_symtab_1): Fix prototype.
+ * config/ncr3000.mh (INSTALL): Don't use /usr/ucb/install,
+ it's broken on ncr3000's.
+
+Mon Jun 15 07:21:00 1992 Fred Fish (fnf@cygnus.com)
+
+ * dwarfread.c (decode_modified_type): Change type of first arg.
+ Change 'modifier' to char from unsigned char. Cast single use
+ that needs to be unsigned char.
+ * symtab.h (SYMBOL_BASEREG_VALID): Explain disabling.
+ * utils.c (strdup_demangled): Add function.
+ * defs.h (strdup_demangled): Add prototype.
+ * stack.c (return_command): Demangle C++ function names for query.
+ * infcmd.c (jump_command): Demangle C++ function names for query.
+ * cplus-dem.c (consume_count): New function and prototype.
+ * cplus-dem.c (demangle_class, gnu_special, demangle_func_type,
+ do_type): Replace conversion code with consume_count().
+ * cplus-dem.c (gnu_special): Fix demangled of static members.
+ * source.c (list_command): Print demangled function names
+ when appropriate. Fix supplied by Peter Schauer.
+
+Mon Jun 15 01:45:48 1992 John Gilmore (gnu at cygnus.com)
+
+ * sparc-tdep.c: Clean up slightly for Solaris2.
+
+ * buildsym.c (define_symbol): Nameless types are now on several
+ platforms; generalize them and un-ifdef them to make Solaris 2
+ work.
+
+Sun Jun 14 10:55:51 1992 John Gilmore (gnu at cygnus.com)
+
+ * infcmd.c: Fix typo (reported by Rob Savoye).
+ * xm-sun4sol2.h (gregset_t): Thinko in register set definition.
+ * symtab.h: Disable SYMBOL_BASEREG_VALID until it works.
+ * dbxread.c (dbx_psymtab_to_symtab_1): Renamed from
+ psymtab_to_symtab_1. Use current psymtab's sym_offset and symbol_size,
+ rather than the one for the first file in the dependency chain.
+
+ * dbxread.c (end_psymtab): Only reset texthigh if it's not already
+ set. Don't reset our own texthigh, or dependency-only pst's, in
+ scanning all the rest of the psymtabs.
+ (process_one_symbol): Fix comments around N_OBJ, N_OPT, N_UNDF.
+
+ * buildsym.h (N_UNDF): Improve comments.
+ (N_LSYM, etc): Skip types without names (":T(0,3)=sfoob...").
+
+Sat Jun 13 11:16:45 1992 Fred Fish (fnf at cygnus.com)
+
+ * symtab.h (struct symbol): Add aux_value union for preserving
+ an additional per-symbol value.
+ * symtab.h (SYMBOL_BASEREG, SYMBOL_BASEREG_VALID): Add defines.
+ * frame.h (FRAME_GET_BASEREG_VALUE): Provide default definition.
+ * findvar.c (read_var_value): Use SYMBOL_BASEREG if valid.
+ * printcmd.c (address_info): Use SYMBOL_BASEREG if valid.
+ * symmisc.c (print_symbol): Use SYMBOL_BASEREG if valid.
+
+Sat Jun 13 09:18:46 1992 Michael Tiemann (tiemann@rtl.cygnus.com)
+
+ * symfile.c (clear_symtab_users_once): Now non-static (for
+ objfiles.c).
+
+Fri Jun 12 18:54:40 1992 John Gilmore (gnu at cygnus.com)
+
+ * arm-pinsn.c, i960-pinsn.c, m68k-pinsn.c, mips-pinsn.c,
+ ns32k-pinsn.c, pyr-pinsn.c, sparc-pinsn.c, tahoe-pinsn.c,
+ vax-pinsn.c: Remove reg_names decl (now in defs.h).
+
+ Solaris-2 support on SPARC:
+
+ * dbxread.c: Add symbol_size to struct dbx_symfile_info.
+ Add symbol_size and file offsets to struct symloc.
+ Add static symbol_table_offset, string_table_offset,
+ file_string_table_offset, next_file_string_table_offset,
+ last_function_name.
+ (add_old_header_file): Convert error() to complain()t.
+ (dbx_symfile_read): Get symbol size via the objfile.
+ Also get symbol_table_offset.
+ (dbx_symfile_init): Record symbol size and count via the objfile.
+ (dbx_next_symbol_text): Always add file_string_table_offset when
+ accessing string table.
+ (read_dbx_symtab): Initialize file_string_table_offset to 0.
+ (SET_NAMESTRING): Use the offset.
+ (end_psymtab): Large kludge to determine addresses where source
+ files start and end (for the psymtab header).
+ (psymtab_to_symtab_1): Set file_string_table_offset before reading.
+ Get this, symbol size, and symbol offset, from psymtab.
+ (read_ofile_symtab): Don't back up one symbol for Solaris2.
+ Patch up last_source_start_addr if zero in N_SO.
+ (process_one_symbol): Add variable function_start_offset.
+ ( "", N_FUN, N_LBRAC, N_RBRAC, N_SLINE): Add ifdef for
+ BLOCK_ADDRESS_FUNCTION_RELATIVE.
+ ( "", N_OBJ, N_OPT): Ignore.
+ (elfstab_build_psymtabs): New function to read stabs out of
+ an ELF file.
+
+ * Makefile.in: Accept $(BISON) even though we really want $(YACC).
+ (gdb): use GLOBAL_CFLAGS when linking, too.
+ * partial-stab.h (N_UNDF): Deal with Sol2 relative stringtab offsets.
+ (N_OBJ, N_OPT): Ignore.
+ ('f', 'F'): Save last function name.
+
+ * elfread.c (record_minimal_symbol_and_info): Kludged to put
+ extra info in the minimal symbol.
+ (elf_symtab_read): The extra info is the size of an ELF object,
+ which was kludged to us in the `udata' field of the BFD symbol.
+ Gag me with a crowbar...
+ (elf_symfile_read): Keep track of both the absolute load address,
+ and the offset between load addr and symbols. Handle STABS as
+ well as DWARF sections, passing the absolute load address to
+ elfstab_build_psymtabs.
+
+ * symfile.h: Prototype elfstab_build_psymtabs.
+ * symfile.c: Add almost-OK debug versions of add_psymbol_*to_list.
+
+ * xm-sysv4.h: Add <limits.h> to avoid conflicting defns in defs.h.
+
+ * buildsym.h: Add processing_acc_compilation flag.
+ * buildsym.c (read_sun_builtin_type, read_sun_floating_type): New.
+ (define_symbol): Skip arg types in function entries. Resolve
+ overloaded 'P' which acc uses for prototypes of functions called
+ by this file.
+ (read_type: 'b', 'r'): Handle Solaris2 builtin types.
+
+ * minsyms.c (prim_record_minimal_symbol_and_info): Hack to
+ save size of ELF symbols. FIXME.
+ * tm-sun4os5.h: Rename to tm-sun4sol2.h. Update defines for Sol2.
+ * xm-sun4os5.h: Rename to xm-sun4sol2.h. Hack more defines.
+
+ * configure.in: Solaris config is sparc-sun-solaris2.
+ * config/sun4os5.m[ht]: Rename to config/sun4sol2.m[ht]; new xm, tm.
+
+ * objfiles.c (free_objfile): Eliminate storage leaks. Contributed
+ by <Peter.Schauer@regent.e-technik.tu-muenchen.dbp.de>.
+ * symfile.c (symfile_bfd_open): Comment where name is freed.
+ * symmisc.c (extend_psymbol_list): Comment where list is freed.
+
+Fri Jun 12 08:24:36 1992 Fred Fish (fnf at cygnus.com)
+
+ * expprint.c (print_subexp): Add missing ']'.
+ * defs.h (reg_names): Fix declaration to match that in infcmd.c
+ * stack.c (reg_names): Delete redundant (and inconsistent) decl.
+ * WHATS.NEW: Point out improved C++ function name handling.
+ * gdbtypes.c (lookup_fundamental_type): For now, use the same
+ type names for both implicitly and explicitly signed integral
+ types. See comment in the source code.
+
+Thu Jun 11 12:31:50 1992 John Gilmore (gnu at cygnus.com)
+
+ Two `long long' fixes from Robert R. Henry (rrh@dino.tera.com):
+ * defs.h (longest_to_int): Avoid void arm of ?: in error case.
+ * expprint.c (print_subexp): Fix printing of register names.
+
+Thu Jun 11 01:33:40 1992 John Gilmore (gnu at cygnus.com)
+
+ * inferior.h (register_valid): Declare.
+ * remote-udi.c, rs6000-xdep.c, sparc-xdep.c, tm-rs6000.h: Remove decl.
+ * objfiles.h (ALL_OBJFILE_{SYMTABS,PSYMTABS,MSYMBOLS}): Add
+ macros for traversing the data structures in a single objfile.
+ * tm-m88k.h, tm-sparc.h (REGISTER_NAMES): Remove extra semicolon.
+ * tm-i960.h (REGISTER_NAMES): Cosmetic change.
+ * infcmd.c: Lint.
+
+Tue Jun 9 17:19:45 1992 Fred Fish (fnf at cygnus.com)
+
+ * c-exp.y, m2-exp.y: Move remapping defines for malloc and
+ realloc. Add remapping defines for {yyss, yyssp, yyvs, yyvsp}.
+ * config/{amix.mh, i386v4.mh, ncr3000.mh, stratus.mh,
+ sun4os5.mh}: Add definition for INSTALL using /usr/ucb/install.
+
+Tue Jun 9 16:29:19 1992 Stu Grossman (grossman at cygnus.com)
+
+ * depend: rebuild to account for remote-st2000.c.
+ * remote-st2000.c: Almost works now.
+ * tm-st2000.h: Need to turn on HAVE_68881, else things won't compile.
+
+Mon Jun 8 23:05:51 1992 Fred Fish (fnf@cygnus.com)
+
+ * c-exp.y (yylex): Recognize single-quoted strings that specify
+ tokens with embedded whitespace, such as C++ demangled names.
+ * defs.h (demangle_and_match, strcmp_iw, skip_quoted): Prototypes.
+ * main.c (gdb_completer_quote_characters): Add global variable.
+ * main.c (symbol_completion_function): Total rewrite for C++
+ demangled name handling.
+ * main.c (skip_quoted): New function.
+ * main.c (main): Set rl_completer_quote_characters.
+ * symmisc.c (dump_symtab): Print source language for symtab.
+ * symtab.c (expensive_mangler): Add prototype and function.
+ * symtab.c (completion_list_add_symbol): Total rewrite for new
+ C++ demangled name handling.
+ * symtab.c (lookup_symbol): Check for demangled C++ symbol first,
+ other changes for demangled C++ symbol handling.
+ * symtab.c (lookup_demangled_block_symbol): Use demangle_and_match.
+ * symtab.c (lookup_demangled_partial_symbol): Use demangle_and_match.
+ * symtab.c (decode_line_1): Recognize C++ demangled names on input.
+ * symtab.c (completion_list_add_symbol): Total rewrite for new
+ C++ demangled name handling.
+ * symtab.c (expensive_mangler): New function.
+ * utils.c (strcmp_iw, demangle_and_match): New functions.
+ * xcoffread.c (aixcoff_symfile_read): Fix prototype.
+
+Mon Jun 8 21:59:08 1992 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Roll VERSION to 4.5.4.
+ * Makefile.in, config/*.mh, config/*.mt: Rename TM_CFLAGS
+ to MT_CFLAGS, XM_CFLAGS to MH_CFLAGS to match file names.
+ * config/sun4os5.mh: Add MH_CFLAGS=-xs to save debug info.
+
+Mon Jun 8 14:17:42 1992 Stu Grossman (grossman at cygnus.com)
+
+ * alldeps.mak: Rebuild to account for new files.
+ * config/st2000.mt: Use tm-st2000.h, not tm-68k.h.
+ * tm-st2000.h: New file.
+ * configure.in: Tandem debug monitor (st2000) support.
+ * remote-st2000.c, config/st2000.mt: ditto.
+
+Fri Jun 5 11:51:01 1992 John Gilmore (gnu at cygnus.com)
+
+ * blockframe.c (inside_entry_file, inside_main_func,
+ inside_entry_func): Return 0 if no symbols; avoid crashing.
+
+Wed Jun 3 17:48:04 1992 John Gilmore (gnu@cygnus.com)
+
+ * xcoffread.c (read_xcoff_symtab): Set c_sclass from n_sclass
+ without masking, since it is signed and will later be compared
+ against signed quantities. The right fix is probably to make
+ it all unsigned, but this is a small, safe fix for this release.
+ FIXME -- make the real change sometime soon.
+
+Mon Jun 1 16:16:12 1992 Michael Tiemann (tiemann@cygnus.com)
+
+ * remote-vx.c (vx_load_command,add_symbol_stub): Default READNOW
+ parameter in call to `symbol_file_add' to 0.
+
+ * xm-sun4os4.h (MALLOC_INCOMPATIBLE): Define it.
+
+Sun May 31 06:38:27 1992 Michael Tiemann (tiemann@cygnus.com)
+
+ * configure.in: Handle -m680[01234]0-wrs.
+
+Fri May 29 22:16:02 1992 Michael Tiemann (tiemann@rtl.cygnus.com)
+
+ * m68k-pinsn.c (print_insn_arg): Pass &EXT_FORMAT_68881 to
+ `ieee_extended_to_double'.
+
+Wed May 27 09:27:57 1992 John Gilmore (gnu at cygnus.com)
+
+ * valops.c (value_assign): Lint, by Pierre Willard.
+
+Tue May 19 19:38:10 1992 John Gilmore (gnu at cygnus.com)
+
+ * coredep.c (fetch_core_registers): Remove premature warning,
+ which triggers on DECstation even though all regs are accessible.
+
+ * m68k-pinsn.c (print_insn_arg): Use new macros to get
+ sign-extension of instruction fields even on unsigned-char hosts.
+ Bug found by Fred J Roeber, fjr@sgfb.ssd.ray.com.
+
+ 88K changes inspired by Ted Lemon (uunet!lupine!mellon):
+ * tm-m88k.h, tm-umax.h: Avoid sizeof() in REGISTER_xxx macros,
+ since they define the target, not the host.
+ * m88k-pinsn.c: Fix typo.
+
+Thu May 14 01:16:48 1992 John Gilmore (gnu at cygnus.com)
+
+ * valarith.c (value_zerop): -0.0 is still zero.
+ * eval.c (evaluate_subexp): Avoid NaN anomalies in float compares.
+ Patches by Paul Eggert <eggert@twinsun.com>.
+
+Mon May 18 13:53:51 1992 Stu Grossman (grossman at cygnus.com)
+
+ * alldeps.mak, depend: re-make to account for ser-*.c.
+
+Sun May 17 16:51:20 1992 Fred Fish (fnf@cygnus.com)
+
+ * inflow.c (new_tty): Temporarily ignore SIGTTOU when
+ disconnecting from controlling terminal, to avoid gdb hanging
+ on SVR4. Fixes bug reported by Oliver Okrongli.
+ * procfs.c (PROC_NAME_FMT): Change format to match default used
+ by system, as suggested by Oliver Okrongli.
+ * tm-68k.h (FRAME_FIND_SAVED_REGS): Apply missing parentheses
+ bug fix from Brent Townshend (bst%tt@cam.ORG).
+ * c-exp.y (nonempty_typelist): Fix memory overrun bug reported
+ by turlais@rechser.total.fr.
+ * dwarfread.c (decode_subscr_data): Fix bug in calculation of
+ length of non-zero lowerbound arrays. Bug fix from Peggy Fieland.
+ * objfiles.h (unlink_objfile): Add prototype.
+ * objfiles.c (unlink_objfile): Add function.
+ * objfiles.c (free_objfile): Call unlink_objfile.
+ * objfiles.c (allocate_objfile): Call unlink_objfile on newly
+ remapped objfiles. Bug reported by hahn@sunshine.labs.tek.com.
+ Also, discard old possibly bogus sf struct.
+ * symfile.c (symbol_file_add): Call init_entry_point_info() and
+ find_sym_fns() for remapped symbol files, in case of any changes
+ since the last mapping.
+
+Wed May 13 18:28:20 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * findvar.c (read_relative_register_raw_bytes): use the raw size
+ of a register to bcopy, rather than the host's sizeof(CORE_ADDR).
+
+Tue May 12 17:44:39 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ Changes to support GDB running on DOS using GO32 and H8 support
+
+ * defs.h: if xm.h doesn't define FOPEN_RB, include "fopen-same.h",
+ allowing hosts with different text and binary file formats to
+ work.
+ * coffread.c (read_coff_symtab): changed calling convention and
+ operation - now it opens its own file with FOPEN_RB rather than
+ duping and fdopening the provided handle.
+ * dbxread.c, cplus-dem.c: #include mangling.
+ * exec.c: If O_BINARY isn't defined, set it to 0, call openp for
+ binary files oring in the right bit.
+ * utils.c, terminal.h, inflow.c: hackery because dos doesn't have terminals.
+ * remote-hms.c: cleanup to use the new remote serial stuff
+ * serial.h, ser-termios.c, ser-go32.c: newfiles to provide host
+ independent remote terminal I/O.
+ * remote.c: if DONT_USE_REMOTE not defined, then don't use it.
+ * source.c (openp): fix off by one problem removing / - can now
+ open a source file in the root directory with DOS.
+ * values.c (value_as_pointer): remove bogus address bits from
+ long. (unpack_long): unpack into unsigned long/short if pointer.
+
+Tue May 12 14:15:48 1992 Stu Grossman (grossman at cygnus.com)
+
+ * infrun.c (child_attach): Don't allow gdb to attach to itself.
+ It gets permanently stuck in many OSes.
+ * breakpoint.c, infcmd.c, infrun.c, utils.c: Change many printfs
+ to printf_filtered.
+ * breakpoint.c: Improve help text for info breakpoints.
+
+Mon May 11 14:17:18 1992 John Gilmore (gnu at cygnus.com)
+
+ * README: Add pointer to internals doc, and describe reading
+ info files.
+ * utils.c (print_sys_errmsg): Use stderr. Reported by Pierre Willard.
+ * symtab.c (output_source_filename): Remove old glop for wrapping
+ lines, use wrap_here. Reported by Pierre Willard (pierre@la.tce.com).
+
+Thu May 7 11:45:03 1992 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: version.c should depend on Makefile, not Makefile.in.
+ * munch: Add sort -u to avoid duplications.
+ * symtab.c (lookup_symbol): Improve Stu's fix of 22 April.
+ Improved fix by hahn@sunshine.labs.tek.com (Doug Hahn).
+
+Mon May 11 13:27:46 1992 Fred Fish (fnf@cygnus.com)
+
+ * cplus-dem.c (demangle_signature): Recognize misplaced '_' to
+ avoid infinite loops while demangling bogus mangled names.
+ * valprint.c (type_print_base): Minor fix for GNU style guide
+ conformance.
+
+Sat May 9 18:02:17 1992 Fred Fish (fnf at fishpond)
+
+ * Makefile.in (VERSION): Bump to 4.5.3
+ * Makefile.in (DEMANGLE_OPTS): Remove obsolete -Dnounderscore
+ * Makefile.in (demangle): New target to create standalone
+ demangler with same code and options as internal demangler.
+ * cplus-dem.c: Massive restructuring, rewriting, cleanups, etc
+ to support ARM style and Lucid style demangling, improve
+ maintainability, fix several demangling bugs. More changes
+ to follow.
+ * defs.h (strstr): Add ANSI compatible prototype.
+ * valprint.c (type_print_1): Demangle using ansi option.
+ * config/ncr3000.mt (DEMANGLE_OPTS): Remove -Dnounderscore.
+
+Sat May 9 14:47:28 1992 Stu Grossman (grossman at cygnus.com)
+
+ * xcoffexec.c (vmap_exec): Don't assume .text and .data are the
+ first two sections.
+
+Fri May 8 11:42:15 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * mipsread.c (parse_procedure): Return rather than using
+ uninitialized variable 'b'.
+
+Fri May 8 07:48:27 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in, remote-udi.c, remote-vx.c, 29k-share/dfe/mini2udi.c,
+ 29k-share/dfe/yank.c, vx-share/xdr_ptrace.c, vx-share/xdr_regs.c:
+ Remove -I29k-share, -Ivx-share from Makefile.in. Make #includes
+ relative to each source file.
+
+Fri May 8 07:48:27 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: propogate INSTALL, INSTALL_DATA, INSTALL_PROGRAM on
+ recursions.
+
+Thu May 7 10:00:52 1992 Stu Grossman (grossman at cygnus.com)
+
+ * am29k-pinsn.c: Use new opcode table in "opcode/a29k.h".
+ * am29k-tdep.c: Update to latest code from AMD.
+ (get_saved_register) don't crap out if no frame.
+ * remote-udi.c: Set/clear inferior_pid as appropriate.
+ (udi_open) call target_preopen, don't close fd 0!!!, clean up
+ error handling. Fixup end-of-debugging messages.
+ (udi_fetch_registers) clean up big time, mainly don't multiply
+ register_valid indices by 4, and use proper Offset when reading
+ gr96-gr127. (udi_store_registers) general cleanup.
+ (fetch_register) cleanup, simplify. (regnum_to_srnum)
+ INT_REGNUM->INTE_REGNUM.
+ * tm-29k.h: Upgrade to latest code from AMD.
+ * 29k-share/udi/udip2soc.c: Get rid of useless errmsg_m macro.
+ (UDIConnect) Clean up error processing (like, don't do exit() if
+ execlp fails), make code restartable, make more attractive.
+ (UDIStop) Use SIGINT instead of SIGUSR1, as isstip won't stop
+ otherwise.
+
+Wed May 6 14:34:18 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * tm-irix3.h: Re-define CPLUS_MARKER to '.'.
+ * xm-rs6000.h, tm-rs6000.h: Move re-definition of CPLUS_MARKER
+ from former to latter.
+
+Wed May 6 14:12:35 1992 Fred Fish (fnf@cygnus.com)
+
+ * cplus-dem.c (do_args): Handle void args the same as others.
+ * objfiles.c (free_objfile): Only try to unmap files when
+ reusable objfiles are supported.
+ * valprint.c (type_print_varspec_suffix): Add parameter that
+ specifies if C++ demangling included function arguments. Use
+ it to suppress printing extra pair of ()'s.
+ * valprint.c (type_print_1): Fix problem with printing demangled
+ C++ function types where demangled type includes the function
+ args.
+
+Tue May 5 11:10:27 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (DEMANGLER): Define and default to cplus-dem.
+ Allows selection of C++ demangler to be a configuration option
+ until multiple demanglers are supported.
+ * demangle.h: New include file for extended demangler support.
+ * breakpoint.c, gdbtypes.c, printcmd.c, stack.c, symtab.c,
+ utils.c, valprint.c: Include "demangle.h" and change all calls
+ to cplus_demangle() or fputs_demangled() to use individual
+ demangling options.
+ * valprint.c (type_print_1): Change options to cplus_demangle
+ to print demangled function args. Still broken, but now less so.
+ * cplus-dem.c: Include demangle.h, reorganize and update some
+ comments to reflect reality.
+ * cplus-dem.c (cplus_demangle, cplus_mangle_opname): Change
+ second arg from fixed integer to bit based multiple options.
+ * cplus-dem.c (optable): Reformat and replace ansi members with
+ bit based options.
+ * cplus-dem.c (do_type): Fix bug with parsing missing return type.
+
+Mon May 4 22:26:59 1992 John Gilmore (gnu at cygnus.com)
+
+ * values.c (set_internalvar): Force evaluation of lazy values.
+ Bug reported by RMS.
+
+Sun May 3 15:47:45 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.5.2.
+ * Makefile.in (DEMANGLE_OPTS): Add, default to -Dnounderscore.
+ * configure.in: Simplify ncr3000 gdb_host logic, add gdb_target.
+ * dwarfread.c (struct_type): Apply fix from Peggy Fieland for
+ proper handling of bit fields.
+ * gdbtypes.h (struct type): Clarify use of field.bitpos.
+ * symtab.h: Fix couple of misspellings in comments.
+ * value.h (struct value): Clarify use of bitpos.
+ * value.h (unpack_field_as_long): Change prototype, returns
+ LONGEST.
+ * values.c (unpack_field_as_long): Change return type to LONGEST,
+ sign extend unpacked fields that are signed, other rewriting.
+ * config/ncr3000.mt: New target config file.
+
+Fri May 1 01:53:26 1992 John Gilmore (gnu at cygnus.com)
+
+ * utils.c (printchar): Print 0x7F and 0x80-0x9F in \nnn notation
+ even when printing 8-bit characters.
+
+ * gdbtypes.c (make_{reference,pointer,function}_type): New
+ functions which handle overwriting of forward-referenced types
+ for stabs file reading.
+ (lookup_{reference,pointer,function}_type): These just call
+ the make_*_type functions with a null storage alloc parameter.
+ * gdbtypes.h (make_{reference,pointer,function}_type): Declare.
+ * xcoffread.c (smash_to_pointer_type): Remove, no longer used.
+
+ * buildsym.c (dbx_lookup_type): Zero result for (-1,-1) arg.
+ (dbx_alloc_type): Make it easier to understand. No funct change.
+ (define_symbol: 't'): Don't put the typedef name into the name of
+ the struct, union, or enum. Bugfix.
+ (read_type: '*', '&', 'f'): Add comments. Use make_XXX_type
+ routines to properly handle overwriting preallocated types so that
+ forward references will work.
+ (read_enum_type): Force enum values to file scope, due to bug in
+ Sun compiler output. FIXME, fix later.
+
+ Remove unused header_file_prev_index mechanism. It was already
+ obsolete in gdb-3.5. These comments appeared in 3.5:
+ /* This code was used before I knew about the instance codes.
+ My first hypothesis is that it is not necessary now
+ that instance codes are handled. */
+ * dbxread.c (add_new_header_file): Remove header_file_prev_index.
+ * buildsym.h: Remove it and prev_index that saves it.
+ * buildsym.c (push_subfile, pop_subfile, start_symtab): Remove it.
+
+ * solib.c (special_symbol_handling): When called from core files,
+ must set up debug_addr. Don't print error messages, just return.
+ * symmisc.c (print_symbol): Less ascii diarrhea for enums, please.
+
+Wed Apr 29 15:26:51 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * cplus-dem.c: Allow nested class names (as in
+ Foo::Bar::method()).
+ Allow the cleaner cfront style of nested class names
+ (Q2_3Foo3Bar as well as Q23Foo3Bar).
+ Make cplus_demangle re-entrant by removing use of global
+ variables. Instead, place all shared variables in a
+ stack-allocated structure, and pass around its address.
+
+Fri Apr 24 07:41:19 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (make-proto-gdb-1): 1st cut at packaging
+ 29k-share/* subdirs...
+
+ * remote-udi.c (udi_insert/remove_breakpoint): Completely
+ rewrite, only leave out the bugs.
+
+ * Makefile.in: Add 29k/UDI support. Improve depend.
+ * alldeps.mak, configure.in, depend: Add 29k/UDI support.
+
+ * am29k-tdep.c: Update to use new calling conventions, and misc
+ symbol elements.
+
+ * m68k-pinsn.c (print_insn_arg): Make branch offsets be signed.
+
+Thu Apr 23 18:43:17 1992 Fred Fish (fnf@cygnus.com)
+
+ * tm-29k.h: Set DECR_PC_AFTER_BREAK to 0, as 29ks have nice
+ breakpoint instructions that leave PC pointing at the right place.
+
+ * core.c (core_open): Call warning() to print warnings.
+
+Wed Apr 22 09:55:42 1992 Stu Grossman (grossman at cygnus.com)
+
+ * symtab.c (lookup_symbol): Need to check if msymbol->name is
+ NULL, as ALL_MSYMBOLS will never return a NULL msymbol pointer.
+ This prevents a crash when trying to lookup the value of a
+ non-existent symbol.
+
+Wed Apr 22 09:42:15 1992 Fred Fish (fnf@cygnus.com)
+
+ * signame.c, signame.h: Remove, replaced by strsignal.c in
+ libiberty.
+ * i960-tdep.c, infrun.c, mach386-xdep.c, procfs.c, sparc-tdep.c,
+ sun386-xdep.c: Remove include of signame.h
+ * Makefile.in (SFILES_MAINDIR): Remove signame.c
+ * Makefile.in (HFILES): Remove signame.h
+ * Makefile.in (OBS): Remove signame.o
+ * defs.h (safe_strerror, safe_strsignal, strerrno, strsigno,
+ errno_max, signo_max, strtoerrno, strtosigno, strsignal,
+ psignal, perror): Add prototypes.
+ * defs.h, xm-apollo68v.h, xm-ultra3.h (SYS_SIGLIST_MISSING):
+ Remove define.
+ * depend: Manually remove signame.[cho] references.
+ * convex-tdep.c (subsig_name): Replace use of sys_siglist with
+ strsignal.
+ * convex-xdep.c (core_file_command): Replace use of sys_siglist
+ with safe_strsignal.
+ * core.c (core_open): Replace use of sys_siglist with
+ safe_strsignal.
+ * core.c (memory_error): Replace use of sys_errlist with
+ safe_strerror.
+ * i960-tdep.c (print_fault): Replace use of sys_siglist with
+ safe_strsignal.
+ * infcmd.c (program_info): Replace use of sys_siglist with
+ safe_strsignal.
+ * infrun.c (signal_stop, signal_print, signal_program):
+ Allocate dynamically based on dynamic determination of number
+ of signals to support.
+ * infrun.c (child_create_inferior): Replace use of sys_errlist
+ with safe_strerror.
+ * infrun.c (wait_for_inferior): Replace use of sys_siglist with
+ safe_strsignal.
+ * infrun.c (sig_print_info): Replace use of sig_abbrev with
+ strsigno and sys_siglist with safe_strsignal.
+ * infrun.c (handle_command): Call signo_max to find number of
+ signals. Replace sig_number with strtosigno and sig_abbrev with
+ strsigno.
+ * infrun.c (signals_info): Replace sig_number with strtosigno.
+ * infrun.c (_initialize_infrun): Call signo_max to find number of
+ signals. Dynamically allocate signal_{stop,print,program}.
+ * procfs.c (errno_table): Remove, now in libiberty/strerror.c.
+ * procfs.c (errnoname): Add function and prototype.
+ * procfs.c (info_proc_siginfo): Call errnoname, replace use
+ of sys_siglist with safe_strsignal.
+ * procfs.c (info_proc_stop, info_proc_signals): Replace use of
+ sys_siglist with safe_strsignal.
+ * procfs.c (info_proc_stop): Call errnoname.
+ * procfs.c (signalname): Replace sig_abbrev with strsigno.
+ * stuff.c (main, get_offset): Replace use of sys_errlist with
+ strerror.
+ * sun386-xdep.c (core_file_command): Replace use of sys_siglist
+ with safe_strsignal.
+ * umax-xdep.c (core_file_command): Replace use of sys_siglist
+ with safe_strsignal.
+ * utils.c (safe_strerror, safe_strsignal): Add functions that
+ call strerror and strsignal respectively, and deal with NULL
+ returns.
+ * utils.c (perror_with_name, print_sys_errmsg): Replace use of
+ sys_errlist with safe_strerror.
+ * valprint.c (val_print): Replace use of sys_errlist with
+ safe_strerror.
+
+Tue Apr 21 12:00:47 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: rework CFLAGS so that they can be set from the
+ command line to make. CFLAGS -> INTERNAL_CFLAGS.
+ USER_CFLAGS -> CFLAGS. Remove MINUS_G. Default CFLAGS to -g.
+ Pass CFLAGS on recusions.
+
+Fri Apr 17 19:25:57 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdbtypes.h, c-exp.y, m2-exp.y, mipsread.c, gdbtypes.c: Back
+ out of change on 4/14/92 and remove TYPE_FLAG_FUND_TYPE. It was
+ overkill for the problem it solved.
+ * valprint.c (type_print_base): Remove TYPE_FLAG_FUND_TYPE test
+ and default to simply printing type names as appropriate.
+ * main.c (main): Remove one of the leading newlines from
+ warning_pre_print initialization.
+ * objfiles.c (open_existing_mapped_file): Add function and
+ prototype.
+ * objfiles.c (open_mapped_file): Rewrite to use new function
+ open_existing_mapped_file.
+
+Thu Apr 16 23:50:12 1992 John Gilmore (gnu at cygnus.com)
+
+ * sun3-xdep.c (fetch_core_registers): Lint.
+ * tm-sun3.h: Prototype lint.
+ * value.h: Typo.
+
+Thu Apr 16 19:56:50 1992 Fred Fish (fnf@cygnus.com)
+
+ * dwarfread.c (TARGET_FT_POINTER_SIZE, TARGET_FT_LONG_SIZE):
+ Define using TARGET_PTR_BIT and TARGET_LONG_BIT for now.
+ * objfiles.c: Cast calls to close() with unused returns to void.
+ * objfiles.c (allocate_objfile): Initialize objfile's mmfd, free
+ old objfile's name before updating it.
+ * objfiles.c (free_objfile): Major rewrite for mapped objfiles.
+ * objfiles.h (objfile struct): Add mmfd member.
+ * symfile.c (syms_from_objfile): Move some code to
+ new_symfile_objfile.
+ * symfile.c (new_symfile_objfile): Add new function, common code
+ from syms_from_objfile.
+ * symfile.c (symbol_file_add): Call new_symfile_objfile for both
+ mapped and unmapped symbol files.
+ * symfile.c (symbol_file_command): Print "No symbol file now"
+ message, ala exec_file_command for the exec file.
+ * symfile.h (new_symfile_objfile): Add prototype.
+ * xcoffexec.c (map_vmap): Add call to new_symfile_objfile.
+ * xcoffsolib.c (solib_add): Add call to new_symfile_objfile.
+
+Thu Apr 16 18:26:34 1992 Per Bothner (bothner@cygnus.com)
+
+ * rs6000-pinsn.c: New version from IBM (Metin).
+ * m2-exp.y: Re-write string initializers ("<>" => {'<', '>'})
+ to avoid warnings from some compilers.
+
+Tue Apr 14 22:33:55 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdbtypes.h (FT_FIXED_DECIMAL, FT_FLOAT_DECIMAL): Add defines.
+ * gdbtypes.h (TYPE_FLAG_FUND_TYPE): Add define for bit in a
+ type's flag word that marks it as a fundamental type.
+ * c-exp.y (_initialize_c_exp): Add TYPE_FLAG_FUND_TYPE bit to
+ flags argument for all calls to init_type().
+ * m2-exp.y (_initialize_m2_exp): Add TYPE_FLAG_FUND_TYPE bit to
+ flags argument for all calls to init_type(). Also remove
+ dependency on host sizes for ints, floats, etc.
+ * mipsread.c (_initialize_mipsread): Add TYPE_FLAG_FUND_TYPE bit to
+ flags argument for all calls to init_type(). Also remove
+ dependency on host sizes for ints, floats, etc.
+ * gdbtypes.c (lookup_fundamental_type): Add TYPE_FLAG_FUND_TYPE
+ bit to flags argument for all calls to init_type(). Add types
+ FT_FIXED_DECIMAL and FT_FLOAT_DECIMAL.
+ * valprint.c (unsigned_type_table, signed_type_table,
+ float_type_table): Remove.
+ * valprint.c (type_print_base): Test new TYPE_FLAG_FUND_TYPE
+ bit when printing fundamental types, and print the actual name
+ for such types, rather than inventing one. Remove code that
+ invented fundamental type names.
+ * valprint.c (_initialize_valprint): Remove initializations
+ for now removed unsigned_type_table, signed_type_table, and
+ float_type_table.
+
+Tue Apr 14 14:30:46 1992 Stu Grossman (grossman at cygnus.com)
+
+ * remote-vx.c, vx-share/xdr_ptrace.c, vx-share/xdr_ptrace.h,
+ vx-share/xdr_rdb.h: Update for new remote protocol under VxWorks
+ 5.0.2.
+
+Mon Apr 13 20:59:21 1992 Fred Fish (fnf@cygnus.com)
+
+ * dwarfread.c (target_to_host): New function similar to previous
+ swapin function.
+ * dwarfread.c (SWAPIN, swapin): Remove macro and support function.
+ Extensive changes to convert all previous usages to use new
+ target_to_host() function.
+ * dwarfread.c (struct dieinfo): Change types of most integral
+ members to be unsigned.
+
+Mon Apr 13 15:59:10 1992 John Gilmore (gnu at cygnus.com)
+
+ * WHATS.NEW: Revise -mapped doc.
+
+Sat Apr 11 23:14:36 1992 John Gilmore (gnu at cygnus.com)
+
+ * mipsread.c (parse_partial_symbols): Complain when sh->index is
+ too high or when skipping `forwards' moves us backwards.
+ (parse_type): Print mis-guessed tag name in complaint.
+ (parse_external): Eliminate cur_stab and obscure top_stack clobbers.
+ (parse_procedure): Do not attempt to create symbols; just fill in
+ the SYMBOL_VALUE field of a .gdbinfo. symbol if we can find one.
+ (psymtab_to_symtab_1): Split up `stabs' from `native ecoff' code
+ for clarity. Set top_stack before calling parse_external. In
+ stabs, sort symbols before calling parse_procedure.
+ * mipsread.c: Lint.
+ * symmisc.c (std_in, std_out, std_err): Add vars to access std
+ FILE *'s when debugging GDB (e.g. as args to dump_symtab).
+ * Makefile.in: Remove stage* targets. Avoid echo on recursive
+ makes. Eliminate doc/Makefile from tar.Z file if doc/Makefile.in
+ exists.
+
+Fri Apr 10 23:47:37 1992 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in (VERSION): Set to 4.5.1.
+ * xcoffread.c (NO_TYPEDEFS): Fix typo in commented-out #define.
+ * sparc-tdep.c (supply_gregset, fill_gregset, supply_fpregset,
+ fill_gregset): New functions for SVR4 /proc support.
+ * mipsread.c: Cleanup. Add more complaints for unhandled cases.
+ Remove new symbol types and such to ../include/coff/symconst.h.
+ (parse_symbol): Simplify code for parsing struct/enum/unions.
+ (parse_type): Handle `long long' types.
+ (upgrade_type): Handle `const' qualifier.
+ (parse_partial_symbols): fix indentation, clean a bit.
+
+Fri Apr 10 22:41:03 1992 Fred Fish (fnf@cygnus.com)
+
+ * dwarfread.c (SWAPIN,swapin): New macro and function to call to
+ copy in data from raw read buffers, calling bfd byteswapping
+ routines as appropriate. Use to replace most existing memcpy
+ calls.
+ * dwarfread.c (basicdieinfo, completedieinfo): Add objfile arg.
+ * configure.in: Recognize new ncr3000 config.
+ * config/ncr3000.mh: New config file.
+
+Fri Apr 10 08:30:58 1992 Stu Grossman (grossman at cygnus.com)
+
+ GDB-4.5 release!
+
+ * README: Update for release.
+ * Makefile.in: Update version to 4.5.
+ * WHATS.NEW: The obvious.
+
+ * depend: Generate new depend file for this release.
+
+ * Makefile.in (depend): Fix dependancy generation so that it does
+ not include gcc 'fixincluded' files, which are usually in a system
+ specific location.
+
+Thu Apr 9 13:35:00 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ Changes from metin@ibmpa.awdpa.ibm.com (Metin G. Ozisik).
+ * buildsym.c (#ifdef RS6000_TARGET): Don't create unnecessary
+ symbols for nameless types. And, handle `R' (register parameter
+ type) for AIX. (an extension to existing stabstring grammar).
+ * rs6000-xdep.c: Fix typo (= should have been ==).
+
+Thu Apr 9 12:10:06 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in: version=4.4.88, add xm-vax.h to HFILES.
+
+Thu Apr 9 02:29:03 1992 John Gilmore (gnu at cygnus.com)
+
+ * xm-sun4os5.h (DO_DEFERRED_STORES, CLEAR_DEFERRED_STORES): Zap.
+ * signame.c (SIGWAITING, SIGLWP): Add.
+
+Tue Apr 7 16:34:07 1992 Per Bothner (bothner@cygnus.com)
+
+ * xm-i386mach.h: add decls for errno and strdup().
+
+ * breakpoint.c (breakpoint_1): Add (int) casts for enums
+ used in array index context (otherwise, some compilers barf).
+
+Tue Apr 7 08:45:46 1992 Stu Grossman (grossman at cygnus.com)
+
+ * m68k-tdep.c, tm-sun3.h: #ifdef around get_longjmp_target().
+ Change def of SAVED_PC_AFTER_CALL to call routine to see if we are
+ in a system call, and provide better backtrace if so.
+
+ * Makefile.in (HFILES): Add xcoffsolib.h.
+ * rs6k-opcode.h: Move to ../include/opcode/rs6k.h.
+ * rs6000-pinsn.c: #include "opcode/rs6k.h"
+
+ * mipsread.c (read_mips_symtab, read_the_mips_symtab,
+ mipscoff_symfile_read): Convert to BFD to do file I/O.
+
+ * symfile.c: #include <ctype.h> to get proper def if isspace().
+
+ * i386-tdep.c (get_longjmp_target): #ifdef GET_LONGJMP_TARGET.
+
+Mon Apr 6 17:25:45 1992 Per Bothner (bothner@cygnus.com)
+
+ * mipsread.c: Create a .gdbinfo pseudo-symbol for each
+ function also when parsing embedded stabs.
+
+Mon Apr 6 15:25:03 1992 Stu Grossman (grossman at cygnus.com)
+
+ * mipsread.c: Fix more declarations.
+
+ * mipsread.c: Fix many invocations of complain. Use enum
+ type_code where appropriate.
+
+ * xm-vaxult.h: Add decl for strdup().
+
+ * Makefile.in: Add dependancies for xm-vaxbsd.h and xm-vaxult.h
+ for xm-vax.h.
+
+Fri Apr 3 17:41:29 1992 Stu Grossman (grossman at cygnus.com)
+
+ * buildsym.h, dbxread.c, mipsread.c: Add objfile arg to
+ process_one_symbol.
+
+Fri Apr 3 12:17:14 1992 Per Bothner (bothner@cygnus.com)
+
+ * munch: Must pre-pend "_" to "initialize" for SYSV style nm.
+ * tm-rs6000.h, xcoffexec.c, xcoffread.c, xm-rs6000.h:
+ Merge in more patches for rs6000 from Metin Ozisik.
+ * utils.c: Fix typo in comment.
+
+Fri Apr 3 11:23:03 1992 Fred Fish (fnf@cygnus.com)
+
+ * procfs.c (procinfo struct): Add nopass_next_sigstop member.
+ * procfs.c (attach): Set nopass_next_sigstop if attached
+ process is forcibly stopped.
+ * procfs.c (child_resume): Use nopass_next_sigstop to suppress
+ resending SIGSTOP to attached process on first resume.
+
+Fri Apr 3 01:37:26 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (SFILES_MAINDIR): add mipsread.c
+
+Thu Apr 2 20:20:54 1992 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in (OBS): Compile mipsread.c for all targets now.
+ (VERSION): Bump to 4.4.85.
+ * mipsread.c: Update for new include files. Lint.
+ * tm-irix3.h, tm-mips.h: Use new include files for ECOFF symtab.
+ * config/{bigmips.mt, littlemips.mt, irix3.mt, decstation.mt}:
+ Don't need to bring in mipsread.o specially any more.
+
+Thu Apr 2 19:38:31 1992 Stu Grossman (grossman at cygnus.com)
+
+ * mipsread.c (fixup_sigtramp): Also look for _sigtramp as a real
+ routine (for Irix-4.x). Make many funcs static and void.
+ * mips-tdep.c (mips-frame-chain): Clean up, simplify.
+ * (init_extra_frame_info): Don't trash cached value of frame
+ pointer register. This fixes backtracing through routines that use
+ alloca(). Generally clean up declarations of functions, and use
+ typedefs and macros to reference data structures as appropriate.
+ * tm-irix3.h, tm-mips.h (EXTRA_FRAME_INFO): use proper type for
+ proc_desc element.
+
+Thu Apr 2 09:47:11 1992 Fred Fish (fnf@cygnus.com)
+
+ * values.c (unpack_long): Fix unpacking error for signed chars
+ on hosts where the default character type is unsigned.
+ * procfs.c (pr_flag_table, pr_why_table): Add some entries
+ for newer SVR4 variants.
+ * procfs.c (proc_set_exec_trap): Reorder tests for ioctl's that
+ turn off trace inherit-on-fork flag to favor latest SVR4 method.
+ * procfs.c (mappingflags): Add support for MA_PHYS
+
+Thu Apr 2 00:55:56 1992 John Gilmore (gnu at cygnus.com)
+
+ * buildsym.c (read_struct_type): Avoid coredump when C++
+ abbreviated type name is messed up. Reported by Joe Buck.
+ FIXME, we need to determine whether GDB or GCC needs to be
+ smarter to correctly locate this type name.
+
+ * c-exp.y, coffread.c, command.c, command.h, copying.awk,
+ dbxread.c, gdbtypes.c, infcmd.c, inferior.h, infrun.c,
+ m2-exp.y, printcmd.c, remote.c, solib.c, source.c, stack.c,
+ symtab.c, tm-sun4os4.h, tm-sun4os5.h, values.c: Lint.
+ * symfile.c (add_symbol_file_command): Initialize mapped/readnow.
+
+Wed Apr 1 11:39:52 1992 Fred Fish (fnf@cygnus.com)
+
+ * breakpoint.h (bpdisp, bptype): Remove trailing comma.
+ * symtab.h (current_source_symtab): Make extern
+ * symtab.h (current_source_line): Make extern
+ * inferior.h: Move all procfs.c prototypes to one place, add
+ prototype for proc_signal_handling_change. Add prototypes for
+ signal_stop_state, signal_print_state, and signal_pass_state.
+ * inferior.h (stop_soon_quietly): Make extern
+ * inferior.h (attach_flag): Make extern
+ * infrun.c (NOTICE_SIGNAL_HANDLING_CHANGE): Default is null.
+ * infrun.c (signal_stop_state, signal_print_state,
+ signal_pass_state): New functions to query specific signal
+ handling flags.
+ * infrun.c (handle_command): Minor error message change, add
+ NOTICE_SIGNAL_HANDLING_CHANGE.
+ * procfs.c (open_proc_file): Remove iris specific reset of
+ inherit-on-fork flag, moved to proc_set_exec_trap().
+ * procfs.c (proc_set_exec_trap): Add SVR4 and iris code
+ to reset inherit-on-fork flag, bash comment to GNU form.
+ * procfs.c (proc_base_address, set_proc_siginfo,
+ fetch_core_registers): Conform to code style.
+ * procfs.c (signame.h): Include.
+ * procfs.c (MAX_SYSCALLS, syscall_table[], init_syscalltable(),
+ syscallname(), info_proc_syscalls()): New macros, tables, and
+ functions to organize and report system call information.
+ * procfs.c (saved_fltset, saved_trace, saved_sighold,
+ saved_exitset, saved_entryset): Add to procinfo struct.
+ * procfs.c (struct trans): Add.
+ * procfs.c (pr_flag_table, pr_why_table, faults_table,
+ siginfo_table, errno_table): Tables to translate numeric values
+ to symbolic names and short descriptions.
+ * procfs.c (signalname, info_proc_signals): Add function and
+ prototype.
+ * procfs.c (proc_info): Now info_proc.
+ * procfs.c (proc_info_address_map): Now info_proc_mappings.
+ * procfs.c (info_proc_flags, info_proc_stop, info_proc_siginfo,
+ info_proc_faults, lookupname, lookupdesc, sigcodename,
+ sigcodedesc): New functions.
+ * procfs.c (proc_signal_handling_change): New function to set
+ the trace flags based on the state of gdb's signal handling flags.
+ * procfs.c (inferior_proc_init): Call proc_signal_handling_change
+ and remove code to do PIOCSTRACE ioctl.
+ * procfs.c (attach, detach): Preserve and restore process flags
+ using saved_* fields in procinfo struct.
+ * procfs.c (attach): Call proc_signal_handling_change.
+ * procfs.c (info_proc): Major rework to expand "info proc" cmd.
+ * procfs.c (proc_desc): Update for latest changes.
+ * xm-irix4.h (CREATE_INFERIOR_HOOK): Protect by USE_PROC_FS.
+ * xm-irix4.h (NOTICE_SIGNAL_HANDLING_CHANGE): Add definition.
+ * xm-sysv4.h (NOTICE_SIGNAL_HANDLING_CHANGE): Add definition.
+
+Tue Mar 31 18:38:28 1992 Fred Fish (fnf@cygnus.com)
+
+ * procfs.c (set_proc_siginfo): Add prototype and new function.
+ * procfs.c (detach, child_resume): Call set_proc_siginfo to set
+ up inferior siginfo struct.
+ * elfread.c (elf_symfile_read): Compute the relocation amount
+ by subtracting off the address of the ".text" section.
+ * solib.c: Add pointer to ".text" section to so_list struct.
+ * solib.c (solib_map_sections): Initialize pointer to ".text"
+ section in so_list struct.
+ * solib.c (symbol_add_stub): Pass base address of ".text"
+ section to symbol_file_add, rather than the load address of
+ the shared library. On SunOS they are the same. On SVR4 they
+ are not.
+
+Tue Mar 31 17:48:15 1992 Stu Grossman (grossman at cygnus.com)
+
+ * mipsread.c (parse_procedure): PDR.isym should get pointer to
+ function name, not .gdbinfo. symbol.
+
+Tue Mar 31 17:05:04 1992 John Gilmore (gnu at cygnus.com)
+
+ * breakpoint.c (breakpoint_1): Fix prototype, this time for sure!
+
+Tue Mar 31 11:01:06 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (VERSION): 4.4.8
+
+ * procfs.c (open_proc_file): Disable inherit-on-fork flag so that
+ commands in .cshrc/.profile won't get traced.
+
+Tue Mar 31 08:11:58 1992 John Gilmore (gnu at cygnus.com)
+
+ * elfread.c (elf_symtab_read): Use xmalloc, not bfd_xmalloc.
+ * exec.c (build_section_table): Don't abort if no sections.
+ * sparc-tdep.c (single_step): Lint.
+ * utils.c (mrealloc): Handle realloc (0, size) case here.
+
+Mon Mar 30 16:50:43 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (alldeps.mak): Config files are now *.m[ht] as
+ opposed to m[ht]-*!
+
+ * config/irix4.mh: Don't use coredep.o. It doesn't work with procfs.
+
+ * mipsread.c (parse_symbol, parse_procedure): Re-do the way that
+ .gdbinfo. symbols are created. Move creation from parse_procedure
+ to parse_symbol, where it is fairly easy to grow the symtab. This
+ also fixes a symtab trashing bug on all mips-based systems.
+ * (got_numargs, lookup_numargs, free_numargs): Delete. Not
+ needed anymore.
+ * tm-mips.h, tm-iris3.h, mips-tdep.c, mipsread.c: Re-do struct
+ mips_extra_func_info, and all the PROC_xxx macros that look at it.
+
+Mon Mar 30 14:17:53 1992 Per Bothner (bothner@cygnus.com)
+
+ * c-exp.y: Add missing return type to yyparse() prototype.
+
+Sat Mar 28 22:22:06 1992 John Gilmore (gnu at cygnus.com)
+
+ Create and use macros for iterating on symtabs, psymtabs, msymbols.
+
+ * minsyms.c (iterate_over_msymbols): Remove; clunky and slow.
+ * symfile.h, symtab.h (iterate_over_msymbols): Remove prototype
+ * coffread.c (coff_symfile_read): iterate_over_symtabs => ALL_SYMTABS.
+ (patch_opaque_types): Avoid dummy args and result.
+ * objfiles.c (have_partial_symbols, have_full_symbols,
+ have_minimal_symbols): explicit iteration => ALL_OBJFILES; simplify.
+ (iterate_over_objfiles, iterate_over_symtabs,
+ iterate_over_psymtabs): Remove, clunky and slow.
+ * objfiles.h: Replace iterate_over_* prototypes with ALL_SYMTABS,
+ ALL_PSYMTABS, and ALL_MSYMBOLS macros.
+ * symmisc.c (dump_symtab, dump_psymtab, dump_msymbols,
+ dump_objfile): Remove dummy args and results. Move filename
+ comparisons to callers.
+ (printsyms_command, printpsyms_command, printmsyms_command,
+ printobjfiles_command): iterate_over_* => ALL_*. Compare filenames.
+ * symtab.c (lookup_symtab_1, lookup_symtab, lookup_partial_symtab,
+ lookup_symbol, find_main_psymtab, find_pc_symtab, sources_info,
+ list_symbols, make_symbol_completion_list): Replace explicit
+ iteration with ALL_SYMTABS, ALL_PSYMTABS, or ALL_MSYMBOLS.
+ Eliminate Dijkstra flag crap, break out of loops with gotos.
+ (lookup_symtab_1): Protect '/' tests from short filenames.
+ (cplus_mangled_symbol): Move inline into lookup_symbol.
+ * xcoffexec.c (relocate_objfile_msymbols): Remove poor hack.
+ (relocate_minimal_symbol): Move inline to vmap_symtab.
+ (vmap_symtab): Replace iteration with ALL_OBJFILES,
+ iterate_over_msymbols with ALL_MSYMBOLS.
+
+ Misc cleanup prior to release.
+
+ * Makefile.in (VERSION): Roll to 4.4.7.
+ (HFILES): Add call-cmds.h.
+ * call-cmds.h: New header for command fns called by other files.
+ * breakpoint.c (watchpoints_info): Remove, same as breakpoints_info.
+ (breakpoint_1): Remove unused type arg. Change callers.
+
+ * dwarfread.c (dwarf_build_psymtabs): Remove mainline test.
+ * mipsread.c (compare_symtabs, compare_psymtabs): Remove, unused.
+ * mipsread.c: Add prototypes for all static functions.
+
+ * symmisc.c (dump_symtab_lines, dump_symtabs, dump_last_symtab,
+ dump_blockvector, dump_block, dump_addrchass, dump_namespace,
+ dump_symbol, dump_type, dump_linetable, dump_strtbl): Remove, unused.
+ * xcoffread.c (dump_symtab_lines, dump_symtabs, dump_last_symtab,
+ dump_blockvector, dump_block, dump_addrchass, dump_namespace,
+ dump_symbol, dump_type, dump_linetable, dump_strtbl): Remove 2nd
+ unused copy!
+
+ * buildsym.c (define_symbol): Handle global register variables
+ (from Pierre Willard). Complain if register numbers are too large.
+ * target.c (nomemory): Now that higher levels examine errno, give EIO.
+ * tm-sparc.h: Don't #include <sun4/reg.h>.
+ * sparc-tdep.c (sparc_frame_chain, frame_saved_pc): Remove
+ dependency on <sun4/reg.h>. Start to handle cross-byte-order.
+
+ * language.h: Avoid forward enum declaration.
+ * configure.in, tm-sun4os5.h, xm-sun4os5.h, config/sun4os5.mh,
+ config/sun4os5.mt: New host and target.
+ * defs.h (errno): #include <errno.h> rather than assuming int.
+ From Pierre Willard.
+
+ * breakpoint.c, breakpoint.h, buildsym.c, coffread.c, cplus-dem.c,
+ dbxread.c, dwarfread.c, elfread.c, infcmd.c, infrun.c, inftarg.c,
+ language.c, main.c, mem-break.c, mips-tdep.c, mipsread.c,
+ partial-stab.h, remote.c, saber.suppress, symfile.c, symtab.c,
+ valops.c, valprint.c, xcoffread.c, c-exp.y, m2-exp.y, blockframe.c,
+ command.c, core.c, exec.c, gdbtypes.h, parse.c, printcmd.c, solib.c,
+ sparc-xdep.c, utils.c, value.h, values.c: Lint.
+
+Sat Mar 28 02:43:26 1992 John Gilmore (gnu at cygnus.com)
+
+ * buildsym.c (read_range_type): Avoid int overflow by using unsigned.
+ * dbxread.c (dbx_symfile_init): Remove bogus `lvalue cast'.
+ * language.h (enum exp_opcode): Avoid forward enum def.
+ * main.c (define_command, user_defined_command): Lint.
+ * mem-break.c, xcoffread.c: Lint.
+ * solib.c: Only #include <a.out.h> on SunOS, not SVR4.
+
+Sun Mar 29 14:16:22 1992 Per Bothner (bothner@cygnus.com)
+
+ * Merged in latest RS6000 diffs from Metin G. Ozisik.
+ * xcoffsolib.c, xcoffsolib.h: New files, from Metin.
+ * Various files: Changed #ifdef IBM6000 to IBM6000_HOST
+ or IBM6000_TARGET as (approximately) appropriate.
+
+Sat Mar 28 13:00:10 1992 Fred Fish (fnf@cygnus.com)
+
+ * objfiles.h (OBJF_SYMS): Define flag bit for objfile flags.
+ * symfile.c (symbol_file_add): Use OBJF_SYMS to decide whether
+ or not to try reading symbols from a mapped objfile. Plugs memory
+ leak due to shared libraries generating no psymtabs or symtabs.
+
+Fri Mar 27 15:44:55 1992 John Gilmore (gnu at cygnus.com)
+
+ * buildsym.c (MAX_OF_C_TYPE, MIN_OF_C_TYPE): Unused, remove.
+ * copying.awk: Lint. Make stronger warning at top of copying.c.
+ * elfread.c (elf_symtab_read): Eliminate check of mainline.
+ * gdbtypes.c (smash_to_*): Remove FIXME comments.
+ (lookup_pointer_type): Add FIXME comment.
+ * main.c (set_history_size_command): Disallow negative size.
+ * partial-stab.h: Update copyright.
+ * rs6000-tdep.c (skip_trampoline_code): Better comments.
+
+Wed Mar 25 10:45:38 1992 John Gilmore (gnu at cygnus.com)
+
+ * main.c (set_history_size_command): Negative size is error.
+ (Reported by Peggy Fieland.)
+
+Thu Mar 26 17:01:18 1992 Fred Fish (fnf@cygnus.com)
+
+ * coffread.c (coff_symfile_init): Update comment.
+ * dbxread.c (DBX_SYMFILE_INFO, DBX_TEXT_SECT, DBX_SYMCOUNT,
+ DBX_STRINGTAB, DBX_STRINGTAB_SIZE, DBX_SYMTAB_OFFSET): Define
+ macros to access the dbx specific objfile information.
+ * dbxread.c (symfile_string_table, symfile_string_table_size):
+ Remove these local variables.
+ * dbxread.c (read_ofile_symtab, psymtab_to_symtab_1,
+ read_dbx_symtab): Remove the stringtab and stringtab_size params
+ from the function prototypes, the function definition, and the
+ function calls. These are now available via DBX_STRINGTAB and
+ DBX_STRINGTAB_SIZE using the objfile pointer.
+ * dbxread.c (dbx_symfile_read): Relocate addr before using as
+ an arg to read_dbx_symtab.
+ * dbxread.c (dbx_symfile_read): Remove code that free'd the
+ stringtab and the dbx specific per-objfile private info.
+ * dbxread.c (init_psymbol_list): Remove symbol count from passed
+ args in prototype, function definition, and function calls. It is
+ now available via the DBX_SYMCOUNT macro using the objfile
+ pointer.
+ * dbxread.c (dbx_symfile_read, dbx_symfile_init): Remove the
+ local instance of struct dbx_symfile_info and replace with DBX_*
+ macros.
+ * dbxread.c (dbx_symfile_read): Remove init's of now deleted
+ symfile_string_table and symfile_string_table_size.
+ * dbxread.c (dbx_symfile_finish): Remove now obsolete free of
+ symfile_string_table.
+ * dbxread.c (init_psymbol_list): Use DBX_SYMCOUNT.
+ * dbxread.c (dbx_psymtab_to_symtab): Remove local stringtab and
+ stringtab size variables. Remove all code that used to reread
+ the stringtab.
+ * objfiles.c (allocate_objfile): Move calls to init_malloc()
+ to prior to any calls to mmalloc for the objfile specific heap.
+ * utils.c (init_malloc): Document the requirement that for each
+ heap for which corruption checking is desired, that init_mmalloc
+ must be called prior to any mmalloc calls on the heap.
+
+Thu Mar 26 13:20:06 1992 Per Bothner (bothner@cygnus.com)
+
+ * rs6000-pinsn.c: Make dis-assembly output more like
+ other targets: Don't print instruction in hex before
+ the assembly; use print_address to print out jump
+ destinations.
+
+Wed Mar 25 16:52:35 1992 Per Bothner (bothner@cygnus.com)
+
+ * c-exp.y, gdbtypes.h: Add builtin_type_signed_char.
+ * cplus-dem.c: Support "Sc" meaning "signed char".
+
+Wed Mar 25 15:21:44 1992 Stu Grossman (grossman at cygnus.com)
+
+ * configure.in: fix iris/iris3.
+
+Wed Mar 25 14:55:48 1992 Per Bothner (bothner@cygnus.com)
+
+ * command.c, main.c (various places): Use ctype.h macros
+ (such as isupper(x)), instead of hard-wiring in ASCII-isms
+ (such as (x >= 'A' && x <= 'Z')).
+ (There are still more of these in other files.)
+ * main.c (defined_command): Lower-case the user's
+ new command before entering it. Needed because
+ command lookup is case-insensitive (and also lower-cases).
+ (Based on Metin's earlier patch.)
+
+Tue Mar 24 23:27:01 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * config/irix4.mh: new file.
+
+Tue Mar 24 14:17:48 1992 Stu Grossman (grossman@cygnus.com)
+
+ * infcmd.c (step_1): Call disable_longjmp_breakpoint at the right
+ time.
+
+ * xm-mips.h: Declare strdup for ultrix.
+
+ * mipsread.c (fixup_sigtramp): Make sure that current_objfile is setup
+ when calling new_symbol.
+ * mips-tdep.c (mips_frame_chain): Use symfile_objfile instead of
+ current_objfile.
+
+Tue Mar 24 13:26:25 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * config/rs6000.mh: Update (for Fred's new mmalloc)
+ flags to disable use of GNU malloc/mmalloc.
+ * munch: Change SYSV rule to allow .text before the label,
+ as well as after, to work for AIX.
+ * gdbtypes.h: Minor clarifiction.
+
+Tue Mar 24 07:26:19 1992 Michael Tiemann (tiemann@cygnus.com)
+
+ * buildsym.c (read_struct_type): Handle cretinous dbx symbol name
+ continuation in yet another place (between method declarations).
+
+Mon Mar 23 23:01:41 1992 Stu Grossman (grossman at cygnus.com)
+
+ * mips-tdep.c: include symfile.h and objfiles.h to fix
+ compilation errors.
+
+Mon Mar 23 15:49:14 1992 Per Bothner (bothner@cygnus.com)
+
+ * valops.c (value_struct_elt_for_reference): Added 'offset'
+ parameter to handle multiple inheritance.
+ * eval.c, value.h: Update accordingly.
+
+Fri Mar 20 17:43:27 1992 Fred Fish (fnf@cygnus.com)
+
+ * objfiles.h: New file
+ * Makefile.in (HFILES): Add objfiles.h
+ * blockframe.c: Remove entry_scope_lowpc, entry_scope_highpc,
+ main_scope_lowpc, main_scope_highpc.
+ * blockframe.c, buildsym.c, coffread.c, dbxread.c, dwarfread.c,
+ elfread.c, gdbtypes.h, minsyms.c, mipsread.c, objfiles.c, solib.c,
+ source.c, symfile.c, symmisc.c, symtab.c, target.c, xcoffexec.c,
+ xcoffread.c, : Include objfiles.h.
+ * tm-29k.h, tm-i386v.h, tm-merlin.h, tm-rs6000.h, tm-sun386.h,
+ tm-symmetry.h, tm-tahoe.h, tm-umax.h, tm-vax.h, m88k-tdep.c,
+ mips-tdep.c (FRAME_CHAIN): Renamed outside_startup_file to
+ inside_entry_file() and logic changed appropriately.
+ * blockframe.c (outside_startup_file): Renamed to
+ inside_entry_file() and logic changed appropriately.
+ * blockframe.c (inside_main_scope): Renamed to inside_main_func()
+ and logic changed to use per-objfile specific fields.
+ * blockframe.c (inside_entry_scope): Renamed to
+ inside_entry_func() and logic changed to use per-objfile specific
+ fields.
+ * blockframe.c, buildsym.h, coffread.c, dwarfread.c, mipsread.c,
+ symfile.c, mips-tdep.c (startup_file_start, startup_file_end):
+ Remove extern decls.
+ * symfile.c, symfile.h (entry_point): Remove extern decl.
+ * coffread.c (coff_symfile_init): Common entry point init code
+ moved to symfiles.c, call init_entry_point_info().
+ * coffread.c (complete_symtab): Use new per-objfile entry info.
+ * mip-tdep.c (mips_frame_chain): Use new per-objfile entry info.
+ * mipsread.c (parse_partial_symbols): Use new per-objfile entry
+ info.
+ * dbxread.c (read_dbx_symtab): Use new per-objfile entry info.
+ * defs.h (inside_entry_scope, outside_startup_file,
+ inside_main_scope): Prototypes changed for renames to
+ inside_entry_func, inside_entry_file, inside_main_func,
+ respectively.
+ * symfile.c (syms_from_objfile): Common entry point init code
+ moved to init_entry_point_info() and call init_entry_point_info().
+ * symfile.h (init_entry_point_info): Include prototype.
+ * xcoffread.c (aixcoff_symfile_init): Common entry point init code
+ moved to symfiles.c and call init_entry_point_info().
+ * dwarfread.c (entry_scope_lowpc, entry_scope_highpc,
+ main_scope_lowpc, main_scope_highpc): Remove extern decls.
+ * dwarfread.c (read_func_scope, read_file_scope): Use new per-
+ objfile entry info.
+ * frame.h (FRAME_CHAIN_VALID): Provide default definition that
+ works for the majority of targets.
+ * tm-68k.h, tm-convex.h, tm-h8300.h, tm-i386v.h, tm-irix3.h,
+ tm-merlin.h, tm-mips.h, tm-pyr.h, tm-rs6000.h, tm-sparc.h,
+ tm-sun386.h, tm-tahoe.h, tm-umax.h, tm-vax.h (FRAME_CHAIN_VALID):
+ Use default definition in frame.h.
+ * frame.h (selected_frame_level): Make decl extern.
+ * objfiles.c, symfile.c (current_objfile): Moved to objfiles.c
+ * objfiles.c, symfile.c (symfile_objfile): Moved to objfiles.c
+ * partial-stab.h: Use new per-objfile entry info.
+ * symfile.h (struct objfile): Removed, moved to objfiles.h.
+ * symfile.h, objfiles.h (allocate_objfile, free_objfile,
+ free_all_objfiles, iterate_over_objfiles, iterate_over_symtabs,
+ iterate_over_psymtabs, have_partial_symbols, have_full_symbols,
+ have_minimal_symbols): Prototypes moved to objfiles.h.
+ * symfile.h, objfiles.h (ALL_OBJFILES, ALL_OBJFILES_SAFE):
+ Macros moved to objfiles.h.
+ * tm-h8300.h, tm-i386v4.h (FRAME_CHAIN_VALID_ALTERNATE): Define.
+
+Thu Mar 19 18:49:45 1992 Per Bothner (bothner@cygnus.com)
+
+ More C++ improvements (pointers to members, qualified names).
+ * c-exp.y: Support exp.type::name and exp->type::name
+ syntaxes. (Unfortunately, doesn't work for static members.)
+ * c-exp.y, eval.c: Make type::~type work better.
+ * eval.c (evaluate_subexp: OP_SCOPE): Replace use of
+ value_static_field by value_struct_elt_for_reference.
+ * eval.c (evaluate_subexp): Merge code for STRUCTOP_MEMBER
+ and STRUCTOP_MPTR; cast arg1 to domain-type of arg2.
+ * eval.c (evaluate_subexp): Remove special case for UNOP_ADDR
+ for OP_SCOPE operand; no point in it now that we use lazy
+ reading of values, and use "reference to member" objects.
+ * gdbtypes.h: Clarify comment.
+ * valops.c: Change value_struct_elt_for_address to return
+ a reference (or variable), rather than a pointer. Change
+ the name to value_struct_elt_for_reference to reflect this.
+ Returning a reference instead of a address provides a
+ generalization, since we can use the routine for both
+ class::name as well as &class::name.
+ Also, recurse to handle multiple inheritance properly.
+ * valprint.c: Moved code to print pointer-to-members
+ to new function point_class_member. This allows a
+ "reference-to-member" to be printed using the same code.
+ * valprint.c (type_print_varspec_prefix): Avoid printing
+ "struct " for domains of class-member types.
+ * valops.c (search_struct_field): Inline code for simplified
+ version of value_static_field (which can then be deleted).
+ * value.h: Rename value_struct_elt_for_address to
+ value_struct_elt_for_reference. Delete value_static_field.
+ * values.c: Remove no longer used function value_static_field.
+
+Thu Mar 19 13:54:11 1992 Fred Fish (fnf@cygnus.com)
+
+ * coffread.c, mipsread.c, xcoffread.c, coffread.c, dbxread.c,
+ elfread.c (coff_symfile_finish): Add function, prototype, and
+ add to the xxxx_sym_fns struct for each file type. Also reformat
+ the xxxx_sym_fns vector to a standard format and add comments.
+ * coffread.c, mipsread.c, xcoffread.c, coffread.c, dbxread.c,
+ elfread.c (xxx_symfile_new_init, xxx_symfile_init, xxx_symfile_read):
+ Pass pointer to struct objfile rather than pointer to sym_fns.
+ Change references inside each function accordingly. Allocate any
+ symbol file specific info in the per-objfile memory region.
+ * dbxread.c (free_and_init_header_files): Break function into
+ free_header_files(), called from dbx_symfile_finish(), and
+ init_header_files(), called from dbx_new_init().
+ * dbxread.c (dbx_new_init): Move deallocation things to new
+ dbx_symfile_finish function.
+ * elfread.c (elf_new_init): Call buildsym_new_init().
+ * objfiles.c (free_objfile): Call the appropriate symfile_finish()
+ routine for the objfile before deallocating other stuff.
+ * sparc-tdep.c (get_longjmp_target): Cast target_read_memory arg.
+ * symfile.h: Move struct sym_fns to before struct objfile def.
+ Add sym_finish function pointer and change prototypes of other
+ function pointers to reflect passing struct objfile pointer rather
+ than struct sym_fns pointer.
+ * symfile.c: Remove now obsolete symtab_fns pointer.
+ * symfile.c (symfile_init): Renamed to find_sym_fns, and now only
+ locates the correct sym_fns struct for the given objfile.
+ * symfile.c (syms_from_objfile, symbol_file_add): Restructured
+ for better support of mapped symbol tables.
+ * symfile.c (symbol_file_command): Remove obsolete code using
+ symfile_fns.
+ * symfile.h: Remove duplicate declarations for symfile_objfile,
+ entry_point, and object_files.
+ * target.c (target_info): Compare symfile_objfile to NULL.
+ * xcoffread.c (aixcoff_new_init): Move deallocation stuff to
+ aixcoff_symfile_finish().
+
+Wed Mar 18 18:22:46 1992 Fred Fish (fnf@cygnus.com)
+
+ * infrun.c (IN_SOLIB_TRAMPOLINE): Add default definition.
+ * infrun.c (wait_for_inferior): Use IN_SOLIB_TRAMPOLINE.
+ * tm-sysv4.h (IN_SOLIB_TRAMPOLINE): Add SVR4 definition.
+
+Wed Mar 18 15:51:15 1992 Per Bothner (bothner@cygnus.com)
+
+ Some improvements to g++ debugging.
+ * symtab.c (list_symbols): demangle before pattern matching.
+ * symtab.c: Other fixes to improve handing of operators.
+ * valprint.c (type_print_base): Fix test for constructor.
+ * values.c (value_static_field): Allow evaluation of
+ CLASS::METHOD, returning a function pointer.
+
+Wed Mar 18 08:39:52 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Roll 4.4.6.
+ * exec.c (exec_file_command): Add code to ignore optional args
+ passed in by file_command() for use in symbol_file_command().
+ * main.c (main): Document -mapped and -readnow in help summary.
+ * objfiles.c (open_mapped_file): Cosmetic change, arg renamed.
+ * objfiles.c (allocate_objfile): Filename arg removed. Changes
+ to get filename from bfd with bfd_get_filename(). Test mapto
+ against 0, not NULL. Use mstrsave() to make copy of filename.
+ * remote-mm.c (mm_load): Symbol_file_add() takes an additional
+ arg.
+ * remote-vx.c (vx_load_command, add_symbol_stub):
+ Symbol_file_add() takes an additional arg.
+ * solib.c (symbol_add_stub): Symbol_file_add() takes an
+ additional arg.
+ * symfile.c (symfile_open): Renamed to symfile_bfd_open and
+ changed to return a bfd not an objfile pointer.
+ * symfile.c (syms_from_objfile): Eliminate local copy of bfd.
+ * symfile.c (symbol_file_add): Takes an additional arg (readnow).
+ Change to eliminate local bfd and use symfile_bfd_open() plus
+ allocate_objfile(). Add code to implement readnow option.
+ * symfile.c (symbol_file_command): Changes to option handling,
+ readnow functionality moved to symbol_file_add().
+ * symfile.c (symfile_init): Eliminate local copy of bfd.
+ * symfile.c (add_symbol_file_command): Changes to parse mapped
+ and readnow options.
+ * symfile.h (allocate_objfile): Arg removed from prototype.
+ * symtab.h (symbol_file_add): Arg added to prototype.
+ * xcoffexec.c (map_vmap): Allocate_objfile() takes an additional
+ arg.
+
+Sat Mar 14 16:38:47 1992 Fred Fish (fnf@cygnus.com)
+
+ * gmalloc.c, gmalloc.h mcheck.c mmap-alloc.c mmap-sbrk.c mtrace.c,
+ mtrace.awk, state.c, state.h: Removed.
+ * .gdbinit: Add ../malloc, ../libiberty, and ../bfd to list of
+ directories searched for source files.
+ * Makefile.in (GNU_MALLOC, MALLOC_CFLAGS, MALLOCSRC): Removed
+ * Makefile.in (MMALLOC_DIR, MMALLOC_DEP, MMALLOC_LIB,
+ MMALLOC_DISABLE, MMALLOC_CHECK, MMALLOC_CFLAGS): Add
+ * Makefile.in (CFLAGS): Replace MALLOC_CFLAGS with MMALLOC_CFLAGS.
+ * Makefile.in (CLIBS, CDEPS): Add MMALLOC_LIB
+ * Makefile.in (ADD_FILES, ADD_DEPS): Remove GNU_MALLOC.
+ * Makefile.in (SFILES_MAINDIR): Remove stat.c mmap-alloc.c, mmap-
+ sbrk.c
+ * Makefile.in (HFILES): Remove state.h
+ * Makefile.in (POSSLIBS_MAINDIR): Remove MALLOCSRC.
+ * Makefile.in (OBS): Remove state.o mmap-alloc.o mmap-sbrk.o
+ * Makefile.in (saber_gdb): Remove mcheck, mtrace. Add MMALLOC_DIR.
+ * Makefile.in (clean): Remove all object files.
+ * c-exp.y: Define malloc to xmalloc and realloc to xrealloc.
+ * cplus-dem.c: Remove prototypes definitions that are now done in
+ def.h.
+ * dbxread.c (throughout): Change from using per-objfile
+ xmalloc/xrealloc/free functions to xmmalloc/xmrealloc/mfree.
+ * defs.h: Remove prototypes for mmap_* functions. Add prototypes
+ for xmmalloc, xmrealloc, mfree, mmcheck, mmtrace, mmalloc_attach,
+ mmalloc_detach, mmalloc_setkey, msavestring, and mstrsave, nomem.
+ * depend: Remove dependencies for state.o, state.h.
+ * dwarfread.c: Add declaration for warning_pre_print.
+ * dwarfread.c (dwarfwarn): Use warning_pre_print.
+ * dwarfread.c (throughout): Change from using per-objfile
+ xmalloc/xrealloc/free functions to xmmalloc/xmrealloc/mfree.
+ * gdbtypes.c (lookup_fundamental_type): Fix init_type calls to
+ use supplied objfile.
+ * i386-xdep.c (print_387_status): Change to use warning() rather
+ than printfs.
+ * i387-tdep.c (print_387_control_word): Change to use warning()
+ rather than printfs.
+ * infrun.c (wait_for_inferior): Remove unreachable abort() call
+ that some compilers grumble about.
+ * language.c (throughout): Add declaration for warning_pre_print
+ and using warning() instead of printfs.
+ * m2-exp.y: Define malloc to xmalloc and realloc to xrealloc.
+ * main.c (main): Add declaration for warning_pre_print and set it
+ similarly to error_pre_print. Add declarations for
+ mapped_symbol_files and readnow_symbol_files. Add appropriate
+ definitions to long_options[].
+ * minsyms.c: Trivial fix to comment.
+ * objfiles.c (allocate_objfile): Substantially rewritten for
+ using mapped symbol files.
+ * objfiles.c (throughout): Change from using per-objfile
+ xmalloc/xrealloc/free functions to xmmalloc/xmrealloc/mfree.
+ * objfiles.c (open_mapped_file, mapped_to_address): Add functions.
+ * source.c (throughout): Change from using per-objfile
+ xmalloc/xrealloc/free functions to xmmalloc/xmrealloc/mfree.
+ * source.c (open_source_file): Use mstrsave to save file name in
+ mapped symbol region for objfile.
+ * symfile.c: Remove include for state.h.
+ include to local form.
+ * symfile.c (symbol_file_add_digested): Remove.
+ * symfile.c (symbol_file_add): Substantially rewritten for mapped
+ symbol files.
+ * symfile.h: Remove malloc/xrealloc/xmalloc/xrealloc/free members
+ from objfile structure. Add malloc descriptor pointer (md).
+ * symfile.h (OBJF_DUMPABLE): Changed name to OBJF_MAPPED.
+ * symm-xdep.c (print_fpu_status): Use warning() rather than
+ printfs.
+ * symmisc.c (free_symtab_block): Now takes and uses current
+ objfile pointer.
+ * symmisc.c (throughout): Change from using per-objfile
+ xmalloc/xrealloc/free functions to xmmalloc/xmrealloc/mfree.
+ * symtab.c (cplus_mangled_symbol): Cast return value to avoid
+ Sun compiler grumblings when PTR is char *.
+ * symtab.c (lookup_symbol): Cast return value of iterate_over_
+ msymbols() to correct pointer type.
+ * utils.c (warning_pre_print): Initialize to "\nwarning: ".
+ * utils.c (fatal, fatal_dump_core): Ensure that the fatal
+ error always starts on a line of it's own.
+ * utils.c (init_malloc, malloc_botch, xmalloc, xrealloc):
+ Rewrite for new mapped malloc package use.
+ * utils.c (mmalloc, mrealloc, mfree): Stubs for configurations
+ that don't want to use the mapped malloc package; pass arguments
+ on to traditional malloc package functions.
+ * utils.c (nomem): Add for fatal virtual memory exhausted aborts.
+ * utils.c (xmmalloc, xmrealloc, xmalloc, xrealloc): Like mmalloc,
+ mrealloc, malloc, and realloc but get fatal error if runs out
+ of memory.
+ * utils.c (msavestring, mstrsave): Save a string in a specific
+ mapped malloc region.
+ * utils.c (print_spaces): Use xmalloc to get the buffer.
+ * xm-amix.h, xm-i386v4.h, xm-sun3os4.h, xm-sun4os4.h: Add defines
+ for MMAP_BASE_ADDRESS and MMAP_INCREMENT.
+ * config/i386v4.mh: Insignificant reorganization.
+
+Sat Mar 14 11:44:47 1992 Fred Fish (fnf@cygnus.com)
+
+ * xcoffread.c: Only enable compilation of debugging functions
+ if IBM6000 is defined. Fails to compile otherwise.
+
+Fri Mar 13 15:51:11 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: pass MAKEINFO down on info.
+
+Fri Mar 13 12:56:36 1992 John Gilmore (gnu at cygnus.com)
+
+ * mipsread.c (mipscoff_symfile_read): Eliminate a lot of
+ useless code, including an lseek to an uninitialized variable.
+ Reported by Jim Williams <jimbo@wrs.com>.
+
+Thu Mar 12 11:56:46 1992 Per Bothner (bothner@cygnus.com)
+
+ Merged in patches from metin@ibmpa.awdpa.ibm.com (Metin G.
+ Ozisik) (dated Fri, 6 Mar 92 17:51) for the rs6000.
+ * minsyms.c, symfile.c: Changes that may be generally
+ applicable, but are #ifdef IBM6000 for now.
+ * rs6000-xdep.c: Fixed typo in comment.
+ * rs6000-tdep.c: Non-substatial changes.
+ * xoffread.c: The main change here is addition of some
+ debugging functions.
+ * xoffexec.c: More changes.
+
+ * xcoffread.c: Fixed two too-few-parameters bugs.
+
+ * solib.h, infrun.c, tm-rs6000.h: Add a PID parameter
+ to SOLIB_CREATE_INFERIOR_HOOK macro.
+
+Sun Mar 8 21:17:48 1992 Fred Fish (fnf@cygnus.com)
+
+ * symfile.h: Add prototype for iterate_over_msymbols().
+ * symtab.c (cplus_mangled_symbol): Add function.
+ * symtab.c (lookup_symbol): Call cplus_mangled_symbol via
+ iterate_over_msymbols to find demangled C++ symbol.
+ * xcoffexec.c (relocate_minimal_symbol): Return meaningful
+ value to iterate_over_msymbols().
+ * xcoffexec.c (vmap_symtab): Ignore return from iterate_over_
+ msymbols().
+
+Fri Mar 6 21:59:34 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: added check target.
+
+Thu Mar 5 23:56:01 1992 John Gilmore (gnu at cygnus.com)
+
+ * ecoff.c: Move to ../bfd/coff-msym.c.
+ * config/mt-*mips: Remove ecoff.o from the configuration.
+ * remote.c (): Add newline to initial +.
+ (remote_resume): Mention how to cope with signals.
+ (remote_interrupt): Add debug msg.
+ (remote-wait): Implement new 'T' reply, which includes
+ status, PC, and FP all in a single short message.
+ (putpkt): Add further debugging of packet acks.
+ * mipsread.c (fixup_symtab): Also swap RFD's.
+ (parse_partial_symbols): Avoid bug on unknown symbol types.
+ * Makefile.in (VERSION): Roll to 4.4.5.
+ * mips-tdep.c (heuristic_proc_start): Avoid long delays
+ for remote MIPS by limiting heuristic to 200 byte search.
+ (heuristic_proc_desc): Byte-swapping.
+ (mips_print_register): Cope with failure of
+ read_relative_register_raw_bytes. Byte-swap integers for
+ printing.
+ * mips-pinsn.c (print_insn): Byte-swap instruction.
+
+Thu Mar 5 12:32:09 1992 Stu Grossman (grossman at cygnus.com)
+
+ * config.sub configure.in config/mh-irix4
+ gdb/configure.in gdb/mips-tdep.c gdb/mipsread.c
+ gdb/procfs.c gdb/signame.h gdb/tm-irix3.h gdb/tm-mips.h
+ gdb/xm-irix4.h gdb/config/mt-irix3
+ gdb/config/mh-irix4 texinfo/configure.in: Port to SGI Irix-4.x.
+
+Wed Mar 4 11:56:42 1992 Fred Fish (fnf@cygnus.com)
+
+ * defs.h, utils.c: xrealloc takes PTR as first arg.
+ * defs.h: Reword confusing comment about ANSI prototypes.
+ * defs.h: Some minor whitespace changes.
+ * infrun.c (wait_for_inferior): Compare int tmp to int 0,
+ not NULL, which can be (void *).
+ * tm-amix.h, tm-i386v4.h: Add defines for setjmp/longjmp handling.
+ * tm-i386v.h (SP_ARG0): Define
+ * xm-sysv4.h: Back out of change for missing prototypes.
+ * i386-tdep.c (get_longjmp_target): Add function.
+
+Wed Mar 4 05:46:11 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: install man page too.
+
+Tue Mar 3 15:11:52 1992 Michael Tiemann (tiemann@cygnus.com)
+
+ * All GDB files that #include defs.h: Removed stdio.h.
+ (defs.h): #include stdio.h.
+
+Mon Mar 2 23:00:12 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * gdbtypes.c (lookup_pointer_type): initialize the TYPE_LENGTH of
+ a ptype to reflect the setting of TARGET_PTR_BIT. Set the
+ TYPE_FLAGS of a ptype to TYPE_FLAG_UNSIGNED.
+ * tm-h8300.h, h8300-tdep.c, remote-hms.c: personal checkpoint
+ * printcmd.c (print_address): if ADDR_BITS_REMOVE is defined, use
+ it before printing out the hex shape of an address.
+
+Sun Mar 1 17:41:09 1992 Per Bothner (bothner@cygnus.com)
+
+ * rs6000-xdep.c (frame_initial_stack_address): Move
+ code to set frame->cache_fsr into new separate function
+ frame_get_cacahe_fsr. This allows fixing a fatal error.
+ * xcoffexec.c: Turn previously suppressed error
+ message back on, after cleaning up BFD.
+
+ * breakpoint.c (breakpoint_re_set): Removed (at least for now)
+ printing of blank line, since it cases printing of an
+ extra blank line. Is this intended? It does mess up
+ gdb test suite.
+ * defs.h: Put back declarations of malloc and realloc,
+ but protected by #ifndef MALLOC_INCOMPATIBLE.
+ * objfiles.c: Undo previous change: Use malloc/realloc
+ for objfile malloc/realloc fields (but add a cast).
+ * xcoffexec.c: Suppress an error message (for now).
+
+Sat Feb 29 14:43:02 1992 Per Bothner (bothner@cygnus.com)
+
+ Changes from metin@ibmpa.awdpa.ibm.com (Metin G. Ozisik)
+ [Mail dated Fri, 21 Feb 92 13:14:54 -0800]
+ * buildsym.c: Use smash_to_pointer_type() to handle forward type
+ references.
+ * xcoffread.c: Modifications to C_DECL storage class handling, and
+ introduction of an old smash_to_pointer_type() routine.
+
+ Changes from metin@ibmpa.awdpa.ibm.com (Metin G. Ozisik)
+ [Mail dated Thu, 20 Feb 92 13:57:16 -0800]
+ * rs6000-xdep.c, rs6000-tdep.c, tm-rs6000.h: function_frame_info()
+ parameters have been modified.
+
+ Changes from metin@ibmpa.awdpa.ibm.com (Metin G. Ozisik)
+ [Mail dated Thu, 20 Feb 92 10:10:05 -0800]
+ * rs6000-tdep.c: Before Feb 5 92, register_valid[] array was not used,
+ and fetch_inferior_registers() always fetched all the registers
+ resulting valid register values at hand all the time. Pushing a dummy
+ frame did not require validating all register values first. After
+ putting the above mechanism into action, we didn't have valid registers
+ values always ready. Thus, all registers need to be fetched before
+ pushing a dummy frame now.
+
+ Changes from metin@ibmpa.awdpa.ibm.com (Metin G. Ozisik)
+ [Mail dated Thu, 13 Feb 92 16:22:44 -0800]
+ * rs6000-xdep.c: frame_initial_stack_address() function to calculate
+ the starting address (actual frame address) of a frame.
+ * rs6000-tdep.c: modifications to function_frame_info() to see if
+ function reserves a frame pointer register (alloca register)
+ * tm-rs6000.h: EXTRA_FRAME_INFO, FRAME_ARGS_ADDRESS and
+ FRAME_LOCALS_ADDRESS has been updated to support debugging of
+ functions with alloca() calls.
+
+Sun Mar 1 13:13:39 1992 Fred Fish (fnf@cygnus.com)
+
+ * xm-sysv4.h: Provide definitions/prototypes for host environment
+ functions for which no definitions or prototypes are provided in
+ any currently included gdb or host environment header files.
+ For SVR4, this currently includes malloc and realloc, which cannot
+ be portably prototyped in any gdb include file.
+
+Sat Feb 29 14:43:02 1992 Per Bothner (bothner@cygnus.com)
+
+ * buildsym.h: Remove obsolete variable file_stabs.
+
+ * Makefile.in: Move place where configure merges in host-
+ and target-dependent fragments later, so the latter
+ can override (say) GNU_MALLOC.
+ * config/mh-rs6000: Use system malloc. Otherwise, I
+ ended up with *two* incompatible versions of malloc
+ (functions in libc would call the malloc in libc).
+ I assume this is a shared library problem.
+
+ * remote.c: Fix (presumed) typo.
+ * objfiles.c: Use xmalloc/xrealloc instead of
+ malloc/realloc (since the latter are no longer declared).
+
+ Changes from metin@ibmpa.awdpa.ibm.com (Metin G. Ozisik)
+ [Mail dated Thu, 6 Feb 1992 10:22:02 -0800]
+ * rs6000-xdep.c: Improvements to fetch_inferior_registers() to
+ handle individual registers.
+ * tm-rs6000.h: Fix SAVED_PC_AFTER_CALL macro to handle pc value
+ correctly in case it wasn't cached yet. (A problem showed up
+ after fetching individual registers.)
+ * buildsym.c: Disable type_synonym_name's type name overwriting
+ in cases it is unnecesary. rs6000 portation doesn't use
+ type_synonym_name, and it used to nullify type names
+ * xcoffread.c: to handle g++'s typename abbreviation, fill in a
+ type's name as soon as space for that type is allocated.
+ * xcoffread.c: ignore a section's lineno information if it is
+ not `.text'. (In rs6000 bfd portation integration, skipping over
+ `.pad' sections are ignored since it was in machine independent
+ part of the code. Thus, a problem of fake sections with invalid
+ lineno information arised.)
+
+ Changes from metin@ibmpa.awdpa.ibm.com (Metin G. Ozisik)
+ [Mail dated Thu, 6 Feb 1992 13:26:22 -0800]
+ * rs6000-tdep.c: make function_frame_info() work whether or not
+ reading from a core file.
+ * tm-rs6000.h: Implementation of FRAME_FIND_SAVED_REGS macro.
+
+ * infrun.c. main.c, printcmd.c. symtab.c:
+ More changes from IBM for rs6000.
+
+
+Thu Feb 27 22:57:19 1992 Per Bothner (bothner@cygnus.com)
+
+ * rs6k-opcode.h, tm-rs6000.h, xm-rs6000.h, rs6000-tdep.c,
+ rs6000-xdep.c, xcoffexec.c, xcoffread.c:
+ Merge in changes (mostly from IBM) for RS6000.
+ * breakpoint.c, buildsym.c, infptrace.c, stack.c, symtab.c:
+ More changes from IBM for RS6000. These are in machine-
+ independent code, and probably could do with some cleaning
+ up. The most questionable of these are #ifdef IBM6000.
+ * infrun.c, sparc-tdep.c: Pass a parameter (signal number)
+ to single_step() (for consistency with rs6000 and i860).
+ * utils.c: Allow the 1st arg to xrealloc to be NULL
+ (in which case do malloc). This removes the need for
+ some tests in xcoff code (and perhaps other places?).
+ * coffread.c: Removed variables last_source_file,
+ type_vector, and type_vector_length as these are now
+ defined by buildsym.[ch].
+ * defs.h: Remove prototypes for malloc and realloc, since
+ these should only be used to implement xmalloc and xrealloc,
+ and they conflict with <stdlib.h> in AIX - where they
+ return void* even when __STDC__ isn't defined. Sigh.
+ * munch: Recognize *initialize* in data as well as text
+ (AIX uses data). Also, incorporate a patch from Garrett
+ Wollman <wollman@uvm-gen.uvm.edu> to make the sed script
+ much more sensible, by only trying to match the name of
+ the initialize_foo function, and not the junk before it.
+
+Thu Feb 27 20:07:43 1992 Stu Grossman (grossman at cygnus.com)
+
+ * breakpoint.c (breakpoint_re_set_one): Don't reset breakpoint
+ unless symbol table indicates that something has changed.
+
+Thu Feb 27 11:48:47 1992 John Gilmore (gnu at cygnus.com)
+
+ * remote.c: Make it work for embedded MIPS. Increase buffer
+ size, and use throughout. Round buffer size up if too many regs.
+ Support baud rate setting and try for an 8-bit path. If
+ interrupted while waiting for target, send a ^C down the wire.
+ Avoid single-byte reads.
+ * tm-mips.h: Add more embedded-system registers to REGISTER_NAMES
+ and NUM_REGS.
+ * mips-xdep.h: Avoid the embedded regs when on Unix.
+
+ * mipsread.c: Byte-swap the symbol table structures, using
+ routines from ecoff.c, to read a symbol table written in any
+ of the four possible byte orders.
+ * configure.in (mips-big-* target): Same as Sony News.
+ * config/mt-bigmips, config/mt-littlemips: Add ecoff.o.
+ * ecoff.c: New file for symbol swapping routines.
+
+Thu Feb 27 09:26:38 1992 Stu Grossman (grossman at cygnus.com)
+
+ * breakpoint.c (all_breakpoints_info, breakpoint_1): Add 'info
+ all-breakpoints' command.
+ * (get_number): Allow users to enter negative breakpoint numbers.
+ * (breakpoint_1): Reformat display of 'info break' to show new
+ fields.
+ * (create_longjmp_breakpoint, breakpoint_re_set,
+ breakpoint_re_set_one, enable/disable_longjmp_breakpoint),
+ symfile.c (syms_from_objfile): Re-do
+ insertion of longjmp breakpoints. Move all code into
+ breakpoint_re_set, and call that instead of
+ create_longjmp_breakpoint in symfile.c.
+
+Thu Feb 27 06:11:05 1992 John Gilmore (gnu at cygnus.com)
+
+ * breakpoint.h (ALL_BREAKPOINTS_SAFE): Add.
+ * breakpoint.c (breakpoint_re_set): Use ALL_BREAKPOINTS_SAFE.
+ * symtab.c (find_pc_symtab): Handle having no objfiles.
+ * infcmd.c: Fix comment.
+ * objfiles.c (free_all_objfiles): Add.
+ * symfile.h (ALL_OBJFILES, ALL_OBJFILES_SAFE): Add.
+ * symfile.c (symbol_file_command): free all objfiles when
+ specifying a new symbol file.
+ (reread_symbols): Stat the file name, don't fstat the descriptor.
+
+Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in, configure.in: removed traces of namesubdir,
+ -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced
+ copyrights to '92, changed some from Cygnus to FSF.
+
+Tue Feb 25 19:31:19 1992 Stu Grossman (grossman at cygnus.com)
+
+ * dbxread.c (end_psymtab): Delete empty psymtabs.
+ * symfile.c (allocate_psymtab): Recycle empty psymtabs.
+ * symfile.h (struct objfile): Add free_psymtabs.
+
+Sat Feb 22 02:00:32 1992 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in (VERSION): Roll to gdb-4.4.4.
+
+ * symfile.c (symbol_file_command): strcmp => !strcmp.
+ * breakpoint.h: Move prototypes to follow enum definition they need.
+ * breakpoint.c, infrun.c: Lint.
+ * printcmd.c: Use `enum enable' rather than `enum
+ display_status'.
+ * mipsread.c: First pass at making it compile with the new
+ objfile changes. Probably seriously broken still, but it
+ compiles. FIXME.
+
+Sat Feb 22 00:56:39 1992 Stu Grossman (grossman at cygnus.com)
+
+ * infrun.c, infcmd.c, breakpoint.c, main.c, symfile.c,
+ breakpoint.h, tm-sun4os4.h, tm-sparc.h, sparc-tdep.c, tm-mips.h,
+ mips-tdep.h, tm-sun3.h, tm-68k.h, m68k-tdep.h: Add support for
+ stepping (and nexting) through longjmp(). Also, cleanup
+ breakpoint handling quite a bit by creating explicit breakpoint
+ types instead of using magic breakpoint numbers.
+ Makefile.in: Update version to 4.4.3
+
+Sat Feb 22 00:08:50 1992 John Gilmore (gnu at cygnus.com)
+
+ * buildsym.c, dwarfread.c, gdbtypes.c, inflow.c, main.c,
+ minsyms.c, printcmd.c, remote.c, saber.suppress: Saberlint.
+ * symmisc.c, xcoffread.c: Move debug functions to symmisc.c.
+
+ * xm-sun3os4.h, xm-sun4os4.h: Enable HAVE_MMAP.
+
+ * minsyms.c (install_minimal_symbols): Add bunches to any
+ existing minsyms in the objfile. Avoid extra mallocation
+ by working directly in the obstack. Remove ignored `mainline' parm.
+ * coffread.c, dbxread.c, elfread.c, mipsread.c, solib.c, symtab.h,
+ xcoffread.c: Change all callers.
+ * FIXME: We should be able to eliminate MAINLINE from all the
+ symbol readers now, with a small bit of work.
+
+ * valops.c, value.h: Lint.
+ * remote-vx.c: Add missing break; statement. Bugfix by
+ Michael Sclafani, <sclafani@src.dec.com>.
+
+Fri Feb 21 17:29:54 1992 Fred Fish (fnf at cygnus.com)
+
+ * Makefile.in (VERSION): Update version to 4.4.2
+ * Makefile.in (SFILES_MAINDIR): Add gdbtypes.c, state.c, objfiles.c,
+ minsyms.c, mmap-alloc.c, mmap-sbrk.c
+ * Makefile.in (HFILES): Add gdbtypes.h, state.h, solib.h
+ * Makefile.in (OBS): Add gdbtypes.o, state.o, objfiles.o, minsyms.o,
+ mmap-alloc.o, mmap-sbrk.o
+
+ * altos-xdep.c: Minor whitespace change.
+ * am29k-tdep.c (examine_prologue): Convert from misc function vector
+ use to new minimal symbol table use.
+ * arm-xdep.c (fetch_inferior_registers): Document unused argument.
+ * arm-xdep.c (store_inferior_registers): Returns void.
+ * blockframe.c (get_pc_function_start, find_pc_partial_function):
+ Convert from misc function vector use to new minimal symbol table use.
+ Remove find_pc_misc_function(). Ifdef out block_innermost_frame().
+ * breakpoint.c: Add prototypes for local functions.
+ * breakpoint.c (catch_command_1): Change to static and remove unused
+ local "pc".
+ * breakpoint.c (map_breakpoint_numbers): Prototype arg "function".
+ * breakpoint.h: Change function decls to prototype form.
+ * buildsym.c: Add prototypes for local functions.
+ * buildsym.c: Moved hashname() function here from dbxread.c.
+ * buildsym.c (dbx_lookup_type): Cast args to xrealloc().
+ * buildsym.c: Remove dbx_create_type(), uses changed to alloc_type().
+ * buildsym.c (dbx_alloc_type): Change to static.
+ * buildsym.c (finish_block): Add objfile parameter.
+ * buildsym.c (misc): Change symbol_obstack to objfile version.
+ * buildsym.c (make_blockvector): Change to static.
+ * buildsym.c (start_subfile): Use strdup instead of obsavestring.
+ * buildsym.c (compare_line_numbers): Change to static, args are const,
+ cast args when used.
+ * buildsym.c (start_symtab): Inline new_object_header_files() call.
+ * buildsym.c (patch_block_stabs): Moved to this file from xcoffread
+ and made static. Add objfile parameter.
+ * buildsym.c (end_symtab): Simplify code using line table size.
+ Realloc the linetable on the objfile symbol_obstack and copy there.
+ * buildsym.c (scan_file_globals): Convert from misc function vector
+ use to new minimal symbol use.
+ * buildsym.c (define_symbol): Add objfile parameter. Make sure
+ strings get allocated in objfile's symbol_obstack. Convert references
+ to builtin types to lookup_fundamental_type().
+ * buildsym.c (read_type): Make static, add objfile parameter, convert
+ references to buildin types to lookup_fundamental_type().
+ * buildsym.c (read_struct_type): Add objfile parameter.
+ * buildsym.c (read_array_type): Make static, add objfile parameter.
+ * buildsym.c (read_enum_type): Make static, add objfile parameter.
+ * buildsym.c (read_huge_number): Make static.
+ * buildsym.c (read_range_type): Make static, add objfile parameter,
+ convert references to buildin types to lookup_fundamental_type ().
+ * buildsym.c (read_args): Make static, add objfile parameter.
+ * buildsym.h: Convert function decl's to prototype form.
+ * c-exp.y: Add prototypes for local functions, convert uses of misc
+ function vector to minimal symbol table. Reformat all builtin type
+ initializations and pass a NULL objfile to init_type() for them.
+ * coffread.c: Change context_stack ref's to coff_context_stack,
+ add local function prototypes. Cast uses of xrealloc arg 1.
+ * coffread.c (coff_alloc_type): Call alloc_type instead of hand-
+ crafting a new type.
+ * coffread.c (add_symbol_to_list): Change to coff_add_symbol_to_list.
+ * coffread.c (finish_block): Change name to coff_finish_block.
+ * coffread.c (make_blockvector): Add and use objfile parameter.
+ * coffread.c (record_line): Change name to coff_record_line.
+ * coffread.c (start_symtab): Change name to coff_start_symtab.
+ * coffread.c (end_symtab): Change name to coff_end_symtab.
+ * coffread.c (record_misc_function): Change name to record_minimal_
+ symbol and change to minimal symbol table use from misc func tbl.
+ * coffread.c (coff_symfile_read): Convert from misc function vector
+ use to minimal symbol table use.
+ * coffread.c (hashname): Remove; use common version in buildsym.c.
+ * coffread.c (decode_base_type): Change references to builtin types
+ to calls to lookup_fundamental_type().
+ * coffread.c (read_struct_type): Change name to coff_read_struct_type.
+ * coffread.c (read_enum_type): Change name to coff_read_enum_type.
+ * command.c: Add prototypes for local functions.
+ * command.c (add_cmd): Prototype the 'fun' parameter and use the
+ appropriate member of the function union for that type.
+ * command.c (add_abbrev_cmd): Prototype the 'fun' parameter and
+ ifdef out the function since it isn't currently used.
+ * command.c (add_alias_cmd): Pass correct function type to add_cmd.
+ * command.c (add_prefix_cmd): Prototype the 'fun' parameter.
+ * command.c (add_abbrev_prefix_cmd): Prototype the 'fun' parameter.
+ * command.c (help_cmd): Compare function pointer to NULL.
+ * command.c (help_cmd_list): Compare function pointer to NULL.
+ * command.c (lookup_cmd_1): Use correct member of function union.
+ * command.c (undef_cmd_error): Make static.
+ * command.c (complete_on_cmdlist): Use correct member of func union.
+ * command.c (do_setshow_command): Use correct member of func union.
+ * command.c (shell_escape): Convert rindex use to strrchr.
+ * command.h (COMMAND_H): Define if already included.
+ * command.h (cmd_list_element struct): Change 'function' to a union
+ and prototype args. Prototype completer function.
+ * command.h: Convert decl's to prototype form.
+ * convex-xdep.c (store_inferior_registers): Returns void.
+ * copying.c: Prototype local functions.
+ * coredep.c: Minor whitespace change.
+ * cplus-dem.c: Remove hack to use BSD equivalents of mem* and str*.
+ * cplus-dem.c: Prototype local functions.
+ * dbxread.c (hashname): Remove; moved to buildsym.c.
+ * dbxread.c (free_and_init_header_files): Make static.
+ * dbxread.c: Add prototypes for local functions.
+ * dbxread.c (new_object_header_files): Remove; inlined usages.
+ * dbxread.c (xrealloc usages): Cast args.
+ * dbxread.c (record_misc_function): Change to record_minimal_symbol
+ and change usages accordingly.
+ * dbxread.c (static_psymbols usages): Change to use per-objfile copy.
+ * dbxread.c (xmalloc usages): Use per-objfile copy when appropriate.
+ * dbxread.c (dbx_next_symbol_text): Make static.
+ * dbxread.c (init_psymbol_list): Convert to use per-objfile data.
+ * dbxread.c (init_bincl_list): Add and use objfile parameter.
+ * dbxread.c (free_bincl_list): Add and use objfile parameter.
+ * dbxread.c (compare_psymbols): Remove; use common symfile.c version.
+ * dbxread.c (end_psymtab): Convert to use per-objfile data.
+ * dwarfread.c (DEFUN/EXFUN): Remove all usages. Use PARAMS for
+ prototypes.
+ * dwarfread.c (record_misc_function): Change name to record_minimal_
+ symbol and use minimal symbol table throughout.
+ * dwarfread.c (compare_psymbols): Remove; use common symtab.c version.
+ * dwarfread.c: Convert all references to builtin types to use the new
+ lookup_fundamental_type function.
+ * dwarfread.c (read_enumeration): Add and use objfile parameter.
+ * elfread.c (DEFUN/EXFUN): Remove all usages. Use PARAMS for proto-
+ types.
+ * elfread.c (record_misc_function): Convert to use record_minimal_
+ symbol.
+ * elfread.c (elf_symtab_read): Add objfile parameter.
+ * eval.c: Add prototypes for local functions and move some decls
+ around to accomodate prototypes.
+ * expprint.c: Add prototypes for local functions. Change references
+ to misc function vector to minimal symbol table.
+ * findvar.c (read_memory usages): Cast args.
+ * gdbtypes.h: New file, type info from symfile.h and symtab.h.
+ * gmalloc.c: Use NOARGS where prototypes used hardwired void.
+ * gmalloc.c (BLOCKSIZE): Constant to be shifted is unsigned.
+ * gmalloc.h: Use NOARGS where prototypes used hardwired void.
+ * gould-xdep.c: Minor whitespace change.
+ * hp300ux-xdep.c (fetch_inferior_registers): Remove unused regno var.
+ * hp300ux-xdep.c (store_inferior_registers): Returns void.
+ * hp300ux-xdep.c (fetch_core_registers): Takes unused arg reg_addr.
+ * i386-stub.c: Add prototypes, change "volatile" to NORETURN.
+ * i386-tdep.c: Add prototypes for local functions.
+ * i386-tdep.c (codestream_fill, codestream_seek, codestream_read,
+ i386_get_frame_setup, i386_skip_prologue): Explicitly declare params
+ that defaulted to int.
+ * i386-tdep.c (i386_follow_jump, i386_frame_find_saved_regs,
+ i386_push_dummy_frame): Returns void.
+ * i386-xdep.c (i386_register_u_addr): Declare params that default to
+ int and explicitly declare return type as int.
+ * i387-tdep.c: Minor formatting changes.
+ * i960-tdep.c (leafproc_return): Convert from misc function vector
+ use to minimal symbol table use.
+ * infcmd.c: Add prototypes for local functions.
+ * infcmd.c (continue_command, until_next_command, until_command,
+ path_info, path_command): Make static.
+ * infcmd.c (step_1, until_next_command): Convert from misc func
+ vector to minimal symbol table use.
+ * inflow.c: Add prototypes for local functions.
+ * infptrace.c (store_inferior_registers): Returns void, not int.
+ * language.c (_initialize_language): Use proper member of function
+ union.
+ * m2-exp.y: Add prototypes for local functions, convert misc function
+ vector uses to minimal symbol table uses.
+ * m2-exp.y (make_qualname, yyerror): Make static.
+ * m2-exp.y (_initialize_m2_exp): Call init_types with NULL objfile.
+ * m68k-pinsn.c: Add prototypes for local functions.
+ * m68k-pinsn.c (print_insn): Cast args to read_memory.
+ * m68k-pinsn.c (fetch_arg): Make parameter 'code' and int.
+ * m68k-stub.c: Add prototypes.
+ * m88k-pinsn.c (sprint_address): Convert from misc function vector
+ use to minimal symbol table use.
+ * m88k-xdep.c (fetch_inferior_registers): Takes an unused parameter.
+ * m88k-xdep.c (store_inferior_registers): Returns void.
+ * mach386-xdep.c (fetch_inferior_registers): Takes an unused param.
+ * mach386-xdep.c (store_inferior_registers): Returns void.
+ * mach386-xdep.c (fetch_core_registers): Takes an unused parameter.
+ * main.c: Add prototypes for local functions.
+ * main.c (return_to_top_level): Is type NORETURN (volatile). Cast
+ longjmp() result to (NORETURN void).
+ * main.c (catch_errors): Prototype the 'func' parameter.
+ * main.c (disconnect, stop_sig, do_nothin, float_handler):
+ Takes an unused arg.
+ * main.c (execute_command): Call the right member of the func union.
+ * main.c (command_loop_marker, symbol_completion_function,
+ command_loop): Make static.
+ * main.c (command_line_input): Make linelength unsigned, cast arg
+ to command_line_input().
+ * main.c (add_info, add_com): Prototype the 'fun' parameter.
+ * main.c (initialize_main): Call right member of function union.
+ * mcheck.c (NOARGS): Change hardwired void in prototypes to NOARGS.
+ * mem-break.c: Include symtab.h
+ * mips-xdep.c (fetch_inferior_registers): Takes unused param.
+ * mips-xdep.c (store_inferior_registers): Returns void.
+ * mipsread.c (mipscoff_symfile_read): Change from misc function vector
+ use to minimal symbol table use.
+ * mipsread.c (symbol_obstack usages): Convert all to use per-objfile
+ version.
+ * mipsread.c (make_type): Remove, convert usages to init_type.
+ * mipsread.c (_initialize_mipsread): Call init_type with NULL objfile.
+ * nindy-tdep.c (nindy_frame_chain_valid): Convert from misc function
+ vector use to minimal symbol table use.
+ * parse.c: Add prototypes for local functions.
+ * parse.c (xrealloc usages): Cast args.
+ * parse.c (prefixify_expression, length_of_subexp): Make static.
+ * parser-defs.h (PARSER_DEFS_H): Define when first included.
+ * parser-defs.h: Convert function decls to prototype form.
+ * partial-stab.h: Convert from misc function vector use to new minimal
+ symbol table use.
+ * partial-stab.h (global_psymbols, static_psymbols usages): Reference
+ the per-objfile copies.
+ * printcmd.c: Add prototypes for local functions. Move some struct
+ definitions around to accomodate prototypes.
+ * printcmd.c (decode_format): Make static, change args oformat and
+ osize to int from char.
+ * printcmd.c (print_formatted): Change 'format' and 'size' to int.
+ * printcmd.c (print_scalar_formatted): Change arg 'format' to int.
+ * printcmd.c (print_address_symbolic): Convert from misc function
+ vector use to minimal symbol table use.
+ * printcmd.c (address_info): Convert from misc function vector use
+ to minimal symbol table use.
+ * printcmd.c (delete_display, enable_display, disable_display_command):
+ Make static.
+ * procfs.c (EXFUN/DEFUN): Remove all usages, convert to PARAMS.
+ * procfs.c (fetch_core_registers): Add unused param reg_addr.
+ * pyr-xdep.c (fetch_inferior_registers): Add unused param regno.
+ * pyr-xdep.c (store_inferior_registers): Returns void.
+ * remote-mm.c (mm_load): symbol_file_add return value unused.
+ * remote-nindy.c: Minor format change.
+ * remote-vx.c (vx_load_command): symbol_file_add result unused.
+ * rs6000-xdep.c (fetch_inferior_registers): Add unused param regno.
+ * rs6000-xdep.c (store_inferior_registers): Returns void.
+ * rs6000-xdep.c (fetch_core_registers): add unused param reg_addr
+ * rs6000-xdep.c (aixcoff_relocate_symtab): Convert from misc function
+ vector use to minimal symbol table use.
+ * solib.c: Add prototypes for local functions.
+ * solib.c (solib_add_common_symbols, locate_base): Convert from misc
+ function vector use to minimal symbol table use.
+ * solib.c (EXFUN/DEFUN): Remove all usages, convert to PARAMS.
+ * solib.c (find_solib, shared_library_command): Make static
+ * solib.c (read_memory, write_memory usages): Cast args.
+ * solib.c (special_symbol_handling): Add function
+ * source.c: Add prototypes for local functions.
+ * source.c (select_source_symtab): Convert to scan objfiles.
+ * source.c (open_source_file): Make static.
+ * source.c (xrealloc usages): Cast args.
+ * source.c (source_line_charpos): ifdef out, unused.
+ * source.c (get_filename_and_charpos): Make static.
+ * stack.c: Add prototypes for local functions.
+ * stack.c (print_frame_info, frame_info): Convert from misc function
+ vector use to minimal symbol table use.
+ * symfile.c: Add prototypes for local functions.
+ * symfile.c (compare_symbols): Make args const PTR's.
+ * symfile.c (compare_psymbols, sort_pst_symbols) add.
+ * symfile.c (sort_all_symtab_syms): Scan objfile list.
+ * symfile.c (obsavestring): Add objfile parameter.
+ * symfile.c (init_misc_bunches, prim_record_misc_function,
+ compare_misc_functions, discard_misc_bunches, condense_misc_bunches,
+ sort_misc_function_vector, compact_misc_function_vector): Remove
+ * symfile.c (symbol_file_add_digested): Add function.
+ * symfile.c (symbol_file_add): Returns struct objfile *.
+ * symfile.c (symbol_file_command): Modify for state file use.
+ * symfile.c (symfile_open): Add parameter "dumpable".
+ * symfile.c (allocate_objfile, free_objfile): Moved to objfiles.c
+ * symfile.c (load_command, add_symbol_file_command): Make static.
+ * symfile.c (fill_in_vptr_fieldno): Moved to gdbtypes.c
+ * symfile.c (rindex usages): Converted to strrchr.
+ * symfile.c (allocate_psymtab): New
+ * symfile.c (free_named_symtabs): Ifdef out code that needs to be
+ converted to minimal symbol table usage, but no obvious conversion.
+ * symfile.c (free_all_symtabs): Remove.
+ * symfile.c (_initialize_symfile): Use per-objfile info.
+ * symfile.h: Rework the objfile structure to add per-objfile data
+ objects (psymbol_obstack, symbol_obstack, type_obstack,
+ global_psymbols, static_psymbols, msymbols, minimal_symbol_count,
+ fundamental_types, malloc, realloc, free, xmalloc, xrealloc, etc).
+ Add prototypes to function declarations.
+ * symm-tdep.c (symmetry_extract_return_value): Convert from misc
+ function vector usage to minimal symbol table usage.
+ * symmisc.c (DEV_TTY): Define if not defined.
+ * symmisc.c: Add local function prototypes.
+ * symmisc.c (dump_objfile, dump_msymbols, dump-symtab, print_syms,
+ printpsyms_command, print_objfiles, print_objfiles_command):
+ Rework to use iterate_over_*
+ * symtab.c: Add prototypes for local functions.
+ * symtab.c (lookup_symtab_1): Convert to look through objfiles.
+ * symtab.c (lookup_partial_symtab): Scan through objfiles.
+ * symtab.c (lookup_primitive_typename, lookup_typename, lookup_
+ unsigned_typename, lookup_struct, lookup_union, lookup_enum,
+ lookup_template_type, lookup_struct_elt_type, lookup_pointer_type,
+ lookup_reference_type, lookup_member_type, allocate_stub_method,
+ check_stub_method, create_array_type, smash_to_member_type,):
+ Moved to gdbtypes.c
+ * symtab.c (lookup_symbol): Some args are const.
+ * symtab.h: All type related defs and structs moved to gdbtypes.h
+ * symtab.h: Convert decls to prototypes.
+ * target.c (noprocess): Make static.
+ * target.h: Change decl's to prototypes.
+ * tm-sunos.h: (CLEAR_SOLIB, SOLIB_ADD, SOLIB_CREATE_INFERIOR_HOOK,
+ DISABLE_UNSETTABLE_BREAK) Moved to solib.h.
+ * utils.c (_initialize_utils): Use correct member of function union.
+ * valarith.c: include gdbtypes.h
+ * valops.c: include gdbtypes.h, add prototypes for local functions.
+ * valops.c (value_push, value_arg_push, find_function_addr):
+ Make static.
+ * valops.c (value_string): Convert from misc function vector use
+ to minimal symbol table use.
+ * valops.c (check_field_in): Make arg const.
+ * valprint.c: Add prototypes for local functions.
+ * valprint.c (print_string): Make static
+ * valprint.c (value_print, val_print_fields, val_print): Make arg int.
+ * values.c: Add prototypes for local functions.
+ * values.c (value_headof): Convert from misc function vector to
+ minimal symbol table.
+ * xcoffexec.c: Add prototypes for local functions.
+ * xcoffexec.c (exec_close, file_command, add_to_section_table):
+ Make static.
+ * xcoffexec.c (relocate_minimal_symbol): Add.
+ * xcoffread.c (patch_block_stabs): Moved to buildsyms.c.
+ * xcoffread.c: Add prototypes for local functions.
+ * xcoffread.c (sort_syms): Convert to scan objfiles.
+ * xcoffread.c (read_xcoff_symtab): Make static.
+ * xcoffread.c (various): Replace references to builtin types with
+ calls to lookup_fundamental_type. Replace references to symbol_obstack
+ and psymbol_obstack with pointers to the per-objfile copies.
+ * xcoffread.c (dump_linetable, dump_type, dump_symbol, dump_namespace,
+ dump_block, dump_blockvector, dump_last_symtab, dump_symtabs):
+ Make static.
+ * xcoffread.c (init_stringtab): Add objfile parameter.
+ * gdbtypes.c: New file
+ * minsyms.c: New file
+ * mmap-alloc.c: New file
+ * mmap-sbrk.c: New file
+ * objfiles.c: New file
+ * state.c: New file
+ * state.h: New file
+
+Fri Feb 21 17:29:54 1992 John Gilmore (gnu at cygnus.com)
+
+ * Check in Fred Fish's changes in these modules. Fred
+ will make ChangeLog entries for all of them. Update VERSION
+ to 4.4.2.
+
+Thu Feb 20 18:10:17 1992 Fred Fish (fnf at cygnus.com)
+
+ * tm-sparc.h, tm-sysv4.h, solib.h: Move shared lib definitions
+ into solib.h.
+ * sparc-pinsn.c, sparc-tdep.c, standalone.c, sun3-xdep.c,
+ sun386-xdep.c, symm-xdep.c, target.c, ultra3-xdep.c, utils.c,
+ value.h: Prototypes for static functions; lint.
+ * gdbtypes.h: Empty file to ease transition.
+
+Thu Feb 20 16:43:13 1992 Fred Fish (fnf at cygnus.com)
+
+ * environ.h, expression.h, frame.h, gdbcmd.h, gdbcore.h,
+ inferior.h, language.h, signame.h, target.h, terminal.h,
+ tm-68k.h, tm-i386v.h, tm-sparc.h, tm-sun386.h, tm-symmetry.h,
+ xm-i386v.h, xm-sparc.h: Prototypes for all external functions.
+ Lint.
+ * core.c, exec.c, infrun.c, inftarg.c, language.c, remote.c,
+ signame.c, sparc-xdep.c: Prototypes for all static functions.
+ Lint.
+ * core.c, eval.c, exec.c, inftarg.c, remote-adapt.c, remote-eb.c,
+ remote-hms.c, remote-mm.c, remote-nindy.c, remote-vx.c, remote.c,
+ target.c, target.h, valarith.c, valops.c, value.h, xcoffexec.c:
+ Remove to_call_function and target_call_function, since it
+ always calls the same thing (call_function_by_hand).
+ * core.c, exec.c, solib.c: Rename target_ops sections =>
+ to_sections, etc.
+ * infcmd.c, inflow.c, infptrace.c, infrun.c, main.c, target.c,
+ target.h: target_kill takes no args.
+ * language.c (language_info): Scaffolding to allow briefer
+ messages when the current language changes. FIXME.
+ * xm-amix.h, xm-i386v4.h, xm-stratus.h: Define NORETURN to avoid
+ complaints about volatile functions.
+ * xm-sysv4.h (HAVE_MMAP): Define.
+
+Thu Feb 20 09:04:18 1992 Fred Fish (fnf at cygnus.com)
+
+ * defs.h: Include ansidecl.h and PARAMS macro. Use PARAMS
+ to make prototypes for all functions declared here.
+ * cplus-dem.c: Avoid declaring xmalloc and xrealloc.
+ * c-exp.y: Rename SIGNED, OR, and AND to avoid conflict.
+ * environ.c: Include <stdio.h> before defs.h. Minor cleanup.
+ * ieee-float.h: Use PARAMS for prototypes; make some params const.
+ * ieee-float.c, valarith.c: Include <stdio.h>. Lint. b*=>mem*.
+ * m2-exp.y: Remove unused CONST; Rename OR and AND.
+ * utils.c: Avoid declaring malloc and realloc. Lint.
+ (request_quit): Accept signal-number parameter.
+
+Mon Feb 17 07:13:27 1992 Fred Fish (fnf at cygnus.com)
+
+ * dwarfread.c (process_dies): Add case to handle TAG_pointer_type
+ DIE's. Add new function read_tag_pointer_type() to read them.
+
+ * dwarfread.c (dwarf_read_array_type, read_subroutine_type):
+ When creating a new user defined type, check to see if a partial
+ type already exists, and if so, bash it to fit.
+
+Fri Feb 14 19:00:17 1992 John Gilmore (gnu at cygnus.com)
+
+ * coffread.c (decode_base_type): Pass long, not union.
+ Fix by Eric Valette, ev@chorus.fr.
+
+Thu Feb 13 17:14:28 1992 Fred Fish (fnf at cygnus.com)
+
+ * elfread.c (elf_symtab_read): Fix code to correctly track
+ changes in bfd for absolute symbols.
+
+Thu Feb 13 12:43:29 1992 Stu Grossman (grossman at cygnus.com)
+
+ * xm-vaxbsd.h: Close off comment.
+
+Thu Feb 13 07:45:19 1992 Fred Fish (fnf at cygnus.com)
+
+ * xm-sysv4.h: Define NEED_POSIX_SETPGID.
+
+Fri Feb 7 11:51:12 1992 Per Bothner (bothner at cygnus.com)
+
+ * mips-tdep.c (mips_print_registers): Print correct register
+ number for double pseudo-registers.
+
+Fri Feb 7 07:56:05 1992 John Gilmore (gnu at cygnus.com)
+
+ * buildsym.c (read_struct_type): Avoid double-bump of parse ptr
+ in the op$::OPERATOR. case. From Steven McCanne,
+ <mccanne@horse.ee.lbl.gov>.
+
+ * exec.c (set_section_name): Pass arg to exec_files_info;
+ only call it if interactive. From Francis Kauth <fk@tv.tv.tek.com>.
+
+Thu Feb 6 17:41:32 1992 John Gilmore (gnu at cygnus.com)
+
+ * main.c (print_gdb_version): Copyright msg: only this year.
+ (cd_command): Avoid changing current_directory on error.
+
+Thu Feb 6 15:14:01 1992 Per Bothner (bothner at cygnus.com)
+
+ * mipsread.c (parse_partial_symbols): Handle dependencies
+ between partial symbol tables (when not doing stabs-in-ecoff).
+ (This used to be handled by parse_fdr, but parse_fdr was
+ incompatible with handling stabs-in-ecoff, so the code
+ was re-written to not use parse_fdr. Unfortunately,
+ the logic to handle dependencies was overlooked.)
+
+Thu Feb 6 11:51:39 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * coffread.c (read_enum_type): Use the size of a target int when
+ describing enum.
+ * defs.h: added new #define for TARGET_PTR_BIT, defaults to size
+ of target int.
+ * h8300-tdep.c, remote-hms.c, tm-h8300.h: too many changes to count
+ * symtab.c (lookup_reference_type, lookup_ptr_type): use
+ TARGET_PTR_BIT to determine size of a pointer
+ * values.c (unpack_long): when unpacking a REF or a PTR don't
+ assume the size of the type.
+
+Wed Feb 5 22:29:59 1992 John Gilmore (gnu at cygnus.com)
+
+ * mipsread.c (parse_symbol): Avoid clobbering enum pointer when
+ looking at its members. Improve guess between struct and union,
+ only assuming union if multiple members have offsets of zero.
+
+Tue Feb 4 18:05:44 1992 Per Bothner (bothner at cygnus.com)
+
+ * mipsread.c: Use (FP0_REGNUM-32) instead of magic number 6.
+ (This is just for clarity - and one day permitting us to
+ change FP0_REGNUM from 38 to 32, which would make more sense.)
+ * tm-mips.h: Added STAB_REG_TO_REGNUM macro, so that
+ register numbers in stabs-in-ecoff get handled correctly.
+
+Sat Feb 1 04:45:10 1992 Stu Grossman (grossman at cygnus.com)
+
+ * xm-vax.h, xm-vaxult.h, xm-vaxbsd.h, config/mh-vaxult,
+ config/mh-vaxbsd, configure.in: Split up config stuff for Vaxen
+ into BSD and Ultrix.
+
+Sat Feb 1 04:39:41 1992 John Gilmore (gnu at cygnus.com)
+
+ * dbxread.c (dbx_symfile_init): Call malloc, not xmalloc.
+
+Sat Feb 1 04:15:41 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in: Increment version to 4.4.1.
+ * main.c (print_gdb_version): Update copyright notice.
+
+Sat Feb 1 01:43:11 1992 Per Bothner (bothner at cygnus.com)
+
+ * mipsread.c: Prepend "struct " to the names of structure
+ types, and similarly for enums and unions. (This used
+ to be done, but got lost in the re-write to "guess" the
+ difference between enum/struct/union.)
+ Also, guess that a tag is an enum if the first member
+ has type btNil.
+
+Fri Jan 31 21:45:51 1992 Stu Grossman (grossman at cygnus.com)
+
+ * xm-vax.h: #ifndef ultrix around #include of endian.h and
+ limits.h (sigh).
+
+Fri Jan 31 00:05:01 1992 John Gilmore (gnu at cygnus.com)
+
+ * Projects: Patching executables is done.
+ * Makefile.in (VERSION): Roll to gdb-4.4.
+ * README, WHATS.NEW: Update for gdb-4.4.
+
+ * symfile.c (reread_symbols): Whenever we reread one object
+ file's symbols, we must restart the scan, because the object_files
+ chain has been permuted.
+
+ * exec.c (exec_files_info): Split out into print_section_info.
+ Print BFD filename of each section if it's not the default one.
+ * core.c (core_files_info): Call print_section_info.
+
+ * xm-vax.h: Include a few system header files whose definitions
+ must precede defs.h.
+ * language.c, language.h: Make some things const.
+ * expression.h, main.c: const spreads like ooze.
+
+ * mem-break.c (break_insn, break_insn_size): Use unsigned chars,
+ since BREAKPOINT values can be >0x80.
+
+Thu Jan 30 17:21:14 1992 Stu Grossman (grossman at cygnus.com)
+
+ * infrun.c, xm-i386sco.h: SCO needs to use setpgid().
+
+Thu Jan 30 01:04:23 1992 John Gilmore (gnu at cygnus.com)
+
+ * sparc-pinsn.c: Remove kludge for preferring architectures.
+ Remove #ifdef's for SORT_NEEDED. We need to sort the table, now
+ and forever. Add `add' instruction to the set that get checked
+ for a preceding `sethi' in order to print an absolute address.
+ Corresponding changes in ../include/opcode/sparc.h needed
+ to eliminate garbage instructions.
+
+Wed Jan 29 19:24:34 1992 Per Bothner (bothner at cygnus.com)
+
+ * mipsread.c (parse_partial_symbols): Make sure partial
+ symbols are created for external symbols (as used to be
+ the case). This is a bit of a pain with the mips-coff.
+ It uses a table which points to all of the external
+ symbols belonging to a particular FDR or psymtab.
+ Once we've generated this table, we might as well save
+ it, and then use it in psymtab_to_symtab_1 to find
+ the symbols to pass to parse_external().
+ * symfile.c, symfile.c: New function start_psymtab_common
+ to share the common parts of allocating a new psymtab
+ for dbxread, mipsread (and later dwarfread). Its code
+ was pulled out from start_psymtab in dbxread.c.
+ * dbxread.c (start_psymtab): Use start_psymtab_common().
+
+ * valprint.c (val_print): If there is an error when trying
+ to print a string, check to see if there really is a problem
+ by reading just one character. If that works, assume
+ things are ok.
+
+Wed Jan 29 18:58:43 1992 Stu Grossman (grossman at cygnus.com)
+
+ * sparc-pinsn.c (compare_opcodes): Make it prefer v6, v7,
+ cypress, v8 mnemonics in that order.
+
+Tue Jan 28 17:32:13 1992 Per Bothner (bothner at cygnus.com)
+
+ * sparc-pinsn.c: Put the qsort() back in.
+
+Mon Jan 27 18:51:03 1992 John Gilmore (gnu at cygnus.com)
+
+ * findvar.c (read_register, write_register): Handle machines
+ where REGISTER_TYPE is not the same size as "int".
+
+ Handle debug symbols in dynamically loaded (relocated) code:
+
+ * dbxread.c (read_ofile_symtab): Fix up N_CATCH better. Pass
+ offset to process_one_symbol.
+ (process_one_symbol): Take new offset parameter. Add it into
+ appropriate symbol types to relocate symbols to loaded addresses.
+ Handle all possible symbol types, and complain() about types that
+ we don't expect to see.
+ * mipsread.c (psymtab_to_symtab_1): Pass offset of zero to
+ process_one_symbol (FIXME, should pass real offset).
+
+ Misc bugfixes:
+
+ * breakpoint.c (resolve_sal_pc): Split out code to resolve a
+ sal's PC value.
+ (set_breakpoint, break_command_1, until_break_command,
+ catch_command_1, breakpoint_re_set_one): Use it.
+ * symtab.h (resolve_sal_pc): Declare.
+ * infcmd.c (jump_command): Use resolve_sal_pc.
+
+ * source.c (list_command): Shorten "FILE, line N" to "FILE:N".
+
+ * putenv.c (putenv): Avoid unportably casting pointers to unsigneds.
+
+ * c-exp.y (yylex): `this' and `template' are only tokens in C++.
+
+ * xm-convex.h, xm-hp300bsd.h, xm-isi.h, xm-merlin.h, xm-news.h,
+ xm-np1.h, xm-pn.h, xm-pyr.h, xm-rtbsd.h, xm-symmetry.h, xm-umax.h:
+ Remove MISSING_VPRINTF declaration, and superfluous "kgdb" defines.
+
+Mon Jan 27 15:46:21 1992 Stu Grossman (grossman at cygnus.com)
+
+ * dbxread.c (process_one_symbol): Make a first cut at handling
+ symbol tables generated by Sun's acc. (#ifdef'd out, FIXME.)
+
+ * symtab.c (find_pc_line): Fix stepping into and out of #included
+ files.
+
+Mon Jan 27 13:00:55 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (OPCODES): Remove OPCODES defs and refs. There is
+ no longer any need to copy ../include/opcode/* into gdb.
+
+Mon Jan 27 12:30:38 1992 John Gilmore (gnu at cygnus.com)
+
+ * ChangeLog, ChangeLog-9091: Split ChangeLog at 1992.
+
+Sun Jan 26 19:05:40 1992 Per Bothner (bothner at cygnus.com)
+
+ * valprint.c (type_print_base, type_print_method_args):
+ Print C++ constructor methods without bogus "return type."
+
+Sat Jan 25 15:57:59 1992 Fred Fish (fnf at cygnus.com)
+
+ * infptrace.c (child_xfer_memory): Parameter "target" should
+ be a pointer to a structure, not the entire structure.
+
+Fri Jan 24 01:30:27 1992 Fred Fish (fnf at cygnus.com)
+
+ * depend: Convert the couple of references to ansidecl.h that
+ used the local gdb version to use the ../include version.
+
+Thu Jan 23 22:24:43 1992 Fred Fish (fnf at cygnus.com)
+
+ * procfs.c
+ (child_xfer_memory): Takes pointer to a struct, not entire struct.
+ (inferior_proc_init): Fix non-ANSI version of args.
+ (attach): Call print_sys_errmsg with correct number of args.
+ (mappingflags): Make static, does not need to be global.
+
+ * i386-tdep.c (i386_frame_num_args): Takes a pointer to a struct
+ not the entire struct itself.
+
+ * valops.c (value_assign): Cast some args to modify_field() and
+ {read,write}_register_bytes() correctly.
+
+ * ansidecl.h: Removed, is duplicate of ../include/ansidecl.h
+
+ * Makefile.in (MALLOCSRC): Removed reference to removed local
+ copy of ansidecl.h.
+
+ * dwarfread.c (list_in_scope): Needs an initial value, use file
+ scope.
+
+Mon Jan 20 19:06:28 1992 Stu Grossman (grossman at cygnus.com)
+
+ * main.c (main): Make option_index local to keep new getopt happy.
+ main.c, solib.c, Makefile.in: Update copyright notices.
+
+Mon Jan 20 08:54:00 1992 Michael Tiemann (tiemann at cygnus.com)
+
+ * cplus-dem.c (cplus_demangle): Correctly demangle destructors.
+
+Sat Jan 18 17:17:45 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (HFILES): Add partial-stab.h.
+
+Sat Jan 18 16:45:01 1992 Fred Fish (fnf at cygnus.com)
+
+ * config/mh-stratus, config/mt-stratus, tm-stratus.h, xm-stratus.h:
+ New files for stratus. Not complete enough to actually build
+ on the Stratus machine; that awaits copyright assignment for
+ i860 changes.
+
+ * Makefile.in (USER_CFLAGS): Add macro specifically reserved
+ for getting custom flags into CFLAGS when doing makes.
+
+ * configure.in: Add config information for stratus.
+
+Thu Jan 16 00:51:46 1992 Fred Fish (fnf at cygnus.com)
+
+ * dbxread.c (process_one_symbol): Pass address of structure
+ to complain(), rather than the whole structure.
+
+Wed Jan 15 09:56:16 1992 Fred Fish (fnf at cygnus.com)
+
+ * solib.c (solib_add_common_symbols): Only compile in when not
+ using SVR4 style shared libraries.
+
+Tue Jan 14 22:34:00 1992 Fred Fish (fnf at cygnus.com)
+
+ * dwarfread.c (locval): Add offreg flag to indicate location
+ values that are computed off a base register.
+
+ * dwarfread.c (new_symbol): Rework TAG_global_variable and
+ TAG_local_variable cases to account for static variables
+ within function scopes.
+
+Tue Jan 14 12:28:52 1992 Stu Grossman (grossman at cygnus.com)
+
+ * inflow.c: remove #include <sys/dir.h>. Not necessary, and
+ doesn't exist on some systems.
+
+ * infrun.c (wait_for_inferior!!!!): Prevent gdb from hanging when
+ nexting over recursive function calls.
+
+ * target.c (target_read_string): Create this routine to read null
+ terminated strings from the target. It deals with running off the
+ end of memory elegantly as well. solib.c (find_solib): Use
+ target_read_string() to avoid problems with running off the end of
+ memory.
+
+ * inflow.c (child_terminal_info): #ifdef TIOCPGRP around lines
+ that reference pgrp_inferior.
+
+Mon Jan 13 14:57:11 1992 Per Bothner (bothner at cygnus.com)
+
+ * tm-mips.h: Removed BLOCK_ADDRESS_ABSOLUTE, now that
+ mips-tfile has been hacked to act more "traditionally."
+ * dbxread.c: Fixed typo in comment.
+
+Sun Jan 12 13:08:36 1992 Per Bothner (bothner at cygnus.com)
+
+ * mips-tdep.c (mips_skip_prologue): Add some number of
+ 'sw' instructions before 'addiu' adjusts the stack.
+
+Fri Jan 10 13:47:06 1992 Fred Fish (fnf at cygnus.com)
+
+ * dwarfread.c (start_symtab, end_symtab, scopecount, openscope,
+ freescope, buildblock closescope, record_line, add_symbol_to_list,
+ gatherblocks, make_blockvector): Extensive changes to switch
+ to generic symbol table building code in buildsym.c. Remove
+ scope tree structures and functions, symbol table building
+ functions, and lots of other small changes.
+
+ * dwarfread.c: Add new macros GCC_PRODUCER and STREQN. Remove
+ GCC_COMPILED_FLAG_SYMBOL and GCC2_COMPILED_FLAG_SYMBOL.
+
+Tue Jan 7 13:09:57 1992 Stu Grossman (grossman at cygnus.com)
+
+ * buildsym.c (cleanup_undefined_types): Add support for enums.
+ This fixes the 'GDB internal error. cleanup_undefined_types with
+ bad type' problem.
+
+Sun Jan 5 09:47:50 1992 Stu Grossman (grossman at cygnus.com)
+
+ * dbxread.c: detect gcc2 compilations.
+
+Thu Jan 2 15:07:41 1992 John Gilmore (gnu at cygnus.com)
+
+ * sparc-pinsn.c: Rename bitfields that overlap with macro names
+ in ../include/opcode/sparc.h.
+
+Wed Jan 1 04:29:00 1992 Fred Fish (fnf at cygnus.com)
+
+ * Makefile.in: Change tm-svr4.h to tm-sysv4.h. Change xm-svr4.h
+ to xm-sysv4.h. Split OPCODE_DIR into OPCODE_DIR1 and OPCODE_DIR2
+ to reflect actual locations of opcode files, so TAGS target will
+ be buildable.
+
+ * i386-tdep.c: Change an erroneous 'm68k' reference to 'i386'.
+
+ * i386-tdep.c (supply_fpregset, fill_fpregset): Remove m68k
+ code.
+
+ * m68k-tdep.c (supply_fpregset, fill_fpregset): Fix array
+ dereferencing to access the correct elements.
+
+ * valops.c (value_addr): Declare return type of external func
+ value_copy().
+
+ * xcoffread.c: Undefine next_symbol_text before redefining it.
+
+For older changes see ChangeLog-1991
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/ChangeLog-1993 b/gdb/ChangeLog-1993
new file mode 100644
index 00000000000..4aba2d330f4
--- /dev/null
+++ b/gdb/ChangeLog-1993
@@ -0,0 +1,7597 @@
+Fri Dec 31 14:33:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * nindy-share/nindy.c: Fix order of arguments to store_unsigned_integer
+ (second and third arguments were reversed).
+ (say): Use varargs.
+
+Fri Dec 31 12:13:47 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * remote-mips.c: Add timeout parameter to mips_request and
+ mips_receive_packet.
+ (callers): pass in mips_receive_wait except mips_initialize (where
+ we use it to clean up the kludge where we had been changing
+ mips_receive_wait temporarily) and mips_wait (where we pass in
+ -1 for no timeout).
+
+Fri Dec 31 14:33:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stack.c (print_block_frame_locals): Also print LOC_BASEREG variables.
+
+Fri Dec 31 06:55:38 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * symtab.c (find_methods): Call fprintf_symbol_filtered with DMGL_ANSI.
+
+Thu Dec 30 10:16:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * values.c (unpack_long): Fix garbled error message.
+
+ * remote-mips.c (mips_error): New function.
+ * remote-mips.c: Use it instead of error() most places.
+ * remote-mips.c (mips_receive_packet): New arg throw_error.
+ (mips_initialize): Use it not catch_errors.
+ * defs.h: Declare error_pre_print and warning_pre_print here...
+ * main.c: ...not here.
+
+ * breakpoint.c (breakpoint_chain): Make static.
+ * breakpoint.c, breakpoint.h (frame_in_dummy): New function.
+ * stack.c (print_frame_info): Use it.
+
+Thu Dec 30 07:41:36 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * exec.c (add_to_section_table): Check for SEC_ALLOC instead of
+ SEC_LOAD to handle .bss segments properly.
+
+Thu Dec 30 10:16:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infrun.c (wait_for_inferior): Enable code which assumes that if
+ we jump into the prologue from another function, then it was a
+ subroutine call. #if 0 AT_FUNCTION_START; the above code should
+ take care of this case.
+
+Wed Dec 29 12:32:08 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * valprint.c (val_print_string): Change chunksize from 200
+ to 8.
+
+ * symfile.c (generic_load): If no arguments, get file name
+ from get_exec_file.
+
+ * c-exp.y: Revert Kung's change. "..." is not a type, and the
+ change caused "p (...)0" to dump core.
+ * gdbtypes.c (check_stub_method): Don't pass "..." to
+ parse_and_eval_type. This should fix the bug which Kung was
+ trying to fix.
+
+ * stabsread.c (define_symbol): If we choose not to combine
+ two symbols, don't just ignore the second (LOC_REGISTER) one.
+ * printcmd.c (print_frame_args): If we have a LOC_ARG and a
+ LOC_REGISTER, use the LOC_ARG not the LOC_REGISTER.
+
+Tue Dec 28 15:08:00 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * solib.c (DEBUG_BASE): Remove macro and all references.
+ * solib.c (debug_base_symbols): Add array of symbols to lookup.
+ * solib.c (IGNORE_FIRST_LINK_MAP_ENTRY): Add macro.
+ * solib.c (look_for_base, locate_base): Use debug_base_symbols.
+ * solib.c (find_solib): Use IGNORE_FIRST_LINK_MAP_ENTRY.
+
+Tue Dec 28 12:06:57 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * c-exp.y : fix grammar to parse ellipsis (...)
+
+Mon Dec 27 18:42:14 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * stabsread.c (read_type): fix problem when reading static member
+ of a class. caused by change to allow :: inside template
+ instantiated name.
+
+Mon Dec 27 11:07:05 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbtypes.h: Expand on comments for TYPE_CODE_BITSTRING and
+ TYPE_CODE_STRING a bit.
+
+ * m68k-tdep.c (m68k_skip_prologue, m68k_find_saved_regs):
+ Allow pea %fp; move.l %sp, %fp instead of link instruction to
+ set up the new frame.
+
+ * main.c (init_main): Change "set remotedebug" back to var_zinteger
+ from var_boolean.
+
+ * c-exp.y (yylex): Don't try to deal with nested types.
+
+ * cp-valprint.c (cplus_print_value): Call check_stub_type on
+ TYPE_BASECLASS (type, i) before we look at its name.
+
+ * dbxread.c: Move default definition of GCC_COMPILED_FLAG_SYMBOL
+ from here . . .
+ * symtab.h: . . . to here.
+ * dbxread.c (record_minimal_symbol): Move check for gcc{,2}_compiled.
+ and __gnu_compiled* from here . . .
+ * minsyms.c (prim_record_minimal_symbol_and_info): . . . to here.
+ * minsyms.c (prim_record_minimal_symbol): Call
+ prim_record_minimal_symbol_and_info rather than duplicating code.
+ * minsyms.c, symtab.h (prim_record_minimal_symbol{,_and_info}),
+ coffread.c (record_minimal_symbol),
+ xcoffread.c (RECORD_MINIMAL_SYMBOL), callers: Add objfile parameter.
+
+Sun Dec 26 20:44:02 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * dbxread.c (process_one_symbol): Handle stabs-in-som just like
+ stabs-in-elf.
+ (pastab_build_psymtabs): Likewise.
+
+ * hppa-tdep.c: Change all comments to reference %r3 or frame
+ pointer rather than %r4.
+ (frame_chain, skip_prologue, dig_rp_from_stack): Handle %r3 as the
+ frame pointer.
+
+ * config/pa/tm-hppa.h (FP_REGNUM): Define as %r3.
+ (FIND_FRAME_SAVED_REGS): Handle %r3 as frame pointer.
+ (CALL_DUMMY): Likewise.
+
+Sun Dec 26 16:59:39 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * exec.c (exec_file_command): If error occurs after we have opened
+ exec_bfd but before we call push_target, make sure to close exec_bfd.
+
+ * infrun.c (wait_for_inferior): Remove confusing and inaccurate
+ stuff about subroutine calls, return, etc., from comment which
+ says "We've wandered out of the step range.".
+
+Sun Dec 26 09:18:10 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * infrun.c (wait_for_inferior): When checking whether the line has
+ changed, check the symtab as well.
+
+Sun Dec 26 09:18:10 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbtypes.c (force_to_range_type): Use switch statement.
+ complain() not warning() if the TYPE_CODE isn't one we know how to
+ deal with gracefully. Use builtin_type_int not
+ lookup_fundamental_type (the objfile we passed to
+ lookup_fundamental_type was sometimes NULL).
+
+ * valops.c (call_function_by_hand, push_word), defs.h (push_word),
+ convex-xdep.c, m88k-nat.c, i386m3-nat.c, mips-tdep.c, mipsm3-nat.c,
+ ns32km3-nat.c, remote-bug.c, m88k-tdep.c, remote-hms.c, remote-mips.c,
+ config/gould/tm-np1.h, hppa-tdep.c (hppa_fix_call_dummy), remote-vx.c:
+ Use REGISTER_SIZE, unsigned LONGEST, and
+ {store,extract}_unsigned_integer, instead of sizeof
+ (REGISTER_TYPE) and REGISTER_TYPE.
+ * All tm.h files: Change REGISTER_TYPE to REGISTER_SIZE.
+ * hppa-tdep.c (pa_print_fp_reg): Remove unused variable val.
+
+ * Makefile.in (ALLDEPFILES): Remove i386ly-nat.c and m68kly-nat.c.
+ Add lynx-nat.c.
+
+Sat Dec 25 20:05:41 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (init_extra_frame_info): Correctly adjust the base
+ of the current frame when "fromleaf" is true. Do not adjust the
+ frame base of the innermost frame if it is a leaf function.
+
+Sat Dec 25 13:39:21 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabsread.c (define_symbol): Only combine a p/r pair into a
+ LOC_REGPARM if REG_STRUCT_HAS_ADDR.
+
+Sat Dec 25 09:50:29 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * valops.c (value_struct_elt): Check for (value)-1 return from
+ search_struct_method.
+
+Sat Dec 25 09:50:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * defs.h: Move definitions of TARGET_*_BIT after include of tm.h.
+ The old way (using #undef in tm.h) was ugly and asking for
+ trouble, because it makes it possible for some file to use the
+ wrong definition. Move definition of HOST_CHAR_BIT after definition
+ of TARGET_CHAR_BIT.
+ * config/alpha/tm-alpha.h, config/h8300/tm-h8300.h,
+ config/h8500/tm-h8500.h, config/z8k/tm-z8k.h: Don't undef TARGET_*_BIT
+ before defining them.
+
+ * mdebugread.c: Change the builtin_type_* in this file to
+ mdebug_type_* and make them static. Use TYPE_CODE_ERROR for
+ complex and float decimal.
+
+ * printcmd.c (disassemble_command): Call wrap_here between printing
+ address and printing instruction.
+
+Fri Dec 24 14:23:57 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabsread.c (read_type): Don't fall through 'S' case (the case it
+ was falling though happened to do the right thing ("break;") but that
+ is hardly a good thing to assume).
+
+Tue Dec 21 13:32:02 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * ch-exp.y (match_dollar_tokens): Fix off-by-one bug.
+ * ch-lang.c (chill_is_varying_struct), ch-lang.h: New function.
+ * ch-lang.c (chill_printstr): Use double quotes, not single quotes.
+ * ch-typeprint.c (chill_type_print_base): Handle TYPE_CODE_BITSTRING.
+ Improve printing of TYPE_CODE_STRING, TYPE_CODE_SET, and
+ TYPE_CODE_STRUCT (including checking chill_is_varying_struct).
+ Print TYPE_DUMMY_RANGE by printing its TYPE_TARGET_TYPE.
+ Handle TYPE_CODE_ENUM.
+ * ch-valprint.c (chill_val_print): Handle TYPE_CODE_BITSTRING.
+ For TYPE_CODE_STRING, never print address. Handle VARYING strings.
+ * gdbtypes.c (force_to_range_type): New.
+ * gdbtypes.c (create_set_type): Make work, following Chill layout.
+ * gdbtypes.h (TYPE_LOW_BOUND, TYPE_HIGH_BOUND, TYPE_DUMMY_RANGE): New.
+ * stabsread.c (read_type): Distinguish string and bitstring from
+ char-array and set.
+ * valarith.c (value_subscript), valops.c (value_coerce_array):
+ Handle STRINGs as well as ARRAYs.
+ * valarith.c (value_bit_index): Fix think. Use new macros.
+
+
+Fri Dec 17 10:45:32 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * symtab (decode_line_1): fix a bug when position char is not
+ set correctly.
+ * c-valprint (c_val_print): handle vtbl printing when vtbl is not
+ set up yet.
+
+Thu Dec 16 16:46:01 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-tdep.c (read_next_frame_reg): If SIGFRAME_REG_SIZE is not
+ defined, define it as 4.
+
+Thu Dec 16 13:08:01 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/m68k/nm-hp300bsd.h: Correctly identify 4.3BSD vs 4.4BSD.
+
+ * config/m68k/tm-hp300bsd.h (REMOTE_BPT_VECTOR): Define.
+
+ * config/m68k/tm-m68k.h (REMOTE_BPT_VECTOR): Allow targets to
+ override.
+ (REMOTE_BREAKPOINT): Likewise.
+
+Thu Dec 16 09:14:58 1993 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c (read_hp_function_type): Correctly handle
+ pass-by-value structures > 64bits in size.
+ (process_one_debug_symbol): Likewise.
+
+Mon Dec 13 20:17:39 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ Implement support for Chill POWERSETs.
+ * ch-exp.y (operand_2): Implement 'Element IN PowerSet'.
+ * ch-typeprint.c (chill_type_print_base): Handle POWERSETs.
+ * ch-valprint.c (chill_val_print): Handle TYPE_CODE_SET.
+ * eval.c (evaluate_subexp): Implement BINOP_IN.
+ * expression.h (enum exp_opcode): Added BINOP_IN.
+ * gdbtypes.c (create_set_type), gdbtypes.h: New function.
+ * stabsread.c (read_type): If 'S', create a set type.
+ * valarith.c (value_bit_index, value_in), value.h: New functions,
+ for indexing in SETs.
+
+Mon Dec 13 06:42:37 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * paread.c (pa_symfile_init): Check for the existance of stabs
+ after DBX_TEXT_SECT has been initialized.
+
+Tue Nov 23 17:29:28 1993 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/h8300/tm-h8300.h (BREAKPOINT): Insn changed to sleep.
+ (DECP_PC_AFTER_BREAK): Now is 0.
+ * config/h8500/tm-h8500.h (REGISTER_BYTES, REGISTER_BYTE,
+ REGISTER_NAMES): update to new view. (INIT_EXTRA_FRAME_INFO): No
+ extra frame info now.
+ * config/sh/sh.h (NOP): Define NOP insn.
+ * config/z8k/tm-z8k.h (BIG): is now sim_z8001_mode.
+ * config/z8k/z8ksim.mt (TDEPFILES): Add remote-sim.o to list.
+ * ser-go32.c: Lint. (strncasecmp): Removed, now in libiberty.
+ (go32_readchar): Special handling for faster polling. (async
+ structure): Volatile.
+ * h8300-tdep.c (print_register_hook): Allocate and use the right
+ number bytes for the raw register.
+ * h8500-tdep.c (regoff, frame_find_saved_reg, examine_prologue):
+ deleted. (h8500_register_size, h8500_register_virtual_type, ):
+ Use new way of counting registers.
+ * remote-e7000.c (echo_index): deleted. (expect): Better handling
+ of user interrupts. (expect_prompt): Remove never used log file
+ support. (want, want_nopc): Add support for H8/300H.
+ (fetch_regs_from_dump): Treat \r and \n as whitespace.
+ (e7000_drain): Send an "end" command before waiting for output to
+ stop. (e7000_wait): Cope with H8/300H, better handling of user
+ interrupts. (why_stop, expect_n, sub2_from_pc): New function.
+ * remote-utils.c (gr_load_image): call fflush and QUIT more regularly.
+ * utils.c (notice_quit): New function for polling for user interrupts.
+
+Fri Dec 10 15:53:56 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * stabsread.c (read_array_type): Allow negative array bounds,
+ without interpreting that to mean "adjustable."
+ * ch-valprint.c (chill_val_print): Handle RANGE types.
+ * ch-typeprint.c (chill_type_print_base): Handle BOOL.
+ Handle variant records. Handle RANGE types.
+
+Tue Dec 7 15:41:32 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/mips/idt.mt: Use tm-idt.h instead of tm-bigmips.h.
+ * config/mips/idtl.mt: Use tm-idtl.h instead of tm-mips.h.
+ * config/mips/tm-idt.h, config/mips/tm-idtl.h: New files; use
+ different BREAKPOINT value for IDT.
+
+ * mipsread.c: Include bfd.h and coff/sym.h.
+
+Mon Dec 6 16:34:10 1993 K. Richard Pixley (rich@cygnus.com)
+
+ * ser-unix.c (set_tty_state): set the rest of the terminal state
+ pieces.
+
+Mon Dec 6 12:01:37 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in: Recognize mips* for all mips targets.
+ (mips*el-*-elf*, mips*-*-elf*): New targets; use idt and idtl.
+
+ Added Irix 5 support.
+ * configure.in (mips-sgi-irix5*): New host and target. Use irix5
+ for both.
+ * config/mips/irix5.mh, config/mips/irix5.mt,
+ config/mips/xm-irix5.h, config/mips/nm-irix5.h,
+ config/mips/tm-irix5.h, irix5-nat.c: New files for Irix 5 support.
+ * mdebugread.c: New file, split out of mipsread.c. Added
+ elfmdebug_build_psymtabs routine. Added some checks on external
+ symbols. Changed code to keep ecoff_debug_info and
+ ecoff_debug_swap structs in the psymtab and in global pointers
+ rather than retrieving them from the bfd. Also changed to keep
+ the pending list with the psymtab rather than the objfile (each
+ psymtab for a single objfile points to the same pending list).
+ * mipsread.c: Bulk of file moved into mdebugread.c, leaving just
+ the sym_fns.
+ * Makefile.in (SFILES): Added mdebugread.c.
+ (OBS): Added mdebugread.o.
+ (mdebugread.o): New target.
+ * symfile.h: Declare mdebug_build_psymtabs and
+ elfmdebug_build_psymtabs.
+ * elfread.c (struct elfinfo): Added mdebugsect field.
+ (elf_locate_sections): Remember location of .mdebug section.
+ (elf_symfile_read): Call elfmdebug_build_psymtabs on .mdebug
+ section.
+ * infrun.c (AT_FUNCTION_START): Set to 0 if not already defined.
+ (wait_for_inferior): Use AT_FUNCTION_START if it is defined to see
+ if PC is at the start of a function.
+ * mips-tdep.c (read_next_frame_reg): Use SIGFRAME_REG_SIZE, and
+ give it a default definition.
+ (mips_skip_prologue): Skip instructions which initialize $gp
+ register.
+ (in_sigtramp): New procedure, moved in from mipsread.c.
+ * config/mips/tm-mips.h: Declare in_sigtramp.
+
+ * serial.h (serial_fdopen): Make parameter const to match
+ function definition.
+
+Fri Dec 3 14:20:43 1993 Stu Grossman (grossman at cygnus.com)
+
+ * config/mips/irix4.mh: Enable ser-tcp.o.
+
+Tue Nov 30 15:24:24 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (check): Do not use subdir_do, so that
+ TARGET_FLAGS_TO_PASS is used correctly.
+
+Mon Nov 29 16:10:38 1993 Stu Grossman (grossman at cygnus.com)
+
+ * i386-nlmstub.c: Undo I/O redirection changes by Tom Lord.
+ These definitely won't work under Netware.
+
+Mon Nov 29 15:34:58 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * stabsread.c(read_struct_field): Fix the check when getting to
+ member functions.
+
+Mon Nov 29 16:48:16 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ gcc -Wall -O lint:
+ * mips-tdep.c (heuristic_proc_desc): Initialize reg30 to avoid
+ warning. Unnest comment.
+ (init_extra_frame_info): Remove unused variable mask.
+ (MASK): Fully parenthesize.
+ (mips_push_dummy_frame): Remove unused variable val.
+ (mips_skip_prologue): Remove unused variables f and b.
+
+Mon Nov 29 12:23:25 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mipsread.c (parse_symbol, parse_partial_symbols): Do not create
+ (partial) symbols for opaque struct definitions.
+
+Mon Nov 29 11:36:57 1993 Stu Grossman (grossman at cygnus.com)
+
+ * i386ly-tdep.c (i386lynx_saved_pc_after_call): Change call_inst
+ to unsigned char to avoid domain warning for some values.
+
+Mon Nov 22 23:42:59 1993 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * remote-e7000.c (e7000_wait): Cope with H8/300 register dump.
+ * config/h8300/h8300hms.mt: Add remote-e7000.
+
+Mon Nov 22 11:03:45 1993 Fred Fish (fnf@cygnus.com)
+
+ Merged changes from kev@spuds.geg.mot.com (Kevin A. Buettner):
+ * gdb/config/m88k/delta88.mh (NATDEPFILES): Added corelow.o and
+ coredep.o to this list.
+ * gdb/m88k-nat.c (m88k_register_u_addr): Avoid error when passed
+ the number for an M88110 extended register by just returning the
+ address of r0.
+
+Sat Nov 20 09:20:51 1993 Fred Fish (fnf@rtl.cygnus.com)
+
+ * go32-xdep.c (re_comp, re_exec): Remove stubs now that gdb
+ always uses it's own version of regex.
+
+Fri Nov 19 18:23:19 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * valops.c(value_struct_elt_for_reference): enhance search operator in
+ c++.
+ * symtab.c(decode_line_1): same as above.
+
+Fri Nov 19 15:08:47 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * symtab.c (decode_line_1): Add comment about use of
+ return_to_top_level directly instead of error. Add comment saying
+ that the '' should not be needed--that the completer should be fixed.
+
+Fri Nov 19 11:00:33 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * symtab.c(decode_line_1): fix the inconsistency of setting
+ breakpoint with '' or without them. The '' is needed when you
+ want name completion.
+
+Thu Nov 18 08:25:50 1993 Fred Fish (fnf@cygnus.com)
+
+ * valprint.c (val_print_string): When looking for a null
+ terminator compare current bufsize to fetchlimit to determine
+ when to stop, instead of computing buffer+fetchlimit which
+ may overflow for very large limits (like "unlimited").
+
+Wed Nov 17 18:23:09 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * eval.c(evaluate_subexp): to use unified search so type conversion
+ operator works in calling method.
+ * valarith.c(value_x_binop, value_x_unop): same as above.
+ * valops.c(search_struct_method): same as above.
+
+Wed Nov 17 18:47:34 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mipsread.c: Change use of ECOFF information to correspond to
+ changes in bfd/libecoff.h.
+ (mipscoff_symfile_offsets): Made static.
+
+Wed Nov 17 09:43:31 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * valops.c (typecmp): improve prototype matching when calling
+ a method. Make 'p (*(ostream *) &cout) << "lll" ' to work.
+ * eval.c(evalute_subexp): fix operator search problem when call
+ like p x.'operator+'(i).
+
+Tue Nov 16 17:15:03 1993 Stu Grossman (grossman at cygnus.com)
+
+ * i386ly-nat.c, i386lynx-nat.c, m68kly-nat.c: Remove. Move
+ common code into lynx-nat.c.
+ * lynx-nat.c: New module. Contains portable code for Lynx native
+ stuff (mostly ptrace related).
+ * config/i386/i386lynx.mh (NATDEPFILES): i386ly-nat.o -> lynx-nat.o
+ * config/m68k/m68klynx.mh (NATDEPFILES): i386ly-nat.o -> lynx-nat.o
+
+ * config/nm-lynx.h, config/tm-lynx.h: New files to contain
+ non-architecture specific native and target defs.
+ * config/i386/nm-i386lynx.h, config/i386/tm-i386lynx.h,
+ config/m68k/nm-m68klynx.h, config/m68k/tm-m68klynx.h: Move all
+ (arch) portable stuff into ../{tm nm}-lynx.h.
+
+Tue Nov 16 13:33:47 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * symtab.c (gdb_mangle_name): Only assume that the physname is
+ the entire mangled name if it looks like the mangled name of a
+ constructor. Needed for testsuite to work with GCC 2.4.5.
+
+ * a68v-nat.c: Replace with new version from Troy Rollo. The
+ version I am replacing appears to be an old copy of sun3-nat.c.
+ * dstread.c (dst_symfile_read): Replace sort_all_symtab_syms call
+ with loop.
+
+ * Makefile.in (TAGS): Depend on TAGFILES_{NO,WITH}_SRCDIR.
+
+ * Makefile.in: (HFILES,TAGFILES): Split into _WITH_SRCDIR and
+ _NO_SRCDIR versions.
+ (TAGS): Only add srcdir to TAGFILES_NO_SRCDIR.
+ (This is part of a long saga involving me putting srcdir on
+ everything (perhaps for now-obsolete reasons, I forget), Rich
+ removing the srcdir from everything, Stu putting it back some
+ places for Sun make, and me just now getting around to fixing
+ `make TAGS' again).
+
+Mon Nov 15 12:29:10 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * stack.c(print_frame_info): print demangled function name
+ ansi style.
+
+Mon Nov 15 14:32:29 1993 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * remote-e7000.c: New file to cope with the Hitachi E7000 ICE.
+ * remote-utils.c, remote-utils.h (gr_load_image): New function to
+ download to target.
+ * h8300-tdep.c, h8500-tdep.c, remote-z8k.c, sh-tdep.c z8k-tdep.c
+ (sim_load): delete.
+ * remote-sim.c (gdbsim_load): Use gr_load_image, rather than
+ sim_load.
+ * config/sh/sh.mt: Add remote-e7000
+
+Mon Nov 15 11:38:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/i386/linux.mh: Remove XM_CLIBS, TERMLIB, SYSV_DEFINE, and
+ REGEX.
+ * config/i386/xm-linux.h: Don't include xm-i386v.h. Define
+ HOST_BYTE_ORDER ourselves. Define HAVE_TERMIOS not HAVE_TERMIO.
+ Define NEED_POSIX_SETPGID. Include unistd.h.
+
+Mon Nov 15 12:29:10 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * symtab.c(gdb_mangle_name): fix the problem with constructor
+ name mangling.
+
+Mon Nov 15 11:38:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbtypes.h: Add TYPE_FLAG_TARGET_STUB.
+ * gdbtypes.c (check_stub_type): On TYPE_FLAG_TARGET_STUB, do
+ what cleanup_undefined_types does for arrays, except we clear
+ TYPE_FLAG_TARGET_STUB if we fix up the type.
+ * stabsread.c (cleanup_undefined_types): Add comments about how
+ doing arrays here is no longer the clean way to do it.
+ (read_array_type): Set TYPE_FLAG_TARGET_STUB as well as calling
+ add_undefined_type.
+ * c-typeprint.c, ch-typeprint.c: Move call to check_stub_type
+ outside switch so it happens for all type codes.
+ * cp-valprint.c (cp_print_value_fields): Recurse to val_print,
+ instead of c_val_print, so that check_stub_type gets called.
+
+ * gdbtypes.h, gdbtypes.c, m2-lang.c, ch-lang.c, c-lang.c: Remove
+ TYPE_FLAG_SIGNED. It was inconsistently set, never checked
+ (except in recursive_dump_type), and is pointless.
+
+Mon Nov 15 00:40:38 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * paread.c (pa_symfile_init): Look for the $TEXT$ section rather
+ than the .text section.
+
+Sun Nov 14 00:28:13 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabsread.c: Remove #if 0'd dbx_class_complaint. We now handle
+ this (more or less) gracefully, and complain() was never a good
+ way of dealing with this.
+
+ * stabsread.c (read_type): Skip the colon when reading a
+ cross-reference. Only complain, not error_type, on unrecognized
+ cross-reference types. error_type, not dump core, if the colon is
+ missing.
+
+Fri Nov 12 16:23:08 1993 Stu Grossman (grossman at cygnus.com)
+
+ * config/m68k/tm-sun3.h: Disable use of alternate breakpoint insn
+ when doing remote stuff.
+
+Fri Nov 12 16:22:39 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * c-exp.y (yylex): Call lookup_symtab not lookup_partial_symtab.
+
+ * partial-stab.h: Ignore ':' symbol descriptors. Same case as
+ Kung's stabsread.c change.
+
+Fri Nov 12 11:18:02 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * stabsread.c (patch_block_stabs, define_symbol, read_type): in
+ g++ template instantiation, nested class can be part of the
+ params, and '::' can gets into symbol or type names. This is
+ to fix the problem.
+
+ * gdbtypes.c (lookup_struct_elt_type): Handle type ref or pointer
+ to struct/union case.
+
+Fri Nov 12 10:39:31 1993 Stu Grossman (grossman at cygnus.com)
+
+ * coff-solib.c (coff_solib_add): Cast result of alloca().
+ * m68k-tdep.c (m68k_saved_pc_after_call): Get rid of
+ GDB_TARGET_IS_SUN3. Use more general SYSCALL_TRAP macro.
+ * config/m68k/m68klynx.mh (NATDEPFILES): Remove exec.o (it's
+ already in TDEPFILES).
+ * config/m68k/tm-m68k.h (SAVED_PC_AFTER_CALL): Use
+ m68k_saved_pc_after_call.
+ * Remove all Sun3 specific stuff.
+ * (FIX_CALL_DUMMY): Cast arg to bfd_putb32 to unsigned char *.
+ * config/m68k/tm-m68klynx.h: Define SYSCALL_TRAP as trap #10.
+ Disable REMOTE_BREAKPOINT mechanism.
+ * config/m68k/tm-sun3.h: Get rid of GDB_TARGET_IS_SUN3.
+ * Protect from multiple includion.
+ * Move Sun3 specific stuff from tm-m68k.h to here.
+ * Define SYSCALL_TRAP as trap #0.
+ * Remove def of SAVED_PC_AFTER_CALL (now in tm-m68k.h).
+ * gdbserver/low-lynx.c: Redo all register store/fetch stuff to
+ make it portable for 386 and 68k.
+
+Fri Nov 12 09:53:26 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * mips-tdep.c (init_extra_frame_info): Check to see whether the
+ registers mentioned in the proc_desc have been saved. This
+ generalizes mips_in_lenient_prologue in the sense that we keep
+ searching until we've found saves for all the registers, not just
+ look for a "lenient prologue" pattern.
+ * mips-tdep.c: #if 0 lenient prologue code.
+
+ * mips-tdep.c (heuristic_proc_desc): Don't assume a host short
+ is 16 bits.
+
+Thu Nov 11 19:58:05 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/i386/i386sol2.mh: Comment out corelow.o.
+
+ * printcmd.c (address_info): Use filtered, not unfiltered functions.
+ We should be able to deal with a QUIT here.
+
+Thu Nov 11 15:22:20 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * printcmd.c (address_info): Use fprintf_symbol_filtered
+ to print the symbol name.
+
+ * stabsread.c (define_symbol): Handle cfront lossage for
+ struct/union/enums and typedefs.
+
+ * partial-stab.h (case N_BINCL): Update psymtab_language
+ as appropriate when changing subfiles.
+ (case N_SOL): Update psymtab_language as appropriate when
+ changing subfiles. Add typedef for structs, unions, and enums
+ when processing C++ files.
+
+Thu Nov 11 13:18:47 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * README: Remove information on languages and just cite the (newly
+ updated) information in doc/gdb.texinfo instead.
+
+ * delta68-nat.c: Fix typos (add missing ");" and stuct -> struct).
+
+Wed Nov 10 09:31:10 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dbxread.c (process_one_symbol, N_RBRAC): Don't clear
+ within_function just because local_symbols is NULL. It appears
+ that this bug has existed since the 10 Apr 89 change which started
+ clearing within_function here.
+
+ * config/m68k/tm-m68k.h: Clean up CALL_DUMMY comment.
+ * config/m68k/{tm-hp300bsd.h,tm-hp300hpux.h,tm-m68k-em.h,
+ tm-monitor.h,tm-sun3.h,tm-vx68.h}, config/sparc/tm-sparc.h:
+ Define BELIEVE_PCC_PROMOTION.
+ * dbxread.c: Remove BELIEVE_PCC_PROMOTION define. The code which
+ used this was moved to stabsread.c a long time ago.
+
+ * dstread.c (dst_sym_fns): Update for flavours.
+ * symfile.c (find_sym_fns): Add kludge for apollo like for rs/6000.
+ * dstread.c (dst_symfile_offsets): Set objfile->num_sections.
+
+ gcc -Wall lint:
+ * thread.c: Include "gdbcmd.h" and <ctype.h>.
+ * Makefile.in: Update dependency.
+ * thread.c (thread_command): Remove unused variable p.
+ * values.c (unpack_double): Use len instead of TYPE_LENGTH (type).
+ * valprint.c (print_floating): Correctly check sign bit now that
+ we are using unsigned arithmetic.
+ * symtab.c (find_pc_line_range): Remove unused variables exact_match,
+ ind, and l.
+
+Tue Nov 9 17:42:25 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * valarith.c (value_x_binop): fix search operator in class bug
+ * valarith.c (value_x_unop): fix search operator in class bug
+
+Tue Nov 9 19:20:17 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (init.c): Add udi2go32.o to list of files that we
+ should not try to search for _initialize_* functions.
+
+ * remote-udi.c (udi_wait): Change UDIGdb_StdoutReady back to
+ UDIStdoutReady. It accidentally got changed on 24 Oct 93 when
+ stdout was changed to gdb_stdout. Likewise for UDIGetStdout,
+ UDIStderrReady, and UDIGetStderr.
+
+Tue Nov 9 12:48:06 1993 Tom Lord (lord@cygnus.com)
+
+ * remote-hms.c (hms_wait): fixed too many arguments to putc_unfiltered.
+
+Tue Nov 9 12:20:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * utils.c (quit): Also call gdb_flush on standard output and error.
+
+ * .gdbinit: Remove "source /.gdbinit". It causes a spurious error
+ if /.gdbinit doesn't exist (and I know of no convention of putting
+ something in /.gdbinit).
+
+Mon Nov 8 18:17:11 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * cp-valprint.c (cp_print_value_fields): change output from <no
+ value> to <optimized out or zero length>
+
+Mon Nov 08 17:05:30 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * Makefile.in: Change RUNTEST_FLAGS back to RUNTESTFLAGS
+ Change RUNTEST = runtest to test for existance of
+ a runtest in the source tree first.
+
+Mon Nov 8 10:42:03 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in: Remove unused variable GCC. Remove "#CC=cc" line
+ which doesn't really relate to anything.
+
+ * Makefile.in (CC_FOR_TARGET): Test for existence of gcc/xgcc, not
+ for existence of gcc/Makefile.
+
+ * inflow.c (terminal_init_inferior), infptrace.c (child_resume):
+ Add comments about use of Lynx PIDGET and how we will want to
+ clean it up.
+
+ * stabsread.c: Remove long_kludge_name code (it was already #if 0).
+ * stabsread.c (read_one_struct_field): Clean up comments to reflect
+ Kung's change of 5 Nov 93.
+ * stabsread.c (read_one_struct_field): Don't give up on unknown
+ visibility character, just shove it in fip->list->visibility.
+ (read_baseclasses): Don't give up on unknown virtual or visibility
+ characters, just assume a reasonable default, complain, and keep
+ going.
+ (attach_fields_to_type): Complain on unrecognized visibility.
+ One result of all this is that '9' (VISIBILITY_IGNORE) can be used
+ in a stab as well as being something which GDB uses internally.
+
+Mon Nov 8 07:57:30 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * configure.in: Remove h8300h, we have multilib now.
+
+Mon Nov 8 06:11:24 1993 D. V. Henkel-Wallace (gumby@cirdan.cygnus.com)
+
+ * configure.in: Add unixware as a configuration alias for x86
+ sysv4
+
+ * config/i386/i386nw.mt: add i387-tdep.o, exec.o to TDEPFILES
+
+Sun Nov 7 23:49:21 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * symtab.c (decode_line_1, decode_line_2): Do not adjust pc by
+ FUNCTION_START_OFFSET if funfirstline is not set.
+
+Fri Nov 5 17:19:30 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * gdbtypes.h : add a field 'ignore_field_bits in cplus_specific,
+ and macros to handle the bits.
+ * stabsread.c (read_one_struct_field): add VISIBILITY_IGNORE, and
+ for field of length 0, set this bit on.
+ * cp-valprint.c (cp_print_value_fields): for VISIBILITY_IGNORE
+ field, print <no value>.
+
+Fri Nov 5 14:43:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Version 4.11.2.
+
+Fri Nov 5 09:49:22 1993 Stu Grossman (grossman at cygnus.com)
+
+ * inflow.c (terminal_init_inferior): Temporarily use Lynx PIDGET
+ macro to set process groups.
+ * infptrace.c (child_resume): Temporarily use Lynx PIDGET to
+ specify resumption of all threads.
+ * infrun.c (wait_for_inferior): Fix handling of thread-specific
+ breakpoints for systems where DECR_PC_AFTER_BREAK > 0 (ie: backup
+ PC by the right amount when continuing the thread).
+ * thread.c (thread_apply_command): Add the `thread apply'
+ command to apply a given GDB command to a list of threads.
+
+Fri Nov 5 05:58:03 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Makefile.in (init.c): Don't call sed if filename is empty.
+
+Thu Nov 4 08:27:24 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dbxread.c (unknown_symchar_complaint): Make message refer to
+ "symbol descriptor" not "symbol type character" for consistency
+ with stabs.texinfo terminology.
+
+ * stabsread.c (read_struct_fields): Accept either '$' or '.' as
+ the character which introduces a cpp_abbrev or anonymous type.
+
+ * c-lang.c (c_printstr): Print "" to stream (like all the other
+ output from this function), not gdb_stdout.
+
+ * dbxread.c (process_one_symbol): Do relocate 'S' symbols by
+ the text offset (revert 12 Oct 93 change).
+
+ * configure.in: Make hppa*-*-hiux* use hppahpux,
+ not non-existent hppahiux.
+
+Wed Nov 3 16:24:09 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * values.c (value_fn_field): when physical name not found, do not
+ error, but return null.
+ * valops.c (value_struct_elt): when name and args match does not
+ mean it is the one, some times a typedef class can have the same
+ member method and args. This probably will not happen with new
+ version of g++, but it does happen in old g++ and cause gdb error.
+
+Wed Nov 3 09:20:18 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ Merge changes for dos x udi:
+ * Makefile.in (udi2go32.o): add rule to build this file
+ * 29k-share/udi/udi2go32.c: new file
+ * config/a29k/a29k-udi.mt: add udi2go32.o
+ * 29k-share/udi/{udr.c, udip2soc.c}: #ifdef out the entire file
+ if __GO32__ is defined. What a hack.
+
+Wed Nov 3 09:20:18 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote.c (putpkt, getpkt): Don't call interrupt_query.
+
+ * findvar.c (value_of_register): Rename val to reg_val to avoid
+ name conflict with some (e.g. tm-m68k.h) REGISTER_CONVERT_TO_VIRTUAL.
+
+ * main.c: Add variables source_line_number, source_file_name,
+ source_error, source_error_allocated, and source_pre_error.
+ (command_line_input): If source_file_name set, increment
+ source_line_number and set error_pre_print with them.
+ (source_command): Set source_* and make a cleanup so they get
+ set back.
+
+Tue Nov 2 16:28:34 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stack.c (down_silently_command): Add comment about PR 1913.
+
+ * breakpoint.c (insert_breakpoints, delete_breakpoint): Call
+ target_terminal_ours_for_output before attempting output.
+
+ * fork-child.c (fork_inferior): Fix comment so that it suggests
+ "set shell" rather than having "set env SHELL" affect GDB's
+ operation.
+
+Tue Nov 2 15:03:08 1993 Tom Lord (lord@rtl.cygnus.com)
+
+ * utils.c (vfprintf_unfiltered): don't use maybe_filtered
+ since it involves a fixed size buffer.
+
+Tue Nov 2 13:42:30 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * findvar.c (value_of_register, value_from_register),
+ hppa-tdep.c (pa_print_fp_reg), infcmd.c (do_registers_info),
+ valops.c (value_assign): Use REGISTER_CONVERT_TO_* only if
+ REGISTER_CONVERTIBLE is defined, otherwise just copy the content.
+ Pass desired type to REGISTER_CONVERT_TO_*.
+
+ * config/m68k/tm-m68k.h, config/i960/tm-i960.h (REGISTER_CONVERT_*):
+ Pass length of desired type to store/extract_floating.
+ * config/i386/tm-arm.h, config/i386/tm-i386aix.h,
+ config/i386/tm-sun386.h, config/i386/tm-symmetry.h,
+ config/m88k/tm-m88k.h config/rs6000/tm-rs6000.h (REGISTER_CONVERT_*):
+ Use extract_floating and store_floating with length of desired type.
+ * config/m68k/tm-news.h (STORE,EXTRACT_RETURN_VALUE): Add type
+ parameter to REGISTER_CONVERT_*.
+
+ * config/a29k/tm-a29k.h, config/convex/tm-convex.h,
+ config/gould/tm-np1.h, config/gould/tm-pn.h, config/h8300/tm-h8300.h,
+ config/h8500/tm-h8500.h, config/i386/tm-i386v.h,
+ config/mips/tm-mips.h, config/ns32k/tm-merlin.h,
+ config/ns32k/tm-umax.h, config/pa/tm-hppa.h, config/pyr/tm-pyr.h,
+ config/sh/tm-sh.h, config/sparc/tm-sparc.h, config/tahoe/tm-tahoe.h,
+ config/vax/tm-vax.h, config/z8k/tm-z8k.h (REGISTER_CONVERTIBLE,
+ REGISTER_CONVERT_TO_RAW, REGISTER_CONVERT_TO_VIRTUAL): Remove
+ versions for which REGISTER_CONVERTIBLE is always false.
+ * z8k-tdep.c (register_convert_to_virtual, register_convert_to_raw):
+ Remove, no longer used.
+
+ * alpha-tdep.c (alpha_register_convert_to_raw,
+ alpha_register_convert_to_virtual): New routines to handle
+ the different raw formats in alpha floating point registers.
+ * config/alpha/tm-alpha.h (REGISTER_CONVERTIBLE,
+ REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW): Use them.
+
+Tue Nov 2 12:45:23 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * gdbserver/configure.in: Recognize *-*-lynxos* instead of
+ *-*-lynx*, recognize sparc-*-lynxos*.
+ * gdbserver/Makefile.in (install, install_only): Add.
+ * gdbserver/gdbserver.1: New file, man page for gdbserver.
+
+Tue Nov 2 03:01:01 1993 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c: Include <time.h> and <sys/types.h>. Change include
+ of "libhppa.h" to "som.h".
+ (BYTES_IN_WORD): Define.
+ (hppa_sym_fns): "hppa" is 4 characters, not 5.
+
+Mon Nov 1 09:40:21 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * symtab.c, symtab.h, source.c: Change find_line_pc_range to take
+ a struct symtab_and_line argument, rather than a symtab and a line.
+ Re-write it to be based on the address rather than bogusly adding
+ one to the line number and hoping that has something to do with the
+ end of the line.
+
+ * config/m88k/m88k.mh (NATDEPFILES): Remove exec.o.
+
+ * paread.c (pa_symtab_read): Change comments to say ignoring
+ labels really should be handled by the assembler/compiler.
+
+ * Makefile.in: Add -O to CXXFLAGS.
+
+ * TODO: Expand comments on fast watchpoints.
+
+Sun Oct 31 19:45:06 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * paread.c (pa_symtab_read): Also filter out local symbols
+ starting with "L$".
+
+Sun Oct 31 09:28:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * symfile.h (sym_fns), symfile.c (find_sym_fns), xcoffread.c,
+ coffread.c, dbxread.c, elfread.c, mipsread.c, nlmread.c, paread.c:
+ Change from using bfd target name to using the flavour.
+
+ * objfiles.h, infcmd.c, symfile.c: Add comments about how various
+ objfiles get created and when we should blow them away.
+
+Sat Oct 30 08:32:53 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * symfile.c (reread_symbols): When re-reading symbols, do all the
+ right operations ourself, rather than calling symbol_file_command.
+ If we re-read something, call clear_symtab_users not just
+ breakpoint_re_set.
+ * objfiles.h, objfiles.c (build_objfile_section_table): No longer
+ static.
+ * symfile.c (clear_symtab_users): Call clear_pc_function_cache.
+ * coffread.c, dbxread.c, elfread.c, mipsread.c, nlmread.c, paread.c
+ (*_symfile_offsets): Set objfile->num_sections.
+ * remote.c (remote_wait), symfile.c (syms_from_objfile):
+ Don't muck with objfile->num_sections now that all the symbol
+ readers set it.
+ * elfread.c: Clean up obsolete comment about handling only DWARF.
+ * paread.c: Remove comment about how we should use an "ordinary"
+ file format with an hppa suffix. There is nothing ordinary about SOM.
+
+ * config/i386/{i386m3.mh,i386mk.mh}, config/mips/mipsm3.mh,
+ config/ns32k/ns32km3.mh: Change MMALLOC_LIB to MMALLOC.
+ * TODO: Update Mach stuff.
+
+Fri Oct 29 16:30:36 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ LynxOS support:
+ * configure.in: Change *-*-lynx* to *-*-lynxos*, add
+ sparc-*-lynxos*.
+ * Makefile.in (ALLDEPFILES): Add m68kly-nat.c, sparcly-nat.c.
+ Rename i386lynx-nat.[co] to i386ly-nat.[co].
+ (ALLCONFIG): Add config/{m68k,sparc}/{m68k,sparc}lynx.m[ht].
+ (m68kly-nat.o, sparcly-nat.o): Add rules.
+ * i386ly-tdep.c: Cosmetics.
+ * i386lynx-nat.c: Removed.
+ * i386ly-nat.c: New file, was i386lynx-nat.c.
+ * m68kly-nat.c: New file.
+ * sparcly-nat.c: New file.
+ * config/xm-lynx.h: New file, cpu-independent host info.
+ * config/i386/i386lynx.mh: Changes for consistency.
+ * config/i386/i386lynx.mt: Ditto.
+ * config/i386/tm-i386lynx.h: Ditto.
+ * config/i386/nm-i386lynx.h: Ditto.
+ * config/i386/xm-i386lynx.h: Include config/xm-lynx.h.
+ * config/m68k/m68klynx.mh, config/m68k/m68klynx.mt,
+ config/m68k/tm-m68klynx.h, config/m68k/nm-m68klynx.h,
+ config/m68k/xm-m68klynx.h: New files, M68K LynxOS support.
+ * config/sparc/sparclynx.mh, config/sparc/sparclynx.mt,
+ config/sparc/tm-sparclynx.h, config/sparc/nm-sparclynx.h,
+ config/sparc/xm-sparclynx.h: New files, Sparc LynxOS support.
+
+Fri Oct 29 08:11:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * defs.h, findvar.c (extract_floating, store_floating): New functions.
+ * Move SWAP_TARGET_AND_HOST from defs.h to findvar.c because it is
+ now used only by extract_floating and store_floating.
+ * valprint.c (print_floating): Use unsigned arithmetic. Use
+ extract_unsigned_integer instead of SWAP_TARGET_AND_HOST.
+ Change sizeof (float) to 4 and sizeof (double) to 8 (those are always
+ the relevant sizes for this code, which is in #ifdef IEEE_FLOAT).
+ * values.c (unpack_long, unpack_double, value_from_double),
+ valarith.c (value_binop), stabsread.c (define_symbol):
+ Use extract_floating and store_floating instead of
+ SWAP_TARGET_AND_HOST.
+ * config/m68k/tm-m68k.h, config/i960/tm-i960.h (REGISTER_CONVERT_*):
+ Use extract_floating and store_floating.
+ * config/m88k/tm-m88k.h: Add comments (it should be doing the same).
+ * i386-tdep.c (i386_extract_return_value),
+ * remote-nindy.c (nindy_store_registers): Use store_floating.
+
+Fri Oct 29 09:31:38 1993 Steve Chamberlain (sac@rtl.cygnus.com)
+
+ * remote-sim.c (gdbsim_store_register): Change var name so
+ it compiles with non-ANSI compilers.
+
+Fri Oct 29 08:11:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Add idea for "disassemble" with source.
+
+Fri Oct 29 00:41:01 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.11.1 after release and cvs
+ tagging.
+
+Thu Oct 28 09:14:42 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Add section on Mach. Stop calling it a "bug list".
+ Remove John's name and email address. Remove item on "always"
+ ("hook-stop" takes care of this). Remove item on executables with
+ no symbols (this works on some machines, at least). Remove item
+ about calling error() during symbol reading (I think all the important
+ ones have been cleaned up). Revise items about signals and remote
+ systems. Remove section on ^Z requiring several continues to make
+ it go (this now works. Perhaps the item is based on confusion over
+ programs (like GDB itself) which catch SIGTSTP and then re-send
+ themselves the signal. PR 2575 might contain relevant info).
+
+Thu Oct 28 16:55:34 1993 Fred Fish (fnf@cygnus.com)
+
+ * NEWS: Note improvements in C++ support, preliminary thread
+ implementation, and LynxOS native and target support for 386.
+
+Thu Oct 28 16:55:34 1993 Fred Fish (fnf@cygnus.com)
+
+ * README: Add note from Peter Schauer about OSF/1 shared
+ libraries. Add note from Pace Willisson about configuring on BSDI
+ BSD/386 release 1.0. Update gdb references to gdb 4.11.
+
+Thu Oct 28 09:14:42 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * NEWS: Add notes about Alpha and "set remotedebug" for UDI.
+
+ * valops.c (value_assign): Change bitfield code to use a buffer of
+ the correct size, rather than an int.
+
+Wed Oct 27 13:43:07 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/i386/{i386m3.mt,i386m3.mh},
+ config/mips/{mipsm3.mt,mipsm3.mh},
+ config/ns32k/{ns32km3.mt,ns32km3.mh}: Use correct names for TM_FILE
+ and XM_FILE. Replace host files *mach3-xdep.o with native
+ files *m3-nat.o. Replace host file os-mach3.o with native
+ file m3-nat.o.
+
+ * remote-udi.c: Remove LOG_FILE stuff; superceded by "set remotedebug".
+ * remote-mon.c: Remove commented out "set remotedebug" command.
+ * remote-nindy.c: Clean up comment about wanting alternative to
+ options specified on the GDB command line.
+
+ * fork-child.c (fork_inferior): Set inferior_pid before calling
+ init_trace_fun. Move the code which gets us through the shell
+ to new function startup_inferior.
+ * inferior.h: Declare startup_inferior.
+ * procfs.c (procfs_init_inferior), inftarg.c (ptrace_him):
+ Call startup_inferior.
+ * m3-nat.c (m3_trace_him): Call intercept_exec_calls.
+ * config/nm-m3.h: Don't define STARTUP_INFERIOR.
+ * config/i386/tm-i386m3.h, config/ns32k/tm-ns32k.h,
+ config/mips/tm-mipsm3.h: Don't define START_INFERIOR_TRAPS_EXPECTED.
+
+ * m68k-stub.c: Change vector 13 from SIGFPE to SIGBUS.
+
+Tue Oct 26 22:05:03 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * mips-tdep.c (mips_pop_frame): If proc_desc is NULL, don't dump core.
+
+Tue Oct 26 15:07:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ gcc -Wall lint:
+ * nlmread.c: Include stabsread.h.
+ * Makefile.in: Update dependencies.
+
+ * remote.c: Change PBUFSIZ back to 400. John's 28 Feb 1992 change
+ to increase it broke the ability to write large chunks of memory
+ with m68k-stub and i386-stub. Now we only use more than 400 on
+ machines where we need that much to write the registers.
+ * remote.c (remote_write_bytes): Eliminate possible abort(). The
+ check for when to abort was off by a few bytes and besides which,
+ it is handled by MAXBUFBYTES, which the caller uses.
+ * m68k-stub.c: Add comments about trap #1 and trap #8 instructions.
+
+Tue Oct 26 08:36:07 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * remote-sim.h (SIM_ADDR): New type (same as CORE_ADDR).
+ (sim_set_pc): Update prototype.
+ (sim_read, sim_write): Ditto, and use unsigned char *buf.
+ (sim_fetch_register, sim_store_register): Use unsigned char *buf.
+ (sim_info): Pass printf function as argument, add verbose argument.
+ (sim_stop_reason): Renamed from sim_stop_signal, fix prototype.
+ * remote-sim.c (gdbsim_wait): Update call to sim_stop_reason.
+ (gdbsim_files_info): Update call to sim_info.
+
+Tue Oct 26 10:41:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * valops.c (value_assign): Call reinit_frame_cache when assigning
+ to a register.
+
+Mon Oct 25 11:08:59 1993 Stu Grossman (grossman at cygnus.com)
+
+ * infrun.c (wait_for_inferior): Fix PC out of objfile bounds
+ check to just use stop_func_name == 0.
+ * remote-udi.c (store_register): Invalidate NPC/PC_REGNUM after
+ changing PC.
+
+Mon Oct 25 14:57:45 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbserver/{low-lynx.c,low-sparc.c,low-sun3.c}, standalone.c,
+ m3-nat.c, i386m3-nat.c, mipsm3-nat.c, ns32km3-nat.c: bcopy -> memcpy.
+
+ gcc -Wall lint:
+ * breakpoint.c: Include thread.h.
+ * coffread.c: Include stabsread.h.
+ * Makefile.in: Update dependencies.
+ * breakpoint.c (mention): Add bp_call_dummy to switch.
+ * symmisc.c (dump_symtab): Use %d not %ld for line number.
+
+Sun Oct 24 18:29:32 1993 Tom Lord (lord@rtl.cygnus.com)
+
+ * every non-obsolete file except utils.c:
+ Change the stream argument to _filtered to GDB_FILE *.
+ Change all references to stdout/stderr to gdb_stdout/gdb_stderr.
+ Replace all calls to stdio output functions with
+ calls to corresponding _unfiltered functions.
+ Replaced calls to fopen for output to gdb_fopen.
+ Added sufficient goo to utils.c and defs.h to make the above
+ work.
+
+ The net effect is that stdio output functions are only directly
+ used in utils.c. Elsewhere, the _unfiltered and _filtered
+ functions and GDB_FILE type are used.
+
+ In the near future, GDB_FILE will stop being equivalant to
+ FILE.
+
+ The semantics of some commands has changed in a very subtle way:
+ called in the right context, they may cause new occurences of
+ prompt_for_continue() behavior.
+
+ Please respect this change by not reintroducing stdio output
+ dependencies in the main body of gdb code. All output from
+ commands should go to a GDB_FILE.
+
+Sun Oct 24 20:16:38 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * parse.c, parser-defs.h (write_exp_msymbol): New function to write
+ the appropriate expression for a minimal symbol. Taken from c-exp.y
+ and m2-exp.y but handles mst_file_*.
+ * c-exp.y, m2-exp.y: Use it.
+
+Sun Oct 24 09:31:05 1993 Fred Fish (fnf@lisa.cygnus.com)
+
+ * elfread.c (elf_symtab_read): Use bfd convention that both
+ initialized and uninitialized data sections have the SEC_ALLOC
+ flag bit set, but only initialized sections have SEC_LOAD set.
+ SEC_DATA is ignored since it only gets set for initialized
+ data.
+
+Sat Oct 23 14:48:18 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * remote-sim.h (sim_stop): New enum.
+ (sim_stop_signal): Change prototype, result is enum sim_stop.
+ * remote-sim.c (gdbsim_wait): Update call to sim_stop_signal.
+
+Fri Oct 22 07:49:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabsread.c (define_symbol): Skip the whole thing about "pcc
+ promotion" on little-endian machines.
+
+ * remote-vx.c (vx_wait): Rename pid parameter to pid_to_wait_for.
+ Some compilers (legitimately) don't like variables in the
+ function's outermost block whose name is the the same as the name of
+ a parameter.
+
+ Merge Apollo patches from Troy Rollo (troy@cbme.unsw.edu.au):
+ * dst.h, dstread.c, config/m68k/{apollo68b.mt,tm-apollo68b.h}:
+ New files.
+ * config/m68k/nm-apollo68b.h: Add more defines.
+ * configure.in: Recognize apollo target, not just host.
+
+ * configure.in: Add * to end of all OS names.
+
+Fri Oct 22 06:14:01 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (ALLPARAM): Add config/m88k/xm-delta88v4.h
+
+Thu Oct 21 12:23:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (init.c): Generate using the source, not munch. This
+ cleans up all kinds of hassles (which nm to use in munch, etc). The
+ new formatting conventions (mostly already followed) are that
+ the name of the _initialize_* routines must start in column zero,
+ and must not be inside #if.
+ * munch: Removed.
+ * Makefile.in: Remove references to munch.
+ * serial.c, remote.c, infptrace.c, maint.c, convex-tdep.c,
+ alpha-tdep.c, hp300ux-nat.c, hppab-nat.c, osfsolib.c, remote-es.c,
+ procfs.c, remote-udi.c, ser-go32.c, ultra3-xdep.c, sh-tdep.c,
+ i960-tdep.c, hppa-tdep.c, h8500-tdep.c, dpx2-nat.c, delta68-nat.c,
+ z8k-tdep.c: Make sure the above conventions are followed. Make
+ sure they are all declared as returning void. Clean up
+ miscellaneous comments and such.
+
+ * sh-tdep.c (sim_load): Add function.
+
+Thu Oct 21 15:58:48 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * remote-mips.c (mips_wait): add pid argument.
+
+Thu Oct 21 12:23:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (c-exp.tab.o): Remove notice about shift/reduce conflicts
+ which no longer occur.
+
+ gcc -Wall lint:
+ * findvar.c (symbol_read_needs_frame), corelow.c (ignore),
+ inflow.c (gdb_has_a_terminal): Make sure to return a value.
+ * regex.h: Declare re_set_syntax.
+ * printcmd.c: Include valprint.h.
+ * infcmd.c, exec.c, maint.c, core.c: Include language.h.
+ * maint.c: Include expression.h.
+ * infrun.c, fork-child.c, corelow.c, inflow.c: Include thread.h.
+ * inftarg.c: Include command.h.
+ * coredep.c: Include value.h.
+ * c-exp.y, m2-exp.y, ch-exp.y: Include bfd.h, symfile.h and objfiles.h.
+ * ch-typeprint.c: Include typeprint.h.
+ * ch-valprint.c: Include c-lang.h.
+ * nlmread.c: Include buildsym.h.
+ * environ.c: Include gdbcore.h. Only include defs.h once.
+ (set_in_environ): Cast const char * to char * when passing to
+ set_gnutarget.
+ * Makefile.in: Update dependencies to reflect all these new includes.
+ Remove unused variables:
+ * printcmd.c (printf_command): args_to_vprintf.
+ * coffread.c (coff_symfile_init): strsection.
+ Move variables to within the #ifdefs where they are used:
+ * symtab.c (gdb_mangle_name): opname.
+ * inftarg.c (child_attach): pid and exec_file.
+ * inftarg.c (child_detach): siggnal.
+ * objfiles.c (allocate_objfile): mapto, md, and fd.
+ * objfiles.c (free_objfile): mmfd.
+ * infrun.c (wait_for_inferior): Include BPSTAT_WHAT_LAST in switch.
+ * infrun.c (wait_for_inferior): Remove unused same_pid label.
+ * inferior.h: Declare set_sigint_trap and clear_sigint_trap.
+ * parser-defs.h: Declare write_exp_elt_block.
+ * stabsread.h: Declare elfstab_offset_sections and
+ coffstab_build_psymtabs.
+
+Thu Oct 21 12:05:08 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ Patch from Jeff Law:
+ * paread.c: Fix references to "hppa" that should now be "som".
+
+Thu Oct 21 12:23:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * symtab.c (decode_line_1): Don't use SYMBOL_LINE for functions.
+
+Thu Oct 21 02:59:07 1993 Stu Grossman (grossman at cygnus.com)
+
+ * remote-udi.c (udi_store_registers, store_register): Use
+ UDI29KPC address space when modifying PC. It seems that you can't
+ modify the PC directly (at least in the isstip simulator).
+
+Wed Oct 20 11:35:43 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * target.h: Put remote_debug declaration back here. Add baud_rate.
+ * remote.c, remote-udi.c, remote-utils.h: Let target.h take care of
+ declaring these. Those random externs all over are error prone.
+ * Move "set remotebaud" from remote-utils.c to main.c to it applies
+ to remote.c as well.
+
+ * xcoffread.c (xcoff_symfile_read), coffread.c (coff_symfile_read):
+ Sort symtabs for this objfile only, not for all objfiles.
+ * symfile.c, symfile.h (sort_all_symtab_syms): Remove; no longer used.
+
+ * mipsread.c (parse_symbol): In third-eye, a function has a block
+ within it which represents the whole function. Create only one
+ GDB block for both.
+
+Wed Oct 20 17:47:42 1993 Stu Grossman (grossman at cygnus.com)
+
+ * main.c: Make baud_rate and remote_debug be global variables,
+ remove #include "remote-utils.h". This makes it possible to build
+ GDB without remote-utils.c. Also, move setting of remote_debug
+ into main, so that all remote*.c files can use it (not just the
+ serial line ones). And, make baud_rate be an int.
+ * remote-udi.c: Change kiodebug to remote_debug.
+ * remote-utils.c: Move setting of baud rate and debug into main.c.
+ * remote-utils.h: Redefine sr_{get set}_debug and sr_{get set}_baud
+ to use baud_rate and remote_debug globals for compatibility.
+ * remote.c: Use remote_debug and baud_rate globals directly,
+ instead of sr_ functions, so that we don't need to load
+ remote-utils.c.
+ * config/a29k/a29k-udi.mt: Define REMOTE_O as null so that we don't
+ get the default remote* modules.
+
+Wed Oct 20 11:35:43 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabsread.c (define_symbol): When combining a LOC_ARG and a
+ LOC_REGISTER, use the type from the LOC_REGISTER, not from the
+ LOC_ARG.
+
+Wed Oct 20 14:34:38 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config/i386/xm-go32.h: define some signals if they aren't
+ already defined.
+
+Wed Oct 20 11:35:43 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (INTERNAL_LDFLAGS): New macro. The new part is
+ that we use CFLAGS and PROFILE_CFLAGS to link.
+ (gdb, rapp, kdb): Use INTERNAL_LDFLAGS instead of
+ LDFLAGS and/or GLOBAL_CFLAGS.
+
+Wed Oct 20 09:29:55 1993 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in: Add $(srcdir) to all refs to 29k-share
+ directories.
+
+Tue Oct 19 17:23:34 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * Makefile.in (ALLCONFIG): Add config/i386/{i386m3.mh, i386m3.mt,
+ i386/i386mk.mh i386/i386mk.mt}, config/mips/{mipsm3.mh,
+ mipsm3.mt}, config/ns32k/{ns32km3.mh, ns32m3.mt}
+ * Makefile.in (remote_utils_h): Add remote-sim.h
+ * Makefile.in (NONSRC): Add i386-nlmstub.c
+ * Makefile.in (HFILES): Add coff-solib.h
+
+Tue Oct 19 14:15:40 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * values.c (value_virtual_fn_field): Fix the offset calculation
+ when calling virtual functions. (gdb.t22/virtfunc.exp).
+ * eval.c (evaluate_subexp): same as above.
+
+Tue Oct 19 10:43:16 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/rs6000/rs6000.mh (TERMCAP): Define to -lcurses.
+
+ * Makefile.in: Define CXXFLAGS.
+
+Tue Oct 19 09:28:52 1993 Stu Grossman (grossman@cygnus.com)
+
+ * sparclite/Makefile.in: Fixup so that this works with Sun make
+ and VPATH.
+
+Tue Oct 19 10:43:16 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.h (struct bpstat_what): Don't use bitfields.
+
+ * typeprint.c: Add "class CLASS-NAME" to docstring for ptype.
+
+Tue Oct 19 06:17:10 1993 Fred Fish (fnf@cirdan.cygnus.com)
+
+ * Makefile.in (ALLPARAM): Add config/m88k/{nm-delta88v4.h,
+ tm-delta88v4.h, xm-dgux.h}.
+ * Makefile.in (ALLCONFIG): Add config/m88k/{delta88v4.mh,
+ delta88v4.mt}.
+
+ * README: Remove comment about SunOS 5.x programs leaving
+ coredumps. Info from Sun is that this was not in customer
+ releases.
+
+Mon Oct 18 10:28:08 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hppa-tdep.c (restore_pc_queue): Call target_terminal_ours after
+ done stepping the inferior.
+
+ * c-exp.y: Remove never-used (because of shift/reduce conflicts)
+ rules for pointers to members.
+ * Makefile.in: Remove notice about expected shift/reduce conflicts.
+
+ * buildsym.c (finish_block): If we pop the context stack and it is
+ not empty, complain () instead of abort ().
+
+Sun Oct 17 19:42:31 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * parse.c, parser-defs.h (follow_types): New function.
+ * c-exp.y (ptype : typebase abs_decl): Use it.
+ * c-exp.y (ptype): Add support for type qualifiers after the
+ typebase. The typebase rule already has support for them before
+ the typebase.
+ * Makefile.in: Change the expected number of shift/reduce
+ conflicts to 6. This is OK--the 2 new conflicts are basically the
+ same as one of the old ones.
+
+Sun Oct 17 13:04:49 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.10.3.
+
+Sun Oct 17 09:18:57 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infrun.c (wait_for_inferior): Clean up comments which were at
+ the top of the file, making them more concise and moving them with
+ the code (Sorry, Randy, but these stream-of-consciousness comments
+ really have to go). Switch the order of the "&&", which makes
+ things clearer and turns out to be an improvement with respect to
+ side effects and speed.
+
+Sun Oct 17 02:06:01 1993 Stu Grossman (grossman at cygnus.com)
+
+ * procfs.c: Handle process exits more elegantly by trapping on
+ entry to _exit. Also, cleanup procinfo list when process dies of
+ it's own accord (as opposed to being killed).
+
+Sat Oct 16 20:47:30 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/m88k/xm-dgux.h: Define NO_PTRACE_H.
+
+ * corelow.c (add_to_thread_list): Need a cast to go from PTR to
+ asection *.
+
+ * infrun.c: Add comment about signals.
+
+ * fork-child.c (fork_inferior): Remove CREATE_INFERIOR_HOOK again.
+ Stu reinstated it (accidently I assume).
+
+Sat Oct 16 15:27:10 1993 Stu Grossman (grossman at cygnus.com)
+
+ * procfs.c (procfs_wait): Losing Unixware can't do poll on /proc
+ files. Use PIOCWSTOP instead.
+ * corelow.c (add_to_thread_list): Fix arg to match prototype.
+
+ * procfs.c (procfs_set_sproc_trap): Don't use this if sproc
+ isn't available.
+ * (procfs_notice_signals): Fix prototype.
+
+Fri Oct 15 22:46:07 1993 Stu Grossman (grossman at cygnus.com)
+
+ * breakpoint.c (breakpoint_thread_match break_command_1):
+ Thread-specific breakpoint support.
+ * breakpoint.h (struct breakpoint): Add thread id field.
+ * fork-child.c (fork_inferior): Move call to init_thread_list()
+ back a bit so that init_trace_fun can do thread functions.
+ * hppa-tdep.c (restore_pc_queue): Add pid to call to target_wait.
+ * hppab-nat.c (child_resume): Handle default pid.
+ * hppah-nat.c (child_resume): Handle default pid.
+ * i386lynx-nat.c (child_wait): New arg pid.
+ * inflow.c (kill_command): Reset thread list.
+ * infptrace.c (child_resume): Handle default pid.
+ * infrun.c: Thread-specific breakpoint support.
+ * inftarg.c (child_wait): Add pid arg.
+ * osfsolib.c (solib_create_inferior_hook): Add pid to call to
+ target_resume.
+ * procfs.c: Multi-thread support.
+ * remote-bug.c (bug_wait): Add pid arg.
+ * remote-hms.c (hms_wait): Add pid arg.
+ * remote-mips.c (mips_wait): Add pid arg.
+ * remote-mon.c (monitor_wait): Add pid arg.
+ * remote-nindy.c (nindy_wait): Add pid arg.
+ * remote-sim.c (gdbsim_wait): Add pid arg.
+ * remote-udi.c (udi_wait): Add pid arg.
+ * remote-vx.c (vx_wait): Add pid arg.
+ * remote-z8k.c (sim_wait): Add pid arg.
+ * remote.c (remote_wait): Add pid arg.
+ * solib.c (solib_create_inferior_hook): Add pid to call to
+ target_resume.
+ * target.h (struct target_ops): Add pid arg to to_wait and
+ to_notice_signals.
+ * thread.c (valid_thread_id): New func to validate thread #s.
+ * (pid_to_thread_id): New func to do the obvious.
+ * thread.h: Prototypes for above.
+
+ * coff-solib.c (coff_solib_add): Use nameoffset field to locate
+ filename.
+
+Fri Oct 15 21:29:40 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * h8300-tdep.c, h8500-tdep.c: Define sim_load only, but not
+ sim_kill, sim_open, or sim_set_args.
+
+ * stack.c (print_stack_frame): Put catch_errors around
+ print_frame_info so (for example) error printing source doesn't
+ cause auto-displays to get skipped in normal_stop.
+
+ * findvar.c (value_from_register): When preparing to cast a value
+ from REGISTER_VIRTUAL_TYPE to type, copy the REGISTER_VIRTUAL_SIZE;
+ the old code didn't copy the whole thing.
+ * valops.c (value_assign): Add comment.
+
+Fri Oct 15 12:57:30 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mipsread.c (upgrade_type): Replace bitsize sanity checks and
+ complaint by a comment explaining why they were useless.
+
+Fri Oct 15 14:30:30 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Move comments on bypassing call dummy breakpoint from stack.c
+ to breakpoint.h.
+
+Fri Oct 15 11:52:56 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * symtab.c (lookup_partial_symtab): If filename is not found and
+ contains no slashes, try again and compare without leading path
+ components.
+ * symtab.c (lookup_symtab_1): Replace open coded version of
+ lookup_partial_symtab with a function call.
+
+Thu Oct 14 20:34:15 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * fork-child.c (fork_inferior), remote-eb.c (eb_create_inferior),
+ remote-mon.c (monitor_create_inferior), remote-nindy.c
+ (nindy_create_inferior), remote-st.c (st2000_create_inferior),
+ remote-vx.c (vx_create_inferior): Remove CREATE_INFERIOR_HOOK; it
+ is replaced by init_trace_fun.
+ * config/convex/xm-convex.h, convex-xdep.c: Add comments explaining
+ how to do without CREATE_INFERIOR_HOOK for whoever fixes the Convex
+ port.
+
+ * Makefile.in: Add Mach files to ALLDEPFILES, etc.
+ * m3-nat.c: Clean up more hair--message(), cprocs.
+ * configure.in: Recognize Mach targets and hosts.
+ * config/ns32k/tm-umax.h: Add some #ifndef's so tm-ns32km3.h can
+ include this file.
+ * Mach headers in config/*/tm-*.h: Fix includes to match correct
+ locations of files.
+
+Thu Oct 14 21:35:55 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * remote-mon.c (general_open): Set dev_name. Minor tweaking to get
+ it working again.
+ * config/m68k/tm-monitor.h: Remove floating point register names
+ as there aren't any on any of the monitors that use this code.
+
+Wed Oct 13 11:47:23 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * inflow.c: Pass pointer to process group, not process group itself,
+ to TIOCSPGRP ioctl.
+
+ * inflow.c (terminal_ours_1): Don't print warning on failure to
+ set process group.
+
+ * printcmd.c (printf_command): Instead of using makeva* and
+ calling vprintf, just make the appropriate calls to printf.
+ * printcmd.c, config/pa/xm-pa.h, config/mips/xm-makeva.h,
+ config/alpha/xm-alpha.h, config/m88k/xm-m88k.h: Remove all
+ traces of makeva*. My apologies to everyone (including me!)
+ who spent so much time getting it to work on various machines,
+ but look at the bright side, at least you won't have to do it
+ again in the future.
+
+ * printcmd.c (printf_command): Make a cleanup for val_args (fixes
+ a memory leak).
+
+Tue Oct 12 22:54:41 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/mips/xm-mips.h: Remove comment about HAVE_SGTTY vs. usleep.
+
+Tue Oct 12 12:01:29 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: only configure gdbserver for native environments
+
+Tue Oct 12 08:59:15 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabsread.c (read_type): Treat a negative type number at the start
+ of a type as a type reference, not as a definition of a type with
+ "50=" omitted. This makes things work on the RS/6000 again (the
+ 14 Sep 1993 change broke it).
+
+ * inflow.c: Use 0 (standard input) not scb->fd.
+ (terminal_ours_1): If printing warning, don't claim it happened in
+ terminal_inferior.
+
+ * blockframe.c (get_prev_frame_info): Don't error() if there are no
+ frames; just return NULL.
+
+ * xcoffsolib.h, xcoffexec.c: Undo the part of Fred's bfd->abfd
+ change which involved structure elements. It was unnecessary and
+ was not consistently done.
+
+ * stabsread.h, stabsread.c, dbxread.c (common_block*, copy_pending):
+ Move common block handling from dbxread.c to stabsread.c.
+ Use the name from the BCOMM instead of the ECOMM.
+ Allocate things on the symbol_obstack.
+ * xcoffread.c (process_xcoff_symbol): Process C_BCOMM, C_ECOMM,
+ and C_ECOML. On unrecognized storage classes, go ahead and call
+ define_symbol (after the complaint).
+
+ * dbxread.c (process_one_symbol): Don't relocate 'S' symbols by
+ the text offset.
+
+Tue Oct 12 12:33:09 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * osfsolib.c (solib_create_inferior_hook): Reset stop_soon_quietly
+ after shared library symbol reading to get rid of warning from
+ heuristic_proc_start.
+
+Tue Oct 12 12:01:29 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * remote-sim.c: fix unterminated character string
+
+Tue Oct 12 08:59:15 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabsread.c: Fix comment about gcc 2.3.3 stab for long long int.
+
+Mon Oct 11 14:27:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * m3-nat.c, config/nm-m3.h: Add a target_ops struct and other
+ various things to try to get this to work.
+
+ * symtab.h: Fix comments re headers, sharing blockvectors, etc.
+
+Mon Oct 11 11:46:06 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * config/i960/vxworks960.mt (REMOTE_O): add dcache.o and remote-utils.o
+
+Mon Oct 11 02:48:57 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mipsread.c (parse_partial_symbols): Do not add undefined
+ symbols to the partial symbol table.
+ * alpha-tdep.c (init_extra_frame_info): Remove kludge for gcc,
+ gcc has to be compatible with the native tools.
+ * alpha-tdep.c (alpha_push_arguments): Rename NUM_ARG_REGS to
+ ALPHA_NUM_ARG_REGS and move its definition to tm-alpha.h.
+ * config/alpha/tm-alpha.h (FRAME_ARGS_ADDRESS): Change it to the
+ way the native tools define it, update comment.
+
+Fri Oct 8 15:54:06 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * osfsolib.c, remote-sim.c, remote.c, solib.c, xcoffexec.c,
+ xcoffsolib.h: Use 'abfd' for bfd variables instead of 'bfd'.
+ Sun cc doesn't like variable names that match their typedef'd type.
+
+Fri Oct 8 14:56:21 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * inflow.c: Remove unused includes of sys/param.h and sys/types.h.
+
+ * inflow.c, ser-unix.c, ser-go32.c, ser-tcp.c, serial.h,
+ terminal.h, fork-child.c, main.c, utils.c: Move all the process
+ group stuff back to inflow.c and terminal.h; that's a better place
+ for it and fixes problems with trying to get/set the process group
+ of a tty we're doing remote debugging on.
+ * terminal.h: Skip the redefines and includes if HAVE_TERMIOS.
+
+ * findvar.c, value.h (symbol_read_needs_frame): New function.
+ * c-exp.y, m2-exp.y: Call it instead of having our own switch on
+ the symbol's class.
+ * valops.c (value_of_variable): Use symbol_read_needs_frame to
+ decide whether we care about finding a frame.
+
+Fri Oct 8 02:34:21 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * blockframe.c (get_frame_block): Do not adjust pc if the frame
+ function was interrupted by a signal.
+
+Thu Oct 7 19:20:11 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/h8300/tm-h8300.h: Don't define sr_get_debug.
+ * remote-sim.c: Include remote-utils.h.
+ * target.h: Add comment about target_has_execution.
+
+Thu Oct 7 16:14:19 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * h8300-tdep.c (sim_load, sim_kill, sim_open, sim_set_args):
+ New functions.
+ * infrun.c (normal_stop): Don't try and set the pc in the current
+ frame coredump if there isn't one.
+ * remote-sim.c (gdbsim_store_register): Don't
+ SWAP_TARGET_AND_HOST, sim_store_register takes bytes in raw order.
+ (gdbsim_wait): Set status with WSETSTOP.
+ * config/h8300/tm-h8300.h (sr_get_debug): Define
+
+Thu Oct 7 12:56:57 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ New Mach stuff:
+ * config/i386/i386mach.c: Explain this is for the old (probably
+ non-functional and/or obsolete) Mach stuff.
+ * m3-nat.c, config/nm-m3.h,
+ i386m3-nat.c, mipsm3-nat.c, ns32km3-nat.c,
+ config/i386/{i386m3.mh,i386m3.mt,tm-i386m3.h,xm-i386m3.h},
+ config/i386/{i386mk.mh,i386mk.mt,tm-i386mk.h,xm-i386mk.h},
+ config/mips/{mipsm3.mh,mipsm3.mt,tm-mipsm3.h,xm-mipsm3.h},
+ config/ns32k/{ns32km3.mh,ns32km3.mt,tm-ns32km3.h,xm-ns32km3.h}:
+ New files.
+
+ * blockframe.c (find_pc_partial_function): If we call
+ PSYMTAB_TO_SYMTAB, call target_terminal_ours_for_output first.
+ This is needed now that wait_for_inferior passes in endaddr.
+ * infrun.c: Move call to target_terminal_inferior from proceed
+ to resume.
+
+Thu Oct 7 09:22:04 1993 Stu Grossman (grossman at cygnus.com)
+
+ * blockframe.c (find_pc_partial_function): Fix handling for PCs
+ beyond the end of the last function in an objfile.
+ * coff-solib.c (coff_solib_add): Use BFD to get fields from .lib
+ section.
+ * infrun.c (wait_for_inferior): Modify test for subroutine entry
+ to include pc out of bounds of the previous function.
+ * remote.c (remote_wait): Use strtoul for parsing 'N' message.
+ Add code to relocate symfile_objfile->sections.
+
+Thu Oct 7 06:22:43 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/sparc/sun4os4.mh: Add comment saying why we don't use
+ -lresolv.
+
+Thu Oct 7 09:29:11 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * breakpoint.c, breakpoint.h (breakpoint_init_inferior): New function
+ that clears the `inserted' flag for all breakpoints and deletes
+ any breakpoints which should go away between runs of programs.
+ * inflow.c (generic_mourn_inferior), infrun.c (init_wait_for_inferior),
+ remote-es.c (es1800_load), comments in exec.c and corelow.c:
+ Use it instead of mark_breakpoints_out.
+ * breakpoint.c (mark_breakpoints_out): Update comment, tm-rs6000.h
+ uses it in a completely different context.
+ * breakpoint.c (breakpoint_re_set_one): Add bp_call_dummy case.
+
+Thu Oct 7 09:29:11 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * Makefile.in (REGEX, REGEX1): Always use our own version of
+ regex.c to be consistent across hosts.
+ * source.c (_initialize_source): Initialize regex to use grep
+ style syntax as an approximation to POSIX basic regex syntax.
+
+Wed Oct 6 12:43:47 1993 Jeffrey A Law (law@snake.cs.utah.edu)
+ Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hppa-tdep.c (frame_chain): Rework so that it correctly
+ handles boundaries where code with a frame pointer calls code
+ without a frame pointer.
+ (dig_fp_from_stack): New function.
+
+Wed Oct 6 12:43:47 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.c (delete_breakpoint): Don't insert a disabled breakpoint.
+
+ * README: Add Alpha notes from Schauer.
+
+Tue Oct 5 15:26:04 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (install, uninstall): Remove $$n.1 stuff; I don't
+ understand what it is trying to do, but I suspect it's not doing
+ it.
+
+ * config/ns32k/merlin.mh: Add comment about M_INSTALL.
+ * config/m88k/{delta88.mh,delta88v4.mh}: Remove M_INSTALL and
+ M_UNINSTALL; it tries to install a non-existent file gdb.z.
+ * Makefile.in: Remove M_INSTALL stuff; the above were the only uses.
+
+ * stabsread.c (read_range_type): Remove comment which recommends
+ distinguishing float from complex by the name.
+
+Tue Oct 5 12:17:40 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+ Jim Kingdon (kingdon@cygnus.com)
+ Stu Grossman (grossman@cygnus.com)
+
+ Changes to support alpha OSF/1 in native mode.
+ * alpha-nat.c, alpha-tdep.c, config/alpha/alpha-osf1.mt,
+ config/alpha/nm-alpha.h, config/alpha/tm-alpha.h, osfsolib.c:
+ New files.
+ * Makefile.in: Add new files and dependencies.
+ * configure.in: Add alpha target.
+ * config/alpha/alpha-osf1.mh (NATDEPFILES): Add osfsolib.o
+ * config/alpha/alpha-osf1.mh (MH_CFLAGS): Remove, we can handle
+ shared libraries now.
+ * config/alpha/xm-alpha.h: Cleanup, get MAKEVA_* defines right.
+
+ * defs.h (CORE_ADDR): Make its type overridable via CORE_ADDR_TYPE,
+ provide `unsigned int' default.
+ * breakpoint.c (breakpoint_auto_delete): Delete only if we really
+ stopped for the breakpoint.
+ * stabsread.c, stabsread.h (define_symbol): Change valu parameter
+ to a CORE_ADDR.
+ * stabsread.c (read_range_type): Handle the case where the lower
+ bound overflows and the upper doesn't and the range is legal.
+ * infrun.c (resume): Do not step a breakpoint instruction if
+ CANNOT_STEP_BREAKPOINT is defined.
+
+ * inferior.h (CALL_DUMMY_LOCATION): New variant AT_ENTRY_POINT.
+ Now that we have the bp_call_dummy breakpoint the call dummy code
+ is no longer needed. PUSH_DUMMY_FRAME, PUSH_ARGUMENTS and
+ FIX_CALL_DUMMY can be used to set up everything for the dummy.
+ The breakpoint for the dummy is set at the entry point and thats it.
+ * blockframe.c (inside_entry_file, inside_entry_func): Do not stop
+ backtraces if pc is in the call dummy at the entry point.
+ * infcmd.c (run_stack_dummy): Handle AT_ENTRY_POINT case. Use
+ the expected breakpoint pc when setting up the frame for
+ set_momentary_breakpoint.
+ * symfile.c (entry_point_address): New function for AT_ENTRY_POINT
+ support.
+ * valops.c (call_function_by_hand): Handle AT_ENTRY_POINT case.
+
+Tue Oct 5 11:37:02 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.in: Recognize hppa*-*-hiux* (currently synonym for hpux).
+ Change other hppa host entries to use -*- not -hp-.
+
+Mon Oct 4 19:16:14 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * i386-nlmstub.c: New file; debugging stub for i386 NetWare. Must
+ be compiled with NetWare header files and turned into an NLM with
+ nlmconv.
+
+Mon Oct 4 11:02:11 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * minsyms.c (lookup_minimal_symbol_by_pc): Don't use mst_abs symbols.
+
+ * dbxread.c (process_one_symbol): Make n_opt_found static.
+
+ * Rename i386lynx-tdep.c to i386ly-tdep.c for 14 character file names.
+ * Makefile.in, config/i386/i386lynx.mt: Change accordingly.
+
+ * values.c (record_latest_value): Fetch lazy values and set VALUE_LVAL
+ to not_lval.
+
+Sun Oct 3 15:54:51 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * objfiles.h (objfile): New slot sym_stab_info, use by most
+ stab-reading formats.
+ * gdb-stabs.h (DBX_SYMFILE_INFO): Access sym_stab_info instead of
+ sym_private.
+ * coffread.c (coff_symfile_init): Alloc struct for sym_stab_info.
+ * dbxread.c, elfread.c, paread.c: Change sym_private references to
+ sym_stab_info references.
+
+Sat Oct 2 19:28:35 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * mipsread.c, objfiles.c, utils.c: Use PTR not void *. RISC/OS
+ 4.02 lacks void *.
+ * elfread.c: Use void * not PTR inside PARAMS.
+
+ * config/mips/news-mips.mh: Remove coredep.o; mips-nat.o does it.
+ * config/mips/news-mips.mh: Define NAT_FILE not NM_FILE.
+ * config/mips/nm-news-mips.h: Include mips/nm-mips.h not nm-mips.h.
+
+Sat Oct 2 16:05:22 1993 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in, coff-solib.c, coff-solib.h, i386lynx.mt,
+ tm-i386lynx.h: Add support for SVR3 COFF shared libraries.
+
+Sat Oct 2 15:50:41 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * m88k-nat.c (store_inferior_registers): When writing all registers,
+ don't try to write EXIP_REGNUM or ENIP_REGNUM (not needed for this
+ case, and they cause trouble).
+
+ * TODO: Don't suggest doing fast watchpoints by stepping a line
+ at a time. That would be really hairy and still not fast enough.
+ Do suggest debug registers and page table diddling.
+
+Fri Oct 1 14:54:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * printcmd.c (do_examine): Make meaning of 'h', 'w', and 'g' not
+ depend on builtin_type_*. Instead, it is always 2, 4, and 8 bytes
+ like the documentation says.
+ * printcmd.c (decode_format) [CC_HAS_LONG_LONG]: Remove 'l' as
+ synonym for 'g'. This was never documented, it shouldn't depend on
+ CC_HAS_LONG_LONG, and I don't see what's wrong with 'g'.
+
+Fri Oct 1 10:06:35 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * symtab.c: fix a bug in testsuite (virtfunc.exp)
+
+Thu Sep 30 11:30:56 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * m88k-nat.c (fill_gregset): Fix typo (R_SFIP -> R_FIP).
+
+ * c-typeprint.c (c_type_print_base, TYPE_FN_FIELD_STUB code):
+ If demangled name lacks a colon, don't dump core.
+
+ * blockframe.c (find_pc_partial_function): If pst->readin is
+ set, don't try to get symbols from pst.
+
+ * inflow.c (generic_mourn_inferior): Call reinit_frame_cache
+ instead of doing it ourself.
+ * blockframe.c (reinit_frame_cache): Use code which was in
+ generic_mourn_inferior so we can use this function even when
+ we have switched targets.
+ * corelow.c (core_detach): Call reinit_frame_cache.
+ * target.c (target_detach): Don't call generic_mourn_inferior
+ (revert yesterday's change, now handled by core_detach).
+ * objfiles.c (free_objfile): Detach any core file if we call
+ SOLIB_CLEAR. #include target.h.
+
+ * fork-child.c (fork_inferior): Don't call target_terminal_init
+ and target_terminal_inferior until we are sure that the inferior
+ has called gdb_setpgid. This fixes PR 2900 (Schauer tracked it
+ down and was able to reliably reproduce it by putting a sleep()
+ before the gdb_setpgid()).
+
+Thu Sep 30 12:00:49 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * c-exp.y, m2-exp.y: Change type of address for msymbol to
+ builtin_type_long.
+ * infptrace.c (fetch_register, store_inferior_register,
+ child_xfer_memory): Use PTRACE_XFER_TYPE for the type of ptrace
+ transfers. Provide an `int' default for PTRACE_XFER_TYPE.
+
+Thu Sep 30 11:30:56 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * defs.h (TARGET_*_BIT): Don't use host information (sizeof) in
+ picking defaults.
+
+ * cp-valprint.c (cp_is_vtbl_ptr_type): Continue to accept old form.
+
+Thu Sep 30 11:25:55 1993 Kung Hsu (kung@cygnus.com)
+
+ * cp-valprint.c (cp_is_vtbl_ptr_type):
+ change vtable field name to __vtbl (pr2695).
+
+ * symtab.c (gdb_mangle_name): fix a bug, to get mangled name right.
+
+Wed Sep 29 18:34:22 1993 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in: Add deps for i386lynx-nat.o and i386lynx-tdep.o to
+ keep non-gnu makes happy.
+
+Wed Sep 29 17:20:54 1993 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c (read_hpux_symtab): When a K_END is found for a
+ K_MODULE, clear the have_module and have_name flags.
+
+Wed Sep 29 10:52:19 1993 Kung Hsu (kung@cygnus.com)
+
+ * c-valprint.c: to fix virtual table print bug (pr2695).
+
+Wed Sep 29 10:52:19 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * target.c (target_detach): Call generic_mourn_inferior.
+ * inflow.c (generic_mourn_inferior): Call flush_cached_frames.
+
+Tue Sep 28 23:08:59 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dbxread.c, coffread.c, elfread.c: A few changes to comments.
+
+Tue Sep 28 18:39:37 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * configure.in: Rename ...-lynx* to ...-lynxos*.
+ Add m68*-*-lynxos* configuration.
+ * dbxread.c (coffstab_build_psymtabs): New function,
+ interfaces coffread.c to dbxread functions.
+ * coffread.c (coff_symfile_info): Expand to include
+ dbx_symfile_info slots.
+ (coff_symfile_init): Init coff_symfile_info struct.
+ (coff_locate_sections): New functions, finds the stab and stabstr
+ sections.
+ (coff_symfile_read): Call coffstab_build_psymtabs if a stab
+ section is present.
+ (coff_section_offsets): Replace fake version with real offsets.
+
+Tue Sep 28 18:00:50 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infcmd.c (run_stack_dummy): Set the frame in the bp_call_dummy
+ breakpoint.
+
+Tue Sep 28 17:53:26 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/nm-sysv4.h: Include solib.h. Define SVR4_SHARED_LIBS.
+ * config/tm-sysv4.h: Don't include solib.h.
+ * config/xm-sysv4.h: Don't define SVR4_SHARED_LIBS.
+ * config/i386/i386v4.mt (TDEPFILES): Move solib.o from here...
+ * config/i386/i386v4.mh (NATDEPFILES): ...to here.
+ * config/i386/nm-i386v4.h: Include nm-sysv4.h.
+ * config/m68k/amix.mt (TDEPFILES): Move solib.o from here...
+ * config/m68k/amix.mh (NATDEPFILES): ...to here.
+
+Tue Sep 28 09:45:38 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * symmisc.c (print_symbol): Use %02x not %2x for LOC_CONST_BYTES.
+
+ Clean up problems with targets and hosts that have 64 bit longs
+ and pointers and 32 bit ints.
+ * breakpoint.c, buildsym.c, c-lang.c, c-valprint.c, ch-lang.c,
+ ch-valprint.c, core.c, cp-valprint.c, dbxread.c, exec.c,
+ expprint.c, gdbtypes.c, infcmd.c, language.c, language.h,
+ m2-lang.c, maint.c, mips-tdep.c, mipsread.c, partial-stab.h,
+ printcmd.c, remote-vx.c, solib.c, source.c, stack.c, symfile.c,
+ symmisc.c, symtab.c, valops.c, valprint.c, xcoffexec.c:
+ Change all printf formats from %x to %lx if outputting an address.
+ Change la_*_format to use long format.
+ local_hex_string, local_hex_string_custom now take an unsigned long
+ argument, change all callers.
+ * coffread.c (read_coff_symtab): Remove superfluous cast for
+ complaint output.
+ * dbxread.c (end_psymtab): Cast MSYMBOL_INFO to long, not int.
+ * findvar.c, value.h (write_register): Change val to LONGEST.
+ * gdbtypes.h (struct type): Change `bitsize' to long as
+ TYPE_FIELD_STATIC_PHYSNAME uses this field as a pointer.
+ * inferior.h (struct inferior_status): Change type of stop_pc to
+ CORE_ADDR.
+ * language.h (local_octal_string, local_octal_string_custom):
+ Remove prototype, the functions are neither defined nor used.
+ * mipsread.c (parse_symbol): Use temporary variable for bitsize as
+ f->bitsize is a long now.
+ * objfiles.c (add_to_objfile_sections, build_objfile_section_table):
+ Use unsigned long casts instead of int for abusing sections_end
+ pointer as integer.
+ * stack.c (parse_frame_specification): Change type of `args' to
+ CORE_ADDR for SETUP_ARBITRARY_FRAME.
+
+ * printcmd.c (make_vasize): Allow redefinition via MAKEVA_SIZE.
+ * mipsread.c (parse_type): Alpha cc now supports the t->continued
+ bit, update algorithm to match the way the compiler uses it.
+
+Tue Sep 28 12:05:11 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * utils.c (fprintfi_filtered): Fix comments.
+
+Mon Sep 27 18:10:08 1993 Stu Grossman (grossman at cygnus.com)
+
+ * coffread.c (read_coff_symtab): Don't call getfilename if there
+ are no auxents.
+
+Mon Sep 27 10:22:37 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * symtab.c (find_pc_line): Fix comments.
+
+ * remote-udi.c (udi_mourn): Don't pop target.
+
+Fri Sep 24 17:25:41 1993 Stu Grossman (grossman at cygnus.com)
+
+ * corelow.c: Add multi thread/process support for core files with
+ .reg/XXX pseudo-sections.
+ * i386lynx-nat.c thread.h thread.c: Remove unnecessary core file
+ support.
+
+Thu Sep 23 10:49:37 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote-udi.c (download): Skip zero length sections.
+
+ * valops.c (search_struct_method, value_struct_elt):
+ Use (value)-1, not -1, for error.
+
+ * infcmd.c (step_1), infrun.c (wait_for_inferior): Add comments
+ about SHIFT_INST_REGS.
+
+ * exec.c (exec_file_command): Set text_end based on all code readonly
+ sections, not just ".text".
+
+ * defs.h, infcmd.c, config/z8k/tm-z8k.h, config/m88k/tm-m88k.h,
+ config/sh/tm-sh.h, config/h8300/tm-h8300.h, config/h8500/tm-h8500.h,
+ z8k-tdep.c: Remove all references to ADDR_BITS_SET.
+ * config/m88k/tm-m88k.h: Define TARGET_WRITE_PC.
+
+ * config/m88k/tm-m88k.h, m88k-tdep.c: Add call function stuff.
+
+Thu Sep 23 00:13:06 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/mips/tm-mips.h (STORE_STRUCT_RETURN): Define as noop as
+ the pushing of the struct return address is already handled in
+ mips_push_arguments.
+ * mips-tdep.c (reinit_frame_cache_sfunc): Fix typo in prototype
+ declaration.
+ * mipsread.c (parse_symbol, parse_type, upgrade_type): Add more
+ sanity checks for corrupt symbol entries to avoid core dumps
+ reported by benson@odi.com. Obviously Ultrix 4.3A cc now has
+ the same problems as the OSF/1 alpha cc.
+ * mipsread.c (parse_lines): Iterate over the range of the compressed
+ line number entries, the old iteration sometimes failed to stop
+ and wrote past the end of the LINETABLE. Add sanity check to avoid
+ the same problem in case the line number info is corrupt.
+ * mipsread.c (parse_procedure): Adjust pdr for alpha __sigtramp.
+ * mipsread.c (parse_external, parse_partial_symbols): Ignore stNil
+ symbols that are produced for statics in .o files and stLocal symbols
+ that are produced for every section in OSF/1 dynamically linked
+ executables.
+ * mipsread.c (psymtab_to_symtab_1): Put out `undefined symbols'
+ warning only under `verbose on' as there are many undefined symbols
+ in a dynamically linked executable.
+
+Wed Sep 22 10:28:06 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/i960/nindy960.mt: Don't define REMOTE_O; REMOTE_O was
+ intended only for VxWorks. Remove dcache.o from TDEPFILES now
+ that we pick it up from the default REMOTE_O.
+
+ * breakpoint.c (bpstat_what): Initialize retval.call_dummy and
+ retval.step_resume.
+
+ * mips-tdep.c (mips_frame_chain): If frame size zero, return zero.
+ * rs6000-tdep.c: Add comment about framelessness.
+
+ * remote-nindy.c: Declare ninMemGet and ninMemPut.
+
+Wed Sep 22 08:02:57 1993 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in: Add i386lynx-tdep to the right places.
+ (TARDIRS): Add gdbserver.
+
+ * exec.c (print_section_info): Print entry point.
+ * i386lynx-nat.c (i386lynx_saved_pc_after_call): Move into
+ i386lynx-tdep.c. Add core file support.
+ * i386lynx-tdep.c: New module for Lynx/386 target dependant code.
+ * maint.c: Add `maint info sections' command to print info about all
+ sections that BFD knows about for exec and core files.
+ * sparc-tdep.c (sparc_push_dummy_frame): Update stack pointer
+ before putting frame on the stack. Consolidate writes to reduce
+ traffic for remote debugging.
+ * config/i386/i386lynx.mh (NATDEPFILES): Remove exec.o.
+ * config/i386/i386lynx.mt (TDEPFILES): Add exec.o, i386lynx-tdep.o.
+ * config/i386/nm-i386lynx.h: Add target_pid_to_str().
+ * config/i386/tm-i386lynx.h: Remove target_pid_to_str().
+ * sparclite/Makefile.in: Add deps to keep Sun make happy.
+
+Tue Sep 21 17:48:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.h, breakpoint.c (bpstat_stop_status): Add new argument
+ not_a_breakpoint.
+ * infrun.c (wait_for_inferior): Pass it. Also consolidate the
+ test of whether we are stepping into a CURRENTLY_STEPPING macro.
+
+Tue Sep 21 17:22:34 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * breakpoint.c (bpstat_stop_status),
+ infcmd.c (step_1),
+ infrun.c (wait_for_inferior): collapse SHIFT_INST_REGS ifdef
+ and insert macro.
+
+ * m88k-tdep.c: include ieee-float.h. new global target_is_m88110.
+ new const struct ext_format_m88110 for float format.
+ (pic_prologue_code): add braces.
+ (next_insn): remove unused variable buf.
+ (frame_find_saved_regs): remove unused variables next_addr,
+ saved_regs, regnum.
+ (frame_locals_address): remove unused variables frame, ap.
+ (frame_args_address): remove unused variables frame, ap.
+ (push_parameters): add some breaks and a default case.
+
+ * remote-bug.c: remove redundant includes of value.h, target.h,
+ serial.h.
+ (bug_open): corrected typo, sr_multi_scan -> gr_multi_scan.
+ (bug_fetch_register): special case sfip register for m88110.
+ remove flag bit masking of pc registers. This should be handled
+ by the ADDR_BITS_* macros.
+ (bug_store_register): special case sfip register for m88110.
+ Corrected sprint format for extended registers.
+
+ * config/m88k/tm-m88k.h: white space and comment changes. include
+ ieee-float.h. expanded to cope with m88110 extended registers.
+ (R0_REGNUM, XFP_REGNUM, X0_REGNUM): new macros.
+ (SHIFT_INST_REGS): becomes a real macro.
+
+Tue Sep 21 17:48:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.c (breakpoint_1): Support bp_call_dummy.
+
+Tue Sep 21 17:06:19 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfread.c (record_minimal_symbol_and_info): Guess the section to
+ use from the type.
+ * objfiles.c: Include gdb-stabs.h for SECT_* macros.
+ (objfile_relocate): Relocate textlow and texthigh in psymtabs.
+ Relocate partial symbols. Check that minimal SYMBOL_SECTION is
+ nonnegative before using it.
+ * symtab.h: Adjust section field comment.
+
+ * remote.c (interrupt_query): New function.
+ (remote_interrupt_twice): Call interrupt_query.
+ (putpkt, getpkt): If quit_flag is set, call interrupt_query.
+ (remote_wait): Don't bother with objfile_relocate if the addresses
+ haven't changed.
+ (remote_fetch_registers): If we see a packet that doesn't start
+ with a hex character, fetch a new one.
+
+Tue Sep 21 11:44:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote.c, remote-utils.c: Use SERIAL_FLUSH_INPUT after opening it.
+
+ * printcmd.c (print_scalar_formatted): When truncating value we are
+ going to print as unsigned, handle it generally for any length
+ less than sizeof (LONGEST), rather than special-casing sizeof (char),
+ sizeof (short), and sizeof (long). Clarify comment on what this
+ is for.
+
+ * symfile.c (deduce_language_from_filename): Accept .cxx for C++.
+ * buildsym.c (start_subfile): Use deduce_language_from_filename
+ rather than checking for .C or .cc ourself.
+
+Mon Sep 20 14:53:11 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * defs.h: Declare argument of re_comp as const char *.
+
+ * remote.c, remote-mips.c: Use sr_get_debug not remote_debug.
+
+ * README: Say using bfd from another release doesn't generally work.
+
+Sat Sep 18 10:13:18 1993 Jim Kingdon (kingdon@poseidon.cygnus.com)
+
+ * mipsread.c (parse_type): Don't complain() if we guessed struct
+ and it was a union, or vice versa.
+
+ * defs.h (make_cleanup): Change PTR to void * when inside PARAMS.
+
+ Some of the following is in #ifdef CALL_DUMMY_BREAKPOINT_OFFSET.
+ * breakpoint.h (enum bptype): Add bp_call_dummy.
+ (struct bpstat_what): Add call_dummy field.
+ * infrun.c (wait_for_inferior): Deal with it.
+ * breakpoint.c (bpstat_what): Deal with call dummy breakpoint.
+ * infcmd.c (run_stack_dummy): Set the call dummy breakpoint.
+ * config/sparc/tm-sparc.h: Define CALL_DUMMY_BREAKPOINT_OFFSET.
+
+ * remote-sim.h: New file.
+ * remote-sim.c: Add remote debug feature. Rename stuff to distinguish
+ interface to simulator from gdb-specific stuff. Other changes.
+ * remote-sp64sim.c: Renamed to remote-sim.c.
+ Use sr_get_debug instead of our own sim_verbose/simif_snoop.
+ Use gnutarget in call to bfd_openr.
+ Rename simif_* to gdbsim_*.
+ * config/sparc/sp64sim.mt: Change remote-sp64sim.c to remote-sim.c.
+
+Fri Sep 17 04:41:17 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * findvar.c (extract_signed_integer): Cast *p to LONGEST before doing
+ the xor and subtract. Otherwise it will not sign extend if the type
+ of LONGEST is larger than int.
+ * cp-valprint.c (cp_print_class_method): Inhibit core dump if
+ domain is an undefined cross reference.
+ * valops.c (call_function_by_hand): Set real_pc to correct
+ value if CALL_DUMMY_LOCATION != ON_STACK.
+
+Thu Sep 16 20:37:06 1993 Jim Kingdon (kingdon@cirdan.cygnus.com)
+
+ * config/a29k/tm-a29k.h (FRAME_CHAIN): If rsize is zero, return zero.
+
+Thu Sep 16 13:16:22 1993 Stu Grossman (grossman at cygnus.com)
+
+ * infrun.c (wait_for_inferior): Allow user to single step within
+ a stack dummy.
+
+Thu Sep 16 12:34:01 1993 Jim Kingdon (kingdon@cirdan.cygnus.com)
+
+ * dbxread.c (copy_pending): Deal with END NULL.
+ (process_one_symbol): Add comments about what common_block NULL means.
+
+Wed Sep 15 14:50:26 1993 Jim Kingdon (kingdon@cirdan.cygnus.com)
+
+ * remote-udi.c, remote-adapt.c, remote-mm.c: Move processor_type
+ to tm-a29k.h and a29k-tdep.c and make it an enum.
+ * a29k-tdep.c (a29k_get_processor_type): New function. Fix many
+ aspects of how we detected the processor type.
+ * remote-udi.c, remote-adapt.c, remote-mm.c (*_open): Call it
+ rather than figuring out the type ourselves.
+
+Thu Sep 16 12:12:59 1993 Stu Grossman (grossman at cygnus.com)
+
+ * sparc-stub.c (_trap_low): Do restore/save sequence after
+ setting sp to ensure that we load the previous window from the
+ right place on the stack.
+
+Thu Sep 16 00:36:32 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mipsread.c: Many changes for alpha ecoff format:
+ Correct sizeof(int) == sizeof(long) assumptions.
+ Replace stParsed hack by putting the parsed types on the pending chain.
+ Replace mips specific ecoff mapping by ECOFF_REG_TO_REGNUM macro,
+ provide default for cross debugging.
+ Swapping the symbol back is no longer needed as the symbol is not
+ modified anymore.
+ Add new alpha basic types, handle btTypedef, handle stStaticProc
+ external symbols .
+ Update and clean up cross_ref for alpha cc cross ref variations.
+ Allocate types on the type_obstack to inhibit storage leaks.
+ * config/mips/tm-mips.h (ECOFF_REG_TO_REGNUM): Define.
+ * gdbtypes.c (recursive_dump_type): Dump TYPE_TAG_NAME if it is set.
+
+Tue Sep 14 09:12:17 1993 Jim Kingdon (kingdon@cirdan.cygnus.com)
+
+ * stabsread.c (read_type): Process "s" (size) type attribute.
+ If type is defined to another type, copy the type.
+
+Tue Sep 14 18:37:17 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/i386/i386v4.mh (NATDEPFILES): Move exec.o from here...
+ * config/i386/i386v4.mt (TDEPFILES): ...to here.
+
+Tue Sep 14 12:21:49 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * Makefile.in (remote_utils_h): add serial.h and target.h.
+ (main.o, remote-es.o, remote-nindy.o, remote.o): remove target.h
+ (already in remote_utils_h).
+ (remote-utils.o): new rule.
+
+ * remote-utils.h: include serial.h.
+
+ * serial.h: ifdef protect from multiple inclusion.
+
+ * remote.c, remote-nindy.c, remote-mon.c, remote-es.c: include
+ remote-utils.h.
+
+ * remote.c (remote_open), remote-nindy.c (nindy_open,
+ nindy_files_info), remote-mon.c (general_open), remote-es.c
+ (es1800_open): use remote-utils facilities for baud rate.
+
+Tue Sep 14 09:12:17 1993 Jim Kingdon (kingdon@cirdan.cygnus.com)
+
+ * paread.c, coffread.c, elfread.c, dwarfread.c:
+ Include <time.h> and <sys/types.h> before libbfd.h.
+
+ * paread.c: Define BYTES_IN_WORD before including aout/aout64.h.
+
+ * Makefile.in (a29k-tdep.o): Depend on $(defs_h).
+ * config/a29k/tm-a29k.h (SAVED_PC_AFTER_CALL): Use gr122 not lr0
+ if this is a transparent procedure.
+
+Mon Sep 13 16:06:43 1993 Jim Kingdon (kingdon@cirdan.cygnus.com)
+
+ * remote.c: Define remote_debug to 0 and #if 0 baud_rate. Temporary
+ hack so this file compiles again.
+
+ * remote-utils.c (gr_multi_scan): Cast return value from alloca.
+ (gr_multi_scan): #if 0 never-reached return(-1).
+
+ * remote-udi.c (udi_wait): Return inferior_pid not 0.
+
+Mon Sep 13 14:14:35 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ Collect some remote things into remote-utils.
+ * remote-utils.[ch]: new files of functions collected from several
+ different remote targets.
+ * Makefile.in (REMOTE_O): add remote-utils.o.
+ (dcache_h, remote_utils_h): new macros.
+ (HFILES): add $(remote_utils_h).
+ (ALLDEPFILES): add $(remote_utils_h).
+ (dcache.o): new rule.
+ (main.o, remote-bug.o): also depend on $(remote_utils_h).
+ * target.h (remote_debug): extern moved to remote-utils.h.
+ * target.c (find_default_run_target, find_core_target): initialize
+ runable.
+ (remote_debug): moved to remote-utils.c.
+ (_initialize_targets): move declaration of user variable
+ remotedebug to remote-utils.c.
+ * remote-bug.c: include remote-utils.h rather than dcache.h.
+ (bug_close, bug_write, bug_write_cr, desc, bug_dcache, timeout,
+ dev_name, check_open, is_open, readchar, readchar_nofail,
+ pollchar, expect, expect_prompt, get_hex_digit, get_hex_byte,
+ get_hex_word, bug_kill, bug_detach, bug_create_inferior,
+ multi-scan, bug_prepare_to_store, bug_fetch_word,
+ bug_store_word, bug_files_info, bug_mourn, bug_com, bug_device,
+ bug_speed): removed and replaced with facilities from
+ remote-utils.[ch].
+ (bug_read_inferior_memory): renamed to bug_read_memory.
+ (bug_write_inferior_memory): renamed to bug_write_memory.
+ (bug_xfer_inferior_memory): renamed to bug_xfer_memory.
+ (get_word): comment out this unused function for now.
+ (bug_settings, cpu_check_strings): new statics.
+ (bug_open): rewritten to use gr_open.
+ (_initialize_remote_bug): remove declarations of commands bug,
+ device, speed.
+ * main.c: include remote-utils.h.
+ (baud_rate): removed to remote-utils.c.
+ (main): handle baud rate settings using new facilities from
+ remote-utils.
+ * defs.h (baud_rate): removed extern.
+
+ m88110 support via bug-197 monitor.
+ * remote-bug.c (get_reg_name, bug_fetch_register,
+ bug_store_register): added m88110 extended register support.
+ (wait_strings): added bug-197 prompt.
+ (bug_wait): cope with bug-197 prompt.
+ (start_load): cope with either bug-197 or bug-187 prompt.
+
+Mon Sep 13 12:53:09 1993 Jim Kingdon (kingdon@cirdan.cygnus.com)
+
+ * inferior.h, infrun.c, thread.c, infcmd.c: Remove all uses of
+ pc_changed. If it was ever set to a non-zero value, it was before
+ GDB 2.8. It doesn't seem to have any useful function.
+
+ * defs.h: Don't define NORETURN (see comment).
+
+Sat Sep 11 10:46:09 1993 Jim Kingdon (kingdon@poseidon.cygnus.com)
+
+ * m88k-nat.c (fill_gregset): Set r31 and sfip.
+
+Thu Sep 9 10:18:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote-udi.c (udi_wait, case UDIStdinNeeded): Use a loop calling
+ getchar() (terminated only on '\n') instead of scanf. Send the
+ '\n' which terminates it to the remote system.
+
+ More gcc lint:
+ * exec.c (ignore): Return 0.
+ * stack.c (return_command): Fetch lazy value directly, not via
+ VALUE_CONTENTS, to avoid "value computed is not used".
+ * inflow.c (new_tty): Move osigttou inside #if.
+
+ * remote.c (remote_fetch_registers): If remote reply is short, just
+ note that fact and keep going (reading extra registers as all bits 0).
+ (remote_store_registers): Send number of registers that were found
+ by remote_fetch_registers.
+ * m68k-tdep.c, config/m68k/tm-m68k.h, config/m68k/tm-*.h: Remove
+ HAVE_68881. Define CANNOT_STORE_REGISTER if ptrace() can't write
+ floating registers.
+ * config/m68k/{tm-m68k-nofp.h,m68k-nofp.mt,tm-m68k-fp.h,m68k-fp.mt}:
+ Remove, replaced by {tm-m68k-em.h,m68k-em.mt}.
+ * Makefile.in, configure.in: Change accordingly.
+
+Thu Sep 9 04:59:03 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mipsread.c (cross_ref): Allow SGI extended symbol types as cross
+ reference targets.
+ * symmisc.c (print_symbol): Use TYPE_TAG_NAME not TYPE_NAME to avoid
+ printing of identities.
+
+Wed Sep 8 19:18:27 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.c (breakpoint_1): Deal with step resume breakpoint.
+
+Wed Sep 8 13:01:10 1993 K. Richard Pixley (rich@cygnus.com)
+
+ Gcc lint.
+ * config/m88k/tm-m88k.h (frame_find_saved_regs): prototype.
+ * config/h8300/tm-h8300.h (NUM_REGS): rewrite to avoid nested comment.
+ * blockframe.c (get_prev_frame_info): initialize address.
+ * breakpoint.c (bpstat_copy): initialize retval.
+ (bpstat_stop_status): initialize value_is_zero.
+ (bpstat_what): initialize bs_class.
+ (breakpoint_1, mention): add do-nothing case for bp_step_resume.
+ (break_command_1): initialize cond_end, addr_end, &
+ canonical_strings_chain.
+ (enable_breakpoint): initialize save_selected_frame.
+ * buildsym.c (end_symtab): initialize symtab & linetablesize.
+ * c-exp.y (parse_number): initialize i.
+ * c-typeprint.c (c_type_print_varspec_prefix): include
+ TYPE_CODE_BITSTRING in switch statements and do nothing.
+ * c-valprint.c (c_val_print): removed unused variable c.
+ * ch-valprint.c (chill_val_print): removed unused variable eltlen.
+ * cp-valprint.c (cp_print_class_method): initialize f & j.
+ * eval.c (evaluate_subexp): initialize pc2, arg1, arg2.
+ * expprint.c (print_subexp): initialize myprec, assoc, & tempstr.
+ * findvar.c (value_from_register): initialize first_addr.
+ * gdbtypes.c (lookup_struct_elt_type): localize use of temporary
+ variable typename.
+ * infcmd.c (run_stack_dummy): return zero rather than simple
+ return.
+ * infrun.c (wait_for_inferior): initialize stop_sp, prologue_pc.
+ remove symtab, appears unused.
+ (restore_selected_frame): return 1.
+ * mipsread.c (psymtab_to_symtab_1): initialize first_off.
+ (fixup_sigtramp): initialize b0.
+ * printcmd.c (do_examine): initialize val_type.
+ (print_frame_args): initialize b.
+ * ser-tcp.c (tcp_restore): comment out declaration. Appears
+ unused.
+ * ser-unix.c (hardwire_restore): comment out declaration. Appears
+ unused.
+ (hardwire_send_break): moved variable status into ifdef
+ HAVE_SGTTY.
+ (wait_for): moved variable numfds into ifdef HAVE_SGTTY.
+ * serial.h: comment change only.
+ * stabsread.c (rs6000_builtin_type): initialize rettype.
+ (read_range_type): initialize nbits.
+ * stack.c (print_frame_info): remove unused variable numargs.
+ (parse_frame_specification): remove unused variables arg1, arg2,
+ arg3.
+ (return_command): initialize return_value.
+ * symfile.c (cashier_psymtab): initialize pprev.
+ * symtab.c (find_pc_psymbol): initialize best.
+ (lookup_symbol): initialize s.
+ (make_symbol_completion_list): initialize quote_pos.
+ * thread.c: include command.h.
+ (thread_info): static declaration removed; unused.
+ (info_threads_command): fix == vs = typo.
+ * typeprint.c (whatis_exp): initialize old_chain.
+ * valprint.c (val_print_string): remove unused variable
+ first_addr_err. Initialize old_chain.
+ (_initialize_valprint): white space comment change.
+ * values.c (show_values): rewrite if statement to avoid empty
+ body.
+ (vb_match): remove unused variable fieldtype_target_type.
+
+Wed Sep 8 10:21:33 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (mipsread.o): Depend on $(bfd_h).
+
+Tue Sep 7 13:06:44 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbserver/Makefile.in (TAGS): config files are in
+ $(srcdir)/../config, not $(srcdir)/config.
+
+ * config/pa/tm-hppa.h: Declare target_read_pc and target_write_pc.
+ (STORE_RETURN_VALUE): Pass the correct offset of the return
+ register to write_register_bytes.
+ * hppa-tdep.c: Use target_write_pc if PCOQ_TAIL_REGNUM was not saved.
+
+Tue Sep 7 14:30:34 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * remote.c (remote_wait): Don't call error. Instead, call warning
+ inside a loop. User can ^C to get out.
+
+ * config/m68k/tm-m68k.h (FIX_CALL_DUMMY): Changed name of swapping
+ routine to match BFD name change.
+ * config/z8k/tm-z8k.h (FIX_CALL_DUMMY): Likewise.
+
+Mon Sep 6 15:01:57 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * elfread.c: change elf32_symbol_type to elf_symbol_type
+
+Mon Sep 6 15:43:25 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * remote.c (remote_wait): Added 'W' and 'N' responses.
+
+Fri Sep 3 08:57:10 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * main.c, utils.c: Add comments about immediate_quit.
+
+ * elfread.c (elf_symtab_read): Don't add symbols starting with ".L"
+ to minimal symbols.
+
+ * target.c (pop_target): Don't try to deal with the stack becoming
+ empty. Shouldn't happen and the code that tried was broken.
+
+ * dcache.c: Cast return value from xmalloc.
+
+ * remote.c: Move setting of immediate_quit from remote_open to
+ remote_start_dummy and set it back to zero when done.
+
+Thu Sep 2 00:07:36 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * m88k-tdep.c: Remove a bunch of unused #includes.
+
+ * language.h: Add comment about current_language.
+
+ * mips-tdep.c (_initialize_mips_tdep): Change heuristic-fence-post
+ from var_uinteger to var_zinteger.
+
+ * configure.in: Fix typo (delta88r4 -> delta88v4).
+
+ * config/m88k/xm-delta88.h: Don't include sys/siginfo.h. It was
+ to make this work on SVR4 before SVR4 had its own configuration,
+ and it breaks SVR3.
+
+ * config/m88k/tm-delta88v4.h: Define FRAME_CHAIN_VALID_ALTERNATE.
+
+ * config/m88k/delta88v4.h (NATDEPFILES): Remove infptrace.o inftarg.o.
+
+ * config/m88k/xm-dgux.h: Renamed from config/m88k/xm-m88k.h.
+ * config/m88k/m88k.mh: Use xm-dgux.h.
+ * config/m88k/xm-m88k.h: New file, with HOST_BYTE_ORDER,
+ MAKEVA_END and MAKEVA_ARG.
+ * config/m88k/xm-*.h: Include m88k/xm-m88k.h.
+ * printcmd.c: Remove __INT_VARARGS_H code; now in xm-m88k.h.
+
+Wed Sep 1 19:31:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote-udi.c (udi_wait): Call `warning' not `error'.
+
+ * symtab.c (COMPLETION_LIST_ADD_SYMBOL): If the symbol has a
+ demangling, don't put the mangled form in the completion list.
+
+ * symtab.c, symfile.c, c-exp.y, ch-exp.y, m2-exp.y, buildsym.c,
+ symfile.h, stabsread.c, minsyms.c, solib.c, nlmread.c, dwarfread.c
+ partial-stab.h, symmisc.c, gdbtypes.c: Lint. Remove (or put
+ inside #if) unused variables and labels. Fix unclosed comment.
+ Deal with enumeration values unhandled in switch statements. Make
+ sure non-void functions return values. Include appropriate
+ headers.
+ * dbxread.c (elfstab_build_psymtabs): Don't check for unsigned
+ value < 0.
+
+Wed Sep 1 14:36:00 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * i960-tdep.c, ns32k-pinsn.c, remote-adapt.c, xcoffread.c:
+ index -> strchr.
+
+Wed Sep 1 11:35:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote.c: Add comment explaining why dcache is disabled.
+ (remote_fetch_word, remote_store_word): Make static and #if 0.
+ They are not called from anywhere.
+
+Wed Sep 1 14:41:28 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * arm-tdep.c, convex-tdep.c, convex-xdep.c, dbxread.c,
+ h8300-tdep.c, h8500-tdep.c, i960-pinsn.c, i960-tdep.c,
+ infptrace.c, m88k-tdep.c, mips-tdep.c, regex.c, remote-vx.c,
+ rs6000-tdep.c, xcoffexec.c, xcoffread.c, z8k-tdep.c,
+ config/arm/tm-arm.h, config/convex/tm-convex.h,
+ config/gould/tm-np1.h, config/gould/tm-pn.h,
+ config/m68k/tm-isi.h, config/ns32k/tm-umax.h,
+ config/pa/tm-hppa.h, config/pyr/tm-pyr.h,
+ config/rs6000/tm-rs6000.h, config/tahoe/tm-tahoe.h,
+ config/vax/tm-vax.h: bzero -> memset.
+
+ * regex.c: bcmp -> memcmp.
+
+Wed Sep 1 11:35:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * symtab.c (find_pc_line, find_line_common),
+ symtab.h (struct linetable), xcoffread.c (arrange_linetable):
+ Revise comments re linetable sorting.
+ * buildsym.c (compare_line_numbers): Sort by pc, not by line.
+ * coffread.c: Tell end_symtab to sort the line table.
+
+ * coffread.c: Re-work a lot of the coff-specific stuff to use stuff
+ in buildsym.c. This includes coff_finish_block, coff_context_stack,
+ coff_local_symbols, coff_file_symbols, coff_global_symbols,
+ coff_end_symtab and coff_add_symbol_to_list.
+ (read_enum_type): Deal with it now that we have a "struct pending"
+ not a "struct coff_pending".
+
+ * buildsym.c (end_symtab): Don't realloc subfile->linetable.
+
+Wed Sep 1 13:12:43 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * a68v-nat.c, altos-xdep.c, convex-tdep.c, convex-xdep.c,
+ findvar.c, hppab-nat.c, hppah-nat.c, i386mach-nat.c,
+ irix4-nat.c, m68k-tdep.c, m88k-tdep.c, mipsread.c, regex.c,
+ remote-bug.c, remote-hms.c, rs6000-nat.c, rs6000-tdep.c,
+ sparc-nat.c, stabsread.c, sun3-nat.c, sun386-nat.c, symfile.c,
+ umax-xdep.c, xcoffread.c, 29k-share/udi/udip2soc.c,
+ 29k-share/udi/udr.c, config/a29k/tm-a29k.h, config/arm/tm-arm.h,
+ config/convex/tm-convex.h, config/gould/tm-np1.h,
+ config/gould/tm-pn.h, config/h8300/tm-h8300.h,
+ config/h8500/tm-h8500.h, config/i386/tm-i386aix.h,
+ config/i386/tm-sun386.h, config/i386/tm-symmetry.h,
+ config/i960/tm-i960.h, config/m68k/tm-news.h,
+ config/m88k/tm-m88k.h, config/mips/tm-mips.h,
+ config/ns32k/tm-merlin.h, config/ns32k/tm-umax.h,
+ config/pa/tm-hppa.h, config/pyr/tm-pyr.h,
+ config/rs6000/tm-rs6000.h, config/sh/tm-sh.h,
+ config/tahoe/tm-tahoe.h, config/vax/tm-vax.h,
+ config/z8k/tm-z8k.h, nindy-share/nindy.c: bcopy -> memcpy.
+
+Wed Sep 1 05:05:53 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mipsread.c (parse_partial_symbols): Use language from FDR if it
+ is unambigous. Patch from ptf@delcam.co.uk (Paul Flinders).
+ * mipsread.c (ecoff_symfile_info): New struct to hold the global
+ pending_list.
+ * mipsread.c (mipscoff_symfile_init, parse_partial_symbols):
+ Allocate the global pending list and link it to the objfile.
+ * mipsread.c (is_pending_symbol, add_pending): Use global pending
+ list from objfile. Allocate pending list entries from the
+ psymbol_obstack.
+ * mipsread.c (free_pending): Remove. The pending list is now
+ freed when the psymbol_obstack is freed.
+ * mipsread.c (psymtab_to_symtab1): Remove pending list allocation,
+ the global pending list is used now.
+ * mipsread.c (parse_partial_symbols): Skip only the first
+ file indirect entry when building the dependency list.
+
+Tue Aug 31 15:01:27 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ Break dcache code out of remote.c.
+ * dcache.h: white space changes only.
+ * dcache.c: add user settable variable to set whether data caching
+ is in use.
+ * remote.c: include dcache.h. removed data caching code which is
+ now in dcache.c. Compile in data caching again. (data caching
+ is currently off by default.)
+ (remote_read_bytes, remote_write_bytes): change second arg to
+ unsigned char.
+ (remote_dcache): new static variable.
+ * Makefile.in (REMOTE_O): add dcache.o.
+ * config/m88k/m88k.mt (TDEPFILES): removed dcache.o.
+
+ Break dcache code out of remote-nindy.c.
+ * remote-nindy.c: removed dcache code. Changed callers to use new
+ conventions. include dcache.h.
+ (nindy_dcache): new static variable.
+ * config/i960/nindy960.mt (TDEPFILES): added dcache.o.
+
+ Break dcache code out of remote-bug.c into dcache.[hc].
+ * Makefile.in (dcache_h): new macro.
+ (HFILES): added $(dcache_h).
+ (ALLDEPFILES): added dcache.c.
+ (dcache.o): new rule.
+ (remote-bug.o): now depends on $(dcache_h).
+ * remote-bug.c: include dcache.h. remove externs for insque and
+ remque, add extern for bcopy. Prototype bug_close,
+ bug_clear_breakpoints, bug_write_cr. dcache code moved to
+ dcache.[hc]. Changed dcache calling convention to include an
+ initial DCACHE argument.
+ (bug_dcache): new static variable.
+ (bug_read_inferior_memory): change second arg to
+ unsigned char.
+ * dcache.[ch]: new files.
+ * config/m88k/m88k.mt (TDEPFILES): add dcache.o.
+
+Tue Aug 31 10:33:13 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * c-typeprint.c (c_print_type_base): Treat show = 0 just like
+ show < 0. The only case where we had been distinguishing is that
+ show = 0 used to print "struct " or "enum " instead of
+ "struct {...}" or "enum {...}" which seems clearly wrong.
+
+Mon Aug 30 17:51:32 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * configure.in: recognize m88110 as an m88k.
+
+Mon Aug 30 16:07:59 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * valops.c (call_function_by_hand): If we discard cleanups, call
+ bpstat_clear (&inf_status.stop_bpstat).
+
+Mon Aug 30 12:47:46 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * stabsread.h, dbxread.c (end_psymtab): Return NULL if the psymtab
+ was empty and thrown away.
+ * mipsread.c (parse_partial_symbols): Do not add empty psymtabs to
+ dependency list, skip self dependencies.
+ * mipsread.c (parse_fdr): Removed, obsolete.
+ * mipsread.c (parse_lines): Check for cbLine being zero, not
+ cbLineOffset.
+ * mipsread.c (struct symloc): Add pst_language.
+ * mipsread.c (parse_partial_symbols): Set up proper language for
+ header files, save it in pst_language for psymtab_to_symtab_1.
+ * mipsread.c (psymtab_to_symtab_1): Use pst_language.
+
+Mon Aug 30 10:48:06 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.in: Fix typo m88*-motorola-svr4* -> sysv4*.
+
+Fri Aug 27 17:09:19 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * paread.c: Include som.h instead of libhppa.h. (From Utah.)
+
+Fri Aug 27 09:30:40 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * symmisc.c (dump_symtab): Use catch_errors around print_symbol.
+ Change calling sequence of print_symbol to fit catch_errors.
+
+ * mips-tdep.c: Call reinit_frame_cache every time the user does
+ "set heuristic-fence-post".
+
+ * gdbserver/low-sun3.c: New file.
+ * gdbserver/Makefile.in, config/m68k/sun3.mh: Change accordingly.
+
+ * Rename files for 14-character limits:
+ gdbserver/remote-gutils.c -> gdbserver/utils.c
+ gdbserver/remote-inflow.c -> gdbserver/low-lynx.c
+ gdbserver/remote-inflow-sparc.c -> gdbserver/low-sparc.c
+ gdbserver/remote-server.c -> gdbserver/server.c
+ remote-monitor.c -> remote-mon.c
+ * Makefile.in, gdbserver/Makefile.in, gdbserver/configure.in,
+ config/m68k/monitor.mt, config/i386/i386lynx.mh,
+ config/sparc/sun4os4.mh: Change accordingly.
+ * gdbserver/Makefile.in: Remove more junk inherited from gdb Makefile.
+
+Thu Aug 26 14:32:51 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infcmd.c, inferior.h (run_stack_dummy): If we stop somewhere
+ besides the dummy, return 1 rather than calling error().
+ Let caller print the error message. Remove name argument.
+ * valops.c (call_function_by_hand): Deal with changes to calling
+ sequence of run_stack_dummy. Discard restore_inferior_status cleanup
+ if run_stack_dummy returns 1.
+
+ * Version 4.10.2.
+
+ * config/mips/tm-mips.h (EXTRACT_STRUCT_VALUE_ADDRESS):
+ Get struct return address from v0, not a0.
+
+ * infrun.c (restore_inferior_status): Use catch_errors when
+ restoring selected frame.
+
+Wed Aug 25 21:52:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infrun.c (save_inferior_status, restore_inferior_status):
+ Save and restore the registers too.
+ * inferior.h (struct inferior_status): Add "registers".
+
+Tue Aug 24 00:36:17 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dbxread.c (end_psymtab): Clean up comment.
+
+ * frame.h, symtab.h, findvar.c (read_var_value): Change basereg
+ support to use LOC_BASEREG rather than SYMBOL_BASEREG_VALID.
+ * dwarfread.c: Use LOC_BASEREG where appropriate.
+ * Various: Support LOC_BASEREG and LOC_BASEREG_ARG.
+
+ * coffread.c (init_lineno, init_stringtab): Don't check whether
+ xmalloc returned NULL.
+
+ * config/vax/xm-vaxult.h: Define NO_PTRACE_H.
+
+ * target.c, target.h: Add "set remotedebug" command.
+ * remote-bug.c, remote.c, remote-mips.c: Remove "set remotedebug" and
+ "set m88ksnoop" options and use generic "set remotedebug" instead.
+ * NEWS: Describe this change.
+
+Mon Aug 23 20:26:22 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * buildsym.h: Remove declaration of dbxread.c functions.
+ * stabsread.h: Group together dbxread.c functions.
+ Move elfstab_build_psymtabs here from symfile.h.
+ Declare pastab_build_psymtabs.
+ * elfread.c, paread.c: Include stabsread.h (for stabsread_new_init
+ declaration, etc).
+
+Mon Aug 23 17:16:23 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * remote-bug.c: rename quiet to bug88k_snoop.
+ (double_scan, multi_scan): generalize double_scan into a scan
+ for multiple patterns. Rename to multi_scan.
+ (bug_wait, bug_write_inferior_memory): adapt to use the new
+ multi_scan in order to catch and represent target bus errors.
+ (bug_scan): currently unused, so comment out.
+ (bug_quiet): removed. Replaced with a standard user settable boolean.
+
+ * m88k-tdep.c: remove include of sys/dir.h. Appears unnecessary
+ and isn't available on solaris.
+
+Mon Aug 23 14:56:42 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/m88k/{delta88v4.mt,delta88v4.mh}: New files
+ * config/m88k/delta88.mh: Fix comment.
+ * config/m88k/tm-delta88.h: Remove unused BCS define.
+ * config/m88k/{tm-delta88v4.h,xm-delta88v4.h,nm-delta88v4.h}:
+ New files.
+ * configure.in: Recognize m88*-motorola-sysv4*.
+ * m88k-nat.c: Always include sys/types.h; don't depend on USG.
+
+Mon Aug 23 12:57:42 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mipsread.c (parse_symbol, parse_type, cross_ref): Pass name of
+ symbol as an argument and use it in complaints.
+ * symmisc.c (dump_psymtab): Dump filenames of dependencies.
+
+Mon Aug 23 1993 Sean Fagan (sef@cygnus.com)
+ and Jim Kingdon (kingdon@cygnus.com)
+
+ Add NetBSD support:
+ * configure.in: Recognize netbsd.
+
+Sun Aug 22 22:50:32 1993 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c (get_textlow): Don't go past a K_END when looking for a
+ K_FUNCTION. Avoids losing on source files with no functions.
+
+Fri Aug 20 14:01:39 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote-nindy.c: Remove unused include of sys/ioctl.h.
+
+ * frame.h, symtab.h: Revise comments regarding baseregs.
+
+Fri Aug 20 15:07:05 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mipsread.c (parse_partial_symbols, psymtab_to_symtab_1):
+ Set language for psymtab and symtab.
+ * mipsread.c (new_symbol): Set language and initialize demangled
+ name for symbol.
+ * symmisc.c (print_symbol): Use SYMBOL_SOURCE_NAME when printing
+ the symbol type.
+ * symtab.c (decode_line_1): Inhibit coredumps with cfront executables.
+
+Fri Aug 20 14:01:39 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Move KERNEL_U_ADDR from xm-hp300bsd.h to nm-hp300bsd.h and make
+ it conditionalized on 4.3 vs. 4.4.
+ * config/m68k/nm-hp300bsd.h: Move REGISTER_U_ADDR out of 4.3 and
+ 4.4 sections; it was identical and now works for 4.4.
+
+ * mips-tdep.c (is_delayed): Use INSN*BRANCH* not ANY_DELAY.
+
+ * printcmd.c (MAKEVA_END): Update this version to use "aligner".
+
+Thu Aug 19 22:08:09 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/vax/tm-vax.h (BELIEVE_PCC_PROMOTION): Define.
+ * mipsread.c (parse_symbol, parse_type, cross_ref): Handle corrupt
+ file indirect entries with complaints instead of core dumps. Remove
+ complaint for stTypedef within aggregates.
+
+Thu Aug 19 17:58:39 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * coffread.c (process_coff_symbol): Ignore tagnames like .0fake.
+
+ * coffread.c (coff_read_enum_type): #if 0 out code which changes
+ enum {FALSE, TRUE} into boolean.
+
+ * config/m68k/delta68.m{t,h}: Use nm-delta68.h, etc. not
+ non-existent files nm-delta.h, etc.
+ * config/m68k/tm-delta68.h: Define CANNOT_STORE_REGISTER.
+ * delta68-nat.c: Add "[0]" in offsetof argument.
+ * delta68-nat.c (_initialize_kernel_u_addr): Don't try to set up
+ nl with initializer, just assign to it. Check n_scnum field on
+ return.
+
+Wed Aug 18 21:42:52 1993 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c (read_hpux_symtab): Call SET_NAMESTRING for K_MODULE
+ debug symbols.
+
+Wed Aug 18 12:03:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * printcmd.c (print_address), values.c (value_as_pointer): Don't
+ use ADDR_BITS_REMOVE.
+ * defs.h: Try to clarify comment about ADDR_BITS_REMOVE.
+
+ * blockframe.c (block_innermost_frame): Uncomment.
+ Return NULL if passed NULL.
+ * frame.h: Declare it.
+ * expression.h (union exp_element): Add field block.
+ * parse.c (write_exp_elt_block): New function.
+ * expression.h (OP_VAR_VALUE): Now takes additional struct block *.
+ * *-exp.y: Write block for OP_VAR_VALUE.
+ * eval.c, expprint.c, parse.c: Deal with block for OP_VAR_VALUE.
+ * valops.c, value.h (value_of_variable), callers:
+ Add second argument, for block.
+
+ * main.c (gdb_readline): If we read some characters followed by EOF,
+ return them rather than returning NULL.
+
+Tue Aug 17 11:14:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * mips-tdep.c: Remove unused #ifndef NUMERIC_REG_NAMES and add comment.
+
+Tue Aug 17 15:10:04 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config/m88k/tm-m88k.h: Fix typo in comment.
+ (FP_REGNUM): define in terms of SP_REGNUM
+ rather than by absolute number. Also clearly comment that this
+ is a convenient lie in order to decrease future confusion.
+ (ACTUAL_FP_REGNUM): new macro for FP.
+ (FRAME_CHAIN_VALID): removed. Standard default works fine.
+ * m88k-tdep.c (frame_chain_valid): redundant, so removed.
+ (NEXT_PROLOGUE_INSN): removed unused fourth arg, fixed all
+ callers.
+ (read_next_frame_reg): declare static.
+ (examine_prologue): removed unused variabel insn2, rename insn1
+ to insn, rewrote comment about finding fp, sp, etc. set frame_fp
+ based on ACTUAL_FP_REGNUM rather than FP_REGNUM which is
+ actually a scammed alias for SP_REGNUM on m88k.
+
+ * frame.h: fixed typo in comment.
+
+Tue Aug 17 11:14:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * 29k-share/udi/udiphcfg.h: Always include udiphunix.h not udiphdos.h.
+
+ * complaints.c (complain): fflush (stdout) after output.
+
+Tue Aug 17 01:43:55 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * blockframe.c, frame.h (sigtramp_saved_pc): New routine to fetch
+ the saved pc from sigcontext on the stack for BSD signal handling.
+ * config/i386/tm-i386bsd.h (SIGTRAMP_START, SIGTRAMP_END, FRAME_CHAIN,
+ FRAMELESS_FUNCTION_INVOCATION, FRAME_SAVED_PC, SIGCONTEXT_PC_OFFSET):
+ Define to make backtracing through sigtramp work.
+ * config/vax/tm-vax.h (SIGTRAMP_START, SIGTRAMP_END, TARGET_UPAGES,
+ FRAME_SAVED_PC, SIGCONTEXT_PC_OFFSET): Ditto.
+
+Mon Aug 16 13:52:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * main.c (cd_command): If current_directory on entry is "/", then
+ don't append an extra slash.
+ Don't assume that /../.. means /.
+
+ * target.c (target_xfer_memory): Clear errno before calling
+ to_xfer_memory.
+
+ * stack.c (frame_info, print_frame_info): Add comment about using
+ the starting source line number on a line boundary if backtracing
+ through sigtramp.
+
+Mon Aug 16 09:52:33 1993 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c: Add U Utah contribution notice. Add TODO list.
+ (hp_type_lookup): Use TYPE_NAME and TYPE_TAG_NAME.
+ (process_one_debug_symbol): Likewise.
+
+Mon Aug 16 02:56:01 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * blockframe.c (create_new_frame, get_prev_frame_info):
+ Use the function name when calling IN_SIGTRAMP.
+ * config/m68k/tm-m68k.h (SIG_PC_FP_OFFSET, SIG_SP_FP_OFFSET):
+ Define for correct handling of bachtraces through _sigtramp.
+ * m68k-tdep.c (m68k_find_saved_regs): Adjust saved sp for fake
+ sigtramp frames.
+ * mipsread.c (parse_type): Handle corrupt TIR info with complaint
+ instead of core dump.
+ * mipsread.c (parse_partial_symbols): Put static symbols into the
+ mimimal symbol table, use proper mst_types for all minimal symbols.
+ * stack.c (frame_info, print_frame_info): Use the starting source
+ line number on a line boundary if backtracing through sigtramp.
+
+Fri Aug 13 14:37:05 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * remote-bug.c: include gdbcmd.h.
+ (sleep, remque, insque): forward decls added.
+ (bug_fetch_registers, bug_store_registers): forward decls
+ removed.
+ (bug_read_inferior_memory, bug_write_inferior_memory): forward
+ decls added.
+ (srec_frame, srec_max_retries, srec_bytes, srec_echo_pace,
+ srec_sleep, srec_noise): new static variables for user settable
+ options. Mostly these are for debugging and tuning. I don't
+ expect them to stay user settable options for long.
+ (timeout): change default to 4 seconds.
+ (check_open): declare funtion static, force return value.
+ (readchar_nofail): if timeout, then say so if not being quiet.
+ (pollchar, double_scan, bug_scan, bug_srec_write_cr,
+ start_load): new functions.
+ (bug_wait): rewritten to use double scan.
+ (expect): while (1) -> for (;;)
+ (get_hex_digit): rewrite if condition to avoid gcc complaints.
+ (bug_load, bug_create_inferior, bug_open, bug_store_register):
+ removed unused variables.
+ (bug_load): replaced DELTA macro with user settable srec_frame
+ variable. Other minor lint.
+ (find_end_of_word, is_baudrate_right, set_rate, not_bug_wait,
+ gethex, timed_read, translate_addr, bug_before_main_loop):
+ unsused and removed.
+ (bug_resume): add missing first arg, pid.
+ (get_reg_name): use ip rather than cr04.
+ (bug_write, bug_write_cr, but_clear_breakpoints, bug_quiet):
+ declare type, args, and explicitly return.
+ (bug_store_register): straighten out the ip vs cr04 confusion.
+ (bug_write_inferior_memory): rewrite to cope with errors while
+ downloading s-records.
+ (bug_read_inferior_memory): declare static.
+ (bug_clear_breakpoints): expect nobr before prompt.
+ (_initialize_remote_bug): add initializations for srec-bytes,
+ srec-max-retries, srec-frame, srec-noise, srec-sleep,
+ srec-echo-pace.
+
+ * Makefile.in (remote-bug.o): new rule.
+ (ALLDEPFILES): added remote-bug.c
+
+ * remote-hms.c (hms_wait): use -1 for timeout's which means block
+ forever rather than 99999.
+
+ * ser-unix.c (get_tty_state): if a descriptor is not a tty, then
+ simply save encode this fact as the process group and return
+ success rather than an error.
+ (set_tty_state): if process group is -1, do not reset the
+ process group.
+ (hardwire_reachar): comment change.
+
+ * serial.h: comment change.
+
+ * config/m88k/tm-m88k.h: comment change to remove embedded
+ comment.
+ (SKIP_PROLOGUE): skip_prologue returns a value which is expected
+ to reset the pc argument. So reset it.
+
+Fri Aug 13 10:15:24 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.10.1 after release and cvs
+ tagging.
+
+Thu Aug 12 20:40:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbserver/Makefile.in: Use GDBSERVER_LIBS and
+ GDBSERVER_DEPFILES. Also remove much (but not all that could be
+ removed) crud inherited from gdb Makefile.in.
+ * config/i386/i386lynx.mh, config/sparc/sun4os4.mh: Define GDBSERVER_*.
+ * gdbserver/README: Say it works on Sun and change configuration
+ instructions slightly.
+
+Wed Aug 11 18:56:59 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * config/i386/i386v4.mh: use -lsocket and -lnsl, for remote
+ targets that use BSD style network connections
+
+Wed Aug 11 17:54:24 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote-{monitor,bug}.c: Make bug_ops not static (forward declaration
+ of statics doesn't work with SunOS4 /bin/cc).
+ Rename the occurrence in remote-monitor.c to monitor_bug_ops.
+
+Tue Aug 10 13:07:14 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * blockframe.c (find_pc_partial_function),
+ mips-tdep.c (find_proc_desc): Deal with "pathological" case.
+
+Tue Aug 10 14:50:30 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * utils.c (wrap_here): Allow indent to be NULL.
+ (fputs_filtered): Don't check for null wrap_indent (wrap_here now
+ guarantees that it isn't, and anyway we were only checking one out
+ of the two places we dereferenced it).
+
+ * objfiles.h (struct objfile): Clean up comments for
+ {obj,sym}_private to clarify what they are private to.
+
+Mon Aug 9 16:45:00 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * stabsread.c, buildsym.c (hashname): Moved function to
+ buildsym.c, as suggested in the sources.
+
+Mon Aug 9 09:53:45 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote-udi.c: Make udi_ops extern rather than trying forward
+ declaration of a static variable.
+
+ * hppab-nat.c: Define ptrace to call_ptrace and pass the 5th arg
+ there, rather than using an ANSI C specific macro.
+
+ * 29k-share/udi/udr.c: Include fcntl.h not sys/fcntl.h. Also put
+ sys/types.h near the top (just on general principles).
+
+ * environ.c (set_in_environ): Remove G960BASE and G960BIN; they are
+ no longer used.
+
+ * gdbcore.h: New variable gnutarget.
+ * core.c: Add commands to set and show it.
+ * Callers to bfd_*open*: Pass gnutarget instead of NULL as target.
+ * environ.c (set_in_environ): For GNUTARGET, use set_gnutarget not
+ putenv.
+
+ * symtab.c (decode_line_1): Give error on unmatched single quote.
+
+Sun Aug 8 13:59:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * ser-unix.c (hardwire_send_break) [HAVE_SGTTY]: Use select not usleep.
+
+ * remote.c: Add comments about 'd', 'r', and unrecognized requests.
+
+ * inflow.c (terminal_init_inferior): Don't muck with tty state if
+ gdb_has_a_terminal() is false.
+
+Sun Aug 8 10:07:47 1993 Fred Fish (fnf@cygnus.com)
+
+ * dwarfread.c (record_minimal_symbol): Remove prototype and
+ function.
+ * dwarfread.c (add_partial_symbol): Remove code to add minimal
+ symbols and remove comment about limitations. Experiments show
+ that now that gdb handles the ELF symtab better for creating
+ minimal symbols, that no additional information is added by
+ examining the DWARF information, and in fact, given the
+ limitations, the DWARF code was actually making things worse.
+
+Sat Aug 7 10:59:03 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * elfread.c (elf_symtab_read): Properly sort out the bss symbols
+ from the data symbols and give them the correct minimal_symbol_type.
+ Add file static symbols to the minimal symbol table, not just
+ global symbols. Add absolute symbols as well (like _edata, _end).
+ Redo stabs-in-elf special symbol handling now that file static
+ symbols are entered into the into the minimal symbol table.
+ * dwarfread.c (add_partial_symbol): Add comment about limitations
+ of DWARF symbols for distinquishing data from bss when adding
+ minimal symbols. Add file local symbols to minimal symbols.
+
+Thu Aug 5 08:58:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * ser-go32.c: Define job_control variable.
+
+Thu Aug 5 15:56:13 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: z8k-coff is the same as z8k-sim
+
+Thu Aug 5 08:58:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * 29k-share/udi/udip2soc.c: Include sys/types.h before sys/file.h.
+
+ * config/i386/tm-i386bsd.h (NUM_REGS): There are only 10, not 11.
+
+ * inflow.c: Put all uses of F_GETFL and F_SETFL in #ifdef F_GETFL.
+
+ * 29k-share/udi/udip2soc.c: Include fcntl.h not sys/fcntl.h.
+
+Wed Aug 4 18:32:12 1993 Fred Fish (fnf@cygnus.com)
+
+ * inflow.c (pass_signal): Signal handlers take one int arg;
+ supply an unused one to make it type compatible as an arg to
+ signal().
+
+Tue Aug 3 18:34:14 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/mips/tm-mips.h: Include bfd.h before coff/sym.h.
+
+Tue Aug 3 15:34:57 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (ALLCONFIG): Add config/i386/i386nw.mt,
+ config/m68k/delta68.mh, config/m68k/delta68.mt,
+ config/m68k/dpx2.mh, config/m68k/dpx2.mt, config/mips/riscos.mh,
+ config/mips/news-mips.mh.
+ * Makefile.in (ALLPARAM): Add config/i386/nm-symmetry.h,
+ config/i386/tm-i386nw.h, config/m68k/nm-delta68.h,
+ config/m68k/tm-delta68.h, config/m68k/xm-delta68.h,
+ config/m68k/nm-dpx2.h, config/m68k/tm-dpx2.h,
+ config/m68k/xm-dpx2.h, config/mips/xm-makeva.h.
+ * Makefile.in (ALLDEPFILES): Add dpx2-nat.c.
+
+Tue Aug 3 12:02:09 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mipsread.c: Updated for BFD ECOFF changes. Now gets the
+ swapping routines and external structure sizes via the
+ ecoff_backend information. No longer includes coff/mips.h.
+
+Tue Aug 3 10:58:04 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (SFILES): Add thread.c
+
+Tue Aug 3 10:21:58 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * remote-sp64sim.c (simif_create_inferior): Add FIXME regarding
+ sim_set_args return code.
+
+Mon Aug 2 16:35:31 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * Makefile.in (VERSION): bumped to 4.9.4.
+
+ * remote-monitor.c: updated copyright.
+ (bug_ops, monitor_desc): now static.
+ (monitor_desc): in several places, check and/or set to NULL.
+
+ * remote-hms.c (hms_files_info): Add the appropriate items where
+ missing in the printf call.
+
+ * remote-bug.c: new file for m88k bug support.
+
+ * config/m88k/m88k.mt (TDEPFILES): added remote-bug.o.
+
+Mon Aug 2 14:22:09 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * h8300-tdep.c: Use new variable h8300hmode.
+
+Mon Aug 2 12:06:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * valops.c (typecmp): If we are passing a non-reference to a function
+ which takes a reference, pass the address.
+ (value_arg_coerce): Don't use COERCE_ENUM; we don't want to dereference
+ references here.
+
+ * thread.c (thread_switch): Define as static.
+ (add_thread): Cast return value from xmalloc.
+
+ * gdbtypes.c (fill_in_vptr_fieldno): Call check_stub_type.
+ * gdbtypes.{c,h}: Improve comments on vptr_fieldno.
+
+Mon Aug 2 11:58:52 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * README: Elaborate on gdb C++ support and cfront support.
+
+Mon Aug 2 11:30:57 1993 Stu Grossman (grossman at cygnus.com)
+
+ * i386lynx-nat.c, thread.c, thread.h: Update copyrights.
+
+Mon Aug 2 12:06:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (ALLDEPFILES): Add i386lynx-nat.c.
+
+Mon Aug 2 08:42:50 1993 Stu Grossman (grossman at cygnus.com)
+
+ * gdbserver/remote-inflow.c (create_inferior): Fix comments, and
+ error msg. Setup seperate process group for child.
+ * (write_inferior_memory): Sleep for 1 second and retry on ptrace
+ failure.
+
+Sun Aug 1 22:58:18 1993 Stu Grossman (grossman at cygnus.com)
+
+ * config/i386/i386lynx.mh (NATDEPFILES): Drop coredep (for now).
+ * config/i386/nm-i386bsd.h: Protect from multiple inclusion.
+ * config/i386/nm-i386lynx.h: Lotsa new host porting stuff.
+ * config/i386/tm-i386lynx.h: Define SAVED_PC_AFTER_CALL and
+ target_pid_to_str.
+
+ * Makefile.in (CLIBS): Reorder to make Lynx ld happy.
+ * (HFILES): New file thread.h.
+ * (OBS): New file thread.c.
+ * configure.in: Host config for Lynx/386.
+ * fork-child.c (fork_inferior): Call init_thread_list().
+ * infrun.c (resume): Add pid to invocation of target_resume().
+ * (wait_for_inferior): Pay attention to pid from target_wait().
+ Multi-threading code now uses this to determine what to do.
+ * inftarg.c (child_wait): Conditionalize based on CHILD_WAIT macro.
+ Use target_pid_to_str() macro throughout when printing pid.
+ * inferior.h (child_resume): Add pid to prototype.
+ * hppab-nat.c hppah-nat.c infptrace.c (child_resume): Pass in pid as
+ argument, instead of using inferior_pid.
+ * procfs.c (procfs_resume): Pass in pid as argument. Ignored for
+ now. Use target_pid_to_str() macro throughout for printing process id.
+ * remote-adapt.c (adapt_resume): Pass in pid as argument.
+ * remote-eb.c (eb_resume): Pass in pid as argument.
+ * remote-es.c (es1800_resume): Pass in pid as argument.
+ * remote-hms.c (hms_resume): Pass in pid as argument.
+ * remote-mips.c (mips_resume): Pass in pid as argument.
+ * remote-mm.c (mm_resume): Pass in pid as argument.
+ * remote-monitor.c (monitor_resume): Pass in pid as argument.
+ * remote-nindy.c (nindy_resume): Pass in pid as argument.
+ * remote-sa.sparc.c (remote_resume): Pass in pid as argument.
+ * remote-sim.c (rem_resume): Pass in pid as argument.
+ * remote-sp64sim.c (simif_resume): Pass in pid as argument.
+ * remote-st.c (st2000_resume): Pass in pid as argument.
+ * remote-udi.c (udi_resume): Pass in pid as argument.
+ * remote-vx.c (vx_resume): Pass in pid as argument.
+ * remote-z8k.c (rem_resume): Pass in pid as argument.
+ * remote.c (remote_resume): Pass in pid as argument.
+ * solib.c (solid_create_inferior_hook): Pass inferior_pid to
+ target_resume().
+ * target.c (normal_pid_to_str): New routine to print out process
+ ID normally.
+ * target.h (struct target_ops): Add pid to prototype at
+ to_resume(). (target_resume): Add pid argument.
+ * (target_pid_to_str): Default definition for normal type pids.
+ * thread.h, thread.c: New modules for multi thread/process control.
+
+Sun Aug 1 13:02:42 1993 John Gilmore (gnu@cygnus.com)
+
+ * README: Say that bug-gdb is also the place to send requests
+ for help with GDB.
+
+Sun Aug 1 09:42:13 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (make-proto-gdb-1): Use -f opt on rm of Makefile.
+ * h8500-tdep.c: Add parens around a few macro args.
+
+Fri Jul 30 15:43:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Remove items about unix-to-unix/rapp debugging (now we
+ have gdbserver), moving xm files to subdirectory, ptype yylval,
+ and file-local symbols.
+
+ * gdbtypes.h: Improve comments about C++ methods.
+
+Fri Jul 30 14:16:32 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * c-exp.y: Add missing 5th arg for one call to lookup_symbol, cast
+ NULL in all other calls to correct pointer types.
+
+Fri Jul 30 15:43:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ From Jeffrey Law:
+ * tm-hppa.h (TARGET_WRITE_PC): Define.
+ * hppa-tdep.c (hppa_fix_call_dummy): If in a syscall,
+ then return the address of the dummy itself rather than
+ the address of $$dyncall.
+ (target_write_pc): New function to store a new PC.
+
+Fri Jul 30 12:51:27 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+ and Jim Kingdon (kingdon@cygnus.com)
+
+ * breakpoint.c (breakpoint_re_set_one): Always reparse breakpoint
+ conditions, they might contain symbol table references.
+
+Fri Jul 30 12:51:27 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mipsread.c (parse_symbol): Handle opaque struct definitions and
+ type naming for stTypedef symbols.
+
+Fri Jul 30 14:44:21 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * c-exp.y (yylex): Detect C++ nested types.
+
+Fri Jul 30 11:07:37 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * sp64-tdep.c (sparc64_frame_chain, sparc64_frame_saved_pc): Deleted.
+ (dump_ccreg, sparc_print_register_hook): New fns.
+ * remote-sim.h: New file.
+ * remote-sp64sim.h (sim_*): External fns. (simif_*): Internal fns.
+
+ * config/sparc/sp64.mt: New file.
+ * config/sparc/tm-sp64.h (FRAME_CHAIN, FRAME_SAVED_PC): Deleted.
+ (PRINT_REGISTER_HOOK): Call new fn sparc_print_register_hook.
+
+Fri Jul 30 10:15:01 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * Makefile.in (ALLCONFIG): Add config/i386/ptx.mh
+
+Fri Jul 30 08:58:01 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ From J. Law:
+ * infcmd.c (read_pc): Remove PA specific code.
+ * tm-hppa.h (TARGET_READ_PC): Define.
+ * hppa-tdep.c (target_read_pc): New function.
+
+ * symtab.c (gdb_mangle_name): Deal with it if type lacks a name.
+
+Fri Jul 30 07:36:53 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * NEWS: Add note that DEC alpha support is host only, not native.
+ * README: Emphasize that C++ support works best with GNU C++ and
+ stabs debugging format.
+ * delta68-nat.c: Add missing FSF copyright.
+
+Fri Jul 30 08:58:01 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * paread.c (pa_symtab_read): Put file-local symbols in minimal symbols.
+ * hppa-tdep.c (frame_chain_valid): Check that our function has the
+ same address as _start, not that it must be the same symbol.
+
+Fri Jul 30 00:18:40 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * Makefile.in (ALLDEPFILES): Add delta68-nat.c
+ * Makefile.in (delta68-nat.o): Add dependency.
+
+Thu Jul 29 12:09:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * value.h (COERCE_ENUM): Use COERCE_REF to coerce refs; value_ind
+ was adequate in gdb 3.5 but not now.
+
+ * valops.c (typecmp): An array in t2 matches a pointer in t1.
+
+ * valops.c (typecmp): When comparing type1& to type2, compare
+ type1 and type2 as leniently as if we were comparing type1 to
+ type2.
+
+ * cp-valprint.c (cplus_print_value): Don't dump core if the
+ baseclass doesn't have a name.
+ * values.c (vb_match): New function, which finds the virtual
+ base class pointer even if the types are nameless.
+ (baseclass_{addr,offset}): Use it.
+
+ * hppa-tdep.c: Make "maintenance print unwind" command from old
+ "unwind" command.
+
+ * remote-udi.c: Remove udi_timer, call to siginterrupt, and associated
+ obsolete junk which apparently had been copied from the
+ pre-serial.h remote.c, but which is no longer used.
+
+Thu Jul 29 12:36:20 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * Makefile.in (NONSRC): Need 29k-share/README, not
+ 29k-share/udi/README.
+
+Thu Jul 29 12:09:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * paread.c (pa_symfile_init): If error reading string table, don't
+ use errno in cases where it hasn't been set.
+
+ * ser-unix.c (gdb_setpgid): Pass our pid, not 0, to setpgid.
+
+ * remote-monitor.c (_initialize_monitor): Comment out use of
+ connect_command, since connect_command itself is commented out.
+
+ * remote-monitor.c (generic_open): Parse arguments the same way
+ as remote.c.
+
+ * hppa-tdep.c (pc_in_linker_stub): Fix unclosed comments.
+
+Wed Jul 28 13:19:34 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/mips/xm-mips.h: Define HAVE_TERMIOS.
+
+ * dbxread.c (record_minimal_symbol): Don't put gcc_compiled or
+ __gnu_compiled* symbols into the minimal symbols.
+
+Wed Jul 28 08:26:58 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * remote-mips.c (_initialize_remote_mips): Added "timeout" and
+ "retransmit-timeout" variables to set mips_receive_wait and
+ mips_retransmit_wait, respectively.
+
+Wed Jul 28 03:58:58 1993 (pes@regent.e-technik.tu-muenchen.de)
+
+ * symmisc.c (dump_msymbols): Handle new mst_file_* types.
+
+Tue Jul 27 12:07:38 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote-udi.c: Remove old comment about download not implemented.
+
+ * serial.h, ser-{unix,go32,tcp}.c: Add flush_input and send_break.
+ * nindy-share/*, remote-nindy.c: Extensive hacking to make it
+ conform to GDB conventions like using memcpy not bcopy, serial.h,
+ etc. This is to make it host on Solaris, AIX, etc.
+ * Makefile.in: Reflect removed nindy-share files.
+ * config/i960/nindy960.mt (TDEPFILES): Remove ttybreak.o.
+
+ * stack.c (print_frame_info): Revise comment about `pathological'
+ case (there was a wrong FIXME about text labels; also asm() can
+ trigger this as well as versions of ar which truncate .o names).
+
+ * buildsym.c (start_subfile): If a .c file includes a .C file, set
+ the language of both of them to C++.
+
+ * config/sparc/xm-sun4os4.h: Define MEM_FNS_DECLARED and include
+ <memory.h>.
+ Include <malloc.h> rather than declaring malloc functions ourself.
+
+ * ser-unix.c (set_tty_state): Don't ignore errors setting process
+ group.
+ * inflow.c (terminal_inferior): If attach_flag set, ignore errors
+ from set_tty_state.
+
+ * fork-child.c (fork_inferior): Only quote exec file if needed.
+
+ * mipsread.c (parse_symbol): Remove 21 Jul 93 change with
+ stTypedef inside an stBlock.
+
+Tue Jul 27 12:36:49 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * breakpoint.c (breakpoint_1): Walk the breakpoint chain to decide if
+ we have breakpoints or watchpoints as we might have to ignore internal
+ breakpoints.
+
+ Fix gdb core dumps after `file newfile' commands.
+ * symtab.h, symfile.c (clear_symtab_users): New routine which
+ unconditionally clears symtab users. clear_symtab_users_once
+ commented out as it was a noop anyway.
+ * objfiles.c (free_objfile): Don't call clear_symtab_users_once.
+ * objfiles.c (free_all_objfiles), symfile.c (new_symfile_objfile),
+ xcoffexec.c (exec_close): Call clear_symtab_users if necessary.
+ * symfile.c (syms_from_objfile): Install cleanups for errors during
+ symbol reading.
+ * coffread.c, dbxread.c, mipsread.c, xcoffread.c (*_symfile_read):
+ Lint cleanup code, call do_cleanups explicitly.
+ * symfile.c (symbol_file_add): Call new_symfile_objfile and
+ reinit_frame_cache _after_ the new symbols are read in.
+
+Tue Jul 27 01:57:01 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mipsread.c (parse_type): Do not set tag name for compiler
+ generated fake tag names.
+
+Mon Jul 26 17:31:49 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * config/m88k/m88k.mt (TDEPFILES): add exec.o.
+
+Mon Jul 26 13:17:36 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hppa-tdep.c: Remove all uses of use_unwind and `set use_unwind'
+ command. Now we use unwind info by default if we can find it.
+
+ * config/sparc: Move VARIABLES_INSIDE_BLOCK and SUN_FIXED_LBRAC_BUG
+ to tm-sparc.h so they are shared between Solaris and SunOS4.
+ * dbxread.c (process_one_symbol): Deal with SunOS4 acc N_STSYM and
+ N_GSYM functions.
+
+ * config/pa/tm-hppa.h (REGISTER_NAMES): Use "fr" rather than "fp"
+ for floating point registers.
+
+ * mipsread.c (parse_symbol): Put stStaticProc symbols in minimal
+ symbols as mst_file_text.
+
+ * hppa-tdep.c (pc_in_linker_stub): Return 0 if can't read memory.
+
+ * stabsread.c (rs6000_builtin_type): Make logical types be
+ TYPE_CODE_BOOL.
+
+Sun Jul 25 23:41:48 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.{c,h} (struct breakpoint): Replace symtab field with
+ source_file field.
+
+Fri Jul 23 09:57:25 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * remote.c: Don't error() on errors xferring memory.
+ * target.h: Clean up comments about *xfer_memory.
+
+ * exec.c, corelow.c (target_ops struct): Don't allow
+ {insert,remove}_breakpoints to be defaulted to
+ memory_{insert_remove}_breakpoint.
+
+ * demangle.c: Make it so `help set dem' tells you how to get the
+ list of demangling styles.
+
+Thu Jul 22 15:41:09 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * Makefile.in: Use REMOTE_O macro not remote.o.
+ * config/i960/{nindy960,vxworks960}: Don't use remote.o.
+
+Thu Jul 22 12:43:25 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coredep.c: If NEED_SYS_CORE_H defined, include <sys/core.h>
+ (can't include it in nm-*.h file because it causes conflicts with
+ a.out symbol definitions).
+ * hp300ux-nat.c (fetch_core_registers): Commented out; obsolete.
+ * config/m68k/hp300hpux.mh (NATDEPFILES): Added coredep.o and
+ corelow.o.
+ * config/m68k/nm-hp300hpux.h (NEED_SYS_CORE_H): Defined.
+ (REGISTER_U_ADDR): Defined.
+ * config/m68k/xm-hp300hpux.h (HAVE_TERMIOS): Define instead of
+ HAVE_TERMIO.
+ * config/pa/xm-hppah.h: Likewise.
+
+Wed Jul 21 11:37:30 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * mipsread.c (parse_symbol): when stTypedef and friends occur within
+ an stBlock, skip over the fields of the inner one.
+
+ * mips-tdep.c (init_extra_frame_info): If in lenient prologue, call
+ heuristic_proc_desc rather than just assuming registers not saved.
+
+ * Makefile.in (regex.o): Add dependency.
+
+ * hppa{b,h}-nat.c: Warning, not error, if can't access registers.
+
+ * config/pa/hppa{b,h}.h: Define ATTACH_DETACH.
+
+Wed Jul 21 03:07:30 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/mips/xm-makeva.h: New file implements va_list alignment
+ restrictions for mips hosts.
+ * config/mips/{xm-irix3.h, xm-mips.h, xm-news-mips.h, xm-riscos.h}:
+ Use it.
+
+Wed Jul 21 00:11:05 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mips-tdep.c (init_extra_frame_info): Do not check for
+ mips_in_lenient_prologue if it is a dummy frame.
+ * mipsread.c (fixup_sigtramp): Initialize pdr.adr, it is used by
+ mips_in_lenient_prologue.
+
+Tue Jul 20 14:14:59 1993 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c (read_hp_array_type): Handle "char foo[]".
+
+Tue Jul 20 12:53:47 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * mips-tdep.c (heuristic_proc_start): First time we print the
+ warning, elaborate.
+ (_initialize_mips_tdep): Improve docstring for `set heur'.
+
+ * config/rs6000/tm-rs6000.h: Remove call to insert_step_breakpoint.
+
+ * symtab.c (find_line_symtab): New function, to deal with multiple
+ symtabs with the same name.
+ (find_line_pc{,_range}): Use it.
+ (find_pc_symtab): Add comment about overlapping symtabs.
+
+Mon Jul 19 21:29:14 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * Makefile.in (SFILES): Add nlmread.c.
+ * Makefile.in (OBS): Add nlmread.o.
+ * Makefile.in (nlmread.o): Add new target.
+ * configure.in (i[34]86-*-netware): New configuration.
+ * nlmread.c, config/i386/{i386nw.mt, tm-i386nw.h}: New files
+ for NLM/NetWare support.
+
+Mon Jul 19 11:48:57 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * symtab.h (enum minimal_symbol_type): Add mst_file_*.
+ * partial-stab.h [DBXREAD_ONLY]: Record statics in miminal symbols.
+ * dbxread.c (record_minimal_symbol): Deal with statics.
+ * minsyms.c (lookup_minimal_symbol): Prefer externals to statics.
+
+ * config/i386/xm-i386sco.h: Define HAVE_TERMIOS.
+
+ * printcmd.c, config/pa/xm-pa.h, config/alpha/xm-alpha.h: Make it so
+ arg_bytes field of makeva_list is always aligned.
+ * config/pa/xm-pa.h: Make arglist_address a char *.
+
+ * ser-unix.c: Don't try to use job control with termio.
+
+Sun Jul 18 23:11:28 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+ and Jim Kingdon (kingdon@cygnus.com)
+
+ Make breakpoint_re_set_one work with overloaded member functions,
+ `b 123' and `b foo' if foo is a static function.
+ * symtab.c (decode_line_1, decode_line_2): New argument `canonical'
+ to return canonical line specs if requested by the caller.
+ * breakpoint.c, source.c, symtab.c, symtab.h: Change prototypes and
+ callers accordingly.
+ * symtab.c (build_canonical_line_spec): New helper function which
+ constructs the canonical line spec.
+ * breakpoint.c (break_command_1): Use canonical line spec instead
+ of command string as addr_string if necessary.
+ * source.c (line_info): Fix storage leak.
+
+Sun Jul 18 15:22:45 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * infptrace.c: Split out define of PT_KILL; Sequent defines PT_KILL
+ but not the others.
+ * symm-tdep.c: Remove exec_file_command.
+ [_SEQUENT_] (ptx_coff_regno_to_gdb, register_addr): New functions.
+ A few miscellaneous cleanups.
+ * symm-nat.c: Renamed from symm-xdep.c.
+ * All symmetry dependent files: Many changes.
+
+ * mips-tdep.c (mips_skip_prologue): New argument lenient.
+ Use read_memory_nobpt.
+ (is_delayed, mips_in_lenient_prologue): New functions.
+ (init_extra_frame_info): If in the prologue, don't use saved registers.
+ * config/mips/tm-mips.h: Declare mips_skip_prologue.
+
+ * partial-stab.h (N_SO): Add the text offset to valu before, not after,
+ passing it to END_PSYMTAB.
+
+Fri Jul 16 18:48:52 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * symtab.c (find_pc_symtab): Call warning, not printf directly.
+
+ * solib.c (solib_add): Use x{re,m}alloc, not {re,m}alloc.
+
+Fri Jul 16 09:56:42 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mipsread.c: No longer need to undefine ZMAGIC.
+
+Thu Jul 15 18:03:37 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * m88k-pinsn.c: Moved code into opcodes/m88k-dis.c.
+ (print_insn): Now just calls print_insn_m88k.
+
+Thu Jul 15 14:54:05 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * h8300-tdep.c (examine_prologue): Make prototype match definition.
+
+Thu Jul 15 08:34:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * NEWS: Mention that remote.c now has a `load' operation.
+
+ * hppa-tdep.c (pc_in_linker_stub): New function.
+ (find_proc_framesize): Return 0 for linker stubs.
+ (rp_saved): Tell the caller where rp is saved.
+ (frame_chain_valid): Return 1 for linker stubs.
+ (frame_saved_pc): Use return value from rp_saved.
+
+ * stack.c (print_frame_info): When checking PC_IN_CALL_DUMMY,
+ pass the sp relative to the frame in question, not the sp in the
+ innermost frame.
+
+Wed Jul 14 17:37:03 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * mipsread.c (parse_procedure): Take as argument the symtab to look
+ the name up in. Look it up with mylookup_symbol, not lookup_symbol.
+ (psymtab_to_symtab_1): For stabs, pass the symtab to parse_procedure.
+
+ * mipsread.c (mylookup_symbol): Use strcmp, not STREQ, as we have
+ already checked the first characters.
+
+ Changes from Jeffrey Law:
+ * printcmd.c (makeva_list): Use MAKEVA_EXTRA_INFO to define
+ machine dependent fields in the makeva_list structure.
+ (makeva_size): Allocate extra space to handle gaps made by
+ alignment restrictions.
+ * config/pa/xm-pa.h (MAKEVA_EXTRA_INFO): Define.
+ (MAKEVA_START): Initialize arglist_address field.
+ (MAKEVA_ARG): Always store arguments on natural alignment
+ boundaries. Set arglist_address to the address right after
+ the args.
+ (MAKEVA_END): Simply return the value stored in arglist_address.
+
+Wed Jul 14 13:51:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * ch-valprint.c (chill_val_print, case TYPE_CODE_STRING): Print
+ address, not addr.
+
+ * hppah-nat.c (store_inferior_registers): Don't print i in cases
+ where we aren't using it.
+
+ * a29k-tdep.c (get_saved_register): Fix typo.
+
+Wed Jul 14 09:45:52 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * configure.in: Recognize h8300h (variant of h8300).
+
+Wed Jul 14 09:45:52 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * configure.in: Recognize sparc64-*-*.
+
+Tue Jul 13 14:03:48 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabsread.c (define_symbol): Make the caddr_t hack apply to `function
+ returning foo' as well as `pointer to foo'.
+
+ * remote.c [REMOTE_BREAKPOINT]: Use for breakpoint insn if defined.
+ * config/m68k/tm-m68k.h: Define it.
+ * mem-break.c, breakpoint.c: Improve comments.
+
+Tue Jul 13 13:35:31 1993 Frederic Pierresteguy (F.Pierresteguy@frcl.bull.fr)
+
+ * config/m68k/tm-dpx2.h: Replace "tm-68k.h" with "m68k/tm-m68k.h".
+ * config/m68k/xm-dpx2.h: Define HAVE_TERMIOS not HAVE_TERMIO.
+
+Tue Jul 13 11:50:38 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * gdbcore.h (read_memory_integer, read_memory_unsigned_integer):
+ Make prototype match definition.
+
+Tue Jul 13 11:15:15 1993 Fred Fish (fnf@cygnus.com)
+
+ * elfread.c: Remove notice about file still being under
+ construction.
+ * Makefile.in (ultra3-xdep.o, umax-xdep.o): Add missing ')'.
+
+Mon Jul 12 17:46:35 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * a29k-tdep.c (read_register_stack): Make val static.
+
+Mon Jul 12 14:10:48 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/h8300/tm-h8300.h (REGISTER_CONVERTIBLE): Change value to 0.
+ (REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW): Move def'n to
+ usual spot.
+
+Mon Jul 12 11:29:44 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * c-valprint.c (c_val_print): Fix thinko with unspecified length
+ arrays.
+
+ * hppa-tdep.c (find_proc_framesize): If there is a frame pointer,
+ use it.
+
+Sun Jul 11 19:35:05 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * symtab.c (decode_line_1): Use end of block to figure out whether
+ val.end is in the same function, not minimal symbols.
+
+ * source.c (line_info): Add a few more wrap_here's.
+
+ * i386-tdep.c (i386_follow_jump): Do byteswapping where needed and
+ don't make assumptions about sizes of host data types.
+
+ * blockframe.c, symtab.h (find_pc_partial_function): New arg endaddr.
+ * infrun.c, breakpoint.c, printcmd.c: Change callers.
+ * printcmd.c (containing_function_bounds): Remove.
+ * printcmd.c (disassemble_command): Use find_pc_partial_function,
+ not containing_function_bounds.
+ * infcmd.c (step_1): Use find_pc_partial_function rather than
+ trying to roll our own. Move check for a pc between SIGTRAMP_START and
+ SIGTRAMP_END in find_pc_partial_function, not step_1.
+
+ * sparc-tdep.c (sparc_frame_chain, frame_saved_pc):
+ Keep unswapped value in array of char, not REGISTER_TYPE.
+ Use REGISTER_RAW_SIZE not sizeof (REGISTER_TYPE).
+ (sparc_extract_struct_value_address): Use TARGET_PTR_BIT not
+ sizeof (CORE_ADDR).
+
+Thu Jul 1 15:50:05 1993 Frederic Pierresteguy (F.Pierresteguy@frcl.bull.fr)
+
+ * configure.in (m68*-bull-sysv*): added support for Bull dpx2.
+ * config/m68k/{t,x,n}m-dpx2.h, dpx2-nat.c: New files.
+ * config/m68k/dpx2.m{h,t}: New files.
+
+Thu Jul 1 15:46:10 1993 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c: Run through gnu-indent.
+
+Sun Jul 11 12:32:08 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/sparc/tm-sparc.h (PRINT_REGISTER_HOOK): Fix typo, add
+ more parens around macro arg.
+
+Sat Jul 10 09:54:17 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infrun.c: Remove step_resume_{duplicate,shadow}. Replace
+ step_resume_break_address with step_resume_breakpoint (now local
+ to wait_for_inferior).
+ ({insert,remove}_step_breakpoint): Remove.
+ (wait_for_inferior): Set step resume break with
+ set_momentary_breakpoint. Test hitting it with bpstat_stop_status
+ and bpstat_what (stop_step_resume_break removed).
+ * breakpoint.{h,c}, infrun.c: Return value from bpstat_what now struct
+ which includes previous return value as main_action, and a step_resume
+ bit.
+ * breakpoint.c (delete_breakpoint): If breakpoint was inserted, and
+ there is another breakpoint there, insert it.
+ * infrun.c (wait_for_inferior): Rearrange the spaghetti a bit. Use
+ a few more gotos.
+ Various: Clean up and add comments.
+
+ * infrun.c [TDESC]: Remove remaining tdesc code (see ChangeLog
+ for Wed Nov 13 16:45:13 1991).
+
+Fri Jul 9 12:36:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * values.c, value.h (modify_field), callers: Make fieldval a LONGEST.
+
+ * h8300-tdep.c (NEXT_PROLOGUE_INSN): Make pword1 an INSN_WORD *
+ not short *.
+
+ * findvar.c, defs.h
+ ({extract,store}_{signed_integer,unsigned_integer,address}):
+ New routines to replace SWAP_TARGET_AND_HOST.
+ All over: All uses of SWAP_TARGET_AND_HOST on integers replaced.
+
+ * config/sparc/tm-sparc.h: Add comment suggesting that removing
+ ins and locals from the registers array might clean things up.
+
+ * utils.c: Clean up comments about wrap buffer and wrap_here.
+ * printcmd.c (printf_command): Call wrap_here before vprintf.
+
+ * mipsread.c (cross_ref): Set the name to unknown for "struct *" case.
+ Patch from ptf@delcam.co.uk (Paul Flinders).
+
+ * a29k-tdep.c, findvar.c (get_saved_register): Fix byteswapping sins.
+
+Fri Jul 9 09:47:02 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * defs.h, remote-eb.c (TM_FILE_OVERRIDE): Remove it.
+ * mips-tdep.c (init_extra_frame_info): Set proper fci->frame if pc
+ is at the start of the dummy code.
+
+Thu Jul 8 14:48:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * sparc-tdep.c (sparc_push_dummy_frame): Skip all the do_save_insn
+ stuff, just write the sp and fp.
+ (sparc_pop_frame): Skip the do_restore_insn; we already restore
+ the sp with the other out registers.
+
+ * hppa-tdep.c (hppa_push_arguments): Allocate enough space for
+ arguments.
+
+ * hppa-tdep.c: Change _initialize_hppab_tdep to _initialize_hppa_tdep.
+
+Thu Jul 8 14:47:00 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * sparc-tdep.c (sparc_frame_chain): Handle sizeof (CORE_ADDR)
+ != sizeof (REGISTER_TYPE).
+ (frame_saved_pc): Ditto.
+
+Thu Jul 8 08:22:05 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/h8300/tm-h8300.h: (REGISTER_TYPES): Adjust for h8/300h.
+ (REGISTER_RAW_SIZE): Ditto.
+ (REGISTER_VIRTUAL_TYPE): Use builtin_type_unsigned_long for regs
+ on the h8/300h (ints may still be 16 bits).
+ (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE,
+ EXTRACT_STRUCT_VALUE_ADDRESS): Add FIXME's for h8/300h. Some
+ thought needed here.
+
+ * h8300-tdep.c (print_insn): Call print_insn_h8300h if h8/300h.
+ (examine_prologue): reg_save_depth is 4 if h8/300h.
+
+ * findvar.c (read_register): Provide some support for 64 bit regs.
+ (write_register): Ditto.
+
+Wed Jul 7 14:30:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/mips/nm-riscos.h: machine/machparam.h is always the right
+ place to look for BSD43_NBPG, not machine/vmparam.h
+
+ * infcmd.c (run_stack_dummy): New argument name.
+ Change error message in (another) attempt to make it comprehensible.
+ * valops.c (call_function_by_hand): Pass name to run_stack_dummy.
+ * symtab.h: Declare demangle and asm_demangle since macros use them.
+
+ * eval.c (evaluate_subexp): Add comment about calling a member
+ function of a variable in a register.
+
+ * expression.h: Clean up comment about string in STRUCT_STRUCT etc.
+
+ * config/{rs6000/tm-rs6000.h,sparc/tm-sparc.h,pyr/tm-pyr.h},
+ inferior.h (PC_IN_CALL_DUMMY) [ON_STACK]: Add comments about stack
+ frame tops and bottoms.
+
+ * frame.h, blockframe.c, stack.c, a29k-tdep.c,
+ config/gould/tmp-{pn,np1}.h,
+ config/{sparc/tm-sparc.h,pyr/tm-pyr.h,vax/tm-vax.h}: Remove field
+ next_frame from struct frame_info. It has no purpose beyond
+ ->next->frame and is an artifact from GDB 2.8.
+
+Tue Jul 6 11:51:18 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in: Remove gdb before creating a new one.
+ Update init.c atomically.
+
+ * Makefile.in (ALLPARAM): Add config/{alpha/xm-alpha.h,pa/xm-pa.h}.
+ (ALLCONFIG): Add config/alpha/alpha-osf1.mh.
+
+ * infcmd.c (_initialize_infcmd): In docstring for "continue",
+ describe argument as setting ignore count.
+
+Sun Jul 4 15:04:47 1993 Doug Evans (dje@cygnus.com)
+
+ * h8300-tdep.c (examine_prologue): Fix call to
+ read_memory_unsigned_integer.
+
+Fri Jul 2 18:22:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/mips/{x,n}m-irix{3,4}.h: Make some definitions here
+ rather than including xm-bigmips.h.
+
+ * eval.c (evaluate_subexp): Improve error messages for OP_TYPE and
+ default cases.
+
+ * Makefile.in (distclean): Remove y.tab.h.
+
+Fri Jul 2 14:55:48 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * exec.c (exec_file_command): Remove Mar 28 hack as BFD handles
+ file updates properly now.
+ * mipsread.c (mips_coff_new_init): Force reevaluation of sigtramp
+ addresses if switching to a new symbol file.
+ * dbxread.c (process_one_symbol): Avoid dereferencing NULL
+ symbols that might be returned from define_symbol.
+
+Fri Jul 2 13:33:12 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ New target macros for getting at the pc, sp and fp.
+ * infcmd.c (read_pc, write_pc): Modify to use new macros.
+ (read_sp, write_sp, read_fp, write_fp): New functions.
+ * blockframe.c (reinit_frame_cache, get_prev_frame_info):
+ Use new functions.
+ * breakpoint.c (bpstat_alloc): ditto.
+ * infrun.c (wait_for_inferior): ditto.
+ * stack.c (print_frame_info): ditto.
+ * valops (call_function_by_hand): ditto.
+ * corelow.c (core_open): ditto.
+ * h8500-tdep.c: (target_read_sp, target_write_sp, target_read_pc,
+ target_write_pc, target_read_fp, target_write_fp): New functions.
+ * inferior.h (read_sp, write_sp, read_fp, write_fp): Prototypes.
+
+ * config/alpha/xm-alpha.h: Add MAKEVA_END.
+ * config/h8500/tm-h8500.h: Define new macros.
+
+Fri Jul 2 13:51:04 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in (mipos-*-riscos*): New host and target; use riscos.
+ * config/mips/nm-riscos.h: If BSD43_NBPG is not defined by
+ vmparam.h, include machparam.h.
+ (KERNEL_U_ADDR): Define to be BSD43_UADDR.
+
+Fri Jul 2 13:39:48 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * c-exp.y (yylex): Give error if unmatched single quote.
+
+ * configure.in, config/m68k/*delta68*, delta68-nat.c: New port.
+
+ * Remove unused STACK_END_ADDR in the following files (in other
+ files it is used for something): tm-mips.h, tm-sun2.h, tm-news.h,
+ tm-a29k, tm-i386v.h, tm-hppa.h, tm-nindy960.h, tm-amix.h,
+ tm-hp300hpux.h, tm-isi.h.
+
+Thu Jul 1 09:51:27 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * config/mips/nm-riscos.h: Define NBPG and UPAGES.
+ config/mips/xm-riscos.h: Include <sys/types.h>.
+
+ * ser-unix.c (hardwire_noflush_set_tty_state): Use an assignment,
+ not an initializer, to copy the structure.
+
+ * gdbtypes.h (struct type): Add field tag_name.
+ * gdbtypes.c (type_name_no_tag), c-typeprint.c (c_type_print_base):
+ Use it.
+ * {coff,dwarf,mips,stabs}read.c: Set it.
+
+ * xm-sysv4.h: Undefine HAVE_TERMIO.
+
+ * config/mips/nm-riscos.h: Remove unmatched #endif.
+ Define FETCH_INFERIOR_REGISTERS.
+ * config/mips/riscos.mh: Don't include coredep.o; mips-nat.o is enough.
+ Fix misspelling of NAT_FILE.
+ * mips-nat.c (fetch_core_registers): If KERNEL_U_ADDR is not defined,
+ we can still process "modern" core files.
+
+ * ser-unix.c (hardwire_print_tty_state) [HAVE_TERMIOS]: Don't
+ print c_line.
+ (_initialize_ser_hardwire): Just check whether _POSIX_JOB_CONTROL
+ is defined; don't care what it is defined to.
+
+Wed Jun 30 20:06:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/vax/xm-vaxult2.h: Define FD_SET and FD_ZERO.
+
+Tue Jun 29 11:02:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * inftarg.c: Remove unused include of terminal.h.
+ * signals.h: Don't undefine signals anymore.
+ * main.c: Use job_control from serial.h.
+ * fork-child.c (fork_inferior): Use gdb_setpgid.
+ * serial.h, ser-unix.c, ser-go32.c: Provide gdb_setpgid.
+ * utils.c (quit): Use current_target->to_terminal_ours to figure
+ out whether we care about lack of job control, rather than __GO32__.
+ * utils.c: Include serial.h not terminal.h
+ (quit): Use job_control not TIOCGPGRP.
+ * terminal.h: Don't undefine TIOCGPGRP.
+ * serial.h, ser-unix.c, ser-go32.c, ser-tcp.c: Add SERIAL_FLUSH_OUTPUT.
+ * utils.c (quit): Use it.
+ * serial.h: Add SERIAL_UN_FDOPEN.
+ * utils.c (quit): Use it.
+ * ser-unix.c: Add process group to ttystate.
+ [HAVE_SGTTY]: Add tchars, ltchars, and lmode to ttystate.
+ * inflow.c: Include serial.h not terminal.h.
+ Use serial.h stuff to replace most of the maze of #ifdef's.
+ * inflow.c, main.c, inferior.h: make gdb_has_a_terminal a function.
+ * serial.h: Document SERIAL_SET_TTY_STATE as being immediate.
+ * ser-unix.c: Use TIOCSETN not TIOCSETP so it is true.
+ * serial.h, ser-unix.c, ser-go32.c, ser-tcp.c:
+ Add SERIAL_PRINT_TTY_STATE, SERIAL_NOFLUSH_SET_TTY_STATE, and
+ SERIAL_SET_PROCESS_GROUP.
+ * inflow.c: Use them.
+ * config/xm-svr4.h, config/rs6000/xm-rs6000.h, config/sparc/sun4os4.h:
+ Define HAVE_TERMIOS.
+ * Various: Remove all use of TIOC*_BROKEN.
+
+Wed Jun 30 12:20:51 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/m68k/tm-sun3.h (BELIEVE_PCC_PROMOTION_TYPE): Define.
+
+Tue Jun 29 13:44:41 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * target.h (target_detach): Turn macro into function.
+ * target.c (target_detach): Define it, do deferred register stores
+ before calling the real target function.
+
+Tue Jun 29 13:15:42 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+ and Jim Kingdon (kingdon@cygnus.com)
+
+ * symtab.h (BLOCK_SHOULD_SORT): Do not sort blocks corresponding to
+ a function to avoid printing of function arguments in wrong order
+ due to sorting.
+ * symfile.c (compare_symbols): Remove code for sorting arguments
+ as blocks containing arguments are no longer sorted.
+ * symtab.c (lookup_block_symbol): Update comment accordingly.
+
+Tue Jun 29 11:02:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/pa/tm-hppa.h: Remove unused ARGS_GROW_DOC.
+ (REG_STRUCT_HAS_ADDR): Add comment.
+
+ * infrun.c (wait_for_inferior): Use find_pc_line not find_pc_symtab
+ to check whether there is line number information.
+
+Tue Jun 29 08:29:17 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * remote-udi.c: Fix docstring so that it compiles.
+
+ * remote-mips.c, remote-nindy.c: move bfd.h before symfile.h
+ (for file_ptr).
+
+Tue Jun 29 09:11:27 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dbxread.c (process_one_symbol): If we find a LOC_BLOCK where we
+ don't expect it, change it to LOC_STATIC so at least we don't coredump.
+
+ * c-typeprint.c (c_type_print_base): Don't error() on invalid type.
+
+ * symtab.h: Add comments about line numbers.
+ * source.c (identify_source_line): Fix off by one bug with line.
+
+Mon Jun 28 19:00:21 1993 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c: Do not include libhppax. Instead include libhppa.h
+ and hpux-symtab.h. Misc indention fixes.
+ (find_unwind_entry): Add PARAM prototype.
+ (read_hpux_symtab): More fixes for names and sizes of structs,
+ unions, enums, typedefs, and tagdefs.
+ (read_hp_enum_type, read_hp_struct_type): Likewise.
+ (read_hp_set_type, read_hp_subrange_type): Likewise.
+ (hp_type_lookup, process_one_debug_symbol): Likewise.
+ (process_one_debug_symbol): Search forward from the K_FUNCTION for
+ the first K_BEGIN when setting the line number associated with a
+ function. Avoid unnecessary calls to savestring.
+ (hp_alloc_type): Initialize TYPE_CPLUS_SPECIFIC here. Remove
+ most cases where we set it elsewhere.
+ (hppa_sym_fns): Use "hppa" instead of hppax since hpread.c and
+ paread.c use the same BFD backend now. All references changed.
+ (hpux_symfile_init): Allocate space to hold the debugging section
+ contents on the symbol obstack.
+
+Mon Jun 28 10:09:08 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * printcmd.c (makeva*): New interface, for making a va_list.
+ (printf_command): Use it.
+ * config/m88k/xm-delta88.h: Remove VPRINTF define, not needed.
+ * config/pa/xm-pa.h: New file.
+ * config/pa/xm-hppa{b,h}.h: Include it.
+
+ * xcoffread.c: Remove obsolete NO_TYPEDEFS comment.
+
+Sun Jun 27 08:54:55 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * valprint.c (val_print_type_code_int): Fix off by one error with
+ eliminating leading zeroes for large little endian integers.
+
+Sun Jun 27 08:58:56 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/mips/riscos.mh (CC): Use -systype sysv.
+
+ * ser-unix.c: Move #include of <sys/time.h> to HAVE_SGTTY section.
+
+ * Makefile.in (ALLPARAM): Add config/mips/{x,n}-{news-mips,riscos}.h.
+
+Fri Jun 25 11:22:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/m68k/tm-m68k.h: Remove obsolete comment about duplicating
+ CALL_DUMMY between different 68k machines.
+
+Fri Jun 25 17:02:45 1993 Stu Grossman (grossman at cygnus.com)
+
+ * gdbserver/Makefile.in: Add dependancies on server.h.
+ * gdbserver/remote-gutils.c: Remove lots of unused functions and
+ variables.
+ * gdbserver/remote-inflow.c: Remove lots of unused variables and
+ #includes. Also, use PTRACE_* symbols instead of constants.
+ (mywait): Surround calls to wait() with enable/disable_async_io()
+ so that we can be interrupted from GDB while waiting for the
+ child. Also, handle child exit more gracefully.
+ * gdbserver/remote-server.c: Remove lots of unused variables.
+ Move all extern defs into server.h. Redo main loop so that
+ failure from getpkt() causes communications to be re-established.
+ Fix 'k' command so that it restarts the child.
+ * gdbserver/remote-utils.c: Remove lots of unloved vars and
+ subrs. Move many extern decls into server.h. (remote_open): For
+ tcp, seperate usage of proto fd from connected fd. Close proto
+ fd after getting connection. (putpkt/getpkt): Pay attention to
+ errors when reading/writing. Report these to the caller. New
+ routines input_interrupt/enable_async_io/disable_async_io to make
+ it possible to get an I/O interrupt when data arrives from the
+ comm link.
+ * serial.h: New file to contain common defs for all remote files.
+
+Fri Jun 25 17:02:45 1993 Stu Grossman (grossman at cygnus.com)
+
+ * remote.c: Add arg names to prototypes, in a modest effort at
+ clarification. Also add prototypes for some new functions.
+ * (remote_wait): Better error reporting for 'T' responses.
+ * ser-go32.c (strncasecmp): Make str1 & str2 be const.
+ * (dos_async_init): Make usage message reflect requested port #.
+ * ser-tcp.c (tcp_open): Terminate hostname properly to prevent
+ random hostname lookup failures. Add nicer message for unknown
+ host error. (wait_for): Wake up in case of exceptions. Also,
+ restart select() if we got EINTR.
+ * ser-unix.c (wait_for): Restart select() if we got EINTR.
+ * serial.c: (serial_close): Clean up code.
+
+Fri Jun 25 11:22:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/m68k/tm-m68k.h: Remove obsolete comment about duplicating
+ CALL_DUMMY between different 68k machines.
+
+Fri Jun 25 11:22:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (*.tab.c): Use ./c-exp.tab.c not just c-exp.tab.c.
+ Make comment explaining this comprehensible.
+ (TAGFILES): Include ALLDEPFILES.
+ (ALLDEPFILES): udi2soc.c and udr.c are in 29k-share/udi, not
+ 29k-share/udi/udi.
+ (update-alldeps): Remove; obsolete.
+
+ * remote.c: Move comments regarding packets to top of file with the
+ rest of the protocol comments.
+ Fix incorrect description of 'T' response.
+
+ * README (Reporting Bugs): Refer people to the GDB manual.
+
+ * c-valprint.c (c_val_print): Handle TYPE_CODE_BOOLEAN.
+ * stabsread.c: Type -16 is 4 bytes.
+
+ * remote-udi.c: Improve docstring.
+
+Fri Jun 25 11:16:31 1993 Fred Fish (fnf@cygnus.com)
+
+ * elfread.c (elf_symfile_read): Call bfd_elf_find_section, not
+ bfd_elf32_find_section, to track bfd changes.
+
+Fri Jun 25 11:22:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/mips/riscos.mh (REGEX{,1}, MUNCH_DEFINE, MH_CFLAGS): Define.
+ * config/mips/xm-riscos.h: Define USG.
+
+Thu Jun 24 14:52:45 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * main.c (filename_completer): Don't complete to files ending in ~.
+
+ * NEWS: Mention filename completion and "info line" enhancements.
+
+ * main.c (symbol_completion_function): On "info t foo", return NULL,
+ don't error().
+
+ * main.c (symbol_completion_function): Don't use readline word
+ breaking. Use new calling convention for c->completer and
+ complete_on_cmdlist.
+ * command.h (struct command): Change arguments; now the text passed
+ to completer does not have any word breaking done. New arg word.
+ * symtab.{c,h} (make_symbol_completion_list): Do word breaking. Take
+ word argument.
+ * {main.c,gdbcmd.h} ({filename,noop}_completer): Take word argument.
+ * command.{c,h} (complete_on_cmdlist): Take word argument.
+
+ * command.c (lookup_cmd_1): Doc fix.
+
+Thu Jun 24 13:26:04 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * Makefile.in (OP_INCLUDE): define.
+ (OPCODE_CFLAGS): use OP_INCLUDE.
+
+ * config/i386/ncr3000.mh, config/i386/i386v4.mh,
+ config/i386/i386sol2.mh, config/m68k/hp300hpux.mh,
+ config/m68k/amix.mh, config/mips/irix[34].mh,
+ config/m88k/delta88.mh, config/sparc/sun4sol2.mh (ALLOCA,
+ ALLOCA1): macros removed.
+
+ * config/mips/decstation.mh, config/rs6000/rs6000.mh
+ (MMALLOC_LIB): renamed to MMALLOC.
+
+Wed Jun 23 00:25:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * partial-stab.h: Consolidate case statements for N_LSYM and N_FUN.
+ * dbxread.c: Change comment regarding acc.
+
+Wed Jun 23 16:33:36 1993 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c: Document a few functions, misc cleanups. Update
+ copyright to reflect the first "release" of this file.
+ (struct hpux_symfile_info): Delete unneeded fields. Keep pointers
+ to the contents of the debug sections rather than offsets within
+ the file itself. Corresponding changes to the accessor macros.
+ (sl_symbol_size, slt_symbuf): Delete unneeded global variables.
+ (slt_symbuf_start, slt_symbuf_end, lntt_symbuf): Likewise.
+ (lntt_symbuf_start, lntt_symbuf_end, gntt_symbuf): Likewise.
+ (gntt_symbuf_start, gntt_symbuf_end): Likewise.
+ (fill_slt_symbuf, fill_lntt_symbuf): Delete unneeded functions.
+ (fill_gntt_symbuf): Likewise.
+ (get_lntt, get_gntt, get_slt): Simplify.
+ (hpux_symfile_init): Read and store the contents of the debugging
+ sections. Do error checking on memory allocation and BFD calls.
+ (read_hpux_symtab): Delete KERNELDEBUG crud. Ignore debug symbols
+ which are not needed for building partial symbol tables. Handle
+ K_CONST, K_TYPEDEF, and K_TAGDEF just like K_SVAR and K_DVAR.
+ (read_ofile_symtab): Delete useless processing_gcc_compilation stuff.
+ (read_hp_struct_type): Initialize TYPE_CPLUS_SPECIFIC.
+ (read_hp_set_type, read_hp_array_type): Likewise.
+ (read_hp_subrange_type, hp_type_lookup): Likewise.
+
+Wed Jun 23 15:04:54 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ Makefile overhaul dropping autodepend features.
+ * Makefile.in: many comment changes. forced consistent use of $()
+ for makefile variables references. dropped leading ./ in file
+ references. Drop $(srcdir)/ prefix on all dependencies.
+ Inserted contents of alldeps.mak and depend.
+ (INCLUDE_CFLAGS): defined as new macro for getting libiberty's
+ include directory into the compilation line.
+ (GDB_CFLAGS): new macro to take up the semantic previously held
+ by INCLUDE_CFLAGS.
+ (LIBIBERTY): dropped ancient subdir macro. I last removed this
+ macro in feb of '92. How does it keep coming back?
+ (MMALLOC_LIB): renamed to MMALLOC.
+ (BFD_SRC_DIR): renamed to BFD_SRC.
+ (BFD_OBJ_DIR): renamed to BFD_DIR.
+ (BFD_LIB): renamed to BFD.
+ (BFD_INCLUDES): renamed to BFD_CFLAGS.
+ (READLINE_DIR): now represents object directory.
+ (RL_LIB): renamed to READLINE.
+ (READLINE_SRC, READLINE_CFLAGS, OPCODES, OPCODES_CFLAGS): new
+ macros.
+ (INTERNAL_CFLAGS): added GDB_CFLAGS, OPCODES_CFLAGS,
+ READLINE_CFLAGS, BFD_CFLAGS. Dropped USER_CFLAGS.
+ (LDFLAGS): removed default assignment.
+ (TEXIDIR, INCLUDE_DEP, MMALLOC_DIR, MMALLOC_DEP, BFD_DEP,
+ READLINE_DEP, LIBIBERTY_DIR, TESTS, depend, STAGESTUFF): unused, so removed.
+ (ALLOCA1, ALLOCA): removed all references. alloca is now in
+ libiberty.
+ (VERSION): unilaterally and arbitrarily bumped to 4.9.3.
+ (SFILES, NONSRC, HFILES, ALLDEPFILES, ALLPARAM, ALLCONFIG):
+ removed all $(srcdir) prefixes.
+ (getopt_h, ieee-float_h, bfd_h, wait_h, dis-asm_h): new macros
+ for potential dependencies. commented out by default.
+ (readline_headers, udiheaders): convenient abbreviations.
+ (gdbcore_h, frame_h, symtab_h, gdbtypes_h, expression_h,
+ value_h, breakpoint_h, command_h, gdbcmd_h, defs_h, inferior_h):
+ new macros used for header file dependencies.
+ (install-info, clean-info): collapse into the info rule.
+ (install): now depends on all.
+ (install-only): new target for installing without depending on
+ all.
+ (uninstall): new target.
+ (config-check, config-check-hosts, config-check-targets): added
+ fixme comments.
+ (ch-exp.tab.c, m2-exp.tab.c): added artificial dependencies in
+ order to force parallel makes into keeping these rules separate.
+ * configure.in: omit cat'ing depend file onto generated Makefile.
+ * alldeps.mak, depend: removed.
+
+ * inferior.h: remove redundant include of symtab.h which is
+ included in value.h via breakpoint.h.
+
+ * alloca.c: removed. alloca is now in libiberty.
+
+ * config/m88k/delta88.mh, config/ns32k/merlin.mh (M_UNINSTALL):
+ new macro to undo what M_INSTALL does.
+
+Wed Jun 23 00:25:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/ns32k/{merlin.mh,xm-merlin.h}: Be consistent about name
+ of gdb-sh.
+
+ * dbxread.c (copy_pending): Change name and function of begi argument
+ to endi, since that is what the caller needs.
+
+ * Makefile.in (TAGFILES): Don't include YYFILES.
+
+ * Makefile.in (HFILES): Include monitor.h.
+
+ * Makefile.in: Include text that used to be in alldeps.mak.
+ Remove config/mips/{bigmips.mh,xm-bigmips} from it.
+ * Makefile.in, configure.in: Remove all traces of alldeps.mak.
+
+ * main.c (main): Print help message on stdout not stderr
+ per standards.texi.
+ New option --version per standards.texi.
+ In help message, show long options with "--" not "-".
+ Don't try to print help message or version until after we have
+ called initialize_all_files.
+
+Tue Jun 22 11:03:13 1993 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c: Delete useless #if 1 statements.
+ (hp_type_translate): Use T_LONG, T_UNS_LONG, and T_DOUBLE instead
+ of magic integers. Fix handling for T_UNS_INT. Abort if the type
+ passed in is not an "immediate" type.
+ (read_hp_enum_type): Properly compute the size of the type.
+ (read_hp_array_type): Likewise.
+ (hp_type_lookup): Prefix the names of structs, unions and enums
+ with "struct", "union", and "enum" as appropriate.
+
+Tue Jun 22 03:15:38 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * solib.c (solib_add_common_symbols): Don't call lookup_minimal_symbol.
+ (solib_add): Call special_symbol_handling once, not once per library.
+
+ * procfs.c (procfs_resume): Don't pass a SIGTSTP whose action
+ is SIG_DFL.
+
+ * procfs.c (procfs_resume): Skip the unnecessary PRSVADDR on all
+ systems, not just Solaris.
+
+ * stabsread.c: Include <ctype.h>.
+
+Mon Jun 21 16:09:46 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * fork-child.c (fork_inferior): Quote exec_file so it can contain
+ funky characters.
+
+Mon Jun 21 16:56:47 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (INCLUDE_CFLAGS): Add BFD_INCLUDES for now, since
+ bfd.h is included by target.h, which most of gdb includes.
+ * depend: Hand remove BFD_INCLUDES from ${CC} lines, now that
+ it's in INCLUDE_CFLAGS.
+
+Mon Jun 21 16:09:46 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * config/i386/*aix*, i386aix-nat.c: New files.
+ * configure.in: Use them.
+ * alldeps.mak: List them.
+ * coffread.c (decode_base_type): Deal with anonymous enum type.
+ * i387-tdep.c (print_387_status_word): Add comment re "top".
+ * i386-tdep.c [I386_AIX_TARGET] (i386_extract_return_value): New func.
+ * dbxread.c: Use SEEK_SET and SEEK_CUR, not L_*. Define them if and
+ only if not defined by a header file.
+ * mipsread.c: Don't define L_SET or L_INCR.
+
+Mon Jun 21 15:10:07 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (BFD_INCLUDES): Bfd.h is now back in bfd build dir.
+ * depend: Hand updated to match.
+
+Mon Jun 21 10:13:42 1993 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c: Include "demangle.h".
+ (process_one_debug_symbol): Set the SYMBOL_LANGUAGE and
+ SYMBOL_INIT_DEMANGLED_NAME for the current symbol. Adjust
+ SYMBOL_VALUE for local variables in the stack by the size of the
+ current function's stack (found in unwind descriptor). Keep
+ better track of the current unwind descriptor.
+
+Sun Jun 20 13:11:11 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * stabsread.c (read_struct_fields): Don't call read_cpp_abbrev on $_.
+ (read_cpp_abbrev): Don't complain specially for $_. Also return 0 if
+ we don't recognize the abbrev.
+
+Sun Jun 20 00:24:41 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * solib.c (solib_add_common_symbols): Add comment about performance.
+
+Fri Jun 18 12:37:36 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/mips/{{x,n}m-riscos.h,riscos.mh}: New files.
+ * configure.in (mips-*-sysv*): Use riscos for host, bigmips for target.
+
+ * config/mips/{{x,n}m-news-mips.h,news-mips.mh}: New files.
+ * config/mips/{bigmips.mh,xm-bigmips.h}: Remove.
+ * configure.in (mips-sony-*): Use news-mips for host.
+
+ * buildsym.h: Doc fix for processing_acc_compilation.
+
+Thu Jun 17 19:57:08 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * printcmd.c (print_formatted): Don't use tab in wrap_here arg.
+
+Thu Jun 17 17:29:30 1993 Jim Kingdon (kingdon@lisa.cygnus.com)
+
+ * Makefile.in (INTERNAL_CFLAGS): Include ../include as well as
+ ${srcdir}/../include.
+
+ * config/m88k/xm-delta88.h: Comment out unused defines which conflict
+ with system headers.
+ * printcmd.c (printf_command): Cast second arg to vprintf to PTR.
+ Use VPRINTF macro if defined.
+ * config/m88k/xm-delta88.h: Define VPRINTF. Include <sys/siginfo.h>.
+ Define TIOC{GETC,GLTC}_BROKEN.
+ * m88k-nat.c: Uncomment include of <sys/ptrace.h>.
+ * main.c: Rename initialize_{main,cmd_lists,history} to init_* to
+ make things easier on munch (apparently this matters on
+ the delta88 with svr3).
+
+Thu Jun 17 16:53:56 1993 david d `zoo' zuhn (zoo@cygnus.com)
+
+ * Makefile.in: canonicalize install.sh; for use within
+ this directory (and subdirs)
+
+Tue Jun 15 17:01:23 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: remove parentdir support; use INSTALL_XFORM
+
+Thu Jun 17 15:08:35 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * configure.in (alpha-*-osf*), config/alpha/alpha-osf.mh: New
+ host.
+ * sh-tdep.c (frame_find_saved_regs): Use NUM_REGS rather than hard
+ wired (and wrong) constant.
+ * values.c (unpack_long): Add case to unpack when target object is
+ sizeof(int).
+ * config/sh/tm-sh.h (REGISTER_NAMES): Know about the news ones the
+ simulator defines.
+
+Wed Jun 16 16:08:18 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * NEWS: tracking user visible changes starting with
+ vxworks-timeout.
+
+ * remote-vx.c (_initialize_vx): rename user settable option from
+ rpcTimeout to vxworks-timeout.
+
+Wed Jun 16 14:34:10 1993 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c (hp_type_translate): Fix promotion bugs from
+ char to short and short to int.
+
+Wed Jun 16 12:21:49 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (depend): More makefile diddling.
+ * alldeps.mak, depend: Update to latest automatically built
+ versions.
+
+ * Makefile.in (depend): Bfd.h keeps moving, keep up with it.
+ * alldeps.mak, depend: Update to latest automatically built
+ versions.
+
+Tue Jun 15 12:26:05 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * remote-vx.c: include gdbcmd.h for setlist.
+ (_initialize_vx): make rpcTimeout user settable.
+
+Mon Jun 14 09:23:51 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * main.c, gdbcmd.h: Add function filename_completer.
+ * main.c, symfile.c, source.c, exec.c, core.c: Use it for
+ "directory", "source", "cd", "symbol-file" "add-symbol-file",
+ "load", "file", "exec-file", "core-file" commands.
+ (But '/' is a word break, limiting usefulness; see comments).
+
+ * source.c (mod_path): Warning not error if can't find directory.
+
+ * isi-xdep.c: New file.
+ * config/m68k/isi.mh (XDEPFILES): Add isi-xdep.o
+
+Sun Jun 13 09:17:48 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * config/m68k/xm-news.h: Include <sys/param.h>.
+
+ * m88k-tdep.c (IEEE_isNAN): Remove.
+ config/m88k/tm-m88k.h (INVALID_FLOAT): Return 0. This was the same
+ broken isNAN as on the mips.
+
+ * valprint.c (_initialize_valprint): Use c->function.sfunc not just
+ c->function.
+
+ * dbxread.c (process_one_symbol): If SUN_FIXED_LBRAC_BUG is not
+ defined, don't worry about Sun's silly LBRAC bug.
+ * config/m68k/tm-sun3.h: Define SUN_FIXED_LBRAC_BUG to 0.
+
+ * dbxread.c (process_one_symbol): If there's a symbol before an
+ N_SO, don't error().
+ (case N_BCOMM): complain () not error ().
+
+ * defs.h, main.c (catch_errors): Add return_mask arg.
+ stack.c (print_frame_info): Pass RETURN_MASK_ERROR.
+ other callers: Pass RETURN_MASK_ALL.
+ (return_to_top_level), callers: Add return_reason arg.
+ * utils.c (quit):
+ Use return_to_top_level (RETURN_QUIT) instead of error ().
+ * main.c (main), tm-nindy960.h (ADDITIONAL_OPTION_HANDLER):
+ Use SET_TOP_LEVEL not setjmp (to_top_level).
+ * remote-nindy.c: Use catch_errors not setjmp (to_top_level).
+
+Sat Jun 12 14:40:54 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * solib.c (solib_create_inferior_hook) [SVR4_SHARED_LIBS]:
+ Don't try to get the debug base yet.
+
+ * dbxread.c (process_one_symbol): Set n_opt_found based on whether
+ a non-gcc N_OPT symbol is found. Make SUN_FIXED_LBRAC_BUG a macro
+ which returns 0 or 1 to say whether to do it.
+ * config/sparc/sun4{sol2,os4}.h
+ (SUN_FIXED_LBRAC_BUG,VARIABLES_INSIDE_BLOCK): Use n_opt_found so
+ the right thing happens for both acc and SunOS4 /bin/cc.
+
+ * valprint.c (print_hex_chars): Use local_hex_format_{pre,suf}fix.
+ * printcmd.c (print_scalar_formatted): Use val_print_type_code_int.
+
+ * mips-tdep.c: Remove isa_NAN; it assumed sizeof(host int) == 4 and
+ probably contained byte-order sins too.
+ config/mips/tm-mips.h (INVALID_FLOAT): Define to 0 like most machines.
+ The IEEE_FLOAT code in print_floating takes care of it.
+
+Sat Jun 12 14:47:04 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.9.2.
+ * c-valprint.c (c_val_print): For array of chars printed with
+ string syntax, don't print the address of the array. From
+ bothner@cygnus.com.
+ * c-exp.y (yylex): Recognize '.' as indicating a floating point
+ number regardless of the radix. From wilson@cygnus.com.
+ * valprint.c (set_input_radix_1, set_output_radix_1): New
+ prototypes and functions that do the actual radix setting work.
+ * valprint.c (set_radix, set_output_radix, set_input_radix):
+ Rewrite to use set_input_radix_1 and set_output_radix_1.
+ * valprint.c (initialize_valprint): Enable commands to
+ independently set and show input and output radices.
+ * valprint.c (show_radix): New prototype and function that
+ handles separate input and output radices.
+
+Fri Jun 11 18:39:38 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ Patches from Jeff Law, law@cs.utah.edu:
+ * hppa-pinsn.c: Now uses disassembler from opcode library,
+ this contains only the stub function print_insn.
+
+Fri Jun 11 15:19:59 1993 K. Richard Pixley (rich@cygnus.com)
+
+ * main.c (main): back to two periods for elipse.
+ (print_gdb_version): revised format for configuration info.
+
+Fri Jun 11 10:24:35 1993 Fred Fish (fnf@cygnus.com)
+
+ * defs.h (INT_MAX): Cast unsigned shift result to int.
+
+Fri Jun 11 10:17:41 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * dbxread.c (process_one_symbol): Rather than having
+ BLOCK_ADDRESS_FUNCTION_RELATIVE a macro, make it a variable which
+ is true if we are doing stabs-in-elf, false otherwise.
+ config/sparc/tm-sun4sol2.h: Don't define it.
+
+Fri Jun 11 13:33:40 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * remote-mips.c (mips_send_packet): Don't print garbage character
+ in debugging info.
+ (mips_request): Don't check that remote pid is 0, because
+ sometimes it isn't.
+ (mips_fetch_registers): Pass a pointer to SWAP_TARGET_AND_HOST,
+ not an integer.
+
+Fri Jun 11 10:17:41 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * stack.c (print_frame_info): Use catch_errors around print_frame_args.
+
+ * Makefile.in (install): Don't depend on gdb.
+
+ * Rename remote-es1800.c to remote-es.c
+ and remote-st2000.c to remote-st.c for 14-char filenames.
+ config/m68k/{es1800,st2000}: Use the new names.
+
+ * mips-tdep.c (isa_NAN): Don't return true on -0.
+
+Fri Jun 11 10:24:35 1993 Fred Fish (fnf@cygnus.com)
+
+ * defs.h (INT_MAX): Cast unsigned shift result to int.
+
+Thu Jun 10 13:26:41 1993 Fred Fish (fnf@cygnus.com)
+
+ * elfread.c (elf_symtab_read): Add bfd section address to bfd
+ symbols, now that they are section relative.
+ * solib.c (bfd_lookup_symbol): Ditto.
+
+Thu Jun 10 11:27:34 1993 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c (read_hp_function_type): Adjust SYMBOL_VALUE for
+ arguments in the stack by the size of the current function's stack
+ (found in the unwind descriptor).
+ (process_one_debug_symbol): Likewise. Keep track of the current
+ function's unwind descriptor.
+
+Thu Jun 10 10:56:56 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Makefile.in (depend): Add bfd -I's for paread.c and xcoffexec.c
+ depend: Updated accordingly.
+
+Wed Jun 9 16:08:44 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Makefile.in (*.tab.c): Use mv for atomic update.
+
+ * Makefile.in ({dist,real}clean): Also remove nm.h.
+ (realclean): Also remove ${TESTS}, y.output, yacc.{acts,tmp}.
+ (distclean): Don't rebuild *.tab.c or TAGS.
+
+Wed Jun 9 12:56:58 1993 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in (version.c): add host and target names to version.c.
+ * main.c (main): print three periods for the elipse.
+ (print_gdb_version): also print configuration.
+
+ * udi/udiids.h, udi/udip2soc.c, udi/udiphcfg.h, udi/udiphunix.h,
+ udi/udiproc.h, udi/udipt29k.h, udi/udiptcfg.h, udi/udisoc.h,
+ udi/udr.c: Change AMD copyrights to FSF copyleft '93.
+
+ * remote-eb.c (get_hex_regs, eb_fetch_registers), remote-adapt.c
+ (get_hex_regs, adapt_fetch_registers): cast args to
+ supply_register to avoid gcc warning.
+
+ * config/a29k/a29k.mt (TDEPFILES): drop minimon support. It
+ doesn't compile on solaris and is now obsolete.
+
+ * config/sparc/sun4os4.mh (XM_CLIBS): remove -lresolv. This
+ breaks stock sunos installations.
+
+Wed Jun 9 06:14:33 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * m68k-stub.c: Add comment about frame cache.
+
+ * target.h (target_store_registers): Doc fix re error handling.
+
+ * findvar.c (write_register): Call SWAP_TARGET_AND_HOST regardless
+ of register_valid[regno].
+
+Tue Jun 8 14:42:10 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * symtab.h, dwarfread.c: Doc fix re dependencies.
+
+Tue Jun 8 17:54:09 1993 Rob Savoye (rob@rtl.cygnus.com)
+
+ * serial.c (serial_close): If scb is NULL, don't try to close
+ it.
+ * configure.in: Add support for rom68k and bug boot monitors.
+
+Tue Jun 8 17:39:12 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * coffread.c (init_stringtab): Fix bug where sizeof(long) != 4.
+ * gdbcore.h, core.c (read_memory_unsigned_integer): New function.
+ * findvar.c (read_register, write_register): Fix thinko where
+ sizeof(host long) != sizeof(target int).
+ * h8300-tdep.c: Use new read_memory_unsigned_integer call.
+ * sh-tdep.c (_initialize_sh_tdep): Add memory_size command.
+
+Tue Jun 8 14:42:10 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * Move config/m68k/tm-m68k.h (FRAME_FIND_SAVED_REGS) to
+ m68k-tdep.c (m68k_find_saved_regs). Don't duplicate code between
+ 68881 and non-68881 cases. Check for a pair of movel instructions.
+
+Tue Jun 8 14:52:55 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ First cut at sparc-vxworks targetting.
+ * config/sparc/tm-vxsparc.h, config/sparc/vxsparc.mt: new files.
+ * configure.in: sparc-vxworks gdb_target now vxsparc.
+
+ * remote-eb.c, remote.c: symfile.h requires bfd.h so include it.
+
+Tue Jun 8 14:42:10 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * config/m68k/xm-news.h: add "extern int errno".
+
+Tue Jun 8 13:45:07 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * remove-vx.c (vx_read_register, vx_write_register): collapse
+ ifdef I80960 else (assumes) m68k into parameterizable macros
+ VX_NUM_REGS and VX_SIZE_FPREGS.
+ * config/m68k/tm-vx68.h, config/i960/tm-vx960.h (VX_NUM_REGS,
+ VX_SIZE_FPREGS): new definitions.
+
+Tue Jun 8 11:08:29 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * symfile.{c,h} (generic_load): New function.
+ remote{,-nindy,-eb,-mips}.c: Use it.
+
+Mon Jun 7 20:07:30 1993 Stu Grossman (grossman@cygnus.com)
+
+ * Makefile.in (depend): More sed gubbish to deal with
+ ../bfd/bfd.h being generated during the build.
+ * depend: Re-done with corrected makefile.
+
+Mon Jun 7 16:32:05 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (BFD_SRC_DIR): Renamed def and usages from BFD_DIR.
+ * Makefile.in (BFD_OBJ_DIR): New definition for the bfd build
+ directory to find automatically generated header files and library.
+ * Makefile.in (BFD_LIB): Use BFD_OBJ_DIR.
+ * Makefile.in (LINTFLAGS): Include BFD_OBJ_DIR.
+ * Makefile.in (saber_gdb): Include BFD_OBJ_DIR.
+ * Makefile.in (depend): Include BFD_OBJ_DIR in gcc args.
+ * Makefile.in (paread.o, xcoffexec.o): Remove, now in depend.
+ * depend, alldeps.mak: Rebuild after Makefile.in changes.
+
+Fri Jun 4 10:18:51 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: change lynx support to CPU-*-lynxos*
+
+ * Makefile.in (subdir_do): change test from existence of directory
+ to existence of Makefile (the directory may exist but not be configured)
+
+Thu Jun 3 01:18:51 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config/sparc/xm-sun4sol2.h: define MEM_FNS_DECLARED
+
+Fri Jun 4 10:43:33 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in (mips-idt-ecoffl*): New target; use idtl.
+ (mips-idt-ecoff*): Added trailing '*'.
+ * config/mips/idtl.mt: New file; like idt.mt, but little endian.
+
+Thu Jun 3 17:36:56 1993 Stu Grossman (grossman@cygnus.com)
+
+ * ser-go32.c: Clean up lots of compilation nits.
+
+Thu Jun 3 14:44:57 1993 Stu Grossman (grossman@cygnus.com)
+
+ * Patches from Jeffrey Law <law@cs.utah.edu>.
+ * hppab-nat.c: Eliminate unnecessary ifdefs for
+ FETCH_INFERIOR_REGISTERS, CANNOT_FETCH_REGISTER, and
+ CANNOT_STORE_REGISTER.
+ (fetch_register): Delete code to handle CANNOT_FETCH_REGISTER.
+ * hppa-pinsn.c: Support 'I', 'J', and 'K' in output
+ templates for 1.1 FP computational instructions.
+
+Thu Jun 3 03:34:49 1993 Stu Grossman (grossman@cygnus.com)
+
+ * Makefile.in: Remove ser-tcp.[co]. (Use XDEPFILES instead.)
+ * alldeps.mak, depend: Rebuild to account for ser-tcp.
+ * config/sparc/sun4os4.mh: Add ser-tcp to XDEPFILES.
+ * gdbserver/Makefile.in (gdbserver): Use -lbsd.
+ * gdbserver/remote-inflow{-sparc}.c (create_inferior): Don't use a
+ shell when running the child, as args have been expanded by the
+ time we get here. Simplify calling convention.
+ * gdbserver/remote-server.c (main): Use new calling convention
+ for create_inferior, remove defunct code for coalescing argv.
+ Remove extra calls to mywait(), as we no longer have to wade
+ through a shell.
+
+ * target.c (target_read_memory_partial): Don't deref errnoptr
+ when checking for null pointer.
+
+Wed Jun 2 19:58:46 1993 John Gilmore (gnu@cygnus.com)
+
+ * remote-es1800.c: Fix typo.
+
+Tue Jun 1 21:22:39 1993 Fred Fish (fnf@cygnus.com)
+
+ * target.c (target_read_memory_partial): Like target_read_memory,
+ but does partial reads, such as reads that bump into the end of
+ the address space.
+ * target.h (target_read_memory_partial): Add prototype.
+ * valprint.c (PRINT_MAX_DEFAULT): New define, initial value 200.
+ * valprint.c (val_print_string): Complete rewrite to fix bug with
+ bumping into end of memory, avoiding unnecessarily long reads, and
+ fixing bug when print_max is set to 0 (unlimited print length).
+ * valprint.c (_initialize_valprint): Use PRINT_MAX_DEFAULT to
+ initialize print_max.
+
+Tue Jun 1 18:11:35 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * configure.in: Add support for rom68k and bug boot monitors.
+
+Mon May 31 10:37:04 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * printcmd.c (print_scalar_formatted): Print integers bigger than
+ LONGEST in hex no matter how big, and no matter what the format
+ and size.
+
+ * stabsread.c (read_type): Skip type attributes if present.
+
+ * stabsread.c (read_huge_number): Don't accept '0' + radix as part
+ of number, just through '0' + radix - 1.
+
+Sun May 30 15:35:21 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (SER_HARDWIRE): Temporarily comment out ser-tcp.o.
+
+ * {dbxread.c, dwarfread.c} (read_ofile_symtab): Rewrite to take
+ single parameter, the pointer to the partial symtab, rather than
+ a bunch of args that are derived from the partial symtab. Change
+ prototypes and callers to match.
+
+ * dbxread.c (read_ofile_symtab): Remove "#if 1" around code to
+ set demangling style automatically.
+ * defs.h (CPLUS_MARKER): Clarify comment that this is only for
+ GNU C++, not C++ in general.
+ * symtab.h (general_symbol_info): Simplify by eliminating one
+ structure level for the language dependent info.
+
+Sat May 29 15:59:29 1993 Fred Fish (fnf@cygnus.com)
+
+ * c-typeprint.c (c_type_print_base): Avoid dereferencing NULL
+ names for TYPE_CODE_STRUCT and TYPE_CODE_UNION types.
+ TYPE_CODE_ENUM was already testing for this.
+
+Fri May 28 17:18:05 1993 Stu Grossman (grossman@cygnus.com)
+
+ * Makefile.in: Add new file ser-tcp.c.
+ * defs.h (memcmp): Add decl for memcmp to #ifndef MEM_FNS_DECLARED.
+ * findvar.c (write_register): See if we are writing back the same
+ value that's already in the register. If so, don't bother.
+ * remote.c (putpkt, getpkt): Improve handling of communication
+ problems.
+ * ser-go32.c: Prototype it to death. Update serial_ops and add
+ dummy routines where appropriate.
+ * ser-tcp.c: New module to implement serial I/O via TCP
+ connections.
+ * ser-unix.c: Clean up getting/setting of tty state. Get rid of
+ SERIAL_RESTORE, add SERIAL_{GET|SET}_TTY_STATE interfaces.
+ * serial.c: Add start of support for connect command.
+ (serial_open): Distinguish between tcp and local devices.
+ * serial.h (struct serial_ops): Get rid of restore, add
+ get_tty_state and set_tty_state. Define protoypes and macros for
+ this mess.
+ * gdbserver/remote-utils.c: Add tcp support. (readchar): Do
+ some real buffering. Handle error conditions gracefully.
+ * gdbserver/remote-inflow-sparc.c: Update to remote-inflow.c
+ (Lynx), remove lots of cruft.
+
+Fri May 28 17:24:51 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * printcmd.c (print_address_symbolic): turn this into an assigment
+ instead of an initialization (many compilers don't accept
+ structure initialization).
+
+Thu May 27 16:56:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * xcoffread.c (read_xcoff_symtab): If several program csects in one
+ source file, give them all the name of the source file, rather than
+ the 2nd and subsequent ones having NULL names.
+
+Thu May 27 06:16:56 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * printcmd.c (print_address_symbolic): Append source filename and
+ linenumber of the symbol if print symbol-filename is on.
+ (initialize_printcmd): `set print symbol-filename'.
+
+Wed May 26 13:46:16 1993 Stu Grossman (grossman@cygnus.com)
+
+ * configure.in: Add config for Lynx target. Configure gdbserver
+ only for Lynx. Re-do selective configuration of sparclite.
+
+ * gdbserver/{remote-gutils.c remote-server.c Makefile.in
+ configure.in remote-inflow.c remote-utils.c}: New files to
+ support GDB remote server. Currently only works for Lynx.
+
+Wed May 26 10:28:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabsread.c (define_symbol, case 't'): Only set the name if it
+ is not a pointer type.
+
+ * stabsread.c (define_symbol): Clean up logic; move the read_type
+ calls to inside the switch statement (this improves the error
+ handling).
+
+ * mipsread.c (parse_symbol, parse_partial_symbols): Deal with Fortran
+ common blocks.
+
+Tue May 25 20:44:24 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * printcmd.c (print_formatted, case 'i'): Pass a tab to wrap_here.
+
+ * source.c (line_info): Change "pc" to "address" in messages and
+ use print_address for addresses.
+
+ * source.c (line_info): If we don't find a symtab, print more useful
+ output, including the symbolic address.
+
+ * source.c (line_info): If --fullname, display the source.
+ (identify_source_line), callers: Take pc as argument, rather than
+ assuming innermost frame (emacs doesn't use this, so no one ever
+ noticed).
+ * symtab.h: Declare frame_file_full_name.
+ * main.c: Don't.
+
+Tue May 25 15:30:43 1993 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * breakpoint.c (catch_command_1): Fix typo in error msg.
+
+Tue May 25 16:05:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * elfread.c (elf_symfile_read): Update ELF structure and routine
+ names to specify 32-bit versions.
+ (elf_symtab_read): Retrieve size field directly from symbol,
+ instead of using old kludge.
+
+ * mips-pinsn.c (print_insn): Cast address to bfd_vma before
+ calling opcodes library.
+ * z8k-tdep.c (print_insn): Likewise.
+
+Tue May 25 13:06:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabsread.c: Remove all uses of error(). Make error_type and
+ read_type_number static.
+ (define_symbol): Don't try to deal with a missing symbol
+ descriptor which isn't followed by digit, '(', or '-'.
+ * stabsread.h: Don't declare read_type_number here.
+ * gdbtypes.h: Don't declare error_type here.
+ * xcoffread.c: Remove NO_TYPEDEFS code.
+
+Tue May 25 09:33:16 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips-tdep.c: Removed #include of many header files, and #define
+ of MIPSMAGIC; no longer used.
+
+Tue May 25 09:36:13 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Many places: replace "the inferior" in messages with "the program"
+ or "the program being debugged".
+ * inflow.c (try_writing_regs): Remove; it's been #if 0'd forever
+ and I'm getting sick of maintaining it.
+
+ * config/i386/linux.mh: Don't use \ newline; the awk scripts don't
+ support it.
+
+ * config/i386/go32.mh: Define SER_HARDWIRE.
+ * Makefile.in: Define SER_HARDWIRE.
+ (DEPFILES): Use it.
+ (alldeps.mak): Add SER_HARDWIRE.
+ Remove all references to ser-hardwire.{c,o}.
+ * configure.in: Remove all ser_hardwire and gdb_serial_driver stuff.
+
+Mon May 24 23:50:05 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * sparc-nat.c (store_inferior_registers): Fill in all members of
+ inferior_fp_registers by reading them from the inferior before
+ modifying and writing them back.
+ Fixes unexplainable inferior FP exceptions after calls to the inferior
+ or setting of floating point registers.
+ * mips-tdep.c (mips_skip_prologue): Skip move of argument register
+ to register which is generated by gcc-2.4.
+
+Tue May 25 00:42:39 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * hppa-pinsn.c: Define OLD_TABLE before including opcode/hppa.h.
+
+Mon May 24 13:55:14 1993 Stu Grossman (grossman@cygnus.com)
+
+ * config/i386/{i386lynx.mh i386lynx.mt nm-i386lynx.h tm-i386lynx.h
+ xm-i386lynx.h}: New configuration for Lynx.
+
+Mon May 24 10:01:10 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * mipsread.c (parse_symbol): Deal with scVar and scVarRegister.
+ * symtab.h: Comment that LOC_REGPARM_ADDR can be call by reference.
+
+ * c-typeprint.c (c_type_print_base): Don't print typedef'd names
+ as struct, union, or enum tags.
+
+Mon May 24 01:10:01 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * symmisc.c (dump_msymbols): Avoid gdb coredump with stripped
+ executable.
+
+Sat May 22 10:03:09 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infrun.c (wait_for_inferior),
+ infcmd.c (program_info, signal_command): Use symbolic signal names.
+
+ * inftarg.c (child_wait): Deal with EINTR and include message from
+ strerror if printing an error message.
+
+ * main.c (command_line_input): Use STOP_SIGNAL not SIGTSTP.
+
+ * stabsread.c: Remove most uses of lookup_fundamental_type.
+ (define_symbol): Use read_type for type of enum constant,
+ not just read_type_number. Also don't call error().
+ (define_symbol): For unrecognized constant type, one complaint (the
+ one from error_type) is enough. Don't make our own in addition.
+ (define_symbol): Don't treat an N_FUN 'R' as a prototype.
+ * gdbtypes.h: Doc fixes.
+
+Sat May 22 03:33:07 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ Fix stack unwinding through _sigtramp on Irix. These patches are from
+ Paul Flinders <ptf@delcam.co.uk>.
+ * mipsread.c (fixup_sigtramp): Find _sigtramp on Irix even when the
+ executable uses sigvec.
+ * mips-tdep.c (read_next_frame_reg): Allow tm-file to override
+ sigcontext offsets.
+ * config/mips/tm-irix3.h: Add sigcontext offsets for Irix.
+
+Sat May 22 00:39:01 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * infrun.c (wait_for_inferior): Clear stop_signal if it should not
+ be passed to the inferior to make "handle <signal> nopass nostop" work.
+
+Sat May 22 00:21:41 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/mips/tm-irix3.h: Clean up, use tm-bigmips.h and redefine
+ the necessary bits.
+ * findvar.c (value_from_register): Fix uninitialized first_addr
+ which caused problems with assignment of doubles to register variables
+ on some targets.
+ * mipsread.c: Remove TM_FILE_OVERRIDE, include tm.h and provide the
+ missing mips definitions if necessary.
+
+ Fix handling of double register variables for mips targets and big
+ endian hosts. These patches are from Paul Flinders <ptf@delcam.co.uk>.
+ * config/mips/tm-mips.h: Increase MAX_REGISTER_{RAW,VIRTUAL}_SIZE to
+ 8 bytes for doubles.
+ * config/mips/tm-mips.h (REGISTER_CONVERT_TO_TYPE): New macro for
+ conversion of type held in multiple registers to host format.
+ * config/mips/tm-mips.h (REGISTER_CONVERT_FROM_TYPE): New macro,
+ companion to REGISTER_CONVERT_TO_TYPE.
+ * config/mips/tm-mips.h (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE):
+ Convert to function calls.
+ * config/mips/tm-mips.h (FIX_CALL_DUMMY): New code for big endian
+ mips targets.
+ * mips-tdep.c (mips_print_register): Raw buffer now needs just
+ MAX_REGISTER_RAW_SIZE bytes.
+ * mips-tdep.c (mips_print_register): Use REGISTER_CONVERT_TO_TYPE
+ (if defined) for doubles.
+ * mips-tdep.c: (mips_extract_return_value, mips_store_return_value):
+ New functions, take care of REGISTER_CONVERT_TO/FROM_TYPE.
+ * valops.c (value_assign): Use REGISTER_CONVERT_TO_TYPE if
+ defined.
+ * findvar.c (value_from_register): Use REGISTER_CONVERT_TO_TYPE if
+ defined.
+
+Fri May 21 09:04:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.in: Add i[34]86-*-isc*.
+
+ * stabsread.c: Make sure all complain() pass the address of the struct.
+
+ * xcoffread.c: Make sure all struct complaints are static not auto.
+
+ * Makefile.in: Add rule for xcoffexec.o like that for paread.o.
+
+ * xcoffread.c (process_xcoff_symbol, case C_LSYM): Use define_symbol.
+
+Wed May 19 12:33:59 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/i386/linux.mh: Re-enable coredumps now that they should work.
+
+Wed May 19 15:44:20 1993 K. Richard Pixley (rich@cygnus.com)
+
+ * config/m68k/tm-m68k.h (FRAME_CHAIN): add missing close paren.
+
+Wed May 19 15:33:57 1993 Stu Grossman (grossman@cygnus.com)
+
+ * config/pa/nm-hppab.h: Comment PTRACE_ARG3_TYPE.
+
+Wed May 19 12:33:59 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (INSTALLED_LIBS): New variable.
+
+Tue May 18 14:08:50 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * main.c (quit_command): In the "quit anyway?" message, tell the user
+ whether we are planning to detach or kill the program.
+
+ * config/vax/vaxbsd.mh: Add "NAT_FILE= nm-vax.h".
+ * config/vax/xm-vaxbsd.h: Use <sys/param.h> not <machine/limits.h>
+
+ * infcmd.c (read_pc): Doc fix.
+
+ * printcmd.c (print_address_symbolic): Use %u not %d for offset.
+
+ * blockframe.c (get_prev_frame_info): If pc in sigtramp, set
+ signal_handler_caller.
+ * tm-68k.h (FRAME_{CHAIN,SAVED_PC}): Deal with sigtramp.
+ * tm-hp300bsd.h: Define SIGTRAMP_{START,END} not IN_SIGTRAMP.
+ * inferior.h (IN_SIGTRAMP): Definition moved from infrun.c.
+ Use SIGTRAMP_START if defined.
+ * infcmd.c (step_1): Use SIGTRAMP_{START,END} if needed.
+ * infrun.c (wait_for_inferior): Check IN_SIGTRAMP before SKIP_PROLOGUE.
+
+ * infptrace.c: Remove unused KERNEL_U_ADDR_HPUX code.
+
+ * infcmd.c (step_1): Fix poorly worded error message.
+
+ * config/{i386/linux.mh,m68k/isi.mh} (NATDEPFILES):
+ Comment out corelow.c because core dumps are broken on these machines.
+
+ * Makefile.in (depend): Put "${srcdir}" in generated dependencies
+ if srcdir is not ".".
+ Also put in -I${BFD_DIR} or -I${READLINE_DIR} for files which need it.
+ (INCLUDE_CFLAGS): Remove BFD_DIR and READLINE_DIR.
+ * depend: Update to latest automatically built version.
+
+Tue May 18 08:10:45 1993 Fred Fish (fnf@cygnus.com)
+
+ * ChangeLog, ChangeLog-92: Split ChangeLog at 1993.
+ * Makefile.in (NONSRC): Add ChangeLog-92
+
+Tue May 18 08:03:37 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * findvar.c ({read,write}_register): Use REGISTER_RAW_SIZE
+ not typo RAW_REGISTER_SIZE.
+
+ * frame.h, inferior.h: Doc fixes.
+
+Mon May 17 15:43:03 1993 Stu Grossman (grossman@cygnus.com)
+
+ * findvar.c (write_register): Add sanity check for register size.
+ (read_register): Fixup sanity check for register size to be
+ consistent with write_register().
+
+Mon May 17 07:36:20 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * sparclite/Makefile.in: Add dummy info, install and install-info
+ targets.
+
+Thu May 13 07:30:22 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * remote-nindy.c: Removed declaration of coffstrip.
+ * nindy-share/nindy.c: #if 0 coffstrip routine; no longer used.
+
+Wed May 12 00:35:19 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.9.1 after release and cvs
+ tagging.
+
+ * Makefile.in (VERSION): GDB 4.9 release.
+
+Tue May 11 08:04:41 1993 Fred Fish (fnf@cygnus.com)
+
+ * README: Update known bugs to include the Solaris bug that
+ leaves core dumps in the current directory when restarting the
+ inferior with "run". Expand on the testsuite information.
+
+ * Makefile.in (VERSION): Bump to 4.8.96 for what should hopefully
+ be the last 4.9 prerelease test archive.
+
+Mon May 10 22:13:23 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * config/m68k/xm-hp300bsd.h: Include <sys/param.h> to avoid INT_MAX
+ redefined warnings.
+
+Mon May 10 20:00:43 1993 Fred Fish (fnf@cygnus.com)
+
+ * README, NEWS: Update for gdb 4.9 release.
+
+Mon May 10 19:38:34 1993 John Gilmore (gnu@cygnus.com)
+
+ * ch-exp.y (MAX, MIN): Rename to MAX_TOKEN, MIN_TOKEN.
+ * target.c (MIN): #undef before defining.
+
+Mon May 10 16:03:03 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ Patch from Jeffrey Law:
+ * gdb/config/pa/nm-hppab.h (PTRACE_ARG3_TYPE): Define as caddr_t.
+
+Mon May 10 15:28:27 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * hppa-tdep.c (hppa_push_arguments): Allocate correct amount of
+ memory.
+
+Mon May 10 13:14:46 1993 Fred Fish (fnf@cygnus.com)
+
+ * ch-exp.y (start): Apply work-around to avoid bison warning.
+
+Sun May 9 07:25:02 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (BISON): Remove double quotes around BISON
+ definition when bison is used.
+
+ * configure.in (hppa*-hp-bsd): Change to hppa*-hp-bsd*
+ * configure.in (hppa*-hp-hpux): Change to hppa*-hp-hpux*
+ * configure.in (m68*-hp-bsd): Change to m68*-hp-bsd*
+ * configure.in (m68*-hp-hpux): Change to m68*-hp-hpux*
+ * configure.in (hppa*-*-bsd): Change to hppa*-*-bsd*
+ * configure.in (hppa*-*-hpux): Change to hppa*-*-hpux*
+ * configure.in (m68*-hp-bsd): Change to m68*-hp-bsd*
+ * configure.in (m68*-hp-hpux): Change to m68*-hp-hpux*
+
+ * Makefile.in (VERSION): Bump to 4.8.6.
+
+Sat May 8 12:36:03 1993 Fred Fish (fnf@cygnus.com)
+
+ * config/pa/xm-hppah.h (MALLOC_INCOMPATIBLE): Define it, and
+ include declarations for malloc/realloc/free. Both malloc and
+ realloc return 'void *' for non-ANSI compilations.
+
+Sat May 8 01:39:30 1993 (pes@regent.e-technik.tu-muenchen.de)
+
+ * coffread.c (read_coff_symtab): Don't fclose stream as it is no
+ longer opened twice.
+
+Thu May 6 21:08:55 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * solib.c (clear_solib): Don't close bfd if it is NULL.
+
+Thu May 6 20:55:35 1993 Fred Fish (fnf@cygnus.com)
+
+ * core.c (dis_asm_read_memory): Cast second arg of
+ target_read_memory to "char *".
+ * breakpoint.c (watchpoint_check): Change arg type from PTR to
+ "char *", to match other functions called by catch_errors().
+
+Thu May 6 15:47:45 1993 Stu Grossman (grossman@cygnus.com)
+
+ * More patches from Jeffrey Law (law@cs.utah.edu).
+ * gdb/config/nm-hppab.h (PTRACE_ARG3_TYPE): Define as caddr_t.
+ * gdb/config/pa/tm-hppah.h (millicode_start, millicode_end):
+ Delete unnecessary declarations.
+
+Thu May 6 15:15:46 1993 Stu Grossman (grossman@cygnus.com)
+
+ * ser-unix.c (wait_for): Use VTIME to do timeouts instead of
+ poll() for termio{s}.
+
+Thu May 6 10:03:41 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * i386-tdep.c (i386_frame_num_args): Always return -1.
+
+Wed May 5 15:16:33 1993 Stu Grossman (grossman@cygnus.com)
+
+ * Patches from Jeffrey Law <law@cs.utah.edu>.
+ * gdb/hppa-tdep.c: Declare frame_saved_pc.
+ (frameless_function_invocation): New function.
+ (frame_saved_pc, init_extra_frame_info): Use
+ frameless_function_invocation.
+ * gdb/config/pa/tm-hppa.h (SAVED_PC_AFTER_CALL): Use saved_pc_after
+ call instead of just grabbing the value currently in %r2.
+ (FRAMELESS_FUNCTION_INVOCATION): Use frameless_function_invocation.
+ * gdb/config/pa/tm-hppah.h (SAVED_PC_AFTER_CALL): Delete private
+ definition and use the common one in tm-hppa.h.
+ * gdb/hppa-tdep.c (frame_chain_valid): If "use_unwind" is true, then
+ use unwind descriptors to determine if the frame chain is valid.
+ * gdb/hppa-tdep.c (find_dummy_frame_regs): Rework so that
+ it does not assume %r4 is the frame pointer.
+ * gdb/hppa-pinsn.c (print_insn): Handle 'r' and 'R' for break, rsm,
+ and ssm instructions.
+ * gdb/hppa-tdep.c (extract_5r_store, extract_5R_store): New
+ helper functions for print_insn.
+ * gdb/hppa-tdep.c (gcc_p, hpux_cc_p): Delete unused functions.
+ * gdb/config/pa/tm-hppa.h (ABOUT_TO_RETURN): Handle a return
+ which nullifies the following instruction.
+
+Tue May 4 12:11:38 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * infptrace.c [FIVE_ARG_PTRACE]: Define ptrace to call_ptrace and
+ pass the 5th arg there, rather than using an ANSI C-specific macro.
+
+ * Makefile.in (depend): Don't include ${CC} command for *.tab.c.
+
+Tue May 4 19:33:12 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.8.5
+ * Makefile.in (INCLUDE_CFLAGS): Add BFD_DIR and READLINE_DIR
+ directories to include search path.
+ * Makefile.in (CLIBS, CDEPS, ADD_FILES, ADD_DEPS): Clean up
+ whitespace.
+ * Makefile.in (depend): For gcc -MM line, use INTERNAL_CFLAGS
+ * Makefile.in (main.o, dbxread.o, coffread.o, mipsread.o,
+ elfread.o, dwarfread.o, stabsread.o, xcoffread.o, xcoffexec.o,
+ xdr_ld.o, xdr_rdb.o, nindy.o, Onindy.o, ttybreak.o, ttyflush.o,
+ udr.o, udip2soc.o): Remove explicit rules, use the ones that
+ are automatically generated in "depend".
+ * Makefile.in (paread.o): Document why a dependency doesn't get
+ automatically generated in "depend" and leave this explicit rule
+ in for now (FIXME).
+ * depend: Update to latest automatically generated version.
+
+Tue May 4 12:11:38 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * xcoffread.c: Doc fix.
+
+ * Makefile.in (depend): Include $(CC) command in generated output.
+
+Mon May 3 22:51:05 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (NONSRC): Remove ${srcdir}/putenv.c.
+ * Makefile.in (SFILES): Add ${srcdir}/putenv.c.
+ * depend: Update to latest automatically built version.
+
+Mon May 3 19:20:20 1993 Stu Grossman (grossman@cygnus.com)
+
+ * sparclite/Makefile.in: Create default target that does nothing
+ in order to force user to build by hand.
+
+ * sparclite/Makefile: Remove. It's not necessary anymore.
+
+ * ser-unix.c (wait_for): New routine to handle read timeouts,
+ etc. Uses poll() if HAVE_TERMIO[S] is defined, select() otherwise.
+
+Mon May 3 13:52:08 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips-pinsn.c (print_insn): Return value.
+
+Sun May 2 11:43:57 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (SFILES): Remove ser-hardwire.c; it is a link made
+ at configuration time and doesn't belong in the distribution archive.
+
+ * Makefile.in (NONSRC): Add 29k-share/README.
+ * Makefile.in (HFILES): Add 29k-share/udi/udiids.h.
+
+ * defs.h (UINT_MAX, LONG_MAX, INT_MAX, INT_MIN): Replace hex
+ constants with slightly more portable definitions (still depends
+ on 2's complement arithmetic though).
+ * config/i386/nm-linux.h: Define NO_SYS_REG_H for no <sys/reg.h>.
+ * i386v-nat.c (sys/reg.h): Conditionalize include on
+ NO_SYS_REG_H. Linux doesn't have <sys/reg.h>.
+ * ser-unix.c (termio.h): Include <termio.h> like other files that
+ include termio.h, not <sys/termio.h> which may not exist (on
+ linux for example).
+
+Sat May 1 16:05:24 1993 Fred Fish (fnf@cygnus.com)
+
+ * valprint.c (print_longest): Change format parameter from a
+ 'char' to an 'int'. We can't have 'char' parameters with the
+ current coding style, where we mix prototypes with pre-ANSI
+ style declarations.
+ * value.h (print_longest): Change format parameter in prototype
+ from a 'char' to an 'int'.
+
+Sat May 1 02:47:20 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/mips/tm-mips.h (STAB_REG_TO_REGNUM): Match it with the gcc
+ definition.
+ * config/mips/tm-irix3.h (STAB_REG_TO_REGNUM): Add.
+ * irix4-nat.c (fill_fpregset): Fix bug with indexing into fpregsetp.
+
+Fri Apr 30 17:45:32 1993 Stu Grossman (grossman@cygnus.com)
+
+ * The following patches are from Jeffrey Law <law@cs.utah.edu>.
+ * config/pa/hppabsd.mh: Add more files to NATDEPFILES.
+ * config/pa/xm-hppa[bh].h: Define FIVE_ARG_PTRACE.
+ * hppab-nat.c: Delete WANT_NATIVE_TARGET ifdefs.
+ ptrace needs 5 arguments, #define ptrace to always
+ pass zero as the 5th argument.
+
+Fri Apr 30 15:54:13 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * configure.in: Match z8k-*-sim for z8000.
+ * config/h8500/tm-h8500.h, h8500-tdep.c: Lint.
+ * remote-hms.c: Update to use new serial protocol.
+
+Fri Apr 30 16:50:38 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * mips-tdep.c: remove include of sys/dir.h. Doesn't seem
+ necessary and Solaris doesn't have it.
+
+ * Makefile.in (clean-info, install, install-info, info, dvi,
+ check, all): do not echo recursion lines.
+
+ * 29k-share/udip2soc.c (UDIConnect): replace union wait with int.
+
+ * config/sparc/sun4sol2.mh (XM_CLIBS): add -lsocket which is
+ required target ports which use sockets (like a29k-udi).
+
+ * remote-udi.c (udi_wait): Use SIGURG, as Solaris doesn't have SIGLOST.
+
+Fri Apr 30 11:05:42 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * ser-unix.c [USE_{TERMIO,ALARM}_TIMEOUT]: New code to deal with
+ systems lacking select().
+
+ * Makefile.in (TAGS): Doc fix. Deal with empty DEPFILES.
+
+Fri Apr 30 10:06:46 1993 Fred Fish (fnf@cygnus.com)
+
+ * alldeps.mak, depend: Update with latest automatically built
+ versions.
+
+Thu Apr 29 12:03:23 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (SFILES): Add ser-unix.c and ser-go32.c.
+
+ * Makefile.in (make-proto-testsuite.dir): New target to make
+ prototype testsuite tree.
+
+ * Makefile.in (VERSION): Bump to 4.8.4.
+
+Thu Apr 29 08:46:22 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * stabsread.c (define_symbol): If unrecognized constant type,
+ complain() not error().
+
+Thu Apr 29 00:03:59 1993 Fred Fish (fnf@cygnus.com)
+
+ * infptrace.c: Add missing close paren to test for
+ FIVE_ARG_PTRACE defined.
+
+ * defs.h (CC_HAS_LONG_LONG): Set up to define CC_HAS_LONG_LONG
+ when compiling with gcc, but disable it for now. See comment.
+ * defs.h (LONGEST): Define as either "long" or "long long"
+ based on CC_HAS_LONG_LONG.
+ * defs.h (longest_to_int): Use CC_HAS_LONG_LONG to control
+ how longest_to_int is defined.
+ * c-valprint.c (c_val_print): Call print_longest.
+ * expprint.c (dump_expression): Use PRINTF_HAS_LONG_LONG
+ instead of LONG_LONG.
+ * {printcmd.c, gdbtypes.h} (LONG_LONG): Replace usages with
+ CC_HAS_LONG_LONG.
+ * printcmd.c (print_scalar_formatted): Call print_longest
+ and let it figure out what to do for PRINTF_HAS_LONG_LONG.
+ * typeprint.c (print_type_scalar): Call print_longest and let
+ it figure out what to do for PRINTF_HAS_LONG_LONG.
+ * valprint.c (val_print_type_code_int): Call print_longest
+ and let it figure out what to do for PRINTF_HAS_LONG_LONG.
+ * stabsread.c (LONG_LONG): Replace usages with CC_HAS_LONG_LONG.
+ * value.h (struct value): Replace usage of LONG_LONG with
+ CC_HAS_LONG_LONG.
+ * value.h (print_longest): Add prototype.
+ * values.c (LONG_LONG): Replace usages with CC_HAS_LONG_LONG.
+ * values.c (unpack_double): Collapse code that was unnecessarily
+ dependent on CC_HAS_LONG_LONG. Use LONGEST instead of direct types.
+ * values.c (value_from_longest): Remove dependency on
+ CC_HAS_LONG_LONG and just use LONGEST.
+ * solib.c (solib_map_sections): Use bfd_get_filename
+ to access filename field.
+ * solib.c (clear_solib): Save filename and free it later, after
+ bfd_close, since bfd_close may reference it. Use bfd_get_filename
+ to access the field.
+ * config/convex/xm-convex.h (LONG_LONG): Replace with
+ CC_HAS_LONG_LONG. Add define for PRINTF_HAS_LONG_LONG.
+ * doc/gdbint.texinfo (LONG_LONG): Replace with CC_HAS_LONG_LONG.
+ Add PRINTF_HAS_LONG_LONG references.
+
+Wed Apr 28 06:11:38 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * inflow.c (kill_command), infcmd.c (attach_command),
+ remote.c (remote_interrupt_twice): In messages for the user, call it
+ "the program" or "the program being debugged" not "the inferior".
+
+ * hp300ux-nat.c: Cast second arg to supply_register calls.
+ (_initialize_kernel_u_addr, getpagesize): New functions.
+ (store_inferior_register_1): Change arg name from value to val.
+ (fetch_core_registers): Make arg core_reg_size unsigned.
+ Pass 5 args to ptrace.
+ * config/m68k/xm-hp300hpux.h: Define FIVE_ARG_PTRACE.
+ Remove KERNEL_U_ADDR stuff.
+ * infptrace.c [FIVE_ARG_PTRACE]: Pass 5th arg to ptrace.
+ * config/m68k/hp300hpux.m{t,h}:
+ Move exec.o from NATDEPFILES to TDEPFILES
+ * config/m68k/hp300hpux.mt: Mention GAS requirement. Remove
+ hp-include stuff. Add m68k-tdep.o to TDEPFILES.
+
+Wed Apr 28 13:27:54 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * ch-exp.y (yylex): Don't STREQ with simplename if it is NULL.
+
+Wed Apr 28 06:11:38 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * config/sparc/xm-sun4os4.h [__STDC__]: Don't use MALLOC_INCOMPATIBLE.
+
+Wed Apr 28 11:39:18 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * doc/gdb.texinfo: make node "Shell Commands" unconditional;
+ describe `set demangle-style arm' (not cfront);
+ mention can type `q' to discard output, when gdb pages
+
+Wed Apr 28 11:32:39 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * valops.c (search_struct_field): Fix gdb core dump with incomplete
+ stabs info.
+
+Wed Apr 28 06:11:38 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * remote.c: Change timeout to 2.
+ (remote_open): Use unpush_target not remote_close.
+ (remote_resume): If siggnal != 0, give warning not error().
+ (remote_wait, remote_interrupt, remote_interrupt_twice):
+ If we get two interrupts, let the user get out if they want.
+ (remote_{kill,mourn}): New functions.
+ i386-stub.c (handle_exception, case 'k'): Don't BREAKPOINT.
+
+Wed Apr 28 09:20:55 1993 Ian Lance Taylor (ian@rtl.cygnus.com)
+
+ * config/sparc/sun4sol2.mh (XM_CLIBS): Define to be -lnsl.
+
+Wed Apr 28 06:11:38 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Remote targets (mourn): Call unpush_target.
+
+ * config/sparc/xm-sun4os4.h: Declare free() to return int.
+ Remove twisted use of PARAMS.
+
+ * config/rs6000/xm-rs6000.h: Don't define MALLOC_INCOMPATIBLE now
+ that ansidecl.h assumes ANSI on AIX.
+
+Tue Apr 27 10:01:33 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * README: Move most stuff about hacking GDB to doc/gdbint.texinfo.
+ (Known bugs): Remove AIX bugs, revise SPARC struct bug description.
+
+Tue Apr 27 13:44:19 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * expprint.c (print_subexp): Fix bug with OP_SCOPE operator output.
+
+Tue Apr 27 10:01:33 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * remote-vx.c (net_connect): Allow numeric IP address for host.
+
+Mon Apr 26 17:59:38 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/sh/sh.mt, config/sh/tm-sh.h, sh-tdep.c: New files.
+
+Mon Apr 26 07:13:32 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * rs6000-tdep.c (branch_dest): Deal with stepping through system call.
+
+ * symtab.h, xcoffread.c: Revise linetable sorting comments.
+
+Sun Apr 25 02:32:16 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * valops.c (value_cast): A cast might also change the object
+ representation in C++.
+ * dbxread.c (end_psymtab): Copy subpst read_symtab function from pst
+ to get the proper read_symtab function when called from mipsread.c.
+ * mipsread.c (mipscoff_psymtab_to_symtab, psymtab_to_symtab_1):
+ Set cur_bfd in psymtab_to_symtab_1 as CURBFD(pst) is invalid
+ for dummy psymtabs, inhibit processing of dummy psymtabs.
+
+Sat Apr 24 19:59:54 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Changes from (or inspired by) AMD:
+ * remote-udi.c (udi_attach): Assignments to Space and Offset were
+ switched, fix it.
+ (udi_wait): Make error message (UDIGetStdout) match error.
+ (udi_wait): Handle UDIStdinNeeded.
+ * command.c [CANT_FORK]: Use system().
+ * utils.c (prompt_for_continue): Allow quit with 'q'.
+
+ * solib.c (solib_add): Don't call special_symbol_handling if there
+ were errors in symbol_add_stub. Also set so->from_tty before
+ calling symbol_add_stub.
+
+Fri Apr 23 16:17:00 1993 Stu Grossman (grossman@cygnus.com)
+
+ * Merge in HPPA/BSD patches from Utah:
+ * defs.h: Add const to 2nd arg of psignal prototype.
+ * hppah-tdep.c: Renamed to hppa-tdep.c 'cuz it's common code with
+ BSD now.
+ * hppab-core.c: Deleted. No longer useful.
+ * hppab-nat.c: #include more files. Use PT_WUREGS, not
+ PT_WRITE_U.
+ * hppab-tdep.c: Deleted. Supplanted by hppa-tdep.c.
+ * config/pa/hppabsd.mh (NATDEPFILES): Remove hppab-core.o.
+ * config/pa/hppabsd.mt (TDEPFILES): hppab-tdep.o => hppa-tdep.o
+ * config/pa/hppahpux.mt (TDEPFILES): hppab-tdep.o => hppa-tdep.o
+ * config/pa/xm-hppab.h: #define SET_STACK_LIMIT_HUGE.
+
+Fri Apr 23 10:34:02 1993 Stu Grossman (grossman@cygnus.com)
+
+ * Fix two bugs found by deja-gnu. One is the incorrect reporting
+ of the PC being in a stack dummy when looking at a core file
+ without symbols. The other is the incorrect passing of char
+ arguments during expression evaluation (ie: p foo('a','b') would
+ mess up the passing of it's args because it wasn't coercing the
+ char's to ints).
+ * hppah-tdep.c: Rename global functions to have consistent hppa_
+ prefix. Make more functions static. Drop hp_ prefix from static
+ functions. (hppa_push_arguments): Call value_arg_coerce to cast
+ char to int args if necessary. (hppa_fix_call_dummy): Create
+ this routine from FIX_CALL_DUMMY macro in tm-hppa.h.
+ * inferior.h (PC_IN_CALL_DUMMY): Check for frame_address being
+ valid (ie: != 0) before doing comparison against PC.
+ * valops.c (call_function_by_hand): Adjust call to FIX_CALL_DUMMY
+ to reflect new arguments.
+ * config/pa/tm-hppa.h (POP_FRAME, PUSH_ARGUMENTS): Use new hppa_
+ prefix for func name. (FIX_CALL_DUMMY): Move code into
+ hppah-tdep.c.
+
+ * testsuite/gdb.t16/gdbme.c, testsuite/gdb.t17/gdbme.c: Add calls
+ to malloc() so that we can test GDB eval of dynamically created
+ arrays (like char strings in `print "foo"').
+
+Fri Apr 23 01:28:14 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * printcmd.c (print_address_symbolic): Search symtabs as well as the
+ minimal symbols for a nearby symbol.
+
+Thu Apr 22 19:44:21 1993 John Gilmore (gnu@cacophony.cygnus.com)
+
+ * coffread.c: Comment changes around minimal symbol recording.
+
+Thu Apr 22 16:24:36 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * command.c: comment changes only.
+
+ * mips-tdep.c (heuristic_fence_post): new static variable.
+ (heuristic_proc_start): use heuristic_fence_post, print better
+ warnings, but only if not stop_soon_quietly.
+ (_initialize_mips_tdep): add_set_cmd for heuristic-fence-post.
+
+Thu Apr 22 14:50:05 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * symtab.h: Fix LOC_REF_ARG comment.
+
+Wed Apr 22 20:21:30 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+ and Jim Kingdon (kingdon@cygnus.com)
+
+ * stabsread.c (define_symbol): Combine a 'p', 'r' arg pair to a
+ LOC_REGPARM symbol.
+ * config/sparc/tm-sparc.h (REG_STRUCT_HAS_ADDR): Revise comments.
+ symfile.c (compare_symbols): Don't check first character; STRCMP
+ does that.
+
+ * stabsread.c (define_symbol): Generate a LOC_REGPARM_ADDR for
+ structures that are passed by address in a register.
+ * symtab.h (enum address_class): Add LOC_REGPARM_ADDR.
+ * findvar.c (read_var_value),
+ printcmd.c (address_info, print_frame_args),
+ stack.c (print_frame_arg_vars), symmisc.c (print_{,partial_}symbol),
+ * symtab.c (lookup_block_symbol): Deal with it.
+
+Thu Apr 22 09:07:24 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * objfiles.h (obj_section), objfiles.c (build_objfile_section_table):
+ Add objfile field.
+ * objfiles.c (find_pc_section): Return a struct obj_section *.
+ * sparc-tdep.c (in_solib_trampoline): Deal with find_pc_section return.
+ * symfile.c (syms_from_objfile) [IBM6000_TARGET]:
+ Don't use obj_section hack.
+ * xcoffexec (vmap_symtab): Relocate obj_sections.
+ * printcmd.c (containing_function_bounds): Use find_pc_section.
+
+ * symtab.h: Clean up SYMBOL_VALUE comments.
+
+Wed Apr 21 14:29:57 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * stack.c (print_frame_arg_vars), printcmd.c (print_frame_args):
+ Expand comments about LOC_ARG/LOC_LOCAL pairs.
+
+ * coffread.c (read_coff_symtab): Use rewind before fseek.
+
+Wed Apr 21 14:24:19 1993 Per Bothner (bothner@cygnus.com)
+
+ * ch-exp.y: Removed unused structure_primitive_value and FIXME_23.
+ * Makefile.in: Add $(YFLAGS) when using $(YACC).
+ * Makefile.in: Remove message to expect conflicts and unused
+ rules in ch-exp.y, since there no longer are any such.
+
+Wed Apr 21 13:27:50 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * stabs.texinfo: fixed bad xrefs (un-initialized statics)
+
+Tue Apr 20 08:55:11 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * xcoffexec.c (xcoff_relocate_core): If no exec file, error()
+ rather than dumping core.
+
+ * Makefile.in: Add ${srcdir}/ to all source files.
+ (alldeps.mak): Add "${srcdir}/" to files when generating alldeps.mak.
+ (TAGS): Deal with srcdir and new config directory scheme.
+ createtags: Remove.
+ Makefile.in (NONSRC): Remove createtags.
+ alldeps.mak: Updated.
+
+ * rs6000-tdep.c: Delete unused function print_frame.
+
+ * frame.h (struct frame_info): Doc fix for next_frame.
+ New field signal_handler_caller.
+ blockframe.c (create_new_frame, get_prev_frame_info),
+ config/rs6000/tm-rs6000.h (INIT_EXTRA_FRAME_INFO): Set it (needs
+ INIT_FRAME_PC_FIRST).
+ stack.c (print_frame_info), rs6000-tdep.c (rs6000_frame_chain):
+ Check it.
+
+Mon Apr 19 22:52:33 1993 Stu Grossman (grossman@cygnus.com)
+
+ * irix4-nat.c (fetch_core_registers): Special version of this for
+ Irix 4.x, which stores regs a bit differently from other /proc
+ based systems.
+ * procfs.c, core-svr4.c: Move fetch_core_registers from procfs.c
+ to new file core-svr4.c.
+ * config/i386/i386sol2.mh, config/i386/i386v4.mh, config/m68k/amix.mh,
+ config/i386/ncr3000.mh, config/sparc/sun4sol2.mh: Add core-svr4.o
+ to NATDEPFILES.
+ * config/mips/irix4.mh: Add corelow.o to NATDEPFILES.
+
+Mon Apr 19 11:13:34 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * i387-tdep.c: Remove unused #includes.
+
+ * configure.in: Match i[34]86-*-sysv3.2 not i[34]86-*-sysv32.
+
+ * config/i386/nm-i386v.h: Define NO_PTRACE_H.
+
+Sun Apr 18 10:39:35 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * xcoffread.c: Nuke NO_DEFINE_SYMBOL code. There is no going back.
+
+ * stabsread.c (define_symbol): 'R' is synonym for 'P', not 'r'.
+ xcoffread.c (process_xcoff_symbol, case C_RPSYM):
+ Don't muck with SYMBOL_CLASS.
+
+Fri Apr 16 17:38:33 1993 Stu Grossman (grossman@cygnus.com)
+
+ * munch: Don't use head command. It doesn't exist everywhere.
+
+Fri Apr 16 15:07:57 1993 Fred Fish (fnf@cygnus.com)
+
+ * inflow.c (new_tty): Remove spurious 'o' character at end
+ of #endif line.
+
+Fri Apr 16 12:27:11 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mips-tdep.c (mips_skip_prologue): Always skip the typical prologue
+ instructions and nothing more.
+ * mipsread.c (add_line): Add comment why we have to combine line number
+ entries for the same line number.
+
+Fri Apr 16 09:42:03 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * symtab.{c,h}: Doc fixes (remove symseg references, last relevant
+ in gdb 2.8!).
+
+Thu Apr 15 21:16:58 1993 Fred Fish (fnf@cygnus.com)
+
+ * depend, alldeps.mak: Update, now that gcc -MM bug is fixed.
+
+Thu Apr 15 12:38:39 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * source.c (select_source_symtab): Clean up comment. Also, if
+ we have a current_source_symtab, and s is NULL, return without
+ doing anything.
+ xcoffread.c (xcoff_symfile_read): Don't call select_source_symtab.
+ breakpoint.c (breakpoint_re_set): Don't call select_source_symtab.
+
+Thu Apr 15 02:37:48 1993 John Gilmore (gnu@cacophony.cygnus.com)
+
+ * dbxread.c (unknown_symchar_complaint): Add new complaint.
+ * stabsread.h: Declare it.
+ * partial-stab.h: Use it.
+
+ * utils.c (malloc_botch): Don't forward-declare if NO_MMALLOC.
+
+Wed Apr 14 17:12:51 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * stack.c (print_frame_info): Print specially if dummy frame.
+
+ * breakpoint.c: Add comments regarding within_scope future direction.
+
+ * Version 4.8.3.
+
+ * xcoffread.c (record_include_{begin,end}): Change fatal to complain.
+
+Wed Apr 14 14:03:18 1993 Per Bothner (bothner@cygnus.com)
+
+ * ch-exp.y: Fix thinko that broke parsing of FALSE.
+
+Wed Apr 14 12:49:29 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * stabsread.c (read_member_functions): Initialize domain for stubbed
+ member functions to avoid gdb core dumps when printing pointers
+ to member functions.
+ * cp-valprint.c (cp_print_class_method): Check for stubbed member
+ functions.
+
+Tue Apr 13 08:28:26 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * expprint.c (print_subexp): If opcode not found in op_print_tab,
+ stop with an error().
+ eval.c (evaluate_subexp): Change error message.
+
+ * objfiles.c (build_objfile_section_table): Cast return value
+ from obstack_finish.
+
+Mon Apr 12 10:53:50 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * config/rs6000/tm-rs6000.h, rs6000-tdep.c: Move FRAME_CHAIN
+ to rs6000_frame_chain and deal with it if we're in a signal handler.
+ (FRAME_SAVED_PC): Use rs6000_frame_chain.
+
+ * breakpoint.c (within_scope): New function.
+ (enable_breakpoint, watchpoint_check): Use it.
+
+ * source.c (openp): Handle "exec-file ./ls" correctly.
+
+ * breakpoint.c (breakpoint_1): Use wrap_here before "at".
+
+Sat Apr 10 01:32:43 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * ch-exp.y: Clean up lexing of identifiers and
+ reserved words. (E.g. don't recognize FALSEXXX as the
+ keyword FALSE followed by the identifier XXX.)
+ Also, convert identifiers to lower case.
+
+Fri Apr 9 15:53:19 1993 Stu Grossman (grossman@cygnus.com)
+
+ * remote-mips.c, remote-monitor.c, remote-st2000.c: Convert to
+ new serial interface.
+
+Fri Apr 9 15:01:12 1993 Stu Grossman (grossman@cygnus.com)
+
+ * remote.c (remote_open): Use SERIAL_OPEN instead of serial_open.
+ (putpkt, getpkt): Use new return codes for SERIAL_READCHAR.
+ * ser-go32.c: Return -1 on most failures, 0 on most successes,
+ and use new return codes for go32_readchar().
+ * ser-unix.c: Ditto. Also, move error handling up to caller for
+ SERIAL_SETBAUDRATE().
+ * serial.c (serial_open): Internal call, not SERIAL_OPEN to get
+ to specific routine.
+ (serial_close): New routine to wrap around device close routine.
+ serial.h: Clean & document return values more clearly.
+
+Fri Apr 9 10:20:55 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * rs6000-pinsn.c (print_operand): Deal with no operand instructions.
+
+ * rs6000-pinsn.c (print_operand, case LI): Print condition register
+ operand in decimal rather than wrong textual versions.
+
+ * printcmd.c (_initialize_printcmd): Clean up docstring for "x"
+ (mention 't', remove false thing about 'g' only good with 'f').
+
+ * breakpoint.h: move "struct breakpoint" and friends to top of
+ file so that bpstat_find_breakpoint prototype works.
+
+ * solib.c (struct so_list): Add bfd field.
+ (solib_map_sections): Leave bfd open and scratch_pathname allocated.
+ Put the bfd in bfd field of the so_list.
+ (clear_solib): Free bfd name and close_bfd on the bfd.
+
+Fri Apr 9 00:45:41 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * valarith.c (value_subscript): Add COERCE_REF.
+ * ch-exp.y (operand_5): We can generalize the 2nd operand
+ of a string repetition ot 'literal' without ambiguity.
+
+Thu Apr 8 10:15:10 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.h (struct bpstat): Remove momentary field.
+ Remove bpstat_momentary_breakpoint. This was always kludgy
+ and is no longer used.
+
+ * breakpoint.h: Add enum bpstat_what.
+ breakpoint.h (struct bpstat), breakpoint.c (bpstat_stop_status):
+ stop and print fields of bpstat now per-breakpoint, not just
+ one for the whole chain.
+ breakpoint.{c,h} (bpstat_what): New function.
+ breakpoint.h: Remove bpstat_stop and bpstat_should_print.
+ infrun.c: Replace switch (stop_bpstat->breakpoint_at->type)
+ with call to bpstat_what.
+ README: Remove watchpoint/breakpoint bug from known bugs.
+
+ * breakpoint.h: Prototype bpstat_find_breakpoint.
+
+Thu Apr 8 16:01:21 1993 Fred Fish (fnf@cygnus.com)
+
+ * symtab.c (find_methods, gdb_mangle_name): Note that functions
+ are g++ specific.
+ * symtab.h (VTBL_FNADDR_OFFSET, OPNAME_PREFIX_P, VTBL_PREFIX_P,
+ DESTRUCTOR_PREFIX_P): Note that macros are g++ specific.
+
+Thu Apr 8 12:45:32 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * i960-pinsn.c (tabent): Copied struct definition from
+ opcodes/i960-dis.c.
+
+Thu Apr 8 10:34:37 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * symtab.h (DESTRUCTOR_PREFIX_P): New macro to check if physname
+ is a C++ destructor.
+ * symtab.c (gdb_mangle_name): Use it.
+ * symtab.c (find_methods): Do not add destructors to choice list
+ for constructors.
+ * symtab.c (decode_line_1): Make breakpoints on destructors work
+ for gcc-2.x again.
+
+Wed Apr 7 18:43:09 1993 Stu Grossman (grossman@cygnus.com)
+
+ * ser-go32.c: Make it use serial port name.
+ * go32-xdep.c: Put in def for strlwr, needed by dir.o in go32 libc.
+
+ * infcmd.c (read_pc): Make sure that we read PC_REGNUM when not
+ in a system call!
+
+Wed Apr 7 15:52:11 1993 Stu Grossman (grossman@cygnus.com)
+
+ * configure.in: Only configure sparclite subdir when target_cpu
+ is sparclite.
+
+Wed Apr 7 10:11:22 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * xcoffread.c (struct coff_symbol): Change c_sclass to unsigned char.
+ Remove FIXME comment regarding this.
+
+ * symfile.h: Change NULL->'\0' in comment (that wasn't a typo).
+
+ * xcoffread.c (read_xcoff_symtab): Use E_SYMNMLEN.
+
+Tue Apr 6 22:30:58 1993 K. Richard Pixley (rich@cygnus.com)
+
+ Add section table to objfile struct. Use it for find_pc_section.
+ * objfiles.c (add_to_objfile_sections,
+ build_objfile_section_table, find_pc_section): new functions.
+ (allocate_objfile): build section table.
+ * objfiles.h (struct obj_section): new structure.
+ (struct objfile): add section table.
+ (find_pc_section): new prototype.
+ * solib.[ch] (find_pc_section_from_so_list): removed.
+ * sparc-tdep.c: include objfiles.h for find_pc_section. include
+ symfile.h for objfiles.h.
+ (in_solib_trampoline): adjusted for new find_pc_section
+ prototype. Removed BAD_RICH_HACK ifdefs.
+ * symfile.c (syms_from_objfile): offset objfile sections.
+ (find_pc_section): removed. Also removed BAD_RICH_HACK ifdefs.
+ * symfile.h (find_pc_section): prototype removed. Also fixed
+ comment typo NUL -> NULL.
+ * target.[ch] (find_pc_section_from_targets): removed.
+ * config/sparc/tm-sun4sol2.h (BAD_RICHH_HACK): removed.
+
+Tue Apr 6 21:41:13 1993 Stu Grossman (grossman@cygnus.com)
+
+ * ser-go32.c: Format. (go32_open): Use proper return value.
+
+ * configure.in: Undo conditional configdirs hack for sparclite.
+
+Tue Apr 6 17:07:37 1993 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * symtab.c (list_symbols): When call break_command, pass both
+ filename and function name not just function name.
+
+Tue Apr 6 15:00:09 1993 Fred Fish (fnf@cygnus.com)
+
+ (Changes and new files to make "none" a full fledged configuration)
+ * config/none/{nm-none.h, tm-none.h, xm-none.h}: New files.
+ Currently only tm-none.h has any meaningful contents.
+ * config/none/none.mh (NAT_FILE): Use nm-none.h
+ * config/none/none.mh (XM_FILE): Use xm-none.h
+ * config/none/none.mt (TM_FILE): Use tm-none.h
+ * Makefile.in (depend): Remove comment about parse errors in
+ valops.c, it now parses correctly and generates a correct depend
+ line. Remove line that touches xm.h, tm.h, and nm.h; they are
+ now linked to config/none/{xm-none.h, tm-none.h, nm-none.h}.
+
+Tue Apr 6 09:54:29 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * values.c (USE_STRUCT_RETURN): Only use gcc wierdness for gcc1.
+
+ * xcoffread.c (read_xcoff_symtab): Deal correctly with symbols of
+ exactly 8 characters.
+
+Tue Apr 6 10:31:26 1993 Stu Grossman (grossman@cygnus.com)
+
+ * configure.in: Sparclite uses sparc config dir. Also has it's
+ own tm- & .mt files now. Also add sparclite to configdirs.
+ * go32-xdep.c: Dummy routines for sigsetmask & strlwr.
+ * config/i386/go32.mh: Nullify def of TERMCAP.
+ * config/i386/xm-go32.h: Get rid of redef of EIO.
+ * config/sparc/{sparclite.mh tm-sparclite.h}: New sparclite
+ specific configs. Very similar to sun4os4, but without solib.
+ * sparclite/{Makefile.in configure.in}: First cut at making this
+ dir configgable.
+
+Tue Apr 6 03:10:44 1993 Stu Grossman (grossman@cygnus.com)
+
+ * ser-go32.c: First cut at adapting to new serial interface.
+
+Mon Apr 5 22:29:43 1993 Stu Grossman (grossman@cygnus.com)
+
+ * Makefile.in (SFILES OBS): Add serial.[co] & ser-hardwire.[co].
+ These implement a new serial line interface for talking to remote
+ targets.
+ * configure.in: Link ser-hardwire.c to ser-unix.c for all hosts,
+ EXCEPT go32, which gets ser-go32.c.
+ * remote.c: Use new serial interface. More remote-xxx's to be
+ converted later.
+ * ser-bsd.c, ser-termios.c: Removed.
+ * serial.c: New. Implements common operations for all serial
+ types.
+ * ser-unix.c: New. Unix specific serial operations for various
+ flavors of Unix (Posix, SysV, BSD).
+ * serial.h: Generic serial interface defs.
+ * config/i386/go32.mh, config/i386/i386bsd.h,
+ config/m68k/apollo68b.mh, config/sparc/sun4os4.mh: Remove
+ ser-bsd.o from XDEPFILES. All the magic is now handled in
+ configure.in.
+
+Mon Apr 5 20:48:54 1993 Stu Grossman (grossman@cygnus.com)
+
+ * config/h8500/tm-h8500.h: Clean up brain damage found by GCC.
+
+Fri Apr 2 08:23:14 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * xcoffread.c (xcoff_symfile_offsets): Use 0 not addr for offsets.
+
+ * rs6000-tdep.c (frameless_function_invocation): Don't even think
+ about framelessness except on the innermost frame.
+
+ * xcoffexec.c: Call fatal() not abort().
+
+ * stabsread.c (patch_block_stabs): If stab & no symbol, make
+ a LOC_OPTIMIZED_OUT symbol.
+ symtab.h (enum address_class): Add LOC_OPTIMIZED_OUT.
+ findvar.c (read_var_value), printcmd.c (address_info),
+ symmisc.c (print_{,partial_}symbol), c-exp.y (variable),
+ m2-exp.y (yylex): Deal with it.
+ ch-exp.y (yylex): Deal with it.
+
+Thu Apr 1 18:43:02 1993 Stu Grossman (grossman@cygnus.com)
+
+ * findvar.c (value_from_register): H8500 specific, check to see
+ if we are looking at short pointer. If so, skip crock.
+ * h8500-tdep.c (h8500_frame_chain): Mask down value from
+ read_memory_integer() to avoid getting messed up by sign extension.
+
+Thu Apr 1 16:44:41 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * sparc-tdep.c (in_solib_trampoline), symfile.c (find_pc_section):
+ ifdef protect using BAD_RICH_HACK. This should be removed soon.
+ * config/sparc/tm-sun4sol2.h (BAD_RICH_HACK): define.
+
+Thu Apr 1 09:01:38 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * i960-pinsn.c, a29k-pinsn.c: Much abridged, just use libopcodes.a.
+
+ * core.c (dis_asm_print_address): New function.
+
+ * core.c (dis_asm_read_memory): Reinstate 4th arg. The prototype
+ has been fixed.
+
+Thu Apr 1 09:34:43 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * breakpoint.c (bpstat_print, bpstat_stop_status): Change to walk the
+ entire breakpoint chain and print only the first entry that needs to
+ be printed and needs to be stopped for. Fixes problems with printing
+ of multiple breakpoints with different conditions.
+ * breakpoint.c (print_it_done): Renamed from print_it_noop as it
+ effectively stops printing of the breakpoint chain.
+ * breakpoint.c (print_it_noop): New routine to print nothing
+ for this breakpoint entry and dont stop printing.
+ * breakpoint.c (breakpoint_re_set_one): mention the reevaluated
+ watchpoint only if it is enabled.
+ * mipsread.c (parse_procedure): Correct incorrect setjmp procedure
+ descriptor from the library to make backtraces through setjmp work.
+ * mipsread.c (fixup_sigtramp): Correct pcreg and fregoffset for
+ sigtramp.
+ * mips-tdep.c (read_next_frame_reg): Provide correct values for
+ all registers saved within sigtramp, cleanup.
+
+Wed Mar 31 12:52:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * sparc-pinsn.c: Much abridged, just calls version in libopcodes.a.
+
+Wed Mar 31 21:23:41 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * core.c (dis_asm_read_memory): drop fourth arg which conflicts
+ with prototype in ../include/dis-asm.h.
+
+Wed Mar 31 12:52:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * core.c (dis_asm_{read_memory,memory_error}): New functions.
+ m68k-pinsn.c, h8500-tdep.c, i386-pinsn.c, mips-pinsn.c, z8k-tdep.c:
+ Use read_memory_func interface to disassembler.
+
+Tue Mar 30 15:46:14 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ Teach sparc solaris to next over shared library functions.
+ * solib.[hc] (find_pc_section_from_so_list): new function and
+ prototype.
+ * sparc-tdep.c (in_solib_trampoline): new function.
+ * symfile.[hc] (find_pc_section): new function and prototypes.
+ * target.[hc] (find_pc_section_from_targets): new function and
+ prototypes.
+ * config/sparc/tm-sun4sol2.h (IN_SOLIB_TRAMPOLINE): redefine to
+ in_solib_trampoline.
+
+Tue Mar 30 08:06:24 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * infrun.c (wait_for_inferior): Revise comment.
+
+ * command.c (do_setshow_command): Use %u with var_{u,z}integer.
+
+ * command.{c,h}: New var_type var_integer.
+ main.c: Use it for history_size.
+
+ * rs6000-tdep.c, xcoffexec.c, config/rs6000/xm-rs6000.h, breakpoint.c:
+ Lint and byte-order fixups.
+
+ * breakpoint.c (print_it_normal): Return 0 after hitting watchpoint.
+
+ * breakpoint.h (bpstat): New field print_it.
+ breakpoint.c (bpstat_print): Use it.
+ (print_it_normal): New function (from old bpstat_print code).
+ (bpstat_{alloc,stop_status}): Set print_it field.
+
+ * breakpoint.c (bpstat_stop_status): Use catch_errors when
+ evaluating watchpoint condition, via new function watchpoint_check.
+ Also stop if watchpoint disabled due to leaving its block.
+
+ * findvar.c [REG_STRUCT_HAS_ADDR]: Add comment.
+
+Tue Mar 30 00:14:38 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mips-pinsn.c: Add missing include of dis-asm.h.
+
+Mon Mar 29 15:03:25 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (clean, distclean, realclean): Recursively apply
+ to subdirs first, rather than last. This avoids, for example,
+ Makefile being removed in a parent directory before the recursive
+ make is run.
+
+ * alldeps.mak, depend: Update for below changes.
+
+ * config/m68k/tm-m68k.h: Renamed from config/m68k/tm-68k.h.
+ * m68k/{tm-3b1.h, tm-altos.h, tm-amix.h, tm-es1800.h,
+ tm-hp300bsd.h, tm-hp300hpux.h, tm-isi.h, tm-news.h, tm-os68k.h,
+ tm-st2000.h, tm-sun2.h, tm-sun3.h, tm-vx68.h}: Include tm-m68k.h
+ instead of tm-68k.h.
+ * Makefile.in (HFILES): tm-68k.h renamed to tm-m68k.h.
+ * README, a29k-pinsn.c, m68k-pinsn.c, m68k-stub.c, remote-vx.c,
+ m68k/{altos.mh, altos.mt, apollo68b.mh, nm-apollo68b.h,
+ nm-hp300bsd.h, config/m68k/xm-apollo68b.h}: Map '68k' to 'm68k'.
+ * a29k/tm-a29k.h, doc/gdbint.texinfo: Account for renaming of
+ tm-68k.h to tm-m68k.h.
+ * m68k/m68k-fp.mt (TM_FILE): tm-68k-fp.h renamed to tm-m68k-fp.h.
+ * m68k/m68k-nofp.mt (TM_FILE): tm-68k-nofp.h renamed to
+ tm-m68k-nofp.h.
+
+ * config/a29k/tm-a29k.h: Renamed from config/a29k/tm-29k.h.
+ * a29k-pinsn.c: Renamed from am29k-pinsn.c.
+ * a29k-tdep.c: Renamed from am29k-tdep.c.
+ * remote-eb.c, config/a29k/tm-ultra3.h: Include renamed tm-a29k.h.
+ * remote-monitor.c, remote-st2000.c, config/a29k/{nm-ultra3.h,
+ tm-a29k.h, xm-ultra3.h}, config/romp/rtbsd.mh, doc/gdbinv-s.texi,
+ testsuite/gdb.t15/funcargs.exp, testsuite/gdb.t17/callfuncs.exp:
+ Map '29k' to 'a29k'.
+ * config/a29k/{a29k-kern.mt, a29k-udi.mt, a29k.mt, ultra3.mt}
+ (TDEPFILES): Use renamed a29k-pinsn.o and a29k-tdep.o.
+ * config/a29k/{a29k-udi.mt, a29k.mt} (TM_FILE): Use renamed
+ tm-a29k.h.
+ * config/a29k/a29k-udi.mt (MT_CFLAGS): Remove TARGET_AM29K
+ define that does not appear anywhere else in the gdb source tree.
+ * doc/gdbinit.texinfo: Document renaming of tm-29k.h to tm-a29k.h.
+
+Mon Mar 29 13:55:29 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * breakpoint.c: Add comments regarding breakpoint_re_set.
+
+ * xcoffread.c (sort_syms, compare_symbols): Remove.
+ (xcoff_symfile_read): Use sort_all_symtab_syms from symfile.c
+ not our own sort_syms (it is identical).
+
+ * xcoffread.c: Nuke NAMES_HAVE_DOT define (not used).
+
+Sun Mar 28 11:24:37 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * breakpoint.c (breakpoint_re_set_one): Fix storage leak.
+ * breakpoint.c (enable_breakpoint): Don't enable watchpoint if it
+ went out of scope.
+ * exec.c (exec_close): Fix storage leak.
+ * exec.c (exec_file_command): Make sure that bfd doesn't realign the
+ output sections when patching an executable.
+ * mips-nat.c (store_inferior_registers): Use REGISTER_PTRACE_ADDR
+ when writing all registers.
+ * mips-tdep.c (mips_push_dummy_frame): Save floating point registers
+ at the right offset in the dummy frame.
+ * mipsread.c (psymtab_to_symtab_1): Do not complain for stProc,
+ stStaticProc and stEnd symbols as they are generated by gcc-2.x.
+ * mipsread.c (mipscoff_new_init): Initialize stabsread and buildsym.
+
+Fri Mar 26 15:25:05 1993 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (TARFILES): Avoid trailing backslash.
+
+Fri Mar 26 11:29:30 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * breakpoint.{c,h}: Add exp_string to struct breakpoint and use
+ it in breakpoint_re_set.
+ * breakpoint.c (watch_command, enable_breakpoint): Fetch lazy values.
+
+ * rs6000-tdep.c (single_step): Misc cleanups (CORE_ADDR not int,
+ don't use sizeof(int) for target stuff, etc).
+
+Thu Mar 25 15:03:53 1993 Fred Fish (fnf@cygnus.com)
+
+ * alldeps.mak, configure.in, i860-break.h, i860-opcode.h,
+ i860-pinsn.c, i860-tdep.c, config/i860/*: Remove incomplete i860
+ support that can't be integrated anyway due to lack of clear
+ authorship.
+
+Thu Mar 25 12:26:50 1993 Stu Grossman (grossman@cygnus.com)
+
+ * findvar.c (read_register, write_register): Make these capable
+ of reading/writing registers that are shorter than REGISTER_TYPE.
+ * (value_from_register): Install H8500 specific code to return
+ proper value when register is being used as a pointer.
+ * h8500-tdep.c: Remove extra defines of NUM_REGS.
+ (h8500_skip_prologue): Use correct lengths for LINK instructions.
+ (FRAME_CHAIN): Change name to h8500_frame_chain. Rewrite code to
+ chain frames properly by combining frame pointer with T reg.
+ (init_extra_frame_info): Delete. It's now a macro.
+ (frame_args_address): Don't add PTR_SIZE. Stack args are already
+ offset by the correct amount off of the frame pointer.
+ (register_byte): Delete. It's now a macro.
+ (register_raw_size, register_virtual_size): Delete. Replaced by
+ common routine h8500_register_size, cuz there's no difference
+ between the raw & virtual sizes on this machine.
+ (register_convert_to_raw, register_convert_to_virtual): Delete,
+ cuz there's no difference between the raw & virtual forms.
+ Replaced by memcpy in tm file.
+ (register_virtual_type): Rename to h8500_register_virtual_type.
+ Get rid of pointer pseudo-regs, use _REGNUM with all reg names.
+ (_initialize_h8500_tdep): Get rid of crock to ensure that GDB &
+ emulator have same reg offsets. This is all handled in the
+ simulator code now.
+ (h8500_trapped_internalvar): New routine to detect references to
+ convenience vars acting as pointer pseudo-regs.
+ (h8500_value_trapped_internalvar): Conjure up value of pointer
+ pseudo-regs.
+ (h8500_set_trapped_internalvar): Convert set value in real
+ register references.
+ infcmd.c (read_pc, write_pc): Add h8500 specific code to handle
+ code segment register.
+ infrun.c (proceed): Simplify. Call write_pc instead of doing it
+ by hand.
+ (wait_for_inferior): Add h8500 specific code to add stack segment
+ when reading SP register.
+ remote-sim.c (fetch_register): Spacing.
+ tm-h8500.h: #define GDB_TARGET_IS_H8500 to make it easier to
+ detect cruft. Redo all register manipulation stuff. Get rid of
+ pointer pseudo-regs. (INIT_EXTRA_FRAME_INFO): Adds stack segment
+ to frame pointer. (IS_TRAPPED_INTERNALVAL,
+ VALUE_OF_TRAPPED_INTERNALVAR, SET_TRAPPED_INTERNALVAR): Use these
+ to create internal vars for pointer pseudo-regs.
+
+Thu Mar 25 10:10:28 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in: Numerous small changes to macro definitions
+ and rules for building gdb distribution tree. Many macros
+ eliminated or merged, and rules simplified.
+ * alldeps.mak: Update.
+ * depend: Update.
+
+Wed Mar 24 13:52:29 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com)
+
+ * Makefile.in: recurse through SUBDIRS for dvi target too
+
+Wed Mar 24 08:48:30 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Clean up xcoff relocation.
+ objfiles.h (struct objfiles): Add section_offsets, num_sections.
+ symfile.c (syms_from_objfile), xcoffread.c (xcoff_symfile_offsets):
+ Set them.
+ symtab.h (struct general_symbol_info): Add section field.
+ minsyms.c (prim_record_minimal_symbol{,_and_info}): Set it.
+ xcoffread.c: Set section for symbols and msymbols.
+ (struct symtab): Add block_line_section field.
+ buildsym.c (end_symtab): Set it.
+ (end_symtab and callers): Add section parameter.
+ objfiles.c (objfile_relocate): New funciton.
+ xcoffexec.c (vmap_symtab): Use it.
+ xcoffsolib.h (struct vmap): Remove unused fields.
+ config/rs6000/tm-rs6000.h, stack.c, xcoffexec.c: Remove
+ CORE_NEEDS_RELOCATION, symtab_relocated.
+ config/rs6000/tm-rs6000.h: Remove use of loadinfotext.
+ rs6000-tdep.c: Make loadinfotext static.
+ breakpoint.c (fixup_breakpoints): Doc fix.
+ symtab.h (struct symtab), config/rs6000/tm-rs6000.h, buildsym.c
+ (end_symtab): primary field replaces nonreloc.
+
+Tue Mar 23 00:10:53 1993 John Gilmore (gnu@cygnus.com)
+
+ * symtab.h (struct linetable_entry): Remove confusing comment.
+
+Tue Mar 23 00:01:23 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: add installcheck target
+
+Mon Mar 22 16:17:58 1993 Fred Fish (fnf@cygnus.com)
+
+ * config/{a29k, arm, convex, gould, h8300, i386, i860, i960, m68k,
+ m88k, mips, none, ns32k, pa, pyr, romp, rs6000, sparc, tahoe, vax,
+ z8k}: New directories to hold cpu specific configuration files.
+ Naming follows gcc convention.
+ * config/{*.mt, *.mh}: All target and host makefile fragment
+ config files moved to an appropriate config/<cpu> subdirectory.
+ * nm-*, xm-*, tm-*: All native, host, and target files, which
+ get linked to nm.h, xm.h, and tm.h respectively by configure,
+ moved to appropriate config/<cpu> subdirectory.
+ * nm-sysv4.h, xm-sysv4.h, tm-sysv4.h, tm-sunos.h, nm-trash.h:
+ Native, host, and target files that are common across more than
+ one cpu architecture and included by one of the configured
+ native, host, or target files, get moved to config directory.
+ * Makefile.in (INCLUDE_CFLAGS): Add -I${srcdir}/config to
+ pick up native, host, or target include files moved to one of
+ the config subdirectories, and that are included by other files.
+ * Makefile.in (alldeps.mak): Modify to account for new config
+ directory structure.
+ * alldeps.mak, depend: Update for new config directory structure.
+ * config/*/[ntx]m-*.h: Modify all files that include other
+ [ntx]m-*.h files to use path relative to gdb/config. I.E.
+ "a29k/tm-ultra3.h" includes "a29k/tm-29k.h" rather than just
+ "tm-29k.h".
+ * remote-eb.c (tm-29k.h): Include a29k/tm-29k.h.
+ * mipsread.c (tm-mips.h): Include mips/tm-mips.h.
+ * i860-pinsn.c (tm-i860.h): Include i860/tm-i860.h.
+ * configure.in: Default gdb_host_cpu to host_cpu, and remap
+ the ones where the default is not unique or different than the
+ config subdirectory name. Similarly, handle gdb_target_cpu.
+ Modify configure.in as appropriate to make use of gdb_host_cpu
+ and gdb_target_cpu to find makefile fragments and make links.
+
+Mon Mar 22 12:36:24 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mipsread.c (compare_blocks): Sort blocks with the same start
+ address by decreasing ending address.
+
+Mon Mar 22 20:36:04 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mipsread.c (parse_procedure): Save cur_fdr accross call to
+ lookup_symbol as it might get clobbered by the call.
+
+ * mipsread.c (parse_partial_symbols): Use ADD_PSYMBOL_ADDR_TO_LIST.
+ The previous code did not initialize the language field for the psymtab
+ entry.
+
+Sat Mar 20 00:33:39 1993 John Gilmore (gnu@cygnus.com)
+
+ * c-exp.y (parse_number): Avoid shift warning.
+ * serial.h (struct ttystate): Declare empty one on DOS.
+
+Fri Mar 19 12:59:50 1993 Stu Grossman (grossman@cygnus.com)
+
+ * xm-sun4os4.h: Return type of free() should be void, not int.
+
+ * vx-share/vxWorks.h: Remove #def of NULL.
+
+Fri Mar 19 11:28:18 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * tm-rs6000.h: Nuke no-op STAB_REG_TO_REGNUM.
+
+Fri Mar 19 07:40:09 1993 Steve Chamberlain (sac@cygnus.com)
+
+ * z8k-tdep.c (print_insn): Include the new dis-asm header file.
+
+Thu Mar 18 14:26:57 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * ieee-float.c: Moved to ../libiberty.
+ * ieee-float.h: Moved to ../include.
+ * Makefile.in: Update accordingly.
+ * i386-pinsn.c (print_insn), m68k-pinsn.c (print_insn):
+ Convert to stubs that call disassemblers in ../opcodes/*-dis.c.
+ * m68k-tdep.c: Removed definition of ext_format ext_format_68881;
+ it is now in ../opcodes/m68881-ext.c.
+ * mips-tdep.c (mips_skip_prologue): Try to skip more of the
+ prologue (some callers _do_ care).
+ * mips-pinsn.c (print_insn), z8k-tdep.c (print_insn): Convert to
+ new interface of ../opcodes/*-dis.c.
+ * ch-exp.y: Add #include <ctype.h>.
+
+Thu Mar 18 11:57:49 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * xcoffexec.c (exec_close): Don't close exec_bfd twice.
+
+ * xcoffread.c (enter_line_range): endaddr is exclusive, not inclusive.
+
+Wed Mar 17 09:46:31 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * xcoffread.c (arrange_linetable): Use x{m,re}alloc not {m,re}alloc.
+
+Wed Mar 17 11:28:11 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * z8k-tdep.c (extract_return_value, write_return_value,
+ store_struct_return): New functions from macros in tm-z8k.h.
+
+Wed Mar 17 11:23:06 1993 Fred Fish (fnf@cygnus.com)
+
+ * valops.c (value_arg_coerce): Apply temporary patch to
+ fix problem with coercion of array and function types when
+ passed as arguments to C functions, pending a more complete
+ review of when and how coercion should be done, depending
+ upon context and language.
+
+Wed Mar 17 09:46:31 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * xcoffread.c (MIN_TBTABSIZ): Change to 12.
+
+ * xcoffread.c (xcoff_symfile_read): Only read stringtab and
+ debugsec if there are a non-zero number of symbols.
+
+Tue Mar 16 18:08:45 1993 John Gilmore (gnu@cygnus.com)
+
+ * command.c (show_user): Avoid fprintf_filtered botch (AGAIN!).
+
+Tue Mar 16 15:18:17 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * xcoffexec.c (add_vmap): Wrap symbol read in catch_errors.
+
+ * xcoffread.c (read_symbol_lineno): Look to end of symbols for .bf,
+ not just 50 symbols.
+ (symtbl_num_syms): New variable.
+ (read_xcoff_symtab): Set it.
+ (read_symbol_nvalue): Check for bad symno.
+ (read_symbol_{lineno,nvalue}, callers): Don't pass symtable; it's
+ always symtbl.
+
+Tue Mar 16 10:09:05 1993 Stu Grossman (grossman@cygnus.com)
+
+ * config/rs6000.mh: Get rid of -Dfd_set=int crock.
+ This is defined in defs.h if necessary.
+ * vx-share/vxWorks.h: Remove #defs of min and max.
+ * vx-share/xdr_ld.c, vx-share/xdr_ptrace.c,
+ vx-share/xdr_rdb.c: include defs.h.
+
+Fri Mar 12 09:33:23 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * xcoffread.c (retrieve_tracebackinfo): Move assignment out
+ of while condition.
+
+ * xcoffread.c (enter_line_range): complain() on bad endoffset.
+ xcoffread.c: Doc fixes.
+
+Tue Mar 9 09:56:12 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * tm-rs6000.h (CORE_NEEDS_RELOCATION): Just call xcoff_relocate_core.
+ xcoffexec.c (xcoff_relocate_core): New function.
+ (text_adjustment): Removed.
+ (add_vmap): Return the vmap.
+ rs6000-tdep.c (add_text_to_loadinfo): No longer static.
+
+Fri Mar 5 05:22:46 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * xcoffsolib.h: Add objfile member to struct vmap.
+ xcoff{exec,solib}.c: Use it, not lookup_objfile_bfd.
+ xcoffexec.c (add_vmap): Allocate objfiles here.
+
+Sun Mar 14 02:54:15 1993 John Gilmore (gnu@cygnus.com)
+
+ Support 68000 series without floating point.
+
+ * configure.in (m68000-*-{aout,elf,coff}): New configs.
+ * tm-68k-nofp.h: New file, lacks 68881 support.
+ * config/m68k-nofp.mt: New file.
+
+Sun Mar 14 02:30:08 1993 John Gilmore (gnu@cygnus.com)
+
+ Remove a few remaining underscore/no-underscore remnants from
+ config files.
+
+ * config/{m68k-un.mt, sparc-un.mt}: Remove.
+ * config/m68k-noun.mt: Rename to m68k-fp.mt.
+ * config/sparc-noun.mt: Rename to sparc-em.mt.
+ * tm-68k-noun.h, tm-spc-noun.h: Remove.
+ * tm-68k-un.h: Rename to tm-68k-fp.h.
+ * tm-spc-un.h: Rename to tm-spc-em.h.
+ * tm-sun4sol2.h: Cleanup.
+ * configure.in (m68k-*, sparc-* targets): Corresponding changes.
+
+Sat Mar 13 14:58:22 1993 John Gilmore (gnu@cygnus.com)
+
+ * symmisc.c (std_in, std_out, std_err): Move initializations
+ to runtime code, in case they aren't constant.
+
+Fri Mar 12 16:23:54 1993 K. Richard Pixley (rich@cygnus.com)
+
+ * symtab.c (find_pc_symtab): some object file formats, notably
+ mips, have holes in the address ranges of symtabs. Change
+ this algorithm from first hit to tightest fit.
+
+ * mips-tdep.c (heuristic_proc_start): if we walk the pc into the
+ fence post without finding the enclosing function, then print a
+ warning.
+
+Thu Mar 11 09:33:01 1993 Fred Fish (fnf@cygnus.com)
+
+ * utils.c (fputs_demangled, fprint_symbol): Remove.
+ * utils.c (fprintf_symbol_filtered): New function which combines
+ the functionality of fputs_demangled and fprint_symbol. Uses a
+ caller provided language parameter to select the appropriate
+ demangler, and caller provided args to pass to the demangler.
+ * defs.h (enum language): Move further up in file so enum can
+ be used in prototypes.
+ * defs.h (fputs_demangled, fprint_symbol): Remove prototypes.
+ * defs.h (fprintf_symbol_filtered): Add prototype.
+ * c-typeprint.c (cp_type_print_method_args): Replace calls to
+ fputs_demangled with call to fprintf_symbol_filtered.
+ * cp-valprint.c (demangle.h): Include
+ * cp-valprint.c (cp_print_value_fields): Replace calls to
+ fprint_symbol with calls to fprintf_symbol_filtered.
+ * printcmd.c (print_frame_args): Replace call to fprint_symbol
+ with call to fprintf_symbol_filtered.
+ * stack.c (print_frame_info): Remove obsolete code so we don't
+ have to update fputs_demangled usage in it.
+ * stack.c (print_frame_info, frame_info): Add language variable
+ to pass to fprintf_symbol_demangled and initialize it from the
+ symbol's language. Replace calls to fputs_demangled with calls
+ to fprintf_symbol_filtered.
+ * symtab.c (find_methods): Replace call to fputs_demangled with
+ call to fprintf_symbol_filtered.
+ * ch-valprint.c (demangle.h): Include.
+ * ch-valprint.c (chill_print_value_fields): Replace call to
+ fprint_symbol with call to new fprintf_symbol_filtered.
+
+Wed Mar 10 17:37:11 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump version to 4.8.2.
+
+ * main.c (source_command): Require an explicit pathname of file
+ to source, since previous behavior of defaulting to gdb init file
+ was troublesome and undocumented.
+ * printcmd.c (disassemble_command): Add missing '{}' pair to
+ else with two statements. Bug reported by Stephane Tsacas
+ <slt@isoft.fr>.
+ * symtab.c (find_pc_line): Don't complain about zero length or
+ negative length line numbers for the moment, since we may not own
+ the terminal when called, such as when single stepping. (FIXME)
+ * language.h (CAST_IS_CONVERSION): True if current language is
+ C++ as well as C. Fix from Peter Schauer.
+ * environ.c (get_in_environ, set_in_environ, unset_in_environ):
+ Use STREQN macro rather than bare '!strncmp()'.
+ * environ.c (unset_in_environ): Avoid use of memcpy on
+ overlapping memory regions, as suggested by Paul Eggert
+ <eggert@twinsun.com>.
+ * c-exp.y (%union struct): Remove unused ulval as suggested
+ by Paul Eggert <eggert@twinsun.com>.
+
+Mon Mar 8 19:03:06 1993 Fred Fish (fnf@cygnus.com)
+
+ * main.c (gdbinit): Make static.
+ * main.c (inhibit_gdbinit): Move to file scope.
+ * main.c (main): Remove local inhibit_gdbinit.
+ * main.c (source_command): Don't source '.gdbinit' file by
+ default if gdb has been told to ignore it.
+
+Sun Mar 7 21:58:53 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (MAKEOVERRIDES): Define to be empty for GNU Make
+ 3.63.
+
+Fri Mar 5 17:39:45 1993 John Gilmore (gnu@cacophony.cygnus.com)
+
+ * printcmd.c (print_address_symbolic): Only print if offset
+ is shorter than max_symbolic_offset.
+ (initialize_printcmd): `set print max-symbolic-offset'.
+
+ * am29k-tdep.c (TAGWORD_ZERO_MASK): New #define.
+ (examine_tag): Use it.
+ (read_register_stack): Only look in the local registers for a
+ memory address if it's between rfb and rsp; go to memory otherwise.
+ (initialize_29k): Fix call_scratch_address doc. Remove reginv_com.
+ (reginv_com): Remove ancient kludge command.
+
+Fri Mar 5 17:16:26 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * tm-irix3.h (ZERO_REGNUM): copy this macro from tm-mips.h so that
+ irix4 will again compile.
+
+ * tm-mips.h (GDB_TARGET_IS_MIPS): no longer used, now removed.
+
+ * configure.in: accept mips-sgi-irix4* for irix4.
+
+Fri Mar 5 07:49:48 1993 Steve Chamberlain (sac@lisa.cygnus.com)
+
+ * z8k-tdep.c (print_register_hook): Lint.
+
+Thu Mar 4 17:42:03 1993 John Gilmore (gnu@cygnus.com)
+
+ Lint fixes from Paul Eggert (eggert@twinsun.com):
+
+ * command.c (do_setshow_command): var_uintegers are unsigned.
+ * sparc-tdep.c (save_insn_opcodes, restore_insn_opcodes):
+ unsigned, since they use hex values with the high bit set.
+
+Thu Mar 4 08:22:55 1993 Fred Fish (fnf@cygnus.com)
+
+ Fixes submitted by Karl Berry (karl@nermal.hq.ileaf.com):
+ * m88k-pinsn.c (sprint_address): Use SYMBOL_NAME macro to
+ access symbol name.
+ * m88k-nat-c (SXIP_OFFSET, SNIP_OFFSET, SFIP_OFFSET): Enclose
+ macro definitions in parenthesis.
+
+ * dbxread.c (dbx_symfile_init): Catch the case where there is
+ no string table, but the only way we find out is by reading zero
+ bytes from EOF.
+
+Wed Mar 3 15:51:28 1993 Fred Fish (fnf@cygnus.com)
+
+ * dbxread.c (dbx_symfile_init): Make size of the string table
+ size field a define (DBX_STRINGTAB_SIZE_SIZE). Ensure that the
+ offset to the string table is nonzero and handle the nonexistant
+ string table case, should it occur. Ensure that the string table
+ size read from the file is reasonable, with a minimum lower bound
+ of DBX_STRINGTAB_SIZE_SIZE instead of zero.
+
+Wed Mar 3 07:23:03 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: Changes to build testsuite correctly.
+ (FLAGS_TO_PASS): Added CXX and CXXFLAGS.
+ (CC_FOR_TARGET, CXX, CXX_FOR_TARGET): New variables.
+ (TARGET_FLAGS_TO_PASS): New variable.
+ (SUBDIRS): Added testsuite.
+ (all): Build testsuite using TARGET_FLAGS_TO_PASS, so that
+ testsuite is compiled with CC_FOR_TARGET rather than CC.
+
+Tue Mar 2 17:57:56 1993 Fred Fish (fnf@cygnus.com)
+
+ * dbxread.c (dbx_symfile_init): Fix for nonexistant string table,
+ reported by mycroft@gnu.ai.mit.edu.
+
+ (Ultrix 2.2 support from Michael Rendell <michael@mercury.cs.mun.ca>)
+ * configure.in (vax-*-ultrix2*): New triplet.
+ * config/vaxult2.mh: New file.
+ * xm-vaxult2.h: New file.
+
+ * c-exp.y (parse_number): Change high_bit to unsigned.
+ * demangle.c: Change all references to cfront to ARM, since the
+ actual algorithm is the one specified in the Annotated Reference
+ Manual. This was confusing users into thinking that full cfront
+ support was implemented.
+ * dwarfread.c (CFRONT_PRODUCER): Remove, was never really used.
+ * eval.c (evaluate_subexp): For STRUCTOP_PTR pass the arg type
+ directly to lookup_struct_elt_type, which will do the
+ dereferencing itself.
+ * gdbtypes.c (lookup_struct_elt_type): Expand comments. Fix
+ NULL dereferencing bug for unnamed structs, comment out
+ questionable code.
+
+Mon Mar 1 17:54:41 1993 John Gilmore (gnu@cygnus.com)
+
+ * coffread.c (process_coff_symbol): Change PCC argument correction
+ so that it only happens on big-endian targets; so that it only
+ happens if the short or char argument is aligned on an int
+ boundary; and so that it changes the location, rather than the
+ type, of the argument. These changes tend to parallel similar
+ (old) changes in stabsread.c.
+
+ * coffread.c (coff_read_enum_type): Use the specified size for
+ enums, don't assume that they are int-sized.
+
+ * c-valprint.c (c_val_print): Don't assume enums are the same as
+ ints.
+
+ * coredep.c: Handle NO_PTRACE_H in coredep.c. Fix by Michael
+ Rendell, <michael@mercury.cs.mun.ca>.
+
+Mon Mar 1 09:25:57 1993 Fred Fish (fnf@cygnus.com)
+
+ * language.h (local_decimal_format_custom): Add prototype.
+ * language.c (local_decimal_format_custom): Add function, bug
+ reported by Robert R. Henry (rrh@tera.com).
+
+Fri Feb 26 18:33:18 1993 John Gilmore (gnu@cacophony.cygnus.com)
+
+ * xcoffexec.c (vmap_ldinfo): Fix "/" for '/' typo, reported
+ by Josef Leherbauer, joe@takeFive.co.at.
+
+Wed Feb 24 19:17:11 1993 John Gilmore (gnu@cacophony.cygnus.com)
+
+ * symfile.c (syms_from_objfile), tm-29k.h, tm-3b1.h, tm-68k-un.h,
+ tm-altos.h, tm-arm.h, tm-convex.h, tm-es1800.h, tm-h8300.h,
+ tm-hp300bsd.h, tm-hp300hpux.h, tm-hppa.h, tm-i386bsd.h,
+ tm-i386v.h, tm-i960.h, tm-irix3.h, tm-isi.h, tm-linux.h,
+ tm-m88k.h, tm-merlin.h, tm-mips.h, tm-news.h, tm-np1.h, tm-pn.h,
+ tm-pyr.h, tm-rs6000.h, tm-spc-un.h, tm-sun386.h, tm-sunos.h,
+ tm-symmetry.h, tm-sysv4.h, tm-tahoe.h, tm-umax.h, tm-vax.h,
+ tm-vx68.h, tm-z8k.h: Remove remnants of NAMES_HAVE_UNDERSCORE.
+
+Wed Feb 24 07:41:15 1993 Fred Fish (fnf@cygnus.com)
+
+ * symtab.h (SYMBOL_INIT_DEMANGLED_NAME): Initialize contents
+ of demangled name fields to NULL if no demangling exists for
+ a symbol. SYMBOL_INIT_LANGUAGE_SPECIFIC does this for new
+ symbols if their language is known at the time they are created,
+ but sometimes the language is not known until later.
+
+ * ch-typeprint.c (chill_print_type_base): Name changed to
+ chill_type_print_base to match pattern for C and C++ names.
+ * ch-typeprint.c (chill_print_type): Change "char" to "CHAR"
+ to be consistent with other usages.
+ * ch-typeprint.c (chill_type_print_base): Add support for
+ printing Chill STRUCT types.
+ * ch-valprint.c: Include values.h.
+ * ch-valprint.c (chill_print_value_fields): New function and
+ prototype for printing Chill STRUCT values.
+ * ch-valprint.c (chill_val_print): Fix call to val_print_string
+ that was being called with two args instead of three.
+ * ch-valprint.c (chill_val_print): Call chill_print_value_fields
+ to print Chill STRUCT values.
+
+Tue Feb 23 18:58:11 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * configure.in: added testsuite to configdirs.
+
+Tue Feb 23 11:46:11 1993 Mike Stump (mrs@cygnus.com)
+
+ * doc/stabs.texi: The `this' pointer is now known by the name
+ `this' instead of `$t'.
+
+Tue Feb 23 11:21:33 1993 Fred Fish (fnf@cygnus.com)
+
+ * dwarfread.c (read_tag_string_type): Rewrite to allow forward
+ references of TAG_string_type DIEs in user defined types.
+ * ch-lang.c (chill_create_fundamental_type): Track compiler
+ change that now emits debugging info with the type long for Chill
+ longs.
+
+Mon Feb 22 15:21:54 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * remote-mips.c: New file; implements MIPS remote debugging
+ protocol.
+ * config/idt.mt: New file; uses remote-mips.c
+ * configure.in (mips-idt-ecoff): New target; uses idt.mt.
+
+ * mips-tdep.c (mips_fpu): New variable; controls use of MIPS
+ floating point coprocessor.
+ (mips_push_dummy_frame): If not mips_fpu, don't save floating
+ point registers.
+ (mips_pop_frame): If not mips_fpu, don't restore floating point
+ registers.
+ (_initialize_mips_tdep): New function; let the user reset mips_fpu
+ variable.
+ * tm-mips.h (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE): If not
+ mips_fpu, don't use fp0 as floating point return register.
+ (FIX_CALL_DUMMY): If not mips_fpu, don't save floating point
+ registers.
+
+Mon Feb 22 07:54:03 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * gdb/testsuite: made modifications to testcases, etc., to allow
+ them to work properly given the reorganization of deja-gnu and the
+ relocation of the testcases from deja-gnu to a "tool" subdirectory.
+
+Sun Feb 21 10:55:55 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * gdb/testsuite: Initial creation of gdb/testsuite.
+ Migrated dejagnu testcases and support files for testing nm to
+ gdb/testsuite from deja-gnu. These files were moved "as is"
+ with no modifications. This migration is part of a major overhaul
+ of dejagnu. The modifications to these testcases, etc., which
+ will allow them to work with the new version of dejagnu will be
+ made in a future update.
+
+Fri Feb 19 18:36:55 1993 John Gilmore (gnu@cygnus.com)
+
+ * NEWS: Add reminders for next release.
+
+Fri Feb 19 10:01:39 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mipsread.c (parse_lines): Correct check for files compiled with
+ -g1.
+
+Fri Feb 19 05:56:15 1993 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (VERSION): 4.8.1 to distinguish local versions.
+
+Fri Feb 19 01:32:58 1993 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (VERSION): GDB-4.8 release!
+ * README, NEWS: Update for release.
+
+Thu Feb 18 22:44:40 1993 Stu Grossman (grossman@cygnus.com)
+
+ * am29k-pinsn.c (print_insn): Minor nits with const.
+ * am29k-tdep.c: More minor nits with arg types for
+ supply_register, NULL vs. 0, read_register_gen, & reginv_com.
+
+Thu Feb 18 22:38:03 1993 John Gilmore (gnu@cygnus.com)
+
+ * gcc.patch: Update for a different GCC (G++) bug.
+ * main.c (print_gdb_version): Update copyright year to 1993.
+ * nm-hp300bsd.h: Decide whether this is BSD 4.3 or 4.4,
+ conditionalize this file on it. FIXME, right way is to split
+ these into two config files.
+ (ATTACH_DETACH): Define for BSD 4.4
+ (PTRACE_ARG_TYPE): caddr_t for BSD 4.4, unset for 4.3.
+ (U_REGS_OFFSET): Revise for 4.4.
+ (REGISTER_U_ADDR): Separate for 4.4, but it doesn't work yet.
+ * xm-hp300bsd.h: Move definitions of UINT_MAX, INT_MAX, INT_MIN,
+ LONG_MAX into this file to avoid cpp "redefinition" warnings.
+
+Thu Feb 18 16:13:28 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * nm-hp300bsd.h (PTRACE_ARG3_TYPE): FSF's hp300's have int* not
+ caddr_t.
+
+Thu Feb 18 04:10:06 1993 John Gilmore (gnu@cygnus.com)
+
+ * c-lang.c (c_printstr): Bugfix for length==0 case.
+
+ * c-lang.c (c_printstr): If a C string ends in a null, don't
+ print the null.
+
+Thu Feb 18 02:39:21 1993 Stu Grossman (grossman at cygnus.com)
+
+ * defs.h (STRCMP): Make it work for unsigned chars.
+
+Thu Feb 18 01:56:06 1993 John Gilmore (gnu@cygnus.com)
+
+ * nm-hp300bsd.h (ATTACH_DETACH, PTRACE_ATTACH, PTRACE_DETACH): define.
+ * config/hp300bsd.mh (REGEX, REGEX1): Define.
+ * m68k-pinsn.c (BREAK_UP_BIG_DECL, AND_OTHER_PART): #if __GNUC__,
+ define to kludge the large opcode table into two smaller tables,
+ since GCC take exponential space to build the table. Lint.
+ (NOPCODES): Remove, use "numopcodes" from opcode/m68k.h instead.
+
+Wed Feb 17 19:24:40 1993 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (VERSION): Roll to 4.7.9.
+ * xm-hp300bsd.h: Define PSIGNAL_IN_SIGNAL_H and put a compatible
+ definition here, to handle both BSD 4.3 and 4.4 systems.
+ * mipsread.c (ZMAGIC): #undef to avoid duplicate define.
+ * remote.c (alarm): Move declaration to global level, before
+ first reference to it.
+ * tm-i386bsd.h (NUM_REGS): There are only eleven, not twelve.
+ * dbxread.c (process_one_symbol): Cast to unsigned char, not int.
+
+Wed Feb 17 13:40:29 1993 K. Richard Pixley (rich@cygnus.com)
+
+ * remote.c (readchar): forward declare alarm which otherwise looks
+ like an undeclared variable to gcc.
+
+ * dbxread.c (process_one_symbol): cast enum value N_SO into int
+ when comparing against an int. Avoids superfluous warning from
+ vax ultrix 4.2 cc.
+
+ * inflow.c (set_sigint_trap): add cast to assignment from signal.
+ Avoids superfluous warnings from some systems and/or compilers
+ (like vax ultrix 4.2.)
+
+ * language.c (struct op_print unk_op_print_tab): use the enum
+ values rather naked zeros as initializers. Avoids warnings from
+ ultrix type compilers.
+
+Tue Feb 16 00:53:20 1993 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (VERSION): Roll to 4.7.6.
+ (SFILES_SUBDIR): Add 29k-share/udi_soc.
+ (SFILES_SUBSUBDIR): Move 29k-share/udi files to this macro.
+ (alldeps.mak): Make ALLDEPFILES_SUBSUBDIR for files in sub sub dirs.
+ (ALLDEPFILES_SUBSUBDIR): Depend on this for deeper dep files.
+ (HFILES): Remove all nm-* except nm-trash.h. Add ns32k-opcode.h.
+ (depend): Fix bug where nm-files in config files weren't noticed.
+ (make-proto-gdb-1): Avoid changing directories while building new
+ prototype. Build SFILES_SUBSUBDIR with longer symlinks.
+
+Mon Feb 15 20:48:09 1993 John Gilmore (gnu@cygnus.com)
+
+ * remote.c: Improve error recovery. Allow user to break out
+ of initial connection attempt with INTERRUPT. Treat a timeout
+ while waiting for remote packet like a retry, unless the remote
+ side is actively running user code. Fix a few long printf_filtered's.
+
+ * xcoffread.c (read_xcoff_symtab): Don't use null symbol name for
+ trampoline symbols.
+
+ * buildsym.c (start_subfile): Allow null file name.
+
+Fri Feb 12 15:46:49 1993 K. Richard Pixley (rich@cygnus.com)
+
+ * xcoffread.c (process_xcoff_symbol, read_symbol_lineno): complain
+ expects a pointer to complaint rather than a complaint
+ structure.
+ (process_linenos): free the previously allocated subfile name,
+ then allocate the new one from the heap.
+
+Fri Feb 12 08:06:05 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * h8300-tdep.c, tm-h8300.h: turn off some experimental features
+
+Thu Feb 11 00:59:07 1993 John Gilmore (gnu@cygnus.com)
+
+ * stabsread.c (dbx_lookup_type): Handle negative type numbers.
+ Previously, would bogusly index off the bottom of type_vector.
+ (rs6000_builtin_type): Accept type number as argument.
+ (read_type, case '-'): Handle negatives like any other type number.
+
+ * symfile.c (deduce_language_from_filename): Handle null name.
+
+ * mips-tdep.c (isa_NAN): Fix byte order dependency.
+ Reported by Nobuyuki Hikichi <hikichi@sra.co.jp>,
+ fixed by sato@sm.sony.co.jp.
+
+ * xcoffread.c (parmsym): Don't use an initializer to set up
+ this struct symbol. Set it up in initialize_xcoffread.
+ (read_xcoff_symtab, xcoff_symfile_read): Surround code that only
+ works on real rs/6000 target with #ifndef FAKING_RS6000.
+
+Wed Feb 10 23:42:37 1993 John Gilmore (gnu@cygnus.com)
+
+ * stabsread.c (rs6000_builtin_type): Move function from
+ xcoffread.c:builtin_type.
+ * xcoffread.c (builtin_type): Move to stabsread. Remove
+ IBM6000_HOST dependency. Move misplaced comments.
+ (various): Change printf's to complaints.
+ (patch_block_stabs, process_xcoff_symbol case C_DECL): Add
+ objfile argument to read_type calls under #if 0.
+ (process_xcoff_symbol case C_RSYM): Fix typo in #ifdef.
+ * xcoffexec.c (map_vmap): Don't allocate an objfile for the exec_file.
+ * Makefile.in: xcoffread.o is not built by default.
+ * xm-rs6000.h (IBM6000_HOST): Remove.
+ * config/rs6000.mh (NATDEPFILES): xcoffread.o is native only.
+ * doc/gdbint.texinfo: Eliminate IBM6000_HOST, document
+ IBM6000_TARGET.
+
+Wed Feb 10 18:31:20 1993 Stu Grossman (grossman at cygnus.com)
+
+ * findvar.c (read_var_value): If REG_STRUCT_HAS_ADDR, then set
+ VALUE_LVAL to be lval_memory so that we don't try to modify wild
+ register numbers when user tries to modify elements in structs
+ passed as arguments.
+ * inflow.c (child_terminal_info): Move banner outside of system
+ specific #ifdefs.
+ * tm-hppa.h (REG_STRUCT_HAS_ADDR): Define this for HPPA, which
+ passes struct/union arguments by address.
+
+Wed Feb 10 15:34:46 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Based on patch from Kean Johnston <maw@netcom.com>:
+ * nm-i386sco4.h: New file. Like nm-i386sco.h, but define
+ ATTACH_DETACH, PTRACE_ATTACH and PTRACE_DETACH.
+ * config/i386sco4.mh (NAT_FILE): Use nm-i386sco4.h.
+
+Tue Feb 9 20:07:18 1993 John Gilmore (gnu@cygnus.com)
+
+ * remote-udi.c (FREEZE_MODE): Fix && for & typo. Found and
+ fixed by Lynn D. Shumaker, shumaker@saifr00.cfsat.honeywell.com.
+
+Tue Feb 9 08:18:07 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/i386sco4.mh (MUNCH_DEFINE): Pass -p to nm to avoid bug in
+ cc debugging output.
+
+Tue Feb 9 00:19:28 1993 John Gilmore (gnu@cygnus.com)
+
+ * stabsread.c (define_symbol): Complain about unrecognized names
+ that begin with CPLUS_MARKER (often '$'), but don't die. Fix
+ suggested by gb@cs.purdue.edu (Gerald Baumgartner).
+ (read_cpp_abbrev): Don't use the class name as part of the
+ vtable pointer member name (_vptr$) in $vf abbrevs or unrecognized
+ abbrevs. Inspired by Mike Tiemann.
+ (read_tilde_fields): Comment. Remove ancient dead code.
+ Remove erroneous but non-dead code. Simplify. Add complaints.
+ (in general): Remove extraneous (parentheses) in return
+ statements.
+
+Fri Feb 5 14:01:22 1993 John Gilmore (gnu@cygnus.com)
+
+ * coffread.c (coff_lookup_type): Fix fencepost error reported
+ by Art Berggreen, <arg@opal.acc.com>.
+
+ Fix long file name bug reported on SCO Open Desktop 2.0 by Ulf Lunde
+ <Ulf.Lunde@kvatro.no> and Dag H. Wanvik <Dag.H.Wanvik@kvatro.no>:
+
+ * coffread.c (getfilename): Eliminate COFF_NO_LONG_FILE_NAMES
+ test, which is apparently left over from when we used native
+ include files and couldn't depend on the member names being there.
+ * tm-3b1.h, tm-altos.h, tm-i386v.h: Don't set it.
+
+Thu Feb 4 12:23:15 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mipsread.c: Major overhaul to use new BFD symbol table reading
+ routines. Now swaps information as it is needed, rather than
+ swapping everything when the file is read.
+
+Thu Feb 4 01:52:36 1993 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (TARDIRS): Add sparclite demo dir.
+ (*.tab.c): Change dependency on Makefile to depend on
+ Makefile.in, otherwise it always rebuilds after configuring.
+ Force output *.tab.c file into current directory even in "make"
+ versions that rewrite dependent file names used in command lines.
+
+ * TODO: Remove some things we did.
+ * am29k-opcode.h, convx-opcode: Remove; now in ../include/opcode.
+ * os68k-xdep.c: Remove; useless file (os68k is a target only).
+ * convex-pinsn.c: Use ../include/opcode/convex.h. Add CONST.
+ * symtab.h: Eliminate unnamed unions and structs.
+
+Wed Feb 3 14:48:08 1993 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (VERSION): Roll to 4.7.5.
+
+Tue Feb 2 20:47:42 1993 John Gilmore (gnu@cygnus.com)
+
+ * breakpoint.c (breakpoint_re_set_one): Handle watchpoints when
+ re-evaluating symbol pointers.
+
+Tue Feb 2 16:10:31 1993 Fred Fish (fnf@cygnus.com)
+
+ * c-exp.y (lcurly, rcurly): New nonterminals.
+ * c-exp.y (exp): Use lcurly and rcurly for arrays and UNOP_MEMVAL
+ constructs.
+ * parse.c (free_funcalls): Moved prototype from parser-defs.h,
+ made function static.
+ * parse.c (struct funcall): Moved struct def from parser-defs.h.
+ * parse.c (funcall_chain): Moved from parser-defs.h, made static.
+ * parse.c (start_arglist):
+ * parser-defs.h (free_funcalls): Moved prototype to parse.c.
+ * parser-defs.h (struct funcall): Moved struct def to parse.c.
+ * parser-defs.h (funcall_chain): Moved to parse.c.
+ * printcmd.c (print_frame_nameless_args): Fix prototype.
+ * tm-mips.h (setup_arbitrary_frame): Fix prototype.
+ * tm-sparc.h (setup_arbitrary_frame): Fix prototype.
+ * valops.c (typecmp): Moved prototype from values.h.
+ * value.h (typecmp): Moved prototype to valops.c, made static.
+ * ch-exp.y (yylex): Change way control sequences are disabled.
+
+Tue Feb 2 16:11:43 1993 John Gilmore (gnu@cygnus.com)
+
+ * tm-mips.h, tm-sparc.h: Fix thinko in SETUP_ARBITRARY_FRAME.
+
+Tue Feb 2 15:30:33 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mipsread.c (upgrade_type): Build array types correctly, using
+ create_range_type and create_array_type.
+
+Tue Feb 2 00:19:08 1993 John Gilmore (gnu@cygnus.com)
+
+ * remote-nindy.c: Cleanup.
+
+ * infrun.c (wait_for_inferior): When rolling back the PC after
+ a breakpoint, call write_pc so that NPC gets rolled back as well
+ (for the 29K).
+
+ * blockframe.c (inside_entry_file, inside_main_func,
+ inside_entry_func): PC of zero is always "bottom of stack".
+
+ * printcmd.c (print_frame_args, print_frame_nameless_args):
+ Let print_frame_nameless_args decide whether there are any,
+ laying groundwork for possibly later printing 29K args for
+ functions where we have tag words but no symbols.
+
+Mon Feb 1 18:09:58 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * Makefile.in: fix GDB doc targets for new doc subdir structure
+
+Mon Feb 1 17:56:47 1993 John Gilmore (gnu@cygnus.com)
+
+ * stack.c (parse_frame_specification): Parse as many arguments
+ as there are (up to MAXARGS). Pass all of them in argc, argv
+ format to SETUP_ARBITRARY_FRAME. Put the burden of checking how
+ many there were, onto SETUP_ARBITRARY_FRAME.
+ * tm-mips.h, tm-sparc.h: Corresponding changes.
+ * mips-tdep.c, sparc-tdep.c: Ditto.
+
+Mon Feb 1 17:19:37 1993 John Gilmore (gnu@cygnus.com)
+
+ * hp300ux-nat.c: Update copyrights.
+ * mipsread.c (parse_partial_symbols): Complain about block
+ indexes that go backwards. Fix from Peter Schauer.
+ * symfile.c (syms_from_objfile, symbol_file_add): Allow a
+ symbol-file that has no linkage symbols to be read.
+ * tm-rs6000.h, xm-rs6000.h: (SIGWINCH_HANDLER and friends): Move
+ from tm- file to xm-file, since they're host dependent.
+ * valarith.c (value_binop): Typo.
+
+Mon Feb 1 16:16:59 1993 Stu Grossman (grossman at cygnus.com)
+
+ * sparclite/aload.c: Add copyleft.
+ * sparclite/crt0.s: Add comment at beginning.
+
+Mon Feb 1 14:36:11 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * remote-z8k.c, z8k-tdep.c: support for the Z8001 and Z8002.
+ * parse.c (std_regs): Only declare if NO_STD_REGS is defined.
+
+Sun Jan 31 04:32:48 1993 Michael Tiemann (tiemann@rtl.cygnus.com)
+
+ * values.c (value_headof): Fix typo in which VTBL and ARG were
+ being confused for one another.
+
+ * valops.c (typecmp): Now static.
+
+ * gdbtypes.c (fill_in_vptr_fieldno): Don't ignore the first
+ baseclass--we don't always inherit its virtual function table
+ pointer.
+
+ * eval.c (evaluate_subexp): In OP_FUNCALL case, adjust `this'
+ pointer correctly in case value_struct_elt moves it around.
+
+ * valops.c (typecmp): Now static. Also, now groks references
+ better.
+
+ * gdbtypes.c (lookup_struct_elt_type): Pass NOERR instead of
+ zero on recursive call. If NAME is the name of TYPE, return TYPE.
+
+Sat Jan 30 19:55:52 1993 John Gilmore (gnu@cygnus.com)
+
+ * hppah-nat.c: Eliminate <sys/user.h> and other unnecessary stuff,
+ to avoid "too much defining" error from native C compiler (!).
+
+ * Makefile.in (HFILES): Add typeprint.h.
+ * typeprint.[ch]: Update copyrights.
+
+Thu Jan 28 19:09:02 1993 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in: Update to match doc/ subdir changes.
+
+ * config/hp300hpux.mh: No cross-host file needed, just native.
+ * config/go32.mh: Remove nonexistent "native" support.
+
+ M88K fixes reported by Carl Greco, <cgreco@Creighton.Edu>:
+ * tm-m88k.h (REGISTER_CONVERT_TO_RAW): Fix typo.
+ * m88k-tdep.c (next_insn): Lint, cleanup.
+ (store_parm_word): Lint.
+
+ * README: Fix typo (reported by karl@hq.ileaf.com).
+
+Wed Jan 27 21:34:21 1993 Fred Fish (fnf@cygnus.com)
+
+ * expression.h (BINOP_CONCAT): Document use for self concatenation
+ an integral number of times.
+ * language.c (binop_type_check): Extend BINOP_CONCAT for self
+ concatenation case.
+ * valarith.c (value_concat): Rewrite to support self
+ concatenation an integral number of times.
+ * Makefile.in (ch-exp.tab.c): Change "expect" message.
+ * ch-exp.y (FIXME's): Make all FIXME tokens distinct, to
+ eliminate hundreds of spurious shift/reduce and reduce/reduce
+ conflicts that mask the 5 real ones.
+ * ch-exp.y (STRING, CONSTANT, SC): Remove unused tokens.
+ * ch-exp.y (integer_literal_expression): Remove production,
+ no longer used.
+
+Thu Jan 21 09:58:36 1993 Fred Fish (fnf@cygnus.com)
+
+ * eval.c (evaluate_subexp): Fix OP_ARRAY, remove code that
+ implied that "no side effects" was nonfunctional.
+ * eval.c (evaluate_subexp): Add BINOP_CONCAT case to deal with
+ character string and bitstring concatenation.
+ * expprint.c (dump_expression): Add case for BINOP_CONCAT.
+ * expression.h (exp_opcode): Add BINOP_CONCAT.
+ * gdbtypes.h (type_code): Add TYPE_CODE_BITSTRING.
+ * language.c (string_type): Add function to determine if a type
+ is a string type.
+ * language.c (binop_type_check): Add case for BINOP_CONCAT.
+ * valarith.c (value_concat): New function to concatenate two
+ values, such as character strings or bitstrings.
+ * valops.c (value_string): Remove error stub and implement
+ function body.
+ * value.h (value_concat): Add prototype.
+ * ch-exp.y (operand_3): Add actions for SLASH_SLASH (//).
+ * ch-exp.y (yylex): Recognize SLASH_SLASH.
+ * ch-lang.c (chill_op_print_tab): Add SLASH_SLASH (//) as
+ BINOP_CONCAT.
+
+Tue Jan 19 14:26:15 1993 Fred Fish (fnf@cygnus.com)
+
+ * c-exp.y (exp): Add production to support direct creation
+ of array constants using the obvious syntax.
+ * c-valprint.c (c_val_print): Set printed string length.
+ * dwarfread.c (read_tag_string_type): New prototype and
+ function that handles TAG_string_type DIEs.
+ * dwarfread.c (process_dies): Add case for TAG_string_type
+ that calls new read_tag_string_type function.
+ * expprint.c (print_subexp): Add support for OP_ARRAY.
+ * gdbtypes.c (create_range_type, create_array_type): Inherit
+ objfile from the index type.
+ * ch-typeprint.c (chill_print_type): Add case for
+ TYPE_CODE_STRING.
+ * ch-valprint.c (chill_val_print): Fix case for
+ TYPE_CODE_STRING.
+
+Mon Jan 18 11:58:45 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mipsread.c (CODE_MASK, MIPS_IS_STAB, MIPS_MARK_STAB,
+ MIPS_UNMARK_STAB, STABS_SYMBOLS): Removed; now in
+ include/coff/mips.h.
+
+Fri Jan 15 20:26:50 1993 Fred Fish (fnf@cygnus.com)
+
+ * c-exp.y (exp:STRING): Convert C strings into array-of-char
+ constants with an explicit null byte terminator. OP_STRING is
+ now used for real string types.
+ * c-lang.c (builtin_type_*): Move declarations to lang.c since
+ they are used by all languages.
+ * c-lang.c (_initialize_c_language): Move initializations of
+ builtin_type_* to lang.c.
+ * c-typeprint.c (c_type_print_varspec_prefix,
+ c_type_print_varspec_suffix): TYPE_CODE_PASCAL_ARRAY renamed
+ to TYPE_CODE_STRING.
+ * c-valprint.c (c_val_print): Change the way character arrays
+ are printed as strings to be consistent with the way strings
+ are printed when pointer-to-char types are dereferenced.
+ Remove test of print_max before calling val_print_string, which
+ now does it's own test.
+ * eval.c (evaluate_subexp): Add case for OP_ARRAY.
+ * expprint.c (print_subexp, dump_expression): Add case for OP_ARRAY.
+ * expression.h (enum exp_opcode): Add OP_ARRAY and document.
+ * gdbtypes.c (builtin_type_*): Add declarations moved from
+ c-lang.c.
+ * gdbtypes.c (create_string_type): New function to create real
+ string types.
+ * gdbtypes.c (recursive_dump_type): TYPE_CODE_PASCAL_ARRAY
+ renamed to TYPE_CODE_STRING.
+ * gdbtypes.c (_initialize_gdbtypes): Add initializations of
+ builtin_type_* types moved from c-lang.c.
+ * gdbtypes.h (enum type_code): TYPE_CODE_PASCAL_ARRAY renamed
+ to TYPE_CODE_STRING.
+ * gdbtypes.h (builtin_type_string): Add extern declaration.
+ * gdbtypes.h (create_string_type): Add prototype.
+ * m2-lang.c (m2_create_fundamental_type): TYPE_CODE_PASCAL_ARRAY
+ renamed to TYPE_CODE_STRING.
+ * m88k-tdep.c (pushed_size): TYPE_CODE_PASCAL_ARRAY renamed to
+ TYPE_CODE_STRING.
+ * mipsread.c (_initialize_mipsread): TYPE_CODE_PASCAL_ARRAY
+ renamed to TYPE_CODE_STRING.
+ * parse.c (length_of_subexp, prefixify_subexp): Add case for
+ OP_ARRAY.
+ * printcmd.c (print_formatted): Recognize TYPE_CODE_STRING.
+ * typeprint.c (print_type_scalar): TYPE_CODE_PASCAL_ARRAY renamed
+ to TYPE_CODE_STRING.
+ * valops.c (allocate_space_in_inferior): New function and
+ prototype, using code ripped out of value_string.
+ * valops.c (value_string): Rewritten to use new function
+ allocate_space_in_inferior, but temporarily disabled until some
+ other support is in place.
+ * valops.c (value_array): New function to create array constants.
+ * valprint.c (val_print_string): Add comment to document use,
+ complete rewrite to fix several small buglets.
+ * value.h (value_array): Add prototype.
+ * value.h (val_print_string): Change prototype to match rewrite.
+ * ch-valprint.c (chill_val_print): Add case for TYPE_CODE_STRING.
+ * ch-exp.y (match_character_literal): Disable recognition of
+ control sequence form of character literals and document why.
+
+Thu Jan 14 15:48:12 1993 Stu Grossman (grossman at cygnus.com)
+
+ * nindy-share/nindy.c: Add comments to #endif's to clarify
+ grouping.
+
+ * hppa-pinsn.c (print_insn): Use read_memory_integer, instead of
+ read_memory to get byte order right.
+ * hppah-tdep.c (find_unwind_info): Don't read in unwind info
+ anymore. This is done in paread.c now. We expect unwind info
+ to hang off of objfiles, and search all of the objfiles when until
+ we find a match.
+ * (skip_trampoline_code): Cast arg to target_read_memory.
+ * objfiles.h (struct objfile): Add new field obj_private to hold
+ per object file private data (unwind info in this case).
+ * paread.c (read_unwind_info): New routine to read unwind info
+ for the objfile. This data is hung off of obj_private.
+ * tm-hppa.h: Define struct obj_unwind_info, to hold pointers to
+ the unwind info for this objfile. Also define OBJ_UNWIND_INFO to
+ make this easier to access.
+
+Wed Jan 13 20:49:59 1993 Fred Fish (fnf@cygnus.com)
+
+ * c-valprint.c (cp_print_class_member): Add extern decl.
+ * c-valprint.c (c_val_print): Extract code for printing methods
+ and move it to cp_print_class_method in cp-valprint.c.
+ * c-valprint.c (c_val_print): Extract code to print strings and
+ move it to val_print_string in valprint.c.
+ * cp-valprint.c (cp_print_class_method): New function using
+ code extracted from c_val_print.
+ * valprint.c (val_print_string): New function using code
+ extracted from c_val_print.
+ * value.h (val_print_string): Add prototype.
+ * ch-exp.y (CHARACTER_STRING_LITERAL): Set correct token type.
+ * ch-exp.y (literal): Add action for CHARACTER_STRING_LITERAL.
+ * ch-exp.y (tempbuf, tempbufsize, tempbufindex, GROWBY_MIN_SIZE,
+ CHECKBUF, growbuf_by_size): New variables, macros, and support
+ functions for implementing a dynamically expandable temp buffer.
+ * ch-exp.y (match_string_literal): New lexer function.
+ * ch-exp.y (match_bitstring_literal): Dynamic buffer code
+ removed and replaced with new CHECKBUF macro.
+ * ch-exp.y (yylex): Call match_string_literal when appropriate.
+ * ch-valprint.c (ch_val_print): Add code for TYPE_CODE_PTR.
+
+Sat Jan 9 19:59:33 1993 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in: Add info for paread.o.
+ * config/hppahpux.mh: Add paread.o to NATDEPFILES.
+
+ * blockframe.c (frameless_look_for_prologue): Correct the
+ comment.
+ * gdbtypes.h, gdbtypes.c: Use const in decl of
+ cplus_struct_default, now that pa-gas assembler has been fixed.
+ * hppah-nat.c: Formatting.
+ * hppah-tdep.c: Remove lots of useless externs for variables we
+ don't use.
+ * (find_unwind_entry): Speed up by using binary search, and a one
+ entry cache.
+ * (rp_saved): New routine to see what unwind info says about RP
+ being saved on the stack frame.
+ * (frame_saved_pc): Look for prologue to see if we need to
+ examine the stack for the saved RP or not.
+ * (init_extra_frame_info): Check for prologue, instead of
+ framesize to determine if we are frameless or not.
+ * (frame_chain_valid): Stop backtraces when we run into _start.
+ * (push_dummy_frame): Reformat to make more readable.
+ * (find_dummy_frame_regs): ditto.
+ * (hp_pop_frame): ditto.
+ * (hp_restore_pc_queue): small cleanup.
+ * (hp_push_arguments): ditto.
+ * (pa_do_registers_info): ditto.
+ * (skip_prologue): New routine created from SKIP_PROLOGUE macro.
+ * tm-hppa.h: Move contents of SKIP_PROLOGUE into hppah-tdep.c.
+ * Define FRAME_CHAIN_VALID.
+ * Turn on BELIEVE_PCC_PROMOTION so that we can access char args
+ passed to functions.
+
+ * paread.c (pa_symtab_read): Use new bfd conventions for
+ accessing linker symbol table.
+ * (pa_symfile_init): Access embedded STAB info via BFD section
+ mechanism and related macros.
+
+
+Sat Jan 9 19:31:43 1993 Stu Grossman (grossman at cygnus.com)
+
+ * sparc-stub.c: Use a seperate stack for our traps.
+ * Handle recursive traps.
+ * Remove all trap init code. This needs to be done by the
+ environment.
+ * (set_mem_fault_trap): Call exceptionHandler() to setup this
+ trap.
+ * (handle_exception): See if we are at breakinst, if so, then
+ advance PC sp that users can just step out of breakpoint().
+ * (case 'G'): Don't let GDB hack CWP. Also, copy saved regs to
+ new place if SP has changed.
+ * (case 's'): Get rid of this, we can't do it yet.
+ * (case 't'): New command to test any old random feature.
+ * (case 'r'): New command to reset the system.
+ * (breakpoint): Add label to breakpoint trap instruction so that
+ handle_exception() can detect where we are and get past the
+ breakpoint trivially.
+
+Thu Jan 7 13:33:06 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips-pinsn.c: Actual work now done by opcodes/mips-dis.c.
+
+Thu Jan 7 09:21:51 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: recognise all sparclite variants
+
+Wed Jan 6 10:14:51 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * symfile.c: If O_BINARY isn't defined, set it to 0, call openp for
+ binary files oring in the right bit.
+
+ * main.c, source.c, state.c, symmisc.c: use macros defined in
+ fopen-{bin|both} when fopening files.
+
+Wed Jan 6 08:19:11 1993 Fred Fish (fnf@cygnus.com)
+
+ * defs.h (HOST_CHAR_BIT): New macro, defaults to either CHAR_BIT
+ from a configuration file (typically including <limits.h>), or to
+ TARGET_CHAR_BIT if CHAR_BIT is not defined.
+ * eval.c (evaluate_subexp): Use new BYTES_TO_EXP_ELEM macro.
+ * eval.c (evaluate_subexp): Add case for OP_BITSTRING.
+ * expprint.c (print_subexp): Use new BYTES_TO_EXP_ELEM macro.
+ * exppritn.c (print_subexp, dump_expression): Add case for
+ OP_BITSTRING.
+ * expression.h (OP_BITSTRING): New expression element type for
+ packed bitstrings.
+ * expression.h (EXP_ELEM_TO_BYTES, BYTES_TO_EXP_ELEM): New
+ macros to convert between number of expression elements and bytes
+ to store that many elements.
+ * i960-tdep.c (leafproc_return): Use new macros to access
+ minimal symbol name and address fields.
+ * m88k-pinsn.c (sprint_address): Use new macros to access
+ minimal symbol name and address fields.
+ * nindy-tdep.c (nindy_frame_chain_valid): Use new macro to access
+ minimal symbol address field.
+ * parse.c (write_exp_elt, write_exp_string, prefixify_expression,
+ parse_exp_1): Use new EXP_ELEM_TO_BYTES macro.
+ * parse.c (write_exp_string, length_of_subexp, prefixify_expression):
+ Use new BYTES_TO_EXP_ELEM macro.
+ * parse.c (write_exp_bitstring): New function to write packed
+ bitstrings into the expression element vector.
+ * parse.c (length_of_subexp, prefixify_subexp): Add case for
+ OP_BITSTRING.
+ * parser-defs.h (struct stoken): Document that it is used for
+ OP_BITSTRING as well as OP_STRING.
+ * parser-defs.h (write_exp_bitstring): Add prototype.
+ * ch-exp.y (BIT_STRING_LITERAL): Change token type to sval.
+ * ch-exp.y (NUM, PRED, SUCC, ABS, CARD, MAX, MIN, SIZE, UPPER,
+ LOWER, LENGTH): New tokens for keywords.
+ * ch-exp.y (chill_value_built_in_routine_call, mode_argument,
+ upper_lower_argument, length_argument, array_mode_name,
+ string_mode_name, variant_structure_mode_name): New non-terminals
+ and productions.
+ * ch-exp.y (literal): Useful production for BIT_STRING_LITERAL.
+ * ch-exp.y (match_bitstring_literal): New lexer support function
+ to recognize bitstring literals.
+ * ch-exp.y (tokentab6): New token table for 6 character keywords.
+ * ch-exp.y (tokentab5): Add LOWER, UPPER.
+ * ch-exp.y (tokentab4): Add PRED, SUCC, CARD, SIZE.
+ * ch-exp.y (tokentab3): Add NUM, ABS, MIN, MAX.
+ * ch-exp.y (yylex): Check tokentab6.
+ * ch-exp.y (yylex): Call match_bitstring_literal.
+
+Mon Jan 4 16:54:18 1993 Fred Fish (fnf@cygnus.com)
+
+ * xcoffexec.c (vmap_symtab): Use new macros to access minimal
+ symbol name and value fields.
+
+ * c-exp.y (yylex): Make static, to match prototype and other
+ <lang>-exp.y files.
+
+ * expression.h (exp_opcode): Add BINOP_MOD.
+ * eval.c (evaluate_subexp): Handle new BINOP_MOD.
+ * expprint.c (dump_expression): Handle new BINOP_MOD.
+ * language.c (binop_type_check): Handle new BINOP_MOD.
+ * main.c (float_handler): Re-enable float handler when hit.
+ * valarith.c (language.h): Include, need current_language.
+ * valarith.c (TRUNCATION_TOWARDS_ZERO): Define default macro
+ for integer divide truncates towards zero for negative results.
+ * valarith.c (value_x_binop): Handle BINOP_MOD if seen.
+ * valarith.c (value_binop): Allow arithmetic operations on
+ TYPE_CODE_CHAR variables. Add case to handle new BINOP_MOD.
+ * ch-exp.y (operand_4): Add useful actions for MOD and REM.
+ * ch-exp.y (tokentab3): Add MOD and REM.
+ * ch-exp.y (yylex): Set innermost_block for symbols found
+ in local scopes. Return LOCATION_NAME for local symbols.
+ * ch-lang.c (chill_op_print_tab): Fix MOD entry to use
+ BINOP_MOD instead of BINOP_REM. Add REM entry, using BINOP_REM.
+
+Mon Jan 4 07:35:31 1993 Steve Chamberlain (sac@wahini.cygnus.com)
+
+ * command.c (shell_escape, make_command, _initialize_command):
+ don't create or use fork if CANT_FORK is defined.
+ * serial.h, ser-go32.c: now compiles, but "the obvious problems of
+ code written for the IBM PC" remain.
+ * xm-go32.h: define CANT_FORK
+
+Sun Jan 3 14:24:56 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * remote-sim.c: first attempt at general simulator interface
+ * remote-hms.c: whitespace
+ * h8300-tdep.c: (h8300_skip_prologue, examine_prologue):
+ understand new stack layout. (print_register_hook): print ccr
+ register in a fancy way.
+
+Sun Jan 3 14:16:10 1993 Fred Fish (fnf@cygnus.com)
+
+ * eval.c (language.h): Include.
+ * eval.c (evaluate_subexp_with_coercion): Only coerce arrays
+ to pointer types when the current language is C. It loses for
+ other languages when the lower index bound is nonzero.
+ * valarith.c (value_subscript): Take array lower bounds into
+ account when performing subscripting operations.
+ * valops.c (value_coerce_array): Add comment describing why
+ arrays with nonzero lower bounds are dealt with in value_subscript,
+ rather than in value_coerce_array.
+
+Sat Jan 2 12:16:41 1993 Fred Fish (fnf@cygnus.com)
+
+ * ch-exp.y (FLOAT_LITERAL): Add token.
+ * ch-exp.y (literal): Add FLOAT_LITERAL.
+ * ch-exp.y (match_float_literal): New lexer routine.
+ * ch-exp.y (convert_float): Remove.
+ * ch-exp.y (yylex): Call match_float_literal.
+ * ch-exp.y (yylex): Match single '.' after trying
+ to match floating point literals.
+
+ * eval.c (evaluate_subexp): Add case MULTI_SUBSCRIPT.
+ * expprint.c (print_subexp): Rename BINOP_MULTI_SUBSCRIPT to
+ MULTI_SUBSCRIPT.
+ * expprint.c (dump_expression): New function for dumping
+ expression vectors during gdb debugging.
+ * expression.h (BINOP_MULTI_SUBSCRIPT): Name changed to
+ MULTI_SUBSCRIPT and moved out of BINOP range.
+ * expression.h (DUMP_EXPRESSION): New macro that calls
+ dump_expression if DEBUG_EXPRESSIONS is defined.
+ * m2-exp.y (BINOP_MULTI_SUBSCRIPT): Changed to MULTI_SUBSCRIPT.
+ * parse.c (length_of_subexp, prefixify_subexp): Change
+ BINOP_MULTI_SUBSCRIPT to MULTI_SUBSCRIPT.
+ * parse.c (parse_exp_1): Call DUMP_EXPRESSION before and after
+ prefixify'ing the expression.
+ * printcmd.c (print_command_1): Add comment.
+ * ch-exp.y (expression_list): Add useful actions.
+ * ch-exp.y (value_array_element): Add useful actions.
+ * ch-exp.y (array_primitive_value): Add production.
+ * ch-exp.y (yylex): Recognize ',' as a token.
+
+Fri Jan 1 18:22:02 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: pass prefix and exec_prefix via FLAGS_TO_PASS,
+ POSIXize the recursive makes (make [variable assignments] target{s})
+
+Fri Jan 1 11:56:23 1993 Fred Fish (fnf@cygnus.com)
+
+ * tm-sun4sol2.h (CPLUS_MARKER): Remove, now set in tm-sysv4.h.
+ * tm-sysv4.h (CPLUS_MARKER): By default, g++ uses '.' as the
+ CPLUS_MARKER for all SVR4 systems, so follow suit.
+ * defs.h (strdup_demangled): Remove prototype.
+ * dwarfread.c (enum_type, synthesize_typedef): Use new macro
+ SYMBOL_INIT_LANGUAGE_SPECIFIC.
+ * dwarfread.c (new_symbol): Use SYMBOL_INIT_DEMANGLED_NAME.
+ * minsyms.c (install_minimal_symbols, prim_record_minimal_symbol,
+ prim_record_minimal_symbol_and_info): Use new macro
+ SYMBOL_INIT_LANGUAGE_SPECIFIC.
+ * minsyms.c (install_minimal_symbols): Use new macro
+ SYMBOL_INIT_DEMANGLED_NAME.
+ * stabsread.c (define_symbol): Use new macro
+ SYMBOL_INIT_DEMANGLED_NAME.
+ * symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list):
+ Use new macro SYMBOL_INIT_DEMANGLED_NAME.
+ * symfile.h (ADD_PSYMBOL_VT_TO_LIST): Use new macro
+ SYMBOL_INIT_DEMANGLED_NAME.
+ * symmisc.c (dump_msymbols, dump_symtab, print_partial_symbol):
+ SYMBOL_DEMANGLED_NAME now tests language itself.
+ * symtab.c (COMPLETION_LIST_ADD_SYMBOL): SYMBOL_DEMANGLED_NAME
+ now tests language itself.
+ * symtab.h (SYMBOL_CPLUS_DEMANGLED_NAME): New macro that does
+ what SYMBOL_DEMANGLED_NAME used to do, directly access the C++
+ mangled name member in the language dependent portion of a symbol.
+ * symtab.h (SYMBOL_DEMANGLED_NAME): New macro that returns the
+ mangled name member appropriate for a symbol's language.
+ * symtab.h (SYMBOL_SOURCE_NAME, SYMBOL_LINKAGE_NAME,
+ SYMBOL_MATCHES_NAME, SYMBOL_MATCHES_REGEXP):
+ SYMBOL_DEMANGLED_NAME now tests language itself.
+ * symtab.h (SYMBOL_INIT_LANGUAGE_SPECIFIC): New macro that
+ initializes language dependent portion of symbol.
+ * symtab.h (SYMBOL_INIT_DEMANGLED_NAME): New macro that
+ demangles and caches the demangled form of symbol names.
+ * utils.c (fputs_demangled, fprint_symbol): Use current language
+ to select an appropriate demangling algorithm.
+ * utils.c (strdup_demangled): Remove, no longer used.
+ * symtab.h (SYMBOL_CHILL_DEMANGLED_NAME): New macro that directly
+ access the Chill mangled name member in the language dependent
+ portion of a symbol.
+ * ch-lang.c (chill_demangle): New function, simple demangler.
+ * defs.h (chill_demangle): Add prototype.
+ * symtab.h (language_dependent_info): Add struct for Chill.
+
+For older changes see ChangeLog-1992
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/ChangeLog-1994 b/gdb/ChangeLog-1994
new file mode 100644
index 00000000000..68dbcb6fc36
--- /dev/null
+++ b/gdb/ChangeLog-1994
@@ -0,0 +1,5705 @@
+Fri Dec 30 17:58:55 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/m68k/tm-est.h: Remove cruft.
+
+
+Thu Dec 29 22:40:00 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * Allow up to 10 whitespace separated arguments to user defined
+ commands.
+ * top.c (struct user_args): Structure for holding arguments to
+ user defined commands.
+ (print_command_line): Delete unused "tmp_chain" variable. Clean
+ up flow control by having cases exit in the same manner.
+ Before executing a command or evaluating an expression, substitute
+ the current $arg0..$arg9 values if the command/expression uses them.
+ (arg_cleanup): New function.
+ (setup_user_args, locate_arg, insert_args): Likewise.
+ (execute_user_command): Allow arguments to user defined commands.
+
+ * Allow if/while commands to be used within a breakpoint command
+ list.
+ * breakpoint.c (bpstat_do_actions): Call execute_control_command
+ rather than execute_command (passes entire command structure rather
+ than just the command line text).
+ (breakpoint_1): Use "print_command_line" to print a breakpoint
+ command line (including control structures).
+ * gdbcmd.h (execute_control_command): Provide extern decl.
+ (print_command_line): Likewise.
+ * top.c (execute_control_command): No longer static.
+ (print_command_line): New function to recursively print a command
+ line, including control structures.
+
+Thu Dec 29 18:18:31 1994 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * hppa-tdep.c (pa_print_registers): Extract register values stored
+ in big endian format on big and little endian hosts.
+
+ * array-rom.c: Support for Array Tech LSI33k based RAID disk
+ controller board.
+ * configure.in: Recognize "mips*-*-ecoff*" rather than
+ "mips*-idt-ecoff*" so it'll work for the LSI33k.
+
+ * monitor.[ch], op50-rom.c, rom68k-rom.c, w89k-rom.c: Add support
+ to monitor config structure for supported baud rates for a target
+ and variable stop bits.
+ * monitor.c (monitor_fetch_register): Store register values in big
+ endian format on any host.
+
+Wed Dec 28 19:27:22 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (hppa_fix_call_dummy): Prefer import stubs over
+ export stubs and actual shared library functions so that lazy
+ binding works correctly. Try both __d_plt_call and __gcc_plt_call
+ trampolines for calling import stubs.
+
+Wed Dec 28 15:29:02 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ * a29k-tdep.c (pop_frame): Fix a variable name.
+
+Wed Dec 28 12:21:39 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (push_dummy_frame): Refine code to determine what
+ space ID to place in the stack & inf_status structure.
+ (hppa_pop_frame): Don't walk through trampoline code if popping a
+ call dummy frame.
+ (hppa_fix_call_dummy): Call the stack dummy directly if the
+ current PC is in a shared library.
+
+ * hppa-tdep.c (push_dummy_frame): Return type is void. Clear
+ in_syscall bit in flags. Don't depend on the PC queue registers
+ when in_syscall is set, they're not valid.
+ * config/pa/tm-hppa.h (PUSH_DUMMY_FRAME): Pass inf_status down to
+ push_dummy_frame.
+ (SR4_REGNUM): Define.
+
+ * hppa-tdep.c: Misc. lint changes.
+
+Tue Dec 27 12:32:43 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * breakpoint.c (watchpoint_check): Don't bother restoring the
+ "selected" frame anymore, it's not necessary. Initialize the
+ frame cache before trying to find the current frame in the frame
+ chain.
+
+ * somsolib.c (som_solib_add): Return without loading any shared
+ libraries if symfile_objfile is NULL.
+ (som_solib_create_inferior_hook): Likewise.
+
+Fri Dec 23 17:03:13 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * remote-est.c: New file supports EST-300 CPU32 background
+ mode ICE.
+ * remote-utils.c (sr_com): Call registers_changed.
+ * configure.in (m68*-*-est*): New configuration.
+ * config/m68k/tm-est.h: New file.
+
+Fri Dec 23 16:18:50 1994 Stu Grossman (grossman@cygnus.com)
+
+ * Makefile.in (CLIBS): Put LIBIBERTY last.
+
+Thu Dec 22 09:27:16 1994 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * ser-tcp.c (tcp_open): Cast to struct sockaddr when passing to
+ function which expects that.
+
+Thu Dec 22 13:25:33 1994 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * nlm/gdbserve.c, nlm/ppc.c, nlm/ppc.h: Don't try to use
+ ALTERNATE_MEM_FUNCS.
+
+Wed Dec 21 14:00:26 1994 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * monitor.c: Now supports xmodem as a remoteloadprotocol.
+
+Tue Dec 20 23:01:17 1994 Stu Grossman (grossman@cygnus.com)
+
+ * config/mips/xm-irix4.h, config/mips/xm-irix5.h: #define
+ _BSD_COMPAT to get reliable signal handling.
+
+Tue Dec 20 11:44:28 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * sparc-tdep.c, a29k-tdep.c, findvar.c (get_saved_register):
+ if !target_has_registers, call error().
+
+ * value.h: Remove obsolete comments about FRAME vs struct
+ frame_info *.
+
+
+Sun Dec 18 11:52:58 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * sparc-tdep.c (sparc_pop_frame): Remove erroneous extra argument
+ to write_register.
+
+Sat Dec 17 13:23:21 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * tm-sparc.c (EXTRA_FRAME_INFO): New field sp_offset.
+ * sparc-tdep.c (sparc_init_extra_frame_info): Set it.
+ (examine_prologue, sparc_init_extra_frame_info): Use ->frame plus
+ ->sp_offset to compute the address something is saved at, not
+ ->bottom.
+
+ * sparc-tdep.c (get_saved_register): New function.
+ * tm-sparc.h: Define GET_SAVED_REGISTER; don't define
+ FRAME_FIND_SAVED_REGS, HAVE_REGISTER_WINDOWS or REGISTER_IN_WINDOW_P.
+ * stack.c (frame_info): Add comment about what to do if
+ FRAME_FIND_SAVED_REGS is not defined.
+
+ * sparc-tdep.c (sparc_init_extra_frame_info): Set ->frame field
+ here. Get it right for flat frames.
+ * sparc-tdep.c (sparc_frame_chain): Instead of returning
+ meaningful value for ->frame field, just return dummy value.
+ This change is needed because the old code didn't deal with mixed
+ flat and non-flat frames.
+
+ * sparc-tdep.c (sparc_pop_frame): Write SP_REGNUM from
+ frame->frame, don't go through saved regs for this.
+
+ * sparc-tdep.c: Move guts of skip_prologue to new function
+ examine_prologue. Check for flat prologue and set is_flat.
+ Provide the caller with the information about what is saved where
+ if desired.
+ (skip_prologue, sparc_frame_find_saved_regs): Call examine_prologue.
+
+ * sparc-tdep.c: Replace union sparc_insn_layout and anonymous
+ union in isannulled, which won't work on a little-endian host,
+ with X_* macros.
+
+ * sparc-tdep.c (sparc_frame_saved_pc): If addr == 0, the saved PC
+ is still in %o7.
+
+ * config/sparc/tm-sparc.h: Define INIT_FRAME_PC and
+ INIT_FRAME_PC_FIRST.
+ * blockframe.c (get_prev_frame_info): Modify comments regarding
+ INIT_FRAME_PC_FIRST and the sparc.
+
+ * sparc-tdep.c (single_step): Use 4 not sizeof (long) for size of
+ instruction.
+
+Sat Dec 17 02:33:37 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * c-typeprint.c (c_type_print_base): Use `show' of -1 to print
+ the return type of methods to avoid infinite loops with anonymous
+ types.
+ * valops.c (search_struct_field): Handle anonymous unions.
+
+ * sparc-tdep.c (sunos4_skip_trampoline_code): New function
+ to correctly handle steps into -g compiled PIC objects in the
+ main executable.
+ * config/sparc/tm-sun4os4.h (SKIP_TRAMPOLINE_CODE):
+ Redefine to use sunos4_skip_trampoline_code.
+
+ * dwarfread.c (DWARF_REG_TO_REGNUM): Provide a default mapping
+ from DWARF to GDB register numbering.
+ * dwarfread.c (locval): Use DWARF_REG_TO_REGNUM to map the
+ register value.
+ * config/mips/tm-mipsv4.h (DWARF_REG_TO_REGNUM): Define.
+
+Fri Dec 16 10:56:29 1994 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * Makefile.in (uninstall): transform file names.
+
+Thu Dec 15 16:55:35 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ * defs.h: Include progress.h.
+ (QUIT): Call PROGRESS.
+ * main.c (main): Call START_PROGRESS and END_PROGRESS, break
+ usage message into shorter strings.
+ * source.c: Change long command help strings into concats of
+ shorter ones, for picky ANSI compilers.
+
+ * top.c (command_loop): For space usage display, show both
+ absolute size and the change from before command execution.
+
+Thu Dec 15 16:40:10 1994 Stu Grossman (grossman@cygnus.com)
+
+ * defs.h, main.c (gdb_fputs), top.c: Add stream arg to
+ fputs_unfiltered_hook.
+ * defs.h, top.c, utils.c (error): Add error_hook.
+
+Tue Dec 13 15:15:33 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ * breakpoint.c, infrun.c, printcmd.c: Change long command help
+ strings into concats of shorter ones, for picky ANSI compilers.
+
+Mon Dec 12 17:08:02 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ Sparc flat register window support.
+ * sparc-tdep.c (sparc_insn_layout): New union, defines layout of
+ instructions symbolically (used to be local to skip_prologue).
+ (sparc_init_extra_frame_info): New function.
+ (sparc_frame_chain): Add flat cases throughout.
+ (skip_prologue): Add recognition of flat prologues.
+ (sparc_frame_find_saved_regs): Add flat cases.
+ (sparc_pop_frame): Ditto.
+ * config/sparc/tm-sparc.h (EXTRA_FRAME_INFO): New slots.
+ (INIT_EXTRA_FRAME_INFO): Call sparc_init_extra_frame_info.
+ (PRINT_EXTRA_FRAME_INFO): Define.
+
+
+Mon Dec 12 13:06:59 1994 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * f-lang.c: Remove duplicate declaration of
+ builtin_type_f_integer, and only include it in the f_builtin_types
+ once.
+
+ * somread.c (som_symfile_read): Just assign to objfile->obj_private,
+ not OBJ_UNWIND_INFO. Assigning to a cast is a GCC-ism which
+ the HP compiler doesn't like.
+
+
+Fri Dec 9 15:50:05 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.c (remote_wait): Pass string instead of char to strcpy.
+
+Fri Dec 9 04:43:17 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbserver/low-lynx.c (mywait): Remove debugging printf.
+
+Thu Dec 8 15:07:29 1994 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * frame.h: Restore pre-Nov 3 comments about FRAME_FP with minor
+ changes. They are correct, unlike the post-Nov 3 comment
+ (FRAME_FP doesn't have any machine-independent relationship with
+ FP_REGNUM or any other such notion of a "frame pointer").
+
+Wed Dec 7 14:50:54 1994 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * gdbserver/remote-utils.c (write_ok): Write "OK", not "Ok", to
+ match stubs and protocol spec.
+ * gdbserver/remote-utils.c (remote_open): Cast to struct sockaddr
+ when passing to function which expects that.
+
+ The following changes aren't quite enough to make things work with
+ LynxOS (apprently kernel problems).
+ * infrun.c (wait_for_inferior): When resuming new thread, pass pid
+ not -1 for remote case.
+ * thread.c (info_threads_command): Give error if !target_has_stack.
+ * infrun.c (start_remote): Call init_thread_list.
+ * thread.c (info_threads_command): Don't call kill for remote
+ debugging target.
+ * target.c (normal_pid_to_str): Print "thread" not "process" for
+ remote.
+ * remote.c, gdbserver/*: Add 'H', 'S', and 'C' requests, 'X'
+ response, and `thread' part of 'T' response.
+ * gdbserver/*: If program exits, send packet to GDB before
+ exiting. Handle termination with a signal the same as exiting
+ with an exitstatus.
+ * remote.c: Don't try to kill program after getting an 'X'
+ response.
+ * infrun.c (wait_for_inferior): Add comment about kill versus mourn.
+
+Thu Dec 8 12:37:38 1994 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * config/pa/tm-pro.h tm-hppap.h, hppapro.mt: Rename tm-hppap.h to
+ tm-pro.h.
+
+Wed Dec 7 18:22:59 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ * source.c: Various cosmetic changes.
+ (forward_search_command): Handle very long source lines correctly.
+
+Wed Dec 7 13:21:47 1994 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * hppa-tdep.c: Use GDB_TARGET_IS_PA_ELF so SOM target support will
+ stop being linked in.
+
+ * config/pa/tm-hppap.h: New file. Set GDB_TARGET_IS_PA_ELF,
+ otherwise it looks like BSD-ELF.
+
+Mon Dec 5 21:43:52 1994 Stu Grossman (grossman@cygnus.com)
+
+ * inftarg.c: include <sys/types.h> to get def of pid_t.
+
+Fri Dec 2 15:03:07 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ * solib.c (auto_solib_add_at_startup): New global.
+ (solib_create_inferior_hook): Call solib_add only if
+ auto_solib_add_at_startup is nonzero.
+ (_initialize_solib): New command "set auto-solib-add".
+
+Fri Dec 2 12:52:04 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * parse.c (msymbol_addr_type): Replaced by
+ lookup_pointer_type (builtin_type_void).
+
+ * printcmd.c (_initialize_printcmd): Give examine_*_type
+ a name for `ptype $_'.
+
+Fri Dec 2 12:52:04 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * printcmd.c (print_formatted): Call val_print_string directly,
+ rather than via value_print.
+
+Wed Nov 30 22:27:27 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * somsolib.c (som_solib_get_got_by_pc): New function.
+ * somsolib.h (som_solib_get_got_by_pc): Add extern decl.
+ * hppa-tdep.c (hppa_fix_call_dummy): Handle case where FUN is the
+ function's export stub or real address in a shared library.
+
+Tue Nov 29 13:40:25 1994 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * config/i386/nbsd.mh (REGEX, REGEX1): No longer define.
+
+ * configure.in (i[345]86-*-freebsd*): New configuration.
+ * config/i386/{fbsd.mh,fbsd.mt,nm-fbsd.h}: New files.
+
+Tue Nov 29 12:23:25 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * top.c (read_next_line): Pass annotation suffix "commands"
+ instead of "command", matches documentation.
+
+Mon Nov 28 14:53:21 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/a29k/tm-a29k.h (setup_arbitrary_frame): Replace
+ FRAME_ADDR with CORE_ADDR in prototype.
+
+ * top.c (command_line_input): If annotation suffix is NULL,
+ replace it with an empty string.
+ (read_next_line): Pass "command" as annotation suffix to
+ command_line_input.
+
+Mon Nov 28 11:03:14 1994 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * config/rs6000/tm-rs6000.h (setpgrp): move defn from here...
+ * config/rs6000/xm-rs6000.h: ...to here.
+
+
+Fri Nov 25 21:26:02 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * tm-hppa.h (skip_trampoline_code): Add extern decl.
+ * hppa-tdep.c (hppa_pop_frame): Silently restart the inferior and
+ allow it to execute any return path trampoline code. Stop the
+ inferior and give the user control when the trampoline has
+ finished executing.
+ (in_solib_call_trampoline): Handle export stubs which also perform
+ parameter relocations.
+ (in_solib_return_trampoline): Likewise.
+
+Fri Nov 25 13:37:10 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * coffread.c, symfile.h (coff_getfilename): Make it static again.
+ * xcoffread.c (coff_getfilename): Use a static copy from
+ coffread.c, modified for accessing the static xcoff strtbl.
+
+Fri Nov 25 00:51:05 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (in_solib_call_trampoline): Recognize calls through
+ _sr4export and $$dyncall as trampolines. Likewise for long-call
+ stubs and parameter relocation stubs.
+ (in_solib_return_trampoline): Recognize a return trampoline for
+ return value relocation stubs.
+
+ * hpread.c: Include hp-symtab.h instead of hpux-symtab.h.
+ Various name changes to match those used by hp-symtab.h.
+
+Thu Nov 24 00:39:27 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * blockframe.c (find_pc_partial_function): Inhibit mst_trampoline
+ symbol special handling when INHIBIT_SUNSOLIB_TRANSFER_TABLE_HACK
+ is defined.
+ * infrun.c (IN_SOLIB_CALL_TRAMPOLINE): Renamed from
+ IN_SOLIB_TRAMPOLINE. All callers changed.
+ (IN_SOLIB_RETURN_TRAMPOLINE): Provide default definition.
+ (wait_for_inferior): Handle single stepping through trampolines on
+ return paths from shared libraries.
+ * config/pa/tm-hppa.h (IN_SOLIB_CALL_TRAMPOLINE): Use
+ in_solib_call_trampoline.
+ (IN_SOLIB_RETURN_TRAMPOLINE): Use in_solib_return_trampoline.
+ (INHIBIT_SUNSOLIB_TRANSFER_TABLE_HACK): Define.
+ * hppa-tdep.c (in_solib_call_trampoline): New function.
+ (in_solib_return_trampoline): New function.
+
+Wed Nov 23 21:43:03 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * tm-h8300.h (REMOTE_BREAKPOINT): Define.
+ * h8300-tdep.c (h8300_pop_frame): Remove redundant call.
+
+ * remote-e7000.c (HARD_BREAKPOINTS): Reenable.
+ (BC_BREAKPOINTS): Disable.
+ * sh-tdep.c (print_insn): Cope with big and little endian machines.
+ * sh/sh.mt: Use libsim.a
+ * sh/tm-sh.h (TARGET_BYTE_ORDER_SELECTABLE): New
+ (BREAKPOINT): Changed to be byteorder independent.
+
+Tue Nov 22 19:13:39 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ Maintenance commands to report time and space usage.
+ * main.c (display_time, display_space): New globals.
+ (main): Add argument --statistics to enable reporting, display
+ time and space after startup is done.
+ * maint.c (maintenance_time_display, maintenance_space_display):
+ New commands.
+ * top.c (command_loop): Display time and space after command
+ execution.
+
+ * top.c (pre_init_ui_hook): New global.
+ (gdb_init): If pre_init_ui_hook set, call before all other init.
+
+Tue Nov 22 10:25:59 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * a29k-tdep.c (examine_tag): Fix a bug in stack frame size.
+
+Sat Nov 19 03:10:51 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/i386/i386sol2.mh: Reenable core file support.
+
+ * symfile.c (deduce_language_from_filename): Treat .c++ as a
+ C++ extension.
+
+ * valops.c (destructor_name_p): Do not compare the template
+ part for template classes.
+
+Fri Nov 18 14:55:59 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * defs.h, infcmd.c (reg_names): Don't declare as constant.
+ * remote-mips.c (mips_open): Read and set the processor type.
+ * mips-tdep.c (mips_set_processor_type): Always return an int.
+
+Fri Nov 18 10:38:12 1994 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * nlm/alpha.c (strtol): Remove, it is provided by NetWare C library.
+ * nlm/gdbserve.def (strtol): Add to import list.
+ * nlm/fake_aio.c: Remove file, no longer used.
+
+ * Makefile.in (LD_FOR_TARGET, NLMCONV_FOR_TARGET): Remove.
+ * nlm/Makefile.in (gdbserve.O): Link with ${CC_FOR_TARGET}.
+ (LD_FOR_TARGET): Remove.
+
+Thu Nov 17 22:09:50 1994 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * monitor.h, monitor.c, w89k-rom.c, op50n-rom.c, idp-rom.c: Add
+ support for two variables used to control the load protocol and
+ conversion type.
+
+Thu Nov 17 17:51:12 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ Support for different MIPS IDT processor models.
+ * mips-tdep.c (mips_processor_type, tmp_mips_processor_type,
+ mips_generic_reg_names, mips_r3041_reg_names,
+ mips_r3051_reg_names, mips_r3081_reg_names,
+ mips_processor_type_table): New globals.
+ (mips_do_registers_info): Don't display register if name is empty.
+ (mips_set_processor_type_command): New command.
+ (mips_show_processor_type_command): New command.
+ (mips_set_processor_type): New function.
+ (mips_read_processor_type): New function.
+ * config/mips/tm-idt.h (DEFAULT_MIPS_TYPE): New macro.
+ * config/mips/tm-mips.h (DEFAULT_MIPS_TYPE): New macro.
+ (NUM_REGS): Increase to account for all CP0 registers.
+ (REGISTER_NAMES): Add empty names for CP0 registers.
+ (FIRST_EMBED_REGNUM, LAST_EMBED_REGNUM): Adjust.
+ (PRID_REGNUM): New macro.
+
+Wed Nov 16 16:41:52 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * README: Add warning about termcap in Ultrix and OSF/1.
+
+Wed Nov 16 15:28:29 1994 Rob Savoye (rob@cygnus.com)
+
+
+ * hppa-tdep.c: Remove including sys/dir.h from a target file.
+
+Wed Nov 16 10:31:27 1994 J.T. Conklin (jtc@cygnus.com)
+
+ * config/powerpc/gdbserve.mt (TDEPFILES): Remove fake_aio.o.
+
+ * nlm/gdbserve.c: Include <nwtypes.h> before other NetWare headers.
+ * nlm/ppc.c: Likewise.
+
+ * nlm/ppc.c (strtol): Remove, it is provided by NetWare C Library.
+ (StopBell): New function (stubbed out).
+
+Wed Nov 16 00:12:21 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (skip_trampoline_code): Handle shared library import
+ trampolines.
+
+Tue Nov 15 16:18:52 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * c-exp.y (yylex): Fix a bug in template scanning.
+
+Tue Nov 15 14:25:47 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * i386-stub.c, m68k-stub.c, sparc-stub.c, sparcl-stub.c: Mask out
+ the top bit returned by getDebugChar.
+
+Tue Nov 15 01:03:56 1994 Rob Savoye (rob@slipknot.cygnus.com)
+
+ * op50-rom.c, w89k-rom.c, monitor.c: Modify to usr two variables
+ to set remote load type and protocol.
+ * rom68k-rom.c: Add to_stop in target_ops.
+
+
+Sat Nov 12 21:55:47 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * somsolib.c: Add TODO list.
+ (som_solib_add): Immediately return if $SHLIB_INFO$ sections does
+ not exist or has size zero. Slightly simplify error handling.
+ Keep an internal list of all the loaded shared libraries and
+ various tidbits of information about the loaded shared libraries.
+ Build section tables for each loaded shared library and add those
+ tables to the core target if necessary.
+ (som_solib_create_inferior_hook): Force re-reading of shared
+ libraries at exec time.
+ (som_sharedlibrary_info_command): New function for dumping
+ information about the currently loaded shared libraries.
+ (_initialize_som_solib): New function.
+
+Sat Nov 12 02:26:50 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * Makefile.in (copying.o, f-exp.tab.o, dpx2-nat.o, dstread.o,
+ i386aix-nat.o, i386m3-nat.o, irix5-nat.o, lynx-nat.o, m3-nat.o,
+ mipsm3-nat.o, ns32km3-nat.o, remote-e7000.o, remote-os9k.o):
+ Add dependencies.
+ (copying.o, os9kread.o, remote.o): Update dependencies.
+
+ * valarith.c (value_sub): When subtracting pointers, only
+ check for a match of the pointed to element lengths.
+ Cast element length to LONGEST to obtain a signed result for
+ pointer subtractions.
+
+Fri Nov 11 10:51:07 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * ch-exp.y (yylex): Fix off-by-one error when converting string to
+ lowercase. Null terminate new string.
+
+ * hppa-tdep.c (rp_saved): Handle IMPORT stubs too.
+
+ * somsolib.c (som_solib_add): Check the value of __dld_flags, if
+ it indicates __dld_list is not valid return an error. If it
+ indicates that libraries were not mapped privately, issue a
+ warning.
+
+Thu Nov 10 23:17:45 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * symfile.c (syms_from_objfile): Only call find_lowest_section if
+ no ".text" section exists.
+
+Thu Nov 10 15:16:21 1994 Rob Savoye <rob@rtl.cygnus.com>
+
+ * rom68k-rom.c: New file. Replaces the old remote-mon.c and uses
+ the new generic ROM interface in monitor.c.
+ * config/m68k/monitor.mt: Use new ROM support.
+ * monitor.c: Add support for xmodem download protocol.
+
+Wed Nov 9 18:46:24 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * findvar.c (find_saved_register): Fix a frame variable name.
+ * infcmd.c (finish_command): Ditto.
+
+Tue Nov 8 13:20:14 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Remove "Watchpoints seem not entirely reliable, though
+ they haven't failed me recently." item--this old (4.6 at least)
+ item is too vague to be useful (some watchpoint bugs have been
+ fixed since then).
+ * TODO: Add explanation of "RPC interface" item.
+
+Mon Nov 7 22:25:21 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (read_unwind_info): Use "text_offset" for linker
+ stub unwind descriptors too.
+
+ * Enable backtracing from inside a SOM shared library back into
+ user code.
+ * hppa-tdep.c (internalize_unwinds): Accept and use new
+ "text_offset" argument for dynamic relocation of
+ region_{start,end} fields in the unwind descriptor.
+ (read_unwind_info): Pass text_offset to internalize unwinds.
+
+Mon Nov 7 14:34:42 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * m3-nat.c: Remove comments about arbitrary limit in
+ printf_filtered; that limit is gone.
+
+Mon Nov 7 00:27:16 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * Beginnings of SOM shared library support. Breakpoints and
+ single frame backtracing within the library only. Only works when
+ using the HPUX 9 dynamic linker. More functionality to be added
+ soon.
+
+ * somsolib.c, somsolib.h: New files.
+ * Makefile.in (HFILES_NO_SRCDIR): Add somsolib.h
+ (ALLDEPFILES): Add somsolib.c.
+ (somsolib.o): Add some dependencies.
+ * somread.c (som_symtab_read): Accept multiple section offsets.
+ All callers changed. Adjust all text symbols with the first
+ section offset.
+ * symfile.c (find_lowest_section): Enable this function. Add some
+ tie-breaking logic when sections have the same vma.
+ (syms_from_objfile): Use find_lowest_section rather than looking
+ for ".text" by name. Relax warning to only warn if the lowest
+ section is not a code section.
+ * config/pa/{hppabsd.mh, hppahpux.mh} (NATDEPFILES): Add somsolib.o
+ * config/pa/{nm-hppab.h, nm-hppah.h}: Include somsolib.h.
+
+Sun Nov 6 12:54:54 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * partial-stab.h (N_TEXT): Put back GDB_TARGET_IS_HPPA kludge,
+ it is still needed for GCC-2.6 compiled code.
+ * TODO (GDB_TARGET_IS_HPPA): Note this kludge can be nuked
+ sometime after GCC-2.7 has been released.
+
+ * hppa-tdep.c (frame_saved_pc): Mask off low two bits when
+ retrieving the PC from a signal handler caller. Fix thinko
+ in Stan's last change ("frame", should have been "frame->next").
+ If the next frame is a signal handler caller and it's a system
+ call which has entered the kernel ((PSW & 0x2) != 0), then the
+ saved pc is in %r2 instead of %r31.
+
+Fri Nov 4 23:47:07 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (hppa_frame_find_saved_regs): Change "frame" to
+ "frame_info" throughout.
+
+Fri Nov 4 16:26:59 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * sparcl-stub.c: get rid of defs.h.
+
+Fri Nov 4 13:11:54 1994 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * gdbserver/Makefile.in (MMALLOC_CFLAGS): Add -I${MMALLOC_DIR}.
+ Correct definition of MMALLOC_DIR to reflect fact this is
+ gdb/gdbserver/Makefile.in, not gdb/Makefile.in.
+
+ * gdbserver/server.c (main): After we kill the inferior in
+ response to a 'k' request, exit.
+
+ * remote.c (remote_kill): Use catch_errors when calling putpkt.
+ (putpkt): Return int, not void, to match catch_errors calling
+ convention.
+
+Fri Nov 4 10:52:38 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * rs6000-tdep.c (pop_frame): Correct a variable name.
+
+Fri Nov 4 05:43:35 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Re-write item about SIGINT handling to reflect the fact
+ that target_stop now exists.
+
+Thu Nov 3 15:19:17 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ Replace useless FRAME, FRAME_ADDR types with struct frame_info *
+ and CORE_ADDR, respectively.
+ * frame.h (FRAME, FRAME_INFO_ID, FRAME_ADDR): Remove.
+ * blockframe.c (get_frame_info): Remove.
+ * a29k-tdep.c, alpha-tdep.c, blockframe.c, breakpoint.c,
+ breakpoint.h, energize.c, findvar.c, gould-pinsn.c,
+ h8300-tdep.c, h8500-tdep.c, hppa-tdep.c, i386-tdep.c, i960-tdep.c,
+ infcmd.c, inferior.h, infrun.c, m68k-tdep.c, m88k-tdep.c,
+ mips-tdep.c, nindy-tdep.c, printcmd.c, pyr-tdep.c, rs6000-tdep.c,
+ sh-tdep.c, sparc-tdep.c, stack.c, valops.c, z8k-tdep.c,
+ config/a29k/tm-a29k.h, config/alpha/tm-alpha.h,
+ config/gould/tm-pn.h, config/h8300/tm-h8300.h,
+ config/h8500/tm-h8500.h, config/mips/tm-mips.h,
+ config/ns32k/tm-merlin.h, config/ns32k/tm-umax.h,
+ config/pyr/tm-pyr.h, config/sparc/tm-sparc.h): Replace FRAME with
+ struct frame_info * everywhere, replace FRAME_ADDR with CORE_ADDR,
+ rename variables consistently (using `frame' or `fi'), remove
+ calls to get_frame_info and FRAME_INFO_ID, remove comments about
+ FRAME and FRAME_ADDR cruftiness.
+
+Thu Nov 3 14:25:24 1994 Stu Grossman (grossman@cygnus.com)
+
+ * corelow.c, exec.c, inftarg.c, m3-nat.c, op50-rom.c, procfs.c,
+ remote-adapt.c, remote-e7000.c, remote-eb.c, remote-es.c,
+ remote-hms.c, remote-mips.c, remote-mm.c, remote-mon.c,
+ remote-nindy.c, remote-os9k.c, remote-pa.c, remote-sim.c,
+ remote-st.c, remote-udi.c, remote-vx.c, remote-z8k.c, remote.c,
+ w89k-rom.c, target.c, target.h: Add support for target_stop().
+
+Thu Nov 3 01:23:45 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * osfsolib.c (solib_map_sections, first_link_map_member,
+ next_link_map_member, xfer_link_map_member): Retrieve and use
+ shared library relocation offset from runtime loader structures.
+ Use libxproc.a routines to get a working version if
+ USE_LDR_ROUTINES is defined.
+ * README: Remove item about shared library relocation for
+ Alpha OSF/1.
+
+Wed Nov 2 15:05:39 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * c-exp.y (yylex): scan template names, and scan nested class
+ names.
+
+Wed Nov 2 11:01:55 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * nlm/Makefile.in: install gdbserve.nlm.
+
+
+Tue Nov 1 13:00:46 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * c-valprint.c (c_value_print): Check for plain literal `char'
+ target type when suppressing `(char *)' output for strings.
+
+Mon Oct 31 19:19:51 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * coffread.c (coff_symfile_init): Remove unused local abfd.
+ * utils.c [NO_MMALLOC] (mmalloc, mrealloc): Define and use size_t
+ instead of long, for compatibility with mmalloc.h.
+
+Sat Oct 29 02:40:40 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * top.c (line_completion_function): Renamed from
+ symbol_completion_function, takes the line buffer and the
+ point in the line buffer as additional arguments.
+ (readline_line_completion_function): New function, interface
+ between readline and line_completion_function.
+ (init_main): Use it.
+ (complete_command): Use line_completion_function instead of
+ abusing rl_line_buffer. Free completion strings after printing
+ them.
+ * symtab.c (completion_list_add_name): Recheck for duplicates
+ if we intend to add a modified symbol.
+
+ * gdbtypes.h (cplus_struct_type): nfn_fields_total no longer
+ includes the number of methods from the baseclasses.
+ * stabsread.c (attach_fn_fields_to_type): No longer add the
+ number of methods from the baseclasses to TYPE_NFN_FIELDS_TOTAL,
+ the baseclass type might not have been completely filled in yet.
+ * symtab.c (total_number_of_methods): New function to compute
+ the total number of methods for a type, including the methods
+ from baseclasses.
+ (decode_line_1): Use it instead of TYPE_NFN_FIELDS_TOTAL to
+ allocate the symbol array for find_methods.
+
+ * stabsread.c (scan_file_globals): Add default case to minimal
+ symbol type switch, to avoid gcc -Wall warnings.
+
+ * config/rs6000/tm-rs6000.h (INIT_EXTRA_FRAME_INFO):
+ Don't test for zero backchain pointer to recognize a signal
+ handler frame, if read() gets interrupted by a signal, the
+ backchain will be non zero.
+ (SIG_FRAME_FP_OFFSET): Move to here from rs6000-tdep.c,
+ improve comment.
+ (SIG_FRAME_PC_OFFSET): New definition.
+ (FRAME_SAVED_PC): Return saved pc from sigcontext if this
+ is a signal handler frame.
+ * rs6000-tdep.c (function_frame_info): Do not error out
+ if we can't access the instructions.
+
+ * config/rs6000/tm-rs6000.h (CONVERT_FROM_FUNC_PTR_ADDR):
+ New definition to get the function address from a function pointer.
+ * valops.c (find_function_addr): Use it when calling a user
+ function through a function pointer.
+
+Fri Oct 28 16:16:52 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in (MMALLOC_DIR): New definition.
+ (MMALLOC): Use MMALLOC_DIR.
+ (MMALLOC_CFLAGS): Look in MMALLOC_DIR for mmalloc.h.
+ (OPCODES): Remove gratuitous "./".
+ * defs.h (mmalloc.h): Include.
+ (mmalloc, mrealloc, etc): Remove decls.
+ (cplus_demangle, cplus_demangle_opname): Remove decls.
+
+Wed Oct 26 15:41:07 1994 Stu Grossman (grossman@cygnus.com)
+
+ * defs.h, main.c, top.c: Change sense and name of
+ no_windows variable. Now called use_windows, and defaults to off
+ (for compatibility).
+
+Wed Oct 26 12:20:53 1994 Jim Kingdon <kingdon@cygnus.com>
+
+ * coffread.c (coff_symtab_read): If we get the address from
+ target_lookup_symbol, set the section to -2 not SECT_OFF_BSS.
+ (coff_symtab_read): Set value and section of symbol that
+ process_coff_symbol returns.
+
+Tue Oct 25 09:53:04 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * config/i386/tm-nbsd.h: Enable longjmp support.
+
+Sat Oct 22 03:41:13 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * valarith.c (value_binop): Take care of ANSI `value preserving'
+ rule, which was not addressed by the previous change.
+
+ * rs6000-tdep.c (skip_prologue): Handle `mr r31,r1', which is
+ generated by gcc-2.6, as a synonym for `oril r31,r1,0'.
+
+ * TODO: Remove item about RS/6000 shared libraries.
+
+Thu Oct 20 17:35:45 1994 Stu Grossman (grossman@cygnus.com)
+
+ * defs.h, infrun.c (wait_for_inferior), top.c: Call
+ target_wait_hook to allow GUI to handle blocking for inferior. Call
+ call_command_hook in execute_command to provide means for wrapping
+ commands with GUI state change updates.
+
+ * infrun.c (wait_for_inferior): Make sure
+ through_sigtramp_breakpoint is non-null before deleting.
+
+Thu Oct 20 10:26:43 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * config/powerpc/ppc-nw.mt (TDEPFILES): Removed exec.o.
+
+Thu Oct 20 06:56:07 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (coffread.o): Depend on target.h.
+ (remote-vx.o): Depend on gdb-stabs.h objfiles.h symfile.h $(bfd_h).
+
+Wed Oct 19 22:49:31 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Fix typo.
+
+Wed Oct 19 11:32:15 1994 Jim Kingdon <kingdon@cygnus.com>
+
+ * objfiles.c (objfile_relocate): When relocating ->sections, use
+ objfile not symfile_objfile.
+
+ * symtab.h, minsyms.c (minsyms_sort): New function.
+ * objfiles.c (objfile_relocate): Call it.
+
+ * remote-vx.c (vx_add_symbols): Call breakpoint_re_set.
+
+ * objfiles.c, objfiles.h (objfile_to_front): New function.
+ * remote-vx.c (vx_add_symbols): Call it.
+
+ * coffread.c (coff_symtab_read): Handle common symbols the same
+ way that partial-stab.h does.
+
+Wed Oct 19 21:06:12 1994 Rob Savoye (rob@cirdan.cygnus.com)
+
+ * hppa-tdep.c: Remove include files a.out.h, ioctl.h, and
+ machine/psl.h. These are host files.
+
+Wed Oct 19 15:13:51 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * objfiles.h (struct objfile): Fix comment--minimal_symbol_count
+ does *not* include the terminating NULL msymbol.
+
+Tue Oct 18 20:53:29 1994 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * monitor.c (monitor_load_srec,monitor_make_srec): Add an asrecord
+ loader that reads files using BFD and converts it on the fly.
+
+Mon Oct 17 18:52:06 1994 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * monitor.c (set_loadtype_command): Fixed so it doesn't core dump.
+ * monitor.c (monitor_load): check the load type and load the file
+ accordingly. Default to gr_load_image().
+ * monitor.c (monitor_load_ascii_srec): Load an ascii file in
+ srecord format by downloading to the monitor.
+ * w89k-rom.c, op50n-rom.c: set supported load types.
+
+Mon Oct 17 10:29:08 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (ALLDEPFILES): Remove xcoffexec.c.
+ * Makefile.in: Remove xcoffexec.o rule.
+
+ * exec.c (exec_file_command): Add comment.
+
+ Fix data and bss relocation for VxWorks 5.1:
+ * remote-vx.c (vx_add_symbols): New function.
+ (vx_load_command, add_symbol_stub): Call it instead of
+ symbol_file_add.
+ (vx_wait): Remove comment which was wrong to useless.
+ * remote-vx.c: Reindent much of file.
+ * coffread.c (cs_to_section, find_targ_sec): New functions.
+ (process_coff_symbol): Set SYMBOL_SECTION to result
+ from cs_to_section.
+ (coff_symtab_read): Call cs_to_section and deal with result
+ rather than assuming sections are in a certain order. Deal with
+ BSS.
+ * coffread.c: Remove text_bfd_scnum variable.
+
+Sat Oct 15 16:55:48 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * corelow.c: Format to standard.
+ (core_close): Use name instead of bfd_filename.
+
+Fri Oct 14 10:29:08 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * exec.c (map_vmap): Cast return from xmalloc to its proper type,
+ not to PTR.
+
+ * symfile.c (reread_symbols): Include bfd_errmsg string in error
+ message if bfd_close fails.
+ * exec.c (exec_close), solib.c (clear_solib), corelow.c
+ (core_close), objfiles.c (free_objfile), irix5-nat.c
+ (clear_solib), osfsolib.c (clear_solib), remote-utils.c
+ (gr_load_image): Check for errors from bfd_close.
+ * solib.c (look_for_base), remote-utils.c (gr_load_image),
+ remote-udi.c (download), corelow.c (core_open), symfile.c
+ (symfile_bfd_open), symfile.c (generic_load): Add comment
+ regarding error from bfd_close.
+ * remote-udi.c (download), remote-utils.c (gr_load_image): Add
+ comment about bogus handling of errors from bfd_openr.
+ * exec.c (exec_close): Add comment regarding memory leak and
+ dangling reference to vp->name.
+
+Sat Oct 15 03:43:00 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * eval.c (evaluate_subexp): Make fnptr a LONGEST instead
+ of using longest_to_int.
+
+ * infcmd.c (run_stack_dummy): Reinstate set_current_frame call,
+ mips and alpha targets need the real breakpoint pc for
+ creating the breakpoint frame.
+
+ * stack.c (return_command): Cast return value to the return
+ type of the function from which we return.
+ * values.c (set_return_value): Pass VALUE_CONTENTS unmodified
+ to STORE_RETURN_VALUE.
+
+ * symtab.c (lookup_symbol): Remove search for `static mangled
+ symbols', the search for `static symbols' already looks for
+ mangled and demangled symbols via lookup_block_symbol.
+
+ * valarith.c (value_binop): Use ANSI C arithmetic conversions
+ when performing integral evaluations, implement BINOP_EQUAL and
+ BINOP_LESS.
+ (value_equal, value_less): Use value_binop to perform the
+ comparison if both operands have TYPE_CODE_INT.
+
+ * rs6000-tdep.c (pop_frame): Make sure all registers are valid,
+ as they are written back later. Handle sp restore for frameless
+ functions. Use fdata.nosavedpc instead of fdata.frameless to
+ determine if the pc has been saved.
+ (function_frame_info): Handle `mr r31,r1', which is generated by
+ gcc-2.6, as a synonym for `oril r31,r1,0'.
+ (skip_trampoline_code): Handle shared library trampolines.
+ * xcoffread.c (read_xcoff_symtabs): Record XMC_GL symbols with
+ their real name. Enables setting of breakpoints in shared libraries
+ before the executable is run.
+
+Fri Oct 14 19:39:47 1994 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * monitor.h, remote-mon.c: Hack up to so the old ROM monitor
+ interface code still works with the new ROM monitor
+ structures. Fake out a couple of fields.
+
+Fri Oct 14 14:54:37 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * h8500-tdep.c (target_read_sp, target_write_sp, target_read_pc,
+ target_write_pc, target_read_fp, target_write_fp): Rename to
+ h8500_read_sp, etc.
+ (h8500_read_pc, h8500_write_pc): Add pid argument.
+ * config/h8500/tm-h8500.h (TARGET_READ_SP, TARGET_WRITE_SP,
+ TARGET_READ_PC, TARGET_WRITE_PC, TARGET_READ_FP, TARGET_WRITE_FP):
+ Change to match functions above.
+
+Thu Oct 13 13:24:29 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * NEWS: Add item about if and while.
+
+ * .gdbinit: Restore `end'; it was not excess. Reindent
+ list-objfiles to make this clear. Comment out all of
+ list-objfiles because old gdb's choke on it.
+
+Wed Oct 12 23:19:08 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/mips/tm-bigmips64.h: Just define TARGET_BYTE_ORDER and
+ include tm-mips64.h.
+
+Wed Oct 12 18:02:17 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in (ANNOTATE_OBS): New definition.
+ (COMMON_OBS): Add exec.o.
+ (annotate.o): Remove extra compile rule.
+ * config/*/*.mh, config/*/*.mt: Remove exec.o from *DEPFILES lists
+ everywhere.
+
+ * .gdbinit: Remove excess `end'.
+
+ * exec.c: Merge in RS6000 support from xcoffexec.c.
+ (symfile.h, objfiles.h, xcoffsolib.h): Include.
+ (vmap): New global variable.
+ (exec_close): Close and free objects in vmap chain.
+ (exec_file_command) [IBM6000_TARGET]: Set up initial vmap.
+ (bfdsec_to_vmap, map_vmap): Moved here from xcoffexec.c.
+ (exec_files_info): Print vmap information.
+ * xcoffexec.c: Remove.
+ * config/rs6000/rs6000.mt, config/rs6000/rs6000lynx.mt
+ (TDEPFILES): Use exec.o instead of xcoffexec.o.
+ * TODO: Remove pertinent items.
+
+Wed Oct 12 10:08:19 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * partial-stab.h (N_TEXT): Delete GDB_TARGET_IS_HPPA kludge; they
+ are no longer needed as of gcc-2.6.0.
+
+Tue Oct 11 15:51:01 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * lynx-nat.c (child_wait): Correct handling of byte reversed SPARC
+ Lynx wait status.
+ (fetch_core_registers): Don't try to fetch a register if
+ regmap maps it to -1.
+ * sparc-tdep.c (sparc_frame_find_saved_regs): Use FRAME_SAVED_I0
+ and FRAME_SAVED_L0 when setting saved_regs_addr. SPARC Lynx
+ stores the registers in a weird order.
+
+Sat Oct 8 20:59:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * blockframe.c (reinit_frame_cache): Reinstate select_frame call
+ if inferior_pid is nonzero.
+
+Sat Oct 8 04:27:21 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ Speed up GDB startup time by not demangling partial symbols.
+ * symfile.h (ADD_PSYMBOL_VT_TO_LIST),
+ symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list):
+ No longer demangle partial symbols.
+ * symtab.c (lookup_symbol, list_symbols): Handle mangled
+ variables, e.g. C++ static members, via the minimal symbols.
+
+ Handle reordered functions in an objfile, for Irix 5.2 shared
+ libraries.
+ * objfiles.h (OBJF_REORDERED): New bit in the objfile flags,
+ set if the functions in an objfile are reordered.
+ * mdebugread.c (parse_partial_symbols): Detect reordered
+ functions in an objfile.
+ * symtab.c (find_pc_psymtab, find_pc_symtab): Use expensive
+ lookup algorithm if the functions in the objfile are reordered.
+
+ * xcoffexec.c (exec_close): If the current target has a copy
+ of the exec_ops sections, reflect the freeing of the sections
+ in current_target.
+
+ * valops.c (call_function_by_hand): Use `sizeof dummy1', not
+ `sizeof dummy', for constructing the call dummy code.
+
+ * config/sparc/tm-sparc.h: Add PARAMS declarations to all
+ function declarations.
+ * sparc-tdep.c (sparc_pop_frame): Cast result of
+ read_memory_integer to CORE_ADDR when passing it to PC_ADJUST.
+
+ * irix5-nat.c (enable_break): Set breakpoint at the entry point
+ of the executable, to handle the case where main resides in a
+ shared library.
+ * irix5-nat.c (solib_create_inferior_hook): Reset stop_soon_quietly
+ after shared library symbol reading, to get rid of a warning from
+ heuristic_proc_start if the startup code has no symbolic debug info.
+
+ * breakpoint.h (struct breakpoint): Add new fields language
+ and input_radix, to enable breakpoint resetting with the
+ proper language and radix.
+ * breakpoint.c (set_raw_breakpoint): Initialize them.
+ (breakpoint_re_set_one): Use them when resetting the breakpoint.
+ (breakpoint_re_set): Preserve current language and input_radix
+ across breakpoint_re_set_one calls.
+
+ * symtab.c (decode_line_1): Do not build a canonical line
+ specification for `*expr' line specifications.
+
+ * breakpoint.h (bpstat_stop_status): Fix prototype declaration.
+
+Fri Oct 7 08:48:18 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ The point of these changes is to avoid reading the frame pointer
+ and stack pointer during stepping, to speed things up.
+ A. Changes to not select a frame until we need a selected frame:
+ * blockframe.c (flush_cached_frames): Call select_frame (NULL, -1).
+ * infrun.c (wait_for_inferior): Move call to select_frame back to
+ normal_stop. This reverts a change of 13 Apr 94 (it says Jeff
+ Law, but the change was my idea); the only reason for that change
+ was so we could save and restore the selected frame in
+ wait_for_inferior, and now that flush_cached frames clears the
+ selected frame, that should work OK now.
+ B. Changes to not create a current_frame until we need one:
+ * blockframe.c (get_current_frame): If current_frame is NULL, try
+ to create an innermost frame.
+ * sparc-tdep.c (sparc_pop_frame), infcmd.c (run-stack_dummy),
+ infrun.c (wait_for_inferior), thread.c (thread_switch),
+ convex-tdep.c (set_thread_command), a29k-tdep.c (pop_frame),
+ alpha-tdep.c (alpha_pop_frame), convex-xdep.c (core_file_command),
+ h8300-tdep.c (h8300_pop_frame), h8500-tdep.c (h8300_pop_frame),
+ hppa-tdep.c (hppa_pop_frame), i386-tdep.c (i386_pop_frame),
+ i960-tdep.c (pop_frame), m68k-tdep.c
+ (m68k_pop_frame), mips-tdep.c (mips_pop_frame), rs6000-tdep.c
+ (push_dummy_frame, pop_dummy_frame, pop_frame), sh-tdep.c
+ (pop_frame), config/arm/tm-arm.h (POP_FRAME),
+ config/convex/tm-convex.h (POP_FRAME), config/gould/tm-pn.h
+ (POP_FRAME), config/ns32k/tm-merlin.h (POP_FRAME),
+ config/ns32k/tm-umax.h (POP_FRAME), config/tahoe/tm-tahoe.h
+ (POP_FRAME), config/vax/tm-vax.h (POP_FRAME): Don't
+ call create_new_frame.
+ * corelow.c (core_open), altos-xdep.c (core_file_command),
+ arm-xdep.c (core_file_command), gould-xdep.c (core_file_command),
+ m3-nat.c (select_thread), sun386-nat.c (core_file_command),
+ umax-xdep.c (core_file_command): Don't call create_new_frame; do
+ call flush_cached_frames.
+ * blockframe.c (reinit_frame_cache): Don't call create_new_frame
+ or select_frame.
+ C. Changes to get rid of stop_frame_address and instead only
+ fetch the frame pointer when we need it.
+ * breakpoint.c (bpstat_stop_status): Remove argument
+ frame_address; use FRAME_FP (get_current_frame ()).
+ * infrun.c (wait_for_inferior): Don't pass frame pointer to
+ bpstat_stop_status.
+ * infrun.c (wait_for_inferior): Use FRAME_FP (get_current_frame
+ ()) instead of stop_frame_address.
+ * infrun.c (save_inferior_status, restore_inferior_status),
+ inferior.h (struct inferior_status): Don't save and restore
+ stop_frame_address.
+ * inferior.h, infcmd.c, thread.c (thread_switch), m3-nat.c
+ (select_thread): Remove stop_frame_address and uses thereof.
+ D. Same thing for the stack pointer.
+ * infrun.c (wait_for_inferior): Remove stop_sp and replace
+ uses thereof with read_sp ().
+ E. Change to eliminate one nasty little spot where we were
+ wanting to know the frame pointer from before the current step
+ (idea from GDB 3.5, which saved my ass, because my other ideas of
+ how to fix it were very baroque).
+ * infrun.c: Remove prev_frame_address.
+ * infrun.c (wait_for_inferior, step_over_function): Use
+ step_frame_address instead of prev_frame_address.
+ F. Same basic idea for the stack pointer.
+ * inferior.h, infcmd.c: New variable step_sp.
+ * infcmd.c (step_1, until_next_command): Set it.
+ * infrun.c: Remove prev_sp and replace uses by step_sp.
+ * infrun.c (wait_for_inferior): If we get out of the step
+ range, then set step_sp to the current stack pointer before we
+ start going again.
+
+Fri Oct 7 12:17:17 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * top.c (target_byte_order_auto): New static variable.
+ (set_endian): Mention that ``auto'' is permitted.
+ (set_endian_auto): New static function.
+ (show_endian): Change message based on target_byte_order_auto.
+ (set_endian_from_file): New function.
+ (init_main): Add command ``auto'' to endianlist.
+ * exec.c (exec_file_command): Call set_endian_from_file.
+ * defs.h (set_endian_from_file): Declare.
+
+Thu Oct 6 18:10:41 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * nlm/i386.c (flush_i_cache): New function, does nothing.
+ (frame_to_registers, registers_to_frame, set_step_traps,
+ clear_step_traps, do_status): Make non-static.
+
+Thu Oct 6 12:26:42 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/mips/tm-mips.h (GDB_TARGET_IS_MIPS64): If not already
+ defined, define as 0.
+ (FIX_CALL_DUMMY): Rewrite to remove presumption that host and
+ target are similar.
+ * config/mips/tm-idt.h (TARGET_BYTE_ORDER_SELECTABLE): Define.
+ * config/mips/tm-idtl.h (TARGET_BYTE_ORDER_SELECTABLE): Define.
+ * config/mips/tm-idt64.h (TARGET_BYTE_ORDER_SELECTABLE): Define.
+ (BREAKPOINT): Remove definition.
+ * config/mips/tm-idtl64.h (TARGET_BYTE_ORDER_SELECTABLE): Define.
+ (BREAKPOINT): Remove definition.
+ * config/mips/tm-mips64.h (GDB_TARGET_IS_MIPS64): Define with a
+ value of 1, rather than without a value.
+ * config/mips/tm-bigmips64.h (GDB_TARGET_IS_MIPS64): Likewise.
+ * mips-tdep.c: Rewrite uses of GDB_TARGET_IS_MIPS64 to switch at
+ run time rather than at compile time.
+
+ * remote-mips.c (break_insn): Remove.
+ (BREAK_INSN, BREAK_INSN_SIZE): Define.
+ (mips_insert_breakpoint): Use BREAK_INSN, not break_insn.
+ (mips_remove_breakpoint): Likewise.
+
+ * defs.h: If TARGET_BYTE_ORDER_SELECTABLE is defined by tm.h,
+ define TARGET_BYTE_ORDER as target_byte_order, and declare
+ target_byte_order as an extern int, and define BITS_BIG_ENDIAN as
+ a test of TARGET_BYTE_ORDER.
+ * top.c: Several additions if TARGET_BYTE_ORDER_SELECTABLE is
+ defined:
+ (endianlist, target_byte_order): New variables.
+ (set_endian, set_endian_big, set_endian_little): New functions.
+ (show_endian): New function.
+ (init_cmd_lists): Initialize endianlist.
+ (init_main): Add commands ``set endian big'', ``set endian
+ little'', and ``show endian''.
+ * a29k-pinsn.c: Rewrite uses of TARGET_BYTE_ORDER and
+ BITS_BIG_ENDIAN to switch at run time rather than at compile time.
+ * coffread.c, dwarfread.c, findvar.c, mips-tdep.c: Likewise.
+ * remote-os9k.c, stabsread.c, valarith.c, valprint.c: Likewise.
+ * values.c: Likewise.
+
+Wed Oct 5 11:41:24 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * nlm/configure.in: ${gdb_host_cpu} defaults to ${host_cpu}.
+
+ * nlm/Makefile.in: Get rid of NWINCLUDES.
+ * config/{alpha,powerpc}/gdbserve.mt: Remove NWINCLUDES.
+ User should now configure with --with-headers.
+
+Mon Oct 3 07:48:34 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbserver/server.c (main): Silently accept all unrecognized
+ requests and send back a zero length acknowledge. That is what
+ *-stub.c do and is what remote.c expects.
+
+Mon Oct 3 05:11:47 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * corelow.c (core_open): Copy the modified to_sections_end
+ vector from current_target to core_ops too.
+
+ * gdbserver/server.c (main): Silently accept query requests
+ and send back a zero length acknowledge.
+
+Fri Sep 30 17:17:21 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * nlm/Makefile.in: Don't define NWINCLUDES.
+ * config/{alpha,powerpc}/gdbserve.mt: define NWINCLUDES.
+
+Fri Sep 30 15:59:55 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbserver/low-lynx.c (create_inferior): Pass all 4 args to ptrace.
+
+Fri Sep 30 06:42:42 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * lynx-nat.c (child_wait): Use status.w_status, not status, in
+ arithmetic. status is a `union wait'.
+
+ * config/nm-lynx.h (PTRACE_ARG3_TYPE): Define to int, not char *.
+
+ * lynx-nat.c (child_wait): Pass fourth argument to ptrace.
+
+Thu Sep 29 08:22:27 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * xcoffread.c (read_xcoff_symtab): Fix comment for yesterday's change.
+
+Wed Sep 28 17:48:18 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * coffread.c (complete_symtab): If last_source_file is set upon
+ entry, free it.
+
+Wed Sep 28 08:59:14 1994 Jim Kingdon (kingdon@cygnus.com)
+
+ * xcoffread.c (read_xcoff_symtab, case C_FILE):
+ Set main_aux before using it.
+
+ * xcoffexec.c (exec_close): If quitting, don't call clear_symtab_users.
+
+ * xcoffread.c (read_xcoff_symtab): Process XTY_LD symbols we were
+ ignoring before. But continue to ignore XMC_DS.
+
+Wed Sep 28 00:35:23 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c (hpread_read_array_type): Do not change the type code
+ to TYPE_CODE_PTR for "char foo[]". Just make it a zero length
+ array type.
+
+ * hpread.c (hpread_type_translate): Handle T_UNS_LONG types with
+ lengths other than 32bits (HP C 9.69 represents an "unsigned char"
+ as an T_UNS_LONG with length 8).
+
+ * hpread.c (struct hpread_symfile_info): Delete have_module field
+ and accessor macro. Minor indentation fix.
+ (hpread_build_psymtabs, case K_MODULE): Only start a new psymtab
+ and reset state variables have_name & texthigh if pst is NULL.
+ (hpread_build_psymtabs, case K_SRCFILE): Only reset the name of a
+ partial symbol table if pst is non-NULL. If pst is NULL, then
+ start a new psymtab.
+ (hpread_process_one_debug_symbol, case K_MODULE): Now empty.
+ (hpread_process_one_debug_symbol, case K_SRCFILE): Simplify and
+ correct handling of subfiles.
+
+Mon Sep 26 02:59:00 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * defs.h (misc_command_type): Remove trailing comma from
+ enumerator list.
+
+Sun Sep 25 23:19:58 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (frame_saved_pc): Fix thinko in code to dig saved pc
+ out of an interrupt frame.
+
+Sun Sep 25 12:50:17 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * infcmd.c (do_registers_info) [INVALID_FLOAT]: Only use if
+ defined.
+ * values.c (unpack_double) [INVALID_FLOAT]: Ditto.
+ * mips-tdep.c (mips_print_register): Don't test float validity.
+ * config/a29k/tm-a29k.h, config/alpha/tm-alpha.h,
+ config/arm/tm-arm.h, config/convex/tm-convex.h,
+ config/h8300/tm-h8300.h, config/h8500/tm-h8500.h,
+ config/i386/tm-i386v.h, config/i386/tm-sun386.h,
+ config/i960/tm-i960.h, config/m68k/tm-m68k.h,
+ config/m88k/tm-m88k.h, config/mips/tm-mips.h,
+ config/ns32k/tm-merlin.h, config/ns32k/tm-nbsd.h,
+ config/ns32k/tm-ns32km3.h, config/ns32k/tm-umax.h,
+ config/pa/tm-hppa.h, config/pyr/tm-pyr.h,
+ config/rs6000/tm-rs6000.h, config/sh/tm-sh.h,
+ config/sparc/tm-sparc.h, config/z8k/tm-z8k.h (INVALID_FLOAT):
+ Remove definition.
+
+Sun Sep 25 06:07:37 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Remove item about adding general multi-threaded stuff;
+ this is done.
+ Remove item about specifying arbitrary locations of stack frames
+ (this works on some machines).
+ Remove item about debugging functions without a frame pointer
+ (this works on some machines).
+ Remove item about re-writing macros which handle frame chaining and
+ frameless functions. They have been re-written at least once
+ since that item was written.
+ Remove item about gdb catching SIGINT when attached; this is done.
+ Remove item about having list_command not read symbols--why bother?
+
+Sat Sep 24 17:40:10 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * TODO: Append contents of Projects file.
+ * Projects: Remove.
+
+Sat Sep 24 01:47:25 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * corelow.c (add_solib_stub): Remove copying of to_sections,
+ pass current_target to SOLIB_ADD. The Sep 10 change failed
+ if SOLIB_ADD errored out, or if SOLIB_ADD was trying to access
+ target memory.
+ * corelow.c (core_open): After reading the shared libraries,
+ copy the modified to_sections vector from current_target to
+ core_ops, so that core_close can free it later.
+ * config/rs6000/nm-rs6000.h, rs6000-nat.c (xcoff_relocate_core):
+ Pass down target parameter from SOLIB_ADD and use it instead of
+ directly accessing core_ops.
+
+Fri Sep 23 14:58:49 1994 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * solib.c: *BSD systems need <a.out.h> to be included before
+ <link.h>.
+
+ * i386b-nat.c: Add i386_float_info(), etc.
+ * config/i386/nm-nbsd.h: #define FLOAT_INFO.
+
+ * config/nm-nbsd.h: New file, for generic NetBSD native support.
+ * config/i386/nm-nbsd.h: Use it.
+ * config/sparc/nm-nbsd.h: Use it.
+ * config/ns32k/nm-nbsd.h: Use it.
+
+ * configure.in (i386-*-netbsd): Use config/i386/nbsd.m[ht].
+ (ns32k-*-netbsd): Use config/ns32k/nbsd.m[ht].
+ * config/i386/{nbsd.mh,nbsd.mt,nm-nbsd.h,tm-nbsd.h,xm-nbsd.h}:
+ New files, support for NetBSD/i386.
+ * config/ns32k/{nbsd.mh,nbsd.mh,nm-nbsd.h,tm-nbsd.h,xm-nbsd.h}:
+ New files, support for NetBSD/ns32k.
+
+Tue Sep 20 11:34:27 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * .gdbinit: Add list-objfiles command.
+
+ * TODO: Reword item regarding NO_STD_REGS.
+
+ * coffread.c (record_minimal_symbol, coff_read_enum_type,
+ coff_read_struct_type): Allocate on symbol_obstack, not directly
+ via malloc/savestring.
+
+Tue Sep 20 15:42:02 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * TODO: Add more items.
+ * tests: Remove the directory and all of its (obsolete) contents.
+
+Tue Sep 20 11:34:27 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * coffread.c (init_stringtab): When copying length to stringtab,
+ use target format, not host format, since that is what the rest of
+ the code assumes.
+
+Mon Sep 19 15:48:10 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * Makefile.in: Removed prelude.o, i386-nlmstub.o, nlmstub.o,
+ nlmstub.nlm, and nlmstub targets. Removed NWSOURCE and
+ NWINCLUDES definitions.
+ * i386-nlmstub.c: Removed.
+
+Mon Sep 19 07:48:36 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dbxread.c (read_dbx_dynamic_symtab): Cast bfd_asymbol_name to
+ char * (from const char *) before assigning. Don't save string we
+ pass to record_minimal_symbol (it already saves it).
+
+
+Sat Sep 17 02:26:58 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * cp-valprint.c (static_field_print): New variable, controls
+ printing of static members.
+ (_initialize_cp_valprint): New print set subcommand
+ "static-members". Turn on printing of static members by default.
+ (cp_print_value_fields): Print static members if necessary.
+
+ * solib.c: Remove inclusion of libelf.h and elf/mips.h.
+ (elf_locate_base): Use only standard BFD functions to collect
+ information about the .dynamic section. Check for DT_MIPS_RLD_MAP
+ tag only if it got defined via the inclusion of <link.h>.
+
+ * f-exp.y: Write block for OP_VAR_VALUE.
+ * f-valprint.c (info_common_command): Handle `info common'
+ without an argument correctly.
+
+ * c-typeprint.c (c_type_print_base): Handle template constructors.
+ * symtab.c (gdb_mangle_name): Handle template method mangling,
+ get rid of GCC_MANGLE_BUG code, which only applied to gcc-2.2.2.
+
+Fri Sep 16 16:06:08 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * gdbtypes.h (TYPE_INDEX_TYPE): New macro.
+ * ch-typeprint.c, ch-valprint.c: Use TYPE_INDEX_TYPE.
+ * ch-valprint.c (chill_val_print): Pass index type directly
+ (instead of its TYPE_TARGET_TYPE) to print_type_scalar.
+ * stabsread.c (read_type): Don't set TYPE_FLAG_TARGET_STUB
+ if the index type is a stub.
+
+Fri Sep 16 17:18:44 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/i386/{i386aix.mh, i386bsd.mh, i386lynx.mh, i386sco.mh,
+ i386sco4.mh, i386sol2.mh, i386v.mh, i386v32.mh, i386v4.mh,
+ ncr3000.mh, ptx.mh, ptx4.mh}, config/m68k/{altos.mh, apollo68v.mh,
+ delta68.mh, dpx2.mh, hp300bsd.mh, hp300hpux.mh, m68klynx.mh,
+ m68kv4.mh}, config/m88k/{delta88.mh, delta88v4.mh},
+ config/mips/riscos.mh, config/pa/hppahpux.mh,
+ config/rs6000/rs6000lynx.mh, config/sparc/{sparclynx.mh,
+ sun4sol2.mh}, config/tahoe/tahoe.mh, config/vax/{vaxbsd.mh,
+ vaxult.mh, vaxult2.mh} (REGEX, REGEX1, SYSV_DEFINE): No longer
+ define.
+ * config/i386/i386sco4.mh (MUNCH_DEFINE): No longer define.
+
+Fri Sep 16 15:40:34 1994 Stu Grossman (grossman@cygnus.com)
+
+ * defs.h (QUIT): Call interactive_hook to allow GUI to interrupt.
+ Also, add decl for symtab_to_filename.
+ * source.c (symtab_to_filename): New. Returns the file
+ associated with a symtab.
+ * top.c: Define interactive_hook. Called during QUIT to animate
+ the GUI.
+
+Fri Sep 16 00:14:40 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * stabsread.c (read_type): Handle stub types for bitstrings.
+ * stabsread.c (read_array_type): Check for stub domain type
+ using TYPE_FLAG_STUB, not its length.
+ * gdbtypes.c (create_set_type): Handle a stub domain type.
+
+ * ch-exp.y: Get rid of some extra non-terminals, and move
+ their rules into primitive_value.
+ * parser-defs.h: Add comment about unary postfix operators.
+ * ch-lang.c (chill_op_print_tab): Add '->', postfix and prefix.
+ * expprint.c (print_subexp): Recognize unary postfix operator.
+
+Wed Sep 14 18:27:42 1994 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * remote-hms.c: use remote_debug instead of hms_silent toggle.
+ Add warnings about depreciation of `snoop' cmd.
+
+Wed Sep 14 18:18:58 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * remote-hms.c (hms_read_inferior_memory): Cope when
+ target sends both \r and \n.
+
+Wed Sep 14 17:14:57 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * remote-mips.c (mips_error): Place NORETURN macro correctly.
+ * TODO: Add item about START_INFERIOR_TRAPS_EXPECTED.
+
+Wed Sep 14 14:26:21 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * xcoffread.c (read_xcoff_symtab): Fix obsolete comment about
+ mst_solib_trampoline.
+
+ * f-valprint.c (f_val_print): Change cast of valaddr from
+ CORE_ADDR * to char **, since that is how it is used.
+
+ * dbxread.c (read_dbx_dynamic_symtab): Save copy of symbol names
+ using obsavestring, and pass that to prim_record_minimal_symbol.
+ Having the objfile point to bfd_asymbol_name directly doesn't work
+ if we save and restore a mapped symbol file.
+
+
+Tue Sep 13 18:23:26 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * w89k-rom.c, op50-rom.c, monitor.c, config/pa/hppapro.mt: New files
+ to add a generic ROM monitor interface, and support file for the
+ WinBond W89K and the Oki OP50N PA based target boards.
+
+
+Sun Sep 11 22:34:57 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/pa/tm-hppa.h (REGISTER_NAMES): Use r26-r23 for arg0-arg3.
+
+Sun Sep 11 04:36:47 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * irix5-nat.c, osfsolib.c, solib.c (solib_add): Simplify last
+ change by replacing `symbols_added' with `so_last'.
+ * mdebugread.c (parse_external, parse_partial_symbols): Ignore
+ global common symbols, they will be resolved by the runtime loader.
+ * mdebugread.c (parse_symbol, parse_partial_symbols, cross_ref):
+ Handle scSCommon like scCommon symbols.
+
+Sat Sep 10 01:43:28 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * corelow.c (add_solib_stub): Copy to_sections changes from
+ core_ops to current_target after adding the shared libraries.
+ * partial-stab.h (N_EXCL), dbxread.c (add_old_header_file,
+ find_corresponding_bincl_psymtab): Change `repeated header not seen'
+ error to a complaint, simplify complaint.
+ * procfs.c (signalname, errnoname): Make `name' const.
+ * symfile.c (reread_symbols): Use filename from old BFD to
+ reopen the objfile.
+ * values.c (record_latest_value): Don't record value in the
+ history chain until we are sure there won't be an error.
+
+Fri Sep 9 15:52:09 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * nlm/Makefile.in: remove MMALLOC, READLINE, TERMCAP, and other
+ cruft.
+
+ * config/i386/gdbserve.mt: New file, defs for i386 nlm stub.
+
+Thu Sep 8 17:14:43 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * remote.c (fromhex): Make error more explicit.
+ (read_frame): Don't print bad checksum information unless
+ remote_debugging. Don't use repeat count unless it's > 0.
+ * remote-e7000.c (expect): When echoing, ignore multiple newlines.
+ (e7000_insert_breakpoint, e7000_remove_breakpoint, target_ops):
+ Optionally cope with BC style breakpoints.
+ (e7000_command): After command send directly to the E7000 mark
+ registers as changed.
+ (why_stop, e7000_wait: Understand BC style stop condition.
+ * sh-tdep.c (sh_skip_prologue): Understand more complicated
+ sequences. (frame_find_saved_regs): Likewise.
+ * config/h8500/tm-h8500.h (target_write_pc, TARGET_WRITE_PC):
+ Handle extra arg.
+ * config/i386/xm-go32.h (GDBINIT_FILENAME): Set to gdb.ini.
+ (more work here to come)
+ * config/sh/tm-sh.h (EXTRA_FRAME_INFO): Add f_offset and leaf_function
+ fields.
+
+Thu Sep 8 16:15:34 1994 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * sparclite/Makefile.in: Assorted stuff needed for eload.
+
+ * sparclite/eload.c: Merge in command line argument parsing and
+ error message handling improvements orignally made to aload.c.
+
+Wed Sep 7 23:24:50 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * defs.h (enum misc_command_type, command_control_type): Enums
+ for describing the command and control types.
+ (struct command_line): Add new fields to keep track of the command
+ type and body associated with the command.
+ * top.c: Include value.h. Delete whitespace at the end of lines.
+ (build_command_line, get_command_line): New functions.
+ (execute_control_command, while_command, if_command): Likewise.
+ (realloc_body_list, read_next_line): Likewise.
+ (recurse_read_control_structure): Likewise.
+ (execute_user_command): Call execute_control_command.
+ (read_command_lines): Simplify by calling read_next_line, call
+ read_control_structure for "if" and "while" commands.
+ (free_command_lines): Free new fields in the command structure.
+ (define_command): Reset control_level to zero.
+ (init_main): Install command handlers for "if" and "while" commands.
+
+Tue Sep 6 16:24:07 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * c-typeprint.c (c_type_print_varspec_prefix,
+ c_type_print_varspec_suffix): Add cases for Fortran type codes.
+ * eval.c (evaluate_subexp): For OP_ARRAY expressions in Fortran,
+ call f77_value_literal_string instead.
+ * f_exp.y: Include <string.h>, move include of parser-defs.h.
+ (parse_number): Translate 'd' floats to 'e' so atof() works.
+ (yylex): Remove unused variables.
+ * f-lang.c: Include <string.h>.
+ (get_bf_for_fcn): Remove unused variable.
+ * f-typeprint.c (f_type_print_varspec_prefix,
+ f_type_print_varspec_suffix): Remove unused
+ variables, add cases to switch statements.
+ (f_type_print_base): Remove unused variables.
+ * f-valprint.c (gdbcore.h, command.h): Include.
+ (f77_get_dynamic_lowerbound, f77_get_dynamic_upperbound):
+ Call read_memory_integer with correct number of arguments.
+ (f77_get_dynamic_upperbound): Call f77_get_dynamic_lowerbound
+ with correct argument type.
+ (f77_print_array): Removed unused array array_size_array.
+ (f_val_print): Don't use a CORE_ADDR as a char *.
+ * valops.c (value_cast): Handle COMPLEX and BOOL types.
+ (value_assign): Handle Fortran literal string and complex values.
+ (f77_cast_into_complex, f77_assign_from_literal_string,
+ f77_assign_from_literal_complex): New functions.
+
+Mon Sep 5 14:46:41 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * ch-typeprint.c (chill_type_print_base): Make TYPE_CODE_RANGE
+ case more robust.
+
+Sun Sep 4 16:06:34 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * i960-tdep.c (signal.h): Don't include.
+
+ * cxux-nat.c (target_is_m88110): Remove definition.
+
+ * configure.in (config/nm-empty.h): If cross only, use instead
+ of config/nm-trash.h.
+ * config/nm-trash.h: Remove.
+ * config/nm-empty.h: New file.
+ * config/i386/nm-m3.h: New file, includes config/nm-m3.h.
+ * config/mips/nm-m3.h: New file, includes config/nm-m3.h.
+ * config/m68k/nm-sysv4.h: New file, includes config/nm-sysv4.h.
+ * config/mips/nm-sysv4.h: New file, includes config/nm-sysv4.h.
+ * config/sparc/nm-sysv4.h: New file, includes config/nm-sysv4.h.
+
+
+Fri Sep 2 17:35:55 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * configure.in: No longer look for nm, tm, and xm headers in
+ config/<header>; they are always in config/<cpu>/<header>.
+
+Fri Sep 2 16:40:03 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * objfiles.c (allocate_objfile): Add the newly-created objfile to
+ the end of the list of objfiles, instead of at the beginning.
+
+ * xcoffread.c (allocate_include_entry): New function, abstracted
+ from code in record_include_begin.
+ (record_include_begin, record_include_end): Call it.
+
+ * blockframe.c (reinit_frame_cache): Test inferior_pid instead of
+ target_has_stack to decide whether to create a real stack frame
+ for the cache.
+
+ * coffread.c (process_coff_symbol) [CXUX_TARGET]: Ignore vendor
+ section.
+ * config/m88k/tm-cxux.h (CXUX_TARGET): Define.
+
+ * h8300-tdep.c: Include "dis-asm.h" instead of <dis-asm.h>.
+
+Fri Sep 2 09:51:46 1994 J.T. Conklin (jtc@cygnus.com)
+
+ * config/sparc/tm-nbsd.h: Add #defines to map NetBSD struct and
+ field names into what is expected by sparc-nat.c.
+
+Thu Sep 1 17:32:54 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * c-typeprint.c (c_typedef_print): Add missing Chill support.
+
+Thu Sep 1 15:41:21 1994 Stu Grossman (grossman@cygnus.com)
+
+ * rs6000-pinsn.c (print_insn): Use powerpc disassembler when
+ doing Power PC.
+ * config/powerpc/tm-ppc-nw.h: Define GDB_TARGET_POWERPC.
+
+ * config/i386/i386lynx.mh, config/m68k/m68klynx.mh,
+ config/rs6000/rs6000lynx.mh, config/sparc/sparclynx.mh: Enable
+ ser-tcp.
+
+ * nlm/Makefile.in: Get rid of NWSOURCE.
+ * nlm/alpha-io.S (inVti, outVti): Remove extraneous ldha's.
+ * nlm/gdbserve.o: Add dummy __main routine.
+ * nlm/gdbserve.def: Turn on debug.
+
+Thu Sep 1 12:36:39 1994 Jim Kingdon (kingdon@cygnus.com)
+
+ * config/xm-nbsd.h: Don't define SET_STACK_LIMIT_HUGE; it is obsolete.
+
+Thu Sep 1 11:01:40 1994 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * config/tm-nbsd.h: New file, support for all NetBSD targets.
+ * config/xm-nbsd.h: fix typo.
+ * config/sparc/{nm,tm,xm}-nbsd.h: New files, renamed from
+ {nm,tm,xm}-sparcnbsd.h to conform to prefered file naming
+ conventions.
+ * configure.in: (sparc-*-netbsd): use config/sparc/nbsd.m[ht].
+
+Wed Aug 31 14:40:33 1994 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * remote-udi.c (udi_read_inferior_memory,udi_write_inferior_memory):
+ change typeo in error msg (`inferrior' -> `inferior').
+
+Wed Aug 31 09:17:02 1994 Jim Kingdon (kingdon@cygnus.com)
+
+ * inflow.c (set_sigint_trap, clear_sigint_trap): Check for
+ attach_flag (this check was performed by the callers). Also check
+ inferior_thisrun_terminal.
+ * inftarg.c (child_wait), lynx-nat.c (child_wait),
+ procfs.c (wait_fd), symm-nat.c (child_wait): Don't check
+ attach_flag in deciding whether to call set_sigint_trap and
+ clear_sigint_trap.
+
+ * value.h (struct value): Change literal_data from PTR to char *,
+ since that is the way it is used.
+
+Tue Aug 30 21:56:54 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * somread.c (som_symfile_read): Force unwinds to be re-read after
+ reading in a new partial symbol table.
+
+Tue Aug 30 13:14:16 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/h8500/tm-8500.h (DONT_USE_REMOTE): Remove definition,
+ an obsolete conditional.
+ * config/pa/tm-hppa.h (BREAKPOINT) [KERNELDEBUG]: Remove use,
+ an obsolete conditional.
+ * config/rs6000/rs6000.mh, config/rs6000/rs6000.mt: Clean up
+ comments.
+
+Mon Aug 29 14:39:42 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in (ns32k-opcode.h): Remove reference.
+ (ns32k-pinsn.o): Update dependencies.
+ * ns32k-opcode.h: Remove file.
+ * ns32k-pinsn.c (print_insn): Call version in libopcodes, remove
+ all other code in this file.
+
+Mon Aug 29 12:04:07 1994 Stu Grossman (grossman@cygnus.com)
+
+ * nlm/configure.in: Stop using cpu.c. Put it in TDEPFILES instead.
+ * config/alpha/gdbserve.mt (TDEPFILES): Remove alpha-patch.o.
+
+ * nlm/Makefile.in: Add rule for .S.o.
+ * nlm/aio.h: Protect from multiple inclusions.
+ * nlm/alpha-io.S: Remove everything we don't need.
+ * nlm/{alpha-patch.c, alpha-patch.h, alpha-uart.c, alpha-uart.h}:
+ Remove, no longer needed.
+ * nlm/alpha.c: Merge in lots of stuff from previous files.
+ * nlm/alpha.h: Don't #include alpha-patch.h. Make
+ breakpoint_insn extern.
+ * Move stuff from alpha-patch.h into here.
+
+ * config/alpha/gdbserve.mt (TDEPFILES): Get rid of alpha-uart.o.
+
+Mon Aug 29 11:34:34 1994 Jim Kingdon (kingdon@cygnus.com)
+
+ * annotate.c (annotate_starting): Flush output.
+
+Sat Aug 27 23:32:43 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * symfile.c (symbol_file_add): Move reinit_frame_cache call to
+ the callers of symbol_file_add. Gets rid of heuristic fence-post
+ warnings on mips and alpha targets when the PC resides in a shared
+ library which is not yet read in.
+ * coff-solib.c (coff_solib_add), cxux-nat.c (add_shared_symbol_files),
+ irix5-nat.c (solib_add), osfsolib.c (solib_add),
+ remote-vx.c (vx_open), solib.c (solib_add):
+ Add call to reinit_frame_cache after all shared libraries are read in.
+ * remote-udi.c (udi_load), remote-vx.c (vx_load_command),
+ symfile.c (symbol_file_command, add_symbol_file_command):
+ Add call to reinit_frame_cache after symbol_file_add.
+
+Wed Aug 24 17:45:14 1994 J.T. Conklin (jtc@cygnus.com)
+
+ * config/xm-nbsd.h: New file, support for all NetBSD ports.
+ * config/sparc/{nm-sparcnbsd.h,tm-sparcnbsd.h,xm-sparcnbsd.h,
+ sparcnbsd.mh,sparcnbsd.mt}: New files, support for NetBSD/sparc.
+ * configure.in: Add sparc-*-netbsd target.
+
+Wed Aug 24 13:17:34 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * remote-vx.c (vx_attach): Interpret the command argument as an
+ unsigned long.
+
+Wed Aug 24 13:08:08 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure.in: Change i[34]86 to i[345]86.
+ * nlm/configure.in: Likewise.
+ * gdbserver/configure.in: Likewise.
+
+Wed Aug 24 09:41:09 1994 J.T. Conklin (jtc@cygnus.com)
+
+ * configure.in (i386-*-netware): Automatically configure nlm
+ subdir.
+
+Tue Aug 23 17:51:13 1994 J.T. Conklin (jtc@cygnus.com)
+
+ * nlm/gdbserve.c: conditionalize header file inclusion for either
+ NetWare 4.0 or PIN targets.
+ * nlm/i386.c: include appropriate header files.
+ * nlm/prelude.c: define TERMINATE_BY_UNLOAD for NetWare 4.0
+ targets.
+
+Tue Aug 23 16:54:16 1994 Stu Grossman (grossman@cygnus.com)
+
+ * nlm/ppc.c (set_step_traps clear_step_traps): Cleanups.
+ * nlm/gdbserve.def: Autoload clib.
+
+Tue Aug 23 12:05:19 1994 Jim Kingdon (kingdon@cygnus.com)
+
+ * breakpoint.c (condition_command): Call breakpoints_changed.
+
+ * gdbtypes.h: Declare f77_create_literal_string_type and
+ f77_create_literal_complex_type.
+ * valops.c (f77_value_literal_string, f77_value_substring,
+ f77_value_literal_complex): Use xmalloc not malloc.
+ * valops.c (f77_value_literal_string, f77_value_substring):
+ Make addr char * not CORE_ADDR.
+ * value.h (struct value): Add new field literal_data of aligner union.
+ (VALUE_LITERAL_DATA): Use it.
+ * f-lang.h: Declare find_common_for_function.
+ * value.h, valops.c: Split VALUE_SUBSTRING_START into memaddr and
+ myaddr fields of a union. Don't overload it with the frame field
+ (not sure this is necessary; I'm not sure what lval_* codes
+ VALUE_SUBSTRING_* can be used with).
+
+Mon Aug 22 11:45:01 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/a29k/{a29k-kern.mt,a29k-udi.mt,a29k.mt,ultra3.mh,
+ ultra3.mt}: Clean up comments, remove no-longer-used definitions.
+
+ * rs6000-nat.c: Include libbfd.h again, needed until reference
+ to bfd_cache_lookup is cleaned out.
+
+ * config/i386/linux.mh (XM_CLIBS): Add -lm.
+
+Mon Aug 22 10:42:15 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ Work to reduce the interrupts-off duration when running in DOS.
+ * ser-go32.c: (dos_async_ready): See if anything is in the buffer.
+ (dos_async_rx): rewrite to unpack as many characters from the
+ asynctsr as possible into a local buffer.
+
+Fri Aug 19 14:55:45 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ Initial Fortran language support, adapted from work by Farooq Butt
+ (fmbutt@engage.sps.mot.com).
+ * Makefile.in: Add Fortran-related files and dependencies.
+ * defs.h (language_fortran): New language enum.
+ * language.h (_LANG_fortran): Define.
+ (MAX_FORTRAN_DIMS): Define.
+ * expression.h: Reformat to standard.
+ (MULTI_F77_SUBSCRIPT, OP_F77_UNDETERMINED_ARGLIST,
+ OP_F77_LITERAL_COMPLEX, OP_F77_SUBSTR): New expression opcodes.
+ * gdbtypes.h (TYPE_CODE_COMPLEX, TYPE_CODE_LITERAL_COMPLEX,
+ TYPE_CODE_LITERAL_STRING): New type codes.
+ (type): New fields upper_bound_type and lower_bound_type.
+ (TYPE_ARRAY_UPPER_BOUND_TYPE, TYPE_ARRAY_LOWER_BOUND_TYPE,
+ TYPE_ARRAY_UPPER_BOUND_VALUE, TYPE_ARRAY_LOWER_BOUND_VALUE): New
+ macros.
+ (builtin_type_f_character, etc): Declare.
+ * value.h (VALUE_LITERAL_DATA, VALUE_SUBSTRING_START): Define.
+ * f-exp.y: New file, Fortran expression grammar.
+ * f-lang.c: New file, Fortran language support functions.
+ * f-lang.h: New file, Fortran language support declarations.
+ * f-typeprint.c: New file, Fortran type printing.
+ * f-valprint.c: New file, Fortran value printing.
+ * eval.c (evaluate_subexp): Add code for new expression opcodes,
+ fix wording of error message.
+ * gdbtypes.c (f77_create_literal_complex_type,
+ f77_create_literal_string_type): New functions.
+ * language.c (set_language_command): Add Fortran info.
+ (calc_f77_array_dims): New function.
+ * parse.c (length_of_subexp, prefixify_subexp): Add cases for new
+ expression opcodes.
+ * symfile.c (deduce_language_from_filename): Recognize .f and .F
+ as Fortran source files.
+ * valops.c (f77_value_literal_string, f77_value_substring,
+ f77_value_literal_complex): New functions.
+
+Fri Aug 19 13:35:01 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * c-typeprint.c (c_print_type): Assume demangled arguments
+ if a '(' is found in varstring, looking for ')' at the end of
+ varstring did fail with demangled const member functions, which
+ have a trailing `const'.
+ * remote.c (get_offsets, putpkt): Change to `char' buffers,
+ to avoid errors when compiling with DEC c89.
+ (remote_wait): Cast to `char *' before passing buffer to
+ fputs_filtered, to avoid errors when compiling with DEC c89.
+ (remote_wait): Do not return inferior_pid by default, this
+ statement is never reached, which causes warnings from some
+ compilers.
+ * stabsread.c (scan_file_globals): Ignore static minimal symbols.
+ * symfile.c (load_command): If called with no argument, try
+ to get the filename from the executable file.
+ (generic_load): Remove check for NULL filename, it is done
+ in load_command now.
+
+Fri Aug 19 10:36:15 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * Makefile.in (ALLDEPFILES): Add hpread.c.
+ (hpread.o): Add dependencies.
+
+ * somread.c: Do not include "aout/aout64.h". SOM has nothing to
+ do with a.out.
+ (BYTES_IN_WORD): Delete.
+ (som_symfile_read): Call hpread_build_psymtabs to build any
+ minimal symbols based on the HP C native debug symbols.
+ (som_symfile_finish): Call hpread_symfile_finish.
+ (som_symfile_init): Call hpread_symfile_init.
+ * config/pa/tm-hppa.h (HPREAD_ADJUST_STACK_ADDRESS): Define.
+ * hppa-tdep.c (hpread_adjust_stack_address): New function.
+
+ * config/pa/hppabsd.mh (NATDEPFILES): Add hpread.o
+ * config/pa/hppahpux.mh (NATDEPFILES): Likewise.
+ * hpread.c: New file.
+
+Fri Aug 19 00:40:55 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (skip_trampoline_code): Revert incorrect change
+ from June 2, 1994 (what was I thinking?!?). Fix it right this
+ time.
+
+Thu Aug 18 17:01:35 1994 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * nlm/i386.c, nlm/i386.h: New files that contain i386 specific code.
+
+Thu Aug 18 14:39:46 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * README: Grammar improvements, clarifications, updates.
+
+Wed Aug 17 23:08:53 1994 Stu Grossman (grossman@cygnus.com)
+
+ * Makefile.in (TARGET_FLAGS_TO_PASS): Pass down LD_FOR_TARGET and
+ NLMCONV_FOR_TARGET. (SUBDIRS): Add nlm target.
+ * configure.in (powerpc-*-netware*): Automatically configure nlm
+ subdir.
+ * nlm/Makefile.in: Add {CC NLMCONV LD}_FOR_TARGET. Remove alpha
+ specific stuff. Make things more configurable.
+ * nlm/configure.in: Add powerpc-*-netware* target. Use
+ gdbserve.mt/cpu.c/cpu.h for target stuff. Get rid of tm/xm/nm.h
+ files.
+ * nlm/gdbserve.c: Move Alpha specific stuff into other files.
+ Remove lots of architecture-specific stuff.
+ * nlm/gdbserve.def: Add new imports.
+ * nlm/ppc.c, nlm/ppc.h: New files that contain PowerPC specific code.
+ * nlm/prelude.c: Don't include libhooks.h, get rid of call to
+ register library.
+ * nlm/prelude.o: What was this doing here?
+ * config/alpha/gdbserve.mt: Defs for alpha nlm stub.
+ * config/powerpc/gdbserve.mt: Defs for PowerPC nlm stub.
+ * config/powerpc/ppc-nw.mt: Defs for PowerPC target for GDB.
+ * config/powerpc/tm-ppc-nw.h: Ditto.
+
+ * nlmstub.def: New file, contains imports for 386 nlm stub.
+
+Wed Aug 17 23:17:33 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * remote-pa.c: New file for HPPA embedded support. Currently it's
+ a copy of remote.c.
+ * config/pa/hppabsd.mt,hppahpux.mt,hppaosf.mt: User remote-pa.c.
+
+Wed Aug 17 13:19:52 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/m68k/tm-delta68.h (EXTRACT_RETURN_VALUE,
+ STORE_RETURN_VALUE): Define to use %a0 for pointers.
+
+Wed Aug 17 07:43:06 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote-mips.c: Remove unused declaration of mips_load.
+
+Tue Aug 16 16:45:34 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * coffread.c: General cleanup, and support for section offsets.
+ (time.h, sys/types.h, libbfd.h): Don't include.
+ (cur_src_start_addr, cur_src_end_addr): Rename to
+ current_source_start_addr, current_source_end_addr.
+ (nlist_stream_global): Remove.
+ (nlist_bfd_global): New global variable.
+ (coff_symfile_read): Remove code that gets and uses fileno()
+ directly.
+ (read_coff_symtab, enter_linenos, process_coff_symbol): Add
+ section_offsets parameter, add text/data section offset to
+ appropriate symbols' values.
+ (read_one_sym): Use bfd_read instead of fread.
+ (init_stringtab, init_lineno): Change first parameter to a bfd,
+ use bfd routines instead of raw I/O.
+
+Tue Aug 16 15:24:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * symtab.c (decode_line_1): If funfirstline and we get a
+ non-LOC_BLOCK symbol (e.g. variable or type), then error().
+
+ * Makefile.in (TARFILES, NONSRC, SFILES_STAND, SFILES_KGDB):
+ Remove; unused.
+ (TAGFILES_NO_SRCDIR): Remove ALLPARAM.
+ (HFILES_NO_SRCDIR): Remove all files in config sub-directory.
+ (TAGS): Also pass result of find on config sub-directory to etags.
+ (ALLPARAM): Remove; now unused.
+
+Sun Aug 14 13:05:26 1994 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.13.1
+ * NEWS, README: Update to match gdb 4.13 release version.
+
+Sat Aug 13 08:22:50 1994 Fred Fish (fnf@cygnus.com)
+
+ Harris CX/UX support, from Bob Rusk (rrusk@mail.csd.harris.com).
+ * cxux-nat.c: Remove dangling #else block.
+ (m88k_harris_core_register_addr): New function.
+
+ * environ.c (init_environ): If no environment, do nothing.
+
+Fri Aug 12 19:30:53 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c: Delete rest of TODO list. Do not include "libbfd.h",
+ <time.h>, <sys/types.h>, "demangle.h", <sys/file.h>,
+ "expression.h", "language.h", "gdbtypes.h", "demangleh".
+ Move all global variables into the private symbol table structure
+ and add accessor macros. Update some comments.
+ (hpread_build_psymtabs): Delete dbsubc_addr, we don't need it.
+ (hpread_end_psymtab): New function to end a partial symbol table,
+ all callers changed (no more bogus sharing with dbxread.c).
+
+Fri Aug 12 15:52:37 1994 Stu Grossman (grossman@cygnus.com)
+
+ * remote.c (remote_wait): Return inferior_pid instead of 0 for
+ `W` message.
+
+Fri Aug 12 11:47:10 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * sparclite/aload.c (sys_error, error): Use vfprintf for variable
+ argument lists.
+
+Thu Aug 11 04:06:42 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * defs.h (concat, basename, buildargv, freeargv, strerrno, strsigno,
+ errno_max, signo_max, strtoerrno, strtosigno): Delete.
+ Include "libiberty.h" instead.
+
+Wed Aug 10 13:23:47 1994 Rick Sladkey (jrs@world.std.com)
+
+ * i386v-nat.c (i386_insert_nonaligned_watchpoint):
+ add additional argument specifying raw address to permit
+ proper release of debug registers.
+ (i386_insert_watchpoint, i386_insert_aligned_watchpoint):
+ change all callers.
+
+Wed Aug 10 16:13:45 1994 Stu Grossman (grossman@cygnus.com)
+
+ * defs.h, top.c: Use `extern' in declarations of GUI hooks, and
+ define them in top.c. Add comments to the hooks.
+
+Wed Aug 10 15:57:43 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * remote-sim.c (gdbsim_ops): Set `to_insert_breakpoint' and
+ `to_remove_breakpoint' fields.
+
+Wed Aug 10 15:46:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infcmd.c (run_command): Remove comment suggesting using
+ target_has_execution instead of inferior_pid.
+
+Wed Aug 10 10:33:20 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * remote-mips.c (mips_open): add code to handle baud rate.
+
+Tue Aug 9 09:44:42 1994 Stu Grossman (grossman@cygnus.com)
+
+ * infrun.c (wait_for_inferior): Call target_resume() upon
+ detection of new processes.
+
+ * procfs.c (create_procinfo): Return pointer to new procinfo
+ structure.
+ * (do_detach): Spacing & formatting cleanup.
+ * (procfs_wait): Move wait_again label to ensure that we really
+ wait again. On exit from fork, release new child from gdbs'
+ clutches.
+ * (procfs_set_sproc_trap): Enable trapping of fork and vfork.
+
+Mon Aug 08 15:34:13 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c (hpread_process_one_debug_symbol): Fix block scoping
+ problem (losing localvars on the close-brace instead of after
+ the close brace).
+
+Mon Aug 8 15:09:32 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * i386-nlmstub.c (handle_exception): Wait until the thread has
+ been started before killing the NLM by pointing the PC at
+ _exit().
+
+Sat Aug 6 22:27:30 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/mips/tm-irix5.h (IN_SIGTRAMP): Redefine for Irix 5,
+ Irix 5 has a standard _sigtramp signal handler.
+ * irix5-nat.c (solib_add): Get rid of sigtramp_address handling,
+ it is not needed for a standard _sigtramp signal handler.
+ Add shared library sections to the section table of the target
+ before adding the symbols.
+ * mips-tdep.c (mips_skip_prologue): Do not skip load immediate
+ instructions that do not prepare a stack adjustment.
+ * regex.c (SIGN_EXTEND_CHAR): Update to emacs-19.25 definition,
+ which does the right thing on machines where `char' is unsigned.
+
+Fri Aug 5 17:50:59 1994 Stu Grossman (grossman@cygnus.com)
+
+ * remote.c (remote_open): Move setting of inferior_pid prior to
+ call to remote_start_remote. Also use unique value for pid to
+ avoid confusion with read_register_pid & friends.
+ * (remote_wait): Return inferior_pid instead of 0 in all cases.
+
+Fri Aug 5 12:23:02 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * dwarfread.c (bfd.h): Don't include.
+
+Fri Aug 5 09:08:34 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * i386-nlmstub.c (handle_exception): Point the PC at _exit() to
+ kill the program being debugged. KillMe(), the undocumented
+ call intended for this purpose, causes the server to hang.
+
+Thu Aug 4 16:26:06 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * remote.c (read_frame): Calculate run length encoded checksum
+ correctly.
+ * config/sh/stub.c: New file.
+
+Thu Aug 4 14:34:12 1994 Stu Grossman (grossman@cygnus.com)
+
+ * target.c (find_default_run_target): Make sure to_can_run is set
+ before calling it.
+
+Thu Aug 4 11:46:27 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Remove note about fast watchpoints and remove obsolete
+ Mach stuff.
+
+Thu Aug 4 11:08:03 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/i386/xm-i386v4.h, config/m68k/xm-m68kv4.h,
+ config/sparc/xm-sun4sol2.h (NORETURN): Don't define.
+ * config/m88k/tm-cxux.h (ARCH_NUM_REGS): Undefine before defining.
+
+Thu Aug 4 10:26:36 1994 Stu Grossman (grossman@rtl.cygnus.com)
+
+ * target.c (add_target): Don't call clean_target on target
+ vectors anymore.
+ * (unpush_target): Test for to_close being set before calling.
+ * (target_xfer_memory, target_info): Check for to_has_memory
+ before playing with memory.
+
+ * remote.c (remote_open): Set inferior_pid to make kill command
+ happy.
+ * inflow.c (kill_command): Revert change of Aug 2. Use
+ inferior_pid to determine whether to print out "The program is not
+ being run." message.
+
+Thu Aug 4 07:55:04 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/i386/i386m3.mh (NAT_CLIBS): Add -lmachid and -lnetname.
+ * m3-nat.c, config/nm-m3.h: #if 0 REQUEST_QUIT stuff.
+ * m3-nat.c: Pass argument to return_to_top_level.
+ Declare m3_kill_inferior before use.
+ (port_chain_insert): In "can't happen" case, abort rather than
+ setting `mid' to large decimal constant (which gcc warns about).
+ (get_thread_name): Use cast to convert const char * to char *.
+ (add_mach_specific_commands): #if 0 "thread break" command.
+ (m3_trace_him): Call push_target.
+ (mach_really_wait): New argument pid; remove unused
+ variable pid.
+ (intercept_exec_calls): Call target_terminal_init and
+ target_terminal_inferior once the child execs.
+ * infrun.c (proceed): Pass argument to PREPARE_TO_PROCEED.
+
+Wed Aug 3 22:41:13 1994 Tom Lord (lord@x1.cygnus.com)
+
+ * procfs.c (procfs_mourn_inferior): don't dereference the
+ procinfo pointer after it has been freed.
+
+Wed Aug 3 12:05:13 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * breakpoint.c (breakpoint_1): Improve pluralization in display
+ of breakpoint hit counts.
+
+ * language.h (struct language_defn): Remove unused field
+ la_longest_float.
+ (longest_float): Remove, no longer used.
+ * language.c (unknown_language_defn, auto_language_defn,
+ local_language_defn): Remove init of la_longest_float field.
+ * c-lang.c (c_language_defn, cplus_language_defn,
+ asm_language_defn): Ditto.
+ * ch-lang.c (chill_language_defn): Ditto.
+ * m2-lang.c (m2_language_defn): Ditto.
+
+Tue Aug 2 10:58:34 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * defs.h (bfd_read, bfd_seek): Remove declarations.
+ * os9kread.c, rs6000-nat.c (libbfd.h): Don't include.
+
+Tue Aug 2 09:50:50 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * inflow.c (kill_command): Fix a bug which prevented target
+ programs to be killed.
+
+Mon Aug 1 18:48:47 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * defs.h: Change two-line declarations to one-line form.
+ (NORETURN): Define as "volatile" only for older GCCs.
+ (ATTR_NORETURN): Define for newer GCCs.
+ * procfs.c (proc_init_failed): Add ATTR_NORETURN to declaration.
+
+Mon Aug 1 16:43:24 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.c (mention), main.c (fputs_unfiltered): Add comments.
+ * breakpoint.c (delete_breakpoint, enable_breakpoint,
+ disable_breakpoint): Don't call breakpoints_changed; it is now
+ called via the *_breakpoint_hook functions.
+ * annotate.c (_initialize_annotate, breakpoint_changed): New functions.
+
+Mon Aug 1 13:38:04 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * stabsread.c (read_type): Fix a bug in enum size calculation.
+
+Mon Aug 1 01:36:13 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (compare_unwind_entries): Add "const" to both
+ argument types to shut up GCC.
+
+ * hppa-tdep.c (saved_pc_after_call): If the saved PC is in a
+ linker stub, then return the address the stub will return to.
+ (frame_saved_pc): Correctly restart the search for the saved
+ pc when a linker stub is encountered.
+
+ * hppa-tdep.c (inst_saves_gr): Handle 16 and 8 bit instruction
+ register stores emitted by the version 9 HP compilers.
+ (inst_saves_fr): Relax test for a specific base register (%r1);
+ this avoids losing with the version 9 HP compilers.
+ (skip_prologue): Try to skip argument stores emitted by the HP
+ compilers. It's not perfect, but it's better than before.
+
+Fri Jul 29 23:20:30 1994 Stu Grossman (grossman@cygnus.com)
+
+ * findvar.c (write_pc write_pc_pid): Remove casts to long when
+ calling write_register_pid.
+ * (write_register_pid): Add prototype.
+
+Fri Jul 29 21:56:23 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * remote.c (read_frame): Split readchar/checksum calculation into
+ two parts since evaluation order is undefined.
+
+Fri Jul 29 13:46:08 1994 Fred Fish (fnf@cygnus.com)
+
+ From Kevin A. Buettner (kev@cujo.geg.mot.com).
+ * Makefile.in (coredep.o): Add inferior.h as dependency.
+ * inflow.c: Add F_SETOWN to list of defines to check
+ around code that uses F_SETOWN.
+
+Fri Jul 29 09:59:05 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * Makefile.in (CC_FOR_TARGET, CXX_FOR_TARGET): If using newlib,
+ set the -L and -B directory prefixes so we can link with it.
+
+Thu Jul 28 14:37:36 1994 Stu Grossman (grossman@cygnus.com)
+
+ * Makefile.in (INSTALLED_LIBS, CLIBS, DEPFILES): Add support for
+ --enable-xxx configure option by adding ENABLE_{CLIBS DEPFILES}
+ where appropriate.
+
+ * General hackery to support alternate user-interface.
+ * breakpoint.c (mention, delete_breakpoint, enable_breakpoint,
+ disable_breakpoint): Call hooks for alternate user-interface.
+ * defs.h: Add declarations for alternate user-interface hooks.
+ * main.c (main): Add --nw (and --nowindows) options to disable
+ the GUI.
+ * (near call to command_loop): Call command_loop_hook if set.
+ * (fputs_unfiltered): Call fputs_unfiltered_hook if set.
+ * stack.c: Call print_frame_info_listing_hook if set.
+ * top.c (gdb_init): Initialize targets.c and utils.c prior to
+ other files to make sure that calls to error and warning will
+ work. Call init_ui_hook after everything else.
+ * utils.c (query): Call query_hook if set.
+ * (gdb_flush): Call flush_hook if set.
+ * Change _initialize_utils to initialize_utils cuz we don't use
+ automatic initialization of utils.c anymore.
+
+
+ * remote.c: Get rid of #ifdef DONT_USE_REMOTE. It's no longer
+ necessary.
+
+Thu Jul 28 14:52:01 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * Makefile.in (CC_FOR_TARGET, CXX_FOR_TARGET): Use newlib if it is
+ there and we are using the gcc from the tree.
+ (LD_FOR_TARGET): Look for ld in ../ld/ld.new.
+
+Thu Jul 28 10:43:36 1994 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (annotate.o): Add dependencies.
+
+Wed Jul 27 14:34:42 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * sparclite/aload.c: Added new -q (quiet) option.
+ return 0 exit status if file was successfully downloaded.
+
+ * nlm/gdbserve.c: merge in command line argument parsing changes
+ and bug fixes made to i386-nlmstub.c.
+
+ * i386-nlmstub.c: The returnLength field must be initialized
+ before portConfig is passed to AIOGetPortConfiguration.
+ Compare command line arguments with strnicmp(); args are
+ case insensitive on netware.
+
+Wed Jul 27 09:24:19 1994 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (DISTSTUFF): Add definition.
+ (diststuff): Add for new distribution support.
+ (gdb.tar.Z, make-proto-gdb.dir, setup-to-dist,
+ gdb-$(VERSION).tar.Z, make-proto-gdb-1, make-proto-testsuite.dir):
+ Remove old distribution building rules, now uses standard
+ distribution support in parent directory Makefile.in.
+
+Tue Jul 26 14:15:53 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * target.c (push_target): Cast result from xmalloc.
+
+Tue Jul 26 18:20:46 1994 Paul Flinders (ptf@smee)
+
+ * elfread.c (elf_symtab_read): Discard compiler labels generated
+ by the Solaris 2.1/Intel SunPro compiler.
+
+Mon Jul 25 18:19:24 1994 Stu Grossman (grossman@cygnus.com)
+
+ * target.c (nomemory): Fix prototype and routine to take correct
+ args.
+
+Mon Jul 25 15:38:23 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (clean): Remove libgdb-files.
+
+Mon Jul 25 11:50:57 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * coredep.c: Include inferior.h.
+
+Mon Jul 25 11:36:02 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * i386-nlmstub.c: Add support for NODE, PORT and BAUD command
+ line arguments.
+
+Sat Jul 23 14:36:09 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * symfile.c (deduce_language_from_filename): Recognize .S as asm,
+ .cp as C++, alphabetize better.
+
+ * breakpoint.c (ignore, condition): Move usage note into body of
+ help text, so first line can be one-line summary.
+
+Sat Jul 23 00:58:15 1994 Stu Grossman (grossman@cygnus.com)
+
+ * target.c (unpush_target): Fix handling of removal of top target.
+
+Fri Jul 22 17:30:39 1994 Stu Grossman (grossman@cygnus.com)
+
+ * Makefile.in: Add stuff to build nlmstub.
+ * Add rule for annotate.o to keep Sun make happy.
+ * configure.in: Add config for powerpc/Netware.
+
+ * partial-stab.h (near N_SO): Don't call START_PSYMTAB with null
+ filename. This speeds up handling of trailing N_SO stabs (they
+ mark the end of a .o file).
+
+ * target.c, target.h: Change the way pushing and popping of
+ targets work to support target overlays and inheritance.
+ * corelow.c, hppa-tdep.c, inflow.c, remote-nindy.c, utils.c:
+ Fixup references to current_target, due to previous changes.
+
+ * config/i386/tm-i386nw.h: Enable longjmp support. More work is
+ needed to get the address of longjmp out of the target.
+
+Tue Jul 19 13:25:06 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * main.c: Include <ctype.h>.
+
+Mon Jul 18 15:32:17 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * remote-mips.c (mips_readchar): Fix a bug in checking <IDT>
+ prompt.
+
+Mon Jul 18 14:26:35 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * solib.c (look_for_base): Don't deref exec_bfd if NULL.
+
+Sun Jul 17 15:38:36 1994 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.12.4.
+
+Sun Jul 17 12:20:35 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ Harris CX/UX support, from Bob Rusk (rrusk@mail.csd.harris.com).
+ * configure.in (m88*-harris-cxux*): New configuration.
+ * cxux-nat.c, config/m88k/cxux.mh, config/m88k/cxux.mt,
+ config/m88k/xm-cxux.h, config/m88k/tm-cxux.h, config/m88k/nm-cxux.h:
+ New files.
+ * config/m88k/tm-m88k.h: Add comment about Harris OS.
+ (TARGET_WRITE_PC): Pass pid through to register writers.
+
+ * configure.in (m68*): Put vendor-only-specified host configs
+ after vendor-and-os-specified configs.
+ (m68*-atari-sysv4*, m68*-cbm-sysv4*): Replace with m68*-*-sysv4.
+
+ * config/m88k/delta88.mh (MUNCH_DEFINE): Remove.
+ * config/m88k/delta88.mt, config/m88k/delta88v4.mh: Format
+ consistently.
+
+Sat Jul 16 23:39:17 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * elfread.c (elf_symtab_read): Handle error return from
+ bfd_get_dynamic_symtab_upper_bound gracefully.
+
+Sat Jul 16 14:43:17 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * inferior.h (ARCH_NUM_REGS): New macro, actual number of
+ registers in use by the inferior.
+ * coredep.c (fetch_core_registers, register_addr): Use it.
+ * findvar.c (registers_changed, registers_fetched,
+ read_register_bytes): Ditto.
+ * infcmd.c (do_registers_info, registers_info): Ditto.
+ * infptrace.c (fetch_inferior_registers,
+ store_inferior_registers): Ditto.
+ * stack.c (frame_info): Ditto.
+
+ * coredep.c (CORE_REGISTER_ADDR): New macro.
+ (fetch_core_registers): Use it.
+
+ * breakpoint.c (ignore, condition): Add usage notes to help strings.
+ * symfile.c (add-symbol-file): Add usage note to help string.
+ (add_shared_symbol_files_command): New command.
+
+ gcc -Wall lint.
+ * inferior.h (read_pc_pid): Declare.
+ * breakpoint.c (watchpoint_check): Cache breakpoint in local
+ variable b, remove unused variable other_type_used.
+ * main.c (inferior.h, call-cmds.h): Include.
+ (gdb_init): Declare.
+ * remote.c (remote_wait): Return 0 by default.
+
+Fri Jul 15 16:43:33 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ Stop printing at null char option, from Oliver Meyer
+ (omeyer@i3.informatik.rwth-aachen.de).
+ * valprint.h, valprint.c (stop_print_at_null): New global.
+ * valprint.c (_initialize_valprint): New print set subcommand
+ "null-stop".
+ * c-valprint.c (c_val_print): If stop_print_at_null is on, and
+ printing a char array, adjust the number of chars to print.
+
+Fri Jul 15 14:33:40 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ From Kevin A. Buettner (kev@cujo.geg.mot.com).
+ * m88k-tdep.c (examine_prologue): Modified to handle prologues for
+ pic code in addition to prologues where an instruction from the
+ prologue gets moved into the delay slot of a branch instruction
+ immediately following the prologue. A table of potential prologue
+ instructions (prologue_insn_tbl) is now used for picking apart a
+ function prologue.
+ (frame_find_saved_regs): Changed the way in which limit gets set
+ so that the delay slot of branch instructions immediately
+ following the prologue gets examined.
+ (pushed_size, store_parm_word, store_parm, push_parameters,
+ collect_returned_value): Deleted.
+
+Fri Jul 15 01:06:00 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * infrun.c (wait_for_inferior): Handle stepping into leaf
+ functions whose prologue consists of gp loading code only.
+
+Thu Jul 14 14:22:12 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * dbxread.c: Don't include libbfd.h.
+ * dwarfread.c, elfread.c somread.c: Don't include libbfd.h,
+ <time.h>, or <sys/types.h>.
+ * elfread.c (elf_symfile_read): Use only standard BFD functions to
+ collect information about the stab and stab string sections.
+
+Thu Jul 14 13:17:39 1994 Kung Hsu (kung@x1.cygnus.com)
+
+ * stabsread.c (read_huge_number): handle large unsigned number
+ for stabs generated by os9k C compiler.
+
+Wed Jul 13 18:58:15 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ Breakpoint hit counts, from Bob Rusk (rrusk@mail.csd.harris.com).
+ * breakpoint.h (hit_count): New breakpoint field.
+ * breakpoint.c (show_breakpoint_hit_counts): New variable.
+ (clear_breakpoint_hit_counts): New function.
+ (bpstat_stop_status): Increment the hit count.
+ (breakpoint_1): Display the hit count.
+ * infcmd.c (run_command): Reset breakpoint hit counts.
+ * target.c (generic_mourn_inferior): Don't clear ignore counts if
+ displaying hit counts.
+
+Tue Jul 12 12:23:15 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * elfread.c (elf_symfile_read): Unconditionally add dynamic
+ symbols for all symbol files. Makes skipping over the
+ trampoline code work when stepping from a function in a shared
+ library into a function in a different shared library for Irix 5.
+ Other ELF targets do not have enough information in their
+ dynamic symbol tables to make this work.
+ (elf_symtab_read): Relocate mst_solib_trampoline address.
+
+Mon Jul 11 16:38:49 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ Atari support, from Uwe Seimet (seimet@chemie.uni-kl.de).
+ * configure.in (m68*-atari-sysv4*): New configuration.
+ (m68*-cbm-sysv4*): Use m68kv4 instead of amix.
+ * m68k-tdep.c (R_PS): Define as R_SR if necessary.
+ * config/m68k/m68kv4.mh, config/m68k/m68kv4.mt,
+ config/m68k/tm-m68kv4.h, config/m68k/xm-m68kv4.h: New files.
+ * config/m68k/amix.mh, config/m68k/amix.mt,
+ config/m68k/tm-amix.h, config/m68k/xm-amix.h: Removed, superseded
+ by m68kv4 files.
+
+Sat Jul 9 16:28:43 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * symtab.c (find_function_start_sal): New function to find
+ the start of a function from a function symbol.
+ (decode_line_1, decode_line_2): Use it instead of open coded
+ partial copies of the code.
+ (list_symbols): Quote symbol name before passing it to
+ break_command to enable proper handling of mangled symbols.
+
+Wed Jul 6 20:22:07 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * ch-exp.y (match_simple_name_string): Don't lower-case here.
+ * ch-exp.y (yylex): First try name lookup using exact name
+ typed by user; if that fails, try lower-cased name.
+
+Wed Jul 06 12:39:07 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c: More cleanups. Delete lots of trailing whitespace.
+ Remove some items from the TODO list and notes throughout code
+ for things which need fixing. Add more comments.
+ Document bogus struct symloc sharing with dbxread.c. Delete more
+ useless variables. Add more PARAM prototypes. Fixup more
+ indention problems that have crept in.
+ (SET_NAMESTRING): Accept new namep and objfile arguments so that
+ it doesn't depend on the variable names on the procedures it's
+ used from.
+ (hpread_symfile_init): Delete incorrect checks for bogus sizes of
+ the debug sections.
+
+Wed Jul 6 00:48:57 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dbxread.c, elfread.c, mipsread.c, nlmread.c, os9kread.c:
+ Move "no debugging symbols found" test to symfile.c.
+ * symfile.c (syms_from_objfile, reread_symbols): Add
+ "no debugging symbols found" test.
+ * coffread.c (init_stringtab): Handle stripped files with a
+ stringtab offset of zero gracefully.
+ * osfsolib.c (solib_create_inferior_hook): Use DYNAMIC flag from
+ BFD instead of stop_pc heuristic to determine if it is a dynamically
+ linked object file.
+ * procfs.c (wait_fd): Handle ENOENT error return from PIOCWSTOP
+ ioctl, it indicates that the process has exited.
+
+Mon Jul 04 19:48:03 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c (hpread_symfile_init): Make sure to initialize all the
+ private data to zero. Not having any HP C debug symbols is not an
+ error. Just return.
+
+Mon Jul 4 19:28:56 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (read_unwind_info): ELF unwind information is in the
+ .PARISC.unwind section now.
+
+Mon Jul 4 17:06:26 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * breakpoint.c (mention): Always show breakpoint address if no
+ source file.
+
+Sat Jul 2 01:51:33 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * solib.c (bfd_lookup_symbol, look_for_base): Reinstate to reenable
+ handling of shared libraries for non-ELF executables, but only if
+ HANDLE_SVR4_EXEC_EMULATORS is defined.
+ (locate_base): Try to find debug_base in the dynamic linker
+ for non-ELF executables if HANDLE_SVR4_EXEC_EMULATORS is defined.
+ * config/sparc/tm-sun4sol2.h (HANDLE_SVR4_EXEC_EMULATORS):
+ Define to enable handling of shared libraries for a.out executables,
+ run under Solaris BCP.
+
+Fri Jul 01 19:50:21 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c: Change contribution notice to the Cygnus/Utah agreed
+ upon notice. Delete some stuff from the TODO list. Rework
+ many comments to be clearer. Major cleanups. Consistently
+ use "hpread_" prefix. Delete unnecessary macros, structures
+ variables, fiels, functions and #if 0 code. Mark code which
+ still needs to be cleaned up. PARAMize and make most functions
+ static. Fix error checking when reading in the debug section
+ contents. No more minimal symbol table handling in this code!
+
+Thu Jun 30 13:59:23 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infrun.c (wait_for_inferior): Print "Program exited normally"
+ regardless of batch_mode.
+ * defs.h, top.c (batch_mode): Removed.
+
+Wed Jun 29 18:53:36 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in (dcache_h): Remove redundant definition.
+ (init.c): Add a comment.
+ (top.c): Remove explicit compile action.
+ * breakpoint.c (mention): Share code indicating location of
+ break/watchpoints, don't print address if addressprint is off.
+ * breakpoint.c, c-typeprint.c, c-valprint.c, energize.c, symtab.h
+ (demangle): Remove redundant declarations.
+ * eval.c: Remove redundant function declarations.
+ * objfiles.h: Cosmetic and grammatical improvements.
+ * TODO: Various updates.
+
+ * remote-mips.c: Replace all \r chars with \015.
+ (mips_receive_header): Display control characters readably.
+ (mips_xfer_memory): Add a simple progress display.
+
+Wed Jun 29 13:11:45 1994 Steve Chamberlain (sac@cirdan.cygnus.com)
+
+ * remote-e7000.c (e7000_open): Don't try a tcp open if we're
+ using go32.
+ * remote-hms.c (flush): New function.
+ (expect): Get edge case right.
+ (hms_read_inferior_memory): Be more tolerant of line noise.
+
+Tue Jun 28 14:17:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.in: Use i386m3.mh and i386m3.mt as names of host and
+ target files, not non-existent mach3.mh and mach3.mt.
+
+Wed Jun 29 00:26:17 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dbxread.c (dbx_symfile_read): Unconditionally add dynamic
+ symbols for all symbol files. Makes skipping over the
+ trampoline code work when stepping from a function in a shared
+ library into a function in a different shared library.
+ (read_dbx_dynamic_symtab): Relocate mst_solib_trampoline address.
+
+Tue Jun 28 15:28:01 1994 Stu Grossman (grossman@cygnus.com)
+
+ * dbxread.c, partial-stab.h (near N_SO): SO stabs with blank
+ names mean end of .o file.
+ * infrun.c (wait_for_inferior): Clean up multi-thread logic near
+ top of routine. Handle new thread notification cleanly.
+ * lynx-nat.c (child_wait): General cleanups, handle new LynxOS
+ thread notification scheme.
+ * (child_resume): General cleanups, handle resumption of all
+ threads properly.
+
+Mon Jun 27 09:57:23 1994 Steve Chamberlain (sac@cirdan.cygnus.com)
+
+ * ser-go32.c: Rewrite to run under windows.
+ * ser-e7kpc.c: New file to support the E7000 with the PC ISA
+ bus interface.
+ * serial.c (serial_open): Notice device "pc".
+ * remote-e7000.c: Fix copyright date.
+ (expect): Compare \n and \r the same.
+ (e7000_open): Allow pc as a serial port
+ * sh/sh.mt: Add ser-e7kpc.
+ * h8300/h8300hms.mt: Add ser-e7kpc.
+ * main.c (proc_wait): Don't wait if using go32.
+
+Mon Jun 27 00:35:51 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * somread.c: Simplify by using stabsect_build_psymtabs.
+ * dbxread.c (stabsect_build_psymtabs): New argument "text_name"
+ corresponding to the name of the text section. All references
+ changed.
+ (somstab_build_psymtabs): Delete function, no longer needed.
+
+Sun Jun 26 23:54:08 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * somread.c: Renamed from paread.c. Changed function names and
+ comments to reflect that this file deals with SOM (an object file
+ format), rather than the PA (a cpu).
+ (Makefile.in): Chaned appropriately.
+ (config/pa/hppabsd.mh, config/pa/hppahpux.mh): Likewise.
+ * dbxread.c (somstab_build_psymtabs): Renamed from
+ pastab_build_psymtabs.
+
+Fri Jun 24 08:15:42 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * core-sol2.c: New file to handle ELF and BCP core file flavours.
+ * config/sparc/sun4sol2.mh (NATDEPFILES): Use it instead of
+ core-svr4.
+ * Makefile.in: Updated for core-sol2.c.
+ * README: Add notes about SPARCworks cc under Solaris 2.x,
+ from Casper H.S. Dik (casper@fwi.uva.nl).
+ * config/mips/xm-makeva.h: Removed, no longer necessary.
+ * Makefile.in, config/mips/xm-irix3.h, config/mips/xm-irix5.h,
+ config/mips/xm-mips.h, config/mips/xm-news-mips.h,
+ config/mips/xm-riscos.h: Remove references to xm-makeva.h
+
+Wed Jun 22 17:48:21 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdba.el: Put program input and output in a separate buffer.
+
+Wed Jun 22 16:54:15 1994 Fred Fish (fnf@cygnus.com)
+
+ * energize-patches, main.c (main), top.c (gdb_init, pwd_command),
+ top.h: Change all occurances of dirbuf to gdb_dirbuf. Collides
+ with global variable of same name in libnsl.so on UnixWare.
+
+Wed Jun 22 14:40:52 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * symtab.c (decode_line_1): fix a bug in dealing with '<>'
+ embedded in template name.
+
+Tue Jun 21 14:06:46 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * config/i386/nm-linux.h: change calling convention of
+ TARGET_CAN_USE_HARDWARE_WATCHPOINT() and
+ target_insert_watchpoint() and
+ target_remove_watchpoint().
+
+ * config/mips/tm-mips64.h: define FORCE_LONG_LONG to force LONGEST
+ to be long long in gdb.
+ * config/mips/tm-bigmips.h: ditto.
+
+Mon Jun 20 23:54:37 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * c-lang.c (asm_language_defn): New definitions for language_asm,
+ mostly copied from c_language_defn, to avoid warnings when
+ switching between c and asm stack frames.
+
+Mon Jun 20 13:51:55 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * mdebugread.c (parse_symbol): Don't call ecoff_swap_tir_in or
+ ecoff_swap_rndx_in directly; use the debug_swap pointer instead.
+ (upgrade_type, handle_psymbol_enumerators): Likewise.
+ (has_opaque_xref, cross_ref): Likewise.
+ (elfmdebug_build_psymtabs): Call swap->read_debug_info to read
+ debugging information, rather than doing it here.
+ * mipsread.c (mipscoff_symfile_read): Call read_debug_info entry
+ point in ecoff_debug_swap backend structure, rather than calling
+ ecoff_slurp_symbolic_info directly.
+
+Fri Jun 17 20:58:58 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.c: Include annotate.h. Call annotate_field rather
+ than printing annotation directly.
+
+ * main.c: Include string.h.
+
+Thu Jun 16 14:41:37 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * fork-child.c (startup_inferior) [STARTUP_INFERIOR]: If defined,
+ call it instead of doing normal loop.
+ * infcmd.c (attach_command): Don't call wait_for_inferior if
+ running Mach 3.
+ * infrun.c (proceed) [PREPARE_TO_PROCEED]: If defined, call
+ hook that can decide whether to step over the next breakpoint.
+ * utils.c (wrap_here): Abort if wrap_buffer not allocated.
+ (request_quit) [REQUEST_QUIT]: If defined, call it instead of
+ doing normal quit.
+
+ * configure.in: Improve sorting/formatting of hosts and targets.
+ (i[34]86-*-mach3*, i[34]86-*-osf1mk*, mips-*-mach3*,
+ m88*-*-mach3*, ns32k-*-mach3*): Recognize.
+ * Makefile.in (stop-gdb): New target.
+ * stop-gdb.c: New file, utility to get attention of waiting GDBs
+ in Mach 3.
+
+Wed Jun 15 00:41:03 1994 Tom Lord (lord@rtl.cygnus.com)
+
+ * top.c (gdb_init): Init current_directory in gdb_init. Probably
+ the identical initialization can be deleted from main.c, but i
+ haven't done so just in case.
+
+Tue Jun 14 17:24:41 1994 Tom Lord (lord@x1.cygnus.com)
+
+ * gdba.el: Added menu windows and slightly improved window
+ handling to gdba.el. Fixed numerous minor bugs that were causing
+ emacs and gdb to fall out of sync.
+
+Tue Jun 14 16:18:44 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * breakpoint.c: annotate changes lost at merge, put back in.
+
+Mon Jun 13 17:28:50 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/i386/i386sco.mh, i386sco4.mh (XDEPFILES): Remove
+ i387-tdep.o.
+
+Sun Jun 12 03:51:52 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/m68k/dpx2.mh (NATDEPFILES): Remove duplicate inclusion
+ of inftarg.o.
+ * config/m68k/tm-dpx2.h (CANNOT_STORE_REGISTER): Define to inhibit
+ writing of floating registers, the dpx2 kernel disallows it.
+ * irix5-nat.c (LM_ADDR): The loaded address of the shared library
+ is contained in o_praw.
+ * irix5-nat.c (solib_map_sections): Adjust sections by the
+ difference between the loaded address and the prelinked address.
+ * irix5-nat.c (solib_address): Use LM_ADDR for the loaded start
+ address.
+ * mdebugread.c (parse_symbol): Do not relocate stEnd/scText
+ symbols, their value is absolute.
+ * mdebugread.c (parse_partial_symbols): Handle Irix 5.2 shared
+ libraries fh->adr fields of zero. Relocate minimal symbol values
+ upon readin. Relocate non-stabs symbols upon readin.
+ * mdebugread.c (psymtab_to_symtab_1): Use pst->textlow for the
+ start address of the outermost block.
+ * mdebugread.c (parse_lines, parse_procedure): Pass in pst
+ instead of section_offsets and use relocated pst->textlow for
+ line number and procedure address relocations.
+
+ From gmo@MicroUnity.com (Guillermo A. Loyola):
+ * mdebugread.c (parse_symbol, parse_partial_symbols, cross_ref):
+ Handle SGI Irix5 stIndirect symbol type.
+
+Fri Jun 10 14:52:56 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * breakpoint.c: fix a syntax error native cc does not like.
+
+ * Makefile.in: change sparclite-tdep.c to sparcl-tdep.c.
+ * sparclite/Makefile.in: ditto.
+ * sparcl-tdpe.c: change file name because first 8 chars has to be
+ unique.
+ * sparcl-stub.c: ditto.
+
+ * sparclite/Makefile.in: fix INCLUDE_CFLAGS to have {srcdir}/../config.
+
+Fri Jun 10 10:38:15 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (target_read_pc, target_write_pc): Accept (and
+ ignore) a PID argument.
+ (hppa_pop_frame): Pass a PID to target_write_pc.
+ * config/pa/tm-hppa.h (TARGET_READ_PC, TARGET_WRITE_PC): Accept
+ and pass through a PID argument.
+ (target_read_pc, target_write_pc): Update prototypes.
+
+Thu Jun 9 18:10:44 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * Makefile.in: add new file sparclite-tdep.c.
+ * sparclite/Makefile.in: add new file sparclite-stub.c.
+ * sparclite/hw_breakpoint.note: note for SPARClite hardware breapoint
+ support.
+ * config/sparc/sparclite.mt: add sparclite-tdep.o.
+ * config/sparc/tm-sparclite.h: add hardware breakpoints support
+ defiines and code.
+ * sparclite-tdep.c: new file, contains hardware breakpoint support
+ code.
+ * sparclite-stub.c: new file, stub code that add support hardware
+ breakpoint support.
+ * breakpoint.c: add hardware breakpoint support.
+ * breakpoint.h: add new breakpoint type to support hardware
+ breakpoint.
+ * config/mips/nm-irix4.h: change interface for target dependent
+ code supporting watch point.
+ * config/pa/nm-hppab.h: change interface for target dependent
+ code supporting watch point.
+
+Thu Jun 9 14:59:58 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * remote-os9k.c (rombuf_command): fix a bug accepting rombug
+ output.
+ * stabsread.c (read_struct_fields): os9k nested structure does not
+ have terminating ';', instead it just get to ',' and bit position
+ and length.
+
+Wed Jun 8 23:20:45 1994 Stu Grossman (grossman@cygnus.com)
+
+ * nlmread.c (nlm_symtab_read): Clean up a bit.
+ * (nlm_symfile_read): Record bounds of main() so that backtrace
+ command will know where to stop.
+ * objfiles.c (objfile_relocate): Relocate entry point/func info
+ for backtrace as well.
+ * objfiles.h: Define values for invalid PCs for entry point info.
+ * symfile.c (init_entry_point_info): Initialize invalid values
+ with aforementioned macros.
+ * config/alpha/tm-alphanw.h: Turn on FRAME_CHAIN_VALID_ALTERNATE
+ to cause backtrace to stop when it gets back to main().
+ * config/i386/tm-i386nw.h: Ditto.
+
+Sat Jun 4 18:17:03 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ Fix value_print, which used to be ostensibly language-independent,
+ but would print pointers and arrays in C syntax. Instead, call
+ a language-specific function.
+ * language.h (struct language_defn): New functional field
+ la_value_print.
+ (LA_VALUE_PRINT): New macro.
+ * language.c (unk_lang_value_print): New stub/dummy function.
+ (unknown_language_defn, auto_language_defn, local_language_defn):
+ Use it.
+ * c-valprint.c (c_value_print): New function, with code moved from:
+ * valprint.c (value_print): ... here. Now just invoke
+ LA_VALUE_PRINT to do language-specific stuff.
+ * valprint.c (value_print_array_elements): Make non-static.
+ * c-lang.c (c_language_defn, cplus_language_defn): Add
+ c_value_print in the la_value_print field.
+ * m2-lang.c (m2_language_defn): Likewise.
+ * ch-lang.c (chill_language_defn): But here use chill_value_print.
+ * ch-valprint.c (chill_val_print): Print null pointer as NULL.
+ * ch-valprint.c (chill_value_print): New function, based on
+ c_value_print, but use Chill "look and feel."
+ * c-lang.h (c_value_print): New prototype.
+ * ch-lang.h (chill_value_print): New prototype.
+ * value.h (value_print_array_elements): New prototype.
+
+ * ch-valprint.c (chill_val_print, case TYPE_CODE_BITSTRING
+ and case TYPE_CODE_SET): Check that the element type isn't a stub.
+
+Fri Jun 3 09:15:00 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * main.c: Move entire file except for #ifndef MAIN_OVERRIDE code
+ to new file top.c. Make things extern instead of static and
+ similar rearrangements to deal with this.
+ * top.h: New file.
+ * utils.c: Move fputs_unfiltered to main.c. Remove
+ FPUTS_UNFILTERED_OVERRIDE ifndef.
+ * Makefile.in: Change so that gdb uses main.c, utils.c, and top.c,
+ and libgdb uses utils.c and top.c.
+
+Thu Jun 2 23:19:10 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (skip_trampoline_code): Fix typo.
+
+Thu Jun 2 18:09:59 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * ch-valprint.c (chill_val_print_array_elements): New function.
+ A Chill version of val_print_array_elements, it prints the
+ array index labels, in additions ot the array element values.
+ (chill_val_print): Use the new function.
+
+Thu Jun 2 08:50:00 1994 Stu Grossman (grossman@cygnus.com)
+
+ * configure.in: Add nlm subdir to configdirs for alpha-*-netware
+ target.
+ * defs.h (enum language): Add language_asm.
+ * findvar.c (read_register_bytes read_register_gen
+ write_register_bytes read_register read_register_pid
+ write_register write_register_pid supply_register): Move multi-
+ thread handling down into these routines. Create XXX_pid routines
+ that allow register references to specify the pid.
+ * findvar.c infcmd.c (read_pc read_pc_pid write_pc write_pc_pid
+ read_sp write_sp read_fp write_fp): Move these routines from
+ infcmd to findvar to centralize the whole mess.
+ * i386-nlmstub.c: Portability fixes.
+ * infptrace.c (child_resume): Conditionalize to allow other natives
+ to override it. Remove PIDGET gubbish, it's no longer necessary.
+ * infrun.c (wait_for_inferior): Put registers_changed() before
+ target_wait() to speed up remote debugging.
+ * Replace code that reads registers from other threads with much
+ nicer looking new function calls (see changes to findvar.c).
+ * Don't skip prologues if debugging assembly source.
+ * lynx-nat.c (child_resume): Lynx now needs it's own version of
+ child_resume to handle multi-thread debugging properly.
+ * remote.c: Add O response to get console output from target.
+ * (readchar): Add timeout parameter. Handle SERIAL_EOF and
+ SERIAL_ERROR here to simplify callers.
+ * Change static var timeout to remote_timeout.
+ * (fromhex): Remove unnecessary return -1 at end of routine.
+ * (remote_wait): Turn this into a big switch statement. Add
+ support for O response.
+ * (putpkt): Remove unnecessary handling of SERIAL_EOF/ERROR.
+ * (getpkt): Split getpkt into two parts. read_frame deals with
+ all formatting issues, run-length encoding, and framing. getpkt
+ now handles error recovery, and frame detection.
+ * ser-tcp.c (tcp_readchar): Handle EINTR from read().
+ * ser-unix.c (hardwire_raw): Set CLOCAL so that we ignore modem
+ control. (hardwire_readchar): Handle EINTR from read().
+ * symfile.c (deduce_language_from_filename): Add support for .s
+ files.
+ * config/nm-lynx.h: Define CHILD_WAIT so that lynx-nat.c can
+ override infptrace's child_wait.
+ * config/rs6000/rs6000lynx.mh: Use xm-rs6000ly.h & nm-rs6000ly.h
+ instead of XXXlynx.h.
+ * config/rs6000/rs6000lynx.mt: Use tm-rs6000ly.h instead of
+ tm-rs6000lynx.h.
+ * nlm/gdbserve.c: Portability fixes.
+
+Tue May 31 20:35:44 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * inftarg.c (child_wait): Call proc_wait, not wait.
+ (child_mourn_inferior): Call proc_remove_foreign.
+ * main.c (gdb_init): Call init_proc.
+ * main.c: Provide dummy versions of init_proc, proc_wait, and
+ proc_remove_foreign for the gdb case (the libgdb case provides its
+ own versions of these functions).
+ * Makefile.in (libgdb-files): Add libproc.a.
+
+Wed Jun 1 11:08:52 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ Hardware watchpoints for Linux, from Rick Sladkey
+ (jrs@world.std.com).
+ * infrun.c (wait_for_inferior) [HAVE_CONTINUABLE_WATCHPOINT]: Add
+ new hardware breakpoint recovery method.
+ * i386v-nat.c (i386_insert_watchpoint,
+ i386_insert_nonaligned_watchpoint, i386_remove_watchpoint,
+ i386_stopped_by_watchpoint) [TARGET_CAN_USE_HARWARE_WATCHPOINT]:
+ New functions to support the 386 hardware debugging registers.
+ * config/i386/nm-linux.h (TARGET_CAN_USE_HARDWARE_WATCHPOINT,
+ HAVE_CONTINUABLE_WATCHPOINT, STOPPED_BY_WATCHPOINT,
+ target_insert_watchpoint, target_remove_watchpoint): Define these
+ macros to use the hardware debugging functions in i386v-nat.c.
+
+Wed May 25 17:06:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in: Replace libgdb.a with libgdb-files. Make "all"
+ build it.
+
+Thu May 19 09:56:20 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * target.c, target.h: New variables target_activity_function and
+ target_activity_fd.
+ * inflow.c, inferior.h: New functions set_sigio_trap and
+ clear_sigio_trap.
+ * inftarg.c (child_wait), procfs.c (wait_fd): Call them.
+
+Wed May 18 13:01:55 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * remote-sim.h (sim_verbose): Delete.
+ Document callbacks needed.
+ (sim_*): Change result to void where there isn't one.
+ (sim_open): Clarify argument and error response.
+ (sim_close): Declare.
+ (sim_load): Change bfd_handle argument to file name. Clarify result.
+ (sim_create_inferior): Renamed from sim_set_args.
+ (sim_set_pc): Delete.
+ (sim_info): Delete printf_fn argument.
+ * remote-sim.c (gdbsim_kill): Add comment describing purpose.
+ (gdbsim_load): Try sim_load first.
+ (gdbsim_create_inferior): Call sim_create_inferior.
+ (gdbsim_open): Handle args == NULL. Update call to sim_open.
+ (gdbsim_close): Call sim_close.
+ (gdbsim_files_info): Update call to sim_info.
+ (gdbsim_ops): Realign comments.
+
+ * printcmd.c (decode_format): Allow TARGET_PTR_BIT to be non-constant.
+
+Tue May 17 16:45:20 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * xcoffread.c (read_xcoff_symtab): For C_FILE symbols, only use
+ the auxent if the symbol's name is ".file". From David Edelsohn
+ <c1dje@watson.ibm.com>.
+
+Tue May 17 11:08:22 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.c (breakpoint_1): Fix typo.
+
+ * annotate.c (annotate_field_end): Fix typo.
+
+ * Makefile.in: Move annotate.o from COMMON_OBS to OBS.
+
+ * Makefile.in (TSSTART): Remove; no longer used.
+
+ * utils.c (vfprintf_maybe_filtered, vfprintf_unfiltered): Call
+ fputs_unfiltered and exit directly, rather than fatal. The latter
+ calls vfprintf_unfiltered!
+
+ * gdbtypes.h, gdbtypes.c (can_dereference): New function.
+ * value.h, printcmd.c (print_value_flags): Move from here...
+ * annotate.c: ...to here, and make it use can_dereference.
+
+Sat May 14 15:13:52 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * inflow.c (job_control, attach_flag, generic_mourn_inferior):
+ Remove, needed for both native and cross.
+ * target.c (attach_flag, generic_mourn_inferior): Put here.
+ * utils.c (job_control): Put here.
+ (terminal.h): Don't include anymore.
+
+Sat May 14 09:11:44 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * source.c (find_source_lines): Always use code that was #ifdef
+ BROKEN_LARGE_ALLOCA. Do the cleanup before returning, rather than
+ leaving it on the chain. Reindent much of this function.
+ * config/sparc/{xm-sun4sol2.h,xm-sun4os4.h},
+ config/i386/{xm-sun386.h,xm-i386m3.h,xm-i386mach.h},
+ config/m68k/{sun3os4.h,xm-news.h,xm-hp300hpux.h},
+ config/ns32k/xm-ns32km3.h: Remove all references to
+ BROKEN_LARGE_ALLOCA; with the above change it is no longer needed.
+ * main.c, fork-child.c, many config files: Remove all
+ SET_STACK_LIMIT_HUGE code; with the above changes it should no
+ longer be needed.
+
+ * symtab.c (lookup_partial_symbol): Use if and abort, not assert.
+ This avoids __eprintf troubles.
+
+Fri May 13 08:10:21 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * main.c (main): Surround in #ifndef MAIN_OVERRIDE. Move
+ initialization code which needs to be called even if we bypass the
+ command line stuff into gdb_init.
+ * utils.c (fputs_unfiltered): Surround in #ifndef
+ FPUTS_UNFILTERED_OVERRIDE.
+ * Makefile.in (libgdb.a): New target.
+
+ * utils.c: Rearrange I/O stuff a bit so that all output goes
+ through fputs_unfiltered. Use vasprintf; removes arbitrary limit
+ which made %s not work with arbitrarily large strings.
+ * printcmd.c (printf_command): Use printf_filtered, not
+ printf_unfiltered and printf, now that arbitrary limit is gone.
+
+ gcc -Wall lint:
+ * breakpoint.c (watchpoint_check): Remove unused variable b.
+ * stack.c (print_frame_info): Move sp and buf inside #if.
+ * eval.c (evaluate_subexp): Remove unused variables pp,
+ mangle_ptr, ptr, and mangle_tstr.
+ * valarith.c (value_x_binop): Remove unused variables mangle_tstr
+ and mangle_ptr.
+ * symtab.c (lookup_symtab): Put variable copy inside #if.
+ (decode_line_1): Put variable q1 inside #if 0.
+ * target.h: Declare target_link.
+ * infrun.c (wait_for_inferior): Remove unused variables signame.
+ * remote.c (remote_resume): Remove unused variable name.
+ * c-exp.y (parse_number): Parenthesize operand of shift.
+ * dbxread.c (record_minimal_symbol): Parenthesize operand of &&
+ (this is a semantic change, the warning seems to have detected a bug).
+ * dbxread.c (end_psymtab): Move variable p1 inside #if.
+ * coffread.c: Move variable temptype inside #if.
+ * ch-typeprint.c (chill_type_print_base): Remove unused variable
+ name.
+ * ch-valprint.c: #include typeprint.h and ch-lang.h.
+ (chill_val_print): Remove unused variable in_range.
+ (chill_val_print): Remove statement "length > TYPE_LENGTH (type);".
+ (chill_val_print): Add default case for switch.
+ * stabsread.h: Declare stabsect_build_psymtabs.
+ * os9kread.c (read_minimal_symbols): Make this return void.
+ (os9k_symfile_read): Remove unused variables stb_exist and val.
+ (os9k_symfile_init): Remove unused variable val.
+ (fill_sym): Remove unused variable id.
+ (read_os9k_psymtab): Put variable back_to inside #if 0. Remove
+ unused variable nsl.
+ Remove unused variable symfile_bfd.
+ #if 0 unused variables lbrac_unmatched_complaint and
+ lbrac_mismatch_complaint.
+ Remove declaration for non-existent function os9k_next_symbol_text.
+
+ * annotate.c, annotate.h: New files, containing a function for
+ each annotation which outputs it.
+ * Move breakpoints_changed from breakpoint.c to annotate.c.
+ * breakpoint.c, blockframe.c, infrun.c, cp-valprint.c, main.c,
+ printcmd.c, source.c, stack.c, utils.c, valprint.c:
+ Use annotate.c functions to output annotations.
+ * Makefile.in (OBS): Add annotate.o.
+
+Thu May 12 10:46:27 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (read_unwind_info): Make sure elf_unwind_size and
+ elf_unwind_entries are always initialized.
+
+ * hppa-tdep.c (skip_trampoline_code): Handle argument relocation
+ stubs which return directly to the caller rather than to the stub
+ itself.
+
+Wed May 11 20:11:51 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * c-exp.y (yyerror): Display a more informative error message.
+ * ch-exp.y (yyerror): Ditto, don't use global yychar.
+ * m2-exp.y (yyerror): Ditto.
+
+Tue May 10 11:57:53 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * inflow.c (job_control): Move definition to front of file.
+
+Tue May 10 14:42:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * maint.c (print_section_table): Rename SEC_SHARED_LIBRARY to
+ SEC_COFF_SHARED_LIBRARY to match corresponding change in bfd.
+
+Fri May 6 13:30:22 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in (kdb): Remove old init.c creation commands.
+ * configure.in (sparclite): Match on sparclite*.
+ * sparclite/aload.c (main): Only change section addresses for
+ a.out format object files.
+
+Fri May 6 13:24:04 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * config/i386/go32.mh: Define CC.
+
+Fri May 6 11:56:54 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * gdbserver/Makefile.in: Remove irrelevant definitions and
+ comments inherited from the gdb Makefile.
+ (BFD_DIR, BFD, BFD_SRC, BFD_CFLAGS): Add from gdb Makefile.
+ (VERSION): Update to 4.12.3.
+ (gdbserver): Remove any existing executable first.
+ (distclean, realclean): Remove nm.h.
+ * gdbserver/low-lynx.c: Add Sparc Lynx support.
+ * gdbserver/low-sparc.c, gdbserver/low-sun3.c (sys/wait.h):
+ Don't use absolute pathname.
+
+Thu May 5 12:00:22 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * rs6000-nat.c (vmap_ldinfo): Don't fail if fstat returns an
+ error.
+
+Wed May 4 06:56:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infrun.c (proceed, normal_stop, wait_for_inferior), breakpoint.c
+ (print_it_normal): Add annotations for the inferior starting and
+ stopping, and for all the various messages related to how it
+ stopped.
+
+ * printcmd.c (do_one_display): Annotate.
+ * stack.c (print_frame_info): Annotate printing of stack frames.
+
+Wed May 4 18:15:51 1994 Stu Grossman (grossman@cygnus.com)
+
+ * remote.c (get_offsets): Handle case where stub doesn't support
+ qOffsets message.
+
+Wed May 4 15:30:39 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ Add partial support for g++ code compiled with -fvtable-thunks.
+ * c-valprint.c (c_val_print): Add vtblprint support
+ when using thunks.
+ * cp-valprint.c (cp_is_vtbl_member): A vtable can be an array of
+ pointers (if using thunks) as well as array of structs (otherwise).
+ * cp-valprint.c (vtbl_ptr_name_old, vtbl_ptr_name): Move to global
+ level, and make the latter non-static (so define_symbol can use it).
+ * stabsread.c (define_symbol): If the type being defined is a
+ pointer type named "__vtbl_ptr_type", set the TYPE_NAME to that name.
+ * symtab.h (VTBL_PREFIX_P): Allow "_VT" as well as "_vt".
+ * values.c (value_virtual_fn_field): Handle thunks.
+ * values.c (value_headof): Minor efficiency hack.
+ * values.c (value_headof): Incomplete thunk support. FIXME.
+
+Wed May 4 06:56:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * valprint.c (print_longest): Clarify comment about use_local.
+ * printcmd.c, defs.h (print_address_numeric), callers in
+ symmisc.c, symfile.c, stack.c, source.c, remote.c, infcmd.c,
+ cp-valprint.c, core.c, ch-valprint.c, c-valprint.c, breakpoint.c,
+ exec.c: New argument use_local.
+ * source.c (identify_source_line): Use filtered output. Use
+ print_address_numeric.
+
+ * core.c (memory_error), symtab.c (cplusplus_hint, decode_line_1),
+ language.c (type_error, range_error): Use filtered output.
+ * utils.c (error_begin): Update comment to tell people to use
+ filtered output.
+
+ * Makefile.in (HFILES_WITH_SRCDIR): List bfd.h.
+ (HFILES_NO_SRCDIR): List gdbcore.h not gdbcore_h, so as not to get
+ bfd.h.
+
+Tue May 3 07:41:33 1994 Jim Kingdon (kingdon@cygnus.com)
+
+ * procfs.c (procfs_wait): Reinstate code which deduces the signal
+ from the fault, #ifndef FAULTED_USE_SIGINFO.
+ * config/sparc/tm-sun4sol2.h: Define FAULTED_USE_SIGINFO.
+
+Fri Apr 29 18:15:04 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.c (breakpoint_1): Annotate each field of the headers.
+ Explicitly annotate each record.
+
+Fri Apr 29 15:56:18 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * xcoffexec.c: Reformat to standards and lint.
+ (language.h): Include.
+ (exec_close): Declare arg "quitting".
+ (file_command): Declare arg "from_tty".
+ (map_vmap): Cast xmalloc result to PTR.
+ * rs6000-nat.c: Reformat to standards and lint.
+ (exec_one_dummy_insn): Use char array for saved instruction.
+ (fixup_breakpoints): Declare.
+ (vmap_ldinfo): Be more informative in fatal error messages.
+ (xcoff_relocate_symtab): Define to return void.
+ * xcoffsolib.h: Reformat to standards, improve comments.
+ * config/rs6000/nm-rs6000.h (xcoff_relocate_symtab): Declare.
+
+Thu Apr 28 08:40:56 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * utils.c, defs.h (error_begin): New function.
+ (quit): Print annotation before printing the error message.
+ * main.c (return_to_top_level): Print annotation before doing the
+ longjmp.
+ * symtab.c (decode_line_1): Call error not warning and then
+ return_to_top_level. Call error_begin and printf_unfiltered
+ rather calling warning (before calls to return_to_top_level).
+ * core.c (memory_error): Use error_begin, printf_unfiltered,
+ print_address_numeric and return_to_top_level instead of error.
+ Cleans up a FIXME-32x64.
+ * language.c (type_error, range_error): Call error_begin
+ not just target_terminal_ours.
+
+ * dbxread.c (stabsect_build_psymtabs): Assign to sym_stab_info
+ directly, rather than via DBX_SYMFILE_INFO. A cast on the left
+ side of an assignment is non-portable.
+
+ * utils.c (query): Change syntax of query annotations to be
+ consistent with other input annotations.
+ (prompt_for_continue): Likewise for prompt-for-continue annotation.
+
+Thu Apr 28 01:20:39 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mdebugread.c (psymtab_to_symtab_1): Do not call sort_blocks
+ for stabs symtabs.
+ * mips-tdep.c (mips_skip_prologue): Handle prologues for functions
+ that have a stack frame size of 32k or larger (from Paul Flinders).
+ Remove #if 0'd code.
+
+Wed Apr 27 16:33:51 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * lynx-nat.c (CANNOT_STORE_REGISTER): Add a fallback definition
+ for Lynx platforms that need it.
+ * config/nm-lynx.h (__LYNXOS): Define if not already defined.
+
+Wed Apr 27 16:01:37 1994 Jim Kingdon (kingdon@cygnus.com)
+
+ * procfs.c (procfs_wait): Use the signal from the pr_info rather
+ than trying to deduce it from the fault.
+
+Wed Apr 27 12:22:46 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * printcmd.c (print_address_symbolic): Initialize name to empty
+ string to avoid core dump if lookup fails.
+ * remote-e7000.c (printf_e7000debug): Error if target not open.
+
+Tue Apr 26 22:45:24 1994 Stu Grossman (grossman at cygnus.com)
+
+ * i386-nlmstub.c: Update to be more in line with PIN stub.
+ * nlm/gdbserve.c (putDebugChar): Install bug fix from i386-nlmstub.
+ * (hex2mem): Init ptr.
+ * General cleanups to use ConsolePrintf, standard prologues, etc...
+
+Tue Apr 26 10:23:04 1994 Stu Grossman (grossman at cygnus.com)
+
+ * i386-nlmstub.c: More changes to be compatible with remote.c.
+
+ * dbxread.c: Move a bunch of strncmps out of process_one_symbol
+ into (the far less frequently called) dbx_symfile_read.
+
+ * i386-nlmstub.c: An interim version till we get PIN for the x86.
+
+Tue Apr 26 09:50:45 1994 Stu Grossman (grossman at cygnus.com)
+
+ * dbxread.c (record_minimal_symbol): Record the section
+ associated with the symbol to make dynmaic relocation work.
+ * (dbx_symfile_read, process_one_symbol): Fixes to work around
+ Solaris brain-damage which don't apply to relocatable object
+ files.
+ * (stabsect_build_psymtabs): New routine to read stabs out of an
+ arbitrarily named section.
+ * nlmread.c (nlm_symtab_read): Read ALL syms from the NLM, not just
+ globals.
+ * (nlm_symfile_read): Call stabsect_build_psymtabs to read the
+ stabs out of the nlm.
+ * partial-stabs.h (cases 'f' & 'F'): Fixes to work around Solaris
+ brain-damage which don't apply to relocatable object files.
+ * remote.c (putpkt): Improve error reporting and error handling.
+ * (get_offsets): Temporary kludge to force data & bss sections to
+ have the same relocation.
+ * stabsread.c (define_symbol, scan_file_globals): Record section
+ info in sym.
+
+Sat Apr 23 19:05:52 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.c (breakpoint_1): Annotate each field of output. Add
+ FIXME-32x64 comment.
+
+Fri Apr 22 16:43:54 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infrun.c (wait_for_inferior): Move call to flush_cached_frames
+ to after call to target_wait. This means that flush_cached_frames
+ can call target_terminal_ours if it wants to.
+ * infrun.c (wait_for_inferior) [HAVE_NONSTEPPABLE_WATCHPOINT]: Add
+ comment about why the code is dubious.
+
+ * stabsread.c (read_type): Call read_type, not nonexistent
+ os9k_read_type.
+
+Fri Apr 22 14:25:36 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * remote-os9k.c (rombug_fetch_registers): set trace mode
+ correctly.
+ * remote-os9k.c (rombug_read_inferior_memory): cache data in
+ buffer.
+ * os9kread,c (read_os9k_psymtab): process file symbol to truncate
+ extra info.
+ * os9kread.c (os9k_read_ofile_symtab): proper casting of args
+ passed to process_one_symbol.
+ * stabsread.c (read_type): process os9k functio prototype.
+
+Fri Apr 22 11:27:39 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * solib.c (symbol_add_stub): If so->textsection is NULL, don't
+ dump core.
+
+Thu Apr 21 07:45:49 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * utils.c (prompt_for_continue): Annotate prompt.
+ (query): Annotate query.
+ * printcmd.c (print_frame_args): Change syntax of argument
+ annotation to make name and value part of a single group of
+ annotations, not two separate groups.
+ * cp-valprint.c (cp_print_value_fields): Likewise for fields.
+ * valprint.c (val_print_array_elements): Change syntax of
+ annotation to be more concise.
+ * main.c, defs.h (command_line_input): New argument tells what
+ string to include in the annotations.
+ * symtab.c (decode_line_2), main.c (read_command_lines,
+ command_loop): Change callers.
+
+ * breakpoint.c (watch_command): Use (CORE_ADDR)0, not NULL, for
+ target null pointer.
+ * blockframe.c (find_frame_addr_in_frame_chain): Likewise.
+
+ * printcmd.c (output_command): Annotate things we print here too.
+ * printcmd.c (print_command_1): Add "value-history-value" annotation.
+ * Move declaration of print_value_flags from defs.h to value.h.
+ * main.c (command_line_input): Call wrap_here as well as gdb_flush.
+
+Thu Apr 21 09:29:37 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dbxread.c (read_dbx_dynamic_symtab): Reinstall support for sun3,
+ BFD handles sun3 dynamic relocations now.
+ * elfread.c (elf_symtab_read, elf_symfile_read): Handle dynamic
+ symbol table.
+
+Wed Apr 20 19:41:21 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * printcmd.c (print_command_1): Annotate the top-level expressions
+ that we print.
+ (print_frame_args): Annotate each argument.
+ * printcmd.c, defs.h (print_value_flags): New function.
+ * cp-valprint.c (cp_print_value_fields): Annotate each field.
+ * valprint.c (val_print_array_elements): Annotate each array element.
+
+Wed Apr 20 13:18:41 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * findvar.c (read_var_value): Handle LOC_REPARM_ADDR case correctly,
+ the register contains a pointer to the type, not the type itself.
+
+Mon Apr 11 10:44:35 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * main.c (main): Accept --annotate=N option and make --fullname
+ the same as --annotate=1.
+ (command_line_input): Print annotatation before and after prompt.
+ * blockframe.c (flush_cached_frames): Print annotation.
+ * Rename frame_file_full_name to annotation_level and move it from
+ symtab.h to defs.h.
+ * source.c (identify_source_line): If annotation_level > 1,
+ change output format.
+ * breakpoint.c: Print annotation whenever a breakpoint changes.
+ * main.c: New variable server_command.
+ (command_line_input): Parse "server " and set server_command.
+ (dont_repeat): Check server_command.
+
+Wed Apr 20 08:37:16 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * xcoffread.c (xcoff_next_symbol_text): Don't return before
+ updating raw_symbol and symnum. Return a value in the case where
+ we complained.
+
+ * dstread.c, coffread.c: Don't define pending_blocks; buildsym.c
+ takes care of it.
+ * parse.c: Don't define block_found; it is defined in symtab.c.
+ * parser-defs.h: Add comment regarding block_found.
+
+Tue Apr 19 09:46:05 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (internalize_unwind_info): Delete unused indexp
+ argument.
+
+Mon Apr 18 13:18:56 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dbxread.c (read_dbx_dynamic_symtab): Relocate BFD symbols by
+ section vma. Do not read dynamic relocs for sun3 executables to
+ avoid BFD assertion message.
+
+Mon Apr 18 10:08:07 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * nm-hppab.h (KERNEL_U_ADDR): Define.
+ (FIVE_ARG_PTRACE): Likewise.
+ (CANNOT_STORE_REGISTER): Likewise.
+ * nm-hppah.h (KERNEL_U_ADDR): Define.
+ (FIVE_ARG_PTRACE): Likewise.
+ (CANNOT_STORE_REGISTER): Likewise.
+ (NEED_TEXT_START_END): Likewise.
+
+ * tm-hppah.h (NEED_TEXT_START_END): Delete definition.
+ * xm-hppah.h (KERNEL_U_ADDR): Delete definition.
+ (FIVE_ARG_PTRACE): Likewise.
+ * xm-hppab.h (KERNEL_U_ADDR): Delete definition.
+ (FIVE_ARG_PTRACE): Likewise.
+
+ * hppa-tdep.c (read_unwind_info): Make static.
+ (restore_pc_queue): Indirect through the target vector to
+ reload the register state.
+
+Sat Apr 16 22:20:51 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * paread.c (compare_unwind_entries): Delete function. It's been
+ moved into hppa-tdep.c.
+ (read_unwind_info): Likewise.
+ (pa_symfile_read): No longer call read_unwind_info. The unwind
+ tables will be read in as they are needed.
+
+ * hppa-tdep.c (compare_unwind_entries): New function.
+ (read_unwind_info, internalize_unwinds): Likewise.
+ (find_unwind_entry): Read in unwind information on demand.
+
+Fri Apr 15 11:53:46 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * source.c (DIRNAME_SEPARATOR): New macro, replaces all references
+ to : in search path processing.
+ * defs.h (qsort): Rename argument in prototype.
+ * symtab.h (SAYMBOL_VALUE): Rename value field, avoids bugs in
+ some compilers.
+ * breakpoint.c, exec.c, mdebugread.c, mipsread.c, xcoffexec.c
+ (false): Eliminate usages.
+
+Fri Apr 15 11:35:19 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * h8500-tdep.c (initialize_h8500_tdep, large_command):
+ All references to value changed to value_ptrlage_command is now
+ called big_command.
+ All references to value changed to value_ptr.
+ * remote-e7000.c (e7000_wait): Use target_waitstatus and SETSTOP
+ * remote-hms.c (hms_wait): Timeout after five seconds.
+ * ser-go32.c (dosasync_read): Poll if timeout < 0.
+ * config/tm/tm-h8500.h (BEFORE_MAIN_LOOP_HOOK): Deleted.
+ * config/sh/tm-sh.h (BREAKPOINT): Is now sleep opcode.
+
+Thu Apr 14 07:01:56 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * procfs.c (procfs_wait): Protect watchpoint code with appropriate
+ #ifdefs.
+ (procfs_set_watchpoint, procfs_stopped_by_watchpoint): Likewise.
+
+Wed Apr 13 14:52:46 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * breakpoint.h (enum bptype): Add bp_hardware_watchpoint and
+ bp_watchpoint_scope breakpoints.
+ (struct breakpoint): Add val_chain and related_breakpoint fields
+ for use by watchpoints.
+
+ * breakpoint.c (within_scope): Delete. No longer used.
+ (TARGET_CAN_USE_HARDWARE_WATCHPOINT): Provide default definition.
+ (target_{remove,insert}_watchpoint): Likewise.
+ (can_use_hardware_watchpoint): New function.
+ (remove_breakpoint): New function to remove a single breakpoint
+ or hardware watchpoint.
+ (insert_breakpoints): Handle insertion of hardware watchpoints.
+ Store a copy of the value chain derived from the watchpoint
+ expression.
+ (remove_breakpoints): Simplify by using remove_breakpoint.
+ (delete_breakpoint): Likewise.
+ (watchpoint_check): Delete the watchpoint and watchpoint scope
+ breakpoints when the watchpoint goes out of scope. Save & restore
+ the current frame after checking watchpoints.
+ (breakpoint_init_inferior): Likewise (restarting the program
+ makes all local watchpoints go out of scope).
+ (bpstat_stop_status): Handle hardware watchpoints much like normal
+ watchpoints. Delete the watchpoint and watchpoint scope breakpoint
+ when the watchpoint goes out of scope. Remove and reinsert all
+ breakpoints before returning if we stopped when a hardware watchpoint
+ fired.
+ (watch_command): Use a hardware watchpoint when possible. If
+ watching a local expression, build a scope breakpoint too.
+ (map_breakpoint_numbers): Also call given function for any
+ related breakpoints.
+ (disable_breakpoint): Never disable a scope breakpoint.
+ (enable_breakpoint): Handle hardware breakpoints much like normal
+ breakpoints, but recompute the watchpoint_scope breakpoint's
+ frame and address (if we have an associated scope breakpoint).
+ (read_memory_nobpt): Handle hardware watchpoints like normal
+ watchpoints. When necessary handle watchpoint_scope breakpoints.
+ (print_it_normal, bpstat_what, breakpoint_1, mention): Likewise.
+ (clear_command, breakpoint_re_set_one, enable_command): Likewise.
+ (disable_command): Likewise.
+
+ * blockframe.c (find_frame_addr_in_frame_chain): New function.
+ Extern prototype added to frame.h
+
+ * infrun.c (wait_for_inferior): Set current_frame and select
+ a frame before checking if we stopped due to a hardare watchpoint
+ firing. Handle stepping over hardware watchpoints.
+ (normal_stop): Remove unnecessary call to select_frame.
+
+ * value.h (value_release_to_mark): Declare.
+ * values.c (value_release_to_mark): New function.
+
+ * procfs.c (procfs_wait): Add cases for hardware watchpoints.
+ (procfs_set_watchpoint, procfs_stopped_by_watchpoint): New functions.
+
+ * hppab-nat.c (hppa_set_watchpoint): New function.
+
+ * config/pa/nm-hppab.h (STOPPED_BY_WATCHPOINT): Define.
+ (HAVE_STEPPABLE_WATCHPOINT): Define.
+ (TARGET_CAN_USE_HARDWARE_WATCHPOINT): Define.
+ (target_{insert,delete}_watchpoint): Define.
+
+ * config/mips/nm-irix4.h (TARGET_CAN_USE_HARDWARE_WATCHPOINT): Define.
+ (STOPPED_BY_WATCHPOINT, HAVE_NONSTEPPABLE_WATCHPOINT): Likewise.
+ (target_{insert,remove}_watchpoint): Likewise.
+
+Mon Apr 11 19:21:27 1994 Stu Grossman (grossman at cygnus.com)
+
+ * xcoffread.c (read_xcoff_symtab): Ignore symbols of class C_EXT,
+ smtyp XTY_LD, sclass XMC_DS (external data segment label). They
+ often have the same names as debug symbols for functions, and
+ confuse lookup_symbol().
+
+Mon Apr 11 10:44:35 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * remote.c: Around redefinition of PBUFSIZE, adjust whitespace.
+ * config/pa/tm-hppa.h (REGISTER_BYTES): Use 4 rather than
+ REGISTER_RAW_SIZE (1).
+ Together these changes work around a bug in HP's compiler. Both
+ seem to be necessary.
+
+Mon Apr 11 09:18:24 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * paread.c (pa_symtab_read): Handle ST_STUB symbols and symbols
+ with scope SS_EXTERNAL. ST_ENTRY symbols in dynamic executables
+ are type mst_solib_trampoline.
+
+Fri Apr 8 17:14:37 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * config/m68k/es1800.mt: Change comments.
+
+Fri Apr 8 17:14:37 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * config/m68k/monitor.mt (TDEPFILES): Don't include remote-es.o.
+
+Fri Apr 8 15:35:30 1994 Stu Grossman (grossman at cygnus.com)
+
+ * lynx-nat.c: Restore regmap structure for SPARC. It's needed
+ for core files.
+
+Fri Apr 8 14:53:35 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * values.c (unpack_long): Remove obsolete comment about using a
+ switch statement.
+
+ * symfile.c (symbol_file_command): Add comments about command syntax.
+
+Thu Apr 7 17:25:21 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+ Jim Kingdon (kingdon@cygnus.com)
+
+ * infrun.c (IN_SOLIB_TRAMPOLINE): Correct comment, trampolines
+ are in the .plt section.
+ * minsyms.c (lookup_solib_trampoline_symbol_by_pc,
+ find_solib_trampoline_target): New functions for handling
+ stepping into -g compiled shared libraries.
+ * symtab.h (lookup_solib_trampoline_symbol_by_pc,
+ find_solib_trampoline_target): Add prototypes.
+ * config/tm-sunos.h (IN_SOLIB_TRAMPOLINE, SKIP_TRAMPOLINE_CODE):
+ Define to handle stepping into -g compiled shared libraries.
+ * config/tm-sysv4.h (SKIP_TRAMPOLINE_CODE): Define to handle
+ stepping into -g compiled shared libraries.
+
+Thu Apr 7 17:22:54 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * configure.in: Add mips-*-sysv4* support.
+ * config/mips/mipsv4.mh, config/mips/mipsv4.mt,
+ config/mips/tm-mipsv4.h, config/mips/xm-mipsv4.h, mipsv4-nat.c:
+ New files for MIPS SVR4 support.
+ * Makefile.in: Update for new mipsv4 files.
+ * alpha-tdep.c (heuristic_proc_desc, find_proc_desc): Use
+ read_next_frame_reg to obtain the frame relative stack pointer.
+ * mips-tdep.c (heuristic_proc_desc): Use read_next_frame_reg to
+ obtain the frame relative stack pointer.
+ * mdebugread.c (parse_partial_symbols, psymtab_to_symtab1):
+ Handle stStatic and stStaticProc symbols in stabs-in-ecoff output
+ by entering them into the minimal symbol table.
+ * printcmd.c (print_scalar_formatted): Do not try to unpack to
+ a long for float formats.
+ * solib.c: Include "elf/mips.h" only if DT_MIPS_RLD_MAP does not
+ get defined in <link.h>.
+ * solib.c (solib_add): Add shared library sections to the section
+ table of the target before adding the symbols.
+ * partial-stab.h: Relocate static and global functions.
+ * dbxread.c (read_dbx_symtab): Remove unused variable
+ end_of_text_address. Relocate text_addr when passing it
+ to end_psymtab.
+
+ For Alpha OSF/1 targets, enable gdb to set breakpoints in shared
+ library functions before the executable is run. Retrieve dynamic
+ symbols from stripped executables.
+ * mipsread.c (read_alphacoff_dynamic_symtab): New function.
+ * mipsread.c (mipscoff_symfile_read): Use it. Issue warning message
+ if no debugging symbols were found.
+ * alpha-tdep.c (alpha_skip_prologue): Silently return the unaltered
+ pc if memory at the pc is not accessible and GDB_TARGET_HAS_SHARED_LIBS
+ is defined.
+ * config/alpha/nm-alpha.h (GDB_TARGET_HAS_SHARED_LIBS): Define,
+ OSF/1 has shared libraries.
+
+Thu Apr 7 15:11:11 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * dbxread.c (read_dbx_dynamic_symtab): Adjust for recent changes
+ to BFD handling of dynamic symbols.
+
+Tue Apr 5 15:29:25 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (hppa_fix_call_dummy): If FUN is a procedure label,
+ then gets its real address into FUN and its GOT/DP value into %r19.
+
+ * tm-hppa.h (CALL_DUMMY): Use %r20, not %r19 as a temporary.
+
+ * hppa-tdep.c (frameless_function_invocation): If no unwind
+ descriptor was found, then assume this was not a frameless
+ function invocation.
+ (frame_saved_pc): If the saved PC is in a linker stub, then
+ return the return address which the linker stub will return to.
+
+ * xm-hppab.h: Never define USG.
+ * xm-hppah.h: Always define USG.
+
+Tue Apr 5 12:58:47 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * values.c (unpack_long, value_from_longest),
+ valarith.c (value_binop): Allow TYPE_CODE_RANGE.
+
+Fri Apr 1 14:04:34 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * symfile.c (deduce_language_from_filename): .cpp is a C++ extension.
+
+Fri Apr 1 00:44:00 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ For SVR4 targets, enable gdb to set breakpoints in shared
+ library functions before the executable is run.
+ * elfread.c (elf_symtab_read): Handle symbols for shared library
+ functions.
+ * sparc-tdep.c (in_solib_trampoline): Renamed to in_plt_section
+ and moved to objfiles.c.
+ * objfiles.c (in_plt_section): Moved to here from sparc-tdep.
+ * config/tm-sysv4.h (IN_SOLIB_TRAMPOLINE): Use new in_plt_section.
+ * config/sparc/tm-sun4sol2.h (IN_SOLIB_TRAMPOLINE): Removed,
+ the new generic definition from tm-sysv4.h works for Solaris.
+
+Wed Mar 30 16:14:27 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfread.c (elf_symtab_read): Change storage_needed,
+ number_of_symbols and i to long. Rename get_symtab_upper_bound to
+ bfd_get_symtab_upper_bound. Check for errors from
+ bfd_get_symtab_upper_bound and bfd_canonicalize_symtab.
+ * nlmread.c (nlm_symtab_read): Same changes.
+
+Wed Mar 30 11:43:29 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * xcoffread.c (xcoff_next_symbol_text): New function.
+ (read_xcoff_symtab): Set next_symbol_text_func to it.
+ Move raw_symbol outside of read_xcoff_symtab.
+
+ * remote.c (getpkt): Remove unused "out" label.
+
+Wed Mar 30 09:15:42 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * breakpoint.c (print_it_normal): Allow GDB to notify the user
+ about more than one watchpoint being triggered.
+
+Wed Mar 30 08:24:18 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/m68k/tm-dpx2.h: Include tm-m68k.h not nonexistent tm-68k.h.
+
+Wed Mar 30 00:31:49 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * blockframe.c (find_pc_partial_function): mst_file_text
+ symbols do not live in the shared library transfer table.
+ * ch-exp.y (decode_integer_value, match_character_literal,
+ match_bitstring_literal): Guard tolower calls with isupper,
+ tolower on old BSD systems blindly subtracts a constant.
+ * dbxread.c (read_ofile_symtab): Check for __gnu_compiled_* as
+ well when determining the producer of the object file.
+ * mdebugread.c (has_opaque_xref): New function to check for
+ cross reference to an opaque aggregate.
+ * mdebugread.c (parse_symbol, parse_partial_symbols): Do not
+ enter typedefs to opaque aggregates into the symbol tables.
+ * mdebugread.c (parse_external): Remove skip_procedures argument,
+ it has always been 1. Remove code that handled stProc symbols,
+ it was never executed and was wrong, as the index of a
+ stProc symbol points to the local symbol table and not to the
+ auxiliary symbol info. Update caller.
+ * mdebugread.c (parse_partial_symbols): Do not enter external
+ stProc symbols into the partial symbol table, they are already
+ entered into the minimal symbol table.
+ * config/i386/tm-symmetry.h: Clean up, it is now only used for Dynix.
+ Remove all conditionals and definitions for ptx.
+ I386_REGNO_TO_SYMMETRY moved to here from symm-tdep.c.
+ Fix addresses of floating point registers in REGISTER_U_ADDR.
+ STORE_STRUCT_RETURN now handles cc and gcc conventions.
+ FRAME_CHAIN, FRAMELESS_FUNCTION_INVOCATION, FRAME_SAVED_PC,
+ IN_SIGTRAMP, SIGCONTEXT_PC_OFFSET defined to make backtracing through
+ signal trampoline code work.
+ * config/i386/xm-symmetry.h: Clean up, it is now only used for Dynix.
+ Remove all conditionals and definitions for ptx.
+ Remove KDB definitions.
+ * symm-nat.c (store_inferior_registers): Fetch registers before
+ storing them to obtain valid floating point control registers.
+ Store fpu registers.
+ * symm-nat.c (print_1167_control_word): Dynix 3.1.1 defines
+ FPA_PCR_CC_C0 and FPA_PCR_CC_C1, avoid duplicate case value.
+ * symm-nat.c (fetch_inferior_registers, child_xfer_memory):
+ Fix typos.
+ * symm-nat.c (child_resume): Update type of `signal' parameter.
+ * symm-tdep.c (I386_REGNO_TO_SYMMETRY): Moved to tm-symmetry.h.
+
+Tue Mar 29 23:01:33 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (hppa_fix_call_dummy): Use an alternate method for
+ calling import stubs for functions in shared libraries.
+
+Tue Mar 29 21:14:04 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * ch-exp.y: Implement SIZE(mode_name) and SIZE(expression).
+
+ * ch-lang.c (chill_is_varying_struct): Magic string is
+ was "<var_length>" is now "__var_length" (more portable).
+
+Tue Mar 29 19:41:34 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote.c (getpkt): If we get a timeout, actually retry rather
+ than just giving up the first time it happens.
+ * remote.c: Document sequence numbers.
+ (remote_store_registers): Change syntax of 'P' request so that it
+ never looks like a sequence number.
+
+Tue Mar 29 16:06:01 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * os9kread.c (record_minimal_symbol): add section_offset to
+ relocate minimal symbol table.
+ * os9kread.c (read_minimal_symbols): ditto.
+ * os9kread.c (os9k_symfile_init): increase size of dbg and stb
+ file names.
+ * os9kread.c (read_os9k_psymtab): if there's no dbg file, just
+ return. Also if file addr is 0 leave it 0, not to relocate.
+ * remote-os9k.c (_initialize_remote_os9k): add 'set remotexon',
+ 'set remotexoff' and 'set remotelog' commands.
+
+Tue Mar 29 12:38:45 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote.c (remote_store_registers): Add 'P' request to set an
+ individual register.
+ (remote_write_bytes, remote_read_bytes): Use %lx, not %x, to print
+ a target address.
+
+Sat Mar 26 07:05:18 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/sparc/tm-sparc.h: Define USE_REGISTER_NOT_ARG.
+ * stabsread (define_symbol): If USE_REGISTER_NOT_ARG, go back to
+ combining all 'p' and 'r' pairs into a LOC_REGPARM.
+
+ * command.c (do_setshow_command, case var_string): Never add a
+ space to the end of the string.
+ * NEWS: Document this change.
+ * .gdbinit: Add a space to the "set prompt" command.
+
+Fri Mar 25 12:40:41 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * m3-nat.c, i386m3-nat.c, config/i386/i386m3.mh: Many minor
+ changes to make it compile (it doesn't link yet).
+
+ * buildsym.c (start_subfile, patch_subfile_names), demangle.c
+ (set_demangling_style, set_demangling_command): Use savestring not
+ strdup. We were not dealing properly with a NULL return from
+ strdup, and were not declaring strdup (the system header may or
+ may not have it).
+
+ * valprint.c (val_print): Remove inaccurate comment about what
+ types can be stub types.
+
+ * config/i386/ptx.mh (XDEPFILES): Add coredep.o. Delete infptrace.o.
+ * symm-nat.c (child_wait, _initialize_symm_nat, kill_inferior):
+ Supply alternate version if ATTACH_DETACH is not defined.
+ * ptx4-nat.c, config/i386/{nm-ptx4.h, ptx4.mh, ptx.mt, ptx4.mt,
+ tm-ptx.h, tm-ptx4.h, xm-ptx.h, xm-ptx4.h}: New files.
+ * configure.in: Recognize i[34]86-sequent-sysv4* host.
+
+Fri Mar 25 10:14:03 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (skip_prologue): Do nothing if not at the beginning
+ of a function.
+ (skip_trampoline_code): Rewrite and add support for argument
+ relocation stubs stubs, import/export stubs, calls through
+ "_sr4export" and cascaded trampolines.
+
+ * hppa-tdep.c (skip_prologue): Return "pc" not zero
+ if no unwind descriptor is found.
+
+ * tm-hppa.h (NUM_REGS): Bump to 128 registers.
+ (REGISTER_NAMES): Add entries for "right-half" of FP registers.
+ (REGISTER_RAW_SIZE, MAX_REGISTER_RAW_SIZE): Do not treat FP regs
+ differently. All registers are four bytes.
+ (REGISTER_BYTES, REGISTER_BYTE): Simplify now that all registers are
+ the same size.
+ (REGISTER_VIRTUAL_TYPE): Use builtin_type_float for all FP regs.
+
+ * hppa-tdep.c (pa_print_fp_reg): Update to print even numbered FP
+ registers as both single and double values (fetching 2nd 32bit half
+ as necessary). Annotate each register printed with its precision.
+
+ * paread.c (read_unwind_info): Fix off-by-one error.
+
+Fri Mar 25 08:33:28 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * main.c (complete_command): Deal with it if arg is NULL.
+
+Thu Mar 24 07:12:09 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/mips/tm-mips.h (SETUP_ARBITRARY_FRAME): Revise comment
+ regarding using the PC--using the PC is necessary and all the
+ FIXME comments in the world won't make it go away.
+
+ * valops.c (value_at, value_at_lazy): Give error if we dereference
+ a pointer to void.
+ * gdbtypes.h: Fix comments regarding TYPE_CODE_VOID.
+ * stabsread.c: Use 1, not 0, for TYPE_LENGTH of void types.
+
+ * stabsread.c (patch_block_stabs): Add comment about what happens
+ if the definition is in another compilation unit from the stab.
+
+ * dbxread.c (end_psymtab): Add comment about empty psymtabs.
+
+Wed Mar 23 07:50:33 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * main.c (complete_command): New command, from Rick Sladkey
+ <jrs@world.std.com>.
+ (symbol_completion_function): Don't declare rl_point and
+ rl_line_buffer; they are now declared in readline.h.
+ (show_commands): Don't declare history_base; it is declared in
+ history.h.
+ * command.c (lookup_cmd): Don't delete trailing whitespace.
+ Reverts change of 14 May 1989.
+
+Wed Mar 23 16:14:52 1994 Stu Grossman (grossman at cygnus.com)
+
+ * minsyms.c (prim_record_minimal_symbol): Move section deduction
+ code from prim_record_minimal_symbol_and_info() to here. Callers
+ of the latter can legitimately supply a section number of -1.
+
+Wed Mar 23 07:50:33 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbtypes.h, gdbtypes.c: Add comments regarding whether static
+ member functions have an element in args for a (nonexistent) this
+ pointer.
+
+Tue Mar 22 20:12:53 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/pa/tm-hppao.h (NO_PC_SPACE_QUEUE_RESTORE): Define.
+
+ * hppa-tdep.c (hppa_pop_frame): Do not restore the PC space
+ queue if NO_PC_SPACE_QUEUE_RESTORE is defined.
+
+ * stabsread.c (REG_STRUCT_HAS_ADDR): Accept additional argument
+ for the structure's type. All callers changed.
+
+ * valops.c (call_function_by_hand): Check REG_STRUCT_HAS_ADDR
+ for each structure argument rather than assuming it's either
+ true or false for all structure arguments.
+
+ * config/pa/tm-hppa.h (REG_STRUCT_HAS_ADDR): Depend only
+ on the length structure passed, not the compiler used.
+
+ * config/sparc/tm-sparc.h (REG_STRUCT_HAS_ADDR): Accept additional
+ argument for the structure's type.
+
+Tue Mar 22 15:28:33 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * values.c (set_internalvar): Don't set var->value until we are
+ sure there won't be an error().
+
+ * remote.c (get_offsets): Reinstate comment which was in
+ remote_wait about use of SECT_OFF_TEXT and so on.
+
+Mon Mar 21 13:11:30 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * symmisc.c (maintenance_check_symtabs): New function to check
+ consistency of psymtabs and symtabs.
+ * symtab.h (maintenance_check_symtabs): Add prototype.
+ * maint.c: Add new `maint check-symtabs' command.
+ * config/i386/tm-i386aix.h, config/i386/tm-sun386.h,
+ config/i386/tm-symmetry.h (REGISTER_CONVERT_TO_RAW): Fix typo.
+ * config/i386/tm-symmetry.h: Make comment inside #if 0 a real
+ comment.
+ * config/i386/tm-symmetry.h (STORE_STRUCT_RETURN): Cast argument
+ to write_memory to avoid warnings from gcc.
+ * config/i386/xm-symmetry.h: Add missing #endif.
+ * config/i386/nm-symmetry.h (NO_PTRACE_H): Add for Dynix.
+ * config/i386/symmetry.mt (TDEPFILES): Add i386-tdep.o.
+ * config/i386/symmetry.mh (NAT_FILE, NATDEPFILES): Add.
+
+Mon Mar 21 11:50:28 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (hppa_fix_call_dummy): Use value_ptr.
+ (hppa_push_arguments): Likewise.
+
+Mon Mar 21 11:02:51 1994 Stu Grossman (grossman at cygnus.com)
+
+ * alpha-tdep.c: Gobs of changes (many imported from mips-tdep) to
+ improve remote debugging efficiency. Also fixed problems with
+ doing function calls for programs with no entry points.
+ * infcmd.c (run_stack_dummy): Use CALL_DUMMY_ADDRESS instead of
+ entry_point_address.
+ * inferior.h (PC_IN_CALL_DUMMY): ditto.
+ * mdebugread.c (parse_symbol, parse_procedure, parse_external,
+ parse_lines): Pass section_offsets info to these routines so that
+ we can relocate symbol table entries upon readin.
+ * (psymtab_to_symtab_1): Set symtab->primary to tell
+ objfile_relocate to do relocations for our symbols.
+ * (ecoff_relocate_efi): New routine to relocate adr field of PDRs
+ (which hang off of the symbol table).
+ * Use prim_record_minimal_symbols_and_info instead of
+ prim_record_minimal_symbols to supply section info to make minimal
+ symbol relocations work.
+ * minsyms.c (prim_record_minimal_symbols_and_info): If section is
+ -1, try to deduce it from ms_type.
+ * objfiles.c (objfile_relocate): Use ALL_OBJFILE_SYMTABS where
+ appropriate. Handle relocation of MIPS_EFI symbols special. Also,
+ add code to relocate objfile->sections data structure.
+ * remote.c (get_offsets): Use new protocol message to acquire
+ section offsets from the target.
+ * (remote_wait): Get rid of relocation stuff. That's all handled
+ by objfile_relocate now.
+ * config/alpha/alpha-nw.mt (TM_FILE): Use tm-alphanw.h.
+ * config/alpha/tm-alpha.h: Define CALL_DUMMY_ADDRESS, and
+ VM_MIN_ADDRESS.
+ * config/alpha/tm-alphanw.h: DECR_PC_AFTER_BREAK=0, VM_MIN_ADDRESS=0.
+
+Mon Mar 21 10:09:06 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c (_initialize_hpuxread): Don't call add_symtab_fns if
+ HPREAD is not defined.
+
+Sun Mar 20 15:21:57 1994 Doug Evans (dje@cygnus.com)
+
+ * sparc-tdep.c (sparc_frame_find_save_regs): Use REGISTER_RAW_SIZE
+ instead of 4.
+ * sp64-tdep.c (target_ptr_bit, set_target_ptr_bit): Deleted,
+ can no longer set this at run time.
+ * config/sparc/sp64.mt (SIMFILES): Use remote-sim.o now.
+ (TM_CLIBS): Define to -lm, the simulator uses the sqrt() function.
+ * config/sparc/tm-sp64.h (FPS_REGNUM, CPS_REGNUM): Define (so
+ sparc-tdep.c compiles).
+ (TARGET_PTR_BIT): Must be a constant now, fix at 64.
+
+Sat Mar 19 08:51:12 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/m68k/{cisco.mt,tm-cisco.h}: New files.
+ * Makefile.in (ALLPARAM, ALLCONFIG): Add them.
+ * configure.in: Recognize m68*-cisco*-*.
+
+ * Makefile.in (TAGS): Use variables directly, rather than using
+ find, to locate TM_FILE, XM_FILE, and NAT_FILE. This is faster
+ and means that these filenames no longer need be unique across all
+ the config/* directories.
+ * configure.in: Put the config/*/ into TM_FILE, etc.
+
+ * m68k-stub.c (computeSignal): Return SIGFPE, not SIGURG, for chk
+ and trapv exceptions.
+
+ * target.h (struct section_table), objfiles.h (struct obj_section):
+ Change name of field sec_ptr to the_bfd_section. More mnemonic
+ and avoids the (sort of, for the ptx compiler) name clash with
+ the name of the typedef.
+ * exec.c, xcoffexec.c, sparc-tdep.c, rs6000-nat.c, osfsolib.c,
+ solib.c, irix5-nat.c, objfiles.c, remote.c: Change users.
+
+ * utils.c: Include readline.h.
+ * Makefile.in (utils.o): Add dependency.
+
+ * remote.c (getpkt): Add support for run-length encoding.
+
+Fri Mar 18 19:11:15 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * utils.c (prompt_for_continue): Call readline, not gdb_readline.
+
+Fri Mar 18 10:25:55 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dstread.c (record_minimal_symbol): New arg objfile. Pass it to
+ prim_record_minimal_symbol.
+ Callers: Pass it.
+
+ * regex.c (EXTEND_BUFFER): Adjust pointers within buffer by
+ computing their offset from the start of the old buffer and adding
+ to the new buffer, rather than by assuming we can add the
+ difference between the old buffer and the new buffer (it might not
+ fit in an int). Merge in cosmetic differences from emacs regex.c
+ version of this macro.
+
+Wed Mar 16 15:28:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (install-only): Fix use of program_transform_name.
+
+Wed Mar 16 07:18:43 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * printcmd.c: Remove "set print fast-symbolic-addr off" command.
+ The bug which it worked around was fixed on 25 Feb 94 in coffread.c,
+ so I'm nuking the command.
+ * symtab.c (find_addr_symbol): Comment out, no longer used.
+
+ * main.c (main): Don't init_source_path for the -cd argument. Now
+ that source_path doesn't contain the current_directory from when
+ GDB started up, init_source_path is no longer useful (and is
+ harmful because it clobbers a source_path set in $HOME/.gdbinit).
+
+ * TODO: Remove item about line numbers being off. It is useless
+ and confusing without a reproducible test case (it mentions
+ proceed(), but I was able to step through proceed without trouble).
+
+Tue Mar 15 13:39:23 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ For Sunos 4.x targets, enable gdb to set breakpoints in shared
+ library functions before the executable is run. Retrieve dynamic
+ symbols from stripped executables.
+ * symtab.h (minimal_symbol_type): Add mst_solib_trampoline type.
+ * parse.c (write_exp_msymbol), symmisc.c (dump_msymbols),
+ symtab.c (list_symbols): Handle mst_solib_trampoline.
+ * minsyms.c (lookup_minimal_symbol): Handle mst_solib_trampoline
+ for all targets, remove IBM6000_TARGET dependencies.
+ * dbxread.c (read_dbx_dynamic_symtab): New function.
+ * dbxread.c (dbx_symfile_read): Use it.
+ * dbxread.c (SET_NAMESTRING): Set namestring to
+ "<bad string table index>" instead of "foo" if the string index is
+ corrupt.
+ * xcoffread.c (read_xcoff_symtab): Use mst_solib_trampoline instead
+ of mst_unknown.
+ * symtab.c (list_symbols): Take from_tty as parameter and pass it
+ to break_command. Handle mst_file_* minimal symbol types.
+ * config/i386/tm-i386bsd.h: Give just macro name, not args, to #undef.
+
+Tue Mar 15 11:40:43 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * c-exp.y(yylex): fix potential memory overflow.
+
+Tue Mar 15 10:33:28 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * environ.c (set_in_environ): Eliminate special handling of PATH and
+ GNUTARGET.
+ * putenv.c: Removed, conflicts with system declaration of
+ putenv on RS/6000 running AIX 3.2.5, and above change makes it
+ unnecessary.
+ * Makefile.in: Change accordingly.
+ * procfs.c (procfs_create_inferior): Change comment accordingly.
+
+Tue Mar 15 10:05:27 1994 Jim Kingdon (kingdon@cygnus.com)
+
+ * rs6000-tdep.c: Change value to value_ptr.
+
+Sun Mar 13 17:19:03 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c (read_hpux_symtab: Correctly determine the namespace
+ and address class of SVAR, DVAR, TYPEDEF, TAGDEF, CONST, and
+ MEMENUM symbols. Do not include function-scoped variables in
+ the partial symbol table.
+
+Sun Mar 13 09:45:51 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * i386m3-nat.c: Include floatformat.h.
+ (get_i387_state): Use memset not bzero.
+
+ * Version 4.12.3.
+
+ * Makefile.in: Enable commented out getopt_h, bfd_h, etc. Change
+ ieee-float.h to floatformat.h.
+
+ * valprint.c (val_print_string): Ignore error if the error
+ happened after a terminating '\0'.
+
+ * c-valprint.c (c_val_print): Never add 1 to return value from
+ val_print_string; just return what it returns.
+
+ * target.h (enum target_signal): Add TARGET_SIGNAL_FIRST, for
+ looping through all of the enums.
+ * infrun.c (signals_info): Use it.
+
+Fri Mar 11 08:08:50 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * main.c (main): When printing warning about bad baud rate, don't
+ use warning(); it relies on current_target which isn't set up yet.
+
+ * breakpoint.c (_initialize_breakpoint): Update docstring for
+ tbreak to match what the code actually does. Don't mention tbreak
+ in docstrings for "enable once" or "enable breakpoints once".
+
+Thu Mar 10 08:52:38 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * symfile.h (ADD_PSYMBOL_VT_TO_LIST): Don't put a semicolon after
+ while (0). That defeats the whole purpose of using do . . . while (0).
+ * mdebugread.c (parse_partial_symbols): Don't use ?: expression as
+ list for ADD_PSYMBOL_TO_LIST; the macro takes its address and
+ using a ?: expression as an lvalue is not portable.
+
+ * stabsread.c (define_symbol): If REG_STRUCT_HAS_ADDR, also
+ convert a LOC_ARG to a LOC_REF_ARG. Update code which combines
+ 'p' and 'r' symbol descriptors into a single symbol to look for a
+ LOC_REF_ARG.
+ * README, config/sparc/tm-sparc.h: Update comments.
+
+Wed Mar 9 21:43:24 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mdebugread.c (parse_type): Do not complain for types with
+ an `indexNil' aux index, these are simply undefined types.
+ Remove indexNil check from caller of parse_type.
+ * mdebugread.c (parse_partial_symbols): Do not enter
+ stGlobal, scCommon symbols into the minimal symbol table, their
+ value is the size of the common, not its address.
+ Handle scInit, scFini, scPData and scXData sections.
+ Use minimal symbol type mst_file_* for stLabel symbols, instead of
+ mst_*.
+ Enter stProc symbols into the global_psymbols list once, not into
+ the static_psymbols_list.
+ Get rid of dummy psymtab if it is empty, to allow proper detection
+ of stripped executables.
+ * mdebugread.c (cross_ref): Allow cross references to Fortran
+ common blocks.
+
+Wed Mar 9 15:23:19 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabsread.c (common_block_end, fix_common_block): Stash the
+ struct pending * in the SYMBOL_TYPE, not the SYMBOL_NAMESPACE, so
+ as to not assume that a pointer fits in an enum.
+
+Wed Mar 9 18:56:36 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * os9kread.c (fill_sym): check compiler verion number for pre-
+ UltraC compiler.
+ * os9kread.c (os9k_process_one_symbol): address of symbol is
+ relative to section not module.
+ * stabsread.c (define_symbol): add symbol type 's' as local
+ symbol for os9k.
+ * remote-os9k.c: add command 'set monitor_log' to turn on or off
+ monitor logging.
+ * remote-os9k.c: fix bug in delete breakpoint, single step trace.
+ * remote-os9k.c: fix bug in 'set remotebaud' function.
+ * remote-os9k.c (rombug_link): minimize checking so to improve
+ speed.
+ * symfile.c (symbol_file_command): check if failed to link, also make
+ the command be able to accept more than one filenames.
+ * target.c (target_link): check if failed to link with rombug.
+ * config/i386/tm-i386os9k.h : add #define DECR_PC_AFTER_BREAK 0.
+
+Wed Mar 9 15:23:19 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote-es.c (es1800_child_ops): Don't declare it static.
+
+Tue Mar 8 11:42:39 1994 Jim Kingdon (kingdon@cygnus.com)
+
+ * config/i386/tm-i386v4.h: Give just macro name, not args, to #undef.
+
+Tue Mar 8 06:56:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dbxread.c: New variable lowest_text_address.
+ (record_minimal_symbol, read_dbx_symtab): Set it.
+ (read_dbx_symtab): Use lowest_text_address + text_size instead of
+ end_of_text_address.
+ * config/gould/tm-pn.h: Add comment regarding END_OF_TEXT_DEFAULT.
+
+ * dbxread.c (end_psymtab): Remove old and commented out
+ capping_global and capping_static. Fix comments regarding
+ N_SO_ADDRESS_MAYBE_MISSING to match the real name of the macro.
+
+ * parser-defs.h: Add "extern" to start of variable declarations so
+ we don't end up with commons.
+ * parse.c: Define these variables.
+
+ * irix5-nat.c (find_solib): Cast o_path to CORE_ADDR when using it
+ as one.
+
+Mon Mar 7 13:00:50 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * alpha-tdep.c: Change value to value_ptr.
+
+Sun Mar 6 17:36:53 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * solib.c (elf_locate_base): New function to locate the address
+ of the dynamic linker's runtime structure in the dynamic info section.
+ * solib.c (locate_base): Use it instead of iterating over the list
+ of mapped address segments.
+ * solib.c (look_for_base, bfd_lookup_symbol): Removed, no longer
+ necessary.
+
+Fri Mar 4 09:50:47 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (pc_in_linker_stub): Move decl to beginning of file.
+ (pc_in_interrupt_handler): New function. Also add PARAM decl.
+ (find_proc_framesize): Deal with HPUX setting SAVE_SP bit for
+ signal trampoline and interrupt routines.
+ (frame_saved_pc): Handle signal trampolines and interrupt routines.
+ (frame_chain, frame_chain_valid): Likewise.
+ (hppa_frame_find_saved_regs): Likewise. Also deal with special
+ saved regs convention for SP.
+
+ * tm-hppa[bho].h: FRAME_FIND_SAVED_PC_IN_SIGTRAMP): Define.
+ (FRAME_BASE_BEFORE_SIGTRAMP): Define.
+ (FRAME_FIND_SAVED_REGS_IN_SIGTRAMP): Define.
+
+ * tm-hppah.h (IN_SIGTRAMP): Define.
+
+Thu Mar 3 12:41:16 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * ch-exp.y (match_simple_name_string): Accept '_' as well as an
+ alphabetic character as the start of a name.
+
+ * sparclite/Makefile.in (all install): Build and install aload.
+
+ * configure.in: Accept i[34]86-*-*sysv32 because that is what
+ config.guess and config.sub produce.
+
+ * mips-tdep.c: Change value to value_ptr.
+
+Wed Mar 2 09:17:55 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * breakpoint.c, breakpoint.h, c-valprint.c, ch-valprint.c,
+ cp-valprint.c, eval.c, expprint.c, findvar.c, language.c,
+ objfiles.h, infcmd.c, printcmd.c, stack.c, typeprint.c,
+ valarith.c, valops.c, valprint.c, value.h, values.c: Replace
+ value with value_ptr. This is for the ptx compiler.
+ * objfiles.h, target.h: Don't declare a "sec_ptr" field using a
+ "sec_ptr" typedef.
+ * symm-nat.c: Add a bunch of stuff for symmetry's ptrace stuff.
+ #if 0 i386_float_info.
+ * symm-tdep.c (round): Remove. Also remove sgttyb.
+ * symm-tdep.c: Remove lots of stuff which duplicates stuff from
+ i386-tdep.c. Remove register_addr and ptx_coff_regno_to_gdb.
+ * i386-tdep.c (i386_frame_find_saved_regs): Put in
+ I386_REGNO_TO_SYMMETRY check in case it is needed for Dynix
+ someday.
+ * config/i386/nm-symmetry.h: Change KERNEL_U_ADDR. Move
+ stuff from PTRACE_READ_REGS, PTRACE_WRITE_REGS macros to
+ symm-nat.c. Define CHILD_WAIT and declare child_wait().
+ * config/i386/tm-symmetry.h: Remove call function stuff; stuff in
+ tm-i386v.h is apparently OK.
+ * config/i386/xm-symmetry.h [_SEQUENT_]: Define HAVE_TERMIOS not
+ HAVE_TERMIO. Define MEM_FNS_DECLARED, NEED_POSIX_SETPGID, and
+ USE_O_NOCTTY.
+
+Wed Mar 2 11:31:08 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * osfsolib.c (xfer_link_map_member): Update to use new
+ target_read_string interface.
+
+Wed Mar 2 09:17:55 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * infrun.c (wait_for_inferior): In checking
+ remove_breakpoints_on_following_step, check
+ through_sigtramp_breakpoint as well as step_resume_breakpoint.
+
+Tue Mar 1 16:22:56 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * os9kread.c (os9k_process_one_symbol): Rename
+ VARIABLES_INSIDE_BLOCK to OS9K_VARIABLES_INSIDE_BLOCK.
+ * symfile.c (symbol_file_command): Check for (CORE_ADDR)-1, not
+ (CORE_ADDR)0, from target_link, since that is what it uses.
+ Process name at end, not during parsing (like we did before Kung's
+ change), so that -readnow and -mapped can appear anywhere.
+ Make text_relocation a local variable.
+ * config/i386/i386os9k.mt: Fix comment.
+ * Makefile.in (ALLDEPFILES): Add remote-os9k.c.
+ * os9kread.c: Put "comments" after #endif inside /* */.
+ * stabsread.h: Add os9k_stabs variable.
+ * stabsread.c (start_stabs), os9kread.c (os9k_process_one_symbol):
+ Set it.
+ * stabsread.c (define_symbol): If os9k_stabs, put a 'V' symbol
+ descriptor in global_symbols not local_symbols.
+ (read_type): If os9k_stabs, accept 'c', 'i', and 'b' type
+ descriptors.
+ (read_type): If os9k_stabs, accept function parameters after 'f'
+ type descriptor.
+ (read_array_type): If os9k_stabs, don't expect index type and
+ expect lower and upper to be separated by ',' not ';'.
+ (read_enum_type): If os9k_stabs, read a number before the first
+ enumeration constant.
+ (os9k_init_type_vector): New function.
+ (dbx_lookup_type): Call it when starting new type vector.
+ * config/i386/tm-i386os9k.h: Define BELIEVE_PCC_PROMOTION.
+ * (os9k_process_one_symbol): Call define_symbol not os9k_define_symbol.
+ * os9kstab.c: Removed.
+ * Makefile.in: Update accordingly.
+ * objfiles.c (objfile_relocate_data): Removed.
+ * remote-os9k.c (rombug_wait): Call objfile_relocate
+ not objfile_relocate_data.
+ * objfiles.h, objfiles.c: Remove find_pc_objfile.
+ * remote-os9k.c (rombug_wait): Call find_pc_section not
+ find_pc_objfile.
+ * main.c (quit_command): Check inferior_pid; revert Kung change.
+ * remote-os9k.c (rombug_create_inferior): Set inferior_pid.
+
+Tue Mar 1 14:56:14 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * os9kread.c: New file to read os9000 style symbo table.
+ * os9kstab.c: new file to read os9000 style stabs.
+ * remote-os9k.c: remote protocol talking to os9000 rombug monitor.
+ * objfiles.c (find_pc_objfile): new function to search objfile
+ from pc.
+ * objfiles.c (objfile_relocate_data): new function to relocate
+ data symbols in symbol table.
+ * objfiles.h: Add two aux fields in struct objfile to handle
+ multiple symbol table files situation like in os9000.
+ * symfile.c: Change so 'symbol-file' command can handle multiple
+ files. Also call target_link() to get relocation infos.
+ * target.c (target_link): new function to get relocation info when
+ a symbol file is requested to load.
+ * main.c (quit_command): take out 'inferior_pid != 0' condition,
+ because in cross mode there's no inferior pid, bit they need to
+ be detached.
+ Makefile.in: add os9kread.c os9kstab.c and .o's.
+ configure.in: add i386os9k target.
+ config/i386/i386os9k.mt: new add.
+ config/i386/tm-i386os9k.h: new add.
+
+Tue Mar 1 13:16:10 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/sparc/tm-sun4sol2.h (IN_SIGTRAMP): Handle ucbsigvechandler.
+ * sparc-tdep.c (sparc_frame_saved_pc): Handle ucbsigvechandler.
+
+Tue Mar 1 11:54:11 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * target.c, target.h (target_read_string): Provide error detection to
+ caller. Put string in malloc'd space, so caller need not impose
+ arbitrary limits.
+ * solib.c (find_solib): Update to use new interface.
+ * irix5-nat.c (find_solib): Read o_path from inferior
+ (clear_solib): Free storage for o_path.
+ * valprint.c (val_print_string): Add comments.
+
+Mon Feb 28 23:54:39 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * symtab.c (decode_line_1): Handle the case when skip_quoted does not
+ advance `p'.
+
+Mon Feb 28 12:40:46 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * value.h (struct value): Add modifiable field.
+ * values.c (allocate_value, record_latest_value, value_copy): Set it.
+ (record_latest_value): Don't mess with VALUE_LVAL of value.
+ * valops.c (value_assign): Check it. Reword existing error
+ message on not_lval.
+
+ * mips-tdep.c (mips_step_skips_delay), config/mips/tm-mips.h
+ (STEP_SKIPS_DELAY): Added.
+ * infrun.c (proceed) [STEP_SKIPS_DELAY]: Check for a breakpoint in
+ the delay slot.
+
+ * valprint.c (val_print_string): If errcode is set, always print
+ an error, regardless of force_ellipsis. In the non-EIO case,
+ just print the error message rather than calling error(). Don't
+ access *(bufptr-1) if bufptr points to the start of the buffer.
+ When looking for '\0', don't increment bufptr and addr if bufptr
+ started out already at limit. If an error happens on fetching the
+ first character, don't print the string.
+
+Sun Feb 27 21:05:06 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * config/m68k/tm-apollo68b.h: Remove HAVE_68881 define; it is
+ obsolete.
+
+ * i387-tdep.c, i386-tdep.c i386v-nat.c, i386aix-nat.c,
+ i386m3-nat.c, config/m68k/tm-m68k.h, i960-tdep.c
+ config/i960/tm-i960.h, remote-nindy.c, config/m88k/tm-m88k.h,
+ m88k-tdep.c: Use floatformat.h instead of ieee-float.h.
+ * sparc-tdep.c: Remove now-obsolete ieee-float.h stuff
+ * findvar.c: Update comment regarding ieee-float.h.
+
+Sun Feb 27 21:39:48 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/i386/tm-i386v4.h (I386V4_SIGTRAMP_SAVED_PC, IN_SIGTRAMP,
+ FRAME_CHAIN, FRAMELESS_FUNCTION_INVOCATION, FRAME_SAVED_PC):
+ Define to make backtracing through the various sigtramp handlers
+ work.
+ * i386-tdep.c (i386v4_sigtramp_saved_pc): New routine to fetch
+ the saved pc from ucontext on the stack for SVR4 signal handling.
+
+Fri Feb 25 09:41:11 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * remote.c, remote-mon.c, remote-utils.c, remote-utils.h,
+ target.h, remote-es.c, remote-nindy.c: Don't set baud rate if
+ baud_rate is -1. Remove sr_get_baud_rate and sr_set_baud_rate;
+ just use the global variable itself. When printing baud rate,
+ don't print a baud rate if baud_rate is -1.
+
+ * coffread.c (read_coff_symtab): Pass mst_file_* to
+ record_minimal_symbol for C_STAT symbols. Put C_EXT and C_STAT
+ symbols in the minimal symbols regardless of SDB_TYPE.
+
+Thu Feb 24 08:30:33 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * breakpoint.h (enum bptype): New type bp_through_sigtramp.
+ (bpstat_what_main_action): New code BPSTAT_WHAT_THROUGH_SIGTRAMP.
+ * breakpoint.c (bpstat_what): Return BPSTAT_WHAT_THROUGH_SIGTRAMP
+ if we hit a bp_through_sigtramp breakpoint. Remove kludge which
+ ignored bs->stop for a bp_step_resume breakpoint.
+ * infrun.c (wait_for_inferior): Make a through_sigtramp_breakpoint
+ which performs one (the check_sigtramp2 one) of the functions
+ which had been handled by the step_resume_breakpoint. For each
+ use of the step_resume_breakpoint, make it still use the
+ step_resume_breakpoint, use the through_sigtramp_breakpoint, or
+ operate on both.
+ Deal with BPSTAT_WHAT_THROUGH_SIGTRAMP return from bpstat_what.
+ When setting the frame address of the step resume breakpoint, set
+ it to the address for frame *before* the call instruction is
+ executed, not after.
+
+ * mips-tdep.c (mips_print_register): Print integers using
+ print_scalar_formatted rather than duplicating all the
+ CC_HAS_LONG_LONG and so on.
+ (mips_push_dummy_frame): Use read_register_gen rather than using
+ read_register and then putting it back in target format with
+ store_unsigned_integer. If registers are more than 4 bytes, give
+ an error rather than have some registers overwrite other
+ registers.
+ #if 0 unused include of opcode/mips.h.
+
+ * symfile.h: Don't declare arguments for coff_getfilename.
+
+ * defs.h: Revert Kung change regarding FORCE_LONG_LONG.
+
+Thu Feb 24 08:06:52 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * configure.in (hppa*-*-osf*): New configuration.
+ * config/pa/hppaosf.mt: New target makefile fragment.
+ * config/pa/tm-hppao.h: New target include file.
+
+Thu Feb 24 04:29:19 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * exec.c (print_section_info): Print entry point for exec_bfd only.
+ * ser-unix.c (wait_for): Fix typo in HAVE_TERMIO case.
+ * dwarfread.c: Remove second inclusion of <sys/types.h>, which
+ causes problems if <sys/types.h> has no multiple inclusion protection.
+
+Wed Feb 23 16:28:55 1994 Jeffrey A. Law (law@cygnus.com)
+
+ * tm-hppa.h (CALL_DUMMY): Add two NOP instructions to the end of
+ the call dummy to avoid kernel bugs in HPUX, BSD, and OSF1.
+ (CALL_DUMMY_LENGTH): Changed accordingly.
+
+Wed Feb 23 16:21:25 1994 Stu Grossman (grossman at cygnus.com)
+
+ * sparc-stub.c (trap_low): Make trap handler work for arbitrary
+ numbers of register windows.
+
+ * sparclite/hello.c: Add factorial function for testing.
+ * salib.c: Use macros instead of constants for I/O addresses to
+ make 931 support easier.
+ * sparclite.h: Change constraint for LOC to "rJ" to force use of
+ register in sta/lda instructions.
+
+Wed Feb 23 10:39:18 1994 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * dbxread.c (process_one_symbol): Set
+ block_address_function_relative for COFF like we do for ELF and SOM.
+
+Sat Feb 19 03:17:32 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mdebugread.c (new_psymtab): Pass in section_offsets and set
+ them in the pst.
+ * mdebugread.c (handle_psymbol_enumerators): New function to enter
+ the enumerators of an ecoff enum into the partial symbol table.
+ * mdebugread.c (parse_partial_symbols): Call it.
+ * symfile.c (reread_symbols): Initialize objfile->*_psymbols.next.
+ * symmisc.c (dump_psymtab): Fix typo, clean up output of section
+ offsets. Cast psymtab->read_symtab to PTR before passing it to
+ gdb_print_address.
+ * i386-tdep.c (i386_skip_prologue): Skip over instructions that
+ set up the global offset table pointer in pic compiled code.
+ * config/mips/tm-mips.h (FIX_CALL_DUMMY): For big endian targets,
+ error() on TYPE_CODE_FLT arguments whose size is greater than 8,
+ swap all other TYPE_CODE_FLT arguments as mips_push_arguments
+ ensures that floats are promoted to doubles before they are pushed
+ on the stack.
+
+Fri Feb 18 23:12:59 1994 Stu Grossman (grossman at cygnus.com)
+
+ * sparclite/Makefile.in, sparclite/salib.c, sparclite/sparclite.h:
+ Fixup cache_on and flush_i_cache so that they work for both the
+ 930 and 932 processors. Rewrite most low level funcs (uart
+ access & cache stuff) to use new ASI access macros in sparclite.h.
+ Also make it easy to access second serial port.
+
+Fri Feb 18 22:17:33 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * hp300ux-nat.c: Don't incloude <sys/dir.h>, <sys/ioctl.h>, or
+ <sys/stat.h>; not needed.
+
+Fri Feb 18 08:26:29 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stack.c (print_frame_info): In "pathological" case, don't
+ distrust the line number information.
+
+Fri Feb 18 16:51:14 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * mips-tdep.c (mips_print_register): handle 64 bits register.
+ * valprint.c (print_longest): fix a bug in printing 64 bits value.
+
+Fri Feb 18 08:26:29 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Version 4.12.2.
+
+ * Makefile.in (install): Do the sed for program_transform_name
+ ourselves instead of worrying about INSTALL_XFORM. This enables
+ users to override INSTALL_PROGRAM in the standard way.
+
+ * Makefile.in (c-exp.tab.o, ch-exp.tab.o, m2-exp.tab.o): Don't
+ depend on Makefile.in.
+
+ * defs.h, valprint.c: Make longest_to_int a function not a macro.
+ Only test against INT_MIN if a LONGEST is bigger than an int.
+
+ * README: Change GhostScript to Ghostscript.
+
+Fri Feb 18 07:30:55 1994 Jim Kingdon (kingdon@cygnus.com)
+
+ * config/rs6000/{tm-rs6000lynx.h,nm-rs6000lynx.h,xm-rs6000lynx.h}:
+ Rename to tm-rs6000ly.h, nm-rs6000ly.h, xm-rs6000ly.h for 14
+ character file names.
+ * Makefile.in (ALLPARAM): Add these files.
+
+ * config/mips/littlemips64.mt: Rename to mipsel64.mt for 14
+ character file names.
+ * Makefile.in: Add Kung's new mips64 files.
+
+Thu Feb 17 17:25:47 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * configure.in: add mips64-*-elf, mips64-*-ecoff, mips64el-*-elf,
+ mips64el-*-ecoff and mips64-big-*.
+ * defs.h: get rid of FORCE_LONG_LONG.
+ * mips-tdep.c (mips_find_saved_regs): add sd and sdc1 instruction
+ parsing. Change register size to be MIPS_REGSIZE.
+
+Thu Feb 17 09:30:22 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * corelow.c, exec.c, irix5-nat.c, mipsread.c, objfiles.c,
+ osfsolib.c, rs6000-nat.c, solib.c, symfile.c, utils.c,
+ xcoffexec.c: Use bfd_get_error and bfd_set_error and new error names.
+
+Fri Feb 11 21:47:24 1994 Steve Chamberlain (sac@sphagnum.cygnus.com)
+
+ * remote-hms.c (readchar, hms_open, hms_fetch_register): Made more robust.
+ (remove_commands, add_commands): Add/remove hms-drain when target
+ is connected.
+
+Fri Feb 11 16:11:38 1994 Stu Grossman (grossman at cygnus.com)
+
+ * configure.in: Add Lynx/rs6000 support.
+ * lynx-nat.c: Clean up some Sparc stuff. Clean up ptrace error
+ messages. Add rs6000 support. Don't try to modify unwritable
+ registers.
+ * rs6000-nat.c: Move lots of native dependent stuff (like core
+ file support) from rs6000-tdep.c & xcoffexec.c to here.
+ * rs6000-tdep.c: Move native dependent stuff to nat.c.
+ * xcoffexec.c: Move native dependent stuff to nat.c.
+ * config/rs6000/nm-rs6000.h: Move defs of SOLIB_* macros to here
+ from tm file.
+ * config/rs6000/tm-rs6000.h: Remove defs of SOLIB_* funcs, cuz they're
+ really native.
+ * config/rs6000/tm-rs6000lynx.h, config/rs6000/xm-rs6000lynx.h:
+ New files to support Lynx/rs6000.
+
+Tue Feb 8 00:32:28 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * README: Remove note about gcc warnings on alpha, these should be
+ gone now.
+ * c-exp.y, ch-exp.y, core.c, corelow.c, eval.c, fork-child.c,
+ m2-exp.y, minsyms.c, nlmread.c, parse.c, putenv.c, regex.c
+ remote-utils.c, stabsread.c: Include <string.h>.
+ * regex.c: Include "defs.h", change re_comp argument to const char *.
+ * infptrace.c (fetch_register, store_inferior_registers): Change
+ regaddr to type CORE_ADDR.
+ * config/alpha/alpha-nw.mt, config/alpha/alpha-osf1.mt (MT_CFLAGS):
+ Remove, no longer necessary now that we use bfd_vma for a CORE_ADDR.
+
+Mon Feb 7 09:21:17 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * symtab.h: Always define BYTE_BITFIELD to nothing.
+
+Mon Feb 7 08:44:17 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * config/m68k/{m68k-em.mt,tm-m68k-em.h}: Remove; no longer used.
+ * configure.in: Remove comment about m68k-em.mt.
+ * Makefile.in: Remove references.
+
+Mon Feb 7 08:22:42 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * defs.h [BFD64]: Use BFD_HOST_64_BIT, not nonexistent
+ BFD_HOST_64_TYPE.
+
+Sun Feb 6 15:56:09 1994 Jeff Law (law@wild.cs.utah.edu)
+
+ * hpread.c (hpux_symfile_init): Use obj_som_* rather than obj_* to
+ access BFD private data. Search for the "$TEXT$" space rather
+ than ".text".
+ (hppa_sym_fns): Add bfd target flavour to initializer.
+
+Sun Feb 6 06:55:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * target.c (target_preopen): If target_kill doesn't remove the
+ target from the stack, use pop_target to do it.
+
+ * coffread.c (process_coff_symbol, case C_TPDEF): Don't set name
+ of TYPE_CODE_PTR or TYPE_CODE_FUNC types. This parallels similar
+ changes to stabsread.c from summer 1993.
+
+ * remote-udi.c (udi_files_info): If prog_name is NULL, just skip
+ printing the program, rather than passing NULL to printf.
+ (udi_detach): Set udi_session_id to -1 so that udi_close doesn't
+ try to call UDIDisconnect again. Print better message.
+ (udi_kill): Just call UDIDisconnect ourselves, rather than doing
+ it via udi_close.
+ (udi_create_inferior): If udi_session_id is negative, open a new
+ TIP rather than giving an error.
+
+ * config/mips/mipsm3.mh, config/i386/i386m3.mh,
+ config/ns32k/ns32km3.mh: Define NAT_FILE.
+ * config/nm-m3.h: Change guard from _OS_MACH3_H_ and _OS_MACH3_H
+ (it was inconsistent and namespace-wrong) to NM_M3_H.
+ * m3-nat.c (mach_really_wait): Change parameter name to ourstatus.
+ (m3_open): New function.
+ (m3_ops): Use it.
+ * TODO: Update Mach section.
+
+ * Makefile.in: Remove "rapp" stuff; it is superseded by gdbserver.
+
+Sun Feb 6 13:26:21 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * printcmd.c (printf_command): Add missing single-letter
+ backslash-escape sequences, and improve error message.
+
+Sun Feb 6 06:55:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * corelow.c (solib_add_stub, core_open): Pass address of from_tty
+ rather than trying to shove an int into a pointer and back out
+ again. This avoids compiler warnings.
+
+ * defs.h (alloca): Declare as void *, not char *, on hpux.
+ Don't prototype it, just declare the return type.
+
+Sun Feb 6 03:25:41 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/i386/tm-sun386.h, config/i386/tm-symmetry.h
+ (REGISTER_CONVERT_TO_RAW): Add missing backslash.
+
+Sat Feb 5 08:03:41 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote-mips.c (mips_fetch_registers): If regno is FP_REGNUM or
+ ZERO_REGNUM, just read it as zero without talking to the board.
+
+ * config/i386/tm-i386aix.h (REGISTER_CONVERT_TO_RAW): Add missing
+ backslash.
+ * i386-tdep.c (i386_extract_return_value): Pass TYPE_LENGTH (type)
+ to store_floating, not nonexistent variable len.
+
+ * remote-mips.c (mips_insert_breakpoint, mips_remove_breakpoint):
+ New functions.
+ (mips_store_word): Change calling convention to return errors, and
+ to provide old contents if the caller wants it.
+ (mips_xfer_memory): Deal with errors from mips_store_word.
+ * config/mips/tm-idt.h, config/mips/tm-idtl.h: Remove BREAKPOINT
+ define now that remote-mips.c doesn't use BREAKPOINT.
+
+ * remote-mips.c (mips_create_inferior): Call warning if arguments
+ specified, and then execute "set args" command. Call error, not
+ mips_error, if executable file not specified.
+
+ * remote-e7000.c: Replace "snoop" command (e7000_noecho) with
+ remote_debug.
+
+ * config/rs6000/tm-rs6000.h (STORE_STRUCT_RETURN): Don't cast
+ to unsigned int.
+
+Sat Feb 5 05:27:05 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * value.h (print_longest): Rename "value" to "val" in prototype
+ declaration because some compilers don't like arguments whose
+ names are the same as types.
+ * remote.c (remote_xfer_memory): Cast "myaddr" to unsigned char *
+ before passing it to remote_*_bytes.
+
+Fri Feb 4 15:53:18 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * h8500-tdep.c (saved_pc_after_call): The size of the
+ pc is memory model dependent. (segmented_command,
+ unsegmented_command, _initialize_h8500_tdep): New commands to
+ change memory model.
+ * remote-e7000.c (_initialize_remote_e7000): Change name of snoop
+ command.
+ * remote-hms.c (hms_load): Remove breakpoints when loaded.
+ (hms_wait): Use new status structure
+ (hms_open): Push the target here. (hms_before_main_loop): Not
+ here. (supply_val, hms_fetch_register, hms_store_register): Cope
+ with H8/500 names too. (hms_fetch_register): Take out REGISTER_TYPE.
+ * sh-tdep.c (show_regs, initialize_sh_tdep): New command to print
+ all registers in a compact way.
+
+Fri Feb 4 07:41:13 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * config/rs6000/tm-rs6000.h: Declare rs6000_struct_return_address
+ as CORE_ADDR to match definition in rs6000-tdep.c.
+
+Fri Feb 4 01:14:20 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dwarfread.c (process_dies): Skip nested TAG_compile_unit DIEs.
+ * dwarfread.c (add_partial_symbol): Do not enter opaque aggregate
+ definitions into the psymtab.
+
+Thu Feb 3 12:38:58 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * m68k-stub.c: Treat mc68332 like mc68020 most places. Provide
+ a special exceptionSize for the 68332.
+
+ * remote-udi.c (udi_attach): If no arguments, print error.
+
+Thu Feb 3 17:34:05 1994 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.12.1
+ * NEWS, README: Update to match 4.12 release.
+
+Thu Feb 3 12:38:58 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * command.c (empty_sfunc): New function.
+ (add_set_cmd): Use it instead of not_just_help_class_command.
+ (not_just_help_class_command): Change calling convention back to
+ what it was before yesterday's change.
+
+ * stabsread.c (read_sun_builtin_type): Skip the semicolon at the end
+ of the type if present.
+
+Wed Feb 2 11:16:45 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * printcmd.c (decode_format): Don't blithely set the size for
+ an address to 'w'. Make it 'g' or 'h', depending on TARGET_PTR_BIT.
+
+ * defs.h: Just typedef CORE_ADDR to bfd_vma. Include bfd.h.
+ If BFD64, make a LONGEST a BFD_HOST_64_BIT.
+ * defs.h (longest_to_int): Don't depend on CC_HAS_LONG_LONG; instead
+ always just check against INT_MIN and INT_MAX (this also fixes things
+ if sizeof (long) > sizeof (int), e.g. Alpha).
+ * config/pa/tm-hppa.h, config/i386/sun386.h, config/rs6000/tm-rs6000.h:
+ Don't define LONGEST or BUILTIN_TYPE_LONGEST.
+ * gdbtypes.h: Remove BUILTIN_TYPE_LONGEST and
+ BUILTIN_TYPE_UNSIGNED_LONGEST.
+ * language.h, c-lang.c, ch-lang.c, m2-lang.c, language.c: Remove
+ longest_int and longest_unsigned_int.
+ * value.h (struct value): Just align to LONGEST, rather than worrying
+ about CC_HAS_LONG_LONG.
+ * valarith.c (value_binop): Figure out type ourself based on
+ sizeof (LONGEST) rather than relying on BUILTIN_TYPE_LONGEST. The
+ point is that we don't depend on CC_HAS_LONG_LONG anymore.
+ * valprint.c (val_print_type_code_int): Just call
+ extract_unsigned_integer directly, rather than going through
+ unpack_long.
+ * printcmd.c (decode_format): Remove code which would sometimes
+ change 'g' size to 'w' for integers. print_scalar_formatted handles
+ printing huge integers well enough, thank you.
+
+ * command.c (add_set_cmd, not_just_help_class_command): Change
+ to make this the sfunc, not cfunc, since that is how we call it.
+ * command.h: Comment difference between sfunc and cfunc.
+ * demangle.c (set_demangling_command): Add third arg since that
+ is how it is called.
+ (_initialize_demangler): Use sfunc, not cfunc, for
+ set_demangling_command, since that is how it is called.
+ Remove show_demangling_command; it has no effect.
+
+ * command.c (shell_escape): Report errors correctly (with error
+ message from strerror).
+
+Wed Feb 2 14:35:41 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * xcoffread.c (read_xcoff_symtab): Change CSECT_LEN to use
+ x_scnlen.l rather than x_scnlen to match corresponding change in
+ coff/internal.h.
+
+Wed Feb 2 11:16:45 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbtypes.h, ch-typeprint.c, ch-valprint.c:
+ Change comments regarding TYPE_CODE_BOOL.
+ * language.c (boolean_type): Always return 1 for TYPE_CODE_BOOL,
+ regardless of the language.
+ (value_true): Just call value_logical_not regardless of language.
+ * coffread.c (coff_read_enum_type), stabsread.c (read_enum_type):
+ Remove #if 0'd code which makes some enums TYPE_CODE_BOOL.
+ * language.h: Improve comment for la_builtin_type_vector.
+ * m2-lang.c (_initialize_m2_language): Don't add any fields to
+ builtin_type_m2_bool.
+
+Tue Feb 1 17:13:32 1994 Kevin Buettner (kev@cujo.geg.mot.com)
+
+ * config/m88k/{tm-delta88.h,tm-delta88v4.h}, m88k-tdep.c:
+ Define IN_SIGTRAMP and backtrace correctly through signal handlers.
+
+Tue Feb 1 22:13:25 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * procfs.c (wait_fd): Handle EINTR error return from PIOCWSTOP ioctl
+ by restarting the ioctl.
+
+Tue Feb 1 16:16:25 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * target.h (target_wait): Add comment about calling
+ return_to_top_level.
+
+Tue Feb 1 12:21:00 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coffread.c (read_one_sym): bfd_coff_swap_aux_in now takes
+ additional arguments.
+ * xcoffread.c (read_xcoff_symtab, read_symbol_lineno): Likewise.
+
+Mon Jan 31 16:10:41 1994 Stu Grossman (grossman at cygnus.com)
+
+ * sparc-stub.c: Remove unnecessary #include of memory.h.
+
+Mon Jan 31 12:12:34 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * mips-tdep.c: Remove code which sets saved_regs from
+ init_extra_frame_info and put it in new function mips_find_saved_regs.
+ (READ_FRAME_REG): Remove macro and replace uses with the expansion.
+ * mips-tdep.c, config/mips/tm-mips.h: When examining ->saved_regs,
+ check if it is NULL and call mips_find_saved_regs if so.
+
+ * remote-mips.c: Use unfiltered, not filtered, output most places.
+
+ * blockframe.c (get_prev_frame_info): Detect and stop an infinite
+ backtrace. Revise comments.
+
+Mon Jan 31 09:40:33 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mdebugread.c (parse_procedure): Remove _sigtramp kludges for
+ alpha and irix. The _sigtramp case has to be handled properly
+ in the tdep files if we have no ecoff debugging info.
+ * alpha-tdep.c (alpha_frame_saved_pc, alpha_frame_chain),
+ mips-tdep.c (mips_frame_saved_pc): Handle signal handler frames
+ without PC_REGNUM kludge.
+ * mdebugread.c (fixup_sigtramp), mips-tdep.c (read_next_frame_reg):
+ Clean up handling of mips sigtramp frames, improve comments.
+
+Sat Jan 29 23:25:57 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * paread.c (read_unwind_info): Fix typo.
+
+ * paread.c (pa_symtab_read): Update the "check_strange_names"
+ filter to match GCC's current output. Filter out section symbols
+ (which the HP linker sometimes puts in the wrong place).
+
+Sat Jan 29 07:44:59 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * serial.h (SERIAL_SET_TTY_STATE): Comment return value.
+
+ * Makefile.in (TAGS): Just echo one line, rather than the whole thing.
+
+ * Makefile.in: Remove all references to sparcly-nat.c.
+
+ * Makefile.in (HFILES_NO_SRCDIR): Include dcache.h remote-utils.h
+ remote-sim.h directly, rather than via $(remote_utils_h). This avoids
+ duplicating serial.h and target.h.
+
+ * Makefile.in: Don't set M_INSTALL and M_UNINSTALL. These variables
+ are not used anywhere (a 5 Oct 1993 change removed the uses).
+
+ * config/m68k/monitor.mt (TDEPFILE): Add remote-es.o.
+ * config/m68k/es1800.mt: Add comment.
+ * remote-es.c: Extensive changes to update to current conventions.
+
+ * ser-unix.c (wait_for, hardwire_readchar) [HAVE_TERMIO, HAVE_TERMIOS]:
+ If the timeout is too big to fit in c_cc[VTIME], then do multiple reads
+ to achieve the desired timeout.
+ * serial.h (serial_t): Add field timeout_remaining.
+
+Fri Jan 28 08:45:02 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * c-exp.y (yylex): Reenable nested type code.
+
+Fri Jan 28 15:40:33 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * a29k-tdep.c (examine_tag): Add comment regarding argcount.
+
+ * remote-mips.c (mips_ops): Fix docstring.
+
+ * remote-bug.c (bug_ops): Remove spurious newline from docstring.
+
+ * config/m68k/tm-monitor.h: Changes to bring this into accordance
+ with the old tm-m68k-em.h:
+ (GDBINIT_FILENAME, DEFAULT_PROMPT): Remove.
+ (HAVE_68881): Don't undefine; HAVE_68881 is obsolete.
+ (REGISTER_NAMES): Don't muck with it; what tm-m68k.h has is fine.
+ Add FIXME regarding GET_LONGJMP_TARGET.
+
+ * remote-udi.c (udi_close, udi_detach, udi_kill): Add comments.
+ * infptrace.c (kill_inferior): Add comments.
+ * main.c (quit_command): Call target_close after we kill or
+ detach.
+ * remote-udi.c (udi_close): Don't error() if QUITTING.
+
+Fri Jan 28 11:55:52 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * configure.in: Make m68k-coff and aout add monitor support in
+ addition to the standard serial support.
+
+Fri Jan 28 08:45:02 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * mdebugread.c (psymtab_to_symtab_1): Don't complain on stLabel with
+ index indexNil.
+
+Fri Jan 28 10:40:34 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/pa/tm-hppa.h: Define macro SMASH_TEXT_ADDRESS.
+ * elfread.c (record_minimal_symbol_and_info),
+ dwarfread.c (process_dies), paread.c (pa_symtab_read): Use it.
+
+Thu Jan 27 15:12:23 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * i386-stub.c: Add ".text" right before "mem_fault:".
+
+ * main.c (baud_rate): Add FIXME comment about printing -1 value.
+
+ * remote-utils.c (usage): Fix message to be accurate and conform
+ more closely to normal conventions.
+
+ * remote-utils.c (gr_files_info): Have the exec_bfd test control
+ whether to show information about exec_bfd, and not control whether
+ to show information about device and speed.
+
+ * remote-utils.c (gr_open): If sr_get_device returns NULL, give
+ usage message, don't dump core.
+
+ * remote-bug.c (bug_write_memory): Use alloca, not GCC extension
+ for variable size array.
+ (bug_fetch_register, bug_store_register): Rename "value" to
+ "fpreg_buf" because some compilers don't like variables whose
+ names are the same as types.
+ (bug_store_register): Use a cast when converting char * to
+ unsigned char *.
+
+ * symmisc.c (maintenance_print_symbols): Don't refer to the name
+ of the command in error message (the text was referring to the old
+ name of the command).
+
+ * symmisc.c (dump_symtab): Fix args to fprintf_filtered.
+
+ * c-typeprint.c (c_type_print_base): Have SHOW == 0 mean to print
+ full details on structure elements without names. This partially
+ reverts the changes of 1 Jul 1993 and 31 Aug 1993; I think this aspect
+ of those changes was accidental.
+
+ * stack.c (parse_frame_specification): If SETUP_ARBITRARY_FRAME is
+ defined, make it an error to specify a single argument which is not
+ a frame number.
+
+ * Makefile.in (version.c), main.c (print_gdb_version): Use
+ host_alias and target_alias, not host_canonical and
+ target_canonical, to print configuration.
+
+Wed Jan 26 10:57:21 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * parse.c (write_exp_msymbol): Use new type msymbol_addr_type instead
+ of builtin_type_long. It is necessary to get a type which is
+ TARGET_PTR_BIT bits in size; builtin_type_long might not be big enough.
+
+ Fix many sins which will come up in 32 bit x 64 bit GDB, and
+ various miscellaneous things discovered in the process:
+ * printcmd.c, defs.h (print_address_numeric): New function.
+ * c-valprint.c (c_val_print), ch-valprint.c (chill_val_print)
+ breakpoint.c (describe_other_breakpoints, breakpoint_1, mention),
+ cp-valprint.c (cplus_print_value), infcmd.c (jump_command),
+ printcmd.c, stack.c, symfile.c, symmisc.c, valprint.c:
+ Use it.
+ * utils.c, defs.h (gdb_print_address): New function.
+ * expprint (dump_expression), gdbtypes.h: Use it.
+ * breakpoint.c (describe_other_breakpoints),
+ symmisc.c (dump_symtab, print_symbol):
+ Use filtered not unfiltered I/O.
+ (remove_breakpoints): Remove BREAKPOINT_DEBUG code. Might as well
+ just run gdb under a debugger for this (and it had problems with
+ printing addresses, how to print b->shadow, etc.).
+ * buildsym.c (make_blockvector), core.c (memory_error),
+ exec.c (print_section_info), maint.c (print_section_table),
+ mdebugread.c (parse_procedure), solib.c, source.c, symfile.c,
+ symmisc.c, symtab.c, valops.c, valprint.c, xcoffexec.c:
+ Add comments saying code is broken. Marked with "FIXME-32x64".
+ * dbxread.c (process_one_symbol), partial-stab.h (default),
+ remote-vx.c (vx_run_files_info):
+ Don't cast int being passed to local_hex_string.
+ * symmisc.c (print_symbol): Don't cast long being passed to %lx.
+ * symtab.h (general_symbol_info): Add comment about SYMBOL_VALUE
+ only being a long.
+ * symmisc.c (print_symbol): Print "offset" in message for LOC_ARG
+ and LOC_LOCAL.
+ * printcmd.c (print_address): Remove #if 0 code with ADDR_BITS_REMOVE.
+ * source.c: Include <sys/types.h> regardless of USG.
+
+Tue Jan 25 12:58:26 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * valops.c (value_assign): Set `type' after coercing toval.
+ * c-valprint.c (c_val_print), ch-valprint.c (chill_val_print):
+ Use extract_unsigned_integer to get the address of a reference.
+
+Tue Jan 25 11:31:53 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabsread.c (STABS_CONTINUE, error_type), partial-stab.h:
+ AIX can use ? instead of \ for continuation. Deal with it.
+
+ * paread.c (read_unwind_info): Just assign to objfile->obj_private,
+ not OBJ_UNWIND_INFO. Assigning to a cast is a GCC-ism which
+ the HP compiler in ANSI mode doesn't like.
+
+ * main.c: When defaulting HAVE_SIGSETMASK based on USG, just do it
+ based on USG, rather than defining HAVE_SIGSETMASK to an
+ expression containing defined. Having a macro used in #if expand
+ to an expression containing "defined" is undefined according to
+ ANSI, and the HP compiler in ANSI mode doesn't do what we wanted
+ it to.
+
+Mon Jan 24 20:51:29 1994 John Gilmore (gnu@cygnus.com)
+
+ * sparc-nat.c (fetch_inferior_registers, store_inferior_registers):
+ Clean up the changes of 11 Jan, as recommended by Peter Schauer.
+
+Fri Jan 21 19:10:44 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * ch-exp.y (match_string_literal): Allow a zero-length string.
+ * ch-lang.c (chill_printstr): Don't print zero-length string funny.
+
+Sat Jan 22 17:08:48 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * i386aix-nat.c (i386_float_info): Reverse order of registers before
+ passing them to print_387_status.
+ (print_387_status): Don't subtract top from 7 before using it.
+ * i387-tdep.c: Remove comment about AIX wanting "top" subtracted
+ from 7; the above explains it.
+
+Sat Jan 22 20:25:11 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mips-tdep.c (init_extra_frame_info): Use frame relative stack
+ pointer value when fixing up the frame at the start of a function.
+
+Sat Jan 22 12:29:13 1994 Stu Grossman (grossman at cygnus.com)
+
+ * lynx-nat.c (fetch_core_registers): Load the I & L regs for the
+ Sparc from the stack.
+
+Sat Jan 22 08:30:42 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * remote-mips.c (mips_initialize): Clear mips_initializing via
+ cleanup chain, not directly.
+
+ * ser-unix.c (wait_for) [HAVE_TERMIO, HAVE_TERMIOS]: Make a timeout
+ of -1 mean forever, like in the HAVE_SGTTY case. Warn if we are
+ munging the timeout due to the limited range of c_cc[VTIME].
+
+ * fork-child.c, inferior.h (fork_inferior): New argument shell_file.
+ * procfs.c (procfs_create_inferior), inftarg.c (child_create_inferior),
+ m3-nat.c (m3_create_inferior): Pass it.
+ * procfs.c: Remove ptrace function. It was declared in a way which
+ conflicted with the prototype in unistd.h on Solaris.
+
+Sat Jan 22 01:37:40 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * sparc-tdep.c (frame_saved_pc): Get the pc from the saved pc
+ in the sigcontext if it is a signal trampoline frame.
+ * config/sparc/tm-sun4sol2.h (IN_SIGTRAMP, SIGCONTEXT_PC_OFFSET):
+ Define for Solaris2.
+
+Sat Jan 22 00:34:47 1994 Stu Grossman (grossman at cygnus.com)
+
+ * sparc-tdep.c, lynx-nat.c, config/sparc/tm-sparc.h,
+ config/sparc/tm-sparclynx.h: Move defs of FRAME_SAVED_I0/L0 to
+ tm-sparc.h so they can be overridden if necessary.
+
+Fri Jan 21 17:49:28 1994 Stu Grossman (grossman at cygnus.com)
+
+ * lynx-nat.c: Add Sparc support.
+ * sparcly-nat.c: Remove. It's useless.
+ * config/sparc/nm-sparclynx.h: Rewrite.
+ * config/sparc/sparclynx.mh (NATDEPFILES): Replace sparcly-nat.o
+ with lynx-nat.o
+ * config/sparc/tm-sparclynx.h: Rewrite.
+
+Fri Jan 21 19:08:48 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * rs6000-pinsn.c: Use the new disassembler in the opcodes
+ directory. Old code was discarded, since the new opcode table has
+ a different format.
+
+Fri Jan 21 14:28:30 1994 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (realclean): Remove info files per make-stds.texi.
+
+Fri Jan 21 12:47:53 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dbxread.c (end_psymtab): Only patch psymtab textlow and texthigh
+ if N_SO_ADDRESS_MAYBE_MISSING is defined.
+ * config/sparc/tm-sun4sol2.h: Define it.
+
+Thu Jan 20 15:04:24 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * printcmd.c (print_address_symbolic): Unconditionally use msymbol
+ if we did not find a symbol.
+
+Fri Jan 21 08:20:18 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * infptrace.c (child_xfer_memory): Only use if CHILD_XFER_MEMORY
+ is not defined.
+
+ * hppab-nat.c (call_ptrace): Delete redundant function.
+ (kill_inferior, attach, detach, child_resume): Likewise.
+ (child_xfer_memory): Likewise.
+
+ * hppah-nat.c (call_ptrace): Delete redundant function.
+ (kill_inferior, attach, detach, child_resume): Likewise.
+
+ * config/pa/hppabsd.mh (NATDEPFILES): Add infptrace.o.
+
+ * config/pa/hppahpux.mh (NATDEPFILES): Add infptrace.o.
+
+ * config/pa/nm-hppab.h (FETCH_INFERIOR_REGISTERS): Define.
+
+ * config/pa/nm-hppah.h (FETCH_INFERIOR_REGISTERS): define.
+ (CHILD_XFER_MEMORY): Define.
+ (PT_*): Define so that generic infptrace.c code can be used.
+
+Fri Jan 21 09:23:33 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * xcoffread.c (xcoff_symfile_read): Make second parameter a
+ struct section_offsets *, not a (nonexistent) struct section_offset *.
+
+ * xcoffread.c (read_xcoff_symtab): Make main_aux just a union
+ internal_xcoff_symtab, not an array of one of them. Change lots of
+ "main_aux" to "&main_aux" and so on.
+
+ * coffread.c, xcoffread.c: Include <coff/internal.h>
+ before "symfile.h".
+
+Thu Jan 20 17:30:55 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * coffread.c (coff_getfilename): Make it not static.
+
+ * xcoffread.c (read_xcoff_symtab): complain() not abort().
+
+ * xcoffread.c (struct coff_symbol): Rename c_nsyms to c_naux (removes
+ a completely gratuitous difference between xcoffread.c and coffread.c).
+
+Wed Jan 19 15:09:44 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infrun.c (wait_for_inferior): Don't set frame for
+ step_resume_breakpoint for IN_SIGTRAMP cases.
+
+ * infrun.c (wait_for_inferior), breakpoint.h (struct bpstat_what),
+ breakpoint.c (bpstat_what): Move step_resume from its own field of
+ the struct bpstat_what into the main_action. Make it override
+ other breakpoints. This is a conservative change in the sense
+ that before the step resume breakpoint was a breakpoint.c
+ breakpoint, hitting the step resume breakpoint overrode even
+ calling bpstat_stop_status.
+
+Wed Jan 19 12:40:25 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * infrun.c (normal_stop): Set stop_pc after popping the dummy frame
+ in case execution was stopped in the called function.
+ * stack.c (print_frame_info, frame_info): If backtracing through
+ a call dummy, handle the starting source line number on a line
+ boundary like backtracing through sigtramp.
+ * sparc-tdep.c (sparc_frame_find_saved_regs): Get frame address
+ for call dummy frame right. Remove old test for dummy frame,
+ it has been unused at least since gdb-3.5.
+ * sparc-tdep.c (sparc_push_dummy_frame): Set return address register
+ of the dummy frame.
+
+Tue Jan 18 16:16:35 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infcmd.c (signal_command): Accept 0 as legitimate signal number.
+
+Tue Jan 18 14:09:25 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * infrun.c (signals_info), target.c (target_signal_from_name):
+ Use ugly casts to avoid enumvar < enumvar or enumvar++.
+
+Mon Jan 17 22:00:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * ser-unix.c (hardwire_noflush_set_tty_state): Don't muck with ICANON.
+ * inflow.c (terminal_ours_1): When discussing how to deal with the
+ tty state, make note of query() as well as readline.
+
+ * infrun.c (_initialize_infrun): Add TARGET_SIGNAL_POLL to list of
+ signals for which stop and print are cleared by default.
+
+Mon Jan 17 20:00:51 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/pa/tm-hppa.h (unwind_table_entry): Use one of the
+ reserved fields to hold a stub unwind entry type. Fix typo.
+ (stub_unwind_entry): New structure for raw stub unwind entries.
+ (stub_unwind_types): The types of stubs we may encounter.
+ (UNWIND_ENTRY_SIZE, STUB_UNWIND_ENTRY_SIZE): New defines.
+ * hppa-tdep.c (rp_saved): Use additional information provided
+ by linker stub unwind descriptors.
+ (frameless_function_invocation): Likewise.
+ (frame_chain_valid): Likewise.
+ * paread.c (compare_unwind_entries): New function for sorting
+ unwind table entries.
+ (read_unwind_info): Rewrite to remove dependency on host endianness.
+ Read in data from the $UNWIND_END$ subspace which contains linker
+ stub unwind descriptors. Merge that data into the basic unwind
+ table.
+
+ * hppab-nat.c (_initialize_kernel_u_addr): Delete unwanted functions.
+
+Mon Jan 17 22:00:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * xcoffread.c (read_xcoff_symtab, case C_FILE): Accept the name
+ from either the symbol name or the auxent.
+ * coffread.c, symfile.h (coff_getfilename): Renamed from getfilename,
+ no longer static.
+
+Mon Jan 17 13:35:01 1994 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (ALLPARAM): Change irix5.h to nm-irix5.h.
+
+Mon Jan 17 12:35:42 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * README: Update notes for alpha port.
+
+Mon Jan 17 11:15:57 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * i960-tdep.c (i960_fault_to_signal): Return TARGET_SIGNAL_ILL
+ for operation fault, constraint fault, and type fault.
+
+Sun Jan 16 12:46:01 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (init.c): Add comment explaining formatting conventions.
+
+ * c-exp.y (parse_number): Assign to temporary between the right
+ shifts, to work around a bug in the SCO compiler.
+
+ * Makefile.in (ALLCONFIG, ALLPARAM, ALLDEPFILES, HFILES_NO_SRCDIR):
+ Add various files which were added to GDB recently.
+
+ * xcoffread.c (process_xcoff_symbol): Only change 'V' to 'S' if not
+ within_function.
+
+ * Makefile.in: Add mostlyclean target.
+
+Sat Jan 15 10:20:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Version 4.11.4.
+
+Sat Jan 15 18:27:34 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * main.c (show_commands): Make return type of extern
+ history_get be HIST_ENTRY, rather than struct _hist_entry.
+ (The latter loses with the upcoming merged readline.)
+
+Sat Jan 15 10:20:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * minsyms.c (prim_record_minimal_symbol_and_info): Make tempstring
+ const char *, not char *.
+
+ * symtab.h (struct symbol): Make section short, not unsigned short.
+
+ * symtab.c (lookup_symbol): Add comment about QUIT here.
+
+ * utils.c (fputs_unfiltered): Call fputs, not fputs_maybe_filtered.
+
+ * c-exp.y (parse_number): Check for overflow regardless of range
+ checking. Fix overflow check to use unsigned LONGEST, not
+ unsigned int.
+
+ * c-exp.y (parse_number): Make it so that integer constants are
+ builtin_type_long_long if builtin_type_long isn't big enough or if
+ an "LL" suffix is used. Properly handle "UL" or "LU" suffixes.
+
+ * c-typeprint.c (c_type_print_varspec_suffix, case TYPE_CODE_FUNC):
+ Print our "()" first, then recurse for the target type.
+
+Fri Jan 14 21:55:39 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote-udi.c (udi_create_inferior): Quote empty execfile argument.
+
+ * gdbserver/low-lynx.c: Include <sys/wait.h> not "/usr/include/wait.h".
+
+Fri Jan 14 14:17:06 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * utils.c (request_quit): Re-establish signal handler regardless
+ of USG.
+
+ * config/mips/xm-irix4.h: Define HAVE_TERMIOS.
+
+Fri Jan 14 21:55:39 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * i960-tdep.c: Include target.h.
+
+Fri Jan 14 17:12:28 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * lynx-nat.c (sys/wait.h): Don't use absolute pathname.
+
+Fri Jan 14 11:06:10 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * lynx-nat.c (child_wait): Fix thinkos in struct target_waitstatus
+ changes (status -> ourstatus; declare status, etc.).
+ * config/nm-lynx.h: Fix child_wait prototype and include target.h.
+
+Fri Jan 14 14:17:06 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (ALLPARAM): Add config/nm-lynx.h.
+
+Fri Jan 14 11:49:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * remote-mips.c (mips_request, mips_wait): Correct prototypes.
+
+Fri Jan 14 11:37:17 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/i386/xm-linux.h: Define HAVE_TERMIOS.
+
+Fri Jan 14 01:04:36 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/alpha/tm-alpha.h (CALL_DUMMY): Improve comment.
+
+Thu Jan 13 10:32:38 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote-vx.c (vx_wait): Only call i960_fault_to_signal if I80960
+ is defined. Otherwise just report TARGET_SIGNAL_UNKNOWN.
+
+ * mips-tdep.c (mips_push_arguments): Byteswap struct_addr before
+ writing it.
+
+ Add search to target vector (#if 0'd until after 4.12):
+ * target.h (to_search, target_search): Add.
+ * gdbcore.h, core.c (generic_search): Add.
+ * remote.c (remote_search): Add.
+ * a29k-tdep.c (init_frame_info): Use target_search to find traceback
+ tag.
+
+ * printcmd.c (print_address_symbolic): If set print fast-symbolic-addr
+ is on, call find_pc_function rather than relying just on the minimal
+ symbols (probably only matters for symbol readers which don't put
+ statics in the minimal symbols, but changing this strikes me as
+ not conservative enough).
+ Initialize name_location in all cases.
+ If no symbol and no msymbol, don't print anything symbolic.
+
+ * a29k-tdep.c (push_dummy_frame): Add comment about saving lr0.
+
+Wed Jan 12 20:53:16 1994 John Gilmore (gnu@cygnus.com)
+
+ * printcmd.c (print_address_symbolic): Make it search the
+ symtabs for variables as well as functions. Add `set print
+ fast-symbolic-addr' and default it to fast (the old way).
+ Print line numbers for data items as well as functions.
+
+ * symtab.c (find_addr_symbol): Return the symtab and the symbol
+ address, if a symbol is found (take two more args pointing to
+ where to store these results).
+
+ * symtab.h (find_addr_symbol): Add prototype.
+
+Wed Jan 12 19:32:11 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * objfiles.h: Fix comments to reflect the fact that the phrase
+ "top of stack" always refers to where the pushing and popping takes
+ place, regardless of whether it is at the highest or lowest address.
+
+Wed Jan 12 13:23:37 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mdebugread.c (parse_symbol): Do not set TYPE_TAG_NAME for
+ compiler generated tag names.
+ * mdebugread.c (parse_type): Handle cross references to qualified
+ aggregate types.
+ * valops.c (value_struct_elt): Improve error message if the
+ address of a method is requested from an object instance.
+ * valops.c (search_struct_method): Make name_matched non-static
+ to get it initialized correctly.
+ * config/i386/nm-i386sco.h (CANNOT_STORE_REGISTER): Define to
+ exclude segment register which are not writable on newer SCO versions.
+
+Wed Jan 12 14:44:45 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * go32-xdep.c: Remove unused function uerror.
+ (sigsetmask): Declare return type. Declare argument (to match the
+ way it is called). Explicitly return 0.
+
+Wed Jan 12 01:44:25 1994 John Gilmore (gnu@cygnus.com)
+
+ * symtab.h (struct symbol, general_symbol_info, minimal_symbol,
+ partial_symbol): Shrink the storage sizes of symbols, by making
+ enums into 1-byte bitfields when compiled __GNUC__, moving all the
+ enums and small ints to the end of each struct to improve
+ alignment, and switching the section number from int to unsigned
+ short.
+
+Wed Jan 12 00:16:26 1994 John Gilmore (gnu@cygnus.com)
+
+ * symtab.c (find_addr_symbol): New routine that will find the nearest
+ symbol associated with an address. It does so by exhaustive
+ search of the symtabs, so it's slow but complete.
+
+Tue Jan 11 23:57:30 1994 John Gilmore (gnu@cygnus.com)
+
+ * coffread.c (read_coff_symtab): Set PC bounds of _globals_ symtab
+ to [0,0] rather than [0, end of first source file]. This avoids
+ problems with other parts of GDB looking for linetables in the
+ _globals_ symtab. Eliminate variables num_object_files and
+ first_object_file_end.
+
+Tue Jan 11 00:53:46 1994 John Gilmore (gnu@cygnus.com)
+
+ * a29k-tdep.c (init_frame_info): Cast null arg to examine_tag.
+ (pop_frame): Restore PC2 and LR0 from dummy frames.
+ (push_dummy_frame): Save PC2 and LR0 into dummy frames.
+ (setup_arbitrary_frame): Handle 3 args and set up real frames.
+ * config/a29k/tm-a29k.h (FRAME_NUM_ARGS): Update comments.
+ (DUMMY_FRAME_RSIZE): Add 2 longwords for PC2 and LR0.
+ (SETUP_ARBITRARY_FRAME): Define.
+
+Tue Jan 11 06:59:10 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * infrun.c, config/mips/tm-irix5.h: Remove #if 0'd AT_FUNCTION_START.
+
+Tue Jan 11 14:27:03 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * remote-udi.c (udi_resume): Correct prototype.
+
+Tue Jan 11 11:10:30 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/pa/tm-hppa.h (FRAME_FIND_SAVED_REGS): Call
+ hppa_frame_find_saved_regs.
+ * hppa-tdep.c (dig_fp_from_stack): Delete function.
+ (prologue_inst_adjust_sp): New function.
+ (is_branch, inst_saves_gr, inst_saves_fr): New functions.
+ (skip_prologue): Completely rewrite to use unwind information.
+ (hppa_frame_find_saved_regs): Likewise.
+
+Tue Jan 11 06:59:10 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * remote-mips.c (mips_wait): Use new function mips_signal_from_protocol
+ to convert a signal number with appropriate bounds checking.
+
+ * remote-mips.c (mips_wait): Fix typos (0x177 -> 0177, 0x377 -> 0377).
+
+Tue Jan 11 00:53:46 1994 John Gilmore (gnu@cygnus.com)
+
+ * stack.c (frame_info): If FRAME_FIND_SAVED_REGS isn't defined,
+ print a newline to end the display anyway.
+
+ * sparc-tdep.c (sparc_pop_frame): Pop the fsr and csr (float and
+ coprocessor status regs) when popping a frame. This fixes
+ float exceptions that occur after calling inferior functions.
+
+ * sparc-nat.c (fetch_inferior_registers, store_inferior_registers):
+ Read and write the fsr (float status register) to/from the child
+ process along with the float regs. Remove Peter Schauer's change
+ of May 24 '93, which has higher overhead and doesn't solve the
+ real problem (which was that FSR wasn't being set).
+
+Mon Jan 10 23:16:42 1994 John Gilmore (gnu@cygnus.com)
+
+ * a29k-tdep.c (examine_prologue): Don't worry if the ASGEQ
+ stack overflow check isn't right after the register stack
+ adjustment instruction. Metaware R2.3u compiler moves other
+ things in front of it. This fix isn't perfect but is what's
+ running.
+
+Mon Jan 10 20:08:23 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * c-valprint.c (c_val_print): Treat TYPE_CODE_RANGE like TYPE_CODE_INT.
+
+ * config/alpha/alpha-netware.mt: Rename to alpha-nw.mt for 14
+ character filenames.
+ * configure.in: Change accordingly.
+
+Mon Jan 10 15:48:36 1994 Tom Lord (lord@rtl.cygnus.com)
+
+ * m68k-stub.c, sparc-stub.c: removed spurious introduction of
+ _filtered io routines from these two files.
+
+Fri Jan 7 12:42:45 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/i386/tm-i386v.h, config/m68k/tm-m68k.h, config/mips/tm-mips.h,
+ config/vax/tm-vax.h (CALL_DUMMY_BREAKPOINT_OFFSET): Define.
+ * mdebugread.c (parse_symbol): Handle enum sh.type produced by
+ DEC c89.
+ * mdebugread.c (add_line): Handle zero linenos produced by DEC c89.
+
+Fri Jan 7 12:55:25 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * utils.c (print_sys_errmsg): Call gdb_flush (gdb_stdout) before
+ printing to gdb_stderr.
+
+ * remote-udi.c (udi_kill): Don't close the connection, just set
+ inferior_pid to zero.
+ (udi_mourn): Call remove_breakpoints.
+
+ * remote-udi.c: Remove obsolete need_artificial_traps comment.
+
+ * i386b-nat.c (sregmap): If sEAX, etc., not defined, use tEAX, etc.
+
+Thu Jan 6 07:17:53 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * symtab.c (lookup_symbol): Don't try adding .c to the name.
+
+ * remote-bug.c: At the start of each section, reset srec_frame
+ back to 160.
+
+ * target.h: Add TARGET_WAITKIND_LOADED and TARGET_WAITKIND_SPURIOUS.
+ * target.c (store_waitstatus): Add CHILD_SPECIAL_WAITSTATUS hook.
+ * infrun.c (wait_for_inferior): Replace SIGTRAP_STOP_AFTER_LOAD with
+ code which looks for those two waitkinds. Use switch statement.
+ * config/rs6000/tm-rs6000.h: Replace SIGTRAP_STOP_AFTER_LOAD with
+ CHILD_SPECIAL_WAITSTATUS.
+
+ * procfs.c (procfs_wait): Fix argument name to match 4 Jan changes.
+ * Move target_signal_from_host, target_signal_to_host, and
+ store_waitstatus from inftarg.c to target.c. procfs needs them.
+ * target.c: Include "wait.h" and <signal.h>.
+ * target.h, infrun.c (proceed), proceed callers: Pass new code
+ TARGET_SIGNAL_DEFAULT instead of -1. This avoids problems with
+ enums being treated as unsigned and is cleaner.
+ * infrun.c (signals_info): Don't print TARGET_SIGNAL_DEFAULT or
+ TARGET_SIGNAL_0.
+ * infcmd.c (signal_command), infrun.c (signals_info):
+ Don't allow user to specify numeric equivalent of
+ TARGET_SIGNAL_DEFAULT.
+
+Tue Jan 4 15:34:36 1994 Stu Grossman (grossman@cygnus.com)
+
+ * config/alpha/alpha-netware.mt: New target support for Alpha
+ running Netware.
+ * configure.in: Add alpha-*-netware* target.
+
+Tue Jan 4 14:51:35 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * remote-mips.c (mips_wait): Fix ref to TARGET_WAITKIND_STOPPED.
+
+Tue Jan 4 09:47:14 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * target.h: Add enum target_waitkind, enum target_signal, and
+ struct target_waitstatus. Change status argument to target_wait to
+ be struct target_waitstatus * instead of int *.
+ * target.h, infrun.c, all targets: Change type of signal arguments
+ to resume(), proceed(), and target_resume() from int to enum
+ target_signal.
+ * All targets (*_wait, *_resume): Change accordingly.
+ * infcmd.c (program_info, signal_command), throughout infrun.c,
+ * fork-child.c, solib.c, hppa-tdep.c, osfsolib.c: Use this stuff.
+ * convex-xdep.c, convex-tdep.c: Add FIXME's (getting the Convex
+ signal code stuff right with the new signals would be non-trivial).
+ * inferior.h (stop_signal): Make it enum target_signal not int.
+ * target.c, target.h (target_signal_to_string, target_signal_to_name,
+ target_signal_from_name): New functions.
+ * inftarg.c, target.h (target_signal_to_host, target_signal_from_host,
+ store_waitstatus): New functions.
+ * procfs.c (procfs_notice_signals): Use them.
+ * i960-tdep.c (i960_fault_to_signal): New function, to replace
+ print_fault.
+ * config/i960/tm-i960.h: Don't define PRINT_RANDOM_SIGNAL.
+
+ * objfiles.c (build_objfile_section_table): Don't abort() if
+ objfile->sections is already set.
+
+ * objfiles.c (add_to_objfile_sections): Check SEC_ALLOC not SEC_LOAD
+ to match recent change to exec.c.
+
+ * Version 4.11.3.
+
+ * main.c (print_gdb_version): Change year to 1994.
+
+ * ChangeLog, ChangeLog-93: Split ChangeLog at 1994.
+ * Makefile.in (NONSRC): Add ChangeLog-93.
+
+Mon Jan 3 11:57:29 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabsread.c (read_type): Allow defining several type numbers
+ at once (e.g. "(1,2)=(3,4)="...).
+
+ * stabsread.c (read_enum_type): Use TARGET_INT_BIT not sizeof (int).
+
+ * breakpoint.c (frame_in_dummy): Check PC as well as frame.
+
+Mon Jan 3 02:47:03 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mdebugread.c (psymtab_to_symtab_1): Only pass N_STAB symbols
+ to process_one_symbol.
+ * symtab.c (find_pc_psymbol): Search global_psymbols as well to
+ avoid caching a bad endaddr in find_pc_partial_function.
+
+Sun Jan 2 21:41:17 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/m68k/tm-sun3.h: Don't define BELIEVE_PCC_PROMOTION.
+
+Sat Jan 1 04:35:23 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * infrun.c (wait_for_inferior): Do not step or step resume past
+ the end of a one-line function we just stepped into.
+
+For older changes see ChangeLog-1993
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/ChangeLog-1995 b/gdb/ChangeLog-1995
new file mode 100644
index 00000000000..9d4149ebf6c
--- /dev/null
+++ b/gdb/ChangeLog-1995
@@ -0,0 +1,4915 @@
+Fri Dec 29 16:30:58 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * symfile.c (find_sym_fns): Add PowerMac to xcoff file recognition
+ kludge.
+
+Fri Dec 22 11:05:59 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (gdb_host): Add support for DG/UX running on x86 as
+ a host.
+ (all x86 targets and hosts): Add support for pentium-pro machines.
+
+ * configure: Rebuild.
+
+ * config/i386/i386dgux.mh: New file for DG/UX running on x86 host.
+
+Thu Dec 21 19:09:20 1995 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * remote-array.c (array_wait): Poll the keyboard along with the
+ serial port so users can tpye at the target while their
+ application is running.
+
+Thu Dec 21 11:58:52 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * Makefile.in (ppcbug-rom.o, srec.o): Add dependencies.
+
+ * monitor.c (monitor_debug): Take prefix, and suffix arguments.
+ Print trailing newline after the suffix.
+ (monitor_printf{,_noecho}): Change monitor_debug calls.
+ (monitor_printf): Call monitor_expect instead of trying to do the
+ expect processing locally so that if there is extra junk, it
+ doesn't hang things up.
+ (readchar): If MO_HANDLE_NL is set, handle \r\n pairs and convert
+ them to a single \r. Use monitor_debug to print out byte read.
+
+ * monitor.h (MO_HANDLE_NL): Add new flag.
+
+ * ppcbug-rom.c (ppcbug_ops{1,2}): Split into two ops, one that
+ uses lo 0 to load, and the other that uses lo 1. Set flag
+ MO_HANDLE_NL.
+ (ppcbug_open{0,1}): Clone and split to handle ppcbug_ops{1,2}.
+ (_initialize_ppcbug_rom): Set up both ppcbug_open{0,1}.
+
+Wed Dec 20 10:54:41 1995 Fred Fish <fnf@cygnus.com>
+
+ * defs.h: Delete extraneous whitespace at end of file.
+ * symfile.h: Move #include of demangle.h outside conditional.
+ * objfiles.h (struct objstats, OBJSTAT, OBJSTATS): New struct and
+ macros to hold per-objfile statistics for internal
+ instrumentation.
+ (struct objfile): Add OBJSTATS member, which is optional.
+ * buildsym.h (next_symbol_text_func): Now takes objfile argument.
+ Also update copyright to 1995.
+ * dbxread.c (dbx_next_symbol_text): Now takes objfile argument.
+ (dbx_symfile_init, coffstab_build_psymtabs, elfstab_build_psymtabs,
+ stabsect_build_psymtabs): Accumulate string table size.
+ (dbx_next_symbol_text, read_dbx_symtab, read_ofile_symtab):
+ Accumulate number of stabs symbols read.
+ * dwarfread.c (new_symbol, symthesize_typedef):
+ Accumulate number of full symbols created.
+ * gdbtypes.c (alloc_type): Accumulate number of types.
+ * maint.c (maintenance_print_statistics): New function.
+ * mdebugread.c (mdebug_next_symbol_text): Now takes objfile
+ argument.
+ * minsyms.c (prim_record_minimal_symbol_and_info): Accumulate
+ number of minimal symbols read.
+ * os9kread.c (read_os9k_psymtab): next_symbol_text takes objfile
+ arg.
+ * partial-stab.h: next_symbol_text takes objfile arg.
+ * stabsread.c (error_type, STABS_CONTINUE): Now takes objfile arg
+ and uses it to call next_symbol_text.
+ * symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list):
+ Accumulate number of partial symbols created.
+ * symfile.h (ADD_PSYMBOL_VT_TO_LIST): Accumulate number of partial
+ symbols created.
+ * symmisc.c (print_objfile_statistics): Print the per-objfile
+ internal instrumentation statistics gathered.
+ * xcoffread.c (xcoff_next_symbol_text): Now takes objfile argument.
+
+Fri Dec 15 16:15:55 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * top.c (set_endian_from_file): Use new bfd_big_endian macro.
+
+Fri Dec 15 12:21:10 1995 Raymond Jou <rjou@mexican.cygnus.com>
+
+ * mpw-make.sed: Add quotes to RIncludes reference.
+
+Fri Dec 15 13:18:55 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * remote-array.c: Remove bogus setting of baudrate to 4800. Their
+ hardware has real UARTS now.
+
+Mon Dec 11 18:19:16 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.in (powerpc-*-macos*): New target configuration.
+ * configure: Update.
+ * config/powerpc/macos.mh, config/powerpc/macos.mt,
+ config/powerpc/nm-macos.h, config/powerpc/tm-macos.h, mac-nat.c:
+ New files, native PowerMac debugging support.
+ * Makefile.in (mac-nat.o): Add build rule.
+ * mpw-config.in (enable_cflags): Add support.
+ (m68k-apple-macos, powerpc-apple-macos): Fix natdepfiles to
+ list object file instead of source file.
+ * mpw-make.sed (@ENABLE_CFLAGS@): Don't edit out, replace with
+ value of variable.
+ (install, install-only): Edit MPW-specific installation into
+ place of Unix shell code.
+ * mac-gdb.r: Fix version resources to use symbolic version strings.
+ (cfrg): New resource, code fragment for PowerMac.
+
+Mon Dec 11 14:13:03 1995 Fred Fish <fnf@amigalib.com>
+
+ * dbxread.c (process_one_symbol): When looking at the next
+ minimal symbol, check for end of the minimal symbol array
+ (symbol with NULL pointer for name) before dereferencing it.
+
+Mon Dec 11 15:56:55 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * eval.c (evaluate_struct_tuple): Fix thinko.
+
+Mon Dec 11 06:52:02 1995 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * ch-typeprint.c (chill_type_print_base): Slightly change of printing
+ of variant structures.
+
+Mon Dec 11 00:36:01 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * valops.c (value_cast): Handle casts to and from TYPE_CODE_CHAR.
+ * ch-exp.c (match_integer_literal): Fix long long support.
+ * gdbtypes.c (get_discrete_bounds): Make TYPE_LENGTH (type) ==
+ sizeof (LONGEST) case work OK.
+
+Fri Dec 8 21:02:24 1995 Fred Fish <fnf@cygnus.com>
+
+ * coffread.c, dbxread.c, dstread.c, objfiles.c, os9kread.c,
+ symfile.c, symtab.c: Use "obstack.h" rather than <obstack.h>.
+
+Wed Dec 6 16:16:18 1995 Stu Grossman (grossman@cirdan.cygnus.com)
+
+ * remote-mips.c (mips_receive_header): Allow mips_syn_garbage to be
+ user-settable (via set syn-garbage-limit). Setting it to -1 makes
+ it unlimited.
+
+Tue Dec 5 18:33:43 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * gdbtypes.c (check_stub_method): Make sure we get back a function
+ string in the demangled name before we try to use it.
+
+Tue Dec 5 18:08:29 1995 Stu Grossman (grossman@cygnus.com)
+
+ * monitor.c (monitor_expect_regexp): Make static, add prototype.
+ * (monitor_read_memory_single): Call monitor_expect_regexp with
+ pointer to getmem_resp_delim_pattern, not entire struct.
+
+Tue Dec 5 15:51:25 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * c-lang.h (c_op_print_tab): Don't declare, some compilers
+ consider illegal if structure not defined, and only used
+ in c-lang.c anyway.
+
+Sun Dec 3 12:31:03 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * eval.c (evaluate_subexp_standard case): Fix typo.
+
+Sun Dec 3 11:59:21 1995 Jeffrey A. Law <law@cygnus.com>
+
+ * ch-exp.c (parse_named_record_element): Avoid aggregrate
+ initializations for automatic variables.
+
+ * hppa-tdep.c (hppa_alignof): Fix typo in last change.
+
+Sat Dec 2 19:32:57 1995 Fred Fish <fnf@cygnus.com>
+
+ * symfile.c (global_psymbols, static_psymbols): Remove, unused.
+
+Sat Dec 2 03:02:21 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * alpha-tdep.c (heuristic_proc_desc): Add heuristic to
+ determine the return address register, needed for OSF/1-3.2C.
+ * config/alpha/tm-alpha.h (T7_REGNUM, T9_REGNUM): Define.
+
+Fri Dec 1 07:23:57 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppcbug-rom.c (ppcbug_cmds): Turn on MO_GETMEM_READ_SINGLE
+ because PPCbug displays the memory as characters as well as hex.
+ Fix getmem/setmem commands.
+
+ * srec.c (load_srec): Fix off by one typo in last submission.
+
+ * rs6000-tdep.c (push_arguments): Fix typo.
+
+Thu Nov 30 23:54:17 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * language.c (lang_bool_type), language.h: New function.
+ * language.h (LA_BOOL_TYPE): New macro.
+ * eval.c (evaluate_subexp_standard) Use LA_BOOL_TYPE instead
+ of builtin_type_int where appropriate,
+ * valarith.c (value_subscript): Likewise.
+
+ * valops.c (value_slice): Implement (value) bitstring slices.
+ * valprint.c (val_print): If TYPE_LENGTH is zero, don't automatically
+ print "<incomplete type>" - Chill has zero-length (string) types.
+
+ * gdbtypes.c (check_stub_type): Removed; no longes needed.
+ * ch-exp.c (expect, parse_call): Tweak error messages.
+
+Wed Nov 29 13:35:18 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * scm-valprint.c (scm_isymnames): Remove "#@" prefix.
+ (scm_scmval_print): Do not print "#@" prefix.
+
+ * gdbtypes.h (enum type_code): Added TYPE_CODE_TYPEDEF.
+ (check_typedef): New prototype.
+ (CHECK_TYPEDEF): New macro.
+ (TYPE_DUMMY_RANGE): Removed.
+ * gdbtypes.c (get_discrete_bounds): Fix paren error; make more robust.
+ (create_array_type): Don't force_to_range_type; users of the
+ array are responsible for handling non-range index types.
+ (create_set_type): Likewise.
+ (force_to_range_type): Removed.
+ (check_typedef): New function handles stub types and typedefs.
+ (check_stub_type): Just call check_typedef. (To be removed.)
+ (recursive_dump_type): Handle TYPE_CODE_TYPEDEF.
+ * ch-lang.c (type_lower_upper): Use get_discrete_bounds.
+ (evaluate_subexp_chill): Handle string repetition.
+ Re-arrange to handle EVAL_AVOID_SIDE_EFFECTS better.
+ * ch-typeprint.c (chill_type_print_base): Handle TYPE_CODE_TYPEDEF.
+ Pass show=0 in recursive calls various places.
+ (case TYPE_CODE_ARRAY): Don't require index type to have
+ TYPE_CODE_RANGE.
+ (case TYPE_CODE_RANGE): Don't need to support TYPE_DUMMY_RANGE.
+ * gdbtypes.c, ch-lang.c, ch-typeprint.c (numerous places):
+ Add check_typedef/CHECK_TYPEDEF as needed.
+
+ * ch-exp.y: Replaced by ...
+ * ch-exp.c: New file. Use recursive-descent.
+ Recognize labelled array tuples and powerset ranges.
+ * Makefile.in: Update for no longer using yacc for ch-exp.
+
+ * c-lang.c: Make various functions non-static.
+ * c-lang.h: Add bunches of prototypes.
+ * cp-valprint.c (cp_print_value_fields): Also take address.
+ (cp_print_value): Likewise. Use baselcass_offset.
+ * stabsread.c (current_symbol): New static variable.
+ (type_synonym_name): Remove.
+ (read_type): If copying, make copy be a TYPE_CODE_TYPEDEF.
+ (read_array_type): Don't need to handle undefined element type here.
+ (cleanup_undefined_types): Ditto.
+ (read_range_type): Look for Chill ranges.
+ * valops.c (value_assign): Fix case lval_internalvar - don't try
+ to assign into old value (which might be too small!).
+ (value_coerce_array): No longer need special VALUE_REPEATED handling.
+ (value_arg_coerce): Cleaner array->pointer decay mechanism.
+ (search_struct_field): Use baseclass_offset rather than
+ baseclass_addr.
+ (value_slice): Use get_discrete_bounds.
+ * value.h (COERCE_VARYING_ARRAY): Take type argumnt as well.
+ * values.c (baseclass_offset): Change parameter interface.
+ (baseclass_addr): Removed.
+ * c-typeprint.c, c-valprint.c, ch-valprint.c, values.c, valops.c:
+ Add check_typedef/CHECK_TYPEDEF as needed.
+
+ * alpha-tdep.c, c-exp.y, h8500-tdep.c, f-exp.y, f-valprint.c,
+ findvar.c, hppa-tdep.c, infcmd.c, language.c, printcmd.c,
+ rs6000-tdep.c, symmisc.c, symtab.c, mdebugread.c:
+ Add check_typedef/CHECK_TYPEDEF as needed.
+
+ * f-typeprint.c, valarith.c, valprint.c, typeprint.c, eval.c:
+ Add check_typedef/CHECK_TYPEDEF as needed.
+ * f-typeprint.c: Various cleaning up.
+ * valarith.c (value_subscript): Also subscript bitstrings (for Chill).
+ * typeprint.c (print_type_scalar): Also support TYPE_CODE_RANGE.
+ * eval.c (evaluate_subexp_standard case OP_ARRAY): Implement
+ support for labelled array tuples and ranges in powerset tuples.
+ (init_array_element): New function.
+
+ * top.c (command_line_input): Only strip out an initial #-comment.
+ Looking for internal comments is language-specific (breaks Scheme).
+
+ * expression.h (enum exp_opcode): Add BINOP_RANGE.
+ * expprint.c (dump_expression): Support BINOP_RANGE.
+ * eval.c (evaluate_subexp_standard): Handle BINOP_RANGE (as error).
+ (case MULTI_SUBSCRIPT): Fix broken f77 value->int ad hoc conversion.
+ * ch-lang.c (chill_op_print_tab): Support BINOP_RANGE.
+ (evaluate_subexp_chill): Error on BINOP_COMMA.
+
+ * Makefile.in: Clean up so doc stuff stays in doc sub-dir.
+
+Wed Nov 29 16:39:50 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * monitor.c (monitor_debug): New function to print monitor debug
+ output in printable fashion.
+ (monitor_printf{,_noecho}): Call monitor_debug instead of
+ fputs_unfiltered.
+
+ * srec.c (load_srec): When printing srec debug information, do not
+ print the carriage return directly, instead print \\r followed by
+ a newline.
+
+Tue Nov 28 15:25:28 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (target_subdir): Define.
+ (CC_FOR_TARGET, CXX_FOR_TARGET): Use it to find target libraries.
+ * configure.in (X_CFLAGS): Fix typo.
+ (target_subdir): Set to "${target_alias}/" if cross.
+ * configure: Regenerated.
+
+ * dbxread.c (dbx_symfile_read): Set block_address_function_relative
+ for `pe' format files.
+
+Tue Nov 28 11:17:47 1995 Fred Fish <fnf@cygnus.com>
+
+ * magic.h: Renamed to gmagic.h to avoid <magic.h> conflict.
+ * magic.c: Renamed to gmagic.c in sympathy.
+ * eval.c, gmagic.c, config/tm-magic.h:
+ Include "gmagic.h" rather than "magic.h".
+
+Sat Nov 25 02:56:38 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mdebugread.c (handle_psymbol_enumerators, parse_symbol):
+ Recognize enums from alpha cc -migrate.
+ (upgrade_type): Pass correct fd to parse_symbol when parsing
+ the index type of an array.
+ (parse_procedure, parse_lines, psymtab_to_symtab_1): Handle
+ unsorted procedure descriptors from Irix 5.x and Alpha OSF/1-3.x
+ shared libraries. Use CORE_ADDR instead of `unsigned long' in
+ procedure descriptor address computations.
+
+ * symtab.c (decode_line_1): Prevent accidental strchr match
+ of a null character with the terminating null character of
+ gdb_completer_quote_characters.
+ (cplusplus_hint): Make sure that only a single quote is printed
+ in the hint message.
+
+Fri Nov 24 16:17:01 1995 Jeffrey A Law (law@cygnus.com)
+
+ * top.c (recurse_read_control_structure): Don't make cleanups
+ here. Callers handle that correctly.
+
+Tue Nov 21 15:16:34 1995 Fred Fish <fnf@rtl.cygnus.com>
+
+ * config/m68k/xm-hp300hpux.h: Define MMAP_BASE_ADDRESS and MMAP_INCREMENT.
+ Also force HAVE_MMAP to be defined since autoconf is currently broken
+ for detecting a working mmap under hpux.
+ * config/pa/xm-hppah.h (MMAP_BASE_ADDRESS): Tweak MMAP_BASE_ADDRESS
+ to a better value suggested by Jeffrey A Law (law@cygnus.com).
+
+Tue Nov 21 08:48:58 1995 Fred Fish <fnf@cygnus.com>
+
+ * config/pa/xm-hppah.h: Define MMAP_BASE_ADDRESS and MMAP_INCREMENT.
+ Also force HAVE_MMAP to be defined since autoconf is currently broken
+ for detecting a working mmap under hpux.
+ * objfiles.c (map_to_address): Have gdb print a warning when it
+ is compiled with HAVE_MMAP but without both MMAP_BASE_ADDRESS and
+ MMAP_INCREMENT defined (thus making it appear mmap doesn't work).
+
+Mon Nov 20 14:13:53 1995 Stu Grossman (grossman@cygnus.com)
+
+ * infrun.c (wait_for_inferior): Add support for dynamic function
+ trampolines. These are pieces of code between the caller and the
+ callee that figure out the address of the callee's code at run
+ time. Upon entry, we can't figure out the callee's address, so we
+ set a breakpoint within the trampoline where the address will be
+ known, and continue the target. Once we hit the breakpoint, we
+ break at the callee's address and proceed as usual.
+
+Mon Nov 20 11:12:34 1995 Fred Fish <fnf@cygnus.com>
+
+ * objfiles.c (allocate_objfile): Change warning message about mapped
+ symbol tables so that it is obvious that they are not supported on
+ this particular machine rather than implying they are not supported
+ at all in this version of gdb.
+
+Sun Nov 19 05:20:53 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * irix5-nat.c, osfsolib.c (solib_address): Return the name of the
+ containing solib.
+ * stack.c (print_frame_info): Use minimal symbol only if
+ fi->pc is in a known section.
+
+Sat Nov 18 11:19:35 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
+
+ * solib.c (solib_address): Return the name of the containing solib.
+ * solib.h (PC_SOLIB): New macro; define using solib_address.
+ * stack.c (print_frame_info) [PC_SOLIB]: If no function name, try
+ PC_SOLIB on the PC value.
+
+Sat Nov 18 04:09:31 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * annotate.c (annotate_source, annotate_frame_begin): Issue
+ `0x' prefix for the pc value, to remain consistent with previous
+ GDB versions.
+
+ * blockframe.c (find_pc_partial_function), config/pa/tm-hppa.h:
+ Remove Sun shared library transfer hack and
+ INHIBIT_SUNSOLIB_TRANSFER_TABLE_HACK, it is obsoleted by the
+ mst_solib_trampoline minimal symbols.
+
+ * blockframe.c (inside_main_func): Check main_func_*pc against
+ INVALID_ENTRY_*PC, not zero.
+ * symfile.c (init_entry_point_info): Initialize ei.*pc with
+ INVALID_ENTRY_*PC.
+ * mipsread.c (mipscoff_symfile_read): If the entry_file bounds
+ are still unknown after processing the partial symbols, then try
+ to set them from the minimal symbols.
+
+ * infcmd.c (registers_info): Error out if selected_frame is NULL.
+ * stack.c (return_command): Select new current frame silently if
+ not interactive.
+
+ * mipsread.c (read_alphacoff_dynamic_symtab): Ignore additional
+ DT_MIPS_LOCAL_GOTNO and DT_MIPS_GOTSYM entries.
+
+ * irix5-nat.c (solib_create_inferior_hook): Call solib_add only
+ if auto_solib_add_at_startup is nonzero.
+ (_initialize_solib): Add "set auto-solib-add" command.
+ * osfsolib.c (solib_create_inferior_hook): Call solib_add only
+ if auto_solib_add_at_startup is nonzero.
+ (_initialize_solib): Add "set auto-solib-add" command.
+
+Wed Nov 15 17:12:04 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * utils.c: Don't include sys/ioctl.h etc if MPW is host.
+
+Tue Nov 14 17:16:46 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/arm/tm-arm.h (ADDITIONAL_REGISTER_NAMES): Fix r5.
+ (FRAME_SAVED_PC): Minor clean up.
+
+Tue Nov 14 14:51:05 1995 Stu Grossman (grossman@cygnus.com)
+
+ * monitor.c (monitor_load_srec monitor_make_srec): Move all
+ S-record download code into srec.c.
+ * srec.c srec.h: New files. Contain S-record loading routines
+ formerly in monitor.c.
+ * serial.c serial.h: New routine just like fprintf, but uses
+ serial_t instead of FILE *.
+ * sh-tdep.c (frame_find_saved_regs init_extra_frame_info):
+ Don't add four to saved pc (makes things match manual). Also, fix
+ bug where we didn't get pc from stack frame correctly.
+ * config/sh/tm-sh.h (SAVED_PC_AFTER_CALL): Don't add four to
+ saved pc. Real hardware does this for you.
+ * sh3-rom.c (sh3_load): New routine. Sets up for download then
+ calls generic S-record loader.
+ * config/h8300/h8300.mt, config/h8500/h8500.mt,
+ config/m68k/monitor.mt, config/pa/hppapro.mt, config/sh/sh.mt:
+ Add srec.o to TDEPFILES.
+
+Tue Nov 14 15:57:36 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppcbug-rom.c: New file to support the Motorola PPCBUG monitor
+ for PowerPC's.
+
+ * config/powerpc/ppc{,le}-{eabi,sim}.mt (TDEPFILES): Include
+ ppcbug-rom.o, monitor.o, and srec.o
+
+ * config/i386/linux.mt (XDEPFILES): Include ser-tcp.o.
+
+Mon Nov 13 13:12:46 1995 Jeffrey A Law (law@cygnus.com)
+
+ * partial-stab.h: Remove GDB_TARGET_IS_HPPA kludge.
+
+Fri Nov 10 13:08:54 1995 Jeff Law (law@kahlua.cs.utah.edu)
+
+ * terminal.h (HAVE_SGTTY): Fix typo.
+
+Thu Nov 9 17:34:01 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (gdb_target): Build in the simulator for all
+ PowerPC eabi targets, not just eabisim, providing
+ --enable-sim-powerpc is used, or the host compiler is GCC.
+
+Thu Nov 9 14:04:05 1995 Raymond Jou (rjou@mexican.cygnus.com)
+
+ * mpw-config.in: Add variable with names of SIOW libraries.
+ * mpw-make.sed: Add an action to build SIOWgdb.
+
+Wed Nov 8 19:25:22 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Edit @ENABLE_CFLAGS@ out, mpw-configure can
+ add back in if necessary.
+
+Wed Nov 8 15:59:52 1995 James G. Smith <jsmith@pasanda.cygnus.co.uk>
+
+ * config/mips/vr4300.mt: Added simulator to default VR4300 build.
+
+Tue Nov 7 16:02:25 1995 Stu Grossman (grossman@cygnus.com)
+
+ * remote-mips.c (mips_initialize): Fix brain damage found by
+ Jamie. Basically had case statement in the wrong place...
+ * (mips_load): Remove unnecessary `db tty0' command. It's all
+ handled by mips_initialize now.
+
+Tue Nov 7 12:59:14 1995 Raymond Jou <rjou@mexican.cygnus.com>
+
+ * mac-gdb.r: Added #ifdef Macgdb.
+
+Tue Nov 7 14:59:51 1995 James G. Smith <jsmith@pasanda.cygnus.co.uk>
+
+ * remote-mips.c (mips_initialize): Updated to talk to VR4300 RISQ
+ monitor board.
+
+Mon Nov 6 11:44:11 1995 James G. Smith <jsmith@pasanda.cygnus.co.uk>
+
+ * config/mips/{tm-vr4300.h tm-vr4300el.h} (TARGET_MONITOR_PROMPT):
+ Change into real strings.
+
+ * remote-sim.c (gdbsim_open): Moved sim_open() call to after
+ callback initialisation.
+
+Sun Nov 5 00:07:52 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in (AC_CHECK_HEADERS): add stddef.h.
+
+Fri Nov 3 12:30:43 1995 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (COMMON_OBS): Use corefile.o rather than core.o
+ * core.c: Rename to corefile.c.
+ * config/pyr/tm-pyr.h, umax-xdep.c, sun386-nat.c, pyr-xdep.c,
+ Makefile.in (SFILES), gould-xdep.c, coredep.c, armtdep.c,
+ arm-xdep.c, altos-xdep.c: Change core.c references to corefile.c.
+
+ From Graham Stoney <greyham@research.canon.oz.au>.
+ * Makefile.in (remote-array.o): Add rule to build.
+ (ALLDEPFILES): Add remote-array.c
+ * remote-array.c (baud_rate): Remove unnecessary declaration.
+ (baudrate): Remove.
+ (array_files_info): Print global baud_rate not baudrate.
+
+Sat Nov 4 10:21:58 1995 Stu Grossman (grossman@cygnus.com)
+
+ * Makefile.in (INTERNAL_CFLAGS): Add ENABLE_CFLAGS.
+ * fork-child.c (fork_inferior): Add call to
+ TARGET_CREATE_INFERIOR_HOOK to allow target specific code to get
+ control just before the new process executes it's first instruction.
+ * remote-mips.c (mips_initialize): Cleanup a bit. Don't try to
+ receive a packet at first. This speeds up initialization a lot.
+ Use TARGET_MONITOR_PROMPT instead of "<IDT>".
+ (common_breakpoint): Use rresponse instead of rerrflg to inspect
+ error code.
+ * symfile.c (syms_from_objfile reread_symbols): Call
+ TARGET_SYMFILE_POSTREAD to allow target specific code to get
+ control after reading new symbols.
+ * target.h: New macros TARGET_SYMFILE_POSTREAD, and
+ TARGET_CREATE_INFERIOR_HOOK. See above for descriptions.
+ * config/mips/{irix5.mh nm-irix5.h}: Delete nm-irix5.h. Make
+ NAT_FILE point directly at ../nm-sysv4.h.
+ * config/mips/{mipsm3.mh nm-m3.h}: Delete nm-m3.h. Make
+ NAT_FILE point directly at ../nm-m3.h.
+ * config/mips/{mipsv4.mh nm-sysv4.h}: Delete nm-sysv4.h. Make
+ NAT_FILE point directly at ../nm-sysv4.h.
+ * config/mips/nm-mips.h: Improve comment at top of file.
+ * config/mips/tm-mips.h (TARGET_MONITOR_PROMPT): Change
+ definition into a proper string.
+
+Wed Nov 1 20:18:08 1995 Fred Fish <fnf@cygnus.com>
+
+ * config/i386/tm-i386.h: New file containing generic i*86 target
+ definitions.
+ (TARGET_BYTE_ORDER): Moved here from tm-i386v.h.
+ (IEEE_FLOAT): Moved here from tm-i386v.h.
+ (START_INFERIOR_TRAPS_EXPECTED): Define default as 2.
+ (FUNCTION_START_OFFSET): Moved here from tm-i386v.h.
+ (SKIP_PROLOGUE): Moved here from tm-i386v.h.
+ (SAVED_PC_AFTER_CALL): Moved here from tm-i386v.h.
+ (INNER_THAN): Moved here from tm-i386v.h.
+ (BREAKPOINT): Moved here from tm-i386v.h.
+ (DECR_PC_AFTER_BREAK): Moved here from tm-i386v.h.
+ (ABOUT_TO_RETURN): Moved here from tm-i386v.h.
+ (REGISTER_SIZE): Moved here from tm-i386v.h.
+ (NUM_REGS): Moved here from tm-i386v.h.
+ (REGISTER_NAMES): Moved here from tm-i386v.h.
+ (EXTRACT_STRUCT_VALUE_ADDRESS): Moved here from tm-i386v.h.
+ (FP_REGNUM): Moved here from tm-i386v.h.
+ (SP_REGNUM): Moved here from tm-i386v.h.
+ (PC_REGNUM): Moved here from tm-i386v.h.
+ (PS_REGNUM): Moved here from tm-i386v.h.
+ (FP0_REGNUM): Moved here from tm-i386aix.h.
+ (FPC_REGNUM): Moved here from tm-sun386.h.
+ (REGISTER_BYTES): Moved here from tm-i386aix.h.
+ (REGISTER_BYTE): Moved here from tm-i386aix.h.
+ (REGISTER_RAW_SIZE): Moved here from tm-i386aix.h.
+ (MAX_REGISTER_RAW_SIZE): Moved here from tm-i386aix.h.
+ (REGISTER_VIRTUAL_SIZE): Moved here from tm-i386aix.h.
+ (MAX_REGISTER_VIRTUAL_SIZE): Moved here from tm-i386aix.h.
+ (EXTRACT_RETURN_VALUE): Moved here from tm-i386aix.h.
+ (STORE_RETURN_VALUE): Moved here from tm-i386aix.h.
+ (REGISTER_VIRTUAL_TYPE): Moved here from tm-i386v.h.
+ (STORE_STRUCT_RETURN): Moved here from tm-i386v.h.
+ (FRAME_CHAIN): Moved here from tm-i386v4.h.
+ (FRAMELESS_FUNCTION_INVOCATION): Moved here from tm-i386v4.h.
+ (FRAME_SAVED_PC): Moved here from tm-i386os9k.h
+ (FRAME_ARGS_ADDRESS): Moved here from tm-i386v.h.
+ (FRAME_LOCALS_ADDRESS): Moved here from tm-i386v.h.
+ (FRAME_NUM_ARGS): Moved here from tm-i386sun.h.
+ (FRAME_ARGS_SKIP): Moved here from tm-i386v.h.
+ (FRAME_FIND_SAVED_REGS): Moved here from tm-i386v.h.
+ (PUSH_DUMMY_FRAME): Moved here from tm-i386v.h.
+ (POP_FRAME): Moved here from tm-i386v.h.
+ (CALL_DUMMY, CALL_DUMMY_LENGTH, CALL_DUMMY_START_OFFSET,
+ CALL_DUMMY_BREAKPOINT_OFFSET, FIX_CALL_DUMMY): Moved here from
+ tm-i386v.h
+ (print_387_control_word, print_387_status_word): Declare prototypes.
+ (struct frame_info, struct frame_saved_regs): Forward decls for
+ prototypes.
+ (SP_ARG0): Moved here from tm-i386v.h.
+
+ * config/i386/tm-i386v.h:
+ (i386/tm-i386.h): Include.
+ (TARGET_BYTE_ORDER): Remove.
+ (IEEE_FLOAT): Remove.
+ (START_INFERIOR_TRAPS_EXPECTED): Undef before redefine to 4.
+ (FUNCTION_START_OFFSET): Remove.
+ (SKIP_PROLOGUE): Remove.
+ (i386_skip_prologue): Remove prototype.
+ (SAVED_PC_AFTER_CALL): Remove.
+ (INNER_THAN): Remove.
+ (BREAKPOINT): Remove.
+ (DECR_PC_AFTER_BREAK): Remove.
+ (ABOUT_TO_RETURN): Remove.
+ (REGISTER_SIZE): Remove.
+ (NUM_REGS): Undef before redefine to 16 (no FP support).
+ (REGISTER_NAMES): Undef before redefine.
+ (FP_REGNUM, SP_REGNUM, PC_REGNUM, PS_REGNUM): Remove.
+ (REGISTER_BYTES): Undef before redefine.
+ (REGISTER_BYTE): Undef before redefine.
+ (REGISTER_RAW_SIZE): Undef before redefine.
+ (REGISTER_VIRTUAL_SIZE): Undef before redefine.
+ (MAX_REGISTER_RAW_SIZE): Undef before redefine.
+ (MAX_REGISTER_VIRTUAL_SIZE): Undef before redefine.
+ (REGISTER_VIRTUAL_TYPE): Undef before redefine.
+ (STORE_STRUCT_RETURN): Undef before redefine.
+ (EXTRACT_RETURN_VALUE): Undef before redefine.
+ (STORE_RETURN_VALUE): Undef before redefine.
+ (EXTRACT_STRUCT_VALUE_ADDRESS): Remove.
+ (FRAME_CHAIN): Undef before redefine.
+ (FRAMELESS_FUNCTION_INVOCATION): Undef before redefine.
+ (FRAME_SAVED_PC): Undef before redefine.
+ (FRAME_ARGS_ADDRESS): Remove.
+ (FRAME_LOCALS_ADDRESS): Remove.
+ (FRAME_NUM_ARGS): Undef before redefine.
+ (FRAME_ARGS_SKIP): Remove.
+ (FRAME_FIND_SAVED_REGS): Remove.
+ (PUSH_DUMMY_FRAME): Remove.
+ (POP_FRAME): Remove.
+ (CALL_DUMMY): Remove.
+ (CALL_DUMMY_LENGTH): Remove.
+ (CALL_DUMMY_START_OFFSET): Remove.
+ (CALL_DUMMY_BREAKPOINT_OFFSET): Remove
+ (FIX_CALL_DUMMY): Remove.
+ (print_387_control_word): Remove.
+ (print_387_status_word): Remove.
+ (SP_ARG0): Remove.
+
+ * config/i386/tm-symmetry.h:
+ (TM_SYMMETRY_H): Enclose file in test for define & define if needed.
+ (START_INFERIOR_TRAPS_EXPECTED): Move to after inclusion of
+ tm-i386v4.h or tm-i386v.h, #undef, and #define back to 2.
+ (DECR_PC_AFTER_BREAK): Move to after inclusion of tm-i386v4.h
+ or tm-i386v.h, #undef, and #define to 0.
+ (MAX_REGISTER_RAW_SIZE): Remove.
+ (FRAME_CHAIN): Remove.
+ (FRAMELESS_FUNCTION_INVOCATION): Remove.
+ (FRAME_SAVED_PC): Remove.
+ (print_387_control_word, print_387_status_word): Remove prototypes.
+
+ * config/i386/tm-ptx.h:
+ (TM_PTX_H): Enclose file in test for define & define if needed.
+ (START_INFERIOR_TRAPS_EXPECTED): Move to after inclusion of
+ tm-i386v4.h or tm-i386v.h, #undef, and #define back to 2.
+ (DECR_PC_AFTER_BREAK): Move to after inclusion of tm-i386v4.h
+ or tm-i386v.h, #undef, and #define to 0.
+ (SDB_REG_TO_REGNUM): Remove obsolete commented out define.
+ (print_387_control_word, print_387_status_word): Remove prototypes.
+
+ * config/i386/tm-linux.h:
+ (TM_LINUX_H): Enclose file in test for define & define if needed.
+ (i386/tm-i386.h): Include instead of tm-i386v.h.
+ (START_INFERIOR_TRAPS_EXPECTED): Remove.
+
+ * config/i386/tm-i386v4.h:
+ (TM_I386V4_H): Enclose file in test for define & define if needed.
+ (i386/tm-i386.h): Include instead of tm-i386v.h.
+ (START_INFERIOR_TRAPS_EXPECTED): Remove.
+ (FRAME_CHAIN): Moved to tm-i386.h.
+ (FRAMELESS_FUNCTION_INVOCATION): Moved to tm-i386.h.
+ (FRAME_SAVED_PC): Remove.
+ (sigtramp_saved_pc): Define as i386v4_sigtramp_saved_pc.
+ (FRAME_NUM_ARGS): Remove.
+
+ * config/i386/tm-i386os9k.h:
+ (TM_I386OS9K_H): Enclose file in test for define & define if needed.
+ (i386/tm-i386.h): Include instead of tm-i386v.h.
+ (START_INFERIOR_TRAPS_EXPECTED): Remove.
+ (NUM_REGS): Undefine before redefining.
+ (FRAME_CHAIN): Remove.
+ (FRAMELESS_FUNCTION_INVOCATION): Remove.
+ (FRAME_SAVED_PC): Move to tm-i386.h.
+
+ * config/i386/tm-i386nw.h:
+ (TM_I386NW_H): Enclose file in test for define & define if needed.
+ (i386/tm-i386.h): Include instead of tm-i386v.h.
+ (START_INFERIOR_TRAPS_EXPECTED): Remove.
+
+ * config/i386/tm-i386bsd.h:
+ (TM_I386BSD_H): Enclose file in test for define & define if needed.
+ (i386/tm-i386.h): Include instead of tm-i386v.h.
+ (START_INFERIOR_TRAPS_EXPECTED): Remove.
+ (FRAMELESS_FUNCTION_INVOCATION): Remove.
+ (FRAME_SAVED_PC): Remove.
+
+ * config/i386/tm-i386aix.h:
+ (i386/tm-i386.h): Include instead of tm-i386v.h.
+ (START_INFERIOR_TRAPS_EXPECTED): Remove.
+ (FP_REGNUM): Remove.
+ (SP_REGNUM): Remove.
+ (PC_REGNUM): Remove.
+ (PS_REGNUM): Remove.
+ (FP0_REGNUM): Moved to tm-i386.h.
+ (NUM_REGS): Remove.
+ (REGISTER_NAMES): Remove.
+ (REGISTER_BYTES): Moved to tm-i386.h.
+ (REGISTER_BYTE): Moved to tm-i386.h.
+ (REGISTER_RAW_SIZE): Moved to tm-i386.h.
+ (MAX_REGISTER_RAW_SIZE): Moved to tm-i386.h.
+ (REGISTER_VIRTUAL_SIZE): Moved to tm-i386.h.
+ (REGISTER_VIRTUAL_TYPE): Removed.
+ (EXTRACT_RETURN_VALUE): Moved to tm-i386.h.
+ (STORE_RETURN_VALUE): Moved to tm-i386.h.
+
+ * config/i386/tm-sun386.h:
+ (TM_SUN386_H): Enclose file in test for define & define if needed.
+ (i386/tm-i386.h): Include.
+ (TARGET_BYTE_ORDER): Remove.
+ (FUNCTION_START_OFFSET): Remove.
+ (SKIP_PROLOGUE): Remove.
+ (SAVED_PC_AFTER_CALL): Remove.
+ (INNER_THAN): Remove.
+ (BREAKPOINT): Remove.
+ (DECR_PC_AFTER_BREAK): Remove.
+ (ABOUT_TO_RETURN): Remove.
+ (REGISTER_SIZE): Remove.
+ (NUM_REGS): Undefine before defining.
+ (REGISTER_NAMES): Undefine before redefining.
+ (REGISTER_BYTES): Undefine before redefining.
+ (REGISTER_BYTE): Undefine before defining.
+ (FP_REGNUM): Undefine before defining.
+ (PC_REGNUM): Undefine before defining.
+ (FPC_REGNUM): Undefine before defining.
+ (REGISTER_RAW_SIZE): Undefine before defining.
+ (FRAME_CHAIN): Undefine before defining.
+ (FRAMELESS_FUNCTION_INVOCATION): Undefine before defining.
+ (FRAME_SAVED_PC): Undefine before defining.
+ (FRAME_NUM_ARGS): Moved to tm-i386.h.
+ (MAX_REGISTER_RAW_SIZE): Remove.
+ (MAX_REGISTER_VIRTUAL_SIZE): Remove.
+ (STORE_STRUCT_RETURN): Remove.
+ (EXTRACT_STRUCT_VALUE_ADDRESS): Remove.
+ (FRAME_ARGS_ADDRESS): Remove.
+ (FRAME_LOCALS_ADDRESS): Remove.
+ (FRAME_NUM_ARGS): Undefine before defining.
+ (FRAME_ARGS_SKIP): Remove.
+ (FRAME_FIND_SAVED_REGS): Remove.
+ (PUSH_DUMMY_FRAME): Remove.
+ (POP_FRAME): Remove.
+ (CALL_DUMMY, CALL_DUMMY_LENGTH, CALL_DUMMY_START_OFFSET): Remove.
+ (struct frame_info, struct frame_saved_regs): Remove forward decls
+ for prototypes.
+
+ * config/i386/tm-i386lynx.h (i386/tm-i386.h): Include instead of
+ tm-i386v.h.
+ * config/i386/tm-i386m3.h (i386/tm-i386.h): Include instead of
+ tm-i386v.h.
+
+ * i386-tdep.c (i386_extract_return_value): Make function visible
+ for all i386 targets, but only assume floating point values returned
+ in floating point registers for I386_AIX_TARGET.
+
+ * i386v-nat.c (i386_register_u_addr): Enable code to locate
+ floating point regs in user struct.
+
+Wed Nov 1 15:32:57 1995 Fred Fish <fnf@cygnus.com>
+
+ * breakpoint.c (breakpoint_re_set): Fix typo in comment.
+ * symtab.c (in_prologue): Document func_start and when it is zero
+ don't call SKIP_PROLOGUE (which typically leads unconditionally to
+ an error when we try to access a prologue at address 0).
+
+Tue Oct 31 13:01:15 1995 Fred Fish <fnf@cygnus.com>
+
+ * elfread.c: Include elf-bfd.h rather than libelf.h.
+
+Tue Oct 31 10:42:42 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * win32-nat.c (xlate_exception): Treat a stack overflow like a SEGV.
+
+Sun Oct 29 11:22:05 1995 Fred Fish <fnf@cygnus.com>
+
+ * monitor.c: Include gnu-regex.h rather than system regex.h.
+
+Sat Oct 28 23:51:48 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * defs.h: Test on name __WIN32__ rather than WIN32.
+ * inflow.c (new_tty): Likewise
+ * terminal.h: Likewise.
+ * utils.c (initialize_utils): Likewise.
+ * win32-nat.c (child_create_inferiror): Print error code when failing.
+ * config/i386/win32.mh (XM_CLIBS): Need -lkernel32.
+
+Sat Oct 28 04:52:36 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * symtab.h (enum address_class): Add LOC_UNRESOLVED for
+ a location whose address has to be resolved via the minimal
+ symbol table.
+ * buildsym.c (finish_block), findvar.c (symbol_read_needs_frame,
+ read_var_value), printcmd.c (address_info),
+ symmisc.c (print_symbol, print_partial_symbol): Handle
+ LOC_UNRESOLVED.
+ * stabsread.c (scan_file_globals): Change unresolved LOC_STATIC
+ symbols to LOC_UNRESOLVED. Remove rt_common_objfile lookup
+ kludge, global common symbols are now handled by LOC_UNRESOLVED.
+ (scan_file_globals_1): Move code back to scan_file_globals,
+ delete.
+
+Fri Oct 27 09:54:07 1995 Stu Grossman (grossman@cygnus.com)
+
+ * breakpoint.c (breakpoint_re_set): #ifdef GET_LONGJMP_TARGET
+ around calls to create_longjmp_breakpoint. Why install the
+ breakpoints if we can't find the longjmp target?
+ * infrun.c (wait_for_inferior): Cleanup comments near call test.
+ * remote-mips.c: Fixed a bunch of prototypes to avoid char/int
+ complaint from picky compilers. Add comment to mips_expect.
+ Replace all instances of sr_get_debug with remote_debug.
+ * (mips_readchar): Don't jam init string to monitor.
+ mips_initialize() handles that.
+ * (mips_receive_header): Print better message when we get too
+ much garbage.
+ * (mips_request): Allow caller to pass in buff to allow them to
+ analyze the returned message.
+ * (mips_initialize): Re-do initialization to try sending a BREAK,
+ a ^C, and then a download escape sequence. Cleanup protocol
+ startup. Eliminate sleeps. Clear breakpoints (if using monitor
+ breakpoints). Re-init frame.
+ * (mips_detach): Close down target.
+ * (mips_wait): Handle return status with registers, or breakpoint
+ * stuff.
+ * (mips_kill): Add ^C handling.
+ * (mips_insert_breakpoint mips_remove_breakpoint): Call new
+ breakpoint stuff if enabled.
+ * (calculate_mask remote_mips_set_watchpoint
+ remote_mips_remove_watchpoint remote_mips_stopped_by_watchpoint):
+ Hardware watchpoint/breakpoint stuff.
+ * (common_breakpoint): Common code for new monitor breakpoint commands.
+ * (mips_load): Don't use `prompt'. It's a global variable.
+ * top.c (dont_repeat_command): New command for use in
+ user-defined commands to suppress auto-repeat (by hittin return key).
+ * valops.c: Add start of auto function-call abandonment capability.
+
+Thu Oct 26 22:02:27 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Add support for PowerMac host, add beginnings
+ of native support.
+ * mpw-make.sed: Disable subdir recursion, edit out useless rule.
+ * mac-xdep.c (Values.h): Don't include.
+ (GestaltEqu.h): Include Gestalt.h instead.
+ (do_mouse_down): Comment out control tracking, needs to be
+ updated to use UPP before will work on PowerMac.
+ * config/xm-mpw.h: New file, all-Mac host support.
+ * config/m68k/xm-mpw.h: Move most definitions into generic Mac
+ support.
+ * config/powerpc/xm-mpw.h: New file, PowerMac host support.
+
+Thu Oct 26 15:21:32 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * regex.h: Renamed to gnu-regex.h.
+ * regex.c: Renamed to gnu-regex.c.
+ * Makefile.in (POSSLIBS): Refer to gnu-regex.h and gnu-regex.c.
+ (REGEX, REGEX1): Change to gnu-regex.o instead of regex.o.
+ (regex.o): Renamed to gnu-regex.o; refer to gnu-regex.c.
+ (irix5-nat.o, osfsolib.o, gnu-regex.o, solib.o, source.o, symtab.o):
+ Likewise.
+ * irix5-nat.c, osfsolib.c, gnu-regex.c, solib.c, source.c, symtab.c):
+ Include "gnu-regex.h" instead of "regex.h".
+ * alpha-tdep.c (in_prologue): Rename to alpha_in_prologue, to
+ avoid conflicts with symtab.h.
+
+Tue Oct 24 18:30:18 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * config/pa/hppahpux.mh: Remove hardcoding of X locations.
+ * Makefile.in: Use X11_CFLAGS, X11_LDFLAGS and X11_LIBS.
+ * configure.in: Link X statically on Solaris, SunOS and HPUX.
+
+Tue Oct 24 12:26:14 1995 Stu Grossman (grossman@cygnus.com)
+
+ * monitor.c (monitor_expect_regexp): Same as monitor_expect, but
+ with the obvious extension.
+ (monitor_read_memory_single): Use regexp for getmem.resp_delim
+ because of parsing ambiguities caused by certain monitors.
+ (monitor_read_memory): Use new regexp stuff to parse
+ getmem.resp_delim.
+ * monitor.h (struct memrw_cmd->resp_delim): Document this as a
+ regexp.
+ * sh3-rom.c: Finish off table. Use new regexp capability for
+ getmem commands.
+
+ * infrun.c (wait_for_inferior): Disable questionable code near
+ the step range test. Replace call detection test with much
+ simpler (and more efficient) test that doesn't require prologue
+ examination (as often).
+ * symtab.c symtab.h (in_prologue): New function that indicates
+ whether or not we are in a function prologue. This uses the
+ symbol table, and then falls back to prologue examination if that
+ fails. It's much more efficient for remote debugging because it
+ avoids examining memory, which is very slow. This is used in
+ wait_for_inferior to determine if we've made a function call that
+ needs to be skipped over (for next/nexti).
+ * mips-tdep.c (after_prologue): New function, returns the PC
+ after the prologue. Uses PDRs and the symbol table.
+ (mips_find_saved_regs): Use in_prologue() to avoid costly
+ prologue examination if possible.
+ (mips_skip_prologue): Use after_prologue() if possible to avoid
+ costly prologue examination.
+
+Mon Oct 23 16:03:33 1995 James G. Smith <jsmith@pasanda.cygnus.co.uk>
+
+ * configure.in (configdirs): Added support for the VR4300 default
+ builds (mips64*vr4300*el-*-elf*, mips64*vr4300*-*-elf*).
+
+ * configure: Regenerated.
+
+ * remote-mips.c (mips_load): Updated the prompt spotting code to
+ make use of the TARGET_MONITOR_PROMPT manifest.
+
+Sat Oct 21 06:11:49 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * alpha-tdep.c, mips-tdep.c (init_extra_frame_info):
+ Do not set saved registers from heuristics for a sigtramp frame.
+
+ * dwarfread.c (enum_type): Determine signedness of enum type
+ from enumerators.
+
+ * mips-tdep.c: Include gdb_string.h, gcc -Wall lint.
+
+ * rs6000-nat.c (xcoff_relocate_core): Fix typo.
+
+ * valops.c (value_repeat): Fix length of memory transfer to
+ match recent allocate_repeat_value change.
+
+Thu Oct 19 19:04:35 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * gdbtypes.c (get_discrete_bounds): Fix typo.
+
+Thu Oct 19 12:15:37 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * defs.h (SEEK_SET, SEEK_CUR): Add default definitions.
+ * dbxread.c, mdebugread.c, os9kread.c (SEEK_SET, SEEK_CUR):
+ Remove default definitions.
+
+ * Makefile.in (CC-LD): Rename to CC_LD, so MPW xform works.
+ (MMALLOC_SRC): Define.
+ (MMALLOC_CFLAGS): Use.
+ (ser-mac.o): Add rule.
+ * dwarfread.c, somread.c, ultra3-nat.c, xcoffread.c: Replace L_SET
+ with SEEK_SET in all calls to bfd_seek.
+ * scm-tags.h (scm_tags): Remove excess comma.
+
+ * mpw-config.in: Adapt to work with autoconf'ed configury;
+ build config.h, add empty definitions to mk.tmp.
+ (powerpc-apple-macos): Make it work.
+ * mpw-make.sed: New file, sed commands to translate Unix makefile
+ into MPW syntax.
+ * mpw-make.in: Remove.
+ * mac-gdb.r: New file, was macgdb.r, renamed for consistency
+ with other tools, now includes cfrg resource.
+ * macgdb.r: Remove.
+ * config/m68k/xm-mpw.h: Remove most of contents, replace with
+ include of include/mpw/mpw.h.
+
+Tue Oct 17 10:38:53 1995 Jeffrey A Law (law@cygnus.com)
+
+ * hppa-tdep.c (frame_chain): Fix more obscure problems caused
+ by system calls that core dump processes without saving all
+ the register state.
+
+ * config/pa/hppahpux.mt (XDEPFILES): Remove bogus definition.
+ * config/pa/hppapro.mt (XDEPFILES): Likewise.
+
+Tue Oct 17 08:04:26 1995 Fred Fish <fnf@rtl.cygnus.com>
+
+ * NEWS: Fix typo.
+
+Mon Oct 16 18:24:03 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * config/sh/tm-sh.h (REGISTER_VIRTUAL_TYPE): Return builtin_type_float
+ for FP registers.
+ (REGISTER_NAMES): Add FP register names. Remove ticks, stalls, cycles,
+ insts, plr, and tlr.
+ (NUM_REGS, NUM_REALREGS): Increase from 23 to 41.
+ (FPUL_REGNUM, FP0_REGNUM): New macros.
+
+Mon Oct 16 11:27:06 1995 Stu Grossman (grossman@cygnus.com)
+
+ * remote-mips.c: Add support for speedy (about 10x faster)
+ downloads.
+
+ * remote-array.c: Move baud_rate initialization from
+ _initialize_array to array_open. It was forcing the baud rate of
+ all targets to be 4800 baud! Seems like I've fixed this before...
+ * config/mips/idt.mt (TDEPFILES): Remove remote-array.o. This
+ has *nothing* to do with IDT!!!
+
+
+ * Makefile.in sh3-rom.c config/sh/sh.mt config/sh/tm-sh.h: Add
+ sh3 monitor support.
+ * monitor.c: Cleanup regexp compilation stuff to make it easier
+ to use several regexps.
+ * monitor.h: Get rid of struct rom_cmd_data. It's no longer used.
+ * config/m68k/tm-monitor.h: Don't redefine NUM_REGS here. It just
+ causes GDB to crash.
+
+ * sparcl-tdep.c: Cleanup serial error handling.
+
+Sun Oct 15 16:19:27 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * rs6000-tdep.c: Don't include a.out.h, improve some formatting.
+
+Fri Oct 13 15:27:49 1995 Stu Grossman (grossman@cygnus.com)
+
+ * dcache.c: Change default value of remotecache to off. It just
+ screws up too many targets.
+ * sparcl-stub.c: Add prototypes to many forward decls.
+ * Create private copies of strlen, strcpy, and memcpy to prevent
+ chaos when user steps into them.
+ * (trap_low handle_exception): Clean up DSU support code
+ (hardware breakpoints). Move lots of stuff from asm-land to
+ C-land (make it much easier to #ifdef if necessary). Also, use
+ trap 255 to get into break mode instead of doing a DSU register
+ write, which may trash the register.
+ * (putpacket): Don't check return value of putDebugChar. It
+ returns void...
+
+Fri Oct 13 14:16:17 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * remote-sim.h: Always include callback.h.
+ (sim_set_callbacks): New declaration.
+
+Fri Oct 13 10:57:40 1995 Jeffrey A Law (law@cygnus.com)
+
+ * somsolib.c (som_solib_add): Just give a warning if a file
+ mentioned in the dld_list can't be found.
+ * config/pa/tm-hppah.h (FRAME_SAVED_PC_IN_SIGTRAMP): Dig out
+ the PC from the PC queues rather than %r31.
+
+Thu Oct 12 13:36:15 1995 Jeffrey A Law (law@cygnus.com)
+
+ * corelow.c (core_open): Don't update the to_sections and
+ to_sections_end fields in core_ops here. It's too late.
+ * irix5-nat.c (solib_add): Update the to_sections and
+ to_sections_end fields in core_ops here if needed.
+ * osfsolib.c (solib_add): Likewise.
+ * rs6000-nat.c (xcoff_relocate_core): Likewise.
+ * solib.c (solib_add): Likewise.
+ * somsolib.c (solib_add): Likewise.
+
+Wed Oct 11 17:25:59 1995 Fred Fish <fnf@rtl.cygnus.com>
+
+ * Makefile.in (VERSION): Bump version to 4.15.1
+
+Tue Oct 10 15:26:39 1995 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (VERSION): Version 4.15 released.
+ * README: Updated for version 4.15.
+ * NEWS: Updated for 4.15 release.
+
+Tue Oct 10 13:18:50 1995 Fred Fish <fnf@cygnus.com>
+
+ * configure.in: Add AC_PROG_YACC
+ * configure: Regenerate
+ * Makefile.in (BISON): Remove macro definition.
+ (YACC): Set from autoconfig.
+ (FLAGS_TO_PASS): Remove BISON.
+ (TARGET_FLAGS_TO_PASS): Remove BISON.
+
+Tue Oct 10 12:25:11 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * win32-nat.c (child_create_inferior): Pass argv correctly.
+ * Makefile.in (win32-nat.o): Add dependencies.
+
+Mon Oct 9 14:36:29 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * NEWS: Add information about win32 and arm code.
+ * win32-nat.c: Renamed from win32.c.
+ * config/i386/win32.mh: Renamed from config/i386/i386win32.mh.
+ * config/i386/win32.mt: Renamed from config/i386/i386win32.mt.
+ * config/i386/tm-win32.h: Renamed from config/i386/tm-i386win32.h.
+ * config/i386/xm-win32.h: Renamed from config/i386/xm-i386win32.h.
+ * configure.in (i[345]86-*-win32): Updated to cope with filename
+ changes.
+ * configure: Regenerated.
+
+Sun Oct 8 18:01:04 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * ch-exp.y (yylex): Also look for '$' following '$'.
+
+Sat Oct 7 22:52:42 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ch-exp.y (yylex): Fix typo.
+
+Fri Oct 6 11:56:49 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * remote-sim.c (gdbsim_open): Put callback initializations here.
+ (_initalize_remote_sim): Not here.
+
+Fri Oct 6 17:08:49 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * top.c (execute_control_command): Use 0/1 instead of BFD's
+ true/false.
+
+Fri Oct 6 14:43:19 1995 Stu Grossman (grossman@cygnus.com)
+
+ * sparcl-stub.c: Include sparclite.h to get access to register
+ fondling macros.
+ * (trap_low): Save and restore FP regs if necessary. Also, clean
+ up save and restore of debug unit regs.
+ * (hard_trap_info): Add more architecturally defined traps.
+ * (set_debug_traps): Only set FP disabled trap if FP is disabled.
+ * (get_in_break_mode): Clean up. Get rid of calls to
+ set_hw_breakpoint_trap(). Also, use write_asi macro.
+ * (handle_exception): Clean up `g' and `G' commands. Add `P'
+ command.
+ * (hw_breakpoint): Why was this here!? It's gone now...
+
+Fri Oct 6 11:56:49 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * callback.c (fdbad): Fix typo in comment.
+ (os_close, os_isatty, os_lseek, os_read, os_write): Use if
+ statements rather than || to get correct return value.
+ (os_write_stdout): Pass missing first argument to os_write.
+ * remote-sim.c: Include callback.h.
+ (_initialize_remote_sim): Call sim_set_callbacks and then
+ initialize the callbacks.
+
+Thu Oct 5 17:28:09 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * values.c (allocate_repeat_value): Allocate an array type, and
+ a value of that type; use that instead of setting VALUE_REPEATED.
+ * value.h (struct value): Remove fields repetitions and repeated.
+ (VALUE_REPEATED, VALUE_REPETITIONS): Removed, no longer used.
+ * c-valprint.c, ch-valprint.c, eval.c, printcmd.c, valops.c,
+ value.h, values.c: Simplify, since now VALUE_REPEATED is never
+ used.
+ * valprint.c (value_print_array_elemen): Removed never-used
+ function.
+
+Thu Oct 5 15:14:36 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * parse.c (write_dollar_variable): New function.
+
+ * c-exp.y (yylex): Replace code for recognizing '$'
+ pseudo-variables with a call to write_dollar_variable.
+ Simplify grammar correspondingly.
+ * f-exp.y: Likewise.
+ * m2-exp.y: Likewise.
+ * ch-exp.y: Likewise. (Remove function match_dollar_tokens.)
+ * scm-exp.c (scm_lreadr): Call write_dollar_variable to handle '$'.
+
+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.
+ * expprint.c (print_subexp): Add OP_NAME support.
+ * parse.c (length_of_subexp, prefixify_subexp): Likewise.
+ * scm-lang.c (scm_unpack, in_eval_c, scm_lookup_name): new function.
+ * scm-lang.h: Declare builtin_type_scm; other minor tweaks.
+ * values.c (unpack_long): If type is SCM, call scm_unpack.
+ * scm-valprint.c (scm_val_print): Use extract_signed_integer,
+ instead unpack_long
+ * scm-lang.c: More Scheme expression parsing from here ...
+ * scm-exp.c: ... to here. New file.
+ Also, provide for gdb to evaluate simple constants and names..
+ * Makefile.in: Note new scm-exp.{c,o}.
+
+Wed Oct 4 17:23:03 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * gdbtypes.c (get_discrete_bounds): New function.
+ (force_to_range_type): Use get_discrete_bounds.
+ * gdbtypes.h (get_discrete_bounds): Add declaration.
+ * valarith.c (value_bit_index): Generalize to use get_discrete_bounds.
+ * ch-valprint.c (chill_val_print): Make (power)sets and bitstring
+ support use get_discrete_bounds and generally be more robust.
+
+Tue Oct 3 16:54:56 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-nrom.c (nrom_ops): Add value for to_thread_alive,
+ add comments naming slots.
+
+Mon Oct 2 21:45:44 1995 Jeff Law (law@hurl)
+
+ * top.c (build_command_line): Demand arguments for if/while
+ commands.
+
+Mon Oct 2 13:08:01 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * Makefile.in (X11_CFLAGS): Set only to @X_INCDIR@.
+
+Sat Sep 30 16:13:36 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * scm-lang.c: Moved Scheme value printing code to ...
+ * scm-valprint.c: ... this new file.
+ Also major improvements in support for printing SCM values.
+ * scm-lang.h: New file.
+ * scm-tags.h: New file.
+ * Makefile.in: Note new scm-valprint.{c,o}.
+
+Sat Sep 30 09:35:02 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in: X_INCDIR and X_LIBDIR added.
+ * Makefile.in: @X_INCDIR@ and @X_LIBDIR@ added.
+ * configure: Regnerated.
+
+Fri Sep 29 02:10:05 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * config/arm/tm-arm.h (FRAME_CHAIN, FRAME_CHAIN_VALID):
+ Any pc > LOWESTPC is ok.
+
+ * remote-rdp.c (rdp_init): Take out variable baud rate stuff.
+ (remote_rdp_detatch): Delete.
+ * breakpoint.c (ctype.h): Don't include twice.
+
+ * Makefile.in (remote-rdp.o): Doesn't need remote-rdp.h
+ * callback.c (os_printf_filtered): fix protos.
+ * defs.h (puts_filtered, puts_unfiltered
+ [v|f|]printf_[un]filtered): Make format arg const.
+ * remote-rdp.c (rdp_init): Attept to sync at different
+ baudrates.
+ * utils.c (puts_filtered, puts_unfiltered
+ [v|f|]printf_[un]filtered): Define prototypes with
+ const in the right place.
+
+Thu Sep 28 17:43:39 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * defs.h (enum language): Add language_scm.
+ * expression.h (enum exp_code): Added OP_EXPRSTRING.
+ * scm-lang.c: Preliminary support for Guile /SCM dialect of Scheme.
+ * expprint.c (print_subexp): Add OP_EXPRSTRING support.
+ * parse.c (length_of_subexp, prefixify_subexp): Likewise.
+ * valops.c (find_function_in_inferior): New function.
+ (value_allocate_space_in_inferior): New function.
+ (allocate_space_in_inferior): Redefine using previous function.
+ * Makefile.in (SFILES): Add scm-lang.c.
+ (COMMON_OBS): Add scm-lang.o
+
+Thu Sep 28 14:32:11 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * callback.[ch]: New files.
+ * remote-rdp.c: Support for the ARM RDP monitor.
+ * Makefile: Update.
+ * arm-tdep.c (arm_othernames): New.
+ (_initialize_arm_tdep): install 'othernames' command.
+ (arm_nullified_insn, shifted_reg_val, arm_get_next_pc): New.
+ * configure.in: Check for termios.h, termio.h and sgtty.h.
+ (i[345]86-*-win32*): New host.
+ * configure: Regenerated.
+ * inflow.c: Clean up inclusions.
+ * main.c (main): Check for WINGDB, not WIN32.
+ * printcmd.c (do_examine): Put QUIT test in loop.
+ * remote-hms.c (e7000_load): Delete.
+ (hms_ops): Point to generic_load instead.
+ * remote-hms.c (hms_ops): Point to generic_load.
+ * remote-sim.c (sim_callback_write_stdout): Becomes
+ gdbsim_write_stdout.
+ (gdbsim_load): Call generic_load.
+ * remote-utils.c (gr_load_image): Delete.
+ * ser-unix.c (terminal.h): Include instead of havig
+ own #if tree.
+ (hardwire_flush_input): Reset input buffer too.
+ * source.c (openp): If WIN32 then open file in binary mode.
+ * terminal.h: Configure IO mechanism using autoconf defines if
+ available and not overriden.
+ * utils.c (quit, pollquit, notice_quit): WIN32 check becomes
+ WINGDB check.
+
+ * config/arm/arm.mt (TDEPFILES): Add remote-rdp.o.
+ * config/arm/tm-arm.h (TARGET_BYTE_ORDER): becomes
+ TARGET_BYTE_ORDER_SELECTABLE.
+ (ADDR_BITS_REMOVE): New.
+ (ORIGINAL_REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): New.
+ (INST_xx): New.
+ (FRAME_FIND_SAVED_REGS): Pass the right argument.
+ (arm_get_next_pc): Declare.
+
+Wed Sep 27 10:14:36 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * valops.c (search_struct_field): Also allow "else" as a variant
+ name.
+ * eval.c (evaluate_struct_tuple): New function. Used to evaluate
+ structure tuples. Now also handles Chill variant records.
+ (get_label): New function, used by evaluate_struct_tuple.
+ (evaluate_subexp_standard case OP_ARRAY): Use evaluate_struct_tuple.
+ (evaluate_labeled_field_init): Removed.
+
+ * valops.c (search_struct_field): Generalize to work with Chill
+ variant records.
+
+Sat Sep 23 01:22:23 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mdebugread.c (parse_partial_symbols): Reset includes_used
+ and dependencies_used after finishing the partial symbol table.
+
+ * rs6000-tdep.c (push_dummy_frame): Handle lr_offset of zero
+ correctly.
+
+ * rs6000-nat.c (xcoff_relocate_core): Don't relocate data
+ addresses for the main objfile if DONT_RELOCATE_SYMFILE_OBJFILE
+ is defined.
+ * xcoffread.c: gcc -Wall lint. Remove traceback table reading
+ code. The existing code tried to add parameter information for
+ functions compiled without -g, which cannot be done properly
+ for optimized code and produced misleading parameter displays.
+ (ef_complaint, eb_complaint): Make a local static copy to avoid
+ dependency on coffread.c.
+ (read_xcoff_symtab, process_xcoff_symbol, scan_xcoff_symtab):
+ Enter C_EXT/C_HIDEXT symbols into the minimal symbol table only.
+ (read_xcoff_symtab): Ignore C_STAT section auxiliary entry
+ symbols. Complain about unmatched .ef and .eb symbols instead of
+ segfaulting.
+ (process_xcoff_symbol): Determine value of C_GSYM symbols via
+ the global_sym_chain mechanism in stabsread.c.
+ (xcoff_new_init): Call stabsread_new_init and buildsym_new_init.
+ (init_string_tab): Initialize length field bytes in the strtbl.
+ (scan_xcoff_symtab): Skip symbols that start with `$' or `.$'.
+ Set first_fun_line_offset for symbols with two auxents only.
+
+Wed Sep 20 21:06:35 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * op50-rom.c (op50n_cmds): Send ".\r" after the interrupt
+ character.
+
+Wed Sep 20 13:12:56 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean): New target, synonym for
+ realclean. Add GNU standard maintainer-clean echos.
+ * gdbserver/Makefile.in (maintainer-clean): New target, synonym
+ for realclean.
+ * nlm/Makefile.in (maintainer-clean): Likewise.
+
+Wed Sep 20 08:16:03 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * defs.h (xmalloc, xrealloc): Delete, they're declared in libiberty.h.
+ (GETENV_PROVIDED, FCLOSE_PROVIDED): New.
+ * doc/gdbint.texinfo (GETENV_PROVIDED, FCLOSE_PROVIDED): Document.
+ * remote-sim.[ch] (sim_callback_write_stdout): New.
+
+Tue Sep 19 15:28:58 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * gdbtypes.c (create_set_type): Set TYPE_LENGTH in bytes, not bits.
+ * valops.c (value_bitstring): TYPE_LENGTH is bytes, not bits.
+
+ * gdbtypes.c (force_to_range_type): Calculate upper limit of
+ TYPE_CODE_CHAR depending on TYPE_LENGTH (instead of just using 255).
+
+Mon Sep 18 01:43:42 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * somsolib.c (auto_solib_add_at_startup): Delete definition. No
+ longer needed.
+
+Sat Sep 16 13:23:36 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/mips/tm-mips.h (UNUSED_REGNUM): Define.
+ * mipsv4-nat.c (supply_gregset): Fill UNUSED_REGNUM register
+ with zero.
+
+Thu Sep 14 17:35:24 1995 Stu Grossman (grossman@cygnus.com)
+
+ * remote-sim.c (gdbsim_create_inferior): Back out change that
+ broke all simulator configurations except the rs6000.
+
+Thu Sep 14 14:44:59 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * monitor.c (monitor_expect): Discard NULL characters.
+
+Thu Sep 14 14:12:30 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * infcmd.c: Add extern declaration for auto_solib_add_at_startup.
+
+Wed Sep 13 13:33:58 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * symfile.c: Move global variable auto_solib_add_at_startup from
+ solib.c to symfile.c.
+ * solib.c: ditto.
+ * symfile.h: Add extern declaration of the above mentioned variable.
+ * infcmd.c: Take out extern declaration, since it's in symfile.h.
+
+Thu Sep 14 12:39:35 1995 Stu Grossman (grossman@cygnus.com)
+
+ * coffread.c (coff_symtab_read): Complain about unmatched .ef and
+ .eb symbols instead of segfaulting.
+
+Wed Sep 13 13:33:58 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * stabsread.c (read_one_struct_field): Use subfile language instead of
+ global language. Improve efficiency.
+
+Wed Sep 13 08:45:02 1995 Jeff Law (law@fast.cs.utah.edu)
+
+ * somsolib.c (auto_solib_add_at_startup): Define new global variable.
+ (som_solib_create_inferior_hook): Don't add libraries if
+ auto_solib_add_at_startup is zero.
+ (_initialize_som_solib): Add command to toggle
+ auto_solib_add_at_startup.
+
+Tue Sep 12 19:37:24 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * monitor.c (monitor_make_srec): Fix thinkos in computation
+ of addr_size.
+
+Tue Sep 12 15:46:18 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * stabsread.c (read_one_struct_field): Add a patch to handle cfront
+ generated stabs that each field is in full mangled name.
+
+ * stabsread.c: To include language.h and expression.h for the reason
+ above.
+
+ * infcmd.c (attach_command): Add solibs only when
+ auto_solib_add_at_startup is set.
+
+Mon Sep 11 17:22:35 1995 Fred Fish <fnf@cygnus.com>
+
+ * NEWS: Add information about remote target caching.
+
+Sun Sep 10 15:36:21 1995 Fred Fish <fnf@cygnus.com>
+
+ * defs.h: Only include mmalloc.h if NO_MMALLOC is not
+ defined.
+
+Sun Sep 10 10:24:48 1995 Michael Tiemann <tiemann@axon.cygnus.com>
+
+ * tm-ppc-eabi.h (PC_IN_CALL_DUMMY): Redefine this to work with the
+ simulator. FIXME.
+
+ * rs6000-tdep.c (push_dummy_frame): Calculate the correct link
+ register offset from the current frame (don't assume it is always 8).
+ (push_dummy_frame): Add comment about having only 4096 bytes of
+ stack space in the simulator (by default).
+
+ * remote-sim.c (gdbsim_create_inferior): Call
+ `add_text_to_loadinfo' so that gdb can find TOC entries when
+ calling functions in the inferior.
+
+Sun Sep 10 09:00:28 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * sparc-tdep.c (fill_fpregset): Fix incorrect FP_MAX_REGNUM
+ substitution.
+ (supply_fpregset): Use FP_MAX_REGNUM.
+
+Sat Sep 9 08:21:52 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * stabsread.c (read_enum_type): Exit loop for putting pending
+ enum symbols into the enum type correctly if we had no pending
+ symbols on entry to read_enum_type.
+
+Fri Sep 8 12:57:41 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * inferior.h: Add extern declaration of inferior_environ.
+ * solib.c (solib_map_sections): To get inferior's env instead of
+ gdb's for LD_LIBRARY_PATH, same for PATH.
+
+ * solib.c (solib_map_sections): Copy full path name into so_list
+ structure so that symbol_file_add can find it.
+
+Tue Sep 5 17:47:53 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/sparc/tm-sp64.h (REGISTER_RAW_SIZE): Lower 32 fp regs
+ have size 4.
+ (REGISTER_VIRTUAL_SIZE): Likewise.
+ (REGISTER_VIRTUAL_TYPE): Lower 32 fp regs have type float.
+ Upper 32 fp regs have type double.
+ * sparc-tdep.c (NUM_SPARC_FPREGS): Replace with
+ (FP_REGISTER_BYTES): this, and update all uses.
+ (FP_MAX_REGNUM): Define if not already.
+ (get_saved_register): Handle new sparc64 fp regs.
+ (sparc_frame_find_saved_regs): Likewise.
+ (sparc_print_register_hook): Only print fp regs < 32 as doubles.
+ Add code to handle long doubles when gdb does.
+ (_initialize_sparc_tdep): Use print_insn_sparc64 if sparc64.
+
+Sat Sep 2 06:41:26 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * configure.in: Explicitly `exit 0' for broken shells.
+ * configure: Rebuilt.
+
+ * symtab.c (list_symbols): Add missing blank after
+ `<function, no debug info>' output.
+
+ * valops.c (value_assign): Handle truncation when assigning
+ to bitfields. Use value_copy to construct the return value
+ from toval.
+ * values.c (value_copy): Copy VALUE_FRAME and VALUE_OPTIMIZED_OUT.
+
+Fri Sep 1 08:25:50 1995 James G. Smith <jsmith@beauty.cygnus.com>
+
+ * configure (mips64*vr4300*-*-elf): Support added.
+ * remote-mips.c (mips_readchar): Change to allow build-time prompt
+ string.
+ * config/mips/tm-mips.h: Added TARGET_MONITOR_PROMPT.
+ * config/mips/{vr4300.mt, vr4300el.mt, tm-vr4300.h,
+ tm-vr4300el.h}: Added.
+
+Thu Aug 31 12:48:04 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * config/sh/sh.mt (SIM): Add -lm.
+
+Wed Aug 30 18:10:57 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * rmote-nindy.c (non_dle, nidy_resume, nindy_wait): Changes to
+ conform to GNU coding standards.
+
+ * solib.c (match_main): Modify to follow GNU coding conventions.
+
+Mon Aug 28 17:07:26 1995 Kung Hsu <kung@lisa.cygnus.com>
+
+ * remote.c (remote_wait): Revert 19 July my change which should be
+ customer specific.
+
+Sat Aug 26 00:26:11 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mdebugread.c (parse_symbol): Handle sh.value of zero for enums.
+ Determine signedness of enum type from enumerators.
+ (parse_type): Handle btIndirect types, handle fBitfield for
+ some non-member types.
+ (upgrade_type): Use TYPE_FLAG_TARGET_STUB for arrays with
+ unknown length.
+ (cross_ref): Handle stIndirect forward reference to btTypedef.
+
+ * stabsread.c (read_enum_type): Determine signedness of enum
+ type from enumerators.
+
+ * top.c (execute_command): Remove trailing whitespace from
+ command arguments, except for `set' and `complete' commands.
+ (validate_comname): Allow underscores in user defined command
+ names.
+
+ * values.c (modify_field): Change `Value does not fit in %d bits'
+ error to a warning. Exclude sign extension bits of negative field
+ values from fit check.
+
+Fri Aug 25 11:31:29 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (powerpc*-*-eabisim*): Only link in the simulator
+ if the target is powerpc{,le}-*-eabisim*, since the simulator
+ needs GCC to build.
+ * config/powerpc/ppc{,le}-sim.mt: Cloned from ppc{,le}-eabi.mt.
+ * config/powerpc/ppc{,le}-eabi.mt: Remove simulator support.
+ * config/powerpc/tm-ppc{,le}-sim.mt: Include tm-ppc{,le}-sim.h.
+
+Wed Aug 23 16:55:35 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/powerpc/ppc{,le}-eabi.mt (SIM_OBJS, SIM): Link in the
+ PowerPC simulator.
+
+Tue Aug 22 02:00:47 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * tm-hppa.h (EXTRACT_RETURN_VALUE): Fix for FP values.
+
+ * tm-hppa.h (STORE_RETURN_VALUE): Fix to work with -msoft-float
+ calling conventions too. Use the TYPE of the return value, not
+ its length to determine if it should also be copied into the
+ floating point registers.
+
+ * tm-hppa.h (PROLOGUE_FIRSTLINE_OVERLAP): Delete. Causes more
+ problems than it fixes.
+ * hppa-tdep.c (skip_prologue): If we exit the main loop without
+ finding all the register saves, retry again without looking for
+ the registers we could not find the first time.
+
+Mon Aug 21 23:39:56 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (frame_chain_valid): Handle systems where "$START$"
+ calls "main" directly.
+ (skip_prologue): Always assume arguments were saved into the stack
+ since GCC will do so without setting the magic Args_Saved bit in
+ the unwind descriptor.
+
+Mon Aug 21 11:49:17 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * remote-udi.c (udi_wait): Mask off high bits of stop reason.
+ * remote-udi.c (fetch_register): For unfetchable regs, pretend it's
+ done. Fix a bug.
+
+Mon Aug 21 00:45:17 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * Makefile.in (install): Remove "brokensed" hack, unnecessary now
+ that we're using autoconf.
+ (uninstall): Likewise.
+
+
+Sat Aug 19 01:19:34 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdbtypes.c (recursive_dump_type): Add dont_print_type_obstack
+ to inhibit infinite recursion when printing aggregate types.
+
+Fri Aug 18 17:48:55 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * dcache.c (dcache_write_line): Write dirty lines right.
+
+Fri Aug 18 06:26:56 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * sparc-tdep.c (isbranch): Fix typo which caused wrong
+ target addresses for annulled branches.
+
+Wed Aug 16 21:54:39 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/pa/tm-hppa.h (PROLOGUE_FIRSTLINE_OVERLAP): Define.
+
+Tue Aug 15 07:51:21 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * remote.c (remote_write_bytes): Chop up large transfers.
+
+Mon Aug 14 17:56:36 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gcc.patch: Remove, relevant only to long-ago versions of GCC.
+
+Mon Aug 14 13:43:01 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * config/sparc/tm-sparclite.h: Define FRAME_CHAIN_VALID_ALTERNATE.
+ * blockframe.c (inside_main_func): If main func addr range not set,
+ try to set it now.
+
+Sat Aug 12 15:34:54 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * config/powerpc/xm-aix.h (FIVE_ARG_PTRACE): Define.
+ * config/rs6000/xm-rs6000.h (FIVE_ARG_PTRACE): Likewise.
+
+ * configure.in: Recognize aix4 specially as some aspects
+ of aix4 need different handling than aix3.
+ * configure: Updated.
+ * config/powerpc/{aix4.mh,aix4.mt,tm-ppc-aix4.h}: New files
+ specific to aix4 support on the power pc.
+ * config/powerpc/tm-ppc-aix.h (DONT_RELOCATE_SYMFILE_OBJFILE): Do
+ not defined. The aix4 specific target files will do that.
+ * config/rs6000/{aix4,mh,aix4,mt,tm-rs6000-aix4.h}: New files
+ specific to aix4 support on the rs6000.
+
+ * config/rs6000/tm-rs6000.h (CONVERT_FROM_FUNC_PTR_ADDR): Don't
+ do the conversion if the pointer is not a magic aix function
+ pointer.
+ * rs6000-tdep.c: Include objfiles.h and symtab.h.
+ (is_magic_function_pointer): New function.
+
+ * rs6000-tdep.c (skip_prologue): Refine check for frameless
+ functions. Handle b .+4 emitted by aix4 compilers. Only
+ allow one load of a minimal toc pointer. Handle aix4 compiler's
+ code for alloca.
+
+ * rs6000-tdep.c (find_toc_address): Report an error if no toc was
+ found rather than possibly core dumping.
+
+ * partial-stab.h: Handle extra field generated by the aix4 compiler
+ for enumerations.
+ * stabsread.c (read_enum_type): Likewise.
+
+Sat Aug 12 03:18:04 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * rs6000-tdep.c (extract_return_value): Fix returning of values
+ whose length is less than the register size for big endian targets.
+
+Fri Aug 11 13:04:32 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * symtab.c (list_symbols): if break command set breakpoint on
+ matched symbol.
+
+Wed Aug 9 18:59:05 1995 Fred Fish <fnf@cygnus.com>
+
+ * defs.h (strchr, strrchr, strstr, strtok, strerror): Enclose in
+ #ifndefs to protect against previous definitions as macros.
+
+Wed Aug 9 14:51:36 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * xcoffread.c (xcoff_symfile_offset): Revert an unwanted change
+ that got in accidentally with Aug 1 change.
+
+Sat Aug 5 09:07:28 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * remote-hms.c (hms_cmds): Get reg term right.
+ * monitor.c (monitor_fetch_register): If we see
+ a non-hex digit, just stop reading.
+ * remote.c (remote_wait): Change way $O is handled.
+
+Wed Aug 9 11:42:36 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * configure.in (powerpc-*-aix*): Recognize as a new gdb host
+ and target.
+ (powerpc-*-eabi*): Don't set configdirs.
+ (powerpcle-*-eabi*): Likewise.
+ * configure: Updated.
+ * rs6000-nat.c (vmap_ldinfo): Don't relocate data addresses
+ for the main objfile if DONT_RELOCATE_SYMFILE_OBJFILE is
+ defined.
+ * config/powerpc/{aix.mh,aix.mh}: Host and target makefile fragments
+ for powerpc running aix4.
+ * config/powerpc/{nm-aix.h, tm-ppc-aix.h, xm-aix.h}: Native, target
+ and host include files for powerpc running aix4.
+
+Wed Aug 9 08:11:45 1995 Stan Shebs <shebs@cygnus.com>
+
+ * top.c (target_output_hook): Really make it match defs.h (char *
+ is not the same as unsigned char *).
+
+Tue Aug 8 15:13:05 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * Makefile.in (CXX_FOR_TARGET): Don't use ${rootme}/../gcc/xgcc
+ unless it is present.
+
+Tue Aug 8 10:50:15 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * top.c (target_output_hook): Make declaration match the one
+ in defs.h.
+
+ * symfile.c (add_psymbol_to_list): Initialize SYMBOL_SECTION.
+ (add_psymbol_addr_to_list): Likewise.
+ * symfile.h (ADD_PSYMBOL_VT_TO_LIST): Likewise.
+
+Mon Aug 7 15:34:29 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * top.c (target_output_hook): New definition.
+ * stack.c (gdb_string.h): Include after defs.h
+ * defs.h (target_output_hook): New declaration.
+ * source.c (mod_path): Fix Win32 \ handling.
+
+Sun Aug 6 22:14:25 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (frame_saved_pc): Don't try to dig a return pointer
+ out of a long branch stub.
+
+Fri Aug 4 13:37:31 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * xcoffread.c (process_linenos): Fix typo in last change.
+
+Thu Aug 3 22:01:26 1995 Fred Fish <fnf@rtl.cygnus.com>
+
+ * ch-exp.y (write_lower_upper_value): Add prototype so bison
+ generated parser will insert prototype before first func usage.
+ Bison and byacc order the output sections differently. Also
+ make function static.
+
+Thu Aug 3 10:45:37 1995 Fred Fish <fnf@cygnus.com>
+
+ * Update all FSF addresses except those in COPYING* files.
+
+Thu Aug 3 01:38:45 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/alpha/tm-alpha.h (EXTRA_FRAME_INFO): Add pc_reg field.
+ (SKIP_TRAMPOLINE_CODE): Define.
+ * alpha-tdep.c (alpha_frame_saved_pc): Use pc_reg field from
+ frame to find the saved pc register.
+ (alpha_saved_pc_after_call): Skip over shared library trampoline
+ before trying to find the saved pc register.
+ (find_proc_desc): Copy PROC_PC_REG from found proc_desc
+ to heuristic proc_desc.
+ (init_extra_frame_info): Initialize pc_reg field in frame.
+
+Wed Aug 2 18:00:36 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.in (m68*-est-*): Use monitor target config.
+ * configure: Update.
+ * config/m68k/est.mt, config/m68k/tm-est.h: Delete.
+ * config/m68k/monitor.mt, config/m68k/tm-monitor.h: Fix comments.
+
+Tue Aug 1 22:52:53 1995 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (VERSION): Bump to 4.14.2
+
+Tue Aug 1 16:04:36 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * xcoffread.c (process_linenos): The value in include file symbol
+ should point to line number table. Currently this value is not
+ set correctly by AIX ld. A fix to get around this bug.
+
+Tue Aug 1 11:44:53 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * configure.in: Check for working mmap, ansi headers, string.h,
+ strings.h, and memory.h.
+ * configure: Regenerated.
+
+ * gdb_stat.h: New file, "portable" <sys/stat.h>.
+ * gdb_string.h: New file, "portable" <string.h>.
+
+ * altos-xdep.c, arm-tdep.c, arm-xdep.c, convex-tdep.c,
+ convex-xdep.c, coredep.c, cxux-nat.c, dbxread.c, exec.c,
+ gould-xdep.c, hppa-tdep.c, i386aix-nat.c, i386b-nat.c,
+ i386mach-nat.c, i386v-nat.c, infptrace.c, m88k-nat.c, main.c,
+ mdebugread.c, objfiles.c, os9kread.c, procfs.c, pyr-xdep.c,
+ rs6000-nat.c, source.c, standalone.c, stuff.c, sun386-nat.c,
+ symfile.c, symm-nat.c, symm-tdep.c, symtab.c, top.c, ultra3-nat.c,
+ ultra3-xdep.c, umax-xdep.c, xcoffread.c: Include "gdb_stat.h"
+ instead of <sys/stat.h>.
+
+ * alpha-tdep.c, breakpoint.c, buildsym.c, c-typeprint.c,
+ ch-typeprint.c, coffread.c, command.c, core-sol2.c, core-svr4.c,
+ core.c, corelow.c, cp-valprint.c, dbxread.c, dcache.c, demangle.c,
+ dpx2-nat.c, dstread.c, dwarfread.c, elfread.c, environ.c, eval.c,
+ exec.c, f-lang.c, f-typeprint.c, f-valprint.c, findvar.c,
+ fork-child.c, gdbtypes.c, hpread.c, i386-tdep.c, infcmd.c,
+ inflow.c, infptrace.c, infrun.c, irix5-nat.c, language.c,
+ m2-typeprint.c, main.c, mdebugread.c, minsyms.c, mipsread.c,
+ monitor.c, nlmread.c, objfiles.c, os9kread.c, osfsolib.c, parse.c,
+ printcmd.c, procfs.c, regex.c, remote-adapt.c,
+ remote-array.c, remote-bug.c, remote-e7000.c, remote-eb.c,
+ remote-es.c, remote-hms.c, remote-mm.c, remote-os9k.c,
+ remote-pa.c, remote-sim.c, remote-st.c, remote-udi.c,
+ remote-utils.c, remote-vx.c, remote-vx29k.c, remote-vx68.c,
+ remote-vx960.c, remote-vxmips.c, remote-vxsparc.c, remote.c,
+ solib.c, somread.c, source.c, stabsread.c, stack.c, symfile.c,
+ symmisc.c, symtab.c, target.c, top.c, typeprint.c, utils.c,
+ valarith.c, valops.c, valprint.c, values.c, xcoffread.c: Include
+ "gdb_string.h" instead of <string.h>.
+
+ * config/xm-sysv4.h, i386/xm-ptx.h, m68k/xm-sun3os4.h,
+ sparc/xm-sun4os4.h (HAVE_MMAP): Removed.
+
+ * config/xm-lynx.h, config/i386/xm-ptx.h,
+ config/m68k/nm-apollo68b.h, config/m68k/xm-hp300hpux.h,
+ config/mips/xm-irix3.h, config/mips/xm-mips.h,
+ config/mips/xm-news-mips.h, config/mips/xm-riscos.h,
+ config/pa/hppah.h, config/rs6000/xm-rs6000.h,
+ config/sparc/xm-sun4os4.h, config/sparc/xm-sun4sol2.h,
+ config/vax/xm-vaxbsd.h, config/vax/xm-vaxult.h,
+ config/vax/xm-vaxult2.h (MEM_FNS_DECLARED): Removed.
+ * config/mips/xm-irix3.h, config/mips/xm-mips.h,
+ config/pa/xm-hppah.h (memcpy, memset): Removed declarations.
+
+Tue Aug 1 02:08:30 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mips-tdep.c (mips_extract_return_value): Fix returning of
+ values whose length is less than the register size for big endian
+ targets.
+ * alpha-tdep.c (alpha_extract_return_value,
+ alpha_store_return_value): Use alpha_convert_register_to_*
+ to handle functions returning "float" correctly.
+
+Mon Jul 31 19:12:48 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * h8500-tdep.c: General linting and cleanup.
+ (opcodes/h8500-opc.h): Don't include.
+ (code_size, data_size): Make static.
+ (frame_locals_address, frame_args_address): Remove.
+ (h8300_pop_frame): Rename to h8500_pop_frame.
+ (big_command, medium_command, compact_command, small_command):
+ Define as regular functions rather than with macro trickery.
+ (tm_print_insn): Set to correct disassembler function.
+ * config/h8500/tm-h8500.h: Minor cleanup, add prototypes.
+ (ABOUT_TO_RETURN): #if 0 out.
+ (FRAME_ARGS_ADDRESS, FRAME_LOCALS_ADDRESS): Use usual define.
+ (GDB_TARGET_IS_H8500): Remove duplicate definition.
+ (regoff): Remove, never used.
+ * config/h8500/h8500.mt (TDEPFILES): Add monitor.o.
+
+Mon Jul 31 14:32:30 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * configure.in: Check for unistd.h.
+ * configure: Regenerated.
+
+ * command.c, cp-valprint.c, fork-child.c, i386-tdep.c,
+ i386b-nat.c, inflow.c, main.c, maint.c, objfiles.c, solib.c,
+ source.c, stack.c, symfile.c, top.c, utils.c: Include strings.h
+ and/or unistd.h to bring prototypes into scope.
+
+Sun Jul 30 01:40:11 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * rs6000-tdep.c (frame_saved_pc): Check for signal handler caller
+ before trying to determine the start of the function.
+ (skip_prologue): Skip subroutine call which might save the
+ floating point registers only if it is within the first three
+ instructions.
+ Reinstate setting of alloca_reg if setup of a gcc frame pointer
+ is found.
+ (frame_get_cache_fsr): Use new fields in rs6000_framedata.
+
+Sat Jul 29 14:43:35 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * sparclite: Removed subdirectory. aload and eload are now in
+ utils/sparclite, low-level library is in libgloss.
+ * configure.in (sparclite*): Don't configure sparclite subdir.
+ * configure: Update.
+ * Makefile.in (TARDIRS): Remove, no longer used.
+
+Sat Jul 29 01:45:56 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * procfs.c (unconditionally_kill_inferior): Clear current signal
+ if PROCFS_NEED_CLEAR_CURSIG_FOR_KILL is defined.
+ * config/alpha/nm-osf3.h (PROCFS_NEED_CLEAR_CURSIG_FOR_KILL): Define.
+
+ * alpha-tdep.c: Move sigtramp handling of saved registers from
+ read_next_frame_reg to alpha_find_saved_regs, handle saved
+ floating point registers.
+ * mips-tdep.c: Move sigtramp handling of saved registers from
+ read_next_frame_reg to mips_find_saved_regs, handle saved
+ floating point registers.
+ * config/mips/tm-irix3.h, config/mips/tm-irix5.h,
+ config/mips/tm-mipsv4.h (SIGFRAME_FPREGSAVE_OFF): Define.
+
+ * sparc-tdep.c (sparc_pc_adjust): Fix check for `unimp'
+ instruction to handle functions returning structures with
+ large sizes properly.
+
+Fri Jul 28 11:50:17 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * configure, configure.in (z8k-*-sim): deleted.
+
+Thu Jul 27 12:49:28 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * lynx-nat.c (child_wait): Handle threads exiting.
+
+Thu Jul 27 07:47:50 1995 Michael Meissner <meissner@cygnus.com>
+
+ * rs6000-tdep.c (skip_prologue): Don't assume the update stack
+ instruction is the last in the prologue, since xlc stores the lr
+ after the stack update. Make sure offset is correct sign for
+ large frames.
+ (frame_saved_pc): Move test for signal before frameless.
+
+ * config/rs6000/tm-rs6000.h (DEFAULT_LR_SAVE): Define.
+ * config/powerpc/tm-ppc-eabi.h (DEFAULT_LR_SAVE): Redefine.
+
+Thu Jul 27 01:22:08 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * hppa-tdep.c (hppa_fix_call_dummy): Rewrite code for calling
+ into shared libraries.
+
+Wed Jul 26 23:33:34 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/rs6000/tm-rs6000.h (rs6000_framedata): Add offsets the
+ gprs, fprs, lr, and cr is stored at.
+ (FRAME_FIND_SAVED_REGS): Use new fields in rs6000_framedata.
+ (function_frame_info): Delete declaration.
+ (SKIP_PROLOGUE): Skip_prologue is now passed a rs6000_framedata
+ structure to fill in.
+ (FRAMELESS_FUNCTION_INVOCATION): Function now longer takes a
+ second argument.
+ (FRAME_SAVED_PC): Call frame_saved_pc.
+
+ * rs6000-tdep.c (skip_prologue): Recognize V.4 prologues as well
+ as AIX style. Fill in rs6000_framedata structure. Remember where
+ the gprs, fprs, cr, and lr are saved.
+ (pop_frame): Use skip_prologue, not function_frame_info, and use
+ new rs6000_framedata fields.
+ (function_frame_info): Function deleted.
+ (frameless_function_invocation): Separate frame_saved_pc support
+ to new function. Recognize V.4 frames.
+ (frame_saved_pc): New function.
+ (frame_get_cache_fsr): Use skip_prologue, not function_frame_info.
+ (frame_initial_stack_address): Ditto.
+
+Wed Jul 26 01:00:37 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * remote.c: Add documentation for extended protocol operations
+ and for thread_alive change from a couple weeks ago.
+ (extended_remote_ops): Declare and define a new target vector
+ for the extended remote protocol.
+ (extended_remote_restart): New function to restart the remote
+ server & process.
+ (remote_open): Just a stub routine.
+ (extended_remote_open): New function to start a remote session
+ using the extended gdb remote protocol.
+ (remote_open_1): New function containing code common to both
+ remote_open and extended_remote_open.
+ (remote_mourn, extended_remote_mourn, remote_mourn_1): Similarly.
+ (extended_remote_create_inferior): New function for the extended
+ remote target.
+ (initialize_remote): Add the extended_remote_ops target vector.
+ * gdbserver/server.c (main, case '!'): Set extended_protocol.
+ (main, case 'k'): If the extended protocol is in use, kill the
+ inferior then start a new one.
+ (main, case 'R'): New command to restart the remote server and
+ inferior process. Only supported when using the extended
+ protocol.
+ (main, server loop): If the inferior terminates while using the
+ extended protocol then start a new one. If getpkt fails when
+ using the extended protocol then exit.
+
+Tue Jul 25 11:43:44 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mdebugread.c (psymtab_to_symtab_1): Relocate encoded stab
+ line numbers using the psymtab's section offsets.
+
+Tue Jul 25 10:43:27 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/rs6000/tm-rs6000.h (rs6000_framedata): Rename from
+ aix_framedata. Change all uses.
+ * rs6000-tdep.c: Change all aix_framedata -> rs6000_framedata.
+
+Sat Jul 22 23:44:18 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * defs.h (ATTR_FORMAT): Disable if ANSI_PROTOTYPES is not defined.
+
+Fri Jul 21 16:50:28 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * lynx-nat.c (child_thread_alive): New function. Somehow I
+ forgot to check this in with all the other thread_alive changes.
+
+Thu Jul 20 22:22:34 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * somread.c (som_symtab_read): Add unsatisfied common symbols to
+ the minimal symbol table. All common symbols are "unsatisfied"
+ when -E is passed to the linker.
+
+Thu Jul 20 15:04:57 1995 Fred Fish <fnf@cygnus.com>
+
+ * top.c (show_endian): Cast first arg of printf_unfiltered to
+ correct type of "char *".
+
+Thu Jul 20 14:18:51 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * lynx-nat.c (child_wait): A thread_id of zero from wait apparently
+ means the process is single threaded, so there's no need to add
+ it to the thread list. Handle case where multi-threaded process
+ reverts back to a single-threaded process.
+
+ * gdbserver/low-hppabsd.c: Remove error declaration.
+ * gdbserver/low-sparc.c: Likewise.
+ * gdbserver/low-sun3.c: Likewise.
+ * gdbserver/server.h: Remove error and fatal declaration.
+ * gdbserver/utils.c (error): Update to be compatable with recent
+ changes in defs.h.
+ (fatal): Likewise.
+
+Wed Jul 19 22:42:43 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/m68k/tm-m68kv4.h (DWARF_REG_TO_REGNUM): Define to
+ correctly map floating point registers numbers.
+
+ * dwarfread.c (locval, new_symbol): Handle variables that are
+ optimized out.
+
+ * mdebugread.c: Replace all uses of builtin_type_* with
+ mdebug_type_*. Define and initialize mdebug_type_*.
+
+ * serial.h (serial_close): Add additional argument `really_close'.
+ (SERIAL_CLOSE): Update serial_close call accordingly.
+ (SERIAL_UN_FDOPEN): Use serial_close to handle refcnt properly.
+ * serial.c (serial_close): Handle `really_close'.
+ * serial.h (scb_base): Moved to serial.c, made static.
+
+ * valops.c (value_addr): Don't coerce arrays.
+ (typecmp): Coerce arrays instead of calling value_addr if necessary.
+
+Wed Jul 19 18:19:28 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Richard Earnshaw (rearnsha@armltd.co.uk):
+ * infrun.c (wait_for_inferior): Set the convenience variable
+ $_exitcode to the termination code of the inferior.
+ * top.c (quit_command): Accept optional expression to use
+ as parameter to exit().
+
+Wed Jul 19 13:15:32 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * remote.c (remote_wait): When getting registers, check endianess and
+ do conversion if necessary.
+
+Tue Jul 18 00:41:31 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdbserver/low-hppabsd.c: New file.
+ * gdbserver/Makefile.in (SFILES): Add low-hppabsd.c.
+ * config/pa/hppabsd.mh (XDEPFILES): Add ser-tcp.o.
+ (GDBSERVER_DEPFILES): Add low-hppabsd.o.
+ * config/pa/hppaosf.mh: Likewise.
+
+Mon Jul 17 21:35:18 1995 Fred Fish <fnf@cygnus.com>
+
+ * dache.c (struct dcache_block): Change data member from unsigned
+ char to char, since everything passed in and out of dcache is char
+ or casted to appropriate type anyway.
+ (dcache_alloc): Move assignment of db out of test and combine
+ separate tests into if-else.
+ (dcache_peek_byte): Change ptr from unsigned char* to char*.
+ (dcache_peek_byte): Remove now unnecessary cast in read_memory call.
+ (dcache_peek): Change cast of incoming data arg.
+ (dcache_poke): Change cast of addr of incoming data arg.
+ (dcache_info): Mask data passed to printf_filtered to lsbyte only.
+ (dcache_info): Change printf_filtered arg from "% 2x" to " %2x".
+ * target.c (debug_to_thread_alive): Change return type to int and
+ return zero, for type compatibility with other *_thread_alive
+ funcs.
+ (cleanup_target): Change cast of ignore function to match type of the
+ to_thread_alive member.
+ * defs.h (error_hook): Add ATTR_NORETURN.
+ * defs.h (NORETURN, ATTR_NORETURN): Switch from volatile to
+ __attribute__ method with gcc 2.7, to avoid gcc 2.6.3 bug.
+ * remote.c (remote_wait): Cast first arg to strtol, strchr, and
+ strncmp to "const char *" from "unsigned char *".
+ (remote_wait): Cast arg to putpkt and strcpy from "unsigned char *"
+ to "char *".
+ (remote_wait): Change printf format for long arg from "%d" to "%ld".
+ (getpkt): Remove unused variable "bp".
+ (remote_fetch_word, remote_store_word): Ifdef out apparently unused
+ functions.
+ * breakpoint.c (watchpoint_check): Removed unused variables
+ "saved_level" and "saved_frame".
+ * valops.c (value_arg_coerce): Add other enum TYPE_CODE_* and
+ default cases to switch for completeness.
+ * infrun.c (wait_for_inferior): Enclose "have_waited" label
+ in #ifdef that matches the one in which it is referenced.
+ * ser-unix.c (hardwire_noflush_set_tty_state): Enclose otherwise
+ unused variable "state" in #ifdef that matches one in which it is
+ referenced.
+ * eval.c (evaluate_subexp_standard): Remove unused variable "var".
+ * eval.c (evaluate_subexp_standard): Remove unused variable
+ "tmp_symbol".
+ * valarith.c (value_subscript): Remove unused variable
+ "lowerbound", which is redeclared in a nested scope prior to use.
+ * printcmd.c (print_frame_nameless_args): Use "%ld" to print long
+ arg, not "%d".
+ * {mem-break.c, remote-pa.c, remote.c, saber.suppress}:
+ Remove unused static var "check_break_insn_size".
+ * buildsym.c (finish_block): Add other enum LOC_* and default
+ cases to switch for completeness.
+ ch-lang.c (type_lower_upper): Removed unused label "retry".
+ Add other enum TYPE_* and default cases to switch for completeness.
+ * f-typeprint.c (f_type_print_args): Ifdef out unused function
+ that may be used someday when Fortran support is complete.
+ * ch-valprint.c (chill_print_type_scalar): Add other enum
+ TYPE_* and default cases to switch for completeness.
+ (chill_val_print): Remove unused local var "high_bound" that
+ is redeclared in a nested scope prior to use.
+ (chill_var_print): Use "%ld" to print long arg, not "%d".
+ * regex.c (re_compile_fastmap, re_match_2): Add remaining enum
+ types and default to switches for completeness.
+ * minsyms.c (lookup_minimal_symbol_text): Delete unused variable
+ "trampoline_symbol".
+ (prim_record_minimal_symbol_and_info): Return NULL rather than
+ trash.
+ * elfread.c (elf_symtab_read): Don't dereference NULL returns from
+ record_minimal_symbol_and_info.
+ * f-lang.c (saved_function_list_end): Ifdef out unused variable
+ that may be used someday.
+ * f-valprint.c (f_val_print): Remove unused local "straddr".
+
+Mon Jul 17 13:08:00 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabsread.h (struct stab_section_list): Define.
+ (coffstab_build_psymtabs): Remove staboff and stabsize parameters.
+ Add textaddr, textsize, and stabs parameters.
+ * gdb-stabs.h (struct dbx_symfile_info): Remove text_sect field.
+ Add text_addr and text_size fields.
+ (DBX_TEXT_SECT): Don't define.
+ (DBX_TEXT_ADDR, DBX_TEXT_SIZE): Define.
+ * coffread.c: Include <ctype.h>.
+ (struct coff_symfile_info): Remove stabsect and stabindexsect
+ fields. Add textaddr, textsize, and stabsects fields.
+ (coff_locate_sections): Record the address of the .text section,
+ and total the sizes of all sections with names beginning with
+ ".text". Don't bother to record a .stab.index section (COFF
+ doesn't use them). Make a linked list of all sections with names
+ beginning with ".stab".
+ (coff_symfile_read): Adjust call to coffstab_build_psymtabs for
+ new parameters.
+ * dbxread.c (dbx_symfile_read): Use DBX_TEXT_ADDR and
+ DBX_TEXT_SIZE, rather than getting both from DBX_TEXT_SECT.
+ (dbx_symfile_init): Set DBX_TEXT_ADDR and DBX_TEXT_SIZE, not
+ DBX_TEXT_SECT.
+ (elfstab_build_psymtabs): Likewise.
+ (stabsect_build_psymtabs): Likewise.
+ (symbuf_sections, symbuf_left, symbuf_read): New static variables.
+ (fill_symbuf): If symbuf_sections is not NULL, read symbols from
+ multiple sections.
+ (coffstab_build_psymtabs): Remove staboffset and stabsize
+ parameters. Add textaddr, textsize, and stabsects parameters.
+ Set DBX_TEXT_ADDR and DBX_TEXT_SIZE, not DBX_TEXT_SECT. Handle
+ multiple stabs sections.
+ * os9kread.c (os9k_symfile_read): Use DBX_TEXT_ADDR and
+ DBX_TEXT_SIZE, rather than getting both from DBX_TEXT_SECT.
+ (os9k_symfile_init): Set DBX_TEXT_ADDR and DBX_TEXT_SIZE, not
+ DBX_TEXT_SECT.
+
+ * remote-vx.c (vx_ops, vx_run_ops): Initialize new to_thread_alive
+ field.
+
+Sat Jul 15 01:02:53 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/alpha/alpha-osf3.mh, config/alpha/nm-osf3.h: New files
+ for OSF/1-3.x procfs support.
+ * configure.in (alpha-dec-osf): Use them when configuring
+ for OSF/1-3.x.
+ * configure: Updated.
+ * target.c: Include <string.h>.
+
+Fri Jul 14 16:16:56 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * Makefile.in, configure.in: Use one variable, frags, to hold
+ pathnames of makefile fragments.
+ * configure: regenerated.
+
+Fri Jul 14 09:49:47 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * procfs.c (procfs_ops): Fix typo in last change.
+
+Thu Jul 13 13:42:38 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * inftarg.c (child_thread_alive): New function to see if a
+ particular thread is still running.
+ (child_ops): Add child_thread_alive entry.
+ * remote.c (remote_thread_alive): New function to see if a
+ particular thread is still alive.
+ (remote_ops): Add remote_thread_alive.
+ * target.c (dummy_target): Add dummy entry for thread_alive.
+ (cleanup_target): de_fault thread_alive too.
+ (update_current_target): INHERIT thread_alive too.
+ (debug_to_thread_alive): New function.
+ (setup_target_debug): Add debug_to_thread_alive.
+ * target.h (struct target_ops): Add to_thread_alive.
+ (target_thread_alive): Define.
+ * thread.c (info_threads_command): Don't call kill; use
+ target_thread_alive instead.
+ * config/nm-lynx.h (CHILD_THREAD_ALIVE): Define.
+ * gdbserver/low-lynx.c (mythread_alive): New function.
+ (mywait): Don't restart any threads after a new thread notification,
+ let the generic code handle it.
+ * gdbserver/low-sparc.c (mythread_alive): Dummy version.
+ * gdbserver/low-sun3.c (mythread_alive): Likewise.
+ * gdbserver/server.c (main): Handle thread_alive requests.
+ * gdbserver/server.h (mythread_alive): Declare.
+ * corelow.c (core_ops): Add dummy entry for thread_alive.
+ * exec.c (exec_ops): Likewise.
+ * m3-nat.c (m3_ops): Likewise.
+ * monitor.c (monitor_ops): Likewise.
+ * procfs.c (procfs_ops): Likewise.
+ * remote-array.c (array_ops): Likewise.
+ * remote-e7000.c (e7000_ops): Likewise.
+ * remote-es.c (es1800_ops, es1800_child_ops): Likewise.
+ * remote-mips.c (mips_ops): Likewise.
+ * remote-pa.c (remote_hppro_ops): Likewise.
+ * remote-sim.c (gdbsim_ops): Likewise.
+ * sparcl-tdep.c (sparclite_ops): Likewise.
+
+Tue Jul 11 11:15:55 1995 Kung Hsu <kung@rtl.cygnus.com>
+
+ * solib.c: Add _DYNAMIC__MGC base symbol for Mentor Graphics Inc.
+ * solib.c (match_main): New function for checking name of main.
+ * solib.c (solib_add): Not to add if solib match main.
+
+Fri Jul 7 14:41:56 1995 Kung Hsu <kung@rtl.cygnus.com>
+
+ * elfread.c (elf_symtab_read): Fix a bug ignoring compiler
+ generated internal labels ($LM...).
+
+Wed Jul 5 11:38:36 1995 Kung Hsu <kung@rtl.cygnus.com>
+
+ * defs.h: if __GO32__ or WIN32 the directory separating symbol should
+ be '\' not '/'.
+
+ * remote-nindy (nindy_wait): Use infinite timeout reading after
+ esacpe character.
+
+Tue Jul 4 10:30:22 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * infrun.c (wait_for_inferior): When switching from one thread to
+ another, save infrun's state for the old thread and load infrun's
+ previous state for the new thread.
+ * thread.c (struct thread_info): Add new fields for thread specific
+ state saved/restored in infrun.c.
+ (add_thread): Initialize new fields.
+ (load_infrun_state): New function.
+ (save_infrun_state): New function.
+ * thread.h (load_infrun_state): Provide external decl.
+ (save_infrun_state): Likewise.
+
+ * infrun.c (wait_for_inferior): When we hit a breakpoint for the
+ wrong thread, make sure to write the fixed PC value into the thread
+ that stopped. Restart all threads after single stepping over a
+ breakpoint for a different thread.
+ * breakpoint.c (set_momentary_breakpoint): Make momentary
+ breakpoints thread specific in a multi-threaded program.
+ * lynx-nat.c (child_resume): Add some comments. Correctly
+ choose between the single and multi-threaded step and continue
+ ptrace calls.
+
+Fri Jun 30 16:15:36 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/h8300/h8300.mt: Renamed from h8300hms.mt.
+ * config/h8500/h8500.mt: Renamed from h8500hms.mt.
+ * config/z8k/z8k.mt: Renamed from z8ksim.mt.
+ * configure, configure.in: Update to reflect renamings.
+
+ * remote-sim.c (sim): New command, passes commands to simulator.
+ (simulator_command): New function.
+ (gdbsim_ops): Clean up.
+ * remote-sim.h (sim_do_command): Declare.
+ * sh-tdep.c (memory_size): Remove command.
+
+ * Makefile.in (SIM, SIM_OBS): New variables.
+ (CLIBS, CDEPS): Add value of SIM.
+ (DEPFILES): Add value of SIM_OBS
+
+ * config/arm/arm.mt, config/h8300/h8300.mt, config/h8500/h8500.mt,
+ config/sh/sh.mt, config/sparc/sp64sim.mt, config/w65/w65.mt,
+ config/z8k/z8k.mt: Remove simulator files from TDEPFILES,
+ define in SIM_OBS and SIM.
+ config/sparc/sp64sim.mt (SIMFILES): Remove.
+
+ * remote-z8k.c: Remove, was superseded by remote-sim.c
+ * Makefile.in, mpw-make.in: Remove references to remote-z8k.c.
+
+Sun Jun 25 15:30:43 1995 Stan Shebs <shebs@cygnus.com>
+
+ * remote.c (remote_read_bytes, remote_write_bytes): Second arg
+ should be char *, not unsigned char *.
+ * dcache.h (memxferfunc): Ditto.
+ * monitor.c (monitor_write_memory, monitor_read_memory_single):
+ Ditto.
+ (monitor_make_srec): Let compiler figure size of hextab.
+
+Sat Jun 24 19:27:37 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * lynx-nat.c (child_wait): Don't restart new threads and loop
+ to the top of child_wait; let the machine independent code in
+ wait_for_inferior deal with new thread notifications.
+
+Fri Jun 23 11:51:58 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * remote-nindy (nindy_load): Put in target specific load, it's
+ 20 times faster.
+
+Thu Jun 22 20:21:59 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * utils.c (error): Move local `args' outside conditional,
+ move local `string1' inside, declare function as void if
+ non-ANSI compiler, dereference error_hook when calling.
+
+ * mac-xdep.c (stdarg.h): Don't include.
+
+Thu Jun 22 13:12:33 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * remote-nindy.c (nindy_wait): Change timeout in SERIAL_READCHAR.
+
+Wed Jun 21 13:24:41 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppam3-nat.c: Change HP800_THREAD_STATE to TRACE_FLAVOR and
+ HP800_THREAD_STATE_COUNT to TRACE_FLAVOR_SIZE.
+
+Wed Jun 21 05:57:56 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * monitor.c: Turn on caching.
+ (monitor_printf): If a ^C was sent, don't expect to see its
+ echo.
+ (monitor_open): Enable caching.
+ (monitor_resume, monitor_load): Flush cache.
+ (monitor_xfer_memory): Call cache routine.
+ (monitor_dump_regs): New.
+ (monitor_fetch_registers): If monitor_dump_regs available
+ then use it.
+ (monitor_load): Don't ref exec_bfd if it's NULL.
+ (monitor_load_srec): Use new monitor_make_srec calling convention.
+ (monitor_make_srec): Rewrite to cope with two, three and four byte
+ addresses.
+ * remote-hms.c (hms_cmds): Initialze end-of-command delim.
+ * dcache.h, dcache.h: Rewritten.
+ * remote.c: Reenable caching.
+ (getpkt): Reduce MAX_TRIES to 3.
+ (remote_xfer_memory): Use dcache_xfer_memory.
+ * defs.h (error_hook): New.
+ * top.c (error_hook): New definition.
+ * utils.c (error): Use error_hook if initialized.
+ * sparcl-tdep.c (HAVE_SOCKETS): Don't define if GO32 or WIN32. Use
+ HAVE_SOCKETS in place of #ifndef GO32.
+
+Tue Jun 20 22:17:44 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/pa/tm-hppa.h (PSW_*): Define processor status word masks.
+ (INSTRUCTION_NULLIFIED): Allow specific targets to override.
+ * config/pa/tm-hppao.h (INSTRUCTION_NULLIFIED): Define to work
+ around losing mach kernel behavior.
+
+Tue Jun 20 12:03:36 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * monitor.c (monitor_wait): Don't use the watchdog timeout
+ if its value is 0.
+ * w89k-rom.c (w89k_open): Define to be static.
+
+
+Sat Jun 17 10:17:16 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * somsolib.c (som_solib_add): Validate regexp argument.
+ Don't assume the first entry on dld's library list is the main
+ program. Don't load the same library more than once and don't
+ consider the main program a shared library.
+ (som_solib_sharedlibrary_command): New function
+ (_initialize_som_solib): Add "sharedlibrary" command.
+
+Thu Jun 15 14:54:58 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * array-rom.c: Remove, no longer used.
+
+ * remote-hms.c (hms_open): Make static.
+
+ * mpw-config.in (MacSerial.h): Copy from version in {CIncludes},
+ not {MPW}Interfaces:CIncludes.
+ * ser-mac.c (mac_baud_rate_table): Fix value for 38400 baud.
+
+Wed Jun 14 14:27:07 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * ch-exp.y: Remove lots of unsupported productions and names.
+ Add support for IF-expressions, ORIF, ANDIF, NUM, and ADDR.
+
+Tue Jun 13 21:40:11 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * parser-defs.h (enum precedence): Added PREC_BUILTIN_FUNCTION.
+ * expression.h (enum exp_opcode): Added UNOP_LOWER, UNOP_UPPER,
+ UNUP_LENGTH.
+ * expprint.c (dump_expression): Handle the new exp_opcodes.
+ (print_subexp): Handle PREC_BUILTIN_FUNCTION.
+ (print_simple_m2_func): Removed.
+ (print_subexp): Remove support for Modula2 builtin functions.
+ * m2-lang.c (m2_op_print_tab): Add support for builtin functions.
+ * ch-exp.y: Parse LOWER, UPPER, and LENGTH builtins.
+ (write_lower_upper_value): Convenience function for LOWER and UPPER.
+ (upper_lower_argument, length_argument): Removed non-terminals.
+ * ch-lang.c (chill_op_print_tab): Entries for UPPER, LOWER, LENGTH.
+ (type_lower_upper): New function. Calculate LOWER/UPPER of type.
+ (value_chill_length): New function. Calcalate LENGTH of ARRAY/STRING.
+ (evaluate_subexp_chill): Handle UNOP_LOWER, UNOP_UPPER, UNOP_LENGTH.
+
+Mon Jun 12 12:48:13 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ Windows support bits from Steve Chamberlain <sac@slash.cygnus.com>.
+ * defs.h: Don't declare strchr and friends if WIN32.
+ (DIRNAME_SEPARATOR): Move here from source.c.
+ (SLASH_P, SLASH_CHAR, SLASH_STRING, ROOTED_P): New macros,
+ symbolic definitions for filename bits.
+ * top.c (cd_command): Use these.
+ * source.c (mod_path, openp): Ditto.
+ * terminal.h: Disable termio/sgtty definitions if WIN32.
+ * findvar.c (registers_changed): Call registers_changed_hook
+ if it is defined.
+
+Mon Jun 12 12:22:05 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * Makefile.in (distclean, realclean): Remove config.cache and
+ config.log.
+
+Mon Jun 12 00:21:59 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * somsolib.c: Include gdb-stabs.h.
+ (som_solib_section_offsets): Use SECT_OFF_XXX rather than 0, 1,
+ etc. Initialize offsets for RODATA & BSS too.
+
+Sat Jun 10 17:59:11 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-tdep.c (frame_chain): Try to compensate for incomplete
+ register information in core files when backtracing.
+
+Fri Jun 9 14:51:38 1995 Stu Grossman (grossman@cygnus.com)
+
+ * remote-nrom.c: Remove everything but download code. More
+ cleanups.
+
+Thu Jun 8 15:06:00 1995 Stu Grossman (grossman@cygnus.com)
+
+ * defs.h maint.c monitor.c remote-mips.c remote.c: Add support
+ for `watchdog' variable. This allows the user to put an upper
+ limit on the amount of time that GDB will wait for the target to
+ return from a step or continue operation. This will primarily be
+ used for the testsuite, where it is difficult to come up with a
+ reasonable timeout for things like function calls, which can take
+ as long as three minutes under some circumstances. If the
+ watchdog timer expires, GDB will generate an error that looks like
+ `Watchdog has expired.', and will detach from the target.
+
+ * remote-mips.c (mips_open): Setup initial frame from target.
+ Print it out so that user is told where the program is stopped
+ when they attach.
+
+ * remote-nrom.c: Loads of cleanups. Use serial code to open
+ network connections. Use expect() to wait for response to
+ download command.
+
+ * ser-tcp.c (tcp_open): Retry connection if we get ECONNREFUSED.
+
+ * serial.c serial.h (serial_open serial_fdopen serial_close):
+ Allow users to open the same device multiple times. They all get
+ to share the same serial_t. This is about the only way to have
+ multiple active targets use the same device (for download and
+ debug).
+
+ * sparcl-tdep.c: Keep #include <unistd.h> away from GO32.
+
+ * target.c: Add `targetdebug' variable. If this is non-zero,
+ then a special target is put at the top of the target stack which
+ will cause all calls through the target vector to have their args
+ and results printed out.
+
+Wed Jun 7 17:40:37 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * ch-exp.y: Handle <primitive_value> "->" <modename>.
+
+Wed Jun 7 17:46:33 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * mem-break.c (LITTLE_BREAKPOINT): If BREAKPOINT and
+ {LITTLE,BIG}_BREAKPOINT are all defined, don't redefine.
+ (BIG_BREAKPOINT): Ditto.
+
+ * config/rs6000/tm-rs6000.h (BREAKPOINT): Define as either
+ BIG_BREAKPOINT or LITTLE_BREAKPOINT depending on the target byte
+ order.
+
+Wed Jun 7 12:41:42 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * somsolib.c (som_solib_section_offsets): Handle relative pathnames.
+
+ * hppa-tdep.c (frame_saved_pc): Handle backtracing through signal
+ handler in dynamically linked executables.
+
+Tue Jun 6 10:44:25 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ From Andrew Cagney <cagney@highland.com.au>
+ * rs6000-tdep.c (single_step): Handle both little and big endian
+ breakpoints.
+ (gdb_print_insn_powerpc): Deal with disassembling both little and
+ big endian PowerPC systems.
+ (_initialize_rs6000_tdep): Use gdb_print_insn_powerpc to handle
+ disassembly, rather that assuming big endian order.
+
+ * config/rs6000/tm-rs6000.h (BREAKPOINT): Delete.
+ (BIG_BREAKPOINT): Define, big endian breakpoint instruction.
+ (LITTLE_BREAKPOINT): Define, little endian breakpoint instruction.
+
+Sat Jun 3 01:54:56 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * README: Add note about Unixware 2.x.
+
+ * dbxread.c (process_one_symbol): Check for exact symbol name
+ match when fixing up N_GSYM and N_STSYM symbols from Sun acc.
+
+ * valprint.c (value_print_array_elements): Use
+ fprintf_filtered to put out `<repeats %u times>',
+ from schwab@issan.informatik.uni-dortmund.de (Andreas Schwab).
+
+ * value.h (struct value): Change `repetitions' field from
+ `short' to `int' type.
+
+Fri Jun 2 11:17:23 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * arc-tdep.c (arc_bfd_mach_type): New static global.
+ (codestream_fill): Handle byte order differences.
+ (setup_prologue_scan): Don't read stdarg function's "sub sp,sp,N".
+ (arc_get_frame_setup): Read it here.
+ (arc_frame_saved_pc): And here.
+ (arc_print_insn): New function.
+ (arc_set_cpu_type): Set arc_bfd_mach_type. Don't set tm_print_insn.
+ (_initialize_arc_tdep): Set tm_print_insn to arc_print_insn.
+
+Wed May 31 12:04:01 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * nlm/{configure.in, Makefile.in}: Converted to use autoconf.
+ * nlm/configure: New file, generated with autoconf 2.3.
+
+ * nlm/configure.in: Use sed instead of awk to get the value of
+ cpufile. Awk is not a utility required by the GNU coding
+ standards. This change also fixes the rigid whitespace
+ requirements that were required for awk.
+
+ * sparclite/aload.c: Use a file descriptor instead of a stdio
+ stream for i/o with target board.
+ Use #error if HAVE_TERMIOS is not defined.
+
+ * sparclite/{Makefile.in, configure.in}: Converted to use
+ autoconf.
+ * sparclite/configure: New file, generated with autoconf 2.3.
+
+Sun May 28 23:10:07 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * defs.h: Include either varargs.h or stdarg.h (for va_list).
+ Fix stupid thinko in last change ("..." -> "va_list").
+
+ * defs.h (vprintf_filtered declaration): Add PARAMS prototype;
+ gcc-2.5 chokes on format attributes for unprototyped functions.
+ (vfprintf_filtered declaration): Likewise.
+ (vprintf_unfiltered declaration): Likewise.
+ (vfprintf_unfiltered). Likewise.
+
+Sat May 27 23:54:17 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * configure.in: Use sed instead of awk to get the values of
+ hostfile, targetfile and nativefile. Awk is not a utility
+ required by the GNU coding standards. This change also
+ fixes the rigid whitespace requirements that were required
+ for awk.
+ * configure: regenerated.
+
+Sat May 27 16:24:04 1995 Angela Marie Thomas <angela@cirdan.cygnus.com>
+
+ * sparclite/{Makefile,configure}.in: Add hooks for building with
+ -lsocket & -lnsl for solaris2. Don't build aload/eload for DOS.
+
+Thu May 25 12:46:37 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbserver/remote-utils.c (prepare_resume_reply): Add FIXME
+ comment regarding signal numbering.
+
+Wed May 24 15:49:47 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * arm-tdep.c (_initialize_arm_tdep): Use print_insn_little_arm
+ now.
+
+ * arm-tdep.c (convert_from_extended, convert_to_extended):
+ New.
+ * coffread.c (enter_linenos): Return if linetab 0.
+ * config/arm/arm.mt (TDEPFILES): Add simulator support.
+ * config/arm/tm-arm.h (FRAME_FIND_SAVED_REGS): Fix prototypes.
+
+Mon May 22 19:37:21 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * config/idt.mt: replace monitor and array-rom with the new
+ remote-array.
+
+Mon May 22 15:38:25 1995 Stu Grossman (grossman@cygnus.com)
+
+ * remote-nindy.c: Install Kung patch for PR 6820. I have no idea
+ what this does...
+
+ * breakpoint.c: Move defaults of watchpoint related macros into
+ target.h.
+ * target.h: Macros from breakpoint.c. Conditionalize based on
+ TARGET_HAS_HARDWARE_WATCHPOINTS.
+ * i386v-nat.c procfs.c: Use TARGET_HAS_HARDWARE_WATCHPOINTS
+ instead of TARGET_CAN_USE_HARDWARE_WATCHPOINT to enable watchpoint
+ code.
+ * config/i386/nm-linux.h, config/mips/nm-irix4.h,
+ config/pa/nm-hppab.h, config/sparc/tm-sparclite.h: #define
+ TARGET_HAS_HARDWARE_WATCHPOINTS to enable watchpoint code.
+
+Mon May 22 06:47:30 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.c, target.h: Move defaults of watchpoint related
+ macros back to breakpoint.c. Required to get GDB compiling
+ on Solaris again.
+
+Fri May 19 14:49:37 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * defs.h (ATTR_FORMAT): New macro, expands to gcc's format
+ attribute when compiled by gcc.
+ * defs.h, language.h, monitor.h: Changed many function
+ declarations to use ATTR_FORMAT.
+
+ * breakpoint.c (delete_command); source.c (directory_command);
+ top.c (define_command): Changed call to query() that had too
+ many arguments.
+ * printcmd.c (address_info): Changed call to printf_filtered()
+ that had too many arguments.
+
+Fri May 19 09:52:07 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infrun.c (wait_for_inferior): Move assignments to stop_signal
+ and stop_pc, and STOPPED_BY_WATCHPOINT code, back where they
+ were--after the switch statement on w.kind. You can't read the
+ registers of an inferior which has exited. Use a goto in the
+ STOPPED_BY_WATCHPOINT code.
+ * infrun.c (wait_for_inferior): Reinstate
+ HAVE_STEPPABLE_WATCHPOINT and HAVE_CONTINUABLE_WATCHPOINT code.
+
+Fri May 19 06:15:40 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * utils.c, complaints.c, language.c, monitor.c, remote-array.c,
+ remote-mips.c, remote-os9k.c, remote-st.c: Conditionalize use of
+ stdarg rather than varargs on ANSI_PROTOTYPES not __STDC__; it
+ must match the definition of PARAMS.
+
+Thu May 18 15:58:46 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * utils.c (fprintf_filtered, fprintf_unfiltered, fprintfi_filtered,
+ printf_filtered, printf_unfiltered, printfi_filtered, query, warning,
+ error, fatal, fatal_dump_core): Use stdarg.h macros when compiling
+ with an ANSI compiler.
+ * complaints.c (complain): Likewise.
+ * language.c (type_error, range_error): Likewise.
+ * monitor.c (monitor_printf, monitor_printf_noecho): Likewise.
+ * remote-array.c (printf_monitor, debuglogs): Likewise.
+ * remote-mips.c (mips_error): Likewise.
+ * remote-os9k.c (printf_monitor): Likewise.
+ * remote-st.c (printf_stdebug): Likewise.
+
+ * defs.h, complaints.h, language.h, monitor.h: Add prototypes to
+ match above changes.
+
+ * printcmd.c: Remove uneeded #include <varargs.h>.
+ * remote-e7000.c: Likewise.
+
+ * f-typeprint.c (f_type_print_base): Fix typo found by above
+ changes.
+
+Wed May 17 11:21:32 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * Makefile.in (xcoffread.o): Depend on partial-stab.h.
+
+ * xcoffsolib.c (sharedlibrary_command): New command.
+ * xcoffsolib.c (solib_info): Call xcoff_relocate_symtab.
+ * xcoffsolib.c: Miscellaneous cleanups.
+
+ * partial-stab.h: Ignore symbol descriptor '-' (for local
+ variables with negative type numbers) without complaint.
+
+ * rs6000-nat.c (vmap_ldinfo): Use bfd_stat rather than our own
+ local emulation thereof. Remove unused variable ostart.
+
+Wed May 17 15:55:53 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * Makefile.in (config.status): changed target so that
+ config.status --recheck is executed if configure script changes.
+
+ * monitor.c (monitor_printf): Changed format specification in
+ error message to work with pre-ansi compilers.
+ (monitor_load_srec): reduced length of s-records from 128 to 32
+ bytes so download is more reliable with the rom68k monitor.
+
+ * rom68k-rom.c: Added trailing space to prompt string.
+
+ * config/i386/xm-i386sco.h (HAVE_STRSTR): Removed.
+ * config/i386/xm-go32.h, mswin/xm.h (SYS_SIGLIST_MISSING):
+ Removed.
+ * defs.h, config/{xm-lynx.h, xm-nbsd.h},
+ config/i386/{xm-i386bsd.h, xm-linux.h},
+ config/m68k/xm-hp300bsd.h, config/mips/xm-irix4.h,
+ config/ns32k/xm-ns32km3.h, doc/gdbint.texinfo
+ (PSIGNAL_IN_SIGNAL_H): Removed.
+
+Tue May 16 13:16:06 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * Makefile.in (Makefile): Added config.status to dependency list.
+
+ * configure.in: Added INIT-CMDS argument to AC_OUTPUT which sets
+ gdb_host_cpu, gdb_target_cpu and nativefile.
+ * configure: regenerated.
+
+Mon May 15 23:50:51 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mdebugread.c (parse_symbol): Do not relocate stBlock/scText
+ symbols, their value is the displacement from the procedure address.
+ * top.c (init_main): Add missing newlines to help strings for
+ `if' and `while' commands, fix help string for `show commands'.
+
+Mon May 15 18:37:56 1995 Stu Grossman (grossman@cygnus.com)
+
+ * breakpoint.c: Move defaults of watchpoint related macros into
+ target.h. Use BP_TEMPFLAG and BP_HARDWAREFLAG instead of
+ constants.
+ * infrun.c (wait_for_inferior): Enhance comment near
+ STOPPED_BY_WATCHPOINT.
+ * target.h: Macros from breakpoint.c.
+
+Mon May 15 17:11:38 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/i386/{i386sol2.mh, i386v4.mh, ncr3000.mh},
+ config/m68k/m68kv4.mh, config/mips/{irix4.mh, irix5.mh,
+ mipsv4.mh}, config/sparc/sun4so2.mh (INSTALL): Removed, figured
+ out by autoconf.
+ * config/apollo68v.mh (RANLIB): Removed, figured out by autoconf.
+
+ * Makefile.in, configure.in: Converted to use autoconf
+ * aclocal.m4: New file, local autoconf macro definitions.
+ * configure: New file, generated with autoconf 2.3.
+
+Mon May 15 14:46:41 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.c (remote_kill): Add prototype.
+ * cpu32bug-rom.c (cpu32bug_open): Properly define as static.
+ * config/h8300/h8300hms.mt (TDEPFILES): Add monitor.o.
+
+Mon May 15 12:12:34 1995 Stu Grossman (grossman@cygnus.com)
+
+ * sparclite/salib.c (win_ovf win_unf): Make window size constant
+ into a variable (__WINSIZE) so that it can be controlled via the
+ .h file.
+ * sparclite/sparclite.h: Add SL933 #ifdef to set __WINSIZE to 6
+ for the 933 board.
+
+ * infrun.c: Add #ifdef HP_OS_BUG to all references to
+ trap_expected_after_continue.
+ * (wait_for_inferior): Fix for remote watchpoints. Don't try to
+ insert breakpoints while target is running (this only works on
+ *some* native targets). This may also speed up native watchpoints
+ considerably.
+
+Sat May 13 13:55:04 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dwarfread.c (struct dwfinfo), dbxread.c (struct symloc),
+ mdebugread.c (struct symloc), hpread.c (struct symloc),
+ xcoffread.c (struct symloc): Fix inaccurate comment introduced
+ 20 Apr 1995.
+
+Sat May 13 13:34:18 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * rs6000-tdep.c (find_toc_address): Revise comment.
+ * symfile.c, symfile.h (init_psymbol_list): New function;
+ consolidate duplicated copies from os9kread.c, dbxread.c
+ and dwarfread.c.
+ * defs.h: Declare info_verbose.
+ * xcoffread.c: Extensive changes to support psymtabs.
+
+Fri May 12 13:48:41 1995 Stu Grossman (grossman@andros.cygnus.com)
+
+ * cpu32bug-rom.c remote-est.c rom68k-rom.c: Update line_term element.
+
+Fri May 12 06:39:30 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * partial-stab.h: Expand comments.
+
+Thu May 11 19:01:37 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * Support debugging using native MACH primitives on hppa*-*-osf*.
+ * configure.in: hppa*-*-osf* != hppa*-*-bsd* anymore.
+ * config/pa/hppaosf.mh: New file.
+ * config/pa/nm-hppao.h: Likewise.
+ * hppam3-nat.c: Likewise.
+ * config/pa/tm-hppao.h (PSW_SS): Define for single-stepping.
+ (MACHINE_CPROC_*_OFFSET): Define.
+ (TRACE_*): Define.
+ (START_INFERIOR_TRAPS_EXPECTED): Delete definition.
+
+Wed May 10 18:59:26 1995 Stu Grossman (grossman@andros.cygnus.com)
+
+ * hppa-tdep.c (read_unwind_info): Cosmetic cleanup.
+ * (unwind_command): Clean it up and make it print things out
+ nicer.
+ * monitor.c: Add ^C handling capability (mostly ripped off from
+ remote.c).
+ * (monitor_printf): Make it check the command echo.
+ * (monitor_printf_noecho): Similar to above, but doesn't check
+ for echo.
+ * (monitor_stop): No longer waits for prompt. That is the job of
+ the caller. This makes things work much better for monitor_wait,
+ which waits for the prompt itself.
+ * (monitor_open): Deal with new monitor_stop semantics. Also,
+ flush input after sending init strings to get rid of junk that may
+ be output. Also, don't always send \r to remote. Use
+ monitor_ops->line_term cuz proper character isn't always \r.
+ * (monitor_fetch_register): Switch to completely different
+ algorithm to deal with lame-ass monitors which put spaces in the
+ middle of numbers, and prompt with a space!!!!!
+ * (monitor_read_memory_single): New routine to be used with
+ monitors that can only return one byte/short/long at a time. This
+ is selected via MO_GETMEM_READ_SINGLE.
+ * (monitor_load_srec): Use monitor_printf_noecho for sending S
+ records. Most targets don't echo them.
+ * (monitor.h): Get rid of cmd_delim. Add line_delim.
+ * op50n-rom.c (op50n_cmds): Fill it up. Make it work.
+ * w89k-rom.c: Change all eols from \r to \n. Change load_resp to
+ ^Q to prevent error message.
+ * config/pa/tm-hppa.h (CALL_DUMMY (for hppro)): Add special
+ instruction sequence at end to make restore_pc_queue happy.
+
+Wed May 10 15:59:00 1995 Torbjorn Granlund <tege@adder.cygnus.com>
+
+ * remote-est.c (est_open): Make static to match prototype.
+
+Tue May 9 16:58:50 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in: Add little endian PowerPC support.
+ * config/powerpc/ppcle-eabi.mt: New file for little endian PowerPC
+ support.
+ * config/powerpc/tm-ppcle-eabi.h: ditto.
+
+Mon May 8 12:11:38 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * nlm/configure.in (gdb_host, gdb_host_cpu, gdb_target): Removed.
+ These variables not used.
+
+ * config/m68k/monitor.mt (TDEPFILES): Added cpu32bug-rom.o.
+
+Wed May 3 17:54:47 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * monitor.c (monitor_command): Don't use PROMPT until monitor
+ target is known to be open.
+ (monitor_make_srec): Don't define size of hextab.
+
+Tue May 2 18:32:24 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.in (--enable-netrom): New configuration option.
+ * Makefile.in (REMOTE_OBS): Rename from REMOTE_O, append
+ value of NETROM_OBS.
+ (NETROM_OBS): New variable.
+ * remote-nrom.c: New file, NetROM target support.
+ * config/a29k/a29k-udi.mt, config/i960/vxworks960.mt: Use
+ REMOTE_OBS instead of REMOTE_O.
+ * config/arc/arc.mt: Ditto.
+
+Fri Apr 28 23:30:00 1995 Stu Grossman (grossman@cygnus.com)
+
+ * array-rom.c (_initialize_array array_open): Move baud_rate
+ initialization from _initxxx to array_open to fix bug with
+ overriding -b command line option.
+
+Thu Apr 27 20:29:34 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (RUNTEST): Fix reference of `srcdir'.
+
+Wed Apr 26 19:01:08 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * remote-hms.c: Rewrite to use new monitor conventions.
+
+Tue Apr 25 11:27:14 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dbxread.c: Add comment explaining lowest_text_address.
+ Add comment regarding stringtab_global and psymtabs.
+
+Sat Apr 22 01:26:29 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/pa/tm-hppa.h (EXTRACT_STRUCT_VALUE_ADDRESS): Fix.
+
+ * config/pa/tm-hppa.h (EXTRACT_RETURN_VALUE): Rewrite to correctly
+ handle "short", "int" and small structures returned in registers.
+
+Fri Apr 21 12:57:53 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * minsyms.c: add new function lookup_minimal_symbol_text, to look
+ for text symbol only.
+ * breakpoint.c (create_longjmp_breakpoint): call
+ lookup_minimal_symbol_text instead of lookup_minimal_symbol.
+ * symtab.h: add lookup_minimal_symbol_text prototype.
+
+Fri Apr 21 12:03:44 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * sh-tdep.c (sh-opc.h): Don't include.
+ (gdbcore.h): Include.
+ (frame_find_saved_regs): Remove unused local.
+
+Thu Apr 20 10:12:21 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dwarfread.c (struct dwfinfo), dbxread.c (struct symloc),
+ mdebugread.c (struct symloc), hpread.c (struct symloc): Clean
+ up comments.
+
+Wed Apr 19 16:58:11 1995 Stu Grossman (grossman@andros.cygnus.com)
+
+ * hppa-tdep.c (deposit_17): New routine to deposit 17 bit
+ constants into PA instructions.
+ * Put #ifdefs around all signal handling code. Not generally
+ needed for embedded boards.
+ * (hppa_fix_call_dummy): Parameterize offsets into call dummy to
+ allow different dummys to be used by this code. Use
+ INSTRUCTION_SIZE instead of REGISTER_SIZE for things.
+ Conditionalize setup of _sr4export fixup. Improve comments.
+ * config/pa/tm-hppa.h: Define INSTRUCTION_SIZE. Use a different
+ call dummy if PA_LEVEL_0 is defined. Better comments for call
+ dummys. Define offsets for LDIL/LDO instructions which load
+ function addresses.
+ * config/pa/tm-pro.h: Get rid of signal handling stuff. Define
+ PA_LEVEL_0 to disable mucking with space regs and such.
+
+Mon Apr 17 15:37:08 1995 Stu Grossman (grossman@andros.cygnus.com)
+
+ * cpu32bug-rom.c monitor.h op50-rom.c remote-est.c rom68k-rom.c
+ w89k-rom.c: Remove loadtypes, loadprotos and baudrates.
+ * op50-rom.c: Fix copyrights and add load routine to op50n_cmds.
+ * rom68k-rom.c (_initialize_rom68k): Don't set baud rate.
+ * w89k-rom.c: Fix copyrights.
+
+Sun Apr 16 14:00:55 1995 Stu Grossman (grossman@andros.cygnus.com)
+
+ * monitor.c: Move all xmodem stuff into xmodem.[ch]. Remove
+ unnecessary remoteloadprotocol and remoteloadtype support.
+ * (expect expect_prompt): Change names to monitor_expect and
+ monitor_expect_prompt. Make them global.
+ * (printf_monitor): Change name to monitor_printf. Make global.
+ * (monitor_read_memory): Flush command echo to avoid parsing
+ ambiguity with CPU32Bug monitor.
+ * (monitor_load): Remove remoteloadprotocol and remoteloadtype
+ support. Call target_ops->load_routine, default to
+ monitor_load_srec.
+ * (monitor_load_srec): Remove everything but S-record support.
+ * monitor.h (monitor_ops): Add load_routine to provide monitor
+ specific download capability.
+ * remote-est.c: Clean up copyrights and comments.
+ * w89k-rom.c: Use new xmodem support.
+ * xmodem.c xmodem.h: New files to support xmodem downloads.
+ * rom68k-rom.c remote-est.c: Fix copyrights, add load_routine
+ entry to monitor_ops.
+ * cpu32bug-rom.c: New file to support Moto BCC debuggers.
+ * config/m68k/est.mt (TDEPFILES): Add cpu32bug.o.
+ * config/pa/hppapro.mt (TDEPFILES): Add xmodem.o.
+
+Sat Apr 15 18:00:15 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * rem-multi.shar: Removed; superceded by gdbserver.
+
+Fri Apr 14 12:10:24 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * xcoffread.c (xcoff_sym_fns): Revise comment about merging this
+ with coffread.c.
+
+ * breakpoint.c (fixup_breakpoints): Removed.
+ * rs6000-nat.c (vmap_symtab): Don't call fixup_breakpoints.
+ (vmap_ldinfo, xcoff_relocate_core): Call breakpoint_re_set.
+
+ * coffread.c (coff_symfile_offsets): Allocate SECT_OFF_MAX
+ sections, not just SECT_OFF_MAX-1.
+
+ * rs6000-nat.c (vmap_symtab), xcoffread.c: Re-do section offsets
+ to be indexed by SECT_OFF_* instead of xcoff section numbers.
+ * objfiles.c, remote.c: Remove comments regarding SECT_OFF_*.
+ * symtab.h: Revise comment about block_line_section.
+ * rs6000-nat.c (vmap_symtab): Don't relocate objfile->sections.
+
+Sat Apr 15 14:15:14 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.in (init.c): Don't try to do symbolic {o} in sed
+ command, not allowed by some version of MPW Make.
+ * ser-mac.c (mac-setbaudrate): Make it actually set baud rates.
+
+Sat Apr 15 14:05:09 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * alpha-tdep.c (alpha_push_arguments): Fix typo (TYPE_VALUE ->
+ VALUE_TYPE). Do the cast for TYPE_CODE_BOOL, TYPE_CODE_CHAR,
+ TYPE_CODE_ENUM, and TYPE_CODE_RANGE as well as TYPE_CODE_INT.
+
+Sat Apr 15 14:04:32 1995 Per Bothner <bothner@cygnus.com>
+
+ * alpha-tdep.c (alpha_push_arguments): Only cast to long for
+ TYPE_CODE_INT.
+
+
+Thu Apr 13 16:17:04 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * remote-array.c: New file for Array Tech LSI33k based controller
+ board.
+
+Thu Apr 13 12:23:31 1995 Kung Hsu <kung@rtl.cygnus.com>
+
+ * a29k-tdep.c (get_longjmp_target): Replace SWAP_TARGET_AND_HOST with
+ extract_address.
+ * remote-vxsparc.c: New file, preliminary check in, this configuration
+ not supported yet.
+ * remote-vxmips.c: ditto.
+
+Thu Apr 13 12:10:14 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * rs6000-tdep.c (xcoff_add_toc_to_loadinfo): Don't use a prototype
+ to declare the function.
+
+Wed Apr 12 16:40:20 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * monitor.h (init_monitor_ops): Declare.
+ * rom68k-rom.c: Clarify some comments.
+ (rom68k_open): Define as static, to match decl.
+
+Wed Apr 12 16:36:44 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.gdb: New file.
+ * .gdbinit: Move list-objfiles to gdb.gdb.
+
+ * values.c (set_internalvar): Set modifiable flag of newval.
+
+Wed Apr 12 14:34:31 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * xcoffread.c: Call complain() rather than error() or printing a
+ warning.
+
+Wed Apr 12 08:15:27 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * arc-tdep.c: #include "gdbcmd.h".
+ (codestream_seek): Pass CORE_ADDR.
+ (arc_cpu_type, tmp_arc_cpu_type, arc_cpu_type_table): New globals.
+ (debug_pipeline_p): Likewise.
+ (X_...): Instruction field access macros.
+ (BUILD_INSN): Define.
+ (codestream_tell): Allow for stream elements > 1 byte.
+ (codestream_fill): Likewise.
+ (setup_prologue_scan): New function.
+ (arc_get_frame_setup): Call it. Update to current spec
+ regarding prologues. Use BUILD_INSN.
+ (skip_prologue): New argument `frameless_p'. Use BUILD_INSN.
+ (arc_frame_saved_pc): New function.
+ (frame_find_saved_regs): Use BUILD_INSN.
+ (get_insn_type, single_step): New functions.
+ (one_stepped): New global.
+ (arc_set_cpu_type_command, arc_show_cpu_type_command): New functions.
+ (arc_set_cpu_type): New function.
+ (_initialize_arc_tdep): Define new `set' commands `cpu',
+ `displaypipeline', and `debugpipeline'.
+ * arc/tm-arc.h (TARGET_BYTE_ORDER): Delete.
+ (TARGET_BYTE_ORDER_SELECTABLE): Define.
+ (DEFAULT_ARC_CPU_TYPE): Define.
+ (SKIP_PROLOGUE_FRAMELESS_P): Define.
+ (BREAKPOINT): Delete.
+ (BIG_BREAKPOINT, LITTLE_BREAKPOINT): Define.
+ (DECR_PC_AFTER_BREAK): Change to 8.
+ (NO_SINGLE_STEP): Define.
+ (ARC_PC_TO_REAL_ADDRESS): Define.
+ (SAVED_PC_AFTER_CALL): Use it.
+ (NUM_REGS, REGISTER_BYTES): Fix.
+ (FRAME_SAVED_PC): Call arc_frame_saved_pc.
+ (FRAME_LOCALS_ADDRESS): Fix.
+
+Tue Apr 11 16:42:37 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * top.c, utils.c, defs.h: Remove error_hook. It is currently
+ unused and would need to hook into error_begin()/return_to_top_level(),
+ instead of error(), if it were to be used.
+
+Tue Apr 11 13:46:25 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * utils.c, defs.h (warning_begin): Renamed from warning_setup, for
+ consistency with error_begin. Also print warning_pre_print.
+ Document it better.
+ * utils.c (warning): Use it.
+ * utils.c (error_begin): Doc fix.
+ * rs6000-nat.c (vmap_ldinfo): If we don't find ldinfo for the
+ symfile_objfile, nuke it.
+
+Tue Apr 11 09:35:20 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * printcmd.c (print_address_numeric): Pass use_local to
+ print_longest, rather than always passing 1.
+
+ * nlm/Makefile.in: Remove comments discussing munch.
+
+
+Mon Apr 10 18:31:57 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ Merge in support for Mac MPW as a host.
+ (Old change descriptions retained for informational value.)
+
+ * mpw-config.in (i386-unknown-go32): Change from aout.
+ (sh-hitachi-hms): New target.
+ * mpw-make.in (BISON): Use byacc instead of bison.
+ (VERSION): Bump to 4.14.1.
+ (*-pinsn.*): Remove mentions everywhere.
+ (all): Don't build MacGDB.
+ (gdb, SiowGDB): Depend on Version.r.
+ (Version.r): Generate from version info.
+ * main.c (main): Pass program name to START_PROGRESS, END_PROGRESS.
+ (main) [MPW]: Remove debugging hook.
+ * mac-xdep.c (debug_openp): New flag.
+ (mac_init): Set flag if env variable defined.
+ * ser-mac.c (mac_open): Clarify error message.
+ (mac_readchar): Call PROGRESS while looping.
+ (mac_write): Call sleep instead of sec_sleep.
+ (sec_sleep): Remove.
+ * source.c (openp) [MPW]: Only print debugging info if debugging.
+ * utils.c (query) [MPW]: Clarify that behavior is a bug.
+
+ * mpw-make.in (init.c): Use open-brace instead of mpw-open-brace.
+
+ * main.c, source.c: Remove hacks that replace long strings
+ with shorter ones, now solved portably.
+
+ * config/m68k/xm-mpw.h (spin.h): Include.
+ (ALMOST_STDC): Only define if MPW_C.
+ * config/m68k/tm-mac.h: New file, Mac target definitions.
+
+ * mpw-config.in (m68k-apple-macos, ppc-apple-macos,
+ i386-unknown-aout): New targets.
+ (mk.tmp): Add *DEPFILES definitions.
+ * mpw-make.in: Remove gC rules, clean up definitions for other
+ include files, bump version, fix bogus \ that should be \Option-d.
+ (init.c): Build correctly.
+
+ * mpw-make.in (HFILES_NO_SRCDIR): Add somsolib.h
+ (ALLDEPFILES): Add somsolib.c.
+ (somsolib.o): Add some dependencies.
+
+ * mpw-config.in: Use nm-empty.h if host is not target.
+ (xdepfiles): Add mac-xdep.c.o.
+ (xm_file): Remove.
+ * mpw-make.in: Add Fortran files.
+ (XDEPFILES): Remove.
+
+ * mpw-config.in (MacSerial.h): Duplicate from standard Serial.h.
+ * ser-mac.c (MacSerial.h): Include instead of Serial.h.
+
+ * mpw-make.in: Use {s} instead of {srcdir} everywhere.
+ (bindir, libdir): Remove extra colon.
+ (source.c): Compile with C instead of gC.
+ (c-exp.tab.c, ch-exp.tab.c, m2-exp.tab.c): Add {o}.
+ (install-only): Don't install MacGDB.
+ * source.c (openp) [MPW]: Add a debugging display.
+ (open_source_file) [MPW]: Use MPW basename finders.
+ [MPW_C]: Briefer versions of help for line and list commands.
+
+ * mpw-make.in: Change references from paread.c to somread.c
+
+ * mpw-make.in (VERSION): Update to 4.12.3.
+ (SiowGDB): New target, GDB using SIOW library.
+ (init-new.c): New target, attempt to generate init.c from sources.
+ (main.c.o, top.c.o): Put each in its own segment.
+ * main.c (main) [MPW]: Always call mac_init.
+ * utils.c (query) [MPW]: Always return "yes" if in MacGDB, output
+ an extra newline otherwise.
+ * mac-xdep.c: More comments in various places, remove junk.
+ (mac_init): Add tests for MPW and SIOW.
+ (use_wne, has_color_qd): Renamed.
+ (use_color_qd): New variable.
+ (grow_window): Only do console resizing to console window,
+ call resize_console_window.
+ (zoom_window): Call resize_console_window.
+ (resize_console_window, scroll_text): New functions.
+ (adjust_console_sizes): Always align viewrect to even multiples of
+ text lines.
+ (adjust_console_text): Always scroll by whole lines.
+ (hacked_vfprintf, hacked_puts, hacked_fputc, hacked_putc): Force a
+ recalculation of scroll positions if a newline was output.
+ (hacked_fflush): Similarly, for flushing.
+ (hacked_fgetc): New function, aborts if called in MacGDB.
+ * ser-mac.c (mac_readchar): Rename starttime to start_time,
+ remove debugging printf.
+ (mac_write): Sleep on first 4 writes.
+ (sec_sleep): New function, works like standard sleep.
+ * macgdb.r: Adjust positioning and contents of About box.
+ Set minimum size to 2000K, preferred size to 5000K.
+ * config/m68k/xm-mpw.h (fgetc): Define as a macro.
+
+ * mpw-make.in (.c.o, .gc.o): Prefix segment names with gdb_.
+ (top.c.o, annotate.c.o): Add build rules.
+ * macgdb.r (SysTypes.r): Include.
+ ('vers'): New resource, version info.
+ (mFile, mEdit, mDebug): Enable all menu items.
+ (mDebug): Add key equivalents for continue, step, next.
+ (wConsole): Add zoom and close boxes to window.
+ * mac-xdep.c (new_console_window): New function, code taken from
+ mac_init.
+ (mac_command_loop): Use GetCaretTime for wait interval, call
+ do_idle on null events.
+ (do_idle): New function.
+ (zoom_window): Implement zooming.
+ (v_scroll_proc): New function, handles vertical scrolling.
+ (activate_window): Do activation of console window.
+ (do_menu_command): Implement items of file, edit, and debug menus.
+ (do_keyboard_command): Fix command extraction.
+ (adjust_console_sizes, adjust_console_text): New functions.
+ (hacked_fprintf, hacked_vfprintf, hacked_fputs, hacked_fputc,
+ hacked_putc): Don't call draw_console.
+ * ser-mac.c (mac_open): Add an error message for invalid ports.
+ (first_mac_write): New global.
+ (mac_write): Use first_mac_write to sleep on first several writes.
+
+ * mpw-make.in (INCLUDE_CFLAGS): Add readline source dir.
+ (READLINE_CFLAGS, READLINE_SRC, READLINE_DIR): Uncomment.
+ (TSOBS): Don't compile inflow.c.
+ (all, install): Add MacGDB.
+ * main.c (main): Do Mac-specific init and command loop if a
+ standalone app, skip full option help message if compiling
+ with MPW C.
+ (gdb_readline): If MPW, add a newline after the (gdb) prompt.
+ * utils.c (_initialize_utils): If MPW, don't try to use termcap to
+ compute the window size.
+ * config/m68k/xm-mpw.h (printf, fprintf, fputs, fputc, putc,
+ fflush): Define as macros that expand into hacked_... versions.
+ (StandAlone, mac_app): Declare.
+ * macgdb.r (SIZE): Set the default partition to 4000K.
+ * mac-xdep.c (readline.h, history.h): Include.
+ (terminal.h): Don't include.
+ (mac_app): Define.
+ (gdb_has_a_terminal): Define Mac-specific version.
+ (do_keyboard_command): Simplify search for command string.
+ (readline): Define as gdb_readline.
+ Add other history/readline stubs to make main gdb link.
+ (hacked_fprintf, hacked_printf, hacked_vfprintf, hacked_fputs,
+ hacked_fputc, hacked_fflush): New functions, intercept output to
+ stdout and stderr, send to console window.
+
+ * mpw-make.in (MacGDB): New target, standalone Mac-hosted gdb.
+ (XDEPFILES): Define.
+ (main.c.o): Compile with gC instead of C.
+ * mac-defs.h: New file, menu etc definitions shared between
+ C and Rez files.
+ * macgdb.r: New file, Rez (resource compiler) resource
+ definitions.
+ * mac-xdep.c: New file, Mac host interface code.
+ * config/m68k/xm-mpw.h (PATHNAME_SEPARATOR): Rename to
+ DIRNAME_SEPARATOR.
+ (PATHNAME_SEPARATOR_STRING): Remove.
+ (SIGQUIT, SIGHUP): Define.
+ (fileno, R_OK): Define.
+
+ * mpw-config.in: New file, MPW configuration fragment.
+ * mpw-make.in: New file, MPW makefile fragment.
+ * config/m68k/xm-mpw.h: New file, MPW host definitions.
+ * ser-mac.c: New file, Mac serial interface.
+
+Mon Apr 10 16:47:57 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * valprint.c (print_longest): Fix a syntax error in #ifdef
+ PRINTF_HAS_LONG_LONG.
+
+ * config/mips/xm-irix5.h: turn on CC_HAS_LONG_LONG and
+ PRINTF_HAS_LONG_LONG.
+ * config/mips/tm-irix5.h: turn on FORCE_LONG_LONG.
+
+Sat Apr 8 02:47:45 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mdebugread.c (parse_symbol): Use new variable
+ nodebug_var_symbol_type as type of variables which don't have any
+ ecoff debug info associated with them.
+ (parse_symbol, parse_procedure): Use heuristics to determine if
+ functions were compiled without debugging info and change their
+ type to nodebug_function_symbol_type.
+ (_initialize_mdebugread): Initialize nodebug_*_symbol_type.
+
+ * source.c (line_info): Clear sal.pc for `info line' without
+ arguments.
+
+Fri Apr 7 17:43:01 1995 Stu Grossman (grossman@andros.cygnus.com)
+
+ * monitor.c: make_xmodem_packet and print_xmodem_packet go away.
+ send_xmodem_packet shows up to do the obvious. Lots of fixes to
+ xmodem downloads including resetting of block number at start of
+ new transfers, fix for buffer overrun problem, addition of CRC
+ generation code.
+ * (monitor_open): loadtype_str and loadproto_str now default to
+ first entry in monitor_ops->loadtypes.
+ * (monitor_wait): Lengthen register dump buf, because of verbose
+ Winbond monitor.
+ * (monitor_fetch_register): Report unimplemented registers as 0.
+ * (monitor_read_memory): Only do 16 byte aligned transfers
+ because of formatting weirdness with the Winbond monitor. Also,
+ ignore non-hex, non-whitespace formatting between bytes (same
+ monitor).
+ * (monitor_load): Clean up logic.
+ * (monitor_load_srec): Re-do xmodem support. Move lots of it
+ into send_xmodem_packet.
+ * (getacknak): Get rid of polls and timeouts. Handle CRC
+ requests from receiver.
+ * (monitor_make_srec): Efficiency improvements. Don't call
+ sprintf to output two digit hex numbers.
+ * (crcinit, docrc): New, CRC-16 support routines.
+ * (send_xmodem_packet): New routine to generate either CRC-16 or
+ checksummed xmodem packets.
+
+ * remote-est.c (est_loadtypes), rom68k-rom.c (rom68k_loadtypes):
+ Reduce tables down to only the load types supported by each
+ monitor.
+
+ * w89k-rom.c (w89k_supply_register): Parses output of Winbond
+ register dumps.
+ * (w89k_loadtypes, w89k_loadprotos): Reduce to just srec/xmodem.
+ * (w89k_cmds): Add clear all breakpoints, memory fill, and dump
+ registers commands.
+
+ * config/pa/tm-hppa.h: Define lots register offsets needed by
+ w89k-rom.c.
+
+
+Thu Apr 6 17:00:46 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * Makefile.in (X11_INCLUDES): Define as empty.
+ (X11_CFLAGS): Define as including $(X11_INCLUDES).
+ (X11_LIB_SWITCHES): Define as empty.
+ (X11_LIBS): Define as -lX11.
+
+
+Wed Apr 5 19:57:38 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * mips-tdep.c (mips_print_register): Remove unused variable
+ our_type and call to init_type. Fixes memory leak. Reindent function.
+
+ * mips-tdep.c (mips_print_register), findvar.c
+ (write_register_bytes): Make buffer char[] instead of unsigned
+ char[].
+
+Mon Apr 3 19:28:14 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * top.c, utils.c, main.c, defs.h: Replace error_pre_print with two
+ variables: error_pre_print (for RETURN_ERROR) and quit_pre_print
+ (for RETURN_QUIT). Fixes a bug whereby typing ^C (e.g. in "maint
+ print sym") could output extraneous stuff.
+ * objfiles.c: Don't declare error_pre_print; defs.h does it.
+
+Mon Apr 3 13:48:28 1995 Stu Grossman (grossman@andros.cygnus.com)
+
+ * monitor.h: Add MO_GETMEM_NEEDS_RANGE flag.
+ * monitor.c (monitor_read_memory): Use previously mentioned flag
+ to send proper format memory examine commands to the w89k monitor.
+ Also, try to handle bizarre format of memory dump...
+
+ * op50-rom.c w89k-rom.c: Update to new monitor.[ch] conventions.
+
+Sat Apr 1 03:22:20 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dbxread.c (process_one_symbol) [SOFUN_ADDRESS_MAYBE_MISSING]:
+ Handle relocated symbol address.
+ * partial-stab.h, case N_SO, SOFUN_ADDRESS_MAYBE_MISSING:
+ Do not relocate a zero address.
+
+Thu Mar 30 19:46:36 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/a29k/tm-a29k.h: Nuke obsolete define CONTROL_END_ADDR; it
+ is nowhere used.
+
+ * stabsread.c (read_range_type): Remove FIXME comment about
+ type-id (I presume this meant a number followed by = followed by a
+ type) versus type number; Per fixed it.
+
+Wed Mar 29 09:56:04 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in: sparc-*-sunos5* is same as sparc-*-solaris2*.
+
+Wed Mar 29 18:30:03 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-e7000.c (why_stop): Add new kinds of strings to expect
+ from the emulator.
+ (e7000_wait): Add interpretations for more stop reasons,
+ including warnings for write protect and cycle address errors.
+
+Wed Mar 29 17:09:29 1995 Stu Grossman (grossman@cygnus.com)
+
+ * monitor.c monitor.h remote-est.c rom68k-rom.c: Add start of
+ support for interrupting target.
+ * monitor.c (monitor_open): Send stop command before doing
+ anything else.
+ * (monitor_load_srec): Fix record size calculation to prevent end
+ of segment from getting trashed.
+ * rom68k-rom.c: Update to latest version of struct monitor_ops.
+ * config/sparc/tm-sparc.h (FIX_CALL_DUMMY): Fix byte-order
+ problems. Makes DOS hosted function calling work.
+ * sparclite/crt0.s: Define _start to make COFF happy.
+
+Wed Mar 29 09:11:51 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * defs.h (atof): Don't provide an external declaration if atof is
+ a macro.
+
+Wed Mar 29 00:01:07 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * rs6000-tdep.c (skip_prologue): Skip saving of LR and CR in
+ the stack frame, fix typos in `st rx,NUM(r1)' and `stu r1,NUM(r1)'
+ tests.
+
+Tue Mar 28 17:04:04 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * gdbtypes.c (create_range_type): If indextype has TYPE_FLAG_STUB
+ set, set TYPE_FLAG_TARGET_STUB.
+ (check_stub_type): Recalculate TYPE_LENGTH for range type.
+ * stabsread.c (read_range_type): If index type number is followed
+ by '=', back up, call read_type. and assume we have a true range.
+ * gdbtypes.h (TYPE_FLAG_TARGET_STUB): Update comment.
+
+Mon Mar 27 22:51:54 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * alpha-nat.c, irix4-nat.c, irix5-nat.c, mipsv4-nat.c,
+ sparc-tdep.c (supply_gregset, supply_fpregset): Fill inaccessible
+ registers with zero to handle recent read_register_bytes change.
+ * irix4-nat.c, irix5-nat.c, mipsv4-nat.c (supply_gregset,
+ fill_gregset): Fix handling of CAUSE_REGNUM.
+ * mips-nat.c (store_inferior_registers): Handle unwritable
+ registers when storing a single register.
+ * config/mips/tm-irix3.h (CAUSE_REGNUM, BADVADDR_REGNUM):
+ Fix definitions.
+
+ * mdebugread.c (parse_symbol, psymtab_to_symtab_1): Clear
+ allocated mips_extra_func_info, if the debug info is corrupt,
+ the PDR to fill it in might be missing.
+
+Mon Mar 27 14:43:00 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * vx-share/regPacket.h: a new file interfacing with vxworks.
+
+Sun Mar 26 13:22:47 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.c (bpstat_do_actions): Once we've executed the
+ commands, set bs->commands to NULL.
+
+Sat Mar 25 01:16:10 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * buildsym.c (patch_subfile_name): Update last_source_file
+ with the real source file name.
+ * dbxread.c (end_psymtab): Handle static functions in the
+ SOFUN_ADDRESS_MAYBE_MISSING case by passing pst->filename
+ to lookup_minimal_symbol.
+ (process_one_symbol): Ignore extra outermost context from
+ SunPRO cc and acc.
+ * stabsread.c (define_symbol): Do not complain for SunPRO
+ static variable encoding if STATIC_TRANSFORM_NAME is defined.
+ * sparc-tdep.c, config/sparc/tm-sun4sol2.h
+ (sunpro_static_transform_name): Renamed from
+ solaris_static_transform_name.
+ * config/sparc/tm-sun4os4.h (STATIC_TRANSFORM_NAME):
+ Define to sunpro_static_transform_name for acc 3.0 compiled
+ executables.
+ * procfs.c, config/alpha/nm-osf2.h (PROCFS_DONT_TRACE_FAULTS):
+ Renamed from PROCFS_DONT_TRACE_IFAULT, don't trace any faults
+ if defined.
+ * procfs.c (info_proc_siginfo): Cast sip->si_addr to
+ `unsigned long' and use `lx' format for printing it.
+
+Fri Mar 24 15:45:42 1995 Stu Grossman (grossman@cygnus.com)
+
+ * configure.in: Move test for m68*-est-* before m68*-*-coff*.
+ * findvar.c: Move default def of CANNOT_STORE_REGISTER closer to
+ the beginning of the code.
+ * (write_register_gen): New routine. Analogous to
+ read_register_gen.
+ * (write_register_bytes): Another rewrite! Make it smarter about
+ not updating regs with the same value.
+ * monitor.c (printf_monitor readchar): Use stderr instead of
+ stdout to output debug info. Also cleanup readchar a little.
+ * (expect): Make sure that excessive responses are null
+ terminated.
+ * (monitor_open): Check for magic number in monitor_ops struct.
+ Allow multiple commands as init strings. Also, clear all
+ breakpoints.
+ * (monitor_resume monitor_wait): Send a command to dump all the
+ regs for those targets which don't do so when waking up after a
+ continue command.
+ * (monitor_wait): Handle excessive response output better.
+ * (monitor_write_memory): Use block fill, word, and long word
+ commands (if they exist) to write memory more efficiently.
+ * General cleanups to use flag bits instead of individual flag
+ words in monitor_ops struct.
+ * (monitor_command): Return output from command.
+ * (monitor_load_srec): Allocate buffer only once. Use alloca.
+ Wait for load response string instead of using a timeout to start
+ sending S-records. Fix bug where value of srec_frame shrinks. If
+ hashmark is set, print `-' for retransmissions. General cleanups.
+ * (monitor_make_srec): Get rid of S-record default type kludge.
+ * monitor.h: Use seperate struct for memory and register
+ read/write commands. Memory commands can come in byte, word,
+ long, and longlong forms.
+ * (monitor_ops): Change lots of fields. Generalize some stuff.
+ Put all flags into flags word. Allow init to be a list of commands.
+ Add command for clearing all breakpoints, block fill, dumping all
+ registers.
+ * remote-est.c: Rewrite to use new monitor conventions.
+ * config/m68k/est.mt (TDEPFILES): Add monitor.o.
+ * config/m68k/tm-est.h: Set NUM_REGS to 18.
+ * testsuite/gdb.base/break.exp: Lots of cleanups. Use gdb_test
+ more thoroughly.
+
+Thu Mar 23 23:20:00 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * somsolib.c (som_solib_add): Handle case where a shared library
+ referenced by a core file has sections without the SEC_ALLOC bit
+ set (eg stabs sections).
+
+Thu Mar 23 15:07:08 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * breakpoint.c (bpstat_do_actions): For each element in the bpstat
+ chain, do all the commands regardless of whether they run the
+ inferior.
+
+Wed Mar 22 19:17:06 1995 Doug Evans <dje@cygnus.com>
+
+ * mem-break.c (LITTLE_BREAKPOINT, BIG_BREAKPOINT): Define as
+ BREAKPOINT if mono-endian.
+ (break_insn): Deleted.
+ (big_break_insn, little_break_insn): Define.
+ (memory_insert_breakpoint): Handle bi-endian cpus.
+ (BREAKPOINT_LEN): Define.
+ (memory_remove_breakpoint): Use it.
+ (memory_breakpoint_size): Likewise.
+
+Tue Mar 21 17:03:17 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * sparc-stub.c: add nop after 'bg good_wim'.
+ * sparcl-stub.c: ditto.
+
+Tue Mar 21 13:34:12 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infrun.c (handle_command): Don't print TARGET_SIGNAL_0,
+ TARGET_SIGNAL_UNKNOWN, or TARGET_SIGNAL_DEFAULT.
+
+Mon Mar 20 10:09:59 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppab-nat.c (store_inferior_registers): Sync with HPUX version.
+
+Mon Mar 20 07:34:48 1995 Stu Grossman (grossman@cygnus.com)
+
+ * hppah-nat.c (store_inferior_registers): Move check for
+ CANNOT_STORE_REGISTER to a better place. Fixes ptrace I/O errors
+ found by test suite during function calls, which attempts to write
+ unwritable registers.
+
+Sat Mar 18 02:02:24 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mdebugread.c (parse_symbol): If finishing a function without
+ known parameter type info, set that from parameter symbols.
+ Remove commented-out add_param_to_type support.
+
+Thu Mar 16 16:38:03 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * xcoffread.c (process_linenos): Make sure filename we pass to
+ start_subfile will cause deduce_language_from_filename to return
+ the correct thing. Reindent function to GNU standards.
+
+Thu Mar 16 15:54:00 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * nlm/gdbserve.c (handle_exception): #if out call to StopBell,
+ as it is not available on NetWare 3 or PIN.
+ * nlm/ppc.c (StopBell): Removed.
+
+Thu Mar 16 12:14:41 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * xcoffread.c (read_xcoff_symtab): When creating a dummy parameter
+ inferred from the traceback tags, give its type the name
+ "<non-float parameter>".
+
+ * stabsread.c (rs6000_builtin_type): Recognize types -31 to -34.
+
+Wed Mar 15 15:09:29 1995 Stu Grossman (grossman@cygnus.com)
+
+ * findvar.c (read_register_bytes write_register_bytes): Make
+ these routines much smarter about updating registers from the
+ target, only doing so when absolutely necessary. This really
+ speeds up register modification on some remote targets.
+
+ * monitor.c: More cleanups. Get rid of monitor_load_ascii_srec.
+ BFD makes this unnecessary. Lots of debugging speedups.
+ * (expect): NULL terminate return string.
+ * (monitor_open monitor_supply_register parse_register_dump
+ monitor_wait monitor_fetch_register): Switch to using GNU regexp
+ library to parse multi-register displays.
+ * (monitor_read_memory): Read multiple bytes (up to 16) at once.
+ * (monitor_create_inferior): Call clear_proceed_status to make run
+ command notice first breakpoint.
+ * (monitor_load): Clean up. Reset inferior_pid, set pc to start
+ address and reset symbol table stuff to make loads put things into
+ a fresh state.
+ * (monitor_load_srec): Lower sleep time to 1 second.
+
+ * monitor.h (struct monitor_ops): Add register_pattern and
+ supply_register to monitor_ops.
+
+ * rom68k-rom.c: Add new support for handling register dumps.
+ * config/m68k/tm-m68k.h: Define D0_REGNUM and A0_REGNUM for register
+ dump handling.
+
+Wed Mar 15 15:18:27 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * utils.c, defs.h (putchar_unfiltered, fputc_unfiltered): Make
+ argument be an int, not a char. Using a prototype followed by an
+ old-style function definition in a case where an argument is
+ widened is a GCC-ism not supported by the native AIX compiler.
+
+Wed Mar 15 12:22:35 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * nlmstub.def: Removed, this was moved to nlm/gdbserve.def
+ long ago.
+
+ * configure.in (alpha-*-netware*): Removed configuration.
+ * config/alpha/{alpha-nw.mt, gdbserve.mt, tm-alphanw.h}: Removed.
+ * nlm/{README-ALPHA-NETWARE, aio.h, alpha-io.S, alpha-regdef.h,
+ alpha.c, alpha.h, altdebug.h}: Removed.
+
+ * nlm/gdbserve.c (main): Add support for processing BOARD=
+ argument, deprecate NODE=.
+
+Wed Mar 15 10:58:26 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * c-exp.y (yylex): Make an empty character constant an error.
+
+Tue Mar 14 15:00:54 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * valops.c (value_arg_coerce): Do possible value_coerce_array
+ before determining type argument to value_cast.
+
+Tue Mar 14 10:41:41 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * remote-es.c: Replace ignore with 0.
+
+Tue Mar 14 05:52:36 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * valops.c (value_repeat), eval.c (evaluate_subexp_standard):
+ If VALUE_REPEATED is already set, just error out.
+
+ * valops.c (value_cast, value_slice), parse.c (follow_types): Add
+ FIXME-type-allocation comments.
+
+ * gdbtypes.h (struct type): Fix comment about what units the
+ TYPE_LENGTH is in.
+
+Mon Mar 13 18:27:25 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * ch-valprint.c (annotate.h): Include.
+ * eval.c (evaluate_subexp_standard): Remove unused variable.
+ (calc_f77_array_dims): Add parens to expression.
+ * f-exp.y (yylex): Add parens to expression, remove unused label.
+ * f-lang.h (calc_f77_array_dims): Declare.
+ * f-valprint.c (f_val_print): Remove unused variables.
+
+Mon Mar 13 15:25:47 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * alpha-tdep.c (find_proc_desc): If pdr.framereg field is -1, don't
+ use the PDR, just examine prologues instead.
+
+Fri Mar 10 16:13:18 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * config/arc/tm-arc.h: Change arc register names.
+
+Fri Mar 10 02:49:40 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ Fix problems with infinite recursion when printing a class
+ that contains a static instance of the class.
+ * cp-valprint.c (dont_print_vb_obstack): Renamed from
+ dont_print_obstack, made static.
+ (dont_print_statmem_obstack): New obstack, controls printing
+ of static member classes.
+ (_initialize_cp_valprint): Initialize it.
+ (cp_print_static_field): New function, handles printing of
+ static members.
+ (cp_print_value_fields): New parameter dont_print_statmem to
+ handle recursive printing of static member classes, use
+ cp_print_static_field to handle printing of static members.
+ * c-valprint.c (cp_print_value_fields): Update prototype and
+ call to include additional dont_print_statmem parameter.
+ * c-valprint.c, f-valprint.c (dont_print_obstack): Remove unused
+ extern declaration.
+
+ * alpha-tdep.c, findvar.c, infptrace.c: Include <string.h>.
+
+ * config/alpha/tm-alpha.h (FRAME_FIND_SAVED_REGS): Call
+ alpha_find_saved_regs if fi->saved_regs is still NULL.
+
+ * elfread.c (elf_symtab_read): Ensure that the filename field
+ of a minsym is nonempty. Ignore solib trampoline symbols from
+ the main symbol table, they might have a bogus value.
+
+ * procfs.c (set_proc_siginfo), config/alpha/alpha-osf2.mh:
+ Fix typos in comments.
+
+Thu Mar 9 17:19:47 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * mdebugread.c (parse_symbol, psymtab_to_symtab_1): Initialize
+ pdr.framereg field of MIPS_EFI_SYMBOL_NAME symbol to -1. That way
+ we know whether the PDR ever got set.
+ * mips-tdep.c (find_proc_desc): If pdr.framereg field is -1, don't
+ use the PDR, just examine prologues instead.
+
+Wed Mar 8 23:35:10 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * somsolib.c (som_solib_section_offsets): Get offset of text
+ section right.
+
+Wed Mar 8 16:12:21 1995 Stu Grossman (grossman@cygnus.com)
+
+
+ * source.c (forward_search_command reverse_search_command): Set
+ convenience variable $_ to be the line # of the match.
+ * symtab.c (decode_line_1): Allow convenience variables to be
+ used in line specs (for breakpoints and such).
+
+Wed Mar 8 12:51:00 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * Makefile.in (VERSION): Bump to 4.14.1.
+ * NEWS, README: Update for 4.14.
+ * i386v-nat.c (i386_insert_aligned_watchpoint): Fix declaration.
+ (i386_insert_nonaligned_watchpoint): Call aligned instead of
+ generic watchpoint insertion.
+
+Tue Mar 7 19:26:10 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * valops.c (value_slice): Do COERCE_VARYING_ARRAY.
+
+Tue Mar 7 00:23:47 1995 Stu Grossman (grossman@cygnus.com)
+
+ * monitor.c, array-rom.c, monitor.h, rom68k-rom.c: Move target_ops
+ into monitor.c.
+ * monitor.c (monitor_create_inferior): Allow run command to start
+ program.
+
+ * monitor.c (monitor_load): Set PC to start address when done
+ loading.
+
+ * array-rom.c, monitor.h, rom68k-rom.c: Clean up target_ops.
+ Remove ref to monitor_create_inferior.
+
+ * monitor.c: More general cleanups. Add prototypes, remove
+ unused routines. Fix bug with wrong number of args to error().
+
+ * main.c (main): Don't start up GUI when running under gdb mode
+ in emacs.
+
+ * Makefile.in: Add rules for monitor.o and rom68k-rom.o to make
+ Sun make (with VPATH) work...
+
+ * monitor.c, monitor.h, rom68k-rom.c: Serious cleanup to make IDP
+ (rom68k) target work right.
+ * array-rom.c, op50-rom.c, w89k-rom.c: Partial updates to new
+ monitor.c interface. More work needs to be done here.
+ * config/m68k/tm-monitor.h: Change DECR_PC_AFTER_BREAK to 0 to
+ match the IDP monitor. Also, set NUM_REGS to 18 cuz there's no
+ floating-point for this card.
+
+ * serial.h, ser-go32.c, ser-mac.c, ser-tcp.c, ser-unix.c: Add
+ SERIAL_SETSTOPBITS to set the number of stopbits (needed for IDP
+ board?!?!?).
+
+ * defs.h, utils.c, remote-hms.c, remote-pa.c, remote.c: Fix defs
+ and usage of fputc_unfiltered and putchar_unfiltered. Eliminate
+ putc_unfiltered (it's superfluous).
+
+ * command.h, command.c, top.c: Add var_enum command type. It's
+ like var_string but allows only only one of the specified strings.
+
+Mon Mar 6 15:03:59 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * valops.c (value_cast): Don't use backslash newline--pre-ANSI
+ compilers (such as SunOS4 /bin/cc) don't generally support it
+ except in some contexts.
+
+Fri Mar 3 17:42:48 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * valops.c (value_cast): Check for cast to array type *before*
+ we coerce array to pointer (in case arg2 is already array).
+
+ * valops.c (call_function_by_hand): Set using_gcc to 2 if using
+ gcc2. Needed for REG_STRUCT_HAS_ADDR to work on sparc.
+ Also check REG_STRUCT_HAS_ADDR for union, array and string types.
+
+ * valops.c (call_function_by_hand): Re-arrange code for pushing
+ paramaters on the stack so we can do better STACK_ALIGN.
+
+ * valops.c (call_function_by_hand): Call error if the number
+ of arguments is fewer than parameter types in function type.
+
+Fri Mar 3 17:13:05 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-tdep.c (sparc_extract_struct_value_address): Move
+ sparc64 support to here.
+ (sparc64_extract_struct_value_address): Deleted.
+ (dump_ccreg): Add a prototype so long long arg -> int.
+ * sparc/tm-sp64.h (USE_STRUCT_CONVENTION): Define.
+ (EXTRACT_STRUCT_VALUE_ADDRESS): Delete.
+
+Fri Mar 3 15:12:12 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c (hpread_record_lines): New argument "offset". All
+ callers changed. Use it to handle dynamic address relocation.
+ (hpread_build_psymtabs): Adjust texthigh as we read each function
+ debug symbol. Fix computation of texthigh.
+ (hpread_read_subrange_type): Work around macro bugs in HP's
+ compilers.
+ (hpread_process_one_debug_symbol): Correctly map source lines.
+
+ * somread.c (check_strange_names): Filter names emitted by the HP
+ compiler when generating PIC code.
+
+ * valops.c (value_struct_elt_for_reference): Work around macro
+ bugs in HP's compilers.
+ * c-exp.y (block): Likewise.
+
+Fri Mar 3 12:27:28 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * rs6000-tdep.c (push_dummy_frame): Fix order of arguments to
+ store_address.
+
+ * utils.c [_AIX]: Include stddef.h instead of #defining size_t.
+
+Fri Mar 3 12:33:24 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * rs6000-tdep.c (skip_prologue): Skip multiple stores of the saved
+ registers that GCC emits on the PowerPC by default in addition to
+ the store multiple instruction used on the Power series.
+
+Fri Mar 3 00:54:58 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-tdep.c (decode_asi): New function.
+ (sparc_print_register_hook): Pretty print more v9 registers.
+ * sparc/tm-sp64.h (REGISTER_NAMES): Fix some typos.
+
+Thu Mar 2 22:20:22 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * dwarfread.c (struct dieinfo): Use CORE_ADDR for at_{low,high}_pc.
+ (target_to_host): Change result type to CORE_ADDR.
+
+Thu Mar 2 15:13:04 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * rs6000-tdep.c: Fix byte-swapping sins.
+
+Thu Mar 2 16:48:45 1995 Michael Meissner <meissner@cygnus.com>
+
+ * rs6000-tdep.c (branch_dest): Minor code cleanup, don't share
+ code between branch unconditional and branch conditional cases.
+
+Wed Mar 1 09:41:26 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ Various changes for sparc64.
+ * sparc-tdep.c (NUM_SPARC_FPREGS): Define.
+ (SPARC_INTREG_SIZE): Define.
+ (*): Use SPARC_INTREG_SIZE instead of REGISTER_RAW_SIZE (intreg)
+ where appropriate.
+ (enum branch_type): New value `done_retry'.
+ (isbranch): Renamed from isannulled. All callers changed.
+ Support new sparc64 branch insns.
+ (single_step): Handle done_retry.
+ (sparc_extract_struct_value_address): Don't assume 4 byte regs.
+ (get_saved_register): Likewise.
+ (sparc_push_dummy_frame): Likewise.
+ (sparc_frame_find_saved_regs): Likewise.
+ (sparc_pop_frame): Likewise. Don't refer to FPS_REGNUM, CPS_REGNUM,
+ or PS_REGNUM if not sparc64. sparc64 has 64 fp regs.
+ (sparc64_extract_struct_value_address): New function.
+ (dump_ccreg, sparc_print_register_hook): Likewise.
+ * sp64-tdep.c: Deleted.
+ * sparc/tm-sp64.h (GDB_TARGET_IS_SPARC64): Define.
+ (NUM_REGS): Reduce by 2, cle/tle are in the pstate reg.
+ (CC_HAS_LONG_LONG): Define.
+ (REGISTER_NAMES): Delete cle/tle and reorganize.
+ (PS_REGNUM, FPS_REGNUM, CPS_REGNUM): Delete, they're ifdef'd out of
+ sparc-tdep.c now.
+ (REGISTER_BYTES): Update.
+ (REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW): Delete.
+ (EXTRACT_RETURN_VALUE): Delete. Use definition in tm-sparc.h.
+ (NO_SINGLE_STEP): Likewise.
+ * sparc/tm-sparc.h (EXTRACT_VALUE_RETURN): Don't assume 4 byte regs.
+ * sparc/sp64.mt: Move simulator support ...
+ * sparc/sp64sim.mt: ... to here.
+
+Wed Mar 1 13:14:42 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * remote-vx960.c: new file for target specific register packaging.
+ * remote-vx68.c: ditto.
+ * config/i960/vxworks960.mt: add remote-vx960.o.
+ * config/m68k/vxworks68.mt: add remote-vx68.o.
+
+Wed Mar 1 13:42:49 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * remote.c (remote_wait): Make calls to strtol be type correct by
+ passing the address of a char * pointer instead of an unsigned
+ char *.
+
+ * rs6000-tdep.c (push_dummy_frame): Cast sp to char * when calling
+ write_memory to make things type correct.
+
+Wed Mar 1 12:17:31 1995 Michael Meissner <meissner@cygnus.com>
+
+ * ch-exp.y, c-exp.y, f-exp.y, m2-exp.y (yy defines): Support the
+ standard Linux yacc by adding more names to be redefined with a
+ prefix.
+
+Tue Feb 28 22:55:47 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hppa-tdep.c (pa_print_registers), monitor.c: Use
+ extract_unsigned_integer and friends, not SWAP_TARGET_AND_HOST.
+ * defs.h, findvar.c: Move SWAP_TARGET_AND_HOST back to findvar.c.
+ Rename it to SWAP_FLOATING to make it clear it is no longer for
+ integers.
+
+Tue Feb 28 14:38:39 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * defs.h (SWAP_TARGET_AND_HOST): check endianess at runtime not
+ compile time.
+ * arc-tdep.c (_initialize_arc_tdep): set tm_print_insn according to
+ processor.
+
+ * vx-share/ptrace.h: merge in WRS new ptrace requests.
+
+ * defs.h: fix a syntax error.
+
+ * a29k-tdep.c (get_longjmp_target): add this function, from WRS.
+ * remote-vx.c: move read_register and write_register out to
+ target specific files.
+ * remote-vx29k.c (get_fp_contnets): add this function, from WRS.
+
+ * defs.h: define SWAP_TARGET_AND_HOST macro.
+ * findvar.c, monitor.c, hppa-tdep.c: remove definition of
+ SWAP_TARGET_AND_HOST.
+
+Tue Feb 28 08:31:40 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * alpha-tdep.c (find_proc_desc): Only attempt to set
+ PROC_LOCALOFF (found_heuristic) if found_heuristic is non-NULL.
+
+Mon Feb 27 11:56:32 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * monitor.c: General gcc -Wall lint cleanup and reformat.
+ (monitor_command): If no args, send an empty command.
+
+Thu Feb 23 21:07:25 1995 Stu Grossman (grossman@cygnus.com)
+
+ * monitor.c (monitor_load_ascii_srec): Add a one second sleep
+ after send LOAD_CMD to prevent loss of first S-record.
+
+Tue Feb 21 20:48:42 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * valops.c (call_function_by_hand): Set using_gcc to 2 if gcc-2.
+ Call error if too few arguments.
+ If REG_STRUCT_HAS_ADDR (structs passed by invisible reference),
+ copy and convert to reference *before* we calculate alignment.
+ Also, make sure structs allocated for return values and invisible
+ reference don't violate STACK_ALIGN.
+
+Tue Feb 21 23:29:59 1995 Per Bothner <bothner@rtl.cygnus.com>
+
+ * ch-exp.y (expression_conversion): Recognize 'ARRAY () TYPE (EXPR)'
+ (same as C's '(TYPE[])EXPR')
+
+Tue Feb 21 11:47:26 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * top.c (print_gdb_version): Update the year.
+
+Sun Feb 19 14:31:57 1995 Jim Kingdon <kingdon@rtl.cygnus.com>
+
+ * Makefile.in (CC_FOR_TARGET, CXX_FOR_TARGET): Look for newlib in
+ `..' not in `../..'.
+
+Sun Feb 19 11:05:28 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * procfs.c (unconditionally_kill_inferior): Don't issue a PIOCKILL
+ in addition to a PIOCSSIG to kill the inferior.
+
+Thu Feb 16 15:06:12 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * parse.c (follow_types): Given (TYPE[]) (i.e. with no length),
+ create a 0-length array type, and set BOUND_CANNOT_BE_DETERMINED.
+ * valops.c (value_cast): If a cast like (TYPE[])VALUE (i.e. array
+ of unknown length) use sizeof(VALUE)/sizeof(TYPE) as the length.
+ * c-typeprint.c (c_type_print_varspec_suffix): If array length
+ is 0, print it, but not if upper_bound is BOUND_CANNOT_BE_DETERMINED.
+
+Thu Feb 16 16:06:50 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * dcache.c (insque, remque): Rewrite Linux support.
+
+Wed Feb 15 12:33:20 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/powerpc/tm-ppc-eabi.h (TEXT_SEGMENT_BASE): Define as 1.
+
+ * dcache.c (insque, remque): If compiling in standard C on Linux,
+ protect insque and remque with macros to cast the pointer
+ arguments to the proper type.
+
+Tue Feb 14 17:16:41 1995 Stu Grossman (grossman@cygnus.com)
+
+ * annotate.c, breakpoint.c, defs.h, top.c: Replace
+ enable/disable_breakpoint_hook with modify_breakpoint_hook.
+
+Tue Feb 14 16:58:07 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * expression.h: Move declaration of evaluate_subexp_with_coercion
+ from here...
+ * value.h: ...to here.
+ * expression.h: Don't include value.h
+
+Tue Feb 14 11:46:07 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * expression.h: Move include of value.h until after declaration of
+ enum exp_opcode.
+
+Sun Feb 12 13:47:30 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-e7000.c: Comprehensive cleanup; removal of dead code,
+ simplify code, declare things, format to standards.
+ (inferior.h, value.h, command.h, remote-utils.h): Include.
+ (e7000_login): Rename to e7000_login_command.
+ (e7000_ftp): Rename to e7000_ftp_command.
+ (e7000_drain): Rename to e7000_drain_command.
+
+ * irix5-nat.c (string.h): Include near beginning of file.
+
+Sun Feb 12 12:36:38 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * valops.c (value_arg_coerce): Use VALUE_TYPE not SYMBOL_TYPE on
+ arg, it is a value not a symbol.
+
+ gcc -Wall lint:
+ * eval.c: Move declaration of evaluate_subexp_with_coercion from here..
+ * expression.h: ..to here.
+ * expression.h: Include value.h.
+ * ch-lang.c (evaluate_subexp_chill): Add default case in switch.
+
+Sun Feb 12 11:03:47 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * language.h (struct language_defn): New field evaluate_exp.
+ * c-lang.c (c_language_defn, cplus_language_defn, asm_langauge_defn),
+ f-lang.c (f_language_defn), language.c (unknown_language_defn,
+ auto_language_defn, local_language_defn), m2-lang.c (m2_language_defn):
+ Set evaluate_exp to evaluate_subexp_standard.
+ * ch-lang.c (evaluate_subexp_chill): New function. Chill-specific
+ support for MULTI_SUBSCRIPT.
+ (chill_language_defn): Set evaluate_exp to evaluate_subexp_chill.
+ * eval.c (enum noside): Move from here ....
+ * expression.h (enum noside): ... to here.
+ (evaluate_subexp_standard): New prototype.
+ * eval.c (evaluate_subexp): Renamed to evaluate_subexp_standard.
+ Removed lo-longer-needed test for chill_varying_type.
+ (evaluate_subexp): New. Calls exp->language_defn->evaluate_exp.
+
+ * ch-exp.y (maybe_expression_list): New non-terminal.
+ (primitive_value): Allow empty parameter list.
+
+Sun Feb 12 10:02:16 1995 Per Bothner <bothner@cygnus.com>
+
+ * buildsym.c (finish_block): If finishing a function without known
+ parameter type info, set that from parameter symbols.
+ * c-typeprint.c (c_type_print_varspec_suffix): For TYPE_CODE_FUNC,
+ print parameter types, if available.
+ * ch-typeprint.c (chill_type_print_base): Likewise.
+
+ * gdbtypes.h (struct type): Remove function type field.
+ (TYPE_FUNCTION_TYPE): Remove macro. We can't as simply re-use
+ function types now that we're also storing parameter types.
+ And the payoff is much less.
+ * gdbtypes.c (make_function_type): Don't use/set TYPE_FUNCTION_TYPE.
+ (recursive_dump_type): Don't print TYPE_FUNCTION_TYPE.
+ * dwarfread.c (read_subroutine_type): Don't set TYPE_FUNCTION_TYPE.
+
+ * valops.c (value_arg_coerce): Now takes param_type argument.
+ (call_function_by_hand): Convert arguments with value_arg_coerce
+ early, and overwrite original args with converted args.
+ No longer need multiple calls to value_arg_coerce.
+ (value_arg_push): Removed.
+ * hppa-tdep.c (hppa_push_arguments): No longer call value_arg_coerce.
+ * mips-tdep.c (mips_push_arguments): Likewise.
+ * alpha-tdep.c (alpha_push_arguments): Likewise.
+ * rs6000-tdep.c (push_arguments, ran_out_of_registers_for_arguments):
+ Likewise.
+ * value.h (value_arg_coerce): Remove declaration. (It's now static.)
+
+ * valops.c (value_cast): Do COERCE_VARYING_ARRAY after COERCE_REF.
+
+ * symtab.c (add_param_to_type): Remove (commented-out) function,
+ since that functionality has been re-written.
+ * coffread.c: Remove commented-out add_param_to_type support.
+ * mdebugread.c (parse_symbol): Likewise.
+ * stabsread.c (define_symbol): Likewise.
+
+Sun Feb 12 09:03:47 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * buildsym.c (start_subfile): Set language for f2c like for cfront.
+
+Thu Feb 9 20:20:11 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * op50n-rom.c: Add the control registers.
+
+Thu Feb 9 15:46:39 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * Makefile.in (CLIBS): Add $(LIBIBERTY) before, in addition to
+ after, any host/target/native libraries.
+ * dcache.c (insque, remque): Remove declarations.
+ * gdbtypes.h (type_code): Remove trailing comma.
+
+ From Peter Schauer:
+ * xcoffread.c (read_xcoff_symtab) [C_HIDEXT]: Move #ifdef
+ STATIC_NODEBUG_VARS inside case.
+
+Thu Feb 9 07:43:41 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * config/sparc/tm-sun4sol2.h: Define STATIC_TRANSFORM_NAME.
+ * partial-stab.h: Call it.
+ * stabsread.c (define_symbol) [STATIC_TRANSFORM_NAME]: Call
+ STATIC_TRANSFORM_NAME to get the name and use minimal symbols to
+ get the address.
+ * sparc-tdep.c (solaris_static_transform_name): New function.
+
+Thu Feb 9 12:09:09 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * somread.c (som_symtab_read): Handle dynamic relocation for both
+ text and data symbols.
+ (som_symfile_offsets): If objfile is a shared library, then get
+ text and data offsets from the shared library structures.
+ * somsolib.c (som_solib_add): Copy the bfd pointer from the
+ objfile rather than reopening the file again.
+ (som_solib_section_offsets): New function.
+ * somsolib.h (som_solib_section_offsets): Declare.
+
+Wed Feb 8 20:32:18 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * config/sparc/tm-sun4sol2.h, dbxread.c: Rename
+ N_SO_ADDRESS_MAYBE_MISSING to SOFUN_ADDRESS_MAYBE_MISSING.
+ * symtab.h (minimal_symbol) [SOFUN_ADDRESS_MAYBE_MISSING]: Add
+ filename field.
+ * elfread.c (record_minimal_symbol_and_info),
+ minsyms.c, symtab.h (prim_record_minimal_symbol_and_info): Return
+ newly created symbol.
+ * elfread.c (elf_symtab_read) [SOFUN_ADDRESS_MAYBE_MISSING]:
+ Set filename field of minimal symbol.
+ * symmisc.c (dump_msymbols) [SOFUN_ADDRESS_MAYBE_MISSING]:
+ Print filename field.
+ * minsyms.c, symtab.h (lookup_minimal_symbol): New arg sfile.
+ * symm-tdep.c, somsolib.c, hppa-tdep.c, c-exp.y, f-exp.y,
+ m2-exp.y, nindy-tdep.c, m3-nat.c, irix5-nat.c, hpread.c,
+ os9kread.c, breakpoint.c, alpha-tdep.c, valops.c, symtab.c,
+ printcmd.c, dbxread.c: Change callers to pass NULL for sfile.
+ * dbxread.c (process_one_symbol) [SOFUN_ADDRESS_MAYBE_MISSING]:
+ Find address of function from minimal symbols.
+ * partial-stab.h, case 'f', 'F': Call find_stab_function_addr
+ instead of getting pst->textlow from the stab.
+ * minsyms.c (find_stab_function_addr): New function.
+
+Wed Feb 8 19:19:56 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * monitor.c: Fix so all the output shows up in the GUI command
+ window.
+
+Mon Feb 6 18:50:59 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * i386-tdep.c (_initialize_i386_tdep): Put void decl on separate
+ line, so init.c generation works correctly.
+ * arc-tdep.c (_initialize_arc_tdep): Ditto.
+
+Mon Feb 6 14:44:36 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * config/mips/idt.mt: Add support for the lsi33k target.
+ * config/sparc/sun4sol2.mh: Add support for ser-tcp.
+ * array-rom.c: Finish the rest of the support commands needed by
+ GDB.
+ * mips-tdep.c: Add LSI33k register names and processor type.
+
+Sat Feb 4 13:29:52 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/m68k/est.mt (TDEPFILES): Remove m68k-pinsn.o.
+
+Fri Feb 3 11:19:20 1995 Stu Grossman (grossman@cygnus.com)
+
+ * core.c (dis_asm_read_memory), defs.h, top.c: Get rid of
+ dis_asm_read_memory_hook. We can now call the disassemblers
+ directly and have no need for this hook anymore.
+ * defs.h, printcmd.c: Make print_insn be static.
+
+ * ser-go32.c (dos_comisr): Make this 8 bit clean.
+ * (dos_open dos_close): Allow multiple opens to the same device.
+ Use a ref count to prevent unwanted deallocations.
+ * sparcl-tdep.c: Put #ifdefs around all socket stuff to make GO32
+ happy.
+ * (sparclite_ops): Switch to download_stratum.
+ * target.h (enum strata): Move download_stratum before
+ process_stratum so that executable targets get pushed on top of
+ download targets.
+
+Thu Feb 2 19:02:45 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * array-rom.c: Remove the non GDB remote protocol config stuff.
+
+ * monitor.c: All reading/writing functions for memory and
+ registers work.
+
+Thu Feb 2 16:11:04 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * config/arc/arc.mt: new target makefile for arc processor.
+ * config/arc/tm-arc.h: new target header for arc processor.
+ * config/arc/go32.mh: new go32 host makefile for arc processor.
+ * config/arc/xm-go32.h: new go32 host header for arc processor.
+ * arc-tdep.c: new target dependent codes for arc processor.
+
+Thu Feb 2 13:58:40 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * Makefile.in (VERSION): Bump to 4.13.2.
+
+Thu Feb 2 07:27:56 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ Fix compiler warnings:
+ * remote-e7000.c (printf_e7000debug): Rename to puts_e7000debug
+ and have the caller do the sprintf. Saves us from varargs hell.
+ (normal): Define before use.
+ * remote-e7000.c: Reindent a few things.
+
+Wed Feb 1 21:16:42 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * f-typeprint.c (f_type_print_varspec_suffix): Print array index
+ ranges in reverse order.
+ * f-valprint.c (f77_create_arrayprint_offset_tbl): Fix calculation.
+
+ * eval.c (evaluate_subscript): Don't call value_subscript, since
+ it adjusts for lower bound and enforces ranges.
+
+ * expression.h (exp_code): Remove MULTI_F77_SUBSCRIPT, OP_F77_SUBSTR.
+ * eval.c, parse.c: Removed uses of removed opcodes.
+ * eval.c (evaluate_subexp): Clean up handling of
+ OP_UNDETERMINED_ARGLIST (no backtracking, more general).
+
+ * f-valprint.c (f_val_print): Print TYPE_CODE_STRING using
+ LA_PRINT_STRING, and not val_print_string (which reads from inferior).
+
+ * ch-lang.c (chill_is_varying_struct), ch-lang.h: Remve function
+ duplicate function made redundant by chill_varying_type.
+
+ Re-write of f77 string and complex number support:
+
+ * language.h (struct language_defn): New fields string_lower_bound
+ and string_char_type.
+ * c-lang.c (c_language_defn, cplus_language_defn, asm_language_defn),
+ language.c (unknown_language_defn, auto_language_defn,
+ local_language_defn), m2-lang.c (m2_language_defn), f-lang.c
+ (f_language_defn), ch-lang.c (chill_language_defn): Set new fields.
+ * gdbtypes.c (create_string_type): Use new string_char_type field.
+ * valops.c (value_string): Use new string_lower_bound field.
+
+ * defs.h (TARGET_COMPLEX_BIT, TARGET_DOUBLE_COMPLEX_BIT): Removed.
+ * f-lang.c (f_create_fundamental_type, _initialize_f_language),
+ m2-lang.c (m2_create_fundamental_type),
+ gdbtypes.c (_initialize_gdbtypes): Set TYPE_TARGET_TYPE of complex
+ types. Set their TYPE_CODEs to TYPE_CODE_COMPLEX.
+ * mdebugread.c (mdebug_type_complex, mdebug_type_double_complex):
+ Removed. Use builtin_type_complex and builtin_type_double_complex.
+
+ * gdbtypes.h (enum type_code): Removed TYPE_CODE_LITERAL_STRING
+ and TYPE_CODE_LITERAL_COMPLEX.
+ * c-typeprint.c, f-typeprint.c, f-valprint.c, eval.c: Removed uses of
+ TYPE_CODE_LITERAL_STRING and TYPE_CODE_LITERAL_COMPLEX.
+ * gdbtypes.c, gdbtypes.h (f77_create_literal_complex_type,
+ f77_create_literal_string_type): Removed.
+ * value.h (VALUE_LITERAL_DATA, VALUE_SUBSTRING_MEMADDR,
+ VALUE_SUBSTRING_MYADDR): Removed.
+
+ * expression.h (enum exp_opcode): Rename OP_F77_LITERAL_COMPLEX to
+ OP_COMPLEX.
+ * parse.c: Update accordingly.
+
+ * f-valprint.c (f77_print_cmplx): Removed.
+ (f_val_print case TYPE_CODE_COMPLEX): Re-write to use print_floating.
+
+ * f-exp.y (STRING_LITERAL): Use OP_STRING instead of OP_ARRAY.
+ * eval.c (evaluate_subexp): For case OP_ARRAY, don't call
+ f77_value_literal_string.
+ * valops.c, value.h (f77_value_literal_string, f77_value_substring,
+ f77_assign_from_literal_string, f77_assign_from_literal_complex):
+ Removed.
+ (value_assign): No longer need to handle literal types.
+ * valops.c (f77_value_literal_complex), value.h: Re-written and
+ renamed to value_literal_complex. Last arg is now a (complex) type.
+ * valops.c (f77_cast_into_complex): Re-written and renamed to
+ cast_into_complex.
+ * eval.c (evaluate_subexp): Update accordingly.
+
+ * ch-valprint.c (chill_val_print): On TYPE_CODE_STRING, don't
+ print address for non-'s'-formats.
+ * ch-typeprint.c, ch-valprint.c: Use chill_varying_type instead
+ of chill_is_varying_struct.
+
+Wed Feb 1 13:27:33 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ gcc -Wall lint.
+ * alpha-tdep.c (alpha_in_lenient_prologue): Comment out.
+ (after_prologue): Remove unused local b.
+ * procfs.c (thread.h): Include.
+ (pr_flag_table, pr_why_table, faults_table, siginfo_table): Use
+ nested braces in initializer.
+ * top.c (initialize_targets, initialize_utils): Declare.
+ (locate_arg, insert_args): Add parens around tested assignments.
+ * remote-utils.c (sr_scan_args): Remove decl of strtol.
+ * remote.c (thread.h): Include.
+ (remote_wait): Remove unused local p2.
+ * sparc-tdep.c (fill_gregset, fill_fpregset): Remove decls of
+ registers array.
+
+ defs.h (stdlib.h): Include.
+ (exit, perror, atoi, qsort, memcpy, memcmp): Don't declare.
+ (fclose, atof, malloc, realloc, free, strchr, strrchr, strstr,
+ strtok, strerror): Don't specify parameter types in declaration.
+
+Wed Feb 1 12:23:57 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * ch-exp.y (value_string_element, string_primitive_value,
+ start_element, left_element, right_element, slice_size,
+ lower_element, upper_element, first_element): Removed.
+ (value_string_slice, value_array_slice): Replaced by ...
+ (slice): New non-terminal, with working slice support.
+ (primitive_value_lparen, rparen): New non-terminals.
+ (maybe_tuple_elements): New non-terminal, to allow empty tuples.
+ (idtokentab): Added "up".
+
+ * value.h (COERCE_VARYING_ARRAY): New macro.
+ * valarith.c (value_subscript): Use it.
+ * valops.c (value_cast): Likewise. Also, do nothing if already
+ correct type, and allow converting from/to range to/from scalar.
+
+ * valops.c, value.h (varying_to_slice, value_slice): New functions.
+ * eval.c (OP_ARRAY): Add cast for array element.
+ * expression.h (TERNOP_SLICE, TERNOP_SLICE_COUNT): New exp_opcodes.
+ * valops.c (chill_varying_type): Moved function frp, here ...
+ * gdbtypes.c (chill_varying_type), gdbtypes.h: ... to here.
+ * parse.c (length_of_subexp, prefixify_subexp): Add support
+ for TERNOP_SLICE, TERNOP_SLICE_COUNT.
+ * expprint.c (print_subexp, dump_expression): Likewise.
+ * eval.c (evaluate_subexp): Likewise.
+
+ * eval.c (evaluate_subexp case MULTI_SUBSCRIPT): Don't call
+ value_x_binop on a Chill varying string.
+
+Tue Jan 31 13:51:53 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/m68k/monitor.mt,
+ config/pa/{hppabsd.mt,hppahpux.mt,hppaosf.mt,hppapro.mt}: Put
+ depfiles in TDEPFILES not REMOTE_O.
+
+Tue Jan 31 11:14:44 1995 Steve Chamberlain <sac@splat>
+
+ From nigel@algor.co.uk.
+ * ser-go32.c (dos_close): Don't crash if scb null.
+ (dos_sendbreak): New function.
+ (dos_ops): Point to dos_sendbreak.
+ (dos_info): Calculate COM number correctly.
+
+Tue Jan 31 09:40:11 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * xcoffread.c (process_xcoff_symbol): Use new variables
+ func_symbol_type and var_symbol_type as type of functions and
+ variables which don't have any stabs associated with them.
+ Reindent most of function.
+ (_initialize_xcoffread): Initialize *_symbol_type.
+
+ * xcoffread.c (read_xcoff_symtab): Reindent most of function.
+ Put C_HIDEXT symbols in the minimal symbols, rather than ignoring
+ them (this part commented out as I didn't quite get it to work).
+ (cs_to_section, find_targ_sec): New functions, to support above code.
+ * xcoffread.c (RECORD_MINIMAL_SYMBOL): Only skip '.' if it is
+ actually present.
+
+Mon Jan 30 17:34:24 1995 Stu Grossman (grossman@cygnus.com)
+ * sparcl-tdep.c: Add `sparclite' target for doing serial and udp
+ downloads to SPARClite demo boards.
+
+Sun Jan 29 09:43:22 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote.c, remote-pa.c: Remove #if 0'd icache code. It has had
+ no hope of working as is for a long time (in particular, shebs' 27
+ Jan 95 change confuses the issue further--target_read_memory and
+ xfer_core_file do *not* do the same thing in this context).
+ Revise comment.
+
+Sat Jan 28 13:40:46 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * elfread.c (elf_symtab_read): Do not test BSF_GLOBAL for
+ procedure linkage table symbols, it is no longer set due to the
+ Jan 6 BFD change in bfd/elfcode.h.
+
+Fri Jan 27 17:08:06 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * top.c (use_windows): Clarify comments.
+
+ * convex-tdep.c (xfer_core_file): Comment out.
+ * config/convex/tm-convex.h (XFER_CORE_FILE): Remove.
+ * remote.c, remote-pa.c (remote_fetch_word): Change xfer_core_file
+ references to target_read_memory.
+ * gdbcore.h (xfer_core_file, core_open, core_detach): Remove
+ declarations.
+ * corelow.c (core_open, core_detach): Make static.
+
+ * arm-tdep.c: Make it compile.
+ (exec_file_command, xfer_core_file): Comment out.
+ (arm_print_insn): Remove, now in libopcodes.
+ (skip_prologue): Comment out most of body.
+ (arm_frame_find_saved_regs): Move here from tm-arm.h.
+ (_initialize_arm_tdep): Set tm_print_insn.
+ * config/arm/tm-arm.h: Remove old refs to first_object_file_end.
+ (XFER_CORE_FILE): Remove.
+ (FRAME_FIND_SAVED_REGS): Call arm_frame_find_saved_regs.
+
+Fri Jan 27 08:48:28 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (CHILL_LIB): Define as in testsuite/Makefile.in.
+
+Thu Jan 26 18:24:41 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * symtab.c (find_pc_line): When subtracting one to get a line
+ number, make sure not to end up with zero.
+
+ * remote-vx.c: Revert all of Kung's changes of 16 Jan. The
+ problems with those changes were (a) the file didn't compile, (b)
+ they changed memset to bzero--memset is correct, (c) they took out
+ code to deal with boards lacking floating point, (d) who knows
+ what I didn't discover in a quick read.
+
+Thu Jan 26 17:32:54 1995 Stu Grossman (grossman@cygnus.com)
+
+ * sparcl-tdep.c: Clean up formatting and indentation.
+
+Thu Jan 26 10:49:59 1995 Steve Chamberlain <sac@splat>
+
+ * remote-hms.c (hms_ops): Change ref of hr_load_image
+ to gr_load_image.
+ (dcache_flush, dcache_hit, dcache_value, dcache_fetch,
+ dcache_poke, dcache_init): Deleted.
+ (hms_open, hms_resume, hms_fetch_word, hms_store_word):
+ Use dcache routines provided by remote-util.h
+
+Thu Jan 26 12:08:31 1995 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in: Add support for powerpc-*-eabi.
+
+ * powerpc/tm-ppc-eabi.h, powerpc/pcc-eabi.mt: New files for
+ PowerPC support.
+
+Wed Jan 25 18:13:14 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * language.h (struct language_defn): New field c_style_arrays.
+ * language.c (unknown_language_defn, auto_language_defn,
+ local_language_defn), c-lang.c (c_language_defn, cplus_language_defn,
+ asm_language_defn): Set c_style_arrays to true.
+ * m2-lang.c (m2_language_defn), ch-lang.c (chill_language_defn),
+ f-lang.c (f_language_defn): Set c_style_arrays to false.
+ * valops.c (value_string): If c_style_array is not set,
+ allocate string in gdb (not inferior) using allocate_value.
+
+ * value.h (COERCE_ARRAY), valops.c (value_addr, value_arg_coerce):
+ Only call value_coerce_array if current_language->c_style_arrays.
+ * values.c: Add #include "language.h". (Needed for COERCE_ARRAY.)
+
+ * valops.c (chill_varying_type): New predicate.
+ * valops.c (value_cast): Support assigning a fixed string or array
+ to a variable string/array structure.
+
+ * valarith.c (value_subscripted_rvalue): Extra parameter lowerbound.
+ Check index>=lowerbound, and then add lowerbound to index here,
+ instead of in caller. Generalize to arbitrary lval_types.
+ (value_subscript): Use enhanced value_subscripted_rvalue if
+ c_style_arrays is false (and index is in range).
+
+
+Wed Jan 25 18:13:14 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * eval.c (evaluate_subexp case OP_ARRAY): Fix calls to memset:
+ TYPE_LENGTH is length in bytes, not bits.
+
+Wed Jan 25 08:19:35 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * infrun.c (proceed): Flush stdout before resuming inferior.
+ * infcmd.c (step_1), annotate.c (annotate_starting):
+ Don't bother to flush here.
+
+Wed Jan 25 01:11:21 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpread.c (hpread_process_one_debug_symbol): Fix lines garbled
+ by an ill-advised global search and replace.
+
+Mon Jan 23 13:11:46 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ Add support for Chill bitstring literals (e.h. H'FF00').
+ * ch-exp.y (match_bitstring_literal): Fix for proper endianness.
+ * expprint.c (print_subexp): Don't call error on OP_BITSTRING,
+ just print B'<unimlemented>'.
+ * gdbtypes.c (create_set_type): Fix bug in length calculation.
+ * valops.c, value.h (value_bitstring): New function.
+ * eval.c (evaluate_subexp): Implement support for OP_BITSTRING.
+
+ * ch-typeprint.c (chill_type_print_base): For TYPE_CODE_FUNC,
+ check that return type is non-void, and print in proper Chill syntax.
+
+Mon Jan 23 12:20:34 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * Makefile.in: Remove references to remote-mon.c.
+ * remote-mon.c: remove. Replaced by rom68k-rom.c.
+ * rom68k-rom.c: Support for Rom68k monitor.
+
+Mon Jan 23 10:50:57 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (CHILL_FOR_TARGET): Update -L argument to point to
+ gcc/ch/runtime not chillrt, since that is where the chill runtime
+ lives now.
+
+Mon Jan 23 00:06:57 1995 Steve Chamberlain <sac@splat>
+
+ * remote-hms.c (hms_load): Delete.
+ (target_ops): Use hr_load_image.
+
+ * remote-e7000.c, remote-z8k.c, remote-nindy.c (target_ops):
+ Define memory_insert/remove_breakpoint.
+ * xm-go32.h: Remove redundant SIGs.
+
+Thu Jan 19 20:26:58 1995 Steve Chamberlain <sac@splat>
+
+ * ser-go32.c: Rewritten by nigel@algor.co.uk.
+
+Fri Jan 20 15:23:55 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * expression.h (OP_LABELED): New operator, for Chill
+ labeled structre tuples.
+ * ch-exp.y (tuple_element, named_record_element, tuple_elements):
+ New non-terminals, to handle labeled structure tuples.
+ (tuple): Re-define using tuple_elements.
+ * eval.c (evaluate_labeled_field_init): New function, to handle
+ initialization of structure fields, possibly using OP_LABELED.
+ (evaluate_subexp): Use it.
+ * expprint.c (print_subexp case): For OP_ARRAY, use Chill syntax
+ for Chill. Handled OP_LABELED.
+ * parse.c (length_of_subexp, prefixify_subexp): Handle OP_LABELED.
+
+ * eval.c (evaluate_subexp): Handle Chill Powerset tuples.
+ * valarith.c (value_bit_index): Just treat bitstring as represented
+ by an array of bytes. Alignment is handled by compiler.
+
+Wed Jan 18 19:00:29 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * h8300-tdep.c (gdb_print_insn_h8300): Fix typo (&info -> info).
+ * sh-tdep.c (gdb_print_insn_sh): Ditto.
+
+Wed Jan 18 11:25:43 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * remote-os9k.c (rombug_open): Fix a bug in exception handling
+ command.
+ * remote-os9k.c (rombug_write_inferior_memory): reset buffer after
+ write.
+
+Tue Jan 17 09:48:38 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * parse.c (_initialize_parse): Improve wording of names of
+ msym_*_symbol_type.
+
+Tue Jan 17 14:00:58 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/mips/tm-mips.h (enum mips_fpu_type): New enum.
+ (mips_fpu): Change type to enum mips_fpu_type.
+ (FIX_CALL_DUMMY): Handle mips_fpu == MIPS_FPU_SINGLE.
+ * mips-tdep.c (mips_fpu): Change type to enum mips_fpu_type.
+ Don't initialize.
+ (mips_fpu_string): New static variable.
+ (mips_push_dummy_frame): Handle mips_fpu == MIPS_FPU_SINGLE.
+ (mips_pop_frame): Likewise.
+ (mips_extract_return_value): Likewise.
+ (mips_store_return_value): Likewise.
+ (mips_set_fpu_command): New static function.
+ (mips_show_fpu_command): New static function.
+ (_initialize_mips_tdep): Change handling of set/show mipsfpu.
+
+Tue Jan 17 09:48:38 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * a29k-tdep.c (gdb_print_insn_a29k): Fix typo (&info -> info).
+
+ * parse.c (write_exp_msymbol): Use new variables
+ msym_*_symbol_type as type of msymbol expression.
+ (_initialize_parse): Initialize them.
+
+Mon Jan 16 18:11:03 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ General cleanup and simplication of disassembler interface.
+ * a29k-pinsn.c, arm-pinsn.c, convex-pinsn.c, gould-pinsn.c,
+ hppa-pinsn.c, i386-pinsn.c, i960-pinsn.c, m68k-pinsn.c,
+ m88k-pinsn.c, mips-pinsn.c, ns32k-pinsn.c, pyr-pinsn.c,
+ rs6000-pinsn.c, sparc-pinsn.c, tahoe-pinsn.c, vax-pinsn.c: Remove.
+ * gould-tdep.c, ns32k-tdep.c, tahoe-tdep.c, vax-tdep.c: New files,
+ had been -pinsn.c files.
+ * Makefile.in (ALLDEPFILES): Remove removed files.
+ (a29k-pinsn.o, arm-pinsn.o, convex-pinsn.o, gould-pinsn.o,
+ hppa-pinsn.o, i386-pinsn.o, i960-pinsn.o, m68k-pinsn.o,
+ m88k-pinsn.o, mips-pinsn.o, ns32k-pinsn.o, pyr-pinsn.o,
+ rs6000-pinsn.o, sparc-pinsn.o, tahoe-pinsn.o, vax-pinsn.o):
+ Remove compile actions.
+ * arm-tdep.o, gould-tdep.o, ns32k-tdep.o, tahoe-tdep.o,
+ vax-tdep.o: Add compile actions.
+ * defs.h (tm_print_insn): New global.
+ * a29k-tdep.c (gdb_print_insn_a29k): New function.
+ (_initialize_a29k_tdep): Rename from _initialize_29k,
+ set tm_print_insn.
+ * alpha-tdep.c (print_insn): Remove.
+ (_initialize_alpha_tdep): Set tm_print_insn.
+ * arm-tdep.c (arm_print_insn): New function, was print_insn
+ in arm-pinsn.c.
+ * convex-tdep.c (convex_print_insn): New function, was print_insn
+ in convex-pinsn.c.
+ * h8300-tdep.c (print_insn): Remove.
+ (gdb_print_insn_h8300): New function.
+ (_initialize_h8300_tdep): New function.
+ * h8500-tdep.c (print_insn): Remove.
+ (_initialize_h8500_tdep): New function.
+ * hppa-tdep.c (_initialize_hppa_tdep): Set tm_print_insn.
+ * i386-tdep.c (_initialize_i386_tdep): New function.
+ * i960-tdep.c (mem, next_insn): New functions, were in
+ i960-pinsn.c.
+ (_initialize_i960_tdep): Set tm_print_insn.
+ * m68k-tdep.c (_initialize_m68k_tdep): New function.
+ * m88k-tdep.c (_initialize_m88k_tdep): New function.
+ * mips-tdep.c (gdb_print_insn_mips): New function.
+ (_initialize_mips_tdep): Set tm_print_insn.
+ * pyr-tdep.c (pyr_print_insn): New function, was print_insn
+ in pyr-pinsn.c.
+ * rs6000-tdep.c (_initialize_rs6000_tdep): New function.
+ * sh-tdep.c (print_insn): Remove.
+ (gdb_print_insn_sh): New function.
+ (_initialize_sh_tdep): Set tm_print_insn.
+ * sparc-tdep.c (_initialize_sparc_tdep): New function.
+ * w65-tdep.c (print_insn): Remove.
+ (_initialize_w65_tdep): New function.
+ * z8k-tdep.c (print_insn): Remove.
+ (gdb_print_insn_z8k): New function.
+ (_initialize_z8k_tdep): Set tm_print_insn.
+ * printcmd.c (print_insn): New function, generic disassembler.
+ * config/*/*.mt (TDEPFILES): Remove refs to *-pinsn.o.
+
+Mon Jan 16 15:43:29 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * Makefile.in: add new files remote-vx29k.c, config/a29k/tm-vx29k.h,
+ and config/a29k/vx29k.mt.
+ * configure.in: add new configuration a29k-*-vxworks.
+ * remote-vx29k.c: new file merged from WRS.
+ * remote-vx.c: merge changes from WRS.
+ * config/a29k/vx29k.mt: new file for new configuration.
+ * config/a29k/tm-vx29k.h: new header file for newconfiguration.
+
+Sun Jan 15 14:36:19 1995 Steve Chamberlain <sac@splat>
+
+ * breakpoint.h (disable_breakpoint, enable_breakpoint):
+ New declarations.
+ (enum bpdisp): Change name of 'delete' member to 'del'.
+ (struct bpstat): Changed name to 'bpstats'.
+ * breakpoint.c (disable_breakpoint, enable_breakpoint,
+ breakpoint_chain): Made globally visible.
+ (bpstat_stop_status): Use new name for bpstat.
+ (break_command_1, watch_command_1, catch_command_1,
+ breakpoint_auto_delete, denable_delete_breakpoint): Use 'del'
+ instead of 'delete'.
+ (set_breakpoint_sal): New function.
+ * defs.h (registers_changed_hook): New declaration.
+ * infcmd.c (run_stack_dummy): 'delete' is now 'del'.
+ * inflow.c (new_tty): Treat WIN32 in same way as __GO32__
+ * main.c (main): Don't scan options when in WIN32 and exit
+ without entering main loop.
+ * m2-exp.y (m2_elx): Member 'class' is now 'aclass'.
+ * symtab.h (struct symbol, struct partial_symbol): Changed name of
+ member 'class' to 'aclass'.
+ (SYMBOL_CLASS, PSYMBOL_CLASS): Reflect change.
+ * top.c (registers_changed_hook): New definition.
+ * utils.c (quit, notice_quit, initialize_utils): Treate WIN32
+ in same way as __GO32__.
+ * value.h (c_typedef_print): Rename 'new' argument.
+
+ * w65-tdep.c, config/tm-w65.h, config/w65.mt: New files.
+ * configure.in: Suppprt for w65,
+
+
+Sat Jan 14 11:18:11 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * infcmd.c (signal_command): For "signal 0", pass (CORE_ADDR)-1,
+ not stop_pc, to proceed.
+
+ * eval.c (evaluate_subexp): Clear expect_type except for C++ and CHILL.
+
+Fri Jan 13 17:52:57 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * infcmd.c (signal_command): Accept "signal 0"; the change to not
+ accept it was accidental. "handle 0" and "info signal 0" remain
+ illegal, though.
+
+Fri Jan 13 15:19:01 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * Makefile.in (all): Don't make libgdb-files.
+ (libgdb): New action, makes libgdb-files.
+
+Thu Jan 12 21:23:25 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * stabsread.c (read_enum_type): When pending enum symbols are
+ put into the enum type, they must be inserted in "backwards
+ order, in case we've overflowed a struct pending buffer.
+
+
+Thu Jan 12 09:33:24 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * README: Add note about SPARCworks cc release 3.0 and higher.
+
+ Add procfs support for Alpha OSF/1-2.x.
+ * config/alpha/nm-osf.h: Renamed from nm-alpha.h, generic
+ OSF/1 native support.
+ * config/alpha/alpha-osf1.mh (NAT_FILE): Changed accordingly.
+ (MUNCH_DEFINE): Removed.
+ * config/alpha/alpha-osf2.mh, config/alpha/nm-osf2.h: New files
+ for procfs support.
+ * configure.in (alpha-dec-osf*): Use alpha-osf2.mh for OSF/1
+ release 2.x and higher, else alpha-osf1.mh, as the procfs support
+ in release 1.x is incomplete.
+ * Makefile.in (ALLCONFIG): Add config/alpha/alpha-osf2.mh.
+ * alpha-nat.c (supply_gregset, fill_gregset, supply_fpgregset,
+ fill_fpgregset): New routines for procfs support.
+ * inftarg.c (_initialize_inftarg): Don't add ptrace support
+ if we have an optional procfs and /proc is accessible.
+ * procfs.c: Include sys/fault.h and sys/syscall.h before
+ including sys/procfs.h.
+ (unconditionally_kill_inferior): If PROCFS_NEED_PIOCSSIG_FOR_KILL
+ is defined, additionally perform a PIOCSSIG to really terminate
+ the inferior.
+ (create_procinfo): Always return a result.
+ (create_procinfo, do_attach): Don't trace T_IFAULT faults if
+ PROCFS_DONT_TRACE_IFAULT is defined.
+ (procfs_init_inferior): Use START_INFERIOR_TRAPS_EXPECTED as
+ argument to startup_inferior if it is defined.
+ (proc_set_exec_trap): If PIOCSSPCACT is defined, use it instead
+ of tracing exits from exec system calls. Needed for the user level
+ loader under Alpha OSF/1.
+ (do_detach): Clear any pending signal if we want to detach from
+ a process without a signal.
+ (set_proc_siginfo): If PROCFS_DONT_PIOCSSIG_CURSIG is defined,
+ don't issue a PIOCSSIG if pr_cursig already contains the signal we
+ intend to set.
+ (info_proc_signals): If PROCFS_SIGPEND_OFFSET is defined, the
+ pending signals are numbered from 1 instead of 0.
+ (info_proc_mappings): Increase size of output format for addresses
+ if BFD_HOST_64_BIT is defined.
+ (procfs_stop): Renamed from child_stop.
+ (_initialize_procfs): Don't add procfs support if we have an
+ optional procfs and /proc is not accessible.
+
+
+Wed Jan 11 17:53:26 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * array-rom.c: Add support for most commands.
+
+ * monitor.c: Add GDB remote protocol for the hybrid environment on
+ the Array board.
+
+Wed Jan 11 00:44:01 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * command.c (show_user_1): Use print_command_line to show a user
+ defined command (including control structures).
+
+ * top.c (init_main): Change documentation for user defined
+ commands to indicate they may accept up to ten arguments.
+
+Tue Jan 10 16:22:41 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * mips-tdep.c (mips_skip_prologue): Accept or as well as addu for
+ `move $s8, $sp' instruction.
+
+Sun Jan 8 12:45:34 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * target.c, target.h (target_signal_from_command): New function.
+ * infrun.c (handle_command, signals_info), infcmd.c
+ (signal_command): Use it.
+ * infrun.c, infcmd.c: Update docstrings for these commands.
+
+ * target.h (enum target_signal), target.c (signals), target.c
+ (target_signal_from_host, target_signal_to_host): Add
+ TARGET_SIGNAL_REALTIME_* and TARGET_SIGNAL_PRIO for lynx.
+ * config/tm-lynx.h: Define signal numbers for realtime events.
+
+Sat Jan 7 07:23:53 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dbxread.c (process_one_symbol): Handle N_FUN symbols
+ for Sun acc 3.0 under SunOS4.
+
+ Changes to improve handling of runtime common symbols
+ under SunOS4.
+ * minsyms.c (get_symbol_leading_char): New routine to determine
+ the leading symbol character for an objfile.
+ (prim_record_minimal_symbol_and_info, install_minimal_symbols):
+ Use it.
+ * objfiles.h (rt_common_objfile): New global, points to objfile
+ containing the runtime common minimal symbols.
+ * objfiles.c (free_objfile): Mark rt_common_objfile as
+ unallocated before freeing it.
+ * solib.c (allocate_rt_common_objfile): New routine to allocate
+ an objfile for the runtime common minimal symbols.
+ (solib_add_common_symbols): Allocate an objfile for the runtime
+ common symbols if necessary and put common symbols into it.
+ Clean up code and comments.
+ (solib_add, special_symbol_handling): Cleanup comments regarding
+ runtime common symbols.
+ * stabsread.c (scan_file_globals_1): New routine, contains
+ old scan_file_globals code. Checks if there are any unresolved
+ global symbols before starting the expensive minimal symbol table
+ search.
+ (scan_file_globals): Now calls scan_file_globals_1 for the passed
+ objfile and eventually for the runtime common objfile. Complains
+ about any unresolved global symbols and removes them from the
+ global symbol chain to avoid dangling pointers into the symbol
+ table if the symbol table is reread.
+
+Thu Jan 5 17:38:29 1995 Stu Grossman (grossman@cygnus.com)
+
+ * Makefile.in (install_only uninstall): Indent for clarity.
+
+ * core.c (dis_asm_read_memory): Add call to
+ dis_asm_read_memory_hook to provide alternate way for disassembler
+ to read memory.
+
+ * defs.h: Protect from multiple inclusion. Add decl for
+ dis_asm_read_memory_hook.
+
+ * top.c: Make window startup be the default.
+ * Add dis_asm_read_memory_hook.
+
+
+Thu Jan 5 01:16:40 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * stabsread.c (define_symbol): Handle `a' symbol type used for
+ reference parameter passed in a register.
+
+
+Wed Jan 4 12:27:29 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * defs.h: move include tm.h up, so that the type LONGEST can
+ also based on the target requirement to determine. In this case
+ target mips64.
+
+ * remote-os9k.c (rombug_open): catch exception e in rombug.
+ * remote-os9k.c (rombug_wait): print message before register display
+ from rombug.
+
+Wed Jan 4 09:18:27 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * top.c (locate_arg): Call strchr not index.
+
+Tue Jan 3 16:52:03 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * ch-exp.y (literal): Recognize NULL.
+ (tuple): Parse simple unlabelled tuples.
+ * eval.c (evaluate_subexp case OP_ARRAY): Use expect_type to
+ evaluate brace-initializer-expressions depending on context.
+ (evaluate_subexp case UNOP_CAST): Pass the target type as
+ expected type when evaluating the expression.
+
+ * ch-typeprint.c (chill_type_print_base): Get names of PTR and
+ BOOL from TYPE_NAME.
+ * ch-valprint.c (chill_print_type_scalar): New function, to handle
+ TYPE_CODE_RANGE better than print_type_scalar does.
+ (chill_val_print_array_elements): Use above new function.
+
+Mon Jan 2 15:02:51 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-udi.c (udi_load): Tell symbol_file_add that the
+ program being loaded is the main program.
+
+For older changes see ChangeLog-1994
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/ChangeLog-1996 b/gdb/ChangeLog-1996
new file mode 100644
index 00000000000..442386fa764
--- /dev/null
+++ b/gdb/ChangeLog-1996
@@ -0,0 +1,5116 @@
+Tue Dec 31 15:19:32 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/mn10300/tm-mn10300.h: more small register fixes
+
+Tue Dec 31 06:51:43 1996 Mark Alexander <marka@cygnus.com>
+
+ * config/i386/xm-windows.h: Undo previous change to SIGTRAP
+ and SIGQUIT values; it messed up non-MIPS targets.
+ * config/mips/tm-mips.h: Undefine BREAKPOINT, replace
+ with separate LITTLE_BREAKPOINT and BIG_BREAKPOINT definitions;
+ this fixes problem with setting breakpoints in little-endian
+ programs in the simulator.
+
+Mon Dec 30 00:14:06 1996 Doug Evans <dje@seba.cygnus.com>
+
+ * remote-sim.c (gdbsim_open_p): New static local.
+ (gdbsim_open): Call unpush_target if sim open. Set gdbsim_open_p.
+ (gdbsim_close): Only call sim_close if sim open. Reset gdbsim_open_p.
+
+Sun Dec 29 09:15:03 1996 Mark Alexander <marka@cygnus.com>
+
+ * config/i386/xm-windows.h: Make SIGTRAP and SIGQUIT consistent
+ with sim/mips/support.h.
+
+Fri Dec 27 14:53:40 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * v850-tdep.c (struct pifsr): Add cur_frameoffset field.
+ (v850_scan_prologue): Add debug code #ifdef'ed DEBUG. Support new
+ compiler prologues using register save functions and short store
+ instructions. Add support for functions with large stack frames.
+
+ * config/v850/tm-vm850.h ({R0,R1,R12,EP}_REGNUMS): New register
+ number defintiions for r0, r1, r12, ep.
+ (SAVE{1,2,3}_{START,END}_REGNUM): Register number definitions for
+ the 3 sets of saved registers.
+
+Thu Dec 26 19:56:55 1996 Mark Alexander <marka@cygnus.com>
+
+ * valprint.c (print_longest): Don't lose upper bits
+ of 64-bit values on Windows.
+ * config/i386/xm-windows.h: Leave CC_HAS_LONG_LONG defined,
+ undefine PRINTF_HAS_LONG_LONG, so that 64-bit values will
+ be printed without loss of upper bits.
+
+Thu Dec 26 15:15:21 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * config/sparc/tm-sparclet.h: make registers ASR15, ASR19 invisible
+ (they're not useful, you can't change, write or even read them)
+
+Thu Dec 26 15:20:48 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/pa/hppahpux.mh (TERMCAP): Always link to libc before
+ libcurses, to avoid picking up broken select() from libcurses
+ on some versions of HPUX.
+
+Thu Dec 26 15:14:41 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * sparclet-rom.c: Remove includes of Unix system files.
+ Add function "sparclet_supply_register" so that parse_register_dump
+ will not seg-fault by calling a null function pointer.
+ Remove XMODEM support (unfinished work?).
+ Remove flag "MO_HANDLE_NL", so monitor's output can be read by humans.
+ Add fill command.
+ Remove colon from getreg.resp_delim so PSR register will work.
+ Remove pointer to sparclet_load (downloading SREC's doesn't work).
+ Null out local register names for %g0, all %cc and all %asr regs,
+ since the monitor can't report them. Will return zero instead.
+ * sparclet-stub.c: New -- remote protocol support for sparclet CPU.
+ * config/sparc/tm-sparclet.h: Re-arrange REGISTER_NAMES:
+ Add back %g0 and %psr, add %cc coprocessor regs, add %asr regs.
+ Adjust NUM_REGS and REGISTER_BYTES accordingly
+
+Tue Dec 24 10:27:37 1996 Jeffrey A Law (law@cygnus.com)
+
+ * remote-e7000.c (want_h8300h, want_nopc_h8300h): Renamed
+ from want and want_nopc.
+ (want_h8300s, want_nopc_h8300s): New variables for H8/S register
+ lists.
+ (e7000_fetch_registers): Use H8/300H or H8/S register list string
+ as needed.
+ (e7000_wait): Likewise.
+
+Mon Dec 23 02:25:58 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mips-tdep.c (mips_find_saved_regs): If a frame has been
+ interrupted by a signal, figure out whether the registers that
+ the proc_desc claims are saved have been saved yet.
+ (mips_push_dummy_frame): Write dummy frame register after all
+ registers have been saved in the dummy frame. Update comments
+ to reflect the fact that we are now using an AT_ENTRY_POINT
+ call dummy.
+
+Sun Dec 22 15:52:25 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-tdep.c (d10v_skip_prologue): PR11287. Fix problem where
+ some breakpoints weren't being set.
+
+Sat Dec 21 12:57:59 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/mips/tm-mips.h (PC_IN_CALL_DUMMY): Removed, the default
+ definition in inferior.h is sufficient.
+ * mips-tdep.c (mips_pc_in_call_dummy): Ditto.
+ (mips_push_arguments): Make sure that the stack is aligned to a
+ multiple of 8 after the arguments are pushed.
+ Structures are always passed by value in the old ABI.
+ Adjust argument register value on big endian targets when passing
+ a value whose length is less than the register size.
+ Write stack arguments with a single write_memory call.
+ (mips_pop_frame): Use frame_saved_regs instead of proc_desc to
+ decide which registers have to be restored.
+
+ * irix5-nat.c (fill_gregset): Sign extend registers before
+ filling in the gregset structure.
+
+Fri Dec 20 11:06:03 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * mswin/genmakes: Don't define _DEBUG. This breaks wingdb.
+
+Thu Dec 19 19:42:44 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * v850-tdep.c (v850_scan_prologue): Deal with -mep shorting
+ register saves by using the ep register.
+
+Thu Dec 19 15:57:16 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * m32r-tdep.c (m32r_frame_find_saved_regs): Fix thinko in arg def.
+
+Thu Dec 19 09:38:56 1996 Mark Alexander <marka@cygnus.com>
+
+ * values.c (unpack_double): Make it compile with MSVC++ 2.x.
+ * remote-mips.c (S_IROTH): Define if not defined by stat.h, e.g.
+ when using MSVC++.
+ (common_open): Fix help string.
+
+Wed Dec 18 23:01:32 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Use NewFolderRecursive for installation.
+
+Sat Dec 14 20:50:01 1996 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mips_push_arguments): Handle floating point args.
+ * config/mips/tm-mips.h (FIX_CALL_DUMMY): Define to set up $25
+ correctly for PIC on Irix 5.
+
+Sat Dec 14 09:52:30 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * i386-tdep.c (i386_frame_find_saved_regs): Handle zero return
+ from get_pc_function_start gracefully.
+
+Sat Dec 14 00:43:57 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * c-exp.y (qualified_name): Replace explicit check for valid
+ destructor name with call to destructor_name_p.
+
+ * c-lang.h, c-typeprint.c (cp_type_print_method_args): Removed,
+ no longer needed.
+
+ * c-typeprint.c (c_type_print_varspec_prefix, c_type_print_base):
+ Replace remaining fprintf_unfiltered calls with their filtered variant.
+ (c_type_print_base): Do not print return type for destructors from
+ template classes.
+ Replace cp_type_print_method_args with cplus_demangle call to get
+ consistent type output for stubbed and unstubbed methods.
+
+ * cp-valprint.c (cp_print_class_method): Replace
+ cp_type_print_method_args with cplus_demangle call to get consistent
+ type output for stubbed and unstubbed methods.
+
+ * gdbtypes.c, gdbtypes.h (get_destructor_fn_field): New function
+ to find the destructor field indices for a type.
+
+ * gdbtypes.h (struct type): Clarify comments for vptr_basetype
+ and arg_types fields.
+ (struct fn_field): Remove args field, no longer used.
+
+ * symtab.c (decode_line_1), valops.c (value_struct_elt,
+ check_field_in): Use get_destructor_fn_field to find the destructor
+ field indices instead of assuming that the compiler passes the member
+ function fields in a specific order.
+
+ * symtab.c (find_methods): Pass NULL instead of SYMBOL_BLOCK_VALUE
+ to lookup_symbol.
+ (list_symbol): Replace cp_type_print_method_args with cplus_demangle
+ call in zapped out code and explain why this code is zapped out.
+
+Thu Dec 12 13:29:14 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/powerpc/ppc{,le}-sim.mt (SIM): Add the simulator common
+ library ../sim/common/libcommon.a.
+
+Wed Dec 11 11:15:08 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * monitor.c (monitor_load): Add support for load address argument.
+ * dsrec.c: #include <time.h>.
+ (load_srec): New argument load_offset. Print download stats.
+ * srec.h (load_srec): Update prototype.
+ * sh3-rom.c (sh3_load): Update call to load_srec.
+
+Mon Dec 9 17:34:05 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/mn10300/tm-mn10300.h: more small register fixes
+ * mn10300-tdep.c: filled in from another target
+
+Mon Dec 9 17:12:19 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * monitor.c (monitor_insert_breakpoint): Handle bi-endian machines.
+
+Mon Dec 9 15:58:51 1996 Mark Alexander <marka@cygnus.com>
+
+ * config/mips/tm-mips.h: Get rid of call-dummy code.
+ Minor changes to make pre-ANSI compilers happy.
+ * mips-tdep.c: Minor changes to make pre-ANSI compilers happy.
+ (mips_push_arguments): Rewrite to partially support EABI.
+ (mips_pc_in_call_dummy): New function.
+ * infcmd.c: Include symfile.h to get prototype of entry_point_address,
+ which fixes 64-bit sign extension bug on MIPS.
+
+Mon Dec 9 00:14:49 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/mn10300/tm-mn10300.h: fix register names
+ * mn10300-tdep.c: new skeleton tdep for mn10300
+
+Sun Dec 8 18:02:57 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * remote-sim.h: Update some comments.
+ * remote-sim.c (gdb_os_error): New function.
+ (init_callbacks): Fix initializing of gdb_callback. Add gdb_os_error.
+ (gdb_os_printf_filtered): Use gdb_stdout, not stdout.
+
+Sun Dec 8 00:36:31 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * irix5-nat.c (supply_gregset, fill_gregset): Handle gregsets
+ from O32 and N32 ABI.
+ (xfer_link_map_member): Work around problem with alignments
+ in struct obj when compiling GDB under N32 ABI.
+
+Thu Dec 5 23:30:44 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * d10v-tdep.c: Add support for examination and interpretation
+ of instruction trace buffer.
+ (trace, untrace, info trace, tdisassemble): New commands.
+
+Thu Dec 5 14:06:23 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/sparc/tm-sparclet.h (TARGET_BYTE_ORDER): Undef.
+ (TARGET_BYTE_ORDER_SELECTABLE): Define.
+ (BREAKPOINT): Undef.
+ ({BIG,LITTLE}_BREAKPOINT): Define.
+ (TM_PRINT_INSN_MACH): Redefine for sparclet.
+
+Wed Dec 4 16:34:05 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/mn10300/mn10300.mt, config/mn10300/tm-mn10300.h: New.
+
+Tue Dec 3 13:02:08 1996 Fred Fish <fnf@ninemoons.com>
+
+ * infptrace.c (store_inferior_registers): Move some common code out
+ to store_register, like fetch_inferior_registers & fetch_register.
+ (store_register): New function, from store_inferior_registers.
+ (fetch_inferior_registers, fetch_register): Minor code tweaks to
+ make {fetch,store}_inferior_registers and {fetch,store}_register
+ routines as similar in structure as possible.
+ (fetch_inferior_registers, store_inferior_registers): Eliminate
+ local variable numregs and just use ARCH_NUM_REGS directly.
+
+Tue Dec 3 11:38:14 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * blockframe.c: add macro USE_GENERIC_DUMMY_FRAMES to enable/disable
+ code for generic call_dummy frames.
+ * config/h8300/tm-h8300.h: turn on USE_GENERIC_DUMMY_FRAMES
+ * config/m32r/tm-m32r.h: Ditto.
+ * config/sh/tm-sh.h: Ditto.
+ * config/v850/tm-v850.h: Ditto.
+
+Sun Dec 1 00:41:47 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * vax-tdep.c (vax_print_insn, print_insn_arg): Use info functions
+ for printing. From Valeriy Ushakov <uwe@ptc.spbu.ru>.
+
+Sun Dec 1 00:40:46 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.tgt: Add new mn10300 entry.
+
+Sun Dec 1 00:18:59 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ Add support for Irix 6.2 native O32 and N32 ABI.
+
+ * config.in, configure.in, configure: Check for <objlist.h>.
+ * configure.tgt: Handle mips*-sgi-irix6* like irix5 for now.
+
+ * cp-valprint.c (cp_print_value_fields): Use SYMBOL_VALUE_ADDRESS
+ instead of SYMBOL_BLOCK_VALUE to get the address of a static member.
+
+ * dwarf2read.c: Turn warnings and recoverable errors into complaints,
+ add new complaints where appropriate.
+ gcc -Wall cleanup.
+ (struct line_head): Change line_base from char to int to avoid
+ problems with compilers whose plain char is represented by an
+ unsigned char.
+ (struct partial_die_info): Add is_declaration field.
+ (dwarf2_tmp_obstack): New obstack for allocating temporary storage
+ used during symbol reading.
+ (cu_header_offset): New variable for resolving relative reference
+ dies.
+ (optimized_out, basereg, islocal, frame_base_reg, frame_base_offset):
+ New interface variables for decode_locdesc.
+ (struct dwarf2_pinfo): New structure for communication between
+ psymtab and symtab reading, passed via pst->read_symtab_private.
+ (dwarf2_has_info, dwarf2_build_psymtabs): Accept objects files
+ without line number sections.
+ (dwarf2_build_psymtabs_hard): Initialize temporary obstack
+ for symbol reading.
+ Allocate and initialize pst->read_symtab_private.
+ Relocate pst->textlow and pst->texthigh with baseaddr.
+ (scan_partial_symbols): Do not add DW_AT_declaration symbols
+ to the partial symbol table.
+ Add file scope enumerator symbols to the partial symbol table.
+ Fix typo in highpc computation.
+ If we didn't find a lowpc, set it to highpc to avoid complaints
+ from `maint check.
+ (add_partial_symbol): Relocate symbol values with baseaddr.
+ Add static DW_TAG_subprogram and DW_TAG_variable symbols to the
+ minimal symbol table.
+ Obtain symbol values for DW_TAG_variable symbols from the location
+ descriptor, skip symbols with missing location desciptors.
+ Skip symbols for aggregate types without children.
+ Handle enumerator symbols.
+ (dwarf2_psymtab_to_symtab): Issue symbol reading message if verbose.
+ (psymtab_to_symtab_1): Set local variables from
+ pst->read_symtab_private, set cu_header_offset and baseaddr.
+ Initialize temporary obstack for symbol reading, initialize
+ buildsym and add a cleanup to really_free_pendings.
+ Relocate highpc with baseaddr when calling end_symtab.
+ If the compilation is from a C file generated by language
+ preprocessors, do not set the symtab language if it was already
+ deduced by start_subfile.
+ Removed verbose sorting symbol table message.
+ (process_die): Handle DW_TAG_ptr_to_member_type and
+ DW_TAG_reference_type.
+ Use read_subroutine_type to get the function type for
+ DW_TAG_subprogram before calling read_func_scope.
+ (read_file_scope): Initialize file name to <unknown>, start_subfile
+ expects a non-NULL name.
+ If we didn't find a lowpc, set it to highpc to avoid complaints
+ from finish_symbol.
+ Relocate lowpc and highpc with baseaddr.
+ Get rid of Irix6.2 native cc compile machine prefix in comp_dir.
+ Zero out ftypes for each new compilation unit (may be different
+ language or different objfile).
+ Accept compilation units without line number information, pass
+ comp_dir to decode_lines.
+ (read_func_scope): Initialize function name to <unknown> to avoid
+ core dumps when DW_AT_name is missing.
+ Relocate lowpc and highpc with baseaddr.
+ Handle DW_AT_frame_base, keep result for DW_OP_fbreg operations.
+ Pass function type to new_symbol.
+ (read_lexical_block_scope): Relocate lowpc and highpc with baseaddr.
+ (read_structure_scope): Set TYPE_TAG_NAME, not TYPE_NAME.
+ Handle DW_TAG_class_type.
+ Copy fields to type_obstack, release temporary storage for fields.
+ Don't add symbol if die is a stub die and has no children.
+ Handle C++ static member fields.
+ (read_enumeration): Set TYPE_TAG_NAME, not TYPE_NAME.
+ Copy fields to type_obstack, release temporary storage for fields.
+ Let new_symbol handle the symbol creation for enumerators
+ instead of handcrafting a symbol.
+ Determine signedness of enum type from enumerators.
+ (dwarf_read_array_type): Handle variable length arrays.
+ Use lookup_pointer_type instead of handcrafting a type.
+ Create array type only if a DW_TAG_subrange_type was found.
+ (read_tag_pointer_type, read_tag_reference_type):
+ Use lookup_pointer_type and lookup_reference_type instead
+ of handcrafting a type.
+ (read_tag_ptr_to_member_type): New function to handle
+ DW_TAG_ptr_to_member_type.
+ (read_subroutine_type): Handle parameter dies.
+ Use lookup_function_type instead of handcrafting a type.
+ (read_typedef): Allocate a TYPE_CODE_TYPEDEF type for the typedef.
+ (read_base_type): If the type has a name, use init_type to create
+ a new type instead of second guessing a fundamental type.
+ (read_comp_unit): Reset die reference table before building
+ a new one.
+ (dwarf2_read_section): Read section contents into psymbol_obstack.
+ (dwarf2_read_abbrevs): Handle unterminated abbreviations
+ for a compile unit gracefully.
+ (read_partial_die): Zero partial die before reading its info.
+ Handle DW_AT_declaration.
+ Fix typo in handling of DW_FORM_block4.
+ (read_full_die): Fix typo in handling of DW_FORM_block4.
+ (read_1_signed_byte, read_2_signed_bytes, read_4_signed_bytes):
+ New routines to get signed values from a buffer.
+ (read_n_bytes, read_string): Allocate storage from the temporary
+ obstack. If the host char size permits it, return pointer
+ to buffer instead of allocating storage.
+ (set_cu_language): Handle DW_LANG_Mips_Assembler.
+ (dwarf_attr): Return NULL if reference die for DW_AT_specification
+ or DW_AT_abstract_origin die is not found.
+ (record_minimal_symbol): Removed, replaced with a direct call to
+ prim_record_minimal_symbol, it now handles saving the string itself.
+ (convert_locdesc): Removed, partial symtab reading now uses
+ decode_locdesc.
+ (dwarf_attr): Use dwarf2_get_ref_die_offset to get the absolute
+ offset for the die reference.
+ (dwarf_decode_lines): Complain if the line section info is missing.
+ Use read_1_signed_byte to extract lh.line_base to avoid
+ problems with compilers whose plain char is represented by an
+ unsigned char.
+ Add cleanups for allocated temporary storage.
+ Start a subfile for the first file in the state machine.
+ Fix off by one problem with dirs.dirs access.
+ Use comp_dir when directory index is 0.
+ Support multiple sequences (from Jason Merrill <jason@cygnus.com>).
+ (dwarf2_start_subfile): Try to keep line numbers from identical
+ absolute and relative file names in a common subfile.
+ (new_symbol): Allocate symbol and symbol name on the symbol_obstack.
+ Set SYMBOL_LINE from DW_AT_decl_line if present.
+ Set SYMBOL_TYPE from passed type if not NULL.
+ Change DW_TAG_variable symbol types with missing type entries
+ to a sensible type.
+ Handle optimized_out, offreg and islocal storage classes.
+ Add external symbols with type information whose address isn't
+ known as LOC_UNRESOLVED symbols.
+ Synthesize typedefs for C++ classes, structs, unions and enumerations.
+ Handle DW_TAG_enumerator symbols, complain for unrecognized
+ symbol tags.
+ (die_type): A missing DW_AT_type represents a void type.
+ Use dwarf2_get_ref_die_offset to get the absolute offset for
+ the die reference.
+ (die_containing_type): New function to build type from
+ DW_AT_containing_type attribut.
+ (read_type_die): Handle DW_TAG_ptr_to_member_type.
+ Treat DW_TAG_subprogram like DW_TAG_subroutine_type.
+ (dwarf_base_type): Fix typo with creation of FT_UNSIGNED_SHORT
+ fundamental type.
+ (create_name): Removed, symbol name allocation is now done
+ in new_symbol.
+ (dump_die): Use print_address_numeric to print a CORE_ADDR.
+ (dwarf2_empty_die_ref_table): New function to clear the die
+ reference table.
+ (dwarf2_get_ref_die_offset): New function to get the absolute
+ die offset from a die reference attribute.
+ (decode_locdesc): Complete rewrite using a stack, code mostly
+ borrowed from dwarfread.c:locval.
+ (dwarf_alloc_type): Removed, replaced by direct calls to alloc_type.
+ (dwarf_alloc_block): Allocate block on temporary obstack.
+
+ * elfread.c (elf_symtab_read): When handling Irix dynamic symbols,
+ skip section name symbols and relocate all others.
+ (elf_symfile_read): Build dwarf2 psymtab even if offset is non-zero.
+
+ * irix5-nat.c (fetch_core_registers): Handle core_reg_sect
+ from N32 executables. Call registers_fetched after extracting
+ the registers.
+ (obj_list_variant, struct link_map, LM_OFFSET, LM_ADDR): New
+ definitions to enable support of O32 and N32 format objlists.
+ (struct so_list): New members offset, so_name and lmstart to
+ eliminate dependencies from the objlist format used.
+ (solib_map_sections, symbol_add_stub, solib_add,
+ info_sharedlibrary_command, solib_address, clear_solib): Use
+ so_name and LM_OFFSET.
+ (first_link_map_member): Rewrite to enable support of O32 and N32
+ format objlists.
+ (next_link_map_member, xfer_link_map_member): New functions to
+ support O32 and N32 format objlists.
+ (find_solib): Use first_link_map_member, next_link_map_member and
+ xfer_link_map_member.
+ (solib_create_inferior_hook): Use TARGET_SIGNAL_* instead of
+ host signal numbers.
+
+ * mdebugread.c (parse_partial_symbols, handle_psymbol_enumerators):
+ Pass CORE_ADDR variant to add_psymbol_to_list.
+
+ * mips-tdep.c (heuristic_proc_desc): Stop examining the prologue
+ if we encounter a positive stack adjustment. Handle `move $30,$sp'.
+ Handle `sd reg,offset($sp)' for 32 bit ABIs.
+
+ * symmisc.c (dump_msymbols, print_partial_symbols): Use
+ print_address_numeric to print a SYMBOL_VALUE_ADDRESS.
+ (dump_symtab): Print compilation directory if it is not NULL.
+
+ * valops.c (search_struct_field, value_struct_elt_for_reference):
+ Use SYMBOL_VALUE_ADDRESS instead of SYMBOL_BLOCK_VALUE to get the
+ address of a static member.
+
+Thu Nov 28 00:46:24 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * vax-tdep.c (vax_print_insn): Made static, modified to take
+ disassemble_info as parameter.
+ (_initialize_vax_tdep): New function to initialize tm_print_insn
+ to vax_print_insn.
+
+Wed Nov 27 11:29:06 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * blockframe.c: Remove old-style CALL_DUMMY code.
+ * h8300-tdep.c, config/h8300/tm-h8300.h: Ditto.
+ * m32r-tdep.c, config/m32r/tm-m32r.h: Ditto.
+ * sh-tdep.c, config/sh/tm-sh.h: Ditto.
+ * v850-tdep.c, config/v850/tm-v850.h: Ditto.
+
+Wed Nov 27 10:32:14 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * breakpoint.c: DELETE command will not delete CALL_DUMMY breakpoint.
+ * blockframe.c: Add target-independant support for managing
+ CALL_DUMMY frames on the host side.
+ * frame.h: Declarations for generic CALL_DUMMY frame support.
+ * h8300-tdep.c: Add target function calls using generic frame support.
+ * config/h8300/tm-h8300.h: config for generic target function calls.
+ * m32r-tdep.c: Add target function calls using generic frame support.
+ * config/m32r/tm-m32r.h: config for generic target function calls.
+ * sh-tdep.c: Add target function calls using generic frame support.
+ * config/sh/tm-sh.h: config for generic target function calls.
+ * v850-tdep.c: Add target function calls using generic frame support.
+ * config/v850/tm-v850.h: config for generic target function calls.
+ * valops.c: ADD PUSH_RETURN_ADDRESS so that it doesn't have to be
+ done by PUSH_ARGUMENTS when there's no CALL_DUMMY.
+
+Tue Nov 26 19:21:35 1996 Mark Alexander <marka@cygnus.com>
+
+ * config/mips/tm-mips.h (ADDR_BITS_REMOVE, TARGET_READ_SP): Define.
+ (mips_addr_bits_remove): Declare.
+ * mips-tdep.c (mips_push_dummy_frame): Fix heuristic-fence-post
+ errors when hitting breakpoints during inferior function calls
+ in 64-bit programs.
+ (fix_sign_extension): Make public, rename to mips_addr_bits_remove.
+ * utils.c (paddr_nz, preg_nz): New functions, similar to
+ paddr and preg but don't print leading zeroes.
+ * defs.h (paddr_nz, preg_nz): Declare.
+ * remote-mips.c: Use paddr_nz instead of paddr throughout
+ to reduce packet size.
+ (pmon_end_download): Improve timeout error handling.
+
+Tue Nov 26 17:21:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.12.
+
+Mon Nov 25 13:17:16 1996 Fred Fish <fnf@ninemoons.com>
+
+ From: Paul Eggert <eggert@twinsun.com>
+ * remote-bug.c (wait_strings): Avoid creating a trigraph.
+
+Fri Nov 22 15:55:22 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * valops.c (value_at, value_fetch_lazy): Put in D10V call
+ to fix up address pointers.
+ * values.c (value_from_longest): Removed previous d10v changes.
+ * config/d10v/tm-d10v.h (TARGET_PTR_BIT): Change to 4 bytes.
+
+Fri Nov 22 10:06:19 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/i386/nm-i386v4.h (LOSING_POLL): Define, needed for
+ Unixware 1.1.2.
+
+Thu Nov 21 19:13:58 1996 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c: Replace hard-coded constants with MIPS_INSTLEN.
+ (common_breakpoint): Use paddr instead of %x to print 64-bit values.
+ (heuristic_proc_desc): Add tests for 64-bit instructions.
+ (init_extra_frame_info, mips_push_arguments): Recognize additional
+ registers for EABI.
+ * remote-mips.c: Extend DDB target to allow TFTP downloads.
+ * config/mips/tm-mips.h (MIPS_LAST_ARG_REGNUM, MIPS_NUM_ARG_REGS):
+ Define.
+
+Wed Nov 20 19:09:16 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * infcmd.c (do_registers_info): Call val_print with the
+ virtual buf instead of the raw buf. Needed for REGISTER_CONVERT
+ to work with non-floating point regs.
+
+ * d10v-tdep.c (d10v_skip_prologue): If we have line debugging
+ information, then the end of the prologue should the first
+ assembly instruction of the first source line.
+
+ * values.c (value_from_longest): Put in D10V call to
+ fix up address pointers.
+
+ * config/d10v/tm-d10v.h (REGISTER_VIRTUAL_SIZE): Modified.
+ (REGISTER_VIRTUAL_TYPE): Modified for PC_REGNUM and SP_REGNUM.
+ (REGISTER_CONVERTIBLE): Make PC and SP convertible.
+ (REGISTER_CONVERT_TO_VIRTUAL): Define.
+ (REGISTER_CONVERT_TO_RAW): Define.
+ (D10V_MAKE_DADDR): Define.
+ (D10V_MAKE_IADDR): Define.
+
+Wed Nov 20 16:15:15 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/i386/cygwin32.mh: add MMALLOC_CFLAGS = -I$(MMALLOC_SRC)
+ -DMMCHECK_FORCE=1 so memory checks are loaded for cygwin32 gdb
+
+Wed Nov 20 00:43:09 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * callback.h: Delete, moved to ../include.
+ * callback.c: Delete, moved to ../sim/common.
+ * Makefile.in (SFILES,COMMON_OBJS): Delete callback.[co].
+ (callback.o): Delete rule.
+ * remote-sim.h: No longer include callback.h.
+ (sim_callback_write_stdout): Delete prototype.
+ * remote-sim.c (init_callbacks,end_callbacks): New functions.
+ (gdb_os_write_stdout, gdb_os_printf_filtered): New functions.
+ (gdb_callback, callbacks_initialized): New static globals.
+ (gdbsim_open): Call init_callbacks.
+ (gdbsim_close): Call end_callbacks.
+ (simulator_command): Call init_callbacks.
+
+ * config/h8300/h8300.mt (SIM): Change to ../sim/h8300/libsim.a.
+ * config/h8500/h8500.mt (SIM): Change to ../sim/h8500/libsim.a.
+
+Mon Nov 18 15:58:05 1996 Jim Wilson <wilson@cygnus.com>
+
+ * config/mips/tm-mips.h (FIX_CALL_DUMMY): Change unsigned LONGEST
+ to ULONGEST.
+
+Fri Nov 15 15:34:18 1996 Fred Fish <fnf@cygnus.com>
+
+ From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
+ * procfs.c (wait_fd): Handle EINTR error return from poll
+ by restarting the poll.
+ * defs.h (PIDGET): Define a default version that just
+ returns its argument unchanged.
+ * inflow.c (terminal_init_inferior): Eliminate #ifdef
+ of PIDGET and fold both alternatives into common code.
+ (pass_signal): Use PIDGET for pid passed to kill().
+
+Thu Nov 14 15:54:20 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * utils.c (paddr,preg): Use a static variable initialized to 32
+ instead of doing addr>>32 to eliminate a warning produced by GCC
+ on 32-bit systems.
+
+ * config/d10v/tm-d10v.h (ULONGEST): Define.
+
+Tue Nov 12 12:25:27 1996 Jim Wilson <wilson@cygnus.com>
+
+ * c-typeprint.c (cp_type_print_method_args): Pass -1 for show in
+ recursive call to type_print.
+
+Tue Nov 12 12:18:29 1996 Jim Wilson <wilson@cygnus.com>
+
+ * defs.h (ULONGEST): New macro.
+ * alpha-tdep.c, breakpoint.c, c-exp.y, ch-exp.c, convex-xdep.c,
+ corefile.c, defs.h, f-exp.y, findvar.c, gdbcore.h, m2-exp.y,
+ m88k-tdep.c, printcmd.c, remote-hms.c, remote-mips.c, sparc-tdep.c,
+ valarith.c, valops.c, values.c, config/gould/tm-np1.h,
+ config/mips/tm-mips.h, mswin/prebuilt/gdb/cexptab.c,
+ mswin/prebuilt/gdb/fexptab.c, mswin/prebuilt/gdb/m2exptab.c:
+ Change all occurances of unsigned LONGEST to ULONGEST.
+
+ * configure.host (mips-sgi-irix6): Add.
+
+Tue Nov 12 12:16:40 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * sh-tdep.c: Add functionality for target function calls.
+ * config/sh/tm-sh.h: Add support for target function calls.
+
+Tue Nov 12 12:06:58 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * m32r-tdep.c: Add functionality for target function calls.
+ * valops.c: Small change to support target function calls.
+ * config/m32r/tm-m32r.h: Add support for target function calls.
+
+Mon Nov 11 17:15:59 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * defs.h: Modify Nov 11 12:59:00 change so _MSC_VER is checked
+ instead of _WIN32.
+ * win32-nat.c: Fix Nov 11 12:59:00 change (windows.h should
+ be included instead of windefs.h for compilers other than
+ VC++).
+ * mswin/windefs.h: Remove ^Ms and change C++ style comments
+ to C style comments.
+
+Mon Nov 11 14:32:38 1996 Mark Alexander <marka@cygnus.com>
+
+ * utils.c (get_cell): Fix off-by-one bug.
+ * mips-tdep.c (get_frame_pointer, fix_sign_extension):
+ New functions to consolidate common code.
+ (mips_frame_chain, init_extra_frame_info): Use new functions
+ to fix problems with backtrace and finish commands on ddb board.
+
+Mon Nov 11 12:59:00 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * mips-tdep.c, remote-mips.c, values.c, mdebugread.c,
+ config/mips/tm-mips.h: Add/fix bugs for 64-bit mips support.
+ * defs.h: Cleanup; add prototypes.
+ * corefile.c: Change FIXME #ifdef
+ * win32-nat.c: Include windefs instead of windows.h.
+ * utils.c: Add routines for printing addresses and registers
+ based on type size.
+
+Sat Nov 9 01:05:10 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * alpha-tdep.c (heuristic_proc_desc): Stop examining the prologue
+ if we encounter a positive stack adjustment.
+ (find_proc_desc): If heuristic_fence_post is non-zero, use
+ heuristic_proc_start to determine the start of a function before
+ calling heuristic_proc_desc.
+
+ * coffread.c (coff_symtab_read): Change minimal symbol types
+ for C_LABEL symbols from mst_* to mst_file_*.
+
+ * config/m68k/sun3os4.mh (MMALLOC_CFLAGS): Define MMCHECK_FORCE to 1.
+
+ * configure.in: Handle error message from sun3 native ld when
+ configuring HLDFLAGS.
+ * configure: Regenerated with autoconf.
+
+ * c-valprint.c (c_value_print): Adjust value address by VALUE_OFFSET.
+ * cp-valprint.c (cp_print_value): Prevent gdb crashes by making sure
+ that the virtual base pointer from an user object still points to
+ accessible memory.
+
+ * dbxread.c (dbx_symfile_init): Initialize sym_stab_info to
+ clear the recently added header_files fields.
+ (dbx_symfile_finish): Free hfiles[i].vector to avoid storage leak.
+
+Fri Nov 8 14:30:23 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * config/tm-sh.h: Added a missing comma in middle of
+ REGISTER_NAMES list.
+
+Fri Nov 8 12:29:51 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * monitor.c: Fix some formatting and comments.
+
+ * remote-sim.c (simulator_command): Set up callbacks before
+ entering the simulator.
+
+Thu Nov 7 15:19:08 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-tdep.c: Fix some problems with inferior function calls.
+ * config/d10v/tm-d10v.h (EXTRA_FRAME_INFO): Change dummy to be
+ a pointer to the dummy's stack instead of just a flag.
+
+Tue Nov 5 10:21:02 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * m32r-tdep.c: Improved frame_chain and fn prologue analysis.
+ * config/tm-m32r.h: Add framesize and register to extra_frame_info.
+
+Tue Nov 5 10:08:07 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * mswin/gdbwin.h: Remove bogus definition of CORE_ADDR.
+ * mswin/srcwin.cpp (CSrcScroll1::CSrcScroll1): Initialize depth
+ to fix divide-by-zero problem with clicking on source window.
+
+Mon Nov 4 00:48:37 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * mswin/recordit: Fix problem with absolute paths.
+ * mswin/recordit: Fix problem with relative paths.
+
+Sun Nov 3 18:06:42 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * mswin/{Makefile.in configure configure.in}: New files for
+ configuring wingdb under Unix.
+
+Sat Nov 2 03:54:13 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * irix5-nat.c, osfsolib.c, solib.c (symbol_add_stub): Handle
+ missing or zero-sized .text sections properly.
+ * mdebugread.c: Handle scRConst and scSUndefined storage classes.
+ * stabsread.c (scan_file_globals): Try to resolve symbols
+ for shared libraries from the minimal symbol table of the main
+ executable first.
+
+Fri Nov 1 13:59:28 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-tdep.c, config/d10v/tm-d10v.h: Major fixes to support
+ inferior function calls and proper stack backtracing on D10V-EVA
+ board.
+
+Fri Nov 1 10:50:51 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/powerpc/linux.mh (NATDEPFILES): Fix up things so that it
+ links.
+ (GDBSERVER_DEPFILES,TERMCAP): Ditto.
+
+ * monitor.c (dev_name,targ_ops): Move static variables before
+ first use, to avoid compiler warnings.
+
+Thu Oct 31 16:37:17 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * m32r-tdep.c: Improved frame_chain and fn prologue analysis.
+ * configure.tgt: Add entry for m32r target.
+ * monitor.h: Add a flag to tell monitor_store_register to use
+ (val, regno) instead of (regno, val).
+ * monitor.c: Make monitor_store_register honor the above flag.
+ Make monitor_exp ignore DC1/DC3 for m32r.
+ Increase buf size in monitor_dump_regs.
+
+Wed Oct 30 18:14:14 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * m32r-tdep.c, m32r-rom.c: New files.
+ * config/m32r/m32r.mt: New file.
+ * config/m32r/tm-m32r.h: New file.
+
+Tue Oct 29 16:56:01 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/i386/xm-cygwin32.h:
+ * config/powerpc/xm-cygwin32.h:
+ add #define LSEEK_NOT_LINEAR so source lines aren't unexpectedly
+ truncated.
+
+Tue Oct 29 18:36:43 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/powerpc/tm-ppc-eabi.h (TARGET_BYTE_ORDER_SELECTABLE):
+ Define.
+
+Tue Oct 29 14:59:20 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * TODO: Add item suggesting an "info bfd" command.
+
+Tue Oct 29 12:48:04 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-tdep.c: Snapshot that supports D10V-EVA board.
+
+ * config/d10v/tm-d10v.h (REGISTER_NAMES): Add imap0,imap1,dmap.
+ (TARGET_READ_FP,TARGET_WRITE_FP): Define.
+
+Mon Oct 28 17:34:24 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * mswin/genmakes mswin/recordit: New scripts to generate make
+ files for MSVC.
+
+Sun Oct 27 20:18:04 1996 Mark Alexander <marka@cygnus.com>
+
+ * config/mips/{tm-vr5000.h,tm-vr5000el.h,vr5000.mt,vr5000el.mt}:
+ New files.
+ * configure.tgt: Modify cases for vr5000 to use new files.
+
+Sat Oct 26 07:15:14 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/alpha/alpha-osf3.mh (XM_CLIBS): Add -lm for OSF/1-4.0.
+
+ * procfs.c (proc_set_exec_trap): Under Alpha OSF/1-4.0, tracing
+ the entry to the exit system call to detect termination of the
+ inferior stopped working. Trace termination of the inferior via
+ PRFS_STOPTERM instead.
+ (procfs_init_inferior): Do not trace entry to exit system call
+ if PIOCSSPCACT is defined.
+ (procfs_wait): Handle PR_DEAD event, which signals the termination
+ of the inferior if PRFS_STOPTERM is set.
+
+ * mdebugread.c (parse_partial_symbols): Ignore stNil section
+ start address symbols.
+
+ * sparc-tdep.c (get_saved_register): Get saved PC from the
+ frame info if not in innermost frame.
+
+Thu Oct 24 10:51:45 1996 Mark Alexander <marka@cygnus.com>
+
+ * dbxread.c (process_one_symbol): Interpret end-of-function
+ markers correctly; this fixes problem on Vr5000 where all
+ functions in a module had the same address.
+ * configure.in, configure.tgt, configure.host, gdbserver/configure.in:
+ Correct for pc-linux-gnu problem in config.guess.
+ * configure: Regenerate.
+
+Thu Oct 24 10:06:58 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * dbxread.c: Don't swap symbols in place, since internal and
+ external forms may have different sizes. Don't assume that an
+ internal_nlist has the same layout as an external_nlist. Create
+ symbol for n_strx element so to hide specifics of nlist from
+ partial-stab.h.
+ * partial-stab.h: Don't reference dbxread symbols directly. Use
+ CUR_SYMBOL_STRX instead.
+ * config/i386/xm-windows.h: Define SIGQUIT and SIGTRAP.
+
+ * config/v850/tm-v850.h: Define PS_REGNUM and TARGET_V850 for
+ MSVC builds.
+ * mswin/gdbwin.c (reg_order): Define register order for V850.
+ * mswin/gui.cpp (CGuiApp::InitInstance): Define target name for
+ V850.
+ * mswin/regdoc.h: Define MAXREGS for V850.
+
+Tue Oct 22 16:28:20 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * v850-tdep.c (scan_prologue): Changes to deal with scheduled
+ prologues correctly. First, prologue end is now defined by
+ presence of a branch, jump or call insn. Second, can no longer
+ fix frame offsets because we may not know the offset until after a
+ register has been saved.
+ * (v850_init_extra_frame_info): Fixup frame offsets here because
+ we have all the info at this time.
+ * (v850_frame_chain): Use new calling convention for scan_prologue.
+
+Tue Oct 22 10:25:29 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-tdep.c, config/d10v/tm-d10v.h: Changes to allow stack
+ backtraces and inferior function calls.
+
+Tue Oct 22 10:32:46 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Update init.c editing to work with Oct 8 change.
+ (@HLDFLAGS@): Always edit out.
+
+Mon Oct 21 18:17:08 1996 Mark Alexander <marka@cygnus.com>
+
+ * mdebugread.c (parse_partial_symbols): Fix 64-bit
+ sign-extension problems in calculating psymtab addresses.
+ * buildsym.c (end_symtab): Use macro to pop context.
+
+Mon Oct 21 14:40:50 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * v850-tdep.c: Cleanup lots of things. Add many comments.
+
+ * v850-tdep.c (v850_init_extra_frame_info v850_frame_chain): Fix
+ sign bugs with scanning prologues. Get a little smarter about
+ calculating the length of uninteresting instructions.
+
+Mon Oct 21 14:01:38 1996 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * top.c: Add new commands "set annotate" and "show annotate".
+
+Sun Oct 20 04:38:39 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * corelow.c (core_close): Clear inferior_pid only if there is
+ an open core_bfd.
+
+ * cp-valprint.c (cp_print_value_fields): Pass correct address
+ to val_print, not 0.
+
+ From Andreas Schwab (schwab@issan.informatik.uni-dortmund.de):
+ * eval.c (evaluate_subexp_standard) [case BINOP_REPEAT]: Chase
+ typedefs before checking for integral type of right operand.
+
+Fri Oct 18 17:26:22 1996 Mark Alexander <marka@cygnus.com>
+
+ * mdebugread.c (parse_symbol): Fix crash when malloc has
+ no type info and void type has no associated pointer type.
+
+Thu Oct 17 18:18:20 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.host: New file, host configuration mapping.
+ * configure.tgt: New file, target configuration mapping.
+ * configure.in: Remove host and target mapping.
+ * configure: Rebuild.
+
+Wed Oct 16 17:46:03 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * breakpoint.c (must_shift_inst_regs): New global.
+ (bpstat_stop_status): Change #if uses of DECR_PC_AFTER_BREAK into
+ equivalent expression uses.
+ * infrun.c (wait_for_inferior): Ditto.
+
+Wed Oct 16 01:53:43 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * v850-tdep.c (v850_push_arguments): Use symbolic names for arg
+ registers.
+ * config/v850/tm-v850.h: Change FP to 29. Define arg regs.
+
+Tue Oct 15 16:30:07 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (init.c): Don't use -s option with grep. It means
+ something different under Digital Unix.
+
+ * buildsym.c (finish_block): Treat LOC_BASEREG_ARG and
+ LOC_LOCAL_ARG as arguments so that GDB will know about function
+ args declared this way. Mostly affects dwarf.
+ * dwarfread.c (decode_die_type): Change default type from int to
+ void. This allows GDB to recognize void functions.
+ * (new_symbol): If AT_PROTOTYPED is present, set a flag in the
+ type structure.
+ * findvar.c (extract_floating store_floating): Clean up comments
+ to reflect reality.
+ * gdbtypes.h: Add TYPE_FLAG_PROTOTYPED so that we can tell if a
+ function has a prototype. Currently, only dwarf supports this.
+ * utils.c (floatformat_from_doublest): Fix logic error with
+ converting from double to float. (It wasn't shifting mant_long if
+ it had a hidden bit.)
+ * v850-tdep.c: Add support for function calling. Fix some
+ problems with debugging code w/o debug symbols.
+ * config/v850/tm-v850.h: Ditto.
+
+Tue Oct 15 18:19:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * utils.c: Always ensure that size_t is defined. Check
+ HAVE_STDDEF_H rather than __STDC__
+ (xmalloc, xrealloc): Use size_t rather than long.
+
+Tue Oct 15 14:24:19 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/powerpc/tm-ppc-eabi.h: Undefine NO_SINGLE_STEP so targets
+ can use single-step commands.
+
+Sun Oct 13 11:38:25 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * stabsread.c (define_symbol): If REG_STRUCT_HAS_ADDR is non-zero,
+ follow typedefs before checking TYPE_CODE for structures and unions.
+
+Fri Oct 11 15:43:54 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * frame.h: Move definition of struct frame_saved_regs to before
+ struct frame to make it possible to use frame_saved_regs in
+ EXTRA_FRAME_INFO macro.
+
+ * v850-tdep.c config/v850/tm-v850.h: Lotsa new functions and
+ macros to make frame operations (such as backtrace) work.
+
+Fri Oct 11 14:23:50 1996 Fred Fish <fnf@cygnus.com>
+
+ * dbxread.c (process_one_symbol): Check for null string directly
+ rather than using strcmp against "".
+ * partial-stab.h: Ditto.
+
+Fri Oct 11 12:18:32 1996 Mark Alexander <marka@cygnus.com>
+
+ * gdbserver/{gdbreplay.c,low-linux.c,remote-utils.c,utils.c}:
+ Make it compile on Linux and eliminate some warnings.
+
+Thu Oct 10 16:32:08 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (init.c): Fixup final sed script to work around
+ Linux bug with `p' operator.
+
+Wed Oct 9 18:02:48 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-mips.c: Use the correct name everywhere (DDB) for NEC's
+ VR4300 target.
+ (ddb_ops, pmon_ops): Fix the documentation strings.
+
+Wed Oct 9 07:42:44 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (init.c): Retro HPUX grep lacks -h option. Strip
+ filenames with sed instead.
+
+Tue Oct 8 15:59:44 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * defs.h: Remove decls of xmalloc and xrealloc. There is a
+ conflicting definition in libiberty.h.
+
+Tue Oct 8 11:47:13 1996 Fred Fish <fnf@cygnus.com>
+
+ * dbxread.c (dbx_symfile_read): Call free_pending_blocks rather
+ than poking global variable (which is now static).
+ * hpread.c (hpread_build_psymtabs): Ditto.
+ * os9kread.c (os9k_symfile_read): Ditto.
+ * xcoffread.c (xcoff_initial_scan): Ditto.
+
+ * buildsym.h (free_pending_blocks): Declare here.
+ (pending_blocks): Remove declaration of global symbol.
+ (free_pendings): Remove declaration of global symbol.
+ (make_blockvector): Declare here.
+ (record_pending_block): Declare here.
+
+ * dstread.c (make_blockvector): Remove static copy that was old
+ clone of version in buildsym.c.
+ (process_dst_block): Call record_pending_block rather than doing
+ it by hand.
+ (read_dst_symtab): Ditto.
+
+ * buildsym.c (make_blockvector): Make global rather than static,
+ (record_pending_block): New function, code moved from finish_block.
+ (finish_block): Use record_pending_block.
+ (free_pending_blocks): New function.
+ (really_free_pendings): Call free_pending_blocks.
+ (pending_blocks): Make static instead of global.
+ (free_pendings): Make static instead of global.
+
+Tue Oct 8 09:03:22 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config/i386/windows.mh config/i386/xm-windows.h:: New config
+ files to support building Wingdb (built under Microsoft build
+ environment).
+
+ * Makefile.in: Add rule for hpux-thread.o (needs special header
+ files).
+ * (SUBDIRS): Remove mswin.
+ * Change procedure for creating init.c. Speeds things up quite a
+ bit.
+ * config.in configure configure.in: Check for select, poll.
+ * Check for OSF header files before including hpux-thread.o.
+ * Don't configure doc or testsuite when building under MSVC.
+ * findvar.c value.h (read_register_pid write_register_pid): Make
+ global. Needed for hppa-tdep.c.
+ * (supply_register): Don't set pid to inferior_pid when supplying
+ registers.
+ * hppa-tdep.c (saved_pc_after_call): frame_saved_pc ->
+ FRAME_SAVED_PC.
+ * (frame_saved_pc): Change name to hppa_frame_saved_pc.
+ * (hppa_pop_frame): Don't use a pid of 0 with target_write_pc.
+ Use write_pc instead, which uses the correct pid.
+ * (target_read_pc target_write_pc): Use read/write_register_pid
+ instead of read/write_register to preserve the pid passed in.
+ * inftarg.c (child_can_run): Add flag child_suppress_run to allow
+ hpux-threads.c to override this as a runnable target.
+ * config/pa/nm-hppah.h: Define target_new_objfile and
+ target_pid_to_str.
+ * config/pa/tm-hppa.h (FRAME_SAVED_PC): Use hppa_frame_saved_pc
+ instead of frame_saved_pc.
+ * config/m68k/tm-m68k.h: Define TARGET_M68K for Wingdb.
+ * config/m68k/tm-monitor.h: Use FRAME_CHAIN_VALID_ALTERNATE, since
+ we can't easily determine the start file bounds with ELF.
+ * config/mips/tm-mips.h: Define TARGET_MIPS for Wingdb.
+ * hpux-thread.c: New file for HPUX/OSF thread support.
+ * osf-share/{README AT386/cma_thread_io.h HP800/cma_thread_io.h
+ RIOS/cma_thread_io.h cma_attr.h cma_deb_core.h cma_debug_client.h
+ cma_errors.h cma_handle.h cma_init.h cma_list.h cma_mutex.h
+ cma_sched.h cma_semaphore_defs.h cma_sequence.h cma_stack.h
+ cma_stack_int.h cma_tcb_defs.h cma_util.h}: New files for OSF
+ thread support.
+
+Sun Oct 6 15:48:09 1996 Fred Fish <fnf@cygnus.com>
+
+ * buildsym.c (finish_block): Change innerblock_anon_complaint to
+ print the addresses as part of the complaint. Add a complaint for
+ cases where the block end address is smaller than the block start
+ address, in case any such conditions slip through our fixup mechanism.
+ * symmisc.c (dump_symtab): Only print blockvector for primary
+ symtabs, to avoid massive duplication of output due to secondary
+ symtabs that point to same blockvector. Also do some minor
+ formatting tweaks.
+
+Mon Oct 7 10:42:32 1996 Per Bothner <bothner@deneb.cygnus.com>
+
+ Replace header_files global by per-objfile field.
+ * gdb-stabs.h (struct dbx_symfile_info): Add fields header_files,
+ n_header_files, n_allocated_header_files.
+ * stabsread.h (header_files, n_header_files, n_allocated_header_files):
+ Replace externs by macros HEADER_FILES, N_HEADER_FILES, and
+ N_ALLOCATED_HEADER_FILES.
+ * dbxread.c (dbx_symfile_finish): Free HEADER_FILES.
+ (free_header_files, init_header-files): Don't free/init headerfiles.
+ (various functions): Use macros instead of header_files globals.
+ * stabsread.c (various functions): Likewise.
+
+Sun Oct 6 22:43:06 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * dwarf2read.c (read_tag_reference_type): New fn.
+ (read_type_die): Call it.
+ (dwarf_attr): Also look in the DIEs referred to by specification
+ or abstract_origin attributes.
+
+Wed Oct 2 22:07:16 1996 Fred Fish <fnf@cygnus.com>
+
+ * inferior.h (IN_SIGTRAMP): Pass pc to SIGTRAMP_START and
+ SIGTRAMP_END.
+ * config/i386/tm-i386os9k.h (SIGTRAMP_START, SIGTRAMP_END):
+ Define with dummy pc arg.
+ * config/m68k/tm-nbsd.h: Ditto.
+ * doc/gdbint.texinfo: Document that SIGTRAMP_START and
+ SIGTRAMP_END are macros that take an single argument.
+
+Mon Sep 30 20:02:45 1996 Fred Fish <fnf@cygnus.com>
+
+ * defs.h: Remove define of PRIVATE_XMALLOC.
+
+Mon Sep 30 15:39:28 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config/v850/tm-v850.h: Use distinct register for PC, not EIPC.
+
+Mon Sep 30 11:16:34 1996 Jeffrey A Law (law@cygnus.com)
+
+ * top.c (execute_control_command): Free values from while_control
+ and if_control conditions after evaluation to avoid storage leaks.
+ From Peter Schauer.
+
+Fri Sep 27 17:43:06 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure configure.in: Recognize v850 target.
+ * v850-tdep.c: New file, NEC V850 target support.
+ * config/v850/{v850.mt tm-v850.h}: New files for NEC V850 support.
+
+Fri Sep 27 14:48:15 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * infrun.c (wait_for_inferior): Update current_line and
+ current_symtab when stepping continues in the middle of a new line.
+
+Fri Sep 27 10:25:30 1996 Fred Fish <fnf@cygnus.com>
+
+ * top.c (print_gdb_version): Rewrote to comply with new GNU coding
+ standards for the --version option.
+ (print_gnu_advertisement): Remove, now part of print_gdb_version.
+ (show_version): Remove call to print_gnu_advertisement.
+ * top.h (print_gnu_advertisement): Remove prototype.
+ * main.c (print_gdb_help): Move help to static function and
+ add prototype.
+ (main): Call print_gdb_help rather than inlining it.
+ (main): Remove call to print_gnu_advertisement.
+
+Fri Sep 27 13:32:53 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/d10v/tm-d10v.h (TARGET_{INT,PTR}_BIT): Define.
+ (TARGET_{,LONG_}DOUBLE_BIT): Ditto.
+
+Thu Sep 26 23:10:26 1996 Mark Alexander <marka@cygnus.com>
+
+ * configure.in, config/i386/tm-linux.h: Fix configure
+ problem on older Linux systems that prevented core files
+ from being recognized.
+
+Wed Sep 25 18:31:33 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * dbug-rom.c: New file, support for Motorola's dBUG monitor.
+ * config/m68k/monitor.mt (TDEPFILES): Add it.
+ * NEWS: Mention it.
+
+Mon Sep 23 16:13:50 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/d10v/tm-d10v.h (SAVED_PC_AFTER_CALL): Fixed.
+ Now single-steps correctly.
+ * d10v-tdep.c (d10v_pop_frame): Fixed.
+
+Fri Sep 20 16:10:58 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/sh/tm-sh.h (REGISTER_NAMES): Move fp registers to
+ be consistent with GCC.
+ (FPUL_REGNUM, etc): Renumber to match list changes.
+ (ADDR_BITS_REMOVE): Delete.
+ * sh-tdep.c (sh_reg_names, sh3_reg_names, sh3e_reg_names):
+ Rearrange to match REGISTER_NAMES.
+ * sh3-rom.c (sh3_regnames, sh3e_regnames): Ditto.
+
+Thu Sep 19 16:19:01 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-tdep.c: Stack chain should work now.
+
+Tue Sep 17 18:46:57 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-tdep.c, config/d10v/tm-d10v.h: Snapshot.
+
+Tue Sep 17 12:20:50 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add cases for MIPS 5000 like MIPS 4300.
+ * configure: Rebuild.
+
+Tue Sep 17 12:09:00 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * ser-e7kpc.c: Added wingdb support for target e7000pc.
+
+Tue Sep 17 10:56:52 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * remote-mips.c (pmon_wait): DDB PMON does not require forced
+ re-entry back into debug mode.
+
+Mon Sep 16 14:32:58 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * remote-mips.c (mips_load): Ensure that the PC is explicitly
+ loaded after a load to a DDB PMON system.
+
+Fri Sep 13 12:02:39 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (INTERNAL_LDFLAGS): Add @HLDFLAGS@ to list.
+ (HLDENV): Set to @HLDENV@.
+ (gdb): Prefix link command line with $(HLDENV).
+ * configure.in: Add support to test for --enable-shared and
+ generate appropriate values for HLDFLAGS and HLDENV.
+ * configure: Regenerated with autoconf.
+
+Sun Sep 8 15:26:27 1996 Fred Fish <fnf@cygnus.com>
+
+ * alpha-nat.c (fetch_core_registers): Match Sep 4 gdbcore.h prototype
+ change for core_read_registers in struct core_fns.
+ * core-regset.c (fetch_core_registers): Ditto & add prototype.
+ * core-sol2.c (fetch_core_registers): Ditto & add prototype.
+ * i386aix-nat.c (fetch_core_registers): Ditto & add prototype.
+ * i386b-nat.c (fetch_core_registers): Ditto.
+ * i386mach-nat.c (fetch_core_registers): Ditto & add prototype.
+ * irix4-nat.c (fetch_core_registers): Ditto.
+ * irix5-nat.c (fetch_core_registers): Ditto.
+ * lynx-nat.c (fetch_core_registers): Ditto & add prototype.
+ * m68knbsd-nat.c (fetch_core_registers): Ditto.
+ * mips-nat.c (fetch_core_registers): Ditto & add prototype.
+ * rs6000-nat.c (fetch_core_registers): Ditto.
+ * sparc-nat.c (fetch_core_registers): Ditto.
+ * sun3-nat.c (fetch_core_registers): Ditto & add prototype.
+ * ultra3-nat.c (fetch_core_registers): Ditto & add prototype.
+
+ * alpha-nat.c (register_addr): Match Sep 4 gdbcore.h prototype change.
+ * delta68-nat.c (register_addr): Ditto.
+ * gdbserver/low-linux.c (register_addr): Ditto.
+ * gdbserver/low-hppabsd.c (register_addr): Ditto.
+ * i386m3-nat.c (register_addr): Ditto.
+ * mips-nat.c (register_addr): Ditto.
+ * ultra3-nat.c (register_addr): Ditto.
+
+Sun Sep 8 15:14:00 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * blockframe.c (inside_main_func): Cleanup slightly. Move
+ mainsym def into the block it's used in.
+ * configure.in configure: Allow NATDEPFILES to be recognized in
+ .mh files regardless of whitespace.
+
+ * cpu32bug-rom.c (cpu32bug_cmds): Change load_response string to
+ keep downloads from hanging.
+
+ * remote-wiggler.c: Add support for flash upgrades.
+ * (wiggler_error): Fix message format. Add new error code.
+ * (wiggler_write_byets): Error code is hex. Report errors with
+ proper routine name.
+ * (wiggler_read_byets): Report errors with proper routine name.
+ * (get_packet): Add support for new flash commands.
+ * (wiggler_load): Call clear_symtab_users() to reset things
+ properly after download.
+ * (flash_xfer_memory bdm_update_flash_command): New funxtions to
+ support flash upgrades for Wiggler.
+ * (_initialize_remote_wiggler): Add `bdm update-flash' command.
+
+Fri Sep 6 13:14:13 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * ser-tcp.c: don't include netinet/tcp.h if __CYGWIN32__
+
+Thu Sep 5 17:05:13 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/i386/cygwin32.mh:
+ * config/powerpc/cygwin32.mh: build ser-tcp.o for both hosts
+
+Thu Sep 5 12:09:13 1996 Per Bothner <bothner@deneb.cygnus.com>
+
+ * value.h (COERCE_REF): Fix previous change.
+ (COERCE_ENUM): Add a check_typedef (this is the real fix).
+
+Thu Sep 5 03:28:30 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * eval.c (evaluate_subexp_standard): In case of OP_ARRAY: make a
+ better check of array boundaries.
+
+Thu Sep 5 01:29:42 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure: Update aclocal.m4 and re-run autoconf to get correct
+ defs for BFD stuff.
+ * remote-wiggler.c (wiggler_error): Error codes are hex. Also,
+ fix default message generation.
+
+Wed Sep 4 17:28:40 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in: Add mswin to SUBDIRS. Add rules for
+ mswin/libwingdb.a and remote-wiggler.o.
+ * breakpoint.c (breakpoint_here_p): Clean up bp enabled test.
+ * (breakpoint_inserted_here_p): New func, just like
+ breakpoint_here_p, except it's honest. Honestly.
+ * breakpoint.h: Proto for above.
+ * configure configure.in: Add mswin to configdirs if host is
+ i[3456]86-*-windows.
+ * core-aout.c (fetch_core_registers register_addr) gdbcore.h:
+ Change all vars that can contain addresses to type CORE_ADDR.
+ * findvar.c (supply_register): Allow val to be NULL. This means
+ that regno is unsupported.
+ * (read_pc read_pc_pid write_pc write_pc_pid): Make non-pid forms
+ just call pid forms with inferior_pid so that there's only once
+ place to hack PC's and such.
+ * infrun.c (proceed): Don't skip breakpoints if user changed PC.
+ * remote-wiggler.c: New file. Support for BDM interface from
+ Macraigor Systems.
+ * serial.c: Enhance serial logging capability. Add hex and octal
+ output modes (set remotelogbase {hex|octal|ascii}. Also log
+ breaks, timeouts, errors, and eofs.
+ * serial.h: Redefine SERIAL_SEND_BREAK to go through a wrapper
+ function so that we can log breaks. Don't export serial_logfile
+ or serial_logfp.
+ * top.c (execute_command): Don't test for serial_logfp here.
+ Just call serial_log_comand, and let serial.c sort it out.
+ * valops.c (value_of_variable): Don't attempt to establish frames
+ for static and global variables. This makes things work a bit
+ better if the stack or frame pointer is trashed.
+ * config/m68k/monitor.mt (TDEPFILES): Add remote-wiggler.o.
+ * config/m68k/tm-m68k.h: Define STACK_ALIGN. CPU32 can't hack
+ misaligned stacks during function calls.
+
+Wed Sep 4 13:06:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * terminal.h: Don't use #elif.
+
+Wed Sep 4 06:49:35 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * ch-exp.c (parse_tuple_element): Allow (*): for array tuples
+ if we have a type.
+
+ * eval.c (evaluate_subexp_standard): In case of OP_ARRAY:
+ check number of args against bounds of array to avoid
+ memory corruption.
+
+ * value.h (COERCE_REF): Do a CHECK_TYPEDEF in case we get
+ a TYPE_CODE_TYPEDEF.
+
+Fri Aug 30 15:07:14 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * remote-mips.c: Provide support for DDBVR4300 target board.
+ (ddb_open, ddb_ops): Added.
+ (mips_monitor_type): MON_DDB Added.
+ (mips_enter_debug, mips_exit_debug, mips_initialize,
+ mips_fetch_registers, common_breakpoint, mips_load,
+ _initialize_remote_mips): Updated.
+
+Thu Aug 29 17:00:18 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * nlm/configure.in (i[345]86-*-*): Recognize i686 for pentium pro.
+ * nlm/configure: Regenerate.
+
+ * gdbserver/configure.in (i[345]86-*-*): Recognize i686 for
+ pentium pro.
+
+Wed Aug 28 13:11:15 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: If CY_AC_PATH_TCLCONFIG can't find TCL, don't run
+ CY_AC_LOAD_TCLCONFIG.
+ * configure: Rebuild.
+
+Tue Aug 27 12:40:40 1996 Fred Fish <fnf@cygnus.com>
+
+ * infrun.c (wait_for_inferior): Initialize stop_func_end before calling
+ find_pc_partial_function.
+
+Tue Aug 27 10:17:34 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure: Regenerate again.
+
+Tue Aug 27 04:25:08 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: work around host_alias configure bug.
+ AC_CANONICAL_HOST is called twice (first by AC_CHECK_TOOL
+ and second by AC_CANONICAL_SYSTEM). The second clobbers the
+ previous setting. Circumventing by moving the second check
+ to before the first.
+ * configure: regenerated
+
+Mon Aug 26 18:36:54 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/d10v/d10v.mt: New file.
+ * config/d10v/tm-d10v.h: New file.
+ * configure.in: New target D10V.
+ * d10v-tdep.c: New file.
+
+Sun Aug 25 00:09:47 1996 Fred Fish <fnf@rtl.cygnus.com>
+
+ * rs6000-tdep.c: Fix typo in comment.
+ * valops.c (call_function_by_hand): Set using_gcc to 2
+ for code compiled without -g, per comment in code.
+ * config/a29k/tm-a29k.h (STACK_ALIGN): Add comment.
+ * config/sparc/tm-sparc.h (STACK_ALIGN): Add comment.
+ * config/sparc/tm-sp64.h (STACK_ALIGN): Add comment.
+ * config/pyr/tm-pyr.h (STACK_ALIGN): Add comment.
+ * config/m88k/tm-m88k.h (STACK_ALIGN): Add comment.
+ * config/pa/tm-hppa.h (PUSH_ARGUMENTS): Enclose args in ()'s.
+ (STACK_ALIGN): Add comment, move to be with other associated
+ macros, and document.
+ * config/mips/tm-mips.h (PUSH_ARGUMENTS): Enclose args in ()'s.
+ (STACK_ALIGN): Remove completely, handled by PUSH_ARGUMENTS.
+ * config/alpha/tm-alpha.h (PUSH_ARGUMENTS): Enclose args in ()'s.
+ * config/rs6000/tm-rs6000.h (STACK_ALIGN): Remove completely,
+ handled by PUSH_ARGUMENTS.
+ (PUSH_ARGUMENTS): Enclose args in ()'s.
+
+Fri Aug 23 13:55:05 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * infrun.c (wait_for_inferior): Try to reenable shared library
+ breakpoints even if auto_solib_load is not set.
+
+Wed Aug 21 16:31:27 1996 Fred Fish <fnf@cygnus.com>
+
+ * valprint.c (print_longest): Test for CC_HAS_LONG_LONG as well as
+ PRINTF_HAS_LONG_LONG.
+ * expprint.c (dump_expression): Ditto.
+ * configure.in: Fix check for long long support in compiler to
+ use a function body, not a nested function.
+ * configure: Rebuild with autoconf.
+
+Tue Aug 20 17:59:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4: Include ../bfd/aclocal.m4.
+ * configure.in: Add stdlib.h to AC_CHECK_HEADERS. Call
+ BFD_NEED_DECLARATION on malloc, realloc, and free.
+ * acconfig.h: Add NEED_DECLARATION_MALLOC,
+ NEED_DECLARATION_REALLOC, and NEED_DECLARATION_FREE.
+ * configure, config.in: Rebuild.
+ * defs.h: Include <stddef.h> and <stdlib.h> based on HAVE_*_H
+ rather than __STDC__. Only declare malloc, realloc, and free if
+ NEED_DECLARATION_* is defined.
+
+Tue Aug 20 15:37:03 1996 Fred Fish <fnf@cygnus.com>
+
+ * solib.c (_initialize_solib): Add missing '\' chars at ends of
+ strings that continue on next line.
+ (enable_break): Replace "return 0" with setting success to zero
+ and letting normal return handle the return.
+
+Sat Aug 17 14:16:23 1996 Fred Fish <fnf@cygnus.com>
+
+ * mips-tdep.c (mips_push_arguments): Make sure sp and struct_addr
+ are properly aligned.
+
+Fri Aug 16 17:54:26 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * rs6000-tdep.c (rs6000_fix_call_dummy): Add full set of arguments.
+ * config/rs6000/tm-rs6000.h (FIX_CALL_DUMMY): Pass all arguments
+ to function, declare function correctly.
+
+Fri Aug 16 17:24:35 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * symtab.h: changed namespace to _namespace for compiling under
+ MFC v4.0.
+
+Fri Aug 16 13:52:21 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Update for various recent changes, add some
+ comments.
+
+Fri Aug 16 15:47:36 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/rs6000/tm-rs6000.h (FIX_CALL_DUMMY): Cast args to be an
+ integer for type correctness.
+
+Fri Aug 16 15:15:37 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/mips/{vr4300.mt, vr4300el.mt} (SIM): Add -lm when
+ simulator is included.
+
+Thu Aug 15 13:44:13 1996 Fred Fish <fnf@cygnus.com>
+
+ * findvar.c (write_register_pid): Only needed when TARGET_WRITE_PC
+ is not defined.
+ (read_register_pid): Only needed when TARGET_READ_PC is not
+ defined.
+ * hppa-tdep.c (frame_saved_pc): Remove prototype.
+ * infptrace.c (udot_info): Prototype when CHILD_XFER_MEMORY is
+ not defined.
+ * config/xm-aix4.h (aix_resizewindow): Convert old style decl
+ to prototype.
+ * xcoffsolib.c (command.h): Include for needed prototypes.
+
+Wed Aug 14 17:54:19 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config/i386/cygwin32.mh: Set NAT_FILE to nm-empty.h to make
+ native work.
+
+Wed Aug 14 02:03:42 1996 Fred Fish <fnf@cygnus.com>
+
+ From Blair MacIntyre <bm@cs.columbia.edu>:
+ * hppa-tdep.c (hppa_fix_call_dummy): Use MSYMBOL_TYPE rather
+ than SYMBOL_TYPE on msymbols.
+ * somsolib.c (som_solib_create_inferior_hook): Ditto.
+
+ * Makefile.in (init.c): Generate with prototypes.
+
+ * config/pa/tm-hppa.h (frame_saved_pc): Add prototype.
+ * config/rs6000/xm-rs6000.h (aix_resizewindow): Ditto.
+ * config/rs6000/tm-rs6000.h (frame_initial_stack_address): Ditto.
+ (pc_load_segment_name): Ditto.
+ (pop_frame): Ditto.
+ (extract_return_value): Ditto.
+ (is_magic_function_pointer): Ditto.
+ (push_dummy_frame): Ditto.
+ (fix_call_dummy): Ditto.
+ (push_arguments): Ditto.
+ (skip_trampoline_code): Ditto.
+ (aix_process_linenos): Ditto.
+
+ * config/m68k/tm-cisco.h (get_longjmp_target): Add prototype.
+ * config/m68k/tm-es1800.h: Ditto.
+ * config/m68k/tm-vx68.h: Ditto.
+ * config/m68k/tm-sun3.h: Ditto.
+ * config/m68k/tm-m68kv4.h: Ditto.
+
+Tue Aug 13 23:04:36 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/mips/nm-mips.h (get_longjmp_target): Add prototype.
+ * config/mips/nm-irix3.h (get_longjmp_target): Add prototype.
+ * remote-mips.c (mips_read_processor_type): Remove prototype.
+ * mips-tdep.c (gdb_print_insn_mips): Add prototype and make static.
+ * irix5-nat.c (fetch_core_registers): Add prototype.
+
+Mon Aug 12 21:23:44 1996 Fred Fish <fnf@cygnus.com>
+
+ * remote-pa.c (boot_board): Add dummy params to make type compatible
+ for passing to add_com.
+ * scm-exp.c (scm_lreadr): Ensure svalue is not used uninitialized.
+ * buildsym.c (compare_line_numbers): Change function to match
+ prototype and also what qsort expects.
+
+Mon Aug 12 19:19:00 1996 Mark Alexander <marka@cygnus.com>
+
+ * remote.c: Make remote_write_size public.
+ * sh-tdep.c (_initialize_sh_tdep): Set remote_write_size to 300
+ to prevent packet errors with some versions of CMON.
+
+Mon Aug 12 16:20:58 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * defs.h: Define CONST_PTR as blank if compiling with Microsoft
+ C, else it's `const'.
+ * c-lang.c c-lang.h ch-lang.c f-lang.c language.c m2-lang.c
+ scm-lang.c: Microsoft C can't hack const pointers. Use CONST_PTR
+ macro instead.
+ * configure configure.in defs.h: Use AC_C_CONST to figure out if
+ the compiler supports const. Gets rid of some cruft in defs.h.
+ * dwarf2read.c: <string.h> -> "gdb_string.h"
+ * remote-sim.c: Add prototypes. Fix call to gdbsim_kill.
+ * sparcl-tdep.c (download): Add prototypes to write_routine and
+ start_routine args.
+
+ * mswin/gdbwin.c: Don't include both varargs.h AND stdarg.h. Get
+ rid of varargs.h Include string.h.
+ * (gdbwin_update gdbwin_fputs regs_changed_f bpt_changed_f
+ update): Fix prototypes, fix calls.
+ * (update): Return value for catch_errors.
+ * (run_execute_command togdb_command_from_tty togdb_command):
+ Cleanup catching of errors from calls to execute_command. Also,
+ dup command string to avoid modifying const strings.
+ * (togdb_breakinfo_i_init togdb_breakinfo_i_next): Use 0 instead
+ of NULL when see if b->address isn't set.
+ * (bi_disable_bpt bi_enable_bpt bi_delete_all
+ bi_delete_breakpoint): Add arg to calls to update.
+ * (gui_command): Add prototype.
+ * (mswin_query): Fix prototype.
+ * (_initialize_gdbwin): Dup string to avoid modifying const.
+ * (info_path togdb_get_info_path): Remove const from decls cuz
+ this can't be const (it points at malloc'ed memory).
+ * (togdb_searchpath): Remove const from path. Dup string to
+ avoid modifying const strings.
+ * rindex -> strrchr.
+ * (gdbwin_list_symbols): Regexp param is const.
+ * Fix lots of refs to psymtabs to deref correct pointers.
+ * (togdb_set_breakpoint_sal): Call set_breakpoint_sal with sal,
+ not &sal.
+ * mswin/gdbwin.h (togdb_searchpath togdb_get_info_path
+ toget_set_info_path): Fix prototypes to match reality.
+ * mswin/gui.cpp: Define _beginthreadex and _endthreadex routines
+ with proper prototypes.
+ * mswin/iface.cpp (gdbwin_fputs): Define with correct number of args.
+ * mswin/ser-win32s.c: Fix defs of min and max.
+ * mswin/serdll32.c (OpenComm16): Make cbInQueue and cbOutQueue be
+ USHORT.
+ * (WriteComm16): Change lpBug from LPVOID to LPCSTR.
+ * mswin/serdll32.h: Fix prototypes for OpenComm16 and WriteComm16.
+
+Sun Aug 11 20:54:16 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * main.c (main): Make sure command loop is used with cygwin32.
+ * terminal.h: Allow cygwin32 to use termios.h.
+
+Fri Aug 9 12:42:49 1996 Jeffrey A Law (law@cygnus.com)
+
+ * somread.c (som_symtab_read): Handle secondary definition
+ symbols (aka weak symbols).
+
+ * config/tm-hppa.h (EXTRACT_RETURN_VALUE): Fix thinko in
+ last change.
+
+Thu Aug 8 10:12:36 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * symfile.c (symfile_bfd_open): Change ifdef from __WIN32__ to
+ _WIN32.
+
+ * somread.c: Rearrange order of includes to fix warnings under
+ hpux-10.10. Also don't include sys/file.h.
+
+Wed Aug 7 21:45:52 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * dbxread.c: Don't include param.h or sys/file.h.
+ * (dbx_symfile_read): Determine symfile_relocatable from bfd
+ flags instead of file extension. Also clean up a little bit.
+
+Wed Aug 7 17:18:37 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * dwarf2read.c dwarfread.c exec.c infcmd.c infrun.c main.c
+ mdebugread.c os9kread.c source.c top.c utils.c: Don't
+ include param.h or sys/file.h (or unistd.h in some cases).
+ * defs.h exec.c inflow.c remote-array.c remote-e7000.c
+ sparcl-tdep.c terminal.h utils.c: Replace all occurances of
+ __WIN32__, WINGDB, WIN32, etc... with _WIN32.
+ * main.c: Remove #ifndef WINGDB around option processing. Fix
+ bug with passing argc==0 and argv==NULL to getopt.
+ * (main) Remove calls to access() before source_command. Let
+ soure_command handle access errors.
+ * maint.c (maintenance_dump_me): #ifdef out for _WIN32.
+ * symtab.c (operator_chars): Make this global for wingdb.
+ * top.c (disconnect): #ifdef out for _WIN32.
+ * (source_command): If got an error and from_tty, then call print
+ error, else just return quietly.
+ * utils.c (fatal_dump_core): Can't kill ourselves under windows.
+ Just exit.
+ * (pollquit notice_quit): #ifdef out stuff that doesn't exist
+ under windows.
+
+Wed Aug 7 09:59:19 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/pa/tm-hppa.h (EXTRACT_RETURN_VALUE): Tweak for
+ structures > 4 bytes in size.
+
+ * valops.c (call_function_by_hand): Handle aligning stacks that
+ grow up correctly.
+ * config/pa/tm-hppa.h (USE_STRUCT_CONVENTION): Define.
+ (STACK_ALIGN): Define.
+ * hppa-tdep.c (hppa_alignof): Don't demand a minumim two byte
+ alignment on structs/unions.
+
+Sun Aug 4 16:22:42 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/powerpc/nm-aix.h (PTRACE_ARG3_TYPE): Define to "int *",
+ which is the documented type under at least AIX 3 and AIX 4.
+
+Sat Aug 3 04:02:46 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/alpha/alpha-osf3.mh (XM_FILE): Change from xm-alpha.h to
+ xm-alphaosf.h.
+ (MMALLOC_CFLAGS): Define NO_MMCHECK to not install consistency
+ checks.
+
+Thu Aug 1 10:11:34 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/mips/tm-mips.h (TM_MIPS_H): Enclose file contents in
+ this, define when contents are included.
+ (mips_read_processor_type): Add prototype.
+ * config/mips/xm-mips.h: Remove strdup decl, now in gdb_string.h
+ * mdebugread.c (ecoff_relocate_efi): Add prototype.
+ (fixup_sigtramp): Only needed when TM_MIPS_H is defined.
+
+Wed Jul 31 20:21:24 1996 Fred Fish <fnf@cygnus.com>
+
+ * rs6000-nat.c (add_vmap): Return 0 to caller rather than random value.
+ (vmap_ldinfo): Ensure got_exec_file is not used uninitialized.
+ (fetch_core_registers): Add prototype.
+ (vmap_symtab): Ditto.
+ (objfile_symbol_add): Ditto.
+ (add_vmap): Ditto.
+ (vmap_ldinfo): Ditto.
+ (vmap_exec): Ditto.
+
+Tue Jul 30 17:57:46 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * stabsread.c (get_substring): Declare second arg as int.
+
+ * remote-es.c: Include gdb_string.h after defs.h.
+
+Mon Jul 29 21:13:20 1996 Fred Fish <fnf@cygnus.com>
+
+ * rs6000-tdep.c (push_arguments): Remove unused variable "pc".
+ (branch_dest): Remove unused variable "offset".
+ (pop_dummy_frame): Add prototype and make static.
+ (push_arguments): Guard against using len uninitialized.
+ (push_arguments): Guard against using arg uninitialized.
+ (frame_saved_pc): Remove unused variable "frameless".
+ (free_loadinfo): Ifdef out unused function.
+
+ * xcoffread.c (compare_lte): Change prototype and function to
+ be correct type for passing to qsort.
+ (add_stab_to_list): Ifdef out unused function and prototype.
+ (compare_lte): Add prototype
+ (arrange_linetable): Ditto.
+ (record_include_begin): Ditto.
+ (record_include_end): Ditto.
+ (process_linenos): Ditto.
+ (xcoff_next_symbol_text): Ditto.
+ (scan_xcoff_symtab): Ditto.
+ (xcoff_initial_scan): Ditto.
+
+ * mips-tdep.c (mips_read_processor_type): Add parens around
+ bitwise-and operands in comparison; previous expression always
+ evaluated to 0 because of equality comparison of two constants.
+
+ * rs6000-tdep.c (skip_prologue): Add missing parens around
+ operands of logical-or so that first operand does not bind
+ to previous logical-and.
+
+ * configure.in: Expand "long long" test to include code that triggers
+ known problem on HPUX with native compiler.
+ (configure): Regenerated.
+
+Mon Jul 29 18:12:27 1996 Jeffrey A Law (law@cygnus.com)
+
+ * somsolib.c (som_solib_create_inferior_hook): Don't
+ warn if __d_pid can't be found.
+
+Sun Jul 28 10:46:39 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/mips/tm-mips.h (struct frame_info): Forward decl.
+ (struct type): Ditto.
+ (struct value): Ditto.
+
+ * config/mips/tm-mips.h (sigtramp_address): Move extern decl
+ from mips-tdep.c to here.
+ (sigtramp_end): Ditto.
+ (fixup_sigtramp): Ditto.
+
+ * config/mips/tm-mips.h (init_extra_frame_info): Add prototype.
+ (mips_frame_chain): Ditto.
+ (mips_step_skips_delay): Ditto.
+ (mips_frame_saved_pc): Ditto.
+ (mips_find_saved_regs): Ditto.
+ (mips_frame_num_args): Ditto.
+ (mips_pop_frame): Ditto.
+ (mips_extract_return_value): Ditto.
+ (mips_store_return_value): Ditto.
+ (mips_push_dummy_frame): Ditto.
+ (mips_push_arguments): Ditto.
+ (mips_do_registers_info): Ditto.
+ (ecoff_relocate_efi): Ditto.
+ (ecoff_relocate_efi): Ditto.
+ * irix4-nat.c (fetch_core_registers): Add prototype.
+ * mips-tdep.c (read_next_frame_reg): Add prototype
+ (heuristic_proc_start): Ditto.
+ (heuristic_proc_desc): Ditto.
+ (mips_print_register): Ditto.
+ * config/mips/nm-irix5.h (procfs_set_watchpoint): Add prototype.
+ (procfs_stopped_by_watchpoint): Ditto.
+ * config/mips/nm-irix4.h (procfs_set_watchpoint): Add prototype.
+ (procfs_stopped_by_watchpoint): Ditto.
+ * config/alpha/tm-alpha.h (ecoff_relocate_efi): Add prototype.
+ (struct symbol): Add forward decl for prototype.
+
+ * breakpoint.c (internal_breakpoint_number): Only needed if
+ GET_LONGJMP_TARGET or SOLIB_ADD is defined.
+
+ * objfiles.c (ecoff_relocate_efi): Remove prototype.
+
+Sat Jul 27 17:47:35 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in: Add test for "long long" support.
+ * configure: Regenerate with autoconf.
+ * acconfig.h: Add CC_HAS_LONG_LONG
+ * config.in: Regenerate with autoheader.
+ * config/mips/tm-mips64.h (FORCE_LONG_LONG): Remove
+ * config/sparc/tm-sp64.h (CC_HAS_LONG_LONG): Remove.
+ * config/mips/tm-vr4300el.h (CC_HAS_LONG_LONG): Remove.
+ * config/mips/tm-vr4300.h (CC_HAS_LONG_LONG): Remove.
+ * config/mips/xm-irix5.h (CC_HAS_LONG_LONG): Remove
+ (PRINTF_HAS_LONG_LONG): Remove.
+ (FORCE_LONG_LONG): Remove.
+ * config/powerpc/xm-aix.h (UINT_MAX): Undef and use gdb's version.
+ * config/convex/xm-convex.h (CC_HAS_LONG_LONG): Remove
+ (PRINTF_HAS_LONG_LONG): Remove.
+ * config/xm-nbsd.h (CC_HAS_LONG_LONG): Remove.
+ (PRINTF_HAS_LONG_LONG): Remove.
+ * config/pa/tm-hppa.h (GET_FIELD): Put parens around
+ subtraction inside shift. Put parens around subtraction
+ in operand of bitwise and.
+ (struct frame_info): Forward declare
+ if __STDC__ defined.
+ (frame_saved_regs): Ditto.
+ (struct value): Ditto.
+ (struct type): Ditto.
+ (struct inferior_status): Ditto.
+ (init_extra_frame_info): Add prototype.
+ (skip_prologue): Ditto.
+ (frameless_function_invocation): Ditto.
+ (frame_chain): Ditto.
+ (frame_chain_valid): Ditto.
+ (saved_pc_after_call): Ditto.
+ (hppa_fix_call_dummy): Ditto.
+ (hppa_push_arguments): Ditto.
+ (pa_do_registers_info): Ditto.
+ (in_solib_call_trampoline): Ditto.
+ (in_solib_return_trampoline): Ditto.
+ (push_dummy_frame): Ditto.
+ * convex-tdep.c (decout): Use print_longest rather than
+ fprintf_filtered.
+ * defs.h: Remove use of FORCE_LONG_LONG and __GNUC__ to set
+ CC_HAS_LONG_LONG.
+ (INT_MIN): Fix so it works correctly when assigned to a long long.
+ * valprint.c (longest_to_int): Rewrite to remove dependence
+ on INT_MIN and INT_MAX.
+ (print_longest): Rewrite the code that falls back to synthesized
+ hex output when LONGEST value is not representable as in a long and
+ printf doesn't support printing long longs.
+ * ch-valprint.c (chill_val_print): Cast 2nd arg of
+ chill_print_type_scalar to LONGEST.
+ chill_print_type_scalar): Make static and add prototype.
+ * hppa-tdep.c (get_field): Ifdef out unused function.
+ (set_field): Ditto.
+ (extract_3): Ditto.
+ (extract_5_store): Ditto.
+ (extract_11): Ditto.
+ (extract_12): Ditto.
+ (deposit_17): Ditto.
+ (extract_14): Convert to static and add prototype.
+ (deposit_14): Ditto.
+ (extract_21): Ditto.
+ (deposit_21): Ditto.
+ (extract_17): Ditto.
+ (extract_5r_store): Ditto.
+ (extract_5R_store): Ditto.
+ (extract_5_load): Ditto.
+ (find_proc_framesize): Ditto.
+ (find_dummy_frame_regs): Ditto.
+ (sign_extend): Ditto.
+ (find_unwind_entry): Add prototype.
+ (find_return_regnum): Ditto.
+ (unwind_command): Ditto.
+ (find_dummy_frame_regs): Add parens around subtraction in operand
+ of bitwise-and.
+ (skip_prologue): Add parens around operands of logical-and inside
+ operand of logical-or.
+ (sign_extend): Add parens around operands of subtraction inside
+ operand of shift.
+ (low_sign_extend): Ditto.
+ * top.c (filename_completer): Convert old style decl of
+ filename_completion_function into prototype.
+ * f-lang.c (patch_common_entries): Ifdef out unused function.
+ * stabsread.c (read_cfront_baseclasses): Remove unused local
+ variable "msg_noterm".
+ (resolve_cfront_continuation): Remove unused local variable "fip".
+ (read_type): Remove unused variable xtypenums.
+ (read_cfront_static_fields): Remove unused variable "i".
+ (read_cfront_static_fields): Remove unused variable "nfields".
+ (read_cfront_member_functions): Add missing comment terminator.
+ (read_cfront_static_fields): Return 1 rather than random value.
+ (read_cfront_baseclasses): Ditto.
+ (read_cfront_baseclasses): Ditto.
+ (read_cfront_baseclasses): Ditto.
+ * somsolib.c (som_solib_create_inferior_hook): Remove unused
+ variable "u".
+ (som_solib_create_inferior_hook): Remove unused variable
+ shadow_contents.
+ (language.h): Add for needed prototypes.
+ (som_solib_sharedlibrary_command): Add prototype.
+ * hpread.c: (hpread_read_array_type): Add prototype.
+ * somread.c (hpread_build_pysmtabs): Add prototype.
+ (hpread_symfile_finish): Ditto.
+ (hpread_symfile_init): Ditto.
+ * hppah-nat.c (fetch_register): Convert old style decl
+ to prototype.
+ (gdbcore.h): Include for needed prototypes.
+ (fetch_register): Remove unused variable "mess".
+ * remote-pa.c (get_offsets): Ifdef out unused function.
+ (remote_start_remote): Remove unused variable "timeout".
+ (boot_board): Add prototype.
+ (reaad_frame): Add prototype.
+ (getpkt): Remove unused variable "bp".
+ (remote_kill): Add prototype.
+ (remote_mourn): Add prototype.
+ (remote_insert_breakpoint): Add prototype.
+ (remote_remove_breakpoint): Add prototype.
+ * valops.c (value_push): Only use if PUSH_ARGUMENTS is not defined.
+ * infcmd.c (do_registers_info): Only need prototype if
+ DO_REGISTERS_INFO is not defined.
+ (breakpoint_auto_delete_contents): Only need if
+ CALL_DUMMY_BREAKPOINT_OFFSET is defined.
+
+Sat Jul 27 08:49:49 1996 Fred Fish <fnf@cygnus.com>
+
+ * xcoffread.c (xcoff_end_psymtab): Add textlow_not_set parameter.
+ (END_PSYMTAB): Ditto.
+ (scan_xcoff_symtab): Call xcoff_end_psymtab with textlow_not_set.
+
+Fri Jul 26 14:07:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * printcmd.c (_initialize_printcmd): Initialize
+ tm_print_insn_info.flavour.
+
+Thu Jul 25 19:41:31 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (scm-valprint.o): Depends upon gdbcore_h.
+ (arm-tdep.o): Ditto.
+ (dcache.o): Ditto.
+ (i386ly-tdep.o): Ditto.
+ (i960-tdep.o): Ditto.
+ (m68k-tdep.o): Ditto.
+ (nindy-tdep.o): Ditto.
+ (scm-lang.o): Ditto.
+ (w65-tdep.o): Ditto.
+ (z8k-tdep.o): Ditto.
+ (m68k-tdep.o): Depends upon value_h and gdb_string.h
+ (m2-valprint.o): Depends upon m2-lang.h.
+ (sparc-tdep.o): Depends upon gdb_string.h
+ (valprint.o): Depends upon valprint.h
+
+ * remote-e7000.c (notice_quit): Remove prototype.
+ * top.c (initialize_targets): Remove prototype, now in target.h.
+ * stabsread.c (resolve_cfront_continuation): Remove prototype.
+ * dbxread.c (resolve_cfront_continuation): Remove prototype.
+ * symfile.h (set_demangling_style): Remove prototype.
+ * config/tm-sysv4.h (in_plt_section): Remove prototype, in objfiles.h.
+ * config/sparc/tm-sparc.h (single_step): Remove extern decl, now in
+ target.h.
+ * config/arc/tm-arc.h (one_stepped, single_step): Remove extern decls,
+ now in target.h.
+ * ser-unix.c (hardwire_restore): Remove obsolete prototype.
+ * sparc-tdep.c (single_step): Remove forward decl of isbranch.
+ * scm-lang.c (find_function_in_inferior): Remove prototype.
+ (value_allocate_space_in_inferior): Ditto.
+ * infrun.c (write_pc_pid): Remove prototype, now in inferior.h.
+ * defs.h (strchr): Remove declarations, they are declared in
+ gdb_string.h also.
+ (strrchr): Ditto.
+ (strstr): Ditto.
+ (strtok): Ditto.
+ (strerror): Ditto.
+ * f-valprint.c (f77_print_array_1): Remove extra arg that was being
+ passed to f77_print_array_1.
+ * gdbtypes.c (add_name): Remove unused variables lenstrlen and lenstr.
+ * scm-exp.c (scm_istr2int): Remove unused variable "j".
+ (scm_parse): Remove unused variable "str".
+ * hp300ux-nat.c (store_inferior_register): Remove unused variable
+ "buf".
+ (store_inferior_registers): Remove unnecessary decl "registers".
+ * m68k-tdep.c (m68k_pop_frame): Remove unused variable "fi".
+ * scm-lang.c (scm_get_field): Remove unused variable "val".
+ (scm_lookup_name): Remove unused variable "symval".
+ * objfiles.c (map_to_file): Remove unused local variable "tempfd".
+ * procfs.c (do_attach, do_detach): Remove unused variable "result".
+ (last_resume_pid): Remove unused static variable.
+ * alpha-tdep.c (alpha_linux_sigtramp_offset): Remove unused variable
+ "res".
+ * objfiles.c (map_to_address): Remove unused function.
+ * f-valprint.c (print_max): Remove extraneous extern decl,
+ in valprint.h.
+ (calc_f77_array_dims): Remove extraneous prototype, in f-lang.h.
+ * ch-exp.c (write_lower_upper_value): Remove prototype for
+ type_lower_upper.
+
+ * gdbtypes.c (cfront_mangle_name): #ifdef out unused function.
+ * ch-exp.c (parse_mode_call): Ditto.
+ * f-valprint.c (there_is_a_visible_common_named): Ditto.
+ * f-lang.c (clear_function_list): Ditto.
+ (get_bf_for_fcn): Ditto.
+ (clear_bf_list): Ditto.
+ (add_common_block): Ditto.
+ (patch_all_commons_by_name): Ditto.
+ (find_first_common_named): Ditto.
+ (add_common_entry): Ditto.
+ (allocate_saved_function_node): Ditto.
+ (allocate_saved_bf_node): Ditto.
+ (allocate_common_entry_node): Ditto.
+ (allocate_saved_f77_common_node): Ditto.
+
+ * arm-tdep.c (gdbcore.h): Include for necessary prototypes.
+ * dcache.c (gdbcore.h): Ditto.
+ * i386ly-tdep.c (gdbcore.h): Ditto.
+ * i960-tdep.c (gdbcore.h): Ditto.
+ * m2-valprint.c (m2-lang.h): Ditto.
+ * m68k-tdep.c (gdbcore.h): Ditto.
+ (value.h): Ditto.
+ (gdb_string.h): Ditto.
+ * nindy-tdep.c (gdbcore.h): Ditto.
+ * scm-lang.c (gdbcore.h): Ditto.
+ * scm-valprint.c (gdbcore.h): Ditto.
+ * w65-tdep.c (gdbcore.h): Ditto.
+ * z8k-tdep.c (gdbcore.h): Ditto.
+ * sparc-tdep.c (gdb_string.h): Include.
+ * valprint.c (valprint.h): Include.
+
+ * config/xm-lynx.h: Remove part of comment about INT_MIN
+ redefined warnings from defs.h, since INT_MIN define in
+ defs.h is now protected by #ifndef INT_MIN.
+ * config/i386/xm-i386bsd.h: Ditto.
+ * config/m68k/xm-hp300bsd.h: Ditto.
+ * config/m68k/xm-news.h: Ditto.
+
+ * config/pa/xm-hppah.h (INT_MIN): Remove bogus INT_MIN
+ definition as 0x80000000. The macro in defs.h is better.
+ * config/i386/xm-i386m3.h (INT_MIN): Ditto.
+ * config/i386/xm-i386mach.h (INT_MIN): Ditto.
+ * config/ns32k/xm-ns32km3.h (INT_MIN): Ditto.
+ * config/pa/xm-hppab.h: Ditto.
+
+ * core-aout.c (fetch_core_registers): Add prototype.
+ * hp300ux-nat.c (fetch_inferior_register): Ditto.
+ (store_inferior_register_1): Ditto.
+ (store_inferior_register): Ditto.
+ * config/m68k/tm-m68k.h (find_saved_regs): Ditto.
+ *scm-valprint.c (c_val_print): Ditto.
+ * procfs.c (add_fd): Ditto.
+ (remove_fd): Ditto.
+ (wait_fd): Ditto.
+ (sigcodename): Ditto.
+ (sigcodedesc): Ditto.
+ (procfs_kill_inferior): Ditto.
+ (procfs_xfer_memory): Ditto.
+ (procfs_store_registers): Ditto.
+ (create_procinfo): Ditto.
+ (procfs_init_inferior): Ditto.
+ (proc_set_exec_trap): Ditto.
+ (procfs_attach): Ditto.
+ (procfs_detach): Ditto.
+ (procfs_prepare_to_store): Ditto.
+ (procfs_files_info): Ditto.
+ (procfs_open): Ditto.
+ (procfs_wait): Ditto.
+ (procfs_fetch_registers): Ditto.
+ (procfs_mourn_inferior): Ditto.
+ (procfs_can_run): Ditto.
+ (procfs_thread_alive): Ditto.
+ (procfs_stop): Ditto.
+ * alpha-nat.c (fetch_core_registers): Ditto.
+ * config/alpha/tm-alpha.h (alpha_osf_skip_sigtramp_frame): Ditto.
+ * objfiles.c (ecoff_relocate_efi): Ditto.
+ * inflow.c (pass_signal): Ditto.
+ (handle_sigio): Ditto.
+ * annotate.c (breakpoint_changed): Ditto.
+ * callback.c (wrap): Ditto.
+ (fdbad): Ditto.
+ (fdmap): Ditto.
+ * utils.c (malloc_botch): Ditto.
+ (fputs_maybe_filtered): Ditto.
+ (vfprintf_maybe_filtered): Ditto.
+ * defs.h (notice_quit): Ditto.
+ * defs.h (xmalloc, xrealloc): Ditto.
+ * top.c (stop_sig): Ditto.
+ (init_signals): Ditto.
+ (user_defined_command): Ditto.
+ (source_cleanup_lines): Ditto.
+ (dont_repeat_command): Ditto.
+ (serial_log_command): Ditto.
+ (disconnect): Ditto.
+ * target.h (initialize_targets): Ditto.
+ * os9kread.c (read_minimal_symbols): Ditto.
+ * mdebugread.c (mdebug_psymtab_to_symtab): Ditto.
+ (fdr_name): Ditto.
+ (push_parse_stack): Ditto.
+ (pop_parse_stack): Ditto.
+ (is_pending_symbol): Ditto.
+ (add_pending): Ditto.
+ * serial.c (serial_logchar): Ditto.
+ (serial_interface_lookup): Ditto.
+ * serial.h (serial_log_command): Ditto.
+ * f-valprint.c (info_common_command): Ditto.
+ * gdbtypes.h (print_type_scalar): Ditto.
+ * scm-valprint.c (scm_scmlist_print): Ditto.
+ (scm_ipruk): Ditto.
+ * scm-lang.c (scm_printstr): Ditto.
+ (in_eval_c): Ditto.
+ (evaluate_subexp_scm): Ditto.
+ * scm-exp.c (scm_read_token): Ditto.
+ (scm_skip_ws): Ditto.
+ (scm_lreadparen): Ditto.
+ * m2-lang.c (emit_char): Ditto.
+ (m2_printchar): Ditto.
+ (m2_printstr): Ditto.
+ (m2_create_fundamental_type): Ditto.
+ * f-lang.c (emit_char): Ditto.
+ (f_printchar): Ditto.
+ (f_printstr): Ditto.
+ (f_create_fundamental_type): Ditto.
+ * ch-lang.c (chill_printchar): Ditto.
+ (chill_printstr): Ditto.
+ (chill_create_fundamental_type): Ditto.
+ (value_chill_length): Ditto.
+ (value_chill_card): Ditto.
+ (value_chill_max_min): Ditto.
+ (evaluate_subexp_chill): Ditto.
+ * ch-exp.c (PEEK_TOKEN): Ditto.
+ (peek_token_): Ditto.
+ (forward_token_): Ditto.
+ (parse_case_label): Ditto.
+ (parse_opt_untyped_expr): Ditto.
+ (parse_unary_call): Ditto.
+ (parse_call): Ditto.
+ (parse_named_record_element): Ditto.
+ (parse_tuple_element): Ditto.
+ (parse_opt_element_list): Ditto.
+ (parse_tuple): Ditto.
+ (parse_primval): Ditto.
+ (parse_operand6): Ditto.
+ (parse_operand5): Ditto.
+ (parse_operand4): Ditto.
+ (parse_operand3): Ditto.
+ (parse_operand2): Ditto.
+ (parse_operand1): Ditto.
+ (parse_operand0): Ditto.
+ (parse_expr): Ditto.
+ (parse_then_alternative): Ditto.
+ (parse_else_alternative): Ditto.
+ (parse_if_expression): Ditto.
+ (parse_untyped_expr): Ditto.
+ (growbuf_by_size): Ditto.
+ (match_simple_name_string): Ditto.
+ (decode_integer_value): Ditto.
+ (decode_integer_literal): Ditto.
+ (match_float_literal): Ditto.
+ (match_float_literal): Ditto.
+ (match_string_literal): Ditto.
+ (match_character_literal): Ditto.
+ (match_integer_literal): Ditto.
+ (match_bitstring_literal): Ditto.
+ (write_lower_upper_value): Ditto.
+ * ch-lang.h (type_lower_upper): Ditto.
+ * c-lang.c (emit_char): Ditto.
+ * dwarfread.c (free_utypes): Ditto.
+ * stabsread.h (resolve_cfront_continuation): Ditto.
+ * stabsread.c (get_substring): Ditto.
+ (read_one_struct_field): Ditto.
+ * stabsread.h (process_later): Ditto.
+ * demangle.c (set_demangling_command): Ditto.
+ * defs.h (set_demangling_style): Ditto.
+ * maint.c (maintenance_info_command): Ditto.
+ (print_section_table): Ditto.
+ (maintenance_info_sections): Ditto.
+ (maintenance_print_command): Ditto.
+ * symtab.h (maintenance_print_statistics): Ditto.
+ * objfiles.h (in_plt_section): Ditto.
+ * objfiles.c (add_to_objfile_sections): Ditto.
+ * bcache.c (hash): Ditto.
+ (lookup_cache): Ditto.
+ * exec.c (bfdsec_to_vmap): Ditto.
+ (ignore): Ditto.
+ * f-exp.y (growbuf_by_size, match_string_literal): Ditto.
+ * language.c (unk_lang_printchar): Ditto.
+ (unk_lang_printstr): Ditto.
+ (unk_lang_create_fundamental_type): Ditto.
+ (unk_lang_print_type): Ditto.
+ (unk_lang_val_print): Ditto.
+ (unk_lang_value_print): Ditto.
+ * target.c (update_current_target): Ditto.
+ (debug_to_open): Ditto.
+ (debug_to_close): Ditto.
+ (debug_to_attach): Ditto.
+ (debug_to_detach): Ditto.
+ (debug_to_resume): Ditto.
+ (debug_to_wait): Ditto.
+ (debug_to_fetch_registers): Ditto.
+ (debug_to_store_registers): Ditto.
+ (debug_to_prepare_to_store): Ditto.
+ (debug_to_xfer_memory): Ditto.
+ (debug_to_files_info): Ditto.
+ (debug_to_insert_breakpoint): Ditto.
+ (debug_to_remove_breakpoint): Ditto.
+ (debug_to_terminal_init): Ditto.
+ (debug_to_terminal_inferior): Ditto.
+ (debug_to_terminal_ours_for_output): Ditto.
+ (debug_to_terminal_ours): Ditto.
+ (debug_to_terminal_info): Ditto.
+ (debug_to_kill): Ditto.
+ (debug_to_load): Ditto.
+ (debug_to_lookup_symbol): Ditto.
+ (debug_to_create_inferior): Ditto.
+ (debug_to_mourn_inferior): Ditto.
+ (debug_to_can_run): Ditto.
+ (debug_to_notice_signals): Ditto.
+ (debug_to_thread_alive): Ditto.
+ (debug_to_stop): Ditto.
+ * breakpoint.h (set_breakpoint_sal): Ditto.
+ * remote-utils.c (usage): Ditto.
+ * remote.c (set_thread): Ditto.
+ (remote_thread_alive): Ditto.
+ (get_offsets): Ditto.
+ (read_frame): Ditto.
+ (remote_insert_breakpoint): Ditto.
+ (remote_remove_breakpoint): Ditto.
+ * sparc-nat.c (fetch_core_registers): Ditto.
+ * corelow.c (add_to_thread_list): Ditto.
+ (ignore): Ditto.
+ * inftarg.c (proc_wait): Ditto.
+ * infptrace.c (udot_info): Ditto.
+ (fetch_register): Ditto.
+ * ser-unix.c (hardwire_noflush_set_tty_state): Ditto.
+ (hardwire_print_tty_state): Ditto.
+ (hardwire_flush_output): Ditto.
+ (hardwire_flush_input): Ditto.
+ (hardwire_send_break): Ditto.
+ (hardwire_setstopbits): Ditto.
+ * ser-tcp.c (tcp_return_0): Ditto.
+ (tcp_noflush_set_tty_state): Ditto.
+ (tcp_print_tty_state): Ditto.
+ * solib.c (match_main): Ditto.
+ * gdbtypes.c (print_bit_vector): Ditto.
+ (print_arg_types): Ditto.
+ (dump_fn_fieldlists): Ditto.
+ (print_cplus_stuff): Ditto.
+ * symfile.h (entry_point_address): Ditto.
+ * symfile.c (decrement_reading_symtab): Ditto.
+ * valops.c (value_arg_coerce): Ditto.
+ * value.h (find_function_in_inferior): Ditto.
+ (value_allocate_space_in_inferior): Ditto.
+ * values.c (vb_match): Ditto.
+ * thread.c (info_thread_command): Ditto.
+ (restore_current_thread): Ditto.
+ (thread_apply_all_command): Ditto.
+ (thread_apply_command): Ditto.
+ * inferior.h (write_pc_pid): Ditto.
+ * infrun.c (delete_breakpoint_current_contents): Ditto.
+ * breakpoint.c (print_it_normal): Ditto.
+ (watchpoint_check): Ditto.
+ (print_it_done): Ditto.
+ (print_it_noop): Ditto.
+ (maintenance_info_breakpoints): Ditto.
+ (create_longjmp_breakpoint): Ditto.
+ (hbreak_command): Ditto.
+ (thbreak_command): Ditto.
+ (watch_commnd_1): Ditto.
+ (rwatch_command): Ditto.
+ (awatch_command): Ditto.
+ (do_enable_breakpoint): Ditto.
+ * ch-valprint.c (chill_val_print_array_elements): Ditto.
+ * eval.c (evaluate_subexp): Ditto.
+ (get_label): Ditto.
+ (evaluate_struct_tuple): Ditto.
+ * eval.c (init_array_element): Ditto.
+
+ * alpha-tdep.c (push_sigtramp_desc): Add prototype and make static.
+ * breakpoint.c (hw_breakpoint_used_count): Ditto.
+ (hw_watchpoint_used_count): Ditto.
+ * findvar.c (write_register_gen): Ditto.
+ (read_register_pid): Ditto.
+ * symtab.c (cplusplus_hint): Ditto.
+ * infcmd.c (breakpoint_auto_delete_contents): Ditto.
+ * ch-valprint.c (chill_print_type_scalar): Ditto.
+ * gdbtypes.c (add_name): Ditto.
+ (add_mangled_type): Ditto.
+ (cfront_mangle_name): Ditto.
+ * sparc-tdep.c (isbranch): Ditto.
+ * inftarg.c (child_stop): Ditto.
+ * win32-nat.c (child_stop): Ditto.
+ * mac-nat.c (child_stop): Ditto.
+ * remote-utils.c (sr_com): Ditto.
+ * dbxread.c (process_now): Ditto.
+ * ch-exp.c (require): Ditto.
+ (check_token): Ditto.
+ (expect): Ditto.
+ (parse_mode_call): Ditto.
+ (parse_mode_or_normal_call): Ditto.
+ * scm-lang.c (scm_lookup_name): Ditto
+ * f-lang.c (allocate_saved_bf_node): Ditto.
+ (allocate_saved_function_node): Ditto.
+ (allocate_saved_f77_common_node): Ditto.
+ (allocate_common_entry_node): Ditto.
+ (add_common_block): Ditto.
+ (add_common_entry): Ditto.
+ (find_first_common_named): Ditto.
+ (patch_common_entries): Ditto.
+ (patch_all_commons_by_name): Ditto.
+ (clear_bf_list): Ditto.
+ (get_bf_for_fcn): Ditto.
+ (clear_function_list): Ditto.
+ * scm-exp.c (scm_istr2int): Ditto.
+ (scm_istring2number): Ditto.
+ * scm-valprint.c (scm_inferior_print): Ditto.
+ * f-typeprint.c (print_equivalent_f77_float_type): Ditto.
+ * f-valprint.c (f77_get_dynamic_length_of_aggregate): Ditto.
+ (f77_create_arrayprint_offset_tbl): Ditto.
+ (f77_print_array_1): Ditto.
+ (f77_print_array): Ditto.
+ (list_all_visible_commons): Ditto.
+ (there_is_a_visible_common_named): Ditto.
+ * mdebugread.c (ecoff_relocate_efi): Ditto.
+ * callback.c (os_close): Ditto.
+ (os_get_errno): Ditto.
+ (os_isatty): Ditto.
+ (os_lseek): Ditto.
+ (os_open): Ditto.
+ (os_read): Ditto.
+ (os_read_stdin): Ditto.
+ (os_write): Ditto.
+ (os_write_stdout): Ditto.
+ (os_rename): Ditto.
+ (os_system): Ditto.
+ (os_time): Ditto.
+ (os_unlink): Ditto.
+ (os_shutdown): Ditto.
+ (os_init): Ditto.
+ (os_printf_filtered): Ditto.
+
+ * scm-lang.h (scm_parse): Change old style decl to prototype.
+ * config/alpha/tm-alphalinux.h (alpha_linux_sigtramp_offset): Ditto.
+ * top.c (init_proc): Ditto.
+ (query_hook): Ditto.
+ (error_hook): Ditto.
+ * f-lang.c (c_value_print): Ditto.
+ * ch-exp.c (parse_expression): Ditto.
+ (parse_primval): Ditto.
+ (parse_untyped_expr): Ditto.
+ (parse_opt_untyped_expr): Ditto.
+ (ch_lex): Ditto.
+ * config/sparc/tm-sparc.h (sparc_init_extra_frame_info): Ditto.
+ (sparc_frame_saved_pc): Ditto.
+ (sparc_push_dummy_frame): Ditto.
+ (sparc_pop_frame): Ditto.
+ * defs.h (fclose): Ditto.
+ (atof): Ditto.
+ (error_hook): Ditto.
+
+ * arc-tdep.c (single_step): Change arg to type "enum target_signal".
+ * rs6000-tdep.c (single_step): Ditto.
+ * sparc-tdep.c (single_step): Ditto.
+
+ * breakpoint.c (cleanup_executing_breakpoints): Change unused arg type
+ to PTR which is what make_cleanup expects.
+ * utils.c (null_cleanup): Change arg type to PTR.
+ * defs.h (null_cleanup): Change prototype to match actual function.
+ * config/sparc/tm-sparc.h (struct frame_info): Move forward decl.
+ * ch-valprint.c (chill_val_print): Cast 2nd arg of
+ chill_print_type_scalar to LONGEST.
+ * infrun.c (wait_for_inferior): Have empty switch case for
+ BPSTAT_WHAT_CHECK_SHLIBS when SOLIB_ADD is not defined.
+ (stop_on_solib_events): Only needed if SOLIB_ADD is defined.
+ * infcmd.c (attach_command): Only need auto_solib_add if SOLIB_ADD
+ is defined.
+ * symfile.c (generic_load): Scan long int using a long int spec,
+ not an int spec.
+ * infptrace.c (udot_info): Only need local variables if KERNEL_U_SIZE
+ is defined.
+ (fetch_register): Only need function if FETCH_INFERIOR_REGISTERS is
+ not defined.
+ * inflow.c (handle_sigio): Only need prototype when the actual
+ function is compiled in.
+ * valprint.c (longest_to_int): Expand error message to be
+ separate messages for args larger than largest signed int
+ and args smaller than smallest signed int.
+ * valprint.c (print_longest): Fix problems with support for case
+ where compiler supports type "long long" but the runtime doesn't
+ support printing them with "%ll".
+ * scm-valprint.c (scm_scmlist_print, scm_scmval_print): Change
+ return types to void since we don't actually return anything
+ meaningful and callees ignore the values anyway.
+ * procfs.c (modify_inherit_on_fork_flag): Enclose pr_flags in PIOCSET
+ ifdef.
+ (modify_run_on_last_close_flag): Ditto.
+ (wait_fd): Enclose local variables "num_fds" and "i" LOSING_POLL
+ ifdef
+ * alpha-tdep.c (push_sigtramp_desc): Return proc_desc rather than
+ random value.
+ * infrun.c (wait_for_inferior): Ensure random_signal is not used
+ uninitialized.
+ * valops.c (call_function_by_hand): Ensure struct_addr is not used
+ uninitialized.
+ * breakpoint.c (watch_command_1): Ensure prev_frame is not used
+ uninitialized.
+ * utils.c (vfprintf_maybe_filtered): Change second arg from "char *"
+ to "const char *".
+ * infptrace.c (udot_info): Add two dummy args so that the type is
+ correct for passing to add_info.
+ * f-lang.c (saved_fcn): Move decl to head of file so it can be used
+ in prototypes.
+ (saved_bf_symnum): Ditto.
+ (SAVED_FUNCTION): Ditto.
+ (SAVED_FUNCTION_PTR): Ditto.
+ (SAVED_BF): Ditto.
+ (SAVED_BF_PTR): Ditto.
+ * ch-exp.c (parse_named_record_element): Build error message in
+ temporary buffer before passing it to expect, rather than passing
+ wrong number of args to expect.
+ * demangle.c (set_demangling_style): Call set_demangling_command with
+ correct number of arguments.
+ * inferior.h (terminal_init_inferior_with_pgrp): Change arg type to
+ int to match actual function.
+ (os_isatty): Call fdmap with right number of arguments, was missing
+ the host_callback* arg.
+ * target.c (cleanup_target): Prototype all functions casts.
+ * target.h (one_stepped, single_step): Declare here and convert
+ single_step to prototype.
+ * infrun.c (one_stepped, single_step): Don't declare externs
+ here, they have moved to target.h.
+ * eval.c (init_array_element): Declare previously undeclared
+ last two args as LONGEST.
+ * dcache.c (dcache_xfer_memory): Change xfunc decls to prototype form.
+
+Thu Jul 25 16:11:54 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * dsrec.c (load_srec): Protect ANSI style function parms with PARAMS.
+
+Mon Jul 22 18:13:27 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (os9kread.o): Remove dependency on partial-stab.h.
+ * dbxread.c (read_dbx_symtab end_psymtab), partial-stab.h: Don't
+ use partial_symtab->textlow==0 as a flag, as 0 is a legitimate
+ text address. Use a seperate flag (textlow_not_set) instead.
+ This makes stabs in ELF .o files work a lot better.
+ * mdebugread.c xcoffread.c: Define textlow_not_set for
+ partial-stab.h.
+ * stabsread.h (end_psymtab): Add textlow_not_set arg to prototype.
+
+Sat Jul 20 10:41:06 1996 Fred Fish <fnf@cygnus.com>
+
+ * dwarf2read.c (struct filenames): Change internal "struct file"
+ to "struct fileinfo" to avoid conflict with "struct file" in
+ <sys/file.h> on HPUX and Solaris.
+
+Fri Jul 19 14:05:57 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * dwarf2read.c: New file, DWARF 2 reader originally contributed by
+ Brent Benson, with additions by Gary Funck and Jerry Kreuscher.
+ * Makefile.in (COMMON_OBS): Add dwarf2read.o.
+ (SFILES): Add dwarf2read.c.
+ (dwarf2read.o): Add build rule.
+ * symfile.h (dwarf2_has_info, dwarf2_build_psymtabs): Declare
+ exported functions.
+ * elfread.c (elf_symfile_read): Call them.
+ (elf_symtab_read) [HARRIS_TARGET]: Skip some special symbols.
+
+Thu Jul 18 01:22:01 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * symfile.c (symfile_bfd_open):
+ * exec.c (exec_file_command): for __GO32__ and __WIN32__ systems,
+ free the user from having to type the .exe extension.
+
+Wed Jul 17 06:54:50 1996 Mark Alexander <marka@cygnus.com>
+
+ * mon960-rom.c: Shorten the mon960_inits string to a single
+ carriage return; this prevents a hang on connecting immediately
+ after powerup, when MON960 is attempting autobaud detection.
+
+Tue Jul 16 23:47:04 1996 Mark Alexander <marka@cygnus.com>
+
+ * a29k-tdep.c (get_saved_register): Allow PC to be modified
+ when innermost frame is selected, but not in outer frames.
+
+Tue Jul 16 23:37:25 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * command.c (do_setshow_command): Don't segfault when showing
+ var_string and var_string_noescape vars that are NULL.
+
+Mon Jul 15 16:55:48 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * win32-nat.c (handle_load_dll): dos_path_to_unix_path renamed to
+ cygwin32_conv_to_posix_path.
+ (child_create_inferior): unix_path_to_dos_path renamed to
+ cygwin32_conv_to_win32_path. Rewrite code to translate PATH.
+
+Mon Jul 15 16:44:05 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * defs.h printcmd.c: Create global disassemble_info structure
+ tm_print_insn_info.
+ * i386-tdep.c (set_assembly_language_command): set
+ tm_print_insn_info.mach to the appropriate value for 386 or 8086
+ disassembly.
+ * printcmd.c (print_insn): Move init of disassembler_info to
+ _initialize_printcmd. Set endian for disassembler here.
+ * sparc-tdep.c: Set tm_print_insn_info.mach as appropriate to
+ select sparc/sparclite.
+ * config/sparc/{tm-sparc.h tm-sparclite.h}: Get rid of
+ TM_PRINT_INSN. Set TM_PRINT_INSN_MACH to
+ bfd_mach_sparc/bfd_mach_sparc_sparclite.
+
+Fri Jul 12 19:04:32 1996 Fred Fish <fnf@cygnus.com>
+
+ * hpread.c (hpread_lookup_type): Use xmmalloc/xmrealloc rather
+ than xmalloc/xrealloc.
+
+Fri Jul 12 17:59:47 1996 Fred Fish <fnf@cygnus.com>
+
+ * objfiles.c (map_to_file): Error return from mmalloc_findbase is
+ a NULL pointer, not a -1.
+
+Fri Jul 12 10:16:24 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * i386-tdep.c (set_assembly_language_command): New routine to
+ select between i386 and i8086 instruction sets for disassembly.
+ New command `set assembly-language {i386 i8086}'.
+
+Thu Jul 11 21:13:21 1996 Mark Alexander <marka@cygnus.com>
+
+ * monitor.c (monitor_write_memory, monitor_read_memory_single):
+ Disable use of "long long" memory read/write commands; can't
+ use them because we hold the values to read/write in an int
+ variable, and because strtoul fails on values that exceed the
+ size of a long. This fixes breakpoint problems on MON960.
+
+Thu Jul 11 11:39:31 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/m68k/xm-hp300hpux.h (HAVE_MMAP): Remove definition.
+ * config/pa/xm-hppah.h (HAVE_MMAP): Ditto.
+
+Wed Jul 10 16:54:41 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (MMALLOC_CFLAGS): Eliminate intermediate MMALLOC_DISABLE
+ and MMALLOC_CHECK macros, and add comment indicating how host dependent
+ makefile fragment should modify MMALLOC_CFLAGS to not use mmalloc, or
+ to use it but to not do heap corruption checking.
+ * gdbserver/Makefile.in: Ditto.
+ * utils.c (init_malloc): Replace warning() use with direct call of
+ fprintf_unfiltered, since current_target has not yet been set and thus
+ we cannot use warning(). If we try to use mmcheck and it fails,
+ suggest that this configuration needs NO_MMCHECK or MMCHECK_FORCE
+ defined. Other small mmalloc related cleanups.
+ * config/sparc/sun4os4.mh (MMALLOC_CFLAGS): Define MMCHECK_FORCE to 1.
+ * config/alpha/alpha-osf2.mh (MMALLOC_CFLAGS): Set to -DNO_MMCHECK.
+
+ * config/sparc/xm-sun4os4.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ * config/i386/xm-i386v4.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ * config/i386/xm-linux.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ * config/m68k/xm-hp300hpux.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ * config/m68k/xm-m68kv4.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT);
+ * config/m68k/xm-sun3os4.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ * config/pa/xm-hppah.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ * config/sparc/xm-sun4sol2.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ Remove obsolete defines.
+
+ * config/alpha/alpha-linux.mh (MMALLOC_DISABLE):
+ * config/alpha/alpha-osf1.mh (MMALLOC_DISABLE):
+ * config/rs6000/rs6000.mh (MMALLOC_DISABLE):
+ * config/rs6000/aix4.mh (MMALLOC_DISABLE):
+ * config/powerpc/aix4.mh (MMALLOC_DISABLE):
+ * config/powerpc/aix.mh (MMALLOC_DISABLE):
+ * config/ns32k/ns32km3.mh (MMALLOC_DISABLE):
+ * config/mips/mipsm3.mh (MMALLOC_DISABLE):
+ * config/mips/decstation.mh (MMALLOC_DISABLE):
+ * config/m88k/cxux.mh (MMALLOC_DISABLE):
+ * config/i386/i386mk.mh (MMALLOC_DISABLE):
+ * config/i386/i386m3.mh (MMALLOC_DISABLE):
+ * config/i386/i386gnu.mh (MMALLOC_DISABLE):
+ Use MMALLOC_CFLAGS instead.
+
+Tue Jul 9 22:41:12 1996 Jeffrey A Law (law@cygnus.com)
+
+ * h8300-tdep.c: Remove some outdated comments.
+ (h8300_skip_prologue): Rework to be more correct for the H8/300H.
+ Handle stm.l insns for the H8/S.
+ (examine_prologue): Likewise.
+
+Tue Jul 9 16:48:55 1996 Raymond Jou <rjou@mexican.cygnus.com>
+
+ * ser-mac.c (mac_close): Change a typo SetSetBuf to SerSetBuf.
+
+Mon Jul 08 08:50:39 1996 Mark Alexander <marka@cygnus.com>
+
+ * mon960-rom.c (mon960_open): Add floating point detection to
+ prevent hang on non-FPU processors (PR 9775).
+ (mon960_cmds): Swap setmem.cmdw and setmem.cmdl to fix problem
+ setting breakpoints and improve loading speed.
+
+Sun Jul 7 14:57:34 1996 Fred Fish <fnf@cygnus.com>
+
+ * coffread.c (record_minimal_symbol): Don't presave name string
+ on symbol_obstack before passing to prim_record_minimal_symbol.
+ It now handles saving the string itself.
+ * dbxread.c (read_dbx_dynamic_symtab): Ditto.
+ * mipsread.c (read_alphacoff_dynamic_symtab): Ditto.
+ * os9kread.c (record_minimal_symbol): Ditto.
+ * solib.c (solib_add_common_symbols): Ditto.
+
+ * coffread.c (coff_symtab_read): Don't presave name string on
+ symbol_obstack before passing to prim_record_minimal_symbol_and_info.
+ It now handles saving the string itself.
+ * dbxread.c (record_minimal_symbol): Ditto.
+ * elfread.c (record_minimal_symbol_and_info): Ditto.
+
+ * dstread.c (record_minimal_symbol): Remove static function that just
+ called prim_record_minimal_symbol with the same args (after change to
+ prim_record_minimal_symbol to do it's own name string saves).
+ * nlmread.c (record_minimal_symbol): Ditto.
+ * somread.c (record_minimal_symbol): Ditto.
+
+ * hpread.c (hpread_read_enum_type): Save symbol name on symbol obstack.
+ (hpread_read_function_type): Ditto.
+ (hpread_process_one_debug_symbol): Ditto.
+ * mdebugread.c (parse_symbol): Ditto.
+ (new_symbol): Ditto.
+ * minsyms.c (prim_record_minimal_symbol_and_info): Ditto.
+
+ * coffread.c (process_coff_symbol): Use obsavestring to save
+ SYMBOL_NAME, rather than obstack_copy0.
+ * dstread.c (create_new_symbol): Ditto
+ * symfile.c (obconcat): Ditto.
+ * stabsread.c (patch_block_stabs): Ditto.
+ * xcoffread.c (SYMNAME_ALLOC): Ditto.
+
+ * symfile.c (obsavestring): Update comments
+ * solib.c (solib_add_common_symbols): Remove local var origname.
+
+Wed Jul 3 15:56:08 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure: Re-build with autoconf-2.10.
+
+ * sparcl-tdep.c (_initialize_sparc_tdep) config/sparc/tm-sparc.h,
+ config/sparc/tm-sparclite.h: Initialize tm_print_insn from
+ TM_PRINT_INSN, which comes from the tm file.
+
+Tue Jul 02 21:41:20 1996 Mark Alexander <marka@cygnus.com>
+
+ * coffread.c, dbxread.c, elfread.c, mipsread.c, nlmread.c,
+ os9kread.c: Replace identical sym_offsets functions with
+ default_symfile_offsets.
+ * somread.c (som_symfile_offsets): Use new SIZEOF_SECTION_OFFSETS
+ macro to allocate section_offsets.
+ * symfile.c (default_symfile_offsets): New function.
+ * symfile.h: Declare default_symfile_offsets.
+ * symtab.h: Define SIZEOF_SECTION_OFFSETS macro to
+ simplify allocation of section_offsets.
+
+Tue Jun 11 12:02:55 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (INTERNAL_LDFLAGS): Add in flags from configure.
+ * configure configure.in: Only make sol-thread.o for native.
+ Also, switch to dlopened libthread_db.so.1.
+ * sol-thread.c: Switch to using dlopen to get the thread_db
+ library.
+
+Thu Jun 13 16:53:25 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure, configure.in: Change test for libthread_db to only
+ work for configs where build/host/target are the same.
+
+Tue Jul 2 15:04:20 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/powerpc/{linux.mh,xm-linux.h}: New files, for Linux on
+ PowerPC.
+
+ * configure.in (powerpc-*-linux): Add Linux, System V, and ELF
+ support.
+ * configure: Regenerate.
+
+Mon Jul 1 13:00:43 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Raymond Jou <rjou@mexican.cygnus.com>:
+ * mpw-make.sed: Add lines to whack out autoconf hook
+ @CONFIG_LDFLAGS@.
+
+Mon Jul 01 11:07:15 1996 Mark Alexander <marka@cygnus.com>
+
+ * remote-e7000.c (e7000_stop): New function.
+
+Fri Jun 28 06:34:19 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * configure, configure.in: Add target sparclet.
+ * monitor.h, monitor.c: Added monitor flags MO_NO_ECHO_ON_SETMEM
+ (don't expect echo on setmem command), MO_RUN_FIRST_TIME (if
+ command to start process running on target is different from one
+ to continue execution), MO_HEX_PREFIX (if addresses from monitor
+ have a "0x" prefix).
+ * monitor.c, parse.c, sparc-tdep.c: Don't require strings in the
+ registers array. This is to allow NULLs to be place holders in
+ the tm-*.h file so that only minor changes are needed when a new
+ processor is introduced (eg, one without floating point).
+ * sparc-tdep.c: Conditionally remove dependancies on floating
+ point.
+ * sparclet-rom.c, config/sparc/sparclet.mt,
+ config/sparc/tm-sparclet.h: New files for target sparclet.
+ * symfile.c (load_command): Add option for 2nd parameter; a load
+ offset added to the vma of each section.
+
+Fri Jun 28 05:39:19 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * main.c (main): Add option "l" for setting remote_timeout.
+
+Fri Jun 28 05:25:18 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * remote-e7000.c, remote.c, target.h, top.c: Add set option
+ "remote_timeout" for setting remote_timeout. Add set option
+ "use_hard_breakpoints" for setting hardware .vs. memory
+ breakpoints.
+
+Fri Jun 28 04:32:18 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * remote-e7000.c (e7000_parse_device): New function.
+ Add option "tcp_remote" to target command if using
+ tcp to connect to a remote host which is then connected
+ via serial port to the e7000 (for exampole, a port master).
+ (e7000_open): Change to call e7000_parse_device.
+
+Fri Jun 28 03:47:17 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * monitor.c (monitor_debug): Fix remotedebug buffering.
+
+Thu Jun 27 18:24:17 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/i386/cygwin32.mh, config/powerpc/cygwin32.mh
+ (NATDEPFILES): Add a space.
+
+Wed Jun 26 06:05:39 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * gdbtypes.c (create_array_type): If TYPE_LENGTH (result_type)
+ is zero, set TYPE_FLAG_TARGET_STUB to force reevaluation of the type.
+
+ * ch-exp.c (calculate_array_length): Function removed.
+
+Tue Jun 25 17:41:06 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * remote-e7000.c (e7000_read_inferior_memory_large): New function.
+ (e7000_xfer_inferior_memory): Call it.
+
+Tue Jun 25 23:14:07 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * gdb/gdbserver/Makefile.in (docdir): Removed.
+
+Tue Jun 25 22:05:38 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir):
+ Use autoconf set values.
+ (docdir): Removed.
+ * configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ * nlm/Makefile.in (bindir, libdir, datadir, mandir, infodir,
+ includedir): Use autoconf set values.
+ (docdir): Removed.
+ * nlm/configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ * nlm/configure: Rebuilt.
+ * gdb/gdbserver/Makefile.in (datadir): Set to $(prefix)/share.
+
+Mon Jun 24 09:56:14 1996 Angela Marie Thomas (angela@cygnus.com)
+
+ * stabsread.c (read_cfront_member_functions): add type
+
+Sun Jun 23 23:40:48 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * win32-nat.c: #include <unistd.h>.
+ (unix_paths_to_dos_paths, dos_paths_to_unix_paths): Delete.
+ (child_create_inferior): Convert only env var PATH to win32 style.
+ (set_pathstyle_dos): Delete.
+ (_initialize_inftarg): Delete dos-path-style command.
+
+Thu Jun 20 13:42:23 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in: Revise sol-thread.o test.
+ * configure: Regenerated.
+
+ * source.c (find_source_lines): Reassign size to result of read.
+
+Tue Jun 18 16:25:54 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * h8300-dep.c (gdb_print_insn_h8300): Handle the H8/S.
+ (h8300_command): Likewise.
+ (set_machine): Likewise.
+ (set_machine_hook): Likewise.
+ (_initialize_h8300m): Likewise.
+
+ * config/h8300/tm-h8300.h (h8300smode): Declare.
+
+Sun Jun 16 15:21:51 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * somsolib.c (som_solib_create_inferior_hook): Handle tracking
+ of shl_load calls for hpux10.
+
+Thu Jun 13 11:16:10 1996 Tom Tromey <tromey@thepub.cygnus.com>
+
+ * config.in: Regenerated.
+ * acconfig.h (HAVE_THREAD_DB_LIB): Added entry.
+
+ * configure: Regenerated.
+ * aclocal.m4 (CY_AC_PATH_TCLH, CY_AC_PATH_TKH): Use odd names to
+ avoid name clashes with SunOS headers.
+
+Tue Jun 11 19:52:50 1996 Fred Fish <fnf@cygnus.com>
+
+ From Michael Snyder <Michael_Snyder@next.com>:
+ * bcache.c (print_bcache_statistics): Avoid divide-by-zero
+ exception if one or more objfile has no symbols, such as when
+ a dynamic library has been stripped.
+
+Tue Jun 11 12:02:55 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (INTERNAL_LDFLAGS): Add in flags from configure.
+ * configure configure.in: Only make sol-thread.o for native.
+ Also, switch to dlopened libthread_db.so.1.
+ * sol-thread.c: Switch to using dlopen to get the thread_db
+ library.
+
+Mon Jun 10 14:17:19 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/sparc/{xm-sun4sol2.h,xm-sun4os4.h} (MMAP_BASE_ADDRESS):
+ Change from 0xE0000000 to 0xC0000000.
+
+Thu Jun 6 17:10:32 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/powerpc/xm-solaris.h: Initial version of support for
+ Solaris on PowerPC.
+
+Wed Jun 5 01:52:57 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * configure.in (configdirs): Force 4100 builds to use 4300 GDB
+ target.
+ * configure: Rebuild.
+
+ * config/mips/vr4300el.mt (SIM_OBS): Include simulator in
+ little-endian builds.
+
+Mon Jun 3 11:48:29 1996 Jeffrey A Law (law@cygnus.com)
+
+ * inftarg.c (child_thread_alive): Protect declaration with
+ #ifndef CHILD_THREAD_ALIVE.
+
+ * source.c (find_source_lines): Check the time on the symtab's bfd if
+ it exists, else check the time on the exec_bfd.
+
+Thu May 30 09:43:17 1996 Mark Alexander <marka@cygnus.com>
+
+ * dsrec.c (make_srec): Fix calculation of address size
+ to allow addresses less than 0x100.
+
+Thu May 30 04:24:09 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * ch-exp.c (ch_lex): In case of LOC_TYPEDEF call calculate_array_length.
+
+Tue May 28 16:15:47 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * remote-mips.c: cannot use EINVAL for breakpoint test since
+ its value varies for different hosts (e.g. go32's is 19, while
+ sunos is 22). Changed to hardcoded 22 since that is what the
+ mips boards return.
+
+Tue May 28 11:14:58 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * configure: Regenerated.
+ * aclocal.m4 (CY_AC_PATH_TCLH): Don't use AC_TRY_RUN.
+ (CY_AC_PATH_TKH): Don't use AC_TRY_RUN.
+
+Sun May 26 16:56:35 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * solib.c (solib_absolute_prefix, solib_search_path): New variables.
+ (_initialize_solib): Add set/show commands for those variables.
+ (solib_map_sections): Implement searching using them.
+
+Sun May 26 14:14:49 1996 Fred Fish <fnf@cygnus.com>
+
+ Changes from: David Mosberger-Tang <davidm@azstarnet.com>
+
+ * NEWS: Add Alpha Linux as a new native configuration.
+
+ * mdebugread.c (parse_symbol): When we find a malloc() symbol with
+ return type VOID, assume no debugging info is available for that
+ object file and patch the return value into VOID *. Otherwise,
+ operations requiring an implicit call to malloc() will fail.
+
+ * infrun.c (wait_for_inferior): The criterion to detect entering a
+ sigtramp handler is now: (a) the current pc is inside a sigtramp
+ handler, (b) the previous pc is not in a sigtramp handler, and (c)
+ the current stack pointer is "inner" than the old one. Condition
+ (c) is new to avoid mistaking a return from a signal handler into
+ sigtramp as a new sigtramp invocation.
+
+ * dcache.c (struct dcache_block): Declare addr as CORE_ADDR. An
+ int may not be big enough to hold an address.
+ (dcache_hit): Ditto.
+ (dcache_peek_byte): Fix indentation.
+
+ * configure.in (alpha-*-linux*): Add target.
+ * configure: Rebuild
+
+ * config/alpha/tm-alpha.h (PROC_DESC_IS_DYN_SIGTRAMP): New macro.
+ (SET_PROC_DESC_IS_DYN_SIGTRAMP): Ditto.
+ (DYNAMIC_SIGTRAMP_OFFSET): Ditto.
+ (SIGCONTEXT_ADDR): Ditto.
+ (FRAME_PAST_SIGTRAMP_FRAME): Ditto.
+
+ * config/alpha/alpha-linux.mh: New file.
+ * config/alpha/alpha-linux.mt: Ditto.
+ * config/alpha/nm-linux.h: Ditto.
+ * config/alpha/tm-alphalinux.h: Ditto.
+ * config/alpha/xm-alphalinux.h: Ditto.
+ * config/alpha/xm-alphaosf.h: Renamed from xm-alpha.h.
+ * config/alpha/alpha-osf1.mh (XM_FILE): Change from xm-alpha.h to
+ xm-alphaosf.h.
+ * config/alpha/alpha-osf2.mh: Ditto.
+
+ * blockframe.c (find_pc_partial_function): Pass PC to
+ SIGTRAMP_START and SIGTRAMP_END macros for the benefit of systems
+ that detect sigtramp code via designated code sequences (as is the
+ case for Linux/Alpha, for example).
+
+ * config/i386/tm-i386bsd.h: Change SIGTRAMP_START and SIGTRAMP_END
+ to ignore new PC argument.
+ * config/m68k/tm-hp300bsd.h: Ditto.
+ * config/vax/tm-vax.h: Ditto.
+
+ * alpha-tdep.c (alpha_linux_sigtramp_offset): New function.
+ (alpha_osf_skip_sigtramp_frame): Ditto.
+ (push_sigtramp_desc): Ditto.
+ (alpha_find_saved_regs): Use SIGCONTEXT_ADDR macro to extract
+ sigcontext address from frame.
+ (alpha_saved_pc_after_call): When in sigtramp, use
+ alpha_frame_saved_pc() instead of read-register().
+ (after_prologue): When inside a dynamically generated sigtramp
+ function, there is no prologue, so return address of first
+ instruction.
+ (alpha_in_prologue): Fix typo in comment.
+ (find_proc_desc): Use macro DYNAMIC_SIGTRAMP_OFFSET to determine
+ whether we're inside a dynamicaly generated sigtramp function. If
+ so, create and push and appropriate procedure descriptor.
+ (alpha_frame_chain): Use macro FRAME_PAST_SIGTRAMP_FRAME to obtain
+ the frame past a sigtramp frame (if the current frame is indeed a
+ sigtramp function).
+ (init_extra_frame_info): Don't read next frame register off of
+ stack-pointer when inside a dynamiccaly generated sigtramp.
+ (alpha_pop_frame): Also unlink and destroy procedure descriptors
+ created for dynamically generated sigtramp functions.
+
+ * alpha-nat.c: When compiling under Linux, include <asm/reg.h> and
+ <alpha/ptrace.h> instead of <machine/reg.h>
+
+Tue Jul 2 13:58:10 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_validate_task_sc):
+ Give terminal to gdb while asking question.
+ (inf_resume): Don't validate the task suspend-count while execing.
+
+Thu Jun 13 11:04:52 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_validate_task_sc): Query user before clearing any
+ additional suspend count.
+ (S_proc_wait_reply, gnu_attach): Don't call inf_validate_task_sc.
+ (inf_resume): Call inf_validate_task_sc here.
+ (gnu_resume): Call inf_update_procs to ensure noticing new threads.
+
+Fri Jun 7 17:00:43 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (gnu_create_inferior: attach_to_child): Return PID.
+
+Thu May 23 15:13:56 1996 Jeffrey A Law (law@cygnus.com)
+
+ * h8300-tdep.c (IS_PUSH): Refine.
+ (IS_MOVE_FP, IS_MOV_SP_FP): Accept H8/300H varaints.
+ (IS_SUB4_SP, IS_SUBL_SP): New macros.
+ (h8300_skip_prologue): Handle H8/300H prologue code sequences.
+ (examine_prologue): Handle addresses from 0x010000 to 0xffffff
+ when in H8/300H mode. Get the return pointer's address correctly
+ for the H8/300H. Handle H8/300H prolouge code sequences.
+
+ * symfile.c (generic_load): Print the starting address
+ of the file just loaded.
+
+Thu May 23 12:09:52 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Edit @THREAD_DB_OBS@ out of makefile.
+
+Tue May 21 11:53:56 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * breakpoint.c (bpstat_do_actions): Avoid endless recursion
+ if a `source' command is contained in bs->commands.
+
+ * infrun.c (wait_for_inferior): Update step_frame_address when
+ stepping into a new line.
+
+ From schwab@issan.informatik.uni-dortmund.de (Andreas Schwab):
+ * breakpoint.c (breakpoint_1): Add shlib_disabled case to
+ bpenables array.
+
+Mon May 20 22:52:00 1996 Mark Alexander <marka@cygnus.com>
+
+ * dsrec.c (load_srec): Add WAITACK parameter, for machines
+ like EST visionICE that send back an ACK after each S-record.
+ * monitor.c (monitor_wait_srec_ack): New function.
+ (monitor_load): Pass monitor_wait_srec_ack to load_srec
+ if the monitor's MO_SREC_ACK flag is set.
+ * monitor.h: Define MO_SREC_ACK flag.
+ * remote-est.c (est_cmds): Add MO_SREC_ACK flag.
+ * sh3-rom.c (sh3_load): Accomodate change in load_srec prototype.
+ * srec.h: Add WAITACK parameter to load_srec prototype.
+
+Sun May 19 21:22:00 1996 Rob Savoye <rob@chinadoll>
+
+ * config/sparc/sparclite.mt: Add the sparc simulator.
+
+Sun May 19 16:49:37 1996 Fred Fish <fnf@cygnus.com>
+
+ * defs.h (read_command_lines, query_hook): Update prototypes.
+ (readline_begin_hook, readline_hook, readline_end_hook): Declare.
+ * breakpoint.c (commands_command): Build message in temporary buffer
+ and pass that, as well as tty control flag, to read_command_lines.
+ * top.c (readline_begin_hook, readline_hook, readline_end_hook):
+ Define here.
+ (command_loop): Check for non-NULL instream before looping.
+ (command_line_input): Use readline_hook when appropriate, to get
+ user input from a GUI window.
+ (read_next_line): Also build prompt if getting user input from a GUI.
+ (recurse_read_control_structure): Fix typo in comment.
+ (read_command_lines): Use passed in prompt and tty flag to decide how
+ to build message. Use readline_begin_hook when appropriate, to set
+ up a GUI interaction window. Just return head, whether NULL or not,
+ after using readline_end_hook to complete GUI interaction.
+ (define_command, document_command): Build message in a temporary
+ buffer and pass it to read_command_lines, along with tty flag.
+
+
+Sat May 18 02:43:58 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * blockframe.c (frameless_look_for_prologue):
+ Add FUNCTION_START_OFFSET only if func_start is non-zero.
+ * minsyms.c (lookup_minimal_symbol_by_pc): Return NULL if
+ pc is not in a known section.
+ * stack.c (print_frame_info): Remove check for fi->pc in known
+ section, now handled by lookup_minimal_symbol_by_pc.
+
+
+Fri May 17 13:31:04 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * sh-stub.c: New file, was config/sh/stub.c.
+
+
+Wed May 15 08:25:12 1996 Jeffrey A Law (law@cygnus.com)
+
+ * top.c (read_next_line): Fix thinkos. From Donn Seeley.
+
+ * coffread.c (coff_symtab_read): Handle C_LABEL symbols like
+ C_STAT symbols.
+ * h8300-tdep.c (h8300_pop_frame): Reset $sp and $pc correctly.
+ Flush cached frames just before exiting.
+ * remote-sim.c (gdbsim_resume): Complain if the program isn't
+ being run.
+ * config/h8300/tm-h8300.h (BELIEVE_PCC_PROMOTION): Define.
+
+Tue May 14 18:05:16 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * procfs.c (procfs_thread_alive procfs_stop): Make static.
+ (procfs_pid_to_str): New routine to print out thread id's in an
+ intelligible manner.
+ * sol-thread.c (sol_thread_fetch_registers): Re-order manner in
+ which supply_register is called to fix bug with writing
+ individual regs.
+ * config/sparc/tm-sun4sol2.h: Define default for
+ target_pid_to_str in case host lacks libthread_db.
+
+Mon May 13 23:53:30 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in config.in configure configure.in
+ config/sparc/nm-sun4sol2.h config/sparc/sun4sol2.mh
+ config/sparc/tm-sun4sol2.h: Use autoconf to config Solaris thread
+ and pthread support, since pre-2.5 systems don't come with
+ libthread_db.so.1.
+
+ * procfs.c (info_proc): Use int instead of id_t. Old versions of
+ Irix don't seem to define this.
+
+Mon May 13 17:40:58 1996 Jeffrey A Law (law@cygnus.com)
+
+ * top.c (execute_control_command, case while_control): Allow
+ a while command to be interrupted.
+
+Mon May 13 16:17:36 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * sol-thread.c: More cleanup, add comments.
+ (sol_thread_resume): Prevent people from trying to step
+ inactive threads.
+ (sol_thread_wait sol_thread_fetch_registers
+ sol_thread_store_registers): Remove unnecessary check for
+ sol_thread_active. These routines won't get called unless threads
+ are active.
+
+Mon May 13 11:29:37 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ SH3-E support from Allan Tajii <atajii@hmsi.com>:
+ * sh-tdep.c (sh_reg_names, sh3_reg_names): Add empty names for
+ float registers.
+ (sh3e_reg_names): New register name array.
+ (sh_processor_type_table): Add sh3e processor type.
+ * config/sh/tm-sh.h (REGISTER_VIRTUAL_TYPE): Fix test.
+ (REGISTER_NAMES, NUM_REGS, NUM_REALREGS, etc): Adjust for
+ full set of registers.
+ * remote-e7000.c (want_sh3, want_sh3_nopc): New globals.
+ (e7000_fetch_registers, e7000_wait): Use them.
+ * sh3-rom.c (sh3_regnames): Add float registers.
+ (sh3e_cmds, sh3e_ops): New globals.
+ (sh3e_open): New function.
+ (_initialize_sh3_rom): Rename from _initialize_sh3, set up
+ sh3e target vector.
+
+Fri May 10 15:53:38 1996 Stu Grossman (grossman@lisa.cygnus.com)
+
+ * sol-thread.c: Cleanup. gcc -Wall fixes. Add prototypes.
+ Print out messages instead of codes for thread_db errors. Make
+ access macros for thread and lwp manipulation. Make cleanups to
+ fixup inferior_pid in case of errors.
+
+Thu May 9 19:06:02 1996 Fred Fish <fnf@cygnus.com>
+
+ * aclocal.m4: Remove unused definition of AC_C_CROSS.
+ * configure.in: Add powerpcle-*-solaris* host and target config
+ so April 30th change does not get lost next time configure is
+ rebuilt.
+
+Thu May 9 14:13:08 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in, breakpoint.c, corelow.c, fork-child.c, inflow.c,
+ infrun.c, mac-nat.c, procfs.c, remote.c, sol-thread.c, thread.c,
+ win32-nat.c, config/nm-lynx.h: Rename thread.h to gdbthread.h to
+ avoid conflict with Solaris /usr/include/thread.h.
+
+Thu May 9 12:33:32 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * abug-rom.c: Config file for the older style ABug monitor that
+ runs on the mvme13x boards.
+ * config/m68k/monitor.mt: Add abug support for m68k cross
+ debugging.
+
+Wed May 8 20:33:24 1996 Fred Fish <fnf@cygnus.com>
+
+ * infcmd.c (do_registers_info): Always print the raw floating
+ point value's bytes in big endian order, so the the leftmost bit
+ is the most significant.
+ * breakpoint.c (clear_momentary_breakpoints): Remove dead code
+ that is referenced nowhere else.
+ (set_breakpoint): Ditto.
+ (do_enable_breakpoint): Created from enable_once_breakpoint
+ with a couple of changes.
+ (enable_breakpoint): Call do_enable_breakpoint with an appropriate
+ bpdisp enum value to set disposition of breakpoint.
+ (enable_once_breakpoint): Ditto.
+ (enable_delete_breakpoint): Ditto.
+ * breakpoint.h (clear_momentary_breakpoints): Remove prototype.
+ * symtab.c (find_pc_line): Improve comments.
+ * xcoffread.c: Ditto.
+
+Tue May 7 18:37:06 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * target.c (debug_to_xfer_memory): Insert line breaks when
+ dumping the memory block.
+
+Mon May 6 13:52:52 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * fork-child.c (fork_inferior), inferior.h: init_trace_fun now
+ returns a possibly modified pid.
+ * inftarg.c (ptrace_him): Now returns pid;
+ * m3-nat.c (m3_trace_him): Now returns pid;
+ * infcmd.c (run_command): Minor cleanup.
+ * infrun.c (wait_for_inferior): Add another check for one_stepped
+ near where we read the pc to avoid erroneously setting
+ random_signal for multi-threaded support.
+ * procfs.c: Add support for Solaris LWPs. Remove def of
+ LOSING_POLL. Many cleanups... Several workarounds for Solaris
+ lossage. System call entry and exit are now handled by
+ dynamically registered handlers.
+ * (syscallname): Don't barf when handed an unknown syscall
+ number.
+ * (info_proc_syscalls): Ditto.
+ * sol-thread.c: New file. Implements Solaris thread support.
+ * symfile.c (symbol_file_add): Add call to target_new_objfile to
+ notify target-dependent code about new symbol tables.
+ * (clear_symtab_users): Call target_new_objfile to notify it of
+ the removal of all symbol tables.
+ * target.c (push_target): Make sure that to_close is non-zero
+ before calling it.
+ * target.h (target_new_objfile): Provide default.
+ * config/alpha/nm-osf2.h: Define LOSING_POLL because this version
+ of OSF can't hack using poll with /proc.
+ * config/sparc/nm-sun4sol2.h (target_new_objfile): Define to be
+ sol-thread-new-objfile.
+ * config/sparc/sun4sol2.mh: Add sol-thread.o to NATDEFFILES, and
+ add libthread_db.so.1 to NAT_CLIBS.
+ * config/sparc/tm-sun4sol2.h: Define PIDGET, TIDGET, and
+ target_pid_to_str.
+
+Sat May 4 02:13:34 1996 N Srin Kumar <nsrin@wipinfo.soft.net>
+
+ * procfs.c (remove_fd): Fix copy of fds to fill hole left after
+ removal of the requested fd.
+
+Mon May 6 07:52:48 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * rs6000-tdep.c (_initialize_rs6000_tdep): Don't do XCOFF specific
+ hooks under ELF.
+
+ * config/powerpc/tm-ppc-eabi.h: Define ELF_OBJECT_FORMAT.
+
+Thu May 2 12:46:14 1996 Jeffrey A Law (law@cygnus.com)
+
+ From Peter Schauer:
+ * breakpoint.h (enum bpdisp): Add del_at_next_stop.
+ * breakpoint.c (insert_breakpoints, watchpoint_check,
+ bpstat_stop_status): Avoid bad references to memory freed via
+ delete_breakpoint on watchpoints going out of scope.
+ Do not delete these watchpoints, disable them and change their
+ disposition to del_at_next_stop instead.
+ (breakpoint_auto_delete): Delete all breakpoints whose disposition
+ is del_at_next_stop.
+ (breakpoint_init_inferior): Use switch to avoid reference to
+ already deleted breakpoint.
+
+Wed May 1 17:29:18 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (rs6000-nat.o): Depend on xcoffsolib.h.
+ * config/rs6000/rs6000.mh (NATDEPFILES): Move xcoffread.o ...
+ * config/rs6000/rs6000.mt (TDEPFILES): ... to here.
+ * xcoffsolib.c (xcoff_relocate_symtab_hook): Define and initialize.
+ (solib_info): Call xcoff_relocate_symtab via the hook.
+ (sharedlibrary_command): Ditto.
+ * xcoffread.c: Remove all FAKING_RS6000 comments and defines.
+ (xcoff_add_toc_to_loadinfo_hook): Define and initialize here.
+ (xcoff_init_loadinfo_hook): Define and initialize here.
+ (scan_xcoff_symtab): Call xcoff_add_toc_to_loadinfo via the hook.
+ (xcoff_initial_scan): Call xcoff_init_loadinfo via the hook.
+ * xcoffsolib.h (xcoff_relocate_symtab_hook): Declare extern func.
+ * rs6000-tdep.c (_initialize_rs6000_tdep): Add initializations
+ of xcoff_add_toc_to_loadinfo_hook and xcoff_init_loadinfo_hook.
+ * rs6000-nat.c (_initialize_core_rs6000): Add initialization
+ of xcoff_relocate_symtab_hook.
+
+Tue Apr 30 13:22:02 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure (powerpcle-*-solaris*): Add Solaris support.
+
+ * config/powerpc/{solaris.m[ht],tm-solaris.h}: New files for
+ Solaris support.
+
+Mon Apr 29 16:17:31 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * c-valprint.c (c_val_print): Fix printing for arrays defined
+ with 0 length.
+
+Sun Apr 28 15:08:05 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ Support for bi-endian remote breakpoints.
+ * remote.c (big_break_insn, little_break_insn): New globals.
+ (break_insn): Remove.
+ (remote_insert_breakpoint, remote_remove_breakpoint): Use own
+ code if REMOTE_BREAKPOINT defined, otherwise call memory
+ breakpoint functions.
+ * config/sh/tm-sh.h (REMOTE_BREAKPOINT): Remove.
+ (BIG_REMOTE_BREAKPOINT, LITTLE_REMOTE_BREAKPOINT): Define.
+
+ * mon960-rom.c (mon960_cmds): Remove forward decl.
+ (mon960_load): Use current_monitor instead of mon960_cmds.
+ (mon960_regnames): Remove backslashes from line ends.
+ (_initialize_mon960): Fix documentation string.
+
+Sun Apr 28 12:10:35 1996 Fred Fish <fnf@cygnus.com>
+
+ * symfile.h (psymbol_allocation_list): Expand comments which
+ describe the psymbol allocation list and how each field is
+ used.
+
+Sun Apr 28 03:44:30 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * breakpoint.c (delete_breakpoint): Fix bpt->val, bpt->exp
+ storage leaks.
+ (breakpoint_re_set_one): Fix b->exp, b->val, b->cond storage leaks.
+
+ * infcmd.c (run_command), solib.c (locate_base): Check for
+ target_has_execution in addition to inferior_pid, a core file
+ from a threaded program is yielding a non-zero inferior_pid.
+
+ * sparc-tdep.c (get_saved_register): Handle window registers
+ in a dummy frame correctly.
+
+Sat Apr 27 20:38:32 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (CLIBS): Move $(MMALLOC) past all other libs,
+ so that anything that wants an allocation function not yet pulled
+ in, will get it from mmalloc rather than a system library.
+ * Makefile.in (INSTALLED_LIBS): Reorder to match order of CLIBS,
+ to avoid surprising results when used.
+
+Sat Apr 27 00:12:05 1996 Dawn Perchik (dawn@cygnus.com)
+
+ * stabsread.c: Changes and bug fixes for cfront support.
+ Fix bug for class data members.
+ Fix parsing bug when no base classes exist.
+ Fix memory bug - allocate space for cplusplus specific info.
+ Add support for static data.
+ Add prototypes for static functions.
+ Enhance comments to show what each function expects to parse.
+ Cleanup code.
+ * stabsread.c(resolve_cont),dbxread.c(resolve_cont): Rename
+ function to resolve_cfront_continuation.
+
+Fri Apr 26 23:58:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * infrun.c (wait_for_inferior): Call registers_changed when
+ restarting the inferior to get over a nullified instruction.
+
+Tue Apr 24 12:12:55 1996 Dawn Perchik (dawn@cygnus.com)
+
+ * dbxread.c,stabsread.c,gdbtypes.c,partial-stab.h,valops.c:
+ Add new support for parsing cfront stabs.
+
+Wed Apr 24 00:32:55 1996 Jeffrey A Law (law@cygnus.com)
+
+ * infrun.c (wait_for_inferior): Move "have_waited" label
+ outside of #ifdef conditionals. Don't trash the wait status
+ if we get a signal and the current instruction is nullified.
+
+Mon Apr 22 20:17:01 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (VERSION): Bump version number to 4.16.1.
+ * NEWS: Update for 4.16 release.
+
+Mon Apr 22 16:32:29 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * monitor.h: Clean up comment formatting.
+ (current_monitor): Remove decl.
+ (LOADTYPES, LOADPROTOS, INIT_CMD, etc): Remove definitions.
+ (push_monitor, SREC_SIZE): Remove.
+ * monitor.c: Expand old macro into current_monitor derefs
+ everywhere.
+ * remote-os9k.c (current_monitor): Remove definition.
+
+Mon Apr 22 14:54:45 1996 Mark Alexander <marka@superball.cygnus.com>
+
+ * corefile.c (specify_exec_file_hook): Allow arbitrary number of
+ hooks.
+ (call_extra_exec_file_hooks): New function.
+ * h8300-tdep.c: Lint; add .h files to provide missing declarations,
+ remove unused variables.
+ (set_machine_hook): New function.
+ (_initialize_h8300m): Initialize it.
+
+Fri Apr 19 15:03:49 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * remote-mips.c (encoding): Don't specify size, to avoid bug in
+ SunOS native compiler.
+
+Thu Apr 18 18:46:57 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * monitor.c: Use int rather than LONGEST for values, since
+ the formatting strings are not prepared to accept long longs.
+
+Wed Apr 17 20:17:27 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * arm-tdep.c (initialize_arm_tdep): Make apcs32 a `zinteger'.
+
+Tue Apr 16 17:38:23 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * corelow.c (add_to_thread_list): Make sure reg_sect is non-null
+ before de-referencing it. Prevents deref of NULL pointer if core
+ file lacks .reg section.
+ * defs.h: Rename floatformat_{to from}_long_double to
+ floatformat_{to from}_doublest. Get rid of FLOATFORMAT_{TO
+ FROM}... macros.
+ * findvar.c (extract_floating store_floating): Change all refs to
+ FLOATFORMAT_{FROM TO}... to floatformat_{from to}_doublest.
+ * utils.c: Change floatformat_{to from}_long_double to
+ floatformat_{to from}_doublest cuz the new routines will use
+ whatever size (double or long double) is appropriate.
+ * config/i960/tm-i960.h (REGISTER_CONVERT_TO_VIRTUAL
+ REGISTER_CONVERT_TO_RAW): Change FLOATFORMAT... macros to
+ floatformat... routine calls.
+
+Mon Apr 15 16:34:11 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * stabsread.c (read_type): Move handling of '@' from type
+ number handling to handling of types proper (as emitted by gcc!).
+ For typedefs, allocate the typedef type before reading its
+ definition, to properly handling recursive types.
+
+Mon Apr 15 11:19:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * ch-exp.c (calculate_array_length): Fix prototype.
+
+Sat Apr 13 14:21:16 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * remote-nindy.c (nindy_open): Acquire more target state so that
+ user can attach to a previously running program.
+ * (nindy_fetch_registers nindy_store_registers): Get rid of fp
+ conversion code. That's all handled in {extract store}_floating
+ now.
+ * utils.c (floatformat_to_double): Don't bias exponent when
+ handling zero's, denorms or NaNs.
+ * config/i960/tm-i960.h (REGISTER_CONVERT_TO_VIRTUAL
+ REGISTER_CONVERT_TO_RAW): Change to using DOUBLST and
+ FLOATFORMAT_TO/FROM_DOUBLEST macros.
+ * config/i960/tm-nindy960.h: Undefine
+ REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW, and
+ REGISTER_CONVERTIBLE. These are no longer necessary now that all
+ the magic happens in extract/store_floating.
+
+Sat Apr 13 02:58:02 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * eval.c (evaluate_subexp_standard): Report error when attempting to
+ evaluate subscripts for types which cannot be subscripted.
+
+ * valarith.c (value_x_binop, value_x_unop): Add noside parameter.
+ Return a zero value with the return type of the member function
+ if noside is EVAL_AVOID_SIDE_EFFECTS instead of calling the member
+ function.
+ * values.h (value_x_binop, value_x_unop): Update prototypes
+ accordingly.
+ * eval.c (evaluate_subexp_standard): Update all callers of
+ value_x_binop, value_x_unop accordingly.
+
+ * valarith.c (value_neg, value_complement): Perform ANSI C/C++
+ integral promotion on operands.
+
+Fri Apr 12 13:19:27 1996 Fred Fish <fnf@cygnus.com>
+
+ * README: Update for 4.16 release.
+ * configure.in (AC_CHECK_FUNCS): Also check for sbrk.
+ * configure: Regenerate with autoconf.
+ * config.in: Regenerate with autoheader.
+ * main.c (main): Only use sbrk() when HAVE_SBRK is defined.
+ * top.c (command_loop): Ditto.
+
+Fri Apr 12 09:45:29 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * defs.h: Define TARGET_{FLOAT DOUBLE LONG_DOUBLE}_FORMAT
+ defaults for bi-endian targets. Replace function pointers for
+ floatformat routines with macros. No need for these to be runtime
+ selectable.
+ * findvar.c: Get rid of floatformat function pointers. Use
+ macros in extract_floating and store_floating.
+ * remote-nindy.c (nindy_fetch_registers nindy_store_registers):
+ Use floatformat macros.
+
+Thu Apr 11 21:28:02 1996 Fred Fish <fnf@cygnus.com>
+
+ From: Miles Bader <miles@gnu.ai.mit.edu>
+ * configure.in (AC_CHECK_HEADERS): check for endian.h.
+ Use AC_CHECK_TOOL to find AR & RANLIB. Add AC_PROG_AWK.
+ Add host & target cases for i[345]86-*-gnu*.
+ * config.in: Regenerate with autoheader.
+ * configure: Regenerate with autoconf.
+ * Makefile.in (AR, AWK): Set from corresponding autoconf substs.
+ (init.c): Don't scan mig-generated files.
+ * defs.h (endian.h): Include if HAVE_ENDIAN_H defined.
+ * config/nm-m3.h (ATTACH_NO_WAIT): Define.
+ * infcmd.c (attach_command): Use "#ifndef ATTACH_NO_WAIT"
+ rather than "#ifndef MACH".
+
+Thu Apr 11 18:49:42 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.c (remotewritesize): New GDB variable, controls size
+ of memory packets sent to the target.
+
+Thu Apr 11 13:47:52 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * dcache.c: Add prototypes. Make many functions static.
+ * (dcache_peek dcache_fetch dcache_poke): Make dcache_fetch and
+ dcache_poke call dcache_xfer_memory directly in order to fix
+ problems with turning off dcache. dcache_peek is now unnecessary,
+ so it goes away.
+
+ * defs.h: Define new macros HOST_{FLOAT DOUBLE LONG_DOUBLE}_FORMAT
+ and TARGET_{FLOAT DOUBLE LONG_DOUBLE}_FORMAT to specify a pointer
+ to a struct floatformat. This allows for better handling of
+ targets whose floating point formats differ from the host by more
+ than just byte order.
+ * (floatformat_to_long_double floatformat_from_long_double):
+ Prototypes for new functions in utils.c.
+ * (floatformat_to_doublest floatformat_from_doublest): Prototypes
+ for pointers to floating point conversion functions. The actual
+ function uses either double or long double if the host supports it.
+ * findvar.c (floatformat_to_doublest floatformat_from_doublest):
+ Initialize to point at correct function depending on HAVE_LONG_DOUBLE.
+ * (extract_floating store_floating): Rewrite. Now, if host fp
+ format is the same as the target, we just do a copy. Otherwise,
+ we call floatformat_{to from}_doublest.
+ * remote-nindy.c (nindy_xfer_inferior_memory): Change param
+ `write' to `should_write'.
+ * utils.c (floatformat_to_long_double
+ floatformat_from_long_double): New routines that implement long
+ double versions of functions in libiberty/floatformat.c.
+ * config/i960/tm-i960.h (TARGET_LONG_DOUBLE_FORMAT): Define this for
+ i960 extended real (80 bit) numbers.
+ * nindy-share/nindy.c (ninMemGet ninMemPut): Return number of bytes
+ actually read or written.
+
+Wed Apr 10 02:56:06 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * ch-valprint.c (chill_val_print): Remove call to calculate_array_length.
+ (calculate_array_length): Move function from here ...
+
+ * ch-exp.c (calculate_array_length): ... to here.
+ (parse_primval): If we have a symbol with an array type
+ and the length is 0, call calculate_array_length.
+
+Tue Apr 9 01:23:05 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * eval.c (evaluate_subexp_standard): In case of TYPE_CODE_SET:
+ Add some checks for powerset compatibility.
+
+ * valops.c (value_slice): Use lowbound instead of lowerbound for
+ call to slice_range_type to get correct bounds.
+
+Mon Apr 8 12:53:56 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (scm-exp.o, scm-lang.o, scm-valprint.o): Add targets and
+ dependencies.
+ * scm-lang.c (gdb_string.h): Include.
+ * objfiles.c (add_to_objfile_sections): Cast second arg of obstack_grow
+ call to correct type (char *).
+ * cp-valprint.c (cp_print_static_field): Ditto.
+ * somsolib.c (som_solib_create_inferior_hook): Add a declaration
+ for external find_unwind_entry function (from hppa-tdep.c).
+ * remote-pa.c (remote_write_bytes, remote_read_bytes): Change
+ type of second arg to "char *" to be type compatible with
+ dcache.
+ (remote_wait): Cast second arg to strtol to correct type.
+ * hppa-tdep.c (compare_unwind_entries): Change argument types to
+ "const void *" to be type compatible with qsort, and then
+ assign to local args prior to use.
+
+Mon Apr 8 15:35:52 1996 Jeffrey A Law (law@cygnus.com)
+
+ * infptrace.c (kill_inferior): Remove call to "kill"; update
+ comments.
+
+Mon Apr 8 14:05:07 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * remote-e7000.c: don't append :23 to target port if __WIN32__
+ is defined (it's WinGDB).
+
+Sun Apr 7 22:34:29 1996 Fred Fish <fnf@cygnus.com>
+
+ From: Miles Bader <miles@gnu.ai.mit.edu>
+ * gnu-nat.c, gnu-nat.h, msg.defs, exc_request.defs, i386gnu-nat.c,
+ msg_reply.defs, notify.defs, process_reply.defs, reply_mig_hack.awk,
+ config/nm-gnu.h, config/i386/{i386gnu.mh, i386gnu.mt, nm-gnu.h,
+ m-i386gnu.h, xm-i386gnu.h}: New files for GNU hurd.
+
+Sun Apr 7 13:32:41 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in (case host): Add i386sco5 host.
+ * configure: Regenerate.
+
+ From: Robert Lipe <robertl@dgii.com>
+ Add support for SCO OpenServer 5 (a.k.a. 3.2v5*) This
+ target is an SVR3.2 with COFF, ELF, and shared libes, but
+ no /proc.
+ * config/i386/i386sco5.mh: New file.
+ * config/i386/nm-i386sco5.h: New file.
+
+Sat Apr 6 08:55:22 1996 Fred Fish <fnf@cygnus.com>
+
+ * bcache.c (bcache): When size of chunk to cache is exactly equal to
+ BCACHE_MAXLENGTH, stash chunk as unique copy.
+
+Sat Apr 6 00:46:26 1996 Fred Fish <fnf@cygnus.com>
+
+ * symfile.c (INLINE_ADD_PSYMBOL): Remove ifdef.
+ (add_psymbol_to_list): Add an arg for passing CORE_ADDR values and
+ use it, rather than calling add_psymbol_addr_to_list.
+ (add_psymbol_addr_to_list): Delete.
+ (add_psymbol_to_list): Make psymbol static to avoid random data in
+ gaps due to alignment of structure members.
+ * symfile.h (INLINE_ADD_PSYMBOL, ADD_PSYMBOL_TO_LIST,
+ ADD_PSYMBOL_ADDR_TO_LIST): Remove. Real world tests show no
+ performance improvements by inlining via complicated macros and
+ they just make gdb larger and harder to maintain.
+ * dwarfread.c (add_enum_psymbol): Replace ADD_PSYMBOL_TO_LIST
+ and/or ADD_PSYMBOL_ADDR_TO_LIST macro(s) with call to
+ add_psymbol_to_list with appropriate long or CORE_ADDR args.
+ (add_partial_symbol): Ditto.
+ * partial-stab.h: Ditto.
+ * os9kread.c (read_os9k_psymtab): Ditto
+ * mdebugread.c (parse_partial_symbols): Ditto.
+ (handle_psymbol_enumerators): Ditto.
+ (demangle.h): Include.
+ * hpread.c (hpread_build_psymtabs): Ditto.
+ (hpread_build_psymtabs): Ditto.
+ (demangle.h): Include
+
+Thu Apr 4 20:16:55 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in: Check for setpgid function.
+ * config.in: Regenerate with autoheader.
+ * configure: Regenerate with autoconf.
+ * inflow.c (_initialize_inflow): Only try to use _SC_JOB_CONTROL
+ if it is actually defined.
+ (gdb_setpgid): Use HAVE_SETPGID.
+ * ch-exp.c: Change include of <string.h> to "gdb_string.h".
+ * c-exp.y, f-exp.y, m2-exp.y: Ditto.
+ * c-exp.y, serial.c: Include <ctype.h>.
+ * config/m68k/nm-news.h: Add typedef for pid_t which is
+ apparently missing from <sys/types.h>. Enclose entire
+ file in NM_NEWS_H ifndef and define when included.
+ * config/mips/nm-news-mips.h: Ditto.
+ * config/m68k/tm-m68k.h (REGISTER_CONVERT_TO_VIRTUAL,
+ REGISTER_CONVERT_TO_RAW): Change name of temporary variable.
+
+Thu Apr 4 19:04:18 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * arm-xdep.c: Move native-specific code to here from arm-tdep.c.
+ * arm-tdep.c (arm_apcs_32): New global.
+ (arm_addr_bits_remove, arm_saved_pc_after_call,
+ arm_push_dummy_frame, arm_pop_frame): New functions.
+ (arm_skip_prologue): Updated version from Richard Earnshaw.
+ (_initialize_arm_tdep): Add set/show "apcs32".
+ * config/arm/tm-arm.h (ADDR_BITS_REMOVE): Call
+ arm_addr_bits_remove.
+ (SAVED_PC_AFTER_CALL): Call arm_saved_pc_after_call.
+ (frame_find_saved_regs): Declare properly.
+ (PUSH_DUMMY_FRAME): Call arm_push_dummy_frame.
+ (POP_FRAME): Call arm_pop_frame, use ADDR_BITS_REMOVE instead of
+ explicit mask.
+ * config/arm/nm-arm.h: New file.
+ * config/arm/xm-arm.h (KERNEL_U_ADDR, FETCH_INFERIOR_REGISTERS):
+ Move definitions to nm-arm.h.
+ * config/arm/arm.mh (NAT_FILE): Define.
+
+ * symfile.c (generic_load): Initialize data_count properly.
+
+Thu Apr 4 17:17:53 1996 Fred Fish <fnf@cygnus.com>
+
+ * symmisc.c (print_objfile_statistics): Print memory used by
+ psymbol cache obstack.
+
+Thu Apr 4 15:43:07 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * symfile.c (report_transfer_performance): New function.
+ (generic_load): Call it to report transfer rate.
+ * remote-e7000.c (e7000_load): Ditto.
+
+Mon Apr 1 16:31:00 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Change references to config.h to be in objdir,
+ edit out rules to rebuild config.h.
+
+Mon Apr 1 08:32:23 1996 Fred Fish <fnf@cygnus.com>
+
+ * hppa-tdep.c (hppa_pop_frame): Call clear_proceed_status before
+ proceeding.
+
+Sun Mar 31 16:15:43 1996 Fred Fish <fnf@cygnus.com>
+
+ * hppah-nat.c (store_inferior_registers, store_inferior_registers,
+ fetch_register, child_xfer_memory): Use call_ptrace function supplied
+ by infptrace.c rather than calling ptrace directly.
+
+Sun Mar 31 15:39:00 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mon960-rom.c: Cleanups and elimination of unused code,
+ clarify documentation string.
+ (mon960_serial, mon960_ttyname): Remove.
+ * config/i960/tm-mon960.h (ADDITIONAL_OPTIONS,
+ ADDITIONAL_OPTION_CASES, ADDITIONAL_OPTION_HELP): Remove.
+
+Sat Mar 30 11:00:22 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in: Check whether printf family supports printing
+ long doubles or not and define PRINTF_HAS_LONG_DOUBLE if so.
+ * acconfig.h: Provide default undef for PRINTF_HAS_LONG_DOUBLE.
+ * configure: Regenerate.
+ * valprint.c (print_floating): Use PRINTF_HAS_LONG_DOUBLE.
+ * c-exp.y (parse_number): Use PRINTF_HAS_LONG_DOUBLE.
+ * configure.in: Fix have_gregset and have_fpregset autoconf
+ variable names so that they match the pattern required to
+ cache them.
+
+Fri Mar 29 21:39:56 1996 Fred Fish <fnf@cygnus.com>
+
+ * core-aout.c (fetch_core_registers): Cast core_reg_size to int
+ before testing against reg_ptr.
+ * eval.c (evaluate_subexp_standard): Cast type of
+ TYPE_FN_FIELD_VOFFSET to int.
+ * findvar.c (extract_signed_integer, extract_unsigned_integer,
+ extract_long_unsigned_integer): Cast type of sizeof to int.
+ * values.c (unpack_field_as_long, modify_field): Ditto.
+ * valops.c (value_assign, call_function_by_hand): Ditto.
+ * infcmd.c (do_registers_info): Ditto.
+ * ser-tcp.c (tcp_open): Ditto.
+ * remote.c (putpkt): Ditto.
+ * dcache.c (dcache_peek): Ditto.
+ * dcache.c (dcache_poke): Ditto.
+ * m2-exp.y (yylex): Ditto.
+ * gnu-regex.c (re_match_2): Ditto.
+ * f-lang.c (ADD_BF_SYMNUM, saved_bf_list_end, tmp_bf_ptr): Ifdef
+ out unused macro definition and variables.
+ * inftarg.c (proc_wait): Move from main.c to here, and make static.
+ * valprint.c (val_print_string): Change bufsize from int to unsigned.
+ * main.c (wait.h): Include.
+ * top.c (command_line_input): Remove unused variable "c".
+ * f-typeprint.c (f_type_print_varspec_prefix): Add missing enum
+ value TYPE_CODE_TYPEDEF to switch statement.
+ (f_type_print_varspec_suffix): Add missing enum value
+ TYPE_CODE_TYPEDEF to switch statement.
+ * ch-exp.c (parse_primval): Add remaining enumeration values to
+ switch statement, with no specific action.
+ (ch_lex): Add LOC_UNRESOLVED in switch statement.
+ (pushback_token): Ifdef out, since code using it is ifdef'd out.
+ * stabsread.c (cleanup_undefined_types): Remove unused label
+ "badtype".
+ * objfiles.h (print_symbol_bcache_statistics): Add prototype.
+ * maint.c (objfiles.h): Include.
+ (maintenance_print_statistics): Remove unused variable "temp".
+ * minsyms.c (lookup_minimal_symbol_solib_trampoline): Remove
+ unused variable "found_file_symbol".
+ * m2-exp.y (yylex): Add LOC_UNRESOLVED case to switch.
+ * language.c (lang_bool_type): Use existing function local type
+ variable rather than create block local variables.
+ * solib.c (disable_break): Enclose in ifndef SVR4_SHARED_LIBS.
+ * infptrace.c (wait.h, command.h): Include.
+ * ser-tcp.c (gdb_string.h): Include
+ * i386-tdep.c (codestream_seek): Change "place" to CORE_ADDR.
+ (i386_get_frame_setup): Change "pc" from int to CORE_ADDR.
+ * command.c (complete_on_enum): Make assignment used as truth value
+ explictly check against NULL.
+ (wait.h): Include.
+ * infrun.c (wait_for_inferior): Ifdef out prologue_pc since code
+ that uses it is ifdef'd out.
+ * parser-defs.h: Add prototype for write_dollar_variable.
+ * infrun.c: Add prototype for write_pc_pid.
+ * breakpoint.h: Add prototype for re_enable_breakpoints_in_shlibs.
+ * symmisc.c (bcache.h): Include.
+ * bcache.h: Add prototype for print_bcache_statistics.
+ * symfile.c: Include <time.h>.
+ * printcmd.c (print_scalar_formatted): Change len to unsigned int.
+ * valarith.c (value_equal): Cast result of TYPE_LENGTH to int.
+ * valarith.c (value_binop): Change result_len, promoted_len1,
+ and promoted_len2 to unsigned int.
+ * valarith.c (value_subscripted_rvalue): Change elt_offs and
+ elt_size to unsigned int.
+ * valops.c (value_array): Change typelength to unsigned int.
+ (destructor_name_p): Change len to unsigned int.
+ * scm-lang.h (scm_parse): Add prototype for scm_unpack.
+ * symfile.c (decrement_reading_symtab): Change return type to void.
+ * valarith.c (value_subscript): Remove unused variable "word".
+ (value_subscript): Remove unused variable "tint".
+ * valops.c (auto_abandon): Ifdef out, since code using it is also
+ ifdef'd out.
+ * eval.c (init_array_element): Remove unused variable "val".
+ * Makefile.in (values.o): Depends on scm-lang.h.
+ (command.o): Depends upon wait_h.
+ (ser-tcp.o): Depends upon gdb_string.h.
+ (infptrace.o): Depends upon wait_h and command_h.
+ (maint.o): Depends on objfiles.h and symfile.h.
+ * values.c (allocate_repeat_value): Remove unused variable
+ "element_type".
+ (scm-lang.h): Include.
+ * breakpoint.c (create_longjmp_breakpoint): Enclose in
+ GET_LONGJMP_TARGET define, unused otherwise.
+ * config/i386/nm-linux.h: Add prototypes for i386_insert_watchpoint,
+ i386_remove_watchpoint and i386_stopped_by_watchpoint.
+
+Thu Mar 28 12:53:19 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in (sparc64-*-solaris2*): Delete.
+ Stick with sparc-*-solaris2*.
+ * configure: Regenerated.
+
+Thu Mar 28 06:51:26 1996 Fred Fish <fnf@cygnus.com>
+
+ * valops.c (value_assign): Make copy of internal variable value
+ before returning it as a new value, since it is owned by the
+ internal variable and will be freed along with it.
+
+Wed Mar 27 08:36:17 1996 Jeffrey A Law (law@cygnus.com)
+
+ * From Peter Schauer.
+ * breakpoint.c (breakpoint_re_set_one): Keep temporary
+ breakpoints bp_until, bp_finish, bp_watchpoint_cope, bp_call_dummy
+ and bp_step_resume in case breakpoint_re_set_one is called due
+ to a step over a dlopen call.
+ * infrun.c (wait_for_inferior): Always remove breakpoints from
+ inferior in BPSTAT_WHAT_CHECK_SHLIBS case.
+
+Tue Mar 26 13:15:32 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/mips/tm-mips.h (COERCE_FLOAT_TO_DOUBLE): Only prefer
+ non-prototyped case over prototyped case for C.
+ * config/pa/tm-hppa.h (COERCE_FLOAT_TO_DOUBLE): Ditto.
+
+Sat Mar 23 17:24:28 1996 Fred Fish <fnf@cygnus.com>
+
+ * os9kread.c (os9k_process_one_symbol): Note nonportable
+ assumption that an int can hold a char *.
+
+ * bcache.h (struct hashlink): Wrap data[] inside union with
+ double to force longest alignment.
+ (BCACHE_DATA): New macro to access data[].
+ (BCACHE_ALIGNMENT): New macro to get offset to data[].
+ * bcache.c (lookup_cache, bcache): Use BCACHE_DATA to get
+ address of cached data. Use BCACHE_ALIGNMENT to compute
+ amount of space to allocate for each hashlink struct.
+
+Sat Mar 23 12:14:02 1996 Fred Fish <fnf@cygnus.com>
+
+ * ch-lang.c (evaluate_subexp_chill): Fix typo.
+
+Thu Mar 21 08:27:19 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (VERSION): Bump version to 4.15.3
+
+Thu Mar 21 10:56:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.in: Rename from config.h.in.
+ * configure.in: Call AC_CONFIG_HEADER with config.h:config.in.
+ Change CONFIG_HEADERS test in AC_OUTPUT accordingly.
+ * configure: Rebuild.
+ * Makefile.in (stamp-h): Depend upon config.in, not config.h.in.
+ Set CONFIG_HEADERS to config.h:config.in.
+
+Tue Mar 19 12:47:51 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * partial-stab.h (case N_ENDM): Finish current partial symbol
+ table for Solaris 2 cc.
+
+Tue Mar 19 10:39:15 1996 Jeffrey A Law (law@cygnus.com)
+
+ * rs6000-nat.c (exec_one_dummy_insn): Don't clobber the
+ PC in the registers array. From Peter Schauer.
+
+Mon Mar 18 13:47:09 1996 Fred Fish <fnf@cygnus.com>
+
+ * symfile.c (reread_symbols): Reinitialize bcache struct
+ members to zero using memset. Also use memset to reinit
+ global_psymbols and static_psymbols, rather than explicitly
+ resetting each structure member.
+
+Sat Mar 16 19:47:36 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in: Add fragment to create stamp-h.
+
+ From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
+ * configure.in (AC_CHECK_HEADERS): Check for link.h.
+ * configure: Regenerate with autoconf.
+ * config.h.in: Regenerate with autoheader.
+ * config/i386/nm-linux.h: Include solib.h only if HAVE_LINK_H
+ is defined.
+ * solib.c: Exclude most of the code if HAVE_LINK_H is not defined.
+ * config/i386/linux.mh: Reinstate XM_CLIBS, it is needed for
+ older a.out based systems.
+
+Sat Mar 16 16:45:43 1996 Fred Fish <fnf@cygnus.com>
+
+ * config.h.in: New file.
+ * acconfig.h: New file, for autoheader.
+ * configure.in (AC_CONFIG_HEADER): Add, generate config.h.
+ * configure: Regenerate.
+ * Makefile.in (defs_h): Add config.h
+ (distclean): Remove config.h and stamp-h during distclean.
+ (config.h, stamp-h): New targets to remake config.h when necessary.
+ * defs.h (config.h): Include before any other includes or defines.
+ * i386-tdep.c (gdb_string.h): Move include after include of defs.h.
+ * i386v4-nat.c (defs.h): Include before testing HAVE_SYS_PROCFS_H.
+
+Sat Mar 16 14:55:27 1996 Fred Fish <fnf@cygnus.com>
+
+ From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
+ * Makefile.in (INSTALLED_LIBS): Make sure that @LIBS@ will not
+ result in an empty line, to work around a bug in native Ultrix 4.4
+ and OSF/1-3.2C make.
+
+Sat Mar 16 13:33:17 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in: Add gdbserver to configdirs under linux.
+ * configure: Regenerate.
+
+Fri Mar 15 12:06:58 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/i386/nm-nbsd.h (FLOAT_INFO): Comment out.
+ * config/i386/tm-nbsd.h (NUM_REGS): Define.
+
+Thu Mar 14 10:31:18 1996 Jeffrey A Law (law@cygnus.com)
+
+ * solib.c (solib_break_names): Add _r_debug_state for
+ vanilla SVR4 implementations. From Peter Schauer.
+
+Mon Mar 11 14:24:57 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * mon960-rom.c: New file; support mon960 rom monitor on i960.
+ * monitor.c (monitor_debug): Change remotedebug to buffer strings.
+ * monitor.c (monitor_open): Add test for flag MO_NO_ECHO_ON_OPEN before
+ epecting prompt and echo during open.
+ * monitor.c (monitor_stop): Add test for flag MO_SEND_BREAK_ON_OPEN to
+ determine if break should be sent as stop command.
+ * monitor.h: Add flags MO_NO_ECHO_ON_OPEN and MO_SEND_BREAK_ON_OPEN.
+ * i960-tdep.c (mon960_frame_chain_valid): New function for getting
+ stack frame on mon960.
+ * Makefile.in: Add mon960 files.
+ * configure.in: Changed i960-*-coff* and i960-*-elf* to target mon960;
+ added i960-nindy-coff* and i960-nindy-elf* for target nindy.
+ * configure: Regenerated.
+ * config/i960/mon960.mt, config/i960/tm-mon960.h: New files;
+ support mon960 rom monitor on i960.
+
+Mon Mar 11 11:02:47 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ With Michael Snyder:
+ * i386-tdep.c (skip_trampoline_code): Fix strncmp length.
+ * win32-nat.c (CHECK, DEBUG*, debug_*): New.
+ (handle_load_dll): Don't reload symbols.
+ (handle_exception): Use the DEBUG_* names.
+ (child_wait): Add DEBUG_* code.
+ (_initialize_inftarg): Add new commands to set debug_ names.
+
+Mon Mar 11 09:19:58 1996 Jeffrey A Law (law@cygnus.com)
+
+ * From Peter Schauer:
+ * breakpoint.c (insert_breakpoints): Use ALL_BREAKPOINTS_SAFE.
+ (bpstat_stop_status): Likewise.
+ (remove_solib_event_breakpoints): Likewise.
+ (clear_momentary_breakpoints): Likewise.
+ (re_enable_breakpoints_in_shlibs): Don't reenable a breakpoint
+ if we still can't read the memory for that breakpoint.
+ (mention): Add bp_shlib_event case to keep gcc quiet.
+
+Fri Mar 8 12:08:12 1996 Jeffrey A Law (law@cygnus.com)
+
+ * breakpoint.h (enum enable): New enum shlib_disabled for
+ shared library breakpoints that have been temporarily disabled.
+ * breakpoint.c: Handle temporarily disabled shared library
+ breakpoints like disabled breakpoints in most places.
+ (insert_breakpoints): Use shlib_disabled to indicate
+ that an unsettable breakpoint is only temporarily disabled.
+ (re_enable_breakpoints_in_shlibs): New function.
+ * corelow.c (solib_add_stub): After adding shared libraries,
+ try to reenable any temporarily disabled breakpoints.
+ * infcmd.c (attach_command): Likewise.
+ * infrun.c (wait_for_inferior): Likewise.
+
+Fri Mar 8 11:41:25 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * defs.h (extract_long_unsigned_integer): Declare.
+ * findvar.c (extract_long_unsigned_integer): New function.
+ * printcmd.c (print_scalar_formatted): Use it.
+ * valprint.c (val_print_type_code_int): Likewise.
+
+Thu Mar 7 17:40:50 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infcmd.c (do_registers_info): Ignore anonymous registers.
+ * sh-tdep.c (set processor): New command to set specific
+ processor type.
+ (sh_reg_names, sh3_reg_names): Arrays of register names for
+ SH and SH3 processors.
+ (sh_set_processor_type): New function.
+ * sh3-rom.c (sh3_open): Call it.
+ (sh3_regname): Add names of all the bank registers.
+ (sh3_supply_register): Clean up formatting.
+ * config/sh/tm-sh.h (NUM_REGS, NUM_REALREGS): Increase to include
+ bank registers.
+ (REGISTER_NAMES): Add names of bank registers.
+ (FP15_REGNUM): Define.
+ (REGISTER_VIRTUAL_TYPE): Use it.
+ * monitor.c: Clean up some comments.
+
+Thu Mar 7 12:09:51 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * i386b-nat.c: Revert part of Mar 5 change. FreeBSD collapsed the
+ s* and t* symbols too.
+
+Thu Mar 7 15:18:51 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * symfile.c (generic_load): Avoid division by zero.
+
+Wed Mar 6 17:57:59 1996 Jeffrey A Law (law@cygnus.com)
+
+ * breakpoint.c (bfd_lookup_symbol): Provide for all SVR4 systems,
+ not just those with HANDLE_SVR4_EXEC_EMULATORS.
+
+ From Peter Schauer:
+ * breakpoint.c (internal_breakpoint_number): Move to file scope.
+ (create_solib_event_breakpoint): Use an internal breakpoint number.
+
+Wed Mar 6 00:32:44 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * valarith.c (value_in): Change builtin_type_chill_bool to
+ LA_BOOL_TYPE.
+
+Tue Mar 5 23:48:36 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * ch-exp.c (parse_primval): Handle CARD, MAX, MIN.
+ (match_string_literal): Handle control sequence.
+ (match_character_literal): Deto.
+
+ * ch-lang.c (chill_printchar): Change formating of nonprintable
+ characters from C'xx' to ^(num).
+ (chill_printstr): Deto.
+ (value_chill_card, value_chill_max_min): New functions to process
+ Chill's CARD, MAX, MIN.
+ (evaluate_subexp_chill): Process UNOP_CARD, UNOP_CHMAX, UNOP_CHMIN.
+
+ * expression.h (exp_opcode): Add UNOP_CARD, UNOP_CHMAX, UNOP_CHMIN
+ for Chill's CARD, MAX, MIN.
+
+ * valarith.c (value_in): Add processing of TYPE_CODE_RANGE
+ and change return type from builtin_type_int to
+ builtin_type_chill_bool.
+
+Tue Mar 5 18:54:04 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/nm-nbsd.h (link_object, lo_name, etc): Move to here
+ from config/nm-nbsd.h.
+ * config/sparc/nm-nbsd.h (regs, fp_status, etc): Move to here
+ from config/sparc/tm-nbsd.h.
+
+ * config/m68k/nm-hp300hpux.h (FIVE_ARG_PTRACE): Define here
+ instead of in config/m68k/xm-hp300hpux.h.
+
+Tue Mar 5 12:05:35 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * i386b-nat.c, m68knbsd-nat.c (fetch_core_registers): Provide
+ implementation for NetBSD systems.
+
+Mon Mar 4 23:44:16 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * valarith.c (binop_user_defined_p): Return 0 for BINOP_CONCAT.
+ (value_concat): Handle varying strings (add COERCE_VARYING_ARRAY).
+
+ * ch-lang.c (evaluate_subexp_chill case MULTI_SUBSCRIPT): Error
+ if "function" is pointer to non-function.
+
+Mon Mar 4 17:47:03 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * top.c (print_gdb_version): Update copyright year.
+
+Mon Mar 4 14:44:54 1996 Jeffrey A Law (law@cygnus.com)
+
+ From Peter Schauer:
+ * infrun.c (wait_for_inferior): Remove breakpoints and
+ switch terminal settings before calling SOLIB_ADD.
+ * solib.c (enable_break, SVR4 variant): Don't map in symbols
+ for the dynamic linker, the namespace pollution causes real
+ problems.
+
+Sun Mar 3 17:18:57 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * remote-mips.c (common_breakpoint): Explicitly terminate the
+ returned buffer.
+
+Wed Feb 28 22:32:18 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Wilfried Moser <wilfried.moser@aut.alcatel.at>:
+ * remote.c (remote_detach): Send a command 'D' to the target
+ when detaching, update the function's comments.
+
+Thu Jun 6 16:11:38 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (thread_cmd_list): New declaration.
+ (parse_int_arg): New function.
+
+Wed Jun 5 17:28:04 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.h (struct proc): Add DETACH_SC field.
+ * gnu-nat.c (make_proc): Set DETACH_SC.
+ (struct inf): Add DETACH_SC & DEFAULT_THREAD_DETACH_SC fields.
+ (make_inf): Set DETACH_SC & DEFAULT_THREAD_DETACH_SC fields.
+ (add_thread_commands): Add set/show for detach-suspend-count.
+ Add takeover-suspend-count cmd.
+ (inf_detach): Set suspend counts to the detach SC, not 0.
+ (set_thread_detach_sc_cmd, show_thread_detach_sc_cmd,
+ set_task_detach_sc_cmd, show_task_detach_sc_cmd,
+ set_thread_default_thread_detach_sc_cmd,
+ show_thread_default_thread_detach_sc_cmd): New functions.
+ (show_task_cmd): Also show detach-suspend-count values.
+ (thread_takeover_sc_cmd): New function.
+
+Fri May 31 16:49:24 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (show_thread_run_cmd): Actually print state.
+
+Thu May 30 10:47:56 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_signal): Make unforwardable exceptions an error.
+
+Tue May 28 17:06:36 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_validate_stopped): proc_getprocinfo takes a
+ pointer to the flags now, not the flags themselves.
+
+Mon May 27 13:31:17 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (gnu_wait): Print debugging msgs for pending execs.
+ (gnu_create_inferior): Check return from ptrace.
+
+Sun May 26 16:56:35 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.h (struct proc): Add DEAD field.
+ * gnu-nat.c (make_proc): Initialize DEAD.
+ (inf_set_traced, inf_validate_task_sc, inf_validate_procs: Frob it.
+ (gnu_wait): Only abort for 0 threads if the task isn't dead.
+
+Sat May 25 17:06:05 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_signal): Pass SIGCODE when posting a signal.
+
+Wed May 22 18:44:28 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (S_proc_wait_reply): Add SIGCODE argument.
+ (inf_set_traced): Only give no-signal-thread error message if
+ turning *on* tracing.
+
+Wed May 15 13:03:16 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_validate_procs): If INF has no threads, always
+ set inf->threads_up_to_date to 0.
+ (inf_signal): Pass in new SIGCODE argument to msg_sig_post_untraced.
+ (gnu_wait): Pass in new TIMEOUT arg to interrupt_operation.
+ (proc_update_sc): Cast thread state arg to thread_set_state.
+ (proc_get_state): Cast thread state arg to thread_get_state.
+ (inf_validate_task_sc): Cast task_basic_info arg to task_info.
+ * i386gnu-nat.c (gnu_fetch_registers, gnu_store_registers): Call
+ inf_update_procs before we lookup the thread.
+ * config/i386/i386gnu.mh (MH_CFLAGS): New variable.
+
+Tue May 7 17:52:33 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (gnu_kill_inferior): Use inf_set_task to clear the task.
+
+Mon May 6 19:06:49 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_set_traced): Use msg_set_init_int with
+ INIT_TRACEMASK instead of setting the exec flags.
+
+Fri May 3 19:10:57 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (inf_validate_procs): Don't clear INF->task if we find
+ the task's died, so others have a chance at it.
+ (gnu_resume): When single-stepping a single thread, given an error
+ if there is no such thread. When single-stepping one but running
+ the others, just given a warning and still run all the threads.
+ (gnu_wait): If there seem to be no threads, look harder, and
+ signal an error if there really aren't any.
+ (gnu_attach): Reset thread numbering to 0.
+
+ * i386gnu-nat.c (gnu_fetch_registers, gnu_store_registers): Give
+ thread name in warning messages.
+
+ * gnu-nat.c (active_inf): New function.
+ (show_sig_thread_cmd, show_stopped_cmd): Use it.
+ (info_port_rights, info_send_rights_cmd, info_port_sets_cmd,
+ info_recv_rights_cmd, info_port_rights_cmd, info_port_rights_cmd):
+ New functions.
+ (add_task_commands): Add new port-right info commands.
+
+Fri Apr 26 20:42:16 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (gnu_wait): Instead of _hurd_intr_rpc_mach_msg, just
+ use mach_msg with MACH_RCV_INTERRUPT.
+ (set_noninvasive_cmd): New function.
+ (add_task_commands): Add command entry for `set noninvasive'.
+
+Mon Mar 4 14:12:02 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (gnu_read_inferior): Use hurd_safe_memmove, not safe_bcopy.
+ (safe_bcopy): Function removed.
+
+Mon Dec 4 14:18:26 1995 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c (proc_update_sc): Assert only threads can have state.
+ (make_proc): Initialize state_valid & state_changed fields.
+
+Tue Nov 28 17:51:21 1995 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * reply_mig_hack.awk: New file.
+
+Tue Nov 14 14:31:03 1995 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * breakpoint.c (breakpoint_1): Print breakpoint thread field.
+
+ * lynx-nat.c (child_wait): Return TARGET_WAITKIND_SPURIOUS for new
+ threads.
+
+Mon Nov 13 18:30:53 1995 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * target.c (debug_to_check_threads): New function.
+
+ * inflow.c (terminal_init_inferior_with_pgrp): New function.
+ (terminal_init_inferior): Call terminal_init_inferior_with_pgrp.
+ * inferior.h (terminal_init_inferior_with_pgrp): New declaration,
+ but only if PROCESS_GROUP_TYPE is defined.
+
+Mon Nov 6 16:42:09 1995 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * target.c (debug_to_thread_alive): Pass through the return value.
+
+Thu Nov 2 18:05:00 1995 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * target.c (signals, target_signal_from_host, target_signal_to_host):
+ Add mach exceptions.
+ * target.h (enum target_signal): Add mach exceptions.
+
+Mon Oct 30 16:41:04 1995 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * gnu-nat.c: New file: gnu native backend.
+ * i386gnu-nat.c: New file: i386-specific part of gnu native backend.
+ * gnu-nat.h: New file.
+ * config/nm-gnu.h: New file.
+ * config/tm-i386gnu.h: New file.
+ * config/xm-i386gnu.h: New file.
+ * config/i386/i386gnu.mh: New file.
+ * config/i386/i386gnu.mt: New file.
+
+Wed Feb 28 15:50:12 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (VERSION): Bump version to 4.15.2 to establish
+ baseline for gdb 4.16 rerelease testing.
+
+Wed Feb 28 13:32:05 1996 Jeffrey A Law (law@cygnus.com)
+
+ * somsolib.c (som_solib_create_inferior_hook): Before returning
+ call clear_symtab_users.
+
+Tue Feb 27 00:04:46 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * remote-e7000.c (e7000_open): Delete all breakpoints when
+ connecting to e7000. Change connect message to allow use of
+ monitor.exp in test suite.
+ * (e7000_load): Print transfer rate of download.
+ * symfile.c (generic_load): Print transfer rate of download.
+
+Sun Feb 25 13:58:33 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.in (mips*-*-vxworks*): New config.
+ * configure: Regenerated.
+
+ * config/mips/vxmips.mt, config/mips/tm-vxmips.h: New files.
+ * remote-vxmips.c (vx_convert_to_virtual, vx_convert_from_virtual):
+ Remove, never used.
+
+Sat Feb 24 12:30:28 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * partial-stab.h (case N_FUN): Function symbols generated
+ by SPARCworks cc have a meaningless zero value, do not update
+ pst->textlow if the function symbol value is zero.
+
+ * stabsread.c (define_symbol): Initialize SYMBOL_TYPE field
+ for function prototype declaration symbols.
+
+Fri Feb 23 22:33:04 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * remote-e7000.c (e7000_load): New routine to download via the
+ network.
+ * (e7000_wait): Don't backup PC when we hit a breakpoint.
+ Apparantly new sh2 pods get this right...
+ * (e7000_ops): Add call to e7000_load.
+
+Thu Feb 22 00:52:42 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/m68k/{nbsd.mh,nbsd.mt,nm-nbsd.h,tm-nbsd.h,xm-nbsd.h},
+ m68knbsd-nat.c: New files, support for NetBSD/m68k.
+
+ * configure.in (m68k-*-netbsd*): New config.
+ * configure: Regenerated.
+
+Wed Feb 21 19:00:21 1996 Fred Fish <fnf@cygnus.com>
+
+ * standalone.c (open, _initialize_standalone): Fix obvious typos
+ reported by Martin Pool <martin@citr.uq.oz.au>.
+
+Wed Feb 21 14:24:04 1996 Jeffrey A Law (law@cygnus.com)
+
+ * solib.c (solib_create_inferior_hook): Fix thinko.
+
+Tue Feb 20 23:59:19 1996 Jeffrey A Law (law@cygnus.com)
+
+ * solib.c (solib_break_names): Define for Solaris and Linux.
+ (enable_break): For SVR4 systems, first try to use the debugger
+ interfaces in the dynamic linker to track shared library events
+ as they happen, then fall back to BKPT_AT_SYMBOL code. Convert
+ BKPT_AT_SYMBOL code to use shared library event breakpoints.
+ (solib_create_inferior_hook): Simplify BKPT_AT_SYMBOL code,
+ it no longer needs to restart/wait on the inferior.
+ * symfile.c (find_lowest_section): No longer static.
+ * symfile.h (find_lowest_section): Corresponding changes.
+
+Tue Feb 20 18:54:08 1996 Fred Fish <fnf@cygnus.com>
+
+ * valops.c (COERCE_FLOAT_TO_DOUBLE): Define default value.
+ (value_arg_coerce): Use COERCE_FLOAT_TO_DOUBLE.
+ * config/alpha/tm-alpha.h (COERCE_FLOAT_TO_DOUBLE): Define to 1.
+ * config/mips/tm-mips.h: Ditto.
+ * config/pa/tm-hppa.h: Ditto.
+ * config/rs6000/tm-rs6000.h: Ditto.
+ * config/sparc/tm-sparc.h: Ditto.
+
+Tue Feb 20 17:32:05 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/{i386,ns32k}/nbsd.mh (NATDEPFILES): Remove core-aout.o.
+
+ * config/nm-nbsd.h (FETCH_INFERIOR_REGISTERS): Defined.
+ * config/xm-nbsd.h (CC_HAS_LONG_LONG, PRINTF_HAS_LONG_LONG):
+ #ifdef'd out definitions --- Causes serious gdb failures on
+ the i386. Need to investigate further before enabling.
+
+ * i386b-nat.c (fetch_inferior_registers, store_inferior_registers,
+ fetch_core_registers): New functions. These functions are defined
+ if FETCH_INFERIOR_REGISTERS is set. Registers are fetched/stored
+ with ptrace PT_GETREGS/PT_SETREGS.
+
+Tue Feb 20 16:55:06 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * findvar.c (extract_floating store_floating): Replace `long
+ double' with `DOUBLEST'.
+
+Mon Feb 19 15:25:51 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/xm-nbsd.h (CC_HAS_LONG_LONG, PRINTF_HAS_LONG_LONG):
+ Define.
+
+Mon Feb 19 10:32:05 1996 Jeffrey A Law (law@cygnus.com)
+
+ * symtab.h (looup_minimal_symbol_solib_trampoline): Declare.
+
+ * breakpoint.h (remove_solib_event_breakpoints): Declare.
+ * breakpoint.c (remove_solib_event_breakpoints): New function.
+ * somsolib.c (solib_create_inferior_hook): Remove all solib event
+ breakpoints before inserting any new ones. Use a solib event
+ breakpoint for the breakpoint at "_start".
+ Remove extraneous "\n" from calls to warning.
+
+ * breakpoint.c (breakpoint_1): Add missing "sigtramp" to bptypes
+ name array.
+
+Mon Feb 19 01:09:32 1996 Doug Evans <dje@cygnus.com>
+
+ * dwarfread.c (add_partial_symbol): Use ADD_PSYMBOL_ADDR_TO_LIST
+ for CORE_ADDR values.
+ (new_symbol): Use SYMBOL_VALUE_ADDRESS for CORE_ADDR values.
+ * symfile.h (add_psymbol_{,addr}to_list): Add prototypes.
+
+Sun Feb 18 14:37:13 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mipsread.c (mipscoff_symfile_read): Unconditionally add
+ alpha coff dynamic symbols for all symbol files. Makes skipping
+ over the trampoline code work when stepping from a function in a
+ shared library into a function in a different shared library.
+
+Sun Feb 18 09:27:10 1996 Stu Grossman (grossman@cygnus.com)
+
+ * config/sparc/tm-sparc.h: Define PS_FLAG_CARRY. Define
+ RETURN_VALUE_ON_STACK to return long doubles on the stack.
+
+Sat Feb 17 16:33:11 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (ch-exp.o): Add dependencies.
+ (various): Add gdb_string.h to dependencies that need it.
+
+Sat Feb 17 08:57:50 1996 Fred Fish <fnf@cygnus.com>
+
+ * symmisc.c (print_symbol_bcache_statistics): Update description for
+ printing byte cache statistics.
+
+Thu Feb 16 16:02:03 1996 Stu Grossman (grossman@cygnus.com)
+
+ * Add native support for long double data type.
+ * c-exp.y (%union): Change dval to typed_val_float. Use DOUBLEST
+ to store actual data. Change types of INT and FLOAT tokens to
+ typed_val_int and typed_val_float respectively. Create new token
+ DOUBLE_KEYWORD to specify the string `double'. Make production
+ for FLOAT use type determined by parse_number. Add production for
+ "long double" data type.
+ * (parse_number): Use sscanf to parse numbers as float, double or
+ long double depending upon the type of typed_val_float.dval. Also
+ allow user to specify `f' or `l' suffix to explicitly specify
+ float or long double constants. Change typed_val to
+ typed_val_int.
+ * (yylex): Change typed_val to typed_val_int. Also, scan for
+ "double" keyword.
+ * coffread.c (decode_base_type): Add support for T_LNGDBL basic
+ type.
+ * configure, configure.in: Add check for long double support in
+ the host compiler.
+ * defs.h: Define DOUBLEST appropriatly depending on whether
+ HAVE_LONG_DOUBLE (from autoconf) is defined. Also, fix prototypes
+ for functions that handle this type.
+ * expression.h (union exp_element): doubleconst is now type
+ DOUBLEST.
+ * m2-exp.y f-exp.y (%union): dval becomes type DOUBLEST.
+ * findvar.c (extract_floating): Make return value be DOUBLEST.
+ Also, add support for numbers with size of long double.
+ * (store_floating): Arg `val' is now type DOUBLEST. Handle all
+ floating types.
+ * parser-defs.h parse.c (write_exp_elt_dblcst): Arg expelt is now
+ DOUBLEST.
+ * valarith.c (value_binop): Change temp variables v1, v2 and v to
+ type DOUBLEST. Coerce type of result to long double if either op
+ was of that type.
+ * valops.c (value_arg_coerce): If argument type is bigger than
+ double, coerce to long double.
+ * (call_function_by_hand): If REG_STRUCT_HAS_ADDR is defined, and
+ arg type is float and > 8 bytes, then use pointer-to-object
+ calling conventions.
+ * valprint.c (print_floating): Arg doub is now type DOUBLEST.
+ Use appropriate format and precision to print out floating point
+ values.
+ * value.h: Fixup prototypes for value_as_double,
+ value_from_double, and unpack_double to use DOUBLEST.
+ * values.c (record_latest_value): Remove check for invalid
+ floats. Allow history to store them so that people may examine
+ them in hex if they want.
+ * (value_as_double unpack_double): Change return value to DOUBLEST.
+ * (value_from_double): Arg `num' is now DOUBLEST.
+ * (using_struct_return): Use RETURN_VALUE_ON_STACK macro (target
+ specific) to expect certain types to always be returned on the stack.
+
+Fri Feb 16 14:00:54 1996 Fred Fish <fnf@cygnus.com>
+
+ * bcache.c, bcache.h: New files to implement a byte cache.
+ * Makefile.in (SFILES): Add bcache.c.
+ (symtab_h): Add bcache.h.
+ (HFILES_NO_SRCDIR): add bcache.h
+ (COMMON_OBJS): Add bcache.o
+ (bcache.o): New target.
+ * dbxread.c (start_psymtab): Make global_syms & static_syms
+ type "partial_symbol **".
+ * hpread.c (hpread_start_symtab): Ditto.
+ * os9kread.c (os9k_start_psymtab): Ditto.
+ * stabsread.h (start_psymtab): Ditto.
+ * {symfile.c, symfile.h} (start_psymtab_common): Ditto.
+ * maint.c (maintenance_print_statistics): Call
+ print_symbol_bcache_statistics.
+ * objfiles.c (allocate_objfile): Initialize psymbol bcache malloc
+ and free pointers.
+ * solib.c (allocate_rt_common_objfile): Ditto.
+ * symfile.c (reread_symbols): Ditto.
+ (free_objfile): Free psymbol bcache when objfile is freed.
+ (objfile_relocate): Use new indirect psymbol pointers.
+ * objfiles.h (struct objfile): Add psymbol cache.
+ * symfile.c (compare_psymbols): Now passed pointers to pointers to
+ psymbols.
+ (reread_symbols): Free psymbol bcache when freeing other objfile
+ resources.
+ (add_psymbol_to_list, add_psymbol_addr_to_list): Initialize new
+ psymbol using the psymbol bcache.
+ (init_psymbol_list): Psymbol lists now contain pointers rather than
+ the actual psymbols.
+ * symfile.h (psymbol_allocation_list): Psymbol lists now dynamically
+ grown arrays of pointers.
+ (ADD_PSYMBOL_VT_TO_LIST): Initialize new symbol using the psymbol
+ bcache.
+ * symmisc.c (print_partial_symbols): Now takes pointer to pointer
+ to partial symbol.
+ (print_symbol_bcache_statistics): New function to print per objfile
+ bcache statistics.
+ (print_partial_symbol, print_partial_symbols,
+ maintenance_check_symtabs, extend_psymbol_list):
+ Account for change to pointer to pointer to partial symbol.
+ * symtab.c (find_pc_psymbol, lookup_partial_symbol, decode_line_2,
+ make_symbol_completion_list):
+ Account for change to pointer to pointer to partial symbol.
+ * symtab.h (bcache.h): Include.
+ * xcoffread.c (xcoff_start_psymtab): Make global_syms & static_syms
+ type "partial_symbol **".
+
+Fri Feb 16 10:02:34 1996 Fred Fish <fnf@cygnus.com>
+
+ * dwarfread.c (free_utypes): New function.
+ (read_file_scope): Call free_utypes as cleanup, rather than just
+ freeing the utypes pointer.
+
+Thu Feb 15 21:40:52 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * demangle.c (is_cplus_marker): New function, checks if a
+ character is one of the commonly used C++ marker characters.
+ * defs.h (is_cplus_marker): Add prototype.
+ * c-typeprint.c (c_type_print_base), ch-lang.c (chill_demangle),
+ cp-valprint.c (cp_print_class_method), mdebugread.c (parse_symbol),
+ stabsread.c (define_symbol, read_member_functions, read_struct_fields),
+ symtab.h (OPNAME_PREFIX_P, VTBL_PREFIX_P, DESTRUCTOR_PREFIX_P),
+ values.c (vb_match): Use is_cplus_marker instead of comparison
+ with CPLUS_MARKER.
+
+Thu Feb 15 18:08:13 1996 Fred Fish <fnf@cygnus.com>
+
+ * symfile.h (INLINE_ADD_PSYMBOL): Default this to 0 and possibly
+ delete entirely someday.
+
+Thu Feb 15 15:25:34 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Edit out makefile rebuild rule.
+ (host_alias, target_alias): Comment out instead of deleting.
+ (@LIBS@): Edit out references.
+
+Tue Feb 13 22:56:46 1996 Fred Fish <fnf@cygnus.com>
+
+ * symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list):
+ Use n_psyms in OBJSTAT, not psyms.
+
+Mon Feb 12 15:59:31 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * configure.in (sparclet-*-aout*): New config.
+ * configure: Regenerated.
+
+Mon Feb 12 14:17:52 1996 Fred Fish <fnf@cygnus.com>
+
+ * somsolib.c (som_solib_add): Use xmalloc rather than bare
+ unchecked call to malloc.
+ * remote-mips.c (pmon_load_fast): ditto.
+ * remote-mm.c (mm_open): ditto.
+ * hpread.c (hpread_lookup_type): ditto.
+ * remote-adapt.c (adapt_open): ditto.
+
+Mon Feb 12 13:11:32 1996 Fred Fish <fnf@cygnus.com>
+
+ * f-lang.c (allocate_saved_bf_node, allocate_saved_function_node,
+ allocate_saved_f77_common_node, allocate_common_entry_node,
+ add_common_block): Use xmalloc rather than malloc, some of which
+ were unchecked.
+ * gnu-regex.c: At same point as other gdb specific changes
+ #undef malloc and then #define it to xmalloc.
+ * ch-exp.c (growbuf_by_size): Use xmalloc/xrealloc rather than
+ bare unchecked calls to malloc/realloc.
+ * stabsread.c (dbx_lookup_type): Use xmalloc rather than bare
+ unchecked call to malloc.
+
+Wed Feb 7 11:31:26 1996 Stu Grossman (grossman@cygnus.com)
+
+ * symtab.c (gdb_mangle_name): Change opname var to be const to
+ match return val of cplus_mangle_name.
+ * i960-tdep.c: Change arg types of next_insn to match callers.
+
+Wed Feb 7 07:34:24 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/i386/linux.mh (XM_CLIBS, GDBSERVER_LIBS): Remove. These
+ apparently aren't needed in any reasonably recent version of
+ linux.
+
+Tue Feb 6 21:37:03 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * stabsread.c (read_range_type): If !self-subrange and language
+ is Chill, assume a true range. If a true_range is a sub_subrange,
+ use builtin_type_int for index_type.
+
+Tue Feb 6 18:38:51 1996 J.T. Conklin <jtc@slave.cygnus.com>
+
+ * nindy-share/nindy.c (say): Use stdarg.h macros when compiling
+ with an ANSI compiler.
+
+Mon Feb 5 18:24:28 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ From Michael_Snyder@NeXT.COM (Michael Snyder):
+ * valops.c (value_arg_coerce): Coerce float to double, unless the
+ function prototype specifies float.
+
+Mon Feb 5 09:51:55 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * language.c (set_language_command): Use languages table when
+ printing available languages.
+
+Sat Feb 3 12:22:05 1996 Fred Fish <fnf@cygnus.com>
+
+ Fix problems reported by Hans Verkuil (hans@wyst.hobby.nl):
+ * command.c (add_cmd): Add missing initialization for enums member.
+ Reorder members to match structure declaration to make it easier to
+ tell when one is missing.
+ * exec.c (exec_file_command): Fix problem where filename in malloc'd
+ memory is referenced after being freed.
+
+Sat Feb 3 03:26:21 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dwarfread.c (read_func_scope): Avoid GDB core dumps if
+ AT_name tag is missing.
+
+ * procfs.c (procfs_stopped_by_watchpoint): Fix logic when
+ FLTWATCH and FLTKWATCH are defined.
+
+ * remote.c (remote_read_bytes): Advance memaddr for transfers,
+ return number of bytes transferred for partial reads.
+
+ * top.c (init_signals): Reset SIGTRAP to SIG_DFL.
+
+Fri Feb 2 13:40:50 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * win32-nat.c (mappings): Add ppc registers.
+ (child_resume): Turn off step for ppc.
+
+Thu Feb 1 10:29:31 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * config/powerpc/(cygwin32.mh, cygwin32.mt, tm-cygwin32.h,
+ xm-cygwin32.h): New.
+ * config/i386/(*win32*): Becomes *cygwin32*.
+ * configure.in (i[3456]86-*-win32*): Becomes i[3456]86-*-cygwin32.
+ (powerpcle-*-cygwin32): New.
+ * configure: Regenerate.
+ * win32-nat.c (child_create_inferior): Call CreateProcess
+ with the right program arg.
+
+Thu Feb 1 11:01:10 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/pa/tm-hppa.h (SOFT_FLOAT): Provide a default definition.
+
+Wed Jan 31 19:01:28 1996 Fred Fish <fnf@cygnus.com>
+
+ * serial.c: Change fputc/fputs/fprintf to _unfiltered forms.
+
+Wed Jan 31 18:36:27 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/sparc/xm-sun4os4.h (HAVE_TERMIOS): Remove.
+
+ * config/sparc/xm-sparc.h (HAVE_WAIT_STRUCT): Remove, never used.
+
+ * config/i386/nm-i386mach.h (CHILD_PREPARE_TO_STORE): Move to
+ here from config/i386/xm-i386mach.h, fix name.
+ * config/i386/nm-sun386.h: Ditto, from config/i386/xm-sun386.h.
+ * config/i386/nm-ptx4.h (CHILD_PREPARE_TO_STORE): Move to
+ here from config/i386/xm-ptx4.h.
+ * config/i386/nm-ptx4.h: Ditto, from config/i386/xm-ptx.h.
+ * config/i386/nm-symmetry.h: Ditto, from config/i386/xm-symmetry.h.
+ * config/m68k/nm-sun3.h: Ditto, from config/m68k/xm-sun3.h.
+ * config/sparc/nm-nbsd.h: Ditto, from config/sparc/xm-nbsd.h.
+ * config/sparc/nm-sun4os4: Ditto, from config/sparc/xm-sparc.h.
+
+ * config/sparc/nm-sun4sol2.h: New file, renamed from nm-sysv4.h.
+ (PRSVADDR_BROKEN): Move here from xm-sun4sol2.h.
+ * config/sparc/sun4sol2.mh (NAT_FILE): Update.
+
+Wed Jan 31 17:20:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/pa/tm-hppa.h (EXTRACT_RETURN_VALUE): Handle software
+ floating point correctly.
+ (STORE_RETURN_VALUE): Likewise.
+ * config/pa/tm-pro.h (SOFT_FLOAT): define.
+
+Wed Jan 31 13:34:52 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/i386/xm-linux.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
+ Define to what should be reasonable values. However, apparently
+ a bug in linux mmap prevents mapped symbol tables from working.
+
+Tue Jan 30 18:26:19 1996 Fred Fish <fnf@cygnus.com>
+
+ * defs.h (errno.h>: Move #include closer to head of file to solve
+ obscure problem with systems that declare perror with const arg, in
+ both errno.h and stdio.h, and const is defined away by intervening
+ local include.
+
+Tue Jan 30 15:41:10 1996 Fred Fish <fnf@cygnus.com>
+
+ From Jon Reeves <reeves@zk3.dec.com>:
+ * i386-stub.c (getpacket): Change fprintf stream from "gdb" to stderr.
+ (mem_fault_routine): Fix misplaced volatile type qualifier in decl.
+
+Mon Jan 29 19:05:58 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (diststuff): Make all-doc; diststuff target does not
+ exist in doc/Makefile.in.
+
+Mon Jan 29 18:44:57 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/m88k/xm-cxux.h (BP_HIT_COUNT): Remove, never used.
+
+Mon Jan 29 00:10:35 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * ch-valprint.c (calculate_array_length): New function to
+ determine the length of an array type.
+ (chill_val_print (case TYPE_CODE_ARRAY)): If the length of an
+ array type is zero, call calculate_array_length.
+
+ * gdbtypes.c (get_discrete_bounds (case TYPE_CODE_ENUM)): The
+ values may not be sorted. Scan all entries and set the real lower
+ and upper bound.
+
+Sun Jan 28 15:50:42 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/xm-linux.h: Move include of solib.h and #define of
+ SVR4_SHARED_LIBS from here ...
+ * config/nm-linux.h: ...to here.
+
+Sat Jan 27 10:34:05 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in (AC_CHECK_HEADERS): Check for sys/procfs.h.
+ Also check for gregset_t and fpregset_t types.
+ * configure: Regenerate.
+ * core-regset.c (sys/procfs.h): Only include if HAVE_SYS_PROCFS_H
+ is defined.
+ (fetch_core_registers): Turn into stub unless both HAVE_GREGSET_T
+ and HAVE_FPREGSET_T are defined. These changes allow systems
+ like linux that are migrating to /proc support to use a single
+ configuration for both new and old versions.
+
+ * config/i386/linux.mt: Note that this is now for both a.out and
+ ELF systems.
+ * config/i386/linux.mh (NATDEPFILES): Add solib.o, core-regset.o,
+ i386v4-nat.o
+ * config/i386/tm-linux.h (tm-sysv4.h): Include.
+ * config/i386/xm-linux.h (solib.h): Include
+ (SVR4_SHARED_LIBS): Define.
+ * i386v4-nat.c: Only compile if HAVE_SYS_PROCFS_H is defined.
+ (supply_gregset, fill_gregset): Compile if HAVE_GREGSET_T defined.
+ (supply_fpregset, fill_fpregset): Compile if HAVE_FPREGSET_T
+ defined.
+
+Fri Jan 26 13:48:14 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/sparc/xm-sparc.h (NEW_SUN_CORE): Remove, never used.
+ * config/i386/xm-sun386.h: Ditto.
+ * config/m68k/xm-sun2.h, config/m68k/xm-sun3.h: Ditto.
+
+Thu Jan 25 16:05:53 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (INSTALLED_LIBS, CLIBS): Include @LIBS@.
+
+Thu Jan 25 09:22:15 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ From Greg McGary <gkm@gnu.ai.mit.edu>:
+ * dcache.c (dcache_peek, dcache_poke): Advance addr for
+ multi-byte I/O.
+
+Thu Jan 25 13:08:51 1996 Doug Evans (dje@cygnus.com)
+
+ * infrun.c (normal_stop): Fix test for shared library event.
+
+Thu Jan 25 03:26:38 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * configure.in (sparc64-*-*): Add default host configuration.
+ (sparc64-*-solaris2*): Add target configuration.
+ (sparc64-*-solaris2* host): Link statically if GCC used.
+ * configure: Regenerated.
+ * sparc/sp64sol2.mt: New file.
+
+Wed Jan 24 22:31:37 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * Makefile.in (RUNTEST): srcdir renamed to rootsrc.
+
+Wed Jan 24 15:42:24 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (lint): Close backquotes.
+
+Wed Jan 24 13:19:10 1996 Fred Fish <fnf@cygnus.com>
+
+ * NEWS: Make note of new record and replay feature for
+ remote debug sessions.
+ * serial.c (gdbcmd.h): Include.
+ (serial_logfile, serial_logfp, serial_reading, serial_writing):
+ Define here, for remote debug session logging.
+ (serial_log_command, serial_logchar, serial_write, serial_readchar):
+ New functions for remote debug session logging.
+ (serial_open): Open remote debug session log file when needed.
+ (serial_close): Close remote debug session log file when needed.
+ (_initialize_serial): Add set/show commands for name of remote
+ debug session log file.
+ * serial.h (serial_readchar): Declare
+ (SERIAL_READCHAR): Call serial_readchar().
+ (SERIAL_WRITE): Call serial_write().
+ (serial_close): Declare as extern.
+ (serial_logfile, serial_logfp): Declare.
+ * top.c (execute_command): Declare serial_logfp. Log user command
+ in remote debug session log if log file is open.
+ * remote-array.c (array_wait): #ifdef out echo to gdb_stdout.
+ (array_read_inferior_memory): Rewrite to fix memory overwrite bug.
+ * remote-array.c (SREC_SIZE): Remove, duplicates define in
+ monitor.h.
+ * remote-array.c (hexchars, hex2mem): Remove, unused.
+ * gdbserver/low-linux.c (store_inferior_registers): Remove
+ unnecessary extern declaration of registers[].
+ * gdbserver/Makefile.in (all): Add gdbreplay.
+ * gdbserver/gdbreplay.c: New file.
+ * gdbserver/README: Give example of recording a remote
+ debug session with gdb and then replaying it with gdbreplay.
+
+Tue Jan 23 18:02:35 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * stabsread.c (rs6000_builtin_type): Make bool type unsigned.
+ (read_one_struct_field): Support boolean bitfields.
+ * c-valprint.c (c_val_print): Print booleans properly.
+
+Tue Jan 23 18:54:09 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-vxsparc.c (vx_convert_to_virtual, vx_convert_from_virtual):
+ Remove, never used.
+ * config/sparc/vxsparc.mt (TDEPFILES): Add remote-vxsparc.o.
+
+Tue Jan 23 14:36:05 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * ch-exp.c (parse_tuple): Error if invalid mode.
+
+ * value.h (COERCE_ARRAY): Don't coerce enums.
+ (COERCE_ENUM): Don't COERCE_REF.
+ (COERCE_NUMBER): New macro (same as COERCE_ARRAY then COERCE_ENUM).
+ * valops.c (value_assign): Only do COERCE_ARRAY if internalvar (let
+ value_cast handle it otherwise); do *not* COERCE_ENUM either way.
+ * valarith.c: Use COERCE_NUMBER instead od COEREC_ARRAY.
+ Add COERCE_REF before COERCE_ENUM.
+ * values.c (value_as_long): Simplify.
+
+ * valops.c (value_array): Create internalvar if !c_style_arrays.
+
+ * language.c (lang_bool_type): Add Fortran support.
+ * eval.c (OP_BOOL): Use LA_BOOL_TYPE.
+
+Tue Jan 23 13:08:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * symfile.c (auto_solib_add): Renamed from auto_solib_add_at_startup.
+ All references changed.
+ * breakpoint.c (bpstat_what): Add shlib_event to the class types.
+ Update state table. Reformat so that it's still readable.
+ When we hit the shlib_event breakpoint, set the calss of shlib_event.
+ (breakpoint_1): Add "shlib events" as a breakpoint type.
+ Print the shlib_event breakpoint like other breakpoints.
+ (create_solib_event_breakpoint): New function.
+ (breakpoint_re_set_one): Handle solib_event breakpoints.
+ * breakpoint.h (enum bytype): Add bp_shlib_event breakpoint type.
+ (enum bpstat_what_main_action): Add BPSTAT_WHAT_CHECK_SHLIBS
+ action.
+ (create_solib_event_breakpoint): Declare.
+ * infrun.c (wait_for_inferior): Handle CHECK_SHLIBS bpstat.
+ (normal_stop): Inform the user when the inferior stoped due
+ to a shared library event.
+ (_initialize_infrun): Add new set/show variable "stop-on-solib-events"
+ to control whether or not gdb continues the inferior or stops it when
+ a shared library event occurs.
+ * minsyms.c (lookup_minimal_symbol_solib_trampoline): New function.
+ * somsolib.c (TODO list): Update.
+ (som_solib_create_inferior_hook): Arrange for gdb to be notified
+ when significant shared library events occur.
+ * hppa-tdep.c (find_unwind_entry): No longer static.
+
+Tue Jan 23 09:00:48 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * printcmd.c (print_insn): Pass fprintf_unfiltered to
+ INIT_DISASSEMBLE_INFO.
+
+Mon Jan 22 16:59:40 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.c (remotebreak): New GDB variable.
+ (remote_break): New global.
+ (remote_interrupt): Send a break instead of ^C if remote_break.
+ * NEWS: Describe the new variable.
+
+Mon Jan 22 16:24:11 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc-tdep.c (_initialize_sparc_tdep): Always use print_insn_sparc.
+
+Fri Jan 19 07:19:38 1996 Fred Fish <fnf@cygnus.com>
+
+ * hp300ux-nat.c (getpagesize): Remove unused function
+ fetch_core_registers.
+ (hp300ux_core_fns): Remove, is unused.
+ (_initialize_core_hp300ux): Remove, is unused.
+ (gdbcore.h): Remove #include, no longer needed.
+
+Fri Jan 19 00:59:53 1996 Jeffrey A Law (law@cygnus.com)
+
+ * rs6000-nat.c (exec_one_dummy_insn): Rework to avoid
+ ptrace bug in aix4.1.3 on the rs6000.
+
+Wed Jan 17 13:22:27 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-hms.c (hms_ops): Add value for to_thread_alive.
+ * remote-nindy.c (nindy_ops): Ditto.
+ * remote-udi.c (udi_ops): Ditto.
+
+Tue Jan 16 18:00:35 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * remote-mips.c (pmon_opn, pmon_wait, pmon_makeb64, pmon_zeroset,
+ pmon_checkset, pmon_make_fastrec, pmon_check_ack,
+ pmon_load_fast): New functions. Support for the PMON monitor world.
+ (common_open): New function to merge support for different monitors.
+ (mips_open): Use common_open().
+ (mips_send_command): New function.
+ (mips_send_packet): Scan out-of-sequence packets.
+ (mips_enter_debug, mips_exit_debug): New functions.
+ (pmon_ops): New target definition structure.
+
+Tue Jan 16 11:22:58 1996 Stu Grossman (grossman@cygnus.com)
+
+ * Makefile.in (CLIBS): Add LIBS to allow libraries to be
+ specified on the make command line (via make LIBS=xxx).
+
+
+Fri Jan 12 21:41:58 1996 Jeffrey A Law (law@cygnus.com)
+
+ * symtab.c (find_pc_symtab): Don't lose if OBJF_REORDERED
+ is set but there are no psymtabs.
+
+Fri Jan 12 15:56:12 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * dsrec.c (load_srec): Remove unused variable.
+ * monitor.c (monitor_expect): Don't expect a ^C to echo.
+ * serial.c (serial_open): Add parallel interface.
+ * sh3-rom.c (parallel, parallel_in_use): New.
+ (sh3_load): If parallel_in_use, download though the
+ parallel port.
+ (sh3_open): Open parallel port if specified.
+ (sh3_close): New function.
+ (_inititalize_sh3): Add sh3_close hook and documentation.
+ * monitor.c (monitor_close): Export.
+ * monitor.h (monitor_close): Add prototype.
+
+Fri Jan 12 13:11:42 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Wilfried Moser <wilfried.moser@aut.alcatel.at>:
+ * remote.c (remotetimeout): New GDB variable, use to set the
+ remote timeout for reading.
+
+Fri Jan 12 07:14:27 1996 Fred Fish <fnf@cygnus.com>
+
+ * lynx-nat.c, irix4-nat.c, sparc-nat.c: Include gdbcore.h
+ to get "struct core_fns" defined.
+ * Makefile.in (lynx-nat.o, irix4-nat.o, sparc-nat.o):
+ Are dependent upon gdbcore_h.
+
+Thu Jan 11 23:13:24 1996 Per Bothner <bothner@cygnus.com>
+
+ * symfile.c (decrement_reading_symtab): New function.
+ * symfile.c, symtab.h (currently_reading_symtab): New variable.
+ * symfile.c (psymtab_to_symtab): Adjust currently_reading_symtab.
+ * gdbtypes.c (check_typedef): Don't call lookup_symbol if
+ currently_reading_symtab (since that could infinitely recurse).
+
+Thu Jan 11 17:21:25 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * stabsread.c (read_struct_type): Trivial simplification.
+
+ * stabsread.c (define-symbol): Use invisible references
+ for TYPE_CODE_SET and TYPE_CODE_BITSTRING too.
+ * valops.c (call_function_by_hand): Likewise.
+ * eval.c (evaluate_subexp_standard): When known, use the formal
+ parameter type as the expected type when evaluating arg expressions.
+ * ch-lang.c (evaluate_subexp_chill): Likewise (for MULTI_SUBSCRIPT).
+
+Thu Jan 11 10:08:14 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * main.c (main): Disable window interface if --help or --version
+ specified.
+
+Wed Jan 10 16:08:49 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * configure.in, configure: Recognize rs6000-*-aix4*.
+ * config/powerpc/xm-aix.h: Reduce to include "xm-aix4.h".
+ * config/rs6000/aix4.mh (XM_FILE): Point to xm-aix4.h.
+ * config/rs6000/xm-aix4.h: New file.
+ * config/xm-aix4.h: New file.
+
+Wed Jan 10 11:25:37 1996 Fred Fish <fnf@cygnus.com>
+
+ From Wilfried Moser <wilfried.moser@aut.alcatel.at>:
+ * gdbserver/low-linux.c: New file.
+ * remote.c (remote_read_bytes): Fix aborts on larger packets.
+
+ * config/i386/linux.mh (GDBSERVER_DEPFILES, GDBSERVER_LIBS):
+ Define.
+ * stabsread.c (define_symbol): If register value is too large,
+ tell what it is and what max is.
+
+Tue Jan 9 09:33:53 1996 Jeffrey A Law (law@cygnus.com)
+
+ * hpread.c (hpread_build_psymtabs): Finish Jan 4th
+ enum namespace -> enum_namespace change.
+
+Tue Jan 9 04:44:47 1996 Wilfried Moser <moser@rtl.cygnus.com>
+
+ * ch-exp.c (parse_primval): In case ARRAY, add missing
+ FORWARD_TOKEN ().
+
+Mon Jan 8 13:29:34 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-mips.c (mips_receive_header): Recognize \012 instead
+ of \n, but write \n when program sends a \012.
+ * ser-mac.c (mac_input_buffer): Increase size of buffer.
+
+Mon Jan 8 12:00:40 1996 Jeffrey A Law (law@cygnus.com)
+
+ * infptrace.c (initialize_infptrace): Move function out of
+ #ifdef conditional; put code within the function inside an
+ #ifdef conditional.
+
+ * buildsym.c (end_symtab): Remove sort_pending and sort_linevec
+ arguments. Sorting is now dependent on OBJF_REORDERED. All
+ callers/references changed.
+ * dbxread.c (read_ofile_symtab): Correctly determine value for
+ last_source_start_addr for reordered executables.
+ (process_one_symbol): Handle N_FUN with no name as an end of
+ function marker.
+ * partial-stab.h (case N_FN, N_TEXT): Don't assume CUR_SYMBOL_VALUE
+ is the high text address for a psymtab.
+ (case N_SO): Likewise.
+ (case N_FUN): Handle N_FUN with no name as an end of function
+ marker.
+ * minsyms.c (lookup_minimal_symbol_by_pc): Examine all symbols
+ at the same address rather than a random subset of them.
+ * coffread.c (coff_symfile_init): Set OBJF_REORDERED.
+ * elfread.c (elf_symfile_init): Similarly.
+ * somread.c (som_symfile_init): Similarly.
+ * xcoffread.c (xcoff_symfile_init): Similarly.
+
+Fri Jan 5 17:46:01 1996 Stu Grossman (grossman@cygnus.com)
+
+ * stack.c (print_stack_frame print_frame_info) symmisc.c
+ (dump_symtab): Change RETURN_MASK_ERROR to RETURN_MASK_ALL so
+ that catch_errors doesn't get blindsided by QUIT and lose the
+ cleanup chain. This fixes a problem where ^C while in a
+ user-defined command sometimes leaves instream NULL and causes a
+ segfault in command_loop.
+
+Fri Jan 5 13:59:16 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * configure.in, configure: Add `-ldl -lw' for Solaris linking.
+
+Fri Jan 5 12:02:00 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * config/sh/sh.mt, config/powerpc/*.mt, config/pa/hppapro.mt,
+ config/m68k/monitor.mt, config/h8500/h8500.mt, config/h8300/h8300.mt:
+ srec.o renamed to dsrec.o.
+
+Thu Jan 4 16:04:54 1996 Stu Grossman (grossman@cygnus.com)
+
+ * breakpoint.c (remove_breakpoint): Change error to warning so
+ that hardware watchpoint removal problems won't leave breakpoint
+ traps in the target.
+ * remote-e7000.c (e7000_insert_breakpoint,
+ e7000_remove_breakpoint): Use e7000 based breakpoints, not memory
+ breakpoints.
+ * (e7000_wait): Adjust PC back by two when we see a breakpoint to
+ compensate for e7000 maladjustment.
+ * sparcl-tdep.c (sparclite_check_watch_resources): Fix logic bug
+ which prevented hardware watchpoints from working.
+
+Thu Jan 4 10:44:17 1996 Fred Fish <fnf@cygnus.com>
+
+ * infptrace.c (udot_info): New function.
+ (PT_*): Define each individually if that one is not defined.
+ * rs6000-nat.c (kernel_u_size): New function
+ Include <sys/user.h> for "struct user"
+ * alpha-nat.c (kernel_u_size): New function.
+ Include <sys/user.h> for "struct user"
+ * sparc-nat.c (kernel_u_size): New function.
+ Include <sys/user.h> for "struct user"
+ * i386b-nat.c (kernel_u_size): New function.
+ * i386v-nat.c (kernel_u_size): New function.
+ * config/i386/nm-fbsd.h (KERNEL_U_SIZE): Define.
+ (kernel_u_size): Declare.
+ * config/i386/nm-linux.h (KERNEL_U_SIZE): Define.
+ (kernel_u_size): Declare.
+ * config/sparc/nm-sun4os4.h (KERNEL_U_SIZE): Define.
+ (kernel_u_size): Declare.
+ * config/alpha/nm-osf2.h (KERNEL_U_SIZE): Define.
+ (kernel_u_size): Declare.
+ * config/rs6000/nm-rs6000.h (KERNEL_U_SIZE): Define.
+ (kernel_u_size): Declare.
+
+Thu Jan 4 11:00:01 1996 steve chamberlain <sac@slash.cygnus.com>
+
+ * mdebugread.c (mylookup_symbol): enum namespace becomes
+ enum_namespace type.
+ * symfile.c (add_psymbol_to_list)
+ (add_psymbol_addr_to_list): Ditto.
+ * symtab.c (lookup_partial_symbol): Ditto.
+ (lookup_symbol): Ditto.
+ (lookup_block_symbol): Ditto.
+ * win32-nat.c (handle_load_dll): Use incoming dll base.
+ (child_wait): Catch DLL load errors.
+ (create_child_inferior): Translated between paths correctly.
+
+Wed Jan 3 23:13:53 1996 Fred Fish <fnf@cygnus.com>
+
+ * i386v4-nat.c (supply_gregset, fill_gregset): Subtract NUM_FREGS
+ from NUM_REGS to get number of general registers that we care about.
+ * config/i386/tm-i386.h (REGISTER_BYTES): Define in terms
+ of number of general regs and number of floating point regs.
+
+Wed Jan 3 19:49:54 1996 steve chamberlain <sac@slash.cygnus.com>
+
+ * config/i386/tm-win32.h (IN_SOLIB_CALL_TRAMPOLINE): New.
+ (SKIP_TRAMPOLINE_CODE): New.
+ * config/i386/xm-win32.h (CANT_FORK): Deleted.
+ (SLASH*) Changed to use unix style slash.
+ * symtab.h (namespace enum): becomes typedef to avoid namespace
+ collision in C++.
+ * infcmd.c (path_command): Use empty string if PATH name not set.
+ * i386-tdep.c (skip_trampoline_code): New function.
+ * srec.c: Renamed dsrec.c to avoid filename collision.
+ * Makefile.in: Cope with renaming.
+
+Wed Jan 3 13:09:04 1996 Fred Fish <fnf@cygnus.com>
+
+ * symmisc.c (print_objfile_statistics): Print memory use statistics
+ for objfile psymbol, symbol, and type obstacks.
+
+Tue Jan 2 13:41:14 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/mips/nm-irix5.h: Restore.
+ (TARGET_HAS_HARDWARE_WATCHPOINTS, etc): Define as for Irix 4;
+ from Lee Iverson <leei@ai.sri.com>.
+ * config/mips/irix5.mh (NAT_FILE): Use nm-irix5.h.
+ * config/mips/irix[345].mh (MUNCH_DEFINE): Remove.
+
+For older changes see ChangeLog-1995
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/ChangeLog-1997 b/gdb/ChangeLog-1997
new file mode 100644
index 00000000000..4f66a90cf42
--- /dev/null
+++ b/gdb/ChangeLog-1997
@@ -0,0 +1,2909 @@
+Wed Dec 31 11:43:53 1997 Mark Alexander <marka@cygnus.com>
+
+ * dsrec.c (load_srec): Check remotedebug flag when printing
+ debug info.
+
+Wed Dec 31 10:33:15 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * breakpoint.c (breakpoint_re_set): add _siglongjmp to list of
+ longjmp breakpoints.
+
+Mon Dec 29 21:25:34 1997 Mark Alexander <marka@cygnus.com>
+
+ * dve3900-rom.c: New file to support Densan DVE-R3900/20 board.
+ * monitor.c (monitor_debug): Move to utils.c, rename to puts_debug.
+ (monitor_write_memory, monitor_read_memory, monitor_insert_breakpoint,
+ monitor_remove_breakpoint): Remove useless address bits if current
+ monitor has MO_ADDR_BITS_REMOVE flag.
+ * monitor.h (MO_ADDR_BITS_REMOVE): Define.
+ * utils.c (puts_debug): Formerly monitor_debug from monitor.c;
+ move here and make public. Add better support for carriage returns.
+ * defs.h (puts_debug): Declare.
+ * dsrec.c (load_srec): Use puts_debug to print remotedebug information.
+ Output header record correctly.
+ (make_srec): Output a header record instead of a termination record
+ if sect is non-NULL (value is ignored), but abfd is NULL.
+ * config/mips/tm-tx39.h (DEFAULT_MIPS_TYPE): Remove definition.
+ (REGISTER_NAMES): Define to add R3900-specific registers.
+ * config/mips/tm-tx39l.h: Ditto.
+ * config/mips/tx39.mt (TDEPFILES): Add dve3900-rom.o and support files.
+ * config/mips/tx39l.mt: Ditto.
+
+Wed Dec 24 12:48:48 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * dsrec.c: Cosmetic improvements.
+ (make-srec): Change indexing of format and code tables to
+ remove confusing empty entries.
+
+Mon Dec 22 21:51:53 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c (_initialize_remote_mips): Fix DDB doc string.
+
+Sun Dec 21 17:00:06 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * d30v-tdep.c (d30v_frame_find_saved_regs): split most of
+ function off into d30v_frame_find_saved_regs_offsets;
+ (d30v_frame_find_saved_regs_offsets): new function. Got
+ backtrace working when calling from framefull (unoptimized)
+ routines (.e.g, main) into frameless (optimized) routines
+ (e.g., printf).
+
+Fri Dec 19 09:49:49 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * d30v-tdep.c (d30v_frame_chain): test end_of_stack
+ (d30v_frame_find_saved_regs): set it.
+ * config/d30v/tm-d30v.h: improved FRAME_CHAIN_VALID
+
+Thu Dec 18 12:34:28 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Gavin Koch <gavin@cygnus.com>: mips-tdep.c
+ * (mips_push_arguments): For big-endian shorts and char's store at
+ * the correct location.
+
+Thu Dec 18 00:26:46 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mdebugread.c (parse_partial_symbols): Delete check that symbols
+ for file not already loaded. Did not work when an include file
+ was involved.
+
+Wed Dec 17 10:43:04 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * elfread.c (elf_symfile_read): Since the partial symbol table is
+ searched last in first, insert mdebug or XCOFF info into the
+ partial symbol table before any DWARF2 info.
+
+Thu Dec 18 00:00:48 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * symfile.c (init_psymbol_list): Handle init with zero elements.
+
+ * elfread.c (elf_symfile_read): If `mainline', clear psymbol table
+ using init_psymbol_list 0. For build_psymtabs functions, pass
+ mainline==0 so that psymbol_list isn't re-initialized.
+
+ * symfile.c (discard_psymtab): New function, correctly unlink an
+ empty psymtab from an object file.
+ * dbxread.c (end_psymtab): Call discard_psymtab.
+ * xcoffread.c (xcoff_end_psymtab): Ditto.
+ * hpread.c (hpread_end_psymtab): Ditto.
+ * os9kread.c (os9k_end_psymtab): Ditto.
+
+Wed Dec 17 10:47:05 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c (set_raw_tracepoint): initialize addr_string
+ to NULL; (trace_actions_command): call readline_begin_hook only
+ if from_tty is true.
+
+Tue Dec 16 20:05:48 1997 Mark Alexander <marka@cygnus.com>
+
+ * configure.tgt: Change little-endian tx39 target name to tx39l.
+
+Tue Dec 16 11:24:30 1997 Jeffrey A Law (law@cygnus.com)
+
+ * remote-sim.c (gdbsim_open): Use "--architecture" instead of
+ ambigious short form.
+
+Tue Dec 16 10:29:16 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * d30v-tdep.c (d30v_frame_chain): don't or in DMEM_START to
+ FP_REGNUM value before return; (prologue_find_regs): two sets
+ of offsets -- frame pointer and stack pointer, not just one that
+ tries to do double duty; (d30v_frame_find_saved_regs): stop once
+ we hit pc (in case we're stopped in the middle of the prologue)
+ and improve handling of frameless prologues; (d30v_push_arguments):
+ *ALL* arguments go on the stack until we run out of args registers,
+ force sp to be 8 byte aligned.
+
+ * config/tm-d30v.h (EXTRACT_STRUCT_VALUE_ADDRESS): fix, it's r2,
+ not r0; (FRAME_CHAIN_VALID): handle use of external memory;
+ (STACK_ALIGN): define.
+
+Mon Dec 15 15:13:57 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_wait): When HAVE_SIGACTION and SA_RESTART
+ intall cntrl-c handler with SA_RESTART clear. On BSD systems this
+ stops read syscalls's being restarted.
+
+ * configure.in (configdirs): Check for sigaction.
+ * configure: Re-generate.
+
+Mon Dec 15 11:38:52 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * dwarf2read.c: From change proposed by Gavin Koch.
+ (address_significant_size): New static variable.
+ (dwarf2_build_psymtabs_hard): Check consistency between
+ `address_size' and `address_significant_size'.
+ (read_address): MASK out all but the significant bits, as
+ determined by `address_significant_size', of any addresses.
+ (elf-bfd.h): Include.
+ (dwarf2_build_psymtabs_hard): Set `address_significant_size'
+ according to the arch_size of the elf object file.
+
+Thu Dec 11 13:40:46 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * dwarf2read.c (dwarf_decode_lines): Change type of address to
+ CORE_ADDR.
+
+Thu Dec 11 22:39:02 1997 Mark Alexander <marka@cygnus.com>
+
+ From change made to branch by Bob Manson <manson@cygnus.com>:
+ * tic80-tdep.c (tic80_push_arguments): The compiler always
+ passes structs by reference.
+
+Thu Dec 11 14:28:01 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c (trace_find_command): don't error if going
+ backwards thru the trace buffer in a loop.
+ * (struct tracepoint): delete unused field.
+
+Wed Dec 10 17:57:00 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * d30v-tdep.c : don't bury lots of magic numbers in the code
+ instead use defines for the opcodes and opcode masks; update
+ to use actual d30v patterns; fix register sizes to be 4 bytes
+ not 2 bytes; improve prologue testing now that we have a C
+ compiler; fix stack frame handling enough to get backtraces
+ working; initial changes to push and pop frames (so that gdb
+ can call functions in the inferior).
+
+ * config/d30v/tm-d30v.h: update DMEM_START, IMEM_START, and
+ STACK_START; change FR_REGNUM to 61 (was 11). Reformat comment
+ about DUMMY FRAMES so that it is readable. Fix SAVED_PC_AFTER_FRAME
+ macro.
+
+Wed Dec 10 17:41:07 1997 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ch-valprint.c (chill_val_print): To avoid segfaults, don't print
+ a string whose dynamic length is longer than its static length.
+
+Wed Dec 10 15:54:00 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * dwarf2read.c (dwarf2_build_psymtabs_hard): Check
+ cu_header.length is within dwarf_info_buffer not
+ dwarf_abbrev_buffer.
+
+Mon Dec 8 14:28:49 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c (memrange_sortmerge): allow for memranges
+ that overlap. (collect_pseudocommand etc.) cleanup decls.
+
+Fri Dec 5 09:22:35 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/v850/tm-v850.h (BREAKPOINT): Reverted back to old value...
+
+Thu Dec 4 09:30:22 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/v850/tm-v850.h (BREAKPOINT): Changed to match new value.
+
+Wed Dec 3 12:44:15 1997 Keith Seitz <keiths@onions.cygnus.com>
+
+ * tracepoint.c: Add declaration for x_command.
+
+ * printcmd.c (x_command): Remove static declaration.
+
+Wed Dec 3 12:00:42 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c (finish_tfind_command): call do_display so that
+ auto-displays are updated by tfind. Also, keep track of frame
+ and current-function so that tfind behaves like stepping (only
+ show the stack frame if we step into a new function or return).
+
+Wed Dec 3 14:14:58 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * sol-thread.c: additional support for debugging threaded core
+ files on solaris; previously only kernel threads were found --
+ user threads generated errors.
+ * corelow.c: don't register core_ops as a target if
+ coreops_suppress_target is true (set by sol-thread.c).
+
+Tue Dec 2 14:53:09 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c: make "tdump" command handle literal memranges.
+
+Tue Dec 2 11:34:48 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c: use "lookup_cmd" to parse actions commands
+ (thus allowing unambiguous prefixes and aliases).
+
+Tue Dec 2 10:15:57 1997 Nick Clifton <nickc@cygnus.com>
+
+ * configure.tgt: Add support for Thumb target.
+
+Tue Dec 2 10:14:15 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c: move prototype of validate_actionline(), and
+ make it consistent with the function declaration.
+
+Thu Nov 27 09:07:18 1997 Michael Meissner <meissner@cygnus.com>
+
+ * Makefile.in (tracepoint_h): New macro for tracepoint.h
+ includes.
+ (tracepoint.o): Add rule to build.
+
+Wed Nov 26 22:59:04 1997 Jeffrey A Law (law@cygnus.com)
+
+ * remote-sim.c (gdbsim_cntrl_c): Lose ANSI prototype.
+
+ * tracepoint.c (set_raw_tracepoint): fix typo
+
+Wed Nov 26 11:33:09 1997 Keith Seitz <keiths@onions.cygnus.com>
+
+ * tracepoint.c (set_raw_tracepoint): Make sure there's a trailing
+ slash on the directory name.
+
+ * top.c (get_prompt): New function.
+ * top.h: Declare it.
+
+Wed Nov 26 09:59:47 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * dwarf2read.c (struct comp_unit_head): Change length and
+ abbrev_offset fields to unsigned int.
+ (dwarf2_build_psymtabs_hard): Verify length and offset read from
+ .debug_info section.
+
+Mon Nov 24 19:36:34 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c, tracepoint.h: new module, implements tracing,
+ which is a new functionality somewhat like breakpoints except
+ that a tracepoint stops the inferior only long enough to collect
+ and cache selected buffers and memory locations, then allows
+ the inferior to continue; the cached trace data can then be
+ examined later.
+
+Mon Nov 24 14:17:02 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * infcmd.c: export registers_info, for use by other modules.
+ * printcmd.c: export output_command, for use by other modules.
+ * stack.c: export locals_info and args_info, for use by other modules.
+ * remote.c: export getpkt, putpkt, and fromhex for external use.
+ Make fromhex case-insensative. New function "remote_console_output"
+ abstracts the acceptance of "O" packets from target.
+ Make all "remotedebug" output go to stdout, not stderr.
+
+Mon Nov 24 08:59:28 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * valprint.c (print_longest): When CC has long long but printf
+ doesn't, print decimal value as three parts.
+
+ * config/i386/tm-fbsd.h: New file.
+ * config/i386/fbsd.mt (TM_FILE): Change to tm-fbsd.h.
+
+ * config/i386/nm-fbsd.h (FLOAT_INFO): Move definition from here.
+ * config/i386/tm-fbsd.h (FLOAT_INFO): To here.
+
+ * configure.in (PRINTF_HAS_LONG_LONG): Check full functionality of
+ %ll format specifier.
+ (SCANF_HAS_LONG_DOUBLE): Check the scanf family for support of
+ long double using %Lg.
+ * acconfig.h: Provide default undef for SCANF_HAS_LONG_DOUBLE.
+ * configure: Re-generate.
+
+ * c-exp.y (parse_number): Use sscanf %Lg when host has
+ SCANF_HAS_LONG_DOUBLE not PRINTF_HAS_LONG_DOUBLE
+
+Sun Nov 23 17:12:58 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * printcmd.c (print_insn): Set the machine type if known.
+
+ * i386-tdep.c (_initialize_i386_tdep): Delete "set
+ assembly-language" command. Replaced by generic "set
+ architecture". Set initial machine using bfd_lookup_arch.
+
+Fri Nov 21 19:43:23 1997 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * valops.c (call_function_by_hand): If the function has a
+ prototype, convert its arguments as if by assignment. Otherwise,
+ do the usual promotions.
+ * stabsread.c (define_symbol): Set the TYPE_FLAG_PROTOTYPED flag
+ on functions' types when we can; all C++ functions should get it,
+ and if the Sun-style prototype notation is in the stabs, we can
+ notice that.
+
+Fri Nov 21 12:20:16 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4 (AM_CYGWIN32, AM_EXEEXT): Remove. They are already
+ defined by the inclusion of ../bfd/aclocal.m4.
+ * configure: Rebuild.
+
+Fri Nov 21 10:52:39 1997 Michael Meissner <meissner@cygnus.com>
+
+ * Makefile.in (SHELL): Really do the change.
+
+Fri Nov 21 02:19:57 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * Makefile.in: also revert SHELL change until configury
+ changes work
+
+Thu Nov 20 16:35:13 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * sparc-tdep.c (sparc_pc_adjust): Don't assume sizeof (long) == 4.
+
+Thu Nov 20 04:11:27 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * aclocal.m4: add EXEEXT setting rule
+ * configure.in: call it
+ * configure: regenerate
+ * Makefile.in: pepper with EXEEXTs in appropriate places,
+ set SHELL = @SHELL@ for those lame hosts that don't have a /bin/sh
+ For some reason, EXEEXT isn't getting substututed in correctly
+ so for now, set EXEEXT to empty string
+
+Mon Nov 17 15:35:06 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * Makefile.in (remote-sim.o): Depend on $(INCLUDE_DIR)/callback.h.
+
+Fri Nov 14 13:04:34 1997 Jeffrey A Law (law@cygnus.com)
+
+ * jv-exp.y (copy_exp, insert_exp): Avoid ANSI prototypes.
+
+Thu Nov 13 09:47:35 1997 Michael Meissner <meissner@cygnus.com>
+
+ * d30v-tdep.c (d30v_print_flags): Function to print the d30v flags
+ in a human readable format.
+ (print_flags_command): Command wrapper to call d30v_print_flags.
+ (d30v_do_registers_info): When printing out all of the registers,
+ print out the flag values in a human readable fashion.
+ (_initialize_d30v_tdep): Add info flags command to print the
+ flags.
+
+ * config/d30v/tm-d30v.h (PSW_*): Add macros for each of the PSW
+ bits that are defined.
+
+Wed Nov 12 14:58:39 1997 Jeff Holcomb <jeffh@cygnus.com>
+
+ * symfile.c (generic_load): Handle cancel from the
+ ui_load_progress_hook routine.
+ * dsrec.c (load_srec): Handle cancel from the
+ ui_load_progress_hook routine.
+
+Mon Nov 10 15:13:13 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * valprint.c (print_longest): The b, h, w, and g format specifiers
+ print unsigned values.
+
+Mon Nov 10 02:02:49 1997 Martin M. Hunt <hunt@cygnus.com>
+
+ * top.c (quit_confirm): Change exit message.
+
+Tue Nov 4 16:52:50 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * config/i386/cygwin32.mh: because cygwin.dll calls malloc/realloc
+ to allocate memory for environ space, gdb cannot use memory
+ checks -- set -DNO_MMCHECK
+
+Tue Nov 4 13:50:59 1997 Jim Blandy <jimb@sendai.cygnus.com>
+
+ * jv-exp.y (ArrayAccess): Implement Name [ Expression ]; check the
+ code to see why this is not trivial.
+ (copy_exp, insert_exp): New functions.
+
+Fri Oct 24 17:24:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * dwarf2read.c (dwarf2_build_psymtabs_hard): Handle the case
+ where a compilation unit die has no children (DW_TAG_compile_unit
+ has DW_children_no).
+ (scan_partial_symbols): Add comment for nesting_level.
+
+Wed Oct 29 15:53:24 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * solib.c (solib_break_names): add entry for Solaris 2.6 run
+ time linker. From Casper Dik via Peter Schauer.
+
+Tue Oct 28 17:31:47 1997 Martin M. Hunt <hunt@cygnus.com>
+
+ * configure.in (configdir): Add -lcomdlg32 and -ladvapi32
+ to WIN32LIBS.
+
+ * configure: Rebuild
+
+Fri Oct 24 16:48:21 1997 David Taylor <taylor@texas.cygnus.com>
+
+ * sol-thread.c (sol_find_new_threads_callback,
+ sol_find_new_threads): New functions.
+ * config/sparc/nm-sun4sol2.h (FIND_NEW_THREADS): New macro, invoke
+ sol_find_new_threads.
+ * thread.c (info_threads_command): invoke FIND_NEW_THREADS if it
+ is defined.
+
+Thu Oct 23 16:16:04 1997 Jeff Law (law@fast.cs.utah.edu)
+
+ * dbxread.c (process_one_symbol): Put back initialization
+ of a variable lost during last change. Don't perform
+ assignment inside conditionals.
+ * stabsread.c (symbol_reference_defined): Return -1 for error/not
+ found. All callers changed appropriately.
+ (define_symbol): Don't perform assignment inside conditionals.
+
+Wed Oct 22 13:04:52 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mdebugread.c (psymtab_to_symtab_1): Handle new live range stabs
+ entries.
+
+ * dbxread.c: More comment cleanups.
+ * stabsread.c: Fix various violations of the GNU coding and
+ formatting standards. Update/add comments to make code clearer.
+ (resolve_reference): Delete unused function.
+ (ref_search_val): Remove function. It didn't belong in stabsread.c
+ (resolve_live_range): No longer returns a value. Do not add it
+ to the live range list until the entire range stab has been parsed.
+ (get_substring): Remove duplicate declaration.
+ (resolve_symbol_reference): Now static. Remove unnecessary code
+ to deal with cleanups.
+ (ref_add): Use xrealloc instea of realloc.
+ (process_reference): Reorganize slightly to make clearer.
+ * stabsread.h (resolve_symbol_reference): Remove declaration.
+ (resolve_reference): Likewise.
+ * symtab.c (find_active_alias): New function.
+ (lookup_block_symbol): Use find_active_alias.
+ * symtab.h (struct range_list): Fix dangling struct live_range
+ reference.
+ (ref_search_val): Remove decl.
+
+ * symtab.h (struct range_list): Renamed from struct live_range.
+ (struct symbol): Remove struct live_range_info substruct.
+ Bring the alias list and range list fields up to the toplevel
+ as "aliases" and "ranges".
+ (SYMBOL_ALIASES, SYMBOL_RANGES): Corresponding changes.
+ (SYMBOL_RANGE_START, SYMBOL_RANGE_END, SYMBOL_RANGE_NEXT): Delete.
+ * stabsread.c: Corresponding changes.
+
+ * dbxread.c: Fix various violations of the GNU coding and
+ formatting standards. Update/add comments to make code
+ clearer.
+ (process_later): Use xrealloc instead of realloc.
+
+ * symtab.c: Include inferior.h.
+
+Tue Oct 21 14:15:26 1997 Per Bothner <bothner@cygnus.com>
+
+ * ch-exp.c: Rename FIELD_NAME to DOT_FIELD_NAME (to avoid conflict).
+
+Fri Oct 17 13:22:02 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infcmd.c: Improve grammar of "set args" help.
+
+Thu Oct 16 15:03:58 1997 Michael Meissner <meissner@cygnus.com>
+
+ * remote-sds.c (sds_load): Properly declare as static.
+
+Wed Oct 15 10:27:14 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/sparc/tm-sparc.h (FIX_CALL_DUMMY): Mask off displacement
+ to 30 bits in call insn to handle --enable-64-bit-bfd.
+ (STORE_STRUCT_RETURN): Change to handle --enable-64-bit-bfd.
+
+Tue Oct 14 22:13:27 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * stabsread.c: Make ref_map entries dynamically allocated.
+
+Thu Oct 9 12:37:57 1997 Frank Ch. Eigler <fche@cygnus.com>
+
+ * printcmd.c (print_address_symbolic, address_info): Mask
+ target-specific flag bits from PC, for more aesthetic disassembly.
+ * config/mips/tm-mips.h: Added PC masking for MIPS family
+ (especially the MIPS16).
+
+Sat Oct 4 18:45:44 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c (mips-initialize): Work around flakiness in
+ some versions of PMON after loading a program.
+
+Fri Oct 3 15:49:18 1997 Per Bothner <bothner@cygnus.com>
+
+ * c-lang.h, cp-valprint.c (static_field_print): Make non-static.
+ * parse.c, parser-defs.h (length_of_subexp): Make non-static.
+ * jv-exp.y (FieldAccess): Handle dollar-VARIABLE as primary.
+ (ArrayAccess): Likewise. Also remove warnings.
+ (CastExpression): Implement (typename) UnaryExpression.
+ (push_qualified_expression_name): Fix small bug.
+ * jv-lang.c: Use TYPE_TAG_NAME, not TYPE_NAME for class names.
+ (_initialize_jave_language): Fix typo (jave -> java).
+ (java_language): Java does *not* have C-style arrays.
+ (java_class_from_object): Make more general (and complicated).
+ (java_link_class_type): Fix typo "super" -> "class". Handle arrays.
+ (java_emit_char, java_printchar): New function.
+ (evaluate_subexp_java case BINOP_SUBSCRIPT): Handle Java arrays.
+ * jv-valprint.c (java_value_print): Implement printing of Java arrays.
+ (java_print_value_fields): New function.
+ (java_val_print): Better printing of TYPE_CODE_CHAR, TYPE_CODE_STRUCT.
+
+Fri Oct 3 09:52:26 1997 Mark Alexander <marka@cygnus.com>
+
+ * config/mips/tm-mips.h (MAKE_MSYMBOL_SPECIAL): Force MIPS16
+ addresses to be odd.
+ (MIPS_FPU_SINGLE_REGSIZE, MIPS_FPU_DOUBLE_REGSIZE): Define.
+ * mips-tdep.c (mips_extract_return_value): Doubles aren't
+ returned in FP0 if FP registers are single-precision only.
+
+Mon Sep 29 23:03:03 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (set_reg_offset): New function.
+ (mips16_heuristic_proc_desc): Calculate offsets of registers
+ saved by entry pseudo-op after rest of prologue has been read.
+ Use set_reg_offset to ignore all but the first save of a given
+ register.
+ (mips32_heuristic_proc_desc): Initialize frame adjustment value.
+ * remote-sim.c (gdbsim_store_register): Don't update registers
+ that have a null or empty name.
+ * findvar.c (read_register_bytes): Don't fetch registers
+ that have a null or empty name.
+
+Tue Sep 30 13:35:54 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/mips/tm-mips.h (NUM_REGS): Define conditionally.
+ (REGISTER_NAMES): Ditto.
+
+Fri Sep 26 21:08:22 1997 Keith Seitz <keiths@pizza.cygnus.com>
+
+ * dsrec.c (load_srec): add ui_load_progress_hook to
+ display some feedback to user
+
+ * symfile.c (generic_load): add ui_load_progress_hook to
+ display some feedback to user
+
+Fri Sep 26 17:32:22 1997 Jason Molenda (crash@pern.cygnus.com)
+
+ * command.c (add_cmd, add_show_from_set): Insert new commands in
+ alphabetical order.
+
+Fri Sep 26 12:22:00 1997 Mark Alexander <marka@cygnus.com>
+
+ * config/mips-tm-mips.h (mips_extra_func_info): New frame_adjust
+ member for storing offset of MIPS16 frame pointer from SP.
+ * mips-tdep.c: Use RA_REGNUM instead of hardcoded 31 throughout.
+ (PROC_FRAME_ADJUST): Define.
+ (mips16_heuristic_proc_desc): Store frame pointer adjustment value.
+ (get_frame_pointer): Use frame pointer adjustment value when
+ calculating frame address.
+ * remote-sim.c (gdbsim_fetch_register): Don't fetch registers
+ that have a null or empty name.
+
+Fri Sep 26 12:40:51 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mips-tdep.c (_initialize_mips_tdep): Allow target files to
+ override default FPU type.
+
+Fri Sep 26 10:33:54 1997 Felix Lee <flee@cygnus.com>
+
+ * configure.tgt (v850-*-*): necmsg.lib instead of v850.lib.
+
+Wed Sep 24 14:02:09 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/v850/tm-v850.h (BREAKPOINT): Use 1 word DIVH insn with
+ RRRRR=0 for simulator breakpoint. Previous breakpoint insn was two
+ words.
+
+Thu Sep 18 15:07:46 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ser-e7kpc.c (get_ds_base): Only use under Windows.
+ (windows.h): Include when any _WIN32 host.
+
+Wed Sep 24 18:12:47 1997 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * The following block of changes add support for debugging assembly
+ source files.
+ * breakpoint.c (resolve_sal_pc): Prevent crash when pc isn't
+ associated with a function.
+ * buildsym.c (record_line start_symtab end_symtab): Don't delete
+ symtabs which only have line numbers (but no other debug symbols).
+ * dbxread.c (read_dbx_symtab end_psymtab): Ditto.
+
+ * remote-sim.c: New functions gdbsim_insert/remove_breakpoint. Use
+ intrinsic simulator breakpoints if available, otherwise do it the
+ hard way.
+
+ * configure.tgt: Add d30v.
+ * d30v-tdep.c: New file.
+ * config/d30v/d30v.mt, config/d30v/tm-d30v.h: New files.
+
+Tue Sep 23 11:24:13 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * Makefile.in (ALLCONFIG): Remove, inaccurate and never used.
+
+Tue Sep 23 00:08:18 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mips-tdep.c (mips_push_arguments): Tweak alignment of register
+ value if the remaining length of a non-integral argument is smaller
+ than the register size for big-endian non-EABI mode.
+
+ * rs6000-tdep.c (branch_dest): Handle return from signal
+ handler function via sigreturn kernel call.
+
+Mon Sep 22 15:32:06 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * stabsread.h, symtab.h, dbxread.c, symtab.c, stabsread.c:
+ Fix prototypes. Remove function scoped function declarations.
+
+Fri Sep 19 18:51:26 1997 Felix Lee <flee@cygnus.com>
+
+ * config/i386/windows.mh (XDEPFILES): need to list some files
+ explicitly, for odd reasons.
+
+Tue Sep 16 20:00:05 1997 Per Bothner <bothner@cygnus.com>
+
+ * jv-exp.y (push_fieldnames): New, to handle EXP.FIELD1....FIELDN.
+ (push_expression_name): New, to handle expression names.
+ (push_qualified_expression_name): New, for qualified expression names.
+ (parse_number): Fix bugs in parsing of non-decimal integers.
+ * jv-lang.h, jv-lang.c (java_demangle_type_signature): New.
+ * jv-lang.c (type_from_class): Just use name with java_lookup_class.
+ (java_link_class_type): Add dummy "class" field.
+ (java_lookup_type): New.
+ (evaluate_subexp_java case STRUCTOP_STRUCT): Force to address.
+ * jv-typeprint.c (java_type_print_base): Don't print "class" field.
+ Use java_demangle_type_signature to print array class types.
+ * jv-valprint.c (java_value_print): Preliminary array support.
+ Print pointer as TYPE@HEXADDR, instead of (TYPE)0xHEXADDR.
+ (java_val_print): Move check for object type to java_value_print.
+ Check for null. Print pointer as @HEXADDR, not 0xHEXADDR.
+
+ * valops.c (search_struct_field): Search basesclasses in
+ ascending, not descending order. Hack to avoid virtual baseclass
+ botch for Java interfaces.
+
+Tue Sep 16 19:56:23 1997 Per Bothner <bothner@cygnus.com>
+
+ * util.c (run_cleanup_chain, make_run_cleanup, do_run_cleanups):
+ New cleanup clean for cleanups to be run when at each 'run' command.
+ * infcmd.c (run_command): Call do_run_cleanups.
+
+ * solib.c (find_solib): Register cleanup to call clear_solib
+ on a new 'run' command.
+ (symbol_add_stub): First look for existing objfile with same name.
+
+Tue Sep 16 16:00:01 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-sds.c (sds_load): New function.
+ (sds_ops): Use it.
+ (sds_open): Don't set inferior_pid yet.
+ (sds_kill): Remove contents.
+ (sds_create_inferior): Rewrite to work more like monitor
+ interfaces.
+ (sds_restart): Remove, no longer used.
+
+ * monitor.h (MO_SREC_ACK_PLUS, MO_SREC_ACK_ROTATE): New flags.
+ * monitor.c (monitor_wait_srec_ack): Add DINK32-specific ack code.
+ * dsrec.c (load_srec): Always write a header S-record.
+ * dink32-rom.c (dink32_regnames): Fix the names of float registers.
+ (dink32_cmds): Set to use S-record downloading with acks.
+ * remote-est.c (est_cmds): Add MO_SREC_ACK_PLUS flag.
+
+Tue Sep 16 10:08:27 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/v850/tm-v850.h (BREAKPOINT): Set to a truely illegal
+ instruction.
+
+ * exec.c (exec_file_command): Call set_architecture_from_file.
+
+Mon Sep 15 13:01:22 1997 Mark Alexander <marka@cygnus.com>
+
+ * dbxread.c (MSYMBOL_SIZE): New macro.
+ (end_psymtab): Use MSYMBOL_SIZE to extract size from minimal symbol.
+ * elfread.c (elf_symtab_read): If ELF symbol is "special",
+ such as a MIPS16 function, mark minimal symbol as special too.
+ * mips-tdep.c (pc_is_mips16): New function to check whether
+ a function is MIPS16 by looking at the minimal symbol. Use
+ pc_is_mips16 throughout instead of IS_MIPS16_ADDR macro.
+ * config/mips/tm-mips.h (SYMBOL_IS_SPECIAL, MAKE_MSYMBOL_SPECIAL,
+ MSYMBOL_IS_SPECIAL, MSYMBOL_SIZE): New functions for setting/testing
+ "special" MIPS16 bit in ELF and minimal symbols.
+ * mdebugread.c (parse_partial_symbols): Don't construct a partial
+ symbol table for a file that already has one.
+
+Sat Sep 13 08:32:13 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mdebugread.c (parse_symbol, handle_psymbol_enumerators): Handle
+ yet another variant of enumerator debugging info, used by DU 4.0
+ native cc.
+
+Tue Sep 9 20:47:23 1997 Felix Lee <flee@cygnus.com>
+
+ * config/i386/windows.mh (XDEPFILES): reduce to libwingdb.a.
+ otherwise link command line is too long.
+
+Tue Sep 9 17:41:41 1997 Jeffrey A Law (law@cygnus.com)
+
+ * symtab.c, dbxread.c, stabsread.c: Fix up ANSI-C isms. Fix
+ some formatting problems.
+
+Mon Sep 8 16:45:51 1997 Stu Grossman <grossman@cygnus.com>
+
+ * ser-e7kpc.c: Don't include w32sut.h. We no longer use the UT
+ mechanism. Remove prototypes for dos_async_* functions. They don't
+ exist anymore.
+
+Mon Sep 8 12:48:50 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * top.c (quit_confirm, quit_force): New functions, broken out of
+ quit_command.
+ (quit_command): Just call quit_confirm and quit_force.
+ * top.h (quit_confirm, quit_force): Declare.
+
+Sun Sep 7 17:26:30 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * dbxread.c, buildsym.c, symtab.c, stabsread.c: Add support for
+ reading stabs extensions for live range information.
+ * stabsread.h, partial-stab.h: Add prototypes for new functions.
+ * symtab.h: Add structure for storing live range information.
+
+Wed Sep 3 16:39:39 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c (set_arch): New function, update target_architecture.
+
+ * defs.h, top.c (set_architecture_from_arch_mach): Replace
+ set_architecture, takes the arch and machine as arguments.
+
+ * sh3-rom.c (sh3e_open): Update.
+ (sh3_open): Ditto.
+
+Tue Sep 2 12:00:46 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-e7000.c (e7000_fetch_registers): Fix typo, stray paren.
+ (e7000_wait): Ditto.
+
+Mon Sep 1 11:21:03 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c (init_main): Add ``set processor'' as an alias for ``set
+ architecture''.
+
+Sat Aug 30 13:44:48 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/sparc/sparclite.mt: Removed simulator references (erc32
+ has been disabled).
+
+Thu Aug 28 10:20:04 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-e7000.c (e7000_fetch_registers): Check
+ target_architecture instead of sh_processor_type.
+ (e7000_wait): Ditto.
+
+ * config/sh/tm-sh.h (sh_set_processor_type): Delete prototype.
+
+ * sh3-rom.c (sh3_open): Call set_architecture not
+ sh_set_processor_type.
+ (sh3e_open): Ditto.
+
+ * sh-tdep.c (sh_show_processor_type_command): Delete.
+ (sh_set_processor_type_command): Delete.
+ (sh_target_architecture_hook): Rename from sh_set_processor_type,
+ use AP to determine architecture.
+ (sh_show_regs): Use bfd_mach_sh* types.
+
+ * remote-sim.c (gdbsim_open): Pass --arch=XXX to simulator when
+ architecture was specified explicitly.
+
+ * defs.h (target_architecture, target_architecture_auto,
+ set_architecture, set_architecture_from_file): Declare.
+ (target_architecture_hook): Allow targets to be notified of set
+ arch commands.
+
+ * top.c (init_main): Add set/show/info architecture commands.
+ (set_architecture, show_architecture, info_architecture): New
+ functions, parse same.
+ (set_architecture_from_file): New function, determine arch from
+ BFD.
+
+Tue Aug 26 17:13:43 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_open): Only pass endianness to sim_open
+ when set explicitly. Prepend endianness arg so that it can be
+ overridden.
+
+ * defs.h, top.c (target_byte_order_auto): Make global when
+ byteorder is selectable.
+
+Tue Aug 26 15:19:56 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_create_inferior): Pass exec_bfd into
+ sim_create_inferior.
+ (gdbsim_create_inferior): Pass -1 to proceed, sim_create_inferior
+ has already set the PC.
+ (gdbsim_create_inferior): Allow exec_file to be NULL, make "No
+ exec file" a warning. Ditto for "No program loaded".
+
+Mon Aug 25 17:08:01 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * ocd.c: revert Sun change -- enable log file handling
+
+Mon Aug 25 12:21:46 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_open): Pass exec_bfd to sim_open call.
+
+Sun Aug 24 21:16:59 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * ocd.c: comment out sections that create and flush wigglers.log
+ log file when using the wiggler.
+
+Thu Aug 21 16:18:08 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * config/powerpc/ppc-eabi.mt:
+ * config/powerpc/ppc-sim.mt:
+ * config/powerpc/ppcle-eabi.mt:
+ * config/powerpc/ppcle-sim.mt: ser-ocd.c needs to be before
+ other ocd-related files in TDEPFILES
+
+Thu Aug 21 14:56:04 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * ppc-bdm.c (bdm_ppc_wait): stop printfing ecr, der
+ * ocd.c: initialize remote_timeout
+ (ocd_wait): while looping, call ocd_do_command with OCD_AYT
+ (ocd_get_packet): remove find_packet goto. If there isn't
+ an 0x55 at the start, something is quite wrong so error out
+ instead of advancing in the packet and trying again. If checksum
+ is invalid, print error message instead of trying again.
+ * ser-ocd.c (ocd_readchar): error if we attempt to read past
+ the end of the from_wiggler_buffer.
+
+
+Wed Aug 20 14:08:39 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * dink32-rom.c: Don't use "mf" command to fill, is too picky
+ about alignment.
+
+
+Tue Aug 19 08:41:36 1997 Fred Fish <fnf@cygnus.com>
+
+ * objfiles.c (objfile_relocate): Add call to breakpoint_re_set
+ after relocations are complete.
+ * remote-vx.c (vx_add_symbols): Remove call to breakpoint_re_set,
+ this is now done in objfile_relocate.
+
+Mon Aug 18 17:29:54 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * win32-nat.c (handle_exception): Return a value indicating
+ whether the exception was handled. Don't handle random exceptions
+ the first time around, so that structured exception handling
+ works.
+ (child_wait): Check the return value of handle_exception. Set the
+ continue_status argument to ContinueDebugEvent accordingly.
+
+Mon Aug 18 11:14:15 1997 Nick Clifton <nickc@cygnus.com>
+
+ * configure.tgt: Add support for v850ea target.
+
+Sun Aug 17 20:31:57 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * m32r-stub.c: fix typo
+
+Sun Aug 17 17:33:34 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-sds.c: Remove unused remnants of remote.c.
+ (tob64): Return the result length.
+ (sds_interrupt): Send a stop message.
+ (sds_wait): Add debug output for signal interpretation, flag
+ that signal was due to a trap.
+ (sds_fetch_registers): Fill the registers array correctly for
+ PowerPC.
+ (sds_store_registers): Get the right values from registers array.
+ (putmessage): Tweak length handling so checksum comes out right.
+ (sds_insert_breakpoint, sds_remove_breakpoint): Do correctly.
+
+Fri Aug 15 20:53:13 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (init.c): Don't use xargs.
+
+Fri Aug 15 13:59:37 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * infrun.c (wait_for_inferior): Add the symbols for any
+ newly loaded objects upon a TARGET_WAITKIND_LOADED event.
+
+ Rewrite code which determines the TOC address for calling functions
+ in the inferior under AIX.
+ * rs6000-nat.c (find_toc_address): New function to determine
+ the required TOC address from a function address.
+ (_initialize_core_rs6000): Set up find_toc_address_hook to point
+ to find_toc_address.
+ (xcoff_relocate_symtab, xcoff_relocate_core): Remove
+ add_text_to_loadinfo calls.
+ (exec_one_dummy_insn): Change pid and status to int to get rid of
+ compiler warnings.
+ (xcoff_relocate_symtab): Cast ldi to `int *' when passing it to
+ ptrace to get rid of compiler warnings.
+ * rs6000-tdep.c: Add definition for find_toc_address_hook.
+ (rs6000_fix_call_dummy): If find_toc_address_hook is non zero,
+ patch TOC address load code in the call dummy with the value
+ returned from find_toc_address_hook.
+ (struct loadinfo, loadinfo, loadinfolen,
+ loadinfotextindex, xcoff_init_loadinfo, free_loadinfo,
+ xcoff_add_toc_to_loadinfo, add_text_to_loadinfo, find_toc_address):
+ Remove.
+ (_initialize_rs6000_tdep): Remove initialization of
+ coff_add_toc_to_loadinfo_hook and xcoff_init_loadinfo_hook.
+ * xcoffread.c (coff_add_toc_to_loadinfo_hook,
+ xcoff_init_loadinfo_hook): Remove.
+ (struct coff_symfile_info): Add toc_offset field.
+ (scan_xcoff_symtab): Record toc_offset value in toc_offset field
+ instead of calling xcoff_add_toc_to_loadinfo_hook.
+ (get_toc_offset): New function to return the value of the
+ toc_offset field for an object file.
+ (xcoff_initial_scan): Remove call of xcoff_init_loadinfo_hook.
+ * xcoffsolib.h (add_text_to_loadinfo): Remove declaration.
+ * config/rs6000/tm-rs6000.h: Add declarations for
+ find_toc_address_hook and get_toc_offset.
+
+Wed Aug 13 19:31:28 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-sds.c: New file, interface to SDS-compatible monitors.
+ * Makefile.in (remote-sds.o): Add build rule.
+ * config/powerpc/ppc-eabi.mt, config/powerpc/ppc-sim.mt
+ (TDEPFILES): Add remote-sds.o.
+
+Tue Aug 12 14:37:18 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * ocd.c (ocd_wait): loop until we're in BDM mode instead of
+ assuming control has returned to GDB.
+
+Mon Aug 11 19:16:04 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * dink32-rom.c: New file, support for DINK32 monitor.
+ * Makefile.in (dink32-rom.o): Add build rule.
+ * config/powerpc/ppc-eabi.mt, config/powerpc/ppc-sim.mt
+ (TDEPFILES): Add dink32-rom.o.
+ * monitor.h (MO_32_REGS_PAIRED, MO_SETREG_INTERACTIVE,
+ MO_SETMEM_INTERACTIVE, MO_GETMEM_16_BOUNDARY,
+ MO_CLR_BREAK_1_BASED): New monitor interface flags.
+ * monitor.c: Use them.
+ (monitor_store_register): Use setreg.term if defined.
+ (monitor_insert_breakpoint, monitor_remove_breakpoint): Notice
+ if set_break and clr_break fields are empty.
+
+Mon Aug 11 16:22:36 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * ocd.c (ocd_insert_breakpoint, ocd_remove_breakpoint): Macro
+ BDM_BREAKPOINT already has braces around it, remove erroneous ones.
+ * ser-ocd.c (ocd_write): Conditionalize on _WIN32 instead of
+ __CYGWIN32__.
+ * config/powerpc/tm-ppc-eabi.h: Remove BDM_NUM_REGS, BDM_REGMAP
+ * ppc-bdm.c: move BDM_NUM_REGS, BDM_REGMAP here from tm.h file,
+ fill in doc fields of bdm_ppc_ops.
+ (bdm_ppc_fetch_registers): Don't ask for invalid registers such
+ as the MQ or floating point regs not present on ppc 8xx boards.
+ (bdm_ppc_store_registers): Don't write those same invalid registers.
+ * config/i386/cygwin32.mh: Stop including ocd.o ser-ocd.o.
+ * config/powerpc/ppc-eabi.mt:
+ * config/powerpc/ppcle-eabi.mt:
+ * config/powerpc/ppc-sim.mt:
+ * config/powerpc/ppcle-sim.mt: Include ser-ocd.o.
+
+Mon Aug 11 16:08:52 1997 Fred Fish <fnf@cygnus.com>
+
+ * frame.h (enum lval_type): Conditionalize on __GNUC__
+ instead of __STDC__.
+
+Sun Aug 10 19:08:26 1997 Jeffrey A Law (law@cygnus.com)
+
+ * utils.c (error): Fix return type for !ANSI_PROTOTYPES.
+
+Sun Aug 10 16:49:09 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * ocd.c: move ocd_write_bytes proto to ocd.h since it is used
+ by ppc-bdm.c, use OCD_LOG_FILE to help debugging, define
+ BDM_BREAKPOINT if not defined in tm.h
+ (ocd_error): add new error cases
+ (ocd_start_remote): send the OCD_INIT command before
+ OCD_AYT and OCD_GET_VERSION calls, 80 was correct speed after all
+ (ocd_write_bytes): no longer static
+ (ocd_insert_breakpoint): no longer static
+ (ocd_remove_breakpoint): new
+ * ocd.h: add protos for ocd_write_bytes, ocd_insert_breakpoint,
+ and ocd_remove_breakpoint
+ * ppc-bdm.c: change bdm_ppc_ops so we call ocd_insert_breakpoint
+ and ocd_remove_breakpoint instead of memory_insert_breakpoint
+ and memory_remove_breakpoint.
+ (bdm_ppc_open): after calling ocd_open, modify DER
+ register so interrupts will drop us into debugging mode, finally
+ disable the watchdog timer on the board so we don't leave BDM
+ mode unexpectedly.
+
+Sat Aug 9 01:50:14 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * values.c (value_primitive_field): Account for offset when
+ extracting the value of a bitfield.
+ From Paul Hilfinger <hilfingr@CS.Berkeley.EDU>.
+
+Fri Aug 8 21:35:44 1997 Mark Alexander <marka@cygnus.com>
+
+ * config/tic80/tic80.mt:
+ (GDBSERVER-DEPFILES, GDBSERVER_LIBS): Define for gdbserver.
+ (SIM): Remove -lm to prevent make errors.
+ * configure.tgt: add gdbserver to configdirs for tic80.
+ * gdbserver/utils.c (error): Change prototype to match defs.h.
+ * gdbserver/low-sim.c: Change simulator calls to use new interface.
+ * remote.c (remote_write_bytes): Include '$' at start of packet
+ and checksum at end of packet in overhead calculation.
+
+Fri Aug 8 15:59:24 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ser-ocd.c: If _WIN32, include <windows.h>.
+ (dll_do_command): New static variable if _WIN32.
+ (ocd_open): Set dll_do_command if _WIN32.
+ (ocd_write): Use dll_do_command rather than do_command.
+ * config/i386/cygwin32.mh (XDEPFILES): Remove libwigglers.a.
+ (BDM_DLLNAME, BDM_LIBNAME, BDM_DEFFILE): Don't define.
+ ($(BDM_LIBNAME)): Remove target.
+ * wigglers.def: Remove.
+
+ * config/i386/cygwin32.mh ($(BDM_LIBNAME)): Rename target from
+ libwigglers.def.
+ (libwigglers.a): Remove target.
+
+Fri Aug 8 13:11:01 1997 Mike Meissner <meissner@cygnus.com>
+
+ * config/powerpc/ppc{,le}-{eabi,sim}.mt (TDEPFILES): Make sure
+ ppc-bdm.o and ocd.o are used for all powerpc-eabi targets.
+
+Thu Aug 7 19:40:52 1997 Geoffrey Noer <noer@cygnus.com>
+
+ Changes to OCD support to support wiggler box as well as
+ target boxes:
+ * ocd.c: change speed in init command to 0 from 80,
+ add (temporary) logging commands to help debugging,
+ (ocd_open): if "target ocd wiggler lpt" then use special
+ ser-ocd.c serial interface which communicates with Wigglers.dll,
+ otherwise ("target ocd <foo>") do as we did before
+ (ocd_get_packet): add OCD_LOG_FILE and OCD_SET_CONNECTION to
+ switch of known commands of len 0
+ * ocd.h: add OCD_LOG_FILE
+ * serial.c (serial_open): do serial_interface_lookup on ocd
+ in the case of ocd
+ * ser-ocd.c: add buffer to contain responses from sending a
+ command to the Wigglers.dll.
+ (ocd_readchar): return curr char from buffer and increment ptr
+ (ocd_write): send buffer to Wigglers.dll, storing response in
+ return buffer and initializing curr location ptr to start of
+ buffer.
+
+Thu Aug 7 13:39:31 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * ocd.h: add OCD_SET_CONNECTION
+ * ocd.c: rename "do_command" to "ocd_do_command"
+
+Thu Aug 7 13:09:17 1997 Geoffrey Noer <noer@cygnus.com>
+
+ Nomenclature change. BDM is a specific type of OCD
+ (On Chip Debugging). Wiggler is the parallel port box controlled
+ by Wigglers.dll. The faster target box from Macraigor Systems
+ is not a wiggler.
+ * ocd.c:
+ * ocd.h:
+ * ppc-bdm.c:
+ * ser-ocd.c:
+ Replace all instances of "wiggler_" with "ocd_" and change most other
+ instances of "wiggler" to "ocd" or "ocd device" depending on context.
+ * config/m68k/monitor.mt: remove remote-wiggler.o from TDEPFILES
+ until OCD with that target is supported again.
+
+Wed Aug 6 16:15:31 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * Makefile.in: add DLLTOOL = @DLLTOOL@, pass on DLLTOOL to
+ sub makes, change clean rule to also remove *.a to remove
+ libwigglers.a, in dependencies: add ppc-bdm.o ocd.o ser-ocd.o and
+ remove remote-wiggler.o
+ * configure.in: add DLLTOOL support
+ * configure: regenerate
+ * wigglers.def: new file for imports for wigglers.dll
+ * ser-ocd.c: new file which is layer between ocd.c and either the
+ wigglers.dll or the target box, only stub so far
+ * config/powerpc/ppc-eabi.mt: add ppc-bdm.o to TDEPFILES
+ * config/powerpc/ppc-sim.mt: add ppc-bdm.o to TDEPFILES
+ * config/i386/cygwin32.mh: add ocd.o ser-ocd.o libwigglers.a
+ to XDEPFILES, add rules to build libwigglers.a
+
+ checking in changes of Stu Grossman <grossman@cygnus.com>:
+ * remote-wiggler.c: delete
+ * ocd.c: new, was remote-wiggler.c
+ always include sys/types.h, include ocd.h, move WIGGLER
+ commands and many wiggler prototypes to ocd.h, make wiggler_desc
+ static, stop making local wiggler functions static,
+ define write_mem_command for wiggler_write_bytes
+ (wiggler_start_remote): stop hardcoding the target type,
+ instead set and use a target_type variable.
+ (wiggler_open): add new target_type and ops args
+ (wiggler_wait): now no longer takes pid and target_status as args,
+ stop trying to set target_status struct, remove BGND insn
+ checks
+ (read_bdm_registers): renamed to wiggler_read_bdm_registers
+ (wiggler_read_bdm_registers): numregs arg changed to reglen arg,
+ remove pktlen check, set reglen instead of numregs
+ (dump_all_bdm_regs): delete
+ (wiggler_fetch_registers): delete
+ (wiggler_prepare_to_store): now just an empty function
+ (wiggler_store_registers): delete
+ (wiggler_read_bdm_register): new
+ (wiggler_write_bdm_registers): new
+ (wiggler_write_bdm_register): new
+ (wiggler_write_bytes): use write_mem_command variable instead of
+ WIGGLER_WRITE_MEM
+ (get_packet): renamed to wiggler_get_packet, change refs throughout
+ (put_packet): renamed to wiggler_put_packet, change refs throughout
+ (wiggler_get_packet): add break to default case of switch,
+ change length of WIGGLER_GET_VERSION len to 10 from 4 to match
+ specs
+ (wiggler_mourn): unpush_target with current_ops, not &wiggler_ops
+ (flash_xfer_memory): delete
+ (noop_store_registers): new placeholder replacement for
+ target_store_registers() which prevents generic_load from trying to
+ set up the PC.
+ (bdm_update_flash_command): add store_registers_tmp variable,
+ make handling of wiggler_ops more generic -- define wiggler_ops
+ in a target-specific file instead (such as ppc-bdm.c in the case
+ of the ppc), use current_target to deal with registers again
+ making this file less target-specific.
+ (bdm_read_register_command): new
+ (_initialize_remote_wiggler): stop doing add_target (&wiggler_ops),
+ comment out add_cmd ("read-register", ...)
+ * ocd.h: new, contains common wiggler prototypes, command definitions
+ * ppc-bdm.c: file for ppc-specific OCD code, including target_ops
+ structure for ppc bdm
+ (bdm_ppc_open): new
+ (bdm_ppc_wait): new
+ (bdm_ppc_fetch_registers): new
+ (bdm_ppc_store_registers_: new
+ (_initialize_bdm_ppc): new
+ * config/powerpc/tm-ppc-eabi.h: add necessary CPU32 BDM defines
+
+Tue Aug 5 23:56:14 1997 Mark Alexander <marka@cygnus.com>
+
+ * tic80-tdep.c (tic80_init_extra_frame_info): Allow zero
+ as a valid SP-relative offset of a saved register.
+
+Wed Aug 6 00:24:08 1997 Jeffrey A Law (law@cygnus.com)
+
+ * hpread.c (hpread_read_struct_type): Use accessor macros rather
+ than directly mucking around with data structures.
+
+Tue Aug 5 13:37:14 1997 Per Bothner <bothner@cygnus.com>
+
+ * gdbtypes.h: Re-interpret struct field. Suppport address of static.
+ Add a bunch of macros.
+ * coffread.c, dwarf2read.c, dwarfread.c, mdebugread.c, stabsread.c:
+ Update to use new macros.
+ * coffread.c, hpread.c, stabsread.c: Remove bugus TYPE_FIELD_VALUE.
+ * value.h, values.c (value_static_field): New function.
+ * cp-valprint.c, valops.c: Modify to use value_static_field.
+
+ * jv-lang.c (get_java_utf8_name): Re-write so it works with
+ implied (missing) data field, as defined by cc1java.
+ (java_link_class_type): Type length and field offset (in interior)
+ now includes object header. Get static fields working.
+ * jv-lang.h (JAVA_OBJECT_SIZE): Update for change in Kaffe.
+ * jv-typeprint.c (java_type_print_derivation_info,
+ java_type_print_base): New functions, for better Java output.
+ * jv-valprint.c: Start to support Java-specific output.
+
+Sun Aug 3 08:18:09 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * c-valprint.c (c_val_print): Use extract_address to retrieve
+ the address of the virtual function.
+ From Peter Bloecher (Peter.Bloecher@eedn.ericsson.se).
+
+ * eval.c (evaluate_subexp_standard), valarith.c (value_x_unop):
+ Handle C++ operator *.
+
+Fri Aug 1 15:21:44 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Check for cygwin32 environment. Define and
+ substitute WIN32LIBS and WIN32LDAPP. Always set configdir to
+ unix; setting it to win was for an old Tcl/Tk configuration
+ scheme.
+ * Makefile.in (TK_CFLAGS): Add @TK_BUILD_INCLUDES@.
+ (WIN32LDAPP, WIN32LIBS): Define.
+ (CLIBS): Add $(WIN32LIBS).
+ (gdb): Use $(WIN32LDAPP).
+ * configure: Rebuild.
+
+Thu Jul 31 15:40:19 1997 Per Bothner <bothner@cygnus.com>
+
+ * symtab.h (SYMBOL_INIT_LANGUAGE_SPECIFIC, SYMBOL_INIT_DEMANGLED_NAME,
+ SYMBOL_DEMANGLED_NAME): Add demangling support for Java.
+ * utils.c (fprintf_symbol_filtered): Handle language_java.
+
+ * symtab.c (decode_line_1): Handle Java-style package.class.method.
+
+Wed Jul 30 14:04:18 1997 Per Bothner <bothner@cygnus.com>
+
+ * java-*: Renamed to jv-*, to make fit within 14 characters.
+ * jv-lang.h (java_type_print): Added declaration.
+ * jv-typeprint.c: New file. Provides java_print_type.
+ * jv-lang.c (java_link_class_type): New function.
+ (java_language_defn): Replace c_print_type by java_print_type.
+ * Makefile.in: Update accordingly.
+
+Tue Jul 29 10:12:44 1997 Felix Lee <flee@cygnus.com>
+
+ * Makefile.in (init.c): except some mswin files do need to be
+ scanned. oh well.
+
+Mon Jul 28 14:04:39 1997 Felix Lee <flee@cygnus.com>
+
+ * Makefile.in (init.c): don't try to scan mswin for _initialize
+ funcs. (generates misleading error message because files have
+ .cpp suffix, not .c suffix)
+
+Mon Jul 28 13:27:21 1997 Felix Lee <flee@cygnus.com>
+
+ * ser-e7kpc.c: <w32sut.h> -> "mswin/w32sut.h"
+
+Mon Jul 28 02:54:31 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * xcoffread.c (coff_getfilename): Do not strip directory component
+ of filename.
+
+Fri Jul 25 15:16:15 1997 Felix Lee <flee@cygnus.com>
+
+ * mon960-rom.c: removed unused #includes; no ioctl.h in Windows.
+ * nindy-share/ttyflush.c: find sleep() for _MSC_VER.
+ * remote-array.c: #include <ctype.h> for isascii().
+ * utils.c (notice_quit,pollquit): cleanup. _WIN32 -> _MSC_VER.
+
+Fri Jul 25 16:48:18 1997 Jeffrey A Law (law@cygnus.com)
+
+ * top.c (execute_command): Force cleanup of alloca areas.
+ * findvar.c (registers_changed): Likewise.
+
+Fri Jul 25 15:37:15 1997 Stu Grossman <grossman@cygnus.com>
+
+ * v850ice.c: Include <windows.h>. Support new v850 DLL interface.
+ * Add defs for target status.
+
+Tue Jul 22 12:11:48 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * config/mips/tm-mips64.h: longs, long longs, and pointers
+ are all 64 bits on EABI mips targets.
+
+Thu Jul 17 11:38:46 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * partial-stab.h (case N_BINCL): detect missing partial symtab.
+ * dbxread.c: Add a complaint for N_BINCL without a corresponding
+ partial symtab. Remove earlier change of 5/27/97.
+
+Wed Jul 16 10:38:03 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * sol-thread.c (sol_thread_[store, fetch]_registers): if
+ inferior_pid is an LWP rather than a Solaris thread, let
+ procfs handle the request.
+ (rw_common, sol_thread_xfer_memory): procfs_xfer_memory will
+ only work if inferior_pid points to an LWP (rather than a
+ Solaris thread). Use procfs_first_available to find a good LWP.
+ (info_solthreads): added a maintenance command to list all
+ known Solaris threads and their attributes.
+ * mips-tdep.c (mips_do_registers_info): Completely changed the
+ output format to be neat and columnar. Added the helper funcs
+ do_fp_register_row and do_gp_register_row. Also small mods to
+ mips_print_register, which is still used to print a single reg.
+
+Mon Jul 14 18:02:53 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * procfs.c (wait_fd): Handle an fd that has "hung up" or
+ otherwise terminated (Solaris threads).
+
+Thu Jul 10 00:02:41 1997 Martin M. Hunt <hunt@cygnus.com>
+
+ * defs.h (init_ui_hook): Change prototype to accept one arg.
+ * main.c (gdb_init): Change prototype to accept one arg.
+ * top.c (gdb_init): Accepts one argument which it uses to
+ call (*init_ui_hook).
+
+Fri Jul 4 14:49:33 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * source.c (OPEN_MODE, FDOPEN_MODE): Define; value depends upon
+ whether CRLF_SOURCE_FILES is defined.
+ (open_source_file): Use OPEN_MODE with open and openp.
+ (print_source_lines): Use FDOPEN_MODE with fdopen. If
+ CRLF_SOURCE_FILES is defined, ignore \r characters.
+ (forward_search_command): Use FDOPEN_MODE with fdopen.
+ (reverse_search_command): Likewise.
+ * config/i386/xm-cygwin32.h (CRLF_SOURCE_FILES): Define.
+ (LSEEK_NOT_LINEAR): Don't define.
+
+Thu Jul 3 17:41:46 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * mips-tdep.c (mips_extract_return_value): align 4-byte float
+ return values within the 8-byte FP register.
+
+Thu Jul 3 13:48:11 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * mips-tdep.c (mips_push_arguments): don't left-adjust 32-bit
+ integers in 64-bit register parameters before function calls.
+
+Mon Jun 30 17:54:51 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * mips-tdep.c (mips_push_arguments): special-case handling for
+ odd-sized struct parameters passed in registers / on stack.
+
+Mon Jun 30 15:30:38 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * mips-tdep.c (mips_push_arguments): tweak alignment of small
+ structs passed in registers for little-endian non-EABI mode.
+
+Mon Jun 30 13:05:39 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * breakpoint.c (frame_in_dummy): use generic dummy if available.
+ (check_duplicates, clear_command): compare sections only if
+ doing overlay debugging.
+
+Fri Jun 27 23:03:53 1997 Fred Fish <fnf@ninemoons.com>
+
+ * buildsym.h (struct subfile): Add debugformat member.
+ (record_debugformat): Declare global function.
+ * buildsym.c (start_subfile): Initialize debugformat member
+ to NULL.
+ (record_debugformat): New function to record the format.
+ (end_symtab): Copy format into symtab debugformat member.
+ (end_symtab): Free subfile debugformat member.
+ * symmisc.c (free_symtab): Free debugformat when freeing
+ symtab.
+ * symfile.c (allocate_symtab): Initialize the new debugformat
+ member for new symtabs.
+ * symtab.h (struct symtab): Add debugformat member.
+ * source.c (source_info): Print the debug format.
+
+ * os9kread.c (os9k_process_one_symbol): Call record_debugformat
+ with "OS9".
+ * hpread.c (hpread_expand_symtab): Call record_debugformat
+ with "HP".
+ (hpread_process_one_debug_symbol): Ditto.
+ * dbxread.c (process_one_symbol): Call record_debugformat
+ with "stabs".
+ * coffread.c (coff_start_symtab): Call record_debugformat
+ with "COFF".
+ * xcoffread.c (read_xcoff_symtab): Call record_debugformat
+ with "XCOFF".
+ * dwarfread.c (read_file_scope): Call record_debugformat
+ with "DWARF 1".
+ * dwarf2read.c (read_file_scope): Call record_debugformat
+ with "DWARF 2".
+ * dstread.c (dst_end_symtab): Set debugformat to be
+ "Apollo DST".
+ * mdebugread.c (new_symtab): Set debugformat to be "ECOFF".
+
+Fri Jun 27 21:05:45 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * mips-tdep.c (mips_push_arguments): handle alignment of
+ integer and struct args on stack for mips64 big-endian.
+
+Fri Jun 27 19:19:12 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * config/mips/tm-mips.h (USE_STRUCT_CONVENTION): MIPS_EABI returns
+ structs in a register wherever possible.
+ * mips-tdep.c (mips_extract_return_value): handle structs.
+ (mips_store_return_value): handle values smaller than MIPS_REGSIZE
+ (including structs, if gdb ever allows it).
+
+Fri Jun 20 17:58:34 1997 Fred Fish <fnf@cygnus.com>
+
+ * sh-tdep.c (sh_skip_prologue): Also recognize fmov insns.
+ (sh_frame_find_saved_regs): Recognize fmov insns and adjust
+ stack push count accordingly.
+ * sh-tdep.c (IS_FMOV, FPSCR_SZ): New defines
+
+Thu Jun 19 08:18:48 1997 Mark Alexander <marka@cygnus.com>
+
+ * utils.c (floatformat_from_doublest): Improve test for infinity.
+
+Wed Jun 18 13:47:52 1997 Fred Fish <fnf@cygnus.com>
+
+ * dwarfread.c (isreg, optimized_out, offreg, basereg): Move
+ global variables into the struct dieinfo structure.
+ (locval): Pass pointer to a dieinfo struct rather than a
+ pointer to the raw location information. Change prototype.
+ Set isreg, optimized_out, offreg and basereg as appropriate.
+ (struct_type): Call locval with dieinfo struct pointer.
+ (new_symbol): Ditto.
+ (new_symbol): Call locval and save location before testing
+ the values of the new dieinfo struct flags, set by locval.
+
+Tue Jun 17 13:30:12 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * procfs.c (proc_set_exec_trap, procfs_init_inferior, procfs_wait,
+ unconditionally_kill_inferior): Undo Oct 26 1996 and Apr 26 1997
+ changes to trace PRFS_STOPTERM and handle PR_DEAD.
+ These changes tried to work around a problem with an early DU 4.0
+ release, but they trigger subtle timing dependent kernel bugs
+ in older OSF/1 releases.
+
+Tue Jun 17 06:52:47 1997 Fred Fish <fnf@cygnus.com>
+
+ * dwarfread.c (new_symbol): Use SYMBOL_VALUE_ADDRESS, instead of
+ SYMBOL_VALUE, to set the value of LOC_STATIC symbols.
+
+Mon Jun 16 18:38:28 1997 Mark Alexander <marka@cygnus.com>
+
+ * infrun.c (wait_for_inferior): Mark registers as invalid when
+ stepping over an instruction that triggered a watchpoint.
+ * remote-mips.c: Numerous changes to support hardware breakpoints
+ and watchpoints on LSI MiniRISC and TinyRISC boards.
+ * mips-tdep.c: Move MIPS16-related macros to config/mips/tm-mips.h.
+ (mips_breakpoint_from_pc): Account for different breakpoint
+ instructions used by PMON and IDT monitor.
+ * config/mips/tm-embed.h: Enable hardware breakpoints on embedded
+ MIPS targets.
+ * config/mips/tm-mips.h: Define breakpoint instructions for
+ PMON and IDT monitor. Move MIPS16-related macros here from
+ mips-tdep.c.
+
+Fri Jun 13 13:44:47 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * config/mips/tm-tx39[l].h, tx39[l].mt: change r3900 target to tx39.
+
+Fri Jun 13 14:14:10 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-tdep.c (mn10300_analyze_prologue): Fix some comments.
+ Add missing return statements after finding an "add imm{16,32},sp"
+ instruction.
+ (mn10300_frame_chain): Add in size of our register save area to find
+ our caller's frame if our caller does not have a frame pointer.
+
+Fri Jun 13 12:55:49 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * symfile.c (generic_load): Check return code of target_write_memory.
+
+Fri Jun 13 10:28:09 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/i386/nm-linux.h: Enable prototypes that were #ifdef out.
+ * config/tm-sysv4.h (in_plt_section): Add prototype.
+
+ * maint.c (maintenance_translate_address): Avoid assignment
+ inside if, per GNU coding standards.
+ * symfile.c (simple_read_overlay_table): Avoid assignments inside if,
+ per GNU coding standards.
+
+ * monitor.c (parse_register_dump): Is really a void function.
+ Add prototype.
+ (monitor_read_memory): Remove unused variable "name".
+ (monitor_read_memory): Remove unused variable "regbuf".
+ (monitor_open): Remove unused variable "i".
+ (get_hex_word): Apparently unused, #if away for now.
+ (from_hex): Ditto.
+
+ * i386v4-nat.c (supply_fpregset): Remove unused variable "regi".
+ (fill_fpregset): Remove unused variables "regi", "to", "from" and
+ "registers".
+
+ * remote-e7000.c (ctype.h): Include.
+ (e7000_insert_breakpoint): #if away unused arg used by unused expr.
+ * frame.h (generic_get_saved_register): Add prototype.
+ (enum lval_type): Add partial forward decl.
+ * dsrec.c (make_srec): Remove unused variable "type_code".
+ * remote-sim.c (gdbsim_wait): Handle sim_running and sim_polling
+ cases by just ignoring them.
+ (command.h): Include.
+
+ * java-exp.y (parse_number): Remove unused variable "unsigned_p".
+ * java-lang.c (gdbcore.h): Include for prototypes.
+ (type_from_class): Remove unused variable "ftype".
+ (type_from_class): Remove unused variable "name_length".
+ (evaluate_subexp_java): Add default case to handle remaining
+ enumerations.
+ * java-valprint.c (c-lang.h): Include for prototypes.
+
+ * symfile.c (simple_read_overlay_region_table): #if away
+ unused function.
+ (simple_free_overlay_region_table): Ditto.
+ (overlay_is_mapped): Add default case to switch.
+ (simple_read_overlay_region_table): Ditto.
+ (simple_read_overlay_region_table): Add prototype.
+
+ * symtab.c (fixup_symbol_section): Remove unused msym variable.
+ (fixup_psymbol_section): Ditto.
+ (find_pc_sect_symtab): Make distance a CORE_ADDR.
+
+ * utils.c: Add comment about t_addr being either unsigned long or
+ unsigned long long.
+ (paddr): Change formats to match actual types args are cast to.
+ (preg): Ditto.
+ (paddr_nz): Ditto.
+ (preg_nz): Ditto.
+
+ * defs.h (perror_with_name): Is a NORETURN function.
+ * utils.c (perror_with_name): Is a NORETURN function.
+ (error): Is NORETURN independently of ANSI_PROTOTYPES.
+
+ * symtab.c (fixup_symbol_section): Remove prototype.
+ * symtab.h: (fixup_symbol_section): Add prototype.
+ * m32r-rom.c (report_transfer_performance): Add prototype.
+ * sparclet-rom.c: Ditto.
+ * dsrec.c: Ditto.
+
+ * c-exp.y (parse_number): Cast args to float* or double* as
+ appropriate for conversion format.
+ * java-exp.y (parse_number): Ditto.
+
+ * Makefile.in (c-exp.tab.c): Remove #line lines that refer
+ to nonexistant y.tab.c file.
+ (java-exp.tab.c): Ditto.
+ (f-exp.tab.c): Ditto.
+ (m2-exp.tab.c): Ditto.
+
+ * sh-tdep.c (symfile.h): Include.
+ (gdb_string.h): Include.
+ (sh_fix_call_dummy): Ifdef away, currently unused.
+ * config/sh/tm-sh.h (pop_frame): Add prototype.
+ * config/sh/tm-sh.h (sh_set_processor_type): Add prototype.
+
+Sat Jun 7 02:34:19 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * eval.c (evaluate_subexp_for_sizeof): Handle dereferencing
+ of non-pointer values.
+
+ * symtab.c (gdb_mangle_name): Improve mangling of nested types,
+ their physical names already include the class name.
+
+ * valops.c (value_cast): Handle upcast of a class pointer.
+
+ From Andreas Schwab (schwab@issan.informatik.uni-dortmund.de):
+ * corelow.c (get_core_registers): Make secname big enough.
+
+Fri Jun 6 14:43:23 1997 Keith Seitz <keiths@pizza.cygnus.com>
+
+ * config/sh/tm-sh.h: add define for FPSCR_REGNUM
+ * sh-tdep.c (sh_show_regs): print out all registers for
+ the current processor
+
+Fri Jun 6 13:01:55 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_kill): Remove call to depreciated function
+ sim_kill.
+
+Thu Jun 5 11:39:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Fixes for recent correction to PE format:
+ * coffread.c (pe_file): New static variable.
+ (struct find_targ_sec_arg): Change resultp from pointer to int to
+ pointer to pointer to asection.
+ (find_targ_sec): Just store the section in args->resultp, not the
+ section offset value.
+ (cs_to_section): Compute the section offset value from the
+ section.
+ (cs_section_address): New static function.
+ (coff_symfile_read): Set pe_file.
+ (read_one_sym): When reading a PE file, adjust the symbol value to
+ include the section address if the symbol has an appropriate
+ storage class.
+
+Tue Jun 3 16:24:46 1997 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * configure.tgt: add mipsr3900-elf target
+ * config/mips/r3900.mt r3900l.mt tm-r3900.h tm-r3900l.h: ditto
+
+Tue May 27 10:34:11 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * dbxread.c: Check malloc's return for null, prevent segv.
+
+Fri May 23 14:45:02 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * infcmd.c (jump_command): Don't try to dereference sfn if it's
+ NULL.
+
+Fri May 23 13:51:57 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c (init_cmd_lists): Always initialize endianlist.
+ (init_main): Always define endian commands.
+ (set_endian_big): Issue warning if endian not selectable.
+ (set_endian_little): Ditto.
+ (set_endian_auto): Ditto.
+
+Thu May 22 11:53:21 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (simulator_command): Restrict access to the
+ simulator to periods when the simulator is open.
+
+Wed May 21 16:03:25 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * procfs.c (init_procinfo): new function, abstracts some code
+ shared by create_procinfo and do_attach;
+ (procfs_set_inferior_syscall_traps): new function, abstracts
+ some code needed by procfs_init_inferior, do_attach, and
+ procfs_lwp_creation_handler; (procfs_first_available): new
+ function, find any LWP that's runnable; (procfs_thread_alive):
+ replace stub function with real implementation;
+ (procfs_lwp_creation_handler): fix bug starting new child
+ threads; (info_proc): bug fixes and enhancements for the
+ "INFO PROCESSES" command; (close_procinfo_file): call new
+ function "delete_thread" to cleanup GDB's thread database;
+ (proc_init_failed): add new argument "kill", to control whether
+ process is killed (so this function can be shared by
+ create_procinfo and do_attach); (procfs_exit_handler): handle
+ exit from an attached process, and cleanup procinfo handles
+ when the process exits; (procfs_resume, procfs_wait): cleanup
+ after a thread when it exits; (do_attach, do_detach): handle
+ attached processes with multiple threads; plus some general
+ improvements in the diagnostic output.
+ * sol-thread.c (sol_thread_alive): replace stub with real
+ implementation; (thread_to_lwp, lwp_to_thread): enhance to
+ handle threads that may have exited; (sol_thread_attach): add
+ startup setup stuff; (sol_thread_detach): add unpush_target
+ call; (sol_thread_mourn_inferior): add unpush_target call;
+ (sol_thread_wait, sol_thread_resume): enhance to deal with
+ thread exit cleanly; (sol_thread_new_objfile,
+ sol_thread_pid_to_str): detect unsuccessful startup and
+ don't crash; plus some general cleanup.
+ * thread.c (delete_thread): new function, allows targets to
+ notify gdb when a thread is no longer valid.
+ * infrun.c (wait_for_inferior): don't try to detect a new
+ thread on receiving a TARGET_EXITED event.
+
+Tue May 20 09:32:02 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_open): Pass callback struct.
+ (init_callbacks): Remove call to sim_set_callbacks.
+
+Thu May 15 07:56:50 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/rs6000/tm-rs6000.h (SIG_FRAME_LR_OFFSET): Define.
+ * rs6000-tdep.c (frameless_function_invocation): Mark frames
+ with a zero PC as frameless to improve backtraces from core dumps
+ caused by dereferencing a NULL function pointer.
+ (frameless_function_invocation, frame_saved_pc, rs6000_frame_chain):
+ Handle frameless functions interrupted by a signal.
+
+ * sparc-tdep.c (sparc_init_extra_frame_info, sparc_frame_saved_pc):
+ Handle frameless functions interrupted by a signal.
+
+Wed May 14 08:58:55 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-tdep.c (mn10200_analyze_prologue): Update prologue comments
+ to reflect current reality. Gross attempt at handling out of
+ line prologues.
+
+ * mn10200-tdep.c (mn10200_skip_prologue): Don't look at the debug
+ symbols to find the end of the prologue.
+ * mn10300-tdep.c (mn10300_skip_prologue): Likewise.
+
+Wed May 14 12:04:49 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/tic80/tm-tic80.h (NUM_REGS): 38 not 37.
+
+Mon May 12 11:35:04 1997 Mark Alexander <marka@cygnus.com>
+
+ * tic80-tdep.c, config/tic80/tm-tic80.h: First cut at getting
+ basic C80 features working.
+
+Thu May 8 08:42:47 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (AC_TYPE_SIGNAL): Add
+ * configure: Re-generate.
+ * remote-sim.c: Signal returns RETSIGTYPE.
+
+Wed May 7 20:05:07 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * target.h (target_stop): Drop argument so it can be tested for
+ NULL.
+
+Sat May 3 20:51:48 1997 Mark Alexander <marka@cygnus.com>
+
+ * utils.c (floatformat_from_doublest): Handle infinity properly.
+
+Thu May 1 11:44:46 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * Finalize merge from Hurd folk.
+ Mon Oct 30 16:41:04 1995 Miles Bader <miles@gnu.ai.mit.edu>
+ * thread.c (thread_apply_command, thread_apply_all_command,
+ thread_command): Make sure TP is alive.
+ (thread_alive): New function.
+ Tue Nov 14 14:31:03 1995 Miles Bader <miles@gnu.ai.mit.edu>
+ * infrun.c (sig_print_info): Deal better with long signal names.
+ Wed Nov 22 15:23:35 1995 Miles Bader <miles@gnu.ai.mit.edu>
+ * thread.c (thread_id_to_pid): New function.
+ Fri Dec 1 13:25:25 1995 Miles Bader <miles@gnu.ai.mit.edu>
+ * gnu-nat.c: (set_thread_cmd_list, show_thread_cmd_list,
+ set_thread_default_cmd_list, show_thread_default_cmd_list):
+ New variables. (set_thread_cmd, show_thread_cmd,
+ set_thread_default_cmd, show_thread_default_cmd): New functions.
+ Fri Apr 18 15:20:16 1997 Miles Bader <miles@gnu.ai.mit.edu>
+ * gnu-nat.c (inf_startup): remove TASK parameter.
+ (inf_set_task): replace with new function (inf_set_pid).
+ * gdbthread.h: Add extern decl for thread_cmd_list.
+
+Thu May 1 02:28:21 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * printcmd.c (disassemble_command): Adjust low function bound
+ by FUNCTION_START_OFFSET.
+
+Wed Apr 30 15:23:02 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/tic80/tm-tic80.h (BREAKPOINT): Set it to trap 73.
+
+Mon Apr 28 21:25:32 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * Makefile.in: Add rule for gnu-nat.o and i386gnu-nat.o (Gnu Hurd)
+ * config/i386/i386gnu.mh: remove rules for [i386]gnu-nat.o, now
+ in Makefile.in (as for other targets); add NATDEPFILE corelow.o to
+ satisfy symbol dependancy in solib.c (core_ops).
+ * target.[ch] conditionalize Mach-specific signals so that they
+ won't show up in non-Mach gdb's!
+ * thread.c: change name of static function "thread_switch" to
+ "switch_to_thread", to avoid conflict with Mach global symbol;
+ move thread_cmd_list to global scope so targets can add their
+ own thread commands.
+ * infrun.c: sig_print_info: allow for long signal names.
+ * gnu-nat.[ch]: tidying up comments.
+ * gnu-nat.c: remove calls to prune_threads and renumber_threads;
+ gnu_wait must not return -1 when inferior exits;
+ attach_to_child will modify inferior_pid in a way that allows
+ fork_inferior to remain unchanged; remove extra arg from
+ startup_inferior; move Mach thread commands here from thread.c.
+
+Mon Apr 28 18:21:20 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * symtab.c: decode_line_1, replace the assignment to
+ values.sals[0].pc which I accidentally left out on 4/3/97.
+
+Mon Apr 28 17:27:40 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * c-exp.y: make parse_number reject "123DEADBEEF".
+ (fix by Bob Manson).
+ * java-exp.y: Ditto.
+ * top.c: change "to enable to enable" to "to enable" in a couple
+ of help strings.
+
+Mon Apr 28 09:01:59 1997 Mark Alexander <marka@cygnus.com>
+
+ * breakpoint.c (remove_breakpoint): Pass correct type to
+ target_remove_watchpoint.
+ * target.h: Improve comment for target_{remove,insert}_breakpoint.
+
+Sat Apr 26 03:38:02 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * alpha-tdep.c (heuristic_proc_desc): Increase search limit
+ for return address register, handle `ret' instruction.
+
+ * corelow.c (get_core_registers): Initialize cf.
+
+ * procfs.c: Minor changes to make pre-ANSI compilers happy.
+ (procfs_notice_signals): Copy traced signal set back to
+ pi->prrun.pr_trace.
+ (unconditionally_kill_inferior): If PR_DEAD is defined,
+ rerun inferior after killing it.
+
+Fri Apr 25 00:10:18 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/mn10300/tm-mn10300.h (EXTRACT_STRUCT_VALUE_ADDRESS): The
+ structure value address is found in $a0 now.
+ * config/mn10200/tm-mn10200.h (EXTRACT_STRUCT_VALUE_ADDRESS): Likewise.
+
+Thu Apr 24 13:31:10 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/mn10300/tm-mn10300.h (STORE_RETURN_VALUE): Pointers are
+ returned in $a0.
+ (EXTRACT_RETURN_VALUE): Likewise.
+
+ * mn10300-tdep.c (mn10300_analyze_prologue): Check for a return
+ insn at "pc", not "fi->pc".
+
+Thu Apr 24 16:11:47 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/tic80/tm-tic80.h (NUM_REGS): Four 64bit accumulators.
+ (REGISTER_BYTE, REGISTER_RAW_SIZE, REGISTER_SIZE,
+ MAX_REGISTER_RAW_SIZE, REGISTER_VIRTUAL_TYPE): Adjust.
+ (NPC_REGNUM): Tic80 has a delay slot.
+ (R0_REGNUM, Rn_REGNUM, An_REGNUM): For sim, provide base/bound for
+ register blocks.
+
+Wed Apr 23 11:18:45 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/mn10200/tm-mn10200.h (STORE_RETURN_VALUE): Pointers are
+ returned in $a0.
+ (EXTRACT_RETURN_VALUE): Likewise.
+
+Tue Apr 22 11:58:15 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/arm/tm-arm.h (TARGET_DOUBLE_FORMAT): Define to use
+ floatformat_ieee_double_littlebyte_bigword for little endian
+ target byte order.
+ * utils.c (floatformat_to_doublest): Create local preswapped
+ copy of input for floatformat_littlebyte_bigword formats.
+ (get_field, put_field): Treat floatformat_littlebyte_bigword
+ the same as floatformat_little.
+ (floatformat_from_doublest): Postswap output words for
+ the floatformat_littlebyte_bigwords format.
+
+Mon Apr 21 22:44:47 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/tic80/tic80.mt (SIM): Link in simulator.
+
+Tue Apr 22 09:02:10 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config/alpha/alpha-osf3.mh config/i386/{i386gnu linux}.mh
+ config/mips/{embed embed64 embedl embedl64 vr4300 vr4300el vr5000
+ vr5000el}.mt config/powerpc/{aix aix4}.mh config/rs6000/{aix
+ aix4}.mh config/sh/sh.mt config/sparc/sp64sim.mt:
+ config/v850/v850.mt:
+ Remove -lm. That's now handled by configure.
+
+ * Makefile.in (maintainer-clean): Add distclean to dependencies.
+ Remove duplicate rm's of files.
+
+Mon Apr 21 09:49:25 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * remote-pa.c: Remove. It's broken and no longer necessary.
+
+ Sat Apr 19 11:56:10 1997 Per Bothner <bothner@deneb.cygnus.com>
+
+ * java-exp.y: Combine TRUE and FALSE into BOOLEAN_LITERAL.
+ (Avoids name clash with broken AIX header files.)
+
+Sat Apr 19 01:49:37 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * serial.c (serial_log_command): Fix fputs_unfiltered calls.
+
+ * config/powerpc/tm-ppc-aix4.h, config/rs6000/tm-rs6000-aix4.h
+ (DONT_RELOCATE_SYMFILE_OBJFILE): Removed.
+ * xcoffsolib.h (struct vmap): Add new members tvma, toffs and dvma,
+ remove tadj.
+ * exec.c (bfdsec_to_vmap): Initialize new vmap members, initialize
+ tstart and dstart with section VMA.
+ * rs6000-nat.c (vmap_symtab): Relocate relative to the VMA in the
+ object file.
+ (vmap_ldinfo, xcoff_relocate_core): Adjust tstart by section offset
+ of the text section, remove DONT_RELOCATE_SYMFILE_OBJFILE hack.
+ (vmap_exec): Relocate relative to the VMA in the object file,
+ relocate .bss section as well.
+ (xcoff_relocate_core): No longer adjust section addresses by VMA.
+ * rs6000-tdep.c (find_toc_address): Change type of tocbase
+ to CORE_ADDR.
+ * xcoffread.c (secnum_to_bfd_section): New routine to get
+ BFD section from CS section number.
+ (scan_xcoff_symtab): Make toc_offset section relative.
+
+ * symtab.c (total_number_of_methods): Avoid core dump if
+ baseclass type is still undefined.
+
+Fri Apr 18 17:25:10 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (SUBDIRS): Add mswin so that make cleanup cleans up
+ that directory.
+ * defs.h utils.c (error warning): Make message be const.
+ * main.c (fputs_unfiltered): Only send gdb_stdout and gdb_stderr
+ to hook. Otherwise send it to fputs.
+ * monitor.c monitor.h (monitor_get_dev_name): New function. Does
+ the obvious.
+ * remote-e7000.c: Remove debugify stuff. Change printf, fprintf
+ to _filtered forms to make output appear in GUIs. Replace all
+ uses of SERIAL_READCHAR with readchar, which has better error
+ checking.
+ * (e7000_parse_device): Add prototype.
+ (readchar): Improve doc. Handle random serial errors.
+ (expect): Disable notice_quit code. It's busted. Remove
+ serial error handling (it's now handled in readchar). Remove
+ remote_debug echoing. That's handled in readchar as well.
+ (e7000_parse_device): Remove serial_flag arg. It's not
+ necessary.
+ (e7000_open): Split into two pieces. Second part is
+ e7000_start_remote, and is error protected. Now, when we connect
+ to the target, we setup the initial frame and registers so that
+ the user gets an immediate indication of where the target is.
+ (gch): Remove debug output. That's handled by readchar.
+ (e7000_read_inferior_memory): Handle errors better.
+ (_initialize_remote_e7000): Get rid of `<xxx>' things from
+ command names. They show up when doing completion and confuse
+ things horribly.
+ * ser-e7kpc.c: Get rid of the DLL's since we can access the device
+ directly from Win32s and Win95. Get rid of debugify crud.
+ * serial.c: Remove debugify cruft.
+ * (serial_logchar serial_log_command serial_write serial_readchar
+ serial_send_break serial_close): Merge common functionality into
+ serial_logchar. Clean up rest of routines.
+ * sparclet-rom.c: Disembowel. Leave only download routine.
+ Download routine now switches to remote target automatically.
+ * top.c (disconnect): Only define if SIGHUP is defined. Cleans
+ up MSVC/Win32 problem.
+ * utils.c (gdb_flush): Don't call hook unless it's for gdb_stdout
+ or gdb_stderr.
+ * config/sh/tm-sh.h: Define TARGET_SH for WinGDB.
+ * config/sparc/tm-sparclet.h: Remove override for prompt.
+
+Fri Apr 18 13:38:19 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * remote-sim.c (gdbsim_open): Only pass -E to sim_open if
+ TARGET_BYTE ORDER_SELECTABLE.
+
+Fri Apr 18 16:52:41 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (init_callbacks): Initialize poll_quit and magic
+ fields of gdb_callback.
+ (gdbsim_stop): Add gdbsim_stop to list of supported client
+ operations.
+ (gdbsim_wait, gdbsim_resume): Move call to sim_resume into
+ sim_wait where gdb is in a position to handle a long running
+ function.
+ (gdbsim_cntrl_c): New function. Wrap the sim_resume call in a
+ SIGINT handler.
+ (gdb_os_poll_quit): New function. Check for a quit pending on the
+ console.
+
+Thu Apr 17 14:30:04 1997 Per Bothner <bothner@deneb.cygnus.com>
+
+ * objfiles.c (allocate_objfile): Allow NULL bfd argument.
+ * defs.h (enum language): Add language_java.
+ * java-exp.y, java-lang.c, java-lang.h, java-valprint.c: New files.
+ * Makefile.in: Update for new files.
+ * symfile.c (deduce_language_from_filename): Recognize .java.
+
+Thu Apr 17 02:20:23 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * m32r-stub.c (stash_registers): Rewrite.
+ (restore_registers): Renamed to restore_and_return.
+ (cleanup_stash): New function.
+ (process_exception): New function.
+ (_catchException*): Rewrite.
+
+ * remote-sim.c (gdbsim_load): Update call to sim_load.
+ (gdbsim_create_inferior): No longer pass start_address to
+ sim_create_inferior.
+ (gdbsim_open): Pass endian indicator as arg.
+
+Tue Apr 15 15:31:09 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.c (get_offsets): Don't use scanf for interpreting
+ response to qOffsets.
+
+Tue Apr 15 14:51:04 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gdbserver/Makefile.in (INSTALL_XFORM): Remove.
+ (INSTALL_XFORM1): Remove.
+ (install-only): Use $(program_transform_name) directly, rather
+ than using $(INSTALL_XFORM) and $(INSTALL_XFORM1).
+ (uninstall): Transform name.
+
+Mon Apr 14 17:06:27 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c (mips_load): Ensure that PC gets updated
+ after a load on LSI target.
+
+Mon Apr 14 15:54:51 1997 Geoffrey Noer <noer@pizza.cygnus.com>
+
+ * procfs.c (notice_signals): fix typo
+
+Mon Apr 14 16:25:10 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gdbserver/Makefile.in (INSTALL): Change install.sh to
+ install-sh.
+
+Mon Apr 14 11:55:27 1997 Geoffrey Noer <noer@pizza.cygnus.com>
+
+ * config/i386/cygwin32.mh: remove -lkernel32 from XM_CLIBS
+ since gcc automatically includes it
+
+Thu Apr 10 13:20:53 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * procfs.c: Substantial (but incomplete) changes to support
+ sysv4.2mp procfs as implemented in UnixWare 2.1. The procinfo
+ struct now has substructs like struct flt_ctl instead of
+ just a fltset_t and has a ctl_fd, status_fd, as_fd, and
+ map_fd instead of a single fd. Non-sysv4.2mp procfs models
+ still have the structs and multiple fds, but don't use the
+ entire struct and the four fds all point to the same thing.
+ We use PROCFS_USE_READ_WRITE to decide whether to talk to
+ procfs with reads/writes or use ioctl instead. We use
+ HAVE_MULTIPLE_PROC_FDS to determine whether procfs really has
+ multiple fds or not. PROC_NAME_FMT is split out into
+ CTL_PROC_NAME_FMT, AS_PROC_NAME_FMT, MAP_PROC_NAME_FMT,
+ STATUS_PROC_NAME_FMT.
+
+ (procfs_notice_signals): now a necessary wrapper around
+ (notice_signals): which are the new guts for noticing signals
+ (open_proc_file): gets a new flag arg used in sysv4.2mp to
+ determine whether or not to attempt to open the ctl_fd.
+ (procfs_read_status): new local function, reads procfs status
+ (procfs_write_pcwstop): new local function, writes a PCWSTOP
+ (procfs_write_pckill): new local function, writes a PCKILL
+ (unconditionally_kill_inferior): remove signo since we now
+ just call procfs_write_pckill().
+ (procfs_xfer_memory): call lseek with SEEK_SET rather than 0
+ (proc_iterate_over_mappings): the whole function is ifdefed
+ on UNIXWARE to keep things readable.
+
+ Expanded the syscall_table to include new potential sysv4.2mp
+ members. Note that all ifdefs of UNIXWARE should be eliminated
+ if possible or renamed to describe what's being selected for a
+ bit better. Sysv4.2mp and IRIX both have SYS_sproc so the
+ IRIX specific code now also checks it's not UNIXWARE.
+
+ * config/i386/tm-i386v42mp.h: also define HAVE_PSTATUS_T,
+ HAVE_NO_PRRUN_T, PROCFS_USE_READ_WRITE, and UNIXWARE
+ * config/mips/nm-irix4.h: set CTL_PROC_NAME_FMT et al to
+ "/debug/%d" as PROC_NAME_FMT used to be
+
+Wed Apr 9 11:36:14 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-tdep.c: Almost completely rewritten based on mn10200
+ port.
+ * config/mn10300/tm-mn10300.h: Likewise.
+
+Tue Apr 8 10:45:24 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config/pa/{hppabsd.mt hppahpux.mt hppaosf.mt}: Remove
+ remote-pa.o from TDEPFILES. Nobody uses it, and besides, it's a
+ lousy out-of-date clone of remote.c.
+
+Fri Apr 4 08:21:21 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * remote.c: Fix problems realized while showering.
+ * (hexnumlen): Add prototype. Use max, not min.
+ * (remote_write_bytes remote_read_bytes): Fix max packet size
+ calculations to properly account for packet overhead. Also handle
+ (probably rare) case where remote_register_buf_size isn't set.
+
+ * remote.c: Fix doc for `C' and `S' commands to indicate full
+ address.
+ * (remote_ops extended_remote_ops remote_desc remote_write_size):
+ Make static.
+ * (remote_fetch_registers remote_write_bytes remote_read_bytes):
+ Record size of response to fetch registers command, use this to
+ limit size of memory read and write commands.
+ * (push_remote_target): New function to make it possible to have
+ another target switch to the remote target.
+ * target.h: Add prototype for push_remote_target.
+ * sh-tdep.c (sh_frame_find_saved_regs): Fix sign extension bugs
+ for hosts which default to unsigned chars (such as SGI's).
+ * (_initialize_sh_tdep): Don't set remote_write_size. It's now
+ handled automatically in remote.c.
+
+Thu Apr 3 15:10:30 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * blockframe.c: blockvector_for_pc_sect(), block_for_pc_sect(),
+ find_pc_sect_function(), find_pc_sect_partial_function(): new
+ functions for debugging overlays; pc without section is ambiguous.
+ * breakpoint.[ch]: add section pointer to breakpoint struct;
+ add section argument to check_duplicates(); check section as well
+ as pc in [breakpoint_here_p(), breakpoint_inserted_here_p(),
+ breakpoint_thread_match(), bpstat_stop_status()];
+ add section argument to describe_other_breakpoints();
+ use INIT_SAL() macro to zero-out new sal structures;
+ make resolve_sal_pc() fix up the sal's section as well as its pc;
+ match on section + pc in clear_command() and delete_breakpoint();
+ account for overlay sections in insert_breakpoints(),
+ remove_breakpoint() and breakpoint_re_set_one();
+ all this to support overlays where a PC is not unique.
+ * exec.c: change xfer_memory() to handle overlay sections.
+ * findvar.c: change read_var_value() to handle overlay sections.
+ * frame.h: declaration for block_for_pc_sect() [blockframe.c].
+ * infcmd.c: jump_command() warns against jumping into an overlay
+ that's not in memory. Also use INIT_SAL() to initialize sals.
+ * infrun.c: wait_for_inferior() sets a flag to invalidate cached
+ overlay state information; Also use INIT_SAL() to init sals.
+ * m32r-rom.c: modify load routines to use LMA instead of VMA.
+ * m32r-stub.c: mask exit value down to 8 bits; screen out any
+ memory read/writes in the range 600000 to a00000, and ff680000
+ to ff800000 (hangs because nothing is mapped there); fix strcpy().
+ * maint.c: maintenance command "translate-address" supports overlays.
+ * minsyms.c: lookup_minimal_symbol_by_pc_sect() supports overlays.
+ * objfiles.[ch]: add ovly_mapped field to the obj_section struct;
+ this constitutes gdb's internal overlay mapping table. Add macro
+ ALL_OBJSECTIONS() to loop thru the obj_structs and look at overlays.
+ Add function find_pc_sect_section().
+ * printcmd.c: modify print_address_symbolic() with overlay smarts;
+ modify address_info() with overlay smarts; add function sym_info()
+ to support the INFO SYMBOL command (translate address to symbol(s));
+ modify disassemble_command() to work on unmapped overlays.
+ * source.c: use INIT_SAL() to initialize sals.
+ * symfile.[ch]: change generic_load() to use section's LMA address
+ instead of VMA address, for overlay sections.
+ Add numerous functions for finding a PC's section / overlay,
+ translating between VMA and LMA address ranges, determining if an
+ overlay section is mapped, etc. Add several user commands for
+ overlay debugging. Add support for a "generic" form of automatically
+ reading overlay mapping info from the inferior (based on the default
+ (simple) overlay manager which Cygnus provides as an example).
+ * symtab.[ch]: add functions find_pc_sect_symtab(),
+ find_pc_sect_psymtab(), find_pc_sect_psymbol(), find_pc_sect_line()
+ for lookup; modify lookup_symbol and decode_line_1() to use them;
+ modify find_function_start_sal() to account for overlay sections;
+ add macro INIT_SAL() for initializing struct symtab_and_line.
+ * target.c: fix a comment in the declaration of target_ops.
+
+Thu Apr 3 10:31:12 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mips_in_call_stub, mips_in_return_stub,
+ mips_skip_stub, mips_ignore_helper): New functions for dealing
+ with MIPS16 call/return thunks.
+ (mips_init_frame_pc_first): New function to implement
+ INIT_FRAME_PC_FIRST macro; includes code from old macro plus
+ new code to skip over MIPS16 thunks.
+ (mips_frame_chain): Skip over MIPS16 thunks.
+ * config/mips/tm-mips.h (mips_in_call_stub, mips_in_return_stub,
+ mips_skip_stub, mips_ignore_helper): Declare.
+ (IN_SOLIB_CALL_TRAMPOLINE, IN_SOLIB_RETURN_TRAMPOLINE,
+ SKIP_TRAMPOLINE_CODE, IGNORE_HELPER_CALL): New macros that invoke
+ the above functions.
+ (INIT_FRAME_PC_FIRST): Change to invoke mips_init_frame_pc.
+ (mips_init_frame_pc): Declare.
+ * infrun.c (wait_for_inferior): Use new IGNORE_HELPER_CALL macro
+ to decide if certain library function calls should be ignored.
+
+Wed Apr 2 14:16:51 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * remote-sim.c (gdbsim_open): Check return code from sim_open.
+ Update call to sim_open (new arg SIM_OPEN_DEBUG).
+
+Mon Mar 31 14:55:53 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gdbinit.in: New file.
+ * .gdbinit: Remove.
+ * configure.in: Generate .gdbinit from gdbinit.in.
+ * configure: Rebuild.
+
+Sun Mar 30 12:28:24 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tic80/tic80.mt: Disable using the simulator
+ until it is ready.
+
+Sat Mar 29 13:57:20 1997 Fred Fish <fnf@cygnus.com>
+
+ * COPYING: Install new version of file from FSF.
+ * copying.c (show_copying_command): Update FSF address.
+
+Fri Mar 28 18:33:41 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (distclean): Remove .gdbinit.
+
+Fri Mar 28 15:37:30 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tic80/tm-tic80.h (NAMES_HAVE_UNDERSCORE): Define.
+
+Fri Mar 28 15:38:04 1997 Mike Meissner <meissner@cygnus.com>
+
+ * remote-sim.c (gdb_os_{,e}vprintf_filtered): Change stdarg type
+ to va_list from void *, since va_list might not be a pointer
+ type.
+
+Thu Mar 27 14:21:46 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c: Clean up comment and extraneous semicolon
+ for mips_monitor_prompt variable.
+
+Thu Mar 27 12:46:58 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c: Add `set monitor-prompt' command.
+
+Wed Mar 26 06:47:44 1997 Mark Alexander <marka@cygnus.com>
+
+ Fix from Peter Schauer:
+ * mdebugread.c (parse_procedure): Set address of procedure to
+ block start; this fixes problems with shared libraries introduced
+ by change of Mar 21.
+
+Mon Mar 24 19:43:16 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * symtab.c (find_pc_symtab): change to support the case
+ where the objfile is reordered and contains both coff and
+ stabs debugging info (continue on if a psymtab isn't found).
+
+Sun Mar 23 16:19:20 1997 Mark Alexander <marka@cygnus.com>
+
+ Fixes from Peter Schauer:
+ * config/mips/tm-mips.h (REGISTER_CONVERT_TO_TYPE,
+ REGISTER_CONVERT_FROM_TYPE): Swap words if target, not host,
+ is big-endian and if registers are 32 bits.
+ * mips-tdep.c (mips_print_register, mips_extract_return_value,
+ mips_store_return_value): Fix floating-point word-order problems on
+ little-endian targets introduced by changes of Mar 21.
+
+Sun Mar 23 15:43:27 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.c (target_resume_hook, target_wait_loop_hook): New
+ globals.
+ (remote_resume, remote_wait): Use them.
+ * d10v-tdep.c: Set the above hooks.
+ (tracesource): New GDB variable, controls source display in
+ traces.
+ (display_trace): Find and display source line if requested.
+ (trace_info): Mention empty trace buffer if appropriate.
+ (tdisassemble_command): Robustify argument handling.
+
+ * configure.host: Remove extra bogus Linux case.
+
+Sat Mar 22 16:41:35 1997 Fred Fish <fnf@cygnus.com>
+
+ * remote-sim.c (simulator_command): Add comment about dealing with
+ NULL or empty args.
+ * Makefile.in (tic80-tdep.o): Add target.
+ * configure.tgt: Add tic80 case.
+ * tic80-tdep.c: New file.
+ * config/tic80/{tic80.mt, tm-tic80.h}: New files.
+
+Sat Mar 22 02:48:11 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * c-exp.y (yylex): Handle nested template parameter lists.
+ * symtab.c (decode_line_2): Fix test for valid choice number.
+
+Fri Mar 21 19:10:05 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mips_push_arguments): On non-EABI architectures,
+ copy first two floating point arguments to general registers, so that
+ MIPS16 functions will receive the arguments correctly.
+ (mips_print_register): Print double registers correctly on
+ little-endian hosts.
+ (mips_extract_return_value): Return double values correctly
+ on little-endian hosts.
+
+ * mdebugread.c (parse_procedure): Adjust address of procedure relative
+ to address in file descriptor record; this accounts for constant
+ strings that may precede functions in the text section. Remove
+ now-useless lowest_pdr_addr from argument list and all calls.
+
+Fri Mar 21 15:36:25 1997 Michael Meissner <meissner@cygnus.com>
+
+ * configure.tgt (powerpc*-{eabi,linux,sysv,elf}*): Determine
+ whether the simulator will be built by whether the Makefile in the
+ simulator directory was built.
+
+ * configure.in (--enable-sim-powerpc): Delete switch.
+ * configure: Regenerate.
+
+Thu Mar 20 20:52:04 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-tdep.c (mn10200_analyze_prologue): Look for save of "a1"
+ in the prologue too.
+
+ * remote-sim.c (gdb_os_vprintf_filtered): Fix to work with non-ANSI
+ compilers.
+ (gdb_os_evprintf_filtered): Similarly.
+
+Wed Mar 19 16:13:22 1997 Geoffrey Noer <noer@pizza.cygnus.com>
+
+ New UnixWare 2.1 configuration
+ * config/i386/i386v42mp.mt: new
+ * config/i386/i386v42mp.mh: new
+ * config/i386/tm-i386v42mp.h: new
+ * config/i386/nm-i386v42mp.h: new
+ * configure.tgt: added new entries
+ * configure.host: added new entries
+
+Mon Mar 17 17:52:00 1997 J.T. Conklin <jtc@cygnus.com>
+
+ * dsrec.c (load_srec): Print leading zeroes when printing section
+ addresses.
+
+Mon Mar 17 15:00:16 1997 Andrew Cagney <cagney@kremvax.cygnus.com>
+
+ * remote-sim.h: Delete - moved to ../include/remote-sim.h.
+
+ * Makefile.in (remote_utils_h): Update path to remote-sim.h.
+
+Fri Mar 7 20:55:28 1997 Andrew Cagney <cagney@kremvax.cygnus.com>
+
+ * remote-sim.c (flush_stdout, write_stderr, flush_stderr,
+ vprintf_filtered, evprintf_filtered): Callbacks that accept
+ varargs.
+
+Sat Mar 15 00:50:46 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * breakpoint.c (insert_breakpoints, watchpoint_check,
+ bpstat_stop_status): Do not disable watchpoints going out of scope.
+ (insert_breakpoints): Make sure that the current frame is valid
+ before calling find_frame_addr_in_frame_chain.
+
+ * top.c (setup_user_args): Handle quotes and backslashes.
+ (print_gdb_version): Update copyright year.
+
+Fri Mar 14 15:44:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (elfread.o): Depend upon elf-bfd.h and elf/mips.h.
+
+Thu Mar 13 22:51:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * utils.c (pollquit, notice_quit): If _WIN32, limit test for
+ cntl-C to wingdb.
+ (initialize_utils): If _WIN32, don't call ScreenRows and ScreenCols
+ except under wingdb. (Contributed by Martin Hunt).
+
+Thu Mar 13 12:40:49 1997 Tom Tromey <tromey@cygnus.com>
+
+ * configure: Regenerated.
+ * configure.in: Run AC_CONFIG_AUX_DIR before AC_CANONICAL_SYSTEM.
+
+Thu Mar 13 11:00:22 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * remote-sim.h (sim_state, SIM_DESC): New types.
+ (sim_open): Return a `descriptor' as result.
+ (*): New argument of descriptor result from sim_open.
+ * remote-sim.c (gdbsim_desc): Renamed from gdbsim_open_p.
+ (gdbsim_open): Record result of sim_open in gdbsim_desc.
+ Pass argv list to sim_open, argv[0] = pseudo program name.
+ (*): Pass gdbsim_desc to sim_foo fns.
+
+Wed Mar 12 14:40:06 1997 Tom Tromey <tromey@cygnus.com>
+
+ * config.in: Regenerated.
+
+ * acconfig.h (START_INFERIOR_TRAPS_EXPECTED, sys_quotactl,
+ HAVE_HPUX_THREAD_SUPPORT): Define.
+
+Tue Mar 11 07:25:27 1997 Mark Alexander <marka@cygnus.com>
+
+ First cut at supporting simulators in gdbserver:
+
+ * configure, configure.in: Allow gdbserver to be configured
+ for cross-target environments.
+ * gdbserver/Makefile.in: Add simulator support.
+ * gdbserver/configure.in: Eliminate assumption that host == target.
+ Simplify using gdb/configure.tgt and gdb/configure.host.
+ Fix other minor configuration errors.
+ * gdbserver/low-sparc.c: Fix compile error.
+ * gdbserver/remote-utils.c: Eliminate assumption that registers
+ and addresses are four bytes. Fix minor compile errors and warnings.
+ * gdbserver/server.c: Rewrite numerous instances of identical code
+ for starting inferior processes to call new function start_inferior.
+ Eliminate assumption that registers and addresses are four bytes.
+ * gdbserver/server.h: Add missing prototypes to eliminate compiler
+ warnings.
+ * gdbserver/low-sim.c: New file to mate gdbserver with simulators.
+ * config/mips/vr5000.mt: Add Vr5000 simulator support to gdbserver.
+ * config/i386/linux.mh: Eliminate gdbserver support as a first step
+ in moving such support from host to target makefile fragments.
+ * config/i386/linux.mt: Move gdbserver support here from linux.mh.
+
+Mon Mar 10 12:27:47 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * symtab.h (INIT_SAL): New macro to initialize symtab_and_line,
+ to insure consistant initialization of unused fields to zero.
+ * symtab.c: replace initializations of sals with new macro INIT_SAL.
+ * breakpoint.c: ditto.
+ * infrun.c: ditto.
+ * infcmd.c: ditto.
+ * source.c: add call to INIT_SAL macro.
+
+Sat Mar 8 00:16:37 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * sparc-tdep.c (isbranch): Always handle v9 branch instructions,
+ they might get used on 32 bit targets as well.
+
+Wed Mar 5 19:34:09 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * remote-mips.c (mips_exit_debug): Some IDT boards don't
+ send the full exit string.
+
+Wed Mar 5 12:59:27 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-tdep.c (mn10200_push_arguments): Handle new calling
+ conventions.
+ (mn10200_store_struct_return): Likewise.
+
+Tue Mar 4 10:31:02 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mips_fetch_instruction): New function; replace
+ common code throughout with calls to it.
+ (mips_find_saved_regs): Examine MIPS16 entry instruction to determine
+ correct saved addresses of $s0 and $s1.
+ (mips_find_saved_regs, mips16_heuristic_proc_desc): Use MIPS_REGSIZE
+ instead of hardcoded 4.
+ (mips16_skip_prologue): Handle extended instructions correctly.
+
+Mon Mar 3 12:29:20 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * defs.h (LONGEST): Move #ifndef LONGEST to outside.
+ Try BFD_HOST_64_BIT if ! CC_HAS_LONG_LONG.
+
+Thu Feb 27 18:54:11 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (IS_MIPS16_ADDR, MAKE_MIPS16_ADDR, UNMAKE_MIPS16_ADDR):
+ New macros for testing, setting, and clearing bit 0 of addresses.
+ Change numerous bits of code where bit 0 was being manipulated
+ to use these macros.
+
+Thu Feb 27 14:12:41 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c: Put back the form feeds.
+
+Thu Feb 27 12:04:24 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c: Remove form feeds (^L) from source.
+ (mips_initialize): LSI PMON doesn't support 'set regsize' command.
+ (pmon_wait): Don't need to exit and re-enter debug mode on LSI
+ PMON after a continue; it causes target program misbehavior.
+ (mips_fetch_register): Don't fetch unsupported registers; this
+ cuts down on wasted serial traffic.
+
+Thu Feb 27 09:38:16 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure.in configure (HPUX/OSF thread support): Enable this
+ only when running GCC, since HP's thread header files use ANSI C
+ which is not supported by their default compiler.
+
+ * configure.host (i[3456]86-*-windows): Disable long long
+ support for WinGDB. Add mswin to configdirs.
+ * configure.in configure: Move calls to configure.host and
+ configure.tgt to the top of configure.in to allow them to set
+ config variables before they are referenced.
+
+Tue Feb 25 20:21:52 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.tgt (mips*-*-lnews*): New target.
+
+Mon Feb 24 16:35:00 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-tdep.c (mn10200_analyze_prologue): Don't fix fi->frame
+ if we're not the innermost frame. Fix minor typos.
+
+Sat Feb 22 03:39:50 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * stabsread.c (read_type): Fix handling of template names
+ with template parameters containing `::'.
+
+ * valops.c (search_struct_field, search_struct_method):
+ Pass correct valaddr parameter to baseclass_offset.
+ Prevent gdb crashes by making sure that the virtual base pointer
+ from an user object still points to accessible memory.
+
+Tue Feb 18 13:36:34 1997 Mark Alexander <marka@cygnus.com>
+
+ * maint.c: Eliminate -Wall warnings by including some header files.
+
+Tue Feb 18 13:06:30 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-sim.c (init_callbacks): Undo previous change.
+
+Tue Feb 18 11:13:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * maint.c: Fix dereference of pointer.
+ * remote-sim.c: Fix reference of structure member "last_error".
+ * debugify.c: Include config.h to get ANSI definitions.
+
+Sat Feb 15 17:43:46 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * remote-vx.c (vx_attach): Remove code added by kung. It made no
+ sense.
+
+Fri Feb 14 13:00:07 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * main.c (print_gdb_help): Make static to match declaration.
+
+Thu Feb 13 18:18:18 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * remote-e7000.c, ser-e7kpc.c, serial.c: Remove // comments.
+
+Wed Feb 12 15:58:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * debugify.c, debugify.h: Make safe for non-ansi compilers.
+
+Wed Feb 12 15:30:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * defs.h: Fix prototypes for new cleanup functions.
+
+Wed Feb 12 15:08:47 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * debugify.c, debugify.h: Fix for general gnu use. Remove C++
+ comment, add PARAMS, add license info and fix indentation.
+
+Wed Feb 12 14:42:47 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * debugify.c, debugify.h: New files. Provide common macros
+ for writing debug info to a log file or stdio.
+
+Wed Feb 12 02:44:39 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * c-valprint.c (c_val_print): Fix printing for arrays defined
+ with 0 length.
+
+Tue Feb 11 22:24:39 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * defs.h: Fix cntl-C to read from the Windows message queue.
+ Add prototypes for make_final_cleanup (and the other cleanup
+ routines.
+ * remote-e7000.c: Fix sync code to timeout if unable to sync.
+ Change sync code to report status while trying to sync-up
+ with hardware. Add debugging output and document.
+ * ser-e7kpc.c: Swap order of len & offset to match implementation.
+ Add debugging output and document.
+ * serial.c: Add debugging output.
+ * top.c: Add call to do_final_cleanups.
+ Remove conditionals preventing Win32 from getting SIGQUIT.
+ * utils.c: (*_cleanup): Modify cleanup routines to accept a cleanup
+ chain as a parameter. Extract this generic code from the cleanup
+ routines into separate funtions (*_my_cleanup). Keep old
+ functionality by passing "cleanup_chain" to the new funtions.
+ Define the cleanup chain "final_cleanup_chain" to be a cleanup
+ chain which will be executed only when gdb exits. Add functions
+ (*_final_cleanup) to match the original (*_cleanup) functions.
+ (pollquit, quit, notice_quit): Fix to read cntl-C from the
+ Windows message queue.
+
+Tue Feb 11 15:36:31 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * m32r-rom.c: #include <sys/types.h>.
+ #ifdef out new load support if wingdb.
+ * m32r/tm-m32r.h (TARGET_M32R): Define, for wingdb.
+
+Tue Feb 11 12:28:09 1997 Jeffrey A Law (law@cygnus.com)
+
+
+ * config/mn10200/tm-mn10200.h (STORE_STRUCT_RETURN): Fix.
+ * mn10200-tdep.c (mn10200_store_struct_return): New function.
+
+ * config/mn10200/tm-mn10200.h (EXTRACT_RETURN_VALUE): Fix case when
+ extracting a return value from a register pair.
+
+ * mn10200-tdep.c (mn10200_push_arguments): Stack only needs to
+ be two byte aligned. Round argument sizes up to two byte boundary.
+ Write out args in two byte hunks.
+ (mn10200_push_return_address): Implement.
+ * config/mn10200/tm-mn10200.h (EXTRACT_RETURN_VALUE): Abort for
+ structures > 8 bytes (temporary).
+ (STORE_RETURN_VALUE): Likewise.
+ (CALL_DUMMY): No longer undefine.
+ (USE_STRUCT_CONVENTION): Use for args > 8 bytes.
+ (REG_STRUCT_HAS_ADDR): Define.
+
+Mon Feb 10 18:35:55 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (non_heuristic_proc_desc): New function.
+ (find_proc_desc): Move non-heuristic proc search code into separate
+ function.
+ (gdb_print_insn_mips): Use non-heuristic method to find procedure
+ descriptor, to avoid prologue examination when disassembling.
+ * remote-mips.c: Add support for new "lsi" target (LSI MiniRISC
+ aka MicroMeteor board).
+ (mips_exit_debug): Prevent protocol reinitialization if an error
+ occurs while exiting debug mode.
+
+Mon Feb 10 16:11:57 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-tdep.c: Remove lots of debugging printfs, update/improve
+ comments, formatting, etc. Plus other minor fixes for problems
+ I found during my first pass over the mn10200 port.
+ (mn10200_analyze_prologue): New function.
+ (mn10200_frame_chain, mn10200_init_extra_frame_info): Use it.
+ * config/mn10200/tm-mn10200.h: Lots of updates/improvements to
+ comments, formatting, etc. Minor fixes for problems I found during
+ my first pass over the mn10200 port.
+ (TARGET_*_BIT): Define appropriately for ints, long longs, doubles and
+ pointers.
+ (REGISTER_VIRTUAL_TYPE): Define as a long.
+ (EXTRACT_RETURN_VALUE): Rework to deal with long ints living
+ in register pairs.
+ (STORE_RETURN_VALUE): Similarly.
+
+ * blockframe.c (generic_get_saved_regs): Remove unused variable
+ "addr".
+ * breakpoint.c (frame_in_dummy): Move struct breakpoint *b decl
+ inside #ifdef CALL_DUMMY.
+ (watch_command_1): Initialize target_resources_ok.
+ * command.c (do_setshow_command): Provide dummy initialization
+ for "match".
+ * valops.c (find_function_addr): Move function & prototype inside
+ #ifdef CALL_DUMMY.
+ (value_arg_coerce): Similarly.
+ (value_of_variable): Provide dummy initialization of "frame".
+
+Mon Feb 10 07:54:26 1997 Fred Fish <fnf@cygnus.com>
+
+ * xcoffread.c (RECORD_MINIMAL_SYMBOL): Add NULL asection* parameter
+ to prim_record_minimal_symbol_and_info call that was missed in Jan 3
+ change.
+ (scan_xcoff_symtab): Ditto.
+
+Sun Feb 09 09:23:26 1997 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c (common_breakpoint): Prevent 64-bit addresses
+ from being sent to 32-bit targets by masking off upper bits.
+ * mips-tdep.c (heuristic_proc_start): Mask off upper 32 bits
+ of PC on 32-bit targets.
+ (mips16_heuristic_proc_desc): Recognize 'addiu s1,sp,n' as a
+ frame setup instruction.
+ (mips32_heuristic_proc_desc): Fix warning found by gcc -Wall.
+ (mips16_skip_prologue): Recognize 'addiu s1,sp,n' as a valid
+ prologue instruction. Fix warnings and bugs found by gcc -Wall.
+ * buildsym.c (finish_block): Improve handling of overlapping blocks;
+ fixes problem on MIPS16 printing function arguments.
+
+Sat Feb 8 01:14:43 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dwarf2read.c (dwarf2_linkage_name): New function to get
+ the linkage name of a die from DW_AT_MIPS_linkage_name or
+ DW_AT_name.
+ (read_func_scope, dwarf2_add_field, dwarf2_add_member_fn,
+ new_symbol): Use it instead of accessing DW_AT_name.
+ (read_partial_die): Use DW_AT_MIPS_linkage name as name of the
+ partial die if present.
+ (dwarf2_add_member_fn): Make a copy of physname on the type obstack.
+
+Fri Feb 7 10:06:22 1997 Jeffrey A Law (law@cygnus.com)
+
+ * blockframe.c (generic_frame_chain_valid): If the new frame
+ is not INNER_THAN the old frame, then it's not valid.
+
+Tue Feb 04 09:04:37 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mips16_get_imm): Fix calculation of extended immediate.
+ (mips16_heuristic_proc_desc): Recognize jal(x) instruction.
+
+Mon Feb 03 17:57:58 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mips16_decode_reg_save): Distinguish between
+ sd and sw instructions correctly.
+ (heuristic_proc_start): Add support for MIPS16.
+ (mips16_get_imm, mips16_heuristic_proc_desc,
+ mips32_heuristic_proc_desc): New helper functions for
+ heuristic_proc_desc.
+ (heuristic_proc_desc): Rewrite and reorganize to support MIPS16.
+ (mips_push_arguments): Don't align small arguments in EABI.
+ (mips32_skip_prologue): Attempt to shrink code size a little.
+
+Mon Feb 3 11:06:05 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * m32r-stub.c: New -- remote protocol support for M32R cpu.
+ * m32r-rom.c: Several experiments with improved download time.
+
+Fri Jan 31 08:26:39 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (MIPS16_INSTLEN): Define.
+ (mips_find_saved_regs): Replace hardcoded 2's with MIPS16_INSTLEN.
+ (heuristic_proc_start): Recognize 'entry' pseudo-op as a start
+ of function on MIPS16.
+ (mips32_skip_prologue, mips16_skip_prologue): New helper functions
+ for mips_skip_prologue.
+ (mips_skip_prologue): Recognize both 16- and 32-bit prologues.
+
+Wed Jan 29 12:45:54 1997 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/powerpc/ppc{,le}-sim.mt (SIM): Remove the library
+ ../sim/common/libcommon.a.
+
+Tue Jan 28 15:54:13 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * blockframe.c: fix a null pointer ref in generic_get_saved_register
+
+Tue Jan 28 15:39:50 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * mn10200-tdep.c (mn10200_frame_chain): Get basic backtracing
+ working.
+
+Mon Jan 27 14:31:52 1997 Mark Alexander <marka@cygnus.com>
+
+First set of changes for mips16:
+ * config/mips/tm-mips.h (MIPS16_BIG_BREAKPOINT,
+ MIPS16_LITTLE_BREAKPOINT, BREAKPOINT_FROM_PC): Define.
+ (ABOUT_TO_RETURN): Call new function mips_about_to_return.
+ (mips_breakpoint_from_pc, mips_about_to_return): Declare.
+ * mem-break.c (memory_breakpoint_from_pc): New function.
+ (memory_insert_breakpoint, memory_remove_breakpoint): Use
+ memory_breakpoint_from_pc to determine breakpoint contents and size.
+ * target.h (memory_breakpoint_from_pc): Declare.
+ * monitor.c (monitor_insert_breakpoint): Use memory_breakpoint_from_pc
+ to determine size of breakpoint instruction.
+ * mips-tdep.c (mips32_decode_reg_save, mips16_decode_reg_save):
+ New helper functions for mips_find_saved_regs.
+ (mips_find_saved_regs): Recognize mips16 prologues.
+ (mips_addr_bits_remove): Strip off upper 32 bits of address
+ when target CPU is 32 bits but CORE_ADDR is 64 bits.
+ (mips_step_skips_delay): No branch delay slot on mips16.
+ (gdb_print_insn_mips): Disassemble mips16 code.
+ (mips_breakpoint_from_pc, mips_about_to_return): New functions.
+
+Mon Jan 27 10:34:03 1997 Jeffrey A Law (law@cygnus.com)
+
+ * tm-mn10200.h (NUM_REGS): Decrease to 12.
+ (REGISTER_NAMES): Elimination registers not found on the mn10200.
+ (PC_REGNUM, MDR_REGNUM, PSW_REGNUM): Corresponding changes.
+ (LIR_REGNUM, LAR_REGNUM): Delete. They don't exist on the mn10200.
+
+Sat Jan 25 00:07:59 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dwarf2read.c: Replace integral tag, name and form fields in
+ internal structure definitions with the corresponding enumeration
+ types from dwarf2.h. Add default cases to switches on enumerations
+ where appropriate.
+ Make quoting of string arguments in complaint messages consistent.
+ Check for NULL returns from DW_STRING.
+ (struct partial_die_info): Add sibling and has_type fields, remove
+ unused value field.
+ (DW_*): Move access macro definitions near the definition of the
+ attribute structure.
+ (struct field_info): New structure to pass information about fields
+ and member functions between die processing routines.
+ (dwarf2_build_psymtabs_hard): Set cu_header_offset.
+ (scan_partial_symbols): Do not enter DW_TAG_subprogram dies into
+ the partial symbol table if the DW_AT_*_pc attributes are missing.
+ Add file scope base type definitions to the partial symbol table.
+ Skip over child dies if the die has a sibling attribute.
+ (add_partial_symbol): Enter global variables with type attributes
+ and without location descriptors into the partial symbol table.
+ Store value of DW_TAG_variable dies in the partial symbol table.
+ Do not enter global variables into the minimal symbol table.
+ Add base type definitions to the partial symbol table.
+ (psymtab_to_symtab_1): Use dwarf2_get_pc_bounds to determine highpc.
+ (process_die): Move check for DW_AT_low_pc to read_func_scope.
+ Add a typedef symbol for base type definitions to the symbol table.
+ Ignore DW_TAG_inlined_subroutine tags for now.
+ (read_file_scope): Use dwarf2_get_pc_bounds to determine pc bounds.
+ (read_func_scope, read_lexical_block_scope): Use dwarf2_get_pc_bounds
+ to determine pc bounds, ignore dies with invalid bounds.
+ (dwarf2_get_pc_bounds): New routine to extract and validate the
+ DW_AT_*_pc attributes of a die.
+ (dwarf2_add_field, dwarf2_attach_fields_to_type, skip_member_fn_name,
+ dwarf2_add_member_fn, dwarf2_attach_fn_fields_to_type):
+ New functions to handle fields and member functions.
+ (read_structure_scope): Rewritten to use them.
+ (read_array_type): Renamed from dwarf_read_array_type.
+ Default upper array bound to describe an array with unspecified
+ length.
+ Create array types in backwards order, as dwarf2 puts out the array
+ dimensions from left to right.
+ (read_subroutine_type): Handle DW_TAG_unspecified_parameters,
+ DW_AT_artificial and DW_AT_prototyped.
+ (read_base_type): Make an unsigned type for DW_ATE_boolean.
+ Pass objfile to dwarf_base_type.
+ (read_partial_die): Use read_attribute to read in the attributes.
+ Handle DW_AT_sibling and DW_AT_type.
+ Follow references when determining DW_AT_name and DW_AT_external
+ attributes of the die.
+ Validate DW_AT_*_pc attributes.
+ (read_full_die): Use read_attribute to read in the attributes.
+ (read_attribute): New function to read an attribute described
+ by an abbreviated attribute.
+ (new_symbol): Relocate symbol value for DW_TAG_label with baseaddr.
+ Do not set SYMBOL_VALUE_ADDRESS for DW_TAG_subprogram,
+ SYMBOL_BLOCK_VALUE for the symbol will be set later by finish_block.
+ Change symbol class for global variables with a zero valued location
+ descriptor to LOC_UNRESOLVED.
+ Handle DW_AT_const_value attributes for DW_TAG_variable,
+ DW_TAG_formal_parameter and DW_TAG_enumerator.
+ Build a typedef symbol for DW_TAG_base_type.
+ (dwarf2_const_value): New routine to copy a constant value from an
+ attribute to a symbol.
+ (dwarf_base_type): Use passed in objfile, not current_objfile
+ when calling dwarf2_fundamental_type.
+ (dump_die): Use DW_* accessor macros to access values of attributes.
+ (decode_locdesc): Handle DW_OP_plus_uconst.
+
+Wed Jan 22 01:31:16 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * mn10200-tdep.c: New file.
+ * config/mn10200/tm-mn10200.h: New, REGISTER_SIZE is 24 bits not 32,
+ SP_REGNUM and FP_REGNUM are different, also no lar or lir.
+ * config/mn10200/mn10200.mt: New file.
+ * configure.tgt: add mn10200 entry.
+
+Tue Jan 21 18:32:23 1997 Stu Grossman (grossman@lisa.cygnus.com)
+
+ * configure.in configure: Check if host has libdl if doing
+ Solaris threads.
+
+Tue Jan 21 17:03:26 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * mn10300-tdep.c: Wrote/fixed implementations of
+ mn10300_frame_chain, mn10300_init_extra_frame_info,
+ mn10300_frame_saved_pc
+ * config/mn10300/tm-mn10300.h: Redefine INIT_EXTRA_FRAME_INFO
+ and INIT_FRAME_PC macros.
+
+Tue Jan 21 17:01:20 1997 Stu Grossman (grossman@lisa.cygnus.com)
+
+ * configure.in configure: Check if host has libm. Make sure we
+ are using gcc when using the -export-dynamic option. Fixes a
+ problem with building under Solaris/SunPro cc.
+
+Mon Jan 20 13:52:13 1997 Mark Alexander <marka@cygnus.com>
+
+ * config/mips/{embed,embed64,embedl,embedl64}.mt:
+ Link in simulator on MIPS embedded targets.
+
+Sat Jan 18 02:31:29 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * blockframe.c (frameless_look_for_prologue): Mark frames
+ with a zero PC as frameless to improve backtraces from core dumps
+ caused by dereferencing a NULL function pointer.
+
+Thu Jan 16 14:10:41 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * config/mn10300/tm-mn10300.h: fix BREAKPOINT definition.
+
+Tue Jan 14 16:01:06 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * mn10300-tdep.c: made a lot more generic, ripping out code
+ from copied target (no more mn10300_scan_prologue,
+ init_extra_frame_info, and mn10300_fix_call_dummy calls)
+ * config/mn10300/tm-mn10300.h: undefine INIT_EXTRA_FRAME_INFO
+ and INIT_FRAME_PC macros
+
+Thu Jan 9 11:44:40 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * sparc-tdep.c (sparc_frame_find_saved_regs): Don't use
+ FP_REGISTER_BYTES to compute offsets into the saved frame,
+ since it fails for SPARC targets configured without any
+ FP regs. Instead, use DUMMY_STACK_REG_BUF_SIZE.
+
+Mon Jan 6 11:15:14 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * symtab.c (fixup_symbol_section): Handle NULL symbols without
+ crashing.
+
+Fri Jan 3 12:08:16 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in configure configure.in: Remove ENABLE_CLIBS,
+ ENABLE_OBS, and THREAD_DB_OBS. These are consolidated into LIBS
+ and CONFIG_OBS.
+ * configure configure.in: Clean up test cases around thread support.
+ * configure.tgt (v850-*-*): Include v850ice.o and v850.lib if
+ host is Windows.
+ * c-valprint.c ch-valprint.c cp-valprint.c eval.c expprint.c
+ printcmd.c valops.c value.h values.c: Add bfd_section arg to
+ value_at and value_at_lazy.
+ * coffread.c dbxread.c elfread.c mdebugread.c minsyms.c symtab.h:
+ Add bfd_section arg to prim_record_minimal_symbol_and_info.
+ * corefile.c gdbcore.h printcmd.c valops.c: Use read_memory_section
+ instead of read_memory. It takes a bfd_section arg.
+ * coffread.c dbxread.c elfread.c gdb-stabs.h objfiles.h: Remove
+ unnecessary cast for assignment of struct dbx_symfile_info.
+ Struct objfile now uses a real pointer instead of PTR for this
+ element.
+ * dbxread.c (dbx_symfile_init): Stash bfd section pointers for
+ text, data and bss into dbx_symfile_info.
+ * exec.c (xfer_memory): Handle transfers for user-specified
+ sections.
+ * findvar.c (read_var_value locate_var_value): Copy bfd section
+ from the symbol to the value.
+ * gdb-stabs.h: Add section pointers for text, data and bss
+ sections.
+ * maint.c (translate address command): Add test code for overlay
+ address translation.
+ * printcmd.c (do_examine do_one_display): Now takes a bfd section
+ arg.
+ * (print_formatted x_command): Record current section along with
+ current address for repeated commands.
+ * sparc-nat.c (fetch_inferior_registers): Change
+ target_xfer_memory to target_{read write}_memory to allow changes
+ to target_xfer_memory interface for section info.
+ * symmisc.c (dump_msymbols print_symbol): Print section
+ assocaited with symbol.
+ * symtab.c (fixup_symbol_section): New routine to
+ add section info to symbols returned by lookup_symbol.
+ * symtab.h (struct general_symbol_info): Add bfd section to
+ symbols.
+ * target.c target.h (target_xfer_memory): Add bfd section to
+ args.
+ * (target_read_memory_section): New routine to read data from a
+ specific section.
+ * (target_memory_bfd_section): New global variable to pass bfd
+ section in to targets.
+ * valarith.c (value_add value_addr value_array): Preserve bfd
+ section when computing new value.
+ * value.h (struct value): Add bfd section to values.
+ * values.c (allocate_value value_copy): Initialize/preserve bfd
+ section.
+ * (unpack_double): Clean up _MSC_VER conditionals to remove
+ duplicate code.
+ * v850ice.c: New module to support communication with NEC's
+ PC-based ICE.
+ * config/v850/tm-v850.h (REGISTER_NAMES): Replace sp, gp, fp, and
+ ep names with rxx names. sp and fp are renamed via a different
+ mechanism.
+
+Fri Jan 3 14:20:05 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * mn10300-tdep.c (mn10300_push_arguments): rewrote,
+ also removed code elsewhere that made use of RP_REGNUM.
+ * config/mn10300/tm-mn10300.h: ripped out RP_REGNUM, V0_REGNUM,
+ ARG0_REGNUM, ARGLAST_REGNUM (all not appropriate for mn10300
+ arch.), redefined SAVED_PC_AFTER_CALL, EXTRACT_RETURN_VALUE,
+ EXTRACT_STRUCT_VALUE_ADDRESS, STORE_RETURN_VALUE.
+
+For older changes see ChangeLog-1996
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/ChangeLog-1998 b/gdb/ChangeLog-1998
new file mode 100644
index 00000000000..a9038f81389
--- /dev/null
+++ b/gdb/ChangeLog-1998
@@ -0,0 +1,7220 @@
+Thu Dec 31 15:26:13 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * corelow.c (core_ops): Don't initialize statically.
+ (init_core_ops): New function, fills in core_ops.
+ (_initialize_corelow): Use it.
+
+Thu Dec 31 16:54:30 1998 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by
+ Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+ Edith Epstein <eepstein@sophia.cygnus.com>
+ David Taylor <taylor@texas.cygnus.com>
+
+ * config/pa/tm-hppa.h (INSTRUCTION_NULLIFIED): Change to read
+ nullify instruction bit from IPSW only when we are not in a system
+ call.
+ (STRCAT_REGISTER, pa_do_strcat_registers_info): Additional
+ parameter -- precision.
+
+ * Makefile.in (BUILD_TUI): To build the tui, only when configured
+ with --enable-tui.
+ (YLWRAP): Use ylwrap to avoid problems on systems w/o bison.
+ (gdb$(EXEEXT)): Make it dependent on BUILD_TUI.
+ (all-tui): Remove dependency from phony target.
+ (c-exp.tab.c): Use ylwrap instead of bison.
+ (jv-exp.tab.c): Ditto.
+ (f-exp.tab.c): Ditto.
+ (m2-exp.tab.c): Ditto.
+
+ * configure.in (ENABLE_CFLAGS): Define and export BUILD_TUI.
+
+ * configure: Regenerated.
+
+ * c-typeprint.c (c_type_print_base): Get to the method name by
+ skipping over all the namespaces, classes and '::'.
+
+ * infcmd.c (run_command): Only call SOLIB_RESTART if it's
+ defined.
+ (detach_command): Ditto.
+
+ * infptrace.c (call_ptrace): Add some debugging code.
+
+ * infrun.c (follow_inferior_fork): Only define on HP.
+ (wait_for_inferior): Only call SOLIB_IN_DYNAMIC_LINKER if we have
+ shared libraries; restore test of IN_SOLIB_DYNSYM_RESOLVE_CODE
+ removed by HP.
+
+ * Makefile.in (ALLDEPFILES): Add somread.c, hp-psymtab-read.c,
+ hp-symtab-read.c.
+ (SFILES): Remove the above files
+ (COMMON_OBS): Remove somread.o
+ (SFILES): Add the tui files to this, so they get
+ included in etags tables.
+ (all-tui): New rule, which does a recursive make in the tui
+ subdir.
+ (gdb$(EXEEXT)): Add tui-all to the list of
+ dependencies, and add tui/libtui.a to the link list.
+ (tui/libtui.a): When recursing, pass down
+ ${FLAGS_TO_PASS}. And don't echo the make command. This is
+ closer to what the other recursions do.
+ (HFILES_NO_SRCDIR) add hpread.h.
+ (COMMON_OBS): Add hp-psymtab-read.o, hp-symtab-read.o
+ Allow the TUI code to be conditionally enabled.
+ (TUI_TARGET, TUI_LIBRARY): New variables, whose values are set by
+ the configuration script. They're set to the empty string when
+ the TUI isn't enabled.
+ (gdb$(GDBEXT)): Use those, instead of referring to tui-all and
+ tui/libtui.a directly.
+
+ * Makefile.in: Avoid spurious relinking.
+ (gdb$(EXEEXT)): Depend on the actual tui library, not on a
+ fictitious target. Since the fictitious target never existed, make
+ would always relink.
+ (tui/libtui.a): Renamed from all-tui. Always recurse to make sure
+ the library is up to date.
+ (TUI_TARGET): Variable removed; there's no need for it any more.
+
+ * Makefile.in: Look for tui include files in the tui source dir.
+
+ * Use automake's `aclocal' program to generate aclocal.m4, to allow
+ us to use automake macros in configure.in with impunity.
+
+ * acconfig.h: Add an entry for the `TUI' symbol.
+
+ * acinclude.m4: New file, containing the code from the old
+ aclocal.m4. Incorporate (by reference) ../bfd/acinclude.m4, not
+ ../bfd/aclocal.m4, since we only want bfd's local macros.
+
+ * aclocal.m4: Now automagically generated. Just run aclocal!
+
+ * annotate.c (annotate_catchpoint): New function.
+
+ * annotate.h: Taking the new includes (symtab.h and gdbtypes.h).
+ not taking the ansic C build fix.
+ (annotate_catchpoint): Declare.
+
+ * blockframe.c (blockvector_for_pc_sect): Check that the end of
+ the block is >= to the pc, not just >.
+
+ * breakpoint.c (create_temp_exception_breakpoint): #If it out --
+ nothing calls it.
+ (bpstat_stop_status): Don't call SOLIB_HAVE_LOAD_EVENT if it's not
+ defined; don't call SOLIB_HAVE_UNLOAD_EVENT if it's not defined.
+ (bpstat_get_triggered_catchpoints): If we don't have shared
+ library support, then don't call SOLIB_LOADED_LIBRARY_PATHNAME nor
+ SOLIB_UNLOADED_LIBRARY_PATHNAME.
+ (watch_command_1): Don't require a run before a watch command
+ unless we're on HP [it's an HP OS bug, not a generic limitation]
+ (catch_load_command_1): Don't define if no shared libraries.
+ (catch_command_1): Don't claim to support fork catchpoints unless
+ CHILD_INSERT_FORK_CATCHPOINT is defined, don't claim to support
+ vfork catchpoints unless CHILD_INSERT_VFORK_CATCHPOINT is defined,
+ don't clain to support shared library load catchpoints if shared
+ libraries aren't supported, and don't claim to support exec
+ catchpoints unless CHILD_INSERT_EXEC_CATCHPOINT is defined
+
+ (bpstat_do_actions): If we just set cmd to NULL, don't then try to
+ set it to cmd->next as we'll SEGV.
+ (bpstat_do_actions): Simplify significantly. It's
+ now almost as simple as before the merge and it no longer has the
+ HP bug that breakpoint commands are executed repeatedly.
+
+ (break_at_finish_command_1): Rewrite and make sure
+ selected_frame points to a frame before using it. Fix string
+ termination error.
+ (break_at_finish_at_depth_command_1): Ditto.
+
+ (can_use_hw_watchpoints): New static variable.
+ (read_memory_nobpt): Test for breakpoint type bp_none.
+ (insert_breakpoints): Test for breakpoint type bp_catch_exec;
+ insure have a current frame before getting the frame address.
+ (remove_breakpoints): Check for breakpoints of types bp_none,
+ bp_catch_fork, bp_catch_vfork, and bp_catch_exec.
+ (bpstat_stop_status): Fix updates of b->hit_count.
+ (bpstat_have_active_hw_watchpoints): New function.
+ (create_exec_event_watchpoint): New function.
+ (watch_command_1): Use can_use_hw_watchpoints.
+ (catch_fork_command_1): Change name of function to call from
+ target_create_catch_(v)fork_hook to create_(v)fork_even_catchpoint.
+ (delete_breakpoint): Test for already deleted breakpoints; add
+ support for bp_catch_fork, bp_catch_vfork, and bp_catch_exec
+ breakpoints.
+ (_initialize_breakpoint): Add can-use-hw-watchpoints to list of
+ user settable debugger variables.
+
+ (clear_command): When there is no argument
+ to the clear command, delete all breakpoints that are hit at
+ default line. This will include a breakpoint whose line number
+ does not correspond to the default line, but has been set at
+ the default address.
+
+ (delete_breakpoint): Don't call bpstat_clear_actions, instead
+ clear things explicitly; if clearing breakpoint_at, then also
+ clear any associated actions so that bpstat_do_actions won't try
+ to execute them.
+ (_initialize_breakpoint): Fix function name for bx command.
+
+ (tbreak_command): Remove static from declaration.
+ (maintenance_info_breakpoints): Ditto.
+
+ (reattach_breakpoints): New funct definition, used with with
+ hardware watchpoints
+ (breakpoint_1): Change format and add entries to bptypes[]
+ (maintenance_info_breakpoints): Function is no longer static
+
+ (_initialize_breakpoint): Removed a comment.
+ (exception_catchpoints_are_fragile,
+ exception_support_initialized): Define.
+ (breakpoint_here_p): Fixed syntax error in conditional
+ (disable_watchpoints_before_interactive_call_start): Fixed call to
+ check_duplicates. Need a section parameter.
+ (enable_watchpoints_after_interactive_call_stop): Fixed call to
+ check_duplicates. Need a section parameter.
+ (breakpoint_re_set_one): Fixed call to check_duplicates. Need a
+ section parameter.
+ (delete_command): Fixed syntax error in conditional
+ (breakpoint_re_set): Fixed some typos.
+
+ (args_for_catchpoint_enable): New type for handling exceptions.
+ (current_exception_event): New variable for handling exceptions.
+ (insert_breakpoints): Check for additional breakpoint types --
+ bp_catch_throw, bp_catch_catch, call_disabled. Also, do some
+ additional work to handle an exception catchpoint.
+ (remove_breakpoint): There are additional breakpoint types to
+ check for: Bp_catch_throw, bp_catch_catch, call_disabled. Also do
+ some additional work to remove the exception catchpoints
+ (breakpoint_init_inferior): New input parameter. If there are
+ exception catchpoints delete them.
+ (breakpoint_here_p): There are additional breakpoint enable
+ settings to check for: Shlib_disabled, call_disabled
+ (breakpoint_thread_match): There are additional breakpoint enable
+ settings to check for: Call_disabled
+ (ep_is_catchpoint): There are additional breakpoint types to check
+ for: Bp_catch_throw, bp_catch_catch
+ (ep_is_exception_catchpoint): New function
+ (bpstat_find_step_resume_breakpoint): New function
+ (bpstat_do_actions): Introduce a local copy of the bpstat
+ structure.
+ (print_it_normal): There are additional breakpoint types to check
+ for: Bp_catch_throw, bp_catch_catch Changeing the control
+ structure a bit (adding else ifs) Add code to print out info about
+ exceptions.
+ (bpstat_stop_status): There are additional breakpoint enable
+ settings to check for: Call_disabled. there are additional
+ breakpoint types to chack for: Bp_catch_catch and bp_catch_throw.
+ Check to see if stopped due to an exception. Minor fixes to the
+ catch_errors calls. Make sure to count all encountered
+ breakpoints. There was something funky going on previously with
+ the counting.
+ (bpstat_what): Add cases for new breakpoint types:
+ bp_catch_catch, bp_catch_throw.
+ (bpstat_get_triggered_catchpoints): Check for new breakpoint types
+ : Bp_catch_catch, bp _catch_throw.
+ (breakpoint_1): Account for new breakpoint types.
+ (describe_other_breakpoints): Account for new breakpoint enable
+ setting (call_disabled)
+ (check_duplicates): Account for new breakpoint enable setting
+ (call_disabled)
+ (disable_breakpoints_in_shlibs): New function
+ (disable_watchpoints_before_interactive_call_start): New function
+ (mention): Account for new breakpoint types.
+ (break_command_1): Some additional checking for a valid PC.
+ (watch_command_1): Some dditional checking to prevent a watch
+ before a run command.
+ (ep_parse_optional_filename): Simplified for loop.
+ (create_exception_catchpoint): New function
+ (cover_target_enable_exception_callback): New function
+ (handle_gnu_4_16_catch_command): This used to be thcatch_command_1
+ function.e
+ (create_temp_exception_breakpoint): New function
+ (catch_command_1): Differs from gdb 4.16 and gdb 4.17. Is now
+ calling catch_exception_command_1 using the EX_EVENT_CATCH and
+ EX_EVENT_THROW values as parameters.
+ (clear_command): Additional comments
+ (delete_breakpoint): Handle exceptions. Check for additional
+ breakpoint enable settings: Shlib_disabled, call_disabled.
+ (delete_command): Hp folks are claiming that we should not delete
+ shlib_event breakpoints
+ (breakpoint_re_set_one): Moved call to check_duplicates. Add new
+ breakpoint types to switch statement.
+ (breakpoint_re_set_thread): New function
+ (enable_command): Account for new breakpoint types.
+
+ (insertion_state_t): New enumerated type.
+ (remove_breakpoint): New param in funct prototype.
+ (insert_breakpoints): Check for bp_catch_fork and bp_catch_vfork.
+ (remove_breakpoints): Changed call to remove_breakpoint.
+ (detach_breakpoints): New function.
+ (remove_breakpoint): New parameter, is. Also changed the
+ way b->inserted is set.
+ (ep_is_catchpoint): New function.
+ (ep_is_shlib_catchpoint): New function.
+ (print_it_normal): Check for bp_catch_load, bp_catch_unload,
+ bp_catch_fork, bp_catch_vfork, bp_catch_exec. Also new code
+ to print out catchpoints properly.
+ (bpstat_stop_status): Check for bp_catch_fork, bp_catch_vfork,
+ and bp_catch_exec. Also, some code to check for catching a
+ shared library load/unload.
+ (bpstat_what): Added catch_shlib_event to class enumeration.
+ Defined new macro, shlr. Expanded the bpstat_what_main_action
+ table. Add cases for bp_catch_load, bp_catch_unload,
+ bp_catch_fork, bp_catch_vfork, and bp_catch_exec.
+ (bpstat_get_triggered_catchpoints): New function.
+ (breakpoint_1): Changes to bptypes definition. Also check for
+ bp_catch_load, bp_catch_unload, bp_catch_fork, bp_catch_vfork,
+ bp_catch_exec. Similar changes to the switch statement.
+ (set_raw_breakpoint): Initialize new breakpoint structure fields.
+ dll_pathname, triggered_dll_pathname, forked_inferior_pid,
+ exec_pathname.
+ (create_solib_load_unload_event_breakpoint): New function.
+ (create_solib_load_event_breakpoint): New function.
+ (create_solib_unload_event_breakpoint): New function.
+ (create_fork_vfork_event_catchpoint): New function.
+ (create_fork_event_catchpoint): New function.
+ (create_vfork_event_catchpoint): New function.
+ (mention): New cases for bp_catch_load, bp_catch_unload,
+ bp_catch_fork, bp_catch_vfork, bp_catch_exec.
+ (ep_skip_leading_whitespace): New function.
+ (ep_find_event_name_end): New function.
+ (ep_parse_optional_if_clause): New function.
+ (ep_parse_optional_filename): New function.
+ (catch_fork_kind): New enumerated type.
+ (catch_fork_command_1): New function.
+ (catch_exec_command_1): New function.
+ (catch_load_command_1): New function.
+ (catch_unload_command_1): New function.
+ (catch_throw_command_1): New function.
+ (catch_command_1): Now calls catch_throw_command_1.
+ (tcatch_command): New function.
+ (delete_breakpoint): Changed call to remove_breakpoint.
+ Also free the new fields in the breakpoint structure.
+ (breakpoint_re_set_one): Handle bp_catch_load, bp_catch_unload,
+ bp_catch_fork, bp_catch_vfork, bp_catch_exec.
+ (disable_command): Handle bp_catch_load, bp_catch_unload,
+ bp_catch_fork, bp_catch_vfork, bp_catch_exec.
+ (enable_command): Handle bp_catch_load, bp_catch_unload,
+ bp_catch_fork, bp_catch_vfork, bp_catch_exec.
+ (_initialize_breakpoint): Alter add_com call for catchpoints,
+ add add_com call for watchpoints.
+
+ * breakpoint.h (enum bptype): New entries bp_catch_catch,
+ bp_catch_throw, and bp_none, bp_catch_load, bp_catch_unload,
+ bp_catch_fork, bp_catch_vfork,bp_catch_exec. Add declarations for
+ new functions bpstat_have_active_hw_watchpoints and
+ create_exec_event_catchpoint.
+ (tbreak_command): Add prototype.
+ (update_breakpoints_after_exec): Add prototype; update comments.
+ (reattach_breakpoints): New funct prototype declaration.
+ (enable): New enumerated value call_disabled.
+ (bpstat_find_step_resume_breakpoint): New funct decl.
+ (inf_context): New enumerated type.
+ (breakpoint_re_set_thread): New funct decl.
+ (breakpoint_init_inferior): New parameter.
+ (disable_watchpoints_before_interactive_call_start): New funct decl.
+ (enable_watchpoints_after_interactive_call_stop): New funct decl.
+ (disable_breakpoints_in_shlibs): New funct decl.
+ (struct breakpoint): New fields, dll_pathname,triggered_dll_pathname,
+ forked_inferior_pid,exec_pathname BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK.
+ (bpstat_get_triggered_catchpoints): New function.
+ (detach_breakpoints): New function.
+ (create_solib_load_event_breakpoint): New function.
+ (create_solib_unload_event_breakpoint) New function.
+ (create_fork_event_catchpoint): New function.
+ (create_vfork_event_catchpoint): New function.
+ (ep_is_catchpoint): New function.
+ (ep_is_shlib_catchpoint) New function.
+ (enum bpstat_what_main_action): New entry.
+
+ * buildsym.c (finish_block): Get rid of processing_hp_compilation;
+ handle LOC_INDIRECT case. Set the BLOCK_GCC_COMPILED to the right
+ compiler.
+ (push_context): Add symbols for parameters to the context_stack.
+ (merge_symbol_lists): New function. Merges two symbol lists.
+ (struct context_stack): Add new field param.
+
+ (processing_hp_compilation): New external var.
+
+ * c-exp.y: Use external flag hp_som_som_object_present to decide
+ whether code was compiled by HP's compilers. Add two new C++
+ tokens for true and false.
+ (yylex): Check for template name is done differently for the
+ HP/aCC compiler case; change some of the template processing code
+ for handling HP aCC templates.
+
+ * c-lang.c (c_create_fundamental_type): Added case to handle
+ template args. Handle FT_BOOLEAN type. Set no sign flag for
+ FT_CHAR.
+ (cplus_builtin_types): New structure for c++ builtin types.
+ (cplus_language_defn): Use cplus_builtin_types instead of
+ c_builtin_types.
+
+ * c-typeprint.c (c_type_print_base): Don't print 'privete' label
+ for a class if all members are private, similarly don't print
+ 'public' for a struct. Add support for sized enums (HP/aCC). get
+ rid of the 'static' keyword printed by the demangler for member
+ function, when printing the type of a class. 'static' will be
+ added by this function. If the demangled name is null, and the
+ method is not stubbed, get the signature by looking at the
+ information stored in the symbol structure. Remove printing of
+ 'const' and 'volatile' keywords for methods. This is now taken
+ care as part of the demangled member names.
+ (cp_type_print_method_args): New function. To print a C++ method
+ arguments and name to the output stream.
+
+ (c_type_print_cv_qualifier): New function. Print out "const" and
+ "volatile" attributes.
+ (c_type_print_varspec_prefix): Print const or volatile qualifiers.
+ (c_type_print_args): Print 'void' for c++.
+ (c_type_print_varspec_suffix): Print 'void' for a no argument
+ function.
+ (c_type_print_base): Print const or volatile qualifiers. Do not
+ print 'unnamed union' if HP aCC compiler used. Distinguish
+ between struct and class based on the DECLARED_TYPE. Handle
+ HP/aCC compiler case for not printing vtable. Add Template
+ support.
+
+ (cp_type_print_derivation_info): Print out 'protected' when
+ appropriate. This applies only to HP's compilers, not gcc.
+
+ (c_val_print): Added parameter embedded_offset. Add
+ embedded_offset to valaddr in function calls; fix calls to
+ val_print and cp_print_value_fields. process TYPE_CODE_METHOD as
+ well. moved call to check_typedef out of conditional. added
+ embedded offset param to val_print call.
+
+ (c_value_print): Add new parameter to call to val_print.
+ handle pointer to class case. Attempt to
+ determine the real type of the object to be printed.
+ ensure that const char *, const unsigned char *
+ come out without the type but the volatile variants
+ and the signed variants don't.
+
+ * coff-solib.c (coff_solib_add): Add parameters to call
+ to symbol_file_add.
+
+ * coff-solib.h: (Solib_REMOVE_INFERIOR_HOOK): New macro. defined
+ to 0. functionality not implemented for coff.
+ (SOLIB_CREATE_CATCH_LOAD_HOOK): New macro, generate error message
+ for coff.
+ (SOLIB_CREATE_CATCH_UNLOAD_HOOK): Ditto.
+ (SOLIB_HAVE_LOAD_EVENT): Ditto.
+ (SOLIB_LOADED_LIBRARY_PATHNAME): Ditto.
+ (SOLIB_HAVE_UNLOAD_EVENT): Ditto.
+ (SOLIB_UNLOADED_LIBRARY_PATHNAME): Ditto.
+ (SOLIB_IN_DYNAMIC_LINKER): Ditto.
+ (SOLIB_RESTART): Ditto.
+
+ * command.c (find_cmd): New function. (lookup_cmd_1): Call it,
+ change parsing if tui_version or xdb_commands is set.
+ (_initialize_command): Install new alias if xdb_commands is set.
+
+ * complaints.h: Add ifdef...endif pair at beginning and end of file.
+
+ * config.in, configure: Regenerated.
+
+ * config/pa/hppabsd.mh (NATDEPFILES): Added new files
+ hp-psymtab-read.o and hp-symtab-read.o.
+ * config/pa/hppahpux.mh (NATDEPFILES): Ditto.
+
+ * config/pa/hppahpux.mh (TERMCAP): Use -lHcurses.
+ * config/pa/hppaosf.mh (NATDEPFILES): Ditto.
+
+ * config/pa/hpux1020.mh (TERMCAP): Use -lHcurses.
+ (MH_CFLAGS): New flag, -D__HP_CURSES, this define
+ is used by HP's linker to find the correct curses library.
+
+ * config/pa/hpux1020.mh: New file.
+
+ * config/pa/hpux1020.mt: New file.
+
+ * config/pa/hpux1100.mh (TERMCAP): Link against -lcurses, not
+ -lHcurses. The latter does not contain mvwaddstr, wscrl, or
+ wstbwlmkfzz.
+
+ * config/pa/hpux1100.mh (TERMCAP): Use -lHcurses.
+ (MH_CFLAGS): New flag, -D__HP_CURSES, this define
+ is used by HP's linker to find the correct curses library.
+
+ * config/pa/hpux1100.mh (TERMCAP): When hosting on hpux 11.00, use
+ -lHcurses rather than -lcurses.
+
+ * config/pa/hpux1100.mh: New file.
+
+ * config/pa/hpux1100.mt: New file.
+
+ * config/pa/nm-hppah.h (CHILD_HAS_SYSCALL_EVENT): New macro
+ (CHILD_THREAD_ALIVE): New macro
+ (STOPPED_BY_WATCHPOINT): Add a condition to the macro,
+ ! stepped_after_stopped_by_watchpoint
+ (TARGET_ENABLE_HW_WATCHPOINTS): New macro
+ (hppa_enable_hw_watchpoints): New funct decl
+ (TARGET_DISABLE_HW_WATCHPOINTS): New macro
+ ( hppa_disable_hw_watchpoints): New funct decl
+ these are for HP's implementation of fast
+ watchpoints (via page protection).
+ (target_pid_to_str): New macro, calls hppa_pid_to_str
+ (target_tid_to_str): New macro, calls hppa_tid_to_str
+
+ * config/pa/nm-hppah.h (CHILD_POST_WAIT): Delete;
+ (CHILD_CREATE_CATCH_FORK_HOOK): Replace with
+ CHILD_INSERT_FORK_CATCHPOINT and CHILD_REMOVE_FORK_CATCHPOINT.
+ (CHILD_CREATE_CATCH_VFORK_HOOK): Replace with
+ CHILD_INSERT_VFORK_CATCHPOINT and CHILD_REMOVE_VFORK_CATCHPOINT.
+ (CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC,
+ CHILD_INSERT_EXEC_CATCHPOINT, CHILD_REMOVE_EXEC_CATCHPOINT,
+ CHILD_HAS_EXECD, CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL,
+ CHILD_POST_ATTACH, TARGET_HAS_HARDWARE_WATCHPOINTS,
+ TARGET_CAN_USE_HARDWARE_WATCHPOINT,
+ TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT,
+ TARGET_RANGE_PROFITABLE_FOR_HW_WATCHPOINT, STOPPED_BY_WATCHPOINT,
+ HAVE_NONSTEPPABLE_WATCHPOINT, target_insert_watchpoint,
+ target_remote_watchpoint): New macros.
+
+ * config/pa/nm-hppah.h (CHILD_XFER_MEMORY): Reinsert accidentally
+ deleted define.
+
+ * config/pa/nm-hppah.h:
+ (PREPARE_TO_PROCEED): Defined macro to use
+ hppa_prepare_to_proceed.
+ (hppa_pid_to_str): Extern decl.
+ (hppa_tid_to_str): Extern decl.
+ (target_pid_or_tid_to_str): New macro definition.
+ (hppa_pid_or_tid_to_str): Extern decl.
+ (ENSURE_VFORKING_PARENT_REMAINS_STOPPED): New macro - for
+ handling events caused by a call to vfork.
+ (hppa_ensure_vforking_parent_remains_stopped): Extern decl.
+ (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK): New macro -
+ for handling events caused by a call to vfork.
+ (hppa_resume_execd_vforking_child_to_get_parent_vfork): Extern decl.
+
+ * config/pa/nm-hppah.h: Fix PREPARE_TO_PROCEED macro.
+
+ * config/pa/nm-hppah.h: Fix for gcc compile on HPUX, change
+ PT_RDUAREA to PT_RUAREA.
+
+ * config/pa/nm-hppah.h: Introduced an HPUXHPPA define.
+ A bit of a hack so that I can ifdef some code that
+ only works for the HP wildebeest debugger.
+
+ * config/pa/nm-hppah.h: Lots of new CHILD_ defines;
+ process_event_kind enum.
+
+ * config/pa/tm-hppa.h (BREAKPOINT32): New define.
+ (CALL_DUMMY_HAS_COMPLETED): New define.
+
+ * config/pa/tm-hppa.h (STACK_ALIGN): New macro.
+ (NO_EXTRA_ALIGNMENT_NEEDED): New macro.
+ (PC_REQUIRES_RUN_BEFORE_USE): New macro.
+ (REGISTER_NAMES): Formatting in file changed.
+ (CR27_REGNUM): Base register for thread local storage.
+ (USE_STRUCT_CONVENTION): New macro used to decide whether
+ a function returning a value of type type will
+ put it on the stack or into registers (based on the
+ PA risc calling conventions).
+ (EXTRACT_RETURN_VALUE): Fixed calculation for extracting return value.
+ (VALUE_RETURNED_FROM_STACK): New macro.
+ (TARGET_READ_PC): Declared the function used in the definition.
+ (SKIP_TRAMPOLINE_CODE): Declared the function used in the definition.
+ (TARGET_WRITE_PC): Declared the function used in the definition.
+ (TARGET_READ_FP): Declared the function used in the definition.
+
+ * config/pa/tm-hppa.h (STRCAT_REGISTER): Define macro for
+ future use.
+ (pa_do_strcat_registers_info): Moved function decl from
+ defs.h to this HPUX specific .h file.
+
+ * config/pa/tm-hppa.h (USE_STRUCT_CONVENTION): Type_LENGTH returns
+ bytes, not bits; fix off by 8 error.
+
+ * config/pa/tm-hppa.h:
+ New comment for obj_unwind_info definition
+ New typedef, obj_private_struct
+
+ * config/pa/tm-hppa.h: Delete most target_ macros -- use default
+ versions instead; remove extraneous comma from proc_wait macro.
+
+ * config/pa/tm-hppa.h: Get rid of macro HP_COMPILED_TARGET.
+
+ * config/pa/tm-hppa.h: Removed redefinitions of
+ USE_STRUCT_CONVENTION and STACK_ALIGN macros.
+
+ * config/pa/tm-hppa.h: Some new definitions
+ New macros: Arg0_REGNUM, ARG1_REGNUM, ARG2_REGNUM, ARG3_REGNUM.
+ target_pid_to_exec_file, target_acknowledge_forked_child,
+ target_create_catch_fork_hook, target_create_catch_vfork_hook,
+ target_has_forked, target_has_vforked, require_attach,
+ require_detach, proc_wait
+ New funct decls: Hppa_pid_to_exec_file,
+ hppa_acknowledge_forked_child, hppa_create_catch_fork_hook,
+ hppa_create_catch_vfork_hook, hppa_target_has_forked,
+ hppa_target_has_vforked, hppa_require_attach,
+ hppa_require_detach, process_wait
+ (unwind_table_entry): Added comments to describe struct fields.
+
+ * config/pa/tm-hppah.h (somsolib.h): Include it.
+
+ * config/pa/tm-hppah.h:
+ (CHILD_ENABLE_EXCEPTION_CALLBACK): New define
+ (CHILD_GET_CURRENT_EXCEPTION_EVENT): New define
+
+ * configure.host (hppa-*-hpux10.20, hppa-*-hpux11.0*): New configs.
+
+ * configure.in (AC_CHECK_HEADERS): Add check for term.h.
+
+ * configure.in: Add an --enable-tui argument.
+
+ * configure.in: Construct tui/Makefile from tui/Makefile.in.
+
+ * configure.in: Use AM_PROG_CC_STDC. If we have the GUI, then we
+ need this to process libgui.h.
+
+ * convex-tdep.c (decout): Change FILE to GDB_FILE.
+
+ * corefile.c: Include objfiles.h, symfile.h.
+ (core_file_command): Attempt to determine the name of the symbol
+ file from the core file.
+ (read_memory_string): New function.
+
+ * corefile.c (core_file_command): Temporary hack to make non-hpux
+ work. For, non-hpux, t->to_core_file_to_sym_file does not have a
+ reasonable value. No target_ops vector on the stack gives it a
+ non-zero value. fix later.
+
+ * corelow.c (core_file_to_sym_file): Added new local variable,
+ failing command, and do some explicit type castings.
+ (core_ops): Add three new fields: to_has_syscall_event,
+ to_enable_exception_callback, to_get_current_exception_event.
+ Necessary since we still have oldstyle initialization in
+ this file
+
+ * corelow.c: Include unistd.h
+ (core_file_to_sym_file): New function
+ (core_file_thread_alive): New function
+ (core_ops): Added new target ops vector fields. see below. And
+ yes we definitiely need to initialize them here, as long as
+ we're using static initialization.
+
+ * cxux-nat.c (add_shared_symbol_files): Additonal params for calls
+ to symbol_file_add.
+
+ * defs.h (gdb_file_isatty): New function decl.
+
+ * defs.h (GDB_FILE): If TUI is defined, define a structure rather
+ than making this an alias for FILE.
+ (gdb_stdout, gdb_stderr): If TUI is defined, then define these
+ as pointers to variables of type GDB_FILE rather than making them
+ be aliases for stdout and stderr.
+
+ * defs.h (TUIDO): Add definition conditionalized on definition
+ (or lack thereof) of TUI.
+
+ * defs.h (command_class): Add two additional values.
+ (precision_type): New enum.
+
+ * defs.h (gdb_fclose): Add declaration.
+
+ * defs.h (store_address): Change prototype to match function.
+
+ * defs.h (tui_version, xdb_commands, dbx_commands): Add decl's.
+
+ * defs.h (gdb_file_deallocate): New function declaration
+
+ * defs.h:
+ (streamtype): New enumerated type to distinguish between
+ output to a FILE and output to a buffer.
+ (tui_stream): New struct type, named GDB_FILE. Contains,
+ streamtype, FILE, buffer, and bufferlength fields.
+ (gdb_stdout): Of type GDB_FILE, will pass this around gdb
+ rather than stdout.
+ (gdb_stderr): Of type GDB_FILE, will pass this around gdb
+ rather than stderr.
+ (fputs_unfiltered_hook): Change stream parameter from FILE to
+ GDB_FILE
+ (flush_hook): Change stream parameter from FILE to GDB_FILE
+ (gdb_fclose): Fix declaration for gdb_fclose; parameter is now of
+ type GDB_FILE **
+ (gdb_file_adjust_strbuf): New function declaration. function lives in
+ utils.c.
+ (gdb_file_init_astring): New function declaration. function lives
+ in utils.c
+ (gdb_file_get_strbuf): New function declaration. function lives
+ in utils.c
+
+ * defs.h: Additional include files included when TUI is defined.
+
+ * defs.h: Funct decl source_full_path_of.
+
+ * demangle.c: Add HP_DEMANGLING_STYLE_STRING.
+
+ * demangle.c: Added new demangling style, EDG_DEMANGLING_STYLE_STRING,
+ to the demanglers structure. This is for support of
+ Kuck & Assoc.'s changes for demangling.
+
+ * eval.c (evaluate_subexp_standard): C++ member function changes.
+
+ * eval.c (evaluate_subexp_standard): Verify TYPE_TARGET_TYPE is
+ non NULL before dereferencing it.
+
+ * eval.c (evaluate_subexp_standard): With HP/aCC compiler it is not possible
+ to perform inferior calls via function pointers.
+ Resolve calls to overloaded functions using find_overload_match.
+ We cannot handle HP/aCC pointers to member functions.
+ Deal with HP/aCC pointers to members in various kind of expressions.
+
+ * f-lang.c (f_printchar): Change FILE to GDB_FILE.
+ (f_printstr): Ditto.
+ (emit_char): Ditto.
+
+ * f-lang.c (f_printstr): Change stdout to gdb_stdout.
+
+ * f-typeprint.c (f_print_type): Change FILE to GDB_FILE.
+ (f_type_print_varspec_prefix): Ditto.
+ (f_type_print_args): Ditto.
+ (f_type_print_varspec_suffix): Ditto.
+ (print_equivalent_f77_float_type): Ditto.
+ (f_type_print_base): Ditto.
+
+ * findvar.c (): Hp snapshot 3 changes. (extract_address): Coerce
+ return value from extract_unsigned_integer to CORE_ADDR.
+ (store_address): Change val from CORE_ADDR to LONGEST; changes to
+ support machines where CORE_ADDR and LONGEST are different sizes.
+ (get_saved_register): Coerce arg to store_address to LONGEST.
+ (read_relative_register_raw_bytes): Cast last arg to
+ store_address to LONGEST. (read_register): Cast return from
+ extract_address to a CORE_ADDR. (write_register_pid): Change val
+ from LONGEST to CORE_ADDR. (read_pc_pid): Save and restore
+ inferior_pid if necessary. (write_pc_pid): Ditto.
+ (read_var_value): Cast arg to store_address.
+
+ * findvar.c (read_relative_register_raw_bytes_for_frame): New
+ function.
+ (read_relative_register_raw_bytes): Call it.
+
+ * findvar.c (symbol_read_needs_frame): Handle LOC_THREAD_LOCAL_STATIC and
+ LOC_INDIRECT.
+
+ * fork-child.c (fork_inferior): Chenge fifth parameter to be a
+ function returning void.
+
+ * fork-child.c (fork_inferior): Delete unused variable f.
+
+ * fork-child.c:
+ (Startup_WITH_SHELL): New macro -- interim fix for a bug
+ (breakup_args): New function -- breaks up an argument string into
+ an argument suitable for passing into execvp().
+ (fork_inferior): Handling problems with starting up gdb with a shell.
+ -- again, this appears to be an interim fix.
+
+ * fork-child.c:
+ (fork_inferior): Added a comment
+ (clone_and_follow_inferior): New function.
+ (startup_inferior): Minor formatting changes.
+
+ * fork-child.c:
+ (fork_inferior): Hp change is problematic. The -f option has
+ different meanings for different shells. It is particularly
+ inappropriate for bourne shells.
+
+ * fork-child.c:
+ (fork_inferior): Added new parameter, pre_trace_fun.
+ pre_trace_fun is a function pointer. For some targets,
+ like HPUX, this function gets called to prepare for forking
+ a child.
+
+ * fork-child.c:
+ (fork_inferior): Fixed call to init_trace_fun
+
+ * fork-child.c:
+ Moved definition of STARTUP_WITH_SHELL to inferior.h
+ Added a DEBUGGING macro. Currently set to 0. May remove
+ later.
+ breakup_args: Add DEBUGGING ifdefs. more sophisticated
+ parsing to break up args.
+ (fork_inferior): Rename kshell variable to shell. new local
+ variable, tryname. Make use of STARTUP_WITH_SHELL macro.
+ More error processing if starting up with a shell.
+ (startup_inferior): Distinguish between starting up with a shell
+ and not doing so.
+
+ * gdbthread.h:
+ Declarations for load_infrun_state and save_infrun_state take
+ an additional parameter.
+
+ * gdbthread.h: Note that sometime between gdb 4.16 and 4.17,
+ thread.h was renamed gdbthread.h
+ (load_infrun_state): Additional parameters
+ (store_infrun_state): Additional parameters
+
+ * gdbthread.h: Include breakpoint.h
+
+ * hp-psymtab-read.c (QUICK_LOOK_UP): Redefine to be 0.
+ (hpread_build_psymtabs): Deal with enums.
+ (hpread_start_psymtab): Include section offset.
+ (hpread_end_psymtab): Take care of offset.
+
+ * hp-psymtab-read.c (TRUE): Define.
+ (FALSE): Define.
+ (file_exists): New function. Checks for existance of file.
+ (hpread_pxdb_needed): Rewrite.
+ (hpread_quick_traverse): Use correct demangling style.
+ Handle F77 case.
+ (hpread_get_header): Rewrite.
+ (hpread_get_textlow): Add support for DOC_FUNCTION.
+ (hpread_build_psymtabs): Make sure we do the right thing
+ for pxdb and F77.
+
+ * hp-psymtab-read.c (hpread_pxdb_check): Change parenthesis positions.
+
+ * hp-psymtab-read.c (hpread_quick_traverse): Compare CORE_ADDR
+ variable end_addr to 0 instaed of NULL to get rif of gcc warning.
+
+ * hp-psymtab-read.c:
+ (Hpread_get_textlow): Added param to function
+ Defined convennience macros and some datatypes and variables for
+ processing the quick lookup-tables. Looks like the code existed
+ before, but has been munged.
+ (hpread_pxdb_needed): Major rearrangements of code. Additional local
+ variables. Also, more extensive checking for various scenarios:
+ debug info for optimized code vs. unoptimized code, pxdb has been
+ run vs. pxdb has not been run.
+ (VALID_FILE): New macro
+ (VALID_MODULE): New macro
+ (VALID_PROC): New macro
+ (VALID_CLASS): New macro
+ (FILE_START): New macro
+ (MODULE_START): New macro
+ (PROC_START): New macro
+ (FILE_END): New macro
+ (MODULE_END): New macro
+ (PROC_END): New macro
+ (FILE_ISYM): New macro
+ (MODULE_ISYM): New macro
+ (PROC_ISYM): New macro
+ (VALID_CURR_FILE): New macro
+ (VALID_CURR_MODULE): New macro
+ (VALID_CURR_PROC): New macro
+ (VALID_CURR_CLASS): New macro
+ (CURR_FILE_START): New macro
+ (CURR_MODULE_START): New macro
+ (CURR_PROC_END): New macro
+ (CURR_FILE_ISYM): New macro
+ (CURR_MODULE_ISYM): New macro
+ (CURR_PROC_ISYM): New macro
+ (TELL_OBJFILE): New macro
+ (pst_syms_struct): New typedef to keep track of the start/end symbol
+ table (LNTT) indices of psymtabs created so far.
+ (pst_syms_count): New variable
+ (pst_syms_size): New variable
+ (told_objfile): New variable
+ (init_pst_syms): New function. sets up psymtab symbol index stuff.
+ (clear_pst_syms): New function. clean up psymtab symbol index stuff.
+ (record_pst_syms): New function. add info about newest psymtab to symbol
+ index table.
+ (find_next_pst_start): New function. Find a suitable symbol table index.
+ (find_next_file_isym): New function
+ (find_next_proc_isym): New function
+ (find_next_module_isym): New function
+ (scan_procs): New function. Scan and record partial symbols for all
+ functions starting from specified index and in a specified code range.
+ (hpread_quick_traverse: Major rearrangement of code. The function
+ now uses all the nifty macros. There are some new local variables.
+ Check for EDG_DEMANGLING style. ifdef out some code for handling F77.
+ Previously, the function looped over all the modules in the table.
+ Now, the function loops over all the files, modules, and procedures.
+ With HP aCC and CTTI, it is possible for a compiled object to have a
+ file and no module.
+ (hpread_build_psymtabs): Added a section of code ifdefed by
+ QUICK_LOOK_UP. It check to see whether or not there are any globals
+ in the executable. Fix number of params to hpread_start_psymtab call.
+ Some changes to the way DNTT_TYPE_MODULE is handled.
+ (hpread_get_textlow): Change in signature, minor code changes. The
+ function finds the low address associated with a specified symbol.
+ In looking for the address for the symbol avoid going of the end of
+ the LNTT file.
+
+ * hp-psymtab-read.c: Change TRUE to 1 and FALSE to 0. Do some
+ reformatting.
+
+ * hp-psymtab-read.c: Include demangle.h
+ (trans_lang): New function to let gdb know the correct language.
+ (hpread_quick_traverse): Use ARM style demangling.
+ Demangle procedures names.
+ Use gdb language names instead of hp language names.
+ Add symbol to list using its demangled name.
+
+ * hp-psymtab-read.c: New file.
+ (hpread_call_pxdb): New function. Call PXDB to process our file.
+ (hpread_pxdb_check): New function. Return TRUE if the file needs
+ pre-processing by PXDB and we have thus called PXDB to do this
+ processing and the file needs to be re-loaded.
+ (hpread_quick_traverse): New function. Traverse the quick look-up
+ tables, building a set of psymtabs.
+ (hpread_get_header): New function. Get appropriate header from obj
+ file, based on pxdb type
+ (hpread_symfile_init): No change from hpread.c
+ (hpread_build_psymtabs): If there are quick lookup tables, read those,
+ then scan the global section LNTT. Otherwise, just scan the whole LNTT.
+ Changed: Add a global function entry to the global partial symbol list.
+ Handle end of symbols, for QLT case.
+ In case of TAGDEF, if it is a class or a template, add the name to the
+ var_namespace, so that it is known as a type by gdb.
+ In case of CONSTANT, and it is global, add it to the globals.
+ (hpread_symfile_finish): No change from hpread.c
+ (hpread_get_lntt): Make it not static
+ (hpread_get_gntt): No change from hpread.c
+ (hpread_get_slt): Make it not static
+ (hpread_get_textlow): No change from hpread.c
+ (hpread_start_psymtab): No change from hpread.c
+ (hpread_end_psymtab): No change from hpread.c
+
+ * hp-symtab-read.c (hpread_get_scope_start): Renamed. It was
+ hpread_get_depth.
+ (hpread_type_translate): Distinguish between signed and unsigned char
+ types.
+ (hpread_psymtab_to_symtab): Set flag for hp compilation.
+ (hpread_read_function_type): Append symbols for parameters to local
+ list as well as to the global list. Get the parameters types from the
+ local list instead of the global list.
+ (hpread_read_struct_type): Add new field num_fn_fields to next_fn_field
+ structure. Rewrite handling of templates
+ (hpread_type_lookup): Change handling of dntt_type_modifier.
+ (hpread_process_one_debug_symbol): Call hpread_get_scope_start instea
+ of hpread_get_depth. Handle enum as well.
+ (hpread_get_scope_depth): New function. Get nesting depth for a
+ DNTT entry.
+
+ * hp-symtab-read.c (hpread_psymtab_to_symtab): Set
+ processing_gcc_compilation to 0.
+
+ * hp-symtab-read.c (hpread_psymtab_to_symtab_1): Change stdout to
+ gdb_stdout; change fflush to gdb_flush.
+ (hpread_psymtab_to_symtab): Change fflush to gdb_flush.
+
+ * hp-symtab-read.c (hpread_read_enum_type): Declare variable.
+ (hpread_read_struct_type): Eliminate references
+ to 'args' member of fn_field.
+
+ * hp-symtab-read.c (hpread_read_struct_type): A static member
+ is now indicated by the bitsize field, not the bitpos.
+ Initialize physname to empty.
+ (fix_static_member_physnames): Use new macros to deal with
+ physnames.
+
+ * hp-symtab-read.c (hpread_read_struct_type): Change references
+ to bitpos member of struct field to use the FIELD_BITPOS macro.
+
+ * hp-symtab-read.c (hpread_read_struct_type): Comment out reference to
+ obsolete field fn_field.args.
+ Add struct complaint definitions for complaints.
+ (hpread_read_struct_type): Change call to complain.
+ (hpread_read_array_type): Change call to complain.
+ (hpread_type_lookup): Change call to complain.
+ (hpread_process_one_debug_symbol): Change calls to complain.
+ (hpread_type_translate): Change calls to complain.
+
+ * hp-symtab-read.c (hpread_read_struct_type): Make sure bitvector
+ has been allocated before calling has_vtable.
+
+ * hp-symtab-read.c (hpread_read_struct_type): Revert change,
+ just check for vtable without checking for bitvectors too.
+
+ * hp-symtab-read.c:
+ (Hpread_expand_symtab): Change name of local variable from
+ at_end_of_module to at_module_boundary.
+ Also, if demangling style is already EDG, do not reset it
+ to the HP demangling style.
+ Change at_end_of_module param to hpread_process_one_debug_symbol
+ call to at_module_boundary.
+ No longer break out of loop when reach end of module. With CTTI,
+ the compiler can generate function symbols which are not in
+ any module. Typically they show up after the end of one
+ module and before the start of the next module.
+ (hpread_read_struct_type): Check that the debug info for
+ a TEMPLATE_ARG is correct.
+ (hpread_process_one_debug_symbol): Change name of at_end_of_module_p
+ param to at_module_boundary_p.
+ Also set *at_module_boundary_p = -1 if missing a module end and set
+ it to 1 when finished expanding the debug info.
+ Handle TLS variable.
+
+ * hp-symtab-read.c: Include defs.h, symtab.h, gdbtypes.h, complaints.h.
+ (fixup_class): New static variable.
+ (fixup_method): New static variable.
+ (hpread_get_location): Rewrite.
+ (hpread_has_name): Add cases for DNTT_TYPE_DOC_FUNCTION and
+ DNTT_TYPE_DOC_MEMFUNC
+ (hpread_expand_symtab): Use HP demangling style.
+ Set hp_som_som_object_present to 1.
+ (hpread_type_translate): Error out if not immediate. Issue warning
+ if there is an unhandled type code.
+ (error_in_hpread_type_translate_complaint): Remove this structure.
+ (hpread_read_enum_type): Don't assume size of enum is always 4 bytes.
+ (hpread_read_function_type): Add new parameter to indicate a new block.
+ Do not add the parameters to the symbol list.
+ If the type was read in earlier, do not modify the type structure.
+ If we are creating a new block, set the local symbol list to be the
+ param list.
+ Need to mark this type as preprocessed.
+ (hpread_read_doc_function_type): New function. Read and internalize
+ a native DOC function debug symbol.
+ (hpread_read_struct_type): A method can be of type doc_function and
+ doc_memfunc too.
+ Handle case in which a method is read before its class. Deal with
+ incomplete method types.
+ Handle cases in which HP/aCC compiler creates operator names w/o
+ the 'operator' keyword. Rewrite the loop over the fileds.
+ (fix_static_member_physnames): New function. Adjust the physnames for
+ each static member.
+ (fixup_class_method_type): New function. Fix-up the type structure for a
+ class.
+ (hpread_read_array_type): Change complaint to warning.
+ (hpread_type_lookup): Add case for DNTT_TYPE_DOC_FUNCTION.
+ For structures/classes set static member to point to strings with full
+ names.
+ Change calls to hpread_read_function_type to pass extra parameter.
+ (hpread_record_lines): Handle case for SLT_NORMAL_OFFSET.
+ (class_of): New function. Given a function "f" which is a member of a class,
+ find the classname that it is a member of.
+ (hpread_process_one_debug_symbol): Deal with possible alias field from the
+ som record for the Function or Entry type.
+ Do the demangling ourselves if the gdb demangler failed.
+ Add support for DOC functions.
+ For function types, add parameters to local list.
+ (hpread_get_scope_depth): Make this function a no-op.
+ (hpread_adjust_bitoffsets): New function. Adjust the bitoffsets for all
+ fields of an anonymous union.
+ (hpread_get_next_skip_over_anon_unions): New function. Skip over anonymous
+ unions.
+
+ * hp-symtab-read.c: Include demangle.h
+ (hpread_expand_symtab): Ensure we are using ARM-style demangling.
+ (hpread_process_one_debug_symbol): Set the mangled and demangled
+ names for functions.
+ Record the class name to generate the demangled names of member
+ functions.
+
+ * hp-symtab-read.c: New file.
+ (hpread_get_depth): No change from hpread.c
+ (hpread_get_line): No change from hpread.c
+ (hpread_get_location): No change from hpread.c
+ (hpread_has_name): Make it not static. Return 1 for DNTT_TYPE_BLOCKDATA
+ and DNTT_TYPE_MEMFUNC. Return 0 for CLASS_SCOPE, REFERENCE,PTRMEM,
+ PTRMEMFUNC, CLASS, GENFIELD, VFUNC, MEMACCESS, INHERITANCE,
+ FRIEND_CLASS, FRIEND_FUNC, MODIFIER, OBJECT_ID, TEMPLATE, TEMPLATE_ARG,
+ FUNC_TEMPLATE, LINK.
+ (hpread_psymtab_to_symtab_1): No changes from hpread.c
+ (hpread_psymtab_to_symtab): Make it a static function
+ (hpread_expand_symtab): Modified
+ (hpread_type_translate): If not typep.dntti.immediate do not abort,
+ but complain and return. Same for default action. Handle more HP_TYPEs.
+ (hpread_lookup_type): Initially allocate a correct-size type-vector.
+ (hpread_alloc_type): Reset type_addr only if a type was allocated.
+ (hpread_read_enum_type): If this has already a type associated, return.
+ (hpread_read_function_type): Do different things depending on whether
+ function is a MEMFUNC, a TEMPLATE, a FUNCTION som record.
+ Do not use the LOC_REGPARM_ADDR symbol class.
+ (hpread_read_struct_type): Handle classes and templates too. Major
+ rewrite.
+ (hpread_get_nth_template_arg): New function.
+ (hpread_read_templ_arg_type): New function.
+ (hpread_read_set_type): No change from hpread.c
+ (hpread_read_array_type): Modified
+ (hpread_read_subrange_type): Add handling of more DNTT entries.
+ added support for templates, classes, references, virtual functions.
+ (hpread_type_lookup): Handle DNNT_TYPE_MODULE.
+ (hpread_record_lines): No changes from hpread.c
+ (hpread_process_one_debug_symbol): Handle WITH, COMMON,
+ CLASS_SCOPE. Expand TAGDEF case to handle classes and templates.
+
+ * hppa-tdep.c (pa_do_strcat_registers_info): Has a new parameter,
+ precision, which is passed into the call to pa_strcat_fp_reg to
+ indicate whether to display the floating point registers using
+ single or double preceision.
+ (pa_strcat_registers): Introduce local variable, precision, and
+ pass it into call to pa_strcat_fp_reg.
+ (pa_strcat_fp_reg): Modified function. New parameter, precision,
+ used by function to decide whether to use single or double
+ precision. Also added the code to put a double precision value
+ into a buffer.
+
+ * hppa-tdep.c: Add'l includes <machine/save_state.h>,
+ <unistd.h>, declare pa_register_look_aside, define is_pa_2.
+ (rp_saved): Check for where to read the return pointer from.
+ (pa_do_registers_info): Handle is_pa_2. (pa_register_look_aside):
+ new function. (pa_print_registers): Handle is_pa_2.
+ (in_solib_call_trampoline): Handle a compiler/linker error.
+ (skip_trampoline_code): Changes to some masks used in examining
+ instructions. (inst_saves_fr): Test for FSTWS instruction.
+ (skip_prologue): Renamed to skip_prologue_hard_way.
+ (after_prologue): New function. (skip_prologue): New function.
+
+ * hppa-tdep.c (after_prologue): If f is NULL, don't dereference
+ it.
+
+ * hppa-tdep.c (after_prologue): If no debug info, return zero
+ telling caller that we need to find the end of the prologue via
+ the hard way (instruction examination).
+
+ * hppa-tdep.c (find_unwind_entry): Avoid dereferencing a null
+ pointer.
+
+ * hppa-tdep.c (hppa_pid_to_exec_file): Deleted -- no longer used.
+
+ * hppa-tdep.c (hppa_prepare_to_proceeed): Add prototype.
+ (read_unwind_info): Purecov comments, bug fixes.
+ (find_unwind_entry): Purecov comments, bug fixes.
+ (find_stub_with_shl_get): Purecov comments.
+ (frame_chain): Additional parens.
+ (hppa_push_arguments): Changes to commented out version of routine.
+ (hppa_fix_call_dummy): Purecov comments, fix location of end.o.
+ (in_solib_call_trampoline): Purecov comments.
+ (in_solib_return_trampoline): Purecov comments.
+ (setup_d_pid_in_inferior): Fix location of end.o.
+ (initialize_hp_cxx_exception_support): Fix location of end.o.
+ (child_enable_exception_callback): Purecov comments.
+
+ * hppa-tdep.c:
+ (Pa_do_strcat_registers_info): New routine. called by
+ tui/tuiRegs.c:_tuiRegisterFormat to place a register name
+ and value into a string buffer. Interface may change in
+ future. Checking this in so that we have something
+ functional for HP.
+ (pa_strcat_registers): New routine, called by
+ pa_do_strcat_registers_info. Does same thing as
+ pa_print_registers except it takes a stream parameter.
+ This routine should disappear in future. Checking in
+ so that we have something functional to give HP
+ (pa_strcat_fp_reg): New routine, called by
+ pa_do_strcat_registers_info and pa_strvat_registers
+ to place a floating point register name and value into
+ a buffer. This interface may change in future.
+ Checking in so that we have something functional to give HP.
+
+ * hppa-tdep.c: (Pa_print_fp_reg): Change prototype to match def'n.
+ (pa_register_look_aside): Fix comment immediately before function.
+
+ * hppa-tdep.c: Changes to better support stack unwinding,
+ reading and writing registers for HPUX. The HP folks had
+ an advantage ... access to a runtime architecture spec ;-}.
+ New includes: Ptrace.h
+ (internalize_unwinds): Initialize new fields in table.
+ (read_unwind_info): Entries in the table are now more complex
+ structures. References of the form ...->table[index].stub_type
+ are now ...->table[index].stub_unwind.stub_type.
+ (find_proc_framesize): Added a check for pc == 0.
+ (rp_saved): Entries in the table are now more complex
+ structures. References of the form ...->table[index].stub_type
+ are now ...->table[index].stub_unwind.stub_type.
+ (frameless_function_invocation): Stub_type becomes
+ stub_unwind.stub_type
+ (saved_pc_after_call): Stub_type becomes stub_unwind.stub_type
+ (hppa_frame_saved_pc): Stub_type becomes stub_unwind.stub_type
+ (frame_chain_valid): Stub_type becomes stub_unwind.stub_type
+ (hppa_call_dummy): Stub_type becomes stub_unwind.stub_type
+ (pa_print_fp_reg): Additional params to call val_print
+ (in_solib_call_trampoline): Stub_type becomes stub_unwind.stub_type
+ (in_solib_return_trampoline): Stub_type becomes stub_unwind.stub_typ
+ (skip_trampoline_code): Additional code to handle external
+ dyncalls. Also stub_type becomes stub_unwind.stub_type
+ (hppa_pid_to_exec_file): New funct. FOr HPUX 10.0 and beyond there
+ is an explicit ptrace request for getting the pathname associated
+ with a process id (pid).
+
+ * hppa-tdep.c: Fix for gcc compile on HPUX
+ (hppa_pid_to_exec_file): Remove unwanted param from
+ call to call_ptrace. Note, hppa_pid_to_exec_file goes
+ away in subsequent hp snapshots.
+
+ * hppa-tdep.c: Include bfd.h.
+ include dl.h
+ (args_for_find_stub): New structure.
+ (find_unwind_entry): Deal with null input pc value.
+ (rp_saved): Ditto.
+ For the import stub, return -24 always.
+ (hppa_frame_saved_pc): Save old pc value, to detect we are in a loop.
+ (init_extra_frame_info): Use TARGET_READ_FP.
+ (frame_chain): Include thread support.
+ If the caller's pc is zero, we loose and return, just like stack bottom.
+ Disable warning about being unable to find unwind info.
+ (hppa_push_arguments): Rewrite.
+ (hppa_value_returned_from_stack): New function. Handles returning a value
+ larger that 64 bits, stored on the stack.
+ (find_stub_with_shl_get): New function. To look up symbols in shlibs.
+ (cover_find_stub_with_shl_get): New function. Cover routine for
+ find_stub_with_shl_get to pass to catch_errors.
+ (hppa_fix_call_dummy): Comment out old stub mechanism. Rewrite using dyncall.
+ (target_read_fp): New function.
+ (pa_do_registers_info): Floating point registers start at FP4.
+ (pa_print_registers): Use FP4_REGNUM instead of 72.
+ (skip_trampoline_code): Do machine instruction matching for PA2.0.
+ (setup_d_pid_in_inferior): New function. Exception handling support.
+ (initialize_hp_cxx_exception_support): Ditto.
+ (child_enable_exception_callback): Ditto.
+ (child_get_current_exception_event): Ditto.
+
+ * hppah-nat.c (child_post_wait, child_post_follow_vfork,
+ child_post_follow_inferior_by_clone): New functions.
+
+ * hppah-nat.c (child_xfer_memory): Make sure the call to ptrace really
+ fails before we give up.
+ (hppa_pid_to_str): New function. Format a process id.
+ (hppa_tid_to_str): New function. Format a thread id.
+
+ * hppah-nat.c (child_xfer_memory): Use xmalloc, not alloca.
+ (child_post_wait): Delete.
+ (child_post_follow_vfork): Delete decl of child_ops; delete
+ large chunks of function -- let it be handled by the normal
+ mechanism that notices and handles exec events, in resume().
+
+ * hppah-nat.c (require_notification_of_exec_events): New function;
+ just notify of exec events, not all events, and just the specified
+ pid, don't include it's children (10.20 version).
+ (child_acknowledge_created_inferior): Call new function
+ require_notification_of_exec_events instead of
+ require_notification_of_events.
+
+ * hppah-nat.c [!GDB_NATIVE_HPUX_11]: Move HPUX 10.x-specific
+ support code here from infptrace.c.
+
+ * hppah-nat.c: Removed #define ptrace call_ptrace
+ replaced all calls to ptrace with calls to call_ptrace
+ (parent_attach_all): Removed call to ptrace
+
+ * hpread.c (hpread_psymtab_to_symtab_1): Change fflush to
+ gdb_flush; change stdout to gdb_stdout.
+ (hpread_psymtab_to_symtab): Change fflush to gdb_flush.
+
+ * hpread.h: New file. Includes all includes, struct defs, defines
+ from hpread.c.
+
+ * infcmd.c
+ (attach_command): New local variable, exec_file, added code to
+ determine exec_file from pid if exec_file is not already known,
+ call new target operation, target_post_attach -- a no-op unless
+ on HPUXHPPA
+ (detach_command): After detaching, do a SOLIB_RESTART
+
+ * infcmd.c (objfiles.h): Fix typo on include line.
+
+ * infcmd.c (run_command): Only call SOLIB_RESTART if it's
+ defined.
+ (detach_command): Ditto.
+
+ * infcmd.c:
+ (run_stack_dummy): Add calls to
+ disable_watchpoints_before_interactive_call_start and
+ enable_watchpoints_after_interactive_call_stops
+ (finish_command): Alter code handling the evaluation and printing
+ of the target function's return value.
+ (attach_command): When given a pid, but no exec file, try to determine
+ the exec file from the process. If the process does not record a
+ full path name, try to qualify the filename against the source path.
+ (_initialize_infcmd): Add some verbiage about how to use the attach command
+
+ * infcmd.c:
+ Include objfiles.h
+ (run_command): If program has already been started, and decide
+ to restart it, then kill the target, flush the caches,
+ call init_wait_for_inferior. Also purge old solib objfiles.
+
+ * infcmd.c: Changed calls to val_print, using a new macro,
+ SOLIB_RESTART
+ (run_command): Calls SOLIB_RESTART
+ (do_registers_info): Changed calls to val_print
+
+ * infcmd.c: Made the symfile.h include preceed the
+ objfiles.h include. The other ordering caused a
+ compile problem (incompletely defined types).
+
+ * inferior.h (REQUIRE_DETACH): Fix default definition.
+ * inftarg.c (child_post_attach): Fix declaration, make static.
+ (proc_wait): Make globally visible.
+ (child_insert_fork_catchpoint, etc): Fix return type.
+
+ * inferior.h (STARTUP_WITH_SHELL): New define.
+ (START_INFERIOR_TRAPS_EXPECTED): New define
+
+ * inferior.h (fork_inferior): Change fifth parameter to be a function
+ returning void.
+
+ * inferior.h (proc_wait): Declare.
+
+ * inferior.h:
+ (Require_ATTACH): New macro
+ (REQUIRE_DETACH): New macro
+ (detach): Definition is now an extern
+ (clone_and_follow_inferior): New definition, it's also an extern
+
+ * inferior.h:
+ (Require_attach): Default definition for require_attach funct
+ (require_detach): Default definition for require_detach funct
+ (pre_fork_inferior): New funct decl for function defined in
+ infptrace.c
+ (fork_inferior): New parameter in funct decl.
+
+ * inferior.h:
+ New variable decls: Inferior_ignoring_startup_exec_events,
+ inferior_ignoring_leading_exec_events -- these variables
+ are used when processing an exec call.
+ (CALL_DUMMY_HAS_COMPLETED): New default macro -- for targets
+ where PC in call dummy implies that call dummy has
+ completed. Note, that on HPUX this inference does not hold.
+
+ * infptrace.c
+ (require_notification_of_events): New function
+ (child_acknowledge_created_inferior): Previously named
+ hppa_acknowledge_forked_child. Also calling
+ require_notification_of_events and clearing some semaphore
+ variables
+ (child_post_startup_inferior): New function
+ (child_create_catch_fork_hook): Previously named
+ hppa_create_catch_fork_hook
+ (child_create_catch_vfork_hook): Previously named
+ hppa_create_catch_vfork_hook
+ (child_has_forked): Previously named hppa_target_has_forked
+ (child_has_vforked): Previously named hppa_target_has_vforked
+ (process_wait): Changed to call target_post_wait
+ (attach): Add call to require_notification_of_events
+ (child_pid_to_exec_file): New function
+ (hppa_require_attach): New local variable, pt_status
+ (hppa_get_process_events): New function
+
+ * infptrace.c (call_ptrace): Simplify control flow.
+ (proc_wait): Move here from inftarg.c, add target_post_wait call.
+
+ * infptrace.c (call_ptrace): Add some debugging code.
+
+ * infptrace.c (child_pid_to_exec_file): Declare variable.
+
+ * infptrace.c (kill_inferior): Clean up call to proc_wait.
+
+ * infptrace.c:
+ (Call_ptrace): When the ptrace request is PT_SETTRC,
+ call ptrace and then call parent_attach_all.
+
+ * infptrace.c:
+ (Child_has_syscall_event): New function. only applicable
+ (for now) on HPUX 10.30 and beyond via the ttrace call.
+ In infptrace.c there is a default operation.
+ With ttrace, it is possible to tell the kernel to
+ notify the debugger that the target program is about to make
+ or return from a syscall.
+ (child_thread_alive): New function. a default function.
+ ptrace doesn't support kernel threads.
+ (hppa_enable_page_protection_events): Defualt function
+ (hppa_disable_page_protection_events): Default function
+
+ * infptrace.c (child_pid_to_exec_file): Fix number of params to
+ cal_ptrace call.
+
+ * infptrace.c (hppa_pid_or_tid_to_str): New function.
+ (hppa_switched_threads): New function.
+ (hppa_ensure_vforking_parent_remains_stopped): New function.
+ (hppa_resume_execd_vforking_child_to_get_parent_vfork): New function.
+
+ * infptrace.c: Most of the changes found in infptrace.c should
+ be moved to hppah-nat.c
+ (PT_VERSION): A new define
+ (startup_semaphore_t): A new struct type. it is used to
+ coordinate the parent and child processes after a fork and
+ before an exec on HPUX.
+ (call_ptrace): Changes to determine whether the ptrace
+ request is for starting the tracing of the target process.
+ (parent_attach_all): New funct. used on HPUX for coordinating
+ the parent and child processes after a fork and before and exec.
+ (hppa_acknowledge_forked_child): New funct. prabably belongs
+ in hppah-nat.c
+ (hppa_enable_catch_fork): New funct. probably belongs in
+ hppah-nat.c
+ (hppa_disable_catch_fork): New funct. probably belongs in
+ hppah-nat.c
+ (hppa_create_catch_fork_hook): New funct. probably belongs in
+ hppah-nat.c
+ (hppa_enable_catch_vfork): New funct. probably belongs in
+ hppah-nat.c
+ (hppa_disable_catch_vfork): New funct. probably belongs in
+ hppah-nat.c
+ (hppa_create_catch_vfork_hook): New funct. probably belongs to
+ hppah-nat.c
+ (hppa_target_has_forked): New funct. probably belongs in
+ hppah-nat.c
+ (hppa_target_has_vforked): New funct. probably belongs in
+ hppah-nat.c
+ (process_wait): New funct. also ifdefed for proc_wait.
+ (kill_inferior): Call proc_wait rather than wait. this is
+ pretty hacky.
+ (pre_fork_inferior): New function. used only by HPUX.
+ probably should be defined elsewhere.
+
+ * infrun.c (follow_inferior_fork): Only define on HP.
+ (wait_for_inferior): Only call SOLIB_IN_DYNAMIC_LINKER if we have
+ shared libraries; restore test of IN_SOLIB_DYNSYM_RESOLVE_CODE
+ removed by HP.
+
+ * infrun.c (normal_stop): Add a call to the TUIDO
+ macro just before the annotate_stopped label. This
+ updates the windows after each program stop.
+
+ * infrun.c (normal_stop): Verify stop_command is non-zero before
+ dereferencing it (it won't be set if dbx_commands is set).
+
+ * infrun.c (resume): Add #ifdef HPPAHPUX around HPUX-specific
+ code.
+
+ * infrun.c (resume): Add missing semicolon.
+
+ * infrun.c (wait_for_inferior): Fix syntax error.
+
+ * infrun.c (follow_fork_mode_kind_names): Removed "both" option.
+ (follow_fork): Added parameters. additional code for handling
+ following of parent, following of child
+ (resume): Added code for deciding how to resume in presence of
+ fork. Additional params to follow_fork call.
+
+ * infrun.c (follow_exec): Ifdef for HPUXHPPA for the moment, the
+ code in here assumes the existance of the child_ops target
+ vector. This is incorrect for Solaris.
+
+ * infrun.c (resume): Fixed ifdefs, HPPAHPUX -> HPUXHPPA.
+
+ * infrun.c (wait_for_inferior): Fixed a matching parens problem --
+ matching curly brace inside ifdefed code which is not being
+ compiled. Change local validFlag to be an 'int' rather than a
+ 'bool' and fixed the corresponding assignment statements.
+
+ * infrun.c:
+ Two new global variables: Inferior_ignoring_startup_exec_events and
+ inferior_ignoring_leading_exec_events.
+ New static variables: Parent_of_vfork_trap_expected_and_ignorable,
+ step_resume_breakpoint, through_sigtramp_breakpoint, pending_follow,
+ follow_vfork_when_exec
+ (follow_inferior_fork): Does what follow_fork did!
+ (follow_fork): Is now a wrapper function for follow_inferior_fork
+ (follow_vfork): Is now a wrapper function for follow_inferior_fork
+ (follow_exec): New function, handles an exec event.
+ (resume): Remove 3 local variables: Child_pid, has_forked, has_vforked.
+ move and expand code that tries to follow a fork (i.e. also check
+ for vfork and exec
+ (init_wait_for_inferior): Initialize the new structure, pending_follow
+ (delete_breakpoint_current_contents): When deleting all the breakpoints also
+ set the breakpoint struct pointer to NULL.
+ (wait_for_inferior): A number of changes.
+ The step_resume_breakpoint and through_sigtramp_breakpoint local
+ variables are now visible in entire module.
+ Changed name of variable from child_inferior_pid to saved_inferior_pid.
+ Added several cases to the event processing switch statement:
+ Target_WAITKIND_FORKED, TARGET_WAITKIND_VFORKED, TARGET_WAITKIND_EXECD.
+ Also, for TARGET_WAITKIND_STOPPED, check to see if expecting a trap
+ from the parent of a vfork (ignorable) otherwise break as usual.
+ When determining the value of 'random_signal' (0 or 1), no longer check for
+ catchpoints.
+ When determining how to handle unexpected signals, must now take into
+ account fork, vfork, and exec.
+ Change call to PC_IN_CALL_DUMMY to a call to CALL_DUMMY_HAS_COMPLETED
+ At stop_stepping label, check to see if stopped for fork or
+ vfork event.
+
+ * infrun.c: New code is related to threads and fork/vfork/exec.
+ New static variable: Thread_step_needed
+ Deleted static variable: Parent_of_vfork_trap_expected_and_ignorable
+ Altered the pending_follow and fork_event structs
+ (follow_inferior_fork): Before detaching from child and removing
+ all breakpoints form it -- but only if forking or following
+ vforks as soon as they happen. Also reset the solib inferior hook.
+ The same kind of logic applies to hitting step_resume_breakpoints
+ (calling breakpoint_re_set_thread) and to resetting and inserting
+ breakpoints.
+ (follow_exec): Forward decl
+ (follow_vfork): Check to see if gdb followed the child. If
+ the child exec'd before gdb saw the parent's vfork event
+ then call follow_exec.
+ (follow_exec): If the exec occured after a vfork, then follow
+ the vfork as well. Do it before following the exec.
+ Make sure to update breakpoints after and exec
+ (resume): New local variable, should_resume.
+ Change parameters in calls to follow_fork, follow_vfork, and
+ follow_exec. Some changes to the way various pending_follow.kind
+ situations are handled (there's TARGET_WAITKIND_FORKED,
+ TARGET_WAITKIND_VFORKED, ARGET_WAITKIND_EXECD. Some additional
+ conditions to check before deciding to resume the target (i.e.
+ should_resume=1, stepping?, thread_step_needed?i, regular
+ resume?)
+ (proceed): When proceeded at location that does not have a breakpoint
+ set thread_step_needed=0 to indicate that it is not necessary to
+ single step thread over breakpoint. SOme additional checks to see
+ if it is necessary to step thread over breakpoint.
+ (start_remote): Remove call to clear_proceed_status.
+ (init_wait_for_inferior): Initialize new fields in fork_event
+ structure and add a call to clear_proceed_status.
+ (wait_for_inferior): New local variable: New_thread_event.
+ Initialize thread_step_needed = 0.
+ Minor massaging of conditions for adding a new thread to the thread list.
+ No longer resuming execution after adding a new thread. Let user play with thread first.
+ Some changes in the way TARGET_WAITKIND_FORKED, ARGET_WAITKIND_VFORKED,
+ TARGET_WAITKIND_EXECD are handled -- this is all HPUX related.
+ Simplified TARGET_WAITKIND_STOPPED -- HP previously had some
+ more complicated code in here.
+ Moved the code to resume threads to after the large case statement that processes the events.
+ Additional processing for stop_signal=TARGET_SIGNAL_TRAP.
+ Cleanup code at process_event_stop_test label.
+ Set thread_step_needed when processing a BPSTAT_WHAT_SINGLE.
+ Minor massaging of fork/vfork/exec part of stop_stepping code.
+ (normal_stop): Minor changes. calling show_and_print_stack_frame.
+ (xdb_handle_command): New function
+ (_initialize_infrun): Handle xdb_commands. also handle dbx commands
+
+ * infrun.c: Changes to support following forks, and handling
+ catchpoints.
+ (follow_fork_mode_kind_names): New array
+ (follow_fork): New function. implements the follow parent,
+ or child functionality.
+ (resume): Additions to check whether the target process
+ just forked and decide which process to follow.
+ (wait_for_inferior): Additional variables (child_inferior_pid,
+ stepping_through_solib_after_catch,
+ - stepping_through_solib_catchpoints.
+ - Altered CURRENTLY_STEPPING macro to check for stepping through
+ a shared library after hitting a catchpoint.
+ - Add parameters to save_infrun_state call
+ - Check for fork and vfork when deciding if event is a random
+ signal
+ - When considering stops due to breakpoints, check for
+ BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK
+ - Check for stop due to an explicit catchpoint
+ - When checking for single stepping event, also check for
+ stepping to get out of dynamic linker's hook after catching
+ a shlib event
+ (is_internal_shlib_eventpoint): New funct. check to see if
+ event type is bp_shlib_event.
+ (stopped_for_internal_shlib_event): New funct. check for shlib
+ events
+ (stopped_for_shlib_catchpoint): New funct. check for catchpoints.
+ (normal_stop): Additions to check for shlib event
+ (set_follow_fork_mode_command): New funct. handles the new follow
+ fork command.
+ (_initialize_infrun): Additions for follow-fork-mode command.
+
+ * infrun.c: Ifdefing references to
+ switched_from_inferior_pid for HPUXHPPA. They don't seem
+ useful for Solaris (i.e. non-HPUX)
+
+ * infrun.c: Included tuiData.h and tuiDataWin.h, ifdefed for TUI.
+ Included top.h. New static variables: Switched_from_inferior_pid,
+ number_of_threads_in_syscalls.
+ (follow_inferior_fork): If there is a step_resume breakpoint
+ explicitly reset the thread number.
+ (resume): For TARGET_WAITKIND_VFORKED, removed a check for getting
+ the vfork event to soon.
+ (init_wait_for_inferior): Added parameter to call to
+ breakpoint_init_inferior. Initialize number_of_threads_in_syscalls.
+ (wait_for_inferior): New local variables: Prev_sal,
+ enable_hw_watchpoints_after_wait, stepping_through_sigtramp,
+ stepped_after_stopped_by_watchpoint. Enable watchpoints after a wait.
+ Added cases for TARGET_WAITKIND_SYSCALL_ENTRY and
+ TARGET_WAITKIND_SYSCALL_RETURN.
+ Do additional processing if stop due to breakpoint, but breakpoint is
+ only valid for a thread other than the one currently running. Additional
+ parameters to save_infrun_state and load_infrun_state. Some additional
+ processing for BPSTAT_WHAT_STEP_RESUME. Some additional processing to
+ handle stepping over a function.
+ (normal_stop): Added notification of switching threads. ifdefing some
+ TUI changes and leaving out non-essential TUI changes.
+ (restore_selected_frame): Ifdefing some TUI changes
+ (restore_inferior_status): Ifdefing some TUI changes
+
+ * infrun.c: Removed the TUI ifdefs and TUI code. Also removed
+ include for top.h. HP introduced this. I'm taking it out.
+
+ * inftarg.c (child_detach_from_process): Declare.
+ (child_attach_to_process): Declare.
+ (child_stop): Make static to match declaration.
+
+ * inftarg.c (ptrace_him): Change prototype back to return int.
+
+ * inftarg.c (ptrace_me): Remove debug output, pass NULL to
+ fork_inferior if not HPUX.
+
+ * inftarg.c:
+ (child_require_attach): New funct prototype and definition
+ (child_require_detach): New funct prototype and definition
+ (proc_wait): Funct prototype and definition are enclosed by
+ proc_wait ifndef
+ (child_attach_to_process): New function, does most of the
+ work that child_attach used to do and some additional
+ work to determine whether gdb is already attached to the
+ target how to react.
+ (child_attach): Altered. It's now a wrapper for
+ child_attach_to_process.
+ (child_require_attach): New function, called if should attach
+ even when gdb is already attached to target.
+ (child_detach_from_process): New function, does most of the
+ work that child_detach used to do and some additional work
+ to determine whether gdb is currently attached to the target.
+ (child_detach): Altered. It's now a wrapper for
+ child_detach_from_process.
+ (child_require_detach): New function, called if should try to
+ detach even when gdb is not attached to target.
+ (ptrace_him): Calls a new function, target_acknowledge_forked_child.
+ Currently, target_acknowledge_forked_child, is only defined to
+ do something for HPUX.
+ (child_create_inferior): Changed call to fork_inferior.
+ (child_ops): Added to_require_attach and to_require_detach fields
+ to the child_ops target ops vector.
+
+ * inftarg.c:
+ Some hacks for ttrace work
+ (child_wait): Additional local variables, additional code in
+ while loop to check for: Process exited, process forked,
+ process vforked, process execd
+ (child_thread_alive): John B. seems to think that the kill
+ call is inapproapriate for HPUX.
+ (child_attach_to_process): Using strtol rather than atoi.
+ no longer check for case where there is no known exec file.
+ (child_post_attach): New function, a default, a no-op
+ (child_insert_fork_catchpoint): New function, a default, a no-op
+ (child_remove_fork_catchpoint): New function, a default, a no-op
+ (child_create_catch_fork_hook): Deleted
+ (child_create_catch_vfork_hook): Deleted
+ (child_insert_vfork_catchpoint): New function, a default, a no-op
+ (child_remove_vfork_catchpoint): New function, a default, a no-op
+ (child_can_follow_vfork_prior_to_exec ):new function, a default,
+ a no-op
+ (child_insert_exec_catchpoint): New function, a default, a no-op
+ (child_remove_exec_catchpoint): New function, a default, a no-op
+ (child_has_execd): New function, a default, returns 0
+ (child_reported_exec_events_per_exec_call): New function, a
+ default, returns 1
+ (child_has_exited): New function, a default.
+ (child_core_file_to_sym_file): New function, a default, returns NULL.
+ (child_ops): Initialize new target_ops vector fields to the
+ child* functions.
+ * infptrace.c:
+ (Call_ptrace): For HPUX, handle additional requests: Pt_CONTIN1,
+ PT_STEP1.
+ (require_notification_of_events): Add several signals to the
+ set of events requiring notification: Ptrace_SIGNAL,
+ PTRACE_EXEC, PTRACE_FORK, PTRACE_VFORK
+ (child_acknowledge_created_inferior): This function is only
+ defined if CHILD_ACKNOWLEDGE_CREATED_INFERIOR is defined.
+ (child_post_startup_inferior): Function is only defined if
+ CHILD_POST_STARTUP_INFERIOR is defiend. Also, now call
+ require_notification_of_events.
+ (child_create_catch_fork_hook): Deleted
+ (child_create_catch_vfork_hook): Deleted
+ (child_insert_fork_catchpoint): New function
+ (child_remove_fork_catchpoint): New function
+ (child_insert_vfork_catchpoint): New function
+ (child_remove_vfork_catchpoint): New function
+ (child_has_forked): Now enclosed by a CHILD_HAS_FORKED ifdef
+ (child_has_vforked): Now enclosed by CHILD_HAS_VFORKED ifdef
+ (child_can_follow_vfork_prior_to_exec): New function
+ (child_insert_exec_catchpoint): New function
+ (attach): Removed call to require_notification_of_events
+ (child_post_attach): New function, call to
+ require_notification_of_events moved here.
+ (child_pid_to_exec_file): New enclosed by CHILD_PID_TO_EXEC_FILE ifdef
+ introduced the concept of a saved_inferior_pid
+ (hppa_require_attach): Add some code to decide if gdb is already
+ attached to process. Can not figure this out via a ptrace call.
+ (hppa_insert_hw_watchpoint): New function
+ (hppa_remove_hw_watchpoint): New function
+
+ * inftarg.c:
+ (child_attach_to_process): Change position in file
+ (child_detach_from_process): Change position in file
+
+ * inftarg.c:
+ (child_attach_to_process): Changed parameter to child_wait call
+
+ * inftarg.c:
+ (child_post_wait): New function declaration and definition
+ (ptrace_him):
+ - change return value to a void.
+ - change target_acknowledge_forked_child call to
+ target_acknowledge_created_inferior
+ - call target_post_startup_inferior rather than returning pid.
+ (child_attach_to_process): Change param name, fail_if_already_attached
+ -> after_fork.
+ Invert a couple of if-then-else statments.
+ Use REQUIRE_ATTACH macro
+ (child_attach): Change params in child_attach_to_process call
+ (child_require_attach): Change params in child_attach_to_process call
+ (child_detach_to_process): Change param name,
+ fail_if_already_attached -> after_fork.
+ Invert a couple of if-then-else statments.
+ Use REQUIRE_DETACH macro
+ (child_detach): Change params in child_detach_from_process call
+ (child_require_detach): Change params in child_detach_from_process
+ call
+ (child_post_startup_inferior): New function
+ (child_acknowledge_created_inferior): New function
+ (child_clone_and_follow_inferior): New function
+ (child_post_follow_inferior_by_clone): New function
+ (child_create_catch_fork_hook): New function
+ (child_create_catch_vfork_hook): New function
+ (child_has_forked): New function
+ (child_has_vforked): New function
+ (child_post_follow_vfork): New function
+ (child_stop): No longer a static function
+ (child_pid_to_exec_file): New function
+
+ * inftarg.c:
+ (child_wait): Child_pid becomes related pid. return pid
+ rather than inferior_pid. Changes are in code handling fork
+ and vfork
+
+ * inftarg.c:
+ Include gdb_stat.h and sys/unistd.h
+ (child_wait): New local variables. Check for live threads.
+ Check for syscall events
+ (child_thread_alive): No longer a static funct.
+ (ptrace_him): Remove some code inserted in snap3
+ (child_create_inferior): Added a bunch of code to handle a
+ bad interaction between start-up-with-shell and the HP
+ catch-fork/catch-exec logic. I am ifdefing this for
+ HPUXHPPA for now.
+ (child_has_syscall_event): New default target_ops function
+ (child_enable_exception_callback): New default target_ops function
+ (child_get_current_exception_event): New default target_ops function
+ (child_ops): 3 new fields
+
+ * inftarg.c: Remove HPUX_SNAP1 and HPUX_SNAP2 ifdefs
+
+ * inftarg.c: Reverted previous change.
+
+ * infttrace.c (hppa_remove_hw_watchpoint): Fix check for write
+ access hardware watchpoint.
+
+ * infttrace.c (proc_wait): Rename from proc_wait.
+
+ * infttrace.c (require_notification_of_exec_events): New function;
+ just notify of exec events, not all events, and just the specified
+ pid, don't include it's children.
+ (child_acknowledge_created_inferior): Call new function
+ require_notification_of_exec_events instead of
+ require_notification_of_events.
+ (child_post_startup_inferior): Call require_notification_of_events
+
+ * infttrace.c: Changed all references to boolean to int.
+ Changed all references to TRUE and FALSE to 1 and 0.
+
+ * irix5-nat.c (symbol_add_stub): Add params to call to
+ symbol_file_add.
+
+ * jv-lang.c (get_dynamics_objfile): Add 2 more parameters to call
+ to allocate_objfile.
+
+ * main.c (fputs_unfiltered): Changes to prevent cursor form
+ jumping around in the TUI. Altered where tuiTermUnsetup and
+ tuiTermSetup are called
+
+ * main.c (fputs_unfiltered): Changed function so that it
+ checks to see if output is to a string buffer or to a
+ FILE stream and does the correct action (i.e. strcat or
+ fputs). Fixed params for fputs call.
+
+ * main.c (fputs_unfiltered): Don't try to call the TUI's
+ CommandCharCount functions when the TUI isn't enabled.
+
+ * main.c (fputs_unfiltered): Change FILE to GDB_FILE.
+
+ * main.c (main): If the user gives the --version or --help flags,
+ disable the TUI.
+
+ * main.c (tui_version, xdb_commands, dbx_commands): New variables.
+ (main): New command line arguments --tui, --xdb, --dbx; add call
+ to tyiCleanUp via tuiDo to main loop.
+ (fputs_unfiltered): Tui related changes.
+
+ * main.c: Define 2 new global variables, gdb_stdout and gdb_stderr
+ of type GDB_FILE.
+ (main): Allocate space for and initialize gdb_stdout and gdb_stdin.
+
+ * objfiles.c (find_pc_sect_section): Make end condition be less
+ than s->endaddr, not less than or equal to s->endaddr.
+
+ * objfiles.c:
+ (allocate_objfile): 2 new parameters: User_loaded and is_solib.
+ When appropriate, record in the object file that it is user loaded.
+ The run command can use this information to purge object file
+ entries associated with the old inferior and keep user loaded
+ object files loaded via the add-symbol-file command.
+ (objfile_purge_solibs): New function. deletes all objectfile entries
+ that are not explicitly loaded by the user.
+
+ * objfiles.c:
+ (objfile_relocate): Check for LOC_INDIRECT
+ (find_pc_sect_section): Change condition from
+ pc < s->endaddr to pc <= s->endaddr
+
+ * objfiles.h:
+ New variables: User_loaded and is_solib
+ (OBJF_SHARED): New macro. used to distinguish objfile for
+ shared library from "vanilla" objfile.
+ (allocate_objfile): Add new parameters to function decl.
+ (objfile_purge_solibs): New function decl.
+
+ * objfiles.h: Add some typedefs: Importentry, ExportEntry.
+ Add some new variables: Import_list, import_list_size,
+ export_list, export_list_size
+
+ * osfsolib.c:
+ (symbol_add_stub): Added params to call to symbol_file_add
+
+ * pa/hpux1020.mh (NATDEPFILES): Add corelow.o, symbol table and
+ solib files.
+
+ * pa/hpux1100.mh (NAT_FILE): Use nm-hppah11.h.
+ (NATDEPFILES): Add symbol table and solib files.
+
+ * pa/nm-hppah11.h: New file, HPUX11-only definitions.
+
+ * pa/tm-hppa.h (proc_wait): Remove decl and macro.
+
+ * parse.c (write_dollar_variable): Handle cases in which variables
+ besides the debugger ones start with $ and $$.
+ (parse_nested_classes_for_hpacc): New function. Parse a string that
+ is possibly a namespace / nested class specification.
+ (find_template_name_end): New function.
+
+ * procfs.c:
+ (procfs_init_inferior): Return value is now a void.
+
+ * procfs.c (procfs_ops): Initializing new target ops vector fields. see list below.
+
+ * procfs.c:
+ (procfs_ops): Adding new target_ops vector fields and
+ removing a few. see list below
+
+ * procfs.c: Added new fields to procfs_ops.
+ Necessary since we still have oldstyle initialization in
+ this file
+
+ * pyr-tdep.c (pyr_do_registers_info): Change stdout to gdb_stdout.
+ (frame_locals_address): Change stderr to gdb_stderr.
+ (frame_args_addr): Ditto.
+
+ * pyr-xdep.c (fetch_inferior_registers): Change stderr to
+ gdb_stderr.
+
+ * serial.c (serial_close): Call gdb_fclose, not fclose on a
+ GDB_FILE.
+
+ * serial.c (serial_logchar): Change chtype to ch_type. sigh.
+
+ * solib.c (look_for_base): The parameter to file must be
+ of type FILE *. So cast exec_bfd -> iostream in the call
+ to fileno as a FILE *, not a GDB_FILE *. This will work because
+ exec_bfd -> iostream is declared and given a value in bdf and
+ bfd will continue to use FILE rather than GDB_FILE.
+
+ * solib.c:
+ (solib_add): Remove references to exec_ops.
+
+ * solib.c:
+ (solib_add): Update exec_ops.to_sections
+
+ * solib.c:
+ (symbol_add_stub): Added params to call to symbol_file_add
+
+ * solib.h:
+ (SOLIB_REMOVE_INFERIOR_HOOK): New macro. defined to 0.
+ functionality not implemented for this target.
+
+ * solib.h: Added macro definitions. These macros generate
+ error messages for solaris??
+ (SOLIB_CREATE_CATCH_LOAD_HOOK)
+ (SOLIB_CREATE_CATCH_UNLOAD_HOOK)
+ (SOLIB_HAVE_LOAD_EVENT)
+ (SOLIB_LOADED_LIBRARY_PATHNAME)
+ (SOLIB_HAVE_UNLOAD_EVENT)
+ (SOLIB_UNLOADED_LIBRARY_PATHNAME)
+ (SOLIB_IN_DYNAMIC_LINKER)
+ (SOLIB_RESTART)
+
+ * somread.c (is_in_import_list): Ditto.
+
+ * somread.c (som_symfile_read): Added some comments
+
+ * somread.c (som_symfile_read): Read in import and export lists.
+ (som_symtab_read): Change test for dynamic executable.
+ (is_in_import_list): New function. Check if a given symbol name
+ is in the import list.
+ (init_import_symbols): New function. Read in and initialize the
+ som import list.
+ (init_export_symbols): New function. Read in and initialize the
+ som export list.
+
+ * somread.c:
+ (som_symfile_read): Fix missing comment delimiters
+
+ * somsolib.c (DLD_FLAGS_MAPPRIVATE): New macro.
+ Define bit of __dld_flags in HP-UX a.out files.
+ (DLD_FLAGS_HOOKVALID): Ditto.
+ (DLD_FLAGS_LISTVALID): Ditto.
+ (DLD_FLAGS_BOR_ENABLE): Ditto.
+ (som_solib_total_st_size): Cumulative size in bytes of the
+ symbol tables of all shared objects on the so_list_head list.
+ (som_solib_st_size_threshhold_exceeded): Threshold for adding symbols
+ for shlibs.
+ (som_solib_sizeof_symbol_table): New function. Computes size of
+ symbol table for a shlib.
+ (som_solib_load_symbols): New function. Load symbols from shlib.
+ (som_solib_add): Detect if __dld_list is not valid.
+ Record main program's symbol table size.
+ Load symbols if called from command line.
+ Keep threshold into account when loading shlib symbols.
+ (som_solib_create_inferior_hook): Use dld_flags macros.
+ (som_sharedlibrary_info_command): Let user know if symbols were
+ not loaded.
+ (som_solib_restart): Discard all the shlibs descriptors.
+ (_initialize_som_solib): Chenge help message for auto-solib-add
+ command.
+ Set threshold for symbol table to 50 megabytes.
+
+ * somsolib.c (_initialize_som_solib): Added call to som_solib_restart.
+ (som_solib_restart): New function
+ (som_solib_in_dynamic_linker): New function
+ (som_solib_desire_dynamic_linker_symbols): New function
+ (som_solib_unloaded_library_pathname): New function
+ (som_solib_loaded_library_pathname): New function
+ (som_solib_library_pathname): New function
+ (som_solib_have_unload_event): New function
+ (som_solib_have_load_event): New function
+ (som_solib_create_catch_unload_hook): New function
+ (som_solib_create_catch_load_hook): New function
+ (som_solib_create_inferior_hook): Rewritten
+ dld_cache: New struct
+ addr_and_unwind_t: New struct
+ (find_unwind_entry) added prototype
+
+ * somsolib.c (som_solib_create_inferior_hook): Introduce new local
+ msymbol2 and change some msymbol's to msymbol2's -- was clobbering
+ msymbol, passing a NULL to lookup_minimal_symbol_solib_trampoline,
+ and ultimately core dumping with a SEGV.
+
+ * somsolib.c:
+ Include assert.h
+ (som_solib_mapped_entry): Additional comments for text_addr,
+ text_link_addr, text_end, and tsd_start_addr fields. Commenting
+ out 2 tsd fields, __data_start and __data_end.
+ (som_solib_add_solib_objfile): Add params to calls to symbol_file_add.
+ Add some code for distinguishing between a shared library and other
+ objfiles. This appears to be a prelude to thread local storage.
+ (som_solib_load_symbols): Changes to printf statement
+ enclosed by SOLIB_DEBUG ifdef.
+ (som_solib_add): Change comment to correctly specify path
+ to end.o -- /opt/langtools/lib/end.o. changes to printf statement
+ enclosed by SOLIB_DEBUG ifdef.
+ Removed several SOLIB_DEBUG ifdefs and the associated printfs.
+ Add code to find the start address for the object file's thread
+ local storage
+ (som_solib_create_inferior_hook): Fix warning messages use correct
+ path to end.o -- /opt/langtools/lib/end.o. Change control flow.
+ No longer user early returns from function is cases of error.
+ (reset_inferior_pid): New function
+ (som_solib_remove_inferior_hook): New function
+ (so_lib_thread_start_addr): New function. used for tsd.
+
+ * somsolib.c: Removed references to ASSERT macro.
+
+ * somsolib.c: Add debugging macro.
+ (struct som_solib_mapped_entry): Add new field tsd_start_addr.
+ (struct so_list): Added new field solib_addr.
+ (som_solib_add_solib_objfile): New function.
+ (som_solib_load_symbols): Rewritten.
+ (som_solib_add): Make sure we don't load the symbols in if the
+ threshold was exceeded.
+ (som_solib_get_solib_by_pc): New function. Return the address of
+ handle of the shared library.
+ (som_solib_restart): Disable breakpoints at restart.
+ (_initialize_som_solib): Set threshold to 100 megabytes.
+
+ * somsolib.c: Add include of fcntl.h so that O_RDONLY is defined.
+
+ * somsolib.h (DISABLE_UNSETTABLE_BREAK): New macro.
+ (PC_SOLIB): New macro.
+
+ * somsolib.h:
+ (SOLIB_CREATE_CATCH_LOAD_HOOK): Define
+ (SOLIB_CREATE_CATCH_UNLOAD_HOOK): Define
+ (SOLIB_HAVE_LOAD_EVENT): Define
+ (SOLIB_LOADED_LIBRARY_PATHNAME): Define
+ (SOLIB_HAVE_UNLOAD_EVENT): Define
+ (SOLIB_UNLOADED_LIBRARY_PATHNAME): Define
+ (SOLIB_IN_DYNAMIC_LINKER): Define
+ (SOLIB_RESTART): Define
+
+ * somsolib.h:
+ (SOLIB_REMOVE_INFERIOR_HOOK): New macro. defined to use
+ som_solib_remove_inferior_hook.
+
+ * somsolib.h:
+ (som_solib_create_catch_load_hook)
+ (som_solib_create_catch_unload_hook)
+ (som_solib_have_load_event)
+ (som_solib_loaded_library_pathname)
+ (som_solib_have_unload_event)
+ (som_solib_unloaded_library_pathname)
+ (som_solib_in_dynamic_linker)
+ Fix prototypes to use type names, not parameter names.
+
+ * source.c (find_source_lines): Make non static.
+ (open_source_file): Ditto.
+ (source_full_path_of): New function.
+ (print_source_lines): Rename to print_source_lines_base and make
+ static; formatting.
+ (print_source_lines): New function.
+ (forward_search_command): Tui changes.
+ (reverse_search_command): Tui changes.
+ (_initialize_source): Add xdb and dbx compatibility commands.
+
+ * source.c (list_command): Handle case of odd number of source
+ lines to display.
+
+ * source.c:
+ (source_full_path_of): New function. file was overlooked
+ in merge ;-/.
+
+ * stack.c (func_command): Make high bound be <, not <=.
+
+ * stack.c (_initialize_stack): For the backtrace command, delete
+ the help line about usage, since this has to be a valid help
+ message for the 'where' command too.
+
+ * stack.c (current_frame_command): Add a check for the
+ existance of a stack. If there is no stack produce an
+ error message and exit.
+
+ * stack.c (down_silently_base, up_silently_base,
+ args_plus_locals_info, print_frame_info_base,
+ print_stack_frame_base, print_stack_frame_base_stub): Declare.
+ (print_frame_local_vars): Add'l parameter.
+ (print_stack_frame_stub): New version created, old version renamed
+ to show_and_print_stack_frame_base_stub.
+ (print_stack_frame_base_stub, print_only_stack_frame_stub,
+ show_and_print_stack_frame, print_only_stack_frame,
+ stack_publish_stopped_with_no_frame, print_frame_info,
+ show_stack_frame, backtrace_full_command, args_plus_locals_info,
+ select_and_print_frame, select_and_maybe_print_frame,
+ current_frame_command, func_command): New functions.
+ (backtrace_command): New function, old renamed to
+ backtrace_command_1.
+ (print_block_frame_locals, print_frame_local_vars): Additional
+ parameter, number of tabs.
+ (up_silently_command): New function, old renamed to
+ up_silently_command_base.
+ (down_silently_command): New function, old renamed to
+ down_silently_base.
+ (_initialize_stack): Register new commands based on values of
+ xdb_commands and dbx_commands variables.
+
+ * stack.c (func_command): Make high bound be <, not <=.
+
+ * stack.c (parse_frame_specification): Fix prototype to match
+ function definition.
+ (show_and_print_stack_frame_stub): Fix name.
+ (select_and_print_frame): Change uncaught tuiDO call.
+
+ * stack.c (up_silent_base): Rename from up_silently_command_base.
+
+ * symfile.c (symbol_file_command): Only call SOLIB_RESTART if it's
+ defined.
+
+ * symfile.c (add_psymbol_with_dem_name_to_list): New function.
+ Adds a symbol with a long value to a psymtab. Differs from
+ add_psymbol_to_list in taking both a mangled and a demangled name.
+
+ * symfile.c (compare_psymbols): Call strcmp directly, instead of
+ using macro.
+
+ * symfile.c (symbol_file_add): Reindent portions.
+ (symbol_file_command): Add call to tuiDo.
+
+ * symfile.c (symbol_file_command): Only call SOLIB_RESTART if it's
+ defined.
+
+ * symfile.c (symfile_bfd_open): Add code to call PXDB on hpux, if
+ the file has not already been processed by pxdb.
+ Added define USE_PXDB.
+
+ * symfile.c (symfile_bfd_open): Change parenthesis positioning
+ around call to hpread_pxdb_check.
+
+ * symfile.c (symfile_bfd_open): Make not static.
+ (RESET_HP_UX_GLOBALS): New macro. Resets globals when new symbol
+ file loaded.
+ (USE_PXDB): Not needed. Removed.
+ (symbol_file_add): Add HP specific code to deal with pxdb.
+ (symbol_file_command): Reset HP specific globals if new symbol file
+ loaded.
+ (symfile_bfd_open): Comment out checking for pxdb.
+ (reread_symbols): Reset HP specific globals.
+
+ * symfile.c (symfile_bfd_open): Uncomment hpus specific code.
+
+ * symfile.c:
+ (symbol_file_add): Add user_loaded and is_solib parameters.
+ fixed number of parameters in call to allocate_objfile
+ (symbol_file_command): Added call to SOLIB_RESTART macro.
+ fixed number of parameters in calls to symbol_file_add.
+ (add_symbol_file_command): Fixed number of parameters in calls to
+ symbol_file_add.
+
+ * symfile.c: Added prototype for hpread_pxdb_check.
+
+ * symfile.c: Changed HPUX_SNAP1 ifdef to HPUXHPPA. enclosed calls to
+ RESET_HP_UX_GLOBALS with an HPUXHPPA ifdef
+
+ * symfile.h (symfile_bfd_open): Add protptype.
+
+ * symfile.h: Add prototype for add_psymbol_with_dem_name_to_list.
+
+ * symfile.h: Clarify purpose of auto_solib_add.
+
+ * symmisc.c (maintenance_print_symbols): Call gdb_fclose, not
+ fclose on a GDB_FILE* during cleanup.
+ (maintenance_print_psymbols): Call gdb_fclose, not fclose on a
+ GDB_FILE* during cleanup.
+ (maintenance_print_msymbols): Call gdb_fclose, not fclose on a
+ GDB_FILE* during cleanup.
+
+ * symmisc.c (maintenance_print_symbols): Gdb_fclose now takes a
+ GDB_FILE ** parameter. Fix the local GDB_FILE variables and the
+ call to make_cleanup.
+ (maintenance_print_psymbols): Ditto
+ (maintenance_print_msymbols): Ditto
+
+ * symmisc.c (print_objfile_statistics): Close quotes in
+ output strings.
+
+ * symmisc.c:
+ (Print_symbol): Add LOC_INDIRECT to switch statement
+ (print_partial_symbols): Add LOC_INDIRECT to switch statement
+
+ * symtab.c (find_pc_sect_psymtab): High bounds should be <, not <=.
+ (find_pc_sect_symtab): Ditto.
+
+ * symtab.c (hp_som_som_object_present): New flag to indicate HP
+ compiled code.
+ (find_pc_sect_psymtab): Change tests to make sure we are checking
+ the texthigh adress as well.
+ (lookup_transparent_type): New function. Look up a type name
+ in the struct_namespace. The type returned must not be opaque.
+ (find_pc_sect_symtab): Make sure we check the address 'pc' itself,
+ too.
+ (find_addr_symbol): Prepare to handle LOC_INDIRECT address class, but
+ leave it commented out.
+ (find_pc_sect_line): Return correct information if pc is in import
+ or export stub (trampoline).
+ (decode_line_1): Skip two chars, if they are '$$'. Like for HP's
+ $$dyncall. Handle cases in which varaible and function names can start
+ with $.
+ (overload_list_add_symbol): If cannot demangle name, use it as is.
+ Free string after use.
+ (make_symbol_overload_list): Initialize oload_name to NULL and
+ oload_name_len to 0. If demangle not successful, use name as it is.
+ Free string after use.
+
+ * symtab.c (lookup_symbol): Changed call to find_pc_sect_symtab,
+ to the original find_pc_symtab, in HP added fragment.
+
+ * symtab.c (lookup_symbol): Change HPUX_SNAP1 ifdef to a HPUXHPPA ifdef
+
+ * symtab.c (lookup_symbol): Ifdef the searching of symbol in the
+ minimal symbol tables, for hpux we move this check at the end
+ of the function.
+ Before we error out if symbol is not found in the symtab, look
+ in the statics.
+ Before erroring out if static symbol not found look in the globals.
+
+ * symtab.c (lookup_symbol): Return symbol as soon as found.
+ (decode_line_1): Check whether we have a conditional break. Temporarily
+ remove it from the line, to not confure perenthesis checking.
+ Handle namespaces.
+ (overload_list_add_symbol): New function. Overload
+ resolution support.
+ (make_symbol_overload_list): Ditto.
+
+ * symtab.c:
+ (find_template_name_end): New prototype decl.
+ (lookup_symbol): When a global or static symbol shows up in the
+ psymtab table, but not the symtab table, tell the user that
+ the symbol may be an inlined function or a template function and
+ provide some guidance to the user about how to more fully
+ specify the symbol.
+ (lookup_transparent_type): When a global or static symbol shows up
+ in the psymtab table, but not the symtab table, tell the user that
+ the symbol may be an inlined function or a template function and
+ provide some guidance to the user about how to more fully
+ specify the symbol.
+ (decode_line_1): Handle template function specification when decoding a
+ line. May need to be ifdefed for HP's aCC?
+ (_initialize_symtab): Handle dbx commands.
+
+ * symtab.h (address_class): Add new address calss for
+ LOC_THREAD_LOCAL_STATIC and LOC_INDIRECT.
+ (lookup_transparent_type): Add prototype.
+ (exception_event_kind): New enum for exception catchpoints.
+ (exception_event_record): New structure for exception catchpoints.
+ (CURRENT_EXCEPTION_KIND): New macro.
+ (CURRENT_EXCEPTION_CATCH_SAL): New macro.
+ (CURRENT_EXCEPTION_CATCH_LINE): New macro.
+ (CURRENT_EXCEPTION_CATCH_FILE): New macro.
+ (CURRENT_EXCEPTION_CATCH_PC): New macro.
+ (CURRENT_EXCEPTION_THROW_SAL): New macro.
+ (CURRENT_EXCEPTION_THROW_LINE): New macro.
+ (CURRENT_EXCEPTION_THROW_FILE) new macro.:
+ (Current_EXCEPTION_THROW_PC): New macro.
+
+ * symtab.h(make_symbol_overload_list): Add prototype.
+
+ * symtab.h:
+ (symbol_file_add): Add new params to function decl.
+
+ * target.c (cleanup_target): Changed casting of default functions for
+ to_has_forked, to_has_vforked, to_pid_to_exec_file to get rid of
+ warnings.
+
+ * target.c (cleanup_target): Changed the default functions for
+ to_pid_to_exec_file and to_core_file_to_sym_file
+
+ * target.c (cleanup_target): Fixed PARAMS for to_has_syscall_event
+
+ * target.c (cleanup_target): Syntax error, mismatched paranthesis.
+
+ * target.c:
+ (Default_clone_and_follow_inferior): New funct prototype declaration
+ and function definition
+ (dummy_target): More target_ops vector changes for HPUX
+ new fields. ifdefed for HPUX_SNAP2. New fields are
+ to_post_wait, to_post_startup_inferior
+ to_acknowledge_created_inferior, to_clone_and_follow_inferior,
+ to_post_follow_inferior_by_clone, to_create_catch_fork_hook,
+ to_create_catch_vfork_hook, to_has_forked, to_has_vforked,
+ to_post_follow_vfork, to_pid_to_exec_file
+ (de_fault): Add new HPUX specific target_ops operations to
+ the de_fault macro
+ (INHERIT): Add new HPUX specific target_ops operations to the
+ INHERIT macro
+ (find_default_clone_and_follow_inferior): New funct definition
+ (debug_to_post_wait): New funct
+ (debug_to_post_startup_inferior): New funct
+ (debug_to_acknowledge_created_inferior): New funct
+ (debug_to_clone_and_follow_inferior): New funct
+ (debug_to_post_follow_inferior_by_clone): New funct
+ (debug_to_create_catch_fork_hook): New funct
+ (debug_to_create_catch_vfork_hook): New funct
+ (debug_to_has_forked): New funct
+ (debug_to_has_vforked): New funct
+ (debug_to_post_follow_vfork): New funct
+ (setup_target_debug): Initialize new target_ops vector fields.
+
+ * target.c:
+ (Cleanup_target): Fixed the return type on a few of the
+ default function values.
+
+ * target.c:
+ (Dummy_target): Add 3 new fields
+ (nosupport_runtime): New function, used in cleanup_target
+ (cleanup_target): Changes in the de_fault macro, both to
+ accomodate the new target_ops vector fields and to use
+ more accurate default functions.
+ (update_current_target): Add new target_ops vector fields to the
+ INHERIT macro
+ (generic_mourn_inferior): The call to breakpoint_init_inferior now takes a
+ parameter
+ (normal_pid_to_str): Adding a \0 to the end of buf.
+ (debug_to_has_syscall_event): New func
+ (debug_to_enable_exception_callback): New func
+ (debug_to_get_current_exception_event): New func
+ (setup_target_debug): Initialize the 3 new target_ops vector fields
+
+ * target.c:
+ (Struct signals): Fix message associated with SIGRETRACT.
+
+ * target.c:
+ (Dummy_target): Fix syntax error
+ (cleanup_target): Changed the default values for the new
+ target_ops vector fields. HP folks inappropriately set
+ most of them to noprocess(). They should be a mixture
+ of ignore() and return_zero().
+
+ * target.c:
+ (Dummy_target): Add new target_ops vector fields and their initializations
+ (cleanup_target): Added new new target_ops vector fields to the de_fault
+ macro definition.
+ (update_current_target): Added new new target_ops vector fields to the INHERIT
+ macro definition
+ (return_one): New function, used by the de_fault macro
+ (debug_to_post_attach): New function
+ (debug_to_wait): Added new cases: Target_WAITKIND_FORKED, TARGET_WAITKIND_VFORKED,
+ TARGET_WAITKIND_EXECD
+ (debug_to_insert_fork_catchpoint): New function
+ (debug_to_remove_fork_catchpoint): New function
+ (debug_to_insert_vfork_catchpoint): New function
+ (debug_to_remove_vfork_catchpoint): New function
+ (debug_to_can_follow_vfork_prior_to_exec): New function
+ (debug_to_insert_exec_catchpoint): New function
+ (debug_to_remove_exec_catchpoint): New function
+ (debug_to_core_file_to_sym_file): New function
+ (setup_target_debug): Give new fields in current_target target_ops vector values.
+
+ * target.c: Hp merge, 4/15/98 snapshot
+ There are new target_ops fields that pertain only
+ to HPUX. All the changes relate to this. First,
+ new fields are added to the dummy_target target_ops
+ vector: To_require_attach, to_require_detach.
+
+ * target.c: Remove HPUX_SNAP1 and HPUX_SNAP2 ifdefs
+
+ * thread.c (info_threads_command): Call print_only_stack_frame
+ instead of print_stack_frame.
+ (_initialize_thread): Make t an alias for thread only if
+ xdb_commands is not set.
+
+ * thread.c (thread_command): If no arguments, don't generate an
+ error, instead tell the user which thread is current.
+ (info_threads_commands): Don't lose the users position within the
+ current thread -- remember it and then restore it.
+
+ * thread.c:
+ (struct thread_info): Add stepping_through_sigtramp field
+ (add_thread): Initialize stepping_through_sigtramp field
+ (load_infrun_state): Add stepping_through_sigtramp param and
+ make sure it gets assigned a value.
+ (save_infrun_state): Add stepping_through_sigtramp param and
+ make sure that the value gets saved.
+ (info_threads_command): Ifdefing some local variables and
+ code for HPUXHPPA. HP folks want print the tid rather than pid?
+ Also, looks like the HP folks solved the same thread switching
+ problem that 4.17 solves. Taking 4.17.
+ (restore_current_thread): Print out the current frame after
+ switching threads.
+ (thread_apply_all_command): Ifdefing a print statement for
+ HPUXHPPA. The HP folks want to print out a tid rather than pid?
+ (thread_apply_command): Ifdefing a print statement for
+ HPUXHPPA. The HP folks want to print out a tid rather than pid?
+ (thread_command): Decided not to take HP change.
+
+ * thread.c: Fixing gdb core dump problem causing many testsuite
+ failures.
+ (add_thread): Remove call to bpstat_clear, initialize
+ tp->stepping_through_solib_catchpoints = NULL;
+
+ * thread.c: Changes for catchpoints, shared libaries,
+ (thread_info): Additional fields in the thread_info struct
+ for stepping_through_solib_after_catch and
+ stepping_through_solib_catchpoints.
+ (add_thread): Initialize the new thread_info fields.
+ (load_infrun_state): Additional parameters for handling
+ catchpoints and shared libraries.
+ (save_infrun_state): Additional parameters for handling
+ catchpoints and shared libraries.
+
+ * top.c (command_loop): Initialize space_at_cmd_start to 0.
+ (set_prompt): New function.
+ (togglelist, stoplist): New command lists.
+ (command_loop): Tui changes -- paranoia to make sure
+ insert mode is off when not editing.
+ (quit_force): Clean up tui on exit.
+ (init_main): Make definition of info status command dependent upon
+ dbx mode not being set.
+ (fputs_unfiltered_hook): Changed stream parameter from FILE
+ to GDB_FILE
+ (flush_hook): Changed stream parameter from FILE to GDB_FILE
+
+ * top.h (set_prompt): Declare.
+
+ * typeprint.c (whatis_exp): Decide real runtime type. For the vtable
+ case.
+
+ * utils.c (query): Changes to prevent cursor from jumping around in the
+ TUI. Call tuiBufferGetc explicitly, rather than passing it
+ into tuiDo. The tuiDo function does some additional work
+ that is inappropriate when handling queries.
+ (GDB_FILE_ISATTY): New macro that takes a GDB_FILE param and
+ determines whether or not it's using a tty.
+ (gdb_file_isatty); called by the GDB_FILE_ISATTY macro. Does
+ the actual work
+ (init_page_info): Call GDB_FILE_ISATTY rather than ISATTY
+ (print_spaces): Fix parameter to fputc. fix call to
+ gdb_file_adjust_strbuf.
+ (gdb_file_init_astring): Fix parameter to xmalloc
+ (gdb_file_deallocate): New function to deallocate
+ a GDB_FILE object and possibly a string buffer
+ (gdb_file_init_astring): Initialize buffer as the empty
+ string. Indent GNU style.
+ (gdb_fopen): Gdb_fopen is called if the GDB_FILE object is
+ actually afile rather than astring. The routine now allocates space
+ for a GDB_FILE object and initializes its fields in addition to
+ performing an fopen.
+ (gdb_flush): Fix the parameter passed into fflush. It's now
+ stream->ts_filestream.
+ (gdb_fclose): Pass in an object of type GDB_FILE **. Fix parameter
+ to fclose. It's now tmpstream->ts_filestream. Make sure to free
+ the GDB_FILE object and set the GDB_FILE * object to NULL.
+ (gdb_adjust_strbuf): New function. Determine if the current
+ ts_strbuf field contains sufficient space to concatenate a string
+ of length n on the end. If not, then reallocate the ts_strbuf.
+ (print_spaces): Check to see if the GDB_FILE is afile or
+ astring. If it is astring, then adjust the size of the ts_strbuf
+ field and concatenate the correct number of spaces onto the end of
+ the buffer. Otherwise continue to use fputc.
+ (gdb_file_get_strbuf): New function. return a ptr to the ts_strbuf
+ field in a GDB_FILE object.
+ (gdb_file_init_astring): New function to allocate space for and
+ initialize a GDB_FILE object when it is an astring.
+ (set_width): Declare it.
+ (pagination_enabled): Define it.
+ (query): Tui changes.
+ (init_page_info, set_width): New functions.
+ (set_width_command): Call set_width.
+ (_initialize_utils): Replace termcap stuff with call to
+ init_page_info; if xdb_commands set, define am and sm commands;
+ define pagination as a set/show command.
+ (vfprintf_maybe_filtered): Change FILE to GDB_FILE.
+ (fputs_maybe_filtered): Ditto.
+ (print_spaces): Ditto.
+ (gdb_printchar): Ditto.
+ (gdb_flush): Ditto.
+ (fputs_filtered): Ditto.
+ (vfprintf_filtered): Ditto.
+ (vfprintf_unfiltered): Ditto.
+ (fprintf_filtered): Ditto.
+ (fprintf_unfiltered): Ditto.
+ (fprintfi_filtered): Ditto.
+ (print_spaces_filtered): Ditto.
+ (fprintf_symbol_filtered): Ditto.
+ (gdb_fclose): New function.
+
+ * valops.c (call_function_by_hand): Assign to param_type only
+ if function has parameters.
+
+ * valops.c (call_function_by_hand): Ifdef the
+ HP_COMPILED_TARGET stuff.
+ (value_arg_coerce): Ditto.
+
+ * valops.c (call_function_by_hand): Make sure param_type is
+ initialized to NULL.
+
+ * valops.c (find_rt_vbase_offset): Add parameter to value_at.
+ (value_rtti_type): Ditto.
+ (value_full_object): Ditto.
+
+ * valops.c (search_struct_field_aux): Fixed mismatching parenths
+
+ * valops.c (search_struct_field_aux): Make sure TYPE_TAG_NAME
+ is not null before copying it.
+
+
+ * valops.c (search_struct_field_aux): Set found_class_name to null
+ if class has no name (anon unions case). Adjust base_addr
+ computation.
+
+ * valops.c (value_arg_coerce): Change final arg to int.
+
+ * valops.c (value_arg_coerce): Remove the conditional on HP
+ compiled target, for doing coercion of float to double. Removed
+ third parameter, using_gcc.
+ (call_function_by_hand): Do not use HP_COMPILED_TARGET, just
+ use the gcc_compiled variable.
+
+ * valops.c (value_cast): Take case of the enclosing_type and
+ pointer_to_offset fields.
+ (value_at): Use VALUE_CONTENTS_ALL_RAW
+ (value_fetch_lazy): Ditto
+ (value_assign): Handle enclosing_type, embedded_offset and
+ pointed_to_offset fields.
+ (value_repeat): Use VALUE_CONTENTS_ALL_RAW and VALUE_ENCLOSING_TYPE.
+ (value_ind): Set enclosing_type and embedded_offset correctly,
+ for a pointer value being dereferenced. Target memory bytes
+ corresponding to the size of the enclosing type are retreived.
+ (value_addr): Handle enclosing_type and pointed_to_offset.
+ (value_push): Use VALUE_CONTENTS_ALL and VALUE_ENCLOSING_TYPE.
+ (value_arg_coerce): Coerce floats to doubles only if gcc was not
+ used to compile the target.
+ (call_function_by_hand): Handle pointers to functions as paramters.
+ (value_array): Use VALUE_CONTENTS_ALL and VALUE_ENCLOSING_TYPE.
+ (search_struct_method): Produce more informative error message.
+ (find_rt_vbase_offset): Deal with negative offsets.
+ (value_find_oload_method_list): New function. Return the list of
+ overloaded methods of a specified name.
+ (find_method_list): New function. Search through the methods of an
+ object (and its bases) to find a specified method.
+ (value_full_object): New function. Given a value, check its real
+ run-time type.
+ (value_rtti_target_type): New function. Given a pointer value V, find
+ the real (RTTI) type of the object it points to.
+ (value_rtti_type): New function. Find the real run-time type of a
+ value using RTTI.
+
+ * valops.c: Include gdbcmd.h
+ Set global overload_resolution to 0.
+ (find_function_in_inferior): Modify error message.
+ (value_allocate_space_in_inferior): Modify error message.
+ (value_cast): Deal with HP/aCC peculiarities.
+ (value_of_variable): Use SYMBOL_SOURCE_NAME instead of SYMBOL_NAME.
+ (value_addr): Modify address value by adding the embedded offset.
+ (value_ind): Modify the address of the object by the pointed_to_offset.
+ (call_function_by_hand): Do not do any extra alignment if not needed.
+ Fetch the return value from the stack rather then from the register,
+ for the hppa architecture.
+ (search_struct_field): Rewritten. Now this function uses
+ search_struct_field_aux to do all the work.
+ (search_struct_field_aux): New function. This is the old
+ search_struct_field rewritten.
+ (find_rt_vbase_offset): Give error if virtual table pointer is not good.
+ (find_overload_match): New function. Find the best function that
+ matches on the argument types according to the overload resolution
+ rules.
+ (_initialize_valops): Add new set/show command for overload-resolution.
+
+ * value.h (VALUE_POINTED_TO_OFFSET): New macro.
+ Add field pointed_to_offset to value structure.
+ Add prototypes for new functions in valops.c.
+
+ * value.h (write_register_pid): Change prototype to match
+ function.
+
+ * value.h: Hp merge, 4/15/98 snapshot
+ Added parameter to val_print func decl.
+ Added new macro, VALUE_EMBEDDED_OFFSET, and
+ new func decl, find_rt_vbase_offset, for C++
+ support.
+
+ * values.c (allocate_value): Allocate also for value_embedded_offset
+ and value_enclosing_type.
+ (value_copy): Copy value_embedded_offset and value_enclosing_type too.
+ Use all_raw in copying the value itself.
+ (value_primitive_field): Add handling of base subobjects.
+
+ * values.c (value_copy): Copy the pointed_to_offset as well.
+ (allocate_value): Allocate the pointed_to_offset as well.
+ (value_virtual_fn_field): Rewrite.
+
+ * values.c (value_primitive_field): Adjust embedded offset and
+ offset calculation.
+
+ * values.c (value_static_field): Take into consideration that static
+ data members can be minimal symbols too.
+
+ * values.c (value_virtual_fn_field): Fix call to value_at.
+
+ * win32-nat.c (handle_load_dll): Added params to call to symbol_file_add.
+
+ Other changes have to do with XDB compatability. Leave oout
+ for now.
+
+ defs.h (vfprintf_filtered): Change FILE to GDB_FILE in decl.
+ (fprintf_filtered): Ditto.
+ (fprintfi_filtered): Ditto.
+ (vfprintf_unfiltered): Ditto.
+ (fprintf_unfiltered): Ditto.
+
+ infcmd.c (_initialize_infcmd): If xdb_commands is set, make S an
+ alias for next and define R, lr, g. Define go.
+
+ pyr-tdep.c (pyr_print_insn): Change FILE to GDB_FILE.
+
+
+ * breakpoint.c (create_temp_exception_breakpoint): #If it out --
+ nothing calls it.
+ (bpstat_stop_status): Don't call SOLIB_HAVE_LOAD_EVENT if it's not
+ defined; don't call SOLIB_HAVE_UNLOAD_EVENT if it's not defined.
+ (bpstat_get_triggered_catchpoints): If we don't have shared
+ library support, then don't call SOLIB_LOADED_LIBRARY_PATHNAME nor
+ SOLIB_UNLOADED_LIBRARY_PATHNAME.
+ (watch_command_1): Don't require a run before a watch command
+ unless we're on HP [it's an HP OS bug, not a generic limitation]
+ (catch_load_command_1): Don't define if no shared libraries.
+ (catch_command_1): Don't claim to support fork catchpoints unless
+ CHILD_INSERT_FORK_CATCHPOINT is defined, don't claim to support
+ vfork catchpoints unless CHILD_INSERT_VFORK_CATCHPOINT is defined,
+ don't clain to support shared library load catchpoints if shared
+ libraries aren't supported, and don't claim to support exec
+ catchpoints unless CHILD_INSERT_EXEC_CATCHPOINT is defined
+
+ There are new target_ops vector fields that pertain
+ only to HPUX. Added the to_require_attach and
+ to_require_detach fields to exec_ops. These new
+ fields are ifdef'ed for HPUX_SNAP1.
+
+ * breakpoint.h:
+ Fix compile error in enum bptype.
+
+ * coff-solib.h:
+ Fixed a number of macro definitions. SOLIB_LOADED_LIBRARY_PATHNAME,
+ SOLIB_HAVE_LOAD_EVENT, SOLIB_HAVE_UNLOAD_EVENT,
+ SOLIB_UNLOADED_LIBRARY_PATHNAME, SOLIB_IN_DYNAMIC_LINKER. These
+ macros are only meaningful (for now) for SOM. So, all
+ the macros were defined as error(...), but were used in
+ conditions. This caused the compile to crap out. I redefined
+ these (for now) to be 0.
+
+ * procfs.c:
+ (procfs_create_inferior): Fix call to fork_inferior -- need another
+ parameter.
+
+ * solib.h:
+ Fixed a number of macro definitions. SOLIB_LOADED_LIBRARY_PATHNAME,
+ SOLIB_HAVE_LOAD_EVENT, SOLIB_HAVE_UNLOAD_EVENT,
+ SOLIB_UNLOADED_LIBRARY_PATHNAME, SOLIB_IN_DYNAMIC_LINKER. These
+ macros are only meaningful (for now) for SOM. So, all
+ the macros were defined as error(...), but were used in
+ conditions. This caused the compile to crap out. I redefined
+ these (for now) to be 0.
+
+ * valops.c:
+ (search_struct_field): Undeclared local variable, "assigned".
+ (find_rt_vbase_offset): Fixed call to value_at
+
+ * value.h: Fix signature for find_rt_vbase_offset funct decl
+ (missing a param)
+
+Wed Dec 30 17:48:12 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ From J.T. Conklin <jtc@redbacknetworks.com>:
+ * i386-stub.c: Fix error string in last change.
+
+1998-12-30 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * utils.c: <Readline/readline.h> instead of "readline/readline.h".
+
+ * configure.in (TERM_LIB): Search for the appropriate term library
+ on the host system.
+ * configure: Regenerated.
+ * Makefile.in (TERMCAP): Set based on autoconf check.
+ * config/*/*.mh: Don't override TERMCAP setting.
+
+Wed Dec 30 17:23:14 1998 Mark Alexander <marka@cygnus.com>
+
+ * value.c (value_virtual_fn_field): Handle the situation where
+ vtbl is a pointer to a structure instead of a pointer to an array.
+
+Mon Dec 28 17:43:36 1998 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by Jim Blandy <jimb@cygnus.com>,
+ Edith Epstein <eepstein@cygnus.com>, Elena Zannoni
+ <ezannoni@cygnus.com> Stan Shebs <shebs@cygnus.com>, and David
+ Taylor <taylor@cygnus.com>, as part of the project to merge in
+ changes originally made by HP; HP did not create ChangeLog
+ entries.
+
+ * c-lang.h (cp_print_value_fields): Update prototype; fixed
+ prototype decl for c_val_print function -- it needed an
+ embedded_offset param; fixed prototype of cp_print_value_fields.
+ Include value.h.
+ (C_LANG_H): Define.
+
+ * c-valprint.c (c_val_print): Add new parameter embedded_offset.
+ Add embedded_offset to valaddr in function calls. fix calls to
+ val_print, and cp_print_value_fields. Attempt to determine the
+ real type of the object to be printed. fixed call to
+ cp_print_value_fields. process TYPE_CODE_METHOD as well. moved
+ call to check_typedef out of conditional. add embedded offset
+ param to val_print call.
+
+ (c_value_print): Add new parameter to call to val_print. Handle
+ pointer to class case. Ensure that const char *, const unsigned
+ char * come out without the type but the volatile variants and the
+ signed variants don't.
+
+ * ch-lang.h (chill_val_print): Add parameter to decl.
+
+ * ch-valprint.c: The various print routines have an additional
+ parameter. Currently, the new parameter is only used when printing
+ C++ expressions. So, in ch-valprint.c, the new parameter is always
+ 0. Changes in calls to val_print, chill_val_print, c_val_print
+ Affected functions are chill_val_print_array_elements,
+ chill_val_print, chill_print_value_fields, chill_value_print.
+
+ * cp-valprint.c add vtable pointers names for aCC (HP) compiler.
+ (cp_print_class_method): Print message for HP/aCC case.
+ (cp_print_class_member): Add comments.
+ (cp_print_value): Adjust address computations for virtual base
+ classes. add new parameter 'offset'. Find correct offset for
+ base class in HP/aCC case. Change call to cp_print_value_fields
+ to have extra par.
+ (cp_print_value_fields): Do not print also if the only field is
+ the vtable pointer. Print out vtable ptr, for HP/aCC compiled
+ case. do not print leading '=' in case of anonymous union, or
+ struct. add new parameter 'offset'. Do not print the vtable
+ pointer as a member, in the HP aCC case. Changed calls to
+ val_print to have extra parameter.
+ (cp_print_hpacc_virtual_table_entries): New function. Print vtable
+ entries, in HP/aCC compiled case.
+ (cp_print_static_field): Change call to cp_print_value_fields, and
+ val_print.
+
+ * d30v-tdep.c (d30v_print_register): Add embedded_offset param
+ to val_print call.
+
+ * defs.h: Additional include files included when TUI is defined.
+ (gdb_file_isatty): New function decl.
+ (GDB_FILE): If TUI is defined, define a structure rather
+ than making this an alias for FILE.
+ (gdb_stdout, gdb_stderr): If TUI is defined, then define these
+ as pointers to variables of type GDB_FILE rather than making them
+ be aliases for stdout and stderr.
+ (TUIDO): Add definition conditionalized on definition
+ (or lack thereof) of TUI.
+ (command_class): Add two additional values.
+ (precision_type): New enum.
+ (gdb_fclose): Add decl.
+ (store_address): Change prototype to match function.
+ (tui_version, xdb_commands, dbx_commands): Add decls.
+ (gdb_file_deallocate): New function decl
+ (pa_do_strcat_registers_info): New function decl.
+ (streamtype): New enumerated type to distinguish between output to
+ a FILE and output to a buffer.
+ (tui_stream): New struct type, named GDB_FILE.
+ (gdb_stdout): Of type GDB_FILE, will pass this around gdb rather
+ than stdout.
+ (gdb_stderr): Of type GDB_FILE, will pass this around gdb rather
+ than stderr.
+ (fputs_unfiltered_hook): Change stream parameter from FILE to
+ GDB_FILE.
+ (flush_hook): Change stream parameter from FILE to GDB_FILE.
+ (gdb_fclose): Fix decl for gdb_fclose; parameter is now of
+ type GDB_FILE **.
+ (gdb_file_adjust_strbuf): New function decl. function lives
+ in utils.c.
+ (gdb_file_init_astring): New function decl. function lives
+ in utils.c.
+ (gdb_file_get_strbuf): New function decl. function lives in
+ utils.c.
+ (source_full_path_of): Declare.
+
+ * exec.c (_initialize_exec): Make definition of file command be
+ dependent upon dbx_commands not being set.
+ (exec_file_attach): New function.
+ (exec_file_command): Call it.
+ (exec_ops): Add new target vector fields.
+
+ * f-lang.h (f_print_type): Change FILE to GDB_FILE in decl.
+ (f_val_print): Ditto.
+ (f_val_print): Add parameter to the function decl.
+
+ * f-valprint.c (_initialize_f_valprint): If xdb_commands is set,
+ define lc command.
+ (f77_create_arrayprint_offset_tbl): Change FILE to GDB_FILE.
+ (f77_print_array): Ditto.
+ (f77_print_array_1): Ditto.
+ (f_val_print): Ditto.
+ (f_val_print): Add a parameter; this new parameter is currently
+ only non-zero when handling C++ expressions. In this file its
+ value is always 0. changed fflush to gdb_flush.
+
+ * gnu-nat.c: (init_gnu_ops): Add new target vector fields.
+ (gnu_create_inferior): Add param to fork_inferior call.
+
+ * hppa-tdep.c (after_prologue): If f is NULL, don't dereference
+ it. if no debug info, return zero telling caller that we need to
+ find the end of the prologue via the hard way (instruction
+ examination).
+ (find_unwind_entry): Avoid dereferencing a null
+ pointer.
+ (hppa_pid_to_exec_file): Deleted -- no longer used.
+ (hppa_prepare_to_proceeed): Add prototype.
+ (read_unwind_info): Purecov comments, bug fixes.
+ (find_unwind_entry): Purecov comments, bug fixes.
+ (find_stub_with_shl_get): Purecov comments.
+ (frame_chain): Additional parens.
+ (hppa_push_arguments): Changes to commented out version of routine.
+ (hppa_fix_call_dummy): Purecov comments, fix location of end.o.
+ (in_solib_call_trampoline): Purecov comments.
+ (in_solib_return_trampoline): Purecov comments.
+ (setup_d_pid_in_inferior): Fix location of end.o.
+ (initialize_hp_cxx_exception_support): Fix location of end.o.
+ (child_enable_exception_callback): Purecov comments.
+ (pa_do_strcat_registers_info): Has a new parameter, precision,
+ which is passed into the call to pa_strcat_fp_reg to indicate
+ whether to display the floating point registers using
+ single or double preceision.
+ (pa_strcat_registers): Introduce local variable, precision, and
+ pass it into call to pa_strcat_fp_reg.
+ (pa_strcat_fp_reg): Modified function. New parameter, precision,
+ used by function to decide whether to use single or double
+ precision. Also add the code to put a double precision value
+ into a buffer.
+ (pa_do_strcat_registers_info): New routine. called by
+ tui/tuiRegs.c:_tuiRegisterFormat to place a register name
+ and value into a string buffer. Interface may change in
+ future. Checking this in so that we have something
+ functional for HP.
+ (pa_strcat_registers): New routine, called by
+ pa_do_strcat_registers_info. Does same thing as
+ pa_print_registers except it takes a stream parameter.
+ This routine should disappear in future. Checking in
+ so that we have something functional to give HP
+ (pa_strcat_fp_reg): New routine, called by
+ pa_do_strcat_registers_info and pa_strvat_registers
+ to place a floating point register name and value into
+ a buffer. This interface may change in future.
+ Checking in so that we have something functional to give HP.
+ (pa_print_fp_reg): Change prototype to match def'n.
+ (pa_register_look_aside): Fix comment immediately before function.
+ Changes to better support stack unwinding, reading and writing
+ registers for HPUX. New includes ptrace.h, bfd.h, dl.h.
+ (internalize_unwinds): Initialize new fields in table.
+ (read_unwind_info): Entries in the table are now more complex
+ structures. References of the form ...->table[index].stub_type are
+ now ...->table[index].stub_unwind.stub_type.
+ (find_proc_framesize): Add a check for pc == 0.
+ (rp_saved): Entries in the table are now more complex
+ structures. References of the form ...->table[index].stub_type are
+ now ...->table[index].stub_unwind.stub_type.
+ (frameless_function_invocation): Stub_type becomes
+ stub_unwind.stub_type
+ (saved_pc_after_call): Stub_type becomes stub_unwind.stub_type
+ (hppa_frame_saved_pc): Stub_type becomes stub_unwind.stub_type
+ (frame_chain_valid): Stub_type becomes stub_unwind.stub_type
+ (hppa_call_dummy): Stub_type becomes stub_unwind.stub_type
+ (pa_print_fp_reg): Additional params to call val_print
+ (in_solib_call_trampoline): Stub_type becomes
+ stub_unwind.stub_type
+ (in_solib_return_trampoline): Stub_type becomes
+ stub_unwind.stub_typ
+ (skip_trampoline_code): Additional code to handle external
+ dyncalls. Also stub_type becomes stub_unwind.stub_type
+ (hppa_pid_to_exec_file): New funct. FOr HPUX 10.0 and beyond there
+ is an explicit ptrace request for getting the pathname associated
+ with a process id (pid).
+ (hppa_pid_to_exec_file): Remove unwanted param from call to
+ call_ptrace.
+ (args_for_find_stub): New structure.
+ (find_unwind_entry): Deal with null input pc value.
+ (rp_saved): Ditto.
+ For the import stub, return -24 always.
+ (hppa_frame_saved_pc): Save old pc value, to detect we are in a loop.
+ (init_extra_frame_info): Use TARGET_READ_FP.
+ (frame_chain): Include thread support.
+ If the caller's pc is zero, we lose and return, just like stack
+ bottom.
+ Disable warning about being unable to find unwind info.
+ (hppa_push_arguments): Rewrite.
+ (hppa_value_returned_from_stack): New function. Handles returning
+ a value larger than 64 bits, stored on the stack.
+ (find_stub_with_shl_get): New function. To look up symbols in shlibs.
+ (cover_find_stub_with_shl_get): New function. Cover routine for
+ find_stub_with_shl_get to pass to catch_errors.
+ (hppa_fix_call_dummy): Comment out old stub mechanism.
+ Rewrite using dyncall.
+ (target_read_fp): New function.
+ (pa_do_registers_info): Floating point registers start at FP4.
+ (pa_print_registers): Use FP4_REGNUM instead of 72.
+ (skip_trampoline_code): Do machine instruction matching for PA2.0.
+ (setup_d_pid_in_inferior): New function. Exception handling support.
+ (initialize_hp_cxx_exception_support): Ditto.
+ (child_enable_exception_callback): Ditto.
+ (child_get_current_exception_event): Ditto.
+
+ * hpux-thread.c (hpux_thread_ops): Add new target vector fields.
+
+ * infcmd.c: Include objfiles.h.
+ (attach_command): New local variable, exec_file, add code to
+ determine exec_file from pid if exec_file is not already known,
+ call new target operation, target_post_attach -- a no-op unless
+ on HPUXHPPA.
+ (detach_command): After detaching, do a SOLIB_RESTART.
+ (objfiles.h): Fix typo on include line.
+ (run_command): Only call SOLIB_RESTART if it's defined.
+ (detach_command): Ditto.
+ (run_command): If program has already been started, and decide
+ to restart it, the kill the target, flush the caches,
+ call init_wait_for_inferior. Also purge old solib objfiles.
+ (run_stack_dummy): Add calls to
+ disable_watchpoints_before_interactive_call_start and
+ enable_watchpoints_after_interactive_call_stops.
+ (finish_command): Alter code handling the evaluation and printing
+ of the target function's return value.
+ (attach_command): When given a pid, but no exec file, try to
+ determine the exec file from the process. If the process does not
+ record a full path name, try to qualify the filename against the
+ source path.
+ (_initialize_infcmd): Add some verbiage about how to use the
+ attach command.
+ (do_registers_info): Changed calls to val_print
+ made the symfile.h include preceed the
+ objfiles.h include. The other ordering caused a
+ compile problem (incompletely defined types).
+
+ * inftarg.c (child_post_attach): Fix decl, make static.
+ (proc_wait): Make globally visible.
+ (child_insert_fork_catchpoint, etc): Fix return type.
+ (child_detach_from_process): Declare.
+ (child_attach_to_process): Declare.
+ (child_stop): Make static to match decl.
+ (ptrace_him): Change prototype back to return int.
+ (ptrace_me): Remove debug output, pass NULL to fork_inferior if
+ not HPUX.
+ (proc_wait): function prototype and definition are enclosed by
+ proc_wait ifndef
+ (child_attach_to_process): New function, does most of the work
+ that child_attach used to do and some additional work to determine
+ whether gdb is already attached to the target how to react.
+ (child_attach): Altered. It's now a wrapper for
+ child_attach_to_process.
+ (child_require_attach): New function, called if should attach even
+ when gdb is already attached to target.
+ (child_detach_from_process): New function, does most of the work
+ that child_detach used to do and some additional work to determine
+ whether gdb is currently attached to the target.
+ (child_detach): Altered. It's now a wrapper for
+ child_detach_from_process.
+ (child_require_detach): New function, called if should try to
+ detach even when gdb is not attached to target.
+ (ptrace_him): Calls a new function,
+ target_acknowledge_forked_child. Currently,
+ target_acknowledge_forked_child, is only defined to do something
+ for HPUX.
+ (child_create_inferior): Changed call to fork_inferior.
+ (child_ops): Add to_require_attach and to_require_detach fields
+ to the child_ops target ops vector.
+ Some hacks for ttrace work:
+ (child_wait): Additional local variables, additional code in
+ while loop to check for process exited, process forked,
+ process vforked, process execd.
+ (child_thread_alive): John B. seems to think that the kill
+ call is inapproapriate for HPUX.
+ (child_attach_to_process): Using strtol rather than atoi.
+ no longer check for case where there is no known exec file.
+ (child_post_attach): New function, a default, a no-op.
+ (child_insert_fork_catchpoint): New function, a default, a no-op.
+ (child_remove_fork_catchpoint): New function, a default, a no-op.
+ (child_insert_vfork_catchpoint): New function, a default, a no-op.
+ (child_remove_vfork_catchpoint): New function, a default, a no-op.
+ (child_can_follow_vfork_prior_to_exec ):new function, a default,
+ a no-op.
+ (child_insert_exec_catchpoint): New function, a default, a no-op.
+ (child_remove_exec_catchpoint): New function, a default, a no-op.
+ (child_has_execd): New function, a default, returns 0.
+ (child_reported_exec_events_per_exec_call): New function, a
+ default, returns 1.
+ (child_has_exited): New function, a default.
+ (child_core_file_to_sym_file): New function, a default, returns NULL.
+ (child_ops): Initialize new target vector fields.
+
+ * jv-lang.h: (Java_val_print): Add embedded_offset param to func
+ decl.
+
+ * jv-valprint.c: Changing calls to val_print to accomodate new param.
+ (java_value_print): Add embedded_offset param to val_print call
+ (java_print_value_fields): Add embedded_offset param to val_print
+ call.
+ (java_val_print): Add embedded_offset param. alter call to
+ c_val_print to accomodate embedded_offset param.
+
+ * language.c (lang_bool_type): Return builtin_type_bool in c++
+ case.
+ (unk_lang_val_print): Add embedded_offset param to
+ prototype decl and definition.
+
+ * language.h (LA_VAL_PRINT macro, la_val_print function decl):
+ altered to accomodate the new parameter to the various print
+ functions.
+
+ * m2-lang.h (m2_val_print): Add a parameter to the function decl.
+
+ * m2-valprint.c (m2_val_print): Add a parameter.
+ This parameter is currently only used when evaluating C++
+ expressions. So, it is always 0 in this file.
+
+ * m3-nat.c (m3_create_inferior): Add param to fork_inferior call
+ (m3_pid_to_exec_file): New function
+ (m3_ops): Add new target vector fields.
+
+ * mac-nat.c (init_child_ops): Add new target vector fields.
+
+ * mips-tdep.c: Chnages to accomodate additional parameter
+ to val_print.
+ (mips_print_register): Alter calls to val_print
+
+ * monitor.c (monitor_write): Change stderr to gdb_stderr.
+ (monitor_remove_breakpoint): Ditto.
+ (init_base_monitor_ops): Add new target vector fields.
+
+ * ppc-bdm.c (init_bdm_ppc_ops): Add new target vector fields.
+
+ * printcmd.c (do_examine): When saving a value_ptr, remove it from
+ the list of value_ptr's to be freed automatically; when discarding
+ a previously saved value_ptr, free it.
+ (print_formatted): Update comments; add new comments.
+ (printf_command, print_insn): Purecov comments.
+ (_initialize_printcmd): Add assign as a command if dbx_commands is
+ set; create va as an alias for disassemble if xdb_commands is set.
+ (address_info): New cases LOC_INDIRECT and
+ LOC_THREAD_LOCAL_STATIC.
+ (display_command): If tui_version and exp starts with a '$', then
+ don't display it unless tui_vSetLayoutTo fails.
+ (disassemble_command): Add tuiDo calls.
+ (print_scalar_formatted): For integers that are long long, check
+ the print format and print out in binary octal, decimal, or
+ hex. Call the new print_*_chars functions in valprint.c
+ (print_frame_args): Altered calls to val_print, to reflect
+ additional parameter to val_print (case LOC_BASEREG_ARG).
+
+ * procfs.c: (Procfs_init_inferior): Return value is now a void.
+ (procfs_ops): Add new target vector fields.
+ (procfs_create_inferior): Fix call to fork_inferior -- need another
+ parameter.
+
+ * remote-adapt.c (adapt_open): Change stderr to gdb_stderr.
+ (adpat_insert_breakpoint): Ditto.
+ (init_adapt_ops): Add new target vector fields.
+
+ * remote-array.c (array_wait): Change fflush to gdb_flush and
+ stdout to gdb_stdout.
+ (init_array_ops): Add new target vector fields.
+
+ * remote-bug.c (bug_load): Change fflush to gdb_flush; stdout to
+ gdb_stdout.
+ (bug_wait): Change stderr to gdb_stderr.
+ (bug_insert_breakpoint): Ditto.
+ (init_bug_ops): Add new target vector fields.
+
+ * remote-e7000.c
+ (init_e7000_ops): Add new target vector fields.
+ * remote-eb.c (init_eb_ops): Ditto.
+ * remote-es.c (init_es1800_ops): Ditto.
+ (init_es1800_child_ops): Ditto.
+ * remote-es.c (init_es1800_ops): Ditto.
+ (init_es1800_child_ops): Ditto.
+ * remote-hms.c (init_hms_ops): Ditto.
+ * remote-hms.c (init_hms_ops): Ditto.
+ * remote-nindy.c (init_nindy_ops): Ditto.
+ * remote-nrom.c (init_nrom_ops): Ditto.
+ * remote-os9k.c (init_rombug_ops): Ditto.
+ * remote-rdp.c (init_remote_rdp_ops): Ditto.
+ * remote-sds.c (init_sds_ops): Ditto.
+ * remote-sim.c (init_gdbsim_ops): Ditto.
+ * remote-st.c (init_st2000_ops): Ditto.
+ * remote-udi.c (init_udi_ops): Ditto.
+ * remote-vx.c (init_vx_ops): Ditto.
+ (init_vx_run_ops): Ditto.
+ * remote-vx.c: (Init_vx_ops): Ditto.
+ (init_vx_run_ops): Ditto.
+
+ * remote-mips.c (mips_getstring): Change stderr to gdb_stderr.
+ (pmon_insert_breakpoint): Ditto.
+ (pmon_remove_breakpoint): Ditto.
+ (check_lsi_error): Ditto.
+ (common_breakpoint): Ditto.
+ (pmon_makeb64): Ditto.
+
+ * remote-mips.c (mips_xfer_memory): Change fflush to gdb_flush;
+ change stdout to gdb_stdout.
+
+ * remote-mm.c (mm_open): Change stderr to gdb_stderr.
+ (init_mm_ops): Add new target vector fields.
+ (mm_load): Fixed params in commented out call to symbol_file_add.
+
+ * remote-nindy.c (instream): Change decl to FILE.
+
+ * remote-udi.c (udi_load): Fixed params in call to symbol_file_add.
+
+ * remote-vx.c (vx_add_symbols): Fixed params in call to
+ symbol_file_add.
+
+ * remote.c (init_remote_ops): Cosmetic change to match expected
+ test output.
+
+ * rs6000-nat.c (add_vmap): Add params to call to allocate_objfile.
+
+ * scm-lang.h: Add parameter to scm_val_print function decl.
+
+ * scm-valprint.c (scm_scmval_print): Cast svalue to (int); new
+ parameter. This parameter is currently only used when evaluating
+ C++ expressions. So, it is always 0 in this file.
+ (c_val_print): Fixed prototype decl; it needed an embedded_offset
+ param.
+
+ * sol-thread.c (sol_core_ops): Add new target vector fields.
+ (sol_thread_ops): Ditto.
+
+ * somsolib.c (DLD_FLAGS_MAPPRIVATE): New macro.
+ Define bit of __dld_flags in HP-UX a.out files.
+ (DLD_FLAGS_HOOKVALID): Ditto.
+ (DLD_FLAGS_LISTVALID): Ditto.
+ (DLD_FLAGS_BOR_ENABLE): Ditto.
+ (som_solib_total_st_size): Cumulative size in bytes of the
+ symbol tables of all shared objects on the so_list_head list.
+ (som_solib_st_size_threshhold_exceeded): Threshold for adding symbols
+ for shlibs.
+ (som_solib_sizeof_symbol_table): New function. Computes size of
+ symbol table for a shlib.
+ (som_solib_load_symbols): New function. Load symbols from shlib.
+ (som_solib_add): Detect if __dld_list is not valid.
+ Record main program's symbol table size.
+ Load symbols if called from command line.
+ Keep threshold into account when loading shlib symbols.
+ (som_solib_create_inferior_hook): Use dld_flags macros.
+ (som_sharedlibrary_info_command): Let user know if symbols were
+ not loaded.
+ (som_solib_restart): Discard all the shlibs descriptors.
+ (_initialize_som_solib): Chenge help message for auto-solib-add
+ command.
+ Set threshold for symbol table to 50 megabytes.
+ (_initialize_som_solib): Add call to som_solib_restart.
+ (som_solib_restart): New function
+ (som_solib_in_dynamic_linker): New function
+ (som_solib_desire_dynamic_linker_symbols): New function
+ (som_solib_unloaded_library_pathname): New function
+ (som_solib_loaded_library_pathname): New function
+ (som_solib_library_pathname): New function
+ (som_solib_have_unload_event): New function
+ (som_solib_have_load_event): New function
+ (som_solib_create_catch_unload_hook): New function
+ (som_solib_create_catch_load_hook): New function
+ (som_solib_create_inferior_hook): Rewritten
+ dld_cache: New struct
+ addr_and_unwind_t: New struct
+ (find_unwind_entry) add prototype
+ Include assert.h, remove references to ASSERT macro,
+ add include of fcntl.h so that O_RDONLY is defined.
+ (som_solib_create_inferior_hook): Introduce new local
+ msymbol2 and change some msymbol's to msymbol2's -- was clobbering
+ msymbol, passing a NULL to lookup_minimal_symbol_solib_trampoline,
+ and ultimately core dumping with a SEGV.
+ (som_solib_mapped_entry): Additional comments for text_addr,
+ text_link_addr, text_end, and tsd_start_addr fields. Commenting
+ out 2 tsd fields, __data_start and __data_end.
+ (som_solib_add_solib_objfile): Add params to calls to symbol_file_add.
+ Add some code for distinguishing between a shared library and other
+ objfiles. This appears to be a prelude to thread local storage.
+ (som_solib_load_symbols): Changes to printf statement
+ enclosed by SOLIB_DEBUG ifdef.
+ (som_solib_add): Change comment to correctly specify path
+ to end.o -- /opt/langtools/lib/end.o. changes to printf statement
+ enclosed by SOLIB_DEBUG ifdef.
+ Removed several SOLIB_DEBUG ifdefs and the associated printfs.
+ Add code to find the start address for the object file's thread
+ local storage
+ (som_solib_create_inferior_hook): Fix warning messages use correct
+ path to end.o -- /opt/langtools/lib/end.o. Change control flow.
+ No longer user early returns from function is cases of error.
+ (reset_inferior_pid): New function
+ (som_solib_remove_inferior_hook): New function
+ (so_lib_thread_start_addr): New function. used for tsd.
+ (struct som_solib_mapped_entry): Add new field tsd_start_addr.
+ (struct so_list): Add new field solib_addr.
+ (som_solib_add_solib_objfile): New function.
+ (som_solib_load_symbols): Rewritten.
+ (som_solib_add): Make sure we don't load the symbols in if the
+ threshold was exceeded.
+ (som_solib_get_solib_by_pc): New function. Return the address of
+ handle of the shared library.
+ (som_solib_restart): Disable breakpoints at restart.
+
+ * sparcl-tdep.c (init_sparclite_ops): Add new target vector fields.
+
+ * target.c (cleanup_target): Changed casting of default functions
+ for to_has_forked, to_has_vforked, to_pid_to_exec_file to get rid
+ of warnings. Fixed PARAMS for to_has_syscall_event. Fixed the
+ return type on a few of the default function values.
+ (cleanup_target): Changes in the de_fault macro, both to
+ accomodate the new target_ops vector fields and to use
+ more accurate default functions.
+ (debug_to_open): Change stderr to gdb_stderr.
+ (debug_to_close): Ditto.
+ (debug_to_attach): Ditto.
+ (debug_to_post_attach): Ditto.
+ (debug_to_require_attach): Ditto.
+ (debug_to_detach): Ditto.
+ (debug_to_require_detach): Ditto.
+ (debug_to_resume): Ditto.
+ (debug_to_wait): Ditto.
+ (debug_to_post_wait): Ditto.
+ (debug_to_fetch_registers): Ditto.
+ (debug_to_store_registers): Ditto.
+ (debug_to_prepare_to_store): Ditto.
+ (debug_to_xfer_memory): Ditto.
+ (debug_to_files_info): Ditto.
+ (debug_to_insert_breakpoint): Ditto.
+ (debug_to_remove_breakpoint): Ditto.
+ (debug_to_terminal_init): Ditto.
+ (debug_to_terminal_inferior): Ditto.
+ (debug_to_terminal_ours_for_output): Ditto.
+ (debug_to_terminal_ours): Ditto.
+ (debug_to_terminal_info): Ditto.
+ (debug_to_kill): Ditto.
+ (debug_to_load): Ditto.
+ (debug_to_lookup_symbol): Ditto.
+ (debug_to_create_inferior): Ditto.
+ (debug_to_post_startup_inferior): Ditto.
+ (debug_to_acknowledge_created_inferior): Ditto.
+ (debug_to_clone_and_follow_inferior): Ditto.
+ (debug_to_post_follow_inferior_by_clone): Ditto.
+ (debug_to_insert_fork_catchpoint): Ditto.
+ (debug_to_remove_fork_catchpoint): Ditto.
+ (debug_to_insert_vfork_catchpoint): Ditto.
+ (debug_to_remove_vfork_catchpoint): Ditto.
+ (debug_to_has_forked): Ditto.
+ (debug_to_has_vforked): Ditto.
+ (debug_to_can_follow_vfork_prior_to_exec): Ditto.
+ (debug_to_post_follow_vfork): Ditto.
+ (debug_to_insert_exec_catchpoint): Ditto.
+ (debug_to_remove_exec_catchpoint): Ditto.
+ (debug_to_has_execd): Ditto.
+ (debug_to_reported_exec_events_per_exec_call): Ditto.
+ (debug_to_has_syscall_event): Ditto.
+ (debug_to_has_exited): Ditto.
+ (debug_to_mourn_inferior): Ditto.
+ (debug_to_can_run): Ditto.
+ (debug_to_notice_signals): Ditto.
+ (debug_to_thread_alive): Ditto.
+ (debug_to_stop): Ditto.
+ (debug_to_enable_exception_callback): Ditto.
+ (debug_to_get_current_exception_event): Ditto.
+ (debug_to_pid_to_exec_file): Ditto.
+ (debug_to_core_file_to_sym_file): Ditto.
+ (default_clone_and_follow_inferior): New function prototype
+ decl and function definition.
+ (dummy_target): Add new target_ops vector fields and their
+ initializations. More target_ops vector changes for HPUX new
+ fields.
+ (de_fault): Add new HPUX specific target_ops operations to the
+ de_fault macro
+ (INHERIT): Add new HPUX specific target_ops operations.
+ (debug_to_post_wait): New function.
+ (debug_to_post_startup_inferior): Ditto.
+ (debug_to_acknowledge_created_inferior): Ditto.
+ (debug_to_clone_and_follow_inferior): Ditto.
+ (debug_to_post_follow_inferior_by_clone): Ditto.
+ (debug_to_create_catch_fork_hook): Ditto.
+ (debug_to_create_catch_vfork_hook): Ditto.
+ (debug_to_has_forked): Ditto.
+ (debug_to_has_vforked): Ditto.
+ (debug_to_post_follow_vfork): Ditto.
+ (setup_target_debug): Initialize new target_ops vector fields.
+ (nosupport_runtime): New function, used in cleanup_target
+ (update_current_target): Add new new target_ops vector fields to
+ the INHERIT macro definition.
+ (generic_mourn_inferior): The call to breakpoint_init_inferior now
+ takes a parameter.
+ (normal_pid_to_str): Add a \0 to the end of buf.
+ (debug_to_has_syscall_event): New function.
+ (debug_to_enable_exception_callback): New function.
+ (debug_to_get_current_exception_event): New function.
+ (setup_target_debug): Initialize the 3 new target_ops vector fields
+ (struct signals): Fix message associated with SIGRETRACT.
+ (return_one): New function, used by the de_fault macro
+ (debug_to_post_attach): New function.
+ (debug_to_wait): Add new cases TARGET_WAITKIND_FORKED,
+ TARGET_WAITKIND_VFORKED, TARGET_WAITKIND_EXECD.
+ (debug_to_insert_fork_catchpoint): New function.
+ (debug_to_remove_fork_catchpoint): Ditto.
+ (debug_to_insert_vfork_catchpoint): Ditto.
+ (debug_to_remove_vfork_catchpoint): Ditto.
+ (debug_to_can_follow_vfork_prior_to_exec): Ditto.
+ (debug_to_insert_exec_catchpoint): Ditto.
+ (debug_to_remove_exec_catchpoint): Ditto.
+ (debug_to_core_file_to_sym_file): Ditto.
+ (setup_target_debug): Give new fields in current_target target_ops
+ vector values.
+
+ * target.h: Include symtab.h.
+ (target_waitkind): New enumerated values
+ TARGET_WAITKIND_SYSCALL_ENTRY, TARGET_WAITKIND_SYSCALL_RETURN,
+ TARGET_WAITKIND_FORKED, TARGET_WAITKIND_VFORKED,
+ TARGET_WAITKIND_EXECD.
+ (target_waitstatus): Add a syscall_id field to structure.
+ (child_has_syscall_event): New decl.
+ (child_thread_alive): New decl.
+ (target_ops): Add 3 new fields: To_has_syscall_event,
+ to_enable_exception_callback, to_get_current_exception_event
+ (target_enable_exception_callback): New macro.
+ (target_has_syscall_event): New macro.
+ (target_get_current_exception_event): New macro.
+ (TARGET_DISABLE_HW_WATCHPOINTS): New macro.
+ (TARGET_ENABLE_HW_WATCHPOINTS): New macro.
+ (PC_REQUIRES_RUN_BEFORE_USE): New macro.
+ (target_tid_to_str): New macro.
+ (target_waitstatus): Additional fields in struct to keep track
+ of child pid and pathname to execd file.
+ (target_ops): Add in the new target_ops function pointer fields.
+ New macros to go along with new target_ops fields.
+ In target_waitstatus.value, change name of child_pid field to
+ related_pid.
+ (target_pid_or_tid_to_str): Define default macro.
+ Add missing #endif after PC_REQUIRES_RUN_BEFORE_USE definition
+ (ENSURE_VFORKING_PARENT_REMAINS_STOPPED): Define default macro.
+ (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK): Define default
+ macro.
+ There are new function decls for to_require_attach
+ and to_require_detach. There are also new macros,
+ target_require_attach and target_require_detach. There are
+ also new function decls for find_default_require_detach
+ and find_default_require_attach.
+ (target_ops): New fields to_post_wait, to_post_startup_inferior
+ to_acknowledge_created_inferior, to_clone_and_follow_inferior,
+ to_post_follow_inferior_by_clone, to_create_catch_fork_hook,
+ to_create_catch_vfork_hook, to_has_forked, to_has_vforked,
+ to_post_follow_vfork, to_pid_to_exec_file.
+ New function definitions child_pid_to_exec_file, child_post_wait,
+ child_post_startup_inferior, child_acknowledge_created_inferior,
+ child_clone_and_follow_inferior,
+ child_post_follow_inferior_by_clone, child_create_catch_fork_hook,
+ child_create_catch_vfork_hook, child_has_forked,
+ child_has_vforked, child_acknowledge_created_inferior,
+ child_post_follow_vfork.
+ New macros target_post_startup_inferior,
+ target_acknowledge_created_inferior,
+ target_clone_and_follow_inferior,
+ target_post_follow_inferior_by_clone,
+ target_create_catch_fork_hook, target_create_catch_vfork_hook,
+ target_pid_to_exec_file.
+ (find_default_clone_and_follow_inferior): New function prototype.
+
+
+ * v850ice.c (init_850ice_ops): Init new target vector fields.
+
+ * valprint.c (print_binary_chars): Print out long long as
+ a binary number.
+ (print_octal_chars): Print out long long as an octal number
+ (print_decimal_chars): Print out long long as a decimal number
+ (strcat_longest): Define it.
+ * valprint.c: Hp merge, 4/15/98 snapshot
+ Add parameter to val_print. This is used for
+ evaluating C++ expressions.
+
+ * value.h (VALUE_POINTED_TO_OFFSET): New macro.
+ Add field pointed_to_offset to value structure.
+ Add prototypes for new functions in valops.c.
+ (write_register_pid): Change prototype to match
+ function.
+ (val_print function decl): Additional parameter.
+ (VALUE_EMBEDDED_OFFSET): New macro.
+ (find_rt_vbase_offset): New function decl -- for C++ support.
+
+Wed Dec 23 15:03:42 1998 Per Bothner <bothner@cygnus.com>
+
+ * Makefile.in (READLINE_CFLAGS): Search $(READLINE_SRC)/.. rather
+ than $(READLINE_SRC) so #include <readline/readline.h> will work.
+ * top.c: #include <readline/history.h> instead of "history.h".
+ * tracepoint.c: Likewise.
+ * mac-xdep.c: Likewise.
+
+Wed Dec 23 12:32:00 1998 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * defs.h (TARGET_FLOAT_FORMAT, TARGET_DOUBLE_FORMAT): Define using
+ TARGET_BYTE_ORDER and not target_byte_order.
+
+Tue Dec 22 10:51:33 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * config/i386/cygwin.mh (TERMCAP): define.
+ (from Chris Faylor, cgf@cygnus.com)
+
+ * top.c: specify directory name for including readline.h
+
+ * tracepoint.c: ditto.
+
+ * utils.c: ditto.
+
+Mon Dec 21 13:30:34 1998 Mark Alexander <marka@cygnus.com>
+
+ * value.c (value_virtual_fn_field): Handle the situation where
+ vtbl is a pointer to a structure instead of a pointer to an array.
+
+Mon Dec 21 10:38:11 1998 Andrew Cagney <cagney@chook>
+
+ * mips-tdep.c: (MIPS_DEFAULT_FPU_TYPE): Default to
+ MIPS_FPU_DOUBLE.
+
+1998-12-17 J.T. Conklin <jtc@redbacknetworks.com>
+
+ * blockframe.c (get_frame_saved_regs): If the saved_regs_addr ptr
+ is null, ensure that saved registers are copied from the local
+ variable that was used to obtain them.
+
+Sat Dec 19 09:55:09 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * mips-tdep.c (mips32_heuristic_proc_desc): Clear temp_saved_regs
+ on restart. Fixes problem with backtracing through functions that
+ use virtual frame pointers.
+
+Fri Dec 18 14:23:34 1998 Andrew Cagney <cagney@chook>
+
+ * mips-tdep.c (mips_push_arguments): Don't left-shift small
+ structs being passed in a register when an O64 target.
+
+ * config/mips/tm-mips.h (enum mips_fpu_type, mips_fpu): Move to
+ mips-tdep.c.
+
+ * mips-tdep.c (mips_fpu_string): Delete variable.
+ (mips_fpu_type_auto): New variable.
+ (mips_fpu_type): Rename mips_fpu.
+ (_initialize_mips_tdep): Delete initialization of mips_fpu et.al.
+ Rewrite ``set mipsfpu'' command set.
+ (set_mipsfpu_command, show_mipsfpu_command,
+ set_mipsfpu_single_command, set_mipsfpu_double_command,
+ set_mipsfpu_none_command, set_mipsfpu_auto_command): New
+ functions, handle commands.
+ (mips_push_arguments, mips_push_dummy_frame, mips_pop_frame,
+ mips_extract_return_value): Update.
+ (_initialize_mips_tdep): Set mips_fpu_type according to current
+ processor.
+ (_initialize_mips_tdep): Only define ``set processor'' command
+ when not multi-sim.
+
+Fri Dec 18 12:56:56 1998 Andrew Cagney <cagney@chook>
+
+ * gdbarch.h (gdbarch_init_ftype): Pass struct gdbarch_info
+ by-value.
+ (struct gdbarch_info): Add struct gdbarch_tdep_info *tdep_info.
+ * gdbarch.c (gdbarch_update): Update.
+ * mips-tdep.c: (mips_gdbarch_init): Update
+
+ * gdbarch.c (gdbarch_update): Add more tracing.
+
+Thu Dec 17 02:15:40 1998 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * configure.tgt (gdb_target): Identify mips64*vr4100*-*-elf* as
+ vr4100.
+ * config/mips/vr4100.mt, config/mips/tm-vr4100.h: Replace
+ vr4xxx.mt and tm-vr4xxx.h.
+
+Thu Dec 17 02:06:17 1998 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * mips-tdep.c (mips_gdbarch_init): New function. Initialize a MIPS
+ architecture vector.
+ (_initialize_mips_tdep): Register MIPS with GDBARCH.
+ (struct gdbarch_tdep): Define.
+ (MIPS_EABI, MIPS_LAST_FP_ARG_REGNUM, MIPS_LAST_ARG_REGNUM): When
+ multi-arch, get value from gdbarch->tdep.
+
+Thu Dec 17 02:01:58 1998 Andrew Cagney <cagney@chook>
+
+ * gdbtypes.c (_initialize_gdbtypes): Register all builtin types
+ with gdbarch so that they are updated whenever the architecture is
+ changed.
+
+Thu Dec 17 01:58:16 1998 Andrew Cagney <cagney@chook>
+
+ * gdbarch.h (GDB_MULTI_ARCH): New macro, default to zero.
+ (current_gdbarch): Current architecture pointer.
+ * gdbarch.c (struct gdbarch): Define.
+
+ * gdbarch.h (TARGET_ARCHITECTURE, TARGET_BYTE_ORDER,
+ TARGET_LONG_BIT, TARGET_LONG_LONG_BIT, TARGET_PTR_BIT): When
+ multi-arch force definition.
+ * gdbarch.h, gdbarch.c (gdbarch_tdep, gdbarch_bfd_arch_info,
+ gdbarch_byte_order, {set,}gdbarch_long_bit,
+ {set,}gdbarch_long_long_bit, {set,}gdbarch_ptr_bit): Corresponding
+ functions.
+
+ * gdbarch.h (struct gdbarch_list, struct gdbarch_info,
+ gdbarch_init_ftype), gdbarch.c (register_gdbarch_init): Mechanism
+ for registering an architecture with GDB.
+ (gdbarch_list_lookup_by_info, gdbarch_alloc, gdbarch_update,
+ verify_gdbarch): Support functions.
+
+ * gdbarch.h (gdbarch_data_ftype), gdbarch.c
+ (register_gdbarch_data, gdbarch_data): Mechanism for maintaining
+ per-architecture pointers.
+ (init_gdbarch_data): Support functions.
+
+ * gdbarch.h (gdbarch_swap_ftype), gdbarch.c
+ (register_gdbarch_swap): Ditto for swapped memory regions.
+ (init_gdbarch_swap, swapout_gdbarch_swap, swapin_gdbarch_swap):
+ Support functions.
+
+ * gdbarch.c (set_endian_big, set_endian_little, set_architecture,
+ info_architecture, set_gdbarch_from_file): Hook in multi-arch
+ code by calling gdbarch_update.
+ (default_gdbarch): Default multi-arch vector. Use host's type
+ system for values.
+
+Thu Dec 17 01:34:36 1998 Andrew Cagney <cagney@chook>
+
+ * gdbtypes.c (build_gdbtypes): New function.
+ (_initialize_gdbtypes): Call.
+
+Wed Dec 16 11:47:00 1998 Andrew Cagney <cagney@chook>
+
+ * gdbarch.c (show_architecture): Use TARGET_ARCHITECTURE.
+ * gdbarch.h, gdbarch.c: Fix typo's. Use struct's in preference to
+ types.
+ * gdbarch.h, gdbarch.c (gdbarch_debug): Add ``set archdebug'' to
+ command set.
+
+Tue Dec 15 23:46:40 1998 Andrew Cagney <cagney@chook>
+
+ * config/mips/tm-*.h: (TARGET_BYTE_ORDER_DEFAULT,
+ TARGET_BYTE_ORDER_SELECTABLE_P): Replace TARGET_BYTE_ORDER and
+ TARGET_BYTE_ORDER_SELECTABLE.
+
+1998-12-14 Anthony Thompson (athompso@cambridge.arm.com)
+
+ * remote-rdp.c (rdp_init): Don't discard first character on reset.
+ (translate_open_mode): Define table.
+ (exec_swi): Handle SWI_Clock. SWI_Open now handles stdin/stdout.
+ SWI_Write returns number of bytes not written. SWI_Read does the
+ same. SWI_Seek should return success/failure flag. Fix SWI_Flen.
+
+1998-12-14 J.T. Conklin <jtc@redbacknetworks.com>
+
+ * config/i386/nbsd.mh, config/m68k/nbsd.mh, config/ns32k/nbsd.mh
+ (XDEPFILES): Add ser-tcp.o.
+
+Mon Dec 14 14:46:13 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * monitor.c (monitor_expect, monitor_printf_noecho,
+ monitor_printf): Always compile EXTRA_RDEBUG code.
+ (RDEBUG): Ditto.
+
+ From Michael Meissner <meissner@cygnus.com>:
+ * ppcbug-rom.c (init_ppc_cmds): Cleanup formatting.
+
+1998-12-08 Michael Meissner <meissner@cygnus.com>
+
+ * monitor.c (monitor_printable_string): New function to convert a
+ string into a printable representation.
+ (monitor_error): Call error after converting string into printable
+ format.
+ (monitor_printf{,_noecho}): If EXTRA_RDEBUG is defined, convert
+ string into printable form before printing.
+ (monitor_expect): Ditto.
+ (monitor_read_memory{,_single}): Call monitor_error, not error.
+ (monitor_read_memory): Return immediately if length is 0.
+
+ * ppcbug-rom.c (init_ppc_cmds): Fill in dump_registers field,
+ which is now required.
+
+Mon Dec 14 11:01:39 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h, gdbarch.c: Consolidate the semi-dynamic target system
+ dependant GDB parameters.
+ (set_gdbarch_from_file): Combine set_architecture_from_file and
+ set_byte_order_from_file.
+ * top.c, defs.h, printcmd.c: Delete them from here.
+ * Makefile.in: Add gdbarch.[ch].
+ * exec.c (exec_file_command): Call set_gdbarch_from_file.
+
+Sun Dec 13 09:52:51 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (TARGET_PRINT_INSN_INFO, TARGET_PRINT_INSN): Define.
+ (TARGET_ARCHITECTURE, TARGET_ARCHITECTURE_AUTO): Define.
+ (TARGET_BYTE_ORDER_AUTO): Define.
+ (TARGET_BYTE_ORDER_SELECTABLE_P): Provide default. Replaces
+ TARGET_BYTE_ORDER_SELECTABLE. Handle compat issues.
+ (BITS_BIG_ENDIAN): Simplify.
+ (TARGET_FLOAT_FORMAT): Ditto.
+ (TARGET_DOUBLE_FORMAT):
+
+ * remote-e7000.c, sh-tdep.c, printcmd.c, remote-sim.c,
+ remote-rdi.c, sparc-tdep.c: Update.
+
+ * config/powerpc/tm-ppcle-eabi.h, config/rs6000/tm-rs6000.h,
+ config/powerpc/tm-ppc-eabi.h, config/mn10300/tm-mn10300.h:
+ Convert.
+
+Sat Dec 12 09:28:13 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * frame.h (struct frame_info): Add CORE_ADDR *saved_regs and
+ struct frame_extra_info *extra_info.
+ (frame_obstack_alloc, frame_saved_regs_zalloc): Prototype.
+ (SIZEOF_FRAME_SAVED_REGS): Provide default.
+ (FRAME_INIT_SAVED_REGS): Provide default.
+ (struct frame_saved_regs): Deprecate.
+ (EXTRA_FRAME_INFO): Deprecate.
+
+ * blockframe.c (frame_obstack_alloc, frame_saved_regs_zalloc): New
+ function.
+ (generic_get_saved_register): Use FRAME_INIT_SAVED_REGS and
+ frame->saved_regs.
+ (frame_cache_obstack): Make static.
+ (get_frame_saved_regs): Deprecate. Copy the saved regs into the
+ frame buffer.
+
+ * stack.c (frame_info): Rewrite using frame->saved_regs and
+ FRAME_INIT_SAVED_REGS.
+ * findvar.c (find_saved_register): Ditto.
+
+ * config/mn10300/tm-mn10300.h (EXTRA_FRAME_INFO): Delete.
+ (FRAME_FIND_SAVED_REGS): Replace with FRAME_INIT_SAVED_REGS. No-op.
+ * mn10300-tdep.c: Update.
+ (analyze_dummy_frame): New function.
+ (struct frame_extra_info): Define.
+ (mn10300_init_extra_frame_info): Update.
+
+ * config/rs6000/tm-rs6000.h: (EXTRA_FRAME_INFO): Delete.
+ (FRAME_FIND_SAVED_REGS): Replace with FRAME_INIT_SAVED_REGS.
+ (FRAME_ARGS_ADDRESS): Replace with function.
+
+ * rs6000-tdep.c (frame_get_saved_regs): Rename from
+ frame_get_cache_fsr.
+ (rs6000_init_extra_frame_info): New function.
+ (rs6000_frame_init_saved_regs): Call frame_get_saved_regs.
+ (FUNCTION_START_OFFSET): Delete references, was ZERO.
+ (rs6000_frame_args_address): New function.
+ (frame_initial_stack_address): Update
+
+ * config/mips/tm-mips.h (EXTRA_FRAME_INFO): Remove saved_regs.
+ (FRAME_INIT_SAVED_REGS): Rename FRAME_FIND_SAVED_REGS, update.
+ * mips-tdep.c (mips_find_saved_regs, read_next_frame_reg,
+ init_extra_frame_info, mips_pop_frame): Update.
+ * config/alpha/tm-alpha.h (FRAME_INIT_SAVED_REGS,
+ EXTRA_FRAME_INFO), alpha-tdep.c (alpha_find_saved_regs,
+ alpha_pop_frame, init_extra_frame_info): Ditto.
+
+ * i960-tdep.c, m88k-tdep.c, h8300-tdep.c: Update.
+ * config/sparc/tm-sparc.h, config/a29k/tm-a29k.h: Define
+ FRAME_INIT_SAVED_REGS as no-op.
+
+ * z8k-tdep.c (z8k_init_frame_saved_regs): Rename
+ get_frame_saved_regs.
+ (examine_frame, z8k_skip_prologue): Update.
+ * config/z8k/tm-z8k.h (FRAME_INIT_SAVED_REGS): Define.
+
+1998-12-11 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From J.T. Conklin <jtc@redbacknetworks.com>:
+ * i386-stub.c (handle_exception): Add support for 'P' command.
+ (NUMREGS): New macro.
+
+Fri Dec 11 09:07:05 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * i386b-nat.c: Include "expression.h".
+
+ * symtab.h: Don't include "gnu-regex.h".
+
+ * solib.c (solib_add_common_symbols): Cast parameters passed to
+ make_cleanup to use the new make_cleanup_func typedef.
+
+ * inftarg.c: Include "wait.h" after, rather than before, <wait.h>.
+ "wait.h" was defining all WIF* macro's instead of filling in those
+ that <wait.h> missed.
+
+Fri Dec 11 09:52:04 1998 Andrew Cagney <cagney@chook>
+
+ * mipsm3-nat.c, hppah-nat.c, infptrace.c, i386gnu-nat.c,
+ hppab-nat.c, core-aout.c, arm-xdep.c, alpha-nat.c, altos-xdep.c,
+ pyr-xdep.c, remote-st.c, remote-os9k.c, tahoe-tdep.c, pyr-tdep.c,
+ vax-tdep.c: Replace reg_name with REGISTER_NAME.
+
+Thu Dec 10 15:19:40 1998 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by Jim Blandy <jimb@cygnus.com>,
+ Edith Epstein <eepstein@cygnus.com>, Elena Zannoni
+ <ezannoni@cygnus.com> Stan Shebs <shebs@cygnus.com>, and David
+ Taylor <taylor@cygnus.com>, as part of the project to merge in
+ changes originally made by HP; HP did not create ChangeLog
+ entries.
+
+ * annotate.c (annotate_catchpoint): New function.
+
+ * annotate.h (annotate_catchpoint): declare it; add new includes
+ (symtab.h and gdbtypes.h).
+
+ * buildsym.h: add external var processing_hp_compilation.
+
+ * coff-solib.h:
+ (SOLIB_REMOVE_INFERIOR_HOOK): new macro. defined to 0.
+ functionality not implemented for coff.
+ (SOLIB_CREATE_CATCH_LOAD_HOOK): New macro; generate error msg for coff.
+ (SOLIB_CREATE_CATCH_UNLOAD_HOOK): ditto.
+ (SOLIB_HAVE_LOAD_EVENT): ditto.
+ (SOLIB_LOADED_LIBRARY_PATHNAME): ditto.
+ (SOLIB_HAVE_UNLOAD_EVENT): ditto.
+ (SOLIB_UNLOADED_LIBRARY_PATHNAME): ditto.
+ (SOLIB_IN_DYNAMIC_LINKER): ditto.
+ (SOLIB_RESTART): ditto.
+
+ * complaints.h: add ifdef...endif pair at beginning and end of file.
+
+ * dstread.c (dst_symfile_read): the parameter to fileno
+ must be of type FILE *. So cast abfd->iostream in the
+ call to fileno must be cast as a FILE *, not a GDB_FILE *.
+ This will work because abfd->iostream is declared and
+ given a value in bdf and bfd will continue to use FILE
+ rather than GDB_FILE.
+
+ * dwarf2read.c (dwarf_bool_name): change parameter from bool
+ to mybool. sigh.
+
+ * expression.h: include symtab.h
+
+ * frame.h (print_only_stack_frame, show_stack_frame,
+ show_frame_info): add prototypes.
+
+ * gdbcmd.h (togglelist, stoplist): declare.
+
+ * gdbcore.h (read_memory_string): declare it.
+ (exec_file_attach): add prototype.
+
+ * inflow.c (terminal_is_ours): make non static.
+
+ * minsyms.c: minor spacing change.
+
+ * parser-defs.h (parse_nested_classes_for_hpacc): add prototype.
+ (find_template_name_end): add prototype.
+
+ * scm-lang.c (scm_unpack): cast svalue to (int).
+
+ * top.h: declare it.
+
+ * valprint.h (print_binary_chars): new prototype definition.
+ (print_octal_chars): new prototype definition.
+ (print_decimal_chars): new prototype definition.
+
+Thu Dec 10 07:14:56 1998 Andrew Cagney <cagney@chook>
+
+ * config/arm/tm-arm.h, arm-tdep.c: Replace REGISTER_NAMES with
+ REGISTER_NAME.
+ * mn10300-tdep.c, config/mn10300/tm-mn10300.h: Ditto.
+ * sh-tdep.c, config/sh/tm-sh.h: Ditto.
+
+ * defs.h (REGISTER_NAME): Provide default for old targets.
+ * defs.h, infcmd.c: Rename reg_names to gdb_register_names.
+
+ * tracepoint.c, target.c, parse.c, infcmd.c, remote-udi.c,
+ expprint.c, infcmd.c, printcmd.c, eval.c, stack.c, findvar.c,
+ remote-udi.c, config/alpha/tm-alpha.h, remote-sim.c, d30v-tdep.c,
+ config/mips/tm-mips.h, hppa-tdep.c: Use REGISTER_NAME.
+
+1998-12-08 James E Wilson <wilson@wilson-pc.cygnus.com>
+
+ * config/i960/mon960.mt (SIM_OBJS, SIM): Define.
+
+Tue Dec 8 16:49:24 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * NEWS: Add mentions of newly-added configurations.
+
+1998-12-08 Philippe De Muyter <phdm@macqel.be>
+
+ * config/xm-aix4.h (SIGWINCH_HANDLER): Function `aix_resize_window'
+ must accept a signal number as parameter.
+ * config/rs6000/xm-rs6000.h (SIGWINCH_HANDLER): Ditto.
+ * utils.c (initialize_utils): Give a parameter to `SIGWINCH_HANDLER'.
+
+ * inferior.h (register_valid): Variable's type is `SIGNED char', not
+ `char'.
+ * findvar.c (register_valid): Ditto.
+
+ * defs.h (make_cleanup_func): Protect parameter list by `PARAMS'.
+ * gdbthread.h (unbind_target_thread_vector): Likewise.
+
+Tue Dec 8 15:09:44 1998 Edith Epstein <eepstein@sophia.cygnus.com>
+
+ Merged in m68k-linux patch from Andreas Schwab
+
+ 1998-12-01 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * Makefile.in, configure.host, configure.tgt: Add support for
+ m68k-linux.
+ * config/m68k/linux.mh: New file.
+ * config/m68k/linux.mt: New file.
+ * config/m68k/nm-linux.h: New file.
+ * config/m68k/tm-linux.h: New file.
+ * config/m68k/xm-linux.h: New file.
+ * gdb/m68klinux-nat.c: New file.
+ * gdbserver/low-linux.c: Add support for m68k-linux.
+ * gdb/config/m68k/tm-m68k.h (NUM_FREGS): New macro.
+
+1998-12-07 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * config/i386/xm-cygwin.h: Remove REQUEST_QUIT definition.
+ * config/powerpc/xm-cygwin.h: Ditto.
+
+1998-12-07 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * rs6000-tdep.c (pop_frame): Correctly find the registers saved in
+ the stack frame. Their offset from the previous stack frame is in
+ fdata.gpr_offset and fdata.fpr_offset, not fdata.offset.
+ (gdb.base/return.exp)
+ * config/rs6000/tm-rs6000.h: Doc fixes.
+
+1998-12-03 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * monitor.c (monitor_read_memory): Zero out pattern buffers
+ before calling re_search.
+ (parse_register_dump): Ditto.
+
+Thu Dec 3 10:37:22 EST 1998 Zdenek Radouch (radouch@cygnus.com)
+
+ FR30 updates - still very preliminary.
+ * configure.tgt
+ * fr30-tdep.c
+ * config/fr30/tm-fr30.h
+
+Thu Dec 3 16:30:35 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ax-gdb.c: Include target.h.
+
+Tue Dec 3 10:59:00 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ax-gdb.c (_initialize_ax_gdb), i960-tdep.c (pop_frame),
+ monitor.c (flush_monitor_dcache, longlongendswap), remote-array.c
+ (hexword2ascii), w89k-rom.c (init_w89k_cmds), z8k-tdep.c
+ (init_frame_pc, extract_return_value): Make return type void.
+ * monitor.c (monitor_write_even_block): Make return type explicit.
+ (monotor_read_memory_block): Delete function.
+ * monitor.h: Update.
+ * remote.c (remote_get_threadlist, remote_update_threads),
+ remote-array.c (array_get_packet), remote-rdi.c (Fail): Always
+ return a value.
+ * m32r-tdep.c (m32r_fix_call_dummy): From Michael Snyder, void
+ function.
+ * jv-valprint.c (java_val_print): From Stu Grossman. Return 0 by
+ default.
+
+Wed Dec 2 15:11:38 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c: Move default definition of
+ TARGET_VIRTUAL_FRAME_POINTER from here to target.h.
+ * target.h: Add default definition of TARGET_VIRTUAL_FRAME_POINTER.
+ * ax-gdb.c (gen_frame_args_address, gen_frame_locals_address):
+ use TARGET_VIRTUAL_FRAME_POINTER to determine frame pointer.
+ (gen_trace_for_expr): new argument, address of tracepoint,
+ gets passed to new_agent_expr and added to struct agent_expr.
+ (is_nontrivial_conversion): call to new_agent_expr now requires
+ a dummy argument. (agent_command): use get_current_frame() to
+ get current PC scope; pass it to gen_trace_for_expr.
+ * ax-general.c (new_agent_expr): new argument, address of
+ tracepoint; store it in new field of struct agent_expr.
+ * ax.h (struct agent_expr): add new field for tracepoint address.
+ * ax-gdb.h: change prototypes to match above changes.
+
+ * m32r-tdep.c (decode_prologue): If no branch or push fp is found,
+ but there's a stack adjust, then use that as the end of prologue.
+ (m32r_skip_prologue): don't skip past the first line if there is
+ line info. (m32r_virtual_frame_pointer): new function.
+ (m32r_fix_call_dummy): no return value needed.
+
+Tue Dec 1 10:59:00 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ocd.c (remote_timeout), (BDM_BREAKPOINT), monitor.c (readchar),
+ remote.c: Cleanup closing of open comments.
+
+Mon Nov 30 16:04:03 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/fr30/tm-fr30.h (INNER_THAN): Add parameters.
+
+Mon Nov 30 11:18:48 1998 Andrew Cagney <cagney@chook>
+
+ * frame.h (FRAME_CHAIN_VALID): Default to
+ default_frame_chain_valid.
+ * blockframe.c (default_frame_chain_valid): New function.
+
+ * frame.h (FRAME_CHAIN_VALID_ALTERNATIVE): Delete references
+ * blockframe.c (alternate_frame_chain_valid): New function.
+ * config/mips/tm-mipsv4.h, config/m88k/tm-delta88v4.h,
+ config/m68k/tm-monitor.h, config/m68k/tm-m68kv4.h,
+ config/i386/tm-i386v4.h, config/i386/tm-i386nw.h,
+ config/h8300/tm-h8300.h: Update.
+
+ * blockframe.c (nonnull_frame_chain_valid): New function.
+ * config/m68k/tm-os68k.h, config/m68k/tm-vx68.h,
+ config/m68k/tm-apollo68b.h, config/i960/tm-vx960.h,
+ config/arc/tm-arc.h: Update FRAME_CHAIN_VALID.
+
+ * hppa-tdep.c (frame_chain_valid, hppa_frame_chain_valid),
+ remote-vx29k.c (get_fp_contents, vx29k_frame_chain_valid),
+ arm-tdep.c (frame_chain_valid, arm_frame_chain_valid): Rename
+ functions so that they are name space clean.
+ * config/pa/tm-hppa.h, config/a29k/tm-vx29k.h,
+ config/arm/tm-arm.h: Update FRAME_CHAIN_VALID.
+
+ * gould-tdep.c (gould_frame_chain_valid), d30v-tdep.c
+ (d30v_frame_chain_valid), d10v-tdep.c (d10v_frame_chain_valid):
+ New functions.
+ * config/gould/tm-np1.h, config/gould/tm-pn.h,
+ config/d30v/tm-d30v.h, config/d10v/tm-d10v.h: Update
+ FRAME_CHAIN_VALID.
+
+Sun Nov 29 11:18:37 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * z8k-tdep.c (z8k_addr_bits_remove), w65-tdep.c
+ (w65_addr_bits_remove), h8500-tdep.c (h8500_addr_bits_remove),
+ m88k-tdep.c (m88k_addr_bits_remove): Function to clean up an
+ address.
+ * config/z8k/tm-z8k.h, config/w65/tm-w65.h, config/m88k/tm-m88k.h,
+ config/h8500/tm-h8500.h: Define ADDR_BITS_REMOVE to call targets
+ corresponding function.
+ * z8k-tdep.c (saved_pc_after_call): Update.
+
+Sat Nov 28 12:24:31 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/z8k/tm-z8k.h, config/w65/tm-w65.h, config/vax/tm-vax.h,
+ config/v850/tm-v850.h, config/tahoe/tm-tahoe.h,
+ config/sparc/tm-sparc.h, config/sh/tm-sh.h,
+ config/rs6000/tm-rs6000.h, config/pyr/tm-pyr.h,
+ config/pa/tm-hppa.h, config/ns32k/tm-umax.h,
+ config/ns32k/tm-merlin.h, config/none/tm-none.h,
+ config/mn10300/tm-mn10300.h, config/mn10200/tm-mn10200.h,
+ config/mips/tm-mips.h, config/m88k/tm-m88k.h,
+ config/m68k/tm-m68k.h, config/m32r/tm-m32r.h,
+ config/i960/tm-i960.h, config/i386/tm-i386.h,
+ config/h8500/tm-h8500.h, config/h8300/tm-h8300.h,
+ config/gould/tm-pn.h, config/gould/tm-np1.h, config/arm/tm-arm.h,
+ config/convex/tm-convex.h, config/d10v/tm-d10v.h,
+ config/alpha/tm-alpha.h, config/a29k/tm-a29k.h: Add parameters to
+ macro INNER_THAN.
+
+ * valops.c (push_word, value_push, call_function_by_hand),
+ breakpoint.c (bpstat_stop_status), blockframe.c
+ (generic_push_dummy_frame, generic_frame_chain_valid), inferior.h
+ (PC_IN_CALL_DUMMY), infrun.c (wait_for_inferior): Update use of
+ INNER_THAN.
+
+Fri Nov 27 11:00:25 1998 Andrew Cagney <cagney@chook>
+
+ * target.h (one_stepped): Move global from here.
+ * infrun.c (singlestep_breakpoints_inserted_p): To here. Rename.
+ Make static.
+ (wait_for_inferior): Update.
+ (resume): Update. Set variable after call to SOFTWARE_SINGLE_STEP.
+
+ * target.h (NO_SINGLE_STEP): Replace with SOFTWARE_SINGLE_STEP_P
+ and SOFTWARE_SINGLE_STEP.
+ * config/sparc/tm-sparc.h, config/rs6000/tm-rs6000.h,
+ config/arc/tm-arc.h: Update.
+ * rs6000-tdep.c (rs6000_software_single_step), sparc-tdep.c
+ (sparc_software_single_step), arc-tdep.c (arc_single_step): New
+ functions. Replace function single_step.
+
+ * config/mips/tm-mips.h (STEP_SKIPS_DELAY_P): Define.
+ * infrun.c (proceed): Cleanup.
+
+Thu Nov 26 11:19:15 1998 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * config/alpha/tm-alpha.h (ABOUT_TO_RETURN): Replace macro.
+ * alpha-tdep.c (alpha_about_to_return): With new function.
+ (heuristic_proc_start): Update.
+ * config/mips/tm-mips.h (ABOUT_TO_RETURN), mips-tdep.c
+ (heuristic_proc_start, mips_about_to_return): Ditto.
+ * config/ns32k/tm-merlin.h (ABOUT_TO_RETURN),
+ config/ns32k/tm-umax.h (ABOUT_TO_RETURN), ns32k-tdep.c
+ (ns32k_about_to_return, ns32k_get_enter_addr): Ditto.
+
+ * config/z8k/tm-z8k.h, config/w65/tm-w65.h, config/vax/tm-vax.h,
+ config/tahoe/tm-tahoe.h, config/sparc/tm-sparc.h,
+ config/sh/tm-sh.h, config/rs6000/tm-rs6000.h, config/pyr/tm-pyr.h,
+ config/pa/tm-hppa.h, config/m88k/tm-m88k.h, config/m68k/tm-m68k.h,
+ config/i960/tm-i960.h, config/i386/tm-i386.h,
+ config/h8500/tm-h8500.h, config/h8300/tm-h8300.h,
+ config/gould/tm-pn.h, config/gould/tm-np1.h,
+ config/convex/tm-convex.h, config/arm/tm-arm.h,
+ config/arc/tm-arc.h, config/a29k/tm-a29k.h: Delete macro
+ ABOUT_TO_RETURN.
+ * config/w65/tm-w65.h (RTL, RTS): Delete macros.
+ * h8500-tdep.c (about_to_return): Delete function.
+
+Thu Nov 26 11:19:15 1998 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * rs6000-tdep.c (rs6000_breakpoint_from_pc): Change big_breakpoint
+ and little_breakpoint to char[] from char*.
+ * remote-array.c (array_insert_breakpoint): Change bp_addr to
+ CORE_ADDR type.
+
+Wed Nov 25 00:13:06 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * vx-share/xdr_ld.c (xdr_ldtabl): Cast second arg to char**
+ instead of char*.
+
+ * configure.tgt (v850): Only build v850ice when cygwin and gui.
+ * configure.in: Add parameter to --enable-build-warnings.
+ * configure: Re-build.
+
+ * c-exp.y (parse_number): Rewrite shift to pacify GCC.
+
+ * config/i960/tm-i960.h (BREAKPOINT): Delete definition - simply
+ wrong.
+
+ * monitor.c (compile_pattern): Make val const char*.
+ (monitor_wait_cleanup): Make old_timeout void*, pointing at
+ old_timeout.
+ (monitor_wait): Update.
+
+ * remote-udi.c, remote-sim.c, remote-e7000.c, hppa-tdep.c,
+ remote-mips.c, sparcl-tdep.c, xcoffread.c: Cast parameters passed
+ to make_cleanup to use the new make_cleanup_func typedef.
+
+ * alpha-tdep.c (MASK): Use LONGEST to avoid arithmetic overflow.
+
+ * config/a29k/tm-a29k.h (TRANSPARENT): Rename macro to
+ TRANSPARENT_FRAME. Avoid name-space clash.
+ * a29k-tdep.c (init_frame_info): Update.
+
+Wed Nov 25 20:37:00 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * rs6000-tdep.c (rs6000_breakpoint_from_pc): Change big_breakpoint
+ and little_breakpoint to char[] from char*.
+ * mem-break.c (memory_insert_breakpoint,
+ memory_remove_breakpoint): Pass address of bplen.
+ * remote-array.c (array_insert_breakpoint): Change bp_addr to
+ CORE_ADDR type.
+
+Tue Nov 24 15:46:33 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * config/mn10300/tm-mn10300.h (TARGET_VIRTUAL_FRAME_POINTER):
+ new target macro.
+ * mn10300-tdep.c (mn10300_virtual_frame_pointer): new function.
+ * tracepoint.c (encode_actions): Use the new target macro to
+ determine the virtual frame pointer, for collecting locals/args.
+ (add_local_symbols, collect_symbol): add a register/offset pair of
+ arguments so that the virtual frame pointer can be passed in.
+
+1998-11-24 Felix Lee <flee@cygnus.com>
+
+ * procfs.c (procfs_wait): handle syscall events first.
+
+ * procfs.c (GDB_GREGSET_TYPE, GDB_FPREGSET_TYPE): new macros.
+ * config/sparc/xm-sun4sol2.h: use them.
+ * core-sol2.c: don't #undef gregset_t and fpregset_t.
+ * sol-thread.c: ditto.
+ * sparc-tdep.c: ditto.
+
+Tue Nov 24 14:13:10 1998 Andrew Cagney <cagney@chook>
+
+ * breakpoint.c (memory_breakpoint_size): Delete global.
+ (read_memory_nobpt): Determine real breakpoint address and size
+ using BREAKPOINT_FROM_PC.
+
+ * defs.h (breakpoint_from_pc_fn): BREAKPOINT_FROM_PC function
+ template.
+ * target.h, mem-break.c (memory_breakpoint_from_pc):
+ Rewrite. Always define. Return NULL when memory breakpoints are
+ not supported.
+ (memory_insert_breakpoint, memory_remove_breakpoint): Call
+ BREAKPOINT_FROM_PC.
+ * target.h (BREAKPOINT_FROM_PC): Provide default.
+ * gdbint.texinfo (BREAKPOINT_FROM_PC): Document.
+
+ * config/rs6000/tm-rs6000.h (BREAKPOINT): Delete macro.
+ (BREAKPOINT_FROM_PC): Define.
+ ({BIG,LITTLE}_BREAKPOINT): Move macros from here.
+ * rs6000-tdep.c: To here.
+ (rs6000_breakpoint_from_pc): New function.
+
+ * config/mn10300/tm-mn10300.h (BREAKPOINT): Delete macro.
+ (BREAKPOINT_FROM_PC): Define, call.
+ * mn10300-tdep.c (mn10300_breakpoint_from_pc): New function.
+
+ * config/mips/tm-mips.h ({BIG,LITTLE}_BREAKPOINT,
+ IDT_{BIG,LITTLE}_BREAKPOINT, PMON_{BIG,LITTLE}_BREAKPOINT,
+ MIPS16_{BIG,LITTLE}_BREAKPOINT): Move macros from here.
+ * mips-tdep.c: To here.
+
+ * config/arm/tm-arm.h ({BIG,LITTLE}_BREAKPOINT): Delete macros.
+ ({ARM,THUMB}_{BE,LE}_BREAKPOINT): Move macros from here.
+ * arm-tdep.c: To here.
+
+ * remote-array.c (memory_breakpoint_size): Delete variable.
+ (array_insert_breakpoint): Obtain breakpoint size using
+ BREAKPOINT_FROM_PC.
+ * remote-st.c (memory_breakpoint_size, st2000_insert_breakpoint):
+ Ditto.
+ * remote-os9k.c (memory_breakpoint_size,
+ rombug_insert_breakpoint): Ditto.
+ * remote-e7000.c (memory_breakpoint_size): Ditto.
+
+Mon Nov 23 11:38:40 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * symfile.c (deduce_language_from_filename): rewrite so as to
+ work from a table of filename extensions, modifiable by the user.
+ (filename_language_table): new data structure.
+ (set_ext_lang_command): new function for new command, "set
+ extension-language". (info_extension_language_command): new
+ function for new command "info extension-languages".
+ (add_filename_language, init_filename_language_table): new
+ support functions for the above.
+ * language.c (language_enum): new function. Support for above.
+
+Mon Nov 23 10:47:54 1998 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * config/sh/tm-sh.h, config/mn10200/tm-mn10200.h,
+ config/m32r/tm-m32r.h, config/arm/tm-arm.h, config/i960/tm-i960.h,
+ config/gould/tm-np1.h, config/d10v/tm-d10v.h,
+ config/v850/tm-v850.h, config/pa/tm-hppa.h, config/a29k/tm-a29k.h,
+ config/mn10300/tm-mn10300.h, config/mips/tm-mips.h
+ (USE_STRUCT_CONVENTION): Cleanup, define macro as function.
+
+ * sh-tdep.c (sh_use_struct_convention), mn10200-tdep.c
+ (mn10200_use_struct_convention), i960-tdep.c
+ (i960_use_struct_convention), gould-tdep.c
+ (gould_use_struct_convention), d10v-tdep.c
+ (d10v_use_struct_convention), v850-tdep.c
+ (v850_use_struct_convention), hppa-tdep.c
+ (hpha_use_struct_convention), m32r-tdep.c
+ (m32r_use_struct_convention), arm-tdep.c
+ (arm_use_struct_convention), mn10300-tdep.c
+ (mn10300_use_struct_convention), a29k-tdep.c
+ (a29k_use_struct_convention), mips-tdep.c
+ (mips_use_struct_convention): New functions
+
+ * value.h, values.c (generic_use_struct_convention): New function,
+ replace macro.
+ * values.c (USE_STRUCT_CONVENTION): Macro defaults to function
+ generic_use_struct_convention.
+
+Sat Nov 21 17:15:40 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * breakpoint.c (bpstat_stop_status): Do not increment hit_count
+ of breakpoint if condition is not true.
+
+ * coffread.c (coff_symtab_read): Discard C_LABEL's that are not
+ function entry points, to avoid getting them in the stack dump
+ instead of the actual function.
+
+ * config/m68k/delta68.mh (NAT_FILE): Undo 1998-08-18 change;
+ without NAT_FILE definition, configure will assume that GDB cannot
+ run native.
+ * config/m68k/nm-delta68.h (KERNEL_U_SIZE): New macro.
+ * delta68-nat.c (kernel_u_size): New function.
+
+Fri Nov 20 10:13:03 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * buildsym.c (end_symtab): Cleanup PROCESS_LINENUMBER_HOOK.
+
+Thu Nov 19 15:21:04 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * rdi-share/host.h: if compiling under Cygwin, make sure new
+ preprocessor define is defined. Define it if not.
+ * rdi-share/hostchan.h: ditto
+ * rdi-share/aclocal.m4: regenerate
+ * rdi-share/configure: regenerate
+
+Thu Nov 19 14:43:44 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: switch back to checking __CYGWIN32__
+ * configure: regenerate
+
+Thu Nov 19 09:53:00 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * exec.c (exec_file_command): Cleanup. Replace #if
+ NEED_TEXT_START_END with if().
+ * config/pa/nm-hppah.h (NEED_TEXT_START_END): Redefine to be 1.
+ * config/convex/tm-convex.h (NEED_TEXT_START_END): Ditto.
+ * config/gould/tm-np1.h (NEED_TEXT_START_END): Ditto.
+ * config/a29k/tm-a29k.h (NEED_TEXT_START_END): Ditto.
+
+Thu Nov 19 13:06:22 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * main.c: Wait until more time has passed before calling
+ new cygwin_ funcs, revert back to the cygwin32_ ones for now.
+ * win32-nat.c: Ditto.
+
+Wed Nov 18 15:03:17 1998 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * 29k-share/udi/udip2soc.c (UDIConnect): Replace sys_errlist with
+ strerror.
+
+Mon Nov 16 14:17:05 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * defs.h: if compiling under Cygwin, define __CYGWIN__ if
+ __CYGWIN32__ is defined and __CYGWIN__ isn't for backwards
+ compatibility.
+
+Fri Nov 13 00:15:08 1998 Geoffrey Noer <noer@cygnus.com>
+
+ Changes to account for name change from cygwin32 to cygwin and
+ clean up Win32-related ifdefs.
+
+ * configure.tgt: check for cygwin* instead of cygwin32.
+ New cygwin gdb_target variable loses the "32".
+ * configure.host: check for cygwin* instead of cygwin32.
+ New cygwin gdb_host variable loses the "32".
+ * configure.in: test __CYGWIN__ instead of __CYGWIN32__,
+ rename gdb_cv_os_cygwin32 variable to drop the "32". Call
+ AM_EXEEXT instead of AC_EXEEXT since that isn't in a released
+ autoconf yet.
+ * configure: regenerate.
+
+ * main.c: drop "32" from cygwin_ funcs, include sys/cygwin.h where
+ cygwin path conv protos live, instead of adding a proto here for
+ them here.
+ * {main.c, ser-tcp.c, ser-unix.c, top.c}: check __CYGWIN__
+ instead of __CYGWIN32__.
+ * source.c: thoughout, check _WIN32 instead of WIN32.
+
+ * config/i386/cygwin32.mh: delete.
+ * config/i386/cygwin.mh: new file, was cygwin32.mh.
+ * config/i386/cygwin32.mt: delete.
+ * config/i386/cygwin.mt: new file, was cygwin32.mt.
+ * config/i386/tm-cygwin32.h: delete.
+ * config/i386/tm-cygwin.h: new file, was tm-cygwin32.h.
+ * config/i386/xm-cygwin32.h: delete.
+ * config/i386/xm-cygwin.h: new file, was xm-cygwin32.h.
+ * config/i386/xm-windows.h: #include xm-cygwin.h now.
+ * config/powerpc/cygwin32.mh: delete.
+ * config/powerpc/cygwin.mh: new file, was cygwin32.mh.
+ * config/powerpc/cygwin32.mt: delete.
+ * config/powerpc/cygwin.mt: new file, was cygwin32.mt.
+ * config/powerpc/tm-cygwin32.h: delete.
+ * config/powerpc/tm-cygwin.h: new file, was tm-cygwin32.h.
+ * config/powerpc/xm-cygwin32.h: delete.
+ * config/powerpc/xm-cygwin.h: new file, was xm-cygwin32.h.
+
+ * rdi-share/aclocal.m4: regenerate with aclocal.
+ * rdi-share/configure: regenerate with autoconf.
+ * rdi-share/{host.h, hostchan.c, hostchan.h, serdrv.c, serpardr.c,
+ unixcomm.c}: check __CYGWIN__ instead of __CYGWIN32__.
+
+Thu Nov 12 17:19:43 1998 John Metzler <jmetzler@cygnus.com>
+
+ * remote.c (remote_get_threadinfo): Support for remote
+ multithread debugging.
+ (remote_get_threadlist): get a partial list of threads
+ (remote_threadlist_iterator): Step through all the threads
+ (init_remote_threadtests): Optional builtin unit test commands.
+
+ * thread.c (bind_target_thread_vector): Implementa a more dynamic
+ way of accessing target specific thread info functions than
+ FIND_NEW_THREADS.
+ (target_thread_info): Function to get extended thread information.
+
+ * gdbthread.h: Export internal data structures corresponding to
+ external detailed thread info response. This is more like a 'ps'
+ command than what might be expected of host based threads. This
+ is for embedded systems.
+
+Wed Nov 11 15:47:00 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * procfs.c (proc_set_exec_trap): don't set PR_ASYNC or PR_FORK
+ in the child process for UnixWare (causes processes forked by
+ the debuggee to hang).
+
+Mon Nov 9 12:00:36 1998 Dave Brolley <brolley@cygnus.com>
+
+ * config/fr30/fr30.mt: New file.
+ * config/fr30/tm-fr30.h: New file.
+
+1998-11-05 Jim Wilson <wilson@cygnus.com>
+
+ * remote-vx.c (net_read_registers, net_write_registers,
+ vx_xver_memory, vx_resume, vx_attach, vx_detach, vx_kill):
+ Change errno to errno_num.
+ * vx-share/xdr_ptrace.c (xdr_ptrace_return): Likewise.
+ * vx-share/xdr_ptrace.h (struct ptrace_return): Likewise.
+
+Thu Nov 5 08:41:33 1998 Christopher Faylor <cgf@cygnus.com>
+
+ * top.c (gdb_readline): Allow CRLF line termination on systems
+ which define CRLF_SOURCE_FILES.
+ * win32-nat.c: 1) Add thread support, 2) fix ability to attach to
+ a running process, and 3) implement limited support for cygwin
+ signals.
+ (thread_rec): New function.
+ (child_add_thread): Ditto.
+ (child_init_thread_list): Ditto.
+ (child_delete_thread): Ditto.
+ (do_child_fetch_inferior_registers): Ditto.
+ (do_child_store_inferior_registers): Ditto.
+ (handle_output_debug_string): Ditto.
+ (child_fetch_inferior_registers): Use do_* function to perform
+ operation.
+ (child_store_inferior_registers): Ditto.
+ (child_continue): Ditto.
+ (child_thread_alive): Ditto.
+ (cygwin_pid_to_str): Ditto.
+ (handle_load_dll): Reorganize, add first attempt at reading
+ dll names from attached processes. Change info messages to provide
+ more information when dll is already loaded.
+ (handle_exception): Changes mandated by new thread-aware structures.
+ (child_wait): Track thread creation/destruction. Handle cygwin
+ signals.
+ (child_create_inferior): Ditto.
+ (child_resume): Ditto.
+ (child_kill_inferior): Ditto. Close child process handle to avoid a
+ handle leak.
+ (child_ops): Fill out child_ops fields that deal with threads.
+ * config/i386/tm-cygwin32.h: Declare function and macro needed
+ for converting a cygwin "pid" to a string.
+ * config/i386/xm-cygwin32.h: define HAVE_SIGSETMASK as 0 since
+ sigsetmask is not defined in cygwin.
+
+Thu Nov 5 08:38:18 1998 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c: Remove obsolete PPC conditionals.
+
+Wed Nov 4 18:44:31 1998 Dave Brolley <brolley@cygnus.com>
+
+ * configure.tgt: Add fr30-*-elf*.
+
+1998-11-03 Jim Wilson <wilson@cygnus.com>
+
+ * c-exp.y (parse_number): Check TARGET_LONG_LONG_BIT when setting
+ high_bit to avoid undefined negative shift.
+
+Mon Nov 2 15:26:33 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: Check cygwin* instead of cygwin32*.
+ * configure: regenerate
+
+Thu Oct 29 10:04:20 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ [Support for trace debugging: registers that were not collected.]
+ * remote.c (remote_fetch_registers): accept 'xxxx' in the register
+ packet, with the meaning "register value is not available".
+ Set register_valid to -1, which will connote "no value available".
+ * findvar.c (read_relative_register_raw_bytes): return failure if
+ register_valid == -1. (value_of_register): return failure if
+ register_valid == -1. (read_var_value): return error if
+ value_of_register fails for a register variable.
+ (value_from_register): return failure if register_valid == -1.
+ * eval.c (evaluate_subexp_standard): return error if
+ value_of_register fails for a register used in an expression.
+ * infcmd.c (do_registers_info): display "value not available"
+ for registers for which register_valid == -1.
+
+ * tracepoint.c (set_raw_tracepoint): just save the filename as is
+ from the symbol table, rather than trying to prepend the dir name.
+ Also save the bfd section. (tracepoints_info): use the section
+ when looking up the function name.
+ * tracepoint.h: add section field to tracepoint struct.
+
+Wed Oct 28 08:01:38 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparcl-tdep.c (send_resp, sparclite_serial_start,
+ sparclite_serial_write): Use remote_timeout instead of hardcoded
+ two second timeout.
+ (download): Fix adjustment of a.out load addresses.
+
+Wed Oct 28 12:32:58 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (--enable-build-warnings): Finish rename from
+ --enable-warnings.
+ (enable-build-warnings): Add -Wpointer-arth, allow =* for
+ sim/common compatibility.
+ * configure: Re-generate.
+
+Wed Oct 21 08:44:30 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * 29k-share/udi/udip2soc.c: Replace sys_errlist with strerror().
+
+Thu Oct 22 09:56:55 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/rs6000/aix4.mh (NATDEPFILES): Move xcoffread.o from here.
+ * config/rs6000/aix4.mt (TDEPFILES): To here.
+
+Wed Oct 21 10:02:31 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * rdi-share/unixcomm.c: Provide definitions of SERPORT and PARPORT
+ on BSD hosts.
+
+1998-10-19 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in (AM_EXEEXT): Use AC_EXEEXT instead.
+ * configure: Regenerated.
+
+Sat Oct 17 17:39:23 1998 Felix Lee <flee@cygnus.com>
+
+ * core-sol2.c: #include <sys/types.h>, for sol2.7 weirdness.
+
+Fri Oct 16 15:31:38 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * m32r-tdep.c (decode_prologue): Return failure if we reach
+ the end of the function without finding the end of the prologue.
+
+1998-10-16 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * command.c copying.c copying.awk core-aout.c core-regset.c
+ corelow.c dcache.c i386-tdep.c i386v4-nat.c i387-tdep.c
+ infcmd.c infptrace.c infrun.c remote.c solib.c symfile.c
+ symmisc.c valarith.c: Add prototypes.
+
+ * defs.h: Add prototype for utils.c::do_run_cleanups.
+
+ * gdbtypes.c: Add prototypes.
+ (make_pointer_type): Add braces to remove nested if-else ambiguity.
+ (make_reference_type): Ditto.
+
+ * printcmd.c (printf_command): Initialize 'f' and 'string' at
+ function startup to suppress possibly-used-before-initialized warning.
+
+ * remote-utils.c: Add prototypes.
+ (sr_pollchar): Add braces to remove nested if-else ambiguity.
+
+ * ser-tcp.c: Add prototypes.
+ (wait_for): Add braces to remove nested if-else ambiguity.
+ (tcp_readchar): Ditto.
+
+ * ser-unix.c: Add prototypes.
+ (get_tty_state): Don't define errno here.
+ (hardwire_readchar): Only define 't' if we are compiling in a Cygwin
+ environment.
+
+ * symtab.c: Add prototypes.
+ (find_methods): Add braces to remove nested if-else ambiguity.
+ (search_symbols): Set 'i' to an initial value to suppress a
+ possibly-used-before-initialized warning.
+
+ * valops.c: Add prototypes.
+ (value_cast): Set 'eltype2' to an initial value to suppress a
+ possibly-used-before-initialized warning.
+ (value_of_variable): Add braces to remove nested if-else ambiguity.
+ (value_of_this): Ditto.
+
+ * valprint.c: Add prototypes.
+ (print_floating): Add braces to remove nested if-else ambiguity.
+
+Thu Oct 15 19:50:48 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * tm-sp64.h (SETUP_ARBITRARY_FRAME, FRAME_SPECIFICATION_DYADIC):
+ Remove, nevermore used.
+
+Thu Oct 15 16:55:00 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * command.c: Include "wait.h" after, rather than before, <wait.h>.
+ "wait.h" was defining all WIF* macro's instead of filling in those
+ that <wait.h> missed.
+
+1998-10-14 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * defs.h: Move _initialize_printcmd, _initialize_stack,
+ _initialize_blockframe out of here and in to their respective .c
+ files.
+ * blockframe.c: Move _initialize_blockframe prototype to here.
+ * printcmd.c: Move _initialize_printcmd prototype to here.
+ * stack.c: Move _initialize_stack prototype to here.
+
+ * source.c, symtab.h: Move _initialize_source prototype to the .c
+ file.
+ * values.c, value.h: Move _initialize_values prototype to the .c file.
+ * gdbthread.h, thread.c: Move _initialize_thread prototype to the .c
+ file.
+ * breakpoint.c, breakpoint.h: Move _initialize_breakpoint prototype
+ to the .c file.
+
+ * abug-rom.c alpha-nat.c alpha-tdep.c annotate.c ax-gdb.c bcache.c:
+ Standardize comments for the prototype section of these files.
+
+ * configure.in: Look in libc for wctype before looking for it in libc.
+
+Tue Oct 13 18:56:51 1998 Felix Lee <flee@cygnus.com>
+
+ * sol-thread.c (ps_pstop, etc): simple test for proc_service.h
+ version didn't work for sol2.6; pushed it to autoconf.
+ * configure.in (gdb_cv_proc_service_is_old): new test.
+ * acconfig.h (PROC_SERVICE_IS_OLD): new define.
+ * configure, config.in: regenerate.
+
+1998-10-13 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * blockframe.c (find_pc_sect_partial_function): Add braces to avoid
+ possible nested-if confusion.
+ * breakpoint.c (breakpoint_here_p): Ditto.
+ (breakpoint_inserted_here_p): Ditto.
+ (breakpoint_thread_match): Ditto.
+
+ * gnu-regex.c: Define _REGEX_RE_COMP only if it isn't already defined.
+ * gnu-regex.h: Define _REGEX_RE_COMP to pick up old compatability
+ prototypes.
+
+ * symtab.h: Add prototype for _initialize_source.
+ * value.h: Add prototype for _initialize_value.
+
+ * defs.h: Include sys/types.h or stddef.h to get size_t.
+ (make_cleanup): Add make_cleanup_func typedef and switch to using
+ a prototype for this function.
+ (mfree): Add prototypes for mmalloc, mrealloc, mfree if we aren't
+ using mmalloc.
+
+ * ax-gdb.c breakpoint.c coffread.c corelow.c dbxread.c
+ dwarf2read.c dwarfread.c elfread.c eval.c exec.c infcmd.c infrun.c
+ mipsread.c nlmread.c os9kread.c parse.c printcmd.c symfile.c
+ symmisc.c symtab.c thread.c top.c tracepoint.c typeprint.c
+ valops.c: Cast parameters passed to make_cleanup to use the new
+ make_cleanup_func typedef.
+
+Tue Oct 13 00:51:48 1998 Felix Lee <flee@cygnus.com>
+
+ * sol-thread.c (ps_pstop, etc): different solaris versions have
+ slightly different prototypes in proc_service.h; compensate.
+
+1998-10-12 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * Makefile.in (AWK): Unused; remove.
+ * configure.in: Remove unused autoconf checks for MINIX, memcpy,
+ poll, select, strings.h.
+ * config.in: Regenerated.
+ * configure: Regenerated.
+
+1998-10-12 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Check for sys/debugreg.h, asm/debugreg.h.
+ * i386v-nat.c: Include asm/debugreg.h, sys/debugreg.h if it is not
+ present.
+
+Sun Oct 11 12:08:07 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * dwarf2read.c (dwarf2_build_psymtabs_hard): Do not adjust the
+ address range of a compilation unit without children.
+
+ * mdebugread.c (parse_partial_symbols): Fix handling of stabs
+ continuations, use xmalloc and xrealloc.
+
+Fri Oct 9 18:14:43 1998 Mark Alexander <marka@cygnus.com>
+
+ * rs6000-tdep.c: Don't include tm.h twice.
+
+1998-10-08 Keith Seitz <keiths@cygnus.com>
+
+ * main.c (main): Remove calls to {pre,post}_add_symbol_hooks.
+ There should be sufficient information/hooks now to eliminate
+ this hack.
+
+ * exec.c (file_command): Add a new hook here to inform ui's
+ when the exec file has changed. Adding it here allows the
+ ui to be informed after symbol reading.
+
+ * gdbcore.h: Add declaration of file_changed_hook.
+
+Thu Oct 8 08:40:42 1998 Mark Alexander <marka@cygnus.com>
+
+ * rs6000-tdep.c (get_saved_register): Define only if
+ USE_GENERIC_DUMMY_FRAMES is defined.
+
+Tue Oct 6 21:35:10 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (DEPFILES): Add TARGET_OBS.
+ (TARGET_OBS): Defined by configure.
+
+1998-10-06 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ Eliminate a few warnings from the compiler.
+ * breakpoint.h: Add prototype.
+ * breakpoint.c (do_enable_breakpoint): cast mem_cnt, i to (void).
+ * configure.in: Check if strdup declaration is necessary.
+ * configure: Regenerated.
+ * defs.h: Add prototypes.
+ * gdb_string.h: Only define strdup if necessary.
+ * gdbthread.h: Add prototypes.
+ * printcmd.c: Add prototyptes.
+ (disassemble_command): Remove unused variable 'section'.
+ * symtab.c: Add prototypes.
+ * symtab.h: Include gnu-regex.h, add prototype.
+ * thread.c: Add prototype.
+
+Mon Oct 5 19:44:39 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ From David Purves <purves@apogee.com>:
+ * stabsread.c (rs6000_builtin_type): Create a complex float instead
+ of an error.
+ (read_sun_floating_type): Similarly.
+ (read_range_type): Create a complex float if self_subrange is
+ true.
+
+Fri Oct 2 19:42:31 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * c-lang.c (emit_char c_printchar c_printstr), c-lang.h (c_printstr)
+ ch-lang.c (chill_printstr chill_printchar) c-valprint.c (c_val_print)
+ ch-valprint.c (chill_val_print) expprint.c (print_subexp) f-lang.c
+ (f_printstr f_printchar emit_char) f-valprint.c (f_val_print)
+ jv-lang.c (java_printchar java_emit_char) jv-valprint.c
+ (java_value_print java_val_print) language.c (unk_lang_printchar
+ unk_lang_printstr unk_lang_emit_char) language.h (struct
+ language_defn LA_PRINT_STRING LA_EMIT_CHAR) m2-lang.c (m2_printstr
+ m2_printchar emit_char) printcmd.c (print_formatted) scm-lang.c
+ (scm_printstr) valprint.c (val_print_string) value.h
+ (val_print_string): Add emit_char routines to language_desc struct
+ to allow finer control over language specific character output issues.
+ Add character width arg to printstr routines to allow handling of
+ wchar_t/Unicode strings. Fix c_printstr to handle wide characters.
+ Supply width argument to LA_PRINT_STRING and val_print_string.
+
+ * jv-lang.c (java_object_type dynamics_objfile java_link_class_type
+ get_dynamics_objfile get_java_object_type) jv-lang.h
+ (get_java_object_type): Make lots of things static.
+
+ * expprint.c (dump_prefix_expression dump_subexp): Move opcode name
+ printing to common routine (op_name).
+ * (dump_subexp): Add support for OP_SCOPE.
+
+Fri Oct 2 16:25:54 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.host (i[3456]86-*-windows): Remove, no longer used.
+ * mswin: Remove directory, no longer used.
+
+Fri Oct 2 18:52:20 1998 Fernando Nasser <fnasser@cygnus.com>
+
+ * sol-thread.c: Fixed prototypes and calls to supply_fpregset and
+ fill_fpregset
+
+1998-10-02 Keith Seitz <keiths@cygnus.com>
+
+ * remote.c (remote_interrupt): Rewrite to use remote_stop.
+ (remote_interrupt_twice): Remove. remote_stop now handles it.
+ (remote_stop): New function which handles interrupting the
+ remote target so that CLUI and GUI use the same core functions
+ to achieve the same goal.
+ (remote_wait): Change to handle remote_stop properly.
+ [interrupted_already]: New static global to help remote_stop.
+ [remote_ops, extended_remote_ops]: Add remote_stop for to_stop member.
+
+ * target.c: Rename static function "ignore" to "target_ignore" and
+ export it so that gdb can determin if some target vector member is
+ actually not defined. Replace all occurances of ignore.
+
+ * target.h: Export target_ignore.
+
+Fri Oct 2 03:51:48 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * target.c (target_xfer_memory): Handle requests with zero
+ transfer length right away.
+
+ * values.c (unpack_double): Set up code, length and signedness of
+ type _after_ checking for typedef.
+
+Thu Oct 1 15:39:27 EDT 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * breakpoint.c (bpstat_stop_status): Do not consider an
+ untripped watchpoint as a "hit".
+
+Thu Oct 1 20:52:39 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * exec.c (exec_file_command), convex-tdep.c (exec_file_command),
+ arm-xdep.c (exec_file_command), remote-rdp.c
+ (remote_rdp_create_inferior), remote-os9k.c
+ (rombug_create_inferior), remote-mm.c (mm_create_inferior),
+ remote-eb.c (eb_create_inferior), remote-es.c
+ (es1800_create_inferior), remote-rdi.c (arm_rdi_create_inferior),
+ remote-sim.c (gdbsim_create_inferior), remote-utils.c
+ (gr_create_inferior), remote-st.c (st2000_create_inferior),
+ remote-nindy.c (nindy_create_inferior), remote-hms.c
+ (hms_create_inferior), remote-e7000.c (e7000_create_inferior),
+ remote-array.c (array_create_inferior), remote-adapt.c
+ (adapt_create_inferior): Replace "exec" with "executable" in
+ messages.
+
+1998-09-25 Keith Seitz <keiths@cygnus.com>
+
+ * rdi-share/unixcomm.c: If using cygwin32, also use the SERPORT and
+ PARPORT defines for win32.
+ (Unix_MatchValidSerialDevice): For cygwin32, valid serial port names
+ start with "com", not "/dev/tty".
+ (Unix_OpenSerial): Do not use O_NONBLOCK on cygwin32.
+
+ * rdi-share/devsw.c (DevSW_Close): Free the device's state
+ (SwitcherState) so that the device may be reopened.
+
+ * remote-rdi.c (mywritec): Send all output through gdb's *_unfiltered
+ functions, ignoring non-ASCII chars, so that non-tty UI's can snarf
+ the output from fputs_hook.
+ (mywrite): Ditto.
+ (arm_rdi_open): Set inferior_pid.
+ (arm_rdi_detach): Pop the target off the target stack so that
+ users can attach and detach multiple times.
+ (arm_rdi_close): Close the opened device and reset inferior_pid, too.
+
+1998-09-24 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Change --enable-warnings to --enable-build-warnings.
+ * configure: Updated.
+
+1998-09-24 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in (WARN_CFLAGS): Add -Wmissing-prototypes.
+ * configure: Regenerated.
+
+1998-09-24 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Add --enable-warnings.
+ Adjust whitespace of other --with and --enable options so that
+ configure --help lines up correctly.
+ * aclocal.m4: Ditto.
+ * Makefile.in (WARN_CFLAGS): Add. Set by configure.
+ * configure: Regenerated.
+
+Thu Sep 24 15:44:34 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-rdi.c: Fix formatting, remove some commented-out code.
+ (init_rdi_ops): Omit needless initializations.
+
+Wed Sep 23 18:21:03 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (remote_address_masked): New function - mask address
+ according to REMOTE_ADDRESS_SIZE.
+ (remote_address_size): New global.
+ (hexnumstr): New function - convert arbitrary unsigned to hex.
+ (remote_write_bytes, remote_read_bytes): Use hexnumstr to
+ construct packet address. Mask address when necessary.
+ (_initialize_remote): Add "set remoteaddresssize" command, set
+ REMOTE_ADDRESS_SIZE variable.
+
+ * NEWS: Update.
+
+Wed Sep 23 18:08:52 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (_initialize_remote, packet_command, print_packet):
+ Pretty print code.
+
+Wed Sep 23 12:32:54 1998 <cagney@amy.cygnus.com>
+
+ * remote.c (packet_command): Test REMOTE_DESC to determine if
+ remote connection is open.
+
+Tue Sep 22 22:27:24 1998 Mark Alexander <marka@cygnus.com>
+
+ Patch from Dawn Perchik <dawn@cygnus.com>:
+ * rs6000-tdep.c (pop_frame): Handle generic dummy frames.
+ (push_arguments): Likewise.
+ (frame_saved_pc): Likewise.
+ (rs6000_frame_chain): Likewise.
+ (ppc_push_return_address): New function.
+ (get_saved_register): New function.
+ * config/powerpc/tm-ppc-eabi.h: Add generic dummy frame macros.
+
+Mon Sep 21 19:29:32 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * defs.h utils.c (fputc_filtered): New function. Does the obvious...
+ * jv-lang.c (java_printchar): Fix output of chars > 0xff. Fold
+ java_emit_char into java_printchar.
+ * language.h (PRINT_LITERAL_FORM): Reformat for readability.
+
+Mon Sep 21 14:38:03 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/arm/tm-arm.h (*_BREAKPOINT): Define both little endian
+ and big endian breakpoint patterns.
+
+ * arm-tdep.c (arm_break_point_from_pc): Insert either big endian
+ or little endian breakpoints depending upon target byte order.
+
+Fri Sep 18 07:53:08 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * sol-thread.c (sol_thread_notice_signals): Use PIDGET when
+ passing pid down to procfs_notice_signals.
+
+Wed Sep 16 14:57:14 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * stabsread.c (resolve_symbol_reference): Return 1 on success, 0 on
+ failure.
+ * (define_symbol): Check return value from resolve_symbol_reference,
+ and drop symbol if it fails.
+
+Tue Sep 15 15:24:16 1998 Stu Grossman <grossman@fencer.cygnus.com>
+
+ * stabsread.c: Make all complaints static.
+ * Fix formatting of live range splitting code.
+ * (resolve_symbol_reference define_symbol resolve_live_range): Change
+ errors to complaints so that bad live range symbols won't abort the
+ entire symbol table. Handle errors by aborting just the current
+ symbol.
+ * (ref_init): Goes away. Folded into ref_add().
+ * (REF_MAP_SIZE): Put parens around parameter so that args like
+ `1 + 2' get handled correctly (yes, this was a real bug).
+ * (ref_add): Remove check for allocation failures. Not necessary
+ when using xrealloc(). Fix pointer arithmetic problem when clearing
+ memory. This and the previous patch prevent random SEGV's when there
+ are lots of live range symbols.
+
+Tue Sep 15 14:02:01 1998 Nick Clifton <nickc@cygnus.com>
+
+ * remote-rdi.c: Prevent multiple attempts to close the remote
+ connection.
+
+Tue Sep 15 10:24:17 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * printcmd.c (examine_i_type): New static - type for instructions.
+ (do_examine): For "i" format, specify examine_i_type.
+ (do_examine): Call value_at_lazy instead of value_at so that
+ examine data is only fetched if it is used.
+ (x_command): If examine data was not fetched, set convenience
+ variable "__" to void.
+ (_initialize_printcmd): Initialize examine_i_type.
+
+Sun Sep 13 01:34:59 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * blockframe.c (find_pc_sect_partial_function): use bfd section
+ of msymbol for end of section comparison.
+
+Fri Sep 11 14:02:49 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c: clean up several unused variables and such.
+
+Fri Sep 11 12:38:34 EDT 1998 Zdenek Radouch (radouch@cygnus.com)
+
+ * arm-tdep.c (arm_push_arguments): fixed frame construction
+
+Thu Sep 10 20:51:23 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * mn10300-tdep.c (mn10300_analyze_prologue): guard against NULL.
+
+Wed Sep 9 19:37:36 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * dbxread.c (IGNORE_SYMBOL): Remove definition, is never used.
+ * os9kread.c: Remove comment mentioning IGNORE_SYMBOL.
+
+Wed Sep 9 11:39:05 1998 Ron Unrau <runrau@cygnus.com>
+
+ * blockframe.c(find_pc_sect_partial_function): look for min syms in
+ the same section when trying to guess the end of a function.
+ * symfile.c(list_overlays_command): use print_address_numeric
+ * remote-sim.c: export simulator_command
+
+1998-09-08 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * breakpoint.c (bpstat_stop_status): Declare a bp match if the
+ current fp matches the bp->fp OR if the current fp is less than
+ the bp->fp if we're looking at a bp_step_resume breakpoint.
+
+Tue Sep 8 19:42:58 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * symtab.h (struct symtab): Remove EXTRA_SYMTAB_INFO hook,
+ not currently used.
+ * symfile.c (allocate_symtab): Deprecate use of
+ INIT_EXTRA_SYMTAB_INFO here.
+
+Fri Sep 4 15:33:25 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * README: Update remote debugging and testsuite info.
+
+Thu Sep 3 13:50:20 1998 Mark Alexander <marka@cygnus.com>
+
+ * config/mn10300/tm-mn10300.h (FP_REGNUM): Redefine to be a
+ pseudo-register, not the same as a3.
+ (D2_REGNUM, D3_REGNUM, A2_REGNUM, A3_REGNUM): Define.
+ * mn10300-tdep.c (fix_frame_pointer): New function.
+ (set_movm_offsets): Use register number macros instead of
+ hard-coded constants.
+ (mn10300_analyze_prologue): Fix to handle redefinition of FP_REGNUM.
+ (mn10300_frame_chain): Fix to handle redefinition of FP_REGNUM;
+ use register number macros instead of hard-coded constants;
+ add missing parameter to call of mn10300_analyze_prologue.
+ (mn10300_frame_saved_pc): Use register number macros instead of
+ hard-coded constants.
+
+Tue Sep 1 12:04:57 EDT 1998 Zdenek Radouch (radouch@cygnus.com)
+
+ Changes to support/fix ARM/ELF port. Use MAKE_MSYMBOL_SPECIAL for
+ both ELF and COFF;
+ * elfread.c (elf_symtab_read): use ELF specific macro
+ * coffread.c (coff_symtab_read): use COFF_MAKE_MSYMBOL_SPECIAL()
+ * arm-tdep.c: separate COFF and ELF thumb processing
+ disable --mapcs-float processing
+ * dwarf2read.c: Disabled building of minimal symbols
+ * config/arm/tm-arm.h: new macros for distinguishing arm/thumb
+ * config/mips/tm-mips.h: use ELF specific macro
+
+Mon Aug 31 15:42:10 1998 Tom Tromey <tromey@cygnus.com>
+
+ * top.c (context_hook): Define.
+
+Tue Aug 25 13:21:58 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * ax-gdb.c (gen_var_ref): Allow for typedef types.
+ (gen_cast, gen_bitfield_ref, gen_expr, gen_deref): ditto.
+
+Mon Aug 24 18:29:03 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (collect_symbol): Handle register doubles that
+ are stored in two registers.
+
+Mon Aug 24 14:39:08 1998 Mark Alexander <marka@cygnus.com>
+
+ * sh-stub.c (undoSStep): Improve comment.
+ * sparc-tdep.c (sparc_extract_struct_value_address): Simplify to use
+ same method on both 32-bit and 64-bit machines.
+ * sparcl-tdep.c (sparclite_check_watch_resources): Simulator doesn't
+ support hardware breakpoints.
+ * config/sparc/tm-sparc.h (CALL_DUMMY): Improve comments.
+
+1998-08-20 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * rdi-share/Makefile.am (INCLUDES): Fix typeo.
+ * rdi-share/Makefile.in: Regenerated.
+
+1998-08-19 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * rdi-share/Makefile.am: Use just `INCLUDES' not `libname_INCLUDES'.
+ * rdi-share/Makefile.in: Regenerated.
+
+1998-08-19 Keith Seitz <keiths@cygnus.com>
+
+ * v850ice.c (v850ice_stop): New function to stop the ICE.
+ (v850ice_load) Pass filename to ICE DLL.
+ (ice_stepi, ice_nexti, ice_cont): Do not directly call the gdb
+ commands -- let the GUI do it so that it can retain control
+ of the display.
+
+Wed Aug 19 15:53:52 1998 Anthony Green <green@hoser.cygnus.com>
+
+ * i386v4-nat.c: Include sys/reg.h if present.
+
+Wed Aug 19 03:07:53 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/alpha/alpha-linux (XDEPFILES): Build ser-tcp.
+
+1998-08-18 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * symtab.c (decode_line_1): For minimal symbol, SKIP_PROLOG to
+ make sure we stop after the frame pointer is locaded and backtrace
+ prints an accurate stack. Complements changes made on Mon Jul 27
+ 10:45:56 1998
+ (decode_line_2): Replaced the whitespace after ">" in a prompt
+ which has been taken away by changes made on Sun Jul 19 02:11:45
+ 1998
+
+1998-08-18 Keith Seitz <keiths@cygnus.com>
+
+ * stack.c: Define new hook, selected_frame_level_changed_hook, which
+ will be called whenever the selected stack level changes.
+ (select_frame): Call the selected_frame_level_changed_hook.
+
+Tue Aug 18 18:03:42 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-rdi.c (arm_rdi_open): Pass serial device name to
+ Adp_OpenDevice, and include it in error reports.
+
+1998-08-18 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Add more header files to AC_CHECK_HEADERS.
+ * configure: Regenerated.
+
+ * command.c: Include wait.h or sys/wait.h if present.
+ * inftarg.c: Ditto.
+ * core-aout.c: Include ptrace.h or sys/ptrace.h if present, based
+ on autoconf test.
+ * infptrace.c: Ditto.
+
+ * expprint.c: Include ctype.h for isprint prototype.
+ * i386aix-nat.c: Include sys/reg.h if autoconf says it is present.
+ * i386v-nat.c: Include ptrace.h, sys/ptrace.h, and sys/reg.h if
+ present, based on autoconf test.
+
+ * utils.c: Include curses.h and term.h if present.
+ (puts_debug): Change 'carriage_return' local variable to return_p
+ to avoid name clash.
+
+ * config/m68k/nm-apollo68b.h: Don't define PTRACE_IN_WRONG_PLACE,
+ determine it with autoconf.
+ * config/i386/nm-linux.h: Don't define NO_SYS_REG_H, determine it
+ with autoconf.
+ * config/i386/nm-i386sco.h: Don't define NO_PTRACE_H, determine it
+ with autoconf.
+ * config/i386/nm-i386v.h: Ditto.
+ * config/i386/nm-symmetry.h: Ditto.
+ * config/m88k/xm-cxux.h: Ditto.
+ * config/m88k/xm-dgux.h: Ditto.
+
+ * config/m68k/delta68.mh (NAT_FILE): nm-delta68.h no longer necessary.
+ * config/m68k/nm-delta68.h: Removed.
+
+Fri Aug 14 11:14:03 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-tdep.c (set_movm_offsets): Change second argument to
+ be the actual args to movm itself. All callers changed. Only set
+ fi->fsr.regs[x] if reg X is saved by the movm instruction.
+
+Fri Aug 14 04:18:23 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * sol-thread.c (lwp_to_thread): Fix error message for failing
+ td_ta_map_lwp2thr call.
+ (ps_lgetLDT): Mask off upper bits in GS register when comparing
+ with selector.
+
+Wed Aug 12 16:30:01 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * remote-sim.c (simulator_command): Reset register cache after
+ simulator command.
+
+Wed Aug 12 09:00:26 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * expprint.c (dump_prefix/postfix_expression): Don't try to print
+ type expressions.
+
+Tue Aug 11 11:33:25 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * c-typeprint.c (c_print_type): Don't crash if varstring is null.
+ * expprint.c expression.h (dump_expression): Rename to
+ dump_prefix_expression.
+ * Print out the expression in normal form. Call print_longest
+ instead of trying to do it ourselves.
+ * (dump_postfix_expression): New function, prints out the expression
+ with indentation and better formatting and interpretation.
+ * parse.c (parse_exp_1): Put calls to dump expressions under ifdef
+ MAINTENANCE_CMDS and expressiondebug variable.
+
+Thu Aug 6 13:20:02 1998 Ron Unrau <runrau@cygnus.com>
+
+ * infrun.c (wait_for_inferior): use stop_func_name instead of
+ stop_func_start to decide that no debug info exists.
+
+Thu Jul 30 13:53:50 1998 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mask_address_p): New variable.
+ (mips_addr_bits_remove): Test mask_address_p to decide whether
+ to mask off the upper 32 bits of addresses.
+ (_initialize_mips_tdep): Add command to set mask_address_p.
+ (mips_call_dummy_address): New function.
+ * config/mips/tm-mips.h (CALL_DUMMY_ADDRESS): Redefine to
+ call mips_call_dummy_address.
+
+1998-07-29 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * symfile.c (add_symbol_file_command): Test for the from_tty
+ parameter and avoid query when not interactive.
+
+Wed Jul 29 10:39:29 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-tdep.c (set_movm_offsets): Do nothing for the am33
+ registers if we are not in am33 mode.
+ (mn10300_frame_chain, mn10300_frame_saved_pc): Similarly.
+ (set_machine_hook): Keep track of whether or not we're in am33 mode.
+
+Mon Jul 27 16:11:42 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (remote_set_transparent_ranges): new function.
+ Send the start and end addresses of all loadable read-only
+ sections down to the trace target, so that it can treat them
+ as "transparent" (ie. don't care if they were collected or not).
+
+Mon Jul 27 15:38:07 1998 Mark Alexander <marka@cygnus.com>
+
+ * mn10300-tdep.c (mn10300_analyze_prologue): Undo previous fix
+ for setting frame address in optimized code; made unnecessary
+ by compiler fixes.
+
+Mon Jul 27 10:45:56 1998 Martin M. Hunt <hunt@cygnus.com>
+
+ * symtab.c (decode_line_1): For minimal symbol, call
+ find_pc_sect_line() to make sure the line number gets set
+ properly.
+ (print_symbol_info): Redeclare function void.
+
+1998-07-27 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * config/d10v/tm-d10v.h (REGISTER_NAMES): sp -> r15. The
+ stack pointer et al are synthesized from the SP_REGNUM (etc)
+ defines and should not be mentioned in REGISTER_NAMES.
+
+Mon Jul 27 08:54:41 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-tdep.c (mn10300_frame_chain): Account for space saved
+ by am33 register saves.
+ (mn10300_frame_saved_pc): Similarly.
+
+Fri Jul 24 14:41:19 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (encode_actions): Treat register names and simple
+ variable names as special cases and don't convert them to byte-
+ codes: these things can be collected far more efficiently
+ without invoking the bytecode interpreter.
+
+Fri Jul 24 13:32:46 1998 Mark Alexander <marka@cygnus.com>
+
+ * config/i386/tm-i386.h (STORE_STRUCT_RETURN): Make it
+ work on hosts of any endianness.
+ * config/i386/tm-i386v.h: Ditto.
+
+Fri Jul 24 07:41:12 1998 Mark Alexander <marka@cygnus.com>
+
+ * mn10300-tdep.c (set_movm_offsets): New helper function
+ for mn10300_analyze_prologue.
+ (mn10300_analyze_prologue): Simplify by factoring out common code.
+ Fix bugs in setting frame address for optimized code.
+ Use read_memory_nobpt instead of target_read_memory.
+
+Thu Jul 23 17:01:17 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (collect_symbol): handle LOC_ARG case.
+
+Thu Jul 23 15:07:40 1998 Dawn Perchik <dawn@cygnus.com>
+
+ * sparc-tdep.c (sparc_init_extra_frame_info): Recognize when we're
+ in a function prologue before the SAVE instruction.
+ (sparc_frame_saved_pc): Ditto.
+ * config/sparc/tm-sparc.h (EXTRA_FRAME_INFO): Add in_prologue flag.
+
+Thu Jul 23 14:58:09 1998 Dawn Perchik <dawn@cygnus.com>
+
+ * i386-tdep.c (i386_get_frame_setup): Recognize function
+ prologues in code compiled with -fcheck-stack.
+
+Thu Jul 23 14:49:27 1998 Dawn Perchik <dawn@cygnus.com>
+
+ * remote-mips.c (remote_mips_insert_hw_breakpoint,
+ remote_mips_remove_hw_breakpoint): New functions for hardware
+ breakpoints on LSI targets.
+ * config/mips/tm-embed.h (target_remove_hw_breakpoint,
+ target_insert_hw_breakpoint): Define to call
+ remote_mips_insert_hw_breakpoint and remote_mips_remove_hw_breakpoint,
+ respectively.
+
+1998-07-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * source.c (print_source_lines): Print "No such file or directory"
+ just once.
+ (directory_command): same as above; resets if user issues dir.
+
+Sun Jul 19 02:11:45 1998 Martin M. Hunt <hunt@cygnus.com>
+
+ * symtab.c (decode_line_2): Instead of printing a prompt
+ and calling command_line_input() without a prompt, just
+ call it with the proper args. This makes the GUI work too.
+
+Fri Jul 17 9:26:50 1998 Ron Unrau <runrau@cygnus.com>
+
+ * blockframe.c (find_pc_sect_partial_function): allow for the possi-
+ bility of multiple symbols at the same address when finding high.
+ * breakpoint.c (resolve_sal_pc): if the function based section lookup
+ fails, try getting the section from the minimal symbol table.
+ * parse.c (write_exp_msymbol): use symbol_overlayed_address to get
+ the LMA of a minimal symbol if unmapped.
+ * symtab.c (find_line_symtab): change interface to return symtab
+ containing the best linetable found.
+ (decode_line_1): use find_line_symtab to set val.symtab. This should
+ improve support for source files with multiple symtabs.
+
+Wed Jul 15 11:51:33 1998 Keith Seitz <keiths@cygnus.com>
+
+ * main.c (main): Fix violations of GNU coding standard.
+
+ * breakpoint.c: Export delete_command.
+
+ * infcmd.c: Export continue_command, stepi_command, and nexti_command.
+
+ * Makefile.in: Add target for v850ice.o.
+
+ * configure.tgt: Add cygwin32 dependencies for v850 ice.
+
+Wed Jul 15 10:58:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * tracepoint.c (set_raw_tracepoint): Cope with symbols that do not
+ have an associated directory.
+
+Mon Jul 13 15:21:04 1998 Mark Alexander <marka@cygnus.com>
+
+ * utils.c (puts_debug): Display non-printable characters in hex
+ instead of octal.
+
+Thu Jul 9 16:16:47 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-tdep.c (mn10300_generic_register_names): New variable.
+ (set_machine_hook): New function. Copy the appropriate register
+ names into reg_names.
+ (_initialize_mn10300_tdep): Set up to call set_machine_hook.
+ * tm-mn10300 (NUM_REGS): Bump to 32.
+ (REGISTER_NAMES): Updated accordingly.
+
+ * mn10300-tdep.c (am33_register_names): New variable.
+ (mn10300_analyze_prologue): Handle regs saved by am33 prologues.
+ * tm-mn10300.h (E0_REGNUM): Define.
+
+Tue Jul 7 7:40:13 1998 Ron Unrau <runrau@cygnus.com>
+
+ * symtab.c (find_pc_sect_psymbol): allow case where textlow is 0
+
+Thu Jul 2 15:57:58 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * breakpoint.c (resolve_sal_pc): Accept absence of innermost
+ Lexical block for breakpoint resolution.
+
+Thu Jul 2 10:22:00 1998 Dawn Perchik <dawn@cygnus.com>
+
+ * mdebugread.c (parse_partial_symbols): Go ahead and read the .mdebug
+ section, but just don't add a 2nd minimal symbol if this is an .mdebug
+ section in an ELF file.
+
+1998-07-01 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * Makefile.in (ax-general.o): Depend on $(defs_h) too.
+ (ax_h): Bother to define this.
+
+Mon Jun 29 19:01:18 1998 Jim Wilson <wilson@cygnus.com>
+
+ * gnu-regex.c (re_comp): Add cast to char * before gettext calls.
+
+Sun Jun 28 11:35:48 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ Improve support for SunPro F77.
+ * dbxread.c (end_psymtab, process_one_symbol): Handle minimal
+ symbols with trailing underscore names.
+ * minsyms.c (find_stab_function_addr): Ditto.
+ * dbxread.c (process_one_symbol): Ignore N_ALIAS for now.
+ * partial-stab.h (case N_ALIAS): Ditto.
+ * stabsread.c (read_sun_builtin_type): Handle boolean types.
+
+Fri Jun 26 14:03:01 1998 Keith Seitz <keiths@cygnus.com>
+
+ * symtab.h (enum namespace): Add new namespaces FUNCTIONS_NAMESPACE,
+ TYPES_NAMESPACE, METHODS_NAMESPACE, and VARIABLES_NAMESPACE used by
+ new search_symbols.
+ Add prototype for search_symbols and free_search_symbols.
+
+ * symtab.c (list_symbols): Rewrite to use new search_symbols.
+ (file_matches): New helper function for search_symbols.
+ (free_search_symbols): New function which frees data returned from
+ search_symbols.
+ (print_symbol_info): New helper function which prints info about a
+ matched symbol to stdout. Extracted from old list_symbols.
+ (print_msymbol_info): New helper function which prints info about
+ a matched msymbol to stdout. Extracted from old list_symbols.
+ (symtab_symbol_info): Extracted from old list_symbols.
+ (variables_info): Use symtab_symbol_info.
+ (functions_info): Use symtab_symbol_info.
+ (types_info): Use symtab_symbol_info.
+ (rbreak_command): Rewrite to use new search_symbols.
+
+Thu Jun 25 22:38:32 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * mips-tdep.c (mips_push_arguments): Use 128-bit stack frame
+ alignment for inferior calls.
+
+Wed Jun 24 23:17:12 1998 Mark Alexander <marka@cygnus.com>
+
+ * mn10200-tdep.c (mn10200_analyze_prologue): Fix calculation
+ of jsr target address.
+
+Tue Jun 23 19:37:46 1998 Mark Alexander <marka@cygnus.com>
+
+ * config/mn10200/tm-mn10200.h (SAVED_PC_AFTER_CALL): Don't
+ zero upper byte of address.
+
+Tue Jun 23 17:32:26 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * rs6000-tdep.c (pop_dummy_frame): use memcpy.
+ (push_arguments): use memset.
+ (various other places): fix up indentation and long lines.
+
+Tue Jun 23 11:58:35 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * configure.in: s/lXext/-lXext/ for Jillian's change.
+
+Tue Jun 23 11:14:04 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * source.c (find_source_lines): fix indentation.
+
+ * config/mips/tm-irix5.h: Modify to work better on irix 6, by
+ making FP registers 8 bytes instead of 4.
+ REGISTER_BYTES: redefine. REGISTER_BYTE(): redefine.
+ REGISTER_VIRTUAL_TYPE: redefine. MIPS_LAST_ARG_REGNUM: redefine.
+ * irix5-nat.c (fetch_core_registers): read 8 bytes per FP register.
+ * mips-tdep.c (FP_REGISTER_DOUBLE): new macro to distinguish
+ targets with 8-byte FP registers (don't use TARGET_MIPS64).
+ (STACK_ARGSIZE): new macro, how much space is taken up on the
+ stack for each function argument (don't use TARGET_MIPS64).
+ (mips_push_arguments): modify logic to work better on Irix 6
+ (n32 ABI).
+
+Tue Jun 23 12:29:53 1998 Jillian Ye <jillian@cygnus.com>
+
+ * configure.in: Add -lXext to mips_extra_libs
+ * configure: Regenerated.
+
+Sun Jun 21 09:31:12 1998 Ron Unrau (runrau@cygnus.com)
+
+ * symtab.c (find_line_pc): assumed that a PC of 0 is illegal.
+ Changed to pass PC as arg and return 1 if valid (0 otherwise).
+ * symtab.h: Change prototype to match.
+ * symtab.c (find_line_pc_range): Use new interface.
+ * breakpoint.c (resolve_sal_pc): Ditto.
+
+Wed Jun 17 15:50:00 1998 Ron Unrau (runrau@cygnus.com)
+
+ * parse.c (target_map_name_to_register): Check target specific
+ aliases *first* so that it can over-ride architectural names
+
+Wed Jun 17 17:13:38 1998 Said Ziouani (saidz@park-street.cygnus.com)
+
+ * remote-sds.c (sds_start_remote): Fix printf call.
+
+Tue Jun 16 16:32:08 1998 Mark Alexander <marka@cygnus.com>
+
+ * mn10200-tdep.c (mn10200_analyze_prologue): Fix null pointer
+ crash when in "start".
+
+Tue Jun 16 14:38:40 1998 Ron Unrau (runrau@cygnus.com)
+
+ * dbxread.c: reset function_start_offset after a finishing N_FUN
+ is seen.
+ * remote-sim.c: allow TARGET_REDEFINE_DEFAULT_OPS to override
+ target vectors as needed.
+
+Sun Jun 14 08:46:25 1998 Ron Unrau (runrau@cygnus.com)
+
+ * partial-stab.h: 'F' and 'f' type N_FUN psymbols should pass
+ CUR_SYMBOL_VALUE as CORE_ADDR instead of long
+ * buildsym.[ch]: export pending_blocks list
+
+Sat Jun 13 13:02:32 1998 Dawn Perchik (dawn@cygnus.com)
+
+ * remote.c: Fix remote help string to match that of help.exp.
+
+Fri Jun 12 14:22:55 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * configure.in (LIBS): Add -lw to the list of libraries if needed.
+
+Thu Jun 11 15:05:10 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * btowc.c: Removed.
+ * configure.in: Don't see if we need to replace btowc().
+ * Makefile.in: Don't include LIBOBJS.
+ * configure: Regenerated.
+ * gnu-regex.c (regex_compile): Only support i18n [:foo:] if
+ we have btowc().
+
+Wed Jun 10 15:39:14 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * c-exp.y: Fix problems with parsing "'foo.bar'::func".
+ Some languages allow symbols with dots.
+
+ * gdbtypes.c (check_stub_method): Cosmetic. Use more descriptive
+ names for parameters.
+
+ * jv-exp.y: Parser now accepts primitive types.
+ * (parse_number): Use correct ifdef for scanf long double support.
+ * jv-lang.c (java_array_type): Initial cut at array support.
+
+ * language.c language.h (set_language): Now returns previous language.
+
+ * symtab.c (find_methods): Make static. Cosmetic changes, including
+ indentation, and adding descriptive comments. Move local variable
+ defs into the block they are used in.
+ * Don't call check_stub_method any more. Use gdb_mangle_name to
+ generate the full method name. find_method doesn't need all the other
+ goobldegook that check_stub_method does.
+ * (gdb_mangle_name): Use more descriptive names for parameters. Fix
+ comment.
+ * (lookup_partial_symbol lookup_block_symbol): Check for java to
+ ensure we can find mangled names.
+ * (decode_line_1): Move local variable defs into the block they are
+ used in. (Improves code readability.)
+
+Wed Jun 10 18:04:35 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * gdbtypes.c (get_discrete_bounds): Assign unsigned type flag for
+ all-positive enum.
+ (create_set_type): Ditto for all-positive set values.
+ * values.c (unpack_field_as_long): Check for typedef in struct
+ field unpacking.
+
+Wed Jun 10 14:06:05 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * configure.in: Add some tests for gnu-regex.c's benefit.
+ See if btowc() function is provided in C library.
+ * configure, config.in: Regenerated.
+ * Makefile.in (CLIBS, CDEPS): Add @LIBOBJS@ to build btowc.c
+ if necessary.
+ * btowc.c: New file.
+
+ * gnu-regex.c: Reorder wchar.h and wctype.h includes for Solaris'
+ benefit.
+ Drop namespace preserving defines for now.
+
+Wed Jun 10 11:53:42 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * gnu-regex.c: Include "gnu-regex.h", not "regex.h".
+
+Wed Jun 10 11:34:07 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * gnu-regex.c, gnu-regex.h: Change LGPL license to GPL license
+ to stay consistent with the rest of GDB.
+
+Wed Jun 10 11:27:39 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * gnu-regex.c, gnu-regex.h: Update to current FSF (glibc) versions.
+
+Wed Jun 10 10:58:18 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * printcmd.c (disassemble_command): move overlay mapping code
+ "up" into find_pc_partial_function.
+ * blockframe.c (find_pc_partial_function): adjust start address
+ and end address for overlays (mapped vs. unmapped addresses),
+ so that all callers of this function may benefit.
+ * m32r-tdep.c (m32r_skip_prologue): adjust indentation.
+
+Mon Jun 8 16:08:10 1998 Ron Unrau <runrau@cygnus.com>
+
+ * objfiles.c (add_to_objfile_sections): All targets to define
+ TARGET_KEEP_SECTION to permit them to retain bfd sections that
+ GDB would otherwise have discarded.
+
+Fri Jun 5 13:56:19 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * dbxread.c (read_dbx_symtab): Don't lower texthigh for last psymtab.
+
+Thu Jun 4 18:35:04 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.c (init_extended_remote_ops): Make extended_remote_ops
+ by copying from remote_ops, move it and init_remote_ops to
+ usual place at end of file, remove "void" from arg lists.
+
+Thu Jun 4 17:51:06 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparc-tdep.c (sparc_fix_call_dummy): Byte-swap the call dummy
+ on bi-endian machines.
+ (sparc_extract_return_value): Handle values smaller than int on
+ machines with little-endian data.
+ (sparc_target_architecture_hook): Set bi_endian flag.
+
+Thu Jun 4 12:14:48 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * printcmd.c (disassemble_command): Fix off-by-one error for
+ disassembling functions in unmapped overlay sections.
+
+Thu Jun 4 10:15:03 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * remote.c: merged.
+
+ - Jim Blandy <jimb@zwingli.cygnus.com>
+ (print_packet, remote_packet_command): New functions.
+ (_initialize_remote): Register the remote-packet command.
+ - David Taylor <taylor@texas.cygnus.com>
+ (_initialize_remote): remote-compare is now
+ compare-sections.
+ - Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+ (remote_compare_command): added warning, issued in case
+ of mismatch only.
+
+Thu Jun 4 08:25:38 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * remote.c (remote_compare_command): New function, new command.
+ Compare object file binary image with corresponding memory on
+ remote target. Report differences.
+
+Tue Jun 2 19:05:04 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparc-tdep.c (sparc_target_architecture_hook): Set target
+ byte order only when it's selectable.
+
+Tue Jun 2 02:01:56 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparc-tdep.c (sparc_target_architecture_hook): New function to
+ set endianness based on machine type.
+ (_initialize_sparc_tdep): Initialize target_architecture_hook.
+ (sparc_print_register_hook): Print PSR and FPSR in fancy format
+ on 32-bit machines.
+ * config/sparc/tm-sparc.h (PRINT_REGISTER_HOOK): Redefine to
+ call sparc_print_register_hook instead of using inline code.
+ * config/sparc/tm-sp64.h (PRINT_REGISTER_HOOK): Remove.
+
+Thu May 28 17:19:14 1998 Keith Seitz <keiths@cygnus.com>
+
+ * main.c (main): Check for NULL from getenv on CYGWIN32.
+
+Thu May 28 09:41:44 1998 Nick Clifton <nickc@cygnus.com>
+
+ * monitor.c (monitor_vsprintf): Handle %%. Patch courtesy of
+ Felix Lee (flee@cygnus.com)
+
+Thu May 28 00:27:35 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * mips-tdep.c (mips_push_dummy_frame): Fix calculation of
+ PROC_REG_OFFSET and PROC_FREG_OFFSET.
+
+Mon Apr 27 14:37:49 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/v850/tm-v850.h (REGISTER_BYTE): FP_REGNUM and
+ FP_RAW_REGNUM use the same register location.
+
+ * v850-tdep.c (v850_scan_prologue): Use FP_RAW_REGNUM instead of
+ FP_REGNUM.
+ (v850_frame_chain): Ditto.
+
+ * config/v850/tm-v850.h (REGISTER_NAMES): Add "fp".
+ (NUM_REGS): Update.
+ (FP_REGNUM): Update.
+ (FP_RAW_REGNUM): Define.
+
+Wed May 27 14:22:31 1998 Keith Seitz <keiths@cygnus.com>
+
+ * main.c (main): Convert the path returned from getenv to a posix
+ path on cygwin32 hosts.
+
+Mon May 25 13:31:27 1998 Keith Seitz <keiths@cygnus.com>
+
+ * remote.c (remote_open_1): If an error occurs starting the remote,
+ pop the target AND return.
+
+Sat May 23 02:23:09 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * dwarf2read.c (read_subroutine_type): Set TYPE_FLAG_PROTOTYPED
+ on C++ functions.
+ * valops.c (value_arg_coerce): Add new argument to indicate whether
+ the function has a prototype, handle integer and float promotions
+ accordingly.
+ (call_function_by_hand): Always call value_arg_coerce, pass down
+ prototype information.
+
+Fri May 22 10:56:36 1998 John Metzler <jmetzler@cygnus.com>
+
+ * remote.c (_initialize_remote): Typo extended__remote
+
+Thu May 21 13:14:25 1998 John Metzler <jmetzler@cygnus.com>
+
+ * gnu-nat.c (init_gnu_ops): Initialization of target ops by assignment.
+ (_initialize_gnu_nat): Call new init
+ * mac-nat.c (init_child_ops): Ditto.
+ (_initialize_mac_nat): Ditto.
+ * monitor.c (init_base_monitor_ops): Ditto.
+ (_initialize_remote_monitors): Ditto.
+ * ppc-bdm.c (init_bdm_ppc_ops): Ditto.
+ (_initialize_bdm_ppc): Ditto.
+ * remote-adapt.c (init_adapt_ops): Ditto.
+ (_initialize_remote_adapt): Ditto.
+ * remote-array.c (init_array_ops): Ditto.
+ (_initialize_array): Ditto.
+ * remote-bug (init_bug_ops): Ditto.
+ (_initialize_remote_bug): Ditto.
+ * remote-e7000.c (init_e7000_ops): Ditto.
+ (_initialize_remote_e7000): Ditto.
+ * remote-eb.c (init_eb_ops): Ditto.
+ (_initialize_remote_eb): Ditto.
+ * remote-es.c (init_es1800_ops): Ditto.
+ (init_es1800_child_ops): Ditto.
+ (_initialize_es1800): Ditto.
+ * remote-hms.c (init_hms_ops): Ditto.
+ (_initialize_remote_hms): Ditto.
+ * remote-mm.c (init_mm_ops): Ditto.
+ (_initialize_remote_mm): Ditto.
+ * remote-nindy.c (init_nindy_ops): Ditto.
+ (_initialize_nindy): Ditto.
+ * remote_nrom.c (init_nrom_ops): Ditto.
+ (_initialize_remote_nrom): Ditto.
+ * remote-os9k (init_rombug_ops): Ditto.
+ (_initialize_remote_os9k): Ditto.
+ * remote-rdi.c (init_rdi_ops): Ditto.
+ (_initialize_remote_rdi): Ditto.
+ * remote-rdp.c (init_remote_rdp_ops): Ditto.
+ (_initialize_remote_rdp): Ditto.
+ * remote-sds.c (init_sds_ops): Ditto.
+ (_initialize_remote_sds): Ditto.
+ * remote-sim.c (init_gdbsim_ops): Ditto.
+ (_initialize_remote_sim): Ditto.
+ * remote-st.c (init_st2000_ops): Ditto.
+ (_initialize_remote_st2000): Ditto.
+ * remote-udi.c (init_udi_ops): Ditto.
+ (_initialize_remote_udi): Ditto.
+ * remote-vx.c (init_vx_ops): Ditto.
+ (init_vx_run_ops): Ditto.
+ (_initialize_vx): Ditto.
+ * remote.c (init_remote_ops): Ditto.
+ (init_extended_remote_ops): Ditto.
+ (_initialize_remote): Ditto.
+ * sparcl-tdep.c (init_sparclite_ops): Ditto.
+ (_initialize_sparcl_tdep): Ditto.
+ * v850ice.c (init_850ice_ops): Ditto.
+ (_initialize_v850ice): Ditto.
+ * win32-nat.c (init_child_ops): Ditto.
+ (_initialize_inftarg): Ditto.
+
+1998-05-21 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-gdb.c (const_var_ref): Don't handle function names. I don't
+ want to implement all the "usual unary conversion" rules for
+ constants.
+ (gen_usual_unary): Turn "function" values into "pointer to
+ function" values, in accordance with ANSI.
+ (gen_deref): Don't do the usual unary conversions here. Let the
+ caller do it. Note that dereferencing a function pointer yields
+ a function designator, which we call an rvalue, not an lvalue.
+ (gen_address_of): Handle functions specially.
+ (gen_struct_ref): Perform the usual unary conversions before
+ calling gen_deref.
+ (gen_expr): In case for the prefix '*' operator, call
+ gen_usual_unary manually.
+
+Wed May 20 15:29:41 1998 Gavin Koch <gavin@cygnus.com>
+
+ * mips/tm-tx39.h (MIPS_DEFAULT_FPU_TYPE): Defined as MIPS_FPU_NONE.
+ * mips/tm-tx39l.h: Same.
+
+Wed May 20 10:12:11 1998 John Metzler <jmetzler@cygnus.com>
+
+ * m32r-tdep.c (decode_prologue): Handle frames compiled with -Os.
+ Split out as separate function called by skip prologue and scan
+ prologue. new formula handles optimization in which the prologue
+ is interleaved with the body of the function. Also recognizes new
+ variations of prologue encoding. Use of frame pointer is
+ essential to debugging, -fno-omit-frame-pointer
+ (m32r_skip_prologue): Call decode prologue, ignore line info
+ (m32r_scan_prologue): Call decode prologue, ignore line info.
+
+Tue May 19 17:23:54 1998 John Metzler <jmetzler@cygnus.com>
+
+ * w89k-rom.c (_initialize_w89k): Call new init function
+ (init_w89k_cmds): Convert to dynamic initialization of monitor_ops
+ data structure for forward compatability with additions to the
+ data structure.
+ * dbug-rom.c (_initialize_dbug_rom): ditto
+ (init_dbug_cmds): ditto
+ * m32r-rom.c (_initialize_m32r_rom): ditto
+ (init_m32r_cmds): ditto
+
+Tue May 19 14:54:11 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (memrange_cmp): use const void * args to avoid
+ ANSI compiler warnings.
+
+1998-05-19 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-gdb.c (gen_fetch, gen_var_ref, gen_deref, find_field,
+ gen_bitfield_ref, gen_expr): Call error, not abort.
+ * ax-general.c (read_const, generic_ext, ax_trace_quick,
+ ax_label, ax_const_d, ax_reg, ax_print): Same.
+
+ * tracepoint.c: Remove the $(...) syntax for memranges.
+ (validate_actionline, encode_actions, trace_dump_command): Remove
+ clauses for the $(...) syntax.
+ (parse_and_eval_memrange): Function deleted.
+ (_initialize_tracepoint): Update function description.
+
+ * ax-gdb.c (_initialize_ax_gdb): Make the "agent" command a
+ subcommand of "maintenance", as it should have been from the
+ beginning. #include "gdbcmd.h", to get the declaration for
+ maintenancelist.
+ * Makefile.in: Document that dependency.
+
+Tue May 19 12:00:58 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * tracepoint.c (get_tracepoint_by_number): new function, to access
+ traceframe_number for use of the GUI.
+
+ * tracepoint.h: added prototype for get_traceframe_number.
+
+Mon May 18 13:34:27 1998 Keith Seitz <keiths@cygnus.com>
+
+ * dbxread.c (process_one_symbol): If block addresses are relative to
+ function start addresses, reset function_start_address whenever a new
+ source file is seen.
+
+Mon May 18 13:04:27 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (get_tracepoint_by_number): make sure to advance
+ arg pointer even if we fail to parse a useful number. Otherwise,
+ since this function is called in a loop, it may loop forever!
+ Also change strtol call to allow arbitrary radix.
+ (map_args_over_tracepoints (and other places)): add QUIT; call
+ to loop, to allow breakout using control-C. Not all loops were
+ analyzed to make sure they could terminate cleanly, but even
+ terminating with a messed-up tracepoint list would be better
+ than not terminating at all!
+ (tdump_command): check to see if we're connected to a trace-
+ capable target (currently only "remote") before doing anything
+ else.
+
+Sat May 16 22:21:48 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * config/d30v/tm-d30v.h (INIT_FRAME_PC_FIRST): Fill in PC into
+ frame struct before extracting saved register offsets.
+
+Fri May 15 22:47:45 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (encode_actions): fix typo in printf format string.
+
+1998-05-15 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Implement a few more tracing operators: ^ | & ~ !
+ * ax-gdb.c (gen_integral_promotions, gen_logical_not,
+ gen_complement): New functions.
+ (gen_binop): New argument MAY_CARRY, indicating whether we need to
+ correct the upper bits of the value after performing the
+ operation. Callers changed.
+ (gen_expr): Handle BINOP_BITWISE_AND, BINOP_BITWISE_IOR, and
+ BINOP_BITWISE_XOR here as well, by calling gen_binop. Handle
+ UNOP_LOGICAL_NOT, UNOP_COMPLEMENT.
+
+ * ax-gdb.c (gen_conversion): Reworked to avoid some unnecessary
+ sign extension.
+
+ * ax-gdb.c (gen_usual_arithmetic): Renamed from gen_usual_binary,
+ to match the ANSI C standard better. Callers changed.
+
+ * ax-gdb.c (gen_traced_pop): Add prototyped declaration.
+
+Fri May 15 18:18:38 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * tracepoint.c (stringify_collections_list): return a collection
+ of strings rather than a single string.
+ (free_actions_list): new function.
+ (encode_actions): process collection of strings returned by
+ stringify_collections_list.
+
+1998-05-15 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-gdb.c (gen_traced_pop): New function.
+ (gen_expr): Call it for comma operator.
+ (gen_trace_for_expr): Call it, instead of writing it out.
+
+ Add facilities for sending arbitrary packets to the remote agent.
+ There are a bunch of improvements to make (make it generic; handle
+ 'O' replies properly), but I just want to get this onto the branch.
+ * remote.c (print_packet, remote_packet_command): New functions.
+ (_initialize_remote): Register the remote-packet command.
+
+Thu May 14 17:52:31 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * tracepoint.c: move actionline_type definition to tracepoint.h.
+ (validate_actionline): make non static.
+
+ * tracepoint.h: move actioline_type definition from tracepoint.c.
+ (validate_actionline) moved prototype from tracepoint.c.
+
+Thu May 14 11:49:18 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * tracepoint.c (validate_actionline): add additional error
+ checking, remove some dead code.
+ (encode_actions): additional cleanups.
+ (trace_find_command): remove some dead code.
+ (trace_find_pc_command): ditto.
+ (trace_find_tracepoint_command): ditto.
+ (trace_find_line_command): ditto.
+ (trace_find_range_command): ditto.
+ (trace_find_outside_command): ditto.
+
+Thu May 14 5:51:00 1998 Ron Unrau <runrau@cygnus.com>
+
+ * symtab.c (decode_line_1): set section for "break *<addr>"
+
+Wed May 13 20:58:02 1998 Mark Alexander <marka@cygnus.com>
+
+ * corefile.c (reopen_exec_file): Reopen the exec file if
+ it has changed.
+
+Wed May 13 15:22:02 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparc-tdep.c (fetch_instruction): New function.
+ (single_step, sparc_init_extra_frame_info, examine_prologue):
+ Use fetch_instruction instead of read_memory_integer
+ to ensure that instructions are always read as big-endian.
+
+Wed May 13 14:42:21 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add AC_FUNC_ALLOCA.
+ * defs.h: Check HAVE_ALLOCA_H rather than sparc. Add _AIX pragma
+ alloca.
+ * configure: Rebuild.
+ * Makefile.in (jv-lang.o, jv-typeprint.o, jv-valprint.o): New
+ targets.
+
+Wed May 13 11:19:08 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (trace_command): Remove old diagnostic code that was
+ preventing tracepoints from being defined with a full-path filename.
+
+Tue May 12 13:17:35 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * stabsread.c (read_one_struct_field): Check for typedef in type
+ tree before clearing bitfield information.
+
+1998-05-11 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-gdb.c (gen_binop): New function, based on gen_mul, to replace
+ gen_mul and gen_div, and handle `%' op as well. Correctly tests
+ type of arguments.
+ (gen_expr): Factor out common code in binary arithmetic operators.
+ Add support for `%'.
+ (gen_mul, gen_div): Removed.
+
+Thu May 7 14:49:38 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/sparc/tm-sp64.h (CALL_DUMMY): Store and retrieve
+ %o0-%o5 as 64-bit values; compensate for stack bias.
+ (USE_STRUCT_CONVENTION): We only pass pointers to structs
+ if they're larger than 32 bytes.
+ (REG_STRUCT_HAS_ADDR): Ditto.
+
+ * sparc-tdep.c (sparc_init_extra_frame_info): Use read_sp()
+ instead of read_register. If the target is a sparc64 and the frame
+ pointer is odd, compensate for the stack bias.
+ (get_saved_register): Use read_sp().
+ (DUMMY_STACK_REG_BUF_SIZE): Use FP_REGISTER_BYTES.
+ (sparc_push_dummy_frame): Use read_sp()/write_sp(). On sparc64,
+ save the PC, NPC, CCR, FSR, FPRS, Y and ASI registers.
+ (sparc_frame_find_saved_regs): Use read_sp(). Read the PC, NPC,
+ CCR, FSR, FPRS, Y and ASI registers from the frame, if it's a
+ dummy frame.
+ (sparc_pop_frame): Use write_sp(). If the target is a sparc64 and
+ the FP is odd, compensate for stack bias.
+ (sparc_store_return_value): Right-justify the return value before
+ writing it to %o0.
+ (sparc_fix_call_dummy): Don't NOP out part of the call dummy on
+ sparc64.
+ (sparc64_read_sp, sparc64_read_fp, sparc64_write_sp,
+ sparc64_write_fp, sp64_push_arguments,
+ sparc64_extract_return_value): New functions to support the
+ sparc64 ABI.
+
+ * dwarfread.c (handle_producer): Set processing_gcc_compilation to
+ the right version number.
+
+ * dwarf2read.c (read_file_scope): Assume we're processing
+ GCC2 output.
+
+Wed May 6 16:34:03 1998 Jeffrey A Law (law@cygnus.com)
+
+ * somsolib.c: Include gdb_stat.h.
+
+Mon May 4 18:34:01 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * ax-gdb.c (gen_mul): new function; (gen_div): new function;
+ (gen_expr): add support for * and / operators, call gen_mul and
+ gen_div as appropriate.
+
+Mon May 4 16:24:22 1998 Mark Alexander <marka@cygnus.com>
+
+ * defs.h (make_run_cleanup): Declare.
+ * solib.c (find_solib): Pass correct number of arguments to
+ make_run_cleanup.
+
+Mon May 4 07:08:25 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (trace_actions_command): actions command must set
+ step_count to zero (in case previous actions have set it but the
+ new set does not).
+
+Sat May 2 09:35:07 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * ocd.h: Add new flags, function codes, and processor types to
+ support new Wiggler capabilities.
+ * (ocd_write_bytes_size): New function to allow atomic writes of
+ memory in sizes larger than a byte.
+
+ * ser-unix.c (baudtab): Add 57600, 115200, 230400, and 460800 baud.
+
+Fri May 1 19:51:32 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * stabsread.c (read_one_struct_field): Do not override supplied
+ bitfield size for a range type value.
+
+ * gdbtypes.c (create_range_type): For a range with positive
+ lower limit, declare range type as unsigned.
+
+Fri May 1 10:58:34 1998 John Metzler <jmetzler@cygnus.com>
+
+ * monitor.c: Turn off debug
+
+Fri May 1 09:29:56 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * breakpoint.c (delete_command): Skip internal breakpoints when
+ all breakpoints are requested.
+
+ * stabsread.c (define_symbol): Record parameter types from Sunpro
+ function stabs in the TYPE_FIELDS of the function type.
+
+Thu Apr 30 15:59:54 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Makefile.in (config-check-targets, config-check-hosts): Removed.
+
+1998-04-30 Paul Eggert <eggert@twinsun.com>
+
+ * Makefile.in (maintainer-clean):
+ Don't get ahead of yourself and delete Makefile
+ before running `make'.
+ (local-maintainer-clean, do-maintainer-clean): New rules.
+
+Wed Apr 29 14:02:59 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * ax-gdb.c (gen_add): when adding a pointer and an int, use
+ the size of the pointer, not the int (typo) to decide how
+ to extend the result.
+
+Wed Apr 29 10:20:40 1998 John Metzler <jmetzler@cygnus.com>
+
+ * nec4102rom.c: New file implements ROM monitor adapter for
+ nec-vr4102 board. This board hosts the vr4111 chip. This file
+ required extensions to the monitor_ops structure, hooks for wait
+ filter, new flags. This version does not support more than one
+ breakpoint and resuming after a breakpoint in 16 bit mode is
+ completely disfunctional.
+
+ * monitor.h: Defined additional hooks for dmpregs, configure_hooks
+ and wait_filter. These additions require that all ROM monitor
+ interfaces be recoded to initialize monitor ops using assignments
+ rather than static structure initialization. Added new bits to
+ flags MO_EXACT_DUMPADDR, MO_HAS_BLOCKWRITES.
+
+ * monitor.c (RDEBUG): Conditional tracing throughout the file.
+ (fromhex): Now recognized upper cse hex digits
+ (monitor_printf_noecho):
+ (monitor_readchar): Tracing interferes with input timing.
+ (monitor_open): Register different memory write functions with
+ dcache_init if MO_HAS_BLOCKWRITES.
+ (flush_monior_dcache): Added as an additional utilty.
+ (monitor-resume): Call continue hook if one has been supplied.
+ (monitor_wait_filter): New function Factored out of monitor wait
+ and used if alternate wait-filter has not been provided.
+ (monitor_wait): call alternate wait filter if provided. Call
+ monitor_dump_regs, a new function factored out from inline code.
+ (monitor_dump_block): A new function used as a utility when
+ monitors must dump several blocks of registers using different
+ commands.
+ (monitor_dump_regs): Call alternate function if provided. Uses new
+ hook in monitor.h.
+ (monitor_write_memory): Engage previouly added hook
+ MO_FILL_USES_ADDR.
+ (monitor_write_even_block): new function supports writing long
+ blocks of 4byte words.
+ (longlongendswap): new internal function
+ (monitor_write_memory_longlongs): new function writes large blocks
+ using command to enter a long long.
+ (monitor_write-memory_block): new Function figures out which block
+ mod to use.
+ (monitor_read_memory): Can now handle dump formats in which the bytes
+ preceeding the requested data is not printed.
+
+Tue Apr 28 19:41:33 1998 Tom Tromey <tromey@cygnus.com>
+
+ * tracepoint.c (memrange_cmp): Another typo fix; `memrbnge' ->
+ `memrange'.
+
+ * tracepoint.c (memrange_cmp): Fixed typo in function intro.
+
+Tue Apr 28 17:41:20 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * symfile.c (overlay_auto_command): Add forgotten parameter
+ definitions.
+ (overlay_manual_command, overlay_off_command): Likewise.
+ (overlay_load_command): Likewise.
+ * tracepoint.c (memrange_cmp): Parameters have type void *, not
+ struct memrange *.
+
+Tue Apr 28 11:08:25 1998 John Metzler <jmetzler@cygnus.com>
+
+ * rom68k-rom.c (_initialize_rom68k): Fix unresolved init_rom_68kcmds.
+
+Mon Apr 27 14:32:21 1998 Mark Alexander <marka@cygnus.com>
+
+ * config/sparc/tm-sparc.h (CALL_DUMMY): Shorten it drastically,
+ make it work on the simulator.
+ (FIX_CALL_DUMMY): Convert to function call instead of inline code.
+ (sparc_fix_call_dummy): Declare.
+ * sparc-tdep.c (sparc_fix_call_dummy): New function, taken from
+ old FIX_CALL_DUMMY macro, with additional fixes for simulator.
+ (sparc_push_dummy_frame): Set registers differently on simulator
+ to prevent corrupted register window save areas.
+
+Mon Apr 27 13:46:40 1998 John Metzler <jmetzler@cygnus.com>
+
+ * rom68k-rom.c (_initialize_rom68k, init_rom68k_cmds):
+ Convert all static initializations of monitor ops structures to
+ executable initializations in order that additions to the data
+ structure definition can me made without repeating this editing
+ exercise.
+ * abug-rom.c (_initialize_abug_rom, init_abug-cmds): Ditto.
+ * cpu32bug-rom.c (_initialize_cpu32bug_rom, init_cpu32bug_cmds): Ditto.
+ * mon960-rom.c (initialize_mon960, init_mon960_cmds): Ditto.
+ * op50-rom.c (initialize_op50n, init_op50n_cmds): Ditto.
+ * ppcbug-rom.c (_initialize_ppcbug_rom, init_ppc_cmds): Ditto.
+ * sh3-rom.c (_initialize_sh3_rom, init_sh3_cmds): Ditto.
+ * sparclet-rom.c (_initialize_sparclet, init_sparclet_cmds): Ditto.
+ * remote-est.c (_initialize_est, init_est_cmds): Ditto.
+ * remote-hms.c ( _initialize_remote_hms, init_hms_cmds): Ditto.
+
+Mon Apr 27 10:43:04 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * gdb_string.h (strdup): Don't specify arguments in prototype.
+
+Sun Apr 26 07:57:21 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * rs6000-nat.c (vmap_ldinfo): Issue warning instead of error if
+ fstat on ldinfo_fd fails. Use objfile->obfd instead of vp->bfd
+ to check for reference to the same file.
+
+ * target.c (target_read_string): Handle string transfers at the
+ end of a memory section gracefully.
+
+Fri Apr 24 17:18:56 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * Makefile.in: enable EXEEXT setting
+
+Fri Apr 24 11:53:49 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * tracepoint.c (add_local_symbols): change type of type from
+ char to int so that type shows up as 'A' or 'L' not 0.
+
+Thu Apr 23 16:37:20 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * README: Minor changes for 4.17 release.
+
+Thu Apr 23 15:44:39 1998 Per Bothner <bothner@cygnus.com>
+
+ * symfile.c (deduce_language_from_filename): .class implies java.
+
+Thu Apr 23 12:52:21 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * configure.in (strerror): Check if function must be declared.
+ * acconfig.h (NEED_DECLARATION_STRERROR): New define slot.
+ * gdb_string.h (strerror): Function declaration issued if
+ NEED_DECLARATION_STRERROR.
+ * configure, config.in: Files regenerated.
+
+Thu Apr 23 12:27:43 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * symfile.c (simple_overlay_update_1): Do not prefix array address
+ by `&'.
+ * bcache.h (BCACHE_DATA_ALIGNMENT): Ditto.
+ * tracepoint.c (encode_actions): Ditto.
+ * language.c, complaints.c, utils.c (varargs.h): Do not include that
+ file here, it is already included indirectly by defs.h.
+ * dbxread.c (dbx_symfile_init, process_one_symbol): Cast xmalloc return
+ value to the appropriate pointer type.
+ * utils.c (floatformat_from_doublest): Ditto.
+ * tracepoint.c (read_actions, _initialize_tracepoint): Ditto.
+ (add_memrange): Likewise with xrealloc return value.
+ * stabsread.c (ref_add): Ditto.
+ * coffread.c (coff_symfile_init): Likewise for xmmalloc return value.
+ * elfread.c (elf_symfile_read): Ditto.
+ * os9kread.c (os9k_symfile_init): Ditto.
+
+Thu Apr 23 00:32:08 1998 Tom Tromey <tromey@cygnus.com>
+
+ * config.in: Rebuilt.
+ * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_STPCPY, HAVE_GETTEXT,
+ HAVE_LC_MESSAGES): Define.
+
+Wed Apr 22 15:38:56 1998 Tom Tromey <tromey@cygnus.com>
+
+ * configure: Rebuilt.
+ * configure.in: Call CY_GNU_GETTEXT.
+ * Makefile.in (top_builddir): New macro.
+ (INTL): Define to @INTLLIBS@.
+ (INTL_DEPS): New macro.
+ (CDEPS): Reference INTL_DEPS, not INTL.
+
+Wed Apr 22 12:58:23 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ Handle missing shared libraries during the examination of a core
+ dump gracefully.
+ * solib.c (find_solib): Use catch_errors around call to
+ solib_map_sections. Use warning instead of error if reading of
+ the shared library name fails.
+ (solib_map_sections): Change return and argument types to make
+ it callable from catch_errors.
+ (symbol_add_stub): Avoid GDB core dump if solib->abfd is NULL.
+ * irix5-nat.c, osfsolib.c (xfer_link_map_member, solib_map_sections,
+ symbol_add_stub): Ditto.
+
+Wed Apr 22 14:34:49 1998 Michael Meissner <meissner@cygnus.com>
+
+ * Makefile.in (INTL*): Add support to link in the intl library,
+ and to add -I options to its source and object directories.
+ (INTERNAL_CFLAGS): Ditto.
+ (C{LIBS,DEPS}): Ditto.
+
+Tue Apr 21 11:20:54 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * mips-tdep.c (gdb_print_insn_mips): Disassemble MIPS instructions
+ with subtarget-specific `mach', rather than fixed default.
+ * config/mips/tm-mips.h (TM_PRINT_INSN_MACH): New macro, default
+ disassembly `mach'.
+
+Mon Apr 20 15:35:03 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * coffread.c (decode_base_type): Treat a long field with size greater
+ than TARGET_LONG_BIT as long long.
+ * values.c (value_from_longest): Print code value in error message.
+
+Mon Apr 20 15:32:21 1998 Mark Kettenis <kettenis@phys.uva.nl>
+
+ * gdb/gdb_string.h (strdup): Declare only if not defined as a
+ macro.
+
+Mon Apr 20 14:18:45 1998 J. Kean Johnston <jkj@sco.com>
+
+ * procfs.c: Added replacement macros for LWP stuff. Fixed support
+ for UnixWare / SVR4.2MP targets and any targets which use
+ multi-file /proc entries. Fixed support for hardware watchpoints.
+ * solib.c: SCO needs some of the same code as SunOS. Change
+ preprocessor conditionals.
+
+ * config/i386/i386sco5.mt: New file.
+ * config/i386/tm-i386sco5.h: New file.
+ * config/i386/i386sco5.mh (NATDEPFILES): add i386v-nat.o.
+ * config/i386/nm-i386v42mp.h
+ (TARGET_HAS_HARDWARE_WATCHPOINTS): define.
+ Add other macros for hardware assisted watchpoints.
+ * config/i386/nm-i386sco5.h: Correct attributions.
+ (TARGET_HAS_HARDWARE_WATCHPOINTS): define.
+ * config/i386/nm-linux.h (target_remote_watchpoint): Pass
+ 'type' through to i386_insert_watchpoint.
+
+Mon Apr 20 14:12:30 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * infrun.c (wait_for_inferior): Don't add signalled processes
+ as new threads.
+ * procfs.c (wait_fd): Note if LWP has exited.
+ (procfs_wait): use GETPID to get process ID.
+
+Sat Apr 18 15:21:04 1998 Stan Cox <scox@cygnus.com>
+
+ * configure.tgt: Added sparc86x support.
+
+Thu Apr 16 13:13:24 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * rdi-share/etherdrv.c (EthernetWrite): Use strerror to get
+ error string if in an ANSI C-ish environment.
+
+Wed Apr 15 18:59:48 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparc-tdep.c (SPARC_HAS_FPU): Define.
+ (sparc_extract_return_value): New function, required to handle
+ machines without floating point.
+ (sparc_store_return_value): Ditto.
+ * config/sparc/tm-sparc.h (EXTRACT_RETURN_VALUE): Call
+ sparc_extract_return_value instead of using inline code.
+ (sparc_extract_return_value): Declare.
+ (STORE_RETURN_VALUE): Call sparc_store_return_value instead
+ of using inline code.
+ (sparc_store_return_value): Declare.
+
+Wed Apr 15 12:19:42 1998 Martin M. Hunt <hunt@cygnus.com>
+
+ * solib.c (enable_break): Only call warning once
+ instead of three times.
+
+Tue Apr 14 16:52:59 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparc-tdep.c (sparc_extract_struct_value_address): Make it
+ work correctly on little-endian hosts.
+ (sparc_push_arguments): New function.
+ (gdb_print_insn_sparc): New function.
+ (_initialize_sparc_tdep): Make gdb_print_insn_sparc the default
+ disassembler, so that SPARClite-specific instructions will
+ be recognized.
+ * sparcl-tdep.c (readchar): Print debugging information.
+ (debug_serial_write): New function, a replacement for SERIAL_WRITE
+ that prints debugging information.
+ * config/sparc/tm-sparc.h (PUSH_ARGUMENTS): Define.
+ (sparc_push_arguments): Declare.
+
+Tue Apr 14 15:43:49 1998 John Metzler <jmetzler@cygnus.com>
+
+ * gdbcfgxref (xref_menu): Call new regex and wild card searches
+ Now you can type in a specific triple like mips64-vr4300-elf or
+ somthing like mips*.h
+ (triple_search, wildcardsearch): The new functions
+
+Mon Apr 13 16:28:07 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * utils.c (warning): added call to warning_hook
+
+ * source.c (find_source_lines): modified to call warning in case
+ of source vs. executable time stamp mismatch. Simplified object
+ file check. Initialized mtime to 0.
+
+ * defs.h: added warning_hook prototype
+
+ * top.c: added warning_hook prototype.
+
+Mon Apr 13 09:54:08 1998 Keith Seitz <keiths@andros.cygnus.com>
+
+ * config/sparc/tm-sun4os4.h (IS_STATIC_TRANSFORM_NAME): Add missing
+ definition.
+
+Fri Apr 10 22:36:28 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ Update support for x86 Solaris 2.
+ * config/i386/tm-i386sol2.h, nm-i386sol2.h: New configuration
+ files for x86 Solaris 2.
+ * config/i386/i386sol2.mt, i386sol2.mh: Use them.
+ * config/sparc/tm-sun4sol2.h (PROCFS_GET_CARRY): New macro, extract
+ carry flag from a given regset.
+ (IS_STATIC_TRANSFORM_NAME): New macro, check if a symbol name
+ is a SunPro transformed name.
+ * i386-tdep.c (sunpro_static_transform_name): New function to
+ extract the source name from a SunPro transformed name.
+ * inferior.h (procfs_first_available, procfs_get_pid_fd):
+ Add prototypes.
+ * infrun.c (wait_for_inferior): Handle breakpoint hit in
+ signal handler without intervening stop in sigtramp.
+ * procfs.c (procfs_lwp_creation_handler): Use PROCFS_GET_CARRY
+ instead of direct access to the status register.
+ (procfs_get_pid_fd): New function, returns procfs fd for a given pid.
+ * sol-thread.c (ps_lgetLDT): New function, returns LDT for a given
+ lwpid.
+ (sol_find_new_threads): Handle failed libthread_db initialization
+ gracefully.
+ * stabsread.c (define_symbol): Use IS_STATIC_TRANSFORM_NAME
+ to check for a SunPro transformed symbol name.
+
+Fri Apr 10 10:35:35 1998 John Metzler <jmetzler@cygnus.com>
+
+ * utils.c (fmthex): A formatting function for hexdumps
+
+ * mips-tdep.c (unpack_mips16): Fixed instruction decoding, lots of
+ bit pattern interpretations. mips_fetch_instruction does not work
+ for 16 bit instructions. Some confusion remains about sign
+ extension in backward branches.
+ (mips32_relative_offset): Sign extension
+ (mips32_next_pc): Major debugging, bit pattern interpretation
+ (print_unpack): debugging printf
+ (fetch_mips_16): new funtion, key on PC low bit, not symbol table
+ (mips16_next_16): Initial major debugging of this function. Lots
+ of bit pattern mistakes.
+ (mips_next_pc): key on low bit of PC, not symbol table.
+ * symfile.c (generic_load): Added a download verification which
+ reads back the loaded code. Download chunk size is now a defined
+ macro. Fixed a bug in which downloading slips into loading one
+ byte at a time. Lower level functions in monitor.c can load long
+ sequences of bytes and make use of these fixups. Referencing
+ bfd-start_address directly was incorrectly getting zero for start.
+
+Thu Apr 9 19:20:32 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-tdep.c (do_fp_register_row): Use alloca rather than arrays
+ with dynamic size.
+
+Wed Apr 8 19:21:42 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * top.c (print_gdb_version): Print 1998 now.
+
+Wed Apr 8 16:57:22 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * source.c: Remove obsolete decl of strstr().
+
+Wed Apr 8 16:47:33 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * solib.c (solib_create_inferior_hook): Remove Ulrich Drepper's
+ patch of March 23 1998.
+ * breakpoint.c (breakpoint_re_set_one): Remove Ulrich Drepper's
+ patch of March 23 1998.
+
+Sat Apr 4 10:05:00 1998 Dawn Perchik <dawn@cygnus.com>
+
+ * mdebugread.c (parse_partial_symbols): If this is an .mdebug
+ section in an ELF file, override a symbol's ECOFF section with its
+ ELF section. Also, fix stabs continuation where a stabs string
+ continues for more than one continuation.
+
+Mon Apr 6 09:17:48 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (mips_push_arguments): Specify dimention of valbuf
+ using MAX_REGISTER_RAW_SIZE.
+
+Sat Apr 4 10:05:00 1998 Dawn Perchik <dawn@cygnus.com>
+
+ * infrun.c: Fix prototype of signals_info to match static funtion.
+
+Thu Apr 2 12:47:41 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * sol-thread.c (sol_thread_store_registers): Save & restore new
+ value of single updated register to prevent accidental clobbering.
+
+Wed Apr 1 22:01:09 1998 Mark Alexander <marka@cygnus.com>
+
+ * config/sparc/tm-sparclite.h (TARGET_BYTE_ORDER_SELECTABLE): Define.
+ * config/sparc/sparclite.mt: Link in the erc32 simulator.
+
+Wed Apr 1 16:30:49 1998 Ian Dall <Ian.Dall@dsto.defence.gov.au>
+
+ * ns32k-tdep.c (flip_bytes, ns32k_localcount,
+ ns32k_get_enter_addr, sign_extend): Restore functions mysteriously
+ deleted.
+
+ * ns32knbsd-nat.c: New (?) file to support fetching and storing
+ registers on NetBSD hosts.
+
+ * nbsd.mh (NATDEPFILES): put ns32knbsd-nat.o instead of
+ ns32k-nat.o
+
+ * ns32km3-nat.c (reg_offset): Get order of floating point
+ registers correct. Add extra 32382 register offsets.
+ (REG_ADDRESS): define to point at correct part of thread
+ state. Use calls to "warning" instead of "message".
+
+ * tm-nbsd.h, tm-ns32km3.h (REGISTER_NAMES, NUM_REGS,
+ REGISTER_BYTES, REGISTER_BYTE): redefine allowing for 32382
+ fpu registers.
+
+Wed Apr 1 13:43:07 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * NEWS: m68k-motorola-sysv host support added.
+ * coffread.c (coff_start_symtab): Accept the filename as an argument,
+ set it here. Callers updated.
+
+Wed Apr 1 23:13:23 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/mips/tm-mips.h (REGISTER_VIRTUAL_TYPE): Handle 32 bit SR,
+ FSR and FIR registers.
+ (REGISTER_VIRTUAL_SIZE): Compute using REGISTER_VIRTUAL_TYPE.
+ (REGISTER_RAW_SIZE): Define using REGISTER_VIRTUAL_SIZE.
+
+ * config/mips/tm-mips64.h: Ditto.
+
+Tue Mar 31 21:30:39 1998 Nick Clifton <nickc@cygnus.com>
+
+ * arm-tdep.c (gdb_print_insn_arm): Attach a fake Thumb symbol
+ vector to the info structure when disassembling thumb
+ instructions.
+
+ * coffread.c (coff_symtab_read, read_one_sym,
+ process_coff_symbol): Support Thumb symbol types.
+
+ * dbxread.c (process_one_symbol): Call SMASH_TEXT_ADDRESS (if it
+ is defined) for function symbols.
+
+Tue Mar 31 16:39:28 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c (get_tracepoint_by_number): change warning to note.
+ (delete_trace_command): suppress y/n query if no tracepoints, or
+ if not from_tty. (trace_pass_command): reject junk at end of args.
+ (read_actions): an action list consisting only of "end" is discarded.
+ (validate_actionline (for collect command)): an argument beginning
+ with a dollar_sign but not recognized as a special argument is
+ parsed like any other expression -- if it isn't a register name,
+ it's rejected. Also reject an empty argument to while-stepping.
+ (trace_find_command): reject a negative frame number argument.
+ (_initialize_tracepoint): set $traceframe initially to -1.
+
+Mon Mar 30 16:42:12 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * rdi-share/Makefile.am, rdi-share/aclocal.m4,
+ rdi-share/configure: New files.
+ * rdi-share/configure.in: Rewritten to be an autoconf input file.
+ * rdi-share/Makefile.in, rdi-share/configure: Generated by
+ automake/autoconf.
+ * rdi-share/dbg_hif.h, etherdrv.c, hostchan.c: Use autoconf tests
+ to check environment.
+
+Sun Mar 29 15:17:16 1998 Keith Seitz <keiths@onions.cygnus.com>
+
+ * tracepoint.c (trace_start_command): Set trace_running_p.
+ (trace_stop_command): Clear trace_running_p.
+
+Sat Mar 28 15:19:48 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * NEWS: Update for 4.17 release.
+
+Fri Mar 27 10:15:50 1998 David Taylor <taylor@tito.cygnus.com>
+
+ * tracepoint.c (parse_and_eval_memrange): Fix memory leaks.
+ (encode_actions): Use the new gen_trace_for_expr function
+ instead of expr_to_address_and_size; collect registers when
+ using expressions. (clear_collection_list): Fix memory leak.
+
+1998-03-26 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-gdb.h (gen_trace_for_expr): Add prototype.
+
+Thu Mar 26 17:24:23 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * tracepoint.c (validate_actionline): Fix memory leak.
+ (encode_actions): Fix memory leak.
+
+Thu Mar 26 16:16:55 1998 David Taylor <taylor@tito.cygnus.com>
+
+ * tracepoint.c (trace_mention): New function.
+ (trace_command): Call it.
+
+1998-03-26 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-general.c (ax_reqs): New function.
+ * ax.h (enum agent_flaws, struct agent_reqs): New types.
+ (agent_reqs): New extern prototype. Well, actually, this was
+ there before, due to a premature checkin.
+ (struct aop_map): Add new `data_size' member.
+ * ax-general.c (aop_map): Supply its value.
+ * ax-gdb.c (agent_command): Call ax_reqs, for testing.
+
+ * ax-general.c (ax_print): If we encounter an invalid or
+ incomplete opcode, don't abort; just print an error message.
+
+ * ax-gdb.c: Generate trace bytecodes, as appropriate.
+ (trace_kludge): New variable.
+ (gen_fetch, gen_bitfield_ref): Emit trace bytecodes, if asked
+ nicely.
+ (expr_to_agent): Ask for no trace bytecodes.
+ (gen_trace_for_expr): New function.
+ (agent_command): Call it, and display the result appropriately ---
+ no struct axs_value, so no type or kind information.
+
+ * ax-gdb.c: Use TARGET_CHAR_BIT throughout, not HOST_CHAR_BIT.
+
+Thu Mar 26 22:29:28 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * tracepoint.c (trace_status_command): Recognize a boolean return
+ value from the stub to indicate whether trace experiment is
+ running. Export this value as a global state variable.
+ (trace_running_p) for use by the GUI. (from Michael Snyder)
+ (trace_pass_command) added call to modify_tracepoint_hook.
+
+ * tracepoint.h export trace_running_p.
+
+Thu Mar 26 13:08:01 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * tracepoint.c (validate_actionline): do not error out if
+ exp->elts[0].opcode is not on short line -- let
+ expr_to_address_and_size handle it.
+
+1998-03-26 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * tracepoint.c: Include "ax.h", not "agentexpr.h".
+
+ * tracepoint.c (encode_actions): Call expr_to_address_and_size,
+ not simply expr_to_agent.
+
+ * ax-general.c: Comment out code in progress, so everyone else can
+ at least compile.
+
+ * gdbtypes.c: Doc fix.
+
+ * ax.h, ax-gdb.h, ax-general.c, ax-gdb.c: New files.
+ * Makefile.in (REMOTE_OBJS): Add ax-general.o and ax-gdb.o.
+ (SFILES): Add ax-general.c, ax-gdb.c.
+ (ax_h): New variable.
+ (ax-general.o, ax-gdb.o): New rules.
+
+
+Tue Mar 24 16:22:40 1998 Stu Grossman <grossman@bhuna.cygnus.co.uk>
+
+ * Makefile.in: Derive SHELL from configure.
+ * config/d10v/d10v.mt config/m32r/m32r.mt
+ config/mn10200/mn10200.mt config/mn10300/mn10300.mt
+ config/d30v/d30v.mt: Remove -lm from SIM. This prevents
+ dependency checking of -lm (under NT native builds). (It is
+ automatically added by configure if it exists.)
+ * doc/configure mswin/configure nlm/configure
+ testsuite/gdb.base/configure testsuite/gdb.c++/configure
+ testsuite/gdb.chill/configure testsuite/gdb.disasm/configure
+ testsuite/gdb.stabs/configure testsuite/gdb.threads/configure:
+ Regenerate with autoconf 2.12.1 to fix shell issues for NT native
+ builds.
+
+Mon Mar 23 18:10:57 1998 Ulrich Drepper (drepper@cygnus.com)
+
+ * solib.c (solib_create_inferior_hook): Rewrite previous
+ change to check the type of file via BFD.
+
+Mon Mar 23 13:52:28 1998 Ulrich Drepper (drepper@cygnus.com)
+
+ * breakpoint.c (breakpoint_re_set_one): Treat bp_shlib_events
+ like bp_breakpoints.
+ * solib.c (solib_create_inferior_hook): Relocate section addresses
+ if the alleged start address doesn't agree with the PC.
+
+Sat Mar 21 19:34:49 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ merged changes from Foundry (list follows by file/author):
+
+ - Tom Tromey <tromey@cygnus.com>
+ * Makefile.in (gdbres.o): New target.
+ (WINDRES): New define.
+ * configure: Rebuilt.
+ * configure.in (WINDRES): Define.
+ (CONFIG_OBS): Include gdbres.o on Windows.
+ * gdbtool.ico: New file.
+ * gdb.rc: New file.
+
+ * ser-unix.c
+ - Keith Seitz <keiths@onions.cygnus.com>
+ (wait_for): Don't reset the timeout_remaining for CYGWIN32,
+ since we now effectively poll the serial port.
+ Don't reset the current_timeout, either, since this member is used
+ by hardwire_readchar to track the timeout and call the ui_loop_hook.
+ (hardwire_readchar): Poll the serial port for Cygwin32. We timeout
+ every second, update the UI, and loop around doing this until we
+ have hit the real timeout or we get data or an error. This will
+ allow the UI to stay active while gdb is "blocked" talking to the
+ target.
+ - Martin M. Hunt <hunt@cygnus.com>
+ (wait_for): Do reset current_timeout because it is only used to
+ keep track of what the current timeout for the scb is.
+
+ * top.c
+ - Martin M. Hunt <hunt@cygnus.com>
+ (quit_confirm): Change exit message again
+ for GUI.
+ (pc_changed_hook): Add prototype.
+ - Tom Tromey <tromey@cygnus.com>
+ (quit_confirm): Added missing `else'.
+ (quit_confirm): Special-case message if init_ui_hook is
+ set.
+
+ * symtab.c
+ - Martin M. Hunt <hunt@cygnus.com>
+ (find_pc_sect_line): If no symbol information
+ is found, return correct pc anyway.
+ (find_methods): Comment out an apparently
+ bogus error message because it messes up Foundry.
+
+ * serial.c
+ - Martin M. Hunt <hunt@cygnus.com>
+ (_initialize_serial): Add a description of
+ "set remotelogbase".
+
+ * findvar.c
+ - Martin M. Hunt <hunt@cygnus.com>
+ (write_register_gen): Add call to
+ pc_changed_hook if the PC is being changed.
+
+ * defs.h
+ - Martin M. Hunt <hunt@cygnus.com>
+ (pc_changed_hook): Define.
+
+ * command.c
+ - Martin M. Hunt <hunt@cygnus.com>
+ (do_setshow_command): If no arguments are supplied,
+ don't dump core, instead print out an error message.
+
+ * breakpoint.c
+ - Martin M. Hunt <hunt@cygnus.com>
+ Make set_raw_breakpoint, set_breakpoint_count,
+ and breakpoint_count non-static so they are accessible from
+ elsewhere.
+ (enable_breakpoint): Enable breakpoint
+ with same disposition instead of changing all breakpoints
+ to donttouch.
+
+ * annotate.h
+ - Keith Seitz <keiths@onions.cygnus.com>
+ Add declarations for annotation hooks.
+
+ * annotate.c
+ - Keith Seitz <keiths@onions.cygnus.com>
+ Add hooks: annotate_starting_hook, annotate_stopped_hook,
+ annotate_signalled_hook, annotate_exited_hook.
+ (annotate_starting): If hook exists, call it instead.
+ (annotate_stopped): If hook exists, call it instead.
+ (annotate_exited): If hook exists, call it instead.
+ (annotate_signalled): If hook exists, call it instead.
+
+Fri Mar 20 14:45:36 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * gdbserver/Makefile.in: add dependency on XM_CLIBS.
+ * gdbserver/low-sim.c (registers) force into alignment.
+ (create_inferior): Fix typo on new_argv; add abfd arg to
+ sim_open, sim_create_inferior. Add reg_size arg to
+ sim_fetch_register, sim_store_register. Make simulator
+ take a single-step to get into a known running state.
+ * gdbserver/gdbreplay.c: include fcntl.h for def'n of F_SETFL.
+ * gdbserver/server.c: Add remote_debug variable to control
+ debug output.
+ * gdbserver/server.h: Add prototypes for enable/disable_async_io.
+ * gdbserver/remote-utils.c: add verbose debugging output controlled
+ by "remote_debug" variable. Add call to "disable_async_io()"
+ to avoid being killed by async SIGIO signals.
+ * config/m32r/m32r.mt: define GDBSERVER_(LIBS and DEPFILES),
+ so that gdbserver can be built with the m32r simulator.
+
+Fri Mar 20 09:04:06 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbtypes.h (builtin_type_{,u}int{8,16,32,64}): New gdb builtin
+ types.
+
+ * gdbtypes.c (_initialize_gdbtypes): Initialize new types.
+
+ * mips-tdep.c (do_gp_register_row): Pad register value when GP
+ register is smaller than MIPS_REGSIZE.
+
+ * findvar.c (value_of_register): When raw and virtual register
+ values identical, check that sizes are consistent.
+
+Thu Mar 19 11:32:15 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * minsyms.c (compare_minimal_symbols): If addresses are identical,
+ then compare on names. Sorted list should have symbols with
+ identical addresses AND names adjacent, so dups can be discarded.
+
+Wed Mar 18 12:50:17 1998 Jeff Law (law@cygnus.com)
+
+ * stabsread.c (define_symbol): Don't look for ',' as a LRS
+ indicator.
+
+Wed Mar 18 10:34:51 1998 Nick Clifton <nickc@cygnus.com>
+
+ * rdi-share/etherdrv.c: Set sys_errlist[] as char * not const char *.
+
+Fri Mar 13 15:43:53 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/mips/xm-mips.h (CC_HAS_LONG_LONG): Undefine for Ultrix
+ when compiling with native cc, the compiler has broken long long
+ support.
+
+Fri Mar 13 15:37:02 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/m68k/xm-sun3os4.h: Remove malloc declarations, they
+ are handled via autoconf now.
+ * remote.c (remote_ops, extended_remote_ops): Replace static
+ forward declaration by moving the static definition to the top of
+ the file, for old K&R compilers.
+ * tracepoint.c (collect_symbol, trace_start_command):
+ Replace ANSI string concatenation with K&R compatible simple string.
+
+1998-03-11 Fred Fish <fnf@ninemoons.com>
+
+ * source.c (select_source_symtab): Don't reach error if we have
+ a current_source_symtab from reading in partial symbol table.
+
+Fri Mar 6 13:10:27 1998 Fred Fish <fnf@cygnus.com>
+
+ * utils.c (quit): Call SERIAL_DRAIN_OUTPUT rather than
+ SERIAL_FLUSH_OUTPUT.
+ * serial.h (struct serial_ops): Add drain_output, pointer to
+ function that waits for output to drain.
+ (SERIAL_DRAIN_OUTPUT): Macro to wait for output to drain.
+ * ser-unix.c (hardwire_drain_output): New function and prototype.
+
+ * ser-unix.c (hardwire_ops): Add entry for drain_output function.
+ * ser-tcp.c (tcp_ops): Ditto.
+ * ser-ocd.c (ocd_ops): Ditto.
+ * ser-mac.c (mac_ops): Ditto.
+ * ser-go32.c (dos_ops): Ditto.
+ * ser-e7kpc.c (e7000pc_ops): Ditto.
+
+Thu Mar 5 16:07:41 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * sparcl-tdep.c: fix #endif comments
+
+Thu Mar 5 15:10:35 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Makefile.in (BISON): Configure substitutes in @YACC@, not @BISON@.
+
+Thu Mar 5 14:42:41 1998 Keith Seitz <keiths@onions.cygnus.com>
+
+ * ocd.c (ocd_open): If we fail ocd_start_remote, make sure we
+ error () so that we abort out of bdm_ppc_open.
+
+Wed Mar 4 16:53:52 1998 Martin M. Hunt <hunt@cygnus.com>
+
+ * serial.c (_initialize_serial): Add a description of
+ "set remotelogbase".
+
+ * command.c (do_setshow_command): If no arguments are supplied,
+ don't dump core, instead print out an error message.
+
+Wed Mar 4 01:39:08 1998 Ron Unrau <runrau@cygnus.com>
+
+ * elfread.c (elf_symtab_read): merge SYMBOL_IS_SPECIAL into
+ MAKE_MSYMBOL_SPECIAL
+ * config/mips/tm-mips.h: ditto
+
+Tue Mar 3 17:19:08 1998 John Metzler <jmetzler@cygnus.com>
+
+ * config/mips/tm-vr4xxx.h: implements vr4111 as separate from 4300
+ * config/mips/vr4xxx.tm: implements vr4111 as separate from 4300
+ * configure.tgt: Recognise mips64vr4111-*-elf as vr4xxx
+ * dwarfread.c (read_tag_pointer_type): Pointer sizes now come from
+ TARGET_PTR_BIT rather from sizeof(char *) on host.
+
+Tue Mar 3 14:37:02 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * alpha-nat.c (fetch_osf_core_registers): Renamed from
+ fetch_aout_core_registers.
+ (alpha_osf_core_fns): Renamed from alpha_aout_core_fns, change
+ flavour to bfd_target_unknown_flavour for OSF core files.
+
+Mon Mar 2 17:44:13 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * breakpoint.c (_initialize_breakpoint): Make "en" an alias
+ for "enable" (so that it doesn't conflict with "end").
+
+Mon Mar 2 17:04:25 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Makefile (VERSION): Bump to 4.17.1.
+
+Mon Mar 2 16:59:15 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * rdi-share/etherdrv.c (sys_errlist): Add correct decl for Linux.
+
+Mon Mar 2 16:51:44 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Makefile.in (YYFILES): Remove in maintainer-clean, not distclean.
+
+Mon Mar 2 16:47:11 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * Makefile.in (distclean): Add `rm $(YYFILES)'.
+
+Mon Mar 2 16:45:48 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * coffread.c (coff_read_enum_type): Set TYPE_FLAG_UNSIGNED if enum
+ is unsigned.
+
+Sun Mar 2 15:16:13 1998 Richard Henderson <rth@cygnus.com>
+
+ * configure.host, configure.tgt: Add sparc-linux.
+ * sparc-nat.c: Include <asm/reg.h> not <machine/reg.h> for Linux.
+ * config/sparc/*linux*: New files.
+
+Mon Mar 2 12:12:41 1998 Anthony Thompson (athompso@cambridge.arm.com)
+
+ * arm-tdep.c (gdb_print_insn_arm): Call print_insn_big_arm
+ if we're big endian; else call print_insn_little_arm.
+
+Mon Feb 24 11:24:57 1998 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.in (BISON): Don't even pretend to use yacc.
+ (c-exp.tab.o): Use bison -o to use a unique intermediate file.
+ (f-exp.tab.o, m2-exp.tab.o): Likewise.
+ (jv-exp.tab.o): Likewise.
+
+Tue Feb 24 03:32:59 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_fetch_register): Don't abort when the
+ register size is wrong.
+
+Thu Feb 19 16:49:48 1998 John Metzler <jmetzler@cygnus.com>
+
+ * target.c (debug_to_fetch_registers,debug_to_store_registers,
+ debug-to_insert_breakpoint,debug_to_remove_breakpoint): tracing
+ 64 bit targets crashed long long printfs.
+
+Tue Feb 17 16:36:22 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * symfile.c (read_target_int_array): rename read_target_long_array
+ and force the sizeof an ovly_table element to sizeof(long),
+ instead of sizeof(int).
+
+Tue Feb 17 18:05:05 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * remote-mips.c (mips_request): Use unsigned long during parsing
+ returned value from monitor, to prevent accidental sign extension.
+
+Tue Feb 17 14:28:33 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * acconfig.h: FORCE_MMCHECK changed to MMCHECK_FORCE.
+ * configure.in: Ditto.
+ * configure: Regenerated.
+
+Tue Feb 17 14:07:34 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * gdbtypes.c (check_typedef): Do not try to resolve the length of
+ a type which has TYPE_FLAG_TARGET_STUB set, if the target type has
+ set TYPE_FLAG_TARGET_STUB as well.
+
+Tue Feb 17 14:32:18 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register):
+ Pass register size to sim_{fetch,store}_register. Check nr of
+ register bytes transfered is correct.
+
+Mon Feb 16 14:05:54 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-d10v.c (remote_d10v_open): Call push_remote_target
+ instead of open_remote_target.
+
+ * remote.c (remote_xfer_memory): Use REMOTE_TRANSLATE_XFER_ADDRESS
+ to translate addr/size when defined.
+ (open_remote_target): Delete.
+
+ * target.h (open_remote_target): Delete.
+
+ * config/d10v/tm-d10v.h (REMOTE_TRANSLATE_XFER_ADDRESS): Define.
+
+Mon Feb 16 14:05:54 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (d10v_extract_return_value): Wierd. GCC wants to
+ return odd sized register quantities with only half of the first
+ register used!
+
+ * config/d10v/tm-d10v.h (USE_STRUCT_CONVENTION): Use stack when
+ size > 8.
+
+Mon Feb 16 14:05:54 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/d10v/tm-d10v.h (USE_STRUCT_CONVENTION): Define. True when
+ sizeof type > 1.
+
+Sun Feb 15 16:10:50 1998 Ron Unrau <runrau@cygnus.com>
+
+ * parse.c (write_dollar_variable): call new function
+ target_map_name_to_register to allow targets to define their own
+ register name aliases.
+ * infcmd.c (registers_info): use target_map_name_to_register so that
+ "print $reg" and "info reg $reg" use the same register name aliases.
+
+Fri Feb 13 16:40:30 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/i386/i386mk.mt (OBJFORMATS): Delete, no longer used.
+ * config/i386/xm-i386mk.h: Fix an include.
+ * config/pyr/tm-pyr.h (PC_INNER_THAN): Remove, never used.
+
+Thu Feb 12 16:12:07 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * remote-mips.c (mips_enter_debug): Sleep before sending CR to
+ monitor.
+ (mips_exit_debug): Accept any whitespace / verbiage before monitor
+ prompt reappears.
+
+Thu Feb 12 18:25:42 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (show_regs): Avoid use of %llx when printing 8 byte
+ accumulators.
+
+Thu Feb 12 17:10:22 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * valops.c (value_at): For d10v, make read pointers with
+ read_target_unsigned_integer, keep addresses unsigned.
+ (value_fetch_lazy): Ditto.
+
+Thu Feb 12 12:14:02 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-d10v.c: New file. Layer the d10v GDB->remote memory map
+ on top of the remote serial memory transfer functions.
+
+ * config/d10v/d10v.mt (TDEPFILES): Add remote-d10v.o
+
+ * Makefile.in (remote-d10v.o): Add dependencies.
+
+ * remote.c (remote_open_1): Add arg extended_p, engage extended
+ protocol when extended_p.
+ (remote_open, extended_remote_open): Pass !extended_p /
+ extended_p to remote_open_1.
+
+ * remote.c (open_remote_target), target.h: New function.
+
+Wed Feb 11 08:41:15 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/i386/fbsd.mh (XDEPFILES): Add ser-tcp.o.
+
+Tue Feb 10 17:50:37 1998 Keith Seitz <keiths@onions.cygnus.com>
+
+ * tracepoint.c (tracepoint_operation): Call the modify_tracepoint_hook
+ if it exists.
+ Remove static declaration of free_actions.
+
+ * tracepoint.h: Add declaration of free_actions.
+
+Tue Feb 10 12:17:13 1998 Fred Fish <fnf@cygnus.com>
+
+ * symtab.c (decode_line_1): Revert change that mistakenly
+ removed assignment of sals[0].pc field.
+
+Mon Feb 10 12:37:47 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * m68k/tm-delta68.h (EXTRACT_RETURN_VALUE): Type argument for
+ `REGISTER_CONVERT_TO_VIRTUAL is `TYPE', not
+ `REGISTER_VIRTUAL_TYPE (FP0_REGNUM)';
+ (STORE_RETURN_VALUE): Ditto, and offset for `write_register_bytes'
+ is `REGISTER_BYTE (FP0_REGNUM)', not `FP0_REGNUM'.
+ (FRAME_NUM_ARGS): New macro.
+ * m68k/tm-news.h (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE): Ditto.
+ * delta68-nat.c (clear_insn_cache): New function, forgotten in previous
+ patch.
+
+Mon Feb 9 11:10:06 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c: Replace references to IMEM_ADDR and DMEM_ADDR with
+ D10V_MAKE_[DI]ADDR and D10V_CONVERT_[ID]ADDR_TO_RAW macros.
+
+ * config/d10v/tm-d10v.h (IMEM_START): Move to 0x01......
+ (DMEM_START): Move to 0x00......
+ (STACK_START): Move to 0x00..7ffe.
+ (D10V_MAKE_IADDR, D10V_MAKE_DADDR): Translate unconditionally.
+
+ * d10v-tdep.c (d10v_xlate_addr): Delete function.
+
+Mon Feb 9 15:10:21 1998 Fred Fish <fnf@cygnus.com>
+
+ * symtab.c (fixup_psymbol_section): Move forward declaration to
+ top of file with other such decls. Make it a static function.
+ * symtab.h: Minor formatting tweaks.
+
+Mon Feb 9 13:14:12 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/a29k-udi.mt, config/i960/vxworks960.mt (REMOTE_OBS):
+ Remove redefinition.
+ * config/i960/tm-i960.h (BREAKPOINT): Define.
+
+Mon Feb 9 15:35:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (init.c): Ignore errors when making init.c. Seems
+ necessary to work around bug in Solaris make.
+
+Sun Feb 6 02:44:28 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * m68k/tm-delta68.h (CPLUS_MARKER): Macro deleted.
+ (EXTRACT_STRUCT_VALUE_ADDRESS): Macro defined.
+ (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE): Macros modified
+ because floating-point values return via %fp0.
+ (CLEAR_INSN_CACHE): New macro.
+ * m68k/tm-m68k.h (REGISTER_CONVERT_TO_VIRTUAL): Macro fixed
+ to use DOUBLEST.
+ (REGISTER_CONVERT_TO_RAW): Ditto.
+ * infptrace.c (child_xfer_memory): If CLEAR_INSN_CACHE is defined,
+ call it after having written in child process's memory.
+ * inflow.c (PROCESS_GROUP_TYPE): Macro defined if HAVE_TERMIO.
+ (gdb_has_a_terminal, terminal_ours_1): Functions fixed for HAVE_TERMIO.
+
+Fri Feb 6 16:17:30 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/mips/tm-mips64.h (TARGET_LONG_BIT): Allow final target to
+ override.
+ (TARGET_LONG_LONG_BIT): Likewise.
+ (TARGET_PTR_BIT): Likewise.
+
+Fri Feb 6 17:42:22 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/d10v/tm-d10v.h (D10V_CONVERT_IADDR_TO_RAW,
+ D10V_CONVERT_DADDR_TO_RAW): Define.
+
+ * d10v-tdep.c (d10v_push_arguments): Re-write. Pass arguments in
+ registers, regardless of their size, when they fit.
+
+Thu Feb 5 13:16:36 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (d10v_extract_return_value): For function pointers
+ translate address to IMAP area.
+
+ * config/d10v/tm-d10v.h (EXTRA_FRAME_INFO): Delete dummy from
+ struct.
+ (POP_FRAME): Point at generic_pop_current_frame.
+
+ * d10v-tdep.c (d10v_pop_frame): Delete code handling dummy frames,
+ handled earlier.
+ (d10v_push_return_address): New function.
+ (d10v_pop_dummy_frame): Delete.
+ (d10v_fix_call_dummy): Delete.
+ (d10v_call_dummy_address): Delete.
+
+ * d10v-tdep.c (d10v_init_extra_frame_info): Clear dummy and
+ frameless.
+
+ * d10v-tdep.c (d10v_push_arguments): Keep stack word aligned.
+
+ * config/d10v/tm-d10v.h (EXTRACT_STRUCT_VALUE_ADDRESS): Extract
+ address of structure from first ARG1_REGNUM.
+
+ * d10v-tdep.c (d10v_push_arguments): Force 4 byte args into
+ even-odd register pair. Store 1 and 2 byte args in registers.
+
+ * valops.c (value_fetch_lazy): Ensure that a D10V function pointer
+ is fetched in the correct byte order.
+ (value_at): Ditto. Also ensure data pointers are mapped to data
+ segment.
+
+ * config/d10v/tm-d10v.h (D10V_DADDR_P, D10V_IADDR_P):
+
+ * d10v-tdep.c: Replace 2 with REGISTER_RAW_SIZE.
+ (d10v_pop_frame): Replace R13 with LR_REGNUM.
+ (d10v_push_arguments): Replace R2 with ARG1_REGNUM.
+ (d10v_push_arguments): Replace 6 with ARGN_REGNUM.
+ (d10v_extract_return_value): Access return value with RET1_REGNUM.
+
+ * config/d10v/tm-d10v.h (ARG1_REGNUM, ARGN_REGNUM, RET1_REGNUM):
+ Define.
+ (STORE_RETURN_VALUE): Specify return register using RET1_REGNUM.
+ (STORE_STRUCT_RETURN): Specify ARG1_REGNUM as the struct ptr
+ location.
+
+Thu Feb 5 13:16:36 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * blockframe.c (generic_pop_dummy_frame): Flush the frame, no
+ longer valid.
+
+ * blockframe.c (generic_pop_current_frame), frames.h: New
+ function.
+
+Thu Feb 5 17:18:16 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdbsim_create_inferior): clear_proceed_status
+ before /re/starting the simulator.
+
+Thu Feb 5 15:55:31 1998 C. M. Heard (heard@vvnet.com)
+
+ * top.c (do_nothing): Remove signal handler after signal is caught.
+
+Thu Feb 5 11:57:06 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c (tracepoint_operation): call free_actions instead
+ of free. (free_actions): eliminate some memory leaks for actions.
+ (validate_actionline): pass string arg by reference, so we can
+ change the pointer. Change all memrange collection arguments to
+ canonical form (literal address and size), to enforce early
+ evaluation. Accept UNOP_MEMVAL (assembly variables) for
+ trace collection. (parse_and_eval_memrange): accept expressions
+ for the address and size fields of a memrange (and evaluate
+ them immediately). (several places): use -1 instead of zero
+ to distinguish an absolute memrange from a register-relative one.
+ (encode_actions): add handling for UNOP_MEMVAL (assembly variable).
+
+Wed Feb 4 17:40:21 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Makefile.in (SFILES): add tracepoint.c.
+ (LINTFILES): add @CONFIG_SRCS@.
+ (SOURCES): Ditto.
+ * configure.in (CONFIG_SRCS): Mirror use of CONFIG_OBS.
+ * configure: Regenerated.
+
+Tue Feb 3 16:12:32 1998 Gordon W. Ross (gwr@mc.com)
+
+ * infptrace.c (child_resume): Don't try to step if
+ NO_SINGLE_STEP is defined.
+
+Mon Feb 2 19:06:13 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Makefile.in (VERSION): Bump to 4.16.2.
+
+Mon Feb 2 17:18:25 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha-nat.c (fetch_aout_core_registers): Rename from
+ fetch_core_registers.
+ (fetch_elf_core_registers): New function.
+ (supply_gregset): Use ALPHA_REGSET_BASE.
+ (supply_fpregset): Likewise.
+ (fill_fpregset): Likewise.
+ (alpha_aout_core_fns): Rename from alpha_core_fns.
+ (alpha_elf_core_fns): New.
+ * config/alpha/alpha-linux.mh (NATDEPFILES): solib.o not osfsolib.o.
+ Disable MMALLOC.
+ * config/alpha/nm-linux.h (SVR4_SHARED_LIBS): Define if ELF.
+ (TARGET_ELF64): Likewise.
+ (ALPHA_REGSET_BASE): New.
+ * config/alpha/nm-osf.h (ALPHA_REGSET_BASE): New.
+ * config/alpha/tm-alphalinux.h: Include tm-sysv4.h.
+
+ * solib.c (elf_locate_base): Add TARGET_ELF64 support.
+ (info_sharedlibary_command): Likewise.
+
+ * configure.host: Match alpha*.
+ * configure.tgt: Likewise.
+
+Fri Jan 30 15:11:38 1998 David Taylor <taylor@texas.cygnus.com>
+
+ Changes by <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
+ * infrun.c (IN_SOLIB_DYNSYM_RESOLVE_CODE): new macro for detecting
+ whether we are in the dynamic symbol resolution code
+ (wait_for_inferior): invoke it.
+ * solib.c (in_svr4_dynsym_resolve_code): new function
+ (enable_break): record start and end of the dynamic linker
+ text and plt sections for use in in_svr4_dynsym_resolve_code.
+ * solib.h (IN_SOLIB_DYNSYM_RESOLVE_CODE): add svr4 definition;
+ (in_svr4_dynsym_resolve_code): declare it.
+ * config/nm-gnu.h (solib.h): move inclusion to after definition
+ of SVR4_SHARED_LIBS.
+ * config/nm-sysv4.h (solib.h): ditto.
+ * config/i386/nm-i386sco5.h (solib.h): ditto.
+ * config/i386/nm-linux.h (solib.h): ditto.
+ * config/mips/nm-irix5.h (IN_SOLIB_DYNSYM_RESOLVE_CODE): undefine.
+
+Thu Jan 29 19:39:31 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * coffread.c (coff_symtab_read) [SEM]: Remove code, macro can
+ never be defined.
+ * dbxread.c (process_one_symbol) [BLOCK_ADDRESS_ABSOLUTE]:
+ Remove, no longer needed.
+ * hppa-tdep.c (N_SET_MAGIC): Remove, no longer used.
+ * config/pa/xm-hppab.h (SEEK_SET, SEEK_CUR, SEEK_END): Ditto.
+ * config/mips/tm-mipsm3.h (NUMERIC_REG_NAMES): Ditto.
+ * config/mips/mipsm3.mt (TDEPFILES): Remove mipsread.o.
+
+Wed Jan 28 14:46:52 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ Suggested by Chris Walter <walter@budoe.bu.edu>:
+ * dwarfread.c (set_cu_language): Recognize Fortran.
+ * dwarf2read.c (set_cu_language): Ditto.
+ (read_array_type): Fix language test.
+
+Wed Jan 28 12:51:08 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * blockframe.c (generic_frame_chain_valid): A frame pointer may
+ be valid if it is equal to the frame pointer of its caller (ie.
+ not necessarily strictly INNER_THAN). Allows frameless functions.
+
+Wed Jan 28 11:23:25 1998 Mark Alexander <marka@cygnus.com>
+
+ * monitor.c (monitor_vsprintf): New function to handle
+ printing of large addresses using %A format specifier.
+ (monitor_printf_noecho, monitor_printf): Use monitor_vsprintf
+ instead of vsprintf.
+ * dve3900-rom.c (_initialize_r3900_rom): Use %A instead of %Lx
+ to print addresses.
+
+Tue Jan 27 16:14:23 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * configure.in (CONFIG_LDFLAGS): Only add -export-dynamic
+ when using GNU ld.
+
+Mon Jan 26 19:07:46 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * config/alpha/tm-alphalinux.h (alpha_linux_sigtramp_offset):
+ Add closing parenthesis. From HJ Lu.
+
+Mon Jan 26 17:54:45 1998 Mark Alexander <marka@cygnus.com>
+
+ * dve3900-rom.c: Improve performance by using memory commands
+ that print less fluff. Minor cosmetic changes.
+ Eliminate compiler warnings.
+
+Sat Jan 24 23:44:43 1998 Martin M. Hunt <hunt@cygnus.com>
+
+ * breakpoint.c (enable_breakpoint): Preserve breakpoint
+ disposition when enabling a breakpoint.
+
+ * symtab.c (find_pc_sect_line): If no symbol information
+ is found, return correct pc anyway.
+
+Fri Jan 23 17:26:22 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.host (i[3456]86-*-osf1mk*, mips-*-mach3*,
+ ns32k-*-mach3*): Fix file names.
+ (i[3456]86-*-os9k, m88*-*-mach3*, w65-*-*): Remove config
+ recognition, no source files for these.
+ * configure.tgt (powerpc-*-aix4*): Remove config, now identical
+ to powerpc-*-aix*.
+ * config/powerpc/{aix4.mh,aix4.mt,tm-ppc-aix4.h}: Remove files,
+ no longer needed.
+
+Fri Jan 23 16:49:41 1998 Mark Alexander <marka@cygnus.com>
+
+ * monitor.c (monitor_write, monitor_readchar): New functions.
+ * monitor.h (monitor_write, monitor_readchar): Declare.
+ * dve3900-rom.c: Add support for fast loading on ethernet connections.
+
+Fri Jan 23 07:47:06 1998 Fred Fish <fnf@cygnus.com>
+
+ * config/d10v/tm-d10v.h (CALL_DUMMY): Define as "{ 0 }".
+ (TARGET_READ_FP): Define to d10v_read_fp rather than d10v_read_sp.
+ (TARGET_WRITE_FP): Define to d10v_write_fp rather than d10v_write_sp.
+ (d10v_write_fp, d10v_read_fp): Add prototypes.
+ * symtab.c (decode_line_1): Remove assignment of sals[0].pc field.
+ * symfile.c (simple_overlay_update, simple_overlay_update_1):
+ Ignore the size of overlay sections. This check is redundant anyway.
+ * printcmd.c (print_frame_args): Ditto.
+ * valops.c (value_fetch_lazy): Ditto.
+ * values.c (unpack_long): Ditto.
+ * d10v-tdep.c (d10v_frame_chain, d10v_frame_find_saved_regs,
+ d10v_init_extra_frame_info): Fix some minor bugs so the finish command
+ works properly.
+ (show_regs): Change num1 and num2 types from "long long" to "LONGEST".
+ (d10v_read_fp, d10v_write_fp): New functions.
+ (d10v_push_arguments): Remove unneeded assigns to "val" and "contents".
+ (d10v_push_arguments): Fix for pointers and structs.
+ (d10v_extract_return_value): Fix for pointers and chars.
+
+Tue Jan 20 18:53:18 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.tgt (i386-*-mach*, m88*-*-mach3*): Remove config
+ recognition, no source files for these (note that the i386 Mach
+ config is for pre-Mach 3).
+ (mips*-*-mach3*, ns32k-*-mach3*): Fix file names.
+ * config/mips/mipsel64.mt: Remove, never referenced.
+
+Mon Jan 19 14:01:28 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * top.c (print_gdb_version): Restore to original message.
+
+Mon Jan 19 13:34:40 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From cgf@bbc.com (Chris Faylor):
+ * win32-nat.c (child_mourn_inferior): Call ContinueDebugEvent to
+ let the child exit.
+ (child_kill_inferior): Respond to all debug events as the child is
+ terminating.
+
+ * Makefile.in (all): Change gdb dependency to gdb$(EXEEXT).
+ (uninstall): Add $(EXEEXT) to file name to remove.
+ (gdb$(EXEEXT)): Rename target from plain gdb.
+ (gdb1$(EXEEXT)): Rename target from plain gdb1.
+ (clean, mostlyclean): Add $(EXEEXT) to binary names to remove.
+
+1998-01-16 Felix Lee <flee@cygnus.com>
+
+ * top.c (print_gdb_version): delete stutter.
+
+Thu Jan 15 12:29:13 1998 Nick Clifton <nickc@cygnus.com>
+
+ * remote-rdi.c (arm_rdi_open): Patch from Tony.Thompson@arm.com
+ to prevent spurous error messages on non-ICE targets.
+
+Wed Jan 14 19:27:02 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/mips/{r3900.mt,r3900l.mt,tm-r3900.h,tm-r3900l.h}:
+ Remove, no longer used.
+
+Wed Jan 14 18:11:26 1998 Michael Meissner <meissner@cygnus.com>
+
+ Patch from Jim Wilson.
+ * d30v-tdep.c (d30v_frame_find_saved_regs_offsets): Properly
+ declare void function before use.
+
+ * config/d30v/tm-d30v.h (CALL_DUMMY): Initialize as { 0 }, not {}.
+
+Tue Jan 13 16:38:48 1998 Fred Fish <fnf@cygnus.com>
+
+ * configure.in (--with-mmalloc): Add new configure arg to use the
+ mmalloc package. Default is to not use it.
+ (START_INFERIOR_TRAPS_EXPECTED): Define to the integer 2, not
+ the string "2".
+ * acconfig.h (USE_MMALLOC, FORCE_MMCHECK): Add #undef.
+ * configure: Regenerated.
+ * config.in: Regenerated.
+ * Makefile.in (MMALLOC_DIR, MMALLOC_SRC): Remove.
+ (MMALLOC): Set using configure.
+ (MMALLOC_CFLAGS): Set using configure.
+
+ * config/i386/tm-linux.h (sys_quotactl): Define to 1 rather
+ than just defining it.
+ * mpw-make.sed: Undefine USE_MMALLOC rather than defining NO_MMALLOC.
+ * utils.c (NO_MMALLOC): Use USE_MMALLOC instead.
+ * objfiles.c: ditto.
+ * defs.h: ditto.
+
+ * config/sparc/sun4os4.mh (MMALLOC_CFLAGS): Remove.
+ * config/m68k/sun3os4.mh (MMALLOC_CFLAGS): Remove.
+ * config/i386/cygwin32.mh (MMALLOC_CFLAGS): Remove.
+ * config/alpha/alpha-osf3.mh (MMALLOC_CFLAGS): Remove.
+ * config/alpha/alpha-osf2.mh (MMALLOC_CFLAGS): Remove.
+ * gdbserver/Makefile.in (MMALLOC_*): Remove.
+ * config/rs6000/rs6000.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/rs6000/aix4.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/powerpc/aix4.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/powerpc/aix.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/ns32k/ns32km3.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/mips/mipsm3.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/mips/decstation.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/m88k/cxux.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/i386/xm-windows.h (NO_MMALLOC, NO_MMCHECK): Remove.
+ * config/i386/i386mk.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/i386/i386m3.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/i386/i386gnu.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/alpha/alpha-osf1.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+ * config/alpha/alpha-linux.mh (MMALLOC, MMALLOC_CFLAGS): Remove.
+
+Mon Jan 12 11:46:51 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * config/m68k/tm-m68k.h (REGISTER_VIRTUAL_TYPE): make A0 thru A7
+ default to void pointer type (so that their default radix is hex).
+
+ * symtab.c: move rbreak_command from no_class to class_breakpoint
+ so it will be listed under "help breakpoints".
+
+Sat Jan 10 14:58:04 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * rdi-share/hostchan.c: Remove gettimeofday declaration.
+
+Thu Jan 8 11:03:59 1998 Nick Clifton <nickc@cygnus.com>
+
+ * remote-rdp.c: Applied patches submitted by Tony.Thompson@arm.com
+ to implement the Angel remote debugging interface.
+
+ * Makefile.in: Add build rules for remote-rdi.c and
+ rdi-share/libangsd.a.
+
+ * configure.tgt: Updated from source on branch.
+ * config/arm/tm-arm.h: Updated from source on branch.
+ * arm-tdep.c: Updated from source on branch.
+
+ * rdi-share: New directory, RDI library contributed by ARM.
+
+Mon Jan 5 20:21:59 1998 Mark Alexander <marka@cygnus.com>
+
+ * monitor.h (MO_PRINT_PROGRAM_OUTPUT): Define.
+ * monitor.c (monitor_wait): Echo program output.
+ * dve3900-rom.c (_initialize_r3900_rom): Remove MO_HANDLE_NL flag,
+ add MO_PRINT_PROGRAM_OUTPUT flag.
+
+Mon Jan 5 18:21:11 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * top.h (HAVE_SIGSETJMP): define SIGJMP_BUF, SIGSETJMP, and
+ SIGLONGJMP appropriately based on whether HAVE_SIGSETJMP is
+ defined.
+ * top.c (return_to_top_level, catch_errors): use the new macros
+ * main.c (SET_TOP_LEVEL): ditto.
+ * config/xm-sysv4.h (HAVE_SIGSETJMP): Define.
+
+Fri Jan 2 18:48:58 1998 Mark Alexander <marka@cygnus.com>
+
+ * configure.in: Double up brackets in shell case pattern.
+
+Fri Jan 2 17:06:05 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
+
+ * tracepoint.c (finish_tfind_command): improved algorithm for
+ deciding when we've "stepped" into a new stack frame.
+ (map_args_over_tracepoints): loop over tracepoint list "safely",
+ since list elements may be deleted during loop.
+ (read_actions): add actions to history list.
+
+For older changes see ChangeLog-1997
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/ChangeLog-1999 b/gdb/ChangeLog-1999
new file mode 100644
index 00000000000..8ed06120d2e
--- /dev/null
+++ b/gdb/ChangeLog-1999
@@ -0,0 +1,9296 @@
+Sun Dec 19 18:56:38 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * breakpoint.c (mention): Delete ui-out breakpoint code. Mention
+ calls breakpoint_create_event and that, eventually, calls
+ gdb_breakpoint_query which displays the breakpoint details.
+ (hbreak_command_wrapper, thbreak_command_wrapper): Delete.
+
+Wed Dec 29 17:41:11 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * breakpoint.c (create_breakpoints, parse_breapoint_sals,
+ breakpoint_sals_to_pc): New functions.
+ (break_command_1): Rewrite. Use create_breakpoints,
+ parse_breapoint_sals, breakpoint_sals_to_pcto create the list of
+ breakpoints specified in ``sals''. Delete unused variables.
+ Pre-allocate addr_strings for all breakpoints. Allocate a
+ separate cond and cond_string for each breakpoint.
+ (gdb_breakpoint, do_captured_breakpoint, struct
+ captured_breakpoint_args): Provide a library interface into
+ create_breakpoints.
+
+ * defs.h (gdb_breakpoint): Add declaration.
+
+1999-12-22 Michael Chastain <chastain@cygnus.com>
+
+ * dbxread.c (process_one_symbol): check for nested LBRAC
+ symbols before calling finish_block rather than after. Do not
+ call define_symbol for these symbols.
+
+1999-12-21 Stan Shebs <shebs@andros.cygnus.com>
+
+ * blockframe.c (generic_pop_current_frame): Cosmetic changes to
+ clarify.
+
+1999-12-20 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * procfs.c: Completely rewritten. All functions replaced, to make
+ maintainence easier in the presence of two very different versions
+ of /proc (ioctl vs. read/write).
+ * proc_api.c: New file, pretty-print /proc diagnostic trace info.
+ * proc_events.c: New file, pretty-print /proc signals, exceptions.
+ * proc_flags.c: New file, pretty-print /proc flags.
+ * proc_why.c: New file, pretty-print /proc reasons for stopping.
+ * Makefile.in: Add rules for above new files.
+ * config/i386/i386sol2.mh: Add above new files to NATDEPFILES.
+ * config/sparc/sun4sol2.mh: ditto.
+ * config/i386/i386dgux.mh: ditto.
+ * config/i386/i386v4.mh: ditto.
+ * config/i386/i386v42mp.mh: ditto.
+ * config/i386/ncr3000.mh: ditto.
+ * config/m68k/m68kv4.mh: ditto.
+ * config/m88k/delta88v4.mh: ditto.
+ * config/mips/irix4.mh: ditto.
+ * config/mips/irix5.mh: ditto.
+ * config/mips/mipsv4.mh: ditto.
+ * config/powerpc/solaris.mh: ditto.
+ * config/alpha/alpha-osf2.mh: ditto.
+ * config/alpha/alpha-osf3.mh: ditto.
+ * testsuite/gdb.base/callfuncs.exp: make "next" test match the
+ next source line, in case the "next" runs away.
+ * acconfig.h: remove obsolete def HAVE_MULTIPLE_PROC_FDS,
+ add new def NEW_PROC_API
+ * config.in; ditto.
+ * configure.in: Detect sparc solaris 7 and all versions of
+ UnixWare, and define NEW_PROC_API.
+ * configure: auto-generate.
+ * infrun.c (MAY_SWITCH_FROM_INFERIOR_PID): remove define, make it
+ the default behavior. (switched_from_inferior_pid): rename to
+ previous_inferior_pid. (handle_inferior_event): remove the
+ [Switching to thread...] message. (normal_stop): move the
+ [Switching to thread...] message to here.
+ * sol-thread.c (sol_find_new_threads): add a call to
+ procfs_find_new_threads, so that new LWPs are found too.
+ * config/mips/nm-irix5.h (TARGET_CAN_USE_HARDWARE_WATCHPOINT):
+ define to always use. (target_insert_watchpoint) define to use
+ new procfs call (one additional parameter).
+ (target_remove_watchpoint): ditto.
+ (TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT) define always true.
+ * config/mips/nm-irix4.h: ditto.
+
+1999-12-21 Jim Blandy <jimb@cygnus.com>
+
+ * Makefile.in (elf_bfd_h): Look for elf-bfd.h in BFD_SRC, not
+ BFD_DIR. Unlike bfd.h, it is not a generated file.
+
+Fri Dec 17 18:24:58 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * language.c (_initialize_language): move settings of language,
+ range, and type and corresponding function calls
+ set_language_command, set_type_command, and set_range_command
+ closer together to match the model of having the user set the
+ variable via the 'set {language | range | type}' commands.
+ This eliminates startup noise introduced by Jimmy Guo's change
+ of Dec 13th.
+
+1999-12-17 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * configure.in: test for <stdint.h>, which is not available
+ on earlier versions of Linux.
+ * config.in: define HAVE_STDINT_H if it's present.
+ * configure: autoconfiscate.
+ * lin-thread.c: if not HAVE_STDINT_H, stub out the entire module.
+
+Fri Dec 17 20:45:21 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * target.c (find_target_beneath): Change ``='' in if to ``==''.
+
+1999-12-16 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * defs.h (TIDGET): add default definition.
+ * lin-thread.c (check_for_thread_event): for now, just provide
+ an empty definition (to be filled in later).
+
+1999-12-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (varobj_list): Improve the test and the text of the
+ assertion that guards against wrong tally of root varobjs.
+ (uninstall_variable): Fix for a bug in which the number of root
+ varobjs was not decremented if the first one in the list was deleted.
+
+1999-12-16 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * linux-thread.c: Remove printf-debugging code.
+ * lin-thread.c: ditto.
+ * config/alpha/nm-linux.h: protect with NM_LINUX_H.
+ * testsuite/gdb.threads/linux-dp.exp: Make test for "New Thread"
+ message more forgiving. Ditto test for "info threads".
+
+1999-12-16 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * lin-thread.c: new file. Implements multi-thread debugging on
+ Linux using the thread_db API first implemented on Solaris. This
+ frees GDB from any dependency on the internal implementation of
+ the thread library. Future versions of the thread library will
+ implement a libthread_db API for debuggers, which GDB will use.
+ * config/i386/linux.mh: add lin-thread.o to the link, and add
+ -ldl and -rdynamic since libthread_db is a dynamic library.
+ * config/alpha/alpha-linux.mh: ditto.
+ * configure.in: test for thread_db.h, proc_service.h
+ * configure: autoconf.
+ * config.in: conditionally define HAVE_THREAD_DB_H
+ and HAVE_PROC_SERVICE_H
+ * gdb_thread_db.h: new file, used when the system doesn't have it.
+ * gdb_proc_service.h: ditto.
+
+1999-12-16 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * linux-thread.c: changes to accomodate the new lin-thread.c
+ module based on the thread_db API. These changes make parts of
+ linux-thread.c shareable with lin-thread.c.
+ (linuxthreads_wait_mask): replace with linuxthreads_block_mask.
+ (using_thread_db): new variable. Allows linux-thread module to
+ detect when lin-thread (thread_db API) module is in use.
+ (save_inferior_pid, restore_inferior_pid): make 32/64 bit safe.
+ (check_all_signal_numbers) make extern, shared with lin-thead.c.
+ (linuxthreads_new_objfile): use target_new_objfile_chain to share
+ this hook with the lin-thread module. Call the other module FIRST.
+ If using_thread_db is turned on by the other thread module, do not
+ set linuxthreads_debug and do not call update_stop_threads. Do call
+ check_all_signal_numbers, to be sure it gets set before target_wait.
+ (linux_child_wait): new function. Abstracts out the "child_wait"
+ functionality, so that it can be shared with the lin-thread module.
+ (linuxthreads_wait): call linux_child_wait, instead of doing the
+ waiting inline. If using_thread_db, do not call update_stop_threads
+ and do not turn on linuxthreads_debug.
+ (linuxthreads_mourn_inferior): abstract out the clearing of global
+ state, so that it can be shared with the lin-thread.c module.
+ (_initialize_linuxthreads): use linuxthreads_wait_mask to block
+ SIGCHLD exactly ONCE, and leave it blocked! Then linux_child_wait
+ will call sigsuspend when it wants to wait for this signal.
+ (thread_attach): abstract out ptrace attach to share with lin-thread.c
+
+1999-12-16 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ Make target_pid_to_str a target_ops vector.
+ * target.h (target_pid_to_str): redefine to use a target_ops vector.
+ (target_tid_to_str): default to using target_pid_to_str.
+ (target_pid_or_tid_to_str): ditto.
+ * target.c (update_current_target): inherit to_pid_to_str method.
+ (find_target_beneath): new function. Find target stratum below
+ the given one.
+ * config/nm-gnu.h: don't define target_pid_to_str.
+ * config/i386/tm-i386sol2.h: ditto.
+ * config/sparc/tm-sun4sol2.h: ditto.
+ * gnu-nat.c (init_gnu_ops): initialize to_pid_to_str vector.
+ * linux-thread.c (init_linuxthreads_ops): ditto.
+ * sol-thread.c (init_sol_thread_ops: ditto.
+ * procfs.c (init_procfs_ops): ditto.
+ * win32-nat.c (init_child_ops): ditto.
+ * config/i386/tm-cygwin.h: don't define target_pid_to_str.
+ * inftarg.c (child_pid_to_str): new function, used to initialize
+ to_pid_to_str vector. May be suppressed by defining CHILD_PID_TO_STR.
+ (init_child_ops): initialize to_pid_to_str using child_pid_to_str.
+ Derivative modules may substitute their own child_pid_to_str func
+ by defining CHILD_PID_TO_STR.
+ * lynx-nat.c (lynx_pid_to_str): rename to child_pid_to_str.
+ * config/nm-lynx.h: define CHILD_PID_TO_STR.
+ Don't define target_pid_to_str.
+ * hppah-nat.c (hppa_pid_to_str): rename to child_pid_to_str.
+ * infttrace.c (hppa_pid_or_tid_to_str): call child_pid_to str
+ instead of hppa_pid_to_str.
+ * config/pa/nm-hppah.h: define CHILD_PID_TO_STR.
+ Don't define target_pid_to_str.
+
+1999-12-16 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * i386-linux-nat.c: introduce PIDGET/TIDGET macros as on Solaris,
+ preparatory to using the thread_db debugging API for Linux.
+ (fill_gregset): guard against invalid input.
+ (fetch_regs): add a pid/thread_id argument, so we can fetch regs
+ from multiple processes/clones/threads. (store_regs): ditto.
+ (fetch_fpregs): ditto. (store_fpregs): ditto.
+ (fetch_xfpregs): ditto. (store_xfpregs): ditto.
+ (fetch_inferior_registers): use TIDGET to extract an appropriate
+ thread/clone/process id from inferior_pid, if there's one there,
+ and pass it to fetch_regs etc. (store_inferior_registers): ditto.
+
+ * infptrace.c: include every available version of wait.h.
+ introduce PIDGET/TIDGET macros for use with thread_db API on Linux.
+ (call_ptrace): rearrange lines that were split by an ifdef.
+ (fetch_register): use TIDGET to extract an appropriate process ID
+ from inferior_pid, in case we are debugging more than one process.
+ (store_register): ditto. This is for Linux.
+ (child_xfer_memory): use PIDGET to extract the main process id from
+ inferior_pid, in case we are debugging multiple processes that share
+ the same address space (as on Linux).
+
+1999-12-16 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c: Add a missing register to mappings array.
+ (child_fetch_inferior_registers): Use precalculated index into mappings
+ array as supply_registers argument.
+ (handle_output_debug_string): Avoid considering every debug string as a
+ cygwin signal.
+ (handle_exception): Trap first chance exceptions.
+ (child_create_inferior): Initialize Microsoft thread walking API.
+ (sgmb): New function. Used by Microsoft API for stack walking.
+ (child_frame_chain): New function. Uses Microsoft API for stack
+ walking.
+ (child_frame_chain_saved_pc): Ditto.
+ * config/i386/tm-cygwin.h: Define frame handling stuff.
+
+1999-12-15 Stan Shebs <shebs@andros.cygnus.com>
+
+ ARM GNU/Linux support and general ARM target fixes/cleanup from
+ Scott Bambrough <scottb@netwinder.org>, plus obsoletion of the old
+ RISCix support.
+ * NEWS: Mention addition and obsoletion.
+ * configure.host: Recognize arm* instead of just arm.
+ (arm*-*-linux*): Recognize.
+ * configure.tgt: Ditto, plus assume arm*-*-* is embedded.
+ * config/arm/arm.mh, config/arm/arm.mt, config/arm/nm-arm.h,
+ config/arm/xm-arm.h: Mark as OBSOLETE.
+ * config/arm/embed.mt, config/arm/tm-embed.h: New files.
+ * config/arm/linux.mh, config/arm/linux.mt, config/arm/nm-linux.h,
+ config/arm/tm-linux.h, config/arm/xm-linux.h: Ditto.
+ * config/arm/tm-arm.h: Add more comments, eliminate PARAMS.
+ (STACK_END_ADDR): Remove.
+ (ARM_LE_BREAKPOINT, ARM_BE_BREAKPOINT, THUMB_LE_BREAKPOINT,
+ THUMB_BE_BREAKPOINT): Move to here from arm-tdep.c.
+ (NUM_REGS): Define as sum.
+ (NUM_FREGS, NUM_SREGS, NUM_GREGS): New definitions.
+ (FP_REGISTER_RAW_SIZE, FP_REGISTER_VIRTUAL_SIZE,
+ STATUS_REGISTER_SIZE): Define.
+ (REGISTER_BYTES, REGISTER_BYTE, REGISTER_RAW_SIZE,
+ REGISTER_VIRTUAL_SIZE): Rewrite to use symbolic values.
+ (REGISTER_CONVERTIBLE, REGISTER_CONVERT_TO_VIRTUAL,
+ REGISTER_CONVERT_TO_RAW, USE_STRUCT_CONVENTION,
+ EXTRACT_RETURN_VALUE): Rewrite to use new functions.
+ (IN_SIGTRAMP): Remove definition.
+ * arm-convert.s: Mark as OBSOLETE.
+ * arm-linux-nat.c: New file.
+ * Makefile.in: Add build rule for it.
+ * arm-tdep.c (struct frame_extra_info): New struct.
+ (arm_use_struct_convention): Rewrite.
+ (arm_push_arguments): Rewrite to handle more cases.
+ (arm_register_convertible, arm_register_convert_to_virtual,
+ arm_register_convert_to_raw, arm_extract_return_value): New
+ functions.
+ (LITTLE_BREAKPOINT, BIG_BREAKPOINT): Remove.
+ * arm-xdep.c: Mark as OBSOLETE.
+
+1999-12-15 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * infcmd.c (run_stack_dummy): Temporarily lie about the target
+ ability to support asynchronous execution.
+
+ * remote.c (remote_can_async_p, remote_is_async_p): Return true
+ iff to_async_mask_value is true too.
+ (remote_async): Error out if called when to_async_mask_value is 0.
+ (init_remote_async_ops): Initialize to_async_mask_value to 1.
+ (remote_async_detach, remote_async_resume, remote_async_wait,
+ remote_async_kill): Change SERIAL_IS_ASYNC_P call to
+ target_is_async_p call.
+ (remote_async_resume): Change SERIAL_CAN_ASYNC_P call to
+ target_can_async_p call.
+
+ * target.c (update_current_target): Inherit to_async_mask_value.
+ (target_async_mask): New function. To temporarily turn the target
+ into a synchronous one for inferior function calls, and back to
+ asynchronous.
+
+ * target.h (to_async_mask_value): New entry in the target
+ vector.
+ (target_async_mask): Export.
+ (target_async_mask_value): Define.
+
+Wed Dec 15 11:24:32 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hp-psymtab-read.c (trans_lang): Use HP_LANGUAGE_FORTRAN instead
+ of HP_LANGUAGE_F77.
+
+Wed Dec 15 13:37:55 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb-events.h, gdb-events.c (set_gdb_event_hooks): Return the old
+ event hooks vector.
+
+1999-08-13 Jim Kingdon <http://developer.redhat.com/>
+
+ * breakpoint.c (bpstat_stop_status): Revert 1998-09-08 change
+ to ->frame matching. The change did not match the ChangeLog
+ entry, looked fishy, and caused infinite stepping when running
+ "next" from main on sparc w/ RH Linux. Thanks to Jakub for the
+ report.
+
+1999-12-14 Stan Shebs <shebs@andros.cygnus.com>
+
+ * arm-tdep.c (arm_get_next_pc): Add argument to shifted_reg_val
+ call.
+
+1999-12-14 Mark Salter <msalter@cygnus.com>
+
+ * mips-tdep.c (mips_print_register): Fix printing of individual
+ registers when REGISTER_VIRTUAL_SIZE != REGISTER_RAW_SIZE.
+
+Tue Dec 14 23:29:19 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (mcalloc): Delcare.
+ * utils.c (xcalloc, mcalloc): New functions.
+
+1999-12-13 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/arm/tm-arm.h: Reformat comments, in preparation for
+ real changes.
+ * arm-tdep.c: Similarly, plus change function definitions to
+ modern form.
+
+1999-12-13 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * breakpoint.h (enum bptype): add new BP type bp_thread_event.
+ This will be used when a target needs to set an invisible
+ breakpoint to detect events such as thread creation.
+ * breakpoint.c (interlan_breakpoint_number): remove ifdefs.
+ (create_thread_event_breakpoint): new function.
+ (remove_thread_event_breakpoints): new function.
+ (bpstat_what): don't stop at invisible thread_event breakpoints.
+ (update_breakpoints_after_exec): if bp_thread_event breakpoins
+ still exist after an exec, delete them. They'll need to be
+ found and installed anew anyway.
+ (print_it_typical): don't announce bp_thread_event breakpoints.
+ (print_one_breakpoint): account for new breakpoint type.
+ (mention): don't mention invisible bp_thread_event breakpoints.
+ (delete_command): don't delete invisible bp_thread_event bp's.
+ (breakpoint_re_set_one): don't touch bp_thread_event bp's.
+
+Mon Dec 13 11:10:59 1999 Jimmy Guo <guo@cup.hp.com>
+
+ * language.h (longest_raw_hex_string, longest_local_hex_string,
+ longest_local_hex_string_custom): Declare.
+ * language.c: New functions, and misc. fixes.
+ (longest_raw_hex_string, longest_local_hex_string,
+ longest_local_hex_string_custom): New functions.
+
+ * c-typeprint.c
+ (c_type_print_varspec_prefix,c_type_print_varpsec_suffix): Add
+ TYPE_CODE_TEMPLATE case and default case.
+ (c_type_print_base): Revise how demangled_no_class is found;
+ print '}' before printing local file:line info.
+ * c-valprint.c (c_value_print): print reference type to class.
+
+ * valarith.c (value_binop): Add support for exponentiation,
+ equal, not equal.
+ (value_strcmp): New function.
+ (value_equal,value_less): Add string equality comparison support.
+
+ * m2-exp.y (lex): add default case statement to capture
+ unhandled token and call error().
+
+1999-12-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * main.c (main): Remove unused variable.
+
+ From Hubert VERSTRAETE (hubertV@bigfoot.com):
+ * main.c (captured_main): Disambiguate command line option '-d' by
+ preferring --directory over --dbx.
+
+ * top.c (return_to_top_level): Do not do exec cleanups if the
+ target is executing. Those cleanups are supposed to be done when
+ the target has stopped.
+
+Mon Dec 13 20:52:37 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * breakpoint.c (do_captured_breakpoint_query,
+ gdb_breakpoint_query): New functions. Implement a breakpoint
+ query.
+
+ * defs.h (enum gdb_rc): Declare.
+ (gdb_breakpoint_query): Declare.
+
+Mon Dec 13 14:18:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb-events.h: Fix typo in description of breakpoint events.
+ * gdb-events.sh: Update.
+
+Mon Dec 13 13:57:26 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * breakpoint.c (ep_type_description_t): Delete.
+ (print_one_breakpoint): Add local declaration of struct
+ ep_type_description.
+
+Mon Dec 13 12:38:31 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.h: Delete #include <setjmp.h>. Moved to top.c.
+ (SIGJMP_BUF, SIGSETJMP, SIGLONGJMP, SIGJMP_BUF, SIGSETJMP,
+ SIGLONGJMP): Delete. Moved to top.c
+ (error_return, quit_return): Delete extern declarations.
+
+ * top.c: #include <setjmp.h>.
+ (error_return, quit_return): Make static.
+ (SIGJMP_BUF, SIGSETJMP, SIGLONGJMP, SIGJMP_BUF, SIGSETJMP,
+ SIGLONGJMP): Define.
+
+Mon Dec 13 11:54:12 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * tracepoint.c (trace_start_command, tracepoints_info): Print
+ step_count using %ld.
+ * Makefile.in (tracepoint.o): Compile tracepoint.o with -Werror.
+
+1999-12-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * target.h (enum target_waitkind): Add new enumeration value
+ TARGET_WAITKIND_IGNORE. For inferior events that we should do
+ nothing about.
+
+ * remote.c (remote_async_wait): After each character of console
+ output from the inferior, return to the event loop with an event
+ kind of TARGET_WAITKIND_IGNORE instead of looping here.
+
+ * infrun.c (handle_inferior_event): In case of
+ TARGET_WAITKIND_IGNORE, return immediately, and set things up so
+ that we are still waiting for the inferior.
+
+1999-12-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-loop.c (handle_timer_event): When calling the timer
+ procedure, use the saved_timer data, not the timer_ptr data,
+ because the latter has been already freed.
+
+Fri Dec 10 12:01:43 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * eval.c (evaluate_subexp): Only inline when GNUC and not STDC.
+
+Sat Dec 11 17:52:03 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * breakpoint.c (print_one_breakpoint): New function. Move
+ breakpoint print code to here.
+ (breakpoint_1): From here.
+ (print_one_breakpoint): Merge in ui-out code.
+ (print_one_breakpoint): Add local variabls ``stb'' and
+ ``old_chain''.
+ (breakpoint_1): Use print_one_breakpoint when UI.
+ (print_one_breakpoint): Print breakpoint type when UI.
+ (breakpoint_1): Merge UI out code into non UI function.
+
+ * ui-out.c (make_cleanup_ui_out_stream_delete): New function. Wrap
+ make_cleanup.
+ (do_stream_delete): New function. Wrap ui_out_stream_delete.
+ * ui-out.h (make_cleanup_ui_out_stream_delete): Declare.
+
+Sat Dec 11 00:12:41 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * breakpoint.c (breakpoint_1): Clone breakpoint_1 creating UI
+ and non-UI versions.
+
+Mon Dec 6 20:31:28 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh: Replace field init_p with invalid_p.
+ (TARGET_BFD_VMA_BIT): New architecture vector method. Defaults to
+ architecture bits_per_address.
+ * gdbarch.h, gdbarch.c: Update.
+ * defs.h (TARGET_BFD_VMA_BIT): Provide default of TARGET_PTR_BIT
+ for non- multi-arch case.
+
+ * gdbtypes.h (builtin_type_bfd_vma, builtin_type_ptr,
+ builtin_type_CORE_ADDR): New GDB specific address types.
+ * gdbtypes.c (_initialize_gdbtypes, build_gdbtypes): Initialize
+ new builtin types.
+
+Wed Dec 8 17:48:56 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/sparc/nm-nbsd.h (FETCH_INFERIOR_REGISTERS): Delete
+ definition. Already defined in config/nm-nbsd.h. Include the
+ more explicit config/nm-nbsd.h.
+
+ * config/sparc/nbsd.mt (TDEPFILES): Move solib.o from here.
+ * config/sparc/nbsd.mh (NATDEPFILES): To here.
+ * config/xm-nbsd.h: #include <sys/param.h> to get definition of
+ NGROUPS needed by <limits.h> and missing on some systems.
+ * config/nm-nbsd.h: Only macro's that match NetBSD definitions
+ with what is expected by solib.c when not SVR4_SHARED_LIBS.
+
+ * configure.host: Add patterns for sparc-*-netbsdaout* and
+ sparc-*-netbsdelf*.
+ * config/sparc/nm-nbsdelf.h: New file.
+ * config/sparc/nbsdelf.mh: New file.
+
+Wed Dec 8 19:56:48 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * frame.h, blockframe.c: Rename default_frame_chain_valid to
+ file_frame_chain_valid. Rename alternate_frame_chain_valid to
+ func_frame_chain_valid.
+
+ * config/sparc/tm-sparclite.h, config/mips/tm-mipsv4.h,
+ config/m88k/tm-delta88v4.h, config/m68k/tm-m68kv4.h,
+ config/m68k/tm-monitor.h, config/i386/tm-i386nw.h,
+ config/i386/tm-i386v4.h, config/h8300/tm-h8300.h: Update.
+ * mips-tdep.c (mips_gdbarch_init): Update.
+
+Wed Dec 8 19:12:17 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * blockframe.c (generic_file_frame_chain_valid): Rename
+ generic_file_frame_chain_valid.
+ * frame.h: Update.
+ * config/fr30/tm-fr30.h, config/m32r/tm-m32r.h,
+ config/mn10200/tm-mn10200.h, config/mn10300/tm-mn10300.h,
+ config/sh/tm-sh.h, config/v850/tm-v850.h, config/mcore/tm-mcore.h:
+ Update.
+
+ * blockframe.c (generic_func_frame_chain_valid): New function.
+ Implement dummy-frame equivalent of function based frame chain
+ valid.
+ * frame.h (generic_func_frame_chain_valid): Declare.
+
+Wed Dec 8 16:26:27 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * blockframe.c (alternate_frame_chain_valid,
+ default_frame_chain_valid): Swap implementations. The change Mon
+ Nov 30 11:18:48 1998 Andrew Cagney <cagney@chook> which converted
+ several macros to functions was backwards.
+
+ * mips-tdep.c (mips_gdbarch_init): Update. Call
+ alternate_frame_chain_valid and not default_frame_chain_valid.
+
+Wed Dec 8 15:29:48 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * infptrace.c: Simplify handling of <sys/wait.h>. Always include
+ "wait.h" from the ../include/wait.h directory. #include
+ <sys/wait.h> was added as part of Mon Nov 29 12:14:10 1999 Andrew
+ Cagney <cagney@b1.cygnus.com> but the ChangeLog was omitted.
+
+1999-12-07 Jim Blandy <jimb@cygnus.com>
+
+ Add support for SSE registers in core files.
+ * corelow.c (get_core_register_section): New function.
+ (get_core_registers): Fetch the new ".reg-xfp" sections,
+ in addition to the traditional ".reg" and ".reg2" sections.
+ Check for per-thread variants of all three. Use
+ get_core_register_section, instead of writing it out over and over
+ again.
+ * i386-linux-nat.c (i386_linux_fetch_core_registers): New function.
+ (i386_linux_nat_core_fns): New core_fns structure. We do our own
+ core handling now, instead of using the generic code in core-regset.c.
+ (_initialize_i386_linux_nat): New function, needed to register
+ i386_linux_nat_core_fns.
+ * config/i386/linux.mh (NATDEPFILES): Remove core-regset.o;
+ i386-linux-nat.c has its own sniffer now.
+ * gdbcore.h: (struct core_fns): Doc fix.
+
+ * i386v-nat.c (i386_float_info): Definition is #if 0'd; delete it
+ altogether. This should use the function i387-tdep.c.
+
+ Patch from Mark Kettenis <kettenis@gnu.org>:
+
+ * config/i386/tm-i386.h (FLOAT_INFO): New define.
+ * i387-tdep.c (print_i387_value, print_i387_ext,
+ print_i387_status_word, print_i387_control_word, i387_float_info):
+ New functions, used to implement generic `info float' command.
+
+1999-12-06 Christopher Faylor <cgf@cygnus.com>
+
+ * dcache.c (set_dcache_state): New function.
+ * dcache.h: Declare set_dcache_state().
+
+Sat Dec 4 15:17:44 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (build_remote_packet_sizes): Reduce the default packet
+ size of 400 bytes by one to 399. Stops GDB trashing stubs that
+ append a trailing NUL to an already full buffer.
+
+Sat Dec 4 01:16:47 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * tracepoint.c (remote_get_noisy_reply): Add parameter sizeof_buf.
+ (finish_tfind_command): Add parameter sizeof_msg.
+
+ * remote.c (remote_threads_info): Move assignment operator to
+ outside of function call.
+ (remote_send): Add parameter sizeof_buf.
+ (getpkt): Add parameter sizeof_buf. Call read_frame passing in
+ sizeof_buf.
+
+ * remote.h (getpkt): Update.
+
+ * tracepoint.c (remote_set_transparent_ranges,
+ remote_get_noisy_reply, trace_start_command, trace_stop_command,
+ trace_status_command, finish_tfind_command, trace_find_pc_command,
+ trace_find_tracepoint_command, trace_find_line_command,
+ trace_find_range_command, trace_find_outside_command): Update.
+
+ * remote.c (set_thread, remote_thread_alive,
+ remote_get_threadinfo, remote_get_threadlist,
+ remote_current_thread, remote_threads_info,
+ extended_remote_restart, get_offsets, remote_open_1,
+ remote_async_open_1, remote_wait, remote_async_wait,
+ remote_fetch_registers, check_binary_download, remote_write_bytes,
+ remote_read_bytes, remote_send, remote_detach,
+ remote_async_detach, remote_fetch_registers,
+ store_register_using_P, store_register_using_P,
+ remote_fetch_registers, remote_store_registers, putpkt_binary,
+ remote_insert_breakpoint, remote_remove_breakpoint,
+ compare_sections_command, remote_rcmd, packet_command,
+ remote_info_process, remote_query, remote_insert_watchpoint,
+ remote_search, remote_remove_watchpoint,
+ remote_insert_hw_breakpoint, remote_remove_hw_breakpoint): Update.
+
+Fri Dec 3 17:38:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * (read_frame): Add sizeof_buf parameter. Don't allow repeat when
+ first character. Always leave space at the end of the buffer.
+ Return size of packet or -1.
+ (getpkt): Update. Pass in PBUFSIZ.
+
+1999-12-02 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * breakpoint.c (print_it_typical): Print reason for stopping in
+ case of bp_until.
+
+Thu Dec 2 17:14:53 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ser-pipe.c: Include <string.h> for memset().
+
+1999-12-01 Jim Blandy <jimb@cygnus.com>
+
+ * gdbtypes.c (builtin_type_v4si, builtin_type_v8qi,
+ builtin_type_v4hi, builtin_type_v2si): New SIMD types.
+ (build_gdbtypes): Initialize them.
+ (_initialize_gdbtypes): Gdbarch_swap them.
+ * gdbtypes.h (builtin_type_v4si, builtin_type_v8qi,
+ builtin_type_v4hi, builtin_type_v2si): Declare them.
+
+ * findvar.c (read_register_bytes, write_register_bytes): Correctly
+ determine how the region the caller is writing overlaps with each
+ register's bytes.
+
+ * value.h (struct value): Doc fixes.
+
+ * valops.c (value_assign): Clarify error message.
+
+1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * stack.c (return_command_wrapper): New function, to export
+ return_command().
+
+1999-12-01 Christopher Faylor <cgf@cygnus.com>
+
+ * config/i386/tm-cygwin.h: Change tm-i386.h include back to tm-i386v.h.
+
+1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * inf-loop.c (inferior_event_handler): In case of
+ INF_EXEC_CONTINUE, don't do all the regular continuations, but
+ just the intermediate ones.
+
+ * infcmd.c (step_once): Add the continuation to the
+ intermediate_continuation list instead of the regular continuation
+ list.
+
+ * utils.c (add_intermediate_continuation): New function, to add
+ continuations to the intermedite_continuation list.
+ (do_all_intermediate_continuations): New function, do all the
+ continuations in the intermediate list.
+ (discard_all_intermediate_continuations): New function, discard
+ all the continuations in the intermediate list.
+ (intermediate_continuation): New global list for use by step_1().
+
+ * defs.h: Export intermediate_continuation,
+ add_intermediate_continuation, do_all_intermediate_continuations,
+ discard_all_intermediate_continuations.
+
+1999-11-30 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c (mappings): Reorganize slightly for new uniform i386
+ register configuration.
+ (do_child_fetch_inferior_registers): Handle special case floating point
+ registers.
+ (handle_output_debug_string): Handle cygwin-specific signals broadcast
+ from the cygwin DLL.
+ (handle_exceptions): Add code to properly allow continuation after a
+ CTRL-C.
+ (child_continue): Accept propagated "continue_status" which controls
+ how the inferior should be continued.
+ (get_child_debug_event): New function.
+ (child_wait): Use above function to handle debug events.
+ (child_create_inferior): Add more intelligent method for running the
+ inferior to the appropriate point before handing it off to the rest of
+ gdb.
+ (child_stop): Specifically send a CTRL-C to the debugged process.
+ (child_kill_inferior): Set global continue status here to cause
+ inferior to run to completion.
+ (child_resume): Eliminate code which attempts to decide how to continue
+ the inferior. This is now handled by child_continue.
+ * config/i386/tm-cygwin.h: Gut and reorganize for consistency with new
+ tm-i386.h.
+
+ Patch from Egor Duda (deo@logos-m.ru)
+ * win32-nat.c (psapi_get_dll_name): New function.
+ (handle_load_dll): Correctly load DLL symbol tables after attaching to
+ a running pid.
+
+1999-11-30 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * infrun.c (handle_inferior_pid): revert 11-29 change: resuming
+ a thread other than the current thread with a signal. Apparently
+ target_resume with a specific pid, a specific signal, and no step
+ means to continue ALL threads but to only send the signal to one
+ (and not, as I had assumed, to continue only the specified thread).
+ * i386-linux-nat.c (fill_gregset): guard against invalid input.
+
+1999-11-30 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * infcmd.c (step_once): New function. Used to do just one step
+ operation.
+ (step_1_continuation): New function. Figure out if we need to step
+ again before returning control to the user.
+ (step_1): If we are in asynchronous mode, don't do the for loop,
+ but rather delegate to continuations the task of repeating the
+ step operation.
+
+ * utils.c (do_all_continuations): Copy the continuation list aside
+ before working on it.
+
+ * target.h (enum inferior_event_type): Add new enum
+ INF_EXEC_CONTINUE.
+
+ * inf-loop.c (inferior_event_handler): Handle new case
+ INF_EXEC_CONTINUE.
+
+ * infrun.c (fetch_inferior_event): If we are in the middle of a
+ 'step n' type command, don't say that the execution is complete,
+ but that it will have to continue.
+
+1999-11-30 Kevin Buettner <kevinb@cygnus.com>
+
+ * utils.c (verror): Don't traverse va_list argument twice. Also,
+ removed extraneous va_end() call.
+
+1999-11-29 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * infrun.c (handle_inferior_pid): If a child thread stops on a
+ signal that we are ignoring, and GDB silently resumes the child,
+ resume ALL threads (not just the one that got the signal). All
+ threads are stopped, so all must be resumed.
+ (handle_inferior_event): on detecting a thread context switch,
+ swap infrun_state ONLY if both the old thread and the new one
+ are in the thread list. Otherwise state information will be lost!
+ Problem may arise with flaky back-ends.
+
+1999-11-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * infrun.c (print_stop_reason): Don't print end of stepping reason
+ if we are in the middle of a multistep command (same condition as
+ in normal_stop).
+
+ * breakpoint.c (bpstat_stop_status): Don't decrease hit_count
+ in case of a wp that has not changed.
+
+Mon Nov 29 12:14:10 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbtypes.c (init_simd_type): Make static.
+
+ * configure.in (AC_CHECK_HEADERS): Check for <sys/ioctl.h>.
+ * configure, config.h: Re-generate.
+ * inflow.c: Include <sys/ioctl.h>
+
+ * i386b-nat.c: Include "gdbcore.h".
+ * fork-child.c: Include "command.h".
+
+ * remote.c (remote_cisco_section_offsets,
+ remote_start_remote_dummy, store_register_using_P,
+ remote_info_process, remote_cisco_open, remote_cisco_close,
+ readsocket, readtty, minitelnet, remote_cisco_wait,
+ init_remote_async_ops, init_extended_async_remote_ops,
+ set_remote_cmd), infrun.c (default_skip_permanent_breakpoint): Use
+ ISO-C syntax for function definition.
+
+Mon Nov 29 11:28:21 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * stabsread.c: Revert 1999-11-09 Jim Blandy
+ <jimb@zwingli.cygnus.com> and 1999-11-08 Jim Blandy
+ <jimb@cygnus.com>. Broken on non-Linux targets.
+
+1999-11-26 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * symfile.c (show_load_progress): Add total sent so far to the
+ information passsed to the hook users.
+ (generic_load): Collect total sent so far and pass that to the
+ progress hook.
+
+ * defs.h (show_load_progress): Update.
+
+1999-11-25 Nick Clifton <nickc@cygnus.com>
+
+ * coffread.c (coff_symfile_read): Treat "epoc-pe" targets as "pe"
+ targets.
+ * dbxread.c (dbx_read_symfile): Treat "epoc-pe" targets as "pe"
+ targets.
+
+Wed Nov 24 17:07:28 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (init.c): Add SUBDIR_INIT_FILES so that sub
+ directories can hook in extra init files.
+
+Wed Nov 24 11:41:01 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ui-out.h (field_string_ftype, ui_out_field_string): Make string
+ parameter const.
+ * cli-out.c (cli_field_string): Update.
+ * ui-out.c (uo_field_string, ui_out_field_string,
+ default_field_string): Update.
+
+1999-11-23 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * defs.h (show_load_progress): Export.
+
+ * symfile.c (show_load_progress): New hook for download.
+ (generic_load): Collect total size of executable to load.
+ Call progress hook when downloading.
+ Add output for ui case.
+ (print_transfer_performance): Add output for ui case.
+
+Thu Nov 18 11:54:24 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * arc-tdep.c (codestream_fill): Rewrite byte swap code using
+ function extract_unsigned_integer.
+
+Wed Nov 17 17:01:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * arm-xdep.c: #include "arm-opcode.h" -> "opcode/arm.h".
+
+1999-11-22 Jim Blandy <jimb@cygnus.com>
+
+ * Makefile.in (i386-tdep.o): Update list of dependencies.
+
+1999-11-22 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * stack.c (print_frame_info_base): Adjust output for stepi/nexti case.
+
+1999-11-22 Jim Blandy <jimb@cygnus.com>
+
+ * config/i386/tm-i386v.h (NUM_REGS, REGISTER_NAMES,
+ REGISTER_BYTES, REGISTER_BYTE, REGISTER_RAW_SIZE,
+ REGISTER_VIRTUAL_SIZE, MAX_REGISTER_RAW_SIZE,
+ MAX_REGISTER_VIRTUAL_SIZE, REGISTER_VIRTUAL_TYPE): Deleted. All
+ of these should inherit identical or compatible values from
+ tm-i386.h, as long as you don't define HAVE_SSE_REGS or
+ HAVE_I387_REGS, which are new anyway.
+
+Mon Nov 22 21:39:27 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * target.c (do_target_signal_to_host): New function. Indicate of
+ the conversion was successful to the caller via an additional
+ parameter.
+ (target_signal_to_host_p): New function. Return non-zero if the
+ GDB signal exists on the host system.
+ (target_signal_to_host): Rewrite. Use do_target_signal_to_host.
+ * target.h (target_signal_to_host_p): Add declaration. Document
+ target_singal vs host signal vs target OS signal confusion.
+
+ From 1999-11-08 Jimmy Guo <guo@cup.hp.com>:
+ * hppah-nat.c (require_notification_of_events): Start by ignoring
+ all signals and then adding back in ones we're interested in.
+
+Thu Nov 18 18:12:48 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * jv-typeprint.c (java_type_print_base), kod-cisco.c
+ (cisco_kod_open), kod.c (kod_set_os), xcoffread.c
+ (process_linenos), symfile.c (add_symbol_file_command),
+ remote-rdi.c (arm_rdi_open, rdilogfile_command), main.c
+ (captured_main), go32-nat.c (go32_create_inferior), exec.c
+ (exec_file_attach), corefile.c (core_file_command,
+ reopen_exec_file): Replace strdup with xstrdup.
+
+ * varobj.c (varobj_gen_name, c_name_of_child, c_value_of_variable,
+ cplus_value_of_variable): Replace strdup with xstrdup.
+ * ui-out.c (ui_out_table_begin): Ditto.
+
+Mon Nov 22 12:02:47 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * bcache.c (print_bcache_statistics): Fix printf_filtered
+ arguments.
+ (print_percentage): Make function void.
+
+1999-11-21 Jim Blandy <jimb@cygnus.com>
+
+ Make the bcache hash table grow.
+ * bcache.h (BCACHE_NUM_BUCKETS): Delete definition.
+ (struct bcache): Add new element: num_buckets. Make bucket be a
+ pointer to an array, not an array.
+ (free_bcache): New extern declaration.
+ * bcache.c (CHAIN_LENGTH_THRESHOLD): New constant.
+ (expand_hash_table): New function.
+ (bcache): Grow the hash table if the average chain length reaches
+ CHAIN_LENGTH_THRESHOLD.
+ (free_bcache): New function.
+ (print_bcache_statistics): Don't assume that the number of buckets
+ is constant any more.
+ (BSTRING_SIZE): Moved down to just above 'bcache' function, where
+ it's used.
+ * objfiles.c (free_objfile): Call free_bcache, instead of just
+ freeing the bcache's obstack directly.
+ * symfile.c (reread_symbols): Same.
+
+1999-11-20 Jim Blandy <jimb@cygnus.com>
+
+ * bcache.c, bcache.h: Rewritten. New version imposes less memory
+ overhead, and has a more effective hash function, so it's probably
+ faster, too.
+
+ * config/nm-linux.h: No need to check whether __STDC__ is
+ #defined --- GDB requires ANSI C now.
+
+ * config/i386/nm-linux.h (linuxthreads_pid_to_str,
+ linuxthreads_prepare_to_proceed): Delete declarations --- they're
+ provided by config/nm-linux.h now.
+
+1999-11-19 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * top.c (print_command_lines): Remove unused var.
+
+1999-11-19 Jim Kingdon <kingdon@redhat.com>
+
+ Patch applied by Jim Blandy <jimb@cygnus.com>:
+
+ Enable threads for all linux architectures:
+ * config/nm-linux.h: New file.
+ config/alpha/nm-linux.h, config/i386/nm-linux.h,
+ config/m68k/nm-linux.h, config/sparc/nm-linux.h: Use it.
+ * config/tm-linux.h: New file.
+ * config/i386/tm-linux.h, config/m68k/tm-linux.h,
+ config/sparc/tm-linux.h, config/alpha/tm-alphalinux.h: Use it.
+ * config/m68k/linux.mh, config/sparc/linux.mh,
+ config/alpha/alpha-linux.mh: Add linux-thread.o.
+
+1999-11-18 Tom Tromey <tromey@cygnus.com>
+
+ * tracepoint.h (get_tracepoint_by_number): Updated declaration.
+ * tracepoint.c (trace_pass_command): Better error message. Fixed
+ logic when `all' not specified.
+ (get_tracepoint_by_number): Added `optional_p' argument. Fixed
+ all callers.
+
+Wed Nov 17 17:40:30 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * findvar.c (SWAP_FLOATING): Delete macro. Unused.
+
+1999-11-16 Mark Salter <msalter@cygnus.com>
+
+ * monitor.c (monitor_supply_register): Initialize value to zero.
+
+1999-11-15 Eli Zaretskii <eliz@is.elta.co.il>
+
+ (Patches applied by Jim Blandy <jimb@zwingli.cygnus.com>)
+
+ Change DJGPP target use the common register layout in
+ config/i386/tm-i386.h.
+ * config/i386/tm-go32.h: #include "i386/tm-i386.h", not
+ "i386/tm-i386v.h".
+ (HAVE_I387_REGS): Define.
+ (HAVE_SSE_REGS): Undefine.
+ (NUM_FREGS, NUM_REGS, REGISTER_NAMES, FP_REGNUM, SP_REGNUM,
+ PS_REGNUM, PC_REGNUM, FP0_REGNUM, FPC_REGNUM, FPCWD_REGNUM,
+ FPSWD_REGNUM, FPTWD_REGNUM, FPIPO_REGNUM, FPIPS_REGNUM,
+ FPOOS_REGNUM, FPOPS_REGNUM, REGISTER_BYTES, REGISTER_BYTE,
+ REGBYTE_0, REGBYTE_10 REGBYTE_16, REGBYTE_24, REGBYTE_29,
+ REGISTER_RAW_SIZE, REGISTER_VIRTUAL_SIZE, MAX_REGISTER_RAW_SIZE,
+ MAX_REGISTER_VIRTUAL_SIZE, REGISTER_CONVERTIBLE): Definitions
+ deleted.
+ (i387_to_double, double_to_i387): Declarations deleted.
+ (REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW,
+ REGISTER_VIRTUAL_TYPE): Use definitions from
+ config/i386/tm-i386.h, unless LD_I387 is #defined.
+
+ * go32-nat.c (go32_fetch_registers, store_register)
+ (go32_create_inferior, init_go32_ops): Replace fatal with
+ internal_error.
+ (sig_map): Map exception 7 to TARGET_SIGNAL_EMT.
+
+ * utils.c (notice_quit): Doc fixes.
+
+1999-11-15 Kevin Buettner <kevinb@cygnus.com>
+
+ * gdbserver/server.h (initialize_low): Declare this target
+ specific function.
+ * gdbserver/server.c (main): Call initialize_low.
+ * gdbserver/low-hppabsd.c, gdbserver/low-linux.c,
+ gdbserver/low-sim.c, gdbserver/low-sparc.c, gdbserver/low-sun3.c
+ (initialize_low): Renamed from initialize. Also removed
+ initialization of inferior_pid.
+ (have_inferior_p): Removed.
+ * gdbserver/low-lynx.c (initialize_low): New function.
+
+1999-11-12 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * remote-rdi.c: Fix indentation accordingly to GNU standards.
+
+1999-11-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * breakpoint.h: Export {watch, awatch, rwatch}_command_wrapper().
+
+ * breakpoint.c (print_it_typical): Add output for bp_watchpoint,
+ bp_hardware_watchpoint, read_watchpoint, access_watchpoint cases.
+ (watchpoint_check): Add output for when the watchpoint goes out of
+ scope.
+ (mention): Add output for bp_watchpoint, bp_hardware_watchpoint,
+ read_watchpoint, access_watchpointcases. Move end of list to end
+ of function.
+ ({watch, awatch, rwatch}_command_wrapper): New functions, to
+ export {watch, awatch, rwatch}_command().
+
+Thu Oct 28 00:28:51 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (d10v_gdbarch_init): Make the d10v:ts3 the default.
+
+Tue Oct 26 09:57:29 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh: Re-sync with Cagney's earlier const change.
+
+Sun Oct 24 20:07:31 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (struct gdbarch_tdep): Replace nr_a_regs,
+ imap0_regnum, nr_imap_regs, dmap0_regnum, with dmap_register and
+ imap_register.
+ (R0_REGNUM, LR_REGNUM, PSW_REGNUM, NR_IMAP_REGS, NR_A_REGS):
+ Convert to enums.
+ (TS2_NR_A_REGS, TS2_NR_IMAP_REGS, TS3_NR_IMAP_REGS,
+ TS3_NR_A_REGS): Delete.
+ (d10v_ts2_dmap_register, d10v_ts3_dmap_register,
+ d10v_ts2_imap_register, d10v_ts3_imap_register): New functions.
+ (d10v_dmap_register, d10v_imap_register,
+ d10v_ts2_register_sim_regno, d10v_ts3_register_sim_regno,
+ show_regs): Update.
+ (remote_d10v_translate_xfer_address): Rewrite. Use
+ sim_d10v_translate_addr to translate addresses.
+ (d10v_gdbarch_init): Initialize tdep members dmap_register and
+ imap_register.
+
+Sun Oct 24 00:12:44 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (struct gdbarch_tdep): Declare.
+ (NR_IMAP_REGS, NR_DMAP_REGS, A0_REGNUM, NR_A_REGS): Redefine using
+ value in gdbarch_tdep.
+ (d10v_dmap_register, d10v_imap_register): Ditto.
+ (d10v_ts2_register_name, d10v_ts2_register_sim_regno): Rename
+ d10v_register_name and d10v_register_sim_regno
+ (enum ts3_regnums, d10v_ts3_register_name,
+ d10v_ts3_register_sim_regno, d10v_register_sim_regno): New.
+ (d10v_gdbarch_init): Configure registers and G packet according to
+ d10v/ts2 and d10v/ts3.
+
+Sat Oct 23 21:28:02 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/d10v/tm-d10v.h (IMAP0_REGNUM, IMAP1_REGNUM, DMAP_REGNUM):
+ Delete macro.
+ (R0_REGNUM, LR_REGNUM, PSW_REGNUM, A0_REGNUM): Move from here.
+ * d10v-tdep.c: To here.
+
+ * d10v-tdep.c: (NR_DMAP_REGS, NR_IMAP_REGS, NR_A_REGS): Define.
+ (d10v_dmap_register, d10v_imap_register): New functions.
+ (remote_d10v_translate_xfer_address): Make static.
+ (d10v_register_virtual_size): Use TYPE_LENGTH of
+ REGISTER_VIRTUAL_TYPE.
+ (d10v_register_byte, do_d10v_pop_frame,
+ remote_d10v_translate_xfer_address, show_regs,
+ d10v_register_raw_size): Ditto.
+ (d10v_register_virtual_type): Ditto. Use explicitly sized builtin
+ types.
+
+Sat Oct 23 19:08:39 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c: Include "sim-d10v.h".
+ (enum ts2_regnums): Declare.
+ (d10v_register_sim_regno): New function.
+
+ * config/d10v/tm-d10v.h: Delete pre multi-arch code.
+ (REGISTER_SIM_REGNO): Define.
+ (d10v_register_sim_regno): Declare.
+
+Sat Oct 23 16:39:34 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.c (initialize_current_architecture): Make ``choice''
+ const.
+
+Wed Nov 10 16:10:22 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppa-tdep.c (hppa_fix_call_dummy): Fix typo in error message.
+
+Wed Nov 10 16:47:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * utils.c (error_last_message): Use gdb_file_xstrdup.
+
+ * defs.h (verror, internal_verror): Declare.
+
+ * utils.c (verror, internal_error): New functions.
+ (error, internal_error): Use verror / internal_verror.
+ (error_stream): Use gdb_file_xstrdup. Correctly handle %s in
+ error message body.
+ (error_init): Use mem_fileopen.
+
+ * corefile.c (memory_error): Use mem_fileopen instead of
+ tui_sfileopen. Don't call error_begin.
+ * varobj.c (c_value_of_variable): Use mem_fileopen () and
+ gdb_file_xstrdup() instead of strdup and tui_sfileopen.
+ * remote-sim.c (gdb_os_error): Rewrite using verror. Don't call
+ error_begin.
+
+Wed Nov 10 14:21:43 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (gdb_file_xstrdup): New function.
+ * utils.c (gdb_file_xstrdup, do_gdb_file_xstrdup): Implement.
+ * ui-out.c (ui_out_stream_new): Simplify, XMALLOC doesn't return
+ if malloc failed. Use mem_fileopen and gdb_file_xstrdup.
+
+1999-11-09 Stan Shebs <shebs@andros.cygnus.com>
+
+ * exec.c (exec_file_attach), irix5-nat.c, osfsolib.c, solib.c
+ (info_sharedlibrary_command), pa64solib.c
+ (pa64_sharedlibrary_info_command), somsolib.c
+ (som_sharedlibrary_info_command): Replace "exec file" with
+ "executable file" in messages.
+
+1999-11-09 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Finish the job attempted by the previous change.
+ * stabsread.c (read_range_type): Make n2 and n3 LONGEST. Adjust
+ the various tests that check for maximum values, bit counts, etc.
+ In the long run, it might have been simpler just to give GDB bignums.
+
+Tue Nov 9 18:34:13 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * defs.h (gdb_file_put): Add parameter write.
+ (gdb_file_put_method_ftype): New typedef.
+ * utils.c (gdb_file_put, mem_file_put, tui_file_put,
+ null_file_put): Update.
+
+ * utils.c (struct gdb_file): Add field magic.
+ (gdb_file_new): Initialize.
+ (gdb_file_data): Verify.
+
+ * utils.c (mem_file_fputs): Delete. Replaced by.
+ (mem_file_write): New function. Rewrite mem_file.
+ (mem_file_new): Update.
+
+Tue Nov 9 17:51:12 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.c (gdb_os_write_stdout): Use gdb_file_write.
+ (gdb_os_flush_stdout): Flush gdb_stdtarg instead of gdb_stdout.
+
+Tue Nov 9 15:33:43 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (procfs.o): Don't compile with -Werror for moment.
+ * sol-thread.c (info_cb): Move assignments to outside of if
+ statement.
+ (info_cb): Use paddr when printing addresses.
+
+1999-11-08 Jim Blandy <jimb@cygnus.com>
+
+ * defs.h (ULONGEST_MAX, LONGEST_MAX): New definitions.
+ * stabsread.c (read_huge_number): Parse and return LONGEST values.
+
+1999-11-08 Mark Salter <msalter@cygnus.com>
+
+ * utils.c (floatformat_to_doublest): Fix conversion of denormals.
+
+1999-11-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * breakpoint.c (hbreak_command_wrapper): New function, to export
+ hbreak_command.
+ (thbreak_command_wrapper): New function, to export thbreak_command.
+
+ * symtab.c (rbreak_command_wrapper): New function, to export
+ rbreak_command.
+
+ * breakpoint.h (hbreak_command_wrapper, thbreak_command_wrapper,
+ rbreak_command_wrapper): Export.
+
+Mon Nov 8 20:14:13 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * remote.c (get_memory_read_packet_size): For moment limit read
+ size to PBUFSIZ.
+ (putpkt_binary): Remove check on packet size. Allocate ``cnt +
+ 6'' characters for output buffer.
+ (get_memory_packet_size): When packet size is ``fixed'' and the
+ size is zero, return MAX_REMOTE_PACKET_SIZE. Check that packets
+ are at least MIN_REMOTE_PACKET_SIZE.
+ (set_memory_packet_size): Print usage when ``args'' is NULL.
+
+Mon Nov 8 18:18:07 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h, utils.c (gdb_file_deallocate): Delete.
+ * varobj.c (varobj_get_type, c_value_of_variable): Use
+ make_cleanup_gdb_file_delete.
+ * ui-out.c (ui_out_stream_delete): Use gdb_file_delete.
+ * corefile.c (memory_error): Use make_cleanup_gdb_file_delete.
+
+ * defs.h, utils.c (gdb_file_init_astring): Delete.
+
+ * defs.h, utils.c (tui_file_get_strbuf): Rename
+ gdb_file_get_strbuf.
+ (tui_file_adjust_strbuf): Rename gdb_file_adjust_strbuf.
+ * utils.c (error_stream, error_last_message): Update.
+ * varobj.c (varobj_get_type, c_value_of_variable): Update.
+ * ui-out.c (ui_out_field_stream): Update.
+
+Mon Nov 8 16:28:00 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h, utils.c (gdb_fclose): Delete.
+ * defs.h (make_cleanup_gdb_file): Declare.
+ * utils.c (make_cleanup_gdb_file_delete, do_gdb_file_delete): New
+ functions.
+
+ * symmisc.c (maintenance_print_symbols,
+ maintenance_print_psymbols, maintenance_print_msymbols): Use
+ make_cleanup_gdb_file_delete.
+ * serial.c (do_serial_close): Use gdb_file_delete.
+
+Mon Nov 8 14:16:32 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (gdb_file_write_ftype, set_gdb_file_write,
+ gdb_file_write): Declare.
+
+ * utils.c (struct gdb_file): Add to_write member.
+ (gdb_file_write, set_gdb_file_write): New functions.
+ (gdb_file_new): Initialize the write method.
+ (null_file_write): New function.
+ (null_file_fputs, null_file_write): ``write'' calls ``fputs'' and
+ ``fputs'' calls ``write'' when the other is implemented.
+ (stdio_file_new): Initialize write method.
+ (stdio_file_write): New function.
+
+ * utils.c (putchar_unfiltered, fputc_unfiltered): Use
+ gdb_file_write.
+
+Thu Nov 4 11:59:24 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (get_memory_packet_size, set_memory_packet_size,
+ build_memory_packet_size): New functions. Set / compute / update
+ the size of a memory read / write packet.
+ (set_memory_read_packet_size, set_memory_write_packet_size): New
+ functions. Verify changes to the memory read / write packet size.
+ (prefered_memory_write_packet_size,
+ current_memory_write_packet_size, prefered_memory_read_packet_size,
+ current_memory_read_packet_size): New variables.
+ (get_memory_read_packet_size, get_memory_write_packet_size): New
+ functions. Determine the current memory read/write packet size. A
+ function is needed as ``current_register_packet_size'', a variable
+ is used in the calculation.
+ (register_remote_packet_sizes, build_remote_packet_sizes):
+ Initialize packet sizes according the current architecture.
+ (remote_fetch_registers, remote_write_bytes, remote_read_bytes,
+ build_remote_gdbarch_data): Update.
+ (_initialize_remote): Add the commands ``set remote
+ memory-read-packet-size'' and ``set remote
+ memory-write-packet-size''. Deprecate ``set remotepacketsize''.
+
+Sun Nov 7 18:09:54 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * target.h, target.c (target_load): Replace macro with a function.
+
+ * config/i960/tm-nindy960.h (ADDITIONAL_OPTION_HANDLER): Rewrite
+ replacing SET_TOP_LEVEL with catch_command_errors.
+ (nindy_open): Add extern declaration.
+
+ * top.h (top_level_val, SET_TOP_LEVEL): Delete.
+ * defs.h (catch_command_errors_ftype, catch_command_errors): Add
+ declarations.
+ * top.c (struct captured_command_args): Declare.
+ (do_captured_command, catch_command_errors): New functions. Call
+ the command function via catch_errors.
+ (catch_errors): Add more comments.
+
+ * main.c (struct captured_main_args): Define.
+ (captured_main): New. Rewrite main. Replace SET_TOP_LEVEL with
+ calls to catch_command_errors. Delete calls to do_cleanups which
+ are now handled by catch_errors. Call the command loop via
+ captured_command_loop and catch_errors.
+ (main): Move code body to captured_main. Call captured_main via
+ catch_errors.
+ (captured_command_loop): New function. Wrap call to command_loop.
+
+1999-11-05 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * procfs.c (unconditionally_kill_inferior) (init_procinfo)
+ (create_procinfo) (procfs_exit_handler) (proc_set_exec_trap)
+ (do_attach) (do_detach) (procfs_wait) (set_proc_siginfo)
+ (procfs_resume) (info_proc_mappings)
+ (modify_run_on_last_close_flag) (procfs_lwp_creation_handler)
+ (procfs_thread_alive): Remove unused variables, conditionalize
+ vars declarations to eliminate compiler warnings.
+
+1999-11-05 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * infcmd.c (print_return_value): Add output for UI.
+
+Fri Nov 5 16:32:04 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * inferior.h (CALL_DUMMY_ADDRESS, CALL_DUMMY_START_OFFSET,
+ CALL_DUMMY_BREAKPOINT_OFFSET, CALL_DUMMY_LENGTH,
+ CALL_DUMMY_STACK_ADJUST, CALL_DUMMY_WORDS,
+ SIZEOF_CALL_DUMMY_WORDS, PUSH_DUMMY_FRAME, FIX_CALL_DUMMY,
+ STORE_STRUCT_RETURN), d10v-tdep.c (print_insn), d30v-tdep.c
+ (print_insn), target.h (SOFTWARE_SINGLE_STEP): Call internal_error
+ instead of abort.
+
+ * utils.c (stdio_file_delete, stdio_file_flush, stdio_file_fputs,
+ stdio_file_isatty, tui_file_delete, tui_file_isatty,
+ tui_file_rewind, tui_file_put, gdb_file_init_astring,
+ gdb_file_get_strbuf, gdb_file_adjust_strbuf): Call internal_error
+ instead of error.
+
+1999-11-04 Kevin Buettner <kevinb@cygnus.com>
+
+ * remote.c (build_remote_gdbarch_data): Set remote_address_size...
+ (_initialize_remote) ...but don't set it here. Also, tie
+ remote_address_size to the target architecture via call to
+ register_gdbarch_swap().
+
+1999-11-04 Jeff Holcomb <jeffh@cygnus.com>
+
+ * remote-rdp.c (send_rdp): Fix typo.
+
+1999-11-04 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * breakpoint.c (commands_command): remove unprotected ref to
+ args pointer (which may be null).
+
+1999-11-04 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * infcmd.c (print_return_value): New function. Print return value
+ from finish command.
+ (finish_command_continuation): Call print_return_value().
+ (finish_command): Ditto.
+
+1999-11-04 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * breakpoint.c (print_it_typical): Print reason for stopping in
+ case of bp_finish.
+
+1999-11-04 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * infrun.c (handle_inferior_event): Add calls to print_stop_reason()
+ for end of stepping range cases.
+ (print_stop_reason): Add output for END_STEPPING_RANGE, EXITED,
+ SIGNAL_EXITED, SIGNAL_RECEIVED cases.
+
+ * breakpoint.c (print_it_typical): Add printing of stop reason for
+ bp_breakpoint case.
+
+Thu Nov 4 17:46:36 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * event-loop.c (gdb_do_one_event): Delete SET_TOP_LEVEL call.
+ Move error code to start_event_loop.
+ (start_event_loop): Call gdb_do_one_event via catch_errors.
+ Handle caught errors.
+
+Thu Nov 4 17:36:27 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * breakpoint.c (get_number): Delete static declaration.
+
+1999-11-03 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * breakpoint.c (map_breakpoint_numbers): use a match count
+ instead of a goto.
+
+1999-11-03 Nick Clifton <nickc@cygnus.com>
+
+ * config/mcore/tm-mcore.h (TARGET_BYTE_ORDER_DEFAULT): Change to
+ little endian.
+
+1999-11-02 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * target.h (target_new_objfile) replace macro with function pointer
+ hook. Any module needing notification of new objfiles may claim
+ this hook. Multiple notification clients must cooperate by saving
+ the previous pointer (if any) and calling it.
+ * sol-thread.c (_initialize_sol_thread): point new_objfile hook at
+ sol_thread_new_objfile. Save old pointer if any.
+ (sol_thread_new_objfile): call old owner of event hook if any.
+ * hpux-thread.c (_initialize_hpux_thread, hpux_thread_new_objfile):
+ ditto.
+ * linux-thread.c (_initialize_linux_thread, linux_thread_new_objfile):
+ ditto.
+ symfile.c (symbol_file_add, clear_symtab_users) call the new
+ function pointer hook, instead of the macro.
+ * config/sparc/nm-sun4sol2.h: remove define of target_new_objfile.
+ * config/pa/nm-hppah.h: ditto.
+ * config/i386/nm-i386sol2.h: ditto.
+ * config/i386/nm-linux.h: ditto.
+
+1999-11-02 Tom Tromey <tromey@cygnus.com>
+
+ * NEWS: Mention breakpoint ranges.
+
+1999-11-02 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * rdi-share/devsw.c (openLogFile): Change a call to setlinebuf()
+ to an equivalent call to setvbuf() to prevent an unresolved
+ reference when building on cygwin.
+
+1999-11-02 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * infrun.c (inferior_stop_reason): New enum, explicitly name the
+ resons for which the inferior stops.
+ (handle_inferior_event): Case TARGET_WAITKIND_EXITED: replace
+ printf's with call to print_stop_reason(). Case
+ TARGET_WAITKIND_SIGNALLED: Same. When stopped by random signal:
+ Same.
+ (print_stop_reason): New static function. Print relevant messages
+ when stopping.
+
+1999-11-02 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * rdi-share/Makefile.in: Rename dependency from bytesex.o to
+ angel_bytesex.o.
+
+1999-11-02 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * kod.c: Remove prototype for show_kod() which is no longer used.
+
+1999-11-01 Michael Snyder <msnyder@cygnus.com>
+ Tom Tromey <tromey@cygnus.com>
+
+ * tracepoint.h (get_tracepoint_by_number): Updated declaration.
+ * tracepoint.c (get_tracepoint_by_number): Added `multi_p'
+ argument. Now uses get_number_or_range and get_number.
+ (trace_pass_command): Allow a tracepoint range.
+ * breakpoint.h (get_number, get_number_or_range): Declare.
+ * breakpoint.c (get_number_trailer): New function.
+ (get_number): Rewrote to use get_number_trailer.
+ (get_number_or_range): New function.
+ (condition_command): Check `get_number' return value.
+ (commands_command): Likewise.
+ (ignore_command): Likewise.
+ (map_breakpoint_numbers): Use get_number_or_range.
+
+1999-11-01 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * remote-rdi.c (_initialize_remote_rdi): Make log commands
+ subcommands of maintenance. Remove improper identation from
+ command documentation.
+
+1999-11-01 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From Grant Edwards <grante@visi.com>:
+ * rdi-share/etherdrv.c (fetch_ports): Print out additional TCP/IP
+ port information in ethernet driver if the DEBUG flag is set.
+ * rdi-share/hostchan.c (Adp_addToQueue): Changed #if statement in
+ hostchan.c to avoid compiler complaint when DEBUG macro was
+ undefined.
+ * rdi-share/unixcomm.c (Unix_ReadSerial): Print system error code
+ if read() system call fails.
+
+1999-11-01 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * rdi-share/bytesex.h: Deleted. Conflicts with a system header file
+ on some systems like Linux Red Hat 5.2.
+ * rdi-share/angel_bytesex.h: New file. Replaces the above.
+ * rdi-share/bytesex.c: Deleted. Name changed to match the header
+ mentioned above (this is the implementation file).
+ * rdi-share/angel_bytesex.c: New file. Replaces the above.
+ * rdi-share/Makefile.am: Reflect above changes.
+ * rdi-share/Makefile.in: Reflect above changes.
+
+1999-11-01 Jimmy Guo <guo@cup.hp.com>
+
+ * annotate.c (breakpoints_changed, annotate_ignore_count_change,
+ annotate_stopped): Provide annotation for breakpoint ignore_count
+ changes but only provide once at annotate_stopped time for
+ sucessive ignore_count triggered breakpoint changes, to make GUIs
+ happy yet lazy.
+ * annotate.h (annotate_ignore_count_change): Declare.
+ * breakpoint.c (bpstat_stop_status): Call
+ annotate_ignore_count_change when ignore_count changes.
+
+1999-11-01 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From Grant Edwards <grante@visi.com>:
+ * rdi-share/ardi.c (HandleStoppedMessage): Changed code that
+ handles the "stop" message so that unrecognized errors are
+ returned as "Error" rather than "NoError". The old code resulted
+ in some error conditions not being reported to the user.
+
+1999-11-01 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From Grant Edwards <grante@visi.com>:
+ * remote-rdi.c (arm_rdi_open): Added a call to Adp_CloseDevice()
+ before attempting to open a connection. This allows the user to
+ issue the "target rdi" command multiple times (in case the user
+ needs to change options or re-initialize the link).
+
+1999-11-01 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From Grant Edwards <grante@visi.com>:
+ * rdi-share/endian.h: Deleted. Name clash with
+ /usr/include/endian.h. This was causing the wrong byte order to
+ be used by htons() in the RDI Ethernet driver.
+ * rdi-share/angel_endian.h: New file. Replaces the above.
+ * rdi-share/ardi.c: Replace include to reflect the above change.
+ * rdi-share/etherdrv.c: Ditto.
+ * rdi-share/hsys.c: Ditto.
+ * rdi-share/msgbuild.c: Ditto.
+ * rdi-share/params.c: Ditto.
+ * rdi-share/rx.c: Ditto.
+ * rdi-share/tx.c: Ditto.
+ * rdi-share/Makefile.am: Reflect above changes.
+ * rdi-share/Makefile.in: Reflect above changes.
+
+1999-11-01 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From Grant Edwards <grante@visi.com>:
+ * remote-rdi.c (_initialize_remote_rdi): Added command
+ rdilogenable. Allows the user to log ADP packets that are
+ exchanged between gdb and the target. Both the raw packets are
+ shown and some minimal decoding is attempted. Default state is
+ disabled.
+ (_initialize_remote_rdi): Added command rdilogfile. Allows the
+ user to specify the filename to which the ADP packet log is to be
+ written. Default state is "rdi.log".
+ (rdilogenable_command): New function. Related to rdilogenable.
+ (rdilogfile_command): New function. Related to rdilogfile.
+ * rdi-share/devsw.c (openLogFile, closeLogFile,
+ DevSW_SetLogEnable, DevSW_SetLogfile, dumpPacket): New
+ functions. Implement logging.
+ (DevSW_Read): Log if requested.
+ (DevSW_Write): Log if requested.
+ * rdi-share/devsw.h: Add prototypes for DevSW_SetLogfile and
+ DevSW_SetLogEnable.
+ * rdi-share/hostchan.c (Adp_SetLogEnable, Adp_SetLogfile): New
+ functions. Related to rdilogenable and rdilogfile.
+ * rdi-share/hostchan.h: Add prototypes for the above functions.
+
+1999-11-01 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From Grant Edwards <grante@visi.com>:
+ * remote-rdi.c (arm_rdi_open): Added code to split the arguments
+ to the 'target rdi' command at the first space. The first word is
+ passed to Adp_OpenDevice as the device name, the tail is passed as
+ the "arguments" parameter. This allows user specified baud rates
+ -- among other things that still need to be documented [e.g. (gdb)
+ target rdi /dev/ttyS1 19200]. NB: With very limited testing, the
+ ARM Embedded-ICE seems to run at 19.2K (though it is reported to
+ be unreliable above 9600), and the EPI Jeeni seems to run at
+ 38.4K.
+
+1999-11-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * stack.c (print_frame_info_base): Do not change printing of stack
+ frame info if not running with our interpreter.
+
+1999-11-01 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From Grant Edwards <grante@visi.com>:
+ * remote-rdi.c (_initialize_remote_rdi): Added the boolean
+ set/show variable rdiromatzero. Should be set to true if the
+ target has ROM at address 0. If true, then gdb will not tell the
+ target to trap fetches to interrupt vectors (which are located at
+ address 0). Using the Angel monitor, attempting to set
+ breakpoints in ROM is an error. Using JTAG debugging of the
+ ARM7TDMI, attempting to set more than two breakpoints in ROM is an
+ error. Default state is false (vectors will be trapped) -- used to
+ be hardwired false.
+
+1999-11-01 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From Grant Edwards <grante@visi.com>:
+ * remote-rdi.c (_initialize_remote_rdi): Added the boolean
+ set/show variable rdiheartbeat. This enables or disables ADP
+ link-check "heartbeat" packets sent by the host to the target.
+ Heartbeat packets can cause both the ARM Embedded-ICE and the EPI
+ Jeeni to malfunction: If a heartbeat packet is received by the
+ target while it is sending a packet, that packet will be aborted,
+ and the ADP protocol engine then gets very confused. Default state
+ is off -- used to hardwired on.
+
+1999-10-29 Kevin Buettner <kevinb@cygnus.com>
+
+ * i386-linux-nat.c (dummy_sse_values): Also define for systems
+ without PTRACE_GETXFPREGS.
+
+1999-10-29 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Hardware watchpoint fix from Eli Zaretskii <eliz@gnu.org>:
+
+ * breakpoint.c (insert_breakpoints): Fetch the value of the
+ expression we need to watch. If it's a lazy memory lvalue, then
+ we need to fetch it now, before we start the inferior again.
+ (insert_breakpoints, remove_breakpoint, bpstat_stop_status,
+ can_use_hardware_watchpoint): Only those values representing
+ memory we actually fetched need to be watched.
+
+1999-10-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * breakpoint.h (bpstat_print): Return 'enum print_stop_action',
+ not 'int'.
+
+1999-10-29 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * acconfig.h: Fix entries for HAVE_STRUCT_SAVE_STATE_T,
+ HAVE_STRUCT_MEMBER_SS_WIDE, and HAVE_PTRACE_GETXFPREGS.
+ * config.h.in: Regenerated.
+
+1999-10-28 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Fixes for warnings from Andreas Jaeger <aj@suse.de>.
+ * linux-thread.c (linuxthreads_sig_restart,
+ linuxthreads_sig_cancel, linuxthreads_sig_debug): Add missing
+ initializers to avoid gcc warnings.
+ (resume_thread): Add braces as recommended by gcc -Wparentheses.
+ (stop_thread): Likewise.
+ (linuxthreads_wait): Likewise.
+ (linuxthreads_find_trap): Likewise.
+
+1999-10-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * infcmd.c: Fix typo.
+
+1999-10-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * stack.c (select_frame_command_wrapper): Fix typo.
+
+ * infcmd.c (interrupt_target_command_wrapper): Wrapper to allow use of
+ static interrupt_target_command outside of file.
+
+ * stack.c (select_frame_command_wrapper): Wrapper to allow use of
+ static select_frame_command outside of file.
+
+1999-10-28 Jim Blandy <jimb@cygnus.com>
+
+ * gdbtypes.c (init_simd_type): The upper bound to
+ create_range_type is inclusive, not exclusive.
+
+ Add preliminary support for the Pentium-III's Streaming SIMD
+ Extensions --- specifically, the ability to read the XMM
+ registers.
+ * Configure.in: Check for PTRACE_GETXFPREGS, and #define
+ HAVE_PTRACE_GETXFPREGS if we have it.
+ * acconfig.h: Add entry for HAVE_PTRACE_GETXFPREGS.
+ * configure, config.in: Regenerated.
+ * config/i386/tm-linux.h (HAVE_SSE_REGS): #define, iff the
+ configure script #defined HAVE_PTRACE_GETXFPREGS.
+ (REGISTER_VIRTUAL_TYPE): Provide the proper types for the pointer
+ registers and the SSE registers.
+ * i386-linux-nat.c (GETREGS_SUPPLIES, GETFPREGS_SUPPLIES,
+ GETXFPREGS_SUPPLIES): New macros.
+ (have_ptrace_getxfpregs): New variable.
+ (FPREGSET_T_FPREG_ADDR): Renamed from FPREGSET_T_FPREG_OFFSET.
+ (supply_fpregset, convert_to_fpregset): Callers changed.
+ (supply_xfpregset, convert_to_xfpregset, fetch_xfpregs,
+ store_xfpregs, dummy_sse_values): New functions.
+ (fetch_inferior_registers, store_inferior_registers): Use the
+ *_SUPPLIES macros to decide how to fetch a given register. Use
+ {fetch,store}_xfpregs and dummy_sse_values to provide access to
+ the SSE registers, on systems where they are present.
+
+1999-10-28 Kevin Buettner <kevinb@cygnus.com>
+
+ * gdbserver/gdbreplay.c (config.h, errno.h): Include.
+ (perror_with_name): Don't declare sys_nerr, sys_errlist, or errno
+ when STDC_HEADERS is defined.
+ * gdbserver/utils.c (STDC_HEADERS): Likewise.
+
+ * gdbserver/low-hppabsd.c, gdbserver/low-linux.c,
+ gdbserver/low-lynx.c, gdbserver/low-sim.c, gdbserver/low-sparc.c,
+ gdbserver/low-sun3.c (my_registers): Declare.
+ (registers): Changed from array type to pointer type in order
+ to match declaration in inferior.h in main gdb sources.
+ * gdbserver/server.h (registers): Likewise.
+ * gdbserver/remote-utils.c (outreg): Removed declaration of
+ registers[].
+
+ * gdbserver/low-linux.c (fetch_register): Changed PTRACE_PEEKUSR to
+ PTRACE_PEEKUSER. [Note the missing 'E'.]
+ (store_inferior_registers): Likewise for PTRACE_POKEUSER.
+
+ * gdbserver/low-linux.c (sys/ptrace.h): Move include to
+ avoid conflict with #defines coming from <sys/user.h>.
+ (sys/reg.h): Only include when HAVE_SYS_REG_H is defined.
+ (PTRACE_XFER_TYPE): Provide a default type in case
+ the target doesn't define it.
+ (fetch_register, read_inferior_memory, write_inferior_memory):
+ Use PTRACE_XFER_TYPE instead of int for ptrace() transfers.
+ (I386_GNULINUX_TARGET): Use #ifdef with this symbol instead
+ of assuming it's an x86 target when it's not a m68k target.
+ (i386_register_raw_size, i386_register_byte): Define these arrays
+ to match other changes that've been occuring to the x86 target
+ in the main gdb sources.
+ (initialize_arch): New (static) function for doing target arch
+ specific initializations.
+
+ * gdbserver/server.h (MAXBUFBYTES, PBUFSIZ): New defines
+ [actually stolen from remote.c].
+ * gdbserver/remote-utils.c (putpkt): Use PBUFSIZ to make
+ sure that buffer is big enough.
+ * gdbserver/server.c (main): Ditto.
+
+ * gdbserver/remote-utils.c (outreg): Allow register numbers
+ bigger than 255.
+ (prepare_resume_reply): Provide alternate mechanism,
+ GDBSERVER_RESUME_REGS, for defining list of registers to send
+ to gdb.
+ * gdbserver/Makefile.in (INTERNAL_CFLAGS): Swapped order of
+ INCLUDE_CFLAGS and BFD_CFLAGS to ensure that gdb's config.h
+ gets found before bfd's config.h. Also added -DGDBSERVER
+ switch.
+ (INCLUDE_CFLAGS): Added -I.. .
+
+1999-10-27 Nick Clifton <nickc@cygnus.com>
+
+ * arm-tdep.c (THUMB_BE_BREAKPOINT): Change to 0xbebe.
+ (THUMB_LE_BREAKPOINT): Change to 0xbebe.
+
+1999-10-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * stack.c (print_frame_info_base): Don't print the arguments
+ during a backtrace.
+ * stack.c (print_frame_info_base): When setting source to 0, save
+ and restore old value. Do this only if source is greater than
+ zero.
+
+Mon Oct 25 18:22:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c: Document future of compare_sections_command.
+ (remote_insert_breakpoint, remote_remove_breakpoint,
+ remote_insert_watchpoint, remote_insert_watchpoint,
+ remote_remove_watchpoint, remote_insert_hw_breakpoint,
+ remote_remove_hw_breakpoint): Use alloca instead of GCC's dynamic
+ array feature.
+
+Mon Oct 25 18:08:31 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h (REGISTER_GDBARCH_SWAP): Define.
+ * gdbarch.sh: Update.
+
+Sat Oct 23 16:39:34 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.c (initialize_current_architecture): Make ``choice''
+ const.
+
+1999-10-22 Tom Tromey <tromey@cygnus.com>
+
+ * gdbarch.sh: Updated for gdbarch.[ch] changes.
+ * top.c (gdb_init): Call initialize_current_architecture.
+ * gdbarch.h (initialize_current_architecture): Declare.
+ * gdbarch.c (initialize_current_architecture): New function.
+
+1999-10-22 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * stack.c (print_frame_info_base): Check for value of source
+ parameter equal to 2, and print address anyway. Set source to 0
+ later, to avoid printing file & line info again.
+
+1999-10-21 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * utils.c (chars_per_line): fix typo in comment.
+
+1999-10-21 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * breakpoint.h (bp_print_how): New enum, used for deciding how to
+ print bpstat information when we stop, instead of having 3
+ different functions.
+ (struct bpstat): Change print_it field to be an enum instead of a
+ function pointer.
+
+ * breakpoint.c (print_it_typical): New name for print_it_normal().
+ (print_bp_stop_message): New function. High level routine for
+ printing of why we stopped.
+ (bpstat_print): Call print_bp_stop_message instead of using the
+ print_it function pointer.
+ (print_it_done, print_it_noop): Delete these functions.
+
+1999-10-21 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * breakpoint.c (print_it_normal): Reorganize into a switch
+ statement.
+
+1999-10-21 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * Makefile.in (event-top.o): Add dependency on target.h.
+ * event-top.c: Make dependency on target.h explicit.
+
+ * breakpoint.c (bpstat_print): Clean up logic. Remove recursion.
+ (catch_exec_command_1): Surround with appropriate ifdef's,
+ to avoid compiler warnings.
+ (catch_fork_command_1): Ditto.
+
+1999-10-20 Jim Blandy <jimb@cygnus.com>
+
+ * Makefile.in (dwarf2read.o): Note that this depends on bfd/elf-bfd.h.
+ (elf_bfd_h): New variable.
+
+1999-10-19 Jim Blandy <jimb@cygnus.com>
+
+ * config/i386/tm-i386.h (REGISTER_NAMES): Change names of FPU
+ instruction and operand pointer registers to improve consistency,
+ following J. T. Conklin's suggestions.
+
+1999-10-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * stack.c (print_frame_info_base): Add printing of list
+ begin and end.
+
+ * breakpoint.h: Change return type of field print_it of struct
+ bpstats to enumeration print_stop_action.
+ Define new enumeration print_stop_action.
+
+ * breakpoint.c (print_it_normal): Change return type to
+ enumeration type print_stop_action. Handle bp_shlib_event here
+ instead of in normal_stop().
+ (bpstat_print): Change return type to enumeration type
+ print_stop_action.
+ (print_it_done): Ditto.
+ (print_it_noop): Ditto.
+
+ * infrun.c (is_internal_shlib_eventpoint): Delete this function.
+ (stopped_for_internal_shlib_event): Delete.
+ (normal_stop): Move logic to handle bp_shlib_event from here to
+ print_it_normal(). Use switch to handle return value from
+ bpstat_print().
+
+Mon Oct 18 17:32:51 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * symfile.c (generic_load): Rewrite. Make the size of each
+ chunk/block write a run-time option. Check for quit_flag.
+ Use target_write_memory_partial for downloads.
+
+1999-10-18 Jim Blandy <jimb@cygnus.com>
+
+ Change Linux x86 register support to use the new tm-i386.h layout.
+ * config/i386/tm-linux.h (HAVE_I387_REGS): #define this, so we get
+ the full set of FP register definitions from tm-i386.h.
+ (REGISTER_RAW_SIZE, REGISTER_NAMES, REGISTER_BYTES, REGISTER_BYTE,
+ MAX_REGISTER_VIRTUAL_SIZE, MAX_REGISTER_RAW_SIZE, NUM_REGS,
+ NUM_FREGS): Remove #undefs and subsequent redefinitions: we're
+ using the values from tm-i386.h now.
+ (FPSTART_REGNUM, FPCONTROL_REGNUM, FPSTATUS_REGNUM, FPTAG_REGNUM,
+ FPDATA_REGNUM, FPEND_REGNUM, FPENV_BYTES, FPREG_RAW_SIZE,
+ FPREG_BYTES): Deleted.
+ (TARGET_LONG_DOUBLE_BIT): Deleted.
+ (REGISTER_CONVERTIBLE, REGISTER_CONVERT_TO_VIRTUAL,
+ REGISTER_CONVERT_TO_RAW): Redefine these only if LD_I387 is #defined.
+ * i386-linux-nat.c (convert_to_gregset, convert_to_fpregset,
+ FPREGSET_T_FPREG_OFFSET): New functions and macros.
+ (supply_gregset, fill_gregset, supply_fpregset,
+ fill_fpregset, fetch_fpregs, store_fpregs, fetch_regs,
+ store_regs, fetch_inferior_registers, store_inferior_registers):
+ Adjusted to use new macros from tm-i386.h.
+
+ * config/i386/tm-i386.h: Provide a decent x86 FPU description here,
+ so that the various i386 targets can share more FPU handling code.
+ (NUM_GREGS): New macro.
+ (NUM_SSE_REGS): New macro, dependent on HAVE_SSE_REGS
+ (NUM_FREGS): Depend on HAVE_I387_REGS.
+ (NUM_REGS, REGISTER_BYTES): Define in terms of NUM_GREGS,
+ NUM_FREGS, and NUM_SSE_REGS.
+ (MAX_NUM_REGS): New macro.
+ (REGISTER_NAMES): Expand name list with FPU control registers and
+ SSE registers.
+ (FP7_REGNUM, FCTRL_REGNUM, FSTAT_REGNUM, FTAG_REGNUM, FCS_REGNUM,
+ FCOFF_REGNUM, FDS_REGNUM, FDOFF_REGNUM, FOP_REGNUM,
+ FIRST_FPU_CTRL_REGNUM, LAST_FPU_CTRL_REGNUM): New macros, more
+ fully describing the FPU register set.
+ (XMM0_REGNUM, XMM7_REGNUM, MXCSR_REGNUM): New macros, describing
+ the SSE register set.
+ (IS_FP_REGNUM, IS_SSE_REGNUM, FPU_REG_RAW_SIZE, SIZEOF_GREGS,
+ SIZEOF_FPU_REGS, SIZEOF_FPU_CTRL_REGS, SIZEOF_SSE_REGS): New
+ convenience macros.
+ (REGISTER_BYTE, REGISTER_RAW_SIZE, REGISTER_VIRTUAL_SIZE): Turn
+ these into tables, since the register sizes are pretty irregular.
+ (i386_register_byte, i386_register_raw_size,
+ i386_register_virtual_size): New extern declarations.
+ (TARGET_LONG_DOUBLE_BIT): Define.
+ (MAX_REGISTER_RAW_SIZE): Bump to 16, for the SSE registers.
+ (REGISTER_VIRTUAL_TYPE, REGISTER_CONVERTIBLE,
+ REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW): New macros
+ for handling floating-point registers.
+ (i387_to_double, double_to_i387): New extern declarations.
+ * i386-tdep.c (i386_register_byte, i386_register_raw_size,
+ i386_register_virtual_size): New arrays.
+ (_initialize_i386_tdep): Initialize i386_register_byte and
+ i386_register_virtual_size.
+
+ * i386-tdep.c (_initialize_i386_tdep): Move new_cmd to a block
+ created specially for its use.
+
+Mon Oct 18 23:36:58 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * symfile.c (generic_load): Cleanup the validate code - remove
+ #ifdef, use paddr to print address.
+ (validate_download): Static, replace VALIDATE_DOWNLOAD
+
+ * symfile.c (generic_load): Use strtoul to scan the optional load
+ offset. Allocate a filename of the correct size.
+
+Mon Oct 18 17:32:51 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * symfile.c (generic_load): Don't filter output. Use
+ print_transfer_performance for summary. Use paddr for addresses.
+ (print_transfer_performance): New function. Includes write count.
+ (report_transfer_performance): Call
+ print_transfer_performance. Deprecate.
+
+ * defs.h (print_transfer_performance): Add declaration.
+ (generic_load): Move declaration to here.
+ * symfile.h (generic_load): From here.
+
+Mon Oct 18 16:29:52 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * remote.c (remote_write_bytes): Re-write. Transfer a single
+ packet and then return the that packets byte size.
+
+Sun Oct 17 15:09:00 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (remote_console_output): Flush gdb_stdtarg after
+ processing an ``O'' packet.
+ * remote.h (remote_console_output): Strip PARAMS.
+
+Sun Oct 17 15:12:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * target.c (target_xfer_memory_partial): New function. Simple
+ implementation of partial memory reads.
+ (target_read_memory_partial): New function. Replaces old
+ target_read_memory_partial.
+ (target_write_memory_partial): New function.
+ * target.h: Update.
+
+ * valprint.c (partial_memory_read): New function, based on old
+ memory_read_partial. Implement partial memory reads the way that
+ val_print_string likes.
+ (val_print_string): Use partial_memory_read.
+
+Sun Oct 17 13:58:56 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (ui_load_progress_hook): Add declaration.
+ * dsrec.c (ui_load_progress_hook): Delete extern declaration.
+
+ * symfile.c (ui_load_progress_hook): Make first argument const.
+ (generic_load): Don't cast the result of bfd_get_section_name.
+ Replace ``sect'' with ``sect_name'', use consistently.
+
+1999-10-15 Jim Blandy <jimb@cygnus.com>
+
+ Add beginnings of support for SIMD register types.
+ * gdbtypes.c (init_simd_type): New function for building
+ types for registers consisting of arrays of objects.
+ (builtin_type_v4sf): New built-in type.
+ (build_gdbtypes): Initialize it.
+ (_initialize_gdbtypes): Arrange for gdbarch swapping.
+ * gdbtypes.h (builtin_type_v4sf): Add external decl.
+
+Fri Oct 15 18:20:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-hms.c: Commented out H8 code.
+
+Fri Oct 15 17:46:39 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * dcache.c (dcache_p): Rename variable remote_dcache. Make
+ static.
+ (_initialize_dcache): Fix description of ``set remotecache''.
+ Cache is OFF by default.
+
+1999-10-13 Jim Blandy <jimb@cygnus.com>
+
+ * valops.c (value_push): Don't forget to initialize container_len.
+
+Wed Oct 13 17:58:20 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * utils.c (tui_file_flush): Don't call flush_hook. Don't try to
+ flush ``astring''.
+ * gdb-events.sh: Update
+ * top.c (flush_hook): Delete.
+
+1999-10-13 Kevin Buettner <kevinb@cygnus.com>
+
+ * mem-break.c (memory_insert_breakpoint,
+ memory_remove_breakpoint): Added missing return statements.
+
+Wed Oct 13 20:53:42 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * utils.c (mem_fileopen, mem_file_delete, mem_file_new,
+ mem_file_rewind, mem_file_put, mem_file_fputs): New functions.
+ * defs.h (mem_fileopen): Declare.
+
+1999-10-13 Kevin Buettner <kevinb@cygnus.com>
+
+ * mem-break.c (default_memory_insert_breakpoint): Renamed from
+ memory_insert_breakpoint.
+ (default_memory_remove_breakpoint): Renamed from
+ memory_remove_breakpoint.
+ (memory_insert_breakpoint, memory_remove_breakpoint,
+ MEMORY_INSERT_BREAKPOINT, MEMORY_REMOVE_BREAKPOINT): New
+ wrappers.
+ * target.h (default_memory_remove_breakpoint,
+ default_memory_insert_breakpoint): Added declarations.
+ * gdbarch.sh (MEMORY_INSERT_BREAKPOINT, MEMORY_REMOVE_BREAKPOINT):
+ New methods.
+ * gdbarch.h, gdbarch.c (MEMORY_INSERT_BREAKPOINT,
+ MEMORY_REMOVE_BREAKPOINT, gdbarch_memory_insert_breakpoint,
+ gdbarch_memory_remove_breakpoint, set_gdbarch_memory_insert_breakpoint,
+ set_gdbarch_memory_remove_breakpoint) : Generated from gdbarch.sh.
+
+Wed Oct 13 19:15:51 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h: Remove PARAMS from all declarations. Re-indent. Clean
+ up the gdb_file declarations.
+
+Tue Oct 12 12:19:07 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * i386-linux-nat.c (supply_fpregset, fill_fpregset): copy
+ from/to start of fpregsetp not start of st_space as the first
+ stuff we copy is the FP control registers not the actual FP values.
+
+1999-10-12 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * eval.c (evaluate_subexp_standard): Fix gdb invocation of
+ inferior C functions when debugging C++ code.
+ * valops.c (find_overload_match): Ditto.
+ * symtab.c (make_symbol_overload_list): Ditto.
+
+1999-10-11 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * config/pa/tm-hppa.h (SYMBOLS_CAN_START_WITH_DOLLAR): It's not
+ enough to #define this; you have to give it a non-zero value.
+
+1999-10-11 Jim Blandy <jimb@cygnus.com>
+
+ Fix from Jim Kingdon <kingdon@redhat.com>, with tweaks to make it
+ gdbarch- and bigendian-friendly:
+ * valops.c (PARM_BOUNDARY): If not #defined, default to zero.
+ (value_push): If PARM_BOUNDARY is not zero, align arguments to
+ that boundary.
+ * config/i386/tm-i386.h: Define PARM_BOUNDARY.
+
+Mon Oct 11 14:23:55 1999 Fred Fish <fnf@cygnus.com>
+
+ * config/mips/tm-irix3.h (PS_REGNUM): Don't undef if we aren't
+ going to redefine it to something else.
+
+1999-10-11 Jason Merrill <jason@yorick.cygnus.com>
+
+ * dwarfread.c (read_func_scope): Don't try to set main_func_*;
+ we handle that in blockframe.c:inside_main_func.
+ * dwarf2read.c (read_func_scope): Likewise.
+ (dwarf2_add_field, dwarf2_add_member_fn): Get member function name
+ directly, not from mangled name.
+ (skip_member_fn_name): Lose.
+
+Mon Oct 11 12:24:52 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * serial.h (enum serial_rc): Clarify SERIAL_TIMEOUT and
+ restrictions on TIMEOUT in ASYNC mode.
+
+ * serial.c (serial_readchar): Check for invalid timeout when in
+ async mode. Disable test.
+
+Thu Oct 7 17:20:01 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * monitor.c (monitor_printable_string): Add length argument. Don't
+ return final string length.
+ (monitor_printf_noecho, monitor_printf, monitor_expect): Update.
+ (monitor_error): Pass real_len to monitor_printable_string.
+ (monitor_error): Rewrite. Replace printf fmt string parameter with
+ function name and message parameters.
+ (monitor_read_memory_single, monitor_read_memory): Update.
+
+1999-10-07 Stan Shebs <shebs@andros.cygnus.com>
+
+ * main.c (print_gdb_help): Fix bug reporting address.
+ * gnu-regex.h, gnu-regex.c: Ditto.
+
+1999-10-07 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * parse.c (SYMBOLS_CAN_START_WITH_DOLLAR): New macro,
+ whose value can be overridden by target files.
+ (write_dollar_variable): Don't check the symbol table for
+ identifiers beginning with `$' unless
+ SYMBOLS_CAN_START_WITH_DOLLAR is non-zero.
+ * config/pa/tm-hppa.h (SYMBOLS_CAN_START_WITH_DOLLAR): Define.
+ * doc/gdbint.texinfo (SYMBOLS_CAN_START_WITH_DOLLAR): Document.
+
+ Remove all traces of the BINOP_SCOPE operator. It's never
+ generated, and not implemented.
+ * expression.h (enum exp_opcode): Delete BINOP_SCOPE.
+ * c-lang.c (c_op_print_tab): Delete entry for BINOP_SCOPE.
+ * eval.c (evaluate_subexp_standard): Doc fix.
+ * expprint.c (op_name): Remove case for BINOP_SCOPE.
+ (dump_subexp): Same.
+
+ * dwarf2read.c (dwarf2_const_value): Treat DW_FORM_data1,
+ DW_FORM_data2, DW_FORM_data4, and DW_FORM_data8 as signed values,
+ since that's what read_var_value will do anyway.
+
+1999-10-07 Fred Fish <fnf@cygnus.com>
+
+ * objfiles.h (struct objfile): Delete is_solib member, now handled
+ by OBJF_SHARED bit in struct objfile's flags.
+ * objfiles.c (objfile_purge_solibs): Check OBJF_SHARED bit in flags
+ instead of old is_solib int member in objfile struct.
+
+ * objfiles.c (allocate_objfile): Remove is_solib arg. Now passed
+ as a bit in combined flags arg.
+ * symfile.c (symbol_file_add): Ditto.
+ * objfiles.h (allocate_objfile): Adjust prototype after removal
+ of is_solib arg.
+ * symtab.h (symbol_file_add): Ditto.
+
+ * cxux-nat.c (add_shared_symbol_files): Remove zero passed to
+ symbol_file_add in old is_solib arg, defaults to zero now in
+ flags.
+ * irix5-nat.c (symbol_add_stub): Ditto.
+ * remote-mm.c (mm_load): Ditto.
+ * remote-udi.c (udi_load): Ditto.
+ * remote-vx.c (vx_add_symbols): Ditto.
+ * symfile.c (symbol_file_command): Ditto.
+ (add_symbol_file_command): Ditto.
+
+ * coff-solib.c (coff_solib_add): Call symbol_file_add with
+ OBJF_SHARED in flags bit, rather than 1 in old is_solib
+ arg.
+ * osfsolib.c (symbol_add_stub): Ditto.
+ * pa64solib.c (pa64_solib_add_solib_objfile): Ditto.
+ * solib.c (symbol_add_stub): Ditto.
+ * somsolib.c (som_solib_add_solib_objfile): Ditto.
+ * win32-nat.c (handle_load_dll): Ditto.
+
+ * objfiles.c (allocate_objfile): Remove old args "mapped" and
+ "user_loaded". Replaced with new arg "flags" containing specific
+ If global var mapped_symbol_files is nonzero
+ then set OBJF_MAPPED in flags arg. Check for OBJF_MAPPED bit in
+ flags where we used to check mapped arg.
+ Pass flags to open_mapped_file instead of mapped arg.
+ Ensure that OBJF_MAPPED bit is reset in flags when the objfile
+ is not mapped. Add passed flags bits to objfile's flags bits.
+ (open_mapped_file): Replace "mapped" arg with new "flags" arg.
+ Adjust prototype. Pass flags to open_existing_mapped_file.
+ (open_existing_mapped_file): Replace "mapped" arg with new "flags".
+ Check flags for OBJF_MAPPED.
+ * objfiles.h (allocate_objfile): Adjust prototype.
+ * rs6000-nat.c (add_vmap): Pass zero for combined flags, rather
+ than separate zero ints for old "mapped" and "user_loaded" flags.
+ * symfile.c (symbol_file_add): Pass allocate_objfile combined flags
+ rather than individual mapped and user loaded bits.
+
+ * symfile.c (symbol_file_add): Delete user_loaded arg.
+ * symtab.h (symbol_file_add): Adjust prototype for deleted
+ user_loaded arg.
+ * objfiles.h (struct objfile): Delete user_loaded member.
+ (OBJF_USERLOADED): New flag bit to replace user_loaded.
+
+ * symfile.c (symbol_file_command): Add OBJF_USER_LOADED to flags
+ passed to symbol_file_add. Delete previous passing of explicit 1
+ for user_loaded.
+ (add_symbol_file_command): Ditto.
+
+ * coff-solib.c (coff_solib_add): No longer pass zero for user loaded,
+ now defaults to zero in flags.
+ * cxux-nat.c (add_shared_symbol_files): Ditto.
+ * irix5-nat.c (symbol_add_stub): Ditto.
+ * osfsolib.c (symbol_add_stub): Ditto.
+ * remote-mm.c (mm_load): Ditto.
+ * pa64solib.c (pa64_solib_add_solib_objfile): Ditto.
+ * remote-udi.c (udi_load): Ditto.
+ * remote-vx.c (vx_add_symbols): Ditto.
+ * solib.c (symbol_add_stub): Ditto.
+ * somsolib.c (som_solib_add_solib_objfile): Ditto.
+ * win32-nat.c (handle_load_dll): Ditto.
+
+Thu Oct 7 19:24:05 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (monitor.o): Allow monitor.o to be compiled with
+ -Werror.
+
+ * monitor.c (monitor_debug_p): New variable. Replaces macro.
+ (EXTRA_RDEBUG): Delete. Update all uses.
+ (monitor_debug): New function. Replaces macro.
+ (RDEBUG): Delete macro. Update all uses.
+ debug output to gdb_stdlog and not the console.
+
+ * monitor.c: Fix printf formating. Replace printf calls with
+ fprintf_unfiltered.
+
+1999-10-06 Stan Shebs <shebs@andros.cygnus.com>
+
+ * MAINTAINERS: Switch ARM target maintenance from Elena
+ Zannoni to Jim Ingham.
+
+1999-10-06 Frank Ch. Eigler <fche@cygnus.com>
+
+ * remote.c (hexnumnstr): New function. Allow setting of width.
+ (hexnumstr): Call the above.
+ (remote_write_bytes): Fill in X-protocol address field more
+ reliably.
+
+1999-10-06 Fred Fish <fnf@cygnus.com>
+
+ * xcoffread.c (xcoff_symfile_offsets): Fix typo, addr->addrs.
+
+1999-10-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * remote.c (handle_remote_sigint_twice): Make this signal be
+ handled by inferior_event_handler, via the wrapper function.
+ (async_remote_interrupt_twice): Make not static. Add debug print.
+ * remote.h (async_remote_interrupt_twice): Export for use in
+ inf-loop.c.
+
+ * inf-loop.c (inferior_event_handler_wrapper): New function.
+ (inferior_event_handler): Handle a request to quit and kill the
+ target.
+ Include remote.h.
+ * inf-loop.h (inferior_event_handler_wrapper): Export.
+
+1999-10-04 James Ingham <jingham@leda.cygnus.com>
+
+ * remote-rdi.c (arm_rdi_open): If the angel_RDI_Open fails, close
+ the serial port and raise an error. If you try to go on, you will
+ stall forever down in the rdi-share code.
+
+1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * printcmd.c (output_command): Makes sure result from the output
+ command is printed before the next prompt.
+
+1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * printcmd.c (print_formatted): Add missing stream parameter.
+ (do_examine, print_command_1, output_command, do_one_display):
+ Adjust call to print_formatted().
+
+1999-10-04 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * infcmd.c: Remove include of event-loop.h.
+ * utils.c: Ditto.
+ * top.c: Ditto.
+
+ * infrun.c (fetch_inferior_event): Call inferior_event_handler
+ when inferior stops, instead of doing work ourselves.
+ (fetch_inferior_event): Use void* instead of gdb_client_data.
+ Remove includes of event-top.h and event-loop.h. Add include of
+ inf-loop.h.
+ (complete_execution): Move from here.
+
+ * inf-loop.c (complete_execution): To here.
+ (inferior_event_handler): Handle inferior's execution completion
+ case as well.
+ * inf-loop.h: Add def of INF_LOOP_H.
+
+ * event-top.h: Don't use gdb_client_data, use void*, to avoid
+ dependency on event-loop.h.
+
+ * remote.c (remote_async_resume): Set target_executing only after we
+ actually register the inferior with the event loop.
+
+1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * corefile.c (memory_error): Use error_stream() and eliminate call
+ to return_to_top_level().
+
+1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * utils.c (error): Save error message text (w/o new line).
+ (error_last_message): New function. Returns the last message
+ issued by gdb.
+ (error_init): New function. Initializes error handling machinery.
+ (error_stream): New function. Allows the error message to be
+ passed on a stream buffer.
+ * defs.h: Add prototypes for error_stream() and
+ error_last_message().
+ * main.c (main): Add call to error_init().
+
+1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (varobj_get_type): Call tui_sfileopen() instead of
+ deprecated gdb_file_init_astream().
+ (c_value_of_variable): Ditto.
+ * ui-out.c (ui_out_stream_new): Ditto.
+
+1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * utils.c (tui_sfileopen): New function. Replaces
+ gdb_file_init_astring().
+ * defs.h: Add prototype for the above.
+
+Mon Oct 4 19:25:55 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * symfile.c (add_symbol_file_command): Fix -Wformat on query call.
+
+1999-10-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * target.c (cleanup_target): Type of to_async param is now
+ function with enum inferior_event_type param.
+
+ * target.h (target_ops): Adjust to_async accordingly. Move enum
+ inferior_event_type to this file. Don't have a typedef for
+ inferior_event_type. Add more enumeration constants INF_QUIT_REQ,
+ INF_EXEC_COMPLETE. Remove INF_SIGINT_FIRST, INF_SIGINT_SECOND.
+
+ * inf-loop.c (inferior_event_handler): Change first param to tell
+ the type of event we are dealing with. Deal with INF_ERROR and
+ INF_REG_EVENT, for the moment.
+ Include target.h.
+
+ * inf-loop.h (inferior_event_handler): Adjust prototype. Remove
+ enum inferior_event_type from here.
+
+ * remote.c (remote_async_serial_handler): Pass INF_REG_EVENT to
+ the client callback.
+ (remote_async): Change callback's param type to inferior_event_type.
+ (async_client_callback): Change type as above.
+
+1999-10-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-top.c (stdin_event_handler): Delete fd parameter, use
+ input_fd instead.
+ * event-top.h (stdin_event_handler): Delete fd parameter.
+
+ * inf-loop.c (inferior_event_handler): Delete fd parameter. Use
+ target_async() to unregister the inferior fd in case of errors.
+ * inf-loop.h(inferior_event_handler): Delete fd parameter.
+
+ * ser-unix.c (fd_event): Delete fd parameter. Use scb->fd,
+ instead.
+
+ * remote.c (async_client_callback): Delete fd parameter.
+ (remote_async_serial_handler): Ditto.
+ (remote_async): Adjust to new type of callback function.
+
+ * target.c (cleanup_target): Adjust parameters for to_async
+ default case.
+ * target.h (*to_async): Delete fd parameter from cb function.
+
+ * event-loop.h (handler_func): Delete fd parameter.
+ * event-loop.c (handle_file_event): Delete fd param from call to
+ proc. Do not include inferior.h.
+
+1999-10-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-loop.c (inferior_event_handler,
+ inferior_event_handler_wrapper): Move from here.
+ * inf-loop.c: To here. New file.
+
+ * event-loop.h (inferior_event_handler): Move from here.
+ * inf-loop.h: To here. New file.
+
+ * remote.c: Include inf-loop.h.
+ (set_extende_protocol): Remove unused prototpye.
+
+ * Makefile.in (SFILES): Add inf-loop.c.
+ (inf_loop_h): Define.
+ (COMMON_OBS): Add inf-loop.o.
+ (inf-loop.o): Add rule.
+ (remote.o): Add dependency on inf-loop.h.
+
+Fri Oct 1 19:59:31 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ser-unix.c: Add some notes on how the async code works.
+
+Fri Oct 1 01:45:32 1999 Jeffrey A Law (law@cygnus.com)
+
+ * somread.c (som_symfile_offsets): Fix typo in last change.
+
+1999-09-30 Fred Fish <fnf@cygnus.com>
+
+ * coff-solib.c (coff_solib_add): Adjust call to symbol_file_add.
+ * cxux-nat.c (add_shared_symbol_files): Ditto.
+ * irix5-nat.c (symbol_add_stub): Ditto.
+ * osfsolib.c (symbol_add_stub): Ditto.
+ * pa64solib.c (pa64_solib_add_solib_objfile): Ditto.
+ * remote-mm.c (mm_load): Ditto.
+ * remote-udi.c (udi_load): Ditto.
+ * remote-vx.c (vx_add_symbols): Ditto.
+ * solib.c (symbol_add_stub): Ditto.
+ * somsolib.c (som_solib_add_solib_objfile): Ditto.
+ * win32-nat.c (handle_load_dll): Ditto.
+
+ * irix5-nat.c (symbol_add_stub): Add section_addrs, zero it.
+ * cxux-nat.c (add_shared_symbol_files): Ditto.
+ * osfsolib.c (symbol_add_stub): Ditto.
+ * pa64solib.c (pa64_solib_add_solib_objfile): Ditto.
+ * solib.c (symbol_add_stub): Ditto.
+ * somsolib.c (som_solib_add_solib_objfile): Ditto.
+ * symfile.c (symbol_file_command): Ditto.
+ * win32-nat.c (handle_load_dll): Ditto.
+
+ * irix5-nat.c (symbol_add_stub): Use section_addrs to pass text addr.
+ * cxux-nat.c (add_shared_symbol_files): Ditto.
+ * osfsolib.c (symbol_add_stub): Ditto.
+ * pa64solib.c (pa64_solib_add_solib_objfile): Ditto.
+ * solib.c (symbol_add_stub): Ditto.
+ * somsolib.c (som_solib_add_solib_objfile): Ditto.
+ * symfile.c (symbol_file_command): Ditto.
+ * win32-nat.c (handle_load_dll): Ditto.
+
+ * coff-solib.c (coff_solib_add): Call symbol_file_add with NULL ptr.
+ * cxux-nat.c (add_shared_symbol_files): Ditto.
+ * remote-udi.c (udi_load): Ditto.
+ * remote-vx.c (vx_add_symbols): Ditto.
+ * symfile.c (symbol_file_command): Ditto.
+
+ * dstread.c (dst_symfile_offsets): Take "section_addr_info *"
+ instead of CORE_ADDR.
+ * somread.c (som_symfile_offsets): Ditto.
+ * symfile.c (default_symfile_offsets): Ditto.
+ * xcoffread.c (xcoff_symfile_offsets): Ditto.
+
+ * symfile.h (default_symfile_offsets): Adjust prototype.
+ (syms_from_objfile): Ditto.
+ * symtab.h (symbol_file_add): Ditto.
+
+ * rs6000-nat.c (objfile_symbol_add): Call syms_from_objfile with NULL.
+ * xcoffsolib.c (solib_add): Ditto.
+ * gdb-stabs.h (SECT_OFF_MAX): Increase from 4 to 16.
+ * symtab.h (MAX_SECTIONS): Define.
+ (struct section_addr_info): New struct for better control over
+ changing load addresses of sections.
+ * objfiles.h (OBJF_READNOW): Add new flag bit.
+ * symfile.h (sym_offsets): Change second param from CORE_ADDR to
+ "section_addr_info *".
+
+ * symfile.c (symbol_file_add): Replace scalar arg "CORE_ADDR addr"
+ with "struct section_addr_info *addrs".
+ (syms_from_objfile): Ditto.
+ (add_symbol_file_command): Remove local variables "readnow" and
+ "mapped". Replaced with general "flags" variable.
+ (symbol_file_command): Ditto.
+ (add_symbol_file_command): Add local variables i, sec_num, argcnt,
+ expecting_option, option_index, and opt. Rework option parsing code
+ to handle additional options.
+ (_initialize_symfile): Adjust add-symbol-file usage to match new
+ option handling.
+ (symbol_file_add): Remove parameters "mapped" and "readnow",
+ replace with general "flags".
+ (symbol_file_add): In call to allocate_objfile, replace "mapped"
+ with extracted OBJF_MAPPED bit from flags.
+ (symbol_file_add): Use OBJF_READNOW bit from flags, instead of
+ "readnow" variable.
+ (symbol_file_command): Set OBJF_MAPPED and OBJF_READNOW bits
+ from parsed options. Pass flags to symbol_file_add.
+ (add_symbol_file_command): Ditto.
+ (syms_from_objfile): Add local variables i, sect, lower_sect,
+ lower_offset, and local_addr. Substitute local_addr for addrs
+ when addrs is NULL. Find lowest loadable section to be used as
+ starting point for contiguous sections. Adjust offsets if segments
+ are not contiguous. Call sym_offsets with section_addr_info
+ instead of single addr.
+ (default_symfile_offsets): Initialize objfile's section_offsets
+ with user specified offsets.
+ (symbol_file_add): Call syms_from_objfile with offsets.
+ (unknown_option_complaint): Add.
+ (add_symbol_file_command): Add "section_addrs", zero it with memset.
+
+1999-09-30 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Call config.sub explicitly instead of misusing the
+ autoconf internal variable $ac_config_sub.
+ * configure: Regenerated.
+
+Thu Sep 30 15:53:59 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (readchar): When EOF mourn the inferior.
+ (getpkt): Try QUIT. Might not be a watchdog timer timeout.
+ (remote_async_serial_handler): Pass ``-1'' as the dummy FD. Safer
+ than ZERO == STDIN.
+
+ * serial.h (enum serial_rc): Replace #define SERIAL_ERROR,
+ SERIAL_TIMEOUT and SERIAL_EOF.
+ (struct _serial_t): Add more notes on termios specific fields.
+
+ * ser-unix.c (generic_readchar): Make SERIAL_ERROR sticky.
+ (do_hardwire_readchar, do_unix_readchar): Don't use bufcnt as a
+ tempoary for the return-value from read.
+
+ * serial.c (serial_logchar): Add a stream parameter.
+ (serial_readchar, serial_write, serial_send_break): Update.
+ (serial_readchar): Add serial debug trace.
+
+Thu Sep 30 12:07:03 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * serial.h (struct _serial_t): Add field async_state. Better
+ document field bufcnt.
+ (SERIAL_ERROR): Delete comment about errno.
+ * serial.c (serial_open, serial_fdopen): Initialize async_state.
+
+ * ser-unix.c (push_event, fd_event, reschedule): New functions.
+ Handle ASYNC serial input.
+ (ser_unix_async): Update.
+ (generic_readchar): New function. Handle event scheduling. Make
+ EOF condition sticky.
+ (do_unix_readchar): Rename ser_unix_readchar.
+ (ser_unix_readchar): New function, call do_unix_readchar via
+ generic_readchar.
+ (do_hardwire_readchar, hardwire_readchar): Ditto.
+
+ * ser-unix.c (ser_unix_readchar): Delete code working around ASYNC
+ fifo bugs.
+ (hardwire_readchar): Delete code working around ASYNC fifo bugs.
+
+Wed Sep 29 21:27:16 1999 Jeffrey A Law (law@cygnus.com)
+
+ * breakpoint.c (insert_breakpoints): Addresses are CORE_ADDRs,
+ not "int"s.
+ (remove_breakpoint): Likewise.
+
+1999-09-29 Fred Fish <fnf@cygnus.com>
+
+ * breakpoint.c (breakpoint_1): Replace cast "(CORE_ADDR) - 1"
+ with the more obviously intended expression "(CORE_ADDR) -1".
+ * dwarf2read.c (scan_partial_symbols, read_file_scope): Ditto.
+ * gnu-nat.c (gnu_create_inferior): Ditto.
+ * go32-nat.c (go32_create_inferior): Ditto.
+ * hppa-tdep.c (hppa_pop_frame): Ditto.
+ * infcmd.c (continue_command, step_1, signal_command): Ditto.
+ (until_next_command, finish_command): Ditto.
+ * infrun.c (proceed): Ditto.
+ * inftarg.c (child_create_inferior): Ditto.
+ * m3-nat.c (m3_create_inferior): Ditto.
+ * mac-nat.c (child_create_inferior): Ditto.
+ * procfs.c (procfs_create_inferior): Ditto.
+ * remote-sim.c (gdbsim_create_inferior): Ditto.
+ * target.c (target_link): Ditto.
+ * win32-nat.c (child_create_inferior): Ditto.
+ * varobj.c (varobj_create, new_root_variable): Ditto.
+
+Thu Sep 30 10:36:19 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ser-unix.c (ser_unix_flush_input): New function. Discard input
+ buffer.
+ (hardwire_flush_input): Use ser_unix_flush_input.
+ (ser_unix_nop_flush_input): Delete.
+ * ser-unix.h (ser_unix_flush_input): Update.
+ ser-tcp.c (_initialize_ser_tcp), ser-pipe.c
+ (_initialize_ser_pipe): Update.
+
+ * ser-unix.c (hardwire_write): Delete.
+ (_initialize_ser_hardwire): Update, use ser_unix_write.
+
+Thu Sep 30 10:16:50 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ser-pipe.c (pipe_open): Don't make the FD non-blocking. Already
+ being handled in ser_unix_wait_for by a select.
+
+Thu Sep 30 10:00:32 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * serial.h (struct _serial_t): Add field debug_p.
+ (SERIAL_DEBUG, SERIAL_DEBUG_P): Define.
+
+ * serial.c (serial_open, serial_fdopen): Initialize debug_p.
+ (serial_debug, serial_debug_p): New functions.
+ (global_serial_debug_p): New variable.
+ (_initialize_serial): Add ``set serialdebug'' command.
+
+Thu Sep 30 09:09:38 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * serial.h (serial_event_ftype): Replace FD and ERROR args with
+ SERRIAL_T arg.
+ * ser-unix.c (ser_unix_event): Update.
+
+ * remote.c (remote_async_serial_handler): New function. Handle
+ serial events.
+ (remote_async): Pass remote_async_serial_handler to SERIAL.
+ (async_client_callback, async_client_context): New variables.
+
+ * remote.c (extended_remote_async_create_inferior): Use
+ target_async to register the inferior event handler.
+
+Thu Sep 30 00:02:03 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (AC_CHECK_FUNCS): Test for sigprocmask.
+ * configure, config.in: Re-generate.
+ * event-top.c (async_stop_sig): Use sigprocmask when available.
+
+1999-09-29 Doug Evans <devans@casey.cygnus.com>
+
+ * sh-stub.c (handle_exception): Fix typo in patch of 1999-08-26.
+ * m68k-stub.c (handle_exception): Ditto.
+
+1999-09-28 Fred Fish <fnf@cygnus.com>
+
+ * alpha-nat.c (alpha_osf_core_fns, alpha_elf_core_fns):
+ Add default entries for check_format and core_sniffer.
+ * core-aout.c (aout_core_fns): Ditto.
+ * core-regset.c (regset_core_fns): Ditto.
+ * core-sol2.c (solaris_core_fns): Ditto.
+ * i386aix-nat.c (i386aix_core_fns): Ditto.
+ * i386mach-nat.c (i386mach_core_fns): Ditto.
+ * irix4-nat.c (irix4_core_fns): Ditto.
+ * irix5-nat.c (irix5_core_fns): Ditto.
+ * lynx-nat.c (lynx_core_fns): Ditto.
+ * mips-nat.c (mips_core_fns): Ditto.
+ * ns32knbsd-nat.c (nat_core_fns): Ditto.
+ * rs6000-nat.c (rs6000_core_fns): Ditto.
+ * sparc-nat.c (sparc_core_fns): Ditto.
+ * sun-nat.c (sun3_core_fns): Ditto.
+ * ultra3-nat.c (ultra3_core_fns): Ditto.
+
+ * corelow.c (core_vec): New, for selected core file handler.
+ (sniff_core_bfd): New function.
+ (gdb_check_format): New function.
+ (default_check_format): New function.
+ (default_core_sniffer): New function.
+ (sniff_core_bfd): New function.
+ (core_close): Reset core_vec to NULL.
+ (core_open): Fall back to gdb_check_format if bfd_check_format
+ does not identify the file format. Call sniff_core_bfd to pick
+ a core file handler.
+ (get_core_registers): Remove code that is now in sniff_core_bfd.
+ Use current core_vec.
+
+ * gdbcore.h (check_format): New core_fns function, points to function
+ to try and identify a core file format.
+ (core_sniffer): New core_fns function, points to function to select
+ a specific handler for the selected core file format.
+ (default_core_sniffer): Add prototype.
+ (default_check_format): Add prototype.
+
+ * i960-tdep.c (inferior.h): Include.
+ * mips-tdep.c (read_next_frame_reg): Use ADDR_BITS_REMOVE
+ on addresses pulled from stack.
+
+1999-09-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-loop.c (poll_timers): Check whether the timer list has any
+ element on it by looking at the first element pointer, instead of
+ num_timers.
+
+Wed Sep 29 18:02:31 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * command.c: Attempt to include POSIX <sys/wait.h> before
+ <wait.h>.
+
+ * ser-unix.c (hardwire_print_tty_state): Ditto.
+ * inflow.c (child_terminal_info): Fix printf args.
+
+1999-09-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * remote.c (remote_async_resume): Register the inferior with the
+ event loop.
+ (remote_async_open_1): Don't put the target in async mode here,
+ just do it when executing.
+
+ * infrun.c (complete_execution): Unregister the inferior from the
+ event loop.
+
+ * event-top.c (async_disable_stdin): Don't add
+ async_enable_stdin() to the exec_cleanups chain.
+
+Tue Sep 28 11:08:34 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppa-tdep.c (hppa_fix_call_dummy): Ignore IMPORT_SHLIB stubs
+ except for hpux11 native. Break out of the loop to find a
+ stub as soon as we find an IMPORT stub.
+ (skip_prologue_hard_way): Also recognize copy %ret1,target and
+ all PA64 argument stores as prologue instructions.
+
+1999-09-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * breakpoint.c, defs.h, event-top.c, infcmd.c, infrun.c, main.c,
+ remote.c, top.c, tracepoint.c, utils.c (async_p): Change var name
+ to event_loop_p.
+
+1999-09-28 Jim Blandy <jimb@cygnus.com>
+
+ * hppa-tdep.c (skip_prologue_hard_way): Recognize ldo insns
+ which generate pointers into the argument list.
+
+Tue Sep 28 13:56:49 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.h (cleanup_sigint_signal_handler,
+ initialize_sigint_signal_handler): Delete extern declarations.
+ * event-top.c, infrun.c: No longer need to include "remote.h".
+ * remote.c (cleanup_sigint_signal_handler,
+ initialize_sigint_signal_handler): Make static.
+ * Makefile.in (event-top.o): Delete dependency on "remote.h".
+
+ * remote.c (remote_async_terminal_ours_p): New static global. Keep
+ track of who currently owns the terminal.
+ (remote_async_open_1): Initialize.
+ (remote_async_terminal_inferior): Test
+ remote_async_terminal_ours_p. Claim CNTRL-C handler as part of
+ transfering the terminal to the target.
+ (remote_async_terminal_ours): Similar.
+
+Mon Sep 27 12:33:45 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (async_interrupt_query): Delete function. Merged into
+ interrupt_query. Async cases handled by target_terminal_ours,
+ target_terminal_inferior and SERIAL_CLOSE.
+ (async_remote_interrupt_twice): Update.
+ (remote_async_terminal_ours, remote_async_terminal_inferior): New
+ functions. Steal STDIN from GDB's CLI.
+ (init_remote_async_ops): Initialize to_terminal_ours and
+ to_terminal_inferior.
+
+ * event-top.c (async_disable_stdin, async_disable_stdin): Use
+ target_terminal_ours / target_terminal_inferior to transfer
+ ownership of the terminal between GDB and the target.
+
+1999-09-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * infcmd.c (run_command): Call async_disable_stdin() only if
+ dealing with an asynchronous target.
+
+Mon Sep 27 11:48:38 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * target.h (struct target_ops): Add to_can_async_p, to_is_async_p,
+ to_async. Delete to_has_async. These correspond well with
+ SERIAL* async methods.
+ (target_can_async_p, target_is_async_p, target_async): Define.
+ * target.c (update_current_target, cleanup_target): Update.
+
+ * remote.c (remote_async_open_1): Change target to async using
+ target_async.
+ (remote_can_async_p, remote_is_async_p, remote_async): New
+ functions.
+ (remote_async_wait, remote_async_open_1): Add FIXME about how
+ wait_forever_enabled_p can almost be deleted once the client can
+ enable/disable target_async.
+
+ * breakpoint.c (until_break_command), infrun.c (proceed), infcmd.c
+ (run_command, continue_command, step_1, jump_command,
+ until_command, finish_command, interrupt_target_command), top.c
+ (return_to_top_level, execute_command), event-top.c
+ (command_handler): Replace target_has_async with
+ target_can_async_p.
+
+Sun Sep 26 02:10:47 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (remote_async_open_1): If we go into async mode, never
+ wait for ever.
+
+ * infcmd.c: Include "event-top.h".
+ (run_command, continue_command, jump_command, until_command,
+ finish_command): Use async_disable_stdin to disable the console
+ for synchronous commands.
+
+ * remote.c (async_interrupt_query): Only disconnect the console
+ from the terminal when sync_execution.
+
+ * remote.c (initialize_sigint_signal_handler): Move declaration
+ from here.
+ * remote.h: To here. Make non-static.
+
+ * remote.c (remote_async_resume, async_interrupt_query): Move
+ prompt code from here.
+ * event-top.c (async_disable_stdin, async_enable_stdin): To
+ here. New function.
+
+ * infrun.c (start_remote): Delete commented out code.
+
+Fri Sep 24 12:38:31 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (remote_async_open_1): Perform the initial async_open
+ using only synchronous calls. Only after the target is fully
+ connected, switch to async mode. Include FIXME about now it
+ currently works VS how it should be working.
+ (remote_async_open_1, set_extended_protocol): Delete function
+ set_extended_protocol. All open communication is now done
+ synchronously.
+ (forever_enabled_p): New variable. Determine if remote_async_wait
+ should block FOREVER when fetching target information.
+ (remote_cisco_open, remote_open_1): Set forever_enabled_p.
+
+ * infrun.c (start_remote): During the initial connect, always use
+ a synchronous wait.
+
+Sat Sep 25 18:13:38 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (event-top.o): Add dependency.
+ * event-top.c: Include "remote.h".
+ * remote.c (async_interrupt_query), event-top.c:
+ (async_enable_stdin): Pass dummy parameter to
+ cleanup_sigint_signal_handler.
+ * remote.c (cleanup_sigint_signal_handler), remote.h
+ (cleanup_sigint_signal_handler), event-top.c (async_enable_stdin),
+ event-top.h (async_enable_stdin): Change signature to match
+ make_exec_error_cleanup handler pararameter.
+
+Thu Sep 23 20:48:22 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (enum command_class): Move from here.
+ * command.h (command_class): To here.
+
+1999-09-24 Kevin Buettner <kevinb@cygnus.com>
+ * breakpoint.c (bpstat_stop_status): Use not_a_breakpoint to
+ help properly set bp_addr.
+ * infrun.c (handle_inferior_event): Simplify calls to
+ bp_stop_status.
+
+1999-09-24 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * top.c (return_to_top_level): Do exec_error cleanups if are
+ interrupting a simulated synchronous execution command.
+
+ * infrun.c (start_remote): Create a cleanup to enable stdin in
+ case of error from this command.
+ (complete_execution): Do the enabling of stdin via the exec_error
+ cleanups, when needed.
+
+ * remote.c (remote_async_resume): Make sure we re-enable stdin in
+ case of error from the target.
+ (handle_remote_sigint_twice): The handler to be set is
+ async_remote_interrupt_twice, not async_remote_interrupt.
+ (async_remote_interrupt_twice): Don't do anything if the target
+ has been killed already. Call async_interrupt_query, instead of
+ interrupt_query.
+ (async_interrupt_query): New function. Async case of
+ interrupt_query().
+
+ * event-top.c (async_enable_stdin): New function. Reinstate stdin
+ with the event loop.
+ * event-top.h (async_enable_stdin): Export.
+
+ * utils.c (exec_error_cleanup_chain): New cleanup chain.
+ (make_exec_error_cleanup, do_exec_error_cleanups,
+ discard_exec_error_cleanups): New functions.
+ * defs.h (make_exec_error_cleanup, do_exec_error_cleanups,
+ discard_exec_error_cleanups): Export.
+
+1999-09-24 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-gdb.c (expr_to_agent): Don't forget to pass argument to
+ new_agent_expr.
+
+1999-09-24 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-loop.c (fetch_inferior_event_wrapper): New
+ function. Wrapper to pass to catch_errors.
+ (inferior_event_handler): Pop the target if things go bad with it.
+ Call fetch_inferior_event() from within catch_errors().
+
+1999-09-24 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-gdb.c: Use internal_error instead of error, where
+ appropriate.
+
+1999-09-23 James Ingham <jingham@leda.cygnus.com>
+
+ * target.c (target_resize_to_sections): New function. Gather the
+ resizing code for the to_sections field into one place, and make
+ sure you update the other targets that are sharing the to_sections
+ structure.
+ * target.h: Declare the target_resize_to_sections function.
+ * solib.c (solib_add): use target_resize_to_sections.
+ * somsolib.c (som_solib_load_symbols): ditto
+ * rs6000-nat.c (xcoff_relocate_core): ditto
+ * pa64solib.c (pa64_solib_load_symbols): ditto
+ * irix5-nat.c (solib_add):ditto
+
+ * top.c: Define the attach & detach hooks
+ * defs.h: Declare the attach & detach hooks.
+ * infcmd.c (attach_command): call the attach hook if it exists.
+ (detach_command): call the detach hook if it exists.
+
+ * complaints.c (complain): Send the complaints to stderr rather
+ than stdout, so they don't get mixed into the result stream from
+ commands.
+
+1999-09-23 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (varobj_set_value): Fix handling of baseclasses and
+ correct the behavior when it is not a baseclass (both cases were
+ dumping core).
+
+1999-09-23 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (varobj_update): Fix setting of child error field.
+
+1999-09-23 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-loop.c (poll_timers): Use correct timeval field names,
+ when setting the notifier timeouts, in case of select() used.
+ (gdb_wait_for_event): Pass a pointer to the timeout structure to
+ select(), not the structure.
+
+1999-09-23 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (varobj_gen_name): Dynamically allocate variable object
+ name string.
+ (varobj_update): Fix creation of result list.
+
+Wed Sep 22 10:35:32 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (init.c): Change generated file to include "defs.h"
+ and "call-cmds.h". Use initialize_file_ftype when declaring
+ each initialize functions.
+ (call_cmds_h): Add definition.
+ (init.o): Add target and dependencies.
+ (init.c): Don't grep for _initialize* in init.c.
+
+ * defs.h (initialize_file_ftype): Add function typedef.
+
+1999-09-22 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * procfs.c (init_procinfo): move fltset initialization to caller.
+ (do_attach, create_procinfo): initialize fltset.
+
+1999-09-22 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (_initialize_varobj): Rename varobjdebug to debugvarobj
+ to avoid conflict with "set var".
+
+1999-09-22 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (varobj_get_type, c_value_of_variable): Remove
+ dependency on ui_out.[ch].
+
+1999-09-22 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (varobj_update): Fix order in which changed variables
+ are reported to match that of the old code.
+
+1999-09-22 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (type_changeable): Fix for testsuite case 2.12. Do not
+ report as changed a structure when one of it's children has changed.
+ (get_type, get_type_deref): Remove uneeded initialization.
+
+1999-09-22 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-loop.c, event-top.c, event-loop.h: Rerun indent.
+
+1999-09-21 Doug Evans <devans@casey.cygnus.com>
+
+ * m32r-stub.c (handle_exception): Fix typo in patch of 1999-08-26.
+
+1999-09-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (_initialize_varobj): Add set/show for varobjdebug.
+ (uninstall_variable): Test for varobjdebug before printing trace
+ and send it to gdb_stdlog.
+
+1999-09-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (c_type_of_child): Fix missing break, improve comment
+ and add warning.
+ (c_number_of_children): Add comment.
+
+Tue Sep 21 14:55:29 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 1999-08-20 J.T. Conklin <jtc@redback.com>:
+ * remote.c (read_frame): expand cisco run-length encoding variant
+ inline as is done for the standard encoding.
+ (remote_cisco_expand): Removed.
+
+1999-09-20 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (varobj_update): Test for illegal invocation for
+ non-root variable object.
+
+1999-09-20 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (my_value_equal): Style. Eliminate side-effects.
+ (varobj_update): Adjust calls to reflect the above change.
+
+1999-09-20 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (c_value_of_variable): Fix return value for struct
+ members when parent is a invalid pointer.
+
+1999-09-20 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-loop.c: Include <sys/time.h>.
+
+1999-09-20 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (cplus_number_of_children): Coding style improvement.
+ (cplus_value_of_child): Ditto.
+
+1999-09-20 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (c_name_of_child): Add missing default clause in switch
+ statement.
+ (c_type_of_child): Ditto.
+ (varobj_set_value): Test for NULL type.
+
+1999-09-20 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (varobj_set_value): Wrap call to evaluate_expression.
+
+1999-09-20 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (format_string[]): Remove unused variable(s).
+ (varobj_set_value): Ditto.
+ (c_value_of_root): Ditto.
+ (cplus_value_of_child): Ditto.
+
+1999-09-20 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c: Add missing header file include.
+ (new_variable, new_root_variable): Fix prototype and header.
+ (_initialize_varobj): Add prototype.
+
+1999-09-20 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * ser-ocd.c: (ser_ocd_open, ser_ocd_raw, ser_ocd_readchar,
+ ser_ocd_setbaudrate, ser_ocd_write, ser_ocd_close,
+ ser_ocd_get_tty_state, ser_ocd_set_tty_state): Remove unused
+ prototypes.
+ (ocd_readremote): Remove.
+ (ocd_write): Remove unused var 'c'.
+
+1999-09-20 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-top.c (change_line_handler): Cleanup dead code. Add comments.
+ * event-loop.c: Cleanup #if 0 code.
+
+ * event-loop.h (timer_handler_func): New function type.
+ (create_timer): Export function.
+ (delete_timer): Export function.
+
+ * event-loop.c: Add timeout and timeout_valid fields to
+ gdb_notifier. New structures gdb_timer and timer_list.
+ (gdb_do_one_event): Check whether there are any timers tht are
+ ready, before going to wait.
+ (gdb_wait_for_event): If the timeout structure is meaningful, pass
+ that to select()/poll().
+ (create_timer): New function. Creates a timer.
+ (delete_timer): New function. Deletes a timer.
+ (handle_timer_event): New function. Deals with timers that are ready.
+ (poll_timers): New Function. Chack whether timers have expired.
+
+Mon Sep 20 17:00:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (getpkt, putpkt, remote_console_output): Move
+ declaration from here.
+ * remote.h: To here. New file.
+ * tracepoint.c(putpkt, getpkt, remote_console_output): Delete
+ declarations. Moved to "remote.h".
+ * Makefile.in (remote_h): Define.
+ * remote.c, tracepoint.c: Include "remote.h".
+ * Makefile.in (tracepoint.o, remote.o): Add dependency on
+ "remote.h".
+
+ * remote.h (remote_cisco_objfile_relocate,
+ cleanup_sigint_signal_handler): Add declaration. Include FIXME.
+ * infrun.c: Include "remote.h".
+ (complete_execution): Delete local extern declaration
+ of ``cleanup_sigint_signal_handler''.
+ * Makefile.in (infrun.o): Add dependency on remote.h.
+
+Mon Sep 20 16:15:29 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ui-out.h (ui_out_test_flags): Add missing declaration.
+
+Mon Sep 20 13:41:04 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * kod.c (ecos_kod_open, ecos_kod_request, ecos_kod_close,
+ cisco_kod_open, cisco_kod_request, cisco_kod_close): Move
+ declarations from here.
+ * kod.h: To here. New file.
+ * kod-cisco.c, kod.c: Include "kod.h".
+ * Makefile.in (kod-cisco.o, kod.o): Add dependency on "kod.h".
+
+ * kod.h (kod_display_callback_ftype, kod_query_callback_ftype):
+ New function types.
+ * kod.h (kod_cisco_open): Use in declaration.
+ * kod.c (gdb_kod_open): Update definition.
+ * kod-cisco.c (cisco_kod_open): Update definition.
+
+Mon Sep 20 12:13:27 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mn10300-tdep.c (_initialize_mn10300_tdep): Add declaration.
+
+ * breakpoint.c (until_break_command_continuation): Add
+ declaration. Make static.
+ * event-top.c (rl_callback_read_char_wrapper): Ditto.
+
+Mon Sep 20 10:54:19 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (varobj.o): Disable warnings. Currently
+ work-in-progress.
+
+Fri Sep 17 19:28:17 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * source.c: Include "source.h".
+ (open_source_file, find_source_lines): Move declaration from here.
+ * source.h: New file. To here.
+ * Makefile.in (source.o): Add dependency on source.h.
+
+ * breakpoints.c (delete_command): Move declaration from here.
+ * breakpoints.h (delete_command): To here.
+
+1999-09-18 Jim Blandy <jimb@cygnus.com>
+
+ * hppa-tdep.c (in_solib_call_trampoline): If we can't recognize
+ the instruction we're at, we're not in a stub.
+
+Sat Sep 18 07:13:03 1999 Jeffrey A Law (law@cygnus.com)
+
+ * dwarf2read.c (dwarf_decode_lines): Correctly handle
+ DW_LNS_const_add_pc.
+
+1999-09-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * remote.c (remote_async_open_1): Use inferior_event_handler to
+ handle inferior events.
+ (extended_remote_async_create_inferior): Ditto.
+
+ * serial.h (serial_event_ftype): Add two pars.
+
+ * ser-unix.c (ser_unix_event): Add two parameters, error and fd.
+ Pass those into the call to the actual inferior event handler.
+
+ * infrun.c (complete_execution): Stdin handler is stdin_event_handler.
+
+ * event-top.h (stdin_event_handler): Export new function.
+
+ * event-top.c (stdin_event_handler): New function. Smarter handler
+ for events on stdin.
+ (change_line_handler): Don't need to update the handler for stdin
+ here anymore.
+ (_initialize_event_loop): Stdin handler is now stdin_event_handler.
+
+ * event-loop.h: (handler_func): Change signature, adding two new
+ args.
+ (sig_handler_func): New function type. It is the old handler_func.
+ (create_async_signal_handler): Update to use sig_handler_func.
+ (delete_async_signal_handler): Prototype for new function.
+
+ * event-loop.c: Include "inferior.h".
+ (struct file_handler): Add field error, to indicate error
+ condition on fd.
+ (struct async_signal_handler): Rename type of proc field.
+ (add_file_handler): Add exception condition as something select()
+ should report.
+ (handle_file_event): In case of error on the fd, record this in
+ the file_handler structure. Update call to (*proc)() to match new
+ signature.
+ (gdb_wait_for_event): If select() or poll() return error, report
+ this to user.
+ (create_async_signal_handler): Change first param type to
+ sig_handler_func*.
+ (inferior_event_handler): New function. Smarter inferior event
+ handling.
+
+1999-09-18 Jim Blandy <jimb@cygnus.com>
+
+ * pa64solib.c (pa64_solib_create_inferior_hook): Remove code which
+ tries to set __d_pid; it's not relevant to PA64 shared libraries.
+
+ A psymtab's texthigh element, and a block's endaddr element, are
+ the address past the end of the address range, never the address
+ of the last byte. These data structures mean the same thing on
+ forty different architectures; there's no reason they should be
+ different on HP/UX.
+ * symtab.c (find_pc_sect_psymtab): Remove special case for HP/UX.
+ (find_pc_sect_symtab): Same.
+ * objfiles.c (find_pc_sect_section): Same.
+
+Sat Sep 18 07:13:03 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppa-tdep.c (internalize_unwinds): Handle PA64 shared libraries
+ correctly
+
+ * hppa-tdep.c (in_solib_call_trampoline): Handle PA64 shared library
+ trampolines.
+
+1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * wrapper.h: Add missing define brackets.
+
+1999-09-17 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * breakpoint.c (permanent_breakpoint_here_p): Delete.
+ Accidentally left over from previous changes.
+
+1999-09-17 Jim Blandy <jimb@cygnus.com>
+
+ * config/pa/tm-hppa64.h (ARGS_GROW_DOWNWARD): Deleted. There are
+ many more differences between the 32- and 64-bit ABI's than the
+ direction the arguments grow, so this name is misleading.
+ (PA20W_CALLING_CONVENTIONS): Define this instead.
+ * config/pa/tm-hppa.h (ARGS_GROW_DOWNWARD): Delete.
+ * hppa-tdep.c (hppa_push_arguments): Split into two separate
+ functions, depending on whether PA20W_CALLING_CONVENTIONS is
+ #defined. These implement completely separate specifications,
+ they don't really share that much code anyway, and this is much
+ more readable. Specifically: leave a 16-byte, not 32-byte, frame
+ marker; correctly align objects larger than eight bytes; promote
+ all integral scalar arguments smaller than eight bytes to a full
+ register width; pad aggregates smaller than eight bytes on the
+ right.
+
+1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * Makefile.in: Add entries for varobj.[cho] and wrapper.[cho].
+ gdbtk-varobj.[co]. gdbtk-varobj.o is not yet on the COMMON_OBS
+ list because it conflicts with the older gdbtk-variable.o which
+ is still the default.
+
+1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.h: New file. GDB variable objects API.
+ * varobj.c: New file. Implementation of the GDB variable objects
+ API.
+
+1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * wrapper.h: New file. Longjump free calls to gdb internal
+ routines.
+ * wrapper.c (gdb_evaluate_expression, wrap_evaluate_expression,
+ gdb_value_fetch_lazy, wrap_value_fetch_lazy, gdb_value_equal,
+ wrap_value_equal, gdb_value_ind, wrap_value_ind): New functions.
+
+Thu Sep 16 17:33:35 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (remote_async_open_1): Use SERIAL_ASYNC to
+ enable/disable async event callback on serial port. Use
+ SERIAL_CAN_ASYNC_P / SERIAL_IS_ASYNC_P to determine if / when
+ async mode.
+ (remote_async_resume, remote_async_detach, remote_async_kill,
+ extended_remote_async_create_inferior, remote_async_wait): Ditto.
+
+ * ser-unix.c (hardwire_readchar): When ASYNC, only read a single
+ character.
+ (ser_unix_readchar): Ditto. Problems occure with back-to-back
+ data from a target. The ASYNC code can loose the second data
+ chunk.
+
+ * serial.c (serial_fdopen): Initialize async_handler and
+ async_context.
+
+1999-09-16 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * utils.c (discard_all_continuations): New function.
+ * defs.h: (discard_all_continuations): Add prototype.
+
+1999-09-16 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * valops.c: Remove prototype for search_struct_field_aux(). THe
+ function was nowhere in the file.
+ (value_ind): Remove unused var real_val.
+ (value_find_oload_method_list): Remove unused var v.
+ (find_overload_match): Remove extra declaration of var jj.
+
+ * Makefile.in (event_top_h): Define. Add dependency on this for
+ every file that includes event-top.h.
+
+Thu Sep 16 17:33:35 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * serial.c (serial_open): Delete ``&'' device.
+ * ser-unix.c (_initialize_ser_hardwire): Make the "hardwire"
+ device async. Delete temporary "async-hardwire" device.
+
+Thu Sep 16 16:27:13 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * serial.h (SERIAL_IS_ASYNC_P): Define. Non-zero when serial
+ device is in async mode.
+ (SERIAL_CAN_ASYNC_P): Rename SERIAL_ASYNC_P.
+ * serial.c (serial_is_async_p): Implement.
+ (serial_can_async_p): Rename serial_async_p.
+ (serial_open): Initialize ASYNC_HANDLER and ASYNC_CONTEXT. Save
+ the original name in SCB instead of the stripped name.
+
+Thu Sep 16 12:20:11 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * serial.h (struct serial_ops): Add field ASYNC.
+ (SERIAL_ASYNC, SERIAL_ASYNC_P): New macros.
+ (struct _serial_t): Add fields async_context and async_handler.
+ * serial.c (serial_async, serial_async_p): Implement.
+
+ * ser-unix.c: Include "event-loop.h".
+ (ser_unix_async), ser-unix.c: New function. Implement async mode.
+ (async_event): Handle async events.
+ * ser-unix.c (_initialize_ser_hardwire), ser-tcp.c
+ (_initialize_ser_tcp), ser-pipe.c (_initialize_ser_pipe): Enable
+ ASYNC.
+
+ * serial.c (serial_open): Discard leading ``|'' before opening a
+ pipe device.
+ * ser-pipe.c (pipe_open): Adjust.
+ * serial.c (serial_open): Add ``&'' prefix so that
+ "async-hardwire" device can be explicitly selected. Work in
+ progress.
+ * ser-unix.c: Register "async-hardwire" device.
+
+Thu Sep 16 09:04:53 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ser-unix.h: New file. Declare generic ser_unix functions.
+ * ser-unix.c (ser_unix_nop_get_tty_state,
+ ser_unix_nop_set_tty_state, ser_unix_nop_raw, ser_unix_wait_for,
+ ser_unix_readchar, ser_unix_nop_noflush_set_tty_state,
+ ser_unix_nop_print_tty_state, ser_unix_nop_setbaudrate,
+ ser_unix_nop_setstopbits, ser_unix_write,
+ ser_unix_nop_flush_output, ser_unix_nop_flush_input,
+ ser_unix_nop_send_break, ser_unix_nop_drain_output): New
+ functions.
+ * ser-unix.c: Include <sys/wait.h>, <sys/socket.h>,
+ "gdb_string.h".
+
+ * ser-tcp.c (_initialize_ser_tcp), ser-unix.c
+ (_initialize_ser_hardwire), ser-pipe.c (_initialize_ser_tcp):
+ Initialize ops vector using assignment.
+
+ * ser-pipe.c, ser-tcp.c, ser-unix.c: Include ser-unix.h.
+
+ * ser-pipe.c (pipe_get_tty_state, pipe_set_tty_state,
+ pipe_return_0, pipe_raw, wait_for, pipe_readchar,
+ pipe_noflush_set_tty_state, pipe_print_tty_state,
+ pipe_setbaudrate, pipe_setstopbits, pipe_write), ser-tcp.c
+ (tcp_get_tty_state, tcp_set_tty_state, tcp_return_0, tcp_raw,
+ wait_for, tcp_readchar, tcp_noflush_set_tty_state,
+ tcp_print_tty_state, tcp_setbaudrate, tcp_setstopbits, tcp_write):
+ Delete functions.
+
+1999-09-15 Stan Shebs <shebs@andros.cygnus.com>
+
+ * d10v-tdep.c (remote_d10v_translate_xfer_address): Move to here
+ from remote-d10v.c, also change the memory translation to its
+ previous version.
+ * remote-d10v.c: Remove.
+ * config/d10v/d10v.mt (TDEPFILES): Remove remote-d10v.o.
+
+1999-09-15 Jim Blandy <jimb@cygnus.com>
+
+ * breakpoint.c (remove_breakpoint): Return zero, not nothing.
+
+1999-09-14 Jim Blandy <jimb@cygnus.com>
+
+ * hppa-tdep.c (frame_chain): If the unwind info says we've saved
+ r3, don't trust it. Call get_frame_saved_regs and see if we can
+ actually find an address for r3 there.
+
+ * pa64solib.c (pa64_sharedlibrary_info_command): Text fix.
+
+Tue Sep 14 14:34:28 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * serial.h (DEPRECATED_SERIAL_FD): Define.
+ * serial.c (deprecated_serial_fd): New function.
+
+ * remote.c (remote_async_open_1, remote_async_open_1,
+ remote_async_detach, remote_async_kill,
+ extended_remote_async_create_inferior, minitelnet): Update.
+ * remote-es.c (es1800_open, es1800_close, es1800_transparent): Update.
+
+ * remote-st.c (connect_command), remote-os9k.c (connect_command):
+ Fix. Call FD_SET et.al. with FD instead of serial_t.
+
+1999-09-14 Jim Blandy <jimb@cygnus.com>
+
+ * hppa-tdep.c (hppa_frame_find_saved_regs): The two possible
+ instructions for saving the return pointer (32- and 64-bit) save
+ it at different offsets.
+
+ * config/pa/tm-hppa64.h: Doc fix.
+
+ * defs.h (continuation): Make this a typedef.
+
+ * Makefile.in (gdbtk.o, gdbtk-cmds.o): Depend on $(top_h).
+
+ * Makefile.in (i386-linux-nat.o): Depend on symfile.h, not
+ $(symfile_h); the latter has no definition.
+
+ * breakpoint.c (breakpoint_here_p): Remove meaningless code,
+ testing b->enable against shlib_disabled and call_disabled after
+ we know it is enabled.
+
+ Implement "permanent breakpoints" --- breakpoints that are
+ hardwired into the inferior's code. GDB knows they're there, but
+ doesn't try to insert or remove them, etc.
+ * breakpoint.h (enum enable): Add `permanent' enablement state.
+ * breakpoint.c (make_breakpoint_permanent): New function.
+ * breakpoint.h (make_breakpoint_permanent): Add declaration.
+ * breakpoint.c (insert_breakpoints): Don't bother to insert
+ permanent breakpoints...
+ (remove_breakpoint): ... or remove them.
+ (breakpoint_here_p): Handle `permanent' like `enabled'. Change
+ return value to indicate whether it's a permanent breakpoint here,
+ or an ordinary breakpoint.
+ * breakpoint.h (enum breakpoint_here): New enum.
+ (breakpoint_here_p): Change declaration.
+ * breakpoint.h (breakpoint_1): Extend bpenables to cover all the
+ enablement states.
+ (describe_other_breakpoints): Describe permanent breakpoints.
+ (check_duplicates): If one of the breakpoints at ADDRESS is a
+ permanent breakpoint, treat all the others as the duplicates, so
+ we don't try to insert or remove any of them. Verify that only
+ the permanent breakpoint is actually inserted.
+ (delete_breakpoint): Complain if we discover that another
+ breakpoint was inserted at the same place as a permanent
+ breakpoint.
+ (disable_breakpoint): Fail silently if asked to disable a
+ permanent breakpoint.
+ (do_enable_breakpoint): Don't change a permanent breakpoint's
+ enablement to ordinary `enabled'. Leave it alone.
+ (create_solib_event_breakpoint): Return the
+ breakpoint object created.
+ * breakpoint.h (create_solib_event_breakpoint): Fix declaration.
+ * pa64solib.c (pa64_solib_create_inferior_hook): Do turn on the
+ DT_HP_DEBUG_CALLBACK flag in the dynamic linker, so it will call
+ __dld_break, which contains the permanent breakpoint, when interesting
+ things happen. Tell GDB that the breakpoint in __dld_break is
+ permanent.
+ * gdbtk-cmds.c (gdb_get_breakpoint_info): Report a permanent
+ breakpoint as enabled.
+ * infrun.c (SKIP_PERMANENT_BREAKPOINT): Provide default definition.
+ (default_skip_permanent_breakpoint): New function.
+ (resume): If we're trying to resume at a permanent breakpoint, use
+ SKIP_PERMANENT_BREAKPOINT to step over it.
+ * hppa-tdep.c (hppa_skip_permanent_breakpoint): New function.
+ * config/pa/tm-hppa.h (hppa_skip_permanent_breakpoint): Declare.
+ (SKIP_PERMANENT_BREAKPOINT): Define.
+
+1999-09-14 Kevin Buettner <kevinb@cygnus.com>
+
+ * symtab.h, minsyms.c (find_stab_function_addr): Changed
+ type of second parameter from partial_symtab * to char *.
+ Fixed all callers.
+ * minsyms.c (find_stab_function_addr): Look for minimal
+ symbol without filename if filename based search fails.
+ * dbxread.c (process_one_symbol): Call find_stab_function_addr()
+ in place of inline code with identical functionality.
+ * partial-stab.h (case N_FUN, descriptors 'F' and 'f'): Look
+ up symbol's address from minimal symbol table when N_FUN
+ address is missing. Also, make sure this value is used for
+ calculating the value of the texthigh field.
+
+1999-09-14 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-loop.c (create_file_handler): Increment the total number
+ of file descriptors for the poll case, only if this is a new file
+ desc.
+
+1999-09-14 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c: misc minor cleanups and fixes missed in last patch.
+
+Tue Sep 14 12:37:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * serial.h (SERIAL_PRINT_TTY_STATE): Add STREAM parameter.
+ (union serial_ops): Update.
+
+ * ser-unix.c (hardwire_print_tty_state, ser-tcp.c
+ (tcp_print_tty_state), ser-pipe.c (pipe_print_tty_state,
+ ser-go32.c (dos_print_tty_state, ser-mac.c (mac_print_tty_state,
+ ser-ocd.c (ocd_print_tty_state, ser-e7kpc.c
+ (e7000pc_print_tty_state): Update.
+ * inflow.c (child_terminal_info): Update.
+ * serial.c (serial_print_tty_state): Update.
+
+Tue Sep 14 11:41:37 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * serial.c, serial.h, ser-tcp.c, ser-unix.c, ser-pipe.c: Convert
+ all functions to ISO-C.
+ * serial.h, serial.c: Move all indirect macro function calls from
+ serial.h into serial.c.
+ (serial_drain_output, serial_flush_output, serial_flush_input,
+ serial_raw, serial_get_tty_state, serial_set_tty_state,
+ serial_print_tty_state, serial_noflush_set_tty_state,
+ serial_setbaudrate, serial_setstopbits): New functions.
+ (do_serial_close): Rename serial_close.
+ (serial_close, serial_un_fdopen): New functions. Call
+ do_serial_close.
+
+1999-09-13 James Ingham <jingham@leda.cygnus.com>
+
+ * symtab.c (decode_line_1): Find the rightmost parenthesis in the
+ expression, not the leftmost. This allows us to parse function
+ declarations with embedded function prototypes.
+
+Mon Sep 13 18:39:31 1999 Jeffrey A Law (law@cygnus.com)
+
+ * pa64solib.c (pa64_sharedlibrary_info_command): Fix typos.
+
+1999-09-13 Kevin Buettner <kevinb@cygnus.com>
+
+ * i386-tdep.c (i386_extract_return_value): ifdef'd so that
+ non-linux targets will work again.
+ (i386_do_registers_info, i386_print_register): Revert changes
+ of 1999-09-03; these functions have been removed because they
+ are Linux specific and break non-Linux builds. This functionality
+ will be restored after FP support unification has been achieved.
+ * i387-tdep.c (i387_print_register, void i387_float_info):
+ Likewise.
+ * config/i386/tm-linux.h (i387_float_info, FLOAT_INFO,
+ DO_REGISTERS_INFO, i386_do_registers_info,
+ i387_print_register): Likewise.
+
+1999-09-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-top.c (call_readline): Change to accept gdb_client_data as
+ param.
+ (rl_callback_read_char_wrapper): New function to match what the
+ event loop expects and what readline expects.
+ (change_line_handler): Make call_readline point to
+ rl_callback_read_char_wrapper, instead of rl_callback_read_char.
+ (_initialize_event_loop): Ditto.
+ (gdb_readline2): Change parameter to gdb_client_data.
+ * event-top.h (call_readline, gdb_readline2): Change accordingly.
+
+ * event-loop.c (add_file_handler): Change 2nd par to
+ handler_func*. No more need for casting.
+ * event-loop.h (create_async_signal_handler): Change accordingly.
+
+ * inferior.h (fetch_inferior_event): Change parameter to void*.
+ * infrun.c (fetch_inferior_event): Ditto.
+
+1999-09-13 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infrun.c (step_into_function): New function, broken out from the
+ step_into_function label in handle_inferior_event.
+ (handle_inferior_event): Change a goto into a function call.
+
+1999-09-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-top.h: New file. All the exported vars and functions from
+ event-top.c.
+
+ * event-loop.h (struct gdb_event, event_handler_func,
+ file_handler, async_signal_handler, SELECT_MASK, fd_mask, NBBY,
+ FD_SETSIZE, howmany, NFDBITS, MASK_SIZE): Move to event-loop.c.
+ (struct prompts, PROMPT, PREFIX, SUFFIX, display_gdb_prompt,
+ async_init_signals, set_async_editing_command,
+ set_async_annotation_level, set_async_prompt, handle_stop_sig,
+ handle_sigint, pop_prompt, push_prompt, gdb_readline2,
+ mark_async_signal_handler_wrapper, async_request_quit,
+ async_command_editing_p, exec_done_display_p,
+ async_annotation_suffix, new_async_prompt, the_prompts,
+ call_readline, input_handler, input_fd): Move to event-top.h.
+ (All function prototypes): Don't use PARAMS anymore.
+
+ * event-loop.c: (struct gdb_event, event_handler_func,
+ file_handler, async_signal_handler, SELECT_MASK, fd_mask, NBBY,
+ FD_SETSIZE, howmany, NFDBITS, MASK_SIZE): Move to here from
+ event-loop.h.
+ Include event-top.h. Remove use of PARAMS. ANSIfy functions headers.
+
+ * event-top.c: Include event-top.h. Include "signals.h", not
+ <signals.h>.
+ Remove use of PARAMS. ANSIfy functions headers.
+ (handle_stop_sig): move prototype to event-top.h.
+
+ * remote.c: Include event-top.h. Make it understand
+ async_signal_handler type.
+ * infrun.c: Include event-top.h.
+ * mi-main.c: Ditto.
+ * top.c Ditto.
+ * utils.c: Ditto.
+
+Mon Sep 13 18:54:05 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh: Describe each of the fields.
+
+Mon Sep 13 17:51:28 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 1999-09-12 Jim Blandy <jimb@cygnus.com>:
+ * gdbarch.sh (generating setters): Use sed to generate the proper
+ indentation, not tr; tr's behavior is notoriously unportable.
+
+1999-09-10 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * i387-tdep.c (print_387_control_bits): Don't print newline; the
+ callers take care of that. (Thanks to H.J. Lu.)
+
+1999-09-09 Stan Shebs <shebs@andros.cygnus.com>
+
+ * d10v-tdep.c (DMEM_START): Set to 0x2000000.
+ (itrace, iuntrace, info itrace, itdisassemble, itracedisplay,
+ itracesource): Add 'i' prefix to commands, so as not to conflict
+ with generic trace commands.
+
+1999-09-09 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * remote.c (_initialize_remote): Fix the specification of the
+ "remote" prefix to set and show commands.
+
+1999-09-09 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * command.c (print_doc_line): Update to use ui_out.
+ (do_setshow_command): Ditto.
+ (cmd_show_list): Ditto.
+
+1999-09-09 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-loop.c (create_file_event): New function. Creates a gdb
+ event for a given fd.
+ (gdb_wait_for_event): Use create_file_event().
+ * event-loop.h: export create_file_event().
+
+ * event-loop.c (delete_file_handler): Move the clearing of the
+ mask to later on in the function, because we need it in order to
+ deactivate the correct fd when using select().
+
+ * m32r-tdep.c (decode_prologue): Fix typo. Instructions starting
+ with 0xf are branch instructions.
+ (m32r_scan_prologue): Initialize framesize to 0.
+
+1999-09-07 J.T. Conklin <jtc@redback.com>
+
+ * i386-stub.c (exceptionHook, oldExceptionHook): Removed.
+ (handle_exception): Removed #if'd out exception hook code.
+
+ * i386-stub.c, m68k-stub.c (error): Removed unused variable.
+
+ * i386-stub.c, m68k-stub.c, sh-stub.c, sparc-stub.c,
+ sparcl-stub.c, sparclet-stub.c (remcomInBuffer, remcomOutBuffer):
+ Make static.
+
+Tue Sep 7 14:06:22 1999 Kevin Buettner <kevinb@cygnus.com>
+
+ * config/i386/tm-linux.h (SOFUN_ADDRESS_MAYBE_MISSING):
+ Define.
+
+Tue Sep 7 08:18:01 1999 Kevin Buettner <kevinb@cygnus.com>
+
+ From Jim Blandy <jimb@cygnus.com>:
+
+ Step into calls to functions in shared libraries properly. See
+ the comments for SKIP_SOLIB_RESOLVER atop infrun.c for details.
+ * infrun.c (SKIP_SOLIB_RESOLVER): New macro.
+
+1999-09-05 Fred Fish <fnf@cygnus.com>
+
+ * elfread.c (elf_symtab_read): Remove separately passed bfd
+ pointer and offset. Pick up bfd pointer from objfile, and
+ get offset from objfile's section_offsets.
+
+Fri Sep 3 22:29:39 1999 Kevin Buettner <kevinb@cygnus.com>
+
+ * config/i386/tm-linux.h (REGISTER_NAMES): Changed register
+ named "foo" to "fopo" which more accurately describes the FPU
+ Operand Pointer Offset. The real reason for this change, of
+ course, is that many programmers use $foo as a convenience
+ variable and are likely to be unpleasantly surprised to find
+ that they're unwittingly changing the state of their ia32 FPU.
+
+1999-09-03 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * monitor.c (monitor_supply_register): Stop scanning val string
+ if a newline is encountered.
+
+1999-09-03 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ monitor.c (TARGET_BUF_SIZE): New macro, defined to 2048.
+ (monitor_expect_regexp, monitor_wait, monitor_dump_reg_block,
+ monitor_dump_reg_block): Dump hard-coded constants in favor
+ of TARGET_BUF_SIZE.
+
+ (readchar): Re-enable output of characters read from monitor when
+ remotedebug is set.
+
+ (monitor_supply_register): Use ULONGEST to hold value.
+ Replace strtoul() call with hand-coded loop to handle values
+ larger than 'long'.
+
+ (monitor_store_register): Use ULONGEST to hold value.
+
+Fri Sep 3 00:47:44 1999 Kevin Buettner <kevinb@cygnus.com>
+
+ [Merged linux/x86 floating point code from Bill Metzenthen,
+ Jim Blandy, Anthony Green, H. J. Lu, and possibly others. The
+ following remarks are Jim Blandy's.]
+
+ * findvar.c (extract_floating): Call TARGET_EXTRACT_FLOATING, if
+ #defined.
+ (store_floating): Call TARGET_STORE_FLOATING, if #defined.
+
+ * i386-tdep.c (i386_print_register, i386_do_registers_info): New
+ functions.
+ (i386_extract_return_value): GNU/Linux returns floating point
+ values in a floating point register too.
+ (set_disassembly_flavor): Add prototype.
+ (i386_extract_return_value): Use FPDATA_REGNUM, not FP0_REGNUM (
+ which wasn't the first FP data register).
+ (i386_do_registers_info): Use FPSTART_REGNUM and FPEND_REGNUM as
+ the limits of the FPU-related registers.
+ (i386_extract_return_value): Tell GDB how to find return values
+ larger than four bytes. (Thanks to Paul N. Hilfinger for the bug
+ report.)
+
+ * i387-tdep.c (print_387_control_word): Break out bit-splitting into...
+ (print_387_control_bits): New function.
+ (print_387_status_word): Break out bit-splitting into...
+ (print_387_status_bits): New function.
+ (i387_print_register, i387_float_info, i387_hex_float_input): New
+ functions.
+ (i387_extract_floating, i387_store_floating): New functions.
+
+ * valprint.c (print_floating): Use macro TARGET_ANALYZE_FLOATING,
+ if it's #defined. Tolerate values of `nonnegative' other than
+ zero and one.
+
+ * i386-linux-nat.c: New file.
+ * Makefile.in (ALLDEPFILES): Mention i386-linux-nat.c.
+ (i386-linux-nat.o): New rule, listing dependencies.
+ * config/i386/linux.mh (NATDEPFILES): Use i386-linux-nat.o, not
+ the plain i386v4-nat.o.
+ * config/i386/nm-linux.h (FETCH_INFERIOR_REGISTERS): Define.
+ * config/i386/xm-linux.h: Define HOST_I386.
+
+ * config/i386/tm-linux.h (FP0_REGNUM): Replaced by...
+ (FPSTART_REGNUM, FPCONTROL_REGNUM, FPSTATUS_REGNUM, FPTAG_REGNUM,
+ FPDATA_REGNUM, FPEND_REGNUM): New definitions.
+ (REGISTER_BYTES): Changed accordingly.
+ (SKIP_SOLIB_RESOLVER): #define this.
+ (i386_linux_skip_solib_resolver): New declaration.
+ (i387_float_info): Added extern decl for this function.
+ (TARGET_EXTRACT_FLOATING, TARGET_STORE_FLOATING,
+ TARGET_ANALYZE_FLOATING): Define.
+ (i387_extract_floating, i387_store_floating): New extern decls.
+ (I386_GNULINUX_TARGET): Define.
+ (NUM_REGS, NUM_FREGS, REGISTER_NAMES, FP0_REGNUM, FPDATA_REGNUM,
+ FPENV_BYTES, FPREG_RAW_SIZE, FPREG_BYTES, REGISTER_BYTES,
+ REGISTER_BYTE, REGISTER_RAW_SIZE, REGISTER_VIRTUAL_SIZE,
+ MAX_REGISTER_RAW_SIZE, MAX_REGISTER_VIRTUAL_SIZE,
+ TARGET_LONG_DOUBLE_BIT, FLOAT_INFO, DO_REGISTERS_INFO): New
+ definitions, perhaps overriding those inherited from
+ config/i386/tm-i386.h.
+ (i386_do_registers_info, i387_print_register, double_to_i387,
+ i387_to_double): New declarations.
+ (LD_I387): Define iff both the host and target are using i387
+ FPU's.
+ (HEX_FLOAT_INPUT, REGISTER_CONVERTIBLE,
+ REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW,
+ REGISTER_VIRTUAL_TYPE): Define these if LD_I387 is defined.
+
+ * source.c (list_command): List the right number of source lines,
+ even if we're at the top of the file.
+
+1999-09-02 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infrun.c (step_over_function): New function, broken out from the
+ step_over_function label in handle_inferior_event.
+ (handle_inferior_event): Change a goto into a function call.
+
+Thu Sep 2 18:26:04 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (GDB_WERROR_CFLAGS, GBB_WARN_CFLAGS): Define.
+ (INTERNAL_CFLAGS): Update
+ * configure.in (WERROR_CFLAGS, WARN_CFLAGS): Sync with
+ ../sim/common/aclocal.m4.
+ * configure: Re-generate.
+
+Thu Sep 2 00:27:36 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (z8k-tdep.o): For moment, don't try to compile with
+ -Werror. See Makefile.in.
+ * z8k-tdep.c (z8k_set_pointer_size): Document problem.
+
+ * config/z8k/tm-z8k.h (z8k_print_register_hook, z8k_frame_chain,
+ z8k_saved_pc_after_call, z8k_frame_saved_pc,
+ z8k_set_pointer_size): Declare.
+ (z8k_skip_prologue): Fix typo. Was mz8k_skip_prologue.
+ (FRAME_CHAIN, PRINT_REGISTER_HOOK, FRAME_SAVED_PC,
+ SAVED_PC_AFTER_CALL): Update.
+ * z8k-tdep.c (z8k_print_register_hook): Rename
+ z8k_print_register_hook.
+ (z8k_frame_chain): Rename frame_chain.
+ (z8k_saved_pc_after_call): Rename saved_pc_after_call.
+ (z8k_frame_saved_pc): Rename frame_saved_pc.
+ (z8k_print_register_hook): Fix printf.
+ (read_memory_pointer): Add declaration.
+ ("value.h"): Include.
+ * Makefile.in (z8k-tdep.o): Add dependency on value.h.
+
+ * config/sparc/tm-sparc.h (PRINT_EXTRA_FRAME_INFO): Fix
+ printf. calls
+ * Makefile.in (remote-e7000.o): For moment, don't try to compile
+ with -Werror. See Makefile.in.
+ * sh-tdep.c (sh_show_regs): Fix printf calls.
+ * xcoffsolib.c (solib_info): Fix Printf calls.
+ * dink32-rom.c: #include "symfile.h" for generic_load and
+ "inferior.h" for write_pc.
+ * Makefile.in (dink32-rom.o): Update.
+
+ * config/mn10300/tm-mn10300.h (mn10300_store_struct_return),
+ config/mn10200/tm-mn10200.h (mn10200_store_struct_return): Add
+ declarations.
+
+Tue Aug 31 00:48:27 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * config/mips/tm-tx49el.h (REGISTER_SIM_REGNO): Define.
+
+ * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register):
+ Pass REGISTER_SIM_REGNO converted register number to the
+ simulator.
+
+1999-09-01 Tom Tromey <tromey@cygnus.com>
+
+ * config/i386/nm-linux.h (PREPARE_TO_PROCEED): Added argument.
+
+1999-09-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * values.c (value_virtual_fn_field): Remove unused var(s).
+ * thread.c (prune_threads): Ditto.
+ * symtab.c (lookup_transparent_type): Ditto.
+ (decode_line_1): Ditto.
+ (make_symbol_overload_list): Ditto.
+ * rs6000-tdep.c (frame_get_saved_regs): Ditto.
+ (set_processor): Ditto.
+ * remote.c (remote_remove_breakpoint): Ditto.
+ (remote_query): Ditto.
+ (readtty): Ditto.
+ * remote-sds.c (sds_fetch_registers): Ditto.
+ (putmessage): Ditto.
+ * ppcbug-rom.c (ppcbug_supply_register): Ditto.
+ (ppcbug_open): Remove unused prototype.
+ * parse.c (parse_nested_classes_for_hpacc): Remove unused var(s).
+ * ocd.c (ocd_open): Ditto.
+ (ocd_get_packet): Ditto.
+ * monitor.c (monitor_error): Ditto.
+ (monitor_wait_srec_ack): Ditto.
+ * main.c (main): Ditto.
+ * gdbtypes.c (count_virtual_fns): Ditto.
+ * exec.c (exec_file_command): Ditto.
+
+ * event-top.c: Include handle_sigwinch() function prototype within
+ appropriate #ifdef.
+
+ * eval.c (evaluate_subexp_standard): Remove unused variable.
+ (evaluate_subexp_standard): Remove unused variables.
+ * dink32-rom.c (dink32_supply_register): Remove unused variable.
+ * dbxread.c (elfstab_build_psymtabs): Ditto.
+ * command.c (do_setshow_command): Ditto.
+ * breakpoint.c (solib_load_unload_1): Remove unused variables 'i'
+ and 'sal'.
+ (until_break_command): Remove unused variables 'arg1' and 'arg2'.
+ (create_exception_catchpoint): Remove unused variable 'i'.
+ * ax-gdb.c (gen_sub): Remove unused variable.
+ (_initialize_ax_gdb): Ditto.
+
+ * ser-pipe.c (pipe_readchar): If timeout is expired return
+ SERIAL_TIMEOUT.
+ * ser-tcp.c (tcp_readchar): If timeout is expired return
+ SERIAL_TIMEOUT.
+
+Wed Sep 1 15:07:25 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * version.h: New file.
+ * Makefile.in (version_h): Define.
+ (version.o): Add target.
+
+ * remote-array.c: #include "version.h".
+ (version): Delete extern declarations.
+ * Makefile.in (remote-array.o): Add dependency on version.h.
+
+ * top.c: #include "version.h".
+ (version, host_name, target_name): Delete extern declarations.
+ * Makefile.in (top.o): Add dependency on version.h.
+
+ * remote.c (remote_remove_watchpoint, remote_insert_watchpoint),
+ remote-array.c (array_open), remote-mips.c (send_srec),
+ dve3900-rom.c (store_bitmapped_register): Fix Printfs.
+
+ * mips-tdep.c (mips_print_extra_frame_info, print_unpack),
+ m32r-rom.c (m32r_load_section), m32r-tdep.c (m32r_frame_chain),
+ dsrec.c (load_srec): Fix printf problems.
+
+Wed Sep 1 13:16:49 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (monitor.o): For moment, don't try to compile with
+ -Werror. monitor.c has -Wformat problems. See Makefile.in for
+ more info.
+
+Tue Aug 31 21:23:38 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppa-tdep.c (prologue_inst_adjust_sp): Correct offset computation
+ for doubleword store instructions.
+ (hppa_frame_find_saved_regs): Similarly.
+
+Wed Sep 1 09:22:50 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d30v-tdep.c (d30v_print_register):
+ (tdisassemble_command):
+
+ * d10v-tdep.c (show_regs, trace_info, tdisassemble_command): Fix
+ printf problems.
+
+ * remote-sim.c (dump_mem), remote-rdi.c (arm_rdi_create_inferior):
+ Fix printf arguments.
+
+ * remote-mips.c, mips-tdep.c: Move declaration of
+ ``mips_set_processor_type_command'' from here.
+ * config/mips/tm-mips.h: To here.
+ * remote-array.c: #include "inferior.h".
+ * config/mips/tm-embed.h (remote_mips_stopped_by_watchpoint): Add
+ declaration.
+ * remote-mips.c (remote_mips_stopped_by_watchpoint): Define using
+ ISO-C prototype.
+ (monitor_supports_breakpoints): Integer variable.
+
+ * m32r-rom.c: #include "inferior.h" and <ctype.h>
+ * config/m32r/tm-m32r.h (m32r_write_sp): Add declaration.
+
+ * config/i960/tm-i960.h (leafproc_return, i960_pop_frame): Add
+ declaration.
+ (POP_FRAME): Call i960_pop_frame.
+ * i960-tdep.c (i960_pop_frame): Rename pop_frame.
+ * mon960-rom.c: #include "inferior.h" for declaration of write_pc.
+
+1999-08-15 Fred Fish <fnf@cygnus.com>
+
+ * objfiles.c (objfile_relocate): Use SIZEOF_SECTION_OFFSETS when
+ allocating section_offsets array.
+ * remote-os9k.c (rombug_wait): Ditto.
+ * remote-vx.c (vx_add_symbols): Ditto.
+ * remote.c (get_offsets): Ditto.
+ (remote_cisco_objfile_relocate): Ditto.
+ * rs6000-nat.c (vmap_symtab): Ditto.
+
+ * dstread.c (dst_symfile_offsets): Set section_offsets directly instead
+ of returning a pointer to section offsets.
+ * somread.c (som_symfile_offsets): Ditto.
+ * xcoffread.c (xcoff_symfile_offsets): Ditto.
+ * symfile.c (default_symfile_offsets): Ditto.
+ (syms_from_objfile): The sym_offsets function has already set section
+ offsets and no longer returns a value.
+
+ * xcoffread.c (scan_xcoff_symtab): Eliminate section_offsets passed
+ separate from objfile.
+ (xcoff_start_psymtab): Ditto.
+ (START_PSYMTAB): Ditto.
+ * os9kread.c (read_minimal_symbols): Ditto.
+ (read_os9k_psymtab): Ditto.
+ (os9k_start_psymtab): Ditto.
+ (record_minimal_symbol): Ditto.
+ * dbxread.c (START_PSYMTAB): Ditto.
+ (start_psymtab): Ditto.
+ * mdebugread.c (START_PSYMTAB): Ditto.
+ (elfmdebug_build_psymtabs): Ditto.
+ (mdebug_build_psymtabs): Ditto.
+ (parse_partial_symbols): Ditto.
+ (new_psymtab): Ditto.
+ * dwarfread.c (dwarf_build_psymtabs): Ditto.
+ * partial-stab.h (START_PSYMTAB): Ditto.
+ * stabsread.h (start_psymtab): Ditto.
+ * dwarf2read.c (dwarf2_build_psymtabs): Ditto.
+ (dwarf2_build_psymtabs_easy): Ditto.
+ (dwarf2_build_psymtabs_hard): Ditto.
+ * hp-psymtab-read.c (hpread_build_psymtabs): Ditto.
+ (hpread_quick_traverse): Ditto.
+ (hpread_start_psymtab): Ditto.
+ (scan_procs): Ditto.
+ * hpread.c (hpread_build_psymtabs): Ditto.
+ * symfile.h (dwarf2_build_psymtabs): Ditto.
+
+ * dbxread.c (read_dbx_symtab): Use ANOFFSET to access section
+ offsets.
+ * coffread.c (enter_linenos): Pass objfile instead of section
+ offsets.
+
+ * dbxread.c (dbx_symfile_read): No need to explicitly pass
+ text addr and size. Let read_dbx_symtab find them.
+ (read_dbx_symtab): Get text addr and size from objfile.
+ (dbx_symfile_read): Remove dead code (call to strlen);
+
+1999-08-31 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * Makefile.in: add rule for sol-thread.o.
+ Add rule for linux-thread.o.
+
+1999-08-13 Jim Kingdon <kingdon@redhat.com>
+
+ Threads code from gdb 4.18-codefusion-990706
+ [Thanks to Eric Paire, H. J. Lu, Jim Blandy and others]
+ * infrun.c (signal_stop_update, signal_print_update,
+ signal_pass_update): new functions.
+ * inferior.h: new prototypes for above functions.
+ * target.h (enum strata): add thread stratum.
+ * linux-thread.c: new file. Support for debugging linux threads.
+ * config/i386/nm-linux.h: several new prototypes for above.
+ * config/i386/linux.mh: add linux-thread.o to NATDEPFILES.
+
+ More threads code from the same place:
+ * config/i386/tm-linux.h (REALTIME_LO, REALTIME_HI): Add
+ definitions.
+ * target.h (enum target_signal): Add TARGET_SIGNAL_REALTIME_32.
+ * target.c (signals, target_signal_from_host,
+ target_signal_to_host): Add clauses for
+ TARGET_SIGNAL_REALTIME_32.
+
+1999-08-31 Neil Schellenberger <neil.schellenberger@crosskeys.com>
+
+ * sol-thread.c (sol_thread_detach): strip thread-id out of
+ inferior_pid, so that procfs_detach can't choke on it.
+
+1999-08-31 J.T. Conklin <jtc@redback.com>
+
+ * i386-stub.c, m32r-stub.c, m68k-stub.c, sh-stub.c, sparc-stub.c,
+ sparcl-stub.c, sparclet-stub.c (getpacket): Remove 'buffer' arg,
+ define it as a pointer to &remcomInBuffer[0].
+ (handle_exception): Update.
+
+ * sparc-stub.c, sparcl-stub.c, sparclet-stub.c (handle_exception):
+ Removed #ifdef'd out code which implements the non-standard 'b'
+ (set baud rate) command.
+
+1999-08-31 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infrun.c (keep_going): New function, broken out from the
+ keep_going label in handle_inferior_event.
+ (handle_inferior_event): Change more gotos into function calls.
+
+Tue Aug 31 02:29:27 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppa-tdep.c (read_unwind_info): Handle multiple unwind sections.
+
+Tue Aug 31 15:28:44 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/alpha/tm-alpha.h (PRINT_EXTRA_FRAME_INFO): Fix printf
+ format argument.
+ * alpha-tdep.c (heuristic_proc_start): Ditto.
+
+ From Stan Shebs <shebs@andros.cygnus.com>:
+ * defs.h (strlen_paddr): Fix prototype - add void argument list.
+
+Tue Aug 31 14:02:12 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (gdb_print_host_address), utils.c
+ (gdb_print_host_address): Rename gdb_print_address.
+
+ * expprint.c, gdbtypes.c, symmisc.c: Update.
+
+ *expprint.c: Use gdb_print_host_address when displaying native
+ pointers.
+
+Sat Aug 28 14:23:29 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * scm-valprint.c (scm_ipruk), jv-valprint.c (java_value_print),
+ cp-valprint.c (cp_print_class_member), exec.c (exec_files_info),
+ remote.c (putpkt_binary, compare_sections_command,
+ remote_cisco_section_offsets), dcache.c (dcache_info),
+ breakpoint.c (break_at_finish_at_depth_command_1,
+ break_at_finish_command_1), symfile.c (generic_load),
+ (report_transfer_performance), top.c (get_prompt_1), f-valprint.c
+ (f_val_print), maint.c (maintenance_translate_address): Fix printf
+ -Wformat warnings. Use paddr, paddr_nz, sizeof_paddr, paddr_u and
+ paddr_d to print addresses. Change ``d'' to ``ld''.
+
+ * utils.c (strlen_paddr): New function.
+
+Tue Aug 31 01:36:44 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/d30v/tm-d30v.h (d30v_frame_chain,
+ d30v_init_frame_pc): Add declaration.
+
+ * arc-tdep.c (arc_pop_frame): Rename pop_frame.
+ (arc_push_dummy_frame): Rename push_dummy_frame.
+ (arc_set_cpu_type_command): Add declaration.
+
+ * config/arc/tm-arc.h (arc_pop_frame, arc_push_dummy_frame): Add
+ declaration.
+
+1999-08-30 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infrun.c (prepare_to_wait): New function, broken out from the
+ wfi_continue label in handle_inferior_event.
+ (handle_inferior_event): Change more gotos into function calls.
+
+1999-08-30 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * tracepoint.c: -Wall warning cleanup.
+ (parse_and_eval_memrange): remove (unused).
+ (output_command, args_info, locals_info, registers_info): add decls.
+ (getpkt, putpkt, remote_console_output): add decls.
+ (isalnum, isspace): cast arg to avoid warning.
+ (printf, fprintf, sprintf): use [fs]printf_vma for printing addrs.
+
+Mon Aug 30 21:47:58 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c: #include "language.h".
+
+Mon Aug 30 20:38:57 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (AC_CHECK_HEADERS): Check for <time.h>.
+ * configure, acconfig.in: Re-generate.
+
+ * remote-rdp.c: #include <time.h>
+
+ * config/arm/tm-arm.h (arm_float_info): Add declaration.
+
+ * arm-tdep.c (convert_from_extended, convert_to_extended): Change
+ double ptr arg to void ptr arg.
+
+ * config/arm/tm-arm.h (arm_frameless_function_invocation): Add
+ declaration.
+ (arm_frame_find_saved_regs): Rename frame_find_saved_regs.
+ (convert_from_extended, convert_to_extended): Add declaration.
+
+Mon Aug 30 19:05:32 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (WERR_CFLAGS): Separate the -Werror flag.
+ * configure: Re-generate.
+
+ * Makefile.in (INTERNAL_CFLAGS): Re-define using
+ INTERNAL_WARN_CFLAGS.
+ (INTERNAL_WARN_CFLAGS): Define. Leave off WERR_CFLAGS.
+ (tracepoint.o): Add explicit rule.
+ (WERR_CFLAGS): Add definition.
+
+Mon Aug 30 17:52:17 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * utils.c: #include "event-loop.h" for declaration of
+ async_request_quit.
+ * Makefile.in (utils.o): Add dependency on event-loop.h.
+
+ * event-top.c (mark_async_signal_handler_wrapper,
+ async_request_quit): Move declaration from here.
+ * event-loop.h: To here.
+
+ * defs.h: Add declaration of exec.c:exec_set_section_offsets.
+
+ * event-top.c: #include "gdbcmd.h" which includes "command.h" and
+ hence expose declaration of function dont_repeat.
+
+ * top.c (ISATTY), tracepoint.c (ISATTY), utils.c (ISATTY),
+ event-top.c (ISATTY): Move definitions from here.
+ * defs.h (ISATTY): To here. #include <unistd.h>.
+
+ * sol-thread.c, solib.c, source.c, sparcl-tdep.c, tracepoint.c,
+ utils.c, win32-nat.c, wince.c, top.c, symfile.c, ser-unix.c,
+ ser-tcp.c, procfs.c, maint.c, infttrace.c, hppa-tdep.c,
+ ser-pipe.c, remote-rdp.c, main.c, inftarg.c, inflow.c,
+ hpux-thread.c, hp-psymtab-read.c, go32-nat.c, fork-child.c,
+ corelow.c, command.c: Do not #include <unistd.h>, moved to defs.h.
+
+Mon Aug 30 15:14:43 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (struct tui_stream, enum streamtype): Move from here.
+ * utils.c: To here.
+
+ * main.c (tui_file_fputs): Move from here.
+ * utils.c: To here.
+
+Sun Aug 29 10:03:32 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb-events.h, gdb-events.c, gdb-events.sh: New files.
+
+1999-08-27 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * solib.c (open_symbol_file_object): new function.
+ Called when attaching to a new process, if there is no loaded
+ symbol file. Attempts to locate the executable file for the
+ attached process and load symbols from it.
+ (solib_add): Call open_symbol_file_object if attaching to a
+ new process and no open symbol file.
+
+1999-08-27 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * config/i386/tm-sun386.h (GDB_TARGET_IS_SUN386): Definition
+ removed--no longer checked anywhere in gdb.
+
+1999-08-27 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infrun.c (stop_stepping): New function, broken out from
+ stop_stepping label in handle_inferior_event.
+ (handle_inferior_event): Change gotos into function calls.
+
+Fri Aug 27 20:13:22 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (LONGEST): Move definition to earlier in file - to just
+ after BFD.
+ (paddr_u, paddr_d): Declare.
+ * utils.c (decimal2str): New function.
+ (paddr_u, paddr_d): Define.
+
+ * remote.c (remote_cisco_section_offsets,
+ compare_sections_command): Fix XprintfX arguments. Use paddr...
+ (putpkt_binary): Fix XprintfX arguments.
+
+Tue Aug 24 21:30:36 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * arm-tdep.c (arm_init_extra_frame_info): Add braces. Recommended
+ by gcc -Wparentheses.
+
+1999-08-26 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infrun.c (check_sigtramp2): New function, broken out from
+ check_sigtramp2 label in handle_inferior_event.
+ (handle_inferior_event): Change gotos into function calls.
+
+ Declare Tahoe configuration obsolete.
+ * configure.host, configure.tgt: Comment out Tahoe configs.
+ * Makefile.in: Comment out Tahoe-related action.
+ * tahoe-tdep.c, config/tahoe/*: Comment out.
+ * NEWS: Mention obsolete status.
+
+1999-08-26 J.T. Conklin <jtc@redback.com>
+
+ * i386-stub.c, m32r-stub.c, m68k-stub.c, sh-stub.c, sh-stub.c,
+ sparc-stub, sparcl-stub.c sparclet-stub.c (getpacket): If '$',
+ the packet start character is received in the 'middle' of a
+ packet, assume that packet end character has been lost and
+ start a new packet.
+
+ * i386-stub.c, m32r-stub.c, m68k-stub.c, sh-stub.c, sparc-stub.c,
+ sparcl-stub.c sparclet-stub.c (getpacket): Changed to return ptr
+ to first character of input buffer. Removed & 0x7f masks.
+ (handle_exception): Don't access remcomInBuffer directly.
+
+1999-08-25 Stan Shebs <shebs@andros.cygnus.com>
+
+ * breakpoint.c (disable_breakpoints_in_shlibs): Only disable
+ enabled breakpoints.
+
+Tue Aug 24 14:59:23 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * tracepoint.c, remote.c, pa64solib.h, value.h, somsolib.h,
+ solib.h, scm-lang.h, language.h, inferior.h, defs.h, coff-solib.h,
+ ch-lang.h, breakpoint.h, annotate.h: Remove #if __STDC__ wrapping
+ struct declarations.
+
+ * config/sparc/nm-sun4sol2.h, config/mn10300/tm-mn10300.h,
+ config/mn10200/tm-mn10200.h, config/i386/tm-i386.h,
+ config/i386/tm-i386v.h, config/i386/nm-i386sol2.h,
+ config/pa/nm-hppah.h, config/rs6000/nm-rs6000.h,
+ config/sparc/tm-sp64.h, config/v850/tm-v850.h,
+ config/tic80/tm-tic80.h, config/sparc/tm-sparc.h,
+ config/sh/tm-sh.h, config/rs6000/tm-rs6000.h, config/pa/tm-hppa.h,
+ config/mips/tm-mips.h, config/m68k/tm-m68k.h,
+ config/m32r/tm-m32r.h, config/i960/tm-mon960.h,
+ config/fr30/tm-fr30.h, config/h8300/tm-h8300.h,
+ config/arm/tm-arm.h, config/alpha/tm-alpha.h,
+ config/a29k/tm-a29k.h: Ditto.
+
+Wed Aug 25 10:45:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (gdb$(EXEEXT)): Add dependency on TDEPLIBS.
+
+ * config/arm/arm.mt (TDEPLIBS): Define. Move libangsd.a to here.
+ (TDEPFILES): From here.
+
+1999-08-24 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * top.c (init_main): Add new set/show command exec-done-display,
+ default value is off.
+ * event-loop.h: Export exec_done_display_p.
+ * event-top.c: New variable exec_done_display_p.
+ * infrun.c (complete_execution): Print completion message if
+ corresponding flag is set.
+
+ * top.c (DEFAULT_PROMPT): Add space after "(gdb)" at end of prompt.
+
+ From: J.T. Conklin <jtc@redback.com>
+ * top.c (DEFAULT_PROMPT): Set to "(gdb)" if not already defined.
+ (init_main): Always use DEFAULT_PROMPT.
+
+Tue Aug 24 03:23:31 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppa-tdep.c: Remove useless "purecov: deadcode" comments.
+ (hppa_use_struct_convention): Update for PA64.
+ (hppa_frame_saved_pc): Properly extract the saved PC in a call
+ dummy frame.
+ (in_solib_call_trampoline): Return nonzero if we are in a function
+ called ".stub".
+ (prologue_inst_adjust_sp): Handle std,ma.
+ (skip_prologue_hard_way): Handle more PA2.0/PA64 insns.
+ (hppa_frame_find_saved_regs): Similarly. Handle indirect save of
+ %r3 into the stack.
+
+ * config/pa/tm-hppa64.h (CALL_DUMMY_BREAKPOINT_OFFSET_P): Define.
+ (CALL_DUMMY_BREAKPOINT_OFFSET): Define.
+
+Tue Aug 24 14:59:23 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (gdb$(EXEEXT)): Add dependency on main.o that was
+ lost when libgdb.a was added.
+
+Tue Aug 24 14:26:34 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.c, gdbarch.h: Convert to pure ISO-C.
+
+ * gdbarch.sh: New file.
+ * gdbarch.c, gdbarch.h: Add note describing gdbarch.sh
+
+Mon Aug 23 19:36:17 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (libgdb.a): New target.
+ (gdb$(EXEEXT)): Add dependency on libgdb.a.
+ (libgdb-files, LIBGDB_OBS, libgdb, LIBGDBDEPS, LIBGDBFILES): Delete.
+
+Mon Aug 23 10:16:32 1999 Jeffrey A Law (law@cygnus.com)
+
+ * infttrate.c (child_pid_to_exec_file): Find the correct base
+ of the stack for PA64.
+
+ * pa64solib.c: Fix some minor whitespace problems.
+ (bfd_lookup_symbol): New function.
+ (pa64_solib_create_inferior_hook): Find the address __dld_break
+ in the dynamic linker. Try to set a shlib event breakpoint in
+ that function.
+ (add_to_solist): Do not add the same shared library to the shlib
+ list more than once.
+
+Sun Aug 22 14:49:40 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * value.h (enum lval_type): Move declaration from here.
+ * defs.h (enum lval_type): To here.
+ * frame.h, gdbarch.h: Delete incomplete declaration of ``enum
+ lval_type''.
+
+1999-08-20 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * breakpoint.c (can_use_hardware_watchpoint): reject expressions
+ that refer to registers or register variables.
+
+Fri Aug 20 10:53:38 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppa-tdep.c (hppa_fix_call_dummy): Provide PA2.0W aware code.
+
+ * pa64solib.c pa64solib.h: New files.
+
+ * config/pa/hppa64.mt: Delete commented out code that is and
+ never will be appropriate for this target.
+ * config/pa/hpux11w.mt (TDEPFILES): Remove SOM references. Also
+ remove pa64solib.o.
+ * config/pa/hpux11w.mh (NATDEPFILES): Remove SOM references.
+
+ * configure.host; Use "hpux11w" and "hpux11" instead of
+ "hpux1100w" and "hpux1100" respectively
+ * config/pa/hpux11w.mh: Renamed from hpux1100w.mh.
+ * config/pa/hpux11w.mt, config/pa/hpux11.mh: Likewise.
+ * config/pa/hpux11.mt: Likewise.
+
+1999-08-19 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * breakpoint.h (target_hw_bp_type): new enum.
+ * breakpoint.c (insert_breakpoints): use enum instead of consts.
+ (remove_breakpoint): use enum instead of consts.
+ (throughout): use "warning" instead of "fprintf(stderr, ..."
+ [Also clean up a bunch of excessively long lines.]
+
+1999-08-19 J.T. Conklin <jtc@redback.com>
+
+ * i386-stub.c (waitabit): Removed.
+ (breakpoint): Update.
+
+ * i386-stub.c, m32r-stub.c, sparc-stub.c, sparcl-stub.c,
+ sparclet-stub.c (set_debug_traps): Don't send gratuitous ACK.
+
+ * m68k-stub.c (putpacket): Restore code so that packets are sent
+ until an ACK is received.
+
+1999-08-19 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * breakpoint.c (bpstat_stop_status): Accept triggered addresses
+ anywhere inside the region occupied by a watched variable as a
+ sign that the watchpoint fired. Don't stop if some watchpoint
+ was triggered, but its address doesn't match the address of this
+ watchpoint.
+ (TARGET_REGION_OK_FOR_HW_WATCHPOINT): New macro.
+ Default definition is to call TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT.
+ (can_use_hardware_watchpoint): Call TARGET_REGION_OK_FOR_HW_WATCHPOINT;
+ if it returns zero, return zero immediately.
+ (insert_breakpoints): Try to insert watchpoints for all the values
+ on the value chain, even if some of them fail to insert. Remove
+ the breakpoint if parts of its value chain couldn't be inserted.
+
+1999-08-19 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c (go32_stopped_by_watchpoint): Remove unused code.
+
+1999-08-19 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c (tcgetpgrp, tcsetpgrp): New functions.
+
+1999-08-19 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c (go32_wait): If we are in a single-step mode, and the
+ next instruction is INT nn or INTO, use a temporary breakpoint to
+ simulate single-step mode, and reset the trace flag.
+
+1999-08-19 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c (wp_op): New typedef.
+ (SHOW_DR): Print the length of watched region as well.
+ (go32_insert_aligned_watchpoint): Remove unused argument PID. All
+ callers and the prototype changed.
+ (go32_handle_nonaligned_watchpoint): Renamed from
+ go32_insert_nonaligned_watchpoint. Now handles all operations on
+ non-aligned watchpoints: insertion, deletion, and counting. If
+ called with wp_count as the first argument, return the count of
+ debug registers needed to watch the region. Don't break out of
+ the loop before all the addresses in the region are processed.
+ (go32_remove_watchpoint): Call go32_remove_aligned_watchpoint to
+ do the actual work.
+ (go32_remove_aligned_watchpoint): New function, modeled after
+ go32_insert_aligned_watchpoint. Removes watchpoints that watch
+ regions of arbitrary length by calling
+ go32_handle_nonaligned_watchpoint as needed.
+ (go32_region_ok_for_watchpoint): New function, called from
+ can_use_hardware_watchpoint via the new macro
+ TARGET_REGION_OK_FOR_HW_WATCHPOINT.
+
+ * config/i386/nm-go32.h (TARGET_REGION_OK_FOR_HW_WATCHPOINT):
+ Define to call go32_region_ok_for_watchpoint.
+ (DECR_PC_AFTER_HW_BREAK): Define back to zero (previous redefinition
+ to 1 was due to a bug in go32-nat.c).
+
+1999-08-19 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c (cleanup_dregs): New function.
+ (go32_mourn_inferior): Call it.
+ (IS_REG_FREE, LOCAL_ENABLE_REG, GLOBAL_ENABLE_REG, DISABLE_REG,
+ SET_BREAK, SET_WATCH, IS_WATCH, WATCH_HIT): Protect arguments with
+ parentheses.
+ (SET_BREAK): Increment the debug register's reference count.
+ (DR_DEF): New macro, returns the access and length bits of the
+ breakpoint.
+ (SHOW_DR): Print the reference count of each register. Disable or
+ enable print-out depending on an environment variable GDB_SHOW_DR.
+ (go32_insert_aligned_watchpoint): Look for an occupied debug
+ register with the same address and access/length bits, and reuse
+ it by incrementing reference the count, before occupying another
+ register. Return zero upon success.
+ (go32_insert_nonaligned_watchpoint): Pass the read/write bits to
+ go32_remove_watchpoint.
+ (go32_remove_watchpoint): Accept an additional parameter: the
+ read/write bits of the watchpoint to remove, and only remove a
+ watchpoint if it's occupied and its address and read/write bits
+ match. Only disable the register if its reference count is zero;
+ otherwise just decrease the reference count.
+ (go32_remove_hw_breakpoint): Only decrease reference count and
+ disable the debug register if it is occupied and its access bits
+ match those of an instruction breakpoint.
+ (go32_insert_hw_breakpoint): Before occupying another debug
+ register, look for an already occupied register that defines an
+ instruction breakpoint with the same address. If found, increment
+ its reference count. Call SHOW_DR even if failed to insert a
+ breakpoint.
+
+ * config/i386/nm-go32.h (target_remove_watchpoint): Accept the
+ TYPE argument as well.
+
+Wed Aug 18 17:47:25 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c: Add more comments.
+
+1999-08-17 Stan Shebs <shebs@andros.cygnus.com>
+
+ * blockframe.c: Don't use PARAMS anymore, remove obsolete comment
+ about frameless functions.
+
+1999-08-16 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * thread.c (delete_thread): delete any step_resume breakpoint
+ held by the thread. (prune_threads): call delete_thread.
+ * breakpoint.c (breakpoint_init_inferior): if startup, then
+ delete any remaining step_resume breakpoints.
+ * infrun.c (handle_inferior_event): add cautionary comment.
+
+1999-08-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * remote.c (remote_async_mourn): New function. Async version of
+ remote_mourn().
+
+1999-08-16 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * terminal.h [__GO32__]: Remove conditional; DJGPP now supports
+ termios.
+
+1999-08-16 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * command.c (CANT_FORK) [__MSDOS__]: Define.
+ (shell_escape) [CANT_FORK]: If ARG is NULL, pass an empty string
+ to `system'.
+ [__DJGPP__]: Return to the original directory after the shell
+ exits.
+
+1999-08-16 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/i386/xm-go32.h (ROOTED_P): Don't reference X[1] if X[0]
+ is a null character.
+
+ * config/i386/nm-go32.h (DECR_PC_AFTER_HW_BREAK): Define to 1.
+
+1999-08-16 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c (redir_cmdline_parse, redir_cmdline_delete,
+ redir_to_child, redir_to_debugger, redir_debug_init)
+ [__DJGPP_MINOR__ < 3]: Dummy stubs for redirecting debuggee's
+ standard handles.
+ (print_387_status): Print "last FP instruction", not "last
+ exception". Restore the upper 5 bits of the opcode that aren't
+ stored in the FPU state. Print the FPU stack in its physical
+ order, not relative to ST(0). Print "special", not "trap" for
+ unnormals and infinities. Print all 10 bytes of each FP register,
+ and print them with 19 significant digits.
+ (regno_mapping): Make the mapping consistent with tm-go32.h.
+ (sig_map): Add mappings for SIGQUIT, SIGFPE, SIGALRM. Map NMI to
+ SIGBUS.
+ (excep_map): New variable, maps GDB signals to DJGPP exceptions.
+ (go32_attach): Signal an error: we cannot attach to other
+ processes.
+ (go32_resume): Record the signal with which the inferior should be
+ resumed, mapped to the DJGPP exception number.
+ (go32_wait): Pass the signal recorded in go32_resume to the
+ debuggee. Save and restore debugger's and debuggee's current
+ working directory.
+ [__DJGPP_MINOR__ < 3]: Save and restore inferior's FPU state.
+ (store_register): FPU regsiters have numbers less than 31.
+ (go32_kill_inferior): Delete the parsed command-line storage.
+ (go32_create_inferior): Initialize the parsed command-line
+ storage. Parse the command line and create the redirections for
+ inferior's standard handles.
+ [__DJGPP_MINOR__ < 3]: Init the inferior's FPU state.
+ (ignore2): Function deleted.
+ (device_mode): New function, switches a character device between
+ raw and cooked mode.
+ (go32_terminal_init): Invalidate the raw/cooked mode information.
+ (go32_terminal_info): Print whether the inferior's terminal is in
+ raw or cooked mode.
+ [__DJGPP_MINOR__ > 2]: Say if standard handles are redirected or
+ closed by the inferior.
+ (go32_terminal_inferior): Switch standard handles to the
+ inferior's files/devices. Put the inferior's input device to
+ raw/cooked mode, exactly like we found it last time.
+ (go32_terminal_ours): Restore debugger's standard handles and put
+ the terminal into cooked mode. Save the mode of inferior's input
+ device.
+ (init_go32_ops): Assign go32_ops.to_attach,
+ go32_ops.to_terminal_info, go32_ops.to_terminal_ours_for_output.
+ Initialize inferior's cwd and the command-line storage.
+
+Mon Aug 16 14:29:30 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/pa/tm-hppa.h (ARGS_GROW_DOWNWARD): Define.
+ * config/pa/tm-hppa64.h (ARGS_GROW_DOWNWARD): Undefine.
+ * hppa-tdep.c (hppa_push_arguments): Handle arguments growing in
+ both directions depending ARGS_GROW_DOWNWARD.
+ (hppa_find_saved_regs): Update for 64bit wide registers & pointers
+ and PA64 ABI.
+
+ * hppa-tdep.c (hppa_pop_frame): Various fixes for 64bit wide
+ registers and pointers.
+ (hppa_fix_call_dummy, skip_trampoline_code): Likewise.
+ (restore_pc_queue): Update tests for width of memory loads.
+ (hppa_push_arguments): Delete version that was #if 0'd out.
+
+ * hppa-tdep.c (push_dummy_frame): Handle the new 64it ABI.
+ (find_dummy_frame_regs): Corresponding changes.
+
+ * hppa-tdep.c (read_unwind_info): Initialize obj_private->dp.
+ (internalize_unwinds): Improve test for when to use segment
+ relative code for unwinder bounds.
+ (rp_saved): Fix offset of saved return pointer for the 64bit ABI.
+ (hppa_frame_saved_pc): Various updates to handle 64bit registers
+ and pointers.
+ (frame_chain, restore_pc_queue): Likewise.
+
+ * hppa-tdep.c (rp_saved): RP is saved at frame-16 when
+ pointers are 64bits wide.
+
+ * hppa-tdep.c (record_text_segment_lowaddr): New function.
+ (internalize_unwinds): Use it if addressess are 8 bytes wide.
+
+ * symfile.c (syms_from_objfile): No longer warn if the lowest
+ section does not have SEC_CODE set.
+
+ * Makefile.in (pa64solib.o): Add dependencies.
+
+ * hppah-nat.c (store_inferior_registers): Do not try to write a
+ nonzero value to the high part of IPSW. Fix typo in unable to store
+ warning.
+
+ * config/pa/tm-hppa.h (opd_data structure): Delete. Not actually
+ needed.
+ (struct obj_private_struct): Add new entry for the objfile's DP
+ value.
+ * config/pa/tm-hppa64.h (CALL_DUMMY): Add a nop to make it an even
+ number of instructions. Pack the dummy into word sized hunks.
+ (CALL_DUMMY_LENGTH): Update appropriately.
+ (PC_IN_CALL_DUMMY, CALL_DUMMY_LOCATION_AFTER_TEXT_END): Delete.
+
+Mon Aug 16 19:08:19 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in: Try -lsocket when looking for socketpair.
+ * configure, config.h: Re-generate.
+
+1999-08-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Christopher Faylor <cgf@cygnus.com>:
+
+ * event-loop.c (gdb_wait_for_event): Before going to wait for
+ another event with select or poll, flush the error and the output
+ streams.
+
+ * event-top.c (gdb_readline2): Do not buffer the input, because
+ doing so can interfere with select/poll in bad ways.
+
+Fri Aug 13 17:36:56 1999 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * maint.c (maintenance_dump_me) [__DJGPP__]: Simulate a core dump
+ with SIGABRT.
+ * utils.c (quit) [__MSDOS__]: Don't mention SIGINT, since it's not
+ gonna happen.
+ (notice_quit): No need to define this function for the DJGPP port.
+
+1999-08-13 James Ingham <jingham@leda.cygnus.com>
+
+ * arm-tdep.c (arm_frameless_function_invocation): SKIP_PROLOGUE
+ macro no longer modifies its argument. Update uses to accord.
+
+ * config/arm/arm.mt (TDEPFILES): Add the remote-rdi.o to the
+ TDEPFILES.
+ * configure.tgt: Add rdi-share to configdir for the Arm targets.
+
+Fri Aug 13 11:16:32 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppah-nat.c (store_inferior_registers): Revamp to be PA2.0W
+ aware.
+
+ * infttrace.c (ttrace_write_reg_64): New function.
+
+ * hp-symtab-read.c (is_in_import_list): Delete extern declaration.
+ * somread.c (is_in_import_list): Delete function.
+ * objfiles.c (is_in_import_list): New function.
+ * objfiles.h (is_in_import_list): Declare.
+
+ * config/pa/tm-hppa64.h (GDB_TARGET_IS_HPPA20W): Define before
+ including tm-hppah.h.
+ (PC_IN_CALL_DUMMY): Define.
+ (HPUX_1100): Similarly.
+ * config/pa/tm-hppa.h (somsolib.h, pa64solib.h): Conditionalize
+ includes on GDB_TARGET_IS_HPPA20W.
+
+ * configure.host: Distinguish between wide and narrow modes
+ for hpux11.
+ * config/pa/hpux1100w.mh, config/pa/hpux1100w.mt: New files.
+
+ * config/pa/tm-hppa64.h (STACK_ALIGN): Redefine.
+ (REG_PARM_STACK_SPACE): Likewise.
+
+ * config/pa/tm-hppa.h (CLEAN_UP_REGISTER_VALUE): Handle 64bit
+ PA target correctly.
+ (REG_PARM_STACK_SPACE): Define.
+ (struct unwind_table_entry): region_start and region_end are
+ CORE_ADDRs.
+ (typedef opd_data): New.
+ (obj_private_data_t): Include pointer to opd_data structure.
+
+1999-08-13 Keith Seitz <keiths@cygnus.com>
+
+ * stabsread.c (stabsread_clear_cache): New funciton which clears
+ an optimization cache of the reader.
+
+ * coffread.c (coff_symfile_finish): Give stabs reader a chance to
+ clean up.
+
+ * win32-nat.c (handle_load_dll): Don't suppress re-reading symbols
+ from a DLL if an objfile for it already exists. (Not that this should
+ happen anymore anyway...)
+
+1999-08-13 Keith Seitz <keiths@cygnus.com>
+
+ * config/mcore/tm-mcore.h (SAVE_DUMMY_FRAME_TOS): Define for MCore,
+ which also requires that the stack pointer be saved for call
+ dummies BEFORE arguments get pushed onto it.
+
+1999-08-12 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Eli Zaretskii <eliz@is.elta.co.il>:
+ * source.c (mod_path) [_WIN32 || __DJGPP__]: Don't remove trailing
+ slash from "d:/". Don't overstep the beginning of name.
+ [_WIN32 || __MSDOS__]: Convert "d:" to "d:.", otherwise appending
+ a slash changes its meaning.
+ (openp): Use SLASH_P, not equality with SLASH_CHAR.
+ (print_source_lines_base) [CRLF_SOURCE_FILES]: Skip \r only before
+ a \n.
+ (forward_search_command) [CRLF_SOURCE_FILES]: Remove \r at the end
+ of all lines.
+ (reverse_search_command) [CRLF_SOURCE_FILES]: Likewise.
+
+ * gnu-regex.c (CHAR_CLASS_MAX_LENGTH): Don't use wide characters
+ unless HAVE_BTOWC is defined.
+
+Fri Aug 13 10:20:12 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From J.T. Conklin <jtc@redback.com>:
+ * gdbinit.in: Change the template .gdbinit to match the recent
+ fatal error handling change.
+
+1999-08-11 Keith Seitz <keiths@cygnus.com>
+
+ * maint.c (maintenance_internal_error): Fix typo in prototype.
+
+Wed Aug 11 15:38:05 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * remote.c (remote_rcmd): Pass an empty command across to the
+ target. Check for and handle an ``Enn'' return status.
+
+Tue Aug 10 13:59:45 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * maint.c (_initialize_maint_cmds): Add ``maintenance
+ internal-error'' command.
+ (maintenance_internal_error): New function.
+
+1999-08-10 James Ingham <jingham@leda.cygnus.com>
+
+ * top.c: Remove the disassembly_flavor_hook, use the new set_hook
+ instead.
+ * defs.h: Ditto.
+ * arm-tdep.c (set_disassembly_flavor_sfunc): Ditto.
+
+1999-08-10 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * config/i386/nm-i386sol2.h (FIND_NEW_THREADS): remove, obsolete.
+ * config/sparc/nm-sun4sol2.h (FIND_NEW_THREADS): remove, obsolete.
+
+1999-08-10 J.T. Conklin <jtc@redback.com>
+
+ * configure.tgt (i[3456]86-*-aout*, i[3456]86-*-coff*,
+ i[3456]86-*-elf*): Use embed.mt.
+ * config/i386/embed.mt: New file.
+
+1999-08-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * remote.c (remote_async_open_1): Remove casting in call to
+ add_file_handler.
+ (extended_remote_async_create_inferior): Ditto.
+
+ * event-top.c (change_line_handler): Ditto.
+ (_initialize_event_loop): Ditto.
+
+ * infrun.c (complete_execution): Ditto.
+
+ * event-loop.c (add_file_handler): Change proc parameter to be ptr
+ to func with void parameter, rather than void*. Coerce second
+ paramter in calls to create_file_handler. Replace
+ async_handler_func and file_handler_func with handler_func.
+
+ * event-loop.h: Get rid of typedefs for file_handler_func and
+ async_handler_func, just have one, and call it handler_func.
+ Replace async_handler_func and file_handler_func occurrences with
+ handler_func.
+
+Tue Aug 10 03:13:03 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppa-tdep.c: Delete random #if 0 code.
+ (is_branch): Handle new branching opcodes from PA2.0
+ (inst_saves_gr, inst_saves_fr): Handle additional instructions
+ used to save general and floating point registers in the stack.
+ (skip_prologue_hard_way): Handle additional instructions to
+ save the return pointer in the stack.
+ (after_prologue): Fix mis-guided and incorrect code to find
+ the end of the prologue using debug symbols.
+ (hppa_skip_prologue): Generally clean up comments, lose code
+ which does not apply to the PA, etc.
+
+Sun Aug 8 17:53:41 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * MAINTAINERS: Make Andrew Cagney the mn10300 maintainer.
+ Transfer responsibility for the PowerPC from Andrew Cagney to
+ Elena Zannoni.
+
+Tue Aug 10 13:59:45 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ Based on code from J.T. Conklin <jtc@redback.com>:
+ * utils.c (internal_error): Make quit? and coredump? separate
+ questions so that the user can dump-core and not quit.
+ (internal_error): Cleanup error message.
+
+1999-08-09 Tom Tromey <tromey@cygnus.com>
+
+ * kod-cisco.c (cisco_kod_open): Removed incorrect `arg' argument.
+
+Sun Aug 8 12:06:47 1999 Fred Fish <fnf@cygnus.com>
+
+ * coffread.c (process_coff_symbol): Remove section_offsets from
+ prototype and function definition. Get section_offsets from the
+ passed objfile and pass it on to callees the same way.
+ (coff_symtab_read): Ditto.
+ (coff_symfile_read): Ditto.
+ * dbxread.c (read_dbx_dynamic_symtab): Ditto.
+ (read_dbx_symtab): Ditto.
+ (dbx_symfile_read): Ditto.
+ (coffstab_build_psymtabs): Ditto.
+ (elfstab_build_psymtabs): Ditto.
+ (stabsect_build_psymtabs): Ditto.
+ * dstread.c (dst_symfile_read): Ditto.
+ * elfread.c (elf_symfile_read): Ditto.
+ * jv-class.c (jv_class_symfile_read): Ditto.
+ * mipsread.c (mipscoff_symfile_read): Ditto.
+ * nlmread.c (nlm_symfile_read): Ditto.
+ * os9kread.c (os9k_symfile_read): Ditto.
+ * somread.c (som_symfile_read): Ditto.
+ * stabsread.h (elfstab_build_psymtabs): Ditto.
+ * xcoffread.c (xcoff_initial_scan): Ditto.
+
+ * symfile.h (sym_read): Remove section_offsets from prototype.
+ * symfile.c (syms_from_objfile): Call sym_read without
+ section_offsets.
+ (reread_symbols): Ditto.
+
+ * elfread.c (elfstab_offset_sections): Use SIZEOF_SECTION_OFFSETS
+ to allocate sections offsets array.
+ * xcoffread.c (xcoff_symfile_offsets): Ditto.
+
+ * partial-stab.h (section_offsets): Get from objfile.
+ * dbxread.c (read_dbx_symtab): Fix typo that made -1 casted
+ to a CORE_ADDR look like an subtraction expression.
+ * objfiles.h: Add some comments.
+ * symfile.c: Add some comments.
+ * objfiles.c: Add some comments.
+ (objfile_relocated): Use ALL_OBJFILE_OSECTIONS to iterate over
+ sections.
+ (find_pc_sect_sections): Use ALL_OBJSECTIONS to iterate over all
+ sections in all objfiles.
+ * symfile.c (syms_from_objfile): Use ALL_OBJFILE_OSECTIONS.
+
+ * irix5-nat.c (symbol_add_stub): Fix typo that made taking the
+ address of lowest_sect with '&' look like a bitwise and op.
+ * osfsolib.c (symbol_add_stub): Ditto.
+ * solib.c (symbol_add_stub): Ditto.
+ * symfile.c (syms_from_objfile): Ditto.
+
+ * dwarf2read.c (dwarf2_build_psymtabs_hard): Minor format tweak.
+ * symfile.c (syms_from_objfile): Ditto, and fix typo.
+ * top.c (init_main): Fix typo in comment (DEFULAT_PROMPT).
+ * doc/gdbint.texinfo (find_sym_fns): This replaces symfile_init.
+
+1999-08-08 James Ingham <jingham@leda.cygnus.com>
+
+ * remote.c (remote_insert_breakpoint): Fix typo in Z packet support.
+ Also move Z packet support OUTSIDE of REMOTE_BREAKPOINT ifdef,
+ since this is not set for all targets that support the Z packet.
+
+Sun Aug 8 17:24:09 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ui-out.c (ui_out_table_begin, ui_out_table_body,
+ ui_out_table_end, ui_out_table_header, ui_out_list_begin,
+ ui_out_list_end, ui_out_stream_new, verify_field_proper_position,
+ verify_field_alignment): Replace incorrect calls to error with
+ calls to internal_error.
+
+Fri Aug 6 17:17:28 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (fatal): Delete declaration.
+ (internal_error): Declare.
+ * utils.c (nomem): Call internal_error instead of fatal.
+ (fatal_dump_core): Delete.
+ (malloc_botch): Print message direct to stderr.
+ (fatal): Delete definition.
+ * utils.c (internal_error): Define.
+
+ * gdbarch.h, gdbarch.c, hppah-nat.c, ch-exp.c, dsrec.c, sh-tdep.c,
+ infptrace.c, f-lang.c, symm-nat.c, top.c, m3-nat.c, v850-tdep.c,
+ remote-vx.c, remote-sim.c, remote-mips.c, source.c, infcmd.c,
+ findvar.c, remote.c: Replace fatal with call to internal_error.
+
+Sun Aug 8 15:28:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ser-pipe.c (STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO): Move
+ definition from here.
+ * defs.h: To here.
+
+Sat Aug 7 21:44:59 1999 Fred Fish <fnf@cygnus.com>
+
+ * remote.c (remote_insert_breakpoint): Fix typo, missing ';'.
+
+Sun Aug 8 11:26:57 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (mips_gdbarch_init): Add break; to the default case.
+
+Fri Aug 6 19:26:03 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h: Delete #if ANSI_PROTOTYPES code, GDB assumes ISO-C.
+ * remote-rdp.c (send_rdp), remote-os9k.c (printf_monitor),
+ remote-mips.c: (mips_error), remote-array.c: (printf_monitor,
+ debuglogs), complaints.c (complain), monitor.c:
+ (monitor_printf_noecho, monitor_printf), language.c (type_error,
+ range_error), remote-st.c: (printf_stdebug), remote-sim.c
+ (gdb_os_printf_filtered, gdb_os_vprintf_filtered,
+ gdb_os_evprintf_filtered, gdb_os_error), serial.c (serial_printf),
+ utils.c (warning, error, fatal, fatal_dump_core, (query,
+ fprintf_filtered, fprintf_unfiltered, fprintfi_filtered,
+ printf_filtered, printf_unfiltered, printfi_filtered): Delete
+ legacy #ifndef ANSI_PROTOTYPES varargs code.
+
+ * defs.h: Don't #include <varargs.h>.
+ * remote-rdp.c, remote-os9k.c, remote-mips.c, remote-array.c,
+ monitor.c, remote-st.c: Don't include <varargs.h> or <stdarg.h>.
+
+1999-08-06 James Ingham <jingham@leda.cygnus.com>
+
+ * configure.in, configure: add the --enable-multi-ice to determine
+ whether to configure and build the multi-ice-gdb-server. Note,
+ for now this only builds on cygwin, so don't enable it for other
+ platforms...
+
+1999-08-06 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (SFILES): Added kod.c and kod-cisco.c.
+ (COMMON_OBS): Added kod.o and kod-cisco.o.
+ (kod-cisco.o): New target.
+ (kod.o): New target.
+ * kod-cisco.c: New file.
+ * kod.c: New file.
+
+1999-08-06 James Ingham <jingham@leda.cygnus.com>
+
+ These are some fixups for the Arm, and support for the
+ disassembly-flavor for the ARM.
+
+ * defs.h: Declare the disassembly_flavor_hook
+ * top.c: Define the disassembly_flavor_hook
+ * i386-tdep.c: Remove unnecessary declaration of the
+ disassembly_flavor_hook.
+
+ * config/arm/tm-arm.h: Change definition of
+ arm_init_extra_frame_info.
+ Add a few more comments.
+ * arm-tdep.c (arm_init_extra_frame_info): Listen to and use the
+ fromleaf parameter passed into init_extra_frame_info.
+ (set_disassembly_flavor_sfunc): New Function.
+ (set_disassembly_flavor): New Function.
+ (arm_othernames): Use the set_disassembly_flavor.
+ (_initialize_arm_tdep): Setup the disassembly flavor commands, and
+ initialize the flavor.
+ (arm_frameless_function_invocation): Adjust for
+ frameless functions that have 1 or 2 instructions that mimic the
+ standard APCS form.
+ (arm_scan_prologue): Be more careful about scanning the function
+ prologue. Don't match things that just have a few of the prologue
+ instructions out of order, and don't get thrown by the scheduler
+ migrating instructions into the prologue.
+
+ Add support for the "Z" and "z" packets to request the stub
+ to set a breakpoint.
+
+ * remote.c (set_remote_protocol_Z_packet_cmd): New function.
+ (show_remote_protocol_Z_packet_cmd): New Function.
+ (remote_open_1): Init the Z packet config.
+ (remote_async_open_1): Init the Z packet config.
+ (remote_insert_breakpoint): Use the "Z" packet if supported.
+ (remote_remove_breakpoint): Use the "z" packet if supported.
+ (remote_insert_watchpoint): New Function - currently wired to
+ nothing.
+ (remote_remove_watchpoint): Ditto.
+ (remote_insert_hw_breakpoint): Ditto.
+ (remote_remove_hw_breakpoint): Ditto.
+
+1999-08-06 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infcmd.c: Include parser-defs.h.
+ (interrupt_target_command): Declare.
+ (stack_dummy_testing): Remove old funky flag.
+ (run_stack_dummy): Remove unused reference to old funky flag.
+
+1999-08-06 Tom Tromey <tromey@cygnus.com>
+
+ * command.c (do_setshow_command): Call set_hook if not NULL.
+ * top.c (set_hook): New hook definition.
+ * defs.h (set_hook): Declare.
+
+1999-08-05 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infrun.c: Convert code to pure standard C, elim some warnings.
+ (stopped_for_shlib_catchpoint): Remove, never used.
+
+1999-08-05 Keith Seitz <keiths@cygnus.com>
+
+ * NEWS: Mention new Motorola MCore target.
+
+ * sparc-tdep.c (gdb_print_insn_sparc): Print insns of the current
+ architecture.
+
+Thu Aug 5 20:41:22 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (configdirs): Add check for socketpair.
+ * configure, config.in: Re-generate.
+
+ From Mon Jul 19 10:46:18 1999 Philippe De Muyter <phdm@macqel.be>:
+ * ser-pipe.c (sys/wait.h): Include this file only #if HAVE_SYS_WAIT_H.
+ (STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO): Macros defined if needed.
+
+Thu Aug 5 20:04:17 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * target.c (debug_to_open, debug_to_attach, debug_to_post_attach,
+ debug_to_require_attach, debug_to_detach, debug_to_require_detach,
+ debug_to_wait, debug_to_post_wait, debug_to_fetch_registers,
+ debug_to_store_registers, debug_to_prepare_to_store,
+ debug_to_xfer_memory, debug_to_files_info,
+ debug_to_insert_breakpoint, debug_to_remove_breakpoint,
+ debug_to_terminal_init, debug_to_terminal_inferior,
+ debug_to_terminal_ours_for_output, debug_to_terminal_ours,
+ debug_to_terminal_info, debug_to_kill, debug_to_load,
+ debug_to_lookup_symbol, debug_to_create_inferior,
+ debug_to_post_startup_inferior,
+ debug_to_acknowledge_created_inferior,
+ debug_to_clone_and_follow_inferior,
+ debug_to_post_follow_inferior_by_clone,
+ debug_to_insert_fork_catchpoint, debug_to_remove_fork_catchpoint,
+ debug_to_insert_vfork_catchpoint,
+ debug_to_remove_vfork_catchpoint, debug_to_has_forked,
+ debug_to_has_vforked, debug_to_can_follow_vfork_prior_to_exec,
+ debug_to_post_follow_vfork, debug_to_insert_exec_catchpoint,
+ debug_to_remove_exec_catchpoint, debug_to_has_execd,
+ debug_to_reported_exec_events_per_exec_call,
+ debug_to_has_syscall_event, debug_to_has_exited,
+ debug_to_mourn_inferior, debug_to_can_run,
+ debug_to_notice_signals, debug_to_thread_alive, debug_to_stop,
+ debug_to_query, debug_to_rcmd, debug_to_enable_exception_callback,
+ debug_to_get_current_exception_event, debug_to_pid_to_exec_file,
+ debug_to_core_file_to_sym_file, debug_to_close): Send trace output
+ to ``gdb_stdlog'' instead of ``gdb_stderr''.
+
+Thu Aug 5 16:22:10 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (init_remote_ops): Initialize remote_ops.to_rcmd.
+ (init_remote_async_ops): Initialize remote_async_ops.to_query.
+ (remote_rcmd): New function.
+
+ * monitor.c (monitor_rcmd): Rename monitor_command.
+ (init_base_monitor_ops): Initialize monitor_ops.to_rcmd.
+ (_initialize_remote_monitors): Move "monitor" command from here.
+ * target.c (initialize_targets): To here.
+ (monitor_command): New function. Implement "monitor" command.
+
+ * target.c (cleanup_target): de_fault to_rcmd.
+ (update_current_target): INHERIT to_rcmd.
+ (debug_to_rcmd): New function.
+ (setup_target_debug): Initialize current_target.to_rcmd.
+
+ * target.h (struct target_ops): Add field to_rcmd.
+ (target_rcmd): Define.
+
+Thu Aug 5 14:24:07 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c: Replace comment describing remote protocol with
+ pointer to official document.
+
+Thu Aug 5 11:59:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (remote_protocol_binary_download): New variable.
+ Replace ``remote_binary_download'' and ``remote_binary_checked''.
+ (set_remote_protocol_binary_download_cmd,
+ show_remote_protocol_binary_download_cmd): New functions.
+ (remote_open_1, remote_async_open_1, remote_cisco_open):
+ Initialize ``remote_protocol_binary_download'' instead of
+ ``remote_binary_download''.
+ (check_binary_download): Re-write.
+ (remote_write_bytes): Ditto.
+ (_initialize_remote): Add ``set remote X-packet'' and ``show
+ remote X-packet'' commands. Disable old ``set
+ remotebinarydownload'' command.
+
+1999-08-04 Keith Seitz <keiths@cygnus.com>
+
+ * remote-rdi.c (arm_rdi_close): Close the transport device, too.
+
+Wed Aug 4 10:42:58 1999 Fred Fish <fnf@cygnus.com>
+
+ * xcoffread.c (scan_xcoff_symtab): Change main_aux into
+ an array of 5 internal_auxent to leave room for bfd to
+ write n_numaux entries. Change code to use the first one.
+
+Wed Aug 4 19:58:15 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ui-out.h (cli_out_new): Move declaration from here.
+ * cli-out.h: To here. New file.
+ * Makefile.in (ui-out.o): Add missing dependencies.
+ (cli-out.o): Ditto.
+ * top.c, cli-out.c: #include "cli-out.h".
+
+1999-08-02 Stan Shebs <shebs@andros.cygnus.com>
+
+ * c-valprint.c (c_val_print): When printing decimal equivalent
+ of a char, cast appropriately.
+
+1999-08-02 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Jonathan Larmour <jlarmour@cygnus.co.uk>:
+ * main.c (print_gdb_help): Use gdbinit variable to determine file
+ name used for --nx help
+
+1999-08-01 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * config/mips/tm-mips.h (BIG_ENDIAN): Don't define here.
+
+1999-08-01 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * stabsread.c (read_range_type): Handle an unsigned range type
+ whose length in bytes is any power of two, not just a few
+ common ones.
+
+ * monitor.c (monitor_expect): When we receive a character that
+ isn't part of the string we were expecting, don't just start
+ matching again at the beginning of the string --- some shorter
+ suffix of the input might be a prefix of the string too.
+
+1999-07-31 Fred Fish <fnf@cygnus.com>
+
+ * symfile.c (symbol_file_command): Fix typo that made -1 casted
+ to a CORE_ADDR look like an subtraction expression.
+ (add_symbol_file_command): Ditto.
+
+1999-07-30 Jim Blandy <jimb@cygnus.com>
+
+ * hppa-tdep.c (pa_print_registers): Frob register output some more.
+
+1999-07-29 Jim Blandy <jimb@cygnus.com>
+
+ * config/pa/nm-hppah.h (PTRACE_ARG3_TYPE): After more
+ consideration, make this a CORE_ADDR, like WDB did.
+
+ Rather than casting every single use of really_free_pendings to
+ make_cleanup_func, why not actually make it have that type? Golly!
+ * buildsym.c (really_free_pendings): Change argument type to PTR.
+ buildsym.h (really_free_pendings): Fix declaration.
+ * dbxread.c (dbx_symfile_read, dbx_psymtab_to_symtab_1),
+ dwarf2read.c (psymtab_to_symtab_1), dwarfread
+ (psymtab_to_symtab_1), hp-psymtab-read.c (hpread_build_psymtabs),
+ os9kread.c (os9k_symfile_read, os9k_psymtab_to_symtab_1),
+ xcoffread.c (xcoff_psymtab_to_symtab_1, xcoff_initial_scan):
+ Remove casts.
+
+ Pass a CORE_ADDR safely through catch_errors.
+ * hppa-tdep.c (args_for_find_stub): New member, return_val.
+ (cover_find_stub_with_shl_get): Change argument and return type to
+ match catch_errors. Save return value of find_stub_with_shl_get
+ in *args.
+ (initialize_hp_cxx_exception_support): Collect value of
+ eh_notify_callback_addr from args.
+
+ Get rid of some noise. It would be nice to get helpful warnings
+ from the compiler about lossy conversions.
+ * hppa-tdep.c (eh_notify_hook_addr, eh_notify_callback_addr,
+ eh_break_addr, eh_catch_catch_addr, eh_catch_throw_addr,
+ break_callback_sal): Initialize these to zero, not NULL, to shush
+ warnings.
+ * infttrace.c (thread_fake_step): Compare signal to
+ TARGET_SIGNAL_0, not NULL, to avoid warnings.
+ (_initialize_infttrace): Add sanity check.
+
+ * config/pa/nm-hppah.h (PTRACE_ARG3_TYPE): Define this to be
+ long, so we can pass arguments properly to ptrace.
+
+ * hppah-nat.c (child_xfer_memory): Correctly compute mask to round
+ address to an int boundary.
+
+1999-07-29 Jim Blandy <jimb@cygnus.com>
+
+ Change from Ian Lance Taylor <ian@zembu.com>. The
+ i386_linux_sigtramp* functions should be moved to
+ i386-linux-tdep.c, when that file is introduced.
+
+ * config/i386/tm-linux.h (LINUX_SIGCONTEXT_SIZE): Define.
+ (LINUX_SIGCONTEXT_PC_OFFSET): Define.
+ (LINUX_SIGCONTEXT_SP_OFFSET): Define.
+ (SIGCONTEXT_PC_OFFSET): Don't define.
+ (I386_LINUX_SIGTRAMP): Define.
+ (IN_SIGTRAMP): Define.
+ (i386_linux_sigtramp): Declare.
+ (sigtramp_saved_pc): Define.
+ (i386_linux_sigtramp_saved_pc): Declare.
+ (FRAMELESS_SIGNAL): Define.
+ (FRAME_CHAIN, FRAME_SAVED_PC): Define after #undef.
+ * i386-tdep.c (i386_linux_sigtramp_start): New static function if
+ I386_LINUX_SIGTRAMP.
+ (i386_linux_sigtramp): New function if I386_LINUX_SIGTRAMP.
+ (i386_linux_sigtramp_saved_pc): Likewise.
+ (i386_linux_sigtramp_saved_sp): Likewise.
+
+1999-07-28 Jim Blandy <jimb@cygnus.com>
+
+ * infrun.c (handle_inferior_event): Don't try to use the code for
+ stepping over a function call to also handle stepping out of a
+ sigtramp on HP-UX. That ends up trashing step-resume breakpoints.
+ This change reverts some of David Taylor's change of 31 Dec 1998.
+ The HP-UX maintainer needs to submit a new change for whatever
+ problem the original change was trying to fix.
+
+1999-07-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-top.c (command_line_handler): Don't treat an empty line
+ from readline the same way as a multiline command. This avoids
+ missing detecting when the user presses just 'enter'.
+
+1999-07-28 Jim Blandy <jimb@cygnus.com>
+
+ Provide more sanity checking:
+ * infrun.c (handle_inferior_event): Before assigning a new
+ breakpoint to step_resume_breakpoint, make sure it's not already
+ pointing at one; if it is, that's a bug.
+ (check_for_old_step_resume_breakpoint): New function.
+
+1999-07-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Eli Zaretskii <eliz@is.elta.co.il>:
+ * top.c (gdb_init) [__MSDOS__]: Arrange for GDB to return to the
+ original directory before exiting.
+ (cd_command) [_WIN32 || __MSDOS__]: Canonicalize the new directory
+ name explicitly. Handle "d:/" names correctly.
+ (init_history) [__MSDOS__]: Use _gdb_history as the default GDB
+ history file name.
+
+Mon Jul 26 17:13:39 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (enum packet_support, enum packet_detect, struct
+ packet_config): Define.
+ (set_packet_config_cmd, show_packet_config_cmd,
+ add_packet_config_cmd, init_packet_config): New functions.
+ Generic support for optional packets.
+ (remote_protocol_P): Replace stub_supports_P.
+ (set_remote_protocol_P_packet_cmd, show_remote_protocol_P_packet_cmd):
+ New functions.
+ (_initialize_remote): Add ``set remote-protocol-P-packet'' command.
+ (remote_open_1, remote_async_open_1, remote_cisco_open):
+ Initialize ``remote_protocol_P''.
+ (remote_store_registers): Re-write ``P'' probe logic.
+ (store_register_using_P): New function.
+
+ From Ian Lance Taylor <ian@airs.com>:
+ (remote_prepare_to_store): Only read registers when ``P'' packet
+ is in state unsupported or support-unknown.
+
+1999-07-24 Fred Fish <fnf@cygnus.com>
+
+ * symfile.c (default_symfile_offsets): Clear section_offsets
+ before filling it in.
+
+1999-07-16 Keith Seitz <keiths@cygnus.com>
+
+ * remote.c (_initialize_remote): "remotebreak" should be a var_boolean.
+
+1999-07-15 Jim Blandy <jimb@cygnus.com>
+
+ Make the output from "info registers" fit withinin 80 columns.
+ * hppa-tdep.c (pa_print_registers): Make it easy to change row and
+ column counts. Switch to three columns, instead of four, and
+ adjust spacing.
+
+ First cut at supporting HPPA2.0 in "wide" (64-bit) mode.
+ * configure.tgt: Add hppa2.0w target.
+ * config/pa/hppa64.mt, config/pa/tm-hppa64.h: New files.
+ * hppa-tdep.c (hppa_fix_call_dummy): Dyke out code to tweak the
+ call dummy, if target is PA2.0w. This is temporary, until I get
+ function calls working.
+ * hppah-nat.c (fetch_register): Rewritten to handle both narrow
+ and wide register requests.
+ (HPPAH_OFFSETOF): New macro.
+
+ * gdbtypes.c (is_integral_type): New function.
+ * gdbtypes.h: Prototype for above.
+
+1999-07-15 J.T. Conklin <jtc@redback.com>
+
+ * configure.tgt (i[3456]86-*-vxworks*): New target.
+ * config/i386/vxworks.mt: New file, x86 VxWorks target
+ * config/i386/tm-vxworks.h: New file.
+
+ * configure.tgt (powerpc-*-vxworks*): New target.
+ * config/powerpc/vxworks.mt: New file, PowerPC VxWorks target
+ * config/powerpc/tm-vxworks.h: New file.
+
+ * NEWS: Mention the new configs.
+
+1999-07-15 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * ui-out.c (struct ui_out): Remove deprecated fields.
+
+1999-07-15 Fernando Nasser <fnasser@cygnus.com>
+
+ * target.c (target_preopen): Prevent query when not from_tty.
+ * infcmd.c (run_command): Prevent query when not from_tty.
+
+1999-07-15 Fernando Nasser <fnasser@cygnus.com>
+
+ * event-loop.c: Fix typo in comment.
+
+1999-07-15 Fernando Nasser <fnasser@cygnus.com>
+
+ * breakpoint.c (breakpoint_1): Fix output when no breakpoins are
+ found.
+
+1999-07-15 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-top.c (display_gdb_prompt): Don't do anything if we are
+ running under the interpreter.
+
+Wed Jul 14 17:29:31 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ser-pipe.c (struct pipe_state): Define.
+ (pipe_close): Retain the PID of the sub-process using ``struct
+ pipe_state''. Delete #ifdef code that used popen().
+ (pipe_close): Kill of the sub-process as part of the cleanup.
+
+ * serial.h (struct _serial_t): Add field ``state''.
+
+1999-07-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-top.c (display_gdb_prompt): Don't display the prompt if we
+ are in the middle of an execution command. Also trick readline so
+ it doesn't try to display the prompt.
+ (command_line_handler): Get rid of change_prompt, unused variable.
+ Use {push, pop}_prompt mechanism in case of multiline commands.
+
+ * infrun.c (complete_execution): Set target_executing to 0 as
+ first thing, so that display_gdb_prompt does the right thing.
+
+Tue Jul 13 20:29:46 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * parse.c (build_parse): Fix conditional increment of num_std_regs
+ for SP_REGNUM. Was conditional on FP_REGNUM.
+
+Tue Jul 13 16:44:58 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h, gdbarch.c: Revert 1999-07-07 Stan Shebs
+ <shebs@andros.cygnus.com> indentation change. Don't let indent
+ mess with these files.
+
+Mon Jul 12 11:15:09 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/mips/tm-mips.h (REGISTER_CONVERT_TO_RAW,
+ REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERTIBLE): Define.
+ (REGISTER_RAW_SIZE): Re-define as mips_register_convert_to_raw.
+ * mips-tdep.c (mips_register_convert_to_raw,
+ mips_register_convert_to_virtual, ): New functions.
+ (mips_register_raw_size, mips_register_convertible): New
+ functions. Handle bug introduced by ``Wed Apr 1 23:13:23 1998
+ Andrew Cagney <cagney@b1.cygnus.com>'' where remote mips64 target
+ transfers SR as 64 bits yet GDB expected only 32 bits.
+ (mips64_transfers_32bit_regs): New static variable.
+ (_initialize_mips_tdep): Add obscure command ``set
+ remote-mips64-transfers-32bit-regs'' that provides backward
+ compatibility.
+ (do_gp_register_row): Extract register values from raw buffer.
+
+ * NEWS: Document protocol change.
+
+1999-07-12 Keith Seitz <keiths@cygnus.com>
+
+ * rdi-share/unixcomm.c (Unix_ResetSerial): Remove CYGWIN32
+ conditional. It's no longer needed.
+ (SERPORT1, SERPORT2): Linux serial ports are "/dev/ttyX", not
+ "/dev/cuaX" (X=0,1,2,3,...).
+
+Mon Jul 12 02:02:00 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * defs.h, utils.c (fputstrn_filtered, fputstrn_unfiltered,
+ fputstrnn_unfiltered): New functions.
+ (gdb_printchar): Delete.
+
+ * remote.c (print_packet): Replace gdb_printchar with
+ fputstrn_filtered.
+ (getpkt): Use fputstrn_unfiltered to dump packet received.
+ (putpkt_binary): Use fputstrnn_unfiltered to dump packet sent.
+
+1999-07-09 Keith Seitz <keiths@cygnus.com>
+
+ * blockframe.c (blockvector_for_pc_sect): When looking for a block,
+ we want the one whose end is greater than our PC, not greater or equal.
+
+1999-07-08 Stan Shebs <shebs@andros.cygnus.com>
+
+ * sparcl-tdep.c (init_sparclite_ops): Fix doc strings, remove
+ useless inits.
+ (sparclite_ops): Remove redundant decl.
+
+Thu Jul 8 16:48:40 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ser-pipe.c (pipe_open): Bi-directional popen found on both
+ NetBSD and OpenBSD.
+ * ser-pipe.c: New file. Implement popen() style serial interface.
+ * NEWS: Mention.
+ * Makefile.in (ALLDEPFILES): Add ser-pipe.c.
+ (ser-pipe.o): Add new target. Specify dependencies.
+ (SER_HARDWIRE): Add ser-pipe.o.
+ * serial.c (serial_open): Recognize a serial pipe ``|''.
+
+1999-07-07 Stan Shebs <shebs@andros.cygnus.com>
+
+ * All C files except *-stub.c and *-share/*: Indent to GNU
+ standard, using indent 1.9.1.
+ * defs.h: Make indent ignore this file, macros confuse it.
+
+ * gnu-regex.c, gnu-regex.h: Don't let indent mess with these.
+
+Wed Jul 7 13:06:24 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-mips.c (fputs_readable): Rename puts_readable, add struct
+ gdb_file argument.
+ (fputc_readable): Rename putc_readable, add struct gdb_file
+ argument.
+
+ * remote-mips.c (mips_expect_timeout, mips_receive_header,
+ mips_send_packet, mips_receive_packet), remote-rdp.c (put_byte,
+ get_byte, put_word, rdp_init, rdp_init), remote-sds.c
+ (sds_interrupt, sds_wait, readchar, putmessage, read_frame,
+ getmessage), remote-udi.c (udi_store_registers, fetch_register):
+ (store_register), xmodem.c (readchar), utils.c (puts_debug),
+ gnu-nat.h (debug), parse.c (parse_exp_1): Cleanup - send debug/log
+ messages to gdb_stdlog.
+
+1999-07-06 Stan Shebs <shebs@andros.cygnus.com>
+
+ * exec.c: Remove long-#ifed-out section of code that confuses
+ indent.
+ * gdbtypes.c (add_mangled_type): Add some braces to indicate
+ grouping better.
+ * gnu-nat.c: Remove literal newlines embedded in strings,
+ causes indent to weird out.
+ * language.c (binop_result_type): Remove extra paren.
+ * lynx-nat.c: Add a missing paren to fetch_core_registers decl.
+ * nec4102rom.c (vr4102_insert_step): Fix typos.
+ (_initialize_vr4102_rom): Remove literal newline in string.
+ * config/a29k/tm-a29k.h: Suppress formatting of pictures.
+ * config/m68k/xm-3b1.h: Remove excess #endif.
+
+ Declare Pyramid configuration obsolete.
+ * configure.host, configure.tgt: Comment out Pyramid configs.
+ * Makefile.in: Comment out Pyramid-related actions.
+ * pyr-xdep.c, pyr-tdep.c, config/pyr/*: Comment out.
+ * NEWS: Mention obsolete status.
+
+1999-07-06 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * remote.c: Include <sys/time.h> to pick up FD_SET et al defns on
+ some old Linux distributions.
+ * remote-os9k.c, remote-st.c, ser-tcp.c, ser-unix.c,
+ sparcl-tdep.c, remote.c: Back out inclusion of <sys/select.h>.
+ It isn't necessary after all.
+
+1999-07-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * infcmd.c (strip_bg_char): Remove assignment from 'if' condition.
+
+1999-07-05 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * remote.c: Include <sys/select.h> if it exists in order to pick up
+ FD_SET et al defns.
+ * remote-os9k.c: Same.
+ * remote-st.c: Same.
+ * ser-tcp.c: Same.
+ * ser-unix.c: Same.
+ * sparcl-tdep.c: Same.
+
+Fri Jul 2 19:38:43 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c (target_output_hook): Delete definition.
+ * defs.h (target_output_hook): Delete declaration.
+
+ * remote.c (remote_console_output): Delete call to
+ target_output_hook(). Send target output to gdb_stdtarg using an
+ unfiltered write. Make more robust.
+
+ * remote-sim.c (gdb_os_write_stdout, gdb_os_write_stderr):
+ Ditto. For moment, do not try to separate target stdout and stderr
+ streams.
+
+ * defs.h (gdb_stdtarg): New global. Output from target and
+ simulators.
+
+1999-07-02 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * top.c (return_to_top_level): Do all the exec_cleanups too.
+
+ * event-top.c (command_handler): Set up for a continuation, if we
+ are in the middle of running an execution command which will
+ finish later on. Do cleanups, an display of time/space only if not
+ running with an async target or not running an execution command.
+ (command_line_handler_continuation): New function. Continuation
+ for command_line_handler.
+
+ * utils.c (exec_cleanup_chain): New cleanup chain to be used in
+ async mode for the execution commands.
+ (make_exec_cleanup): New function. Add a cleanup to the
+ exec_cleanup_chain.
+ (do_exec_cleanups): New Function. Do cleanups on the
+ exec_cleanup_chain.
+ (add_continuation): New function. Add a new continuation to the
+ cmd_continuation list.
+ (do_all_continuations): New function. Do all the continuations on
+ the cmd_continuation list.
+
+ * top.h (ALL_CLEANUPS): Move from here to defs.h.
+
+ * defs.h (struct continuation_arg): New structure. Arg to pass to
+ the call to a command continuation.
+ (struct continuation): New structure. Continuation for an
+ execution command.
+ (ALL_CLEANUPS): Move here from top.h.
+
+ * remote.c (remote_async_open_1): Set things up for telling the
+ target we are running the extended protocol, only after the target
+ has stopped.
+ (set_extended_protocol): New function. Tell the target we are
+ using the extended protocol.
+ (remote_async_resume): Set things up for sync execution only if
+ this is the first time we are called.
+
+ * breakpoint.c (until_break_command_continuation): New function.
+ Stuff to be done after the target stops during the 'until'
+ command.
+ (until_break_command): Set things up for completing the 'until'
+ command later on. Do the final cleanups only if not running
+ asynchronously or async execution is not supported by the target.
+
+ * infcmd.c (until_command): Recognize '&' at end of command and
+ handle it properly.
+ (finish_command_continuation): New function. Do whatever is needed
+ after the target has stopped.
+ (finish_command): Recognize '&' at end of command and handle it
+ properly. Don't do stuff needed after target has stopped if
+ running asynchronously and target has async. Use exec_cleanup_chain
+ if running asynchronously and target is asynchronous.
+
+ * infrun.c (cmd_continuation): New gloabl variable. Used to
+ coplete execution commands in async mode, after the target has
+ stoped.
+ (fetch_inferior_event): Use exec_cleanup_chain, instead of
+ cleanup_chain. Do all the exec cleanups at the end. Do all the
+ continuations at the end. Call complete_execution from here,
+ instead of normal_stop.
+ (complete_execution): Cleanup the signals handlers for SIGINT
+ before displaying the prompt.
+ (start_remote): Set target_executing to 1.
+ (normal_stop): Don't call complete_execution from here.
+
+Thu Jul 1 19:14:30 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * blockframe.c (struct dummy_frame): Add member ``top''.
+ (generic_push_dummy_frame): Initialize top to sp.
+ (generic_save_dummy_frame_tos): New function. Initialize top.
+ (generic_find_dummy_frame): Check for the top of the frame.
+
+ * blockframe.c (generic_push_dummy_frame): Free the dummy_frame
+ registers.
+
+ * config/mn10300/tm-mn10300.h (SAVE_DUMMY_FRAME_TOS): Define.
+ (TARGET_READ_FP): Return the SP as a best guess.
+
+Wed Jun 30 15:45:48 1999 Jeffrey A Law (law@cygnus.com)
+
+ * configure.host (hppa*-*-hpux11*): Accept any version of hpux11
+ instead of hpux11.0*.
+
+1999-06-30 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * source.c (directory_command): Add missing test for from_tty.
+
+1999-06-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * remote.c: Include event-loop.h.
+ (remote_async_ops, extended_async_remote_ops): Define new target
+ vector structures for asynchronous debugging.
+ (remote_async_open): New function. Asynchronous version of
+ remote_open.
+ (extended_remote_async_open): New function. Asynchronous version
+ of extended_remote_open.
+ (remote_async_open_1): New function. Async version of
+ remote_open_1.
+ (remote_async_detach): New function. Async version of
+ remote_detach.
+ (remote_async_resume): New function. Async version of
+ remote_resume.
+ (initialize_sigint_signal_handler, handle_remote_sigint,
+ handle_remote_sigint_twice, async_remote_interrupt,
+ async_remote_interrupt_twice, cleanup_sigint_signal_handler): New
+ functions. Used for handling ^C while target is running.
+ (remote_async_wait): New function. Async version of remote_wait.
+ (remote_async_kill): New function. Async version of remote_kill.
+ (extended_remote_async_create_inferior): New function. Async
+ version of extended_remote_create_inferior.
+ (init_remote_async_ops): New function. Initialize target vector
+ for target async.
+ (init_extended_async_remote_ops): New function. Initialize target
+ vector for target extended-async.
+ (_initialize_remote): Initialize remote_async_ops and
+ extended_async_remote_ops.
+
+ * infrun.c: Include "event-loop.h".
+ (sync_execution): new global variable.
+ (proceed): Invoke wait_for_inferior and normal_stop only if not
+ running in async mode or if target doesn't support async
+ execution.
+ (start_remote): Don't call wait_for_inferior and normal_stop if
+ not running in async mode or if target not async. If running async
+ and target is async, start the target in simulated synchronous
+ mode.
+ (async_ecss, async_ecs): New global vars, for inferior state.
+ (fetch_inferior_event): New function. Async version of
+ wait_for_inferior.
+ (complete_execution): New function. Reset of gdb prompt and stdin,
+ after inferior execution has completed.
+ (normal_stop): Call complete_execution at end of asynchronous
+ execution.
+
+ * infcmd.c (strip_bg_char): New function to detect the background
+ execution char '&'.
+ (run_command): Modify to support background and foreground
+ execution in async mode.
+ (continue_command): Ditto.
+ (step_1): Ditto.
+ (jump_command): Ditto.
+ (interrupt_target_command): New function. Interrupt the
+ target execution.
+ (_initialize_infcmd): Add new command 'interrupt'.
+
+ * top.c (target_executing): New global variable.
+ (execute_command): Reject commands that cannot be executed while
+ the target is running asynchronously.
+
+ * event-top.c (push_prompt): Make non static.
+ (pop_prompt): Make non static. If the current prompt is empty,
+ don't try to copy it over the previous one.
+ (handle_sigint): Make non static.
+ (command_handler): Do the cleanups only when not executing with an
+ asynchronous target.
+
+ * event-loop.c (delete_async_signal_handler): Pass a pointer to a
+ pointer to a signal handler, so that is can be freed at the end.
+
+ * target.c (update_current_target): Inherit to_has_async_exec.
+
+ * inferior.h: Add global variables target_executing, and
+ sync_execution. Export function fetch_inferior_event.
+
+ * event-loop.h: Add push_prompt, pop_prompt, handle_sigint to the
+ exported functions. Update prototype for delete_signal_handler.
+
+ * target.h (struct target_ops): New target op: to_has_async_exec.
+ (target_has_async): New macro.
+
+ * Makefile.in (infrun.o): Add dependency on event-loop.h.
+ (remote.o): Ditto.
+
+1999-06-28 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * solib.c (clear_solib): Don't disable breakpoints if we're
+ running an a.out executable (Solaris's SunOS emulation).
+
+1999-06-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * main.c (main): Remove intialization of command_loop_hook, it
+ is now done in _initialize_event_loop().
+ * event-loop.c (gdb_do_one_event): Make static.
+ (start_event_loop): New function. Just start the event loop.
+ * event-top.c (cli_command_loop): New name for start_event_loop().
+ (gdb_readline2): Make non static.
+ (_initialize_event_loop): Set command_loop_hook to cli_command_loop.
+ * event-loop.h: Adjust exported functions accordingly.
+
+ * top.c (init_main): Move setting of async_command_editing_p from
+ here.
+ * event-top.c (_initialize_event_loop): To here.
+ (change_line_handler): Revert previous change. Add comment.
+ (_initialize_event_loop): Revert previous change.
+ (cli_command_loop): New name for start_event_loop().
+ (start_event_loop): New function. This just starts up the event loop.
+ (gdb_readline2): Make non static.
+ (_initialize_event_loop): Set command_loop_hook to cli_command_loop.
+
+1999-06-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-top.c (change_line_handler): Get rid of the global
+ variable input_fd, use `fileno (instream)' instead.
+ (_initialize_event_loop): Ditto
+
+ * event-loop.c (add_file_handler): New function. Wrapper for
+ create_file_handler.
+ (create_file_handler): Make static.
+ * event-top.c (_initialize_event_loop): Call add_file_handler,
+ instead of create_file_handler.
+ (change_line_handler): Ditto.
+ Remove poll.h include.
+ * event-loop.h: Export add_file_handler instead of
+ create_file_handler.
+
+1999-06-24 Stan Shebs <shebs@andros.cygnus.com>
+
+ Declare Altos configuration obsolete.
+ * configure.host, configure.tgt: Comment out Altos config.
+ * Makefile.in: Comment out Altos-related actions.
+ * altos-xdep.c, config/m68k/altos.mh, altos.mt, tm-altos.h,
+ xm-altos.h: Comment out.
+ * NEWS: Mention obsolete status.
+
+1999-06-24 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * Makefile.in: Add MAKEHTML and MAKEHTMLFLAGS; pass them down;
+ recognize html and install-html targets.
+ * gdbserver/Makefile.in: Add empty html and install-html targets.
+ * nlm/Makefile.in: Ditto.
+ * rdi-share/Makefile.in: Ditto.
+
+1999-06-24 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-gdb.c (agent_command): Remove vestigial call to ax_reqs.
+
+1999-06-24 James Ingham <jingham@leda.cygnus.com>
+
+ * arm-tdep.c (arm_othernames): Change both gdb's register display
+ AND the opcode disassembly register naming if the othernames
+ command. Fixes the gdb part of CR 101177.
+
+1999-06-23 Stan Shebs <shebs@andros.cygnus.com>
+
+ Declare Convex configuration obsolete.
+ * configure.host, configure.tgt: Comment out Convex configs.
+ * Makefile.in: Comment out Convex-related actions.
+ * convex-xdep.c, convex-tdep.c, config/convex/*: Comment out.
+ * NEWS: Mention obsolete status.
+
+1999-06-23 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * main.c: Turn on async by default by setting async_p to 1.
+
+Wed Jun 23 20:39:24 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * main.c (main): Recognize --ui. Will eventually replace
+ --interpreter.
+
+Wed Jun 23 15:44:39 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Jimmy Guo <guo@cup.hp.com>:
+ * frame.h (enum lval_type): Delcare when an __STDC__ compiler.
+ Reverts Mon Aug 11 16:08:52 1997 Fred Fish <fnf@cygnus.com>
+ change.
+ * utils.c (gdb_file_rewind, gdb_file_put): Fix. A void function
+ does not return a result.
+
+Wed Jun 23 15:30:46 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (set_thread, remote_get_threadinfo,
+ remote_threads_info, remote_current_thread, remote_get_threadlist,
+ extended_remote_restart, get_offsets, remote_open_1,
+ remote_detach, remote_resume, remote_wait, remote_fetch_registers,
+ remote_store_registers, check_binary_download, remote_write_bytes,
+ remote_read_bytes, remote_search, putpkt_binary, putpkt_binary,
+ read_frame, compare_sections_command, remote_query,
+ packet_command, remote_info_process): Use alloca to create space
+ for arrays of size PBUFSIZ.
+
+1999-06-22 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * top.c: Update copyright years to include 1999.
+
+1999-06-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * top.c: Move include of event-loop.h, to avoid redefinition of
+ NFDBITS.
+
+ * event-loop.c (create_file_handler): Do not do a realloc of the
+ pollfd structure of the notifier, unless there is already one.
+ Include <sys/types.h> for platforms that have no poll.
+
+ * event-top.c: Fix prototype for _initialize_event_loop.
+ (_initialize_event_loop): Do something only if running in async
+ mode.
+
+1999-06-17 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Make the '/c' print format use a true character type. This is
+ more appropriate than builtin_type_char for languages other than
+ C, and C tolerates it.
+ * gdbtypes.c (builtin_type_true_char): New variable.
+ (build_gdbtypes): Initialize it.
+ * gdbtypes.h (builtin_type_true_char): New declaration.
+ * printcmd.c (print_scalar_formatted): When the format is 'c',
+ extract the value as a builtin_type_true_char.
+
+ * jv-exp.y (yylex): Say character literals are java_char_type, not
+ builtin_type_char. Java treats the latter like `byte'.
+
+1999-06-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * Makefile.in (top_h): Define.
+ (event-loop.o): Add dependencies on top.h and defs.h.
+ (event-top.o): Add dependency on terminal.h.
+
+ * event-loop.c: Get rid of #include <readline.h>.
+
+ * event-loop.h: Get rid of nested #include's.
+ * event-loop.c: Rearrange includes to accomodate change in
+ event-loop.h. Include poll.h, not sys/poll.h.
+ * event-top.c: Ditto.
+ * main.c: Ditto.
+
+1999-06-16 David Taylor <taylor@louisiana.cygnus.com>
+
+ * alpha-tdep.c (alpha_pop_frame): if frame->proc_desc
+ is NULL, call find_proc_desc so we know how to restore
+ the registers.
+
+1999-06-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * cli-out.c (cli_out_new): Add flags argument to ui-out-new call.
+ * source.c (print_source_lines_base): Test for ui_source_list flag
+ and use ui_out for file and line output.
+ * ui-out.c (struct ui_out): Add flags field to struct and to default
+ initialization.
+ (ui_out_set_flags): New function. Handle flags.
+ (ui_out_clear_flags): New function. Ditto.
+ (ui_out_test_flags): New function. Ditto.
+ (ui_out_new): Add flags parameter.
+ * ui-out.h: Add flags argument to ui_out_new declaration.
+ Add declarations for ui_out_*_flags functions.
+ (enum ui_flags): New enum. Defines ui_out flags.
+ * top.c (gdb_init): Fix misspelling typo.
+
+1999-06-15 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * event-top.c (start_event_loop): call get_prompt.
+ (display_gdb_prompt): call get_prompt.
+ (async_stop_sig): call get_prompt.
+
+1999-06-15 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-loop.c (delete_file_handler): When positioning prev_ptr,
+ keep looping while the one after is not equal to file_ptr, instead
+ of equal.
+
+1999-06-14 Stan Shebs <shebs@andros.cygnus.com>
+
+ * MAINTAINERS: Add Jimmy Guo and Jim Blandy as HP testsuite and
+ SVR4 solib maintainers, respectively.
+
+1999-06-14 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ Add parameters to the gdb prompt.
+ * top.c (prompt): Rename to gdb_prompt_string for clarity.
+ (command_line_input): rename "prrompt" to prompt_arg for clarity.
+ (gdb_readline): rename "prrompt" to prompt_arg for clarity.
+ (read_command_lines): rename "prompt" to prompt_arg for clarity.
+ (stop_sig): call get_prompt instead of reading prompt string directly.
+ (command_loop): ditto.
+ (simplified_command_loop): ditto.
+ (gdb_prompt_escape): New variable. Esc char for prompt parameters.
+ (get_prompt_1): New function, workhorse for get_prompt.
+ (get_prompt): Completely rewrite. Add functionality for a
+ parameterized prompt, ie. the displayed prompt can change according
+ to the value of one or more expressions given as parameters in the
+ prompt string.
+ (init_main): use renamed variable gdb_prompt_string. Add new
+ command "set prompt-escape-char" to set gdb_prompt_escape.
+
+Sun Jun 13 10:44:13 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (gdb_stdlog), main.c: Declare.
+ * main.c (main): Initialize.
+ * gdbarch.c: Write trace messages to the log file.
+ * remote.c: Update any debug/log prints.
+
+1999-06-11 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * remote.c (remote_wait): Clean up new thread handling.
+ (record_currthread): Announce new threads.
+
+1999-06-11 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * partial-stab.h (case N_LSYM, 'T' descriptor): Don't create
+ partial symbol table entries for nameless enums, even if the type
+ name is " ". (We still pick up the enum elements, though.)
+
+ * partial-stab.h: Remove #if 0'd sections, dating back to 1992,
+ which set a variable which exists nowhere else in the source.
+ Please examine your test suite output carefully, and report any
+ problems to me.
+
+1999-06-11 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * top.c (gdb_init): Add pre-processor test for UI_OUT.
+
+1999-06-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-top.c (setup_event_loop): Change name to start_event_loop.
+ Move the intialization of event-loop variables to
+ _initialize_event_loop.
+ (_initialize_event_loop): New function. Called at init time, to
+ set up important event-loop variables.
+
+ * event-loop.h: setup_event_loop is now start_event_loop.
+ * main.c (main): Ditto.
+
+Fri Jun 11 18:34:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (gdb_file_rewind_ftype, gdb_file_rewind,
+ set_gdb_file_rewind, gdb_file_put_ftype, gdb_file_put,
+ set_gdb_file_put): Declare.
+
+ * utils.c (gdb_file_new): Initialize ``rewind'' and ``put''.
+ (struct gdb_file): Add to_rewind and to_put.
+ (null_file_put, null_file_rewind, gdb_file_put, gdb_file_rewind,
+ set_gdb_file_put, set_gdb_file_rewind): New functions.
+ (tui_file_rewind, tui_file_put): New functions.
+ (tui_file_new): Add rewind and put.
+
+ * cli-out.c (cli_spaces): Replace gdb_stdout with data->stream.
+ (cli_text, cli_message, cli_flush, out_field_fmt,
+ field_separator): Ditto.
+
+Fri Jun 11 16:08:37 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * cli-out.c (cli_out_new): Replace init_cli_out,
+ * top.c (gdb_init): Call cli_out_new.
+ * main.c (main): Delete call to set_ui_out_impl.
+
+ * ui-out.h (set_ui_out_impl, cli_ui_out_impl), ui-out.c: Delete.
+ (cli_out_new): Add declaration. Will move later.
+
+ * ui-out.c (ui_out_new, ui_out_data), ui-out.h: New functions.
+ (struct ui_out): Add field data.
+ (ui_out_new): Replace init_ui_out_state.
+
+ * ui-out.c (XMALLOC): Define.
+ (ui_out_stream_new, append_header_to_list): Use XMALLOC instead of
+ xmalloc.
+ * cli-out.c (XMALLOC): Define.
+
+Fri Jun 11 10:31:29 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ui-out.c (ui_out_field_int, ui_out_field_skip,
+ ui_out_field_fmt): Rewrite statements to remove infix operators.
+
+ * ui-out.c (get_curr_header, verify_field_proper_position,
+ verify_field_alignment, init_ui_out_state, set_ui_out_impl,
+ append_header_to_list): Add explicit ui_out parameter.
+ (struct ui_out): Move the local variables ``table_flag'',
+ ``body_flag'', ``table_columns'', ``table_id'', ``list_flat'',
+ ``field_count'', ``headerfirst'', ``headerlast'', ``headercurr''
+ into this struct.
+ (typedef ui_out_hdr): Delete.
+ (struct ui_out_hdr): Rename struct _ui_out_hdr.
+ (ui_out_table_begin, ui_out_table_end, ui_out_table_body,
+ ui_out_table_header, ui_out_field_int, ui_out_list_begin,
+ ui_out_table_end, ui_out_list_end, ui_out_field_skip,
+ ui_out_table_body, ui_out_list_begin, ui_out_list_end,
+ ui_out_field_string, ui_out_field_fmt, init_ui_out_state,
+ verify_field_proper_position, verify_field_alignment,
+ clear_header_list, append_header_to_list, _initialize_ui_out):
+ Update.
+
+ * ui-out.h (typedef streambuf): Delete.
+ (struct _streambuf): Rename to struct ui_stream.
+ * breakpoint.c (breakpoint_1), stack.c (print_frame_info_base),
+ printcmd.c (print_frame_args): Rename streambuf to struct
+ ui_stream.
+
+Fri Jun 11 15:10:32 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (d10v_push_arguments): Fix order of arguments passed
+ to store_address.
+
+Fri Jun 11 10:31:29 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (tty_input): Change array to pointer.
+ (_initialize_remote): Call build_remote_gdbarch_data.
+ (build_remote_gdbarch_data): New function. Allocate space for
+ tty_input.
+ (readsocket, readtty): Delete extern declaration of tty_input.
+
+1999-06-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-top.c (gdb_readline2): Call the command handling function
+ via the input_handler pointer.
+ (change_line_handler): When turning off editing, set input_handler
+ as well.
+
+ * utils.c (prompt_for_continue): If running asynchronously, call
+ async_request_quit, instead of request_quit.
+
+ * tracepoint.c (read_actions): If running asynchronously, set the
+ signal handler for STOP_SIGNAL to handle_stop_sig.
+
+ * top.h: (source_line_number, source_file_name, source_error,
+ source_pre_error, history_expansion_p, server_command): export for
+ use of event-top.c.
+
+ * event-top.c: Include top.h and terminal.h.
+ (instream): Remove extern declaration.
+ (handle_sigint, handle_sigquit, handle_sighup, handle_sigfpe,
+ handle_sigwinch, async_do_nothing, async_disconnect,
+ async_float_handler, async_stop_sig): Make static.
+ (async_request_quit, async_do_nothing, async_disconnect,
+ async_float_handler, async_stop_sig): Add gdb_glient_data
+ argument.
+ (handle_stop_sig): New function.
+ (sigtstp_token): New variable.
+ (sigint_token, sigquit_token, sigfpe_token, sigwinch_token):
+ Change their type tp PTR.
+ (mark_async_signal_handler_wrapper): New function.
+ (setup_event_loop): Initialize all the variables used by readline
+ only if not already done while reading the .gdbinit file. Display
+ the initial gdb prompt, if .gdbinit took care of setting things up
+ for readline.
+ (change_line_handler): When turning on the use of readline,
+ initialize input_handler as well.
+ (command_line_handler): Set up the signal handler for STOP_SIGNAL
+ to be handle_stop_sig.
+ (async_init_signals): Remove coercion of signal handlers in calls
+ to create_async_signal_handler. Initialize token for stop signal.
+ (handle_sigint): Call async_request_quit using one argument.
+ (handle_sigint, handle_sigquit, handle_sighup, handle_sigfpe,
+ handle_sigwinch): Call mark_async_signal_handler_wrapper instead
+ of mark_async_signal_handler.
+
+ * event-loop.h: Add extern declarations for handle_stop_sig,
+ async_command_editing_p, async_annotation_suffix,
+ new_async_prompt, the_prompts.
+
+ * top.c (command_line_input): Set the signal handler to be
+ handle_stop_sig, in case gdb is running asynchronously.
+ (get_prompt): Return the top of the prompt stack if running
+ asynchronously.
+ (set_prompt): Set the top of the prompt stack if running
+ asynchronously.
+ (init_main): Move ``extern'' vars from here to event-loop.h.
+
+1999-06-10 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * values.c (value_from_string): new function. Make a value_ptr
+ from a string, with storage in local GDB memory (not in inferior).
+ * value.h (value_from_string): add prototype.
+ * remote.c (remote_cisco_ops): New remote target, "target cisco".
+ (init_remote_cisco_ops): New function, initialize new target.
+ (remote_cisco_mourn, remote_cisco_wait, remote_cisco_open,
+ remote_cisco_close): New functions, implement new target cisco.
+ (minitelnet, readtty, readsocket) New functions, implement the
+ I/O pass-through mode for target cisco.
+ (remote_wait): Detect special enhanced version of the 'S' packet
+ for target cisco.
+ (remote_cisco_expand): Perform Cisco variant of RLL decoding.
+
+1999-06-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-loop.c (gdb_wait_for_event): Initialize num_found to 0.
+
+ * top.c (print_prompt): Delete this function.
+
+ From: Andrew Cagney <cagney@b1.cygnus.com>
+
+ * event-top.c (async_hook): Delete extern declaration.
+
+ * defs.h: Replace ``async_hook'' with ``async_p''.
+ * top.c (gdb_init, init_main, init_main, init_main, init_main):
+ Replace ``async_hook'' with ``async_p''.
+
+ * main.c: Rename ``async'' to ``async_p''.
+ (main): Add --noasync option.
+ (main): Hook in the asynchronous event-loop based CLI using
+ command_loop_hook instead of async_hook. Delete call to
+ async_hook().
+
+Thu Jun 10 21:14:16 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mn10300-tdep.c (mn10300_store_return_value,
+ mn10300_extract_struct_value_address,
+ mn10300_extract_return_value), config/mn10300/tm-mn10300.h: New
+ functions.
+ * config/mn10300/tm-mn10300.h (EXTRACT_STRUCT_VALUE_ADDRESS,
+ STORE_RETURN_VALUE, EXTRACT_RETURN_VALUE): Update.
+ (TARGET_MN10300): Delete macro. Not used.
+
+Thu Jun 10 20:04:02 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mn10300-tdep.c (mn10300_register_names): Make static.
+ (STORE_STRUCT_RETURN): Do not modify SP.
+
+ * config/mn10300/tm-mn10300.h(mn10300_register_name),
+ mn10300-tdep.c : New function.
+ * config/mn10300/tm-mn10300.h (REGISTER_NAME): Update.
+ * config/mn10300/tm-mn10300.h (mn10300_saved_pc_after_call),
+ mn10300-tdep.c: New function.
+ * config/mn10300/tm-mn10300.h (SAVED_PC_AFTER_CALL): Update.
+
+Wed Jun 9 16:42:16 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.h, top.c (simplified_command_loop): Make global.
+
+ * main.c (main): Delete call to call_interp_loop. Interpreters
+ hook in using command_loop_hook.
+ * top.c (call_interp_loop): Delete function.
+
+1999-06-10 Keith Seitz <keiths@cygnus.com>
+
+ * mcore-rom.c (picobug_dumpregs): Return a value. Any value, it
+ doesn't matter.
+ * mcore-tdep.c (mcore_analyze_prologue): Set NO_MORE_FRAMES
+ if the start of the function is the entry point.
+ (mcore_analyze_prologue): rotli takes an immediate, not an
+ offset immediate.
+ (mcore_push_arguments): Fix compiler warning.
+
+1999-06-09 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * rs6000-tdep.c (skip_prologue): Don't mistake a branch for a
+ subroutine call.
+
+1999-06-08 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * remote.c (remote_wait): Add 'N' response packet, which is a
+ stop with signal number plus section offsets for .text, .data and
+ .bss. This is used by Cisco to indicate relocation offsets.
+ (remote_cisco_section_offsets, remote_cisco_objfile_relocate):
+ new files to support 'N' packet.
+ (remote_info_process): New function. Implements the
+ "info remote-process" command, by means of which the remote target
+ can report anything it wants to about the remote process/app being
+ debugged.
+ (_initialize_remote): add info remote-proc command.
+ (remote_threads_info): New function for "info threads" command.
+ Attempts to use new query "qfThreadInfo" instead of the old
+ undocumented query.
+ * exec.c (exec_set_section_offsets) new files to support 'N' packet.
+
+Tue Jun 8 13:33:42 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * inferior.h (generic_target_read_pc, generic_target_write_pc,
+ generic_target_read_fp, generic_target_write_fp,
+ generic_target_read_sp, generic_target_write_sp): Declare new
+ functions.
+ * findvar.c (generic_target_read_pc, generic_target_write_pc,
+ generic_target_read_fp, generic_target_write_fp,
+ generic_target_read_sp, generic_target_write_sp): New functions.
+ (TARGET_READ_PC, TARGET_WRITE_PC, TARGET_READ_FP, TARGET_WRITE_FP,
+ TARGET_READ_SP, TARGET_WRITE_SP): Default to corresponding generic
+ function.
+ (write_pc_pid, write_pc_pid, read_sp, write_sp, read_fp,
+ write_fp): Simplify.
+
+ * gdbarch.c (verify_gdbarch): Always verify TARGET_PTR_BIT,
+ TARGET_SHORT_BIT, TARGET_INT_BIT, TARGET_LONG_BIT,
+ TARGET_LONG_LONG_BIT, TARGET_FLOAT_BIT, TARGET_DOUBLE_BIT,
+ TARGET_LONG_DOUBLE_BIT, TARGET_READ_PC, TARGET_WRITE_PC,
+ TARGET_READ_FP, TARGET_WRITE_FP, TARGET_READ_SP, TARGET_WRITE_SP,
+ USE_GENERIC_DUMMY_FRAMES, CALL_DUMMY_BREAKPOINT_OFFSET_P,
+ CALL_DUMMY_P, CALL_DUMMY_STACK_ADJUST_P, GET_SAVED_REGISTER,
+ REGISTER_CONVERTIBLE, PUSH_ARGUMENTS, PUSH_RETURN_ADDRESS,
+ FRAME_CHAIN_VALID.
+ (GET_GDBARCH, SET_GDBARCH): Delete macros. Implement functions
+ directly.
+ * gdbarch.h, gdbarch.c: Call fatal() instead of abort(). Identify
+ the function / macro with a problem. Always verify a architecture
+ attribute before returning it.
+ * gdbarch.h, gdbarch.c (generic_register_convertible_not): New
+ function.
+
+ * mips-tdep.c (mips_push_return_address): New function.
+ * config/mips/tm-mips.h (PUSH_RETURN_ADDRESS): Define.
+
+ * mips-tdep.c (mips_gdbarch_init): Initialize short_bit,
+ double_bit, long_double_bit, read_pc, write_pc, read_fp, write_fp,
+ read_sp, write_sp, frame_chain_valid, get_saved_register,
+ push_arguments, push_return_address, register_convertible,
+ call_dummy_p, use_generic_dummy_frames,
+ call_dummy_breakpoint_offset_p, call_dummy_stack_adjust_p,
+ call_dummy_words and sizeof_call_dummy_words.
+ * config/mips/tm-mips.h: Don't define CALL_DUMMY when multi-arch.
+
+1999-06-07 Keith Seitz <keiths@cygnus.com>
+
+ * v850ice.c (init_hidden_window): Do not rely on the existence of
+ a gui for window creation. Return boolean status.
+ (v850ice_open): Use boolean status of init_hidden_window.
+ Allow any ICE execution command to run under CLI. Maybe one
+ day gdb will use a real event loop and allow this code to run.
+ * configure.tgt: Configure the v850 ice for all cygwin-hosted
+ toolchains.
+
+Mon Jun 7 23:37:26 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * config/mips/tm-mips.h (EXTRA_FRAME_INFO): Delete.
+ * mips-tdep.c (mips_init_extra_frame_info): Allocate saved_regs.
+ (temp_saved_regs): Replace struct with a simple pointer.
+ (set_reg_offset, mips32_heuristic_proc_desc, heuristic_proc_desc,
+ mips_init_extra_frame_info): Update.
+
+Mon Jun 7 21:40:12 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * config/mips/tm-mips.h (EXTRA_FRAME_INFO): Move elements from here.
+ * mips-tdep.c (struct frame_extra_info): To here.
+
+ * mips-tdep.c (mips_print_extra_frame_info, mips_find_saved_regs,
+ mips_init_extra_frame_info, mips_pop_frame): Update
+ (mips_init_extra_frame_info): Allocate space for the extra info.
+
+Mon Jun 7 21:08:50 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * config/mips/tm-mips.h (mips_init_extra_frame_info), mips-tdep.c:
+ Rename init_extra_frame_info. Add argument ``fromleaf''.
+ mips-tdep.c (mips_gdbarch_init): Add mips_init_extra_frame_info.
+
+ * config/mips/tm-mips.h (mips_print_extra_frame_info),
+ mips-tdep.c: New function.
+ (PRINT_EXTRA_FRAME_INFO): Update definition.
+
+Mon Jun 7 20:11:07 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * config/mips/tm-mips.h, config/mips/tm-irix3.h,
+ config/mips/tm-tx19.h, config/mips/tm-tx19l.h,
+ config/mips/tm-tx39.h, config/mips/tm-tx39l.h: Rename macro
+ REGISTER_NAMES to MIPS_REGISTER_NAMES.
+
+ * config/mips/tm-mips.h (REGISTER_NAME): Define.
+ * mips-tdep.c (mips_processor_reg_names): New static variable.
+ (mips_register_name): New function.
+ (mips_set_processor_type): Update mips_processor_reg_names.
+ (mips_generic_reg_names): Initialize using MIPS_REGISTER_NAMES.
+ (mips_gdbarch_init): Add mips_register_name.
+
+Sun Jun 6 11:09:19 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (PBUFSIZ): Re-define so that value is computed at
+ run-time.
+ (MAXBUFBYTES): Re-define as a macro function.
+ * gdbarch.h, gdbarch.c: Add multi-arch support for REGISTER_BYTES.
+ * d10v-tdep.c, config/d10v/tm-d10v.h: Update.
+
+1999-06-05 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * symtab.c (decode_line_1): Accept filenames with spaces in
+ 'linespecs' when enclosed in double quotation marks and handle
+ drive specification is DOS format (D:).
+
+1999-06-04 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * parse.c: Don't include <ctype.h> twice.
+
+1999-06-04 David Taylor <taylor@louisiana.cygnus.com>
+
+ Sat May 15 12:16:09 1999 Per Bothner <bothner@deneb.cygnus.com>
+
+ * eval.c (evaluate_subexp_standard): Remove Gilmore rant.
+ (Of course C has "expected types", at least if you allow
+ brace-initializer expressions - as in Gcc.)
+ Remove NULLing out expect_type. Do pass NULL_TYPE in place
+ the incoming expect_type where appropriate.
+
+Fri Jun 4 10:56:23 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppa-tdep.c (hppa_fix_call_dummy): Make it work for GCC compiled
+ executables without end.o. Clean up lots of mis-guided comments.
+
+Fri Jun 4 17:10:36 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * parser-defs.h (std_regs): Replace array with pointer.
+ * parse.c (build_parse): Build the std_regs table according to the
+ standard registers available.
+ (_initialize_parse): Register std_regs and num_std_regs as
+ architecture specific.
+ * gdbarch.h, gdbarch.c: Add multi-arch support for SP_REGNUM,
+ FP_REGNUM, PC_REGNUM, NUM_REGS, REGISTER_NAME.
+ * d10v-tdep.c, config/d10v/tm-d10v.h: Update.
+
+1999-06-03 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * printcmd.c (print_frame_args): Convert some of the output to use
+ ui_out.
+ * stack.c (print_frame_info_base): Adjust the call to the above
+ function.
+
+1999-06-03 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * thread.c: eliminate the target_thread_vector (functionality
+ moved into the standard target vector).
+ * gdbthread.h: eliminate target_thread_vector. Move all related
+ defines into remote.c, since they are no longer shared with thread.c.
+ * remote.c: eliminate the target_thread_vector.
+ (remote_find_new_threads): change return type to void, consistent
+ with the target vector table. (cont_thread): rename continue_thread.
+ (record_currthread): remove dead code. (remote_thread_alive):
+ clean up and simplify. (threadref etc.): move definitions to here
+ from gdbthread.h.
+
+1999-06-02 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * inftarg.c (child_create_inferior): Remove dead HPUX specific code
+ which tries to find csh.
+ * fork-child.c: Remove DEBUGGING predefine and conditionalized
+ printfs.
+ (fork_inferior): Remove dead HPUX specific code which assumes shell
+ is csh.
+
+ * hppa-tdep.c: Remove DEBUGGING and #if 0 debugging printfs.
+ * parse.c: Ditto.
+ * somread.c: Ditto.
+
+ * gdbarch.h: Forward decl of struct value.
+
+Thu Jun 3 10:12:38 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (do_d10v_pop_frame): Rename d10v_pop_frame. Make
+ static.
+ * d10v-tdep.c (d10v_pop_frame), config/d10v/tm-d10v.h: New
+ function. Call generic_pop_current_frame.
+ * config/d10v/tm-d10v.h (POP_FRAME): Update.
+ * gdbarch.h, gdbarch.c (frame_num_args_unknown): New function.
+ * gdbarch.h, gdbarch.c: Add multi-arch support for POP_FRAME,
+ SKIP_PROLOGUE, INNER_THAN, DECR_PC_AFTER_BREAK,
+ FUNCTION_START_OFFSET, REMOTE_TRANSLATE_XFER_ADDRESS, FRAME_CHAIN,
+ FRAME_CHAIN_VALID, FRAME_SAVED_PC, FRAME_ARGS_ADDRESS,
+ FRAME_LOCALS_ADDRESS, FRAME_ARGS_SKIP,
+ FRAMELESS_FUNCTION_INVOCATION, REGISTER_BYTE, REGISTER_RAW_SIZE,
+ REGISTER_VIRTUAL_SIZE, REGISTER_VIRTUAL_TYPE, SAVED_PC_AFTER_CALL,
+ FRAME_NUM_ARGS, MAX_REGISTER_RAW_SIZE, MAX_REGISTER_VIRTUAL_SIZE,
+ REGISTER_SIZE.
+ * d10v-tdep.c, config/d10v/tm-d10v.h: Update.
+ * config/d10v/tm-d10v.h (DMEM_START, IMEM_START, STACK_START,
+ ARG1_REGNUM, ARGN_REGNUM, RET1_REGNUM): Move definitions from
+ here.
+ * d10v-tdep.c: To here.
+ * config/d10v/tm-d10v.h (struct type): Move declaration from here.
+ * gdbarch.h: To here.
+ * config/d10v/tm-d10v.h (struct frame_info, struct
+ frame_saved_regs, struct type): Delete declarations.
+
+1999-06-02 Robert Hoehne <robert.hoehne@gmx.net>
+
+ * go32-nat.c: go32_terminal_init, go32_terminal_inferior and
+ go32_terminal_ours are new functions to save/restore the inferior`s
+ stdin/stdout filemodes
+
+1999-06-02 Stan Shebs <shebs@andros.cygnus.com>
+
+ * MAINTAINERS: Add Mark Kettenis, Jeff Law, and Philippe De Muyter
+ as maintainers for Hurd, HP/UX, and COFF, respectively.
+
+1999-06-02 Mark Kettenis <kettenis@gnu.org>
+
+ * gnu-nat.c (inf_continue): New function.
+ (struct inf): Use `unsigned int' instead of `int' for bit-fields.
+ Add new bit-field named `nomsg'.
+ (inf_validate_procinfo): Renamed from inf_validate_stopped, all
+ callers changed. Also update the `nomsg' and `traced' fields of
+ INF.
+ (make_inf): Initialize INF->nomsg.
+ (inf_cleanup): Reset INF->nomsg.
+ (inf_detach): Call `inf_validate_procinfo'. Call `inf_continue'
+ instead of `inf_signal' if the inferior does not have a message
+ port.
+ (gnu_resume): Likewise.
+ (gnu_create_inferior): Reset INF->nomsg in `attach_to_child'.
+ Call `inf_validate_procinfo' after returning from `fork_inferior'.
+ (gnu_attach): Update signal thread and tracing state.
+
+ * config/i386/tm-i386gnu.h: Include "i386/tm-i386.h" instead of
+ "i386/tm-i386v.h".
+ (STACK_END_ADDR): Remove.
+ (SIGCONTEXT_PC_OFFSET): New define.
+ Include "tm-sysv4.h".
+
+1999-06-02 J.T. Conklin <jtc@redback.com>
+
+ * config/tm-vxworks.h: New file, header for definitions common to
+ all vxWorks targets.
+ * config/a29k/tm-vx29k.h, config/i960/tm-vx960.h,
+ config/m68k/tm-vx68.h, config/mips/tm-vxmips.h,
+ config/sparc/tm-vxsparc.h: Include tm-vxworks.h.
+
+Wed Jun 2 17:37:03 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/pa/tm-hppa.h (IMPORT_SHLIB): New unwind stub type.
+
+1999-06-02 Christopher Faylor <cgf@cygnus.com>
+
+ * configure.tgt: Alphabetically reorder some targets.
+
+1999-06-02 Keith Seitz <keiths@cygnus.com>
+
+ * v850ice.c (v850ice_xfer_memory): Insert lost "break".
+
+1999-06-02 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * rs6000-tdep.c (variants): Fix description of 750 register set.
+ (Thanks to J. T. Conklin.)
+
+Wed Jun 2 16:10:08 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h, gdbarch.c: Add multi-arch support for
+ STORE_STRUCT_RETURN, STORE_RETURN_VALUE,
+ EXTRACT_STRUCT_VALUE_ADDRESS, USE_STRUCT_CONVENTION,
+ FRAME_INIT_SAVED_REGS and INIT_EXTRA_FRAME_INFO.
+ * d10v-tdep.c, config/d10v/tm-d10v.h: Update.
+
+ * config/d10v/tm-d10v.h (FRAME_INIT_SAVED_REGS): Replace
+ FRAME_FIND_SAVED_REGS.
+ (d10v_frame_init_saved_regs): Replace d10v_frame_find_saved_regs.
+ * d10v-tdep.c (d10v_pop_frame, d10v_frame_chain,
+ d10v_frame_init_saved_regs): Update.
+ * gdbarch.h: Disallow FRAME_FIND_SAVED_REGS when multi-arch.
+
+ * gdbarch.h, gdbarch.c: Add multi-arch support for
+ D10V_MAKE_DADDR, D10V_MAKE_IADDR, D10V_DADDR_P, D10V_IADDR_P,
+ D10V_CONVERT_DADDR_TO_RAW and D10V_CONVERT_IADDR_TO_RAW.
+ * d10v-tdep.c, config/d10v/tm-d10v.h: Update.
+
+ * config/d10v/tm-d10v.h (EXTRA_FRAME_INFO): Delete.
+ * d10v-tdep.c (struct frame_extra_info): Define.
+ (d10v_init_extra_frame_info, d10v_pop_frame, d10v_frame_chain,
+ d10v_frame_find_saved_regs): Update.
+ * gdbarch.h: Disallow EXTRA_FRAME_INFO when multi-arch.
+
+Tue Jun 1 13:36:31 1999 Philippe De Muyter <phdm@macqel.be>
+
+ * config/m68k/tm-delta68.h (FRAME_NUM_ARGS): Macro prototype fixed.
+ * config/m68k/tm-news.h, config/ns32k/tm-merlin.h: Ditto.
+ * config/ns32k/tm-umax.h (FRAME_NUM_ARGS): Old macro definition
+ removed; new macro prototype fixed.
+
+Wed Jun 2 11:18:37 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h, gdbarch.c: Add multi-arch support for
+ EXTRACT_RETURN_VALUE, PUSH_ARGUMENTS, PUSH_DUMMY_FRAME,
+ PUSH_RETURN_ADDRESS, POP_FRAME, FRAME_FIND_SAVED_REGS.
+ * d10v-tdep.c, config/d10v/tm-d10v.h: Update.
+
+ * gdbarch.h, gdbarch.c: Add multi-arch support for
+ REGISTER_CONVERTIBLE, REGISTER_CONVERT_TO_VIRTUAL,
+ REGISTER_CONVERT_TO_RAW.
+ * config/d10v/tm-d10v.h, d10v-tdep.c (d10v_gdbarch_init): Update.
+
+ * defs.h (REGISTER_NAME): Move compatibility definition from here.
+ * gdbarch.h: To here.
+
+ * frame.h, blockframe.c (generic_fix_call_dummy): New
+ stub function.
+ * gdbarch.h, gdbarch.c: Add multi-arch support for FIX_CALL_DUMMY.
+ * config/d10v/tm-d10v.h, d10v-tdep.c (d10v_gdbarch_init): Update.
+
+Tue Jun 1 20:06:38 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (d10v_gdbarch_init): Set get_saved_register.
+ * config/d10v/tm-d10v.h: Update.
+
+Tue Jun 1 19:50:05 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h, gdbarch.c: Add multi-arch support for TARGET_READ_PC,
+ TARGET_WRITE_PC, TARGET_READ_FP, TARGET_WRITE_FP, TARGET_READ_SP
+ and TARGET_WRITE_SP.
+ * config/d10v/tm-d10v.h, d10v-tdep.c (d10v_gdbarch_init): Update.
+
+Tue Jun 1 19:19:02 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.c (default_gdbarch): Set field GET_SAVED_REGISTER to
+ generic_get_saved_register.
+ * gdbarch.c: Change update dispatch functions so that they check
+ for a NULL function pointer.
+
+Tue Jun 1 19:19:02 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h, gdbarch.c: Add multi-arch support for TARGET_INT_BIT,
+ TARGET_CHAR_BIT, TARGET_SHORT_BIT, TARGET_FLOAT_BIT,
+ TARGET_DOUBLE_BIT and TARGET_LONG_DOUBLE_BIT.
+ * config/d10v/tm-d10v.h, d10v-tdep.c (d10v_gdbarch_init): Update.
+
+Tue Jun 1 18:47:54 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * parse.c (build_parse): New function. Initialize
+ msym_text_symbol_type, msym_data_symbol_type and
+ msym_unknown_symbol_type.
+ (_initialize_parse): Call build_parse.
+ (_initialize_parse): Register variables msym_text_symbol_type,
+ msym_data_symbol_type as msym_unknown_symbol_type as
+ per-architecture.
+
+Tue Jun 1 11:30:09 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (_initialize_d10v_tdep): Register d10v as an
+ architecture.
+ (d10v_gdbarch_init): New function.
+ * confg/d10v/tm-d10v.h (GDB_MULTI_ARCH): Define.
+
+Tue Jun 1 10:45:24 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/d10v/tm-d10v.h (REGISTER_CONVERTIBLE,
+ REGISTER_CONVERT_TO_RAW, REGISTER_CONVERT_TO_VIRTUAL): Convert
+ macros into functions.
+ * config/d10v/tm-d10v.h, d10v-tdep.c (d10v_register_convertable,
+ d10v_register_convert_to_virtual, d10v_register_convert_to_raw):
+ The new functions.
+
+1999-05-31 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * breakpoint.c (print_it_normal): Convertion of part of the output
+ to use ui-out.
+ (mention): Same as above.
+ * infcmd.c (run_command): Same.
+ * source.c (print_source_lines_base): Same.
+ * stack.c (print_frame_info_base): Same.
+
+1999-05-31 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * breakpoint.c (breakpoint_1): Fix names of fields on ui_out
+ produced output.
+ * ui-out.h: Cosmetic change.
+
+1999-05-31 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * stack.c (print_args_stub): Add missing stream parameter.
+
+Mon May 31 15:50:08 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ Fri May 28 16:51:00 1999 Martin Dorey <martin.dorey@madge.com>:
+ * valops.c, value.h (default_push_arguments): Fix order of
+ parameters to match PUSH_ARGUMENTS arguments.
+
+1999-05-28 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * top.c (print_command_lines): Simplified script format for
+ non-console output.
+
+1999-05-28 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * top.c (print_command_lines): Fixed printing of if clauses.
+ * breakpoint.c (breakpoint_1): Adjust call to the above.
+ * top.c (show_user_1): Same as above.
+
+1999-05-27 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * top.c (call_interp_loop): Correct build problem with UI_OUT defined.
+
+Thu May 27 11:42:55 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h (EXTRACT_STRUCT_VALUE_ADDRESS): Return 0.
+
+ * valops.c (value_assign): Delete redundant test of
+ REGISTER_CONVERTIBLE.
+
+Thu May 27 11:33:57 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/w65/tm-w65.h, config/tic80/tm-tic80.h, config/sh/tm-sh.h,
+ config/i386/tm-i386m3.h, config/i386/tm-go32.h,
+ config/i386/tm-cygwin.h, config/h8500/tm-h8500.h,
+ config/d30v/tm-d30v.h, config/d10v/tm-d10v.h: Delete definition of
+ macro NAMES_HAVE_UNDERSCORE.
+
+Thu May 27 09:31:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h (EXTRACT_STRUCT_VALUE_ADDRESS,
+ EXTRACT_STRUCT_VALUE_ADDRESS_P): Provide default definitions.
+ * values.c (value_being_returned): Use
+ EXTRACT_STRUCT_VALUE_ADDRESS when EXTRACT_STRUCT_VALUE_ADDRESS_P.
+
+Wed May 26 13:51:25 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * utils.c (tui_file_new, tui_file_delete, tui_fileopen): New
+ functions.
+ (tui_file_isatty): Rename gdb_file_isatty.
+ (gdb_file_init_astring): Use tui_file_new to create stream.
+ (gdb_file_get_strbuf, gdb_file_adjust_strbuf): Call gdb_file_data
+ to access the tui_stream.
+ (tui_file_flush): Rename gdb_flush. Call gdb_file_data to access
+ the tui_stream. Pass FILE and not STREAM down.
+
+ * utils.c (struct stdio_file, stdio_file_flush, stdio_file_fputs,
+ stdio_file_isatty, stdio_file_delete, stdio_file_new,
+ stdio_fileopen): Define type and functions. Implement a simple
+ STDIO based gdb_file.
+ (struct gdb_file, gdb_file_new, gdb_file_delete, null_file_isatty,
+ null_file_flush, null_file_fputs, null_file_delete, gdb_file_data,
+ set_gdb_file_flush, set_gdb_file_isatty, set_gdb_file_fputs,
+ set_gdb_file_data, fputs_unfiltered, gdb_flush, gdb_file_isatty):
+ Define type and functions. Implement virtual functions for
+ gdb_file.
+
+ * defs.h (struct gdb_file): Declare.
+ (GDB_FILE): Change type to struct gdb_file. Deprecate.
+ (gdb_file_flush_ftype, gdb_file_fputs_ftype,
+ gdb_file_isatty_ftype, gdb_file_delete_ftype): Add function type
+ declarations.
+
+ * defs.h (set_gdb_file_flush, set_gdb_file_fputs,
+ set_gdb_file_isatty, set_gdb_file_data, gdb_file_new,
+ gdb_file_delete, gdb_file_data, stdio_fileopen, tui_fileopen): Add
+ function declarations.
+ (gdb_fopen): Re-implement. Call stdio_file_new.
+ (gdb_fclose): Re-implement. Call gdb_file_delete.
+
+ * main.c (tui_file_fputs): Rename fputs_unfiltered. Use
+ gdb_file_data to gain access to the tui_stream data. Use FILE
+ instead of STREAM where applicable.
+ (main): Create gdb_stdout and gdb_stderr using tui_fileopen.
+
+ * defs.h (struct tui_stream): Add field ts_magic.
+ * utils.c (tui_file_magic): Local variable.
+ (tui_file_new): Set field ts_magic.
+ (tui_file_delete, tui_file_isatty, gdb_file_init_astring,
+ gdb_file_get_strbuf, gdb_file_adjust_strbuf, tui_file_flush):
+ Verify ts_magic.
+
+1999-05-25 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * top.c (print_command_lines): New function, fix bug in printing
+ while commands and uses ui_out.
+ * gdbcmd.c: Add prototype for the above.
+ * breakpoint.c (breakpoint_1): Fix breakpoint script printing.
+ * command.c (show_user_1): Fix user command script printing.
+
+1999-05-25 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * breakpoint.c (insert_breakpoints, remove_breakpoint,
+ breakpoint_1): Add a 'default' case, which prints a warning
+ message, to remove EGCS warnings.
+
+1999-05-25 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * utils.c (gdb_file_adjust_strbuf): Take into account the
+ possibility that the buffer has not been allocated yet.
+
+Tue May 25 16:05:11 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h (REGISTER_CONVERTIBLE, REGISTER_CONVERT_TO_VIRTUAL,
+ REGISTER_CONVERT_TO_RAW): Provide default definition.
+
+ * valops.c (value_assign), infcmd.c (do_registers_info), findvar.c
+ (value_from_register, value_of_register): Remove #ifdef
+ REGISTER_CONVERTIBLE. Assume REGISTER_CONVERTIBLE etc defined.
+
+1999-05-25 Keith Seitz <keiths@cygnus.com>
+
+ * config/mcore/tm-mcore.h (FRAME_NUM_ARGS): Re-write definition of
+ FRAME_NUM_ARGS so that it returns NUM_ARGS as a result instead of
+ setting a variable as a side effect.
+
+Tue May 25 16:18:25 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * remote-d10v.c (d10v_eva_prepare_to_trace,
+ d10v_eva_get_trace_data), remote-sim.c (_initialize_remote_sim):
+ Add declaraton. Make static.
+
+ * remote-d10v.c (_initialize_remote_d10v), d10v-tdep.c
+ (_initialize_d10v_tdep): Add declaration.
+ * config/d10v/tm-d10v.h (d10v_frame_chain): Add declaration.
+
+Tue May 25 15:20:58 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * main.c (init_proc, proc_remove_foreign): Delete function.
+ * inftarg.c (child_mourn_inferior): Update. Delete call to
+ proc_remove_foreign().
+ * top.c (gdb_init): Update. Delete call to init_proc().
+
+ * utils.c (pollquit, fmthex, hexlate): Delete function.
+
+Tue May 25 13:01:43 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * main.c (gdb_init): Move declaration from here.
+ * top.h: To here.
+
+ * main.c (call_interp_loop): Move declaration from here.
+ * top.h: To here.
+
+ * defs.h (init_page_info): Add declaration.
+
+ * top.c (initialize_utils): Move declaration from here.
+ * defs.h: To here.
+
+ * infcmd.c (target_map_name_to_register): Move declaration from
+ here.
+ * parser-defs.h: To here.
+
+ * c-typeprint.c (cp_type_print_method_args), target.c
+ (nosupport_runtime, normal_target_post_startup_inferior): Add
+ declaration. Make static.
+
+Tue May 25 13:53:23 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * main.c: Include "event-loop.h".
+ * Makefile.in (main.o): Add dependency.
+
+ * top.h (setup_event_loop, async_init_signals), top.c
+ (set_async_editing_command, set_async_annotation_level,
+ set_async_prompt), event-loop.c (display_gdb_prompt): Move
+ declarations from here.
+ * event-loop.h: To here.
+
+ * event-loop.h (delete_async_signal_handler): Add function
+ declaration.
+
+ * event-top.c (change_annotation_level, command_handler): Add
+ declaration. Make static.
+
+Tue May 25 12:44:58 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * tracepoint.c (free_actions_list, add_register): Add declaration.
+ Make static.
+ (free_actions_list_cleanup_wrapper): New function. Wraps
+ free_actions_list for make_cleanup.
+ (trace_start_command): Pass free_actions_list_cleanup_wrapper
+ instead of free_actions_list to make_cleanup.
+ (_initialize_tracepoint): Add extern declaration.
+
+Tue May 25 12:23:39 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * jv-typeprint.c (java_type_print_base, jv-valprint.c
+ (java_print_value_fields): Add static declaration.
+
+ * jv-lang.c (java_lookup_type, get_java_utf8_name,
+ java_lookup_type): Add static declaration.
+ (get_java_class_symtab, java_class_is_primitive,
+ java_value_string): Add declaration. Make static.
+ (java_rerun_cleanup): Add extern declaration for this stub
+ function.
+
+Tue May 25 12:06:29 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h: When multi-arch, check that REGISTER_NAMES was not
+ defined.
+
+Mon May 24 16:16:29 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * inflow.c (_initialize_inflow), annotate.c
+ (_initialize_annotate), os9kread.c (_initialize_os9kread),
+ serial.c (_initialize_serial), nlmread.c (_initialize_nlmread),
+ f-valprint.c (_initialize_f_valprint), cp-valprint.c
+ (_initialize_cp_valprint), typeprint.c (_initialize_typeprint),
+ complaints.c (_initialize_complaints), scm-lang.c
+ (_initialize_scheme_language), m2-lang.c
+ (_initialize_m2_language), dbxread.c (_initialize_dbxread),
+ f-lang.c (_initialize_f_language), ch-lang.c
+ (_initialize_chill_language), c-lang.c (_initialize_c_language),
+ corefile.c (_initialize_core), stabsread.c
+ (_initialize_stabsread), mipsread.c (_initialize_mipsread),
+ elfread.c (_initialize_elfread), coffread.c
+ (_initialize_coffread), maint.c (_initialize_maint_cmds),
+ demangle.c (_initialize_demangler), maint.c
+ (_initialize_maint_cmds), language.c (_initialize_language): Add
+ external declaration.
+ * ui-out.c (_initialize_ui_out), cli-out.c (_initialize_cli_out):
+ Ditto.
+
+Mon May 24 10:04:56 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/z8k/tm-z8k.h, config/w65/tm-w65.h, config/v850/tm-v850.h,
+ config/tic80/tm-tic80.h, config/tahoe/tm-tahoe.h,
+ config/rs6000/tm-rs6000.h, config/sparc/tm-sparc.h,
+ config/sh/tm-sh.h, config/pyr/tm-pyr.h, config/pa/tm-hppa.h,
+ config/ns32k/tm-merlin.h, config/mn10300/tm-mn10300.h,
+ config/mn10200/tm-mn10200.h, config/mips/tm-mips.h,
+ config/m88k/tm-m88k.h, config/m68k/tm-news.h,
+ config/m68k/tm-delta68.h, config/m68k/tm-isi.h,
+ config/m68k/tm-m68k.h, config/m32r/tm-m32r.h,
+ config/i960/tm-i960.h, config/i386/tm-i386v.h,
+ config/i386/tm-i386.h, config/h8500/tm-h8500.h,
+ config/h8300/tm-h8300.h, config/fr30/tm-fr30.h,
+ config/d30v/tm-d30v.h, config/d10v/tm-d10v.h,
+ config/convex/tm-convex.h, config/arc/tm-arc.h,
+ config/arm/tm-arm.h, config/alpha/tm-alpha.h,
+ config/a29k/tm-a29k.h: Re-write definition of FRAME_NUM_ARGS so
+ that it returns NUM_ARGS as a result instead of setting a variable
+ as a side effect.
+
+ * ns32k-tdep.c (merlin_frame_num_args), tahoe-tdep.c
+ (tahoe_frame_num_args), vax-tdep.c (vax_frame_num_args),
+ m68k-tdep.c (news_frame_num_args, delta68_frame_num_args,
+ isi_frame_num_args), convex-tdep.c (convex_frame_num_args): New
+ functions.
+
+ * stack.c (print_args_stub): Update use of FRAME_NUM_ARGS.
+
+Mon May 24 11:57:04 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (remote_xfer_memory): Re-write with assumption that
+ REMOTE_TRANSLATE_XFER_ADDRESS is defined. Pass targ_addr and
+ targ_len by reference.
+ (REMOTE_TRANSLATE_XFER_ADDRESS): Provide default definition.
+
+ * remote-d10v.c (remote_d10v_translate_xfer_address): Update.
+ * config/d10v/tm-d10v.h (REMOTE_TRANSLATE_XFER_ADDRESS): Update.
+
+Mon May 24 12:10:58 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * value.h (default_push_arguments): Add function declaration.
+
+ * alpha-tdep.c (alpha_about_to_return), gdbarch.c (verify_gdbarch,
+ arch_ok, set_arch), command.c (find_cmd), infrun.c
+ (follow_inferior_fork, follow_fork, follow_vfork,
+ set_schedlock_func, is_internal_shlib_eventpoint,
+ stopped_for_internal_shlib_event, stopped_for_shlib_catchpoint,
+ xdb_handle_command), infcmd.c (run_no_args_command, go_command),
+ symfile.c (add_filename_language, set_ext_lang_command,
+ info_ext_lang_command, init_filename_language_table), symtab.c
+ (overload_list_add_symbol), defs.h (default_get_saved_register),
+ ax-general.c (grow_expr, append_const, read_const, generic_ext):
+ Ditto.
+
+ * infrun.c (currently_stepping): Ditto. Make static.
+
+ * valops.c (hand_function_call): Explictly type static variable
+ ``checked''.
+
+Mon May 24 08:36:18 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (d10v_breakpoint_from_pc, d10v_register_name,
+ d10v_register_byte, d10v_register_raw_size,
+ d10v_register_virtual_size, d10v_register_virtual_type,
+ d10v_make_daddr, d10v_make_iaddr, d10v_daddr_p, d10v_iaddr_p,
+ d10v_convert_iaddr_to_raw, d10v_convert_daddr_to_raw,
+ d10v_store_struct_return, d10v_store_return_value,
+ d10v_extract_struct_value_address, d10v_frame_saved_pc,
+ d10v_frame_args_address, d10v_frame_locals_address,
+ d10v_saved_pc_after_call): New functions.
+
+ * config/d10v/tm-d10v.h (REGISTER_BYTE, REGISTER_RAW_SIZE,
+ REGISTER_VIRTUAL_SIZE, REGISTER_VIRTUAL_TYPE, STORE_STRUCT_RETURN,
+ D10V_MAKE_DADDR, D10V_MAKE_IADDR, D10V_DADDR_P, D10V_IADDR_P,
+ D10V_CONVERT_DADDR_TO_RAW, D10V_CONVERT_IADDR_TO_RAW,
+ STORE_STRUCT_RETURN, STORE_RETURN_VALUE,
+ EXTRACT_STRUCT_VALUE_ADDRESS, SAVED_PC_AFTER_CALL, FRAME_SAVED_PC,
+ FRAME_ARGS_ADDRESS): Re-define using new functions.
+
+ * config/d10v/tm-d10v.h (BREAKPOINT_FROM_PC): Replace BREAKPOINT.
+ (REGISTER_NAME): Replace REGISTER_NAMES.
+
+ * utils.c (core_addr_lessthan, core_addr_greaterthan): New
+ functions.
+ * defs.h (core_addr_lessthan, core_addr_greaterthan): Declare.
+
+Sat May 22 16:44:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * utils.c (n_spaces): Handle case where first call has N equal to
+ zero.
+ (print_spaces): Use n_spaces.
+
+Fri May 21 11:23:54 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * valops.c (value_push): Remove conditional definition based on
+ absense of macro PUSH_ARGUMENTS. Pass SP and STRUCT_ADDR by
+ reference.
+ (default_push_arguments): New function.
+
+ * config/v850/tm-v850.h, config/tic80/tm-tic80.h,
+ config/sparc/tm-sparc.h, config/sparc/tm-sp64.h,
+ config/sh/tm-sh.h, config/rs6000/tm-rs6000.h, config/pa/tm-hppa.h,
+ config/mn10300/tm-mn10300.h, config/mn10200/tm-mn10200.h,
+ config/mips/tm-mips.h, config/m32r/tm-m32r.h,
+ config/h8300/tm-h8300.h, config/fr30/tm-fr30.h,
+ config/d30v/tm-d30v.h, config/d10v/tm-d10v.h, config/arm/tm-arm.h,
+ config/alpha/tm-alpha.h: Update definition of PUSH_ARGUMENTS.
+ Return updated SP.
+
+ * rs6000-tdep.c (rs6000_push_arguments): Rename push_arguments.
+
+1999-05-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * breakpoint.c (breakpoint_1): Added ui_out output code but still
+ uses old code by default.
+
+1999-05-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * Makefile.in: Added ui-ou files.
+ * main.c (main): Install cli_out by default.
+ * ui-out.c (ui_out_table_begin): Use saved table id.
+
+1999-05-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * ui-out.h: Export implementation vectors so they can be
+ installed in main.c and top.c.
+
+1999-05-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * ui-out.h: New file. Defines the ui_out API.
+ * ui-out.c: New file. Implements the ui_out API abstraction only.
+ * cli-out.c: New file. Implements low-level ui-out primitives for
+ CLI-based interaction.
+
+1999-05-20 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * top.c (simplified_command_loop): Reformat using GNU style.
+ (call_interp_loop): Ditto.
+
+Thu May 20 12:18:28 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * blockframe.c (get_prev_frame): Remove #ifdef around test for
+ FRAMELESS_FUNCTION_INVOCATION.
+ (get_prev_frame): Change FRAMELESS_FUNCTION_INVOCATION call to a
+ function invocation.
+ * i386-tdep.c (i386_frame_num_args), stack.c (frame_info): Ditto.
+ * config/z8k/tm-z8k.h, config/w65/tm-w65.h, config/vax/tm-vax.h,
+ config/sparc/tm-sparc.h, config/sh/tm-sh.h,
+ config/rs6000/tm-rs6000.h, config/pa/tm-hppa.h,
+ config/mips/tm-mips.h, config/m88k/tm-m88k.h,
+ config/m68k/tm-m68k.h, config/i960/tm-i960.h,
+ config/i386/tm-sun386.h, config/i386/tm-i386v.h,
+ config/i386/tm-i386.h, config/h8500/tm-h8500.h,
+ config/h8300/tm-h8300.h, config/fr30/tm-fr30.h,
+ config/d30v/tm-d30v.h, config/d10v/tm-d10v.h,
+ config/convex/tm-convex.h, config/arm/tm-arm.h,
+ config/arc/tm-arc.h, config/alpha/tm-alpha.h,
+ config/a29k/tm-a29k.h: Update FRAMELESS_FUNCTION_INVOCATION.
+ * fr30-tdep.c (fr30_frameless_function_invocation), convex-tdep.c
+ (convex_frameless_function_invocation), arm-tdep.c
+ (arm_frameless_function_invocation): New functions.
+
+1999-05-20 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * top.c: Change dates in comments to ISO format.
+
+ * event-top.c: Ditto.
+ * event-loop.c: Ditto.
+ * main.c: Ditto.
+
+1999-05-20 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * top.c (simplified_command_loop): New function. It is just a
+ bare minimal command_loop.
+ (call_interp_loop): New function. Call the correct version of the
+ command loop, with the appropriate input reading function,
+ depending on which interpreter gdb was invoked with.
+
+ * main.c (main): Recognize and handle the new command line option
+ --interpreter. If an interpreter is specified, call the appropriate
+ command handling function.
+
+1999-05-19 Keith Seitz <keiths@cygnus.com>
+
+ * config/mcore/tm-mcore.h (BELIEVE_PCC_PROMOTION): Define. We
+ really do want to believe what gcc tells us about types...
+
+1999-05-19 Keith Seitz <keiths@cygnus.com>
+
+ * config/mcore/tm-mcore.h (FRAME_ARGS_ADDRESS): Define to a function.
+ (FRAME_LOCALS_ADDRESS): Ditto.
+ * mcore-tdep.c (mcore_frame_args_addcress): New function.
+ (mcore_frame_locals_address): New function.
+
+ * monitor.c (monitor_open): Only assume we have eight
+ breakpoints if the monitor implementation does not tell
+ us how many there really are. Alloc memory for these
+ dynamically.
+ (monitor_close): Free memory associated with breakpoint
+ storage.
+ (monitor_insert_breakpoint): Don't rely on a hardcoded
+ number of breakpoints.
+ (monitor_remove_breakpoint): Ditto.
+ (NUM_MONITOR_BREAKPOINTS): Removed and replaced with monitor_ops
+ specification.
+ * monitor.h (struct monitor_ops): Add new member so that the
+ individual monitor implementations can tell us how many
+ breakpoints the monitor supports.
+
+ * mcore-rom.c (init_picobug_cmds): Add number of breakpoints supported
+ by picobug monitor.
+
+1999-05-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Philippe De Muyter <phdm@macqel.be>:
+ * event-loop.h: Include sys/wait.h only if HAVE_SYS_WAIT_H.
+
+1999-05-17 Keith Seitz <keiths@cygnus.com>
+
+ * configure.tgt: Add MCore target.
+ * Makefile.in: Add mcore-tdep.c and mcore-rom.c
+ * config/mcore/tm-mcore.h: New file.
+ * config/mcore/mcore.mt: New file.
+ * mcore-rom.c: New file.
+ * mcore-tdep.c: New file.
+
+1999-05-17 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * top.c (print_command_line): Added the missing stream argument.
+ * gdbcmd.h: Added argument to prototype.
+ * command.c: Fixed call to include extra argument.
+ * breakpoint.c: Same.
+
+1999-05-14 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Targets are #defining PREPARE_TO_PROCEED with inconsistent numbers
+ of arguments. Since the Mach 3 target needs an argument, we'll
+ make things consistent by adding an argument everywhere.
+ * infrun.c (proceed): Pass an argument to PREPARE_TO_PROCEED.
+ * config/pa/nm-hppah.h (PREPARE_TO_PROCEED): Add ignored argument
+ to definition.
+
+1999-05-11 Stan Shebs <shebs@andros.cygnus.com>
+
+ Fri Apr 23 13:27:34 PDT 1999 Toshiyasu Morita (tm@netcom.com)
+ * sh-stub.c: Mostly localize processor dependencies.
+
+1999-05-10 Martin Hunt <hunt@cygnus.com>
+
+ * debugify.c, debugify.h: Removed because they are no
+ longer used.
+
+1999-05-08 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * infrun.c (_initialize_infrun): Handle TARGET_SIGNAL_LWP,
+ TARGET_SIGNAL_WAITING, and TARGET_SIGNAL_CANCEL like SIGALRM or
+ SIGIO --- pass them through to the inferior silently.
+ * target.h (enum target_signals): Add TARGET_SIGNAL_CANCEL, for
+ Solaris's SIGCANCEL.
+ * target.c (target_signal_from_host, target_signal_to_host): Add
+ mapping between SIGCANCEL and TARGET_SIGNAL_CANCEL.
+ (signals): Add entry for SIGCANCEL.
+
+1999-05-07 Stan Shebs <shebs@andros.cygnus.com>
+
+ After years of talking about it, finally break up the
+ wait_for_inferior loop.
+ * infrun.c (struct execution_control_state): New struct,
+ holds what used to be local vars governing wfi behavior.
+ (init_execution_control_state): New function, was code in
+ wfi that set up execution control state.
+ (handle_inferior_event): New function, was body of main
+ wfi loop. Rewrite all local var references to go through
+ the ecs structure passed into this function.
+ (wait_for_inferior): Rewrite to set up and use execution control
+ state, and to call the new functions.
+ (currently_stepping): New function, was the macro
+ CURRENTLY_STEPPING.
+ (enum infwait_states): Rename from wfi_states.
+ (infwait_normal_state, etc): Similarly.
+
+Thu May 6 15:25:32 1999 Philippe De Muyter <phdm@macqel.be>
+
+ * coffread.c (coff_symtab_read): Call `record_line' with the line
+ number of the ".bf" symbol only for one-line functions.
+
+1999-05-06 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * Makefile.in: thread.o depends on target.h.
+
+1999-05-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-top.c (change_line_handler): Use POLLIN instead of
+ POLLRDNORM, for compatibility with Linux.
+ (setup_event_loop): Ditto.
+
+1999-05-06 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * mips-tdep.c (heuristic_proc_start): Rewrite cryptic error
+ message about hitting the "heuristic fence post" with something
+ that actually gives the user a fighting chance of figuring out
+ why GDB is unhappy.
+
+1999-05-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * top.c: Include event-loop.h.
+ (init_main): Add async version of 'set prompt' command.
+ If in async mode define the editing and annotate set
+ commands in a different way.
+ Initialize new variable asyn_command_editing_p to 1.
+ Initialize the gdb prompt for async mode.
+ (quit_cover): Make not static, for use by the event loop.
+ (gdb_init): Call async_init_signals for the asynchronous case.
+ (source_line_number, source_file_name, source_error,
+ source_pre_error, history_expansion_p): Make non-static, so
+ event-top.c can use them.
+ (command_loop_marker): Make non-static, for use in event-top.c.
+ Include event-loop.h.
+
+ * top.h: Add prototype for async_init_signals.
+ (SET_TOP_LEVEL): Move here from main.c.
+ Add setup_event_loop to exported functions.
+
+ * defs.h: Add async_hook to exported variables.
+
+ * main.c (SET_TOP_LEVEL): Move to top.h, so that it is visible in
+ event-loop.c. Add new global variable async to determine whether
+ we are running in async mode or not.
+ (main): Add support for --async switch. Use async_hook to call
+ setup_event_loop, when running in async mode.
+
+ * event-top.c: New file. Gdb input line handler and command line
+ handler for the event loop. Initialization of signal handlers.
+ All the handled signals have handlers called handle_<signalname>.
+ Set up all the appropriate tokens for asynchronous signal
+ handling.
+
+ * event-loop.h: New file. Data structures and definitions for the
+ event loop.
+
+ * event-loop.c: New file. Functions for the event loop
+ implementation.
+
+ * config.in: Regenerate with autoheader.
+
+ * configure.in (AC_CHECK_FUNCS): Add poll to list of functions
+ to be checked for.
+
+ * configure: Regenerate.
+
+ * Makefile.in (SFILES): Add new source files.
+ (eventloop_h): Define.
+ (COMMON_OBS): Add new object files.
+ (event-loop.o): Add rule for target object.
+ (event-top.o): Ditto.
+
+1999-05-05 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infrun.c (wait_for_inferior): Transform breaks and continues
+ into gotos, move the target_wait to the very top of the loop.
+
+1999-05-05 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * configure.in: Ensure that GDB links with libuser32.a under
+ cygwin because libreadline requires it.
+ * Makefile.in (WIN32LIBS): Substitute in result from configure
+ * configure: regenerate
+
+1999-05-04 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Fix from John Rigby. Richard Henderson says it seems okay.
+ * alpha-tdep.c (PROC_DUMMY_FRAME): As long as we're abusing fields
+ of (proc)->pdr, we ought to at least abuse one large enough to
+ hold the value we're trying to store in it. iopt is only 32 bits
+ wide; cbLineOffset is a bfd_vma.
+
+1999-05-04 DJ Delorie <dj@cygnus.com>
+
+ DJGPP changes from Robert Hoehne <robert.hoehne@gmx.net>
+
+ * ser-go32.c: correct includes
+ * source.c (openp): use ROOTED_P instead of SLASH_P
+ * go32-nat.c: enhance exception and NPX handling
+ (go32_kill_inferior): fix small bug killing inferior
+ * configure.in: don't look for termcap with djgpp
+ * configure: rebuild
+
+1999-05-04 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * main.c (main): Comment out unused and undocumented command line
+ option '-'.
+
+1999-04-30 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Cleanup from Philippe De Muyter:
+ * configure.in (BFD_NEED_DECLARATION): Check also for strstr.
+ * acconfig.h (NEED_DECLARATION_MALLOC, NEED_DECLARATION_REALLOC,
+ NEED_DECLARATION_FREE, NEED_DECLARATION_STRERROR): Define slots
+ removed; they are now generated automatically.
+ * gdb_string.h (strstr): Provide function prototype if
+ NEED_DECLARATION_STRSTR.
+ * configure, config.in: Regenerated.
+
+Fri Apr 30 11:16:09 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * target.h (to_find_new_threads): new target ops vector.
+ (target_find_new_threads): define.
+ * target.c (update_current_target): inherit new target ops vector.
+ * remote.c: Setup to_find_new_threads vector.
+ * sol-thread.c: ditto.
+ * thread.c (target_find_new_threads): rename: local_find_new_threads.
+ (info_threads_command): call target_find_new_threads by new method,
+ as a target ops vector, rather than previous macro definition method.
+ * infcmd.c (go_command): define only if in xdb mode.
+ * procfs.c: fix typo in comment.
+
+Fri Apr 30 01:02:05 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppah-nat.c: Fix various coding convention violations introduced
+ by HP.
+ (child_acknowledge_created_inferior): Do nothing if PT_SET_EVENT_MASK
+ is not defined.
+
+1999-04-28 Stan Shebs <shebs@andros.cygnus.com>
+
+ * TODO: Add some items inspired by review of the manual.
+
+Tue Apr 27 17:38:19 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/z8k/tm-z8k.h, config/v850/tm-v850.h,
+ config/tic80/tm-tic80.h, config/sparc/tm-sparc.h,
+ config/sh/tm-sh.h, config/pyr/tm-pyr.h, config/pa/tm-hppa.h,
+ config/mn10300/tm-mn10300.h, config/mn10200/tm-mn10200.h,
+ config/mips/tm-mips.h, config/m88k/tm-m88k.h,
+ config/m68k/tm-m68k.h, config/m32r/tm-m32r.h,
+ config/i960/tm-i960.h, config/i386/tm-i386.h,
+ config/h8500/tm-h8500.h, config/h8300/tm-h8300.h,
+ config/fr30/tm-fr30.h, config/d30v/tm-d30v.h,
+ config/d10v/tm-d10v.h, config/alpha/tm-alpha.h,
+ config/arm/tm-arm.h, config/a29k/tm-a29k.h, config/arc/tm-arc.h:
+ Change SKIP_PROLOGUE and SKIP_PROLOGUE_FRAMELESS_P macros so that
+ they return the new address.
+
+ * sparc-tdep.c (sparc_skip_prologue), hppa-tdep.c
+ (hppa_skip_prologue), m88k-tdep.c
+ (m88k_skip_prologue), i960-tdep.c
+ (i960_skip_prologue), arc-tdep.c
+ (arc_skip_prologue), a29k-tdep.c (a29k_skip_prologue): Rename
+ skip_prologue function.
+
+ * config/m68k/tm-isi.h: Convert macro SKIP_PROLOGUE into a new
+ function.
+ * m68k-tdep.c (isi_skip_prologue): That new function.
+ * vax-tdep.c (vax_skip_prologue), config/vax/tm-vax.h: Ditto.
+ * tahoe-tdep.c (tahoe_skip_prologue), config/tahoe/tm-tahoe.h: Ditto.
+ * rs6000-tdep.c (rs6000_skip_prologue), config/rs6000/tm-rs6000.h:
+ Ditto.
+ * ns32k-tdep.c (umax_skip_prologue), config/ns32k/tm-umax.h: Ditto.
+ * config/ns32k/tm-merlin.h, ns32k-tdep.c (merlin_skip_prologue):
+ Ditto.
+ * config/m68k/tm-altos.h, m68k-tdep.c (altos_skip_prologue): Ditto.
+ * config/convex/tm-convex.h, convex-tdep.c (convex_skip_prologue):
+ Ditto.
+
+ * symtab.c (in_prologue, find_function_start_sal, decode_line_1),
+ infrun.c (wait_for_inferior), blockframe.c
+ (frameless_look_for_prologue): Update.
+ * config/fr30/tm-fr30.h (FRAMELESS_FUNCTION_INVOCATION): Update.
+
+1999-04-27 Stan Shebs <shebs@andros.cygnus.com>
+
+ * TODO: Remove item about DEBUG_EXPRESSIONS, no longer meaningful.
+
+ * infrun.c (enum wfi_state): New enum.
+ (wait_for_inferior): Merge all but one of the target_wait calls
+ into a single call, add a wfi_state variable to encode which of
+ the calls is being made.
+
+1999-04-26 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Fix from Dave Holcomb.
+ * hpux-thread.c (init_hpux_thread_ops): Use the right function
+ name when initializing hpux_thread_ops.to_thread_alive.
+
+ * coffread.c (coff_symfile_read): If we have a `.stab' section,
+ but no `.stabstr' section, then print an error message; don't
+ crash.
+
+1999-04-26 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ 1999-04-25 Mark Kettenis <kettenis@gnu.org>
+
+ * gnu-nat.c (gnu_attach): Call target_terminal_init before calling
+ inf_set_traced, since that function calls code that might try to
+ restore the terminal settings.
+
+Mon Apr 26 08:55:46 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h, gdbarch.c: More format cleanups.
+
+Sun Apr 25 18:54:51 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h (CALL_DUMMY_STACK_ADJUST_P): Replace
+ SIZEOF_CALL_DUMMY_STACK_ADJUST_P.
+ (CALL_DUMMY_STACK_ADJUST): Replace
+ SIZEOF_CALL_DUMMY_STACK_ADJUST_P.
+ * gdbarch.c (gdbarch_call_dummy_stack_adjust,
+ set_gdbarch_call_dummy_stack_adjust): Define.
+
+Fri Apr 23 15:00:25 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.c (arch_ok): New function. Fix logic test for a valid
+ architecture.
+ (set_arch): Use.
+
+1999-04-22 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * README: Note that readline is not installed as a part of
+ make install.
+
+Thu Apr 22 21:02:28 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h, gdbarch.c (GET_SAVED_REGISTER, get_saved_register):
+ Add.
+ (struct gdbarch, verify_gdbarch, gdbarch_alloc, gdbarch_dump,
+ default_gdbarch): Update.
+
+ * value.h (get_saved_register): Cleanup prototype.
+ * findvar.c (default_get_saved_register): Rename function
+ get_saved_register.
+ (GET_SAVED_REGISTER): Define as default_get_saved_register when
+ undefined.
+ (get_saved_register): Always declare. Call GET_SAVED_REGISTER.
+
+ * sparc-tdep.c (sparc_get_saved_register): Rename function
+ get_saved_register.
+ * config/sparc/tm-sparc.h (GET_SAVED_REGISTER): Update.
+ * a29k-tdep.c (a29k_get_saved_register): Rename function
+ get_saved_register.
+ * config/a29k/tm-a29k.h (GET_SAVED_REGISTER): Update.
+
+ * config/d10v/tm-d10v.h, config/powerpc/tm-ppc-eabi.h,
+ config/h8300/tm-h8300.h, config/m32r/tm-m32r.h,
+ config/mn10200/tm-mn10200.h, config/mn10300/tm-mn10300.h,
+ config/sh/tm-sh.h, config/tic80/tm-tic80.h, config/v850/tm-v850.h:
+ Update macro GET_SAVED_REGISTER so that it calls
+ generic_get_saved_register.
+ * v850-tdep.c, tic80-tdep.c, sh-tdep.c, mn10300-tdep.c,
+ mn10200-tdep.c, m32r-tdep.c, h8300-tdep.c, rs6000-tdep.c: Delete
+ function get_saved_register.
+
+Thu Apr 22 13:32:23 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.c: Cleanup. Re-order the definition of the ``struct
+ gdbarch'' initialization functions so that maintenance is more
+ straightforward.
+
+Thu Apr 22 11:07:21 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h, gdbarch.c (use_generic_dummy_frames,
+ USE_GENERIC_DUMMY_FRAMES): Add.
+ (struct gdbarch, verify_gdbarch, gdbarch_alloc, gdbarch_dump,
+ default_gdbarch): Update.
+
+ * config/v850/tm-v850.h, config/tic80/tm-tic80.h,
+ config/sh/tm-sh.h, config/powerpc/tm-ppc-eabi.h,
+ config/mn10300/tm-mn10300.h, config/mn10200/tm-mn10200.h,
+ config/m32r/tm-m32r.h, config/h8300/tm-h8300.h,
+ config/fr30/tm-fr30.h, config/d10v/tm-d10v.h: Give the
+ USE_GENERIC_DUMMY_FRAMES macro the value one.
+ * inferior.h (USE_GENERIC_DUMMY_FRAMES): Default to a value of
+ zero.
+
+ * blockframe.c (generic_find_dummy_frame,
+ generic_pc_in_call_dummy, generic_read_register_dummy,
+ generic_push_dummy_frame, generic_pop_current_frame,
+ generic_pop_dummy_frame, generic_frame_chain_valid,
+ generic_get_saved_register): Always define.
+
+ * breakpoint.c (frame_in_dummy): Convert #ifdef
+ USE_GENERIC_DUMMY_FRAMES to runtime test.
+
+ * rs6000-tdep.c (pop_frame, push_arguments, push_arguments,
+ push_arguments, frame_saved_pc, rs6000_frame_chain,
+ rs6000_frame_chain): Convert #ifdef USE_GENERIC_DUMMY_FRAMES to
+ runtime test.
+ (get_saved_register): Always define.
+
+Wed Apr 21 17:15:52 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.c (gdbarch_dump): Fix robustness check on
+ BELIEVE_PCC_PROMOTION_TYPE.
+
+Wed Apr 21 15:39:27 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h (TARGET_BYTE_ORDER_SELECTABLE_P): When multi-arch,
+ force selectable byte order.
+ (CALL_DUMMY): Check for CALL_DUMMY definition when multi-arch. Are
+ incompatible.
+ * gdbarch.c (verify_gdbarch): Check call_dummy_stack_adjust.
+
+Wed Apr 21 14:45:44 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.c (gdbarch_update): Move dump-arch code from here.
+ (gdbarch_dump): To here. Make more robust.
+ * gdbarch.h (gdbarch_dump): Add prototype.
+
+ * gdbarch.c (enum set_arch): Declare.
+ (set_arch): Add type parameter. Only disable
+ ``target_architecture_auto'' when set_arch_manual.
+ (set_architecture, set_architecture_from_arch_mach,
+ set_architecture_from_file): Update.
+ (set_arch): When ``gdbarch_debug'', gdbarch_dump() the current
+ architecture.
+
+Wed Apr 21 10:48:53 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * frame.h (generic_pc_in_call_dummy): Make signature consistent
+ with other pc_in_call_dummy functions by adding SP parameter.
+ * blockframe.c (generic_pc_in_call_dummy): Update. Pass SP and
+ not FP to generic_find_dummy_frame().
+ * breakpoint.c (frame_in_dummy): Update.
+ * config/v850/tm-v850.h, config/tic80/tm-tic80.h,
+ config/sh/tm-sh.h, config/mn10300/tm-mn10300.h,
+ config/mn10200/tm-mn10200.h, config/m32r/tm-m32r.h,
+ config/h8300/tm-h8300.h, config/fr30/tm-fr30.h,
+ config/d10v/tm-d10v.h: Update PC_IN_CALL_DUMMY definition.
+
+Tue Apr 20 12:15:45 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/d10v/tm-d10v.h (GDB_TARGET_IS_D10V): Move from here.
+ * gdbarch.h (GDB_TARGET_IS_D10V): To here. Implement using
+ TARGET_ARCHITECTURE.
+ (D10V_MAKE_DADDR, D10V_MAKE_IADDR): Provide fatal default
+ definitions.
+
+ * valops.c (value_at): Replace #ifdef GDB_TARGET_IS_D10V code with
+ runtime test.
+ (value_fetch_lazy): Ditto.
+ * values.c (unpack_long): Ditto.
+ * printcmd.c (print_frame_args): Ditto.
+
+Sat Apr 17 15:39:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h: Cleanup multi-arch comments.
+
+Fri Apr 16 15:39:10 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h: Provide definition if GDB_MULTI_ARCH > 1 or
+ GDB_MULTI_ARCH > 0 and no previous definition.
+ * gdbarch.c (verify_gdbarch): Only verify a full multi-arch
+ target.
+
+1999-04-15 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infrun.c (wait_for_inferior) [HAVE_STEPPABLE_WATCHPOINT,
+ HAVE_NONSTEPPABLE_WATCHPOINT, HAVE_CONTINUABLE_WATCHPOINT]: Test
+ at runtime instead of compile time.
+
+Thu Apr 15 15:15:07 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * mips-tdep.c (struct gdbarch_tdep): Rename elf_abi to
+ elf_flags. Check ABFD is elf_flavour before extracting elf_flags.
+ Match ARCH against entire elf_flags instead of just the
+ EF_MIPS_ABI field.
+ (mips_gdbarch_init): Extract/print ef_mips_arch and
+ ef_mips_bitptrs and ef_mips_abi fields from elf_flags.
+
+1999-04-14 Philippe De Muyter <phdm@macqel.be>
+
+ * breakpoint.c (maintenance_info_breakpoints): Function made
+ static to match previous prototype.
+
+ * coffread.c (coff_record_line): Static function removed.
+ (enter_linenos): Call `record_line' instead of `coff_record_line'.
+ (FILE-LEVEL, coff_start_symtab, coff_end_symtab): `coff_record_line'
+ -related stuff removed.
+ (coff_symfile_read): Redundant statement removed.
+ (coff_symtab_read): `record_line' is now called with the first line
+ number of each function, given by the ".bf" symbol. This solves
+ the line-number bug for one-line functions.
+
+Wed Apr 14 11:09:45 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h (BELIEVE_PCC_PROMOTION_TYPE, BELIEVE_PCC_PROMOTION):
+ Add multi-arch definitions.
+ * gdbarch.c (gdbarch_believe_pcc_promotion,
+ gdbarch_believe_pcc_promotion_type): New functions.
+ (gdbarch_update): Update
+ (struct gdbarch default_gdbarch): Update.
+
+ * stabsread.c (BELIEVE_PCC_PROMOTION_TYPE): Provide default.
+ (define_symbol): Change #if BELIEVE_PCC_PROMOTION_TYPE and #if
+ BELIEVE_PCC_PROMOTION to if().
+
+1999-04-13 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in (HAVE_MULTIPLE_PROC_FDS): Don't define if we're
+ on a Solaris host (of any architecture).
+ * configure: Regenerated.
+
+Wed Apr 14 08:23:32 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.c (SET_GDBARCH, GET_GDBARCH, FSET_GDBARCH): New macros.
+ (gdbarch_byte_order, gdbarch_long_bit, gdbarch_long_long_bit,
+ gdbarch_ptr_bit, gdbarch_call_dummy_location,
+ gdbarch_call_dummy_address, gdbarch_call_dummy_address,
+ gdbarch_call_dummy_breakpoint_offset,
+ gdbarch_call_dummy_breakpoint_offset, gdbarch_call_dummy_length,
+ gdbarch_pc_in_call_dummy, dbarch_call_dummy_breakpoint_offset_p,
+ dbarch_call_dummy_p, dbarch_call_dummy_words,
+ dbarch_sizeof_call_dummy_words, dbarch_call_dummy_stack_adjust,
+ dbarch_call_dummy_stack_adjust_p): Define using new macros.
+
+1999-04-13 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * rom68k-rom.c (init_rom68k_cmds): Fix an accidental substitution
+ in monitor command strings, fix some formatting mistakes.
+
+1999-04-13 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.tgt (arm-*-*): Whack another vestige of wingdb.
+
+1999-04-12 James Ingham <jingham@cygnus.com>
+
+ * arm-tdep.c (arm_pop_frame): don't clobber the previous frame's
+ stack pointer (stored in frame->framereg's register) BEFORE
+ reading it. This was causing "return" to behave very oddly.
+
+1999-04-12 Stan Shebs <shebs@andros.cygnus.com>
+
+ * NEWS: Mention tic80.
+
+1999-04-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * a68v-nat.c: Remove reference to 'extern char registers[]' throughout.
+ * altos-xdep.c: Ditto.
+ * arm-xdep.c: Ditto.
+ * convex-xdep.c: Ditto.
+ * cxux-nat.c: Ditto.
+ * hp300ux-nat.c: Ditto.
+ * hppab-nat.c: Ditto.
+ * i386aix-nat.c: Ditto.
+ * i386mach-nat.c: Ditto.
+ * m88k-nat.c: Ditto.
+ * ptx4-nat.c: Ditto.
+ * pyr-xdep.c: Ditto.
+ * rs6000-nat.c: Ditto.
+ * sun3-nat.c: Ditto.
+ * sun386-nat.c: Ditto.
+ * symm-nat.c: Ditto.
+ * umax-xdep.c: Ditto.
+ * i386v4-nat.c: Ditto. Also include inferior.h.
+ * m68k-tdep.c: Ditto. Also include inferior.h.
+
+Mon Apr 12 15:57:16 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * inferior.h (CALL_DUMMY_STACK_ADJUST, CALL_DUMMY_STACK_ADJUST_P):
+ Provide default definitions.
+ * valops.c (hand_function_call): Replace #ifdef
+ CALL_DUMMY_STACK_ADJUST with if (CALL_DUMMY_STACK_ADJUST_P).
+
+ * gdbarch.h (SIZEOF_CALL_DUMMY_STACK_ADJUST,
+ (SIZEOF_CALL_DUMMY_STACK_ADJUST_P): Define
+ * gdbarch.c (struct gdbarch): Add call_dummy_stack_adjust,
+ call_dummy_stack_adjust_p.
+ (gdbarch_call_dummy_stack_adjust,
+ set_gdbarch_call_dummy_stack_adjust,
+ gdbarch_call_dummy_stack_adjust_p,
+ set_gdbarch_call_dummy_stack_adjust_p): New functions.
+ (default_gdbarch): Update.
+
+1999-04-09 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * ax-gdb.c, ax-gdb.h, ax-general.c, ax.h: Remove RCS Id strings.
+ They're a pain.
+
+ * GDB 4.18 released.
+ * Makefile.in (VERSION): Bump to 4.18.1.
+
+Thu Apr 8 16:04:34 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * inferior.h (CALL_DUMMY_P, CALL_DUMMY_WORDS,
+ SIZEOF_CALL_DUMMY_WORDS): Define macros.
+ (PUSH_DUMMY_FRAME, FIX_CALL_DUMMY, STORE_STRUCT_RETURN): Provide
+ fatal default.
+
+ * inferior.h, gdbarch.c (call_dummy_words,
+ sizeof_call_dummy_words): Declare/Define variables.
+ * valops.c (value_arg_coerce, find_function_addr,
+ call_function_by_hand): Always define.
+ (hand_function_call): Rename CALL_DUMMY version of
+ call_function_by_hand. Make static. Add prototype.
+ (hand_function_call): Update. Allocate space for *dummy and
+ *dummy1 using alloca.
+ * breakpoint.c (frame_in_dummy): Update.
+
+ * gdbarch.h (CALL_DUMMY_P, CALL_DUMMY_WORDS,
+ SIZEOF_CALL_DUMMY_WORDS): Define.
+ * gdbarch.c (gdbarch_call_dummy_p, set_gdbarch_call_dummy_p,
+ gdbarch_call_dummy_words, set_gdbarch_call_dummy_words,
+ gdbarch_sizeof_call_dummy_words,
+ set_gdbarch_sizeof_call_dummy_words): New functions.
+ (gdbarch_alloc, verify_gdbarch, gdbarch_update, struct
+ default_gdbarch): Update.
+
+1999-04-08 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * monitor.c (monitor_read_memory): If a MO_GETMEM_NEEDS_RANGE
+ monitor, increase the end address by one byte.
+
+1999-04-08 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * dbug-rom.c (init_dbug_cmds): Fix strings in
+ dbug_cmds.{step,clr_break,clr_all_break,fill} to send correct
+ commands to the monitor.
+
+1999-04-08 Keith Seitz <keiths@cygnus.com>
+
+ * m32r-stub.c (branchDestination): Undo overly ambitious
+ sed script's conversion of cast from "char" to "unsigned char".
+ Return offset should now be properly computed.
+
+Thu Apr 8 14:13:19 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * inferior.h (CALL_DUMMY_BREAKPOINT_OFFSET_P): New macro.
+ Non-zero when CALL_DUMMY_BREAKPOINT_OFFSET is valid.
+
+ * infcmd.c (breakpoint_auto_delete_contents): Always define.
+ (run_stack_dummy): Update.
+ * infrun.c (wait_for_inferior): Update
+
+ * gdbarch.h (CALL_DUMMY_BREAKPOINT_OFFSET_P): New macro.
+ * gdbarch.c (set_gdbarch_call_dummy_breakpoint_offset_p,
+ gdbarch_call_dummy_breakpoint_offset_p): New functions.
+ (struct gdbarch, gdbarch_alloc, default_gdbarch, gdbarch_update):
+ Update.
+
+1999-04-07 Stan Shebs <shebs@andros.cygnus.com>
+
+ * MAINTAINERS: Mark Alexander can no longer maintain
+ h8300 and other embedded targets, sniff.
+
+1999-04-06 Stan Shebs <shebs@andros.cygnus.com>
+
+ * inftarg.c (child_wait): Initialize execd_pathname.
+ * target.c (debug_to_has_execd): Handle NULL execd_pathname.
+
+ * solib.c (clear_solib): Don't call disable_breakpoints_in_shlibs,
+ this breaks rerunning on sun4 native.
+
+1999-04-06 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * config/sparc/nm-linux.h: Don't redefine PT_ATTACH to use the
+ deprecated PTRACE_SUNATTACH compatibility commands. The
+ definitions from <sys/ptrace.h> are fine.
+
+1999-04-06 Martin Hunt <hunt@cygnus.com>
+
+ * annotate.h: Declare annotate_signal_hook.
+
+ * annotate.c (annotate_signal): Add a call to
+ annotate_signal_hook().
+
+1999-04-06 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * dwarf2read.c (dwarf_decode_lines): Don't call record_line when
+ we hit a DW_LNE_end_sequence instruction.
+
+ * README: Note that GDB requires an ANSI C compiler, and explain
+ how to get GCC.
+
+ * README: Update.
+
+1999-04-05 Stan Shebs <shebs@andros.cygnus.com>
+
+ * NEWS: Add more notes about user-visible changes.
+
+Mon Apr 5 14:56:59 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * target.c (target_signal_to_string): check for signal
+ number in range; otherwise if the target board returns
+ a bogus signal number we might core dump (per David Taylor).
+
+1999-04-05 David Taylor <taylor@ryobi.cygnus.com>
+
+ * utils.c (fputs_maybe_filtered): test value of
+ pagination_enabled before paginating.
+
+1999-04-02 James Ingham <jingham@cygnus.com>
+
+ * blockframe.c (get_prev_frame): Remove the redundant
+ get_prev_frame_info. It is now exactly the same as
+ get_prev_frame, so there is no reason to have both functions.
+
+ * rs6000-tdep.c (rs6000_init_extra_frame_info):
+ frame.h:
+ a29k-tdep.c (init_extra_frame_info):
+ config/a29k/tm-a29k.h:
+ i386-tdep.c:
+ Change all references to get_prev_frame_info to get_prev_frame.
+
+1999-04-02 Stan Shebs <shebs@andros.cygnus.com>
+
+ * bcache.c, bcache.h, breakpoint.c, defs.h, expprint.c,
+ expression.h, gdbarch.c, gdbtypes.c, gdbtypes.h, gnu-nat.c,
+ gnu-nat.h, hppa-tdep.c, maint.c, monitor.c, objfiles.h, parse.c,
+ remote-mips.c, remote-sds.c, remote.c, sol-thread.c, symmisc.c,
+ symtab.h, target.c, top.c, typeprint.c, config/nm-gnu.h: Evaporate
+ the unused MAINTENANCE_CMDS conditional.
+
+1999-04-02 James Ingham <jingham@cygnus.com>
+
+ * config/arm/tm-arm.h: (EXTRACT_STRUCT_VALUE_ADDRESS): This needs
+ to call extract_address, not just cast the first 4 bytes, since
+ the result will be passed to value_at which expects host-byte
+ order.
+
+ * arm-tdep.c (arm_scan_prologue): The prologue_start address was
+ directly &'ed with 0x03fffffc, rather than using
+ ADDR_BITS_REMOVE. This would cause inferior function calls to
+ report the stack incorrectly on return.
+
+
+1999-04-02 Keith Seitz <keiths@cygnus.com>
+
+ * top.c (ui_loop_hook): Change declaration. Now returns an int.
+ * win32-nat.c (child_wait): Timeout WaitForDebugEvent and call
+ the ui_loop_hook if there was no debug event.
+ * top.c (ui_loop_hook): Change to return an int and include
+ on all non-Cygwin builds.
+ * v850ice.c: Change prototype of ui_loop_hook.
+ (v850ice_wait): Update call to ui_loop_hook.
+ * ser-unix.c (hardwire_readchar): Enable ui_loop_hook callbacks
+ for non-Cygwin builds. Check return status of ui_loop_hook and
+ return a timeout if told to detach. Add more documentation.
+ * ser-tcp.c (tcp_readchar): Break up timeouts into one second
+ intervals and call ui_loop_hook so that other UIs can
+ keep up to date. If ui_loop_hook returns non-zero, then
+ return SERIAL_TIMEOUT to facilitate detaching from the
+ target.
+ * remote.c (remote_interrupted_already): Remove.
+ (remote_interrupt_twice): Revive.
+ (remote_interrupt): Call remote_stop to interrupt the target
+ and install remote_interrupt_twice to take more severe
+ actions if this fails.
+ (remote_stop): Only attempt to stop the target. This separates
+ the command line from other UIs.
+ * remote-sim.c (gdb_os_poll_quit): Add a call to ui_loop_hook,
+ if it is defined.
+
+1999-04-01 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Fix for cross-debugging on an AIX host from Johanna Svenningsson:
+ * ax-gdb.h (enum axs_lvalue_kind): Remove trailing comma from enum.
+ * ax.h (enum agent_op): Same.
+ * tracepoint.h (enum actionline_type): Same.
+ * config/xm-aix4.h: Add declaration for termdef.
+
+1999-03-31 Stan Shebs <shebs@andros.cygnus.com>
+
+ * jv-lang.h (dynamics_objfile): Remove decl, conflicts with static
+ decl in jv-lang.c.
+
+ * infrun.c (follow_inferior_fork): Add ifdefs around
+ SOLIB_REMOVE_INFERIOR_HOOK.
+
+Wed Mar 31 11:39:49 1999 David Taylor <taylor@ryobi.cygnus.com>
+
+ * valops.c (search_struct_field): revert HP merge change
+ to this function -- it causes messages to be printed about
+ member class ambiguity when the compiler is happy.
+ (search_struct_field_aux): delete -- added as part of HP merge
+ change; with aforementioned change it is no longer called.
+
+1999-03-30 Stan Shebs <shebs@andros.cygnus.com>
+
+ Make more HPUX-specific code generic.
+ * infrun.c: Include top.h.
+ (MAY_SWITCH_FROM_INFERIOR_PID, MAY_FOLLOW_EXEC,
+ USE_THREAD_STEP_NEEDED): New native macros.
+ (may_switch_from_inferior_pid, may_follow_exec,
+ use_thread_step_needed): New globals.
+ (follow_inferior_fork): Remove HPUXHPPA ifdef.
+ (follow_exec): Ditto, also save run target and re-push instead of
+ always pushing child_ops, add ifdefs around SOLIB_RESTART and
+ SOLIB_CREATE_INFERIOR_HOOK.
+ (wait_for_inferior): Use new globals instead of ifdefing HPUXHPPA,
+ always use printf_filtered to report new threads.
+ (normal_stop): Ditto.
+ * target.h, target.c (find_run_target): New function.
+ * config/pa/nm-hppah.h: Define new macros.
+
+1999-03-29 Stan Shebs <shebs@andros.cygnus.com>
+
+ * top.h: Include setjmp.h here.
+ * main.c, top.c: Don't include it here.
+
+1999-03-29 Keith Seitz <keiths@cygnus.com>
+
+ * symtab.c (decode_line_1): Take out change which breaks symbols
+ which include class names and methods, e.g., "Foo::bar".
+
+1999-03-26 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.tgt (i[3456]86-*-sysv4.2MP, i[3456]86-*-sysv4.2uw2*):
+ Recognize both, as i[3456]86-*-sysv4.2*.
+ (i[3456]86-*-sysv5*): Recognize.
+
+ * infrun.c (wait_for_inferior): Remove most #if 0 segments.
+
+Fri Mar 26 17:27:27 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * blockframe.c (pc_in_call_dummy_on_stack): Fix. Had copied code
+ from at_entry_point.
+
+Thu Mar 25 19:30:02 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * gdbarch.c: Include all headers.
+ (struct gdbarch), gdbarch.h (CALL_DUMMY_LOCATION,
+ CALL_DUMMY_ADDRESS, CALL_DUMMY_START_OFFSET,
+ CALL_DUMMY_BREAKPOINT_OFFSET, CALL_DUMMY_LENGTH,
+ PC_IN_CALL_DUMMY): Add ``call_dummy_location'',
+ ``call_dummy_length'', ``pc_in_call_dummy'',
+ ``call_dummy_start_offset'', ``call_dummy_breakpoint_offset'' to
+ multi-arch framework.
+
+ * inferior.h, blockframe.c (pc_in_call_dummy_before_text_end,
+ pc_in_call_dummy_after_text_end, pc_in_call_dummy_on_stack,
+ pc_in_call_dummy_at_entry_point): Convert PC_IN_CALL_DUMMY macro's
+ into functions.
+
+ * mips-tdep.c (mips_gdbarch_init): Initialize above
+
+Tue Mar 23 17:22:57 1999 Philippe De Muyter <phdm@macqel.be>
+
+ * remote.c, parse.c: Include ctype.h.
+
+1999-03-24 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.host (mips-dec-mach3*): Use mipsm3 not mach3.
+
+ Attempt to sort out SCO-related configs.
+ * configure.host (i[3456]86-*-sysv4.2*): Use instead of
+ i[3456]86-*-sysv4.2MP and i[3456]86-*-sysv4.2uw2*.
+ (i[3456]86-*-sysv5*): Recognize.
+ * configure.tgt (i[3456]86-*-sco3.2v5*, i[3456]86-*-sco3.2v4*):
+ Recognize.
+
+Wed Mar 24 16:19:01 1999 Christopher Faylor <cgf@cygnus.com>
+
+ * MAINTAINERS: Add DJ Delorie (dj@cygnus.com) as the djgpp
+ maintainer.
+
+Wed Mar 24 21:19:57 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * target.h (enum target_signal): Do not hardwire values of MACH
+ signals.
+
+1999-03-14 Ken Raeburn <raeburn@raeburn.org>
+
+ * target.h (enum target_signal): Add TARGET_SIGNAL_INFO.
+ * target.c (signals): Add SIGINFO description.
+ (target_signal_from_host, target_signal_to_host): Translate
+ SIGINFO to/from TARGET_SIGNAL_INFO.
+
+Wed Mar 24 01:01:27 1999 Andrew Cagney <cagney@sludge.cygnus.com>
+
+ * rs6000-tdep.c (rs6000_software_single_step): Change SIGNAL to
+ unsigned int.
+
+ From Rodney Brown <rodneybrown@pmsc.com>
+ * target.h (enum thread_control_capabilities), breakpoint.h (enum
+ bptype), breakpoint.c (enum insertion_state_t): Strict ISO-C
+ doesn't allow trailing comma in enum definition.
+
+Mon Mar 22 15:56:04 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * blockframe.c (inside_entry_file, inside_entry_func): Convert #if
+ CALL_DUMMY_LOCATION to if.
+ * valops.c (call_function_by_hand): Ditto.
+ * infcmd.c (run_stack_dummy): Ditto.
+ * inferior.h (CALL_DUMMY_ADDRESS, CALL_DUMMY_START_OFFSET,
+ CALL_DUMMY_BREAKPOINT_OFFSET): Provide default.
+
+1999-03-23 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * hppa-tdep.c (pa_register_look_aside): Remove CPU_HPPA_RISC_20
+ check, test for presence of struct save_state_t and the ss_wide
+ member directly.
+ * configure.in: Remove CPU_HPPA_RISC_20 test. Add tests for
+ HAVE_STRUCT_SAVE_STATE_T and HAVE_STRUCT_MEMBER_SS_WIDE.
+ * acconfig.h: Add HAVE_STRUCT_SAVE_STATE_T HAVE_STRUCT_MEMBER_SS_WIDE.
+ * configure, config.in: Regenerated.
+
+Mon Mar 22 13:25:13 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * infttrace.c (proc_wait): rename to ptrace_wait.
+
+1999-03-18 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * dwarf2read.c: Correctly recognize location expressions that
+ designate LOC_REF_ARG arguments. Doc fixes.
+ (isderef): New global. (Yuck.)
+ (dwarf2_complex_location_expr): New complaint.
+ (read_func_scope): Reject frame_base attributes that use the
+ `deref' opcode as too complex.
+ (new_symbol): If both regoff and isderef are set, and the base
+ register is the frame pointer, then it's a LOC_REF_ARG argument.
+ (decode_locdesc): Recognize the `deref' opcode in location
+ expressions. Complain if it's not the last op in the expression.
+
+ * config/fr30/tm-fr30.h (COERCE_FLOAT_TO_DOUBLE): #define this to
+ be true, or else value_arg_coere won't respect the (accurate)
+ information we have about whether a function is prototyped.
+
+1999-03-17 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * config/fr30/tm-fr30.h (STACK_ALIGN): Define this here, so
+ calling functions by hand with odd-sized arguments doesn't munge
+ the stack.
+
+1999-03-17 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in (HAVE_MULTIPLE_PROC_FDS): Don't define for Solaris
+ hosts--gdb doesn't support this yet.
+ * configure: Regenerated.
+
+1999-03-16 Keith Seitz <keiths@cygnus.com>
+
+ * remote.c (remote_binary_checked): New file global.
+ (check_binary_download): New function to check if
+ stub supports binary downloading that works with
+ stubs that are not eight bit clean.
+ (remote_write_bytes): Check for binary download capability
+ and use it if available.
+ Remove references to global remote_binary_length. What a hack.
+ (putpkt_binary): New function.
+ (putpkt): Call putpkt_binary.
+ Use xor to escape trouble characters.
+ * m32r-stub.c (bin2mem): Follow escape char convention change.
+
+Tue Mar 16 01:11:33 1999 Andrew Cagney <cagney@rhino.cygnus.com>
+
+ * target.h (struct target_ops), target.c (debug_to_query),
+ remote.c (pack_hex_byte, remote_query): Promote char parameters to
+ int. Stops compile problems with pedantic ISO-C compilers.
+
+Tue Mar 16 15:29:04 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * go32-xdep.c: Remove, no longer used by anything.
+ * Makefile.in: Remove references.
+
+ * jv-lang.c, jv-lang.h (java_primitive_type): Declare argument
+ as int instead of char.
+
+Mon Mar 15 11:42:43 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (push_stack_item, pop_stack_item): New function.
+ (d10v_push_arguments): Use.
+
+ From Martin M. Hunt <hunt@cygnus.com>:
+ * d10v-tdep.c (d10v_push_arguments): When arguments
+ must be pushed onto the stack, they go on in
+ reverse order.
+
+1999-03-16 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * symtab.c (make_symbol_overload_list): Don't try to stuff minimal
+ or partial symbols into the overload list; we don't know their
+ types. (Thanks to Rajiv Mirani.)
+
+1999-03-15 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * acinclude.m4 (--with-itclconfig, --with-itkconfig, --with-tixconfig):
+ Fix whitespace so --help messages line up.
+ * configure.in (--with-cpu): Fix capitalization for --help messages.
+ * configure, aclocal.m4: Regenerated.
+
+Mon Mar 15 11:39:03 1999 Ian Carmichael <iancarm@cygnus.com>
+
+ Support building gdb w/o simulator:
+ * configure.in: Support --disable-sim. Check for sim directory.
+ * Makefile.in (IGNORE_SIM, IGNORE_SIM_OBS): New.
+ * acconfig.h (WITH_SIM): Define.
+ * configure, config.in: Regenerate.
+
+Mon Mar 15 08:01:33 1999 Elena Zannoni <ezannoni@cygnus.com>
+
+ Patch from Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * top.c (read_command_lines): Reset control_level to 0.
+ (define_command): Don't do it here.
+
+Sun Mar 14 16:12:15 1999 Andrew Cagney <cagney@rhino.cygnus.com>
+
+ * hppah-nat.c (store_inferior_registers): Delete extern
+ registers[] declaration.
+
+Sun Mar 14 19:17:30 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * infrun.c (write_inferior_status_register): New function. Provide
+ update access to an inf_status register buffer. Only used by HP.
+ * inferior.h (write_inferior_status_register): Add prototype.
+
+ * hppa-tdep.c (push_dummy_frame): Use
+ write_inferior_status_register when hacking around a sleeping
+ inferior. Accidently fix byte-order problem.
+
+Sun Mar 14 16:40:10 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/pa/tm-hppa.h (PUSH_DUMMY_FRAME): Fix parameter. Address
+ not needed.
+
+Fri Mar 12 13:11:48 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * remote.c (remote_write_bytes): fix 'X' packet protocol so that it
+ can't overwrite the end of its buffer with escaped characters.
+
+1999-03-12 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Alpha patches from Richard Henderson:
+
+ * alpha-tdep.c (alpha_skip_prologue): Recognize subq.
+
+ * config/alpha/tm-alpha.h (REGISTER_NAMES): No f31, but fpcr.
+ (FPCR_REGNUM): New.
+ (REGISTER_CONVERTIBLE): Don't convert fpcr.
+ (REGISTER_VIRTUAL_TYPE): Don't make fpcr a double.
+
+ * stabsread.c (define_symbol): Only consider live range extension
+ if we have an open parenthesis.
+
+1999-03-11 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * monitor.c (monitor_fetch_register): Print RDEBUG info correctly
+ when the register name is null.
+
+Thu Mar 11 19:33:07 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * infrun.c (wait_for_inferior): Change #if DECR_PC_AFTER_BREAK
+ uses to expressions, remove redundant extern decls.
+
+Thu Mar 11 18:05:11 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * infptrace.c (proc_wait): Rename to ptrace_wait.
+ * inftarg.c (child_wait): call ptrace_wait instead of proc_wait.
+ * inferior.h: Declare ptrace_wait instead of proc_wait.
+
+Thu Mar 11 11:46:25 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * breakpoint.c (create_solib_load_unload_event_breakpoint,
+ create_fork_vfork_event_catchpoint, tcatch_command,
+ create_exception_catchpoint, break_at_finish_at_depth_command_1,
+ catch_fork_command_1, ep_skip_leading_whitespace,
+ break_at_finish_command_1, catch_exec_command_1,
+ catch_exception_command_1, stop_command, stopin_command,
+ stopat_command, ep_parse_optional_filename,
+ ep_find_event_name_end, ep_parse_optional_if_clause,
+ catch_fork_command_1), stack.c (show_and_print_stack_frame_stub,
+ print_stack_frame_stub, print_only_stack_frame_stub,
+ backtrace_command_1, backtrace_full_command, func_command),
+ valprint.c (print_decimal), source.c (print_source_lines_base):
+ Add prototype.
+
+ * stack.c (print_stack_frame_stub, show_and_print_stack_frame_stub,
+ print_only_stack_frame_stub): Make param void*.
+
+Wed Mar 10 19:33:28 1999 Geoffrey Noer <noer@cygnus.com>
+
+ * win32-nat.c: If old Cygwin Win32 API headers aren't being used,
+ define some gdb-specific defines that shouldn't have been in the
+ global headers.
+
+Wed Mar 10 21:20:25 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * findvar.c (registers, register_valid): Replace array with pointer.
+ (build_findvar): New function. Allocate space for REGISTERS and
+ REGISTER_VALID.
+ (_initialize_findvar): Call build_findvar.
+ (_initialize_findvar): Register REGISTERS and REGISTER_VALID as
+ arch dependant.
+
+ * inferior.h (registers, register_valid): Replace array with
+ pointer.
+
+ * inferior.h (struct inferior_status): Move definition from here.
+
+ * infrun.c (struct inferior_status): To here.
+ (struct inferior_status): Change ``stop_registers'' and
+ ``registers'' to pointers.
+ (xmalloc_inferior_status, free_inferior_status): New functions.
+ (restore_inferior_status): Call free_inferior_status.
+ (save_inferior_status): Call xmalloc_inferior_status.
+ (discard_inferior_status): New function, discard inf_status
+ buffer. Call free_inferior_status.
+
+ * inferior.h (stop_registers): Replace array with pointer.
+ * infrun.c (stop_registers): Update.
+ (build_infrun): Initialize stop_registers.
+ (_initialize_infrun): Call build_infrun.
+ (_initialize_infrun): Register ``stop_registers'' as arch dependant.
+
+Wed Mar 10 14:50:42 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * alpha-tdep.c (alpha_linux_sigtramp_offset): Only compile when
+ LINUXALPHA target. Hack.
+
+ * infrun.c (set_follow_fork_mode_command): Make static. Add
+ prototype.
+ * tracepoint.c (add_register): Ditto.
+ * valprint.c (strcat_longest): Comment out. Does not appear to be
+ used.
+ * valops.c (find_method_list): Make static. Add prototype.
+ * thread.c (target_find_new_threads): Make static. Add prototype.
+ * stack.c (stack_publish_stopped_with_no_frame,
+ select_and_maybe_print_frame): Comment out. Does not appear to be
+ used.
+ (current_frame_command): Add prototype.
+ * breakpoint.c (break_at_finish_command,
+ break_at_finish_at_depth_command, tbreak_at_finish_command): Make
+ static. Add prototype.
+ * findvar.c (read_relative_register_raw_bytes_for_frame): Ditto.
+
+Wed Mar 10 23:38:54 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * corefile.c (registers): Delete redundant variable declaration.
+ * inferior.h (run_stack_dummy): Change array argument to pointer.
+ * infcmd.c (run_stack_dummy): Update.
+ * value.h (value_being_returned): Change RETBUF to a pointer.
+ * values.c (value_being_returned): Update.
+
+Wed Mar 10 11:08:16 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * source.c (list_command): GCC suggested explicit braces to avoid
+ ambiguous `else'.
+
+ * jv-typeprint.c: Include "c-lang.h".
+ * Makefile.in (jv-typeprint.o): Add dependency.
+ * jv-valprint.c: Include "gdbcore.h", "annotate.h".
+ * Makefile.in (jv-valprint.o): Add dependencies.
+ * objfiles.c: Include "breakpoint.h".
+ * Makefile.in (objfiles.o): Add dependency.
+ * main.c: Include <unistd.h>.
+ * parse.c: Include <ctype.h>.
+ * remote.c: Include <ctype.h>.
+ * ser-tcp.c: Include <unistd.h>.
+ * ax-general.c: Include "value.h".
+ * Makefile.in (ax-general.o): Add dependency.
+
+ * alpha-tdep.c (alpha_push_arguments): Make ``i'' an int instead
+ of a register.
+ * frame.h (show_and_print_stack_frame): Add function prototype.
+ * language.h (language_enum): Add function prototype.
+ * value.h (find_overload_match): Add function prototype.
+
+ * defs.h, utils.c (subset_compare): Rename subsetCompare. Add
+ prototype.
+ * stack.c (backtrace_command): Update.
+
+Wed Mar 10 13:58:36 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (AC_CHECK_HEADERS): Check for <sys/select.h>
+ * configure, config.in: Re-generate.
+ * inflow.c: Conditionally include <sys/select.h>.
+
+Wed Mar 10 13:44:38 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * frame.h (struct dummy_frame): Move from here.
+ * blockframe.c (struct dummy_frame): To here.
+
+ * blockframe.c (struct dummy_frame): Replace ``regs'' with pointer
+ ``registers''.
+ (generic_pop_dummy_frame): Free it.
+ (generic_push_dummy_frame): Allocate dummy frame register buffer.
+
+Wed Mar 10 11:08:16 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * thread.c (_initialize_thread): Delete redundant ``extern struct
+ cmd_list_element *cmdlist''.
+ * printcmd.c (print_command_1): Ditto for ``objectprint'';
+
+1999-03-09 Stan Shebs <shebs@andros.cygnus.com>
+
+ * MAINTAINERS: New file, list of maintainers and areas they
+ maintain.
+
+1999-03-09 Rodney Brown <RodneyBrown@pmsc.com>
+
+ Get working on UnixWare 2.1.1.
+ * acconfig.h: Update for defines for procfs.c.
+ * configure.in: Identify defines for procfs.c.
+ * configure.host: i386-*-sysv4.2uw2* => i386v42mp
+ * configure.tgt: i386-*-sysv4.2uw2* => i386v42mp
+ * configure, config.in: Regenerate.
+ * procfs.c: Rename HAVE_NO_PRRUN_T to HAVE_PRRUN_T (autoconf
+ standard), wrap UNIXWARE difference in THE_PR_LWP macro for
+ legibility.
+ * config/i386/tm-i386v42mp.h: Remove HAVE_PSTATUS_T,
+ HAVE_NO_PRRUN_T; now set by configure.
+
+Tue Mar 9 16:29:24 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * i386-tdep.c (gdb_print_insn_i386): Abort when disassembly_flavor
+ undefined..
+
+ * fr30-tdep.c (_initialize_fr30_tdep): Add prototype. Fix
+ coding style.
+
+ * target.c (debug_to_enable_exception_callback,
+ debug_to_get_current_exception_event): Return result of call to
+ debug_target().
+
+1999-03-09 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Another HURD fix from Mark Kettenis:
+ * gnu-nat.c: Include <string.h>. Remove declaration of strerror.
+ Include <bits/waitflags.h> instead of <waitflags.h> and define
+ _SYS_WAIT_H to prevent the warning that we should not include it.
+ (gnu_create_inferior): Change return type of attach_to_child to
+ void. Do not return INFERIOR_PID.
+ (gnu_pid_to_exec_file): Change return type to char *.
+ Return NULL.
+
+ Fix for the HURD from Mark Kettenis:
+ * configure.in: Add AC_PROG_AWK. Needed by the machine-dependent
+ makefile fragments for the Hurd.
+ * Makefile.in (AWK): Add. Set by configure.
+ * configure: Regenerated.
+
+1999-03-08 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * infttrace.c (hppa_get_process_events): Removed. Function only
+ usable on HPUX 10 and above. It is not called by any other part
+ of GDB.
+ * hppah-nat.c (hppa_get_process_events): Ditto.
+ (child_pid_to_exec_file): Only call ptrace with
+ PT_GET_PROCESS_PATHNAME if that symbol has been defined.
+ * config/pa/nm-hppah.h: Don't set up prototypes et al for
+ hppa_get_process_events.
+
+ * config/pa/hppahpux.mh (TERM_LIB): Do not initialize, let autoconf
+ determine best library automatically.
+ * config/pa/hpux1020.mh: Ditto.
+ * config/pa/hpux1100.mh: Ditto.
+ * configure.in (TERM_LIB): Also check for libHcurses.
+ * configure: Regenerated.
+
+Thu Mar 4 17:16:04 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * m32r-stub.c: add support for crc "Compare" command.
+
+1999-03-04 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * fr30-tdep.c (fr30_store_return_value): Allocate zeroes
+ dynamically, to save BSS space, and to remove assumptions about
+ the size of the largest value we'll return.
+
+ * config/fr30/tm-fr30.h (fr30_store_return_value): Use PARAMS in
+ prototype.
+
+Thu Mar 4 08:37:35 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sh3-rom.c (sh3_supply_register, sh3_supply_register),
+ mips-tdep.c (mips_push_arguments), m32r-rom.c
+ (m32r_upload_command), m32r-tdep.c (decode_prologue), monitor.c
+ (longlong_hexchars), tracepoint.c (validate_actionline,
+ read_actions), mdebugread.c
+ (parse_symbol), jv-typeprint.c
+ (java_type_print_base, java_type_print_base), mdebugread.c
+ (parse_symbol), top.c (source_command), utils.c
+ (floatformat_to_doublest): GCC suggest explicit braces to avoid
+ ambiguous `else'.
+
+ * tracepoint.c (map_args_over_tracepoints, trace_actions_command),
+ m32r-rom.c (m32r_supply_register), win32-nat.c
+ (handle_output_debug_string, child_continue), i960-tdep.c
+ (pop_frame), m32r-rom.c (m32r_upload_command): GCC suggested
+ parentheses around assignment used as truth value.
+
+ * remote-sds.c (sds_wait), monitor.c (monitor_fetch_register),
+ ser-e7kpc.c, (dosasync_write), arc-tdep.c (arc_get_frame_setup):
+ GCC suggested parentheses around operands.
+
+ * c-typeprint.c (c_type_print_base): GCC suggested enclosing
+ "while" expression in paren.
+
+Wed Mar 3 18:14:33 1999 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * sol-thread.c (save_inferior_pid): Cast the saved pid to void*.
+ (restore_inferior_pid): Takes void* as required by make_cleanup.
+ Casts pid back to an int.
+
+ * procfs.c (make_cleanup_close_proc_file,
+ close_proc_file_cleanup): Create a proc_file cleanup.
+ (info_proc): Use.
+
+ * defs.h (make_cleanup_freeargv): Helper function. Establish
+ cleanup using freeargv. Can not just typecast/pass freeargv as it
+ violates ISO-C.
+ * utils.c (do_freeargv): Helper.
+ (make_cleanup_freeargv): New function.
+
+ * symmisc.c (maintenance_print_symbols,
+ maintenance_print_psymbols, maintenance_print_msymbols), symfile.c
+ (symbol_file_command), stack.c (backtrace_command), remote-sim.c
+ (gdbsim_create_inferior, gdbsim_open), remote-mips.c
+ (common_open), procfs.c (info_proc), infrun.c (handle_command,
+ xdb_handle_command), exec.c (exec_file_attach): Call
+ make_cleanup_freeargv.
+
+1999-03-03 James Ingham <jingham@cygnus.com>
+
+ * i386-tdep.c (_initialize_i386_tdep): Set the inital value for
+ disassembly flavor at startup, rather than hardcoding it.
+
+1999-03-03 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Put return values in the right place.
+ * fr30-tdep.c (fr30_store_return_value): New function.
+ * config/fr30/tm-fr30.h (STORE_RETURN_VALUE): Call
+ fr30_store_return_value.
+
+Wed Mar 3 18:10:55 1999 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * gdbtypes.c (virtual_base_list_aux): Return void. Add prototype.
+
+ * breakpoint.c (map_catch_names): Comment out unused function.
+
+1999-03-02 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * hppa-tdep.c (pa_register_look_aside): Only refer to save_state_t
+ structure on PA 2.0 systems.
+
+1999-03-02 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Gary Thomas <gthomas@cygnus.co.uk>:
+ * arm-tdep.c (ARM_LE_BREAKPOINT, ARM_BE_BREAKPOINT,
+ THUMB_LE_BREAKPOINT, THUMB_BE_BREAKPOINT): Use illegal instruction
+ instead of SWI 24.
+ * config/arm/tm-arm.h (CALL_DUMMY): Ditto.
+ (IN_SIGTRAMP): Define.
+
+1999-03-02 Nick Clifton <nickc@cygnus.com>
+
+ * findvar.c (store_address): Delete incorrect big endian
+ code.
+
+Tue Mar 2 18:02:42 1999 Andrew Cagney <cagney@chook>
+
+ * configure.in (gdb_cv_os_cygwin): Compat. Continue to reconize
+ __CYGWIN32__.
+
+1999-03-01 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Move setting of gdb_cv_os_cygwin to before
+ setting of TERM_LIB. Check for __CYGWIN__ instead of __CYGWIN32__.
+ * configure: Regenerated.
+
+1999-03-01 DJ Delorie <dj@cygnus.com>
+
+ * configure.in: Change -cygwin32* to -cygwin*.
+ * configure: Ditto.
+
+1999-02-25 Stan Shebs <shebs@andros.cygnus.com>
+
+ * breakpoint.c (SOLIB_LOADED_LIBRARY_PATHNAME,
+ SOLIB_UNLOADED_LIBRARY_PATHNAME, SOLIB_CREATE_CATCH_LOAD_HOOK,
+ SOLIB_CREATE_CATCH_UNLOAD_HOOK): Supply default definitions.
+ * infrun.c (SOLIB_IN_DYNAMIC_LINKER): Ditto.
+
+1999-02-25 Keith Seitz <keiths@cygnus.com>
+
+ * corelow.c (core_close): Clear out solib state before
+ closing the bfd associated with the core file.
+ * solib.c (clear_solib): Mention that clear_solib requires
+ an open BFD in order for disable_breakpoints_in_shlibs to
+ determine whether breakpoints live in shared libraries.
+
+1999-02-24 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Set CPU_HPPA_RISC_20 if the host CPU is a PA 2.0
+ processor.
+ * acconfig.h: Add CPU_HPPA_RISC_20
+ * config.in, configure: Regenerated.
+ * hppa-tdep.c (pa_register_look_aside): Only refer to new
+ structure elements if we are on a PA2.0 system.
+ * defs.h: Include limits.h.
+
+Tue Feb 23 14:37:08 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * infrun.c (wait_for_inferior): Check scheduler_locking state
+ before resuming after a thread-specific breakpoint.
+
+1999-02-23 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * aclocal.m4, config.in, configure: Regenerated with latest
+ autotools.
+
+Mon Feb 22 12:32:19 1999 Per Bothner <bothner@cygnus.com>
+
+ * jv-valprint.c (java_val_print): Restore line that somehow got lost.
+
+ * jv-valprint.c (java_print_value_fields): Check for NULL type.
+
+1999-02-21 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * tm-h8500.h, i386lynx-nat.c: Removed. These files are long
+ dead; it seems that they only appeared due to some CVS weirdness.
+ If they appear again, we may need to distribute garlic and holy
+ water.
+
+1999-02-19 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in (TERM_LIB): Move checking for TERM_LIB, substituting.
+ * configure: Regenerated.
+
+1999-02-19 Robert Hoehne (robert.hoehne@gmx.net)
+
+ * configure.host (i[3456]86-*-msdosdjgpp*): New host.
+ * configure.tgt (i[3456]86-*-msdosdjgpp*): New target.
+ * go32-nat.c: New file, native DJGPP support.
+ * config/i386/go32.mh: Rewrite for DJGPP (go32) host.
+ * config/i386/go32.mt: New file, DJGPP (go32) target.
+ * config/i386/nm-go32.h: New file.
+ * config/i386/tm-go32.h: New file.
+ * config/i386/xm-go32.h: Rewritten for current DJGPP.
+
+1999-02-18 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * reply_mig_hack.awk, config/nm-gnu.h, config/alpha/nm-linux.h
+ config/alpha/xm-alphalinux.h, config/alpha/xm-alphaosf.h
+ config/i386/nm-i386sco5.h, config/i386/tm-fbsd.h, config/i386/tm-i386.h
+ config/powerpc/nm-aix.h, config/powerpc/tm-macos.h
+ config/powerpc/tm-ppc-aix.h, config/powerpc/xm-aix.h
+ config/rs6000/tm-rs6000-aix4.h, testsuite/gdb.chill/tests1.ch
+ testsuite/gdb.chill/tests2.ch, testsuite/gdb.chill/tests2.exp:
+ Update FSF address in copyright notices.
+
+1999-02-18 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Quote "$GCC" correctly.
+ * configure: Regenerated.
+
+1999-02-18 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * dbxread.c (elfstab_build_psymtabs): Don't assume that there's a
+ section named ".text", which has all the code in it. Instead, look
+ at all the sections in the file with the `code' flag set.
+ (find_text_range): New function, that does all the work.
+
+Thu Feb 18 17:50:45 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (FP_REGISTER_DOUBLE): Conditionally define.
+
+Fri Jan 29 16:51:11 1999 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * mips-tdep.c (return_value_location): New function. Merge/rewrite
+ of return-value code in mips_extract_return_value,
+ mips_store_return_value. Stop buffer overflow when 64 bit value
+ in 32 bit registers. Extract 64bit float from 32 bit register
+ pair of correct order.
+ (mips_extract_return_value, mips_store_return_value): Call
+ return_value_location. For store, ensure that remainder of
+ register is zero.
+
+Thu Jan 28 18:58:02 1999 Andrew Cagney <cagney@chook.cygnus.com>
+
+ From John Metzler <jmetzler@cygnus.com>:
+ * mips-tdep.c (struct gdbarch_tdep): Add mips_saved_regsize.
+ (MIPS_SAVED_REGSIZE): Define.
+ (mips_find_saved_regs, read_next_frame_reg, mips_pop_frame):
+ Read/write MIPS_SAVED_REGSIZE bytes of register on stack instead
+ of MIPS_REGSIZE.
+ (mips_gdbarch_init): Initialize mips_saved_regsize.
+
+ * mips-tdep.c (mips_frame_saved_pc, mips16_heuristic_proc_desc,
+ mips_push_arguments, mips_push_dummy_frame,
+ mips_use_struct_convention): Ditto. For MIPS_SAVED_REGSIZE <
+ REGISTER_RAW_SIZE, handle little/big endian issues from only using
+ half the register.
+ (STACK_ARGSIZE): Default to MIPS_SAVED_REGSIZE instead of
+ MIPS_REGSIZE.
+
+ * mips-tdep.c (struct gdbarch_tdep, FP_REGISTER_DOUBLE,
+ mips_gdbarch_init): Apply similar changes. Add
+ mips_fp_register_double to struct.
+
+Wed Feb 17 10:10:27 1999 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * gdbtypes.h (get_discrete_bounds): Remove duplicate decl.
+
+ * jv-typeprint.c (java_type_print_base): Change fputs => fputs_filtered.
+
+Mon Jan 25 18:30:57 1999 Per Bothner <bothner@cygnus.com>
+
+ * jv-lang.h (JAVA_OBJECT_SIZE): Change from hard-wired constant.
+ (java_primitive_type_from_name, get_java_object_header_size): Declare.
+ * jv-lang.c (java_class_from_object): Use get_java_object_type.
+ * jv-lang.c: Update Class field names: dtable->vtable,
+ msize->method_count, nfields->field_count, bfsize->size_in_bytes,
+ nmethods->method_count.
+ (type_from_class): Demangle array type names.
+ (java_link_class_type): Array type names are now demangled.
+ (get_java_object_type): If not defined yet, try looking it up.
+ (get_java_object_header_size): New function.
+ (java_primitive_type_from_name): New function.
+ (java_demangled_signature_length, java_demangled_signature_copy): New.
+ (java_demangle_type_signature): Re-implement using above functions.
+ (evaluate_subexp_java): For UNOP_IND, call evaluate_subexp_java
+ to evaluate subexp (not evaluate_subexp_standard).
+ For BINOP_SUBSCRIPT update for new array type naming scheme.
+ * jv-valprint.c (java_value_print): Use java_class_from_object.
+ Update array printing to new array type naming convention.
+ (java_val_print): Doing check_typedef when printing a pointer is
+ is a waste of effort. Also, handle TYPE_CODE_INT, to make sure
+ Java bytes as not printed as C chars.
+
+Fri Jan 8 16:58:22 1999 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * blockframe.c (find_pc_sect_partial_function): Search full symtabs as
+ a last ditch effort (after the partial & minimal symtabs).
+ * defs.h utils.c: Fixup prototypes for vprintf_filtered,
+ vfprintf_filtered, vfprintf_unfiltered and vprintf_unfiltered to return
+ ints to match their standard equivalents.
+ * defs.h symtab.c top.c: Create skip_prologue_hook to allow Java to
+ control the prologue skipping process.
+ * jv-typeprint.c (java_type_print_base): Remove extern for
+ jv_class_demangle, add new arg for objfile (NULL).
+ * symtab.h: Remove struct sourcevector and struct source. Definately
+ not needed.
+ * values.c (value_virtual_fn_field): Fixes code to handle new vtable
+ debug info format. Patch from marka.
+
+Wed Dec 16 23:11:25 1998 Stu Grossman <grossman@fencer.cygnus.com>
+
+ * jv-lang.c (java_class_from_object java_class_is_primitive
+ is_object_type): Change dtable to vtable.
+ * (java_primitive_type): Change arg to type char.
+ * (_initialize_java_language): Make java_char_type be unsigned.
+ * jv-lang.h: Fixup prototypes.
+
+Mon Dec 7 19:02:15 1998 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * jv-valprint.c (java_value_print): Fix printing of values where
+ run time type != compile time type.
+
+Fri Dec 4 15:23:38 1998 Stu Grossman <grossman@fencer.cygnus.com>
+
+ * Makefile.in: Whack out m2-typeprint.c.
+ * c-typeprint.c (c_type_print_varspec_suffix) typeprint.h: Make this
+ global. It's needed by Java.
+ * (c_type_print_base): Whack prefix off of qualified method names
+ (names with name spaces).
+ * gdbtypes.h (struct cplus_struct_type): Add bits for Java attributes.
+ Shrink voffset
+ to 16 bits to compensate for added bits above (hopefully this is still
+ enough).
+ * Add new accessor macros (TYPE_FND_FIELD_PUBLIC, ...) for all new
+ attribute bits.
+ * jv-typeprint.c (java_type_print_base): Fix printing of method
+ attributes. Handle JVM style manglings.
+ * (java_print_type): Enable code type print varspec_suffix to allow
+ array indices to print out.
+ * jv-valprint.c (java_val_print): Minor formatting.
+ * m2-lang.c (m2_language_d): Change m2_print_type to c_print_type.
+ * stabsread.c (read_member_functions): Save public and static attributes.
+
+Wed Feb 17 15:32:57 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * breakpoint.c (watch_command_1): Reformat comment.
+
+ * c-typeprint.c (c_type_print_base): Reformat comments.
+
+1999-02-17 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * Makefile.in (VERSION): Bump version to 4.17.2.
+
+Tue Feb 16 15:48:20 1999 Edith Epstein <eepstein@sophia.cygnus.com>
+
+ * config/pa/nm-hppah.h: Added prototype declarations for
+ hppa_enable_page_protection_events and
+ hppa_disable_page_protection_events.
+
+ * inftarg.c (child_wait): Fixed code that checks whether
+ or not the target program has done a fork/vfork.
+ related_pid does not have a value unless the target
+ program has forked/vforked.
+
+ * infttrace.c (hppa_insert_hw_watchpoint): Make sure that
+ function always returns a value.
+ (hppa_remove_hw_watchpoint): Make sure that function always
+ returns a value.
+
+Tue Feb 16 06:31:58 1999 Keith Seitz <keiths@cygnus.com>
+
+ * config/powerpc/tm-ppc-eabi.h: Do not define PC_IN_CALL_DUMMY,
+ let the generic call dummy infrastructure do it.
+
+Sun Feb 14 18:21:08 1999 Mark Alexander <marka@cygnus.com>
+
+ * config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
+ coffread.c will correctly handle char or short function parameters.
+
+1999-02-11 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure, aclocal.m4: Regenerate with correct version of aclocal.
+
+1999-02-10 Syd Polk <spolk@cygnus.com>
+
+ * acinclude.m4: Fix for new location of itclConfig.sh and itkConfig.sh.
+ * aclocal.m4: Regnerate.
+ * configure: Regenerate.
+
+1999-02-10 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * demangle.c: Fix comments to mention "set demangle-style"
+ instead of "set demangle".
+ Run through indent to fix minor indenting problems.
+
+Wed Feb 10 17:53:09 1999 Bob Manson <manson@charmed.cygnus.com>
+
+ * i386-tdep.c (gdb_print_insn_i386): Add missing returns.
+
+Wed Feb 10 13:17:21 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ Declare Gould configuration obsolete:
+ * configure.host, configure.tgt: Comment out Gould configs.
+ * Makefile.in: Comment out Gould-related actions.
+ * gould-xdep.c, gould-tdep.c, config/gould/*: Comment out.
+ * NEWS: Mention obsolete status.
+
+1999-02-09 DJ Delorie <dj@cygnus.com>
+
+ * sparcl-tdep.c: UDP download works in cygwin
+
+1999-02-08 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * gnu-regex.c: Check ENABLE_NLS instead of HAVE_LIBINTL_H.
+ * configure.in: Don't check for libintl.h.
+ * configure, config.in: Regenerated.
+
+Mon Feb 8 18:10:50 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * NEWS: Mention new X packet and PowerPC variant support.
+
+1999-02-08 Nick Clifton <nickc@cygnus.com>
+
+ * configure.host: Add support for StrongARM host.
+ * configure.tgt: Add support for StrongARM target.
+
+Mon Feb 8 12:05:05 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * dsrec.c (make_srec): Cast targ_addr to int in call to sprintf
+ otherwise on big endian machine with a bfd_vma of 64 bits,
+ *everything* gets loaded at location 0.
+
+Mon Feb 7 10:05:43 1999 Frank Ch. Eigler <fche@cygnus.com>
+
+ * infrun.c (wait_for_inferior): Allow SIGTRAP to be "pass"ed
+ to target program.
+
+Fri Feb 5 16:46:14 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * NEWS: Add mentions of various new things.
+
+Thu Feb 4 00:19:14 1999 Christopher Faylor <cgf@cygnus.com>
+
+ * configure.in: Move termcap determination later in the
+ file to catch setting of cygwin flag.
+ * configure: Regenerate.
+
+Wed Feb 3 14:16:38 1999 Christopher Faylor <cgf@cygnus.com>
+
+ * config/i386/cygwin.mh: Move TERMCAP test code to configure.in.
+ * configure.in: Treat libtermcap.a detection as a special case
+ when hosting on cygwin.
+ * configure: Regenerate.
+
+1999-02-03 Keith Seitz <keiths@cygnus.com>
+
+ * remote.c (remote_binary_download, remote_binary_length): New
+ static globals for dealing with binary transmissions.
+ (remote_write_bytes): Add support for binary downloads
+ by shadowing the "M" packet with a new "X" packet. This
+ defaults to ON; if the stub does not understand this, it
+ will fall back to using "M".
+ (putpkt): Add support for binary downloading.
+ * monitor.c (monitor_expect): The mon2000 monitor
+ on the MSA2000 will also emit random DC1/DC3 chars.
+ * m32r-stub.c: Change all char's to unsigned char's
+ to support binary downloading.
+ (handle_exception): Add support for binary downloading
+ via a new "X" packet.
+ (getpacket): Do NOT strip eighth bit of incoming chars.
+ Watch out for escaped characters in the incoming stream.
+ (putpacket): Do NOT strip eighth bit of incoming chars.
+ (bin2mem): New function to write binary data directly to
+ memory.
+ * m32r-rom.c: Add new "mon2000" target.
+
+Tue Feb 2 18:40:29 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * hp-psymtab-read.c (hpread_build_psymtabs): Coerce first arg
+ passed to make_cleanup to the correct type.
+ (hpread_quick_traverse): Change fifth arg to call to
+ hpread_end_psymtab to be 0.
+ Compare CURR_MODULE_END to 0 rather than NULL.
+ Get rid of ifdef'ed out code.
+ (scan_procs): Get rid of ifdef'ed out code.
+
+ * somread.c (som_symfile_read): Coerce first argument passed to
+ make_cleanup to the correct type.
+
+Tue Feb 2 17:36:29 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * hp-psymtab-read.c (do_pxdb): New function. Check whether the
+ file needs to be processed by pxdb (an HP debug info massaging
+ tool), if so call it.
+ (hpread_build_psymtabs): Initialize scan_start to 0 and
+ simplify flow of control.
+
+ * somread.c (som_symfile_read): Add call to do_pxdb (),
+ in hp-psymtab-read.c.
+
+ * symfile.c (symbol_file_add): Remove ifdef'ed out HPUX specific
+ code.
+ (symfile_bfd_open): Remove HPUXHPPA ifdef'ed code. Code is now
+ in hp-psymtab-read.c.
+
+1999-02-02 Martin Hunt <hunt@cygnus.com>
+
+ * printcmd.c (print_scalar_formatted): Use strcat to concat all
+ the output together before calling fprintf_filtered().
+
+1999-02-01 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Require autoconf 2.13.
+ (AM_EXEEXT): Replace with new AC_EXEEXT.
+ * acinclude.m4: Move itcl header macros from aclocal.m4 to here.
+ * aclocal.m4: Regenerated.
+ * configure: Regenerated.
+
+1999-02-01 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Allow PPC users to select which PPC/RS6000 variant they're
+ debugging at run-time. At the moment, the only thing this affects
+ is the set of registers visible.
+ * config/rs6000/tm-rs6000.h (REGISTER_NAME): Define this as a call
+ to the function rs6000_register_name.
+ (rs6000_register_name): Include extern decl.
+ (NUM_REGS): Bump to 183. What's the right way to do this?
+ (FIRST_UISA_SP_REGNUM, LAST_UISA_SP_REGNUM): Renamed from
+ FIRST_SP_REGNUM, LAST_SP_REGNUM.
+ (REGISTER_BYTES): Recompute this.
+ * rs6000-tdep.c: Renamed all uses of FIRST_SP_REGNUM and
+ LAST_SP_REGNUM to FIRST_UISA_SP_REGNUM and LAST_UISA_SP_REGNUM, with
+ some concomitant formatting changes.
+ #include "gdbcmd.h", so we can define commands here.
+ (struct variant): New structure.
+ (COMMON_UISA_REG_NAMES, PPC_UISA_SPR_NAMES, PPC_SEGMENT_REG_NAMES,
+ PPC_32_OEA_SPR_NAMES, num_registers): New macros.
+ (register_names_rs6000, register_names_uisa, register_names_403,
+ register_names_403GC, register_names_505, register_names_860,
+ register_names_601, register_names_602, register_names_603,
+ register_names_604, register_names_750, variants): New variables.
+ (rs6000_register_name, install_variant, find_variant_by_name,
+ install_variant_by_name, list_variants, show_current_variant,
+ set_processor, show_processor): New functions.
+ (_initialize_rs6000_tdep): Define new commands `set processor' and
+ `show processor', and call install_variant_by_name to set the
+ default variant.
+ * rs6000-nat.c: Renamed all uses of FIRST_SP_REGNUM and
+ LAST_SP_REGNUM to FIRST_UISA_SP_REGNUM and LAST_UISA_SP_REGNUM, with
+ some concomitant formatting changes.
+ * configure.in: Accept the `--with-cpu' flag, to specify a default
+ processor variant.
+ * acconfig.h: Provide a blurb for TARGET_CPU_DEFAULT, which is set
+ by configure's `--with-cpu' flag.
+ * config.in, configure: Regenerated.
+
+Sun Jan 31 15:24:24 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * buildsym.h, buildsym.c: Convert to ANSI-only.
+
+ * buildsym.h, buildsym.c: Reformat to standard.
+
+ * buildsym.c (merge_symbol_lists): Remove unused variable.
+ (_initialize_buildsym): Remove, does nothing.
+
+1999-01-31 J.T. Conklin <jtc@redbacknetworks.com>
+
+ * i386-stub.c, m32r-stub.c, m68k-stub.c, sh-stub.c, sparc-stub.c,
+ sparcl-stub, sparclet-stub.c: Change declaration of putDebugChar
+ to include explicit void return type as per documentation. Fix up
+ occasions where stubs erroneously checked return type.
+
+Sun Jan 31 13:18:33 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ From J.T. Conklin <jtc@redbacknetworks.com>:
+ * remote.c (remote_query): Fix tipo.
+
+Fri Jan 29 15:25:09 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.tgt (v850): Add wildcard to match.
+
+Fri Jan 29 16:44:01 1999 Edith Epstein <eepstein@sophia.cygnus.com>
+
+ * inferior.h: Ran indent.
+
+ * fork-child.c: Ran indent.
+
+ * infrun.c : Ran indent.
+
+Fri Jan 29 12:57:34 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * infrun.c (_initialize_infrun): Do not stop or print anything
+ when a SIGWINCH is received.
+
+ * Makefile.in (m2-exp.tab.c): Use YACC not BISON.
+ (f-exp.tab.c): Ditto.
+ (jv-exp.tab.c): Ditto.
+ (c-exp.tab.c): Ditto.
+ (YACC): Define as @YACC@.
+
+1999-01-29 Martin Hunt <hunt@cygnus.com>
+
+ Changes from Keith Seitz <keiths@cygnus.com>
+ * valops.c (value_assign): Add calls to register_changed_hook and
+ memory_changed_hook to inform UIs that the user has changed
+ the target's registers/memory.
+ * findvar.c (write_register_gen): Remove call to pc_changed_hook.
+ * defs.h: Remove declaration for pc_changed_hook and
+ add declarations for register_changed_hook and
+ memory_changed_hook.
+ * top.c: Ditto.
+
+1999-01-29 Mark Alexander <marka@cygnus.com>
+
+ * procfs.c (wait_fd): Handle deleted threads correctly.
+
+1999-01-28 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * utils.c (init_page_info): Force window size if running under emacs.
+
+1999-01-27 James Ingham <jingham@cygnus.com>
+
+ * typeprint.c (whatis_exp): Remove static declaration.
+
+Wed Jan 27 16:50:25 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * hp-psymtab-read.c: Reformat using indent.
+
+Wed Jan 27 13:20:25 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * hp-psymtab-read.c: Reformat comments, update copyright.
+
+Wed Jan 27 15:09:22 1999 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * mips-tdep.c (mips_gdbarch_init): Trace e_flags from BFD
+ elf_info.
+
+Tue Jan 26 16:02:47 1999 Mark Alexander <marka@cygnus.com>
+
+ * v850-tdep.c (v850_generic_reg_names, v850e_reg_names,
+ v850_register_names, v850_processor_type_table): Declare tables
+ and structures for handling differences in register names for
+ v850 and v850e.
+ (struct reg_list): Define new structure for creating tables
+ of register bit masks in v850e instrutions.
+ (handle_prepare, handle_pushm): New helpers for v850_scan_prologue.
+ (v850_scan_prologue): Recognize v850e instructions: callt, prepare,
+ and pushm.
+ (v850_target_architecture_hook): New function to set register
+ names based on current machine.
+ (_initialize_v850_tdep): Set up target_architecture_hook.
+ * config/v850/tm-v850.h (v850_register_names): Declare.
+ (REGISTER_NAME): Define to refer to v850_register_names.
+ (SR0_REGNUM, CTBP_REGNUM): Define.
+ (PS_REGNUM): Redefine in terms of SR0_REGNUM.
+
+Tue Jan 26 18:27:26 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * Makefile.in (c-exp.tab.c): Use BISON instead of YACC, to pick
+ the correct value from configure output.
+ (jv-exp.tab.c): Ditto.
+ (f-exp.tab.c): Ditto.
+ (m2-exp.tab.c): Ditto.
+
+1999-01-26 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * breakpoint.h (ep_is_exception_catchpoint): Add prototype.
+ * frame.h (select_and_print_frame): Add prototype.
+ * stack.c (func_command): Call select_and_print_frame with correct
+ number of arguments. Reformat whitespace.
+
+Tue Jan 26 16:53:54 1999 Fernando Nasser <fnasser@cygnus.com>
+
+ * remote.c (remote_query): fix maximum packet size to account for
+ remote_debug use.
+ (putpkt): add comment to alert about extra byte need.
+
+Mon Jan 25 19:55:30 1999 Mark Alexander <marka@cygnus.com>
+
+ * sh-tdep.c (sh_target_architecture_hook): Return immediately
+ when a matching machine is found.
+
+Fri Jan 22 09:10:35 1999 Mark Alexander <marka@cygnus.com>
+
+ * remote-mips.c (mips_initialize): Fix parameters to clear_breakpoint.
+ (common_breakpoint): Restore support for instruction breakpoints
+ on non-LSI targets.
+
+Thu Jan 21 17:16:19 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * stack.c: Close open comment.
+ * symtab.c (find_pc_sect_line): Ditto.
+
+Thu Jan 21 17:51:51 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * procfs.c (init_procfs_ops): New function, fills in procfs_ops,
+ init only nonzero fields, leave to_require_attach and
+ to_require_detach empty, not needed for /proc systems yet.
+ (_initialize_procfs): Call init_procfs_ops.
+
+ From J.T. Conklin <jtc@redbacknetworks.com>:
+ * top.c (init_main): Fix tipo in description of the remotetimeout
+ variable.
+ * breakpoint.c (bpstat_stop_status): Handle systems where
+ DECR_PC_AFTER_BREAK != DECR_PC_AFTER_HW_BREAK.
+
+Thu Jan 21 17:25:46 1999 Mark Alexander <marka@cygnus.com>
+
+ * mon960-rom.c (_initialize_mon960): Call init_mon960_cmds
+ to fill in mon960_cmds structure properly.
+
+Wed Jan 20 17:53:22 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-sds.c (sds_ops): Define only once.
+ (init_sds_ops, sds_command, _initialize_remote_sds): Declare.
+ (init_sds_ops): Init only non-zero fields.
+
+Wed Jan 20 15:45:15 1999 Mark Alexander <marka@cygnus.com>
+
+ * h8300-tdep.c (original_register_names, h8300h_register_names,
+ h8300_register_names): Define new variables.
+ (set_register_names): New function to set register names based on
+ current CPU type.
+ (h8300_command, h8300h_command, h8300s_command): Call
+ set_register_names.
+ * config/h8300/tm-h8300.h (h8300_register_names): Declare.
+ (REGISTER_NAME): Define to refer to h8300_register_names.
+
+1999-01-19 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * sol-thread.c abug-rom.c cpu32bug-rom.c dbug-rom.c m32r-rom.c
+ mac-nat.c mon960-rom.c op50-rom.c ppc-bdm.c remote-adapt.c
+ remote-array.c remote-bug.c remote-e7000.c remote-eb.c remote-es.c
+ remote-est.c remote-hms.c remote-mm.c remote-nindy.c remote-nrom.c
+ remote-os9k.c remote-rdp.c remote-sds.c remote-sim.c remote-st.c
+ remote-udi.c rom68k-rom.c sh3-rom.c sparcl-tdep.c sparclet-rom.c
+ v850ice.c win32-nat.c: cosmetic changes to conform to coding
+ standards.
+
+1999-01-19 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Use aclocal to generate GDB's aclocal.m4 script.
+ * acinclude.m4: New file, containing the hand-written local macro
+ definitions that used to be in aclocal.m4. Don't sinclude
+ ../bfd/aclocal.m4 any more; running aclocal in this directory will
+ get us the definitions we need. HOWEVER: Do sinclude
+ ../bfd/acinclude.m4, because we need the definition of
+ BFD_NEED_DECLARATION.
+ * aclocal.m4: Regenerated by aclocal.
+ * configure: Regenerated by autoconf.
+
+Tue Jan 19 10:27:23 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * breakpoint.c (disable_breakpoints_in_shlibs): new parameter,
+ silent, controls whether to print message about removal of shared
+ library breakpoints.
+ * breakpoint.h (disable_breakpoints_in_shlibs): decl updated.
+ * irix5-nat.c (clear_solib): call disable_breakpoints_in_shlibs.
+ * osfsolib.c (clear_solib): ditto.
+ * solib.c (clear_solib): ditto.
+ * somsolib.c (som_solib_restart): update call to
+ disable_breakpoints_in_shlibs.
+
+ * target.h (child_post_attach): only declare if CHILD_POST_ATTACH
+ is define.
+
+Tue Jan 19 18:07:11 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * corelow.c (solib_add_stub): Ditto.
+ (core_file_to_sym_file): Cast make_cleanup parameter.
+
+ * solib.c (symbol_add_stub, solib_map_sections): Change argument
+ to PTR insted of a char*. Matches catch_errors interface.
+
+Mon Jan 18 14:01:24 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-array.c (array_open): Don't use fprintf_filtered to send
+ data to the log file.
+
+ * remote-array.c (handle_load_dll): Change argument type to PTR so
+ that it is compatible with catch_errors.
+ * ocd.c (ocd_start_remote): Ditto.
+ * remote-sds.c (sds_start_remote): Ditto.
+
+ * win32-nat.c (win32_child_thread_alive): Namespace proof
+ child_thread_alive.
+ (init_child_ops): Update.
+
+Mon Jan 18 12:03:47 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-rdi.c (arm_rdi_open): Set gdb_hostif.hostosarg and
+ gdb_hostif.dbgarg to NULL instead of stdout.
+ (voiddummy, myprint, mywritec): Use gdb_stdout instead of stdout.
+
+Mon Jan 18 16:40:50 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * ser-ocd.c (ocd_open): Handle Unix case gracefully.
+
+ * target.c (dummy_target): Don't initialize statically.
+ (init_dummy_target): New function, fills in dummy_target.
+ (initialize_targets): Use it.
+ * hpux-thread.c (hpux_thread_ops): Don't initialize statically.
+ (init_hpux_thread_ops): New function, fills in hpux_thread_ops.
+ (_initialize_hpux_thread): Use it.
+ * m3-nat.c (m3_ops): Don't initialize statically.
+ (init_m3_ops): New function, fills in m3_ops.
+ (_initialize_m3): Use it.
+
+1999-01-18 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * sol-thread.c: delete compile time initialization of target_ops
+ (_initialize_sol_thread): initialize target_ops at run time.
+ * hpux-thread.c: added target_ops entry.
+ * m3-nat.c: ditto.
+
+Mon Jan 18 15:19:13 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * procfs.c (procfs_ops): delete compile time initialization.
+ (_initialize_procfs): initialize procfs_ops at run time.
+
+Mon Jan 18 12:51:44 1999 Christopher Faylor <cgf@cygnus.com>
+
+ * configure.in: Ensure that -luser32 is always linked in
+ for cygwin build.
+ * configure: Regenerated.
+
+Mon Jan 18 08:38:05 1999 Mark Alexander <marka@cygnus.com>
+
+ * values.c (value_virtual_fn_field): Clear the pointed-to
+ offset when casting to the base class.
+
+Mon Jan 18 10:30:51 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * remote-udi.c (init_udi_ops): change non-existant udi_run_ops to
+ udi_ops; delete NULL initializers.
+
+Mon Jan 18 12:03:47 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * serial.c (serial_close): gdb_fclose tages gdb_file** arg, not
+ gdb_file*.
+
+ * f-valprint.c, target.c, gdbarch.c: Pass gdb_stderr not stderr.
+
+Mon Jan 18 10:46:12 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * stack.c (print_frame_info_base): Don't cast call to
+ catch_errors.
+ (print_args_stub): Change char* arg to PTR.
+ * symmisc.c (print_symbol): Ditto.
+ * top.c (quit_cover): Ditto.
+ * remote.c (remote_open_1, remote_start_remote): Ditto.
+ * infrun.c (normal_stop, hook_stop_stub, restore_selected_frame):
+ Ditto.
+
+ * stack.c (backtrace_command): Cast first arg of make_cleanup to
+ make_cleanup_func.
+ * remote.c (remote_kill): Cast putpkt arg to catch_errors_ftype.
+
+Mon Jan 18 08:47:02 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (catch_errors_ftype): Define.
+ (catch_errors): Replace char* arg with PTR arg.
+ * top.c (catch_errors): Update
+
+ * breakpoint.c (bpstat_stop_status, bpstat_stop_status,
+ delete_breakpoint, breakpoint_re_set): Delete all casts in call to
+ catch_errors.
+ (breakpoint_cond_eval, watchpoint_check,
+ cover_target_enable_exception_callback, breakpoint_re_set_one):
+ Arg is PTR not char*.
+
+ * breakpoint.c (cover_target_enable_exception_callback): Change
+ type to int. Check for cast values of 0 and -1. Return a result!
+ (insert_breakpoints): Move declaration of SAL and ARGS to where
+ they are used.
+
+1999-01-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * remote.c (remote_query): new function - creates proper interface
+ to the remote protocol "q" command.
+
+Fri Jan 15 17:11:48 EST 1999 Zdenek Radouch (radouch@cygnus.com)
+
+ * config/fr30/tm-fr30.h: Changed ABI to match GCC change
+ (always use pointer for structs passed by value).
+
+1999-01-15 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * target.h: added entry for target queries (to_query)
+ target.c: ditto.
+
+Thu Jan 14 18:29:17 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * mips-tdep.c (mips_gdbarch_init): fix stream arg in
+ fprintf_unfiltered calls.
+ * remote-mm.c (mm_wait): fix stream arg to gdb_flush.
+ * remote-udi.c (udi_wait): fix stream arg to fwrite.
+ * symmisc.c (maintenance_check_symtabs): fix stream argument to
+ print_address_numeric.
+
+Wed Jan 13 19:33:16 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * breakpoint.c (insert_breakpoints): insert cast to eliminate
+ warning.
+
+Wed Jan 13 14:59:02 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * infrun.c (set/show scheduler-locking) New command. Set a
+ mode bit that will control how GDB attempts to control thread
+ scheduling for step, continue, etc. (resume): make use of
+ the schedule-locking mode.
+ * target.h (struct target_ops): new field to_has_thread_control.
+ * sol-thread.c: initialize target_ops to_has_thread_control.
+ * procfs.c: ditto.
+ * target.c: ditto.
+ * m3-nat.c: ditto.
+ * remote.c: ditto.
+ * hpux-thread.c: ditto.
+ * thread.c: cull duplicate prototypes. Move prototypes to top.
+ * serial.c: indentation cleanup.
+ * breakpoint.c: add casts to eliminate compiler warnings.
+
+Tue Jan 12 17:00:00 1999 Edith Epstein <eepstein@sophia.cygnus.com>
+
+ * inftarg.c (child_create_inferior): fixed HPUXHPPA specific
+ call to fork_inferior. The shell param is now NULL.
+
+1999-01-12 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * monitor.c (init_base_monitor_ops): Whitespace cleanup.
+ (_initialize_remote_monitors): Same.
+
+1999-01-12 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * monitor.c (init_monitor_ops): Initialize the monitor_ops
+ structure if it hasn't already been done.
+
+Tue Jan 12 14:50:10 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * inftarg.c (child_ops): Don't initialize statically.
+ (init_child_ops): New function, fills in child_ops.
+ (_initialize_inftarg): Use it.
+ (child_post_attach): Declare extern.
+ (child_wait): Fix ambiguous parens.
+ (child_attach_to_process): Remove unused local wstatus.
+ (child_insert_fork_catchpoint, child_remove_fork_catchpoint,
+ child_insert_vfork_catchpoint, child_remove_vfork_catchpoint,
+ child_has_forked, child_insert_exec_catchpoint,
+ child_remove_exec_catchpoint): Return a value.
+
+Mon Jan 11 16:43:44 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * remote.c (remote_wait): Add inferior_pid to thread list only
+ if it is not already there.
+
+1999-01-11 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * scm-tags.h: Update FSF's address on copyright notice.
+ * ser-e7kpc.c: Same.
+ * gnu-nat.h: Same.
+
+Mon Jan 11 13:45:57 1999 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * dwarf2read.c (dump_die): Change stderr to gdb_stderr.
+ * expprint.c (print_subexp): fprintf => fprintf_unfiltered.
+ * jv-typeprint.c (java_type_print_base): fputs => fputs_filtered.
+ * stack.c (struct function_bounds): Remove superfluous `typedef'.
+ * symfile.c (list_overlays_command): stdout => gdb_stdout.
+ * symmisc.c (maintenance_check_symtabs): stdout => gdb_stdout.
+ * utils.c (print_spaces): Make more efficient.
+
+Mon Jan 11 13:55:51 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * utils (print_spaces): fix arg to strcat; fix formatting.
+
+Fri Jan 8 11:57:24 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * exec.c (exec_ops): Don't initialize statically.
+ (init_exec_ops): New function, fills in exec_ops.
+ (_initialize_exec): Use it.
+
+Thu Jan 7 17:50:15 EST 1999 Zdenek Radouch (radouch@cygnus.com)
+
+ Beta FR30 port.
+ * fr30-tdep.c
+ * config/fr30/tm-fr30.h
+
+Wed Jan 6 12:28:35 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * configure.in: Add an --enable-tui argument. Construct
+ tui/Makefile from tui/Makefile.in. Use AM_PROG_CC_STDC. If we
+ have the GUI, then we need this to process libgui.h.
+ (ENABLE_CFLAGS): define and export BUILD_TUI.
+ (AC_CHECK_HEADERS): Add check for term.h.
+
+ * configure.host (hppa-*-hpux10.20, hppa-*-hpux11.0*): New configs.
+
+ * config.in, configure : regenerated.
+
+ * Makefile.in: Allow the TUI code to be conditionally enabled.
+ (TUI_LIBRARY): New variable, value are set by the configuration
+ script. Set to the empty string when the TUI isn't enabled.
+ (gdb$(GDBEXT)): Use those, instead of referring to all-tui and
+ tui/libtui.a directly.
+ (BUILD_TUI): build the tui -- only when configured with
+ --enable-tui.
+ (YLWRAP): use ylwrap to avoid problems on systems w/o bison.
+ (gdb$(EXEEXT)): make it dependent on BUILD_TUI.
+ (all-tui): remove dependency from phony target.
+ (c-exp.tab.c): use ylwrap instead of bison.
+ (jv-exp.tab.c): ditto.
+ (f-exp.tab.c): ditto.
+ (m2-exp.tab.c): ditto.
+ (ALLDEPFILES): add somread.c, hp-psymtab-read.c, hp-symtab-read.c.
+ (SFILES): remove the above files
+ (COMMON_OBS): remove somread.o
+ (SFILES): Add the tui files to this, so they get included in etags
+ tables.
+ (gdb$(EXEEXT)): Add all-tui to the list of dependencies, and add
+ tui/libtui.a to the link list.
+ (all-tui): New rule, which does a recursive make in the tui
+ subdir.
+ (tui/libtui.a): When recursing, pass down ${FLAGS_TO_PASS}. And
+ don't echo the make command. This is closer to what the other
+ recursions do.
+ (HFILES_NO_SRCDIR): add hpread.h
+ (COMMON_OBS): add hp-psymtab-read.o, hp-symtab-read.o
+ (SFILES): add hp-psymtab-read.c, hp-symtab-read.c add rules for
+ the new files. Remove hpread.c, hpread.o
+ (gdb$(EXEEXT)): Depend on the actual tui library, not on a
+ fictitious target. Since the fictitious target never existed,
+ make would always relink.
+ (tui/libtui.a): Always recurse to make sure the library is up to
+ date.
+
+Wed Jan 6 12:05:12 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.c: Pacify --enable-build-warnings, reformat code
+ to conform to standards, fix spelling errors.
+ (ishex, stubhex, record_currthread, etc): Declare.
+ (ishex, stubhex): Declare char arg as int.
+ (pack_string): Comment out, never used but possibly useful.
+ (threadref_to_int, remote_get_threadinfo, etc): Make static.
+
+Wed Jan 6 11:43:32 1999 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by Elena Zannoni
+ <ezannoni@cygnus.com> and Edith Epstein <eepstein@cygnus.com> as
+ part of a project to merge in changes made by HP.
+
+ * c-exp.y: use external flag hp_som_som_object_present to decide
+ whether code was compiled by HP's compilers. Add two new C++
+ tokens for true and false.
+ (yylex): check for template name is done differently for the
+ HP/aCC compiler case. Change some of the template processing code
+ for handling HP aCC templates. Handle true and false tokens.
+
+Tue Jan 5 11:13:36 1999 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * remote.c (record_curthread): Must not modify inferior_pid when
+ called from wait_for_inferior. Instead, if a new thread-id is
+ detected, call add_thread.
+ (MAGIC_NULL_PID): new macro, use instead of the magic number
+ "42000".
+ (remote_find_new_threads): if inferior_pid is unknown, get and use
+ the current thread id.
+ (remote_start_remote): on connecting, attempt to get the current
+ thread id for inferior_pid.
+ (remote_resume): If pid == -1, then resume any-thread (not the
+ current thread specifically). Also some cosmetic fixups.
+
+ * thread.c (info_threads_command): don't initialize current_pid
+ until after call to FIND_NEW_THREADS (which may change inferior_pid).
+ Also some cosmetic fixups.
+ * infrun.c: cosmetic fixups and casts to avoid warnings.
+ * infcmd.c: cosmetic fixups, mainly long lines.
+
+Tue Jan 5 11:55:57 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * target.c (noprocess): terminate sentence with a period.
+ * breakpoint.c (catch_command_1): ditto.
+
+ * c-valprint.c (c_value_print): remove hack^2 from HP; it causes
+ testsuite losses with no real gain.
+
+ * inferior.h (START_INFERIOR_TRAPS_EXPECTED): restore, but only
+ if tm-*.h hasn't overridden default value.
+
+1999-01-04 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Fix whitespace indentation for --help.
+ * configure: Regenerated.
+
+1999-01-04 Manuel Bouyer <bouyer@antioche.lip6.fr>
+
+ * main.c: Add --write command line option, document -w.
+ * gdb.1: Document --write.
+
+1999-01-04 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Require autoconf 2.12.1 or higher.
+ * doc/configure.in: Ditto.
+ * nlm/configure.in: Ditto.
+ * rdi-share/configure.in: Ditto.
+ * testsuite/configure.in: Ditto.
+ * doc/Makefile.in: Don't hardcode $(SHELL).
+ * nlm/Makefile.in: Ditto.
+ * rdi-share/Makefile.in: Ditto.
+ * testsuite/Makefile.in: Ditto.
+
+Mon Jan 4 12:53:03 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote-vx.c (init_vx_ops, init_vx_run_ops): Remove unneeded
+ inits of new fields, including ref to bogus field.
+ (vx_ops, vx_run_ops): Make static.
+
+Mon Jan 4 15:05:29 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * inferior.h (START_INFERIOR_TRAPS_EXPECTED): delete,
+ already defined in tm.h.
+
+ * inftarg.c: change <sys/unistd.h> to <unistd.h> and
+ conditionalize its inclusion.
+ * infttrace.c: ditto.
+
+For older changes see ChangeLog-1998
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/ChangeLog-2000 b/gdb/ChangeLog-2000
new file mode 100644
index 00000000000..25ced55f09c
--- /dev/null
+++ b/gdb/ChangeLog-2000
@@ -0,0 +1,8204 @@
+2000-12-20 Michael Snyder <msnyder@mvstp600e.cygnus.com>
+
+ * arch-utils.c (default_frame_address): New function. Default
+ implementation of frame_args_address and frame_locals_address.
+ * arch-utils.h (default_frame_address): Export.
+ * d10v-tdep.c (d10v_gdbarch_init): Use default_frame_address.
+ (d10v_frame_args_address, d10v_frame_locals_address): Delete.
+ * sh-tdep.c (sh_gdbarch_init): Use default_frame_address.
+ (sh_frame_args_address, sh_frame_locals_address): Delete.
+ * sparc-tdep.c (sparc_gdbarch_init): Use default_frame_address.
+ (sparc_frame_address): Delete.
+
+2000-12-27 Mark Kettenis <kettenis@gnu.org>
+
+ Fix debugging programs statically linked against the thread library.
+ * thread-db.c: Various comment fixes and additions.
+ Include "bfd.h", "symfile.h" and "objfiles.h".
+ (keep_thread_db): New variable.
+ (find_new_threads_callback): Remove prototype.
+ (thread_db_find_new_threads): New prototype.
+ (thread_db_push_target, thread_db_unpush_target): Remove
+ functions.
+ (deactivate_target): New function.
+ (thread_db_new_objfile): If OBJFILE == NULL, force deactivation of
+ target vector. Activate target vector directly instead of calling
+ thread_db_push_target. Set keep_thread_db if thread library is
+ detected in the main symbol file. Only enable thread event
+ reporting if there actually is a child process. Likewise for
+ detecting new threads, done by calling thread_db_find_new_threads
+ instead of iterating over the threads ourselves.
+ (thread_db_detach): Call deactivate_target instead of
+ thread_db_unpush_target.
+ (thread_db_wait): Bail out early if we're not debugging the
+ multi-threaded child process yet.
+ (thread_db_post_startup_inferior): New function.
+ (thread_db_mourn_inferior): Call deactivate_target instead of
+ thread_db_unpush_target.
+ (init_thread_db_ops): Add thread_db_post_startup_inferior to
+ thread_db_ops.
+
+2000-12-22 Mark Kettenis <kettenis@gnu.org>
+
+ * solib.c (solib_open): If path is relative, look for it
+ literally. This matches the behaviour of the GNU dynamic linker
+ more closely.
+
+2000-12-22 Fernando Nasser <fnasser@redhat.com>
+
+ * README: Suggest building in an empty directory.
+
+2000-12-21 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-tdep.c: Add missing ')' in comment.
+ (i386_extract_return_value): Return directly after issuing the
+ warning and filling *VALBUF with zeroes if we cannot get at the
+ floating-point registers.
+ (i386_store_return_value): New function.
+ * config/i386/tm-i386.h (STORE_RETURN_VALUE): Simply call
+ i386_store_return_value.
+ Add prototype for i386_store_return_value.
+
+ * i386-linux-nat.c (store_fpxregs): Add code to detect support for
+ the PTRACE_GETFPXREGS request, and return zero if it's not.
+
+2000-12-21 Fernando Nasser <fnasser@redhat.com>
+
+ * TODO: Add pre-uiout code removal to 5.2 cleanups.
+
+2000-12-20 Fernando Nasser <fnasser@redhat.com>
+
+ * configure.in: Rename CONFIG_LOBS to CONFIG_LIB_OBS.
+ * Makefile.in: Ditto.
+ * configure: Regenerate.
+
+2000-12-20 Fernando Nasser <fnasser@redhat.com>
+
+ * command.h: Register date when it was deprecated.
+ * call-cmds.h: Ditto.
+
+2000-12-20 Fernando Nasser <fnasser@redhat.com>
+
+ * Makefile.in (UIOUT_CFLAGS): New macro. CFLAGS needed for uiout code
+ to be compiled. Defines UI_OUT.
+ (SUBDIR_MI_CFLAGS): Defines MI_OUT, not UI_OUT.
+ (INTERNAL_WARN_CFLAGS): Also include UIOUT_CFLAGS.
+ * configure.in (UIOUT_CFLAGS): New configuration variable.
+ (--with-uiout): New configuration option. Causes uiout code to
+ be compiled, instead of the old *printf one.
+ * configure: Regenerate.
+ * top.c (print_gdb_version): Test for and print MI_OUT, not UI_OUT.
+
+2000-12-20 Fernando Nasser <fnasser@redhat.com>
+
+ * complaints.c (complain): Call warning_hook if defined, instead of
+ writting to gdb_stderr.
+ (clear_complaints): Do not write anything to gdb_stderr if warning_hook
+ is defined.
+
+2000-12-19 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * sh-tdep.c (sh_print_register): Don't leave regnum 0 out of the
+ non-pseudo-regs group.
+
+2000-12-19 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * sh-tdep.c (sh_gdbarch_init): Move setting of breakpoint_from_pc
+ to before switch statement.
+
+2000-12-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * sh-tdep.c (sh_gdbarch_init): Initialize do_registers_info.
+
+ * config/sh/tm-sh.h: Don't remove SR_REGNUM from enum.
+ (DO_REGISTERS_INFO): Remove macro. Use multiarch version instead.
+
+Fri Dec 15 23:12:15 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * i386gnu-nat.c: Include "gdb_assert.h" instead of <assert.h>.
+ (gnu_store_registers): Replace assert with gdb_assert.
+
+2000-12-15 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * sh-tdep.c (sh_generic_show_regs, sh3_show_regs, sh3e_show_regs,
+ sh3_dsp_show_regs, sh4_show_regs, sh_dsp_show_regs): SR_REGNUM is
+ now part of gdbarch_tdep structure.
+ (sh_gdbarch_init): Initialize SR_REGNUM.
+
+ * config/sh/tm-sh.h (struct gdbarch_tdep): Add field SR_REGNUM.
+
+ * sh-tdep.c (sh_do_pseudo_register): Indent properly. Call
+ do_dr_register_info() only for DR registers.
+ (sh_sh4_register_name): Add comments with numbers.
+ (_initialize_sh_tdep): Move assignment to disassemble printing
+ function from here...
+ (sh_gdbarch_init):...to here. Move some more general settings to
+ before the architecture is recognized.
+
+Fri Dec 15 23:27:56 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (remote_fetch_registers): Replace #ifdef
+ REGISTER_BYTES_OK with REGISTER_BYTES_OK_P.
+
+ * gdbarch.sh (REGISTER_BYTES_OK): Multi-arch.
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+Fri Dec 15 22:58:59 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * serial.c (serial_printf): Call xvasprintf instead of vasprintf.
+
+2000-12-14 Matthew Green <mrg@eterna.com.au>
+
+ * solib-svr4.c (solib_break_names): Add NetBSD's `_rtld_debug_state'.
+
+2000-12-14 Kevin Buettner <kevinb@redhat.com>
+
+ * defs.h, utils.c (xfree): New function.
+ * alpha-tdep.c, altos-xdep.c, arch-utils.c, arm-xdep.c,
+ ax-general.c, bcache.c, blockframe.c, breakpoint.c,
+ buildsym.c, c-typeprint.c, coffread.c, completer.c,
+ convex-tdep.c, convex-xdep.c, corefile.c, corelow.c,
+ cp-valprint.c, cxux-nat.c, d10v-tdep.c, d30v-tdep.c,
+ dbxread.c, dcache.c, defs.h, demangle.c, dstread.c,
+ dve3900-rom.c, dwarf2read.c, dwarfread.c, elfread.c,
+ environ.c, event-loop.c, event-top.c, exec.c, f-lang.c,
+ gdb-events.c, gdbarch.c, gdbtypes.c, gnu-nat.c, h8500-tdep.c,
+ hp-psymtab-read.c, hppah-nat.c, infcmd.c, inflow.c, infrun.c,
+ infttrace.c, irix5-nat.c, jv-typeprint.c, kod-cisco.c, kod.c,
+ language.c, lin-lwp.c, lin-thread.c, linespec.c,
+ linux-thread.c, main.c, maint.c, mdebugread.c, minsyms.c,
+ mips-tdep.c, monitor.c, nlmread.c, objfiles.c, osfsolib.c,
+ p-valprint.c, pa64solib.c, parse.c, printcmd.c,
+ proc-service.c, procfs.c, pyr-xdep.c, remote-adapt.c,
+ remote-bug.c, remote-eb.c, remote-es.c, remote-mips.c,
+ remote-mm.c, remote-nindy.c, remote-rdi.c, remote-rdp.c,
+ remote-udi.c, remote-vx.c, remote.c, rs6000-nat.c, ser-pipe.c,
+ serial.c, solib-svr4.c, solib.c, somread.c, somsolib.c,
+ source.c, sparcl-tdep.c, stabsread.c, stack.c, sun386-nat.c,
+ symfile.c, symmisc.c, symtab.c, target.c, thread-db.c,
+ thread.c, top.c, tracepoint.c, ui-file.c, ui-out.c,
+ umax-xdep.c, utils.c, valops.c, valprint.c, values.c,
+ varobj.c, win32-nat.c, wince.c, xcoffread.c, cli/cli-cmds.c,
+ cli/cli-decode.c, cli/cli-script.c, cli/cli-setshow.c:
+ Replace occurrences of free() with xfree().
+
+2000-12-14 J.T. Conklin <jtc@redback.com>
+
+ * configure.tgt (hppa*-*-bsd*, hppa*-*-osf*, m68*-*-sunos4*,
+ rs6000-*-lynxos*, sparc-*-sunos4*): Add gdbserver to configdirs.
+
+2000-12-13 Michael Chastain <chastain@redhat.com>
+
+ * MAINTAINERS: Add Michael Chastain to Write After Approval list.
+
+2000-12-11 Fernando Nasser <fnasser@redhat.com>
+
+ * Makefile.in (CONFIG_LOBS): New macro. Configured to the files
+ that must be added to the gdblib itself.
+ (DEPFILES): Use CONFIG_LOBS, not CONFIG_OBS.
+ (INIT_FILES): Include CONFIG_OBS.
+ (gdb$(EXEEXT)): Depend on CONFIG_OBS and link with it.
+ (kdb): Ditto.
+ * configure.in (CONFIG_LOBS): New variable. Object files that must
+ be added to gdblib for the specific configuration.
+ * configure: Regenerate.
+
+2000-12-11 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * sh-tdep.c (sh_extract_struct_value_address): Protoize.
+
+2000-12-11 Michael Snyder <msnyder@mvstp600e.cygnus.com>
+
+ * blockframe.c (get_prev_frame): Add missing paren omitted in
+ last check-in.
+
+2000-12-11 Fernando Nasser <fnasser@redhat.com>
+
+ * Makefile.in (SUBDIR_GDBTK_OBS, SUBDIR_GDBTK_SRCS,
+ SUBDIR_GDBTK_DEPS, SUBDIR_GDBTK_INITS, SUBDIR_GDBTK_LDFLAGS,
+ SUBDIR_GDBTK_CFLAGS): New macros. For gdbtk subdir.
+ * configure.in: Fix typo. It is CONFIG_OBS not CONFIG_OJS.
+ Use the SUBDIR_GDBTK_* macros instead of hard coded file names.
+ * configure: Regenerate.
+
+2000-12-11 Michael Snyder <msnyder@mvstp600e.cygnus.com>
+
+ * blockframe.c (get_prev_frame): Zero all fields of prev by
+ default using memset (instead of one at a time).
+
+2000-12-11 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * sh-tdep.c (sh_extract_struct_value_address): For consistancy,
+ change decl from "CORE_ADDR static" to "static CORE_ADDR".
+
+2000-12-11 Fernando Nasser <fnasser@redhat.com>
+
+ * configure.in: Fix typos. It is CONFIG_SRCS not CONFIG_SRS.
+ * configure: Regenerate.
+
+2000-12-11 Fernando Nasser <fnasser@redhat.com>
+
+ * configure.in: Fix a couple of typos in the handling of the
+ enable_gdbcli option. Make it check enableval for the result
+ of AC_ARG_ENABLE.
+ * configure: Regenerate.
+
+2000-12-08 Michael Snyder <msnyder@mvstp600e.cygnus.com>
+
+ * dwarf2read.c (DWARF2_REG_TO_REGNUM): New macro. Provide default
+ definition. Will be used to translate between the compiler's
+ register numbering and GDB's (for register variables etc).
+ (new_symbol): Use DWARF2_REG_TO_REGNUM to translate register ids.
+ * alpha-tdep.c: Fix typo in comment.
+ * dbxread.c: Fix typo in comment.
+ * fr30-tdep.c: Fix typo: newline missing after comment.
+ * mcore-tdep.c: Fix typo in comment.
+
+2000-12-07 J.T. Conklin <jtc@redback.com>
+
+ * gdbserver/low-hppabsd.c (buf2, environ, quit, quit_flag):
+ Removed unused variables and declarations.
+ * gdbserver/low-linux.c (buf2, environ, query, quit, quit_flag):
+ Likewise.
+ * gdbserver/low-nbsd.c (buf2, environ, quit, quit_flag):
+ Likewise.
+ * gdbserver/low-sparc.c (buf2, environ, query, quit, quit_flag):
+ Likewise.
+ * gdbserver/low-sun.c (buf2, environ, query, quit, quit_flag):
+ Likewise.
+
+ * gdbserver/low-hppabsd.c, gdbserver/low-linux.c,
+ gdbserver/low-nbsd.c, gdbserver/low-sparc.c, gdbserver/low-sun3.c
+ (create_inferior): Update comment.
+
+ * gdbserver/low-nbsd.c (initialize_arch, fetch_inferior_registers,
+ store_inferior_registers): Provide implementations for the m68k
+ and ns32k.
+ * config/m68k/nbsd.mt (GDBSERVER_DEPFILES): Add low-nbsd.o
+ * config/ns32k/nbsd.mt (GDBSERVER_DEPFILES): Likewise.
+ * configure.tgt (m68*-*-netbsd*, ns32k-*-netbsd*): Add gdbserver
+ to configdirs.
+
+2000-12-07 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * config/sh/tm-sh.h (struct gdbarch_tdep): Rename fields
+ {FP15,DR14,FV12}_REGNUM to {FP,DR,FV}_LAST_REGNUM.
+ * sh-tdep.c (sh_sh3e_register_virtual_type,
+ sh_sh4_register_virtual_type, sh_do_registers_info,
+ sh_gdbarch_init, sh_sh4_register_byte, sh_sh4_register_raw_size,
+ sh_sh4_register_convertible, sh_sh4_register_convert_to_virtual,
+ sh_sh4_register_convert_to_raw, sh_fetch_pseudo_register,
+ sh_store_pseudo_register, sh_do_pseudo_register): Ditto.
+
+ * sh-tdep.c (sh_gdbarch_init): Use a function pointer to set the
+ disassembly print function.
+ (_initialize_sh_tdep): Initialize tm_print_insn using the function
+ pointer.
+
+2000-12-07 Mark Kettenis <kettenis@gnu.org>
+
+ From Richard Henderson <rth@twiddle.net>:
+ * alpha-nat.c (supply_gregset, fill_gregset): Use gdb_gregset_t.
+ (supply_fpregset, fill_fpregset): Use gdb_fpregset_t.
+
+2000-12-06 Fernando Nasser <fnasser@redhat.com>
+
+ * cli/cli-decode.c (add_abbrev_cmd): Reinstate. Add comment saying
+ that is not currently used.
+
+2000-12-06 Fernando Nasser <fnasser@redhat.com>
+
+ * cli/cli-decode.c (lookup_cmd): Change disabled code into comment.
+
+2000-12-06 Fernando Nasser <fnasser@redhat.com>
+
+ * cli/cli-decode.c (lookup_cmd): Remove old stale copy of this routine
+ which was not being used for quite some time.
+
+2000-12-05 Mark Kettenis <kettenis@gnu.org>
+
+ * gdb-stabs.h (SECT_OFF_MAX): Increase to 64.
+ * symfile.h (MAX_SECTIONS): Increase to 64.
+
+2000-12-05 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * config/sh/tm-sh.h (struct gdbarch_tdep): Get rid of
+ DR{2,4,6,8,10,12}_REGNUM, FV{4,8}_REGNUM, they are not used
+ anywhere.
+ * sh-tdep.c (sh_gdbarch_init): Don't initialize
+ DR{2,4,6,8,10,12}_REGNUM, FV{4,8}_REGNUM.
+
+2000-12-04 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * utils.c (internal_verror): Fix typo in error msg.
+
+2000-12-03 Mark Kettenis <kettenis@gnu.org>
+
+ * Makefile.in (symfile.o): Add gdb-stabs.h to dependencies list.
+
+2000-12-04 Kevin Buettner <kevinb@redhat.com>
+
+ * elfread.c (record_minimal_symbol_and_info): Don't guess
+ at the section index; instead just always use the bfd index.
+ (elf_symtab_read): Handle weak symbols appearing in data
+ sections.
+
+Mon Dec 4 14:36:39 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh (STAB_REG_TO_REGNUM, ECOFF_REG_TO_REGNUM,
+ DWARF_REG_TO_REGNUM, SDB_REG_TO_REGNUM, DWARF2_REG_TO_REGNUM):
+ Add.
+ * gdbarch.h, gdbarch.c: Regenerate.
+ * arch-utils.c (no_op_reg_to_regnum): New function.
+ * arch-utils.h (no_op_reg_to_regnum): Declare.
+
+ * dwarfread.c (DWARF_REG_TO_REGNUM), coffread.c
+ (SDB_REG_TO_REGNUM), stabsread.h (STAB_REG_TO_REGNUM),
+ mdebugread.c (ECOFF_REG_TO_REGNUM): Delete macro.
+
+ * config/mips/tm-mips.h (ECOFF_REG_TO_REGNUM, STAB_REG_TO_REGNUM):
+ Delete. Moved to mips-tdep.c.
+ * mips-tdep.c (mips_ecoff_reg_to_regnum, mips_stab_reg_to_regnum):
+ New functions.
+ (mips_gdbarch_init): Add ``mips_ecoff_reg_to_regnum'' and
+ ``mips_stab_reg_to_regnum'' to multi-arch vector.
+
+2000-12-03 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * m68hc11-tdep.c (m68hc11_gdbarch_init): Remove elf_flags, cleanup.
+ (gdbarch_tdep): Likewise.
+
+2000-12-03 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * m68hc11-tdep.c (SOFT_D1_REGNUM): Soft registers start at 14.
+ (m68hc11_register_names): Add null for register 13.
+
+2000-12-03 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * m68hc11-tdep.c (m68hc11_frame_args_address): Fix args address
+ computation.
+ (m68hc11_frame_init_saved_regs): Frame pointer is saved only if
+ the symbol exist.
+ (m68hc11_analyze_instruction): New function.
+ (m6811_prologue, m6812_prologue): New prologue description tables.
+ (m68hc11_guess_from_prologue): Use the above.
+ (m68hc11_gdbarch_init): Setup gdbarch_tdep for the prologue
+ descriptions.
+
+Sun Dec 3 02:28:26 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ser-pipe.c (pipe_open): Only use vfork when available.
+ * fork-child.c (fork_inferior): Fix #ifdef HAVE_VFORK test.
+ (clone_and_follow_inferior): Ditto.
+
+ * configure.in (AC_CHECK_FUNCS): Check for vfork.
+ * configure, config.in: Regenerate.
+
+Sun Dec 3 01:54:49 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ser-unix.c (wait_for): Initialize the FD_SET before every select
+ call.
+ (ser_unix_wait_for): Ditto.
+
+Sun Dec 3 01:01:02 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (varobj.o): Delete special .c.o rule supressing
+ -Werror flag.
+
+Sun Dec 3 00:29:31 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * m32r-rom.c (m32r_load_section): Update to match
+ bfd_map_over_sections's ``func'' arg.
+
+Thu Nov 30 01:24:37 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (struct upk_mips16): Delete fields ``inst'' and
+ ``fmt''. Make ``offset'' a CORE_ADDR.
+ (print_unpack): Delete.
+ (extended_offset): Construct and return a CORE_ADDR.
+ (fetch_mips_16): Return an int. Don't assume short is 16 bits.
+ (unpack_mips16): Rewrite. Add ``extension'' parameter instead of
+ incorrectly guessing if the instruction had an extension.
+ (map16): Delete array.
+ (mips16_op): Delete macro.
+ (extended_mips16_next_pc): Rewrite of old mips16_next_pc function.
+ When an extended instruction do a recursive call.
+ (mips16_next_pc): Call extended_mips16_next_pc.
+ (mips_next_pc): Cleanup.
+
+Sat Dec 2 10:40:16 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ser-e7kpc.c (e7000pc_setstopbits): New function.
+ (e7000pc_ops): Add e7000pc_setstopbits.
+
+ * remote-e7000.c (e7000_detach, e7000_resume,
+ e7000_xfer_inferior_memory, e7000_files_info, e7000_files_info,
+ e7000_insert_breakpoint, e7000_remove_breakpoint, e7000_kill):
+ Update function signature to match target vector.
+
+ * h8300-tdep.c (h8300_command, h8300h_command, h8300s_command):
+ h8500-tdep.c (small_command, big_command, medium_command,
+ compact_command): Update function signature to match add_cmd.
+
+2000-12-01 Fernando Nasser <fnasser@redhat.com>
+
+ * p-exp.y: Define strncasecmp as strnicmp for MSVC.
+ (yylex): Use strncasecmp, not strnicmp.
+
+2000-12-01 Fernando Nasser <fnasser@redhat.com>
+
+ * cli/cli-decode.c: New file. Handle lists of commands, their decoding
+ and documentation.
+ (add_cmd, deprecate_cmd, add_abbrev_cmd, add_alias_cmd, add_prefix_cmd,
+ add_abbrev_prefix_cmd, not_just_help_class_command, empty_sfunc,
+ add_set_cmd, add_set_enum_cmd, add_set_auto_boolean_cmd,
+ add_show_from_set, delete_cmd, apropos_cmd, help_cmd, help_list,
+ help_all, print_doc_line, help_cmd_list, find_cmd, lookup_cmd_1,
+ undef_cmd_error, lookup_cmd, deprecated_cmd_warning,
+ lookup_cmd_composition, complete_on_cmdlist, complete_on_enum):
+ Moved here from command.c.
+ (add_info, add_info_alias, add_com, add_com_alias): Moved here from
+ top.c.
+ * cli/cli-decode.h: Definitions/declarations for the above.
+ * cli/cli-cmds.c: New file. GDB CLI commands.
+ (error_no_arg, info_command, show_command, help_command, show_version,
+ quit_command, pwd_command, cd_command, echo_command, shell_escape,
+ make_command, show_user, set_debug, show_debug, init_cmd_lists):
+ Moved here from top.c.
+ (apropos_command): Moved here from command.c.
+ (complete_command, source_command): Moved here (part) from top.c.
+ (is_complete_command): New function. Checks if a command is the
+ "complete" command.
+ (init_cli_cmds): New function. Add commands to the CLI (from code
+ previously in top.c.
+ * cli/cli-cmds.h: Definitions/declarations for the above.
+ * cli/cli-script.c: New file. GDB CLI command scripting.
+ (build_command_line, get_command_line, print_command_lines,
+ print_command_line, execute_user_command, execute_control_command,
+ while_command, if_command, arg_cleanup, setup_user_args, locate_arg,
+ insert_args, realloc_body_list, read_next_line,
+ recurse_read_control_structure, read_command_lines, free_command_lines,
+ do_free_command_lines_cleanup, make_cleanup_free_command_lines,
+ validate_comname, user_defined_command, define_command,
+ document_command, source_cleanup_lines, do_fclose_cleanup,
+ show_user_1): Moved here from top.c.
+ (script_from_file): New function. Implements execution of a script
+ contained in a file (part of code for the source_command() that used
+ to exist in top.c).
+ * cli/cli-script.h: Definitions/declarations for the above.
+ * cli/cli-setshow.c: New file. Handle set and show GDB CLI commands.
+ (parse_auto_binary_operation, parse_binary_operation,
+ do_setshow_command, cmd_show_list): Moved here from command.c.
+ * cli/cli-setshow.h: Definitions/declarations for the above.
+ * top.c: Remove all CLI code, except the command loop.
+ (gdb_init): Call init_cli_cmds().
+ * command.c: Remove obsolete file.
+ * command.h: Mark as DEPRECATED.
+ * gdbcmd.h: Ditto.
+ * call-cmds.h: Ditto.
+ * Makefile.in (SFILES): Remove command.c.
+ (COMMON_OBS): Remove command.o.
+ (command.o): Remove obsolete target.
+ (cli_decode_h, cli_cmds_h, cli_script_h, cli_setshow_h): New macros.
+ Refer to CLI header files.
+ (cli-decode.o, cli-cmds.o, cli-setshow.o, cli-script.o): New targets.
+ (SUBDIR_CLI_OBS, SUBDIR_CLI_SRCS, SUBDIR_CLI_DEPS, SUBDIR_CLI_INITS,
+ SUBDIR_CLI_LDFLAGS, SUBDIR_CLI_CFLAGS, SUBDIR_CLI_ALL, SUBDIR_CLI_CLEAN,
+ SUBDIR_CLI_INSTALL, SUBDIR_CLI_UNINSTALL): New macros for new cli
+ subdirectory.
+ * configure.in (enable_gdbcli): New option. Include the CLI in the
+ executable (cannot be disabled yet).
+ (CONFIG_OBS, CONFIG_DEPS, CONFIG_SRCS, CONFIG_INITS, ENABLE_CFLAGS,
+ CONFIG_ALL, CONFIG_CLEAN, CONFIG_INSTALL, CONFIG_UNINSTALL): Add
+ the corresponding SUBDIR_CLI_* macros if CLI requested.
+ * configure: Regenerate.
+
+2000-10-27 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * p-exp.y (yylex): avoid problem with symbol name
+ starting as a operator name.
+
+2000-11-30 Fernando Nasser <fnasser@redhat.com>
+
+ * linespec.h: New file. Declarations for linespec.c.
+ * linespec.c, alpha-tdep.c, breakpoint.c, parse.c, source.c,
+ symtab.c, tracepoint.c: Include the above.
+ * completer.c: New file. Line completion stuff for GDB.
+ (get_gdb_completer_word_break_characters,
+ get_gdb_completer_quote_characters): New functions. Accessors for
+ useful completer internal data.
+ (filename_completer, line_completion_function, skip_quoted): Moved
+ here from top.c.
+ * completer.h: New file. Declarations for the above.
+ * linespec.c (decode_line_1): Use
+ get_gdb_completer_word_break_characters and
+ get_gdb_completer_quote_characters.
+ * top.c: Include completer.h.
+ (filename_completer, line_completion_function, skip_quoted):
+ Moved to completer.c.
+ * corefile.c, exec.c, source.c, symfile.c, linespec.c: Include
+ completer.h.
+ * Makefile.in (SFILES): Add completer.c.
+ (COMMON_OBS): Add completer.o.
+ (completer.o): New target.
+ (linespec.o, alpha-tdep.o, breakpoint.o, parse.o, source.o,
+ symtab.o, tracepoint.o): Add linespec.h to dependencies list.
+ (corefile.o, exec.o, source.o, symfile.o, linespec.o): Add completer.h
+ to dependencies list.
+
+Thu Nov 30 13:19:16 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.c: Regenerate.
+
+Thu Nov 30 01:14:21 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * varobj.c (varobj_create): Initialize ``old_fi''.
+ (varobj_update): Initialize ``templist''.
+
+ * kod-cisco.c (cisco_kod_request): Simplify allocation of
+ ``sync_ids'' eliminating uninitialized variable.
+
+2000-11-28 Mark Salter <msalter@redhat.com>
+
+ * MAINTAINERS: Add Mark Salter to Write After Approval list.
+
+Tue Nov 28 12:24:43 2000 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c (dll_code_sections_add): strdup -> xstrdup.
+
+Mon Nov 27 11:45:52 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (remote_write_bytes): Add default case to switch
+ initializing ``todo''. Ditto for ``nr_bytes''.
+ * top.c (catch_errors): Always initialize ``val''.
+ * solib.c (info_sharedlibrary_command): Handle bfd_get_arch_size
+ returning an unknown size.
+ * gdbtypes.c (count_virtual_fns): Always initialize ``vfuncs''.
+ * breakpoint.c (break_at_finish_at_depth_command_1): Initialise
+ extra_args to NULL.
+ (break_at_finish_command_1): Ditto.
+
+Mon Nov 27 11:27:06 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Add GFDL updates to 5.1 release criteria.
+
+2000-11-26 Nick Clifton <nickc@redhat.com>
+
+ * configure.tgt (xscale-*): Add.
+ * configure.host (xscale-*): Add.
+
+2000-11-24 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * m68hc11-tdep.c (gdb_print_insn_m68hc11): New function.
+ (_initialize_m68hc11_tdep): Install it. Register bfd_arch_m68hc12.
+
+2000-11-24 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * m68hc11-tdep.c (gdbarch_tdep): Move stack_correction global to here.
+ (STACK_CORRECTION): Get stack correction using gdbarch_tdep.
+ (m68hc11_saved_pc_after_call): Use STACK_CORRECTION.
+ (m68hc11_frame_chain): Likewise.
+ (m68hc11_frame_init_saved_regs): Likewise.
+ (m68hc11_init_extra_frame_info): Likewise.
+ (m68hc11_push_arguments): Likewise.
+ (m68hc11_push_arguments): Likewise.
+ (m68hc11_store_struct_return): Likewise.
+ (m68hc11_push_return_address): Likewise.
+ (m68hc11_gdbarch_init): Setup stack_correction according to arch.
+
+Mon Nov 20 13:59:29 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in: Add support for configure option
+ --enable-gdb-build-warnings. Mention need to update doco.
+ * configure: Regenerate.
+
+2000-11-21 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * target.h (TARGET_SIGNAL_REALTIME_64): Added for IRIX 6.
+ * target.c (target_signal_from_host, do_target_signal_to_host):
+ Handle TARGET_SIGNAL_REALTIME_64.
+
+2000-11-21 Kevin Buettner <kevinb@redhat.com>
+
+ * solib.c (solib_open): Handle the case where
+ solib_absolute_prefix is NULL.
+
+2000-11-20 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * solist.h: Declare new function solib_open.
+ * solib.c (solib_open): New function. Abstracts some of the
+ code from solib_map_sections, for finding the binary solib file.
+ (solib_map_sections): Call solib_open.
+ * solib-svr4.c (enable_break): Call solib_open.
+
+2000-11-20 J.T. Conklin <jtc@redback.com>
+
+ * gdbserver/low-nbsd.c (fetch_inferior_registers,
+ store_inferior_registers): Support older NetBSD/powerpc systems
+ from before fp reg support was added. Adapt to register number
+ changes caused when powerpc target was multi-arched.
+
+2000-11-20 H.J. Lu <hjl@gnu.org>
+
+ * ia64-tdep.c (gdbarch_tdep): Change reference from
+ ELFOSABI_MONTEREY to ELFOSABI_AIX.
+
+2000-11-20 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * c-valprint.c (print_function_pointer_address): New function
+ to automatically dereference a function pointer for printing
+ if necessary.
+ (c_val_print): Use print_function_pointer_address when printing
+ function pointer addresses.
+
+2000-11-20 J.T. Conklin <jtc@redback.com>
+
+ * gdbserver/low-nbsd.c: Fix typos.
+
+2000-11-20 Jeffrey A Law (law@cygnus.com)
+
+ * pa64solib.c (add_to_solib): Pass TARGET to pa64_solib_load_symbols.
+
+Mon Nov 20 23:21:53 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Peter Schauer and Kevin Buettner maintain AIX. Jim
+ Blandy, Kevin Buettner and Peter Schauer share shared libs.
+
+ From Nick Duffek:
+ * MAINTAINERS: Share responsibility for
+ Solaris/x86 between co-maintainers.
+
+ * MAINTAINERS: Add linespec as a separate component.
+
+Mon Nov 20 14:29:39 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * command.h (error_no_arg): Add noreturn attribute to declaration.
+
+Fri Nov 17 16:07:23 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * utils.c (xvasprintf, xasprintf): New functions.
+ * defs.h (xvasprintf, xasprintf): Add declarations.
+
+ * remote.c (add_packet_config_cmd): Use function xasprintf instead
+ of asprintf.
+ * utils.c (vfprintf_maybe_filtered, vfprintf_unfiltered): Use
+ function xvasprintf instead of vasprintf.
+
+ * TODO (xasprintf): Update.
+
+Mon Nov 20 12:22:32 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Mention ``extern'' and ``STREQ'' cleanups.
+
+2000-11-19 Jim Blandy <jimb@redhat.com>
+
+ * symtab.c (no_symtab_msg): Remove definition.
+ (sources_info): Replace use of no_symtab_msg with the string
+ itself.
+ * linespec.c (no_symtab_msg): Remove declaration.
+ (decode_line_1): Replace uses of no_symtab_msg with the string
+ itself.
+
+2000-11-17 Kevin Buettner <kevinb@redhat.com>
+
+ * rs6000-tdep.c (refine_prologue_limit): New function.
+ (skip_prologue): When zero, attempt to obtain value for
+ lim_pc by calling refine_prologue_limit(). Also, fix
+ fencepost error regarding the limit in the loop.
+
+ From Peter Schauer:
+ * rs6000-tdep.c (skip_prologue): Handle optimizer code motions into
+ the prologue by continuing the prologue search, if we have no valid
+ frame yet or if the return address is not yet saved in the frame.
+
+2000-11-17 Kevin Buettner <kevinb@redhat.com>
+
+ * wrapper.c (gdb_value_assign, wrap_value_assign): Protoize.
+
+2000-11-16 Christopher Faylor <cgf@redhat.com>
+
+ * thread.c (thread_apply_all_command): Save the command before
+ executing it because it may be modified. Restore the saved command so
+ that the same command is executed on next thread.
+ (thread_apply_command): Same correction.
+
+2000-11-16 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * regcache.c (read_register_bytes): Failing to set register_valid
+ is not necessarily an error, if the register is a pseudo-register.
+ Some pseudo-registers are never marked as valid, so that they will
+ be read anew every time. Determining if a pseudo-register is valid
+ (or should be marked invalid) may be difficult, whereas just
+ recomputing it may be cheap.
+
+Thu Nov 16 09:47:57 2000 David Taylor <taylor@redhat.com>
+
+ * tracepoint.c (trace_find_tracepoint_command): Replace call to
+ parse_and_eval_address with a call to parse_and_eval_long as
+ we are evaluating an integer, not an address.
+ * top.c (show_commands): Ditto.
+
+2000-11-15 Kevin Buettner <kevinb@redhat.com>
+
+ * xcoffread.c (arrange_linetable, xcoff_initial_scan): Protoize.
+
+Wed Nov 15 09:31:39 2000 David Taylor <taylor@redhat.com>
+
+ * utils.c (strlen_paddr, paddr, paddr_nz): Use TARGET_ADDR_BIT,
+ not TARGET_PTR_BIT, since we are dealing with addresses, not
+ pointers.
+
+2000-11-14 Daniel Berlin <dberlin@redhat.com>
+
+ From Kenneth Block <kenneth.block@compaq.com>
+
+ * demangle.c : Use libibery list of demanglers instead of out of
+ date local copy.
+
+Wed Nov 15 00:29:46 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Klaus Espenlaub <espenlaub@informatik.uni-ulm.de>
+ * remote.c (_initialize_remote): Call
+ show_memory_write_packet_size when ``show remotewritesize''
+ command.
+
+2000-11-13 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/djgpp/config.sed: Fix tweaking "VPATH=.:foo", and handle
+ the gettext's posrcprefix correctly with drive letters.
+
+2000-11-10 Jim Blandy <jimb@redhat.com>
+
+ * stabsread.c (read_range_type): Properly construct complex
+ type nodes.
+
+2000-11-10 Fernando Nasser <fnasser@totem.toronto.redhat.com>
+
+ * symtab.c (decode_line_1, total_number_of_methods, find_methods,
+ build_command_line_spec, find_toplevel_char, decode_line_2):
+ Move to linespec.c.
+ * linespec.c: New file. Routines that handle linespecs, formerly
+ in symtab.c.
+ * symtab.h: Export find_line_symtab and find_function_start_sal.
+ * Makefile.in (SFILES): Add linespec.c.
+ (COMMON_OBS): Add linespec.o.
+ (linespec.o): New target.
+
+2000-11-10 Christopher Faylor <cgf@cygnus.com>
+
+ * inferior.h (step_over_calls_kind): New enum to clarify values in
+ step_over_calls.
+ * infcmd.c (step_over_calls): Change definition.
+ (step_1): Use new enum values in relation to step_over_calls.
+ (step_once): Ditto.
+ (until_next_command): Ditto.
+ * infrun.c (clear_proceed_status): Ditto.
+ (handle_inferior_event): Ditto.
+
+2000-11-10 Stephane Carrez <Stephane.Carrez@sun.com>
+
+ * inferior.h (step_stop_if_no_debug): New variable.
+ * infrun.c (step_stop_if_no_debug): Declare.
+ (handle_inferior_event): Stop the step command if we entered a function
+ without line info.
+ (_initialize_infrun): New command 'set step-mode' to control the step
+ command.
+ * infcmd.c (step_once): Switch to stepi mode if there is no line info
+ (and switching is enabled).
+
+2000-11-10 J.T. Conklin <jtc@redback.com>
+
+ * target.c (do_xfer_memory): Only perform a single memory transfer
+ instead of iterating to tranfer the entire region. Higher layers
+ are expected to call this function multiple times for partial
+ transfers.
+ (target_xfer_memory_partial): Remove unused local variables.
+
+2000-11-10 Nick Duffek <nsd@redhat.com>
+
+ * target.c (target_xfer_memory_partial): Return bytes transferred
+ instead of 0.
+
+2000-11-09 Kevin Buettner <kevinb@redhat.com>
+
+ * values.c (value_being_returned, using_struct_return): Protoize.
+ * varobj.c (child_exists, cplus_class_num_children): Protoize.
+
+2000-11-09 Kevin Buettner <kevinb@redhat.com>
+
+ Changes based on a patch from Ulrich Drepper:
+ * solib-svr4.c (svr4_relocate_main_executable): New function.
+ (svr4_solib_create_inferior_hook): Call
+ svr4_relocate_main_executable.
+
+2000-11-09 J.T. Conklin <jtc@redback.com>
+
+ * config/i386/nbsd.mh: Remove solib.o, solib-svr4.o from NATDEPFILES.
+ * config/i386/nbsdelf.mh: Likewise.
+ * config/m68k/nbsd.mh: Likewise.
+ * config/ns32k/nbsd.mh: Likewise.
+ * config/powerpc/nbsd.mh: Likewise.
+ * config/sparc/nbsd.mh: Likewise.
+ * config/sparc/nbsdelf.mh: Likewise.
+ * config/i386/nbsd.mt: Add solib.o, solib-svr4.o to TDEPFILES.
+ * config/i386/nbsdelf.mt: Likewise.
+ * config/m68k/nbsd.mt: Likewise.
+ * config/ns32k/nbsd.mt: Likewise.
+ * config/powerpc/nbsd.mt: Likewise.
+ * config/sparc/nbsd.mt: Likewise.
+
+2000-11-09 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ Add auto-solib-add support for AIX, remove obsolete and unused
+ SOLIB_SYMBOLS_MANUAL code, cleanup of AIX shared library handling code.
+ * rs6000-nat.c (vmap_symtab): Do not try to modify offsets
+ if symbols are not yet loaded.
+ (vmap_add_symbols): New function to add symbols for a vmap entry.
+ (add_vmap): Turn errors into warnings, return NULL vmap upon
+ failure. Add symbols via vmap_add_symbols only if requested.
+ (xcoff_relocate_core): Allow debugging of core files without an
+ executable file. Handle NULL returns from add_vmap gracefully.
+ * xcoffsolib.c (solib_add): Remove, no longer needed.
+ (solib_info): Do not check for new shared libraries if there is no
+ inferior process.
+ (sharedlibrary_command): Made static.
+ Do not check for new shared libraries if there is no inferior process.
+ Add symbols for requested shared libraries via vmap_add_symbols.
+ (_initialize_solib): Add `set auto-solib-add' command.
+ * xcoffsolib.h (vmap_add_symbols): Add prototype declaration.
+
+ * config/rs6000/tm-rs6000.h (PC_LOAD_SEGMENT): Move from here ...
+ * config/rs6000/nm-rs6000.h: ... to here, this is an AIX native
+ feature.
+ * config/powerpc/tm-macos.h, config/powerpc/tm-ppc-eabi.h,
+ config/powerpc/tm-ppc-nw.h, config/rs6000/tm-rs6000ly.h:
+ Remove #undef PC_LOAD_SEGMENT.
+ * config/powerpc/aix.mt, config/rs6000/aix4.mt, config/rs6000/rs6000.mt
+ (TDEPFILES): Move xcoffsolib.o from here ...
+ * config/powerpc/aix.mh, config/rs6000/aix4.mh, config/rs6000/rs6000.mh
+ (NATDEPFILES): ... to here, xcoffsolib.o contains AIX native code
+ only.
+ * rs6000-tdep.c: Remove #include xcoffsolib.h, no longer needed.
+ * xcoffsolib.h (xcoff_relocate_symtab_hook): Remove declaration.
+ * rs6000-nat.c (_initialize_core_rs6000): Remove setting of
+ xcoff_relocate_symtab_hook, no longer needed.
+ * xcoffsolib.c (solib_info, sharedlibrary_command): Remove
+ xcoff_relocate_symtab_hook indirection, call xcoff_relocate_symtab
+ directly, as xcoffsolib.c is now compiled in native AIX configurations
+ only.
+ * Makefile.in: Update dependencies for rs6000-tdep.o, rs6000-nat.o
+ and xcoffsolib.o.
+
+Thu Nov 9 17:16:29 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Specify the vax-dec-vms5.5 target tupple.
+ * vax-tdep.c: Include "gdbcore.h", "frame.h" and "value.h".
+ (vax_print_insn): Change ``d'' to a const char pointer.
+
+2000-11-08 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * gdbarch.sh: Spelling correction: registrary -> registry.
+ * gdbarch.c: Ditto.
+
+Wed Nov 8 23:08:48 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * m68k-tdep.c (m68k_get_longjmp_target): Work around targets that
+ don't define JB_PC or JB_ELEMENT_SIZE.
+
+Wed Nov 8 22:46:43 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * m68k-tdep.c (m68k_get_longjmp_target): Rename function
+ get_longjmp_target. Remove wrapping #ifdef GET_LONGJMP_TARGET.
+ * config/m68k/tm-m68k.h (m68k_get_longjmp_target): Add function
+ declaration.
+
+ * config/m68k/tm-vx68.h, config/m68k/tm-sun3.h,
+ config/m68k/tm-m68kv4.h, config/m68k/tm-linux.h,
+ config/m68k/tm-es1800.h, config/m68k/tm-cisco.h: Update definition
+ of GET_LONGJMP_TARGET. Delete get_longjmp_target function
+ declaratation.
+
+Wed Nov 8 15:32:23 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbserver/configure.in (files): Don't link nm-empty.h when a
+ non-native target.
+ * gdbserver/configure: Regenerate.
+
+2000-11-07 Kevin Buettner <kevinb@redhat.com>
+
+ * valops.c (typecmp): Protoize.
+ * valprint.c (strcat_longest): Protoize.
+
+2000-11-07 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-tdep.c (native_find_global_pointer): New global variable.
+ (struct gdbarch_tdep): Add member find_global_pointer.
+ (ia64_gdbarch_init): Initialize find_global_pointer member. Also,
+ tell the gdbarch machinery that we have floating point registers.
+ (FIND_GLOBAL_POINTER): New macro.
+ (generic_elf_find_global_pointer): Renamed from find_global_pointer.
+ (find_func_descr, ia64_push_return_address): Call
+ FIND_GLOBAL_POINTER instead of find_global_pointer.
+ (process_note_abi_tag_sections): Enable code previously disabled
+ by #if 0.
+
+2000-11-07 Daniel Berlin <dberlin@redhat.com>
+
+ * dwarf2read.c: Revert June 5th change for caching of types,
+ as per Jim Blandy's request.
+
+2000-11-06 Fernando Nasser <fnasser@totem.toronto.redhat.com>
+
+ * wrapper.c (gdb_value_assign): New function. Longjump-free
+ version of value_assign.
+ (wrap_value_assign): New function. Wrapper for value_assign.
+ * wrapper.h: Add declaration for the above.
+ * varobj.c (varobj_set_value): Use gdb_value_assign, not
+ value_assign which can longjump. Do not change varobj value if
+ assign fails.
+
+2000-11-06 Fernando Nasser <fnasser@cygnus.com>
+
+ From Steven Johnson <sbjohnson@ozemail.com.au>:
+
+ This set of changes add "hookpost-" as an expansion on the original
+ hooking of commands to GDB. A Hook may now be run "AFTER" execution of
+ a command as well as before.
+
+ * command.h (struct cmd_list_element): Changed elements hook and hookee
+ to hook_pre and hookee_pre respectively. Added hook_post and hookee_post
+ for the post hook command operation. Added hook_in so that an executing
+ hook can be flagged to prevent recursion.
+ * command.c (add_cmd): Changed initilization of cmd_list_element to
+ reflect above changes.
+ (delete_cmd): Remove both pre and post hooks.
+ (help_cmd): Notify that the command has pre and/or post hooks.
+ * infrun.c (normal_stop): Change references to hook_pre from hook.
+ * top.c (execute_command): Run both pre and post hooks.
+ (define_command): Allow definition of both pre and post hooks.
+ The definition of pre-hooks is done as before, with the "hook-"
+ prefix for backward compatibility.
+
+2000-11-06 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * stack.c (return_command): Pop dummy frame if we just returned from
+ a stop in a call dummy.
+
+2000-11-05 Kevin Buettner <kevinb@redhat.com>
+
+ * v850-tdep.c (handle_prepare, handle_pushm): Remove extraneous
+ blank line after function declarator.
+ * v850ice.c (v850ice_xfer_memory, do_gdb): Protoize.
+
+2000-11-03 Kevin Buettner <kevinb@redhat.com>
+
+ * utils.c (add_continuation, add_intermediate_continuation,
+ printchar): Protoize.
+
+2000-11-03 Kevin Buettner <kevinb@redhat.com>
+
+ * dwarf2read.c (new_symbol): Relocate address of symbol by the
+ base address of the section it is in rather than always using
+ the base address of the .text section.
+
+2000-11-01 J.T. Conklin <jtc@redback.com>
+
+ * TODO: Note abstraction layer violation where "ocd reset" command
+ must invalidate the dcache, and how this might be fixed.
+
+ * monitor.c (#include "dcache.h"): Removed.
+ (remote_dcache): Removed.
+ (monitor_open): Removed code that created local dcache.
+ (flush_monitor_dcache): Removed (unused function).
+ (monitor_resume): Removed call to dcache_invd().
+ (monitor_load): Likewise.
+ (monitor_xfer_memory): Changed to call monitor_write_memory(),
+ monitor_write_memory_block(), and monitor_read_memory() instead
+ of dcache_xfer_memory().
+ * monitor.h (flush_monitor_dcache): Removed (unused function).
+ * ocd.c (#include "dcache.h"): Removed.
+ (ocd_dcache): Removed.
+ (ocd_open): Removed code that created local dcache.
+ (ocd_resume): Removed call to dcache_invd().
+ (ocd_xfer_memory): Changed to call ocd_write_bytes() and
+ ocd_read_bytes() instead of dcache_xfer_memory().
+ (bdm_reset_command): Invalidate target dcache.
+ * remote-bug.c (bug_load): Remove call to dcache_invd().
+ (bug_resume): Likewise.
+ (bug_settings): Remove dcache, readfunc, and writefunc fields
+ from initializer.
+ (bug_xfer_memory): Changed to call bug_read_memory() and
+ bug_write_memory() instead of dcache_xfer_memory().
+ * remote-nindy.c (#include "dcache.h"): Removed.
+ (nindy_dcache): Removed.
+ (nindy_open): Removed code that created local dcache.
+ (nindy_resume): Removed call to dcache_invd().
+ (nindy_load): Likewise.
+ (nindy_xfer_inferior_memory): Changed to call ninMemPut() and
+ ninMemGet() instead of dcache_xfer_memory().
+ * remote-sds.c (#include "dcache.h"): Removed.
+ (sds_dcache): Removed.
+ (sds_open): Removed code that created local dcache.
+ (sds_resume): Removed call to dcache_invd().
+ (sds_xfer_memory): Changed to call sds_write_bytes() and
+ sds_read_bytes() instead of dcache_xfer_memory().
+ * remote-utils.c (gr_open): Removed code that created local dcache.
+ * remote-utils.h (#include "dcache.h"): Removed.
+ (struct gr_settings): Removed dcache, readfunc, and writefunc fields.
+ (gr_get_dcache, gr_set_dcache): Removed macro definitions.
+ * remote.c (#include "dcache.h"): Removed.
+ (remote_dcache): Removed.
+ (remote_open_1): Removed code that created local dcache.
+ (remote_async_open_1): Likewise.
+ (remote_resume): Removed call to dcache_invd().
+ (remote_async_resume): Likewise.
+ (remote_xfer_memory): Changed to call remote_write_bytes() and
+ remote_read_bytes() instead of dcache_xfer_memory().
+ * wince.c (#include "dcache.h"): Removed.
+ (remote_dcache): Removed.
+ (child_create_inferior): Removed code that created local dcache.
+ (child_xfer_memory): Changed to call remote_write_bytes() and
+ remote_read_bytes() instead of dcache_xfer_memory().
+ (child_resume): Removed call to dcache_invd().
+
+ * target.c (target_dcache): Added.
+ (target_load): Invalidate target_dcache.
+ (do_xfer_memory): New function.
+ (target_xfer_memory): Reimplement in terms of dcache_xfer_memory().
+ (target_xfer_memory_partial): Likewise.
+ (initialize_targets): Create target_dcache.
+ * target.h (#include "dcache.h"): Added.
+ (target_open): Invalidate target_dcache.
+ (target_resume): Likewise.
+ (do_xfer_memory): New declaration.
+
+ * dcache.c (dcache_init): Removed reading and writing arguments.
+ (dcache_struct): Removed read_memory and write_memory fields.
+ (dcache_write_line): Call do_xfer_memory.
+ (dcache_read_line): Likewise.
+ (dcache_xfer_memory): Likewise.
+ (dcache_invalidate): Renamed from dcache_invd.
+ (dcache_init): Updated.
+ (dcache_xfer_memory): Updated.
+ * dcache.h (memxferfunc): Removed definition.
+ (dcache_init): Removed reading and writing arguments.
+
+2000-11-03 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * objfiles.c (objfile_relocate): Relocate ei.entry_point with
+ its section offset, use SECT_OFF_TEXT only as a fallback.
+
+2000-11-01 Kevin Buettner <kevinb@redhat.com>
+
+ * symm-nat.c (print_1167_regs): Remove extraneous blank line
+ after function declarator.
+ * symtab.c (search_symbols): Likewise.
+ * ultra3-nat.c (fetch_core_registers): Protoize.
+
+2000-10-30 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * config/sh/tm-linux.h: New file. Include generic tm-linux.h,
+ plus tm-sh.h, then define SVR4_FETCH_LINK_MAP_OFFSETS to use
+ the sh target function instead of the default link map offsets.
+ * config/sh/sh.mt: Add solib.o and solib-svr4.o to TDEPFILES.
+ Use sh/tm-linux.h instead of sh/tm-sh.h.
+ * sh-tdep.c (sh_linux_svr4_fetch_link_map_offsets):
+ New function. Construct target-specific link map offsets.
+ * i386-linux-tdep.c (i386_linux_svr4_fetch_link_map_offsets:
+ New function. Construct target-specific link map offsets.
+ * config/i386/tm-linux.h: Use above function instead of default.
+
+2000-10-30 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * config/i386/tm-linux.h: Remove definition of SVR4_SHARED_LIBS,
+ and inclusion of solib.h. Move up into ../tm-linux.h.
+ config/tm-linux.h: Define SVR4_SHARED_LIBS, include solib.h.
+
+2000-10-30 Kevin Buettner <kevinb@redhat.com>
+
+ * top.c (simplified_command_loop, add_info, add_com,
+ help_command): Protoize.
+ * ui-out.c (gdb_query): Protoize.
+
+2000-10-30 Kevin Buettner <kevinb@redhat.com>
+
+ Changes based on analysis from Peter Schauer:
+ * solist.h (struct so_list): Remove field lmend.
+ (struct target_so_ops): Remove field lm_addr. Add field
+ relocate_section_addresses. Add comments for all fields
+ in this structure
+ (TARGET_SO_LM_ADDR): Remove.
+ (TARGET_SO_RELOCATE_SECTION_ADDRESSES): New macro.
+ * solib-svr4.c (svr4_relocate_section_addresses): New function.
+ (_initialize_svr4_solib): Remove lm_addr initialization. Add
+ initialization for relocate_section_addresses.
+ * solib.c (solib_map_sections): Invoke
+ TARGET_SO_RELOCATE_SECTION_ADDRESSES instead of using now
+ defunct TARGET_SO_LM_ADDR to relocate the section addresses.
+ Also, eliminate assignment to the lmend field since this
+ field no longer exists.
+ (symbol_add_stub): Remove machinery for determining the lowest
+ section.
+ (info_sharedlibrary_command): Print the text section starting
+ and ending addresses.
+ (solib_address): Don't use TARGET_SO_LM_ADDR, nor so->lmend to
+ determine if an address is in a shared object. Instead, scan
+ the section table and test against the starting and ending
+ addresses for each section.
+
+2000-10-30 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * config/m68k/linux.mh: Remove solib.c, solib-svr4.c from NATDEPFILES.
+ * config/powerpc/linux.mh: ditto.
+ * config/ia64/linux.mh: ditto.
+ * config/i386/linux.mh: ditto.
+ * config/alpha/alpha-linux.mh: ditto.
+ * config/arm/linux.mh: ditto.
+ * config/m68k/linux.mt: Add solib.c, solib-svr4.c to TDEPFILES.
+ * config/powerpc/linux.mt: ditto.
+ * config/ia64/linux.mt: ditto.
+ * config/i386/linux.mt: ditto.
+ * config/alpha/alpha-linux.mt: ditto.
+ * config/arm/linux.mt: ditto.
+
+2000-10-30 J.T. Conklin <jtc@redback.com>
+
+ * gdbarch.sh, hp-psymtab-read.c, hpread.c, m3-nat.c, mcore-tdep.c,
+ mips-tdep.c, monitor.c, regcache.c, remote-es.c, ser-unix.c,
+ somread.c, tracepoint.c: Fix spelling errors in comments.
+ * gdbarch.c: Regenerate.
+
+ * gnu-nat.c (S_exception_raise_request): Fix typos and spelling
+ errors in strings.
+ * m3-nat.c (intercept_exec_calls, mach_thread_parse_id): Likewise.
+ * mcore-tdep.c (mcore_analyze_prologue): Likewise.
+ * mips-tdep.c (mips16_next_pc, _initialize_mips_tdep): Likewise.
+ * remote-e7000.c (e7000_start_remote): Likewise.
+ * remote-rdp.c (handle_swi): Likewise.
+ * remote-vx.c (vx_load_command): Likewise.
+ * sh-tdep.c (sh_do_pseudo_register): Likewise.
+ * sol-thread.c (td_err_string): Likewise.
+ * symtab.c (decode_line_2): Likewise.
+
+Mon Oct 30 10:19:01 2000 David Taylor <taylor@redhat.com>
+
+ * eval.c (parse_and_eval_long): New function.
+ * value.h: Declare it.
+
+ * breakpoint.c (breakpoints_info, maintenance_info_breakpoints):
+ Call parse_and_eval_long, not parse_and_eval_address.
+ * command.c (do_setshow_command): Ditto.
+ * infcmd.c (step_1, signal_command, continue_command): Ditto.
+ * infrun.c (signals_info): Ditto.
+ * stack.c (set_backtrace_limit_command, backtrace_command_1,
+ up_silently_base, down_silently_base): Ditto.
+ * tracepoints.c (tracepoints_info, trace_find_command,
+ trace_find_tracepoint_command): Ditto.
+ * valprint.c (set_radix): Ditto.
+ * values.c (show_values): Ditto.
+
+2000-10-28 Kevin Buettner <kevinb@redhat.com>
+
+ * symtab.c (decode_line_2, file_matches, search_symbols): Protoize.
+ * thread.c (iterate_over_threads): Protoize.
+
+2000-10-27 J.T. Conklin <jtc@redback.com>
+
+ * arch-utils.c (set_architecture, set_architecture_from_arch_mach,
+ set_gdbarch_from_file): Fix spelling error in string.
+ * v850-tdep.c (v850_target_architecture_hook): Likewise.
+ * gdbarch.sh: Fix spelling errors in comments.
+ * gdbarch.c, gdbarch.h: Regenerate.
+
+ * ppcnbsd-nat.c (fetch_core_registers, fetch_inferior_registers,
+ store_inferior_registers): Support older NetBSD/powerpc systems
+ from before fp reg support was added. Adapt to register number
+ changes caused when powerpc target was multi-arched.
+
+2000-10-26 David B. Anderson <davea@sgi.com>
+
+ * breakpoint.c breakpoint.h hppab-nat.c infrun.c
+ language.h mcore-tdep.c mips-tdep.c symfile.c symtab.c
+ symtab.h target.c tm-mips.h xm-sun4sol2.h: Corrected
+ spelling errors in comments.
+ * gdbarch.c gdbarch.sh: Removed word from comment.
+
+2000-10-26 Kevin Buettner <kevinb@redhat.com>
+
+ * sun3-nat.c (fetch_core_registers): Protoize.
+ * symm-nat.c (print_1167_regs, child_xfer_memory): Protoize.
+
+2000-10-26 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * stabsread.c (define_symbol): Update comment.
+
+2000-10-26 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * stabsread.c (define_symbol): Set the type_name of the type
+ of the new symbol to the symbol name for type symbol, if the
+ language is Pascal.
+
+2000-10-26 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * arch-utils.c, arch-utils.h (default_convert_from_func_ptr_addr):
+ New function.
+ * gdbarch.sh (CONVERT_FROM_FUNC_PTR_ADDR): Add.
+ * gdbarch.c, gdbarch.h: Regenerate.
+ * valops.c (find_function_addr): Use CONVERT_FROM_FUNC_PTR_ADDR
+ unconditionally.
+
+ * config/rs6000/tm-rs6000.h (CONVERT_FROM_FUNC_PTR_ADDR): Delete
+ definition.
+ * config/powerpc/tm-linux.h (CONVERT_FROM_FUNC_PTR_ADDR): Remove
+ undef.
+ * rs6000-tdep.c (rs6000_convert_from_func_ptr_addr): Fix comment.
+ (rs6000_gdbarch_init): Register rs6000_convert_from_func_ptr_addr
+ if not ELFOSABI_LINUX.
+
+2000-10-25 Kevin Buettner <kevinb@redhat.com>
+
+ * config/rs6000/rs6000lynx.mt (TDEPFILES): Revert 2000-10-24
+ change in which solib-svr4.o was inadvertently added to this
+ list.
+
+2000-10-25 Fred Fish <fnf@cygnus.com>
+
+ * mips-tdep.c (MIPS_DEFAULT_MASK_ADDRESS_P): Define using either
+ the current arch or use zero.
+
+2000-10-25 Fernando Nasser <fnasser@cygnus.com>
+
+ * ser-unix.c (do_unix_readchar): Coding style improvement only.
+
+2000-10-25 Fernando Nasser <fnasser@cygnus.com>
+
+ * target.c (generic_mourn_inferior): Notify GUI that inferior is gone
+ by calling detach_hook, if defined.
+
+2000-10-24 Kevin Buettner <kevinb@redhat.com>
+
+ * coffread.c (coff_end_symtab): When calling end_symtab(),
+ use SECT_OFF_TEXT() instead of 0 to represent the .text
+ section.
+ * hp-symtab-read.c (hpread_expand_symtab): Likewise.
+ * hpread.c (hpread_expand_symtab, hpread_process_one_debug_symbol):
+ Likewise.
+
+2000-10-24 Kevin Buettner <kevinb@redhat.com>
+
+ * solib-svr4.c: New file created out of much of solib.c...
+ * solib.c (_SYSCALL32, BKPT_AT_SYMBOL): Move these defines to
+ solib-svr4.c.
+ (sys/types.h, signal.h, sys/param.h, fcntl.h, a.out.h,
+ elf/external.h, link.h): Move these includes to solib-svr4.c.
+ (bkpt_names, debug_base_symbols, main_name_list,
+ solib_extract_address, SOLIB_EXTRACT_ADDRESS, dynamic_copy,
+ ld_2_copy, debug_addr, flag_addr, LM_ADDR, LM_NEXT, LM_NAME,
+ IGNORE_FIRST_LINK_MAP_ENTRY, breakpoint_addr,
+ allocate_rt_common_objfile, solib_add_common_symbols,
+ bfd_lookup_symbol, look_for_base, elf_locate_base, locate_base,
+ first_link_map_member, open_symbol_file_object, match_main,
+ current_sos, interp_text_sect_low, interp_text_sect_high,
+ interp_plt_sect_low, interp_plt_sect_high,
+ in_svr4_dynsym_resolve_code, disable_break, enable_break,
+ special_symbol_handling): Moved to solib-svr4.c.
+ (debug32_copy, shadow_contents, fdmatch)
+ Removed entirely.
+ (struct so_list): Moved to solist.h
+ (MAX_PATH_SIZE): Moved to solist.h and renamed to
+ SO_NAME_MAX_PATH_SIZE.
+
+ * solist.h: New file created from struct so_list in solib.c.
+ (struct lm_info): Add forward declaration.
+ (struct so_list): Remove fields lm, lm32, lmaddr. Replace with a
+ single field, lm_info, which will be a pointer to target specific
+ data.
+ (struct target_so_ops): New struct.
+ (free_so): Add extern declaration.
+ (current_target_so_ops): Declare new global variable.
+ (solib_map_sections):
+ (TARGET_SO_LM_ADDR, TARGET_SO_FREE_SO, TARGET_SO_CLEAR_SOLIB,
+ TARGET_SO_SOLIB_CREATE_INFERIOR_HOOK,
+ TARGET_SO_SPECIAL_SYMBOL_HANDLING, TARGET_SO_CURRENT_SOS,
+ TARGET_SO_OPEN_SYMBOL_FILE_OBJECT): New macros.
+ * solib.c (solib_map_sections, free_so, symbol_add_stub,
+ update_solib_list, solib_add, info_shared_library_command,
+ solib_address, clear_solib, solib_create_inferior_hook): Use
+ new TARGET_SO_* macros to call function on target specific
+ side indirectly.
+ (current_target_so_ops): Define new global variable.
+ (_initialize_solib): Eliminate HAVE_LINK_H ifdef.
+ * solib-svr4.h: New file; defines struct link_map_offsets and
+ SVR4_FETCH_LINK_MAP_OFFSETS.
+ * solib-svr4.c (_initialize_svr4_solib, svr4_clear_solib,
+ svr4_free_so): New functions.
+ (special_symbol_handling, solib_create_inferior_function_hook,
+ current_sos): Rename by adding a svr4_ prefix.
+ (default_svr4_fetch_link_map_offsets): New function.
+ (LM_ADDR, LM_NEXT, LM_NAME, IGNORE_FIRST_LINK_MAP_ENTRY,
+ first_link_map_member, open_symbol_file_object, svr4_current_sos):
+ Remove dependence on existence of link.h by calling
+ SVR4_FETCH_LINK_MAP_OFFSETS to obtain the offsets of shared library
+ data. As a result, SVR4 and non-SVR4 versions of many of these
+ functions coalesce into a single function and HAVE_STRUCT_LINK_MAP32
+ ugliness is moved into default_svr4_fetch_link_map_offsets where it
+ is relatively contained.
+ (SOLIB_EXTRACT_ADDRESS): Revert 2000-08-29 change in which
+ solib_extract_address() is called instead of extract_address().
+ (solib_extract_address): Removed.
+
+ * Makefile.in (solib.o): Add solist.h as a dependency.
+ (solib-svr4.o): Add dependencies.
+ * config/alpha/alpha-linux.mh, config/alpha/fbsd.mh,
+ config/arm/linux.mh, config/i386/fbsd.mh,
+ config/i386/i386dgux.mh, config/i386/i386gnu.mh,
+ config/i386/i386sco5.mh, config/i386/i386sol2.mt,
+ config/i386/i386v4.mh, config/i386/i386v42mp.mh,
+ config/i386/linux.mh, config/i386/nbsd.mh,
+ config/i386/nbsdelf.mh, config/i386/ncr3000.mt,
+ config/i386/ptx4.mh, config/i386/sun386.mt,
+ config/ia64/linux.mh, config/m68k/linux.mh,
+ config/m68k/m68kv4.mh, config/m68k/nbsd.mh,
+ config/m68k/sun2os4.mt, config/m68k/sun3os4.mt,
+ config/m88k/delta88v4.mh, config/mips/mipsv4.mh,
+ config/ns32k/nbsd.mh, config/powerpc/linux.mh,
+ config/powerpc/nbsd.mh, config/powerpc/solaris.mh,
+ config/rs6000/rs6000lynx.mt, config/sparc/linux.mt,
+ config/sparc/nbsd.mh, config/sparc/nbsdelf.mh,
+ config/sparc/sun4os4.mt, config/sparc/sun4sol2.mh
+ (NATDEPFILES): Add solib-svr4.o to list.
+
+ * sparc-tdep.c (gregset.h): Don't include unless USE_PROC_FS is
+ defined.
+
+2000-10-24 Kevin Buettner <kevinb@redhat.com>
+
+ * stabsread.c (dbx_lookup_type, dbx_alloc_type,
+ read_sun_builtin_type, read_sun_floating_type,
+ read_range_type): Protoize.
+
+Wed Oct 25 01:19:26 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * solib.c (open_symbol_file_object): Update function signature to
+ match catch_errors function argument.
+
+Wed Oct 25 00:08:01 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-09-06 Angela Marie Thomas <angela@cygnus.com>:
+ * infttrace.c (get_dictionary_entry_of_page): Function
+ require_memory_page_dictionary takes no args.
+
+Tue Oct 24 16:12:00 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdba.el: Delete file.
+ * NEWS: Mention.
+
+2000-10-23 David B Anderson <davea@sgi.com>
+
+ * TODO: Correct spelling errors
+ * command.c (_initialize_command) corelow.c (core_open)
+ main.c (captured_command_loop) mips-tdep.c (mips32_next_pc)
+ remote.c serial.h top.c utils.c config/nm-lynx.h:
+ Correct spelling errors in comments
+
+2000-10-22 Kevin Buettner <kevinb@redhat.com>
+
+ * sparc-nat.c (fetch_core_registers): Protoize.
+ * sparcl-tdep.c (download): Protoize.
+
+Fri Oct 20 19:08:47 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Add Fred Fish to Blanket Write Privs list.
+
+2000-10-19 Josef Ezra <jezra@emc.com>
+
+ * ax-gdb.c (gen_struct_ref): while generating data code, cases of
+ "collect p1->p2->data" where not covered if p2 is a 'typedefed'
+ type. this simple fix should forward the type pointer to the real
+ type.
+
+2000-10-19 Kevin Buettner <kevinb@redhat.com>
+
+ * solib.c (LM_ADDR, LM_NEXT, LM_NAME, IGNORE_FIRST_LINK_MAP_ENTRY,
+ open_symbol_file_object): Protoize.
+
+2000-10-17 Kevin Buettner <kevinb@redhat.com>
+
+ * remote-vx29k.c (vx29k_frame_chain_valid): Protoize.
+ * remote.c (remote_xfer_memory, remote_search): Protoize.
+ * sol-thread.c (sol_thread_xfer_memory): Protoize.
+
+2000-10-16 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * sparc-tdep.c (sparc_fix_call_dummy): Improve comments.
+ Adjust call_dummy_breakpoint_offset, so that `finish' after a stop
+ in a call dummy works.
+ (sparc_gdbarch_init): Fix setting of pc_in_call_dummy, it depends
+ on SPARC32/64_CALL_DUMMY_ON_STACK, not DO_CALL_DUMMY_ON_STACK.
+
+2000-10-15 Kevin Buettner <kevinb@redhat.com>
+
+ * remote-st.c (st2000_xfer_inferior_memory): Protoize.
+ * remote-utils.c (gr_multi_scan): Protoize.
+ * remote-vx.c (vx_xfer_memory, net_get_symbols): Protoize.
+
+2000-10-13 Fernando Nasser <fnasser@cygnus.com>
+
+ * remote.c (putpkt_binary): Call read_frame, not getpkt. Log message.
+ (read_frame): Do not call error() on communication error when
+ reading checksum, but return failure instead and log message.
+
+2000-10-13 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (type_changeable): Arrays are not changeable.
+ Trying to check for updates was causing an error if the array lived
+ in a register as gdb value_equal() cannot handle that case yet.
+
+2000-10-13 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (varobj_update): Prevent uninitialized error code to be
+ returned on type_changed. Also, prevent value_equal() to be called
+ for the types we do not want to test for updates.
+
+2000-10-11 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From Grant Edwards <grante@visi.com>
+ This keeps the GUI alive while running an RDI target and lets the
+ STOP button be used to stop the target.
+ * remote-rdi.c (arm_rdi_stop): New function. Implements target_stop.
+ (init_rdi_ops): Set to_stop target vector entry to the above.
+ * rdi-share/ardi.c (stop_request): New variable. Tells when a stop
+ has been requested.
+ (angel_RDI_stop_request): New function. Registers that a stop has
+ been requested.
+ (angel_RDI_ExecuteOrStep): Add call to ui_loop_hook() in loop that
+ waits while target is executing. Initialize and reset stop_request.
+ * rdi-share/ardi.h: Add declaration of angel_RDI_stop_request().
+
+2000-10-12 Kevin Buettner <kevinb@redhat.com>
+
+ * remote-rdp.c (remote_rdp_xfer_inferior_memory): Protoize.
+ * remote-sds.c (sds_xfer_memory): Protoize.
+ * remote-sim.c (gdbsim_xfer_inferior_memory): Protoize.
+
+2000-10-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Daniel Berlin <dberlin@redhat.com> :
+
+ * symtab.h (SYMBOL_INIT_DEMANGLED_NAME): Initialize the symbol
+ language to auto instead of unknown, so it will try to demangle
+ the symbol.
+ * symtab.h (OPNAME_PREFIX_P): Change operator prefix to correct value.
+ * symtab.c (gdb_mangle_name): Properly handle C++ operators.
+
+2000-10-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Daniel Berlin <dberlin@redhat.com> :
+
+ * symtab.c (lookup_symbol_aux): New function. Renamed from
+ lookup_symbol. Move code to do demangling/case sensitivity to
+ lookup_symbol().
+ (lookup_symbol): Now wrapper for lookup_symbol_aux, so we can
+ perform case sensitivity/demangling without leaking memory. Move
+ code to do demangling/case sensitivity from old_lookup_symbol to
+ here.
+ (lookup_partial_symbol): Use SYMBOL_SOURCE_NAME instead of
+ SYMBOL_NAME.
+ (lookup_block_symbol): Use SYMBOL_SOURCE_NAME instead of
+ SYMBOL_NAME. Don't do linear search in case of C++.
+
+ * symfile.c (compare_symbols): Use SYMBOL_SOURCE_NAME instead of
+ SYMBOL_NAME.
+ (compare_psymbols): Same here.
+
+2000-10-09 Kevin Buettner <kevinb@redhat.com>
+
+ * remote-nindy.c (non_dle, nindy_xfer_inferior_memory): Protoize.
+ * remote-os9k.c (rombug_xfer_inferior_memory): Protoize.
+ * remote-rdi.c (arm_rdi_xfer_memory): Protoize.
+
+2000-10-09 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * config/i386/i386sol2.mh: Add XM_CLIBS definition to resolve
+ reference to gethostbyname.
+
+2000-10-06 Kevin Buettner <kevinb@redhat.com>
+
+ * remote-eb.c (eb_xfer_inferior_memory): Protoize.
+ * remote-es.c (es1800_xfer_inferior_memory, es1800_files_info):
+ Protoize.
+ * remote-mm.c (expect_msg): Protoize.
+
+2000-10-04 Kevin Buettner <kevinb@redhat.com>
+
+ * rs6000-tdep.c (skip_prologue): Add new parameter lim_pc.
+ Update all callers.
+
+2000-10-03 Kevin Buettner <kevinb@redhat.com>
+
+ * remote-bug.c (bug_xfer_memory, bug_insert_breakpoint,
+ bug_remove_breakpoint): Protoize.
+ * remote-e7000.c (fetch_regs_from_dump, e7000_xfer_inferior_memory):
+ Protoize.
+
+2000-10-01 Kevin Buettner <kevinb@redhat.com>
+
+ * remote-adapt.c (adapt_insert_breakpoint, adapt_remove_breakpoint):
+ Protoize.
+ * remote-array.c (write_monitor, array_xfer_memory): Protoize.
+
+2000-09-29 Kevin Buettner <kevinb@redhat.com>
+
+ * ppc-linux-nat.c (supply_gregset, fill_gregset): Change type
+ of first argument from gregset_t to gdb_gregset_t in order
+ to match declarations in gregset.h.
+ (supply_fpregset, fill_fpregset): Change type of first argument
+ from fpregset_t to gdb_fpregset_t in order to match declarations
+ in gregset.h.
+
+2000-09-29 Kevin Buettner <kevinb@redhat.com>
+
+ * procfs.c (proc_iterate_over_mappings, proc_iterate_over_threads,
+ procfs_xfer_memory): Protoize.
+ * ptx4-nat.c (proc_iterate_over_mappings): Protoize.
+
+2000-09-28 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * sol-thread.c (ps_pdmodel): Return PR_MODEL_UNKNOWN instead of
+ PS_ERR if exec_bfd is not yet open.
+
+2000-09-28 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * target.c (target_signal_from_host, do_target_signal_to_host):
+ Add support for Solaris realtime signals.
+
+2000-09-27 Kevin Buettner <kevinb@redhat.com>
+
+ * os9kread.c (os9k_symfile_read, os9k_end_psymtab): Protoize.
+ * osfsolib.c (find_solib): Protoize.
+
+2000-09-25 Kevin Buettner <kevinb@redhat.com>
+
+ * ns32knbsd-nat.c (fetch_core_registers): Protoize.
+ * ocd.c (ocd_xfer_memory): Protoize.
+
+2000-09-25 Andrew Cagney <ac131313@cygnus.com>
+
+ * MAINTAINERS: Add Mark Kettenis to ``Blanket Write Privs'' list.
+
+2000-09-24 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * rs6000-tdep.c (rs6000_pop_frame): Use PC_IN_CALL_DUMMY to test
+ for call dummy instead of accessing stop_stack_dummy, which does
+ not work if we `return' from a stop in a call dummy.
+ (rs6000_gdbarch_init): Use generic_save_dummy_frame_tos for
+ dummy_frame_tos function to make PC_IN_CALL_DUMMY work.
+
+2000-09-23 Kevin Buettner <kevinb@redhat.com>
+
+ * mdebugread.c (mdebug_next_symbol_text): Protoize.
+ * monitor.c (monitor_xfer_memory): Protoize.
+
+2000-09-22 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * i386-linux-nat.c (OLD_CANNOT_FETCH_REGISTER,
+ OLD_CANNOT_FETCH_REGISTER): New definitions for accessible registers
+ when accessing the registers via the U area.
+ (fetch_register, store_register): Use them.
+ (cannot_fetch_register, cannot_store_register): New functions,
+ all registers should be accessible if we have GETREGS support.
+ * config/i386/nm-linux.h: Use cannot_fetch/store_register for
+ CANNOT_FETCH/STORE_REGISTER definitions.
+
+2000-09-06 Fred Fish <fnf@cygnus.com>
+
+ * infttrace.c (update_thread_state_after_attach): Pass address
+ of ttstate_t object, not the object itself.
+
+2000-09-18 Mark Kettenis <kettenis@gnu.org>
+
+ * lin-lwp.c (stop_wait_callback): Remove bogus assertions in the
+ code that deals with exiting/signalled threads. Replace with
+ code similar to what's done in lin_lwp_wait.
+
+2000-09-17 Kevin Buettner <kevinb@redhat.com>
+
+ * ppc-linux-nat.c (fill_gregset, fill_fpregset): New functions.
+ * config/powerpc/linux.mh (NATDEPFILES): Remove linux-thread.o.
+ Add proc-service.o, thread-db.o, and lin-lwp.o.
+ (LOADLIBES): Define.
+ * config/powerpc/nm-linux.h (ATTACH_DETACH, SVR4_SHARED_LIBS):
+ Remove defines which are already present in ../nm-linux.h.
+ (solib.h): Don't include this file; it's already included by
+ ../nm-linux.h.
+ (PREPARE_TO_PROCEED, GET_THREAD_SIGNALS, ATTACH_LWP): Define
+ to use the following lin-lwp.c functions...
+ (lin_lwp_prepare_to_proceed, lin_thread_get_thread_signals,
+ lin_lwp_attach_lwp): Declare.
+
+2000-09-17 Kevin Buettner <kevinb@redhat.com>
+
+ * m88k-nat.c (fetch_inferior_registers): Protoize.
+ * m88k-tdep.c (m88k_skip_prologue): Protoize.
+
+2000-09-15 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * varobj.c (varobj_set_value): Call wrapped version of
+ parse_exp_1() to avoid longjumps.
+
+2000-09-15 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * remote.c (putpkt_binary): Call read_frame, not getpkt. Log message.
+ (read_frame): Do not call error() on communication error when
+ reading checksum, but return failure instead and log message.
+
+2000-09-15 Fernando Nasser <fnasser@cygnus.com>
+
+ * ser-unix.c (do_unix_readchar): Prevent infinite read wait to be
+ interrupted after 32K seconds.
+
+2000-09-15 Kevin Buettner <kevinb@redhat.com>
+
+ * language.c (show_case_command, set_case_command): Protoize.
+ * m3-nat.c (m3_xfer_memory, fetch_thread_info): Protoize.
+
+2000-09-12 Kevin Buettner <kevinb@redhat.com>
+
+ * lin-thread.c (threadlist_iter, get_lwp_from_thread_id,
+ thread_db_xfer_memory): Protoize.
+ * linux-thread.c (iterate_active_threads): Protoize.
+
+2000-09-12 Kevin Buettner <kevinb@redhat.com>
+
+ * objfiles.c (objfile_relocate): Don't assume that offsets
+ associated with one of SECT_OFF_TEXT, SECT_OFF_DATA, or
+ SECT_OFF_BSS will be adequate for relocating all of the
+ sections in an objfile.
+
+2000-09-12 Fernando Nasser <fnasser@cygnus.com>
+
+ * remote-rdi.c (arm_rdi_open): Fix typo in error message.
+
+Wed Sep 13 03:08:32 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-mips.c (mips_expect, mips_getstring, mips_send_packet,
+ mips_send_packet, pmon_insert_breakpoint, send_srec,
+ pmon_check_ack, pmon_check_entry_address,
+ _initialize_remote_mips): Replace the magic two seconds with
+ ``remote_timeout''.
+ (pmon_check_entry_address, pmon_check_total): New functions. Use
+ ``remote_timeout'' instead of magic two seconds.
+ (pmon_end_download): Rewrite. Use pmon_check_entry_address and
+ pmon_check_total.
+
+2000-09-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * MAINTAINERS: Added myself.
+
+2000-09-11 Alexandre Oliva <aoliva@redhat.com>
+
+ * acinclude.m4 (CY_GNU_GETTEXT): Add dummy definition, so that the
+ one brought in by ../bfd/acinclude.m4 prevails.
+ * aclocal.m4, configure: Rebuilt.
+
+2000-09-11 Kevin Buettner <kevinb@redhat.com>
+
+ * configure.in (HAVE_STRUCT_LINK_MAP32): Change test to use
+ AC_TRY_COMPILE instead of AC_TRY_RUN.
+ * configure: Regenerate.
+
+2000-09-11 Kevin Buettner <kevinb@redhat.com>
+
+ * irix4-nat.c (fetch_core_registers): Protoize.
+ * irix5-nat.c (fetch_core_registers, find_solib): Protoize.
+
+2000-09-06 Mark Kettenis <kettenis@gnu.org>
+
+ * lin-lwp.c (normal_mask, blocked_mask): New variables.
+ (lin_lwp_wait): Block SIGCHLD here if it isn't already blocked.
+ (lin_lwp_mourn_inferior): Restore the origional signal mask, and
+ reset the mask of blocked signals.
+ (_initialize_lin_lwp): Don't block SIGCHLD here, but do initialize
+ suspend_mask and blocked_mask. This makes us pass
+ gdb.base/sigall.exp for Linux/x86 now.
+ (lin_thread_get_thread_signals): Treat the LinuxThreads "cancel"
+ signal similarly to SIGCHLD in the generic code. Avoids GDB being
+ terminated by a Real-time signal.
+
+2000-09-08 Kevin Buettner <kevinb@redhat.com>
+
+ * infptrace.c, infttrace.c (child_xfer_memory): Protoize.
+
+2000-09-07 J.T. Conklin <jtc@redback.com>
+
+ * config/i386/nbsd.mt (TDEPFILES): Add i386nbsd-tdep.o.
+ * i386nbsd-nat.c (i386nbsd_use_struct_convention): Moved from here.
+ * i386nbsd-tdep.c (i386nbsd_use_struct_convention): To here.
+ * i386nbsd-tdep.c: New file.
+
+2000-09-07 Kevin Buettner <kevinb@redhat.com>
+
+ * i386mach-nat.c (fetch_inferior_registers, fetch_core_registers):
+ Protoize.
+ * i960-tdep.c (i960_skip_prologue, leafproc_return, mem): Protoize.
+
+Thu Sep 7 21:59:23 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * aclocal.m4: Regenerate.
+ * config.in, configure: Regenerate.
+
+Wed Sep 6 23:15:43 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-rdi.c (voiddummy): Update function signature to match
+ struct Dbg_HostosInterface's reset method.
+ * remote-rdp.c (rdp_step): Fix handle parameter to
+ remote_rdp_insert_breakpoint and remote_rdp_remove_breakpoint.
+
+ * arm-tdep.c (SIGCONTEXT_REGISTER_ADDRESS_P): Provide default
+ definition.
+ (arm_init_extra_frame_info): Use.
+
+2000-09-06 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * m68hc11-tdep.c (m68hc11_store_return_value): Store the value
+ in D and X if it's larger than 16-bits.
+ (m68hc11_extract_return_value): Fix extractions for 1 and 3 bytes
+ return.
+ (m68hc11_push_return_address): Use CALL_DUMMY_ADDRESS for the
+ return address.
+ (m68hc11_use_struct_convention): Check for struct and union.
+ (m68hc11_return_value_on_stack): Use the struct convention.
+ (m68hc11_call_dummy_address): Use the entry point address.
+ (m68hc11_push_arguments): Fix alignment and padding.
+ (m68hc11_stack_align): New function.
+ (m68hc11_gdbarch_init): Register it.
+
+2000-09-06 Scott Bambrough <scottb@netwinder.org>
+
+ * arm-linux-tdep.c (arm_linux_skip_solib_resolver):
+ Removed debug print statement. Removed arm_pc_is_thumb prototype.
+ * config/arm/tm-arm.h (arm_pc_is_thumb, arm_pc_is_thumb_dummy):
+ Move prototypes here from tm-embed.h.
+ * config/arm/tm-embed.h (arm_pc_is_thumb, arm_pc_is_thumb_dummy):
+ Remove prototypes. Moved to tm-arm.h.
+
+2000-09-06 H.J. Lu <hjl@gnu.org>
+
+ * TODO: Add hardware watchpoint problems on x86 OSes for 5.1.
+
+2000-09-06 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-tdep.c (examine_prologue): Add rotating register rename
+ support for the general registers.
+ (ia64_get_saved_register): Add rotating register rename support
+ for the predicate registers and the floating-point registers.
+
+2000-09-05 Kevin Buettner <kevinb@redhat.com>
+
+ * config/arm/tm-linux.h (arm_linux_sigcontext_register_address,
+ arm_linux_in_sigtramp): Declare.
+ (IN_SIGTRAMP, SIGCONTEXT_REGISTER_ADDRESS): Define.
+ * arm-tdep.c (SIGCONTEXT_REGISTER_ADDRESS): Define to be 0
+ if not already defined by tm.h.
+ (arm_scan_prologue): Don't assume that the prologue instructions
+ will be in a contiguous clump.
+ (arm_init_extra_frame_info): Add support for sigtramp frames.
+ (arm_pc_is_thumb, arm_pc_is_thumb_dummy): Change type of
+ `memaddr' from bfd_vma to CORE_ADDR.
+ * arm-linux-tdep.c (gdbcore.h, frame.h): Include.
+ (arm_pc_is_thumb): Declare.
+ (arm_linux_skip_solib_resolver): Fix printf() statement. [Which
+ shouldn't be there anyway.]
+ (ARM_LINUX_SIGRETURN_INSTR, ARM_LINUX_RT_SIGRETURN_INSTR): New
+ defines.
+ (arm_linux_in_sigtramp, arm_linux_sigcontext_register_address):
+ New functions.
+
+2000-09-05 Kevin Buettner <kevinb@redhat.com>
+
+ * i386aix-nat.c (fetch_core_registers): Protoize.
+ * hpux-thread.c (hpux_thread_xfer_memory): Protoize.
+
+2000-09-06 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * m68hc11-tdep.c (m68hc11_frame_chain): Check for pc in call dummy.
+ (m68hc11_guess_from_prologue): 'des' instruction to allocate 1 byte
+ on the stack can appear in the prologue.
+
+2000-09-05 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * sol-thread.c (ps_pdmodel): Protect with an ifdef.
+
+Mon Sep 4 16:21:31 2000 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * gdbarch.sh: Use printf instead of echo.
+ (do_read): During read, pad ``::'' with spaces and then strip out
+ those spaces. Avoid problems with IFS=:.
+
+2000-09-04 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/nm-linux.h: Include <signal.h>.
+
+2000-09-04 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * c-typeprint.c (c_typedef_print): remove (replaced by
+ typedef_print in typeprint.c).
+ * typeprint.c (typedef_print): new function. (old c_typedef_print
+ function with pascal language support added).
+ * value.h (c_printdef_print): removed.
+ (typedef_print): declare.
+ * symtab.c (print_symbol_info): call to c_typedef_print replaced
+ by call to typedef_print.
+
+2000-09-03 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/nm-linux.h (PREPARE_TO_PROCEED, ATTCH_LWP,
+ GET_THREAD_SIGNALS): New defines.
+ * config/i386/linux.mh (NATDEPFILES): Remove lin-thread.o and
+ linux-threads.o. Add proc-service.o, thread-db.o and lin-lwp.o.
+ * proc-service.c: New file.
+ * thread-db.c: New file.
+ * lin-lwp.c: New file.
+
+ * gdb_assert.h: New file.
+
+ * gdb_thread_db.h [HAVE_THREAD_DB_H]: Include <thread_db.h>.
+ [!HAVE_THREAD_DB_H]: Update from current glibc thread_db.h. Deal
+ with absence of <stdint.h> here.
+
+ * gdb_proc_service.h: Add copyright notice.
+ Protect against multiple inclusion.
+ Add fix for broken prfpregset_t here.
+ (struct ps_prochandle): Declare here.
+ [HAVE_PROC_SERVICE_H]: Include <proc_service.h>.
+ [!HAVE_PROC_SERVICE_H]: Include "gregset.h", define prgregset_t
+ and prfpregset_t in terms of gdb_gregset_t and gdb_fpregset_t if
+ necessary.
+ * lin-thread.c: Unconditionally include "gdb_proc_service.h".
+ Remove fix for broken prfpregset_t here.
+ (struct ps_prochandle): Don't declare here.
+
+ * MAINTAINERS: Add myself as threads co-maintainer.
+
+2000-09-01 David Anderson <davea@sgi.com>
+
+ * arch-utils.c arch-utils.h blockframe.c fork-child.c:
+ Corrected comment spelling dependant->dependent.
+ * corelow.c (default_core_sniffer): Corrected comment
+ spelling.
+ * cp-valprint.c (cp_print_value_fields): Corrected
+ comment spelling.
+ * d10v-tdep.c dbxread.c: Corrected comment spelling
+ dependan->dependen.
+ * defs.h: Corrected spelling, meant 64, not 32, in comment.
+ * dst.h eval.c event-loop.c: Corrected comment spelling.
+ * event-top.c gdb-events.sh: Corrected comment spelling.
+ * gdbarch.c: Corrected comment spelling.
+ * gdbarch.h gdbarch.sh: Corrected comment spelling,
+ dependant->dependent.
+ * gdbtypes.c gdbtypes.h: Corrected comment spelling.
+ * infcmd.c infrun.c: Corrected comment spelling.
+ * symfile.c symfile.h target.h: Corrected comment spelling,
+ dependant->dependent.
+ * tracepoint.h: Corrected comment spelling.
+
+2000-09-01 Kevin Buettner <kevinb@redhat.com>
+
+ * hppa-tdep.c (record_text_segment_lowaddr): Protoize.
+ * hppah-nat.c (child_xfer_memory): Protoize.
+
+2000-09-01 Kevin Buettner <kevinb@redhat.com>
+
+ * symtab.c (decode_line_1): Make sure leading character is
+ actually a colon before skipping over leading colons in global
+ namespace specification.
+
+2000-09-01 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * regcache.c (reg_flush_command): New function. Maintainer-mode
+ command, flushes GDB's register cache, for testing purposes.
+
+2000-08-31 J.T. Conklin <jtc@redback.com>
+
+ * dcache.c (dcache_info): Output a cache line's state vector so it
+ lines up under the data vector.
+
+ * dcache.c (dcache_read_line): New function.
+ (dcache_peek_byte): Use it.
+ (dcache_alloc): Return NULL if write of reclaimed cache line fails.
+ (dcache_peek_byte, dcache_poke_byte): Return failure if
+ dcache_alloc() returns a NULL data block pointer.
+ (dcache_xfer_memory): Don't force writeback unless we were writing.
+
+ * monitor.c (monitor_expect): Change places where immediate_quit
+ is set to 1 or 0 to increments and decrements respectively. This
+ allows such changes to nest properly.
+ * ocd.c (ocd_start_remote): Likewise.
+ * remote-adapt.c (expect): Likewise.
+ * remote-array.c (expect): Likewise.
+ * remote-eb.c (expect): Likewise.
+ * remote-e7000.c (e7000_start_remote): Likewise.
+ * remote-mips.c (mips_expect_timeout, mips_getstring): Likewise.
+ * remote-nrom.c (expect): Likewise.
+ * remote-os9k.c (expect): Likewise.
+ * remote-sds.c (sds_start_remote): Likewise.
+ * remote-st.c (expect): Likewise.
+ * remote-utils.c (sr_expect): Likewise.
+ * remote.c (remote_start_remote): Likewise.
+ * tracepoint.c (read_actions): Likewise.
+
+ * remote-mips.c (mips_getstring): Balance changes to immediate_quit.
+
+2000-08-31 David Anderson <davea@sgi.com>
+
+ * MAINTAINERS: Add myself to write-after-approval list.
+
+2000-08-30 Kevin Buettner <kevinb@redhat.com>
+
+ * gnu-nat.c (gnu_xfer_memory): Protoize.
+ * hp-psymtab-read.c (scan_procs, hp_quick_traverse): Protoize.
+
+2000-08-30 Kevin Buettner <kevinb@redhat.com>
+
+ * solib.c (solib_extract_address, LM_ADDR, LM_NEXT, LM_NAME,
+ LM_ADDR, IGNORE_FIRST_LINK_MAP_ENTRY, first_link_map_member,
+ open_symbol_file_object, current_sos): Rename
+ bfd_elf_get_arch_size to bfd_get_arch_size().
+ * sol-thread.c (rw_common, ps_pdmodel): Likewise.
+
+2000-08-30 David Edelsohn <dje@watson.ibm.com>
+
+ Patch applied by Kevin Buettner <kevinb@redhat.com>:
+
+ * rs6000-nat.c (xcoff_relocate_symtab): Pass correct size
+ to xrealloc().
+
+2000-08-29 Michael Snyder <msnyder@seadog.cygnus.com>
+
+ * valops.c (value_cast): Indentation fix-up.
+ * acconfig.h (HAVE_PRGREGSET32_T, HAVE_PRFPREGSET32_T,
+ HAVE_STRUCT_LINK_MAP32): New configure macros.
+ * config.in: Ditto.
+ * configure.in: Test for the above new macros.
+ * breakpoint.c: Update copyright date.
+ * core-sol2.c: Include v9/sys/privregs.h directly to
+ work around a bug in Sun's Solaris 8 header files.
+ (fetch_core_registers): Use the above new configure macros to
+ handle cross-debugging of 32-bit core files on a 64-bit host.
+ * sol-thread.c (ps_pdmodel) New function.
+ (rw_common): For debugging of 32-bit apps on a 64-bit host,
+ truncate addresses to 32 bits.
+ * solib.c (solib_extract_address): Functionize. Make 32/64 aware.
+ (LM_ADDR, LM_NEXT, LM_NAME): Ditto.
+ (IGNORE_FIRST_LINK_MAP): Ditto.
+ (first_link_map_member): Make 32/64 aware.
+ (open_symbol_file_object): Ditto.
+ (current_sos): Ditto.
+
+2000-08-29 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * i386-linux-nat.c (i386_linux_skip_solib_resolver,
+ skip_hurd_resolver, find_minsym_and_objfile): Move these
+ solib functions into i386-linux-tdep.c for cross debugging.
+ * i386-linux-tdep.c: Receive the above functions.
+
+2000-08-29 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * m68hc11-tdep.c (stack_correction): New variable for stack offset
+ correction (1 for 68hc11, 0 for 68hc12).
+ (m68hc11_saved_pc_after_call): Use it.
+ (m68hc11_frame_chain): Likewise.
+ (m68hc11_frame_init_saved_regs): Likewise.
+ (m68hc11_init_extra_frame_info): Likewise.
+ (m68hc11_push_return_address): Likewise.
+ (m68hc11_push_arguments): Struct address must be corrected by
+ applying the stack_correction offset.
+ (m68hc11_store_struct_return): Likewise.
+
+2000-08-28 Kevin Buettner <kevinb@redhat.com>
+
+ * gdbserver/utils.c (error, fatal): Protoize.
+
+2000-08-27 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-linux-nat.c (fetch_inferior_registers): Move call to
+ dummy_sse_values ...
+ (supply_fpregset): ... here.
+
+2000-08-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * pa64solib.c (pa64_solib_load_symbols): Don't use ANOFFSET as an
+ lvalue.
+ * xcoffread.c (xcoff_symfile_offsets): Ditto
+ * somsolib.c (som_solib_section_offsets): Ditto.
+ * somread.c (som_symfile_offsets): Ditto.
+ * rs6000-nat.c (vmap_symtab): Ditto.
+ * remote-vx.c (vx_add_symbols): Ditto.
+ * remote-os9k.c (rombug_wait): Ditto.
+
+2000-08-27 Mark Kettenis <kettenis@gnu.org>
+
+ * gregset.h: Protect against multiple inclusion. Remove some
+ redundant spaces.
+
+Sun Aug 27 00:00:04 2000 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c (dll_symbol_command): Tack a .dll on the end of a
+ supplied argument if it is missing an extension.
+
+2000-08-24 Egor Duda <deo@logos-m.ru>
+
+ * corelow.c: Define O_BINARY if it isn't defined.
+ (core_open): Open core file in binary mode.
+ * config/i386/tm-cygwin.h (child_clear_solibs): Rename from
+ child_clear_solib.
+ * config/i386/cygwin.mh: Add dependency from corelow.o.
+ * win32-nat.c (register_loaded_dll): New function. Add dll to the list
+ of currently loaded dlls.
+ (handle_load_dll): Use register_loaded_dll.
+ (child_solib_add): Distinguish between active process and core targets.
+ (solib_symbols_add): Load symbols from loaded dll.
+ (core_dll_symbols_add): New function. Load symbols from dll referenced
+ in core.
+ (core_section_load_dll_symbols): New function.
+ (dll_code_sections_add): New function.
+ (map_single_dll_code_section): New function.
+ (fetch_elf_core_registers): New function.
+ (_initialize_core_win32): New function.
+
+2000-08-26 Kevin Buettner <kevinb@redhat.com>
+
+ * gdbserver/gdbreplay.c (main): Protoize.
+ * gdbserver/server.c (start_inferior, main): Protoize.
+
+2000-08-26 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * m68hc11-tdep.c (m68hc11_register_names): Update name of registers.
+ (m68hc11_get_register_info): New function.
+ (m68hc11_initialize_register_info): New function to get addresses
+ of soft registers.
+ (m68hc11_which_soft_register): New function.
+ (m68hc11_fetch_pseudo_register, m68hc11_store_pseudo_register):
+ New functions to translate read/write of soft registers into a
+ memory read/write.
+ (m68hc11_guess_from_prologue): Initialize soft register addresses.
+ Use the soft register addresses to guess the prologue.
+ (m68hc11_gdbarch_init): Install the pseudo registers.
+
+ * m68hc11-tdep.c (m68hc11_register_name, m68hc11_breakpoint_from_pc,
+ m68hc11_saved_pc_after_call, m68hc11_frame_saved_pc,
+ m68hc11_frame_args_address, m68hc11_frame_locals_address,
+ m68hc11_guess_from_prologue, m68hc11_push_arguments,
+ m68hc11_call_dummy_address, m68hc11_call_dymmy_address,
+ m68hc11_register_virtual_type, m68hc11_store_struct_return,
+ m68hc11_store_return_value, m68hc11_extract_return_value,
+ m68hc11_use_struct_convention, m68hc11_return_value_on_stack,
+ m68hc11_extract_struct_value_address, m68hc11_push_return_address,
+ m68hc11_register_byte, m68hc11_register_raw_size,
+ m68hc11_gdbarch_init): New functions for multi-arch support.
+ (m68hc11_not_yet): Remove.
+
+Fri Aug 25 16:57:05 2000 David Taylor <taylor@texas.cygnus.com>
+
+ * regcache.c (register_changed): New function.
+ * value.h: Declare it.
+
+Fri Aug 25 12:11:21 2000 David Taylor <taylor@texas.cygnus.com>
+
+ * symtab.c (search_symbols): Fix off by one error in index for
+ initializing variables ourtype, ourtype2, ourtype3, and ourtype4.
+ (symtab_symbol_info): fix similar off by one error.
+
+Fri Aug 25 12:03:15 2000 David Taylor <taylor@texas.cygnus.com>
+
+ * gdbarch.sh (TARGET_ADDR_BIT): New macro for the number
+ of bits in gdb's representation of a target address.
+ * gdbarch.c, gdbarch.h: Regenerated.
+ * gdbtypes.c (build_gdbtypes): Use TARGET_ADDR_BIT instead of
+ TARGET_PTR_BIT when initializing builtin_type_CORE_ADDR.
+ * printcmd.c (print_address_numeric): Use TARGET_ADDR_BIT instead
+ of TARGET_PTR_BIT, because we're printing an address, not a pointer.
+
+2000-08-25 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * Makefile.in: add rules to compile and link pascal specific files.
+ * config/djgpp/fnchange.lst: add substitution for p-exp.tab.c.
+
+2000-08-20 Michael Chastain <chastain@redhat.com>
+
+ * remote.c (read_frame): Handle SERIAL_TIMEOUT while reading
+ checksum.
+
+2000-08-23 Kevin Buettner <kevinb@redhat.com>
+
+ * dstread.c (dst_symfile_offsets): Protoize.
+ * fork-child.c (fork_inferior): Protoize.
+
+2000-08-21 Kevin Buettner <kevinb@redhat.com>
+
+ * dbxread (dbx_symfile_read, process_later): Protoize.
+ * dsrec.c (load_srec): Protoize.
+
+2000-08-18 Andrew Cagney <cagney@ops1.cygnus.com>
+
+ * mips-tdep.c (mips_gdbarch_init): Check arches->gdbarch and not
+ current_gdbarch for a match.
+
+2000-08-18 J.T. Conklin <jtc@redback.com>
+
+ * MAINTAINERS: Add myself as dcache.c maintainer.
+
+ * remote-nindy.c (nindy_load): Invalidate dcache.
+
+ * dcache.c (dcache_invd): Renamed from dcache_flush. The term
+ flush with respect to caches usually implies that data will be
+ written to memory.
+ (dcache_init, dcache_xfer_memory): Updated.
+ * monitor.c (flush_monitor_dcache, monitor_resume, monitor_load):
+ Updated.
+ * ocd.c (ocd_open, ocd_resume, bdm_reset_command): Updated.
+ * remote-bug.c (bug_load, bug_resume): Updated.
+ * remote-nindy.c (nindy_open, nindy_resume): Updated.
+ * remote-sds.c (sds_open, sds_resume): Updated.
+ * remote-utils.c (gr_open): Updated.
+ * remote.c (remote_open_1, remote_resume, remote_async_resume,
+ remote_cisco_open): Updated.
+ * wince.c (child_create_inferior, child_resume): Updated.
+
+ * monitor.c (monitor_open): Free dcache before creating a new one.
+ * dcache.c (dcache_free): New function.
+ * dcache.h (dcache_free): New prototype.
+
+2000-08-18 Andrew Cagney <cagney@ops1.cygnus.com>
+
+ * remote-array.c (array_fetch_register): Pass dummy parameter to
+ array_fetch_registers.
+ (array_store_register): Ditto.
+
+2000-08-16 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * value.h (struct value) <lazy>: Add a comment about its use for
+ watchpoints.
+
+2000-08-12 Kevin Buettner <kevinb@redhat.com>
+
+ * cxux-nat.c (fetch_inferior_registers): Protoize.
+ * d10v-tdep.c (d10v_frame_chain_valid, d10v_extract_return_value):
+ Protoize.
+ * d30v-tdep.c (d30v_frame_chain_valid, d30v_extract_return_value):
+ Protoize.
+
+Fri Aug 11 19:00:51 2000 Andrew Cagney <cagney@makita.cygnus.com>
+
+ * config/mn10300/tm-mn10300.h (REGISTER_SIZE,
+ MAX_REGISTER_RAW_SIZE, REGISTER_VIRTUAL_TYPE, REGISTER_BYTE,
+ REGISTER_VIRTUAL_SIZE, REGISTER_RAW_SIZE): Disable.
+ * mn10300-tdep.c (mn10300_do_registers_info,
+ mn10300_print_register): New functions. Pretty print registers.
+ (mn10300_register_virtual_type, mn10300_register_byte,
+ mn10300_register_virtual_size, mn10300_register_raw_size): New
+ functions.
+ (mn10300_gdbarch_init): Update.
+
+ * mn10300-tdep.c (mn10300_gdbarch_init): Check for mn10300 variant
+ and not mips variant in the info struct.
+
+2000-08-11 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-linux-nat.c [! HAVE_PTRACE_GETFPXREGS] (fetch_fpxregs,
+ store_fpxregs): Return 0.
+
+2000-08-11 Andrew Cagney <cagney@lulu.cygnus.com>
+
+ * regcache.c (GET_SAVED_REGISTER): Restore definition. Was lost
+ as part of 2000-08-10 Andrew Cagney <cagney@ops1.cygnus.com>.
+
+2000-08-11 J.T. Conklin <jtc@redback.com>
+
+ * dcache.c (dcache_info): Don't print cache state if last_cache
+ is NULL.
+
+2000-08-10 Andrew Cagney <cagney@ops1.cygnus.com>
+
+ * config/mn10300/tm-mn10300.h, mn10300-tdep.c
+ (mn10300_push_arguments): Fix function signature to match gdbarch
+ vector.
+ * config/mn10300/tm-mn10300.h (REGISTER_NAME): Delete.
+ * mn10300-tdep.c (struct gdbarch_tdep): Define.
+ (mn10300_generic_register_names, am33_register_names): Convert to
+ functions.
+ (set_machine_hook): Delete.
+ (register_name): New function.
+ (mn10300_register_name): Delete.
+ (mn10300_dump_tdep, mn10300_gdbarch_init): New functions.
+ (_initialize_mn10300_tdep): Call register_gdbarch_init instead of
+ specify_exec_file_hook.
+ (AM33_MODE): Define.
+ (set_movm_offsets): Update.
+
+2000-08-10 Mark Kettenis <kettenis@gnu.org>
+
+ Adapt support for SSE registers in Linux/x86 for Linux 2.4.
+ * i386-linux-nat.c: Various doc fixes. Include "i387-nat.h".
+ (GETFPXREGS_SUPPLIES): Renamed from GETXFPREGS_SUPPLIES.
+ (have_ptrace_getfpxregs): Renamed from have_ptrace_getxfpregs.
+ (convert_to_gregset): Removed. Moved logic to ...
+ (fill_gregset): ... here. Simplified function.
+ (fetch_regs): Use perror_with_name for error reporting.
+ (store_regs): Add `regno' parameter. Use perror_with_name for
+ error reporting. Call fill_gregset instead of convert_to_gregset.
+ (FPREG_ADDR): Remove.
+ (supply_fpregset): Implement by calling i387_supply_fsave.
+ (convert_to_fpregset): Remove.
+ (fill_fpregset): Implement by calling i387_fill_fsave.
+ (fetch_fpregs): Use perror_with_name fro error reporting.
+ (store_fpregs) Add `regno' parameter. Use perror_with_name fro
+ error reporting. Call fill_fpregset instead of
+ convert_to_fpregset.
+ (supply_xfpregset, convert_to_xfpregset): Removed.
+ (supply_fpxregset, fill_fpxregset): New functions.
+ (fetch_fpxregs): Renamed from fetch_xfpregs. Use perror_with_name
+ for error reporting. Call supply_fpxregset instead of
+ supply_xfpregset.
+ (store_xfpregs): Removed.
+ (store_fpxregs): New function.
+ (fetch_inferior_registers): Adjust for xfp -> fpx change. Tweak
+ message in call to internal_error.
+ (store_inferior_registers): Adjust for xfp ->fpx change. Pass
+ REGNO to store_regs, store_fpregs and store_fpxregs.
+ (fetch_core_registers): Adjust for xfp -> fpx change.
+ * acconfig.h (HAVE_PTRACE_GETFPXREGS): Renamed from
+ HAVE_PTRACE_GETXFPREGS.
+ * config.in: Regenerated.
+ * configure.in: Replace check for PTRACE_GETXFPREGS with check for
+ PTRACE_GETFPXREGS. Remove comment about Cygnus SSE extensions.
+ * configure: Regenerated.
+ * config/i386/linux.mh (NATDEPFILES): Add i387-nat.o.
+ * config/i386/tm-linux.h: Base definition of HAVE_SSE_REGS on
+ HAVE_PTRACE_GETFPXREGS instead of HAVE_PTRACE_GETXFPREGS.
+
+2000-08-10 Andrew Cagney <cagney@ops1.cygnus.com>
+
+ * regcache.c (TARGET_WRITE_PC, TARGET_READ_PC, TARGET_READ_FP,
+ TARGET_WRITE_FP, TARGET_READ_SP, TARGET_WRITE_SP): Move
+ initialization from here.
+ * gdbarch.sh: To here.
+ * gdbarch.h, gdbarch.c: Regenerate.
+
+Thu Aug 10 18:58:04 2000 Andrew Cagney <cagney@makita.cygnus.com>
+
+ * defs.h (TARGET_BFD_VMA_BIT, TARGET_SHORT_BIT, TARGET_INT_BIT,
+ TARGET_LONG_BIT, TARGET_LONG_LONG_BIT, TARGET_FLOAT_BIT,
+ TARGET_DOUBLE_BIT, TARGET_LONG_DOUBLE_BIT, TARGET_PTR_BIT): Move
+ non- multi-arch handling from here.
+ * gdbarch.sh: To here. Update printf gdbarch_update_p. Make more
+ portable.
+ * gdbarch.h, gdbarch.c: Regenerate.
+
+2000-08-10 Andrew Cagney <cagney@ops1.cygnus.com>
+
+ * partial-stab.h (DBX_READ): Eliminate redundant check for null
+ ``pst''. Also fixes GCC warning.
+
+2000-08-10 Andrew Cagney <cagney@ops1.cygnus.com>
+
+ * rs6000-nat.c (set_host_arch): Check value returned by
+ gdbarch_update_p.
+ * gdbarch.sh (gdbarch_update_p): Rename gdbarch_update.
+ * gdbarch.h, gdbarch.c: Regenerate
+ * arch-utils.c (set_gdbarch_from_file,
+ initialize_current_architecture, set_endian): Update.
+
+2000-08-10 Jimmy Guo <guo@cup.hp.com>
+
+ * c-lang.c: Set case sensitivity on for c_language_defn,
+ cplus_language_defn, and asm_language_defn.
+ * ch-lang.c: Set case sensitivity on for chill_language_defn.
+ * f-lang.c: Set case sensivitity off for f_language_defn.
+ * jv-lang.c: Set case sensitivity on for java_language_defn.
+ * language.h: Add enum case_mode, case_sensitivity.
+ * language.c: Define case_mode, case_sensitivity. Set case
+ sensitivity on for unknown_language_defn, auto_language_defn,
+ and local_language_defn.
+ (show_case_command,set_case_command,set_case_str): New static func.
+ (set_type_range_case): New static func, replaces set_type_range ().
+ (set_language_command,set_type_command,set_range_command,set_language):
+ Call set_type_range_case ().
+ (language_info): Print case sensitivity setting.
+ (_initialize_language): Add set/show commands for 'case-sensitive'.
+ Set default case mode 'auto'. Set default language 'auto'.
+ * m2-lang.c: Set case sensitivity on for m2_language_defn.
+ * p-lang.c: Set case sensitivity on for pascal_language_defn.
+ * scm-lang.c: Set case sensitivity off for scm_language_defn.
+ * symtab.c (lookup_symbol): Downcase symbol name if case sensivitity
+ is off.
+
+2000-08-10 Jimmy Guo <guo@cup.hp.com>
+
+ * MAINTAINERS: Change my contact email for hp tests maintainership.
+
+Thu Aug 10 15:28:17 2000 Andrew Cagney <cagney@ryobi.cygnus.com>
+
+ * sparc-tdep.c (sparc_init_extra_frame_info): Fix number of
+ arguments to fetch_instruction.
+
+2000-08-10 Kazu Hirata <kazu@hxi.com>
+
+ * hppa_tdep.c: Fix a comment typo.
+ * gdba.el: Likewise.
+
+2000-08-10 Tom Tromey <tromey@cygnus.com>
+
+ * MAINTAINERS: Added myself with write-after-approval access.
+
+2000-08-10 J.T. Conklin <jtc@redback.com>
+
+ * monitor.c (monitor_open): If a dcache has already been created,
+ invalidate it rather than creating another.
+ * ocd.c (ocd_open): Likewise.
+ * remote-nindy.c (nindy_open): Likewise.
+ * remote-sds.c (sds_open): Likewise.
+ * remote-utils.c (gr_open): Likewise.
+ * remote.c (remote_open_1, remote_cisco_open): Likewise.
+
+ * dcache.c (dcache_alloc): Changed to take address of line as an
+ argument, and to invalidate cache line before returning.
+ (dcache_peek_byte): Updated.
+ (dcache_poke_byte): Updated.
+
+2000-08-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Greg McGary <greg@mcgary.org>:
+ * partial-stab.h: Don't crash if pst is null.
+
+2000-08-10 Mark Kettenis <kettenis@gnu.org>
+
+ * i387-nat.h (i387_supply_fsave, i387_fill_fsave): Make extern.
+ (i387_supply_fxsave, i387_fill_fxsave): New prototypes.
+ * i387-nat.c (i387_supply_fsave): Declare `val' as `unsigned int'.
+ (fxsave_offset): New variable.
+ (FXSAVE_ADDR): New macro.
+ (i387_supply_fxsave, i387_fill_fxsave, i387_tag): New functions.
+
+2000-08-08 Tom Tromey <tromey@cygnus.com>
+
+ * jv-valprint.c (java_value_print): Only print non-null Strings.
+
+2000-08-09 Kevin Buettner <kevinb@redhat.com>
+
+ * core-sol2.c (fetch_core_registers): Protoize; add prefatory
+ comment.
+ * corefile.c (specify_exec_file_hook, generic_search): Protoize.
+
+2000-08-09 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * blockframe.c (sigtramp_saved_pc): Use dynamic allocation,
+ since TARGET_PTR_BIT is no longer a constant (MULTI_ARCH).
+ * irix4-nat.c (get_longjmp_target): Ditto.
+ * irix5-nat.c (get_longjmp_target): Ditto.
+ * jv-valprint.c (java_value_print): Ditto.
+ * m3-nat.c (get_cprocs): Ditto.
+ * m68k-tdep.c (get_longjmp_target): Ditto.
+ * mips-nat.c (get_longjmp_target): Ditto.
+ * mipsv4-nat.c(get_longjmp_target): Ditto.
+ * pa64solib.c (read_dynamic_info): Ditto.
+ * solib.c (elf_locate_base): Ditto.
+
+Mon Aug 7 23:21:22 2000 David Taylor <taylor@texas.cygnus.com>
+
+ * TODO: remove build_parse entry.
+
+2000-08-07 Kevin Buettner <kevinb@redhat.com>
+
+ * command.c (add_cmd, add_abbrev_cmd, add_prefix_cmd,
+ add_abbrev_prefix_cmd): Protoize.
+
+2000-08-07 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * objfiles.h (SECT_OFF_BSS): Don't detect invalid sect_index_bss
+ here, let the users of the macro do it.
+ * symtab.h (ANOFFSET): Detect here if the section index is not
+ initialized.
+ * xcoffread.c (find_targ_sec): Don't treat .bss as special,
+ because some objfiles may not have that section at all.
+ * coffread.c (cs_to_section): Ditto.
+ * elfread.c (elf_symtab_read): Detect an uninitialized index
+ value.
+ (elfstab_offset_sections): The macro ANOFFSET cannot be used as an
+ lvalue anymore.
+ * remote.c (get_offsets, remote_cisco_objfile_relocate): Don't use
+ ANOFFSET as an lvalue.
+ * objfiles.c (objfile_relocate, objfile_relocate): Don't use
+ ANOFFSET as an lvalue.
+ * symfile.c (default_symfile_offsets): Don't use ANOFFSET as an
+ lvalue.
+
+Mon Aug 7 10:24:30 2000 David Taylor <taylor@texas.cygnus.com>
+
+ * parse.c (build_parse): don't write off the end of the std_regs
+ array.
+
+2000-05-21 Mark Kettenis <kettenis@gnu.org>
+
+ * solib.c (bfd_lookup_symbol): Fall back on the dynamic symbol
+ table if the symbol couldn't be found in the normal symbol table
+ (i.e. if the shared object in question was stripped).
+
+2000-08-06 Kevin Buettner <kevinb@redhat.com>
+
+ * ch-exp.c (parse_opt_name_string): Protoize. [Thanks to Eli
+ Zaretskii for the prefatory comment.]
+ * core-regset.c (fetch_core_registers): Protoize; revise
+ comment.
+
+2000-08-06 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c: Perform various gcc warning cleanups.
+ (safe_symbol_file_add_cleanup): Reset stdout to saved stdout, not
+ stderr.
+ (dll_symbol_command): Pass OBJF_USERLOADED to safe_symbol_file_add.
+ (get_child_debug_event): Always reset last_sig. Always reset inferior
+ pid appropriately.
+ (do_initial_child_stuff): New function. Called when attaching or
+ starting a new inferior process.
+ (child_attach): Use do_initial_child_stuff.
+ (child_create_inferior): Ditto.
+ * config/i386/cygwin.mh (NAT_FILE): Set to modern location.
+ * config/i386/tm-cygwin.h: Define ATTACH_NO_WAIT.
+
+2000-08-05 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c: (go32_wait): If child_cwd[] is empty, initialize
+ it to GDB's current directory.
+ (go32_create_inferior, init_go32_ops): Initialize child_cwd[] to
+ an empty string, to signal an uninitialized value.
+ From Robert Hoehne <robert.hoehne@gmx.net>.
+
+2000-08-04 Kevin Buettner <kevinb@redhat.com>
+
+ * symtab.h (fixup_psymbol_section): Declare.
+ * symtab.c (fixup_psymbol_section): Make extern.
+ (fixup_section): Fix up section as well as bfd_section.
+ * objfiles.c (objfile_relocate): Call fixup_symbol_section
+ or fixup_psymbol_section before attempting to access
+ the SYMBOL_SECTION component of a symbol or partial symbol.
+
+2000-08-04 Kevin Buettner <kevinb@redhat.com>
+
+ * minsyms.c (build_minimal_symbol_hash_tables): New function.
+ (compact_minimal_symbols): Don't construct hash tables here.
+ (install_minimal_symbols): Instead, construct them here.
+ (msymbols_sort): And rebuild them here too.
+
+ * dwarf2read.c (struct comp_unit_head): Add fields offset_size
+ and initial_length_size. Change type of ``length'' field to long.
+ (read_initial_length, read_offset): New functions.
+ (dwarf2_build_psymtabs_easy): Call read_initial_length() instead
+ of just reading 4 bytes.
+ (read_comp_unit_head): Likewise; also, call read_offset() to
+ fetch the offset instead of just reading 4 bytes.
+ (dwarf_decode_lines): Likewise.
+ (read_comp_unit_head): Fix internal error message so it
+ accurately reflects the function in which the error occurred.
+ (dwarf2_build_psymtabs_hard): Properly account for size of the
+ initial length field in the section.
+ (read_attribute, dwarf2_get_ref_die_offset): Add a case for
+ DW_ORM_ref8.
+ (dwarf2_build_psymtabs_hard, psymtabs_to_symtab_1): Don't
+ assume that the .text section will have index 0 in the
+ section_offsets table.
+
+Fri Aug 4 18:00:41 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (enum Z_packet_type): Define.
+ (remote_protocol_Z): Change to an array of size NR_Z_PACKET_TYPES.
+ (remote_insert_watchpoint): Check watchpoint type.
+ (watchpoint_to_Z_packet): New function.
+ (enum packet_result): Define.
+ (packet_ok): New function. Return enum packet_result.
+ (init_all_packet_configs): New function.
+ (remote_open_1, remote_async_open_1, remote_cisco_open): Use
+ init_all_packet_configs instead of initializing remote_protocol_P,
+ remote_protocol_Z, remote_protocol_binary_download separatly.
+ (remote_remove_hw_breakpoint, remote_insert_hw_breakpoint,
+ remote_remove_watchpoint, remote_insert_watchpoint): Use
+ watchpoint_to_Z_packet and packet_ok. Remove #ifdef
+ TARGET_HAS_HARDWARE_WATCHPOINTS.
+ (set_remote_protocol_Z_software_bp_packet_cmd,
+ show_remote_protocol_Z_software_bp_packet_cmd,
+ set_remote_protocol_Z_hardware_bp_packet_cmd,
+ show_remote_protocol_Z_hardware_bp_packet_cmd,
+ set_remote_protocol_Z_write_wp_packet_cmd,
+ show_remote_protocol_Z_write_wp_packet_cmd,
+ set_remote_protocol_Z_read_wp_packet_cmd,
+ show_remote_protocol_Z_read_wp_packet_cmd,
+ set_remote_protocol_Z_access_wp_packet_cmd,
+ show_remote_protocol_Z_access_wp_packet_cmd): New functions.
+ (remote_Z_packet_packet_detect): New variable.
+ (show_remote_protocol_Z_packet_cmd,
+ set_remote_protocol_Z_packet_cmd): Iterate over all ``Z'' packet
+ variants.
+ (add_packet_config_cmd): Add argument legacy. Change syntax to
+ ``set/show remote FULL_NAME-packet ...'' command. Add ``set/show
+ remote XXX-packet ...'' command using add_alias_cmd when legacy.
+ (set_packet_config_cmd): Delete.
+ (show_remote_cmd): New function.
+
+ * TODO: Update.
+
+Fri Aug 4 14:05:57 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (infodir, SER_HARDWIRE): Fix merge problems from
+ 2000-07-07 Michael Snyder <msnyder@cleaver.cygnus.com>.
+
+Wed Aug 2 21:15:26 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh (EXTRA_STACK_ALIGNMENT_NEEDED): Add.
+ * gdbarch.h, gdbarch.c: Regenerate.
+ * valops.c (hand_function_call): Replace #ifndef
+ NO_EXTRA_ALIGNMENT_NEEDED with if EXTRA_STACK_ALIGNMENT_NEEDED.
+
+ * d10v-tdep.c (d10v_gdbarch_init): Set
+ extra_stack_alignment_needed to 0.
+ * config/d10v/tm-d10v.h (NO_EXTRA_ALIGNMENT_NEEDED): Delete.
+ * config/pa/tm-hppa.h (EXTRA_STACK_ALIGNMENT_NEEDED): Replace
+ NO_EXTRA_ALIGNMENT_NEEDED.
+
+2000-08-03 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * MAINTAINERS (m68hc11): Stephane Carrez is maintainer.
+
+2000-08-03 Kevin Buettner <kevinb@redhat.com>
+
+ * breakpoint.c (bpstat_alloc, map_catch_names,
+ map_breakpoint_numbers): Protoize.
+
+Thu Aug 3 15:02:23 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-mips.c (mips_expect, mips_expect_timeout, common_open,
+ fputs_readable): Make string pointer arguments constant.
+
+Thu Aug 3 18:39:10 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS, TODO: Tweeks.
+
+Thu Aug 3 15:46:43 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO (5.1): Update.
+
+2000-08-02 Kevin Buettner <kevinb@redhat.com>
+
+ * alpha-tdep.c (alpha_extract_return_value): Protoize.
+
+2000-08-02 Jimmy Guo <guo@hpcleara.cup.hp.com>
+
+ * gdbarch.sh: Add print_p field for CALL_DUMMY_BREAKPINT_OFFSET
+ to be printed only if CALL_DUMMY_BREAKPOINT_OFFSET_P.
+
+ * gdbarch.c: Regenerated.
+
+2000-08-02 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * remote-vx.c (vx_add_symbols): Fix typos.
+
+Wed Aug 2 19:15:34 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * arch-utils.h, gdbarch.c (default_register_sim_regno): New
+ function.
+ * gdbarch.sh (REGISTER_SIM_REGNO): Add.
+ * gdbarch.h, gdbarch.c: Regenerate.
+ * remote-sim.c (REGISTER_SIM_REGNO): Delete definition.
+
+ * config/d10v/tm-d10v.h (REGISTER_SIM_REGNO): Delete.
+ * d10v-tdep.c (d10v_gdbarch_init): Update.
+ (struct gdbarch_tdep): Delete member register_sim_regno.
+ (d10v_register_sim_regno): Delete function.
+
+Wed Aug 2 14:46:18 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (enum packet_detect, packet_support_enums,
+ packet_support_auto, packet_enable, packet_disable): Delete.
+ (show_packet_config_cmd, set_packet_config_cmd,
+ init_packet_config): Use add_set_auto_boolean_cmd.
+ * TODO: Update.
+
+Wed Aug 2 13:06:25 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-udi.c (udi_xfer_inferior_memory, udi_files_info,
+ udi_kill): Update function signatures so that match target vector.
+ * MAINTAINERS: Update.
+
+Wed Aug 2 11:04:15 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Updates.
+
+2000-08-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbarch.sh: Multiarch DO_REGISTERS_INFO macro.
+ * gdbarch.h, gdbarch.c: Regenerate.
+ * infcmd.c (do_registers_info): Make not static and
+ unconditionalize.
+ * inferior.h (do_registers_info): Export.
+
+2000-08-01 Kazu Hirata <kazu@hxi.com>
+
+ * MAINTAINERS: Add myself to "Write After Approval" list.
+
+Tue Aug 1 21:02:42 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Update list of target maintainers. List all
+ targets explicitly.
+ (sh): Elena Zannoni is maintainer.
+ (powerpc): Nick Duffek is a maintainer.
+
+Tue Aug 1 17:45:12 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh: Parse and save comments in the function_list. Print
+ them out as part of the header. Convert all function definitions
+ to ISO-C form.
+ * gdbarch.h, gdbarch.c: Regenerate.
+
+Tue Aug 1 14:50:55 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c (get_prompt_1), tracepoint.c (replace_comma): Update
+ function signatures so that they match catch_errors and
+ make_cleanup callbacks.
+
+ * tracepoint.c (encode_actions): Fix arguments passed to
+ stringify_collection_list.
+
+2000-07-31 Kevin Buettner <kevinb@redhat.com>
+
+ * ppc-tdep.h: New file.
+ * Makefile.in (ppc-linux-tdep.o, rs6000-tdep.o): Add ppc-tdep.h
+ as a dependency.
+ * ppc-linux-tdep.c, rs6000-tdep.c (ppc-tdep.h): Include.
+
+ * ppc-linux-tdep.c (ppc_linux_at_sigtramp_return_path): Made static.
+
+ * rs6000-tdep.c (elf-bfd.h): Include.
+ (gdbarch_tdep): Add field osabi to this struct.
+ (rs6000_init_extra_frame_info, rs6000_frame_init_saved_regs,
+ rs6000_frameless_function_invocation, rs6000_frame_saved_pc,
+ rs6000_frame_chain): No longer static.
+ (process_note_abi_tag_sections, get_elfosabi): New static
+ functions.
+ (rs6000_gdbarch_init): Revised to accomodate ELF executables;
+ also use Linux specific methods when the target is Linux.
+
+ * config/powerpc/aix.mt, config/powerpc/cygwin.mt,
+ config/powerpc/macos.mt, config/powerpc/nbsd.mt,
+ config/powerpc/ppc-eabi.mt, config/powerpc/ppc-nw.mt,
+ config/powerpc/ppc-sim.mt, config/powerpc/ppcle-eabi.mt,
+ config/powerpc/ppcle-sim.mt, config/powerpc/solaris.mt,
+ config/powerpc/vxworks.mt, config/rs6000/aix4.mt,
+ config/rs6000/rs6000.mt, config/rs6000/rs6000lynx.mt
+ (TDEPFILES): Add ppc-linux-tdep.o.
+
+ * config/tm-linux.h (SIGCONTEXT_PC_OFFSET, FRAME_SAVED_PC,
+ INIT_EXTRA_FRAME_INFO, FRAMELESS_FUNCTION_INVOCATION,
+ FRAME_INIT_SAVED_REGS, FRAME_CHAIN, PUSH_ARGUMENTS,
+ MEMORY_REMOVE_BREAKPOINT: Removed defines.
+ (ppc_linux_frame_saved_pc, ppc_linux_init_extra_frame_info,
+ ppc_linux_frameless_function_invocation,
+ ppc_linux_frame_init_saved_regs, ppc_linux_frame_chain,
+ ppc_sysv_abi_push_arguments, ppc_linux_memory_remove_breakpoint):
+ Removed declarations.
+ (CANNOT_FETCH_REGISTER, CANNOT_STORE_REGISTER): Disabled.
+
+ * dink32-rom.c (dink32_regnames): Make array size implicit.
+
+ * ppc-bdm.h (ppc-tdep.h): Include.
+
+ * rs6000-tdep.c, ppc-linux-tdep.c, ppc-bdm.h, ppc-tdep.h
+ (GP0_REGNUM, TOC_REGNUM, PS_REGNUM, CR_REGNUM, LR_REGNUM,
+ CTR_REGNUM, XER_REGNUM, MQ_REGNUM): Add PPC_ prefix.
+
+ From Nick Duffek:
+ * ppc-tdep.h (ppc_linux_frame_saved_pc, rs6000_frame_saved_pc):
+ Change return type to CORE_ADDR.
+ * ppc-linux-tdep.c (ppc_linux_frame_saved_pc): Likewise.
+
+2000-07-31 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * sh-tdep.c (sh_push_arguments): Make header match prototype.
+
+ * remote-e7000.c (e7000_start_remote): Use void *, not char * as
+ parameter to avoid compiler warning.
+ (fetch_regs_from_dump): Call get_hex() with the correct number of
+ parameters.
+
+2000-07-31 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/djgpp/fnchange.lst: Add file mappings as per last weekly
+ snapshot.
+
+2000-07-29 Kevin Buettner <kevinb@redhat.com>
+
+ * a29k-tdep.c, a68v-nat.c, abug-rom.c, alpha-nat.c,
+ alpha-tdep.c, annotate.c, arc-tdep.c, arch-utils.c, ax-gdb.c,
+ ax-general.c, blockframe.c, breakpoint.c, buildsym.c,
+ c-lang.c, c-typeprint.c, c-valprint.c, ch-exp.c, ch-lang.c,
+ ch-typeprint.c, ch-valprint.c, cli-out.c, coff-solib.c,
+ coffread.c, command.c, complaints.c, copying.c, core-aout.c,
+ core-regset.c, core-sol2.c, corefile.c, corelow.c,
+ cp-valprint.c, cpu32bug-rom.c, cxux-nat.c, d10v-tdep.c,
+ d30v-tdep.c, dbug-rom.c, dbxread.c, dcache.c, delta68-nat.c,
+ demangle.c, dink32-rom.c, dpx2-nat.c, dsrec.c, dstread.c,
+ dve3900-rom.c, dwarf2read.c, dwarfread.c, elfread.c,
+ environ.c, eval.c, event-top.c, exec.c, expprint.c, f-lang.c,
+ f-typeprint.c, f-valprint.c, findvar.c, fork-child.c,
+ fr30-tdep.c, gdbarch.c, gdbserver/gdbreplay.c,
+ gdbserver/low-hppabsd.c, gdbserver/low-linux.c,
+ gdbserver/low-lynx.c, gdbserver/low-nbsd.c,
+ gdbserver/low-sim.c, gdbserver/low-sparc.c,
+ gdbserver/low-sun3.c, gdbserver/remote-utils.c,
+ gdbserver/utils.c, gdbtypes.c, gnu-nat.c, h8300-tdep.c,
+ h8500-tdep.c, hp-psymtab-read.c, hp-symtab-read.c,
+ hp300ux-nat.c, hppa-tdep.c, hppab-nat.c, hppah-nat.c,
+ hppam3-nat.c, hpread.c, hpux-thread.c, i386-linux-nat.c,
+ i386-stub.c, i386-tdep.c, i386aix-nat.c, i386b-nat.c,
+ i386ly-tdep.c, i386m3-nat.c, i386mach-nat.c, i386nbsd-nat.c,
+ i386v-nat.c, i386v4-nat.c, i387-tdep.c, i960-tdep.c,
+ ia64-linux-nat.c, ia64-tdep.c, infcmd.c, inflow.c,
+ infptrace.c, infrun.c, inftarg.c, infttrace.c, irix4-nat.c,
+ irix5-nat.c, jv-lang.c, jv-typeprint.c, jv-valprint.c,
+ kdb-start.c, kod-cisco.c, kod.c, language.c, lin-thread.c,
+ linux-thread.c, lynx-nat.c, m2-lang.c, m2-typeprint.c,
+ m2-valprint.c, m3-nat.c, m32r-rom.c, m32r-stub.c, m32r-tdep.c,
+ m68hc11-tdep.c, m68k-stub.c, m68k-tdep.c, m68klinux-nat.c,
+ m68knbsd-nat.c, m88k-nat.c, m88k-tdep.c, mac-nat.c,
+ mac-xdep.c, maint.c, mcore-rom.c, mcore-tdep.c, mdebugread.c,
+ mem-break.c, mi/mi-cmds.c, mi/mi-main.c, mi/mi-out.c,
+ mi/mi-parse.c, minsyms.c, mips-nat.c, mips-tdep.c,
+ mipsm3-nat.c, mipsread.c, mipsv4-nat.c, mn10200-tdep.c,
+ mn10300-tdep.c, mon960-rom.c, monitor.c, news-xdep.c,
+ nindy-tdep.c, nlm/gdbserve.c, nlm/i386.c, nlm/ppc.c,
+ nlmread.c, ns32k-tdep.c, ns32km3-nat.c, ns32knbsd-nat.c,
+ objfiles.c, ocd.c, op50-rom.c, os9kread.c, osfsolib.c,
+ p-lang.c, p-typeprint.c, p-valprint.c, pa64solib.c, parse.c,
+ ppc-bdm.c, ppc-linux-nat.c, ppc-linux-tdep.c, ppcbug-rom.c,
+ ppcnbsd-nat.c, printcmd.c, proc-api.c, proc-events.c,
+ proc-flags.c, proc-why.c, procfs.c, ptx4-nat.c,
+ remote-adapt.c, remote-array.c, remote-bug.c, remote-e7000.c,
+ remote-eb.c, remote-es.c, remote-est.c, remote-hms.c,
+ remote-mips.c, remote-mm.c, remote-nindy.c, remote-nrom.c,
+ remote-os9k.c, remote-rdi.c, remote-rdp.c, remote-sds.c,
+ remote-sim.c, remote-st.c, remote-udi.c, remote-utils.c,
+ remote-vx.c, remote-vx29k.c, remote-vx68.c, remote-vx960.c,
+ remote-vxmips.c, remote-vxsparc.c, remote.c, rom68k-rom.c,
+ rs6000-tdep.c, scm-exp.c, scm-lang.c, scm-valprint.c,
+ ser-e7kpc.c, ser-go32.c, ser-mac.c, ser-ocd.c, ser-unix.c,
+ sh-stub.c, sh-tdep.c, sh3-rom.c, sol-thread.c, solib.c,
+ somread.c, somsolib.c, source.c, sparc-nat.c, sparc-stub.c,
+ sparc-tdep.c, sparcl-stub.c, sparcl-tdep.c, sparclet-rom.c,
+ sparclet-stub.c, stabsread.c, stack.c, standalone.c,
+ stop-gdb.c, stuff.c, sun3-nat.c, sun386-nat.c, symfile.c,
+ symm-nat.c, symm-tdep.c, symmisc.c, symtab.c, target.c,
+ thread.c, tic80-tdep.c, top.c, tracepoint.c, tui/tui-file.c,
+ tui/tui.c, tui/tuiLayout.c, tui/tuiRegs.c, tui/tuiStack.c,
+ tui/tuiWin.c, typeprint.c, ui-file.c, ui-out.c, ultra3-nat.c,
+ ultra3-xdep.c, umax-xdep.c, utils.c, v850-tdep.c, v850ice.c,
+ valarith.c, valops.c, valprint.c, values.c, varobj.c,
+ vax-tdep.c, w65-tdep.c, w89k-rom.c, win32-nat.c, wince.c,
+ wrapper.c, xcoffread.c, xcoffsolib.c, xmodem.c, z8k-tdep.c:
+ Convert old-style, pre-ISO function definitions to prototyped
+ form.
+
+2000-07-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * sh-tdep.c (sh_gdbarch_init): For sh4 initialize
+ register_convert_to_raw, register_convert_to_virtual,
+ register_convertible.
+ (sh_sh4_register_convertible): New function.
+ (sh_sh4_register_convert_to_virtual): New function.
+ (sh_sh4_register_convert_to_raw): New function.
+ Include floatformat.h.
+
+Thu Jul 27 14:06:27 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-06-25 Stephane Carrez <Stephane.Carrez@worldnet.fr>:
+ * configure.tgt: Recognize the 68hc11.
+ * m68hc11-tdep.c: New file for 68hc11 target.
+ * config/m68hc11/m68hc11.mt: New file for 68hc11 port.
+
+ * configure.tgt: When 68hc11, set gdb_multi_arch.
+
+Wed Jul 26 17:22:53 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (GDB_MULTI_ARCH): Define from configure.tgt
+ or makefile fragment.
+ * acconfig.h (GDB_MULTI_ARCH): Add.
+ * config.in, configure: Regenerate.
+
+ * gdbarch.sh (GDB_MULTI_ARCH): Delete definition, moved to
+ configure.in and defs.h. Use GDB_MULTI_ARCH_TM,
+ GDB_MULTI_ARCH_PARTIAL and GDB_MULTI_ARCH_PURE in tests.
+ * gdbarch.h, gdbarch.c: Regenerate.
+
+ * defs.h (GDB_MULTI_ARCH_PARTIAL, GDB_MULTI_ARCH_TM, ,
+ GDB_MULTI_ARCH_PURE): Define. Only include "tm.h" when the target
+ is less than pure multi-arch.
+
+2000-07-26 Jimmy Guo <guo@cup.hp.com>
+
+ * config/convex/tm-convex.h: Remove stray control characters.
+ * config/m68k/tm-altos.h: Ditto.
+ * config/tahoe/tm-tahoe.h: Ditto.
+
+2000-07-26 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * sh-tdep.c (sh_sh4_register_name, sh_sh4_register_byte,
+ sh_sh4_register_raw_size, sh_sh4_register_virtual_type,
+ sh_fetch_pseudo_register, sh_store_pseudo_register,
+ sh_do_pseudo_register, sh_gdbarch_init): Fix names for pseudoregs,
+ they should be numbered as drx fvy where x and y are multiples of
+ 2 and 4 respectively.
+
+ * config/sh/tm-sh.h: Fix names of pseudo regs.
+
+2000-07-24 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * config/sh/tm-sh.h (struct gdbarch_tdep): Add sh4 specific
+ pseudo registers.
+ (DO_REGISTERS_INFO): Define.
+
+ * sh-tdep.c (sh_sh4_register_name): New function.
+ (sh_generic_show_regs, sh3_show_regs, sh3e_show_regs,
+ sh3_dsp_show_regs, sh4_show_regs, sh_dsp_show_regs): Update
+ signature.
+ (sh_show_regs_command): New function. Actual function called by
+ the 'regs' command.
+ (sh_register_byte): Rename to...
+ (sh_default_register_byte): ...New function.
+ (sh_sh4_register_byte): New function.
+ (sh_register_raw_size): Rename to...
+ (sh_default_register_raw_size): ...New function.
+ (sh_sh4_register_raw_size): New function.
+ (sh_sh4_register_virtual_type): New function.
+ (sh_sh4_build_float_register_type): New function.
+ (sh_fetch_pseudo_register, sh_store_pseudo_register): New
+ functions.
+ (fv_reg_base_num, dr_reg_base_num): New functions.
+ (do_fv_register_info, do_dr_register_info, sh_do_pseudo_register,
+ sh_do_fp_register, sh_do_register, sh_print_register,
+ sh_do_registers_info): New functions.
+ (sh_gdbarch_init): Initialize sh4 pseudo registers to -1. Update
+ architecture specific parts.
+ (_initialize_sh_tdep): Use sh_show_regs_command for 'regs' command.
+
+2000-07-24 Jim Blandy <jimb@redhat.com>
+
+ * dwarf2read.c (read_structure_scope): Correct overzealous
+ addition of cu_header argument.
+
+Mon Jul 24 07:47:46 2000 Anthony Green <green@redhat.com>
+
+ * TODO: Update. Two of my java patches are in.
+
+2000-07-24 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbarch.sh: Add FETCH_PSEUDO_REGISTER and STORE_PSEUDO_REGISTER
+ to the gdbarch structure.
+ * gdbarch.c: Regenerate.
+ * gdbarch.h: Regenerate.
+ * inferior.h (FETCH_PSEUDO_REGISTER, STORE_PSEUDO_REGISTER):
+ Delete macros.
+ * regcache.c (write_register, read_register, write_register_bytes,
+ write_register_gen, read_register_bytes, read_register_gen):
+ Rename ARCH_FECTH_PSEUDO_REGISTERS to FETCH_PSEUDO_REGISTERS and
+ ARCH_STORE_PSEUDO_REGISTER to STORE_PSEUDO_REGISTER.
+
+2000-07-24 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbarch.sh: Add NUM_PSEUDO_REGS to the gdbarch structure.
+ * gdbarch.c: Regenerate.
+ * gdbarch.h: Regenerate.
+ * inferior.h (NUM_PSEUDO_REGS): Delete macro.
+
+Sun Jul 23 21:40:55 2000 Anthony Green <green@redhat.com>
+
+ * language.c: Include jv-lang.h.
+ (lang_bool_type): Add case for java booleans.
+
+Mon Jul 24 11:23:14 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * dwarf2read.c (address_size): Delete file wide global.
+ (struct comp_unit_head): Add signed_addr_p;
+ (read_comp_unit_head): New function.
+ (psymtab_to_symtab_1, dwarf2_build_psymtabs_hard): Use
+ read_comp_unit_head to parse the debug_info header.
+ (read_address): Add parameters cu_header and bytes_read. When
+ specified, sign extend the address.
+
+ * dwarf2read.c (add_partial_symbol, decode_locdesc,
+ die_containing_type, die_type, dwarf_decode_lines,
+ dwarf2_add_field, dwarf2_add_member_fn,
+ dwarf2_build_psymtabs_hard, dwarf2_const_value, new_symbol,
+ process_die, psymtab_to_symtab_1, read_array_type,
+ read_enumeration, read_attribute, read_common_block,
+ read_comp_unit, read_file_scope, read_full_die, read_func_scope,
+ read_lexical_block_scope, read_partial_die, scan_partial_symbols,
+ read_structure_scope, read_subroutine_type, read_tag_const_type,
+ read_tag_pointer_type, read_tag_ptr_to_member_type,
+ read_tag_reference_type, read_type_die, read_typedef,
+ tag_type_to_type): Pass cu_header parameter.
+
+2000-07-21 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * regcache.c (read_register, read_register_bytes): Fix typos.
+
+2000-07-21 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * thread.c (thread_apply_all_command): Update thread list first.
+ * printcmd.c (printf_command): Guard against 0-length string.
+ * config/i386/tm-i386.h: treat PC and FP as unsigned.
+ (SAVED_PC_AFTER_CALL): Use read_memory_unsigned_integer.
+ (FRAME_SAVED_PC): Ditto.
+ (FRAME_CHAIN): Ditto.
+
+2000-07-20 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * valarith.c (value_sub): Call check_typedef.
+
+2000-07-19 Nicholas Duffek <nsd@redhat.com>
+
+ * thread.c (free_thread): New function.
+ (init_thread_list): Always zero highest_thread_num. Call
+ free_thread() instead of free().
+ (delete_thread): Move thread cleanup code to free_thread().
+
+2000-07-19 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ Multiarch the sh target.
+ * sh-tdep.c:
+ (sh_generic_reg_names, sh_reg_names,sh3_reg_names, sh3e_reg_names,
+ sh_dsp_reg_names, sh3_dsp_reg_names, sh_processor_type_table):
+ Remove.
+ (XMALLOC): Define.
+ (struct frame_extra_info): Define.
+ (sh_register_raw_size, sh_register_virtual_size,
+ sh_register_virtual_type, sh_register_byte, sh_breakpoint_from_pc,
+ sh_frame_saved_pc, sh_skip_prologue,
+ sh_nofp_frame_init_saved_regs, sh_fp_frame_init_saved_regs,
+ sh_extract_struct_value_address, sh_use_struct_convention,
+ sh_store_struct_return, sh_push_arguments, sh_push_return_address,
+ sh_saved_pc_after_call, sh_generic_register_name,
+ sh_sh_register_name, sh_sh3_register_name, sh_sh3e_register_name,
+ sh_sh_dsp_register_name, sh_sh3_dsp_register_name,
+ sh_frame_args_address, sh_frame_locals_address,
+ sh_coerce_float_to_double, sh_default_store_return_value,
+ sh3e_sh4_store_return_value, sh_generic_show_regs,
+ sh3_show_regs,sh3e_show_regs, sh3_dsp_show_regs, sh4_show_regs,
+ sh_dsp_show_regs, sh_register_byte, sh_register_raw_size,
+ sh_register_virtual_size, sh_sh3e_register_virtual_type,
+ sh_default_register_virtual_type, sh_gdbarch_init): New functions.
+ (sh_target_architecture_hook, sh_frame_find_saved_regs,
+ sh_show_regs): Delete functions.
+ (sh_frame_chain, sh_find_callers_reg, sh_init_extra_frame_info,
+ sh_pop_frame, sh_extract_return_value): Update
+
+ * config/sh/tm-sh.h (GDB_MULTI_ARCH): Define to 1.
+ (struct gdbarch_tdep): Define.
+ Remove all unnecessary defines.
+
+ * remote-e7000.c ({PR,GBR,SR,MACL,VBR,MACH}_REGNUM): Define to -1,
+ for h8300 case.
+ (want_sh,want_nopc_sh,want_nopc_sh3): Make nomenclature
+ consistent.
+ (e7000_fetch_registers): Remove ifdef GDB_TARGET_IS_SH, use
+ runtime check instead.
+ (e7000_wait): Ditto.
+
+ * sh3-rom.c (sh3_supply_register): Use gdbarch_tdep to get the SSR
+ and SPC register numbers.
+ (sh3_regnames, sh3e_regnames): Don't specify a size.
+
+ * config/h8300/tm-h8300.h: Add comment.
+
+Wed Jul 19 12:50:16 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * solib.c (elf_locate_base, info_sharedlibrary_command): Rename
+ bfd_elf_get_arch_size to bfd_get_arch_size.
+
+Tue Jul 18 17:13:01 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Richard Henderson <rth@cygnus.com>:
+ * dwarf2read.c (dwarf2_empty_hash_tables): Renamed from
+ dwarf2_empty_die_ref_table; zero dwarf2_cached_types as well.
+ Update all callers.
+
+2000-07-17 Daniel Berlin <dberlin@redhat.com>
+
+ * valops.c (value_struct_elt): Change error message
+
+2000-07-17 matthew green <mrg@redhat.com>
+
+ * config/sparc/nm-nbsd.h (GDB_GREGSET_T, GDB_FPREGSET_T): Define.
+
+Mon Jul 17 13:08:10 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * values.c (value_as_pointer): When VAL is an integer, explictly
+ cast to a pointer before converting to a CORE_ADDR.
+ * gdbtypes.c (build_gdbtypes): For builtin_type_ptr, construct a
+ real void pointer instead of an integer.
+
+2000-07-15 Daniel Berlin <dberlin@redhat.com>
+
+ * valops.c (typecmp): Seperate loop into two, add support for
+ references. This way, we can say a reference to a pointer to a
+ char is compatible with a pointer to a char. Before, this would
+ not be true.
+
+2000-07-14 Nicholas Duffek <nsd@redhat.com>
+
+ * ppcbug-rom.c (ppcbug_regnames[]): Make array size implicit.
+ * rs6000-tdep.c (DEFAULT_LR_SAVE): Move to config/*/tm-*.h.
+ (rs6000_gdbarch_init): Use generic_pc_in_call_dummy instead of
+ rs6000_pc_in_call_dummy.
+ * config/rs6000/tm-rs6000.h (DEFAULT_LR_SAVE): Move here from
+ rs6000-tdep.c.
+ * config/powerpc/tm-ppc-eabi.h: Remove various definitions
+ handled by multi-arched rs6000-tdep.c.
+
+2000-07-14 Nick Clifton <nickc@cygnus.com>
+
+ * config/mcore/tm-mcore.h (SKIP_PROLOGUE): Fix defintion to avoid
+ assignment.
+
+2000-07-13 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * parse.c: Include inferior.h.
+
+2000-07-12 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * regcache.c (registers_changed, registers_fetched): Use
+ ARCH_NUM_REGS directly, eliminating an unnecessary variable.
+
+ This change adds pseudo-register capability to GDB.
+ Pseudo-registers are handled like registers, but they
+ don't come from or live on the target. They may be
+ aliases for an existing register, or they may be computed.
+ * inferior.h (NUM_PSEUDO_REGISTERS): Define default of zero.
+ (ARCH_FETCH_PSEUDO_REGISTERS): Define default of no-op.
+ (ARCH_STORE_PSEUDO_REGISTERS): Define default of no-op.
+ # regcache.c (registers_changed): Mark pseudo-registers
+ invalid, as well as real registers.
+ (registers_fetched): Do not mark pseudo-registers as fetched
+ at the same time as other (real) registers.
+ (read_register_bytes): Fetch pseudo-registers (if any) from
+ the target architecture module instead of from the target.
+ (read_register_gen): Ditto.
+ (read_register): Ditto.
+ (write_register_bytes): Store pseudo-registers (if any) to
+ the target architecture module instead of to the target.
+ (write_register_gen): Ditto.
+ (write_register): Ditto.
+ (build_regcache): Allocate enough register_valid space for
+ pseudo-registers as well as normal (real) ones.
+ * parse.c (target_map_name_to_register): Include pseudo-regs.
+
+Tue Jul 11 19:45:42 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * valops.c (value_cast): Allow cast from INT, ENUM or RANGE to
+ POINTER.
+
+2000-07-11 Scott Bambrough <scottb@netwinder.org>
+
+ * command.c (do_setshow_command): Fix typo in var_auto_boolean
+ case.
+
+Tue Jul 11 20:38:36 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c: General cleanup. Delete all #if 0 code. Convert
+ all old style K&R function definitions to ISO-C.
+ (struct gdbarch_tdep): Add mips_abi_string.
+ (mips_gdbarch_init): Initialize.
+ (mips_dump_tdep): Print mips_abi_string and other values.
+ (mips_push_arguments): Add more detailed tracing.
+
+Tue Jul 11 20:16:09 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (mips32_next_pc, mips16_next_pc,
+ read_next_frame_reg, mips_push_dummy_frame, mips_skip_stub,
+ mips_saved_pc_after_call): Use read_signed_register when
+ extracting register value. Ensures all addresses are sign
+ extended.
+ (mips_read_pc): New function. Return sign extended address.
+ (mips_gdbarch_init): Set gdbarch_read_pc.
+
+Tue Jul 11 19:06:29 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-mips.c (mips_request): Change all arguments to ULONGEST.
+ (mips_exit_debug, mips_resume, mips_initialize, mips_wait,
+ mips_fetch_registers, mips_store_registers, mips_fetch_word):
+ Update.
+ (mips_xfer_memory): When mask_address_p, mask MEMADDR down to just
+ 32 bits.
+ (_initialize_remote_mips): Add ``set mask-address'' command.
+
+ * mips-tdep.c (_initialize_mips_tdep): Replace "set mask-address"
+ with "set mips mask-address". Implement using
+ add_set_auto_boolean_cmd.
+ (struct gdbarch_tdep): Add default_mask_address_p.
+ (mips_mask_address_p, show_mask_address): New functions.
+ (mips_addr_bits_remove): Use mips_mask_address_p() to determine if
+ masking is needed.
+ (mips_gdbarch_init): Set default_mask_address_p to zero.
+ (mips_dump_tdep): Print value of mask_address_p.
+
+Tue Jul 11 18:32:40 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * printcmd.c (print_scalar_formatted): Move masking of 'a' address
+ from here.
+ (print_address_numeric): To here.
+ * TODO: Update.
+
+Tue Jul 11 17:50:31 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * symtab.c: Use paddr_nz() to print addresses.
+
+Tue Jul 11 12:52:31 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * value.h (read_register, read_signed_register): Change return
+ type to ULONGEST.
+ (read_signed_register, read_signed_register_pid): Declare.
+
+ * regcache.c (read_register, read_register_pid): Update.
+ (read_signed_register_pid, read_signed_register): New functions.
+
+Mon Jul 10 18:06:18 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (mips_push_arguments): Always align struct_addr on a
+ 16 byte boundary. Align allocated argument space using
+ MIPS_STACK_ARGSIZE. Reserve space on stack for the struct return
+ and floating-point registers. Use fp_register_arg_p to determine
+ if float_argreg should be aligned.
+
+2000-07-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * config/sh/tm-sh.h (STORE_RETURN_VALUE): Redefine as
+ sh_store_return_value().
+ * sh-tdep.c (sh_store_return_value): New function. Store the
+ value returned by a function into the appropriate register.
+
+2000-07-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * sh-tdep.c (sh_skip_prologue): Before looking at the actual
+ instructions, try to see if the symbol table can be of help, by
+ calling after_prologue(). If this doesn't work, call
+ skip_prologue_hard_way().
+ (skip_prologue_hard_way): Renamed from sh_skip_prologue. Add some
+ more instruction pattern matching for pushing of arguments, and
+ manipulation of r14.
+ (after_prologue): New function. Use symbol table info to determine
+ the end of the prologue, if possible.
+
+2000-07-07 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * findvar.c (_initialize_findvar, build_findvar, write_fp, read_fp,
+ generic_target_write_fp, generic_target_read_fp, write_sp, read_sp,
+ generic_target_write_sp, generic_target_read_sp, write_pc, read_pc,
+ generic_target_write_pc, generic_target_read_pc, write_pc_pid,
+ read_pc_pid, supply_register, write_register_pid, write_register,
+ read_register_pid, read_register, write_register_bytes,
+ read_register_bytes, write_register_gen, read_register_gen,
+ registers_fetched, registers_changed, find_saved_register,
+ read_relative_register_raw_bytes, default_get_saved_register,
+ read_relative_register_raw_bytes_for_frame, get_saved_register):
+ Move from this file into new file regcache.c.
+ (register_valid, registers_pid, registers): Ditto.
+ * regcache.c: New file to hold the register cache.
+ (register_cached): New function to read register_valid array.
+ * value.h (register_cached): Declare.
+ * defs.h (default_get_saved_register): Delete decl of static function.
+ * Makefile.in: Add regcache module.
+
+Mon Jul 10 15:02:35 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-07-05 Pierre Muller <muller@ics.u-strasbg.fr>:
+ * p-typeprint.c (pascal_type_print_method_args): Add braces around
+ isdigit after while keyword.
+
+2000-07-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * TODO: Remove readline 4.1 import item.
+
+2000-07-09 Nick Duffek <nsd@redhat.com>
+
+ * gdbtypes.c (is_ancestor): Infer type equivalence from name
+ equivalence.
+ (rank_one_type): Use strcmp instead of == to compare type names.
+ Don't swap parm with arg when checking TYPE_CODE_REF types.
+ * valops.c (find_overload_match): Fix indentation. Compare
+ parameter rankings to 0..9, 10..99, and 100+ instead of 0, 10,
+ and 100.
+
+2000-07-07 David Edelsohn <edelsohn@gnu.org>
+
+ * xcoffread.c (read_symbol_nvalue): Return CORE_ADDR.
+ * rs6000-tdep.c (rs6000_pop_frame): Make addr CORE_ADDR type.
+
+Fri Jul 7 18:29:51 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/mips/tm-mips.h (IEEE_FLOAT, SKIP_PROLOGUE,
+ SAVED_PC_AFTER_CALL, DECR_PC_AFTER_BREAK, BREAKPOINT_FROM_PC,
+ INNER_THAN): Macros.
+
+ * mips-tdep.c (mips_in_lenient_prologue): Delete function.
+ (mips32_skip_prologue, mips16_skip_prologue, mips_skip_prologue):
+ Remove ``lenient'' argument.
+ (mips_saved_pc_after_call): New function.
+ (mips_gdbarch_init): Initialize gdbarch members inner_than,
+ breakpoint_from_pc, decr_pc_after_break, ieee_float,
+ skip_prologue, saved_pc_after_call.
+
+2000-07-07 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-linux.h: Add longjmp support.
+ (JB_ELEMENT_SIZE, JB_PC): New defines.
+ (GET_LONGJMP_TARGET): Define.
+ (get_longjmp_target): Add prototype.
+
+ * breakpoint.c (bpstat_what): Keep returning
+ BPSTAT_WHAT_SET_LONGJMP_RESUME when hitting multiple longjmp()
+ breakpoints instead of signalling an error by returning
+ BPSTAT_WHAT_STOP_NOISY.
+
+2000-07-06 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * mips-tdep.c: Replace '16' with bfd_mach_mips16 where appropriate.
+
+2000-07-06 Christopher Faylor <cgf@cygnus.com>
+
+ * infcmd.c (attach_command): Move "stop_soon_quietly" setting
+ inside ATTACH_NO_WAIT conditional since we are not about to
+ stop soon if we're not calling wait_for_inferior.
+
+Wed Jul 5 21:06:39 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/i386/fbsd.mh (NATDEPFILES): Keep NATDEPFILES to a single
+ line. configure.in assumes this.
+
+Wed Jul 5 20:48:22 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (SER_HARDWIRE): When go32 or DJGPP, set to
+ ser-go32.c.
+ * configure: Re-generate.
+
+Wed Jul 5 20:28:32 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.h (command_loop_marker), top.c (command_loop_marker):
+ Delete.
+ * event-top.c (command_handler), top.c (simplified_command_loop,
+ command_loop): Use null_cleanup instead of command_loop_marker.
+
+Wed Jul 5 20:09:41 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * event-loop.c: Include either <poll.h> or <sys/poll.h>.
+
+ * configure.in (targ_archs): Check for <poll.h> and <sys/poll.h>.
+ * configure, config.in: Re-generate.
+
+Wed Jul 5 18:10:44 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-06-12 Bill Nottingham <notting@redhat.com>:
+ * Makefile.in: add $(infodir) to FLAGS_TO_PASS
+
+Wed Jul 5 18:03:55 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Updates.
+
+2000-07-05 Mark Kettenis <kettenis@gnu.org>
+
+ * TODO: Update.
+
+2000-07-03 Chris Faylor <cfg@cygnus.com>
+
+ Committed by Elena Zannoni <ezannoni@cygnus.com>
+ * sh-tdep.c (sh_skip_prologue): Change prologue matching for modern
+ compilers.
+ (sh_frame_find_saved_regs): Ditto.
+ (sh_find_callers_reg): Stop if pc is zero.
+
+Sat Jul 1 17:47:08 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ser-unix.c (do_unix_readchar): Revert Tue Mar 28 18:19:50 2000
+ Andrew Cagney <cagney@b1.cygnus.com>. Locks up when no data is
+ pending.
+
+Sat Jul 1 15:40:14 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (SER_HARDWIRE): Restore code to set it by configure.
+
+2000-06-26 Kevin Buettner <kevinb@redhat.com>
+
+ * copying.awk: Eliminate use of PARAMS from this file.
+
+Fri Jun 23 20:47:03 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (mips_push_arguments): Use the variable stack_used_p
+ to determine if any arguments were written to the stack. Do not
+ rely on NUMARG>=8.
+
+Mon Jun 19 11:29:35 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * command.h (add_set_auto_boolean_cmd): Add declaration.
+ (enum var_types): Add var_auto_boolean.
+
+ * command.c (add_set_auto_boolean_cmd): New function.
+ (do_setshow_command): Recognize auto_boolean.
+ (parse_binary_operation): Recognize enable and disable.
+ (parse_auto_binary_operation): Parse auto binary variables.
+
+ * TODO: Update
+
+Fri Jun 23 16:20:21 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (fp_register_arg_p): New function.
+ (mips_push_arguments): Use. Do not pass floating point arguments
+ on in an integer register.
+
+2000-06-21 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * symfile.c (init_filename_language_table): add ".pas", ".p" and ".pp"
+ as pascal source file extensions.
+
+2000-06-19 J.T. Conklin <jtc@redback.com>
+
+ * remote-nindy.c (nindy_fetch_word, nindy_store_word): Removed
+ (nindy_xfer_inferior_memory): Use dcache_xfer_memory() instead of
+ breaking transfer into chunks and using nindy_fetch_word() and
+ nindy_store_word().
+
+ * remote-bug.c (bug_xfer_memory): Use dcache_xfer_memory() instead
+ of breaking transfer into chunks and using gr_fetch_word() and
+ gr_store_word().
+
+ * remote.c (remote_fetch_word, remote_store_word): Removed.
+
+ * remote-utils.h (gr_fetch_word, gr_store_word): Removed.
+ * remote-utils.c (gr_fetch_word, gr_store_word): Removed.
+
+ * dcache.h (dcache_fetch, dcache_poke, dcache_poke_block): Removed.
+ * dcache.c (dcache_fetch, dcache_poke): Removed.
+
+2000-06-16 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * defs.h: define language_pascal in language enumeration.
+ * language.h: define _LANG_pascal macro.
+ * language.c: add language_pascal support in all language dependant
+ functions.
+
+Sun Jun 18 01:01:09 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (mips_debug): New variable.
+ (_initialize_mips_tdep): Add command "set debug mips".
+ (mips_push_arguments): Add code to dump the argument list as it is
+ created.
+
+Sun Jun 18 00:27:15 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (mips_push_arguments): For MIPS_EABI, squeeze a
+ strut containing a floating-point into an FP register.
+
+Sat Jun 17 16:00:56 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-mips.c: Include <ctype.h>
+ (mips_receive_header): Write printable characters to gdb_stdtarg
+ instead of gdb_stdlog. Only count non-printables as invalid.
+ (mips_syn_garbage): Reduce to 10.
+
+Sat Jun 17 15:39:28 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (mips_gdbarch_init): When the object file header
+ specifies EABI64, select EABI64 and not EABI32.
+
+2000-06-16 Nicholas Duffek <nsd@redhat.com>
+
+ * rs6000-tdep.c: Changes throughout for multi-arch 64-bit
+ support. Incorporate most of tm-rs6000.h.
+ (find_toc_address_hook): Rename to rs6000_find_toc_address_hook.
+ (rs6000_set_host_arch_hook): Declare.
+ (read_memory_addr): Define.
+ (pop_frame): Rename to rs6000_pop_frame.
+ (rs6000_pop_frame, rs6000_fix_call_dummy, rs6000_push_arguments,
+ rs6000_frame_saved_pc, rs6000_frame_chain): Remove non-generic
+ dummy frame handling.
+ (branch_dest, rs6000_pop_frame, rs6000_skip_trampoline_code,
+ rs6000_frame_saved_pc, frame_get_saved_regs,
+ frame_initial_stack_address, rs6000_frame_chain,
+ rs6000_convert_from_func_ptr_addr): Call read_memory_addr instead
+ of read_memory_integer.
+ (branch_dest, rs6000_pop_frame, rs6000_push_arguments,
+ rs6000_skip_trampoline_code, rs6000_frame_saved_pc,
+ frame_get_saved_regs, frame_initial_stack_address,
+ rs6000_frame_chain): Replace 4 with TDEP->wordsize.
+ (skip_prologue): Recognize some 64-bit stack adjustments.
+ (push_dummy_frame, pop_dummy_frame, set_processor,
+ show_processor): Delete.
+ (frame_get_saved_regs): Manipulate saved register addresses using
+ CORE_ADDR instead of int.
+ (rs6000_create_inferior): New function.
+ (register_names_*[]): Change to struct reg registers_*[].
+ (variants[]): Assimilate into multi-arch approach.
+ (register_names_*[], variants[]): Refer to pre-PowerPC
+ architectures as POWER instead of RS6000.
+ * rs6000-nat.c: Ubiquitous changes for 64-bit support.
+ (vmap_secs, xcoff_relocate_symtab): Cast addresses
+ to unsigned long to avoid sign-extension errors.
+ (set_host_arch): New function.
+ (xcoff_relocate_symtab): Try disabling usleep(36000) workaround.
+ (rs6000_core_fns): Use new bfd_target_xcoff_flavour.
+ (_initialize_core_rs6000): Initialize rs6000_set_host_arch_hook.
+ * symfile.c (find_sym_fns): Remove special xcoff kludge.
+ * xcoffread.c (secnum_to_bfd_section): Initialize args.objfile.
+ (process_linenos): Query line struct size from coff
+ backend instead of using compile-time constant.
+ (enter_line_range): Likewise.
+ (read_xcoff_symtab): Pass "XCOFF64" instead of "XCOFF" to
+ record_debugformat() if appropriate.
+ (process_xcoff_symbol): Access symbol addresses using
+ SYMBOL_VALUE_ADDRESS instead of SYMBOL_VALUE.
+ (read_symbol_lineno): Retrieve XCOFF64 symbol names from strtbl.
+ (scan_xcoff_symtab): Likewise. Query syment struct size from
+ coff backend instead of using compile-time constant.
+ (xcoff_sym_fns): Set flavour to bfd_target_xcoff_flavour.
+ * Makefile.in (INTERNAL_LDFLAGS): Add $(MH_LDFLAGS) to list of flags
+ that this Makefile variable get set to. (From Kevin Buettner.)
+ * config/powerpc/aix.mh (MH_LDFLAGS): Add linker flags so that
+ the TOC doesn't overflow. (From Kevin Buettner.)
+ * config/powerpc/tm-ppc-aix.h: Move config decisions to
+ multi-arched rs6000-tdep.c.
+ * config/rs6000/tm-rs6000.h: Likewise.
+ (GDB_MULTI_ARCH): Define.
+ (skip_trampoline_code): Rename to rs6000_skip_trampoline_code.
+ (is_magic_function_pointer): Replace with
+ rs6000_convert_from_func_ptr_addr.
+ (TARGET_CREATE_INFERIOR_HOOK): Define.
+ (find_toc_address_hook): Rename to rs6000_find_toc_address_hook.
+ (rs6000_set_host_arch_hook): Declare.
+ * config/rs6000/nm-rs6000.h (CHILD_XFER_MEMORY): Define.
+
+2000-06-15 Kevin Buettner <kevinb@redhat.com>
+
+ * v850ice.c: Eliminate use of PARAMS from this file.
+
+2000-06-15 Michael Snyder <msnyder@cygnus.com>
+
+ * valops.c (value_cast): Break up long lines.
+ * utils.c: Fix comment typo.
+
+2000-06-14 Jim Blandy <jimb@redhat.com>
+
+ * dwarf2read.c (dump_die): Use the proper printf format for
+ printing DW_UNSND values; they're longs now.
+
+ * dwarf2read.c (dump_die): We can read DW_FORM_data8 now, on
+ at least some platforms, so print it out too.
+
+2000-06-14 James E. Wilson <wilson@bletchleypark.cygnus.com>
+
+ * dwarf2read.c (struct attribute): Change unsnd and snd field types
+ to long.
+ (read_8_bytes): Change return type to long.
+ (read_unsigned_leb128): Change return type to long. Change type of
+ local result to long. Cast argument of left shift to long.
+ (read_signed_leb128): Likewise.
+
+2000-06-14 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ Add support for Pascal language. Part 1: new files.
+ * p-exp.y, p-lang.c, p-lang.h, p-typeprint.c, p-valprint.c: New files.
+
+2000-06-13 Kevin Buettner <kevinb@redhat.com>
+
+ * ser-ocd.c, symtab.c: Eliminate use of PARAMS from these files.
+
+Tue Jun 13 09:21:23 2000 Jeffrey A Law (law@cygnus.com)
+
+ * configure.host (hppa*64*): Renamed from hppa2.0w per
+ gcc/binutils changes.
+ * configure.tgt: Similarly.
+
+2000-06-12 Bill Nottingham <notting@redhat.com>
+
+ Patch applied by Kevin Buettner <kevinb@redhat.com>:
+
+ * ia64-linux-nat.c, gdbserver/low-linux.c (u_offsets): PT_CR_IFS
+ is deprecated. Use PT_CFM instead.
+
+2000-06-12 Michael Snyder <msnyder@cygnus.com>
+
+ * breakpoint.c (breakpoint_thread_match): Fix comment.
+
+2000-06-12 Fernando Nasser <fnasser@cygnus.com>
+
+ * valops.c (value_assign): Adjust the length to take into
+ consideration that we are not starting from the beginning.
+
+2000-06-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * symfile.c (add_symbol_file_command): Properly reformat "else if"
+ code.
+ * coffread.c (coff_symtab_read): Ditto.
+
+Mon Jun 12 15:24:04 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (SER_HARDWIRE): Set using autoconf.
+ * configure.in (SER_HARDWIRE): Define, add ser-tcp.o.
+ * configure: Re-generate.
+
+ * config/i386/go32.mh (SER_HARDWIRE): Delete. Handled by
+ configure.in.
+ * config/sparc/sun4sol2.mh, config/sparc/sun4os4.mh,
+ config/sparc/sparclynx.mh, config/sparc/nbsdelf.mh,
+ config/sparc/nbsd.mh, config/sparc/linux.mh,
+ config/rs6000/rs6000lynx.mh, config/powerpc/solaris.mh,
+ config/powerpc/nbsd.mh, config/powerpc/linux.mh,
+ config/powerpc/cygwin.mh, config/pa/hpux11w.mh,
+ config/pa/hpux11.mh, config/pa/hpux1020.mh, config/pa/hppaosf.mh,
+ config/pa/hppahpux.mh, config/pa/hppabsd.mh, config/ns32k/nbsd.mh,
+ config/mips/irix5.mh, config/mips/irix4.mh, config/m68k/nbsd.mh,
+ config/m68k/m68klynx.mh, config/m68k/linux.mh,
+ config/i386/nbsdelf.mh, config/i386/nbsd.mh, config/i386/linux.mh,
+ config/i386/i386sco5.mh, config/i386/i386lynx.mh,
+ config/i386/i386dgux.mh, config/i386/fbsd.mh,
+ config/i386/cygwin.mh, config/arm/linux.mh, config/alpha/fbsd.mh,
+ config/alpha/alpha-osf3.mh, config/alpha/alpha-linux.mh: Remove
+ ser-tcp.o from XDEPFILES.
+ * config/ia64/linux.mh: Ditto.
+
+ * TODO: Update.
+
+Mon Jun 12 14:26:02 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (GDB_TARGET_IS_MIPS64): Define.
+ (struct gdbarch_tdep): Add gdb_target_is_mips64.
+ (mips_addr_bits_remove): Update.
+ (mips_gdbarch_init): Initialize.
+
+ * config/mips/tm-mips64.h (GDB_TARGET_IS_MIPS64,
+ GDB_TARGET_IS_MIPS64): Delete.
+
+Mon Jun 12 12:17:20 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c: Include "symcat.h".
+ (mips_dump_tdep): Print all known but not yet multi-arched values.
+
+2000-06-12 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-i386.h: Add forward declaration of `struct value'.
+ (FIX_CALL_DUMMY): Redefined to call i386_fix_call_dummy.
+ (i386_fix_call_dummy): Add prototype.
+ * i386-tdep.c (i386_fix_call_dummy): New function based on the
+ code from the old FIX_CALL_DUMMY macro.
+
+2000-06-12 Kevin Buettner <kevinb@redhat.com>
+
+ * procfs.c, remote.c: Eliminate use of PARAMS from these files.
+
+Mon Jun 12 10:21:24 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh (gdbarch_dump): When non multi-arch skip macros that
+ return void.
+
+Sun Jun 11 12:06:21 2000 Christopher Faylor <cgf@cygnus.com>
+
+ * exec.c (exec_file_attach): Add .exe extension when __CYGWIN__.
+
+Sat Jun 10 22:31:46 2000 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c (safe_symbol_file_add_args): Store old gdb_stderr and
+ gdb_stdout here.
+ (safe_symbol_file_add_stub): Redirect gdb_stdout as well as stderr.
+ (safe_symbol_file_add_cleanup): Restore gdb_stdout.
+ (info_dll_command): Use the pager for displaying DLLs since there are
+ often quite a few.
+
+Sun Jun 11 11:34:05 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Sat Jun 10 17:54:04 2000 Hans-Peter Nilsson <hp@axis.com>:
+ * configure.in (targ_archs): Clear out secondary components.
+ * configure: Regenerate.
+
+Fri Jun 9 15:06:37 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh (struct gdbarch): Add member dump_tdep.
+ (struct gdbarch_registration): Ditto.
+ (gdbarch_dump): Add ui_file and gdbarch arguments. Add support
+ for external dump functions. Dump the macro value. Call target
+ dump routine.
+ (gdbarch_register): New function.
+ (gdbarch_registrary): Replace gdbarch_init_registrary.
+ * gdbarch.h, gdbarch.c: Re-generate.
+ * arch-utils.c (set_arch): Update.
+
+ * mips-tdep.c (mips_dump_tdep): New function. Move dump code here.
+ (mips_gdbarch_init): From here.
+
+ * maint.c (maintenance_print_architecture): New function.
+ (_initialize_maint_cmds): Add command ``maintenance print
+ architecture''.
+
+2000-06-08 Kevin Buettner <kevinb@redhat.com>
+
+ * command.h, monitor.h: Eliminate use of PARAMS from these
+ files.
+
+2000-06-08 Fernando Nasser <fnasser@cygnus.com>
+
+ * config/i386/tm-embed.h: New file. Specific for embedded targets
+ like i386-elf, i386-coff and i386-aout.
+ * config/i386/embed.mt (): Specify tm-embed.h instead of the System V
+ header file.
+
+2000-06-08 Fernando Nasser <fnasser@cygnus.com>
+
+ * MAINTAINERS: Add myself to gdbtk list.
+
+2000-06-08 Kevin Buettner <kevinb@redhat.com>
+
+ * config/ia64/nm-linux.h (U_REGS_OFFSET): Define.
+
+2000-06-08 Fernando Nasser <fnasser@cygnus.com>
+
+ * configure.in: Replace misplaced CONFIG_ADD by the correct
+ CONFIG_CLEAN.
+ * configure, config.in: Regenerate.
+
+2000-06-08 Fernando Nasser <fnasser@cygnus.com>
+
+ * values.c (value_primitive_field): Copy VALUE_REGNO as well.
+ With typed registers we may have the location information in this field,
+ in addition to VALUE_ADDRESS (which was already being copied).
+
+Thu Jun 8 15:26:44 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/mips/tm-mips.h (GDB_MULTI_ARCH): Define as 1.
+ (CALL_DUMMY, TARGET_BYTE_ORDER_SELECTABLE_P,
+ COERCE_FLOAT_TO_DOUBLE): Delete.
+ * config/mips/tm-vr5000el.h, config/mips/tm-vr5000.h,
+ config/mips/tm-vr4xxxel.h, config/mips/tm-vr4xxx.h,
+ config/mips/tm-vr4100.h, config/mips/tm-tx39l.h
+ config/mips/tm-tx39.h, config/mips/tm-irix5.h: Delete
+ GDB_MULTI_ARCH.
+
+ * config/mips/tm-mips64.h (TARGET_LONG_BIT, TARGET_LONG_LONG_BIT,
+ TARGET_PTR_BIT): Delete definitions.
+ * config/mips/tm-vr5000el.h, config/mips/tm-vr5000.h,
+ config/mips/tm-tx39l.h, config/mips/tm-vr4100.h,
+ config/mips/tm-tx39.h: Delete definition of MIPS_EABI.
+ * mips-tdep.c (mips_gdbarch_init): Use the ISA to determine the
+ ABI. If all else fails, assume O32.
+
+ * TODO, NEWS: Update. Mention MIPS is multi-arch.
+
+Thu Jun 8 14:23:12 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/mips/tm-vr4xxxel.h, config/mips/tm-vr4xxx.h,
+ config/mips/tm-vr4100.h, config/mips/tm-tx39l.h,
+ config/mips/tm-tx39.h: Delete definition of
+ MIPS_DEFAULT_FPU_TYPE. Enable multi-arch.
+ * mips-tdep.c: (mips_gdbarch_init): The bfd_mach_mips3900 has no
+ FPU. bfd_mach_mips4650 FPU is single precision.
+
+ * config/mips/tm-mips.h (MIPS_FPU_SINGLE_REGSIZE):
+ (MIPS_FPU_DOUBLE_REGSIZE): Move from here.
+ * mips-tdep.c: To here. Change to an enum.
+
+Wed Jun 7 18:27:51 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (DEFAULT_BFD_ARCH, DEFAULT_BFD_VEC): Use config.bfd
+ to determine the default architecture / target.
+ * acconfig (DEFAULT_BFD_ARCH, DEFAULT_BFD_VEC): Add.
+ * configure, config.in: Regenerate.
+
+ * arch-utils.c (set_endian): Better separate multi-arch and non-
+ multi-arch cases.
+ (set_endian_from_file): Call internal_error when multi-arch.
+ (initialize_current_architecture): Rewrite logic selecting a byte
+ order. Use DEFAULT_BFD_ARCH DEFAULT_BFD_VEC.
+ (version.h): Include.
+
+ * config/mips/tm-mips.h, config/mips/tm-bigmips64.h,
+ config/mips/tm-bigmips.h: Delete definition of
+ TARGET_BYTE_ORDER_DEFAULT.
+
+Thu Jun 8 11:41:41 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * infrun.c (follow_inferior_fork): Bad merge from below. Compare
+ strings using follow_fork_mode_ask and not "ask".
+
+Wed Jun 7 15:13:04 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * command.h (add_set_enum_cmd): Make ``enumlist'' and ``var''
+ constant char pointers.
+ (complete_on_enum): Change ``enumlist'' to a constant char
+ pointer.
+ (struct cmd_list_element): Ditto for member ``enums''.
+ * command.c (complete_on_enum, add_set_enum_cmd,
+ do_setshow_command): Update.
+
+ * infrun.c (follow_fork_mode_ask, follow_fork_mode_parent,
+ follow_fork_mode_both, follow_fork_mode_child): New. Use to
+ construct the follow_fork_mode_kind_names.
+ (set_follow_fork_mode_command): Delete function.
+ (_initialize_infrun): Update.
+ (follow_inferior_fork): Do not strdup follow_fork_mode_string.
+ Use follow_fork_mode_* variables directly instead. Call
+ internal_error instead of error when unimplemented "ask" mode.
+
+ * infrun.c (scheduler_enums, scheduler_mode, schedlock_off,
+ schedlock_on, schedlock_step): Update.
+ * serial.c (serial_logbase, logbase_hex, logbase_octal,
+ logbase_ascii, logbase_enums): Update.
+ * remote.c (packet_support_enums, packet_support_auto,
+ packet_enable, packet_disable, struct packet_config): Update.
+ * arch-utils.c (initialize_current_architecture,
+ set_architecture_string): Update.
+ (endian_big, endian_little, endian_auto, endian_enum,
+ set_endian_string): Update.
+ * i386-tdep.c (valid_flavors, att_flavor, intel_flavor,
+ disassembly_flavor): Update.
+ * mips-tdep.c (size_enums, size_64, size_32, size_auto,
+ mips_stack_argsize_string, mips_saved_regsize_string): Update.
+ * arm-tdep.c (disassembly_flavor, valid_flavors): Update.
+ (_initialize_arm_tdep): Ditto.
+
+ * TODO: Update.
+
+Mon Jun 5 18:44:14 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * thread.c (make_cleanup_restore_current_thread,
+ do_restore_current_thread_cleanup): New functions.
+ (thread_apply_all_command, thread_apply_command): Use. Call
+ do_cleanups when finished.
+
+ * defs.h (make_cleanup_func): Delete typedef.
+ * TODO: Update.
+
+Wed Jun 7 11:34:54 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * arch-utils.c (target_byte_order, target_byte_order_auto,
+ show_endian, set_endian, set_endian_big, set_endian_little,
+ set_endian_auto, set_endian_from_file, enum set_arch,
+ target_architecture_auto, set_architecture_string,
+ target_architecture_hook, target_architecture, arch_ok, set_arch,
+ set_architecture_from_arch_mach, set_architecture_from_file,
+ show_architecture, set_architecture, info_architecture,
+ set_gdbarch_from_file, initialize_current_architecture): Copy from
+ gdbarch.c. Rewrite ``set architecture'' and ``set endian''
+ commands to use enums.
+ (_initialize_gdbarch_utils): Fix name.
+ * arch-utils.h (set_architecture_from_arch_mach,
+ target_architecture_hook): Copy from gdbarch.h.
+ * gdbarch.sh: Update.
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+ * TODO: Update.
+
+ * v850-tdep.c, sh3-rom.c, sh-tdep.c, i386-tdep.c: Include
+ "arch-utils.h".
+ * Makefile.in (v850-tdep.o): Specify dependencies.
+ (i386-tdep.o, sh3-rom.o, sh-tdep.o): Add arch-utils.h to
+ dependency list.
+
+2000-06-06 Michael Snyder <msnyder@cygnus.com>
+
+ * configure.in: Enable autoconf to find curses.h on Solaris 2.8.
+ * configure: Regenerate.
+
+Tue Jun 6 21:14:47 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * command.c (do_setshow_command): Accept an enum option immediatly
+ when it is an exact match.
+
+Tue Jun 6 16:46:37 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/mips/tm-vr5000el.h, config/mips/tm-vr5000.h,
+ config/mips/tm-vr4xxxel.h, config/mips/tm-vr4xxx.h,
+ config/mips/tm-vr4300el.h, config/mips/tm-vr4100.h,
+ config/mips/tm-vr4300.h, config/mips/tm-tx39l.h,
+ config/mips/tm-tx39.h, config/mips/tm-embedl64.h,
+ config/mips/tm-embedl.h, config/mips/tm-embed64.h,
+ config/mips/tm-embed.h: Delete TARGET_BYTE_ORDER_SELECTABLE_P.
+
+ * tm-mips.h (TARGET_BYTE_ORDER_SELECTABLE_P): Define as 1.
+
+Tue Jun 6 16:21:14 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh (generic_register_convertible_not,
+ frame_num_args_unknown): Move from here.
+ * arch-utils.c (generic_register_convertible_not,
+ frame_num_args_unknown): To here.
+ * arch-utils.h (frame_num_args_unknown): Add declaration.
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+Tue Jun 6 15:07:08 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-mips.c (mips_open): Select the default monitor prompt
+ based on the target ISA.
+
+ * config/mips/tm-vr4100.h (TARGET_MONITOR_PROMPT),
+ config/mips/tm-vr4300el.h (TARGET_MONITOR_PROMPT),
+ config/mips/tm-vr4300.h (TARGET_MONITOR_PROMPT),
+ config/mips/tm-vr4xxx.h (TARGET_MONITOR_PROMPT),
+ config/mips/tm-vr4xxxel.h (TARGET_MONITOR_PROMPT),
+ config/mips/tm-vr5000el.h (TARGET_MONITOR_PROMPT),
+ config/mips/tm-vr5000.h (TARGET_MONITOR_PROMPT),
+ config/mips/tm-mips.h (TARGET_MONITOR_PROMPT): Delete macro.
+
+2000-06-05 Daniel Berlin <dan@cgsoftware.com>
+
+ * c-exp.y (yylex): template handling fixes.
+
+2000-06-03 Daniel Berlin <dan@cgsoftware.com>
+
+ * symtab.h (VTBL_PREFIX_P): Add newer g++ vtbl prefix to prefix
+ list.
+
+ * symtab.c (lookup_partial_symbol): Change to stop forcing linear
+ searches on C++ when we fail the binary search, by doing the
+ binary search right.
+
+2000-05-30 Daniel Berlin <dan@cgsoftware.com>
+
+ * buildsym.c (hashname): Change to use hash function from bcache.c/.h
+
+ * bcache.c (hash): Change to newer hash function.
+
+ * bcache.h (hash): Prototype for hash function
+
+ * dwarf2read.c (TYPE_HASH_SIZE): New define for controlling size
+ of type hash.
+ (dwarf2_cached_types): New variable that is the cached types.
+ (tag_type_to_type): Do the actual caching of types here.
+
+2000-06-05 Mark Kettenis <kettenis@gnu.org>
+
+ * acconfig.h, configure.in, i386bsd.c (HAVE_STRUCT_REG_R_FS):
+ Renamed from HAVE_R_FS.
+ (HAVE_STRUCT_REG_GS): Renamed from HAVE_R_GS.
+ * configure, config.in: Regenerated.
+
+Sun Jun 4 14:00:01 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Update. Mention GNU/Linux/SPARC problems.
+
+Wed May 31 21:41:37 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh (POINTER_TO_ADDRESS, ADDRESS_TO_POINTER): Change buf
+ to a void pointer. Update initial values.
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+ * findvar.c (address_to_signed_pointer,
+ signed_pointer_to_address): New functions.
+ * inferior.h (signed_pointer_to_address,
+ signed_address_to_pointer): Declare.
+
+ * inferior.h, findvar.c (unsigned_pointer_to_address,
+ address_to_unsigned_pointer): Rename generic_address_to_pointer
+ and generic_pointer_to_address. Update signatures to match
+ gdbarch changes.
+
+ * config/mips/tm-mips.h (POINTER_TO_ADDRESS, ADDRESS_TO_POINTER):
+ Define. MIPS has signed pointers.
+
+ * defs.h, utils.c (host_pointer_to_address,
+ address_to_host_pointer): New functions.
+ * irix5-nat.c (next_link_map_member, first_link_map_member),
+ procfs.c (proc_set_watchpoint, proc_iterate_over_mappings): Use.
+
+ * irix5-nat.c (solib_map_sections, symbol_add_stub): Change
+ function signature to match catch_errors_ftype.
+
+ * TODO: Update. GDB builds using the IRIX native compiler.
+
+Sat Jun 3 20:43:59 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (strsignal, safe_strsignal): Delete declarations.
+ * utils.c (safe_strsignal): Delete.
+ * corelow.c (core_open): Replace save_strsignal with
+ target_signal_to_string + target_signal_from_host.
+ * TODO: Document problems with target_signal_from_host.
+
+2000-06-03 Kevin Buettner <kevinb@redhat.com>
+
+ * annotate.c, annotate.h, breakpoint.c, command.c, command.h,
+ config/rs6000/tm-rs6000.h, corefile.c, d10v-tdep.c,
+ d30v-tdep.c, dbxread.c, dcache.c, dcache.h, dsrec.c,
+ dve3900-rom.c, exec.c, fork-child.c, gdbcore.h, hpux-thread.c,
+ language.h, linux-thread.c, mdebugread.c, monitor.h, ocd.c,
+ procfs.c, ptx4-nat.c, remote-sim.c, remote-utils.h, remote.c,
+ rs6000-tdep.c, ser-ocd.c, sol-thread.c, sparcl-tdep.c,
+ stabsread.h, stack.c, symfile.c, symfile.h, symtab.h,
+ target.c, target.h, top.c, tracepoint.c, tracepoint.h,
+ tui/tui.h, tui/tuiIO.c, utils.c, v850ice.c, varobj.c,
+ win32-nat.c, wince.c, xcoffsolib.c, xcoffsolib.h: Eliminate
+ PARAMS from function pointer declarations.
+
+2000-06-03 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c (safe_symbol_file_add_cleanup): Ensure that gdb_stderr is
+ flushed before deleting and restoring it.
+ (safe_symbol_file_add): Ensure that gdb_stderr is flushed before
+ reassigning it.
+ (handle_load_dll): Split into two functions so that WFI can handle
+ shared library events.
+ (child_solib_loaded_library_pathname): New function.
+ (child_clear_solibs): New function. Clears shared library list.
+ (child_solib_add): New function. Adds shared library symbols.
+ (dll_symbol_command): New function. Handles "dll-symbol" command.
+ (info_dll_command): New function. Handles info
+ "sharedlibrary" command.
+ (handle_exceptions): Eliminate 'ignore_trap' argument.
+ (get_child_debug_event): Eliminate two arguments. Return "pid" when
+ appropriate. Break out on most events to allow WFI to handle stuff.
+ (child_wait): Accomodate get_child_debug_event changes.
+ (child_attach): Clear thread list and list of loaded dlls.
+ (child_create_inferior): Clear list of loaded dlls. Use
+ wait_for_inferior in a loop to look for first "trap".
+ (child_resume): Avoid accessing a possibly-freed thread pointer.
+ (_initialize_inftarg): Add "dll-symbols", "sharedlibrary", and "info
+ sharedlibrary" commands.
+ * config/i386/tm-cygwin.h: Add some shared library (aka DLL) hooks.
+
+2000-06-02 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c: Fix up gcc warnings throughout.
+ (handle_load_dll): Change DLL name to lower case.
+ (handle_exception): Add a second argument indicating whether a
+ breakpoint should be ignored. Return a 0 if the breakpoint was
+ ignored.
+ (get_child_debug_event): Pass argument to handle_exception to control
+ whether a breakpoint should be ignored.
+ (child_create_inferior): Use modern cygwin API. Explicitly clear
+ last_sig. Pass FIRST_EXCEPTION to get_child_debug_event for detection
+ of first breakpoint.
+
+2000-06-02 Christopher Faylor <cgf@cygnus.com>
+
+ * configure.in: Detect correct versions of dlltool and windres when
+ cross-compiling.
+ * configure: Regenerate.
+
+2000-06-02 J.T. Conklin <jtc@redback.com>
+
+ * configure.tgt: Add pattern for i[3456]86-*-netbsdelf*.
+ * config/i386/nbsdelf.mt: New file.
+ * config/i386/tm-nbsdelf.h: New file.
+
+ * config/i386/tm-nbsd.h: change include of tm-nbsd.h to
+ the more explicit config/tm-nbsd.h.
+
+2000-06-02 Mark Kettenis <kettenis@gnu.org>
+
+ * alphabsd-nat.c (supply_fpregset): Substract FP0_REGNUM from
+ register number when used as index into fpr_regs array.
+
+Tue May 30 13:31:57 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (TARGET_FLOAT_FORMAT, TARGET_DOUBLE_FORMAT,
+ TARGET_LONG_DOUBLE_FORMAT): Delete.
+
+ * gdbarch.sh: Add support for parameterized expressions.
+ (TARGET_FLOAT_FORMAT, TARGET_DOUBLE_FORMAT,
+ TARGET_LONG_DOUBLE_FORMAT): Add. Include "floatformat.h".
+ * gdbarch.h, gdbarch.c: Regenerate.
+
+ * arch-utils.c (default_single_format, default_double_format,
+ default_long_double_format): New functions. Include
+ "floatformat.h"
+ * arch-utils.h: Declare.
+
+ * d10v-tdep.c (d10v_gdbarch_init): Set floating point format.
+ Note that long double is 64 bit, the rest are 32 bit. Include
+ "floatformat.h".
+
+2000-06-02 Mark Kettenis <kettenis@gnu.org>
+
+ * config/alpha/nm-fbsd.h (CANNOT_STEP_BREAKPOINT): Define.
+
+2000-06-01 Michael Snyder <msnyder@cygnus.com>
+
+ * sol-thread.c (rw_common): Circumstances (eg. a bug in Sun's
+ thread_db library) may cause this function to be called with an
+ illegal address, in which case procfs_to_xfer_memory will
+ return zero. Return an error code instead of looping forever.
+
+Thu Jun 1 20:05:26 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: More suggestions added.
+
+2000-06-01 Klee Dienes <kdienes@apple.com>
+
+ * MAINTAINERS: Add Klee Dienes and Jim Ingham as maintainers for
+ Mac OS X and Objective C components (to be contributed).
+
+2000-05-31 J.T. Conklin <jtc@redback.com>
+
+ * configure.host: Add patterns for i[3456]86-*-netbsdaout*
+ and i[3456]86-*-netbsdelf*.
+ * config/i386/nm-nbsdelf.h: New file.
+ * config/i386/nbsdelf.mh: New file.
+
+ * config/i386/nm-nbsd.h: change include of nm-nbsd.h to
+ the more explicit config/nm-nbsd.h.
+ * config/i386/tm-nbsd.h: change include of tm-i386bsd.h to
+ tm-i386.h.
+ (SIGTRAMP_START, SIGTRAMP_END, SIGCONTEXT_PC_OFFSET): Define.
+
+2000-06-01 Mark Kettenis <kettenis@gnu.org>
+
+ * NEWS: Mention FreeBSD/Alpha and FreeBSD/i386 3.x and up as new
+ native configurations.
+
+ * i386bsd-nat.c: Include "gregset.h".
+ (CANNOT_STORE_REGISTER): Define to cannot_fetch_register instead
+ of CANNOT_FETCH_REGISTER, if not already defined.
+ (supply_gregset): Call supply_register with NULL as its second
+ argument instead of supplying our own zeroed out buffer.
+ (fill_gregset): Copy contents of correct registers instead of the
+ contents of register REGNO.
+
+2000-05-31 Kevin Buettner <kevinb@redhat.com>
+
+ * gnu-regex.c (re_match_2_internal): Revert 2000-05-27
+ patch which removed use of PARAMS from declaration. This
+ file should not have been touched as it is supposed to track
+ the version in glibc.
+
+2000-05-31 Mark Kettenis <kettenis@gnu.org>
+
+ Add support for FreeBSD/Alpha.
+ * configure.host, configure.tgt (alpha*-*-freebsd*): New entry.
+ * alphabsd-nat.c, config/alpha/fbsd.mh, config/alpha/fbsd.mt,
+ config/alpha/nm-fbsd.h, config/alpha/tm-fbsd.h,
+ config/alpha/xm-fbsd.h: New files.
+
+2000-05-31 Pierre Muller <muller@sourceware.cygnus.com>
+
+ * MAINTAINERS: Add myself to "Write After Approval" list.
+
+Tue May 30 18:48:33 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Re-organize.
+
+Tue May 30 11:22:28 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh: Add field ``postdefault''. Rename fields
+ ``startup'' and ``default'' to ``staticdefault'' and
+ ``predefault''. Fix initialization of valid_p. Create/compare
+ gdbarch.log.
+
+Mon May 29 22:47:16 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/sparc/nm-sun4sol2.h (GDB_GREGSET_T, GDB_FPREGSET_T):
+ Define.
+ * config/sparc/xm-sun4sol2.h: (GDB_GREGSET_TYPE,
+ GDB_FPREGSET_TYPE): Delete.
+
+Mon May 29 15:41:10 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * symtab.h (make_cleanup_free_search_symbols): Add declaration.
+ * symtab.c (make_cleanup_free_search_symbols,
+ do_free_search_symbols_cleanup): New functions.
+ (search_symbols, symtab_symbol_info, rbreak_command): Update.
+ (search_symbols): Pass ``sr'', and not its address, to
+ make_cleanup_free_search_symbols.
+
+2000-05-28 Kevin Buettner <kevinb@redhat.com>
+
+ * config/nm-linux.h (GDB_GREGSET_T, GDB_FPREGSET_T): Fix typos.
+
+2000-05-27 Kevin Buettner <kevinb@redhat.com>
+
+ * abug-rom.c, alpha-nat.c, alpha-tdep.c, annotate.c,
+ annotate.h, arc-tdep.c, ax-gdb.c, ax-gdb.h, ax-general.c,
+ ax.h, breakpoint.c, breakpoint.h, c-exp.y, c-lang.c, c-lang.h,
+ call-cmds.h, ch-exp.c, ch-lang.c, ch-lang.h, cli-out.c,
+ coff-solib.h, coffread.c, command.c, command.h, complaints.c,
+ complaints.h, config/a29k/tm-a29k.h, config/a29k/tm-vx29k.h,
+ config/alpha/nm-linux.h, config/alpha/nm-osf.h,
+ config/alpha/nm-osf2.h, config/alpha/tm-alpha.h,
+ config/alpha/tm-alphalinux.h, config/arc/tm-arc.h,
+ config/arm/tm-embed.h, config/d30v/tm-d30v.h,
+ config/fr30/tm-fr30.h, config/h8300/tm-h8300.h,
+ config/h8500/tm-h8500.h, config/i386/nm-i386bsd.h,
+ config/i386/nm-i386sco.h, config/i386/nm-i386sol2.h,
+ config/i386/nm-i386v.h, config/i386/nm-linux.h,
+ config/i386/nm-nbsd.h, config/i386/nm-ptx4.h,
+ config/i386/nm-symmetry.h, config/i386/tm-cygwin.h,
+ config/i386/tm-i386.h, config/i386/tm-i386nw.h,
+ config/i386/tm-i386sol2.h, config/i386/tm-i386v.h,
+ config/i386/tm-i386v4.h, config/i386/tm-nbsd.h,
+ config/i386/tm-ptx.h, config/i386/tm-sun386.h,
+ config/i960/tm-mon960.h, config/i960/tm-nindy960.h,
+ config/m32r/tm-m32r.h, config/m68k/nm-dpx2.h,
+ config/m68k/nm-linux.h, config/m68k/tm-cisco.h,
+ config/m68k/tm-delta68.h, config/m68k/tm-es1800.h,
+ config/m68k/tm-isi.h, config/m68k/tm-linux.h,
+ config/m68k/tm-m68k.h, config/m68k/tm-m68kv4.h,
+ config/m68k/tm-news.h, config/m68k/tm-sun3.h,
+ config/m68k/tm-vx68.h, config/m68k/xm-hp300bsd.h,
+ config/m88k/tm-m88k.h, config/mcore/tm-mcore.h,
+ config/mips/nm-irix3.h, config/mips/nm-irix4.h,
+ config/mips/nm-irix5.h, config/mips/nm-mips.h,
+ config/mips/tm-embed.h, config/mips/tm-mips.h,
+ config/mn10200/tm-mn10200.h, config/mn10300/tm-mn10300.h,
+ config/nm-linux.h, config/nm-lynx.h, config/ns32k/nm-nbsd.h,
+ config/ns32k/tm-merlin.h, config/ns32k/tm-umax.h,
+ config/pa/nm-hppah.h, config/pa/tm-hppa.h,
+ config/pa/tm-hppa64.h, config/pa/xm-hppah.h,
+ config/powerpc/nm-linux.h, config/powerpc/tm-linux.h,
+ config/powerpc/tm-ppc-eabi.h, config/powerpc/tm-solaris.h,
+ config/powerpc/xm-aix.h, config/rs6000/nm-rs6000.h,
+ config/rs6000/tm-rs6000.h, config/rs6000/xm-rs6000.h,
+ config/sh/tm-sh.h, config/sparc/nm-linux.h,
+ config/sparc/nm-sun4os4.h, config/sparc/nm-sun4sol2.h,
+ config/sparc/tm-sp64.h, config/sparc/tm-sp64sim.h,
+ config/sparc/tm-sparc.h, config/sparc/tm-sparclet.h,
+ config/sparc/tm-spc-em.h, config/sparc/tm-sun4os4.h,
+ config/sparc/tm-sun4sol2.h, config/tic80/tm-tic80.h,
+ config/tm-sysv4.h, config/v850/tm-v850.h, config/vax/tm-vax.h,
+ config/w65/tm-w65.h, config/xm-aix4.h, config/z8k/tm-z8k.h,
+ copying.c, core-aout.c, core-regset.c, core-sol2.c,
+ corefile.c, corelow.c, cp-valprint.c, cpu32bug-rom.c,
+ d10v-tdep.c, d30v-tdep.c, dbug-rom.c, dbxread.c, dcache.c,
+ dcache.h, demangle.c, dink32-rom.c, dsrec.c, dstread.c,
+ dve3900-rom.c, dwarf2read.c, dwarfread.c, elfread.c,
+ environ.h, eval.c, exec.c, expprint.c, expression.h, f-exp.y,
+ f-lang.c, f-lang.h, f-valprint.c, findvar.c, fr30-tdep.c,
+ frame.h, gdb_string.h, gdbcmd.h, gdbcore.h,
+ gdbserver/server.h, gdbtypes.c, gdbtypes.h, gnu-regex.c,
+ h8300-tdep.c, hp-psymtab-read.c, hp-symtab-read.c,
+ hp300ux-nat.c, hppa-tdep.c, hppah-nat.c, hpread.c, hpread.h,
+ hpux-thread.c, i386-tdep.c, i386aix-nat.c, i386mach-nat.c,
+ i386v-nat.c, i386v4-nat.c, i387-tdep.c, i960-tdep.c, infcmd.c,
+ inferior.h, inflow.c, infptrace.c, inftarg.c, irix4-nat.c,
+ irix5-nat.c, jv-exp.y, jv-lang.c, jv-lang.h, language.c,
+ language.h, lynx-nat.c, m2-exp.y, m2-lang.c, m2-lang.h,
+ m32r-rom.c, mac-nat.c, main.c, maint.c, mdebugread.c,
+ mi/mi-out.c, minsyms.c, mips-nat.c, mips-tdep.c, mipsread.c,
+ mn10300-tdep.c, mon960-rom.c, monitor.c, monitor.h, nlmread.c,
+ objfiles.c, objfiles.h, ocd.c, ocd.h, op50-rom.c, os9kread.c,
+ osfsolib.c, pa64solib.c, pa64solib.h, parse.c, parser-defs.h,
+ ppc-bdm.c, printcmd.c, procfs.c, remote-array.c, remote-bug.c,
+ remote-e7000.c, remote-es.c, remote-est.c, remote-hms.c,
+ remote-mips.c, remote-nindy.c, remote-nrom.c, remote-rdi.c,
+ remote-rdp.c, remote-sds.c, remote-sim.c, remote-udi.c,
+ remote-utils.c, remote-utils.h, remote-vx.c, remote.c,
+ rom68k-rom.c, rs6000-nat.c, rs6000-tdep.c, scm-exp.c,
+ scm-lang.c, scm-lang.h, ser-e7kpc.c, ser-mac.c, sh3-rom.c,
+ sol-thread.c, solib.c, solib.h, somread.c, somsolib.c,
+ somsolib.h, source.c, sparc-nat.c, sparcl-tdep.c,
+ sparclet-rom.c, srec.h, stabsread.c, stabsread.h, stack.c,
+ sun3-nat.c, symfile.c, symfile.h, symmisc.c, symtab.c,
+ symtab.h, target.c, target.h, terminal.h, thread.c, top.c,
+ top.h, tracepoint.c, tracepoint.h, tui/tui-file.c, tui/tui.c,
+ tui/tui.h, tui/tuiCommand.h, tui/tuiData.c, tui/tuiData.h,
+ tui/tuiDataWin.h, tui/tuiDisassem.c, tui/tuiDisassem.h,
+ tui/tuiGeneralWin.c, tui/tuiGeneralWin.h, tui/tuiIO.c,
+ tui/tuiIO.h, tui/tuiLayout.c, tui/tuiLayout.h, tui/tuiRegs.c,
+ tui/tuiRegs.h, tui/tuiSource.c, tui/tuiSource.h,
+ tui/tuiSourceWin.h, tui/tuiStack.c, tui/tuiStack.h,
+ tui/tuiWin.c, tui/tuiWin.h, typeprint.c, ui-file.c, ui-out.h,
+ ultra3-nat.c, utils.c, v850-tdep.c, v850ice.c, valarith.c,
+ valops.c, valprint.c, value.h, values.c, varobj.c, w89k-rom.c,
+ win32-nat.c, wince.c, wrapper.c, wrapper.h, xcoffread.c,
+ xcoffsolib.c, xmodem.h, z8k-tdep.c: Remove PARAMS from function
+ declarations.
+
+2000-05-26 Michael Snyder <msnyder@cygnus.com>
+
+ * gregset.h: New file. Typedefs for gdb_gregset_t and
+ gdb_fpregset_t, prototypes for supply_gregset and friends.
+ * procfs.c: Include gregset.h. Delete local prototypes for
+ supply_gregset etc., and local typedef gdb_gregset_t etc.
+ * sol-thread.c: Include gregset.h, delete local prototypes,
+ add appropriate casts to gdb_gregset_t.
+ * uw-thread.c, lin-thread.c, core-sol2.c, core-regset.c,
+ sparc-tdep.c, ptx4-nat.c, ppc-linux-nat.c, mipsv4-nat.c,
+ m88k-nat.c, m68klinux-nat.c, m68k-tdep.c, irix5-nat.c,
+ irix4-nat.c, ia64-linux-nat.c, i386v4-nat.c, cxux-nat.c,
+ arm-linux-nat.c, alpha-nat.c: Include gregset.h.
+ * config/nm-linux.h: Define GDB_GREGSET_T, GDB_FPREGET_T.
+ * config/sparc/nm-sun4sol2.h: Ditto.
+ * config/sparc/xm-sun4sol2.h: (GDB_GREGSET_TYPE,
+ GDB_FPREGSET_TYPE): Delete (replaced by GDB_GREGSET_T etc.)
+
+Thu May 25 16:56:05 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (AC_CHECK_HEADERS): Check for ncurses.h.
+ * config.in, configure: Re-generate.
+
+2000-05-25 Scott Bambrough <scottb@netwinder.org>
+
+ * arm-linux-tdep.c (find_minsym_and_objfile): New.
+ (skip_hurd_resolver): New.
+ (arm_linux_skip_solib_resolver): New.
+ (arm_skip_solib_resolver): Removed.
+
+ * config/arm/tm-linux.h (SKIP_SOLIB_RESOLVER): Changed to use
+ arm_linux_skip_solib_resolver.
+
+2000-05-25 Mark Kettenis <kettenis@gnu.org>
+
+ * acconfig.h (HAVE_R_FS, HAVE_R_GS): Add.
+ * configure.in: Add checks for r_fs and r_gs members of
+ `struct reg'.
+ * config.in, configure: Regenerated.
+
+2000-05-25 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * ser-go32.c: Remove PARAMS.
+
+Thu May 25 15:22:12 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (AC_CHECK_HEADERS): Check for <dirent.h>,
+ <sys/ndir.h>, <sys/dir.h> and <ndir.h>.
+ * config.in, configure: Re-generate.
+ * gdb_dirent.h: New file
+
+ * infptrace.c: Include "gdb_dirent.h" instead of <sys/dir.h>.
+ * core-aout.c: Ditto.
+ * procfs.c: Include "gdb_dirent.h" instead of <dirent.h>.
+
+Thu May 25 14:43:30 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config.in: Regenerate.
+
+Thu May 25 13:49:17 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Fri 19 May 2000 Eli Zaretskii <eliz@is.elta.co.il>: *
+ config/djgpp/fnchange.lst: Fix bfd/coff-tic54x.c, bfd/coff-tc54x.c
+ and gdb/testsuite/gdb.mi/mi-var-cmd.exp.
+
+Thu May 25 11:09:50 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (AC_OUTPUT): Do not generate tui/Makefile.
+ (enable-tui): Convert Makefile configury to use the same mechanism
+ as MI.
+
+ * Makefile.in (BUILD_TUI, TUI_LIBRARY, TUI_DIR, TUI_SRC,
+ TUI_CFLAGS): Delete
+ (all-tui): Delete target.
+ (tuiWin.o, tuiStack.o, tuiSourceWin.o, tuiSource.o, tuiRegs.o,
+ tuiLayout.o, tuiIO.o, tuiGeneralWin.o, tuiDisassem.o,
+ tuiDataWin.o, tuiData.o, tuiCommand.o, tui.o): New targets.
+ (SUBDIR_TUI_OBS, SUBDIR_TUI_SRCS, SUBDIR_TUI_DEPS,
+ SUBDIR_TUI_INITS, SUBDIR_TUI_LDFLAGS, SUBDIR_TUI_CFLAGS,
+ SUBDIR_TUI_ALL, SUBDIR_TUI_CLEAN, SUBDIR_TUI_INSTALL,
+ SUBDIR_TUI_UNINSTALL): Define.
+
+ * TODO: Update.
+
+Thu May 25 11:02:24 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Update. Mark Kettenis fixed FreeBSD >2.2 support.
+ * MAINTAINERS: Update Jim Ingham's address.
+
+2000-05-25 Mark Kettenis <kettenis@gnu.org>
+
+ Add support for FreeBSD/i386 ELF.
+ * i386bsd-nat.c: New file.
+ * config/i386/tm-fbsd.h (HAVE_I387_REGS): Define.
+ Include "i386/tm-i386.h" instead of "i386/tm-i386b.h".
+ (NUM_REGS): Remove redefinition.
+ (USE_STRUCT_CONVENTION): Define.
+ (i386_float_info): Remove prototype.
+ (FLOAT_INFO): Remove define.
+ (JB_ELEMENT_SIZE): Define to 4.
+ (JB_PC): Define to 0.
+ (GET_LONGJMP_TARGET): Define.
+ (SIGTRAMP_START, SIGTRAMP_END): Define.
+ (SIGCONTEXT_PC_OFFSET): Define.
+ (IN_SOLIB_CALL_TRAMPOLINE): Only define if !SVR4_SHARED_LIBS
+ * config/i386/nm-fbsd.h (PTRACE_ARG3_TYPE): Define to caddr_t.
+ (FETCH_INFERIOR_REGISTERS): Define.
+ (ATTACH_DETACH): Define.
+ (kernel_u_size): Remove PARAMS.
+ (register_u_addr): Use CORE_ADDR in prototype where appropriate.
+ Remove PARAMS.
+ (SVR4_SHARED_LIBS) [FREEBSD_ELF || __ELF__ && !FREEBSD_AOUT]:
+ Define.
+ [SVR4_SHARED_LIBS]: Include "elf/common.h".
+ Only define aliases for struct members from <link.h> if
+ !SVR4_SHARED_LIBS.
+ * config/i386/xm-fbsd.h: New file.
+ * config/i386/fbsd.mt (TDEPFILES): Remove solib.o.
+ * config/i386/fbsd.mh (NATDEPFILES): Remove i386b-nat.o. Add
+ core-regset.o i387-nat.o i386bsd-nat.o.
+
+2000-05-24 Michael Snyder <msnyder@cygnus.com>
+
+ * findvar.c (value_from_register): Factor code, simplify logic.
+
+2000-05-23 J.T. Conklin <jtc@redback.com>
+
+ * config/i386/nbsd.mt (TDEPFILES): Move solib.o from here...
+ * config/i386/nbsd.mh (NATDEPFILES): ...to here.
+ * config/m68k/nbsd.mt (TDEPFILES): Move solib.o from here...
+ * config/m68k/nbsd.mh (NATDEPFILES): ...to here.
+ * config/ns32k/nbsd.mt (TDEPFILES): Move solib.o from here...
+ * config/ns32k/nbsd.mh (NATDEPFILES): ...to here.
+
+ * config/powerpc/nbsd.mt (GDBSERVER_DEPFILES): Add low-nbsd.o.
+ * configure.tgt (powerpc-*-netbsd*): add gdbserver to configdirs.
+ * gdbserver/low-nbsd.c (initialize_arch): Define for PPC.
+ (fetch_inferior_registers): Likewise.
+ (store_inferior_registers): Likewise.
+
+ * gdbserver/low-nbsd.c (fetch_inferior_registers): Handle X86
+ floating point registers.
+ (store_inferior_registers): Likewise.
+
+2000-05-24 Mark Kettenis <kettenis@gnu.org>
+
+ * i387-nat.h, i387-nat.c: New files.
+
+Tue May 23 17:21:24 2000 Alexandre Oliva <aoliva@cygnus.com>
+
+ * config/sparc/nm-linux.h: Include config/nm-linux.h.
+ * config/powerpc/nm-linux.h: Likewise.
+
+Tue May 23 13:20:00 1999 Gregory Lielens <info@fft.be>
+
+ * f-valprint.c : Corrected f_val_print function for TYPE_CODE
+ (type) = TYPE_CODE_COMPLEX
+
+Wed May 24 00:38:09 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * utils.c (make_cleanup_close, do_close_cleanup): New functions.
+ * defs.h (make_cleanup_close): Add declaration.
+
+Tue May 23 20:47:50 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (build_warnings): Add -Wuninitialized.
+ * configure: Regenerate.
+
+Tue May 23 17:44:18 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Mon May 8 14:49:51 2000 Andrew Cagney <cagney@b1.cygnus.com>
+ (gdb 5.0): From Michael Paddon <mmpp@esec.com.au>:
+ * configure.in (AC_CHECK_HEADERS): Check for <sys/user.h>.
+
+ * configure: Re-generate.
+ * proc-api.c: Only include <sys/user.h> when available.
+ (ioctl_table): Check that PIOCGETPR and PIOCGETU are defined.
+
+ * TODO: Update.
+
+2000-05-17 Michael Snyder <msnyder@cygnus.com>
+
+ * config/sparc/tm-sun4sol2.h: Turn on multi-arch.
+ * sparc-tdep.c (gdb_print_insn_sparc): Remove temp. multi-arch hack.
+
+2000-05-17 Andrew Cagney <cagney@sourceware.cygnus.com>
+
+ * GDB 5.0 released.
+ * Makefile.in (VERSION): Set to 5.0.
+
+Mon May 22 16:20:31 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * inferior.h (make_cleanup_restore_inferior_status):
+ * infrun.c (make_cleanup_restore_inferior_status,
+ do_restore_inferior_status_cleanup): New functions.
+ * valops.c (hand_function_call): Use.
+ * infcmd.c (disable_longjmp_breakpoint_cleanup): New function.
+ (step_1): Use.
+ * symfile.c (clear_symtab_users_cleanup): New function.
+ (syms_from_objfile, reread_symbols): Use.
+ * objfiles.c (make_cleanup_free_objfile, do_free_objfile_cleanup):
+ New functions.
+ * objfiles.h (make_cleanup_free_objfile): Add declaration.
+ * symfile.c (syms_from_objfile, reread_symbols), hpread.c
+ (hpread_build_psymtabs), hp-psymtab-read.c
+ (hpread_build_psymtabs): Use.
+ * dwarf2read.c (make_cleanup_free_die_list,
+ do_free_die_list_cleanup): New functions.
+ (psymtab_to_symtab_1): Use.
+ * tracepoint.c (make_cleanup_free_actions,
+ do_free_actions_cleanup): New functions.
+ (read_actions): Use.
+ * corelow.c (core_close_cleanup): New function.
+ (core_open): Use.
+ * dbxread.c (make_cleanup_free_bincl_list,
+ do_free_bincl_list_cleanup): New function.
+ (read_dbx_symtab): Use.
+ * coffread.c (free_linetab_cleanup, free_stringtab_cleanup): New
+ functions.
+ (coff_symfile_read): Use.
+ * varobj.c (make_cleanup_free_variable, do_free_variable_cleanup):
+ New function.
+ (varobj_create): Use.
+ * sparcl-tdep.c (close_tty), infrun.c (resume_cleanups), parse.c
+ (free_funcalls): Change signature to match make_cleanup_ftype.
+ * infrun.c (resume), tracepoint.c (encode_actions), remote-udi.c
+ (download), solib.c (open_symbol_file_object), sparcl-tdep.c
+ (sparclite_open), parse.c (parse_exp_1): Remove cast using
+ make_cleanup_func.
+
+Mon May 22 15:49:13 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * procfs.c (info_proc_cmd): Use make_cleanup_freeargv.
+ (proc_iterate_over_mappings): Use make_cleanup_close.
+ (proc_get_LDT_entry): Ditto.
+ (do_closedir_cleanup): New function.
+ (proc_update_threads): Use.
+ (do_destroy_procinfo_cleanup): New function.
+ (info_proc_cmd): Use.
+
+Mon May 22 15:21:38 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.h (command_loop_marker): Change signature to match
+ make_cleanup_ftype.
+ * top.c (command_loop_marker): Update.
+ (command_loop, simplified_command_loop), event-top.c
+ (command_handler): Remove cast using make_cleanup_func.
+ * event-top.c (command_handler): Ditto.
+
+ * top.c (do_chdir_cleanup): New function.
+ (gdb_init): Use. Use xstrdup instead of strsave.
+ * top.c (do_fclose_cleanup): New function.
+ (source_command): Use.
+ * top.c (do_restore_instream_cleanup): Rename
+ source_cleanup. Change signature to match make_cleanup.
+ (read_command_filem execute_user_command): Update. Remove cast
+ using make_cleanup_func.
+ * top.c (do_free_command_lines_cleanup,
+ make_cleanup_free_command_lines): New funtions.
+ (get_command_line, read_command_lines): Use.
+ * top.c (arg_cleanup): Change signature to match make_cleanup.
+ (setup_user_args): Remove cast using make_cleanup_func.
+
+Mon May 22 12:05:13 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (t_reg): Delete typedef.
+ (preg, preg_nz): Delete function. Replaced by phex and phex_nz.
+ * utils.c (phex, phex_nz): New functions.
+ (paddr, paddr_nz): Use.
+
+ * monitor.c (monitor_store_register): Replace preg with phex.
+
+Mon May 22 11:46:01 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Add note on typecast using catch_errors_ftype.
+
+2000-05-21 Mark Kettenis <kettenis@gnu.org>
+
+ * i387-tdep.c (print_i387_value): Cast &value to (char *) in
+ pointer arithmetic. Fixes a bug which manifested itself on
+ FreeBSD.
+
+2000-05-20 J.T. Conklin <jtc@redback.com>
+
+ * target.h (target_memory_bfd_section): Removed declaration.
+ * target.c (target_memory_bfd_section): Removed.
+ * exec.c (xfer_memory): Removed #if'ed-out code which referenced
+ target_memory_bfd_section.
+
+ * target.h (target_read_memory_section): Removed declaration.
+ * target.c (target_read_memory_section): Removed.
+ (target_xfer_memory): Update, removed bfd_section argument.
+ (target_read_string, target_read_memory, target_write_memory):
+ Update for above change.
+
+ * gdbcore.h (read_memory_section): Removed declaration.
+ * corefile.c (read_memory_section): Removed.
+ * jv-lang.c (get_java_utf8_name): Changed calls to
+ read_memory_section to read_memory.
+ * printcmd.c (printf_command): Likewise.
+ * valops.c (value_at, value_fetch_lazy): Likewise.
+
+2000-05-18 J.T. Conklin <jtc@redback.com>
+
+ * configure.host, configure.tgt (powerpc-*-netbsd*): New entry.
+ * config/powerpc/nbsd.mh, config/powerpc/nbsd.mt,
+ config/powerpc/tm-nbsd.h, config/powerpc/nm-nbsd.h,
+ config/powerpc/xm-nbsd.h: New files.
+
+2000-05-17 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb/config/djgpp/README: Fine-tune installation instructions
+ based on user reports.
+
+Wed May 17 18:27:45 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (build_warnings): List possible warnings.
+ * configure: Regenerate.
+ * TODO: More updates.
+ * MAINTAINERS: Add Gary Thomas and Joern Renneck to Write After
+ Approval.
+
+Wed May 17 16:48:36 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-04-14 Gary Thomas <gthomas@redhat.com>:
+ * config/v850/tm-v850.h: Change breakpoint sequence to be
+ 'br *' since there is no 16bit "illegal" instruction on this
+ processor.
+
+Tue May 16 18:57:14 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Review. Delete anything that is no longer applicable.
+
+Tue May 16 14:17:20 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * utils.c (free_current_contents): Make more robust.
+
+Tue May 16 13:30:08 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * symtab.h (make_cleanup_discard_minimal_symbols): Replace
+ discard_minimal_symbols.
+ * minsyms.c (make_cleanup_discard_minimal_symbols):
+ (do_discard_minimal_symbols_cleanup): New functions.
+
+ * xcoffread.c (xcoff_initial_scan), somread.c (som_symfile_read),
+ solib.c (solib_add_common_symbols), os9kread.c
+ (os9k_symfile_read), nlmread.c (nlm_symfile_read), mipsread.c
+ (mipscoff_symfile_read), elfread.c (elf_symfile_read), dstread.c
+ (dst_symfile_read), dbxread.c (dbx_symfile_read), coffread.c
+ (coff_symfile_read): Replace make_cleanup.
+
+Mon May 15 09:32:31 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * command.h (add_set_cmd): Change VAR parameter to void pointer.
+ (add_set_enum_cmd): Change VAR parameter to char pointer pointer.
+ (struct command): Change member VAR to void pointer.
+ * command.c (add_set_cmd, add_set_enum_cmd): Update.
+
+ * remote.c (add_packet_config_cmd), mips-tdep.c
+ (_initialize_mips_tdep), infrun.c (_initialize_infrun),
+ i386-tdep.c (_initialize_i386_tdep), arm-tdep.c
+ (_initialize_arm_tdep): Update VAR parameter to add_set_enum_cmd.
+
+Tue May 16 12:46:04 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * wrapper.h (wrap_value_subscript): Delete declaration.
+
+Tue May 16 10:54:55 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (make_cleanup_bfd_close): Add declaration.
+ * utils.c (do_bfd_close_cleanup, make_cleanup_bfd_close): New
+ functions.
+
+ * symfile.c (generic_load), sparcl-tdep.c (download), remote-udi.c
+ (download), remote-e7000.c (e7000_load), corelow.c (core_open,
+ core_file_to_sym_file): Replace calls to make_cleanup.
+
+Mon May 15 16:50:45 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Add notes on register cache.
+
+Mon May 15 21:27:27 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh-tdep.c (sh_dsp_reg_names, sh3_dsp_reg_names): New arrays.
+ (sh_processor_type_table): Add entries for bfd_mach_sh_dsp and
+ bfd_mach_sh3_dsp.
+ (sh_show_regs): Floating point registers are called fr0-fr15.
+ For sh4, display fpul, fpscr and fr0-fr15 / dr0-dr14 as appropriate.
+ Handle sh-dsp and sh3-dsp.
+ config/sh/tm-sh.h (REGISTER_VIRTUAL_TYPE): sh-dsp / sh3-dsp
+ don't have floating point registers.
+ (DSR_REGNUM, A0G_REGNUM, A0_REGNUM, A1G_REGNUM, A1_REGNUM): Define.
+ (M0_REGNUM, M1_REGNUM, X0_REGNUM, X1_REGNUM, Y0_REGNUM): Likewise.
+ (Y1_REGNUM, MOD_REGNUM, RS_REGNUM, RE_REGNUM, R0B_REGNUM): Likewise.
+
+2000-05-15 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * Makefile.in (gdbtypes.o, varobj.o): Depend on wrapper.h.
+
+ * wrapper.h (gdb_value_subscript, wrap_value_subscript): Add
+ prototypes.
+
+Mon May 15 15:31:30 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * valops.c (hand_function_call): Replace #ifdef
+ SAVE_DUMMY_FRAME_TOS with if SAVE_DUMMY_FRAME_TOS_P.
+
+ * gdbarch.sh (SAVE_DUMMY_FRAME_TOS): Add.
+ * gdbarch.h, gdbarch.c: Regenerate.
+
+Mon May 15 16:05:46 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ax.h (make_cleanup_free_agent_expr): Add declaration.
+ * ax-general.c (do_free_agent_expr_cleanup):
+ (make_cleanup_free_agent_expr): New functions.
+
+ * tracepoint.c (validate_actionline, encode_actions), ax-gdb.c
+ (expr_to_agent, gen_trace_for_expr, agent_command): Replace calls
+ to make_cleanup.
+
+Mon May 15 14:06:23 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * breakpoint.h (make_cleanup_delete_breakpoint,
+ make_exec_cleanup_delete_breakpoint): Declare.
+ * breakpoint.c (make_cleanup_delete_breakpoint,
+ make_exec_cleanup_delete_breakpoint,
+ do_delete_breakpoint_cleanup): New fuctions.
+
+ * infcmd.c (finish_command), hppa-tdep.c (hppa_pop_frame),
+ breakpoint.c (until_break_command, until_break_command): Replace
+ call to make_cleanup / make_exec_cleanup.
+
+Mon May 15 13:25:57 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (core_addr_greaterthan, core_addr_lessthan), utils.c
+ (core_addr_greaterthan, core_addr_lessthan): Move from here.
+ * arch-utils.h (core_addr_greaterthan, core_addr_lessthan),
+ arch-utils.c (core_addr_greaterthan, core_addr_lessthan): To here.
+
+Mon May 15 12:07:55 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * printcmd.c (print_frame_args), stack.c (print_frame), command.c
+ (do_setshow_command), breakpoint.c (print_it_typical, mention):
+ Use make_cleanup_ui_out_stream_delete.
+
+Mon May 15 11:23:23 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * proc-events.c (init_syscall_table): Delete stray ``;''.
+ * ui-out.c (ui_out_set_flags, ui_out_clear_flags): Return old
+ value.
+ * mdebugread.c (START_PSYMTAB): Add paren to avoid x=x=x.
+
+2000-05-12 Michael Snyder <msnyder@cygnus.com>
+
+ * config/i386/tm-i386sol2.h (COERCE_FLOAT_TO_DOUBLE): Define.
+
+2000-05-12 Kevin Buettner <kevinb@redhat.com>
+
+ * dwarf2read.c (dwarf2_const_value_data): Fix typo in sign
+ extension code.
+
+Fri May 12 20:38:55 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Mention weak symbol problem. Mention UnixWare thread
+ problem.
+
+Fri May 12 14:12:17 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * README: Update section on kernel debugging.
+
+Fri May 12 19:13:15 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (mips_get_saved_register): New function. Handle
+ case of 32 ABI saving 32 bit registers on stack when target has 64
+ bit ISA.
+ (mips_gdbarch_init): Update.
+
+Fri May 12 14:46:52 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (MIPS_EABI): Fix typo. Test for MIPS_ABI_EABI64.
+
+Thu May 11 21:52:55 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (WERROR_CFLAGS): Check that GCC accepts a -W
+ options before using them. Report result.
+ * configure: Regenerate.
+
+2000-05-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * coffread.c (coff_symtab_read): In the case of C_THUMBEXT |
+ C_THUMBEXTFUNC | C_EXT, sec will never ever be the index for
+ .rodata, because cs_to_section doesn't deal with .rodata. Fix test
+ accordingly.
+
+Thu May 11 21:33:59 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh (gdbarch_dump): Print the value of GDB_MULTI_ARCH.
+ Always check that a macro is defined before printing it.
+ * gdbarch.c: Re-generate.
+
+Thu May 11 17:22:36 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * README: Update for GDB 5.0.
+
+Thu May 11 13:24:52 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (MIPS_DEFAULT_STACK_ARGSIZE): Fix typo.
+
+ * config/mips/tm-irix5.h (GDB_MULTI_ARCH): Add
+ definition. Disable. Document known problems.
+ (MIPS_DEFAULT_ABI): Define.
+
+ * mips-tdep.c (enum mips_abi): Define.
+ (struct gdbarch_tdep): Replace mips_eabi with mips_abi.
+ (MIPS_EABI): Update.
+ (mips_gdbarch_init): Add preliminary support for IRIX N32 ABI.
+ Determine ABI from either ELF_FLAGS or MIPS_DEFAULT_ABI. When
+ looking for a matching architecture require a matching MIPS_ABI.
+ (mips_gdbarch_init): Cleanup arch_debug information.
+
+2000-05-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * solib.c (symbol_add_stub): Remember the index and the name of
+ the section with the lowest address. Use this data (instead of
+ data from .text) to pass info into symbol_file_add.
+
+ * elfread.c (record_minimal_symbol_and_info): Use the section
+ where the symbol lives to get the index, instead of guessing.
+
+2000-05-10 Michael Snyder <msnyder@cygnus.com>
+
+ Make Sparc a Multi-Arch target. Discard PARAMS macro (require ANSI).
+ * sparc-tdep.c: include arch-utils.h.
+ (SPARC_HAS_FPU, FP_REGISTER_BYTES, FP_MAX_REG NUM, SPARC_INTREG_SIZE,
+ DUMMY_REG_SAVE_OFFSET): provide multi-arch-compatible definitions.
+ (GDB_TARGET_IS_SPARC64): make into a runtime test.
+ (struct frame_extra_info): Define, use instead of the macro.
+ (Many places): Use alloca instead of statically allocated buffers
+ that depend on a multi-arch variable such as MAX_REGISTER_RAW_SIZE.
+ (sparc_extract_struct_value_address): Accept a pointer arg instead
+ of an array sized by REGISTER_BYTES.
+ (examine_prologue): Accept a pointer to an array of CORE_ADDR,
+ instead of the defunct struct frame_saved_regs. Recognize new
+ Sparc64 store instructions as part of the prologue. Ignore the
+ destination of a frame store when parsing the prologue (so long
+ as it's on the stack).
+ (sparc_push_dummy_frame): Fix incorrect buffer offset for PSTATE.
+ (sparc_frame_find_saved_regs): Accept a ptr to an array of CORE_ADDR
+ instead of the defunct struct frame_saved_regs.
+ (supply_gregset): Discard unnecessary 'zerobuf': just send NULL to
+ supply_register. Provide 4-byte offset to compensate for diff
+ between size of the prgreg_t elements on a 64-bit host and size
+ of the registers for a 32-bit target. Fill all inaccessible regs
+ with zero so they won't keep being requested again and again.
+ (fill_gregset): Handle 32/64 size difference between registers
+ and prgreg_t. Handle as many new 64-bit regs as possible.
+ (supply_fpregset, fill_fpregset): Attempt to handle 64-bit world.
+ (sparc_push_arguments): Rename to sparc32_push_arguments.
+ Copy arguments into registers as well as onto stack, so that the
+ CALL_DUMMY (code pushed onto the target stack) is not required.
+ (sparc_extract_return_value): Rename to sparc32_extract_return_value.
+ (sparc_store_return_value): Use memset instead of bzero.
+ Use write_register_gen instead of write_register_bytes.
+ (sparclet_store_return_value): New function.
+ (_initialize_sparc_tdep): Call register_gdbarch_init to activate
+ the gdbarch multi-architecture system.
+ (sp64_push_arguments): Rename to sparc64_push_arguments.
+ Extend to store arguments in general registers as well as on stack.
+ (sparc64_extract_return_value): Rename to sp64_extract_return_value.
+ Use as a private function, to be called by the new external function
+ sparc64_extract_return_value.
+ (sparclet_extract_return_value): New function.
+ (sparc32_stack_align, sparc64_stack_align, sparc32_register_name,
+ sparc64_register_name, sparc_print_extra_frame_info,
+ sparclite_register_name, sparclet_register_name,
+ sparc_push_return_address, sparc64_use_struct_convention,
+ sparc32_store_struct_return, sparc64_store_struct_return,
+ sparc32_register_virtual_type, sparc64_register_virtual_type,
+ sparc32_register_size, sparc64_register_size,
+ sparc32_register_byte, sparc64_register_byte,
+ sparc_gdbarch_skip_prologue, sparc_convert_to_virtual,
+ sparc_convert_to_raw, sparc_frame_init_saved_regs,
+ sparc_frame_address, sparc_gdbarch_fix_call_dummy,
+ sparc_coerce_float_to_double, sparc_call_dummy_address,
+ sparc_y_regnum, sparc_reg_struct_has_addr, sparc_intreg_size,
+ sparc_return_value_on_stack): New functions supporting multi-arch.
+ (sparc_gdbarch_init): New function; initialize multi-arch.
+ (struct gdbarch_tdep): Define, use for private multi-arch data.
+ * config/sparc/tm-sparc.h: Move definitions around, enclose with
+ #ifdef GDB_MULTI_ARCH tests, provide some multi-arch alternate
+ definitions. Add enums for register names, to help debugging gdb.
+ This header file must work for non-multi-arch and for multi-arch.
+ * config/sparc/tm-sp64.h: Add GDB_MULTI_ARCH configuration. Also add
+ AT_ENTRY_POINT definitions for CALL_DUMMY, for non-multi-arch case.
+ Define GDB_MULTI_ARCH.
+ * config/sparc/tm-sparclet.h: Add GDB_MULTI_ARCH configuration.
+ Do not define GDB_MULTI_ARCH (bfd does not correctly identify target).
+ * config/sparc/tm-sparclite.h: Ditto.
+ * config/sparc/tm-sun4sol2.h: Define GDB_MULTI_ARCH.
+ * sparclet-rom.c (sparclet_regnames): Initialize explicitly, to
+ avoid using deprecated REGISTER_NAMES macro.
+ * Makefile.in: Let sparc-tdep.c depend on arch-utils.h.
+
+2000-05-08 Michael Snyder <msnyder@cygnus.com>
+
+ * gdbarch.sh: Add FP0_REGNUM to list of multi-arched register numbers.
+ * gdbarch.c, gdbarch.h: Regenerate.
+ * core-regset.c: Change FP0_REGNUM to a runtime test.
+ * procfs.c: Ditto.
+ * sun3-nat.c: Ditto.
+ * sparc-tdep.c: Ditto.
+
+ * i386mach-nat.c: Remove unnecessary ifdef for FP0_REGNUM.
+ * ptx4-nat.c: Ditto.
+
+ * sol-thread.c (sol_thread_create_inferior): only add the thread
+ to the thread list if it is not already in there.
+ (prototypes for thread_db func ptrs): pretty up formatting.
+
+2000-05-08 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/djgpp/djconfig.sh: Use more warning switches.
+
+ * config/djgpp/fnchange.lst: Replace the leading gdb-0222 with the
+ @V@ placebo. djunpack.bat changed accordingly.
+
+Mon May 8 11:19:47 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c (size_auto, size_32, size_64, size_enums): Rename
+ saved_gpreg_size_auto, saved_gpreg_size_32, saved_gpreg_size_64
+ and saved_gpreg_size_enums.
+ (mips_stack_argsize): Update. Cleanup.
+
+ * mips-tdep.c (STACK_ARGSIZE): Delete macro. Replaced by
+ MIPS_STACK_ARGSIZE.
+ (MIPS_NABI32): Delete macro. Replaced by
+ MIPS_REGS_HAVE_STACK_HOME_P.
+ (mips_push_arguments): Update.
+ (mips_push_arguments): Replace check for MIPS_EABI or MIPS_NABI32
+ with test for MIPS_REGS_HAVE_STACK_HOME_P.
+ (MIPS_REGS_HAVE_STACK_HOME_P): Define. Provide non- multi-arch
+ default.
+ (struct gdbarch_tdep): Add mips_regs_have_stack_home_p and
+ mips_default_stack_argsize.
+ (MIPS_STACK_ARGSIZE): Define as mips_stack_argsize.
+ (mips_stack_argsize_string): New static variable.
+ (mips_stack_argsize): New function, handle default case.
+ (__initialize_mips_tdep): Add command ``set mips stack-arg-size''
+ implemented as an enum using size_auto et.al.
+ (mips_gdbarch_init): Initialize mips_default_stack_argsize and
+ mips_regs_have_stack_home_p.
+
+ * config/mips/tm-irix5.h (MIPS_DEFAULT_SAVED_REGSIZE): Define as 8
+ for n32.
+ (MIPS_REGS_HAVE_STACK_HOME_P): Define as 0 for n32.
+
+Mon May 8 00:49:32 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * procfs.c (PROCFS_TRACE): Delete definition.
+ * proc-utils.h (PROCFS_NOTE, PROC_PRETTYFPRINT_STATUS): Always
+ define.
+
+2000-05-05 Michael Snyder <msnyder@cygnus.com>
+
+ * procfs.c: Cleanup of procfs tracing. Move defines and
+ prototypes to proc-utils.h
+ * proc-utils.h: Define tracing macros. Declare trace functions.
+ * proc-api.c: Make procfs tracing a runtime option.
+ (prepare_to_trace): New function, abstracted out of several
+ places. Open a trace file if one is required.
+ (ioctl_with_trace, write_with_trace, open_with_trace,
+ close_with_trace, wait_with_trace, lseek_with_trace):
+ Report errno if an error occurs in a system call.
+ (write_with_trace): Make 2nd arg void *, to agree with write.
+
+2000-05-05 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * elfread.c (elf_symtab_read): The calculation of 'offset'
+ must be done for each symbol, not just once. The index
+ used must be the index of the section where 'sym' resides,
+ not .text.
+
+2000-05-05 Michael Snyder <msnyder@cygnus.com>
+
+ * procfs.c (many functions): change int cmd; to long cmd;
+ Solaris /proc API calls this parameter a long, and requires it
+ for 64-bit hosts (where sizeof(long) != sizeof(int)). UnixWare
+ calls it an int, but on existing UnixWare hosts, int and long
+ are the same size. So long it must be. If a future UnixWare
+ version has problems with this, we'll have to use autoconf.
+ * proc-api.c (write_with_trace): use long instead of int.
+
+2000-05-04 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-linux-nat.c: Define PT_READ_U and PT_WRITE_U if they're not
+ already defined.
+
+2000-05-01 Mark Kettenis <kettenis@gnu.org>
+
+ * infrun.c (handle_inferior_event): Add missing call to keep_going
+ and missing return when handling an ordinary signal from the
+ inferior.
+
+2000-05-04 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * objfiles.h (SECT_OFF_DATA, SECT_OFF_TEXT, SECT_OFF_BSS,
+ SECT_OFF_RODATA): Define as functions of OBJFILE. Add
+ sect_index_text, sect_index_data, sect_index_rodata,
+ sect_index_bss to objfile structure.
+ * gdb-stabs.h (SECT_OFF_DATA, SECT_OFF_TEXT, SECT_OFF_BSS,
+ SECT_OFF_RODATA): Remove.
+ * objfiles.c (allocate_objfile): Initialize
+ sect_index_{text,data,bss,rodata} to -1, for error detection.
+
+ * symfile.c (default_symfile_offsets): Initialize
+ sect_index_{text,data,bss,rodata} from bfd information.
+ * xcoffread.c (xcoff_symfile_offsets): Ditto.
+ * somread.c (som_symfile_offsets): Initialize
+ sect_index_{text,data,bss,rodata}.
+
+ * coffread.c, dbxread.c, elfread.c, hp-psymtab-read.c,
+ hp-symtab-read.c, hpread.c, mdebugread.c, minsyms.c,
+ mipsread.c, objfiles.c, os9kread.c, pa64solib.c, partial-stab.h,
+ remote-os9k.c, remote-vx.c, remote.c, rs6000-nat.c, somsolib.c,
+ stabsread.c, symfile.c, xcoffread.c:
+ Update use of SECT_OFF_{TEXT,DATA,BSS,RODATA} to depend on the
+ current objfile.
+
+ * xcoffread.c: Add new field objfile to find_targ_sec_arg.
+
+Thu May 4 20:54:00 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/mips/tm-mipsv4.h (Dest_Reg), config/mips/tm-irix5.h
+ (MIPS_NUM_ARG_REGS, Dest_Reg), config/mips/tm-mips.h
+ (MIPS_NUM_ARG_REGS), config/mips/tm-mips.h (MIPS_NUM_FP_ARG_REGS):
+ Delete unused macros.
+
+2000-05-03 Michael Snyder <msnyder@cygnus.com>
+
+ * solib.c (elf_locate_base, info_sharedlibrary_command):
+ Look at the bfd to determine if it is elf32 or elf64, rather
+ than using an ifdef. This makes it runtime teststable and
+ multi-arch.
+
+2000-05-01 Mark Kettenis <kettenis@gnu.org>
+
+ * infrun.c (handle_inferior_event): When doing a "next", and
+ stepping out of a signal handler into its calling trampoline
+ ignore the value of step_frame_address.
+ (step_over_function): Only modify step_resume_breakpoint->frame if
+ the value of step_frame_address is non-zero.
+
+2000-05-03 Michael Snyder <msnyder@cygnus.com>
+
+ * monitor.c (monitor_fetch_register): MAX_REGISTER_RAW_SIZE
+ is not static in the MULTI_ARCH world, so don't use it in a
+ static array declaration.
+
+2000-05-03 Elena Zannoni <ezannoni@makita.cygnus.com>
+
+ * symtab.c (in_prologue): From Jim Blandy. Rewrite, more
+ intelligently, making sure we use the information from the
+ symbol tables fully.
+
+2000-05-02 H.J. Lu <hjl@gnu.org>
+
+ * ia64-tdep.c (ia64_gdbarch_init): Reference to ELFOSABI_NONE
+ instead of ELFOSABI_SYSV.
+
+Tue May 2 19:07:20 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh (NPC_REGNUM, NNPC_REGNUM): Add.
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+ * gdbserver/remote-utils.c (prepare_resume_reply): Change #ifdef
+ NPC_REGNUM to run-time test.
+ * findvar.c (generic_target_write_pc): Change #ifdef NPC_REGNUM
+ and NNPC_REGNUM to run-time test.
+ * procfs.c (procfs_fetch_registers): Change #ifdef NPC_REGNUM to
+ run-time test.
+ (procfs_store_registers): Ditto.
+
+Tue May 2 18:48:57 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh: Provide non- multi-arch defaults by direct
+ definition in "gdbarch.h" instead of going through "gdbarch.c".
+ * gdbarch.h, gdbarch.c: Re-generate.
+ * defs.h: When non- multi-arch, include "arch-utils.h" so that
+ legacy definitions are globally visible.
+
+Tue May 2 16:32:06 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Add Syd Polk to gdbtk maintainers.
+ (symtabs): Add Elena to symtabs maintainers list.
+ (Blanket Write Privs): Add Jim Blandy.
+
+2000-05-01 Stan Shebs <shebs@apple.com>
+
+ Remove obsolete Gould configuration:
+ * configure.host, configure.tgt: Remove Gould configs.
+ * Makefile.in: Remove Gould-related actions.
+ * gould-xdep.c, gould-tdep.c, config/gould/*: Remove files.
+ * NEWS: Mention removal.
+
+Mon May 1 15:37:58 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-04-28 Andreas Jaeger <aj@suse.de>:
+ * defs.h: Properly check for GCC version number.
+
+2000-04-30 Mark Kettenis <kettenis@gnu.org>
+
+ Fix single-stepping out of signal trampolines.
+ * config/i386/nm-linux.h (CHILD_RESUME): Define.
+ * i386-linux-nat.c (child_resume): New function.
+
+Fri Apr 28 16:22:34 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * blockframe.c (frameless_look_for_prologue): Use
+ PROLOG_FRAMELESS_P instead of SKIP_PROLOGUE_FRAMELESS_P.
+ * gdbarch.sh (PROLOG_FRAMELESS_P): Define.
+ * gdbarch.h, gdbarch.c: Re-generate.
+ * arch-utils.h, arch-utils.c (generic_prologue_frameless_p): New
+ function.
+
+Fri Apr 28 15:31:10 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From "Serge Nikulin" <nikulin@actsw.amat.com>:
+ * m68k-tdep.c (delta68_in_sigtramp): Return 0 when the function
+ name is unknow.
+
+2000-04-27 Michael Snyder <msnyder@cygnus.com>
+
+ * gdbarch.sh (d10v_daddr_p, d10v_iaddr_p, d10v_convert_daddr_to_raw,
+ d10v_convert_iaddr_to_raw): make these multi-arch functions optional.
+ * gdbarch.c, gdbarch.h: regenerate
+
+Fri Apr 28 12:21:28 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Tim Mooney <mooney@dogbert.cc.ndsu.nodak.edu>:
+ * target.c (do_monitor_command): Cast tcomplain to correct
+ function type in comparison.
+
+Fri Apr 28 11:43:05 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-04-25 Guy Harris <guy@netapp.com>:
+ * config/alpha/alpha-osf3.mh (XDEPFILES): Add ser-tcp.o and
+ ser-pipe.o
+
+2000-04-27 Michael Snyder <msnyder@cygnus.com>
+
+ * jv-valprint.c (java_val_print): Add arg declaration,
+ fix compiler warning.
+ * corelow.c (core_open): Call set_gdbarch_from_file so that
+ gdbarch becomes aware of the architecture encoded in the
+ corefile.
+ * findvar.c (write_register_gen): Export this useful interface.
+ * value.h (write_register_gen): Declare.
+
+2000-04-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * cxux-nat.c (add_shared_symbol_files): Don't treat .text section
+ as special in the section_addr_info structure.
+ * pa64solib.c (pa64_solib_add_solib_objfile): Ditto.
+ * osfsolib.c (symbol_add_stub): Ditto.
+ * irix5-nat.c (symbol_add_stub): Ditto.
+
+Thu Apr 27 14:07:16 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips-tdep.c, d10v-tdep.c: Include "arch-utils.h".
+
+Thu Apr 27 10:06:42 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Document IRIX X ARM cross compile problems.
+
+2000-04-26 Michael Snyder <msnyder@cygnus.com>
+
+ * utils.c (internal_verror): Call target_terminal_ours.
+ * wrapper.h: Fix minor comment typo.
+ * proc-api.c (write_with_trace): Change 'arg' from long to int.
+ Treat 'off_t' and 'size_t' as unsigned long in printfs.
+ (lseek_with_trace): Treat 'off_t' as unsigned long in printf.
+ * procfs.c (comments): Eliminate "???" in comments, which GCC
+ wants to interpret as a trigraph. (fill_gregset, supply_gregset,
+ fill_fpregset, supply_fpregset): Declare.
+ (procfs_wait): Sysargs is a long, change printf format to match.
+ (test-mapping, mapping_test, test_mapping_cmd) Remove (test only).
+
+2000-04-26 Kevin Buettner <kevinb@redhat.com>
+
+ * config/djgpp/fnchange.lst (ia64-linux-nat.c): Map to
+ ia64linux-nat.c.
+
+Wed Apr 26 13:50:35 2000 Philippe De Muyter <phdm@macqel.be>
+
+ * ax-gdb.c (agent_command): Remove now useless cast of
+ `free_current_contents' when passed to `make_cleanup'.
+ * coffread.c (coff_symfile_read): Ditto.
+ * dwarf2read.c (dwarf2_add_member_fn, read_array_type): Ditto.
+ (dwarf_decode_lines): Ditto.
+ * eval.c (parse_and_eval_address, parse_and_eval_address_1): Ditto.
+ (parse_and_eval, parse_to_comma_and_eval): Ditto.
+ * parse.c (parse_exp_1): Ditto.
+ * printcmd.c (print_command_1, output_command, set_command): Ditto.
+ (x_command, print_frame_args, printf_command): Ditto.
+ * top.c (execute_control_command): Ditto.
+ * tracepoint.c (validate_actionline): Ditto.
+ * typeprint.c (whatis_exp, ptype_command): Ditto.
+ (maintenance_print_type): Ditto.
+
+2000-04-26 Kevin Buettner <kevinb@redhat.com>
+
+ * Makefile.in (ALLDEPFILES): Add ia64-linux-tdep.c.
+ (ia64-linux-tdep.o): Add dependencies.
+ (ia64-tdep.o): Add dependency for arch-utils.h.
+ * ia64-linux-tdep.c, ia64-tdep.c (arch-utils.h): Include.
+
+2000-04-25 Michael Snyder <msnyder@cygnus.com>
+
+ * blockframe.c: Fix a minor typo in a comment.
+
+2000-04-25 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-tdep.c (examine_prologue): Recognize store instructions;
+ those whose source operands are input registers which haven't
+ been seen before are considered to be part of the prologue.
+
+Tue Apr 25 13:51:58 2000 glen mccready <gkm@pobox.com>
+
+ * rs6000-nat.c (xcoff_relocate_symtam): Recover from the wrong
+ patch being applied `Fri Apr 7 13:44:38 2000'.
+
+2000-04-24 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-linux-tdep.c: New file.
+ * ia64-tdep.c (elf-bfd.h): Include.
+ (ia64_linux_sigcontext_register_address): New extern declaration.
+ (struct gdbarch_tdep): New struct.
+ (SIGCONTEXT_REGISTER_ADDRESS): New define.
+ (read_sigcontext_register): New static function.
+ (extract_bit_field, replace_bit_field, slotN_contents,
+ replace_slotN_contents): Made static.
+ (ia64_frame_chain, ia64_frame_saved_pc, ia64_init_extra_frame_info):
+ Added new code for signal handler frames and call dummy frames.
+ (ia64_frame_init_saved_regs): Handle signal handler frames.
+ (ia64_find_saved_register): Removed.
+ (ia64_get_saved_register): Handle call dummy frames; reorganized
+ to call generic_get_saved_register() to find registers saved
+ in previous frames.
+ (process_note_abi_tag_sections): New static function.
+ (ia64_gdbarch_init): Attempt to determine the ABI/OS of the
+ executable. Based upon this information, set target dependent
+ field sigcontext_register_address appropriately. Also set
+ FRAME_CHAIN_VALID to be generic_func_frame_chain_valid.
+ * config/ia64/linux.mt (TDEPFILES): Add ia64-linux-tdep.o.
+ * config/ia64/tm-linux.h (IN_SIGTRAMP): Define.
+ (ia64_linux_in_sigtramp): New declaration.
+
+2000-04-23 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * TODO, NEWS: Update due to inclusion of gdbmi.texinfo in the GDB
+ manual.
+
+2000-04-23 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/djgpp/README: Explain how to unpack using djunpack.bat.
+
+Fri Apr 21 15:23:13 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * stabsread.c (REG_STRUCT_HAS_ADDR): Delete default.
+ (define_symbol): Check REG_STRUCT_HAS_ADDR_P before using
+ REG_STRUCT_HAS_ADDR.
+ (define_symbol): Ditto.
+
+ * valops.c (hand_function_call): Replace #ifdef
+ REG_STRUCT_HAS_ADDR with if REG_STRUCT_HAS_ADDR_P. Re-indent
+ affected code.
+
+ * gdbarch.sh (REG_STRUCT_HAS_ADDR): Add along with the predicate
+ function REG_STRUCT_HAS_ADDR_P.
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+2000-04-21 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb-stabs.h (SECT_OFF_MAX): Increase to 40.
+
+2000-04-21 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * win32-nat.c (handle_load_dll): Don't treat .text as a special
+ section anymore.
+ * somread.c (som_symfile_offsets): Ditto.
+ * somsolib.c (som_solib_add_solib_objfile): Ditto.
+
+Fri Apr 21 16:14:38 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Make Jimmy Guo TUI maintainer.
+
+Fri Apr 21 14:37:40 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * command.h (help_all): Delete declaration.
+ * command.c (help_all): Add declaration. Convert function
+ argument list to ISO-C.
+
+Thu Apr 20 18:15:08 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * d10v-tdep.c (d10v_gdbarch_init): Initialize stack_align.
+ (d10v_stack_align): Make static.
+ * config/d10v/tm-d10v.h (STACK_ALIGN): Delete.
+
+Thu Apr 20 14:35:46 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * valops.c (hand_function_call): Replace #ifdef STACK_ALIGN with
+ run-time test for STACK_ALIGN_P.
+ * gdbarch.sh: Add support for function and variable predicates.
+ (STACK_ALIGN): Add. Implement with predicate - STACK_ALIGN_P.
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+Thu Apr 20 17:39:11 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h, utils.c (free_current_contents): Change parameter to
+ void*.
+
+ From Philippe De Muyter <phdm@macqel.be>:
+ * printcmd.c (print_address_symbolic): Call `make_cleanup' with
+ `(free_current_contents, &x)', not `(free, x)'.
+ * utils.c (free_current_contents): Do not `free (NULL)'.
+
+ * printcmd.c (print_address_symbolic): Cleanup after a failed
+ call to build_address_symbolic.
+
+2000-04-20 Christopher Faylor <cgf@cygnus.com>
+
+ * wince-stub.c (FREE): New macro.
+ (mempool): Just free any buffer prior to reuse. Don't bother with
+ realloc.
+ (flag_single_step): New function.
+ (skip_message): Detect "helpful" Windows CE messages and skip sending
+ them to the host.
+ (wait_for_debug_event): Use skip_message to avoid sending debug
+ messages to the host.
+ (dispatch): Prelimary implementation of single step detection.
+ * wince.c: Rework SH single stepping code to be more consistent with
+ other wince targets.
+ (handle_output_debug_string): Allow first chance exceptions to come
+ through since they seem to be all that we get on some versions of
+ Windows CE.
+ (check_for_step): New function, conditionally compiled based on target.
+ (regptr): Delete obsolete function.
+ (handle_exception): Detect illegal instructions.
+ (get_child_debug_event): Return success only if event code matches
+ target.
+ (child_create_inferior): Reflect change to get_child_debug_event
+ arguments.
+
+2000-04-20 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c (thread_rec): Be more defensive about suspending already
+ suspended threads.
+ (safe_symbol_file_add_stub): New function.
+ (safe_symbole_file_add_cleanup): New function.
+ (safe_symbol_file_add): New function.
+ (handle_load_dll): Use wrapper to add DLL symbol information to avoid
+ bogus errors from non-stabs DLLs.
+ (handle_exception): Add work around for detection of first exception
+ breakpoint which does not seem to occur on W2K. Detect more "signals"
+ that can be effectively passed to the debuggee. Reorganize to eliminate
+ continue_status global.
+ (child_continue): Reorganize to eliminate continue_status global.
+ (child_wait): Ditto.
+ (child_resume): Ditto.
+ (get_child_debug_event): Ditto. Recognize when an a breakpoint
+ exception should be ignored. Change method for signalling when an
+ important event has occured to the caller.
+ (child_create_inferior): Use new method for noticing when
+ get_child_debug_event has found something interesting.
+
+Fri Apr 7 13:44:38 2000 glen mccready <gkm@pobox.com>
+
+ * rs6000-nat.c (xcoff_relocate_symtab): Grow buffer if ptrace()
+ fails due to lack of space.
+
+Fri Mar 24 12:10:38 2000 glen mccready <gkm@pobox.com>
+
+ * command.c, command.h (help_all): Add functionality to display
+ a complete listing of available commands.
+
+2000-04-20 Scott Bambrough <scottb@netwinder.org>
+
+ * arm-linux-nat.c (PIDGET, TIDGET): New.
+ (get_thread_id, GET_THREAD_ID): New.
+ (fetch_nwfpe_register, store_nwfpe_register): New.
+ (fetch_register, store_register): New.
+ (fetch_fpregister, store_fpregister): New.
+ (fill_gregset, supply_gregset): New.
+ (fill_fpregset, supply_fpregset): New.
+ (fetch_fpregs): Modified to use thread id's.
+ (store_fpregs): Modified to use thread id's and
+ fetch_nwfpe_register.
+ (fetch_regs): Modified to use thread id's.
+ (store_regs): Modified to use thread id's.
+ (fetch_inferior_registers): Modified to handle single register
+ fetches.
+ (store_inferior_registers): Modified to handle single register
+ stores.
+ (arm_linux_register_u_addr): Removed.
+
+ * configure.tgt: Added gdbserver to configdirs for arm*-*-linux*.
+
+ * config/arm/linux.mh
+ (NATDEPFILES): Removed core-aout.o. Added core-regset.o.
+ (LOADLIBES): Define.
+
+ * config/arm/nm-linux.h: Include config/nm-linux.h.
+ (ATTACH_DETACH): Removed. Defined in config/nm-linux.h.
+ (REGISTER_U_ADDR): Removed.
+ (SVR4_SHARED_LIBS): Removed. Defined in config/nm-linux.h.
+ (#include "solib.h"): Removed. Included via config/nm-linux.h.
+
+Thu Apr 20 18:54:15 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Daniel Berlin <dan@cgsoftware.com> and Tim Mooney
+ <mooney@dogbert.cc.ndsu.nodak.edu>:
+ * infrun.c (follow_fork_mode_kind_names): NULL terminate
+ array. Re-indent.
+ (scheduler_enums): Ditto.
+
+Mon Apr 17 13:37:10 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh: Make multi-arch variable defaults, defaults for non-
+ multi-arch targets.
+ (TARGET_BFD_VMA_BIT, IEEE_FLOAT, CALL_DUMMY_WORDS,
+ SIZEOF_CALL_DUMMY_WORDS): Update.
+
+ * inferior.h (CALL_DUMMY_WORDS, SIZEOF_CALL_DUMMY_WORDS): Default
+ provided by gdbarch.
+ (CALL_DUMMY_P): Add FIXME. gdbarch should provide default.
+
+ * valprint.c (IEEE_FLOAT): Default provided by gdbarch.
+
+2000-04-19 Jim Blandy <jimb@redhat.com>
+
+ Bring RETURN_VALUE_ON_STACK under gdbarch's control.
+ * gdbarch.sh (RETURN_VALUE_ON_STACK): New entry.
+ * gdbarch.c, gdbarch.h: Regenerated.
+ * arch-utils.c (default_return_value_on_stack): New function.
+ * arch-utils.h (default_return_value_on_stack): New declaration.
+ * values.c (RETURN_VALUE_ON_STACK): Delete default definition.
+
+ * i386v-nat.c (i386_insert_nonaligned_watchpoint): Use a
+ two-dimensional array, instead of faking it with explicit index
+ arithmetic.
+
+ * minsyms.c (prim_record_minimal_symbol_and_info): Doc fix.
+ (Thanks to Guy Harris.)
+
+2000-04-19 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * xcoffsolib.c (solib_add): Fix call to vmap_symtab().
+
+2000-04-19 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * TODO: Update.
+
+Wed Apr 19 19:10:07 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Document -Wreturn-type problem.
+
+2000-03-27 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * maint.c (_initialize_maint_cmds): Add `mt i' alias for `mt info'.
+
+2000-03-27 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * infcmd.c (_initialize_infcmd): Add `info r' alias for
+ `info registers'.
+
+Wed Apr 19 17:03:07 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Philippe De Muyter <phdm@macqel.be>:
+ * bcache.c (free_bcache): Do not free NULL.
+
+Wed Apr 19 16:37:47 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Cleanup.
+ * NEWS: Update GDB version. Duplicate paragraph explaining
+ obsolete.
+
+Wed Apr 19 13:06:55 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (distclean): Delete tui/Makefile.
+ * TODO: Add deletion of tui/Makefile.in to list.
+
+2000-04-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * symfile.h (struct section_addr_info ): Remove fields for special
+ treatment of .text, .data and .bss sections.
+
+ * solib.c (symbol_add_stub): The special field text_addr is not
+ available anymore. Search for the .text field the hard way.
+
+ * symfile.c (build_section_addr_info_from_section_table): Don't
+ fill in {text, data, bss}_addr any more.
+ (default_symfile_offsets): Don't use {text, data, bss}_addr fields
+ to fill in section_offsets for objfile.
+ (syms_from_objfile): Don't deal with {text, data, bss}_addr as a
+ special case anymore.
+ (add_symbol_file_command): Ditto.
+
+2000-04-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ symfile.c: (symbol_file_command): Remove support for rombug, to
+ simplify code.
+
+2000-04-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * symfile.c (add_symbol_file_command): Rewrite the arguments
+ processing part. Simplify syntax of command. Remove support for
+ rombug.
+ (_initialize_symfile): Update help message for add-symbol-file
+ command.
+
+Mon Apr 17 15:53:38 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh (IEEE_FLOAT): Only dump when defined.
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+Mon Apr 17 11:26:01 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (REMOTE_TRANSLATE_XFER_ADDRESS), mem-break.c
+ (MEMORY_INSERT_BREAKPOINT, MEMORY_REMOVE_BREAKPOINT), target.h
+ (BREAKPOINT_FROM_PC), valops.c (COERCE_FLOAT_TO_DOUBLE),
+ gdbarch.sh (D10V_MAKE_DADDR, D10V_MAKE_IADDR,
+ FRAMELESS_FUNCTION_INVOCATION, REGISTER_CONVERTIBLE,
+ REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW,
+ REGISTER_NAME), findvar.c (POINTER_TO_ADDRESS,
+ ADDRESS_TO_POINTER): Delete default definition. Handled by
+ gdbarch.
+
+ * gdbarch.sh: Make multi-arch defaults, defaults for non-
+ multi-arch targets.
+ (REGISTER_NAME, COERCE_FLOAT_TO_DOUBLE, REGISTER_CONVERTIBLE,
+ REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW,
+ D10V_MAKE_DADDR, D10V_MAKE_IADDR, BREAKPOINT_FROM_PC,
+ MEMORY_INSERT_BREAKPOINT, MEMORY_REMOVE_BREAKPOINT,
+ REMOTE_TRANSLATE_XFER_ADDRESS, FRAMELESS_FUNCTION_INVOCATION):
+ Provide default/legacy implementation.
+ (REGISTER_NAMES, CALL_DUMMY): Allow legacy definition.
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+2000-04-16 Jim Blandy <jimb@redhat.com>
+
+ * findvar.c (store_typed_address, extract_typed_address): Fix
+ function names in error messages.
+
+2000-04-16 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/djgpp/config.sed: Fix the lines which edit clean: and
+ uninstall-info: targets.
+
+2000-04-14 Jim Blandy <jimb@redhat.com>
+
+ Bring IEEE_FLOAT under gdbarch's control.
+ * gdbarch.sh (IEEE_FLOAT): New entry.
+ * gdbarch.c, gdbarch.h: Regenerated.
+ * valprint.c (IEEE_FLOAT): Provide a default #definition for this.
+ (print_floating): Use IEEE_FLOAT as if it were an expression; use
+ the code specific to IEEE-format numbers whenever the value of
+ IEEE_FLOAT is non-zero.
+ * config/a29k/tm-a29k.h, config/alpha/tm-alpha.h,
+ config/arc/tm-arc.h, config/arm/tm-arm.h, config/fr30/tm-fr30.h,
+ config/h8300/tm-h8300.h, config/i386/tm-i386.h,
+ config/i960/tm-i960.h, config/m88k/tm-m88k.h,
+ config/mips/tm-mips.h, config/pa/tm-hppa.h,
+ config/sparc/tm-sparc.h (IEEE_FLOAT): For all ports that #define
+ IEEE_FLOAT, make sure they give it the value (1).
+
+ Provide the hooks needed to support architectures on which
+ pointers are not always simple byte addresses.
+
+ * gdbarch.sh (POINTER_TO_ADDRESS, ADDRESS_TO_POINTER): Two new
+ functions which architectures can redefine, defaulting to
+ generic_pointer_to_address and generic_address_to_pointer.
+ * findvar.c (extract_typed_address, store_typed_address,
+ generic_pointer_to_address, generic_address_to_pointer): New
+ functions.
+ (POINTER_TO_ADDRESS, ADDRESS_TO_POINTER): Provide default
+ definitions.
+ (extract_address, store_address): Doc fixes.
+ * values.c (value_as_pointer): Doc fix.
+ (value_from_pointer): New function.
+ * defs.h (extract_typed_address, store_typed_address): New
+ declarations.
+ * inferior.h (generic_address_to_pointer,
+ generic_pointer_to_address): New declarations.
+ * value.h (value_from_pointer): New declaration.
+
+ The following changes are all of the general form "Use these
+ functions instead of these other functions." In each case, the
+ change is because the new calls provide enough information to do
+ the appropriate address / pointer conversions, where the old calls
+ did not, or because the new functions are more appropriately named
+ for the operation being performed.
+
+ * ax-gdb.c (const_var_ref): Use value_from_pointer, not
+ value_from_longest.
+ * blockframe.c (generic_push_dummy_frame): Use read_pc and
+ read_sp, not read_register.
+ * c-valprint.c (c_val_print): Use extract_typed_address instead of
+ extract_address to extract vtable entries and references.
+ * cp-valprint.c (cp_print_value_fields): Use value_from_pointer
+ instead of value_from_longest to extract the vtable's address.
+ * eval.c (evaluate_subexp_standard): Use value_from_pointer
+ instead of value_from_longest to compute `this', and for doing
+ pointer-to-member dereferencing.
+ * findvar.c (read_register): Use extract_unsigned_integer, not
+ extract_address.
+ (read_var_value): Use store_typed_address instead of store_address
+ for building label values.
+ (locate_var_value): Use value_from_pointer instead of
+ value_from_longest.
+ * hppa-tdep.c (find_stub_with_shl_get): Use value_from_pointer,
+ instead of value_from_longest, to build arguments to __d_shl_get.
+ * printcmd.c (set_next_address): Use value_from_pointer, not
+ value_from_longest.
+ (x_command): Use value_from_pointer, not value_from_longest.
+ * tracepoint.c (set_traceframe_context): Use value_from_pointer,
+ not value_from_longest.
+ * valarith.c (value_add, value_sub): Use value_from_pointer, not
+ value_from_longest.
+ * valops.c (find_function_in_inferior, value_coerce_array,
+ value_coerce_function, value_addr, hand_function_call): Same.
+ * value.h (COERCE_REF): Use unpack_pointer, not unpack_long.
+ * values.c (unpack_long): Use extract_typed_address to produce
+ addresses from pointers and references, not extract_address.
+ (value_from_longest): Use store_typed_address instead of
+ store_address to produce pointer and reference values.
+
+2000-04-13 Mark Kettenis <kettenis@gnu.org>
+
+ * acconfig.h (HAVE_PRGREGSET_T, HAVE_PRFPREGSET_T, HAVE_LWPID_T,
+ HAVE_PSADDR_T): Add them here instead of in config.in.
+
+ * acconfig.h (PRFPREGSET_T_BROKEN): New define.
+ * configure.in: Add check for broken prfpregset_t type.
+ * lin-thread.c (gdb_prfpregset): New typedef, depends on
+ definition of PRFPREGSET_T_BROKEN.
+ (ps_lgetfpregs, ps_lsetfpregs, p_td_thr_getfpregs,
+ p_td_thr_setfpregs, thread_db_fetch_registers,
+ thread_db_store_registers): Use gdb_prfpregset_t instead of
+ prfpregset_t.
+ * config.in: Regenerated.
+ * configure: Regenerated.
+
+2000-04-13 DJ Delorie <dj@cygnus.com>
+
+ * mips-tdep.c (do_fp_register_row): copy the number of bytes
+ allocated, not the size of the pointer.
+
+2000-04-13 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * config/i386/nm-i386sol2.h (CANNOT_STEP_HW_WATCHPOINTS): Define.
+ * config/i386/tm-i386sol2.h (HAVE_I387_REGS): Define.
+ * i386v4-nat.c (supply_fpregset, fill_fpregset): Add code
+ to handle floating point registers if NUM_FREGS is not zero.
+
+2000-04-13 Nick Duffek <nsd@cygnus.com>
+
+ * sol-thread.c (init_sol_core_ops): Initialize to_thread_alive
+ and document to_find_new_threads bug.
+
+2000-04-13 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * infrun.c (proceed, normal_stop): Change the error message about
+ failure to insert breakpoints/watchpoints so that it makes sense
+ even if ptrace is not used or no other processes can be active.
+
+Thu Apr 13 13:24:27 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in: Add --enable-maintainer-mode.
+ * aclocal.m4, configure: Re-generate.
+
+ * Makefile.in ($(srcdir)/copying.c): Enable dependencies only when
+ on maintainer-mode. Update copying.c in source directory.
+ (copying.txt): Delete rule.
+ (copying.o): Add explict paths to $(srcdir) and explicit make
+ rule.
+
+2000-04-12 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-linux-nat.c (IA64_PSR_DB, IA64_PSR_DD): Define.
+ (fetch_debug_register, fetch_debug_register_pair,
+ store_debug_register, store_debug_register_pair, is_power_of_2,
+ enable_watchpoints_in_psr, ia64_linux_insert_watchpoint,
+ ia64_linux_remove_watchpoint, ia64_linux_stopped_by_watchpoint):
+ New functions.
+ * config/ia64/nm-linux.h (TARGET_HAS_HARDWARE_WATCHPOINTS,
+ TARGET_CAN_USE_HARDWARE_WATCHPOINT, HAVE_STEPPABLE_WATCHPOINT,
+ STOPPED_BY_WATCHPOINT, target_insert_watchpoint,
+ target_remove_watchpoint): Define.
+ (ia64_linux_stopped_by_watchpoint, ia64_linux_insert_watchpoint,
+ ia64_linux_remove_watchpoint): Declare.
+
+2000-04-12 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c (go32_insert_hw_breakpoint): When there are no more
+ hardware breakpoint resources, return EBUSY.
+ (go32_handle_nonaligned_watchpoint): If the argument WHAT is not
+ one of the enumerated values, return EINVAL.
+
+2000-04-12 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * README: Mention special build instructions for DJGPP.
+ * NEWS: Update with FP features on x87 platforms, and
+ DJGPP-related changes.
+
+2000-04-12 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * top.c (gdb_completer_file_name_break_characters): New variable.
+ (line_completion_function): When completing on file names, use
+ gdb_completer_file_name_break_characters as word break
+ characters for the readline library.
+
+2000-04-12 Mark Kettenis <kettenis@gnu.org>
+
+ * i387-tdep.c (print_i387_value): Avoid call to
+ floatformat_to_doublest if long double type is the same on host
+ and target.
+
+2000-04-11 Fernando Nasser <fnasser@cygnus.com>
+
+ * wrapper.h: Remove definitions of internal functions.
+ * wrapper.c: Remove definitions of exported functions (which are
+ already in wrapper.h) and make static all internal wrap_* functions.
+
+Mon Apr 10 21:58:36 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * acconfig.h (USE_INCLUDED_REGEX): Add.
+ * Makefile.in (REGEX_CFLAGS): Delete
+ * configure.in (REGEX_CFLAGS): Delete. Use AC_DEFINE instead.
+ * configure, config.in: Re-generate.
+
+2000-04-10 Philip Blundell <philb@gnu.org>
+
+ * arm-linux-nat.c (arm_skip_solib_resolver): Remove and move to
+ arm-linux-tdep.c.
+ * arm-linux-tdep.c (arm_skip_solib_resolver): New.
+
+2000-04-10 Fernando Nasser <fnasser@cygnus.com>
+
+ From 2000-04-10 Rodney Brown <rdb@redhat.com>:
+ * command.h (enum command_class): Remove trailing "," to placate
+ AIX xlc.
+
+Mon Apr 10 20:17:32 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO, NEWS: Update. Mention MI.
+
+Mon Apr 10 00:21:09 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch-utils.h, gdbarch-utils.c: Delete.
+ * arch-utils.h, arch-utils.c: New files. Avoid 14 character file
+ name problems.
+ * Makefile.in: Update.
+ * gdbarch.c: Update.
+
+Sun Apr 9 23:42:16 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-04-07 Jonathan Larmour <jlarmour@redhat.co.uk>:
+ * mips-tdep.c (saved_gpreg_size_enums): Define enum command for
+ new "set mips saved-gpreg-size" command
+ (MIPS_SAVED_REGSIZE): Now a function mips_saved_regsize()
+ (MIPS_DEFAULT_SAVED_REGSIZE): Define for default MIPS_SAVED_REGSIZE,
+ either from target, or gdb multi-arch
+ (show_mips_command): New. For "show mips" prefix command
+ (set_mips_command): New. For "show mips" prefix command
+ (_initialize_mips_tdep): Add top-level mips prefix command
+ Add "set mips saved-gpreg-size" command
+
+ * mips-tdep.c (struct gdbarch_tdep): Rename mips_saved_regsize to
+ mips_default_saved_regsize.
+ (mips_gdbarch_init): Update.
+ (MIPS_DEFAULT_SAVED_REGSIZE): Update.
+ (mips_gdbarch_init): Use MIPS_REGSIZE as the default value for
+ mips_default_saved_regsize.
+
+Sun Apr 9 23:27:00 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-04-07 J.T. Conklin <jtc@redback.com>:
+ * lynx-nat.c (fetch_inferior_registers, store_inferior_registers):
+ replace calls to target_xfer_memory() with target_read_memory()
+ and target_write_memory().
+
+Sun Apr 9 22:54:29 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * valops.c (value_rtti_type): Compare VALUE_ADDRESS with ``0'' not
+ NULL. Macro returns a CORE_ADDR.
+
+2000-04-08 Jim Blandy <jimb@redhat.com>
+
+ * dwarf2read.c: Revert Andrew Cagney's change of Dec 15, 1997.
+ Don't include "bfd-elf.h".
+ (address_significant_size): Delete variable.
+ (dwarf2_build_psymtabs_hard): Don't set it, or check for
+ consistency between it and the Dwarf 2 compilation unit header
+ address size.
+ (read_address): Don't mask off bits above
+ address_significant_size.
+ * Makefile.in (dwarf2read.o): Don't depend on $(elf_bfd_h).
+ (elf_bfd_h): Remove variable; it's no longer used.
+
+2000-04-08 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * configure.in (NEW_PROC_API): Escape square brackets when testing
+ for solaris2.[678].
+ * configure: Regenerate.
+
+2000-04-07 Scott Bambrough <scottb@netwinder.org>
+
+ * ChangeLog: Correct date on last entry.
+ * arm-linux-tdep.c (arm_linux_push_arguments): New function.
+ * config/arm/tm-linux: Redefined PUSH_ARGUMENTS for Linux.
+ * config/arm/tm-embed: Fix build warning from redefinition of
+ LOWEST_PC.
+ * config/arm/tm-arm.h: Remove TARGET_BYTE_ORDER_SELECTABLE.
+ * config/arm/tm-wince.h: Remove TARGET_BYTE_ORDER_SELECTABLE and
+ TARGET_BYTE_ORDER. Add TARGET_BYTE_ORDER_SELECTABLE_P to
+ override default in tm-arm.h. Use default target byte order
+ from tm-arm.h.
+
+2000-04-07 Scott Bambrough <scottb@netwinder.org>
+
+ * Makefile.in: Add dependency information for arm-linux-tdep.c.
+ * config/djgpp/fnchange.lst: Add arm-linux-tdep.c, arm-linux-nat.c.
+
+2000-04-07 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * sol-thread.c (gdb_ps_addr_t): New typedef, depends on definition
+ of PROC_SERVICE_IS_OLD.
+ (ps_pglobal_lookup, ps_pdread, ps_pdwrite, ps_ptread, ps_ptwrite,
+ rw_common): Change argument type from psaddr_t to gdb_ps_addr_t.
+
+Fri Apr 7 17:18:42 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (CFLAGS): Set using configure.
+
+ * configure.in (WARN_CFLAGS): Enable by default when GCC.
+ * configure: Re-generate.
+
+Fri Apr 7 13:33:43 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-03-27 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>:
+ * procfs.c (init_procfs_ops): Set procfs_ops.to_has_memory and
+ procfs_ops.to_has_all_memory to 1.
+
+ * TODO: Update
+
+2000-04-06 Nick Duffek <nsd@cygnus.com>
+
+ * configure.in (_MSE_INT_H): Define on Solaris 7.
+ (NEW_PROC_API): Define on Solaris 7 and 8 as well as 6.
+ * acconfig.h (_MSE_INT_H): Define on Solaris 7.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+
+2000-04-06 Michael Snyder <msnyder@cygnus.com>
+
+ * sol-thread.c (GET_LWP, GET_THREAD, BUILD_LWP, BUILD_THREAD):
+ Change to rely on PIDGET etc.
+ * config/i386/nm-i386sol2.h (TARGET_HAS_WATCHPOINTS,
+ TARGET_CAN_USE_HARDWARE_WATCHPOINT, HAVE_CONTINUABLE_WATCHPOINT,
+ STOPPED_BY_WATCHPOINT, target_[insert/remove]_watchpoint):
+ define. Allow target to use procfs hardware watchpoints.
+ * config/sparc/nm-sun4sol2.h: ditto.
+ * config/i386/tm-i386sol2.h (PIDGET, TIDGET, MERGEPID): modify
+ definitions to use 16 bits for the pid, 15 bits for the tid, and
+ 1 bit for the flag.
+ * config/sparc/tm-sun4sol2.h: ditto.
+ (SOFTWARE_SINGLE_STEP, SOFTWARE_SINGLE_STEP_P): undefine.
+ * testsuite/gdb.threads/pthreads.exp (all_threads_running): Allow
+ for more than 15 thread increments.
+
+2000-04-06 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * top.c (filename_completer): Set subsequent_name to 1 early on,
+ to prevent an infinite loop if the first file in the directory is
+ a backup file (whose name ends in a `~').
+
+2000-04-05 Jim Blandy <jimb@redhat.com>
+
+ * solib.c (update_solib_list): New function.
+ (solib_add): Call update_solib_list, and then read symbols.
+ (info_sharedlibrary_command): Call update_solib_list, not
+ solib_add.
+
+2000-04-05 Scott Bambrough <scottb@netwinder.org>
+
+ * arm-linux-tdep.c: Resolve implicit function declarations by
+ including target.h and value.h. Inclusion of symtab.h is
+ no longer needed.
+
+2000-04-05 Scott Bambrough <scottb@netwinder.org>
+
+ * arm-linux-tdep.c: New file.
+ * arm-linux-nat.c (fetch_fpregs): Remove unused code.
+ (arm_get_longjmp_target): Moved it and all defines
+ it uses to arm-linux-tdep.c.
+ (arm_linux_extract_return_value): Moved to
+ arm-linux-tdep.c.
+ * config/arm/linux.mt: Add arm-linux-tdep.c to TDEPFILES.
+
+2000-04-04 Nick Duffek <nsd@cygnus.com>
+
+ * infrun.c (handle_inferior_event): Call target_mourn_inferior
+ instead of kill_target.
+
+2000-04-04 Daniel Berlin <dan@cgsoftware.com>
+
+ * TODO: Make note of various C++ things i have planned for 5.1.
+
+Tue Apr 4 12:13:19 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * printcmd.c (print_scalar_formatted): Use local variable ptr_bit
+ in shift. Stop GCC thinking it has a shift overflow.
+
+2000-04-03 H.J. Lu <hjl@gnu.org>
+
+ * TODO: Remove the regex entry.
+
+2000-04-03 H.J. Lu <hjl@gnu.org>
+
+ * gdb_regex.h: New. Include "regex.h" if USE_INCLUDED_REGEX
+ is defined and <regex.h> otherwise.
+
+ * irix5-nat.c: Include "gdb_regex.h" instead of "gnu-regex.h".
+ * monitor.c: Likewise.
+ * osfsolib.c: Likewise.
+ * solib.c: Likewise.
+ * source.c: Likewise.
+ * symtab.c: Likewise.
+
+ * Makefile.in (REGEX): Changed to @REGEX@.
+ (REGEX_CFLAGS): New.
+ (REGEX1): Removed.
+ (ADD_DEPS): Use $(REGEX) instead of $(REGEX1).
+ (INTERNAL_WARN_CFLAGS): Add $(REGEX_CFLAGS).
+
+ * configure.in (--with-included-regex): New switch.
+ (REGEX): New. Subsstitue @REGEX@ in Makefile.in.
+ (REGEX_CFLAGS): New. Subsstitue @REGEX_CFLAGS@ in Makefile.in.
+ * configure: Regenerated.
+
+2000-04-03 Kevin Buettner <kevinb@redhat.com>
+
+ * NEWS (powerpc-*-linux*): Mention.
+
+2000-04-03 J.T. Conklin <jtc@redback.com>
+
+ * config/i386/xm-nbsd.h (HOST_LONG_DOUBLE_FORMAT): Define.
+
+2000-04-03 Kevin Buettner <kevinb@redhat.com>
+
+ * Makefile.in (ALLDEPFILES): Add ia64-linux-nat.c and ia64-tdep.c.
+ (ia64-linux-nat.o, ia64-tdep.o): Add dependencies.
+
+ * ia64-linux-nat.c (fill_gregset): Implement.
+ (supply_fpregset, fill_fpregset): New functions.
+
+ * ia64-tdep.c (ia64_init_extra_frame_info): Revise manner in
+ which the CFM is fetched for certain frames.
+ (find_global_pointer, find_extant_func_descr): Don't use
+ partial symtabs for locating sections.
+
+ * config/ia64/linux.mh (LOADLIBES): Define.
+ (NATDEPFILES): Add linux-thread.o and lin-thread.o.
+ * config/ia64/nm-linux.h (nm-linux.h): Include this upper-level
+ file containing generic linux declarations/definitions.
+ (SVR4_SHARED_LIBS, ATTACH_DETACH): Remove defines; already
+ defined in generic nm-linux.h.
+ (solib.h): Remove include; already included in generic nm-linux.h.
+
+2000-04-03 Jim Blandy <jimb@redhat.com>
+
+ * solib.c (solib_add): Move all the code for loading symbol tables
+ below the code to sort out additions and removals. That way, we
+ always catch all loaded shared libraries whose symbols we haven't
+ grabbed yet.
+
+ * solib.c (solib_add): Don't try to free a shared object's objfile
+ if it doesn't have one. Duh.
+
+ * solib.c (solib_add): If a pattern was given, but it doesn't
+ match any currently loaded shared libraries, print a message;
+ don't just be silent.
+
+2000-04-03 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c (go32_handle_nonaligned_watchpoint): Use a
+ two-dimensional array instead of faking it with index
+ arithmetics.
+
+2000-04-03 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/i386/xm-go32.h (HOST_LONG_DOUBLE_FORMAT): Define.
+
+ * config/i386/tm-go32.h (TARGET_LONG_DOUBLE_BIT): Remove
+ definition (and use the common one in tm-i386.h).
+ (REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW): Likewise.
+ (I386_DJGPP_TARGET): Don't define, it's no longer required.
+ (LOW_RETURN_REGNUM, HIGH_RETURN_REGNUM): Remove definition,
+ i386-tdep.c defines it for all x86 targets.
+ (LD_I387, HEX_LONG_DOUBLE_INPUT): Remove.
+
+ * config/djgpp/fnchange.lst: Add i386-linux-tdep.c.
+
+ * config/djgpp/djcheck.sh: Edit the copyright year out of the test
+ results. Fix editing of `main' arguments for non-GNU Sed.
+
+2000-04-03 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * symfile.c (map_overlay_command, unmap_overlay_command): Fix
+ error message: there's no "overlay on" command.
+
+2000-04-03 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * Makefile.in (copying.c): Depend on copying.txt, not COPYING.
+ (copying.txt): New target, a link to COPYING.
+
+Mon Apr 3 18:20:03 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Update.
+
+Mon Apr 3 14:56:11 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c: Re-indent.
+ (set_hook, error_hook): Remove PARAMS.
+
+Mon Apr 3 14:45:25 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * symtab.h (add_minsym_to_demangled_hash_table): Revert 2000-03-29
+ Daniel Berlin <dan@cgsoftware.com>. Function was static.
+ * minsyms.c (add_minsym_to_demangled_hash_table): Add prototype.
+
+Mon Apr 3 14:10:37 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb-events.h, gdb-events.c, gdb-events.sh: Re-indent.
+
+2000-04-02 Nick Duffek <nsd@cygnus.com>
+
+ * gdbtypes.c (safe_parse_type): New wrapper function to ignore
+ error() during parse_and_eval_type().
+ (check_stub_method): Call safe_parse_type instead of
+ parse_and_eval_type().
+ * wrapper.c (gdb_parse_and_eval_type): New wrapper function.
+ (wrap_parse_and_eval_type): New support function.
+ * wrapper.h (gdb_parse_and_eval_type): Prototype.
+ (wrap_parse_and_eval_type): Prototype.
+
+Sun Apr 2 10:32:54 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Eli Zaretskii is a doco maintainer.
+
+Fri Mar 31 08:59:58 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch-utils.h, gdbarch-utils.c: New files.
+ * Makefile.in (SFILES, COMMON_OBS): Update.
+ (gdbarch_utils_h) Define.
+ (gdbarch-utils.o): Add dependencies.
+
+ * gdbarch.c, gdbarch.sh: Include "gdbarch-utils.h". Fix code
+ handling default method values.
+ (startup_gdbarch): Rename default_gdbarch, name misleading.
+ (breakpoint_from_pc): Default to legacy_breakpoint_from_pc.
+ (register_name): Default to legacy_register_name.
+ (call_dummy_words): Default to legacy_call_dummy_words.
+ (sizeof_call_dummy_words): Default to
+ legacy_sizeof_call_dummy_words.
+ (register_convertible): Default to
+ generic_register_convertible_not.
+ (breakpoint_from_pc): Default to legacy_breakpoint_from_pc.
+ (remote_translate_xfer_address): Default to
+ generic_remote_translate_xfer_address.
+ (frameless_function_invocation): Default to
+ generic_frameless_function_invocation_not.
+
+2000-04-02 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-linux-nat.c: Add copyright notice.
+
+ * config/i386/xm-linux.h (HOST_LONG_DOUBLE_FORMAT): Define as
+ &floatformat_i387_ext.
+ * config/i386/xm-i386gnu.h (HOST_LONG_DOUBLE_FORMAT): Likewise.
+
+2000-03-29 Mark Kettenis <kettenis@gnu.org>
+
+ * findvar.c (extract_floating): Remove reference to
+ TARGET_EXTRACT_FLOATING.
+ (store_floating): Remove reference to TARGET_STORE_FLOATING.
+
+2000-03-30 Fernando Nasser <fnasser@cygnus.com>
+
+ * wrapper.c (gdb_value_subscript, wrap_value_subscript): New functions.
+ Safe version of value_subscript.
+ * varobj.c (): Use gdb_value_subscript() to get an array element value.
+
+2000-03-30 Michael Snyder <msnyder@cygnus.com>
+
+ * ui-file.c: Include "gdb_string.h"
+ * cli-out.c: Include gdb_string.h to avoid compiler warnings.
+ * wrapper.[ch] (struct gdb_wrapper_arguments): Change fields into
+ unions, since they are all used to hold both pointers and ints
+ at various times. Casting pointer to int and vice versa gives
+ warnings (and is not safe) if they are not the same size.
+
+2000-03-30 Michael Snyder <msnyder@cygnus.com>
+
+ * defs.h (struct continuation_arg): Make 'data' a union, to avoid
+ casting problems when int and pointer are not the same size.
+ * event-top.c (command_handler): Use data as a union.
+ (command_line_handler_continuation): Ditto.
+ * infcmd.c (step_1_continuation): Use data as a union. Re-indent.
+ (step_once): ditto. (finish_command_continuation): Ditto.
+ (finish_command): Ditto.
+ * breakpoint.c (until_break_command): Use data as a union.
+ (until_break_command_continuation): Ditto.
+ * utils.c (add_intermediate_continuation): Fix typo in comment.
+
+Thu Mar 30 12:09:50 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.h, gdbarch.c: Re-indent. Remove FIXMEs.
+ * gdbarch.sh: Re-sync with gdbarch.[hc].
+
+2000-03-29 Daniel Berlin <dan@cgsoftware.com>
+
+ * minsyms.c (add_minsym_to_demangled_hash_table): New function.
+ (install_minimal_symbols): Fix demangled symbol problems caused by
+ using add_minsym_to_hash_table for the demangled names, which is
+ wrong. Now we use add_minsym_to_demangled_hash_table.
+ (lookup_minimal_symbol): Fix problems with demangled symbol lookup
+ caused by weird control flow.
+ * symtab.h: Add add_minsym_to_demangled_hash_table prototype here.
+
+2000-03-29 Jason Merrill <jason@casey.cygnus.com>
+
+ * configure.in: -linux-gnu*, not -linux-gnu.
+
+Tue Mar 28 18:28:40 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.c (remote_threads_extra_info): Replace qfThreadExtraInfo
+ with qThreadExtraInfo.
+
+2000-03-29 J.T. Conklin <jtc@redback.com>
+
+ * i386nbsd-nat.c (fetch_core_registers): Make static.
+
+ * m68knbsd-nat.c (fetch_core_registers): Make static.
+ (m68knbsd_core_fns, _initialize_m68knbsd_nat): Added.
+
+Wed Mar 29 13:40:40 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Update GDB 5 status.
+
+Wed Mar 29 10:16:35 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * breakpoint.h (remove_hw_watchpoints): Add declaration.
+ * breakpoints.c (remove_hw_watchpoints): Update.
+ * maint.c (maintenance_do_deprecate): Avoid assignment within IF
+ condition.
+
+2000-03-28 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ breakpoint.c, breakpoint.h (remove_hw_watchpoints): New function.
+ infrun.c (resume): Remove hardware watchpoints before stepping
+ when CANNOT_STEP_HW_WATCHPOINTS is nonzero.
+
+2000-03-28 Michael Snyder <msnyder@cygnus.com>
+
+ * Makefile.in: Anchor tui-file.h dependency to $srcdir.
+
+2000-03-28 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * procfs.c (proc_set_watchpoint): Declare addr parameter as
+ CORE_ADDR, to match call from procfs_set_watchpoint.
+
+ * breakpoint.c (insert_breakpoints, do_enable_breakpoint):
+ Reselect the saved frame silently after frame selection for
+ watchpoint evaluation.
+ (insert_breakpoints): Add missing space in `Hardware watchpoint
+ deleted' message. Do not reinsert hardware watchpoint if it is
+ already marked for deletion at next stop.
+
+2000-03-28 Christopher Faylor <cgf@cygnus.com>
+
+ * partial-stab.h: Add one more check against corrupted or irregular
+ stabs entry.
+
+Tue Mar 28 12:23:37 2000 Philippe De Muyter <phdm@macqel.be>
+
+ * gnu-regex.c (regerror): Function renamed from `__regerror'.
+ (Change also approved in the mainline glibc sources)
+
+Tue Mar 28 18:19:50 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-03-20 Jonathan Larmour <jlarmour@redhat.co.uk>:
+ * ser-unix.c (do_unix_readchar): Reorganise to be more robust,
+ particularly ensuring it can't return SERIAL_TIMEOUT when told
+ not to time out.
+
+2000-03-24 Daniel Berlin <dan@cgsoftware.com>
+
+ * gdbtypes.c (_initialize_gdbtypes): Add "set debug overload",
+ which never existed before, and thus, has no deprecated old command.
+
+ * gdbarch.c (_initialize_gdbarch): Add "set debug arch", deprecate
+ "set archdebug" (same goes for the show commands).
+ * gdb-events.c (_initialize_gdb_events): Add "set debug event",
+ deprecate "set eventdebug" (same goes for the show commands).
+ * gdbcmd.h: Add the setdebuglist and showdebuglist externs.
+ * top.c (init_main): Deprecate remotedebug, use "set/show debug remote"
+ instead.
+ x(init_main): Add the "set debug" and "show debug" commands.
+ Add setdebuglist and showdebuglist.
+
+Fri Mar 24 13:00:10 2000 Daniel Berlin <dan@cgsoftware.com>
+
+ * maint.c (maintenance_do_deprecate): Fix crash if you call with no arguments, and fixed the warning.
+ Added prototype for the deprecate command so it doesn't complain.
+
+Tue Mar 28 11:52:45 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c (print_gdb_version): Bump copyright year to 2000.
+
+Tue Mar 28 10:13:11 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Add Glen McCready to write after approval list.
+
+Tue Mar 28 09:59:00 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * acconfig.h: Fix typo in comment describing HAVE_PTRACE_GETREGS.
+ * config.h: Regenerate.
+
+Mon Mar 27 19:53:29 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * TODO: Update. Add criteria for next release of GDB.
+
+Mon Mar 27 17:20:25 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * acconfig.h: Provide default for HAVE_PTRACE_GETREGS.
+ * config.h: Regenerate.
+
+Mon Mar 27 16:43:35 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (install-only): Create $(bindir) and $(man1dir)
+ before installing GDB.
+
+Mon Mar 27 16:26:11 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (all-gdbtk): Check for an existing link/directory.
+ Re-format warning message. Document that post 5.0 this can be
+ deleted.
+
+Mon Mar 27 14:46:37 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ChangeLog: Revert whitespace changes.
+
+Mon Mar 27 10:20:34 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Update folks who need accounts.
+
+Mon Mar 27 09:29:14 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: J.T. Conklin is NetBSD maintainer.
+
+2000-03-27 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-i386.h: Fix typo. It is TARGET_LONG_DOUBLE_BIT
+ instead of TARGET_LONG_DOUBLE_BITS.
+ * config/i386/tm-i386mk.h: Likewise.
+
+2000-03-26 Mark Kettenis <kettenis@gnu.org>
+
+ Provide `long double' support for most i386 targets.
+ * config/i386/tm-i386.h (TARGET_LONG_DOUBLE_FORMAT): Define as
+ &floatformat_i387_ext.
+ (TARGET_LONG_DOUBLE_BITS): Define as 96.
+ (REGISTER_VIRTUAL_TYPE): Change type for FPU registers to
+ `builtin_type_long_double'.
+ (REGISTER_CONVERT_TO_VIRTUAL): Call
+ i386_register_convert_to_virtual.
+ (REGISTER_CONVERT_TO_RAW): Call i386_register_convert_to_raw.
+ (i387_to_double, double_to_i387): Remove prototypes.
+ (i386_extract_return_value): Change prototype to match definition
+ in i386-tdep.c.
+ * config/i386/tm-i386mk.h (TARGET_LONG_DOUBLE_FORMAT): #undef.
+ (TARGET_LONG_DOUBLE_BITS): #undef.
+ * config/i386/tm-linux.h (TARGET_LONG_DOUBLE_BIT): Remove.
+ [HAVE_LONG_DOUBLE && HOST_I386] (LD_I387): Remove.
+ (i387_extract_floating, i387_store_floating): Remove prototypes.
+ (TARGET_EXTRACT_FLOATING, TARGET_STORE_FLOATING): Remove.
+ (REGISTER_CONVERT_TO_VIRTUAL, REGOISTER_CONVERT_TO_RAW): Remove.
+ (REGISTER_VIRTUAL_TYPE): Remove.
+ * i386-tdep.c (i386_register_convert_to_virtual): New function.
+ (i386_register_convert_to_raw): New function.
+ * i387-tdep.c [LD_I387] (i387_extract_floating): Remove.
+ (i387_store_floating): Remove.
+
+Sat Mar 25 18:55:57 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * maint.c: Re-indent.
+
+Sat Mar 25 18:51:50 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * maint.c (_initialize_maint_cmds): Remove quoted trailing space.
+
+2000-03-24 Christopher Faylor <cgf@cygnus.com>
+
+ * config/mips/tm-wince.h: Fix typo which caused include of tm-mips.h to
+ be inoperative.
+
+2000-03-24 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c: Back out special frame walking code. It was broken.
+ (handle_exception): Correctly identify an illegal instruction.
+ * config/tm-cygwin.h: Eliminate special frame handling. Just use
+ normal i386 handling.
+
+2000-03-24 J.T. Conklin <jtc@redback.com>
+
+ * i386/tm-nbsd.h (USE_STRUCT_CONVENTION): Define.
+ * i386nbsd-nat.c (i386nbsd_use_struct_convention): New function.
+ (fetch_core_registers): Read fp registers.
+ (i386nbsd_core_fns, _initialize_i386nbsd_nat): Added.
+
+2000-03-24 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * arm-tdep.c (thumb_skip_prologue): Take function end addr argument
+ so that we can stop searching for the prologue past the function end
+ (arm_skip_prologue): Call thumb_skip_prologue with function end addr
+
+2000-03-24 Kevin Buettner <kevinb@redhat.com>
+
+ * linux-thread.c, lin-thread.c (save_inferior_pid,
+ restore_inferior_pid): Don't do compile time comparison
+ of TARGET_PTR_BIT and TARGET_INT_BIT.
+
+Thu Mar 23 13:18:26 2000 Philippe De Muyter <phdm@macqel.be>
+
+ * m68k-tdep.c (P_LINKL_FP, P_LINKW_FP): Macros renamed from P_LINK_L
+ and P_LINK_W.
+ (P_PEA_FP, P_MOVL_SP_FP): New macros.
+ (P_MOVL, P_LEAL, P_MOVML): Macros renamed from P_MOV_L, P_LEA_L and
+ P_MOVM_L.
+ (altos_skip_prologue, isi_skip_prologue): Use P_* macros, not octal
+ constants.
+ (delta68_in_sigtramp): New function.
+ (delta68_frame_args_address, delta68_frame_saved_pc): Ditto.
+ (m68k_skip_prologue): Use P_* macros, not hex constants.
+ (m68k_find_saved_regs): Do not expect a fixed sequence of register save
+ instructions, but accept them in any order; use P_* macros, not octal
+ or hex constants; recognize also `fmovemx to (fp + displacement)' and
+ `moveml to (fp + displacement)'.
+ * m68/tm-delta68.h (IN_SIGTRAMP): New macro.
+ (FRAME_SAVED_PC, FRAME_ARGS_ADDRESS): Ditto.
+
+Fri Mar 24 13:44:57 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Add Fernando Nasser to testsuite maintainers.
+
+2000-03-23 Michael Snyder <msnyder@cygnus.com>
+
+ * solib.c (open_symbol_file_object): To sneak an int argument
+ past catch_errors, instead of casting it to a pointer, simply
+ pass it by address.
+
+2000-03-23 Jimmy Guo <guo@cup.hp.com>
+
+ * gdbtypes.c (rank_function): Rank all N parameters and use correct
+ index into the prams[] and args[] arrays.
+
+2000-03-23 Fernando Nasser <fnasser@cygnus.com>
+
+ From David Whedon <dwhedon@gordian.com>
+
+ * top.c (execute_command): Checks all commands beore executing
+ to see if the user needs to be warned that the command is
+ deprecated, warns user if appropriate.
+ (add_info), (add_info_alias), (add_com) , (add_com_alias): Changed
+ return values from void to struct cmd_list_element *.
+ * command.c (lookup_cmd_1): Check aliases before following link
+ in case user needs to be warned about a deprecated alias.
+ (deprecate_cmd): new exported function for command deprecation,
+ sets flags and posibly a replacement string.
+ (deprecated_cmd_warning): New exported funciton to warn user about
+ a deprecated command.
+ (lookup_cmd_composition): New exported function that determines
+ alias, prefix_command, and cmd based on a string. This is useful
+ is we want to full name of a command.
+ * command.h : Added prototypes for deprecate_cmd,
+ deprecated_warn_user and lookup_cmd_composition, added flags to
+ the cmd_list_element structure, changed return values for
+ add_com_* and add_info_* from void to cmd_list_element.
+ * maint.c : (maintenance_deprecate): New function to deprecate a
+ command. This exists only so that the testsuite can deprecate
+ commands at runtime and check the warning behavior.
+ (maintenance_undeprecate) : New function, drops deprecated flags.
+ (maintenance_do_deprecate): Actually does the (un)deprecation.
+ (initialize_maint_cmds): Added the above new deprecate commands.
+
+2000-03-22 Daniel Berlin <dan@cgsoftware.com>
+ * command.c (apropos_cmd_helper): New function, meat of the
+ apropos command.
+ (apropos_command): New apropos command to search command
+ names/documentation for regular expressions.
+ (_initialize_command): Add the apropos command.
+
+2000-03-23 Michael Snyder <msnyder@cygnus.com>
+
+ * sol-thread.c (ps_pglobal_lookup): Change argument type from
+ paddr_t to psaddr_t. This mistake appears to date from an
+ erroneous man page in Solaris 2.5 -- the correct type from the
+ system headers has always been psaddr_t.
+ (ps_pdread, ps_pdwrite, ps_ptread, ps_ptwrite): Ditto.
+ (rw_common): Ditto.
+
+2000-03-22 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-linux-nat.c: Fix copyright.
+ (fill_gregset): Minor formatting fix.
+ * ia64-tdep.c (template_encoding_table, fetch_instruction,
+ examine_prologue): Clean up some compiler warnings.
+ (is_float_or_hfa_type_recurse, is_float_or_hfa_type, find_func_descr,
+ find_global_pointer, find_extant_func_descr): New functions.
+ (ia64_use_struct_convention, ia64_extract_return_value,
+ ia64_push_arguments): Handle HFAs.
+ (ia64_push_arguments): Find (or build) a function descriptor
+ when given a function address.
+ (ia64_push_return_address): Moved code for finding the
+ global pointer into its own function, find_global_pointer ().
+
+2000-03-22 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-loop.c (handle_file_event): Run through indent.
+
+2000-03-22 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Philippe De Muyter <phdm@macqel.be>
+
+ * event-loop.c (sys/types.h): File now included unconditionally.
+ (use_poll): New variable..
+ (gdb_notifier): poll- and select-versions merged.
+ (add_file_handler): If HAVE_POLL, check whether poll is usable,
+ and reset `use_poll' if not.
+ (create_file_handler): Select poll- or select-version according to
+ `use_poll'.
+ (delete_file_handler, handle_file_event): Likewise.
+ (gdb_wait_for_event, poll_timers): Likewise.
+
+2000-03-22 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * printcmd.c (print_scalar_formatted): Truncate addresses to the
+ size of a target pointer before passing them to print_address.
+
+2000-03-22 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-i386aix.h (I386_AIX_TARGET): Remove.
+ * config/i386/tm-linux.h (LOW_RETURN_REGNUM, HIGH_RETURN_REGNUM):
+ Remove
+ * i386-tdep.c (LOW_RETURN_REGNUM, HIGH_RETURN_REGNUM): New defines.
+ (i386_extract_return_value): Rewritten. Correctly support all
+ floating-point types and large integer types on targets that use
+ the standard i386 GDB register layout and return floating-point
+ values in the FPU.
+
+Wed Mar 22 15:09:34 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (CONFIG_INITS): Do not append remote-nrom.c
+
+2000-03-21 J.T. Conklin <jtc@redback.com>
+
+ * i386/nbsd.mh (NATDEPFILES): Change i386b-nat.o to i386nbsd-nat.o.
+ * i386nbsd-nat.c: New file.
+
+ * i386/tm-nbsd.h (NUM_REGS): Removed.
+ (HAVE_I387_REGS): Defined.
+ * i386/nm-nbsd.h (FLOAT_INFO): Removed.
+
+ * tm-nbsd.h (IN_SOLIB_CALL_TRAMPOLINE): Define if not
+ SVR4_SHARED_LIBS.
+
+Wed Mar 22 11:18:59 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Add Jim Blandy to breakpoint maintainers. David
+ taylor is the Solaris/SPARC maintainer. Add Jonathan Larmour to
+ the write after approval list.
+
+2000-03-21 Kevin Buettner <kevinb@redhat.com>
+
+ * symtab.h (MAX_SECTIONS, struct section_addr_info,
+ symbol_file_add): Move declarations from here...
+ * symfile.h: ...to here.
+
+ * solib.c (symbol_add_stub): Make symbol_file_add () aware of
+ all section addresses, not just .text.
+ * symfile.h, symfile.c (free_section_addr_info,
+ build_section_addr_info_from_section_table): New functions.
+
+ * symfile.h (MAX_SECTIONS): Increase value to 40.
+ * symfile.c (syms_from_objfile): Add bounds check prior to
+ accessing ``other'' array in a section_addr_info_struct.
+ Remove unused variable section_offsets.
+ (add_symbol_file_command): Remove unused variable text_addr.
+
+2000-03-21 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * breakpoint.c (bpstat_stop_status): Don't stop if a read
+ watchpoint appears to break, but the watched value changed.
+
+2000-03-21 Jim Blandy <jimb@redhat.com>
+
+ * gdbarch.sh: Emit a definition and declaration for gdbarch_free,
+ a companion to gdbarch_alloc, which allows a gdbarch init function
+ to free partially-built gdbarch structures.
+ * gdbarch.c, gdbarch.h: Regenerated.
+
+2000-03-20 Kevin Buettner <kevinb@redhat.com>
+
+ * configure.host, configure.tgt (ia64-*-linux*): New entry.
+
+ * gdbserver/low-linux.c (u_offsets, ia64_register_u_addr,
+ initialize_arch): Define for IA-64.
+ (initialize_arch): Add declaration.
+
+2000-03-20 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * breakpoint.c (insert_breakpoints, remove_breakpoint)
+ (bpstat_stop_status, can_use_hardware_watchpoint): Don't insert,
+ remove, or check status of hardware watchpoints for entire structs
+ and arrays unless the user explicitly asked to watch that struct
+ or array.
+ (insert_breakpoints): Try to insert watchpoints for all the values
+ on the value chain, even if some of them fail to insert.
+
+ * values.c (value_primitive_field): Set the offset in struct value
+ we return when the field is a packed bitfield.
+
+2000-03-20 Michael Snyder <msnyder@cygnus.com>
+
+ * remote.c (remote_threads_extra_info): New function.
+ Implement the extra thread info query for "info threads".
+ (remote_threads_info): Clean up a bit.
+ (use_threadinfo_query, use_threadextra_query): New variables.
+ Control whether GDB will use the new or old protocol for
+ thread info queries.
+ (remote_open_1): Initialize new variables.
+ (remote_async_open_1): Ditto.
+ (remote_cisco_open): Ditto.
+
+2000-03-20 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-linux-nat.c, ia64-tdep.c, config/ia64/linux.mh,
+ config/ia64/linux.mt, config/ia64/nm-linux.h, config/ia64/tm-ia64.h,
+ config/ia64/tm-linux.h, config/ia64/xm-linux.h: New files.
+
+2000-03-20 Kevin Buettner <kevinb@redhat.com>
+
+ * utils.c (floatformat_from_doublest): Don't assume that a long
+ will be exactly 32 bits in length. Also... make sure space
+ that we're writing the float to is completely initialized to
+ zeroes, even when the number of bits in the float is not
+ evenly divisible by FLOATFORMAT_CHAR_BIT.
+
+2000-03-20 Jim Blandy <jimb@redhat.com>
+
+ * i386-linux-nat.c: No need to #include "frame.h" any more.
+ (LINUX_SIGTRAMP_INSN0, LINUX_SIGTRAMP_OFFSET0,
+ LINUX_SIGTRAMP_INSN1, LINUX_SIGTRAMP_OFFSET1,
+ LINUX_SIGTRAMP_INSN2, LINUX_SIGTRAMP_OFFSET2, linux_sigtramp_code,
+ LINUX_SIGTRAMP_LEN, i386_linux_sigtramp_start,
+ LINUX_RT_SIGTRAMP_INSN0, LINUX_RT_SIGTRAMP_OFFSET0,
+ LINUX_RT_SIGTRAMP_INSN1, LINUX_RT_SIGTRAMP_OFFSET1,
+ linux_rt_sigtramp_code, LINUX_RT_SIGTRAMP_LEN,
+ i386_linux_rt_sigtramp_start, i386_linux_in_sigtramp,
+ i386_linux_sigcontext_addr, LINUX_SIGCONTEXT_PC_OFFSET,
+ i386_linux_sigtramp_saved_pc, LINUX_SIGCONTEXT_SP_OFFSET,
+ i386_linux_sigtramp_saved_sp): Deleted. Folks rightly pointed
+ out that these are target-dependent, and useful in non-native
+ configurations. Moved to...
+ * i386-linux-tdep.c: ... Here, a new file.
+ * Makefile.in (ALLDEPFILES): Add i386-linux-tdep.c.
+ (i386-linux-tdep.o): New rule.
+ (i386-linux-nat.o): We no longer depend on frame.h.
+ * config/i386/linux.mt (TDEPFILES): Add i386-linux-tdep.o.
+
+2000-03-04 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * event-loop.c (top-level) [NO_FD_SET]: Deprecate this branch.
+ Print an error at compile time if we are to use select, but FD_SET
+ is not available.
+ (SELECT_MASK, NBBY, FD_SETSIZE, NFDBITS, MASK_SIZE): Define only
+ if HAVE_POLL is not defined and NO_FD_SET *is* defined.
+ (create_file_handler) [!HAVE_POLL]: Use FD_SET and FD_CLR.
+ (delete_file_handler) [!HAVE_POLL]: Use FD_CLR and FD_ISSET.
+ (gdb_wait_for_event) [!HAVE_POLL]: Copy fd_set sets directly
+ instead of using memcpy and memset. Use FD_ISSET.
+
+ * config/i386/xm-go32.h (fd_mask): Remove typedef.
+
+Mon Mar 20 19:58:45 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * command.c (_initialize_command): Document requirements for ``!''
+ command.
+
+Mon Mar 20 18:12:46 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Fri 10 Mar 2000 Robert
+ <robert.melchers@drives.eurotherm.co.uk>:
+ * sh-tdep.c (sh_processor_type_table): Add entry for sh2.
+
+Mon Mar 20 17:33:32 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Thu Mar 16 16:49:27 EST 2000 John David Anglin
+ <dave@hiauly1.hia.nrc.ca>:
+ * configure.in (CONFIG_INITS): Don't include hpux-thread.c. Stops
+ _initialize_hpux_thread being called twice.
+ * configure: Regenerated.
+
+2000-03-19 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * event-top.c (_initialize_event_loop): If instream is not
+ connected to a terminal device, turn editing off.
+
+2000-03-19 Eli Zaretskii <eliz@is.elta.co.il>
+
+ Support for building GDB with DJGPP, and running the test suite on
+ it:
+ * config/djgpp/djconfig.sh: New file.
+ * config/djgpp/config.sed: New file.
+ * config/djgpp/README: New file.
+ * config/djgpp/fnchange.lst: New file.
+ * config/djgpp/djcheck.sh: New file.
+
+2000-03-19 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * ser-go32.c (ports): Make the initializers complete, to pacify
+ GCC 2.9X.
+
+2000-03-17 Jim Blandy <jimb@redhat.com>
+
+ * i386v-nat.c (i386_insert_nonaligned_watchpoint): Use a
+ two-dimensional array, instead of faking it with explicit index
+ arithmetic.
+
+ * linux-thread.c (linuxthreads_attach, linuxthreads_detach,
+ linuxthreads_create_inferior): Fix typo in variable name: it's
+ linuxthreads_exit_status, not linux_exit_status.
+
+ * gdb_wait.h (WSETSTOP): Pass the appropriate number of arguments
+ to W_STOPCODE.
+
+ * solib.c (solib_add): Delete debugging code.
+
+2000-03-17 Mark Kettenis <kettenis@gnu.org>
+
+ * gdb_wait.h: add definitions of WSETSTOP and WSETEXIT for Linux.
+ * linux-thread.c: Use WSETSTOP instead of W_STOPCODE.
+
+Fri Mar 17 11:06:59 2000 Philippe De Muyter <phdm@macqel.be>
+
+ * language.c (set_lang_str): Do not call `free' for a null pointer.
+ (set_type_str, set_range_str): Ditto.
+
+2000-03-16 Jim Blandy <jimb@redhat.com>
+
+ * i386-linux-nat.c (i386_linux_saved_pc_after_call): Lost in the
+ merge; reinstated.
+
+ * solib.c (current_sos): Be more careful about freeing the new
+ so_list node if an error occurs.
+
+ * i386-tdep.c (LINUX_SIGTRAMP_INSN0, LINUX_SIGTRAMP_OFFSET0,
+ LINUX_SIGTRAMP_INSN1, LINUX_SIGTRAMP_OFFSET1,
+ LINUX_SIGTRAMP_INSN2, LINUX_SIGTRAMP_OFFSET2, linux_sigtramp_code,
+ LINUX_SIGTRAMP_LEN, i386_linux_sigtramp_start,
+ LINUX_RT_SIGTRAMP_INSN0, LINUX_RT_SIGTRAMP_OFFSET0,
+ LINUX_RT_SIGTRAMP_INSN1, LINUX_RT_SIGTRAMP_OFFSET1,
+ linux_rt_sigtramp_code, LINUX_RT_SIGTRAMP_LEN,
+ i386_linux_rt_sigtramp_start, i386_linux_in_sigtramp,
+ i386_linux_sigcontext_addr, LINUX_SIGCONTEXT_PC_OFFSET,
+ i386_linux_sigtramp_saved_pc, LINUX_SIGCONTEXT_SP_OFFSET,
+ i386_linux_sigtramp_saved_sp): Deleted. These all implement
+ Linux-specific signal trampoline detection, and should be moved
+ to...
+ * i386-linux-nat.c: ... here.
+ * config/i386/tm-linux.h (I386_LINUX_SIGTRAMP): No need to define
+ this any more, since we're not enabling OS-specific code in a
+ OS-independent file.
+
+2000-03-16 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * Makefile.in (go32-nat.o): Add prerequisites.
+ (ALLDEPFILES): Add go32-nat.c.
+
+2000-03-15 Michael Snyder <msnyder@cygnus.com>
+
+ From "Peter.Schauer" <Peter.Schauer@regent.e-technik.tu-muenchen.de>
+ * symfile.c (reread_symbols): Clear msymbol hash table.
+
+2000-03-15 Jim Blandy <jimb@redhat.com>
+
+ Deal with the inferior unloading shared objects.
+ * solib.c (current_sos): New function, replacing find_solib.
+ (find_solib): Deleted.
+ (free_so): New function.
+ (clear_solib): Call free_so, instead of writing it out.
+ (solib_add): Rewritten: compare the inferior's current list of
+ shared objects with GDB's list, and do the required loads and
+ unloads.
+ (info_sharedlibrary_command, solib_address): Don't use find_solib
+ to walk the list of shared libraries: call solib_add, and then
+ walk the list at so_list_head normally.
+ * objfiles.c (free_objfile): Don't call CLEAR_SOLIB, and don't
+ detach the core target. These tasks are taken care of elsewhere.
+ * target.c (remove_target_sections): New function.
+ * target.h (remove_target_sections): New declaration.
+
+ * solib.c (symbol_add_stub): Check whether we've already created
+ an objfile for this shared object first, before doing all that
+ work to compute section addresses, etc.
+
+ * objfiles.c (unlink_objfile): Report an internal error if objfile
+ doesn't occur in the object_files list.
+
+ * solib.c (special_symbol_handling): Delete argument; it's not
+ used.
+
+ Changes from Peter Schauer <pes@regent.e-technik.tu-muenchen.de>:
+
+ * solib.c (SOLIB_EXTRACT_ADDRESS): New macro to extract addresses
+ from solib structures. Use it throughout solib.c, get rid of all
+ CORE_ADDR casts.
+ (struct so_list): Change type of lmaddr to CORE_ADDR.
+ (first_link_map_member): Change return value type to CORE_ADDR,
+ update callers.
+ (solib_add_common_symbols): Change parameter type to CORE_ADDR,
+ update callers.
+ (open_symbol_file_object, find_solib): Change type of lm variable
+ to CORE_ADDR.
+
+2000-03-15 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * ser-go32.c (dos_noop, dos_raw, dos_noflush_set_tty_state)
+ (dos_print_tty_state, dos_info, _initialize_ser_dos): Convert
+ to ISO C. Use ATTRIBUTE_UNUSED to avoid compiler warnings.
+ (dos_info): Avoid compiler warning when printing a ptrdiff_t.
+
+ * ser-go32.c (dos_get_tty_state): Fail if the (fake) handle was
+ not opened by dos_open, but let the 3 standard handles go through
+ unharmed.
+
+2000-03-14 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * eval.c (evaluate_subexp_with_coercion): Add call to
+ check_typedef, to handle typedeffed vars correctly.
+
+Mon Mar 13 21:21:41 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (STREQ, STRCMP, STREQN): Document that these macros are
+ somewhat redundant.
+ (QUIT): Note that this can probably be replaced by a function.
+
+2000-03-13 James Ingham <jingham@leda.cygnus.com>
+
+ Add support for a variable object that tries to evaluate itself in
+ the currently selected frame, rather than in a fixed frame.
+
+ * wrapper.c,h (gdb_parse_exp_1): Added a wrapper for
+ gdb_parse_exp_1.
+ * varobj.h: Added USE_CURRENT_FRAME to varobj_type & changed def'n
+ of varobj_create.
+ * varobj.c (varobj_list): Return type indicates whether the
+ variable's type has changed (for current frame variables).
+ (varobj_update): Handle the case where the variable's type has
+ changed.
+ (delete_variable_1): Allow for deletion of variables that have not
+ been installed yet.
+ (new_root_variable): Initialize use_selected_frame variable.
+ (value_of_root): This is where most of the work to handle "current
+ frame" variables was added. Most of the complexity involves
+ handling the case where the type of the variable has changed.
+ (varobj_create): Add a "type" argument, to tell if the
+ variable is one of these "current frame" variables. Also protect
+ call to parse_exp_1 from long jumping.
+
+2000-03-13 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c (struct env387): Remove declaration.
+ (print_387_status, i386_go32_float_info): Remove redundant
+ functions.
+ (regno_mapping, sig_map, excepn_map): Add braces around inner
+ initializers.
+ (many functions): Use ATTRIBUTE_UNUSED to shut up the compiler;
+ fix code which mixed signed with unsigned.
+ (go32_resume): Use TARGET_SIGNAL_LAST instead of -1.
+ (go32_wait): Initialize INT3_addr.
+ (go32_fetch_registers): Extend all FP registers that are shorter
+ than 4 bytes to 32 bits. Support 32 standard FP registers defined
+ on config/i386/tm-i386.h.
+ (store_register): Support 32 FP registers.
+ (go32_create_inferior): Don't crash if handed a NULL pointer
+ instead of exec file name.
+ (ignore): Remove unused function.
+ (go32_insert_hw_breakpoint): Remove unused variables.
+ (init_go32_ops): Set value of processing_gcc_compilation to 2.
+
+Mon Mar 13 18:54:42 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-03-10 Daniel Berlin <dan@cgsoftware.com> Fix C++
+ overloading, add support for seeing through references:
+ * valops.c (find_overload_match): Handle STABS overloading for
+ C++.
+ (find_overload_match): Look in right place for function arguments
+ in the debug info.
+ (find_overload_match): Rather than giving up when we have >1
+ perfect match, just choose one, especially since the
+ recommendation GDB gives ("disambiguate it by specifying function
+ signature"), is basically impossible.
+ (check_field_in): STREQ->strcmp_iw
+ (search_struct_field): STREQ->strcmp_iw
+ (find_method_list): STREQ->strcmp_iw
+ * gdbtypes.c (rank_one_type): Add ability to see through
+ references.
+ (rank_one_type): strcmp->strcmp_iw, because the whitespace could
+ be different.
+ (rank_function): Rank function properly (was doing it wrong
+ before, comparing the wrong parts of the arrays)
+ (rank_one_type): Change #if 0 to #ifdef DEBUG_OLOAD.
+ * gdbtypes.h: Add REFERENCE_CONVERSION_BADNESS for "badness"
+ associated with converting a non-reference to a reference.
+ * eval.c (evaluate_subexp_standard): for OP_VAR_VALUE, always
+ return full value object; for STRUCTOP_PTR, use pointer to
+ rtti type to get member / method if objectprint is set and
+ target type of pointer is class.
+
+ * gdbtypes.c (rank_one_type): Add comment on how to eliminate the
+ #ifdef DEBUG_OLOAD.
+
+2000-03-11 Mark Kettenis <kettenis@gnu.org>
+
+ * gnu-nat.c: Fix the formatting where indent misinterpreted `&' as
+ a binary operator.
+ (gnu_attach): Change error message for missing
+ argument to be identical to the corresponding message in
+ `inftarg.c'. This makes the testsuite happy.
+
+2000-03-11 Mark Kettenis <kettenis@gnu.org>
+
+ * i386gnu-nat.c (gnu_store_registers): Make sure the T bit in the
+ %eflags isn't modified. This fixes a bug where every call to a
+ function in the program beyond the first call would fail.
+
+Fri Mar 10 11:44:55 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Devolve responsibility for domain maintenance.
+
+2000-03-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * minsyms.c (prim_record_minimal_symbol_and_info): Add comment.
+
+2000-02-25 Scott Bambrough <scottb@netwinder.org>
+
+ * gdb.base/long_long.exp: Correct test suite failure when printing
+ a long long value as a double on ARM platforms.
+
+Thu Mar 9 14:21:07 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS (Core): Anthony Green is the Java - including
+ testsuite - maintainer. Reformat testsuite and language support
+ sections
+
+2000-03-08 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-tdep.c (i386_linux_saved_pc_after_call): New function.
+ * config/i386/tm-linux.h (SAVED_PC_AFTER_CALL): Define to call
+ i386_linux_saved_pc_after_call.
+
+2000-03-06 Jim Blandy <jimb@redhat.com>
+
+ From Tom Tromey <tromey@cygnus.com> and Keith Seitz <?>:
+
+ * minsyms.c: #include <ctype.h>, for msymbol_hash_iw.
+ (compact_minimal_symbols): Added `objfile' argument.
+ Put symbols in the objfile's hash table.
+ (install_minimal_symbols): Put symbols in the objfile's demangled
+ hash table.
+ (lookup_minimal_symbol): Use hash table to find symbol in
+ objfile.
+ (msymbol_hash_iw, msymbol_hash, add_minsym_to_hash_table): New
+ functions.
+ (prim_record_minimal_symbol_and_info): Initialize the
+ hash link fields of the new minimal symbol.
+ * symtab.h (struct minimal_symbol): New fields `hash_next',
+ `demangled_hash_next'.
+ (msymbol_hash_iw, msymbol_hash, add_minsym_to_hash_table): Declare.
+ * objfiles.h (MINIMAL_SYMBOL_HASH_SIZE): New define.
+ (struct objfile): New fields `msymbol_hash',
+ `msymbol_demangled_hash'.
+
+2000-03-06 Jim Blandy <jimb@redhat.com>
+
+ * solib.c (first_link_map_member): Doc fix.
+
+2000-03-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Eli Zaretskii <eliz@is.elta.co.il>:
+
+ * event-loop.c (poll_timers): Don't compare delta.tv_sec with
+ zero, since time_t might be unsigned.
+
+2000-03-06 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-linux-nat.c (supply_fpregset): Mask off the reserved bits
+ in *FPREGSETP.
+ (convert_to_fpregset): Don't touch the reserved bits in *FPREGSETP.
+
+2000-03-05 Mark Kettenis <kettenis@gnu.org>
+
+ Allow GDB to run on Linux 2.0 again.
+ * config.in: Add HAVE_PTRACE_GETREGS.
+ * configure.in: Check if <sys/ptrace.h> defines PTRACE_GETREGS.
+ * configure: Regenerated.
+ * config/i386/nm-linux.h (CANNOT_FETCH_REGISTER,
+ CANNOT_STORE_REGISTER): New defines.
+ * i386-linux-nat.c (have_ptrace_getregs): New variable.
+ (PTRACE_XFER_TYPE, CANNOT_FETCH_REGISTER, fetch_register,
+ old_fetch_inferior_registers, CANNOT_STORE_REGISTER,
+ store_register, old_store_inferior_registers): Copied over from
+ `inptrace.c' as a temporary measure.
+ (fetch_regs, store_regs, fetch_fpregs, store_fpregs):
+ Conditionalize on HAVE_PTRACE_GETREGS. Define stubs if
+ HAVE_PTRACE_GETREGS isn't defined.
+ (fetch_regs): Reset `have_ptrace_getregs' if ptrace call fails
+ with EIO.
+ (fetch_inferior_registers, store_inferior_registers): Fall back on
+ the method use in `infptrace.c' (by calling
+ old_fetch_inferior_registers and old_store_inferior_registers) if
+ `have_ptrace_getregs' isn't set.
+
+2000-03-05 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-linux-nat.c: Use elf_gregset_t and elf_fpregset_t instead
+ of gregset_t and fpregset_t. Those are the only names that are
+ guaranteed to specify the right types for all supported Linux
+ systems out there.
+ Various doc fixes and gratitious local variable renames, all in an
+ attempt to stress similarities between the code and unify the
+ terminology used. Use ISO-C all over.
+ (regmap): Remove trailing comma.
+ (FPREG_ADDR): Renamed from FPREGSET_T_FPREG_ADDR.
+ (convert_to_gregset): Make static. Remove GDB_REGS argument. It
+ is unnecessary and wasn't used anyway. All callers changed.
+ (convert_to_fpregset, convert_to_xfpregset): Likewise.
+ (fetch_regs, store_regs): Remove unused variable `regno'.
+ (fill_fpregs): If REGNO is not -1, only update the specified
+ register.
+ (fetch_core_registers): Renamed from
+ i386_linux_fetch_core_registers. There is no need for a unique
+ name since the function is static anyway.
+ (linux_elf_core_fns): Renamed from i386_linux_nat_core_functions
+ since it is more descriptive.
+
+Sun Mar 5 19:40:27 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS (readline/): Expand to include host maintainers.
+
+2000-03-04 Mark Kettenis <kettenis@gnu.org>
+
+ Fix support for Linux/i386 signal trampolines. The old approach
+ didn't work for Linux 2.2 and beyond, and didn't work with recent
+ versions of the GNU C library.
+ * i386-tdep.c (LINUX_RT_SIGTRAMP_INSN0, LINUX_RT_SIGTRAMP_OFFSET0,
+ LINUX_RT_SIGTRAMP_INSN1, LINUX_RT_SIGTRAMP_OFFSET1): New defines.
+ (linux_rt_sigtramp_code): New variable.
+ (LINUX_RT_SIGTRAMP_LEN): New define.
+ (i386_linux_rt_sigtramp_start): New function. Detect start of
+ signal trampolines for RT signals.
+ (i386_linux_sigtramp): Removed.
+ (i386_linux_in_sigtramp): New function.
+ (i386_linux_sigcontext_addr): New function. Recognize the names
+ of the signal tranmpolines used by recent versions of the GNU C
+ library, and add support for RT signals.
+ (LINUX_SIGCONTEXT_PC_OFFSET, LINUX_SIGCONTEXT_SP_OFFSET): New
+ defines. Moved here from config/i386/tm-linux.h.
+ (i386_linux_sigtramp_saved_pc, i386_linux_sigtramp_saved_sp):
+ Reimplement in terms of i386_linux_sigcontext_addr.
+ * config/i386/tm-linux.h (LINUX_SIGCONTEXT_SIZE): Removed.
+ (LINUX_SIGCONTEXT_PC_OFFSET, LINUX_SIGCONTEXT_SP_OFFSET):
+ Moved to i386-tdep.c.
+ (IN_SIGTRAMP): Redefine to call i386_linux_in_sigtramp.
+
+Sat Mar 4 19:38:11 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ By: Sat Mar 4 04:08:58 2000 Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+ * Makefile.in (all-gdbtk): Fix $srcdir to ${srcdir}.
+
+Sat Mar 4 17:23:06 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Frank Ch. Eigler and Andrew Cagney co-ordinate the
+ sim directory.
+
+Sat Mar 4 16:19:31 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Add Michael Snyder and Peter Schauer to list of
+ ``Blanket Write Privs'' maintainers.
+
+Sat Mar 4 15:58:40 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Sun 20 Feb 2000 Robert Lipe <robertl@sco.com>:
+ * language.c (longest_local_hex_string_custom): Don't compile
+ 'long long' section if host doesn't have 'long long'.
+
+Sat Mar 4 15:45:38 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * language.c (longest_raw_hex_string): Comment out. Appears
+ unused.
+
+Sat Mar 4 13:02:09 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * utils.c (mcalloc), defs.h (mcalloc): Keep consistent with
+ "mmalloc.h" which means using PTRs.
+ (init_malloc, msavestring, mstrsave): Convert to PTR free ISO-C.
+
+Sat Mar 4 11:49:21 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (store_address, store_unsigned_integer, store_address):
+ Replace PTR with void* in delcaration.
+ * findvar.c (extract_signed_integer, extract_unsigned_integer,
+ extract_long_unsigned_integer, extract_address,
+ store_signed_integer, store_unsigned_integer, store_address):
+ Convert definition to ISO-C. Replace PTR with void*.
+
+Sat Mar 4 10:57:25 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (make_cleanup_func): Document as deprecated.
+ (make_cleanup_ftype): New typedef. Make signature consistent with
+ other function typedefs. Document as not be used out side of
+ make_cleanup code. Use in make_cleanup declarations.
+ (null_cleanup): Replace PTR with void*.
+
+ * utils.c (make_cleanup, make_final_cleanup, make_run_cleanup,
+ make_exec_cleanup, make_exec_error_cleanup, make_my_cleanup,
+ null_cleanup): Change K&R definition to ISO-C using void* and
+ make_cleanup_fytpe.
+ (discard_my_cleanups): Don't cast argument to free.
+
+2000-03-03 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * defs.h (struct continuation_arg): Change type of field 'data'
+ from PTR to void *.
+
+ * event-loop.h: Eliminate uses of PTR, use 'void *' instead.
+
+ * event-top.c: Ditto.
+
+Fri Mar 3 15:39:34 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (CONFIG_CLEAN, CONFIG_ALL, LN_S): Defined by
+ configure.
+ (SUBDIR_MI_CLEAN, SUBDIR_GDBTK_CLEAN, SUBDIR_MI_ALL,
+ SUBDIR_GDBTK_ALL): Define.
+ (all-gdbtk, clean-gdbtk): New targets.
+ (all): Add CONFIG_ALL as dependency.
+ (clean): Add CONFIG_CLEAN as dependency.
+
+ * configure.in (CONFIG_ALL, CONFIG_CLEAN): Define.
+ (LN_S): Define. Delete GDBtk's link code.
+
+Fri Mar 3 13:12:34 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (ENABLE_GDBTK): Delete variable.
+ (enable-gdbtk): Only enable gdbtk when there is a GDBTK directory.
+ * Makefile.in: Update.
+ * configure: Regenerate
+
+2000-03-02 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * config/alpha/alpha-linux.mh: Remove core-regset.o fron the
+ NATDEPFILES list.
+
+2000-03-02 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-i386aix.h (NUM_FPREGS, NUM_REGS, REGISTER_BYTES):
+ Override definitions to include the normal FPU registers.
+ (REGISTER_CONVERTIBLE, REGISTER_CONVERT_TO_VIRTUAL,
+ REGISTER_CONVERT_TO_RAW): Removed. The default definitions are
+ fine for AIX/i386.
+ (i387_to_double, double_to_i387): Remove prototypes.
+
+2000-03-02 Kevin Buettner <kevinb@redhat.com>
+
+ * findvar.c (extract_floating, store_floating): Use target
+ floating point type sizes rather host sizes to determine
+ which conversion needs to be done.
+
+2000-03-02 Nick Duffek <nsd@cygnus.com>
+
+ * uw-thread.c: Apply GNU conventions to comment formatting.
+ (deactivate_uw_thread): Call remove_thread_event_breakpoints().
+ (uw_thread_mourn_inferior): Move remove_thread_event_breakpoints()
+ call to deactivate_uw_thread().
+
+Thu Mar 2 09:04:46 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Daniel Berlin is C++ maintainer.
+
+Thu Mar 2 08:55:35 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Mark Kettenis is the x86 architcture maintainer and
+ a joint GNU/Linux/x86 maintainer. Nick Duffeck and Robert Lipe
+ share SCO/Unixware. Nick Duffek and Peter Schauer share
+ Solaris/x86.
+
+Wed Mar 1 22:12:35 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Wed 23 Feb 2000 Fernando Nasser <fnasser@redhat.com>:
+ * remote-sim.c (gdbsim_close): Call generic_mourn_inferior.
+ * remote-rdi.c (arm_rdi_close): Ditto.
+
+Wed Mar 1 19:31:32 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * CONTRIBUTE (configure.in): Note that patches to configure are
+ not needed.
+
+2000-03-01 Mark Kettenis <kettenis@gnu.org>
+
+ * MAINTAINERS: Correct my own mail address.
+
+Wed Mar 1 11:26:07 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Document people with paperwork pending.
+
+Wed Mar 1 00:49:06 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-02-28 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>:
+ Make NEW_PROC_ABI interface functional on Solaris x86.
+ * sol-thread.c (ps_lgetLDT): Rewrite to use new
+ procfs_find_LDT_entry function from procfs.c, mostly copied from
+ lin-thread.c.
+ * inferior.h, procfs.c (procfs_get_pid_fd): Removed, no longer
+ needed.
+
+Wed Mar 1 00:34:55 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-02-26 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>:
+ * config/i386/tm-i386sol2.h (MERGEPID): Define.
+
+Wed Mar 1 00:06:19 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 1999-08-13 J.T. Conklin <jtc@redback.com>:
+ * config/i386/tm-i386.h (FRAME_INIT_SAVED_REGS): Replace
+ FRAME_FIND_SAVED_REGS.
+ (i386_frame_init_saved_regs): Replace i386_frame_find_saved_regs.
+ * i386-tdep.c (i386_frame_init_saved_regs, i386_pop_frame):
+ Update.
+
+Tue Feb 29 23:56:41 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-02-23 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>:
+ * objfiles.c (open_mapped_file): Fix obsolete references to `mapped'
+ parameter.
+
+Tue Feb 29 18:47:58 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-02-23 Eli Zaretskii <eliz@is.elta.co.il>:
+ * config/i386/nm-go32.h (FLOAT_INFO): Remove macro definition.
+ (top level): Add prototypes for go32_* functions.
+ * config/i386/tm-go32.h (I386_DJGPP_TARGET): Define.
+ (FRAME_CHAIN, FRAMELESS_FUNCTION_INVOCATION, FRAME_SAVED_PC):
+ Override definitions from tm-i386.h.
+ (REGISTER_VIRTUAL_TYPE): Remove macro definition.
+ * i386-tdep.c (i386_extract_return_value)
+ [I386_AIX_TARGET || I386_GNULINUX_TARGET]: Add I386_DJGPP_TARGET
+ to the list of targets which return FP values in FP registers.
+
+ * i386-tdep.c (i386_extract_return_value): Add FIXME recommending
+ that this function be re-implemented using multi-arch.
+
+Tue Feb 29 18:40:08 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-02-23 Eli Zaretskii <eliz@is.elta.co.il>:
+ * utils.c [__GO32__]: Include pc.h, for prototypes of ScreenCols
+ and ScreenRows.
+ * ser-go32.c: Include string.h, for prototype of strncasecmp.
+ (dpmi_regs, dpmi_sregs): Remove unused variables.
+ (dos_flush_input): Return a value, to prevent compiler warning.
+ * expprint.c (dump_prefix_expression): Use %ld in format and cast
+ sizeof(union exp_element) to long, to prevent GCC from complaining
+ about format/argument mismatch.
+ (dump_postfix_expression): Likewise.
+
+Tue Feb 29 18:09:46 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * arm-tdep.c: Include <ctype.h>.
+
+Tue Feb 29 17:33:49 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Wed, 23 Feb 2000 Fernando Nasser <fnasser@redhat.com>:
+ * stack.c (backtrace_command_1), infrun.c (normal_stop): Check
+ that the target's stack was valid.
+
+Tue Feb 29 15:14:56 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-02-22 Stephane Carrez <stcarrez@worldnet.fr>:
+ * dwarf2read.c (read_address): Read 16-bits addresses.
+
+2000-02-28 Scott Bambrough <scottb@netwinder.org>
+
+ * arm-linux-nat.c (fetch_nw_fpe_*):
+ Renamed to fetch_nwfpe_* to use the same naming convention
+ as in the Linux kernel. Modified prototype to get rid of
+ unused parameters.
+ (store_nw_fpe_*): Renamed to store_nwfpe_* to use the same
+ naming convention as in the Linux kernel. Fixed calls to
+ fetch_nwfpe_*.
+ (store_fpregs): Fixed calls to store_nwfpe_*. Removed
+ unused variable.
+
+Mon Feb 28 18:24:32 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Transfer d30v maintainership to David Taylor.
+
+2000-02-28 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c: Remove unneeded header.
+ * wince.c: Ditto.
+
+Mon Feb 28 13:34:54 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * wince.c: Include "gdb_wait.h" and not "wait.h".
+
+Mon Feb 28 10:58:45 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Mention mmalloc. Expand Host/Native and
+ Target/Architecture maintainers descriptions.
+
+2000-02-26 Mark Kettenis <kettenis@gnu.org>
+
+ * gnu-nat.c: Include "gdbthread.h". Include <hurd.h>.
+ Reorder headers a bit. Overall cleanup and minor reformatting.
+ (MIG_SERVER_DIED): Remove define.
+ (proc_update_sc): Add braces to silence compiler warning.
+ (proc_steal_exc_port): Initialize err to zero.
+ (make_proc): Add braces to silence compiler warning.
+ (inf_validate_task_sc): Add cast to silence compiler warning.
+ (inf_set_traced): Reorganize a bit to silence compiler warning.
+ (inf_validate_procs): Use mach_msg_type_number_t for all thread
+ numbers and add braces to silence compiler warning.
+ (gnu_wait): Add prototypes for server functions and add braces to
+ silence compiler warnings.
+ (S_exception_raise_request): Pass subcode to inf_debug call.
+ (gnu_write_inferior): Remove unused variable `protection_changed'.
+ (gnu_xfer_memory): Remove unused variable `result'.
+ (set_sig_thread_cmd): Remove unused varible `tid'.
+ (set_signals_cmd): Remve unused variable `trace'.
+ (add_task_commands): Provide complete prototype. Reformat help
+ strings a bit to make sure the first line is a full sentence.
+ Call info_port_rights_cmd instead of info_send_rights_cmd for the
+ "info port-rights" command.
+ (add_thread_commands): Provide complete prototype. Make static.
+ Reformat help strings a bit to make sure the first line is a full
+ sentence.
+ (_initialize_gnu_nat): Provide complete prototype.
+
+2000-02-26 Mark Kettenis <kettenis@gnu.org>
+
+ Make cross-compilation for the Hurd more friendly.
+ From Jeff Bailey <jbailey@gnu.org>:
+ * configure.in: Use AC_CHECK_TOOL to find MiG.
+ * Makefile.in (MIG): New variable.
+ * config/i386/i386gnu.mh (MIG): Remove.
+ * configure: Regenerated.
+
+2000-02-26 Kevin Buettner <kevinb@redhat.com>
+
+ * ppc-linux-tdep.c (ppc_linux_memory_remove_breakpoint): Add
+ comment explaining motivation behind this function and why
+ the generic facilities won't work for this platform.
+ * rs6000-tdep.c (skip_prologue): Always test to make sure
+ that an instruction is read successfully from the target's
+ memory. Introduce notion of instructions which may appear in
+ the prologue, but may not end the prologue. Added explicit
+ check for nop instruction. Use memset() to zero the frame
+ data instead of assignment from a statically allocated,
+ uninitialized structure.
+
+Sat Feb 26 17:15:16 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Chris Faylor is responsible for all MS Windows
+ systems. Note that Jim Blandy as maintainer for ``tracing
+ bytecode stuff''
+
+2000-02-25 Fernando Nasser <fnasser@cygnus.com>
+
+ From: Thomas Zenker <thz@Lennartz-electronic.DE>
+ * rdi-share/hsys.c: to compile under 4.4BSD derived systems (FreeBSD,
+ NetBSD...) sys_errlist should not be declared in hsys.c.
+ NEED_SYSERRLIST is set already by configure, so we can use it.
+ * rdi-share/unixcomm.c: 4.4BSD derived systems define BSD, but are
+ posix compliant and we should not work with the old compatibility
+ stuff. Because of that I undef BSD in case of FBSD etc and include
+ sys/ioctl to get the flags.
+ * rdi-share/unixcomm.c: If the TIOCEXCL flags exists set serial line
+ for exclusive use.
+
+2000-02-24 Kevin Buettner <kevinb@redhat.com>
+
+ * ppc-linux-tdep.c (ppc_sysv_abi_push_arguments): Put address
+ of return structure in r3 if necessary.
+ (ppc_linux_memory_remove_breakpoints): New function.
+ * rs6000-tdep.c (skip_prologue): Make sure that the cases
+ for storing either cr or lr to the stack only handle those
+ cases. (I.e, don't let these cases match 0x00000000 which is
+ found found in the shared library trampoline prior to the
+ loading of the shared library.)
+ * config/powerpc/tm-linux.h (ppc_linux_memory_remove_breakpoint):
+ Declare.
+ (MEMORY_REMOVE_BREAKPOINT): Define.
+
+Wed Feb 23 23:27:48 2000 Andrew Cagney <cagney@behemoth.cygnus.com>
+
+ * hppah-nat.c: Include "gdb_wait.h" instead of <wait.h>.
+
+Thu Feb 24 18:42:15 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (CONFIG_INSTALL, CONFIG_UNINSTALL): Set to
+ $(SUBDIR_*_INSTALL) when so configured.
+ * configure: Regenerate.
+
+ * Makefile.in (CONFIG_INSTALL, CONFIG_UNINSTALL): Define using
+ configure.
+ (install-only): Add dependency on $(CONFIG_INSTALL). Delete code
+ installing GDBtk.
+ (uninstall): Add dependency on $(CONFIG_UNINSTALL).
+ (SUBDIR_MI_INSTALL, SUBDIR_MI_UNINSTALL, SUBDIR_GDBTK_UNINSTALL,
+ SUBDIR_GDBTK_INSTALL): Define.
+ (install-gdbtk): New target.
+
+Thu Feb 24 18:19:52 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (SUBDIR_MI_CFLAGS): Fix typo, wrong brace.
+ * configure: Regenerate.
+
+2000-02-24 Christopher Faylor <cgf@cygnus.com>
+
+ * configure.tgt: Add arm, mips, sh wince targets.
+ * config/arm/tm-wince.h: New file.
+ * config/arm/wince.mt: New file.
+ * config/sh/tm-wince.h: New file.
+ * config/sh/wince.mt: New file.
+ * config/mips/tm-wince.h: New file.
+ * config/mips/wince.mt: New file.
+ * wince.c: New file.
+ * wince-stub.c: New file.
+ * wince-stub.h: New file.
+ * sh-tdep.c: Use correct register names for Windows CE.
+
+Wed Feb 23 19:01:45 EST 2000 Nicholas Duffek <nsd@cygnus.com>
+
+ * top.c (SIGJMP_BUF, SIGSETJMP, SIGLONGJMP): Update comments.
+ (error_return, quit_return): Merge into catch_return pointer.
+ (return_to_top_level): Update comment. Longjmp to *catch_errors,
+ and communicate reason to catch_errors via setjmp return value.
+ (catch_errors): Always catch both quit and error, and if a catch
+ wasn't requested by caller, throw it to the next catch_error.
+ Replace dual longjmp buffer memcpy with single pointer change.
+ Add FIXME for possibly adding new interface to tell caller what
+ event was caught. Add extensive comments.
+ * defs.h (enum return_reason): Reserve 0 for use as initial
+ setjmp() return value.
+ (RETURN_MASK): New public macro to generate RETURN_MASK_* from
+ enum return_reason.
+ (RETURN_MASK_QUIT, RETURN_MASK_ERROR): Define using RETURN_MASK.
+
+2000-02-23 Fernando Nasser <fnasser@cygnus.com>
+
+ * infcmd.c (run_stack_dummy): Do not pop frame on random signal.
+ * valops.c (_initialize_valops): Add command "set unwindonsignal".
+ (hand_function_call): Test for unwind_on_signal and act accordingly.
+
+Wed Feb 23 12:58:46 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh (dis_asm_read_memory): Change LEN to unsigned long.
+ Match ../include/dis-asm.h change.
+ * gdbarch.h: Regenerate.
+ * corefile.c (dis_asm_read_memory): Update.
+
+Mon Feb 21 13:57:27 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (CONFIG_INITS): Fix typo, was CONFIG_INIT.
+ (ENABLE_CFLAGS): Move initialization to start of file.
+ (enable-gdbmi): Add new configure option --enable-gdbmi. When
+ selected and an ${srcdir}/mi directory is present enable MI
+ interface.
+
+ * configure: Regenerate.
+
+ * Makefile.in (SUBDIR_MI_OBS, SUBDIR_MI_SRCS, SUBDIR_MI_DEPS,
+ SUBDIR_MI_INITS, SUBDIR_MI_LDFLAGS, SUBDIR_MI_CFLAGS): New macros.
+ (CONFIG_OBS, CONFIG_SRCS, CONFIG_DEPS, CONFIG_INITS,
+ CONFIG_LDFLAGS): New macros. Initialized by autoconf via
+ @CONFIG...@.
+ (INTERNAL_LDFLAGS, CDEPS, LINTFILES, DEPFILES, SOURCES,
+ INIT_FILES): Use $(CONFIG_...) instead of @CONFIG...@.
+
+ * mi: New directory. MI interface to GDB.
+
+ * defs.h (interpreter_p): Declare when UI_OUT.
+ * top.c (gdb_init): When interpreter_p, check that the interpreter
+ was recognized by one of the linked in interpreters.
+ * main.c (interpreter_p): Define.
+ (captured_main): When UI_OUT, check for ``-i <interpreter>'' option.
+ * event-top.c (display_gdb_prompt): When interpreter_p, assume
+ interpreter displays prompt.
+
+ * breakpoint.c (print_it_typical, watchpoint_check,
+ print_one_breakpoint, mention): When MI include additional
+ target status information.
+ * infrun.c (print_stop_reason, normal_stop): Ditto.
+
+2000-02-22 Jim Blandy <jimb@redhat.com>
+
+ * gdbarch.sh: Make the `default' field really default to zero, as
+ documented.
+
+ Bring COERCE_FLOAT_TO_DOUBLE under gdbarch's control.
+ * valops.c (COERCE_FLOAT_TO_DOUBLE): Rework definition to be
+ more function-like.
+ (default_coerce_float_to_double, standard_coerce_float_to_double):
+ New functions.
+ (value_arg_coerce): Adjust for new definition.
+ * value.h (default_coerce_float_to_double,
+ standard_coerce_float_to_double): New declarations for the above.
+ * gdbarch.sh (coerce_float_to_double): New entry, replacing macro.
+ * gdbarch.c, gdbarch.h: Regenerated.
+ * tm-alpha.h, tm-fr30.h, tm-m32r.h, tm-mips.h, tm-hppa.h,
+ tm-rs6000.h, tm-sh.h, tm-sparc.h (COERCE_FLOAT_TO_DOUBLE): Change
+ definitions.
+ * mips-tdep.c (mips_coerce_float_to_double): Supply our own custom
+ function here.
+ (mips_gdbarch_init): Install that as our coerce_float_to_double
+ function.
+
+2000-02-22 Kevin Buettner <kevinb@redhat.com>
+
+ * ppc-linux-nat.c (supply_gregset, supply_fpregset): Add return
+ type.
+ * ppc-linux-tdep.c (ppc_linux_at_sigtramp_return_path): Add
+ forward declaration.
+
+ * ppc-linux-tdep.c (ppc_linux_frame_saved_pc): Handle case
+ where the next frame is a signal handler caller.
+
+ * config/powerpc/tm-linux.h (PUSH_ARGUMENTS): Remove extraneous
+ undef.
+ (tm-linux.h): Include.
+ (tm-sysv4.h): Don't include (directly). config/tm-linux.h will
+ include this file for us.
+ (REALTIME_LO, REALTIME_HI): Don't define. These are defined by
+ config/tm-linux.h for us.
+ (SOFUN_ADDRESS_MAYBE_MISSING): Define.
+
+2000-02-21 Kevin Buettner <kevinb@redhat.com>
+
+ * Makefile.in (ppc-linux-nat.c, ppc-linux-tdep.c): New files.
+ (ppc-linux-nat.o, ppc-linux-tdep.o): Add dependencies.
+ * configure.tgt (powerpc-*-linux*): Separate from powerpc-*-eabi
+ and like targets.
+
+ * ppc-linux-nat.c, ppc-linux-tdep.c, config/powerpc/linux.mt,
+ config/powerpc/nm-linux.h, config/powerpc/tm-linux.h: New files.
+ * config/powerpc/xm-linux.h: Substantially revised for native
+ port.
+ * config/powerpc/linux.mh (NAT_FILE): Redefine to be nm-linux.h.
+ (NATDEPFILES): Update list to reflect the fact that we can
+ now debug natively.
+
+ * rs6000-tdep.c, config/rs6000/tm-rs6000.h
+ (rs6000_frameless_function_invocation, rs6000_frame_saved_pc):
+ Renamed; The former names were lacking the rs6000_ prefix.
+ * rs6000-tdep.c (rs6000_frame_saved_pc): Call FRAME_CHAIN
+ instead of rs6000_frame_chain.
+ (rs6000_frame_chain): Call FRAMELESS_FUNCTION_INVOCATION instead
+ of rs6000_frameless_function_invocation.
+
+2000-02-21 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Philippe De Muyter <phdm@macqel.be>
+
+ * event-loop.c (handle_file_event): In case of poll, enable
+ printing of informational message if an error/exception is
+ detected on the file descriptor.
+
+2000-02-21 Jim Kingdon <kingdon@redhat.com>
+
+ * MAINTAINERS (Misc): Clarify that yes, anyone can edit web pages.
+
+Mon Feb 21 12:50:57 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * buildsym.c: Include "language.h" and "expression.h" for
+ longest_local_hex_string_custom.
+
+Mon Feb 21 11:17:18 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbarch.sh: Include <gdb_wait.h> instead of <wait.h>.
+ * gdbarch.c: Already updated by Wed Feb 9 18:59:16 2000 Andrew
+ Cagney <cagney@b1.cygnus.com>.
+
+Mon Feb 21 11:03:01 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Update: IA-64 - Kevin Buettner; ARM - Fernando
+ nasser, Jim Ingham and Scott Bambrough; GNU/Linux ARM - Scott
+ Bambrough; event loop - Elena Zannoni; SDS and RDI/APD protocol -
+ to Fernando Nasser and Jim Ingham; KOD - Fernando Nasser; MI -
+ Andrew Cagney, Elena Zannoni and Fernando Nasser; Web pages - Jim
+ Kingdon.
+ * MAINTAINERS: Add Nick Clifton to write after approval list.
+
+Mon Feb 21 10:30:39 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Add note on multiple maintainers.
+
+2000-02-19 Philippe De Muyter <phdm@macqel.be>
+
+ * cli-out.c (cli_table_header): Type of parameter `alignment' is
+ `enum ui_align', not `int'.
+ (cli_field_string, cli_field_skip): Likewise.
+
+2000-02-18 Jim Blandy <jimb@redhat.com>
+
+ From Jimmy Guo <guo@cup.hp.com>:
+ * buildsym.h (add_free_pendings): Declare.
+ * buildsym.c (add_free_pendings): New function.
+ (make_blockvector): 32x64 fix using longest_local_hex_string().
+ (start_subfile): initialize variable 'subfile'.
+
+2000-02-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * remote.c (remote_async_detach): Use target_mourn_inferior(), to
+ make sure that all is cleaned up after we disconnect from the
+ target.
+ (remote_detach): Ditto.
+
+2000-02-17 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From Rodney Brown <RodneyBrown@pmsc.com>
+ * ui-out.c (ui_out_set_flags): Fix typo, removing warning and
+ potentially harming mistake.
+
+2000-02-17 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * arm-tdep.c: Use header file instead of extern declarations for
+ the {get,set}_arm_regname* functions.
+
+2000-02-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * configure.in: Replaces obsolete gdbtk-variable.c with
+ gdbtk-varobj.c.
+ * configure: Regenerate.
+ * Makefile.in: Remove obsolete/extraneous references to
+ gdbtk-var* files.
+
+2000-02-16 Mark Kettenis <kettenis@gnu.org>
+
+ * target.c (do_target_signal_to_host): Do not use REALTIME_LO in
+ the conversion of the signal number. TARGET_SIGNAL_REALTIME_33 is
+ 33 by definition, whereas REALTIME_LO might be 32 on systems that
+ have SIG32 such as Linux. Make sure that the signal number
+ returned is within the range specified by REALTIME_LO and
+ REALTIME_HI.
+
+2000-02-16 Mark Kettenis <kettenis@gnu.org>
+
+ * configure: Regenerated.
+
+2000-02-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * arm-tdep.c (set_disassembly_flavor, arm_othernames,
+ _initialize_arm_tdep): Allows the user to choose between any of
+ the flavors available for the disassembly to be used in the "info
+ reg" command and elsewhere in gdb. It prevents having to maintain
+ this information in two places by using the data kept in the
+ opcodes directory.
+
+2000-02-09 Mark Kettenis <kettenis@gnu.org>
+
+ * configure.in: Check for lwpid_t, psaddr_t, prgregset_t and
+ prfpregset_t in <sys/procfs.h>.
+ * config.in: Add HAVE_LWPID_T, HAVE_PSADDR_T, HAVE_PRGREGSET_T,
+ HAVE_PRFPREGSET_T.
+ * gdb_proc_service.h: Only provide typedefs for lwpid_t, psaddr_t,
+ prgregset_t and prfpregset_t if they are not already present.
+
+Wed Feb 16 19:00:02 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-01-26 Rodney Brown <RodneyBrown@pmsc.com>:
+ * procfs.c: Define MERGEPID if not defined. For osf4.0e.
+
+2000-02-15 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * Makefile.in (diststuff): Run 'diststuff' in doc/ subdir, not
+ 'do-doc'.
+
+2000-02-15 Kevin Buettner <kevinb@redhat.com>
+
+ Changes for AIX 4.3:
+ * rs6000-tdep.c (rs6000_fix_call_dummy): Set TOC register
+ to correct value for generic dummy frames. When using
+ generic dummy frames, don't attempt to write TOC value or
+ function to call into the call dummy.
+ (rs6000_push_arguments): Adapt USE_GENERIC_DUMMY_FRAMES
+ code to also handle the PowerOpen ABI.
+ (ppc_push_return_address): Enable for all ports.
+ * config/powerpc/tm-ppc-aix.h (USE_GENERIC_DUMMY_FRAMES,
+ PUSH_DUMMY_FRAME, PUSH_RETURN_ADDRESS, GET_SAVED_REGISTER,
+ CALL_DUMMY_BREAKPOINT_OFFSET, CALL_DUMMY_LOCATION,
+ CALL_DUMMY_ADDRESS, CALL_DUMMY_START_OFFSET): Override defaults
+ provided by generic RS6000 definitions so that call dummies
+ are implemented using generic dummy frames instead.
+
+ * rs6000-nat.c (store_inferior_registers): Call exec_one_dummy_insn()
+ prior to changing the stack pointer via ptrace(). Also, ignore
+ attempts to store to undefined registers that are less than
+ NUM_REGS.
+
+ * rs6000-tdep.c (DUMMY_FRAME_SIZE): Change size of the dummy
+ frame from 436 to 448 to account for alignment padding.
+ (rs6000_push_arguments): Obtain actual register size instead
+ of assuming the register is 4 bytes long. [There's still
+ more work to be done to totally remove the 4 byte assumption,
+ however.] Make sure the stack is 16 byte aligned as required
+ by the PowerOpen ABI. Also, make sure that small structures
+ passed in registers are properly aligned within the register.
+
+2000-02-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ Patch applied by Kevin Buettner <kevinb@redhat.com>
+
+ * rs6000-tdep.c (skip_prologue): skip copying of argument
+ registers to local variable registers.
+
+2000-02-14 Jim Kingdon <kingdon@redhat.com>
+
+ * elfread.c (elf_symtab_read): Revert changes by Amit S. Kale. A
+ sym->section->index number is not a SECT_OFF_* code.
+
+Tue Feb 15 12:07:30 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS (write after approval): Add H.J. Lu.
+
+2000-02-14 Nick Clifton <nickc@cygnus.com>
+
+ * sh-tdep.c: Remove extraneous code.
+
+2000-02-14 Amit S. Kale <akale@veritas.com>
+
+ * elfread.c (elf_symtab_read): Move the use of sym to after where
+ it is set.
+ Checked in by Jim Kingdon <kingdon@redhat.com>
+
+Mon Feb 14 15:39:01 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Make Nick Duffek the UnixWare threads maintainer.
+
+Mon Feb 14 15:20:26 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 1999-11-24 Jason Merrill <jason@casey.cygnus.com>:
+ * dwarf2read.c: (die_is_declaration): New fn.
+ (read_structure_scope): Use it.
+
+ * dwarf2read.c: (die_is_declaration): Convert to ISO-C.
+
+2000-02-10 J.T. Conklin <jtc@redback.com>
+
+ * config/i386/nbsd.mt (GDBSERVER_DEPFILES): Add low-nbsd.o
+ * configure.tgt (i[3456]86-*-netbsd*): add gdbserver to
+ configdirs.
+ * gdbserver/low-nbsd.c: New file.
+
+ * gdbserver/Makefile.in: convert to autoconf.
+ * gdbserver/configure.in: likewise.
+ * gdbserver/configure: generate.
+
+Sun Feb 13 11:21:00 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * CONTRIBUTE: New file. How to contribute to GDB.
+
+Sun Feb 13 10:34:48 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Add Eli Zaretskii to djgpp maintiners. Add Kevin
+ Buettner to powerpc maintainers. Make Kevin Buettner the
+ GNU/LINUX PPC native maintainer. Add J.T. Conklin, Jim Kingdon
+ and Jason Molenda to write after aproval list.
+
+Sun Feb 13 10:18:44 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Reformat. Separate into check-in categories.
+
+Sat Feb 12 01:08:21 EST 2000 Nicholas Duffek <nsd@cygnus.com>
+
+ * uw-thread.c: Remove __FUNCTION__ GNUism.
+
+2000-01-17 Amit S. Kale <akale@veritas.com>
+
+ * elfread.c (elf_symtab_read): Use offset for the section in which a
+ symbol resides, instead of .text section for calculating address of a
+ symbol.
+ Checked in by Jim Kingdon <kingdon@redhat.com>
+
+2000-02-10 Mark Kettenis <kettenis@gnu.org>
+
+ * gnu-nat.c: Remove hackery to include <bits/waitflags.h>. It is
+ no longer necessary now we have gdb_wait.h.
+
+2000-02-09 Mark Kettenis <kettenis@gnu.org>
+
+ * gnu-nat.c (proc_string): Make global.
+ (do_mach_notify_dead_name): Suppress dead name notifications if we
+ know that the task is dead.
+
+1999-12-13 Mark Kettenis <kettenis@gnu.org>
+
+ * gnu-nat.c (inf_validate_task_sc): Get task info via proc server
+ instead of directly from the kernel. Add some hackery to make
+ sure that the info isn't influenced by suspension of the task in
+ the proc server itself.
+
+2000-02-10 Jim Kingdon <kingdon@redhat.com>
+
+ * defs.h (MERGEPID): Added. Patch submitted by Andrew Hobson and
+ approved by Michael Snyder.
+
+2000-02-09 Mark Kettenis <kettenis@gnu.org>
+
+ * linux-thread.c: Include defs.h before gdb_wait.h.
+
+Wed Feb 9 18:59:16 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (wait_h): Delete macro. Update all dependencies
+ specifying gdb_wait.h instead.
+
+ * ser-unix.c, ser-pipe.c, remote.c, remote-udi.c, remote-sds.c,
+ remote-os9k.c, remote-es.c, remote-rdp.c, remote-vx960.c,
+ remote-vx.c, remote-st.c, remote-nindy.c, remote-mm.c,
+ convex-xdep.c, convex-tdep.c, target.c, win32-nat.c, standalone.c,
+ remote-vxmips.c, remote-vxsparc.c, remote-vx68.c, remote-vx29k.c,
+ remote-sim.c, remote-rdi.c, remote-mips.c, remote-eb.c,
+ remote-e7000.c, remote-bug.c, remote-array.c, remote-adapt.c,
+ ppc-bdm.c, ocd.c, monitor.c, m3-nat.c, linux-thread.c,
+ infttrace.c, lin-thread.c, infptrace.c, gnu-nat.c, gdbarch.c,
+ fork-child.c, command.c: Include "gdb_wait.h" instead of <wait.h>
+ or <sys/wait.h>.
+ * nindy-share/nindy.c, nindy-share/Onindy.c: Ditto.
+
+ * gdb_wait.h: New file. Based on ../include/wait.h. Include
+ <sys/wait.h> or <wait.h> and then define any missing WIF macros.
+
+Wed Feb 9 01:14:54 2000 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * config/d10v/tm-d10v.h (NO_EXTRA_ALIGNMENT_NEEDED): Define.
+ * config/d10v/tm-d10v.h (STACK_ALIGN): Define.
+ (d10v_stack_align): Declare.
+ * d10v-tdep.c (d10v_stack_align): Define.
+
+1999-08-23 J.T. Conklin <jtc@redback.com>
+
+ * top.c (remote_timeout): Change default to 2. Add comment
+ explaining history of changes to the default value.
+ * remote.c (_initialize_remote): Remove code that adds set/
+ show remotetimeout, as that's also done in top.c
+
+1999-10-18 J.T. Conklin <jtc@redback.com>
+
+ * m32r-stub.c, sparcl-stub.c, sparclet-stub.c (handle_exception):
+ Return E01 instead of P01 when 'P' command fails.
+
+2000-02-05 J.T. Conklin <jtc@redback.com>
+
+ * remote.c (putpkt_binary): Handle NAK from target stub.
+
+2000-02-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * configure.in: Remove the addition of sol-thread.c to the
+ CONFIG_INITS list. This caused problems with init.c, because
+ sol-thread.c would be grepped twice for _initialize_* functions.
+ * configure: Ditto.
+ * Makefile.in: Add FIXME for init.c.
+
+2000-02-07 Jim Kingdon <kingdon@redhat.com>
+
+ Clean up compiler warnings:
+ * bcache.h, bcache.c, c-valprint.c, coffread.c, stabsread.c,
+ stack.c, valprint.c: Change variables to unsigned.
+ * bcache.c: Rearrange to avoid warnings about variables not being set.
+ * c-lang.c, ch-lang.c, f-lang.c, m2-lang.c: Include valprint.h
+ rather than declaring print_max and repeat_count_threashold
+ ourselves (incorrectly).
+ * valprint.h: Do declare repeat_count_threashold.
+ * ch-exp.c: Use default case for internal error.
+ * findvar.c: Don't omit argument type.
+ * symtab.c: Remove unused variable.
+
+2000-02-04 Jim Blandy <jimb@redhat.com>
+
+ * c-typeprint.c (remove_qualifiers): New function.
+ (c_type_print_base): Use it to remove qualifiers from C++
+ qualified names, not strrchr.
+
+ * c-typeprint.c (c_type_print_base): Recognize type conversion
+ operators by calling is_type_conversion_operator.
+ (is_type_conversion_operator): New function.
+
+2000-02-04 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/tm-arm.h (LOWEST_PC): Define.
+
+2000-02-04 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * infrun.c (resume): Make just one call to target_resume(), instead
+ of four: set up correct parameters in all the cases ahead of time,
+ and do call at the end.
+
+2000-02-04 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * config/powerpc/tm-ppc-eabi.h: Define
+ SOFUN_ADDRESS_MAYBE_MISSING.
+
+2000-02-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * arm-tdep.c (arm_pc_is_thumb_dummy): Account for large dummy
+ frames (revisited).
+
+Fri Feb 4 22:42:36 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (INIT_FILES): Append CONFIG_INITS
+ * configure.in (CONFIG_INIT): Initialize.
+ (links): Link srcdir/gdbtk/library to gdbtcl2.
+ * gdbtcl2: Moved to gdbtk/library.
+ ChangeLog-gdbtk, gdbtk-cmds.c, gdbtk-hooks.c, gdbtk-variable.c,
+ gdbtk-varobj.c, gdbtk-wrapper.c, gdbtk-wrapper.h, gdbtk.c,
+ gdbtk.h: Moved to gdbtk/generic.
+
+2000-02-03 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * printcmd.c (build_address_symbolic): New function. Returns all
+ the parts that are necessary to print an address in a symbolic
+ form.
+ (print_address_symbolic): Split into a printing part and an
+ information building part, build_address_symbolic().
+
+ * defs.h (build_address_symbolic): Export.
+
+2000-02-03 Jim Blandy <jimb@redhat.com>
+
+ * dwarf2read.c (decode_locdesc): Add support for the DW_OP_bregx
+ opcode.
+
+2000-02-02 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * arm-tdep.c (arm_push_arguments): Fix passing of floating point
+ arguments on dummy frames.
+
+2000-02-02 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * arm-tdep.c (arm_pc_is_thumb_dummy): Account for large dummy frames.
+ (arm_pop_frame): Account fr dummy frames (as opposed to real ones).
+
+2000-02-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * remote.c (getpkt_sane): New function. It is the old getpkt(),
+ which now returns a timeout indication.
+ (getpkt): New function. Wrapper for getpkt_sane(), so that return
+ value can still be ignored.
+
+Tue Feb 1 18:47:31 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c (print_gdb_version): Print ``UI_OUT'' when configured with
+ UI_OUT.
+
+Tue Feb 1 00:17:12 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ui-file.c, ui-file.h: Rename gdb-file.h, gdb-file.c. Rename
+ ``struct gdb_file'' to ``struct ui_file''. Delete typedef
+ GDB_FILE.
+
+ * Makefile.in: Update.
+
+ * ax-gdb.c, ax-general.c, ax.h, buildsym.c, c-lang.c, c-lang.h,
+ c-typeprint.c, c-valprint.c, ch-lang.c, ch-lang.h, ch-typeprint.c,
+ ch-valprint.c, command.c, command.h, convex-tdep.c, corefile.c,
+ cp-valprint.c, d10v-tdep.c, d30v-tdep.c, defs.h, expprint.c,
+ expression.h, f-lang.c, f-lang.h, f-typeprint.c, f-valprint.c,
+ frame.h, gdb-events.sh, gdb-file.c, gdb-file.h, gdbcmd.h,
+ gdbtypes.h, hppa-tdep.c, jv-lang.c, jv-lang.h, jv-typeprint.c,
+ jv-valprint.c, language.c, language.h, m2-lang.c, m2-lang.h,
+ m2-typeprint.c, m2-valprint.c, m3-nat.c, main.c, monitor.c,
+ printcmd.c, pyr-tdep.c, remote-mips.c, remote-sim.c, remote-udi.c,
+ remote.c, scm-lang.c, scm-lang.h, scm-valprint.c, ser-e7kpc.c,
+ ser-go32.c, ser-mac.c, ser-ocd.c, ser-unix.c, ser-unix.h,
+ serial.c, serial.h, stack.c, symfile.c, symmisc.c, tahoe-tdep.c,
+ target.c, target.h, top.c, top.h, typeprint.c, typeprint.h,
+ utils.c, v850ice.c, valprint.c, valprint.h, value.h,
+ config/pa/tm-hppa.h: Update.
+ * cli-out.c, cli-out.h, ui-out.c, ui-out.h, varobj.c: Update.
+
+2000-01-31 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * config/alpha/alpha-osf2.mh, config/alpha/alpha-osf3.mh,
+ config/i386/i386dgux.mh, config/i386/i386sol2.mh,
+ config/i386/i386v4.mh, config/i386/i386v42mp.mh,
+ config/i386/ncr3000.mh, config/m68k/m68kv4.mh,
+ config/m88k/delta88v4.mh, config/mips/irix4.mh,
+ config/mips/irix5.mh, config/mips/mipsv4.mh,
+ config/powerpc/solaris.mh (NATDEPFILES): Change references to
+ proc_api.o, proc_events.o, proc_flags.o, and proc_why.o to
+ proc-api.o, proc-events.o, proc-flags.o, and proc-why.o.
+
+Mon Jan 31 17:14:52 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c (fputs_unfiltered_hook): Moved to tui/tui-file.c.
+
+ * main.c (captured_main): Only use the legacy tui_file code when
+ linking in older code such as the TUI.
+
+ * gdb-file.h, gdb-file.c: New files.
+ * utils.c, defs.h (struct gdb_file, gdb_file_new, gdb_file_delete,
+ null_file_isatty, null_file_rewind, null_file_put,
+ null_file_flush, null_file_write, null_file_fputs,
+ null_file_delete, gdb_file_data, gdb_flush, gdb_file_isatty,
+ gdb_file_rewind, gdb_file_put, gdb_file_write, fputs_unfiltered,
+ set_gdb_file_flush, set_gdb_file_isatty, set_gdb_file_rewind,
+ set_gdb_file_put, set_gdb_file_write, set_gdb_file_fputs,
+ set_gdb_file_data, struct accumulated_gdb_file,
+ do_gdb_file_xstrdup, gdb_file_xstrdup, struct mem_file):
+ mem_file_new, mem_file_delete, mem_fileopen, mem_file_rewind,
+ mem_file_put, mem_file_write, struct stdio_file): stdio_file_new,
+ stdio_file_delete, stdio_file_flush, stdio_file_write,
+ stdio_file_fputs, stdio_file_isatty, stdio_fileopen, gdb_fopen):
+ Moved to gdb-file.h and gdb-file.c.
+ * utils.c (enum streamtype, struct tui_stream, tui_file_new,
+ tui_file_delete, tui_fileopen, tui_sfileopen, tui_file_isatty,
+ tui_file_rewind, tui_file_put, tui_file_fputs,
+ tui_file_get_strbuf, tui_file_adjust_strbuf, tui_file_flush,
+ fputs_unfiltered_hook):
+ Moved to tui/tui-file.c and tui/tui-file.h.
+
+ * Makefile.in (COMMON_OBS): Add gdb-file.o, tui-file.o.
+ (tui-file.o, gdb-file.o): Add dependencies.
+ (corefile.o, main.o, utils.o, simmisc.o): Update dependencies.
+ * main.c: #include tui/tui-file.h.
+
+2000-01-28 Fred Fish <fnf@cygnus.com>
+
+ * findvar.c (value_from_register): Special case handling of D10V
+ pointer values fetched from registers.
+
+2000-01-28 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * arm-tdep.c (thumb_skip_prologue, thumb_scan_prologue): Add
+ support for new style thumb prologues.
+
+2000-01-28 Nick Clifton <nickc@redhat.com>
+
+ * arm-tdep.c: Remove extraneous dash at start of strings
+ introduced in previous delta.
+
+2000-01-27 Nick Clifton <nickc@redhat.com>
+
+ * arm-tdep.c: Replace uses of arm_toggle_renames() with
+ parse_arm_disassembler_option().
+
+2000-01-27 Jim Blandy <jimb@cygnus.com>
+
+ * symtab.c (decode_line_1): Don't let commas that are within
+ quotes or parenthesis terminate the line spec. Don't use pp when
+ removing the final double quote of a double-quoted string. Don't
+ forget to skip the opening double quote. I have no clue whether
+ this change is correct; probably we've just moved this function
+ from one buggy place to another buggy place, and never came within
+ an outhouse whiff of correctness.
+ (find_toplevel_char): New function.
+
+2000-01-27 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * arm-tdep.c (arm_push_arguments): Set the thumb mode bit when
+ passing the pointer to a thumb function as an argument.
+
+2000-01-27 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * remote-rdi.c (arm_rdi_mourn_inferior): Make sure breakpoints
+ are reinserted for another run.
+
+2000-01-27 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * cli-out.c (cli_filed_string): Test for NULL string.
+
+2000-01-27 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * infcmd.c (run_stack_dummy): Account for a random signal stopping
+ the inferior as well as breakpoints being hit while performing an
+ inferior function call.
+ * valops.c (hand_function_call): Ditto.
+
+2000-01-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-i386gnu.h (THREAD_STATE_FLAVOR): Define to
+ i386_REGS_SEGS_STATE.
+ (HAVE_I387_REGS): Define.
+ (FLOAT_INFO): Remove.
+ * i386gnu-nat.c: Almost completely rewritten to use new i386
+ register layout and `float info' implementation.
+ * gnu-nat.c (inf_update_procs, proc_get_state, proc_string):
+ Move prototypes from here.
+ * gnu-nat.h: To here.
+
+2000-01-24 Kevin Buettner <kevinb@redhat.com>
+
+ * utils.c (get_field, put_field): Fix buffer underruns and
+ overruns. Also, handle case where total_len is not evenly
+ divisible by 8.
+ (getfield): Make sure zeroing of unwanted bits occurs even
+ when bit field to extract does not straddle two or more
+ bytes.
+
+2000-01-23 Christopher Faylor <cgf@cygnus.com>
+
+ * defs.h: Add gdb_thread_select declaration.
+
+2000-01-23 Kevin Buettner <kevinb@redhat.com>
+
+ * linux-thread.c (_initialize_linuxthreads): Make sure that
+ linuxthreads_block_mask does not block SIGCHLD.
+
+2000-01-20 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * rdi-share/devsw.c (openLogFile): On cygwin, set the log mode to
+ text so that new lines work properly.
+
+2000-01-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * proc-utils.h: New file. Export functions from proc-*.c.
+
+ * proc_api.c: Rename to:
+ * proc-api.c: New file. Add include of proc-utils.h.
+
+ * proc_events.c: Rename to:
+ * proc-events.c: New file.
+
+ * proc_flags.c: Rename to:
+ * proc-flags.c: New file.
+
+ * proc_why.c: Rename to:
+ * proc-why.c: New file. Add include of proc-utils.h.
+
+ * procfs.c: Add includes of gdbthread.h, sys/wait.h, signal.h,
+ ctype.h, proc-utils.h.
+ (find_procinfo_or_die): Add braces to avoid ambiguous else clause.
+ (open_procinfo_files): Conditionalize local variable tmp, to avoid
+ compiler warnings.
+ (proc_iterate_over_mappings): Conditionalize local vars mapfd and
+ pathname.
+ (procfs_wait): Adjust format in some printf_filetered calls to
+ avoid compiler warnings.
+ (make_signal_thread_runnable): Ifdef 0. The calls to this function
+ are also ifdef'd 0 .
+ (procfs_resume): Add parentheses around '&&' operation.
+ (procfs_set_exec_trap): Remove unused variable.
+ (info_proc_cmd): Add braces to avoid ambiguous else clause.
+
+ * Makefile.in (procfs.o, proc-api.o, proc-events.o, proc-flags.o,
+ proc-why.o): Update dependencies.
+
+ * config/sparc/sun4sol2.mh (NATDEPFILES): Change proc_*.o files to
+ proc-*.o.
+
+2000-01-17 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in (NEW_PROC_API): Fix Unixware-matching regexp.
+ Fix from Robert Lipe <robertl@sco.com>.
+ * configure: Regenerated.
+
+2000-01-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * stack.c (print_frame_info_base): Break up into the frame info
+ (location) printing part and the rest (source line printing).
+ (print_frame): New function. Take care of printing the location
+ information.
+ Update copyright.
+
+ * infrun.c (normal_stop): Use enum values rather than integers for the
+ source_flag to be passed to show_and_print_stack_frame().
+ Update copyright.
+
+ * frame.h (print_what): New enum for 'source' argument to
+ print_frame_info_base(). Use this instead of obscure numbers.
+ Update copyright.
+
+Sun Jan 16 17:58:00 2000 David Taylor <taylor@texas.cygnus.com>
+
+ * event-top.c (stdin_event_handler): call quit_command rather than
+ exit -- run cleanups, give target code a chance to say goodbye to
+ the target. Fixes bug where the inferior processes were left
+ around on Solaris (and probably elsewhere) by the testsuite.
+
+2000-01-14 Mark Salter <msalter@cygnus.com>
+
+ * v850-tdep.c (v850_target_architecture_hook): Setup correct
+ machine id for disassembly.
+
+2000-01-13 Jim Blandy <jimb@cygnus.com>
+
+ * i386-linux-nat.c (fill_gregset): Pass the correct arguments to
+ convert_to_regset, when regno indicates a specific register.
+
+Thu Jan 13 23:34:17 EST 2000 Nicholas Duffek <nsd@cygnus.com>
+
+ * uw-thread.c: Document libthread.so debugging interface. Minor
+ comment and formatting tweaks.
+ (DEBUG): #define as 0 instead of 1.
+ (CALL_BASE): Include function name in error msg.
+ (libthread_stub): Adjust inferior_pid after thread exit.
+ (uw_thread_create_inferior): Deactivate uw_thread_ops before
+ asking procfs_ops to create inferior.
+ (libthread_init): Don't return nonlocally on error.
+
+2000-01-12 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * rdi-share/ardi.c (negotiate_params): Fix initialization of static
+ variable.
+
+2000-01-12 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * remote-rdi.c (arm_rdi_open): Call arm-rdi-close() to make sure
+ both sides are on the same state.
+
+2000-01-12 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * rdi-share/serdrv.c (find_baud_rate): Fix entries for 57600 and
+ 115200 (minor syntax mistake).
+
+2000-01-12 Jim Blandy <jimb@cygnus.com>
+
+ * config/sparc/tm-sun4sol2.h (MERGEPID): Provide a definition for
+ this here, to go along with the definitions of PIDGET and TIDGET.
+
+2000-01-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * thread.c (do_captured_thread_select): New function. Switch
+ current thread, safely from within catch_errors().
+ (gdb_thread_select): New function. Switch threads safely.
+ (thread_command): Use gdb_thread_select().
+ Include ui-out.h.
+ (do_captured_list_thread_ids): New function.
+ (gdb_list_thread_ids): New function.
+
+ * defs.h (gdb_thread_select, gdb_list_thread_ids): Export.
+
+2000-01-11 Christopher Faylor <cgf@cygnus.com>
+
+ * configure.in: Avoid linking -limagehlp unless it's a native build.
+ * configure: Regenerate.
+ * thread.cc (add_thread): Clear private data pointer here or suffer
+ strange behavior when it is checked for NULL later.
+
+2000-01-09 Christopher Faylor <cgf@cygnus.com>
+
+ * win32nat.c (handle_exceptions): Handle various arithmetic exceptions.
+ * configure.in: Add an additional library to cygwin link.
+ * configure: Regenerate.
+
+ Patch from Egor Duda <deo@logos-m.ru>:
+ * coffread.c (coff_symfile_read): Reinstate ability to recognize "pe"
+ type.
+
+2000-01-07 Michael Snyder <msnyder@cygnus.com>
+
+ * uw-thread.c: New file to support UnixWare user-mode threads:
+ contributed by Nickolas Duffek <nsd@cygnus.com>.
+ * target.h (struct target_ops): New vector, to_extra_thread_info,
+ allows back-ends to give extra details in info thread display.
+ (target_extra_thread_info): define new macro.
+ (target_find_new_threads): simplify macro. Cleanup comments.
+ * target.c (to_extra_thread_info): default and inherit new vector.
+ (cleanup_target): eliminate PARAMS, break up long lines,
+ provide default definition for to_extra_thread_info, and
+ to_find_new_threads. Default to_thread_alive and to_query
+ to return_zero, not target_ignore (they each return int not void).
+ (debug_to_find_new_threads): new debug entry.
+ (setup_target_debug): add debug_to_find_new_threads.
+ * gdbthread.h: export struct thread_info, find_thread_pid, and
+ iterate_over_threads. Add comments. Eliminate PARAMS. Update
+ copyright. Add new private data pointer for use by target back-ends.
+ * thread.c (struct thread_info): move definition to gdbthread.h.
+ (find_thread_pid): new exported function for thread lookup.
+ (iterate_over_threads): new exported function for applying
+ arbitrary operations to threads. Update copyright to 2000.
+ (info_threads_command): use new target_extra_thread_info vector
+ to display extra information about each thread (if implemented).
+ * config/i386/tm-i386v42mp.h: remove obsolete #defines for procfs.
+ Add defines for PIDGET, etc.
+ * config/i386/tm-i386sol2.h: ditto.
+ * config/sparc/tm-sun4sol2.h: ditto.
+ * config/i386/i386v42mp.mh: add uw-thread.o to NATDEPFILES.
+ * testsuite/gdb.threads/pthreads.exp: Try to link with -lthread
+ if -lpthread and -lpthreads fail.
+
+ * procfs.c: (PIDGET, TIDGET, MERGEPID): change default to no-op.
+ (proc_flags): combine flags that UnixWare splits into two locations.
+ (proc_modify_flag): add support for PR_KLC (kill on last close).
+ (proc_[un]set_kill_on_last_close): new functions.
+
+2000-01-07 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * infrun.c (normal_stop): Print out thread id when we stop.
+
+2000-01-06 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * remote.c (remote_open_1): Fix message so it does not imply a
+ specific syntax for serial ports, as it is OS dependent.
+ (remote_async_open_1): Ibid.
+ (init_remote_ops): Ibid.
+
+2000-01-06 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * rdi-share/serdrv.c (SerialOpen): Use speed from "-b" argument or
+ "set remotebaud" command (if set) when no speed is specified on
+ the "target rdi" command.
+
+2000-01-06 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * rdi-share/serdrv.c (find_baud_rate): Add entries for 57600 and
+ 115200.
+ (baud_options[]): Ibid.
+
+2000-01-06 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * rdi-share/unixcomm.c: Fix SERIAL_PREFIX so it matches the prefix
+ used by each operating system.
+
+2000-01-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * breakpoint.c (until_break_command): Add an argument for the
+ continuation, the beginning of the cleanups set up by this
+ command.
+ (until_break_command_continuation): Do cleanups until the one
+ passed in as argument instead of doing all of them.
+
+ * infcmd.c (finish_command_continuation): Expect a new argument,
+ which indicates up to where to do cleanups. Update calls to
+ do_exec_cleanups to use this marker, instead of ALL_CLEANUPS.
+ (finish_command): Add another argument for the continuation: the
+ starting cleanup for this command.
+
+2000-01-05 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From Grant Edwards <grante@visi.com> (original patch from Thomas
+ Zenker ):
+ * rdi-share/ardi.c: Allow interruption of interruptible
+ targets with a <CNTL-C>.
+
+2000-01-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * rdi-share/etherdrv.c (fetch_ports): Send extra words on request
+ to control port to accommodate some versions of Angel.
+
+2000-01-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * rdi-share/devsw.c (dumpPacket): Fix source of channel information.
+ Add interpretation for C Support Library packets.
+
+2000-01-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * rdi-share/devsw.c (DevSW_Close): Remove const from argument that
+ is now being modified.
+ * rdi-share/devsw.h: Adjust declaration of the above funtion.
+
+For older changes see ChangeLog-1999
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/ChangeLog-2001 b/gdb/ChangeLog-2001
new file mode 100644
index 00000000000..ccd64de50a3
--- /dev/null
+++ b/gdb/ChangeLog-2001
@@ -0,0 +1,9895 @@
+2001-12-30 Michael Snyder <msnyder@redhat.com>
+
+ * sparc-tdep.c (sparc-store-return-value): Whitespace fix-up.
+
+2001-12-29 Elena Zannoni <ezannoni@redhat.com>
+
+ * Makefile.in (rs6000-tdep.o): Add dependency on parser-defs.h.
+
+ * rs6000-tdep.c: Include parser-defs.h.
+ (rs6000_register_virtual_type): Rewrite, including handling of
+ AltiVec regs type.
+ (altivec_register_p): New function.
+ (rs6000_do_altivec_registers): New function.
+ (rs6000_altivec_registers_info): New function.
+ (rs6000_do_registers_info): New function.
+ (R16): Define.
+ (PPC_ALTIVEC_REGS): Define.
+ (registers_powerpc): Add AltiVec registers.
+ (registers_7400): Define.
+ (variants): Add 7400 machine.
+ (rs6000_gdbarch_init): Set the numbers of AltiVec registers.
+ Initialize gdbarch_do)_registers_info.
+ (rs6000_info_power_command): New function.
+ (info_power_cmdlist): New static variable.
+ (_initialize_rs6000_tdep): Add new 'info powerpc altivec' command.
+
+ * ppc-tdep.h (struct gdbarch_tdep): Add altivec regnum fields.
+ (altivec_register_p): Export.
+
+2001-12-29 Mark Kettenis <kettenis@gnu.org>
+
+ * i386bsd-nat.c (reg_offset): Fix typo.
+
+ * i386-tdep.c (i386_push_dummy_frame): Don't write back the
+ modified frame pointer until the old frame pointer has been saved.
+
+2001-12-30 Andrew Cagney <ac131313@redhat.com>
+
+ * arch-utils.c (initialize_current_architecture): Test byte_order
+ against BFD_ENDIAN_UNKNOWN.
+ (gdbarch_info_init): Initialize byte_order to BFD_ENDIAN_UNKNOWN.
+ * gdbarch.sh: Update comments on default value of byte_order.
+ (verify_gdbarch, gdbarch_update_p): Test byte_order against
+ BFD_ENDIAN_UNKNOWN.
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+2001-12-27 Michael Snyder <msnyder@redhat.com>
+
+ * i386-linux-nat.c: Include i386-tdep.h.
+
+ * maint.c (match_substring): GNU coding standards fixes.
+ (print_bfd_section_info): Ditto.
+ (print_objfile_section_info): Ditto.
+
+2001-12-27 Mark Kettenis <kettenis@gnu.org>
+
+ * maint.c (match_substring): Make parameters `string' and `substr'
+ const. Make local variable `tok' const.
+
+2001-12-27 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-i386.h (FP7_REGNUM, FIRST_FPU_CTRL_REGNUM,
+ FCTRL_REGNUM, FPC_REGNUM, FSTAT_REGNUM, FTAG_REGNUM, FCS_REGNUM,
+ FCOFF_REGNUM, FDS_REGNUM, FDOFF_REGNUM, FOP_REGNUM,
+ LAST_FPU_CTRL_REGNUM, XMM0_REGNUM, XMM7_REGNUM, MXCSR_REGNUM,
+ IS_FP_REGNUM, IS_SSE_REGNUM): Removed.
+ (FP0_REGNUM): Define conditionally depending on HAVE_I387_REGS.
+ (SIZEOF_FPU_CTRL_REGS): Hardcode value.
+ * i386-tdep.h (struct gdbarch_tdep): Change such that it contains
+ a single member `num_xmm_regs'.
+ (FPC_REGNUM): New macro.
+ (FIRST_FPU_REGNUM, LAST_FPU_REGNUM, FISRT_XMM_REGNUM,
+ LAST_XMM_REGNUM, MXCSR_REGNUM, FIRST_FPU_CTRL_REGNUM,
+ LAST_FPU_CTRL_REGNUM): Removed.
+ (FCTRL_REGNUM, FSTAT_REGNUM, FTAG_REGNUM, FOP_REGNUM, XMM0_REGNUM,
+ MXCSR_REGNUM): Define unconditionally. Change macros to match the
+ comment describing the register layout.
+ (FISEG_REGNUM, FIOFF_REGNUM, FOSEG_REGNUM, FOOFF_REGNUM): New macros.
+ (FP_REGNUM_P, FPC_REGNUM_P, SSE_REGNUM_P): New macros.
+ (IS_FP_REGNUM, IS_FPU_CTRL_REGNUM, IS_SSE_REGNUM): Make obsolete,
+ unconditionally define in terms of FP_REGNUM_P, FPC_REGNUM_P and
+ SSE_REGNUM_P).
+ (FCS_REGNUM, FCOFF_REGNUM, FDS_REGNUM, FDOFF_REGNUM): Make
+ obsolete, unconditionally define in terms of FISEG_REGNUM,
+ FIOFF_REGNUM, FOSEG_REGNUM, FOOFF_REGNUM.
+ * i386-tdep.c (i386_gdbarch_init): Initialize `num_xmm_regs'
+ member of `struct gdbarch_tdep'.
+ * x86-64-tdep.c (i386_gdbarch_init): Change initialization of
+ `struct gdbarch_tdep'.
+ * i387-nat.c (FCS_REGNUM, FCOFF_REGNUM, FDS_REGNUM, FDOFF_REGNUM):
+ Replace with FISEG_REGNUM, FIOFF_REGNUM, FOSEG_REGNUM and
+ FOOFF_REGNUM. Use FPC_REGNUM instead of FIRST_FPU_CTRL_REGNUM.
+ Use XMM0_REGNUM instead of LAST_FPU_CTRL_REGNUM.
+
+2001-12-25 Andrew Cagney <ac131313@redhat.com>
+
+ * cli/cli-script.c (execute_control_command): Replace value_ptr
+ with a struct value pointer.
+ * ch-lang.c (evaluate_subexp_chill): Ditto.
+ * printcmd.c (printf_command): Ditto.
+ * tracepoint.c (set_traceframe_context): Ditto.
+ (encode_actions): Ditto.
+ * eval.c (evaluate_subexp_standard): Ditto.
+
+2001-12-25 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh: When an int variable, print value using %d instead
+ of %ld.
+ * gdbarch.c: Re-generate.
+
+2001-12-24 Tom Rix <trix@redhat.com>
+
+ * config/powerpc/aix.mt (TDEPFILES): Add xcoffread.o to fix a build
+ failure.
+
+2001-12-21 Michael Snyder <msnyder@redhat.com>
+
+ * procfs.c (info_proc_cmd): Add the 'mappings' sub-command that
+ was dropped a few years ago, when procfs.c was rewritten.
+ (info_proc_mappings): New function, implement 'info proc mappings'.
+ (mappingflags): New function.
+ (_initialize_procfs): Document new option to 'info proc' command.
+
+2001-12-21 Tom Tromey <tromey@redhat.com>
+
+ * configure, config.in: Rebuilt.
+ * configure.in: Check for realpath.
+ * defs.h (gdb_realpath): Declare.
+ * symtab.h (partial_symtab): Added fullname field.
+ * source.c (openp): Use gdb_realpath.
+ (forget_cached_source_info): Clear full name of each partial
+ symtab.
+ * utils.c (gdb_realpath): New function.
+ * symtab.c (lookup_symtab): Removed.
+ (lookup_symtab_1): Renamed to lookup_symtab.
+ (lookup_symtab): Look for real path.
+ (lookup_partial_symtab): Likewise.
+
+2001-12-21 Michael Snyder <msnyder@redhat.com>
+
+ * maint.c (match_substring): New function. Tokenizer for
+ maint info sections command arguments.
+ (match_bfd_flag): Use match_substring.
+ (print_bfd_section_info): Use match_substring.
+ (print_objfile_section_info): Use match_substring.
+ (maintenance_info_sections): Use match_substring.
+
+2001-12-21 Orjan Friberg <orjanf@axis.com>
+
+ * configure.tgt: Delete CRIS from multi-arch targets.
+
+ * config/cris/tm-cris.h: New file.
+
+ * config/cris/cris.mt (TDEPFILES): Add corelow.o solib.o solib-svr4.o.
+ (TM_FILE): New macro.
+
+ * cris-tdep.c (cris_examine): Correct check for srp register.
+ (supply_gregset, fetch_core_registers,
+ cris_linux_svr4_fetch_link_map_offsets, cris_fpless_backtrace):
+ New functions.
+ (_initialize_cris_tdep): Add core functions and new command.
+ (cris_gdbarch_init): Define link map offsets.
+
+Thu Dec 20 16:42:30 2001 Jeffrey A Law (law@cygnus.com)
+
+ * somsolib.c (som_solib_add): Ignore the solib limit threshhold
+ if AUTO_SOLIB_LIMIT is not greater than zero.
+
+ * somsolib.c (som_solib_create_inferior_hook): No longer warn
+ about missing __d_pid symbol.
+
+2001-12-20 Elena Zannoni <ezannoni@redhat.com>
+
+ * ppc-linux-nat.c (ppc_ptrace_cannot_fetch_store_register):
+ New function.
+ (fetch_register): New function.
+ (fetch_ppc_registers): New function.
+ (fetch_inferior_registers): New function.
+ (store_register): New function.
+ (store_ppc_registers): New function.
+ (store_inferior_registers): New function.
+ (ppc_register_u_addr): Eliminate ustart parameter and its
+ uses. Make static.
+ (PT_READ_U, PT_WRITE_U, PTRACE_XFER_TYPE): Define if needed.
+ Include sys/ptrace.h.
+
+ * config/powerpc/nm-linux.h (FETCH_INFERIOR_REGISTERS): Define.
+ (U_REGS_OFFSET, REGISTER_U_ADDR): Delete.
+
+ * config/powerpc/linux.mh (NATDEPFILES): Delete core-aout.o.
+
+2001-12-20 Elena Zannoni <ezannoni@redhat.com>
+
+ * rs6000-nat.c (fetch_register): Don't error out unless the
+ register number is really bogus.
+
+2001-12-20 Michael Snyder <msnyder@redhat.com>
+
+ * maint.c (maintenance_info_sections): Accept new argument
+ 'ALLOBJ', iterate over all object files.
+ (print_section_table): Delete. Replaced by:
+ (print_section_info): New function.
+ (print_bfd_section_info): New function.
+ (print_objfile_section_info): New function.
+ (_initialize_maint_commands): Add help for new features.
+
+2001-12-20 Kevin Buettner <kevinb@redhat.com>
+
+ * arm-tdep.c (arm_init_extra_frame_info): Add special case for
+ call dummies.
+ (arm_frame_saved_pc): Likewise.
+ (arm_push_dummy_frame): Make sure all of the GPRs are saved.
+ (arm_pop_frame): Eliminate special case for call dummies. It
+ is no longer needed now that the frame info is being properly
+ initialized.
+
+ * arm-tdep.c (arm_scan_prologue): Don't require "mov ip, sp"
+ to be the first instruction in the prologue. Also, revise
+ the way the frame offset is computed for frameless functions.
+
+2001-12-20 Michael Snyder <msnyder@redhat.com>
+
+ * maint.c (maintenance_info_sections): Pass string argument to
+ print_section_table, so that it can be used to select sections.
+ (print_section_table): Change PTR to void *. Look at string arg
+ to select sections by name and by flag attributes.
+ (match_bfd_flags): New function.
+ (print_bfd_flags): New function.
+
+Thu Dec 20 11:37:50 2001 Jeffrey A Law (law@redhat.com)
+
+ * cli/cli-decode.c (add_cmd): Initialize pre_show_hook in
+ the new command.
+
+2001-12-20 Andrew Cagney <ac131313@redhat.com>
+
+ * remote.c (struct packet_reg): Add field in_g_packet.
+ (struct remote_state): Rename field g_packet to regs;
+ (free_remote_state): Update.
+ (init_remote_state): Add pseudo-registers to table. Initialize
+ in_g_packet. Drop sentinal from table.
+ (packet_reg_from_regnum, packet_reg_from_pnum): Update.
+ (remote_fetch_registers): Handle registers not in the g-packet.
+ (remote_store_registers): Ditto.
+
+2001-12-20 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (TARGET_CHAR_SIGNED): Do not specify the print
+ format.
+
+2001-12-19 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c (s390_pop_frame_regular): Make sure the saved_regs
+ array is actually set before we try to use it.
+
+ * s390-tdep.c (s390_frame_saved_pc_nofix): If we get the saved PC
+ out of the return address register, cache that in the frame's
+ extra info, just as if we'd gotten it from the saved regs array;
+ that way, it's not a lie to set the saved_pc_valid flag.
+
+ * s390-tdep.c (s390_get_frame_info): Give orig_sp a reasonable
+ value, even when fextra_info->stack_bought can't be trusted,
+
+ * s390-tdep.c (s390_readinstruction): Don't call
+ info->read_memory_func to read zero bytes. Some targets'
+ xfer_memory functions can't cope with that.
+
+ * gdbarch.sh (TARGET_CHAR_SIGNED): New macro.
+ * gdbarch.c, gdbarch.h: Regenerated.
+ * gdbtypes.c (build_gdbtypes): If TARGET_CHAR_SIGNED is zero,
+ set the TYPE_FLAG_UNSIGNED bit on the type.
+ * s390-tdep.c (s390_gdbarch_init): On the S/390, characters
+ are unsigned by default.
+ * rs6000-tdep.c (rs6000_gdbarch_init): Same for PowerPC and
+ RS6000.
+
+2001-12-19 Elena Zannoni <ezannoni@redhat.com>
+
+ * corefile.c (do_captured_read_memory_integer,
+ safe_read_memory_integer): New functions.
+ * gdbcore.h (safe_read_memory_integer): Export.
+ * arm-tdep.c (arm_scan_prologue): Use safe_read_memory_integer,
+ to read the frame value, to capture calls to error().
+
+2001-12-19 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c (s390_register_name): S390_LAST_REGNUM is, in fact,
+ the last register number, not one greater than the last register
+ number.
+
+ * s390-tdep.c (s390_register_virtual_type): Replace clever but
+ incorrect range comparison with correct, legible equivalent.
+
+ * s390-tdep.c (s390_register_raw_size): Replace unnecessarily
+ obscure range comparison with legible equivalent.
+
+Wed Dec 19 12:18:57 2001 Jeffrey A Law (law@redhat.com)
+
+ * config/pa/tm-hppa.h (STORE_RETURN_VALUE): Use hppa_store_return_value.
+ (EXTRACT_RETURN_VALUE): Similarly.
+ * hppa-tdep.c (hppa_store_return_value): New function.
+ (hppa_extract_return_value): New function.
+
+ * infttrace.c (child_acknowledge_created_inferior): Pass
+ correct argument to add_thread.
+ (update_thread_state_after_attach): Likewise.
+
+2001-12-19 Fernando Nasser <fnasser@redhat.com>
+
+ * config/arm/tm-arm.h: Properly define SOFTWARE_SINGLE_STEP_P.
+ Always define SOFTWARE_SINGLE_STEP.
+ * config/arm/tm-embed.h: Properly define SOFTWARE_SINGLE_STEP_P.
+ * arm-tdep.c (arm_get_next_pc, thumb_get_next_pc, bitcount,
+ shifted_reg_val): Always compile these functions.
+ (arm_software_single_step): Fix second argument in function calls.
+
+2001-12-19 Andrew Cagney <ac131313@redhat.com>
+
+ * arch-utils.h (gdbarch_info_init): Declare.
+ * arch-utils.c: Include "arch-utils.h".
+ (gdbarch_info_init): Define.
+ (set_endian, set_architecture, set_gdbarch_from_file)
+ (initialize_current_architecture): Use gdbarch_info_init.
+ * rs6000-nat.c (set_host_arch): Ditto.
+ * cris-tdep.c (cris_version_update, cris_mode_update)
+ (cris_abi_update): Ditto.
+
+2001-12-19 Jim Blandy <jimb@redhat.com>
+
+ * c-lang.c (c_emit_char): Print ASCII 11 as '\v', to match
+ ISO C, and our parser. Print ASCII 0 as '\0', since that's what
+ people are used to seeing.
+
+2001-12-18 Jim Blandy <jimb@redhat.com>
+
+ * c-lang.c (c_printstr, c_builtin_types, cplus_builtin_types):
+ Fix indentation.
+
+ * Makefile.in (c-exp.tab.o): Delete duplicate build rule. Fix
+ dependency list on remaining build rule.
+
+2001-12-18 Martin M. Hunt <hunt@redhat.com>
+
+ * ser-tcp.c (tcp_open): Disable Nagle algorithm which
+ improves performance in some cases.
+
+2001-12-17 Ben Harris <bjh21@netbsd.org>
+
+ * armbsd-nat.c: Remove file, renamed to armnbsd-nat.c.
+ * armnbsd-nat.c: New file, renamed from armbsd-nat.c.
+ * Makefile.in: Rename armbsd-nat.c to armnbsd-nat.c.
+ * config/arm/nbsd.mh: Likewise.
+
+2001-12-17 Corinna Vinschen <vinschen@redhat.com>
+
+ * NEWS: Note new target XStormy16.
+ * MAINTAINERS: Add -Werror to XStormy16.
+
+2001-12-17 Fernando Nasser <fnasser@redhat.com>
+
+ From Richard Earnshaw <rearnsha@arm.com>:
+ * arm-tdep.c (arm_software_single_step): New function. Implements
+ software single-stepping for ARM targets.
+ (arm_get_next_pc, thumb_get_next_pc, bitcount, shifted_reg_val): Only
+ needed for software single-stepping.
+ * config/arm/tm-arm.h: Activate SOFTWARE_SINGLE_STEP_P.
+
+2001-12-17 Fernando Nasser <fnasser@redhat.com>
+
+ From Richard Earnshaw <rearnsha@arm.com>:
+ * config/arm/nbsd.mh, config/arm/nbsd.mt, config/arm/tm-nbsd.h,
+ config/arm/nm-nbsd.h, config/arm/xm-nbsd.h: New files.
+ * armbsd-nat.c: New file.
+ * Makefile.in: Build it.
+ * configure.host, configure.tgt: Support NetBSD/arm.
+
+2001-12-17 Corinna Vinschen <vinschen@redhat.com>
+
+ * MAINTAINERS: Add myself as XStormy16 maintainer.
+
+2001-12-15 Kevin Buettner <kevinb@redhat.com>
+
+ * config/rs6000/tm-rs6000.h (solib.h): Conditionally include.
+
+2001-12-15 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.c: Re-generate.
+
+2001-12-15 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Remove powerpcle-eabi and rs6000-ibm-aix3.2 from
+ target list.
+
+2001-12-15 Andrew Cagney <ac131313@redhat.com>
+
+ * defs.h (LITTLE_ENDIAN): Delete definition.
+ * arch-utils.c, cris-tdep.c, d10v-tdep.c, defs.h, gdbarch.c,
+ gdbarch.sh, remote-rdp.c, remote-sim.c, sh-tdep.c, sparc-tdep.c,
+ config/alpha/tm-alpha.h, config/arm/tm-arm.h,
+ config/i386/tm-i386.h, config/i960/tm-i960.h,
+ config/ia64/tm-ia64.h, config/mcore/tm-mcore.h,
+ config/mips/tm-wince.h, config/mn10200/tm-mn10200.h,
+ config/ns32k/tm-umax.h, config/powerpc/tm-ppcle-eabi.h,
+ config/sh/tm-wince.h, config/v850/tm-v850.h, config/vax/tm-vax.h,
+ doc/gdbint.texinfo: Replace LITTLE_ENDIAN with BFD_ENDIAN_LITTLE.
+
+2001-12-15 Andrew Cagney <ac131313@redhat.com>
+
+ * ui-out.c (struct ui_out_table): Add field entry_level.
+ (verify_field): New function.
+ (verify_field_proper_position): Delete function.
+ (verify_field_alignment): Delete function.
+ (ui_out_field_int): Update to use verify_field.
+ (ui_out_field_skip): Ditto.
+ (ui_out_field_string): Ditto.
+ (ui_out_field_fmt): Ditto.
+ (ui_out_table_begin): Initialize table.entry_level.
+ (ui_out_table_end): Clear table.entry_level.
+ (ui_out_begin): Call verify_field before pushing the new tuple or
+ list onto the stack. Use table.entry_level.
+
+2001-12-14 Corinna Vinschen <vinschen@redhat.com>
+
+ * config/djgpp/fnchange.lst: Add entries for opcodes/xstormy16-* files.
+
+2001-12-13 Andrew Cagney <ac131313@redhat.com>
+
+ * arch-utils.c (generic_register_virtual_size): Return TYPE_LENGTH
+ of register's type.
+
+2001-12-13 Jackie Smith Cashion <jsmith@redhat.com>
+
+ * cli/cli-script.c (print_command_lines): Remove extra
+ "if", "else", "while", and "end" from show user output.
+
+2001-12-13 Kevin Buettner <kevinb@redhat.com>
+
+ * i387-nat.c (i387_fill_fxsave): Change type of ``val'' from char
+ to short so that we don't memcpy() beyond the end of this buffer.
+ Also, change shift value used in computing val to account for the
+ fact that only eight bits are used.
+
+2001-12-13 Corinna Vinschen <vinschen@redhat.com>
+
+ * Makefile.in: Add support for xstormy16.
+ * configure.tgt: Ditto.
+ * xstormy16-tdep.c: New file.
+ * config/xstormy16/xstormy16.mt: New file.
+
+2001-12-13 Andreas Schwab <schwab@suse.de>
+
+ * MAINTAINERS (write-after-approval): Add myself.
+
+2001-12-12 Jim Blandy <jimb@redhat.com>
+
+ * Makefile.in (c-exp.tab.o): Add missing dependencies.
+
+ * Makefile.in (c_lang_h): New variable. Use it in dependency
+ lists, instead of `c-lang.h' itself.
+
+2001-12-11 Fred Fish <fnf@redhat.com>
+
+ * c-typeprint.c (c_type_print_base): Use type flags access macros
+ to test bits.
+ * ch-typeprint.c (chill_type_print_base): Ditto.
+ * ch-valprint.c (chill_val_print): Ditto.
+ * d10v-tdep.c (d10v_pointer_to_address): Ditto.
+ * dwarf2read.c (dwarf2_add_member_fn): Ditto.
+ * dwarfread.c (read_structure_scope): Ditto.
+ * gdbtypes.c (create_range_type): Dittol
+ (create_set_type): Ditto.
+ (check_typedef): Ditto.
+ * jv-typeprint.c (java_type_print_base): Ditto.
+ * p-typeprint.c (pascal_type_print_base): Ditto
+ * p-valprint.c (pascal_val_print): Ditto.
+ * stabsread.c (read_cfront_member_functions): Ditto.
+ (read_member_functions): Ditto.
+ (cleanup_undefined_types): Ditto.
+ * valprint.c (val_print): Ditto.
+
+ * valops.c (hand_function_call): Remove is_prototyped
+ variable and just use type flag test macro directly.
+
+2001-12-11 Fred Fish <fnf@redhat.com>
+
+ * gdbtypes.c (print_bound_type): New function.
+ (recursive_dump_type): Print type struct code values
+ TYPE_CODE_BITSTRING, TYPE_CODE_COMPLEX, TYPE_CODE_TEMPLATE,
+ and TYPE_CODE_TEMPLATE_ARG.
+ (recursive_dump_type): Print type struct members
+ upper_bound_type, lower_bound_type, cv_type, and as_type.
+ Also always print the tagname member, even when it is NULL.
+
+2001-12-11 Michael Snyder <msnyder@redhat.com>
+
+ * d10v-tdep.c (d10v_register_virtual_size): Delete.
+ (d10v_gdbarch_init): Use generic_register_virtual_size.
+ * rs6000-tdep.c (rs6000_register_virtual_size): Delete.
+ (rs6000_gdbarch_init): Use generic_register_virtual_size.
+ * x86-64-tdep.c (x86_64_register_virtual_size): Delete.
+ (i386_gdbarch_init): Use generic_register_virtual_size.
+
+2001-12-11 Andrew Cagney <ac131313@redhat.com>
+
+ * values.c: Include "gdb_assert.h".
+ (value_fn_field): Rearange to avoid -Wuninitialized warning.
+
+2001-12-10 Fred Fish <fnf@redhat.com>
+
+ * values.c (value_fn_field): Add physname variable. Use a minimal
+ symbol if we don't find a full symbol. Remove setting of the new
+ value's type since that was already done by allocate_value().
+ Remove obsolete commented out error call since callees need to
+ handle a NULL return, which is possible result not an error.
+ * eval.c (evaluate_subexp_standard): Move check for inlined
+ functions to precede attempt to dereference a NULL argvec[0].
+
+2001-12-10 Fred Fish <fnf@redhat.com>
+
+ * arm-linux-tdep.c (skip_hurd_resolver): Use NULL rather than
+ zero in args to lookup_minimal_symbol.
+ * linespec.c (decode_line_1): Ditto.
+ * i386-linux-tdep.c (skip_hurd_resolver): Ditto.
+ * minsyms.c (find_stab_function_addr): Ditto.
+ * symfile.c (simple_read_overlay_table): Ditto.
+ (simple_read_overlay_region_table): Ditto.
+
+2001-12-10 Michael Snyder <msnyder@redhat.com>
+
+ * arch-utils.c (generic_register_virtual_size): New function.
+ * arch-utils.h: Export generic version of register_virtual_size.
+ * gdbarch.sh (REGISTER_VIRTUAL_SIZE): Use new function as default.
+ * gdbarch.c: Regenerate.
+
+2001-12-09 Fred Fish <fnf@redhat.com>
+
+ * gdbtypes.c (TYPE_FLAG_UNSIGNED, TYPE_FLAG_STUB): Use
+ TYPE_UNSIGNED and TYPE_NOSIGN to determine when to print these
+ rather than testing the bits directly.
+ (TYPE_FLAG_NOSIGN, TYPE_FLAG_TARGET_STUB, TYPE_FLAG_STATIC,
+ TYPE_FLAG_CONST, TYPE_FLAG_VOLATILE, TYPE_FLAG_PROTOTYPED,
+ TYPE_FLAG_INCOMPLETE, TYPE_FLAG_CODE_SPACE, TYPE_FLAG_DATA_SPACE,
+ TYPE_FLAG_VARARGS): Test for and print these bits as well.
+
+2001-12-09 Fred Fish <fnf@redhat.com>
+
+ * gdbtypes.c (build_gdbtypes): For builtin_type_char, pass
+ TYPE_FLAG_NOSIGN to init_type() rather than setting it after the
+ type is created.
+
+2001-12-09 Fred Fish <fnf@redhat.com>
+
+ * gdbtypes.h (TYPE_UNSIGNED, TYPE_NOSIGN, TYPE_CONST,
+ TYPE_VOLATILE, TYPE_INCOMPLETE): Move macros that test the
+ bits to location in file where the bits are defined.
+ (TYPE_STUB, TYPE_TARGET_STUB, TYPE_STATIC, TYPE_PROTOTYPED,
+ TYPE_CODE_SPACE, TYPE_DATA_SPACE): New test macros.
+
+2001-12-09 Fred Fish <fnf@redhat.com>
+
+ * gdbtypes.c (allocate_stub_method): Replace hand crafted type
+ initialization with call to the init_type() function.
+
+2001-12-09 Andrew Cagney <ac131313@redhat.com>
+
+ * arch-utils.c (generic_register_raw_size): New function.
+ * gdbarch.sh (REGISTER_RAW_SIZE): Use generic_register_raw_size as
+ the static default.
+ * gdbarch.c: Regenerate.
+ * arch-utils.h (generic_register_raw_size): Declare.
+
+ * config/mips/tm-mips.h (REGISTER_RAW_SIZE): Delete macro.
+ * mips-tdep.c (mips_register_raw_size): Make function static.
+ (mips_gdbarch_init): Initialize register_raw_size.
+
+2001-12-08 Fred Fish <fnf@redhat.com>
+
+ * dwarf2read.c (read_typedef): Replace hand crafted type
+ initialization with a call to the init_type() function, which
+ is how the rest of gdb creates types.
+
+2001-12-09 Fred Fish <fnf@redhat.com>
+
+ * mdebugread.c (cross_ref): Pass TYPE_FLAG_STUB to init_type()
+ rather than setting it after the type is created.
+
+2001-12-09 Elena Zannoni <ezannoni@redhat.com>
+
+ * config/rs6000/tm-rs6000.h (STAB_REG_TO_REGNUM): Remove
+ definition, it is now multiarched.
+ * ppc-tdep.h (struct gdbarch_tdep): Move from rs6000-tdep.c. Add
+ fields for special register numbers.
+ * rs6000-tdep.c (rs6000_gdbarch_init): Initialize new tdep special
+ regnum fields.
+ (rs6000_saved_pc_after_call): Use gdbarch_tdep registers fields
+ instead of hardcoded macros.
+ (branch_dest, rs6000_pop_frame, rs6000_fix_call_dummy,
+ ppc_push_return_address, rs6000_frame_saved_pc,
+ frame_get_saved_regs, rs6000_frame_chain,
+ rs6000_store_return_value): Ditto.
+ (rs6000_stab_reg_to_regnum): New function.
+ * ppcnbsd-nat.c (fetch_inferior_registers,
+ store_inferior_registers, fetch_core_registers): Ditto.
+ * ppc-linux-tdep.c (ppc_linux_in_sigtramp,
+ ppc_linux_frame_init_saved_regs): Ditto.
+ * ppc-linux-nat.c (ppc_register_u_addr, supply_gregset,
+ fill_gregset): Ditto.
+ * ppc-bdm.c (bdm_ppc_fetch_registers, bdm_ppc_store_registers):
+ Ditto.
+
+2001-12-08 Fred Fish <fnf@redhat.com>
+
+ * c-lang.c (c_create_fundamental_type): For FT_CHAR, pass
+ TYPE_FLAG_NOSIGN to init_type() rather than setting it after the
+ type is created.
+
+2001-12-08 Fred Fish <fnf@redhat.com>
+
+ * dwarf2read.c (TYPE_FLAG_VARARGS): Remove from here.
+ * gdbtypes.h (TYPE_FLAG_VARARGS): Add here and change value to
+ not collide with other flag bits.
+
+2001-12-08 Fred Fish <fnf@redhat.com>
+
+ * dwarf2read.c (read_base_type): Rename is_unsigned to type_flags.
+ For unsigned types set TYPE_FLAG_UNSIGNED and pass it to
+ init_type().
+
+2001-12-08 Daniel Jacobowitz <drow@mvista.com>
+
+ * Makefile.in (cp-valprint.o): Add dependency on $(cp_abi_h).
+
+2001-12-08 Jim Blandy <jimb@redhat.com>
+
+ * config/s390/s390.mh: Don't use the linux-thread.o module;
+ thread-db.o, lin-lwp.o, and proc-service.o should work just fine.
+
+2001-12-07 Andrew Cagney <ac131313@redhat.com>
+
+ * PROBLEMS: New file.
+ * README: Move known problems to PROBLEMS file.
+
+2001-12-07 Daniel Jacobowitz <drow@mvista.com>
+
+ * stabsread.c (read_member_functions): Skip member functions which
+ are duplicates of the callable constructor/destructor.
+
+2001-12-07 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c (s390_store_return_value): Don't convert float
+ values to double format when returning them; just return them in
+ the first half of the FP register, as the ABI specifies.
+
+2001-12-07 Daniel Jacobowitz <drow@mvista.com>
+
+ * valops.c (hand_function_call): Check for method arguments in
+ TYPE_ARG_TYPES(), not in TYPE_FIELD ().
+
+2001-12-07 Daniel Jacobowitz <drow@mvista.com>
+
+ * cp-valprint.c (cp_print_value): Preserve offset if
+ the virtual base is outside of this object.
+
+2001-12-07 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdbtypes.c (finish_cv_type): New function.
+ (check_typedef): Remove ``register'' keyword from argument.
+ Preserve const and volatile attributes across filling in
+ opaque types.
+ * gdbtypes.h (finish_cv_type): Add prototype.
+
+ * hp-symtab-read.c (hpread_read_struct_type): Call finish_cv_type.
+ * stabsread.c (read_struct_type): Likewise.
+ * dwarf2read.c (read_structure_scope): Likewise. Remove redundant
+ assignment to die->type.
+
+2001-12-07 Jim Blandy <jimb@redhat.com>
+
+ * printcmd.c (print_scalar_formatted): Compare the length of the
+ value against the lengths of the target's floating-point types,
+ not the host's. Add support for `long double'.
+
+2001-12-07 Martin M. Hunt <hunt@redhat.com>
+
+ * configure.in: Check for sys/filio.h
+ * configure: Rebuild.
+ * config.in: Add HAVE_SYS_FILIO_H
+ * ser-tcp.c: Conditionally include sys/filio.h.
+
+2001-12-07 Andrew Cagney <ac131313@redhat.com>
+
+ * ui-out.c (ui_out_table_begin): Initialize body_flag.
+ (struct ui_out_table): New structure. Move table fields to here.
+ Rename headercurr to headernext.
+ (struct ui_out): Remove table specific fields. Add field table.
+ (ui_out_table_begin, ui_out_table_body, ui_out_table_end): Update.
+ (ui_out_table_header, ui_out_begin): Update.
+ (verify_field_proper_position, verify_field_alignment): Update.
+ (ui_out_new, clear_header_list, append_header_to_list): Update.
+ (get_next_header): Rename get_curr_header. Update comments and
+ code.
+
+2001-12-06 Andrew Cagney <ac131313@redhat.com>
+
+ * regcache.c (XCALLOC): Delete macro that should not have been
+ added.
+
+2001-12-07 Jiri Smid <smid@suse.cz>
+
+ * dwarf2cfi.c: New file.
+ * dwarf2cfi.h: New file.
+ * dwarf2read.c (dwarf_frame_offset, dwarf_frame_size): New variables.
+ (dwarf_eh_frame_offset, dwarf_eh_frame_size): New variables.
+ (dwarf2_read_section): Change to non static.
+ (dwarf2_locate_sections): Add .debug_frame and .eh_frame section
+ recognition.
+ (FRAME_SECTION, EH_FRAME_SECTION): New define.
+ * elfread.c (elf_symfile_read): Add call of frame informations build.
+ * frame.h (frame_info): Add pointer to unwind_context.
+ * symfile.h (dwarf2_build_frame_info): Add declaration.
+ * gdbarch.sh (DWARF2_BUILD_FRAME_INFO): Add.
+ * gdbarch.h, gdbarch.c: Regenerate.
+ * Makefile.in: Add dwarf2cfi_h, dwarf2cfi.o
+ * x86-64-tdep.c (i386_gdbarch_init): Initialize target vector to
+ use debug frame info.
+
+2001-12-06 Andrew Cagney <ac131313@redhat.com>
+
+ * defs.h: Do not include "mmalloc.h".
+ (mcalloc, mmalloc, mrealloc, mfree): Delete declaration.
+ * objfiles.c: Include "mmalloc.h".
+ * utils.c: Include "mmalloc.h".
+ (mmalloc, mfree, mrealloc, mmalloc): Make static, change PTR to
+ void pointer.
+
+2001-12-06 Andrew Cagney <ac131313@redhat.com>
+
+ * regcache.c (store_register, fetch_register): Only use
+ fetch/store pseudo-register when function is present. Assume
+ target can handle all registers.
+ (registers_changed): Simplify invalidate loop.
+ (registers_fetched): Add comments.
+ (register_buffer): Add regnum range assertion. Remove code
+ handling -ve regnum.
+ (build_regcache): Make space for pseudo-registers when computing
+ sizeof_registers. Initialize register_offset.
+
+ * gdbarch.sh (FETCH_PSEUDO_REGISTER): Change to a function with
+ predicate.
+ (STORE_PSEUDO_REGISTER): Ditto.
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+2001-12-06 Jim Blandy <jimb@redhat.com>
+
+ * config/s390/nm-linux.h: Watchpoints are either continuable or
+ steppable, not both. The S/390 has continuable watchpoints, so
+ delete the #definition of HAVE_STEPPABLE_WATCHPOINT.
+
+2001-12-04 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * go32-nat.c (go32_fetch_registers): Remove call to register_buffer
+ (which is now a static function in regcache.c)
+ and use regcache_collect instead.
+
+2001-12-05 Andrew Cagney <cagney@redhat.com>
+
+ * target.c (cleanup_target): Do not initialize to_query to
+ return_zero.
+
+2001-12-05 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c (s390_get_frame_info): Recognize argument register
+ spills that use the `stm' instruction.
+ (is_arg_reg): New function.
+
+2001-12-03 Keith Walker <keith.walker@arm.com>
+
+ * gdbserver/low-linux.c (arm_register_u_addr): Added.
+ (initialize_arch): Added for ARM target.
+ * config/arm/nm-linux.h (U_REGS_OFFSET): Defined.
+ (REGISTER_U_ADDR): Defined.
+ * config/arm/tm-linux.h (ARM_GNULINUX_TARGET): Defined.
+
+2001-12-04 Corinna Vinschen <vinschen@redhat.com>
+
+ * arm-tdep.c (arm_skip_prologue): Always skip prologue by scanning
+ the prologue if source is assembler.
+
+2001-12-04 Jackie Smith Cashion <jsmith@redhat.com>
+
+ * MAINTAINERS (write-after-approval): Add self.
+
+ * d10v-tdep.c (d10v_gdbarch_init): Change size of long long to 8 bytes.
+
+ From Andrew Cagney <cagney@redhat.com>:
+ * d10v-tdep.c (d10v_frame_chain_valid): Check if the caller's PC
+ is in the entry function.
+ (d10v_use_struct_convention): Store multi-field struct and union
+ return values on the stack.
+
+2001-12-04 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c (s390_get_frame_info): Recognize spills of reg
+ arguments into their stack slots.
+
+ * s390-tdep.c (s390_get_frame_info): More doc fixes.
+
+ * s390-tdep.c (s390_get_frame_info): Doc fixes.
+
+2001-12-04 Orjan Friberg <orjanf@axis.com>
+
+ * cris-tdep.c (cris_regnums): Add DCCR_REGNUM for completeness.
+ (cris_examine): Add comment about solib prologue parsing.
+ (bdap_prefix): Read offset with correct signedness and size.
+ (move_to_preg_op): Don't rely on register numbering for register size.
+ (none_reg_mode_move_from_preg_op): Ditto.
+
+2001-12-04 Orjan Friberg <orjanf@axis.com>
+
+ * solib.c (solib_open): Make path relative if search for absolute path
+ failed. If search for relative path in solib_search_path failed, fall
+ back to search for basename only.
+
+2001-12-03 Martin M. Hunt <hunt@redhat.com>
+
+ * serial.h: Add a note to serial_open.
+
+ * ser-tcp.c (tcp_open): Rewrite to use a non-blocking connect.
+ Allow UI and CLI to abort connect. Instead of trying 15 times
+ with very long timeouts, just try one connect with a maximum timeout
+ of 15 seconds.
+
+2001-12-03 Kevin Buettner <kevinb@redhat.com>
+
+ * config/powerpc/tm-macos.h (solib.h): Include.
+ * config/powerpc/tm-ppc-eabi.h (solib.h): Include.
+
+2001-12-03 Michael Snyder <msnyder@redhat.com>
+
+ * symtab.c (search_symbols): Make sure alloca size is big enough.
+
+2001-12-03 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Prune m68k targets down to just m68k-elf.
+
+2001-12-03 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c (s390_get_frame_info): Don't used fextra_info to set
+ orig_sp if it's not initialized.
+
+2001-11-30 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * findvar.c (locate_var_value): Specify in which register a register
+ variable is stored.
+
+2001-11-30 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * win32-nat.c (mappings): Correct position of XMM registers,
+ based on FXSAVE instruction structure.
+
+2001-12-02 Andrew Cagney <ac131313@redhat.com>
+
+ * jv-lang.c (get_java_class_symtab): Use xmmalloc instead of
+ mmalloc.
+
+ * coffread.c, dbxread.c, elfread.c, hp-psymtab-read.c, hpread.c,
+ nlmread.c, objfiles.c, os9kread.c, somread.c, source.c, symfile.c,
+ symmisc.c, xcoffread.c: Use xmfree instead of mfree.
+
+ * jv-lang.c (add_class_symtab_symbol): Use xmrealloc instead of
+ mrealloc.
+
+2001-12-02 Andrew Cagney <ac131313@redhat.com>
+
+ * i386-tdep.c (i386go32_frame_saved_pc): New function.
+ * config/i386/tm-go32.h (i386go32_frame_saved_pc): Declare.
+ (FRAME_SAVED_PC): Redefine to i386go32_frame_saved_pc.
+
+2001-12-01 Andrew Cagney <ac131313@redhat.com>
+
+ * defs.h: Update comment on HOST_BYTE_ORDER.
+ * config/xm-aix4.h: Delete definition of HOST_BYTE_ORDER.
+ * config/xm-nbsd.h, config/alpha/xm-alphalinux.h: Ditto.
+ * config/alpha/xm-alphaosf.h, config/alpha/xm-fbsd.h: Ditto.
+ * config/arm/xm-linux.h, config/i386/xm-cygwin.h: Ditto.
+ * config/i386/xm-i386bsd.h, config/i386/xm-i386gnu.h: Ditto.
+ * config/i386/xm-i386lynx.h, config/i386/xm-i386m3.h: Ditto.
+ * config/i386/xm-i386mach.h, config/i386/xm-i386v.h: Ditto.
+ * config/i386/xm-ptx.h, config/i386/xm-symmetry.h: Ditto.
+ * config/ia64/xm-aix.h, config/ia64/xm-linux.h: Ditto.
+ * config/m68k/xm-3b1.h, config/m68k/xm-apollo68b.h: Ditto.
+ * config/m68k/xm-apollo68v.h, config/m68k/xm-delta68.h: Ditto.
+ * config/m68k/xm-dpx2.h, config/m68k/xm-hp300bsd.h: Ditto.
+ * config/m68k/xm-hp300hpux.h, config/m68k/xm-m68k.h: Ditto.
+ * config/m68k/xm-m68klynx.h, config/m68k/xm-sun2.h: Ditto.
+ * config/m68k/xm-sun3.h, config/m88k/xm-dgux.h: Ditto.
+ * config/m88k/xm-m88k.h, config/mips/xm-irix3.h: Ditto.
+ * config/mips/xm-irix5.h, config/mips/xm-linux.h: Ditto.
+ * config/mips/xm-mips.h, config/mips/xm-mipsm3.h: Ditto.
+ * config/mips/xm-mipsv4.h, config/mips/xm-news-mips.h: Ditto.
+ * config/mips/xm-riscos.h, config/pa/xm-hppab.h: Ditto.
+ * config/pa/xm-hppah.h, config/powerpc/xm-linux.h: Ditto.
+ * config/romp/xm-rtbsd.h, config/rs6000/xm-rs6000.h: Ditto.
+ * config/rs6000/xm-rs6000ly.h, config/s390/xm-linux.h: Ditto.
+ * config/sparc/xm-sparc.h, config/sparc/xm-sparclynx.h: Ditto.
+ * config/vax/xm-vax.h: Ditto.
+
+ * config/a29k/tm-vx29k.h: Add #error as file depends on
+ HOST_BYTE_ORDER.
+ * config/a29k/tm-a29k.h: Ditto.
+ * MAINTAINERS (a29k-amd-udi): Document as broken.
+
+2001-12-01 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in (tm-news.h, tm-isi.h, xm-news1000.h): Delete.
+ (ALLDEPFILES): Delete news-xdep.c.
+ (news-xdep.o): Delete.
+ (isi-xdep.o): Delete.
+ * configure.tgt: Delete m68*-isi-*, m68*-sony-*, m68*-rom68k-*,
+ m68*-*bug-*, m68*-monitor-* and m68*-est-* targets.
+ * configure.host: Delete m68030-sony-*, m68*-isi-* and m68*-sony-*
+ Hosts.
+ * m68k-tdep.c (isi_skip_prologue): Delete function.
+ * news-xdep.c: Delete file.
+ * isi-xdep.c: Delete file.
+ * config/m68k/isi.mh: Delete file.
+ * config/m68k/isi.mt: Delete file.
+ * config/m68k/news.mh: Delete file.
+ * config/m68k/news.mt: Delete file.
+ * config/m68k/news1000.mh: Delete file.
+ * config/m68k/nm-news.h: Delete file.
+ * config/m68k/tm-isi.h: Delete file.
+ * config/m68k/tm-news.h: Delete file.
+ * config/m68k/xm-isi.h: Delete file.
+ * config/m68k/xm-news.h: Delete file.
+ * config/m68k/xm-news1000.h: Delete file.
+
+ * kdb-start.c: Delete file.
+ * stuff.c: Delete file.
+
+ * NEWS: Note that a29k-nyu-sym1 and a29k-*-kern* were deleted.
+ * configure.host: Delete a29k-*-* host.
+ * configure.tgt: Delete a29k-*-kern* and a29k-*-sym1* targets.
+ * config/a29k/a29k-kern.mt: Delete file.
+ * config/a29k/nm-ultra3.h: Delete file.
+ * config/a29k/tm-ultra3.h: Delete file.
+ * config/a29k/ultra3.mh: Delete file.
+ * config/a29k/ultra3.mt: Delete file.
+ * config/a29k/xm-ultra3.h: Delete file.
+
+ * NEWS: Note that i[3456]86-*-sunos* was deleted.
+ * Makefile.in (sun386-nat.o): Delete.
+ * configure.tgt: Delete i[3456]86-*-sunos* target.
+ * configure.host: Delete i[3456]86-*-sunos* host.
+ * sun386-nat.c: Delete.file.
+ * config/i386/nm-sun386.h: Delete file.
+ * config/i386/sun386.mh: Delete file.
+ * config/i386/sun386.mt: Delete file.
+ * config/i386/tm-sun386.h: Delete file.
+ * config/i386/xm-sun386.h: Delete file.
+
+ * NEWS: Note that ns32k-*-mach3*, ns32k-umax-*, ns32k-utek-sysv*
+ and ns32k-utek-* were deleted.
+ * Makefile.in (ultra3-nat.o, ultra3-xdep.o): Delete.
+ (umax-xdep.o, ns32km3-nat.o): Delete.
+ * configure.tgt: Delete ns32k-*-mach3*, ns32k-utek-sysv* and
+ ns32k-utek-* targets.
+ * configure.host: Delete ns32k-*-mach3*, ns32k-umax-* and
+ ns32k-utek-sysv* hosts.
+ * ultra3-nat.c: Delete file.
+ * ultra3-xdep.c: Delete file.
+ * umax-xdep.o: Delete file.
+ * ns32km3-nat: Delete file.
+ * config/ns32k/merlin.mh: Delete file.
+ * config/ns32k/merlin.mt: Delete file.
+ * config/ns32k/nm-umax.h: Delete file.
+ * config/ns32k/ns32km3.mh: Delete file.
+ * config/ns32k/ns32km3.mt: Delete file.
+ * config/ns32k/tm-merlin.h: Delete file.
+ * config/ns32k/tm-ns32km3.h: Delete file.
+ * config/ns32k/umax.mh: Delete file.
+ * config/ns32k/umax.mt: Delete file.
+ * config/ns32k/xm-merlin.h: Delete file.
+ * config/ns32k/xm-ns32km3.h: Delete file.
+ * config/ns32k/xm-umax.h: Delete file.
+
+ * NEWS: Note that m88*-harris-cxux* was deleted.
+ * configure.host: Delete m88*-harris-cxux* host.
+ * configure.tgt: Delete m88*-harris-cxux* target.
+ * config/m88k/cxux.mh: Delete file.
+ * config/m88k/cxux.mt: Delete file.
+ * config/m88k/nm-cxux.h: Delete file.
+ * config/m88k/tm-cxux.h: Delete file.
+ * config/m88k/xm-cxux.h: Delete file.
+
+ * NEWS: Note that powerpc-*-netware*, powerpcle-*-cygwin* and
+ powerpcle-*-solaris* were deleted.
+ * configure.host: Delete powerpcle-*-cygwin* and
+ powerpcle-*-solaris* hosts.
+ * configure.tgt: Delete powerpc-*-netware*, powerpcle-*-cygwin*
+ and powerpcle-*-solaris* targets.
+ * config/powerpc/cygwin.mh: Delete file.
+ * config/powerpc/cygwin.mt: Delete file.
+ * config/powerpc/nm-solaris.h: Delete.file.
+ * config/powerpc/ppc-nw.mt: Delete file.
+ * config/powerpc/solaris.mh: Delete file.
+ * config/powerpc/solaris.mt: Delete file.
+ * config/powerpc/tm-cygwin.h: Delete file.
+ * config/powerpc/tm-ppc-nw.h: Delete file.
+ * config/powerpc/tm-solaris.h: Delete file.
+ * config/powerpc/xm-cygwin.h: Delete file.
+ * config/powerpc/xm-mpw.h: Delete file.
+ * config/powerpc/xm-solaris.h: Delete file.
+
+ * NEWS, MAINTAINERS: Note that w65-*-* was deleted.
+ * configure.tgt: Delete w65-*-*.
+ * Makefile.in (w65-tdep.o): Delete.
+ * config/w65/tm-w65.h: Delete file.
+ * config/w65/w65.mt: Delete file.
+ * w65-tdep.c: Delete file.
+
+ * NEWS: Mention deleted tic80-*-*.
+ * configure.tgt: Delete tic80-*-*.
+ * Makefile.in (tic80-tdep.o): Delete.
+ * config/tic80/tic80.mt: Delete.
+ * config/tic80/tm-tic80.h: Delete.
+ * tic80-tdep.c: Delete.
+ * MAINTAINERS: Note that tic80 was deleted.
+
+2001-11-30 Kevin Buettner <kevinb@redhat.com>
+
+ * ppc-linux-tdep.c (solib-svr4.h): Include.
+ (ppc_linux_svr4_fetch_link_map_offsets): New function.
+ * ppc-tdep.h (ppc_linux_svr4_fetch_link_map_offsets): Declare.
+ * rs6000-tdep.c (solib-svr4.h): Include.
+ (rs6000_gdbarch_init): Set up ppc_linux_svr4_fetch_link_map_offsets()
+ as the link map offsets fetcher.
+
+ * config/powerpc/aix.mt (TDEPFILES): Add solib-svr4.o.
+ * config/powerpc/macos.mt (TDEPFILES): Likewise.
+ * config/powerpc/nbsd.mt (TDEPFILES): Likewise.
+ * config/powerpc/ppc-eabi.mt (TDEPFILES): Likewise.
+ * config/powerpc/ppc-sim.mt (TDEPFILES): Likewise.
+ * config/powerpc/ppcle-eabi.mt (TDEPFILES): Likewise.
+ * config/powerpc/ppcle-sim.mt (TDEPFILES): Likewise.
+ * config/powerpc/vxworks.mt (TDEPFILES): Likewise.
+ * config/rs6000/aix4.mt (TDEPFILES): Likewise.
+ * config/rs6000/rs6000.mt (TDEPFILES): Likewise.
+ * config/rs6000/rs6000lynx.mt (TDEPFILES): Likewise.
+
+2001-11-30 Kevin Buettner <kevinb@redhat.com>
+
+ From Louis Hamilton <hamilton@redhat.com>:
+ * arm-tdep.c (solib-svr4.h): Include.
+ (arm_linux_svr4_fetch_link_map_offsets): New function.
+ * config/arm/tm-linux.h (SVR4_FETCH_LINK_MAP_OFFSETS): Define.
+ (arm_linux_svr4_fetch_link_map_offsets): Declare.
+
+2001-11-30 Daniel Jacobowitz <drow@mvista.com>
+
+ * values.c (value_primitive_field): Add embedded_offset to the
+ address of structure members.
+ * gnu-v3-abi.c (gnuv3_rtti_type): Cast to base type before
+ attempting to access vtable pointer. Set using_enc_p if we cast.
+ (gnuv3_virtual_fn_field): Call value_cast with structure rather than
+ structure pointer. Cast to base type before attempting to access
+ vtable pointer.
+
+2001-11-29 Elena Zannoni <ezannoni@redhat.com>
+
+ * Makefile.in (ppc-linux-nat.o): Add dependency on ppc-tdep.h.
+
+ * ppc-tdep.h (PPC_GPLAST_REGNUM): Define.
+
+ * ppc-linux-nat.c: Include ppc-tdep.h.
+ (ppc_register_u_addr): Don't use the static array regmap[],
+ dynamically define the mapping instead.
+ (supply_gregset): Ditto.
+ (fill_gregset): Ditto.
+ (COPY_REG): Delete macro defintion.
+ (regmap): Delete array.
+
+2001-11-29 Jim Blandy <jimb@redhat.com>
+
+ Tighten up GDB's support for returning structs by value.
+ * s390-tdep.c (s390_use_struct_convention): New function.
+ (s390_gdbarch_init): Register it as the S/390's
+ USE_STRUCT_CONVENTION method. Register
+ generic_cannot_extract_struct_value_address as our
+ EXTRACT_STRUCT_VALUE_ADDRESS method.
+ * arch-utils.c (generic_cannot_extract_struct_value_address): New
+ function.
+ * arch-utils.h: Add corresponding prototype.
+
+ * values.c (value_being_returned): Make error message a proper
+ sentence.
+
+2001-11-27 Keith Walker <keith.walker@arm.com>
+
+ * dwarf2read.c (read_attribute_value): New function to handle
+ DW_FORM_indirect
+ (read_attribute): uses read_attribute_value
+
+2001-11-29 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c (s390_frame_saved_pc_nofix): If the prologue didn't
+ save the return address register, assume that the return address
+ is still in there.
+
+2001-11-27 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Clarify obvious fix a little (as suggested by Eli
+ Zaretskii).
+
+2001-11-25 Jim Blandy <jimb@redhat.com>
+
+ * mn10300-tdep.c (mn10300_analyze_prologue): Doc fixes.
+
+2001-11-27 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c: Get frame chains and saved pc values properly from
+ dummy frames.
+ (s390_frame_saved_pc_nofix): if `*fi' is a dummy frame, get the
+ saved PC from the dummy frame's registers.
+ (s390_frame_chain): Same for the saved SP.
+ (s390_gdbarch_init): Register `generic_save_dummy_frame_tos' as
+ the `SAVE_DUMMY_FRAME_TOS' method, so the dummy frame's `top' gets
+ set correctly.
+
+ * s390-tdep.c (s390_frame_chain): Remember that the SP's element
+ of the frame's saved_regs array is special.
+
+ * s390-tdep.c (register_names): Call the general-purpose registers
+ `r0' -- `r15', and the floating-point registers `f0' -- `f15', to
+ match the assembly language.
+
+2001-11-26 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * config/i386/tm-cygwin.h: Define HAVE_SSE_REGS if
+ HAVE_CONTEXT_EXTENDED_REGISTERS is defined.
+ * win32-nat.c: Define CONTEXT_DEBUGGER_DR that will also include
+ extended registers if HAVE_SSE_REGS is defined.
+ (mappings array): Add offset of extended registers.
+ (thread_rec): Use new CONTEXT_DEBUGGER_DR macro.
+
+2001-11-26 Tom Tromey <tromey@redhat.com>
+
+ * NEWS: Updated.
+ * event-loop.c (start_event_loop): Call
+ after_char_processing_hook.
+ * event-top.h (after_char_processing_hook): Declare.
+ * event-top.c (rl_callback_read_char_wrapper): Call
+ after_char_processing_hook.
+ (after_char_processing_hook): New global.
+ * top.c (operate_saved_history): New global.
+ (gdb_rl_operate_and_get_next): New function.
+ (init_main): Add the operate-and-get-next defun.
+ (gdb_rl_operate_and_get_next_completion): New function.
+
+2001-11-26 Tom Tromey <tromey@redhat.com>
+
+ * NEWS: Update for --args.
+ * infcmd.c (construct_inferior_arguments): Moved from ...
+ * fork-child.c: ... here.
+
+2001-11-26 Jim Blandy <jimb@redhat.com>
+
+ * symtab.c (find_pc_sect_line): Revert change of 2001-11-13; add
+ comment explaining that hand-written assembly code can have line
+ number info but no debug info for an enclosing function.
+
+2001-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ * sparc-nat.c (fetch_inferior_registers): Don't rely
+ on CORE_ADDR being 32-bit.
+ (store_inferior_registers): Likewise.
+
+2001-11-25 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/djgpp/config.sed: Fix an error in etc/ at "make install"
+ time on non-LFN systems where standards*.inf* expands to nothing.
+
+ * go32-nat.c (save_npx): Avoid a warning from GCC 3.x.
+
+2001-11-24 Pierre Muller <muller@ics.u-strasbg.fr>
+ Christopher Faylor <cgf@redhat.com>
+
+ * win32-nat.c (struct so_stuff): Add objfile *objfile field needed to
+ be able to remove the DLL when unloaded. Remove unused last field.
+ (handle_unload_dll): New function to handle unloading of DLL.
+ (solib_symbols_add): Change return type to struct objfile *.
+ (get_child_debug_event): Call handle_unload_dll function.
+
+2001-11-24 Christopher Faylor <cgf@redhat.com>
+
+ * win32-nat.c (_initialize_check_for_gdb_ini): New function.
+ * config/i386/xm-cygwin.h: Remove obsolete handling of __CYGWIN32__.
+ (GDBINIT_FILENAME): Remove.
+
+2001-11-23 Mark Kettenis <kettenis@gnu.org>
+
+ Add x86 OpenBSD native configuration.
+ * config/i386/obsd.mt, config/i386/tm-obsd.h, config/i386/obsd.mh,
+ config/i386/nm-obsd.h: New files.
+ * configure.host (i[3456]86-*-openbsd*): New host.
+ * configure.tgt (i[3456]86-*-openbsd*): New target.
+ * NEWS: Update.
+
+2001-11-21 GDB Administrator <gdbadmin@sourceware.cygnus.com>
+
+ * GDB 5.1 was released.
+
+2001-11-21 Tom Tromey <tromey@redhat.com>
+
+ Fix for PR gdb/209, PR gdb/156:
+ * gdbarch.c, gdbarch.h: Rebuilt.
+ * gdbarch.sh: Added `construct_inferior_arguments'.
+ * cli/cli-decode.h (cmd_list_element): Added pre_show_hook.
+ Typo fix.
+ * cli/cli-setshow.c (do_setshow_command): Call the pre_show_hook.
+ * infcmd.c (_initialize_infcmd): Set sfunc on `set args' command.
+ (inferior_argc, inferior_argv): New globals.
+ (notice_args_set): New function.
+ (set_inferior_args): Clear inferior_argc and inferior_argv.
+ (set_inferior_args_vector): New function.
+ (get_inferior_args): Handle inferior argument vector.
+ (run_command): Use get_inferior_args().
+ (notice_args_read): New function.
+ (_initialize_infcmd): Don't call set_inferior_args.
+ * command.h: Typo fix.
+ (cmd_list_element): Added pre_show_hook.
+ * main.c (captured_main): Added --args option.
+ (print_gdb_help): Document --args.
+ * inferior.h (construct_inferior_arguments): Declare.
+ (set_inferior_args_vector): Likewise.
+ * fork-child.c (construct_inferior_arguments): New function.
+
+2001-11-21 Kevin Buettner <kevinb@redhat.com>
+
+ * lin-lwp.c (lin_lwp_attach_lwp): Make sure SIGCHLD is in set of
+ blocked signals.
+
+ * lin-lwp.c (lin_lwp_attach_lwp): Mark main thread as stopped.
+
+2001-11-20 Jim Blandy <jimb@redhat.com>
+
+ * target.h (TARGET_RANGE_PROFITABLE_FOR_HW_WATCHPOINT): Delete
+ default definition; this is never used.
+
+2001-11-20 Keith Seitz <keiths@redhat.com>
+
+ * varobj.c (c_value_of_child): Release memory for "name" when
+ finshed using it.
+ (c_type_of_child): Likewise.
+ (cplus_value_of_child): Isolate the use of name_of_child to
+ one case that needs it.
+ Release memory for "name" when finished using it.
+
+2001-11-20 Keith Seitz <keiths@redhat.com>
+
+ * top.c (gdb_init): Call init_ui_hook before initializing
+ the default UI.
+
+2001-11-19 Elena Zannoni <ezannoni@redhat.com>
+
+ * config/powerpc/nm-linux.h (ppc_register_u_addr): Add extern
+ declaration.
+
+2001-11-19 Elena Zannoni <ezannoni@redhat.com>
+
+ * ppc-linux-nat.c (COPY_REG): Use regcache_collect instead of
+ accessing registers[].
+ (fill_fpregset): Ditto.
+
+2001-11-19 Elena Zannoni <ezannoni@redhat.com>
+
+ * infptrace.c (fetch_register): Dynamically allocate buffer for
+ register.
+ (store_register): Use regcache_collect, instead of accessing the
+ register buffer directly.
+
+2001-11-19 Daniel Jacobowitz <drow@mvista.com>
+
+ * mips-tdep.c (find_proc_desc): Add cur_frame argument. Pass
+ cur_frame to heuristic_proc_desc.
+ (heuristic_proc_desc): Add cur_frame argument. Do not read SP
+ if cur_frame == 0.
+ (after_prologue): Pass cur_frame == 0 to find_proc_desc.
+ (mips_frame_chain): Pass cur_frame == 1 to find_proc_desc.
+ (mips_init_extra_frame_info): Likewise.
+
+2001-11-19 Andrew Cagney <ac131313@redhat.com>
+
+ * defs.h (return_to_top_level): Comment.
+
+Mon Nov 19 14:58:52 2001 Andrew Cagney <cagney@redhat.com>
+
+ * remote.c (remote_open_1, remote_async_open_1): Use ISO C string
+ concatenation for error parameter.
+ (remote_cisco_open): Ditto.
+
+2001-11-19 Keith Seitz <keiths@redhat.com>
+
+ * varobj.c (c_value_of_child): Use the wrapper function,
+ gdb_value_struct_elt.
+ (cplus_value_of_child): Likewise.
+
+2001-11-18 Andrew Cagney <ac131313@redhat.com>
+
+ * i386-tdep.c (i386_gdbarch_init): Initialize num_regs.
+ * config/i386/tm-i386.h (NUM_REGS): Delete.
+
+2001-11-18 Kevin Buettner <kevinb@redhat.com>
+
+ * i386-linux-nat.c (fill_gregset): Fix botched regcache_collect()
+ conversion for I386_LINUX_ORIG_EAX_REGNUM.
+
+2001-11-18 Andrew Cagney <ac131313@redhat.com>
+
+ * config/i386/embed.mt (TM_FILE): Set to tm-i386.h.
+ * config/i386/tm-embed.h: Delete.
+
+2001-11-17 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in (distclean): Explicitly delete Makefile et.al. in
+ gdbserver sub directory.
+
+2001-11-17 Andrew Cagney <ac131313@redhat.com>
+
+ * README: Mention need for alloca(). Mention problems with
+ alpha-dec-osf4.0e. Clarify that comments refer to GDB 5.1.
+
+2001-11-17 Kevin Buettner <kevinb@redhat.com>
+
+ * i386-linux-nat.c (fill_gregset): Use regcache_collect() instead
+ of accessing registers[] directly.
+
+2001-11-17 Kevin Buettner <kevinb@redhat.com>
+
+ * i386-linux-nat.c (fill_gregset): Don't invoke read_register_gen()
+ when fetching ORIG_EAX.
+
+2001-11-17 Daniel Jacobowitz <drow@mvista.com>
+
+ * arm-linux-nat.c: Don't include <asm/ptrace.h>.
+ (fetch_register): Use elf_gregset_t instead of struct pt_regs.
+ (fetch_regs): Likewise.
+ (store_register): Likewise.
+ (store_regs): Likewise.
+
+2001-11-17 Daniel Jacobowitz <drow@mvista.com>
+
+ * sparc-linux-nat.c (fill_gregset): Replace read_register_gen
+ with regcache_collect.
+ (fill_fpregset): Likewise.
+
+2001-11-17 Daniel Jacobowitz <drow@mvista.com>
+
+ * Makefile.in: Add mips-linux-nat.c, mips-linux-tdep.c,
+ and sparc-linux-nat.c to ALLDEPFILES. Add dependencies.
+ * config/sparc/linux.mh: Add sparc-linux-nat.o to NATDEPFILES.
+ * sparc-linux-nat.c: New file, from Mark Kettenis.
+
+2001-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2read.c (dwarf_str_buffer): New.
+ (struct dwarf2_pinfo): Add dwarf_str_buffer and dwarf_str_size.
+ (DWARF_STR_BUFFER, DWARF_STR_SIZE): Define.
+ (dwarf2_has_info): Clear dwarf_str_offset.
+ (dwarf2_build_psymtabs): Read .debug_str section if present.
+ (dwarf2_build_psymtabs_hard): Save DWARF_STR_BUFFER and
+ DWARF_STR_SIZE.
+ (psymtab_to_symtab_1): Restore DWARF_STR_BUFFER and DWARF_STR_SIZE.
+ (read_attribute): Handle DW_FORM_strp.
+ (read_n_bytes, read_string): Remove HOST_CHAR_BIT != 8
+ handling code.
+ (read_indirect_string): New.
+ (dump_die): Handle DW_FORM_strp.
+
+2001-11-16 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c: Tweak argument-passing to match GCC bugs.
+ (is_float_singleton, is_struct_like, is_float_like): New
+ functions, that isolate the weirdness.
+ (is_double_or_float, is_simple_arg, pass_by_copy_ref,
+ is_double_arg): Use is_struct_like and is_float_like, rather than
+ testing the type codes ourselves.
+ (s390_push_arguments): When passing args on the stack, align each
+ on to a four-byte boundary, regardless of what the type itself
+ needs.
+
+2001-11-16 Ben Harris <bjh21@netbsd.org>
+
+ * Makefile.in (os9kread.o): Replace $< with autoconf-approved
+ $(srcdir)/....
+ (procfs.o): Ditto.
+ (z8k-tdep.o): Ditto.
+
+2001-11-16 Ben Harris <bjh21@netbsd.org>
+
+ * MAINTAINERS (write-after-approval): Add self.
+
+2001-11-15 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c (is_simple_arg): Structs and unions exactly eight
+ bytes long should be handled as DOUBLE_ARGs; don't recognize them
+ as SIMPLE_ARGs.
+
+2001-11-12 Andrew Cagney <ac131313@redhat.com>
+
+ * remote.c (struct packet_reg): Declare.
+ (struct remote_state): Add fields sizeof_g_packet and g_packet.
+ (init_remote_state): Initialize sizeof_g_packet and g_packet.
+ (free_remote_state): Free g_packet.
+ (packet_reg_from_pnum, packet_reg_by_regnum): New functions.
+ (remote_wait): Use above instead of gdbarch methods
+ REGISTER_RAW_SIZE and REGISTER_BYTES.
+ (remote_async_wait): Ditto.
+ (remote_fetch_registers, remote_store_registers): Ditto.
+ (store_register_using_P): Ditto.
+
+2001-11-15 Andrew Cagney <ac131313@redhat.com>
+
+ * remote.c (_initialize_remote): Don't multi-arch swap tty_input.
+ Second attempt.
+
+2001-11-15 Andrew Cagney <ac131313@redhat.com>
+
+ * utils.c (phex_nz): For default case, set str to phex_nz return
+ value.
+ (phex): Ditto.
+
+2001-11-15 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO (register_buffer): Delete.
+ * regcache.c (register_buffer): Make static.
+ (regcache_collect): New function.
+ * regcache.h (register_buffer): Delete declaration.
+ (regcache_collect): Declare.
+ * remote.c (store_register_using_P): Rewrite using
+ regcache_collect.
+ (remote_store_registers): Ditto.
+ * go32-nat.c (store_register): Ditto.
+
+2001-11-14 Andrew Cagney <ac131313@redhat.com>
+
+ * remote.c (struct remote_state): Declare.
+ (get_remote_state): New function.
+ (init_remote_state): New function.
+ (remote_gdbarch_data_handle): New global.
+ (build_remote_packet_sizes): Delete function, moved to
+ init_remote_state.
+ (register_remote_packet_sizes): Delete function.
+ (actual_register_packet_size, remote_packet_size): Moved to
+ ``struct remote_state''.
+ (PBUFSIZE): Delete. Replaced by rs->remote_packet_size.
+ (free_remote_state): New function.
+ (get_memory_packet_size, get_memory_read_packet_size)
+ (set_thread, remote_unpack_thread_info_response)
+ (remote_get_threadinfo, parse_threadlist_response)
+ (remote_get_threadlist, remote_current_thread)
+ (remote_threads_info, remote_threads_extra_info)
+ (extended_remote_restart, get_offsets)
+ (get_offsets, remote_check_symbols, remote_open_1)
+ (remote_async_open_1, remote_detach, remote_async_detach)
+ (remote_resume, remote_async_resume, remote_wait)
+ (remote_async_wait, remote_fetch_registers)
+ (store_register_using_P, remote_store_registers)
+ (check_binary_download, putpkt_binary)
+ (remote_insert_breakpoint, remote_remove_breakpoint)
+ (remote_insert_watchpoint, remote_remove_watchpoint)
+ (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint)
+ (compare_sections_command, remote_query)
+ (remote_rcmd, remote_rcmd, packet_command)
+ (remote_info_process): Update.
+
+2001-11-14 Andrew Cagney <ac131313@redhat.com>
+
+ * remote.c: Include "gdb_assert.h".
+ (tty_input): Wire buffer to 400 bytes.
+ (readsocket): Check tty_input doesn't overflow.
+ (build_remote_gdbarch_data, _initialize_remote): Don't multi-arch
+ tty_input.
+
+2001-11-14 Michael Snyder <msnyder@redhat.com>
+
+ * d10v-tdep.c (d10v_pointer_to_address): Use new type flag
+ TYPE_FLAG_CODE_SPACE to recognize a pointer that has been cast
+ into the instruction address space.
+ * Makefile.in (doublest.o): Add dependency on gdbtypes.h.
+
+2001-11-14 Michael Snyder <msnyder@redhat.com>
+ Add address space identifiers to expression language for types.
+ * c-exp.y (space_identifier, cv_with_space_id,
+ const_or_volatile_or_space_identifier_noopt,
+ const_or_volatile_or_space_identifier): New terminals.
+ (ptype): Accept const_or_volatile_or_space_identifier.
+ (typebase): Accept const_or_volatile_or_space_identifier.
+ * c-typeprint.c (c_type_print_cv_qualifier): Rename to
+ c_type_print_modifier. Handle address space modified types.
+ * gdbtypes.h (TYPE_FLAG_CODE_SPACE, TYPE_FLAG_DATA_SPACE):
+ New type flags.
+ (struct type): Add new field as_type for addr-space qualified types.
+ (TYPE_AS_TYPE): New macro, retrieves the chain of types that are
+ identical to this one except for address-space qualification.
+ * gdbtypes.c (alloc_type): Initialize new field 'as_type'.
+ (address_space_name_to_int): New function.
+ (address_space_int_to_name): New function.
+ (make_type_with_address_space): New function.
+ (make_cv_type): Handle as_type field of new struct type object.
+ * parse.c (check_type_stack_depth): New function.
+ (push_type_address_space): New function.
+ (follow_types): Handle types with address-space qualifier.
+ * parser-defs.h (enum type_pieces): Add enum tp_space_identifier.
+
+2001-11-14 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c (s390_pop_frame_regular): On the S/390, the frame
+ pointer and the SP are often the same, so we can't pop the frame
+ by setting the SP to the FP; we need to get the old SP from
+ saved_regs.
+
+ * s390-tdep.c (s390_extract_return_value): Returned `float' values
+ can simply be copied bitwise from the registers into the value
+ object's buffer.
+
+ * s390-tdep.c (s390_get_frame_info): Initialize SP's element of
+ the frame's saved_regs array correctly.
+
+ * symfile.c (simple_read_overlay_table): Make sure we can find
+ both `_novlys' and `_ovly_table' before we try anything else;
+ print a helpful error message.
+ (simple_overlay_update): No need to print error message here.
+
+2001-11-14 Michael Snyder <msnyder@redhat.com>
+
+ * Makefile.in (doublest.o): Add dependency on gdbtypes.h.
+
+2001-11-10 Andrew Cagney <ac131313@redhat.com>
+
+ * arm-tdep.c (arm_register_type): New function.
+ (arm_register_convertible): Delete.
+ (arm_register_convert_to_virtual): Delete.
+ (arm_register_convert_to_raw): Delete.
+ * config/arm/tm-arm.h (REGISTER_CONVERTIBLE): Delete.
+ (REGISTER_CONVERT_TO_VIRTUAL): Delete.
+ (REGISTER_CONVERT_TO_RAW): Delete.
+ (REGISTER_VIRTUAL_TYPE): Redefine as call to arm_register_type.
+ (arm_register_type): Declare.
+
+2001-11-13 Elena Zannoni <ezannoni@redhat.com>
+
+ From Andrew Cagney <cagney@redhat.com>:
+ * gdbtypes.h (builtin_type_int128, builtin_type_uint128): Declare.
+ * gdbtypes.c (_initialize_gdbtypes, build_gdbtypes): Initialize
+ new builtin types.
+
+2001-11-13 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c: Rewrite inferior function call code. This may
+ break zSeries support; that should be fixed soon.
+ #include "gdb_assert.h".
+ (is_integer_like, is_pointer_like, is_simple_arg,
+ pass_by_copy_ref, extend_simple_arg, is_double_arg, round_up,
+ round_down, alignment_of): New functions.
+ (s390_push_arguments): Rewritten to handle passing large arguments
+ by value, and to make more readable.
+
+ * s390-tdep.c (s390_pop_frame): Call generic_pop_current_frame, to
+ interact correctly with generic dummy frames.
+ (s390_pop_frame_regular): Move the guts of the frame-popping code
+ to here, to be called by generic_pop_current_frame. Use the
+ frame's saved_regs array; this works for `return' as well as
+ inferior function calls.
+
+ * s390-tdep.c (s390_gdbarch_init): Register the function
+ `standard_coerce_float_to_double', since GCC for the S/390 follows
+ the standard rules for passing floats.
+
+ * valops.c (default_coerce_float_to_double,
+ standard_coerce_float_to_double): Doc fixes.
+
+ Patch from Peter Schauer:
+
+ * symtab.c (find_pc_sect_line): If we can't find the function
+ containing PC, we certainly won't have line number information for
+ that location, so return zero immediately.
+
+2001-11-10 Andrew Cagney <ac131313@redhat.com>
+
+ * config/i960/tm-nindy960.h (REGISTER_CONVERTIBLE)
+ (REGISTER_CONVERT_TO_RAW, REGISTER_CONVERT_TO_VIRTUAL): Delete
+ undef.
+ * i960-tdep.c (i960_register_type): New function.
+ * config/i960/tm-i960.h (REGISTER_CONVERTIBLE): Delete.
+ (REGISTER_CONVERT_TO_VIRTUAL): Delete.
+ (REGISTER_CONVERT_TO_RAW): Delete.
+ (REGISTER_VIRTUAL_TYPE): Update. Call i960_register_type.
+
+2001-11-10 Andrew Cagney <ac131313@redhat.com>
+
+ * m88k-tdep.c (m88k_register_type): New function.
+ * config/m88k/tm-m88k.h (REGISTER_CONVERTIBLE): Delete.
+ (REGISTER_CONVERT_TO_VIRTUAL): Delete.
+ (REGISTER_CONVERT_TO_RAW): Delete.
+ (m88k_register_type): Declare.
+ (REGISTER_VIRTUAL_TYPE): Update. Call m88k_register_type.
+
+2001-11-11 Mark Kettenis <kettenis@elgar.my.domain>
+
+ * i386-tdep.h (FPU_REG_RAW_SIZE): Define unconditionally.
+ * i387-nat.c, i387-tdep.c: Unconditionally include "i386-tdep.h".
+ * config/i386/tm-i386.h (FPU_REG_RAW_SIZE): Removed.
+ (SIZEOF_FPU_REGS): Don't use FPU_REG_RAW_SIZE here.
+
+2001-11-12 Jim Blandy <jimb@redhat.com>
+
+ Patch from Andreas Schwab <schwab@suse.de>:
+ * eval.c (evaluate_subexp_standard): Fix memory leak: use alloca
+ instead of xmalloc.
+
+2001-11-12 Jim Blandy <jimb@redhat.com>
+
+ * corefile.c (write_memory_unsigned_integer,
+ write_memory_signed_integer): New functions.
+ (write_memory): Move to be with other write_memory_* functions.
+ * gdbcore.h (write_memory_unsigned_integer,
+ write_memory_signed_integer): New declarations.
+
+2001-11-11 Geoffrey Keating <geoffk@redhat.com>
+
+ * dwarf2read.c (dwarf_decode_lines): Properly deal with
+ unknown standard opcodes.
+
+2001-11-11 Andrew Cagney <ac131313@redhat.com>
+
+ * README (alpha-dec-osf5.1): Mention -DUSE_LDR_ROUTINES.
+ (sparcv9-sun-solars2.8): Mention problem with 64 bit GCC 3.0.x.
+ (i586-sco-sysv5uw7.1.1): Mention problem with threads.
+
+2001-11-11 Andrew Cagney <ac131313@redhat.com>
+
+ From Mark Kettenis <kettenis@gnu.org>:
+ * breakpoint.c (breakpoint_re_set_one): Don't discard SHLIB
+ breakpoints when they fail.
+
+2001-11-10 Andrew Cagney <ac131313@redhat.com>
+
+ * printcmd.c, valprint.c, language.c, linespec.c, infcmd.c,
+ gnu-nat.c, findvar.c, expprint.c, typeprint.c, stack.c, top.c:
+ Replace value_ptr with struct value.
+
+2001-11-10 Andrew Cagney <ac131313@redhat.com>
+
+ * c-valprint.c, ch-lang.c, ch-valprint.c, cp-valprint.c,
+ p-valprint.c, scm-exp.c, scm-lang.c, scm-valprint.c: Replace
+ value_ptr with struct value.
+
+2001-11-10 Andrew Cagney <ac131313@redhat.com>
+
+ * eval.c: Replace most occurances of value_ptr with struct value.
+
+2001-11-09 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c: Don't use a call dummy.
+ (s390_fix_call_dummy, s390_pc_in_call_dummy): Delete.
+ (s390_push_return_address): Put the address of the inferior call
+ breakpoint in r14.
+ (s390_gdbarch_init):
+ - Provide trivial definition of s390_call_dummy_words; register it
+ with the gdbarch appropriately.
+ - Delete S390x_call_dummy_words.
+ - Gather inferior-call-related settings into a group.
+ - Use generic dummy frames.
+ - Put the inferior call breakpoint at the entry point.
+ - Use generic gdbarch methods: pc_in_call_dummy_at_entry_point,
+ generic_push_dummy_frame, generic_fix_call_dummy.
+ - There is a call dummy breakpoint offset; it's zero.
+
+ * s390-tdep.c: (s390_push_arguments): Write a back chain pointer
+ into the dummy frame, to help us get backtraces.
+
+ * values.c (value_as_address): If VAL is a function or method,
+ just return its address; don't let COERCE_ARRAY convert its
+ address to a pointer, and then have unpack_long convert it back to
+ an address.
+
+2001-11-06 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * p-lang.c (is_pascal_string_type): New function to determine if a
+ type is a string type.
+ * p-lang.h: Add prototype for is_pascal_string_type.
+ * p-valprint.c (pascal_val_print) : Use is_pascal_string_type function
+ to display strings nicely.
+
+2001-11-06 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * p-exp.y (yylex): Only change case of expression if symbol is found.
+ Also check for GPC standard name form.
+
+2001-11-08 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb_indent.sh: New file.
+
+2001-11-08 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c (s390_get_frame_info): Initialize got_load_addr and
+ got_load_len, to placate compiler.
+
+2001-11-08 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-tdep.c (i386_gdbarch_init): Fix typo.
+
+2001-11-08 Jim Blandy <jimb@redhat.com>
+
+ * s390-tdep.c (s390_gdbarch_init): Use func_frame_chain_valid, not
+ file_frame_chain_valid.
+
+ * s390-tdep.c (s390_get_frame_info): If the prologue loads r12
+ from the constant pool, but doesn't add in the constant pool's
+ address to it, then this function probably isn't using r12 as a
+ GOT pointer, and that load probably wasn't part of the prologue.
+
+ * s390-tdep.c (s390_gdbarch_init): Use the default
+ prepare_to_proceed function established by config/nm-linux.h;
+ don't try to set it to linuxthreads_prepare_to_proceed.
+
+Wed Nov 7 20:38:14 2001 Andrew Cagney <cagney@redhat.com>
+
+ * i386-tdep.c: Include "i386-tdep.h".
+ (XMALLOC): Define.
+ (i386_gdbarch_init): New function.
+ (_initialize_i386_tdep): Register bfd_arch_i386.
+ * config/i386/tm-i386.h (GDB_MULTI_ARCH): Define as
+ GDB_MULTI_ARCH_PARTIAL.
+ * i386-tdep.h: When partially multi-arch, conditionally define
+ all macros.
+
+Wed Nov 7 20:45:32 2001 Andrew Cagney <cagney@redhat.com>
+
+ * i386-tdep.c (set_disassembly_flavor): Delete function.
+ (set_disassembly_flavor_sfunc): Delete function.
+
+2001-11-07 Elena Zannoni <ezannoni@redhat.com>
+
+ * dbxread.c (set_namestring): New function, replacing the
+ SET_NAMESTRING macro.
+ (SET_NAMESTRING, CUR_SYMBOL_TYPE, CUR_SYMBOL_VALUE,
+ CUR_SYMBOL_STRX, DBXREAD_ONLY, START_PSYMTAB, END_PSYMTAB): Delete
+ definitions.
+ (read_dbx_symtab): Don't include partial-stab.h any more. Don't
+ reuse code in partial-stab.h, include the code directly, instead.
+
+ * Makefile.in (dbxread.o): Remove dependency on partial-stab.h.
+ (HFILES_NO_SRCDIR): Remove partial-stab.h.
+
+ * partial-stab.h: Remove file.
+
+2001-11-07 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh: For multi-arch functions, check there is a
+ predefault and use it as the static default.
+ * gdbarch.c: Re-generate.
+
+2001-11-08 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-linux.h (I386_LINUX_ORIG_EAX_REGNUM): Define in
+ terms of NUM_GREGS, NUM_FREGS and NUM_SSE_REGS instead of
+ hardcoding the register number.
+
+2001-11-07 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (USE_STRUCT_CONVENTION): Default to
+ generic_use_struct_convention.
+ * gdbarch.h, gdbarch.c: Regenerate.
+ * values.c (USE_STRUCT_CONVENTION): Delete definition, moved to
+ gdbarch.h.
+
+2001-11-06 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (PC_IN_CALL_DUMMY): Require a value.
+ * gdbarch.c: Regenerate.
+
+2001-11-06 Fred Fish <fnf@redhat.com>
+
+ * complaints.c (info_verbose): Remove unneeded decl, is in defs.h.
+ * dbxread.c: Ditto
+ * dwarf2read.c: Ditto.
+ * dwarfread.c: Ditto.
+ * exec.c: Ditto.
+ * hpread.c: Ditto.
+ * hpread.h: Ditto.
+ * mdebugread.c: Ditto.
+ * os9kread.c: Ditto.
+ * stack.c: Ditto.
+ * symfile.c: Ditto.
+ * tracepoint.c: Ditto.
+
+2001-11-06 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Update Andrew Cagney's responsibilities. Mention
+ David Taylor and Nick Duffek in past maintainers.
+
+2001-11-06 Elena Zannoni <ezannoni@redhat.com>
+
+ * mdebugread.c (CUR_SYMBOL_TYPE, CUR_SYMBOL_VALUE, START_PSYMTAB,
+ END_PSYMTAB, SET_NAMESTRING, HANDLE_RBRAC): Delete definitions.
+ (parse_partial_symbols): Don't include partial-stab.h any
+ more. Don't reuse code in partial-stab.h, include the code
+ directly, instead. Simplify code from partial-stab.h eliminating
+ ifdef DBXREAD_ONLY code.
+
+ * Makefile.in (mdebugread.o): Remove dependency on partial-stab.h.
+
+2001-11-06 Jim Blandy <jimb@redhat.com>
+
+ * s390-nat.c: #include "regcache.h", to get declaration for
+ `supply_register'. (The last change already added the dependency
+ of s390-nat.o on regcache.h. Oops.)
+
+ * Makefile.in (ALLDEPFILES): Add s390-tdep.c and s390-nat.c.
+ (s390-tdep.o, s390-nat.o): New rules.
+
+ * s390-nat.c (s390_register_u_addr): Pass proper arguments to
+ internal_error.
+
+2001-11-06 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (CALL_DUMMY_LOCATION): Require a value.
+ * gdbarch.c: Regenerate.
+
+2001-11-06 Andrew Cagney <ac131313@redhat.com>
+
+ * blockframe.c (get_prev_frame): Replace #ifdef
+ INIT_EXTRA_FRAME_INFO with run-time test.
+
+2001-11-05 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (push_return_address): Change to a function with
+ predicate.
+ * gdbarch.h, gdbarch.c: Re-generate.
+ * valops.c (hand_function_call): Replace #ifdef
+ PUSH_RETURN_ADDRESS with run-time test of PUSH_RETURN_ADDRESS_P.
+
+2001-11-06 Corinna Vinschen <vinschen@redhat.com>
+
+ * arch-utils.c (generic_in_function_epilogue_p): New function.
+ * arch-utils.h (generic_in_function_epilogue_p): Declare extern.
+ * breakpoint.c (watchpoint_check): Add test whether the pc is
+ currently in the epilogue of a function.
+ * gdbarch.c: Autogenerated from gdbarch.sh.
+ * gdbarch.h: Ditto.
+ * gdbarch.sh (function_list): Add `in_function_epilogue_p' definition.
+
+2001-11-05 Jim Blandy <jimb@redhat.com>
+
+ * config/s390/s390.mh (NATDEPFILES): Don't split this across
+ several lines with backslashes; the `sed' command in
+ configure.in's AC_OUTPUT clause that comments out the NATDEPFILES
+ assignment doesn't handle lines extended with backslashes.
+
+ * configure.in (AC_OUTPUT): Handle assignments to NATDEPFILES
+ using `+=' as well as `='.
+ * configure: Regenerated.
+
+2001-11-05 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (init_extra_frame_info): Change to a function with
+ predicate.
+ * gdbarch.h, gdbarch.c: Re-generate.
+ * blockframe.c (create_new_frame): Replace #ifdef
+ INIT_EXTRA_FRAME_INFO with run-time test of
+ INIT_EXTRA_FRAME_INFO_P.
+
+2001-11-05 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (verify_gdbarch): Use a mem_file to accumulate all
+ error messages. Print in a single batch.
+ * gdbarch.c: Re-generate.
+
+2001-11-04 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-linux-nat.c (GETREGS_SUPPLIES, supply_gregset,
+ fill_gregset): Add support for "orig_eax" register.
+
+ Add support for "orig_eax" pseudo register on Linux/x86.
+ * i386-linux-tdep.c: Include "inferior.h".
+ (i386_linux_register_name, i386_linux_register_byte,
+ i386_linux_register_raw_size): New functions.
+ (i386_linux_write_pc): New function.
+ * config/i386/tm-linux.h (I386_LINUX_ORIG_EAX_REGNUM): New define.
+ (NUM_REGS, MAX_NUM_REGS, REGISTER_BYTES, REGISTER_NAME,
+ REGISTER_BYTE, REGISTER_RAW_SIZE): Define to deal with additional
+ register.
+ (i386_linux_register_name, i386_linux_register_byte,
+ i386_linux_register_raw_size): New prototypes.
+ (TARGET_WRITE_PC): New define.
+ (i386_linux_write_pc): New prototype.
+
+ * i386-tdep.c (i386_register_offset): Renamed from
+ i386_register_byte. Made static.
+ (i386_register_size): Renamed from i386_register_raw_size. Made
+ static.
+ (i386_register_virtual_size): Removed.
+ (i386_register_byte, i386_register_raw_size,
+ i386_register_virtual_size): New functions.
+ (_initialize_i386_tdep): Initialize i386_register_offset instead
+ of i386_register_byte. Remove code to initialize
+ i386_register_virtual_size.
+ * config/i386/tm-i386.h (REGISTER_BYTE): Redefine to use
+ i386_register_byte function.
+ (REGISTER_RAW_SIZE): Redefine to use i386_register_raw_size
+ function.
+ (REGISTER_VIRTUAL_SIZE): Redefine to use
+ i386_register_virtual_size function.
+ (i386_register_byte, i386_register_raw_size,
+ i386_register_virtual_size): New functions.
+
+ * Makefile.in (ALLDEPFILES): Add i387-nat.c.
+ (i387-nat.o): Add dependencies.
+
+2001-11-02 Andrew Cagney <ac131313@redhat.com>
+
+ * README: Mention problem with alpha-dec-osf5.1.
+
+2001-11-02 Andrew Cagney <ac131313@redhat.com>
+
+ * utils.c (internal_verror): Restore calls to abort().
+ Fix PR gdb/219.
+
+2001-11-02 Michael Chastain <mec@shout.net>
+
+ * MAINTAINERS: Update my entry.
+
+2001-11-01 Michael Snyder <msnyder@redhat.com>
+
+ * symtab.c (operator_chars): Allow '*' and '[' to be quoted in
+ operator names, to avoid regexp expansion.
+ (search_symbols): Alloca buffer is too small, may get clobbered.
+
+2001-11-01 Fred Fish <fnf@redhat.com>
+
+ * coff-solib.c (coff_solib_add): Add new readsyms arg.
+ * irix5-nat.c (solib_add): Ditto.
+ * osfsolib.c (solib_add): Ditto.
+ * pa64solib.c (pa64_solib_add): Ditto.
+ * pa64solib.c (add_to_solist): Ditto.
+ * pa64solib.c (read_dld_descriptor): Ditto.
+ * solib.c (solib_add): Ditto.
+ * somsolib.c (som_solib_add): Ditto.
+ * win32-nat.c (child_solib_add): Ditto.
+ * xcoffsolib.c (solib_add): Ditto.
+
+ * coff-solib.h (coff_solib_add): Add new readsyms arg to prototype.
+ * pa64solib.c (add_to_solist): Ditto.
+ * pa64solib.c (read_dld_descriptor): Ditto.
+ * pa64solib.h (pa64_solib_add): Ditto.
+ * solib.h (solib_add): Ditto.
+ * somsolib.h (som_solib_add): Ditto.
+ * config/i386/tm-cygwin.h (child_solib_add): Ditto.
+
+ * coff-solib.c (coff_solib_add): If readsyms is zero don't read
+ symbols but do any other needed work for shared libs.
+ * irix5-nat.c: Ditto.
+ * osfsolib.c (solib_add): Ditto.
+ * solib.c (solib_add): Ditto.
+ * win32-nat.c (child_solib_add): Ditto.
+ * xcoffsolib.c (solib_add): Ditto.
+
+ * irix5-nat.c (sharedlibrary_command): Pass 1 as readsyms to
+ solib_add to force reading of shared library symbols.
+ * osfsolib.c (sharedlibrary_command;): Ditto.
+ * pa64solib.c (pa64_solib_sharedlibrary_command): Ditto.
+ * solib.c (sharedlibrary_command): Ditto.
+ * somsolib.c (som_solib_sharedlibrary_command): Ditto.
+ * xcoffsolib.c (sharedlibrary_command): Ditto.
+
+ * coff-solib.c (coff_solib_create_inferior_hook): Call solib_add
+ unconditionally with auto_solib_add.
+ * irix5-nat.c (solib_create_inferior_hook): Ditto.
+ * osfsolib.c (solib_create_inferior_hook): Ditto.
+ * solib.c (solib_create_inferior_hook): Ditto.
+ * solib-osf.c (osf_solib_create_inferior_hook): Ditto.
+ * solib-svr4.c (enable_break): Ditto.
+ * solib-sunos.c (sunos_solib_create_inferior_hook): Ditto.
+
+ * corelow.c (solib_add_stub): Add auto_solib_add to args passed
+ via SOLIB_ADD.
+ * sol-thread.c (sol_thread_attach): Ditto.
+ * config/rs6000/nm-rs6000.h (SOLIB_ADD): Ditto.
+
+ * infcmd.c (attach_command): Remove auto_solib_add decl.
+ Call SOLIB_ADD directly with auto_solib_add.
+ * infrun.c (handle_inferior_event): Ditto.
+
+ * coff-solib.h (SOLIB_ADD): Add readsyms arg.
+ * pa64solib.h (SOLIB_ADD): Ditto.
+ * solib.h (SOLIB_ADD): Ditto.
+ * somsolib.h (SOLIB_ADD): Ditto.
+ * config/i386/tm-cygwin.h (SOLIB_ADD): Ditto.
+
+ * fork-child.c (clone_and_follow_inferior): Remove unused
+ auto_solib_add decl.
+
+ * pa64solib.c (pa64_solib_add): Call add_to_solist with readsyms.
+ (read_dld_descriptor): Ditto.
+ (pa64_solib_add): Call read_dld_descriptor with readsyms.
+ (pa64_solib_in_dynamic_linker): Ditto.
+
+ * corelow.c (symfile.h): Need this for auto_solib_add declaration.
+ * sol-thread.c (symfile.h): Ditto.
+
+2001-10-31 Andrew Cagney <ac131313@redhat.com>
+
+ * s390-nat.c (s390_remove_watchpoint): Use xfree.
+ (s390_insert_watchpoint): Use xmalloc.
+
+2001-10-31 Andrew Cagney <ac131313@redhat.com>
+
+ * varobj.c: Replace value_ptr with ``struct value *''.
+
+2001-10-31 Andrew Cagney <ac131313@redhat.com>
+
+ * varobj.c: Re-indent.
+
+2001-10-31 Andrew Cagney <ac131313@redhat.com>
+
+ * x86-64-tdep.c (value_push, x86_64_push_arguments): Replace
+ ``value_ptr'' with ``struct value *''.
+ * s390-tdep.c (s390_push_arguments): Ditto.
+
+2001-10-30 Andrew Cagney <ac131313@redhat.com>
+
+ * ppc-tdep.h: Add #ifndef wrapper. Replace value_ptr with
+ ``struct value *''.
+ (struct frame_info, struct value): Add opaque declarations.
+
+2001-10-31 Corinna Vinschen <vinschen@redhat.com>
+
+ * arch-utils.c (generic_in_solib_call_trampoline): New function.
+ * arch-utils.h (generic_in_solib_call_trampoline): Extern declaration.
+ * gdbarch.c: Regenerated from gdbarch.sh.
+ * gdbarch.h: Ditto.
+ * gdbarch.sh (function_list): Add `IN_SOLIB_CALL_TRAMPOLINE' definition.
+ * infrun.c (IN_SOLIB_CALL_TRAMPOLINE): Remove macro.
+
+2001-10-31 Andrew Cagney <ac131313@redhat.com>
+
+ From DJ Barrow.
+ * s390-tdep.c: (s390_gdbarch_init): Don't initialize
+ find_solib_trampoline_target.
+
+2001-10-31 Andrew Cagney <ac131313@redhat.com>
+
+ * remote-vx.c (net_wait): Fix typo from PIDGET change.
+
+2001-10-31 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-i386.h (REGISTER_NAMES): Remove.
+ (REGISTER_NAME): New define.
+ (i386_register_name): New prototype.
+ * i386-tdep.c (i386_register_names): New variable.
+ (i386_register_name): New function.
+ * config/i386/tm-i386os9k.h, config/i386/tm-ptx.h,
+ config/i386/tm-symmetry.h: Undefine REGISTER_NAME instead of
+ REGISTER_NAMES.
+
+2001-10-31 Christopher Faylor <cgf@redhat.com>
+
+ * win32-nat.c (register_loaded_dll): Attempt to ensure that the case of
+ the loaded DLL matches the on-disk case since the debugging API does
+ not seem to ensure this. Calculate max name length here.
+ (handle_load_dll): Move max name length calculation to
+ register_loaded_dll.
+
+2001-10-31 Daniel Jacobowitz <drow@mvista.com>
+
+ * arm-linux-nat.c: Include <asm/ptrace.h> explicitly.
+
+2001-10-30 Keith Seitz <keiths@redhat.com>
+
+ * wrapper.h (gdb_value_struct_elt): New function.
+ * wrapper.c (gdb_value_struct_elt): Ditto.
+ (do_captured_value_struct_elt): Ditto.
+
+2001-10-30 Andrew Cagney <ac131313@redhat.com>
+
+ * README, NEWS: Update for 5.1.
+
+2001-10-30 Andrew Cagney <ac131313@redhat.com>
+
+ * configure.in (WERROR_CFLAGS): Use AC_TRY_COMPILE to test the
+ -W... flags.
+ * configure: Re-generate.
+
+2001-10-30 Fred Fish <fnf@redhat.com>
+
+ * somsolib.c (som_solib_add): A megabyte is 1024*1024 bytes.
+ * pa64solib.c (add_to_solist): Ditto.
+ * win32-nat.c (_initialize_inftarg): Remove unnecessary
+ initialization of auto_solib_add, it defaults to 1.
+
+2001-10-27 Fred Fish <fnf@redhat.com>
+
+ * symfile.c (auto_solib_add): Update comment to note that
+ this variable is now just used as a boolean to control shlib
+ autoloading, and clarify when it is used.
+ * symfile.h (auto_solib_add): Ditto.
+
+ * symfile.c (auto_solib_limit): New variable that holds the
+ autoloading threshold instead of overloading auto_solib_add.
+ * symfile.h (auto_solib_limit): Ditto.
+
+ * irix5-nat.c (_initialize_solib): Change auto-solib-add
+ variable from var_zinteger to var_boolean and update help.
+ * osfsolib.c (_initialize_solib): Ditto.
+ * pa64solib.c (_initialize_pa64_solib): Ditto.
+ * solib.c (_initialize_solib): Ditto.
+ * somsolib.c (_initialize_som_solib): Ditto.
+ * xcoffsolib.c (_initialize_solib): Ditto.
+
+ * pa64solib.c (pa64_solib_total_st_size): Update comment to
+ note that the new auto_solib_limit variable is used instead
+ of overloading auto_solib_add variable.
+ (_initialize_pa64_solib): Ditto.
+ * somsolib.c (som_solib_total_st_size): Ditto.
+ (_initialize_som_solib): Ditto.
+
+ * pa64solib.c (_initialize_pa64_solib): Add new set/show
+ commands for auto-solib-limit variable.
+ * somsolib.c (_initialize_som_solib): Ditto
+
+ * pa64solib.c (add_to_solist): Check that auto_solib_add is
+ set and use auto_solib_limit as the threshold size instead
+ of auto_solib_add.
+ * somsolib.c (som_solib_add): Ditto, and also change warning
+ text about size threshold exceeded.
+
+2001-10-21 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-i386v.h: Don't include "regcache.h".
+ (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE, FRAME_CHAIN,
+ FRAMELESS_FUNCTION_INVOCATION, FRAME_SAVED_PC, FRAME_NUM_ARGS):
+ Remove macros. The versions from "tm-i386.h" should work fine
+ (and in most cases even better).
+
+2001-10-30 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-tdep.c (i386_extract_return_value): Use
+ convert_typed_floating to extract floating-point value from
+ register buffer.
+ (i386_store_return_value): Use convert_typed_floating to store
+ floating-point return balue in register buffer
+ (i386_register_virtual_type): Change type of floating-point
+ registers to builtin_type_i387_ext.
+ (i386_register_convert_to_virtual): Use convert_typed_floating to
+ do the conversion.
+ (i386_register_convert_to_raw): Likewise.
+
+2001-10-29 Mark Kettenis <kettenis@gnu.org>
+
+ * doublest.h (convert_typed_floating): New prototype.
+ * doublest.c (convert_typed_floating): New function.
+
+2001-10-28 Mark Kettenis <kettenis@gnu.org>
+
+ * doublest.c: Improve comments a bit.
+ (floatformat_from_length): New function.
+ (NAN): Define to 0.0 if not already defined.
+ (extract_floating): Rewrite to use floatformat_from_length. Warn
+ instead of error if LEN doesn't match a known floating-point type,
+ and return NaN (or 0.0 if NaN isn't available) in that case.
+ (store_floating): Likewise, but zero out the target byte-stream if
+ LEN doesn't match a known floating-point type.
+ (extract_typed_floating): Reformat a bit.
+ (store_typed_floating): Reformat a bit. Add comment about zeroing
+ out padding in the target buffer.
+ * doublest.h (extract_floating, store_floating): Fix comment about
+ deprecation of these functions. Add parameter names to prototypes.
+
+2001-10-28 Mark Kettenis <kettenis@gnu.org>
+
+ * i387-tdep.c (print_i387_value): Use extract_typed_floating to
+ convert RAW to a DOUBLEST instead of extract_floating.
+
+ * gdbtypes.c (_initialize_gdbtypes): Set floating-point type for
+ builtin_type_i387_ext to floatformat_i387_ext.
+
+2001-10-24 Daniel Jacobowitz <drow@mvista.com>
+
+ * arm-linux-nat.c (fill_gregset): Do not check register_valid[].
+ (fill_fpregset): Likewise.
+
+2001-10-26 Orjan Friberg <orjanf@axis.com>
+
+ * cris-tdep.c (constraint): Loop through the whole cris_spec_regs
+ struct, not just the NUM_SPECREGS first entries.
+ (bdap_prefix): Read PC before autoincrement.
+
+2001-10-24 Corinna Vinschen <vinschen@redhat.com>
+
+ * win32-nat.c (DebugSetProcessKillOnExit): New static function
+ pointer to Windows' DebugSetProcessKillOnExit() function.
+ (DebugActiveProcessStop): Ditto for DebugActiveProcessStop().
+ (has_detach_ability): New function.
+ (child_attach): If system has detach ability, enable it.
+ (child_detach): If system has detach ability, actually
+ detach from process.
+ Change tty output to Linux format.
+
+2001-10-23 Jim Blandy <jimb@redhat.com>
+
+ Isolate STABS readers' use of the `textlow' and `texthigh' fields
+ of `struct partial_symtab' to only a few locations. This change
+ is not supposed to affect the way the values are computed, only
+ where they live.
+
+ * dbxread.c (struct symloc): Add `textlow' and `texthigh' fields
+ to the reader-specific structure.
+ * mdebugread.c (struct symloc): Same.
+ * dbxread.c (TEXTLOW, TEXTHIGH): New accessor macros.
+ * mdebugread.c (TEXTLOW, TEXTHIGH): Same.
+ * dbxread.c (dbx_symfile_read): After we've built all our partial
+ symbol tables, set each partial symtab's `textlow' and `texthigh'
+ fields from our reader-specific structure.
+ * mdebugread.c (mdebug_build_psymtabs): Same.
+ * dbxread.c (start_psymtab): Initialize the reader-specific
+ structure's `textlow' and `texthigh' from the new psymtab's.
+ * mdebugread.c (parse_partial_symbols, new_psymtab): Same.
+ * dbxread.c (read_dbx_symtab, end_psymtab, read_ofile_symtab): Use
+ the reader-specific `textlow' and `texthigh', not the generic
+ psymtab fields.
+ * mdebugread.c (parse_lines, parse_partial_symbols,
+ psymtab_to_symtab_1): Same.
+ * partial-stab.h: Same.
+
+Tue Oct 23 18:59:42 2001 Andrew Cagney <cagney@redhat.com>
+
+ * hp-psymtab-read.c, hppah-nat.c, hppa-tdep.c: Fix -Wformat
+ problems.
+
+Tue Oct 23 14:16:10 2001 Andrew Cagney <cagney@redhat.com>
+
+ * somsolib.c (som_solib_add): Use core_addr_to_host_pointer.
+ (som_solib_desire_dynamic_linker_symbols): Compare integers with
+ zero not NULL.
+ * hp-psymtab-read.c (hpread_call_pxdb): Make parameter constant.
+
+2001-10-21 Andrew Cagney <ac131313@redhat.com>
+
+ * top.c (print_gdb_version): Do not print ``(MI_OUT)''. MI
+ interface is always enabled.
+
+2001-10-21 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in: Replace top.h with $(top_h). Replace expression.h
+ with $(expression_h). Replace command.h with $(command_h).
+ (language_h): Define. Replace language.h with $(language_h).
+ Replace call-cmds.h with $(call_cmds_h). Replace varobj.h with
+ $(varobj_h).
+ (wrapper_h, valprint_h, objfiles_h, complaints_h): Ditto.
+ (serial_h, hpread_h, buildsym_h, stabsread_h): Ditto.
+ (xcoffsolib_h, gdb_stabs_h, linespec_h): Ditto.
+ (bcache_h, gdb_events_h, monitor_h): Ditto.
+ (ser_unix_h, source_h): Ditto.
+ (varobj_h): Update list.
+
+ * call-cmds.h: Add CALL_CMDS_H macro wrapper.
+ * solist.h: Add SOLIST_H macro wrapper.
+ * monitor.h: Add MONITOR_H macro wrapper.
+ * typeprint.h: Add TYPEPRINT_H macro wrapper.
+ * xcoffsolib.h: Add XCOFFSOLIB_H macro wrapper.
+ * valprint.h: Add VALPRINT_H macro wrapper.
+ * top.h: Add TOP_H macro wrapper.
+
+2001-10-21 Andrew Cagney <ac131313@redhat.com>
+
+ * config/a29k/tm-vx29k.h, i386-tdep.c: Include "value.h".
+ * arm-tdep.c, exec.c, ia64-tdep.c, infrun.c: Ditto.
+ * ppc-linux-tdep.c, remote-es.c, remote.c: Ditto.
+ * rs6000-tdep.c, s390-tdep.c, x86-64-tdep.c: Ditto.
+ * Makefile.in (arm-tdep.o, exec.o, i386-tdep.o, ia64-tdep.o)
+ (infrun.o, ppc-linux-tdep.o, remote.o, rs6000-tdep.o)
+ (x86-64-tdep.o): Update dependencies.
+ * gdbarch.sh [!GDB_MULTI_ARCH]: Include "value.h".
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+2001-10-21 Mark Kettenis <kettenis@gnu.org>
+
+ * infptrace.c (child_xfer_memory): Fix a few coding standards
+ violations.
+
+2001-10-21 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/djgpp/README: Fix a typo and tweak for GDB 5.1.
+
+2001-10-20 Andrew Cagney <ac131313@redhat.com>
+
+ * jv-lang.h: Add #ifndef JV_LANG_H wrapper.
+ (struct value): Add opaque declaration. Replace value_ptr with
+ ``struct value *''.
+ * jv-valprint.c, jv-lang.c: Replace value_ptr with equivalent
+ struct.
+
+ * wrapper.h (struct value): Add opaque declaration. Replace
+ value_ptr with ``struct value *''.
+ * wrapper.c: Replace value_ptr with ``struct value *''.
+ * breakpoint.h, breakpoint.c: Ditto.
+ * cp-abi.h, hpacc-abi.c, gnu-v2-abi.c, cp-abi.c: Ditto.
+
+2001-10-20 Andrew Cagney <ac131313@redhat.com>
+
+ * alpha-nat.c: Include <alpha/coreregs.h> instead of
+ <machine/reg.h>.
+ (fetch_osf_core_registers): Define core_reg_mapping in a way that
+ works on OSF5 as well as previous OSF versions.
+
+2001-10-20 Christopher Faylor <cgf@redhat.com>
+
+ * win32-nat.c (handle_load_dll): Avoid strlwr'ing loaded DLLs or cygwin
+ may not be able to read them in certain situations.
+
+2001-10-18 Andrew Cagney <ac131313@redhat.com>
+
+ * config/powerpc/nbsd.mt (SIM_OBS, SIM): Define.
+ * config/powerpc/linux.mt (SIM, SIM_OBS): Ditto
+
+2001-10-18 Andrew Cagney <ac131313@redhat.com>
+
+ * README: Mention problems with HP/UX.
+
+2001-10-16 Andrew Cagney <ac131313@redhat.com>
+
+ Based on code by John Moore <jmore@redhat.com>:
+
+ * utils.c (core_addr_to_string): New function for conversion of
+ CORE_ADDR to string.
+ (string_to_core_addr): New function to convert from string to
+ CORE_ADDR.
+ * defs.h: Added extern statements for the above.
+
+2001-10-17 Jason Molenda (jason-cl@molenda.com)
+
+ * symtab.c (lookup_block_symbol): Break out of linear search
+ if we're past the range of possible matches.
+
+2001-10-16 Christopher Faylor <cgf@redhat.com>
+
+ * win32-nat.c (safe_symbol_file_add_stub): Improve logic for avoiding
+ load of already loaded DLL.
+ (register_loaded_dll): Convert loaded DLL name to "posix" format or it
+ will confuse subsequent opening of the filename due to dos paths.
+ (dll_symbol_command): Pass from_tty parameter to safe_symbol_file_add.
+
+2001-10-15 Elena Zannoni <ezannoni@redhat.com>
+
+ * symtab.c (lookup_block_symbol): Update comment.
+
+2001-10-15 Andrew Cagney <ac131313@redhat.com>
+
+ * value.h (value_as_address): Rename value_as_pointer.
+ * eval.c, findvar.c, gnu-v2-abi.c, gnu-v3-abi.c, jv-lang.c,
+ jv-valprint.c, printcmd.c, stack.c, top.c, valarith.c, valops.c,
+ values.c: Update.
+
+202001-10-15 Jim Ingham <jingham@inghji.apple.com>
+
+ * valarith.c (value_sub): Don't pass a raw type to
+ value_from_pointer, it has to go through check_typedef first.
+
+2001-10-15 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (fallbackdefault): Set to one when predefault is
+ empty.
+ * gdbarch.h: Regenerate.
+
+2001-10-15 Andrew Cagney <ac131313@redhat.com>
+
+ * mips-tdep.c (mips_integer_to_address): New function.
+ (mips_gdbarch_init): Initialize pointer_to_address,
+ address_to_pointer and integer_to_address.
+
+ * config/mips/tm-mips.h (POINTER_TO_ADDRESS): Delete
+ (ADDRESS_TO_POINTER): Delete.
+
+ * d10v-tdep.c (d10v_integer_to_address): New function.
+ (d10v_gdbarch_init): Initialize integer_to_address.
+
+ * values.c (value_as_pointer): Use INTEGER_TO_ADDRESS when
+ available.
+
+ * gdbarch.sh (INTEGER_TO_ADDRESS): New predicate and function.
+ * gdbarch.h, gdbarch.c: Regenerate.
+
+2001-10-14 Mark Kettenis <kettenis@gnu.org>
+
+ * config/s390/nm-linux.h: Don't include <signal.h>.
+ (lin_lwp_attach_lwp, ATTACH_LWP, lin_thread_get_thread_signals,
+ GET_THREAD_SIGNAL): Remove.
+
+ * config/nm-linux.h (struct objfile): Remove forward declaration.
+ (linuxthreads_new_objfile): Remove prototype.
+ (linuxthreads_pid_to_str): Remove prototype.
+ (PREPARE_TO_PROCEED): Redefine in terms of
+ lin_lwp_prepare_to_proceed.
+ (struct target_waitstatus): Forward declaration.
+ (child_wait): New prototype.
+ (CHILD_WAIT): Define.
+ (lin_lwp_attach_lwp, ATTACH_LWP, lin_thread_get_thread_signals,
+ GET_THREAD_SIGNAL): Moved here from arch-specific files.
+ * config/alpha/nm-linux.h, config/arm/nm-linux.h,
+ config/ia64/nm-linux.h, config/mips/nm-linux.h,
+ config/powerpc/nm-linux.h: Don't include <signal.h>.
+ (lin_lwp_attach_lwp, ATTACH_LWP, lin_thread_get_thread_signals,
+ GET_THREAD_SIGNAL): Remove.
+ * config/i386/nm-linux.h: Likewise.
+ (struct target_waitstatus, child_wait, CHILD_WAIT): Remove.
+ * config/m68k/linux.mh, config/sparc/linux.mh (NATDEPFILES):
+ Remove linux-thread.o. Add proc-service.o, thread-db.o and
+ lin-lwp.o.
+ (LOADLIBES): New variable.
+
+ * sparc-nat.c (fetch_core_registers): Remove redundant prototype.
+
+ * proc-service.c (BUILD_LWP): Redefine in terms of ptid_build.
+
+ Fix attaching to cloned processes. This fixes PR gdb/61.
+ * lin-lwp.c (struct lwp_info): Add new member `cloned'.
+ (is_cloned) Removed.
+ (lin_lwp_attach_lwp): Don't call stop_wait_callback. Instead call
+ waitpid explicitly. Mark the LWP as cloned if waitpid fails and
+ retry with __WCLONE flag.
+ (lin_lwp_attach): Likewise. Warn if attaching to a cloned process.
+ (detach_callback): Replace use of is_cloned with explicit check on
+ LWP id and process id.
+ (stop_wait_callback): Replace use of is_cloned with check if LWP
+ is marked as cloned.
+ [CHILD_WAIT] (child_wait): New function.
+ (lin_lwp_wait): Replace use of is_cloned with check if LWP is
+ marked as cloned. Mark newly detected LWPs as cloned if detected
+ by waitpid with __WCLONE flag.
+ (kill_wait_callback): Replace use of is_cloned with check if LWP
+ is marked as cloned.
+ * config/i386/nm-linux.h (struct target_waitstatus): Add forward
+ declaration.
+ (child_wait): Add prototype.
+ (CHILD_WAIT): Define.
+
+2001-10-13 Andrew Cagney <ac131313@redhat.com>
+
+ S/390 31 & 64 bit target and GNU/Linux native support.
+ Contributed by D.J. Barrow <djbarrow@de.ibm.com> of IBM.
+ * s390-nat.c, s390-tdep.c: New file.
+ * config/s390/nm-linux.h, config/s390/s390.mh: New file.
+ * config/s390/s390.mt, config/s390/s390x.mt: New file.
+ * config/s390/tm-linux.h, config/s390/tm-s390.h: New file.
+ * config/s390/xm-linux.h: New file.
+ * NEWS: Update.
+ * MAINTAINERS: Update.
+
+2001-10-13 Andrew Cagney <ac131313@redhat.com>
+
+ From 2001-07-09 D.J. Barrow <djbarrow@de.ibm.com>:
+ * gdbarch.sh: Fixed CALL_DUMMY_BREAKPOINT_OFFSET to check
+ CALL_DUMMY_BREAKPOINT_OFFSET_P.
+ * gdbarch.c: Regenerate.
+
+2001-10-13 Mark Kettenis <kettenis@gnu.org>
+
+ * thread-db.c: Fix a few formatting mistakes.
+
+2001-10-12 Christopher Faylor <cgf@redhat.com>
+
+ * win32-nat.c (safe_symbol_file_add_stub): Properly initialize linked
+ list pointer to beginning rather than one beyond beginning.
+
+2001-10-12 Daniel Jacobowitz <drow@mvista.com>
+
+ * symtab.h (struct block): (ALL_BLOCK_SYMBOLS): New macro.
+
+ * symtab.c (find_pc_sect_symtab): Use ALL_BLOCK_SYMBOLS.
+ (make_symbol_completion_list): Likewise.
+ (make_symbol_overload_list): Likewise.
+ * buildsym.c (finish_block): Likewise.
+ * breakpoint.c (get_catch_sals): Likewise.
+ * mdebugread.c (mylookup_symbol): Likewise.
+ * objfiles.c (objfile_relocate): Likewise.
+ * printcmd.c (print_frame_args): Likewise.
+ * stack.c (print_block_frame_locals): Likewise.
+ (print_block_frame_labels): Likewise.
+ (print_frame_arg_vars): Likewise.
+ * symmisc.c (dump_symtab): Likewise.
+ * tracepoint.c (add_local_symbols): Likewise.
+ (scope_info): Likewise.
+
+2001-10-12 Daniel Jacobowitz <drow@mvista.com>
+
+ * minsyms.c (msymbol_hash): Use better hash function.
+ (msymbol_hash_iw): Likewise. Terminate loop at '(' properly.
+
+ * objfiles.h: Increase MINIMAL_SYMBOL_HASH_SIZE to match modern
+ binaries.
+
+2001-10-12 Daniel Jacobowitz <drow@mvista.com>
+
+ * printcmd.c (print_frame_args): Move symbol iteration explicitly
+ inside the func != NULL block.
+
+2001-10-12 Fernando Nasser <fnasser@redhat.com>
+
+ * MAINTAINERS (Misc): Add Ian Roxborough as tcl/, tk/ and itcl/
+ maintainer.
+
+2001-10-12 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * config/i386/tm-cygwin.h: Include tm-i386.h instead of tm-i386v.h.
+ This fixes errors in "long long" handling for 'finish' and 'return'
+ commands.
+
+2001-10-12 Christopher Faylor <cgf@redhat.com>
+
+ * win32-nat.c (safe_symbol_file_add_stub): Avoid adding a shared
+ library if it has already been loaded.
+ (safe_symbol_file_add_cleanup): Don't mess with stderr or we won't see
+ any error messages.
+ (safe_symbol_file_add): Ditto.
+ (solib_symbols_add): Make static. Accept 'from_tty' parameter. Pass
+ it to safe_symbol_file_add.
+ (core_dll_symbols_add): Accomodate extra solib_symbols_add parameter.
+ (child_solib_add): Ditto.
+
+ * win32-nat.c (handle_exception): Don't print "first chance"
+ exceptions.
+ (get_child_debug_event): Continue from exceptions if !handle_exception.
+
+2001-10-11 Tom Tromey <tromey@redhat.com>
+
+ * symtab.c (lookup_symtab): Removed.
+ (lookup_symtab_1): Renamed to lookup_symtab.
+
+2001-10-10 Christopher Faylor <cgf@redhat.com>
+
+ * win32-nat.c (get_child_debug_event): Close file handles created after
+ process creation and DLL load.
+ (child_create_inferior): Close unneeded process/thread handle after
+ thread creation.
+
+2001-10-10 Jim Blandy <jimb@redhat.com>
+
+ * mn10300-tdep.c (mn10300_analyze_prologue): Doc fixes.
+
+2001-10-10 Keith Seitz <keiths@redhat.com>
+
+ * varobj.c (cplus_value_of_child): Deal with a failure
+ to dereference a pointer object.
+
+2001-10-08 J. Brobecker <brobecker@gnat.com>
+
+ * hpux-thread.c: rewrite find_active_thread() and find_tcb()
+ to use ptid_t, instead of overloading the thread and the pid
+ into the same 32-bit value. Make associated necessary adaptations.
+ Also remove unused variable cached_active_thread.
+
+2001-10-08 Nicholas Duffek <nsd@redhat.com>
+
+ * MAINTAINERS (powerpc, SCO/Unixware, Solaris/x86): Remove my
+ entries.
+
+2001-10-06 Mark Kettenis <kettenis@beast.freebsd.org>
+
+ * config/alpha/tm-fbsd.h (FRAME_CHAIN_VALID): Define.
+
+2001-10-04 Tom Tromey <tromey@redhat.com>
+
+ * main.c (enable_external_editor): Don't declare.
+ (captured_main): Don't set enable_external_editor.
+
+2001-10-02 Kevin Buettner <kevinb@redhat.com>
+
+ * Makefile.in (ALLDEPFILES): Add solib-svr4.c and solib-sunos.c
+ to this list.
+ (solib-sunos.o): Add dependencies.
+ (solib-svr4.o): Revise dependencies.
+ * solib-svr4.c: Remove SunOS shared library support.
+ * solib-sunos.c: New file, created from solib-svr4.c, which still
+ contains SunOS shared library support, but no SVR4 support.
+
+ * config/i386/nbsd.mh (NATDEPFILES): Remove solib-svr4.o and
+ solib-legacy.o from this list. Add solib-sunos.o.
+ * config/i386/sun386.mt (TDEPFILES): Likewise.
+ * config/m68k/nbsd.mh (NATDEPFILES): Likewise.
+ * config/m68k/sun2os4.mt (TDEPFILES): Likewise.
+ * config/m68k/sun3os4.mt (TDEPFILES): Likewise.
+ * config/ns32k/nbsd.mh (NATDEPFILES): Likewise.
+ * config/sparc/nbsd.mh (NATDEPFILES): Likewise.
+ * config/sparc/sun4os4.mt (TDEPFILES): Likewise.
+
+2001-10-01 Elena Zannoni <ezannoni@redhat.com>
+
+ * Makefile.in (mipsread.o): Remove old dependency on partial-stab.h.
+
+2001-10-01 Elena Zannoni <ezannoni@redhat.com>
+
+ * xcoffread.c (N_UNDF, N_ABS, N_TEXT, N_DATA, N_BSS, N_COMM, N_FN,
+ N_EXT, N_INDR, N_SETA, N_SETT, N_SETD, N_SETB, N_SETV,
+ CUR_SYMBOL_TYPE, CUR_SYMBOL_VALUE, START_PSYMTAB, END_PSYMTAB,
+ SET_NAMESTRING): Delete definitions.
+ Don't include language.h any more.
+ Don't include partial-stab.h any more.
+ (scan_xcoff_symtab): Don't jump through hoops to reuse code in
+ partial-stab.h, include the code directly, instead.
+
+ * Makefile.in (xcoffread.o): Remove dependency on partial-stab.h.
+
+2001-10-01 Andrew Cagney <ac131313@redhat.com>
+
+ * infcmd.c (do_registers_info): Delete code dumping large
+ registers. Handled by val_print.
+
+2001-09-30 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (gdbarch_alloc): Name the new architecture
+ ``current_gdbarch'' so that it, and not the identically named
+ global is refered to by macros.
+ * gdbarch.c: Regenerate.
+
+2001-09-29 Andrew Cagney <ac131313@redhat.com>
+
+ * cli/cli-decode.c (add_set_boolean_cmd): Define.
+ * cli/cli-decode.h (add_set_boolean_cmd): Declare.
+ * command.h (add_set_boolean_cmd): Ditto.
+ * remote.c (_initialize_remote): Use add_set_boolean_cmd for "set
+ remotebreak"
+
+2001-09-29 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (gdbarch_dump): Sort output.
+ * gdbarch.c: Regenerate.
+
+2001-09-29 Andrew Cagney <ac131313@redhat.com>
+
+ * rs6000-tdep.c (rs6000_gdbarch_init): Don't use the previous
+ architecture to infer the wordsize. Previous architecture may not
+ be a PowerPC.
+
+2001-09-27 J. Brobecker <brobecker@gnat.com>
+
+ * infttrace.c (kill_inferior): Issue a TT_PROC_EXIT request rather
+ than a TT_PROC_STOP request to kill the inferior and its child
+ processes. Otherwise, the inferior is not killed on HPUX 11.0.
+ Removed the code that detaches the child processes since we just
+ killed them.
+
+2001-09-26 Andrew Cagney <ac131313@redhat.com>
+
+ * serial.c (serial_set_cmdlist, serial_show_cmdlist): New
+ variables.
+ (serial_set_cmd, serial_show_cmd): New functions.
+ (_initialize_serial): Add "set/show serial" command.
+
+2001-09-26 Andrew Cagney <ac131313@redhat.com>
+
+ * CONTRIBUTE: Update.
+
+2001-09-26 Kevin Buettner <kevinb@redhat.com>
+
+ * solib-svr4.h (set_solib_svr4_fetch_link_map_offsets): Add
+ argument ``gdbarch''.
+ * solib-svr4.c (SVR4_FETCH_LINK_MAP_OFFSETS): Change default value.
+ (default_svr4_fetch_link_map_offsets): Rename to
+ legacy_fetch_link_map_offsets().
+ (svr4_fetch_link_map_offsets): New function.
+ (fetch_link_map_offsets, fetch_link_map_offsets_init): Deleted.
+ (fetch_link_map_offsets_gdbarch_data): New static global.
+ (set_solib_svr4_fetch_link_map_offsets): Add argument ``gdbarch''.
+ Revise to invoke set_gdbarch_data().
+ (init_fetch_link_map_offsets): Change return type and add an
+ argument so that it may be used as a gdbarch_data initializer.
+ (_initialize_svr4_solib): Eliminate use of gdbarch swap mechanism.
+ Use gdbarch data mechanism instead.
+
+2001-09-25 Jiri Smid <smid@suse.cz>
+
+ * x86-64-linux-tdep.c (LINUX_SIGINFO_SIZE): Add.
+ (x86_64_linux_sigcontext_addr): Replace `sizeof (struct siginfo)'
+ by LINUX_SIGINFO_SIZE.
+
+2001-09-24 Andrew Cagney <ac131313@redhat.com>
+
+ * maint.c (maintenance_set_cmdlist, maintenance_show_cmdlist): New
+ variables.
+ (maintenance_set_profile_cmd): New function.
+ (maintenance_show_cmd, maintenance_set_cmd): New functions.
+ (_initialize_maint_cmds): Add "maintenance set" and "maintenance
+ show" and, commented out, "maintenance set/show profile" commands.
+
+2001-09-24 Andrew Cagney <ac131313@redhat.com>
+
+ * findvar.c (read_var_value): For LOC_INDIRECT and LOC_REF_ARG
+ convert the pointer into a CORE_ADDRs.
+
+2001-09-24 Andrew Cagney <ac131313@redhat.com>
+
+ * doublest.h (store_floating, extract_floating): Add comment
+ indicating these functions are deprecated.
+ (extract_typed_floating, store_typed_floating): Declare.
+ * doublest.c: Include "gdbtypes.h".
+ (extract_typed_floating, store_typed_floating): Define.
+
+ * stabsread.c (define_symbol): Use store_typed_floating.
+ * valarith.c (value_binop): Ditto.
+ * values.c (unpack_long): Use extract_typed_floating.
+ (unpack_double): Ditto.
+
+2001-09-24 Orjan Friberg <orjanf@axis.com>
+
+ * cris-tdep.c (reg_mode_add_sub_cmp_and_or_move_op): Fetch operand1
+ from correct register.
+
+2001-09-22 Mark Kettenis <kettenis@gnu.org>
+
+ * x86-64-linux-tdep.c (STRUCT_OFFSET): Removed.
+
+2001-09-21 Jiri Smid <smid@suse.cz>
+
+ * config/i386/x86-64linux.mh: New file.
+ * config/i386/x86-64linux.mt: New file.
+ * config/i386/nm-x86_64.h: New file.
+ * x86-64-linux-tdep.c: New file.
+ * x86-64-linux-nat.c: New file.
+ * x86-64-tdep.c: New file.
+ * x86-64-tdep.h: New file.
+ * i386-tdep.h: New file.
+ * i387-nat.c: Include i386-tdep.h when multiarch.
+ * i387-tdep.c: Ditto.
+ * config/djgpp/fnchange.lst: Add entries for x86_64-linux-tdep.c
+ and x86_64-linux-nat.c
+ * Makefile.in: Add x86_64-linux-tdep.o, x86_64-tdep.o,
+ x86_64-linux-tdep.o, x86_64-nat.o, update dependencies.
+
+2001-09-21 Jiri Smid <smid@suse.cz>
+
+ * MAINTAINERS: Add myself to the write-after-approval list.
+ * i386-nat.c (TARGET_HAS_DR_LEN_8, DR_LEN_8): Declare.
+ (i386_length_and_rw_bits, i386_handle_nonaligned_watchpoint,
+ i386_insert_watchpoint, i386_remove_watchpoint): Add support for
+ 8-byte wide watchpoints.
+ (i386_show_dr): Debug message format string change.
+
+2001-09-21 Michael Snyder <msnyder@redhat.com>
+
+ * c-exp.y (typebase): Accept (signed long long) as a type expr.
+
+2001-09-20 Michael Snyder <msnyder@redhat.com>
+ Changes by Daniel Berlin <dan@cgsoftware.com>, to support
+ better parsing of const and volatile type expressions.
+ * c-exp.y (const_and_volatile, const_or_volatile_noopt,
+ const_or_volatile): New non-terminals.
+ (ptype): Use new rule for const_or_volatile.
+ (typebase): Use new rule for const_or_volatile_noopt.
+ * parser-defs.h (enum type_pieces): New values tp_const, tp_volatile.
+ * parse.c (follow_types): Handle tp_const and tp_volatile on the
+ type stack: call make_cv_type to create new const/volatile type.
+
+2001-09-20 Kevin Buettner <kevinb@redhat.com>
+
+ * solib-svr4.c (fetch_link_map_offsets): Add comment.
+ (fetch_link_map_offsets_init): New static global.
+ (set_solib_svr4_fetch_link_map_offsets, init_fetch_link_map_offsets):
+ Revise implementation to use ``fetch_link_map_offsets_init''
+ instead of ``fetch_link_map_offsets''.
+
+2001-09-20 Alan Modra <amodra@bigpond.net.au>
+
+ * coffread.c: Replace all occurrences of bfd_read with bfd_bread.
+ * dbxread.c: Likewise.
+ * dwarf2read.c: Likewise.
+ * dwarfread.c: Likewise.
+ * somread.c: Likewise.
+ * ultra3-nat.c: Likewise.
+ * xcoffread.c: Likewise.
+
+2001-09-19 Andrew Cagney <ac131313@redhat.com>
+
+ * cris-tdep.c (cris_get_signed_offset): Change return type to an
+ explicitly signed char.
+
+ * config/mcore/tm-mcore.h (mcore_virtual_frame_pointer): Update
+ function signature to match recent tracepoint.c:encode_actions
+ changes.
+ * mcore-tdep.c (mcore_virtual_frame_pointer): Ditto.
+
+2001-09-18 Andrew Cagney <ac131313@redhat.com>
+
+ * thread.c (do_captured_thread_select): Add uiout parameter.
+ (do_captured_list_thread_ids): Ditto.
+ * breakpoint.c (do_captured_breakpoint_query): Ditto.
+
+ * breakpoint.c (gdb_breakpoint_query): Update. Use
+ catch_exceptions.
+ * thread.c (gdb_list_thread_ids): Ditto.
+ (gdb_thread_select): Ditto.
+ (thread_command): Pass uiout to gdb_thread_select.
+
+ * gdb.h (gdb_breakpoint_query): Add parameter ui_out.
+ (gdb_thread_select, gdb_list_thread_ids): Ditto.
+
+2001-09-13 Kevin Buettner <kevinb@redhat.com>
+
+ From Ilya Golubev <gin@mo.msk.ru>:
+ * solib.c (clear_solib): Call `remove_target_sections' to fix
+ stale pointers in `struct target_ops'.
+ * irix5-nat.c (clear_solib): Likewise.
+ * osfsolib.c (clear_solib): Likewise.
+
+2001-09-13 Jim Blandy <jimb@redhat.com>
+
+ * monitor.c (monitor_load): Don't delete symtab users, or reset
+ inferior_ptid.
+
+ * monitor.c (monitor_load): Fix indentation.
+
+2001-09-11 Jim Blandy <jimb@redhat.com>
+
+ * printcmd.c (print_scalar_formatted): Compare the length of the
+ value against the lengths of the target's floating-point types,
+ not the host's. Add support for `long double'.
+
+ * printcmd.c (print_scalar_formatted): Fix indentation.
+
+2001-09-10 Jim Blandy <jimb@redhat.com>
+
+ * rom68k-rom.c (init_rom68k_cmds): Set the flag indicating that
+ programs running on the board can produce output.
+
+2001-09-10 Jason Molenda (jmolenda@apple.com)
+
+ * NEWS: "ANS/ISO C" -> "ISO C".
+ * MAINTAINERS (write-after-approval): Update my entry.
+
+2001-09-08 Mark Kettenis <kettenis@gnu.org>
+
+ * config/xm-aix4.h (MEM_FNS_DECLARED): Removed.
+
+ * config/arm/xm-linux.h, config/ia64/xm-linux.h,
+ config/m68k/xm-linux.h, config/mips/xm-linux.h,
+ config/powerpc/xm-linux.h, config/sparc/xm-linux.h: Remove
+ redundant inclusion of <unistd.h>.
+
+ * gdbtypes.h (struct block): Add forward declaration.
+
+2001-09-07 Andrew Cagney <ac131313@redhat.com>
+
+ * defs.h (enum return_reason): Renumber so that all values are
+ negative.
+ (RETURN_MASK): Negate reason.
+ (catch_exception_ftype): Declare.
+ (catch_exceptions): Declare.
+ * top.c (catcher): New function, based on catch_errors. Add in
+ parameter func_uiout and out parameters func_val, func_caught and
+ func_cleanup. Change type of func to catch_exceptions_ftype.
+ Save/restore uiout.
+ (struct catch_errors_args): Define.
+ (do_catch_errors): New function.
+ (catch_errors): Rewrite, use do_catch_errors and catcher.
+ (catch_exceptions): New function, use catcher.
+
+2001-09-07 Jim Blandy <jimb@redhat.com>
+
+ Correctly parse register values provided by the monitor.
+ * rom68k-rom.c: #include "value.h".
+ (is_hex_digit, hex_digit_value, is_whitespace,
+ rom68k_supply_one_register): New static functions.
+ (rom68k_supply_register): Call rom68k_supply_one_register, instead
+ of monitor_supply_register; the latter was incorrectly parsing
+ the values.
+ * Makefile.in (rom68k-rom.o): Note that this now #includes value.h.
+
+2001-09-07 Mark Kettenis <kettenis@gnu.org>
+
+ * config/rs6000/xm-rs6000.h (setpgrp): Remove macro. GDB defaults
+ to using setpgid if available now.
+
+2001-09-06 Keith Seitz <keiths@redhat.com>
+
+ From Ian Roxborough <irox@redhat.com>
+ * configure.in: Use ITCL_LIB_FULL_PATH and
+ ITK_LIB_FULL_PATH to set Itcl and Itk dependancies
+ for gdb.
+ * configure: Regenerated.
+
+2001-09-06 Kevin Buettner <kevinb@redhat.com>
+
+ * dbxread.c (process_one_symbol): Don't use error result from
+ find_stab_function_addr().
+ * partial-stab.h (case 'F'): Likewise.
+
+ * partial-stab.h (case 'f'): Make SOFUN_ADDRESS_MAYBE_MISSING
+ code match that used for case 'F'. This fixes the divergence
+ that was introduced by my 1999-09-14 changes to partial-stab.h.
+
+2001-09-05 Elena Zannoni <ezannoni@redhat.com>
+
+ * gdbarch.sh: Move include of dis-asm.h so it is generated earlier
+ in gdbarch.h.
+ (TARGET_PRINT_INSN): Multiarch.
+ * gdbarch.h: Regenerate.
+ * gdbarch.c: Regenerate.
+
+ * arch-utils.c (legacy_print_insn): New function.
+ * arch-utils.h (legacy_print_insn): Export.
+
+ * cris-tdep.c (cris_delayed_get_disassembler): Use
+ TARGET_PRINT_INSN, instead of tm_print_insn.
+ * d10v-tdep.c (print_insn): Ditto.
+ * d30v-tdep.c (print_insn): Ditto.
+ * m32r-tdep.c (dump_insn): Ditto.
+ * v850-tdep.c (v850_scan_prologue): Ditto.
+ * mcore-tdep.c (mcore_dump_insn): Ditto.
+ * sh-tdep.c (sh_gdbarch_init): Set print_insn gdbarch field.
+
+2001-09-05 Jim Blandy <jimb@redhat.com>
+
+ * gdbtypes.h (struct type): Doc fix.
+
+2001-09-04 Elena Zannoni <ezannoni@redhat.com>
+
+ From Daniel Jacobowitz <drow@mvista.com>
+ * dbxread.c (free_header_files): Make global.
+ (init_header_files): Likewise.
+ * stabsread.h (free_header_files): Add prototype.
+ (init_header_files): Likewise.
+ * mdebugread.c (mdebug_build_psymtabs): Initialize
+ properly before using the stabs debug reader.
+
+2001-09-04 Elena Zannoni <ezannoni@redhat.com>
+
+ From Daniel Jacobowitz <drow@mvista.com>
+ * dbxread.c (dbx_symfile_read): Only reinitialize
+ the psymbol list if mainline or if both static
+ and global lists are empty.
+ * dwarf2read.c (dwarf2_build_psymtabs): Likewise.
+ * dwarfread.c (dwarf_build_psymtabs): Likewise.
+ * xcoffread.c (xcoff_initial_scan): Likewise.
+ * os9kread.c (os9k_symfile_read): Likewise.
+
+2001-09-04 Elena Zannoni <ezannoni@redhat.com>
+
+ From Daniel Jacobowitz <drow@mvista.com>
+ * mdebugread.c (psymtab_to_symtab_1): Handle N_SO stabs without
+ a name specially.
+
+2001-09-01 Mark Kettenis <kettenis@gnu.org>
+
+ Make GDB use libiberty regex implementation.
+ * gdb_regex.h: Normalize protection against multiple inclusion.
+ Include "xregex.h" instead of "gnu-regex.h".
+ * cli/cli-cmds.c: Include "gdb_regex.h" instead of "gnu-regex.h".
+ * cli/cli-decode.c: Likewise.
+ * Makefile.in (REGEX): Remove.
+ (GDB_CFLAGS): Remove reference to gnu-regex.h in comment.
+ (ADD_FILES, ADD_DEPS): Remove $(REGEX).
+ (POSSLIBS): Remove.
+ (TAGFILES_NO_SRCDIR): Remove $(POSSLIBS).
+ (irix5-nat.o, solib.o, solib-svr4.o, source.o, symtab.o,
+ xcoffsolib.o, cli-decode.o, cli-cmd.o): Replace gnu-regex.h with
+ gdb_regex.h in list of dependencies.
+ (gnu-regex.o): Remove rule.
+ * gnu-regex.c, gnu-regex.h: Remove files.
+
+2001-08-31 Jason Molenda (jmolenda@apple.com)
+
+ * c-valprint.c (c_val_print): Second call to check_typedef ()
+ is no longer necessary.
+
+2001-08-31 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-tdep.c (examine_prologue): Don't let a branch unit nop
+ terminate the prologue scan.
+
+2001-08-30 Jim Blandy <jimb@redhat.com>
+
+ * symfile.c (sections_overlap): New function.
+ (map_overlay_command): Call sections_overlap, instead of using
+ incorrect logic to recognize overlapping sections.
+
+ * symfile.c (load_command): Invalidate the overlay cache.
+
+2001-08-30 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/xm-i386.h (HOST_BYTE_ORDER): Removed.
+
+2001-08-29 Kevin Buettner <kevinb@redhat.com>
+
+ From 2001-08-07 Daniel Jacobowitz <drow@mvista.com>:
+ * solib-svr4.c (enable_break): Check the inferior link map
+ before assuming the inferior PC is at the start of the dynamic
+ loader.
+
+2001-08-28 Andrew Cagney <cagney@toribio.toronto.redhat.com>
+
+ * frame.h (struct frame_info): Fix documentation on fields
+ saved_regs, next and prev.
+
+2001-08-23 Mark Kettenis <kettenis@gnu.org>
+
+ * event-top.c (async_stop_sig) [HAVE_SIGPROCMASK]: Some
+ gratuitious whitespace changes.
+ [!HAVE_SIGPROCMASK]: Call sigsetmask if HAVE_SIGSETMASK is defined.
+ * top.c: Remove redundant logic to define HAVE_SIGSETMASK.
+ (sigsetmask) Don't define macro.
+ (stop_sig) [HAVE_SIGPROCMASK]: Add bit of code snatched from
+ async_stop_sig from event-top.c.
+ [!HAVE_SIGPROCMASK]: Call sigsetmask if HAVE_SIGSETMASK is
+ defined.
+ * configure.in (AC_CHECK_FUNCS): Put functions in alphabetical
+ order. Add sigsetmask.
+ (AC_FUNC_VFORK, AC_FUNC_ALLOCA): Reorder such that they're in
+ alphabetical order.
+ * config/xm-aix4.h, config/alpha/xm-alphalinux.h,
+ config/i386/xm-cygwin.h, config/rs6000/xm-rs6000.h
+ (HAVE_SIGSETMASK): Remove.
+ * aclocal.m4, config.in, configure: Regenerated.
+
+2001-08-26 Andrew Cagney <ac131313@redhat.com>
+
+ From 2001-06-29 Andrew Cagney <ac131313@redhat.com>:
+ * config/powerpc/nbsd.mh (XM_FILE): Delete.
+
+2001-08-21 Andrew Cagney <ac131313@redhat.com>
+
+ * doublest.h (HOST_FLOAT_FORMAT): Delete macro.
+ (HOST_DOUBLE_FORMAT): Delete macro.
+
+2001-08-24 Mark Kettenis <kettenis@gnu.org>
+
+ * config/xm-lynx.h, config/xm-nbsd.h, config/xm-sysv4.h,
+ config/i386/xm-i386aix.h, config/m68k/xm-dpx2.h: Remove redundant
+ inclusion of <limits.h>.
+
+2001-08-24 Andrew Cagney <ac131313@redhat.com>
+
+ * regcache.c (read_register_bytes): When REGISTER_NAME indicates
+ that a register should be ignored, supply a value for the register
+ from the raw registers[] buffer.
+
+2001-08-24 Andrew Cagney <ac131313@redhat.com>
+
+ * go32-nat.c (go32_create_inferior): Use xfree instead of free.
+ * config/djgpp/fnchange.lst: Add entries for i386bsd-tdep.c and
+ i386bsd-nat.c.
+
+2001-08-21 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbtypes.h (builtin_type_ieee_single_big)
+ (builtin_type_ieee_single_little, builtin_type_ieee_double_big)
+ (builtin_type_ieee_double_little)
+ (builtin_type_ieee_double_littlebyte_bigword)
+ (builtin_type_i387_ext, builtin_type_m68881_ext)
+ (builtin_type_i960_ext, builtin_type_m88110_ext)
+ (builtin_type_m88110_harris_ext, builtin_type_arm_ext_big)
+ (builtin_type_arm_ext_littlebyte_bigword)
+ (builtin_type_ia64_spill_big, builtin_type_ia64_spill_little)
+ (builtin_type_ia64_quad_big)
+ (builtin_type_ia64_quad_little): Declare.
+ * gdbtypes.c (builtin_type_ieee_single_big)
+ (builtin_type_ieee_single_little, builtin_type_ieee_double_big)
+ (builtin_type_ieee_double_little)
+ (builtin_type_ieee_double_littlebyte_bigword)
+ (builtin_type_i387_ext, builtin_type_m68881_ext)
+ (builtin_type_i960_ext, builtin_type_m88110_ext)
+ (builtin_type_m88110_harris_ext, builtin_type_arm_ext_big)
+ (builtin_type_arm_ext_littlebyte_bigword)
+ (builtin_type_ia64_spill_big, builtin_type_ia64_spill_little)
+ (builtin_type_ia64_quad_big)
+ (builtin_type_ia64_quad_little): Define.
+ (_initialize_gdbtypes): Initialize builtin floatformat types.
+
+2001-08-23 Mark Kettenis <kettenis@gnu.org>
+
+ * tracepoint.c (read_actions): Add FIXME for code depending on
+ STOP_SIGNAL.
+
+2001-08-23 Martin M. Hunt <hunt@redhat.com>
+
+ * remote-mips.c (pmon_load_fast): Add ui_load_progress_hook
+ to download loop.
+ (mips_load_srec): Ditto.
+
+2001-08-22 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbtypes.c (build_gdbtypes): Initialize TYPE_FLOATFORMAT field
+ of builtin_type_float, builtin_type_double and
+ builtin_type_long_double.
+ (recursive_dump_type): Print the floatformat name.
+ * gdbtypes.h (struct type): Add type_specific field floatformat.
+ (TYPE_FLOATFORMAT): Define
+
+2001-08-21 Keith Seitz <keiths@redhat.com>
+
+ * printcmd.c (print_insn): Use the given stream for
+ output.
+
+2001-07-24 Andrew Cagney <ac131313@redhat.com>
+
+ * arm-tdep.c (convert_from_extended, convert_to_extended): Delete
+ assembler version of function.
+ (convert_from_extended, convert_to_extended): Rewrite. Use
+ floatformat_to_doublest, floatformat_from_doublest,
+ floatformat_arm_ext_big, floatformat_arm_ext_littlebyte_bigword.
+ (arm_push_arguments): Use extract_floating and store_floating to
+ perform floating point conversions.
+ (SWAP_TARGET_AND_HOST): Delete macro.
+ * arm-linux-tdep.c (arm_linux_push_arguments): Use
+ extract_floating and store_floating to perform floating point
+ conversions.
+
+2001-08-20 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbtypes.h (struct type): Clarify meaning of field ``length''.
+
+2001-08-17 Keith Seitz <keiths@redhat.com>
+
+ * varobj.c (varobj_update): Change first parameter to
+ pointer to struct varobj*. This function can delete
+ varobjs, so we need to give callers the new varobj
+ when this happens.
+ (value_of_root): Update "var", too, if "var_handle"
+ changes.
+ * varobj.h (varobj_update): Likewise.
+
+2001-08-17 Keith Seitz <keiths@redhat.com>
+
+ * Makefile.in (varobj_h): Define.
+ (mi-cmd-var.o): Depends on varobj_h.
+ (gdbtk-varobj.o): Change varobj.h to $(varobj_h).
+
+2001-08-16 Keith Seitz <keiths@redhat.com>
+
+ * configure.in (GDBTK_SRC_DIR): We must have autoconf
+ give us the absolute path to the source directory.
+ * configure: Regenerated.
+ * Makefile.in (GDBTK_SRC_DIR): Add variable so that
+ autoconf can substitue it in for us.
+ (gdbtk.o): Pass in GDBTK_SRC_DIR instead of srcdir. We
+ really do need an absolute pathname.
+
+2001-08-15 Keith Seitz <keiths@redhat.com>
+
+ * Makefile.in (GDBTK_VERSION): Set a version number.
+ (GDBTK_LIBRARY): New variable to point to location where
+ gdbtk will install its tcl library. Changed all refereneces
+ to $(datadir)/insight1.0 to $(GDBTK_LIBRARY).
+ (SUBDIR_GDBTK_ALL): Remove "all-gdbtk". No longer needed.
+ (SUBDIR_GDBTK_CLEAN): Remove "clean-gdbtk". No longer needed.
+ (all-gdbtk): Remove.
+ (install-gdbtk): Remove.
+ (gdbtk.o): Pass srcdir to file when compiling.
+
+2001-08-15 Ian Roxborough <irox@redhat.com>
+
+ * Makefile.in: Changed all references to the install directory
+ "gdbtcl" to read "insight1.0".
+
+2001-08-15 Corinna Vinschen <vinschen@redhat.com>
+
+ * arch-utils.c (generic_skip_trampoline_code): New function.
+ * arch-utils.h (generic_skip_trampoline_code): Declare external.
+ * gdbarch.c: Regeberated from gdbarch.sh.
+ * gdbarch.h: Ditto.
+ * gdbarch.sh (SKIP_TRAMPOLINE_CODE): Multi-arch.
+ * infrun.c: Remove default setting of SKIP_TRAMPOLINE_CODE macro.
+
+2001-08-14 Daniel Jacobowitz <drow@mvista.com>
+ H.J. Lu (hjl@gnu.org)
+
+ * partial-stab.h: valu should be a CORE_ADDR.
+
+2001-08-14 H.J. Lu (hjl@gnu.org)
+
+ * dbxread.c (SWAP_SYMBOL): Removed.
+ (INTERNALIZE_SYMBOL): Check sign extended vma.
+
+2001-08-13 Christopher Faylor <cgf@cygnus.com>
+
+ * top.c (SIGSETJMP): Protect env argument with parentheses.
+ (SIGLONGJMP): Protect env argument with parentheses.
+
+2001-08-11 Andrew Cagney <ac131313@redhat.com>
+
+ * config/mn10300/mn10300.mt (TM_FILE): Delete.
+ * configure.tgt: Add mn10300 to list of mulit-arch targets.
+ * config/mn10300/tm-mn10300.h: Delete file. Move contents ...
+ * mn10300-tdep.c: To here.
+
+2001-08-11 Andrew Cagney <ac131313@redhat.com>
+
+ * config/i386/tm-symmetry.h (REGISTER_CONVERT_TO_VIRTUAL): Make
+ val a DOUBLEST. Use floatformat_to_doublest.
+ (REGISTER_CONVERT_TO_RAW): Ditto. Use foatformat_from_doublest.
+ * config/m88k/tm-m88k.h (REGISTER_CONVERT_TO_VIRTUAL): Ditto.
+ (REGISTER_CONVERT_TO_RAW): Ditto.
+
+2001-08-11 Andrew Cagney <ac131313@redhat.com>
+
+ * config/mn10300/tm-mn10300.h (PC_REGNUM, SP_REGNUM): Delete.
+ * mn10300-tdep.c (mn10300_gdbarch_init): Initialize pc_regnum and
+ sp_regnum.
+
+2001-08-11 Andrew Cagney <ac131313@redhat.com>
+
+ * doublest.c (convert_doublest_to_floatformat): Rename
+ floatformat_from_doublest. Make static.
+ (convert_floatformat_to_doublest): Rename floatformat_to_doublest.
+ Make static.
+ (floatformat_to_doublest): New function.
+ (floatformat_from_doublest): New function.
+ (host_float_format, host_double_format, host_long_double_format):
+ New static variables.
+ (store_floating, extract_floating): Always use
+ floatformat_to_doublest and floatformat_from_doublest.
+ * doublest.h (HOST_LONG_DOUBLE_FORMAT): Delete macro.
+
+2001-08-11 Andrew Cagney <ac131313@redhat.com>
+
+ * config/mn10300/tm-mn10300.h (INIT_FRAME_PC): Delete.
+ * mn10300-tdep.c (mn10300_gdbarch_init): Initialize init_frame_pc.
+
+2001-08-07 Andrew Cagney <ac131313@redhat.com>
+
+ * target.h (TARGET_VIRTUAL_FRAME_POINTER): Delete, multi-arched.
+ * gdbarch.sh (TARGET_VIRTUAL_FRAME_POINTER): Add.
+ * gdbarch.h, gdbarch.c: Regenerate.
+
+ * arch-utils.h (legacy_virtual_frame_pointer): Declare.
+ * arch-utils.c: Include "gdb_assert.h".
+ (legacy_virtual_frame_pointer): Define.
+ * Makefile.in (arch-utils.o): Depends on gdb_assert.h.
+
+ * tracepoint.c (encode_actions): Make frame_reg an int. Make
+ frame_offset a LONGEST.
+ * ax-gdb.c (gen_frame_args_address): Ditto.
+ (gen_frame_locals_address): Ditto.
+ * mn10300-tdep.c (mn10300_gdbarch_init): Initialize
+ virtual_frame_pointer.
+ (mn10300_virtual_frame_pointer): Make static. Update parameter
+ list to match function signature.
+ * config/mn10300/tm-mn10300.h (TARGET_VIRTUAL_FRAME_POINTER): Delete.
+
+2001-08-10 Keith Seitz <keiths@redhat.com>
+
+ * gdb-events.sh: Add architecture_changed event.
+ * gdbarch.sh: Include gdb-event.h.
+ (gdbarch_update_p): Notify UIs when architecture changes.
+ * gdb-events.h: Regenerated.
+ * gdb-events.c: Regenerated.
+ * gdbarch.c: Regenerated.
+
+2001-08-10 Michael Snyder <msnyder@redhat.com>
+
+ * regcache.c (legacy_write_register_gen): Don't 'optimize out'
+ a write_register to a pseudo-reg. Target_store_pseudo_register
+ needs to get called, because these regs may be computed and may
+ have side-effects.
+
+2001-08-10 Keith Seitz <keiths@redhat.com>
+
+ * gdb-events.sh: Deal with event notifications with no
+ arguments.
+
+2001-08-10 Orjan Friberg <orjanf@axis.com>
+
+ * remote.c (read_frame): Correct off-by-one error in condition.
+
+2001-08-08 Don Howard <dhoward@redhat.com>
+
+ * stabsread.c (read_type): Add support for const and volatile
+ modifiers.
+
+2001-08-02 Daniel Jacobowitz <drow@mvista.com>
+
+ * core-regset.c (fetch_core_registers): Remove HAVE_GREGSET_T
+ and HAVE_FPREGSET_T checks. Use gdb_gregset_t and gdb_fpregset_t.
+
+2001-08-02 Keith Seitz <keiths@redhat.com>
+
+ * defs.h (SLASH_STRING): If not defined, set
+ to "/", regardless of _WIN32, __CYGWIN__, or
+ whatnot.
+
+2001-08-02 Mark Kettenis <kettenis@gnu.org>
+
+ * cli/cli-decode.h: Include "gdb_regex.h" instead of
+ "gnu-regex.h".
+
+ * NEWS: Update.
+
+2001-08-02 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/i386/xm-go32.h: Include xm-i386.h.
+ (HOST_BYTE_ORDER, HOST_LONG_DOUBLE_FORMAT): Remove definitions.
+
+2001-08-02 Eli Zaretskii <eliz@is.elta.co.il>
+
+ The following changes avoid polluting global namespace with the
+ `enable' and `disable' identifiers, because some platforms define
+ in their system headers symbols with global scope that go by those
+ names.
+
+ * breakpoint.h (enum enable_state): Rename from `enum enable'.
+ Also rename all the enum members to have the "bp_" prefix.
+ (struct breakpoint): Rename the `enable' member to `enable_state'.
+ (enum bpdisp): Rename all members to have the "disp_" prefix.
+
+ * breakpoint.c: All users of `enum enable' and `enum bpdisp'
+ changed.
+ (args_for_catchpoint_enable): Rename the `enable' member to
+ `enable_p'. All users changed.
+
+ * tracepoint.h (enum enable): Remove.
+ (struct tracepoint): The member `enabled' is now `int enabled_p'.
+
+ * tracepoint.c: All users of the `enabled' member changed.
+
+ * printcmd.c (struct display): The `status' member is now an int.
+
+ * memattr.h (struct mem_region): Rename the `status' member to
+ `enabled_p'.
+ (enum enable): Remove.
+
+ * memattr.c: Change all users of the `status' member of struct
+ mem_region to use `enabled_p' instead.
+
+ * infcmd.c (run_stack_dummy): Use disp_del instead of del.
+
+ * go32-nat.c: Remove the kludgey work-around for conflicts between
+ <dos.h> and "breakpoint.h".
+
+2001-08-02 Corinna Vinschen <vinschen@redhat.com>
+
+ * MAINTAINERS: Add myself to the write-after-approval list.
+ * ser-tcp.c (tcp_open): Use `localhost' as default host if no
+ hostname is given.
+
+2001-08-01 Andrew Cagney <ac131313@redhat.com>
+
+ * doublest.h (store_floating, floatformat_to_doublest): Make IN
+ paramter a const void pointer.
+ (floatformat_from_doublest): Make IN const, Make OUT a void
+ pointer.
+ * doublest.c (floatformat_to_doublest): Update.
+ (floatformat_from_doublest): Update.
+ (extract_floating): Update.
+
+2001-07-31 Andrew Cagney <ac131313@redhat.com>
+
+ * defs.h (HOST_FLOAT_FORMAT, HOST_DOUBLE_FORMAT)
+ (HOST_FLOAT_FORMAT, HOST_DOUBLE_FORMAT)
+ (HOST_LONG_DOUBLE_FORMAT, DOUBLEST)
+ (floatformat_to_doublest, floatformat_from_doublest)
+ (floatformat_is_negative, floatformat_is_nan)
+ (floatformat_mantissa, store_floating)
+ (extract_floating): Move declaration from here.
+ * doublest.h: To here. New file.
+ * utils.c (get_field, floatformat_to_doublest, put_field)
+ (ldfrexp, floatformat_from_doublest, floatformat_is_negative)
+ (floatformat_is_nan, floatformat_mantissa)
+ (FLOATFORMAT_CHAR_BIT): Move from here.
+ * doublest.c: To here. New file.
+ * findvar.c (store_floating, extract_floating): Move from here.
+ * doublest.c: To here.
+ * Makefile.in (SFILES): Add doublest.c.
+ (COMMON_OBS): Add doublest.o.
+ (doublest.o): Specify dependencies.
+ (doublest_h): Define.
+
+ * config/m88k/tm-m88k.h: Include "doublest.h".
+ * config/i960/tm-i960.h: Ditto.
+ * config/i386/tm-symmetry.h: Ditto.
+ * rs6000-tdep.c, valarith.c: Ditto.
+ * valprint.c, stabsread.c, sh-tdep.c: Ditto.
+ * ia64-tdep.c, i387-tdep.c, i386-tdep.c: Ditto.
+ * values.c, arm-tdep.c, arm-linux-tdep.c: Ditto.
+ * alpha-tdep.c, ax.h, expression.h: Ditto.
+ * sh-tdep.c, parse.c, top.c, value.h: Ditto.
+
+ * Makefile.in (arm-tdep.o): Add $(doublest_h).
+ (i386-tdep.o, i387-tdep.o, ia64-tdep.o): Ditto.
+ (rs6000-tdep.o, stabsread.o, valarith.o): Ditto.
+ (values.o, valprint.o, arm-linux-tdep.o): Ditto.
+ (alpha-tdep.o, ax_h, parse.o, top.o, value_h): Ditto.
+ (parser_defs_h): Ditto.
+ (expression_h): Add $(doublest_h) and $(symtab_h).
+
+2001-08-01 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in: Sort header definitions.
+ (parser_defs_h, dis_asm_h, annotate_h, gdbthread_h): Define.
+ Replace parser-defs.h with $(parser_defs_h). Replace $(dis-asm_h)
+ and $(dis-asm.h) with $(dis_asm_h). Replace annotate.h with
+ $(annotate_h). Replace target.h with $(target_h). Replace
+ gdbthread.h with $(gdb_thread_h). Replace symfile.h with $(symfile_h).
+
+2001-07-31 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/xm-i386.h: New file.
+ * config/i386/xm-fbsd.h: Removed.
+ * config/i386/xm-linux.h: Removed.
+ * config/i386/fbsd.mh: Reorganize a bit.
+ (XM_FILE): Set to xm-i386.h instead of xm-fbsd.h.
+ * config/i386/linux.mh (XM_FILE): Set to xm-i386.h insread of
+ xm-linux.h.
+
+2001-07-30 Jim Blandy <jimb@redhat.com>
+
+ * dwarf2read.c (dwarf2_build_psymtabs_hard): Doc fix.
+
+2001-07-27 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure.in: Only invoke AC_FUNC_SETPGRP if not cross-compiling.
+ Check for SETPGRP_VOID separately if cross-compiling and ISO C
+ headers are available.
+
+2001-07-30 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-i386sol2.h (STAB_REG_TO_REGNUM): Redefine to call
+ i386_dwarf_reg_to_regnum.
+
+ * i386-tdep.c (i386_register_convert_to_virtual): Replace
+ assertion with a warning if we're asked to convert towards a
+ non-floating-point type. Zero out the the buffer where the data
+ is supposed to be stored in that case.
+
+2001-07-29 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/djgpp/djconfig.sh: Unset CDPATH.
+
+ * go32-nat.c (get_cr3): Temporary disable support for page tables
+ in UMBs, as it is incomplete.
+
+ Support for stepping through longjmp in DJGPP programs:
+
+ * config/i386/tm-go32.h (JB_ELEMENT_SIZE, JB_PC): New macros.
+ (GET_LONGJMP_TARGET): Define to call get_longjmp_target.
+ (get_longjmp_target): Add prototype.
+
+2001-07-28 Andrew Cagney <ac131313@redhat.com>
+
+ Fix some PID/TPID fallout for HP/UX.
+ From 2001-07-22 Rodney Brown <rbrown64@csc.com.au>:
+ * infttrace.c (ptrace_wait): Match external declaration,
+ and match target_post_wait declaration.
+
+2001-07-28 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Add Orjan Friberg as cris target maintainer.
+ (cris): Set --enable-gdb-build-warnings flag to -w.
+
+2001-07-28 Andrew Cagney <ac131313@redhat.com>
+
+ From 2001-07-23 Andreas Schwab <schwab@suse.de>:
+ * config/m68k/tm-m68k.h (TARGET_LONG_DOUBLE_FORMAT): Define.
+ (TARGET_LONG_DOUBLE_BIT): Define.
+ (REGISTER_VIRTUAL_SIZE): Return 12 for floating point registers.
+ (MAX_REGISTER_VIRTUAL_SIZE): Increase to 12.
+ (REGISTER_VIRTUAL_TYPE): Return builtin_type_long_double for
+ floating point registers.
+ (REGISTER_CONVERTIBLE, REGISTER_CONVERT_TO_VIRTUAL)
+ (REGISTER_CONVERT_TO_RAW): Remove.
+ * config/m68k/xm-linux.h (HOST_LONG_DOUBLE_FORMAT): Define.
+
+2001-07-26 Andrew Cagney <ac131313@redhat.com>
+
+ * thread.c, breakpoint.c: Include "gdb.h".
+ * Makefile.in (gdb_h): Define.
+ (HFILES_NO_SRCDIR): Add gdb.h.
+ (mi-cmd-break.o, mi-main.o, thread.o)
+ (breakpoint.o): Add dependency on $(gdb_h).
+
+ * defs.h (enum gdb_rc, gdb_breakpoint_query)
+ (gdb_breakpoint, gdb_thread_select)
+ (gdb_list_thread_ids): Move declaration from here ...
+ * gdb.h: To here. New file.
+
+2001-07-28 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * Makefile.in (SUBDIR_TUI_OBS): Add tui-out.o, tui-hooks.o.
+ (SUBDIR_TUI_SRCS): Add tui-out.c tui-hooks.c
+ (SFILES): Likewise.
+ (tui-out.o): Define dependencies.
+ (tui-hooks.o): Likewise.
+
+2001-07-28 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Update e-mail address of active @cygnus.com
+ maintainers to @redhat.com.
+
+2001-07-28 Andrew Cagney <ac131313@redhat.com>
+
+ * README (Known bugs): Delete section.
+ (Kernel debugging): Delete section.
+ (Languages other than C): Delete section.
+ (Host/target specific installation notes) New section.
+
+2001-07-28 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-i386.h (STAB_REG_TO_REGNUM, SDB_REG_TO_REGNUM,
+ DWARF_REG_TO_REGNUM, DWARF2_REG_TO_REGNUM): New defines.
+ (i386_stab_reg_to_regnum, i386_dwarf_reg_to_regnum): New
+ prototypes.
+ * config/i386/tm-fbsd.h, config/i386/tm-i386gnu.h,
+ config/i386/tm-linux.h (STAB_REG_TO_REGNUM): Redefine to call
+ i386_dwarf_reg_to_regnum.
+ * i386-tdep.c (i386_stab_reg_to_regnum, i386_dwarf_reg_to_regnum):
+ New functions.
+
+ * i386-tdep.c: Include "gdb_assert.h"
+ (i386_register_convert_to_virtual): Fix such that it can handle
+ conversion to any floating-point type. Assert that we are dealing
+ with a floating-point first.
+ (i386_register_convert_to_raw): Assert that TYPE is a
+ floating-point type with length 12.
+
+2001-07-27 John R. Moore <jmoore@redhat.com>
+
+ * configure.in: Added dependency of gdb on tcl/tk libraries.
+ * Makefile.in: Likewise.
+ * configure: Regenerated with the above using autoconf.
+
+2001-07-26 Elena Zannoni <ezannoni@redhat.com>
+
+ * sh-tdep.c (sh_gdbarch_init): Use SH_DEFAULT_NUM_REGS instead of
+ NUM_REGS.
+ (SH_DEFAULT_NUM_REGS): Define.
+
+2001-07-26 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c (read_memory_region): Make sure the segment limit was
+ indeed set, to work around a Windows 2000 bug.
+
+2001-07-25 Daniel Jacobowitz <drow@mvista.com>
+
+ * infptrace.c (child_xfer_memory): Add cast to CORE_ADDR.
+ * infttrace.c (child_xfer_memory): Likewise.
+ * symm-nat.c (child_xfer_memory): Likewise.
+ * gdbserver/low-hppabsd.c (read_inferior_memory): Likewise.
+ (write_inferior_memory): Likewise.
+ * gdbserver/low-linux.c (read_inferior_memory): Likewise.
+ (write_inferior_memory): Likewise.
+ * gdbserver/low-lynx.c (read_inferior_memory): Likewise.
+ (write_inferior_memory): Likewise.
+ * gdbserver/low-nbsd.c (read_inferior_memory): Likewise.
+ (write_inferior_memory): Likewise.
+ * gdbserver/low-sparc.c (read_inferior_memory): Likewise.
+ (write_inferior_memory): Likewise.
+ * gdbserver/low-sun3.c (read_inferior_memory): Likewise.
+ (write_inferior_memory): Likewise.
+
+2001-07-25 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * README: Mention how to make gdb.pdf.
+
+ * NEWS: Update.
+
+2001-07-24 Stephen P. Smith <ischis2@home.com>
+
+ * MAINTAINERS (Stephen P. Smith): Added to write after approval
+ list.
+
+2001-07-23 Andrew Cagney <ac131313@redhat.com>
+
+ * mips-tdep.c (mips_push_arguments): Add comment explaining
+ problem with LE o32 GCC.
+
+2001-07-23 Elena Zannoni <ezannoni@redhat.com>
+
+ * config/powerpc/aix.mh (MH_LDFLAGS): Don't set these, the Gnu linker
+ doesn't understand them.
+
+2001-07-23 Elena Zannoni <ezannoni@redhat.com>
+
+ * memattr.c (mem_info_command): Reformat output to look more like
+ 'info break' output.
+ (_initialize_mem): Improve help.
+
+2001-07-23 Mark Kettenis <kettenis@gnu.org>
+
+ * configure.in (AC_CHECK_FUNCS): Add setpggrp.
+ (AC_FUNC_SETPGRP): Add.
+ * aclocal.m4, configure, config.in: Regenerated.
+ * inflow.c (gdb_setpgid): Get rid of NEED_POSIX_SETPGID and
+ SETPGRP_ARGS. Always use setpgid if it is available, fall back on
+ setpgrp if it isn't. Use SETPGRP_VOID (defined by autoconf) to
+ distinguish between the two setpgrp flavours.
+ * config/xm-sysv4.h, config/arm/xm-linux.h,
+ config/i386/xm-i386aix.h, config/i386/xm-sco.h,
+ config/i386/xm-linux.h, config/i386/xm-ptx.h,
+ config/m68k/xm-linux.h, config/powerpc/xm-linux.h,
+ config/sparc/xm-linux.h, config/sparc/xm-sun4sol2.h,
+ config/ia64/xm-linux.h (NEED_POSIX_SETPGID): Remove.
+ * config/rs6000/xm-rs6000.h (SETPGRP_ARGS): Remove.
+
+2001-07-23 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c (read_memory_region): Set the granularity bit of the
+ allocated segment according to its size, and adjust the limit to
+ be page-aligned if the segment is page-granular.
+
+ * (get_cr3, get_pde, get_pte, display_ptable_entry, go32_pde)
+ (display_page_table, go32_pte, go32_pte_for_address): New functions.
+ (_initialize_go32_nat): Initialize and document them.
+
+2001-07-22 Mark Kettenis <kettenis@gnu.org>
+
+ * i386gnu-nat.c: Include "i387-nat.h".
+ (struct env387): Removed.
+ (reg_offset): Fix comment.
+ (fetch_fpregs): Use FCTRL_REGNUM and FOP_REGNUM instead of
+ FIRST_FPU_CONTROL_REGNUM and LAST_FPU_CONTROL_REGNUM. Rewrite to
+ use i387_supply_fsave.
+ (gnu_fetch_registers): Remove spurious whitespace.
+ (convert_to_env387): Remove.
+ (store_fpregs): Add argument regno. Use i387_fill_fsave instead
+ of convert_to_env387.
+ (gnu_store_registers): Remove spurious whitespace. Pass REGNO to
+ store_fpregs.
+ * config/i386/i386gnu.mt (TDEPFILES): Add i387-tdep.o.
+ * config/i386/i386gnu.mh (XDEPFILES): Remove i387-tdep.o.
+ (NATDEPFILES): Add i387-nat.o.
+
+2001-07-22 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * Makefile.in (ALLDEPFILES): Add m68hc11-tdep.c.
+ (m68hc11-tdep.o): Define dependencies.
+
+2001-07-22 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * m68hc11-tdep.c (m68hc11_gdbarch_init): Define int at 16-bits.
+
+2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * utils.c (init_page_info): Use tui_get_command_dimension.
+ * printcmd.c (disassemble_command): Simplify tui specific code,
+ use tui_is_window_visible, tui_show_assembly.
+
+2001-07-21 Mark Kettenis <kettenis@gnu.org>
+
+ * i386bsd-nat.c: Do not include <sys/sysctl.h>.
+ (_initialize_i386bsd_nat) [KERN_PS_STRINGS]: Move FreeBSD-specific
+ code to ...
+ * i386fbsd-nat.c: ... here. New file.
+ * config/i386/fbsd.mh (NATDEPFILES): Add i386-fbsd.o.
+ * config/i386/nm-fbsd.h (CHILD_RESUME): Define.
+ * Makefile.in (ALLDEPFILES): Add i386fbsd-nat.c.
+ (i386fbsd-nat.o): Add dependencies.
+
+2001-07-19 Daniel Jacobowitz <drow@mvista.com>
+
+ * signals.c: New file.
+ * Makefile.in: Add signals.o.
+ * target.c (struct signals, target_signal_to_name)
+ (target_signal_from_name, target_signal_from_host)
+ (do_target_signal_to_host, target_signal_to_host_p)
+ (target_signal_to_host, target_signal_from_command): Move to
+ signals.c.
+ (initialize_targets): Move check of struct signals to...
+ * signals.c (_initialize_signals): Here.
+
+2001-07-19 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Add Michael Chastain as C++ testsuite maintainer.
+
+2001-07-19 Andrew Cagney <ac131313@redhat.com>
+
+ From Stephen Smith:
+ * configure.tgt (i*86-*-pe*): New target.
+
+2001-07-19 Andrew Cagney <ac131313@redhat.com>
+
+ From 2001-07-16 Rodney Brown <rbrown64@csc.com.au>:
+ * infttrace.c (child_thread_alive): Fix gdb_tid typo.
+ * somsolib.c (no_shared_libraries): Provide stub.
+ * xcoffsolib.c (no_shared_libraries): Provide stub.
+
+2001-07-18 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * Makefile.in (COMMON_OBS): Remove tui-file.o.
+ (SUBDIR_TUI_OBS): Add it here.
+ (SUBDIR_TUI_SRCS): Move tui-file.c and tui-file.h here.
+ (main.o): Remove dependency with tui-file.h.
+
+2001-07-17 Elena Zannoni <ezannoni@redhat.com>
+
+ * Makefile.in (tui-file.o): Update dependencies.
+
+2001-07-17 Elena Zannoni <ezannoni@redhat.com>
+
+ * top.c (catch_errors): Convert PTR to void * in parameters list.
+ (quit_cover): Ditto.
+
+2001-07-17 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * source.c (find_source_lines): Remove tui test, must be replaced
+ by appropriate warning hook.
+ (print_source_lines): Remove tui hacks, must be replaced by cli.
+ (forward_search_command): Remove tui hacks, can be replaced by
+ appropriate calls to identify_source_line when tui scrolls.
+ (reverse_search_command): Likewise.
+
+2001-07-16 Nick Duffek <nsd@redhat.com>
+
+ * remote.c (init_remote_ops, init_remote_cisco_ops,
+ init_remote_async_ops): Set to_pid_to_str and
+ to_extra_thread_info correctly and in the same order as declared
+ in target.h.
+
+2001-07-16 Andrew Cagney <ac131313@redhat.com>
+
+ * remote.c: Revert below. Included more than intended.
+
+2001-07-16 Nick Duffek <nsd@redhat.com>
+
+ * remote.c (init_remote_ops, init_remote_cisco_ops,
+ init_remote_async_ops): Set to_pid_to_str and
+ to_extra_thread_info correctly and in the same order as declared
+ in target.h.
+
+2001-07-16 Nick Duffek <nsd@redhat.com>
+
+ * findvar.c (read_var_value): Apply value_as_pointer() to
+ addresses retrieved from the target for LOC_BASEREG and
+ LOC_BASEREG_ARG variables.
+
+2001-07-16 Orjan Friberg <orjanf@axis.com>
+
+ * NEWS: New target CRIS.
+
+2001-07-16 Elena Zannoni <ezannoni@redhat.com>
+
+ * top.c (show_commands): Remove extern decl of history_get, it's
+ already in readline/history.h.
+
+2001-07-16 Elena Zannoni <ezannoni@redhat.com>
+
+ * top.c (is_complete_command, init_cmd_lists, init_cli_cmds,
+ execute_user_command, do_setshow_command, get_prompt, init_proc,
+ serial_log_command): Remove extern declarations. Include
+ cli/cli-cmds.h, cli/cli-script.h, cli/cli-setshow.h, serial.h.
+ * gdbcmd.h (execute_user_command): Remove declaration, it's already
+ in cli/cli-script.h.
+ * command.h (do_setshow_command): Remove declaration, it's already
+ in cli/cli-setshow.h.
+ * infrun.c: Include "cli/cli-script.h" for execute_user_command.
+ * Makefile.in (infrun.o): Update dependencies.
+ (top.o): Ditto.
+ * cli/cli-setshow.h: Add comment for do_setshow_command.
+
+2001-07-16 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * cli/cli-cmds.c (shell_escape) [GLOBAL_CURDIR]: Condition the
+ call to chdir on this symbol rather than on __DJGPP__.
+ (CANT_FORK) [__MSDOS__]: Move from here...
+ * defs.h (CANT_FORK) [__MSDOS__]: ...to here.
+ (GLOBAL_CURDIR) [__MSDOS__]: Define.
+
+2001-07-16 Orjan Friberg <orjanf@axis.com>
+
+ * configure.tgt: Recognise the CRIS architecture.
+ * config/cris/cris.mt: New file for CRIS target.
+ * cris-tdep.c: New file for CRIS target.
+
+2001-07-15 Elena Zannoni <ezannoni@redhat.com>
+
+ * top.c (quit_cover, float_handler): Move definition up before use.
+ (gdb_init): Move to end of file, to avoid calls to not yet defined
+ functions.
+ Delete prototypes.
+
+2001-07-14 Andrew Cagney <ac131313@redhat.com>
+
+ * serial.h (SERIAL_ASYNC): Delete.
+ (DEPRECATED_SERIAL_FD): Delete.
+ (SERIAL_DEBUG): Delete.
+ (SERIAL_DEBUG_P): Delete.
+ (SERIAL_DRAIN_OUTPUT): Delete.
+ (SERIAL_FLUSH_OUTPUT): Delete.
+ (SERIAL_FLUSH_INPUT): Delete.
+ (SERIAL_SEND_BREAK): Delete.
+ (SERIAL_RAW): Delete.
+ (SERIAL_GET_TTY_STATE): Delete.
+ (SERIAL_SET_TTY_STATE): Delete.
+ (SERIAL_PRINT_TTY_STATE): Delete.
+ (SERIAL_NOFLUSH_SET_TTY_STATE): Delete.
+ (SERIAL_SETBAUDRATE): Delete.
+ (SERIAL_SETSTOPBITS): Delete.
+ (SERIAL_CAN_ASYNC_P): Delete.
+ (SERIAL_IS_ASYNC_P): Delete.
+ (SERIAL_UN_FDOPEN): Delete.
+ (SERIAL_READCHAR): Delete.
+ (SERIAL_CLOSE): Delete.
+ (SERIAL_FDOPEN): Delete.
+ (SERIAL_OPEN): Delete.
+ * ser-unix.c: Update.
+ * sparclet-rom.c: Update.
+ * remote-bug.c: Update.
+ * dsrec.c: Update.
+ * xmodem.c: Update.
+ * nindy-share/ttyflush.c: Update.
+ * nindy-share/Onindy.c: Update.
+ * utils.c: Update.
+ * serial.c: Update.
+ * remote-nindy.c: Update.
+ * inflow.c: Update.
+ * sparcl-tdep.c: Update.
+ * sh3-rom.c: Update.
+ * remote.c: Update.
+ * remote-utils.c: Update.
+ * remote-st.c: Update.
+ * remote-sds.c: Update.
+ * remote-rdp.c: Update.
+ * remote-os9k.c: Update.
+ * remote-nrom.c: Update.
+ * remote-mips.c: Update.
+ * remote-es.c: Update.
+ * remote-e7000.c: Update.
+ * remote-array.c: Update.
+ * ocd.c: Update.
+ * nindy-share/nindy.c: Update.
+ * monitor.c: Update.
+
+2001-07-14 Andrew Cagney <ac131313@redhat.com>
+
+ * mn10200-tdep.c: Replace value_ptr with ``struct value *''.
+ * mcore-tdep.c: Ditto.
+ * sparc-tdep.c: Ditto.
+ * sh-tdep.c: Ditto.
+ * rs6000-tdep.c: Ditto.
+ * ppc-linux-tdep.c: Ditto.
+ * m68hc11-tdep.c: Ditto.
+ * ia64-tdep.c: Ditto.
+ * i386-tdep.c: Ditto.
+ * arm-linux-tdep.c: Ditto.
+ * hppa-tdep.c: Ditto.
+ * h8500-tdep.c: Ditto.
+ * fr30-tdep.c: Ditto.
+ * arm-tdep.c: Ditto.
+ * alpha-tdep.c: Ditto.
+ * d30v-tdep.c: Ditto.
+ * d10v-tdep.c: Ditto.
+ * m32r-tdep.c: Ditto.
+ * mips-tdep.c: Ditto.
+ * v850-tdep.c: Ditto.
+
+2001-07-15 Elena Zannoni <ezannoni@redhat.com>
+
+ * top.c (readline_line_completion_function, noop_completer): Move
+ from here...
+ * completer.c (readline_line_completion_function, noop_completer):
+ ...to here.
+ * gdbcmd.h (readline_line_completion_function, noop_completer):
+ Move declarations from here...
+ * completer.h (readline_line_completion_function, noop_completer):
+ ...to here.
+ * corefile.c: Include completer.h.
+ * source.c: Ditto.
+ * symfile.c: Ditto.
+ * Makefile.in: Update dependencies.
+
+2001-07-15 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c (go32_create_inferior): Support command lines longer
+ than 126 characters.
+
+2001-07-14 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * NEWS: New target 68HC11/68HC12.
+
+2001-07-14 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * utils.c (query): Remove tui hacks; tui must use the query_hook.
+ * top.c (command_loop): Remove tui insert_mode hacks; don't call
+ tuiCleanUp because this must be made with atexit by tui.
+ * symfile.c (symbol_file_command): Remove call to TUIDO
+ * stack.c (show_and_print_stack_frame_stub): Remove tui check;
+ not necessary when using the selected frame hooks.
+ (print_stack_frame_stub): Likewise.
+ (print_frame_info_base): Likewise.
+ (print_frame_info): Likewise.
+ (up_silently_command): Likewise.
+ (down_silently_command): Likewise.
+ (show_stack_frame): Likewise for TUIDO.
+ (select_frame): Likewise.
+ (select_and_print_frame): Likewise.
+ (stack_publish_stopped_with_no_frame): Remove.
+ (select_and_maybe_print_frame): Remove.
+ * main.c (captured_main): Remove tui_fileopen and tuiInit; tui
+ must use the initialize ui hook.
+ * infrun.c (normal_stop): Remove call to TUIDO; tui must use the
+ selected frame hooks.
+ * event-top.c (command_handler): Remove tui insert_mode hack.
+ * defs.h: Remove TUIDO; Only include tui.h.
+ * breakpoint.c (mention): Remove calls to TUIDO.
+ (delete_breakpoint): Remove tui hacks; tui must install
+ the breakpoint hooks.
+
+2001-07-14 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/xm-linux.h (KERNEL_U_ADDR): Move from here...
+ * config/i386/nm-linux.h: ...to here. Change comments about user
+ area/struct a bit.
+
+ * config/i386/xm-linux.h (HAVE_TERMIOS): Really remove.
+
+ * Makefile.in (ALLDEPFILES): Add i386bsd-nat.c and i386bsd-tdep.c
+ (i386bsd-tdep.o, i386bsd-nat.o): New targets.
+
+2001-07-13 Elena Zannoni <ezannoni@redhat.com>
+
+ * remote-e7000.c (fetch_regs_from_dump): If register set is null,
+ generate an internal error.
+ (e7000_fetch_registers): Initialize variable 'wanted'.
+ (e7000_wait): Initialize variable 'wanted_nopc'.
+ (e7000_store_register): Fix sprintf compiler warnings.
+ (sub2_from_pc): Ditto.
+ (e7000_open): Close the descriptor, not the name.
+ (e7000_load): Fix compiler warnings.
+ (sub2_from_pc): Ditto.
+ * Makefile.in (remote-e7000.o): Can now compile with -Werror.
+
+2001-07-13 Mark Kettenis <kettenis@gnu.org>
+
+ * i386bsd-nat.c: Include <signal.h>, <stddef.h> and
+ <sys/sysctl.h>.
+ (store_inferior_registers): Wrap long line.
+ (i386bsd_dr_get_status): Fix typo in comment.
+ (_initialize_i386bsd_nat): New function. * i386bsd-tdep.c: New
+ file. * config/i386/tm-fbsd.h (IN_SIGTRAMP): New define.
+ (i386bsd_in_sigtramp): New prototype.
+ (SIGTRAMP_START, SIGTRAMP_END): Redefine in terms...
+ (i386bsd_sigtramp_start, i386bsd_sigtramp_end): ...these new
+ (external) variables.
+ (SIGCONTEXT_PC_OFFSET): Removed.
+ (FRAME_SAVED_PC): New define.
+ (i386bsd_frame_saved_pc): New function. * config/i386/fbsd.mt
+ (TDEPFILES): Add i386bsd-tdep.o.
+
+2001-07-12 Daniel Jacobowitz <drow@mvista.com>
+
+ * mips-linux-tdep.c (_initialize_mips_linux_tdep): Use ISO C
+ definition.
+
+2001-07-13 Mark Kettenis <kettenis@gnu.org>
+
+ * lin-lwp.c (lin_lwp_wait): Avoid check for resumed LWPs if there
+ are no registered LWPs yet.
+
+2001-07-12 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/i386/nm-linux.h (CANNOT_FETCH_REGISTER): Call the right
+ function.
+ (CANNOT_STORE_REGISTER): Likewise.
+
+2001-07-12 Keith Seitz <keiths@redhat.com>
+
+ * remote-rdp.c: Include "serial.h"
+
+2001-07-12 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdbserver/remote-utils.c (remote_open): Set VMIN to 1
+ in HAVE_TERMIO/HAVE_TERMIOS cases.
+
+2001-07-12 Mark Kettenis <kettenis@gnu.org>
+
+ * lin-lwp.c (stop_wait_callback): Add support for flushing
+ signals. Use that in favour of the old code to get rid of
+ superfluous SIGINTs.
+ (lin_lwp_wait): Use the new support in stop_wait_callback to
+ flush all but one SIGINT.
+
+ * i386-tdep.c (i386_extract_return_value): Undo 2001-07-11 changes
+ to comment.
+ (i386_store_return_value): Improve comments about storing
+ floating-point return values.
+
+ * config/arm/xm-linux.h, config/i386/xm-linux.h,
+ config/m68k/xm-linux.h, config/powerpc/xm-linux.h,
+ config/sparc/xm-linux.h, config/ia64/xm-linux.h (HAVE_TERMIOS):
+ Removed. Taken care of by autoconf and terminal.h.
+
+2001-07-12 Daniel Jacobowitz <drow@mvista.com>
+
+ * mips-tdep.c (mips_type_needs_double_align): New function.
+ (mips_push_arguments): Align o32 structs to even argument
+ registers if necessary.
+
+2001-07-11 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/djgpp/fnchange.lst: Add entries for
+ mips-linux-nat.c and mips-linux-tdep.c.
+
+2001-07-12 Mark Kettenis <kettenis@gnu.org>
+
+ * config/powerpc/xm-linux.h: Fix corrupted file.
+
+ * configure.in: Add check for sigsetjmp.
+ * config/m68k/xm-linux.h (HAVE_SIGSETJMP): Removed.
+ * config/xm-sysv4.h (HAVE_SIGSETJMP): Removed.
+ * configure, config.in: Regenerated.
+
+2001-07-11 Elena Zannoni <ezannoni@redhat.com>
+
+ * config/sh/tm-sh.h (struct gdbarch_tdep): Add
+ FLOAT_ARGLAST_REGNUM, RETURN_REGNUM, ARG0_REGNUM, ARGLAST_REGNUM,
+ PR_REGNUM fields.
+
+ * sh-tdep.c (sh_skip_prologue_hard_way): Rename from
+ skip_prologue_hard_way().
+ (skip_prologue_hard_way): Make it a function pointer.
+ (sh_print_register): Use function pointer do_pseudo_register,
+ instead of sh_do_pseudo_register.
+ (sh_do_registers_info): Ditto.
+ (sh_gdbarch_init): Initialize do_pseudo_register.
+ (IS_MOV_TO_R14): Rename from IS_MOV_R14.
+ (skip_prologue_hard_way): Update.
+ (sh_gdbarch_init): Move setting of frame_chain,
+ get_saved_register, init_extra_frame_info, push_arguments,
+ extract_return_value, pop_frame, store_struct_return,
+ extract_struct_value_address, use_struct_convention,
+ init_extra_frame_info to before target specific settings.
+ (sh_gdbarch_init): Initialize new tdep fields
+ FLOAT_ARGLAST_REGNUM, RETURN_REGNUM, ARG0_REGNUM, ARGLAST_REGNUM,
+ PR_REGNUM.
+ (sh_push_arguments): Use new gdbarch_tdep fields
+ {ARG0,ARGLAST}_REGNUM.
+ (sh_saved_pc_after_call, sh_nofp_frame_init_saved_regs,
+ sh_init_extra_frame_info, sh_push_return_address,
+ sh_generic_show_regs, sh3_show_regs, sh3e_show_regs,
+ sh3_dsp_show_regs, sh4_show_regs, sh_dsp_show_regs): Update to use
+ gdbarch_tdep->PR_REGNUM.
+ (dr_reg_base_num, fv_reg_base_num): Move to earlier in the file.
+
+2001-07-11 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/mips/tm-linux.h: Include "tm-linux.h" instead of copying
+ from it. Move definitions of REALTIME_LO and REALTIME_HI above
+ include.
+
+2001-07-11 Daniel Jacobowitz <drow@mvista.com>
+
+ * MAINTAINERS: List myself for MIPS/Linux
+ port.
+
+2001-07-11 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdbserver/remote-utils.c (remote_open): Only
+ check for F_SETOWN if we had F_SETFL and FASYNC.
+
+2001-07-11 Daniel Jacobowitz <drow@mvista.com>
+
+ From Michael Fedrowitz <michael.fedrowitz@informatik.uni-ulm.de>:
+
+ * config/m68k/linux.mh: Remove core-regset.o.
+ * m68klinux-nat.c: Fix comment.
+ (supply_gregset): Change argument to elf_gregset_t *.
+ (supply_fpregset): Change argument to elf_fpregset_t *.
+ (fetch_core_registers): New function.
+ (linux_elf_core_fns): Define.
+ (_initialize_m68k_linux_nat): New function.
+
+2001-07-11 Andrew Cagney <ac131313@redhat.com>
+
+ * configure.tgt: Mark d10v as pure multi-arch.
+ * config/d10v/tm-d10v.h: Delete file.
+ * config/d10v/d10v.mt (TM_FILE): Delete.
+
+2001-07-10 Andrew Cagney <ac131313@redhat.com>
+
+ * serial.h (typedef serial_t): Delete. Replace all references to
+ serial_t with `struct serial *'.
+ * serial.c: Update.
+ * nindy-share/ttyflush.c: Update.
+ * nindy-share/ttyflush.c: Update.
+ * nindy-share/Onindy.c: Update.
+ * nindy-share/nindy.c: Update.
+ * remote-rdp.c: Update.
+ * remote-sds.c: Update.
+ * remote-st.c: Update.
+ * remote-nindy.c: Update.
+ * remote-mips.c: Update.
+ * remote-e7000.c: Update.
+ * remote-os9k.c: Update.
+ * remote-nrom.c: Update.
+ * remote-es.c: Update.
+ * remote-array.c: Update.
+ * ocd.c: Update.
+ * mon960-rom.c: Update.
+ * dsrec.c: Update.
+ * inflow.c: Update.
+ * ser-e7kpc.c: Update.
+ * sparclet-rom.c: Update.
+ * srec.h: Update.
+ * ser-tcp.c: Update.
+ * ser-go32.c: Update.
+ * sparcl-tdep.c: Update.
+ * w89k-rom.c: Update.
+ * utils.c: Update.
+ * sh3-rom.c: Update.
+ * remote.c: Update.
+ * ser-pipe.c: Update.
+ * ser-unix.c: Update.
+ * ser-unix.h: Update.
+ * xmodem.c: Update.
+ * xmodem.h: Update.
+
+2001-07-11 J.T. Conklin <jtc@redback.com>
+
+ From Greg McGary <greg@mcgary.org>:
+ * gdbserver/remote-utils.c (remote_open): Set gdbserver as "owner"
+ of SIGIO.
+ (input_interrupt): Don't block on read, in case we got redundant
+ SIGIO. Don't gripe about redundant SIGIO.
+ * gdbserver/low-hppabsd.c (mywait): Use waitpid(). Enable SIGIO
+ handler while waiting.
+ * gdbserver/low-linux.c (mywait): Likewise.
+ * gdbserver/low-nbsd.c (mywait): Likewise.
+ * gdbserver/low-sparc.c (mywait): Likewise.
+
+2001-07-11 Keith Seitz <keiths@redhat.com>
+
+ * infrun.c (print_stop_reason): Add missing uiout field
+ "reason" for SIGNAL_RECEIVED case.
+
+2001-07-11 Mark Kettenis <kettenis@gnu.org>
+
+ * config/alpha/nm-linux.h (TARGET_ELF64, PSIGNAL_IN_SIGNAL_H):
+ Remove unused macro's.
+
+ * config/powerpc/nm-linux.h (NO_SYS_REG_H): Remove, it's no longer
+ used.
+
+2001-07-11 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c (info_dos_cmdlist): New variable.
+ (go32_info_dos_command): New function.
+ (_initialize_go32_nat): Convert all DOS-specific commands into
+ subcommands of "info dos". Suggested by Andrew Cagney
+ <ac131313@redhat.com>.
+
+2001-07-11 Mark Kettenis <kettenis@gnu.org>
+
+ * config/nm-linux.h: Fix comments.
+
+ * thread-db.c (enable_thread_event_reporting): Correct warning
+ message about getting thread death breakpoint.
+ Reported by John S Kallal <jskallal@home.com>.
+
+ * i386-tdep.c (i386_extract_return_value): "Fix" comment.
+ (i386_store_return_value): Frob FPU status and tag word to make
+ sure the return value is the only value on the FPU stack.
+
+ * config/tm-linux.h: Do not include <signal.h>. Instead provide
+ reasonable defaults for REALTIME_LO and REALTIME_HI if they're not
+ already defined.
+ * config/nm-linux.h: Include <signal.h>.
+ [__SIGRTMIN] (REALTIME_LO, REALTIME_HI): Define to __SIGRTMIN and
+ (__SIGRTMAX + 1) respectively.
+
+2001-07-10 Andrew Cagney <ac131313@redhat.com>
+
+ * mcore-rom.c: Include "serial.h".
+ * Makefile.in (mcore-rom.o): Depends on "serial.h".
+
+2001-07-10 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in (remote-bug.o): Depends on serial.h.
+ * remote-bug.c: Include "serial.h".
+ * MAINTAINERS: Mark m88k target as buildable.
+ * TODO: Update.
+
+2001-07-10 Jim Blandy <jimb@redhat.com>
+
+ Clean up the D10V port so that GDB and the target program no
+ longer disagree on how big pointers are.
+ * findvar.c (value_from_register): Remove special case code for D10V.
+ * printcmd.c (print_frame_args): Same.
+ * valops.c (value_at, value_fetch_lazy): Same.
+ * values.c (unpack_long): Same.
+ * gdbarch.sh: Changes to effect the following:
+ * gdbarch.h (GDB_TARGET_IS_D10V, D10V_MAKE_DADDR,
+ gdbarch_d10v_make_daddr_ftype, gdbarch_d10v_make_daddr,
+ set_gdbarch_d10v_make_daddr, D10V_MAKE_IADDR,
+ gdbarch_d10v_make_iaddr_ftype, gdbarch_d10v_make_iaddr,
+ set_gdbarch_d10v_make_iaddr, D10V_DADDR_P,
+ gdbarch_d10v_daddr_p_ftype, gdbarch_d10v_daddr_p,
+ set_gdbarch_d10v_daddr_p, D10V_IADDR_P,
+ gdbarch_d10v_iaddr_p_ftype, gdbarch_d10v_iaddr_p,
+ set_gdbarch_d10v_iaddr_p, D10V_CONVERT_DADDR_TO_RAW,
+ gdbarch_d10v_convert_daddr_to_raw_ftype,
+ gdbarch_d10v_convert_daddr_to_raw,
+ set_gdbarch_d10v_convert_daddr_to_raw, D10V_CONVERT_IADDR_TO_RAW,
+ gdbarch_d10v_convert_iaddr_to_raw_ftype,
+ gdbarch_d10v_convert_iaddr_to_raw,
+ set_gdbarch_d10v_convert_iaddr_to_raw): Delete declarations.
+ * gdbarch.c: Delete the corresponding definitions.
+ (struct gdbarch): Delete members d10v_make_daddr,
+ d10v_make_iaddr, d10v_daddr_p, d10v_iaddr_p,
+ d10v_convert_daddr_to_raw, and d10v_convert_iaddr_to_raw.
+ (startup_gdbarch): Remove initializers for the above.
+ (verify_gdbarch, gdbarch_dump): Don't verify or dump them any
+ more.
+ * d10v-tdep.c (d10v_register_virtual_type): Rather that
+ claiming the stack pointer and PC are 32 bits long (which they
+ aren't), say that the stack pointer is an int16_t, and the
+ program counter is a function pointer. This allows the rest
+ of GDB to make the appropriate conversions between the code
+ pointer format and real addresses.
+ (d10v_register_convertible, d10v_register_convert_to_virtual,
+ d10v_register_convert_to_raw): Delete function; no registers
+ are convertible now, so we use
+ generic_register_convertible_not instead.
+ (d10v_address_to_pointer, d10v_pointer_to_address): New gdbarch
+ methods.
+ (d10v_push_arguments, d10v_extract_return_value): Remove special
+ cases for code and data pointers.
+ (d10v_gdbarch_init): Set gdbarch_ptr_bit to 16, so that GDB and
+ the target agree on how large pointers are. Say that addresses
+ are 32 bits long. Register the address_to_pointer and
+ pointer_to_address conversion functions. Since no registers are
+ convertible now, register generic_register_convertible_not as the
+ gdbarch_register_convertible method instead of
+ d10v_register_convertible. Remove registrations for
+ d10v_register_convert_to_virtual,
+ d10v_register_convert_to_raw, gdbarch_d10v_make_daddr,
+ gdbarch_d10v_make_iaddr, gdbarch_d10v_daddr_p,
+ gdbarch_d10v_iaddr_p, gdbarch_d10v_convert_daddr_to_raw, and
+ gdbarch_d10v_convert_iaddr_to_raw.
+
+ * printcmd.c (print_scalar_formatted): If we are printing an
+ address, remember that TARGET_ADDR_BIT is not always equal to
+ TARGET_PTR_BIT.
+
+ * valops.c (value_cast): When casting a pointer to an integer,
+ don't convert it to an address.
+
+2001-07-10 Andrew Cagney <ac131313@redhat.com>
+
+ * remote-utils.h (struct serial): Declare as opaque. Remove
+ include of "serial.h".
+ * Makefile.in (remote_utils_h): Update.
+
+ * monitor.h (struct serial): Declare as opaque. Remove include of
+ "serial.h".
+ (struct monitor_ops): Replace serial_t with `struct serial *'.
+ * monitor.c (monitor_desc): Ditto.
+
+2001-07-10 Daniel Jacobowitz <drow@mvista.com>
+
+ * mips-linux-tdep.c: New file.
+ * mips-linux-nat.c: New file.
+ * config/mips/linux.mh: New file.
+ * config/mips/linux.mt: New file.
+ * config/mips/xm-linux.h: New file.
+ * config/mips/nm-linux.h: New file.
+ * config/mips/tm-linux.h: New file.
+ * configure.host: Recognize mips*-*-linux*.
+ * configure.tgt: Likewise.
+ * NEWS: Mention mips*-*-linux* port.
+
+2001-07-09 Andrew Cagney <ac131313@redhat.com>
+
+ * serial.h (struct serial): Rename `struct _serial_t'.
+ * serial.c (XMALLOC): Define.
+ (serial_open): Update. Use XMALLOC.
+ (serial_fdopen): Ditto.
+
+2001-07-07 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbtypes.h (builtin_type_void_data_ptr): Rename
+ builtin_type_ptr.
+ * gdbtypes.c (builtin_type_void_data_ptr): Update.
+ (build_gdbtypes): Update.
+ (_initialize_gdbtypes): Update.
+ * values.c (value_as_pointer): Update.
+ * utils.c (host_pointer_to_address): Update.
+ (address_to_host_pointer): Update.
+
+2001-07-08 Andrew Cagney <ac131313@redhat.com>
+
+ * remote-udi.c (udi_wait): Make type, instead of name, of first
+ parameter a ptid_t.
+
+2001-07-07 Andrew Cagney <ac131313@redhat.com>
+
+ * ser-mac.c: Make obsolete.
+ * Makefile.in (ser-mac.o): Ditto.
+
+2001-07-08 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c (go32_get_windows_version, print_mem, go32_sysinfo)
+ (read_memory_region, get_descriptor, display_descriptor)
+ (go32_sldt, go32_sgdt, go32_sidt): New functions.
+ (top-level): Include ctype.h, utsname.h, dos.h, and go32.h. Ifdef
+ away `disable' from dos.h, since breakpoint.h defines an enum
+ member of the same name, and GCC 2.7.2 barfs.
+ (_initialize_go32_nat): Provide new commands dos-sysinfo, dos-ldt,
+ dos-gdt, and dos-idt, all of them in the "info" class
+
+2001-07-07 Kevin Buettner <kevinb@redhat.com>
+
+ * procfs.c (create_procinfo): Allocate space for saved_entryset
+ and saved_exitset.
+ (destroy_one_procinfo): Free space allocated to saved_entryset
+ and saved_exitset.
+
+2001-07-07 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO (5.1): Update.
+
+2001-07-07 Andrew Cagney <ac131313@redhat.com>
+
+ * symtab.c (main_name): New function.
+ (set_main_name): New function.
+ * symtab.h: Declare.
+ * TODO: Update
+
+ From 2000-03-05 Anthony Green <green@redhat.com>:
+ * dbxread.c (process_one_symbol): Handle the N_MAIN stab by
+ setting main_name.
+ * blockframe.c (inside_main_func): Use main_name instead of
+ "main".
+ * symtab.c (find_main_psymtab): Ditto.
+ * source.c (select_source_symtab): Ditto.
+ * nlmread.c (nlm_symfile_read): Ditto.
+ * rs6000-tdep.c (skip_prologue): Ditto.
+
+2001-07-07 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO: Convert most items into PRs.
+
+2001-07-07 Mark Kettenis <kettenis@gnu.org>
+
+ * lin-lwp.c (status_to_str): New function.
+ (lin_lwp_wait): Use it to print debug messages where appropriate.
+
+2001-07-06 Michael Chastain <chastain@redhat.com>
+
+ * i387-tdep.c (print_i387_value): Fix pointer glitch.
+
+2001-07-07 Mark Kettenis <kettenis@gnu.org>
+
+ * lin-lwp.c (count_events_callback): Fix formatting. Turn check
+ commented with "paranoia" into gdb_assert.
+ (select_event_lwp_callback): Likewise.
+ (cancel_breakpoints_callback): Bail out early if LP is the event
+ LWP. Add comment about backup up breakpoints. Fix formatting and
+ debug message.
+ (select_event_lwp): Make solely repsonsible for switching event
+ LWP. Fix formatting and remove bogus "ERROR" debug message.
+ Don't backup breakpoints from here.
+ (lin_lwp_wait): Don't touch LP->status, let select_event_lwp
+ handle that. Only call select_event_lwp if we're not waiting for
+ a specific LWP, i.e. when PID == -1. Backup breakpoints from here.
+
+2001-07-06 Michael Snyder <msnyder@redhat.com>
+
+ * procfs.c (procfs_resume): Silence noisy warning.
+
+2001-06-12 Michael Snyder <msnyder@redhat.com>
+
+ * lin-lwp.c: Prevent thread starvation by using a monte carlo
+ method to choose which of several event threads to handle next.
+
+ (stop_wait_callback): Defer pushback of breakpoint events until
+ later; add SIGTRAP events to the queue of unhandled events.
+ Keep calling waitpid until SIGSTOP retrieved. If more than one
+ non-SIGSTOP event is retrieved, push them back onto the process
+ queue using kill.
+ (count_events_callback, select_singlestep_lwp_callback,
+ select_event_lwp_callback, cancel_breakpoints_callback,
+ select_event_lwp): New functions. Implement monte carlo method
+ for selecting which of several SIGTRAP threads to handle next.
+ Push back the breakpoint event for all threads other than the
+ selected one.
+ (lin_lwp_wait): Call select_event_lwp to decide which of several
+ sigtrapped lwps to handle next.
+ (resume_callback): Disable code that attempts to handle
+ step_resume breakpoints. Let core gdb handle this.
+
+2001-07-06 Jim Blandy <jimb@redhat.com>
+
+ * gdbtypes.h (builtin_type_void_func_ptr): New builtin type.
+ * gdbtypes.c (builtin_type_void_func_ptr): Define the variable.
+ (build_gdbtypes): Initialize it.
+ (_initialize_gdbtypes): Swap it.
+
+2001-07-04 Daniel Jacobowitz <drow@mvista.com>
+
+ * mips-tdep.c (mips32_op): Correct offset.
+ (itype_op): Likewise.
+ (itype_rs): Fix formatting.
+ (itype_immediate): Fix formatting.
+ (jtype_op): Correct offset.
+ (jtype_target): Fix formatting.
+ (rtype_op): Correct offset.
+ (rtype_rs): Fix formatting.
+ (rtype_rt): Likewise.
+ (rtype_rd): Likewise.
+ (rtype_shamt): Likewise.
+ (rtype_funct): Likewise.
+
+ (mips32_next_pc): Fix formatting and comments. Recognize
+ coprocessor 1 branches. Check the correct field for BLT family
+ branches. Use itype_rt instead of itype_rs for the second register
+ of a BNE or BNEL branch. Move (unreachable) default case.
+
+2001-07-04 Andrew Cagney <ac131313@redhat.com>
+
+ * ui-out.h (struct ui_out_impl): Add field is_mi_like_p.
+ (ui_out_is_mi_like_p): Declare.
+ * ui-out.c (ui_out_is_mi_like_p): Define.
+ (default_ui_out_impl): Initialize is_mi_like_p to zero.
+ * cli-out.c (cli_ui_out_impl): Ditto.
+ * breakpoint.c (print_it_typical): Use ui_out_is_mi_like_p.
+ (watchpoint_check, print_one_breakpoint, mention): Ditto.
+ * infrun.c (print_stop_reason, normal_stop): Ditto.
+
+2001-07-05 Daniel Jacobowitz <drow@mvista.com>
+
+ * mips-tdep.c (mips_software_single_step): New function.
+ * config/mips/tm-mips.h: Add prototype for
+ mips_software_single_step.
+
+2001-07-05 Daniel Jacobowitz <drow@mvista.com>
+
+ * ppc-linux-nat.c (supply_gregset): Use elf_greg_t instead
+ of greg_t.
+ (fill_gregset): Likewise.
+
+2001-07-05 Andrew Cagney <ac131313@redhat.com>
+
+ * objfiles.c (open_mapped_file): Use lbasename instead of
+ basename.
+
+2001-07-05 Jim Blandy <jimb@redhat.com>
+
+ * d10v-tdep.c (d10v_frame_chain, d10v_frame_init_saved_regs,
+ show_regs, d10v_read_pc, d10v_write_pc, d10v_read_sp,
+ d10v_write_sp, d10v_write_fp, d10v_read_fp,
+ d10v_push_return_address): Call the functions d10v_make_daddr,
+ d10v_make_iaddr, d10v_convert_iaddr_to_raw, and
+ d10v_convert_daddr_to_raw, not the global macros D10V_MAKE_DADDR,
+ D10V_MAKE_IADDR, D10V_CONVERT_IADDR_TO_RAW, and
+ D10V_CONVERT_DADDR_TO_RAW.
+
+ * dwarf2read (dwarf2_build_psymtabs_hard): Doc fix.
+
+2001-07-05 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/xm-go32.h (HOST_I386): Removed.
+ * config/i386/xm-linux.h (HOST_I386): Removed.
+
+2001-07-04 Mark Kettenis <kettenis@gnu.org>
+
+ * i387-tdep.c (print_i387_value): Add extra space after final full
+ stop in comment.
+
+2001-07-04 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO (5.1): Update. Doco changes committed.
+
+2001-06-29 Andrew Cagney <ac131313@redhat.com>
+
+ * config/arm/tm-arm.h: Include "floatformat.h".
+
+2001-06-29 Andrew Cagney <ac131313@redhat.com>
+
+ * i387-tdep.c: Include "gdb_assert.h".
+ (print_i387_value): Use extract_floating to extract the FP value
+ from a zero padded local buffer.
+
+2001-06-28 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO: Delete all thread items. The thread code was overhauled.
+
+2001-07-04 Elena Zannoni <ezannoni@redhat.com>
+
+ * memattr.c (create_mem_region): Move n to next memory region,
+ to avoid infinite loop.
+
+ * memattr.h: Add copyright statement.
+ * memattr.c: Ditto.
+
+2001-07-04 Jim Blandy <jimb@redhat.com>
+
+ * dwarf2read.c (struct partial_die_info): New member: has_pc_info.
+ (read_partial_die): Delete fourth argument; we return this info in
+ the struct partial_die_info object itself now.
+ (dwarf2_build_psymtabs_hard, scan_partial_symbols): Use the
+ has_pc_info field of the partial die struct, rather than passing a
+ variable by reference to read_partial_die.
+
+ * dwarf2read.c (dwarf2_build_psymtabs_hard): Remove extraneous
+ code in loop condition.
+
+2001-07-03 Michael Snyder <msnyder@redhat.com>
+
+ * thread_db (find_new_threads_callback, thread_db_thread_alive,
+ attach_thread): Update comments.
+
+2001-06-29 Ken Whaley <ken@believe.com>
+
+ * thread-db.c (attach_thread): Check for TD_THR_ZOMBIE in addition
+ to TD_THR_UNKNOWN when looking for defunct zombie threads.
+ (thread_db_thread_alive): Ditto.
+ (find_new_threads_callback): Ditto.
+
+2001-07-02 Daniel Jacobowitz <drow@mvista.com>
+
+ * MAINTAINERS: Add myself to the write-after-approval list.
+
+2001-07-02 Daniel Jacobowitz <drow@mvista.com>
+
+ * solib-svr4.c: Include "elf/mips.h".
+ (elf_locate_base): Make DT_MIPS_RLD_MAP block unconditional.
+
+2001-07-02 Jim Blandy <jimb@redhat.com>
+
+ * dwarf2read.c (read_comp_unit, sibling_die, dump_die,
+ dump_die_list, store_in_ref_table, follow_die_ref): Make these
+ static; they're private functions.
+
+2001-07-01 Mark Elbrecht <snowball@bigfoot.com>
+
+ * coffread.c (coff_symfile_read): Parse DWARF2 info if present.
+
+2001-06-28 Elena Zannoni <ezannoni@redhat.com>
+
+ * TODO: Add import of readline 4.2 as a gdb 5.2 task.
+
+2001-06-29 Andrew Cagney <ac131313@redhat.com>
+
+ * config/djgpp/fnchange.lst: Sort.
+
+2001-06-28 Andrew Cagney <ac131313@redhat.com>
+
+ * config/djgpp/fnchange.lst: Rename mi0-var-block.exp,
+ mi0-var-cmd.exp, mi0-var-child.exp and mi0-var-display.exp.
+
+2001-06-29 Andreas Jaeger <aj@suse.de>
+
+ * MAINTAINERS: Add myself to the write-after-approval list.
+
+2001-06-28 Andrew Cagney <ac131313@redhat.com>
+
+ * remote-array.c (SWAP_TARGET_AND_HOST): Delete macro.
+ (get_hex_word): Don't use HOST_BYTE_ORDER.
+ (array_fetch_registers): Add variable ``reg''. Use
+ store_unsigned_integer to byte-swap the register. Delete unused
+ local ``regs''.
+
+2001-06-28 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Add Per Bothner to Java maintainers.
+
+2001-06-28 Andrew Cagney <ac131313@redhat.com>
+
+ * rdi-share/unixcomm.c (SERIAL_PREFIX): Always provide a default.
+ * rdi-share/hostchan.h (__unix): Hack, provide a default value.
+ * rdi-share/host.h (__unix): Hack, define when __NetBSD__.
+ * TODO: Update.
+ * MAINTAINERS: Update. arm-elf builds.
+
+2001-06-28 Jim Blandy <jimb@redhat.com>
+
+ * d10v-tdep.c (d10v_ts2_dmap_register): Doc fix.
+
+ * d10v-tdep.c (d10v_frame_chain_valid, d10v_use_struct_convention,
+ d10v_breakpoint_from_pc, d10v_register_byte,
+ d10v_register_raw_size, d10v_register_virtual_size,
+ d10v_register_virtual_type, d10v_register_convertible,
+ d10v_register_convert_to_virtual, d10v_register_convert_to_raw,
+ d10v_make_daddr, d10v_make_iaddr, d10v_daddr_p, d10v_iaddr_p,
+ d10v_convert_iaddr_to_raw, d10v_convert_daddr_to_raw,
+ d10v_store_struct_return, d10v_store_return_value,
+ d10v_extract_struct_value_address, d10v_frame_saved_pc,
+ d10v_saved_pc_after_call, d10v_pop_frame, d10v_skip_prologue,
+ d10v_frame_chain, d10v_frame_init_saved_regs,
+ d10v_init_extra_frame_info, d10v_read_pc, d10v_write_pc,
+ d10v_read_sp, d10v_write_sp, d10v_write_fp, d10v_read_fp,
+ d10v_push_return_address, d10v_push_arguments,
+ d10v_extract_return_value): Make these functions static.
+
+2001-06-28 Andrew Cagney <ac131313@redhat.com>
+
+ From Fernando Nasser:
+ * infrun.c (handle_inferior_event): Handle "nexti" inside function
+ prologues.
+
+2001-06-28 Michael Snyder <msnyder@redhat.com>
+
+ * infrun.c (handle_inferior_event): Replace prev_pc test in all
+ calls to bpstat_stop_status (removed in 1999-09-24). This test
+ helps distinguish stepping over a breakpoint trap from stepping
+ thru a jump to the instruction after a breakpoint trap.
+ (handle_inferior_event): Don't bother writing the PC if
+ DECR_PC_AFTER_BREAK is zero (optimization).
+ * breakpoint.c (bpstat_stop_status): Add comment explaining the
+ purpose and usage of the "not_a_breakpoint" argument in computing
+ the breakpoint address.
+
+2001-06-28 Andrew Cagney <ac131313@redhat.com>
+
+ From 2000-12-03 Stephane Carrez <Stephane.Carrez@worldnet.fr>:
+ * monitor.c (setmem_resp_delim_pattern): New regexp pattern.
+ (setreg_resp_delim_pattern): Likewise.
+ (setmem_resp_delim_fastmap): New buffer.
+ (setreg_resp_delim_fastmap): Likewise.
+ (monitor_open): Initialize above regexp if they are defined.
+ (monitor_write_memory): Use regexp to check the result of write.
+ (monitor_store_register): Likewise to check result of register set.
+
+2001-06-28 Andrew Cagney <ac131313@redhat.com>
+
+ From 2000-06-14 John Marshall <john_w_marshall@palm.com>:
+ * coff-solib.c: Include symfile.h and objfiles.h to make
+ OBJF_SHARED visible.
+
+2001-06-28 Andrew Cagney <ac131313@redhat.com>
+
+ * configure.in (--enable-gdbmi): Enable by default.
+ * configure: Regenerate.
+ * TODO: Update.
+ * NEWS: Update
+
+2001-06-28 Joel Brobecker <brobecker@act-europe.fr>
+
+ * solib-osf.c (osf_in_dynsym_resolve_code): Add a comment
+ explaining the consequences of always returning zero. No code
+ change.
+
+2001-06-28 Andrew Cagney <ac131313@redhat.com>
+
+ From 2001-06-08 Daniel Jacobowitz <djacobowitz@mvista.com>:
+ * defs.h (enum target_signal): Add TARGET_SIGNAL_REALTIME_65
+ to TARGET_SIGNAL_REALTIME_127.
+ * target.c (struct signals): Add SIG63 to SIG127.
+ (target_signal_from_host): Handle up to 127 signals.
+ (do_target_signal_to_host): Likewise.
+
+2001-06-27 Andrew Cagney <ac131313@redhat.com>
+
+ * remote-sds.c (sds_start_remote): Change type of ``c'' to int
+ from possibly unsigned char.
+
+2001-06-27 Andrew Cagney <ac131313@redhat.com>
+
+ * ser-ocd.c: Delete file.
+ * Makefile.in (ALLDEPFILES): Remove ser-ocd.c
+ (ser-ocd.o): Delete target.
+ * TODO: Update.
+ * NEWS: Update.
+
+2001-06-27 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS (Write After Approval): Sort.
+ (Past Maintainers): Daniel Berlin stepped down as C++ maintainer.
+
+2001-06-26 Andrew Cagney <ac131313@redhat.com>
+
+ * breakpoint.c (breakpoint_1): Always output the breakpoint
+ headings. Leave it to ui-out to decide which
+
+2001-06-25 Andrew Cagney <ac131313@redhat.com>
+
+ * stack.c (print_frame): For ui_out, output a list of arguments.
+
+2001-06-25 Kevin Buettner <kevinb@redhat.com>
+
+ * MAINTAINERS (paper trail): Update.
+
+2001-06-25 Michael Snyder <msnyder@redhat.com>
+
+ * infrun.c: Eliminate the "thread_step_needed" state variable,
+ and replace it with a relatively simple test in resume.
+ (resume): Replace thread_step_needed logic with a test for
+ stepping, breakpoint_here_p and breakpoints_inserted.
+ Move CANNOT_STEP_BREAKPOINT logic to after thread_step logic.
+ (proceed): Discard thread_step_needed logic.
+ (wait_for_inferior, fetch_inferior_event, handle_inferior_event):
+ Discard thread_step_needed logic.
+
+2001-06-24 Fernando Nasser <fnasser@redhat.com>
+
+ * remote-rdi.c (arm_rdi_wait): Fix return type in prototype.
+ * rdi-share/host.h: Add missing parenthesis in conditional.
+
+2001-06-22 J.T. Conklin <jtc@redback.com>
+
+ * configure.in: include nlist.h when checking for member som_addr
+ in struct so_map.
+ * configure: regenerate.
+
+2001-06-21 Keith Seitz <keiths@redhat.com>
+
+ * cli-out.c (cli_out_new): Initialize new structure member
+ "suppress_output".
+
+2001-06-20 Andrew Cagney <ac131313@redhat.com>
+
+ * ui-out.h (ui_out_table_header): Add parameter ``col_name''.
+ (table_header_ftype): Ditto.
+ * cli-out.c (cli_table_header): Update.
+ * ui-out.c (ui_out_table_header): Update.
+ (uo_table_header): Update.
+ (default_table_header): Update.
+ (append_header_to_list): Update.
+ (struct ui_out_header): Add field ``col_name''.
+ (append_header_to_list): Use xstrdup. Initialize col_name.
+ * breakpoint.c (breakpoint_1): Pass COL_NAME to
+ ui_out_table_header.
+
+2001-06-19 Andrew Cagney <ac131313@redhat.com>
+
+ * cli-out.c: Include "gdb_assert.h'.
+ (struct ui_out_data): Add field ``suppress_output.
+ (cli_table_begin): When NR_ROWS is zero, suppress_output.
+ (cli_table_end): Clear suppress_output.
+ (cli_table_body): Check suppress_output.
+ (cli_table_header, cli_begin): Ditto.
+ (cli_end, cli_field_int, cli_field_skip): Ditto.
+ (cli_field_string, cli_field_fmt, cli_spaces): Ditto.
+ (cli_text, cli_message, cli_wrap_hint): Ditto.
+ * breakpoint.c (breakpoint_1): Close the ui_out table before
+ printing the breakpoint not found message.
+
+2001-06-18 Andrew Cagney <ac131313@redhat.com>
+
+ * ui-out.c (ui_out_table_begin): Add parameter ``nr_rows''.
+ (default_table_begin): Ditto.
+ (uo_table_begin): Ditto.
+ * cli-out.c (cli_table_begin): Ditto.
+ * ui-out.h (ui_out_table_begin): Update
+ (table_begin_ftype): Update.
+ * breakpoint.c (breakpoint_1): Pass nr_printable_breakpoints to
+ ui_out_table_begin.
+
+2001-06-16 Andrew Cagney <ac131313@redhat.com>
+
+ * breakpoint.c (breakpoint_1): Restructure. Compute the
+ nr_printable_breakpoints. Move the header output to before the
+ main print breakpoints loop.
+ (user_settable_breakpoint): New function.
+
+2001-06-18 Andrew Cagney <ac131313@redhat.com>
+
+ * infrun.c, breakpoint.c: Use strncmp as the "mi" test. Allow,
+ "mi", "mi0" and "mi1".
+
+2001-06-17 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh: Generate an error when conflicting macro
+ definitions. Generate an error when both pure multi-arch and
+ "tm.h".
+ * gdbarch.h, gdbarch.c: Regenerate.
+ * defs.h (GDB_MULTI_ARCH_TM): Rewrite definition.
+
+2001-06-17 Andrew Cagney <ac131313@redhat.com>
+
+ * config/sparc/tm-sun4sol2.h (GDB_MULTI_ARCH): Down grade to
+ GDB_MULTI_ARCH_PARTIAL from two.
+
+2001-06-17 Fernando Nasser <fnasser@redhat.com>
+
+ From 2001-06-15 Eirik Fuller <eirik@hackrat.com>
+ * cli/cli-script.c (free_command_lines): Reset list pointer.
+
+2001-06-16 Andrew Cagney <ac131313@redhat.com>
+
+ * arch-utils.c (init_frame_pc_default): New function
+ * arch-utils.h (init_frame_pc_default): Declare.
+ * gdbarch.sh (INIT_FRAME_PC): Default to init_frame_pc_default and
+ not init_frame_pc_noop.
+ * gdbarch.h, gdbarch.c: Re-generate.
+ * blockframe.c (INIT_FRAME_PC): Delete macro definition.
+ * mips-tdep.c (mips_gdbarch_init): Set init_frame_pc to
+ init_frame_pc_noop.
+
+2001-06-16 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.c: Regenerate. Out-of-sync with gdbarch.sh.
+
+2001-06-15 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (CANNOT_FETCH_REGISTER): Multi-arch.
+ (CANNOT_STORE_REGISTER): Ditto.
+ * infptrace.c (CANNOT_FETCH_REGISTER): Delete definition.
+ (CANNOT_STORE_REGISTER): Ditto.
+ * regcache.c (CANNOT_STORE_REGISTER): Ditto.
+ * lynx-nat.c (CANNOT_STORE_REGISTER): Ditto.
+ * arch-utils.h (cannot_register_not): Define.
+ * arch-utils.c (cannot_register_not): Declare.
+
+2001-06-15 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh: Clarify pre/post default
+ (INIT_FRAME_PC_FIRST, INIT_FRAME_PC): Multiarch.
+ * blockframe.c (get_prev_frame): Remove #ifdef from around
+ INIT_FRAME_PC_FIRST call.
+ * arch-utils.c (init_frame_pc_noop): Define.
+ * arch-utils.h (init_frame_pc_noop): Declare.
+ * config/mips/tm-mips.h (INIT_FRAME_PC_FIRST): Delete.
+ (INIT_FRAME_PC, mips_init_frame_pc_first): Ditto.
+ * mips-tdep.c (mips_init_frame_pc_first): Make static.
+ (mips_gdbarch_init): Initialize init_frame_pc_first.
+ (mips_dump_tdep): Update.
+
+2001-06-15 Michael Snyder <msnyder@redhat.com>
+
+ * infrun.c (context_switch): New function. Abstract the operation
+ of saving and restoring infrun's state when switching threads.
+ (handle_inferior_event): Normalize the handling of the 'thread hop'
+ event (when the wrong thread hits a thread-specific breakpoint,
+ and we need to solo-step that thread past the breakpoint).
+ Call keep_going, instead of target_resume. Handle the subsequent
+ singlestep-trap as a normal event instead of just resuming.
+
+2001-06-15 Andrew Cagney <ac131313@redhat.com>
+
+ * arch-utils.c (core_addr_identity): New function. Rename
+ default_convert_from_func_ptr_addr.
+ * gdbarch.sh (CONVERT_FROM_FUNC_PTR_ADDR): Update.
+ (ADDR_BITS_REMOVE): Define. Default to core_addr_identity.
+ * defs.h (ADDR_BITS_REMOVE): Delete macro definition.
+ * config/mips/tm-mips.h (ADDR_BITS_REMOVE): Delete definition.
+ * mips-tdep.c (mips_addr_bits_remove): Make static.
+ (mips_gdbarch_init): Initialize addr_bits_remove.
+
+2001-06-15 Andrew Cagney <ac131313@redhat.com>
+
+ From 2001-02-26 D.J. Barrow <djbarrow@de.ibm.com>:
+ * configure.tgt: Add S/390 31 & 64 bit target configuration.
+ * configure.host: Ditto for host.
+
+2001-06-15 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (EXTRACT_STRUCT_VALUE_ADDRESS_P): Delete definition.
+ (EXTRACT_STRUCT_VALUE_ADDRESS): Change to a function with
+ predicate.
+ * gdbarch.h, gdbarch.c: Regenerate.
+ * values.c (value_being_returned): Change the reference to
+ EXTRACT_STRUCT_VALUE_ADDRESS_P to a function call.
+
+2001-06-15 Joel Brobecker <brobecker@act-europe.fr>
+
+ * MAINTAINERS: Add Paul Hilfinger and Joel Brobecker to the
+ Write After Approval list.
+
+2001-06-14 Michael Snyder <msnyder@redhat.com>
+
+ * remote.c (show_remote_protocol_qSymbol_packet_cmd,
+ set_remote_protocol_qSymbol_packet_cmd): New functions.
+ (init_all_packet_configs, show_remote_cmd): Add qSymbol packet.
+ (remote_check_symbols): New function. Implement qSymbol packet,
+ allowing target to request symbol lookup service from gdb.
+ (remote_open_1, remote_async_open_1): Call remote_check_symbols,
+ allowing symbol lookup from exec_bfd on connection to target.
+ (remote_new_objfile): New function. Catch new objfile notifications
+ from shared library module, and call remote_check_symbols.
+ (_initialize_remote): Hook remote_new_objfile into the shared
+ library notification chain. Add "set remote symbol-lookup" command.
+
+2001-06-14 Keith Seitz <keiths@redhat.com>
+
+ * tracepoint.c (trace_command): We now have tracepoint
+ events. Get rid of those ugly hooks.
+ (tracepoint_operation): Likewise.
+ (trace_pass_command): Likewise.
+
+2001-06-13 Michael Snyder <msnyder@redhat.com>
+
+ * gdbthread.h (struct thread_info): Add new fields:
+ current_line, current_symtab, step_sp, for saved infrun state.
+ * thread.c (save_infrun_state, load_infrun_state): Save and
+ restore current_line, current_symtab, and step_sp.
+ (add_thread): Rather than adding assignments to initialize
+ the new fields, just use memset (tp, 0, sizeof (*tp).
+ This way future new fields will not be overlooked.
+ * infrun.c (handle_inferior_event): Save and restore save_sp,
+ current_line, and current_symtab when switching threads.
+
+2001-06-13 Elena Zannoni <ezannoni@redhat.com>
+
+ * MAINTAINERS: Add Andrew Cagney as co-maintainer of
+ testsuite/gdb.mi.
+
+2001-06-11 Andrew Cagney <ac131313@redhat.com>
+
+ * symtab.c (lookup_symtab_1): Replace basename with lbasename.
+ (lookup_partial_symtab, file_matches): Ditto.
+ (make_source_files_completion_list): Ditto.
+ (make_file_symbol_completion_list): Ditto. Make local char*
+ variable ``tail'' constant.
+ (make_source_files_completion_list): Ditto with ``base_name''.
+ * source.c (open_source_file): Use lbasename. Make ``p'' const
+ char *.
+
+2001-06-13 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/i386/xm-go32.h (SLASH_P, ROOTED_P, SLASH_CHAR)
+ (SLASH_STRING): Remove unused definitions.
+ * config/i386/xm-cygwin.h: Likewise.
+
+2001-06-12 Andrew Cagney <ac131313@redhat.com>
+
+ * ui-out.c (ui_out_list_begin): Add parameter ``id''.
+ (make_cleanup_ui_out_list_begin_end): Ditto. Open the list.
+ * ui-out.h: Update declarations.
+
+Mon Jun 11 17:26:43 2001 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * source.c (openp): Make parameters ``path'' and ``string''
+ constant.
+ (openp): Use alloca to safely duplicate ``string''. Make local
+ variables ``p'' and ``p1'' constant. Delete char* casts.
+ * defs.h: Update.
+
+ * symtab.c (lookup_symtab_1): Make parameter ``name'' constant.
+ (lookup_symtab, lookup_partial_symtab): Ditto.
+ * symtab.h (lookup_symtab, lookup_partial_symtab): Update.
+
+2001-06-11 Andrew Cagney <ac131313@redhat.com>
+
+ * ui-out.h (ui_out_table_begin): Make char* parameters constant.
+ (ui_out_table_header, ui_out_field_int): Ditto.
+ (ui_out_field_core_addr, ui_out_field_string): Ditto.
+ (ui_out_field_stream, ui_out_field_fmt): Ditto.
+ (ui_out_field_skip, ui_out_text, ui_out_message): Ditto.
+ * ui-out.c (ui_out_table_begin, ui_out_table_header): Update.
+ (ui_out_field_core_addr, ui_out_field_stream): Update.
+ (ui_out_field_string, ui_out_field_fmt): Update.
+ (ui_out_text, ui_out_message): Update.
+ (append_header_to_list): Make char* parameters constant.
+ (uo_table_header, uo_table_begin): Ditto.
+ (uo_field_int, uo_field_skip): Ditto.
+ (uo_field_string, uo_field_fmt): Ditto.
+ (uo_text, uo_message): Ditto.
+
+2001-06-11 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * completer.c (gdb_completer_loc_break_characters): New variable.
+ (line_completion_function): If we are completing on locations,
+ back up the start of word pointer past all characters which can
+ appear in a location spec.
+ (location_completer): New function.
+
+ * completer.h: Add prototype for location_completer.
+
+ * symtab.c (make_source_files_completion_list)
+ (add_filename_to_list, not_interesting_fname): New functions.
+ (filename_seen): New function, body extracted from
+ output_source_filename.
+ (output_source_filename): Call filename_seen to check if the file
+ was already printed.
+ (make_symbol_completion_list): If TEXT includes a
+ double-quoted string, return an empty list, not NULL.
+ (make_file_symbol_completion_list): New function, similar to
+ make_symbol_completion_list but with an additional argument
+ SRCFILE.
+
+ * symtab.h (make_file_symbol_completion_list)
+ (make_source_files_completion_list): Add prototypes.
+
+ * breakpoint.c (_initialize_breakpoint): Make location_completer
+ be the completion function for all commands which set breakpoints
+ and watchpoints.
+ (top-level): #include "completer.h".
+
+ * tracepoint.c (_initialize_tracepoint): Make location_completer
+ be the completion function for the "trace" command.
+ (top-level): #include "completer.h".
+
+ * printcmd.c (_initialize_printcmd): Make location_completer be
+ the completion function for the "print", "inspect", "call", and
+ "disassemble" commands.
+ (top-level): #include "completer.h".
+
+ * infcmd.c (_initialize_infcmd): Make location_completer be the
+ completion function for the "go", "jump", and "until" commands.
+ (top-level): #include "completer.h".
+
+2001-06-10 Christopher Faylor <cgf@redhat.com>
+
+ * gnu-regex.c: Eliminate obsolete check for _MSC_VER.
+ * utils.c (notice_quit): Remove dummy function only used for _MSC_VER.
+ * values.c (unpack_double): Remove obsolete check for _MSC_VER.
+ * defs.h: Ditto.
+ * m32r-rom.c: Ditto.
+ * p-exp.y: Ditto.
+ * ser-e7kpc.c: Ditto. Define WIN32_LEAN_AND_MEAN under _WIN32, for
+ faster compilation.
+ (get_ds_base): Remove _MSC_VER version of this function.
+ * nindy-share/ttyflush.c: Ditto.
+ * rdi-share/host.h: Ditto.
+ * ser-go32.c (dos_readchar): Remove call to obsolete function.
+ * remote-sim.c (gdb_os_poll_quit): Ditto.
+ * remote-e7000.c (expect): Remove obsolete #if 0'ed code.
+
+ * main.c (captured_main): Eliminate special Cygwin checks.
+ * ser-tcp.c: Remove unneeded __CYGWIN__ guard against system include.
+
+2001-06-09 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in (gdbcmd_h): Add ui_out_h.
+ (breakpoint.o, infcmd.o, main.o, printcmd.o, stack.o): Ditto.
+ (thread.o, top.o): Ditto.
+
+ * ui-out.h (table_begin_ftype): Make string parameters constant.
+ (table_header_ftype): Ditto.
+ (field_int_ftype): Ditto.
+ (field_skip_ftype): Ditto.
+ (field_string_ftype): Ditto.
+ (field_fmt_ftype): Ditto.
+ (text_ftype): Ditto.
+ (message_ftype): Ditto.
+ * cli-out.c (cli_table_begin): Ditto.
+ (cli_table_header): Ditto.
+ (cli_field_int): Ditto.
+ (cli_field_skip): Ditto.
+ (cli_field_string): Ditto.
+ (cli_field_fmt): Ditto.
+ (cli_text): Ditto.
+ (cli_message): Ditto.
+ (out_field_fmt): Ditto.
+ * ui-out.c (default_table_begin): Ditto.
+ (default_table_header): Ditto.
+ (default_field_int): Ditto.
+ (default_field_skip): Ditto.
+ (default_field_string): Ditto.
+ (default_field_fmt): Ditto.
+ (default_text): Ditto.
+ (default_message): Ditto.
+
+2001-06-08 Michael Snyder <msnyder@redhat.com>
+
+ * breakpoint.c (delete_breakpoint): Pass mark_inserted to
+ remove_breakpoint, so that the subsequent test for
+ bpt->inserted will succeed, and duplicates will be fixed up.
+
+2001-06-08 Per Bothner <per@bothner.com>
+
+ * dwarf2read.c (set_cu_language): Handle DW_LANG_Java.
+
+2001-06-07 Keith Seitz <keiths@redhat.com>
+
+ * tracepoint.c (tracepoint_opertation): Add ui event
+ notifications.
+ (trace_pass_command): Ditto.
+
+2001-06-07 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS (Write After Approval): Note the entry criteria.
+ (HP/PA): Jeff Law stepped down
+
+2001-06-07 Jim Blandy <jimb@redhat.com>
+
+ * gdbarch.sh: Make sure that '[' doesn't interpret interesting
+ variable values as operators.
+
+2001-06-07 Keith Seitz <keiths@redhat.com>
+
+ * gdb-events.sh: Fix quote escaping which was obsoleted
+ by last patch.
+
+2001-06-07 Keith Seitz <keiths@redhat.com>
+
+ * gdb-events.sh: Make if statements and tests
+ a little more portable.
+ Don't use shell's echo command to put strings containing
+ escaped characeters into a file -- different flavors of /bin/sh
+ require differnt levels of escaping. Use cat <<EOF instead.
+ Our internal field separator is a colon. Change all
+ commands which assume it is a space.
+
+2001-06-06 Mark Kettenis <kettenis@gnu.org>
+
+ * lin-lwp.c (struct lwp_info): Add member `resumed'.
+ (iterate_over_lwps): Make sure we can handle CALLBACK deleting the
+ LWP it's called for.
+ (lin_lwp_attach): Mark LWP as resumed to make sure the fake
+ SIGSTOP is reported.
+ (resume_clear_callback): New function.
+ (resume_set_callback): New function.
+ (lin_lwp_resume): Mark all LWP's that we're going to resume as
+ resumed, and unmark all others.
+ (status_callback): Only report a pending wait status if we pretend
+ that LP has been resumed.
+ (resumed_callback): New function.
+ (lin_lwp_wait): Add assertions to check that LWP's are properly
+ marked as resumed. Partially revert 2001-05-25 patch by Michael
+ Snyder: do not resume all threads. Add comment explaining the
+ problems associated with this bit of code.
+
+2001-06-07 Keith Seitz <keiths@redhat.com>
+
+ * MAINTAINTERS: Syd Polk is stepping down from
+ maintaining libgui. I am replacing him.
+
+2001-06-07 Eli Zaretskii <elis@is.elta.co.il>
+
+ * config/mips/tm-irix6.h: New file.
+
+ * config/mips/irix6.mh: New file.
+
+ * config/mips/irix6.mt: New file.
+
+ * config/mips/xm-irix6.h: New file.
+
+ * config/mips/nm-irix6.h: New file.
+
+ * mips-tdep.c (mips_gdbarch_init) <MIPS_ABI_N32>: Set up the
+ disassembler info in tm_print_insn_info as appropriate for the N32
+ ABI. Force N32 ABI to be the default if the CPU is R8000 or
+ R10000.
+
+ * configure.tgt (mips*-sgi-irix6*): Map to irix6.
+
+ * configure.host (mips*-sgi-irix6*): Ditto.
+
+2001-06-07 Andrew Cagney <ac131313@redhat.com>
+
+ * gnu-v3-abi.c: Include "gdb_assert.h".
+ (build_gdb_vtable_type): Replace abort() with gdb_assert().
+
+2001-06-06 Jim Blandy <jimb@redhat.com>
+
+ * cp-abi.h: Rearrange code to put documentation comments above the
+ functions we export. The actual function table itself simply
+ refers to those functions. Minor doc fixes.
+
+ * gdbarch.sh: Changes to effect the following:
+ * gdbarch.c (initialize_non_multiarch): New function.
+ * gdbarch.h (initialize_non_multiarch): New declaration.
+ * arch-utils.c (initialize_current_architecture): For
+ non-multiarch configurations, call initialize_non_multiarch.
+
+2001-06-06 Andrew Cagney <ac131313@redhat.com>
+
+ * symfile.c (compare_psymbols): Replace PTR with void*. Delete
+ declaration.
+ (compare_symbols): Ditto.
+
+2001-06-06 Jonathan Larmour <jlarmour@redhat.com>
+
+ * arch-utils.c (generic_prepare_to_proceed): Allow for having
+ stopped due to a Ctrl-C as well as breakpoints.
+
+ * hppa-tdep.c (hppa_prepare_to_proceed): Add FIXME as this may not
+ support thread switches after Ctrl-C.
+ * lin-lwp.c (lin_lwp_prepare_to_proceed): Ditto.
+ * linux-thread.c (linuxthreads_prepare_to_proceed): Ditto.
+ * m3-nat.c (mach3_prepare_to_proceed): Ditto.
+
+2001-06-06 Jim Blandy <jimb@redhat.com>
+
+ * gdbarch.sh, gdbarch.c: Revert change of 2001-06-01; all
+ per-architecture data should be registered at initialization time,
+ before any gdbarch objects get used, so the generality is
+ unnecessary.
+
+2001-06-06 Keith Seitz <keiths@redhat.com>
+
+ * gdb-events.sh (function_list): Add tracepoint_create,
+ tracepoint_delete, and tracepoint_modify events.
+ * gdb-events.c: Regenerated.
+ * gdb-events.h: Regenerated.
+
+2001-06-06 Keith Seitz <keiths@redhat.com>
+
+ * gdb-events.sh: Update copyrights.
+ Change free to xfree.
+ * gdb-events.c: Regenerated.
+ * gdb-events.h: Regenerated.
+
+2001-06-06 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * source.c (mod_path, openp): Use #ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ instead of #if HAVE_DOS_BASED_FILE_SYSTEM.
+ * completer.c: Ditto.
+ * cli/cli-cmds.c (cd_command): Ditto.
+
+2001-06-04 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * mips-tdep.c (show_mipsfpu_command): Remove unused variable msg.
+ (mips_set_processor_type_command): Remove unused variable j.
+ (mips_breakpoint_from_pc): Declare breakpoint instruction
+ sequences as unsigned char, to avoid compiler warnings.
+
+ * source.c (mod_path, openp): Use HAVE_DOS_BASED_FILE_SYSTEM
+ instead of system-specific define's like _WIN32 and __MSDOS__.
+ Use IS_DIR_SEPARATOR and IS_ABSOLUTE_PATH instead of SLASH_P and
+ ROOTED_P.
+ (top-level): #include "filenames.h".
+
+ * solib.c (solib_open): Use IS_DIR_SEPARATOR and IS_ABSOLUTE_PATH
+ instead of SLASH_CHAR, ROOTED_P and SLASH_P.
+ (top-level): #include "filenames.h".
+
+ * defs.h (SLASH_P, SLASH_CHAR, ROOTED_P): Remove definitions.
+ (SLASH_STRING): Define only for _WIN32.
+
+ * completer.c: Use HAVE_DOS_BASED_FILE_SYSTEM instead of
+ __MSDOS_.
+
+ * cli/cli-cmds.c (cd_command): Use IS_DIR_SEPARATOR and
+ IS_ABSOLUTE_PATH instead of SLASH_P and ROOTED_P. Replace
+ system-specific ifdefs with HAVE_DOS_BASED_FILE_SYSTEM.
+ (top-level): #include "filenames.h".
+
+ * go32-nat.c (go32_wait): Change the return value to ptid_t.
+
+ * config/djgpp/fnchange.lst: Add two new files in the
+ gdb/testsuite/gdb.c++/ directory to the remapped names.
+
+ * config/djgpp/djconfig.sh (lt_cv_sys_max_cmd_len): Set to 12KB.
+
+2001-06-01 Jim Blandy <jimb@redhat.com>
+
+ Expand the gdbarch per-architecture data vector as needed, rather
+ than requiring that all per-architecture data be registered before
+ the first gdbarch object is allocated.
+ * gdbarch.sh: Changes to effect the following:
+ * gdbarch.c (alloc_gdbarch_data, init_gdbarch_data): Delete
+ declarations and definitions.
+ (check_gdbarch_data): New function, and declaration.
+ (gdbarch_alloc): Don't call alloc_gdbarch_data; leaving the fields
+ zero is good enough.
+ (free_gdbarch_data): Tolerate a null data pointer. Free only
+ those data items gdbarch->data actually has allocated.
+ (set_gdbarch_data, gdbarch_data): Call check_gdbarch_data.
+ (gdbarch_update_p): No need to call init_gdbarch_data.
+
+2001-06-01 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-tdep.c (is_float_or_hfa_type_recurse): Call check_typedef()
+ on types that we wish to recurse on.
+ (slot_alignment_is_next_even): New function.
+ (ia64_push_arguments): Call slot_alignment_is_next_even() to
+ examine the type in order to decide if it's necessary to skip
+ an odd slot.
+
+2001-06-01 Michael Snyder <msnyder@redhat.com>
+
+ * thread.c (delete_step_resume_breakpoint): New function.
+ Maintain internal consistency of the thread list while deleting
+ a step_resume_breakpoint.
+ * gdbthread.h (delete_step_resume_breakpoint): Export.
+ * breakpoint.c (bpstat_find_step_resume_breakpoint):
+ Make thread-aware: don't return a step_resume_breakpoint
+ for the wrong thread.
+ * infrun.c (wait_for_inferior): Call delete_step_resume_breakpoint
+ instead of delete_breakpoint_current_contents.
+ (fetch_inferior_event): Ditto.
+ (handle_inferior_event): Call delete_step_resume_breakpoint
+ instead of delete_breakpoint.
+ * infrun.c (handle_inferior_event): After singlestepping over a
+ thread-specific breakpoint, use currently_stepping() to decide
+ whether to step or continue.
+
+2001-06-01 Jim Blandy <jimb@redhat.com>
+
+ * gnu-v3-abi.c (gnu_v3_abi_ops, vtable_type_gdbarch_data): Make
+ these static --- there's no reason other files should use these.
+
+ * partial-stab.h (case N_FUN: case 'f':, case N_FUN: case 'F':)
+ Fix memory leak.
+
+ * partial-stab.h: New complaint: function_outside_compilation_unit.
+ (case N_FUN: case 'f':, case N_FUN: case 'F':): If pst is zero,
+ complain, and don't try to set pst's start address.
+
+2001-05-31 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-linux-tdep.c (IA64_LINUX_SIGCONTEXT_OFFSET): Revise to
+ match the location at which the kernel is placing the sigcontext
+ struct.
+
+ * ia64-tdep.c (max_skip_non_prologue_insns): New static global.
+ (refine_prologue_limit): New function.
+ (examine_prologue): Further limit number of instructions
+ scanned by calling refine_prologue_limit(). Revise way in
+ which the end of prologue address is computed for frameless
+ functions.
+
+2001-05-29 Christopher Faylor <cgf@redhat.com>
+
+ * partial-stab.h: Revert previous patch.
+
+2001-05-29 Christopher Faylor <cgf@redhat.com>
+
+ * partial-stab.h: Consistently guard against pst being NULL.
+
+2001-05-29 Alexandre Oliva <aoliva@redhat.com>
+
+ * symfile.c (compare_psymbols, compare_symbols): Declare using
+ PTR, as in the definition.
+ * minsyms.c (compare_minimal_symbols): Likewise.
+ * coffread.c (find_targ_sec): Likewise.
+ * elfread.c (free_elfinfo, elf_locate_sections): Likewise.
+ * mipsread.c (alphacoff_locate_sections): Likewise.
+ * mdebugread.c (compare_blocks): Likewise.
+
+2001-05-25 Nick Duffek <nsd@redhat.com>
+
+ * solib.c (update_solib_list): Move target_resize_to_sections()
+ into solib_map_sections() loop.
+ (info_sharedlibrary_command): Try bfd_arch_bits_per_address() if
+ bfd_get_arch_size() fails.
+
+2001-05-25 Nick Duffek <nsd@redhat.com>
+
+ * Makefile.in (osfsolib.c, osfsolib.o): Rename to solib-osf.c and
+ solib-osf.o.
+ * config/alpha/alpha-osf1.mh (NATDEPFILES): Replace osfsolib.o
+ with solib-osf.o and solib.o.
+ * config/alpha/alpha-osf2.mh: Likewise.
+ * config/alpha/alpha-osf3.mh: Likewise.
+ * solib-osf.c: New file, renamed and largely rewritten from
+ osfsolib.c.
+
+2001-05-25 Michael Snyder <msnyder@redhat.com>
+
+ * lin-lwp.c (lin_lwp_attach_lwp): Call stop_wait_callback,
+ to consume the SIGSTOP generated by PTRACE_ATTACH.
+ (stop_wait_callback): If a SIGTRAP or a SIGINT event is consumed,
+ try again to get the SIGSTOP event.
+ (lin_lwp_wait): Resume all threads when ignoring a signal.
+ This will insure that newly attached threads get resumed.
+ * lin-lwp.c (stop_wait_callback): Discard redundant SIGINT events.
+ * remote.c (remote_write_bytes): Update 'p' packet pointer.
+
+2001-05-25 Jim Blandy <jimb@redhat.com>
+
+ * gnu-v2-abi.c (gnuv2_virtual_fn_field): There's no need to clear
+ VALUE_POINTED_TO_OFFSET here; if value_cast doesn't return a
+ useful value, then we should fix that instead.
+
+2001-05-24 Nick Duffek <nsd@redhat.com>
+
+ * solist.h (struct so_list): Document the requirement that
+ current_sos initialize some fields to 0.
+
+2001-05-24 Mark Kettenis <kettenis@gnu.org>
+
+ * gnu-nat.c: Include <ctype.h>.
+ (gnu_pid_to_exec_file): Add PID parameter.
+ (set_sig_thread_cmd): Use PIDGET on return value from
+ thread_id_to_pid.
+ (proc_string): Use MERGEPID to construct argument to
+ pid_to_thread_id.
+
+2001-05-22 Kevin Buettner <kevinb@redhat.com>
+
+ * breakpoint.c (breakpoint_address_is_meaningful): New function.
+ (check_duplicates): Don't compare non-meaningful addresses.
+
+2001-05-22 Michael Snyder <msnyder@redhat.com>
+
+ * thread-db.c: Allow for defunct zombie threads.
+ (attach_thread): Do not attempt to attach zombie thread.
+ (thread_db_thread_alive): Return false for defunct zombie thread.
+ (find_new_threads_callback): Don't add defunct zombie thread to list.
+
+2001-05-22 Jim Blandy <jimb@redhat.com>
+
+ Add support for the GNU V3 C++ ABI.
+ (Includes changes by Dan Berlin.)
+
+ * gnu-v3-abi.c: New file.
+ * minsyms.c: #include "value.h" and "cp-abi.h".
+ (install_minimal_symbols): Check the minimal symbol table for
+ symbols that look mangled in the V3 style, and select the V3 ABI
+ if we find any.
+ * Makefile.in (SFILES): Add gnu-v3-abi.c.
+ (COMMON_OBS): Add gnu-v3-abi.o.
+ (gnu-v3-abi.o): Add new rule.
+ (minsyms.o): Depend on $(cp_abi_h) and $(value_h).
+
+2001-05-21 Jim Blandy <jimb@redhat.com>
+
+ * values.c (value_primitive_field): If we're extracting a base
+ class, then the type of the result should be the base class being
+ extracted, not the type of which it is a base class.
+
+ * value.h (struct value): Doc fix, and rearrange members to place
+ them near their explanations.
+
+2001-05-21 Michael Snyder <msnyder@redhat.com>
+
+ * remote.c (remote_async_wait): Added new variable fieldsize.
+ Add fieldsize (return value of hex2bin) to string pointer p.
+
+2001-05-20 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * m68hc11-tdep.c (m68hc11_pop_frame): Fix stack pointer computation.
+ (m68hc11_analyze_instruction): Update the pc correctly.
+ (m68hc11_guess_from_prologue): Take into account the stack correction
+ for the saving address.
+
+2001-05-07 Daniel Berlin <dan@cgsoftware.com>
+
+ Changes by Jim Ingham:
+
+ * values.c (value_change_enclosing_type): New function. If the
+ new enclosing type is larger than the old one, we need to allocate
+ more space.
+ * value.h: Add value_change_enclosing_type prototype.
+ * valops.c (value_cast): Use it.
+ (value_assign): Use it.
+ (value_addr): Use it.
+ (value_ind): Use it.
+ (value_full_object): Use it.
+
+2001-05-07 Daniel Berlin <dan@cgsoftware.com>
+
+ * values.c (value_static_field): Handle static fields that have a
+ constant value.
+
+2001-05-17 Michael Snyder <msnyder@redhat.com>
+
+ * blockframe.c (create_new_frame): Zero all the fields via memset,
+ rather than zeroing them one by one.
+
+2001-05-17 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * top.c (user_args): Remove unused declaration.
+
+2001-05-16 Michael Snyder <msnyder@redhat.com>
+
+ * infcmd.c (do_registers_info): Move alloca outside of loop.
+
+2001-05-15 John S Kallal <jskallal@home.com>
+
+ * remote.c (remote_wait): Added new variable fieldsize.
+ Add fieldsize (return value of hex2bin) to string pointer p.
+
+2001-05-15 Mark Kettenis <kettenis@gnu.org>
+
+ * sparc-tdep.c (sparc_gdbarch_init): Get the architecture from
+ info.bfd_arch_info.
+
+2001-05-14 Kevin Buettner <kevinb@redhat.com>
+
+ * lin-lwp.c (detach_callback, lin_lwp_wait, lin_lwp_pid_to_str):
+ Adjust format strings for printing LWPs to account for the fact
+ that the type returned by GET_LWP() is now a long instead of an
+ int.
+
+2001-05-14 Kevin Buettner <kevinb@redhat.com>
+
+ * inferior.h (null_ptid, minus_one_ptid): New variable declarations.
+ (ptid_build, pid_to_ptid, ptid_get_pid, ptid_get_lwp)
+ (ptid_get_tid, ptid_equal): New function declarations.
+ * infrun.c (null_ptid, minus_one_ptid): New variables.
+ (ptid_build, pid_to_ptid, ptid_get_pid, ptid_get_lwp)
+ (ptid_get_tid, ptid_equal): New functions.
+ (_initialize_infrun): Initialize null_ptid, minus_one_ptid,
+ inferior_ptid, and target_last_wait_ptid.
+
+ * defs.h (ptid_t): Redefine to be a struct rather than an int.
+ (pid_to_ptid, null_ptid, ptid_equal): Delete these macros.
+ (PIDGET, TIDGET, MERGEPID): Redefine these macros using the
+ new ptid accessors and constructor.
+
+ * config/i386/tm-i386v42mp.h (PIDGET, TIDGET, LIDGET, MERGEPID,
+ MKLID, MKTID, ISTID): Provide new definitions for these macros.
+ The old macros are retained, but disabled via #if 0 in order
+ to aid in future restructuring. See FIXME.
+
+ * arm-linux-nat.c (PIDGET, TIDGET): Delete macro definitions.
+ * i386-linux-nat.c (PIDGET, TIDGET): Likewise.
+ * infptrace.c (PIDGET, TIDGET): Likewise.
+ * lin-lwp.c (PIDGET0, PIDGET, TIDGET, MERGEPID): Likewise.
+ * lin-thread.c (PIDGET0, PIDGET, TIDGET, MERGEPID): Likewise.
+ * proc-service.c (MERGEPID): Likewise.
+ * procfs.c (PIDGET, TIDGET, MERGEPID): Likewise.
+ * thread-db.c (PIDGET0, PIDGET, TIDGET, MERGEPID): Likewise.
+ * config/nm-linux.h (PIDGET0, PIDGET, TIDGET, MERGEPID): Likewise.
+ * config/i386/tm-i386sol2.h (PIDGET0, PIDGET, TIDGET, MERGEPID):
+ Likewise.
+ * config/sparc/tm-sun4sol2.h (PIDGET0, PIDGET, TIDGET, MERGEPID):
+ Likewise.
+
+ * lin-lwp.c (THREAD_FLAG): Delete macro definition.
+ (GET_LWP): Redefine in terms of ptid_get_lwp().
+ (GET_PID): Redefine in terms of ptid_get_pid().
+ (is_lwp): Redefine without the need for THREAD_FLAG.
+ (BUILD_LWP): Redefine in terms of ptid_build().
+ * lin-thread.c (THREAD_FLAG): Delete macro definition.
+ (GET_LWP): Redefine in terms of ptid_get_lwp().
+ (GET_PID): Redefine in terms of ptid_get_pid().
+ (GET_THREAD): Redefine in terms of ptid_get_tid().
+ (BUILD_THREAD, BUILD_LWP): Redefine in terms of ptid_build().
+ (is_lwp, is_thread): Redefine.
+ (linux_child_wait, check_all_signal_numbers)
+ (linuxthreads_discard_global_state, attach_thread): Declare these
+ functions to squash warnings about missing declarations.
+ * sol-thread.c (THREAD_FLAG): Delete macro definition.
+ (GET_PID): Redefine in terms of ptid_get_pid().
+ (GET_LWP): Redefine in terms of ptid_get_lwp().
+ (GET_THREAD): Redefine in terms of ptid_get_tid().
+ (BUILD_THREAD, BUILD_LWP): Redefine in terms of ptid_build().
+ (is_lwp, is_thread): Redefine.
+ * thread-db.c (THREAD_FLAG): Delete macro definition.
+ (GET_PID): Redefine in terms of ptid_get_pid().
+ (GET_LWP): Redefine in terms of ptid_get_lwp().
+ (GET_THREAD): Redefine in terms of ptid_get_tid().
+ (BUILD_THREAD, BUILD_LWP): Redefine in terms of ptid_build().
+ (is_lwp, is_thread): Redefine.
+
+ * corelow.c (add_to_thread_list, get_core_register_section):
+ Eliminate hacks needed to prevent regressions when inferior_ptid
+ wasn't wide enough to hold the core file thread id in the pid
+ component of inferior_ptid.
+
+2001-05-14 Michael Snyder <msnyder@redhat.com>
+
+ * remote.c (hex2bin): Make first argument const.
+ Require explicit count, don't accept null-terminated str.
+ (remote_resume, remote_async_resume): White space fix-up.
+ (remote_write_bytes): Set nr_bytes to return value of bin2hex.
+
+2001-05-13 Mark Kettenis <kettenis@gnu.org>
+
+ * symtab.c (lookup_symtab_1): Use lbasename (NAME) instead of
+ basename (NAME). The FreeBSD basename returns a pointer to a
+ static buffer, even if it's simply returning a string identical to
+ its argument.
+ (lookup_partial_symtab): Likewise.
+
+2001-05-14 Michael Snyder <msnyder@redhat.com>
+
+ * solib.c, solib.h: Add comment for function no_shared_libraries.
+
+2001-05-14 Kevin Buettner <kevinb@redhat.com>
+
+ * solib.h (no_shared_libraries): Make declaration match definition
+ in solib.c.
+
+2001-05-14 Andrew Cagney <ac131313@redhat.com>
+
+ * remote.c (remote_write_bytes): Set nr_bytes before returning it.
+ * solib.h (no_shared_libraries): Declare.
+
+2001-05-12 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (struct gdbarch_info): Delete field bfd_architecture.
+ (gdbarch_update_p): Rewrite logic filling in INFO struct. Use
+ user specified values when available.
+ * rs6000-tdep.c (rs6000_gdbarch_init): Update. Get the
+ architecture from info.bfd_arch_info.
+ * gdbarch.c, gdbarch.h: Regenerate.
+
+2001-05-12 Fernando Nasser <fnasser@redhat.com>
+
+ * remote-e7000.c (e7000_open): Check for bad baud rate.
+ * remote-st.c (st2000_open): Ditto.
+
+2001-05-11 Jim Blandy <jimb@redhat.com>
+
+ * thread.c (do_captured_list_thread_ids): Use ui_out_tuple_begin
+ and ui_out_tuple_end instead of ui_out_list_begin and
+ ui_out_list_end.
+
+ * Makefile.in (gnu-v2-abi.o): Add $(demangle_h) to list of
+ dependencies. Reorder dependencies to match #includes in file,
+ for easier verification.
+
+Fri May 11 13:32:50 2001 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * breakpoint.c: Replace ui_out_list_begin, ui_out_list_end and
+ make_cleanup_ui_out_list_end with ui_out_tuple_begin,
+ ui_out_tuple_end and make_cleanup_ui_out_tuple_begin_end.
+ * cli/cli-setshow.c: Ditto.
+ * printcmd.c: Ditto.
+ * stack.c: Ditto.
+
+ * ui-out.h (enum ui_out_type): Fix tipo - tupple -> tuple.
+ * ui-out.c (ui_out_list_begin): Delete ``lstid'' parameter.
+ (ui_out_tuple_begin): New function.
+ (ui_out_tuple_end): New function.
+ (ui_out_tuple_begin_end): New function.
+ (make_cleanup_ui_out_list_begin_end): Replace
+ make_cleanup_ui_out_list_end function.
+ * ui-out.h (ui_out_list_begin): Update declaration.
+ (make_cleanup_ui_out_list_begin_end): Replace
+ make_cleanup_ui_out_list_end declaration.
+ (ui_out_tuple_begin, ui_out_tuple_end): Declare.
+ (ui_out_tuple_begin_end): Declare.
+
+2001-05-11 Jim Blandy <jimb@redhat.com>
+
+ * gnu-v2-abi.c: Don't #include "gdb_regex.h". We don't use it.
+
+2001-05-11 Andrew Cagney <ac131313@redhat.com>
+
+ From 2001-03-26 Rodney Brown <RodneyBrown@mynd.com>
+ * config/pa/tm-hppa.h: Remove trigraph.
+ * hp-symtab-read.c (hpread_type_translate): Provide return value.
+ (hpread_read_struct_type): Remove trigraph. Add parameter in
+ `warning'.
+ (hpread_read_array_type): Provide return value.
+ (hpread_type_lookup): Avoid ambiguous `else'. Provide return
+ value.
+ * hppa-tdep.c (initialize_hp_cxx_exception_support): Remove
+ trigraph.
+
+2001-05-11 Jim Blandy <jimb@redhat.com>
+
+ * mips-tdep.c (mips_store_return_value,
+ mips_extract_return_value): Pass arguments to
+ return_value_location in the proper order.
+
+2001-05-11 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in (VERSION): Delete. Moved to file ``version.in''.
+ (version.c): Depends on file ``version.in''. Extract version
+ number from ``version.in'' file.
+ (clean mostlyclean): Update.
+ * version.in: New file.
+ * NEWS: Update.
+
+2001-05-11 Kevin Buettner <kevinb@redhat.com>
+
+ * breakpoint.c (set_raw_breakpoint): Add new parameter
+ representing the breakpoint's type. Adjust all callers.
+ (create_longjmp_breakpoint, create_temp_exception_breakpoint)
+ (create_thread_event_breakpoint): Don't test for zero return
+ value from set_raw_breakpoint(). It can never be zero.
+ (create_exception_catchpoint, watch_command_1): Move logic
+ which calculates the breakpoint type prior to the call to
+ set_raw_breakpoint().
+
+2001-05-11 Fernando Nasser <fnasser@redhat.com>
+
+ * ser-unix.c (rate_to_code): Issue warning if baud rate is invalid.
+ (hardwire_setbaudrate): Set errno to EINVAL and return with error
+ if the conversion of the baud rate to code fails.
+
+2001-05-10 Andrew Cagney <ac131313@redhat.com>
+
+ * ui-out.h (make_cleanup_ui_out_begin_end): Declare.
+ * ui-out.c (struct ui_out_end_cleanup_data): Define.
+ (do_cleanup_end): New function. Replace do_list_end.
+ (make_cleanup_ui_out_end): New function.
+ (make_cleanup_ui_out_begin_end): New function.
+ (make_cleanup_ui_out_list_end): Use make_cleanup_ui_out_end.
+
+2001-05-10 Elena Zannoni <ezannoni@redhat.com>
+
+ * MAINTAINERS: Declare xcoffread.c open to all maintainers,
+ and make Kevin Buettner (kevinb@redhat.com) the reference person.
+
+2001-05-10 Elena Zannoni <ezannoni@redhat.com>
+
+ * proc-api.c (ioctl_with_trace): Fix uninitialized variable.
+
+2001-05-10 Fernando Nasser <fnasser@redhat.com>
+
+ * MAINTAINERS: Add testsuite subdirectory co-maintainers.
+
+Thu May 10 16:26:47 2001 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (mi-main.o): Compile with -Werror.
+
+2001-05-10 Michael Snyder <msnyder@redhat.com>
+
+ * remote.c (remote_open_1): Call no_shared_libraries, so that
+ symbols for shared libraries can be reloaded per session.
+ (remote_async_open_1): Ditto.
+ * remote.c (bin2hex, hex2bin): New functions. Factor out these
+ two conversions which are coded for repeatedly in this module.
+ (remote_threads_extra_info, remote_wait, remote_async_wait,
+ store_register_using_P, remote_store_registers, remote_write_bytes,
+ remote_read_bytes, remote_rcmd): Use bin2hex and hex2bin instead
+ of coding the conversions inline.
+ (fromhex): Not exported, change from extern to static.
+
+2001-05-10 Andrew Cagney <ac131313@redhat.com>
+
+ * arch-utils.c (initialize_current_architecture): Delete obsolete
+ ``info architecture'' command.
+ (info_architecture): Delete function.
+
+2001-05-10 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO (5.1, 5.2): Update.
+
+2001-05-09 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Jim Ingham is no longer maintaining Arm related
+ stuff.
+
+2001-05-10 Keith Seitz <keiths@cygnus.com>
+
+ * Makefile.in (SUBDIR_GDBTK_OBS): Add gdbtk-bp.o, gdbtk-register.o
+ and gdbtk-stack.o.
+ (SUBDIR_GDBTK_SRCS): Ditto for the sources.
+ (gdbtk-bp.o): New rule.
+ (gdbtk-register.o): New rule.
+ (gdbtk-stack.o): New rule.
+ (gdbtk-cmds.o): Update dependencies.
+ (gdbtk.o): Ditto.
+ (gdbtk-hooks.o): Ditto.
+ (gdbtk-varobj.o): Ditto.
+
+2001-05-10 Fernando Nasser <fnasser@redhat.com>
+
+ * varobj.c (c_number_of_children): Fix memory leak. Delete unwanted old
+ variables, not just unregister them.
+
+2001-05-10 Fernando Nasser <fnasser@redhat.com>
+
+ * varobj.c (c_number_of_children): Check for target type of void*,
+ not the target type name. Allow dereferencing char*.
+
+2001-05-10 Fernando Nasser <fnasser@redhat.com>
+
+ * symfile.c (symbol_file_add_main_1): New static function.
+ Passes the flags arguments to symbol_file_add() and takes care
+ of any necessary reinitializations.
+ (symbol_file_command): Call symbol_file_add_main_1() instead of
+ symbol_file_add().
+ (symbol_file_add_main): Ditto.
+
+2001-05-09 Kevin Buettner <kevinb@redhat.com>
+
+ * lin-lwp.c (lin_lwp_pid_to_str): Revert inadvertent format
+ string change in 2001-05-03 changes.
+ (lin_lwp_wait): Revert GET_LWP coercion introduced in 2001-05-03
+ changes.
+
+2001-05-09 Kevin Buettner <kevinb@redhat.com>
+
+ * lin-lwp.c (lin_lwp_attach): Use PIDGET() to fetch the pid
+ component from inferior_ptid.
+ (lin_lwp_detach): Use pid_to_ptid() to convert from a pid to a
+ ptid.
+
+2001-05-09 Elena Zannoni <ezannoni@redhat.com>
+
+ * sh3-rom.c (_initialize_sh3_rom): Get rid of specific _WINDOWS
+ conditional for help with connections through parallel ports,
+ given that the actual code for downloading through a parallel port
+ is not conditionalized.
+
+ * sh-tdep.c: Remove WIN32_WCE conditional. The wince sh target is
+ unmaintaned, and probably on its way to obsolescence.
+
+2001-05-09 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-tdep.c (i386_frame_saved_pc): New function.
+ * config/i386/tm-i386.h (FRAME_SAVED_PC): Redefine in terms of
+ i386_frame_saved_pc.
+ (i386_frame_saved_pc): New prototype.
+
+ * i386-tdep.c (i386_register_virtual_type): New function.
+ (i386_register_convertible): New function.
+ * config/i386/tm-i386.h (REGISTER_VIRTUAL_TYPE): Redefine in terms
+ of i386_register_virtual_type.
+ (REGISTER_CONVERTIBLE): Redefine in terms of
+ i386_register_convertible.
+ (i386_register_virtual_type, i386_register_convertible): New
+ prototypes.
+
+2001-05-08 Jim Blandy <jimb@redhat.com>
+
+ * Makefile.in (mn10300-tdep.o): New rule.
+
+ * Makefile.in (gdb_string_h): Define. Use it throughout.
+ Some rules were already using this, even though it isn't defined.
+
+ * Makefile.in (obstack_h, target_h): Define; these are already
+ used elsewhere, but have been expanding to the empty string.
+ (memattr_h): Define; needed by target_h.
+
+ * mn10300-tdep.c (mn10300_extract_return_value): Mark this as
+ static. (This was accidentally omitted from the earlier patch.)
+
+ * mn10300-tdep.c (mn10300_dwarf2_reg_to_regnum): New function.
+ (mn10300_gdbarch_init): Register it as the architecture's
+ dwarf2_reg_to_regnum method.
+
+ Correct and expand handling of `movm' instruction, and register
+ saves in general.
+ * config/mn10300/tm-mn10300.h (D0_REGNUM, A0_REGNUM, MDRQ_REGNUM,
+ MCRH_REGNUM, MCRL_REGNUM, MCVF_REGNUM): New definitions.
+ (enum movm_register_bits): New enum.
+ * mn10300-tdep.c (set_movm_offsets): Use symbolic names for the
+ bits, not hex literals. Handle the `other', `exreg0', and
+ `exother' bits. Correct handling of `exreg1': it saves r4, r5,
+ r6, and r7, not r2, r3, r4, and r5.
+ (saved_regs_size): New function.
+ (mn10300_frame_chain, mn10300_frame_saved_pc): Use it, instead
+ of computing the same thing inline, incorrectly.
+
+ * mn10300-tdep.c (mn10300_gdbarch_init): We do have a
+ dummy_breakpoint_offset; it's zero.
+
+ * mn10300-tdep.c (mn10300_pop_frame): Split the mn10300-specific
+ stuff out into mn10300_pop_frame_regular, and use
+ generic_pop_current_frame. This lets us share code, and also
+ makes this function's prototype match that expected by gdbarch.
+ Make this function static.
+ (mn10300_pop_frame_regular): New function.
+ (mn10300_gdbarch_init): Register mn10300_pop_frame as the
+ gdbarch's pop_frame method.
+ * config/mn10300/tm-mn10300.h (POP_FRAME): Delete definition.
+ (mn10300_pop_frame): Delete declaration.
+
+ * mn10300-tdep.c (mn10300_saved_pc_after_call,
+ mn10300_extract_return_value,
+ mn10300_extract_struct_value_address, mn10300_store_return_value,
+ mn10300_use_struct_convention, mn10300_breakpoint_from_pc,
+ mn10300_frame_chain, mn10300_skip_prologue,
+ mn10300_push_arguments, mn10300_push_return_address,
+ mn10300_store_struct_return, mn10300_frame_saved_pc,
+ mn10300_init_extra_frame_info, mn10300_frame_init_saved_regs):
+ Make these functions static; they should only be visible to the
+ outside world as gdbarch methods.
+
+ * config/mn10300/tm-mn10300.h (mn10300_find_callers_reg): Delete
+ unused declaration.
+
+ * mn10300-tdep.c (mn10300_gdbarch_init): Put the gdbarch methods
+ in some rational order.
+
+ * mn10300-tdep.c (mn10300_gdbarch_init): Rather than using
+ generic_pc_in_call_dummy, use pc_in_call_dummy_at_entry_point.
+
+ Use gdbarch for most target parameters for the MN10300, rather
+ than the tm-*.h file.
+ * config/mn10300/tm-mn10300.h (MAX_REGISTER_VIRTUAL_SIZE,
+ REGISTER_BYTES, FP_REGNUM, BREAKPOINT_FROM_PC,
+ FUNCTION_START_OFFSET, DECR_PC_AFTER_BREAK, INNER_THAN,
+ SAVED_PC_AFTER_CALL, INIT_EXTRA_FRAME_INFO, FRAME_INIT_SAVED_REGS,
+ FRAME_CHAIN, FRAME_CHAIN_VALID, FRAME_SAVED_PC,
+ EXTRACT_RETURN_VALUE, EXTRACT_STRUCT_VALUE_ADDRESS,
+ STORE_RETURN_VALUE, STORE_STRUCT_RETURN, SKIP_PROLOGUE,
+ FRAME_ARGS_SKIP, FRAME_ARGS_ADDRESS, FRAME_LOCALS_ADDRESS,
+ FRAME_NUM_ARGS, POP_FRAME, USE_GENERIC_DUMMY_FRAMES, CALL_DUMMY,
+ CALL_DUMMY_START_OFFSET, CALL_DUMMY_BREAKPOINT_OFFSET,
+ CALL_DUMMY_LOCATION, FIX_CALL_DUMMY, CALL_DUMMY_ADDRESS,
+ TARGET_READ_FP, PUSH_RETURN_ADDRESS, PUSH_DUMMY_FRAME,
+ SAVE_DUMMY_FRAME_TOS, PUSH_ARGUMENTS, PC_IN_CALL_DUMMY,
+ REG_STRUCT_HAS_ADDR, USE_STRUCT_CONVENTION, GET_SAVED_REGISTER):
+ Delete definitions. We register gdbarch methods for these now.
+ (struct frame_info, struct type, struct value): Delete forward
+ declarations of these types; they're no longer necessary, since we
+ don't have function declarations here any more.
+ * mn10300-tdep.c: #include "arch-utils.h", to get declarations for
+ some default gdbarch methods.
+ (mn10300_store_struct_return): Return void, as expected by
+ gdbarch.
+ (mn10300_init_extra_frame_info): Take initial `fromleaf' argument,
+ as expected by gdbarch.
+ (mn10300_frame_init_saved_regs): Provide dummy definition for
+ this, as required by gdbarch.
+ (mn10300_gdbarch_init): Add mn10300_call_dummy_words, as expected
+ by gdbarch. Register gdbarch methods or values for all the stuff
+ removed from tm-10300.h, listed above.
+
+2001-05-08 Andrew Cagney <ac131313@redhat.com>
+
+ * cli-out.c (cli_begin, cli_end): Replace cli_list_begin and
+ cli_list_end.
+ (cli_ui_out_impl): Update.
+
+ * ui-out.c (default_begin, default_end): Replace
+ default_list_begin and default_list_end.
+ (default_ui_out_impl): Update.
+ (uo_begin, uo_end): Replace ou_list_begin and uo_list_end.
+ (ui_out_begin, ui_out_end): Replace ui_out_list_begin and
+ ui_out_list_end.
+ (ui_out_list_begin, ui_out_list_end): New. Compatibility
+ functions.
+ (struct ui_out_level): Add field type.
+ (push_level, pop_level): Update. Add type parameter.
+
+ * ui-out.h (enum ui_out_type): Declare.
+ (ui_out_begin, ui_out_end): Declare.
+ (ui_out_begin_ftype, ui_out_end_ftype): Replace list_begin_ftype
+ and list_end_ftype.
+ (struct ui_out_impl): Update.
+
+2001-05-07 Andrew Cagney <ac131313@redhat.com>
+
+ * ui-out.h (list_begin_ftype, list_end_ftype): Rename argument
+ ``list_flag'' to ``depth''.
+ * ui-out.c (default_list_begin, default_list_end): Update.
+ (uo_list_begin, uo_list_end): Update.
+ (MAX_UI_OUT_LEVELS): Define.
+ (struct ui_out_level): Define.
+ (top-level): Include "gdb_assert.h".
+ (struct ui_out): Add fields ``level'' and ``levels''. Delete
+ fields ``list_flag'' and ``field_count''.
+ (ui_out_new): Update.
+ (verify_field_proper_position): Update.
+ (current_level, push_level, pop_level): New functions.
+ (ui_out_list_begin): Use push_level.
+ (ui_out_list_end): Use pop_level.
+ (ui_out_field_int): Use current_level.
+ (ui_out_field_skip): Ditto.
+ (ui_out_field_fmt): Ditto.
+
+2001-05-08 Michael Snyder <msnyder@redhat.com>
+
+ * language.c (longest_local_hex_string_custom): Strlen test is
+ inverted -- reverse the sense of the test.
+
+2001-05-08 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-i386v.h (struct frame_info, struct
+ frame_saved_regs): Remove declarations.
+ (i386_frame_num_args): Remove prototype.
+
+2001-05-07 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: I'm no longer actively maintaining the mn10300
+ target.
+
+2001-05-04 Andrew Cagney <ac131313@redhat.com>
+
+ * main.c (captured_main): Delete #ifndef _WIN32 conditional for
+ WinGDB.
+
+2001-05-06 Kevin Buettner <kevinb@redhat.com>
+
+ * inferior.h (save_inferior_ptid): Declare.
+ * infrun.c (save_inferior_ptid, restore_inferior_ptid): Define.
+
+ * hpux-thread.c (save_inferior_ptid, restore_inferior_ptid):
+ Delete these functions.
+ * lin-lwp.c (save_inferior_ptid, restore_inferior_ptid): Likewise.
+ * lin-thread.c (save_inferior_ptid, restore_inferior_ptid): Likewise.
+ * linux-thread.c (save_inferior_ptid, restore_inferior_ptid):
+ Likewise.
+ * proc-service.c (save_inferior_ptid, restore_inferior_ptid):
+ Likewise.
+ * sol-thread.c (save_inferior_ptid, restore_inferior_ptid): Likewise.
+ * thread-db.c (save_inferior_ptid, restore_inferior_ptid): Likewise.
+
+ * somsolib.c (reset_inferior_ptid): Delete.
+ (som_solib_remove_inferior_hook): Use save_inferior_ptid() to
+ build the cleanup struct.
+
+ * breakpoint.c (reattach_breakpoints, detach_breakpoints): Use
+ a cleanup to save/restore inferior_ptid.
+
+2001-05-06 Mark Kettenis <kettenis@gnu.org>
+
+ Implement attach/detach for multi-threaded programs on Linux.
+ * thread-db.c (keep_thread_db): Adjust comment.
+ (deactivate_target): Removed.
+ (thread_db_new_objfile): Don't call deactivate_target. Implement
+ guts of deactivate_target inline instead.
+ (attach_thread): Call ATTACH_LWP unconditionally if defined.
+ (thread_db_attach): New function.
+ (thread_db_detach): Don't call deactivate_target. Do necessary
+ cleanup inline instead. Set inferior_ptid to LWP corresponding to
+ the current user-level thread.
+ (thread_db_kill): Set inferior_ptid to LWP corresponding to the
+ current user-level thread.
+ (thread_db_create_inferior): Deactivate target vector if
+ KEEP_THREAD_DB is zero.
+ (thread_db_mourn_inferior): Don't call deactivate_target. Do
+ necessary cleanup inline instead.
+ (init_thread_db_ops): Initialize to_attach field to
+ thread_db_attach.
+ * lin-lwp.c (lin_lwp_mourn_inferior): Remove prototype.
+ (stop_wait_callback): Add prototype.
+ (init_lwp_list): Add comment about when to re-initialize the LWP
+ list.
+ (lin_lwp_attach_lwp): Only call ptrace for cloned processes.
+ Avoid adding publicates to the LWP list. Only mark an LWP as
+ signalled if it doesn't correspond to a cloned process.
+ (lin_lwp_attach): Add initial process to the LWP list. Make sure
+ it's stopped and fake a SIGSTOP.
+ (detach_callback): New function.
+ (lin_lwp_detach): Implement.
+ (lin_lwp_create_inferior): Don't re-initialize LWP list here.
+ Call child_ops.to_create_inferior directly instead of via
+ target_beneath local.
+ (lin_lwp_mourn_inferior): Call child_ops.to_mourn_inferior
+ directly instead of via target_beneath local.
+
+2001-05-06 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * symtab.c (lookup_symtab_1, lookup_partial_symtab): Use basename
+ instead of non-portable search for `/'. Use FILENAME_CMP instead
+ of STREQ, to account for case-insensitive filesystems.
+ (top-level): #include "filenames.h".
+
+2001-05-05 Jim Blandy <jimb@redhat.com>
+
+ * breakpoint.c (check_duplicates): Use the breakpoint's type, not
+ its address, to decide whether it's a watchpoint or not. Zero
+ is a valid code address.
+ (update_breakpoints_after_exec): Admonishing comments.
+ * breakpoint.h (struct breakpoint): Doc fixes.
+
+ * breakpoint.c (check_duplicates): Take a breakpoint object as an
+ argument, rather than an address and section. All callers changed.
+
+2001-05-03 Kevin Buettner <kevinb@redhat.com>
+
+ * defs.h (ptid_t): New typedef.
+ (pid_to_ptid, null_ptid, minus_one_ptid, ptid_equal): New macros.
+
+ * a68v-nat.c, alphabsd-nat.c, arch-utils.c, arm-linux-nat.c,
+ blockframe.c, breakpoint.c, breakpoint.h,
+ config/i386/nm-i386sol2.h, config/i386/tm-i386sco5.h,
+ config/ia64/nm-linux.h, config/m68k/nm-hp300bsd.h,
+ config/mips/nm-irix4.h, config/mips/nm-irix5.h,
+ config/pa/nm-hppah.h, config/pa/tm-hppa.h,
+ config/rs6000/nm-rs6000.h, config/sparc/nm-sun4sol2.h,
+ corelow.c, cxux-nat.c, d10v-tdep.c, dink32-rom.c,
+ dve3900-rom.c, fork-child.c, frame.c, gnu-nat.c, go32-nat.c,
+ hp300ux-nat.c, hppa-tdep.c, hppab-nat.c, hppah-nat.c,
+ hpux-thread.c, i386-linux-nat.c, i386aix-nat.c, i386b-nat.c,
+ i386bsd-nat.c, i386gnu-nat.c, i386mach-nat.c, i386nbsd-nat.c,
+ infcmd.c, inferior.h, inflow.c, infptrace.c, infrun.c,
+ inftarg.c, infttrace.c, lin-lwp.c, lin-thread.c,
+ linux-thread.c, lynx-nat.c, m3-nat.c, m32r-rom.c,
+ m68knbsd-nat.c, m88k-nat.c, mac-nat.c, mips-nat.c,
+ mon960-rom.c, monitor.c, ns32knbsd-nat.c, ocd.c, ppc-bdm.c,
+ ppcnbsd-nat.c, proc-service.c, procfs.c, ptx4-nat.c,
+ regcache.c, remote-adapt.c, remote-array.c, remote-bug.c,
+ remote-e7000.c, remote-es.c, remote-mips.c, remote-mm.c,
+ remote-nindy.c, remote-os9k.c, remote-rdi.c, remote-rdp.c,
+ remote-sds.c, remote-sim.c, remote-st.c, remote-udi.c,
+ remote-vx.c, remote.c, rs6000-nat.c, sol-thread.c,
+ solib-aix5.c, solib-svr4.c, somsolib.c, sparc-nat.c,
+ standalone.c, sun3-nat.c, sun386-nat.c, symm-nat.c, target.c,
+ target.h, thread-db.c, thread.c, top.c, ultra3-nat.c,
+ uw-thread.c, v850ice.c, win32-nat.c, wince.c, xcoffsolib.c
+ (inferior_pid): Rename to inferior_ptid everywhere - even in
+ comments and obsolete ports. In cases where this variable
+ really is supposed to be used as a process id, use PIDGET() to
+ extract the process id component from inferior_ptid. The
+ other cases, either involving other variables whose types had
+ to be changed or functions whose signatures had to changed
+ are listed separately below.
+
+ * arm-linux-nat.c (get_thread_id): Change type of argument
+ representing a combined process/thread id from ``int'' to
+ ``ptid_t''. Also change parameter name to ptid.
+ * breakpoint.h, breakpoint.c (breakpoint_thread_match): Likewise.
+ * corelow.c (core_file_thread_alive): Likewise.
+ * d10v-tdep.c (d10v_read_pc, d10v_write_pc): Likewise.
+ * defs.h (*target_wait_hook): Likewise.
+ * gdbthread.h (thread_info, delete_thread, pid_to_thread_id)
+ (find_thread_pid, save_infrun_state, load_infrun_state): Likewise.
+ * gnu-nat.c (gnu_thread_alive, gnu_pid_to_str, gnu_wait)
+ (gnu_resume): Likewise.
+ * go32-nat.c (go32_wait, go32_resume): Likewise.
+ * h8500-tdep.c (h8500_read_pc, h8500_write_pc): Likewise.
+ * hppa-tdep.c (target_read_pc, target_write_pc): Likewise.
+ * hppah-nat.c (child_pid_to_str, hppa_tid_to_str,
+ (hppa_pid_or_tid_to_str, child_post_startup_inferior)
+ (child_thread_alive): Likewise.
+ * hpux-thread.c (hpux_thread_notice_signals, hpux_thread_alive)
+ (hpux_pid_to_str, hpux_thread_wait, hpux_thread_resume): Likewise.
+ * i386-linux-nat.c (child_resume): Likewise.
+ * ia64-linux-nat.c (enable_watchpoints_in_psr, fetch_debug_register)
+ (store_debug_register, fetch_debug_register_pair)
+ (store_debug_register_pair, ia64_linux_insert_watchpoint)
+ (ia64_linux_remove_watchpoint, ia64_linux_stopped_by_watchpoint):
+ Likewise.
+ * ia64-tdep.c (ia64_read_pc, ia64_write_pc): Likewise.
+ * inferior.h (read_pc_pid, generic_target_read_pc, write_pc_pid)
+ (generic_target_write_pc, ptrace_wait, child_resume)
+ (get_last_target_status): Likewise.
+ * infptrace.c (ptrace_wait, child_resume): Likewise.
+ * inftarg.c (child_wait, child_post_wait, child_thread_live)
+ (child_pid_to_str): Likewise.
+ * infttrace.c (ptrace_wait, child_thread_alive, child_resume)
+ (hppa_pid_or_tid_to_str, child_post_startup_inferior): Likewise.
+ * lin-lwp.c (add_lwp, delete_lwp, find_lwp_pid, lin_lwp_attach_lwp)
+ (lin_lwp_resume, lin_lwp_wait, lin_lwp_thread_alive)
+ (lin_lwp_pid_to_str): Likewise.
+ * lin-thread.c (thread_db_alive, thread_db_pid_to_str)
+ (thread_db_resume, thread_db_wait): Likewise.
+ * linux-thread.c (linuxthreads_thread_alive, linuxthreads_pid_to_str)
+ (linuxthreads_resume, linuxthreads_wait): Likewise.
+ * lynx-nat.c (child_wait, child_thread_alive, child_resume)
+ (child_pid_to_str): Likewise.
+ * m3-nat.c (mach_really_wait, m3_resume): Likewise.
+ * mac-nat.c (child_wait, child_resume): Likewise.
+ * mips-tdep.c (mips_read_pc): Likewise.
+ * monitor.c (monitor_wait, monitor_resume): Likewise.
+ * ocd.c, ocd.h (ocd_thread_alive, ocd_resume): Likewise.
+ * ppc-bdm.c (bdm_ppc_wait): Likewise.
+ * procfs.c (do_attach, procfs_wait, procfs_resume)
+ (procfs_notice_signals, procfs_thread_alive, procfs_pid_to_str)
+ (procfs_set_watchpoint, procfs_stopped_by_watchpoint)
+ (procfs_find_LDT_entry): Likewise.
+ * regcache.c (read_register_pid, read_signed_register_pid)
+ (write_register_pid, generic_target_read_pc, read_pc_pid)
+ (generic_target_write_pc, write_pc_pid): Likewise.
+ * regcache.h (read_register_pid, read_signed_register_pid)
+ (write_register_pid): Likewise.
+ * remote-adapt.c (adapt_wait, adapt_resume): Likewise.
+ * remote-array.c (array_wait, array_resume): Likewise.
+ * remote-bug.c (bug_wait, bug_resume): Likewise.
+ * remote-e7000.c (e7000_wait, e7000_resume): Likewise.
+ * remote-eb.c (eb_wait, eb_resume): Likewise.
+ * remote-es.c (es1800_wait, es1800_resume): Likewise.
+ * remote-mips.c (mips_wait, mips_resume): Likewise.
+ * remote-mm.c (mm_wait, mm_resume): Likewise.
+ * remote-nindy.c (nindy_wait, nindy_resume): Likewise.
+ * remote-os9k.c (rombug_wait, rombug_resume): Likewise.
+ * remote-rdi.c (arm_rdi_wait, arm_rdi_resume): Likewise.
+ * remote-rdp.c (remote_rdp_resume, remote_rdp_wait): Likewise.
+ * remote-sds.c (sds_wait, sds_resume): Likewise.
+ * remote-sim.c (gdbsim_wait, gdbsim_resume): Likewise.
+ * remote-st.c (st2000_wait, st2000_resume): Likewise.
+ * remote-udi.c (udi_wait, udi_resume): Likewise.
+ * remote-vx.c (vx_wait, vx_resume): Likewise.
+ * remote.c (remote_current_thread, remote_resume, remote_wait)
+ (remote_async_resume, remote_async_wait, remote_cisco_wait)
+ (remote_thread_alive): Likewise.
+ * sol-thread.c (thread_to_lwp, lwp_to_thread, sol_thread_resume)
+ (sol_thread_wait, sol_thread_notice_signals, sol_thread_alive)
+ (solaris_pid_to_str): Likewise.
+ * symm-nat.c (child_wait, child_resume): Likewise.
+ * target.c (debug_to_resume, debug_to_wait, debug_to_post_wait)
+ (debug_to_notice_signals, debug_to_thread_alive)
+ (normal_target_post_startup_inferior, normal_pid_to_str)
+ (debug_to_post_startup_inferior): Likewise.
+ * target.h (to_resume, to_wait, to_post_wait)
+ (to_post_startup_inferior, to_notice_signals, to_thread_alive)
+ (to_pid_to_str [all in struct target_ops]): Likewise.
+ (child_post_wait, child_thread_alive, normal_pid_to_str): Likewise.
+ * thread-db.c (thread_from_lwp, lwp_from_thread, thread_db_wait)
+ (attach_thread, detach_thread, thread_db_resume, check_event)
+ (thread_db_post_startup_inferior, thread_db_thread_alive)
+ (thread_db_pid_to_str): Likewise.
+ * thread.c (add_thread, delete_thread, find_thread_pid)
+ (pid_to_thread_id, in_thread_list, load_infrun_state)
+ (save_infrun_state, switch_to_thread, restore_current_thread)
+ (make_cleanup_restore_current_thread): Likewise.
+ * top.c (target_wait_hook): Likewise.
+ * uw-thread.c (dbgpid, thr_to_lwp, lwp_to_thr, add_thread_uw)
+ (uw_thread_resume, libtrhead_stub, uw_thread_wait, uw_thread_alive)
+ (uw_thread_pid_to_str): Likewise.
+ * v850ice.c (v850ice_wait, v850ice_resume): Likewise.
+ * win32-nat.c (child_wait, child_resume, win32_child_thread_alive)
+ (cywin_pid_to_str): Likewise.
+ * wince.c (child_wait, child_resume, win32_child_thread_alive):
+ Likewise.
+ * config/nm-linux.h (linuxthreads_pid_to_str): Likewise.
+ * config/nm-lynx.h (child_wait, lynx_pid_to_str): Likewise.
+ * config/alpha/nm-linux.h (lin_lwp_attach_lwp): Likewise.
+ * config/arm/nm-linux.h (lin_lwp_attach_lwp): Likewise.
+ * config/h8500/tm-h8500.h (h8500_read_pc, h8500_write_pc): Likewise.
+ * config/i386/nm-i386sol2.h (procfs_stopped_by_watchpoint)
+ (procfs_set_watchpoint): Likewise.
+ * config/i386/nm-linux.h (lin_lwp_attach_lwp): Likewise.
+ * config/i386/nm-ptx4.h (child_wait): Likewise.
+ * config/i386/nm-symmetry.h (child_wait): Likewise.
+ * config/i386/tm-cygwin.h (cygwin_pid_to_str): Likewise.
+ * config/ia64/nm-linux.h (ia64_linux_stopped_by_watchpoint)
+ (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint)
+ (lin_lwp_attach_lwp): Likewise.
+ * config/mips/nm-irix4.h, config/mips/nm-irix5.h
+ (procfs_stopped_by_watchpoint, procfs_set_watchpoint): Likewise.
+ * config/pa/nm-hppah.h (child_pid_to_str, hppa_tid_to_str)
+ (hppa_pid_or_tid_to_str): Likewise.
+ * config/pa/tm-hppa.h (target_read_pc, target_write_pc): Likewise.
+ * config/powerpc/nm-linux.h (lin_lwp_attach_lwp): Likewise.
+ * config/sparc/nm-sun4sol2.h (procfs_stopped_by_watchpoint)
+ (procfs_set_watchpoint): Likewise.
+
+ * gdbthread.h (thread_id_to_pid): Change return type which
+ represents a combined process/thread id from ``int'' to
+ ``ptid_t''.
+ * gnu-nat.c (gnu_wait): Likewise.
+ * go32-nat.c (go32_wait): Likewise.
+ * hpux-thread.c (hpux_thread_wait): Likewise.
+ * inferior.h (procfs_first_available): Likewise.
+ * inftarg.c (child_wait): Likewise.
+ * infttrace.c (ptrace_wait): Likewise.
+ * lin-lwp.c (lin_lwp_wait): Likewise.
+ * lin-thread.c (thread_db_wait): Likewise.
+ * linux-thread.c (linuxthreads_wait): Likewise.
+ * lynx-nat.c (child_wait): Likewise.
+ * m3-nat.c (mach_really_wait): Likewise.
+ * mac-nat.c (child_wait): Likewise.
+ * monitor.c (monitor_wait): Likewise.
+ * ppc-bdm.c (bdm_ppc_wait): Likewise.
+ * procfs.c (do_attach, procfs_wait, procfs_first_available): Likewise.
+ * remote-adapt.c (adapt_wait): Likewise.
+ * remote-array.c (array_wait): Likewise.
+ * remote-bug.c (bug_wait): Likewise.
+ * remote-e7000.c (e7000_wait): Likewise.
+ * remote-eb.c (eb_wait): Likewise.
+ * remote-es.c (es1800_wait): Likewise.
+ * remote-mips.c (mips_wait): Likewise.
+ * remote-mm.c (mm_wait): Likewise.
+ * remote-nindy.c (nindy_wait): Likewise.
+ * remote-os9k (rombug_wait): Likewise.
+ * remote-rdi.c (arm_rdi_wait): Likewise.
+ * remote-rdp.c (remote_rdp_wait): Likewise.
+ * remote-sds.c (sds_wait): Likewise.
+ * remote-sim.c (gdbsim_wait): Likewise.
+ * remote-st.c (st2000_wait): Likewise.
+ * remote-udi.c (udi_wait): Likewise.
+ * remote-vx.c (vx_wait): Likewise.
+ * remote.c (remote_wait, remote_async_wait, remote_current_thread)
+ (remote_cisco_wait): Likewise.
+ * sol-thread.c (thread_to_lwp, lwp_to_thread, sol_thread_wait):
+ Likewise.
+ * symm-nat.c (child_wait): Likewise.
+ * target.c (debug_to_wait): Likewise.
+ * target.h (to_wait [in struct target_ops]): Likewise.
+ * thread.c (thread_id_to_pid): Likewise.
+ * thread-db.c (thread_from_lwp, lwp_from_thread, thread_db_wait):
+ Likewise.
+ * top.c (*target_wait_hook): Likewise.
+ * uw-thread.c (lwp_to_thr, uw_thread_wait): Likewise.
+ * v850ice.c (v850ice_wait): Likewise.
+ * win32-nat.c (child_wait): Likewise.
+ * wince.c (child_wait): Likewise.
+ * config/nm-lynx.h (child_wait): Likewise.
+ * config/i386/nm-ptx4.h (child_wait): Likewise.
+ * config/i386/nm-symmetry.h (child_wait): Likewise.
+
+ * arch-utils.c (generic_prepare_to_proceed): Rename wait_pid
+ to wait_ptid and change its type from ``int'' to ``ptid_t''.
+ * breakpoint.c (reattach_breakpoints, detach_breakpoints): Likewise,
+ but rename saved_inferior_pid to saved_inferior_ptid.
+ * d10v-tdep.c (d10v_read_pc, d10_write_pc): Likewise, but rename
+ save_pid to save_ptid.
+ * gdbthread.h (struct thread_info): Likewise, but rename pid to ptid.
+ * hppah-nat.c (child_pid_to_exec): Likewise, but rename
+ saved_inferior_pid to saved_inferior_ptid.
+ * hpux-thread.c (main_ptid): Likewise, but rename from main_pid.
+ * infrun.c (previous_inferior_pid [static global]): Likewise,
+ but rename to previous_inferior_ptid.
+ (resume): Likewise, but rename resume_pid to resume_ptid.
+ (struct execution_control_state): Likewise, but rename
+ pid to ptid, saved_inferior_pid to saved_inferior_ptid,
+ and waiton_pid to waiton_ptid.
+ (target_last_wait_pid): Likewise, but rename to
+ target_last_wait_ptid.
+ * infttrace.c (saved_real_pid): Likewise, but rename to
+ saved_real_ptid.
+ (child_pid_to_exec_file): Likewise, but rename saved_inferior_pid
+ to saved_inferior_ptid.
+ * lin-lwp.c (struct lwp_info): Likewise, but rename pid to ptid.
+ (trap_ptid): Likewise, but renamed from trap_pid.
+ * lin-thread.c (handle_new_thread): Likewise, but rename gdb_pid
+ to gdb_ptid.
+ * linux-thread.c (detach_thread): Likewise, but rename pid to ptid.
+ (thread_db_wait): Likewise, but rename ret_pid to retptid.
+ * procfs.c (procfs_wait): Likewise, for retval whose name
+ doesn't change. Also, ``temp'' becomes two separate variables,
+ one named temp_tid (an int) and the other temp_ptid.
+ (procfs_notice_thread): Likewise (type change) for gdb_threadid
+ whose name does not change.
+ * regcache.c (registers_ptid): Likewise, but renamed from
+ registers_pid.
+ (read_register_pid, read_signed_register_pid, write_register_pid):
+ Likewise, but rename save_pid to save_ptid.
+ (read_pc_pid, write_pc_pid): Likewise, but rename saved_inferior_pid
+ to saved_inferior_ptid.
+ * remote.c (remote_newthread_step): Likewise, but rename pid to ptid.
+ * sol-thread.c (struct ps_prochandle): Likewise.
+ (sol_thread_resume): Likewise, for save_pid which becomes save_ptid.
+ (sol_thread_wait): Likewise, for rtnval whose name does not
+ change, and for save_pid which becomes save_ptid.
+ (solaris_pid_to_str): Likewise for lwp whose name does not change.
+ (sol_find_new_threads_callback): Likewise, for pid which becomes
+ ptid.
+ * target.h (target_resume, target_wait, target_post_wait)
+ (target_post_startup_inferior, target_notice_signals)
+ (target_thread_alive): Likewise.
+ * thread.c (info_threads_command): Likewise, but rename
+ current_pid to current_ptid.
+ (struct current_thread_cleanup): Likewise, but rename field
+ inferior_pid to inferior_ptid.
+ * thread-db.c (find_new_threads_callback): Likewise, but rename
+ pid to ptid.
+ * uw-thread.c (thr_to_lwp): Likewise for lid whose name does not
+ change.
+ (lwp_to_tr): Likewise fo tid whose name remains unchanged.
+ (thr_infpid, lwp_infpid, notice_thread, libthread_stub): Likewise,
+ but rename pid to ptid.
+ * config/alpha/nm-linux.h (ATTACH_LWP): Likewise.
+ * config/arm/nm-linux.h (ATTACH_LWP): Likewise.
+ * config/i386/nm-linux.h (ATTACH_LWP): Likewise.
+ * config/ia64/nm-linux.h (ATTACH_LWP): Likewise.
+ * config/pa/nm-hppah.h (target_tid_to_str): Likewise.
+ * config/powerpc/nm-linux.h (ATTACH_LWP): Likewise.
+
+ * arch-utils.c (generic_prepare_to_proceed): Test for the
+ "zero" ptid by using ptid_equal() to test to see if variable
+ in question is the same as null_ptid. This replaces a direct
+ test against zero.
+ * cxux-nat.c (add_shared_symbol_files): Likewise.
+ * i386aix-nat.c, i386b-nat.c (i386_float_info): Likewise.
+ * infcmd.c (run_command): Likewise.
+ * inflow.c (kill_command): Likewise.
+ * infttrace.c (call_ttrace): Likewise.
+ * lin-lwp.c (lin_lwp_prepare_to_proceed): Likewise.
+ * lin-thread.c (thread_db_kill): Likewise.
+ * procfs.c (procfs_kill_inferior, procfs_mourn_inferior): Likewise.
+ * remote-es.c (es1800_kill): Likewise.
+ * sol-thread.c (sol_thread_create_inferior): Likewise.
+ * solib.c (locate_base): Likewise.
+ * target.c (nosupport_runtime): Likewise.
+ * thread-db.c (thread_db_wait): Likewise.
+ * top.c (quit_confirm, quit_force): Likewise.
+ * uw-thread (lwp_infpid, uw_thread_resume): Likewise.
+
+ * infrun.c (handle_inferior_event, stop_stepping, normal_stop):
+ Use ptid_equal to compare value of process/thread ids instead of
+ ``=='' and ``!='' operators.
+ lin-lwp.c (delete_lwp, lin_lwp_prepare_to_proceed)
+ (stop_wait_callback, lin_lwp_wait): Likewise.
+ * procfs.c (procfs_wait): Likewise.
+ * regcache.c (read_register_bytes, read_register_gen)
+ (write_register_gen, read_register, read_register_pid)
+ (read_signed_register, read_signed_register_pid, write_register)
+ (write_register_pid, supply_register): Likewise.
+ * remote-vx.c (vx_resume): Likewise.
+ * sol-thread.c (sol_thread_wait): Likewise.
+ * symm-nat.c (kill_inferior): Likewise.
+ * thread.c (delete_thread, find_thread_pid, pid_to_thread_id)
+ (in_thread_list, info_threads_command, switch_to_thread)
+ (restore_current_thread): Likewise.
+ * uw-thread (libtread_stub): Likewise.
+
+ * arm-linux-nat.c (GET_THREAD_ID): Change PID to PTID.
+
+ * corelow.c (add_to_thread_list): Convert argument in add_thread()
+ call to a ptid_t.
+ * gnu-nat.c (inf_validate_procs): Likewise.
+ * linux-thread.c (stop_thread, update_stop_threads): Likewise.
+ * remote.c (record_currthread, remote_threads_info): Likewise.
+ * win32-nat.c (child_add_thread): Likewise.
+
+ * hpux-thread.c (save_inferior_pid, restore_inferior_pid): Rename,
+ respectively, to save_inferior_ptid() and restore_inferior_ptid().
+ Adjust implementations to operate on ``ptid_t'' instead of ``int''.
+ * lin-lwp.c (save_inferior_pid, restore_inferior_pid): Likewise.
+ * lin-thread.c (save_inferior_pid, restore_inferior_pid): Likewise.
+ * linux-thread.c (save_inferior_pid, restore_inferior_pid): Likewise.
+ * proc-service.c (save_inferior_pid, restore_inferior_pid): Likewise.
+ * sol-thread.c (save_inferior_pid, restore_inferior_pid): Likewise.
+ * thread-db.c (save_inferior_pid, restore_inferior_pid): Likewise.
+
+ * infrun.c (RESUME_ALL): New macro representing the -1 ptid
+ to be passed to target_resume() when all threads should resume.
+ (resume): Set resume_ptid to RESUME_ALL rather than -1.
+ (handle_inferior_event): Invoke target_resume() with RESUME_ALL
+ instead of -1.
+ * irix5-nat.c (solib_create_inferior_hook): Convert -1 to
+ a ptid_t in target_resume() call.
+ * osfsolib.c (solib_create_inferior_hook): Likewise.
+ * solib-svr4.c (solib_create_inferior_hook): Likewise.
+
+ * lin-lwp.c (PIDGET, PIDGET0): Rename original PIDGET macro to
+ PIDGET0. Define new PIDGET macro which uses PIDGET0, the only
+ difference being that the 0xffff pattern will be interpreted
+ as -1.
+ * lin-thread.c (PIDGET, PIDGET0): Likewise.
+ * thread-db.c (PIDGET, PIDGET0): Likewise.
+ * config/nm-linux.h (PIDGET, PIDGET0): Likewise.
+ * config/i386/tm-i386sol2.h (PIDGET, PIDGET0): Likewise.
+ * config/i386/tm-i386v42mp.h (PIDGET, PIDGET0): Likewise.
+ * config/sparc/tm-sun4sol2.h (PIDGET, PIDGET0): Likewise.
+
+ * m3-nat.c (init_m3_ops): Fix typo; initialize to_wait field to
+ mach_really_wait rather than mach_really__wait.
+ * lin-thread.c (check_for_thread_event): Fix warning; make function
+ actually return a value.
+
+ * gdbarch.sh (TARGET_READ_PC, TARGET_WRITE_PC): Change type of
+ ``pid'' arguments from ``int'' to ``ptid_t''. Also renamed
+ pid to ptid.
+ * gdbarch.h, gdbarch.c: Regenerated.
+
+2001-05-03 Jonathan Larmour <jlarmour@redhat.com>
+
+ * rdi-share/devsw.c: Include <time.h> for struct tm
+
+2001-05-03 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/djgpp/fnchange.lst: Add mappings for the new
+ opcodes/openrisc-* files.
+
+2001-05-01 Michael Snyder <msnyder@redhat.com>
+
+ * lin-lwp.c: Change printf to fprintf_unfiltered.
+ * Makefile.in: Add rules for thread-db.o, lin-lwp.o, proc-service.o.
+
+2001-05-01 Nicholas Duffek <nsd@redhat.com>
+
+ * config/rs6000/tm-rs6000.h (IN_SOLIB_RETURN_TRAMPOLINE): Define.
+ (rs6000_in_solib_return_trampoline): Declare.
+ * rs6000-tdep.c (rs6000_in_solib_return_trampoline): New
+ function.
+ (rs6000_skip_trampoline_code): Skip bigtoc fixup code.
+ * xcoffread.c (read_xcoff_symtab): Perform the ISFCN function
+ check after the CSECT check rather than before it. Allocate
+ separate symtabs for CSECTs whose names begin with '@'.
+ (scan_xcoff_symtab): Don't ignore symbols beginning with '@'.
+ Activate the misc_func_recorded mechanism for whose names begin
+ with '@'.
+
+2001-04-30 J.T. Conklin <jtc@redback.com>
+
+ * ppcnbsd-nat.c (fetch_inferior_registers)
+ (store_inferior_registers, fetch_core_registers): Changed to use
+ fpreg[] instead of r_regs[] to access floating point registers.
+
+2001-04-30 Elena Zannoni <ezannoni@redhat.com>
+
+ * sh-tdep.c: Get rid of the function prototypes.
+ (sh_sh4_build_float_register_type): Move earlier in file.
+ (fv_reg_base_num): Ditto.
+ (dr_reg_base_num): Ditto.
+
+2001-04-30 Michael Snyder <msnyder@redhat.com>
+
+ * thread-db.c: Revert 2001-04-26 change for debugging output.
+ * lin-lwp.c: Ditto.
+ * lin-lwp.c: Add set/show debug lin-lwp command. Use this
+ command to turn extra debugging output on / off.
+
+2001-04-30 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * buildsym.c (start_subfile): Use FILENAME_CMP instead of STREQ.
+ (top-level): #include filenames.h.
+
+ * dwarf2read.c (dwarf2_start_subfile): Use IS_ABSOLUTE_PATH and
+ FILENAME_CMP, to DTRT on non-Posix platforms.
+ (top-level): #include filenames.h.
+
+
+2001-04-27 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbtypes.c (check_stub_method): Always initialize ``p''.
+
+2001-04-27 Andrew Cagney <ac131313@redhat.com>
+
+ * configure.host: Delete romp host.
+ * TODO: Update.
+
+2001-04-27 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO: Updates to 5.1. No more targets to obsolete.
+
+2001-04-27 Don Howard <dhoward@redhat.com>
+
+ (Changes from Kevin Buettner, with minor update by Don Howard.)
+
+ * i387-nat.c (i387_supply_fxsave, i387_fill_fxsave, i387_tag): Fix
+ typos in which hexadecimal constants were really intended to be
+ binary constants.
+ (i387_tag): Swap logic regarding zero vs non-zero exponents.
+ * MAINTAINERS (Misc): Added myself to the write-after-approval
+ list.
+
+2001-04-26 Jim Blandy <jimb@redhat.com>
+
+ (Changes from Daniel Berlin, with revisions by Jim Blandy.)
+
+ Abstract out operations specific to particular C++ ABI's, and
+ invoke them through a function table. This removes the C++ ABI
+ dependencies scattered throughout the code, and allows us to
+ cleanly add support for new C++ ABI's.
+ * cp-abi.h, cp-abi.h, gnu-v2-abi.c, hpacc-abi.c: New files.
+ * c-typeprint.c, c-valprint.c, dbxread.c, eval.c, gdbtypes.c,
+ jv-typeprint.c, linespec.c, symtab.c, typeprint.c, valops.c:
+ #include "cp-abi.h". These files all use functions now declared
+ there.
+ * symtab.h (OPNAME_PREFIX_P, VTBL_PREFIX_P, DESTRUCTOR_PREFIX_P):
+ Deleted. These services are now provided by functions declared in
+ cp-abi.h.
+ * value.h (value_rtti_type, value_virtual_fn_field): Same.
+ * values.c (value_virtual_fn_field): Same, for this definition.
+ * valops.c (value_rtti_type): Same.
+ * c-typeprint.c (c_type_print_base): Use the functions from
+ "cp-abi.h", instead of the old macros, or hard-coded ABI-specific
+ tests.
+ * dbxread.c (record_minimal_symbol): Same.
+ * gdbtypes.c (get_destructor_fn_field, virtual_base_index,
+ virtual_base_index_skip_primaries): Same.
+ * jv-typeprint.c (java_type_print_base): Same.
+ * linespec.c (find_methods, decode_line_1): Same.
+ * symtab.c (gdb_mangle_name): Same.
+ * Makefile.in (SFILES): Add the new .c files mentioned above.
+ (cp_abi_h): New variable.
+ (COMMON_OBS): Add gnu-v2-abi.o, hpacc-abi.o, and cp-abi.o.
+ (cp-abi.o, gnu-v2-abi.o, hpacc-abi.o): New targets.
+ (c-typeprint.o, c-valprint.o, dbxread.o, eval.o, gdbtypes.o,
+ jv-typeprint.o, symtab.o, linespec.o, typeprint.o, valops.o): Add
+ dependency on $(cp_abi_h).
+
+2001-04-26 Michael Snyder <msnyder@redhat.com>
+
+ * thread-db.c (_initialize_thread_db): Add set/show command
+ "debug-linux-threads" for debugging output.
+ * lin-lwp.c (various): Use global "debug_linux_threads to
+ turn on extra debugging output.
+ * lin-lwp.c: Minor cleanups in comments.
+ * target.c (normal_pid_to_str): Get rid of an ancient hack.
+ * remote.c (remote_pid_to_str): New function for remote target.
+
+2001-04-24 Jim Blandy <jimb@redhat.com>
+
+ * c-typeprint.c (c_type_print_cv_qualifier): Don't print `const'
+ qualifier on C++ references; all references are innately const.
+
+2001-04-20 Mark Kettenis <kettenis@gnu.org>
+
+ * event-top.h: Fix formatting.
+
+2001-04-17 Andrew Cagney <ac131313@redhat.com>
+
+ * source.c (openp): Obsolete #ifdef MPW code.
+ (open_source_file): Ditto.
+ * event-top.c (display_gdb_prompt): Ditto.
+ * utils.c (query): Ditto.
+ (init_page_info): Ditto.
+ (init_page_info): Delete #ifndef MPW.
+ * top.c (gdb_readline): Ditto.
+ * mac-xdep.c: Obsolete.
+ * mac-gdb.r: Obsolete.
+ * config/powerpc/xm-mpw.h: Obsolete.
+ * config/xm-mpw.h: Obsolete.
+ * mpw-make.sed: Obsolete.
+ * mpw-config.in: Obsolete.
+ * TODO: Update
+ * NEWS: Update
+
+2001-04-19 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-tdep.c (i386_frameless_function_invocation): New function.
+ * config/i386/tm-i386.h (FRAMELESS_FUNCTION_INVOCATION): Redefine
+ in terms of i386_frameless_function_invocation. Adjust comment.
+ (i386_frameless_function_invocation): New prototype.
+
+2001-04-18 Martin M. Hunt <hunt@redhat.com>
+
+ * top.c (gdb_init): Don't call cli_out_new() to
+ create global uiout if init_ui_hook is set. uiout will
+ have to be initialized there.
+
+2001-04-18 Andrew Cagney <ac131313@redhat.com>
+
+ * arch-utils.c: Include "regcache.h".
+
+2001-04-18 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-tdep.c (i386_saved_pc_after_call): New function.
+ * config/i386/tm-i386.h (SAVED_PC_AFTER_CALL): Redefine in terms
+ of i386_saved_pc_after_call.
+ (i386_saved_pc_after_call): New prototype.
+
+2001-04-17 Michael Snyder <msnyder@redhat.com>
+
+ * i386-nat.c: Fix typo in comment.
+ * solib.c (no_shared_libraries): New function. Discard all symbols
+ from shared libraries.
+ (_initialize_solib): Add command "nosharedlibrary" as complement
+ to the command "sharedlibrary". Unloads symbols for all solibs.
+
+2001-04-16 Andrew Cagney <ac131313@redhat.com>
+
+ * configure.host (m68030-sony-*, m68*-isi-*, m68*-sony-*):
+ * configure.tgt (m68*-rom68k-*, m68*-*bug-*, m68*-monitor-*)
+ (m68*-est-*, m68*-sony-*, m68*-isi-*):
+ * Makefile.in (xm-news1000.h, tm-news.h, xm-news.h): Obsolete..
+ * config/m68k/xm-news.h: Obsolete.
+ * config/m68k/tm-news.h:
+ * config/m68k/xm-news1000.h: Obsolete.
+ * config/m68k/news.mh: Obsolete.
+ * config/m68k/news.mt: Obsolete.
+ * config/m68k/nm-news.h: Obsolete.
+ * config/m68k/news1000.mh: Obsolete.
+ * news-xdep.c: Obsolete.
+ * Makefile.in (isi-xdep.o): Obsolete.
+ (ALLDEPFILES): Delete isi-xdep.c.
+ (tm-isi.h): Obsolete.
+ * m68k-tdep.c (altos_skip_prologue): Update comments.
+ (isi_skip_prologue): Obsolete.
+ * isi-xdep.c: Obsolete.
+ * config/m68k/xm-isi.h: Obsolete.
+ * config/m68k/isi.mh: Obsolete.
+ * config/m68k/tm-isi.h: Obsolete.
+ * config/m68k/isi.mt: Obsolete.
+
+ * TODO: Update.
+ * NEWS: Update.
+
+2001-04-17 Michael Snyder <msnyder@redhat.com>
+
+ * remote.c (remote_open_1): On opening the remote target, activate
+ the solib_create_inferior_hook, so that it can detect when the
+ target loads shared libraries.
+ (remote_async_open_1): Ditto.
+
+2001-04-17 Michael Snyder <msnyder@redhat.com>
+
+ * breakpoint.c (print_one_breakpoint): Handle 64-bit addresses.
+ * tracepoint.c (tracepoints_info): Handle 64-bit addresses.
+ * testsuite/gdb.trace/deltrace.exp: Allow for 64-bit addresses.
+ * testsuite/gdb.trace/infotrace.exp: Ditto.
+ * testsuite/gdb.trace/passcount.exp: Ditto.
+ * testsuite/gdb.trace/while-stepping.exp: Ditto.
+
+2001-04-17 Michael Snyder <msnyder@redhat.com>
+
+ * thread-db.c (check_thread_signals): When looping over all
+ signals, ignore signal zero.
+ (disable_thread_signals): Ditto.
+
+2001-04-17 Eirik Fuller <eirik@netapp.com>
+
+ * thread.c (do_captured_thread_select): Allow the argument to the
+ thread command to be an expression rather than a literal integer.
+
+2001-04-17 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-linux-tdep.c (i386_linux_saved_pc_after_call): Use
+ read_memory_unsigned_integer instead of read_memory_integer.
+
+2001-04-16 Kevin Buettner <kevinb@redhat.com>
+
+ * solib-aix5.c (map_index_vs_section_name_okay): New function.
+ (aix5_relocate_main_executable): Don't use file offsets for
+ determining corresponding sections and map file entries. Call
+ map_index_vs_section_name_okay() to do this instead.
+
+2001-04-16 Kevin Buettner <kevinb@redhat.com>
+
+ * procfs.c (open_with_retry): New function.
+ (open_procinfo_files, load_syscalls, proc_iterate_over_mappings)
+ (proc_get_LDT_entry): Call open_with_retry() instead of open().
+
+2001-04-16 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-linux-nat.c (ia64_linux_stopped_by_watchpoint): Adjust
+ comparison against TRAP_HWBKPT constant yet again to account
+ for the various values used by different kernel versions.
+
+2001-04-16 Daniel Berlin <dan@cgsoftware.com>
+
+ * demangle.c (_initialize_demangler): Use xcalloc on the
+ demangling_style_names, and make it a null terminated array of
+ names, to avoid a crash.
+
+2001-04-16 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-tdep.c (i386_frame_chain): New function.
+ * config/i386/tm-i386.h (FRAME_CHAIN): Redefine in terms of
+ i386_frame_chain.
+ (i386_frame_chain): New prototype.
+
+2001-04-14 J.T. Conklin <jtc@redback.com>
+
+ * target.h (target_ops): Removed to_core_file_to_sym_file vector
+ function.
+ * corelow.c (core_ops): Updated for above change.
+ * gnu-nat.c (core_ops): Likewise.
+ * inftarg.c (child_ops): Likewise.
+ * monitor.c (monitor_ops): Likewise.
+ * ppc-bdm.c (bdm_ppc_ops): Likewise.
+ * remote-adapt.c (adapt_ops): Likewise.
+ * remote-bug.c (bug_ops): Likewise.
+ * remote-e7000.c (e7000_ops): Likewise.
+ * remote-eb.c (eb_ops): Likewise.
+ * remote-es.c (es1800_ops, es1800_child_ops): Likewise.
+ * remote-mm.c (mm_ops): Likewise.
+ * remote-nindy.c (nindy_ops): Likewise.
+ * remote-nrom.c (nrom_ops): Likewise.
+ * remote-os9k.c (rombug_ops): Likewise.
+ * remote-rdp.c (remote_rdp_ops): Likewise.
+ * remote-sim.c (gdbsim_ops): Likewise.
+ * remote-st.c (st2000_ops): Likewise.
+ * v850ice.c (v850ice_ops): Likewise.
+ * target.c (cleanup_target): Likewise
+ (update_current_target): Likewise.
+ (setup_target_debug): Likewise
+ (debug_to_core_file_to_sym_file): Removed.
+
+ * corefile.c (core_file_command) [HPUXHPPA]: Removed code that
+ sets symbol file from information obtained from the core file.
+ * corelow.c (core_file_to_sym_file): Removed.
+
+2001-04-13 Fernando Nasser <fnasser@redhat.com>
+
+ From Adam Mirowski <Adam.Mirowski@Sun.COM>
+ Fixed Insight on Solaris. It was not possible to debug a process
+ because of EINTR "errors".
+ * procfs.c: (procfs_wait): if proc_wait_for_stop() fails
+ with EINTR, retry the call.
+
+2001-04-12 Kevin Buettner <kevinb@redhat.com>
+
+ * solib-aix5.c (enum maptype): Delete.
+ (struct lm_info): Add new member ``nmappings''. Make ``mapping''
+ member a pointer instead of a statically sized array.
+ (build_so_list_from_mapfile): Dynamically allocate ``mapping''
+ array.
+ (aix5_relocate_main_executable, aix5_relocate_section_addresses,
+ aix5_find_global_pointer): Search for correct mapping to use
+ based on file offset instead of knowledge of whether the section
+ is read-only or read/write.
+ (aix5_find_gate_addresses): Use the first mapping instead of
+ the (now defunct) MT_READONLY mapping.
+
+2001-04-12 Nicholas Duffek <nsd@redhat.com>
+
+ * xcoffread.c (scan_xcoff_symtab): Ignore symbols beginning with
+ "@".
+
+2001-04-12 Kevin Buettner <kevinb@redhat.com>
+
+ * config/i386/fbsd.mh (NATDEPFILES): Add i386-nat.o.
+
+2001-04-09 Andrew Cagney <ac131313@redhat.com>
+
+ Obsolete i[3456]86-*-sunos* (aka Sun386) host and target.
+ * config/i386/sun386.mh: Obsolete.
+ * config/i386/sun386.mt: Obsolete.
+ * config/i386/xm-sun386.h: Obsolete.
+ * config/i386/tm-sun386.h: Obsolete.
+ * config/i386/nm-sun386.h: Obsolete.
+ * Makefile.in (ALLDEPFILES): Delete sun386-nat.c.
+ (sun386-nat.o): Target is obsolete.
+ * sun386-nat.c: Obsolete.
+ * configure.tgt (i[3456]86-*-sunos*): Obsolete.
+ * configure.host (i[3456]86-*-sunos*): Obsolete.
+ * NEWS: Update.
+ * TODO: Update.
+
+2001-04-10 J.T. Conklin <jtc@redback.com>
+
+ * maint.c: Fix typo in comment.
+
+2001-04-09 Keith Seitz <keiths@cygnus.com>
+
+ * MAINTAINERS: Swap with Syd Polk as a gdbtk maintainer.
+
+2001-04-08 Kevin Buettner <kevinb@redhat.com>
+
+ * fork-child.c (fork_inferior, clone_and_follow_inferior):
+ Document fact that apparent call to vfork() might actually be
+ a call to fork() instead.
+ * ser-pipe.c (pipe_open): Likewise.
+
+2001-04-08 Kevin Buettner <kevinb@redhat.com>
+
+ * printcmd.c (print_frame_args): Use a cleanup to invoke
+ ui_out_list_end() so that the list count nesting flag will
+ be decremented properly when an error occurs.
+ * stack.c (print_frame): Likewise.
+
+2001-04-06 J.T. Conklin <jtc@redback.com>
+
+ * dcache.c (dcache_write_line): Fixed bugs where cache line was
+ not written to target correctly.
+
+ * gdbserver/low-hppabsd.c (read_inferior_memory): Add explicit
+ void return value;
+ * gdbserver/low-nbsd.c: Likewise.
+ * gdbserver/low-sparc.c: Likewise.
+ * gdbserver/low-sun3.c: Likewise.
+
+2001-04-06 Geoffrey Keating <geoffk@redhat.com>
+
+ * config/rs6000/nm-rs6000.h (PTRACE_ATTACH): Don't define.
+ (PTRACE_DETACH): Don't define.
+
+2001-04-06 David Smith <dsmith@redhat.com>
+
+ * arch-utils.c (default_prepare_to_proceed)
+ (generic_prepare_to_proceed): Added new functions.
+ * arch-utils.h: New function declarations for
+ default_prepare_to_proceed() and generic_prepare_to_proceed().
+ * gdbarch.sh: Added PREPARE_TO_PROCEED.
+ * gdbarch.c: Regenerated.
+ * gdbarch.h: Regenerated.
+ * inferior.h: Added get_last_target_status() declaration.
+ * infrun.c (get_last_target_status): Added new function.
+ (handle_inferior_event): Saves last pid and waitstatus, which will
+ get returned by get_last_target_status().
+
+ * hppa-tdep.c (prepare_to_proceed): Added comment stating that
+ prepare_to_proceed() is potentially redundant since
+ default_prepare_to_proceed() has been added.
+ * linux-thread.c (prepare_to_proceed): Ditto.
+ * lin-lwp.c (prepare_to_proceed): Ditto.
+ * m3-nat.c (prepare_to_proceed): Ditto.
+
+2001-04-05 Andrew Cagney <ac131313@redhat.com>
+
+ Obsolete powerpcle-*-cygwin* and powerpcle-*-solaris* platforms
+ and powerpc-*-netware* target.
+ * configure.host (powerpcle-*-cygwin*, powerpcle-*-solaris*):
+ Obsolete.
+ * configure.tgt (powerpc-*-netware*, powerpcle-*-cygwin*)
+ (powerpcle-*-solaris*): Obsolete.
+ * config/powerpc/tm-cygwin.h: Obsolete.
+ * config/powerpc/cygwin.mt: Obsolete.
+ * config/powerpc/xm-cygwin.h: Obsolete.
+ * config/powerpc/cygwin.mh: Obsolete.
+ * config/powerpc/nm-solaris.h: Obsolete.
+ * config/powerpc/xm-solaris.h: Obsolete.
+ * config/powerpc/tm-solaris.h: Obsolete.
+ * config/powerpc/solaris.mt: Obsolete.
+ * config/powerpc/tm-ppc-nw.h: Obsolete.
+ * config/powerpc/ppc-nw.mt: Obsolete.
+ * TODO: Update.
+ * NEWS: Update.
+
+2001-04-06 Fernando Nasser <fnasser@redhat.com>
+
+ * buildsym.c (record_line): Turn off unused addr bits.
+
+2001-04-06 Fernando Nasser <fnasser@redhat.com>
+
+ From David Deephanphongs <deephan@telocity.com>
+ * inferior.h: Fix declarations of get_inferior_args and
+ set_inferior_args, which were missing the trailing 's'.
+
+2001-04-05 Jeff Holcomb <jeffh@redhat.com>
+
+ * monitor.c (monitor_supply_register): Only report an error if we
+ don't get a valid value.
+
+2001-04-05 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * README: Don't mention gdba.el.
+
+2001-04-05 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Jimmy Guo <guo@cup.hp.com>
+ * top.c (init_main): set prompt if annotation_level>1,
+ this is necessary when annotation_level is set to 2 via
+ --annotate=2 command line option.
+
+2001-04-04 Andrew Cagney <ac131313@redhat.com>
+
+ Obsolete a29k-*-* host and a29k-*-sym1* and a29k-*-kern* targets.
+ * configure.tgt (a29k-*-sym1*, a29k-*-kern*): Obsolete.
+ * configure.host (a29k-*-*): Obsolete.
+ * Makefile.in (ALLDEPFILES): Remove ultra3-nat.c and
+ ultra3-xdep.c.
+ (ultra3-nat.o, ultra3-xdep.o): Obsolete.
+ * config/a29k/tm-ultra3.h: Obsolete.
+ * config/a29k/ultra3.mt: Obsolete.
+ * config/a29k/ultra3.mh: Obsolete.
+ * config/a29k/nm-ultra3.h: Obsolete.
+ * config/a29k/xm-ultra3.h: Obsolete.
+ * ultra3-xdep.c: Obsolete.
+ * ultra3-nat.c: Obsolete.
+ * config/a29k/a29k-kern.mt: Obsolete.
+ * NEWS: Update.
+ * TODO: Update.
+
+Wed Apr 4 21:48:42 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * main.c: Remove windows.h use.
+ (gdbtk_test): Use PATH_MAX for home var calculation.
+ * remote-e7000.c (e7000_parse_device): Accomodate Cygwin as well as
+ Win32 in colon test.
+ * ser-tcp.c: Use modern __CYGWIN__ conditional.
+ * source.c (mod_path): Add __CYGWIN__ conditional to WIN32 test.
+ (openp): Ditto.
+ * symfile.c (symfile_bfd_open): Ditto.
+
+2001-04-04 Martin M. Hunt <hunt@redhat.com>
+
+ * main.c (captured_main): For GDBtk, don't use tui_fileopen().
+ Handle all stream setup in gdbtk_init
+
+2001-04-04 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-tdep.c (i386_extract_return_value): Don't return the return
+ value of a void function.
+ (i386_store_return_value): Likewise.
+
+2001-04-03 Andrew Cagney <ac131313@redhat.com>
+
+ Obsolete w65-*-* target.
+ * configure.tgt (w65-*-*): Obsolete.
+ * config/w65/w65.mt: Obsolete.
+ * config/w65/tm-w65.h: Obsolete.
+ * w65-tdep.c: Obsolete.
+ * NEWS: Update. Fix TiC80 description.
+ * TODO: Update.
+
+2001-04-03 Andrew Cagney <ac131313@redhat.com>
+
+ Obsolete tic80-*-* target.
+ * configure.tgt (tic80-*-*): Obsolete.
+ * config/tic80/tic80.mt: Obsolete.
+ * config/tic80/tm-tic80.h: Obsolete.
+ * tic80-tdep.c: Obsolete.
+ * TODO: Update
+ * NEWS: Update.
+
+2001-04-02 J.T. Conklin <jtc@redback.com>
+
+ * remote-mips.c (S_IROTH): Moved definition from here.
+ * gdb_stat.h (S_IROTH): to here.
+
+ * remote.c (remote_protocol_e, remote_protocol_E): Define.
+ (set_remote_protocol_e_packet_cmd)
+ (set_remote_protocol_E_packet_cmd)
+ (show_remote_protocol_e_packet_command)
+ (show_remote_protocol_E_packet_command): New functions.
+ (init_all_packet_configs): Initialize remote_protocol_e and
+ remote_protocol_E.
+ (remote_resume, remote_async_resume): Support e/E command
+ packets.
+ (show_remote_cmd): Show state of remote_protocol_e and
+ remote_protocol_E.
+ (_initialize_remote): Add "set remote step-over-range-packet"
+ and "set remote step-over-range-w-signal-packet" to CLI.
+
+2001-04-01 Andrew Cagney <ac131313@redhat.com>
+
+ Obsolete ns32k-*-mach3*, ns32k-umax-*, ns32k-utek-sysv* and
+ ns32k-utek-*.
+ * Makefile.in (ALLDEPFILES): Delete umax-xdep.c and ns32km3-nat.c.
+ (umax-xdep.o, ns32km3-nat.o): Obsolete.
+ * configure.tgt (ns32k-*-mach3*, ns32k-utek-sysv*, ns32k-utek-*):
+ Obsolete.
+ * configure.host (ns32k-*-mach3*, ns32k-umax-*, ns32k-utek-sysv*):
+ Obsolete.
+ * config/ns32k/merlin.mh: Obsolete.
+ * config/ns32k/merlin.mt: Obsolete.
+ * config/ns32k/xm-merlin.h: Obsolete.
+ * config/ns32k/tm-merlin.h: Obsolete.
+ * config/ns32k/nm-umax.h: Obsolete.
+ * config/ns32k/umax.mh: Obsolete.
+ * config/ns32k/umax.mt: Obsolete.
+ * config/ns32k/xm-umax.h: Obsolete.
+ * umax-xdep.c: Obsolete.
+ * config/ns32k/ns32km3.mh: Obsolete.
+ * config/ns32k/ns32km3.mt: Obsolete.
+ * config/ns32k/tm-ns32km3.h: Obsolete.
+ * config/ns32k/xm-ns32km3.h: Obsolete.
+ * ns32km3-nat.c: Obsolete.
+ * ns32k-tdep.c (merlin_skip_prologue): Obsolete.
+ (merlin_frame_num_args): Ditto.
+ * NEWS: Update.
+ * TODO: Update.
+
+2001-04-02 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/djgpp/fnchange.lst: Tweak due to
+ expect/example/chesslib.c.
+
+2001-04-02 Kevin Buettner <kevinb@redhat.com>
+
+ * m88k-tdep.c (examine_prologue): Change type of ``insn'' from
+ unsigned int to unsigned long. Also, fix format string.
+ (pop_frame): Fix PC_IN_CALL_DUMMY() call so that it doesn't
+ use an undeclared variable. Also, delete declaration and
+ initialization of ``fp'' because it is otherwise unused.
+ * remote-bug.c (sleep): Delete declaration.
+ (bug_store_register, bug_write_memory, bug_read_memory)
+ (bug_insert_breakpoint, bug_remove_breakpoint): Fix sprintf()
+ format statements and cast certain sprintf() arguments to
+ eliminate warnings.
+ (bug_load): Likewise for call to printf_filtered().
+ * config/m88k/tm-m88k.h (FIX_CALL_DUMMY): Eliminate
+ assignment to ``pc''. The necessary assignment is done in
+ hand_function_call() after the invocation of FIX_CALL_DUMMY().
+
+2001-03-20 Daniel Berlin <dberlin@redhat.com>
+
+ * symtab.c (completion_list_add_name): Remove duplicate string checks,
+ readline already does this, and it's much faster at it, too.
+
+2001-04-01 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c: Minor tweaks, to pacify the ari script.
+
+2001-04-01 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-tdep.c (i386_extract_struct_value_address): New function.
+ * config/i386/tm-i386.h (EXTRACT_STRUCT_VALUE_ADDRESS): Redefine
+ in terms of i386_extract_struct_value_address.
+ (i386_extract_struct_value_address): New prototype.
+
+ * i386-linux-nat.c (i386_linux_dr_get): Change type of return
+ value to `unsigned long'. Change type of `value' to `unsigned
+ long'.
+ (i386_linux_dr_set): Change type of second argument to `unsigned
+ long'.
+ (i386_linux_dr_set_control): Change type of first argument to
+ `unsigned long'.
+ (i386_linux_dr_get_status): Change type of return value to
+ unsigned long.
+ * config/i386/nm-linux.h (i386_linux_dr_set_control,
+ i386_linux_dr_get_status): Adjust prototypes accordingly.
+
+2001-03-31 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-linux-nat.c (ia64_linux_stopped_by_watchpoint): Change
+ TRAP_HWBKPT constant to match that in the kernel headers for
+ Linux/IA-64.
+
+2001-03-31 Mark Kettenis <kettenis@gnu.org>
+
+ * i386bsd-nat.c: Include "gdb_assert.h".
+ [HAVE_PT_GETDBREGS] (DBREG_DRX): Define if not
+ already defined.
+ [HAVE_PT_GETDBREGS] (i386bsd_dr_set, i386bsd_dr_set_control,
+ i386bsd_dr_set_addr, i386bsd_dr_reset_addr,
+ i386bsd_dr_get_status): New functions.
+ * config/i386/nm-fbsd.h [HAVE_PT_GETDBREGS]
+ (I386_USE_GENERIC_WATCHPOINTS): Define.
+ Include "i386/nm-i386.h".
+ (I386_DR_LOW_SET_CONTROL, I386_DR_LOW_SET_ADDR,
+ I386_DR_LOW_RESET_ADDR, I386_DR_LOW_GET_STATUS): New macros.
+ (i386bsd_dr_set_control, i386bsd_dr_set_addr,
+ i386bsd_dr_reset_addr, i386bsd_dr_get_status): New prototypes.
+ * acconfig.h (HAVE_PT_GETDBREGS): New configure macro.
+ * configure.in: Cleanup a few comments. Check for PT_GETDBREGS
+ ptrace request.
+ * config.in, configure: Regenerate.
+
+ * i386-nat.c (i386_insert_aligned_watchpoint): Set address
+ register before enabling it by setting the control register.
+ (i386_remove_aligned_watchpoint): Reset address register after
+ disabling it by setting the control register.
+
+ * i386-tdep.c (i386_extract_return_value): If the type of the
+ return value is TYPE_STRUCT and the number of fields is one, call
+ ourselves with TYPE set tp the type of the first field.
+ (i386_store_return_value): Likewise.
+ This fixes a problem with returning structs consisting of a single
+ `float' or `double' on *BSD.
+
+2001-03-30 Mark Kettenis <kettenis@gnu.org>
+
+ * lin-lwp.c (lin_lwp_resume): Don't mark LWP as not stopped until
+ we're absolutely sure we're going to resume it.
+
+ * thread-db.c (check_event): Don't report an error if we encounter
+ a thread creation event for a thread that's already in the thread
+ list, since that may legitemately happen. Instead only call
+ attach_thread if it's not already in the thread list.
+
+2001-03-28 Andrew Cagney <ac131313@redhat.com>
+
+ * config/pa/xm-hppah.h (malloc): Really delete declaration
+ (MALLOC_INCOMPATIBLE): Really delete macro.
+ * cli/cli-cmds.c (apropos_command): Use xcalloc.
+
+2001-03-28 Andrew Cagney <ac131313@redhat.com>
+
+ * configure.in (build_warnings): Add -Wuninitialized.
+ * configure: Regenerate.
+
+ * v850-tdep.c (v850_scan_prologue): Initialize ``insn2''.
+ * sparc-tdep.c (sparc64_push_arguments): Add default case to
+ switch.
+ * sh-tdep.c (sh_do_fp_register): Replace ``?:'' printf format
+ expression with if statement.
+ * mn10200-tdep.c (mn10200_analyze_prologue): Initialize
+ ``stack_size''.
+ * mips-tdep.c (show_mipsfpu_command): Add default case to switch.
+ (mips_dump_tdep): Fix setting of ef_mips_arch.
+ * mcore-tdep.c (mcore_analyze_prologue): Initialize ``fp_regnum''.
+ * dsrec.c (make_srec): Always initialize ``binbuf''.
+ * monitor.c (monitor_read_memory_single): Do not pass an
+ uninitialized buffer to monitor_error. Make ``i'' more local.
+
+2001-03-28 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Change ns32k target to ,-Werror.
+
+ * ns32k-tdep.c: Include "gdbcore.h"
+ (flip_bytes): Change first argument to void*. Add forward
+ declaration.
+ (sign_extend): Add declaration.
+ (merlin_frame_num_args): Add final else clause to if-else chain.
+ (umax_frame_num_args): Ditto.
+ * config/ns32k/tm-umax.h (ns32k_localcount): Declare.
+ (flip_bytes): Ditto.
+
+2001-03-28 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-linux-tdep.c (FRAMELESS_SIGNAL): Moved here from
+ config/i386/nm-linux.h (including comment).
+ (i386_linux_frame_chain): New function implementing guts of the
+ former FRAME_CHAIN macro, but using read_memory_unsigned_integer
+ instead of read_memory_integer.
+ (i386_linux_frame_saved_pc): Removed doc pointing to
+ i386/tm-linux.h for an explanation of FRAMELESS_SIGNAL since that
+ now lives in this file.
+ * config/i386/tm-linux.h (FRAMELESS_SIGNAL): Moved to
+ i386-linux-tdep.c (including comment).
+ (FRAME_CHAIN): Redefined in terms of i386_linux_frame_chain.
+ (i386_linux_frame_chain): New prototype.
+
+ * gdbserver/low-linux.c [I386_GNULINUX_TARGET]: Cleanup code and
+ make it work again.
+ (NUM_FREGS): Redefine to 0.
+ (NUM_REGS): Redefine as NUM_GREGS.
+ (i386_register_byte, i386_register_raw_size): Update from
+ i386-tdep.c. Add comment about their origin.
+ (regmap, register_u_addr): Take these from i386-linux-nat.c.
+ (i386_register_u_addr): Removed.
+
+ * i386-linux-nat.c (i386_linux_dr_get): Return 0 if ptrace call
+ fails instead of calling perror_with_name. This should fix
+ debugging remote i386 targets with a native Linux/x86 GDB. Add
+ FIXME for this hack.
+
+2001-03-19 J.T. Conklin <jtc@redback.com>
+
+ * arch-utils.c (#include "gdbthread.h"): Removed.
+ (#include "symfile.h"): Removed.
+ (XMALLOC): Removed unused macro.
+ * breakpoint.c (tbreak_command): Removed local declaration.
+ (awatch_command, do_enable_breakpoint, set_breakpoint_count):
+ Remove duplicate declarations.
+ (bpstat_should_step, bpstat_have_active_hw_watchpoints)
+ (remove_solib_event_breakpoints): Fix indentation botch.
+ * c-typeprint.c (#include "command.h"): Removed.
+ (#include "gdbcmd.h"): Removed.
+ * ch-exp.c (ch_terminal_match_float_literal, parse_expr)
+ (parse_primval, parse_untyped_expr, parse_opt_untyped_expr):
+ Removed duplicate declarations.
+ * ch-typeprint.c (#include "command.h"): Removed.
+ (#include "gdbcmd.h"): Removed.
+ * corefile.c (#include "frame.h"): Removed
+ (#include "symfile.h"): Removed.
+ (#include "language.h"): Removed.
+ * dbxread.c (#include "command.h"): Removed.
+ * environ.c (#include "gdbcore.h"): Removed.
+ * event-loop.c (#include "top.h"): Removed.
+ * f-typeprint.c (#include "command.h"): Removed.
+ (#include "gdbcmd.h"): Removed.
+ (#include "language.h"): Removed.
+ (#include "typeprint.h"): Removed.
+ (#include "frame.h"): Removed.
+ * gdbtypes.h (print_type_scalar): Removed declaration.
+ * infcmd.c (#include "completer.h"): Removed.
+ * language.c (#include "frame.h"): Removed.
+ * m2-typeprint.c (#include "command.h"): Removed.
+ (#include "gdbcmd.h"): Removed.
+ (#include "language.h"): Removed.
+ * m2-valprint.c (#include "valprint.h"): Removed.
+ * p-typeprint.c (#include "command.h"): Removed.
+ (#include "gdbcmd.h"): Removed.
+ * p-valprint.c (#include "typeprint.h"): Removed.
+ * parse.c (#include "linespec.h"): Removed.
+ * regcache.c (#include "frame.h"): Removed.
+ * remote.c (#include "frame.h"): Removed.
+ (getpkt_sane): Make static.
+ * source.c (#include "completer.h"): Removed.
+ * stack.c (#include "symfile.h"): Removed.
+ (#include "objfiles.h"): Removed.
+ * symfile.c (#include "completer.h"): Removed.
+ * tracepoint.c (#include "completer.h"): Removed.
+ * values.c (#include "frame.h"): Removed.
+ * varobj.c (#include "valprint.h"): Removed.
+ * wrapper.c (#include "frame.h"): Removed.
+
+ * memattr.c (create_mem_region): Removed unused variable.
+ * remote-nrom.c: Removed spurious semicolon after init_nrom_ops.
+
+2001-03-27 Nick Clifton <nickc@redhat.com>
+
+ * remote-rdp.c (rdp_set_command_line): Add missing double quote.
+
+2001-03-27 Kevin Buettner <kevinb@redhat.com>
+
+ * solib-aix5.c (build_so_lib_from_mapfile): Use xfree() instead
+ of free().
+
+2001-03-27 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * TODO (Cleanups): Remove the item about converting docs to GFDL.
+
+2001-03-26 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-tdep.c (slotN_contents, replace_slotN_contents): Change
+ type of ``bundle'' from unsigned char * to char *.
+ (ia64_get_saved_register): Use alloca() to allocate register
+ buffers.
+
+ * solib-aix5.c (build_so_lib_from_mapfile): Fix xasprintf() usage.
+
+2001-03-26 Kevin Buettner <kevinb@redhat.com>
+
+ * proc-utils.h (procfs_ctl_t): New typedef.
+ * proc-api.c (write_with_trace): Change type of ``opcode'' from
+ long to procfs_ctl_t. Don't assume that the target has defined
+ BREAKPOINT. Handle case in which PCRESET is the same as PCUNSET.
+ * proc-events.c (sys/syscall.h, sys/fault.h): Include conditionally.
+ * procfs.c (sys/fault.h, sys/syscall.h): Include conditionally.
+ (gdb_sigset_t, gdb_sigaction_t, gdb_siginfo_t, gdb_premptysysset)
+ (gdb_praddsysset, gdb_prdelsysset, gdb_pr_issyssetmember):
+ Conditionally define as appropriate for AIX/non-AIX systems. Use
+ these defines/typedefs as appropriate elsewhere in file.
+ (struct procinfo): Change type of saved_sigset and saved_sighold
+ from sigset_t to gdb_sigset_t. Make saved_exitset and
+ saved_entryset pointer variables. Add two new fields, num_syscalls
+ and syscall_names.
+ (DYNAMIC_SYSCALLS): Define when HAVE_PRSYSENT_T is defined.
+ (sysset_t_size, sysset_t_alloc): New functions.
+ (load_syscalls, free_syscalls, find_syscall): New functions for
+ platforms which define DYNAMIC_SYSCALLS.
+ (create_procinfo): Call load_syscalls.
+ (destroy_one_procinfo): Call free_syscalls.
+ (GDBRESET): Don't define twice.
+ (proc_modify_flag): Change type of operation code array `arg'
+ from long to procfs_ctl_t.
+ (proc_stop_process, proc_wait_for_stop, proc_run_process)
+ (proc_set_traced_signals, proc_set_traced_faults)
+ (proc_set_traced_sysentry, proc_set_traced_sysexit)
+ (proc_set_held_signals, proc_clear_current_fault)
+ (proc_set_current_signal, proc_clear_current_signal, proc_set_gregs)
+ (proc_set_fpregs, proc_kill, proc_set_watchpoint): Likewise for `cmd'.
+ (proc_set_traced_sysentry): Dynamically allocate variable sized
+ struct gdb_proc_ctl_pcsentry. Also, free it at function exit.
+ (proc_set_traced_sysexit): Dynamically allocate variable
+ sized struct gdb_proc_ctl_pcsexit. Also, free it at
+ function exit.
+ (proc_get_traced_sysentry, proc_get_traced_sysexit): Add new code
+ for reading the sysset_t struct on AIX5.
+ (procfs_debug_inferior): Don't assume that SYS_exit will be
+ defined. Add new code for finding certain syscalls on AIX5.
+ (syscall_is_lwp_exit, syscall_is_exit, syscall_is_exec)
+ (syscall_is_lwp_create): New functions.
+ (procfs_wait): Restructured code which checks for certain
+ system calls to use the new syscall_is_... functions.
+ (procfs_notice_signals): Account for the fact that saved_entryset
+ and saved_exitset in struct procinfo are now pointers.
+
+2001-03-26 Kevin Buettner <kevinb@redhat.com>
+
+ * symtab.c (find_pc_sect_line): Revise method used for finding
+ the ending pc.
+
+2001-03-26 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-linux-tdep.c (i386_linux_sigtramp_saved_pc,
+ i386_linux_sigtramp_saved_sp): Make static.
+ (i386_linux_frame_saved_pc): New function based on the old
+ FRAME_SAVED_PC macro, but use read_memory_unsigned_integer instead
+ of read_memory_integer.
+ * config/i386/tm-linux.h (sigtramp_saved_pc): Remove definition.
+ (i386_linux_sigtramp_saved_pc): Remove prototype.
+ (FRAME_SAVED_PC): Redefine in terms of i386_linux_frame_saved_pc.
+ (i386_linux_frame_saved_pc): New prototype.
+
+2001-03-26 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Document m88k as a ``Known problem in 5.1''.
+ * TODO (GDB 5.1 - Cleanups): Update.
+
+2001-03-26 Andrew Cagney <ac131313@redhat.com>
+
+ * fork-child.c (clone_and_follow_inferior): Delete #ifdef
+ HAVE_VFORK.
+
+2001-03-26 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-symmetry.h (PUSH_ARGUMENTS): #undef.
+
+ * i386-tdep.c (i386_push_arguments, i386_store_struct_return): New
+ functions.
+ * config/i386/tm-i386.h (PUSH_ARGUMENTS): New macro.
+ (STORE_STRUCT_RETURN): Redefine in terms of
+ i386_store_struct_return.
+ (i386_push_arguments, i386_store_struct_return): New prototypes.
+ * config/i386/tm-i386v.h (STORE_STRUCT_RETURN): Remove. It's
+ definition was identical to the definition in "i386/tm-i386.h" so
+ the new definition should suffice too.
+
+2001-03-26 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * event-loop.c (toplevel) [!HAVE_POLL] [NO_FD_SET]: Remove unused
+ definitions for SELECT, NBBY, FD_SETSIZE, NFDBITS, and MASK_SIZE.
+
+ * config/djgpp/djconfig.sh: Add copyright notice.
+
+ * ser-go32.c (rawclock): Remove prototype; include time.h instead.
+ (ISR, dos_hookirq, isr_t): Convert K&R definition to ANSI C.
+ (top level) <string.h>: Include gdb_string.h instead.
+ (dos_noop, dos_raw, dos_noflush_set_tty_state)
+ (dos_print_tty_state, dos_info): Remove ATTRIBUTE_UNUSED.
+
+ * go32-nat.c (go32_create_inferior): Move the declaration of
+ `environ' to here from the top level.
+ (top level) <_initialize_go32_nat>: Remove redundant prototype.
+ <gdb_string.h>: Include it instead of string.h.
+ (store_register): Call register_buffer instead of accessing
+ registers[] directly.
+ (redir_cmdline_delete, redir_cmdline_parse, redir_to_debugger)
+ (redir_to_debugger, redir_debug_init) [__DJGPP_MINOR__ < 3]: Put
+ the function names at the start of the line.
+ (go32_set_dr): Throw internal_error if the argument is not a valid
+ debug register number.
+ (go32_open, go32_close, go32_attach, go32_detach, go32_resume)
+ (go32_wait, go32_xfer_memory, go32_files_info)
+ (go32_terminal_info): Remove ATTRIBUTE_UNUSED.
+
+2001-03-25 Jim Blandy <jimb@redhat.com>
+
+ * mips-tdep.c (mips_gdbarch_init): Tweak indentation.
+
+2001-03-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Andrew Cagney <ac131313@redhat.com>
+
+ * coffread.c: Include "gdb_assert.h".
+ (coff_symtab_read): Cast the integer s_sclass to a long before
+ casting it to a pointer.
+
+2001-03-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Andrew Cagney <ac131313@redhat.com>
+
+ * coffread.c (coff_symtab_read): Initialize
+ ``fcn_first_line_addr''. Check that the ``.bf'' always preceeds
+ the ``.ef'' info.
+ * dbxread.c (find_text_range): Initialize ``start'' and ``end''.
+
+2001-03-23 Andrew Cagney <ac131313@redhat.com>
+
+ * config/sparc/tm-sp64.h (GDB_MULTI_ARCH): Down grade to
+ GDB_MULTI_ARCH_PARTIAL from two. SOFTWARE_SINGLE_STEP is not
+ multi-arch.
+
+ * gdbarch.sh (SOFTWARE_SINGLE_STEP): Add.
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+ * target.h (SOFTWARE_SINGLE_STEP_P)
+ (SOFTWARE_SINGLE_STEP): Delete macro definitions.
+
+2001-03-23 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (gdbarch_register_read, gdbarch_register_write): Add.
+ * gdbarch.h, gdbarch.c: Regenerate.
+
+ * regcache.h (regcache_read, regcache_write): Declare.
+ (registers, register_valid, register_buffer): Add note that these
+ interfaces are deprecated.
+
+ * regcache.c: Include "gdb_assert.h".
+ (legacy_write_register_gen): Rename write_register_gen.
+ (legacy_read_register_gen): Rename read_register_gen.
+ (regcache_read, regcache_write): New function.
+ (read_register_gen, write_register_gen): New function.
+ (write_register): Simplify. Use write_register_gen.
+ (read_register): Ditto using read_register_gen.
+ (read_signed_register): Ditto.
+ (read_register_bytes): Ditto!!!!
+ (supply_register): Add note that CLEANUP_REGISTER_VALUE is being
+ replaced by gdbarch_register_read.
+
+ * TODO (GDB 5.2 - Cleanups): Add list of gdbarch methods to
+ deprecate.
+
+2001-03-23 Jim Blandy <jimb@redhat.com>
+
+ Fix from Dan Berlin:
+
+ * stabsread.c (read_cpp_abbrev): Properly construct the names of
+ virtual function table pointer fields.
+
+2001-03-19 Andrew Cagney <ac131313@redhat.com>
+
+ * defs.h (xfree, mcalloc, mmalloc, mrealloc, mfree, xmmalloc,
+ xmrealloc): Move existing declarations to the one place and
+ re-order to be consistent.
+ (xmcalloc, xmfree): Declare.
+ (xmmalloc, xmrealoc): Assume ISO-C - use size_t and void* in
+ declaration.
+
+ * utils.c (size_t): Delete #ifdef defining size_t.
+ (mmalloc, mrealloc, mcalloc, mfree): Re-order.
+ (mmalloc, mrealloc, mcalloc): Document as only calls in GDB
+ corresponding malloc, realloc, calloc.
+ (mfree): Call free directly.
+ (xmmalloc, xmrealloc): Clean up. Assume ISO-C.
+ (xmcalloc, xmfree): New functions. Copy old xcalloc and xfree
+ function bodies to here.
+ (xcalloc, xfree): Call xmcalloc and xmfree respectfully.
+
+2001-03-23 Andrew Cagney <ac131313@redhat.com>
+
+ * fork-child.c (fork_inferior): Make ``argv'', ``exec_file'' and
+ ``shell_file'' static locals.
+
+ * jv-lang.c (java_link_class_type): Initialize ``field'' and
+ ``method''.
+
+ * jv-valprint.c (java_value_print): Initialize ``next_element''.
+
+2001-03-23 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/nm-i386.h: Fix formatting and change reference to
+ i386-tdep.c to i386-nat.c.
+
+2001-03-23 David Smith <dsmith@redhat.com>
+
+ * configure.in: Corrected spelling errors.
+ * configure: Regenerated.
+
+2001-03-22 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO (GDB 5.1 - Cleanups): Add more targets to obsolete.
+
+2001-03-22 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in (NTSSTART): Delete.
+ (NTSOBS): Delete.
+ (kdb): Delete target.
+ * kdb-start.c, stuff.c: Mark as obsolete.
+ * NEWS: Update.
+
+2001-03-22 Andrew Cagney <ac131313@redhat.com>
+
+ * config/pa/xm-hppah.h (HPPA_COMPILER_BUG): Delete. GDB only
+ compiles using an ISO-C compiler.
+ (MALLOC_INCOMPATIBLE): Ditto.
+ * linespec.c (decode_line_1): Delete hack to work around
+ HPPA_COMPILER_BUG.
+
+2001-03-22 Andrew Cagney <ac131313@redhat.com>
+
+ * exec.c (xfer_memory): Always initialize section.
+ * infrun.c (normal_stop): Always initialize source_flag.
+
+2001-03-22 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO (Remote Protocol Support): Review. Add notes about ``!'',
+ non-use of a continue address and typical use of ``q'' packet.
+
+2001-03-22 Eli Zaretskii <eliz@is.elta.co.il>
+
+ Make DJGPP use the new unified support for hardware
+ breakpoints and watchpoints on x86 targets:
+
+ * config/i386/nm-go32.h <top level>: Don't include nm-i386v.h,
+ include nm-i386.h instead.
+ (TARGET_HAS_HARDWARE_WATCHPOINTS, HAVE_CONTINUABLE_WATCHPOINT)
+ (TARGET_CAN_USE_HARDWARE_WATCHPOINT, STOPPED_BY_WATCHPOINT)
+ (TARGET_REGION_OK_FOR_HW_WATCHPOINT, DECR_PC_AFTER_HW_BREAK)
+ (target_stopped_data_address, target_insert_watchpoint)
+ (target_remove_watchpoint, target_insert_hw_breakpoint)
+ (target_remove_hw_breakpoint): Don't define.
+ (I386_USE_GENERIC_WATCHPOINTS, I386_DR_LOW_SET_CONTROL)
+ (I386_DR_LOW_SET_ADDR, I386_DR_LOW_RESET_ADDR)
+ (I386_DR_LOW_GET_STATUS): Define to call appropriate go32_*
+ functions from go32-nat.c.
+
+ * config/i386/go32.mh (NATDEPFILES): Add i386-nat.o.
+
+ * go32-nat.c <top level>: Remove prototypes for watchpoint-
+ related functions. Remove definitions of watchpoint-related
+ macros.
+ (go32_mourn_inferior): Call i386_cleanup_dregs instead of the
+ private cleanup_dregs function.
+ (cleanup_dregs, go32_insert_watchpoint)
+ (go32_insert_aligned_watchpoint, go32_handle_nonaligned_watchpoint)
+ (go32_remove_watchpoint, go32_remove_aligned_watchpoint)
+ (go32_region_ok_for_watchpoint, go32_stopped_by_watchpoint)
+ (go32_remove_hw_breakpoint, go32_insert_hw_breakpoint): Remove.
+ (go32_set_dr, go32_set_dr7, go32_get_dr6): New functions.
+
+2001-03-21 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-tdep.c (fetch_instruction): Warn about slot numbers greater
+ than two instead of generating an error.
+
+2001-03-21 Jim Blandy <jimb@redhat.com>
+
+ * cp-valprint.c: Reformat to bring into line with GNU coding
+ standards.
+
+2001-03-21 Mark Kettenis <kettenis@gnu.org>
+
+ Make Linux use the new unified support for hardware breakpoints
+ and watchpoints on x86 targets.
+ * i386-linux-nat.c: Doc fixes. Include "gdb_assert.h".
+ [HAVE_SYS_DEBUGREG_H]: Include <sys/debugreg.h>.
+ (DR_FIRSTADDR, DR_LASTADDR, DR_STATUS, DR_CONTROL): Define to
+ appropriate value if not already defined.
+ (register_u_addr): New function.
+ (kernel_u_size): New function.
+ (i386_linux_dr_get, i386_linux_dr_set): New functions.
+ (i386_linux_dr_set_control, i386_linux_dr_set_addr,
+ i386_linux_reset_addr, i386_linux_dr_get_status): New functions.
+ * config/i386/nm-linux.h: Don't include "nm-i386v.h".
+ (I386_USE_GENERIC_WATCHPOINTS): Define and include "nm-i386.h".
+ (TARGET_HAS_HARDWARE_WATCHPOINTS,
+ TARGET_CAN_USE_HARDWARE_WATCHPOINTS, HAVE_CONTINUABLE_WATCHPOINT,
+ STOPPED_BY_WATCHPOINT, target_insert_watchpoint,
+ target_remove_watchpoint): Remove macros.
+ (i386_stopped_by_watchpoint, i386_insert_watchpoint,
+ i386_remove_watchpoint): Remove prototypes.
+ (register_u_addr): New prototype.
+ (REGISTER_U_ADDR): Define in terms of register_u_addr.
+ (i386_linux_dr_set_control, i386_linux_dr_set_addr,
+ i386_linux_reset_addr, i386_linux_dr_get_status): New prototypes.
+ (I386_DR_LOW_SET_CONTROL, I386_DR_LOW_SET_ADDR,
+ I386_DR_LOW_RESET_ADDR, I386_DR_LOW_GET_STATUS): New macros.
+ * config/i386/linux.mh (NATDEPFILES): Replace i386v-nat.o with
+ i386-nat.o.
+
+2001-03-21 Jim Blandy <jimb@redhat.com>
+
+ Fix from Dan Berlin:
+
+ * linespec.c (find_methods): Whitespace differences aren't
+ significant in *un*mangled method names. Use strcmp_iw to compare
+ them, not STREQ.
+
+2001-03-21 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh: Allow a non- multi-arch target to override a
+ predicate.
+ * gdbarch.h: Regenerate.
+
+2001-03-21 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh: Avoid use of ``!''.
+
+2001-03-20 Andrew Cagney <ac131313@redhat.com>
+
+ * target.h (enum target_signal): Move definition from here.
+ * defs.h (enum target_signal): To here.
+
+ * config/arc/tm-arc.h (arc_software_single_step): Change type of
+ first parameter to enum target_signal.
+ * config/rs6000/tm-rs6000.h (rs6000_software_single_step): Ditto.
+ * config/sparc/tm-sparc.h (sparc_software_single_step): Ditto.
+ * rs6000-tdep.c (rs6000_software_single_step): Update.
+
+2001-03-20 Andrew Cagney <ac131313@redhat.com>
+
+ * frame.h (SIZEOF_FRAME_SAVED_REGS): Report an error if macro
+ already defined.
+
+ From 2000-08-25 Stephane Carrez <Stephane.Carrez@worldnet.fr>:
+ * stabsread.c (define_symbol): A parameter ('R'), a local ('r'),
+ or a reference ('a') can be in a pseudo register.
+ * infcmd.c (do_registers_info): Must take into account the pseudo
+ registers to print their value.
+ (registers_info): Likewise.
+ * stack.c (frame_info): Likewise.
+ * frame.h (SIZEOF_FRAME_SAVED_REGS): Save the pseudo registers.
+
+2001-03-21 Eli Zaretskii <eliz@is.elta.co.il>
+
+ Unified support for hardware breakpoints and watchpoints on
+ x86 targets:
+
+ * config/i386/nm-i386.h: New file.
+
+ * config/i386/nm-i386.h: (i386_cleanup_dregs)
+ (i386_insert_watchpoint, i386_remove_watchpoint)
+ (i386_region_ok_for_watchpoint, i386_stopped_by_hwbp)
+ (i386_stopped_data_address, i386_insert_hw_breakpoint)
+ (i386_remove_hw_breakpoint): Declare prototypes.
+ [I386_USE_GENERIC_WATCHPOINTS] (TARGET_CAN_USE_HARDWARE_WATCHPOINT):
+ Define if not already defined.
+ (TARGET_REGION_OK_FOR_HW_WATCHPOINT, HAVE_CONTINUABLE_WATCHPOINT)
+ (STOPPED_BY_WATCHPOINT, target_stopped_data_address)
+ (target_insert_watchpoint, target_remove_watchpoint)
+ (target_insert_hw_breakpoint, target_remove_hw_breakpoint): Define
+ to call the appropriate i386_* functions.
+
+ * i386-nat.c: New file.
+
+ * i386-nat.c (I386_DR_CONTROL_MASK, I386_DR_LOCAL_ENABLE)
+ (I386_DR_GLOBAL_ENABLE, I386_DR_DISABLE, I386_DR_SET_RW_LEN)
+ (I386_DR_GET_RW_LEN, I386_DR_WATCH_HIT): New macros.
+ (dr_mirror, dr_status_mirror, dr_control_mirror, dr_ref_count)
+ (maint_show_dr): New variables.
+ (i386_cleanup_dregs, i386_show_dr, i386_length_and_rw_bits)
+ (i386_insert_aligned_watchpoint, i386_remove_aligned_watchpoint)
+ (i386_handle_nonaligned_watchpoint, i386_insert_watchpoint)
+ (i386_remove_watchpoint, i386_region_ok_for_watchpoint)
+ (i386_stopped_data_address, i386_stopped_by_hwbp)
+ (i386_insert_hw_breakpoint, i386_remove_hw_breakpoint): New
+ functions.
+ (_initialize_i386_nat): New function.
+ [I386_USE_GENERIC_WATCHPOINTS]: Add new maint command
+ `show-debug-regs', sets maint_show_dr to non-zero value and
+ activates debugging print-outs in functions which insert, remove,
+ and test watchpoints and hardware breakpoints.
+
+ * Makefile.in (i386-nat.o): New target.
+ (ALLDEPFILES): Add i386-nat.o.
+
+2001-03-21 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-tdep.c: Add back _initialize_i386_tdep prototype with
+ appropriate comment.
+
+2001-03-20 Kevin Buettner <kevinb@redhat.com>
+
+ * config/alpha/alpha-linux.mh (NATDEPFILES): Use proc-service.o,
+ thread-db.o, and lin-lwp.o for thread support instead of
+ linux-thread.o and lin-thread.o.
+ * config/alpha/nm-linux.h (PREPARE_TO_PROCEED, GET_THREAD_SIGNALS)
+ (ATTACH_LWP): Define to use the following lin-lwp.c functions...
+ (lin_lwp_prepare_to_proceed, lin_thread_get_thread_signals)
+ (lin_lwp_attach_lwp): Declare.
+
+2001-03-20 Jim Blandy <jimb@redhat.com>
+
+ Fix from Dan Berlin:
+
+ * Makefile.in: Clean up dependencies on ../include/demangle.h.
+ (demangle_h): New variable.
+ (jv-typeprint.o, jv-valprint.o, linespec.o): Use it.
+
+2001-03-20 Andrew Cagney <ac131313@redhat.com>
+
+ * target.h (SOFTWARE_SINGLE_STEP_P): Add empty parameter list.
+ * breakpoint.c (bpstat_stop_status): Update.
+ * infrun.c (handle_inferior_event): Ditto.
+ * mips-tdep.c (mips_dump_tdep): Ditto.
+ * infrun.c (resume): Ditto.
+ * infptrace.c (child_resume): Ditto.
+ * config/mips/tm-wince.h (SOFTWARE_SINGLE_STEP_P): Ditto.
+ * config/sh/tm-wince.h (SOFTWARE_SINGLE_STEP_P): Ditto.
+ * config/sparc/tm-sparc.h (SOFTWARE_SINGLE_STEP_P): Ditto.
+ * config/powerpc/tm-linux.h (SOFTWARE_SINGLE_STEP_P): Ditto.
+ * config/arm/tm-wince.h (SOFTWARE_SINGLE_STEP_P): Ditto.
+ * config/arc/tm-arc.h (SOFTWARE_SINGLE_STEP_P): Ditto.
+ * config/powerpc/tm-ppc-eabi.h (SOFTWARE_SINGLE_STEP_P): Ditto.
+
+2001-03-20 Andrew Cagney <ac131313@redhat.com>
+
+ * config/powerpc/tm-linux.h (SOFTWARE_SINGLE_STEP): Replace abort
+ with internal_error.
+
+2001-03-20 Jim Blandy <jimb@redhat.com>
+
+ Fix from Dan Berlin:
+
+ * linespec.c (find_methods): Just call CHECK_TYPEDEF on t, rather
+ than asking for sym_class's type; that's circuitous. Remove
+ sym_class, since the last use of it is gone.
+
+2001-03-20 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * breakpoint.c (print_it_typical) <bp_access_watchpoint> [UI_OUT]:
+ Correct the order of calls to ui_out_field_string and
+ ui_out_list_begin when bs->old_val is NULL.
+
+2001-03-19 Kevin Buettner <kevinb@redhat.com>
+
+ * configure.in (AC_CHECK_HEADERS): Check for existence of nlist.h.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * solib-legacy.c (nlist.h): Include if HAVE_NLIST_H is defined.
+
+2001-03-19 Kevin Buettner <kevinb@redhat.com>
+
+ * config/i386/i386v42mp.mh (NATDEPFILES): List all files on
+ same line to avoid problems with Unixware 7's make when building
+ a cross debugger.
+
+2001-03-19 Andrew Cagney <ac131313@redhat.com>
+
+ * defs.h (malloc): Move declaration from here.
+ * utils.c (malloc): To here.
+ * config/pa/xm-hppah.h (malloc): Delete declaration.
+
+ * gnu-nat.c (make_proc): Use xmalloc instead of malloc.
+ * hp-psymtab-read.c (hpread_call_pxdb): Ditto.
+ (hpread_quick_traverse): Ditto.
+ * infttrace.c (create_thread_info): Ditto.
+ (kill_inferior): Ditto.
+ * gnu-nat.c (make_inf): Ditto, and don't check return value.
+ * procfs.c (proc_update_threads): Ditto.
+ * valprint.c (print_decimal_chars): Ditto.
+ * gdbtypes.c (cfront_mangle_name): Use xasprintf instead of
+ malloc and sprintf.
+ * remote-rdp.c (rdp_set_command_line): Ditto.
+
+2001-03-19 Andrew Cagney <ac131313@redhat.com>
+
+ * defs.h (realloc): Move declaration from here.
+ * utils.c (realloc): To here.
+ * config/pa/xm-hppah.h (realloc): Delete declaration.
+ * lin-thread.c (insert_thread): Use xrealloc instead of realloc.
+ * symfile.c (add_filename_language): Ditto.
+ * event-loop.c (create_file_handler): Ditto.
+
+2001-03-19 Andrew Cagney <ac131313@redhat.com>
+
+ * defs.h (free): Move declaration from here.
+ * utils.c (free): To here.
+ (xfree): Document as the only call to free().
+ * config/pa/xm-hppah.h (free): Delete declaration.
+
+2001-03-19 Kevin Buettner <kevinb@redhat.com>
+
+ * config/ia64/linux.mh (NATDEPFILES): Add proc-service.o to
+ this list.
+
+2001-03-19 Andrew Cagney <ac131313@redhat.com>
+
+ * eval.c (evaluate_subexp): Remove #ifdef __STDC__ and ``inline''.
+ * config/mips/xm-mips.h (offsetof): Define when !GNUC not !STDC.
+ * cli/cli-cmds.c (init_cli_cmds): Remove #ifdef __STDC__
+
+2001-03-19 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO: List known problems with TUI.
+
+2001-03-19 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Jimmy Guo stepped down as a maintiner (TUI,
+ gdb.hp).
+
+2001-03-19 Andrew Cagney <ac131313@redhat.com>
+
+ * remote.c (remote_cisco_section_offsets): Do not cast result from
+ bfd_get_section_name.
+ (compare_sections_command): Ditto.
+ (remote_cisco_section_offsets): Make ``p'' a const pointer.
+ (compare_sections_command): Ditto for ``sectname''.
+
+2001-03-19 Andrew Cagney <ac131313@redhat.com>
+
+ From Mon Nov 20 13:59:29 2000 Andrew Cagney <cagney@b1.cygnus.com>:
+ * valops.c (hand_function_call): Simplify computation of the
+ address of the pushed argument.
+
+2001-03-17 Andrew Cagney <ac131313@redhat.com>
+
+ * p-exp.y (parse_number): Avoid shift overflow when ``long''.
+ Code copied from c-exp.y.
+
+2001-03-18 Kevin Buettner <kevinb@redhat.com>
+
+ * acconfig.h (HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS)
+ (HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS)
+ (HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS): New configure macros.
+ * configure.in (HAVE_STRUCT_LINK_MAP32): Move this test out
+ of the Solaris procfs testing section. Instead, group with...
+ (HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS)
+ (HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS)
+ (HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS): New <link.h> tests.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+
+ * solib-legacy.c (legacy_svr4_fetch_link_map_offsets): Use
+ new configure macros to choose which (if any) code to
+ compile in. Added code to explicitly handle *BSD systems;
+ these systems were previously handled only through macro
+ redefinition. Also, due to the way the autoconf tests are set
+ up, this function will no longer return a non-zero value when
+ GDB is configured as a cross debugger. I.e, cross debuggers
+ will no longer be able to "accidentally" get the host system's
+ link map offsets.
+
+2001-03-18 Kevin Buettner <kevinb@redhat.com>
+
+ * config/i386/nbsd.mh (NATDEPFILES): List all files on the same
+ line to avoid build problem on NetBSD 1.4.
+
+2001-03-17 Michael Chastain <chastain@redhat.com>
+
+ * win32-nat.c (child_attach): check args for NULL before passing
+ to strtoul. This fixes PR gdb/43.
+
+2001-03-17 Mark Kettenis <kettenis@gnu.org>
+
+ * i387-nat.h: Doc Fix.
+
+ * i386-tdep.c: Fix formatting.
+ (i386_get_frame_setup, i386_follow_jump, codestream_read,
+ codestream_seek, codestream_fill, skip_trampoline_code,
+ gdb_print_insn_i386, _initialize_i386_tdep): Remove redundant
+ prototypoes.
+
+2001-03-17 Mark Kettenis <kettenis@gnu.org>
+
+ * config/i386/tm-linux.h (TARGET_ANALYZE_FLOATING): Remove. It's
+ no longer used. Also remove associated FIXME.
+
+2001-03-16 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh: Add classes ``m'' and ``M'' for pure multi-arch. Do
+ not generate macro wrappers for multi-arch functions or
+ predicates.
+ (class_is_info_p, class_is_predicate_p): Update.
+ (class_is_function_p, class_is_variable_p): Ditto.
+ (class_is_multiarch_p): New class function.
+
+2001-03-16 J.T. Conklin <jtc@redback.com>
+
+ * config/h8300/tm-h8300.h (FRAME_ARGS_ADDRESS): Changed to use
+ h8300_frame_args_address from frame_args_address.
+ (FRAME_LOCALS_ADDRESS): Changed to use h8300_frame_locals_address
+ from frame_locals_address.
+ (PRINT_REGISTER_HOOK): Changed to use h8300_print_register_hook
+ from print_register_hook.
+ (h8300_frame_args_address): Declare.
+ (h8300_frame_find_saved_regs): Declare.
+ (h8300_frame_locals_address): Declare.
+ (h8300_frame_saved_pc): Declare.
+ (h8300_pop_frame): Declare.
+ (h8300_print_register_hook): Declare.
+ * h8300-tdep.c (h8300_frame_find_saved_regs): Removed declaration.
+ (h8300_frame_args_address): Renamed from frame_args_address.
+ (h8300_frame_locals_address): Renamed from frame_locals_address.
+ (h8300_pop_frame): Renamed from pop_frame.
+ (h8300_print_register_hook): Renamed from print_register_hook.
+
+2001-03-16 Kevin Buettner <kevinb@redhat.com>
+
+ * solib-svr4.c (bfd_lookup_symbol): Change type of
+ ``storage_needed'' from unsigned int to long in order to
+ match return type of bfd_get_symtab_upper_bound() and
+ bfd_get_dynamic_symtab_upper_bound().
+ * solib-aix5.c (bfd_lookup_symbol): Likewise. Also, eliminate
+ REASONABLE_LIMIT hack which had been added to work around this
+ problem.
+
+2001-03-15 Kevin Buettner <kevinb@redhat.com>
+
+ * solib-aix5.c (bfd_lookup_symbol, build_so_list_from_mapfile)
+ (aix5_relocate_main_executable, aix5_clear_solib): Replace calls
+ to free() with calls to xfree().
+ (bfd_lookup_symbol): Eliminate use of PTR.
+ (build_so_list_from_mapfile): Use xasprintf() instead of sprintf().
+
+2001-03-15 Martin Hunt <hunt@redhat.com>
+
+ * linespec.c (decode_line_1): Remove trailing quote
+ when parsing double quotes.
+
+2001-03-15 Kevin Buettner <kevinb@redhat.com>
+
+ * uw-thread.c (read_thr_debug, read_map, read_lwp, thread_iter)
+ (libthread_stub, libthread_init): Pass NULL for the mem_attrib
+ argument in the to_xfer_memory calls.
+
+2001-03-15 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Fix typo - w65 not w64. Still doesn't build.
+ * TODO (GDB 5.1 - Cleanups): Add status of targets being obsoleted.
+
+2001-03-15 Andrew Cagney <ac131313@redhat.com>
+
+ * wince.c (child_xfer_memory): Add attrib parameter.
+ * symm-nat.c (child_xfer_memory): Ditto.
+ * mac-nat.c (child_xfer_memory): Ditto.
+ * infttrace.c (child_xfer_memory): Ditto.
+ * procfs.c (procfs_xfer_memory): Ditto.
+ * lin-thread.c (thread_db_xfer_memory): Ditto.
+ * gnu-nat.c (gnu_xfer_memory): Ditto.
+
+2001-03-14 Andrew Cagney <ac131313@redhat.com>
+
+ * NEWS: Mention that Harris/CXUX m88k is obsolete.
+
+2001-03-13 Andrew Cagney <ac131313@redhat.com>
+
+ * config/mips/tm-mips.h: Include "regcache.h" for macros refering
+ to regcache functions.
+ * config/m68k/tm-m68k.h: Ditto.
+ * config/i386/tm-i386v.h: Ditto.
+ * config/mcore/tm-mcore.h: Ditto.
+ * config/m88k/tm-m88k.h: Ditto.
+ * config/m68k/tm-news.h: Ditto.
+ * config/m68k/tm-linux.h: Ditto.
+ * config/m68k/tm-delta68.h: Ditto.
+ * config/m68k/nm-sun3.h: Ditto.
+ * config/m32r/tm-m32r.h: Ditto.
+ * config/i386/tm-symmetry.h: Ditto.
+ * config/i386/tm-sun386.h: Ditto.
+ * config/i386/tm-i386.h: Ditto.
+ * config/i386/nm-symmetry.h: Ditto.
+ * config/i386/nm-sun386.h: Ditto.
+ * config/i386/nm-ptx4.h: Ditto.
+ * config/i386/nm-i386mach.h: Ditto.
+ * config/h8500/tm-h8500.h: Ditto.
+ * config/h8300/tm-h8300.h: Ditto.
+ * config/fr30/tm-fr30.h: Ditto.
+ * config/d30v/tm-d30v.h: Ditto.
+ * config/arm/tm-arm.h: Ditto.
+ * config/arc/tm-arc.h: Ditto.
+ * config/alpha/tm-alpha.h: Ditto.
+ * config/a29k/tm-vx29k.h: Ditto.
+ * config/a29k/tm-a29k.h: Ditto.
+ * config/w65/tm-w65.h: Ditto.
+ * config/vax/tm-vax.h: Ditto.
+ * config/v850/tm-v850.h: Ditto.
+ * config/tic80/tm-tic80.h: Ditto.
+ * config/sparc/tm-sparclite.h: Ditto.
+ * config/sparc/tm-sparclet.h: Ditto.
+ * config/sparc/tm-sparc.h: Ditto.
+ * config/sparc/nm-sun4sol2.h: Ditto.
+ * config/sparc/nm-sun4os4.h: Ditto.
+ * config/sparc/nm-nbsd.h: Ditto.
+ * config/powerpc/nm-solaris.h: Ditto.
+ * config/pa/tm-hppao.h: Ditto.
+ * config/pa/tm-hppa.h: Ditto.
+ * config/pa/nm-hppab.h: Ditto.
+ * config/ns32k/tm-umax.h: Ditto.
+ * config/ns32k/tm-merlin.h: Ditto.
+ * config/nm-m3.h: Ditto.
+ * config/nm-gnu.h: Ditto.
+
+2001-03-14 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Update list of targets. Mark arm-* and v850-elf as
+ broken. Mark sh-*, ia64-linux and ns32k-netbsd as buildable.
+ Specify an m88k target. Include sample GAWK script to generate
+ target list. Delete non-existant romp target.
+ * TODO (GDB 5.1 - Cleanups): Update.
+
+2001-03-14 Keith Seitz <keiths@cygnus.com>
+
+ * linespec.c (decode_line_1): Skip argptr over a leading
+ double quote. Prevents alloc of 0 bytes and memcpy of -1 bytes.
+
+2001-03-14 Kevin Buettner <kevinb@redhat.com>
+
+ * config/djgpp/fnchange.lst (ia64-aix-nat.c): Add entry.
+
+2001-03-13 Andrew Cagney <ac131313@redhat.com>
+
+ * ui-out.h: Remove #if __STDC__, assume an ISO-C compiler.
+ * m3-nat.c: Ditto.
+ * p-lang.h: Ditto.
+ * printcmd.c (printf_command): Ditto.
+ * ch-exp.c (match_integer_literal): Ditto.
+ * scm-tags.h: Ditto.
+ * ser-go32.c: Ditto.
+ * hppa-tdep.c (unwind_command): Ditto.
+ * defs.h (volatile): Delete macro definition. Assume __STDC__.
+ * remote-adapt.c (volatile): Ditto.
+ * remote-eb.c (volatile): Ditto.
+ * remote-mm.c (volatile): Ditto.
+ * defs.h (alloca): Assume __STDC__, declare returning void *.
+
+2001-03-08 Andrew Cagney <ac131313@redhat.com>
+
+ * inferior.h (ARCH_NUM_REGS): Delete definition.
+ * stack.c (frame_info): Use NUM_REGS, not ARCH_NUM_REGS.
+ * regcache.c (registers_changed): Ditto.
+ (registers_fetched): Ditto.
+ * infptrace.c (fetch_inferior_registers): Ditto.
+ (store_inferior_registers): Ditto.
+ * infcmd.c (do_registers_info): Ditto.
+ (registers_info): Ditto.
+ * i386-linux-nat.c (old_fetch_inferior_registers): Ditto.
+ (old_store_inferior_registers): Ditto.
+ * gdbserver/low-linux.c (register_addr): Ditto.
+ * gdbserver/low-hppabsd.c (register_addr): Ditto.
+ * core-aout.c: Don't include "inferior.h".
+ (fetch_core_registers): Use NUM_REGS not ARCH_NUM_REGS.
+ (register_addr): Ditto.
+
+2001-03-13 Fernando Nasser <fnasser@redhat.com>
+
+ From Steven Johnson <sjohnson@neurizon.net>
+ * cli/cli-script.c (define_command): Fix setting of post hooks.
+
+2001-03-13 Mark Kettenis <kettenis@gnu.org>
+
+ * i386-linux-tdep.c: Fix formatting and clarify comments.
+ (i386_linux_svr4_fetch_link_map_offsets): Use NULL instead of 0
+ where appropriate.
+
+2001-03-12 Andrew Cagney <ac131313@redhat.com>
+
+ * gnu-nat.c: Include "gdb_assert.h" instead of <assert.h>.
+ (proc_update_sc): Use gdb_assert instead of assert.
+ (proc_abort): Ditto.
+ (inf_set_step_thread): Ditto.
+ (gnu_wait): Ditto.
+ (S_exception_raise_request): Ditto.
+ (gnu_terminal_init_inferior): Ditto.
+
+2001-03-09 Kevin Buettner <kevinb@redhat.com>
+
+ * Makefile.in (solib-svr4.o): Depend on solib-svr4.c, not solib.c.
+ (solib-legacy.o): New makefile target.
+ * solib-legacy.c: New file.
+ * solib-svr4.h (SVR4_FETCH_LINK_MAP_OFFSETS): Delete.
+ (default_svr4_fetch_link_map_offsets): Delete.
+ (set_solib_svr4_fetch_link_map_offsets): Declare.
+ (legacy_svr4_fetch_link_map_offsets_hook): Declare.
+ * solib-svr4.c (elf/common.h): Include.
+ (link.h): Only include for SunOS shared library support.
+ (_SYSCALL32): Don't define.
+ (SVR4_FETCH_LINK_MAP_OFFSETS): Define.
+ (default_svr4_fetch_link_map_offsets): Made static; added forward
+ declaration.
+ (fetch_link_map_offsets): New static global.
+ (legacy_svr4_fetch_link_map_offsets_hook): New global variable.
+ (default_svr4_fetch_link_map_offsets): Rewritten. The guts
+ of what used to be in this function now reside in
+ legacy_svr4_fetch_link_map_offsets() in solib-legacy.c.
+ (open_symbol_file_object): Fix declaration in SunOS section
+ of the code.
+ (set_solib_svr4_fetch_link_map_offsets): New extern function.
+ (init_fetch_link_map_offsets): New static function.
+ (_initialize_svr4_solib): Put static global fetch_link_map_offsets
+ under multiarch control.
+
+ * config/alpha/alpha-linux.mt (TDEPFILES): Add solib-legacy.o to
+ list.
+ * config/alpha/fbsd.mh (NATDEPFILES): Likewise.
+ * config/arm/linux.mt (TDEPFILES): Likewise.
+ * config/i386/fbsd.mh (NATDEPFILES): Likewise.
+ * config/i386/i386dgux.mh (NATDEPFILES): Likewise.
+ * config/i386/i386gnu.mh (NATDEPFILES): Likewise.
+ * config/i386/i386sco5.mh (NATDEPFILES): Likewise.
+ * config/i386/i386sol2.mt (TDEPFILES): Likewise.
+ * config/i386/i386v4.mh (NATDEPFILES): Likewise.
+ * config/i386/i386v42mp.mh (NATDEPFILES): Likewise.
+ * config/i386/linux.mt (TDEPFILES): Likewise.
+ * config/i386/nbsd.mh (NATDEPFILES): Likewise.
+ * config/i386/nbsdelf.mh (NATDEPFILES): Likewise.
+ * config/i386/ncr3000.mt (TDEPFILES): Likewise.
+ * config/i386/ptx4.mh (XDEPFILES): Likewise.
+ * config/i386/sun386.mt (TDEPFILES): Likewise.
+ * config/ia64/linux.mt (TDEPFILES): Likewise.
+ * config/m68k/linux.mt (TDEPFILES): Likewise.
+ * config/m68k/m68kv4.mh (NATDEPFILES): Likewise.
+ * config/m68k/nbsd.mh (NATDEPFILES): Likewise.
+ * config/m68k/sun2os4.mt (TDEPFILES): Likewise.
+ * config/m68k/sun3os4.mt (TDEPFILES): Likewise.
+ * config/m88k/delta88v4.mh (NATDEPFILES): Likewise.
+ * config/mips/mipsv4.mh (NATDEPFILES): Likewise.
+ * config/ns32k/nbsd.mh (NATDEPFILES): Likewise.
+ * config/powerpc/linux.mt (TDEPFILES): Likewise.
+ * config/powerpc/nbsd.mh (NATDEPFILES): Likewise.
+ * config/powerpc/solaris.mh (NATDEPFILES): Likewise.
+ * config/sh/linux.mt (TDEPFILES): Likewise.
+ * config/sparc/linux.mt (TDEPFILES): Likewise.
+ * config/sparc/nbsd.mh (NATDEPFILES): Likewise.
+ * config/sparc/nbsdelf.mh (NATDEPFILES): Likewise.
+ * config/sparc/sp64linux.mt (TDEPFILES): Likewise.
+ * config/sparc/sun4os4.mt (TDEPFILES): Likewise.
+ * config/sparc/sun4sol2.mh (NATDEPFILES): Likewise.
+
+2001-03-09 Kevin Buettner <kevinb@redhat.com>
+
+ * utils.c (xmrealloc, xcalloc): Return NULL for zero-sized requests.
+
+2001-03-09 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS (Write After Approval): Update Philip Blundell.
+
+2001-03-09 Keith Seitz <keiths@cygnus.com>
+
+ * MAINTAINERS: Add myself to write after approval list.
+
+2001-03-09 Mark Kettenis <kettenis@gnu.org>
+
+ * i387-tdep.c (print_i387_status_word): Fix printing of Stack
+ fault flag. It is bit 6 of the x87 FPU status word, not bit 7.
+
+2001-03-08 Andrew Cagney <ac131313@redhat.com>
+
+ * configure.host (m88*-harris-cxux*): Mark as obsolete.
+ * configure.tgt: Ditto.
+ * config/m88k/xm-cxux.h: Ditto.
+ * config/m88k/tm-cxux.h: Ditto.
+ * config/m88k/nm-cxux.h: Ditto.
+ * config/m88k/cxux.mt: Ditto.
+ * config/m88k/cxux.mh: Ditto.
+
+2001-03-08 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in: Delete rules for obsolete files.
+
+Thu Mar 8 15:43:40 2001 David Taylor <taylor@redhat.com>
+
+ * stack.c (parse_frame_specification): For one argument case,
+ handle the situation where the argument is an integer, not an
+ address -- arguably the most common case. This matters on
+ targets where pointers and addresses are different.
+
+2001-03-08 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO: Revise 5.1 list. Delete PARAMS task. Add coding standard
+ review. Clarify GNU/LINUX/sparc. Move other tasks to 5.2 or
+ general.
+
+2001-03-07 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO (GDB 5.1 Known Problems): Document problem of building GDB
+ with SID on Solaris 8.
+
+2001-03-07 Mark Kettenis <kettenis@gnu.org>
+
+ * defs.h: Provide prototypes for floatformat_is_negative,
+ floatformat_is_nan and floatformat_mantissa.
+ * utils.c: Include "gdb_assert.h".
+ (floatformat_is_negative): New function.
+ (floatformat_is_nan): New function.
+ (floatformat_mantissa): New function.
+ * valprint.c: Include "floatformat.h".
+ (print_floating): Get rid of the Linux-specific
+ TARGET_ANALYZE_FLOATING macro and rewrite NaN detection with the
+ help these new functions. Print NaN's in a format conforming to
+ ISO C99.
+
+2001-03-07 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * top.c (init_main): Make `set history file name' complete on file
+ names.
+
+2001-03-06 J.T. Conklin <jtc@redback.com>
+
+ * Makefile.in (LINTFLAGS): Update to contain all of the macros
+ which define include paths used when compiling.
+
+ * util.c (savestring, msavestring): Change type of length argument.
+ * defs.h (savestring, msavestring): Update to match.
+
+ * symtab.h (decode_line_1): Removed declaration.
+
+ * symfile.c (#include <assert.h>): Removed.
+
+ * arch-utils.c (#include <ctype.h>): Removed.
+ * c-typeprint.c: Likewise.
+ * dbxread.c: Likewise.
+ * gdbtypes.c: Likewise.
+ * target.c: Likewise.
+ * os9kread.c: Likewise.
+
+ * c-valprint.c (#include "demangle.h"): Removed.
+ * ch-typeprint.c: Likewise.
+ * eval.c: Likewise.
+ * f-typeprint.c: Likewise.
+ * f-valprint.c: Likewise.
+ * m2-typeprint.c: Likewise.
+ * typeprint.c: Likewise.
+ * p-typeprint.c: Likewise.
+ * valarith.c: Likewise.
+ * valprint.c: Likewise.
+
+ * m2-typeprint.c (#include "gdb_string.h"): Removed.
+ * nlmread.c: Likewise.
+
+ * mdebugread.c (#include "gdb-stabs.h"): Removed.
+ * minsyms.c: Likewise.
+ * mipsread.c: Likewise.
+ * nlmread.c: Likewise.
+
+ * m2-typeprint.c (#include "obstack.h"): Removed.
+ * m2-valprint.c: Likewise.
+
+ * event-loop.c (#include <setjmp.h>): Removed.
+
+2001-03-06 Stan Shebs <shebs@apple.com>
+
+ * MAINTAINERS: Remove self from specific maintenance domains
+ (macos, gdbserver, documentation, testsuite).
+
+2001-03-06 Kevin Buettner <kevinb@redhat.com>
+
+ * 29k-share/udi/udip2soc.c, Makefile.in, a29k-tdep.c,
+ a68v-nat.c, abug-rom.c, aclocal.m4, alpha-nat.c, alpha-tdep.c,
+ annotate.c, annotate.h, arc-tdep.c, arch-utils.c,
+ arch-utils.h, arm-tdep.c, ax-gdb.c, ax-gdb.h, ax-general.c,
+ ax.h, bcache.c, bcache.h, blockframe.c, breakpoint.c,
+ breakpoint.h, buildsym.c, buildsym.h, c-exp.y, c-lang.c,
+ c-lang.h, c-typeprint.c, c-valprint.c, call-cmds.h, ch-exp.c,
+ ch-lang.c, ch-lang.h, ch-typeprint.c, ch-valprint.c,
+ cli/cli-cmds.h, cli/cli-decode.c, cli/cli-decode.h,
+ cli/cli-script.c, cli/cli-script.h, cli/cli-setshow.h,
+ cli/cli-utils.h, cli-out.c, cli-out.h, coff-solib.c,
+ coff-solib.h, coffread.c, command.h, complaints.c,
+ complaints.h, completer.c, completer.h,
+ config/a29k/nm-ultra3.h, config/a29k/tm-a29k.h,
+ config/a29k/tm-ultra3.h, config/a29k/tm-vx29k.h,
+ config/a29k/xm-ultra3.h, config/alpha/nm-fbsd.h,
+ config/alpha/nm-linux.h, config/alpha/nm-osf.h,
+ config/alpha/nm-osf2.h, config/alpha/nm-osf3.h,
+ config/alpha/tm-alpha.h, config/alpha/tm-alphalinux.h,
+ config/alpha/xm-alphalinux.h, config/alpha/xm-alphaosf.h,
+ config/alpha/xm-fbsd.h, config/arc/tm-arc.h,
+ config/arm/nm-linux.h, config/arm/tm-arm.h,
+ config/arm/tm-embed.h, config/d10v/tm-d10v.h,
+ config/d30v/tm-d30v.h, config/fr30/tm-fr30.h,
+ config/h8300/tm-h8300.h, config/h8500/tm-h8500.h,
+ config/i386/nm-fbsd.h, config/i386/nm-gnu.h,
+ config/i386/nm-i386bsd.h, config/i386/nm-i386mach.h,
+ config/i386/nm-i386sco.h, config/i386/nm-i386sol2.h,
+ config/i386/nm-i386v.h, config/i386/nm-i386v4.h,
+ config/i386/nm-i386v42mp.h, config/i386/nm-linux.h,
+ config/i386/nm-nbsd.h, config/i386/nm-nbsdelf.h,
+ config/i386/nm-ptx4.h, config/i386/nm-sun386.h,
+ config/i386/nm-symmetry.h, config/i386/tm-cygwin.h,
+ config/i386/tm-fbsd.h, config/i386/tm-i386.h,
+ config/i386/tm-i386aix.h, config/i386/tm-i386bsd.h,
+ config/i386/tm-i386gnu.h, config/i386/tm-i386lynx.h,
+ config/i386/tm-i386m3.h, config/i386/tm-i386mk.h,
+ config/i386/tm-i386nw.h, config/i386/tm-i386os9k.h,
+ config/i386/tm-i386sco5.h, config/i386/tm-i386sol2.h,
+ config/i386/tm-i386v.h, config/i386/tm-i386v4.h,
+ config/i386/tm-i386v42mp.h, config/i386/tm-linux.h,
+ config/i386/tm-nbsd.h, config/i386/tm-ptx.h,
+ config/i386/tm-ptx4.h, config/i386/tm-sun386.h,
+ config/i386/tm-symmetry.h, config/i386/tm-vxworks.h,
+ config/i386/xm-fbsd.h, config/i386/xm-i386bsd.h,
+ config/i386/xm-i386gnu.h, config/i386/xm-i386m3.h,
+ config/i386/xm-i386mach.h, config/i386/xm-i386mk.h,
+ config/i386/xm-i386sco.h, config/i386/xm-i386v4.h,
+ config/i386/xm-linux.h, config/i386/xm-nbsd.h,
+ config/i386/xm-ptx.h, config/i386/xm-ptx4.h,
+ config/i386/xm-sun386.h, config/i386/xm-symmetry.h,
+ config/i960/tm-i960.h, config/i960/tm-mon960.h,
+ config/i960/tm-nindy960.h, config/i960/tm-vx960.h,
+ config/ia64/nm-aix.h, config/ia64/nm-linux.h,
+ config/ia64/tm-aix.h, config/ia64/tm-ia64.h,
+ config/ia64/tm-linux.h, config/ia64/xm-aix.h,
+ config/ia64/xm-linux.h, config/m68k/nm-apollo68b.h,
+ config/m68k/nm-delta68.h, config/m68k/nm-dpx2.h,
+ config/m68k/nm-hp300bsd.h, config/m68k/nm-hp300hpux.h,
+ config/m68k/nm-linux.h, config/m68k/nm-sun3.h,
+ config/m68k/tm-apollo68b.h, config/m68k/tm-cisco.h,
+ config/m68k/tm-dpx2.h, config/m68k/tm-es1800.h,
+ config/m68k/tm-hp300bsd.h, config/m68k/tm-hp300hpux.h,
+ config/m68k/tm-isi.h, config/m68k/tm-linux.h,
+ config/m68k/tm-m68k.h, config/m68k/tm-m68kv4.h,
+ config/m68k/tm-mac.h, config/m68k/tm-monitor.h,
+ config/m68k/tm-nbsd.h, config/m68k/tm-news.h,
+ config/m68k/tm-os68k.h, config/m68k/tm-sun3.h,
+ config/m68k/tm-vx68.h, config/m68k/xm-3b1.h,
+ config/m68k/xm-apollo68b.h, config/m68k/xm-dpx2.h,
+ config/m68k/xm-hp300bsd.h, config/m68k/xm-hp300hpux.h,
+ config/m68k/xm-linux.h, config/m68k/xm-m68kv4.h,
+ config/m68k/xm-mpw.h, config/m68k/xm-news.h,
+ config/m68k/xm-sun2.h, config/m68k/xm-sun3.h,
+ config/m68k/xm-sun3os4.h, config/m88k/nm-delta88v4.h,
+ config/m88k/tm-delta88.h, config/m88k/tm-delta88v4.h,
+ config/m88k/tm-m88k.h, config/m88k/xm-cxux.h,
+ config/m88k/xm-delta88.h, config/m88k/xm-delta88v4.h,
+ config/m88k/xm-dgux.h, config/mcore/tm-mcore.h,
+ config/mips/nm-irix3.h, config/mips/nm-irix4.h,
+ config/mips/nm-irix5.h, config/mips/nm-mips.h,
+ config/mips/nm-news-mips.h, config/mips/tm-bigmips.h,
+ config/mips/tm-embed.h, config/mips/tm-embed64.h,
+ config/mips/tm-embedl.h, config/mips/tm-embedl64.h,
+ config/mips/tm-irix3.h, config/mips/tm-irix5.h,
+ config/mips/tm-mips.h, config/mips/tm-mips64.h,
+ config/mips/tm-mipsm3.h, config/mips/tm-mipsv4.h,
+ config/mips/tm-tx39.h, config/mips/tm-tx39l.h,
+ config/mips/tm-vr4100.h, config/mips/tm-vr4300.h,
+ config/mips/tm-vr4300el.h, config/mips/tm-vr4xxx.h,
+ config/mips/tm-vr4xxxel.h, config/mips/tm-vr5000.h,
+ config/mips/tm-vr5000el.h, config/mips/xm-irix3.h,
+ config/mips/xm-irix4.h, config/mips/xm-irix5.h,
+ config/mips/xm-mips.h, config/mips/xm-mipsm3.h,
+ config/mips/xm-mipsv4.h, config/mips/xm-news-mips.h,
+ config/mips/xm-riscos.h, config/mn10200/tm-mn10200.h,
+ config/mn10300/tm-mn10300.h, config/nm-gnu.h,
+ config/nm-linux.h, config/nm-lynx.h, config/nm-m3.h,
+ config/nm-sysv4.h, config/none/nm-none.h,
+ config/none/tm-none.h, config/none/xm-none.h,
+ config/ns32k/nm-nbsd.h, config/ns32k/nm-umax.h,
+ config/ns32k/tm-merlin.h, config/ns32k/tm-nbsd.h,
+ config/ns32k/tm-ns32km3.h, config/ns32k/tm-umax.h,
+ config/ns32k/xm-merlin.h, config/ns32k/xm-ns32km3.h,
+ config/pa/nm-hppab.h, config/pa/nm-hppah.h,
+ config/pa/nm-hppao.h, config/pa/tm-hppa.h,
+ config/pa/tm-hppa64.h, config/pa/tm-hppah.h,
+ config/pa/xm-hppab.h, config/pa/xm-hppah.h,
+ config/powerpc/nm-aix.h, config/powerpc/nm-linux.h,
+ config/powerpc/nm-macos.h, config/powerpc/nm-nbsd.h,
+ config/powerpc/tm-cygwin.h, config/powerpc/tm-linux.h,
+ config/powerpc/tm-macos.h, config/powerpc/tm-ppc-aix.h,
+ config/powerpc/tm-ppc-eabi.h, config/powerpc/tm-ppc-nw.h,
+ config/powerpc/tm-ppcle-eabi.h, config/powerpc/tm-solaris.h,
+ config/powerpc/xm-aix.h, config/powerpc/xm-linux.h,
+ config/powerpc/xm-mpw.h, config/rs6000/nm-rs6000.h,
+ config/rs6000/tm-rs6000.h, config/rs6000/tm-rs6000ly.h,
+ config/rs6000/xm-aix4.h, config/rs6000/xm-rs6000.h,
+ config/sh/tm-linux.h, config/sh/tm-sh.h, config/sh/tm-wince.h,
+ config/sparc/nm-linux.h, config/sparc/nm-nbsd.h,
+ config/sparc/nm-nbsdelf.h, config/sparc/nm-sparclynx.h,
+ config/sparc/nm-sun4os4.h, config/sparc/nm-sun4sol2.h,
+ config/sparc/tm-linux.h, config/sparc/tm-sp64.h,
+ config/sparc/tm-sp64sim.h, config/sparc/tm-sparc.h,
+ config/sparc/tm-sparclet.h, config/sparc/tm-sparclite.h,
+ config/sparc/tm-sparclynx.h, config/sparc/tm-spc-em.h,
+ config/sparc/tm-sun4os4.h, config/sparc/tm-sun4sol2.h,
+ config/sparc/xm-sun4os4.h, config/sparc/xm-sun4sol2.h,
+ config/tic80/tm-tic80.h, config/tm-linux.h, config/tm-lynx.h,
+ config/tm-sysv4.h, config/v850/tm-v850.h, config/vax/tm-vax.h,
+ config/w65/tm-w65.h, config/xm-aix4.h, config/xm-lynx.h,
+ config/xm-mpw.h, config/xm-nbsd.h, config/xm-sysv4.h,
+ config/z8k/tm-z8k.h, configure.in, core-aout.c, core-regset.c,
+ core-sol2.c, corefile.c, corelow.c, cp-valprint.c,
+ cpu32bug-rom.c, cxux-nat.c, d10v-tdep.c, d30v-tdep.c,
+ dbug-rom.c, dbxread.c, dcache.c, dcache.h, defs.h,
+ delta68-nat.c, demangle.c, dink32-rom.c, dpx2-nat.c, dsrec.c,
+ dstread.c, dve3900-rom.c, dwarf2read.c, dwarfread.c,
+ elfread.c, environ.c, environ.h, eval.c, event-loop.c,
+ event-loop.h, event-top.c, exec.c, expprint.c, f-exp.y,
+ f-lang.c, f-lang.h, f-typeprint.c, f-valprint.c, findvar.c,
+ fork-child.c, fr30-tdep.c, frame.c, frame.h, gdb-events.c,
+ gdb-events.h, gdb-events.sh, gdb-stabs.h, gdb.1, gdb_string.h,
+ gdb_thread_db.h, gdbcmd.h, gdbcore.h, gdbserver/Makefile.in,
+ gdbserver/gdbreplay.c, gdbserver/gdbserver.1,
+ gdbserver/low-hppabsd.c, gdbserver/low-linux.c,
+ gdbserver/low-lynx.c, gdbserver/low-nbsd.c,
+ gdbserver/low-sim.c, gdbserver/low-sparc.c,
+ gdbserver/low-sun3.c, gdbserver/remote-utils.c,
+ gdbserver/server.c, gdbserver/server.h, gdbserver/utils.c,
+ gdbthread.h, gdbtypes.c, gdbtypes.h, gnu-nat.c, gnu-nat.h,
+ gnu-regex.c, gnu-regex.h, h8300-tdep.c, h8500-tdep.c,
+ hp-psymtab-read.c, hp-symtab-read.c, hp300ux-nat.c,
+ hppa-tdep.c, hppab-nat.c, hppah-nat.c, hppam3-nat.c, hpread.c,
+ hpread.h, hpux-thread.c, i386-tdep.c, i386aix-nat.c,
+ i386b-nat.c, i386gnu-nat.c, i386ly-tdep.c, i386m3-nat.c,
+ i386mach-nat.c, i386nbsd-nat.c, i386nbsd-tdep.c, i386v-nat.c,
+ i386v4-nat.c, i387-tdep.c, i960-tdep.c, infcmd.c, inferior.h,
+ inflow.c, infptrace.c, infrun.c, inftarg.c, infttrace.c,
+ irix4-nat.c, irix5-nat.c, isi-xdep.c, jv-exp.y, jv-lang.c,
+ jv-lang.h, jv-typeprint.c, jv-valprint.c, kdb-start.c,
+ kod-cisco.c, kod.c, language.c, language.h, lin-thread.c,
+ linespec.c, linespec.h, linux-thread.c, lynx-nat.c, m2-exp.y,
+ m2-lang.c, m2-lang.h, m2-typeprint.c, m2-valprint.c, m3-nat.c,
+ m32r-rom.c, m32r-tdep.c, m68k-tdep.c, m68klinux-nat.c,
+ m68knbsd-nat.c, m88k-nat.c, m88k-tdep.c, mac-nat.c,
+ mac-xdep.c, main.c, maint.c, mcore-rom.c, mcore-tdep.c,
+ mdebugread.c, mem-break.c, minimon.h, minsyms.c, mips-nat.c,
+ mips-tdep.c, mipsm3-nat.c, mipsread.c, mipsv4-nat.c,
+ mn10200-tdep.c, mn10300-tdep.c, mon960-rom.c, monitor.c,
+ monitor.h, news-xdep.c, nindy-share/env.h, nindy-tdep.c,
+ nlm/Makefile.in, nlmread.c, ns32k-tdep.c, ns32km3-nat.c,
+ ns32knbsd-nat.c, objfiles.c, objfiles.h, ocd.c, ocd.h,
+ op50-rom.c, os9kread.c, osfsolib.c, p-exp.y, pa64solib.c,
+ pa64solib.h, parse.c, parser-defs.h, partial-stab.h,
+ ppc-bdm.c, ppc-linux-nat.c, ppc-linux-tdep.c, ppcbug-rom.c,
+ ppcnbsd-nat.c, printcmd.c, proc-api.c, proc-events.c,
+ proc-flags.c, proc-utils.h, proc-why.c, procfs.c, ptx4-nat.c,
+ rdi-share/Makefile.in, rdi-share/aclocal.m4, regcache.c,
+ regcache.h, remote-adapt.c, remote-array.c, remote-bug.c,
+ remote-e7000.c, remote-eb.c, remote-es.c, remote-est.c,
+ remote-hms.c, remote-mips.c, remote-mm.c, remote-nindy.c,
+ remote-nrom.c, remote-os9k.c, remote-rdi.c, remote-rdp.c,
+ remote-sds.c, remote-sim.c, remote-st.c, remote-udi.c,
+ remote-utils.c, remote-utils.h, remote-vx.c, remote.c,
+ remote.h, reply_mig_hack.awk, rom68k-rom.c, rs6000-nat.c,
+ rs6000-tdep.c, scm-exp.c, scm-lang.c, scm-lang.h, scm-tags.h,
+ scm-valprint.c, ser-e7kpc.c, ser-mac.c, ser-ocd.c, ser-pipe.c,
+ ser-tcp.c, ser-unix.c, serial.c, serial.h, sh-tdep.c,
+ sh3-rom.c, sol-thread.c, solib-aix5.c, solib-svr4.c, solib.c,
+ solib.h, solist.h, somread.c, somsolib.c, somsolib.h,
+ source.c, sparc-nat.c, sparc-tdep.c, sparcl-tdep.c,
+ sparclet-rom.c, srec.h, stabsread.c, stabsread.h, stack.c,
+ standalone.c, stop-gdb.c, stuff.c, sun3-nat.c, sun386-nat.c,
+ symfile.c, symfile.h, symm-nat.c, symm-tdep.c, symmisc.c,
+ symtab.c, symtab.h, target.c, target.h, terminal.h, thread.c,
+ tic80-tdep.c, top.c, top.h, tracepoint.c, tracepoint.h,
+ typeprint.c, ui-file.c, ui-file.h, ui-out.h, ultra3-nat.c,
+ ultra3-xdep.c, umax-xdep.c, utils.c, v850-tdep.c, v850ice.c,
+ valarith.c, valops.c, valprint.c, value.h, values.c, varobj.h,
+ vax-tdep.c, version.h, vx-share/vxWorks.h, vx-share/xdr_ld.c,
+ vx-share/xdr_ptrace.c, vx-share/xdr_ptrace.h,
+ vx-share/xdr_rdb.c, w65-tdep.c, w89k-rom.c, win32-nat.c,
+ wrapper.c, wrapper.h, xcoffread.c, xcoffsolib.c, xcoffsolib.h,
+ xmodem.c, xmodem.h, z8k-tdep.c: Update/correct copyright
+ notices.
+
+2001-03-05 Kevin Buettner <kevinb@redhat.com>
+
+ * acconfig.h (HAVE_PRSYSENT_T, HAVE_PR_SIGSET_T,
+ HAVE_PR_SIGACTION64_T, HAVE_PR_SIGINFO64_T): New configure
+ macros.
+ * configure.in (prsysent_t, pr_sigset_t, pr_sigaction64_t,
+ pr_siginfo64_t): Test for these typedefs in <sys/procfs.h>.
+ (sys/fault.h, sys/select.h): Test for presence of these
+ header files.
+ (ia64-*-aix*): Define NEW_PROC_API for this host.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+
+ * configure.host (ia64-*-aix*): New host.
+ * configure.tgt (ia64-*-aix*): New target.
+
+2001-03-05 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO (GDB 5.1 Known Problems): Document z8k as broken.
+
+Mon Mar 5 11:56:09 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * wince.c: Change realloc to xrealloc throughout.
+ (handle_load_dll): Use void * rather than PTR in argument.
+
+2001-03-04 Andrew Cagney <ac131313@redhat.com>
+
+ * ocd.h (ocd_xfer_memory): Add ``attrib'' parameter.
+ * ocd.c (ocd_xfer_memory): Ditto.
+ * ser-ocd.c (ocd_setstopbits): New function. Add to ocd_ops.
+ * MAINTAINERS: Document powerpc-eabi and powerpcle-eabi as
+ buildable with ,-Werror.
+
+ * Makefile.in (symfile_h): Define.
+ (mcore-tdep.o): Add $(symfile_h), $(gdbcore_h) and $(inferior_h).
+ * mcore-tdep.c: Include "symfile.h", "gdbcore.h" and "inferior.h".
+ * MAINTAINERS: Document mcore-elf and mcore-pe as buildable with
+ ,-Werror.
+
+ * dsrec.c (make_srec): Fix internal_error fmt arg.
+ * MAINTAINERS: Document i960-coff as buildable with ,-Werror.
+
+2001-03-03 Kevin Buettner <kevinb@redhat.com>
+
+ * solib-aix5.c (aix5_relocate_main_executable): Don't use ANOFFSET
+ as an lvalue.
+
+2001-03-02 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS (paper trail): Update.
+
+ * CONTRIBUTE: Update note on ``Fix PR gdb/4706'' convention.
+
+2001-03-02 Andrew Cagney <ac131313@redhat.com>
+
+ From 2001-03-01 Tom Rix <trix@redhat.com>:
+ * mn10200-tdep.c (mn10200_frame_chain): Pass 0 for ``pc''
+ parameter to mn10200_analyze_prologue.
+
+ * config/mn10200/tm-mn10200.h: Include "regcache.h".
+ * MAINTAINERS: Document that mn10200-elf target is buildable.
+
+2001-03-02 Kevin Buettner <kevinb@redhat.com>
+
+ * config/ia64/xm-aix.h (GDB_GREGSET_T, GDB_FPREGSET_T): Move defines
+ from here...
+ * config/ia64/nm-aix.h (GDB_GREGSET_T, GDB_FPREGSET_T): ...to here.
+ (MONTEREY): Don't define.
+ (AIX5): Define.
+
+2001-03-02 Matt Hiller <hiller@redhat.com>
+
+ * config/mn10300/tm-mn10300.h (E0_REGNUM): Correct to 15.
+
+2001-03-02 Kevin Buettner <kevinb@redhat.com>
+
+ * sparc-nat.c (sparc-nat.c): Don't include self.
+
+2001-03-01 J.T. Conklin <jtc@redback.com>
+
+ * defs.h (__CYGWIN__): Moved conditional which defines __CYGWIN__
+ if __CYGWIN32__ is set from here.
+ * config/i386/xm-cygwin.h: To here.
+ * config/powerpc/xm-cygwin.h: To here.
+
+ * i386-stub.c (handle_exception): Use 'T' response packet.
+
+2001-03-01 Michael Snyder <msnyder@mvstp600e.cygnus.com>
+
+ * m32r-tdep.c: Fix cut and paste error in comment.
+
+2001-02-28 Michael Snyder <msnyder@mvstp600e.cygnus.com>
+
+ * symtab.c (print_msymbol_info): Print addresses by portable method
+ longest_local_hex_string_custom. Allow for 64-bit addresses.
+
+2001-03-01 J.T. Conklin <jtc@redback.com>
+
+ * gdbtypes.h (builtin_type_f_integer): Removed duplicate declaration.
+ (MAX_OF_TYPE): Wrap macro definition in parenthesis.
+ (MIN_OF_TYPE): Likewise.
+
+ * memattr.h (mem_access_mode): Removed extraneous trailing comma.
+
+2001-03-01 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in (os9kread.o): Do not compile with WERROR_CFLAGS.
+ * os9kread.c (os9k_process_one_symbol): Add assert to detect
+ ``loses if sizeof (char *) > sizeof (int)''.
+
+2001-03-01 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb_assert.h: Document pragmatics behind gdb_assert's case.
+
+2001-03-01 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in (gdbtk-cmds.o): Add $(regcache_h) to dependency
+ lists.
+ (mi-main.o): Ditto.
+
+2001-03-01 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in (regcache_h): Define. Add $(regcache_h) to
+ dependency lists.
+
+2001-02-28 Michael Snyder <msnyder@mvstp600e.cygnus.com>
+
+ * printcmd.c (print_address_numeric): Update comments to refer
+ to sizeof addr, not sizeof pointer.
+ (x_command): Remove needless whitespace (shorten long line).
+
+ * breakpoint.c (print_one_breakpoint): Formatting clean-up.
+ (read_memory_nobpt): Ditto.
+ (ep_is_catchpoint): Ditto.
+ (ep_is_shlib_catchpoint): Ditto.
+ (ep_is_exception_catchpoint): Ditto.
+ (describe_other_breakpoints): Ditto.
+
+Wed Feb 28 20:37:36 2001 Andrew Cagney <ac131313@redhat.com>
+
+ * regcache.h (register_valid): Fix comment documenting valid
+ states.
+
+Tue Feb 27 23:56:23 2001 Andrew Cagney <ac131313@redhat.com>
+
+ From Steven Johnson:
+ * regcache.h: New file.
+
+ * value.h (read_register_bytes, read_register_gen)
+ (write_register_gen, write_register_bytes)
+ (read_register, read_register_pid)
+ (read_signed_register, read_signed_register_pid)
+ (write_register, write_register_pid)
+ (register_cached, set_register_cached)
+ (register_changed, register_buffer)
+ (registers_changed, supply_register): Move declaration from here.
+ * regcache.h: To here.
+ * gdbcore.h (registers_fetched): Ditto.
+ * inferior.h (registers, registers_valid): Ditto.
+
+ * regcache.c (generic_target_read_pc, read_pc_pid, read_pc,
+ generic_target_write_pc, write_pc_pid, write_pc,
+ generic_target_read_sp, read_sp, generic_target_write_sp,
+ write_sp, generic_target_read_fp, read_fp,
+ generic_target_write_fp, write_fp): Add note that these functions
+ will be moved from this file.
+
+ * a29k-tdep.c: Include "regcache.h".
+ * a68v-nat.c: Ditto.
+ * abug-rom.c: Ditto.
+ * alpha-nat.c: Ditto.
+ * alpha-tdep.c: Ditto.
+ * alphabsd-nat.c: Ditto.
+ * arc-tdep.c: Ditto.
+ * arm-linux-nat.c: Ditto.
+ * arm-linux-tdep.c: Ditto.
+ * arm-tdep.c: Ditto.
+ * blockframe.c: Ditto.
+ * core-aout.c: Ditto.
+ * core-sol2.c: Ditto.
+ * corelow.c: Ditto.
+ * cpu32bug-rom.c: Ditto.
+ * cxux-nat.c: Ditto.
+ * d10v-tdep.c: Ditto.
+ * d30v-tdep.c: Ditto.
+ * dbug-rom.c: Ditto.
+ * dink32-rom.c: Ditto.
+ * dve3900-rom.c: Ditto.
+ * findvar.c: Ditto.
+ * fr30-tdep.c: Ditto.
+ * frame.c: Ditto.
+ * go32-nat.c: Ditto.
+ * h8300-tdep.c: Ditto.
+ * h8500-tdep.c: Ditto.
+ * hp300ux-nat.c: Ditto.
+ * hppa-tdep.c: Ditto.
+ * hppab-nat.c: Ditto.
+ * hppah-nat.c: Ditto.
+ * hppam3-nat.c: Ditto.
+ * hpux-thread.c: Ditto.
+ * i386-linux-nat.c: Ditto.
+ * i386-linux-tdep.c: Ditto.
+ * i386-tdep.c: Ditto.
+ * i386aix-nat.c: Ditto.
+ * i386b-nat.c: Ditto.
+ * i386bsd-nat.c: Ditto.
+ * i386gnu-nat.c: Ditto.
+ * i386ly-tdep.c: Ditto.
+ * i386m3-nat.c: Ditto.
+ * i386mach-nat.c: Ditto.
+ * i386nbsd-nat.c: Ditto.
+ * i386v4-nat.c: Ditto.
+ * i387-nat.c: Ditto.
+ * i387-tdep.c: Ditto.
+ * i960-tdep.c: Ditto.
+ * ia64-aix-nat.c: Ditto.
+ * ia64-linux-nat.c: Ditto.
+ * ia64-tdep.c: Ditto.
+ * infptrace.c: Ditto.
+ * infrun.c: Ditto.
+ * irix4-nat.c: Ditto.
+ * irix5-nat.c: Ditto.
+ * lin-lwp.c: Ditto.
+ * lin-thread.c: Ditto.
+ * lynx-nat.c: Ditto.
+ * m3-nat.c: Ditto.
+ * m32r-rom.c: Ditto.
+ * m32r-tdep.c: Ditto.
+ * m68hc11-tdep.c: Ditto.
+ * m68k-tdep.c: Ditto.
+ * m68klinux-nat.c: Ditto.
+ * m68knbsd-nat.c: Ditto.
+ * m68knbsd-tdep.c: Ditto.
+ * m88k-nat.c: Ditto.
+ * m88k-tdep.c: Ditto.
+ * mac-nat.c: Ditto.
+ * mcore-rom.c: Ditto.
+ * mcore-tdep.c: Ditto.
+ * mi/mi-main.c: Ditto.
+ * mips-nat.c: Ditto.
+ * mips-tdep.c: Ditto.
+ * mipsm3-nat.c: Ditto.
+ * mipsv4-nat.c: Ditto.
+ * mn10200-tdep.c: Ditto.
+ * mn10300-tdep.c: Ditto.
+ * monitor.c: Ditto.
+ * ns32km3-nat.c: Ditto.
+ * ns32knbsd-nat.c: Ditto.
+ * ocd.c: Ditto.
+ * pa64solib.c: Ditto.
+ * ppc-bdm.c: Ditto.
+ * ppc-linux-nat.c: Ditto.
+ * ppc-linux-tdep.c: Ditto.
+ * ppcbug-rom.c: Ditto.
+ * ppcnbsd-nat.c: Ditto.
+ * ptx4-nat.c: Ditto.
+ * regcache.c: Ditto.
+ * remote-adapt.c: Ditto.
+ * remote-array.c: Ditto.
+ * remote-bug.c: Ditto.
+ * remote-e7000.c: Ditto.
+ * remote-eb.c: Ditto.
+ * remote-es.c: Ditto.
+ * remote-est.c: Ditto.
+ * remote-hms.c: Ditto.
+ * remote-mips.c: Ditto.
+ * remote-mm.c: Ditto.
+ * remote-nindy.c: Ditto.
+ * remote-os9k.c: Ditto.
+ * remote-rdi.c: Ditto.
+ * remote-rdp.c: Ditto.
+ * remote-sds.c: Ditto.
+ * remote-sim.c: Ditto.
+ * remote-st.c: Ditto.
+ * remote-udi.c: Ditto.
+ * remote-utils.c: Ditto.
+ * remote-vx.c: Ditto.
+ * remote-vx29k.c: Ditto.
+ * remote-vx68.c: Ditto.
+ * remote-vx960.c: Ditto.
+ * remote-vxmips.c: Ditto.
+ * remote-vxsparc.c: Ditto.
+ * remote.c: Ditto.
+ * rom68k-rom.c: Ditto.
+ * rs6000-nat.c: Ditto.
+ * rs6000-tdep.c: Ditto.
+ * sh-tdep.c: Ditto.
+ * sh3-rom.c: Ditto.
+ * sol-thread.c: Ditto.
+ * solib-svr4.c: Ditto.
+ * somsolib.c: Ditto.
+ * sparc-nat.c: Ditto.
+ * sparc-tdep.c: Ditto.
+ * sparcl-tdep.c: Ditto.
+ * sparclet-rom.c: Ditto.
+ * sun3-nat.c: Ditto.
+ * sun386-nat.c: Ditto.
+ * symm-nat.c: Ditto.
+ * target.c: Ditto.
+ * thread-db.c: Ditto.
+ * thread.c: Ditto.
+ * tic80-tdep.c: Ditto.
+ * tracepoint.c: Ditto.
+ * ultra3-nat.c: Ditto.
+ * umax-xdep.c: Ditto.
+ * uw-thread.c: Ditto.
+ * v850-tdep.c: Ditto.
+ * v850ice.c: Ditto.
+ * valops.c: Ditto.
+ * w65-tdep.c: Ditto.
+ * w89k-rom.c: Ditto.
+ * win32-nat.c: Ditto.
+ * wince.c: Ditto.
+ * z8k-tdep.c: Ditto.
+
+2001-02-28 Matt Hiller <hiller@redhat.com>
+
+ * MAINTAINERS: Add Matt Hiller to Write After Approval list.
+
+2001-02-27 Matt Hiller <hiller@redhat.com>
+
+ * mn10300-tdep.c (mn10300_stab_reg_to_regnum): New function.
+ (mn10300_gdbarch_init): Set appropriate elements of gdbarch to
+ mn10300_stab_reg_to_regnum.
+
+Tue Feb 27 16:56:13 2001 David Taylor <taylor@redhat.com>
+
+ * symtab.c (search_symbols): Fix off by one error in test for
+ error.
+
+2001-02-23 Andrew Cagney <ac131313@redhat.com>
+
+ * config/sparc/sp64linux.mt: New file.
+ * configure.tgt: Recognize sparc64-*-linux* as a sp64linux target.
+ * configure.host: Recognize sparc64-*-linux* as a linux host.
+
+ From 2000-03-17 Jakub Jelinek <jakub@redhat.com>:
+ * config/sparc/tm-sp64linux.h: New file.
+
+2001-02-24 Kevin Buettner <kevinb@redhat.com>
+
+ * buildsym.c (push_subfile, pop_subfile): Replace call to abort()
+ with call to internal_error().
+ * dbxread.c (process_one_symbol): Likewise.
+ * exec.c (build_section_table, xfer_memory): Likewise.
+ * h8500-tdep.c (h8500_register_size, h8500_register_virtual_type):
+ Likewise.
+ * hpread.c (hpread_type_translate, hpread_read_array_type)
+ (hpread_type_lookup): Likewise.
+ * i386-tdep.c (gdb_print_insn_i386): Likewise.
+ * i960-tdep.c (mem): Likewise
+ * inflow.c (set_sigio_trap, clear_sigio_trap): Likewise.
+ * infptrace.c (child_resume): Likewise.
+ * infttrace.c (_initialize_infttrace): Likewise.
+ * language.c (binop_result_type, add_language): Likewise.
+ * lynx-nat.c (store_inferior_registers): Likewise.
+ * m3-nat.c (port_chain_insert, m3_trace_me): Likewise.
+ * mdebugread.c (parse_partial_symbols): Likewise.
+ * monitor.c (monitor_printf_noecho, monitor_printf)
+ (monitor_dump_regs): Likewise.
+ * ocd.c (stu_put_packet): Likewise.
+ * printcmd.c (decode_format, print_scalar_formatted): Likewise.
+ * remote-bug.c (bug_open): Likewise.
+ * remote-e7000.c (fetch_regs_from_dump, e7000_wait): Likewise.
+ * remote-es.c (es1800_read_bytes): Likewise.
+ * remote-mips.c (common_breakpoint): Likewise.
+ * remote-rdp.c (send_rdp): Likewise.
+ * remote-sds.c (putmessage): Likewise.
+ * sparc-nat.c (fetch_inferior_registers, store_inferior_registers):
+ Likewise.
+ * sparcl-tdep.c (sparclite_download): Likewise.
+ * symtab.c (lookup_partial_symbol): Likewise.
+ * target.c (push_target, pop_target, initialize_targets): Likewise.
+ * utils.c (internal_verror, malloc_botch, wrap_here, decimal2str):
+ Likewise.
+ * valprint.c (print_decimal, print_longest, print_longest)
+ (strcat_longest): Likewise.
+ * w65-tdep.c (init_frame_pc, w65_push_dummy_frame): Likewise.
+ * xmodem.c (xmodem_send_packet): Likewise.
+ * z8k-tdep.c (init_frame_pc, z8k_push_dummy_frame): Likewise.
+ * config/h8500/tm-h8500.h (STORE_STRUCT_RETURN): Likewise.
+ * config/mn10200/tm-mn10200.h (EXTRACT_RETURN_VALUE)
+ (STORE_RETURN_VALUE): Likewise.
+ * config/ns32k/nm-umax.h (REGISTER_U_ADDR): Likewise.
+ * config/ns32k/xm-merlin.h (REGISTER_U_ADDR): Likewise.
+ * config/z8k/tm-z8k.h (STORE_STRUCT_RETURN, STORE_RETURN_VALUE):
+ Likewise.
+
+2001-02-23 Andrew Cagney <ac131313@redhat.com>
+
+ * CONTRIBUTE: Document how to cite a problem report.
+ * TODO: Note need to replace CONTRIBUTE with generated file.
+
+ * CONTRIBUTE: Mention that patches do not need to include the
+ generated files gdbarch.h and gdbarch.c.
+
+2001-02-21 Andrew Cagney <ac131313@redhat.com>
+
+ * value.h (get_saved_register): Move from here.
+ * frame.h: To here.
+
+2001-02-21 Kevin Buettner <kevinb@redhat.com>
+
+ * solib.h (in_svr4_dynsym_resolve_code): Delete declaration.
+ (in_solib_dynsym_resolve_code): Add declaration.
+ (IN_SOLIB_DYNSYM_RESOLVE_CODE): Changed define to invoke
+ in_solib_dynsym_resolve_code() rather than
+ in_svr4_dynsym_resolve_code(). Also, removed the ifdefs
+ which caused this macro to only be defined when
+ SVR4_SHARED_LIBS is defined.
+ * solib.c (in_solib_dynsym_resolve_code): New function.
+ * solist.h (struct target_so_ops): Add new member
+ in_dynsym_resolve_code.
+ * solib-aix5.c (aix5_in_dynsym_resolve_code): Renamed from
+ in_svr4_dynsym_resolve_code. Also, made static.
+ (_initialize_aix5_solib): Initialize in_dynsym_resolve_code
+ member in aix5_so_ops.
+ * solib-svr4.c (svr4_in_dynsym_resolve_code): Renamed from
+ in_svr4_dynsym_resolve_code. Also, added second version
+ of this function which will be used when SVR4_SHARED_LIBS
+ is not defined.
+ (_initialize_svr4_solib): Initialize in_dynsym_resolve_code
+ member in svr4_so_ops.
+
+ * ia64-aix-nat.c, ia64-aix-tdep.c, config/ia64/aix.mh,
+ config/ia64/aix.mt, config/ia64/nm-aix.h, config/ia64/tm-aix.h,
+ config/ia64/xm-aix.h: New files.
+ * ia64-tdep.c (_initialize_ia64_tdep): Remove declaration.
+ (ia64_aix_sigcontext_register_address): New declaration.
+ (ia64_gdbarch_init): Provide for initialization of
+ sigcontext_register_address member of struct tdep when
+ on target is detected to be running AIX.
+ * config/ia64/linux.mt (TDEPFILES): Add ia64-aix-tdep.o to
+ this list.
+
+2001-02-20 Kevin Buettner <kevinb@redhat.com>
+
+ * ia64-tdep.c (ia64_frameless_function_invocation): Implement.
+ * config/ia64/linux.mh (NATDEPFILES): Use thread-db.o and lin-lwp.o
+ for thread support instead of linux-thread.o and lin-thread.o.
+ * config/ia64/nm-linux.h (PREPARE_TO_PROCEED, GET_THREAD_SIGNALS,
+ ATTACH_LWP): Define to use the following lin-lwp.c functions...
+ (lin_lwp_prepare_to_proceed, lin_thread_get_thread_signals,
+ lin_lwp_attach_lwp): Declare.
+
+2001-02-20 Andrew Cagney <ac131313@redhat.com>
+
+ * mips-tdep.c (do_fp_register_row, do_fp_register_row): Fix printf
+ formatting.
+
+2001-02-20 Kevin Buettner <kevinb@redhat.com>
+
+ * solib-aix5.c (solib-svr4.h): Remove include.
+ (solib_break_names): Delete names which aren't actually
+ used by AIX5.
+ (bkpt_names): Remove.
+ (aix5_relocate_main_executable, bfd_lookup_symbol): Replace calls
+ to STREQ() with equivalent calls to strcmp().
+ (in_svr4_dynsym_resolve_code, enable_break, bfd_lookup_symbol,
+ aix5_solib_create_inferior_hook): Revise comments.
+ (enable_break): Remove old ``bkpt_names'' code.
+
+2001-02-19 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in (SFILES): Add frame.c .
+ (COMMON_OBS): Add frame.o .
+ (frame.o): New target.
+
+ * frame.c (find_saved_register):
+ (default_get_saved_register):
+ (get_saved_register):
+ (read_relative_register_raw_bytes_for_frame):
+ (read_relative_register_raw_bytes): Moved to here.
+ * regcache.c: From here.
+
+2001-02-20 Kevin Buettner <kevinb@redhat.com>
+
+ * solib-aix5.c: New file.
+
+2001-02-20 Martin M. Hunt <hunt@redhat.com>
+
+ * solib.c (info_sharedlibrary_command): Don't assume pointers
+ are the same size of long, call longest_local_hex_string_custom().
+
+ * solib-svr4.c (LM_ADDR): LM_ADDR is a signed offset, so
+ extract_signed_integer() should be called instead of
+ extract_address().
+
+2001-02-20 Martin M. Hunt <hunt@redhat.com>
+
+ * MAINTAINERS: Add Martin Hunt to Write After Approval list.
+
+2001-02-19 Andrew Cagney <ac131313@redhat.com>
+
+ Frm 2001-02-09 Jim Kingdon <jkingdon@engr.sgi.com>:
+ * mips-tdep.c (mips_register_raw_size): If FP_REGISTER_DOUBLE,
+ then floating point registers are 8 bytes.
+
+2001-02-19 Michael Snyder <msnyder@mvstp600e.cygnus.com>
+
+ * parse.c (write_exp_msymbol): Make the type CORE_ADDR, to
+ accomodate 64-bit addresses.
+
+2001-02-19 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Peter Schauer <Peter.Schauer@regent.e-technik.tu-muenchen.de>
+ * symtab.c (lookup_symbol_aux): Call lookup_symbol_aux, not
+ lookup_symbol, when trying to find a symbol with a mangled name,
+ to avoid infinite recursion.
+
+2001-02-18 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO (5.2): Mention G++ 3.0 ABI. General cleanups.
+
+2001-02-19 Jonathan Larmour <jlarmour@redhat.com>
+
+ * arm-tdep.c (check_prologue_cache): Fix off by 1 error.
+ (save_prologue_cache): Ditto.
+
+2001-02-19 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From: innadadadavida@yahoo.com:
+ * partial-stab.h (switch): Check that pst is not null
+ before dereferencing it.
+
+2001-02-19 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Andrew Cagney <cagney@b1.cygnus.com>:
+ * symfile.c (add_symbol_file_command): Always initialize
+ my_cleanup using a NULL cleanup.
+
+2001-02-19 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * demangle.c (demangling_style_names): New variable.
+ (_initialize_demangler): Fill demangling_style_names with the
+ names of known demangling styles from libiberty_demanglers[]. Use
+ add_set_enum_cmd instead of add_set_cmd, to get completion on
+ demangling style names.
+
+ * proc-api.c (_initialize_proc_api): Make `procfs-file' use
+ file-name completion.
+
+ * remote-rdi.c (_initialize_remote_rdi): Ditto for `rdilogfile'.
+
+ * solib.c (_initialize_solib): Ditto for `solib-search-path' and
+ `solib-absolute-prefix'.
+
+ * tracepoint.c (_initialize_tracepoint): Ditto for
+ `save-tracepoints'.
+
+ * win32-nat.c (_initialize_inftarg): Ditto for `dll-symbols'.
+
+ * cli/cli-cmds.c (init_cli_cmds): Make `shell' and `make' use
+ file-name completion.
+
+ * infcmd.c (_initialize_infcmd): Make the following commands use
+ the file-name completer: `tty', `args', `path', `paths', and
+ `run'.
+
+2001-02-18 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * go32-nat.c: Include i387-nat.h.
+ (fetch_register): New function, uses some of the guts of
+ go32_fetch_registers and calls i387_supply_register.
+ (go32_fetch_registers): Most of the code moved into
+ fetch_register. Use i387_supply_fsave.
+ (store_register): Use i387_fill_fsave instead of custom code.
+ (go32_store_registers): Use i387_fill_fsave.
+
+ * Makefile.in (go32-nat.o): Depend on i387-nat.h.
+
+ * config/i386/go32.mh (NATDEPFILES): Add i387-nat.o.
+
+ * completer.c (gdb_completer_file_name_break_characters): Remove
+ slash from file-name break characters.
+ [__MSDOS__]: Special definition for DOS/Windows file names.
+ (line_completion_function): When completing on file names, bump
+ `p' to the first file-name constituent character of `word', before
+ invoking the completer.
+
+2001-02-17 Mark Kettenis <kettenis@gnu.org>
+
+ * i387-nat.c: Include "i387-nat.h". Use regnum instead of regno
+ consistently for parameter names. Fix comments accordingly.
+ (i387_supply_register): New function.
+ (i387_supply_fsave): Implement using i387_supply_register.
+ * i387-nat.h: Use regnum instead of regno consistently for
+ parameter names. Fix comments accordingly.
+ (i387_supply_register): New prototype.
+
+2001-02-16 Michael Snyder <msnyder@mvstp600e.cygnus.com>
+
+ * remote.c (build_remote_gdbarch_data): Use new TARGET_ADDR_BIT
+ instead of TARGET_PTR_BIT (to support Harvard architectures).
+
+2001-02-16 Andrew Cagney <ac131313@redhat.com>
+
+ From 2001-02-11 Paul Hilfinger <hilfingr@lisbon.int.act-europe.fr>
+ * hpux-thread.c (hpux_thread_xfer_memory): Add mem_attrib
+ argument to parameter list and to call in order to conform to
+ to_xfer_memory field of struct target_ops.
+
+2001-02-12 Michael Chastain <chastain@redhat.com>
+
+ * somsolib.c (som_solib_add_solib_objfile): Do not use
+ section relocation feature of syms_from_objfile. Do my own
+ section relocation, offsetting each section of the som by
+ either text_addr - text_link_addr or data_start.
+
+2001-02-16 Andrew Cagney <ac131313@redhat.com>
+
+ * TODO (5.1): Move ``Hardware watchpint problems'' out of 5.1.
+
+2001-02-16 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS (paper trail): Update.
+
+2001-02-16 Mark Kettenis <kettenis@gnu.org>
+
+ * target.h (target_fetch_registers): Fix comment.
+
+2001-02-15 Andrew Cagney <ac131313@redhat.com>
+
+ * f-exp.y: Include <ctype.h>.
+ (parse_number): Ensure that ``i'' is always initialized.
+
+2001-02-14 Jim Kingdon <jkingdon@engr.sgi.com>
+
+ * MAINTAINERS: Add myself to paper trail section.
+
+2001-02-14 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * configure.in (AC_CHECK_HEADERS): Add sys/file.h.
+ * configure, config.in: Regenerate.
+ * corelow.c: Include <sys/file.h> if present.
+
+2001-02-14 Andrew Cagney <ac131313@redhat.com>
+
+ * inflow.c (terminal_ours_1): Initialize ``osigtou''. Only
+ declare when have SIGTTOU.
+
+2001-02-14 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/djgpp/fnchange.lst: Add entries for gdb/gdbtk/*/ChangeLog-*.
+
+2001-02-12 Jim Kingdon <jkingdon@engr.sgi.com>
+
+ * MAINTAINERS: Update my email address.
+
+2001-02-11 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * NEWS: Document that "info symbol" works with COFF debug info and
+ its variants.
+
+ * minsyms.c (lookup_minimal_symbol_by_pc_section): Don't skip
+ symbols whose SYMBOL_BFD_SECTION is NULL.
+
+2001-02-10 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ Get rid of AIX specific PC_LOAD_SEGMENT, replace with PC_SOLIB.
+ * xcoffsolib.c (xcoff_solib_address): Renamed from
+ pc_load_segment_name. Return NULL if address is not in a shared
+ library. Cleanup shared library name construction, using xasprintf.
+ Format shared library member names consistent with format in exec.c.
+ (solib_info): Format shared library member names consistent with
+ format in exec.c.
+ * config/rs6000/nm-rs6000.h: Replace PC_LOAD_SEGMENT with PC_SOLIB,
+ using xcoff_solib_address for PC_SOLIB definition.
+ * stack.c (print_frame): Remove PC_LOAD_SEGMENT code, no longer
+ needed.
+
+2001-02-10 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * mipsread.c (read_alphacoff_dynamic_symtab): Replace alloca calls
+ with xmalloc calls and cleanups.
+
+2001-02-10 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * rs6000-nat.c (child_xfer_memory): Add missing parameter
+ 'struct mem_attrib *' required by 2001-01-23 change.
+
+2001-02-08 Jim Kingdon <jkingdon@engr.sgi.com>
+
+ Updates to "make TAGS":
+ * Makefile.in (ALLDEPFILES): Remove altos-xdep.c arm-convert.s
+ arm-xdep.c convex-tdep.c convex-xdep.c pyr-tdep.c pyr-xdep.c
+ tahoe-tdep.c.
+ (TAGFILES_NO_SRCDIR): Add $(SUBDIR_CLI_SRCS).
+
+2001-02-08 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/djgpp/fnchange.lst: Remove extraneous "too many dots".
+
+Wed Feb 7 22:39:26 2001 Andrew Cagney <cagney@redhat.com>
+
+ From Dean Luick <luick@cray.com>:
+ * defs.h (continuation): Remove unused global variable.
+
+Wed Feb 7 22:28:31 2001 Andrew Cagney <cagney@redhat.com>
+
+ * configure.tgt: Remove references to convex, pyramid, altos and
+ tahoe.
+ * configure.host: Ditto.
+ * MAINTAINERS: Ditto.
+ * NEWS: Update.
+
+ * tahoe-tdep.c: Delete obsolete file.
+ * pyr-xdep.c: Ditto.
+ * pyr-tdep.c: Ditto.
+ * convex-tdep.c: Ditto.
+ * convex-xdep.c: Ditto.
+ * config/tahoe/xm-tahoe.h: Ditto.
+ * config/tahoe/tm-tahoe.h: Ditto.
+ * config/tahoe/tahoe.mt: Ditto.
+ * config/tahoe/tahoe.mh: Ditto.
+ * config/pyr/xm-pyr.h: Ditto.
+ * config/pyr/tm-pyr.h: Ditto.
+ * config/pyr/pyramid.mt: Ditto.
+ * config/pyr/pyramid.mh: Ditto.
+ * config/m68k/xm-altos.h: Ditto.
+ * config/m68k/tm-altos.h: Ditto.
+ * config/m68k/altos.mt: Ditto.
+ * config/m68k/altos.mh: Ditto.
+ * config/convex/xm-convex.h: Ditto.
+ * config/convex/tm-convex.h: Ditto.
+ * config/convex/convex.mt: Ditto.
+ * config/convex/convex.mh: Ditto.
+ * config/convex/Convex.notes: Ditto.
+ * config/arm/xm-arm.h: Ditto.
+ * config/arm/nm-arm.h: Ditto.
+ * config/arm/arm.mt: Ditto.
+ * config/arm/arm.mh: Ditto.
+ * arm-convert.s: Ditto.
+ * arm-xdep.c: Ditto.
+ * altos-xdep.c: Ditto.
+
+Wed Feb 7 19:41:21 2001 Andrew Cagney <cagney@redhat.com>
+
+ * defs.h (internal_error, internal_verror): Add __FILE__ and
+ __LINE__ parameter.
+ * utils.c (internal_error, internal_verror): Update.
+
+ * v850-tdep.c: Update calls to internal_error.
+ * utils.c: Ditto.
+ * ui-out.c: Ditto.
+ * ui-file.c: Ditto.
+ * target.h: Ditto.
+ * symtab.h: Ditto.
+ * symm-nat.c: Ditto.
+ * sparc-tdep.c: Ditto.
+ * source.c: Ditto.
+ * serial.c: Ditto.
+ * rs6000-tdep.c: Ditto.
+ * rs6000-nat.c: Ditto.
+ * remote.c: Ditto.
+ * remote-vx.c: Ditto.
+ * remote-sim.c: Ditto.
+ * remote-mips.c: Ditto.
+ * regcache.c: Ditto.
+ * objfiles.h: Ditto.
+ * objfiles.c: Ditto.
+ * mn10300-tdep.c: Ditto.
+ * mips-tdep.c: Ditto.
+ * maint.c: Ditto.
+ * m68k-tdep.c: Ditto.
+ * m3-nat.c: Ditto.
+ * language.c: Ditto.
+ * infptrace.c: Ditto.
+ * inferior.h: Ditto.
+ * infcmd.c: Ditto.
+ * ia64-tdep.c: Ditto.
+ * i386-tdep.c: Ditto.
+ * i386-linux-nat.c: Ditto.
+ * hppah-nat.c: Ditto.
+ * go32-nat.c: Ditto.
+ * findvar.c: Ditto.
+ * f-lang.c: Ditto.
+ * elfread.c: Ditto.
+ * event-loop.c: Ditto.
+ * dwarf2read.c: Ditto.
+ * dsrec.c: Ditto.
+ * d30v-tdep.c: Ditto.
+ * d10v-tdep.c: Ditto.
+ * cli/cli-setshow.c: Ditto.
+ * cli/cli-script.c: Ditto.
+ * ch-exp.c: Ditto.
+ * breakpoint.c: Ditto.
+ * ax-gdb.c: Ditto.
+ * arch-utils.c: Ditto.
+ * a29k-tdep.c: Ditto.
+ * gdb_assert.h: Ditto.
+ * gdbarch.sh: Ditto.
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+2001-02-07 Andrew Cagney <ac131313@redhat.com>
+
+ From Mark Kettenis <kettenis@gnu.org>:
+ * event-top.h [!STOP_SIGNAL]: #include <signal.h>.
+
+2001-02-07 Andrew Cagney <ac131313@redhat.com>
+
+ * remote-sim.c (dump_mem): Cleanup printf format argument.
+ * MAINTAINERS: Update, mn10300-elf now builds.
+
+2001-02-07 Mark Kettenis <kettenis@gnu.org>
+
+ * event-top.c: Remove duplicate #include <signal.h>.
+
+2001-02-06 Andrew Cagney <ac131313@redhat.com>
+
+ * sol-thread.c (restore_inferior_pid): Save the PID in a freshly
+ allocated buffer.
+ (save_inferior_pid): Restore the PID from that tempoary
+ buffer. Delete the buffer.
+ * utils.c (make_cleanup_close, do_close_cleanup): Ditto for FD.
+
+2001-02-06 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Add ``The Obvious Fix Rule''.
+
+2001-02-06 Andrew Cagney <ac131313@redhat.com>
+
+ * MAINTAINERS: Add Michael Snyder to Solaris/SPARC list.
+
+2001-02-06 Andrew Cagney <ac131313@cygnus.com>
+
+ * gdbarch.sh: Include "gdb_assert.h".
+ (struct gdbarch): Change ``nr_data'' to unsigned.
+ (alloc_gdbarch_data, free_gdbarch_data): New functions.
+ (gdbarch_free): Free the data-pointer vector. Use xfree to delete
+ architecture vector.
+ (struct gdbarch_data, struct gdbarch_data_registration): Move init
+ method to gdbarch_data. Add free method, make index unsigned.
+ (struct gdbarch_data_registry): Make nr unsigned.
+ (register_gdbarch_data): Add free parameter. Store in
+ gdbarch_data.
+ (init_gdbarch_data): Use set_gdbarch_data.
+ (set_gdbarch_data): New function.
+
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+2001-02-06 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * ser-unix.c (hardware_print_tty_state) [HAVE_SGTTY]: Call
+ fprintf_filtered with correct arguments.
+
+2001-02-06 Michael Snyder <msnyder@makita.cygnus.com>
+ Submitted by Paul Hilfinger (hilfingr@gnat.com)
+ and Andrei Petrov (and@genesyslab.com).
+ * findvar.c: Buffers of size MAX_REGISTER_RAW_SIZE or REGISTER_BYTES
+ must be allocated dynamically, since these are no longer constants.
+ * infcmd.c: Ditto.
+ * regcache.c: Ditto.
+ * remote.c: Ditto.
+ * sol-thread.c: Ditto.
+ * valops.c: Ditto.
+ * config/sparc/sun4sol2.mh (MH_CFLAGS): Add -I/usr/include/v9, as a
+ work-around for a missing Sun header file in solaris for sparc64.
+
+2001-02-04 Philip Blundell <philb@gnu.org>
+
+ * config/arm/linux.mh (NATDEPFILES): Add proc-service.o,
+ thread-db.o, lin-lwp.o; remove lin-thread.o, linux-thread.o.
+ * config/arm/nm-linux.h (PREPARE_TO_PROCEED, ATTACH_LWP,
+ GET_THREAD_SIGNALS): Define.
+ * arm-linux-nat.c (fill_gregset): Correct type of argument.
+ (supply_gregset): Likewise.
+ (fill_fpregset): Likewise.
+ (supply_fpregset): Likewise.
+
+Tue Feb 6 11:58:57 2001 David Taylor <taylor@redhat.com>
+
+ * valops.c (value_cast): If casting a scalar to a pointer, do not
+ issue a message about truncation unless it exceeds the length of
+ an address, not the length of a pointer. This is because what the
+ user gives us is an address, not a pointer, and we will ultimately
+ convert it (via ADDRESS_TO_POINTER) to a pointer, not truncate it
+ to a pointer. This allows things like "print *(int *)0x01000234"
+ to work without generating a misleading message on a target having
+ two byte pointers and four byte addresses.
+
+2001-02-05 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c: Change PTR to void * throughout.
+
+2001-02-05 J.T. Conklin <jtc@redback.com>
+
+ * signals.h: Removed.
+ * event-top.c (#include <signal.h>): Changed from signals.h.
+ * inflow.c: Likewise.
+ * mac-xdep.c: Likewise.
+ * ser-pipe.c: Likewise.
+ * ser-tcp.c: Likewise.
+ * standalone.c: Likewise.
+ * top.c: Likewise.
+ * utils.c: Likewise.
+ * Makefile.in: Removed signals.h from dependencies.
+
+2001-02-05 Christopher Faylor <cgf@cygnus.com>
+
+ Change suggested by Dean Luick <luick@cray.com>
+ * inferior.h (step_over_calls_kind): Remove trailing comma from
+ last enum element.
+ (step_over_calls): Declare as extern rather than global.
+
+2001-02-05 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * sh-tdep.c: Update copyright.
+ (sh_extract_return_value): Rewrite.
+ (sh3e_sh4_extract_return_value): New function.
+ (sh_gdbarch_init): Initialize gdbarch_extract-return_value to new
+ version of the function for sh3e and sh4 CPUs.
+
+2001-02-05 Michael Chastain <chastain@redhat.com>
+
+ * hppah-nat.c (child_xfer_memory): Add parameter 'struct mem_attrib *'
+ to conform with interface change.
+
+2001-02-04 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * config/djgpp/fnchange.lst: Tweak to make consistent with the
+ new files.
+
+ * config/djgpp/djconfig.sh: Use explicit absolute file name when
+ invoking `find'.
+
+ * ser-go32.c (dos_write) [UART_FIFO_WORKS]: Use outportsb only if
+ UART_FIFO_WORKS is defined. Otherwise use outportb.
+ From Francisco Pastor <fpastor.etra-id@etra.es>
+
+ * go32-nat.c (go32_xfer_memory): Make the argument list consistent
+ with target.h's `to_xfer_memory' member.
+
+2001-02-02 J.T. Conklin <jtc@redback.com>
+
+ * ppc-bdm.c (#include <signal.h>): Removed.
+ * remote-array.c: Likewise.
+ * remote-bug.c: Likewise.
+ * remote-e7000.c: Likewise.
+ * remote-mips.c: Likewise.
+ * remote-os9k.c: Likewise.
+ * remote-st.c: Likewise.
+ * remote-udi.c: Likewise.
+ * remote-vx29k.c: Likewise.
+ * remote-vx68.c: Likewise.
+ * remote-vx960.c: Likewise.
+ * remote-vxmips.c: Likewise.
+ * remote-vxsparc.c: Likewise.
+
+2001-02-02 John Moore <jmoore@redhat.com>
+
+ * remote-utils.h (sr_set_device): Changed free() to xfree() where
+ appropriate. Also changed Copyright to include 2001.
+ * symtab.h (obstack_chunk_free, SYMBOL_INIT_DEMANGLED_NAME): Likewise.
+ * value.h (value_free): Likewise.
+ * gdbarch.sh (gdbarch_free): Likewise.
+ * gdbarch.c, gdbarch.h: Regenerated.
+
+2001-02-02 John Moore <jmoore@redhat.com>
+
+ * cli/cli-cmds.c (apropos_command): Changed occurance of free() to
+ xfree(). Also changed Copyright to include 2001.
+
+2001-02-02 J.T. Conklin <jtc@redback.com>
+
+ * monitor.c (#include "gdb_wait.h"): Removed.
+ * ocd.c: Likewise.
+ * ppc-bdm.c: Likewise.
+ * remote-adapt.c: Likewise.
+ * remote-array.c: Likewise.
+ * remote-bug.c: Likewise.
+ * remote-e7000.c: Likewise.
+ * remote-eb.c: Likewise.
+ * remote-es.c: Likewise.
+ * remote-mips.c: Likewise.
+ * remote-mm.c: Likewise.
+ * remote-nindy.c: Likewise.
+ * remote-os9k.c: Likewise.
+ * remote-rdi.c: Likewise.
+ * remote-rdp.c: Likewise.
+ * remote-sds.c: Likewise.
+ * remote-sim.c: Likewise.
+ * remote-st.c: Likewise.
+ * remote-udi.c: Likewise.
+ * remote-vx.c: Likewise.
+ * remote-vx29k.c: Likewise.
+ * remote-vx68.c: Likewise.
+ * remote-vx960.c: Likewise.
+ * remote-vxmips.c: Likewise.
+ * remote-vxsparc.c: Likewise.
+ * remote.c: Likewise.
+ * ser-pipe.c: Likewise.
+ * ser-unix.c: Likewise.
+ * Makefile.in: Updated dependencies.
+
+2001-01-31 David Smith <dsmith@redhat.com>
+
+ * event-loop.c: Change inclusion of string.h to gdb_string.h and
+ updated the copyright notice.
+ * ser-pipe.c: Ditto.
+ * mi/mi-cmds.c: Ditto.
+ * mi/mi-console.c: Ditto.
+ * mi/mi-getopt.c: Ditto.
+ * mi/mi-parse.c: Ditto.
+
+2001-01-31 David Smith <dsmith@redhat.com>
+
+ * MAINTAINERS: Add David Smith to Write After Approval list.
+
+Tue Jan 30 15:43:08 2001 Andrew Cagney <cagney@cygnus.com>
+
+ * cli/cli-utils.c (putchar_filtered): Move function from here.
+ * utils.c (putchar_filtered): To here.
+ * cli/cli-utils.h (putchar_filtered): Move declaration from here.
+ * defs.h (putchar_filtered): To here.
+
+Tue Jan 30 17:27:11 2001 Andrew Cagney <cagney@redhat.com>
+
+ * configure.in (AC_CHECK_FUNCS): Replace vfork test with
+ AC_FUNC_VFORK macro.
+ * config.in, configure: Re-generate.
+
+ * gdb_vfork.h: New file.
+ * ser-pipe.c (pipe_open): Update. Include "gdb_vfork.h".
+ * fork-child.c (fork_inferior): Ditto.
+
+Tue Jan 30 17:09:07 2001 Andrew Cagney <cagney@redhat.com>
+
+ * defs.h (strsave): Delete declaration.
+ * utils.c (strsave): Delete definition.
+ * TODO (strsave): Update
+
+ * mac-xdep.c (tilde_expand): Replace strsave with xstrdup.
+ * sparcl-tdep.c (sparclite_open): Ditto.
+ * mips-tdep.c (mips_set_processor_type_command): Ditto.
+ (_initialize_mips_tdep): Ditto.
+ * solib.c (solib_open): Ditto.
+ * symfile.c (add_filename_language): Ditto.
+ (set_ext_lang_command): Ditto.
+ * source.c (init_source_path): Ditto.
+ (mod_path): Ditto.
+ * sh3-rom.c (sh3_open): Ditto.
+ (sh3e_open): Ditto.
+ * serial.c (serial_open): Ditto.
+ * remote-mips.c (common_open): Ditto.
+ * monitor.c (monitor_open): Ditto.
+ * m32r-rom.c (m32r_upload_command): Ditto.
+ * infcmd.c (path_command): Ditto.
+ * f-exp.y (parse_number): Ditto.
+ * breakpoint.c (create_longjmp_breakpoint): Ditto.
+ (create_thread_event_breakpoint): Ditto.
+ * arc-tdep.c (arc_set_cpu_type_command): Ditto.
+ (_initialize_arc_tdep): Ditto.
+
+Tue Jan 30 15:14:26 2001 Andrew Cagney <cagney@skil>
+
+ * cli/cli-script.c (define_command): Check for a bad hook value in
+ switch statement.
+
+2001-01-30 J.T. Conklin <jtc@redback.com>
+
+ * configure/sh/embed.mt: New file.
+ * configure/sh/linux.mt: New file.
+ * configure/sh/sh.mt: Removed.
+ * configure.tgt (sh-*-hms,sh-*-coff*,sh-*-elf*,sh-*-linux): New targets.
+ (sh-*-*): Removed.
+
+2001-01-29 Michael Chastain <chastain@redhat.com>
+
+ * symtab.c (lookup_block_symbol): Use 'namespace' parameter in
+ symbol comparisons in binary search.
+
+2001-01-27 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c (child_xfer_memory): Add missing argument required by
+ 2001-01-23 change.
+
+2001-01-27 Mark Kettenis <kettenis@gnu.org>
+
+ * ui-out.c (do_list_end): New function.
+ (make_cleanup_ui_out_list_end): New function.
+ * ui-out.h: Provide prototype for make_cleanup_ui_out_list_end.
+ * stack.c (print_frame) [UI_OUT]: Call
+ make_cleanup_ui_out_list_end to make sure we mark the end of the
+ list if we do a non-local exit. At the end of the function,
+ instead of calling ui_out_list_end directly, let do_cleanups
+ handle it.
+
+2001-01-26 Fernando Nasser <fnasser@redhat.com>
+
+ Fix double parsing of filenames passed as command line arguments
+ to GDB (causes weird handling of escape characters).
+ Also, remove dependencies on the CLI from libgdb.
+ * call-cmds.h: Remove declaration of exec_file_command().
+ * gdbcore.h: Remove declaration of exec_file_command().
+ Add declarations for exec_open() and exec_file_clear().
+ * symfile.h: Add declarations for symbol_file_add_main() and
+ symbol_file_clear().
+ * exec.c (exec_open): New function. Implements to_open for exec
+ targets.
+ (exec_file_clear): New function. Makes GDB forget about a previously
+ specified executable file.
+ (exec_file_attach): Move parsing of arguments from here ...
+ (exec_file_command): ... to here.
+ (init_exec_ops): Use exec_open(), not exec_file_command() to
+ implement to_open for exec targets.
+ * symfile.c (symbol_file_add_main): New function. Call symbol_file_add()
+ with default values. Used when the file name has already been parsed.
+ (symbol_file_clear): New function. Makes GDB forget about previously
+ read symbols.
+ (symbol_file_command): Call the above function instead of inline code.
+ * main.c: Include "symfile.h" and "gdbcore.h" instead of the deprecated
+ "call-cmds.h".
+ (captured_main): Call exec_file_attach() and symbol_file_add_main()
+ instead of exec_file_command() and symbol_file_command().
+ (captured_main): Add comment.
+ * corefile.c: Include "symfile.h".
+ (core_file_command): Call symbol_file_add_main() instead of
+ symbol_file_command().
+ (reopen_exec_file): Call exec_open() instead of exec_file_command().
+ * infcmd.c: Include "symfile.h".
+ (attach_command): Call symbol_file_add_main() instead of
+ symbol_file_command().
+ * infrun.c: Remove comment about the inclusion of "symfile.h",
+ not any longer appropriate.
+ (follow_exec): Call symbol_file_add_main() instead of
+ symbol_file_command().
+ * remote-es.c: Include "symfile.h".
+ (es1800_load): Call symbol_file_add_main() instead of
+ symbol_file_command().
+ * remote-vx.c: Remove comment about the inclusion of "symfile.h",
+ not any longer appropriate.
+ (vx-wait): Call symbol_file_add_main() instead of
+ symbol_file_command().
+ * solib-svr4.c (open_symbol_file_object): Call symbol_file_add_main()
+ instead of symbol_file_command().
+ * v850ice.c (ice_file): Call exec_open(), exec_file_attach() and
+ symbol_file_add_main() instead of exec_file_command() and
+ symbol_file_command().
+ * Makefile.in: Update dependencies.
+
+2001-01-26 Jeff Holcomb <jeffh@redhat.com>
+
+ * remote-udi.c (udi_open): Change strdup to xstrdup.
+ * thread.c (thread_apply_all_command): Change strdup to xstrdup.
+ Update copyright message.
+ * varobj.c (delete_variable_1): Likewise.
+
+ * gdb_string.h: Remove declaration of strdup. Update copyright
+ message.
+ * config/xm-mpw.h: Likewise.
+ * config/i386/xm-i386mach.h: Likewise.
+ * config/m68k/xm-apollo68b.h: Likewise.
+ * config/m68k/xm-hp300bsd.h: Likewise.
+ * config/rs6000/xm-rs6000.h: Likewise.
+ * config/vax/xm-vaxult.h: Remove declaration of strdup.
+ * config/vax/xm-vaxult2.h: Likewise.
+
+2001-01-26 Jeff Holcomb <jeffh@redhat.com>
+
+ * MAINTAINERS: Add Jeff Holcomb to Write After Approval list.
+
+2001-01-25 J.T. Conklin <jtc@redback.com>
+
+ * target.c (target_xfer_memory_partial): Return -1 on failure due
+ to invalid access mode attribute.
+
+2001-01-25 Christopher Faylor <cgf@cygnus.com>
+
+ * win32-nat.c (_initialize_core_win32): Prototype correctly.
+
+2001-01-25 Mark Kettenis <kettenis@gnu.org>
+
+ * config/alpha/tm-fbsd.h: Update copyright.
+ (USE_STRUCT_CONVENTION): Define in terms of
+ alphabsd_use_struct_convention.
+ * config/alpha/fbsd.mt (TDEPFILES): Add alphafbsd-tdep.c.
+ * alphafbsd-tdep.c: New file.
+
+2001-01-24 Fernando Nasser <fnasser@redhat.com>
+
+ * top.c (print_gdb_version): Update Copyright year.
+
+2001-01-24 J.T. Conklin <jtc@redback.com>
+
+ * dcache.c (dcache_write_line): Fix typo.
+
+ * memattr.c (delete_mem_region): Replace free() with xfree().
+ (mem_number): Add explicit type.
+
+ * sol-thread.c (sol_thread_xfer_memory): Add attrib argument.
+ (rw_common): Likewise.
+
+2001-01-24 Fernando Nasser <fnasser@redhat.com>
+
+ * infcmd.c (get_inferior_args, set_inferior_args): Accessor functions
+ for the inferior program arguments.
+ (run_command, run_no_args_command, init_infcmd)): Use accessor
+ functions to set the inferior program arguments.
+ * inferior.h: Add definitions to the accessor functions above.
+
+2001-01-23 Jim Blandy <jimb@redhat.com>
+
+ * dwarf2read.c (read_tag_const_type, read_tag_volatile_type):
+ Implement these correctly, using make_cv_type.
+
+2001-01-23 J.T. Conklin <jtc@redback.com>
+
+ * exec.c (xfer_memory): Add attrib argument.
+ * infptrace.c (child_xfer_memory): Likewise.
+ * lin-lwp.c (lin_lwp_xfer_memory): Likewise.
+ * monitor.c (monitor_xfer_memory): Likewise.
+ * remote-adapt.c (adapt_xfer_inferior_memory): Likewise.
+ * remote-array.c (array_xfer_memory): Likewise.
+ * remote-bug.c (bug_xfer_memory): Likewise.
+ * remote-e7000.c (e7000_xfer_inferior_memory): Likewise.
+ * remote-eb.c (eb_xfer_inferior_memory): Likewise.
+ * remote-es.c (es1800_xfer_inferior_memory): Likewise.
+ * remote-mips.c (mips_xfer_memory): Likewise.
+ * remote-mm.c (mm_xfer_inferior_memory): Likewise.
+ * remote-nindy.c (nindy_xfer_inferior_memory): Likewise.
+ * remote-os9k.c (rombug_xfer_inferior_memory): Likewise.
+ * remote-rdi.c (arm_rdi_xfer_memory): Likewise.
+ * remote-rdp.c (remote_rdp_xfer_inferior_memory): Likewise.
+ * remote-sds.c (sds_xfer_memory): Likewise.
+ * remote-sim.c (gdbsim_xfer_inferior_memory): Likewise.
+ * remote-st.c (st2000_xfer_inferior_memory): Likewise.
+ * remote-udi.c (udi_xfer_inferior_memory): Likewise.
+ * remote-vx.c (vx_xfer_memory): Likewise.
+ * remote.c (remote_xfer_memory): Likewise.
+ * target.c (debug_to_xfer_memory, do_xfer_memory): Likewise.
+ * target.h (child_xfer_memory, do_xfer_memory, xfer_memory): Likewise.
+ * thread-db.c (thread_db_xfer_memory): Likewise.
+
+ * target.h (#include "memattr.h"): Added.
+ (target_ops.to_xfer_memory): Add attrib argument.
+
+ * wince.c (_initialize_inftarg): Removed call to set_dcache_state.
+ * dcache.h (set_dcache_state): Removed declaration.
+ * dcache.c (set_dcache_state): Removed definition
+
+ * dcache.c: Update module comment, as dcache is now enabled and
+ disabled with memory region attributes instead of by the global
+ variable "remotecache". Add comment describing the interaction
+ between dcache and memory region attributes.
+ (dcache_xfer_memory): Add comment describing benefits of moving
+ cache writeback to a higher level.
+ (dcache_struct): Removed cache_has_stuff field. This was used to
+ record whether the cache had been accessed in order to invalidate
+ it when it was disabled. However, this is not needed because the
+ cache is write through and the code that enables, disables, and
+ deletes memory regions invalidate the cache. Add comment which
+ suggests that we could be more selective and only invalidate those
+ cache lines containing data from those memory regions.
+ (dcache_invalidate): Updated.
+ (dcache_xfer_memory): Updated.
+
+ (dcache_alloc): Don't abort() if dcache_enabled_p is clear.
+ (dcache_xfer_memory): Removed code that called do_xfer_memory() to
+ perform a uncached transfer if dcache_enabled_p was clear. This
+ function is now only called if caching is enabled for the memory
+ region.
+ (dcache_info): Always print cache info.
+
+ * target.c (do_xfer_memory): Add attrib argument.
+ (target_xfer_memory, target_xfer_memory_partial): Break transfer
+ into chunks defined by memory regions, pass region attributes to
+ do_xfer_memory().
+ * dcache.c (dcache_read_line, dcache_write_line): Likewise.
+
+ * Makefile.in (SFILES): Add memattr.c.
+ (COMMON_OBS): Add memattr.o.
+ (dcache.o): Add target.h to dependencies.
+ * memattr.c: New file.
+ * memattr.h: Likewise.
+
+ * config/m32r/m32r.mt (GDBSERVER_LIBS): Added ../../intl/libintl.a.
+ * config/mips/vr5000.mt (GDBSERVER_LIBS): Likewise.
+ * config/tic80/tic80.mt (GDBSERVER_LIBS): Likewise.
+ * gdbserver/low-sim.c (#include "defs.h"): Removed.
+ (mygeneric_load): Rename from generic_load.
+
+ * gdbserver/low-hppabsd.c (#include "server.h"): Added.
+ (#include "defs.h"): Removed.
+ (inferior_pid, perror_with_name): Remove declarations.
+ * gdbserver/low-linux.c: Likewise.
+ * gdbserver/low-nbsd.c: Likewise.
+ * gdbserver/low-sparc.c: Likewise.
+ * gdbserver/low-sun3.c: Likewise.
+
+ * i386-stub.c: Re-indent.
+ * m68k-stub.c: Re-indent.
+
+2001-01-22 Nicholas Duffek <nsd@redhat.com>
+
+ * gdbarch.sh (PARM_BOUNDARY): Define.
+ * gdbarch.c: Regenerate.
+ * gdbarch.h: Regenerate.
+
+2001-01-22 J.T. Conklin <jtc@redback.com>
+
+ * ns32k-tdep.c: #include "frame.h"
+ * config/ns32k/tm-umax.h (FRAME_FIND_SAVED_REGS): Restore. It
+ appears to have been inadvertantly removed sometime in May 1999.
+
+ * Revert 2000-11-09 changes where shared library objects were
+ moved from NATDEPFILES to TDEPFILES on NetBSD targets. While
+ we'd like to be able to debug dynamically linked executables,
+ this makes it impossible to build a cross debugger on a many
+ hosts.
+
+ * config/i386/nbsd.mt: Remove solib.o, solib-svr4.o from TDEPFILES.
+ * config/i386/nbsdelf.mt: Likewise.
+ * config/m68k/nbsd.mt: Likewise.
+ * config/ns32k/nbsd.mt: Likewise.
+ * config/powerpc/nbsd.mt: Likewise.
+ * config/sparc/nbsd.mt: Likewise.
+ * config/sparc/nbsdelf.mt: Likewise.
+ * config/i386/nbsd.mh: Add solib.o, solib-svr4.o to NATDEPFILES.
+ * config/i386/nbsdelf.mh: Likewise.
+ * config/m68k/nbsd.mh: Likewise.
+ * config/ns32k/nbsd.mh: Likewise.
+ * config/powerpc/nbsd.mh: Likewise.
+ * config/sparc/nbsd.mh: Likewise.
+
+2001-01-19 Jason Merrill <jason@redhat.com>
+
+ * dbxread.c (read_ofile_symtab): Stay with AUTO_DEMANGLING for G++.
+ (process_one_symbol): Likewise.
+ * dwarfread.c (handle_producer): Likewise.
+
+Thu Jan 18 12:08:57 2001 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (build_warnings): Disable -Wuninitialized until GDB
+ compiles with -Wuninitialized,-Werror.
+ * configure: Regenerate.
+
+ * MAINTAINERS: Add list of buildable targets.
+
+Thu Jan 18 12:48:04 2001 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * defs.h (STRCMP): Delete macro.
+
+ * objfiles.c (objfile_relocate): Replace STRCMP with call to
+ strcmp.
+ * symtab.c (lookup_partial_symbol, lookup_block_symbol): Ditto.
+ * symfile.c (compare_symbols): Ditto.
+ * standalone.c (open): Ditto.
+ * remote-es.c (verify_break): Ditto.
+ * cli/cli-decode.c (add_cmd, add_show_from_set): Ditto.
+
+ * symfile.c (compare_psymbols): Delete comment refering to STRCMP.
+
+Thu Jan 18 12:25:06 2001 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * varobj.c (FREEIF): Delete macro.
+ (varobj_set_value, free_variable): Replace FREEIF with ``xfree''
+ call.
+
+2001-01-18 Nick Clifton <nickc@redhat.com>
+
+ * arc-tdep.c (arc_cpu_type_table): Add new arc core numbers.
+ (arc_print_insn): No bfd available, so pass NULL to
+ arc_get_disassembler.
+
+2001-01-09 James Ingham <jingham@inghji.apple.com>
+
+ * symtab.c (lookup_symbol_aux): Call lookup_symbol_aux to lookup
+ a mangled symbol rather than recursing into lookup_symbol, since
+ this will just re-unmangle the name & call lookup_symbol_aux -
+ leading to an infinite recursion.
+
+2001-01-18 Mark Kettenis <kettenis@gnu.org>
+
+ * infcmd.c (print_return_value): Restore another space lost by
+ switch to UIOUT. ``$NN='' should be ``$NN =''.
+
+Fri Jan 19 02:31:40 2001 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * target.h (TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT)
+ * breakpoint.c (TARGET_REGION_OK_FOR_HW_WATCHPOINT): Wrap macro
+ definition in parenthesis.
+
+Fri Jan 19 02:13:40 2001 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-10-27 Mark Salter <msalter@redhat.com>:
+ * remote.c (remote_remove_hw_breakpoint): Add 'len' field to Z
+ packet.
+ (remote_insert_hw_breakpoint): Ditto.
+
+2001-01-17 J.T. Conklin <jtc@redback.com>
+
+ * config/m68k/tm-nbsd.h (USE_STRUCT_CONVENTION): Define.
+ (BPT_VECTOR, REMOTE_BPT_VECTOR): Change to 0xf.
+ * config/m68k/nbsd.mt (TDEPFILES): Add m68knbsd-tdep.o.
+ * m68knbsd-tdep.c: New file.
+
+ * i386nbsd-tdep.c: Remove #if 0'd out #includes.
+
+ * m68knbsd-nat.c: #include gdbcore.h.
+
+Wed Jan 17 09:41:58 2001 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * MAINTAINERS: Add J.T. Conklin to Blanket Write Privs.
+
+2001-01-16 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * procfs.c (procfs_stopped_by_watchpoint): Don't die if process
+ goes away -- just return false (ie. not stopped by watchpoint).
+ * source.c (openp): Fix typo in comment.
+
+2001-01-12 Nicholas Duffek <nsd@redhat.com>
+
+ * blockframe.c (generic_get_saved_register): Spelling fix.
+ * frame.h (FRAME_FP): Spelling fix.
+
+Fri Jan 12 18:29:46 2001 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * infcmd.c (print_return_value): Restore space lost by switch to
+ UIOUT. ``$NN='' should be ``$NN =''.
+
+2001-01-08 Nicholas Duffek <nsd@redhat.com>
+
+ * regcache.c (set_register_cached, register_buffer,
+ real_register, pseudo_register fetch_register, store_register):
+ New functions.
+ (register_changed, read_relative_register_raw_bytes_for_frame,
+ registers_changed, registers_fetched, read_register_bytes,
+ read_register_gen, write_register_gen, read_register,
+ read_signed_register, write_register, supply_register): Replace
+ register_valid[] with register_cached() and
+ set_register_cached().
+ (read_register_bytes, read_register_gen, write_register_gen,
+ read_register, read_signed_register, write_register,
+ supply_register): Replace registers[] with register_buffer().
+ (read_register_bytes, read_register_gen, read_register,
+ read_signed_register): Call fetch_register().
+ (write_register_gen, write_register): Call real_register() and
+ store_register().
+ (write_register_bytes): Call store_register().
+ * value.h (set_register_cached, register_buffer): Prototype.
+ * remote.c (remote_fetch_registers): Allocate regs[] with a
+ run-time size. Replace register_valid[] with
+ set_register_cached().
+ (store_register_using_P, remote_store_registers): Replace
+ registers[] with register_buffer().
+
+2001-01-08 Nicholas Duffek <nsd@redhat.com>
+
+ * regcache.c: Change "write-back" comment to "write-through".
+ Change "regno" to "regnum".
+ (read_register, read_signed_register): Remove "raw" from return
+ value description.
+ (supply_register): Spelling fix.
+ * value.h: Change "regno" to "regnum".
+
+2001-01-08 Fernando Nasser <fnasser@redhat.com>
+
+ * Makefile.in (install-gdbtk): Add .itcl files to the list of files
+ to be installed.
+
+2001-01-04 Michael Snyder <msnyder@mvstp600e.cygnus.com>
+
+ * mips-tdep.c (mips_coerce_float_to_double): Fix typo in comment.
+
+2001-01-04 Nicholas Duffek <nsd@redhat.com>
+
+ * valops.c (VALUE_SUBSTRING_START): Delete.
+
+2001-01-04 Nicholas Duffek <nsd@redhat.com>
+
+ * Makefile.in (SUBDIR_CLI_OBS): Add cli/cli-utils.o.
+ (SUBDIR_CLI_SRCS): Add cli/cli-utils.c.
+ (cli_utils_h): New variable.
+ (cli/cli-utils.o): New rule.
+ * cli/cli-utils.c: New file.
+ * cli/cli-utils.h: New file.
+
+2001-01-04 Nicholas Duffek <nsd@redhat.com>
+
+ * config/i386/tm-i386.h (REGISTER_CONVERT_TO_VIRTUAL,
+ REGISTER_CONVERT_TO_RAW): Delete trailing semicolon.
+
+2001-01-03 J.T. Conklin <jtc@redback.com>
+
+ * alphabsd-nat.c, i386-linux-nat.c, i386bsd-nat.c: Fix typo in
+ comment.
+
+2001-01-02 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * sh-tdep.c (sh_default_store_return_value): Allow for small return type.
+ (sh3e_sh4_store_return_value): Call sh_default_store_return_value for
+ non-float types.
+ * sparc-tdep.c (sparc_frame_chain): Fix typo in comment.
+ Update copyright notice.
+
+For older changes see ChangeLog-2000
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/ChangeLog-3.x b/gdb/ChangeLog-3.x
new file mode 100644
index 00000000000..672aa3daa1c
--- /dev/null
+++ b/gdb/ChangeLog-3.x
@@ -0,0 +1,4838 @@
+Tue Jan 23 15:49:47 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * dbxread.c (define_symbol): Deal with deftype 'X'.
+
+ * convex-dep.c (wait): Make it pid_t.
+
+ * convex-dep.c (comm_registers_info): accept decimal comm register
+ specification, as "i comm 32768".
+
+ * dbxread.c (process_one_symbol): Make VARIABLES_INSIDE_BLOCK
+ macro say by itself where variables are. Pass it desc.
+ m-convex.h (VARIABLES_INSIDE_BLOCK): Nonzero for native compiler.
+
+ * m-convex.h (SET_STACK_LIMIT_HUGE): Define.
+ (IGNORE_SYMBOL): Take out #ifdef N_MONPT and put in 0xc4.
+
+Fri Jan 19 20:04:15 1990 Jim Kingdon (kingdon at albert.ai.mit.edu)
+
+ * printcmd.c (print_frame_args): Always set highest_offset to
+ current_offset when former is -1.
+
+ * dbxread.c (read_struct_type): Print nice error message
+ when encountering multiple inheritance.
+
+Thu Jan 18 13:43:30 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
+
+ * dbxread.c (read_dbx_symtab): Always treat N_FN as a potential
+ source for a x.o or -lx symbol, ignoring OFILE_FN_FLAGGED.
+
+ * printcmd.c (print_frame_args): Cast -1 to (CORE_ADDR).
+
+ * hp300bsd-dep.c (_initialize_hp300_dep): Get kernel_u_addr.
+ m-hp300bsd.h (KERNEL_U_ADDR): Use kernel_u_addr.
+
+ * infcmd.c (run_command): #if 0 out call to
+ breakpoint_clear_ignore_counts.
+
+Thu Jan 11 12:58:12 1990 Jim Kingdon (kingdon at mole)
+
+ * printcmd.c (print_frame_args) [STRUCT_ARG_SYM_GARBAGE]:
+ Try looking up name of var before giving up & printing '?'.
+
+Wed Jan 10 14:00:14 1990 Jim Kingdon (kingdon at pogo)
+
+ * many files: Move stdio.h before param.h.
+
+ * sun3-dep.c (store_inferior_registers): Only try to write FP
+ regs #ifdef FP0_REGNUM.
+
+Mon Jan 8 17:56:15 1990 Jim Kingdon (kingdon at pogo)
+
+ * symtab.c: #if 0 out "info methods" code.
+
+Sat Jan 6 12:33:04 1990 Jim Kingdon (kingdon at pogo)
+
+ * dbxread.c (read_struct_type): Set TYPE_NFN_FIELDS_TOTAL
+ from all baseclasses; remove vestigial variable baseclass.
+
+ * findvar.c (read_var_value): Check REG_STRUCT_HAS_ADDR.
+ printcmd.c (print_frame_args): Check STRUCT_ARG_SYM_GARBAGE.
+ m-sparc.h: Define REG_STRUCT_HAS_ADDR and STRUCT_ARG_SYM_GARBAGE.
+
+ * blockframe.c (get_frame_block): Subtract one from pc if not
+ innermost frame.
+
+Fri Dec 29 15:26:33 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * printcmd.c (print_frame_args): check highest_offset != -1, not i.
+
+Thu Dec 28 16:21:02 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * valops.c (value_struct_elt): Clean up error msg.
+
+ * breakpoint.c (describe_other_breakpoints):
+ Delete extra space before "also set at" and add period at end.
+
+Tue Dec 19 10:28:42 1989 Jim Kingdon (kingdon at pogo)
+
+ * source.c (print_source_lines): Tell user which line number
+ was out of range when printing error message.
+
+Sun Dec 17 14:14:09 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * blockframe.c (find_pc_partial_function): Use
+ BLOCK_START (SYMBOL_BLOCK_VALUE (f)) instead of
+ SYMBOL_VALUE (f) to get start of function.
+
+ * dbxread.c: Make xxmalloc just a #define for xmalloc.
+
+Thu Dec 14 16:13:16 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * m68k-opcode.h (fseq & following fp instructions):
+ Change @ to $.
+
+Fri Dec 8 19:06:44 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * breakpoint.c (breakpoint_clear_ignore_counts): New function.
+ infcmd.c (run_command): Call it.
+
+Wed Dec 6 15:03:38 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * valprint.c: Change it so "array-max 0" means there is
+ no limit.
+
+ * expread.y (yylex): Change error message "invalid token in
+ expression" to "invalid character '%c' in expression".
+
+Mon Dec 4 16:12:54 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * blockframe.c (find_pc_partial_function): Always return 1
+ for success, 0 for failure, and set *NAME and *ADDRESS to
+ match the return value.
+
+ * dbxread.c (symbol_file_command): Use perror_with_name on
+ error from stat.
+ (psymtab_to_symtab, add_file_command),
+ core.c (validate_files), source.c (find_source_lines),
+ default-dep.c (exec_file_command): Check for errors from stat,
+ fstat, and myread.
+
+Fri Dec 1 05:16:42 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * valops.c (check_field): When following pointers, just get
+ their types; don't call value_ind.
+
+Thu Nov 30 14:45:29 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * config.gdb (pyr): New machine.
+ core.c [REG_STACK_SEGMENT]: New code.
+ dbxread.c (process_one_symbol): Cast return from copy_pending
+ to long before casting to enum namespace.
+ infrun.c: Split registers_info into DO_REGISTERS_INFO
+ and registers_info.
+ m-pyr.h, pyr-{dep.c,opcode.h,pinsn.c}: New files.
+
+ * hp300bsd-dep.c: Stay in sync with default-dep.c.
+
+ * m-hp300bsd.h (IN_SIGTRAMP): Define.
+
+Mon Nov 27 23:48:21 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * m-sparc.h (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE):
+ Return floating point values in %f0.
+
+Tue Nov 21 00:34:46 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * dbxread.c (read_type): #if 0 out code which skips to
+ comma following x-ref.
+
+Sat Nov 18 20:10:54 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * valprint.c (val_print): Undo changes of Nov 11 & 16.
+ (print_string): Add parameter force_ellipses.
+ (val_print): Pass force_ellipses true when we stop fetching string
+ before we get to the end, else pass false.
+
+Thu Nov 16 11:59:50 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * infrun.c (restore_inferior_status): Don't try to restore
+ selected frame if the inferior no longer exists.
+
+ * valprint.c (val_print): Rewrite string printing code not to
+ call print_string.
+
+ * Makefile.dist (clean): Remove xgdb and xgdb.o.
+
+Tue Nov 14 12:41:47 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * Makefile.dist (XGDB, bindir, xbindir, install, all): New stuff.
+
+Sat Nov 11 15:29:38 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * valprint.c (val_print): chars_to_get: New variable.
+
+Thu Nov 9 12:31:47 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * main.c (main): Process "-help" as a switch that doesn't
+ take an argument.
+
+Wed Nov 8 13:07:02 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * Makefile.dist (gdb.tar.Z): Add "else true".
+
+Tue Nov 7 12:25:14 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * infrun.c (restore_inferior_status): Don't dereference fid if NULL.
+
+ * config.gdb (sun3, sun4): Accept "sun3" and "sun4".
+
+Mon Nov 6 09:49:23 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * Makefile.dist (Makefile): Move comments after commands.
+
+ * *-dep.c [READ_COFF_SYMTAB]: Pass optional header size to
+ read_section_hdr().
+
+ * inflow.c: Include <fcntl.h> regardless of USG.
+
+ * coffread.c (read_section_hdr): Add optional_header_size.
+ (symbol_file_command): Pass optional header size to
+ read_section_hdr().
+ (read_coff_symtab): Initialize filestring.
+
+ * version.c: Change version to 3.4.xxx.
+
+ * GDB 3.4 released.
+
+Sun Nov 5 11:39:01 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * version.c: Change version to 3.4.
+
+ * symtab.c (decode_line_1): Only skip past "struct" if it
+ is there.
+
+ * valops.c (value_ind), eval.c (evaluate_subexp, case UNOP_IND):
+ Have "*" <int-valued-exp> return an int, not a LONGEST.
+
+ * utils.c (fprintf_filtered): Pass arg{4,5,6} to sprintf.
+
+ * printcmd.c (x_command): Use variable itself rather
+ than treating it as a pointer only if it is a function.
+ (See comment "this makes x/i main work").
+
+ * coffread.c (symbol_file_command): Use error for
+ "%s does not have a symbol-table.\n".
+
+Wed Nov 1 19:56:18 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * dbxread.c [BELIEVE_PCC_PROMOTION_TYPE]: New code.
+ m-sparc.h: Define BELIEVE_PCC_PROMOTION_TYPE.
+
+Thu Oct 26 12:45:00 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * infrun.c: Include <sys/dir.h>.
+
+ * dbxread.c (read_dbx_symtab, case N_LSYM, case 'T'):
+ Check for enum types and put constants in psymtab.
+
+Mon Oct 23 15:02:25 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * dbxread.c (define_symbol, read_dbx_symtab): Handle enum
+ constants (e.g. "b:c=e6,0").
+
+Thu Oct 19 14:57:26 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * stack.c (frame_info): Use FRAME_ARGS_ADDRESS_CORRECT
+ m-vax.h (FRAME_ARGS_ADDRESS_CORRECT): New macro.
+ (FRAME_ARGS_ADDRESS): Restore old meaning.
+
+ * frame.h (Frame_unknown): New macro.
+ stack.c (frame_info): Check for Frame_unknown return from
+ FRAME_ARGS_ADDRESS.
+ m-vax.h (FRAME_ARGS_ADDRESS): Sometimes return Frame_unknown.
+
+ * utils.c (fatal_dump_core): Add "internal error" to message.
+
+ * infrun.c (IN_SIGTRAMP): New macro.
+ (wait_for_inferior): Use IN_SIGTRAMP.
+ m-vax.h (IN_SIGTRAMP): New macro.
+
+Wed Oct 18 15:09:22 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * config.gdb, Makefile.dist: Shorten m-i386-sv32.h.
+
+ * coffread.c (symbol_file_command): Pass 0 to select_source_symtab.
+
+Tue Oct 17 12:24:41 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * i386-dep.c (i386_frame_num_args): Take function from m-i386.h
+ file. Check for pfi null.
+ m-i386.h (FRAME_NUM_ARGS): Use i386_frame_num_args.
+
+ * infrun.c (wait_for_inferior): set stop_func_name to 0
+ before calling find_pc_partial_function.
+
+Thu Oct 12 01:08:50 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * breakpoint.c (_initialize_breakpoint): Add "disa".
+
+ * Makefile.dist: Add GLOBAL_CFLAGS and pass to readline.
+
+ * config.gdb (various): "$machine =" -> "machine =".
+
+Wed Oct 11 11:54:31 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * inflow.c (try_writing_regs): #if 0 out this function.
+
+ * main.c (main): Add "-help" option.
+
+ * dbxread.c (read_dbx_symtab): Merge code for N_FUN with
+ N_STSYM, etc.
+
+Mon Oct 9 14:21:55 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * inflow.c (try_writing_regs_command): Don't write past end
+ of struct user.
+
+ * dbxread.c (read_struct_type): #if 0 out code which checks for
+ bitpos and bitsize 0.
+
+ * config.gdb: Accept sequent-i386 (not seq386).
+ (symmetry): Set depfile and paramfile.
+
+ * m-convex.h (IGNORE_SYMBOL): Check for N_MONPT if defined.
+
+Thu Oct 5 10:14:26 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * default-dep.c (read_inferior_memory): Put #if 0'd out comment
+ within /* */.
+
+Wed Oct 4 18:44:41 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * config.gdb: Change /dev/null to m-i386.h for various
+ 386 machine "opcodefile" entries.
+
+ * config.gdb: Accept seq386 for sequent symmetry.
+
+Mon Oct 2 09:59:50 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * hp300bsd-dep.c: Fix copyright notice.
+
+Sun Oct 1 16:25:30 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * Makefile.dist (DEPFILES): Add isi-dep.c.
+
+ * default-dep.c (read_inferior_memory): Move #endif after else.
+
+Sat Sep 30 12:50:16 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * version.c: Change version number to 3.3.xxx.
+
+ * GDB 3.3 released.
+
+ * version.c: Change version number to 3.3.
+
+ * Makefile.dist (READLINE): Add vi_mode.c
+
+ * config.gdb (i386): Change /dev/null to m-i386.h
+
+ * config.gdb: Add ';;' before 'esac'.
+
+ * Makefile.dist (gdb.tar.Z): Move comment above dependency.
+
+ * dbxread.c (read_ofile_symtab): Check symbol before start
+ of source file for GCC_COMPILED_FLAG_SYMBOL.
+ (start_symtab): Don't clear processing_gcc_compilation.
+
+Thu Sep 28 22:30:23 1989 Roland McGrath (roland at hobbes.ai.mit.edu)
+
+ * valprint.c (print_string): If LENGTH is zero, print "".
+
+Wed Sep 27 10:15:10 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * config.gdb: "rm tmp.c" -> "rm -f tmp.c".
+
+Tue Sep 26 13:02:10 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * utils.c (_initialize_utils): Use termcap to set lines_per_page
+ and chars_per_line.
+
+Mon Sep 25 10:06:43 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * dbxread.c (read_dbx_symtab, N_SOL): Do not add the same file
+ more than once.
+
+Thu Sep 21 12:43:18 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * infcmd.c (unset_environment_command): Delete all variables
+ if called with no arg.
+
+ * remote.c, inferior.h (remote_{read,write}_inferior_memory):
+ New functions.
+ core.c ({read,write}_memory): Use remote_{read,write}_inferior_memory.
+
+ * valops.c (call_function): When reserving stack space for
+ arguments, call value_arg_coerce.
+
+ * m-hp9k320.h: define BROKEN_LARGE_ALLOCA.
+
+ * breakpoint.c (delete_command): Ask for confirmation only
+ when there are breakpoints.
+
+ * dbxread.c (read_struct_type): If lookup_basetype_type has
+ copied a stub type, call add_undefined_type.
+
+ * sparc_pinsn.c (compare_opcodes): Check for "1+i" anywhere
+ in args.
+
+ * val_print.c (type_print_base): Print stub types as
+ "<incomplete type>".
+
+Wed Sep 20 07:32:00 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * sparc-opcode.h (swapa): Remove i bit from match.
+ (all alternate space instructions): Delete surplus "foo rs1+0"
+ patterns.
+
+ * Makefile.dist (LDFLAGS): Set to $(CFLAGS).
+
+ * remote-multi.shar (remote_utils.c, putpkt): Change csum to unsigned.
+
+Tue Sep 19 14:15:16 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * sparc-opcode.h: Set i bit in lose for many instructions which
+ aren't immediate.
+
+ * stack.c (print_frame_info): add "func = 0".
+
+Mon Sep 18 16:19:48 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * sparc-opcode.h (mov): Add mov to/from %tbr, %psr, %wim.
+
+ * sparc-opcode.h (rett): Fix notation to use suggested assembler
+ syntax from architecture manual.
+
+ * symmetry-dep.c (I386_REGNO_TO_SYMMETRY): New macro.
+ (i386_frame_find_saved_regs): Use I386_REGNO_TO_SYMMETRY.
+
+Sat Sep 16 22:21:17 1989 Jim Kingdon (kingdon at spiff)
+
+ * remote.c (remote_close): Set remote_desc to -1.
+
+ * gdb.texinfo (Output): Fix description of echo to match
+ reality and ANSI C.
+
+Fri Sep 15 14:28:59 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * symtab.c (lookup_symbol): Add comment about "asm".
+
+ * sparc-pinsn.c: Use NUMOPCODES.
+
+ * sparc-opcode.h (NUMOPCODES): Use sparc_opcodes[0] not *sparc_opcodes.
+
+Thu Sep 14 15:25:20 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (xxmalloc): Print error message before calling abort().
+
+ * infrun.c (wait_for_inferior): Check for {stop,prev}_func_name
+ null before passing to strcmp.
+
+Wed Sep 13 12:34:15 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * sparc-opcode.h: New field delayed.
+ sparc-pinsn.c (is_delayed_branch): New function.
+ (print_insn): Check for delayed branches.
+
+ * stack.c (print_frame_info): Use misc_function_vector in
+ case where ar truncates file names.
+
+Tue Sep 12 00:16:14 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * convex-dep.c (psw_info): Move "struct pswbit *p" with declarations.
+
+Mon Sep 11 14:59:57 1989 Jim Kingdon (kingdon at spiff)
+
+ * convex-dep.c (core_file_command): Delete redundant printing
+ of "Program %s".
+
+ * m-convex.h (ENTRY_POINT): New macro.
+
+ * m-convex.h (FRAME_CHAIN_VALID): Change outside_first_object_file
+ to outside_startup_file
+
+ * main.c: #if 0 out catch_termination and related code.
+
+ * command.c (lookup_cmd_1): Consider underscores part of
+ command names.
+
+Sun Sep 10 09:20:12 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * printcmd.c: Change asdump_command to disassemble_command
+ (_initialize_printcmd): Change asdump to diassemble.
+
+ * main.c (main): Exit with code 0 if we hit the end of a batch
+ file.
+
+ * Makefile.dist (libreadline.a): Fix syntax of "CC=${CC}".
+
+Sat Sep 9 01:07:18 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * values.c (history_info): Renamed to value_history_info.
+ Command renamed to "info value" (with "info history" still
+ accepted).
+
+ * sparc-pinsn.c (print_insn): Extend symbolic address printing
+ to cover "sethi" following by an insn which uses 1+i.
+
+Fri Sep 8 14:24:01 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * m-hp9k320.h, m-hp300bsd.h, m-altos.h, m-sparc.h, m-sun3.h
+ (READ_GDB_SYMSEGS): Remove.
+ dbxread.c [READ_GDB_SYMSEGS]: Remove code to read symsegs.
+
+ * sparc-pinsn.c (print_insn): Detect "sethi-or" pairs and
+ print symbolic address.
+
+ * sparc-opcode.h (sethi, set): Change lose from 0xc0000000 to
+ 0xc0c00000000.
+
+ * remote.c (remote_desc): Initialize to -1.
+
+ * Makefile.dist (libreadline.a): Pass CC='${CC}' to readline makefile.
+
+Thu Sep 7 00:07:17 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (read_struct_type): Check for static member functions.
+ values.c, eval.c, valarith.c, valprint.c, valops.c: Merge changes
+ from Tiemann for static member functions.
+
+ * sparc-opcode.h (tst): Fix all 3 patterns.
+
+ * Makefile.dist (gdb1): New rule.
+
+ * sparc-opcode.h: Change comment about what the disassembler
+ does with the order of the opcodes.
+
+ * sparc-pinsn.c (compare_opcodes): Put 1+i before i+1.
+ Also fix mistaken comment about preserving order of original table.
+
+ * sparc-opcode.h (clr, mov): Fix incorrect lose entries.
+
+ * m-symmetry.h (FRAME_NUM_ARGS): Add check to deal with code that
+ GCC sometimes generates.
+
+ * config.gdb: Change all occurances of "skip" to "/dev/null".
+
+ * README (about languages other than C): Update comments about
+ Pascal and FORTRAN.
+
+ * sparc-opcode.h (nop): Change lose from 0xae3fffff to 0xfe3fffff.
+
+ * values.c (value_virtual_fn_field): #if 0-out assignment to
+ VALUE_TYPE(vtbl).
+
+Wed Sep 6 12:19:22 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * utils.c (fatal_dump_core): New function.
+ Makefile.dist (MALLOC_FLAGS): use -Dbotch=fatal_dump_core
+
+Tue Sep 5 15:47:18 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * breakpoint.c (enable_command): With no arg, enable all bkpts.
+
+ * Makefile.dist (Makefile): Remove \"'s around $(MD).
+
+ * Makefile.dist: In "cd readline; make . . ." change first
+ SYSV_DEFINE to SYSV.
+
+ * m68k-pinsn.c (_initialize_pinsn): Use alternate assembler
+ syntax #ifdef HPUX_ASM
+
+Sat Sep 2 23:24:43 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * values.c (history_info): Don't check num_exp[0] if num_exp
+ is nil (just like recent editing_info change).
+
+Fri Sep 1 19:19:01 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * gdb.texinfo (inc-history, inc-readline): Copy in the inc-* files
+ because people might not have makeinfo.
+
+ * README (xgdb): Strengthen nasty comments.
+
+ * gdb.texinfo: Change @setfilename to "gdb.info".
+
+Thu Aug 31 17:23:50 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * main.c (editing_info): Don't check arg[0] if arg is null.
+
+ * m-vax.h: Add comment about known sigtramp bug.
+
+ * sun3-dep.c, sparc-dep.c (IS_OBJECT_FILE, exec_file_command):
+ Get right text & data addresses for .o files.
+
+Wed Aug 30 13:54:19 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * utils.c (tilde_expand): Remove function (it's in readline).
+
+ * sparc-opcode.h (call): Change "8" to "9" in first two
+ patterns (%g7->%o7).
+
+Tue Aug 29 16:44:41 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * printcmd.c (whatis_command): Change 4th arg to type_print
+ from 1 to -1.
+
+Mon Aug 28 12:22:41 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * dbxread.c (psymtab_to_symtab_1): In "and %s ..." change
+ pst->filename to pst->dependencies[i]->filename.
+
+ * blockframe.c (FRAMELESS_LOOK_FOR_PROLOGUE): New macro
+ made from FRAMELESS_FUNCTION_INVOCATION from m-sun3.h except
+ that it checks for zero return from get_pc_function_start.
+ m-hp9k320.h, m-hp300bsd.h, m-i386.h, m-isi.h, m-altos.h,
+ m-news.h, m-sparc.h, m-sun2.h, m-sun3.h, m-symmetry.h
+ (FRAMELESS_FUNCTION_INVOCATION): Use FRAMELESS_LOOK_FOR_PROLOGUE.
+
+ * dbxread.c (read_struct_type): Give warning and ignore field
+ if bitpos and bitsize are zero.
+
+Sun Aug 27 04:55:20 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (psymtab_to_symtab{,_1}): Print message about
+ reading in symbols before reading stringtab, not after.
+
+Sat Aug 26 02:01:53 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * dbxread.c (IS_OBJECT_FILE, ADDR_OF_TEXT_SEGMENT): New macros.
+ (read_dbx_symtab): Use text_addr & text_size to set end_of_text_addr.
+ (symbol_file_command): pass text_addr & text_size to read_dbx_symtab.
+
+Fri Aug 25 23:08:13 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * valprint.c (value_print): Try to give the name of function
+ pointed to when printing a function pointer.
+
+Thu Aug 24 23:18:40 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * core.c (xfer_core_file): In cases where MEMADDR is above the
+ largest address that makes sense, set i to len.
+
+Thu Aug 24 16:04:17 1989 Roland McGrath (roland at hobbes.ai.mit.edu)
+
+ * valprint.c (print_string): New function to print a character
+ string, doing array-max limiting and repeat count processing.
+ (val_print, value_print): Use print_string.
+ (REPEAT_COUNT_THRESHOLD): New #define, the max number of elts to print
+ without using a repeat count. Set to ten.
+ (value_print, val_print): Use REPEAT_COUNT_THRESHOLD.
+
+ * utils.c (printchar): Use {fputs,fprintf}_filtered.
+
+ * valprint.c (val_print): Pass the repeat count arg to the
+ fprintf_filtered call for "<repeats N times>" messages.
+
+Wed Aug 23 22:53:47 1989 Roland McGrath (roland at hobbes.ai.mit.edu)
+
+ * utils.c: Include <pwd.h>.
+
+ * main.c: Declare free.
+
+Wed Aug 23 05:05:59 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * utils.c, defs.h: Add tilde_expand.
+ source.c (directory_command),
+ main.c (cd_command),
+ main.c (set_history_filename),
+ dbxread.c (symbol_file_command),
+ coffread.c (symbol_file_command),
+ dbxread.c (add_file_command),
+ symmisc.c (print_symtabs),
+ *-dep.c (exec_file_command, core_file_command),
+ main.c (source_command): Use tilde_expand.
+
+ * dbxread.c (read_type): When we get a cross-reference, resolve
+ it immediately if possible, only calling add_undefined_type if
+ necessary.
+
+ * gdb.texinfo: Uncomment @includes and put comment at start
+ of file telling people to use makeinfo.
+
+ * valprint.c (type_print_base): Print the right thing for
+ bitfields.
+
+ * config.gdb (sun3os3): Set paramfile and depfile.
+
+Tue Aug 22 05:38:36 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * dbxread.c (symbol_file_command): Pass string table size to
+ read_dbx_symtab().
+ (read_dbx_symtab): Before indexing into string table, check
+ string table index for reasonableness.
+ (psymtab_to_symtab{,_1}, read_ofile_symtab): Same.
+
+Tue Aug 22 04:04:39 1989 Roland McGrath (roland at hobbes.ai.mit.edu)
+
+ * m68k-pinsn.c: Replaced many calls to fprintf and fputs with
+ calls to fprintf_filtered and fputs_filtered.
+ (print_insn_arg): Use normal MIT 68k syntax for postincrement,
+ predecrement, and register indirect addressing modes.
+
+Mon Aug 21 10:08:02 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * main.c (initialize_signals): Set signal handler for SIGQUIT
+ and SIGHUP to do_nothing.
+
+ * ns32k-opcode.h (ord): Change 1D1D to 1D2D.
+
+ * ns32k-pinsn.c (print_insn_arg, print_insn): Handle index
+ bytes correctly.
+
+ * ns32k-opcode.h: Add comments.
+
+ * dbxread.c (read_type): Put enum fields in type.fields in order
+ that they were found in the debugging symbols (not reverse order).
+
+Sun Aug 20 21:17:13 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * main.c (source_command): Read .gdbinit if run without argument.
+
+ * source.c (directory_command): Only print "foo already in path"
+ if from_tty.
+
+ * version.c: Change version number to 3.2.xxx
+
+Sat Aug 19 00:24:08 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * m-news.h: Define HAVE_WAIT_STRUCT.
+
+ * m-isi.h, isi-dep.c: Replace with new version from Adam de Boor.
+ config.gdb: Remove isibsd43.
+
+ * main.c (catch_termination): Don't say we have written
+ .gdb_history until after we really have.
+
+ * convex-dep.c (attach): Add "sleep (1)".
+ (write_vector_register): Use "LL" with long long constant.
+ (wait): Close comment.
+ (wait): Change "unix 7.1 bug" to "unix 7.1 feature" & related
+ changes in comment.
+ (scan_stack): And fp with 0x80000000 in while loop test.
+ (core_file_command): Move code to set COREFILE.
+ (many places): Change printf to printf_filtered.
+ (psw_info): Allow argument giving value to print as a psw.
+ (_initialize_convex_dep): Update docstrings.
+
+ * m-convex.h (WORDS_BIG_ENDIAN): Correct typo ("WRODS")
+ define NO_SIGINTERRUPT.
+ define SET_STACK_LIMIT_HUGE.
+ add "undef BUILTIN_TYPE_LONGEST" before defining it.
+ Use "LL" after constants in CALL_DUMMY.
+
+ * dbxread.c: In the 3 places it says error "ridiculous string
+ table size"... delete extra parameter to error.
+
+ * dbxread.c (scan_file_globals): Check for FORTRAN common block.
+ Allow multiple references for the sake of common blocks.
+
+ * main.c (initialize_main): Set history_filename to include
+ current directory.
+
+ * valprint.c (decode_format): Don't return a defaulted size
+ field if osize is zero.
+
+ * gdb.texinfo (Compilation): Update information on -gg symbols.
+ Document problem with ar.
+
+Fri Aug 18 19:45:20 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * valprint.c (val_print, value_print): Add "<repeats %d times>" code.
+ Also put "..." outside quotes for strings.
+
+ * main.c (initialize_main): Add comment about history output file
+ being different from history input file.
+
+ * m-newsos3.h: Undefine NO_SIGINTERRUPT. Rearrange a few comments.
+
+ * m-newsos3.h (REGISTER_U_ADDR): Use new version from Hikichi.
+
+ * sparc-opcode.h: Add comment clarifying meaning of the order of
+ the entries in sparc_opcodes.
+
+ * eval.c (evaluate_subexp, case UNOP_IND): Deal with deferencing
+ things that are not pointers.
+
+ * valops.c (value_ind): Make dereferencing an int give a LONGEST.
+
+ * expprint.c (print_subexp): Add (int) cast in OP_LAST case.
+
+ * dbxread.c (read_array_type): Set lower and upper if adjustable.
+
+ * symtab.c (lookup_symbol): Don't abort if symbol found in psymtab
+ but not in symtab.
+
+Thu Aug 17 15:51:20 1989 Randy Smith (randy at hobbes.ai.mit.edu)
+
+ * config.gdb: Changed "Makefile.c" to "Makefile.dist".
+
+Thu Aug 17 01:58:04 1989 Roland McGrath (roland at apple-gunkies.ai.mit.edu)
+
+ * sparc-opcode.h (or): Removed incorrect lose bit 0x08000000.
+ [many]: Changed many `lose' entries to have the 0x10 bit set, so
+ they don't think %l0 is %g0.
+
+Wed Aug 16 00:30:44 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * m-symmetry.h (STORE_STRUCT_RETURN): Also write reg 0.
+ (EXTRACT_RETURN_VALUE): Call symmetry_extract_return_value.
+ symmetry-dep.c (symmetry_extract_return_value): New fn.
+
+ * main.c (symbol_completion_function): Deal with changed
+ result_list from lookup_cmd_1 for ambiguous return.
+ command.c (lookup_cmd): Same.
+
+ * inflow.c [TIOCGETC]: Move #include "param.h" back before
+ system #includes. Change all #ifdef TIOCGETC to
+ #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
+ m-i386-sysv3.2.h, m-i386gas-sysv3.2.h: Remove "#undef TIOCGETC"
+ and add "#define TIOCGETC_BROKEN".
+
+ * command.c (lookup_cmd_1): Give the correct result_list in the
+ case of an ambiguous return where there is a partial match
+ (e.g. "info a"). Add comment clarifying what is the correct
+ result_list.
+
+ * gdb.texinfo (GDB History): Document the two changes below.
+
+ * main.c (command_line_input): Make history expansion not
+ just occur at the beginning of a line.
+
+ * main.c (initialize_main): Make history expansion off by default.
+
+ * inflow.c: Move #include "param.h" after system #includes.
+
+ * i386-dep.c (i386_float_info): Use U_FPSTATE macro.
+
+ * m-i386-sysv3.2.h, m-i386gas-sysv3.2.h: New files.
+ Makefile.dist, config.gdb: Know about these new files.
+
+Tue Aug 15 21:36:11 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * symtab.c (lookup_struct_elt_type): Use type_print rather
+ than assuming type has a name.
+
+Tue Aug 15 02:25:43 1989 Roland McGrath (roland at apple-gunkies.ai.mit.edu)
+
+ * sparc-opcode.h (mov): Removed bogus "or i,0,d" pattern.
+
+ * sparc-opcode.h (mov, or): Fixed incorrect `lose' members.
+
+ * sparc-dep.c: Don't include "sparc-opcode.h".
+ (skip_prologue, isanulled): Declare special types to recognize
+ instructions, and use them.
+
+ * sparc-pinsn.c (print_insn): Sign-extend 13-bit immediate args.
+ If they are less than +9, print them in signed decimal instead
+ of unsigned hex.
+
+ * sparc-opcode.h, sparc-pinsn.c: Completely rewritten to share an
+ opcode table with gas, and thus produce disassembly that looks
+ like what the assembler accepts.
+
+Tue Aug 15 16:20:52 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * symtab.c (find_pc_psymbol): Move best_pc=psymtab->textlow-1
+ after test for psymtab null.
+
+ * main.c (editing_info): Remove variable retval.
+
+ * config.gdb (sun3, isi): Comment out obsolete message about telling
+ it whether you have an FPU (now that it detects it).
+
+ * config.gdb (sun3): Accept sun3os3.
+
+ * m68k-insn.h: Include <signal.h>.
+
+ * m68k-pinsn.h (convert_{to,from}_68881): Add have_fpu code
+
+ * m-newsos3.h: Undefine USE_PCB. That code didn't seem to work.
+
+ * sparc-dep.c: Put in insn_fmt and other stuff from the old
+ sparc-opcode.h.
+
+ * sparc-opcode.h, sparc-pinsn.c: Correct copyright notice.
+
+ * sparc-opcode.h, sparc-pinsn.c: Replace the old ones with the new
+ ones by roland.
+
+Tue Aug 15 02:25:43 1989 Roland McGrath (roland at apple-gunkies.ai.mit.edu)
+
+ * Makefile.dist: Don't define CC at all.
+
+ * Makefile.dist (Makefile): Remove tmp.c after preprocessing.
+ Use $(MD) instead of M_MAKEDEFINE in the cc command.
+
+ * Makefile.dist: Don't define RL_LIB as
+ "${READLINE}/libreadline.a", since READLINE is a list of files.
+
+Mon Aug 14 23:49:29 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * main.c (print_version): Change 1988 to 1989.
+
+ * main.c (copying_info, initialize_main): Remove #if 0'd code.
+
+Tue Aug 1 14:44:56 1989 Hikichi (hikichi at sran203)
+
+ * m-newsos3.h
+ (NO_SIGINTERRUPT): have SIGINTERRUPT on NEWS os 3.
+
+ * m-news.h(FRAME_FIND_SAVED_REGS): use the sun3's instead of old
+ one.
+
+Mon Aug 14 15:27:01 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * m-news.h, m-newsos3.h, news-dep.c: Merge additional changes
+ by Hikichi (ChangeLog entries above).
+
+ * Makefile.dist (READLINE): List readline files individually
+ so we don't accidently get random files from the readline
+ directory.
+
+ * m-news.h (STORE_RETURN_VALUE, EXTRACT_RETURN_VALUE):
+ Expect floating point returns to be in fp0.
+
+ * gdb.texinfo (Format options): New node.
+
+ * gdb.texinfo: Comment out "@include"s until bfox fixes the
+ readline & history docs.
+
+ * dbxread.c (read_addl_syms): Set startup_file_* if necessary at
+ the end (as well as when we hit ".o").
+
+ * printcmd.c (decode_format): Set val.format & val.size to '?' at
+ start and set defaults at end.
+
+ * symtab.c (decode_line_1): Check for class_name null.
+
+ * valops.c: Each place where it compares against field names,
+ check for null field names. (new t_field_name variables).
+
+ * utils.c (fputs_filtered): Check for linebuffer null before
+ checking whether to call fputs. Remove later check for linebuffer
+ null.
+
+Sun Aug 13 15:56:50 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * m-isi.h, m-sun3.h ({PUSH,POP}_FP_REGS): New macros.
+ m-sun3.h (NUM_REGS): Conditionalize on FPU.
+ config.gdb (sun3, isi): Add message about support for machines
+ without FPU.
+
+ * main.c (catch_termination, initialize_signals): new functions.
+
+ * main.c (editing_info): Add "info editing n" and "info editing +".
+ Rewrite much of this function.
+ gdb.texinfo (GDB Readline): Document it.
+
+ * values.c (history_info): Add "info history +". Also add code to
+ do "info history +" when command is repeated.
+ gdb.texinfo (Value History): Document "info history +".
+
+ * expprint.c (print_subexp): Add OP_THIS to case stmt.
+
+ * config.gdb (sun4os4): Put quotes around make define.
+
+ * config.gdb: Canonicalize machine name at beginning.
+
+Sat Aug 12 00:50:59 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * config.gdb: define M_MAKEDEFINE
+ Makefile (Makefile, MD): Be able to re-make Makefile.
+
+ * main.c (command_line_input): Add comments to
+ the command history.
+
+ * Makefile.dist (Makefile): Add /bin/false.
+
+Fri Aug 11 14:35:33 1989 Jim Kingdon (kingdon at spiff)
+
+ * Makefile.dist: Comment out .c.o rule and add TARGET_ARCH.
+
+ * m-altos.h: Include sys/page.h & sys/net.h
+
+ * m-altos.h (FRAME_CHAIN{,_VALID}): Use outside_startup_file.
+
+ * config.gdb (altos, altosgas): Add M_SYSV & M_BSD_NM and remove
+ M_ALLOCA=alloca.o from makedefine.
+
+ * coffread.c (complete_symtab): Change a_entry to entry.
+
+ * m-altosgas.h: New file.
+
+ * m-symmetry (REGISTER_BYTE): Fix dumb mistake.
+
+Fri Aug 11 06:39:49 1989 Roland McGrath (roland at hobbes.ai.mit.edu)
+
+ * utils.c (set_screensize_command): Check for ARG being nil, since
+ that's what execute_command will pass if there's no argument.
+
+ * expread.y (yylex): Recognize "0x" or "0X" as the beginning of a
+ number.
+
+Thu Aug 10 15:43:12 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * config.gdb, Makefile.dist: Rename Makefile.c to Makefile.dist.
+
+ * m-altos.h: Add comment about porting to USGR2.
+
+ * config.gdb (sparc): Add -Usparc.
+
+Wed Aug 9 14:20:39 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * m-sun3os4.h: Define BROKEN_LARGE_ALLOCA.
+
+ * values.c (modify_field): Check for value too large to fit in
+ bitfield.
+
+ * utils.c (fputs_filtered): Allow LINEBUFFER to be NULL.
+
+ * breakpoint.c (condition_command): Check for attempt to specify
+ non-numeric breakpoint number.
+
+ * config.gdb, Makefile, m-altos.h, altos-dep.c: Merge Altos
+ port.
+
+ * README: Change message about editing Makefile.
+
+ * config.gdb: Edit Makefile.
+ Copied Makefile to Makefile.c and changed to let config.gdb
+ run us through the C preprocessor.
+
+ * expread.y (yylex): Test correctly for definition of number.
+
+Wed Aug 9 11:56:05 1989 Randy Smith (randy at hobbes.ai.mit.edu)
+
+ * dbxread.c (read_dbx_symtab): Put bracketing of entry point in
+ test case for .o symbols so that it will be correct even without
+ debugging symbols.
+ (end_psymtab): Took bracketing out.
+
+ * blockframe.c (outside_startup_file): Reverse the sense of the
+ return value to make the functionality implied by the name
+ correct.
+
+Tue Aug 8 11:48:38 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * coffread.c (symbol_file_command): Do not assume presence of a.out
+ header.
+
+ * blockframe.c: Replace first_object_file_end with
+ startup_file_{start,end}
+ (outside_startup_file): New function.
+ dbxread.c (read_addl_syms, read_dbx_symtab, end_psymbol): set
+ startup_file_*. Delete first_object_file_end code.
+ Add entry_point and ENTRY_POINT
+ coffread.c (complete_symtab): Set startup_file_*.
+ (first_object_file_end): Add as static.
+ m-*.h (FRAME_CHAIN, FRAME_CHAIN_VALID): Call outside_startup_file
+ instead of comparing with first_object_file_end.
+
+ * breakpoint.c (breakpoint_1): Change -1 to (CORE_ADDR)-1.
+
+ * config.gdb (i386, i386gas): Add missing quotes at end of "echo"
+
+ * source.c (directory_command): Add dont_repeat ();
+
+Mon Aug 7 18:03:51 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * dbxread.c (read_addl_syms): Change strcmp to strncmp and put 3rd
+ arg back.
+
+ * command.h (struct cmd_list_element): Add comment clarifying
+ purpose of abbrev_flag.
+
+Mon Aug 7 12:51:03 1989 Randy Smith (randy at hobbes.ai.mit.edu)
+
+ * printcmd.c (_initialize_printcmd): Changed "undisplay" not to
+ have abbrev flag set; it isn't an abbreviation of "delete
+ display", it's an alias.
+
+Mon Aug 7 00:25:15 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * symtab.c (lookup_symtab_1): Remove filematch (never used).
+
+ * expread.y [type]: Add second argument to 2 calls to
+ lookup_member_type which were missing them.
+
+ * dbxread.c (symbol_file_command): Add from_tty arg.
+ Check it before calling query.
+
+ * infcmd.c (tty_command): Add from_tty arg.
+
+ * eval.c (evaluate_subexp): Remove 3rd argument from
+ calls to value_x_unop.
+
+ * dbxread.c (read_addl_syms): Remove 3rd argument from
+ call to strcmp.
+
+ * gdb.texinfo (Command editing): @include inc-readline.texinfo
+ and inc-history.texinfo and reorganize GDB-specific stuff.
+
+ * Makefile: Add line MAKE=make.
+
+ * README (second paragraph): Fix trivial errors.
+
+ * dbxread.c (read_struct_type): Make sure p is initialized.
+
+ * main.c (symbol_completion_function): Complete correctly
+ on the empty string.
+
+Sun Aug 6 21:01:59 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * symmetry-dep.c: Remove "long" from definition of i386_follow_jump.
+
+ * gdb.texinfo (Backtrace): Document "where" and "info stack".
+
+ * dbxread.c (cleanup_undefined_types): Strip off "struct "
+ or "union " from type names before doing comparison
+
+Sat Aug 5 02:05:36 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * config.gdb (i386, i386gas): Improve makefile editing instructions.
+
+ * Makefile: Fix typo in CLIBS for SYSV.
+
+ * dbxread.c (read_dbx_symtab): Deal with N_GSYM typedefs.
+
+ * dbxread.c (add_file_command): Do not free name. We didn't
+ allocate it; it just points into arg_string.
+
+ * Makefile, m-*.h: Change LACK_VPRINTF to HAVE_VPRINTF.
+
+Fri Jul 28 00:07:48 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * valprint.c (val_print): Made sure that all returns returned a
+ value (usually 0, indicating no memory printed).
+
+ * core.c (read_memory): Changed "return" to "return 0".
+
+ * expread.y (parse_number): Handle scientific notation when the
+ string does not contain a '.'.
+
+Thu Jul 27 15:14:03 1989 Randy Smith (randy at hobbes.ai.mit.edu)
+
+ * infrun.c (signals_info): Error if signal number passed is out of
+ bounds.
+
+ * defs.h: Define alloca to be __builtin_alloca if compiling with
+ gcc and localized inclusion of alloca.h on the sparc with the
+ other alloca stuff.
+ * command.c: Doesn't need to include alloca.h on the sparc; defs.h
+ does it for you.
+
+ * printcmd.c (print_frame_args): Changed test for call to
+ print_frame_nameless_args to check i to tell if any args had been
+ printed.
+
+Thu Jul 27 04:40:56 1989 Roland McGrath (roland at hobbes.ai.mit.edu)
+
+ * blockframe.c (find_pc_partial_function): Always check that NAME
+ and/or ADDRESS are not nil before storing into them.
+
+Wed Jul 26 23:41:21 1989 Roland McGrath (roland at hobbes.ai.mit.edu)
+
+ * m-newsos3.h: Define BROKEN_LARGE_ALLOCA.
+ * dbxread.c (symbol_file_command, psymtab_to_symtab):
+ Use xmalloc #ifdef BROKEN_LARGE_ALLOCA.
+
+Tue Jul 25 16:28:18 1989 Jay Fenlason (hack at apple-gunkies.ai.mit.edu)
+
+ * m68k-opcode.h: moved some of the fmovem entries so they're
+ all consecutive. This way the assembler doesn't bomb.
+
+Mon Jul 24 22:45:54 1989 Randy Smith (randy at hobbes.ai.mit.edu)
+
+ * symtab.c (lookup_symbol): Changed error to an informational (if
+ not very comforting) message about internal problems. This will
+ get a null symbol returned to decode_line_1, which should force
+ things to be looked up in the misc function vector.
+
+Wed Jul 19 13:47:34 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * symtab.c (lookup_symbol): Changed "fatal" to "error" in
+ external symbol not found in symtab in which it was supposed to be
+ found. This can be reached because of a bug in ar.
+
+Tue Jul 18 22:57:43 1989 Randy Smith (roland at hobbes.ai.mit.edu)
+
+ * m-news.h [REGISTER_U_ADDR]: Decreased the assumed offset of fp0
+ by 4 to bring it into (apparently) appropriate alignment with
+ reality.
+
+Tue Jul 18 18:14:42 1989 Randy Smith (randy at hobbes.ai.mit.edu)
+
+ * Makefile: pinsn.o should depend on opcode.h
+
+ * m68k-opcode.h: Moved fmovemx with register lists to before other
+ fmovemx.
+
+Tue Jul 18 11:21:42 1989 Jim Kingdon (kingdon at susie)
+
+ * Makefile, m*.h: Only #define vprintf (to _doprnt or printf,
+ depends on the system) if the library lacks it (controlled by
+ LACK_VPRINTF_DEFINE in makefile). Unpleasant, but necessary to
+ make this work with the GNU C library.
+
+Mon Jul 17 15:17:48 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * breakpoint.c (breakpoint_1): Change addr-b->address to
+ b->address-addr.
+
+Sun Jul 16 16:23:39 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * eval.c (evaluate_subexp): Change error message printed when
+ right operand of '@' is not an integer to English.
+
+ * infcmd.c (registers_info): Fix call to print_spaces_filtered
+ to specify right # of arguments.
+
+ * gdb.texinfo (Command Editing): Document info editing command.
+
+ * coffread.c (read_file_hdr): Add MC68MAGIC.
+
+ * source.c (select_source_symtab): Change MAX to max.
+
+Fri Jul 14 21:19:11 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * infcmd.c (registers_info): Clean up display to look good with long
+ register names, to say "register" instead of "reg", and to put the
+ "relative to selected stack frame" bit at the top.
+
+Fri Jul 14 18:23:09 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (record_misc_function): Put parens around | to force
+ correct evaluation.
+
+Wed Jul 12 12:25:53 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * m-newsos3, m-news, infrun.c, Makefile, config.gdb, news-dep.c:
+ Merge in Hikichi's changes for Sony/News-OS 3 support.
+
+Tue Jul 11 21:41:32 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * utils.c (fputs_filtered): Don't do any filtering if output is
+ not to stdout, or if stdout is not a tty.
+ (fprintf_filtered): Rely on fputs_filtered's check for whether to
+ do filtering.
+
+Tue Jul 11 00:33:58 1989 Randy Smith (randy at hobbes.ai.mit.edu)
+
+ * GDB 3.2 Released.
+
+ * valprint.h: Deleted.
+
+ * utils.c (fputs_filtered): Don't do any filtering if filtering is
+ disabled (lines_per_page == 0).
+
+Mon Jul 10 22:27:53 1989 Randy Smith (roland at hobbes.ai.mit.edu)
+
+ * expread.y [typebase]: Added "unsigned long int" and "unsigned
+ short int" to specs.
+
+Mon Jul 10 21:44:55 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * main.c (main): Make -cd use cd_command to avoid
+ current_directory with non-absolute pathname.
+
+Mon Jul 10 00:34:29 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (symbol_file_command): Catch errors from stat (even
+ though they should never happen).
+
+ * source.c (openp): If the path is null, use the current
+ directory.
+
+ * dbxread.c (read_dbx_symtab): Put N_SETV symbols into the misc
+ function vector ...
+ (record_misc_function): ... as data symbols.
+
+ * utils.c (fprintf_filtered): Return after printing if we aren't
+ going to do filtering.
+
+ * Makefile: Added several things for make clean to take care of.
+
+ * expread.y: Lowered "@" in precedence below +,-,*,/,%.
+
+ * eval.c (evaluate_subexp): Return an error if the rhs of "@"
+ isn't integral.
+
+ * Makefile: Added removal of core and gdb[0-9] files to clean
+ target.
+
+ * Makefile: Made a new target "distclean", which cleans things up
+ correctly for making a distribution.
+
+Sun Jul 9 23:21:27 1989 Randy Smith (randy at hobbes.ai.mit.edu)
+
+ * dbxread.c: Surrounded define of gnu symbols with an #ifndef
+ NO_GNU_STABS in case you don't want them on some machines.
+ * m-npl.h, m-pn.h: Defined NO_GNU_STABS.
+
+Sun Jul 9 19:25:22 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * utils.c (fputs_filtered): New function.
+ (fprintf_filtered): Use fputs_filtered.
+ utils.c (print_spaces_filtered),
+ command.c (help_cmd,help_cmd_list),
+ printcmd.c (print_frame_args),
+ stack.c (print_block_frame_locals, print_frame_arg_vars),
+ valprint.c (many functions): Use fputs_filtered instead of
+ fprintf_filtered to avoid arbitrary limit.
+
+ * utils.c (fprintf_filtered): Fix incorrect comment.
+
+Sat Jul 8 18:12:01 1989 Randy Smith (randy at hobbes.ai.mit.edu)
+
+ * valprint.c (val_print): Changed assignment of pretty to use
+ prettyprint as a conditional rather than rely on values of the
+ enum.
+
+ * Projects: Cleaned up a little for release.
+
+ * main.c (initialize_main): Initialize
+ rl_completion_entry_function instead of completion_entry_function.
+
+ * Makefile: Modified to use the new readline library setup.
+
+ * breakpoint.c (break_command_1, delete_breakpoint,
+ enable_breakpoint, disable_breakpoint): Put in new printouts for
+ xgdb usage triggered off of xgdb_verbose.
+ * main.c (main): Added check for flag to set xgdb_verbose.
+ * stack.c (frame_command): Set frame_changed when frame command
+ used.
+
+Fri Jul 7 16:20:58 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * Remove valprint.h and move contents to value.h (more logical).
+
+Fri Jul 7 02:28:06 1989 Randall Smith (randy at rice-chex)
+
+ * m68k-pinsn.c (print_insn): Included a check for register list;
+ if there is one, make sure to start p after it.
+
+ * breakpoint.c (break_command_1, delete_breakpoint,
+ enable_breakpoint, disable_breakpoint): #ifdef'd out changes
+ below; they produce unwanted output in gdb mode in gnu-emacs.
+
+ * gdb.texinfo: Spelled. Also removed index references from
+ command editing section; the relevance/volume ratio was too low.
+ Removed all references to the function index.
+
+ * ns32k-opcode.h, ns32k-pinsn.c: Backed out changes of June 24th;
+ haven't yet received legal papers.
+
+ * .gdbinit: Included message telling the user what it is doing.
+
+ * symmetry-dep.c: Added static decls for i386_get_frame_setup,
+ i386_follow_jump.
+ * values.c (unpack_double): Added a return (double)0 at the end to
+ silence a compiler warning.
+
+ * printcmd.c (containing_function_bounds, asdump_command): Created
+ to dump the assembly code of a function (support for xgdb and a
+ useful hack).
+ (_initialize_printcmd): Added this to command list.
+ * gdb.texinfo [Memory]: Added documentation for the asdump
+ command.
+ * breakpoint.c (break_command_1, delete_breakpoint,
+ enable_breakpoint, disable_breakpoint): Added extra verbosity for
+ xgdb conditionalized on the new external frame_full_file_name.
+ * source.c (identify_source_line): Increase verbosity of fullname
+ prointout to include pc value.
+ * stack.c: Added a new variable; "frame_changed" to indicate when
+ a frame has been changed so that gdb can print out a frame change
+ message when the frame only changes implicitly.
+ (print_frame_info): Check the new variable in determining when to
+ print out a new message and set it to zero when done.
+ (up_command): Increment it.
+ (down_command): Decrement it.
+
+ * m68k-pinsn.c (print_insn_arg [lL]): Modified cases for register
+ lists to reset the point to point to after the word from which the
+ list is grabbed *if* that would cause point to point farther than
+ it currently is.
+
+Thu Jul 6 14:28:11 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * valprint.c (val_print, value_print): Add parameter to control
+ prettyprinting.
+ valprint.h: New file containing constants used for passing
+ prettyprinting parameter to val{,ue}_print.
+ expprint.c, infcmd.c, printcmd.c, valprint.c, values.c:
+ Change all calls to val{,ue}_print to use new parameter.
+
+Mon Jul 3 22:38:11 1989 Randy Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (,process_one_symbol): Moved extern declaration for
+ index out of function to beginning of file.
+
+Mon Jul 3 18:40:14 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * gdb.texinfo (Registers): Add "ps" to list of standard registers.
+
+Sun Jul 2 23:13:03 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * printcmd.c (enable_display): Change d->next to d = d->next so
+ that "enable display" without args works.
+
+Fri Jun 30 23:42:04 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * source.c (list_command): Made error message given when no
+ symtab is loaded clearer.
+
+ * valops.c (value_assign): Make it so that when assigning to an
+ internal variable, the type of the assignment exp is the type of
+ the value being assigned.
+
+Fri Jun 30 12:12:43 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * main.c (verbose_info): Created.
+ (initialize_main): Put "info verbose" into command list.
+
+ * utils.c (screensize_info): Created.
+ (_initialize_utils): Defined "info screensize" as a normal command.
+
+ * valprint.c (format_info): Added information about maximum number
+ of array elements to function.
+
+ * blockframe.c (find_pc_partial_function): Again.
+
+ * blockframe.c (find_pc_partial_function): Replaced a "shouldn't
+ happen" (which does) with a zero return.
+
+ * main.c (dont_repeat): Moved ahead of first use.
+
+Thu Jun 29 19:15:08 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * vax-opcode.h: Made minor modifications (moved an instruction and
+ removed a typo) to bring this into accord with gas' table; also
+ changed copyright to reflect it being part of both gdb and gas.
+
+ * m68k-opcode.h: Added whole scads and bunches of new stuff for
+ the m68851 and changed the coptyrightto recognize that the file
+ was shared between gdb and gas.
+
+ * main.c (stop_sig): Use "dont_repeat ()" instead of *line = 0;
+
+ * core.c (read_memory): Don't do anything if length is 0.
+
+ * Makefile: Added readline.c to the list of files screwed by
+ having the ansi ioctl.h compilation with gcc.
+
+ * config.gdb: Added sun4os3 & sun4-os3 as availible options.
+
+Wed Jun 28 02:01:26 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
+
+ * command.c (lookup_cmd): Add ignore_help_classes argument.
+ (lookup_cmd_1): Add ignore_help_classes argument.
+ command.c, main.c: Change callers of lookup_cmd{,_1} to supply
+ value for ignore_help_classes.
+
+Tue Jun 27 18:01:31 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * utils.c (print_spaces_filtered): Made more efficient.
+ * defs.h: Declaration.
+ * valprint.c (val_print): Used in a couple of new places.
+
+Mon Jun 26 18:27:28 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * m68k-pinsn.c (print_insn_arg ['#', '^']): Combined them into one
+ case which always gets the argument from the word immediately
+ following the instruction.
+ (print_insn_arg ["[lL]w"]): Make sure to always get the register
+ mask from the word immediately following the instruction.
+
+Sun Jun 25 19:14:56 1989 Randall Smith (randy at galapas.ai.mit.edu)
+
+ * Makefile: Added hp-include back in as something to distribute.
+
+ * stack.c (print_block_frame_locals): Return value changed from
+ void to int; return 1 if values printed. Use _filtered.
+ (print_frame_local_vars): Use return value from
+ print_block_frame_locals to mention if nothing printed; mention
+ lack of symbol table, use _filtered.
+ (print_frame_arg_vars): Tell the user if no symbol table
+ or no values printed. Use fprintf_filtered instead of fprintf.
+ * blockframe.c (get_prev_frame_info): Check for no inferior or
+ core file before crashing.
+
+ * inflow.c (inferior_died): Set current frame to zero to keep from
+ looking like we're in start.
+
+Sat Jun 24 15:50:53 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * stack.c (frame_command): Added a check to make sure that there
+ was an inferior or a core file.
+
+ * expread.y (yylex): Allow floating point numbers of the form ".5"
+ to be parsed.
+
+ Changes by David Taylor at TMC:
+ * ns32k-pinsn.c: Added define for ?floating point coprocessor? and
+ tables for register names to be used for each of the possibilities.
+ (list_search): Created; searches a list of options for a specific
+ value.
+ (print_insn_arg): Added 'Q', 'b', 'M', 'P', 'g', and 'G' options
+ to the value location switch.
+ * ns32k-opcode.h: Added several new location flags.
+ [addr, enter, exit, ext[bwd], exts[bwd], lmr, lpr[bwd], restore,
+ rett, spr[bwd], smr]: Improved insn format output.
+
+ * symtab.c (list_symbols): Rearrange printing to produce readable
+ output for "info types".
+
+ * eval.c (evaluate_subexp_for_address): Fixed typo.
+
+ * dbxread.c (read_type): Don't output an error message when
+ there isn't a ',' after a cross-reference.
+
+ * dbxread.c (read_dbx_symtab): #if'd out N_FN case in
+ read_dbx_symtab if it has the EXT bit set (otherwise multiple
+ cases with the same value).
+
+Fri Jun 23 13:12:08 1989 Randall Smith (randy at plantaris.ai.mit.edu)
+
+ * symmisc.c: Changed decl of print_spaces from static to extern
+ (since it's defined in utils.c).
+
+ * remote.c (remote_open): Close remote_desc if it's already been
+ opened.
+
+ * Remote_Makefile, remote_gutils.c, remote_inflow.c,
+ remote_server.c, remote_utils.c: Combined into remote-multi.shar.
+ * remote-multi.shar: Created (Vikram Koka's remote stub).
+ * remote-sa.m68k.shar: Created (Glenn Engel's remcom.c).
+ * README: Updated to reflect new organization of remote stubs.
+
+ * dbxread.c (read_dbx_symtab): Put an N_FN in with N_FN | N_EXT to
+ account for those machines which don't use the external bit here.
+ Sigh.
+
+ * m-symmetry.h: Defined NO_SIGINTERRUPT.
+
+Thu Jun 22 12:51:37 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * printcmd.c (decode_format): Make sure characters are printed
+ using a byte size.
+
+ * utils.c (error): Added a terminal_ours here.
+
+ * stack.c (locals_info): Added check for selected frame.
+
+ * dbxread.c (read_type): Checked to make sure that a "," was
+ actually found in the symbol to end a cross reference.
+
+Wed Jun 21 10:30:01 1989 Randy Smith (randy at tartarus.uchicago.edu)
+
+ * expread.y (parse_number, [exp]): Allowed for the return of a
+ number marked as unsigned; this will allow inclusion of unsigned
+ constants.
+
+ * symtab.h: Put in default definitions for BUILTIN_TYPE_LONGEST
+ and BUILTIN_TYPE_UNSIGNED_LONGEST.
+
+ * expread.y (parse_number): Will now accept integers suffixed with
+ a 'u' (though does nothing special with it).
+
+ * valarith.c (value_binop): Added cases to deal with unsigned
+ arithmetic correctly.
+
+Tue Jun 20 14:25:54 1989 Randy Smith (randy at tartarus.uchicago.edu)
+
+ * dbxread.c (psymtab_to_symtab_1): Changed reading in info message
+ to go through printf_filtered.
+
+ * symtab.c (list_symbols): Placed header message after all calls
+ to psymtab_to_symtab.
+
+ * symtab.c (smash_to_{function, reference, pointer}_type): Carried
+ attribute of permanence for the type being smashed over the bzero
+ and allowed any type to point at this one if it is permanent.
+
+ * symtab.c (smash_to_{function, reference, pointer}_type): Fix
+ typo: check flags of to_type instead of type.
+
+ * m-hp9k320.h: Changed check on __GNU__ predefine to __GNUC__.
+
+ * Makefile: Made MUNCH_DEFINE seperate and based on SYSV_DEFINE;
+ they aren't the same on hp's.
+
+Mon Jun 19 17:10:16 1989 Randy Smith (randy at tartarus.uchicago.edu)
+
+ * Makefile: Fixed typo.
+
+ * valops.c (call_function): Error if the inferior has not been
+ started.
+
+ * ns32k-opcode.h [check[wc], cmpm[bwd], movm[bwd], skpsb]: Fixed
+ typos.
+
+Fri Jun 9 16:23:04 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * m-news.h [NO_SIGINTERRUPT]: Defined.
+
+ * dbxread.c (read_type): Start copy of undefined structure name
+ past [sue] defining type of cross ref.
+
+ * dbxread.c (process_one_symbol): Changed strchr to index.
+
+ * ns32k-opcode.h, ns32k-pinsn.c: More changes to number of
+ operands, addition of all of the set condition opcodes, addition
+ of several flag letters, all patterned after the gas code.
+
+ * ns32k-opcode.h [mov{su,us}[bwd], or[bwd]]: Changed number of
+ operands from 1 to 2.
+
+Wed Jun 7 15:04:24 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * symseg.h [TYPE_FLAG_STUB]: Created.
+ * dbxread.c (read_type): Set flag bit if type is stub.
+ (cleanup_undefined_types): Don't mark it as a stub if it's been
+ defined since we first learned about it.
+ * valprint.c (val_print): Print out a message to that effect if
+ this type is encountered.
+
+ * symseg.h, symtab.h: Moved the definition of TYPE_FLAG_PERM over
+ to symseg.h so that all such definitions would be in the same place.
+
+ * valprint.c (val_print): Print out <No data fields> for a
+ structure if there aren't any.
+
+ * dbxread.c (read_type): Set type name of a cross reference type
+ to "struct whatever" or something.
+
+Tue Jun 6 19:40:52 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * breakpoint.c (breakpoint_1): Print out symbolic location of
+ breakpoints for which there are no debugging symbols.
+
+Mon Jun 5 15:14:51 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * command.c (help_cmd_list): Made line_size static.
+
+Sat Jun 3 17:33:45 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * Makefile: Don't include the binutils hp-include directory in the
+ distribution anymore; refer the users to the binutils distribution.
+
+Thu Jun 1 16:33:07 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * printcmd.c (disable_display_command): Fixed loop iteration for
+ no arg case.
+
+ * printcmd.c (disable_display_command): Added from_tty parameter
+ to function.
+
+ * valops.c (value_of_variable): Call read_var_value with 0 cast to
+ FRAME instead of CORE_ADDR.
+
+ * eval.c (evaluate_subexp): Corrected number of args passed to
+ value_subscript (to 2).
+
+ * infrun.c (wait_for_inferior), symtab.c (decode_line_1),
+ m-convex.h: Changed name of FIRSTLINE_DEBUG_BROKEN to
+ PROLOGUE_FIRSTLINE_OVERLAP.
+
+ * m-merlin.h: Fixed typo.
+ * ns32k-opcode.h: Added ns32381 opcodes and "cinv" insn, and fixed
+ errors in movm[wd], rett, and sfsr.
+
+ * eval.c (evaluate_subexp, evaluate_subexp_for_address), valops.c
+ (value_zero): Change value_zero over to taking two arguments
+ instead of three.
+
+ * eval.c (evaluate_subexp)
+ [OP_VAR_VALUE]: Get correct lval type for AVOID_SIDE_EFFECTS for
+ all types of symbols.
+ [BINOP_DIV]: Don't divide if avoiding side effects; just return
+ an object of the correct type.
+ [BINOP_REPEAT]: Don't call value_repeat, just allocate a
+ repeated value.
+ (evaluete_subexp_for_address) [OP_VAR_VALUE]: Just return a thing
+ of the right type (after checking to make sure that we are allowed
+ to take the address of whatever variable has been passed).
+
+Mon May 29 11:01:02 1989 Randall Smith (randy at galapas.ai.mit.edu)
+
+ * breakpoint.c (until_break_command): Set the breakpoint with a
+ frame specification so that it won't trip in inferior calls to the
+ function. Also set things up so that it works based on selected
+ frame, not current one.
+
+Sun May 28 15:05:33 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * eval.c (evalue_subexp): Change subscript case to use value_zero
+ in EVAL_AVOID_SIDE_EFFECTS case.
+
+Fri May 26 12:03:56 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (read_addl_syms, psymtab_to_symtab): Removed
+ cleanup_undefined_types; this needs to be done on a symtab basis.
+ (end_symtab): Called cleanup_undefined_types from here.
+ (cleanup_undefined_types): No longer uses lookup_symbol (brain
+ dead idea; oh, well), now it searches through file_symbols.
+
+Wed May 24 15:52:43 1989 Randall Smith (randy at galapas)
+
+ * source.c (select_source_symtab): Only run through
+ partial_symtab_list if it exists.
+
+ * coffread.c (read_coff_symtab): Don't unrecord a misc function
+ when a function symbol is seen for it.
+
+ * expread.y [variable]: Make sure to write a type for memvals if
+ you don't get a mft you recognize.
+
+Tue May 23 12:15:57 1989 Randall Smith (randy at plantaris.ai.mit.edu)
+
+ * dbxread.c (read_ofile_symtab, psymtab_to_symtab): Moved cleanup
+ of undefined types to psymtab_to_symtab. That way it will be
+ called once for all readins (which will, among other things,
+ help reduce infinite loops).
+
+ * symtab.h [misc_function_type]: Forced mf_unknown to 0.
+ * dbxread.c (record_misc_function): Cast enum to unsigned char (to
+ fit).
+ * expread.y [variable]: Cast unsigned char back to enum to test.
+
+Mon May 22 13:08:25 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ Patches by John Gilmore for dealing well with floating point:
+ * findvar.c (value_from_register, locate_var_value): Used
+ BYTES_BIG_ENDIAN instead of an inline test.
+ * m-sparc.h [IEEE_FLOAT]: Created to indicate that the sparc is
+ IEEE compatible.
+ * printcmd.c (print_scalar_formatted): Use BYTES_BIG_ENDIAN and
+ the stream argument for printing; also modify default type for
+ 'f'. Change handling of invalid floats; changed call syntax for
+ is_nan.
+ (print_command): Don't print out anything indicating that
+ something was recorded on the history list if it wasn't.
+ * valprint.c (val_print): Fixed to deal properley with new format
+ of is_nan and unpacking doubles without errors occuring.
+ (is_nan): Changed argument list and how it figures big endianness
+ (uses macros).
+ * values.c (record_latest_value): Return -1 and don't record if
+ it's an invalid float.
+ (value_as_double): Changed to use new unpack_double calling
+ convention.
+ (unpack_double): Changed not to call error if the float was
+ invalid; simply to set invp and return. Changed calling syntax.
+ (unpack_field_as_long, modify_field): Changed to use
+ BITS_BIG_ENDIAN to determine correct action.
+
+ * m-hp9k320.h [HP_OS_BUG]: Created; deals with problem where a
+ trap happens after a continue.
+ * infrun.c (wait_for_inferior): Used.
+
+ * m-convex.h [FIRSTLINE_DEBUG_BROKEN]: Defined a flag to indicate
+ that the debugging symbols output by the compiler for the first
+ line of a function were broken.
+ * infrun.c (wait_for_inferior), symtab.c (decode_line_1): Used.
+
+ * gdb.texinfo [Data, Memory]: Minor cleanups of phrasing.
+
+Fri May 19 00:16:59 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (add_undefined_type, cleanup_undefined_types): Created
+ to keep a list of cross references to as yet undefined types.
+ (read_type): Call add_undefined_type when we run into such a case.
+ (read_addl_syms, read_ofile_symtab): Call cleanup_undefined_types
+ when we're done.
+
+ * dbxread.c (psymtab_to_symtab, psymtab_to_symtab_1): Broke
+ psymtab_to_symtab out into two routines; made sure the string
+ table was only readin once and the globals were only scanned once,
+ for any number of dependencies.
+
+Thu May 18 19:59:18 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * m-*.h: Defined (or not, as appropriate per machine)
+ BITS_BIG_ENDIAN, BYTES_BIG_ENDIAN, and WORDS_BIG_ENDIAN.
+
+Wed May 17 13:37:45 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * main.c (symbol_completion_function): Always complete on result
+ command list, even if exact match found. If it's really an exact
+ match, it'll find it again; if there's something longer than it,
+ it'll get the right result.
+
+ * symtab.c (make_symbol_completion_function): Fixed typo; strcmp
+ ==> strncmp.
+
+ * dbxread.c (read_dbx_symtab): Change 'G' case to mark symbols as
+ LOC_EXTERNAL.
+
+ * expread.y [variables]: Changed default type of text symbols to
+ function returning int so that one can use, eg. strcmp.
+
+ * infrun.c (wait_for_inferior): Include a special flag indicating
+ that one shouldn't insert the breakpoints on the next step for
+ returning from a sigtramp and forcing at least one move forward.
+
+ * infrun.c (wait_for_inferior): Change test for nexting into a
+ function to check for current stack pointer inner than previous
+ stack pointer.
+
+ * infrun.c (wait_for_inferior): Check for step resume break
+ address before dealing with normal breakpoints.
+
+ * infrun.c (wait_for_inferior): Added a case to deal with taking
+ and passing along a signal when single stepping past breakpoints
+ before inserting breakpoints.
+
+ * infrun.c (wait_for_inferior): Inserted special case to keep
+ going after taking a signal we are supposed to be taking.
+
+Tue May 16 12:49:55 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * inflow.c (terminal_ours_1): Cast result of signal to (int
+ (*)()).
+
+ * gdb.texinfo: Made sure that references to the program were in
+ upper case. Modify description of the "set prompt" command.
+ [Running]: Cleaned up introduction.
+ [Attach]: Cleaned up.
+ [Stepping]: Change "Proceed" to "Continue running" or "Execute".
+ Minor cleanup.
+ [Source Path]: Cleaned up intro. Cleared up distinction between
+ the executable search path and the source path. Restated effect
+ of the "directory" command with no arguments.
+ [Data]: Fixed typos and trivial details.
+ [Stepping]: Fixed up explanation of "until".
+
+ * source.c (print_source_lines): Print through filter.
+
+ * printcmd.c (x_command): If the format with which to print is
+ "i", use the address of anything that isn't a pointer instead of
+ the value. This is for, eg. "x/10i main".
+
+ * gdb.texinfo: Updated last modification date on manual.
+
+Mon May 15 12:11:33 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * symtab.c (lookup_symtab): Fixed typo (name ==> copy) in call to
+ lookup_symtab_1.
+
+ * gdb.texinfo: Added documentation for "break [+-]n" and for new
+ actions of "directory" command (taking multiple directory names at
+ the same time).
+
+ * m68k-opcode.h: Replaced the version in gdb with an up-to-date
+ version from the assembler directory.
+ * m68k-pinsn.c (print_insn_arg): Added cases 'l' & 'L' to switch
+ to print register lists for movem instructions.
+
+ * dbxread.c, m-convex.h: Moved convex dependent include files over
+ from dbxread.c to m-convex.h.
+
+ * printcmd.c (disable_display, disable_display_command): Changed
+ name of first to second, and created first which takes an int as
+ arg rather than a char pointer. Changed second to use first.
+ (_initialize_printcmd): Changed to use second as command to call.
+ (delete_current_display, disable_current_display): Changed name of
+ first to second, and changed functionality to match.
+ * infrun.c (normal_stop), main.c (return_to_top_level): Changed to
+ call disable_current_display.
+
+ * dbxread.c (process_one_symbol, read_dbx_symtab): Changed N_FN to
+ be N_FN | N_EXT to deal with new Berkeley define; this works with
+ either the old or the new.
+
+ * Remote_Makefile, remote_gutils.c, remote_inflow.c,
+ remote_server.c, remote_utils.c: Created.
+ * Makefile: Included in tag and tar files.
+ * README: Included a note about them.
+
+ * printcmd.c (print_address): Use find_pc_partial_function to
+ remove need to readin symtabs for symbolic addresses.
+
+ * source.c (directory_command): Replaced function with new one
+ that can accept lists of directories seperated by spaces or :'s.
+
+ * inflow.c (new_tty): Replaced calls to dup2 with calls to dup.
+
+Sun May 14 12:33:16 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * stack.c (args_info): Make sure that you have an inferior or core
+ file before taking action.
+
+ * ns32k-opcode.h [deiw, deid]: Fixed machine code values for these
+ opcodes.
+
+ * dbxread.c (scan_file_globals): Modified to use misc function
+ vector instead of file itself. Killed all arguments to the
+ funciton; no longer needed.
+ (psymtab_to_symtab): Changed call for above to reflect new (void)
+ argument list.
+
+ * dbxread.c (read_dbx_symtab, ): Moved HASH_OFFSET define out of
+ read_dbx_symtab.
+
+ * expread.y [variable]: Changed default type of misc function in
+ text space to be (void ()).
+
+ * Makefile: Modified for proper number of s/r conflicts (order is
+ confusing; the mod that necessitated this change was on May 12th,
+ not today).
+
+ * expread.y (yylex): Added SIGNED, LONG, SHORT, and INT keywords.
+ [typename]: Created.
+ [typebase]: Added rules for LONG, LONG INT, SHORT, SHORT INT,
+ SIGNED name, and UNSIGNED name (a good approximation of ansi
+ standard).
+
+ * Makefile: Included .c.o rule to avoid sun's make from throwing
+ any curves at us.
+
+ * blockframe.c: Included <obstack.h>
+
+ * command.c (lookup_cmd): Clear out trailing whitespace.
+
+ * command.c (lookup_cmd_1): Changed malloc to alloca.
+
+Fri May 12 12:13:12 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * printcmd.c (print_frame_args): Only print nameless args when you
+ know how many args there are supposed to be and when you've
+ printed fewer than them. Don't print nameless args between
+ printed args.
+
+ * symtab.c (make_symbol_completion_function): Fixed typo (= ==>
+ ==).
+
+ * remote.c (remote_open): ifdef'd out siginterrupt call by #ifndef
+ NO_SIGINTERRUPT.
+ * m-umax.h: Defined NO_SIGINTERRUPT.
+
+ * expread.y [ptype, array_mod, func_mod, direct_abs_decl,
+ abs_decl]: Added rules for parsing and creating arbitrarily
+ strange types for casts and sizeofs.
+
+ * symtab.c, symtab.h (create_array_type): Created. Some minor
+ misfeatures; see comments for details (main one being that you
+ might end up creating two arrays when you only needed one).
+
+Thu May 11 13:11:49 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * valops.c (value_zero): Add an argument for type of lval.
+ * eval.c (evaluate_subexp_for_address): Take address properly in
+ the avoid side affects case (ie. keep track of whether we have an
+ lval in memory and we can take the address).
+ (evaluate_subexp): Set the lval type of expressions created with
+ value_zero properley.
+
+ * valops.c, value.h (value_zero): Created--will return a value of
+ any type with contents filled with zero.
+ * symtab.c, symtab.h (lookup_struct_elt_type): Created.
+ * eval.c (evaluate_subexp): Modified to not read memory when
+ called with EVAL_AVOID_SIDE_EFFECTS.
+
+ * Makefile: Moved dbxread.c ahead of coffread.c in the list of
+ source files.
+
+Wed May 10 11:29:19 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * munch: Make sure that sysv version substitutes for the whole
+ line.
+
+ * symtab.h: Created an enum misc_function_type to hold the type of
+ the misc function being recorded.
+ * dbxread.c (record_misc_function): Branched on dbx symbols to
+ decide which type to assign to a misc function.
+ * coffread.c (record_misc_function): Always assign type unknown.
+ * expread.y [variable]: Now tests based on new values.
+
+Tue May 9 13:03:54 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * symtab.c: Changed inclusion of <strings.h> (doesn't work on
+ SYSV) to declaration of index.
+
+ * Makefile: Changed last couple of READLINE_FLAGS SYSV_DEFINE
+
+ * source.c ({forward, reverse}_search_command): Made a default
+ search file similar to for the list command.
+
+Mon May 8 18:07:51 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * printcmd.c (print_frame_args): If we don't know how many
+ arguments there are to this function, don't print the nameless
+ arguments. We don't know enough to find them.
+
+ * printcmd.c (print_frame_args): Call print_frame_nameless_args
+ with proper arguments (start & end as offsets from addr).
+
+ * dbxread.c (read_addl_syms): Removed cases to deal with global
+ symbols; this should all be done in scan_global_symbols.
+
+Sun May 7 11:36:23 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * Makefile: Added copying.awk to ${OTHERS}.
+
+Fri May 5 16:49:01 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * valprint.c (type_print_varspec_prefix): Don't pass
+ passed_a_pointer onto children.
+
+ * valprint.c (type_print_varspec_suffix): Print "array of" with
+ whatever the "of" is after tha array brackets.
+
+ * valprint.c (type_print_varspec_{prefix,suffix}): Arrange to
+ parenthesisze pointers to arrays as well as pointers to other
+ objects.
+
+ * valprint.c (type_print_varspec_suffix): Make sure to print
+ subscripts of multi-dimensional arrays in the right order.
+
+ * infcmd.c (run_command): Fixed improper usages of variables
+ within remote debugging branch.
+
+ * Makefile: Added Convex.notes to the list of extra files to carry
+ around.
+
+ * dbxread.c (symbol_file_command): Made use of alloca or malloc
+ dependent on macro define.
+
+Thu May 4 15:47:04 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * Makefile: Changed READLINE_FLAGS to SYSV_DEFINE and called munch
+ with it also.
+ * munch: Check first argument for -DSYSV and be looser about
+ picking up init routines if you find it.
+
+ * coffread.c: Made fclose be of type int.
+
+ * breakpoint.c (_initialize_breakpoint): Put "unset" into class
+ alias.
+
+Wed May 3 14:09:12 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * m-sparc.h [STACK_END_ADDR]: Parameterized off of
+ machine/vmparam.h (as per John Gilmore's suggestion).
+
+ * blockframe.c (get_prev_frame_info): Changed this function back
+ to checking frameless invocation first before checking frame
+ chain. This means that a backtrace up from start will produce the
+ wrong value, but that a backtrace from a frameless function called
+ in main will show up correctly.
+
+ * breakpoint.c (_initialize_breakpoint): Added entry in help for
+ delete that indicates that unset is an alias for it.
+
+ * main.c (symbol_completion_function): Modified recognition of
+ being within a single command.
+
+Tue May 2 15:13:45 1989 Randy Smith (randy at gnu)
+
+ * expread.y [variable]: Add some parens to get checking of the
+ misc function vector right.
+
+Mon May 1 13:07:03 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * default-dep.c (core_file_command): Made reg_offset unsigned.
+
+ * default-dep.c (core_file_command): Improved error messages for
+ reading in registers.
+
+ * expread.y: Allowed a BLOCKNAME to be ok for a variable name (as
+ per C syntax).
+
+ * dbxread.c (psymtab_to_symtab): Flushed stdout after printing
+ starting message about reading in symbols.
+
+ * printcmd.c (print_frame_args): Switched starting place for
+ printing of frameless args to be sizeof int above last real arg
+ printed.
+
+ * printcmd.c (print_frame_args): Modified final call to
+ print_nameless_args to not use frame slots used array if none had
+ been used.
+
+ * infrun.c (wait_for_inferior): Take FUNCTION_START_OFFSET into
+ account when dealing with comparison of pc values to function
+ addresses.
+
+ * Makefile: Added note about compiling gdb on a Vax running 4.3.
+
+Sun Apr 30 12:59:46 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * command.c (lookup_cmd): Got correct error message on bad
+ command.
+
+ * m-sun3.h [ABOUT_TO_RETURN]: Modified to allow any of the return
+ instructions, including trapv and return from interupt.
+
+ * command.c (lookup_cmd): If a command is found, use it's values
+ for error reporting and determination of needed subcommands.
+
+ * command.c (lookup_cmd): Use null string for error if cmdtype is
+ null; pass *line to error instead of **.
+
+ * command.c (lookup_cmd_1): End of command marked by anything but
+ alpha numeric or '-'. Included ctype.h.
+
+Fri Apr 28 18:30:49 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * source.c (select_source_symtab): Kept line number from ever
+ being less than 1 in main decode.
+
+Wed Apr 26 13:03:20 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * default-dep.c (core_file_command): Fixed typo.
+
+ * utils.c (fprintf_filtered): Don't use return value from
+ numchars.
+
+ * main.c, command.c (complete_on_cmdlist): Moved function to
+ command.c.
+
+ * command.c (lookup_cmd): Modified to use my new routine. Old
+ version is still there, ifdef'd out.
+
+ * command.c, command.h (lookup_cmd_1): Added a routine to do all
+ of the work of lookup_cmd with no error reporting and full return
+ of information garnered in search.
+
+Tue Apr 25 12:37:54 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * breakpoint.c (_initialize_breakpoint): Change "delete
+ breakpionts" to be in class alias and not have the abbrev flag
+ set.
+
+ * main.c (symbol_completion_function): Fix to correctly complete
+ things that correspond to multiword aliases.
+
+ * main.c (complete_on_cmdlist): Don't complete on something if it
+ isn't a command or prefix (ie. if it's just a help topic).
+
+ * main.c (symbol_completion_function): Set list index to be 0 if
+ creating a list with just one element.
+
+ * main.c (complete_on_cmdlist): Don't allow things with
+ abbrev_flag set to be completion values.
+ (symbol_completion_function): Don't accept an exact match if the
+ abbrev flag is set.
+
+ * dbxread.c (read_type): Fixed typo in comparision to check if
+ type number existed.
+
+ * dbxread.c (read_type): Made sure to only call dbx_lookup_type on
+ typenums if typenums were not -1.
+
+Mon Apr 24 17:52:12 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * symtab.c: Added strings.h as an include file.
+
+Fri Apr 21 15:28:38 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * symtab.c (lookup_partial_symtab): Changed to only return a match
+ if the name match is exact (which is what I want in all cases in
+ which this is currently used.
+
+Thu Apr 20 11:12:34 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * m-isi.h [REGISTER_U_ADDR]: Installed new version from net.
+ * default-dep.c: Deleted inclusion of fcntl.h; apparently not
+ necessary.
+ * Makefile: Added comment about compiling on isi under 4.3.
+
+ * breakpoint.c (break_command_1): Only give decode_line_1 the
+ default_breakpoint_defaults if there's nothing better (ie. make
+ the default be off of the current_source notes if at all
+ possible).
+
+ * blockframe.c (get_prev_frame_info): Clean up comments and
+ delete code ifdefed out around FRAMELESS_FUNCTION_INVOCATION test.
+
+ * remote.c: Added a "?" message to protocol.
+ (remote_open): Used at startup.
+ (putpkt): Read whatever garbage comes over the line until we see a
+ '+' (ie. don't treat garbage as a timeout).
+
+ * valops.c (call_function): Eliminated no longer appropriate
+ comment.
+
+ * infrun.c (wait_for_inferior): Changed several convex conditional
+ compilations to be conditional on CANNOT_EXECUTE_STACK.
+
+Wed Apr 19 10:18:17 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * printcmd.c (print_frame_args): Added code to attempt to deal
+ with arguments that are bigger than an int.
+
+ Continuation of Convex/Fortran changes:
+ * printcmd.c (print_scalar_formatted): Added leading zeros to
+ printing of large integers.
+ (address_info, print_frame_args): Added code to deal with
+ LOC_REF_ARG.
+ (print_nameless_args): Allow param file to specify a routine with
+ which to print typeless integers.
+ (printf_command): Deal with long long values well.
+ * stack.c (print_frame_arg_vars): Change to deal with LOC_REF_ARG.
+ * symmisc.c (print_symbol): Change to deal with LOC_REF_ARG.
+ * symseg.h: Added LOC_REF_ARG to enum address_class.
+ * symtab.c (lookup_block_symbol): Changed to deal with
+ LOC_REF_ARG.
+ * valarith.c (value_subscripted_rvalue): Created.
+ (value_subscript): Used above when app.
+ (value_less, value_equal): Change to cast to (char *) before doing
+ comparison, for machines where that casting does something.
+ * valops.c (call_function): Setup to deal with machines where you
+ cannot execute code on the stack segment.
+ * valprint.c (val_print): Make sure that array element size isn't
+ zero before printing. Set address of default array to address of
+ first element. Put in a couple of int cast. Removed some convex
+ specific code. Added check for endianness of machine in case of a
+ packed structure. Added code for printing typeless integers and
+ for LONG LONG's.
+ (set_maximum_command): Change to use parse_and_eval_address to get
+ argument (so can use expressions there).
+ * values.c (value_of_internalvar, set_internalvar_component,
+ set_internalvar, convenience_info): Add in hooks for trapped
+ internal vars.
+ (unpack_long): Deal with LONG_LONG.
+ (value_field): Remove LONGEST cast.
+ (using_struct_return): Fixed typo ENUM ==> UNION.
+ * xgdb.c (_initialize_xgdb): Make sure that specify_exec_file_hook
+ is not called unless we are setting up a windowing environ.
+
+Tue Apr 18 13:43:37 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ Various changes involved in 1) getting gdb to work on the convex,
+ and 2) Getting gdb to work with fortran (due to convex!csmith):
+ * convex-dep.c, convex-opcode.h, m-convex.h, convex-pinsn.c:
+ Created (or replaced with new files).
+ * Makefile: Add convex dependent files. Changed default flags to
+ gnu malloc to be CFLAGS.
+ * config.gdb: Added convex to list of machines.
+ * core.c (files_info): Added a FILES_INFO_HOOK to be used if
+ defined.
+ (xfer_core_file): Conditionalized compilation of xfer_core_file on
+ the macro XFER_CORE_FILE.
+ * coffread.c (record_misc_function): Made sure it zerod type field
+ (which is now being used; see next).
+ * dbxread.c: Included some convex dependent include files.
+ (copy_pending, fix_common_blocks): Created.
+ [STAB_REG_REGNUM, BELIEVE_PCC_PROMOTION]: Created default values;
+ may be overridden in m-*.h.
+ Included data structures for keeping track of common blocks.
+ (dbx_alloc_type): Modified; if called with negative 1's will
+ create a type without putting it into the type vector.
+ (read_dbx_symtab, read_addl_syms): Modified calls to
+ record_misc_function to include the new information.
+ (symbol_file_command, psymtab_to_symtab, add_file_command):
+ Modified reading in of string table to adapt to machines which
+ *don't* store the size of the string table in the first four bytes
+ of the string table.
+ (read_dbx_symtab, scan_file_globals, read_ofile_symtab,
+ read_addl_syms): Modified assignment of namestring to accept null
+ index into symtab as ok.
+ (read_addl_syms): Modified readin of a new object file to fiddle
+ with common blocks correctly.
+ (process_one_symbol): Fixed incorrect comment about convex. Get
+ symbols local to a lexical context from correct spot on a per
+ machine basis. Catch a bug in pcc which occaisionally puts an SO
+ where there should be an SOL. Seperate sections for N_BCOMM &
+ N_ECOMM.
+ (define_symbol): Ignore symbols with no ":". Use
+ STAB_REG_TO_REGNUM. Added support for function args calling by
+ reference.
+ (read_type): Only read type number if one is there. Remove old
+ (#if 0'd out) array code.
+ (read_array_type): Added code for dealing with adjustable (by
+ parameter) arrays half-heartedly.
+ (read_enum_type): Allow a ',' to end a list of values.
+ (read_range_type): Added code to check for long long.
+ * expread.y: Modified to use LONGEST instead of long where
+ necessary. Modified to use a default type of int for objects that
+ weren't in text space.
+ * findvar.c (locate_var_value, read_var_value): Modified to deal
+ with args passed by reference.
+ * inflow.c (create_inferior): Used CREATE_INFERIOR_HOOK if it
+ exists.
+ * infrun.c (attach_program): Run terminal inferior when attaching.
+ (wait_for_inferior): Removed several convex dependencies.
+ * main.c (float_handler): Created.
+ Made whatever signal indicates a stop configurable (via macro
+ STOP_SIGNAL).
+ (main): Setup use of above as a signal handler. Added check for
+ "-nw" in args already processed.
+ (command_line_input): SIGTSTP ==>STOP_SIGNAL.
+
+ * expread.y: Added token BLOCKNAME to remove reduce/reduce
+ conflict.
+ * Makefile: Change message to reflect new grammar.
+
+Mon Apr 17 13:24:59 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * printcmd.c (compare_ints): Created.
+ (print_frame_args): Modified to always print arguments in the
+ order in which they were found in the symbol table. Figure out
+ what apots are missing on the fly.
+
+ * stack.c (up_command): Error if no inferior or core file.
+
+ * m-i386.h, m-symmetry.h [FRAMELESS_FUNCTION_INVOCATION]: Created;
+ same as m68k.
+
+ * dbxread.c (define_symbol): Changed "desc==0" test to
+ "processing_gcc_compilation", which is the correct way to do it.
+
+Sat Apr 15 17:18:38 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * expread.y: Added precedence rules for arglists, ?:, and sizeof
+ to eliminate some shift-reduce conflicts.
+ * Makefile: Modified "Expect" message to conform to new results.
+
+Thu Apr 13 12:29:26 1989 Randall Smith (randy at plantaris.ai.mit.edu)
+
+ * inflow.c (terminal_init_inferior): Fixed typo in recent diff
+ installation; TIOGETC ==> TIOCGETC.
+
+ * m-vax.h, m-sun2.h, m-sun3.h, m-sparc.h, m-hp*.h, m-isi.h,
+ m-news.h [FRAMELESS_FUNCTION_INVOCATION]: Created macro with
+ appropriate definition.
+
+Wed Apr 12 15:30:29 1989 Randall Smith (randy at plantaris.ai.mit.edu)
+
+ * blockframe.c (get_prev_frame_info): Added in a macro to specify
+ when a "frame" is called without a frame pointer being setup.
+
+ * Makefile [clean]: Made sure to delete gnu malloc if it was being
+ used.
+
+Mon Apr 10 12:43:49 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (process_one_symbol): Reset within_function to 0 after
+ last RBRAC of a function.
+
+ * dbxread.c (read_struct_type): Changed check for filling in of
+ TYPE_MAIN_VARIANT of type.
+
+ * inflow.c (create_inferior): Conditionalized fork so that it
+ would be used if USG was defined and HAVE_VFORK was not defined.
+
+ * defs.h: Added comment about enum command_class element
+ class_alias.
+
+ * dbxread.c (process_one_symbol): Fixed a typo with interesting
+ implications for associative processing in the brain (':' ==> 'c').
+
+ * sparc-dep.c (isabranch): Changed name to isannulled, modified to
+ deal with coprocessor branches, and improved comment.
+ (single_step): Changed to trap at npc + 4 instead of pc +8 on
+ annulled branches. Changed name in call to isabranch as above.
+
+ * m-sun4os4.h (STACK_END_ADDRESS): Changed it to 0xf8000000 under
+ os 4.0.
+
+Sat Apr 8 17:04:07 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (process_one_symbol): In the case N_FUN or N_FNAME the
+ value being refered to is sometimes just a text segment variable.
+ Catch this case.
+
+ * infrun.c (wait_for_inferior), breakpoint.c
+ (breakpoint_stop_status): Move the selection of the frame to
+ inside breakpoint_stop_status so that the frame only gets selected
+ (and the symbols potentially read in) if the symbols are needed.
+
+ * symtab.c (find_pc_psymbol): Fixed minor misthough (pc >=
+ fucntion start, not >).
+
+ * breakpoint.c (_initialize_breakpoint): Change "delete" internal
+ help entry to simply refer to it being a prefix command (since the
+ list of subcommands is right there on a "help delete").
+
+Fri Apr 7 15:22:18 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * blockframe.c (find_pc_partial_function): Created; figures out
+ what function pc is in (name and address) without reading in any
+ new symbols.
+ * symtab.h: Added decl for above.
+ * infrun.c (wait_for_inferior): Used instead of
+ find_pc_function_start.
+ * stack.c (print_frame_info): Used instead of hand coding for same
+ thing.
+
+ * dbxread.c (psymtab_to_symtab): No longer patch readin pst's out
+ of the partial_symtab_list; need them there for some checks.
+ * blockframe.c (block_for_pc), source.c (select_source_symtab),
+ symtab.c (lookup_symbol, find_pc_symtab, list_symbols): Made extra
+ sure not to call psymtab_to_symtab with ->readin == 1, since these
+ psymtab now stay on the list.
+ * symtab.c (sources_info): Now distinguishes between psymtabs with
+ readin set and those with it not set.
+
+ * symtab.c (lookup_symtab): Added check through partial symtabs
+ for name with .c appended.
+
+ * source.c (select_source_symtab): Changed semantics a little so
+ that the argument means something.
+ * source.c (list_command), symtab.c (decode_line_1): Changed call
+ to select_source_symtab to match new conventions.
+
+ * dbxread.c (add_file_command): This command no longer selects a
+ symbol table to list from.
+
+ * infrun.c (wait_for_inferior): Only call find_pc_function (to
+ find out if we have debugging symbols for a function and hence if
+ we should step over or into it) if we are doing a "step".
+
+Thu Apr 6 12:42:28 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * main.c (command_line_input): Added a local buffer and only
+ copied information into the global main.c buffer when it is
+ appropriate for it to be saved (and repeated).
+ (dont_repeat): Only nail line when we are reading from stdin
+ (otherwise null lines won't repeat and what's in line needs to be
+ saved).
+ (read_command_lines): Fixed typo; you don't what to repeat when
+ reading command lines from the input stream unless it's standard
+ input.
+
+ John Gilmore's (gnu@toad.com) mods for USG gdb:
+ * inflow.c: Removed inclusion of sys/user.h; no longer necessary.
+ (, terminal_init_inferior, terminal_inferior, terminal_ours_1,
+ term_status_command, _initialize_inflow) Seperated out declaration
+ and usage of terminal mode structures based on the existence of
+ the individual ioctls.
+ * utils.c (request_quit): Restore signal handler under USG. If
+ running under USG initialize sys_siglist at run time (too much
+ variation between systems).
+
+Wed Apr 5 13:47:24 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ John Gilmore's (gnu@toad.com) mods for USG gdb:
+ * default-dep.c: Moved include of sys/user.h to after include of
+ a.out.h.
+ (store_inferior_registers): Fixed error message.
+ (core_file_command): Improved error messages from reading in of
+ u area in core file. Changed calculation of offset of registers
+ to account for some machines putting it in as an offset rather
+ than an absolute address. Changed error messages for reading of
+ registers from core file.
+
+ * coffread.c (read_file_hdr): Added final check for BADMAG macro
+ to use if couldn't recognize magic number.
+ * Makefile: Added explicit directions for alloca addition.
+ Included alloca.c in list of possible library files. Cleaned up
+ possible library usage. Included additional information on gcc
+ and include files.
+
+ * source.c, remote.c, inflow.c, dbxread.c, core.c, coffread.c:
+ Changed include of sys/fcntl.h to an include of fcntl.h (as per
+ posix; presumably this will break fewer machines. I hopw).
+ * README: Added a pointer to comments at top of Makefile.
+ * Makefile: Added a comment about machines which need fcntl.h in
+ sys.
+
+Tue Apr 4 11:29:04 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * valprint.c (set_prettyprint_command, set_unionprint_command,
+ format_info): Created.
+ (_initialize_valprint): Added to lists of commands.
+
+ * gdb.texinfo [Backtrace]: Added a section describing the format
+ if symbols have not yet been read in.
+
+ * valprint.c (val_print): Added code to prettyprint structures if
+ "prettyprint" is set and only to print unions below the top level
+ if "unionprint" is set.
+
+ * infcmd.c (registers_info), valprint.c (value_print, val_print):
+ Added argument to call to val_print indicating deptch of recursion.
+
+ * symtab.[ch] (find_pc_psymbol): Created; finds static function
+ psymbol with value nearest to but under value passed.
+ * stack.c (print_frame_info): Used above to make sure I have best
+ fit to pc value.
+
+ * symseg.h (struct partial_symbol): Added value field.
+ * dbxread.c (read_dbx_symtab): Set value field for partial symbols
+ saved (so that we can lookup static symbols).
+
+ * symtab.[ch] (find_pc_symtab): Changed to external.
+ * stack.c (select_frame): Call above to make sure that symbols for
+ a selected frame is readin.
+
+Mon Apr 3 12:48:16 1989 Randall Smith (randy at plantaris.ai.mit.edu)
+
+ * stack.c (print_frame_info): Modified to only print out full
+ stack frame info on symbols whose tables have been read in.
+ * symtab.c, symtab.h (find_pc_psymtab): Made function external;
+ above needed it.
+
+ * main.c (,set_verbose_command, initialize_main): Created a
+ variable "info_verbose" which says to talk it up in various and
+ sundry places. Added command to set this variable.
+ * gdb.texinfo (GDB Output): Added documentation on "set verbose"
+ and changed the name of the "Screen Output" section to "GDB
+ Output".
+ * dbxread.c (psymtab_to_symtab): Added information message about
+ symbol readin. Conditionalized on above.
+
+ * dbxread.c (define_symbol): Made an "i" constant be of class
+ LOC_CONST and an "r" constant be of class LOC_CONST_BYTES.
+
+ * README: Made a note about modifications which may be necessary
+ to the manual for this version of gdb.
+
+ * blockframe.c (get_prev_frame_info): Now we get saved address and
+ check for validity before we check for leafism. This means that
+ we will catch the fact that we are in start, but we will miss any
+ fns that start calls without an fp. This should be fine.
+
+ * m-*.h (FRAME_CHAIN): Modified to return 0 if we are in start.
+ This is usually a test for within the first object file.
+ * m-sparc.h (FRAME_CHAIN): The test here is simply if the fp saved
+ off the the start sp is 0.
+
+ * blockframe.c (get_prev_frame_info): Removed check to see if we
+ were in start. Screws up sparc.
+
+ * m-sparc.h (FRAME_FIND_SAVED_REGISTERS): Changed test for dummy
+ frame to not need frame to be innermost.
+
+ * gdb.texinfo: Added section on frameless invocations of functions
+ and when gdb can and can't deal with this.
+
+ * stack.c (frame_info): Disallowed call if no inferior or core
+ file; fails gracefully if truely bad stack specfication has been
+ given (ie. parse_frame_specification returns 0).
+
+Fri Mar 31 13:59:33 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * infrun.c (normal_stop): Changed references to "unset-env" to
+ "delete env".
+
+ * infcmd.c (_initialize_infcmd): Change reference to set-args in
+ help run to "set args".
+
+ * remote.c (getpkt): Allow immediate quit when reading from
+ device; it could be hung.
+
+ * coffread.c (process_coff_symbol): Modify handling of REG
+ parameter symbols.
+
+Thu Mar 30 15:27:23 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (symbol_file_command): Use malloc to allocate the
+ space for the string table in symbol_file_command (and setup a
+ cleanup for this). This allows a more graceful error failure if
+ there isn't any memory availible (and probably allows more memory
+ to be avail, depending on the machine).
+
+ Additional mods for handling GNU C++ (from Tiemann):
+ * dbxread.c (read_type): Added case for '#' type (method type, I
+ believe).
+ (read_struct_type): If type code is undefined, make the main
+ variant for the type be itself. Allow recognition of bad format
+ in reading of structure fields.
+ * eval.c (evaluate_subexp): Modify evaluation of a member of a
+ structure and pointer to same to make sure that the syntax is
+ being used correctly and that the member is being accessed correctly.
+ * symseg.h: Added TYPE_CODE_METHOD to enum type_code. Add a
+ pointer to an array of argument types to the type structure.
+ * symtab.c (lookout_method_type, smash_to_method_type): Created.
+ * symtab.h (TYPE_ARG_TYPES): Created.
+ * valops.c (call_function): Modified handling of methods to be the
+ same as handling of functions; no longer check for members.
+ * valprint.c (val_print, type_print_varspec_{prefix,suffix},
+ type_print_base): Added code to print method args correctly.
+ * values.c (value_virtual_fn_field): Modify access to virtual
+ function table.
+
+Wed Mar 29 13:19:34 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * findvar.c: Special cases for REGISTER_WINDOWS: 1) Return 0 if we
+ are the innermost frame, and 2) return the next frame in's value
+ if the SP is being looked for.
+
+ * blockframe.c (get_next_frame): Created; returns the next (inner)
+ frame of the called frame.
+ * frame.h: Extern delcaration for above.
+
+ * main.c (command_line_input): Stick null at end before doing
+ history expansion.
+
+Tue Mar 28 17:35:50 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (read_dbx_symtab): Added namestring assignment to
+ N_DATA/BSS/ABS case. Sigh.
+
+Sat Mar 25 17:49:07 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * expread.y: Defined YYDEBUG.
+
+Fri Mar 24 20:46:55 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * symtab.c (make_symbol_completion_list): Completely rewrote to
+ never call psymtab_to_symtab, to do a correct search (no
+ duplicates) through the visible symbols, and to include structure
+ and union fields in the things that it can match.
+
+Thu Mar 23 15:27:44 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (dbx_create_type): Created; allocates and inits space
+ for a type without putting it on the type vector lists.
+ (dbx_alloc_type): Uses above.
+
+ * Makefile: xgdb.o now produced by default rules for .o.c.
+
+Fri Mar 17 14:27:50 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * infrun.c: Fixed up inclusion of aouthdr.h on UMAX_PTRACE.
+
+ * Makefile, config.gdb: Added hp300bsd to potential
+ configurations.
+ * hp300bsd-dep.c, m-hp300bsd.h: Created.
+
+ * infrun.c (wait_for_inferior): Rewrote to do no access to
+ inferior until we make sure it's still there.
+
+ * inflow.c (inferior_died): Added a select to force the selected
+ frame to null when inferior dies.
+
+ * dbxread.c (symbol_file_command): free and zero symfile when
+ discarding symbols.
+
+ * core.c (xfer_core_file): Extended and cleaned up logic in
+ interpeting memory address.
+
+ * core.c (xfer_core_file): Extended opening comment.
+
+Thu Mar 16 15:39:42 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * coffread.c (symbol_file_command): Free symfile name when freeing
+ contents.
+
+ * blockframe.c (get_prev_frame_info): Added to fatal error message
+ to indicate that it should never happen.
+
+ * stack.c (frame_info): Printed out value of "saved" sp seperately
+ to call attention to the fact that it isn't stored in memory
+ anywhere; the actual previous frames address is printed.
+
+ * m-sparc.h (FRAME_FIND_SAVED_REGS): Set address of sp saved in
+ frame to value of fp (rather than value of sp in current frame).
+
+ * expread.y: Allow "unsigned" as a type itself, as well as a type
+ modifier.
+
+ * coffread.c: Added declaration for fclose
+
+Fri Mar 10 17:22:31 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * main.c (command_line_input): Checked for -1 return from
+ readline; indicates EOF.
+
+Fri Mar 3 00:31:27 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * remote.c (remote_open): Cast return from signal to (void (*)) to
+ avoid problems on machines where the return type of signal is (int
+ (*)).
+
+ * Makefile: Removed deletion of version control from it (users
+ will need it for their changes).
+
+Thu Mar 2 15:32:21 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * symmetry-dep.c (print_1167_regs): Print out effective doubles on
+ even number regs.
+ (fetch_inferior_registers): Get the floating point regs also.
+
+ * xgdb.c (do_command): Copied command before calling execute
+ command (so that execute_command wouldn't write into text space).
+
+ * copying.awk: Created (will produce copying.c as output when
+ given COPYING as input).
+ * Makefile: Used above to create copying.c.
+ * main.c: Took out info_warranty and info_copying.
+
+ * *.*: Changed copyright notice to use new GNU General Public
+ License (includes necessary changes to manual).
+
+ * xgdb.c (create_text_widget): Created text_widget before I create
+ the source and sink.
+ (print_prompt): Added fflush (stdout).
+
+ * Makefile: Added -lXmu to the compilation line for xgdb. Left
+ the old one there incase people still had R2.
+
+ * README: Added note about -gg format.
+
+ * remote.c (getpkt): Fixed typo; && ==> &.
+
+ * Makefile: Added new variable READLINE_FLAGS so that I could
+ force compilation of readline.c and history.c with -DSYSV on
+ system V machines. Mentioned in Makefile comments at top.
+
+Wed Mar 1 17:01:01 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * hp9k320-dep.c (store_inferior_registers): Fixed typo.
+
+Fri Feb 24 14:58:45 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * hp9k320-dep.c (store_inferior_registers,
+ fetch_inferior_registers): Added support for remote debugging.
+
+ * remote.c (remote_timer): Created.
+ (remote_open, readchar): Setup to timeout reads if they take
+ longer than "timeout". This allows one to debug how long such
+ things take.
+ (putpkt): Modified to print a debugging message (if such things
+ are enabled) each time it resends a packet.
+ (getpkt): Modified to make the variable CSUM unsigned and read it
+ CSUM with an & 0xff (presumably to deal with poor sign extension
+ on some machines). Also made c1 and c2 unsigned.
+ (remote_wait): Changed buffer to unsigned status.
+ (remote_store_registers, remote_write_bytes): Puts a null byte at
+ the end of the control string.
+
+ * infcmd.c (attach_command, detach_command, _initialize_infcmd):
+ Made attach_command and detach_command always availible, but
+ modified them to only allow device file attaches if ATTACH_DETACH
+ is not defined.
+
+ * gdb.texinfo: Added cross reference from attach command to remote
+ debugging.
+
+Thu Feb 23 12:37:59 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * remote.c (remote_close): Created to close the remote connection
+ and set the remote_debugging flag to 0.
+ * infcmd.c (detach_command): Now calls the above when appropriate.
+
+ * gdb.texinfo: Removed references to the ``Distribution'' section
+ in the copyright.
+
+ * main.c, utils.c (ISATTY): Created default defintions of this
+ macro which use isatty and fileno.
+ * utils.c (fprintf_filtered, print_spaces_filtered), main.c
+ (command_loop, command_line_input): Used this macro.
+ * m-news.h: Created a definition to override this one.
+
+ * utils.c (fprintf_filtered): Made line_size static (clueless).
+
+ * utils.c (fprintf_filtered): Changed max length of line printed
+ to be 255 chars or twice the format length.
+
+ * symmetry-dep.c, m-symmetry: Fixed typo (^L ==> ).
+
+ * printcmd.c (do_examine): Fixed typo (\n ==> \t).
+
+Wed Feb 22 16:00:33 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ Contributed by Jay Vosburgh (jay@mentor.cc.purdue.edu)
+ * m-symmetry.h, symmetry-dep.c: Created.
+ * Makefile: Added above in appropriate lists.
+ * config.gdb: Added "symmetry" target.
+
+ * utils.c (prompt_for_continue): Zero'd chars_printed also.
+
+ * utils.c (fprintf_filtered): Call prompt for continue instead of
+ doing it yourself.
+
+ * dbxread.c (read_dbx_symtab): Added code to conditionalize what
+ symbol type holds to "x.o" or "-lx" symbol that indicates the
+ beginning of a new file.
+
+Tue Feb 21 16:22:13 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * gdb.texinfo: Deleted @ignore block at end of file.
+
+ * findvar.c, stack.c: Changed comments that refered to "frame
+ address" to "frame id".
+
+ * findvar.c (locate_var_value): Modified so that taking the
+ address of an array generates an object whose type is a pointer to
+ the elements of the array.
+
+Sat Feb 18 16:35:14 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * gdb.texinfo: Removed reference to "!" as a shell escape
+ character. Added a section on controling screen output
+ (pagination); changing "Input" section to "User Interface"
+ section. Changed many inappropriate subsubsection nodes into
+ subsections nodes (in the readline and history expansion
+ sections).
+
+Fri Feb 17 11:10:54 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * utils.c (set_screensize_command): Created.
+ (_initialize_utils): Added above to setlist.
+
+ * main.c (main): Added check to see if ~/.gdbinit and .gdbinit
+ were the same file; only one gets read if so. Had to include
+ sys/stat.h for this.
+
+ * valprint.c (type_print_base): Changed calls to print_spaces to
+ print_spaces_filtered.
+
+ * main.c (command_line_input): Chaned test for command line
+ editing to check for stdin and isatty.
+
+ * main.c (command_loop): Call reinitialize_more_filter before each
+ command (if reading from stdin and it's a tty).
+ utils.c (initialize_more_filter): Changed name to
+ reinitialize_more_filter; killed arguments.
+ utils.c (_initialize_utils): Created; initialized lines_per_page
+ and chars_per_line here.
+
+ * utils.c (fprintf_filtered): Removed printing of "\\\n" after
+ printing linesize - 1 chars; assume that the screen display will
+ take care of that. Still watching that overflow.
+
+ * main.c: Created the global variables linesize and pagesize to
+ describe the number of chars per line and lines per page.
+
+Thu Feb 16 17:27:43 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * printcmd.c (do_examine, print_scalar_formatted, print_address,
+ whatis_command, do_one_display, ptype_command), valprint.c
+ (value_print, val_print, type_print_method_args, type_print_1,
+ type_print_derivation_info, type_print_varspec_suffix,
+ type_print_base), breakpoint.c (breakpoints_info, breakpoint_1),
+ values.c (history_info), main.c (editing_info, warranty_info,
+ copying_info), infcmd.c (registers_info), inflow.c
+ (term_status_command), infrun.c (signals_info), stack.c
+ (backtrace_command, print_frame_info), symtab.c (list_symbols,
+ output_source_filename), command.c (help_cmd, help_list,
+ help_command_list): Replaced calls to printf, fprintf, and putc
+ with calls to [f]printf_filtered to handle more processing.
+ Killed local more emulations where I noticed them.
+
+Wed Feb 15 15:27:36 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * defs.h, utils.c (initialize_more_filter, fprintf_filtered,
+ printf_filtered): Created a printf that will also act as a more
+ filter, prompting the user for a <return> whenever the page length
+ is overflowed.
+
+ * symtab.c (list_symbols): Elminated some code inside of an #if 0.
+
+Tue Feb 14 11:11:24 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * Makefile: Turned off backup versions for this file; it changes
+ too often.
+
+ * command.c (lookup_cmd, _initialize_command): Changed '!' so that
+ it was no longer a shell escape. "sh" must be used.
+
+ * main.c (command_line_input, set_history_expansion,
+ initialize_main): Turned history expansion on, made it the
+ default, and only execute it if the first character in the line is
+ a '!'.
+
+ * version.c, gdb.texinfo: Moved version to 3.2 (as usual, jumping
+ the gun some time before release).
+
+ * gdb.texinfo: Added sections (adapted from Brian's notes) on
+ command line editing and history expansion.
+
+ * main.c (set_command_editing, initialize_main): Modified name to
+ set_editing and modified command to "set editing".
+
+ * Makefile: Put in dependencies for READLINEOBJS.
+
+ * main.c (history_info, command_info): Combined into new command
+ info; deleted history_info.
+ (initialize_main): Deleted "info history" command; it was
+ interfering with the value history.
+
+ * coffread.c (enter_linenos): Modified to do bit copy instead of
+ pointer dereference, since the clipper machine can't handle having
+ longs on short boundaries.
+ (read_file_hdr): Added code to get number of syms for clipper.
+
+ * stack.c (return_command): Fixed method for checking when all of
+ the necessary frames had been popped.
+
+ * dbxread.c (read_dbx_symtab (ADD_PSYMBOL_TO_LIST)): Fixed typo in
+ allocation length.
+
+Mon Feb 13 10:03:27 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * dbxread.c (read_dbx_symtab): Split assignment to namestring into
+ several different assignments (so that it wouldn't be done except
+ when it had to be). Shortened switches and duplicated code to
+ produce the lowest possible execution time. Commented (at top of
+ switch) which code I duplicated.
+
+ * dbxread.c (read_dbx_symtab): Modified which variables were
+ register and deleted several variables which weren't used. Also
+ eliminated 'F' choice from subswitch, broke out strcmp's, reversed
+ compare on line 1986, and elminated test for !namestring[0]; it is
+ caught by following test for null index of ':'.
+
+Sun Feb 12 12:57:56 1989 Randall Smith (randy at plantaris.ai.mit.edu)
+
+ * main.c (gdb_completer_word_break_characters): Turned \~ into ~.
+
+Sat Feb 11 15:39:06 1989 Randall Smith (randy at plantaris.ai.mit.edu)
+
+ * symtab.c (find_pc_psymtab): Created; checks all psymtab's till
+ it finds pc.
+ (find_pc_symtab): Used; fatal error if psymtab found is readin
+ (should have been caught in symtab loop).
+ (lookup_symbol): Added check before scan through partial symtab
+ list for symbol name to be on the misc function vector (only if in
+ VAR_NAMESPACE). Also made sure that psymtab's weren't fooled with
+ if they had already been read in.
+ (list_symbols): Checked through misc_function_vector for matching
+ names if we were looking for functions.
+ (make_symbol_completion_list): Checked through
+ misc_function_vector for matching names.
+ * dbxread.c (read_dbx_symtab): Don't bother to do processing on
+ global function types; this will be taken care of by the
+ misc_function hack.
+
+ * symtab.h: Modified comment on misc_function structure.
+
+Fri Feb 10 18:09:33 1989 Randall Smith (randy at plantaris.ai.mit.edu)
+
+ * symseg.h, dbxread.c (read_dbx_symtab, init_psymbol_list,
+ start_psymtab, end_psymtab), coffread.c (_initialize_coff),
+ symtab.c (lookup_partial_symbol, list_symbols,
+ make_symbol_completion_list): Changed separate variables for
+ description of partial symbol allocation into a specific kind of
+ structure.
+
+ (read_dbx_symtab, process_symbol_for_psymtab): Moved most of
+ process_symbol_for_psymtab up into read_dbx_symtab, moved a couple
+ of symbol types down to the ingore section, streamlined (I hope)
+ code some, modularized access to psymbol lists.
+
+Thu Feb 9 13:21:19 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * main.c (command_line_input): Made sure that it could recognize
+ newlines as indications to repeat the last line.
+
+ * symtab.c (_initialize_symtab): Changed size of builtin_type_void
+ to be 1 for compatibility with gcc.
+
+ * main.c (initialize_main): Made history_expansion the default
+ when gdb is compiled with HISTORY_EXPANSION.
+
+ * readline.c, readline.h, history.c, history.h, general.h,
+ emacs_keymap.c, vi_keymap.c, keymaps.c, funmap.c: Made all of
+ these links to /gp/gnu/bash/* to keep them updated.
+ * main.c (initialize_main): Made default be command editing on.
+
+Wed Feb 8 13:32:04 1989 & Smith (randy at hobbes)
+
+ * dbxread.c (read_dbx_symtab): Ignore N_BSLINE on first
+ readthrough.
+
+ * Makefile: Removed convex-dep.c from list of distribution files.
+
+Tue Feb 7 14:06:25 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * main.c: Added command lists sethistlist and unsethistlist to
+ accesible command lists.
+ (parse_binary_operation): Created to parse a on/1/yes vs. off/0/no
+ spec.
+ (set_command_edit, set_history, set_history_expansion,
+ set_history_write, set_history_size, set_history_filename,
+ command_info, history_info): Created to allow users to control
+ various aspects of command line editing.
+
+ * main.c (symbol_creation_function): Created.
+ (command_line_input, initialize_main): Added rest of stuff
+ necessary for calling bfox' command editing routines under
+ run-time control.
+ * Makefile: Included readline and history source files for command
+ editing; also made arrangements to make sure that the termcap
+ library was available.
+ * symtab.c (make_symbol_completion_list): Created.
+
+Mon Feb 6 16:25:25 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * main.c: Invented variables to control command editing.
+ command_editing_p, history_expansion_p, history_size,
+ write_history_p, history_filename. Initialized them to default
+ values in initialize_main.
+
+ * infcmd.c (registers_info), infrun.c (signals_info),
+ * main.c (gdb_read_line): Changed name to command_line_input.
+ (readline): Changed name to gdb_readline; added second argument
+ indicating that the read value shouldn't be saved (via malloc).
+ * infcmd.c (registers_info), infrun.c (signals_info), main.c
+ (copying_info), symtab.c (output_source_filename, MORE,
+ list_symbols): Converted to use gdb_readline in place of
+ gdb_read_line.
+
+
+Sun Feb 5 17:34:38 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * blockframe.c (get_frame_saved_regs): Removed macro expansion
+ that had accidentally been left in the code.
+
+Sat Feb 4 17:54:14 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * main.c (gdb_read_line, readline): Added function readline and
+ converted gdb_read_line to use it. This was a conversion to the
+ line at a time style of input, in preparation for full command
+ editing.
+
+Fri Feb 3 12:39:03 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (read_dbx_symtab): Call end_psymtab at the end of
+ read_dbx_symtab if any psymtab still needs to be completed.
+
+ * config.gdb, sun3-dep.c: Brought these into accord with the
+ actual sun2 status (no floating point period; sun3-dep.c unless
+ has os > 3.0).
+ * m-sun2os2.h: Deleted; not needed.
+
+ * config.gdb: Added a couple of aliases for machines in the
+ script.
+
+ * infrun.c: Added inclusion of aouthdr.h inside of #ifdef UMAX
+ because ptrace needs to know about the a.out header.
+
+ * Makefile: Made dep.o depend on dep.c and config.status only.
+
+ * expread.y: Added declarations of all of the new write_exp_elt
+ functions at the include section in the top.
+
+ * Makefile: Added a YACC definition so that people can use bison
+ if they wish.
+
+ * Makefile: Added rms' XGDB-README to the distribution.
+
+ * Makefile: Added removal of init.o on a "make clean".
+
+Thu Feb 2 16:27:06 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * *-dep.c: Deleted definition of COFF_FORMAT if AOUTHDR was
+ defined since 1) We *may* (recent mail message) want to define
+ AOUTHDR under a basically BSD system, and 2) AOUTHDR is sometimes
+ a typedef in coff encapsulation setups. Also removed #define's of
+ AOUTHDR if AOUTHDR is already defined (inside of coff format).
+ * core.c, dbxread.c: Removed #define's of AOUTHDR if AOUTHDR is
+ already defined (inside of coff format).
+
+Tue Jan 31 12:56:01 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * GDB 3.1 released.
+
+ * values.c (modify_field): Changed test for endianness to assign
+ to integer and reference character (so that all bits would be
+ defined).
+
+Mon Jan 30 11:41:21 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * news-dep.c: Deleted inclusion of fcntl.h; just duplicates stuff
+ found in sys/file.h.
+
+ * i386-dep.c: Included default definition of N_SET_MAGIC for
+ COFF_FORMAT.
+
+ * config.gdb: Added checks for several different operating
+ systems.
+
+ * coffread.c (read_struct_type): Put in a flag variable so that
+ one could tell when you got to the end of a structure.
+
+ * sun3-dep.c (core_file_command): Changed #ifdef based on SUNOS4
+ to ifdef based on FPU.
+
+ * infrun.c (restore_inferior_status): Changed error message to
+ "unable to restore previously selected frame".
+
+ * dbxread.c (read_dbx_symtab): Used intermediate variable in error
+ message reporting a bad symbol type. (scan_file_globals,
+ read_ofile_symtab, read_addl_syms): Data type of "type" changed to
+ unsigned char (which is what it is).
+ * i386-dep.c: Removed define of COFF_FORMAT if AOUTHDR is defined.
+ Removed define of a_magic to magic (taken care of by N_MAGIC).
+ (core_file_command): Zero'd core_aouthdr instead of setting magic
+ to zero.
+ * i386-pinsn.c: Changed jcxz == jCcxz in jump table.
+ (putop): Added a case for 'C'.
+ (OP_J): Added code to handle possible masking of PC value on
+ certain kinds of data.
+ m-i386gas.h: Moved COFF_ENCAPSULATE to before inclusion of
+ m-i386.h and defined NAMES_HAVE_UNDERSCORE.
+
+ * coffread.c (unrecrod_misc_function, read_coff_symtab): Added
+ symbol number on which error occured to error output.
+
+Fri Jan 27 11:55:04 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * Makefile: Removed init.c in make clean. Removed it without -f
+ and with leading - in make ?gdb.
+
+Thu Jan 26 15:08:03 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ Changes to get it to work on gould NP1.
+ * dbxread.c (read_dbx_symtab): Included cases for N_NBDATA and
+ N_NBBSS.
+ (psymtab_to_symtab): Changed declaration of hdr to
+ DECLARE_FILE_HEADERS. Changed access to use STRING_TABLE_SIZE and
+ SYMBOL_TABLE_SIZE.
+ * gld-pinsn.c (findframe): Added declaration of framechain() as
+ FRAME_ADDR.
+
+ * coffread.c (read_coff_symtab): Avoided treating typedefs as
+ external symbol definitions.
+
+Wed Jan 25 14:45:43 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * Makefile: Removed reference to alloca.c. If they need it, they
+ can pull alloca.o from the gnu-emacs directory.
+
+ * version.c, gdb.texinfo: Updated version to 3.1 (jumping the gun
+ a bit so that I won't forget when I release).
+
+ * m-sun2.h, m-sun2os2.h, m-sun3os4.h, config.gdb: Modified code so
+ that default includes new sun core, ptrace, and attach-detach.
+ Added defaults for sun 2 os 2.
+
+ Modifications to reset stack limit back to what it used to be just
+ before exec. All mods inside of #ifdef SET_STACK_LIMIT_HUGE.
+ * main.c: Added global variable original_stack_limit.
+ (main): Set original_stack_limit to original stack limit.
+ * inflow.c: Added inclusion of necessary files and external
+ reference to original_stack_limit.
+ (create_inferior): Reset stack limit to original_stack_limit.
+
+ * dbxread.c (read_dbx_symtab): Killed PROFILE_SYMBOLS ifdef.
+
+ * sparc-dep.c (isabranch): Multiplied offset by 4 before adding it
+ to addr to get target.
+
+ * Makefile: Added definition of SHELL to Makefile.
+
+ * m-sun2os4.h: Added code to define NEW_SUN_PTRACE, NEW_SUN_CORE,
+ and ATTACH_DETACH.
+ * sun3-dep.c: Added code to avoid fp regs if we are on a sun2.
+
+Tue Jan 24 17:59:14 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (read_array_type): Added function.
+ (read_type): Added call to above instead of inline code.
+
+ * Makefile: Added ${GNU_MALLOC} to the list of dependencies for
+ the executables.
+
+Mon Jan 23 15:08:51 1989 Randall Smith (randy at plantaris.ai.mit.edu)
+
+ * gdb.texinfo: Added paragraph to summary describing languages
+ with which gdb can be run. Also added descriptions of the
+ "info-methods" and "add-file" commands.
+
+ * symseg.h: Commented a range type as having TYPE_TARGET_TYPE
+ pointing at the containing type for the range (often int).
+ * dbxread.c (read_range_type): Added code to do actual range types
+ if they are defined. Assumed that the length of a range type is
+ the length of the target type; this is a lie, but will do until
+ somebody gets back to me as to what these silly dbx symbols mean.
+
+ * dbxread.c (read_range_type): Added code to be more picky about
+ recognizing builtins as range types, to treat types defined as
+ subranges of themselves to be subranges of int, and to recognize
+ the char type idiom from dbx as a special case.
+
+Sun Jan 22 01:00:13 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * m-vax.h: Removed definition of FUNCTION_HAS_FRAME_POINTER.
+ * blockframe.c (get_prev_frame_info): Removed default definition
+ and use of above. Instead conditionalized checking for leaf nodes
+ on FUNCTION_START_OFFSET (see comment in code).
+
+Sat Jan 21 16:59:19 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (read_range_type): Fixed assumption that integer was
+ always type 1.
+
+ * gdb.texinfo: Fixed spelling mistake and added a note in the
+ running section making it clear that users may invoke subroutines
+ directly from gdb.
+
+ * blockframe.c: Setup a default definition for the macro
+ FUNCTION_HAS_FRAME_POINTER.
+ (get_prev_frame_info): Used this macro instead of checking
+ SKIP_PROLOGUE directly.
+ * m-vax.h: Overroad definition; all functions on the vax have
+ frame pointers.
+
+Fri Jan 20 12:25:35 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * core.c: Added default definition of N_MAGIC for COFF_FORMAT.
+
+ * xgdb.c: Installed a fix to keep the thing from dying when there
+ isn't any frame selected.
+
+ * core.c: Made a change for the UMAX system; needs a different
+ file included if using that core format.
+
+ * Makefile: Deleted duplicate obstack.h in dbxread.c dependency.
+
+ * munch: Modified (much simpler) to cover (I hope) all cases.
+
+ * utils.c (save_cleanups, restore_cleanups): Added functions to
+ allow you to push and pop the chain of cleanups to be done.
+ * defs.h: Declared the new functions.
+ * main.c (catch_errors): Made sure that the only cleanups which
+ would be done were the ones put on the chain *after* the current
+ location.
+
+ * m-*.h (FRAME_CHAIN_VALID): Removed check on pc in the current
+ frame being valid.
+ * blockframe.c (get_prev_frame_info): Made the assumption that if
+ a frame's pc value was within the first object file (presumed to
+ be /lib/crt0.o), that we shouldn't go any higher.
+
+ * infrun.c (wait_for_inferior): Do *not* execute check for stop pc
+ at step_resume_break if we are proceeding over a breakpoint (ie.
+ if trap_expected != 0).
+
+ * Makefile: Added -g to LDFLAGS.
+
+ * m-news.h (POP_FRAME) Fixed typo.
+
+ * printcmd.c (print_frame_args): Modified to print out register
+ params in order by .stabs entry, not by register number.
+
+ * sparc-opcode.h: Changed declaration of (struct
+ arith_imm_fmt).simm to be signed (as per architecture manual).
+ * sparc-pinsn.c (fprint_addr1, print_insn): Forced a cast to an
+ int, so that we really would get signed behaivior (default for sun
+ cc is unsigned).
+
+ * i386-dep.c (i386_get_frame_setup): Replace function with new
+ function provided by pace to fix bug in recognizing prologue.
+
+Thu Jan 19 11:01:22 1989 Randall Smith (randy at plantaris.ai.mit.edu)
+
+ * infcmd.c (run_command): Changed error message to "Program not
+ restarted."
+
+ * value.h: Changed "frame" field in value structure to be a
+ FRAME_ADDR (actually CORE_ADDR) so that it could survive across
+ calls.
+
+ * m-sun.h (FRAME_FIND_SAVED_REGS): Fixed a typo.
+
+ * value.h: Added lval: "lval_reg_frame_relative" to indicate a
+ register that must be interpeted relative to a frame. Added
+ single entry to value structure: "frame", used to indicate which
+ frame a relative regnum is relative to.
+ * findvar.c (value_from_register): Modified to correctly setup
+ these fields when needed. Deleted section to fiddle with last
+ register copied on little endian machine; multi register
+ structures will always occupy an integral number of registers.
+ (find_saved_register): Made extern.
+ * values.c (allocate_value, allocate_repeat_value): Zero frame
+ field on creation.
+ * valops.c (value_assign): Added case for lval_reg_frame_relative;
+ copy value out, modify it, and copy it back. Desclared
+ find_saved_register as being external.
+ * value.h: Removed addition of kludgy structure; thoroughly
+ commented file.
+ * values.c (free_value, free_all_values, clear_value_history,
+ set_internalvar, clear_internavars): Killed free_value.
+
+Wed Jan 18 20:09:39 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * value.h: Deleted struct partial_storage; left over from
+ yesterday.
+
+ * findvar.c (value_from_register): Added code to create a value of
+ type lval_reg_partsaved if a value is in seperate registers and
+ saved in different places.
+
+Tue Jan 17 13:50:18 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * value.h: Added lval_reg_partsaved to enum lval_type and
+ commented enum lval_type. Commented value structure.
+ Added "struct partial_register_saved" to value struct; added
+ macros to deal with structure to value.h.
+ * values.c (free_value): Created; special cases lval_reg_partsaved
+ (which has a pointer to an array which also needs to be free).
+ (free_all_values, clear_value_history, set_internalvar,
+ clear_internalvars): Modified to use free_values.
+
+ * m-sunos4.h: Changed name to sun3os4.h.
+ * m-sun2os4.h, m-sun4os4.h: Created.
+ * config.gdb: Added configuration entries for each of the above.
+ * Makefile: Added into correct lists.
+
+ * Makefile: Added dependencies on a.out.encap.h. Made
+ a.out.encap.h dependent on a.out.gnu.h and dbxread.c dependent on
+ stab.gnu.h.
+
+ * infrun.c, remote.c: Removed inclusion of any a.out.h files in
+ these files; they aren't needed.
+
+ * README: Added comment about bug reporting and comment about
+ xgdb.
+
+ * Makefile: Added note to HPUX dependent section warning about
+ problems if compiled with gcc and mentioning the need to add
+ -Ihp-include to CFLAGS if you compile on those systems. Added a
+ note about needing the GNU nm with compilers *of gdb* that use the
+ coff encapsulate feature also. * hp-include: Made symbolic link
+ over to /gp/gnu/binutils.
+
+ * Makefile: Added TSOBS NTSOBS OBSTACK and REGEX to list of things
+ to delete in "make clean". Also changed "squeakyclean" target as
+ "realclean".
+
+ * findvar.c (value_from_register): Added assignment of VALUE_LVAL
+ to be lval_memory when that is appropriate (original code didn't
+ bother because it assumed that it was working with a pre lval
+ memoried value).
+
+ * expread.y (yylex): Changed to only return type THIS if the
+ symbol "$this" is defined in some block superior or equal to the
+ current expression context block.
+
+Mon Jan 16 13:56:44 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * m-*.h (FRAME_CHAIN_VALID): On machines which check the relation
+ of FRAME_SAVED_PC (thisframe) to first_object_file_end (all except
+ gould), make sure that the pc of the current frame also passes (in
+ case someone stops in _start).
+
+ * findvar.c (value_of_register): Changed error message in case of
+ no inferior or core file.
+
+ * infcmd.c (registers_info): Added a check for inferior or core
+ file; error message if not.
+
+ * main.c (gdb_read_line): Modified to take prompt as argument and
+ output it to stdout.
+ * infcmd.c (registers_info, signals_info), main.c (command_loop,
+ read_command_lines, copying_info), symtab.c (decode_line_2,
+ output_source_filename, MORE, list_symbols): Changed calling
+ convention used to call gdb_read_line.
+
+ * infcmd.c, infrun.c, main.c, symtab.c: Changed the name of the
+ function "read_line" to "gdb_read_line".
+ * breakpoint.c: Deleted external referenced to function
+ "read_line" (not needed by code).
+
+Fri Jan 13 12:22:05 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * i386-dep.c: Include a.out.encap.h if COFF_ENCAPSULATE.
+ (N_SET_MAGIC): Defined if not defined by include file.
+ (core_file_command): Used N_SET_MAGIC instead of assignment to
+ a_magic.
+ (exec_file_command): Stuck in a HEADER_SEEK_FD.
+
+ * config.gdb: Added i386-dep.c as depfile for i386gas choice.
+
+ * munch: Added -I. to cc to pick up things included by the param
+ file.
+
+ * stab.gnu.def: Changed name to stab.def (stab.gnu.h needs this name).
+ * Makefile: Changed name here also.
+ * dbxread.c: Changed name of gnu-stab.h to stab.gnu.h.
+
+ * gnu-stab.h: Changed name to stab.gnu.h.
+ * stab.gnu.def: Added as link to binutils.
+ * Makefile: Put both in in the distribution.
+
+Thu Jan 12 11:33:49 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c: Made which stab.h is included dependent on
+ COFF_ENCAPSULATE; either <stab.h> or "gnu-stab.h".
+ * Makefile: Included gnu-stab.h in the list of files to include in
+ the distribution.
+ * gnu-stab.h: Made a link to /gp/gnu/binutils/stab.h
+
+ * Makefile: Included a.out.gnu.h and m-i386gas.h in list of
+ distribution files.
+ * m-i386gas.h: Changed to include m-i386.h and fiddle with it
+ instead of being a whole new file.
+ * a.out.gnu.h: Made a link to /gp/gnu/binutils/a.out.gnu.h.
+
+ Chris Hanson's changes to gdb for hp Unix.
+ * Makefile: Modified comments on hpux.
+ * hp9k320-dep.c: #define'd WOPR & moved inclusion of signal.h
+ * inflow.c: Moved around declaratiosn of <sys/fcntl.h> and
+ <sys/ioctl.h> inside of USG depends and deleted all SYSV ifdef's
+ (use USG instead).
+ * munch: Modified to accept any number of spaces between the T and
+ the symbol name.
+
+ Pace's changes to gdb to work with COFF_ENCAPSULATE (robotussin):
+ * config.gdb: Added i386gas to targets.
+ * default-dep.c: Include a.out.encap.h if COFF_ENCAPSULATE.
+ (N_SET_MAGIC): Defined if not defined by include file.
+ (core_file_command): Used N_SET_MAGIC instead of assignment to a_magic.
+ (exec_file_command): Stuck in a HEADER_SEEK_FD.
+ * infrun.c, remote.c: Added an include of a.out.encap.h if
+ COFF_ENCAPSULATE defined. This is commented out in these two
+ files, I presume because the definitions aren't used.
+ * m-i386gas.h: Created.
+ * dbxread.c: Included defintions for USG.
+ (READ_FILE_HEADERS): Now uses HEADER_SEEK_FD if it exists.
+ (symbol_file_command): Deleted use of HEADER_SEEK_FD.
+ * core.c: Deleted extra definition of COFF_FORMAT.
+ (N_MAGIC): Defined to be a_magic if not already defined.
+ (validate_files): USed N_MAGIC instead of reading a_magic.
+
+Wed Jan 11 12:51:00 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * remote.c: Upped PBUFSIZ.
+ (getpkt): Added zeroing of c inside loop in case of error retry.
+
+ * dbxread.c (read_dbx_symtab, process_symbol_for_psymtab): Removed
+ code to not put stuff with debugging symbols in the misc function
+ list. Had been ifdef'd out.
+
+ * gdb.texinfo: Added the fact that the return value for a function
+ is printed if you use return.
+
+ * infrun.c (wait_for_inferior): Removed test in "Have we hit
+ step_resume_breakpoint" for sp values in proper orientation. Was
+ in there for recursive calls in functions without frame pointers
+ and it was screwing up calls to alloca.
+
+ * dbxread.c: Added #ifdef COFF_ENCAPSULATE to include
+ a.out.encap.h.
+ (symbol_file_command): Do HEADER_SEEK_FD when defined.
+ * dbxread.c, core.c: Deleted #ifdef ROBOTUSSIN stuff.
+ * robotussin.h: Deleted local copy (was symlink).
+ * a.out.encap.h: Created symlink to
+ /gp/gnu/binutils/a.out.encap.h.
+ * Makefile: Removed robotussin.h and included a.out.encap.h in
+ list of files.
+
+ * valprint.c (val_print, print_scalar_formatted): Changed default
+ precision of printing float value; now 6 for a float and 16 for a
+ double.
+
+ * findvar.c (value_from_register): Added code to deal with the
+ case where a value is spread over several registers. Still don't
+ deal with the case when some registers are saved in memory and
+ some aren't.
+
+Tue Jan 10 17:04:04 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * xgdb.c (xgdb_create_window): Removed third arg (XtDepth) to
+ frameArgs.
+
+ * infrun.c (handle_command): Error if signal number is less or
+ equal to 0 or greater or equal to NSIG or a signal number is not
+ provided.
+
+ * command.c (lookup_cmd): Modified to not convert command section
+ of command line to lower case in place (in case it isn't a
+ subcommand, but an argument to a command).
+
+Fri Jan 6 17:57:34 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c: Changed "text area" to "data area" in comments on
+ N_SETV.
+
+Wed Jan 4 12:29:54 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * dbxread.c: Added definitions of gnu symbol types after inclusion
+ of a.out.h and stab.h.
+
+Mon Jan 2 20:38:31 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * eval.c (evaluate_subexp): Binary logical operations needed to
+ know type to determine whether second value should be evaluated.
+ Modified to discover type before binup_user_defined_p branch.
+ Also commented "enum noside".
+
+ * Makefile: Changed invocations of munch to be "./munch".
+
+ * gdb.texinfo: Updated to refer to current version of gdb with
+ January 1989 last update.
+
+ * coffread.c (end_symtab): Zero context stack when finishing
+ lexical contexts.
+ (read_coff_symtab): error if context stack 0 in ".ef" else case.
+
+ * m-*.h (FRAME_SAVED_PC): Changed name of argument from "frame" to
+ "FRAME" to avoid problems with replacement of "->frame" part of
+ macro.
+
+ * i386-dep.c (i386_get_frame_setup): Added codestream_get() to
+ move codestream pointer up to the correct location in "subl $X,
+ %esp" case.
+
+Sun Jan 1 14:24:35 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * valprint.c (val_print): Rewrote routine to print string pointed
+ to by char pointer; was producing incorrect results when print_max
+ was 0.
+
+Fri Dec 30 12:13:35 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (read_dbx_symtab, process_symbol_for_psymtab): Put
+ everything on the misc function list.
+
+ * Checkpointed distribution.
+
+ * Makefile: Added expread.tab.c to the list of things slated for
+ distribution.
+
+Thu Dec 29 10:06:41 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * stack.c (set_backtrace_limit_command, backtrace_limit_info,
+ bactrace_command, _initialize_stack): Removed modifications for
+ limit on backtrace. Piping the backtrace through an interuptable
+ "more" emulation is a better way to do it.
+
+Wed Dec 28 11:43:09 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * stack.c
+ (set_backtrace_limit_command): Added command to set a limit to the
+ number of frames for a backtrace to print by default.
+ (backtrace_limit_info): To print the current limit.
+ (backtrace_command): To use the limit.
+ (_initialize_stack): To initialize the limit to its default value
+ (30), and add the set and info commands onto the appropriate
+ command lists.
+
+ * gdb.texinfo: Documented changes to "backtrace" and "commands"
+ commands.
+
+ * stack.c (backtrace_command): Altered so that a negative argument
+ would show the last few frames on the stack instead of the first
+ few.
+ (_initialize_stack): Modified help documentation.
+
+ * breakpoint.c (commands_command): Altered so that "commands" with
+ no argument would refer to the last breakpoint set.
+ (_initialize_breakpoint): Modified help documentation.
+
+ * infrun.c (wait_for_inferior): Removed ifdef on Sun4; now you can
+ single step through compiler generated sub calls and will die if
+ you next off of the end of a function.
+
+ * sparc-dep.c (single_step): Fixed typo; "break_insn" ==> "sizeof
+ break_insn".
+
+ * m-sparc.h (INIT_EXTRA_FRAME_INFO): Set the bottom of a stack
+ frame to be the bottom of the stack frame inner from this, if that
+ inner one is a leaf node.
+
+ * dbxread.c (read_dbx_symtab): Check to make sure we don't add a
+ psymtab to it's own dependency list.
+
+ * dbxread.c (read_dbx_symtab): Modified check for duplicate
+ dependencies to catch them correctly.
+
+Tue Dec 27 17:02:09 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * m-*.h (FRAME_SAVED_PC): Modified macro to take frame info
+ pointer as argument.
+ * stack.c (frame_info), blockframe.c (get_prev_frame_info),
+ gld-pinsn.c (findframe), m-*.h (SAVED_PC_AFTER_CALL,
+ FRAME_CHAIN_VALID, FRAME_NUM_ARGS): Changed usage of macros to
+ conform to above.
+ * m-sparc.h (FRAME_SAVED_PC), sparc-dep.c (frame_saved_pc):
+ Changed frame_saved_pc to have a frame info pointer as an
+ argument.
+
+ * m-vax.h, m-umax.h, m-npl.h, infrun.c (wait_for_inferior),
+ blockframe.c (get_prev_frame_info): Modified SAVED_PC_AFTER_CALL
+ to take a frame info pointer as an argument.
+
+ * blockframe.c (get_prev_frame_info): Altered the use of the
+ macros FRAME_CHAIN, FRAME_CHAIN_VALID, and FRAME_CHAIN_COMBINE to
+ use frame info pointers as arguments instead of frame addresses.
+ * m-vax.h, m-umax.h, m-sun3.h, m-sun3.h, m-sparc.h, m-pn.h,
+ m-npl.h, m-news.h, m-merlin.h, m-isi.h, m-hp9k320.h, m-i386.h:
+ Modified definitions of the above macros to suit.
+ * m-pn.h, m-npl.h, gould-dep.c (findframe): Modified findframe to
+ use a frame info argument; also fixed internals (wouldn't work
+ before).
+
+ * m-sparc.h: Cosmetic changes; reordered some macros and made sure
+ that nothing went over 80 lines.
+
+Thu Dec 22 11:49:15 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * Version 3.0 released.
+
+ * README: Deleted note about changing -lobstack to obstack.o.
+
+Wed Dec 21 11:12:47 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * m-vax.h (SKIP_PROLOGUE): Now recognizes gcc prologue also.
+
+ * blockframe.c (get_prev_frame_info): Added FUNCTION_START_OFFSET
+ to result of get_pc_function_start.
+ * infrun.c (wait_for_inferior): Same.
+
+ * gdb.texinfo: Documented new "step" and "next" behavior in
+ functions without line number information.
+
+Tue Dec 20 18:00:45 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * infcmd.c (step_1): Changed behavior of "step" or "next" in a
+ function witout line number information. It now sets the step
+ range around the function (to single step out of it) using the
+ misc function vector, warns the user, and continues.
+
+ * symtab.c (find_pc_line): Zero "end" subsection of returned
+ symtab_and_line if no symtab found.
+
+Mon Dec 19 17:44:35 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * i386-pinsn.c (OP_REG): Added code from pace to streamline
+ disassembly and corrected types.
+ * i386-dep.c
+ (i386_follow_jump): Code added to follow byte and word offset
+ branches.
+ (i386_get_frame_setup): Expanded to deal with more wide ranging
+ function prologue.
+ (i386_frame_find_saved_regs, i386_skip_prologue): Changed to use
+ i386_get_frame_setup.
+
+
+Sun Dec 18 11:15:03 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * m-sparc.h: Deleted definition of SUN4_COMPILER_BUG; was designed
+ to avoid something that I consider a bug in our code, not theirs,
+ and which I fixed earlier. Also deleted definition of
+ CANNOT_USE_ARBITRARY_FRAME; no longer used anywhere.
+ FRAME_SPECIFICATION_DYADIC used instead.
+
+ * infrun.c (wait_for_inferior): On the sun 4, if a function
+ doesn't have a prologue, a next over it single steps into it.
+ This gets around the problem of a "call .stret4" at the end of
+ functions returning structures.
+ * m-sparc.h: Defined SUN4_COMPILER_FEATURE.
+
+ * main.c (copying_info): Seperated the last printf into two
+ printfs. The 386 compiler will now handle it.
+
+ * i386-pinsn.c, i386-dep.c: Moved print_387_control_word,
+ print_387_status_word, print_387_status, and i386_float_info to
+ dep.c Also included reg.h in dep.c.
+
+Sat Dec 17 15:31:38 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * main.c (source_command): Don't close instream if it's null
+ (indicating execution of a user-defined command).
+ (execute_command): Set instream to null before executing
+ commands and setup clean stuff to put it back on error.
+
+ * inflow.c (terminal_inferior): Went back to not checking the
+ ioctl returns; there are some systems when this will simply fail.
+ It seems that, on most of these systems, nothing bad will happen
+ by that failure.
+
+ * values.c (value_static_field): Fixed dereferencing of null
+ pointer.
+
+ * i386-dep.c (i386_follow_jump): Modified to deal with
+ unconditional byte offsets also.
+
+ * dbxread.c (read_type): Fixed typo in function type case of switch.
+
+ * infcmd.c (run_command): Does not prompt to restart if command is
+ not from a tty.
+
+Fri Dec 16 15:21:58 1988 Randy Smith (randy at calvin)
+
+ * gdb.texinfo: Added a third option under the "Cannot Insert
+ Breakpoints" workarounds.
+
+ * printcmd.c (display_command): Don't do the display unless there
+ is an active inferior; only set it.
+
+ * findvar.c (value_of_register): Added an error check for calling
+ this when the inferior isn't active and a core file isn't being
+ read.
+
+ * config.gdb: Added reminder about modifying REGEX in the
+ makefile for the 386.
+
+ * i386-pinsn.c, i386-dep.c: Moved m-i386.h helper functions over
+ to i386-dep.c.b
+
+Thu Dec 15 14:04:25 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * README: Added a couple of notes about compiling gdb with itself.
+
+ * breakpoint.c (set_momentary_breakpoint): Only takes FRAME_FP of
+ frame if frame is non-zero.
+
+ * printcmd.c (print_scalar_formatted): Implemented /g size for
+ hexadecimal format on machines without an 8 byte integer type. It
+ seems to be non-trivial to implement /g for other formats.
+ (decode_format): Allowed hexadecimal format to make it through /g
+ fileter.
+
+Wed Dec 14 13:27:04 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * expread.y: Converted all calls to write_exp_elt from the parser
+ to calls to one of write_exp_elt_{opcode, sym, longcst, dblcst,
+ char, type, intern}. Created all of these routines. This gets
+ around possible problems in passing one of these things in one ear
+ and getting something different out the other. Eliminated
+ SUN4_COMPILER_BUG ifdef's; they are now superfluous.
+
+ * symmisc.c (free_all_psymtabs): Reinited partial_symtab_list to 0.
+ (_initialize_symmisc): Initialized both symtab_list and
+ partial_symtab_list.
+
+ * dbxread.c (start_psymtab): Didn't allocate anything on
+ dependency list.
+ (end_psymtab): Allocate dependency list on psymbol obstack from
+ local list.
+ (add_psymtab_dependency): Deleted.
+ (read_dbx_symtab): Put dependency on local list if it isn't on it
+ already.
+
+ * symtab.c: Added definition of psymbol_obstack.
+ * symtab.h: Added declaration of psymbol_obstack.
+ * symmisc.c (free_all_psymtabs): Added freeing and
+ reinitionaliztion of psymbol_obstack.
+ * dbxread.c (free_all_psymbols): Deleted.
+ (start_psymtab, end_psymtab,
+ process_symbol_for_psymtab): Changed most allocation
+ of partial symbol stuff to be off of psymbol_obstack.
+
+ * symmisc.c (free_psymtab, free_all_psymtabs): Deleted
+ free_psymtab subroutine.
+
+ * symtab.h: Removed num_includes and includes from partial_symtab
+ structure; no longer needed now that all include files have their
+ own psymtab.
+ * dbxread.c (start_psymtab): Eliminated initialization of above.
+ (end_psymtab): Eliminated finalization of above; get
+ includes from seperate list.
+ (read_dbx_symtab): Moved includes from psymtab list to
+ their own list; included in call to end_psymtab.
+ * symmisc.c (free_psymtab): Don't free includes.
+
+Tue Dec 13 14:48:14 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * i386-pinsn.c: Reformatted entire file to correspond to gnu
+ software indentation conventions.
+
+ * sparc-dep.c (skip_prologue): Added capability of recognizign
+ stores of input register parameters into stack slots.
+
+ * sparc-dep.c: Added an include of sparc-opcode.h.
+ * sparc-pinsn.c, sparc-opcode.h: Moved insn_fmt structures and
+ unions from pinsn.c to opcode.h.
+ * sparc-pinsn.c, sparc-dep.c (isabranch, skip_prologue): Moved
+ this function from pinsn.c to dep.c.
+
+ * Makefile: Put in warnings about compiling with gcc (non-ansi
+ include files) and compiling with shared libs on Sunos 4.0 (can't
+ debug something that's been compiled that way).
+
+ * sparc-pinsn.c: Put in a completely new file (provided by
+ Tiemann) to handle floating point disassembly, load and store
+ instructions, and etc. better. Made the modifications this file
+ (ChangeLog) list for sparc-pinsn.c again.
+
+ * symtab.c (output_source_filename): Included "more" emulation hack.
+
+ * symtab.c (output_source_filename): Initialized COLUMN to 0.
+ (sources_info): Modified to not print out a line for
+ all of the include files within a partial symtab (since
+ they have pst's of their own now). Also modified to
+ make a distinction between those pst's read in and
+ those not.
+
+ * infrun.c: Included void declaration of single_step() if it's
+ going to be used.
+ * sparc-dep.c (single_step): Moved function previous to use of it.
+
+ * Makefile: Took removal of expread.tab.c out of make clean entry
+ and put it into a new "squeakyclean" entry.
+
+Mon Dec 12 13:21:02 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * sparc-pinsn.c (skip_prologue): Changed a struct insn_fmt to a
+ union insn_fmt.
+
+ * inflow.c (terminal_inferior): Checked *all* return codes from
+ ioctl's and fcntl's in routine.
+
+ * inflow.c (terminal_inferior): Added check for sucess of
+ TIOCSPGRP ioctl call. Just notifies if bad.
+
+ * dbxread.c (symbol_file_command): Close was getting called twice;
+ once directly and once through cleanup. Killed the direct call.
+
+Sun Dec 11 19:40:40 1988 & Smith (randy at hobbes.ai.mit.edu)
+
+ * valprint.c (val_print): Deleted spurious printing of "=" from
+ TYPE_CODE_REF case.
+
+Sat Dec 10 16:41:07 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * dbxread.c: Changed allocation of psymbols from using malloc and
+ realloc to using obstacks. This means they aren't realloc'd out
+ from under the pointers to them.
+
+Fri Dec 9 10:33:24 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * sparc-dep.c inflow.c core.c expread.y command.c infrun.c
+ infcmd.c dbxread.c symmisc.c symtab.c printcmd.c valprint.c
+ values.c source.c stack.c findvar.c breakpoint.c blockframe.c
+ main.c: Various cleanups inspired by "gcc -Wall" (without checking
+ for implicit declarations).
+
+ * Makefile: Cleaned up some more.
+
+ * valops.c, m-*.h (FIX_CALL_DUMMY): Modified to take 5 arguments
+ as per what sparc needs (programming for a superset of needed
+ args).
+
+ * dbxread.c (process_symbol_for_psymtab): Modified to be slightly
+ more picky about what it puts on the list of things *not* to be
+ put on the misc function list. When/if I shift everything over to
+ being placed on the misc_function_list, this will go away.
+
+ * inferior.h, infrun.c: Added fields to save in inferior_status
+ structure.
+
+ * maketarfile: Deleted; functionality is in Makefile now.
+
+ * infrun.c (wait_for_inferior): Modified algorithm for determining
+ whether or not a single-step was through a subroutine call. See
+ comments at top of file.
+
+ * dbxread.c (read_dbx_symtab): Made sure that the IGNORE_SYMBOL
+ macro would be checked during initial readin.
+
+ * dbxread.c (read_ofile_symtab): Added macro GCC_COMPILED_FLAG_SYMBOL
+ into dbxread.c to indicate what string in a local text symbol will
+ indicate a file compiled with gcc. Defaults to "gcc_compiled.".
+
+Thu Dec 8 11:46:22 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * m-sparc.h (FRAME_FIND_SAVED_REGS): Cleaned up a little to take
+ advantage of the new frame cache system.
+
+ * inferior.h, infrun.c, valops.c, valops.c, infcmd.c: Changed
+ mechanism to save inferior status over calls to inferior (eg.
+ call_function); implemented save_inferior_info and
+ restore_inferior_info.
+
+ * blockframe.c (get_prev_frame): Simplified this by a direct call
+ to get_prev_frame_info.
+
+ * frame.h, stack.c, printcmd.c, m-sparc.h, sparc-dep.c: Removed
+ all uses of frame_id_from_addr. There are short routines like it
+ still in frame_saved_pc (m-sparc.h) and parse_frame_spec
+ (stack.c). Eventually the one in frame_saved_pc will go away.
+
+ * infcmd.c, sparc-dep.c: Implemented a new mechanism for
+ re-selecting the selected frame on return from a call.
+
+ * blockframe.c, stack.c, findvar.c, printcmd.c, m-*.h: Changed
+ all routines and macros that took a "struct frame_info" as an
+ argument to take a "struct frame_info *". Routines: findarg,
+ framechain, print_frame_args, FRAME_ARGS_ADDRESS,
+ FRAME_STRUCT_ARGS_ADDRESS, FRAME_LOCALS_ADDRESS, FRAME_NUM_ARGS,
+ FRAME_FIND_SAVED_REGS.
+
+ * frame.h, stack.c, printcmd.c, infcmd.c, findvar.c, breakpoint.c,
+ blockframe.c, xgdb.c, i386-pinsn.c, gld-pinsn.c, m-umax.h,
+ m-sun2.h, m-sun3.h, m-sparc.h, m-pn.h, m-npl.h, m-news.h,
+ m-merlin.h, m-isi.h, m-i386.h, m-hp9k320.h: Changed routines to
+ use "struct frame_info *" internally.
+
+Wed Dec 7 12:07:54 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * frame.h, blockframe.c, m-sparc.h, sparc-dep.c: Changed all calls
+ to get_[prev_]frame_cache_item to get_[prev_]frame_info.
+
+ * blockframe.c: Elminated get_frame_cache_item and
+ get_prev_frame_cache_item; functionality now taken care of by
+ get_frame_info and get_prev_frame_info.
+
+ * blockframe.c: Put allocation on an obstack and eliminated fancy
+ reallocation routines, several variables, and various nasty
+ things.
+
+ * frame.h, stack.c, infrun.c, blockframe.c, sparc-dep.c: Changed
+ type FRAME to be a typedef to "struct frame_info *". Had to also
+ change routines that returned frame id's to return the pointer
+ instead of the cache index.
+
+ * infcmd.c (finish_command): Used proper method of getting from
+ function symbol to start of function. Was treating a symbol as a
+ value.
+
+ * blockframe.c, breakpoint.c, findvar.c, infcmd.c, stack.c,
+ xgdb.c, i386-pinsn.c, frame.h, m-hp9k320.h, m-i386.h, m-isi.h,
+ m-merlin.h, m-news.h, m-npl.h, m-pn.h, m-sparc.h, m-sun2.h,
+ m-sun3.h, m-umax.h: Changed get_frame_info and get_prev_frame_info
+ to return pointers instead of structures.
+
+ * blockframe.c (get_pc_function_start): Modified to go to misc
+ function table instead of bombing if pc was in a block without a
+ containing function.
+
+ * coffread.c: Dup'd descriptor passed to read_coff_symtab and
+ fdopen'd it so that there wouldn't be multiple closes on the same
+ fd. Also put (fclose, stream) on the cleanup list.
+
+ * printcmd.c, stack.c: Changed print_frame_args to take a
+ frame_info struct as argument instead of the address of the args
+ to the frame.
+
+ * m-i386.h (STORE_STRUCT_RETURN): Decremented sp by sizeof object
+ to store (an address) rather than 1.
+
+ * dbxread.c (read_dbx_symtab): Set first_object_file_end in
+ read_dbx_symtab (oops).
+
+ * coffread.c (fill_in_vptr_fieldno): Rewrote TYPE_BASECLASS as
+ necessary.
+
+Tue Dec 6 13:03:43 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * coffread.c: Added fake support for partial_symtabs to allow
+ compilation and execution without there use.
+ * inflow.c: Added a couple of minor USG mods.
+ * munch: Put in appropriate conditionals so that it would work on
+ USG systems.
+ * Makefile: Made regex.* handled same as obstack.*; made sure tar
+ file included everything I wanted it to include (including
+ malloc.c).
+
+ * dbxread.c (end_psymtab): Create an entry in the
+ partial_symtab_list for each subfile of the .o file just read in.
+ This allows a "list expread.y:10" to work when we haven't read in
+ expread.o's symbol stuff yet.
+
+ * symtab.h, dbxread.c (psymtab_to_symtab): Recognize pst->ldsymlen
+ == 0 as indicating a dummy psymtab, only in existence to cause the
+ dependency list to be read in.
+
+ * dbxread.c (sort_symtab_syms): Elminated reversal of symbols to
+ make sure that register debug symbol decls always come before
+ parameter symbols. After mod below, this is not needed.
+
+ * symtab.c (lookup_block_symbol): Take parameter type symbols
+ (LOC_ARG or LOC_REGPARM) after any other symbols which match.
+
+ * dbxread.c (read_type): When defining a type in terms of some
+ other type and the other type is supposed to have a pointer back
+ to this specific kind of type (pointer, reference, or function),
+ check to see if *that* type has been created yet. If it has, use
+ it and fill in the appropriate slot with a pointer to it.
+
+Mon Dec 5 11:25:04 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * symmisc.c: Eliminated existence of free_inclink_symtabs and
+ init_free_inclink_symtabs; they aren't called from anywhere, and
+ if they were they could disrupt gdb's data structure badly
+ (elimination of struct type's which values that stick around past
+ elimination of inclink symtabs).
+
+ * dbxread.c (symbol_file_command): Fixed a return pathway out of
+ the routine to do_cleanups before it left.
+
+ * infcmd.c (set_environment_command), gdb.texinfo: Added
+ capability to set environmental variable values to null.
+
+ * gdb.texinfo: Modified doc on "break" without args slightly.
+
+Sun Dec 4 17:03:16 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * dbxread.c (symbol_file_command): Added check; if there weren't
+ any debugging symbols in the file just read, the user is warned.
+
+ * infcmd.c: Commented set_environment_command (a little).
+
+ * createtags: Cleaned up and commented.
+
+ * Makefile: Updated dependency list and cleaned it up somewhat
+ (used macros, didn't make .o files depend on .c files, etc.)
+
+Fri Dec 2 11:44:46 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * value.h, values.c, infcmd.c, valops.c, m-i386.h, m-sparc.h,
+ m-merlin.h, m-npl.h, m-pn.h, m-umax.h, m-vax.h, m-hp9k320.h,
+ m-isi.h, m-news.h, m-sun2.h, m-sun3.h: Cleaned up dealings with
+ functions returning structures. Specifically: Added a function
+ called using_struct_return which indicates whether the function
+ being called is using the structure returning conventions or it is
+ using the value returning conventions on that machine. Added a
+ macro, STORE_STRUCT_RETURN to store the address of the structure
+ to be copied into wherever it's supposed to go, and changed
+ call_function to handle all of this correctly.
+
+ * symseg.h, symtab.h, dbxread.c: Added hooks to recognize an
+ N_TEXT symbol with name "*gcc-compiled*" as being a flag
+ indicating that a file had been compiled with gcc and setting a
+ flag in all blocks produced during processing of that file.
+
+Thu Dec 1 13:54:29 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * m-sparc.h (PUSH_DUMMY_FRAME): Saved 8 less than the current pc,
+ as POP_FRAME and sparc return convention restore the pc to 8 more
+ than the value saved.
+
+ * valops.c, printcmd.c, findvar.c, value.h: Added the routine
+ value_from_register, to access a specific register of a specific
+ frame as containing a specific type, and used it in read_var_value
+ and print_frame_args.
+
+Wed Nov 30 17:39:50 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * dbxread.c (read_number): Will accept either the argument passed
+ as an ending character, or a null byte as an ending character.
+
+ * Makefile, createtags: Added entry to create tags for gdb
+ distribution which will make sure currently configured machine
+ dependent files come first in the list.
+
+Wed Nov 23 13:27:34 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * stack.c, infcmd.c, sparc-dep.c: Modified record_selected_frame
+ to work off of frame address.
+
+ * blockframe.c (create_new_frame, get_prev_frame_cache_item):
+ Added code to reset pointers within frame cache if it must be
+ realloc'd.
+
+ * dbxread.c (read_dbx_symtab): Added in optimization comparing
+ last couple of characters instead of first couple to avoid
+ strcmp's in read_dbx_symtab (recording extern syms in misc
+ functions or not). 1 call to strlen is balanced out by many fewer
+ calls to strcmp.
+
+Tue Nov 22 16:40:14 1988 Randall Smith (randy at cream-of-wheat.ai.mit.edu)
+
+ * dbxread.c (read_dbx_symtab): Took out optimization for ignoring
+ LSYM's; was disallowing typedefs. Silly me.
+
+ * Checkpointed distribution (mostly for sending to Tiemann).
+
+ * expression.h: Added BINOP_MIN and BINOP_MAX operators for C++.
+ * symseg.h: Included flags for types having destructors and
+ constructors, and flags being defined via public and via
+ virtual paths. Added fields NEXT_VARIANT, N_BASECLASSES,
+ and BASECLASSES to this type (tr: Changed types from
+ having to be derived from a single baseclass to a multiple
+ base class).
+ * symtab.h: Added macros to access new fields defined in symseg.h.
+ Added decl for lookup_basetype_type.
+ * dbxread.c
+ (condense_addl_misc_bunches): Function added to condense the misc
+ function bunches added by reading in a new .o file.
+ (read_addl_syms): Function added to read in symbols
+ from a new .o file (incremental linking).
+ (add_file_command): Command interface function to indicate
+ incrmental linking of a new .o file; this now calls
+ read_addl_syms and condense_addl_misc_bunches.
+ (define_symbol): Modified code to handle types defined from base
+ types which were not known when the derived class was
+ output.
+ (read_struct_type): Modified to better handle description of
+ struct types as derived types. Possibly derived from
+ several different base classes. Also added new code to
+ mark definitions via virtual paths or via public paths.
+ Killed seperate code to handle classes with destructors
+ but without constructors and improved marking of classes
+ as having destructors and constructors.
+ * infcmd.c: Modified call to val_print (one more argument).
+ * symtab.c (lookup_member_type): Modified to deal with new
+ structure in symseg.h.
+ (lookup_basetype_type): Function added to find or construct a type
+ ?derived? from the given type.
+ (decode_line_1): Modified to deal with new type data structures.
+ Modified to deal with new number of args for
+ decode_line_2.
+ (decode_line_2): Changed number of args (?why?).
+ (init_type): Added inits for new C++ fields from
+ symseg.h.
+ *valarith.c
+ (value_x_binop, value_binop): Added cases for BINOP_MIN &
+ BINOP_MAX.
+ * valops.c
+ (value_struct_elt, check_field, value_struct_elt_for_address):
+ Changed to deal with multiple possible baseclasses.
+ (value_of_this): Made SELECTED_FRAME an extern variable.
+ * valprint.c
+ (val_print): Added an argument DEREF_REF to dereference references
+ automatically, instead of printing them like pointers.
+ Changed number of arguments in recursive calls to itself.
+ Changed to deal with varibale numbers of base classes.
+ (value_print): Changed number of arguments to val_print. Print
+ type of value also if value is a reference.
+ (type_print_derivation_info): Added function to print out
+ derivation info a a type.
+ (type_print_base): Modified to use type_print_derivation_info and
+ to handle multiple baseclasses.
+
+Mon Nov 21 10:32:07 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * inflow.c (term_status_command): Add trailing newline to output.
+
+ * sparc-dep.c (do_save_insn, do_restore_insn): Saved
+ "stop_registers" over the call for the sake of normal_stop and
+ run_stack_dummy.
+
+ * m-sparc.h (EXTRACT_RETURN_VALUE): Put in parenthesis to force
+ addition of 8 to the int pointer, not the char pointer.
+
+ * sparc-pinsn.c (print_addr1): Believe that I have gotten the
+ syntax right for loads and stores as adb does it.
+
+ * symtab.c (list_symbols): Turned search for match on rexegp into
+ a single loop.
+
+ * dbxread.c (psymtab_to_symtab): Don't read it in if it's already
+ been read in.
+
+ * dbxread.c (psymtab_to_symtab): Changed error to fatal in
+ psymtab_to_symtab.
+
+ * expread.y (parse_number): Fixed bug which treated 'l' at end of
+ number as '0'.
+
+Fri Nov 18 13:57:33 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * dbxread.c (read_dbx_symtab, process_symbol_for_psymtab): Was
+ being foolish and using pointers into an array I could realloc.
+ Converted these pointers into integers.
+
+Wed Nov 16 11:43:10 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * m-sparc.h (POP_FRAME): Made the new frame be PC_ADJUST of the
+ old frame.
+
+ * i386-pinsn.c, m-hp9k320.h, m-isi.h, m-merlin.h, m-news.h,
+ m-npl.h, m-pn.h, m-sparc.h, m-sun2.h, m-sun3.h, m-umax.h, m-vax.h:
+ Modified POP_FRAME to use the current frame instead of
+ read_register (FP_REGNUM) and to flush_cached_frames before
+ setting the current frame. Also added a call to set the current
+ frame in those POP_FRAMEs that didn't have it.
+
+ * infrun.c (wait_for_inferior): Moved call to set_current_frame up
+ to guarrantee that the current frame will always be set when a
+ POP_FRAME is done.
+
+ * infrun.c (normal_stop): Added something to reset the pc of the
+ current frame (was incorrect because of DECR_PC_AFTER_BREAK).
+
+ * valprint.c (val_print): Changed to check to see if a string was
+ out of bounds when being printed and to indicate this if so.
+
+ * convex-dep.c (read_inferior_memory): Changed to return the value
+ of errno if the call failed (which will be 0 if the call
+ suceeded).
+
+Tue Nov 15 10:17:15 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * infrun.c (wait_for_inferior): Two changes: 1) Added code to
+ not trigger the step breakpoint on recursive calls to functions
+ without frame info, and 2) Added calls to distinguish recursive
+ calls within a function without a frame (which next/nexti might
+ wish to step over) from jumps to the beginning of a function
+ (which it generally doesn't).
+
+ * m-sparc.h (INIT_EXTRA_FRAME_INFO): Bottom set correctly for leaf
+ parents.
+
+ * blockframe.c (get_prev_frame_cache_item): Put in mod to check
+ for a leaf node (by presence or lack of function prologue). If
+ there is a leaf node, it is assumed that SAVED_PC_AFTER_CALL is
+ valid. Otherwise, FRAME_SAVED_PC or read_pc is used.
+
+ * blockframe.c, frame.h: Did final deletion of unused routines and
+ commented problems with getting a pointer into the frame cache in
+ the frame_info structure comment.
+
+ * blockframe.c, frame.h, stack.c: Killed use of
+ frame_id_from_frame_info; used frame_id_from_addr instead.
+
+ * blockframe.c, frame.h, stack.c, others (oops): Combined stack
+ cache and frame info structures.
+
+ * blockframe.c, sparc-dep.c, stack.c: Created the function
+ create_new_frame and used it in place of bad calls to
+ frame_id_from_addr.
+
+ * blockframe.c, inflow.c, infrun.c, i386-pinsn.c, m-hp9k320.h,
+ m-npl.h, m-pn.h, m-sparc.h, m-sun3.h, m-vax.h, default-dep.c,
+ convex-dep.c, gould-dep.c, hp9k320-dep.c, news-dep.c, sparc-dep.c,
+ sun3-dep.c, umax-dep.c: Killed use of
+ set_current_Frame_by_address. Used set_current_frame
+ (create_new_frame...) instead.
+
+ * frame.h: Killed use of FRAME_FP_ID.
+
+ * infrun.c, blockframe.c: Killed select_frame_by_address. Used
+ select_frame (get_current_frame (), 0) (which was correct in all
+ cases that we need to worry about.
+
+Mon Nov 14 14:19:32 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * frame.h, blockframe.c, stack.c, m-sparc.h, sparc-dep.c: Added
+ mechanisms to deal with possible specification of frames
+ dyadically.
+
+Sun Nov 13 16:03:32 1988 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * ns32k-opcode.h: Add insns acbw, acbd.
+
+Sun Nov 13 15:09:58 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * breakpoint.c: Changed breakpoint structure to use the address of
+ a given frame (constant across inferior runs) as the criteria for
+ stopping instead of the frame ident (which varies across inferior
+ calls).
+
+Fri Nov 11 13:00:22 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * gld-pinsn.c (findframe): Modified to work with the new frame
+ id's. Actually, it looks as if this routine should be called with
+ an address anyway.
+
+ * findvar.c (find_saved_register): Altered bactrace loop to work
+ off of frames and not frame infos.
+
+ * frame.h, blockframe.c, stack.c, sparc-dep.c, m-sparc.h: Changed
+ FRAME from being the address of the frame to being a simple ident
+ which is an index into the frame_cache_item list.
+ * convex-dep.c, default-dep.c, gould-dep.c, hp9k320-dep.c,
+ i386-pinsn.c, inflow.c, infrun.c, news-dep.c, sparc-dep.c,
+ sun3-dep.c, umax-dep.c, m-hp9k320.h, m-npl.h, m-pn.h, m-sparc.h,
+ m-sun3.h, m-vax.h: Changed calls of the form set_current_frame
+ (read_register (FP_REGNUM)) to set_current_frame_by_address (...).
+
+Thu Nov 10 16:57:57 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * frame.h, blockframe.c, gld-pinsn.c, sparc-dep.c, stack.c,
+ infrun.c, findvar.c, m-sparc.h: Changed the FRAME type to be
+ purely an identifier, using FRAME_FP and FRAME_FP_ID to convert
+ back and forth between the two. The identifier is *currently*
+ still the frame pointer value for that frame.
+
+Wed Nov 9 17:28:14 1988 Chris Hanson (cph at kleph)
+
+ * m-hp9k320.h (FP_REGISTER_ADDR): Redefine this to return
+ difference between address of given FP register, and beginning of
+ `struct user' that it occurs in.
+
+ * hp9k320-dep.c (core_file_command): Fix sign error in size
+ argument to myread. Change buffer argument to pointer; was
+ copying entire structure.
+ (fetch_inferior_registers, store_inferior_registers): Replace
+ occurrences of `FP_REGISTER_ADDR_DIFF' with `FP_REGISTER_ADDR'.
+ Flush former definition.
+
+Wed Nov 9 12:11:37 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * xgdb.c: Killed include of initialize.h.
+
+ * Pulled in xgdb.c from the net.
+
+ * Checkpointed distribution (to provide to 3b2 guy).
+
+ * coffread.c, dbxread.c, symmisc.c, symtab.c, symseg.h: Changed
+ format of table of line number--pc mapping information. Can
+ handle negative pc's now.
+
+ * command.c: Deleted local copy of savestring; code in utils.c is
+ identical.
+
+Tue Nov 8 11:12:16 1988 Randall Smith (randy at plantaris.ai.mit.edu)
+
+ * gdb.texinfo: Added documentation for shell escape.
+
+Mon Nov 7 12:27:16 1988 Randall Smith (randy at sugar-bombs.ai.mit.edu)
+
+ * command.c: Added commands for shell escape.
+
+ * core.c, dbxread.c: Added ROBOTUSSIN mods.
+
+ * Checkpointed distribution.
+
+ * printcmd.c (x_command): Yanked error if there is no memory to
+ examine (could be looking at executable straight).
+
+ * sparc-pinsn.c (print_insn): Amount to leftshift sethi imm by is
+ now 10 (matches adb in output).
+
+ * printcmd.c (x_command): Don't attempt to set $_ & $__ if there
+ is no last_examine_value (can happen if you did an x/0).
+
+Fri Nov 4 13:44:49 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * printcmd.c (x_command): Error if there is no memory to examine.
+
+ * gdb.texinfo: Added "cont" to the command index.
+
+ * sparc-dep.c (do_save_insn): Fixed typo in shift amount.
+
+ * m68k-opcode.h: Fixed opcodes for 68881.
+
+ * breakpoint.c, infcmd.c, source.c: Changed defaults in several
+ places for decode_line_1 to work off of the default_breakpoint_*
+ values instead of current_source_* values (the current_source_*
+ values are off by 5 or so because of listing defaults).
+
+ * stack.c (frame_info): ifdef'd out FRAME_SPECIFCATION_DYADIC in
+ the stack.c module. If I can't do this right, I don't want to do
+ it at all. Read the comment there for more info.
+
+Mon Oct 31 16:23:06 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * gdb.texinfo: Added documentation on the "until" command.
+
+Sat Oct 29 17:47:10 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * breakpoint.c, infcmd.c: Added UNTIL_COMMAND and subroutines of
+ it.
+
+ * breakpoint.c, infcmd.c, infrun.c: Added new field to breakpoint
+ structure (silent, indicating a silent breakpoint), and modified
+ breakpoint_stop_status and things that read it's return value to
+ understand it.
+
+Fri Oct 28 17:45:33 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * dbxread.c, symmisc.c: Assorted speedups for readin, including
+ special casing most common symbols, and doing buffering instead of
+ calling malloc.
+
+Thu Oct 27 11:11:15 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * stack.c, sparc-dep.c, m-sparc.h: Modified to allow "info frame"
+ to take two arguments on the sparc and do the right thing with
+ them.
+
+ * dbxread.c (read_dbx_symtab, process_symbol_for_psymtab): Put
+ stuff to put only symbols that didn't have debugging info on the
+ misc functions list back in.
+
+Wed Oct 26 10:10:32 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * valprint.c (type_print_varspec_suffix): Added check for
+ TYPE_LENGTH(TYPE_TARGET_TYPE(type)) > 0 to prevent divide by 0.
+
+ * printcmd.c (print_formatted): Added check for VALUE_REPEATED;
+ value_print needs to be called for that.
+
+ * infrun.c (wait_for_inferior): Added break when you decide to
+ stop on a null function prologue rather than continue stepping.
+
+ * m-sun3.h: Added explanatory comment to REGISTER_RAW_SIZE.
+
+ * expread.y (parse_c_1): Initialized paren_depth for each parse.
+
+Tue Oct 25 14:19:38 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * valprint.c, coffread.c, dbxread.c: Enum constant values in enum
+ type now accessed through TYPE_FIELD_BITPOS.
+
+ * dbxread.c (process_symbol_for_psymtab): Added code to deal with
+ possible lack of a ":" in a debugging symbol (do nothing).
+
+ * symtab.c (decode_line_1): Added check in case of all numbers for
+ complete lack of symbols.
+
+ * source.c (select_source_symtab): Made sure that this wouldn't
+ bomb on complete lack of symbols.
+
+Mon Oct 24 12:28:29 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * m-sparc.h, findvar.c: Ditched REGISTER_SAVED_UNIQUELY and based
+ code on REGISTER_IN_WINDOW_P and HAVE_REGISTER_WINDOWS. This will
+ break when we find a register window machine which saves the
+ window registers within the context of an inferior frame.
+
+ * sparc-dep.c (frame_saved_pc): Put PC_ADJUST return back in for
+ frame_saved_pc. Seems correct.
+
+ * findvar.c, m-sparc.h: Created the macro REGISTER_SAVED_UNIQUELY
+ to handle register window issues (ie. that find_saved_register
+ wasn't checking the selected frame itself for shit).
+
+ * sparc-dep.c (core_file_command): Offset target of o & g register
+ bcopy by 1 to hit correct registers.
+
+ * m-sparc.h: Changed STACK_END_ADDR.
+
+Sun Oct 23 19:41:51 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * sparc-dep.c (core_file_command): Added in code to get the i & l
+ registers from the stack in the corefile, and blew away some wrong
+ code to get i & l from inferior.
+
+Fri Oct 21 15:09:19 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * m-sparc.h (PUSH_DUMMY_FRAME): Saved the value of the RP register
+ in the location reserved for i7 (in the created frame); this way
+ the rp value won't get lost. The pc (what we put into the rp in
+ this routine) gets saved seperately, so we loose no information.
+
+ * sparc-dep.c (do_save_insn & do_restore_insn): Added a wrapper to
+ preserve the proceed status state variables around each call to
+ proceed (the current frame was getting munged because this wasn't
+ being done).
+
+ * m-sparc.h (FRAME_FIND_SAVED_REGS): Fix bug: saved registers
+ addresses were being computed using absolute registers number,
+ rather than numbers relative to each group of regs.
+
+ * m-sparc.h (POP_FRAME): Fixed a bug (I hope) in the context
+ within which saved reg numbers were being interpetted. The
+ values to be restored were being gotten in the inferior frame, and
+ the restoring was done in the superior frame. This means that i
+ registers must be restored into o registers.
+
+ * sparc-dep.c (do_restore_insn): Modified to take a pc as an
+ argument, instead of a raw_buffer. This matches (at least it
+ appears to match) usage from POP_FRAME, which is the only place
+ from which do_restore_insn is called.
+
+ * sparc-dep.c (do_save_insn and do_restore_insn): Added comments.
+
+ * m-sparc.h (FRAME_FIND_SAVED_REGS): Modified my code to find the
+ save addresses of out registers to use the in regs off the stack
+ pointer when the current frame is 1 from the innermost.
+
+Thu Oct 20 13:56:15 1988 & Smith (randy at hobbes.ai.mit.edu)
+
+ * blockframe.c, m-sparc.h: Removed code associated with
+ GET_PREV_FRAME_FROM_CACHE_ITEM. This code was not needed for the
+ sparc; you can always find the previous frames fp from the fp of
+ the current frame (which is the sp of the previous). It's getting
+ the information associated with a given frame (ie. saved
+ registers) that's a bitch, because that stuff is saved relative to
+ the stack pointer rather than the frame pointer.
+
+ * m-sparc.h (GET_PREV_FRAME_FROM_CACHE_ITEM): Modified to return
+ the frame pointer of the previous frame instead of the stack
+ pointer of same.
+
+ * blockframe.c (flush_cached_frames): Modified call to
+ obstack_free to free back to frame_cache instead of back to zero.
+ This leaves the obstack control structure in finite state (and
+ still frees the entry allocated at frame_cache).
+
+Sat Oct 15 16:30:47 1988 & Smith (randy at tartarus.uchicago.edu)
+
+ * valops.c (call_function): Suicide material here. Fixed a typo;
+ CALL_DUMMY_STACK_ADJUST was spelled CAll_DUMMY_STACK_ADJUST on
+ line 530 of the file. This cost me three days. I'm giving up
+ typing for lent.
+
+Fri Oct 14 15:10:43 1988 & Smith (randy at tartarus.uchicago.edu)
+
+ * m-sparc.h: Corrected a minor mistake in the dummy frame code
+ that was getting the 5th argument and the first argument from the
+ same place.
+
+Tue Oct 11 11:49:33 1988 & Smith (randy at tartarus.uchicago.edu)
+
+ * infrun.c: Made stop_after_trap and stop_after_attach extern
+ instead of static so that code which used proceed from machine
+ dependent files could fiddle with them.
+
+ * blockframe.c, frame.h, sparc-dep.c, m-sparc.h: Changed sense of
+ ->prev and ->next in struct frame_cache_item to fit usage in rest
+ of gdb (oops).
+
+Mon Oct 10 15:32:42 1988 Randy Smith (randy at gargoyle.uchicago.edu)
+
+ * m-sparc.h, sparc-dep.c, blockframe.c, frame.h: Wrote
+ get_frame_cache_item. Modified FRAME_SAVED_PC and frame_saved_pc
+ to take only one argument and do the correct thing with it. Added
+ the two macros I recently defined in blockframe.c to m-sparc.h.
+ Have yet to compile this thing on a sparc, but I've now merged in
+ everything that I received from tiemann, either exactly, or simply
+ effectively.
+
+ * source.c: Added code to allocated space to sals.sals in the case
+ where no line was specified.
+
+ * blockframe.c, infrun.c: Modified to cache stack frames requested
+ to minimize accesses to subprocess.
+
+Tue Oct 4 15:10:39 1988 Randall Smith (randy at cream-of-wheat.ai.mit.edu)
+
+ * config.gdb: Added sparc.
+
+Mon Oct 3 23:01:22 1988 Randall Smith (randy at cream-of-wheat.ai.mit.edu)
+
+ * Makefile, blockframe.c, command.c, core.c, dbxread.c, defs.h,
+ expread.y, findvar.c, infcmd.c, inflow.c, infrun.c, sparc-pinsn.c,
+ m-sparc.h, sparc-def.c, printcmd.c, stack.c, symmisc.c, symseg.h,
+ valops.c, values.c: Did initial merge of sparc port. This will
+ not compile; have to do stack frame caching and finish port.
+
+ * inflow.c, gdb.texinfo: `tty' now resets the controling terminal.
+
+Fri Sep 30 11:31:16 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * inferior.h, infcmd.c, infrun.c: Changed the variable
+ stop_random_signal to stopped_by_random signal to fit in better
+ with name conventions (variable is not a direction to the
+ proceed/resume set; it is information from it).
+
+Thu Sep 29 13:30:46 1988 Randall Smith (randy at cream-of-wheat.ai.mit.edu)
+
+ * infcmd.c (finish_command): Value type of return value is now
+ whatever the function returns, not the type of the function (fixed
+ a bug in printing said value).
+
+ * dbxread.c (read_dbx_symtab, process_symbol_for_psymtab):
+ Put *all* global symbols into misc_functions. This is what was
+ happening anyway, and we need it for find_pc_misc_function.
+
+ ** This was eventually taken out, but I didn't mark it in the
+ ChangeLog. Oops.
+
+ * dbxread.c (process_symbol_for_psymtab): Put every debugger
+ symbol which survives the top case except for constants on the
+ symchain. This means that all of these *won't* show up in misc
+ functions (this will be fixed once I make sure it's broken the way
+ it's supposed to be).
+
+ * dbxread.c: Modified placement of debugger globals onto the hash
+ list; now we exclude the stuff after the colon and don't skip the
+ first character (debugger symbols don't have underscores).
+
+ * dbxread.c: Killed debuginfo stuff with ifdef's.
+
+Wed Sep 28 14:31:51 1988 Randall Smith (randy at cream-of-wheat.ai.mit.edu)
+
+ * symtab.h, dbxread.c: Modified to deal with BINCL, EINCL, and
+ EXCL symbols produced by the sun loader by adding a list of
+ pre-requisite partial_symtabs that each partial symtab needs.
+
+ * symtab.h, dbxread.c, symtab.c, symmisc.c: Modified to avoid
+ doing a qsort on the local (static) psymbols for each file to
+ speed startup. This feature is not completely debugged, but it's
+ inclusion has forced the inclusion of another feature (dealing
+ with EINCL's, BINCL's and EXCL's) and so I'm going to go in and
+ deal with them.
+
+ * dbxread.c (process_symbol_for_psymtab): Made sure that the class
+ of the symbol made it into the partial_symbol entry.
+
+Tue Sep 27 15:10:26 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * dbxread.c: Fixed bug; init_psymbol_list was not being called
+ with the right number of arguments (1).
+
+ * dbxread.c: Put ifdef's around N_MAIN, N_M2C, and N_SCOPE to
+ allow compilation on a microvax.
+
+ * config.gdb: Modified so that "config.gdb vax" would work.
+
+ * dbxread.c, symtab.h, symmisc.h, symtab.c, source.c: Put in many
+ and varied hacks to speed up gdb startup including: A complete
+ rewrite of read_dbx_symtab, a modification of the partial_symtab
+ data type, deletion of select_source_symtab from
+ symbol_file_command, and optimiztion of the call to strcmp in
+ compare_psymbols.
+
+Thu Sep 22 11:08:54 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * dbxread.c (psymtab_to_symtab): Removed call to
+ init_misc_functions.
+
+ * dbxread.c: Fixed enumeration type clash (used enum instead of
+ integer constant).
+
+ * breakpoint.c: Fixed typo; lack of \ at end of line in middle of
+ string constant.
+
+ * symseg.h: Fixed typo; lack of semicolon after structure
+ definition.
+
+ * command.c, breakpoint.c, printcmd.c: Added cmdlist editing
+ functions to add commands with the abbrev flag set. Changed
+ help_cmd_list to recognize this flag and modified unset,
+ undisplay, and enable, disable, and delete breakpoints to have
+ this flag set.
+
+Wed Sep 21 13:34:19 1988 Randall Smith (randy at plantaris.ai.mit.edu)
+
+ * breakpoint.c, infcmd.c, gdb.texinfo: Created "unset" as an alias
+ for delete, and changed "unset-environment" to be the
+ "environment" subcommand of "delete".
+
+ * gdb.texinfo, valprint.c: Added documentation in the manual for
+ breaking the set-* commands into subcommands of set. Changed "set
+ maximum" to "set array-max".
+
+ * main.c, printcmd.c, breakpoint.c: Moved the declaration of
+ command lists into main and setup a function in main initializing
+ them to guarrantee that they would be initialized before calling
+ any of the individual files initialize routines.
+
+ * command.c (lookup_cmd): A null string subcommand is treated as
+ an unknown subcommand rather than an ambiguous one (eg. "set $x =
+ 1" will now work).
+
+ * infrun.c (wait_for_inferior): Put in ifdef for Sony News in
+ check for trap by INNER_THAN macro.
+
+ * eval.c (evaluate_subexp): Put in catch to keep the user from
+ attempting to call a non function as a function.
+
+Tue Sep 20 10:35:53 1988 Randall Smith (randy at oatmeal.ai.mit.edu)
+
+ * dbxread.c (read_dbx_symtab): Installed code to keep track of
+ which global symbols did not have debugger symbols refering to
+ them, and recording these via record_misc_function.
+
+ * dbxread.c: Killed code to check for extra global symbols in the
+ debugger symbol table.
+
+ * printcmd.c, breakpoint.c: Modified help entries for several
+ commands to make sure that abbreviations were clearly marked and
+ that the right commands showed up in the help listings.
+
+ * main.c, command.c, breakpoint.c, infcmd.c, printcmd.c,
+ valprint.c, defs.h: Modified help system to allow help on a class
+ name to show subcommands as well as commands and help on a command
+ to show *all* subcommands of that command.
+
+Fri Sep 16 16:51:19 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * breakpoint.c (_initialize_breakpoint): Made "breakpoints"
+ subcommands of enable, disable, and delete use class 0 (ie. they
+ show up when you do a help xxx now).
+
+ * infcmd.c,printcmd,c,main.c,valprint.c: Changed the set-*
+ commands into subcommands of set. Created "set variable" for use
+ with variables whose names might conflict with other subcommands.
+
+ * blockframe.c, dbxread.c, coffread.c, expread.y, source.c:
+ Fixed mostly minor (and one major one in block_for_pc) bugs
+ involving checking the partial_symtab_list when a scan through the
+ symtab_list fails.
+
+Wed Sep 14 12:02:05 1988 Randall Smith (randy at sugar-smacks.ai.mit.edu)
+
+ * breakpoint.c, gdb.texinfo: Added enable breakpoints, disable
+ breakpoints and delete breakpoints as synonyms for enable,
+ disable, and delete. This seemed reasonable because of the
+ immeninent arrival of watchpoints & etc.
+
+ * gdb.texinfo: Added enable display, disable display, and delete
+ display to manual.
+
+Tue Sep 13 16:53:56 1988 Randall Smith (randy at sugar-smacks.ai.mit.edu)
+
+ * inferior.h, infrun.c, infcmd.c: Added variable
+ stop_random_signal to indicate when a proceed had been stopped by
+ an unexpected signal. Used this to determine (in normal_stop)
+ whether the current display point should be deleted.
+
+ * valops.c: Fix to value_ind to check for reference before doing a
+ COERCE_ARRAY.
+
+Sun Jul 31 11:42:36 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu)
+
+ * breakpoint.c (_initialize_breakpoint): Clean up doc for commands
+ that can now apply also to auto-displays.
+
+ * coffread.c (record_line): Corrected a spazz in editing.
+ Also removed the two lines that assume line-numbers appear
+ only in increasing order.
+
+Tue Jul 26 22:19:06 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * expression.h, eval.c, expprint.c, printcmd.c, valarith.c,
+ valops.c, valprint.c, values.c, m-*.h: Changes for evaluating and
+ displaying 64-bit `long long' integers. Each machine must define
+ a LONGEST type, and a BUILTIN_TYPE_LONGEST.
+
+ * symmisc.c: (print_symtab) check the status of the fopen and call
+ perror_with_name if needed.
+
+Thu Jul 21 00:56:11 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * Convex: core.c: changes required by Convex's SOFF format were
+ isolated in convex-dep.c.
+
+Wed Jul 20 21:26:10 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * coffread.c, core.c, expread.y, i386-pinsn.c, infcmd.c, inflow.c,
+ infrun.c, m-i386.h, main.c, remote.c, source.c, valops.c:
+ Improvements for the handling of the i386 and other machines
+ running USG. (Several of these files just needed extra header files
+ such as types.h.) utils.c: added bcopy, bcmp, bzero, getwd, list
+ of signals, and queue routines for USG systems. Added vfork macro
+ to i386
+
+ * printcmd.c, breakpoint.c: New commands to enable/disable
+ auto-displays. Also `delete display displaynumber' works like
+ `undisplay displaynumber'.
+
+Tue Jul 19 02:17:18 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * coffread.c: (coff_lookup_type) Wrong portion of type_vector was
+ being bzero'd after type_vector was reallocated.
+
+ * printcmd.c: (delete_display) Check for a display chain before
+ attempting to delete a display.
+
+ * core.c, *-dep.c (*-infdep moved to *-dep): machine-dependent
+ parts of core.c (core_file_command, exec_file_command) moved to
+ *-dep.c.
+
+Mon Jul 18 19:45:51 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * dbxread.c: typo in read_struct_type (missing '=') was causing a
+ C struct to be parsed as a C++ struct, resulting in a `invalid
+ character' message.
+
+Sun Jul 17 22:27:32 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * printcmd.c, symtab.c, valops.c, expread.y: When an expression is
+ read, the innermost block required to evaluate the expression is
+ saved in the global variable `innermost_block'. This information
+ is saved in the `block' field of an auto-display so that
+ expressions with inactive variables can be skipped. `info display'
+ tells the user which displays are active and which are not. New
+ fn `contained_in' returns nonzero if one block is contained within
+ another.
+
+Fri Jul 15 01:53:14 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * infrun.c, m-i386.h: Use macro TRAPS_EXPECTED to set number of
+ traps to skip when sh execs the program. Default is 2, m-i386.h
+ overrides this and sets to 4.
+
+ * coffread.c, infrun.c: minor changes for the i386. May be able
+ to eliminate them with more general code.
+
+ * default-infdep.c: #ifdef SYSTEMV, include header file types.h.
+ Also switched the order of signal.h and user.h, since System 5
+ requires signal.h to come first.
+
+ * core.c main.c, remote,c, source.c, inflow.c: #ifdef SYSTEMV,
+ include various header files. Usually types.h and fcntl.h.
+
+ * utils.c: added queue routines needed by the i386 (and other sys
+ 5 machines).
+
+ * sys5.c, regex.c, regex.h: new files for sys 5 systems. (The
+ regex files are simply links to /gp/gnu/lib.)
+
+Thu Jul 14 01:47:14 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * config.gdb, README: Provide a list of known machines when user
+ enters an invalid machine. New second arg is operating system,
+ currently only used with `sunos4' or `os4'. Entry for i386 added.
+
+ * news-infdep.c: new file.
+
+ * m-news.h: new version which deals with new bugs in news800's OS.
+
+Tue Jul 12 19:52:16 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * Makefile, *.c, munch, config.gdb, README: New initialization
+ scheme uses nm to find functions whose names begin with
+ `_initialize_'. Files `initialize.h', `firstfile.c',
+ `lastfile.c', `m-*init.h' no longer needed.
+
+ * eval.c, symtab.c, valarith.c, valops.c, value.h, values.c: Bug
+ fixes from gdb+ 2.5.4. evaluate_subexp takes a new arg, type
+ expected. New fn value_virtual_fn_field.
+
+Mon Jul 11 00:48:49 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * core.c (read_memory): xfer_core_file was being called with an
+ extra argument (0) by read_memory.
+
+ * core.c (read_memory), *-infdep.c (read_inferior_memory),
+ valops.c (value_at): read_memory and read_inferior_memory now work
+ like write_memory and write_inferior_memory in that errno is
+ checked after each ptrace and returned to the caller. Used in
+ value_at to detect references to addresses which are out of
+ bounds. Also core.c (xfer_core_file): return 1 if invalid
+ address, 0 otherwise.
+
+ * inflow.c, <machine>-infdep.c: removed all calls to ptrace from
+ inflow.c and put them in machine-dependent files *-infdep.c.
+
+Sun Jul 10 19:19:36 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * symmisc.c: (read_symsegs) Accept only format number 2. Since
+ the size of the type structure changed when C++ support was added,
+ format 1 can no longer be used.
+
+ * core.c, m-sunos4.h: (core_file_command) support for SunOS 4.0.
+ Slight change in the core structure. #ifdef SUNOS4. New file
+ m-sunos4.h. May want to change config.gdb also.
+
+Fri Jul 8 19:59:49 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * breakpoint.c: (break_command_1) Allow `break if condition'
+ rather than parsing `if' as a function name and returning an
+ error.
+
+Thu Jul 7 22:22:47 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * C++: valops.c, valprint.c, value.h, values.c: merged code to deal
+ with C++ expressions.
+
+Wed Jul 6 03:28:18 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * C++: dbxread.c: (read_dbx_symtab, condense_misc_bunches,
+ add_file_command) Merged code to read symbol information from
+ an incrementally linked file. symmisc.c:
+ (init_free_inclink_symtabs, free_inclink_symtabs) Cleanup
+ routines.
+
+Tue Jul 5 02:50:41 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * C++: symtab.c, breakpoint.c, source.c: Merged code to deal with
+ ambiguous line specifications. In C++ one can have overloaded
+ function names, so that `list classname::overloadedfuncname'
+ refers to several different lines, possibly in different files.
+
+Fri Jul 1 02:44:20 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu)
+
+ * C++: symtab.c: replaced lookup_symtab_1 and lookup_symtab_2 with
+ a modified lookup_symbol which checks for fields of the current
+ implied argument `this'. printcmd.c, source.c, symtab.c,
+ valops.c: Need to change callers once callers are
+ installed.
+
+Wed Jun 29 01:26:56 1988 Peter TerMaat (pete at frosted-flakes.ai.mit.edu)
+
+ * C++: eval.c, expprint.c, expread.y, expression.h, valarith.c,
+ Merged code to deal with evaluation of user-defined operators,
+ member functions, and virtual functions.
+ binop_must_be_user_defined tests for user-defined binops,
+ value_x_binop calls the appropriate operator function.
+
+Tue Jun 28 02:56:42 1988 Peter TerMaat (pete at frosted-flakes.ai.mit.edu)
+
+ * C++: Makefile: changed the echo: expect 101 shift/reduce conflicts
+ and 1 reduce/reduce conflict.
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/MAINTAINERS b/gdb/MAINTAINERS
new file mode 100644
index 00000000000..8b80d417c6e
--- /dev/null
+++ b/gdb/MAINTAINERS
@@ -0,0 +1,437 @@
+ GDB Maintainers
+
+
+ Blanket Write Privs
+ (alphabetic)
+
+Jim Blandy jimb@redhat.com
+Kevin Buettner kevinb@redhat.com
+Andrew Cagney ac131313@redhat.com
+J.T. Conklin jtc@redback.com
+Fred Fish fnf@ninemoons.com
+Mark Kettenis kettenis@gnu.org
+Peter Schauer Peter.Schauer@regent.e-technik.tu-muenchen.de
+Stan Shebs shebs@apple.com
+Michael Snyder msnyder@redhat.com
+Elena Zannoni ezannoni@redhat.com
+Eli Zaretskii eliz@gnu.org
+
+
+ Various Maintainers
+
+Note individuals who maintain parts of the debugger need approval to
+check in changes outside of the immediate domain that they maintain.
+
+If there is no maintainer for a given domain then the responsibility
+falls to the head maintainer.
+
+If there are several maintainers for a given domain then
+responsibility falls to the first maintainer. The first maintainer is
+free to devolve that responsibility among the other maintainers.
+
+
+ The Obvious Fix Rule
+
+All maintainers listed in this file are allowed to check in obvious
+fixes.
+
+An "obvious fix" means that there is no possibility that anyone will
+disagree with the change.
+
+A good mental test is "will the person who hates my work the most be
+able to find fault with the change" - if so, then it's not obvious and
+needs to be posted first. :-)
+
+Something like changing or bypassing an interface is _not_ an obvious
+fix, since such a change without discussion will result in
+instantaneous and loud complaints.
+
+
+Target/Architecture:
+
+Generic ISA (Instruction Set Architecture) issues, API variants, CPU
+variants. *-tdep.c. The Target/Architecture maintainer works with the
+host maintainer when resolving build issues. The Target/Architecture
+maintainer works with the native maintainer when resolving API issues.
+
+ a29k Deleted.
+
+ alpha --target=alpha-dec-osf4.0a -Werror
+ Maintenance only
+
+ arc --target=arc-elf ,-Werror
+ Maintenance only
+ OBSOLETE candidate, not multi-arch
+
+ arm --target=arm-elf -w
+ Fernando Nasser fnasser@redhat.com
+ Scott Bambrough scottb@netwinder.org
+ Richard Earnshaw rearnsha@arm.com
+ Not multi-arch
+
+ avr --target=avr ,-Werror
+ Theodore A. Roth troth@verinet.com
+
+ cris --target=cris-elf -w
+ Orjan Friberg orjanf@axis.com
+
+ d10v --target=d10v-elf ,-Werror
+ Maintenance only
+
+ d30v --target=d30v-elf ,-Werror
+ Maintenance only
+ OBSOLETE candidate, not multi-arch
+
+ djgpp --target=i586-pc-msdosdjgpp ,-Werror
+ (See native and host)
+
+ fr30 --target=fr30-elf -Werror
+ Maintenance only
+ OBSOLETE candidate, not multi-arch
+
+ h8300 --target=h8300hms -Werror
+ Maintenance only
+ Not multi-arch, work in progress
+
+ h8500 --target=h8500hms -Werror
+ Maintenance only
+ Not multi-arch, work in progress
+
+ i386 --target=i386-elf,i386-aout ,-Werror
+ Mark Kettenis kettenis@gnu.org
+
+ i960 --target=i960-coff ,-Werror
+ Maintenance only
+ OBSOLETE candidate, not multi-arch
+
+ ia64 --target=ia64-linux ,-Werror
+ Kevin Buettner kevinb@redhat.com
+
+ m32r --target=m32r-elf -Werror
+ Michael Snyder msnyder@redhat.com
+ Not multi-arch
+
+ m68hc11 --target=m68hc11-elf ,-Werror
+ Stephane Carrez stcarrez@nerim.fr
+
+ m68k --target=m68k-elf ,-Werror
+ Maintenance only
+ OBSOLETE candidate, not multi-arch
+
+ m88k --target=m88k ,-Werror
+ Known problem in 5.1
+ Maintenance only
+ OBSOLETE candidate, not multi-arch
+
+ mcore --target=mcore-elf,mcore-pe ,-Werror
+ Maintenance only
+ OBSOLETE candidate, not multi-arch
+
+ mips --target=mips-elf,mips64-elf ,-Werror
+ Andrew Cagney cagney@redhat.com
+
+ mn10200 --target=mn10200-elf ,-Werror
+ Maintenance only
+ OBSOLETE candidate, not multi-arch
+
+ mn10300 --target=mn10300-elf ,-Werror
+ Maintenance only
+
+ ns32k --target=ns32k-netbsd ,-Werror
+ Maintenance only
+
+ pa (--target=hppa1.1-hp-proelf broken)
+ Maintenance only
+ OBSOLETE candidate, not multi-arch
+
+ powerpc --target=powerpc-eabi ,-Werror
+ Kevin Buettner kevinb@redhat.com
+
+ rs6000 --target=rs6000-ibm-aix4.1 ,-Werror
+ (see rs6000 native and ppc target)
+
+ s390 --target=s390-linux ,-Werror
+ (contact DJ Barrow djbarrow@de.ibm.com)
+
+ sh --target=sh-elf ,-Werror
+ Elena Zannoni ezannoni@redhat.com
+
+ sparc --target=sparc-elf,sparc64-elf ,-Werror
+ Maintenance only
+
+ tic80 Deleted.
+
+ v850 --target=v850-elf ,-Werror
+ Maintenance only
+
+ vax --target=vax-dec-vms5.5 ,-Werror
+ Maintenance only
+
+ w65 Deleted.
+
+ x86-64 (--target=x86_64-linux-gnu broken)
+ Maintenance only
+
+ xstormy16 --target=xstormy16-elf ,-Werror
+ Corinna Vinschen vinschen@redhat.com
+
+ z8k --target=z8k-coff ,-Werror
+ Known problem in 5.1
+ Maintenance only
+ OBSOLETE candidate, not multi-arch
+
+All developers recognized by this file can make arbitrary changes to
+OBSOLETE targets.
+
+All maintainers can test and thence approve non-trivial changes to
+``maintenance only'' targets submitted by recognized developers.
+
+All recognized developers can make mechanical changes (by virtue of
+the obvious fix rule) to ``maintenance only'' targets. The change
+shall be sanity checked by compiling with one of the listed targets.
+
+The Bourne shell script:
+
+cat MAINTAINERS | tr -s '[\t]' '[ ]' | sed -n '
+/^[ ]*[-a-z0-9\.]*[ ]*[(]*--target=.*/ !d
+s/^.*--target=//
+s/).*$//
+h
+:loop
+ g
+ /^[^ ]*,/ !b end
+ s/,[^ ]*//
+ p
+ g
+ s/^[^,]*,//
+ h
+b loop
+:end
+p
+'
+
+can be used to generate a complete list of --target=
+--enable-gdb-build-warnings= pairs of the form:
+
+ arc-elf ,-Werror
+ ...
+ hppa1.1-hp-proelf broken
+ ...
+
+While the ``broken'' targets are included in the listing, the are not
+expected to build.
+
+
+Host/Native:
+
+The Native maintainer is responsible for target specific native
+support - typically shared libraries and quirks to procfs/ptrace/...
+The Native maintainer works with the Arch and Core maintainers when
+resolving more generic problems.
+
+The host maintainer ensures that gdb (including mmalloc) can be built
+as a cross debugger on their platform.
+
+AIX Peter Schauer Peter.Schauer@regent.e-technik.tu-muenchen.de
+ Kevin Buettner kevinb@redhat.com
+
+djgpp native Eli Zaretskii eliz@gnu.org
+ DJ Delorie dj@redhat.com
+MS Windows (NT, CE, '00, 9x, Me) host & native
+ Chris Faylor cgf@redhat.com
+GNU/Linux/x86 native & host
+ Mark Kettenis kettenis@gnu.org
+ Jim Blandy jimb@redhat.com
+GNU/Linux PPC native Kevin Buettner kevinb@redhat.com
+GNU/Linux MIPS native & host
+ Daniel Jacobowitz dan@debian.org
+GNU/Linux m68k Andreas Schwab schwab@suse.de
+FreeBSD native & host Mark Kettenis kettenis@gnu.org
+ David O'Brien obrien@freebsd.org
+hurd native Mark Kettenis kettenis@gnu.org
+NetBSD native & host Jason Thorpe thorpej@wasabisystems.com
+SCO/Unixware Robert Lipe rjl@sco.com
+GNU/Linux ARM native Scott Bambrough scottb@netwinder.org
+Solaris/x86 native & host (devolved)
+ Peter Schauer Peter.Schauer@regent.e-technik.tu-muenchen.de
+Solaris/SPARC native & host (devolved)
+ Michael Snyder msnyder@redhat.com
+
+
+
+Core: Generic components used by all of GDB
+
+generic arch support Andrew Cagney cagney@redhat.com
+ Any host/target maintainer can add to
+ gdbarch.{c,h,sh}. Send tricky ones to cagney.
+target vector Andrew Cagney cagney@redhat.com
+main (main.c, top.c) Elena Zannoni ezannoni@redhat.com
+event loop Elena Zannoni ezannoni@redhat.com
+
+generic symtabs Jim Blandy jimb@redhat.com
+ Elena Zannoni ezannoni@redhat.com
+ dwarf readers Jim Blandy jimb@redhat.com
+ Elena Zannoni ezannoni@redhat.com
+ elf reader Jim Blandy jimb@redhat.com
+ Elena Zannoni ezannoni@redhat.com
+ stabs reader Jim Blandy jimb@redhat.com
+ Elena Zannoni ezannoni@redhat.com
+ coff reader Philippe De Muyter phdm@macqel.be
+ xcoff reader Any maintainer can modify this; please send tricky
+ ones to Kevin Buettner <kevinb@redhat.com>
+ linespec Jim Blandy jimb@redhat.com
+ Elena Zannoni ezannoni@redhat.com
+ Fernando Nasser fnasser@redhat.com
+
+tracing bytecode stuff Jim Blandy jimb@redhat.com
+tracing Michael Snyder msnyder@redhat.com
+threads Michael Snyder msnyder@redhat.com
+ Mark Kettenis kettenis@gnu.org
+breakpoints Michael Snyder msnyder@redhat.com
+ Jim Blandy jimb@redhat.com
+language support (Blanket Write Privs Maintainers)
+ C++ Daniel Jacobowitz dan@debian.org
+ Java support (devolved)
+ Per Bothner per@bothner.com
+ Anthony Green green@redhat.com
+ Pascal support Pierre Muller muller@sources.redhat.com
+ Scheme support Jim Blandy jimb@redhat.com
+
+shared libs (devolved) Jim Blandy jimb@redhat.com
+ Kevin Buettner kevinb@redhat.com
+ xcoffsolib Peter Schauer Peter.Schauer@regent.e-technik.tu-muenchen.de
+
+remote.c Andrew Cagney cagney@redhat.com
+include/remote-sim.h, remote-sim.c
+ Andrew Cagney cagney@redhat.com
+sds protocol Fernando Nasser fnasser@redhat.com
+rdi/adp protocol Fernando Nasser fnasser@redhat.com
+documentation Eli Zaretskii eliz@gnu.org
+testsuite Fernando Nasser fnasser@redhat.com
+ config Mark Salter msalter@redhat.com
+ lib Mark Salter msalter@redhat.com
+ gdbtk (gdb.gdbtk) Keith Seitz keiths@redhat.com
+ c++ (gdb.c++) Michael Chastain mec@shout.net
+ mi tests (gdb.mi) Elena Zannoni ezannoni@redhat.com
+ Andrew Cagney cagney@redhat.com
+ stabs (gdb.stabs) Elena Zannoni ezannoni@redhat.com
+ threads (gdb.threads) Michael Snyder msnyder@redhat.com
+ trace (gdb.trace) Michael Snyder msnyder@redhat.com
+ hp tests (gdb.hp) (vacant)
+ Java tests (gdb.java) Anthony Green green@redhat.com
+Kernel Object Display Fernando Nasser fnasser@redhat.com
+
+
+UI: External (user) interfaces.
+
+command interpreter Fernando Nasser fnasser@redhat.com
+gdbtk (c & tcl) Jim Ingham jingham@apple.com
+ Fernando Nasser fnasser@redhat.com
+ Keith Seitz keiths@redhat.com
+libgui (w/foundry, sn) Jim Ingham jingham@apple.com
+ Keith Seitz keiths@redhat.com
+mi (gdb/mi) Andrew Cagney cagney@redhat.com
+ Elena Zannoni ezannoni@redhat.com
+ Fernando Nasser fnasser@redhat.com
+tui (vacant)
+ Technical Contact Point wdb@cup.hp.com
+
+
+Misc:
+
+gdb/gdbserver Daniel Jacobowitz dan@debian.org
+
+Web pages. Jim Kingdon jkingdon@engr.sgi.com ++
+ (anyone can edit; kingdon is just lead maintainer)
+
+Makefile.in, configure* ALL
+
+mmalloc/ ALL Host maintainers
+
+sim/ See sim/MAINTAINERS
+
+readline/ Master version: ftp://ftp.cwru.edu/pub/bash/
+ Elena Zannoni ezannoni@redhat.com
+ Host maintainers (host dependant parts)
+ (but get your changes into the master version)
+
+tcl/ tk/ itcl/ Ian Roxborough irox@redhat.com
+
+ Write After Approval
+ (alphabetic)
+
+To get recommended for the Write After Approval list you need a valid
+FSF assignment and have submitted one good patch.
+
+David Anderson davea@sgi.com
+Philip Blundell philb@gnu.org
+Joel Brobecker brobecker@act-europe.fr
+Nick Clifton nickc@redhat.com
+Chris G. Demetriou cgd@broadcom.com
+Klee Dienes kdienes@apple.com
+Richard Earnshaw rearnsha@arm.com
+Matthew Green mrg@eterna.com.au
+Orjan Friberg orjanf@axis.com
+Ben Harris bjh21@netbsd.org
+Richard Henderson rth@redhat.com
+Paul Hilfinger hilfinger@gnat.com
+Matt Hiller hiller@redhat.com
+Kazu Hirata kazu@hxi.com
+Jeff Holcomb jeffh@redhat.com
+Don Howard dhoward@redhat.com
+Martin Hunt hunt@redhat.com
+Jim Ingham jingham@apple.com
+Daniel Jacobowitz dan@debian.org
+Andreas Jaeger aj@suse.de
+Geoff Keating geoffk@redhat.com
+Jim Kingdon jkingdon@engr.sgi.com ++
+Jonathan Larmour jlarmour@redhat.co.uk
+H.J. Lu hjl@lucon.org
+Glen McCready gkm@redhat.com
+Greg McGary greg@mcgary.org
+Jason Merrill jason@redhat.com
+Jason Molenda jmolenda@apple.com
+Pierre Muller muller@sources.redhat.com
+Alexandre Oliva aoliva@redhat.com
+Tom Rix trix@redhat.com
+Theodore A. Roth troth@verinet.com
+Mark Salter msalter@redhat.com
+Andreas Schwab schwab@suse.de
+Keith Seitz keiths@redhat.com
+Jiri Smid smid@suse.cz
+David Smith dsmith@redhat.com
+Stephen P. Smith ischis2@home.com
+Jackie Smith Cashion jsmith@redhat.com
+Petr Sorfa petrs@caldera.com
+Gary Thomas gthomas@redhat.com
+Jason Thorpe thorpej@wasabisystems.com
+Tom Tromey tromey@redhat.com
+Corinna Vinschen vinschen@redhat.com
+Keith Walker keith.walker@arm.com
+Michal Ludvig mludvig@suse.cz
+David S. Miller davem@redhat.com
+Eric Christopher echristo@redhat.com
+
+
+
+ Past Maintainers
+
+Jimmy Guo (gdb.hp, tui) guo at cup dot hp dot com
+Jeff Law (hppa) law at cygnus dot com
+Daniel Berlin (C++ support) dan at cgsoftware dot com
+Nick Duffek (powerpc, SCO, Sol/x86) nick at duffek dot com
+David Taylor (d10v, sparc, utils, defs,
+ expression evaluator, language support) taylor at candd dot org
+J.T. Conklin (dcache, NetBSD, remote) jtc at redback dot com
+Frank Ch. Eigler (sim) fche at redhat dot com
+
+
+
+Folks that have been caught up in a paper trail:
+
+Jim Kingdon jkingdon@engr.sgi.com
+
+--
+
+(*) Indicates folks that don't have a Kerberos/SSH account in the GDB
+group.
diff --git a/gdb/NEWS b/gdb/NEWS
new file mode 100644
index 00000000000..a61b435c687
--- /dev/null
+++ b/gdb/NEWS
@@ -0,0 +1,2120 @@
+ What has changed in GDB?
+ (Organized release by release)
+
+*** Changes since GDB 5.2:
+
+* GDB now supports C/C++ preprocessor macros.
+
+GDB now expands preprocessor macro invocations in C/C++ expressions,
+and provides various commands for showing macro definitions and how
+they expand.
+
+Most compilers don't include information about macros in the debugging
+information by default. In GCC 3.1, for example, you need to compile
+your program with the options `-gdwarf-2 -g3'. If the macro
+information is present in the executable, GDB will read it.
+
+Here are the new commands for working with macros:
+
+** macro expand EXPRESSION
+
+Expand any macro invocations in expression, and show the result.
+
+** show macro MACRO-NAME
+
+Show the definition of the macro named MACRO-NAME, and where it was
+defined.
+
+* Multi-arched targets.
+
+DEC Alpha (partial) alpha*-*-*
+DEC VAX (partial) vax-*-*
+NEC V850 v850-*-*
+National Semiconductor NS32000 (partial) ns32k-*-*
+
+* New targets.
+
+Atmel AVR avr*-*-*
+
+* New native configurations
+
+Alpha NetBSD alpha*-*-netbsd*
+SH NetBSD sh*-*-netbsdelf*
+MIPS NetBSD mips*-*-netbsd*
+
+* OBSOLETE configurations and files
+
+Configurations that have been declared obsolete in this release have
+been commented out. Unless there is activity to revive these
+configurations, the next release of GDB will have their sources
+permanently REMOVED.
+
+* REMOVED configurations and files
+
+AMD 29k family via UDI a29k-amd-udi, udi29k
+A29K VxWorks a29k-*-vxworks
+AMD 29000 embedded, using EBMON a29k-none-none
+AMD 29000 embedded with COFF a29k-none-coff
+AMD 29000 embedded with a.out a29k-none-aout
+
+testsuite/gdb.hp/gdb.threads-hp/ directory
+
+* New command "set max-user-call-depth <nnn>"
+
+This command allows the user to limit the call depth of user-defined
+commands. The default is 1024.
+
+* Changes in FreeBSD/i386 native debugging.
+
+Support for the "generate-core-file" has been added.
+
+* New commands "dump", "append", and "restore".
+
+These commands allow data to be copied from target memory
+to a bfd-format or binary file (dump and append), and back
+from a file into memory (restore).
+
+*** Changes in GDB 5.2:
+
+* New command "set trust-readonly-sections on[off]".
+
+This command is a hint that tells gdb that read-only sections
+really are read-only (ie. that their contents will not change).
+In this mode, gdb will go to the object file rather than the
+target to read memory from read-only sections (such as ".text").
+This can be a significant performance improvement on some
+(notably embedded) targets.
+
+* New command "generate-core-file" (or "gcore").
+
+This new gdb command allows the user to drop a core file of the child
+process state at any time. So far it's been implemented only for
+GNU/Linux and Solaris, but should be relatively easily ported to other
+hosts. Argument is core file name (defaults to core.<pid>).
+
+* New command line option
+
+GDB now accepts --pid or -p followed by a process id.
+
+* Change in command line behavior -- corefiles vs. process ids.
+
+There is a subtle behavior in the way in which GDB handles
+command line arguments. The first non-flag argument is always
+a program to debug, but the second non-flag argument may either
+be a corefile or a process id. Previously, GDB would attempt to
+open the second argument as a corefile, and if that failed, would
+issue a superfluous error message and then attempt to attach it as
+a process. Now, if the second argument begins with a non-digit,
+it will be treated as a corefile. If it begins with a digit,
+GDB will attempt to attach it as a process, and if no such process
+is found, will then attempt to open it as a corefile.
+
+* Changes in ARM configurations.
+
+Multi-arch support is enabled for all ARM configurations. The ARM/NetBSD
+configuration is fully multi-arch.
+
+* New native configurations
+
+ARM NetBSD arm*-*-netbsd*
+x86 OpenBSD i[3456]86-*-openbsd*
+AMD x86-64 running GNU/Linux x86_64-*-linux-*
+Sparc64 running FreeBSD sparc64-*-freebsd*
+
+* New targets
+
+Sanyo XStormy16 xstormy16-elf
+
+* OBSOLETE configurations and files
+
+Configurations that have been declared obsolete in this release have
+been commented out. Unless there is activity to revive these
+configurations, the next release of GDB will have their sources
+permanently REMOVED.
+
+AMD 29k family via UDI a29k-amd-udi, udi29k
+A29K VxWorks a29k-*-vxworks
+AMD 29000 embedded, using EBMON a29k-none-none
+AMD 29000 embedded with COFF a29k-none-coff
+AMD 29000 embedded with a.out a29k-none-aout
+
+testsuite/gdb.hp/gdb.threads-hp/ directory
+
+* REMOVED configurations and files
+
+TI TMS320C80 tic80-*-*
+WDC 65816 w65-*-*
+PowerPC Solaris powerpcle-*-solaris*
+PowerPC Windows NT powerpcle-*-cygwin32
+PowerPC Netware powerpc-*-netware*
+Harris/CXUX m88k m88*-harris-cxux*
+Most ns32k hosts and targets ns32k-*-mach3* ns32k-umax-*
+ ns32k-utek-sysv* ns32k-utek-*
+SunOS 4.0.Xi on i386 i[3456]86-*-sunos*
+Ultracomputer (29K) running Sym1 a29k-nyu-sym1 a29k-*-kern*
+Sony NEWS (68K) running NEWSOS 3.x m68*-sony-sysv news
+ISI Optimum V (3.05) under 4.3bsd. m68*-isi-*
+Apple Macintosh (MPW) host and target N/A host, powerpc-*-macos*
+
+* Changes to command line processing
+
+The new `--args' feature can be used to specify command-line arguments
+for the inferior from gdb's command line.
+
+* Changes to key bindings
+
+There is a new `operate-and-get-next' function bound to `C-o'.
+
+*** Changes in GDB 5.1.1
+
+Fix compile problem on DJGPP.
+
+Fix a problem with floating-point registers on the i386 being
+corrupted.
+
+Fix to stop GDB crashing on .debug_str debug info.
+
+Numerous documentation fixes.
+
+Numerous testsuite fixes.
+
+*** Changes in GDB 5.1:
+
+* New native configurations
+
+Alpha FreeBSD alpha*-*-freebsd*
+x86 FreeBSD 3.x and 4.x i[3456]86*-freebsd[34]*
+MIPS GNU/Linux mips*-*-linux*
+MIPS SGI Irix 6.x mips*-sgi-irix6*
+ia64 AIX ia64-*-aix*
+s390 and s390x GNU/Linux {s390,s390x}-*-linux*
+
+* New targets
+
+Motorola 68HC11 and 68HC12 m68hc11-elf
+CRIS cris-axis
+UltraSparc running GNU/Linux sparc64-*-linux*
+
+* OBSOLETE configurations and files
+
+x86 FreeBSD before 2.2 i[3456]86*-freebsd{1,2.[01]}*,
+Harris/CXUX m88k m88*-harris-cxux*
+Most ns32k hosts and targets ns32k-*-mach3* ns32k-umax-*
+ ns32k-utek-sysv* ns32k-utek-*
+TI TMS320C80 tic80-*-*
+WDC 65816 w65-*-*
+Ultracomputer (29K) running Sym1 a29k-nyu-sym1 a29k-*-kern*
+PowerPC Solaris powerpcle-*-solaris*
+PowerPC Windows NT powerpcle-*-cygwin32
+PowerPC Netware powerpc-*-netware*
+SunOS 4.0.Xi on i386 i[3456]86-*-sunos*
+Sony NEWS (68K) running NEWSOS 3.x m68*-sony-sysv news
+ISI Optimum V (3.05) under 4.3bsd. m68*-isi-*
+Apple Macintosh (MPW) host N/A
+
+stuff.c (Program to stuff files into a specially prepared space in kdb)
+kdb-start.c (Main loop for the standalone kernel debugger)
+
+Configurations that have been declared obsolete in this release have
+been commented out. Unless there is activity to revive these
+configurations, the next release of GDB will have their sources
+permanently REMOVED.
+
+* REMOVED configurations and files
+
+Altos 3068 m68*-altos-*
+Convex c1-*-*, c2-*-*
+Pyramid pyramid-*-*
+ARM RISCix arm-*-* (as host)
+Tahoe tahoe-*-*
+ser-ocd.c *-*-*
+
+* GDB has been converted to ISO C.
+
+GDB's source code has been converted to ISO C. In particular, the
+sources are fully protoized, and rely on standard headers being
+present.
+
+* Other news:
+
+* "info symbol" works on platforms which use COFF, ECOFF, XCOFF, and NLM.
+
+* The MI enabled by default.
+
+The new machine oriented interface (MI) introduced in GDB 5.0 has been
+revised and enabled by default. Packages which use GDB as a debugging
+engine behind a UI or another front end are encouraged to switch to
+using the GDB/MI interface, instead of the old annotations interface
+which is now deprecated.
+
+* Support for debugging Pascal programs.
+
+GDB now includes support for debugging Pascal programs. The following
+main features are supported:
+
+ - Pascal-specific data types such as sets;
+
+ - automatic recognition of Pascal sources based on file-name
+ extension;
+
+ - Pascal-style display of data types, variables, and functions;
+
+ - a Pascal expression parser.
+
+However, some important features are not yet supported.
+
+ - Pascal string operations are not supported at all;
+
+ - there are some problems with boolean types;
+
+ - Pascal type hexadecimal constants are not supported
+ because they conflict with the internal variables format;
+
+ - support for Pascal objects and classes is not full yet;
+
+ - unlike Pascal, GDB is case-sensitive for symbol names.
+
+* Changes in completion.
+
+Commands such as `shell', `run' and `set args', which pass arguments
+to inferior programs, now complete on file names, similar to what
+users expect at the shell prompt.
+
+Commands which accept locations, such as `disassemble', `print',
+`breakpoint', `until', etc. now complete on filenames as well as
+program symbols. Thus, if you type "break foob TAB", and the source
+files linked into the programs include `foobar.c', that file name will
+be one of the candidates for completion. However, file names are not
+considered for completion after you typed a colon that delimits a file
+name from a name of a function in that file, as in "break foo.c:bar".
+
+`set demangle-style' completes on available demangling styles.
+
+* New platform-independent commands:
+
+It is now possible to define a post-hook for a command as well as a
+hook that runs before the command. For more details, see the
+documentation of `hookpost' in the GDB manual.
+
+* Changes in GNU/Linux native debugging.
+
+Support for debugging multi-threaded programs has been completely
+revised for all platforms except m68k and sparc. You can now debug as
+many threads as your system allows you to have.
+
+Attach/detach is supported for multi-threaded programs.
+
+Support for SSE registers was added for x86. This doesn't work for
+multi-threaded programs though.
+
+* Changes in MIPS configurations.
+
+Multi-arch support is enabled for all MIPS configurations.
+
+GDB can now be built as native debugger on SGI Irix 6.x systems for
+debugging n32 executables. (Debugging 64-bit executables is not yet
+supported.)
+
+* Unified support for hardware watchpoints in all x86 configurations.
+
+Most (if not all) native x86 configurations support hardware-assisted
+breakpoints and watchpoints in a unified manner. This support
+implements debug register sharing between watchpoints, which allows to
+put a virtually infinite number of watchpoints on the same address,
+and also supports watching regions up to 16 bytes with several debug
+registers.
+
+The new maintenance command `maintenance show-debug-regs' toggles
+debugging print-outs in functions that insert, remove, and test
+watchpoints and hardware breakpoints.
+
+* Changes in the DJGPP native configuration.
+
+New command ``info dos sysinfo'' displays assorted information about
+the CPU, OS, memory, and DPMI server.
+
+New commands ``info dos gdt'', ``info dos ldt'', and ``info dos idt''
+display information about segment descriptors stored in GDT, LDT, and
+IDT.
+
+New commands ``info dos pde'' and ``info dos pte'' display entries
+from Page Directory and Page Tables (for now works with CWSDPMI only).
+New command ``info dos address-pte'' displays the Page Table entry for
+a given linear address.
+
+GDB can now pass command lines longer than 126 characters to the
+program being debugged (requires an update to the libdbg.a library
+which is part of the DJGPP development kit).
+
+DWARF2 debug info is now supported.
+
+It is now possible to `step' and `next' through calls to `longjmp'.
+
+* Changes in documentation.
+
+All GDB documentation was converted to GFDL, the GNU Free
+Documentation License.
+
+Tracepoints-related commands are now fully documented in the GDB
+manual.
+
+TUI, the Text-mode User Interface, is now documented in the manual.
+
+Tracepoints-related commands are now fully documented in the GDB
+manual.
+
+The "GDB Internals" manual now has an index. It also includes
+documentation of `ui_out' functions, GDB coding standards, x86
+hardware watchpoints, and memory region attributes.
+
+* GDB's version number moved to ``version.in''
+
+The Makefile variable VERSION has been replaced by the file
+``version.in''. People creating GDB distributions should update the
+contents of this file.
+
+* gdba.el deleted
+
+GUD support is now a standard part of the EMACS distribution.
+
+*** Changes in GDB 5.0:
+
+* Improved support for debugging FP programs on x86 targets
+
+Unified and much-improved support for debugging floating-point
+programs on all x86 targets. In particular, ``info float'' now
+displays the FP registers in the same format on all x86 targets, with
+greater level of detail.
+
+* Improvements and bugfixes in hardware-assisted watchpoints
+
+It is now possible to watch array elements, struct members, and
+bitfields with hardware-assisted watchpoints. Data-read watchpoints
+on x86 targets no longer erroneously trigger when the address is
+written.
+
+* Improvements in the native DJGPP version of GDB
+
+The distribution now includes all the scripts and auxiliary files
+necessary to build the native DJGPP version on MS-DOS/MS-Windows
+machines ``out of the box''.
+
+The DJGPP version can now debug programs that use signals. It is
+possible to catch signals that happened in the debuggee, deliver
+signals to it, interrupt it with Ctrl-C, etc. (Previously, a signal
+would kill the program being debugged.) Programs that hook hardware
+interrupts (keyboard, timer, etc.) can also be debugged.
+
+It is now possible to debug DJGPP programs that redirect their
+standard handles or switch them to raw (as opposed to cooked) mode, or
+even close them. The command ``run < foo > bar'' works as expected,
+and ``info terminal'' reports useful information about the debuggee's
+terminal, including raw/cooked mode, redirection, etc.
+
+The DJGPP version now uses termios functions for console I/O, which
+enables debugging graphics programs. Interrupting GDB with Ctrl-C
+also works.
+
+DOS-style file names with drive letters are now fully supported by
+GDB.
+
+It is now possible to debug DJGPP programs that switch their working
+directory. It is also possible to rerun the debuggee any number of
+times without restarting GDB; thus, you can use the same setup,
+breakpoints, etc. for many debugging sessions.
+
+* New native configurations
+
+ARM GNU/Linux arm*-*-linux*
+PowerPC GNU/Linux powerpc-*-linux*
+
+* New targets
+
+Motorola MCore mcore-*-*
+x86 VxWorks i[3456]86-*-vxworks*
+PowerPC VxWorks powerpc-*-vxworks*
+TI TMS320C80 tic80-*-*
+
+* OBSOLETE configurations
+
+Altos 3068 m68*-altos-*
+Convex c1-*-*, c2-*-*
+Pyramid pyramid-*-*
+ARM RISCix arm-*-* (as host)
+Tahoe tahoe-*-*
+
+Configurations that have been declared obsolete will be commented out,
+but the code will be left in place. If there is no activity to revive
+these configurations before the next release of GDB, the sources will
+be permanently REMOVED.
+
+* Gould support removed
+
+Support for the Gould PowerNode and NP1 has been removed.
+
+* New features for SVR4
+
+On SVR4 native platforms (such as Solaris), if you attach to a process
+without first loading a symbol file, GDB will now attempt to locate and
+load symbols from the running process's executable file.
+
+* Many C++ enhancements
+
+C++ support has been greatly improved. Overload resolution now works properly
+in almost all cases. RTTI support is on the way.
+
+* Remote targets can connect to a sub-program
+
+A popen(3) style serial-device has been added. This device starts a
+sub-process (such as a stand-alone simulator) and then communicates
+with that. The sub-program to run is specified using the syntax
+``|<program> <args>'' vis:
+
+ (gdb) set remotedebug 1
+ (gdb) target extended-remote |mn10300-elf-sim program-args
+
+* MIPS 64 remote protocol
+
+A long standing bug in the mips64 remote protocol where by GDB
+expected certain 32 bit registers (ex SR) to be transfered as 32
+instead of 64 bits has been fixed.
+
+The command ``set remote-mips64-transfers-32bit-regs on'' has been
+added to provide backward compatibility with older versions of GDB.
+
+* ``set remotebinarydownload'' replaced by ``set remote X-packet''
+
+The command ``set remotebinarydownload'' command has been replaced by
+``set remote X-packet''. Other commands in ``set remote'' family
+include ``set remote P-packet''.
+
+* Breakpoint commands accept ranges.
+
+The breakpoint commands ``enable'', ``disable'', and ``delete'' now
+accept a range of breakpoints, e.g. ``5-7''. The tracepoint command
+``tracepoint passcount'' also accepts a range of tracepoints.
+
+* ``apropos'' command added.
+
+The ``apropos'' command searches through command names and
+documentation strings, printing out matches, making it much easier to
+try to find a command that does what you are looking for.
+
+* New MI interface
+
+A new machine oriented interface (MI) has been added to GDB. This
+interface is designed for debug environments running GDB as a separate
+process. This is part of the long term libGDB project. See the
+"GDB/MI" chapter of the GDB manual for further information. It can be
+enabled by configuring with:
+
+ .../configure --enable-gdbmi
+
+*** Changes in GDB-4.18:
+
+* New native configurations
+
+HP-UX 10.20 hppa*-*-hpux10.20
+HP-UX 11.x hppa*-*-hpux11.0*
+M68K GNU/Linux m68*-*-linux*
+
+* New targets
+
+Fujitsu FR30 fr30-*-elf*
+Intel StrongARM strongarm-*-*
+Mitsubishi D30V d30v-*-*
+
+* OBSOLETE configurations
+
+Gould PowerNode, NP1 np1-*-*, pn-*-*
+
+Configurations that have been declared obsolete will be commented out,
+but the code will be left in place. If there is no activity to revive
+these configurations before the next release of GDB, the sources will
+be permanently REMOVED.
+
+* ANSI/ISO C
+
+As a compatibility experiment, GDB's source files buildsym.h and
+buildsym.c have been converted to pure standard C, no longer
+containing any K&R compatibility code. We believe that all systems in
+use today either come with a standard C compiler, or have a GCC port
+available. If this is not true, please report the affected
+configuration to bug-gdb@gnu.org immediately. See the README file for
+information about getting a standard C compiler if you don't have one
+already.
+
+* Readline 2.2
+
+GDB now uses readline 2.2.
+
+* set extension-language
+
+You can now control the mapping between filename extensions and source
+languages by using the `set extension-language' command. For instance,
+you can ask GDB to treat .c files as C++ by saying
+ set extension-language .c c++
+The command `info extensions' lists all of the recognized extensions
+and their associated languages.
+
+* Setting processor type for PowerPC and RS/6000
+
+When GDB is configured for a powerpc*-*-* or an rs6000*-*-* target,
+you can use the `set processor' command to specify what variant of the
+PowerPC family you are debugging. The command
+
+ set processor NAME
+
+sets the PowerPC/RS6000 variant to NAME. GDB knows about the
+following PowerPC and RS6000 variants:
+
+ ppc-uisa PowerPC UISA - a PPC processor as viewed by user-level code
+ rs6000 IBM RS6000 ("POWER") architecture, user-level view
+ 403 IBM PowerPC 403
+ 403GC IBM PowerPC 403GC
+ 505 Motorola PowerPC 505
+ 860 Motorola PowerPC 860 or 850
+ 601 Motorola PowerPC 601
+ 602 Motorola PowerPC 602
+ 603 Motorola/IBM PowerPC 603 or 603e
+ 604 Motorola PowerPC 604 or 604e
+ 750 Motorola/IBM PowerPC 750 or 750
+
+At the moment, this command just tells GDB what to name the
+special-purpose processor registers. Since almost all the affected
+registers are inaccessible to user-level programs, this command is
+only useful for remote debugging in its present form.
+
+* HP-UX support
+
+Thanks to a major code donation from Hewlett-Packard, GDB now has much
+more extensive support for HP-UX. Added features include shared
+library support, kernel threads and hardware watchpoints for 11.00,
+support for HP's ANSI C and C++ compilers, and a compatibility mode
+for xdb and dbx commands.
+
+* Catchpoints
+
+HP's donation includes the new concept of catchpoints, which is a
+generalization of the old catch command. On HP-UX, it is now possible
+to catch exec, fork, and vfork, as well as library loading.
+
+This means that the existing catch command has changed; its first
+argument now specifies the type of catch to be set up. See the
+output of "help catch" for a list of catchpoint types.
+
+* Debugging across forks
+
+On HP-UX, you can choose which process to debug when a fork() happens
+in the inferior.
+
+* TUI
+
+HP has donated a curses-based terminal user interface (TUI). To get
+it, build with --enable-tui. Although this can be enabled for any
+configuration, at present it only works for native HP debugging.
+
+* GDB remote protocol additions
+
+A new protocol packet 'X' that writes binary data is now available.
+Default behavior is to try 'X', then drop back to 'M' if the stub
+fails to respond. The settable variable `remotebinarydownload'
+allows explicit control over the use of 'X'.
+
+For 64-bit targets, the memory packets ('M' and 'm') can now contain a
+full 64-bit address. The command
+
+ set remoteaddresssize 32
+
+can be used to revert to the old behaviour. For existing remote stubs
+the change should not be noticed, as the additional address information
+will be discarded.
+
+In order to assist in debugging stubs, you may use the maintenance
+command `packet' to send any text string to the stub. For instance,
+
+ maint packet heythere
+
+sends the packet "$heythere#<checksum>". Note that it is very easy to
+disrupt a debugging session by sending the wrong packet at the wrong
+time.
+
+The compare-sections command allows you to compare section data on the
+target to what is in the executable file without uploading or
+downloading, by comparing CRC checksums.
+
+* Tracing can collect general expressions
+
+You may now collect general expressions at tracepoints. This requires
+further additions to the target-side stub; see tracepoint.c and
+doc/agentexpr.texi for further details.
+
+* mask-address variable for Mips
+
+For Mips targets, you may control the zeroing of the upper 32 bits of
+a 64-bit address by entering `set mask-address on'. This is mainly
+of interest to users of embedded R4xxx and R5xxx processors.
+
+* Higher serial baud rates
+
+GDB's serial code now allows you to specify baud rates 57600, 115200,
+230400, and 460800 baud. (Note that your host system may not be able
+to achieve all of these rates.)
+
+* i960 simulator
+
+The i960 configuration now includes an initial implementation of a
+builtin simulator, contributed by Jim Wilson.
+
+
+*** Changes in GDB-4.17:
+
+* New native configurations
+
+Alpha GNU/Linux alpha*-*-linux*
+Unixware 2.x i[3456]86-unixware2*
+Irix 6.x mips*-sgi-irix6*
+PowerPC GNU/Linux powerpc-*-linux*
+PowerPC Solaris powerpcle-*-solaris*
+Sparc GNU/Linux sparc-*-linux*
+Motorola sysV68 R3V7.1 m68k-motorola-sysv
+
+* New targets
+
+Argonaut Risc Chip (ARC) arc-*-*
+Hitachi H8/300S h8300*-*-*
+Matsushita MN10200 w/simulator mn10200-*-*
+Matsushita MN10300 w/simulator mn10300-*-*
+MIPS NEC VR4100 mips64*vr4100*{,el}-*-elf*
+MIPS NEC VR5000 mips64*vr5000*{,el}-*-elf*
+MIPS Toshiba TX39 mips64*tx39*{,el}-*-elf*
+Mitsubishi D10V w/simulator d10v-*-*
+Mitsubishi M32R/D w/simulator m32r-*-elf*
+Tsqware Sparclet sparclet-*-*
+NEC V850 w/simulator v850-*-*
+
+* New debugging protocols
+
+ARM with RDI protocol arm*-*-*
+M68K with dBUG monitor m68*-*-{aout,coff,elf}
+DDB and LSI variants of PMON protocol mips*-*-*
+PowerPC with DINK32 monitor powerpc{,le}-*-eabi
+PowerPC with SDS protocol powerpc{,le}-*-eabi
+Macraigor OCD (Wiggler) devices powerpc{,le}-*-eabi
+
+* DWARF 2
+
+All configurations can now understand and use the DWARF 2 debugging
+format. The choice is automatic, if the symbol file contains DWARF 2
+information.
+
+* Java frontend
+
+GDB now includes basic Java language support. This support is
+only useful with Java compilers that produce native machine code.
+
+* solib-absolute-prefix and solib-search-path
+
+For SunOS and SVR4 shared libraries, you may now set the prefix for
+loading absolute shared library symbol files, and the search path for
+locating non-absolute shared library symbol files.
+
+* Live range splitting
+
+GDB can now effectively debug code for which GCC has performed live
+range splitting as part of its optimization. See gdb/doc/LRS for
+more details on the expected format of the stabs information.
+
+* Hurd support
+
+GDB's support for the GNU Hurd, including thread debugging, has been
+updated to work with current versions of the Hurd.
+
+* ARM Thumb support
+
+GDB's ARM target configuration now handles the ARM7T (Thumb) 16-bit
+instruction set. ARM GDB automatically detects when Thumb
+instructions are in use, and adjusts disassembly and backtracing
+accordingly.
+
+* MIPS16 support
+
+GDB's MIPS target configurations now handle the MIP16 16-bit
+instruction set.
+
+* Overlay support
+
+GDB now includes support for overlays; if an executable has been
+linked such that multiple sections are based at the same address, GDB
+will decide which section to use for symbolic info. You can choose to
+control the decision manually, using overlay commands, or implement
+additional target-side support and use "overlay load-target" to bring
+in the overlay mapping. Do "help overlay" for more detail.
+
+* info symbol
+
+The command "info symbol <address>" displays information about
+the symbol at the specified address.
+
+* Trace support
+
+The standard remote protocol now includes an extension that allows
+asynchronous collection and display of trace data. This requires
+extensive support in the target-side debugging stub. Tracing mode
+includes a new interaction mode in GDB and new commands: see the
+file tracepoint.c for more details.
+
+* MIPS simulator
+
+Configurations for embedded MIPS now include a simulator contributed
+by Cygnus Solutions. The simulator supports the instruction sets
+of most MIPS variants.
+
+* Sparc simulator
+
+Sparc configurations may now include the ERC32 simulator contributed
+by the European Space Agency. The simulator is not built into
+Sparc targets by default; configure with --enable-sim to include it.
+
+* set architecture
+
+For target configurations that may include multiple variants of a
+basic architecture (such as MIPS and SH), you may now set the
+architecture explicitly. "set arch" sets, "info arch" lists
+the possible architectures.
+
+*** Changes in GDB-4.16:
+
+* New native configurations
+
+Windows 95, x86 Windows NT i[345]86-*-cygwin32
+M68K NetBSD m68k-*-netbsd*
+PowerPC AIX 4.x powerpc-*-aix*
+PowerPC MacOS powerpc-*-macos*
+PowerPC Windows NT powerpcle-*-cygwin32
+RS/6000 AIX 4.x rs6000-*-aix4*
+
+* New targets
+
+ARM with RDP protocol arm-*-*
+I960 with MON960 i960-*-coff
+MIPS VxWorks mips*-*-vxworks*
+MIPS VR4300 with PMON mips64*vr4300{,el}-*-elf*
+PowerPC with PPCBUG monitor powerpc{,le}-*-eabi*
+Hitachi SH3 sh-*-*
+Matra Sparclet sparclet-*-*
+
+* PowerPC simulator
+
+The powerpc-eabi configuration now includes the PSIM simulator,
+contributed by Andrew Cagney, with assistance from Mike Meissner.
+PSIM is a very elaborate model of the PowerPC, including not only
+basic instruction set execution, but also details of execution unit
+performance and I/O hardware. See sim/ppc/README for more details.
+
+* Solaris 2.5
+
+GDB now works with Solaris 2.5.
+
+* Windows 95/NT native
+
+GDB will now work as a native debugger on Windows 95 and Windows NT.
+To build it from source, you must use the "gnu-win32" environment,
+which uses a DLL to emulate enough of Unix to run the GNU tools.
+Further information, binaries, and sources are available at
+ftp.cygnus.com, under pub/gnu-win32.
+
+* dont-repeat command
+
+If a user-defined command includes the command `dont-repeat', then the
+command will not be repeated if the user just types return. This is
+useful if the command is time-consuming to run, so that accidental
+extra keystrokes don't run the same command many times.
+
+* Send break instead of ^C
+
+The standard remote protocol now includes an option to send a break
+rather than a ^C to the target in order to interrupt it. By default,
+GDB will send ^C; to send a break, set the variable `remotebreak' to 1.
+
+* Remote protocol timeout
+
+The standard remote protocol includes a new variable `remotetimeout'
+that allows you to set the number of seconds before GDB gives up trying
+to read from the target. The default value is 2.
+
+* Automatic tracking of dynamic object loading (HPUX and Solaris only)
+
+By default GDB will automatically keep track of objects as they are
+loaded and unloaded by the dynamic linker. By using the command `set
+stop-on-solib-events 1' you can arrange for GDB to stop the inferior
+when shared library events occur, thus allowing you to set breakpoints
+in shared libraries which are explicitly loaded by the inferior.
+
+Note this feature does not work on hpux8. On hpux9 you must link
+/usr/lib/end.o into your program. This feature should work
+automatically on hpux10.
+
+* Irix 5.x hardware watchpoint support
+
+Irix 5 configurations now support the use of hardware watchpoints.
+
+* Mips protocol "SYN garbage limit"
+
+When debugging a Mips target using the `target mips' protocol, you
+may set the number of characters that GDB will ignore by setting
+the `syn-garbage-limit'. A value of -1 means that GDB will ignore
+every character. The default value is 1050.
+
+* Recording and replaying remote debug sessions
+
+If you set `remotelogfile' to the name of a file, gdb will write to it
+a recording of a remote debug session. This recording may then be
+replayed back to gdb using "gdbreplay". See gdbserver/README for
+details. This is useful when you have a problem with GDB while doing
+remote debugging; you can make a recording of the session and send it
+to someone else, who can then recreate the problem.
+
+* Speedups for remote debugging
+
+GDB includes speedups for downloading and stepping MIPS systems using
+the IDT monitor, fast downloads to the Hitachi SH E7000 emulator,
+and more efficient S-record downloading.
+
+* Memory use reductions and statistics collection
+
+GDB now uses less memory and reports statistics about memory usage.
+Try the `maint print statistics' command, for example.
+
+*** Changes in GDB-4.15:
+
+* Psymtabs for XCOFF
+
+The symbol reader for AIX GDB now uses partial symbol tables. This
+can greatly improve startup time, especially for large executables.
+
+* Remote targets use caching
+
+Remote targets now use a data cache to speed up communication with the
+remote side. The data cache could lead to incorrect results because
+it doesn't know about volatile variables, thus making it impossible to
+debug targets which use memory mapped I/O devices. `set remotecache
+off' turns the the data cache off.
+
+* Remote targets may have threads
+
+The standard remote protocol now includes support for multiple threads
+in the target system, using new protocol commands 'H' and 'T'. See
+gdb/remote.c for details.
+
+* NetROM support
+
+If GDB is configured with `--enable-netrom', then it will include
+support for the NetROM ROM emulator from XLNT Designs. The NetROM
+acts as though it is a bank of ROM on the target board, but you can
+write into it over the network. GDB's support consists only of
+support for fast loading into the emulated ROM; to debug, you must use
+another protocol, such as standard remote protocol. The usual
+sequence is something like
+
+ target nrom <netrom-hostname>
+ load <prog>
+ target remote <netrom-hostname>:1235
+
+* Macintosh host
+
+GDB now includes support for the Apple Macintosh, as a host only. It
+may be run as either an MPW tool or as a standalone application, and
+it can debug through the serial port. All the usual GDB commands are
+available, but to the target command, you must supply "serial" as the
+device type instead of "/dev/ttyXX". See mpw-README in the main
+directory for more information on how to build. The MPW configuration
+scripts */mpw-config.in support only a few targets, and only the
+mips-idt-ecoff target has been tested.
+
+* Autoconf
+
+GDB configuration now uses autoconf. This is not user-visible,
+but does simplify configuration and building.
+
+* hpux10
+
+GDB now supports hpux10.
+
+*** Changes in GDB-4.14:
+
+* New native configurations
+
+x86 FreeBSD i[345]86-*-freebsd
+x86 NetBSD i[345]86-*-netbsd
+NS32k NetBSD ns32k-*-netbsd
+Sparc NetBSD sparc-*-netbsd
+
+* New targets
+
+A29K VxWorks a29k-*-vxworks
+HP PA PRO embedded (WinBond W89K & Oki OP50N) hppa*-*-pro*
+CPU32 EST-300 emulator m68*-*-est*
+PowerPC ELF powerpc-*-elf
+WDC 65816 w65-*-*
+
+* Alpha OSF/1 support for procfs
+
+GDB now supports procfs under OSF/1-2.x and higher, which makes it
+possible to attach to running processes. As the mounting of the /proc
+filesystem is optional on the Alpha, GDB automatically determines
+the availability of /proc during startup. This can lead to problems
+if /proc is unmounted after GDB has been started.
+
+* Arguments to user-defined commands
+
+User commands may accept up to 10 arguments separated by whitespace.
+Arguments are accessed within the user command via $arg0..$arg9. A
+trivial example:
+define adder
+ print $arg0 + $arg1 + $arg2
+
+To execute the command use:
+adder 1 2 3
+
+Defines the command "adder" which prints the sum of its three arguments.
+Note the arguments are text substitutions, so they may reference variables,
+use complex expressions, or even perform inferior function calls.
+
+* New `if' and `while' commands
+
+This makes it possible to write more sophisticated user-defined
+commands. Both commands take a single argument, which is the
+expression to evaluate, and must be followed by the commands to
+execute, one per line, if the expression is nonzero, the list being
+terminated by the word `end'. The `if' command list may include an
+`else' word, which causes the following commands to be executed only
+if the expression is zero.
+
+* Fortran source language mode
+
+GDB now includes partial support for Fortran 77. It will recognize
+Fortran programs and can evaluate a subset of Fortran expressions, but
+variables and functions may not be handled correctly. GDB will work
+with G77, but does not yet know much about symbols emitted by other
+Fortran compilers.
+
+* Better HPUX support
+
+Most debugging facilities now work on dynamic executables for HPPAs
+running hpux9 or later. You can attach to running dynamically linked
+processes, but by default the dynamic libraries will be read-only, so
+for instance you won't be able to put breakpoints in them. To change
+that behavior do the following before running the program:
+
+ adb -w a.out
+ __dld_flags?W 0x5
+ control-d
+
+This will cause the libraries to be mapped private and read-write.
+To revert to the normal behavior, do this:
+
+ adb -w a.out
+ __dld_flags?W 0x4
+ control-d
+
+You cannot set breakpoints or examine data in the library until after
+the library is loaded if the function/data symbols do not have
+external linkage.
+
+GDB can now also read debug symbols produced by the HP C compiler on
+HPPAs (sorry, no C++, Fortran or 68k support).
+
+* Target byte order now dynamically selectable
+
+You can choose which byte order to use with a target system, via the
+commands "set endian big" and "set endian little", and you can see the
+current setting by using "show endian". You can also give the command
+"set endian auto", in which case GDB will use the byte order
+associated with the executable. Currently, only embedded MIPS
+configurations support dynamic selection of target byte order.
+
+* New DOS host serial code
+
+This version uses DPMI interrupts to handle buffered I/O, so you
+no longer need to run asynctsr when debugging boards connected to
+a PC's serial port.
+
+*** Changes in GDB-4.13:
+
+* New "complete" command
+
+This lists all the possible completions for the rest of the line, if it
+were to be given as a command itself. This is intended for use by emacs.
+
+* Trailing space optional in prompt
+
+"set prompt" no longer adds a space for you after the prompt you set. This
+allows you to set a prompt which ends in a space or one that does not.
+
+* Breakpoint hit counts
+
+"info break" now displays a count of the number of times the breakpoint
+has been hit. This is especially useful in conjunction with "ignore"; you
+can ignore a large number of breakpoint hits, look at the breakpoint info
+to see how many times the breakpoint was hit, then run again, ignoring one
+less than that number, and this will get you quickly to the last hit of
+that breakpoint.
+
+* Ability to stop printing at NULL character
+
+"set print null-stop" will cause GDB to stop printing the characters of
+an array when the first NULL is encountered. This is useful when large
+arrays actually contain only short strings.
+
+* Shared library breakpoints
+
+In SunOS 4.x, SVR4, and Alpha OSF/1 configurations, you can now set
+breakpoints in shared libraries before the executable is run.
+
+* Hardware watchpoints
+
+There is a new hardware breakpoint for the watch command for sparclite
+targets. See gdb/sparclite/hw_breakpoint.note.
+
+Hardware watchpoints are also now supported under GNU/Linux.
+
+* Annotations
+
+Annotations have been added. These are for use with graphical interfaces,
+and are still experimental. Currently only gdba.el uses these.
+
+* Improved Irix 5 support
+
+GDB now works properly with Irix 5.2.
+
+* Improved HPPA support
+
+GDB now works properly with the latest GCC and GAS.
+
+* New native configurations
+
+Sequent PTX4 i[34]86-sequent-ptx4
+HPPA running OSF/1 hppa*-*-osf*
+Atari TT running SVR4 m68*-*-sysv4*
+RS/6000 LynxOS rs6000-*-lynxos*
+
+* New targets
+
+OS/9000 i[34]86-*-os9k
+MIPS R4000 mips64*{,el}-*-{ecoff,elf}
+Sparc64 sparc64-*-*
+
+* Hitachi SH7000 and E7000-PC ICE support
+
+There is now support for communicating with the Hitachi E7000-PC ICE.
+This is available automatically when GDB is configured for the SH.
+
+* Fixes
+
+As usual, a variety of small fixes and improvements, both generic
+and configuration-specific. See the ChangeLog for more detail.
+
+*** Changes in GDB-4.12:
+
+* Irix 5 is now supported
+
+* HPPA support
+
+GDB-4.12 on the HPPA has a number of changes which make it unable
+to debug the output from the currently released versions of GCC and
+GAS (GCC 2.5.8 and GAS-2.2 or PAGAS-1.36). Until the next major release
+of GCC and GAS, versions of these tools designed to work with GDB-4.12
+can be retrieved via anonymous ftp from jaguar.cs.utah.edu:/dist.
+
+
+*** Changes in GDB-4.11:
+
+* User visible changes:
+
+* Remote Debugging
+
+The "set remotedebug" option is now consistent between the mips remote
+target, remote targets using the gdb-specific protocol, UDI (AMD's
+debug protocol for the 29k) and the 88k bug monitor. It is now an
+integer specifying a debug level (normally 0 or 1, but 2 means more
+debugging info for the mips target).
+
+* DEC Alpha native support
+
+GDB now works on the DEC Alpha. GCC 2.4.5 does not produce usable
+debug info, but GDB works fairly well with the DEC compiler and should
+work with a future GCC release. See the README file for a few
+Alpha-specific notes.
+
+* Preliminary thread implementation
+
+GDB now has preliminary thread support for both SGI/Irix and LynxOS.
+
+* LynxOS native and target support for 386
+
+This release has been hosted on LynxOS 2.2, and also can be configured
+to remotely debug programs running under LynxOS (see gdb/gdbserver/README
+for details).
+
+* Improvements in C++ mangling/demangling.
+
+This release has much better g++ debugging, specifically in name
+mangling/demangling, virtual function calls, print virtual table,
+call methods, ...etc.
+
+*** Changes in GDB-4.10:
+
+ * User visible changes:
+
+Remote debugging using the GDB-specific (`target remote') protocol now
+supports the `load' command. This is only useful if you have some
+other way of getting the stub to the target system, and you can put it
+somewhere in memory where it won't get clobbered by the download.
+
+Filename completion now works.
+
+When run under emacs mode, the "info line" command now causes the
+arrow to point to the line specified. Also, "info line" prints
+addresses in symbolic form (as well as hex).
+
+All vxworks based targets now support a user settable option, called
+vxworks-timeout. This option represents the number of seconds gdb
+should wait for responses to rpc's. You might want to use this if
+your vxworks target is, perhaps, a slow software simulator or happens
+to be on the far side of a thin network line.
+
+ * DEC alpha support
+
+This release contains support for using a DEC alpha as a GDB host for
+cross debugging. Native alpha debugging is not supported yet.
+
+
+*** Changes in GDB-4.9:
+
+ * Testsuite
+
+This is the first GDB release which is accompanied by a matching testsuite.
+The testsuite requires installation of dejagnu, which should be available
+via ftp from most sites that carry GNU software.
+
+ * C++ demangling
+
+'Cfront' style demangling has had its name changed to 'ARM' style, to
+emphasize that it was written from the specifications in the C++ Annotated
+Reference Manual, not necessarily to be compatible with AT&T cfront. Despite
+disclaimers, it still generated too much confusion with users attempting to
+use gdb with AT&T cfront.
+
+ * Simulators
+
+GDB now uses a standard remote interface to a simulator library.
+So far, the library contains simulators for the Zilog Z8001/2, the
+Hitachi H8/300, H8/500 and Super-H.
+
+ * New targets supported
+
+H8/300 simulator h8300-hitachi-hms or h8300hms
+H8/500 simulator h8500-hitachi-hms or h8500hms
+SH simulator sh-hitachi-hms or sh
+Z8000 simulator z8k-zilog-none or z8ksim
+IDT MIPS board over serial line mips-idt-ecoff
+
+Cross-debugging to GO32 targets is supported. It requires a custom
+version of the i386-stub.c module which is integrated with the
+GO32 memory extender.
+
+ * New remote protocols
+
+MIPS remote debugging protocol.
+
+ * New source languages supported
+
+This version includes preliminary support for Chill, a Pascal like language
+used by telecommunications companies. Chill support is also being integrated
+into the GNU compiler, but we don't know when it will be publically available.
+
+
+*** Changes in GDB-4.8:
+
+ * HP Precision Architecture supported
+
+GDB now supports HP PA-RISC machines running HPUX. A preliminary
+version of this support was available as a set of patches from the
+University of Utah. GDB does not support debugging of programs
+compiled with the HP compiler, because HP will not document their file
+format. Instead, you must use GCC (version 2.3.2 or later) and PA-GAS
+(as available from jaguar.cs.utah.edu:/dist/pa-gas.u4.tar.Z).
+
+Many problems in the preliminary version have been fixed.
+
+ * Faster and better demangling
+
+We have improved template demangling and fixed numerous bugs in the GNU style
+demangler. It can now handle type modifiers such as `static' or `const'. Wide
+character types (wchar_t) are now supported. Demangling of each symbol is now
+only done once, and is cached when the symbol table for a file is read in.
+This results in a small increase in memory usage for C programs, a moderate
+increase in memory usage for C++ programs, and a fantastic speedup in
+symbol lookups.
+
+`Cfront' style demangling still doesn't work with AT&T cfront. It was written
+from the specifications in the Annotated Reference Manual, which AT&T's
+compiler does not actually implement.
+
+ * G++ multiple inheritance compiler problem
+
+In the 2.3.2 release of gcc/g++, how the compiler resolves multiple
+inheritance lattices was reworked to properly discover ambiguities. We
+recently found an example which causes this new algorithm to fail in a
+very subtle way, producing bad debug information for those classes.
+The file 'gcc.patch' (in this directory) can be applied to gcc to
+circumvent the problem. A future GCC release will contain a complete
+fix.
+
+The previous G++ debug info problem (mentioned below for the gdb-4.7
+release) is fixed in gcc version 2.3.2.
+
+ * Improved configure script
+
+The `configure' script will now attempt to guess your system type if
+you don't supply a host system type. The old scheme of supplying a
+host system triplet is preferable over using this. All the magic is
+done in the new `config.guess' script. Examine it for details.
+
+We have also brought our configure script much more in line with the FSF's
+version. It now supports the --with-xxx options. In particular,
+`--with-minimal-bfd' can be used to make the GDB binary image smaller.
+The resulting GDB will not be able to read arbitrary object file formats --
+only the format ``expected'' to be used on the configured target system.
+We hope to make this the default in a future release.
+
+ * Documentation improvements
+
+There's new internal documentation on how to modify GDB, and how to
+produce clean changes to the code. We implore people to read it
+before submitting changes.
+
+The GDB manual uses new, sexy Texinfo conditionals, rather than arcane
+M4 macros. The new texinfo.tex is provided in this release. Pre-built
+`info' files are also provided. To build `info' files from scratch,
+you will need the latest `makeinfo' release, which will be available in
+a future texinfo-X.Y release.
+
+*NOTE* The new texinfo.tex can cause old versions of TeX to hang.
+We're not sure exactly which versions have this problem, but it has
+been seen in 3.0. We highly recommend upgrading to TeX version 3.141
+or better. If that isn't possible, there is a patch in
+`texinfo/tex3patch' that will modify `texinfo/texinfo.tex' to work
+around this problem.
+
+ * New features
+
+GDB now supports array constants that can be used in expressions typed in by
+the user. The syntax is `{element, element, ...}'. Ie: you can now type
+`print {1, 2, 3}', and it will build up an array in memory malloc'd in
+the target program.
+
+The new directory `gdb/sparclite' contains a program that demonstrates
+how the sparc-stub.c remote stub runs on a Fujitsu SPARClite processor.
+
+ * New native hosts supported
+
+HP/PA-RISC under HPUX using GNU tools hppa1.1-hp-hpux
+386 CPUs running SCO Unix 3.2v4 i386-unknown-sco3.2v4
+
+ * New targets supported
+
+AMD 29k family via UDI a29k-amd-udi or udi29k
+
+ * New file formats supported
+
+BFD now supports reading HP/PA-RISC executables (SOM file format?),
+HPUX core files, and SCO 3.2v2 core files.
+
+ * Major bug fixes
+
+Attaching to processes now works again; thanks for the many bug reports.
+
+We have also stomped on a bunch of core dumps caused by
+printf_filtered("%s") problems.
+
+We eliminated a copyright problem on the rpc and ptrace header files
+for VxWorks, which was discovered at the last minute during the 4.7
+release. You should now be able to build a VxWorks GDB.
+
+You can now interrupt gdb while an attached process is running. This
+will cause the attached process to stop, and give control back to GDB.
+
+We fixed problems caused by using too many file descriptors
+for reading symbols from object files and libraries. This was
+especially a problem for programs that used many (~100) shared
+libraries.
+
+The `step' command now only enters a subroutine if there is line number
+information for the subroutine. Otherwise it acts like the `next'
+command. Previously, `step' would enter subroutines if there was
+any debugging information about the routine. This avoids problems
+when using `cc -g1' on MIPS machines.
+
+ * Internal improvements
+
+GDB's internal interfaces have been improved to make it easier to support
+debugging of multiple languages in the future.
+
+GDB now uses a common structure for symbol information internally.
+Minimal symbols (derived from linkage symbols in object files), partial
+symbols (from a quick scan of debug information), and full symbols
+contain a common subset of information, making it easier to write
+shared code that handles any of them.
+
+ * New command line options
+
+We now accept --silent as an alias for --quiet.
+
+ * Mmalloc licensing
+
+The memory-mapped-malloc library is now licensed under the GNU Library
+General Public License.
+
+*** Changes in GDB-4.7:
+
+ * Host/native/target split
+
+GDB has had some major internal surgery to untangle the support for
+hosts and remote targets. Now, when you configure GDB for a remote
+target, it will no longer load in all of the support for debugging
+local programs on the host. When fully completed and tested, this will
+ensure that arbitrary host/target combinations are possible.
+
+The primary conceptual shift is to separate the non-portable code in
+GDB into three categories. Host specific code is required any time GDB
+is compiled on that host, regardless of the target. Target specific
+code relates to the peculiarities of the target, but can be compiled on
+any host. Native specific code is everything else: it can only be
+built when the host and target are the same system. Child process
+handling and core file support are two common `native' examples.
+
+GDB's use of /proc for controlling Unix child processes is now cleaner.
+It has been split out into a single module under the `target_ops' vector,
+plus two native-dependent functions for each system that uses /proc.
+
+ * New hosts supported
+
+HP/Apollo 68k (under the BSD domain) m68k-apollo-bsd or apollo68bsd
+386 CPUs running various BSD ports i386-unknown-bsd or 386bsd
+386 CPUs running SCO Unix i386-unknown-scosysv322 or i386sco
+
+ * New targets supported
+
+Fujitsu SPARClite sparclite-fujitsu-none or sparclite
+68030 and CPU32 m68030-*-*, m68332-*-*
+
+ * New native hosts supported
+
+386 CPUs running various BSD ports i386-unknown-bsd or 386bsd
+ (386bsd is not well tested yet)
+386 CPUs running SCO Unix i386-unknown-scosysv322 or sco
+
+ * New file formats supported
+
+BFD now supports COFF files for the Zilog Z8000 microprocessor. It
+supports reading of `a.out.adobe' object files, which are an a.out
+format extended with minimal information about multiple sections.
+
+ * New commands
+
+`show copying' is the same as the old `info copying'.
+`show warranty' is the same as `info warrantee'.
+These were renamed for consistency. The old commands continue to work.
+
+`info handle' is a new alias for `info signals'.
+
+You can now define pre-command hooks, which attach arbitrary command
+scripts to any command. The commands in the hook will be executed
+prior to the user's command. You can also create a hook which will be
+executed whenever the program stops. See gdb.texinfo.
+
+ * C++ improvements
+
+We now deal with Cfront style name mangling, and can even extract type
+info from mangled symbols. GDB can automatically figure out which
+symbol mangling style your C++ compiler uses.
+
+Calling of methods and virtual functions has been improved as well.
+
+ * Major bug fixes
+
+The crash that occured when debugging Sun Ansi-C compiled binaries is
+fixed. This was due to mishandling of the extra N_SO stabs output
+by the compiler.
+
+We also finally got Ultrix 4.2 running in house, and fixed core file
+support, with help from a dozen people on the net.
+
+John M. Farrell discovered that the reason that single-stepping was so
+slow on all of the Mips based platforms (primarily SGI and DEC) was
+that we were trying to demangle and lookup a symbol used for internal
+purposes on every instruction that was being stepped through. Changing
+the name of that symbol so that it couldn't be mistaken for a C++
+mangled symbol sped things up a great deal.
+
+Rich Pixley sped up symbol lookups in general by getting much smarter
+about when C++ symbol mangling is necessary. This should make symbol
+completion (TAB on the command line) much faster. It's not as fast as
+we'd like, but it's significantly faster than gdb-4.6.
+
+ * AMD 29k support
+
+A new user controllable variable 'call_scratch_address' can
+specify the location of a scratch area to be used when GDB
+calls a function in the target. This is necessary because the
+usual method of putting the scratch area on the stack does not work
+in systems that have separate instruction and data spaces.
+
+We integrated changes to support the 29k UDI (Universal Debugger
+Interface), but discovered at the last minute that we didn't have all
+of the appropriate copyright paperwork. We are working with AMD to
+resolve this, and hope to have it available soon.
+
+ * Remote interfaces
+
+We have sped up the remote serial line protocol, especially for targets
+with lots of registers. It now supports a new `expedited status' ('T')
+message which can be used in place of the existing 'S' status message.
+This allows the remote stub to send only the registers that GDB
+needs to make a quick decision about single-stepping or conditional
+breakpoints, eliminating the need to fetch the entire register set for
+each instruction being stepped through.
+
+The GDB remote serial protocol now implements a write-through cache for
+registers, only re-reading the registers if the target has run.
+
+There is also a new remote serial stub for SPARC processors. You can
+find it in gdb-4.7/gdb/sparc-stub.c. This was written to support the
+Fujitsu SPARClite processor, but will run on any stand-alone SPARC
+processor with a serial port.
+
+ * Configuration
+
+Configure.in files have become much easier to read and modify. A new
+`table driven' format makes it more obvious what configurations are
+supported, and what files each one uses.
+
+ * Library changes
+
+There is a new opcodes library which will eventually contain all of the
+disassembly routines and opcode tables. At present, it only contains
+Sparc and Z8000 routines. This will allow the assembler, debugger, and
+disassembler (binutils/objdump) to share these routines.
+
+The libiberty library is now copylefted under the GNU Library General
+Public License. This allows more liberal use, and was done so libg++
+can use it. This makes no difference to GDB, since the Library License
+grants all the rights from the General Public License.
+
+ * Documentation
+
+The file gdb-4.7/gdb/doc/stabs.texinfo is a (relatively) complete
+reference to the stabs symbol info used by the debugger. It is (as far
+as we know) the only published document on this fascinating topic. We
+encourage you to read it, compare it to the stabs information on your
+system, and send improvements on the document in general (to
+bug-gdb@prep.ai.mit.edu).
+
+And, of course, many bugs have been fixed.
+
+
+*** Changes in GDB-4.6:
+
+ * Better support for C++ function names
+
+GDB now accepts as input the "demangled form" of C++ overloaded function
+names and member function names, and can do command completion on such names
+(using TAB, TAB-TAB, and ESC-?). The names have to be quoted with a pair of
+single quotes. Examples are 'func (int, long)' and 'obj::operator==(obj&)'.
+Make use of command completion, it is your friend.
+
+GDB also now accepts a variety of C++ mangled symbol formats. They are
+the GNU g++ style, the Cfront (ARM) style, and the Lucid (lcc) style.
+You can tell GDB which format to use by doing a 'set demangle-style {gnu,
+lucid, cfront, auto}'. 'gnu' is the default. Do a 'set demangle-style foo'
+for the list of formats.
+
+ * G++ symbol mangling problem
+
+Recent versions of gcc have a bug in how they emit debugging information for
+C++ methods (when using dbx-style stabs). The file 'gcc.patch' (in this
+directory) can be applied to gcc to fix the problem. Alternatively, if you
+can't fix gcc, you can #define GCC_MANGLE_BUG when compling gdb/symtab.c. The
+usual symptom is difficulty with setting breakpoints on methods. GDB complains
+about the method being non-existent. (We believe that version 2.2.2 of GCC has
+this problem.)
+
+ * New 'maintenance' command
+
+All of the commands related to hacking GDB internals have been moved out of
+the main command set, and now live behind the 'maintenance' command. This
+can also be abbreviated as 'mt'. The following changes were made:
+
+ dump-me -> maintenance dump-me
+ info all-breakpoints -> maintenance info breakpoints
+ printmsyms -> maintenance print msyms
+ printobjfiles -> maintenance print objfiles
+ printpsyms -> maintenance print psymbols
+ printsyms -> maintenance print symbols
+
+The following commands are new:
+
+ maintenance demangle Call internal GDB demangler routine to
+ demangle a C++ link name and prints the result.
+ maintenance print type Print a type chain for a given symbol
+
+ * Change to .gdbinit file processing
+
+We now read the $HOME/.gdbinit file before processing the argv arguments
+(e.g. reading symbol files or core files). This allows global parameters to
+be set, which will apply during the symbol reading. The ./.gdbinit is still
+read after argv processing.
+
+ * New hosts supported
+
+Solaris-2.0 !!! sparc-sun-solaris2 or sun4sol2
+
+GNU/Linux support i386-unknown-linux or linux
+
+We are also including code to support the HP/PA running BSD and HPUX. This
+is almost guaranteed not to work, as we didn't have time to test or build it
+for this release. We are including it so that the more adventurous (or
+masochistic) of you can play with it. We also had major problems with the
+fact that the compiler that we got from HP doesn't support the -g option.
+It costs extra.
+
+ * New targets supported
+
+Hitachi H8/300 h8300-hitachi-hms or h8300hms
+
+ * More smarts about finding #include files
+
+GDB now remembers the compilation directory for all include files, and for
+all files from which C is generated (like yacc and lex sources). This
+greatly improves GDB's ability to find yacc/lex sources, and include files,
+especially if you are debugging your program from a directory different from
+the one that contains your sources.
+
+We also fixed a bug which caused difficulty with listing and setting
+breakpoints in include files which contain C code. (In the past, you had to
+try twice in order to list an include file that you hadn't looked at before.)
+
+ * Interesting infernals change
+
+GDB now deals with arbitrary numbers of sections, where the symbols for each
+section must be relocated relative to that section's landing place in the
+target's address space. This work was needed to support ELF with embedded
+stabs used by Solaris-2.0.
+
+ * Bug fixes (of course!)
+
+There have been loads of fixes for the following things:
+ mips, rs6000, 29k/udi, m68k, g++, type handling, elf/dwarf, m88k,
+ i960, stabs, DOS(GO32), procfs, etc...
+
+See the ChangeLog for details.
+
+*** Changes in GDB-4.5:
+
+ * New machines supported (host and target)
+
+IBM RS6000 running AIX rs6000-ibm-aix or rs6000
+
+SGI Irix-4.x mips-sgi-irix4 or iris4
+
+ * New malloc package
+
+GDB now uses a new memory manager called mmalloc, based on gmalloc.
+Mmalloc is capable of handling mutiple heaps of memory. It is also
+capable of saving a heap to a file, and then mapping it back in later.
+This can be used to greatly speedup the startup of GDB by using a
+pre-parsed symbol table which lives in a mmalloc managed heap. For
+more details, please read mmalloc/mmalloc.texi.
+
+ * info proc
+
+The 'info proc' command (SVR4 only) has been enhanced quite a bit. See
+'help info proc' for details.
+
+ * MIPS ecoff symbol table format
+
+The code that reads MIPS symbol table format is now supported on all hosts.
+Thanks to MIPS for releasing the sym.h and symconst.h files to make this
+possible.
+
+ * File name changes for MS-DOS
+
+Many files in the config directories have been renamed to make it easier to
+support GDB on MS-DOSe systems (which have very restrictive file name
+conventions :-( ). MS-DOSe host support (under DJ Delorie's GO32
+environment) is close to working but has some remaining problems. Note
+that debugging of DOS programs is not supported, due to limitations
+in the ``operating system'', but it can be used to host cross-debugging.
+
+ * Cross byte order fixes
+
+Many fixes have been made to support cross debugging of Sparc and MIPS
+targets from hosts whose byte order differs.
+
+ * New -mapped and -readnow options
+
+If memory-mapped files are available on your system through the 'mmap'
+system call, you can use the -mapped option on the `file' or
+`symbol-file' commands to cause GDB to write the symbols from your
+program into a reusable file. If the program you are debugging is
+called `/path/fred', the mapped symbol file will be `./fred.syms'.
+Future GDB debugging sessions will notice the presence of this file,
+and will quickly map in symbol information from it, rather than reading
+the symbol table from the executable program. Using the '-mapped'
+option in a GDB `file' or `symbol-file' command has the same effect as
+starting GDB with the '-mapped' command-line option.
+
+You can cause GDB to read the entire symbol table immediately by using
+the '-readnow' option with any of the commands that load symbol table
+information (or on the GDB command line). This makes the command
+slower, but makes future operations faster.
+
+The -mapped and -readnow options are typically combined in order to
+build a `fred.syms' file that contains complete symbol information.
+A simple GDB invocation to do nothing but build a `.syms' file for future
+use is:
+
+ gdb -batch -nx -mapped -readnow programname
+
+The `.syms' file is specific to the host machine on which GDB is run.
+It holds an exact image of GDB's internal symbol table. It cannot be
+shared across multiple host platforms.
+
+ * longjmp() handling
+
+GDB is now capable of stepping and nexting over longjmp(), _longjmp(), and
+siglongjmp() without losing control. This feature has not yet been ported to
+all systems. It currently works on many 386 platforms, all MIPS-based
+platforms (SGI, DECstation, etc), and Sun3/4.
+
+ * Solaris 2.0
+
+Preliminary work has been put in to support the new Solaris OS from Sun. At
+this time, it can control and debug processes, but it is not capable of
+reading symbols.
+
+ * Bug fixes
+
+As always, many many bug fixes. The major areas were with g++, and mipsread.
+People using the MIPS-based platforms should experience fewer mysterious
+crashes and trashed symbol tables.
+
+*** Changes in GDB-4.4:
+
+ * New machines supported (host and target)
+
+SCO Unix on i386 IBM PC clones i386-sco-sysv or i386sco
+ (except core files)
+BSD Reno on Vax vax-dec-bsd
+Ultrix on Vax vax-dec-ultrix
+
+ * New machines supported (target)
+
+AMD 29000 embedded, using EBMON a29k-none-none
+
+ * C++ support
+
+GDB continues to improve its handling of C++. `References' work better.
+The demangler has also been improved, and now deals with symbols mangled as
+per the Annotated C++ Reference Guide.
+
+GDB also now handles `stabs' symbol information embedded in MIPS
+`ecoff' symbol tables. Since the ecoff format was not easily
+extensible to handle new languages such as C++, this appeared to be a
+good way to put C++ debugging info into MIPS binaries. This option
+will be supported in the GNU C compiler, version 2, when it is
+released.
+
+ * New features for SVR4
+
+GDB now handles SVR4 shared libraries, in the same fashion as SunOS
+shared libraries. Debugging dynamically linked programs should present
+only minor differences from debugging statically linked programs.
+
+The `info proc' command will print out information about any process
+on an SVR4 system (including the one you are debugging). At the moment,
+it prints the address mappings of the process.
+
+If you bring up GDB on another SVR4 system, please send mail to
+bug-gdb@prep.ai.mit.edu to let us know what changes were reqired (if any).
+
+ * Better dynamic linking support in SunOS
+
+Reading symbols from shared libraries which contain debugging symbols
+now works properly. However, there remain issues such as automatic
+skipping of `transfer vector' code during function calls, which
+make it harder to debug code in a shared library, than to debug the
+same code linked statically.
+
+ * New Getopt
+
+GDB is now using the latest `getopt' routines from the FSF. This
+version accepts the -- prefix for options with long names. GDB will
+continue to accept the old forms (-option and +option) as well.
+Various single letter abbreviations for options have been explicity
+added to the option table so that they won't get overshadowed in the
+future by other options that begin with the same letter.
+
+ * Bugs fixed
+
+The `cleanup_undefined_types' bug that many of you noticed has been squashed.
+Many assorted bugs have been handled. Many more remain to be handled.
+See the various ChangeLog files (primarily in gdb and bfd) for details.
+
+
+*** Changes in GDB-4.3:
+
+ * New machines supported (host and target)
+
+Amiga 3000 running Amix m68k-cbm-svr4 or amix
+NCR 3000 386 running SVR4 i386-ncr-svr4 or ncr3000
+Motorola Delta 88000 running Sys V m88k-motorola-sysv or delta88
+
+ * Almost SCO Unix support
+
+We had hoped to support:
+SCO Unix on i386 IBM PC clones i386-sco-sysv or i386sco
+(except for core file support), but we discovered very late in the release
+that it has problems with process groups that render gdb unusable. Sorry
+about that. I encourage people to fix it and post the fixes.
+
+ * Preliminary ELF and DWARF support
+
+GDB can read ELF object files on System V Release 4, and can handle
+debugging records for C, in DWARF format, in ELF files. This support
+is preliminary. If you bring up GDB on another SVR4 system, please
+send mail to bug-gdb@prep.ai.mit.edu to let us know what changes were
+reqired (if any).
+
+ * New Readline
+
+GDB now uses the latest `readline' library. One user-visible change
+is that two tabs will list possible command completions, which previously
+required typing M-? (meta-question mark, or ESC ?).
+
+ * Bugs fixed
+
+The `stepi' bug that many of you noticed has been squashed.
+Many bugs in C++ have been handled. Many more remain to be handled.
+See the various ChangeLog files (primarily in gdb and bfd) for details.
+
+ * State of the MIPS world (in case you wondered):
+
+GDB can understand the symbol tables emitted by the compilers
+supplied by most vendors of MIPS-based machines, including DEC. These
+symbol tables are in a format that essentially nobody else uses.
+
+Some versions of gcc come with an assembler post-processor called
+mips-tfile. This program is required if you want to do source-level
+debugging of gcc-compiled programs. I believe FSF does not ship
+mips-tfile with gcc version 1, but it will eventually come with gcc
+version 2.
+
+Debugging of g++ output remains a problem. g++ version 1.xx does not
+really support it at all. (If you're lucky, you should be able to get
+line numbers and stack traces to work, but no parameters or local
+variables.) With some work it should be possible to improve the
+situation somewhat.
+
+When gcc version 2 is released, you will have somewhat better luck.
+However, even then you will get confusing results for inheritance and
+methods.
+
+We will eventually provide full debugging of g++ output on
+DECstations. This will probably involve some kind of stabs-in-ecoff
+encapulation, but the details have not been worked out yet.
+
+
+*** Changes in GDB-4.2:
+
+ * Improved configuration
+
+Only one copy of `configure' exists now, and it is not self-modifying.
+Porting BFD is simpler.
+
+ * Stepping improved
+
+The `step' and `next' commands now only stop at the first instruction
+of a source line. This prevents the multiple stops that used to occur
+in switch statements, for-loops, etc. `Step' continues to stop if a
+function that has debugging information is called within the line.
+
+ * Bug fixing
+
+Lots of small bugs fixed. More remain.
+
+ * New host supported (not target)
+
+Intel 386 PC clone running Mach i386-none-mach
+
+
+*** Changes in GDB-4.1:
+
+ * Multiple source language support
+
+GDB now has internal scaffolding to handle several source languages.
+It determines the type of each source file from its filename extension,
+and will switch expression parsing and number formatting to match the
+language of the function in the currently selected stack frame.
+You can also specifically set the language to be used, with
+`set language c' or `set language modula-2'.
+
+ * GDB and Modula-2
+
+GDB now has preliminary support for the GNU Modula-2 compiler,
+currently under development at the State University of New York at
+Buffalo. Development of both GDB and the GNU Modula-2 compiler will
+continue through the fall of 1991 and into 1992.
+
+Other Modula-2 compilers are currently not supported, and attempting to
+debug programs compiled with them will likely result in an error as the
+symbol table is read. Feel free to work on it, though!
+
+There are hooks in GDB for strict type checking and range checking,
+in the `Modula-2 philosophy', but they do not currently work.
+
+ * set write on/off
+
+GDB can now write to executable and core files (e.g. patch
+a variable's value). You must turn this switch on, specify
+the file ("exec foo" or "core foo"), *then* modify it, e.g.
+by assigning a new value to a variable. Modifications take
+effect immediately.
+
+ * Automatic SunOS shared library reading
+
+When you run your program, GDB automatically determines where its
+shared libraries (if any) have been loaded, and reads their symbols.
+The `share' command is no longer needed. This also works when
+examining core files.
+
+ * set listsize
+
+You can specify the number of lines that the `list' command shows.
+The default is 10.
+
+ * New machines supported (host and target)
+
+SGI Iris (MIPS) running Irix V3: mips-sgi-irix or iris
+Sony NEWS (68K) running NEWSOS 3.x: m68k-sony-sysv or news
+Ultracomputer (29K) running Sym1: a29k-nyu-sym1 or ultra3
+
+ * New hosts supported (not targets)
+
+IBM RT/PC: romp-ibm-aix or rtpc
+
+ * New targets supported (not hosts)
+
+AMD 29000 embedded with COFF a29k-none-coff
+AMD 29000 embedded with a.out a29k-none-aout
+Ultracomputer remote kernel debug a29k-nyu-kern
+
+ * New remote interfaces
+
+AMD 29000 Adapt
+AMD 29000 Minimon
+
+
+*** Changes in GDB-4.0:
+
+ * New Facilities
+
+Wide output is wrapped at good places to make the output more readable.
+
+Gdb now supports cross-debugging from a host machine of one type to a
+target machine of another type. Communication with the target system
+is over serial lines. The ``target'' command handles connecting to the
+remote system; the ``load'' command will download a program into the
+remote system. Serial stubs for the m68k and i386 are provided. Gdb
+also supports debugging of realtime processes running under VxWorks,
+using SunRPC Remote Procedure Calls over TCP/IP to talk to a debugger
+stub on the target system.
+
+New CPUs supported include the AMD 29000 and Intel 960.
+
+GDB now reads object files and symbol tables via a ``binary file''
+library, which allows a single copy of GDB to debug programs of multiple
+object file types such as a.out and coff.
+
+There is now a GDB reference card in "doc/refcard.tex". (Make targets
+refcard.dvi and refcard.ps are available to format it).
+
+
+ * Control-Variable user interface simplified
+
+All variables that control the operation of the debugger can be set
+by the ``set'' command, and displayed by the ``show'' command.
+
+For example, ``set prompt new-gdb=>'' will change your prompt to new-gdb=>.
+``Show prompt'' produces the response:
+Gdb's prompt is new-gdb=>.
+
+What follows are the NEW set commands. The command ``help set'' will
+print a complete list of old and new set commands. ``help set FOO''
+will give a longer description of the variable FOO. ``show'' will show
+all of the variable descriptions and their current settings.
+
+confirm on/off: Enables warning questions for operations that are
+ hard to recover from, e.g. rerunning the program while
+ it is already running. Default is ON.
+
+editing on/off: Enables EMACS style command line editing
+ of input. Previous lines can be recalled with
+ control-P, the current line can be edited with control-B,
+ you can search for commands with control-R, etc.
+ Default is ON.
+
+history filename NAME: NAME is where the gdb command history
+ will be stored. The default is .gdb_history,
+ or the value of the environment variable
+ GDBHISTFILE.
+
+history size N: The size, in commands, of the command history. The
+ default is 256, or the value of the environment variable
+ HISTSIZE.
+
+history save on/off: If this value is set to ON, the history file will
+ be saved after exiting gdb. If set to OFF, the
+ file will not be saved. The default is OFF.
+
+history expansion on/off: If this value is set to ON, then csh-like
+ history expansion will be performed on
+ command line input. The default is OFF.
+
+radix N: Sets the default radix for input and output. It can be set
+ to 8, 10, or 16. Note that the argument to "radix" is interpreted
+ in the current radix, so "set radix 10" is always a no-op.
+
+height N: This integer value is the number of lines on a page. Default
+ is 24, the current `stty rows'' setting, or the ``li#''
+ setting from the termcap entry matching the environment
+ variable TERM.
+
+width N: This integer value is the number of characters on a line.
+ Default is 80, the current `stty cols'' setting, or the ``co#''
+ setting from the termcap entry matching the environment
+ variable TERM.
+
+Note: ``set screensize'' is obsolete. Use ``set height'' and
+``set width'' instead.
+
+print address on/off: Print memory addresses in various command displays,
+ such as stack traces and structure values. Gdb looks
+ more ``symbolic'' if you turn this off; it looks more
+ ``machine level'' with it on. Default is ON.
+
+print array on/off: Prettyprint arrays. New convenient format! Default
+ is OFF.
+
+print demangle on/off: Print C++ symbols in "source" form if on,
+ "raw" form if off.
+
+print asm-demangle on/off: Same, for assembler level printouts
+ like instructions.
+
+print vtbl on/off: Prettyprint C++ virtual function tables. Default is OFF.
+
+
+ * Support for Epoch Environment.
+
+The epoch environment is a version of Emacs v18 with windowing. One
+new command, ``inspect'', is identical to ``print'', except that if you
+are running in the epoch environment, the value is printed in its own
+window.
+
+
+ * Support for Shared Libraries
+
+GDB can now debug programs and core files that use SunOS shared libraries.
+Symbols from a shared library cannot be referenced
+before the shared library has been linked with the program (this
+happens after you type ``run'' and before the function main() is entered).
+At any time after this linking (including when examining core files
+from dynamically linked programs), gdb reads the symbols from each
+shared library when you type the ``sharedlibrary'' command.
+It can be abbreviated ``share''.
+
+sharedlibrary REGEXP: Load shared object library symbols for files
+ matching a unix regular expression. No argument
+ indicates to load symbols for all shared libraries.
+
+info sharedlibrary: Status of loaded shared libraries.
+
+
+ * Watchpoints
+
+A watchpoint stops execution of a program whenever the value of an
+expression changes. Checking for this slows down execution
+tremendously whenever you are in the scope of the expression, but is
+quite useful for catching tough ``bit-spreader'' or pointer misuse
+problems. Some machines such as the 386 have hardware for doing this
+more quickly, and future versions of gdb will use this hardware.
+
+watch EXP: Set a watchpoint (breakpoint) for an expression.
+
+info watchpoints: Information about your watchpoints.
+
+delete N: Deletes watchpoint number N (same as breakpoints).
+disable N: Temporarily turns off watchpoint number N (same as breakpoints).
+enable N: Re-enables watchpoint number N (same as breakpoints).
+
+
+ * C++ multiple inheritance
+
+When used with a GCC version 2 compiler, GDB supports multiple inheritance
+for C++ programs.
+
+ * C++ exception handling
+
+Gdb now supports limited C++ exception handling. Besides the existing
+ability to breakpoint on an exception handler, gdb can breakpoint on
+the raising of an exception (before the stack is peeled back to the
+handler's context).
+
+catch FOO: If there is a FOO exception handler in the dynamic scope,
+ set a breakpoint to catch exceptions which may be raised there.
+ Multiple exceptions (``catch foo bar baz'') may be caught.
+
+info catch: Lists all exceptions which may be caught in the
+ current stack frame.
+
+
+ * Minor command changes
+
+The command ``call func (arg, arg, ...)'' now acts like the print
+command, except it does not print or save a value if the function's result
+is void. This is similar to dbx usage.
+
+The ``up'' and ``down'' commands now always print the frame they end up
+at; ``up-silently'' and `down-silently'' can be used in scripts to change
+frames without printing.
+
+ * New directory command
+
+'dir' now adds directories to the FRONT of the source search path.
+The path starts off empty. Source files that contain debug information
+about the directory in which they were compiled can be found even
+with an empty path; Sun CC and GCC include this information. If GDB can't
+find your source file in the current directory, type "dir .".
+
+ * Configuring GDB for compilation
+
+For normal use, type ``./configure host''. See README or gdb.texinfo
+for more details.
+
+GDB now handles cross debugging. If you are remotely debugging between
+two different machines, type ``./configure host -target=targ''.
+Host is the machine where GDB will run; targ is the machine
+where the program that you are debugging will run.
diff --git a/gdb/PROBLEMS b/gdb/PROBLEMS
new file mode 100644
index 00000000000..49d27967daa
--- /dev/null
+++ b/gdb/PROBLEMS
@@ -0,0 +1,32 @@
+
+ Known problems in GDB 5.2
+
+ See also: http://www.gnu.org/software/gdb/bugs/
+
+
+hppa2.0-hp-hpux10.20
+--------------------
+
+gdb/487: The top level make files used to build GDB are not compatible
+with HP/UX make. As a workaround, use GNU make.
+
+gdb/486: The HP/UX C compiler defaults to K&R mode but GDB only builds
+with an ISO C compiler. The top level configuration incorrectly sets
+CC to `cc' instead of `cc -Ae'. As a workaround, the correct compiler
+can be specified as part of the configuration vis:
+
+ $ 'CC=cc -Ae' ./configure
+
+
+s390*-*-*
+---------
+
+gdb/513: GDB does not build on s390 GNU/Linux. The problem should be
+fixed in more recent sources.
+
+
+i386-*-freebsd4.4*
+------------------
+
+gdb/455: GDB doesn't build on a FreeBSD 4.4-STABLE system. The
+problem is still being investigated.
diff --git a/gdb/README b/gdb/README
new file mode 100644
index 00000000000..8af440fbd68
--- /dev/null
+++ b/gdb/README
@@ -0,0 +1,578 @@
+ README for gdb-5.2 release
+ Updated 17 April, 2002 by Andrew Cagney
+
+This is GDB, the GNU source-level debugger.
+
+A summary of new features is in the file `gdb/NEWS'.
+
+Check the GDB home page at http://www.gnu.org/software/gdb/ for up to
+date release information, mailing list links and archives, etc.
+
+The file `gdb/PROBLEMS' contains information on problems identified
+late in the release cycle. GDB's bug tracking data base at
+http://www.gnu.org/software/gdb/bugs/ contains a more complete list of
+bugs.
+
+
+Unpacking and Installation -- quick overview
+==========================
+
+ In this release, the GDB debugger sources, the generic GNU include
+files, the BFD ("binary file description") library, the readline
+library, and other libraries all have directories of their own
+underneath the gdb-5.2 directory. The idea is that a variety of GNU
+tools can share a common copy of these things. Be aware of variation
+over time--for example don't try to build gdb with a copy of bfd from
+a release other than the gdb release (such as a binutils release),
+especially if the releases are more than a few weeks apart.
+Configuration scripts and makefiles exist to cruise up and down this
+directory tree and automatically build all the pieces in the right
+order.
+
+ When you unpack the gdb-5.2.tar.gz file, you'll find a directory
+called `gdb-5.2', which contains:
+
+ COPYING config.sub intl missing opcodes
+ COPYING.LIB configure libiberty mkinstalldirs readline
+ Makefile.in configure.in libtool.m4 mmalloc sim
+ README djunpack.bat ltcf-c.sh move-if-change symlink-tree
+ bfd etc ltcf-cxx.sh mpw-README texinfo
+ config gdb ltcf-gcj.sh mpw-build.in utils
+ config-ml.in gettext.m4 ltconfig mpw-config.in ylwrap
+ config.guess include ltmain.sh mpw-configure
+ config.if install-sh md5.sum mpw-install
+
+You can build GDB right in the source directory:
+
+ cd gdb-5.2
+ ./configure
+ make
+ cp gdb/gdb /usr/local/bin/gdb (or wherever you want)
+
+However, we recommend that an empty directory be used instead.
+This way you do not clutter your source tree with binary files
+and will be able to create different builds with different
+configuration options.
+
+You can build GDB in any empty build directory:
+
+ mkdir build
+ cd build
+ <full path to your sources>/gdb-5.2/configure
+ make
+ cp gdb/gdb /usr/local/bin/gdb (or wherever you want)
+
+(Building GDB with DJGPP tools for MS-DOS/MS-Windows is slightly
+different; see the file gdb-5.2/gdb/config/djgpp/README for details.)
+
+ This will configure and build all the libraries as well as GDB. If
+`configure' can't determine your system type, specify one as its
+argument, e.g., `./configure sun4' or `./configure decstation'.
+
+ If you get compiler errors during this stage, see the `Reporting
+Bugs' section below; there are a few known problems.
+
+ GDB requires an ISO C (ANSI C) compiler. If you do not have an ISO
+C compiler for your system, you may be able to download and install
+the GNU CC compiler. It is available via anonymous FTP from the
+directory `ftp://ftp.gnu.org/pub/gnu/gcc'.
+
+ GDB can be used as a cross-debugger, running on a machine of one
+type while debugging a program running on a machine of another type.
+See below.
+
+
+More Documentation
+******************
+
+ All the documentation for GDB comes as part of the machine-readable
+distribution. The documentation is written in Texinfo format, which
+is a documentation system that uses a single source file to produce
+both on-line information and a printed manual. You can use one of the
+Info formatting commands to create the on-line version of the
+documentation and TeX (or `texi2roff') to typeset the printed version.
+
+ GDB includes an already formatted copy of the on-line Info version
+of this manual in the `gdb/doc' subdirectory. The main Info file is
+`gdb-5.2/gdb/doc/gdb.info', and it refers to subordinate files
+matching `gdb.info*' in the same directory. If necessary, you can
+print out these files, or read them with any editor; but they are
+easier to read using the `info' subsystem in GNU Emacs or the
+standalone `info' program, available as part of the GNU Texinfo
+distribution.
+
+ If you want to format these Info files yourself, you need one of the
+Info formatting programs, such as `texinfo-format-buffer' or
+`makeinfo'.
+
+ If you have `makeinfo' installed, and are in the top level GDB
+source directory (`gdb-5.2', in the case of version 5.2), you can make
+the Info file by typing:
+
+ cd gdb/doc
+ make info
+
+ If you want to typeset and print copies of this manual, you need
+TeX, a program to print its DVI output files, and `texinfo.tex', the
+Texinfo definitions file. This file is included in the GDB
+distribution, in the directory `gdb-5.2/texinfo'.
+
+ TeX is a typesetting program; it does not print files directly, but
+produces output files called DVI files. To print a typeset document,
+you need a program to print DVI files. If your system has TeX
+installed, chances are it has such a program. The precise command to
+use depends on your system; `lpr -d' is common; another (for PostScript
+devices) is `dvips'. The DVI print command may require a file name
+without any extension or a `.dvi' extension.
+
+ TeX also requires a macro definitions file called `texinfo.tex'.
+This file tells TeX how to typeset a document written in Texinfo
+format. On its own, TeX cannot read, much less typeset a Texinfo file.
+ `texinfo.tex' is distributed with GDB and is located in the
+`gdb-5.2/texinfo' directory.
+
+ If you have TeX and a DVI printer program installed, you can typeset
+and print this manual. First switch to the the `gdb' subdirectory of
+the main source directory (for example, to `gdb-5.2/gdb') and then type:
+
+ make doc/gdb.dvi
+
+ If you prefer to have the manual in PDF format, type this from the
+`gdb/doc' subdirectory of the main source directory:
+
+ make gdb.pdf
+
+For this to work, you will need the PDFTeX package to be installed.
+
+
+Installing GDB
+**************
+
+ GDB comes with a `configure' script that automates the process of
+preparing GDB for installation; you can then use `make' to build the
+`gdb' program.
+
+ The GDB distribution includes all the source code you need for GDB in
+a single directory, whose name is usually composed by appending the
+version number to `gdb'.
+
+ For example, the GDB version 5.2 distribution is in the `gdb-5.2'
+directory. That directory contains:
+
+`gdb-5.2/{COPYING,COPYING.LIB}'
+ Standard GNU license files. Please read them.
+
+`gdb-5.2/bfd'
+ source for the Binary File Descriptor library
+
+`gdb-5.2/config*'
+ script for configuring GDB, along with other support files
+
+`gdb-5.2/gdb'
+ the source specific to GDB itself
+
+`gdb-5.2/include'
+ GNU include files
+
+`gdb-5.2/libiberty'
+ source for the `-liberty' free software library
+
+`gdb-5.2/mmalloc'
+ source for the GNU memory-mapped malloc package
+
+`gdb-5.2/opcodes'
+ source for the library of opcode tables and disassemblers
+
+`gdb-5.2/readline'
+ source for the GNU command-line interface
+ NOTE: The readline library is compiled for use by GDB, but will
+ not be installed on your system when "make install" is issued.
+
+`gdb-5.2/sim'
+ source for some simulators (ARM, D10V, SPARC, M32R, MIPS, PPC, V850, etc)
+
+`gdb-5.2/intl'
+ source for the GNU gettext library, for internationalization.
+ This is slightly modified from the standalone gettext
+ distribution you can get from GNU.
+
+`gdb-5.2/texinfo'
+ The `texinfo.tex' file, which you need in order to make a printed
+ manual using TeX.
+
+`gdb-5.2/etc'
+ Coding standards, useful files for editing GDB, and other
+ miscellanea.
+
+`gdb-5.2/utils'
+ A grab bag of random utilities.
+
+ Note: the following instructions are for building GDB on Unix or
+Unix-like systems. Instructions for building with DJGPP for
+MS-DOS/MS-Windows are in the file gdb/config/djgpp/README.
+
+ The simplest way to configure and build GDB is to run `configure'
+from the `gdb-VERSION-NUMBER' source directory, which in this example
+is the `gdb-5.2' directory.
+
+ First switch to the `gdb-VERSION-NUMBER' source directory if you are
+not already in it; then run `configure'.
+
+ For example:
+
+ cd gdb-5.2
+ ./configure
+ make
+
+ Running `configure' followed by `make' builds the `bfd',
+`readline', `mmalloc', and `libiberty' libraries, then `gdb' itself.
+The configured source files, and the binaries, are left in the
+corresponding source directories.
+
+ `configure' is a Bourne-shell (`/bin/sh') script; if your system
+does not recognize this automatically when you run a different shell,
+you may need to run `sh' on it explicitly:
+
+ sh configure
+
+ If you run `configure' from a directory that contains source
+directories for multiple libraries or programs, such as the `gdb-5.2'
+source directory for version 5.2, `configure' creates configuration
+files for every directory level underneath (unless you tell it not to,
+with the `--norecursion' option).
+
+ You can run the `configure' script from any of the subordinate
+directories in the GDB distribution, if you only want to configure that
+subdirectory; but be sure to specify a path to it.
+
+ For example, with version 5.2, type the following to configure only
+the `bfd' subdirectory:
+
+ cd gdb-5.2/bfd
+ ../configure
+
+ You can install `gdb' anywhere; it has no hardwired paths. However,
+you should make sure that the shell on your path (named by the `SHELL'
+environment variable) is publicly readable. Remember that GDB uses the
+shell to start your program--some systems refuse to let GDB debug child
+processes whose programs are not readable.
+
+
+Compiling GDB in another directory
+==================================
+
+ If you want to run GDB versions for several host or target machines,
+you need a different `gdb' compiled for each combination of host and
+target. `configure' is designed to make this easy by allowing you to
+generate each configuration in a separate subdirectory, rather than in
+the source directory. If your `make' program handles the `VPATH'
+feature correctly (GNU `make' and SunOS 'make' are two that should),
+running `make' in each of these directories builds the `gdb' program
+specified there.
+
+ To build `gdb' in a separate directory, run `configure' with the
+`--srcdir' option to specify where to find the source. (You also need
+to specify a path to find `configure' itself from your working
+directory. If the path to `configure' would be the same as the
+argument to `--srcdir', you can leave out the `--srcdir' option; it
+will be assumed.)
+
+ For example, with version 5.2, you can build GDB in a separate
+directory for a Sun 4 like this:
+
+ cd gdb-5.2
+ mkdir ../gdb-sun4
+ cd ../gdb-sun4
+ ../gdb-5.2/configure
+ make
+
+ When `configure' builds a configuration using a remote source
+directory, it creates a tree for the binaries with the same structure
+(and using the same names) as the tree under the source directory. In
+the example, you'd find the Sun 4 library `libiberty.a' in the
+directory `gdb-sun4/libiberty', and GDB itself in `gdb-sun4/gdb'.
+
+ One popular reason to build several GDB configurations in separate
+directories is to configure GDB for cross-compiling (where GDB runs on
+one machine--the host--while debugging programs that run on another
+machine--the target). You specify a cross-debugging target by giving
+the `--target=TARGET' option to `configure'.
+
+ When you run `make' to build a program or library, you must run it
+in a configured directory--whatever directory you were in when you
+called `configure' (or one of its subdirectories).
+
+ The `Makefile' that `configure' generates in each source directory
+also runs recursively. If you type `make' in a source directory such
+as `gdb-5.2' (or in a separate configured directory configured with
+`--srcdir=PATH/gdb-5.2'), you will build all the required libraries,
+and then build GDB.
+
+ When you have multiple hosts or targets configured in separate
+directories, you can run `make' on them in parallel (for example, if
+they are NFS-mounted on each of the hosts); they will not interfere
+with each other.
+
+
+Specifying names for hosts and targets
+======================================
+
+ The specifications used for hosts and targets in the `configure'
+script are based on a three-part naming scheme, but some short
+predefined aliases are also supported. The full naming scheme encodes
+three pieces of information in the following pattern:
+
+ ARCHITECTURE-VENDOR-OS
+
+ For example, you can use the alias `sun4' as a HOST argument or in a
+`--target=TARGET' option. The equivalent full name is
+`sparc-sun-sunos4'.
+
+ The `configure' script accompanying GDB does not provide any query
+facility to list all supported host and target names or aliases.
+`configure' calls the Bourne shell script `config.sub' to map
+abbreviations to full names; you can read the script, if you wish, or
+you can use it to test your guesses on abbreviations--for example:
+
+ % sh config.sub sun4
+ sparc-sun-sunos4.1.1
+ % sh config.sub sun3
+ m68k-sun-sunos4.1.1
+ % sh config.sub decstation
+ mips-dec-ultrix4.2
+ % sh config.sub hp300bsd
+ m68k-hp-bsd
+ % sh config.sub i386v
+ i386-pc-sysv
+ % sh config.sub i786v
+ Invalid configuration `i786v': machine `i786v' not recognized
+
+`config.sub' is also distributed in the GDB source directory
+(`gdb-5.2', for version 5.2).
+
+
+`configure' options
+===================
+
+ Here is a summary of the `configure' options and arguments that are
+most often useful for building GDB. `configure' also has several other
+options not listed here. *note : (configure.info)What Configure Does,
+for a full explanation of `configure'.
+
+ configure [--help]
+ [--prefix=DIR]
+ [--srcdir=PATH]
+ [--norecursion] [--rm]
+ [--enable-build-warnings]
+ [--target=TARGET]
+ [--host=HOST]
+ [HOST]
+
+You may introduce options with a single `-' rather than `--' if you
+prefer; but you may abbreviate option names if you use `--'.
+
+`--help'
+ Display a quick summary of how to invoke `configure'.
+
+`-prefix=DIR'
+ Configure the source to install programs and files under directory
+ `DIR'.
+
+`--srcdir=PATH'
+ *Warning: using this option requires GNU `make', or another `make'
+ that compatibly implements the `VPATH' feature.*
+ Use this option to make configurations in directories separate
+ from the GDB source directories. Among other things, you can use
+ this to build (or maintain) several configurations simultaneously,
+ in separate directories. `configure' writes configuration
+ specific files in the current directory, but arranges for them to
+ use the source in the directory PATH. `configure' will create
+ directories under the working directory in parallel to the source
+ directories below PATH.
+
+`--norecursion'
+ Configure only the directory level where `configure' is executed;
+ do not propagate configuration to subdirectories.
+
+`--rm'
+ Remove the configuration that the other arguments specify.
+
+`--enable-build-warnings'
+ When building the GDB sources, ask the compiler to warn about any
+ code which looks even vaguely suspicious. You should only using
+ this feature if you're compiling with GNU CC. It passes the
+ following flags:
+ -Wimplicit
+ -Wreturn-type
+ -Wcomment
+ -Wtrigraphs
+ -Wformat
+ -Wparentheses
+ -Wpointer-arith
+
+`--target=TARGET'
+ Configure GDB for cross-debugging programs running on the specified
+ TARGET. Without this option, GDB is configured to debug programs
+ that run on the same machine (HOST) as GDB itself.
+
+ There is no convenient way to generate a list of all available
+ targets.
+
+`--host=HOST'
+ Configure GDB to run on the specified HOST.
+
+ There is no convenient way to generate a list of all available
+ hosts.
+
+`HOST ...'
+ Same as `--host=HOST'. If you omit this, GDB will guess; it's
+ quite accurate.
+
+`configure' accepts other options, for compatibility with configuring
+other GNU tools recursively; but these are the only options that affect
+GDB or its supporting libraries.
+
+
+Remote debugging
+=================
+
+ The files m68k-stub.c, i386-stub.c, and sparc-stub.c are examples
+of remote stubs to be used with remote.c. They are designed to run
+standalone on an m68k, i386, or SPARC cpu and communicate properly
+with the remote.c stub over a serial line.
+
+ The directory gdb/gdbserver/ contains `gdbserver', a program that
+allows remote debugging for Unix applications. gdbserver is only
+supported for some native configurations, including Sun 3, Sun 4, and
+Linux.
+
+ There are a number of remote interfaces for talking to existing ROM
+monitors and other hardware:
+
+ remote-adapt.c AMD 29000 "Adapt"
+ remote-array.c Array Tech RAID controller
+ remote-bug.c Motorola BUG monitor
+ remote-e7000.c Hitachi E7000 ICE
+ remote-eb.c AMD 29000 "EBMON"
+ remote-es.c Ericsson 1800 monitor
+ remote-est.c EST emulator
+ remote-hms.c Hitachi Micro Systems H8/300 monitor
+ remote-mips.c MIPS remote debugging protocol
+ remote-mm.c AMD 29000 "minimon"
+ remote-nindy.c Intel 960 "Nindy"
+ remote-nrom.c NetROM ROM emulator
+ remote-os9k.c PC running OS/9000
+ remote-rdi.c ARM with Angel monitor
+ remote-rdp.c ARM with Demon monitor
+ remote-sds.c PowerPC SDS monitor
+ remote-sim.c Generalized simulator protocol
+ remote-st.c Tandem ST-2000 monitor
+ remote-udi.c AMD 29000 using the AMD "Universal Debug Interface"
+ remote-vx.c VxWorks realtime kernel
+
+ Remote-vx.c and the vx-share subdirectory contain a remote
+interface for the VxWorks realtime kernel, which communicates over TCP
+using the Sun RPC library. This would be a useful starting point for
+other remote- via-ethernet back ends.
+
+ Remote-udi.c and the 29k-share subdirectory contain a remote
+interface for AMD 29000 programs, which uses the AMD "Universal Debug
+Interface". This allows GDB to talk to software simulators,
+emulators, and/or bare hardware boards, via network or serial
+interfaces. Note that GDB only provides an interface that speaks UDI,
+not a complete solution. You will need something on the other end
+that also speaks UDI.
+
+
+Reporting Bugs in GDB
+=====================
+
+ There are several ways of reporting bugs in GDB. The prefered
+method is to use the World Wide Web:
+
+ http://www.gnu.org/software/gdb/bugs/
+
+As an alternative, the bug report can be submitted, via e-mail, to the
+address "bug-gdb@gnu.org".
+
+ When submitting a bug, please include the GDB version number (e.g.,
+gdb-5.2), and how you configured it (e.g., "sun4" or "mach386 host,
+i586-intel-synopsys target"). Since GDB now supports so many
+different configurations, it is important that you be precise about
+this. If at all possible, you should include the actual banner that
+GDB prints when it starts up, or failing that, the actual configure
+command that you used when configuring GDB.
+
+ For more information on how/whether to report bugs, see the
+Reporting Bugs chapter of the GDB manual (gdb/doc/gdb.texinfo).
+
+
+Graphical interface to GDB -- X Windows, MS Windows
+==========================
+
+ Several graphical interfaces to GDB are available. You should
+check:
+
+ http://www.gnu.org/software/gdb/gui/
+
+for an up-to-date list.
+
+ Emacs users will very likely enjoy the Grand Unified Debugger mode;
+try typing `M-x gdb RET'.
+
+
+Writing Code for GDB
+=====================
+
+ There is a lot of information about writing code for GDB in the
+internals manual, distributed with GDB in gdb/doc/gdbint.texinfo. You
+can read it by hand, print it by using TeX and texinfo, or process it
+into an `info' file for use with Emacs' info mode or the standalone
+`info' program.
+
+ If you are pondering writing anything but a short patch, especially
+take note of the information about copyrights in the node Submitting
+Patches. It can take quite a while to get all the paperwork done, so
+we encourage you to start that process as soon as you decide you are
+planning to work on something, or at least well ahead of when you
+think you will be ready to submit the patches.
+
+
+GDB Testsuite
+=============
+
+ Included with the GDB distribution is a DejaGNU based testsuite
+that can either be used to test your newly built GDB, or for
+regression testing a GDB with local modifications.
+
+ Running the testsuite requires the prior installation of DejaGNU,
+which is generally available via ftp. The directory
+ftp://sources.redhat.com/pub/dejagnu/ will contain a recent snapshot.
+Once DejaGNU is installed, you can run the tests in one of the
+following ways:
+
+ (1) cd gdb-5.2
+ make check-gdb
+
+or
+
+ (2) cd gdb-5.2/gdb
+ make check
+
+or
+
+ (3) cd gdb-5.2/gdb/testsuite
+ make site.exp (builds the site specific file)
+ runtest -tool gdb GDB=../gdb (or GDB=<somepath> as appropriate)
+
+The last method gives you slightly more control in case of problems
+with building one or more test executables or if you are using the
+testsuite `standalone', without it being part of the GDB source tree.
+
+See the DejaGNU documentation for further details.
+
+
+(this is for editing this file with GNU emacs)
+Local Variables:
+mode: text
+End:
diff --git a/gdb/TODO b/gdb/TODO
new file mode 100644
index 00000000000..f743ae7999f
--- /dev/null
+++ b/gdb/TODO
@@ -0,0 +1,347 @@
+If you find inaccuracies in this list, please send mail to
+gdb-patches@sources.redhat.com. If you would like to work on any
+of these, you should consider sending mail to the same address, to
+find out whether anyone else is working on it.
+
+
+ GDB 5.1 - Fixes
+ ===============
+
+Below is a list of problems identified during the GDB 5.0 release
+cycle. People hope to have these problems fixed in 5.1.
+
+--
+
+Wow, three bug reports for the same problem in one day! We should
+probably make fixing this a real priority :-).
+
+Anyway, thanks for reporting.
+
+The following patch will fix the problems with setting breakpoints in
+dynamically loaded objects:
+
+ http://sources.redhat.com/ml/gdb-patches/2000-05/msg00230.html
+
+This patch isn't checked in yet (ping Michael/JimB), but I hope this
+will be in the next GDB release.
+
+There should really be a test in the testsuite for this problem, since
+it keeps coming up :-(. Any volunteers?
+
+Mark
+
+--
+
+ GDB 5.1 - New features
+ ======================
+
+The following new features should be included in 5.1.
+
+--
+
+ GDB 5.1 - Cleanups
+ ==================
+
+The following code cleanups will hopefully be applied to GDB 5.1.
+
+--
+
+ GDB 5.1 - Known Problems
+ ========================
+
+--
+
+z8k
+
+The z8k has suffered bit rot and is known to not build. The problem
+was occuring in the opcodes directory.
+
+--
+
+The BFD directory requires bug-fixed AUTOMAKE et.al.
+
+AUTOMAKE 1.4 incorrectly set the TEXINPUTS environment variable. It
+contained the full path to texinfo.tex when it should have only
+contained the directory. The bug has been fixed in the current
+AUTOMAKE sources. Automake snapshots can be found in:
+ ftp://sources.redhat.com/pub/gdb/infrastructure
+and ftp://sources.redhat.com/pub/binutils
+
+--
+
+Solaris 8 x86 CURSES_H problem
+http://sources.redhat.com/ml/gdb/2000-07/msg00038.html
+
+The original problem was worked around with:
+
+ 2000-06-06 Michael Snyder <msnyder@cygnus.com>
+
+ * configure.in: Enable autoconf to find curses.h on Solaris 2.8.
+ * configure: Regenerate.
+
+When building both GDB and SID using the same source tree the problem
+will still occure. sid/component/configure.in mis-configures
+<curses.h> and leaves wrong information in the config cache.
+
+--
+
+ GDB 5.2 - Fixes
+ ===============
+
+--
+
+ GDB 5.2 - New features
+ ======================
+
+--
+
+GCC 3.0 ABI support (but hopefully sooner...).
+
+--
+
+Objective C/C++ support (but hopefully sooner...).
+
+--
+
+Import of readline 4.2
+
+--
+
+ GDB 5.2 - Cleanups
+ ==================
+
+The following cleanups have been identified as part of GDB 5.2.
+
+--
+
+Remove old code that does not use ui_out functions and all the related
+"ifdef"s. This also allows the elimination of -DUI_OUT from
+Makefile.in and configure.in.
+
+--
+
+Compiler warnings.
+
+Eliminate warnings for all targets on at least one host for one of the
+-W flags. Flags up for debate include: -Wswitch -Wcomment -trigraphs
+-Wtrigraphs -Wunused-function -Wunused-label -Wunused-variable
+-Wunused-value -Wchar-subscripts -Wtraditional -Wshadow -Wcast-qual
+-Wcast-align -Wwrite-strings -Wconversion -Wstrict-prototypes
+-Wmissing-prototypes -Wmissing-declarations -Wredundant-decls
+-Woverloaded-virtual -Winline
+
+--
+
+Deprecate, if not delete, the following:
+
+ register[]
+ register_valid[]
+ REGISTER_BYTE()
+ Replaced by, on the target side
+ supply_register()
+ and on core-gdb side:
+ {read,write}_register_gen()
+ Remote.c will need to use something
+ other than REGISTER_BYTE() and
+ REGISTER_RAW_SIZE() when unpacking
+ [gG] packets.
+
+ STORE_PSEUDO_REGISTER
+ FETCH_PSEUDO_REGISTER
+ Now handed by the methods
+ gdbarch_{read,write}_register()
+ which sits between core GDB and
+ the register cache.
+
+ REGISTER_CONVERTIBLE
+ REGISTER_CONVERT_TO_RAW
+ REGISTER_CONVERT_TO_VIRTUAL
+ I think these three are redundant.
+ gdbarch_register_{read,write} can
+ do any conversion it likes.
+
+ REGISTER_VIRTUAL_SIZE
+ MAX_REGISTER_VIRTUAL_SIZE
+ REGISTER_VIRTUAL_TYPE
+ I think these can be replaced by
+ the pair:
+ FRAME_REGISTER_TYPE(frame, regnum)
+ REGISTER_TYPE(regnum)
+
+ DO_REGISTERS_INFO
+ Replace with
+ FRAME_REGISTER_INFO (frame, ...)
+
+ REGISTER_SIM_REGNO()
+ If nothing else rename this so that
+ how it relates to rawreg and the
+ regnum is clear.
+
+ REGISTER_BYTES
+ The size of the cache can be computed
+ on the fly.
+
+ IS_TRAPPED_INTERNALVAR
+ The pseudo registers should eventually make
+ this redundant.
+
+--
+
+Obsolete the targets:
+
+arm*-wince-pe
+mips*-*-pe
+sh*-*-pe
+
+--
+
+Obsolete the protocols:
+
+RDB?
+
+``As of version 5.3, WindRiver has removed the RDB server (RDB
+protocol support is built into gdb).'' -- Till.
+
+--
+
+Restructure gdb directory tree so that it avoids any 8.3 and 14
+filename problems.
+
+--
+
+Convert GDB build process to AUTOMAKE.
+
+See also sub-directory configure below.
+
+The current convention is (kind of) to use $(<header>_h) in all
+dependency lists. It isn't done in a consistent way.
+
+--
+
+ GDB 5.2 - Known Problems
+ ========================
+
+--
+
+ Code Cleanups: General
+ ======================
+
+The following are more general cleanups and fixes. They are not tied
+to any specific release.
+
+
+ New Features and Fixes
+ ======================
+
+These are harder than cleanups but easier than work involving
+fundamental architectural change.
+
+--
+
+ Language Support
+ ================
+
+New languages come onto the scene all the time.
+
+--
+
+Re: Various C++ things
+
+RTTI for g++ should be using the typeinfo functions rather than the
+vtables. The typeinfo functions are always at offset 4 from the
+beginning of the vtable, and are always right. The vtables will have
+weird names like E::VB sometimes. The typeinfo function will always
+be "E type_info function", or somesuch.
+
+value_virtual_fn_field needs to be fixed so there are no failures for
+virtual functions for C++ using g++.
+
+Testsuite cases are the major priority right now for C++ support,
+since i have to make a lot of changes that could potentially break
+each other.
+
+--
+
+
+ Symbol Support
+ ==============
+
+--
+
+Investiagate ways of reducing memory.
+
+--
+
+Investigate ways of improving load time.
+
+--
+
+ Testsuite Support
+ =================
+
+There are never to many testcases.
+
+--
+
+Better thread testsuite.
+
+--
+
+Better C++ testsuite.
+
+--
+
+ Architectural Changes: General
+ ==============================
+
+These are harder than simple cleanups / fixes and, consequently
+involve more work. Typically an Architectural Change will be broken
+down into a more digestible set of cleanups and fixes.
+
+--
+
+ Architectural Change: Multi-arch et al.
+ =======================================
+
+The long term objective is to remove all assumptions that there is a
+single target with a single address space with a single instruction
+set architecture and single application binary interface.
+
+This is an ongoing effort. The first milestone is to enable
+``multi-arch'' where by all architectural decisions are made at
+runtime.
+
+It should be noted that ``gdbarch'' is really ``gdbabi'' and
+``gdbisa''. Once things are multi-arched breaking that down correctly
+will become much easier.
+
+--
+
+ Architectural Change: MI, LIBGDB and scripting languages
+ ========================================================
+
+See also architectural changes related to the event loop. LIBGDB
+can't be finished until there is a generic event loop being used by
+all targets.
+
+The long term objective is it to be possible to integrate GDB into
+scripting languages.
+
+--
+
+ Architectural Change: Async
+ ===========================
+
+While GDB uses an event loop when prompting the user for input. That
+event loop is not exploited by targets when they allow the target
+program to continue. Typically targets still block in (target_wait())
+until the program again halts.
+
+The closest a target comes to supporting full asynchronous mode are
+the remote targets ``async'' and ``extended-async''.
+
+--
+
+# Local Variables:
+# mode: text
+# End:
diff --git a/gdb/a68v-nat.c b/gdb/a68v-nat.c
new file mode 100644
index 00000000000..4cc25cedb54
--- /dev/null
+++ b/gdb/a68v-nat.c
@@ -0,0 +1,122 @@
+/* Host-dependent code for Apollo-68ks for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1999, 2000, 2001
+ 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 "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#ifndef _ISP__M68K
+#define _ISP__M68K 1
+#endif
+
+#include <ptrace.h>
+
+extern int errno;
+
+void
+fetch_inferior_registers (int ignored)
+{
+ struct ptrace_$data_regs_m68k inferior_registers;
+ struct ptrace_$floating_regs_m68k inferior_fp_registers;
+ struct ptrace_$control_regs_m68k inferior_control_registers;
+
+ ptrace_$init_control (&inferior_control_registers);
+ inferior_fp_registers.size = sizeof (inferior_fp_registers);
+
+ registers_fetched ();
+
+ ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers,
+ ptrace_$data_set,
+ (PTRACE_ARG3_TYPE) & inferior_registers,
+ ptrace_$data_set);
+
+ ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers,
+ ptrace_$floating_set_m68k,
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers,
+ ptrace_$floating_set_m68k);
+
+ ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_control_registers,
+ ptrace_$control_set_m68k,
+ (PTRACE_ARG3_TYPE) & inferior_control_registers,
+ ptrace_$control_set_m68k);
+
+ bcopy (&inferior_registers, registers, 16 * 4);
+ bcopy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
+ sizeof inferior_fp_registers.regs);
+ *(int *) &registers[REGISTER_BYTE (PS_REGNUM)] = inferior_control_registers.sr;
+ *(int *) &registers[REGISTER_BYTE (PC_REGNUM)] = inferior_control_registers.pc;
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ struct ptrace_$data_regs_m68k inferior_registers;
+ struct ptrace_$floating_regs_m68k inferior_fp_registers;
+ struct ptrace_$control_regs_m68k inferior_control_registers;
+
+ ptrace_$init_control (&inferior_control_registers);
+ inferior_fp_registers.size = sizeof (inferior_fp_registers);
+
+ ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers,
+ ptrace_$floating_set_m68k,
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers,
+ ptrace_$floating_set_m68k);
+
+ ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_control_registers,
+ ptrace_$control_set_m68k,
+ (PTRACE_ARG3_TYPE) & inferior_control_registers,
+ ptrace_$control_set_m68k);
+
+ bcopy (registers, &inferior_registers, sizeof (inferior_registers));
+
+ bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)], inferior_fp_registers.regs,
+ sizeof inferior_fp_registers.regs);
+
+ inferior_control_registers.sr = *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
+ inferior_control_registers.pc = *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
+
+ ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers,
+ ptrace_$data_set_m68k,
+ (PTRACE_ARG3_TYPE) & inferior_registers,
+ ptrace_$data_set_m68k);
+
+ ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers,
+ ptrace_$floating_set_m68k,
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers,
+ ptrace_$floating_set_m68k);
+
+ ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_control_registers,
+ ptrace_$control_set_m68k,
+ (PTRACE_ARG3_TYPE) & inferior_control_registers,
+ ptrace_$control_set_m68k);
+}
diff --git a/gdb/abug-rom.c b/gdb/abug-rom.c
new file mode 100644
index 00000000000..b4c44a94b54
--- /dev/null
+++ b/gdb/abug-rom.c
@@ -0,0 +1,167 @@
+/* Remote debugging interface for ABug Rom monitor for GDB, the GNU debugger.
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+
+ Written by Rob Savoye of 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 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "regcache.h"
+
+/* Prototypes for local functions. */
+
+static void abug_open (char *args, int from_tty);
+
+static void
+abug_supply_register (char *regname, int regnamelen, char *val, int vallen)
+{
+ int regno;
+
+ if (regnamelen != 2)
+ return;
+
+ switch (regname[0])
+ {
+ case 'S':
+ if (regname[1] != 'R')
+ return;
+ regno = PS_REGNUM;
+ break;
+ case 'P':
+ if (regname[1] != 'C')
+ return;
+ regno = PC_REGNUM;
+ break;
+ case 'D':
+ if (regname[1] < '0' || regname[1] > '7')
+ return;
+ regno = regname[1] - '0' + D0_REGNUM;
+ break;
+ case 'A':
+ if (regname[1] < '0' || regname[1] > '7')
+ return;
+ regno = regname[1] - '0' + A0_REGNUM;
+ break;
+ default:
+ return;
+ }
+
+ monitor_supply_register (regno, val);
+}
+
+/*
+ * This array of registers needs to match the indexes used by GDB. The
+ * whole reason this exists is because the various ROM monitors use
+ * different names than GDB does, and don't support all the
+ * registers either. So, typing "info reg sp" becomes an "A7".
+ */
+
+static char *abug_regnames[NUM_REGS] =
+{
+ "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
+ "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
+ "PC",
+};
+
+/*
+ * Define the monitor command strings. Since these are passed directly
+ * through to a printf style function, we need can include formatting
+ * strings. We also need a CR or LF on the end.
+ */
+
+static struct target_ops abug_ops;
+
+static char *abug_inits[] =
+{"\r", NULL};
+
+static struct monitor_ops abug_cmds;
+
+static void
+init_abug_cmds (void)
+{
+ abug_cmds.flags = MO_CLR_BREAK_USES_ADDR;
+ abug_cmds.init = abug_inits; /* Init strings */
+ abug_cmds.cont = "g\r"; /* continue command */
+ abug_cmds.step = "t\r"; /* single step */
+ abug_cmds.stop = NULL; /* interrupt command */
+ abug_cmds.set_break = "br %x\r"; /* set a breakpoint */
+ abug_cmds.clr_break = "nobr %x\r"; /* clear a breakpoint */
+ abug_cmds.clr_all_break = "nobr\r"; /* clear all breakpoints */
+ abug_cmds.fill = "bf %x:%x %x;b\r"; /* fill (start count val) */
+ abug_cmds.setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */
+ abug_cmds.setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */
+ abug_cmds.setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */
+ abug_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ abug_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
+ abug_cmds.setmem.term = NULL; /* setreg.term */
+ abug_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
+ abug_cmds.getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */
+ abug_cmds.getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */
+ abug_cmds.getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */
+ abug_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ abug_cmds.getmem.resp_delim = " "; /* getmem.resp_delim */
+ abug_cmds.getmem.term = NULL; /* getmem.term */
+ abug_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
+ abug_cmds.setreg.cmd = "rm %s %x\r"; /* setreg.cmd (name, value) */
+ abug_cmds.setreg.resp_delim = "="; /* setreg.resp_delim */
+ abug_cmds.setreg.term = "? "; /* setreg.term */
+ abug_cmds.setreg.term_cmd = ".\r"; /* setreg.term_cmd */
+ abug_cmds.getreg.cmd = "rm %s\r"; /* getreg.cmd (name) */
+ abug_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */
+ abug_cmds.getreg.term = "? "; /* getreg.term */
+ abug_cmds.getreg.term_cmd = ".\r"; /* getreg.term_cmd */
+ abug_cmds.dump_registers = "rd\r"; /* dump_registers */
+ abug_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
+ abug_cmds.supply_register = abug_supply_register; /* supply_register */
+ abug_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ abug_cmds.load = "lo 0\r"; /* download command */
+ abug_cmds.loadresp = "\n"; /* load response */
+ abug_cmds.prompt = "135Bug>"; /* monitor command prompt */
+ abug_cmds.line_term = "\r"; /* end-of-line terminator */
+ abug_cmds.cmd_end = NULL; /* optional command terminator */
+ abug_cmds.target = &abug_ops; /* target operations */
+ abug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ abug_cmds.regnames = abug_regnames; /* registers names */
+ abug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+};
+
+static void
+abug_open (char *args, int from_tty)
+{
+ monitor_open (args, &abug_cmds, from_tty);
+}
+
+void
+_initialize_abug_rom (void)
+{
+ init_abug_cmds ();
+ init_monitor_ops (&abug_ops);
+
+ abug_ops.to_shortname = "abug";
+ abug_ops.to_longname = "ABug monitor";
+ abug_ops.to_doc = "Debug via the ABug monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ abug_ops.to_open = abug_open;
+
+ add_target (&abug_ops);
+}
diff --git a/gdb/acconfig.h b/gdb/acconfig.h
new file mode 100644
index 00000000000..619b0ae97b4
--- /dev/null
+++ b/gdb/acconfig.h
@@ -0,0 +1,178 @@
+/* Define if compiling on Solaris 7. */
+#undef _MSE_INT_H
+
+/* Define if your struct reg has r_fs. */
+#undef HAVE_STRUCT_REG_R_FS
+
+/* Define if your struct reg has r_gs. */
+#undef HAVE_STRUCT_REG_R_GS
+
+/* Define if pstatus_t type is available */
+#undef HAVE_PSTATUS_T
+
+/* Define if prrun_t type is available */
+#undef HAVE_PRRUN_T
+
+/* Define if fpregset_t type is available. */
+#undef HAVE_FPREGSET_T
+
+/* Define if gregset_t type is available. */
+#undef HAVE_GREGSET_T
+
+/* Define if <sys/procfs.h> has prgregset_t. */
+#undef HAVE_PRGREGSET_T
+
+/* Define if <sys/procfs.h> has prfpregset_t. */
+#undef HAVE_PRFPREGSET_T
+
+/* Define if <sys/procfs.h> has lwpid_t. */
+#undef HAVE_LWPID_T
+
+/* Define if <sys/procfs.h> has psaddr_t. */
+#undef HAVE_PSADDR_T
+
+/* Define if <sys/procfs.h> has prgregset32_t. */
+#undef HAVE_PRGREGSET32_T
+
+/* Define if <sys/procfs.h> has prfpregset32_t. */
+#undef HAVE_PRFPREGSET32_T
+
+/* Define if <sys/procfs.h> has prsysent_t */
+#undef HAVE_PRSYSENT_T
+
+/* Define if <sys/procfs.h> has pr_sigset_t */
+#undef HAVE_PR_SIGSET_T
+
+/* Define if <sys/procfs.h> has pr_sigaction64_t */
+#undef HAVE_PR_SIGACTION64_T
+
+/* Define if <sys/procfs.h> has pr_siginfo64_t */
+#undef HAVE_PR_SIGINFO64_T
+
+/* Define if <link.h> exists and defines struct link_map which has
+ members with an ``l_'' prefix. (For Solaris, SVR4, and
+ SVR4-like systems.) */
+#undef HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS
+
+/* Define if <link.h> exists and defines struct link_map which has
+ members with an ``lm_'' prefix. (For SunOS.) */
+#undef HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS
+
+/* Define if <link.h> exists and defines a struct so_map which has
+ members with an ``som_'' prefix. (Found on older *BSD systems.) */
+#undef HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS
+
+/* Define if <sys/link.h> has struct link_map32 */
+#undef HAVE_STRUCT_LINK_MAP32
+
+/* Define if <sys/link.h> has link_map32 (solaris sparc-64 target) */
+#undef _SYSCALL32
+
+/* Define if the prfpregset_t type is broken. */
+#undef PRFPREGSET_T_BROKEN
+
+/* Define if you want to use new multi-fd /proc interface
+ (replaces HAVE_MULTIPLE_PROC_FDS as well as other macros). */
+#undef NEW_PROC_API
+
+/* Define if ioctl argument PIOCSET is available. */
+#undef HAVE_PROCFS_PIOCSET
+
+/* Define if the `long long' type works. */
+#undef CC_HAS_LONG_LONG
+
+/* Define if the "ll" format works to print long long ints. */
+#undef PRINTF_HAS_LONG_LONG
+
+/* Define if the "%Lg" format works to print long doubles. */
+#undef PRINTF_HAS_LONG_DOUBLE
+
+/* Define if the "%Lg" format works to scan long doubles. */
+#undef SCANF_HAS_LONG_DOUBLE
+
+/* Define if using Solaris thread debugging. */
+#undef HAVE_THREAD_DB_LIB
+
+/* Define on a GNU/Linux system to work around problems in sys/procfs.h. */
+#undef START_INFERIOR_TRAPS_EXPECTED
+#undef sys_quotactl
+
+/* Define if you have HPUX threads */
+#undef HAVE_HPUX_THREAD_SUPPORT
+
+/* Define if you want to use the memory mapped malloc package (mmalloc). */
+#undef USE_MMALLOC
+
+/* Define if the runtime uses a routine from mmalloc before gdb has a chance
+ to initialize mmalloc, and we want to force checking to be used anyway.
+ This may cause spurious memory corruption messages if the runtime tries
+ to explicitly deallocate that memory when gdb calls exit. */
+#undef MMCHECK_FORCE
+
+/* Define to 1 if NLS is requested. */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have catgets and don't want to use GNU gettext. */
+#undef HAVE_CATGETS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Define as 1 if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define if you want to use the full-screen terminal user interface. */
+#undef TUI
+
+/* Define if <proc_service.h> on solaris uses int instead of
+ size_t, and assorted other type changes. */
+#undef PROC_SERVICE_IS_OLD
+
+/* If you want to specify a default CPU variant, define this to be its
+ name, as a C string. */
+#undef TARGET_CPU_DEFAULT
+
+/* Define if the simulator is being linked in. */
+#undef WITH_SIM
+
+/* Set to true if the save_state_t structure is present */
+#undef HAVE_STRUCT_SAVE_STATE_T
+
+/* Set to true if the save_state_t structure has the ss_wide member */
+#undef HAVE_STRUCT_MEMBER_SS_WIDE
+
+/* Define if <sys/ptrace.h> defines the PTRACE_GETREGS request. */
+#undef HAVE_PTRACE_GETREGS
+
+/* Define if <sys/ptrace.h> defines the PTRACE_GETFPXREGS request. */
+#undef HAVE_PTRACE_GETFPXREGS
+
+/* Define if <sys/ptrace.h> defines the PT_GETDBREGS request. */
+#undef HAVE_PT_GETDBREGS
+
+/* Define if <sys/ptrace.h> defines the PT_GETXMMREGS request. */
+#undef HAVE_PT_GETXMMREGS
+
+/* Define if gnu-regex.c included with GDB should be used. */
+#undef USE_INCLUDED_REGEX
+
+/* BFD's default architecture. */
+#undef DEFAULT_BFD_ARCH
+
+/* BFD's default target vector. */
+#undef DEFAULT_BFD_VEC
+
+/* Multi-arch enabled. */
+#undef GDB_MULTI_ARCH
+
+/* hostfile */
+#undef GDB_XM_FILE
+
+/* targetfile */
+#undef GDB_TM_FILE
+
+/* nativefile */
+#undef GDB_NM_FILE
diff --git a/gdb/acinclude.m4 b/gdb/acinclude.m4
new file mode 100644
index 00000000000..12f4c483a6b
--- /dev/null
+++ b/gdb/acinclude.m4
@@ -0,0 +1,978 @@
+dnl written by Rob Savoye <rob@cygnus.com> for Cygnus Support
+dnl major rewriting for Tcl 7.5 by Don Libes <libes@nist.gov>
+
+dnl gdb/configure.in uses BFD_NEED_DECLARATION, so get its definition.
+sinclude(../bfd/acinclude.m4)
+
+dnl This gets the standard macros, like the TCL, TK, etc ones.
+sinclude(../config/acinclude.m4)
+
+dnl CYGNUS LOCAL: This gets the right posix flag for gcc
+AC_DEFUN(CY_AC_TCL_LYNX_POSIX,
+[AC_REQUIRE([AC_PROG_CC])AC_REQUIRE([AC_PROG_CPP])
+AC_MSG_CHECKING([if running LynxOS])
+AC_CACHE_VAL(ac_cv_os_lynx,
+[AC_EGREP_CPP(yes,
+[/*
+ * The old Lynx "cc" only defines "Lynx", but the newer one uses "__Lynx__"
+ */
+#if defined(__Lynx__) || defined(Lynx)
+yes
+#endif
+], ac_cv_os_lynx=yes, ac_cv_os_lynx=no)])
+#
+if test "$ac_cv_os_lynx" = "yes" ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(LYNX)
+ AC_MSG_CHECKING([whether -mposix or -X is available])
+ AC_CACHE_VAL(ac_cv_c_posix_flag,
+ [AC_TRY_COMPILE(,[
+ /*
+ * This flag varies depending on how old the compiler is.
+ * -X is for the old "cc" and "gcc" (based on 1.42).
+ * -mposix is for the new gcc (at least 2.5.8).
+ */
+ #if defined(__GNUC__) && __GNUC__ >= 2
+ choke me
+ #endif
+ ], ac_cv_c_posix_flag=" -mposix", ac_cv_c_posix_flag=" -X")])
+ CC="$CC $ac_cv_c_posix_flag"
+ AC_MSG_RESULT($ac_cv_c_posix_flag)
+ else
+ AC_MSG_RESULT(no)
+fi
+])
+
+#
+# Sometimes the native compiler is a bogus stub for gcc or /usr/ucb/cc. This
+# makes configure think it's cross compiling. If --target wasn't used, then
+# we can't configure, so something is wrong. We don't use the cache
+# here cause if somebody fixes their compiler install, we want this to work.
+AC_DEFUN(CY_AC_C_WORKS,
+[# If we cannot compile and link a trivial program, we can't expect anything to work
+AC_MSG_CHECKING(whether the compiler ($CC) actually works)
+AC_TRY_COMPILE(, [/* don't need anything here */],
+ c_compiles=yes, c_compiles=no)
+
+AC_TRY_LINK(, [/* don't need anything here */],
+ c_links=yes, c_links=no)
+
+if test x"${c_compiles}" = x"no" ; then
+ AC_MSG_ERROR(the native compiler is broken and won't compile.)
+fi
+
+if test x"${c_links}" = x"no" ; then
+ AC_MSG_ERROR(the native compiler is broken and won't link.)
+fi
+AC_MSG_RESULT(yes)
+])
+
+AC_DEFUN(CY_AC_PATH_TCLH, [
+#
+# Ok, lets find the tcl source trees so we can use the headers
+# Warning: transition of version 9 to 10 will break this algorithm
+# because 10 sorts before 9. We also look for just tcl. We have to
+# be careful that we don't match stuff like tclX by accident.
+# the alternative search directory is involked by --with-tclinclude
+#
+
+no_tcl=true
+AC_MSG_CHECKING(for Tcl private headers. dir=${configdir})
+AC_ARG_WITH(tclinclude, [ --with-tclinclude=DIR Directory where tcl private headers are], with_tclinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_tclh,[
+# first check to see if --with-tclinclude was specified
+if test x"${with_tclinclude}" != x ; then
+ if test -f ${with_tclinclude}/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}; pwd)`
+ elif test -f ${with_tclinclude}/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}/generic; pwd)`
+ else
+ AC_MSG_ERROR([${with_tclinclude} directory doesn't contain private headers])
+ fi
+fi
+
+# next check if it came with Tcl configuration file
+if test x"${ac_cv_c_tclconfig}" = x ; then
+ if test -f $ac_cv_c_tclconfig/../generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $ac_cv_c_tclconfig/..; pwd)`
+ fi
+fi
+
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[[7-9]]* 2>/dev/null` \
+ ${srcdir}/../../tcl \
+ `ls -dr ${srcdir}/../../tcl[[7-9]]* 2>/dev/null` \
+ ${srcdir}/../../../tcl \
+ `ls -dr ${srcdir}/../../../tcl[[7-9]]* 2>/dev/null ` ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tcl[[7-9]]* 2>/dev/null` \
+ `ls -dr /usr/local/lib/tcl[[7-9]]* 2>/dev/null` \
+ /usr/local/src/tcl \
+ /usr/local/lib/tcl \
+ ${prefix}/include ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# see if one is installed
+if test x"${ac_cv_c_tclh}" = x ; then
+ AC_HEADER_CHECK(tclInt.h, ac_cv_c_tclh=installed, ac_cv_c_tclh="")
+fi
+])
+if test x"${ac_cv_c_tclh}" = x ; then
+ TCLHDIR="# no Tcl private headers found"
+ AC_MSG_ERROR([Can't find Tcl private headers])
+fi
+if test x"${ac_cv_c_tclh}" != x ; then
+ no_tcl=""
+ if test x"${ac_cv_c_tclh}" = x"installed" ; then
+ AC_MSG_RESULT([is installed])
+ TCLHDIR=""
+ else
+ AC_MSG_RESULT([found in ${ac_cv_c_tclh}])
+ # this hack is cause the TCLHDIR won't print if there is a "-I" in it.
+ TCLHDIR="-I${ac_cv_c_tclh}"
+ fi
+fi
+
+AC_SUBST(TCLHDIR)
+])
+
+
+AC_DEFUN(CY_AC_PATH_TCLCONFIG, [
+#
+# Ok, lets find the tcl configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tclconfig
+#
+
+if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+ AC_ARG_WITH(tclconfig, [ --with-tclconfig=DIR Directory containing tcl configuration (tclConfig.sh)],
+ with_tclconfig=${withval})
+ AC_MSG_CHECKING([for Tcl configuration])
+ AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+ # First check to see if --with-tclconfig was specified.
+ if test x"${with_tclconfig}" != x ; then
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tcl installation
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[[7-9]]* 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[[7-9]]* 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[[7-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[[7-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCLCONFIG="# no Tcl configs found"
+ AC_MSG_WARN(Can't find Tcl configuration definitions)
+ else
+ no_tcl=
+ TCLCONFIG=${ac_cv_c_tclconfig}/tclConfig.sh
+ AC_MSG_RESULT(found $TCLCONFIG)
+ fi
+fi
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TCLCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_TCLCONFIG, [
+ . $TCLCONFIG
+
+ AC_SUBST(TCL_VERSION)
+ AC_SUBST(TCL_MAJOR_VERSION)
+ AC_SUBST(TCL_MINOR_VERSION)
+ AC_SUBST(TCL_CC)
+ AC_SUBST(TCL_DEFS)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_LIB_FILE)
+
+dnl don't export, not used outside of configure
+dnl AC_SUBST(TCL_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_EXEC_PREFIX)
+
+ AC_SUBST(TCL_SHLIB_CFLAGS)
+ AC_SUBST(TCL_SHLIB_LD)
+dnl don't export, not used outside of configure
+ AC_SUBST(TCL_SHLIB_LD_LIBS)
+ AC_SUBST(TCL_SHLIB_SUFFIX)
+dnl not used, don't export to save symbols
+ AC_SUBST(TCL_DL_LIBS)
+ AC_SUBST(TCL_LD_FLAGS)
+dnl don't export, not used outside of configure
+ AC_SUBST(TCL_LD_SEARCH_FLAGS)
+ AC_SUBST(TCL_COMPAT_OBJS)
+ AC_SUBST(TCL_RANLIB)
+ AC_SUBST(TCL_BUILD_LIB_SPEC)
+ AC_SUBST(TCL_LIB_SPEC)
+ AC_SUBST(TCL_LIB_VERSIONS_OK)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_SHARED_LIB_SUFFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_UNSHARED_LIB_SUFFIX)
+])
+
+# Warning: Tk definitions are very similar to Tcl definitions but
+# are not precisely the same. There are a couple of differences,
+# so don't do changes to Tcl thinking you can cut and paste it do
+# the Tk differences and later simply substitute "Tk" for "Tcl".
+# Known differences:
+# - Acceptable Tcl major version #s is 7-9 while Tk is 4-9
+# - Searching for Tcl includes looking for tclInt.h, Tk looks for tk.h
+# - Computing major/minor versions is different because Tk depends on
+# headers to Tcl, Tk, and X.
+# - Symbols in tkConfig.sh are different than tclConfig.sh
+# - Acceptable for Tk to be missing but not Tcl.
+
+AC_DEFUN(CY_AC_PATH_TKH, [
+#
+# Ok, lets find the tk source trees so we can use the headers
+# If the directory (presumably symlink) named "tk" exists, use that one
+# in preference to any others. Same logic is used when choosing library
+# and again with Tcl. The search order is the best place to look first, then in
+# decreasing significance. The loop breaks if the trigger file is found.
+# Note the gross little conversion here of srcdir by cd'ing to the found
+# directory. This converts the path from a relative to an absolute, so
+# recursive cache variables for the path will work right. We check all
+# the possible paths in one loop rather than many seperate loops to speed
+# things up.
+# the alternative search directory is involked by --with-tkinclude
+#
+no_tk=true
+AC_MSG_CHECKING(for Tk private headers)
+AC_ARG_WITH(tkinclude, [ --with-tkinclude=DIR Directory where tk private headers are], with_tkinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_tkh,[
+# first check to see if --with-tkinclude was specified
+if test x"${with_tkinclude}" != x ; then
+ if test -f ${with_tkinclude}/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}; pwd)`
+ elif test -f ${with_tkinclude}/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}/generic; pwd)`
+ else
+ AC_MSG_ERROR([${with_tkinclude} directory doesn't contain private headers])
+ fi
+fi
+
+# next check if it came with Tk configuration file
+if test x"${ac_cv_c_tkconfig}" = x ; then
+ if test -f $ac_cv_c_tkconfig/../generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $ac_cv_c_tkconfig/..; pwd)`
+ fi
+fi
+
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tkh}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[[4-9]]* 2>/dev/null` \
+ ${srcdir}/../../tk \
+ `ls -dr ${srcdir}/../../tk[[4-9]]* 2>/dev/null` \
+ ${srcdir}/../../../tk \
+ `ls -dr ${srcdir}/../../../tk[[4-9]]* 2>/dev/null ` ; do
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tkh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tk[[4-9]]* 2>/dev/null` \
+ `ls -dr /usr/local/lib/tk[[4-9]]* 2>/dev/null` \
+ /usr/local/src/tk \
+ /usr/local/lib/tk \
+ ${prefix}/include ; do
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# see if one is installed
+if test x"${ac_cv_c_tkh}" = x ; then
+ AC_HEADER_CHECK(tk.h, ac_cv_c_tkh=installed, ac_cv_c_tkh="")
+fi
+])
+if test x"${ac_cv_c_tkh}" != x ; then
+ no_tk=""
+ if test x"${ac_cv_c_tkh}" = x"installed" ; then
+ AC_MSG_RESULT([is installed])
+ TKHDIR=""
+ else
+ AC_MSG_RESULT([found in ${ac_cv_c_tkh}])
+ # this hack is cause the TKHDIR won't print if there is a "-I" in it.
+ TKHDIR="-I${ac_cv_c_tkh}"
+ fi
+else
+ TKHDIR="# no Tk directory found"
+ AC_MSG_WARN([Can't find Tk private headers])
+ no_tk=true
+fi
+
+AC_SUBST(TKHDIR)
+])
+
+
+AC_DEFUN(CY_AC_PATH_TKCONFIG, [
+#
+# Ok, lets find the tk configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tkconfig
+#
+
+if test x"${no_tk}" = x ; then
+ # we reset no_tk in case something fails here
+ no_tk=true
+ AC_ARG_WITH(tkconfig, [ --with-tkconfig=DIR Directory containing tk configuration (tkConfig.sh)],
+ with_tkconfig=${withval})
+ AC_MSG_CHECKING([for Tk configuration])
+ AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+ # First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tk library
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ../tk \
+ `ls -dr ../tk[[4-9]]* 2>/dev/null` \
+ ../../tk \
+ `ls -dr ../../tk[[4-9]]* 2>/dev/null` \
+ ../../../tk \
+ `ls -dr ../../../tk[[4-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[[4-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TKCONFIG="# no Tk configs found"
+ AC_MSG_WARN(Can't find Tk configuration definitions)
+ else
+ no_tk=
+ TKCONFIG=${ac_cv_c_tkconfig}/tkConfig.sh
+ AC_MSG_RESULT(found $TKCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TKCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_TKCONFIG, [
+ if test -f "$TKCONFIG" ; then
+ . $TKCONFIG
+ fi
+
+ AC_SUBST(TK_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(TK_MAJOR_VERSION)
+dnl AC_SUBST(TK_MINOR_VERSION)
+ AC_SUBST(TK_DEFS)
+
+dnl not used, don't export to save symbols
+ dnl AC_SUBST(TK_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(TK_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TK_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TK_EXEC_PREFIX)
+
+ AC_SUBST(TK_BUILD_INCLUDES)
+ AC_SUBST(TK_XINCLUDES)
+ AC_SUBST(TK_XLIBSW)
+ AC_SUBST(TK_BUILD_LIB_SPEC)
+ AC_SUBST(TK_LIB_SPEC)
+])
+
+# check for Itcl headers.
+
+AC_DEFUN(CY_AC_PATH_ITCLCONFIG, [
+#
+# Ok, lets find the itcl configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itclconfig
+#
+
+if test x"${no_itcl}" = x ; then
+ # we reset no_itcl in case something fails here
+ no_itcl=true
+ AC_ARG_WITH(itclconfig, [ --with-itclconfig Directory containing itcl configuration (itclConfig.sh)],
+ with_itclconfig=${withval})
+ AC_MSG_CHECKING([for Itcl configuration])
+ AC_CACHE_VAL(ac_cv_c_itclconfig,[
+
+ # First check to see if --with-itclconfig was specified.
+ if test x"${with_itclconfig}" != x ; then
+ if test -f "${with_itclconfig}/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd ${with_itclconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_itclconfig} directory doesn't contain itclConfig.sh])
+ fi
+ fi
+
+ # then check for a private Itcl library
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in \
+ ../itcl/itcl \
+ `ls -dr ../itcl[[4-9]]*/itcl 2>/dev/null` \
+ ../../itcl \
+ `ls -dr ../../itcl[[4-9]]*/itcl 2>/dev/null` \
+ ../../../itcl \
+ `ls -dr ../../../itcl[[4-9]]*/itcl 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../itcl/itcl \
+ `ls -dr ${srcdir}/../itcl[[4-9]]*/itcl 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ ITCLCONFIG="# no Itcl configs found"
+ AC_MSG_WARN(Can't find Itcl configuration definitions)
+ else
+ no_itcl=
+ ITCLCONFIG=${ac_cv_c_itclconfig}/itclConfig.sh
+ AC_MSG_RESULT(found $ITCLCONFIG)
+ fi
+fi
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_ITCLCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_ITCLCONFIG, [
+ if test -f "$ITCLCONFIG" ; then
+ . $ITCLCONFIG
+ fi
+
+ AC_SUBST(ITCL_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(ITCL_MAJOR_VERSION)
+dnl AC_SUBST(ITCL_MINOR_VERSION)
+ AC_SUBST(ITCL_DEFS)
+
+dnl not used, don't export to save symbols
+ dnl AC_SUBST(ITCL_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(ITCL_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITCL_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITCL_EXEC_PREFIX)
+
+ AC_SUBST(ITCL_BUILD_INCLUDES)
+ AC_SUBST(ITCL_BUILD_LIB_SPEC)
+ AC_SUBST(ITCL_LIB_SPEC)
+])
+
+# check for Itcl headers.
+
+AC_DEFUN(CY_AC_PATH_ITCLH, [
+AC_MSG_CHECKING(for Itcl private headers. srcdir=${srcdir})
+if test x"${ac_cv_c_itclh}" = x ; then
+ for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ${srcdir}/../itcl/itcl; do
+ if test -f $i/generic/itcl.h ; then
+ ac_cv_c_itclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_itclh}" = x ; then
+ ITCLHDIR="# no Itcl private headers found"
+ AC_MSG_ERROR([Can't find Itcl private headers])
+fi
+if test x"${ac_cv_c_itclh}" != x ; then
+ ITCLHDIR="-I${ac_cv_c_itclh}"
+fi
+# should always be here
+# ITCLLIB="../itcl/itcl/unix/libitcl.a"
+AC_SUBST(ITCLHDIR)
+#AC_SUBST(ITCLLIB)
+])
+
+
+AC_DEFUN(CY_AC_PATH_ITKCONFIG, [
+#
+# Ok, lets find the itk configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itkconfig
+#
+
+if test x"${no_itk}" = x ; then
+ # we reset no_itk in case something fails here
+ no_itk=true
+ AC_ARG_WITH(itkconfig, [ --with-itkconfig Directory containing itk configuration (itkConfig.sh)],
+ with_itkconfig=${withval})
+ AC_MSG_CHECKING([for Itk configuration])
+ AC_CACHE_VAL(ac_cv_c_itkconfig,[
+
+ # First check to see if --with-itkconfig was specified.
+ if test x"${with_itkconfig}" != x ; then
+ if test -f "${with_itkconfig}/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd ${with_itkconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_itkconfig} directory doesn't contain itkConfig.sh])
+ fi
+ fi
+
+ # then check for a private Itk library
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in \
+ ../itcl/itk \
+ `ls -dr ../itcl[[4-9]]*/itk 2>/dev/null` \
+ ../../itk \
+ `ls -dr ../../itcl[[4-9]]*/itk 2>/dev/null` \
+ ../../../itk \
+ `ls -dr ../../../itcl[[4-9]]*/itk 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../itcl/itk \
+ `ls -dr ${srcdir}/../itcl[[4-9]]*/itk 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ ITKCONFIG="# no Itk configs found"
+ AC_MSG_WARN(Can't find Itk configuration definitions)
+ else
+ no_itk=
+ ITKCONFIG=${ac_cv_c_itkconfig}/itkConfig.sh
+ AC_MSG_RESULT(found $ITKCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_ITKCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_ITKCONFIG, [
+ if test -f "$ITKCONFIG" ; then
+ . $ITKCONFIG
+ fi
+
+ AC_SUBST(ITK_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(ITK_MAJOR_VERSION)
+dnl AC_SUBST(ITK_MINOR_VERSION)
+ AC_SUBST(ITK_DEFS)
+
+dnl not used, don't export to save symbols
+ dnl AC_SUBST(ITK_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(ITK_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITK_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITK_EXEC_PREFIX)
+
+ AC_SUBST(ITK_BUILD_INCLUDES)
+ AC_SUBST(ITK_BUILD_LIB_SPEC)
+ AC_SUBST(ITK_LIB_SPEC)
+])
+
+AC_DEFUN(CY_AC_PATH_ITKH, [
+AC_MSG_CHECKING(for Itk private headers. srcdir=${srcdir})
+if test x"${ac_cv_c_itkh}" = x ; then
+ for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ${srcdir}/../itcl/itk; do
+ if test -f $i/generic/itk.h ; then
+ ac_cv_c_itkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_itkh}" = x ; then
+ ITKHDIR="# no Itk private headers found"
+ AC_MSG_ERROR([Can't find Itk private headers])
+fi
+if test x"${ac_cv_c_itkh}" != x ; then
+ ITKHDIR="-I${ac_cv_c_itkh}"
+fi
+# should always be here
+# ITKLIB="../itcl/itk/unix/libitk.a"
+AC_SUBST(ITKHDIR)
+#AC_SUBST(ITKLIB)
+])
+
+# check for Tix headers.
+
+AC_DEFUN(CY_AC_PATH_TIXH, [
+AC_MSG_CHECKING(for Tix private headers. srcdir=${srcdir})
+if test x"${ac_cv_c_tixh}" = x ; then
+ for i in ${srcdir}/../tix ${srcdir}/../../tix ${srcdir}/../../../tix ; do
+ if test -f $i/generic/tix.h ; then
+ ac_cv_c_tixh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_tixh}" = x ; then
+ TIXHDIR="# no Tix private headers found"
+ AC_MSG_ERROR([Can't find Tix private headers])
+fi
+if test x"${ac_cv_c_tixh}" != x ; then
+ TIXHDIR="-I${ac_cv_c_tixh}"
+fi
+AC_SUBST(TIXHDIR)
+])
+
+AC_DEFUN(CY_AC_PATH_TIXCONFIG, [
+#
+# Ok, lets find the tix configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itkconfig
+#
+
+if test x"${no_tix}" = x ; then
+ # we reset no_tix in case something fails here
+ no_tix=true
+ AC_ARG_WITH(tixconfig, [ --with-tixconfig Directory containing tix configuration (tixConfig.sh)],
+ with_tixconfig=${withval})
+ AC_MSG_CHECKING([for Tix configuration])
+ AC_CACHE_VAL(ac_cv_c_tixconfig,[
+
+ # First check to see if --with-tixconfig was specified.
+ if test x"${with_tixconfig}" != x ; then
+ if test -f "${with_tixconfig}/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd ${with_tixconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tixconfig} directory doesn't contain tixConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tix library
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in \
+ ../tix \
+ `ls -dr ../tix 2>/dev/null` \
+ ../../tix \
+ `ls -dr ../../tix 2>/dev/null` \
+ ../../../tix \
+ `ls -dr ../../../tix 2>/dev/null` ; do
+ echo "**** Looking at $i - with ${configdir}"
+ if test -f "$i/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ echo "**** Looking at $i"
+ if test -f "$i/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ echo "**** Other private locations"
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tix \
+ `ls -dr ${srcdir}/../tix 2>/dev/null` ; do
+ echo "**** Looking at $i - with ${configdir}"
+ if test -f "$i/${configdir}/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ TIXCONFIG="# no Tix configs found"
+ AC_MSG_WARN(Can't find Tix configuration definitions)
+ else
+ no_tix=
+ TIXCONFIG=${ac_cv_c_tixconfig}/tixConfig.sh
+ AC_MSG_RESULT(found $TIXCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TIXCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_TIXCONFIG, [
+ if test -f "$TIXCONFIG" ; then
+ . $TIXCONFIG
+ fi
+
+ AC_SUBST(TIX_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(TIX_MAJOR_VERSION)
+dnl AC_SUBST(TIX_MINOR_VERSION)
+dnl AC_SUBST(TIX_DEFS)
+
+dnl not used, don't export to save symbols
+dnl dnl AC_SUBST(TIX_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(TIX_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TIX_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TIX_EXEC_PREFIX)
+
+dnl AC_SUBST(TIX_BUILD_INCLUDES)
+ AC_SUBST(TIX_BUILD_LIB_SPEC)
+dnl AC_SUBST(TIX_LIB_SPEC)
+])
+
+dnl sinclude(../gettext.m4) already included by bfd/acinclude.m4
+dnl The lines below arrange for aclocal not to bring gettext.m4's
+dnl CY_GNU_GETTEXT into aclocal.m4.
+ifelse(yes,no,[
+AC_DEFUN([CY_GNU_GETTEXT],)
+])
+
+## ----------------------------------------- ##
+## ANSIfy the C compiler whenever possible. ##
+## From Franc,ois Pinard ##
+## ----------------------------------------- ##
+
+# Copyright 1996, 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+# 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, 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.
+
+# serial 1
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so. This macro tries various
+# options that select ANSI C on some system or another. It considers the
+# compiler to be in ANSI C mode if it handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+AC_DEFUN([AM_PROG_CC_STDC],
+[AC_REQUIRE([AC_PROG_CC])
+AC_BEFORE([$0], [AC_C_INLINE])
+AC_BEFORE([$0], [AC_C_CONST])
+dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require
+dnl a magic option to avoid problems with ANSI preprocessor commands
+dnl like #elif.
+dnl FIXME: can't do this because then AC_AIX won't work due to a
+dnl circular dependency.
+dnl AC_BEFORE([$0], [AC_PROG_CPP])
+AC_MSG_CHECKING([for ${CC-cc} option to accept ANSI C])
+AC_CACHE_VAL(am_cv_prog_cc_stdc,
+[am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ AC_TRY_COMPILE(
+[#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+], [
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+],
+[am_cv_prog_cc_stdc="$ac_arg"; break])
+done
+CC="$ac_save_CC"
+])
+if test -z "$am_cv_prog_cc_stdc"; then
+ AC_MSG_RESULT([none needed])
+else
+ AC_MSG_RESULT([$am_cv_prog_cc_stdc])
+fi
+case "x$am_cv_prog_cc_stdc" in
+ x|xno) ;;
+ *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+])
diff --git a/gdb/aclocal.m4 b/gdb/aclocal.m4
new file mode 100644
index 00000000000..5b9d643f04d
--- /dev/null
+++ b/gdb/aclocal.m4
@@ -0,0 +1,1020 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+dnl written by Rob Savoye <rob@cygnus.com> for Cygnus Support
+dnl major rewriting for Tcl 7.5 by Don Libes <libes@nist.gov>
+
+dnl gdb/configure.in uses BFD_NEED_DECLARATION, so get its definition.
+sinclude(../bfd/acinclude.m4)
+
+dnl This gets the standard macros, like the TCL, TK, etc ones.
+sinclude(../config/acinclude.m4)
+
+dnl CYGNUS LOCAL: This gets the right posix flag for gcc
+AC_DEFUN(CY_AC_TCL_LYNX_POSIX,
+[AC_REQUIRE([AC_PROG_CC])AC_REQUIRE([AC_PROG_CPP])
+AC_MSG_CHECKING([if running LynxOS])
+AC_CACHE_VAL(ac_cv_os_lynx,
+[AC_EGREP_CPP(yes,
+[/*
+ * The old Lynx "cc" only defines "Lynx", but the newer one uses "__Lynx__"
+ */
+#if defined(__Lynx__) || defined(Lynx)
+yes
+#endif
+], ac_cv_os_lynx=yes, ac_cv_os_lynx=no)])
+#
+if test "$ac_cv_os_lynx" = "yes" ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(LYNX)
+ AC_MSG_CHECKING([whether -mposix or -X is available])
+ AC_CACHE_VAL(ac_cv_c_posix_flag,
+ [AC_TRY_COMPILE(,[
+ /*
+ * This flag varies depending on how old the compiler is.
+ * -X is for the old "cc" and "gcc" (based on 1.42).
+ * -mposix is for the new gcc (at least 2.5.8).
+ */
+ #if defined(__GNUC__) && __GNUC__ >= 2
+ choke me
+ #endif
+ ], ac_cv_c_posix_flag=" -mposix", ac_cv_c_posix_flag=" -X")])
+ CC="$CC $ac_cv_c_posix_flag"
+ AC_MSG_RESULT($ac_cv_c_posix_flag)
+ else
+ AC_MSG_RESULT(no)
+fi
+])
+
+#
+# Sometimes the native compiler is a bogus stub for gcc or /usr/ucb/cc. This
+# makes configure think it's cross compiling. If --target wasn't used, then
+# we can't configure, so something is wrong. We don't use the cache
+# here cause if somebody fixes their compiler install, we want this to work.
+AC_DEFUN(CY_AC_C_WORKS,
+[# If we cannot compile and link a trivial program, we can't expect anything to work
+AC_MSG_CHECKING(whether the compiler ($CC) actually works)
+AC_TRY_COMPILE(, [/* don't need anything here */],
+ c_compiles=yes, c_compiles=no)
+
+AC_TRY_LINK(, [/* don't need anything here */],
+ c_links=yes, c_links=no)
+
+if test x"${c_compiles}" = x"no" ; then
+ AC_MSG_ERROR(the native compiler is broken and won't compile.)
+fi
+
+if test x"${c_links}" = x"no" ; then
+ AC_MSG_ERROR(the native compiler is broken and won't link.)
+fi
+AC_MSG_RESULT(yes)
+])
+
+AC_DEFUN(CY_AC_PATH_TCLH, [
+#
+# Ok, lets find the tcl source trees so we can use the headers
+# Warning: transition of version 9 to 10 will break this algorithm
+# because 10 sorts before 9. We also look for just tcl. We have to
+# be careful that we don't match stuff like tclX by accident.
+# the alternative search directory is involked by --with-tclinclude
+#
+
+no_tcl=true
+AC_MSG_CHECKING(for Tcl private headers. dir=${configdir})
+AC_ARG_WITH(tclinclude, [ --with-tclinclude=DIR Directory where tcl private headers are], with_tclinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_tclh,[
+# first check to see if --with-tclinclude was specified
+if test x"${with_tclinclude}" != x ; then
+ if test -f ${with_tclinclude}/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}; pwd)`
+ elif test -f ${with_tclinclude}/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}/generic; pwd)`
+ else
+ AC_MSG_ERROR([${with_tclinclude} directory doesn't contain private headers])
+ fi
+fi
+
+# next check if it came with Tcl configuration file
+if test x"${ac_cv_c_tclconfig}" = x ; then
+ if test -f $ac_cv_c_tclconfig/../generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $ac_cv_c_tclconfig/..; pwd)`
+ fi
+fi
+
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[[7-9]]* 2>/dev/null` \
+ ${srcdir}/../../tcl \
+ `ls -dr ${srcdir}/../../tcl[[7-9]]* 2>/dev/null` \
+ ${srcdir}/../../../tcl \
+ `ls -dr ${srcdir}/../../../tcl[[7-9]]* 2>/dev/null ` ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tcl[[7-9]]* 2>/dev/null` \
+ `ls -dr /usr/local/lib/tcl[[7-9]]* 2>/dev/null` \
+ /usr/local/src/tcl \
+ /usr/local/lib/tcl \
+ ${prefix}/include ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# see if one is installed
+if test x"${ac_cv_c_tclh}" = x ; then
+ AC_HEADER_CHECK(tclInt.h, ac_cv_c_tclh=installed, ac_cv_c_tclh="")
+fi
+])
+if test x"${ac_cv_c_tclh}" = x ; then
+ TCLHDIR="# no Tcl private headers found"
+ AC_MSG_ERROR([Can't find Tcl private headers])
+fi
+if test x"${ac_cv_c_tclh}" != x ; then
+ no_tcl=""
+ if test x"${ac_cv_c_tclh}" = x"installed" ; then
+ AC_MSG_RESULT([is installed])
+ TCLHDIR=""
+ else
+ AC_MSG_RESULT([found in ${ac_cv_c_tclh}])
+ # this hack is cause the TCLHDIR won't print if there is a "-I" in it.
+ TCLHDIR="-I${ac_cv_c_tclh}"
+ fi
+fi
+
+AC_SUBST(TCLHDIR)
+])
+
+
+AC_DEFUN(CY_AC_PATH_TCLCONFIG, [
+#
+# Ok, lets find the tcl configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tclconfig
+#
+
+if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+ AC_ARG_WITH(tclconfig, [ --with-tclconfig=DIR Directory containing tcl configuration (tclConfig.sh)],
+ with_tclconfig=${withval})
+ AC_MSG_CHECKING([for Tcl configuration])
+ AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+ # First check to see if --with-tclconfig was specified.
+ if test x"${with_tclconfig}" != x ; then
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tcl installation
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[[7-9]]* 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[[7-9]]* 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[[7-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[[7-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCLCONFIG="# no Tcl configs found"
+ AC_MSG_WARN(Can't find Tcl configuration definitions)
+ else
+ no_tcl=
+ TCLCONFIG=${ac_cv_c_tclconfig}/tclConfig.sh
+ AC_MSG_RESULT(found $TCLCONFIG)
+ fi
+fi
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TCLCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_TCLCONFIG, [
+ . $TCLCONFIG
+
+ AC_SUBST(TCL_VERSION)
+ AC_SUBST(TCL_MAJOR_VERSION)
+ AC_SUBST(TCL_MINOR_VERSION)
+ AC_SUBST(TCL_CC)
+ AC_SUBST(TCL_DEFS)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_LIB_FILE)
+
+dnl don't export, not used outside of configure
+dnl AC_SUBST(TCL_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_EXEC_PREFIX)
+
+ AC_SUBST(TCL_SHLIB_CFLAGS)
+ AC_SUBST(TCL_SHLIB_LD)
+dnl don't export, not used outside of configure
+ AC_SUBST(TCL_SHLIB_LD_LIBS)
+ AC_SUBST(TCL_SHLIB_SUFFIX)
+dnl not used, don't export to save symbols
+ AC_SUBST(TCL_DL_LIBS)
+ AC_SUBST(TCL_LD_FLAGS)
+dnl don't export, not used outside of configure
+ AC_SUBST(TCL_LD_SEARCH_FLAGS)
+ AC_SUBST(TCL_COMPAT_OBJS)
+ AC_SUBST(TCL_RANLIB)
+ AC_SUBST(TCL_BUILD_LIB_SPEC)
+ AC_SUBST(TCL_LIB_SPEC)
+ AC_SUBST(TCL_LIB_VERSIONS_OK)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_SHARED_LIB_SUFFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_UNSHARED_LIB_SUFFIX)
+])
+
+# Warning: Tk definitions are very similar to Tcl definitions but
+# are not precisely the same. There are a couple of differences,
+# so don't do changes to Tcl thinking you can cut and paste it do
+# the Tk differences and later simply substitute "Tk" for "Tcl".
+# Known differences:
+# - Acceptable Tcl major version #s is 7-9 while Tk is 4-9
+# - Searching for Tcl includes looking for tclInt.h, Tk looks for tk.h
+# - Computing major/minor versions is different because Tk depends on
+# headers to Tcl, Tk, and X.
+# - Symbols in tkConfig.sh are different than tclConfig.sh
+# - Acceptable for Tk to be missing but not Tcl.
+
+AC_DEFUN(CY_AC_PATH_TKH, [
+#
+# Ok, lets find the tk source trees so we can use the headers
+# If the directory (presumably symlink) named "tk" exists, use that one
+# in preference to any others. Same logic is used when choosing library
+# and again with Tcl. The search order is the best place to look first, then in
+# decreasing significance. The loop breaks if the trigger file is found.
+# Note the gross little conversion here of srcdir by cd'ing to the found
+# directory. This converts the path from a relative to an absolute, so
+# recursive cache variables for the path will work right. We check all
+# the possible paths in one loop rather than many seperate loops to speed
+# things up.
+# the alternative search directory is involked by --with-tkinclude
+#
+no_tk=true
+AC_MSG_CHECKING(for Tk private headers)
+AC_ARG_WITH(tkinclude, [ --with-tkinclude=DIR Directory where tk private headers are], with_tkinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_tkh,[
+# first check to see if --with-tkinclude was specified
+if test x"${with_tkinclude}" != x ; then
+ if test -f ${with_tkinclude}/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}; pwd)`
+ elif test -f ${with_tkinclude}/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}/generic; pwd)`
+ else
+ AC_MSG_ERROR([${with_tkinclude} directory doesn't contain private headers])
+ fi
+fi
+
+# next check if it came with Tk configuration file
+if test x"${ac_cv_c_tkconfig}" = x ; then
+ if test -f $ac_cv_c_tkconfig/../generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $ac_cv_c_tkconfig/..; pwd)`
+ fi
+fi
+
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tkh}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[[4-9]]* 2>/dev/null` \
+ ${srcdir}/../../tk \
+ `ls -dr ${srcdir}/../../tk[[4-9]]* 2>/dev/null` \
+ ${srcdir}/../../../tk \
+ `ls -dr ${srcdir}/../../../tk[[4-9]]* 2>/dev/null ` ; do
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tkh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tk[[4-9]]* 2>/dev/null` \
+ `ls -dr /usr/local/lib/tk[[4-9]]* 2>/dev/null` \
+ /usr/local/src/tk \
+ /usr/local/lib/tk \
+ ${prefix}/include ; do
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# see if one is installed
+if test x"${ac_cv_c_tkh}" = x ; then
+ AC_HEADER_CHECK(tk.h, ac_cv_c_tkh=installed, ac_cv_c_tkh="")
+fi
+])
+if test x"${ac_cv_c_tkh}" != x ; then
+ no_tk=""
+ if test x"${ac_cv_c_tkh}" = x"installed" ; then
+ AC_MSG_RESULT([is installed])
+ TKHDIR=""
+ else
+ AC_MSG_RESULT([found in ${ac_cv_c_tkh}])
+ # this hack is cause the TKHDIR won't print if there is a "-I" in it.
+ TKHDIR="-I${ac_cv_c_tkh}"
+ fi
+else
+ TKHDIR="# no Tk directory found"
+ AC_MSG_WARN([Can't find Tk private headers])
+ no_tk=true
+fi
+
+AC_SUBST(TKHDIR)
+])
+
+
+AC_DEFUN(CY_AC_PATH_TKCONFIG, [
+#
+# Ok, lets find the tk configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tkconfig
+#
+
+if test x"${no_tk}" = x ; then
+ # we reset no_tk in case something fails here
+ no_tk=true
+ AC_ARG_WITH(tkconfig, [ --with-tkconfig=DIR Directory containing tk configuration (tkConfig.sh)],
+ with_tkconfig=${withval})
+ AC_MSG_CHECKING([for Tk configuration])
+ AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+ # First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tk library
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ../tk \
+ `ls -dr ../tk[[4-9]]* 2>/dev/null` \
+ ../../tk \
+ `ls -dr ../../tk[[4-9]]* 2>/dev/null` \
+ ../../../tk \
+ `ls -dr ../../../tk[[4-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[[4-9]]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TKCONFIG="# no Tk configs found"
+ AC_MSG_WARN(Can't find Tk configuration definitions)
+ else
+ no_tk=
+ TKCONFIG=${ac_cv_c_tkconfig}/tkConfig.sh
+ AC_MSG_RESULT(found $TKCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TKCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_TKCONFIG, [
+ if test -f "$TKCONFIG" ; then
+ . $TKCONFIG
+ fi
+
+ AC_SUBST(TK_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(TK_MAJOR_VERSION)
+dnl AC_SUBST(TK_MINOR_VERSION)
+ AC_SUBST(TK_DEFS)
+
+dnl not used, don't export to save symbols
+ dnl AC_SUBST(TK_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(TK_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TK_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TK_EXEC_PREFIX)
+
+ AC_SUBST(TK_BUILD_INCLUDES)
+ AC_SUBST(TK_XINCLUDES)
+ AC_SUBST(TK_XLIBSW)
+ AC_SUBST(TK_BUILD_LIB_SPEC)
+ AC_SUBST(TK_LIB_SPEC)
+])
+
+# check for Itcl headers.
+
+AC_DEFUN(CY_AC_PATH_ITCLCONFIG, [
+#
+# Ok, lets find the itcl configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itclconfig
+#
+
+if test x"${no_itcl}" = x ; then
+ # we reset no_itcl in case something fails here
+ no_itcl=true
+ AC_ARG_WITH(itclconfig, [ --with-itclconfig Directory containing itcl configuration (itclConfig.sh)],
+ with_itclconfig=${withval})
+ AC_MSG_CHECKING([for Itcl configuration])
+ AC_CACHE_VAL(ac_cv_c_itclconfig,[
+
+ # First check to see if --with-itclconfig was specified.
+ if test x"${with_itclconfig}" != x ; then
+ if test -f "${with_itclconfig}/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd ${with_itclconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_itclconfig} directory doesn't contain itclConfig.sh])
+ fi
+ fi
+
+ # then check for a private Itcl library
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in \
+ ../itcl/itcl \
+ `ls -dr ../itcl[[4-9]]*/itcl 2>/dev/null` \
+ ../../itcl \
+ `ls -dr ../../itcl[[4-9]]*/itcl 2>/dev/null` \
+ ../../../itcl \
+ `ls -dr ../../../itcl[[4-9]]*/itcl 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../itcl/itcl \
+ `ls -dr ${srcdir}/../itcl[[4-9]]*/itcl 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ ITCLCONFIG="# no Itcl configs found"
+ AC_MSG_WARN(Can't find Itcl configuration definitions)
+ else
+ no_itcl=
+ ITCLCONFIG=${ac_cv_c_itclconfig}/itclConfig.sh
+ AC_MSG_RESULT(found $ITCLCONFIG)
+ fi
+fi
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_ITCLCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_ITCLCONFIG, [
+ if test -f "$ITCLCONFIG" ; then
+ . $ITCLCONFIG
+ fi
+
+ AC_SUBST(ITCL_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(ITCL_MAJOR_VERSION)
+dnl AC_SUBST(ITCL_MINOR_VERSION)
+ AC_SUBST(ITCL_DEFS)
+
+dnl not used, don't export to save symbols
+ dnl AC_SUBST(ITCL_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(ITCL_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITCL_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITCL_EXEC_PREFIX)
+
+ AC_SUBST(ITCL_BUILD_INCLUDES)
+ AC_SUBST(ITCL_BUILD_LIB_SPEC)
+ AC_SUBST(ITCL_LIB_SPEC)
+])
+
+# check for Itcl headers.
+
+AC_DEFUN(CY_AC_PATH_ITCLH, [
+AC_MSG_CHECKING(for Itcl private headers. srcdir=${srcdir})
+if test x"${ac_cv_c_itclh}" = x ; then
+ for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ${srcdir}/../itcl/itcl; do
+ if test -f $i/generic/itcl.h ; then
+ ac_cv_c_itclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_itclh}" = x ; then
+ ITCLHDIR="# no Itcl private headers found"
+ AC_MSG_ERROR([Can't find Itcl private headers])
+fi
+if test x"${ac_cv_c_itclh}" != x ; then
+ ITCLHDIR="-I${ac_cv_c_itclh}"
+fi
+# should always be here
+# ITCLLIB="../itcl/itcl/unix/libitcl.a"
+AC_SUBST(ITCLHDIR)
+#AC_SUBST(ITCLLIB)
+])
+
+
+AC_DEFUN(CY_AC_PATH_ITKCONFIG, [
+#
+# Ok, lets find the itk configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itkconfig
+#
+
+if test x"${no_itk}" = x ; then
+ # we reset no_itk in case something fails here
+ no_itk=true
+ AC_ARG_WITH(itkconfig, [ --with-itkconfig Directory containing itk configuration (itkConfig.sh)],
+ with_itkconfig=${withval})
+ AC_MSG_CHECKING([for Itk configuration])
+ AC_CACHE_VAL(ac_cv_c_itkconfig,[
+
+ # First check to see if --with-itkconfig was specified.
+ if test x"${with_itkconfig}" != x ; then
+ if test -f "${with_itkconfig}/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd ${with_itkconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_itkconfig} directory doesn't contain itkConfig.sh])
+ fi
+ fi
+
+ # then check for a private Itk library
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in \
+ ../itcl/itk \
+ `ls -dr ../itcl[[4-9]]*/itk 2>/dev/null` \
+ ../../itk \
+ `ls -dr ../../itcl[[4-9]]*/itk 2>/dev/null` \
+ ../../../itk \
+ `ls -dr ../../../itcl[[4-9]]*/itk 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../itcl/itk \
+ `ls -dr ${srcdir}/../itcl[[4-9]]*/itk 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ ITKCONFIG="# no Itk configs found"
+ AC_MSG_WARN(Can't find Itk configuration definitions)
+ else
+ no_itk=
+ ITKCONFIG=${ac_cv_c_itkconfig}/itkConfig.sh
+ AC_MSG_RESULT(found $ITKCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_ITKCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_ITKCONFIG, [
+ if test -f "$ITKCONFIG" ; then
+ . $ITKCONFIG
+ fi
+
+ AC_SUBST(ITK_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(ITK_MAJOR_VERSION)
+dnl AC_SUBST(ITK_MINOR_VERSION)
+ AC_SUBST(ITK_DEFS)
+
+dnl not used, don't export to save symbols
+ dnl AC_SUBST(ITK_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(ITK_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITK_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(ITK_EXEC_PREFIX)
+
+ AC_SUBST(ITK_BUILD_INCLUDES)
+ AC_SUBST(ITK_BUILD_LIB_SPEC)
+ AC_SUBST(ITK_LIB_SPEC)
+])
+
+AC_DEFUN(CY_AC_PATH_ITKH, [
+AC_MSG_CHECKING(for Itk private headers. srcdir=${srcdir})
+if test x"${ac_cv_c_itkh}" = x ; then
+ for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ${srcdir}/../itcl/itk; do
+ if test -f $i/generic/itk.h ; then
+ ac_cv_c_itkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_itkh}" = x ; then
+ ITKHDIR="# no Itk private headers found"
+ AC_MSG_ERROR([Can't find Itk private headers])
+fi
+if test x"${ac_cv_c_itkh}" != x ; then
+ ITKHDIR="-I${ac_cv_c_itkh}"
+fi
+# should always be here
+# ITKLIB="../itcl/itk/unix/libitk.a"
+AC_SUBST(ITKHDIR)
+#AC_SUBST(ITKLIB)
+])
+
+# check for Tix headers.
+
+AC_DEFUN(CY_AC_PATH_TIXH, [
+AC_MSG_CHECKING(for Tix private headers. srcdir=${srcdir})
+if test x"${ac_cv_c_tixh}" = x ; then
+ for i in ${srcdir}/../tix ${srcdir}/../../tix ${srcdir}/../../../tix ; do
+ if test -f $i/generic/tix.h ; then
+ ac_cv_c_tixh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_tixh}" = x ; then
+ TIXHDIR="# no Tix private headers found"
+ AC_MSG_ERROR([Can't find Tix private headers])
+fi
+if test x"${ac_cv_c_tixh}" != x ; then
+ TIXHDIR="-I${ac_cv_c_tixh}"
+fi
+AC_SUBST(TIXHDIR)
+])
+
+AC_DEFUN(CY_AC_PATH_TIXCONFIG, [
+#
+# Ok, lets find the tix configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itkconfig
+#
+
+if test x"${no_tix}" = x ; then
+ # we reset no_tix in case something fails here
+ no_tix=true
+ AC_ARG_WITH(tixconfig, [ --with-tixconfig Directory containing tix configuration (tixConfig.sh)],
+ with_tixconfig=${withval})
+ AC_MSG_CHECKING([for Tix configuration])
+ AC_CACHE_VAL(ac_cv_c_tixconfig,[
+
+ # First check to see if --with-tixconfig was specified.
+ if test x"${with_tixconfig}" != x ; then
+ if test -f "${with_tixconfig}/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd ${with_tixconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tixconfig} directory doesn't contain tixConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tix library
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in \
+ ../tix \
+ `ls -dr ../tix 2>/dev/null` \
+ ../../tix \
+ `ls -dr ../../tix 2>/dev/null` \
+ ../../../tix \
+ `ls -dr ../../../tix 2>/dev/null` ; do
+ echo "**** Looking at $i - with ${configdir}"
+ if test -f "$i/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ echo "**** Looking at $i"
+ if test -f "$i/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ echo "**** Other private locations"
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tix \
+ `ls -dr ${srcdir}/../tix 2>/dev/null` ; do
+ echo "**** Looking at $i - with ${configdir}"
+ if test -f "$i/${configdir}/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ TIXCONFIG="# no Tix configs found"
+ AC_MSG_WARN(Can't find Tix configuration definitions)
+ else
+ no_tix=
+ TIXCONFIG=${ac_cv_c_tixconfig}/tixConfig.sh
+ AC_MSG_RESULT(found $TIXCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TIXCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_TIXCONFIG, [
+ if test -f "$TIXCONFIG" ; then
+ . $TIXCONFIG
+ fi
+
+ AC_SUBST(TIX_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(TIX_MAJOR_VERSION)
+dnl AC_SUBST(TIX_MINOR_VERSION)
+dnl AC_SUBST(TIX_DEFS)
+
+dnl not used, don't export to save symbols
+dnl dnl AC_SUBST(TIX_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(TIX_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TIX_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TIX_EXEC_PREFIX)
+
+dnl AC_SUBST(TIX_BUILD_INCLUDES)
+ AC_SUBST(TIX_BUILD_LIB_SPEC)
+dnl AC_SUBST(TIX_LIB_SPEC)
+])
+
+dnl sinclude(../gettext.m4) already included by bfd/acinclude.m4
+dnl The lines below arrange for aclocal not to bring gettext.m4's
+dnl CY_GNU_GETTEXT into aclocal.m4.
+ifelse(yes,no,[
+AC_DEFUN([CY_GNU_GETTEXT],)
+])
+
+
+# Copyright 1996, 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+# 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, 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.
+
+# serial 1
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so. This macro tries various
+# options that select ANSI C on some system or another. It considers the
+# compiler to be in ANSI C mode if it handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+AC_DEFUN([AM_PROG_CC_STDC],
+[AC_REQUIRE([AC_PROG_CC])
+AC_BEFORE([$0], [AC_C_INLINE])
+AC_BEFORE([$0], [AC_C_CONST])
+dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require
+dnl a magic option to avoid problems with ANSI preprocessor commands
+dnl like #elif.
+dnl FIXME: can't do this because then AC_AIX won't work due to a
+dnl circular dependency.
+dnl AC_BEFORE([$0], [AC_PROG_CPP])
+AC_MSG_CHECKING([for ${CC-cc} option to accept ANSI C])
+AC_CACHE_VAL(am_cv_prog_cc_stdc,
+[am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ AC_TRY_COMPILE(
+[#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+], [
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+],
+[am_cv_prog_cc_stdc="$ac_arg"; break])
+done
+CC="$ac_save_CC"
+])
+if test -z "$am_cv_prog_cc_stdc"; then
+ AC_MSG_RESULT([none needed])
+else
+ AC_MSG_RESULT([$am_cv_prog_cc_stdc])
+fi
+case "x$am_cv_prog_cc_stdc" in
+ x|xno) ;;
+ *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT($USE_MAINTAINER_MODE)
+ AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi])
+
diff --git a/gdb/ada-exp.tab.c b/gdb/ada-exp.tab.c
new file mode 100644
index 00000000000..bb6d29bf276
--- /dev/null
+++ b/gdb/ada-exp.tab.c
@@ -0,0 +1,2389 @@
+/* A Bison parser, made from ./ada-exp.y
+ by GNU bison 1.35. */
+
+#define YYBISON 1 /* Identify Bison output. */
+
+# define INT 257
+# define NULL_PTR 258
+# define CHARLIT 259
+# define FLOAT 260
+# define TYPENAME 261
+# define BLOCKNAME 262
+# define STRING 263
+# define NAME 264
+# define DOT_ID 265
+# define OBJECT_RENAMING 266
+# define DOT_ALL 267
+# define LAST 268
+# define REGNAME 269
+# define INTERNAL_VARIABLE 270
+# define ASSIGN 271
+# define _AND_ 272
+# define OR 273
+# define XOR 274
+# define THEN 275
+# define ELSE 276
+# define NOTEQUAL 277
+# define LEQ 278
+# define GEQ 279
+# define IN 280
+# define DOTDOT 281
+# define UNARY 282
+# define MOD 283
+# define REM 284
+# define STARSTAR 285
+# define ABS 286
+# define NOT 287
+# define TICK_ACCESS 288
+# define TICK_ADDRESS 289
+# define TICK_FIRST 290
+# define TICK_LAST 291
+# define TICK_LENGTH 292
+# define TICK_MAX 293
+# define TICK_MIN 294
+# define TICK_MODULUS 295
+# define TICK_POS 296
+# define TICK_RANGE 297
+# define TICK_SIZE 298
+# define TICK_TAG 299
+# define TICK_VAL 300
+# define ARROW 301
+# define NEW 302
+
+#line 38 "./ada-exp.y"
+
+
+#include "defs.h"
+#include <string.h>
+#include <ctype.h>
+#include "expression.h"
+#include "value.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "ada-lang.h"
+#include "bfd.h" /* Required by objfiles.h. */
+#include "symfile.h" /* Required by objfiles.h. */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+#include "frame.h"
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
+ as well as gratuitiously global symbol names, so we can have multiple
+ yacc generated parsers in gdb. These are only the variables
+ produced by yacc. If other parser generators (bison, byacc, etc) produce
+ additional global names that conflict at link time, then those parser
+ generators need to be fixed instead of adding those names to this list. */
+
+/* NOTE: This is clumsy, especially since BISON and FLEX provide --prefix
+ options. I presume we are maintaining it to accommodate systems
+ without BISON? (PNH) */
+
+#define yymaxdepth ada_maxdepth
+#define yyparse _ada_parse /* ada_parse calls this after initialization */
+#define yylex ada_lex
+#define yyerror ada_error
+#define yylval ada_lval
+#define yychar ada_char
+#define yydebug ada_debug
+#define yypact ada_pact
+#define yyr1 ada_r1
+#define yyr2 ada_r2
+#define yydef ada_def
+#define yychk ada_chk
+#define yypgo ada_pgo
+#define yyact ada_act
+#define yyexca ada_exca
+#define yyerrflag ada_errflag
+#define yynerrs ada_nerrs
+#define yyps ada_ps
+#define yypv ada_pv
+#define yys ada_s
+#define yy_yys ada_yys
+#define yystate ada_state
+#define yytmp ada_tmp
+#define yyv ada_v
+#define yy_yyv ada_yyv
+#define yyval ada_val
+#define yylloc ada_lloc
+#define yyreds ada_reds /* With YYDEBUG defined */
+#define yytoks ada_toks /* With YYDEBUG defined */
+
+#ifndef YYDEBUG
+#define YYDEBUG 0 /* Default to no yydebug support */
+#endif
+
+struct name_info {
+ struct symbol* sym;
+ struct minimal_symbol* msym;
+ struct block* block;
+ struct stoken stoken;
+};
+
+/* If expression is in the context of TYPE'(...), then TYPE, else
+ * NULL. */
+static struct type* type_qualifier;
+
+int yyparse (void);
+
+static int yylex (void);
+
+void yyerror (char *);
+
+static struct stoken string_to_operator (struct stoken);
+
+static void write_attribute_call0 (enum ada_attribute);
+
+static void write_attribute_call1 (enum ada_attribute, LONGEST);
+
+static void write_attribute_calln (enum ada_attribute, int);
+
+static void write_object_renaming (struct block*, struct symbol*);
+
+static void write_var_from_name (struct block*, struct name_info);
+
+static LONGEST
+convert_char_literal (struct type*, LONGEST);
+
+#line 131 "./ada-exp.y"
+#ifndef YYSTYPE
+typedef union
+ {
+ LONGEST lval;
+ struct {
+ LONGEST val;
+ struct type *type;
+ } typed_val;
+ struct {
+ DOUBLEST dval;
+ struct type *type;
+ } typed_val_float;
+ struct type *tval;
+ struct stoken sval;
+ struct name_info ssym;
+ int voidval;
+ struct block *bval;
+ struct internalvar *ivar;
+
+ } yystype;
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+
+
+#define YYFINAL 184
+#define YYFLAG -32768
+#define YYNTBASE 68
+
+/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */
+#define YYTRANSLATE(x) ((unsigned)(x) <= 302 ? yytranslate[x] : 82)
+
+/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */
+static const char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 34, 63,
+ 57, 62, 36, 32, 64, 33, 56, 37, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 61,
+ 25, 23, 26, 2, 31, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 58, 2, 67, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 65, 2, 66, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 24, 27, 28,
+ 29, 30, 35, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 59, 60
+};
+
+#if YYDEBUG
+static const short yyprhs[] =
+{
+ 0, 0, 2, 4, 6, 10, 13, 16, 21, 26,
+ 27, 35, 36, 43, 47, 49, 51, 53, 55, 57,
+ 61, 64, 67, 70, 73, 74, 76, 80, 84, 90,
+ 95, 99, 103, 107, 111, 115, 119, 123, 127, 131,
+ 135, 139, 143, 149, 155, 159, 166, 173, 178, 182,
+ 186, 190, 194, 199, 203, 208, 212, 215, 218, 222,
+ 226, 230, 233, 236, 244, 252, 258, 262, 266, 270,
+ 276, 279, 280, 284, 286, 288, 289, 291, 293, 295,
+ 297, 299, 302, 304, 307, 309, 312, 314, 316, 318,
+ 320, 323, 325, 328, 331, 335, 338, 341
+};
+static const short yyrhs[] =
+{
+ 69, 0, 81, 0, 73, 0, 69, 61, 73, 0,
+ 70, 13, 0, 70, 11, 0, 70, 57, 74, 62,
+ 0, 81, 57, 73, 62, 0, 0, 81, 63, 72,
+ 71, 57, 73, 62, 0, 0, 70, 57, 73, 30,
+ 73, 62, 0, 57, 69, 62, 0, 78, 0, 15,
+ 0, 16, 0, 70, 0, 14, 0, 73, 17, 73,
+ 0, 33, 73, 0, 32, 73, 0, 42, 73, 0,
+ 41, 73, 0, 0, 73, 0, 79, 59, 73, 0,
+ 74, 64, 73, 0, 74, 64, 79, 59, 73, 0,
+ 65, 81, 66, 73, 0, 73, 40, 73, 0, 73,
+ 36, 73, 0, 73, 37, 73, 0, 73, 39, 73,
+ 0, 73, 38, 73, 0, 73, 31, 73, 0, 73,
+ 32, 73, 0, 73, 34, 73, 0, 73, 33, 73,
+ 0, 73, 23, 73, 0, 73, 24, 73, 0, 73,
+ 27, 73, 0, 73, 29, 73, 30, 73, 0, 73,
+ 29, 73, 52, 75, 0, 73, 29, 7, 0, 73,
+ 42, 29, 73, 30, 73, 0, 73, 42, 29, 73,
+ 52, 75, 0, 73, 42, 29, 7, 0, 73, 28,
+ 73, 0, 73, 25, 73, 0, 73, 26, 73, 0,
+ 73, 18, 73, 0, 73, 18, 21, 73, 0, 73,
+ 19, 73, 0, 73, 19, 22, 73, 0, 73, 20,
+ 73, 0, 70, 43, 0, 70, 44, 0, 70, 45,
+ 75, 0, 70, 46, 75, 0, 70, 47, 75, 0,
+ 70, 53, 0, 70, 54, 0, 77, 49, 57, 73,
+ 64, 73, 62, 0, 77, 48, 57, 73, 64, 73,
+ 62, 0, 77, 51, 57, 73, 62, 0, 76, 45,
+ 75, 0, 76, 46, 75, 0, 76, 47, 75, 0,
+ 76, 55, 57, 73, 62, 0, 76, 50, 0, 0,
+ 57, 3, 62, 0, 7, 0, 76, 0, 0, 3,
+ 0, 5, 0, 6, 0, 4, 0, 9, 0, 60,
+ 7, 0, 10, 0, 80, 10, 0, 12, 0, 80,
+ 12, 0, 10, 0, 7, 0, 12, 0, 8, 0,
+ 80, 8, 0, 7, 0, 80, 7, 0, 7, 43,
+ 0, 80, 7, 43, 0, 36, 73, 0, 34, 73,
+ 0, 73, 58, 73, 67, 0
+};
+
+#endif
+
+#if YYDEBUG
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const short yyrline[] =
+{
+ 0, 203, 204, 210, 211, 216, 220, 227, 235, 243,
+ 243, 254, 256, 261, 264, 267, 274, 282, 285, 292,
+ 296, 300, 304, 308, 312, 315, 317, 319, 321, 325,
+ 335, 339, 343, 347, 351, 355, 359, 363, 367, 371,
+ 375, 379, 383, 387, 393, 400, 405, 413, 423, 427,
+ 431, 435, 439, 443, 447, 451, 455, 457, 463, 465,
+ 467, 469, 471, 473, 475, 477, 479, 481, 483, 485,
+ 487, 491, 493, 497, 504, 506, 513, 521, 533, 541,
+ 548, 575, 579, 580, 582, 583, 587, 588, 589, 592,
+ 594, 599, 600, 601, 603, 610, 612, 614
+};
+#endif
+
+
+#if (YYDEBUG) || defined YYERROR_VERBOSE
+
+/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */
+static const char *const yytname[] =
+{
+ "$", "error", "$undefined.", "INT", "NULL_PTR", "CHARLIT", "FLOAT",
+ "TYPENAME", "BLOCKNAME", "STRING", "NAME", "DOT_ID", "OBJECT_RENAMING",
+ "DOT_ALL", "LAST", "REGNAME", "INTERNAL_VARIABLE", "ASSIGN", "_AND_",
+ "OR", "XOR", "THEN", "ELSE", "'='", "NOTEQUAL", "'<'", "'>'", "LEQ",
+ "GEQ", "IN", "DOTDOT", "'@'", "'+'", "'-'", "'&'", "UNARY", "'*'",
+ "'/'", "MOD", "REM", "STARSTAR", "ABS", "NOT", "TICK_ACCESS",
+ "TICK_ADDRESS", "TICK_FIRST", "TICK_LAST", "TICK_LENGTH", "TICK_MAX",
+ "TICK_MIN", "TICK_MODULUS", "TICK_POS", "TICK_RANGE", "TICK_SIZE",
+ "TICK_TAG", "TICK_VAL", "'.'", "'('", "'['", "ARROW", "NEW", "';'",
+ "')'", "'\\''", "','", "'{'", "'}'", "']'", "start", "exp1",
+ "simple_exp", "@1", "save_qualifier", "exp", "arglist", "tick_arglist",
+ "type_prefix", "opt_type_prefix", "variable", "any_name", "block",
+ "type", 0
+};
+#endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const short yyr1[] =
+{
+ 0, 68, 68, 69, 69, 70, 70, 70, 70, 71,
+ 70, 72, 70, 70, 70, 70, 70, 73, 70, 73,
+ 73, 73, 73, 73, 74, 74, 74, 74, 74, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 70, 70, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+ 70, 75, 75, 76, 77, 77, 73, 73, 73, 73,
+ 73, 73, 78, 78, 78, 78, 79, 79, 79, 80,
+ 80, 81, 81, 81, 81, 73, 73, 73
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const short yyr2[] =
+{
+ 0, 1, 1, 1, 3, 2, 2, 4, 4, 0,
+ 7, 0, 6, 3, 1, 1, 1, 1, 1, 3,
+ 2, 2, 2, 2, 0, 1, 3, 3, 5, 4,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 5, 5, 3, 6, 6, 4, 3, 3,
+ 3, 3, 4, 3, 4, 3, 2, 2, 3, 3,
+ 3, 2, 2, 7, 7, 5, 3, 3, 3, 5,
+ 2, 0, 3, 1, 1, 0, 1, 1, 1, 1,
+ 1, 2, 1, 2, 1, 2, 1, 1, 1, 1,
+ 2, 1, 2, 2, 3, 2, 2, 4
+};
+
+/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
+ doesn't specify something else to do. Zero means the default is an
+ error. */
+static const short yydefact[] =
+{
+ 75, 76, 79, 77, 78, 73, 89, 80, 82, 84,
+ 18, 15, 16, 75, 75, 75, 75, 75, 75, 75,
+ 0, 0, 1, 17, 3, 74, 0, 14, 0, 2,
+ 93, 21, 0, 20, 96, 95, 23, 22, 0, 81,
+ 91, 0, 0, 75, 6, 5, 56, 57, 71, 71,
+ 71, 61, 62, 75, 75, 75, 75, 75, 75, 75,
+ 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+ 75, 75, 75, 75, 0, 75, 71, 71, 71, 70,
+ 0, 0, 0, 0, 92, 90, 83, 85, 75, 11,
+ 13, 75, 4, 0, 58, 59, 60, 73, 82, 84,
+ 25, 0, 0, 19, 75, 51, 75, 53, 55, 39,
+ 40, 49, 50, 41, 48, 44, 0, 35, 36, 38,
+ 37, 31, 32, 34, 33, 30, 75, 0, 66, 67,
+ 68, 75, 75, 75, 75, 94, 0, 9, 29, 0,
+ 75, 7, 75, 75, 52, 54, 75, 71, 47, 0,
+ 97, 0, 0, 0, 0, 8, 0, 72, 0, 27,
+ 0, 26, 42, 43, 75, 71, 69, 75, 75, 65,
+ 75, 12, 75, 45, 46, 0, 0, 0, 28, 64,
+ 63, 10, 0, 0, 0
+};
+
+static const short yydefgoto[] =
+{
+ 182, 22, 23, 156, 137, 24, 101, 94, 25, 26,
+ 27, 102, 28, 32
+};
+
+static const short yypact[] =
+{
+ 251,-32768,-32768,-32768,-32768, 20,-32768,-32768,-32768,-32768,
+ -32768,-32768,-32768, 251, 251, 251, 251, 251, 251, 251,
+ 2, 79, -47, 53, 958, -23, 54,-32768, 104, -32,
+ -32768, 31, -32, 31, -22, -22, 31, 31, 33,-32768,
+ -5, 101, -27, 251,-32768,-32768,-32768,-32768, 4, 4,
+ 4,-32768,-32768, 131, 251, 171, 211, 251, 251, 251,
+ 251, 251, 251, 251, 291, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 47, 251, 4, 4, 4,-32768,
+ 23, 25, 27, 35, 45,-32768,-32768,-32768, 251,-32768,
+ -32768, 251, 958, 98,-32768,-32768,-32768, 22, 56, 58,
+ 930, -36, 64, 986, 251, 1009, 251, 1009, 1009, -21,
+ -21, -21, -21, -21, -21, 534, 858, 387, 31, 31,
+ 31, 32, 32, 32, 32, 32, 331, 415,-32768,-32768,
+ -32768, 251, 251, 251, 251,-32768, 536,-32768, -22, 62,
+ 251,-32768, 371, 251, 1009, 1009, 251, 4, 534, 894,
+ -32768, 582, 452, 494, 628,-32768, 68,-32768, 674, 958,
+ 67, 958, -21,-32768, 251, 4,-32768, 251, 251,-32768,
+ 251,-32768, 251, -21,-32768, 720, 766, 812, 958,-32768,
+ -32768,-32768, 128, 132,-32768
+};
+
+static const short yypgoto[] =
+{
+ -32768, 112,-32768,-32768,-32768, -13,-32768, -43,-32768,-32768,
+ -32768, 0, 123, 8
+};
+
+
+#define YYLAST 1067
+
+
+static const short yytable[] =
+{
+ 31, 33, 34, 35, 36, 37, 95, 96, 29, 39,
+ 65, 66, 67, 68, 43, 69, 70, 71, 72, 73,
+ -91, 74, 76, 77, 78, 88, 141, 79, 142, 42,
+ 92, 89, 80, 128, 129, 130, 75, 75, 30, 91,
+ 100, 103, 105, 107, 108, 109, 110, 111, 112, 113,
+ 114, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 93, 127, 30, 44, 30, 45, 69, 70, 71,
+ 72, 73, 73, 74, 74, 136, 126, -91, 138, -91,
+ 131, -87, 132, -91, 133, -91, 40, 6, 135, 75,
+ 75, 144, 134, 145, 43, 90, 46, 47, 48, 49,
+ 50, 139, 81, 82, 163, 83, 51, 52, 84, 85,
+ 53, 84, 85, 149, 86, -86, 87, -88, 151, 152,
+ 153, 154, 174, 143, 157, 170, 172, 158, 183, 159,
+ 161, 38, 184, 162, 1, 2, 3, 4, 97, 6,
+ 7, 98, 160, 99, 41, 10, 11, 12, 0, 0,
+ 0, 173, 0, 0, 175, 176, 0, 177, 0, 178,
+ 0, 0, 0, 13, 14, 15, 0, 16, 0, 0,
+ 0, 0, 17, 18, 1, 2, 3, 4, 5, 6,
+ 7, 8, 0, 9, 0, 10, 11, 12, 19, 0,
+ 0, 20, 104, -24, 0, -24, 21, 0, 0, 0,
+ 0, 0, 0, 13, 14, 15, 0, 16, 0, 0,
+ 0, 0, 17, 18, 1, 2, 3, 4, 5, 6,
+ 7, 8, 0, 9, 0, 10, 11, 12, 19, 0,
+ 0, 20, 0, 106, 0, 0, 21, 0, 0, 0,
+ 0, 0, 0, 13, 14, 15, 0, 16, 0, 0,
+ 0, 0, 17, 18, 1, 2, 3, 4, 5, 6,
+ 7, 8, 0, 9, 0, 10, 11, 12, 19, 0,
+ 0, 20, 0, 0, 0, 0, 21, 0, 0, 0,
+ 0, 0, 0, 13, 14, 15, 0, 16, 0, 0,
+ 0, 0, 17, 18, 1, 2, 3, 4, 115, 6,
+ 7, 8, 0, 9, 0, 10, 11, 12, 19, 0,
+ 0, 20, 0, 0, 0, 0, 21, 0, 0, 0,
+ 0, 0, 0, 13, 14, 15, 0, 16, 0, 0,
+ 0, 0, 17, 18, 1, 2, 3, 4, 148, 6,
+ 7, 8, 0, 9, 0, 10, 11, 12, 19, 0,
+ 0, 20, 0, 0, 0, 0, 21, 0, 0, 0,
+ 0, 0, 0, 13, 14, 15, 0, 16, 0, 0,
+ 0, 0, 17, 18, 1, 2, 3, 4, 97, 6,
+ 7, 98, 0, 99, 0, 10, 11, 12, 19, 0,
+ 0, 20, 0, 0, 0, 0, 21, 0, 0, 0,
+ 0, 0, 0, 13, 14, 15, 0, 16, 0, 0,
+ 0, 0, 17, 18, 0, 0, 0, 0, 0, 66,
+ 67, 68, 0, 69, 70, 71, 72, 73, 19, 74,
+ 0, 20, 54, 55, 56, 57, 21, 0, 58, 59,
+ 60, 61, 62, 63, 64, 75, 65, 66, 67, 68,
+ 0, 69, 70, 71, 72, 73, 0, 74, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,
+ 55, 56, 57, 75, 0, 58, 59, 60, 61, 62,
+ 63, 64, 150, 65, 66, 67, 68, 0, 69, 70,
+ 71, 72, 73, 0, 74, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 75, 54, 55, 56, 57, 0, 167, 58, 59, 60,
+ 61, 62, 63, 64, 0, 65, 66, 67, 68, 0,
+ 69, 70, 71, 72, 73, 0, 74, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 75, 54, 55, 56, 57, 0, 168, 58,
+ 59, 60, 61, 62, 63, 64, 0, 65, 66, 67,
+ 68, 0, 69, 70, 71, 72, 73, 30, 74, -73,
+ -73, -73, -73, -73, -73, -73, 0, 0, 0, -73,
+ 0, -91, 0, 0, 75, 0, 0, -91, 155, 54,
+ 55, 56, 57, 0, 0, 58, 59, 60, 61, 62,
+ 63, 64, 0, 65, 66, 67, 68, 0, 69, 70,
+ 71, 72, 73, 0, 74, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 75, 0, 0, 0, 166, 54, 55, 56, 57, 0,
+ 0, 58, 59, 60, 61, 62, 63, 64, 0, 65,
+ 66, 67, 68, 0, 69, 70, 71, 72, 73, 0,
+ 74, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 75, 0, 0, 0,
+ 169, 54, 55, 56, 57, 0, 0, 58, 59, 60,
+ 61, 62, 63, 64, 0, 65, 66, 67, 68, 0,
+ 69, 70, 71, 72, 73, 0, 74, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 75, 0, 0, 0, 171, 54, 55, 56,
+ 57, 0, 0, 58, 59, 60, 61, 62, 63, 64,
+ 0, 65, 66, 67, 68, 0, 69, 70, 71, 72,
+ 73, 0, 74, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 75, 0,
+ 0, 0, 179, 54, 55, 56, 57, 0, 0, 58,
+ 59, 60, 61, 62, 63, 64, 0, 65, 66, 67,
+ 68, 0, 69, 70, 71, 72, 73, 0, 74, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 75, 0, 0, 0, 180, 54,
+ 55, 56, 57, 0, 0, 58, 59, 60, 61, 62,
+ 63, 64, 0, 65, 66, 67, 68, 0, 69, 70,
+ 71, 72, 73, 0, 74, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 75, 0, 0, 0, 181, 54, 55, 56, 57, 0,
+ 0, 58, 59, 60, 61, 62, 63, 64, 146, 65,
+ 66, 67, 68, 0, 69, 70, 71, 72, 73, 0,
+ 74, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 147, 54, 55, 56, 57, 0, 75, 58, 59, 60,
+ 61, 62, 63, 64, 164, 65, 66, 67, 68, 0,
+ 69, 70, 71, 72, 73, 0, 74, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 165, 54, 55, 56,
+ 57, 0, 75, 58, 59, 60, 61, 62, 63, 64,
+ 140, 65, 66, 67, 68, 0, 69, 70, 71, 72,
+ 73, 0, 74, 0, 0, 54, 55, 56, 57, 0,
+ 0, 58, 59, 60, 61, 62, 63, 64, 75, 65,
+ 66, 67, 68, 0, 69, 70, 71, 72, 73, 0,
+ 74, 0, 0,-32768, 55, 56, 57, 0, 0, 58,
+ 59, 60, 61, 62, 63, 64, 75, 65, 66, 67,
+ 68, 0, 69, 70, 71, 72, 73, 0, 74, 0,
+ 0, 0, 58, 59, 60, 61, 62, 63, 64, 0,
+ 65, 66, 67, 68, 75, 69, 70, 71, 72, 73,
+ 0, 74, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 75
+};
+
+static const short yycheck[] =
+{
+ 13, 14, 15, 16, 17, 18, 49, 50, 0, 7,
+ 31, 32, 33, 34, 61, 36, 37, 38, 39, 40,
+ 0, 42, 45, 46, 47, 57, 62, 50, 64, 21,
+ 43, 63, 55, 76, 77, 78, 58, 58, 43, 66,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 57, 75, 43, 11, 43, 13, 36, 37, 38,
+ 39, 40, 40, 42, 42, 88, 29, 57, 91, 57,
+ 57, 59, 57, 63, 57, 63, 7, 8, 43, 58,
+ 58, 104, 57, 106, 61, 62, 43, 44, 45, 46,
+ 47, 3, 48, 49, 147, 51, 53, 54, 7, 8,
+ 57, 7, 8, 126, 10, 59, 12, 59, 131, 132,
+ 133, 134, 165, 59, 62, 57, 59, 140, 0, 142,
+ 143, 19, 0, 146, 3, 4, 5, 6, 7, 8,
+ 9, 10, 142, 12, 21, 14, 15, 16, -1, -1,
+ -1, 164, -1, -1, 167, 168, -1, 170, -1, 172,
+ -1, -1, -1, 32, 33, 34, -1, 36, -1, -1,
+ -1, -1, 41, 42, 3, 4, 5, 6, 7, 8,
+ 9, 10, -1, 12, -1, 14, 15, 16, 57, -1,
+ -1, 60, 21, 62, -1, 64, 65, -1, -1, -1,
+ -1, -1, -1, 32, 33, 34, -1, 36, -1, -1,
+ -1, -1, 41, 42, 3, 4, 5, 6, 7, 8,
+ 9, 10, -1, 12, -1, 14, 15, 16, 57, -1,
+ -1, 60, -1, 22, -1, -1, 65, -1, -1, -1,
+ -1, -1, -1, 32, 33, 34, -1, 36, -1, -1,
+ -1, -1, 41, 42, 3, 4, 5, 6, 7, 8,
+ 9, 10, -1, 12, -1, 14, 15, 16, 57, -1,
+ -1, 60, -1, -1, -1, -1, 65, -1, -1, -1,
+ -1, -1, -1, 32, 33, 34, -1, 36, -1, -1,
+ -1, -1, 41, 42, 3, 4, 5, 6, 7, 8,
+ 9, 10, -1, 12, -1, 14, 15, 16, 57, -1,
+ -1, 60, -1, -1, -1, -1, 65, -1, -1, -1,
+ -1, -1, -1, 32, 33, 34, -1, 36, -1, -1,
+ -1, -1, 41, 42, 3, 4, 5, 6, 7, 8,
+ 9, 10, -1, 12, -1, 14, 15, 16, 57, -1,
+ -1, 60, -1, -1, -1, -1, 65, -1, -1, -1,
+ -1, -1, -1, 32, 33, 34, -1, 36, -1, -1,
+ -1, -1, 41, 42, 3, 4, 5, 6, 7, 8,
+ 9, 10, -1, 12, -1, 14, 15, 16, 57, -1,
+ -1, 60, -1, -1, -1, -1, 65, -1, -1, -1,
+ -1, -1, -1, 32, 33, 34, -1, 36, -1, -1,
+ -1, -1, 41, 42, -1, -1, -1, -1, -1, 32,
+ 33, 34, -1, 36, 37, 38, 39, 40, 57, 42,
+ -1, 60, 17, 18, 19, 20, 65, -1, 23, 24,
+ 25, 26, 27, 28, 29, 58, 31, 32, 33, 34,
+ -1, 36, 37, 38, 39, 40, -1, 42, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 17,
+ 18, 19, 20, 58, -1, 23, 24, 25, 26, 27,
+ 28, 29, 67, 31, 32, 33, 34, -1, 36, 37,
+ 38, 39, 40, -1, 42, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 58, 17, 18, 19, 20, -1, 64, 23, 24, 25,
+ 26, 27, 28, 29, -1, 31, 32, 33, 34, -1,
+ 36, 37, 38, 39, 40, -1, 42, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 58, 17, 18, 19, 20, -1, 64, 23,
+ 24, 25, 26, 27, 28, 29, -1, 31, 32, 33,
+ 34, -1, 36, 37, 38, 39, 40, 43, 42, 45,
+ 46, 47, 48, 49, 50, 51, -1, -1, -1, 55,
+ -1, 57, -1, -1, 58, -1, -1, 63, 62, 17,
+ 18, 19, 20, -1, -1, 23, 24, 25, 26, 27,
+ 28, 29, -1, 31, 32, 33, 34, -1, 36, 37,
+ 38, 39, 40, -1, 42, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 58, -1, -1, -1, 62, 17, 18, 19, 20, -1,
+ -1, 23, 24, 25, 26, 27, 28, 29, -1, 31,
+ 32, 33, 34, -1, 36, 37, 38, 39, 40, -1,
+ 42, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 58, -1, -1, -1,
+ 62, 17, 18, 19, 20, -1, -1, 23, 24, 25,
+ 26, 27, 28, 29, -1, 31, 32, 33, 34, -1,
+ 36, 37, 38, 39, 40, -1, 42, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 58, -1, -1, -1, 62, 17, 18, 19,
+ 20, -1, -1, 23, 24, 25, 26, 27, 28, 29,
+ -1, 31, 32, 33, 34, -1, 36, 37, 38, 39,
+ 40, -1, 42, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 58, -1,
+ -1, -1, 62, 17, 18, 19, 20, -1, -1, 23,
+ 24, 25, 26, 27, 28, 29, -1, 31, 32, 33,
+ 34, -1, 36, 37, 38, 39, 40, -1, 42, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 58, -1, -1, -1, 62, 17,
+ 18, 19, 20, -1, -1, 23, 24, 25, 26, 27,
+ 28, 29, -1, 31, 32, 33, 34, -1, 36, 37,
+ 38, 39, 40, -1, 42, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 58, -1, -1, -1, 62, 17, 18, 19, 20, -1,
+ -1, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, -1, 36, 37, 38, 39, 40, -1,
+ 42, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 52, 17, 18, 19, 20, -1, 58, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, -1,
+ 36, 37, 38, 39, 40, -1, 42, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 52, 17, 18, 19,
+ 20, -1, 58, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, -1, 36, 37, 38, 39,
+ 40, -1, 42, -1, -1, 17, 18, 19, 20, -1,
+ -1, 23, 24, 25, 26, 27, 28, 29, 58, 31,
+ 32, 33, 34, -1, 36, 37, 38, 39, 40, -1,
+ 42, -1, -1, 17, 18, 19, 20, -1, -1, 23,
+ 24, 25, 26, 27, 28, 29, 58, 31, 32, 33,
+ 34, -1, 36, 37, 38, 39, 40, -1, 42, -1,
+ -1, -1, 23, 24, 25, 26, 27, 28, 29, -1,
+ 31, 32, 33, 34, 58, 36, 37, 38, 39, 40,
+ -1, 42, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 58
+};
+/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
+#line 3 "/usr/local/share/bison/bison.simple"
+
+/* Skeleton output parser for bison,
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software
+ Foundation, Inc.
+
+ 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, 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. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* This is the parser code that is written into each bison parser when
+ the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE)
+
+/* The parser invokes alloca or xmalloc; define the necessary symbols. */
+
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# else
+# ifndef YYSTACK_USE_ALLOCA
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC xmalloc
+# define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short yyss;
+ YYSTYPE yyvs;
+# if YYLSP_NEEDED
+ YYLTYPE yyls;
+# endif
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# if YYLSP_NEEDED
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAX)
+# else
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAX)
+# endif
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrlab1
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+#define YYFAIL goto yyerrlab
+#define YYRECOVERING() (!!yyerrstatus)
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up"); \
+ YYERROR; \
+ } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+ are run).
+
+ When YYLLOC_DEFAULT is run, CURRENT is set the location of the
+ first token. By default, to implement support for ranges, extend
+ its range to the last symbol. */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ Current.last_line = Rhs[N].last_line; \
+ Current.last_column = Rhs[N].last_column;
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#if YYPURE
+# if YYLSP_NEEDED
+# ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+# else
+# define YYLEX yylex (&yylval, &yylloc)
+# endif
+# else /* !YYLSP_NEEDED */
+# ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, YYLEX_PARAM)
+# else
+# define YYLEX yylex (&yylval)
+# endif
+# endif /* !YYLSP_NEEDED */
+#else /* !YYPURE */
+# define YYLEX yylex ()
+#endif /* !YYPURE */
+
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+#endif /* !YYDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+#ifdef YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+#endif
+
+#line 315 "/usr/local/share/bison/bison.simple"
+
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+ into yyparse. The argument should have type void *.
+ It should actually point to an object.
+ Grammar actions can access the variable by casting it
+ to the proper pointer type. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+# define YYPARSE_PARAM_DECL
+# else
+# define YYPARSE_PARAM_ARG YYPARSE_PARAM
+# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+# endif
+#else /* !YYPARSE_PARAM */
+# define YYPARSE_PARAM_ARG
+# define YYPARSE_PARAM_DECL
+#endif /* !YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+# ifdef YYPARSE_PARAM
+int yyparse (void *);
+# else
+int yyparse (void);
+# endif
+#endif
+
+/* YY_DECL_VARIABLES -- depending whether we use a pure parser,
+ variables are global, or local to YYPARSE. */
+
+#define YY_DECL_NON_LSP_VARIABLES \
+/* The lookahead symbol. */ \
+int yychar; \
+ \
+/* The semantic value of the lookahead symbol. */ \
+YYSTYPE yylval; \
+ \
+/* Number of parse errors so far. */ \
+int yynerrs;
+
+#if YYLSP_NEEDED
+# define YY_DECL_VARIABLES \
+YY_DECL_NON_LSP_VARIABLES \
+ \
+/* Location data for the lookahead symbol. */ \
+YYLTYPE yylloc;
+#else
+# define YY_DECL_VARIABLES \
+YY_DECL_NON_LSP_VARIABLES
+#endif
+
+
+/* If nonreentrant, generate the variables here. */
+
+#if !YYPURE
+YY_DECL_VARIABLES
+#endif /* !YYPURE */
+
+int
+yyparse (YYPARSE_PARAM_ARG)
+ YYPARSE_PARAM_DECL
+{
+ /* If reentrant, generate the variables here. */
+#if YYPURE
+ YY_DECL_VARIABLES
+#endif /* !YYPURE */
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yychar1 = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to xreallocate them elsewhere. */
+
+ /* The state stack. */
+ short yyssa[YYINITDEPTH];
+ short *yyss = yyssa;
+ register short *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+#if YYLSP_NEEDED
+ /* The location stack. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp;
+#endif
+
+#if YYLSP_NEEDED
+# define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
+#else
+# define YYPOPSTACK (yyvsp--, yyssp--)
+#endif
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+#if YYLSP_NEEDED
+ YYLTYPE yyloc;
+#endif
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+#if YYLSP_NEEDED
+ yylsp = yyls;
+#endif
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to xreallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. */
+# if YYLSP_NEEDED
+ YYLTYPE *yyls1 = yyls;
+ /* This used to be a conditional around just the two extra args,
+ but that might be undefined if yyoverflow is a macro. */
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yyls1, yysize * sizeof (*yylsp),
+ &yystacksize);
+ yyls = yyls1;
+# else
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yystacksize);
+# endif
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ goto yyoverflowlab;
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyoverflowlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+# if YYLSP_NEEDED
+ YYSTACK_RELOCATE (yyls);
+# endif
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+#if YYLSP_NEEDED
+ yylsp = yyls + yysize - 1;
+#endif
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more */
+
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE (yychar);
+
+#if YYDEBUG
+ /* We have to keep this `#if YYDEBUG', since we use variables
+ which are defined only if `YYDEBUG' is set. */
+ if (yydebug)
+ {
+ YYFPRINTF (stderr, "Next token is %d (%s",
+ yychar, yytname[yychar1]);
+ /* Give the individual parser a way to print the precise
+ meaning of a token, for further debugging info. */
+# ifdef YYPRINT
+ YYPRINT (stderr, yychar, yylval);
+# endif
+ YYFPRINTF (stderr, ")\n");
+ }
+#endif
+ }
+
+ yyn += yychar1;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ goto yydefault;
+
+ yyn = yytable[yyn];
+
+ /* yyn is what to do for this token type in this state.
+ Negative => reduce, -yyn is rule number.
+ Positive => shift, yyn is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrlab;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+ YYDPRINTF ((stderr, "Shifting token %d (%s), ",
+ yychar, yytname[yychar1]));
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+#if YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to the semantic value of
+ the lookahead token. This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+#if YYLSP_NEEDED
+ /* Similarly for the default location. Let the user run additional
+ commands if for instance locations are ranges. */
+ yyloc = yylsp[1-yylen];
+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+#endif
+
+#if YYDEBUG
+ /* We have to keep this `#if YYDEBUG', since we use variables which
+ are defined only if `YYDEBUG' is set. */
+ if (yydebug)
+ {
+ int yyi;
+
+ YYFPRINTF (stderr, "Reducing via rule %d (line %d), ",
+ yyn, yyrline[yyn]);
+
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+ YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+ }
+#endif
+
+ switch (yyn) {
+
+case 2:
+#line 204 "./ada-exp.y"
+{ write_exp_elt_opcode (OP_TYPE);
+ write_exp_elt_type (yyvsp[0].tval);
+ write_exp_elt_opcode (OP_TYPE); }
+ break;
+case 4:
+#line 212 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_COMMA); }
+ break;
+case 5:
+#line 217 "./ada-exp.y"
+{ write_exp_elt_opcode (UNOP_IND); }
+ break;
+case 6:
+#line 221 "./ada-exp.y"
+{ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ write_exp_string (yyvsp[0].ssym.stoken);
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ }
+ break;
+case 7:
+#line 228 "./ada-exp.y"
+{
+ write_exp_elt_opcode (OP_FUNCALL);
+ write_exp_elt_longcst (yyvsp[-1].lval);
+ write_exp_elt_opcode (OP_FUNCALL);
+ }
+ break;
+case 8:
+#line 236 "./ada-exp.y"
+{
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (yyvsp[-3].tval);
+ write_exp_elt_opcode (UNOP_CAST);
+ }
+ break;
+case 9:
+#line 243 "./ada-exp.y"
+{ type_qualifier = yyvsp[-2].tval; }
+ break;
+case 10:
+#line 244 "./ada-exp.y"
+{
+ /* write_exp_elt_opcode (UNOP_QUAL); */
+ /* FIXME: UNOP_QUAL should be defined in expression.h */
+ write_exp_elt_type (yyvsp[-6].tval);
+ /* write_exp_elt_opcode (UNOP_QUAL); */
+ /* FIXME: UNOP_QUAL should be defined in expression.h */
+ type_qualifier = yyvsp[-4].tval;
+ }
+ break;
+case 11:
+#line 254 "./ada-exp.y"
+{ yyval.tval = type_qualifier; }
+ break;
+case 12:
+#line 258 "./ada-exp.y"
+{ write_exp_elt_opcode (TERNOP_SLICE); }
+ break;
+case 13:
+#line 261 "./ada-exp.y"
+{ }
+ break;
+case 15:
+#line 268 "./ada-exp.y"
+{ write_exp_elt_opcode (OP_REGISTER);
+ write_exp_elt_longcst ((LONGEST) yyvsp[0].lval);
+ write_exp_elt_opcode (OP_REGISTER);
+ }
+ break;
+case 16:
+#line 275 "./ada-exp.y"
+{ write_exp_elt_opcode (OP_INTERNALVAR);
+ write_exp_elt_intern (yyvsp[0].ivar);
+ write_exp_elt_opcode (OP_INTERNALVAR);
+ }
+ break;
+case 18:
+#line 286 "./ada-exp.y"
+{ write_exp_elt_opcode (OP_LAST);
+ write_exp_elt_longcst ((LONGEST) yyvsp[0].lval);
+ write_exp_elt_opcode (OP_LAST);
+ }
+ break;
+case 19:
+#line 293 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_ASSIGN); }
+ break;
+case 20:
+#line 297 "./ada-exp.y"
+{ write_exp_elt_opcode (UNOP_NEG); }
+ break;
+case 21:
+#line 301 "./ada-exp.y"
+{ write_exp_elt_opcode (UNOP_PLUS); }
+ break;
+case 22:
+#line 305 "./ada-exp.y"
+{ write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
+ break;
+case 23:
+#line 309 "./ada-exp.y"
+{ write_exp_elt_opcode (UNOP_ABS); }
+ break;
+case 24:
+#line 312 "./ada-exp.y"
+{ yyval.lval = 0; }
+ break;
+case 25:
+#line 316 "./ada-exp.y"
+{ yyval.lval = 1; }
+ break;
+case 26:
+#line 318 "./ada-exp.y"
+{ yyval.lval = 1; }
+ break;
+case 27:
+#line 320 "./ada-exp.y"
+{ yyval.lval = yyvsp[-2].lval + 1; }
+ break;
+case 28:
+#line 322 "./ada-exp.y"
+{ yyval.lval = yyvsp[-4].lval + 1; }
+ break;
+case 29:
+#line 327 "./ada-exp.y"
+{ write_exp_elt_opcode (UNOP_MEMVAL);
+ write_exp_elt_type (yyvsp[-2].tval);
+ write_exp_elt_opcode (UNOP_MEMVAL);
+ }
+ break;
+case 30:
+#line 336 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_EXP); }
+ break;
+case 31:
+#line 340 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_MUL); }
+ break;
+case 32:
+#line 344 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_DIV); }
+ break;
+case 33:
+#line 348 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_REM); }
+ break;
+case 34:
+#line 352 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_MOD); }
+ break;
+case 35:
+#line 356 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_REPEAT); }
+ break;
+case 36:
+#line 360 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_ADD); }
+ break;
+case 37:
+#line 364 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_CONCAT); }
+ break;
+case 38:
+#line 368 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_SUB); }
+ break;
+case 39:
+#line 372 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_EQUAL); }
+ break;
+case 40:
+#line 376 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_NOTEQUAL); }
+ break;
+case 41:
+#line 380 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_LEQ); }
+ break;
+case 42:
+#line 384 "./ada-exp.y"
+{ /*write_exp_elt_opcode (TERNOP_MBR); */ }
+ break;
+case 43:
+#line 388 "./ada-exp.y"
+{ /*write_exp_elt_opcode (BINOP_MBR); */
+ /* FIXME: BINOP_MBR should be defined in expression.h */
+ write_exp_elt_longcst ((LONGEST) yyvsp[0].lval);
+ /*write_exp_elt_opcode (BINOP_MBR); */
+ }
+ break;
+case 44:
+#line 394 "./ada-exp.y"
+{ /*write_exp_elt_opcode (UNOP_MBR); */
+ /* FIXME: UNOP_QUAL should be defined in expression.h */
+ write_exp_elt_type (yyvsp[0].tval);
+ /* write_exp_elt_opcode (UNOP_MBR); */
+ /* FIXME: UNOP_MBR should be defined in expression.h */
+ }
+ break;
+case 45:
+#line 401 "./ada-exp.y"
+{ /*write_exp_elt_opcode (TERNOP_MBR); */
+ /* FIXME: TERNOP_MBR should be defined in expression.h */
+ write_exp_elt_opcode (UNOP_LOGICAL_NOT);
+ }
+ break;
+case 46:
+#line 406 "./ada-exp.y"
+{ /* write_exp_elt_opcode (BINOP_MBR); */
+ /* FIXME: BINOP_MBR should be defined in expression.h */
+ write_exp_elt_longcst ((LONGEST) yyvsp[0].lval);
+ /*write_exp_elt_opcode (BINOP_MBR);*/
+ /* FIXME: BINOP_MBR should be defined in expression.h */
+ write_exp_elt_opcode (UNOP_LOGICAL_NOT);
+ }
+ break;
+case 47:
+#line 414 "./ada-exp.y"
+{ /*write_exp_elt_opcode (UNOP_MBR);*/
+ /* FIXME: UNOP_MBR should be defined in expression.h */
+ write_exp_elt_type (yyvsp[0].tval);
+ /* write_exp_elt_opcode (UNOP_MBR);*/
+ /* FIXME: UNOP_MBR should be defined in expression.h */
+ write_exp_elt_opcode (UNOP_LOGICAL_NOT);
+ }
+ break;
+case 48:
+#line 424 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_GEQ); }
+ break;
+case 49:
+#line 428 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_LESS); }
+ break;
+case 50:
+#line 432 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_GTR); }
+ break;
+case 51:
+#line 436 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_BITWISE_AND); }
+ break;
+case 52:
+#line 440 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_LOGICAL_AND); }
+ break;
+case 53:
+#line 444 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_BITWISE_IOR); }
+ break;
+case 54:
+#line 448 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_LOGICAL_OR); }
+ break;
+case 55:
+#line 452 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_BITWISE_XOR); }
+ break;
+case 56:
+#line 456 "./ada-exp.y"
+{ write_exp_elt_opcode (UNOP_ADDR); }
+ break;
+case 57:
+#line 458 "./ada-exp.y"
+{ write_exp_elt_opcode (UNOP_ADDR);
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (builtin_type_ada_system_address);
+ write_exp_elt_opcode (UNOP_CAST);
+ }
+ break;
+case 58:
+#line 464 "./ada-exp.y"
+{ write_attribute_call1 (ATR_FIRST, yyvsp[0].lval); }
+ break;
+case 59:
+#line 466 "./ada-exp.y"
+{ write_attribute_call1 (ATR_LAST, yyvsp[0].lval); }
+ break;
+case 60:
+#line 468 "./ada-exp.y"
+{ write_attribute_call1 (ATR_LENGTH, yyvsp[0].lval); }
+ break;
+case 61:
+#line 470 "./ada-exp.y"
+{ write_attribute_call0 (ATR_SIZE); }
+ break;
+case 62:
+#line 472 "./ada-exp.y"
+{ write_attribute_call0 (ATR_TAG); }
+ break;
+case 63:
+#line 474 "./ada-exp.y"
+{ write_attribute_calln (ATR_MIN, 2); }
+ break;
+case 64:
+#line 476 "./ada-exp.y"
+{ write_attribute_calln (ATR_MAX, 2); }
+ break;
+case 65:
+#line 478 "./ada-exp.y"
+{ write_attribute_calln (ATR_POS, 1); }
+ break;
+case 66:
+#line 480 "./ada-exp.y"
+{ write_attribute_call1 (ATR_FIRST, yyvsp[0].lval); }
+ break;
+case 67:
+#line 482 "./ada-exp.y"
+{ write_attribute_call1 (ATR_LAST, yyvsp[0].lval); }
+ break;
+case 68:
+#line 484 "./ada-exp.y"
+{ write_attribute_call1 (ATR_LENGTH, yyvsp[0].lval); }
+ break;
+case 69:
+#line 486 "./ada-exp.y"
+{ write_attribute_calln (ATR_VAL, 1); }
+ break;
+case 70:
+#line 488 "./ada-exp.y"
+{ write_attribute_call0 (ATR_MODULUS); }
+ break;
+case 71:
+#line 492 "./ada-exp.y"
+{ yyval.lval = 1; }
+ break;
+case 72:
+#line 494 "./ada-exp.y"
+{ yyval.lval = yyvsp[-1].typed_val.val; }
+ break;
+case 73:
+#line 499 "./ada-exp.y"
+{ write_exp_elt_opcode (OP_TYPE);
+ write_exp_elt_type (yyvsp[0].tval);
+ write_exp_elt_opcode (OP_TYPE); }
+ break;
+case 75:
+#line 507 "./ada-exp.y"
+{ write_exp_elt_opcode (OP_TYPE);
+ write_exp_elt_type (builtin_type_void);
+ write_exp_elt_opcode (OP_TYPE); }
+ break;
+case 76:
+#line 514 "./ada-exp.y"
+{ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (yyvsp[0].typed_val.type);
+ write_exp_elt_longcst ((LONGEST)(yyvsp[0].typed_val.val));
+ write_exp_elt_opcode (OP_LONG);
+ }
+ break;
+case 77:
+#line 522 "./ada-exp.y"
+{ write_exp_elt_opcode (OP_LONG);
+ if (type_qualifier == NULL)
+ write_exp_elt_type (yyvsp[0].typed_val.type);
+ else
+ write_exp_elt_type (type_qualifier);
+ write_exp_elt_longcst
+ (convert_char_literal (type_qualifier, yyvsp[0].typed_val.val));
+ write_exp_elt_opcode (OP_LONG);
+ }
+ break;
+case 78:
+#line 534 "./ada-exp.y"
+{ write_exp_elt_opcode (OP_DOUBLE);
+ write_exp_elt_type (yyvsp[0].typed_val_float.type);
+ write_exp_elt_dblcst (yyvsp[0].typed_val_float.dval);
+ write_exp_elt_opcode (OP_DOUBLE);
+ }
+ break;
+case 79:
+#line 542 "./ada-exp.y"
+{ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_int);
+ write_exp_elt_longcst ((LONGEST)(0));
+ write_exp_elt_opcode (OP_LONG);
+ }
+ break;
+case 80:
+#line 549 "./ada-exp.y"
+{ /* Ada strings are converted into array constants
+ a lower bound of 1. Thus, the array upper bound
+ is the string length. */
+ char *sp = yyvsp[0].sval.ptr; int count;
+ if (yyvsp[0].sval.length == 0)
+ { /* One dummy character for the type */
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_ada_char);
+ write_exp_elt_longcst ((LONGEST)(0));
+ write_exp_elt_opcode (OP_LONG);
+ }
+ for (count = yyvsp[0].sval.length; count > 0; count -= 1)
+ {
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_ada_char);
+ write_exp_elt_longcst ((LONGEST)(*sp));
+ sp += 1;
+ write_exp_elt_opcode (OP_LONG);
+ }
+ write_exp_elt_opcode (OP_ARRAY);
+ write_exp_elt_longcst ((LONGEST) 1);
+ write_exp_elt_longcst ((LONGEST) (yyvsp[0].sval.length));
+ write_exp_elt_opcode (OP_ARRAY);
+ }
+ break;
+case 81:
+#line 576 "./ada-exp.y"
+{ error ("NEW not implemented."); }
+ break;
+case 82:
+#line 579 "./ada-exp.y"
+{ write_var_from_name (NULL, yyvsp[0].ssym); }
+ break;
+case 83:
+#line 581 "./ada-exp.y"
+{ write_var_from_name (yyvsp[-1].bval, yyvsp[0].ssym); }
+ break;
+case 84:
+#line 582 "./ada-exp.y"
+{ write_object_renaming (NULL, yyvsp[0].ssym.sym); }
+ break;
+case 85:
+#line 584 "./ada-exp.y"
+{ write_object_renaming (yyvsp[-1].bval, yyvsp[0].ssym.sym); }
+ break;
+case 86:
+#line 587 "./ada-exp.y"
+{ }
+ break;
+case 87:
+#line 588 "./ada-exp.y"
+{ }
+ break;
+case 88:
+#line 589 "./ada-exp.y"
+{ }
+ break;
+case 89:
+#line 593 "./ada-exp.y"
+{ yyval.bval = yyvsp[0].bval; }
+ break;
+case 90:
+#line 595 "./ada-exp.y"
+{ yyval.bval = yyvsp[0].bval; }
+ break;
+case 91:
+#line 599 "./ada-exp.y"
+{ yyval.tval = yyvsp[0].tval; }
+ break;
+case 92:
+#line 600 "./ada-exp.y"
+{ yyval.tval = yyvsp[0].tval; }
+ break;
+case 93:
+#line 602 "./ada-exp.y"
+{ yyval.tval = lookup_pointer_type (yyvsp[-1].tval); }
+ break;
+case 94:
+#line 604 "./ada-exp.y"
+{ yyval.tval = lookup_pointer_type (yyvsp[-1].tval); }
+ break;
+case 95:
+#line 611 "./ada-exp.y"
+{ write_exp_elt_opcode (UNOP_IND); }
+ break;
+case 96:
+#line 613 "./ada-exp.y"
+{ write_exp_elt_opcode (UNOP_ADDR); }
+ break;
+case 97:
+#line 615 "./ada-exp.y"
+{ write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+ break;
+}
+
+#line 705 "/usr/local/share/bison/bison.simple"
+
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+#if YYLSP_NEEDED
+ yylsp -= yylen;
+#endif
+
+#if YYDEBUG
+ if (yydebug)
+ {
+ short *yyssp1 = yyss - 1;
+ YYFPRINTF (stderr, "state stack now");
+ while (yyssp1 != yyssp)
+ YYFPRINTF (stderr, " %d", *++yyssp1);
+ YYFPRINTF (stderr, "\n");
+ }
+#endif
+
+ *++yyvsp = yyval;
+#if YYLSP_NEEDED
+ *++yylsp = yyloc;
+#endif
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+ if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTBASE];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (yyn > YYFLAG && yyn < YYLAST)
+ {
+ YYSIZE_T yysize = 0;
+ char *yymsg;
+ int yyx, yycount;
+
+ yycount = 0;
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+ if (yycheck[yyx + yyn] == yyx)
+ yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+ yysize += yystrlen ("parse error, unexpected ") + 1;
+ yysize += yystrlen (yytname[YYTRANSLATE (yychar)]);
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg != 0)
+ {
+ char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]);
+
+ if (yycount < 5)
+ {
+ yycount = 0;
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *));
+ yyx++)
+ if (yycheck[yyx + yyn] == yyx)
+ {
+ const char *yyq = ! yycount ? ", expecting " : " or ";
+ yyp = yystpcpy (yyp, yyq);
+ yyp = yystpcpy (yyp, yytname[yyx]);
+ yycount++;
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ yyerror ("parse error; also virtual memory exhausted");
+ }
+ else
+#endif /* defined (YYERROR_VERBOSE) */
+ yyerror ("parse error");
+ }
+ goto yyerrlab1;
+
+
+/*--------------------------------------------------.
+| yyerrlab1 -- error raised explicitly by an action |
+`--------------------------------------------------*/
+yyerrlab1:
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ /* return failure if at end of input */
+ if (yychar == YYEOF)
+ YYABORT;
+ YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
+ yychar, yytname[yychar1]));
+ yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this */
+
+ goto yyerrhandle;
+
+
+/*-------------------------------------------------------------------.
+| yyerrdefault -- current state does not do anything special for the |
+| error token. |
+`-------------------------------------------------------------------*/
+yyerrdefault:
+#if 0
+ /* This is wrong; only states that explicitly want error tokens
+ should shift them. */
+
+ /* If its default is to accept any token, ok. Otherwise pop it. */
+ yyn = yydefact[yystate];
+ if (yyn)
+ goto yydefault;
+#endif
+
+
+/*---------------------------------------------------------------.
+| yyerrpop -- pop the current state because it cannot handle the |
+| error token |
+`---------------------------------------------------------------*/
+yyerrpop:
+ if (yyssp == yyss)
+ YYABORT;
+ yyvsp--;
+ yystate = *--yyssp;
+#if YYLSP_NEEDED
+ yylsp--;
+#endif
+
+#if YYDEBUG
+ if (yydebug)
+ {
+ short *yyssp1 = yyss - 1;
+ YYFPRINTF (stderr, "Error: state stack now");
+ while (yyssp1 != yyssp)
+ YYFPRINTF (stderr, " %d", *++yyssp1);
+ YYFPRINTF (stderr, "\n");
+ }
+#endif
+
+/*--------------.
+| yyerrhandle. |
+`--------------*/
+yyerrhandle:
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yyerrdefault;
+
+ yyn += YYTERROR;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+ goto yyerrdefault;
+
+ yyn = yytable[yyn];
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrpop;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrpop;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ YYDPRINTF ((stderr, "Shifting error token, "));
+
+ *++yyvsp = yylval;
+#if YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+/*---------------------------------------------.
+| yyoverflowab -- parser overflow comes here. |
+`---------------------------------------------*/
+yyoverflowlab:
+ yyerror ("parser stack overflow");
+ yyresult = 2;
+ /* Fall through. */
+
+yyreturn:
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+#line 618 "./ada-exp.y"
+
+
+/* yylex defined in ada-lex.c: Reads one token, getting characters */
+/* through lexptr. */
+
+/* Remap normal flex interface names (yylex) as well as gratuitiously */
+/* global symbol names, so we can have multiple flex-generated parsers */
+/* in gdb. */
+
+/* (See note above on previous definitions for YACC.) */
+
+#define yy_create_buffer ada_yy_create_buffer
+#define yy_delete_buffer ada_yy_delete_buffer
+#define yy_init_buffer ada_yy_init_buffer
+#define yy_load_buffer_state ada_yy_load_buffer_state
+#define yy_switch_to_buffer ada_yy_switch_to_buffer
+#define yyrestart ada_yyrestart
+#define yytext ada_yytext
+#define yywrap ada_yywrap
+
+/* The following kludge was found necessary to prevent conflicts between */
+/* defs.h and non-standard stdlib.h files. */
+#define qsort __qsort__dummy
+#include "ada-lex.c"
+
+int
+ada_parse ()
+{
+ lexer_init (yyin); /* (Re-)initialize lexer. */
+ left_block_context = NULL;
+ type_qualifier = NULL;
+
+ return _ada_parse ();
+}
+
+void
+yyerror (msg)
+ char *msg;
+{
+ error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
+}
+
+/* The operator name corresponding to operator symbol STRING (adds
+ quotes and maps to lower-case). Destroys the previous contents of
+ the array pointed to by STRING.ptr. Error if STRING does not match
+ a valid Ada operator. Assumes that STRING.ptr points to a
+ null-terminated string and that, if STRING is a valid operator
+ symbol, the array pointed to by STRING.ptr contains at least
+ STRING.length+3 characters. */
+
+static struct stoken
+string_to_operator (string)
+ struct stoken string;
+{
+ int i;
+
+ for (i = 0; ada_opname_table[i].mangled != NULL; i += 1)
+ {
+ if (string.length == strlen (ada_opname_table[i].demangled)-2
+ && strncasecmp (string.ptr, ada_opname_table[i].demangled+1,
+ string.length) == 0)
+ {
+ strncpy (string.ptr, ada_opname_table[i].demangled,
+ string.length+2);
+ string.length += 2;
+ return string;
+ }
+ }
+ error ("Invalid operator symbol `%s'", string.ptr);
+}
+
+/* Emit expression to access an instance of SYM, in block BLOCK (if
+ * non-NULL), and with :: qualification ORIG_LEFT_CONTEXT. */
+static void
+write_var_from_sym (orig_left_context, block, sym)
+ struct block* orig_left_context;
+ struct block* block;
+ struct symbol* sym;
+{
+ if (orig_left_context == NULL && symbol_read_needs_frame (sym))
+ {
+ if (innermost_block == 0 ||
+ contained_in (block, innermost_block))
+ innermost_block = block;
+ }
+
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ /* We want to use the selected frame, not another more inner frame
+ which happens to be in the same block */
+ write_exp_elt_block (NULL);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+}
+
+/* Emit expression to access an instance of NAME. */
+static void
+write_var_from_name (orig_left_context, name)
+ struct block* orig_left_context;
+ struct name_info name;
+{
+ if (name.msym != NULL)
+ {
+ write_exp_msymbol (name.msym,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
+ }
+ else if (name.sym == NULL)
+ {
+ /* Multiple matches: record name and starting block for later
+ resolution by ada_resolve. */
+ /* write_exp_elt_opcode (OP_UNRESOLVED_VALUE); */
+ /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */
+ write_exp_elt_block (name.block);
+ /* write_exp_elt_name (name.stoken.ptr); */
+ /* FIXME: write_exp_elt_name should be defined in defs.h, located in parse.c */
+ /* write_exp_elt_opcode (OP_UNRESOLVED_VALUE); */
+ /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */
+ }
+ else
+ write_var_from_sym (orig_left_context, name.block, name.sym);
+}
+
+/* Write a call on parameterless attribute ATR. */
+
+static void
+write_attribute_call0 (atr)
+ enum ada_attribute atr;
+{
+ /* write_exp_elt_opcode (OP_ATTRIBUTE); */
+ /* FIXME: OP_ATTRIBUTE should be defined in expression.h */
+ write_exp_elt_longcst ((LONGEST) 0);
+ write_exp_elt_longcst ((LONGEST) atr);
+ /* write_exp_elt_opcode (OP_ATTRIBUTE); */
+ /* FIXME: OP_ATTRIBUTE should be defined in expression.h */
+}
+
+/* Write a call on an attribute ATR with one constant integer
+ * parameter. */
+
+static void
+write_attribute_call1 (atr, arg)
+ enum ada_attribute atr;
+ LONGEST arg;
+{
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_int);
+ write_exp_elt_longcst (arg);
+ write_exp_elt_opcode (OP_LONG);
+ /*write_exp_elt_opcode (OP_ATTRIBUTE);*/
+ /* FIXME: OP_ATTRIBUTE should be defined in expression.h */
+ write_exp_elt_longcst ((LONGEST) 1);
+ write_exp_elt_longcst ((LONGEST) atr);
+ /*write_exp_elt_opcode (OP_ATTRIBUTE);*/
+ /* FIXME: OP_ATTRIBUTE should be defined in expression.h */
+}
+
+/* Write a call on an attribute ATR with N parameters, whose code must have
+ * been generated previously. */
+
+static void
+write_attribute_calln (atr, n)
+ enum ada_attribute atr;
+ int n;
+{
+ /*write_exp_elt_opcode (OP_ATTRIBUTE);*/
+ /* FIXME: OP_ATTRIBUTE should be defined in expression.h */
+ write_exp_elt_longcst ((LONGEST) n);
+ write_exp_elt_longcst ((LONGEST) atr);
+ /* write_exp_elt_opcode (OP_ATTRIBUTE);*/
+ /* FIXME: OP_ATTRIBUTE should be defined in expression.h */
+}
+
+/* Emit expression corresponding to the renamed object designated by
+ * the type RENAMING, which must be the referent of an object renaming
+ * type, in the context of ORIG_LEFT_CONTEXT (?). */
+static void
+write_object_renaming (orig_left_context, renaming)
+ struct block* orig_left_context;
+ struct symbol* renaming;
+{
+ const char* qualification = SYMBOL_NAME (renaming);
+ const char* simple_tail;
+ const char* expr = TYPE_FIELD_NAME (SYMBOL_TYPE (renaming), 0);
+ const char* suffix;
+ char* name;
+ struct symbol* sym;
+ enum { SIMPLE_INDEX, LOWER_BOUND, UPPER_BOUND } slice_state;
+
+ /* if orig_left_context is null, then use the currently selected
+ block, otherwise we might fail our symbol lookup below */
+ if (orig_left_context == NULL)
+ orig_left_context = get_selected_block (NULL);
+
+ for (simple_tail = qualification + strlen (qualification);
+ simple_tail != qualification; simple_tail -= 1)
+ {
+ if (*simple_tail == '.')
+ {
+ simple_tail += 1;
+ break;
+ }
+ else if (STREQN (simple_tail, "__", 2))
+ {
+ simple_tail += 2;
+ break;
+ }
+ }
+
+ suffix = strstr (expr, "___XE");
+ if (suffix == NULL)
+ goto BadEncoding;
+
+ name = (char*) xmalloc (suffix - expr + 1);
+ /* add_name_string_cleanup (name); */
+ /* FIXME: add_name_string_cleanup should be defined in
+ parser-defs.h, implemented in parse.c */
+ strncpy (name, expr, suffix-expr);
+ name[suffix-expr] = '\000';
+ sym = lookup_symbol (name, orig_left_context, VAR_NAMESPACE, 0, NULL);
+ /* if (sym == NULL)
+ error ("Could not find renamed variable: %s", ada_demangle (name));
+ */
+ /* FIXME: ada_demangle should be defined in defs.h, implemented in ada-lang.c */
+ write_var_from_sym (orig_left_context, block_found, sym);
+
+ suffix += 5;
+ slice_state = SIMPLE_INDEX;
+ while (*suffix == 'X')
+ {
+ suffix += 1;
+
+ switch (*suffix) {
+ case 'L':
+ slice_state = LOWER_BOUND;
+ case 'S':
+ suffix += 1;
+ if (isdigit (*suffix))
+ {
+ char* next;
+ long val = strtol (suffix, &next, 10);
+ if (next == suffix)
+ goto BadEncoding;
+ suffix = next;
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_ada_int);
+ write_exp_elt_longcst ((LONGEST) val);
+ write_exp_elt_opcode (OP_LONG);
+ }
+ else
+ {
+ const char* end;
+ char* index_name;
+ int index_len;
+ struct symbol* index_sym;
+
+ end = strchr (suffix, 'X');
+ if (end == NULL)
+ end = suffix + strlen (suffix);
+
+ index_len = simple_tail - qualification + 2 + (suffix - end) + 1;
+ index_name = (char*) xmalloc (index_len);
+ memset (index_name, '\000', index_len);
+ /* add_name_string_cleanup (index_name);*/
+ /* FIXME: add_name_string_cleanup should be defined in
+ parser-defs.h, implemented in parse.c */
+ strncpy (index_name, qualification, simple_tail - qualification);
+ index_name[simple_tail - qualification] = '\000';
+ strncat (index_name, suffix, suffix-end);
+ suffix = end;
+
+ index_sym =
+ lookup_symbol (index_name, NULL, VAR_NAMESPACE, 0, NULL);
+ if (index_sym == NULL)
+ error ("Could not find %s", index_name);
+ write_var_from_sym (NULL, block_found, sym);
+ }
+ if (slice_state == SIMPLE_INDEX)
+ {
+ write_exp_elt_opcode (OP_FUNCALL);
+ write_exp_elt_longcst ((LONGEST) 1);
+ write_exp_elt_opcode (OP_FUNCALL);
+ }
+ else if (slice_state == LOWER_BOUND)
+ slice_state = UPPER_BOUND;
+ else if (slice_state == UPPER_BOUND)
+ {
+ write_exp_elt_opcode (TERNOP_SLICE);
+ slice_state = SIMPLE_INDEX;
+ }
+ break;
+
+ case 'R':
+ {
+ struct stoken field_name;
+ const char* end;
+ suffix += 1;
+
+ if (slice_state != SIMPLE_INDEX)
+ goto BadEncoding;
+ end = strchr (suffix, 'X');
+ if (end == NULL)
+ end = suffix + strlen (suffix);
+ field_name.length = end - suffix;
+ field_name.ptr = (char*) xmalloc (end - suffix + 1);
+ strncpy (field_name.ptr, suffix, end - suffix);
+ field_name.ptr[end - suffix] = '\000';
+ suffix = end;
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ write_exp_string (field_name);
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ break;
+ }
+
+ default:
+ goto BadEncoding;
+ }
+ }
+ if (slice_state == SIMPLE_INDEX)
+ return;
+
+ BadEncoding:
+ error ("Internal error in encoding of renaming declaration: %s",
+ SYMBOL_NAME (renaming));
+}
+
+/* Convert the character literal whose ASCII value would be VAL to the
+ appropriate value of type TYPE, if there is a translation.
+ Otherwise return VAL. Hence, in an enumeration type ('A', 'B'),
+ the literal 'A' (VAL == 65), returns 0. */
+static LONGEST
+convert_char_literal (struct type* type, LONGEST val)
+{
+ char name[7];
+ int f;
+
+ if (type == NULL || TYPE_CODE (type) != TYPE_CODE_ENUM)
+ return val;
+ sprintf (name, "QU%02x", (int) val);
+ for (f = 0; f < TYPE_NFIELDS (type); f += 1)
+ {
+ if (STREQ (name, TYPE_FIELD_NAME (type, f)))
+ return TYPE_FIELD_BITPOS (type, f);
+ }
+ return val;
+}
diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y
new file mode 100644
index 00000000000..7d46dd2cf8b
--- /dev/null
+++ b/gdb/ada-exp.y
@@ -0,0 +1,962 @@
+/* YACC parser for Ada expressions, for GDB.
+ Copyright (C) 1986, 1989, 1990, 1991, 1993, 1994, 1997, 2000
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Parse an Ada expression from text in a string,
+ and return the result as a struct expression pointer.
+ That structure contains arithmetic operations in reverse polish,
+ with constants represented by operations that are followed by special data.
+ See expression.h for the details of the format.
+ What is important here is that it can be built up sequentially
+ during the process of parsing; the lower levels of the tree always
+ come first in the result.
+
+ malloc's and realloc's in this file are transformed to
+ xmalloc and xrealloc respectively by the same sed command in the
+ makefile that remaps any other malloc/realloc inserted by the parser
+ generator. Doing this with #defines and trying to control the interaction
+ with include files (<malloc.h> and <stdlib.h> for example) just became
+ too messy, particularly when such includes can be inserted at random
+ times by the parser generator. */
+
+%{
+
+#include "defs.h"
+#include <string.h>
+#include <ctype.h>
+#include "expression.h"
+#include "value.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "ada-lang.h"
+#include "bfd.h" /* Required by objfiles.h. */
+#include "symfile.h" /* Required by objfiles.h. */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+#include "frame.h"
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
+ as well as gratuitiously global symbol names, so we can have multiple
+ yacc generated parsers in gdb. These are only the variables
+ produced by yacc. If other parser generators (bison, byacc, etc) produce
+ additional global names that conflict at link time, then those parser
+ generators need to be fixed instead of adding those names to this list. */
+
+/* NOTE: This is clumsy, especially since BISON and FLEX provide --prefix
+ options. I presume we are maintaining it to accommodate systems
+ without BISON? (PNH) */
+
+#define yymaxdepth ada_maxdepth
+#define yyparse _ada_parse /* ada_parse calls this after initialization */
+#define yylex ada_lex
+#define yyerror ada_error
+#define yylval ada_lval
+#define yychar ada_char
+#define yydebug ada_debug
+#define yypact ada_pact
+#define yyr1 ada_r1
+#define yyr2 ada_r2
+#define yydef ada_def
+#define yychk ada_chk
+#define yypgo ada_pgo
+#define yyact ada_act
+#define yyexca ada_exca
+#define yyerrflag ada_errflag
+#define yynerrs ada_nerrs
+#define yyps ada_ps
+#define yypv ada_pv
+#define yys ada_s
+#define yy_yys ada_yys
+#define yystate ada_state
+#define yytmp ada_tmp
+#define yyv ada_v
+#define yy_yyv ada_yyv
+#define yyval ada_val
+#define yylloc ada_lloc
+#define yyreds ada_reds /* With YYDEBUG defined */
+#define yytoks ada_toks /* With YYDEBUG defined */
+
+#ifndef YYDEBUG
+#define YYDEBUG 0 /* Default to no yydebug support */
+#endif
+
+struct name_info {
+ struct symbol* sym;
+ struct minimal_symbol* msym;
+ struct block* block;
+ struct stoken stoken;
+};
+
+/* If expression is in the context of TYPE'(...), then TYPE, else
+ * NULL. */
+static struct type* type_qualifier;
+
+int yyparse (void);
+
+static int yylex (void);
+
+void yyerror (char *);
+
+static struct stoken string_to_operator (struct stoken);
+
+static void write_attribute_call0 (enum ada_attribute);
+
+static void write_attribute_call1 (enum ada_attribute, LONGEST);
+
+static void write_attribute_calln (enum ada_attribute, int);
+
+static void write_object_renaming (struct block*, struct symbol*);
+
+static void write_var_from_name (struct block*, struct name_info);
+
+static LONGEST
+convert_char_literal (struct type*, LONGEST);
+%}
+
+%union
+ {
+ LONGEST lval;
+ struct {
+ LONGEST val;
+ struct type *type;
+ } typed_val;
+ struct {
+ DOUBLEST dval;
+ struct type *type;
+ } typed_val_float;
+ struct type *tval;
+ struct stoken sval;
+ struct name_info ssym;
+ int voidval;
+ struct block *bval;
+ struct internalvar *ivar;
+
+ }
+
+%type <voidval> exp exp1 simple_exp start variable
+%type <tval> type
+
+%token <typed_val> INT NULL_PTR CHARLIT
+%token <typed_val_float> FLOAT
+%token <tval> TYPENAME
+%token <bval> BLOCKNAME
+
+/* Both NAME and TYPENAME tokens represent symbols in the input,
+ and both convey their data as strings.
+ But a TYPENAME is a string that happens to be defined as a typedef
+ or builtin type name (such as int or char)
+ and a NAME is any other symbol.
+ Contexts where this distinction is not important can use the
+ nonterminal "name", which matches either NAME or TYPENAME. */
+
+%token <sval> STRING
+%token <ssym> NAME DOT_ID OBJECT_RENAMING
+%type <bval> block
+%type <lval> arglist tick_arglist
+
+%type <tval> save_qualifier
+
+%token DOT_ALL
+
+/* Special type cases, put in to allow the parser to distinguish different
+ legal basetypes. */
+%token <lval> LAST REGNAME
+
+%token <ivar> INTERNAL_VARIABLE
+
+%nonassoc ASSIGN
+%left _AND_ OR XOR THEN ELSE
+%left '=' NOTEQUAL '<' '>' LEQ GEQ IN DOTDOT
+%left '@'
+%left '+' '-' '&'
+%left UNARY
+%left '*' '/' MOD REM
+%right STARSTAR ABS NOT
+ /* The following are right-associative only so that reductions at this
+ precedence have lower precedence than '.' and '('. The syntax still
+ forces a.b.c, e.g., to be LEFT-associated. */
+%right TICK_ACCESS TICK_ADDRESS TICK_FIRST TICK_LAST TICK_LENGTH
+%right TICK_MAX TICK_MIN TICK_MODULUS
+%right TICK_POS TICK_RANGE TICK_SIZE TICK_TAG TICK_VAL
+%right '.' '(' '[' DOT_ID DOT_ALL
+
+%token ARROW NEW
+
+
+%%
+
+start : exp1
+ | type { write_exp_elt_opcode (OP_TYPE);
+ write_exp_elt_type ($1);
+ write_exp_elt_opcode (OP_TYPE); }
+ ;
+
+/* Expressions, including the sequencing operator. */
+exp1 : exp
+ | exp1 ';' exp
+ { write_exp_elt_opcode (BINOP_COMMA); }
+ ;
+
+/* Expressions, not including the sequencing operator. */
+simple_exp : simple_exp DOT_ALL
+ { write_exp_elt_opcode (UNOP_IND); }
+ ;
+
+simple_exp : simple_exp DOT_ID
+ { write_exp_elt_opcode (STRUCTOP_STRUCT);
+ write_exp_string ($2.stoken);
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ }
+ ;
+
+simple_exp : simple_exp '(' arglist ')'
+ {
+ write_exp_elt_opcode (OP_FUNCALL);
+ write_exp_elt_longcst ($3);
+ write_exp_elt_opcode (OP_FUNCALL);
+ }
+ ;
+
+simple_exp : type '(' exp ')'
+ {
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type ($1);
+ write_exp_elt_opcode (UNOP_CAST);
+ }
+ ;
+
+simple_exp : type '\'' save_qualifier { type_qualifier = $1; } '(' exp ')'
+ {
+ /* write_exp_elt_opcode (UNOP_QUAL); */
+ /* FIXME: UNOP_QUAL should be defined in expression.h */
+ write_exp_elt_type ($1);
+ /* write_exp_elt_opcode (UNOP_QUAL); */
+ /* FIXME: UNOP_QUAL should be defined in expression.h */
+ type_qualifier = $3;
+ }
+ ;
+
+save_qualifier : { $$ = type_qualifier; }
+
+simple_exp :
+ simple_exp '(' exp DOTDOT exp ')'
+ { write_exp_elt_opcode (TERNOP_SLICE); }
+ ;
+
+simple_exp : '(' exp1 ')' { }
+ ;
+
+simple_exp : variable
+ ;
+
+simple_exp: REGNAME /* GDB extension */
+ { write_exp_elt_opcode (OP_REGISTER);
+ write_exp_elt_longcst ((LONGEST) $1);
+ write_exp_elt_opcode (OP_REGISTER);
+ }
+ ;
+
+simple_exp: INTERNAL_VARIABLE /* GDB extension */
+ { write_exp_elt_opcode (OP_INTERNALVAR);
+ write_exp_elt_intern ($1);
+ write_exp_elt_opcode (OP_INTERNALVAR);
+ }
+ ;
+
+
+exp : simple_exp
+ ;
+
+simple_exp: LAST
+ { write_exp_elt_opcode (OP_LAST);
+ write_exp_elt_longcst ((LONGEST) $1);
+ write_exp_elt_opcode (OP_LAST);
+ }
+ ;
+
+exp : exp ASSIGN exp /* Extension for convenience */
+ { write_exp_elt_opcode (BINOP_ASSIGN); }
+ ;
+
+exp : '-' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_NEG); }
+ ;
+
+exp : '+' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_PLUS); }
+ ;
+
+exp : NOT exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
+ ;
+
+exp : ABS exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_ABS); }
+ ;
+
+arglist : { $$ = 0; }
+ ;
+
+arglist : exp
+ { $$ = 1; }
+ | any_name ARROW exp
+ { $$ = 1; }
+ | arglist ',' exp
+ { $$ = $1 + 1; }
+ | arglist ',' any_name ARROW exp
+ { $$ = $1 + 1; }
+ ;
+
+exp : '{' type '}' exp %prec '.'
+ /* GDB extension */
+ { write_exp_elt_opcode (UNOP_MEMVAL);
+ write_exp_elt_type ($2);
+ write_exp_elt_opcode (UNOP_MEMVAL);
+ }
+ ;
+
+/* Binary operators in order of decreasing precedence. */
+
+exp : exp STARSTAR exp
+ { write_exp_elt_opcode (BINOP_EXP); }
+ ;
+
+exp : exp '*' exp
+ { write_exp_elt_opcode (BINOP_MUL); }
+ ;
+
+exp : exp '/' exp
+ { write_exp_elt_opcode (BINOP_DIV); }
+ ;
+
+exp : exp REM exp /* May need to be fixed to give correct Ada REM */
+ { write_exp_elt_opcode (BINOP_REM); }
+ ;
+
+exp : exp MOD exp
+ { write_exp_elt_opcode (BINOP_MOD); }
+ ;
+
+exp : exp '@' exp /* GDB extension */
+ { write_exp_elt_opcode (BINOP_REPEAT); }
+ ;
+
+exp : exp '+' exp
+ { write_exp_elt_opcode (BINOP_ADD); }
+ ;
+
+exp : exp '&' exp
+ { write_exp_elt_opcode (BINOP_CONCAT); }
+ ;
+
+exp : exp '-' exp
+ { write_exp_elt_opcode (BINOP_SUB); }
+ ;
+
+exp : exp '=' exp
+ { write_exp_elt_opcode (BINOP_EQUAL); }
+ ;
+
+exp : exp NOTEQUAL exp
+ { write_exp_elt_opcode (BINOP_NOTEQUAL); }
+ ;
+
+exp : exp LEQ exp
+ { write_exp_elt_opcode (BINOP_LEQ); }
+ ;
+
+exp : exp IN exp DOTDOT exp
+ { /*write_exp_elt_opcode (TERNOP_MBR); */ }
+ /* FIXME: TERNOP_MBR should be defined in
+ expression.h */
+ | exp IN exp TICK_RANGE tick_arglist
+ { /*write_exp_elt_opcode (BINOP_MBR); */
+ /* FIXME: BINOP_MBR should be defined in expression.h */
+ write_exp_elt_longcst ((LONGEST) $5);
+ /*write_exp_elt_opcode (BINOP_MBR); */
+ }
+ | exp IN TYPENAME %prec TICK_ACCESS
+ { /*write_exp_elt_opcode (UNOP_MBR); */
+ /* FIXME: UNOP_QUAL should be defined in expression.h */
+ write_exp_elt_type ($3);
+ /* write_exp_elt_opcode (UNOP_MBR); */
+ /* FIXME: UNOP_MBR should be defined in expression.h */
+ }
+ | exp NOT IN exp DOTDOT exp
+ { /*write_exp_elt_opcode (TERNOP_MBR); */
+ /* FIXME: TERNOP_MBR should be defined in expression.h */
+ write_exp_elt_opcode (UNOP_LOGICAL_NOT);
+ }
+ | exp NOT IN exp TICK_RANGE tick_arglist
+ { /* write_exp_elt_opcode (BINOP_MBR); */
+ /* FIXME: BINOP_MBR should be defined in expression.h */
+ write_exp_elt_longcst ((LONGEST) $6);
+ /*write_exp_elt_opcode (BINOP_MBR);*/
+ /* FIXME: BINOP_MBR should be defined in expression.h */
+ write_exp_elt_opcode (UNOP_LOGICAL_NOT);
+ }
+ | exp NOT IN TYPENAME %prec TICK_ACCESS
+ { /*write_exp_elt_opcode (UNOP_MBR);*/
+ /* FIXME: UNOP_MBR should be defined in expression.h */
+ write_exp_elt_type ($4);
+ /* write_exp_elt_opcode (UNOP_MBR);*/
+ /* FIXME: UNOP_MBR should be defined in expression.h */
+ write_exp_elt_opcode (UNOP_LOGICAL_NOT);
+ }
+ ;
+
+exp : exp GEQ exp
+ { write_exp_elt_opcode (BINOP_GEQ); }
+ ;
+
+exp : exp '<' exp
+ { write_exp_elt_opcode (BINOP_LESS); }
+ ;
+
+exp : exp '>' exp
+ { write_exp_elt_opcode (BINOP_GTR); }
+ ;
+
+exp : exp _AND_ exp /* Fix for Ada elementwise AND. */
+ { write_exp_elt_opcode (BINOP_BITWISE_AND); }
+ ;
+
+exp : exp _AND_ THEN exp %prec _AND_
+ { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
+ ;
+
+exp : exp OR exp /* Fix for Ada elementwise OR */
+ { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
+ ;
+
+exp : exp OR ELSE exp
+ { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
+ ;
+
+exp : exp XOR exp /* Fix for Ada elementwise XOR */
+ { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
+ ;
+
+simple_exp : simple_exp TICK_ACCESS
+ { write_exp_elt_opcode (UNOP_ADDR); }
+ | simple_exp TICK_ADDRESS
+ { write_exp_elt_opcode (UNOP_ADDR);
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (builtin_type_ada_system_address);
+ write_exp_elt_opcode (UNOP_CAST);
+ }
+ | simple_exp TICK_FIRST tick_arglist
+ { write_attribute_call1 (ATR_FIRST, $3); }
+ | simple_exp TICK_LAST tick_arglist
+ { write_attribute_call1 (ATR_LAST, $3); }
+ | simple_exp TICK_LENGTH tick_arglist
+ { write_attribute_call1 (ATR_LENGTH, $3); }
+ | simple_exp TICK_SIZE
+ { write_attribute_call0 (ATR_SIZE); }
+ | simple_exp TICK_TAG
+ { write_attribute_call0 (ATR_TAG); }
+ | opt_type_prefix TICK_MIN '(' exp ',' exp ')'
+ { write_attribute_calln (ATR_MIN, 2); }
+ | opt_type_prefix TICK_MAX '(' exp ',' exp ')'
+ { write_attribute_calln (ATR_MAX, 2); }
+ | opt_type_prefix TICK_POS '(' exp ')'
+ { write_attribute_calln (ATR_POS, 1); }
+ | type_prefix TICK_FIRST tick_arglist
+ { write_attribute_call1 (ATR_FIRST, $3); }
+ | type_prefix TICK_LAST tick_arglist
+ { write_attribute_call1 (ATR_LAST, $3); }
+ | type_prefix TICK_LENGTH tick_arglist
+ { write_attribute_call1 (ATR_LENGTH, $3); }
+ | type_prefix TICK_VAL '(' exp ')'
+ { write_attribute_calln (ATR_VAL, 1); }
+ | type_prefix TICK_MODULUS
+ { write_attribute_call0 (ATR_MODULUS); }
+ ;
+
+tick_arglist : %prec '('
+ { $$ = 1; }
+ | '(' INT ')'
+ { $$ = $2.val; }
+ ;
+
+type_prefix :
+ TYPENAME
+ { write_exp_elt_opcode (OP_TYPE);
+ write_exp_elt_type ($1);
+ write_exp_elt_opcode (OP_TYPE); }
+ ;
+
+opt_type_prefix :
+ type_prefix
+ | /* EMPTY */
+ { write_exp_elt_opcode (OP_TYPE);
+ write_exp_elt_type (builtin_type_void);
+ write_exp_elt_opcode (OP_TYPE); }
+ ;
+
+
+exp : INT
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type ($1.type);
+ write_exp_elt_longcst ((LONGEST)($1.val));
+ write_exp_elt_opcode (OP_LONG);
+ }
+ ;
+
+exp : CHARLIT
+ { write_exp_elt_opcode (OP_LONG);
+ if (type_qualifier == NULL)
+ write_exp_elt_type ($1.type);
+ else
+ write_exp_elt_type (type_qualifier);
+ write_exp_elt_longcst
+ (convert_char_literal (type_qualifier, $1.val));
+ write_exp_elt_opcode (OP_LONG);
+ }
+
+
+exp : FLOAT
+ { write_exp_elt_opcode (OP_DOUBLE);
+ write_exp_elt_type ($1.type);
+ write_exp_elt_dblcst ($1.dval);
+ write_exp_elt_opcode (OP_DOUBLE);
+ }
+ ;
+
+exp : NULL_PTR
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_int);
+ write_exp_elt_longcst ((LONGEST)(0));
+ write_exp_elt_opcode (OP_LONG);
+ }
+
+exp : STRING
+ { /* Ada strings are converted into array constants
+ a lower bound of 1. Thus, the array upper bound
+ is the string length. */
+ char *sp = $1.ptr; int count;
+ if ($1.length == 0)
+ { /* One dummy character for the type */
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_ada_char);
+ write_exp_elt_longcst ((LONGEST)(0));
+ write_exp_elt_opcode (OP_LONG);
+ }
+ for (count = $1.length; count > 0; count -= 1)
+ {
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_ada_char);
+ write_exp_elt_longcst ((LONGEST)(*sp));
+ sp += 1;
+ write_exp_elt_opcode (OP_LONG);
+ }
+ write_exp_elt_opcode (OP_ARRAY);
+ write_exp_elt_longcst ((LONGEST) 1);
+ write_exp_elt_longcst ((LONGEST) ($1.length));
+ write_exp_elt_opcode (OP_ARRAY);
+ }
+ ;
+
+exp : NEW TYPENAME
+ { error ("NEW not implemented."); }
+ ;
+
+variable: NAME { write_var_from_name (NULL, $1); }
+ | block NAME /* GDB extension */
+ { write_var_from_name ($1, $2); }
+ | OBJECT_RENAMING { write_object_renaming (NULL, $1.sym); }
+ | block OBJECT_RENAMING
+ { write_object_renaming ($1, $2.sym); }
+ ;
+
+any_name : NAME { }
+ | TYPENAME { }
+ | OBJECT_RENAMING { }
+ ;
+
+block : BLOCKNAME /* GDB extension */
+ { $$ = $1; }
+ | block BLOCKNAME /* GDB extension */
+ { $$ = $2; }
+ ;
+
+
+type : TYPENAME { $$ = $1; }
+ | block TYPENAME { $$ = $2; }
+ | TYPENAME TICK_ACCESS
+ { $$ = lookup_pointer_type ($1); }
+ | block TYPENAME TICK_ACCESS
+ { $$ = lookup_pointer_type ($2); }
+ ;
+
+/* Some extensions borrowed from C, for the benefit of those who find they
+ can't get used to Ada notation in GDB. */
+
+exp : '*' exp %prec '.'
+ { write_exp_elt_opcode (UNOP_IND); }
+ | '&' exp %prec '.'
+ { write_exp_elt_opcode (UNOP_ADDR); }
+ | exp '[' exp ']'
+ { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+ ;
+
+%%
+
+/* yylex defined in ada-lex.c: Reads one token, getting characters */
+/* through lexptr. */
+
+/* Remap normal flex interface names (yylex) as well as gratuitiously */
+/* global symbol names, so we can have multiple flex-generated parsers */
+/* in gdb. */
+
+/* (See note above on previous definitions for YACC.) */
+
+#define yy_create_buffer ada_yy_create_buffer
+#define yy_delete_buffer ada_yy_delete_buffer
+#define yy_init_buffer ada_yy_init_buffer
+#define yy_load_buffer_state ada_yy_load_buffer_state
+#define yy_switch_to_buffer ada_yy_switch_to_buffer
+#define yyrestart ada_yyrestart
+#define yytext ada_yytext
+#define yywrap ada_yywrap
+
+/* The following kludge was found necessary to prevent conflicts between */
+/* defs.h and non-standard stdlib.h files. */
+#define qsort __qsort__dummy
+#include "ada-lex.c"
+
+int
+ada_parse ()
+{
+ lexer_init (yyin); /* (Re-)initialize lexer. */
+ left_block_context = NULL;
+ type_qualifier = NULL;
+
+ return _ada_parse ();
+}
+
+void
+yyerror (msg)
+ char *msg;
+{
+ error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
+}
+
+/* The operator name corresponding to operator symbol STRING (adds
+ quotes and maps to lower-case). Destroys the previous contents of
+ the array pointed to by STRING.ptr. Error if STRING does not match
+ a valid Ada operator. Assumes that STRING.ptr points to a
+ null-terminated string and that, if STRING is a valid operator
+ symbol, the array pointed to by STRING.ptr contains at least
+ STRING.length+3 characters. */
+
+static struct stoken
+string_to_operator (string)
+ struct stoken string;
+{
+ int i;
+
+ for (i = 0; ada_opname_table[i].mangled != NULL; i += 1)
+ {
+ if (string.length == strlen (ada_opname_table[i].demangled)-2
+ && strncasecmp (string.ptr, ada_opname_table[i].demangled+1,
+ string.length) == 0)
+ {
+ strncpy (string.ptr, ada_opname_table[i].demangled,
+ string.length+2);
+ string.length += 2;
+ return string;
+ }
+ }
+ error ("Invalid operator symbol `%s'", string.ptr);
+}
+
+/* Emit expression to access an instance of SYM, in block BLOCK (if
+ * non-NULL), and with :: qualification ORIG_LEFT_CONTEXT. */
+static void
+write_var_from_sym (orig_left_context, block, sym)
+ struct block* orig_left_context;
+ struct block* block;
+ struct symbol* sym;
+{
+ if (orig_left_context == NULL && symbol_read_needs_frame (sym))
+ {
+ if (innermost_block == 0 ||
+ contained_in (block, innermost_block))
+ innermost_block = block;
+ }
+
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ /* We want to use the selected frame, not another more inner frame
+ which happens to be in the same block */
+ write_exp_elt_block (NULL);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+}
+
+/* Emit expression to access an instance of NAME. */
+static void
+write_var_from_name (orig_left_context, name)
+ struct block* orig_left_context;
+ struct name_info name;
+{
+ if (name.msym != NULL)
+ {
+ write_exp_msymbol (name.msym,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
+ }
+ else if (name.sym == NULL)
+ {
+ /* Multiple matches: record name and starting block for later
+ resolution by ada_resolve. */
+ /* write_exp_elt_opcode (OP_UNRESOLVED_VALUE); */
+ /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */
+ write_exp_elt_block (name.block);
+ /* write_exp_elt_name (name.stoken.ptr); */
+ /* FIXME: write_exp_elt_name should be defined in defs.h, located in parse.c */
+ /* write_exp_elt_opcode (OP_UNRESOLVED_VALUE); */
+ /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */
+ }
+ else
+ write_var_from_sym (orig_left_context, name.block, name.sym);
+}
+
+/* Write a call on parameterless attribute ATR. */
+
+static void
+write_attribute_call0 (atr)
+ enum ada_attribute atr;
+{
+ /* write_exp_elt_opcode (OP_ATTRIBUTE); */
+ /* FIXME: OP_ATTRIBUTE should be defined in expression.h */
+ write_exp_elt_longcst ((LONGEST) 0);
+ write_exp_elt_longcst ((LONGEST) atr);
+ /* write_exp_elt_opcode (OP_ATTRIBUTE); */
+ /* FIXME: OP_ATTRIBUTE should be defined in expression.h */
+}
+
+/* Write a call on an attribute ATR with one constant integer
+ * parameter. */
+
+static void
+write_attribute_call1 (atr, arg)
+ enum ada_attribute atr;
+ LONGEST arg;
+{
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_int);
+ write_exp_elt_longcst (arg);
+ write_exp_elt_opcode (OP_LONG);
+ /*write_exp_elt_opcode (OP_ATTRIBUTE);*/
+ /* FIXME: OP_ATTRIBUTE should be defined in expression.h */
+ write_exp_elt_longcst ((LONGEST) 1);
+ write_exp_elt_longcst ((LONGEST) atr);
+ /*write_exp_elt_opcode (OP_ATTRIBUTE);*/
+ /* FIXME: OP_ATTRIBUTE should be defined in expression.h */
+}
+
+/* Write a call on an attribute ATR with N parameters, whose code must have
+ * been generated previously. */
+
+static void
+write_attribute_calln (atr, n)
+ enum ada_attribute atr;
+ int n;
+{
+ /*write_exp_elt_opcode (OP_ATTRIBUTE);*/
+ /* FIXME: OP_ATTRIBUTE should be defined in expression.h */
+ write_exp_elt_longcst ((LONGEST) n);
+ write_exp_elt_longcst ((LONGEST) atr);
+ /* write_exp_elt_opcode (OP_ATTRIBUTE);*/
+ /* FIXME: OP_ATTRIBUTE should be defined in expression.h */
+}
+
+/* Emit expression corresponding to the renamed object designated by
+ * the type RENAMING, which must be the referent of an object renaming
+ * type, in the context of ORIG_LEFT_CONTEXT (?). */
+static void
+write_object_renaming (orig_left_context, renaming)
+ struct block* orig_left_context;
+ struct symbol* renaming;
+{
+ const char* qualification = SYMBOL_NAME (renaming);
+ const char* simple_tail;
+ const char* expr = TYPE_FIELD_NAME (SYMBOL_TYPE (renaming), 0);
+ const char* suffix;
+ char* name;
+ struct symbol* sym;
+ enum { SIMPLE_INDEX, LOWER_BOUND, UPPER_BOUND } slice_state;
+
+ /* if orig_left_context is null, then use the currently selected
+ block, otherwise we might fail our symbol lookup below */
+ if (orig_left_context == NULL)
+ orig_left_context = get_selected_block (NULL);
+
+ for (simple_tail = qualification + strlen (qualification);
+ simple_tail != qualification; simple_tail -= 1)
+ {
+ if (*simple_tail == '.')
+ {
+ simple_tail += 1;
+ break;
+ }
+ else if (STREQN (simple_tail, "__", 2))
+ {
+ simple_tail += 2;
+ break;
+ }
+ }
+
+ suffix = strstr (expr, "___XE");
+ if (suffix == NULL)
+ goto BadEncoding;
+
+ name = (char*) malloc (suffix - expr + 1);
+ /* add_name_string_cleanup (name); */
+ /* FIXME: add_name_string_cleanup should be defined in
+ parser-defs.h, implemented in parse.c */
+ strncpy (name, expr, suffix-expr);
+ name[suffix-expr] = '\000';
+ sym = lookup_symbol (name, orig_left_context, VAR_NAMESPACE, 0, NULL);
+ /* if (sym == NULL)
+ error ("Could not find renamed variable: %s", ada_demangle (name));
+ */
+ /* FIXME: ada_demangle should be defined in defs.h, implemented in ada-lang.c */
+ write_var_from_sym (orig_left_context, block_found, sym);
+
+ suffix += 5;
+ slice_state = SIMPLE_INDEX;
+ while (*suffix == 'X')
+ {
+ suffix += 1;
+
+ switch (*suffix) {
+ case 'L':
+ slice_state = LOWER_BOUND;
+ case 'S':
+ suffix += 1;
+ if (isdigit (*suffix))
+ {
+ char* next;
+ long val = strtol (suffix, &next, 10);
+ if (next == suffix)
+ goto BadEncoding;
+ suffix = next;
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_ada_int);
+ write_exp_elt_longcst ((LONGEST) val);
+ write_exp_elt_opcode (OP_LONG);
+ }
+ else
+ {
+ const char* end;
+ char* index_name;
+ int index_len;
+ struct symbol* index_sym;
+
+ end = strchr (suffix, 'X');
+ if (end == NULL)
+ end = suffix + strlen (suffix);
+
+ index_len = simple_tail - qualification + 2 + (suffix - end) + 1;
+ index_name = (char*) malloc (index_len);
+ memset (index_name, '\000', index_len);
+ /* add_name_string_cleanup (index_name);*/
+ /* FIXME: add_name_string_cleanup should be defined in
+ parser-defs.h, implemented in parse.c */
+ strncpy (index_name, qualification, simple_tail - qualification);
+ index_name[simple_tail - qualification] = '\000';
+ strncat (index_name, suffix, suffix-end);
+ suffix = end;
+
+ index_sym =
+ lookup_symbol (index_name, NULL, VAR_NAMESPACE, 0, NULL);
+ if (index_sym == NULL)
+ error ("Could not find %s", index_name);
+ write_var_from_sym (NULL, block_found, sym);
+ }
+ if (slice_state == SIMPLE_INDEX)
+ {
+ write_exp_elt_opcode (OP_FUNCALL);
+ write_exp_elt_longcst ((LONGEST) 1);
+ write_exp_elt_opcode (OP_FUNCALL);
+ }
+ else if (slice_state == LOWER_BOUND)
+ slice_state = UPPER_BOUND;
+ else if (slice_state == UPPER_BOUND)
+ {
+ write_exp_elt_opcode (TERNOP_SLICE);
+ slice_state = SIMPLE_INDEX;
+ }
+ break;
+
+ case 'R':
+ {
+ struct stoken field_name;
+ const char* end;
+ suffix += 1;
+
+ if (slice_state != SIMPLE_INDEX)
+ goto BadEncoding;
+ end = strchr (suffix, 'X');
+ if (end == NULL)
+ end = suffix + strlen (suffix);
+ field_name.length = end - suffix;
+ field_name.ptr = (char*) malloc (end - suffix + 1);
+ strncpy (field_name.ptr, suffix, end - suffix);
+ field_name.ptr[end - suffix] = '\000';
+ suffix = end;
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ write_exp_string (field_name);
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ break;
+ }
+
+ default:
+ goto BadEncoding;
+ }
+ }
+ if (slice_state == SIMPLE_INDEX)
+ return;
+
+ BadEncoding:
+ error ("Internal error in encoding of renaming declaration: %s",
+ SYMBOL_NAME (renaming));
+}
+
+/* Convert the character literal whose ASCII value would be VAL to the
+ appropriate value of type TYPE, if there is a translation.
+ Otherwise return VAL. Hence, in an enumeration type ('A', 'B'),
+ the literal 'A' (VAL == 65), returns 0. */
+static LONGEST
+convert_char_literal (struct type* type, LONGEST val)
+{
+ char name[7];
+ int f;
+
+ if (type == NULL || TYPE_CODE (type) != TYPE_CODE_ENUM)
+ return val;
+ sprintf (name, "QU%02x", (int) val);
+ for (f = 0; f < TYPE_NFIELDS (type); f += 1)
+ {
+ if (STREQ (name, TYPE_FIELD_NAME (type, f)))
+ return TYPE_FIELD_BITPOS (type, f);
+ }
+ return val;
+}
diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h
new file mode 100644
index 00000000000..e5353f8524b
--- /dev/null
+++ b/gdb/ada-lang.h
@@ -0,0 +1,365 @@
+/* Ada language support definitions for GDB, the GNU debugger.
+ Copyright 1992, 1997 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if !defined (ADA_LANG_H)
+#define ADA_LANG_H 1
+
+#include "value.h"
+#include "gdbtypes.h"
+
+/* A macro to reorder the bytes of an address depending on the endiannes
+ of the target */
+#define EXTRACT_ADDRESS(x) ((void *) extract_address (&(x), sizeof (x)))
+/* A macro to reorder the bytes of an int depending on the endiannes
+ of the target */
+#define EXTRACT_INT(x) ((int) extract_signed_integer (&(x), sizeof (x)))
+
+/* Chain of cleanups for arguments of OP_UNRESOLVED_VALUE names. Created in
+ yyparse and freed in ada_resolve. */
+extern struct cleanup* unresolved_names;
+
+/* Corresponding mangled/demangled names and opcodes for Ada user-definable
+ operators. */
+struct ada_opname_map {
+ const char* mangled;
+ const char* demangled;
+ enum exp_opcode op;
+};
+
+/* Table of Ada operators in mangled and demangled forms. */
+/* Defined in ada-lang.c */
+extern const struct ada_opname_map ada_opname_table[];
+
+/* The maximum number of tasks known to the Ada runtime */
+extern const int MAX_NUMBER_OF_KNOWN_TASKS;
+
+/* Identifiers for Ada attributes that need special processing. Be sure
+ to update the table attribute_names in ada-lang.c whenever you change this.
+ */
+
+enum ada_attribute {
+ /* Invalid attribute for error checking. */
+ ATR_INVALID,
+
+ ATR_FIRST,
+ ATR_LAST,
+ ATR_LENGTH,
+ ATR_IMAGE,
+ ATR_IMG,
+ ATR_MAX,
+ ATR_MIN,
+ ATR_MODULUS,
+ ATR_POS,
+ ATR_SIZE,
+ ATR_TAG,
+ ATR_VAL,
+
+ /* Dummy last attribute. */
+ ATR_END
+};
+
+enum task_states {
+ Unactivated,
+ Runnable,
+ Terminated,
+ Activator_Sleep,
+ Acceptor_Sleep,
+ Entry_Caller_Sleep,
+ Async_Select_Sleep,
+ Delay_Sleep,
+ Master_Completion_Sleep,
+ Master_Phase_2_Sleep
+};
+
+extern char *ada_task_states[];
+
+typedef struct {
+ char *P_ARRAY;
+ int *P_BOUNDS;
+} fat_string;
+
+typedef struct entry_call {
+ void *self;
+} *entry_call_link;
+
+struct task_fields
+{
+ int entry_num;
+#if (defined (VXWORKS_TARGET) || !defined (i386)) \
+ && !(defined (VXWORKS_TARGET) && defined (M68K_TARGET))
+ int pad1;
+#endif
+ char state;
+#if (defined (VXWORKS_TARGET) && defined (M68K_TARGET))
+ char pad_8bits;
+#endif
+ void *parent;
+ int priority;
+ int current_priority;
+ fat_string image;
+ entry_call_link call;
+#if (defined (sun) && defined (__SVR4)) && !defined (VXWORKS_TARGET)
+ int pad2;
+ unsigned thread;
+ unsigned lwp;
+#else
+ void *thread;
+ void *lwp;
+#endif
+}
+#if (defined (VXWORKS_TARGET) && defined (M68K_TARGET))
+__attribute__ ((packed))
+#endif
+;
+
+struct task_entry
+{
+ void *task_id;
+ int task_num;
+ int known_tasks_index;
+ struct task_entry *next_task;
+ void *thread;
+ void *lwp;
+ int stack_per;
+};
+
+extern struct type* builtin_type_ada_int;
+extern struct type* builtin_type_ada_short;
+extern struct type* builtin_type_ada_long;
+extern struct type* builtin_type_ada_long_long;
+extern struct type* builtin_type_ada_char;
+extern struct type* builtin_type_ada_float;
+extern struct type* builtin_type_ada_double;
+extern struct type* builtin_type_ada_long_double;
+extern struct type* builtin_type_ada_natural;
+extern struct type* builtin_type_ada_positive;
+extern struct type* builtin_type_ada_system_address;
+
+/* Assuming V points to an array of S objects, make sure that it contains at
+ least M objects, updating V and S as necessary. */
+
+#define GROW_VECT(v, s, m) \
+ if ((s) < (m)) grow_vect ((void**) &(v), &(s), (m), sizeof(*(v)));
+
+extern void grow_vect (void**, size_t*, size_t, int);
+
+extern int ada_parse (void); /* Defined in ada-exp.y */
+
+extern void ada_error (char *); /* Defined in ada-exp.y */
+
+ /* Defined in ada-typeprint.c */
+extern void ada_print_type (struct type*, char*, struct ui_file*, int, int);
+
+extern int ada_val_print (struct type*, char*, int, CORE_ADDR,
+ struct ui_file*, int, int, int, enum val_prettyprint);
+
+extern int ada_value_print (struct value*, struct ui_file*, int,
+ enum val_prettyprint);
+
+ /* Defined in ada-lang.c */
+
+extern struct value* value_from_contents_and_address (struct type*, char*, CORE_ADDR);
+
+extern void ada_emit_char (int, struct ui_file *, int, int);
+
+extern void ada_printchar (int, struct ui_file*);
+
+extern void ada_printstr (struct ui_file*, char *, unsigned int, int, int);
+
+extern void ada_convert_actuals (struct value*, int, struct value**, CORE_ADDR*);
+
+extern struct value* ada_value_subscript (struct value*, int, struct value**);
+
+extern struct type* ada_array_element_type (struct type*, int);
+
+extern int ada_array_arity (struct type*);
+
+struct type* ada_type_of_array (struct value*, int);
+
+extern struct value* ada_coerce_to_simple_array (struct value*);
+
+extern struct value* ada_coerce_to_simple_array_ptr (struct value*);
+
+extern int ada_is_simple_array (struct type*);
+
+extern int ada_is_array_descriptor (struct type*);
+
+extern int ada_is_bogus_array_descriptor (struct type*);
+
+extern struct type* ada_index_type (struct type*, int);
+
+extern struct value* ada_array_bound (struct value*, int, int);
+
+extern int ada_lookup_symbol_list (const char*, struct block*, namespace_enum,
+ struct symbol***, struct block***);
+
+extern char* ada_fold_name (const char*);
+
+extern struct symbol* ada_lookup_symbol (const char*, struct block*, namespace_enum);
+
+extern struct minimal_symbol* ada_lookup_minimal_symbol (const char*);
+
+extern void ada_resolve (struct expression**, struct type*);
+
+extern int ada_resolve_function (struct symbol**, struct block**, int,
+ struct value**, int, const char*, struct type*);
+
+extern void ada_fill_in_ada_prototype (struct symbol*);
+
+extern int user_select_syms (struct symbol**, struct block**, int, int);
+
+extern int get_selections (int*, int, int, int, char*);
+
+extern char* ada_start_decode_line_1 (char*);
+
+extern struct symtabs_and_lines ada_finish_decode_line_1 (char**, struct symtab*, int, char***);
+
+extern int ada_scan_number (const char*, int, LONGEST*, int*);
+
+extern struct type* ada_parent_type (struct type*);
+
+extern int ada_is_ignored_field (struct type*, int);
+
+extern int ada_is_packed_array_type (struct type*);
+
+extern struct value* ada_value_primitive_packed_val (struct value*, char*, long, int,
+ int, struct type*);
+
+extern struct type* ada_coerce_to_simple_array_type (struct type*);
+
+extern int ada_is_character_type (struct type*);
+
+extern int ada_is_string_type (struct type*);
+
+extern int ada_is_tagged_type (struct type*);
+
+extern struct type* ada_tag_type (struct value*);
+
+extern struct value* ada_value_tag (struct value*);
+
+extern int ada_is_parent_field (struct type*, int);
+
+extern int ada_is_wrapper_field (struct type*, int);
+
+extern int ada_is_variant_part (struct type*, int);
+
+extern struct type* ada_variant_discrim_type (struct type*, struct type*);
+
+extern int ada_is_others_clause (struct type*, int);
+
+extern int ada_in_variant (LONGEST, struct type*, int);
+
+extern char* ada_variant_discrim_name (struct type*);
+
+extern struct type* ada_lookup_struct_elt_type (struct type*, char*, int, int*);
+
+extern struct value* ada_value_struct_elt (struct value*, char*, char*);
+
+extern struct value* ada_search_struct_field (char*, struct value*, int, struct type*);
+
+extern int ada_is_aligner_type (struct type*);
+
+extern struct type* ada_aligned_type (struct type*);
+
+extern char* ada_aligned_value_addr (struct type*, char*);
+
+extern const char* ada_attribute_name (int);
+
+extern int ada_is_fixed_point_type (struct type*);
+
+extern DOUBLEST ada_delta (struct type*);
+
+extern DOUBLEST ada_fixed_to_float (struct type *, LONGEST);
+
+extern LONGEST ada_float_to_fixed (struct type*, DOUBLEST);
+
+extern int ada_is_vax_floating_type (struct type*);
+
+extern int ada_vax_float_type_suffix (struct type*);
+
+extern struct value* ada_vax_float_print_function (struct type*);
+
+extern struct type* ada_system_address_type (void);
+
+extern int ada_which_variant_applies (struct type*, struct type*, char*);
+
+extern struct value* ada_to_fixed_value (struct type*, char*, CORE_ADDR, struct value*);
+
+extern struct type* ada_to_fixed_type (struct type*, char*, CORE_ADDR, struct value*);
+
+extern int ada_name_prefix_len (const char*);
+
+extern char* ada_type_name (struct type*);
+
+extern struct type* ada_find_parallel_type (struct type*, const char *suffix);
+
+extern LONGEST get_int_var_value (char*, char*, int* );
+
+extern struct type* ada_find_any_type (const char *name);
+
+extern int ada_prefer_type (struct type*, struct type*);
+
+extern struct type* ada_get_base_type (struct type*);
+
+extern struct type* ada_completed_type (struct type*);
+
+extern char* ada_mangle (const char*);
+
+extern const char* ada_enum_name (const char*);
+
+extern int ada_is_modular_type (struct type*);
+
+extern LONGEST ada_modulus (struct type*);
+
+extern struct value* ada_value_ind (struct value*);
+
+extern void ada_print_scalar (struct type*, LONGEST, struct ui_file*);
+
+extern int ada_is_range_type_name (const char*);
+
+extern const char* ada_renaming_type (struct type*);
+
+extern int ada_is_object_renaming (struct symbol*);
+
+extern const char* ada_simple_renamed_entity (struct symbol*);
+
+extern char* ada_breakpoint_rewrite (char*, int*);
+
+/* Tasking-related: ada-tasks.c */
+
+extern int valid_task_id (int);
+
+extern int get_current_task (void);
+
+extern void init_task_list (void);
+
+extern void* get_self_id (void);
+
+extern int get_current_task (void);
+
+extern int get_entry_number (void*);
+
+extern void ada_report_exception_break (struct breakpoint *);
+
+extern int ada_maybe_exception_partial_symbol (struct partial_symbol* sym);
+
+extern int ada_is_exception_sym (struct symbol* sym);
+
+
+#endif
diff --git a/gdb/ada-lex.c b/gdb/ada-lex.c
new file mode 100644
index 00000000000..9538f76b0cb
--- /dev/null
+++ b/gdb/ada-lex.c
@@ -0,0 +1,3174 @@
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header$
+ * $FreeBSD: src/usr.bin/lex/flex.skl,v 1.4 1999/10/27 07:56:44 obrien Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define YY_USES_REJECT
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 57
+#define YY_END_OF_BUFFER 58
+static yyconst short int yy_acclist[386] =
+ { 0,
+ 58, 56, 57, 1, 56, 57, 1, 57, 15, 56,
+ 57, 53, 56, 57, 41, 56, 57, 56, 57, 43,
+ 56, 57, 44, 56, 57, 41, 56, 57, 42, 56,
+ 57, 41, 56, 57, 41, 56, 57, 41, 56, 57,
+ 4, 56, 57, 4, 56, 57, 41, 56, 57, 41,
+ 56, 57, 41, 56, 57, 41, 56, 57, 50, 56,
+ 57, 47, 56, 57, 47, 56, 57, 47, 56, 57,
+ 47, 56, 57, 47, 56, 57, 47, 56, 57, 47,
+ 56, 57, 47, 56, 57, 47, 56, 57, 47, 56,
+ 57, 1, 56, 57, 56, 57, 16, 56, 57, 53,
+
+ 56, 57, 41, 56, 57, 56, 57, 43, 56, 57,
+ 44, 56, 57, 41, 56, 57, 42, 56, 57, 41,
+ 56, 57, 41, 56, 57, 41, 56, 57, 4, 56,
+ 57, 4, 56, 57, 41, 56, 57, 41, 56, 57,
+ 41, 56, 57, 41, 56, 57, 50, 56, 57, 41,
+ 56, 57, 47, 56, 57, 47, 56, 57, 47, 56,
+ 57, 47, 56, 57, 47, 56, 57, 47, 56, 57,
+ 47, 56, 57, 47, 56, 57, 47, 56, 57, 47,
+ 56, 57, 56, 57, 40, 56, 57, 51, 55, 54,
+ 55, 55, 35, 2, 34, 46, 46, 37, 4, 36,
+
+ 38, 33, 39, 47, 47, 47, 47, 47, 19, 47,
+ 23, 47, 47, 47, 47, 47, 28, 47, 47, 47,
+ 47, 16, 51, 55, 54, 55, 55, 16, 35, 2,
+ 34, 46, 46, 37, 4, 36, 38, 33, 39, 16,
+ 47, 47, 47, 47, 47, 19, 47, 23, 47, 47,
+ 47, 47, 47, 28, 47, 47, 47, 47,16398, 52,
+ 55, 12, 12, 32, 2, 46, 46, 9, 3, 7,
+ 47, 47, 49, 20, 47, 21, 47, 47, 24, 47,
+ 25, 47, 26, 47, 47, 29, 47, 47, 31, 47,
+ 52, 55, 16, 32, 2, 2, 16, 2, 46, 46,
+
+ 9, 3, 7, 47, 16, 47, 49, 20, 47, 21,
+ 47, 47, 24, 47, 25, 47, 26, 47, 47, 29,
+ 47, 47, 31, 47, 8206, 46, 45, 46, 6, 9,
+ 3, 47, 22, 47, 27, 47, 30, 47, 2, 16,
+ 46, 45, 46, 6, 9, 3, 47, 22, 47, 27,
+ 47, 30, 47, 48, 47, 48, 2, 2, 18, 47,
+ 5, 11, 8, 18, 2, 2, 5, 11, 8, 17,
+ 5, 8, 17, 2, 18, 2, 5, 8, 13, 2,
+ 17, 10, 10, 10, 10
+ } ;
+
+static yyconst short int yy_accept[364] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 2, 4, 7,
+ 9, 12, 15, 18, 20, 23, 26, 29, 32, 35,
+ 38, 41, 44, 47, 50, 53, 56, 59, 62, 65,
+ 68, 71, 74, 77, 80, 83, 86, 89, 92, 95,
+ 97, 100, 103, 106, 108, 111, 114, 117, 120, 123,
+ 126, 129, 132, 135, 138, 141, 144, 147, 150, 153,
+ 156, 159, 162, 165, 168, 171, 174, 177, 180, 183,
+ 185, 188, 188, 188, 188, 188, 188, 188, 188, 188,
+ 188, 188, 188, 190, 192, 193, 193, 193, 193, 193,
+ 193, 193, 193, 194, 195, 195, 196, 196, 197, 198,
+
+ 199, 199, 199, 200, 200, 200, 201, 202, 202, 203,
+ 204, 204, 204, 205, 205, 206, 206, 207, 208, 209,
+ 211, 213, 214, 215, 216, 217, 219, 220, 221, 222,
+ 222, 223, 223, 225, 227, 228, 228, 228, 229, 229,
+ 229, 230, 231, 231, 232, 232, 233, 234, 235, 235,
+ 235, 236, 236, 236, 237, 238, 238, 239, 240, 241,
+ 241, 242, 242, 243, 243, 244, 245, 246, 248, 250,
+ 251, 252, 253, 254, 256, 257, 258, 259, 259, 260,
+ 260, 260, 260, 260, 260, 260, 262, 262, 263, 264,
+ 264, 265, 266, 266, 267, 268, 268, 269, 269, 270,
+
+ 271, 271, 272, 272, 272, 272, 273, 274, 276, 278,
+ 279, 281, 283, 285, 286, 288, 289, 291, 293, 293,
+ 294, 295, 296, 298, 299, 299, 300, 301, 301, 302,
+ 302, 303, 304, 304, 305, 305, 305, 305, 306, 306,
+ 307, 308, 310, 312, 313, 315, 317, 319, 320, 322,
+ 323, 325, 325, 326, 326, 326, 326, 326, 327, 329,
+ 330, 330, 330, 331, 331, 332, 332, 332, 332, 332,
+ 332, 332, 332, 332, 332, 332, 332, 332, 333, 335,
+ 337, 339, 339, 339, 339, 339, 341, 341, 342, 344,
+ 345, 345, 345, 346, 346, 347, 347, 347, 347, 348,
+
+ 350, 352, 354, 355, 355, 355, 355, 355, 356, 356,
+ 356, 356, 356, 356, 356, 356, 357, 357, 357, 358,
+ 359, 359, 359, 359, 360, 360, 360, 361, 361, 361,
+ 362, 363, 363, 364, 365, 365, 366, 367, 367, 368,
+ 369, 369, 370, 371, 371, 372, 372, 373, 374, 376,
+ 377, 378, 378, 379, 380, 380, 382, 382, 383, 384,
+ 385, 386, 386
+ } ;
+
+static yyconst int yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 4, 5, 6, 7, 8, 5, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 21, 22, 23,
+ 24, 25, 5, 26, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 36, 36, 39, 40, 41, 42, 36,
+ 36, 43, 44, 45, 46, 36, 47, 48, 36, 36,
+ 27, 5, 28, 5, 29, 5, 30, 31, 32, 33,
+
+ 34, 35, 36, 37, 38, 36, 36, 39, 40, 41,
+ 42, 36, 36, 43, 44, 45, 46, 36, 47, 48,
+ 36, 36, 26, 22, 26, 5, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst int yy_meta[49] =
+ { 0,
+ 1, 2, 3, 4, 5, 6, 7, 8, 5, 9,
+ 5, 5, 5, 5, 5, 5, 10, 5, 11, 11,
+ 9, 5, 12, 13, 14, 5, 5, 5, 15, 16,
+ 16, 16, 16, 16, 16, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17
+ } ;
+
+static yyconst short int yy_base[385] =
+ { 0,
+ 0, 0, 48, 0, 91, 92, 1405, 1771, 1771, 1771,
+ 94, 96, 1771, 142, 1771, 1771, 1391, 1771, 1387, 189,
+ 1378, 188, 194, 1377, 1376, 1374, 1361, 1771, 222, 242,
+ 82, 91, 89, 196, 68, 163, 179, 97, 100, 194,
+ 0, 280, 223, 328, 227, 228, 234, 229, 235, 375,
+ 242, 418, 1335, 243, 463, 247, 251, 252, 254, 510,
+ 168, 1343, 161, 1333, 234, 1331, 1336, 1323, 1316, 0,
+ 558, 1340, 127, 258, 420, 422, 398, 1299, 1285, 1258,
+ 1266, 1257, 411, 413, 0, 605, 1288, 1287, 1286, 1285,
+ 119, 644, 1771, 0, 691, 1771, 0, 0, 1255, 1771,
+
+ 0, 421, 690, 429, 0, 1771, 1771, 1244, 1771, 1771,
+ 608, 696, 1771, 699, 419, 1247, 420, 422, 582, 583,
+ 586, 587, 624, 625, 591, 590, 627, 628, 684, 430,
+ 1771, 705, 653, 1256, 710, 1252, 731, 0, 1254, 750,
+ 710, 798, 1222, 717, 802, 832, 1199, 720, 875, 730,
+ 1189, 732, 892, 733, 795, 924, 796, 797, 1230, 971,
+ 800, 997, 0, 876, 1183, 1191, 1176, 0, 0, 1174,
+ 1151, 1150, 1097, 0, 1095, 1100, 1089, 1096, 805, 1043,
+ 1047, 1043, 1023, 1016, 1010, 439, 808, 883, 1771, 1027,
+ 1041, 0, 971, 0, 952, 736, 864, 614, 799, 0,
+
+ 965, 976, 1046, 1061, 0, 1061, 1771, 714, 717, 858,
+ 774, 789, 859, 1042, 860, 953, 954, 1047, 1086, 1108,
+ 0, 1092, 0, 1094, 1140, 0, 950, 1182, 1091, 1110,
+ 1199, 1210, 0, 1244, 981, 0, 0, 0, 1243, 1273,
+ 890, 0, 0, 949, 0, 0, 0, 943, 0, 935,
+ 0, 1120, 1771, 1188, 900, 1303, 895, 1771, 0, 882,
+ 0, 1098, 1174, 440, 1177, 909, 421, 1048, 1093, 1102,
+ 1169, 846, 818, 814, 822, 779, 792, 1249, 1190, 1191,
+ 1192, 1322, 1228, 750, 1331, 1361, 0, 1106, 0, 1229,
+ 1378, 0, 1325, 1326, 1349, 726, 725, 1410, 0, 0,
+
+ 0, 0, 1771, 722, 839, 713, 644, 1369, 668, 671,
+ 663, 615, 617, 576, 591, 1198, 540, 459, 456, 1440,
+ 1462, 1483, 1458, 1771, 414, 0, 1517, 249, 794, 1238,
+ 237, 258, 1310, 0, 203, 190, 209, 1460, 1477, 1350,
+ 0, 1480, 1771, 131, 1328, 726, 1472, 0, 0, 86,
+ 1516, 1523, 1522, 1385, 835, 0, 1505, 1511, 1527, 1533,
+ 1549, 1771, 1571, 1587, 1592, 1608, 1622, 1639, 1642, 1649,
+ 89, 187, 1656, 1672, 1689, 1701, 1707, 1718, 1720, 1736,
+ 902, 903, 1743, 1754
+ } ;
+
+static yyconst short int yy_def[385] =
+ { 0,
+ 362, 1, 362, 3, 1, 1, 362, 362, 362, 362,
+ 362, 363, 362, 362, 362, 362, 362, 362, 362, 364,
+ 362, 362, 362, 362, 365, 362, 362, 362, 366, 366,
+ 30, 30, 30, 30, 30, 30, 30, 30, 367, 367,
+ 11, 362, 367, 362, 367, 367, 367, 367, 367, 362,
+ 367, 367, 52, 367, 362, 367, 367, 367, 367, 362,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 11,
+ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 363, 363, 363, 71, 71, 71, 86, 362,
+ 86, 86, 362, 368, 364, 362, 369, 370, 370, 362,
+
+ 371, 362, 362, 362, 372, 362, 362, 373, 362, 362,
+ 362, 362, 362, 374, 30, 362, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 367,
+ 362, 367, 42, 42, 42, 44, 44, 86, 137, 137,
+ 367, 375, 50, 367, 55, 145, 146, 367, 367, 367,
+ 52, 367, 149, 367, 367, 362, 367, 367, 376, 367,
+ 367, 362, 60, 367, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 92, 362, 362,
+ 362, 362, 362, 362, 362, 363, 362, 362, 362, 86,
+ 92, 368, 377, 370, 370, 378, 362, 362, 362, 372,
+
+ 373, 362, 374, 362, 379, 380, 362, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 42, 367, 86,
+ 140, 375, 368, 375, 362, 146, 146, 149, 367, 367,
+ 367, 149, 156, 367, 362, 381, 162, 204, 145, 60,
+ 367, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 362, 362, 362, 362, 86, 377, 362, 370, 362,
+ 382, 378, 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 383, 380, 30, 30,
+ 30, 367, 367, 86, 86, 368, 225, 367, 146, 367,
+ 149, 228, 367, 367, 367, 362, 362, 362, 240, 60,
+
+ 60, 60, 362, 86, 362, 384, 362, 362, 362, 362,
+ 362, 362, 362, 362, 383, 367, 86, 86, 368, 368,
+ 367, 149, 367, 362, 362, 298, 367, 86, 362, 362,
+ 362, 384, 362, 86, 86, 368, 368, 367, 367, 367,
+ 322, 367, 362, 86, 362, 362, 362, 86, 368, 368,
+ 367, 367, 367, 362, 362, 368, 367, 362, 367, 362,
+ 367, 0, 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362
+ } ;
+
+static yyconst short int yy_nxt[1820] =
+ { 0,
+ 8, 9, 10, 9, 8, 11, 8, 12, 13, 14,
+ 15, 16, 17, 13, 18, 19, 20, 21, 22, 23,
+ 24, 13, 25, 26, 27, 28, 13, 13, 29, 30,
+ 29, 29, 29, 31, 29, 29, 29, 32, 29, 33,
+ 34, 35, 36, 29, 37, 29, 29, 38, 8, 9,
+ 10, 39, 40, 41, 40, 42, 43, 44, 45, 46,
+ 47, 43, 48, 49, 50, 51, 52, 53, 54, 43,
+ 55, 56, 57, 58, 59, 43, 60, 61, 60, 60,
+ 60, 62, 60, 60, 60, 63, 60, 64, 65, 66,
+ 67, 60, 68, 60, 60, 69, 70, 70, 115, 196,
+
+ 71, 71, 72, 83, 196, 131, 73, 72, 115, 72,
+ 126, 74, 115, 356, 84, 84, 75, 72, 76, 115,
+ 119, 115, 115, 77, 190, 120, 132, 115, 188, 115,
+ 122, 121, 179, 78, 79, 80, 81, 115, 129, 72,
+ 354, 82, 86, 87, 87, 88, 89, 89, 89, 89,
+ 89, 90, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 91, 89,
+ 89, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 95, 95, 95, 115, 101, 168, 127, 200, 165, 131,
+
+ 101, 169, 200, 115, 102, 96, 103, 103, 166, 115,
+ 102, 97, 103, 103, 350, 128, 103, 349, 99, 115,
+ 132, 104, 103, 111, 111, 112, 115, 104, 131, 123,
+ 348, 113, 131, 131, 131, 105, 115, 124, 114, 131,
+ 131, 125, 116, 111, 111, 112, 141, 131, 131, 132,
+ 142, 113, 131, 132, 132, 132, 131, 131, 114, 159,
+ 132, 132, 116, 179, 331, 148, 154, 171, 132, 132,
+ 346, 157, 117, 132, 158, 172, 344, 132, 132, 173,
+ 132, 72, 118, 130, 130, 131, 130, 133, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 134, 134,
+
+ 130, 130, 130, 130, 130, 130, 132, 130, 135, 135,
+ 135, 135, 135, 135, 135, 135, 135, 135, 135, 135,
+ 135, 135, 135, 135, 135, 135, 135, 135, 86, 87,
+ 87, 136, 137, 138, 137, 137, 137, 130, 137, 137,
+ 137, 137, 137, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 137, 139, 137, 137, 140, 140, 140,
+ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+ 140, 140, 140, 140, 140, 140, 95, 95, 143, 130,
+ 131, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 144, 130, 130, 130, 130, 130, 145, 130, 130,
+
+ 130, 132, 130, 146, 147, 146, 146, 146, 146, 146,
+ 146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
+ 146, 146, 146, 131, 149, 179, 308, 179, 180, 186,
+ 186, 84, 84, 266, 150, 131, 151, 151, 181, 197,
+ 197, 343, 198, 72, 132, 72, 151, 199, 199, 115,
+ 115, 152, 115, 307, 209, 307, 132, 186, 186, 115,
+ 115, 336, 115, 208, 335, 153, 130, 130, 131, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 155, 130, 130, 132,
+ 130, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 111, 111, 160, 130, 131, 130, 130, 130, 161,
+ 130, 130, 130, 130, 130, 130, 162, 130, 163, 163,
+ 164, 130, 130, 130, 130, 130, 132, 130, 163, 163,
+ 163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
+ 163, 163, 163, 163, 163, 163, 163, 163, 86, 87,
+ 87, 87, 86, 86, 86, 86, 86, 334, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 178, 178, 178,
+ 178, 178, 178, 178, 178, 178, 178, 178, 178, 178,
+
+ 178, 178, 178, 178, 178, 178, 86, 86, 86, 111,
+ 111, 111, 115, 115, 187, 308, 115, 115, 266, 211,
+ 115, 115, 115, 115, 114, 210, 115, 115, 116, 214,
+ 115, 115, 199, 199, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 188, 115, 115, 266, 115, 115, 266,
+ 135, 216, 333, 333, 115, 115, 215, 115, 115, 213,
+ 212, 218, 218, 191, 191, 191, 191, 191, 191, 191,
+ 191, 191, 191, 191, 191, 191, 191, 191, 191, 191,
+ 191, 191, 95, 95, 95, 266, 101, 111, 111, 112,
+
+ 203, 203, 203, 266, 204, 113, 102, 362, 103, 103,
+ 159, 266, 114, 97, 115, 131, 116, 135, 103, 331,
+ 99, 205, 131, 104, 115, 131, 217, 328, 135, 135,
+ 325, 132, 86, 86, 137, 131, 132, 131, 131, 355,
+ 219, 355, 260, 132, 115, 230, 132, 115, 229, 229,
+ 231, 231, 261, 324, 115, 317, 132, 115, 132, 132,
+ 137, 137, 137, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 137, 137, 137, 137, 137, 137, 221,
+ 221, 221, 221, 221, 221, 221, 221, 221, 221, 221,
+ 221, 221, 221, 221, 221, 221, 221, 221, 192, 192,
+
+ 131, 131, 131, 223, 115, 131, 252, 252, 252, 254,
+ 254, 254, 330, 330, 115, 253, 308, 265, 265, 115,
+ 314, 132, 132, 132, 224, 130, 132, 265, 255, 115,
+ 225, 225, 225, 225, 225, 225, 225, 225, 225, 225,
+ 225, 225, 225, 225, 225, 225, 225, 225, 225, 225,
+ 226, 226, 329, 358, 358, 313, 266, 330, 330, 312,
+ 226, 226, 226, 226, 226, 226, 226, 226, 226, 226,
+ 226, 226, 226, 226, 226, 226, 226, 226, 226, 226,
+ 131, 131, 263, 263, 254, 254, 254, 311, 115, 115,
+ 115, 279, 263, 228, 228, 131, 241, 264, 115, 115,
+
+ 115, 132, 132, 255, 228, 228, 228, 228, 228, 228,
+ 232, 232, 297, 306, 308, 305, 132, 297, 306, 258,
+ 303, 232, 232, 232, 232, 232, 232, 130, 130, 131,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 233, 233, 130, 130, 130, 130, 234, 130,
+ 132, 130, 233, 233, 233, 233, 233, 233, 233, 233,
+ 233, 233, 233, 233, 233, 233, 233, 233, 233, 233,
+ 233, 233, 111, 111, 160, 302, 131, 111, 111, 112,
+ 161, 301, 300, 115, 115, 113, 296, 162, 289, 202,
+ 259, 164, 114, 281, 115, 258, 116, 132, 203, 203,
+
+ 237, 130, 238, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 239,
+ 130, 130, 130, 132, 130, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 256, 256, 203, 203, 203,
+ 187, 204, 72, 308, 135, 72, 256, 256, 256, 256,
+ 256, 256, 111, 111, 112, 218, 218, 72, 205, 266,
+ 113, 266, 115, 267, 266, 72, 266, 114, 268, 72,
+ 280, 116, 115, 269, 266, 270, 72, 254, 254, 282,
+ 271, 131, 192, 192, 192, 192, 131, 223, 308, 286,
+
+ 272, 273, 274, 275, 260, 187, 283, 308, 276, 293,
+ 293, 131, 132, 284, 261, 131, 266, 132, 224, 293,
+ 224, 252, 252, 252, 294, 266, 285, 285, 231, 231,
+ 253, 251, 132, 250, 249, 248, 132, 285, 285, 285,
+ 285, 285, 285, 130, 130, 131, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 287, 287,
+ 130, 130, 130, 130, 288, 130, 132, 130, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287, 290, 254,
+ 254, 254, 263, 263, 247, 265, 265, 246, 291, 309,
+
+ 292, 292, 263, 131, 131, 265, 245, 264, 255, 310,
+ 292, 292, 292, 292, 292, 292, 292, 295, 295, 244,
+ 115, 115, 115, 243, 132, 132, 242, 295, 232, 232,
+ 115, 115, 115, 131, 131, 235, 130, 227, 130, 232,
+ 232, 232, 232, 232, 232, 111, 111, 160, 316, 131,
+ 111, 111, 112, 161, 132, 132, 345, 345, 113, 220,
+ 162, 219, 321, 135, 164, 114, 345, 207, 202, 116,
+ 132, 298, 298, 298, 298, 298, 298, 298, 298, 298,
+ 298, 298, 298, 298, 298, 298, 298, 298, 298, 298,
+ 298, 299, 299, 195, 189, 188, 188, 187, 185, 184,
+
+ 72, 299, 299, 299, 299, 299, 299, 299, 299, 299,
+ 299, 299, 299, 299, 299, 299, 299, 299, 299, 299,
+ 299, 304, 304, 254, 254, 282, 183, 131, 347, 347,
+ 131, 131, 304, 304, 304, 304, 304, 304, 347, 323,
+ 182, 323, 283, 293, 293, 179, 345, 345, 132, 318,
+ 318, 132, 132, 293, 131, 131, 345, 177, 294, 176,
+ 318, 318, 318, 318, 318, 318, 319, 295, 295, 175,
+ 111, 111, 112, 174, 170, 132, 132, 295, 113, 320,
+ 320, 167, 130, 352, 110, 114, 254, 254, 254, 116,
+ 320, 320, 320, 320, 320, 320, 322, 322, 109, 107,
+
+ 106, 100, 94, 93, 362, 255, 362, 322, 322, 322,
+ 322, 322, 322, 130, 130, 131, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 326, 326,
+ 130, 130, 130, 130, 327, 130, 132, 130, 326, 326,
+ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 326, 326, 326, 337, 337,
+ 362, 362, 362, 131, 362, 131, 362, 131, 362, 337,
+ 337, 337, 337, 337, 337, 338, 342, 342, 339, 339,
+ 339, 339, 131, 362, 132, 131, 132, 362, 132, 340,
+ 347, 347, 362, 362, 362, 351, 351, 362, 353, 353,
+
+ 347, 341, 341, 132, 362, 351, 132, 362, 353, 362,
+ 131, 341, 341, 341, 341, 341, 341, 341, 111, 111,
+ 160, 131, 131, 359, 359, 362, 161, 131, 131, 360,
+ 360, 132, 131, 162, 351, 351, 357, 164, 357, 360,
+ 353, 353, 132, 132, 351, 361, 361, 362, 132, 132,
+ 353, 360, 360, 132, 131, 361, 362, 362, 362, 362,
+ 362, 360, 362, 362, 362, 362, 362, 361, 361, 362,
+ 362, 362, 362, 362, 362, 132, 362, 361, 85, 362,
+ 362, 85, 362, 362, 362, 85, 85, 85, 98, 98,
+ 98, 362, 362, 362, 362, 362, 98, 362, 98, 362,
+
+ 362, 98, 98, 98, 108, 362, 108, 108, 108, 115,
+ 115, 115, 362, 362, 362, 362, 115, 115, 115, 362,
+ 362, 362, 115, 115, 115, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 192,
+ 192, 362, 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 193, 193, 193, 194,
+ 362, 362, 362, 194, 194, 194, 201, 362, 362, 201,
+ 201, 201, 201, 206, 206, 206, 362, 206, 362, 362,
+ 362, 362, 362, 206, 362, 362, 206, 206, 206, 222,
+ 222, 362, 222, 222, 222, 222, 222, 222, 222, 222,
+
+ 222, 222, 222, 222, 222, 222, 236, 362, 362, 362,
+ 362, 236, 362, 362, 362, 362, 236, 257, 362, 362,
+ 257, 257, 257, 257, 262, 362, 362, 262, 262, 362,
+ 362, 362, 262, 262, 277, 277, 277, 278, 278, 278,
+ 362, 362, 362, 362, 278, 278, 278, 362, 362, 362,
+ 278, 278, 278, 315, 362, 362, 315, 315, 315, 315,
+ 332, 362, 362, 362, 332, 362, 362, 362, 332, 332,
+ 7, 362, 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
+
+ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362, 362
+ } ;
+
+static yyconst short int yy_chk[1820] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 5, 6, 35, 371,
+
+ 5, 6, 11, 12, 371, 39, 11, 11, 35, 11,
+ 35, 11, 31, 350, 12, 12, 11, 11, 11, 33,
+ 31, 32, 31, 11, 91, 32, 39, 38, 91, 33,
+ 33, 32, 73, 11, 11, 11, 11, 38, 38, 73,
+ 344, 11, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 20, 20, 20, 36, 22, 63, 36, 372, 61, 40,
+
+ 23, 63, 372, 36, 22, 20, 22, 22, 61, 37,
+ 23, 20, 23, 23, 337, 37, 22, 336, 20, 37,
+ 40, 22, 23, 29, 29, 29, 34, 23, 43, 34,
+ 335, 29, 45, 46, 48, 22, 34, 34, 29, 47,
+ 49, 34, 29, 30, 30, 30, 47, 51, 54, 43,
+ 49, 30, 56, 45, 46, 48, 57, 58, 30, 59,
+ 47, 49, 30, 74, 332, 51, 54, 65, 51, 54,
+ 331, 56, 30, 56, 57, 65, 328, 57, 58, 65,
+ 59, 74, 30, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 52, 52, 75, 267, 76, 77, 83,
+ 83, 84, 84, 267, 52, 130, 52, 52, 77, 102,
+ 102, 325, 104, 75, 52, 76, 52, 104, 104, 115,
+ 117, 52, 118, 264, 118, 264, 130, 186, 186, 115,
+ 117, 319, 118, 117, 318, 52, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
+
+ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 317, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+
+ 71, 71, 71, 71, 71, 71, 86, 86, 86, 111,
+ 111, 111, 119, 120, 86, 315, 121, 122, 314, 122,
+ 126, 125, 119, 120, 111, 119, 121, 122, 111, 125,
+ 126, 125, 198, 198, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 92, 123, 124, 313, 127, 128, 312,
+ 133, 128, 307, 307, 123, 124, 127, 127, 128, 124,
+ 123, 133, 133, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 95, 95, 95, 311, 103, 112, 112, 112,
+
+ 114, 114, 114, 310, 114, 112, 103, 95, 103, 103,
+ 132, 309, 112, 95, 129, 141, 112, 135, 103, 306,
+ 95, 114, 144, 103, 129, 148, 129, 304, 135, 135,
+ 297, 132, 137, 137, 137, 150, 141, 152, 154, 346,
+ 137, 346, 196, 144, 208, 152, 148, 209, 150, 150,
+ 152, 152, 196, 296, 208, 284, 150, 209, 152, 154,
+ 137, 137, 137, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 137, 137, 137, 137, 137, 137, 140,
+ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+ 140, 140, 140, 140, 140, 140, 140, 140, 142, 142,
+
+ 155, 157, 158, 142, 211, 161, 179, 179, 179, 187,
+ 187, 187, 329, 329, 211, 179, 277, 199, 199, 212,
+ 276, 155, 157, 158, 142, 145, 161, 199, 187, 212,
+ 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
+ 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
+ 146, 146, 305, 355, 355, 275, 274, 305, 305, 273,
+ 146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
+ 146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
+ 149, 164, 197, 197, 188, 188, 188, 272, 210, 213,
+ 215, 210, 197, 149, 149, 241, 164, 197, 210, 213,
+
+ 215, 149, 164, 188, 149, 149, 149, 149, 149, 149,
+ 153, 153, 381, 382, 266, 260, 241, 381, 382, 257,
+ 255, 153, 153, 153, 153, 153, 153, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 160, 160, 160, 250, 160, 202, 202, 202,
+ 160, 248, 244, 216, 217, 202, 235, 160, 227, 201,
+ 195, 160, 202, 216, 217, 193, 202, 160, 162, 162,
+
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 190, 190, 203, 203, 203,
+ 191, 203, 185, 268, 218, 184, 190, 190, 190, 190,
+ 190, 190, 206, 206, 206, 218, 218, 183, 203, 204,
+ 206, 268, 214, 204, 204, 182, 204, 206, 204, 181,
+ 214, 206, 214, 204, 204, 204, 180, 219, 219, 219,
+ 204, 219, 222, 222, 224, 224, 229, 222, 269, 224,
+
+ 204, 204, 204, 204, 262, 178, 219, 270, 204, 229,
+ 229, 288, 219, 220, 262, 230, 269, 229, 222, 229,
+ 224, 252, 252, 252, 229, 270, 220, 220, 230, 230,
+ 252, 177, 288, 176, 175, 173, 230, 220, 220, 220,
+ 220, 220, 220, 225, 225, 225, 225, 225, 225, 225,
+ 225, 225, 225, 225, 225, 225, 225, 225, 225, 225,
+ 225, 225, 225, 225, 225, 225, 225, 225, 225, 225,
+ 225, 225, 225, 225, 225, 225, 225, 225, 225, 225,
+ 225, 225, 225, 225, 225, 225, 225, 225, 228, 254,
+ 254, 254, 263, 263, 172, 265, 265, 171, 228, 271,
+
+ 228, 228, 263, 316, 231, 265, 170, 263, 254, 271,
+ 228, 228, 228, 228, 228, 228, 228, 231, 231, 167,
+ 279, 280, 281, 166, 316, 231, 165, 231, 232, 232,
+ 279, 280, 281, 283, 290, 159, 151, 147, 143, 232,
+ 232, 232, 232, 232, 232, 234, 234, 234, 283, 234,
+ 278, 278, 278, 234, 283, 290, 330, 330, 278, 139,
+ 234, 136, 290, 134, 234, 278, 330, 116, 108, 278,
+ 234, 239, 239, 239, 239, 239, 239, 239, 239, 239,
+ 239, 239, 239, 239, 239, 239, 239, 239, 239, 239,
+ 239, 240, 240, 99, 90, 89, 88, 87, 82, 81,
+
+ 80, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 256, 256, 282, 282, 282, 79, 282, 333, 333,
+ 293, 294, 256, 256, 256, 256, 256, 256, 333, 294,
+ 78, 294, 282, 293, 293, 72, 345, 345, 282, 285,
+ 285, 293, 294, 293, 295, 340, 345, 69, 293, 68,
+ 285, 285, 285, 285, 285, 285, 286, 295, 295, 67,
+ 308, 308, 308, 66, 64, 295, 340, 295, 308, 286,
+ 286, 62, 53, 340, 27, 308, 354, 354, 354, 308,
+ 286, 286, 286, 286, 286, 286, 291, 291, 26, 25,
+
+ 24, 21, 19, 17, 7, 354, 0, 291, 291, 291,
+ 291, 291, 291, 298, 298, 298, 298, 298, 298, 298,
+ 298, 298, 298, 298, 298, 298, 298, 298, 298, 298,
+ 298, 298, 298, 298, 298, 298, 298, 298, 298, 298,
+ 298, 298, 298, 298, 298, 298, 298, 298, 298, 298,
+ 298, 298, 298, 298, 298, 298, 298, 298, 320, 320,
+ 0, 0, 0, 323, 0, 338, 0, 321, 0, 320,
+ 320, 320, 320, 320, 320, 321, 323, 323, 338, 338,
+ 321, 321, 339, 0, 323, 342, 338, 0, 321, 322,
+ 347, 347, 0, 0, 0, 339, 339, 0, 342, 342,
+
+ 347, 322, 322, 339, 0, 339, 342, 0, 342, 0,
+ 357, 322, 322, 322, 322, 322, 322, 322, 327, 327,
+ 327, 351, 327, 357, 357, 0, 327, 353, 352, 358,
+ 358, 357, 359, 327, 351, 351, 352, 327, 352, 358,
+ 353, 353, 351, 327, 351, 359, 359, 0, 353, 352,
+ 353, 360, 360, 359, 361, 359, 0, 0, 0, 0,
+ 0, 360, 0, 0, 0, 0, 0, 361, 361, 0,
+ 0, 0, 0, 0, 0, 361, 0, 361, 363, 0,
+ 0, 363, 0, 0, 0, 363, 363, 363, 364, 364,
+ 364, 0, 0, 0, 0, 0, 364, 0, 364, 0,
+
+ 0, 364, 364, 364, 365, 0, 365, 365, 365, 366,
+ 366, 366, 0, 0, 0, 0, 366, 366, 366, 0,
+ 0, 0, 366, 366, 366, 367, 367, 367, 367, 367,
+ 367, 367, 367, 367, 367, 367, 367, 367, 367, 368,
+ 368, 0, 368, 368, 368, 368, 368, 368, 368, 368,
+ 368, 368, 368, 368, 368, 368, 369, 369, 369, 370,
+ 0, 0, 0, 370, 370, 370, 373, 0, 0, 373,
+ 373, 373, 373, 374, 374, 374, 0, 374, 0, 0,
+ 0, 0, 0, 374, 0, 0, 374, 374, 374, 375,
+ 375, 0, 375, 375, 375, 375, 375, 375, 375, 375,
+
+ 375, 375, 375, 375, 375, 375, 376, 0, 0, 0,
+ 0, 376, 0, 0, 0, 0, 376, 377, 0, 0,
+ 377, 377, 377, 377, 378, 0, 0, 378, 378, 0,
+ 0, 0, 378, 378, 379, 379, 379, 380, 380, 380,
+ 0, 0, 0, 0, 380, 380, 380, 0, 0, 0,
+ 380, 380, 380, 383, 0, 0, 383, 383, 383, 383,
+ 384, 0, 0, 0, 384, 0, 0, 0, 384, 384,
+ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
+
+ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362, 362
+ } ;
+
+static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;
+static char *yy_full_match;
+static int yy_lp;
+static int yy_looking_for_trail_begin = 0;
+static int yy_full_lp;
+static int *yy_full_state;
+#define YY_TRAILING_MASK 0x2000
+#define YY_TRAILING_HEAD_MASK 0x4000
+#define REJECT \
+{ \
+*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \
+yy_cp = yy_full_match; /* restore poss. backed-over text */ \
+yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \
+yy_state_ptr = yy_full_state; /* restore orig. state */ \
+yy_current_state = *yy_state_ptr; /* restore curr. state */ \
+++yy_lp; \
+goto find_rule; \
+}
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "./ada-lex.l"
+#define INITIAL 0
+/* FLEX lexer for Ada expressions, for GDB.
+ Copyright (C) 1994, 1997, 2000
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+/*----------------------------------------------------------------------*/
+/* The converted version of this file is to be included in ada-exp.y, */
+/* the Ada parser for gdb. The function yylex obtains characters from */
+/* the global pointer lexptr. It returns a syntactic category for */
+/* each successive token and places a semantic value into yylval */
+/* (ada-lval), defined by the parser. */
+/* Run flex with (at least) the -i option (case-insensitive), and the -I */
+/* option (interactive---no unnecessary lookahead). */
+#line 48 "./ada-lex.l"
+#define NUMERAL_WIDTH 256
+#define LONGEST_SIGN ((ULONGEST) 1 << (sizeof(LONGEST) * HOST_CHAR_BIT - 1))
+
+/* Temporary staging for numeric literals. */
+static char numbuf[NUMERAL_WIDTH];
+ static void canonicalizeNumeral (char* s1, const char*);
+static int processInt (const char*, const char*, const char*);
+static int processReal (const char*);
+static int processId (const char*, int);
+static int processAttribute (const char*);
+static int find_dot_all (const char*);
+
+#undef YY_DECL
+#define YY_DECL static int yylex ( void )
+
+#undef YY_INPUT
+#define YY_INPUT(BUF, RESULT, MAX_SIZE) \
+ if ( *lexptr == '\000' ) \
+ (RESULT) = YY_NULL; \
+ else \
+ { \
+ *(BUF) = *lexptr; \
+ (RESULT) = 1; \
+ lexptr += 1; \
+ }
+
+static char *tempbuf = NULL;
+static int tempbufsize = 0;
+static int tempbuf_len;
+static struct block* left_block_context;
+
+static void resize_tempbuf (unsigned int);
+
+static void block_lookup (char*, char*);
+
+static int name_lookup (char*, char*, int*);
+
+static int find_dot_all (const char*);
+
+#define IN_STRING 1
+#define BEFORE_QUAL_QUOTE 2
+
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 91 "./ada-lex.l"
+
+
+
+ if ( yy_init )
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! yy_current_buffer )
+ yy_current_buffer =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+ yy_state_ptr = yy_state_buf;
+ *yy_state_ptr++ = yy_current_state;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 363 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ *yy_state_ptr++ = yy_current_state;
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 1771 );
+
+yy_find_action:
+ yy_current_state = *--yy_state_ptr;
+ yy_lp = yy_accept[yy_current_state];
+find_rule: /* we branch to this label when backing up */
+ for ( ; ; ) /* until we find what rule we matched */
+ {
+ if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )
+ {
+ yy_act = yy_acclist[yy_lp];
+ if ( yy_act & YY_TRAILING_HEAD_MASK ||
+ yy_looking_for_trail_begin )
+ {
+ if ( yy_act == yy_looking_for_trail_begin )
+ {
+ yy_looking_for_trail_begin = 0;
+ yy_act &= ~YY_TRAILING_HEAD_MASK;
+ break;
+ }
+ }
+ else if ( yy_act & YY_TRAILING_MASK )
+ {
+ yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;
+ yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;
+ }
+ else
+ {
+ yy_full_match = yy_cp;
+ yy_full_state = yy_state_ptr;
+ yy_full_lp = yy_lp;
+ break;
+ }
+ ++yy_lp;
+ goto find_rule;
+ }
+ --yy_cp;
+ yy_current_state = *--yy_state_ptr;
+ yy_lp = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+
+do_action: /* This label is used only to access EOF actions. */
+
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+case 1:
+YY_RULE_SETUP
+#line 93 "./ada-lex.l"
+{ }
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 95 "./ada-lex.l"
+{ yyterminate(); }
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 97 "./ada-lex.l"
+{
+ canonicalizeNumeral (numbuf, yytext);
+ return processInt (NULL, numbuf, strrchr(numbuf, 'e')+1);
+ }
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 102 "./ada-lex.l"
+{
+ canonicalizeNumeral (numbuf, yytext);
+ return processInt (NULL, numbuf, NULL);
+ }
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 107 "./ada-lex.l"
+{
+ canonicalizeNumeral (numbuf, yytext);
+ return processInt (numbuf,
+ strchr (numbuf, '#') + 1,
+ strrchr(numbuf, '#') + 1);
+ }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 114 "./ada-lex.l"
+{
+ canonicalizeNumeral (numbuf, yytext);
+ return processInt (numbuf, strchr (numbuf, '#') + 1, NULL);
+ }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 119 "./ada-lex.l"
+{
+ canonicalizeNumeral (numbuf, yytext+2);
+ return processInt ("16#", numbuf, NULL);
+ }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 125 "./ada-lex.l"
+{
+ canonicalizeNumeral (numbuf, yytext);
+ return processReal (numbuf);
+ }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 130 "./ada-lex.l"
+{
+ canonicalizeNumeral (numbuf, yytext);
+ return processReal (numbuf);
+ }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 135 "./ada-lex.l"
+{
+ error ("Based real literals not implemented yet.");
+ }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 139 "./ada-lex.l"
+{
+ error ("Based real literals not implemented yet.");
+ }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 143 "./ada-lex.l"
+{
+ yylval.typed_val.type = builtin_type_ada_char;
+ yylval.typed_val.val = yytext[1];
+ return CHARLIT;
+ }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 149 "./ada-lex.l"
+{
+ int v;
+ yylval.typed_val.type = builtin_type_ada_char;
+ sscanf (yytext+3, "%2x", &v);
+ yylval.typed_val.val = v;
+ return CHARLIT;
+ }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 157 "./ada-lex.l"
+{ return processId (yytext, yyleng); }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 159 "./ada-lex.l"
+{
+ tempbuf_len = 0;
+ BEGIN IN_STRING;
+ }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 164 "./ada-lex.l"
+{
+ resize_tempbuf (yyleng+tempbuf_len);
+ strncpy (tempbuf+tempbuf_len, yytext, yyleng-1);
+ tempbuf_len += yyleng-1;
+ yylval.sval.ptr = tempbuf;
+ yylval.sval.length = tempbuf_len;
+ BEGIN INITIAL;
+ return STRING;
+ }
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 174 "./ada-lex.l"
+{
+ int n;
+ resize_tempbuf (yyleng-5+tempbuf_len+1);
+ strncpy (tempbuf+tempbuf_len, yytext, yyleng-6);
+ sscanf(yytext+yyleng-4, "%2x", &n);
+ tempbuf[yyleng-6+tempbuf_len] = (char) n;
+ tempbuf_len += yyleng-5;
+ }
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 183 "./ada-lex.l"
+{
+ int n;
+ resize_tempbuf (yyleng-4+tempbuf_len+1);
+ strncpy (tempbuf+tempbuf_len, yytext, yyleng-6);
+ tempbuf[yyleng-5+tempbuf_len] = '"';
+ tempbuf_len += yyleng-4;
+ }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 191 "./ada-lex.l"
+{
+ while (*lexptr != 'i' && *lexptr != 'I')
+ lexptr -= 1;
+ yyrestart(NULL);
+ return 0;
+ }
+ YY_BREAK
+/* ADA KEYWORDS */
+case 20:
+YY_RULE_SETUP
+#line 200 "./ada-lex.l"
+{ return ABS; }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 201 "./ada-lex.l"
+{ return _AND_; }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 202 "./ada-lex.l"
+{ return ELSE; }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 203 "./ada-lex.l"
+{ return IN; }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 204 "./ada-lex.l"
+{ return MOD; }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 205 "./ada-lex.l"
+{ return NEW; }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 206 "./ada-lex.l"
+{ return NOT; }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 207 "./ada-lex.l"
+{ return NULL_PTR; }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 208 "./ada-lex.l"
+{ return OR; }
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 209 "./ada-lex.l"
+{ return REM; }
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 210 "./ada-lex.l"
+{ return THEN; }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 211 "./ada-lex.l"
+{ return XOR; }
+ YY_BREAK
+/* ATTRIBUTES */
+case 32:
+YY_RULE_SETUP
+#line 215 "./ada-lex.l"
+{ return processAttribute (yytext+1); }
+ YY_BREAK
+/* PUNCTUATION */
+case 33:
+YY_RULE_SETUP
+#line 219 "./ada-lex.l"
+{ return ARROW; }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 220 "./ada-lex.l"
+{ return DOTDOT; }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 221 "./ada-lex.l"
+{ return STARSTAR; }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 222 "./ada-lex.l"
+{ return ASSIGN; }
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 223 "./ada-lex.l"
+{ return NOTEQUAL; }
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 224 "./ada-lex.l"
+{ return LEQ; }
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 225 "./ada-lex.l"
+{ return GEQ; }
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 227 "./ada-lex.l"
+{ BEGIN INITIAL; return '\''; }
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 229 "./ada-lex.l"
+{ return yytext[0]; }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 231 "./ada-lex.l"
+{ if (paren_depth == 0 && comma_terminates)
+ {
+ lexptr -= 1;
+ yyrestart(NULL);
+ return 0;
+ }
+ else
+ return ',';
+ }
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 241 "./ada-lex.l"
+{ paren_depth += 1; return '('; }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 242 "./ada-lex.l"
+{ if (paren_depth == 0)
+ {
+ lexptr -= 1;
+ yyrestart(NULL);
+ return 0;
+ }
+ else
+ {
+ paren_depth -= 1;
+ return ')';
+ }
+ }
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 255 "./ada-lex.l"
+{ return DOT_ALL; }
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 257 "./ada-lex.l"
+{
+ processId (yytext+1, yyleng-1);
+ return DOT_ID;
+ }
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 262 "./ada-lex.l"
+{
+ int all_posn = find_dot_all (yytext);
+ int token_type, segments, k;
+ int quote_follows;
+
+ if (all_posn == -1 && yytext[yyleng-1] == '\'')
+ {
+ quote_follows = 1;
+ do {
+ yyless (yyleng-1);
+ } while (yytext[yyleng-1] == ' ');
+ }
+ else
+ quote_follows = 0;
+
+ if (all_posn >= 0)
+ yyless (all_posn);
+ processId(yytext, yyleng);
+ segments = name_lookup (ada_mangle (yylval.ssym.stoken.ptr),
+ yylval.ssym.stoken.ptr, &token_type);
+ left_block_context = NULL;
+ for (k = yyleng; segments > 0 && k > 0; k -= 1)
+ {
+ if (yytext[k-1] == '.')
+ segments -= 1;
+ quote_follows = 0;
+ }
+ if (k <= 0)
+ error ("confused by name %s", yytext);
+ yyless (k);
+ if (quote_follows)
+ BEGIN BEFORE_QUAL_QUOTE;
+ return token_type;
+ }
+ YY_BREAK
+/* GDB EXPRESSION CONSTRUCTS */
+case 48:
+YY_RULE_SETUP
+#line 300 "./ada-lex.l"
+{
+ processId(yytext, yyleng-2);
+ block_lookup (yylval.ssym.stoken.ptr, yylval.ssym.stoken.ptr);
+ return BLOCKNAME;
+ }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 306 "./ada-lex.l"
+{
+ processId(yytext, yyleng-2);
+ block_lookup (ada_mangle (yylval.ssym.stoken.ptr),
+ yylval.ssym.stoken.ptr);
+ return BLOCKNAME;
+ }
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 313 "./ada-lex.l"
+{ return yytext[0]; }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 315 "./ada-lex.l"
+{ yylval.lval = -1; return LAST; }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 316 "./ada-lex.l"
+{ yylval.lval = -atoi(yytext+2); return LAST; }
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 317 "./ada-lex.l"
+{ yylval.lval = 0; return LAST; }
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 318 "./ada-lex.l"
+{ yylval.lval = atoi(yytext+1); return LAST; }
+ YY_BREAK
+/* REGISTERS AND GDB CONVENIENCE VARIABLES */
+case 55:
+YY_RULE_SETUP
+#line 323 "./ada-lex.l"
+{
+ int c;
+ for (c = 0; c < NUM_REGS; c++)
+ if (REGISTER_NAME (c) &&
+ strcmp (yytext + 1, REGISTER_NAME (c)) == 0)
+ {
+ yylval.lval = c;
+ return REGNAME;
+ }
+ yylval.sval.ptr = yytext;
+ yylval.sval.length = yyleng;
+ yylval.ivar =
+ lookup_internalvar (copy_name (yylval.sval) + 1);
+ return INTERNAL_VARIABLE;
+ }
+ YY_BREAK
+/* CATCH-ALL ERROR CASE */
+case 56:
+YY_RULE_SETUP
+#line 341 "./ada-lex.l"
+{ error ("Invalid character '%s' in expression.", yytext); }
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 342 "./ada-lex.l"
+YY_FATAL_ERROR( "flex scanner jammed" );
+ YY_BREAK
+ case YY_STATE_EOF(INITIAL):
+ case YY_STATE_EOF(IN_STRING):
+ case YY_STATE_EOF(BEFORE_QUAL_QUOTE):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+ {
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( yy_current_buffer->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset =
+ (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yy_flex_realloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+ yy_state_ptr = yy_state_buf;
+ *yy_state_ptr++ = yy_current_state;
+
+ for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 363 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ *yy_state_ptr++ = yy_current_state;
+ }
+
+ return yy_current_state;
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+ {
+ register int yy_is_jam;
+
+ register YY_CHAR yy_c = 1;
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 363 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 362);
+ if ( ! yy_is_jam )
+ *yy_state_ptr++ = yy_current_state;
+
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+ {
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[
+ yy_current_buffer->yy_buf_size + 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+ }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /* fall through */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ return EOF;
+
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+
+ return c;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! yy_current_buffer )
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( ! b )
+ return;
+
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yy_flex_free( (void *) b->yy_ch_buf );
+
+ yy_flex_free( (void *) b );
+ }
+
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+ {
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == yy_current_buffer )
+ yy_load_buffer_state();
+ }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+ {
+ int len;
+ for ( len = 0; yy_str[len]; ++len )
+ ;
+
+ return yy_scan_bytes( yy_str, len );
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( yy_start_stack_ptr >= yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof( int );
+
+ if ( ! yy_start_stack )
+ yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size );
+
+ if ( ! yy_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+ {
+ if ( --yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+ }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+ {
+ return yy_start_stack[yy_start_stack_ptr - 1];
+ }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+ }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+ {
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+ {
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+
+#if YY_MAIN
+int main()
+ {
+ yylex();
+ return 0;
+ }
+#endif
+#line 342 "./ada-lex.l"
+
+
+#include <ctype.h>
+#include <string.h>
+
+/* Initialize the lexer for processing new expression */
+void
+lexer_init (FILE* inp)
+{
+ BEGIN INITIAL;
+ yyrestart (inp);
+}
+
+
+/* Make sure that tempbuf points at an array at least N characters long. */
+
+static void
+resize_tempbuf (n)
+ unsigned int n;
+{
+ if (tempbufsize < n)
+ {
+ tempbufsize = (n+63) & ~63;
+ tempbuf = (char*) xrealloc (tempbuf, tempbufsize);
+ }
+}
+
+/* Copy S2 to S1, removing all underscores, and downcasing all letters. */
+
+static void
+canonicalizeNumeral (s1,s2)
+ char* s1;
+ const char* s2;
+{
+ for (; *s2 != '\000'; s2 += 1)
+ {
+ if (*s2 != '_')
+ {
+ *s1 = tolower(*s2);
+ s1 += 1;
+ }
+ }
+ s1[0] = '\000';
+}
+
+#define HIGH_BYTE_POSN ((sizeof (ULONGEST) - 1) * HOST_CHAR_BIT)
+
+/* True (non-zero) iff DIGIT is a valid digit in radix BASE,
+ where 2 <= BASE <= 16. */
+
+static int
+is_digit_in_base (digit, base)
+ unsigned char digit;
+ int base;
+{
+ if (!isxdigit (digit))
+ return 0;
+ if (base <= 10)
+ return (isdigit (digit) && digit < base + '0');
+ else
+ return (isdigit (digit) || tolower (digit) < base - 10 + 'a');
+}
+
+static int
+digit_to_int (c)
+ unsigned char c;
+{
+ if (isdigit (c))
+ return c - '0';
+ else
+ return tolower (c) - 'a' + 10;
+}
+
+/* As for strtoul, but for ULONGEST results. */
+ULONGEST
+strtoulst (num, trailer, base)
+ const char *num;
+ const char **trailer;
+ int base;
+{
+ unsigned int high_part;
+ ULONGEST result;
+ int i;
+ unsigned char lim;
+
+ if (base < 2 || base > 16)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+ lim = base - 1 + '0';
+
+ result = high_part = 0;
+ for (i = 0; is_digit_in_base (num[i], base); i += 1)
+ {
+ result = result*base + digit_to_int (num[i]);
+ high_part = high_part*base + (unsigned int) (result >> HIGH_BYTE_POSN);
+ result &= ((ULONGEST) 1 << HIGH_BYTE_POSN) - 1;
+ if (high_part > 0xff)
+ {
+ errno = ERANGE;
+ result = high_part = 0;
+ break;
+ }
+ }
+
+ if (trailer != NULL)
+ *trailer = &num[i];
+
+ return result + ((ULONGEST) high_part << HIGH_BYTE_POSN);
+}
+
+
+
+/* Interprets the prefix of NUM that consists of digits of the given BASE
+ as an integer of that BASE, with the string EXP as an exponent.
+ Puts value in yylval, and returns INT, if the string is valid. Causes
+ an error if the number is improperly formated. BASE, if NULL, defaults
+ to "10", and EXP to "1". The EXP does not contain a leading 'e' or 'E'. */
+
+static int
+processInt (base0, num0, exp0)
+ const char* num0;
+ const char* base0;
+ const char* exp0;
+{
+ ULONGEST result;
+ long exp;
+ int base;
+
+ char* trailer;
+
+ if (base0 == NULL)
+ base = 10;
+ else
+ {
+ base = strtol (base0, (char**) NULL, 10);
+ if (base < 2 || base > 16)
+ error ("Invalid base: %d.", base);
+ }
+
+ if (exp0 == NULL)
+ exp = 0;
+ else
+ exp = strtol(exp0, (char**) NULL, 10);
+
+ errno = 0;
+ result = strtoulst (num0, &trailer, base);
+ if (errno == ERANGE)
+ error ("Integer literal out of range");
+ if (isxdigit(*trailer))
+ error ("Invalid digit `%c' in based literal", *trailer);
+
+ while (exp > 0)
+ {
+ if (result > (ULONG_MAX / base))
+ error ("Integer literal out of range");
+ result *= base;
+ exp -= 1;
+ }
+
+ if ((result >> (TARGET_INT_BIT-1)) == 0)
+ yylval.typed_val.type = builtin_type_ada_int;
+ else if ((result >> (TARGET_LONG_BIT-1)) == 0)
+ yylval.typed_val.type = builtin_type_ada_long;
+ else if (((result >> (TARGET_LONG_BIT-1)) >> 1) == 0)
+ {
+ /* We have a number representable as an unsigned integer quantity.
+ For consistency with the C treatment, we will treat it as an
+ anonymous modular (unsigned) quantity. Alas, the types are such
+ that we need to store .val as a signed quantity. Sorry
+ for the mess, but C doesn't officially guarantee that a simple
+ assignment does the trick (no, it doesn't; read the reference manual).
+ */
+ yylval.typed_val.type = builtin_type_unsigned_long;
+ if (result & LONGEST_SIGN)
+ yylval.typed_val.val =
+ (LONGEST) (result & ~LONGEST_SIGN)
+ - (LONGEST_SIGN>>1) - (LONGEST_SIGN>>1);
+ else
+ yylval.typed_val.val = (LONGEST) result;
+ return INT;
+ }
+ else
+ yylval.typed_val.type = builtin_type_ada_long_long;
+
+ yylval.typed_val.val = (LONGEST) result;
+ return INT;
+}
+
+static int
+processReal (num0)
+ const char* num0;
+{
+ if (sizeof (DOUBLEST) <= sizeof (float))
+ sscanf (num0, "%g", &yylval.typed_val_float.dval);
+ else if (sizeof (DOUBLEST) <= sizeof (double))
+ sscanf (num0, "%lg", &yylval.typed_val_float.dval);
+ else
+ {
+#ifdef PRINTF_HAS_LONG_DOUBLE
+ sscanf (num0, "%Lg", &yylval.typed_val_float.dval);
+#else
+ /* Scan it into a double, then convert and assign it to the
+ long double. This at least wins with values representable
+ in the range of doubles. */
+ double temp;
+ sscanf (num0, "%lg", &temp);
+ yylval.typed_val_float.dval = temp;
+#endif
+ }
+
+ yylval.typed_val_float.type = builtin_type_ada_float;
+ if (sizeof(DOUBLEST) >= TARGET_DOUBLE_BIT / TARGET_CHAR_BIT)
+ yylval.typed_val_float.type = builtin_type_ada_double;
+ if (sizeof(DOUBLEST) >= TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT)
+ yylval.typed_val_float.type = builtin_type_ada_long_double;
+
+ return FLOAT;
+}
+
+static int
+processId (name0, len)
+ const char *name0;
+ int len;
+{
+ char* name = xmalloc (len + 11);
+ int i0, i;
+
+/* add_name_string_cleanup (name); */
+/* FIXME: add_name_string_cleanup should be defined in parse.c */
+ while (len > 0 && isspace (name0[len-1]))
+ len -= 1;
+ i = i0 = 0;
+ while (i0 < len)
+ {
+ if (isalnum (name0[i0]))
+ {
+ name[i] = tolower (name0[i0]);
+ i += 1; i0 += 1;
+ }
+ else switch (name0[i0])
+ {
+ default:
+ name[i] = name0[i0];
+ i += 1; i0 += 1;
+ break;
+ case ' ': case '\t':
+ i0 += 1;
+ break;
+ case '\'':
+ i0 += 1;
+ while (i0 < len && name0[i0] != '\'')
+ {
+ name[i] = name0[i0];
+ i += 1; i0 += 1;
+ }
+ i0 += 1;
+ break;
+ case '<':
+ i0 += 1;
+ while (i0 < len && name0[i0] != '>')
+ {
+ name[i] = name0[i0];
+ i += 1; i0 += 1;
+ }
+ i0 += 1;
+ break;
+ }
+ }
+ name[i] = '\000';
+
+ yylval.ssym.sym = NULL;
+ yylval.ssym.stoken.ptr = name;
+ yylval.ssym.stoken.length = i;
+ return NAME;
+}
+
+static void
+block_lookup (name, err_name)
+ char* name;
+ char* err_name;
+{
+ struct symbol** syms;
+ struct block** blocks;
+ int nsyms;
+ struct symtab *symtab;
+ nsyms = ada_lookup_symbol_list (name, left_block_context,
+ VAR_NAMESPACE, &syms, &blocks);
+ if (left_block_context == NULL &&
+ (nsyms == 0 || SYMBOL_CLASS (syms[0]) != LOC_BLOCK))
+ symtab = lookup_symtab (name);
+ else
+ symtab = NULL;
+
+ if (symtab != NULL)
+ left_block_context = yylval.bval =
+ BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
+ else if (nsyms == 0 || SYMBOL_CLASS (syms[0]) != LOC_BLOCK)
+ {
+ if (left_block_context == NULL)
+ error ("No file or function \"%s\".", err_name);
+ else
+ error ("No function \"%s\" in specified context.", err_name);
+ }
+ else
+ {
+ left_block_context = yylval.bval = SYMBOL_BLOCK_VALUE (syms[0]);
+ if (nsyms > 1)
+ warning ("Function name \"%s\" ambiguous here", err_name);
+ }
+}
+
+/* Look up NAME0 (assumed to be mangled) as a name in VAR_NAMESPACE,
+ setting *TOKEN_TYPE to NAME or TYPENAME, depending on what is
+ found. Try first the entire name, then the name without the last
+ segment (i.e., after the last .id), etc., and return the number of
+ segments that had to be removed to get a match. Calls error if no
+ matches are found, using ERR_NAME in any error message. When
+ exactly one symbol match is found, it is placed in yylval. */
+
+static int
+name_lookup (name0, err_name, token_type)
+ char* name0;
+ char* err_name;
+ int* token_type;
+{
+ struct symbol** syms;
+ struct block** blocks;
+ struct type* type;
+ int len0 = strlen (name0);
+ char* name = savestring (name0, len0);
+ int nsyms;
+ int segments;
+
+/* add_name_string_cleanup (name);*/
+/* FIXME: add_name_string_cleanup should be defined in parse.c */
+ yylval.ssym.stoken.ptr = name;
+ yylval.ssym.stoken.length = strlen (name);
+ for (segments = 0; ; segments += 1)
+ {
+ struct type* preferred_type;
+ int i, preferred_index;
+
+ if (left_block_context == NULL)
+ nsyms = ada_lookup_symbol_list (name, expression_context_block,
+ VAR_NAMESPACE, &syms, &blocks);
+ else
+ nsyms = ada_lookup_symbol_list (name, left_block_context,
+ VAR_NAMESPACE, &syms, &blocks);
+
+ /* Check for a type definition. */
+
+ /* Look for a symbol that doesn't denote void. This is (I think) a */
+ /* temporary kludge to get around problems in GNAT output. */
+ preferred_index = -1; preferred_type = NULL;
+ for (i = 0; i < nsyms; i += 1)
+ switch (SYMBOL_CLASS (syms[i]))
+ {
+ case LOC_TYPEDEF:
+ if (ada_prefer_type (SYMBOL_TYPE (syms[i]), preferred_type))
+ {
+ preferred_index = i;
+ preferred_type = SYMBOL_TYPE (syms[i]);
+ }
+ break;
+ case LOC_REGISTER:
+ case LOC_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_LOCAL:
+ case LOC_LOCAL_ARG:
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
+ goto NotType;
+ default:
+ break;
+ }
+ if (preferred_type != NULL)
+ {
+/* if (TYPE_CODE (preferred_type) == TYPE_CODE_VOID)
+ error ("`%s' matches only void type name(s)",
+ ada_demangle (name));
+*/
+/* FIXME: ada_demangle should be defined in defs.h, and is located in ada-lang.c */
+/* else*/ if (ada_is_object_renaming (syms[preferred_index]))
+ {
+ yylval.ssym.sym = syms[preferred_index];
+ *token_type = OBJECT_RENAMING;
+ return segments;
+ }
+ else if (ada_renaming_type (SYMBOL_TYPE (syms[preferred_index]))
+ != NULL)
+ {
+ int result;
+ const char* renaming =
+ ada_simple_renamed_entity (syms[preferred_index]);
+ char* new_name = xmalloc (strlen (renaming) + len0
+ - yylval.ssym.stoken.length + 1);
+/* add_name_string_cleanup (new_name);*/
+/* FIXME: add_name_string_cleanup should be defined in parse.c */
+ strcpy (new_name, renaming);
+ strcat (new_name, name0 + yylval.ssym.stoken.length);
+ result = name_lookup (new_name, err_name, token_type);
+ if (result > segments)
+ error ("Confused by renamed symbol.");
+ return result;
+ }
+ else if (segments == 0)
+ {
+ yylval.tval = preferred_type;
+ *token_type = TYPENAME;
+ return 0;
+ }
+ }
+
+ if (segments == 0)
+ {
+ type = lookup_primitive_typename (name);
+ if (type == NULL && STREQ ("system__address", name))
+ type = builtin_type_ada_system_address;
+ if (type != NULL)
+ {
+ yylval.tval = type;
+ *token_type = TYPENAME;
+ return 0;
+ }
+ }
+
+ NotType:
+ if (nsyms == 1)
+ {
+ *token_type = NAME;
+ yylval.ssym.sym = syms[0];
+ yylval.ssym.msym = NULL;
+ yylval.ssym.block = blocks[0];
+ return segments;
+ }
+ else if (nsyms == 0) {
+ int i;
+ yylval.ssym.msym = ada_lookup_minimal_symbol (name);
+ if (yylval.ssym.msym != NULL)
+ {
+ yylval.ssym.sym = NULL;
+ yylval.ssym.block = NULL;
+ *token_type = NAME;
+ return segments;
+ }
+
+ for (i = yylval.ssym.stoken.length - 1; i > 0; i -= 1)
+ {
+ if (name[i] == '.')
+ {
+ name[i] = '\0';
+ yylval.ssym.stoken.length = i;
+ break;
+ }
+ else if (name[i] == '_' && name[i-1] == '_')
+ {
+ i -= 1;
+ name[i] = '\0';
+ yylval.ssym.stoken.length = i;
+ break;
+ }
+ }
+ if (i <= 0)
+ {
+ if (!have_full_symbols () && !have_partial_symbols ()
+ && left_block_context == NULL)
+ error ("No symbol table is loaded. Use the \"file\" command.");
+ if (left_block_context == NULL)
+ error ("No definition of \"%s\" in current context.",
+ err_name);
+ else
+ error ("No definition of \"%s\" in specified context.",
+ err_name);
+ }
+ }
+ else
+ {
+ *token_type = NAME;
+ yylval.ssym.sym = NULL;
+ yylval.ssym.msym = NULL;
+ if (left_block_context == NULL)
+ yylval.ssym.block = expression_context_block;
+ else
+ yylval.ssym.block = left_block_context;
+ return segments;
+ }
+ }
+}
+
+/* Returns the position within STR of the '.' in a
+ '.{WHITE}*all' component of a dotted name, or -1 if there is none. */
+static int
+find_dot_all (str)
+ const char* str;
+{
+ int i;
+ for (i = 0; str[i] != '\000'; i += 1)
+ {
+ if (str[i] == '.')
+ {
+ int i0 = i;
+ do
+ i += 1;
+ while (isspace (str[i]));
+ if (strcmp (str+i, "all") == 0
+ && ! isalnum (str[i+3]) && str[i+3] != '_')
+ return i0;
+ }
+ }
+ return -1;
+}
+
+/* Returns non-zero iff string SUBSEQ matches a subsequence of STR, ignoring
+ case. */
+
+static int
+subseqMatch (subseq, str)
+ const char* subseq;
+ const char* str;
+{
+ if (subseq[0] == '\0')
+ return 1;
+ else if (str[0] == '\0')
+ return 0;
+ else if (tolower (subseq[0]) == tolower (str[0]))
+ return subseqMatch (subseq+1, str+1) || subseqMatch (subseq, str+1);
+ else
+ return subseqMatch (subseq, str+1);
+}
+
+
+static struct { const char* name; int code; }
+attributes[] = {
+ { "address", TICK_ADDRESS },
+ { "unchecked_access", TICK_ACCESS },
+ { "unrestricted_access", TICK_ACCESS },
+ { "access", TICK_ACCESS },
+ { "first", TICK_FIRST },
+ { "last", TICK_LAST },
+ { "length", TICK_LENGTH },
+ { "max", TICK_MAX },
+ { "min", TICK_MIN },
+ { "modulus", TICK_MODULUS },
+ { "pos", TICK_POS },
+ { "range", TICK_RANGE },
+ { "size", TICK_SIZE },
+ { "tag", TICK_TAG },
+ { "val", TICK_VAL },
+ { NULL, -1 }
+};
+
+/* Return the syntactic code corresponding to the attribute name or
+ abbreviation STR. */
+
+static int
+processAttribute (str)
+ const char* str;
+{
+ int i, k;
+
+ for (i = 0; attributes[i].code != -1; i += 1)
+ if (strcasecmp (str, attributes[i].name) == 0)
+ return attributes[i].code;
+
+ for (i = 0, k = -1; attributes[i].code != -1; i += 1)
+ if (subseqMatch (str, attributes[i].name))
+ {
+ if (k == -1)
+ k = i;
+ else
+ error ("ambiguous attribute name: `%s'", str);
+ }
+ if (k == -1)
+ error ("unrecognized attribute: `%s'", str);
+
+ return attributes[k].code;
+}
+
+int
+yywrap()
+{
+ return 1;
+}
diff --git a/gdb/ada-lex.l b/gdb/ada-lex.l
new file mode 100644
index 00000000000..2252d526a52
--- /dev/null
+++ b/gdb/ada-lex.l
@@ -0,0 +1,928 @@
+/* FLEX lexer for Ada expressions, for GDB.
+ Copyright (C) 1994, 1997, 2000
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/*----------------------------------------------------------------------*/
+
+/* The converted version of this file is to be included in ada-exp.y, */
+/* the Ada parser for gdb. The function yylex obtains characters from */
+/* the global pointer lexptr. It returns a syntactic category for */
+/* each successive token and places a semantic value into yylval */
+/* (ada-lval), defined by the parser. */
+
+/* Run flex with (at least) the -i option (case-insensitive), and the -I */
+/* option (interactive---no unnecessary lookahead). */
+
+DIG [0-9]
+NUM10 ({DIG}({DIG}|_)*)
+HEXDIG [0-9a-f]
+NUM16 ({HEXDIG}({HEXDIG}|_)*)
+OCTDIG [0-7]
+LETTER [a-z_]
+ID ({LETTER}({LETTER}|{DIG})*|"<"{LETTER}({LETTER}|{DIG})*">")
+WHITE [ \t\n]
+TICK ("'"{WHITE}*)
+GRAPHIC [a-z0-9 #&'()*+,-./:;<>=_|!$%?@\[\]\\^`{}~]
+OPER ([-+*/=<>&]|"<="|">="|"**"|"/="|"and"|"or"|"xor"|"not"|"mod"|"rem"|"abs")
+
+EXP (e[+-]{NUM10})
+POSEXP (e"+"?{NUM10})
+
+%{
+#define NUMERAL_WIDTH 256
+#define LONGEST_SIGN ((ULONGEST) 1 << (sizeof(LONGEST) * HOST_CHAR_BIT - 1))
+
+/* Temporary staging for numeric literals. */
+static char numbuf[NUMERAL_WIDTH];
+ static void canonicalizeNumeral (char* s1, const char*);
+static int processInt (const char*, const char*, const char*);
+static int processReal (const char*);
+static int processId (const char*, int);
+static int processAttribute (const char*);
+static int find_dot_all (const char*);
+
+#undef YY_DECL
+#define YY_DECL static int yylex ( void )
+
+#undef YY_INPUT
+#define YY_INPUT(BUF, RESULT, MAX_SIZE) \
+ if ( *lexptr == '\000' ) \
+ (RESULT) = YY_NULL; \
+ else \
+ { \
+ *(BUF) = *lexptr; \
+ (RESULT) = 1; \
+ lexptr += 1; \
+ }
+
+static char *tempbuf = NULL;
+static int tempbufsize = 0;
+static int tempbuf_len;
+static struct block* left_block_context;
+
+static void resize_tempbuf (unsigned int);
+
+static void block_lookup (char*, char*);
+
+static int name_lookup (char*, char*, int*);
+
+static int find_dot_all (const char*);
+
+%}
+
+%s IN_STRING BEFORE_QUAL_QUOTE
+
+%%
+
+{WHITE} { }
+
+"--".* { yyterminate(); }
+
+{NUM10}{POSEXP} {
+ canonicalizeNumeral (numbuf, yytext);
+ return processInt (NULL, numbuf, strrchr(numbuf, 'e')+1);
+ }
+
+{NUM10} {
+ canonicalizeNumeral (numbuf, yytext);
+ return processInt (NULL, numbuf, NULL);
+ }
+
+{NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#"{POSEXP} {
+ canonicalizeNumeral (numbuf, yytext);
+ return processInt (numbuf,
+ strchr (numbuf, '#') + 1,
+ strrchr(numbuf, '#') + 1);
+ }
+
+{NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#" {
+ canonicalizeNumeral (numbuf, yytext);
+ return processInt (numbuf, strchr (numbuf, '#') + 1, NULL);
+ }
+
+"0x"{HEXDIG}+ {
+ canonicalizeNumeral (numbuf, yytext+2);
+ return processInt ("16#", numbuf, NULL);
+ }
+
+
+{NUM10}"."{NUM10}{EXP} {
+ canonicalizeNumeral (numbuf, yytext);
+ return processReal (numbuf);
+ }
+
+{NUM10}"."{NUM10} {
+ canonicalizeNumeral (numbuf, yytext);
+ return processReal (numbuf);
+ }
+
+{NUM10}"#"{NUM16}"."{NUM16}"#"{EXP} {
+ error ("Based real literals not implemented yet.");
+ }
+
+{NUM10}"#"{NUM16}"."{NUM16}"#" {
+ error ("Based real literals not implemented yet.");
+ }
+
+<INITIAL>"'"({GRAPHIC}|\")"'" {
+ yylval.typed_val.type = builtin_type_ada_char;
+ yylval.typed_val.val = yytext[1];
+ return CHARLIT;
+ }
+
+<INITIAL>"'[\""{HEXDIG}{2}"\"]'" {
+ int v;
+ yylval.typed_val.type = builtin_type_ada_char;
+ sscanf (yytext+3, "%2x", &v);
+ yylval.typed_val.val = v;
+ return CHARLIT;
+ }
+
+\"{OPER}\"/{WHITE}*"(" { return processId (yytext, yyleng); }
+
+<INITIAL>\" {
+ tempbuf_len = 0;
+ BEGIN IN_STRING;
+ }
+
+<IN_STRING>{GRAPHIC}*\" {
+ resize_tempbuf (yyleng+tempbuf_len);
+ strncpy (tempbuf+tempbuf_len, yytext, yyleng-1);
+ tempbuf_len += yyleng-1;
+ yylval.sval.ptr = tempbuf;
+ yylval.sval.length = tempbuf_len;
+ BEGIN INITIAL;
+ return STRING;
+ }
+
+<IN_STRING>{GRAPHIC}*"[\""{HEXDIG}{2}"\"]" {
+ int n;
+ resize_tempbuf (yyleng-5+tempbuf_len+1);
+ strncpy (tempbuf+tempbuf_len, yytext, yyleng-6);
+ sscanf(yytext+yyleng-4, "%2x", &n);
+ tempbuf[yyleng-6+tempbuf_len] = (char) n;
+ tempbuf_len += yyleng-5;
+ }
+
+<IN_STRING>{GRAPHIC}*"[\"\"\"]" {
+ int n;
+ resize_tempbuf (yyleng-4+tempbuf_len+1);
+ strncpy (tempbuf+tempbuf_len, yytext, yyleng-6);
+ tempbuf[yyleng-5+tempbuf_len] = '"';
+ tempbuf_len += yyleng-4;
+ }
+
+if {
+ while (*lexptr != 'i' && *lexptr != 'I')
+ lexptr -= 1;
+ yyrestart(NULL);
+ return 0;
+ }
+
+ /* ADA KEYWORDS */
+
+abs { return ABS; }
+and { return _AND_; }
+else { return ELSE; }
+in { return IN; }
+mod { return MOD; }
+new { return NEW; }
+not { return NOT; }
+null { return NULL_PTR; }
+or { return OR; }
+rem { return REM; }
+then { return THEN; }
+xor { return XOR; }
+
+ /* ATTRIBUTES */
+
+{TICK}[a-zA-Z][a-zA-Z]+ { return processAttribute (yytext+1); }
+
+ /* PUNCTUATION */
+
+"=>" { return ARROW; }
+".." { return DOTDOT; }
+"**" { return STARSTAR; }
+":=" { return ASSIGN; }
+"/=" { return NOTEQUAL; }
+"<=" { return LEQ; }
+">=" { return GEQ; }
+
+<BEFORE_QUAL_QUOTE>"'" { BEGIN INITIAL; return '\''; }
+
+[-&*+./:<>=|;\[\]] { return yytext[0]; }
+
+"," { if (paren_depth == 0 && comma_terminates)
+ {
+ lexptr -= 1;
+ yyrestart(NULL);
+ return 0;
+ }
+ else
+ return ',';
+ }
+
+"(" { paren_depth += 1; return '('; }
+")" { if (paren_depth == 0)
+ {
+ lexptr -= 1;
+ yyrestart(NULL);
+ return 0;
+ }
+ else
+ {
+ paren_depth -= 1;
+ return ')';
+ }
+ }
+
+"."{WHITE}*all { return DOT_ALL; }
+
+"."{WHITE}*{ID} {
+ processId (yytext+1, yyleng-1);
+ return DOT_ID;
+ }
+
+{ID}({WHITE}*"."{WHITE}*({ID}|\"{OPER}\"))*(" "*"'")? {
+ int all_posn = find_dot_all (yytext);
+ int token_type, segments, k;
+ int quote_follows;
+
+ if (all_posn == -1 && yytext[yyleng-1] == '\'')
+ {
+ quote_follows = 1;
+ do {
+ yyless (yyleng-1);
+ } while (yytext[yyleng-1] == ' ');
+ }
+ else
+ quote_follows = 0;
+
+ if (all_posn >= 0)
+ yyless (all_posn);
+ processId(yytext, yyleng);
+ segments = name_lookup (ada_mangle (yylval.ssym.stoken.ptr),
+ yylval.ssym.stoken.ptr, &token_type);
+ left_block_context = NULL;
+ for (k = yyleng; segments > 0 && k > 0; k -= 1)
+ {
+ if (yytext[k-1] == '.')
+ segments -= 1;
+ quote_follows = 0;
+ }
+ if (k <= 0)
+ error ("confused by name %s", yytext);
+ yyless (k);
+ if (quote_follows)
+ BEGIN BEFORE_QUAL_QUOTE;
+ return token_type;
+ }
+
+ /* GDB EXPRESSION CONSTRUCTS */
+
+
+"'"[^']+"'"{WHITE}*:: {
+ processId(yytext, yyleng-2);
+ block_lookup (yylval.ssym.stoken.ptr, yylval.ssym.stoken.ptr);
+ return BLOCKNAME;
+ }
+
+{ID}({WHITE}*"."{WHITE}*({ID}|\"{OPER}\"))*{WHITE}*:: {
+ processId(yytext, yyleng-2);
+ block_lookup (ada_mangle (yylval.ssym.stoken.ptr),
+ yylval.ssym.stoken.ptr);
+ return BLOCKNAME;
+ }
+
+[{}@] { return yytext[0]; }
+
+"$$" { yylval.lval = -1; return LAST; }
+"$$"{DIG}+ { yylval.lval = -atoi(yytext+2); return LAST; }
+"$" { yylval.lval = 0; return LAST; }
+"$"{DIG}+ { yylval.lval = atoi(yytext+1); return LAST; }
+
+
+ /* REGISTERS AND GDB CONVENIENCE VARIABLES */
+
+"$"({LETTER}|{DIG}|"$")+ {
+ int c;
+ for (c = 0; c < NUM_REGS; c++)
+ if (REGISTER_NAME (c) &&
+ strcmp (yytext + 1, REGISTER_NAME (c)) == 0)
+ {
+ yylval.lval = c;
+ return REGNAME;
+ }
+ yylval.sval.ptr = yytext;
+ yylval.sval.length = yyleng;
+ yylval.ivar =
+ lookup_internalvar (copy_name (yylval.sval) + 1);
+ return INTERNAL_VARIABLE;
+ }
+
+ /* CATCH-ALL ERROR CASE */
+
+. { error ("Invalid character '%s' in expression.", yytext); }
+%%
+
+#include <ctype.h>
+#include <string.h>
+
+/* Initialize the lexer for processing new expression */
+void
+lexer_init (FILE* inp)
+{
+ BEGIN INITIAL;
+ yyrestart (inp);
+}
+
+
+/* Make sure that tempbuf points at an array at least N characters long. */
+
+static void
+resize_tempbuf (n)
+ unsigned int n;
+{
+ if (tempbufsize < n)
+ {
+ tempbufsize = (n+63) & ~63;
+ tempbuf = (char*) xrealloc (tempbuf, tempbufsize);
+ }
+}
+
+/* Copy S2 to S1, removing all underscores, and downcasing all letters. */
+
+static void
+canonicalizeNumeral (s1,s2)
+ char* s1;
+ const char* s2;
+{
+ for (; *s2 != '\000'; s2 += 1)
+ {
+ if (*s2 != '_')
+ {
+ *s1 = tolower(*s2);
+ s1 += 1;
+ }
+ }
+ s1[0] = '\000';
+}
+
+#define HIGH_BYTE_POSN ((sizeof (ULONGEST) - 1) * HOST_CHAR_BIT)
+
+/* True (non-zero) iff DIGIT is a valid digit in radix BASE,
+ where 2 <= BASE <= 16. */
+
+static int
+is_digit_in_base (digit, base)
+ unsigned char digit;
+ int base;
+{
+ if (!isxdigit (digit))
+ return 0;
+ if (base <= 10)
+ return (isdigit (digit) && digit < base + '0');
+ else
+ return (isdigit (digit) || tolower (digit) < base - 10 + 'a');
+}
+
+static int
+digit_to_int (c)
+ unsigned char c;
+{
+ if (isdigit (c))
+ return c - '0';
+ else
+ return tolower (c) - 'a' + 10;
+}
+
+/* As for strtoul, but for ULONGEST results. */
+ULONGEST
+strtoulst (num, trailer, base)
+ const char *num;
+ const char **trailer;
+ int base;
+{
+ unsigned int high_part;
+ ULONGEST result;
+ int i;
+ unsigned char lim;
+
+ if (base < 2 || base > 16)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+ lim = base - 1 + '0';
+
+ result = high_part = 0;
+ for (i = 0; is_digit_in_base (num[i], base); i += 1)
+ {
+ result = result*base + digit_to_int (num[i]);
+ high_part = high_part*base + (unsigned int) (result >> HIGH_BYTE_POSN);
+ result &= ((ULONGEST) 1 << HIGH_BYTE_POSN) - 1;
+ if (high_part > 0xff)
+ {
+ errno = ERANGE;
+ result = high_part = 0;
+ break;
+ }
+ }
+
+ if (trailer != NULL)
+ *trailer = &num[i];
+
+ return result + ((ULONGEST) high_part << HIGH_BYTE_POSN);
+}
+
+
+
+/* Interprets the prefix of NUM that consists of digits of the given BASE
+ as an integer of that BASE, with the string EXP as an exponent.
+ Puts value in yylval, and returns INT, if the string is valid. Causes
+ an error if the number is improperly formated. BASE, if NULL, defaults
+ to "10", and EXP to "1". The EXP does not contain a leading 'e' or 'E'. */
+
+static int
+processInt (base0, num0, exp0)
+ const char* num0;
+ const char* base0;
+ const char* exp0;
+{
+ ULONGEST result;
+ long exp;
+ int base;
+
+ char* trailer;
+
+ if (base0 == NULL)
+ base = 10;
+ else
+ {
+ base = strtol (base0, (char**) NULL, 10);
+ if (base < 2 || base > 16)
+ error ("Invalid base: %d.", base);
+ }
+
+ if (exp0 == NULL)
+ exp = 0;
+ else
+ exp = strtol(exp0, (char**) NULL, 10);
+
+ errno = 0;
+ result = strtoulst (num0, &trailer, base);
+ if (errno == ERANGE)
+ error ("Integer literal out of range");
+ if (isxdigit(*trailer))
+ error ("Invalid digit `%c' in based literal", *trailer);
+
+ while (exp > 0)
+ {
+ if (result > (ULONG_MAX / base))
+ error ("Integer literal out of range");
+ result *= base;
+ exp -= 1;
+ }
+
+ if ((result >> (TARGET_INT_BIT-1)) == 0)
+ yylval.typed_val.type = builtin_type_ada_int;
+ else if ((result >> (TARGET_LONG_BIT-1)) == 0)
+ yylval.typed_val.type = builtin_type_ada_long;
+ else if (((result >> (TARGET_LONG_BIT-1)) >> 1) == 0)
+ {
+ /* We have a number representable as an unsigned integer quantity.
+ For consistency with the C treatment, we will treat it as an
+ anonymous modular (unsigned) quantity. Alas, the types are such
+ that we need to store .val as a signed quantity. Sorry
+ for the mess, but C doesn't officially guarantee that a simple
+ assignment does the trick (no, it doesn't; read the reference manual).
+ */
+ yylval.typed_val.type = builtin_type_unsigned_long;
+ if (result & LONGEST_SIGN)
+ yylval.typed_val.val =
+ (LONGEST) (result & ~LONGEST_SIGN)
+ - (LONGEST_SIGN>>1) - (LONGEST_SIGN>>1);
+ else
+ yylval.typed_val.val = (LONGEST) result;
+ return INT;
+ }
+ else
+ yylval.typed_val.type = builtin_type_ada_long_long;
+
+ yylval.typed_val.val = (LONGEST) result;
+ return INT;
+}
+
+static int
+processReal (num0)
+ const char* num0;
+{
+ if (sizeof (DOUBLEST) <= sizeof (float))
+ sscanf (num0, "%g", &yylval.typed_val_float.dval);
+ else if (sizeof (DOUBLEST) <= sizeof (double))
+ sscanf (num0, "%lg", &yylval.typed_val_float.dval);
+ else
+ {
+#ifdef PRINTF_HAS_LONG_DOUBLE
+ sscanf (num0, "%Lg", &yylval.typed_val_float.dval);
+#else
+ /* Scan it into a double, then convert and assign it to the
+ long double. This at least wins with values representable
+ in the range of doubles. */
+ double temp;
+ sscanf (num0, "%lg", &temp);
+ yylval.typed_val_float.dval = temp;
+#endif
+ }
+
+ yylval.typed_val_float.type = builtin_type_ada_float;
+ if (sizeof(DOUBLEST) >= TARGET_DOUBLE_BIT / TARGET_CHAR_BIT)
+ yylval.typed_val_float.type = builtin_type_ada_double;
+ if (sizeof(DOUBLEST) >= TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT)
+ yylval.typed_val_float.type = builtin_type_ada_long_double;
+
+ return FLOAT;
+}
+
+static int
+processId (name0, len)
+ const char *name0;
+ int len;
+{
+ char* name = xmalloc (len + 11);
+ int i0, i;
+
+/* add_name_string_cleanup (name); */
+/* FIXME: add_name_string_cleanup should be defined in parse.c */
+ while (len > 0 && isspace (name0[len-1]))
+ len -= 1;
+ i = i0 = 0;
+ while (i0 < len)
+ {
+ if (isalnum (name0[i0]))
+ {
+ name[i] = tolower (name0[i0]);
+ i += 1; i0 += 1;
+ }
+ else switch (name0[i0])
+ {
+ default:
+ name[i] = name0[i0];
+ i += 1; i0 += 1;
+ break;
+ case ' ': case '\t':
+ i0 += 1;
+ break;
+ case '\'':
+ i0 += 1;
+ while (i0 < len && name0[i0] != '\'')
+ {
+ name[i] = name0[i0];
+ i += 1; i0 += 1;
+ }
+ i0 += 1;
+ break;
+ case '<':
+ i0 += 1;
+ while (i0 < len && name0[i0] != '>')
+ {
+ name[i] = name0[i0];
+ i += 1; i0 += 1;
+ }
+ i0 += 1;
+ break;
+ }
+ }
+ name[i] = '\000';
+
+ yylval.ssym.sym = NULL;
+ yylval.ssym.stoken.ptr = name;
+ yylval.ssym.stoken.length = i;
+ return NAME;
+}
+
+static void
+block_lookup (name, err_name)
+ char* name;
+ char* err_name;
+{
+ struct symbol** syms;
+ struct block** blocks;
+ int nsyms;
+ struct symtab *symtab;
+ nsyms = ada_lookup_symbol_list (name, left_block_context,
+ VAR_NAMESPACE, &syms, &blocks);
+ if (left_block_context == NULL &&
+ (nsyms == 0 || SYMBOL_CLASS (syms[0]) != LOC_BLOCK))
+ symtab = lookup_symtab (name);
+ else
+ symtab = NULL;
+
+ if (symtab != NULL)
+ left_block_context = yylval.bval =
+ BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
+ else if (nsyms == 0 || SYMBOL_CLASS (syms[0]) != LOC_BLOCK)
+ {
+ if (left_block_context == NULL)
+ error ("No file or function \"%s\".", err_name);
+ else
+ error ("No function \"%s\" in specified context.", err_name);
+ }
+ else
+ {
+ left_block_context = yylval.bval = SYMBOL_BLOCK_VALUE (syms[0]);
+ if (nsyms > 1)
+ warning ("Function name \"%s\" ambiguous here", err_name);
+ }
+}
+
+/* Look up NAME0 (assumed to be mangled) as a name in VAR_NAMESPACE,
+ setting *TOKEN_TYPE to NAME or TYPENAME, depending on what is
+ found. Try first the entire name, then the name without the last
+ segment (i.e., after the last .id), etc., and return the number of
+ segments that had to be removed to get a match. Calls error if no
+ matches are found, using ERR_NAME in any error message. When
+ exactly one symbol match is found, it is placed in yylval. */
+
+static int
+name_lookup (name0, err_name, token_type)
+ char* name0;
+ char* err_name;
+ int* token_type;
+{
+ struct symbol** syms;
+ struct block** blocks;
+ struct type* type;
+ int len0 = strlen (name0);
+ char* name = savestring (name0, len0);
+ int nsyms;
+ int segments;
+
+/* add_name_string_cleanup (name);*/
+/* FIXME: add_name_string_cleanup should be defined in parse.c */
+ yylval.ssym.stoken.ptr = name;
+ yylval.ssym.stoken.length = strlen (name);
+ for (segments = 0; ; segments += 1)
+ {
+ struct type* preferred_type;
+ int i, preferred_index;
+
+ if (left_block_context == NULL)
+ nsyms = ada_lookup_symbol_list (name, expression_context_block,
+ VAR_NAMESPACE, &syms, &blocks);
+ else
+ nsyms = ada_lookup_symbol_list (name, left_block_context,
+ VAR_NAMESPACE, &syms, &blocks);
+
+ /* Check for a type definition. */
+
+ /* Look for a symbol that doesn't denote void. This is (I think) a */
+ /* temporary kludge to get around problems in GNAT output. */
+ preferred_index = -1; preferred_type = NULL;
+ for (i = 0; i < nsyms; i += 1)
+ switch (SYMBOL_CLASS (syms[i]))
+ {
+ case LOC_TYPEDEF:
+ if (ada_prefer_type (SYMBOL_TYPE (syms[i]), preferred_type))
+ {
+ preferred_index = i;
+ preferred_type = SYMBOL_TYPE (syms[i]);
+ }
+ break;
+ case LOC_REGISTER:
+ case LOC_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_LOCAL:
+ case LOC_LOCAL_ARG:
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
+ goto NotType;
+ default:
+ break;
+ }
+ if (preferred_type != NULL)
+ {
+/* if (TYPE_CODE (preferred_type) == TYPE_CODE_VOID)
+ error ("`%s' matches only void type name(s)",
+ ada_demangle (name));
+*/
+/* FIXME: ada_demangle should be defined in defs.h, and is located in ada-lang.c */
+/* else*/ if (ada_is_object_renaming (syms[preferred_index]))
+ {
+ yylval.ssym.sym = syms[preferred_index];
+ *token_type = OBJECT_RENAMING;
+ return segments;
+ }
+ else if (ada_renaming_type (SYMBOL_TYPE (syms[preferred_index]))
+ != NULL)
+ {
+ int result;
+ const char* renaming =
+ ada_simple_renamed_entity (syms[preferred_index]);
+ char* new_name = xmalloc (strlen (renaming) + len0
+ - yylval.ssym.stoken.length + 1);
+/* add_name_string_cleanup (new_name);*/
+/* FIXME: add_name_string_cleanup should be defined in parse.c */
+ strcpy (new_name, renaming);
+ strcat (new_name, name0 + yylval.ssym.stoken.length);
+ result = name_lookup (new_name, err_name, token_type);
+ if (result > segments)
+ error ("Confused by renamed symbol.");
+ return result;
+ }
+ else if (segments == 0)
+ {
+ yylval.tval = preferred_type;
+ *token_type = TYPENAME;
+ return 0;
+ }
+ }
+
+ if (segments == 0)
+ {
+ type = lookup_primitive_typename (name);
+ if (type == NULL && STREQ ("system__address", name))
+ type = builtin_type_ada_system_address;
+ if (type != NULL)
+ {
+ yylval.tval = type;
+ *token_type = TYPENAME;
+ return 0;
+ }
+ }
+
+ NotType:
+ if (nsyms == 1)
+ {
+ *token_type = NAME;
+ yylval.ssym.sym = syms[0];
+ yylval.ssym.msym = NULL;
+ yylval.ssym.block = blocks[0];
+ return segments;
+ }
+ else if (nsyms == 0) {
+ int i;
+ yylval.ssym.msym = ada_lookup_minimal_symbol (name);
+ if (yylval.ssym.msym != NULL)
+ {
+ yylval.ssym.sym = NULL;
+ yylval.ssym.block = NULL;
+ *token_type = NAME;
+ return segments;
+ }
+
+ for (i = yylval.ssym.stoken.length - 1; i > 0; i -= 1)
+ {
+ if (name[i] == '.')
+ {
+ name[i] = '\0';
+ yylval.ssym.stoken.length = i;
+ break;
+ }
+ else if (name[i] == '_' && name[i-1] == '_')
+ {
+ i -= 1;
+ name[i] = '\0';
+ yylval.ssym.stoken.length = i;
+ break;
+ }
+ }
+ if (i <= 0)
+ {
+ if (!have_full_symbols () && !have_partial_symbols ()
+ && left_block_context == NULL)
+ error ("No symbol table is loaded. Use the \"file\" command.");
+ if (left_block_context == NULL)
+ error ("No definition of \"%s\" in current context.",
+ err_name);
+ else
+ error ("No definition of \"%s\" in specified context.",
+ err_name);
+ }
+ }
+ else
+ {
+ *token_type = NAME;
+ yylval.ssym.sym = NULL;
+ yylval.ssym.msym = NULL;
+ if (left_block_context == NULL)
+ yylval.ssym.block = expression_context_block;
+ else
+ yylval.ssym.block = left_block_context;
+ return segments;
+ }
+ }
+}
+
+/* Returns the position within STR of the '.' in a
+ '.{WHITE}*all' component of a dotted name, or -1 if there is none. */
+static int
+find_dot_all (str)
+ const char* str;
+{
+ int i;
+ for (i = 0; str[i] != '\000'; i += 1)
+ {
+ if (str[i] == '.')
+ {
+ int i0 = i;
+ do
+ i += 1;
+ while (isspace (str[i]));
+ if (strcmp (str+i, "all") == 0
+ && ! isalnum (str[i+3]) && str[i+3] != '_')
+ return i0;
+ }
+ }
+ return -1;
+}
+
+/* Returns non-zero iff string SUBSEQ matches a subsequence of STR, ignoring
+ case. */
+
+static int
+subseqMatch (subseq, str)
+ const char* subseq;
+ const char* str;
+{
+ if (subseq[0] == '\0')
+ return 1;
+ else if (str[0] == '\0')
+ return 0;
+ else if (tolower (subseq[0]) == tolower (str[0]))
+ return subseqMatch (subseq+1, str+1) || subseqMatch (subseq, str+1);
+ else
+ return subseqMatch (subseq, str+1);
+}
+
+
+static struct { const char* name; int code; }
+attributes[] = {
+ { "address", TICK_ADDRESS },
+ { "unchecked_access", TICK_ACCESS },
+ { "unrestricted_access", TICK_ACCESS },
+ { "access", TICK_ACCESS },
+ { "first", TICK_FIRST },
+ { "last", TICK_LAST },
+ { "length", TICK_LENGTH },
+ { "max", TICK_MAX },
+ { "min", TICK_MIN },
+ { "modulus", TICK_MODULUS },
+ { "pos", TICK_POS },
+ { "range", TICK_RANGE },
+ { "size", TICK_SIZE },
+ { "tag", TICK_TAG },
+ { "val", TICK_VAL },
+ { NULL, -1 }
+};
+
+/* Return the syntactic code corresponding to the attribute name or
+ abbreviation STR. */
+
+static int
+processAttribute (str)
+ const char* str;
+{
+ int i, k;
+
+ for (i = 0; attributes[i].code != -1; i += 1)
+ if (strcasecmp (str, attributes[i].name) == 0)
+ return attributes[i].code;
+
+ for (i = 0, k = -1; attributes[i].code != -1; i += 1)
+ if (subseqMatch (str, attributes[i].name))
+ {
+ if (k == -1)
+ k = i;
+ else
+ error ("ambiguous attribute name: `%s'", str);
+ }
+ if (k == -1)
+ error ("unrecognized attribute: `%s'", str);
+
+ return attributes[k].code;
+}
+
+int
+yywrap()
+{
+ return 1;
+}
diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
new file mode 100644
index 00000000000..23dc105ea9d
--- /dev/null
+++ b/gdb/ada-tasks.c
@@ -0,0 +1,806 @@
+/* file ada-tasks.c: Ada tasking control for GDB
+ Copyright 1997 Free Software Foundation, Inc.
+ Contributed by Ada Core Technologies, Inc
+.
+ This file is part of GDB.
+
+ [$Id$]
+ Authors: Roch-Alexandre Nomine Beguin, Arnaud Charlet <charlet@gnat.com>
+
+ 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.
+
+*/
+
+#include <ctype.h>
+#include "defs.h"
+#include "command.h"
+#include "value.h"
+#include "language.h"
+#include "inferior.h"
+#include "symtab.h"
+#include "target.h"
+#include "gdbcore.h"
+
+#if (defined(__alpha__) && defined(__osf__) && !defined(__alpha_vxworks))
+#include <sys/procfs.h>
+#endif
+
+#if (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET))
+#include "gregset.h"
+#endif
+
+#include "ada-lang.h"
+
+/* FIXME: move all this conditional compilation in description
+ files or in configure.in */
+
+#if defined (VXWORKS_TARGET)
+#define THREAD_TO_PID(tid,lwpid) (tid)
+
+#elif defined (linux)
+#define THREAD_TO_PID(tid,lwpid) (0)
+
+#elif (defined (sun) && defined (__SVR4))
+#define THREAD_TO_PID thread_to_pid
+
+#elif defined (sgi) || defined (__WIN32__) || defined (hpux)
+#define THREAD_TO_PID(tid,lwpid) ((int)lwpid)
+
+#else
+#define THREAD_TO_PID(tid,lwpid) (0)
+#endif
+
+#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)
+#define THREAD_FETCH_REGISTERS dec_thread_fetch_registers
+#define GET_CURRENT_THREAD dec_thread_get_current_thread
+extern int dec_thread_get_registers (gdb_gregset_t *, gdb_fpregset_t *);
+#endif
+
+#if defined (_AIX)
+#define THREAD_FETCH_REGISTERS aix_thread_fetch_registers
+#define GET_CURRENT_THREAD aix_thread_get_current_thread
+#endif
+
+#if defined(VXWORKS_TARGET)
+#define GET_CURRENT_THREAD() ((void*)inferior_pid)
+#define THREAD_FETCH_REGISTERS() (-1)
+
+#elif defined (sun) && defined (__SVR4)
+#define GET_CURRENT_THREAD solaris_thread_get_current_thread
+#define THREAD_FETCH_REGISTERS() (-1)
+extern void *GET_CURRENT_THREAD();
+
+#elif defined (_AIX) || (defined(__alpha__) && defined(__osf__))
+extern void *GET_CURRENT_THREAD();
+
+#elif defined (__WIN32__) || defined (hpux)
+#define GET_CURRENT_THREAD() (inferior_pid)
+#define THREAD_FETCH_REGISTERS() (-1)
+
+#else
+#define GET_CURRENT_THREAD() (NULL)
+#define THREAD_FETCH_REGISTERS() (-1)
+#endif
+
+#define KNOWN_TASKS_NAME "system__tasking__debug__known_tasks"
+
+#define READ_MEMORY(addr, var) read_memory (addr, (char*) &var, sizeof (var))
+/* external declarations */
+
+extern struct value* find_function_in_inferior (char *);
+
+/* Global visible variables */
+
+struct task_entry *task_list = NULL;
+int ada__tasks_check_symbol_table = 1;
+void *pthread_kern_addr = NULL;
+
+#if (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET))
+gdb_gregset_t gregset_saved;
+gdb_fpregset_t fpregset_saved;
+#endif
+
+/* The maximum number of tasks known to the Ada runtime */
+const int MAX_NUMBER_OF_KNOWN_TASKS = 1000;
+
+/* the current task */
+int current_task = -1, current_task_id = -1, current_task_index;
+void *current_thread, *current_lwp;
+
+char *ada_task_states[] =
+{
+ "Unactivated",
+ "Runnable",
+ "Terminated",
+ "Child Activation Wait",
+ "Accept Statement",
+ "Waiting on entry call",
+ "Async Select Wait",
+ "Delay Sleep",
+ "Child Termination Wait",
+ "Wait Child in Term Alt",
+ "",
+ "",
+ "",
+ "",
+ "Asynchronous Hold"
+};
+
+/* Global internal types */
+
+static char *ada_long_task_states[] =
+{
+ "Unactivated",
+ "Runnable",
+ "Terminated",
+ "Waiting for child activation",
+ "Blocked in accept statement",
+ "Waiting on entry call",
+ "Asynchronous Selective Wait",
+ "Delay Sleep",
+ "Waiting for children termination",
+ "Waiting for children in terminate alternative",
+ "",
+ "",
+ "",
+ "",
+ "Asynchronous Hold"
+};
+
+/* Global internal variables */
+
+static int highest_task_num = 0;
+int thread_support = 0; /* 1 if the thread library in use is supported */
+static int gdbtk_task_initialization = 0;
+
+static int add_task_entry (p_task_id, index)
+ void *p_task_id;
+ int index;
+{
+ struct task_entry *new_task_entry = NULL;
+ struct task_entry *pt;
+
+ highest_task_num++;
+ new_task_entry = malloc (sizeof (struct task_entry));
+ new_task_entry->task_num = highest_task_num;
+ new_task_entry->task_id = p_task_id;
+ new_task_entry->known_tasks_index = index;
+ new_task_entry->next_task = NULL;
+ pt = task_list;
+ if (pt)
+ {
+ while (pt->next_task)
+ pt = pt->next_task;
+ pt->next_task = new_task_entry;
+ pt->stack_per = 0;
+ }
+ else task_list = new_task_entry;
+ return new_task_entry->task_num;
+}
+
+int
+get_entry_number (p_task_id)
+ void *p_task_id;
+{
+ struct task_entry *pt;
+
+ pt = task_list;
+ while (pt != NULL)
+ {
+ if (pt->task_id == p_task_id)
+ return pt->task_num;
+ pt = pt->next_task;
+ }
+ return 0;
+}
+
+static struct task_entry *get_thread_entry_vptr (thread)
+ void *thread;
+{
+ struct task_entry *pt;
+
+ pt = task_list;
+ while (pt != NULL)
+ {
+ if (pt->thread == thread)
+ return pt;
+ pt = pt->next_task;
+ }
+ return 0;
+}
+
+static struct task_entry *get_entry_vptr (p_task_num)
+ int p_task_num;
+{
+ struct task_entry *pt;
+
+ pt = task_list;
+ while (pt)
+ {
+ if (pt->task_num == p_task_num)
+ return pt;
+ pt = pt->next_task;
+ }
+ return NULL;
+}
+
+void init_task_list ()
+{
+ struct task_entry *pt, *old_pt;
+
+ pt = task_list;
+ while (pt)
+ {
+ old_pt = pt;
+ pt = pt->next_task;
+ free (old_pt);
+ };
+ task_list = NULL;
+ highest_task_num = 0;
+}
+
+int valid_task_id (task)
+ int task;
+{
+ return get_entry_vptr (task) != NULL;
+}
+
+void *get_self_id ()
+{
+ struct value* val;
+ void *self_id;
+ int result;
+ struct task_entry *ent;
+ extern int do_not_insert_breakpoints;
+
+#if !((defined(sun) && defined(__SVR4)) || defined(VXWORKS_TARGET) || defined(__WIN32__))
+ if (thread_support)
+#endif
+ {
+ ent = get_thread_entry_vptr (GET_CURRENT_THREAD ());
+ return ent ? ent->task_id : 0;
+ }
+
+ /* FIXME: calling a function in the inferior with a multithreaded application
+ is not reliable, so return NULL if there is no safe way to get the current
+ task */
+ return NULL;
+}
+
+int get_current_task ()
+{
+ int result;
+
+ /* FIXME: language_ada should be defined in defs.h */
+ /* if (current_language->la_language != language_ada) return -1; */
+
+ result = get_entry_number (get_self_id ());
+
+ /* return -1 if not found */
+ return result == 0 ? -1 : result;
+}
+
+/* Print detailed information about specified task */
+
+static void
+info_task (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ void *temp_task;
+ struct task_entry *pt, *pt2;
+ void *self_id, *caller;
+ struct task_fields atcb, atcb2;
+ struct entry_call call;
+ int bounds [2];
+ char image [256];
+ int num;
+
+ /* FIXME: language_ada should be defined in defs.h */
+ /* if (current_language->la_language != language_ada)
+ {
+ printf_filtered ("The current language does not support tasks.\n");
+ return;
+ }
+ */
+ pt = get_entry_vptr (atoi (arg));
+ if (pt == NULL)
+ {
+ printf_filtered ("Task %s not found.\n", arg);
+ return;
+ }
+
+ temp_task = pt->task_id;
+
+ /* read the atcb in the inferior */
+ READ_MEMORY ((CORE_ADDR) temp_task, atcb);
+
+ /* print the Ada task id */
+ printf_filtered ("Ada Task: %p\n", temp_task);
+
+ /* print the name of the task */
+ if (atcb.image.P_ARRAY != NULL) {
+ READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb.image.P_BOUNDS), bounds);
+ bounds [1] = EXTRACT_INT (bounds [1]);
+ read_memory ((CORE_ADDR) EXTRACT_ADDRESS (atcb.image.P_ARRAY),
+ (char*) &image, bounds [1]);
+ printf_filtered ("Name: %.*s\n", bounds [1], image);
+ }
+ else printf_filtered ("<no name>\n");
+
+ /* print the thread id */
+
+ if ((long) pt->thread < 65536)
+ printf_filtered ("Thread: %ld\n", (long int) pt->thread);
+ else
+ printf_filtered ("Thread: %p\n", pt->thread);
+
+ if ((long) pt->lwp != 0)
+ {
+ if ((long) pt->lwp < 65536)
+ printf_filtered ("LWP: %ld\n", (long int) pt->lwp);
+ else
+ printf_filtered ("LWP: %p\n", pt->lwp);
+ }
+
+ /* print the parent gdb task id */
+ num = get_entry_number (EXTRACT_ADDRESS (atcb.parent));
+ if (num != 0)
+ {
+ printf_filtered ("Parent: %d", num);
+ pt2 = get_entry_vptr (num);
+ READ_MEMORY ((CORE_ADDR) pt2->task_id, atcb2);
+
+ /* print the name of the task */
+ if (atcb2.image.P_ARRAY != NULL) {
+ READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb2.image.P_BOUNDS),
+ bounds);
+ bounds [1] = EXTRACT_INT (bounds [1]);
+ read_memory ((CORE_ADDR) EXTRACT_ADDRESS (atcb2.image.P_ARRAY),
+ (char*) &image, bounds [1]);
+ printf_filtered (" (%.*s)\n", bounds [1], image);
+ }
+ else
+ printf_filtered ("\n");
+ }
+ else
+ printf_filtered ("No parent\n");
+
+ /* print the base priority of the task */
+ printf_filtered ("Base Priority: %d\n", EXTRACT_INT (atcb.priority));
+
+ /* print the current state of the task */
+
+ /* check if this task is accepting a rendezvous */
+ if (atcb.call == NULL)
+ caller = NULL;
+ else {
+ READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb.call), call);
+ caller = EXTRACT_ADDRESS (call.self);
+ }
+
+ if (caller != NULL)
+ {
+ num = get_entry_number (caller);
+ printf_filtered ("Accepting rendezvous with %d", num);
+
+ if (num != 0)
+ {
+ pt2 = get_entry_vptr (num);
+ READ_MEMORY ((CORE_ADDR) pt2->task_id, atcb2);
+
+ /* print the name of the task */
+ if (atcb2.image.P_ARRAY != NULL) {
+ READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb2.image.P_BOUNDS),
+ bounds);
+ bounds [1] = EXTRACT_INT (bounds [1]);
+ read_memory ((CORE_ADDR) EXTRACT_ADDRESS (atcb2.image.P_ARRAY),
+ (char*) &image, bounds [1]);
+ printf_filtered (" (%.*s)\n", bounds [1], image);
+ }
+ else
+ printf_filtered ("\n");
+ }
+ else
+ printf_filtered ("\n");
+ }
+ else
+ printf_filtered ("State: %s\n", ada_long_task_states [atcb.state]);
+}
+
+#if 0
+
+/* A useful function that shows the alignment of all the fields in the
+ tasks_fields structure
+ */
+
+print_align ()
+{
+ struct task_fields tf;
+ void *tf_base = &(tf);
+ void *tf_state = &(tf.state);
+ void *tf_entry_num = &(tf.entry_num);
+ void *tf_parent = &(tf.parent);
+ void *tf_priority = &(tf.priority);
+ void *tf_current_priority = &(tf.current_priority);
+ void *tf_image = &(tf.image);
+ void *tf_call = &(tf.call);
+ void *tf_thread = &(tf.thread);
+ void *tf_lwp = &(tf.lwp);
+ printf_filtered ("\n");
+ printf_filtered ("(tf_base = 0x%x)\n", tf_base);
+ printf_filtered ("task_fields.entry_num at %3d (0x%x)\n", tf_entry_num - tf_base, tf_entry_num);
+ printf_filtered ("task_fields.state at %3d (0x%x)\n", tf_state - tf_base, tf_state);
+ printf_filtered ("task_fields.parent at %3d (0x%x)\n", tf_parent - tf_base, tf_parent);
+ printf_filtered ("task_fields.priority at %3d (0x%x)\n", tf_priority - tf_base, tf_priority);
+ printf_filtered ("task_fields.current_priority at %3d (0x%x)\n", tf_current_priority - tf_base, tf_current_priority);
+ printf_filtered ("task_fields.image at %3d (0x%x)\n", tf_image - tf_base, tf_image);
+ printf_filtered ("task_fields.call at %3d (0x%x)\n", tf_call - tf_base, tf_call);
+ printf_filtered ("task_fields.thread at %3d (0x%x)\n", tf_thread - tf_base, tf_thread);
+ printf_filtered ("task_fields.lwp at %3d (0x%x)\n", tf_lwp - tf_base, tf_lwp);
+ printf_filtered ("\n");
+}
+#endif
+
+/* Print information about currently known tasks */
+
+static void
+info_tasks (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ struct value* val;
+ int i, task_number, state;
+ void *temp_task, *temp_tasks [MAX_NUMBER_OF_KNOWN_TASKS];
+ struct task_entry *pt;
+ void *self_id, *caller, *thread_id=NULL;
+ struct task_fields atcb;
+ struct entry_call call;
+ int bounds [2];
+ char image [256];
+ int size;
+ char car;
+
+#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)
+ pthreadTeb_t thr;
+ gdb_gregset_t regs;
+#endif
+
+ static struct symbol *sym;
+ static struct minimal_symbol *msym;
+ static void *known_tasks_addr = NULL;
+
+ int init_only = gdbtk_task_initialization;
+ gdbtk_task_initialization = 0;
+
+ task_number = 0;
+
+ if (PIDGET(inferior_ptid) == 0)
+ {
+ printf_filtered ("The program is not being run under gdb. ");
+ printf_filtered ("Use 'run' or 'attach' first.\n");
+ return;
+ }
+
+ if (ada__tasks_check_symbol_table)
+ {
+ thread_support = 0;
+#if (defined(__alpha__) && defined(__osf__) & !defined(VXWORKS_TARGET)) || \
+ defined (_AIX)
+ thread_support = 1;
+#endif
+
+ msym = lookup_minimal_symbol (KNOWN_TASKS_NAME, NULL, NULL);
+ if (msym != NULL)
+ known_tasks_addr = (void *) SYMBOL_VALUE_ADDRESS (msym);
+ else
+#ifndef VXWORKS_TARGET
+ return;
+#else
+ {
+ if (target_lookup_symbol (KNOWN_TASKS_NAME, &known_tasks_addr) != 0)
+ return;
+ }
+#endif
+
+ ada__tasks_check_symbol_table = 0;
+ }
+
+ if (known_tasks_addr == NULL)
+ return;
+
+#if !((defined(sun) && defined(__SVR4)) || defined(VXWORKS_TARGET) || defined(__WIN32__) || defined (hpux))
+ if (thread_support)
+#endif
+ thread_id = GET_CURRENT_THREAD ();
+
+ /* then we get a list of tasks created */
+
+ init_task_list ();
+
+ READ_MEMORY ((CORE_ADDR) known_tasks_addr, temp_tasks);
+
+ for (i=0; i<MAX_NUMBER_OF_KNOWN_TASKS; i++)
+ {
+ temp_task = EXTRACT_ADDRESS (temp_tasks[i]);
+
+ if (temp_task != NULL)
+ {
+ task_number = get_entry_number (temp_task);
+ if (task_number == 0)
+ task_number = add_task_entry (temp_task, i);
+ }
+ }
+
+ /* Return without printing anything if this function was called in
+ order to init GDBTK tasking. */
+
+ if (init_only) return;
+
+ /* print the header */
+
+#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)
+ printf_filtered
+ (" ID TID P-ID Pri Stack %% State Name\n");
+#else
+ printf_filtered (" ID TID P-ID Pri State Name\n");
+#endif
+
+ /* Now that we have a list of task id's, we can print them */
+ pt = task_list;
+ while (pt)
+ {
+ temp_task = pt->task_id;
+
+ /* read the atcb in the inferior */
+ READ_MEMORY ((CORE_ADDR) temp_task, atcb);
+
+ /* store the thread id for future use */
+ pt->thread = EXTRACT_ADDRESS (atcb.thread);
+
+#if defined (linux)
+ pt->lwp = (void *) THREAD_TO_PID (atcb.thread, 0);
+#else
+ pt->lwp = EXTRACT_ADDRESS (atcb.lwp);
+#endif
+
+ /* print a star if this task is the current one */
+ if (thread_id)
+#if defined (__WIN32__) || defined (SGI) || defined (hpux)
+ printf_filtered (pt->lwp == thread_id ? "*" : " ");
+#else
+ printf_filtered (pt->thread == thread_id ? "*" : " ");
+#endif
+
+ /* print the gdb task id */
+ printf_filtered ("%3d", pt->task_num);
+
+ /* print the Ada task id */
+#ifndef VXWORKS_TARGET
+ printf_filtered (" %9lx", (long) temp_task);
+#else
+#ifdef TARGET_64
+ printf_filtered (" %#9lx", (unsigned long)pt->thread & 0x3ffffffffff);
+#else
+ printf_filtered (" %#9lx", (long)pt->thread);
+#endif
+#endif
+
+ /* print the parent gdb task id */
+ printf_filtered
+ (" %4d", get_entry_number (EXTRACT_ADDRESS (atcb.parent)));
+
+ /* print the base priority of the task */
+ printf_filtered (" %3d", EXTRACT_INT (atcb.priority));
+
+#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)
+ if (pt->task_num == 1 || atcb.state == Terminated)
+ {
+ printf_filtered (" Unknown");
+ goto next;
+ }
+
+ read_memory ((CORE_ADDR)atcb.thread, &thr, sizeof (thr));
+ current_thread = atcb.thread;
+ regs.regs [SP_REGNUM] = 0;
+ if (dec_thread_get_registers (&regs, NULL) == 0) {
+ pt->stack_per = (100 * ((long)thr.__stack_base -
+ regs.regs [SP_REGNUM])) / thr.__stack_size;
+ /* if the thread is terminated but still there, the
+ stack_base/size values are erroneous. Try to patch it */
+ if (pt->stack_per < 0 || pt->stack_per > 100) pt->stack_per = 0;
+ }
+
+ /* print information about stack space used in the thread */
+ if (thr.__stack_size < 1024*1024)
+ {
+ size = thr.__stack_size / 1024;
+ car = 'K';
+ }
+ else if (thr.__stack_size < 1024*1024*1024)
+ {
+ size = thr.__stack_size / 1024 / 1024;
+ car = 'M';
+ }
+ else /* Who knows... */
+ {
+ size = thr.__stack_size / 1024 / 1024 / 1024;
+ car = 'G';
+ }
+ printf_filtered (" %4d%c %2d", size, car, pt->stack_per);
+next:
+#endif
+
+ /* print the current state of the task */
+
+ /* check if this task is accepting a rendezvous */
+ if (atcb.call == NULL)
+ caller = NULL;
+ else {
+ READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb.call), call);
+ caller = EXTRACT_ADDRESS (call.self);
+ }
+
+ if (caller != NULL)
+ printf_filtered (" Accepting RV with %-4d", get_entry_number (caller));
+ else
+ {
+ state = atcb.state;
+#if defined (__WIN32__) || defined (SGI) || defined (hpux)
+ if (state == Runnable && (thread_id && pt->lwp == thread_id))
+#else
+ if (state == Runnable && (thread_id && pt->thread == thread_id))
+#endif
+ /* Replace "Runnable" by "Running" if this is the current task */
+ printf_filtered (" %-22s", "Running");
+ else
+ printf_filtered (" %-22s", ada_task_states [state]);
+ }
+
+ /* finally, print the name of the task */
+ if (atcb.image.P_ARRAY != NULL) {
+ READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb.image.P_BOUNDS), bounds);
+ bounds [1] = EXTRACT_INT (bounds [1]);
+ read_memory ((CORE_ADDR) EXTRACT_ADDRESS (atcb.image.P_ARRAY),
+ (char*)&image, bounds [1]);
+ printf_filtered (" %.*s\n", bounds [1], image);
+ }
+ else printf_filtered (" <no name>\n");
+
+ pt = pt->next_task;
+ }
+}
+
+/* Task list initialization for GDB-Tk. We basically use info_tasks()
+ to initialize our variables, but abort that function before we
+ actually print anything. */
+
+int
+gdbtk_tcl_tasks_initialize ()
+{
+ gdbtk_task_initialization = 1;
+ info_tasks ("", gdb_stdout);
+
+ return (task_list != NULL);
+}
+
+static void
+info_tasks_command (arg, from_tty)
+ char *arg;
+ int from_tty;
+{
+ if (arg == NULL || *arg == '\000')
+ info_tasks (arg, from_tty);
+ else
+ info_task (arg, from_tty);
+}
+
+/* Switch from one thread to another. */
+
+static void
+switch_to_thread (ptid_t ptid)
+
+{
+ if (ptid_equal (ptid, inferior_ptid))
+ return;
+
+ inferior_ptid = ptid;
+ flush_cached_frames ();
+ registers_changed ();
+ stop_pc = read_pc ();
+ select_frame (get_current_frame ());
+}
+
+/* Switch to a specified task. */
+
+static int task_switch (tid, lwpid)
+ void *tid, *lwpid;
+{
+ int res = 0, pid;
+
+ if (thread_support)
+ {
+ flush_cached_frames ();
+
+ if (current_task != current_task_id)
+ {
+ res = THREAD_FETCH_REGISTERS ();
+ }
+ else
+ {
+#if (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET))
+ supply_gregset (&gregset_saved);
+ supply_fpregset (&fpregset_saved);
+#endif
+ }
+
+ if (res == 0) stop_pc = read_pc();
+ select_frame (get_current_frame ());
+ return res;
+ }
+
+ return -1;
+}
+
+static void task_command (tidstr, from_tty)
+ char *tidstr;
+ int from_tty;
+{
+ int num;
+ struct task_entry *e;
+
+ if (!tidstr)
+ error ("Please specify a task ID. Use the \"info tasks\" command to\n"
+ "see the IDs of currently known tasks.");
+
+ num = atoi (tidstr);
+ e = get_entry_vptr (num);
+
+ if (e == NULL)
+ error ("Task ID %d not known. Use the \"info tasks\" command to\n"
+ "see the IDs of currently known tasks.", num);
+
+ if (current_task_id == -1)
+ {
+#if (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET))
+ fill_gregset (&gregset_saved, -1);
+ fill_fpregset (&fpregset_saved, -1);
+#endif
+ current_task_id = get_current_task ();
+ }
+
+ current_task = num;
+ current_task_index = e->known_tasks_index;
+ current_thread = e->thread;
+ current_lwp = e->lwp;
+ if (task_switch (e->thread, e->lwp) == 0)
+ {
+ /* FIXME: find_printable_frame should be defined in frame.h, and
+ implemented in ada-lang.c */
+ /* find_printable_frame (selected_frame, frame_relative_level (selected_frame));*/
+ printf_filtered ("[Switching to task %d]\n", num);
+ print_stack_frame (selected_frame, frame_relative_level (selected_frame), 1);
+ }
+ else
+ printf_filtered ("Unable to switch to task %d\n", num);
+}
+
+void
+_initialize_tasks ()
+{
+ static struct cmd_list_element *task_cmd_list = NULL;
+ extern struct cmd_list_element *cmdlist;
+
+ add_info (
+ "tasks", info_tasks_command,
+ "Without argument: list all known Ada tasks, with status information.\n"
+ "info tasks n: print detailed information of task n.\n");
+
+ add_prefix_cmd ("task", class_run, task_command,
+ "Use this command to switch between tasks.\n\
+ The new task ID must be currently known.", &task_cmd_list, "task ", 1,
+ &cmdlist);
+}
diff --git a/gdb/ada-typeprint.c b/gdb/ada-typeprint.c
new file mode 100644
index 00000000000..677356186b2
--- /dev/null
+++ b/gdb/ada-typeprint.c
@@ -0,0 +1,896 @@
+/* Support for printing Ada types for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1991, 1997 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "defs.h"
+#include "obstack.h"
+#include "bfd.h" /* Binary File Description */
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "language.h"
+#include "demangle.h"
+#include "c-lang.h"
+#include "typeprint.h"
+#include "ada-lang.h"
+
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+
+static int print_record_field_types (struct type *, struct type *,
+ struct ui_file *, int, int);
+
+static void print_array_type (struct type*, struct ui_file*, int, int);
+
+static void print_choices (struct type*, int, struct ui_file*, struct type*);
+
+static void print_range (struct type*, struct ui_file*);
+
+static void print_range_bound (struct type*, char*, int*, struct ui_file*);
+
+static void
+print_dynamic_range_bound (struct type*, const char*, int,
+ const char*, struct ui_file*);
+
+static void print_range_type_named (char*, struct ui_file*);
+
+
+
+static char* name_buffer;
+static int name_buffer_len;
+
+/* The (demangled) Ada name of TYPE. This value persists until the
+ next call. */
+
+static char*
+demangled_type_name (type)
+ struct type *type;
+{
+ if (ada_type_name (type) == NULL)
+ return NULL;
+ else
+ {
+ char* raw_name = ada_type_name (type);
+ char *s, *q;
+
+ if (name_buffer == NULL || name_buffer_len <= strlen (raw_name))
+ {
+ name_buffer_len = 16 + 2 * strlen (raw_name);
+ name_buffer = xrealloc (name_buffer, name_buffer_len);
+ }
+ strcpy (name_buffer, raw_name);
+
+ s = (char*) strstr (name_buffer, "___");
+ if (s != NULL)
+ *s = '\0';
+
+ s = name_buffer + strlen (name_buffer) - 1;
+ while (s > name_buffer && (s[0] != '_' || s[-1] != '_'))
+ s -= 1;
+
+ if (s == name_buffer)
+ return name_buffer;
+
+ if (! islower (s[1]))
+ return NULL;
+
+ for (s = q = name_buffer; *s != '\0'; q += 1)
+ {
+ if (s[0] == '_' && s[1] == '_')
+ {
+ *q = '.'; s += 2;
+ }
+ else
+ {
+ *q = *s; s += 1;
+ }
+ }
+ *q = '\0';
+ return name_buffer;
+ }
+}
+
+
+/* Print a description of a type in the format of a
+ typedef for the current language.
+ NEW is the new name for a type TYPE. */
+
+void
+ada_typedef_print (type, new, stream)
+ struct type *type;
+ struct symbol *new;
+ struct ui_file *stream;
+{
+ fprintf_filtered (stream, "type %.*s is ",
+ ada_name_prefix_len (SYMBOL_SOURCE_NAME(new)),
+ SYMBOL_SOURCE_NAME(new));
+ type_print (type, "", stream, 1);
+}
+
+/* Print range type TYPE on STREAM. */
+
+static void
+print_range (type, stream)
+ struct type* type;
+ struct ui_file* stream;
+{
+ struct type* target_type;
+ target_type = TYPE_TARGET_TYPE (type);
+ if (target_type == NULL)
+ target_type = type;
+
+ switch (TYPE_CODE (target_type))
+ {
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_ENUM:
+ break;
+ default:
+ target_type = builtin_type_ada_int;
+ break;
+ }
+
+ if (TYPE_NFIELDS (type) < 2)
+ {
+ /* A range needs at least 2 bounds to be printed. If there are less
+ than 2, just print the type name instead of the range itself.
+ This check handles cases such as characters, for example.
+
+ Note that if the name is not defined, then we don't print anything.
+ */
+ fprintf_filtered (stream, "%.*s",
+ ada_name_prefix_len (TYPE_NAME (type)),
+ TYPE_NAME (type));
+ }
+ else
+ {
+ /* We extract the range type bounds respectively from the first element
+ and the last element of the type->fields array */
+ const LONGEST lower_bound = (LONGEST) TYPE_LOW_BOUND (type);
+ const LONGEST upper_bound =
+ (LONGEST) TYPE_FIELD_BITPOS (type, TYPE_NFIELDS (type) -1);
+
+ ada_print_scalar (target_type, lower_bound, stream);
+ fprintf_filtered (stream, " .. ");
+ ada_print_scalar (target_type, upper_bound, stream);
+ }
+}
+
+/* Print the number or discriminant bound at BOUNDS+*N on STREAM, and
+ set *N past the bound and its delimiter, if any. */
+
+static void
+print_range_bound (type, bounds, n, stream)
+ struct type* type;
+ char* bounds;
+ int* n;
+ struct ui_file* stream;
+{
+ LONGEST B;
+ if (ada_scan_number (bounds, *n, &B, n))
+ {
+ ada_print_scalar (type, B, stream);
+ if (bounds[*n] == '_')
+ *n += 2;
+ }
+ else
+ {
+ int bound_len;
+ char* bound = bounds + *n;
+ char* pend;
+
+ pend = strstr (bound, "__");
+ if (pend == NULL)
+ *n += bound_len = strlen (bound);
+ else
+ {
+ bound_len = pend - bound;
+ *n += bound_len + 2;
+ }
+ fprintf_filtered (stream, "%.*s", bound_len, bound);
+ }
+}
+
+/* Assuming NAME[0 .. NAME_LEN-1] is the name of a range type, print
+ the value (if found) of the bound indicated by SUFFIX ("___L" or
+ "___U") according to the ___XD conventions. */
+
+static void
+print_dynamic_range_bound (type, name, name_len, suffix, stream)
+ struct type* type;
+ const char* name;
+ int name_len;
+ const char* suffix;
+ struct ui_file* stream;
+{
+ static char *name_buf = NULL;
+ static size_t name_buf_len = 0;
+ LONGEST B;
+ int OK;
+
+ GROW_VECT (name_buf, name_buf_len, name_len + strlen (suffix) + 1);
+ strncpy (name_buf, name, name_len);
+ strcpy (name_buf + name_len, suffix);
+
+ B = get_int_var_value (name_buf, 0, &OK);
+ if (OK)
+ ada_print_scalar (type, B, stream);
+ else
+ fprintf_filtered (stream, "?");
+}
+
+/* Print the range type named NAME. */
+
+static void
+print_range_type_named (name, stream)
+ char* name;
+ struct ui_file* stream;
+{
+ struct type *raw_type = ada_find_any_type (name);
+ struct type *base_type;
+ LONGEST low, high;
+ char* subtype_info;
+
+ if (raw_type == NULL)
+ base_type = builtin_type_int;
+ else if (TYPE_CODE (raw_type) == TYPE_CODE_RANGE)
+ base_type = TYPE_TARGET_TYPE (raw_type);
+ else
+ base_type = raw_type;
+
+ subtype_info = strstr (name, "___XD");
+ if (subtype_info == NULL && raw_type == NULL)
+ fprintf_filtered (stream, "? .. ?");
+ else if (subtype_info == NULL)
+ print_range (raw_type, stream);
+ else
+ {
+ int prefix_len = subtype_info - name;
+ char *bounds_str;
+ int n;
+
+ subtype_info += 5;
+ bounds_str = strchr (subtype_info, '_');
+ n = 1;
+
+ if (*subtype_info == 'L')
+ {
+ print_range_bound (raw_type, bounds_str, &n, stream);
+ subtype_info += 1;
+ }
+ else
+ print_dynamic_range_bound (raw_type, name, prefix_len, "___L", stream);
+
+ fprintf_filtered (stream, " .. ");
+
+ if (*subtype_info == 'U')
+ print_range_bound (raw_type, bounds_str, &n, stream);
+ else
+ print_dynamic_range_bound (raw_type, name, prefix_len, "___U", stream);
+ }
+}
+
+/* Print enumerated type TYPE on STREAM. */
+
+static void
+print_enum_type (type, stream)
+ struct type *type;
+ struct ui_file *stream;
+{
+ int len = TYPE_NFIELDS (type);
+ int i, lastval;
+
+ fprintf_filtered (stream, "(");
+ wrap_here (" ");
+
+ lastval = 0;
+ for (i = 0; i < len; i++)
+ {
+ QUIT;
+ if (i) fprintf_filtered (stream, ", ");
+ wrap_here (" ");
+ fputs_filtered (ada_enum_name (TYPE_FIELD_NAME (type, i)), stream);
+ if (lastval != TYPE_FIELD_BITPOS (type, i))
+ {
+ fprintf_filtered (stream, " => %d", TYPE_FIELD_BITPOS (type, i));
+ lastval = TYPE_FIELD_BITPOS (type, i);
+ }
+ lastval += 1;
+ }
+ fprintf_filtered (stream, ")");
+}
+
+/* Print representation of Ada fixed-point type TYPE on STREAM. */
+
+static void
+print_fixed_point_type (type, stream)
+ struct type *type;
+ struct ui_file *stream;
+{
+ DOUBLEST delta = ada_delta (type);
+ DOUBLEST small = ada_fixed_to_float (type, 1.0);
+
+ if (delta < 0.0)
+ fprintf_filtered (stream, "delta ??");
+ else
+ {
+ fprintf_filtered (stream, "delta %g", (double) delta);
+ if (delta != small)
+ fprintf_filtered (stream, " <'small = %g>", (double) small);
+ }
+}
+
+/* Print representation of special VAX floating-point type TYPE on STREAM. */
+
+static void
+print_vax_floating_point_type (type, stream)
+ struct type *type;
+ struct ui_file *stream;
+{
+ fprintf_filtered (stream, "<float format %c>",
+ ada_vax_float_type_suffix (type));
+}
+
+/* Print simple (constrained) array type TYPE on STREAM. LEVEL is the
+ recursion (indentation) level, in case the element type itself has
+ nested structure, and SHOW is the number of levels of internal
+ structure to show (see ada_print_type). */
+
+static void
+print_array_type (type, stream, show, level)
+ struct type *type;
+ struct ui_file *stream;
+ int show;
+ int level;
+{
+ int bitsize;
+ int n_indices;
+
+ bitsize = 0;
+ fprintf_filtered (stream, "array (");
+
+ n_indices = -1;
+ if (show < 0)
+ fprintf_filtered (stream, "...");
+ else
+ {
+ if (ada_is_packed_array_type (type))
+ type = ada_coerce_to_simple_array_type (type);
+ if (ada_is_simple_array (type))
+ {
+ struct type* range_desc_type =
+ ada_find_parallel_type (type, "___XA");
+ struct type* arr_type;
+
+ bitsize = 0;
+ if (range_desc_type == NULL)
+ {
+ for (arr_type = type; TYPE_CODE (arr_type) == TYPE_CODE_ARRAY;
+ arr_type = TYPE_TARGET_TYPE (arr_type))
+ {
+ if (arr_type != type)
+ fprintf_filtered (stream, ", ");
+ print_range (TYPE_INDEX_TYPE (arr_type), stream);
+ if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0)
+ bitsize = TYPE_FIELD_BITSIZE (arr_type, 0);
+ }
+ }
+ else
+ {
+ int k;
+ n_indices = TYPE_NFIELDS (range_desc_type);
+ for (k = 0, arr_type = type;
+ k < n_indices;
+ k += 1, arr_type = TYPE_TARGET_TYPE (arr_type))
+ {
+ if (k > 0)
+ fprintf_filtered (stream, ", ");
+ print_range_type_named (TYPE_FIELD_NAME (range_desc_type, k),
+ stream);
+ if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0)
+ bitsize = TYPE_FIELD_BITSIZE (arr_type, 0);
+ }
+ }
+ }
+ else
+ {
+ int i, i0;
+ for (i = i0 = ada_array_arity (type); i > 0; i -= 1)
+ fprintf_filtered (stream, "%s<>", i == i0 ? "" : ", ");
+ }
+ }
+
+ fprintf_filtered (stream, ") of ");
+ wrap_here ("");
+ ada_print_type (ada_array_element_type (type, n_indices), "", stream,
+ show == 0 ? 0 : show-1, level+1);
+ if (bitsize > 0)
+ fprintf_filtered (stream, " <packed: %d-bit elements>", bitsize);
+}
+
+/* Print the choices encoded by field FIELD_NUM of variant-part TYPE on
+ STREAM, assuming the VAL_TYPE is the type of the values. */
+
+static void
+print_choices (type, field_num, stream, val_type)
+ struct type *type;
+ int field_num;
+ struct ui_file *stream;
+ struct type *val_type;
+{
+ int have_output;
+ int p;
+ const char* name = TYPE_FIELD_NAME (type, field_num);
+
+ have_output = 0;
+
+ /* Skip over leading 'V': NOTE soon to be obsolete. */
+ if (name[0] == 'V')
+ {
+ if (! ada_scan_number (name, 1, NULL, &p))
+ goto Huh;
+ }
+ else
+ p = 0;
+
+ while (1)
+ {
+ switch (name[p])
+ {
+ default:
+ return;
+ case 'S':
+ case 'R':
+ case 'O':
+ if (have_output)
+ fprintf_filtered (stream, " | ");
+ have_output = 1;
+ break;
+ }
+
+ switch (name[p])
+ {
+ case 'S':
+ {
+ LONGEST W;
+ if (! ada_scan_number (name, p + 1, &W, &p))
+ goto Huh;
+ ada_print_scalar (val_type, W, stream);
+ break;
+ }
+ case 'R':
+ {
+ LONGEST L, U;
+ if (! ada_scan_number (name, p + 1, &L, &p)
+ || name[p] != 'T'
+ || ! ada_scan_number (name, p + 1, &U, &p))
+ goto Huh;
+ ada_print_scalar (val_type, L, stream);
+ fprintf_filtered (stream, " .. ");
+ ada_print_scalar (val_type, U, stream);
+ break;
+ }
+ case 'O':
+ fprintf_filtered (stream, "others");
+ p += 1;
+ break;
+ }
+ }
+
+Huh:
+ fprintf_filtered (stream, "??");
+
+}
+
+/* Assuming that field FIELD_NUM of TYPE is a VARIANTS field whose
+ discriminant is contained in OUTER_TYPE, print its variants on STREAM.
+ LEVEL is the recursion
+ (indentation) level, in case any of the fields themselves have
+ nested structure, and SHOW is the number of levels of internal structure
+ to show (see ada_print_type). For this purpose, fields nested in a
+ variant part are taken to be at the same level as the fields
+ immediately outside the variant part. */
+
+static void
+print_variant_clauses (type, field_num, outer_type, stream, show, level)
+ struct type *type;
+ int field_num;
+ struct type *outer_type;
+ struct ui_file *stream;
+ int show;
+ int level;
+{
+ int i;
+ struct type *var_type;
+ struct type *discr_type;
+
+ var_type = TYPE_FIELD_TYPE (type, field_num);
+ discr_type = ada_variant_discrim_type (var_type, outer_type);
+
+ if (TYPE_CODE (var_type) == TYPE_CODE_PTR)
+ {
+ var_type = TYPE_TARGET_TYPE (var_type);
+ if (TYPE_FLAGS (var_type) & TYPE_FLAG_STUB)
+ {
+ var_type = ada_find_parallel_type (var_type, "___XVU");
+ if (var_type == NULL)
+ return;
+ }
+ }
+
+ for (i = 0; i < TYPE_NFIELDS (var_type); i += 1)
+ {
+ fprintf_filtered (stream, "\n%*swhen ", level + 4, "");
+ print_choices (var_type, i, stream, discr_type);
+ fprintf_filtered (stream, " =>");
+ if (print_record_field_types (TYPE_FIELD_TYPE (var_type, i),
+ outer_type, stream, show, level+4) <= 0)
+ fprintf_filtered (stream, " null;");
+ }
+}
+
+/* Assuming that field FIELD_NUM of TYPE is a variant part whose
+ discriminants are contained in OUTER_TYPE, print a description of it
+ on STREAM. LEVEL is the recursion (indentation) level, in case any of
+ the fields themselves have nested structure, and SHOW is the number of
+ levels of internal structure to show (see ada_print_type). For this
+ purpose, fields nested in a variant part are taken to be at the same
+ level as the fields immediately outside the variant part. */
+
+static void
+print_variant_part (type, field_num, outer_type, stream, show, level)
+ struct type *type;
+ int field_num;
+ struct type *outer_type;
+ struct ui_file *stream;
+ int show;
+ int level;
+{
+ fprintf_filtered (stream, "\n%*scase %s is", level + 4, "",
+ ada_variant_discrim_name
+ (TYPE_FIELD_TYPE (type, field_num)));
+ print_variant_clauses (type, field_num, outer_type, stream, show, level + 4);
+ fprintf_filtered (stream, "\n%*send case;", level + 4, "");
+}
+
+/* Print a description on STREAM of the fields in record type TYPE, whose
+ discriminants are in OUTER_TYPE. LEVEL is the recursion (indentation)
+ level, in case any of the fields themselves have nested structure,
+ and SHOW is the number of levels of internal structure to show
+ (see ada_print_type). Does not print parent type information of TYPE.
+ Returns 0 if no fields printed, -1 for an incomplete type, else > 0.
+ Prints each field beginning on a new line, but does not put a new line at
+ end. */
+
+static int
+print_record_field_types (type, outer_type, stream, show, level)
+ struct type *type;
+ struct type *outer_type;
+ struct ui_file *stream;
+ int show;
+ int level;
+{
+ int len, i, flds;
+
+ flds = 0;
+ len = TYPE_NFIELDS (type);
+
+ if (len == 0 && (TYPE_FLAGS (type) & TYPE_FLAG_STUB) != 0)
+ return -1;
+
+ for (i = 0; i < len; i += 1)
+ {
+ QUIT;
+
+ if (ada_is_parent_field (type, i)
+ || ada_is_ignored_field (type, i))
+ ;
+ else if (ada_is_wrapper_field (type, i))
+ flds += print_record_field_types (TYPE_FIELD_TYPE (type, i), type,
+ stream, show, level);
+ else if (ada_is_variant_part (type, i))
+ {
+ print_variant_part (type, i, outer_type, stream, show, level);
+ flds = 1;
+ }
+ else
+ {
+ flds += 1;
+ fprintf_filtered (stream, "\n%*s", level + 4, "");
+ ada_print_type (TYPE_FIELD_TYPE (type, i),
+ TYPE_FIELD_NAME (type, i),
+ stream, show - 1, level + 4);
+ fprintf_filtered (stream, ";");
+ }
+ }
+
+ return flds;
+}
+
+/* Print record type TYPE on STREAM. LEVEL is the recursion (indentation)
+ level, in case the element type itself has nested structure, and SHOW is
+ the number of levels of internal structure to show (see ada_print_type). */
+
+static void
+print_record_type (type0, stream, show, level)
+ struct type* type0;
+ struct ui_file* stream;
+ int show;
+ int level;
+{
+ struct type* parent_type;
+ struct type* type;
+
+ type = type0;
+ if (TYPE_FLAGS (type) & TYPE_FLAG_STUB)
+ {
+ struct type* type1 = ada_find_parallel_type (type, "___XVE");
+ if (type1 != NULL)
+ type = type1;
+ }
+
+ parent_type = ada_parent_type (type);
+ if (ada_type_name (parent_type) != NULL)
+ fprintf_filtered (stream, "new %s with ",
+ demangled_type_name (parent_type));
+ else if (parent_type == NULL && ada_is_tagged_type (type))
+ fprintf_filtered (stream, "tagged ");
+
+ fprintf_filtered (stream, "record");
+
+ if (show < 0)
+ fprintf_filtered (stream, " ... end record");
+ else
+ {
+ int flds;
+
+ flds = 0;
+ if (parent_type != NULL && ada_type_name (parent_type) == NULL)
+ flds += print_record_field_types (parent_type, parent_type,
+ stream, show, level);
+ flds += print_record_field_types (type, type, stream, show, level);
+
+ if (flds > 0)
+ fprintf_filtered (stream, "\n%*send record", level, "");
+ else if (flds < 0)
+ fprintf_filtered (stream, " <incomplete type> end record");
+ else
+ fprintf_filtered (stream, " null; end record");
+ }
+}
+
+/* Print the unchecked union type TYPE in something resembling Ada
+ format on STREAM. LEVEL is the recursion (indentation) level
+ in case the element type itself has nested structure, and SHOW is the
+ number of levels of internal structure to show (see ada_print_type). */
+static void
+print_unchecked_union_type (struct type* type, struct ui_file* stream,
+ int show, int level)
+{
+ fprintf_filtered (stream, "record (?) is");
+
+ if (show < 0)
+ fprintf_filtered (stream, " ... end record");
+ else if (TYPE_NFIELDS (type) == 0)
+ fprintf_filtered (stream, " null; end record");
+ else
+ {
+ int i;
+
+ fprintf_filtered (stream, "\n%*scase ? is",
+ level+4, "");
+
+ for (i = 0; i < TYPE_NFIELDS (type); i += 1)
+ {
+ fprintf_filtered (stream, "\n%*swhen ? =>\n%*s", level+8, "",
+ level+12, "");
+ ada_print_type (TYPE_FIELD_TYPE (type, i),
+ TYPE_FIELD_NAME (type, i),
+ stream, show - 1, level + 12);
+ fprintf_filtered (stream, ";");
+ }
+
+ fprintf_filtered (stream, "\n%*send case;\n%*send record",
+ level+4, "", level, "");
+ }
+}
+
+
+
+/* Print function or procedure type TYPE on STREAM. Make it a header
+ for function or procedure NAME if NAME is not null. */
+
+static void
+print_func_type (type, stream, name)
+ struct type *type;
+ struct ui_file *stream;
+ char* name;
+{
+ int i, len = TYPE_NFIELDS (type);
+
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID)
+ fprintf_filtered (stream, "procedure");
+ else
+ fprintf_filtered (stream, "function");
+
+ if (name != NULL && name[0] != '\0')
+ fprintf_filtered (stream, " %s", name);
+
+ if (len > 0)
+ {
+ fprintf_filtered (stream, " (");
+ for (i = 0; i < len; i += 1)
+ {
+ if (i > 0)
+ {
+ fputs_filtered ("; ", stream);
+ wrap_here (" ");
+ }
+ fprintf_filtered (stream, "a%d: ", i+1);
+ ada_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
+ }
+ fprintf_filtered (stream, ")");
+ }
+
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+ {
+ fprintf_filtered (stream, " return ");
+ ada_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, 0);
+ }
+}
+
+
+/* Print a description of a type TYPE0.
+ Output goes to STREAM (via stdio).
+ If VARSTRING is a non-empty string, print as an Ada variable/field
+ declaration.
+ SHOW+1 is the maximum number of levels of internal type structure
+ to show (this applies to record types, enumerated types, and
+ array types).
+ SHOW is the number of levels of internal type structure to show
+ when there is a type name for the SHOWth deepest level (0th is
+ outer level).
+ When SHOW<0, no inner structure is shown.
+ LEVEL indicates level of recursion (for nested definitions). */
+
+void
+ada_print_type (type0, varstring, stream, show, level)
+ struct type* type0;
+ char* varstring;
+ struct ui_file* stream;
+ int show;
+ int level;
+{
+ enum type_code code;
+ int demangled_args;
+ struct type* type = ada_completed_type (ada_get_base_type (type0));
+ char* type_name = demangled_type_name (type);
+ int is_var_decl = (varstring != NULL && varstring[0] != '\0');
+
+ if (type == NULL)
+ {
+ if (is_var_decl)
+ fprintf_filtered (stream, "%.*s: ",
+ ada_name_prefix_len(varstring),
+ varstring);
+ fprintf_filtered (stream, "<null type?>");
+ return;
+ }
+
+ if (show > 0)
+ CHECK_TYPEDEF (type);
+
+ if (is_var_decl && TYPE_CODE (type) != TYPE_CODE_FUNC)
+ fprintf_filtered (stream, "%.*s: ",
+ ada_name_prefix_len (varstring), varstring);
+
+ if (type_name != NULL && show <= 0)
+ {
+ fprintf_filtered (stream, "%.*s",
+ ada_name_prefix_len (type_name), type_name);
+ return;
+ }
+
+ if (ada_is_aligner_type (type))
+ ada_print_type (ada_aligned_type (type), "", stream, show, level);
+ else if (ada_is_packed_array_type (type))
+ print_array_type (type, stream, show, level);
+ else
+ switch (TYPE_CODE (type))
+ {
+ default:
+ fprintf_filtered (stream, "<");
+ c_print_type (type, "", stream, show, level);
+ fprintf_filtered (stream, ">");
+ break;
+ case TYPE_CODE_PTR:
+ fprintf_filtered (stream, "access ");
+ ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show,
+ level);
+ break;
+ case TYPE_CODE_REF:
+ fprintf_filtered (stream, "<ref> ");
+ ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show,
+ level);
+ break;
+ case TYPE_CODE_ARRAY:
+ print_array_type (type, stream, show, level);
+ break;
+ case TYPE_CODE_INT:
+ if (ada_is_fixed_point_type (type))
+ print_fixed_point_type (type, stream);
+ else if (ada_is_vax_floating_type (type))
+ print_vax_floating_point_type (type, stream);
+ else
+ {
+ char* name = ada_type_name (type);
+ if (! ada_is_range_type_name (name))
+ fprintf_filtered (stream, "<%d-byte integer>", TYPE_LENGTH (type));
+ else
+ {
+ fprintf_filtered (stream, "range ");
+ print_range_type_named (name, stream);
+ }
+ }
+ break;
+ case TYPE_CODE_RANGE:
+ if (ada_is_fixed_point_type (type))
+ print_fixed_point_type (type, stream);
+ else if (ada_is_vax_floating_type (type))
+ print_vax_floating_point_type (type, stream);
+ else if (ada_is_modular_type (type))
+ fprintf_filtered (stream, "mod %ld", (long) ada_modulus (type));
+ else
+ {
+ fprintf_filtered (stream, "range ");
+ print_range (type, stream);
+ }
+ break;
+ case TYPE_CODE_FLT:
+ fprintf_filtered (stream, "<%d-byte float>", TYPE_LENGTH (type));
+ break;
+ case TYPE_CODE_ENUM:
+ if (show < 0)
+ fprintf_filtered (stream, "(...)");
+ else
+ print_enum_type (type, stream);
+ break;
+ case TYPE_CODE_STRUCT:
+ if (ada_is_array_descriptor (type))
+ print_array_type (type, stream, show, level);
+ else if (ada_is_bogus_array_descriptor (type))
+ fprintf_filtered (stream, "array (?) of ? (<mal-formed descriptor>)");
+ else
+ print_record_type (type, stream, show, level);
+ break;
+ case TYPE_CODE_UNION:
+ print_unchecked_union_type (type, stream, show, level);
+ break;
+ case TYPE_CODE_FUNC:
+ print_func_type (type, stream, varstring);
+ break;
+ }
+}
diff --git a/gdb/ada-valprint.c b/gdb/ada-valprint.c
new file mode 100644
index 00000000000..6db18ebae1e
--- /dev/null
+++ b/gdb/ada-valprint.c
@@ -0,0 +1,1058 @@
+/* Support for printing Ada values for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1997, 2001
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <ctype.h>
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "demangle.h"
+#include "valprint.h"
+#include "language.h"
+#include "annotate.h"
+#include "ada-lang.h"
+#include "c-lang.h"
+
+/* Encapsulates arguments to ada_val_print. */
+struct ada_val_print_args {
+ struct type* type;
+ char* valaddr0;
+ int embedded_offset;
+ CORE_ADDR address;
+ struct ui_file *stream;
+ int format;
+ int deref_ref;
+ int recurse;
+ enum val_prettyprint pretty;
+};
+
+extern int inspect_it;
+extern unsigned int repeat_count_threshold;
+
+static void print_record (struct type*, char*, struct ui_file*, int,
+ int, enum val_prettyprint);
+
+static int print_field_values (struct type*, char*, struct ui_file*,
+ int, int, enum val_prettyprint,
+ int, struct type*, char*);
+
+static int print_variant_part (struct type*, int, char*,
+ struct ui_file*, int, int, enum val_prettyprint,
+ int, struct type*, char*);
+
+static void
+val_print_packed_array_elements (struct type*, char *valaddr, int,
+ struct ui_file*, int, int,
+ enum val_prettyprint);
+
+static void adjust_type_signedness (struct type*);
+
+static int ada_val_print_stub (PTR args0);
+
+static int
+ada_val_print_1 (struct type*, char*, int, CORE_ADDR, struct ui_file*,
+ int, int, int, enum val_prettyprint);
+
+
+/* Make TYPE unsigned if its range of values includes no negatives. */
+static void
+adjust_type_signedness (type)
+ struct type* type;
+{
+ if (type != NULL && TYPE_CODE (type) == TYPE_CODE_RANGE
+ && TYPE_LOW_BOUND (type) >= 0)
+ TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+}
+
+/* Assuming TYPE is a simple array type, prints its lower bound on STREAM,
+ if non-standard (i.e., other than 1 for numbers, other than lower bound
+ of index type for enumerated type). Returns 1 if something printed,
+ otherwise 0. */
+
+static int
+print_optional_low_bound (stream, type)
+ struct ui_file *stream;
+ struct type *type;
+{
+ struct type *index_type;
+ long low_bound;
+
+ index_type = TYPE_INDEX_TYPE (type);
+ low_bound = 0;
+
+ if (index_type == NULL)
+ return 0;
+ if (TYPE_CODE (index_type) == TYPE_CODE_RANGE)
+ {
+ low_bound = TYPE_LOW_BOUND (index_type);
+ index_type = TYPE_TARGET_TYPE (index_type);
+ }
+ else
+ return 0;
+
+ switch (TYPE_CODE (index_type)) {
+ case TYPE_CODE_ENUM:
+ if (low_bound == TYPE_FIELD_BITPOS (index_type, 0))
+ return 0;
+ break;
+ case TYPE_CODE_UNDEF:
+ index_type = builtin_type_long;
+ /* FALL THROUGH */
+ default:
+ if (low_bound == 1)
+ return 0;
+ break;
+ }
+
+ ada_print_scalar (index_type, (LONGEST) low_bound, stream);
+ fprintf_filtered (stream, " => ");
+ return 1;
+}
+
+/* Version of val_print_array_elements for GNAT-style packed arrays.
+ Prints elements of packed array of type TYPE at bit offset
+ BITOFFSET from VALADDR on STREAM. Formats according to FORMAT and
+ separates with commas. RECURSE is the recursion (nesting) level.
+ If PRETTY, uses "prettier" format. TYPE must have been decoded (as
+ by ada_coerce_to_simple_array). */
+
+static void
+val_print_packed_array_elements (type, valaddr, bitoffset, stream, format,
+ recurse, pretty)
+ struct type *type;
+ char *valaddr;
+ int bitoffset;
+ struct ui_file *stream;
+ int format;
+ int recurse;
+ enum val_prettyprint pretty;
+{
+ unsigned int i;
+ unsigned int things_printed = 0;
+ unsigned len;
+ struct type *elttype;
+ unsigned eltlen;
+ /* Position of the array element we are examining to see
+ whether it is repeated. */
+ unsigned int rep1;
+ /* Number of repetitions we have detected so far. */
+ unsigned int reps;
+ unsigned long bitsize = TYPE_FIELD_BITSIZE (type, 0);
+ struct value* mark = value_mark ();
+
+ elttype = TYPE_TARGET_TYPE (type);
+ eltlen = TYPE_LENGTH (check_typedef (elttype));
+
+ {
+ LONGEST low, high;
+ if (get_discrete_bounds (TYPE_FIELD_TYPE (type, 0), &low, &high) < 0)
+ len = 1;
+ else
+ len = high - low + 1;
+ }
+
+ i = 0;
+ annotate_array_section_begin (i, elttype);
+
+ while (i < len && things_printed < print_max)
+ {
+ struct value *v0, *v1;
+ int i0;
+
+ if (i != 0)
+ {
+ if (prettyprint_arrays)
+ {
+ fprintf_filtered (stream, ",\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ else
+ {
+ fprintf_filtered (stream, ", ");
+ }
+ }
+ wrap_here (n_spaces (2 + 2 * recurse));
+
+ i0 = i;
+ v0 = ada_value_primitive_packed_val (NULL, valaddr,
+ (i0 * bitsize) / HOST_CHAR_BIT,
+ (i0 * bitsize) % HOST_CHAR_BIT,
+ bitsize, elttype);
+ while (1)
+ {
+ i += 1;
+ if (i >= len)
+ break;
+ v1 = ada_value_primitive_packed_val (NULL, valaddr,
+ (i * bitsize) / HOST_CHAR_BIT,
+ (i * bitsize) % HOST_CHAR_BIT,
+ bitsize, elttype);
+ if (memcmp (VALUE_CONTENTS (v0), VALUE_CONTENTS (v1), eltlen)
+ != 0)
+ break;
+ }
+
+ if (i - i0 > repeat_count_threshold)
+ {
+ val_print (elttype, VALUE_CONTENTS (v0), 0, 0, stream, format,
+ 0, recurse + 1, pretty);
+ annotate_elt_rep (i - i0);
+ fprintf_filtered (stream, " <repeats %u times>", i - i0);
+ annotate_elt_rep_end ();
+
+ }
+ else
+ {
+ int j;
+ for (j = i0; j < i; j += 1)
+ {
+ if (j > i0)
+ {
+ if (prettyprint_arrays)
+ {
+ fprintf_filtered (stream, ",\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ else
+ {
+ fprintf_filtered (stream, ", ");
+ }
+ wrap_here (n_spaces (2 + 2 * recurse));
+ }
+ val_print (elttype, VALUE_CONTENTS (v0), 0, 0, stream, format,
+ 0, recurse + 1, pretty);
+ annotate_elt ();
+ }
+ }
+ things_printed += i - i0;
+ }
+ annotate_array_section_end ();
+ if (i < len)
+ {
+ fprintf_filtered (stream, "...");
+ }
+
+ value_free_to_mark (mark);
+}
+
+static struct type*
+printable_val_type (type, valaddr)
+ struct type* type;
+ char* valaddr;
+{
+ return ada_to_fixed_type (ada_aligned_type (type), valaddr, 0, NULL);
+}
+
+/* Print the character C on STREAM as part of the contents of a literal
+ string whose delimiter is QUOTER. TYPE_LEN is the length in bytes
+ (1 or 2) of the character. */
+
+void
+ada_emit_char (c, stream, quoter, type_len)
+ int c;
+ struct ui_file *stream;
+ int quoter;
+ int type_len;
+{
+ if (type_len != 2)
+ type_len = 1;
+
+ c &= (1 << (type_len * TARGET_CHAR_BIT)) - 1;
+
+ if (isascii (c) && isprint (c))
+ {
+ if (c == quoter && c == '"')
+ fprintf_filtered (stream, "[\"%c\"]", quoter);
+ else
+ fprintf_filtered (stream, "%c", c);
+ }
+ else
+ fprintf_filtered (stream, "[\"%0*x\"]", type_len*2, c);
+}
+
+/* Character #I of STRING, given that TYPE_LEN is the size in bytes (1
+ or 2) of a character. */
+
+static int
+char_at (string, i, type_len)
+ char* string;
+ int i;
+ int type_len;
+{
+ if (type_len == 1)
+ return string[i];
+ else
+ return (int) extract_unsigned_integer (string + 2*i, 2);
+}
+
+void
+ada_printchar (c, stream)
+ int c;
+ struct ui_file *stream;
+{
+ fputs_filtered ("'", stream);
+ ada_emit_char (c, stream, '\'', 1);
+ fputs_filtered ("'", stream);
+}
+
+/* [From print_type_scalar in typeprint.c]. Print VAL on STREAM in a
+ form appropriate for TYPE. */
+
+void
+ada_print_scalar (type, val, stream)
+ struct type *type;
+ LONGEST val;
+ struct ui_file *stream;
+{
+ unsigned int i;
+ unsigned len;
+
+ CHECK_TYPEDEF (type);
+
+ switch (TYPE_CODE (type))
+ {
+
+ case TYPE_CODE_ENUM:
+ len = TYPE_NFIELDS (type);
+ for (i = 0; i < len; i++)
+ {
+ if (TYPE_FIELD_BITPOS (type, i) == val)
+ {
+ break;
+ }
+ }
+ if (i < len)
+ {
+ fputs_filtered (ada_enum_name (TYPE_FIELD_NAME (type, i)), stream);
+ }
+ else
+ {
+ print_longest (stream, 'd', 0, val);
+ }
+ break;
+
+ case TYPE_CODE_INT:
+ print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0, val);
+ break;
+
+ case TYPE_CODE_CHAR:
+ LA_PRINT_CHAR ((unsigned char) val, stream);
+ break;
+
+ case TYPE_CODE_BOOL:
+ fprintf_filtered (stream, val ? "true" : "false");
+ break;
+
+ case TYPE_CODE_RANGE:
+ ada_print_scalar (TYPE_TARGET_TYPE (type), val, stream);
+ return;
+
+ case TYPE_CODE_UNDEF:
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_FUNC:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_SET:
+ case TYPE_CODE_STRING:
+ case TYPE_CODE_ERROR:
+ case TYPE_CODE_MEMBER:
+ case TYPE_CODE_METHOD:
+ case TYPE_CODE_REF:
+ warning ("internal error: unhandled type in ada_print_scalar");
+ break;
+
+ default:
+ error ("Invalid type code in symbol table.");
+ }
+ gdb_flush (stream);
+}
+
+/* Print the character string STRING, printing at most LENGTH characters.
+ Printing stops early if the number hits print_max; repeat counts
+ are printed as appropriate. Print ellipses at the end if we
+ had to stop before printing LENGTH characters, or if
+ FORCE_ELLIPSES. TYPE_LEN is the length (1 or 2) of the character type.
+ */
+
+static void
+printstr (stream, string, length, force_ellipses, type_len)
+ struct ui_file *stream;
+ char *string;
+ unsigned int length;
+ int force_ellipses;
+ int type_len;
+{
+ unsigned int i;
+ unsigned int things_printed = 0;
+ int in_quotes = 0;
+ int need_comma = 0;
+
+ if (length == 0)
+ {
+ fputs_filtered ("\"\"", stream);
+ return;
+ }
+
+ for (i = 0; i < length && things_printed < print_max; i += 1)
+ {
+ /* Position of the character we are examining
+ to see whether it is repeated. */
+ unsigned int rep1;
+ /* Number of repetitions we have detected so far. */
+ unsigned int reps;
+
+ QUIT;
+
+ if (need_comma)
+ {
+ fputs_filtered (", ", stream);
+ need_comma = 0;
+ }
+
+ rep1 = i + 1;
+ reps = 1;
+ while (rep1 < length &&
+ char_at(string, rep1, type_len) == char_at (string, i, type_len))
+ {
+ rep1 += 1;
+ reps += 1;
+ }
+
+ if (reps > repeat_count_threshold)
+ {
+ if (in_quotes)
+ {
+ if (inspect_it)
+ fputs_filtered ("\\\", ", stream);
+ else
+ fputs_filtered ("\", ", stream);
+ in_quotes = 0;
+ }
+ fputs_filtered ("'", stream);
+ ada_emit_char (char_at (string, i, type_len), stream, '\'', type_len);
+ fputs_filtered ("'", stream);
+ fprintf_filtered (stream, " <repeats %u times>", reps);
+ i = rep1 - 1;
+ things_printed += repeat_count_threshold;
+ need_comma = 1;
+ }
+ else
+ {
+ if (!in_quotes)
+ {
+ if (inspect_it)
+ fputs_filtered ("\\\"", stream);
+ else
+ fputs_filtered ("\"", stream);
+ in_quotes = 1;
+ }
+ ada_emit_char (char_at (string, i, type_len), stream, '"',
+ type_len);
+ things_printed += 1;
+ }
+ }
+
+ /* Terminate the quotes if necessary. */
+ if (in_quotes)
+ {
+ if (inspect_it)
+ fputs_filtered ("\\\"", stream);
+ else
+ fputs_filtered ("\"", stream);
+ }
+
+ if (force_ellipses || i < length)
+ fputs_filtered ("...", stream);
+}
+
+void
+ada_printstr (stream, string, length, force_ellipses, width)
+ struct ui_file *stream;
+ char *string;
+ unsigned int length;
+ int force_ellipses;
+ int width;
+{
+ printstr (stream, string, length, force_ellipses, width);
+}
+
+
+/* Print data of type TYPE located at VALADDR (within GDB), which came from
+ the inferior at address ADDRESS, onto stdio stream STREAM according to
+ FORMAT (a letter as for the printf % codes or 0 for natural format).
+ The data at VALADDR is in target byte order.
+
+ If the data is printed as a string, returns the number of string characters
+ printed.
+
+ If DEREF_REF is nonzero, then dereference references, otherwise just print
+ them like pointers.
+
+ RECURSE indicates the amount of indentation to supply before
+ continuation lines; this amount is roughly twice the value of RECURSE.
+
+ When PRETTY is non-zero, prints record fields on separate lines.
+ (For some reason, the current version of gdb instead uses a global
+ variable---prettyprint_arrays--- to causes a similar effect on
+ arrays.) */
+
+int
+ada_val_print (type, valaddr0, embedded_offset, address, stream,
+ format, deref_ref, recurse, pretty)
+ struct type* type;
+ char* valaddr0;
+ int embedded_offset;
+ CORE_ADDR address;
+ struct ui_file *stream;
+ int format;
+ int deref_ref;
+ int recurse;
+ enum val_prettyprint pretty;
+{
+ struct ada_val_print_args args;
+ args.type = type; args.valaddr0 = valaddr0;
+ args.embedded_offset = embedded_offset;
+ args.address = address;
+ args.stream = stream;
+ args.format = format;
+ args.deref_ref = deref_ref;
+ args.recurse = recurse;
+ args.pretty = pretty;
+
+ return catch_errors (ada_val_print_stub, &args, NULL, RETURN_MASK_ALL);
+}
+
+/* Helper for ada_val_print; used as argument to catch_errors to
+ unmarshal the arguments to ada_val_print_1, which does the work. */
+static int
+ada_val_print_stub (PTR args0)
+{
+ struct ada_val_print_args* argsp = (struct ada_val_print_args*) args0;
+ return ada_val_print_1 (argsp->type, argsp->valaddr0, argsp->embedded_offset,
+ argsp->address, argsp->stream, argsp->format,
+ argsp->deref_ref, argsp->recurse,
+ argsp->pretty);
+}
+
+/* See the comment on ada_val_print. This function differs in that it
+ * does not catch evaluation errors (leaving that to ada_val_print). */
+
+static int
+ada_val_print_1 (type, valaddr0, embedded_offset, address, stream,
+ format, deref_ref, recurse, pretty)
+ struct type* type;
+ char* valaddr0;
+ int embedded_offset;
+ CORE_ADDR address;
+ struct ui_file *stream;
+ int format;
+ int deref_ref;
+ int recurse;
+ enum val_prettyprint pretty;
+{
+ unsigned int len;
+ int i;
+ struct type *elttype;
+ unsigned int eltlen;
+ LONGEST val;
+ CORE_ADDR addr;
+ char* valaddr = valaddr0 + embedded_offset;
+
+ CHECK_TYPEDEF (type);
+
+ if (ada_is_array_descriptor (type) || ada_is_packed_array_type (type))
+ {
+ int retn;
+ struct value* mark = value_mark ();
+ struct value* val;
+ val = value_from_contents_and_address (type, valaddr, address);
+ val = ada_coerce_to_simple_array_ptr (val);
+ if (val == NULL)
+ {
+ fprintf_filtered (stream, "(null)");
+ retn = 0;
+ }
+ else
+ retn = ada_val_print_1 (VALUE_TYPE (val), VALUE_CONTENTS (val), 0,
+ VALUE_ADDRESS (val), stream, format,
+ deref_ref, recurse, pretty);
+ value_free_to_mark (mark);
+ return retn;
+ }
+
+ valaddr = ada_aligned_value_addr (type, valaddr);
+ embedded_offset -= valaddr - valaddr0 - embedded_offset;
+ type = printable_val_type (type, valaddr);
+
+ switch (TYPE_CODE (type))
+ {
+ default:
+ return c_val_print (type, valaddr0, embedded_offset, address, stream,
+ format, deref_ref, recurse, pretty);
+
+ case TYPE_CODE_INT:
+ case TYPE_CODE_RANGE:
+ if (ada_is_fixed_point_type (type))
+ {
+ LONGEST v = unpack_long (type, valaddr);
+ int len = TYPE_LENGTH (type);
+
+ fprintf_filtered (stream, len < 4 ? "%.11g" : "%.17g",
+ (double) ada_fixed_to_float (type, v));
+ return 0;
+ }
+ else if (ada_is_vax_floating_type (type))
+ {
+ struct value* val =
+ value_from_contents_and_address (type, valaddr, address);
+ struct value* func = ada_vax_float_print_function (type);
+ if (func != 0)
+ {
+ static struct type* parray_of_char = NULL;
+ struct value* printable_val;
+
+ if (parray_of_char == NULL)
+ parray_of_char =
+ make_pointer_type
+ (create_array_type
+ (NULL, builtin_type_char,
+ create_range_type (NULL, builtin_type_int, 0, 32)),
+ NULL);
+
+ printable_val =
+ value_ind (value_cast (parray_of_char,
+ call_function_by_hand (func, 1, &val)));
+
+ fprintf_filtered (stream, "%s", VALUE_CONTENTS (printable_val));
+ return 0;
+ }
+ /* No special printing function. Do as best we can. */
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
+ {
+ struct type* target_type = TYPE_TARGET_TYPE (type);
+ if (TYPE_LENGTH (type) != TYPE_LENGTH (target_type))
+ {
+ /* Obscure case of range type that has different length from
+ its base type. Perform a conversion, or we will get a
+ nonsense value. Actually, we could use the same
+ code regardless of lengths; I'm just avoiding a cast. */
+ struct value* v =
+ value_cast (target_type,
+ value_from_contents_and_address (type, valaddr, 0));
+ return ada_val_print_1 (target_type, VALUE_CONTENTS (v), 0, 0,
+ stream, format, 0, recurse + 1, pretty);
+ }
+ else
+ return ada_val_print_1 (TYPE_TARGET_TYPE (type),
+ valaddr0, embedded_offset,
+ address, stream, format, deref_ref,
+ recurse, pretty);
+ }
+ else
+ {
+ format = format ? format : output_format;
+ if (format)
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ }
+ else
+ {
+ val_print_type_code_int (type, valaddr, stream);
+ if (ada_is_character_type (type))
+ {
+ fputs_filtered (" ", stream);
+ ada_printchar ((unsigned char) unpack_long (type, valaddr),
+ stream);
+ }
+ }
+ return 0;
+ }
+
+ case TYPE_CODE_ENUM:
+ if (format)
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ break;
+ }
+ len = TYPE_NFIELDS (type);
+ val = unpack_long (type, valaddr);
+ for (i = 0; i < len; i++)
+ {
+ QUIT;
+ if (val == TYPE_FIELD_BITPOS (type, i))
+ {
+ break;
+ }
+ }
+ if (i < len)
+ {
+ const char* name = ada_enum_name (TYPE_FIELD_NAME (type, i));
+ if (name[0] == '\'')
+ fprintf_filtered (stream, "%ld %s", (long) val, name);
+ else
+ fputs_filtered (name, stream);
+ }
+ else
+ {
+ print_longest (stream, 'd', 0, val);
+ }
+ break;
+
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_STRUCT:
+ if (ada_is_bogus_array_descriptor (type))
+ {
+ fprintf_filtered (stream, "(...?)");
+ return 0;
+ }
+ else
+ {
+ print_record (type, valaddr, stream, format,
+ recurse, pretty);
+ return 0;
+ }
+
+ case TYPE_CODE_ARRAY:
+ if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
+ {
+ elttype = TYPE_TARGET_TYPE (type);
+ eltlen = TYPE_LENGTH (elttype);
+ len = TYPE_LENGTH (type) / eltlen;
+
+ /* For an array of chars, print with string syntax. */
+ if (ada_is_string_type (type)
+ && (format == 0 || format == 's'))
+ {
+ if (prettyprint_arrays)
+ {
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ /* If requested, look for the first null char and only print
+ elements up to it. */
+ if (stop_print_at_null)
+ {
+ int temp_len;
+
+ /* Look for a NULL char. */
+ for (temp_len = 0;
+ temp_len < len && temp_len < print_max
+ && char_at (valaddr, temp_len, eltlen) != 0;
+ temp_len += 1);
+ len = temp_len;
+ }
+
+ printstr (stream, valaddr, len, 0, eltlen);
+ }
+ else
+ {
+ len = 0;
+ fprintf_filtered (stream, "(");
+ print_optional_low_bound (stream, type);
+ if (TYPE_FIELD_BITSIZE (type, 0) > 0)
+ val_print_packed_array_elements (type, valaddr, 0, stream,
+ format, recurse,
+ pretty);
+ else
+ val_print_array_elements (type, valaddr, address, stream,
+ format, deref_ref, recurse,
+ pretty, 0);
+ fprintf_filtered (stream, ")");
+ }
+ gdb_flush (stream);
+ return len;
+ }
+
+ case TYPE_CODE_REF:
+ elttype = check_typedef (TYPE_TARGET_TYPE (type));
+ if (addressprint)
+ {
+ fprintf_filtered (stream, "@");
+ print_address_numeric
+ (extract_address (valaddr,
+ TARGET_PTR_BIT / HOST_CHAR_BIT), 1, stream);
+ if (deref_ref)
+ fputs_filtered (": ", stream);
+ }
+ /* De-reference the reference */
+ if (deref_ref)
+ {
+ if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
+ {
+ LONGEST deref_val_int = (LONGEST)
+ unpack_pointer (lookup_pointer_type (builtin_type_void),
+ valaddr);
+ if (deref_val_int != 0)
+ {
+ struct value* deref_val =
+ ada_value_ind (value_from_longest
+ (lookup_pointer_type (elttype),
+ deref_val_int));
+ val_print (VALUE_TYPE (deref_val),
+ VALUE_CONTENTS (deref_val), 0,
+ VALUE_ADDRESS (deref_val), stream, format,
+ deref_ref, recurse + 1, pretty);
+ }
+ else
+ fputs_filtered ("(null)", stream);
+ }
+ else
+ fputs_filtered ("???", stream);
+ }
+ break;
+ }
+ return 0;
+}
+
+static int
+print_variant_part (type, field_num, valaddr,
+ stream, format, recurse, pretty, comma_needed,
+ outer_type, outer_valaddr)
+ struct type *type;
+ int field_num;
+ char *valaddr;
+ struct ui_file *stream;
+ int format;
+ int recurse;
+ enum val_prettyprint pretty;
+ int comma_needed;
+ struct type *outer_type;
+ char *outer_valaddr;
+{
+ struct type *var_type = TYPE_FIELD_TYPE (type, field_num);
+ int which =
+ ada_which_variant_applies (var_type, outer_type, outer_valaddr);
+
+ if (which < 0)
+ return 0;
+ else
+ return print_field_values
+ (TYPE_FIELD_TYPE (var_type, which),
+ valaddr + TYPE_FIELD_BITPOS (type, field_num) / HOST_CHAR_BIT
+ + TYPE_FIELD_BITPOS (var_type, which) / HOST_CHAR_BIT,
+ stream, format, recurse, pretty,
+ comma_needed, outer_type, outer_valaddr);
+}
+
+int
+ada_value_print (val0, stream, format, pretty)
+ struct value* val0;
+ struct ui_file *stream;
+ int format;
+ enum val_prettyprint pretty;
+{
+ char* valaddr = VALUE_CONTENTS (val0);
+ CORE_ADDR address = VALUE_ADDRESS (val0) + VALUE_OFFSET (val0);
+ struct type* type =
+ ada_to_fixed_type (VALUE_TYPE (val0), valaddr, address, NULL);
+ struct value* val = value_from_contents_and_address (type, valaddr, address);
+
+ /* If it is a pointer, indicate what it points to. */
+ if (TYPE_CODE (type) == TYPE_CODE_PTR ||
+ TYPE_CODE (type) == TYPE_CODE_REF)
+ {
+ /* Hack: remove (char *) for char strings. Their
+ type is indicated by the quoted string anyway. */
+ if (TYPE_CODE (type) == TYPE_CODE_PTR &&
+ TYPE_LENGTH (TYPE_TARGET_TYPE (type)) == sizeof(char) &&
+ TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_INT &&
+ !TYPE_UNSIGNED (TYPE_TARGET_TYPE (type)))
+ {
+ /* Print nothing */
+ }
+ else
+ {
+ fprintf_filtered (stream, "(");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, ") ");
+ }
+ }
+ else if (ada_is_array_descriptor (type))
+ {
+ fprintf_filtered (stream, "(");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, ") ");
+ }
+ else if (ada_is_bogus_array_descriptor (type))
+ {
+ fprintf_filtered (stream, "(");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, ") (...?)");
+ return 0;
+ }
+ return (val_print (type, VALUE_CONTENTS (val), 0, address,
+ stream, format, 1, 0, pretty));
+}
+
+static void
+print_record (type, valaddr, stream, format, recurse, pretty)
+ struct type *type;
+ char *valaddr;
+ struct ui_file *stream;
+ int format;
+ int recurse;
+ enum val_prettyprint pretty;
+{
+ CHECK_TYPEDEF (type);
+
+ fprintf_filtered (stream, "(");
+
+ if (print_field_values (type, valaddr, stream, format, recurse, pretty,
+ 0, type, valaddr) != 0
+ && pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 * recurse, stream);
+ }
+
+ fprintf_filtered (stream, ")");
+}
+
+/* Print out fields of value at VALADDR having structure type TYPE.
+
+ TYPE, VALADDR, STREAM, FORMAT, RECURSE, and PRETTY have the
+ same meanings as in ada_print_value and ada_val_print.
+
+ OUTER_TYPE and OUTER_VALADDR give type and address of enclosing record
+ (used to get discriminant values when printing variant parts).
+
+ COMMA_NEEDED is 1 if fields have been printed at the current recursion
+ level, so that a comma is needed before any field printed by this
+ call.
+
+ Returns 1 if COMMA_NEEDED or any fields were printed. */
+
+static int
+print_field_values (type, valaddr, stream, format, recurse, pretty,
+ comma_needed, outer_type, outer_valaddr)
+ struct type *type;
+ char *valaddr;
+ struct ui_file *stream;
+ int format;
+ int recurse;
+ enum val_prettyprint pretty;
+ int comma_needed;
+ struct type *outer_type;
+ char *outer_valaddr;
+{
+ int i, len;
+
+ len = TYPE_NFIELDS (type);
+
+ for (i = 0; i < len; i += 1)
+ {
+ if (ada_is_ignored_field (type, i))
+ continue;
+
+ if (ada_is_wrapper_field (type, i))
+ {
+ comma_needed =
+ print_field_values (TYPE_FIELD_TYPE (type, i),
+ valaddr
+ + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT,
+ stream, format, recurse, pretty,
+ comma_needed, type, valaddr);
+ continue;
+ }
+ else if (ada_is_variant_part (type, i))
+ {
+ comma_needed =
+ print_variant_part (type, i, valaddr,
+ stream, format, recurse, pretty, comma_needed,
+ outer_type, outer_valaddr);
+ continue;
+ }
+
+ if (comma_needed)
+ fprintf_filtered (stream, ", ");
+ comma_needed = 1;
+
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ else
+ {
+ wrap_here (n_spaces (2 + 2 * recurse));
+ }
+ if (inspect_it)
+ {
+ if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)
+ fputs_filtered ("\"( ptr \"", stream);
+ else
+ fputs_filtered ("\"( nodef \"", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus, DMGL_NO_OPTS);
+ fputs_filtered ("\" \"", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus, DMGL_NO_OPTS);
+ fputs_filtered ("\") \"", stream);
+ }
+ else
+ {
+ annotate_field_begin (TYPE_FIELD_TYPE (type, i));
+ fprintf_filtered (stream, "%.*s",
+ ada_name_prefix_len (TYPE_FIELD_NAME (type, i)),
+ TYPE_FIELD_NAME (type, i));
+ annotate_field_name_end ();
+ fputs_filtered (" => ", stream);
+ annotate_field_value ();
+ }
+
+ if (TYPE_FIELD_PACKED (type, i))
+ {
+ struct value* v;
+
+ /* Bitfields require special handling, especially due to byte
+ order problems. */
+ if (TYPE_CPLUS_SPECIFIC (type) != NULL
+ && TYPE_FIELD_IGNORE (type, i))
+ {
+ fputs_filtered ("<optimized out or zero length>", stream);
+ }
+ else
+ {
+ int bit_pos = TYPE_FIELD_BITPOS (type, i);
+ int bit_size = TYPE_FIELD_BITSIZE (type, i);
+
+ adjust_type_signedness (TYPE_FIELD_TYPE (type, i));
+ v = ada_value_primitive_packed_val (NULL, valaddr,
+ bit_pos / HOST_CHAR_BIT,
+ bit_pos % HOST_CHAR_BIT,
+ bit_size,
+ TYPE_FIELD_TYPE (type, i));
+ val_print (TYPE_FIELD_TYPE(type, i), VALUE_CONTENTS (v), 0, 0,
+ stream, format, 0, recurse + 1, pretty);
+ }
+ }
+ else
+ ada_val_print (TYPE_FIELD_TYPE (type, i),
+ valaddr + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT,
+ 0, 0, stream, format, 0, recurse + 1, pretty);
+ annotate_field_end ();
+ }
+
+ return comma_needed;
+}
diff --git a/gdb/alpha-linux-tdep.c b/gdb/alpha-linux-tdep.c
new file mode 100644
index 00000000000..4596d37e327
--- /dev/null
+++ b/gdb/alpha-linux-tdep.c
@@ -0,0 +1,121 @@
+/* Target-dependent code for GNU/Linux on Alpha.
+ Copyright 2002 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 "defs.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "value.h"
+
+#include "alpha-tdep.h"
+
+/* Under GNU/Linux, signal handler invocations can be identified by the
+ designated code sequence that is used to return from a signal
+ handler. In particular, the return address of a signal handler
+ points to the following sequence (the first instruction is quadword
+ aligned):
+
+ bis $30,$30,$16
+ addq $31,0x67,$0
+ call_pal callsys
+
+ Each instruction has a unique encoding, so we simply attempt to
+ match the instruction the pc is pointing to with any of the above
+ instructions. If there is a hit, we know the offset to the start
+ of the designated sequence and can then check whether we really are
+ executing in a designated sequence. If not, -1 is returned,
+ otherwise the offset from the start of the desingated sequence is
+ returned.
+
+ There is a slight chance of false hits: code could jump into the
+ middle of the designated sequence, in which case there is no
+ guarantee that we are in the middle of a sigreturn syscall. Don't
+ think this will be a problem in praxis, though. */
+LONGEST
+alpha_linux_sigtramp_offset (CORE_ADDR pc)
+{
+ unsigned int i[3], w;
+ long off;
+
+ if (read_memory_nobpt (pc, (char *) &w, 4) != 0)
+ return -1;
+
+ off = -1;
+ switch (w)
+ {
+ case 0x47de0410:
+ off = 0;
+ break; /* bis $30,$30,$16 */
+ case 0x43ecf400:
+ off = 4;
+ break; /* addq $31,0x67,$0 */
+ case 0x00000083:
+ off = 8;
+ break; /* call_pal callsys */
+ default:
+ return -1;
+ }
+ pc -= off;
+ if (pc & 0x7)
+ {
+ /* designated sequence is not quadword aligned */
+ return -1;
+ }
+ if (read_memory_nobpt (pc, (char *) i, sizeof (i)) != 0)
+ return -1;
+
+ if (i[0] == 0x47de0410 && i[1] == 0x43ecf400 && i[2] == 0x00000083)
+ return off;
+
+ return -1;
+}
+
+static int
+alpha_linux_pc_in_sigtramp (CORE_ADDR pc, char *func_name)
+{
+ return (alpha_linux_sigtramp_offset (pc) >= 0);
+}
+
+static CORE_ADDR
+alpha_linux_sigcontext_addr (struct frame_info *frame)
+{
+ return (frame->frame - 0x298); /* sizeof(struct sigcontext) */
+}
+
+static void
+alpha_linux_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ set_gdbarch_pc_in_sigtramp (gdbarch, alpha_linux_pc_in_sigtramp);
+
+ tdep->dynamic_sigtramp_offset = alpha_linux_sigtramp_offset;
+ tdep->sigcontext_addr = alpha_linux_sigcontext_addr;
+
+ tdep->jb_pc = 2;
+ tdep->jb_elt_size = 8;
+}
+
+void
+_initialize_alpha_linux_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_alpha, GDB_OSABI_LINUX,
+ alpha_linux_init_abi);
+}
diff --git a/gdb/alpha-nat.c b/gdb/alpha-nat.c
new file mode 100644
index 00000000000..580dcc0e809
--- /dev/null
+++ b/gdb/alpha-nat.c
@@ -0,0 +1,278 @@
+/* Low level Alpha interface, for GDB when running native.
+ Copyright 1993, 1995, 1996, 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "regcache.h"
+
+#include "alpha-tdep.h"
+
+#include <sys/ptrace.h>
+#ifdef __linux__
+#include <asm/reg.h>
+#include <alpha/ptrace.h>
+#else
+#include <alpha/coreregs.h>
+#endif
+#include <sys/user.h>
+
+/* Prototypes for local functions. */
+
+static void fetch_osf_core_registers (char *, unsigned, int, CORE_ADDR);
+static void fetch_elf_core_registers (char *, unsigned, int, CORE_ADDR);
+
+/* Extract the register values out of the core file and store
+ them where `read_register' will find them.
+
+ CORE_REG_SECT points to the register values themselves, read into memory.
+ CORE_REG_SIZE is the size of that area.
+ WHICH says which set of registers we are handling (0 = int, 2 = float
+ on machines where they are discontiguous).
+ REG_ADDR is the offset from u.u_ar0 to the register values relative to
+ core_reg_sect. This is used with old-fashioned core files to
+ locate the registers in a large upage-plus-stack ".reg" section.
+ Original upage address X is at location core_reg_sect+x+reg_addr.
+ */
+
+static void
+fetch_osf_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+ register int regno;
+ register int addr;
+ int bad_reg = -1;
+
+ /* Table to map a gdb regnum to an index in the core register
+ section. The floating point register values are garbage in
+ OSF/1.2 core files. OSF5 uses different names for the register
+ enum list, need to handle two cases. The actual values are the
+ same. */
+ static int core_reg_mapping[ALPHA_NUM_REGS] =
+ {
+#ifdef NCF_REGS
+#define EFL NCF_REGS
+ CF_V0, CF_T0, CF_T1, CF_T2, CF_T3, CF_T4, CF_T5, CF_T6,
+ CF_T7, CF_S0, CF_S1, CF_S2, CF_S3, CF_S4, CF_S5, CF_S6,
+ CF_A0, CF_A1, CF_A2, CF_A3, CF_A4, CF_A5, CF_T8, CF_T9,
+ CF_T10, CF_T11, CF_RA, CF_T12, CF_AT, CF_GP, CF_SP, -1,
+ EFL + 0, EFL + 1, EFL + 2, EFL + 3, EFL + 4, EFL + 5, EFL + 6, EFL + 7,
+ EFL + 8, EFL + 9, EFL + 10, EFL + 11, EFL + 12, EFL + 13, EFL + 14, EFL + 15,
+ EFL + 16, EFL + 17, EFL + 18, EFL + 19, EFL + 20, EFL + 21, EFL + 22, EFL + 23,
+ EFL + 24, EFL + 25, EFL + 26, EFL + 27, EFL + 28, EFL + 29, EFL + 30, EFL + 31,
+ CF_PC, -1
+#else
+#define EFL (EF_SIZE / 8)
+ EF_V0, EF_T0, EF_T1, EF_T2, EF_T3, EF_T4, EF_T5, EF_T6,
+ EF_T7, EF_S0, EF_S1, EF_S2, EF_S3, EF_S4, EF_S5, EF_S6,
+ EF_A0, EF_A1, EF_A2, EF_A3, EF_A4, EF_A5, EF_T8, EF_T9,
+ EF_T10, EF_T11, EF_RA, EF_T12, EF_AT, EF_GP, EF_SP, -1,
+ EFL + 0, EFL + 1, EFL + 2, EFL + 3, EFL + 4, EFL + 5, EFL + 6, EFL + 7,
+ EFL + 8, EFL + 9, EFL + 10, EFL + 11, EFL + 12, EFL + 13, EFL + 14, EFL + 15,
+ EFL + 16, EFL + 17, EFL + 18, EFL + 19, EFL + 20, EFL + 21, EFL + 22, EFL + 23,
+ EFL + 24, EFL + 25, EFL + 26, EFL + 27, EFL + 28, EFL + 29, EFL + 30, EFL + 31,
+ EF_PC, -1
+#endif
+ };
+ static char zerobuf[ALPHA_MAX_REGISTER_RAW_SIZE] =
+ {0};
+
+ for (regno = 0; regno < NUM_REGS; regno++)
+ {
+ if (CANNOT_FETCH_REGISTER (regno))
+ {
+ supply_register (regno, zerobuf);
+ continue;
+ }
+ addr = 8 * core_reg_mapping[regno];
+ if (addr < 0 || addr >= core_reg_size)
+ {
+ if (bad_reg < 0)
+ bad_reg = regno;
+ }
+ else
+ {
+ supply_register (regno, core_reg_sect + addr);
+ }
+ }
+ if (bad_reg >= 0)
+ {
+ error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
+ }
+}
+
+static void
+fetch_elf_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+ if (core_reg_size < 32 * 8)
+ {
+ error ("Core file register section too small (%u bytes).", core_reg_size);
+ return;
+ }
+
+ if (which == 2)
+ {
+ /* The FPU Registers. */
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], core_reg_sect, 31 * 8);
+ memset (&registers[REGISTER_BYTE (FP0_REGNUM + 31)], 0, 8);
+ memset (&register_valid[FP0_REGNUM], 1, 32);
+ }
+ else
+ {
+ /* The General Registers. */
+ memcpy (&registers[REGISTER_BYTE (ALPHA_V0_REGNUM)], core_reg_sect,
+ 31 * 8);
+ memcpy (&registers[REGISTER_BYTE (PC_REGNUM)], core_reg_sect + 31 * 8, 8);
+ memset (&registers[REGISTER_BYTE (ALPHA_ZERO_REGNUM)], 0, 8);
+ memset (&register_valid[ALPHA_V0_REGNUM], 1, 32);
+ register_valid[PC_REGNUM] = 1;
+ }
+}
+
+
+/* Map gdb internal register number to a ptrace ``address''.
+ These ``addresses'' are defined in <sys/ptrace.h> */
+
+#define REGISTER_PTRACE_ADDR(regno) \
+ (regno < FP0_REGNUM ? GPR_BASE + (regno) \
+ : regno == PC_REGNUM ? PC \
+ : regno >= FP0_REGNUM ? FPR_BASE + ((regno) - FP0_REGNUM) \
+ : 0)
+
+/* Return the ptrace ``address'' of register REGNO. */
+
+CORE_ADDR
+register_addr (int regno, CORE_ADDR blockend)
+{
+ return REGISTER_PTRACE_ADDR (regno);
+}
+
+int
+kernel_u_size (void)
+{
+ return (sizeof (struct user));
+}
+
+#if defined(USE_PROC_FS) || defined(HAVE_GREGSET_T)
+#include <sys/procfs.h>
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/*
+ * See the comment in m68k-tdep.c regarding the utility of these functions.
+ */
+
+void
+supply_gregset (gdb_gregset_t *gregsetp)
+{
+ register int regi;
+ register long *regp = ALPHA_REGSET_BASE (gregsetp);
+ static char zerobuf[ALPHA_MAX_REGISTER_RAW_SIZE] =
+ {0};
+
+ for (regi = 0; regi < 31; regi++)
+ supply_register (regi, (char *) (regp + regi));
+
+ supply_register (PC_REGNUM, (char *) (regp + 31));
+
+ /* Fill inaccessible registers with zero. */
+ supply_register (ALPHA_ZERO_REGNUM, zerobuf);
+ supply_register (FP_REGNUM, zerobuf);
+}
+
+void
+fill_gregset (gdb_gregset_t *gregsetp, int regno)
+{
+ int regi;
+ register long *regp = ALPHA_REGSET_BASE (gregsetp);
+
+ for (regi = 0; regi < 31; regi++)
+ if ((regno == -1) || (regno == regi))
+ *(regp + regi) = *(long *) &registers[REGISTER_BYTE (regi)];
+
+ if ((regno == -1) || (regno == PC_REGNUM))
+ *(regp + 31) = *(long *) &registers[REGISTER_BYTE (PC_REGNUM)];
+}
+
+/*
+ * Now we do the same thing for floating-point registers.
+ * Again, see the comments in m68k-tdep.c.
+ */
+
+void
+supply_fpregset (gdb_fpregset_t *fpregsetp)
+{
+ register int regi;
+ register long *regp = ALPHA_REGSET_BASE (fpregsetp);
+
+ for (regi = 0; regi < 32; regi++)
+ supply_register (regi + FP0_REGNUM, (char *) (regp + regi));
+}
+
+void
+fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
+{
+ int regi;
+ register long *regp = ALPHA_REGSET_BASE (fpregsetp);
+
+ for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
+ {
+ if ((regno == -1) || (regno == regi))
+ {
+ *(regp + regi - FP0_REGNUM) =
+ *(long *) &registers[REGISTER_BYTE (regi)];
+ }
+ }
+}
+#endif
+
+
+/* Register that we are able to handle alpha core file formats. */
+
+static struct core_fns alpha_osf_core_fns =
+{
+ /* This really is bfd_target_unknown_flavour. */
+
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_osf_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+static struct core_fns alpha_elf_core_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_elf_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_alpha (void)
+{
+ add_core_fns (&alpha_osf_core_fns);
+ add_core_fns (&alpha_elf_core_fns);
+}
diff --git a/gdb/alpha-osf1-tdep.c b/gdb/alpha-osf1-tdep.c
new file mode 100644
index 00000000000..12320519ae8
--- /dev/null
+++ b/gdb/alpha-osf1-tdep.c
@@ -0,0 +1,73 @@
+/* Target-dependent code for OSF/1 on Alpha.
+ Copyright 2002 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 "defs.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "value.h"
+
+#include "alpha-tdep.h"
+
+/* Under OSF/1, the __sigtramp routine is frameless and has a frame
+ size of zero, but we are able to backtrace through it. */
+static CORE_ADDR
+alpha_osf1_skip_sigtramp_frame (struct frame_info *frame, CORE_ADDR pc)
+{
+ char *name;
+
+ find_pc_partial_function (pc, &name, (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
+ if (PC_IN_SIGTRAMP (pc, name))
+ return frame->frame;
+ return 0;
+}
+
+static int
+alpha_osf1_pc_in_sigtramp (CORE_ADDR pc, char *func_name)
+{
+ return (func_name != NULL && STREQ ("__sigtramp", func_name));
+}
+
+static CORE_ADDR
+alpha_osf1_sigcontext_addr (struct frame_info *frame)
+{
+ return (read_memory_integer (frame->next ? frame->next->frame
+ : frame->frame, 8));
+}
+
+static void
+alpha_osf1_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ set_gdbarch_pc_in_sigtramp (gdbarch, alpha_osf1_pc_in_sigtramp);
+
+ tdep->skip_sigtramp_frame = alpha_osf1_skip_sigtramp_frame;
+ tdep->sigcontext_addr = alpha_osf1_sigcontext_addr;
+
+ tdep->jb_pc = 2;
+ tdep->jb_elt_size = 8;
+}
+
+void
+_initialize_alpha_osf1_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_alpha, GDB_OSABI_OSF1, alpha_osf1_init_abi);
+}
diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
new file mode 100644
index 00000000000..efafcc90078
--- /dev/null
+++ b/gdb/alpha-tdep.c
@@ -0,0 +1,1988 @@
+/* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger.
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "symtab.h"
+#include "value.h"
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "dis-asm.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdb_string.h"
+#include "linespec.h"
+#include "regcache.h"
+#include "doublest.h"
+#include "arch-utils.h"
+
+#include "elf-bfd.h"
+
+#include "alpha-tdep.h"
+
+static gdbarch_init_ftype alpha_gdbarch_init;
+
+static gdbarch_register_name_ftype alpha_register_name;
+static gdbarch_register_raw_size_ftype alpha_register_raw_size;
+static gdbarch_register_virtual_size_ftype alpha_register_virtual_size;
+static gdbarch_register_virtual_type_ftype alpha_register_virtual_type;
+static gdbarch_register_byte_ftype alpha_register_byte;
+static gdbarch_cannot_fetch_register_ftype alpha_cannot_fetch_register;
+static gdbarch_cannot_store_register_ftype alpha_cannot_store_register;
+static gdbarch_register_convertible_ftype alpha_register_convertible;
+static gdbarch_register_convert_to_virtual_ftype
+ alpha_register_convert_to_virtual;
+static gdbarch_register_convert_to_raw_ftype alpha_register_convert_to_raw;
+static gdbarch_store_struct_return_ftype alpha_store_struct_return;
+static gdbarch_extract_return_value_ftype alpha_extract_return_value;
+static gdbarch_store_return_value_ftype alpha_store_return_value;
+static gdbarch_extract_struct_value_address_ftype
+ alpha_extract_struct_value_address;
+static gdbarch_use_struct_convention_ftype alpha_use_struct_convention;
+
+static gdbarch_breakpoint_from_pc_ftype alpha_breakpoint_from_pc;
+
+static gdbarch_frame_args_address_ftype alpha_frame_args_address;
+static gdbarch_frame_locals_address_ftype alpha_frame_locals_address;
+
+static gdbarch_skip_prologue_ftype alpha_skip_prologue;
+static gdbarch_get_saved_register_ftype alpha_get_saved_register;
+static gdbarch_saved_pc_after_call_ftype alpha_saved_pc_after_call;
+static gdbarch_frame_chain_ftype alpha_frame_chain;
+static gdbarch_frame_saved_pc_ftype alpha_frame_saved_pc;
+static gdbarch_frame_init_saved_regs_ftype alpha_frame_init_saved_regs;
+
+static gdbarch_push_arguments_ftype alpha_push_arguments;
+static gdbarch_push_dummy_frame_ftype alpha_push_dummy_frame;
+static gdbarch_pop_frame_ftype alpha_pop_frame;
+static gdbarch_fix_call_dummy_ftype alpha_fix_call_dummy;
+static gdbarch_init_frame_pc_first_ftype alpha_init_frame_pc_first;
+static gdbarch_init_extra_frame_info_ftype alpha_init_extra_frame_info;
+
+static gdbarch_get_longjmp_target_ftype alpha_get_longjmp_target;
+
+struct frame_extra_info
+ {
+ alpha_extra_func_info_t proc_desc;
+ int localoff;
+ int pc_reg;
+ };
+
+/* FIXME: Some of this code should perhaps be merged with mips-tdep.c. */
+
+/* Prototypes for local functions. */
+
+static void alpha_find_saved_regs (struct frame_info *);
+
+static alpha_extra_func_info_t push_sigtramp_desc (CORE_ADDR low_addr);
+
+static CORE_ADDR read_next_frame_reg (struct frame_info *, int);
+
+static CORE_ADDR heuristic_proc_start (CORE_ADDR);
+
+static alpha_extra_func_info_t heuristic_proc_desc (CORE_ADDR,
+ CORE_ADDR,
+ struct frame_info *);
+
+static alpha_extra_func_info_t find_proc_desc (CORE_ADDR,
+ struct frame_info *);
+
+#if 0
+static int alpha_in_lenient_prologue (CORE_ADDR, CORE_ADDR);
+#endif
+
+static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
+
+static CORE_ADDR after_prologue (CORE_ADDR pc,
+ alpha_extra_func_info_t proc_desc);
+
+static int alpha_in_prologue (CORE_ADDR pc,
+ alpha_extra_func_info_t proc_desc);
+
+static int alpha_about_to_return (CORE_ADDR pc);
+
+void _initialize_alpha_tdep (void);
+
+/* Heuristic_proc_start may hunt through the text section for a long
+ time across a 2400 baud serial line. Allows the user to limit this
+ search. */
+static unsigned int heuristic_fence_post = 0;
+/* *INDENT-OFF* */
+/* Layout of a stack frame on the alpha:
+
+ | |
+ pdr members: | 7th ... nth arg, |
+ | `pushed' by caller. |
+ | |
+----------------|-------------------------------|<-- old_sp == vfp
+ ^ ^ ^ ^ | |
+ | | | | | |
+ | |localoff | Copies of 1st .. 6th |
+ | | | | | argument if necessary. |
+ | | | v | |
+ | | | --- |-------------------------------|<-- FRAME_LOCALS_ADDRESS
+ | | | | |
+ | | | | Locals and temporaries. |
+ | | | | |
+ | | | |-------------------------------|
+ | | | | |
+ |-fregoffset | Saved float registers. |
+ | | | | F9 |
+ | | | | . |
+ | | | | . |
+ | | | | F2 |
+ | | v | |
+ | | -------|-------------------------------|
+ | | | |
+ | | | Saved registers. |
+ | | | S6 |
+ |-regoffset | . |
+ | | | . |
+ | | | S0 |
+ | | | pdr.pcreg |
+ | v | |
+ | ----------|-------------------------------|
+ | | |
+ frameoffset | Argument build area, gets |
+ | | 7th ... nth arg for any |
+ | | called procedure. |
+ v | |
+ -------------|-------------------------------|<-- sp
+ | |
+*/
+/* *INDENT-ON* */
+
+#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) /* least address */
+/* These next two fields are kind of being hijacked. I wonder if
+ iline is too small for the values it needs to hold, if GDB is
+ running on a 32-bit host. */
+#define PROC_HIGH_ADDR(proc) ((proc)->pdr.iline) /* upper address bound */
+#define PROC_DUMMY_FRAME(proc) ((proc)->pdr.cbLineOffset) /*CALL_DUMMY frame */
+#define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset)
+#define PROC_FRAME_REG(proc) ((proc)->pdr.framereg)
+#define PROC_REG_MASK(proc) ((proc)->pdr.regmask)
+#define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask)
+#define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset)
+#define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset)
+#define PROC_PC_REG(proc) ((proc)->pdr.pcreg)
+#define PROC_LOCALOFF(proc) ((proc)->pdr.localoff)
+#define PROC_SYMBOL(proc) (*(struct symbol**)&(proc)->pdr.isym)
+#define _PROC_MAGIC_ 0x0F0F0F0F
+#define PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym == _PROC_MAGIC_)
+#define SET_PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym = _PROC_MAGIC_)
+
+struct linked_proc_info
+ {
+ struct alpha_extra_func_info info;
+ struct linked_proc_info *next;
+ }
+ *linked_proc_desc_table = NULL;
+
+static CORE_ADDR
+alpha_frame_past_sigtramp_frame (struct frame_info *frame, CORE_ADDR pc)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (tdep->skip_sigtramp_frame != NULL)
+ return (tdep->skip_sigtramp_frame (frame, pc));
+
+ return (0);
+}
+
+static LONGEST
+alpha_dynamic_sigtramp_offset (CORE_ADDR pc)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ /* Must be provided by OS/ABI variant code if supported. */
+ if (tdep->dynamic_sigtramp_offset != NULL)
+ return (tdep->dynamic_sigtramp_offset (pc));
+
+ return (-1);
+}
+
+#define ALPHA_PROC_SIGTRAMP_MAGIC 0x0e0f0f0f
+
+/* Return TRUE if the procedure descriptor PROC is a procedure
+ descriptor that refers to a dynamically generated signal
+ trampoline routine. */
+static int
+alpha_proc_desc_is_dyn_sigtramp (struct alpha_extra_func_info *proc)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (tdep->dynamic_sigtramp_offset != NULL)
+ return (proc->pdr.isym == ALPHA_PROC_SIGTRAMP_MAGIC);
+
+ return (0);
+}
+
+static void
+alpha_set_proc_desc_is_dyn_sigtramp (struct alpha_extra_func_info *proc)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (tdep->dynamic_sigtramp_offset != NULL)
+ proc->pdr.isym = ALPHA_PROC_SIGTRAMP_MAGIC;
+}
+
+/* Dynamically create a signal-handler caller procedure descriptor for
+ the signal-handler return code starting at address LOW_ADDR. The
+ descriptor is added to the linked_proc_desc_table. */
+
+static alpha_extra_func_info_t
+push_sigtramp_desc (CORE_ADDR low_addr)
+{
+ struct linked_proc_info *link;
+ alpha_extra_func_info_t proc_desc;
+
+ link = (struct linked_proc_info *)
+ xmalloc (sizeof (struct linked_proc_info));
+ link->next = linked_proc_desc_table;
+ linked_proc_desc_table = link;
+
+ proc_desc = &link->info;
+
+ proc_desc->numargs = 0;
+ PROC_LOW_ADDR (proc_desc) = low_addr;
+ PROC_HIGH_ADDR (proc_desc) = low_addr + 3 * 4;
+ PROC_DUMMY_FRAME (proc_desc) = 0;
+ PROC_FRAME_OFFSET (proc_desc) = 0x298; /* sizeof(struct sigcontext_struct) */
+ PROC_FRAME_REG (proc_desc) = SP_REGNUM;
+ PROC_REG_MASK (proc_desc) = 0xffff;
+ PROC_FREG_MASK (proc_desc) = 0xffff;
+ PROC_PC_REG (proc_desc) = 26;
+ PROC_LOCALOFF (proc_desc) = 0;
+ alpha_set_proc_desc_is_dyn_sigtramp (proc_desc);
+ return (proc_desc);
+}
+
+
+static char *
+alpha_register_name (int regno)
+{
+ static char *register_names[] =
+ {
+ "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
+ "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp",
+ "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
+ "t10", "t11", "ra", "t12", "at", "gp", "sp", "zero",
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "fpcr",
+ "pc", "vfp",
+ };
+
+ if (regno < 0)
+ return (NULL);
+ if (regno >= (sizeof(register_names) / sizeof(*register_names)))
+ return (NULL);
+ return (register_names[regno]);
+}
+
+static int
+alpha_cannot_fetch_register (int regno)
+{
+ return (regno == FP_REGNUM || regno == ALPHA_ZERO_REGNUM);
+}
+
+static int
+alpha_cannot_store_register (int regno)
+{
+ return (regno == FP_REGNUM || regno == ALPHA_ZERO_REGNUM);
+}
+
+static int
+alpha_register_convertible (int regno)
+{
+ return (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31);
+}
+
+static struct type *
+alpha_register_virtual_type (int regno)
+{
+ return ((regno >= FP0_REGNUM && regno < (FP0_REGNUM+31))
+ ? builtin_type_double : builtin_type_long);
+}
+
+static int
+alpha_register_byte (int regno)
+{
+ return (regno * 8);
+}
+
+static int
+alpha_register_raw_size (int regno)
+{
+ return 8;
+}
+
+static int
+alpha_register_virtual_size (int regno)
+{
+ return 8;
+}
+
+
+static CORE_ADDR
+alpha_sigcontext_addr (struct frame_info *fi)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (tdep->sigcontext_addr)
+ return (tdep->sigcontext_addr (fi));
+
+ return (0);
+}
+
+/* Guaranteed to set frame->saved_regs to some values (it never leaves it
+ NULL). */
+
+static void
+alpha_find_saved_regs (struct frame_info *frame)
+{
+ int ireg;
+ CORE_ADDR reg_position;
+ unsigned long mask;
+ alpha_extra_func_info_t proc_desc;
+ int returnreg;
+
+ frame_saved_regs_zalloc (frame);
+
+ /* If it is the frame for __sigtramp, the saved registers are located
+ in a sigcontext structure somewhere on the stack. __sigtramp
+ passes a pointer to the sigcontext structure on the stack.
+ If the stack layout for __sigtramp changes, or if sigcontext offsets
+ change, we might have to update this code. */
+#ifndef SIGFRAME_PC_OFF
+#define SIGFRAME_PC_OFF (2 * 8)
+#define SIGFRAME_REGSAVE_OFF (4 * 8)
+#define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_REGSAVE_OFF + 32 * 8 + 8)
+#endif
+ if (frame->signal_handler_caller)
+ {
+ CORE_ADDR sigcontext_addr;
+
+ sigcontext_addr = alpha_sigcontext_addr (frame);
+ if (sigcontext_addr == 0)
+ {
+ /* Don't know where the sigcontext is; just bail. */
+ return;
+ }
+ for (ireg = 0; ireg < 32; ireg++)
+ {
+ reg_position = sigcontext_addr + SIGFRAME_REGSAVE_OFF + ireg * 8;
+ frame->saved_regs[ireg] = reg_position;
+ }
+ for (ireg = 0; ireg < 32; ireg++)
+ {
+ reg_position = sigcontext_addr + SIGFRAME_FPREGSAVE_OFF + ireg * 8;
+ frame->saved_regs[FP0_REGNUM + ireg] = reg_position;
+ }
+ frame->saved_regs[PC_REGNUM] = sigcontext_addr + SIGFRAME_PC_OFF;
+ return;
+ }
+
+ proc_desc = frame->extra_info->proc_desc;
+ if (proc_desc == NULL)
+ /* I'm not sure how/whether this can happen. Normally when we can't
+ find a proc_desc, we "synthesize" one using heuristic_proc_desc
+ and set the saved_regs right away. */
+ return;
+
+ /* Fill in the offsets for the registers which gen_mask says
+ were saved. */
+
+ reg_position = frame->frame + PROC_REG_OFFSET (proc_desc);
+ mask = PROC_REG_MASK (proc_desc);
+
+ returnreg = PROC_PC_REG (proc_desc);
+
+ /* Note that RA is always saved first, regardless of its actual
+ register number. */
+ if (mask & (1 << returnreg))
+ {
+ frame->saved_regs[returnreg] = reg_position;
+ reg_position += 8;
+ mask &= ~(1 << returnreg); /* Clear bit for RA so we
+ don't save again later. */
+ }
+
+ for (ireg = 0; ireg <= 31; ++ireg)
+ if (mask & (1 << ireg))
+ {
+ frame->saved_regs[ireg] = reg_position;
+ reg_position += 8;
+ }
+
+ /* Fill in the offsets for the registers which float_mask says
+ were saved. */
+
+ reg_position = frame->frame + PROC_FREG_OFFSET (proc_desc);
+ mask = PROC_FREG_MASK (proc_desc);
+
+ for (ireg = 0; ireg <= 31; ++ireg)
+ if (mask & (1 << ireg))
+ {
+ frame->saved_regs[FP0_REGNUM + ireg] = reg_position;
+ reg_position += 8;
+ }
+
+ frame->saved_regs[PC_REGNUM] = frame->saved_regs[returnreg];
+}
+
+static void
+alpha_frame_init_saved_regs (struct frame_info *fi)
+{
+ if (fi->saved_regs == NULL)
+ alpha_find_saved_regs (fi);
+ fi->saved_regs[SP_REGNUM] = fi->frame;
+}
+
+static void
+alpha_init_frame_pc_first (int fromleaf, struct frame_info *prev)
+{
+ prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (prev->next) :
+ prev->next ? FRAME_SAVED_PC (prev->next) : read_pc ());
+}
+
+static CORE_ADDR
+read_next_frame_reg (struct frame_info *fi, int regno)
+{
+ for (; fi; fi = fi->next)
+ {
+ /* We have to get the saved sp from the sigcontext
+ if it is a signal handler frame. */
+ if (regno == SP_REGNUM && !fi->signal_handler_caller)
+ return fi->frame;
+ else
+ {
+ if (fi->saved_regs == NULL)
+ alpha_find_saved_regs (fi);
+ if (fi->saved_regs[regno])
+ return read_memory_integer (fi->saved_regs[regno], 8);
+ }
+ }
+ return read_register (regno);
+}
+
+static CORE_ADDR
+alpha_frame_saved_pc (struct frame_info *frame)
+{
+ alpha_extra_func_info_t proc_desc = frame->extra_info->proc_desc;
+ /* We have to get the saved pc from the sigcontext
+ if it is a signal handler frame. */
+ int pcreg = frame->signal_handler_caller ? PC_REGNUM
+ : frame->extra_info->pc_reg;
+
+ if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
+ return read_memory_integer (frame->frame - 8, 8);
+
+ return read_next_frame_reg (frame, pcreg);
+}
+
+static void
+alpha_get_saved_register (char *raw_buffer,
+ int *optimized,
+ CORE_ADDR *addrp,
+ struct frame_info *frame,
+ int regnum,
+ enum lval_type *lval)
+{
+ CORE_ADDR addr;
+
+ if (!target_has_registers)
+ error ("No registers.");
+
+ /* Normal systems don't optimize out things with register numbers. */
+ if (optimized != NULL)
+ *optimized = 0;
+ addr = find_saved_register (frame, regnum);
+ if (addr != 0)
+ {
+ if (lval != NULL)
+ *lval = lval_memory;
+ if (regnum == SP_REGNUM)
+ {
+ if (raw_buffer != NULL)
+ {
+ /* Put it back in target format. */
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
+ (LONGEST) addr);
+ }
+ if (addrp != NULL)
+ *addrp = 0;
+ return;
+ }
+ if (raw_buffer != NULL)
+ target_read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum));
+ }
+ else
+ {
+ if (lval != NULL)
+ *lval = lval_register;
+ addr = REGISTER_BYTE (regnum);
+ if (raw_buffer != NULL)
+ read_register_gen (regnum, raw_buffer);
+ }
+ if (addrp != NULL)
+ *addrp = addr;
+}
+
+static CORE_ADDR
+alpha_saved_pc_after_call (struct frame_info *frame)
+{
+ CORE_ADDR pc = frame->pc;
+ CORE_ADDR tmp;
+ alpha_extra_func_info_t proc_desc;
+ int pcreg;
+
+ /* Skip over shared library trampoline if necessary. */
+ tmp = SKIP_TRAMPOLINE_CODE (pc);
+ if (tmp != 0)
+ pc = tmp;
+
+ proc_desc = find_proc_desc (pc, frame->next);
+ pcreg = proc_desc ? PROC_PC_REG (proc_desc) : ALPHA_RA_REGNUM;
+
+ if (frame->signal_handler_caller)
+ return alpha_frame_saved_pc (frame);
+ else
+ return read_register (pcreg);
+}
+
+
+static struct alpha_extra_func_info temp_proc_desc;
+static CORE_ADDR temp_saved_regs[ALPHA_NUM_REGS];
+
+/* Nonzero if instruction at PC is a return instruction. "ret
+ $zero,($ra),1" on alpha. */
+
+static int
+alpha_about_to_return (CORE_ADDR pc)
+{
+ return read_memory_integer (pc, 4) == 0x6bfa8001;
+}
+
+
+
+/* This fencepost looks highly suspicious to me. Removing it also
+ seems suspicious as it could affect remote debugging across serial
+ lines. */
+
+static CORE_ADDR
+heuristic_proc_start (CORE_ADDR pc)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ CORE_ADDR start_pc = pc;
+ CORE_ADDR fence = start_pc - heuristic_fence_post;
+
+ if (start_pc == 0)
+ return 0;
+
+ if (heuristic_fence_post == UINT_MAX
+ || fence < tdep->vm_min_address)
+ fence = tdep->vm_min_address;
+
+ /* search back for previous return */
+ for (start_pc -= 4;; start_pc -= 4)
+ if (start_pc < fence)
+ {
+ /* It's not clear to me why we reach this point when
+ stop_soon_quietly, but with this test, at least we
+ don't print out warnings for every child forked (eg, on
+ decstation). 22apr93 rich@cygnus.com. */
+ if (!stop_soon_quietly)
+ {
+ static int blurb_printed = 0;
+
+ if (fence == tdep->vm_min_address)
+ warning ("Hit beginning of text section without finding");
+ else
+ warning ("Hit heuristic-fence-post without finding");
+
+ warning ("enclosing function for address 0x%s", paddr_nz (pc));
+ if (!blurb_printed)
+ {
+ printf_filtered ("\
+This warning occurs if you are debugging a function without any symbols\n\
+(for example, in a stripped executable). In that case, you may wish to\n\
+increase the size of the search with the `set heuristic-fence-post' command.\n\
+\n\
+Otherwise, you told GDB there was a function where there isn't one, or\n\
+(more likely) you have encountered a bug in GDB.\n");
+ blurb_printed = 1;
+ }
+ }
+
+ return 0;
+ }
+ else if (alpha_about_to_return (start_pc))
+ break;
+
+ start_pc += 4; /* skip return */
+ return start_pc;
+}
+
+static alpha_extra_func_info_t
+heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
+ struct frame_info *next_frame)
+{
+ CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
+ CORE_ADDR cur_pc;
+ int frame_size;
+ int has_frame_reg = 0;
+ unsigned long reg_mask = 0;
+ int pcreg = -1;
+
+ if (start_pc == 0)
+ return NULL;
+ memset (&temp_proc_desc, '\0', sizeof (temp_proc_desc));
+ memset (&temp_saved_regs, '\0', SIZEOF_FRAME_SAVED_REGS);
+ PROC_LOW_ADDR (&temp_proc_desc) = start_pc;
+
+ if (start_pc + 200 < limit_pc)
+ limit_pc = start_pc + 200;
+ frame_size = 0;
+ for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4)
+ {
+ char buf[4];
+ unsigned long word;
+ int status;
+
+ status = read_memory_nobpt (cur_pc, buf, 4);
+ if (status)
+ memory_error (status, cur_pc);
+ word = extract_unsigned_integer (buf, 4);
+
+ if ((word & 0xffff0000) == 0x23de0000) /* lda $sp,n($sp) */
+ {
+ if (word & 0x8000)
+ frame_size += (-word) & 0xffff;
+ else
+ /* Exit loop if a positive stack adjustment is found, which
+ usually means that the stack cleanup code in the function
+ epilogue is reached. */
+ break;
+ }
+ else if ((word & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */
+ && (word & 0xffff0000) != 0xb7fe0000) /* reg != $zero */
+ {
+ int reg = (word & 0x03e00000) >> 21;
+ reg_mask |= 1 << reg;
+ temp_saved_regs[reg] = sp + (short) word;
+
+ /* Starting with OSF/1-3.2C, the system libraries are shipped
+ without local symbols, but they still contain procedure
+ descriptors without a symbol reference. GDB is currently
+ unable to find these procedure descriptors and uses
+ heuristic_proc_desc instead.
+ As some low level compiler support routines (__div*, __add*)
+ use a non-standard return address register, we have to
+ add some heuristics to determine the return address register,
+ or stepping over these routines will fail.
+ Usually the return address register is the first register
+ saved on the stack, but assembler optimization might
+ rearrange the register saves.
+ So we recognize only a few registers (t7, t9, ra) within
+ the procedure prologue as valid return address registers.
+ If we encounter a return instruction, we extract the
+ the return address register from it.
+
+ FIXME: Rewriting GDB to access the procedure descriptors,
+ e.g. via the minimal symbol table, might obviate this hack. */
+ if (pcreg == -1
+ && cur_pc < (start_pc + 80)
+ && (reg == ALPHA_T7_REGNUM || reg == ALPHA_T9_REGNUM
+ || reg == ALPHA_RA_REGNUM))
+ pcreg = reg;
+ }
+ else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */
+ pcreg = (word >> 16) & 0x1f;
+ else if (word == 0x47de040f) /* bis sp,sp fp */
+ has_frame_reg = 1;
+ }
+ if (pcreg == -1)
+ {
+ /* If we haven't found a valid return address register yet,
+ keep searching in the procedure prologue. */
+ while (cur_pc < (limit_pc + 80) && cur_pc < (start_pc + 80))
+ {
+ char buf[4];
+ unsigned long word;
+
+ if (read_memory_nobpt (cur_pc, buf, 4))
+ break;
+ cur_pc += 4;
+ word = extract_unsigned_integer (buf, 4);
+
+ if ((word & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */
+ && (word & 0xffff0000) != 0xb7fe0000) /* reg != $zero */
+ {
+ int reg = (word & 0x03e00000) >> 21;
+ if (reg == ALPHA_T7_REGNUM || reg == ALPHA_T9_REGNUM
+ || reg == ALPHA_RA_REGNUM)
+ {
+ pcreg = reg;
+ break;
+ }
+ }
+ else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */
+ {
+ pcreg = (word >> 16) & 0x1f;
+ break;
+ }
+ }
+ }
+
+ if (has_frame_reg)
+ PROC_FRAME_REG (&temp_proc_desc) = ALPHA_GCC_FP_REGNUM;
+ else
+ PROC_FRAME_REG (&temp_proc_desc) = SP_REGNUM;
+ PROC_FRAME_OFFSET (&temp_proc_desc) = frame_size;
+ PROC_REG_MASK (&temp_proc_desc) = reg_mask;
+ PROC_PC_REG (&temp_proc_desc) = (pcreg == -1) ? ALPHA_RA_REGNUM : pcreg;
+ PROC_LOCALOFF (&temp_proc_desc) = 0; /* XXX - bogus */
+ return &temp_proc_desc;
+}
+
+/* This returns the PC of the first inst after the prologue. If we can't
+ find the prologue, then return 0. */
+
+static CORE_ADDR
+after_prologue (CORE_ADDR pc, alpha_extra_func_info_t proc_desc)
+{
+ struct symtab_and_line sal;
+ CORE_ADDR func_addr, func_end;
+
+ if (!proc_desc)
+ proc_desc = find_proc_desc (pc, NULL);
+
+ if (proc_desc)
+ {
+ if (alpha_proc_desc_is_dyn_sigtramp (proc_desc))
+ return PROC_LOW_ADDR (proc_desc); /* "prologue" is in kernel */
+
+ /* If function is frameless, then we need to do it the hard way. I
+ strongly suspect that frameless always means prologueless... */
+ if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
+ && PROC_FRAME_OFFSET (proc_desc) == 0)
+ return 0;
+ }
+
+ if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ return 0; /* Unknown */
+
+ sal = find_pc_line (func_addr, 0);
+
+ if (sal.end < func_end)
+ return sal.end;
+
+ /* The line after the prologue is after the end of the function. In this
+ case, tell the caller to find the prologue the hard way. */
+
+ return 0;
+}
+
+/* Return non-zero if we *might* be in a function prologue. Return zero if we
+ are definitively *not* in a function prologue. */
+
+static int
+alpha_in_prologue (CORE_ADDR pc, alpha_extra_func_info_t proc_desc)
+{
+ CORE_ADDR after_prologue_pc;
+
+ after_prologue_pc = after_prologue (pc, proc_desc);
+
+ if (after_prologue_pc == 0
+ || pc < after_prologue_pc)
+ return 1;
+ else
+ return 0;
+}
+
+static alpha_extra_func_info_t
+find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame)
+{
+ alpha_extra_func_info_t proc_desc;
+ struct block *b;
+ struct symbol *sym;
+ CORE_ADDR startaddr;
+
+ /* Try to get the proc_desc from the linked call dummy proc_descs
+ if the pc is in the call dummy.
+ This is hairy. In the case of nested dummy calls we have to find the
+ right proc_desc, but we might not yet know the frame for the dummy
+ as it will be contained in the proc_desc we are searching for.
+ So we have to find the proc_desc whose frame is closest to the current
+ stack pointer. */
+
+ if (PC_IN_CALL_DUMMY (pc, 0, 0))
+ {
+ struct linked_proc_info *link;
+ CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
+ alpha_extra_func_info_t found_proc_desc = NULL;
+ long min_distance = LONG_MAX;
+
+ for (link = linked_proc_desc_table; link; link = link->next)
+ {
+ long distance = (CORE_ADDR) PROC_DUMMY_FRAME (&link->info) - sp;
+ if (distance > 0 && distance < min_distance)
+ {
+ min_distance = distance;
+ found_proc_desc = &link->info;
+ }
+ }
+ if (found_proc_desc != NULL)
+ return found_proc_desc;
+ }
+
+ b = block_for_pc (pc);
+
+ find_pc_partial_function (pc, NULL, &startaddr, NULL);
+ if (b == NULL)
+ sym = NULL;
+ else
+ {
+ if (startaddr > BLOCK_START (b))
+ /* This is the "pathological" case referred to in a comment in
+ print_frame_info. It might be better to move this check into
+ symbol reading. */
+ sym = NULL;
+ else
+ sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE,
+ 0, NULL);
+ }
+
+ /* If we never found a PDR for this function in symbol reading, then
+ examine prologues to find the information. */
+ if (sym && ((mips_extra_func_info_t) SYMBOL_VALUE (sym))->pdr.framereg == -1)
+ sym = NULL;
+
+ if (sym)
+ {
+ /* IF this is the topmost frame AND
+ * (this proc does not have debugging information OR
+ * the PC is in the procedure prologue)
+ * THEN create a "heuristic" proc_desc (by analyzing
+ * the actual code) to replace the "official" proc_desc.
+ */
+ proc_desc = (alpha_extra_func_info_t) SYMBOL_VALUE (sym);
+ if (next_frame == NULL)
+ {
+ if (PROC_DESC_IS_DUMMY (proc_desc) || alpha_in_prologue (pc, proc_desc))
+ {
+ alpha_extra_func_info_t found_heuristic =
+ heuristic_proc_desc (PROC_LOW_ADDR (proc_desc),
+ pc, next_frame);
+ if (found_heuristic)
+ {
+ PROC_LOCALOFF (found_heuristic) =
+ PROC_LOCALOFF (proc_desc);
+ PROC_PC_REG (found_heuristic) = PROC_PC_REG (proc_desc);
+ proc_desc = found_heuristic;
+ }
+ }
+ }
+ }
+ else
+ {
+ long offset;
+
+ /* Is linked_proc_desc_table really necessary? It only seems to be used
+ by procedure call dummys. However, the procedures being called ought
+ to have their own proc_descs, and even if they don't,
+ heuristic_proc_desc knows how to create them! */
+
+ register struct linked_proc_info *link;
+ for (link = linked_proc_desc_table; link; link = link->next)
+ if (PROC_LOW_ADDR (&link->info) <= pc
+ && PROC_HIGH_ADDR (&link->info) > pc)
+ return &link->info;
+
+ /* If PC is inside a dynamically generated sigtramp handler,
+ create and push a procedure descriptor for that code: */
+ offset = alpha_dynamic_sigtramp_offset (pc);
+ if (offset >= 0)
+ return push_sigtramp_desc (pc - offset);
+
+ /* If heuristic_fence_post is non-zero, determine the procedure
+ start address by examining the instructions.
+ This allows us to find the start address of static functions which
+ have no symbolic information, as startaddr would have been set to
+ the preceding global function start address by the
+ find_pc_partial_function call above. */
+ if (startaddr == 0 || heuristic_fence_post != 0)
+ startaddr = heuristic_proc_start (pc);
+
+ proc_desc =
+ heuristic_proc_desc (startaddr, pc, next_frame);
+ }
+ return proc_desc;
+}
+
+alpha_extra_func_info_t cached_proc_desc;
+
+static CORE_ADDR
+alpha_frame_chain (struct frame_info *frame)
+{
+ alpha_extra_func_info_t proc_desc;
+ CORE_ADDR saved_pc = FRAME_SAVED_PC (frame);
+
+ if (saved_pc == 0 || inside_entry_file (saved_pc))
+ return 0;
+
+ proc_desc = find_proc_desc (saved_pc, frame);
+ if (!proc_desc)
+ return 0;
+
+ cached_proc_desc = proc_desc;
+
+ /* Fetch the frame pointer for a dummy frame from the procedure
+ descriptor. */
+ if (PROC_DESC_IS_DUMMY (proc_desc))
+ return (CORE_ADDR) PROC_DUMMY_FRAME (proc_desc);
+
+ /* If no frame pointer and frame size is zero, we must be at end
+ of stack (or otherwise hosed). If we don't check frame size,
+ we loop forever if we see a zero size frame. */
+ if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
+ && PROC_FRAME_OFFSET (proc_desc) == 0
+ /* The previous frame from a sigtramp frame might be frameless
+ and have frame size zero. */
+ && !frame->signal_handler_caller)
+ return alpha_frame_past_sigtramp_frame (frame, saved_pc);
+ else
+ return read_next_frame_reg (frame, PROC_FRAME_REG (proc_desc))
+ + PROC_FRAME_OFFSET (proc_desc);
+}
+
+void
+alpha_print_extra_frame_info (struct frame_info *fi)
+{
+ if (fi
+ && fi->extra_info
+ && fi->extra_info->proc_desc
+ && fi->extra_info->proc_desc->pdr.framereg < NUM_REGS)
+ printf_filtered (" frame pointer is at %s+%s\n",
+ REGISTER_NAME (fi->extra_info->proc_desc->pdr.framereg),
+ paddr_d (fi->extra_info->proc_desc->pdr.frameoffset));
+}
+
+static void
+alpha_init_extra_frame_info (int fromleaf, struct frame_info *frame)
+{
+ /* Use proc_desc calculated in frame_chain */
+ alpha_extra_func_info_t proc_desc =
+ frame->next ? cached_proc_desc : find_proc_desc (frame->pc, frame->next);
+
+ frame->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+
+ frame->saved_regs = NULL;
+ frame->extra_info->localoff = 0;
+ frame->extra_info->pc_reg = ALPHA_RA_REGNUM;
+ frame->extra_info->proc_desc = proc_desc == &temp_proc_desc ? 0 : proc_desc;
+ if (proc_desc)
+ {
+ /* Get the locals offset and the saved pc register from the
+ procedure descriptor, they are valid even if we are in the
+ middle of the prologue. */
+ frame->extra_info->localoff = PROC_LOCALOFF (proc_desc);
+ frame->extra_info->pc_reg = PROC_PC_REG (proc_desc);
+
+ /* Fixup frame-pointer - only needed for top frame */
+
+ /* Fetch the frame pointer for a dummy frame from the procedure
+ descriptor. */
+ if (PROC_DESC_IS_DUMMY (proc_desc))
+ frame->frame = (CORE_ADDR) PROC_DUMMY_FRAME (proc_desc);
+
+ /* This may not be quite right, if proc has a real frame register.
+ Get the value of the frame relative sp, procedure might have been
+ interrupted by a signal at it's very start. */
+ else if (frame->pc == PROC_LOW_ADDR (proc_desc)
+ && !alpha_proc_desc_is_dyn_sigtramp (proc_desc))
+ frame->frame = read_next_frame_reg (frame->next, SP_REGNUM);
+ else
+ frame->frame = read_next_frame_reg (frame->next, PROC_FRAME_REG (proc_desc))
+ + PROC_FRAME_OFFSET (proc_desc);
+
+ if (proc_desc == &temp_proc_desc)
+ {
+ char *name;
+
+ /* Do not set the saved registers for a sigtramp frame,
+ alpha_find_saved_registers will do that for us.
+ We can't use frame->signal_handler_caller, it is not yet set. */
+ find_pc_partial_function (frame->pc, &name,
+ (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
+ if (!PC_IN_SIGTRAMP (frame->pc, name))
+ {
+ frame->saved_regs = (CORE_ADDR *)
+ frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS);
+ memcpy (frame->saved_regs, temp_saved_regs,
+ SIZEOF_FRAME_SAVED_REGS);
+ frame->saved_regs[PC_REGNUM]
+ = frame->saved_regs[ALPHA_RA_REGNUM];
+ }
+ }
+ }
+}
+
+static CORE_ADDR
+alpha_frame_locals_address (struct frame_info *fi)
+{
+ return (fi->frame - fi->extra_info->localoff);
+}
+
+static CORE_ADDR
+alpha_frame_args_address (struct frame_info *fi)
+{
+ return (fi->frame - (ALPHA_NUM_ARG_REGS * 8));
+}
+
+/* ALPHA stack frames are almost impenetrable. When execution stops,
+ we basically have to look at symbol information for the function
+ that we stopped in, which tells us *which* register (if any) is
+ the base of the frame pointer, and what offset from that register
+ the frame itself is at.
+
+ This presents a problem when trying to examine a stack in memory
+ (that isn't executing at the moment), using the "frame" command. We
+ don't have a PC, nor do we have any registers except SP.
+
+ This routine takes two arguments, SP and PC, and tries to make the
+ cached frames look as if these two arguments defined a frame on the
+ cache. This allows the rest of info frame to extract the important
+ arguments without difficulty. */
+
+struct frame_info *
+alpha_setup_arbitrary_frame (int argc, CORE_ADDR *argv)
+{
+ if (argc != 2)
+ error ("ALPHA frame specifications require two arguments: sp and pc");
+
+ return create_new_frame (argv[0], argv[1]);
+}
+
+/* The alpha passes the first six arguments in the registers, the rest on
+ the stack. The register arguments are eventually transferred to the
+ argument transfer area immediately below the stack by the called function
+ anyway. So we `push' at least six arguments on the stack, `reload' the
+ argument registers and then adjust the stack pointer to point past the
+ sixth argument. This algorithm simplifies the passing of a large struct
+ which extends from the registers to the stack.
+ If the called function is returning a structure, the address of the
+ structure to be returned is passed as a hidden first argument. */
+
+static CORE_ADDR
+alpha_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int i;
+ int accumulate_size = struct_return ? 8 : 0;
+ int arg_regs_size = ALPHA_NUM_ARG_REGS * 8;
+ struct alpha_arg
+ {
+ char *contents;
+ int len;
+ int offset;
+ };
+ struct alpha_arg *alpha_args =
+ (struct alpha_arg *) alloca (nargs * sizeof (struct alpha_arg));
+ register struct alpha_arg *m_arg;
+ char raw_buffer[sizeof (CORE_ADDR)];
+ int required_arg_regs;
+
+ for (i = 0, m_arg = alpha_args; i < nargs; i++, m_arg++)
+ {
+ struct value *arg = args[i];
+ struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+ /* Cast argument to long if necessary as the compiler does it too. */
+ switch (TYPE_CODE (arg_type))
+ {
+ case TYPE_CODE_INT:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_ENUM:
+ if (TYPE_LENGTH (arg_type) < TYPE_LENGTH (builtin_type_long))
+ {
+ arg_type = builtin_type_long;
+ arg = value_cast (arg_type, arg);
+ }
+ break;
+ default:
+ break;
+ }
+ m_arg->len = TYPE_LENGTH (arg_type);
+ m_arg->offset = accumulate_size;
+ accumulate_size = (accumulate_size + m_arg->len + 7) & ~7;
+ m_arg->contents = VALUE_CONTENTS (arg);
+ }
+
+ /* Determine required argument register loads, loading an argument register
+ is expensive as it uses three ptrace calls. */
+ required_arg_regs = accumulate_size / 8;
+ if (required_arg_regs > ALPHA_NUM_ARG_REGS)
+ required_arg_regs = ALPHA_NUM_ARG_REGS;
+
+ /* Make room for the arguments on the stack. */
+ if (accumulate_size < arg_regs_size)
+ accumulate_size = arg_regs_size;
+ sp -= accumulate_size;
+
+ /* Keep sp aligned to a multiple of 16 as the compiler does it too. */
+ sp &= ~15;
+
+ /* `Push' arguments on the stack. */
+ for (i = nargs; m_arg--, --i >= 0;)
+ write_memory (sp + m_arg->offset, m_arg->contents, m_arg->len);
+ if (struct_return)
+ {
+ store_address (raw_buffer, sizeof (CORE_ADDR), struct_addr);
+ write_memory (sp, raw_buffer, sizeof (CORE_ADDR));
+ }
+
+ /* Load the argument registers. */
+ for (i = 0; i < required_arg_regs; i++)
+ {
+ LONGEST val;
+
+ val = read_memory_integer (sp + i * 8, 8);
+ write_register (ALPHA_A0_REGNUM + i, val);
+ write_register (ALPHA_FPA0_REGNUM + i, val);
+ }
+
+ return sp + arg_regs_size;
+}
+
+static void
+alpha_push_dummy_frame (void)
+{
+ int ireg;
+ struct linked_proc_info *link;
+ alpha_extra_func_info_t proc_desc;
+ CORE_ADDR sp = read_register (SP_REGNUM);
+ CORE_ADDR save_address;
+ char raw_buffer[ALPHA_MAX_REGISTER_RAW_SIZE];
+ unsigned long mask;
+
+ link = (struct linked_proc_info *) xmalloc (sizeof (struct linked_proc_info));
+ link->next = linked_proc_desc_table;
+ linked_proc_desc_table = link;
+
+ proc_desc = &link->info;
+
+ /*
+ * The registers we must save are all those not preserved across
+ * procedure calls.
+ * In addition, we must save the PC and RA.
+ *
+ * Dummy frame layout:
+ * (high memory)
+ * Saved PC
+ * Saved F30
+ * ...
+ * Saved F0
+ * Saved R29
+ * ...
+ * Saved R0
+ * Saved R26 (RA)
+ * Parameter build area
+ * (low memory)
+ */
+
+/* MASK(i,j) == (1<<i) + (1<<(i+1)) + ... + (1<<j)). Assume i<=j<31. */
+#define MASK(i,j) ((((LONGEST)1 << ((j)+1)) - 1) ^ (((LONGEST)1 << (i)) - 1))
+#define GEN_REG_SAVE_MASK (MASK(0,8) | MASK(16,29))
+#define GEN_REG_SAVE_COUNT 24
+#define FLOAT_REG_SAVE_MASK (MASK(0,1) | MASK(10,30))
+#define FLOAT_REG_SAVE_COUNT 23
+ /* The special register is the PC as we have no bit for it in the save masks.
+ alpha_frame_saved_pc knows where the pc is saved in a dummy frame. */
+#define SPECIAL_REG_SAVE_COUNT 1
+
+ PROC_REG_MASK (proc_desc) = GEN_REG_SAVE_MASK;
+ PROC_FREG_MASK (proc_desc) = FLOAT_REG_SAVE_MASK;
+ /* PROC_REG_OFFSET is the offset from the dummy frame to the saved RA,
+ but keep SP aligned to a multiple of 16. */
+ PROC_REG_OFFSET (proc_desc) =
+ -((8 * (SPECIAL_REG_SAVE_COUNT
+ + GEN_REG_SAVE_COUNT
+ + FLOAT_REG_SAVE_COUNT)
+ + 15) & ~15);
+ PROC_FREG_OFFSET (proc_desc) =
+ PROC_REG_OFFSET (proc_desc) + 8 * GEN_REG_SAVE_COUNT;
+
+ /* Save general registers.
+ The return address register is the first saved register, all other
+ registers follow in ascending order.
+ The PC is saved immediately below the SP. */
+ save_address = sp + PROC_REG_OFFSET (proc_desc);
+ store_address (raw_buffer, 8, read_register (ALPHA_RA_REGNUM));
+ write_memory (save_address, raw_buffer, 8);
+ save_address += 8;
+ mask = PROC_REG_MASK (proc_desc) & 0xffffffffL;
+ for (ireg = 0; mask; ireg++, mask >>= 1)
+ if (mask & 1)
+ {
+ if (ireg == ALPHA_RA_REGNUM)
+ continue;
+ store_address (raw_buffer, 8, read_register (ireg));
+ write_memory (save_address, raw_buffer, 8);
+ save_address += 8;
+ }
+
+ store_address (raw_buffer, 8, read_register (PC_REGNUM));
+ write_memory (sp - 8, raw_buffer, 8);
+
+ /* Save floating point registers. */
+ save_address = sp + PROC_FREG_OFFSET (proc_desc);
+ mask = PROC_FREG_MASK (proc_desc) & 0xffffffffL;
+ for (ireg = 0; mask; ireg++, mask >>= 1)
+ if (mask & 1)
+ {
+ store_address (raw_buffer, 8, read_register (ireg + FP0_REGNUM));
+ write_memory (save_address, raw_buffer, 8);
+ save_address += 8;
+ }
+
+ /* Set and save the frame address for the dummy.
+ This is tricky. The only registers that are suitable for a frame save
+ are those that are preserved across procedure calls (s0-s6). But if
+ a read system call is interrupted and then a dummy call is made
+ (see testsuite/gdb.t17/interrupt.exp) the dummy call hangs till the read
+ is satisfied. Then it returns with the s0-s6 registers set to the values
+ on entry to the read system call and our dummy frame pointer would be
+ destroyed. So we save the dummy frame in the proc_desc and handle the
+ retrieval of the frame pointer of a dummy specifically. The frame register
+ is set to the virtual frame (pseudo) register, it's value will always
+ be read as zero and will help us to catch any errors in the dummy frame
+ retrieval code. */
+ PROC_DUMMY_FRAME (proc_desc) = sp;
+ PROC_FRAME_REG (proc_desc) = FP_REGNUM;
+ PROC_FRAME_OFFSET (proc_desc) = 0;
+ sp += PROC_REG_OFFSET (proc_desc);
+ write_register (SP_REGNUM, sp);
+
+ PROC_LOW_ADDR (proc_desc) = CALL_DUMMY_ADDRESS ();
+ PROC_HIGH_ADDR (proc_desc) = PROC_LOW_ADDR (proc_desc) + 4;
+
+ SET_PROC_DESC_IS_DUMMY (proc_desc);
+ PROC_PC_REG (proc_desc) = ALPHA_RA_REGNUM;
+}
+
+static void
+alpha_pop_frame (void)
+{
+ register int regnum;
+ struct frame_info *frame = get_current_frame ();
+ CORE_ADDR new_sp = frame->frame;
+
+ alpha_extra_func_info_t proc_desc = frame->extra_info->proc_desc;
+
+ /* we need proc_desc to know how to restore the registers;
+ if it is NULL, construct (a temporary) one */
+ if (proc_desc == NULL)
+ proc_desc = find_proc_desc (frame->pc, frame->next);
+
+ /* Question: should we copy this proc_desc and save it in
+ frame->proc_desc? If we do, who will free it?
+ For now, we don't save a copy... */
+
+ write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
+ if (frame->saved_regs == NULL)
+ alpha_find_saved_regs (frame);
+ if (proc_desc)
+ {
+ for (regnum = 32; --regnum >= 0;)
+ if (PROC_REG_MASK (proc_desc) & (1 << regnum))
+ write_register (regnum,
+ read_memory_integer (frame->saved_regs[regnum],
+ 8));
+ for (regnum = 32; --regnum >= 0;)
+ if (PROC_FREG_MASK (proc_desc) & (1 << regnum))
+ write_register (regnum + FP0_REGNUM,
+ read_memory_integer (frame->saved_regs[regnum + FP0_REGNUM], 8));
+ }
+ write_register (SP_REGNUM, new_sp);
+ flush_cached_frames ();
+
+ if (proc_desc && (PROC_DESC_IS_DUMMY (proc_desc)
+ || alpha_proc_desc_is_dyn_sigtramp (proc_desc)))
+ {
+ struct linked_proc_info *pi_ptr, *prev_ptr;
+
+ for (pi_ptr = linked_proc_desc_table, prev_ptr = NULL;
+ pi_ptr != NULL;
+ prev_ptr = pi_ptr, pi_ptr = pi_ptr->next)
+ {
+ if (&pi_ptr->info == proc_desc)
+ break;
+ }
+
+ if (pi_ptr == NULL)
+ error ("Can't locate dummy extra frame info\n");
+
+ if (prev_ptr != NULL)
+ prev_ptr->next = pi_ptr->next;
+ else
+ linked_proc_desc_table = pi_ptr->next;
+
+ xfree (pi_ptr);
+ }
+}
+
+/* To skip prologues, I use this predicate. Returns either PC itself
+ if the code at PC does not look like a function prologue; otherwise
+ returns an address that (if we're lucky) follows the prologue. If
+ LENIENT, then we must skip everything which is involved in setting
+ up the frame (it's OK to skip more, just so long as we don't skip
+ anything which might clobber the registers which are being saved.
+ Currently we must not skip more on the alpha, but we might need the
+ lenient stuff some day. */
+
+static CORE_ADDR
+alpha_skip_prologue_internal (CORE_ADDR pc, int lenient)
+{
+ unsigned long inst;
+ int offset;
+ CORE_ADDR post_prologue_pc;
+ char buf[4];
+
+ /* Silently return the unaltered pc upon memory errors.
+ This could happen on OSF/1 if decode_line_1 tries to skip the
+ prologue for quickstarted shared library functions when the
+ shared library is not yet mapped in.
+ Reading target memory is slow over serial lines, so we perform
+ this check only if the target has shared libraries (which all
+ Alpha targets do). */
+ if (target_read_memory (pc, buf, 4))
+ return pc;
+
+ /* See if we can determine the end of the prologue via the symbol table.
+ If so, then return either PC, or the PC after the prologue, whichever
+ is greater. */
+
+ post_prologue_pc = after_prologue (pc, NULL);
+
+ if (post_prologue_pc != 0)
+ return max (pc, post_prologue_pc);
+
+ /* Can't determine prologue from the symbol table, need to examine
+ instructions. */
+
+ /* Skip the typical prologue instructions. These are the stack adjustment
+ instruction and the instructions that save registers on the stack
+ or in the gcc frame. */
+ for (offset = 0; offset < 100; offset += 4)
+ {
+ int status;
+
+ status = read_memory_nobpt (pc + offset, buf, 4);
+ if (status)
+ memory_error (status, pc + offset);
+ inst = extract_unsigned_integer (buf, 4);
+
+ /* The alpha has no delay slots. But let's keep the lenient stuff,
+ we might need it for something else in the future. */
+ if (lenient && 0)
+ continue;
+
+ if ((inst & 0xffff0000) == 0x27bb0000) /* ldah $gp,n($t12) */
+ continue;
+ if ((inst & 0xffff0000) == 0x23bd0000) /* lda $gp,n($gp) */
+ continue;
+ if ((inst & 0xffff0000) == 0x23de0000) /* lda $sp,n($sp) */
+ continue;
+ if ((inst & 0xffe01fff) == 0x43c0153e) /* subq $sp,n,$sp */
+ continue;
+
+ if ((inst & 0xfc1f0000) == 0xb41e0000
+ && (inst & 0xffff0000) != 0xb7fe0000)
+ continue; /* stq reg,n($sp) */
+ /* reg != $zero */
+ if ((inst & 0xfc1f0000) == 0x9c1e0000
+ && (inst & 0xffff0000) != 0x9ffe0000)
+ continue; /* stt reg,n($sp) */
+ /* reg != $zero */
+ if (inst == 0x47de040f) /* bis sp,sp,fp */
+ continue;
+
+ break;
+ }
+ return pc + offset;
+}
+
+static CORE_ADDR
+alpha_skip_prologue (CORE_ADDR addr)
+{
+ return (alpha_skip_prologue_internal (addr, 0));
+}
+
+#if 0
+/* Is address PC in the prologue (loosely defined) for function at
+ STARTADDR? */
+
+static int
+alpha_in_lenient_prologue (CORE_ADDR startaddr, CORE_ADDR pc)
+{
+ CORE_ADDR end_prologue = alpha_skip_prologue_internal (startaddr, 1);
+ return pc >= startaddr && pc < end_prologue;
+}
+#endif
+
+/* The alpha needs a conversion between register and memory format if
+ the register is a floating point register and
+ memory format is float, as the register format must be double
+ or
+ memory format is an integer with 4 bytes or less, as the representation
+ of integers in floating point registers is different. */
+static void
+alpha_register_convert_to_virtual (int regnum, struct type *valtype,
+ char *raw_buffer, char *virtual_buffer)
+{
+ if (TYPE_LENGTH (valtype) >= REGISTER_RAW_SIZE (regnum))
+ {
+ memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum));
+ return;
+ }
+
+ if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
+ {
+ double d = extract_floating (raw_buffer, REGISTER_RAW_SIZE (regnum));
+ store_floating (virtual_buffer, TYPE_LENGTH (valtype), d);
+ }
+ else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4)
+ {
+ ULONGEST l;
+ l = extract_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum));
+ l = ((l >> 32) & 0xc0000000) | ((l >> 29) & 0x3fffffff);
+ store_unsigned_integer (virtual_buffer, TYPE_LENGTH (valtype), l);
+ }
+ else
+ error ("Cannot retrieve value from floating point register");
+}
+
+static void
+alpha_register_convert_to_raw (struct type *valtype, int regnum,
+ char *virtual_buffer, char *raw_buffer)
+{
+ if (TYPE_LENGTH (valtype) >= REGISTER_RAW_SIZE (regnum))
+ {
+ memcpy (raw_buffer, virtual_buffer, REGISTER_RAW_SIZE (regnum));
+ return;
+ }
+
+ if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
+ {
+ double d = extract_floating (virtual_buffer, TYPE_LENGTH (valtype));
+ store_floating (raw_buffer, REGISTER_RAW_SIZE (regnum), d);
+ }
+ else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4)
+ {
+ ULONGEST l;
+ if (TYPE_UNSIGNED (valtype))
+ l = extract_unsigned_integer (virtual_buffer, TYPE_LENGTH (valtype));
+ else
+ l = extract_signed_integer (virtual_buffer, TYPE_LENGTH (valtype));
+ l = ((l & 0xc0000000) << 32) | ((l & 0x3fffffff) << 29);
+ store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum), l);
+ }
+ else
+ error ("Cannot store value in floating point register");
+}
+
+static const unsigned char *
+alpha_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+ static const unsigned char alpha_breakpoint[] =
+ { 0x80, 0, 0, 0 }; /* call_pal bpt */
+
+ *lenptr = sizeof(alpha_breakpoint);
+ return (alpha_breakpoint);
+}
+
+/* Given a return value in `regbuf' with a type `valtype',
+ extract and copy its value into `valbuf'. */
+
+static void
+alpha_extract_return_value (struct type *valtype,
+ char regbuf[ALPHA_REGISTER_BYTES], char *valbuf)
+{
+ if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
+ alpha_register_convert_to_virtual (FP0_REGNUM, valtype,
+ regbuf + REGISTER_BYTE (FP0_REGNUM),
+ valbuf);
+ else
+ memcpy (valbuf, regbuf + REGISTER_BYTE (ALPHA_V0_REGNUM),
+ TYPE_LENGTH (valtype));
+}
+
+/* Given a return value in `regbuf' with a type `valtype',
+ write its value into the appropriate register. */
+
+static void
+alpha_store_return_value (struct type *valtype, char *valbuf)
+{
+ char raw_buffer[ALPHA_MAX_REGISTER_RAW_SIZE];
+ int regnum = ALPHA_V0_REGNUM;
+ int length = TYPE_LENGTH (valtype);
+
+ if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
+ {
+ regnum = FP0_REGNUM;
+ length = REGISTER_RAW_SIZE (regnum);
+ alpha_register_convert_to_raw (valtype, regnum, valbuf, raw_buffer);
+ }
+ else
+ memcpy (raw_buffer, valbuf, length);
+
+ write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, length);
+}
+
+/* Just like reinit_frame_cache, but with the right arguments to be
+ callable as an sfunc. */
+
+static void
+reinit_frame_cache_sfunc (char *args, int from_tty, struct cmd_list_element *c)
+{
+ reinit_frame_cache ();
+}
+
+/* This is the definition of CALL_DUMMY_ADDRESS. It's a heuristic that is used
+ to find a convenient place in the text segment to stick a breakpoint to
+ detect the completion of a target function call (ala call_function_by_hand).
+ */
+
+CORE_ADDR
+alpha_call_dummy_address (void)
+{
+ CORE_ADDR entry;
+ struct minimal_symbol *sym;
+
+ entry = entry_point_address ();
+
+ if (entry != 0)
+ return entry;
+
+ sym = lookup_minimal_symbol ("_Prelude", NULL, symfile_objfile);
+
+ if (!sym || MSYMBOL_TYPE (sym) != mst_text)
+ return 0;
+ else
+ return SYMBOL_VALUE_ADDRESS (sym) + 4;
+}
+
+static void
+alpha_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+ struct value **args, struct type *type, int gcc_p)
+{
+ CORE_ADDR bp_address = CALL_DUMMY_ADDRESS ();
+
+ if (bp_address == 0)
+ error ("no place to put call");
+ write_register (ALPHA_RA_REGNUM, bp_address);
+ write_register (ALPHA_T12_REGNUM, fun);
+}
+
+/* On the Alpha, the call dummy code is nevery copied to user space
+ (see alpha_fix_call_dummy() above). The contents of this do not
+ matter. */
+LONGEST alpha_call_dummy_words[] = { 0 };
+
+static int
+alpha_use_struct_convention (int gcc_p, struct type *type)
+{
+ /* Structures are returned by ref in extra arg0. */
+ return 1;
+}
+
+static void
+alpha_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ /* Store the address of the place in which to copy the structure the
+ subroutine will return. Handled by alpha_push_arguments. */
+}
+
+static CORE_ADDR
+alpha_extract_struct_value_address (char *regbuf)
+{
+ return (extract_address (regbuf + REGISTER_BYTE (ALPHA_V0_REGNUM),
+ REGISTER_RAW_SIZE (ALPHA_V0_REGNUM)));
+}
+
+/* Figure out where the longjmp will land.
+ We expect the first arg to be a pointer to the jmp_buf structure from
+ which we extract the PC (JB_PC) that we will land at. The PC is copied
+ into the "pc". This routine returns true on success. */
+
+static int
+alpha_get_longjmp_target (CORE_ADDR *pc)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ CORE_ADDR jb_addr;
+ char raw_buffer[ALPHA_MAX_REGISTER_RAW_SIZE];
+
+ jb_addr = read_register (ALPHA_A0_REGNUM);
+
+ if (target_read_memory (jb_addr + (tdep->jb_pc * tdep->jb_elt_size),
+ raw_buffer, tdep->jb_elt_size))
+ return 0;
+
+ *pc = extract_address (raw_buffer, tdep->jb_elt_size);
+ return 1;
+}
+
+/* alpha_software_single_step() is called just before we want to resume
+ the inferior, if we want to single-step it but there is no hardware
+ or kernel single-step support (NetBSD on Alpha, for example). We find
+ the target of the coming instruction and breakpoint it.
+
+ single_step is also called just after the inferior stops. If we had
+ set up a simulated single-step, we undo our damage. */
+
+static CORE_ADDR
+alpha_next_pc (CORE_ADDR pc)
+{
+ unsigned int insn;
+ unsigned int op;
+ int offset;
+ LONGEST rav;
+
+ insn = read_memory_unsigned_integer (pc, sizeof (insn));
+
+ /* Opcode is top 6 bits. */
+ op = (insn >> 26) & 0x3f;
+
+ if (op == 0x1a)
+ {
+ /* Jump format: target PC is:
+ RB & ~3 */
+ return (read_register ((insn >> 16) & 0x1f) & ~3);
+ }
+
+ if ((op & 0x30) == 0x30)
+ {
+ /* Branch format: target PC is:
+ (new PC) + (4 * sext(displacement)) */
+ if (op == 0x30 || /* BR */
+ op == 0x34) /* BSR */
+ {
+ branch_taken:
+ offset = (insn & 0x001fffff);
+ if (offset & 0x00100000)
+ offset |= 0xffe00000;
+ offset *= 4;
+ return (pc + 4 + offset);
+ }
+
+ /* Need to determine if branch is taken; read RA. */
+ rav = (LONGEST) read_register ((insn >> 21) & 0x1f);
+ switch (op)
+ {
+ case 0x38: /* BLBC */
+ if ((rav & 1) == 0)
+ goto branch_taken;
+ break;
+ case 0x3c: /* BLBS */
+ if (rav & 1)
+ goto branch_taken;
+ break;
+ case 0x39: /* BEQ */
+ if (rav == 0)
+ goto branch_taken;
+ break;
+ case 0x3d: /* BNE */
+ if (rav != 0)
+ goto branch_taken;
+ break;
+ case 0x3a: /* BLT */
+ if (rav < 0)
+ goto branch_taken;
+ break;
+ case 0x3b: /* BLE */
+ if (rav <= 0)
+ goto branch_taken;
+ break;
+ case 0x3f: /* BGT */
+ if (rav > 0)
+ goto branch_taken;
+ break;
+ case 0x3e: /* BGE */
+ if (rav >= 0)
+ goto branch_taken;
+ break;
+ }
+ }
+
+ /* Not a branch or branch not taken; target PC is:
+ pc + 4 */
+ return (pc + 4);
+}
+
+void
+alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
+{
+ static CORE_ADDR next_pc;
+ typedef char binsn_quantum[BREAKPOINT_MAX];
+ static binsn_quantum break_mem;
+ CORE_ADDR pc;
+
+ if (insert_breakpoints_p)
+ {
+ pc = read_pc ();
+ next_pc = alpha_next_pc (pc);
+
+ target_insert_breakpoint (next_pc, break_mem);
+ }
+ else
+ {
+ target_remove_breakpoint (next_pc, break_mem);
+ write_pc (next_pc);
+ }
+}
+
+
+
+/* Initialize the current architecture based on INFO. If possible, re-use an
+ architecture from ARCHES, which is a list of architectures already created
+ during this debugging session.
+
+ Called e.g. at program startup, when reading a core file, and when reading
+ a binary file. */
+
+static struct gdbarch *
+alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch_tdep *tdep;
+ struct gdbarch *gdbarch;
+ enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
+
+ /* Try to determine the ABI of the object we are loading. */
+
+ if (info.abfd != NULL)
+ {
+ osabi = gdbarch_lookup_osabi (info.abfd);
+ if (osabi == GDB_OSABI_UNKNOWN)
+ {
+ /* If it's an ECOFF file, assume it's OSF/1. */
+ if (bfd_get_flavour (info.abfd) == bfd_target_ecoff_flavour)
+ osabi = GDB_OSABI_OSF1;
+ }
+ }
+
+ /* Find a candidate among extant architectures. */
+ for (arches = gdbarch_list_lookup_by_info (arches, &info);
+ arches != NULL;
+ arches = gdbarch_list_lookup_by_info (arches->next, &info))
+ {
+ /* Make sure the ABI selection matches. */
+ tdep = gdbarch_tdep (arches->gdbarch);
+ if (tdep && tdep->osabi == osabi)
+ return arches->gdbarch;
+ }
+
+ tdep = xmalloc (sizeof (struct gdbarch_tdep));
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ tdep->osabi = osabi;
+
+ /* Lowest text address. This is used by heuristic_proc_start() to
+ decide when to stop looking. */
+ tdep->vm_min_address = (CORE_ADDR) 0x120000000;
+
+ tdep->dynamic_sigtramp_offset = NULL;
+ tdep->skip_sigtramp_frame = NULL;
+ tdep->sigcontext_addr = NULL;
+
+ tdep->jb_pc = -1; /* longjmp support not enabled by default */
+
+ /* Type sizes */
+ set_gdbarch_short_bit (gdbarch, 16);
+ set_gdbarch_int_bit (gdbarch, 32);
+ set_gdbarch_long_bit (gdbarch, 64);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+ set_gdbarch_float_bit (gdbarch, 32);
+ set_gdbarch_double_bit (gdbarch, 64);
+ set_gdbarch_long_double_bit (gdbarch, 64);
+ set_gdbarch_ptr_bit (gdbarch, 64);
+
+ /* Register info */
+ set_gdbarch_num_regs (gdbarch, ALPHA_NUM_REGS);
+ set_gdbarch_sp_regnum (gdbarch, ALPHA_SP_REGNUM);
+ set_gdbarch_fp_regnum (gdbarch, ALPHA_FP_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, ALPHA_PC_REGNUM);
+ set_gdbarch_fp0_regnum (gdbarch, ALPHA_FP0_REGNUM);
+
+ set_gdbarch_register_name (gdbarch, alpha_register_name);
+ set_gdbarch_register_size (gdbarch, ALPHA_REGISTER_SIZE);
+ set_gdbarch_register_bytes (gdbarch, ALPHA_REGISTER_BYTES);
+ set_gdbarch_register_byte (gdbarch, alpha_register_byte);
+ set_gdbarch_register_raw_size (gdbarch, alpha_register_raw_size);
+ set_gdbarch_max_register_raw_size (gdbarch, ALPHA_MAX_REGISTER_RAW_SIZE);
+ set_gdbarch_register_virtual_size (gdbarch, alpha_register_virtual_size);
+ set_gdbarch_max_register_virtual_size (gdbarch,
+ ALPHA_MAX_REGISTER_VIRTUAL_SIZE);
+ set_gdbarch_register_virtual_type (gdbarch, alpha_register_virtual_type);
+
+ set_gdbarch_cannot_fetch_register (gdbarch, alpha_cannot_fetch_register);
+ set_gdbarch_cannot_store_register (gdbarch, alpha_cannot_store_register);
+
+ set_gdbarch_register_convertible (gdbarch, alpha_register_convertible);
+ set_gdbarch_register_convert_to_virtual (gdbarch,
+ alpha_register_convert_to_virtual);
+ set_gdbarch_register_convert_to_raw (gdbarch, alpha_register_convert_to_raw);
+
+ set_gdbarch_skip_prologue (gdbarch, alpha_skip_prologue);
+
+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+ set_gdbarch_frameless_function_invocation (gdbarch,
+ generic_frameless_function_invocation_not);
+
+ set_gdbarch_saved_pc_after_call (gdbarch, alpha_saved_pc_after_call);
+
+ set_gdbarch_frame_chain (gdbarch, alpha_frame_chain);
+ set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
+ set_gdbarch_frame_saved_pc (gdbarch, alpha_frame_saved_pc);
+
+ set_gdbarch_frame_init_saved_regs (gdbarch, alpha_frame_init_saved_regs);
+ set_gdbarch_get_saved_register (gdbarch, alpha_get_saved_register);
+
+ set_gdbarch_use_struct_convention (gdbarch, alpha_use_struct_convention);
+ set_gdbarch_extract_return_value (gdbarch, alpha_extract_return_value);
+
+ set_gdbarch_store_struct_return (gdbarch, alpha_store_struct_return);
+ set_gdbarch_store_return_value (gdbarch, alpha_store_return_value);
+ set_gdbarch_extract_struct_value_address (gdbarch,
+ alpha_extract_struct_value_address);
+
+ /* Settings for calling functions in the inferior. */
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_push_arguments (gdbarch, alpha_push_arguments);
+ set_gdbarch_pop_frame (gdbarch, alpha_pop_frame);
+
+ /* On the Alpha, the call dummy code is never copied to user space,
+ stopping the user call is achieved via a bp_call_dummy breakpoint.
+ But we need a fake CALL_DUMMY definition to enable the proper
+ call_function_by_hand and to avoid zero length array warnings. */
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_words (gdbarch, alpha_call_dummy_words);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
+ set_gdbarch_frame_args_address (gdbarch, alpha_frame_args_address);
+ set_gdbarch_frame_locals_address (gdbarch, alpha_frame_locals_address);
+ set_gdbarch_init_extra_frame_info (gdbarch, alpha_init_extra_frame_info);
+
+ /* Alpha OSF/1 inhibits execution of code on the stack. But there is
+ no need for a dummy on the Alpha. PUSH_ARGUMENTS takes care of all
+ argument handling and bp_call_dummy takes care of stopping the dummy. */
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_address (gdbarch, alpha_call_dummy_address);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ set_gdbarch_push_dummy_frame (gdbarch, alpha_push_dummy_frame);
+ set_gdbarch_fix_call_dummy (gdbarch, alpha_fix_call_dummy);
+ set_gdbarch_init_frame_pc (gdbarch, init_frame_pc_noop);
+ set_gdbarch_init_frame_pc_first (gdbarch, alpha_init_frame_pc_first);
+
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+
+ /* Floats are always passed as doubles. */
+ set_gdbarch_coerce_float_to_double (gdbarch,
+ standard_coerce_float_to_double);
+
+ set_gdbarch_breakpoint_from_pc (gdbarch, alpha_breakpoint_from_pc);
+ set_gdbarch_decr_pc_after_break (gdbarch, 4);
+
+ set_gdbarch_function_start_offset (gdbarch, 0);
+ set_gdbarch_frame_args_skip (gdbarch, 0);
+
+ /* Hook in ABI-specific overrides, if they have been registered. */
+ gdbarch_init_osabi (info, gdbarch, osabi);
+
+ /* Now that we have tuned the configuration, set a few final things
+ based on what the OS ABI has told us. */
+
+ if (tdep->jb_pc >= 0)
+ set_gdbarch_get_longjmp_target (gdbarch, alpha_get_longjmp_target);
+
+ return gdbarch;
+}
+
+static void
+alpha_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (tdep == NULL)
+ return;
+
+ fprintf_unfiltered (file, "alpha_dump_tdep: OS ABI = %s\n",
+ gdbarch_osabi_name (tdep->osabi));
+
+ fprintf_unfiltered (file,
+ "alpha_dump_tdep: vm_min_address = 0x%lx\n",
+ (long) tdep->vm_min_address);
+
+ fprintf_unfiltered (file,
+ "alpha_dump_tdep: jb_pc = %d\n",
+ tdep->jb_pc);
+ fprintf_unfiltered (file,
+ "alpha_dump_tdep: jb_elt_size = %ld\n",
+ (long) tdep->jb_elt_size);
+}
+
+void
+_initialize_alpha_tdep (void)
+{
+ struct cmd_list_element *c;
+
+ gdbarch_register (bfd_arch_alpha, alpha_gdbarch_init, alpha_dump_tdep);
+
+ tm_print_insn = print_insn_alpha;
+
+ /* Let the user set the fence post for heuristic_proc_start. */
+
+ /* We really would like to have both "0" and "unlimited" work, but
+ command.c doesn't deal with that. So make it a var_zinteger
+ because the user can always use "999999" or some such for unlimited. */
+ c = add_set_cmd ("heuristic-fence-post", class_support, var_zinteger,
+ (char *) &heuristic_fence_post,
+ "\
+Set the distance searched for the start of a function.\n\
+If you are debugging a stripped executable, GDB needs to search through the\n\
+program for the start of a function. This command sets the distance of the\n\
+search. The only need to set it is when debugging a stripped executable.",
+ &setlist);
+ /* We need to throw away the frame cache when we set this, since it
+ might change our ability to get backtraces. */
+ set_cmd_sfunc (c, reinit_frame_cache_sfunc);
+ add_show_from_set (c, &showlist);
+}
diff --git a/gdb/alpha-tdep.h b/gdb/alpha-tdep.h
new file mode 100644
index 00000000000..cea232b502c
--- /dev/null
+++ b/gdb/alpha-tdep.h
@@ -0,0 +1,109 @@
+/* Common target dependent code for GDB on Alpha systems.
+ Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002 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. */
+
+#ifndef ALPHA_TDEP_H
+#define ALPHA_TDEP_H
+
+#include "osabi.h"
+
+/* Say how long (ordinary) registers are. This is a piece of bogosity
+ used in push_word and a few other places; REGISTER_RAW_SIZE is the
+ real way to know how big a register is. */
+#define ALPHA_REGISTER_SIZE 8
+
+/* Number of machine registers. */
+#define ALPHA_NUM_REGS 66
+
+/* Total amount of space needed to store our copies of the machine's
+ register state. */
+#define ALPHA_REGISTER_BYTES (ALPHA_NUM_REGS * 8)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+#define ALPHA_MAX_REGISTER_RAW_SIZE 8
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+#define ALPHA_MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Register numbers of various important registers.
+ Note that most of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and FP_REGNUM is a "phony" register number which is too large
+ to be an actual register number as far as the user is concerned
+ but serves to get the desired value when passed to read_register. */
+
+#define ALPHA_V0_REGNUM 0 /* Function integer return value */
+#define ALPHA_T7_REGNUM 8 /* Return address register for OSF/1 __add* */
+#define ALPHA_GCC_FP_REGNUM 15 /* Used by gcc as frame register */
+#define ALPHA_A0_REGNUM 16 /* Loc of first arg during a subr call */
+#define ALPHA_T9_REGNUM 23 /* Return address register for OSF/1 __div* */
+#define ALPHA_T12_REGNUM 27 /* Contains start addr of current proc */
+#define ALPHA_SP_REGNUM 30 /* Contains address of top of stack */
+#define ALPHA_RA_REGNUM 26 /* Contains return address value */
+#define ALPHA_ZERO_REGNUM 31 /* Read-only register, always 0 */
+#define ALPHA_FP0_REGNUM 32 /* Floating point register 0 */
+#define ALPHA_FPA0_REGNUM 48 /* First float arg during a subr call */
+#define ALPHA_FPCR_REGNUM 63 /* Floating point control register */
+#define ALPHA_PC_REGNUM 64 /* Contains program counter */
+#define ALPHA_FP_REGNUM 65 /* Virtual frame pointer */
+
+/* The alpha has two different virtual pointers for arguments and locals.
+
+ The virtual argument pointer is pointing to the bottom of the argument
+ transfer area, which is located immediately below the virtual frame
+ pointer. Its size is fixed for the native compiler, it is either zero
+ (for the no arguments case) or large enough to hold all argument registers.
+ gcc uses a variable sized argument transfer area. As it has
+ to stay compatible with the native debugging tools it has to use the same
+ virtual argument pointer and adjust the argument offsets accordingly.
+
+ The virtual local pointer is localoff bytes below the virtual frame
+ pointer, the value of localoff is obtained from the PDR. */
+#define ALPHA_NUM_ARG_REGS 6
+
+/* Target-dependent structure in gdbarch. */
+struct gdbarch_tdep
+{
+ enum gdb_osabi osabi; /* OS/ABI of inferior. */
+
+ CORE_ADDR vm_min_address; /* used by heuristic_proc_start */
+
+ /* If PC is inside a dynamically-generated signal trampoline function
+ (i.e. one copied onto the user stack at run-time), return how many
+ bytes PC is beyond the start of that function. Otherwise, return -1. */
+ LONGEST (*dynamic_sigtramp_offset) (CORE_ADDR);
+
+ /* If FRAME refers to a sigtramp frame, return the address of the next
+ frame. */
+ CORE_ADDR (*skip_sigtramp_frame) (struct frame_info *, CORE_ADDR);
+
+ /* Translate a signal handler frame into the address of the sigcontext
+ structure for that signal handler. */
+ CORE_ADDR (*sigcontext_addr) (struct frame_info *);
+
+ int jb_pc; /* Offset to PC value in jump buffer.
+ If htis is negative, longjmp support
+ will be disabled. */
+ size_t jb_elt_size; /* And the size of each entry in the buf. */
+};
+
+void alpha_software_single_step (enum target_signal, int);
+
+#endif /* ALPHA_TDEP_H */
diff --git a/gdb/alphabsd-nat.c b/gdb/alphabsd-nat.c
new file mode 100644
index 00000000000..b26d3ea7c48
--- /dev/null
+++ b/gdb/alphabsd-nat.c
@@ -0,0 +1,157 @@
+/* Native-dependent code for Alpha BSD's.
+ Copyright 2000, 2001, 2002 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 "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include "alpha-tdep.h"
+#include "alphabsd-tdep.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#ifdef HAVE_SYS_PROCFS_H
+#include <sys/procfs.h>
+#endif
+
+#ifndef HAVE_GREGSET_T
+typedef struct reg gregset_t;
+#endif
+
+#ifndef HAVE_FPREGSET_T
+typedef struct fpreg fpregset_t;
+#endif
+
+#include "gregset.h"
+
+/* Provide *regset() wrappers around the generic Alpha BSD register
+ supply/fill routines. */
+
+void
+supply_gregset (gregset_t *gregsetp)
+{
+ alphabsd_supply_reg ((char *) gregsetp, -1);
+}
+
+void
+fill_gregset (gregset_t *gregsetp, int regno)
+{
+ alphabsd_fill_reg ((char *) gregsetp, regno);
+}
+
+void
+supply_fpregset (fpregset_t *fpregsetp)
+{
+ alphabsd_supply_fpreg ((char *) fpregsetp, -1);
+}
+
+void
+fill_fpregset (fpregset_t *fpregsetp, int regno)
+{
+ alphabsd_fill_fpreg ((char *) fpregsetp, regno);
+}
+
+/* Determine if PT_GETREGS fetches this register. */
+
+static int
+getregs_supplies (int regno)
+{
+
+ return ((regno >= ALPHA_V0_REGNUM && regno <= ALPHA_ZERO_REGNUM)
+ || regno >= PC_REGNUM);
+}
+
+
+/* Fetch register REGNO from the inferior. If REGNO is -1, do this
+ for all registers (including the floating point registers). */
+
+void
+fetch_inferior_registers (int regno)
+{
+
+ if (regno == -1 || getregs_supplies (regno))
+ {
+ struct reg gregs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ alphabsd_supply_reg ((char *) &gregs, regno);
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1 || regno >= FP0_REGNUM)
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point status");
+
+ alphabsd_supply_fpreg ((char *) &fpregs, regno);
+ }
+
+ /* Reset virtual frame pointer. */
+ supply_register (FP_REGNUM, NULL);
+}
+
+/* Store register REGNO back into the inferior. If REGNO is -1, do
+ this for all registers (including the floating point registers). */
+
+void
+store_inferior_registers (int regno)
+{
+
+ if (regno == -1 || getregs_supplies (regno))
+ {
+ struct reg gregs;
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ alphabsd_fill_reg ((char *) &gregs, regno);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
+ perror_with_name ("Couldn't write registers");
+
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1 || regno >= FP0_REGNUM)
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point status");
+
+ alphabsd_fill_fpreg ((char *) &fpregs, regno);
+
+ if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't write floating point status");
+ }
+}
diff --git a/gdb/alphabsd-tdep.c b/gdb/alphabsd-tdep.c
new file mode 100644
index 00000000000..39a9b1ae77e
--- /dev/null
+++ b/gdb/alphabsd-tdep.c
@@ -0,0 +1,102 @@
+/* Common target dependent code for GDB on Alpha systems running BSD.
+ Copyright 2000, 2001, 2002 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 "defs.h"
+#include "regcache.h"
+
+#include "alpha-tdep.h"
+#include "alphabsd-tdep.h"
+
+/* Number of general-purpose registers. */
+#define NUM_GREGS 32
+
+/* Number of floating-point registers. */
+#define NUM_FPREGS 31
+
+/* Conviently, GDB uses the same register numbering as the
+ ptrace register structure used by BSD on Alpha. */
+
+void
+alphabsd_supply_reg (char *regs, int regno)
+{
+ int i;
+
+ for (i = 0; i < NUM_GREGS; i++)
+ {
+ if (i == regno || regno == -1)
+ {
+ if (CANNOT_FETCH_REGISTER (i))
+ supply_register (i, NULL);
+ else
+ supply_register (i, regs + (i * 8));
+ }
+ }
+
+ /* The PC travels in the ZERO slot. */
+ if (regno == PC_REGNUM || regno == -1)
+ supply_register (PC_REGNUM, regs + (31 * 8));
+}
+
+void
+alphabsd_fill_reg (char *regs, int regno)
+{
+ int i;
+
+ for (i = 0; i < NUM_GREGS; i++)
+ if ((regno == i || regno == -1) && ! CANNOT_STORE_REGISTER (i))
+ regcache_collect (i, regs + (i * 8));
+
+ /* The PC travels in the ZERO slot. */
+ if (regno == PC_REGNUM || regno == -1)
+ regcache_collect (PC_REGNUM, regs + (31 * 8));
+}
+
+void
+alphabsd_supply_fpreg (char *fpregs, int regno)
+{
+ int i;
+
+ for (i = FP0_REGNUM; i < FP0_REGNUM + NUM_FPREGS; i++)
+ {
+ if (i == regno || regno == -1)
+ {
+ if (CANNOT_FETCH_REGISTER (i))
+ supply_register (i, NULL);
+ else
+ supply_register (i, fpregs + ((i - FP0_REGNUM) * 8));
+ }
+ }
+
+ if (regno == ALPHA_FPCR_REGNUM || regno == -1)
+ supply_register (ALPHA_FPCR_REGNUM, fpregs + (32 * 8));
+}
+
+void
+alphabsd_fill_fpreg (char *fpregs, int regno)
+{
+ int i;
+
+ for (i = FP0_REGNUM; i < FP0_REGNUM + NUM_FPREGS; i++)
+ if ((regno == i || regno == -1) && ! CANNOT_STORE_REGISTER (i))
+ regcache_collect (i, fpregs + ((i - FP0_REGNUM) * 8));
+
+ if (regno == ALPHA_FPCR_REGNUM || regno == -1)
+ regcache_collect (ALPHA_FPCR_REGNUM, fpregs + (32 * 8));
+}
diff --git a/gdb/alphabsd-tdep.h b/gdb/alphabsd-tdep.h
new file mode 100644
index 00000000000..48d87988ff6
--- /dev/null
+++ b/gdb/alphabsd-tdep.h
@@ -0,0 +1,33 @@
+/* Common target dependent code for GDB on Alpha systems running BSD.
+ Copyright 2002 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. */
+
+#ifndef ALPHABSD_TDEP_H
+#define ALPHABSD_TDEP_H
+
+void alphabsd_supply_reg (char *, int);
+void alphabsd_fill_reg (char *, int);
+
+void alphabsd_supply_fpreg (char *, int);
+void alphabsd_fill_fpreg (char *, int);
+
+#define SIZEOF_STRUCT_REG (32 * 8)
+#define SIZEOF_STRUCT_FPREG (33 * 8)
+
+#endif /* ALPHABSD_TDEP_H */
diff --git a/gdb/alphafbsd-tdep.c b/gdb/alphafbsd-tdep.c
new file mode 100644
index 00000000000..f8f515d3cc8
--- /dev/null
+++ b/gdb/alphafbsd-tdep.c
@@ -0,0 +1,83 @@
+/* Target-dependent code for FreeBSD/Alpha.
+ Copyright 2001, 2002 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 "defs.h"
+#include "value.h"
+
+#include "alpha-tdep.h"
+
+static int
+alphafbsd_use_struct_convention (int gcc_p, struct type *type)
+{
+ enum type_code code;
+ int i;
+
+ /* All aggregate types that won't fit in a register must be returned
+ in memory. */
+ if (TYPE_LENGTH (type) > REGISTER_SIZE)
+ return 1;
+
+ /* The only aggregate types that can be returned in a register are
+ structs and unions. Arrays must be returned in memory. */
+ code = TYPE_CODE (type);
+ if (code != TYPE_CODE_STRUCT && code != TYPE_CODE_UNION)
+ return 1;
+
+ /* We need to check if this struct/union is "integer" like. For
+ this to be true, the offset of each adressable subfield must be
+ zero. Note that bit fields are not addressable. */
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
+ {
+ /* If the field bitsize is non-zero, it isn't adressable. */
+ if (TYPE_FIELD_BITPOS (type, i) != 0
+ && TYPE_FIELD_BITSIZE (type, i) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+alphafbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name)
+{
+ /* FIXME */
+ return 0;
+}
+
+static void
+alphafbsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ set_gdbarch_pc_in_sigtramp (gdbarch, alphafbsd_pc_in_sigtramp);
+
+ set_gdbarch_use_struct_convention (gdbarch, alphafbsd_use_struct_convention);
+
+ tdep->jb_pc = 2;
+ tdep->jb_elt_size = 8;
+}
+
+void
+_initialize_alphafbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_alpha, GDB_OSABI_FREEBSD_ELF,
+ alphafbsd_init_abi);
+}
diff --git a/gdb/alphanbsd-tdep.c b/gdb/alphanbsd-tdep.c
new file mode 100644
index 00000000000..519d8164ca3
--- /dev/null
+++ b/gdb/alphanbsd-tdep.c
@@ -0,0 +1,213 @@
+/* Target-dependent code for NetBSD/Alpha.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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 "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "value.h"
+
+#include "solib-svr4.h"
+
+#include "alpha-tdep.h"
+#include "alphabsd-tdep.h"
+#include "nbsd-tdep.h"
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR ignore)
+{
+ char *regs, *fpregs;
+ int regno;
+
+ /* Table to map a gdb register number to a trapframe register index. */
+ static const int regmap[] =
+ {
+ 0, 1, 2, 3,
+ 4, 5, 6, 7,
+ 8, 9, 10, 11,
+ 12, 13, 14, 15,
+ 30, 31, 32, 16,
+ 17, 18, 19, 20,
+ 21, 22, 23, 24,
+ 25, 29, 26
+ };
+#define SIZEOF_TRAPFRAME (33 * 8)
+
+ /* We get everything from one section. */
+ if (which != 0)
+ return;
+
+ regs = core_reg_sect;
+ fpregs = core_reg_sect + SIZEOF_TRAPFRAME;
+
+ if (core_reg_size < (SIZEOF_TRAPFRAME + SIZEOF_STRUCT_FPREG))
+ {
+ warning ("Wrong size register set in core file.");
+ return;
+ }
+
+ /* Integer registers. */
+ for (regno = 0; regno < ALPHA_ZERO_REGNUM; regno++)
+ supply_register (regno, regs + (regmap[regno] * 8));
+ supply_register (ALPHA_ZERO_REGNUM, NULL);
+ supply_register (FP_REGNUM, NULL);
+ supply_register (PC_REGNUM, regs + (28 * 8));
+
+ /* Floating point registers. */
+ alphabsd_supply_fpreg (fpregs, -1);
+}
+
+static void
+fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR ignore)
+{
+ switch (which)
+ {
+ case 0: /* Integer registers. */
+ if (core_reg_size != SIZEOF_STRUCT_REG)
+ warning ("Wrong size register set in core file.");
+ else
+ alphabsd_supply_reg (core_reg_sect, -1);
+ break;
+
+ case 2: /* Floating point registers. */
+ if (core_reg_size != SIZEOF_STRUCT_FPREG)
+ warning ("Wrong size FP register set in core file.");
+ else
+ alphabsd_supply_fpreg (core_reg_sect, -1);
+ break;
+
+ default:
+ /* Don't know what kind of register request this is; just ignore it. */
+ break;
+ }
+}
+
+static struct core_fns alphanbsd_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+static struct core_fns alphanbsd_elfcore_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_elfcore_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+/* Under NetBSD/alpha, signal handler invocations can be identified by the
+ designated code sequence that is used to return from a signal handler.
+ In particular, the return address of a signal handler points to the
+ following code sequence:
+
+ ldq a0, 0(sp)
+ lda sp, 16(sp)
+ lda v0, 295(zero) # __sigreturn14
+ call_pal callsys
+
+ Each instruction has a unique encoding, so we simply attempt to match
+ the instruction the PC is pointing to with any of the above instructions.
+ If there is a hit, we know the offset to the start of the designated
+ sequence and can then check whether we really are executing in the
+ signal trampoline. If not, -1 is returned, otherwise the offset from the
+ start of the return sequence is returned. */
+static const unsigned char sigtramp_retcode[] =
+{
+ 0x00, 0x00, 0x1e, 0xa6, /* ldq a0, 0(sp) */
+ 0x10, 0x00, 0xde, 0x23, /* lda sp, 16(sp) */
+ 0x27, 0x01, 0x1f, 0x20, /* lda v0, 295(zero) */
+ 0x83, 0x00, 0x00, 0x00, /* call_pal callsys */
+};
+#define RETCODE_NWORDS 4
+#define RETCODE_SIZE (RETCODE_NWORDS * 4)
+
+LONGEST
+alphanbsd_sigtramp_offset (CORE_ADDR pc)
+{
+ unsigned char ret[RETCODE_SIZE], w[4];
+ LONGEST off;
+ int i;
+
+ if (read_memory_nobpt (pc, (char *) w, 4) != 0)
+ return -1;
+
+ for (i = 0; i < RETCODE_NWORDS; i++)
+ {
+ if (memcmp (w, sigtramp_retcode + (i * 4), 4) == 0)
+ break;
+ }
+ if (i == RETCODE_NWORDS)
+ return (-1);
+
+ off = i * 4;
+ pc -= off;
+
+ if (read_memory_nobpt (pc, (char *) ret, sizeof (ret)) != 0)
+ return -1;
+
+ if (memcmp (ret, sigtramp_retcode, RETCODE_SIZE) == 0)
+ return off;
+
+ return -1;
+}
+
+static int
+alphanbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name)
+{
+ return (alphanbsd_sigtramp_offset (pc) >= 0);
+}
+
+static void
+alphanbsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ set_gdbarch_pc_in_sigtramp (gdbarch, alphanbsd_pc_in_sigtramp);
+
+ /* NetBSD/alpha does not provide single step support via ptrace(2); we
+ must use software single-stepping. */
+ set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
+
+ set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ nbsd_lp64_solib_svr4_fetch_link_map_offsets);
+
+ tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset;
+
+ tdep->jb_pc = 2;
+ tdep->jb_elt_size = 8;
+}
+
+void
+_initialize_alphanbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_alpha, GDB_OSABI_NETBSD_ELF,
+ alphanbsd_init_abi);
+
+ add_core_fns (&alphanbsd_core_fns);
+ add_core_fns (&alphanbsd_elfcore_fns);
+}
diff --git a/gdb/annotate.c b/gdb/annotate.c
new file mode 100644
index 00000000000..66211e91f36
--- /dev/null
+++ b/gdb/annotate.c
@@ -0,0 +1,585 @@
+/* Annotation routines for GDB.
+ Copyright 1986, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1998, 1999,
+ 2000 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 "defs.h"
+#include "annotate.h"
+#include "value.h"
+#include "target.h"
+#include "gdbtypes.h"
+#include "breakpoint.h"
+
+
+/* Prototypes for local functions. */
+
+extern void _initialize_annotate (void);
+
+static void print_value_flags (struct type *);
+
+static void breakpoint_changed (struct breakpoint *);
+
+void (*annotate_starting_hook) (void);
+void (*annotate_stopped_hook) (void);
+void (*annotate_signalled_hook) (void);
+void (*annotate_signal_hook) (void);
+void (*annotate_exited_hook) (void);
+
+static int ignore_count_changed = 0;
+
+static void
+print_value_flags (struct type *t)
+{
+ if (can_dereference (t))
+ printf_filtered ("*");
+ else
+ printf_filtered ("-");
+}
+
+void
+breakpoints_changed (void)
+{
+ if (annotation_level > 1)
+ {
+ target_terminal_ours ();
+ printf_unfiltered ("\n\032\032breakpoints-invalid\n");
+ if (ignore_count_changed)
+ ignore_count_changed = 0; /* Avoid multiple break annotations. */
+ }
+}
+
+/* The GUI needs to be informed of ignore_count changes, but we don't
+ want to provide successive multiple breakpoints-invalid messages
+ that are all caused by the fact that the ignore count is changing
+ (which could keep the GUI very busy). One is enough, after the
+ target actually "stops". */
+
+void
+annotate_ignore_count_change (void)
+{
+ if (annotation_level > 1)
+ ignore_count_changed = 1;
+}
+
+void
+annotate_breakpoint (int num)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032breakpoint %d\n", num);
+}
+
+void
+annotate_catchpoint (int num)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032catchpoint %d\n", num);
+}
+
+void
+annotate_watchpoint (int num)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032watchpoint %d\n", num);
+}
+
+void
+annotate_starting (void)
+{
+
+ if (annotate_starting_hook)
+ annotate_starting_hook ();
+ else
+ {
+ if (annotation_level > 1)
+ {
+ printf_filtered ("\n\032\032starting\n");
+ }
+ }
+}
+
+void
+annotate_stopped (void)
+{
+ if (annotate_stopped_hook)
+ annotate_stopped_hook ();
+ else
+ {
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032stopped\n");
+ }
+ if (annotation_level > 1 && ignore_count_changed)
+ {
+ ignore_count_changed = 0;
+ breakpoints_changed ();
+ }
+}
+
+void
+annotate_exited (int exitstatus)
+{
+ if (annotate_exited_hook)
+ annotate_exited_hook ();
+ else
+ {
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032exited %d\n", exitstatus);
+ }
+}
+
+void
+annotate_signalled (void)
+{
+ if (annotate_signalled_hook)
+ annotate_signalled_hook ();
+
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032signalled\n");
+}
+
+void
+annotate_signal_name (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032signal-name\n");
+}
+
+void
+annotate_signal_name_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032signal-name-end\n");
+}
+
+void
+annotate_signal_string (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032signal-string\n");
+}
+
+void
+annotate_signal_string_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032signal-string-end\n");
+}
+
+void
+annotate_signal (void)
+{
+ if (annotate_signal_hook)
+ annotate_signal_hook ();
+
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032signal\n");
+}
+
+void
+annotate_breakpoints_headers (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032breakpoints-headers\n");
+}
+
+void
+annotate_field (int num)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032field %d\n", num);
+}
+
+void
+annotate_breakpoints_table (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032breakpoints-table\n");
+}
+
+void
+annotate_record (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032record\n");
+}
+
+void
+annotate_breakpoints_table_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032breakpoints-table-end\n");
+}
+
+void
+annotate_frames_invalid (void)
+{
+ if (annotation_level > 1)
+ {
+ target_terminal_ours ();
+ printf_unfiltered ("\n\032\032frames-invalid\n");
+ }
+}
+
+void
+annotate_field_begin (struct type *type)
+{
+ if (annotation_level > 1)
+ {
+ printf_filtered ("\n\032\032field-begin ");
+ print_value_flags (type);
+ printf_filtered ("\n");
+ }
+}
+
+void
+annotate_field_name_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032field-name-end\n");
+}
+
+void
+annotate_field_value (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032field-value\n");
+}
+
+void
+annotate_field_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032field-end\n");
+}
+
+void
+annotate_quit (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032quit\n");
+}
+
+void
+annotate_error (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032error\n");
+}
+
+void
+annotate_error_begin (void)
+{
+ if (annotation_level > 1)
+ fprintf_filtered (gdb_stderr, "\n\032\032error-begin\n");
+}
+
+void
+annotate_value_history_begin (int histindex, struct type *type)
+{
+ if (annotation_level > 1)
+ {
+ printf_filtered ("\n\032\032value-history-begin %d ", histindex);
+ print_value_flags (type);
+ printf_filtered ("\n");
+ }
+}
+
+void
+annotate_value_begin (struct type *type)
+{
+ if (annotation_level > 1)
+ {
+ printf_filtered ("\n\032\032value-begin ");
+ print_value_flags (type);
+ printf_filtered ("\n");
+ }
+}
+
+void
+annotate_value_history_value (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032value-history-value\n");
+}
+
+void
+annotate_value_history_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032value-history-end\n");
+}
+
+void
+annotate_value_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032value-end\n");
+}
+
+void
+annotate_display_begin (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032display-begin\n");
+}
+
+void
+annotate_display_number_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032display-number-end\n");
+}
+
+void
+annotate_display_format (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032display-format\n");
+}
+
+void
+annotate_display_expression (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032display-expression\n");
+}
+
+void
+annotate_display_expression_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032display-expression-end\n");
+}
+
+void
+annotate_display_value (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032display-value\n");
+}
+
+void
+annotate_display_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032display-end\n");
+}
+
+void
+annotate_arg_begin (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032arg-begin\n");
+}
+
+void
+annotate_arg_name_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032arg-name-end\n");
+}
+
+void
+annotate_arg_value (struct type *type)
+{
+ if (annotation_level > 1)
+ {
+ printf_filtered ("\n\032\032arg-value ");
+ print_value_flags (type);
+ printf_filtered ("\n");
+ }
+}
+
+void
+annotate_arg_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032arg-end\n");
+}
+
+void
+annotate_source (char *filename, int line, int character, int mid, CORE_ADDR pc)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032source ");
+ else
+ printf_filtered ("\032\032");
+
+ printf_filtered ("%s:%d:%d:%s:0x", filename,
+ line, character,
+ mid ? "middle" : "beg");
+ print_address_numeric (pc, 0, gdb_stdout);
+ printf_filtered ("\n");
+}
+
+void
+annotate_frame_begin (int level, CORE_ADDR pc)
+{
+ if (annotation_level > 1)
+ {
+ printf_filtered ("\n\032\032frame-begin %d 0x", level);
+ print_address_numeric (pc, 0, gdb_stdout);
+ printf_filtered ("\n");
+ }
+}
+
+void
+annotate_function_call (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032function-call\n");
+}
+
+void
+annotate_signal_handler_caller (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032signal-handler-caller\n");
+}
+
+void
+annotate_frame_address (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032frame-address\n");
+}
+
+void
+annotate_frame_address_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032frame-address-end\n");
+}
+
+void
+annotate_frame_function_name (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032frame-function-name\n");
+}
+
+void
+annotate_frame_args (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032frame-args\n");
+}
+
+void
+annotate_frame_source_begin (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032frame-source-begin\n");
+}
+
+void
+annotate_frame_source_file (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032frame-source-file\n");
+}
+
+void
+annotate_frame_source_file_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032frame-source-file-end\n");
+}
+
+void
+annotate_frame_source_line (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032frame-source-line\n");
+}
+
+void
+annotate_frame_source_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032frame-source-end\n");
+}
+
+void
+annotate_frame_where (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032frame-where\n");
+}
+
+void
+annotate_frame_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032frame-end\n");
+}
+
+void
+annotate_array_section_begin (int index, struct type *elttype)
+{
+ if (annotation_level > 1)
+ {
+ printf_filtered ("\n\032\032array-section-begin %d ", index);
+ print_value_flags (elttype);
+ printf_filtered ("\n");
+ }
+}
+
+void
+annotate_elt_rep (unsigned int repcount)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032elt-rep %u\n", repcount);
+}
+
+void
+annotate_elt_rep_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032elt-rep-end\n");
+}
+
+void
+annotate_elt (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032elt\n");
+}
+
+void
+annotate_array_section_end (void)
+{
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032array-section-end\n");
+}
+
+static void
+breakpoint_changed (struct breakpoint *b)
+{
+ breakpoints_changed ();
+}
+
+void
+_initialize_annotate (void)
+{
+ if (annotation_level > 1)
+ {
+ delete_breakpoint_hook = breakpoint_changed;
+ modify_breakpoint_hook = breakpoint_changed;
+ }
+}
diff --git a/gdb/annotate.h b/gdb/annotate.h
new file mode 100644
index 00000000000..ac3cec8f94f
--- /dev/null
+++ b/gdb/annotate.h
@@ -0,0 +1,106 @@
+/* Annotation routines for GDB.
+ Copyright 1986, 1989, 1990, 1991, 1992, 1994, 1998, 1999, 2000
+ 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 "symtab.h"
+#include "gdbtypes.h"
+
+extern void breakpoints_changed (void);
+
+extern void annotate_ignore_count_change (void);
+extern void annotate_breakpoint (int);
+extern void annotate_catchpoint (int);
+extern void annotate_watchpoint (int);
+extern void annotate_starting (void);
+extern void annotate_stopped (void);
+extern void annotate_exited (int);
+extern void annotate_signalled (void);
+extern void annotate_signal_name (void);
+extern void annotate_signal_name_end (void);
+extern void annotate_signal_string (void);
+extern void annotate_signal_string_end (void);
+extern void annotate_signal (void);
+
+extern void annotate_breakpoints_headers (void);
+extern void annotate_field (int);
+extern void annotate_breakpoints_table (void);
+extern void annotate_record (void);
+extern void annotate_breakpoints_table_end (void);
+
+extern void annotate_frames_invalid (void);
+
+struct type;
+
+extern void annotate_field_begin (struct type *);
+extern void annotate_field_name_end (void);
+extern void annotate_field_value (void);
+extern void annotate_field_end (void);
+
+extern void annotate_quit (void);
+extern void annotate_error (void);
+extern void annotate_error_begin (void);
+
+extern void annotate_value_history_begin (int, struct type *);
+extern void annotate_value_begin (struct type *);
+extern void annotate_value_history_value (void);
+extern void annotate_value_history_end (void);
+extern void annotate_value_end (void);
+
+extern void annotate_display_begin (void);
+extern void annotate_display_number_end (void);
+extern void annotate_display_format (void);
+extern void annotate_display_expression (void);
+extern void annotate_display_expression_end (void);
+extern void annotate_display_value (void);
+extern void annotate_display_end (void);
+
+extern void annotate_arg_begin (void);
+extern void annotate_arg_name_end (void);
+extern void annotate_arg_value (struct type *);
+extern void annotate_arg_end (void);
+
+extern void annotate_source (char *, int, int, int, CORE_ADDR);
+
+extern void annotate_frame_begin (int, CORE_ADDR);
+extern void annotate_function_call (void);
+extern void annotate_signal_handler_caller (void);
+extern void annotate_frame_address (void);
+extern void annotate_frame_address_end (void);
+extern void annotate_frame_function_name (void);
+extern void annotate_frame_args (void);
+extern void annotate_frame_source_begin (void);
+extern void annotate_frame_source_file (void);
+extern void annotate_frame_source_file_end (void);
+extern void annotate_frame_source_line (void);
+extern void annotate_frame_source_end (void);
+extern void annotate_frame_where (void);
+extern void annotate_frame_end (void);
+
+extern void annotate_array_section_begin (int, struct type *);
+extern void annotate_elt_rep (unsigned int);
+extern void annotate_elt_rep_end (void);
+extern void annotate_elt (void);
+extern void annotate_array_section_end (void);
+
+extern void (*annotate_starting_hook) (void);
+extern void (*annotate_stopped_hook) (void);
+extern void (*annotate_signalled_hook) (void);
+extern void (*annotate_signal_hook) (void);
+extern void (*annotate_exited_hook) (void);
diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c
new file mode 100644
index 00000000000..cab7721a440
--- /dev/null
+++ b/gdb/arc-tdep.c
@@ -0,0 +1,737 @@
+/* ARC target-dependent stuff.
+ Copyright 1995, 1996, 1999, 2000, 2001 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "floatformat.h"
+#include "symtab.h"
+#include "gdbcmd.h"
+#include "regcache.h"
+
+/* Local functions */
+
+static int arc_set_cpu_type (char *str);
+
+/* Current CPU, set with the "set cpu" command. */
+static int arc_bfd_mach_type;
+char *arc_cpu_type;
+char *tmp_arc_cpu_type;
+
+/* Table of cpu names. */
+struct
+ {
+ char *name;
+ int value;
+ }
+arc_cpu_type_table[] =
+{
+ { "arc5", bfd_mach_arc_5 },
+ { "arc6", bfd_mach_arc_6 },
+ { "arc7", bfd_mach_arc_7 },
+ { "arc8", bfd_mach_arc_8 },
+ { NULL, 0 }
+};
+
+/* Used by simulator. */
+int display_pipeline_p;
+int cpu_timer;
+/* This one must have the same type as used in the emulator.
+ It's currently an enum so this should be ok for now. */
+int debug_pipeline_p;
+
+#define ARC_CALL_SAVED_REG(r) ((r) >= 16 && (r) < 24)
+
+#define OPMASK 0xf8000000
+
+/* Instruction field accessor macros.
+ See the Programmer's Reference Manual. */
+#define X_OP(i) (((i) >> 27) & 0x1f)
+#define X_A(i) (((i) >> 21) & 0x3f)
+#define X_B(i) (((i) >> 15) & 0x3f)
+#define X_C(i) (((i) >> 9) & 0x3f)
+#define X_D(i) ((((i) & 0x1ff) ^ 0x100) - 0x100)
+#define X_L(i) (((((i) >> 5) & 0x3ffffc) ^ 0x200000) - 0x200000)
+#define X_N(i) (((i) >> 5) & 3)
+#define X_Q(i) ((i) & 0x1f)
+
+/* Return non-zero if X is a short immediate data indicator. */
+#define SHIMM_P(x) ((x) == 61 || (x) == 63)
+
+/* Return non-zero if X is a "long" (32 bit) immediate data indicator. */
+#define LIMM_P(x) ((x) == 62)
+
+/* Build a simple instruction. */
+#define BUILD_INSN(op, a, b, c, d) \
+ ((((op) & 31) << 27) \
+ | (((a) & 63) << 21) \
+ | (((b) & 63) << 15) \
+ | (((c) & 63) << 9) \
+ | ((d) & 511))
+
+/* Codestream stuff. */
+static void codestream_read (unsigned int *, int);
+static void codestream_seek (CORE_ADDR);
+static unsigned int codestream_fill (int);
+
+#define CODESTREAM_BUFSIZ 16
+static CORE_ADDR codestream_next_addr;
+static CORE_ADDR codestream_addr;
+/* FIXME assumes sizeof (int) == 32? */
+static unsigned int codestream_buf[CODESTREAM_BUFSIZ];
+static int codestream_off;
+static int codestream_cnt;
+
+#define codestream_tell() \
+ (codestream_addr + codestream_off * sizeof (codestream_buf[0]))
+#define codestream_peek() \
+ (codestream_cnt == 0 \
+ ? codestream_fill (1) \
+ : codestream_buf[codestream_off])
+#define codestream_get() \
+ (codestream_cnt-- == 0 \
+ ? codestream_fill (0) \
+ : codestream_buf[codestream_off++])
+
+static unsigned int
+codestream_fill (int peek_flag)
+{
+ codestream_addr = codestream_next_addr;
+ codestream_next_addr += CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]);
+ codestream_off = 0;
+ codestream_cnt = CODESTREAM_BUFSIZ;
+ read_memory (codestream_addr, (char *) codestream_buf,
+ CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]));
+ /* FIXME: check return code? */
+
+
+ /* Handle byte order differences -> convert to host byte ordering. */
+ {
+ int i;
+ for (i = 0; i < CODESTREAM_BUFSIZ; i++)
+ codestream_buf[i] =
+ extract_unsigned_integer (&codestream_buf[i],
+ sizeof (codestream_buf[i]));
+ }
+
+ if (peek_flag)
+ return codestream_peek ();
+ else
+ return codestream_get ();
+}
+
+static void
+codestream_seek (CORE_ADDR place)
+{
+ codestream_next_addr = place / CODESTREAM_BUFSIZ;
+ codestream_next_addr *= CODESTREAM_BUFSIZ;
+ codestream_cnt = 0;
+ codestream_fill (1);
+ while (codestream_tell () != place)
+ codestream_get ();
+}
+
+/* This function is currently unused but leave in for now. */
+
+static void
+codestream_read (unsigned int *buf, int count)
+{
+ unsigned int *p;
+ int i;
+ p = buf;
+ for (i = 0; i < count; i++)
+ *p++ = codestream_get ();
+}
+
+/* Set up prologue scanning and return the first insn. */
+
+static unsigned int
+setup_prologue_scan (CORE_ADDR pc)
+{
+ unsigned int insn;
+
+ codestream_seek (pc);
+ insn = codestream_get ();
+
+ return insn;
+}
+
+/*
+ * Find & return amount a local space allocated, and advance codestream to
+ * first register push (if any).
+ * If entry sequence doesn't make sense, return -1, and leave
+ * codestream pointer random.
+ */
+
+static long
+arc_get_frame_setup (CORE_ADDR pc)
+{
+ unsigned int insn;
+ /* Size of frame or -1 if unrecognizable prologue. */
+ int frame_size = -1;
+ /* An initial "sub sp,sp,N" may or may not be for a stdarg fn. */
+ int maybe_stdarg_decr = -1;
+
+ insn = setup_prologue_scan (pc);
+
+ /* The authority for what appears here is the home-grown ABI.
+ The most recent version is 1.2. */
+
+ /* First insn may be "sub sp,sp,N" if stdarg fn. */
+ if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
+ == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0))
+ {
+ maybe_stdarg_decr = X_D (insn);
+ insn = codestream_get ();
+ }
+
+ if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st blink,[sp,4] */
+ == BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4))
+ {
+ insn = codestream_get ();
+ /* Frame may not be necessary, even though blink is saved.
+ At least this is something we recognize. */
+ frame_size = 0;
+ }
+
+ if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st fp,[sp] */
+ == BUILD_INSN (2, 0, SP_REGNUM, FP_REGNUM, 0))
+ {
+ insn = codestream_get ();
+ if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
+ != BUILD_INSN (12, FP_REGNUM, SP_REGNUM, SP_REGNUM, 0))
+ return -1;
+
+ /* Check for stack adjustment sub sp,sp,N. */
+ insn = codestream_peek ();
+ if ((insn & BUILD_INSN (-1, -1, -1, 0, 0))
+ == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, 0, 0))
+ {
+ if (LIMM_P (X_C (insn)))
+ frame_size = codestream_get ();
+ else if (SHIMM_P (X_C (insn)))
+ frame_size = X_D (insn);
+ else
+ return -1;
+ if (frame_size < 0)
+ return -1;
+
+ codestream_get ();
+
+ /* This sequence is used to get the address of the return
+ buffer for a function that returns a structure. */
+ insn = codestream_peek ();
+ if ((insn & OPMASK) == 0x60000000)
+ codestream_get ();
+ }
+ /* Frameless fn. */
+ else
+ {
+ frame_size = 0;
+ }
+ }
+
+ /* If we found a "sub sp,sp,N" and nothing else, it may or may not be a
+ stdarg fn. The stdarg decrement is not treated as part of the frame size,
+ so we have a dilemma: what do we return? For now, if we get a
+ "sub sp,sp,N" and nothing else assume this isn't a stdarg fn. One way
+ to fix this completely would be to add a bit to the function descriptor
+ that says the function is a stdarg function. */
+
+ if (frame_size < 0 && maybe_stdarg_decr > 0)
+ return maybe_stdarg_decr;
+ return frame_size;
+}
+
+/* Given a pc value, skip it forward past the function prologue by
+ disassembling instructions that appear to be a prologue.
+
+ If FRAMELESS_P is set, we are only testing to see if the function
+ is frameless. If it is a frameless function, return PC unchanged.
+ This allows a quicker answer. */
+
+CORE_ADDR
+arc_skip_prologue (CORE_ADDR pc, int frameless_p)
+{
+ unsigned int insn;
+ int i, frame_size;
+
+ if ((frame_size = arc_get_frame_setup (pc)) < 0)
+ return (pc);
+
+ if (frameless_p)
+ return frame_size == 0 ? pc : codestream_tell ();
+
+ /* Skip over register saves. */
+ for (i = 0; i < 8; i++)
+ {
+ insn = codestream_peek ();
+ if ((insn & BUILD_INSN (-1, 0, -1, 0, 0))
+ != BUILD_INSN (2, 0, SP_REGNUM, 0, 0))
+ break; /* not st insn */
+ if (!ARC_CALL_SAVED_REG (X_C (insn)))
+ break;
+ codestream_get ();
+ }
+
+ return codestream_tell ();
+}
+
+/* Is the prologue at PC frameless? */
+
+int
+arc_prologue_frameless_p (CORE_ADDR pc)
+{
+ return (pc == arc_skip_prologue (pc, 1));
+}
+
+/* Return the return address for a frame.
+ This is used to implement FRAME_SAVED_PC.
+ This is taken from frameless_look_for_prologue. */
+
+CORE_ADDR
+arc_frame_saved_pc (struct frame_info *frame)
+{
+ CORE_ADDR func_start;
+ unsigned int insn;
+
+ func_start = get_pc_function_start (frame->pc) + FUNCTION_START_OFFSET;
+ if (func_start == 0)
+ {
+ /* Best guess. */
+ return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame) + 4, 4));
+ }
+
+ /* The authority for what appears here is the home-grown ABI.
+ The most recent version is 1.2. */
+
+ insn = setup_prologue_scan (func_start);
+
+ /* First insn may be "sub sp,sp,N" if stdarg fn. */
+ if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
+ == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0))
+ insn = codestream_get ();
+
+ /* If the next insn is "st blink,[sp,4]" we can get blink from there.
+ Otherwise this is a leaf function and we can use blink. Note that
+ this still allows for the case where a leaf function saves/clobbers/
+ restores blink. */
+
+ if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st blink,[sp,4] */
+ != BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4))
+ return ARC_PC_TO_REAL_ADDRESS (read_register (BLINK_REGNUM));
+ else
+ return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame) + 4, 4));
+}
+
+/*
+ * Parse the first few instructions of the function to see
+ * what registers were stored.
+ *
+ * The startup sequence can be at the start of the function.
+ * 'st blink,[sp+4], st fp,[sp], mov fp,sp'
+ *
+ * Local space is allocated just below by sub sp,sp,nnn.
+ * Next, the registers used by this function are stored (as offsets from sp).
+ */
+
+void
+frame_find_saved_regs (struct frame_info *fip, struct frame_saved_regs *fsrp)
+{
+ long locals;
+ unsigned int insn;
+ CORE_ADDR dummy_bottom;
+ CORE_ADDR adr;
+ int i, regnum, offset;
+
+ memset (fsrp, 0, sizeof *fsrp);
+
+ /* If frame is the end of a dummy, compute where the beginning would be. */
+ dummy_bottom = fip->frame - 4 - REGISTER_BYTES - CALL_DUMMY_LENGTH;
+
+ /* Check if the PC is in the stack, in a dummy frame. */
+ if (dummy_bottom <= fip->pc && fip->pc <= fip->frame)
+ {
+ /* all regs were saved by push_call_dummy () */
+ adr = fip->frame;
+ for (i = 0; i < NUM_REGS; i++)
+ {
+ adr -= REGISTER_RAW_SIZE (i);
+ fsrp->regs[i] = adr;
+ }
+ return;
+ }
+
+ locals = arc_get_frame_setup (get_pc_function_start (fip->pc));
+
+ if (locals >= 0)
+ {
+ /* Set `adr' to the value of `sp'. */
+ adr = fip->frame - locals;
+ for (i = 0; i < 8; i++)
+ {
+ insn = codestream_get ();
+ if ((insn & BUILD_INSN (-1, 0, -1, 0, 0))
+ != BUILD_INSN (2, 0, SP_REGNUM, 0, 0))
+ break;
+ regnum = X_C (insn);
+ offset = X_D (insn);
+ fsrp->regs[regnum] = adr + offset;
+ }
+ }
+
+ fsrp->regs[PC_REGNUM] = fip->frame + 4;
+ fsrp->regs[FP_REGNUM] = fip->frame;
+}
+
+void
+arc_push_dummy_frame (void)
+{
+ CORE_ADDR sp = read_register (SP_REGNUM);
+ int regnum;
+ char regbuf[MAX_REGISTER_RAW_SIZE];
+
+ read_register_gen (PC_REGNUM, regbuf);
+ write_memory (sp + 4, regbuf, REGISTER_SIZE);
+ read_register_gen (FP_REGNUM, regbuf);
+ write_memory (sp, regbuf, REGISTER_SIZE);
+ write_register (FP_REGNUM, sp);
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ {
+ read_register_gen (regnum, regbuf);
+ sp = push_bytes (sp, regbuf, REGISTER_RAW_SIZE (regnum));
+ }
+ sp += (2 * REGISTER_SIZE);
+ write_register (SP_REGNUM, sp);
+}
+
+void
+arc_pop_frame (void)
+{
+ struct frame_info *frame = get_current_frame ();
+ CORE_ADDR fp;
+ int regnum;
+ struct frame_saved_regs fsr;
+ char regbuf[MAX_REGISTER_RAW_SIZE];
+
+ fp = FRAME_FP (frame);
+ get_frame_saved_regs (frame, &fsr);
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ {
+ CORE_ADDR adr;
+ adr = fsr.regs[regnum];
+ if (adr)
+ {
+ read_memory (adr, regbuf, REGISTER_RAW_SIZE (regnum));
+ write_register_bytes (REGISTER_BYTE (regnum), regbuf,
+ REGISTER_RAW_SIZE (regnum));
+ }
+ }
+ write_register (FP_REGNUM, read_memory_integer (fp, 4));
+ write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
+ write_register (SP_REGNUM, fp + 8);
+ flush_cached_frames ();
+}
+
+/* Simulate single-step. */
+
+typedef enum
+{
+ NORMAL4, /* a normal 4 byte insn */
+ NORMAL8, /* a normal 8 byte insn */
+ BRANCH4, /* a 4 byte branch insn, including ones without delay slots */
+ BRANCH8, /* an 8 byte branch insn, including ones with delay slots */
+}
+insn_type;
+
+/* Return the type of INSN and store in TARGET the destination address of a
+ branch if this is one. */
+/* ??? Need to verify all cases are properly handled. */
+
+static insn_type
+get_insn_type (unsigned long insn, CORE_ADDR pc, CORE_ADDR *target)
+{
+ unsigned long limm;
+
+ switch (insn >> 27)
+ {
+ case 0:
+ case 1:
+ case 2: /* load/store insns */
+ if (LIMM_P (X_A (insn))
+ || LIMM_P (X_B (insn))
+ || LIMM_P (X_C (insn)))
+ return NORMAL8;
+ return NORMAL4;
+ case 4:
+ case 5:
+ case 6: /* branch insns */
+ *target = pc + 4 + X_L (insn);
+ /* ??? It isn't clear that this is always the right answer.
+ The problem occurs when the next insn is an 8 byte insn. If the
+ branch is conditional there's no worry as there shouldn't be an 8
+ byte insn following. The programmer may be cheating if s/he knows
+ the branch will never be taken, but we don't deal with that.
+ Note that the programmer is also allowed to play games by putting
+ an insn with long immediate data in the delay slot and then duplicate
+ the long immediate data at the branch target. Ugh! */
+ if (X_N (insn) == 0)
+ return BRANCH4;
+ return BRANCH8;
+ case 7: /* jump insns */
+ if (LIMM_P (X_B (insn)))
+ {
+ limm = read_memory_integer (pc + 4, 4);
+ *target = ARC_PC_TO_REAL_ADDRESS (limm);
+ return BRANCH8;
+ }
+ if (SHIMM_P (X_B (insn)))
+ *target = ARC_PC_TO_REAL_ADDRESS (X_D (insn));
+ else
+ *target = ARC_PC_TO_REAL_ADDRESS (read_register (X_B (insn)));
+ if (X_Q (insn) == 0 && X_N (insn) == 0)
+ return BRANCH4;
+ return BRANCH8;
+ default: /* arithmetic insns, etc. */
+ if (LIMM_P (X_A (insn))
+ || LIMM_P (X_B (insn))
+ || LIMM_P (X_C (insn)))
+ return NORMAL8;
+ return NORMAL4;
+ }
+}
+
+/* single_step() is called just before we want to resume the inferior, if we
+ want to single-step it but there is no hardware or kernel single-step
+ support. We find all the possible targets of the coming instruction and
+ breakpoint them.
+
+ single_step is also called just after the inferior stops. If we had
+ set up a simulated single-step, we undo our damage. */
+
+void
+arc_software_single_step (enum target_signal ignore, /* sig but we don't need it */
+ int insert_breakpoints_p)
+{
+ static CORE_ADDR next_pc, target;
+ static int brktrg_p;
+ typedef char binsn_quantum[BREAKPOINT_MAX];
+ static binsn_quantum break_mem[2];
+
+ if (insert_breakpoints_p)
+ {
+ insn_type type;
+ CORE_ADDR pc;
+ unsigned long insn;
+
+ pc = read_register (PC_REGNUM);
+ insn = read_memory_integer (pc, 4);
+ type = get_insn_type (insn, pc, &target);
+
+ /* Always set a breakpoint for the insn after the branch. */
+ next_pc = pc + ((type == NORMAL8 || type == BRANCH8) ? 8 : 4);
+ target_insert_breakpoint (next_pc, break_mem[0]);
+
+ brktrg_p = 0;
+
+ if ((type == BRANCH4 || type == BRANCH8)
+ /* Watch out for branches to the following location.
+ We just stored a breakpoint there and another call to
+ target_insert_breakpoint will think the real insn is the
+ breakpoint we just stored there. */
+ && target != next_pc)
+ {
+ brktrg_p = 1;
+ target_insert_breakpoint (target, break_mem[1]);
+ }
+
+ }
+ else
+ {
+ /* Remove breakpoints. */
+ target_remove_breakpoint (next_pc, break_mem[0]);
+
+ if (brktrg_p)
+ target_remove_breakpoint (target, break_mem[1]);
+
+ /* Fix the pc. */
+ stop_pc -= DECR_PC_AFTER_BREAK;
+ write_pc (stop_pc);
+ }
+}
+
+/* Because of Multi-arch, GET_LONGJMP_TARGET is always defined. So test
+ for a definition of JB_PC. */
+#ifdef JB_PC
+/* Figure out where the longjmp will land. Slurp the args out of the stack.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
+ This routine returns true on success. */
+
+int
+get_longjmp_target (CORE_ADDR *pc)
+{
+ char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
+ CORE_ADDR sp, jb_addr;
+
+ sp = read_register (SP_REGNUM);
+
+ if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */
+ buf,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ return 1;
+}
+#endif /* GET_LONGJMP_TARGET */
+
+/* Disassemble one instruction. */
+
+static int
+arc_print_insn (bfd_vma vma, disassemble_info *info)
+{
+ static int current_mach;
+ static int current_endian;
+ static disassembler_ftype current_disasm;
+
+ if (current_disasm == NULL
+ || arc_bfd_mach_type != current_mach
+ || TARGET_BYTE_ORDER != current_endian)
+ {
+ current_mach = arc_bfd_mach_type;
+ current_endian = TARGET_BYTE_ORDER;
+ current_disasm = arc_get_disassembler (NULL);
+ }
+
+ return (*current_disasm) (vma, info);
+}
+
+/* Command to set cpu type. */
+
+void
+arc_set_cpu_type_command (char *args, int from_tty)
+{
+ int i;
+
+ if (tmp_arc_cpu_type == NULL || *tmp_arc_cpu_type == '\0')
+ {
+ printf_unfiltered ("The known ARC cpu types are as follows:\n");
+ for (i = 0; arc_cpu_type_table[i].name != NULL; ++i)
+ printf_unfiltered ("%s\n", arc_cpu_type_table[i].name);
+
+ /* Restore the value. */
+ tmp_arc_cpu_type = xstrdup (arc_cpu_type);
+
+ return;
+ }
+
+ if (!arc_set_cpu_type (tmp_arc_cpu_type))
+ {
+ error ("Unknown cpu type `%s'.", tmp_arc_cpu_type);
+ /* Restore its value. */
+ tmp_arc_cpu_type = xstrdup (arc_cpu_type);
+ }
+}
+
+static void
+arc_show_cpu_type_command (char *args, int from_tty)
+{
+}
+
+/* Modify the actual cpu type.
+ Result is a boolean indicating success. */
+
+static int
+arc_set_cpu_type (char *str)
+{
+ int i, j;
+
+ if (str == NULL)
+ return 0;
+
+ for (i = 0; arc_cpu_type_table[i].name != NULL; ++i)
+ {
+ if (strcasecmp (str, arc_cpu_type_table[i].name) == 0)
+ {
+ arc_cpu_type = str;
+ arc_bfd_mach_type = arc_cpu_type_table[i].value;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void
+_initialize_arc_tdep (void)
+{
+ struct cmd_list_element *c;
+
+ c = add_set_cmd ("cpu", class_support, var_string_noescape,
+ (char *) &tmp_arc_cpu_type,
+ "Set the type of ARC cpu in use.\n\
+This command has two purposes. In a multi-cpu system it lets one\n\
+change the cpu being debugged. It also gives one access to\n\
+cpu-type-specific registers and recognize cpu-type-specific instructions.\
+",
+ &setlist);
+ set_cmd_cfunc (c, arc_set_cpu_type_command);
+ c = add_show_from_set (c, &showlist);
+ set_cmd_cfunc (c, arc_show_cpu_type_command);
+
+ /* We have to use xstrdup() here because the `set' command frees it
+ before setting a new value. */
+ tmp_arc_cpu_type = xstrdup (DEFAULT_ARC_CPU_TYPE);
+ arc_set_cpu_type (tmp_arc_cpu_type);
+
+ c = add_set_cmd ("displaypipeline", class_support, var_zinteger,
+ (char *) &display_pipeline_p,
+ "Set pipeline display (simulator only).\n\
+When enabled, the state of the pipeline after each cycle is displayed.",
+ &setlist);
+ c = add_show_from_set (c, &showlist);
+
+ c = add_set_cmd ("debugpipeline", class_support, var_zinteger,
+ (char *) &debug_pipeline_p,
+ "Set pipeline debug display (simulator only).\n\
+When enabled, debugging information about the pipeline is displayed.",
+ &setlist);
+ c = add_show_from_set (c, &showlist);
+
+ c = add_set_cmd ("cputimer", class_support, var_zinteger,
+ (char *) &cpu_timer,
+ "Set maximum cycle count (simulator only).\n\
+Control will return to gdb if the timer expires.\n\
+A negative value disables the timer.",
+ &setlist);
+ c = add_show_from_set (c, &showlist);
+
+ tm_print_insn = arc_print_insn;
+}
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
new file mode 100644
index 00000000000..bde89a8fa8e
--- /dev/null
+++ b/gdb/arch-utils.c
@@ -0,0 +1,889 @@
+/* Dynamic architecture support for GDB, the GNU debugger.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+
+#if GDB_MULTI_ARCH
+#include "arch-utils.h"
+#include "gdbcmd.h"
+#include "inferior.h" /* enum CALL_DUMMY_LOCATION et.al. */
+#else
+/* Just include everything in sight so that the every old definition
+ of macro is visible. */
+#include "gdb_string.h"
+#include "symtab.h"
+#include "frame.h"
+#include "inferior.h"
+#include "breakpoint.h"
+#include "gdb_wait.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "annotate.h"
+#endif
+#include "regcache.h"
+#include "gdb_assert.h"
+
+#include "version.h"
+
+#include "floatformat.h"
+
+/* Use the program counter to determine the contents and size
+ of a breakpoint instruction. If no target-dependent macro
+ BREAKPOINT_FROM_PC has been defined to implement this function,
+ assume that the breakpoint doesn't depend on the PC, and
+ use the values of the BIG_BREAKPOINT and LITTLE_BREAKPOINT macros.
+ Return a pointer to a string of bytes that encode a breakpoint
+ instruction, stores the length of the string to *lenptr,
+ and optionally adjust the pc to point to the correct memory location
+ for inserting the breakpoint. */
+
+const unsigned char *
+legacy_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
+{
+ /* {BIG_,LITTLE_}BREAKPOINT is the sequence of bytes we insert for a
+ breakpoint. On some machines, breakpoints are handled by the
+ target environment and we don't have to worry about them here. */
+#ifdef BIG_BREAKPOINT
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ static unsigned char big_break_insn[] = BIG_BREAKPOINT;
+ *lenptr = sizeof (big_break_insn);
+ return big_break_insn;
+ }
+#endif
+#ifdef LITTLE_BREAKPOINT
+ if (TARGET_BYTE_ORDER != BFD_ENDIAN_BIG)
+ {
+ static unsigned char little_break_insn[] = LITTLE_BREAKPOINT;
+ *lenptr = sizeof (little_break_insn);
+ return little_break_insn;
+ }
+#endif
+#ifdef BREAKPOINT
+ {
+ static unsigned char break_insn[] = BREAKPOINT;
+ *lenptr = sizeof (break_insn);
+ return break_insn;
+ }
+#endif
+ *lenptr = 0;
+ return NULL;
+}
+
+int
+generic_frameless_function_invocation_not (struct frame_info *fi)
+{
+ return 0;
+}
+
+int
+generic_return_value_on_stack_not (struct type *type)
+{
+ return 0;
+}
+
+CORE_ADDR
+generic_skip_trampoline_code (CORE_ADDR pc)
+{
+ return 0;
+}
+
+int
+generic_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+ return 0;
+}
+
+int
+generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+ return 0;
+}
+
+char *
+legacy_register_name (int i)
+{
+#ifdef REGISTER_NAMES
+ static char *names[] = REGISTER_NAMES;
+ if (i < 0 || i >= (sizeof (names) / sizeof (*names)))
+ return NULL;
+ else
+ return names[i];
+#else
+ internal_error (__FILE__, __LINE__,
+ "legacy_register_name: called.");
+ return NULL;
+#endif
+}
+
+#if defined (CALL_DUMMY)
+LONGEST legacy_call_dummy_words[] = CALL_DUMMY;
+#else
+LONGEST legacy_call_dummy_words[1];
+#endif
+int legacy_sizeof_call_dummy_words = sizeof (legacy_call_dummy_words);
+
+void
+generic_remote_translate_xfer_address (CORE_ADDR gdb_addr, int gdb_len,
+ CORE_ADDR * rem_addr, int *rem_len)
+{
+ *rem_addr = gdb_addr;
+ *rem_len = gdb_len;
+}
+
+int
+generic_prologue_frameless_p (CORE_ADDR ip)
+{
+ return ip == SKIP_PROLOGUE (ip);
+}
+
+/* New/multi-arched targets should use the correct gdbarch field
+ instead of using this global pointer. */
+int
+legacy_print_insn (bfd_vma vma, disassemble_info *info)
+{
+ return (*tm_print_insn) (vma, info);
+}
+
+/* Helper functions for INNER_THAN */
+
+int
+core_addr_lessthan (CORE_ADDR lhs, CORE_ADDR rhs)
+{
+ return (lhs < rhs);
+}
+
+int
+core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs)
+{
+ return (lhs > rhs);
+}
+
+
+/* Helper functions for TARGET_{FLOAT,DOUBLE}_FORMAT */
+
+const struct floatformat *
+default_float_format (struct gdbarch *gdbarch)
+{
+#if GDB_MULTI_ARCH
+ int byte_order = gdbarch_byte_order (gdbarch);
+#else
+ int byte_order = TARGET_BYTE_ORDER;
+#endif
+ switch (byte_order)
+ {
+ case BFD_ENDIAN_BIG:
+ return &floatformat_ieee_single_big;
+ case BFD_ENDIAN_LITTLE:
+ return &floatformat_ieee_single_little;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "default_float_format: bad byte order");
+ }
+}
+
+
+const struct floatformat *
+default_double_format (struct gdbarch *gdbarch)
+{
+#if GDB_MULTI_ARCH
+ int byte_order = gdbarch_byte_order (gdbarch);
+#else
+ int byte_order = TARGET_BYTE_ORDER;
+#endif
+ switch (byte_order)
+ {
+ case BFD_ENDIAN_BIG:
+ return &floatformat_ieee_double_big;
+ case BFD_ENDIAN_LITTLE:
+ return &floatformat_ieee_double_little;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "default_double_format: bad byte order");
+ }
+}
+
+void
+default_print_float_info (void)
+{
+#ifdef FLOAT_INFO
+#if GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL
+#error "FLOAT_INFO defined in multi-arch"
+#endif
+ FLOAT_INFO;
+#else
+ printf_filtered ("No floating point info available for this processor.\n");
+#endif
+}
+
+/* Misc helper functions for targets. */
+
+int
+frame_num_args_unknown (struct frame_info *fi)
+{
+ return -1;
+}
+
+
+int
+generic_register_convertible_not (int num)
+{
+ return 0;
+}
+
+
+/* Under some ABI's that specify the `struct convention' for returning
+ structures by value, by the time we've returned from the function,
+ the return value is sitting there in the caller's buffer, but GDB
+ has no way to find the address of that buffer.
+
+ On such architectures, use this function as your
+ extract_struct_value_address method. When asked to a struct
+ returned by value in this fashion, GDB will print a nice error
+ message, instead of garbage. */
+CORE_ADDR
+generic_cannot_extract_struct_value_address (char *dummy)
+{
+ return 0;
+}
+
+int
+default_register_sim_regno (int num)
+{
+ return num;
+}
+
+
+CORE_ADDR
+core_addr_identity (CORE_ADDR addr)
+{
+ return addr;
+}
+
+int
+no_op_reg_to_regnum (int reg)
+{
+ return reg;
+}
+
+/* For use by frame_args_address and frame_locals_address. */
+CORE_ADDR
+default_frame_address (struct frame_info *fi)
+{
+ return fi->frame;
+}
+
+/* Default prepare_to_procced(). */
+int
+default_prepare_to_proceed (int select_it)
+{
+ return 0;
+}
+
+/* Generic prepare_to_proceed(). This one should be suitable for most
+ targets that support threads. */
+int
+generic_prepare_to_proceed (int select_it)
+{
+ ptid_t wait_ptid;
+ struct target_waitstatus wait_status;
+
+ /* Get the last target status returned by target_wait(). */
+ get_last_target_status (&wait_ptid, &wait_status);
+
+ /* Make sure we were stopped either at a breakpoint, or because
+ of a Ctrl-C. */
+ if (wait_status.kind != TARGET_WAITKIND_STOPPED
+ || (wait_status.value.sig != TARGET_SIGNAL_TRAP &&
+ wait_status.value.sig != TARGET_SIGNAL_INT))
+ {
+ return 0;
+ }
+
+ if (!ptid_equal (wait_ptid, minus_one_ptid)
+ && !ptid_equal (inferior_ptid, wait_ptid))
+ {
+ /* Switched over from WAIT_PID. */
+ CORE_ADDR wait_pc = read_pc_pid (wait_ptid);
+
+ if (wait_pc != read_pc ())
+ {
+ if (select_it)
+ {
+ /* Switch back to WAIT_PID thread. */
+ inferior_ptid = wait_ptid;
+
+ /* FIXME: This stuff came from switch_to_thread() in
+ thread.c (which should probably be a public function). */
+ flush_cached_frames ();
+ registers_changed ();
+ stop_pc = wait_pc;
+ select_frame (get_current_frame ());
+ }
+ /* We return 1 to indicate that there is a breakpoint here,
+ so we need to step over it before continuing to avoid
+ hitting it straight away. */
+ if (breakpoint_here_p (wait_pc))
+ {
+ return 1;
+ }
+ }
+ }
+ return 0;
+
+}
+
+void
+init_frame_pc_noop (int fromleaf, struct frame_info *prev)
+{
+ return;
+}
+
+void
+init_frame_pc_default (int fromleaf, struct frame_info *prev)
+{
+ if (fromleaf)
+ prev->pc = SAVED_PC_AFTER_CALL (prev->next);
+ else if (prev->next != NULL)
+ prev->pc = FRAME_SAVED_PC (prev->next);
+ else
+ prev->pc = read_pc ();
+}
+
+void
+default_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
+{
+ return;
+}
+
+void
+default_coff_make_msymbol_special (int val, struct minimal_symbol *msym)
+{
+ return;
+}
+
+int
+cannot_register_not (int regnum)
+{
+ return 0;
+}
+
+/* Legacy version of target_virtual_frame_pointer(). Assumes that
+ there is an FP_REGNUM and that it is the same, cooked or raw. */
+
+void
+legacy_virtual_frame_pointer (CORE_ADDR pc,
+ int *frame_regnum,
+ LONGEST *frame_offset)
+{
+ gdb_assert (FP_REGNUM >= 0);
+ *frame_regnum = FP_REGNUM;
+ *frame_offset = 0;
+}
+
+/* Assume the world is sane, every register's virtual and real size
+ is identical. */
+
+int
+generic_register_size (int regnum)
+{
+ gdb_assert (regnum >= 0 && regnum < NUM_REGS + NUM_PSEUDO_REGS);
+ return TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (regnum));
+}
+
+#if !defined (IN_SIGTRAMP)
+#if defined (SIGTRAMP_START)
+#define IN_SIGTRAMP(pc, name) \
+ ((pc) >= SIGTRAMP_START(pc) \
+ && (pc) < SIGTRAMP_END(pc) \
+ )
+#else
+#define IN_SIGTRAMP(pc, name) \
+ (name && STREQ ("_sigtramp", name))
+#endif
+#endif
+
+int
+legacy_pc_in_sigtramp (CORE_ADDR pc, char *name)
+{
+ return IN_SIGTRAMP(pc, name);
+}
+
+int
+legacy_convert_register_p (int regnum)
+{
+ return REGISTER_CONVERTIBLE (regnum);
+}
+
+void
+legacy_register_to_value (int regnum, struct type *type,
+ char *from, char *to)
+{
+ REGISTER_CONVERT_TO_VIRTUAL (regnum, type, from, to);
+}
+
+void
+legacy_value_to_register (struct type *type, int regnum,
+ char *from, char *to)
+{
+ REGISTER_CONVERT_TO_RAW (type, regnum, from, to);
+}
+
+
+/* Functions to manipulate the endianness of the target. */
+
+/* ``target_byte_order'' is only used when non- multi-arch.
+ Multi-arch targets obtain the current byte order using the
+ TARGET_BYTE_ORDER gdbarch method.
+
+ The choice of initial value is entirely arbitrary. During startup,
+ the function initialize_current_architecture() updates this value
+ based on default byte-order information extracted from BFD. */
+int target_byte_order = BFD_ENDIAN_BIG;
+int target_byte_order_auto = 1;
+
+static const char endian_big[] = "big";
+static const char endian_little[] = "little";
+static const char endian_auto[] = "auto";
+static const char *endian_enum[] =
+{
+ endian_big,
+ endian_little,
+ endian_auto,
+ NULL,
+};
+static const char *set_endian_string;
+
+/* Called by ``show endian''. */
+
+static void
+show_endian (char *args, int from_tty)
+{
+ if (TARGET_BYTE_ORDER_AUTO)
+ printf_unfiltered ("The target endianness is set automatically (currently %s endian)\n",
+ (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "big" : "little"));
+ else
+ printf_unfiltered ("The target is assumed to be %s endian\n",
+ (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "big" : "little"));
+}
+
+static void
+set_endian (char *ignore_args, int from_tty, struct cmd_list_element *c)
+{
+ if (set_endian_string == endian_auto)
+ {
+ target_byte_order_auto = 1;
+ }
+ else if (set_endian_string == endian_little)
+ {
+ target_byte_order_auto = 0;
+ if (GDB_MULTI_ARCH)
+ {
+ struct gdbarch_info info;
+ gdbarch_info_init (&info);
+ info.byte_order = BFD_ENDIAN_LITTLE;
+ if (! gdbarch_update_p (info))
+ {
+ printf_unfiltered ("Little endian target not supported by GDB\n");
+ }
+ }
+ else
+ {
+ target_byte_order = BFD_ENDIAN_LITTLE;
+ }
+ }
+ else if (set_endian_string == endian_big)
+ {
+ target_byte_order_auto = 0;
+ if (GDB_MULTI_ARCH)
+ {
+ struct gdbarch_info info;
+ gdbarch_info_init (&info);
+ info.byte_order = BFD_ENDIAN_BIG;
+ if (! gdbarch_update_p (info))
+ {
+ printf_unfiltered ("Big endian target not supported by GDB\n");
+ }
+ }
+ else
+ {
+ target_byte_order = BFD_ENDIAN_BIG;
+ }
+ }
+ else
+ internal_error (__FILE__, __LINE__,
+ "set_endian: bad value");
+ show_endian (NULL, from_tty);
+}
+
+/* Set the endianness from a BFD. */
+
+static void
+set_endian_from_file (bfd *abfd)
+{
+ int want;
+ if (GDB_MULTI_ARCH)
+ internal_error (__FILE__, __LINE__,
+ "set_endian_from_file: not for multi-arch");
+ if (bfd_big_endian (abfd))
+ want = BFD_ENDIAN_BIG;
+ else
+ want = BFD_ENDIAN_LITTLE;
+ if (TARGET_BYTE_ORDER_AUTO)
+ target_byte_order = want;
+ else if (TARGET_BYTE_ORDER != want)
+ warning ("%s endian file does not match %s endian target.",
+ want == BFD_ENDIAN_BIG ? "big" : "little",
+ TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "big" : "little");
+}
+
+
+/* Functions to manipulate the architecture of the target */
+
+enum set_arch { set_arch_auto, set_arch_manual };
+
+int target_architecture_auto = 1;
+
+const char *set_architecture_string;
+
+/* Old way of changing the current architecture. */
+
+extern const struct bfd_arch_info bfd_default_arch_struct;
+const struct bfd_arch_info *target_architecture = &bfd_default_arch_struct;
+int (*target_architecture_hook) (const struct bfd_arch_info *ap);
+
+static int
+arch_ok (const struct bfd_arch_info *arch)
+{
+ if (GDB_MULTI_ARCH)
+ internal_error (__FILE__, __LINE__,
+ "arch_ok: not multi-arched");
+ /* Should be performing the more basic check that the binary is
+ compatible with GDB. */
+ /* Check with the target that the architecture is valid. */
+ return (target_architecture_hook == NULL
+ || target_architecture_hook (arch));
+}
+
+static void
+set_arch (const struct bfd_arch_info *arch,
+ enum set_arch type)
+{
+ if (GDB_MULTI_ARCH)
+ internal_error (__FILE__, __LINE__,
+ "set_arch: not multi-arched");
+ switch (type)
+ {
+ case set_arch_auto:
+ if (!arch_ok (arch))
+ warning ("Target may not support %s architecture",
+ arch->printable_name);
+ target_architecture = arch;
+ break;
+ case set_arch_manual:
+ if (!arch_ok (arch))
+ {
+ printf_unfiltered ("Target does not support `%s' architecture.\n",
+ arch->printable_name);
+ }
+ else
+ {
+ target_architecture_auto = 0;
+ target_architecture = arch;
+ }
+ break;
+ }
+ if (gdbarch_debug)
+ gdbarch_dump (current_gdbarch, gdb_stdlog);
+}
+
+/* Set the architecture from arch/machine (deprecated) */
+
+void
+set_architecture_from_arch_mach (enum bfd_architecture arch,
+ unsigned long mach)
+{
+ const struct bfd_arch_info *wanted = bfd_lookup_arch (arch, mach);
+ if (GDB_MULTI_ARCH)
+ internal_error (__FILE__, __LINE__,
+ "set_architecture_from_arch_mach: not multi-arched");
+ if (wanted != NULL)
+ set_arch (wanted, set_arch_manual);
+ else
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: hardwired architecture/machine not recognized");
+}
+
+/* Set the architecture from a BFD (deprecated) */
+
+static void
+set_architecture_from_file (bfd *abfd)
+{
+ const struct bfd_arch_info *wanted = bfd_get_arch_info (abfd);
+ if (GDB_MULTI_ARCH)
+ internal_error (__FILE__, __LINE__,
+ "set_architecture_from_file: not multi-arched");
+ if (target_architecture_auto)
+ {
+ set_arch (wanted, set_arch_auto);
+ }
+ else if (wanted != target_architecture)
+ {
+ warning ("%s architecture file may be incompatible with %s target.",
+ wanted->printable_name,
+ target_architecture->printable_name);
+ }
+}
+
+
+/* Called if the user enters ``show architecture'' without an
+ argument. */
+
+static void
+show_architecture (char *args, int from_tty)
+{
+ const char *arch;
+ arch = TARGET_ARCHITECTURE->printable_name;
+ if (target_architecture_auto)
+ printf_filtered ("The target architecture is set automatically (currently %s)\n", arch);
+ else
+ printf_filtered ("The target architecture is assumed to be %s\n", arch);
+}
+
+
+/* Called if the user enters ``set architecture'' with or without an
+ argument. */
+
+static void
+set_architecture (char *ignore_args, int from_tty, struct cmd_list_element *c)
+{
+ if (strcmp (set_architecture_string, "auto") == 0)
+ {
+ target_architecture_auto = 1;
+ }
+ else if (GDB_MULTI_ARCH)
+ {
+ struct gdbarch_info info;
+ gdbarch_info_init (&info);
+ info.bfd_arch_info = bfd_scan_arch (set_architecture_string);
+ if (info.bfd_arch_info == NULL)
+ internal_error (__FILE__, __LINE__,
+ "set_architecture: bfd_scan_arch failed");
+ if (gdbarch_update_p (info))
+ target_architecture_auto = 0;
+ else
+ printf_unfiltered ("Architecture `%s' not recognized.\n",
+ set_architecture_string);
+ }
+ else
+ {
+ const struct bfd_arch_info *arch
+ = bfd_scan_arch (set_architecture_string);
+ if (arch == NULL)
+ internal_error (__FILE__, __LINE__,
+ "set_architecture: bfd_scan_arch failed");
+ set_arch (arch, set_arch_manual);
+ }
+ show_architecture (NULL, from_tty);
+}
+
+/* Set the dynamic target-system-dependent parameters (architecture,
+ byte-order) using information found in the BFD */
+
+void
+set_gdbarch_from_file (bfd *abfd)
+{
+ if (GDB_MULTI_ARCH)
+ {
+ struct gdbarch_info info;
+ gdbarch_info_init (&info);
+ info.abfd = abfd;
+ if (! gdbarch_update_p (info))
+ error ("Architecture of file not recognized.\n");
+ }
+ else
+ {
+ set_architecture_from_file (abfd);
+ set_endian_from_file (abfd);
+ }
+}
+
+/* Initialize the current architecture. Update the ``set
+ architecture'' command so that it specifies a list of valid
+ architectures. */
+
+#ifdef DEFAULT_BFD_ARCH
+extern const bfd_arch_info_type DEFAULT_BFD_ARCH;
+static const bfd_arch_info_type *default_bfd_arch = &DEFAULT_BFD_ARCH;
+#else
+static const bfd_arch_info_type *default_bfd_arch;
+#endif
+
+#ifdef DEFAULT_BFD_VEC
+extern const bfd_target DEFAULT_BFD_VEC;
+static const bfd_target *default_bfd_vec = &DEFAULT_BFD_VEC;
+#else
+static const bfd_target *default_bfd_vec;
+#endif
+
+void
+initialize_current_architecture (void)
+{
+ const char **arches = gdbarch_printable_names ();
+
+ /* determine a default architecture and byte order. */
+ struct gdbarch_info info;
+ gdbarch_info_init (&info);
+
+ /* Find a default architecture. */
+ if (info.bfd_arch_info == NULL
+ && default_bfd_arch != NULL)
+ info.bfd_arch_info = default_bfd_arch;
+ if (info.bfd_arch_info == NULL)
+ {
+ /* Choose the architecture by taking the first one
+ alphabetically. */
+ const char *chosen = arches[0];
+ const char **arch;
+ for (arch = arches; *arch != NULL; arch++)
+ {
+ if (strcmp (*arch, chosen) < 0)
+ chosen = *arch;
+ }
+ if (chosen == NULL)
+ internal_error (__FILE__, __LINE__,
+ "initialize_current_architecture: No arch");
+ info.bfd_arch_info = bfd_scan_arch (chosen);
+ if (info.bfd_arch_info == NULL)
+ internal_error (__FILE__, __LINE__,
+ "initialize_current_architecture: Arch not found");
+ }
+
+ /* Take several guesses at a byte order. */
+ if (info.byte_order == BFD_ENDIAN_UNKNOWN
+ && default_bfd_vec != NULL)
+ {
+ /* Extract BFD's default vector's byte order. */
+ switch (default_bfd_vec->byteorder)
+ {
+ case BFD_ENDIAN_BIG:
+ info.byte_order = BFD_ENDIAN_BIG;
+ break;
+ case BFD_ENDIAN_LITTLE:
+ info.byte_order = BFD_ENDIAN_LITTLE;
+ break;
+ default:
+ break;
+ }
+ }
+ if (info.byte_order == BFD_ENDIAN_UNKNOWN)
+ {
+ /* look for ``*el-*'' in the target name. */
+ const char *chp;
+ chp = strchr (target_name, '-');
+ if (chp != NULL
+ && chp - 2 >= target_name
+ && strncmp (chp - 2, "el", 2) == 0)
+ info.byte_order = BFD_ENDIAN_LITTLE;
+ }
+ if (info.byte_order == BFD_ENDIAN_UNKNOWN)
+ {
+ /* Wire it to big-endian!!! */
+ info.byte_order = BFD_ENDIAN_BIG;
+ }
+
+ if (GDB_MULTI_ARCH)
+ {
+ if (! gdbarch_update_p (info))
+ {
+ internal_error (__FILE__, __LINE__,
+ "initialize_current_architecture: Selection of initial architecture failed");
+ }
+ }
+ else
+ {
+ /* If the multi-arch logic comes up with a byte-order (from BFD)
+ use it for the non-multi-arch case. */
+ if (info.byte_order != BFD_ENDIAN_UNKNOWN)
+ target_byte_order = info.byte_order;
+ initialize_non_multiarch ();
+ }
+
+ /* Create the ``set architecture'' command appending ``auto'' to the
+ list of architectures. */
+ {
+ struct cmd_list_element *c;
+ /* Append ``auto''. */
+ int nr;
+ for (nr = 0; arches[nr] != NULL; nr++);
+ arches = xrealloc (arches, sizeof (char*) * (nr + 2));
+ arches[nr + 0] = "auto";
+ arches[nr + 1] = NULL;
+ /* FIXME: add_set_enum_cmd() uses an array of ``char *'' instead
+ of ``const char *''. We just happen to know that the casts are
+ safe. */
+ c = add_set_enum_cmd ("architecture", class_support,
+ arches, &set_architecture_string,
+ "Set architecture of target.",
+ &setlist);
+ set_cmd_sfunc (c, set_architecture);
+ add_alias_cmd ("processor", "architecture", class_support, 1, &setlist);
+ /* Don't use set_from_show - need to print both auto/manual and
+ current setting. */
+ add_cmd ("architecture", class_support, show_architecture,
+ "Show the current target architecture", &showlist);
+ }
+}
+
+
+/* Initialize a gdbarch info to values that will be automatically
+ overridden. Note: Originally, this ``struct info'' was initialized
+ using memset(0). Unfortunatly, that ran into problems, namely
+ BFD_ENDIAN_BIG is zero. An explicit initialization function that
+ can explicitly set each field to a well defined value is used. */
+
+void
+gdbarch_info_init (struct gdbarch_info *info)
+{
+ memset (info, 0, sizeof (struct gdbarch_info));
+ info->byte_order = BFD_ENDIAN_UNKNOWN;
+}
+
+/* */
+
+extern initialize_file_ftype _initialize_gdbarch_utils;
+
+void
+_initialize_gdbarch_utils (void)
+{
+ struct cmd_list_element *c;
+ c = add_set_enum_cmd ("endian", class_support,
+ endian_enum, &set_endian_string,
+ "Set endianness of target.",
+ &setlist);
+ set_cmd_sfunc (c, set_endian);
+ /* Don't use set_from_show - need to print both auto/manual and
+ current setting. */
+ add_cmd ("endian", class_support, show_endian,
+ "Show the current byte-order", &showlist);
+}
diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h
new file mode 100644
index 00000000000..594a83209a3
--- /dev/null
+++ b/gdb/arch-utils.h
@@ -0,0 +1,173 @@
+/* Dynamic architecture support for GDB, the GNU debugger.
+
+ Copyright 1998, 1999, 2000, 2002 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. */
+
+#ifndef GDBARCH_UTILS_H
+#define GDBARCH_UTILS_H
+
+/* gdbarch trace variable */
+extern int gdbarch_debug;
+
+/* Fallback for register convertible. */
+extern gdbarch_register_convertible_ftype generic_register_convertible_not;
+
+extern CORE_ADDR generic_cannot_extract_struct_value_address (char *dummy);
+
+/* Helper function for targets that don't know how my arguments are
+ being passed */
+extern gdbarch_frame_num_args_ftype frame_num_args_unknown;
+
+/* Implementation of breakpoint from PC using any of the deprecated
+ macros BREAKPOINT, LITTLE_BREAKPOINT, BIG_BREAPOINT. For legacy
+ targets that don't yet implement their own breakpoint_from_pc(). */
+extern gdbarch_breakpoint_from_pc_ftype legacy_breakpoint_from_pc;
+
+/* Frameless functions not identifable. */
+extern gdbarch_frameless_function_invocation_ftype generic_frameless_function_invocation_not;
+
+/* Only structures, unions, and arrays are returned using the struct
+ convention. Note that arrays are never passed by value in the C
+ language family, so that case is irrelevant for C. */
+extern gdbarch_return_value_on_stack_ftype generic_return_value_on_stack_not;
+
+/* Map onto old REGISTER_NAMES. */
+extern char *legacy_register_name (int i);
+
+/* Accessor for old global function pointer for disassembly. */
+extern int legacy_print_insn (bfd_vma vma, disassemble_info *info);
+
+/* Backward compatible call_dummy_words. */
+extern LONGEST legacy_call_dummy_words[];
+extern int legacy_sizeof_call_dummy_words;
+
+/* Typical remote_translate_xfer_address */
+extern gdbarch_remote_translate_xfer_address_ftype generic_remote_translate_xfer_address;
+
+/* Generic implementation of prologue_frameless_p. Just calls
+ SKIP_PROLOG and checks the return value to see if it actually
+ changed. */
+extern gdbarch_prologue_frameless_p_ftype generic_prologue_frameless_p;
+
+/* The only possible cases for inner_than. */
+extern int core_addr_lessthan (CORE_ADDR lhs, CORE_ADDR rhs);
+extern int core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs);
+
+/* Floating point values. */
+extern const struct floatformat *default_float_format (struct gdbarch *gdbarch);
+extern const struct floatformat *default_double_format (struct gdbarch *gdbarch);
+
+/* Helper function for targets that don't know how my arguments are
+ being passed */
+extern int frame_num_args_unknown (struct frame_info *fi);
+
+
+/* The following DEPRECATED interfaces are for pre- multi-arch legacy
+ targets. */
+
+/* DEPRECATED pre- multi-arch interface. Explicitly set the dynamic
+ target-system-dependent parameters based on bfd_architecture and
+ machine. This function is deprecated, use
+ set_gdbarch_from_arch_machine(). */
+
+extern void set_architecture_from_arch_mach (enum bfd_architecture, unsigned long);
+
+/* DEPRECATED pre- multi-arch interface. Notify the target dependent
+ backend of a change to the selected architecture. A zero return
+ status indicates that the target did not like the change. */
+
+extern int (*target_architecture_hook) (const struct bfd_arch_info *);
+
+
+/* Default raw->sim register re-numbering - does nothing. */
+
+extern int default_register_sim_regno (int reg_nr);
+
+/* Identity function on a CORE_ADDR. Just returns its parameter. */
+
+extern CORE_ADDR core_addr_identity (CORE_ADDR addr);
+
+/* No-op conversion of reg to regnum. */
+
+extern int no_op_reg_to_regnum (int reg);
+
+/* Default frame_args_address and frame_locals_address. */
+
+extern CORE_ADDR default_frame_address (struct frame_info *);
+
+/* Default prepare_to_procced. */
+
+extern int default_prepare_to_proceed (int select_it);
+
+extern int generic_prepare_to_proceed (int select_it);
+
+/* Versions of init_frame_pc(). Do nothing; do the default. */
+
+void init_frame_pc_noop (int fromleaf, struct frame_info *prev);
+
+void init_frame_pc_default (int fromleaf, struct frame_info *prev);
+
+/* Do nothing version of elf_make_msymbol_special. */
+
+void default_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym);
+
+/* Do nothing version of coff_make_msymbol_special. */
+
+void default_coff_make_msymbol_special (int val, struct minimal_symbol *msym);
+
+/* Version of cannot_fetch_register() / cannot_store_register() that
+ always fails. */
+
+int cannot_register_not (int regnum);
+
+/* Legacy version of target_virtual_frame_pointer(). Assumes that
+ there is an FP_REGNUM and that it is the same, cooked or raw. */
+
+extern gdbarch_virtual_frame_pointer_ftype legacy_virtual_frame_pointer;
+
+extern CORE_ADDR generic_skip_trampoline_code (CORE_ADDR pc);
+
+extern int generic_in_solib_call_trampoline (CORE_ADDR pc, char *name);
+
+extern int generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc);
+
+extern void default_print_float_info (void);
+
+/* Assume that the world is sane, a registers raw and virtual size
+ both match its type. */
+
+extern int generic_register_size (int regnum);
+
+/* Prop up old targets that use various IN_SIGTRAMP() macros. */
+extern int legacy_pc_in_sigtramp (CORE_ADDR pc, char *name);
+
+/* The orginal register_convert*() functions were overloaded. They
+ were used to both: convert between virtual and raw register formats
+ (something that is discouraged); and to convert a register to the
+ type of a corresponding variable. These legacy functions preserve
+ that overloaded behavour in existing targets. */
+extern int legacy_convert_register_p (int regnum);
+extern void legacy_register_to_value (int regnum, struct type *type, char *from, char *to);
+extern void legacy_value_to_register (struct type *type, int regnum, char *from, char *to);
+
+/* Initialize a ``struct info''. Can't use memset(0) since some
+ default values are not zero. */
+extern void gdbarch_info_init (struct gdbarch_info *info);
+
+#endif
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
new file mode 100644
index 00000000000..8d7ee9de277
--- /dev/null
+++ b/gdb/arm-linux-nat.c
@@ -0,0 +1,698 @@
+/* GNU/Linux on ARM native support.
+ Copyright 1999, 2000, 2001, 2002 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 "defs.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "gdb_string.h"
+#include "regcache.h"
+
+#include "arm-tdep.h"
+
+#include <sys/user.h>
+#include <sys/ptrace.h>
+#include <sys/utsname.h>
+#include <sys/procfs.h>
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+extern int arm_apcs_32;
+
+#define typeNone 0x00
+#define typeSingle 0x01
+#define typeDouble 0x02
+#define typeExtended 0x03
+#define FPWORDS 28
+#define ARM_CPSR_REGNUM 16
+
+typedef union tagFPREG
+ {
+ unsigned int fSingle;
+ unsigned int fDouble[2];
+ unsigned int fExtended[3];
+ }
+FPREG;
+
+typedef struct tagFPA11
+ {
+ FPREG fpreg[8]; /* 8 floating point registers */
+ unsigned int fpsr; /* floating point status register */
+ unsigned int fpcr; /* floating point control register */
+ unsigned char fType[8]; /* type of floating point value held in
+ floating point registers. */
+ int initflag; /* NWFPE initialization flag. */
+ }
+FPA11;
+
+/* The following variables are used to determine the version of the
+ underlying GNU/Linux operating system. Examples:
+
+ GNU/Linux 2.0.35 GNU/Linux 2.2.12
+ os_version = 0x00020023 os_version = 0x0002020c
+ os_major = 2 os_major = 2
+ os_minor = 0 os_minor = 2
+ os_release = 35 os_release = 12
+
+ Note: os_version = (os_major << 16) | (os_minor << 8) | os_release
+
+ These are initialized using get_linux_version() from
+ _initialize_arm_linux_nat(). */
+
+static unsigned int os_version, os_major, os_minor, os_release;
+
+/* On GNU/Linux, threads are implemented as pseudo-processes, in which
+ case we may be tracing more than one process at a time. In that
+ case, inferior_ptid will contain the main process ID and the
+ individual thread (process) ID. get_thread_id () is used to get
+ the thread id if it's available, and the process id otherwise. */
+
+int
+get_thread_id (ptid_t ptid)
+{
+ int tid = TIDGET (ptid);
+ if (0 == tid)
+ tid = PIDGET (ptid);
+ return tid;
+}
+#define GET_THREAD_ID(PTID) get_thread_id ((PTID));
+
+static void
+fetch_nwfpe_single (unsigned int fn, FPA11 * fpa11)
+{
+ unsigned int mem[3];
+
+ mem[0] = fpa11->fpreg[fn].fSingle;
+ mem[1] = 0;
+ mem[2] = 0;
+ supply_register (ARM_F0_REGNUM + fn, (char *) &mem[0]);
+}
+
+static void
+fetch_nwfpe_double (unsigned int fn, FPA11 * fpa11)
+{
+ unsigned int mem[3];
+
+ mem[0] = fpa11->fpreg[fn].fDouble[1];
+ mem[1] = fpa11->fpreg[fn].fDouble[0];
+ mem[2] = 0;
+ supply_register (ARM_F0_REGNUM + fn, (char *) &mem[0]);
+}
+
+static void
+fetch_nwfpe_none (unsigned int fn)
+{
+ unsigned int mem[3] =
+ {0, 0, 0};
+
+ supply_register (ARM_F0_REGNUM + fn, (char *) &mem[0]);
+}
+
+static void
+fetch_nwfpe_extended (unsigned int fn, FPA11 * fpa11)
+{
+ unsigned int mem[3];
+
+ mem[0] = fpa11->fpreg[fn].fExtended[0]; /* sign & exponent */
+ mem[1] = fpa11->fpreg[fn].fExtended[2]; /* ls bits */
+ mem[2] = fpa11->fpreg[fn].fExtended[1]; /* ms bits */
+ supply_register (ARM_F0_REGNUM + fn, (char *) &mem[0]);
+}
+
+static void
+fetch_nwfpe_register (int regno, FPA11 * fpa11)
+{
+ int fn = regno - ARM_F0_REGNUM;
+
+ switch (fpa11->fType[fn])
+ {
+ case typeSingle:
+ fetch_nwfpe_single (fn, fpa11);
+ break;
+
+ case typeDouble:
+ fetch_nwfpe_double (fn, fpa11);
+ break;
+
+ case typeExtended:
+ fetch_nwfpe_extended (fn, fpa11);
+ break;
+
+ default:
+ fetch_nwfpe_none (fn);
+ }
+}
+
+static void
+store_nwfpe_single (unsigned int fn, FPA11 *fpa11)
+{
+ unsigned int mem[3];
+
+ regcache_collect (ARM_F0_REGNUM + fn, (char *) &mem[0]);
+ fpa11->fpreg[fn].fSingle = mem[0];
+ fpa11->fType[fn] = typeSingle;
+}
+
+static void
+store_nwfpe_double (unsigned int fn, FPA11 *fpa11)
+{
+ unsigned int mem[3];
+
+ regcache_collect (ARM_F0_REGNUM + fn, (char *) &mem[0]);
+ fpa11->fpreg[fn].fDouble[1] = mem[0];
+ fpa11->fpreg[fn].fDouble[0] = mem[1];
+ fpa11->fType[fn] = typeDouble;
+}
+
+void
+store_nwfpe_extended (unsigned int fn, FPA11 *fpa11)
+{
+ unsigned int mem[3];
+
+ regcache_collect (ARM_F0_REGNUM + fn, (char *) &mem[0]);
+ fpa11->fpreg[fn].fExtended[0] = mem[0]; /* sign & exponent */
+ fpa11->fpreg[fn].fExtended[2] = mem[1]; /* ls bits */
+ fpa11->fpreg[fn].fExtended[1] = mem[2]; /* ms bits */
+ fpa11->fType[fn] = typeDouble;
+}
+
+void
+store_nwfpe_register (int regno, FPA11 * fpa11)
+{
+ if (register_cached (regno))
+ {
+ unsigned int fn = regno - ARM_F0_REGNUM;
+ switch (fpa11->fType[fn])
+ {
+ case typeSingle:
+ store_nwfpe_single (fn, fpa11);
+ break;
+
+ case typeDouble:
+ store_nwfpe_double (fn, fpa11);
+ break;
+
+ case typeExtended:
+ store_nwfpe_extended (fn, fpa11);
+ break;
+ }
+ }
+}
+
+
+/* Get the value of a particular register from the floating point
+ state of the process and store it into regcache. */
+
+static void
+fetch_fpregister (int regno)
+{
+ int ret, tid;
+ FPA11 fp;
+
+ /* Get the thread id for the ptrace call. */
+ tid = GET_THREAD_ID (inferior_ptid);
+
+ /* Read the floating point state. */
+ ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
+ if (ret < 0)
+ {
+ warning ("Unable to fetch floating point register.");
+ return;
+ }
+
+ /* Fetch fpsr. */
+ if (ARM_FPS_REGNUM == regno)
+ supply_register (ARM_FPS_REGNUM, (char *) &fp.fpsr);
+
+ /* Fetch the floating point register. */
+ if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
+ {
+ int fn = regno - ARM_F0_REGNUM;
+
+ switch (fp.fType[fn])
+ {
+ case typeSingle:
+ fetch_nwfpe_single (fn, &fp);
+ break;
+
+ case typeDouble:
+ fetch_nwfpe_double (fn, &fp);
+ break;
+
+ case typeExtended:
+ fetch_nwfpe_extended (fn, &fp);
+ break;
+
+ default:
+ fetch_nwfpe_none (fn);
+ }
+ }
+}
+
+/* Get the whole floating point state of the process and store it
+ into regcache. */
+
+static void
+fetch_fpregs (void)
+{
+ int ret, regno, tid;
+ FPA11 fp;
+
+ /* Get the thread id for the ptrace call. */
+ tid = GET_THREAD_ID (inferior_ptid);
+
+ /* Read the floating point state. */
+ ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
+ if (ret < 0)
+ {
+ warning ("Unable to fetch the floating point registers.");
+ return;
+ }
+
+ /* Fetch fpsr. */
+ supply_register (ARM_FPS_REGNUM, (char *) &fp.fpsr);
+
+ /* Fetch the floating point registers. */
+ for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
+ {
+ int fn = regno - ARM_F0_REGNUM;
+
+ switch (fp.fType[fn])
+ {
+ case typeSingle:
+ fetch_nwfpe_single (fn, &fp);
+ break;
+
+ case typeDouble:
+ fetch_nwfpe_double (fn, &fp);
+ break;
+
+ case typeExtended:
+ fetch_nwfpe_extended (fn, &fp);
+ break;
+
+ default:
+ fetch_nwfpe_none (fn);
+ }
+ }
+}
+
+/* Save a particular register into the floating point state of the
+ process using the contents from regcache. */
+
+static void
+store_fpregister (int regno)
+{
+ int ret, tid;
+ FPA11 fp;
+
+ /* Get the thread id for the ptrace call. */
+ tid = GET_THREAD_ID (inferior_ptid);
+
+ /* Read the floating point state. */
+ ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
+ if (ret < 0)
+ {
+ warning ("Unable to fetch the floating point registers.");
+ return;
+ }
+
+ /* Store fpsr. */
+ if (ARM_FPS_REGNUM == regno && register_cached (ARM_FPS_REGNUM))
+ regcache_collect (ARM_FPS_REGNUM, (char *) &fp.fpsr);
+
+ /* Store the floating point register. */
+ if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
+ {
+ store_nwfpe_register (regno, &fp);
+ }
+
+ ret = ptrace (PTRACE_SETFPREGS, tid, 0, &fp);
+ if (ret < 0)
+ {
+ warning ("Unable to store floating point register.");
+ return;
+ }
+}
+
+/* Save the whole floating point state of the process using
+ the contents from regcache. */
+
+static void
+store_fpregs (void)
+{
+ int ret, regno, tid;
+ FPA11 fp;
+
+ /* Get the thread id for the ptrace call. */
+ tid = GET_THREAD_ID (inferior_ptid);
+
+ /* Read the floating point state. */
+ ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
+ if (ret < 0)
+ {
+ warning ("Unable to fetch the floating point registers.");
+ return;
+ }
+
+ /* Store fpsr. */
+ if (register_cached (ARM_FPS_REGNUM))
+ regcache_collect (ARM_FPS_REGNUM, (char *) &fp.fpsr);
+
+ /* Store the floating point registers. */
+ for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
+ {
+ fetch_nwfpe_register (regno, &fp);
+ }
+
+ ret = ptrace (PTRACE_SETFPREGS, tid, 0, &fp);
+ if (ret < 0)
+ {
+ warning ("Unable to store floating point registers.");
+ return;
+ }
+}
+
+/* Fetch a general register of the process and store into
+ regcache. */
+
+static void
+fetch_register (int regno)
+{
+ int ret, tid;
+ elf_gregset_t regs;
+
+ /* Get the thread id for the ptrace call. */
+ tid = GET_THREAD_ID (inferior_ptid);
+
+ ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
+ if (ret < 0)
+ {
+ warning ("Unable to fetch general register.");
+ return;
+ }
+
+ if (regno >= ARM_A1_REGNUM && regno < ARM_PC_REGNUM)
+ supply_register (regno, (char *) &regs[regno]);
+
+ if (ARM_PS_REGNUM == regno)
+ {
+ if (arm_apcs_32)
+ supply_register (ARM_PS_REGNUM, (char *) &regs[ARM_CPSR_REGNUM]);
+ else
+ supply_register (ARM_PS_REGNUM, (char *) &regs[ARM_PC_REGNUM]);
+ }
+
+ if (ARM_PC_REGNUM == regno)
+ {
+ regs[ARM_PC_REGNUM] = ADDR_BITS_REMOVE (regs[ARM_PC_REGNUM]);
+ supply_register (ARM_PC_REGNUM, (char *) &regs[ARM_PC_REGNUM]);
+ }
+}
+
+/* Fetch all general registers of the process and store into
+ regcache. */
+
+static void
+fetch_regs (void)
+{
+ int ret, regno, tid;
+ elf_gregset_t regs;
+
+ /* Get the thread id for the ptrace call. */
+ tid = GET_THREAD_ID (inferior_ptid);
+
+ ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
+ if (ret < 0)
+ {
+ warning ("Unable to fetch general registers.");
+ return;
+ }
+
+ for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
+ supply_register (regno, (char *) &regs[regno]);
+
+ if (arm_apcs_32)
+ supply_register (ARM_PS_REGNUM, (char *) &regs[ARM_CPSR_REGNUM]);
+ else
+ supply_register (ARM_PS_REGNUM, (char *) &regs[ARM_PC_REGNUM]);
+
+ regs[ARM_PC_REGNUM] = ADDR_BITS_REMOVE (regs[ARM_PC_REGNUM]);
+ supply_register (ARM_PC_REGNUM, (char *) &regs[ARM_PC_REGNUM]);
+}
+
+/* Store all general registers of the process from the values in
+ regcache. */
+
+static void
+store_register (int regno)
+{
+ int ret, tid;
+ elf_gregset_t regs;
+
+ if (!register_cached (regno))
+ return;
+
+ /* Get the thread id for the ptrace call. */
+ tid = GET_THREAD_ID (inferior_ptid);
+
+ /* Get the general registers from the process. */
+ ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
+ if (ret < 0)
+ {
+ warning ("Unable to fetch general registers.");
+ return;
+ }
+
+ if (regno >= ARM_A1_REGNUM && regno <= ARM_PC_REGNUM)
+ regcache_collect (regno, (char *) &regs[regno]);
+
+ ret = ptrace (PTRACE_SETREGS, tid, 0, &regs);
+ if (ret < 0)
+ {
+ warning ("Unable to store general register.");
+ return;
+ }
+}
+
+static void
+store_regs (void)
+{
+ int ret, regno, tid;
+ elf_gregset_t regs;
+
+ /* Get the thread id for the ptrace call. */
+ tid = GET_THREAD_ID (inferior_ptid);
+
+ /* Fetch the general registers. */
+ ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
+ if (ret < 0)
+ {
+ warning ("Unable to fetch general registers.");
+ return;
+ }
+
+ for (regno = ARM_A1_REGNUM; regno <= ARM_PC_REGNUM; regno++)
+ {
+ if (register_cached (regno))
+ regcache_collect (regno, (char *) &regs[regno]);
+ }
+
+ ret = ptrace (PTRACE_SETREGS, tid, 0, &regs);
+
+ if (ret < 0)
+ {
+ warning ("Unable to store general registers.");
+ return;
+ }
+}
+
+/* Fetch registers from the child process. Fetch all registers if
+ regno == -1, otherwise fetch all general registers or all floating
+ point registers depending upon the value of regno. */
+
+void
+fetch_inferior_registers (int regno)
+{
+ if (-1 == regno)
+ {
+ fetch_regs ();
+ fetch_fpregs ();
+ }
+ else
+ {
+ if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
+ fetch_register (regno);
+
+ if (regno >= ARM_F0_REGNUM && regno <= ARM_FPS_REGNUM)
+ fetch_fpregister (regno);
+ }
+}
+
+/* Store registers back into the inferior. Store all registers if
+ regno == -1, otherwise store all general registers or all floating
+ point registers depending upon the value of regno. */
+
+void
+store_inferior_registers (int regno)
+{
+ if (-1 == regno)
+ {
+ store_regs ();
+ store_fpregs ();
+ }
+ else
+ {
+ if ((regno < ARM_F0_REGNUM) || (regno > ARM_FPS_REGNUM))
+ store_register (regno);
+
+ if ((regno >= ARM_F0_REGNUM) && (regno <= ARM_FPS_REGNUM))
+ store_fpregister (regno);
+ }
+}
+
+/* Fill register regno (if it is a general-purpose register) in
+ *gregsetp with the appropriate value from GDB's register array.
+ If regno is -1, do this for all registers. */
+
+void
+fill_gregset (gdb_gregset_t *gregsetp, int regno)
+{
+ if (-1 == regno)
+ {
+ int regnum;
+ for (regnum = ARM_A1_REGNUM; regnum <= ARM_PC_REGNUM; regnum++)
+ regcache_collect (regnum, (char *) &(*gregsetp)[regnum]);
+ }
+ else if (regno >= ARM_A1_REGNUM && regno <= ARM_PC_REGNUM)
+ regcache_collect (regno, (char *) &(*gregsetp)[regno]);
+
+ if (ARM_PS_REGNUM == regno || -1 == regno)
+ {
+ if (arm_apcs_32)
+ regcache_collect (ARM_PS_REGNUM,
+ (char *) &(*gregsetp)[ARM_CPSR_REGNUM]);
+ else
+ regcache_collect (ARM_PC_REGNUM,
+ (char *) &(*gregsetp)[ARM_PC_REGNUM]);
+ }
+}
+
+/* Fill GDB's register array with the general-purpose register values
+ in *gregsetp. */
+
+void
+supply_gregset (gdb_gregset_t *gregsetp)
+{
+ int regno, reg_pc;
+
+ for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
+ supply_register (regno, (char *) &(*gregsetp)[regno]);
+
+ if (arm_apcs_32)
+ supply_register (ARM_PS_REGNUM, (char *) &(*gregsetp)[ARM_CPSR_REGNUM]);
+ else
+ supply_register (ARM_PS_REGNUM, (char *) &(*gregsetp)[ARM_PC_REGNUM]);
+
+ reg_pc = ADDR_BITS_REMOVE ((CORE_ADDR)(*gregsetp)[ARM_PC_REGNUM]);
+ supply_register (ARM_PC_REGNUM, (char *) &reg_pc);
+}
+
+/* Fill register regno (if it is a floating-point register) in
+ *fpregsetp with the appropriate value from GDB's register array.
+ If regno is -1, do this for all registers. */
+
+void
+fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
+{
+ FPA11 *fp = (FPA11 *) fpregsetp;
+
+ if (-1 == regno)
+ {
+ int regnum;
+ for (regnum = ARM_F0_REGNUM; regnum <= ARM_F7_REGNUM; regnum++)
+ store_nwfpe_register (regnum, fp);
+ }
+ else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
+ {
+ store_nwfpe_register (regno, fp);
+ return;
+ }
+
+ /* Store fpsr. */
+ if (ARM_FPS_REGNUM == regno || -1 == regno)
+ regcache_collect (ARM_FPS_REGNUM, (char *) &fp->fpsr);
+}
+
+/* Fill GDB's register array with the floating-point register values
+ in *fpregsetp. */
+
+void
+supply_fpregset (gdb_fpregset_t *fpregsetp)
+{
+ int regno;
+ FPA11 *fp = (FPA11 *) fpregsetp;
+
+ /* Fetch fpsr. */
+ supply_register (ARM_FPS_REGNUM, (char *) &fp->fpsr);
+
+ /* Fetch the floating point registers. */
+ for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
+ {
+ fetch_nwfpe_register (regno, fp);
+ }
+}
+
+int
+arm_linux_kernel_u_size (void)
+{
+ return (sizeof (struct user));
+}
+
+static unsigned int
+get_linux_version (unsigned int *vmajor,
+ unsigned int *vminor,
+ unsigned int *vrelease)
+{
+ struct utsname info;
+ char *pmajor, *pminor, *prelease, *tail;
+
+ if (-1 == uname (&info))
+ {
+ warning ("Unable to determine GNU/Linux version.");
+ return -1;
+ }
+
+ pmajor = strtok (info.release, ".");
+ pminor = strtok (NULL, ".");
+ prelease = strtok (NULL, ".");
+
+ *vmajor = (unsigned int) strtoul (pmajor, &tail, 0);
+ *vminor = (unsigned int) strtoul (pminor, &tail, 0);
+ *vrelease = (unsigned int) strtoul (prelease, &tail, 0);
+
+ return ((*vmajor << 16) | (*vminor << 8) | *vrelease);
+}
+
+void
+_initialize_arm_linux_nat (void)
+{
+ os_version = get_linux_version (&os_major, &os_minor, &os_release);
+}
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
new file mode 100644
index 00000000000..920d27ba95f
--- /dev/null
+++ b/gdb/arm-linux-tdep.c
@@ -0,0 +1,547 @@
+/* GNU/Linux on ARM target support.
+ Copyright 1999, 2000, 2001, 2002 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 "defs.h"
+#include "target.h"
+#include "value.h"
+#include "gdbtypes.h"
+#include "floatformat.h"
+#include "gdbcore.h"
+#include "frame.h"
+#include "regcache.h"
+#include "doublest.h"
+
+#include "arm-tdep.h"
+
+/* For shared library handling. */
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+
+/* Under ARM GNU/Linux the traditional way of performing a breakpoint
+ is to execute a particular software interrupt, rather than use a
+ particular undefined instruction to provoke a trap. Upon exection
+ of the software interrupt the kernel stops the inferior with a
+ SIGTRAP, and wakes the debugger. Since ARM GNU/Linux is little
+ endian, and doesn't support Thumb at the moment we only override
+ the ARM little-endian breakpoint. */
+
+static const char arm_linux_arm_le_breakpoint[] = {0x01,0x00,0x9f,0xef};
+
+/* CALL_DUMMY_WORDS:
+ This sequence of words is the instructions
+
+ mov lr, pc
+ mov pc, r4
+ swi bkpt_swi
+
+ Note this is 12 bytes. */
+
+LONGEST arm_linux_call_dummy_words[] =
+{
+ 0xe1a0e00f, 0xe1a0f004, 0xef9f001
+};
+
+/* Description of the longjmp buffer. */
+#define ARM_LINUX_JB_ELEMENT_SIZE INT_REGISTER_RAW_SIZE
+#define ARM_LINUX_JB_PC 21
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. */
+/* FIXME rearnsha/2002-02-23: This function shouldn't be necessary.
+ The ARM generic one should be able to handle the model used by
+ linux and the low-level formatting of the registers should be
+ hidden behind the regcache abstraction. */
+static void
+arm_linux_extract_return_value (struct type *type,
+ char regbuf[REGISTER_BYTES],
+ char *valbuf)
+{
+ /* ScottB: This needs to be looked at to handle the different
+ floating point emulators on ARM GNU/Linux. Right now the code
+ assumes that fetch inferior registers does the right thing for
+ GDB. I suspect this won't handle NWFPE registers correctly, nor
+ will the default ARM version (arm_extract_return_value()). */
+
+ int regnum = ((TYPE_CODE_FLT == TYPE_CODE (type))
+ ? ARM_F0_REGNUM : ARM_A1_REGNUM);
+ memcpy (valbuf, &regbuf[REGISTER_BYTE (regnum)], TYPE_LENGTH (type));
+}
+
+/* Note: ScottB
+
+ This function does not support passing parameters using the FPA
+ variant of the APCS. It passes any floating point arguments in the
+ general registers and/or on the stack.
+
+ FIXME: This and arm_push_arguments should be merged. However this
+ function breaks on a little endian host, big endian target
+ using the COFF file format. ELF is ok.
+
+ ScottB. */
+
+/* Addresses for calling Thumb functions have the bit 0 set.
+ Here are some macros to test, set, or clear bit 0 of addresses. */
+#define IS_THUMB_ADDR(addr) ((addr) & 1)
+#define MAKE_THUMB_ADDR(addr) ((addr) | 1)
+#define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1)
+
+static CORE_ADDR
+arm_linux_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ char *fp;
+ int argnum, argreg, nstack_size;
+
+ /* Walk through the list of args and determine how large a temporary
+ stack is required. Need to take care here as structs may be
+ passed on the stack, and we have to to push them. */
+ nstack_size = -4 * REGISTER_SIZE; /* Some arguments go into A1-A4. */
+
+ if (struct_return) /* The struct address goes in A1. */
+ nstack_size += REGISTER_SIZE;
+
+ /* Walk through the arguments and add their size to nstack_size. */
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ int len;
+ struct type *arg_type;
+
+ arg_type = check_typedef (VALUE_TYPE (args[argnum]));
+ len = TYPE_LENGTH (arg_type);
+
+ /* ANSI C code passes float arguments as integers, K&R code
+ passes float arguments as doubles. Correct for this here. */
+ if (TYPE_CODE_FLT == TYPE_CODE (arg_type) && REGISTER_SIZE == len)
+ nstack_size += FP_REGISTER_VIRTUAL_SIZE;
+ else
+ nstack_size += len;
+ }
+
+ /* Allocate room on the stack, and initialize our stack frame
+ pointer. */
+ fp = NULL;
+ if (nstack_size > 0)
+ {
+ sp -= nstack_size;
+ fp = (char *) sp;
+ }
+
+ /* Initialize the integer argument register pointer. */
+ argreg = ARM_A1_REGNUM;
+
+ /* The struct_return pointer occupies the first parameter passing
+ register. */
+ if (struct_return)
+ write_register (argreg++, struct_addr);
+
+ /* Process arguments from left to right. Store as many as allowed
+ in the parameter passing registers (A1-A4), and save the rest on
+ the temporary stack. */
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ int len;
+ char *val;
+ CORE_ADDR regval;
+ enum type_code typecode;
+ struct type *arg_type, *target_type;
+
+ arg_type = check_typedef (VALUE_TYPE (args[argnum]));
+ target_type = TYPE_TARGET_TYPE (arg_type);
+ len = TYPE_LENGTH (arg_type);
+ typecode = TYPE_CODE (arg_type);
+ val = (char *) VALUE_CONTENTS (args[argnum]);
+
+ /* ANSI C code passes float arguments as integers, K&R code
+ passes float arguments as doubles. The .stabs record for
+ for ANSI prototype floating point arguments records the
+ type as FP_INTEGER, while a K&R style (no prototype)
+ .stabs records the type as FP_FLOAT. In this latter case
+ the compiler converts the float arguments to double before
+ calling the function. */
+ if (TYPE_CODE_FLT == typecode && REGISTER_SIZE == len)
+ {
+ DOUBLEST dblval;
+ dblval = extract_floating (val, len);
+ len = TARGET_DOUBLE_BIT / TARGET_CHAR_BIT;
+ val = alloca (len);
+ store_floating (val, len, dblval);
+ }
+
+ /* If the argument is a pointer to a function, and it is a Thumb
+ function, set the low bit of the pointer. */
+ if (TYPE_CODE_PTR == typecode
+ && NULL != target_type
+ && TYPE_CODE_FUNC == TYPE_CODE (target_type))
+ {
+ CORE_ADDR regval = extract_address (val, len);
+ if (arm_pc_is_thumb (regval))
+ store_address (val, len, MAKE_THUMB_ADDR (regval));
+ }
+
+ /* Copy the argument to general registers or the stack in
+ register-sized pieces. Large arguments are split between
+ registers and stack. */
+ while (len > 0)
+ {
+ int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE;
+
+ if (argreg <= ARM_LAST_ARG_REGNUM)
+ {
+ /* It's an argument being passed in a general register. */
+ regval = extract_address (val, partial_len);
+ write_register (argreg++, regval);
+ }
+ else
+ {
+ /* Push the arguments onto the stack. */
+ write_memory ((CORE_ADDR) fp, val, REGISTER_SIZE);
+ fp += REGISTER_SIZE;
+ }
+
+ len -= partial_len;
+ val += partial_len;
+ }
+ }
+
+ /* Return adjusted stack pointer. */
+ return sp;
+}
+
+/*
+ Dynamic Linking on ARM GNU/Linux
+ --------------------------------
+
+ Note: PLT = procedure linkage table
+ GOT = global offset table
+
+ As much as possible, ELF dynamic linking defers the resolution of
+ jump/call addresses until the last minute. The technique used is
+ inspired by the i386 ELF design, and is based on the following
+ constraints.
+
+ 1) The calling technique should not force a change in the assembly
+ code produced for apps; it MAY cause changes in the way assembly
+ code is produced for position independent code (i.e. shared
+ libraries).
+
+ 2) The technique must be such that all executable areas must not be
+ modified; and any modified areas must not be executed.
+
+ To do this, there are three steps involved in a typical jump:
+
+ 1) in the code
+ 2) through the PLT
+ 3) using a pointer from the GOT
+
+ When the executable or library is first loaded, each GOT entry is
+ initialized to point to the code which implements dynamic name
+ resolution and code finding. This is normally a function in the
+ program interpreter (on ARM GNU/Linux this is usually
+ ld-linux.so.2, but it does not have to be). On the first
+ invocation, the function is located and the GOT entry is replaced
+ with the real function address. Subsequent calls go through steps
+ 1, 2 and 3 and end up calling the real code.
+
+ 1) In the code:
+
+ b function_call
+ bl function_call
+
+ This is typical ARM code using the 26 bit relative branch or branch
+ and link instructions. The target of the instruction
+ (function_call is usually the address of the function to be called.
+ In position independent code, the target of the instruction is
+ actually an entry in the PLT when calling functions in a shared
+ library. Note that this call is identical to a normal function
+ call, only the target differs.
+
+ 2) In the PLT:
+
+ The PLT is a synthetic area, created by the linker. It exists in
+ both executables and libraries. It is an array of stubs, one per
+ imported function call. It looks like this:
+
+ PLT[0]:
+ str lr, [sp, #-4]! @push the return address (lr)
+ ldr lr, [pc, #16] @load from 6 words ahead
+ add lr, pc, lr @form an address for GOT[0]
+ ldr pc, [lr, #8]! @jump to the contents of that addr
+
+ The return address (lr) is pushed on the stack and used for
+ calculations. The load on the second line loads the lr with
+ &GOT[3] - . - 20. The addition on the third leaves:
+
+ lr = (&GOT[3] - . - 20) + (. + 8)
+ lr = (&GOT[3] - 12)
+ lr = &GOT[0]
+
+ On the fourth line, the pc and lr are both updated, so that:
+
+ pc = GOT[2]
+ lr = &GOT[0] + 8
+ = &GOT[2]
+
+ NOTE: PLT[0] borrows an offset .word from PLT[1]. This is a little
+ "tight", but allows us to keep all the PLT entries the same size.
+
+ PLT[n+1]:
+ ldr ip, [pc, #4] @load offset from gotoff
+ add ip, pc, ip @add the offset to the pc
+ ldr pc, [ip] @jump to that address
+ gotoff: .word GOT[n+3] - .
+
+ The load on the first line, gets an offset from the fourth word of
+ the PLT entry. The add on the second line makes ip = &GOT[n+3],
+ which contains either a pointer to PLT[0] (the fixup trampoline) or
+ a pointer to the actual code.
+
+ 3) In the GOT:
+
+ The GOT contains helper pointers for both code (PLT) fixups and
+ data fixups. The first 3 entries of the GOT are special. The next
+ M entries (where M is the number of entries in the PLT) belong to
+ the PLT fixups. The next D (all remaining) entries belong to
+ various data fixups. The actual size of the GOT is 3 + M + D.
+
+ The GOT is also a synthetic area, created by the linker. It exists
+ in both executables and libraries. When the GOT is first
+ initialized , all the GOT entries relating to PLT fixups are
+ pointing to code back at PLT[0].
+
+ The special entries in the GOT are:
+
+ GOT[0] = linked list pointer used by the dynamic loader
+ GOT[1] = pointer to the reloc table for this module
+ GOT[2] = pointer to the fixup/resolver code
+
+ The first invocation of function call comes through and uses the
+ fixup/resolver code. On the entry to the fixup/resolver code:
+
+ ip = &GOT[n+3]
+ lr = &GOT[2]
+ stack[0] = return address (lr) of the function call
+ [r0, r1, r2, r3] are still the arguments to the function call
+
+ This is enough information for the fixup/resolver code to work
+ with. Before the fixup/resolver code returns, it actually calls
+ the requested function and repairs &GOT[n+3]. */
+
+/* Find the minimal symbol named NAME, and return both the minsym
+ struct and its objfile. This probably ought to be in minsym.c, but
+ everything there is trying to deal with things like C++ and
+ SOFUN_ADDRESS_MAYBE_TURQUOISE, ... Since this is so simple, it may
+ be considered too special-purpose for general consumption. */
+
+static struct minimal_symbol *
+find_minsym_and_objfile (char *name, struct objfile **objfile_p)
+{
+ struct objfile *objfile;
+
+ ALL_OBJFILES (objfile)
+ {
+ struct minimal_symbol *msym;
+
+ ALL_OBJFILE_MSYMBOLS (objfile, msym)
+ {
+ if (SYMBOL_NAME (msym)
+ && strcmp (SYMBOL_NAME (msym), name) == 0)
+ {
+ *objfile_p = objfile;
+ return msym;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+static CORE_ADDR
+skip_hurd_resolver (CORE_ADDR pc)
+{
+ /* The HURD dynamic linker is part of the GNU C library, so many
+ GNU/Linux distributions use it. (All ELF versions, as far as I
+ know.) An unresolved PLT entry points to "_dl_runtime_resolve",
+ which calls "fixup" to patch the PLT, and then passes control to
+ the function.
+
+ We look for the symbol `_dl_runtime_resolve', and find `fixup' in
+ the same objfile. If we are at the entry point of `fixup', then
+ we set a breakpoint at the return address (at the top of the
+ stack), and continue.
+
+ It's kind of gross to do all these checks every time we're
+ called, since they don't change once the executable has gotten
+ started. But this is only a temporary hack --- upcoming versions
+ of GNU/Linux will provide a portable, efficient interface for
+ debugging programs that use shared libraries. */
+
+ struct objfile *objfile;
+ struct minimal_symbol *resolver
+ = find_minsym_and_objfile ("_dl_runtime_resolve", &objfile);
+
+ if (resolver)
+ {
+ struct minimal_symbol *fixup
+ = lookup_minimal_symbol ("fixup", NULL, objfile);
+
+ if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc)
+ return (SAVED_PC_AFTER_CALL (get_current_frame ()));
+ }
+
+ return 0;
+}
+
+/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c.
+ This function:
+ 1) decides whether a PLT has sent us into the linker to resolve
+ a function reference, and
+ 2) if so, tells us where to set a temporary breakpoint that will
+ trigger when the dynamic linker is done. */
+
+CORE_ADDR
+arm_linux_skip_solib_resolver (CORE_ADDR pc)
+{
+ CORE_ADDR result;
+
+ /* Plug in functions for other kinds of resolvers here. */
+ result = skip_hurd_resolver (pc);
+
+ if (result)
+ return result;
+
+ return 0;
+}
+
+/* The constants below were determined by examining the following files
+ in the linux kernel sources:
+
+ arch/arm/kernel/signal.c
+ - see SWI_SYS_SIGRETURN and SWI_SYS_RT_SIGRETURN
+ include/asm-arm/unistd.h
+ - see __NR_sigreturn, __NR_rt_sigreturn, and __NR_SYSCALL_BASE */
+
+#define ARM_LINUX_SIGRETURN_INSTR 0xef900077
+#define ARM_LINUX_RT_SIGRETURN_INSTR 0xef9000ad
+
+/* arm_linux_in_sigtramp determines if PC points at one of the
+ instructions which cause control to return to the Linux kernel upon
+ return from a signal handler. FUNC_NAME is unused. */
+
+int
+arm_linux_in_sigtramp (CORE_ADDR pc, char *func_name)
+{
+ unsigned long inst;
+
+ inst = read_memory_integer (pc, 4);
+
+ return (inst == ARM_LINUX_SIGRETURN_INSTR
+ || inst == ARM_LINUX_RT_SIGRETURN_INSTR);
+
+}
+
+/* arm_linux_sigcontext_register_address returns the address in the
+ sigcontext of register REGNO given a stack pointer value SP and
+ program counter value PC. The value 0 is returned if PC is not
+ pointing at one of the signal return instructions or if REGNO is
+ not saved in the sigcontext struct. */
+
+CORE_ADDR
+arm_linux_sigcontext_register_address (CORE_ADDR sp, CORE_ADDR pc, int regno)
+{
+ unsigned long inst;
+ CORE_ADDR reg_addr = 0;
+
+ inst = read_memory_integer (pc, 4);
+
+ if (inst == ARM_LINUX_SIGRETURN_INSTR
+ || inst == ARM_LINUX_RT_SIGRETURN_INSTR)
+ {
+ CORE_ADDR sigcontext_addr;
+
+ /* The sigcontext structure is at different places for the two
+ signal return instructions. For ARM_LINUX_SIGRETURN_INSTR,
+ it starts at the SP value. For ARM_LINUX_RT_SIGRETURN_INSTR,
+ it is at SP+8. For the latter instruction, it may also be
+ the case that the address of this structure may be determined
+ by reading the 4 bytes at SP, but I'm not convinced this is
+ reliable.
+
+ In any event, these magic constants (0 and 8) may be
+ determined by examining struct sigframe and struct
+ rt_sigframe in arch/arm/kernel/signal.c in the Linux kernel
+ sources. */
+
+ if (inst == ARM_LINUX_RT_SIGRETURN_INSTR)
+ sigcontext_addr = sp + 8;
+ else /* inst == ARM_LINUX_SIGRETURN_INSTR */
+ sigcontext_addr = sp + 0;
+
+ /* The layout of the sigcontext structure for ARM GNU/Linux is
+ in include/asm-arm/sigcontext.h in the Linux kernel sources.
+
+ There are three 4-byte fields which precede the saved r0
+ field. (This accounts for the 12 in the code below.) The
+ sixteen registers (4 bytes per field) follow in order. The
+ PSR value follows the sixteen registers which accounts for
+ the constant 19 below. */
+
+ if (0 <= regno && regno <= ARM_PC_REGNUM)
+ reg_addr = sigcontext_addr + 12 + (4 * regno);
+ else if (regno == ARM_PS_REGNUM)
+ reg_addr = sigcontext_addr + 19 * 4;
+ }
+
+ return reg_addr;
+}
+
+static void
+arm_linux_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->lowest_pc = 0x8000;
+ tdep->arm_breakpoint = arm_linux_arm_le_breakpoint;
+ tdep->arm_breakpoint_size = sizeof (arm_linux_arm_le_breakpoint);
+
+ tdep->jb_pc = ARM_LINUX_JB_PC;
+ tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE;
+
+ set_gdbarch_call_dummy_words (gdbarch, arm_linux_call_dummy_words);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch,
+ sizeof (arm_linux_call_dummy_words));
+
+ /* The following two overrides shouldn't be needed. */
+ set_gdbarch_extract_return_value (gdbarch, arm_linux_extract_return_value);
+ set_gdbarch_push_arguments (gdbarch, arm_linux_push_arguments);
+
+ /* Shared library handling. */
+ set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
+ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+}
+
+void
+_initialize_arm_linux_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_arm, GDB_OSABI_LINUX, arm_linux_init_abi);
+}
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
new file mode 100644
index 00000000000..04fca2e44c6
--- /dev/null
+++ b/gdb/arm-tdep.c
@@ -0,0 +1,3079 @@
+/* Common target dependent code for GDB on ARM systems.
+ Copyright 1988, 1989, 1991, 1992, 1993, 1995, 1996, 1998, 1999, 2000,
+ 2001, 2002 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 <ctype.h> /* XXX for isupper () */
+
+#include "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "symfile.h"
+#include "gdb_string.h"
+#include "dis-asm.h" /* For register flavors. */
+#include "regcache.h"
+#include "doublest.h"
+#include "value.h"
+#include "arch-utils.h"
+#include "solib-svr4.h"
+
+#include "arm-tdep.h"
+
+#include "elf-bfd.h"
+#include "coff/internal.h"
+#include "elf/arm.h"
+
+/* Each OS has a different mechanism for accessing the various
+ registers stored in the sigcontext structure.
+
+ SIGCONTEXT_REGISTER_ADDRESS should be defined to the name (or
+ function pointer) which may be used to determine the addresses
+ of the various saved registers in the sigcontext structure.
+
+ For the ARM target, there are three parameters to this function.
+ The first is the pc value of the frame under consideration, the
+ second the stack pointer of this frame, and the last is the
+ register number to fetch.
+
+ If the tm.h file does not define this macro, then it's assumed that
+ no mechanism is needed and we define SIGCONTEXT_REGISTER_ADDRESS to
+ be 0.
+
+ When it comes time to multi-arching this code, see the identically
+ named machinery in ia64-tdep.c for an example of how it could be
+ done. It should not be necessary to modify the code below where
+ this macro is used. */
+
+#ifdef SIGCONTEXT_REGISTER_ADDRESS
+#ifndef SIGCONTEXT_REGISTER_ADDRESS_P
+#define SIGCONTEXT_REGISTER_ADDRESS_P() 1
+#endif
+#else
+#define SIGCONTEXT_REGISTER_ADDRESS(SP,PC,REG) 0
+#define SIGCONTEXT_REGISTER_ADDRESS_P() 0
+#endif
+
+/* Macros for setting and testing a bit in a minimal symbol that marks
+ it as Thumb function. The MSB of the minimal symbol's "info" field
+ is used for this purpose. This field is already being used to store
+ the symbol size, so the assumption is that the symbol size cannot
+ exceed 2^31.
+
+ MSYMBOL_SET_SPECIAL Actually sets the "special" bit.
+ MSYMBOL_IS_SPECIAL Tests the "special" bit in a minimal symbol.
+ MSYMBOL_SIZE Returns the size of the minimal symbol,
+ i.e. the "info" field with the "special" bit
+ masked out. */
+
+#define MSYMBOL_SET_SPECIAL(msym) \
+ MSYMBOL_INFO (msym) = (char *) (((long) MSYMBOL_INFO (msym)) \
+ | 0x80000000)
+
+#define MSYMBOL_IS_SPECIAL(msym) \
+ (((long) MSYMBOL_INFO (msym) & 0x80000000) != 0)
+
+#define MSYMBOL_SIZE(msym) \
+ ((long) MSYMBOL_INFO (msym) & 0x7fffffff)
+
+/* Number of different reg name sets (options). */
+static int num_flavor_options;
+
+/* We have more registers than the disassembler as gdb can print the value
+ of special registers as well.
+ The general register names are overwritten by whatever is being used by
+ the disassembler at the moment. We also adjust the case of cpsr and fps. */
+
+/* Initial value: Register names used in ARM's ISA documentation. */
+static char * arm_register_name_strings[] =
+{"r0", "r1", "r2", "r3", /* 0 1 2 3 */
+ "r4", "r5", "r6", "r7", /* 4 5 6 7 */
+ "r8", "r9", "r10", "r11", /* 8 9 10 11 */
+ "r12", "sp", "lr", "pc", /* 12 13 14 15 */
+ "f0", "f1", "f2", "f3", /* 16 17 18 19 */
+ "f4", "f5", "f6", "f7", /* 20 21 22 23 */
+ "fps", "cpsr" }; /* 24 25 */
+static char **arm_register_names = arm_register_name_strings;
+
+/* Valid register name flavors. */
+static const char **valid_flavors;
+
+/* Disassembly flavor to use. Default to "std" register names. */
+static const char *disassembly_flavor;
+/* Index to that option in the opcodes table. */
+static int current_option;
+
+/* This is used to keep the bfd arch_info in sync with the disassembly
+ flavor. */
+static void set_disassembly_flavor_sfunc(char *, int,
+ struct cmd_list_element *);
+static void set_disassembly_flavor (void);
+
+static void convert_from_extended (void *ptr, void *dbl);
+
+/* Define other aspects of the stack frame. We keep the offsets of
+ all saved registers, 'cause we need 'em a lot! We also keep the
+ current size of the stack frame, and the offset of the frame
+ pointer from the stack pointer (for frameless functions, and when
+ we're still in the prologue of a function with a frame). */
+
+struct frame_extra_info
+{
+ int framesize;
+ int frameoffset;
+ int framereg;
+};
+
+/* Addresses for calling Thumb functions have the bit 0 set.
+ Here are some macros to test, set, or clear bit 0 of addresses. */
+#define IS_THUMB_ADDR(addr) ((addr) & 1)
+#define MAKE_THUMB_ADDR(addr) ((addr) | 1)
+#define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1)
+
+static int
+arm_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
+{
+ return (chain != 0 && (FRAME_SAVED_PC (thisframe) >= LOWEST_PC));
+}
+
+/* Set to true if the 32-bit mode is in use. */
+
+int arm_apcs_32 = 1;
+
+/* Flag set by arm_fix_call_dummy that tells whether the target
+ function is a Thumb function. This flag is checked by
+ arm_push_arguments. FIXME: Change the PUSH_ARGUMENTS macro (and
+ its use in valops.c) to pass the function address as an additional
+ parameter. */
+
+static int target_is_thumb;
+
+/* Flag set by arm_fix_call_dummy that tells whether the calling
+ function is a Thumb function. This flag is checked by
+ arm_pc_is_thumb and arm_call_dummy_breakpoint_offset. */
+
+static int caller_is_thumb;
+
+/* Determine if the program counter specified in MEMADDR is in a Thumb
+ function. */
+
+int
+arm_pc_is_thumb (CORE_ADDR memaddr)
+{
+ struct minimal_symbol *sym;
+
+ /* If bit 0 of the address is set, assume this is a Thumb address. */
+ if (IS_THUMB_ADDR (memaddr))
+ return 1;
+
+ /* Thumb functions have a "special" bit set in minimal symbols. */
+ sym = lookup_minimal_symbol_by_pc (memaddr);
+ if (sym)
+ {
+ return (MSYMBOL_IS_SPECIAL (sym));
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/* Determine if the program counter specified in MEMADDR is in a call
+ dummy being called from a Thumb function. */
+
+int
+arm_pc_is_thumb_dummy (CORE_ADDR memaddr)
+{
+ CORE_ADDR sp = read_sp ();
+
+ /* FIXME: Until we switch for the new call dummy macros, this heuristic
+ is the best we can do. We are trying to determine if the pc is on
+ the stack, which (hopefully) will only happen in a call dummy.
+ We hope the current stack pointer is not so far alway from the dummy
+ frame location (true if we have not pushed large data structures or
+ gone too many levels deep) and that our 1024 is not enough to consider
+ code regions as part of the stack (true for most practical purposes). */
+ if (PC_IN_CALL_DUMMY (memaddr, sp, sp + 1024))
+ return caller_is_thumb;
+ else
+ return 0;
+}
+
+/* Remove useless bits from addresses in a running program. */
+static CORE_ADDR
+arm_addr_bits_remove (CORE_ADDR val)
+{
+ if (arm_pc_is_thumb (val))
+ return (val & (arm_apcs_32 ? 0xfffffffe : 0x03fffffe));
+ else
+ return (val & (arm_apcs_32 ? 0xfffffffc : 0x03fffffc));
+}
+
+/* When reading symbols, we need to zap the low bit of the address,
+ which may be set to 1 for Thumb functions. */
+static CORE_ADDR
+arm_smash_text_address (CORE_ADDR val)
+{
+ return val & ~1;
+}
+
+/* Immediately after a function call, return the saved pc. Can't
+ always go through the frames for this because on some machines the
+ new frame is not set up until the new function executes some
+ instructions. */
+
+static CORE_ADDR
+arm_saved_pc_after_call (struct frame_info *frame)
+{
+ return ADDR_BITS_REMOVE (read_register (ARM_LR_REGNUM));
+}
+
+/* Determine whether the function invocation represented by FI has a
+ frame on the stack associated with it. If it does return zero,
+ otherwise return 1. */
+
+static int
+arm_frameless_function_invocation (struct frame_info *fi)
+{
+ CORE_ADDR func_start, after_prologue;
+ int frameless;
+
+ /* Sometimes we have functions that do a little setup (like saving the
+ vN registers with the stmdb instruction, but DO NOT set up a frame.
+ The symbol table will report this as a prologue. However, it is
+ important not to try to parse these partial frames as frames, or we
+ will get really confused.
+
+ So I will demand 3 instructions between the start & end of the
+ prologue before I call it a real prologue, i.e. at least
+ mov ip, sp,
+ stmdb sp!, {}
+ sub sp, ip, #4. */
+
+ func_start = (get_pc_function_start ((fi)->pc) + FUNCTION_START_OFFSET);
+ after_prologue = SKIP_PROLOGUE (func_start);
+
+ /* There are some frameless functions whose first two instructions
+ follow the standard APCS form, in which case after_prologue will
+ be func_start + 8. */
+
+ frameless = (after_prologue < func_start + 12);
+ return frameless;
+}
+
+/* The address of the arguments in the frame. */
+static CORE_ADDR
+arm_frame_args_address (struct frame_info *fi)
+{
+ return fi->frame;
+}
+
+/* The address of the local variables in the frame. */
+static CORE_ADDR
+arm_frame_locals_address (struct frame_info *fi)
+{
+ return fi->frame;
+}
+
+/* The number of arguments being passed in the frame. */
+static int
+arm_frame_num_args (struct frame_info *fi)
+{
+ /* We have no way of knowing. */
+ return -1;
+}
+
+/* A typical Thumb prologue looks like this:
+ push {r7, lr}
+ add sp, sp, #-28
+ add r7, sp, #12
+ Sometimes the latter instruction may be replaced by:
+ mov r7, sp
+
+ or like this:
+ push {r7, lr}
+ mov r7, sp
+ sub sp, #12
+
+ or, on tpcs, like this:
+ sub sp,#16
+ push {r7, lr}
+ (many instructions)
+ mov r7, sp
+ sub sp, #12
+
+ There is always one instruction of three classes:
+ 1 - push
+ 2 - setting of r7
+ 3 - adjusting of sp
+
+ When we have found at least one of each class we are done with the prolog.
+ Note that the "sub sp, #NN" before the push does not count.
+ */
+
+static CORE_ADDR
+thumb_skip_prologue (CORE_ADDR pc, CORE_ADDR func_end)
+{
+ CORE_ADDR current_pc;
+ /* findmask:
+ bit 0 - push { rlist }
+ bit 1 - mov r7, sp OR add r7, sp, #imm (setting of r7)
+ bit 2 - sub sp, #simm OR add sp, #simm (adjusting of sp)
+ */
+ int findmask = 0;
+
+ for (current_pc = pc;
+ current_pc + 2 < func_end && current_pc < pc + 40;
+ current_pc += 2)
+ {
+ unsigned short insn = read_memory_unsigned_integer (current_pc, 2);
+
+ if ((insn & 0xfe00) == 0xb400) /* push { rlist } */
+ {
+ findmask |= 1; /* push found */
+ }
+ else if ((insn & 0xff00) == 0xb000) /* add sp, #simm OR
+ sub sp, #simm */
+ {
+ if ((findmask & 1) == 0) /* before push ? */
+ continue;
+ else
+ findmask |= 4; /* add/sub sp found */
+ }
+ else if ((insn & 0xff00) == 0xaf00) /* add r7, sp, #imm */
+ {
+ findmask |= 2; /* setting of r7 found */
+ }
+ else if (insn == 0x466f) /* mov r7, sp */
+ {
+ findmask |= 2; /* setting of r7 found */
+ }
+ else if (findmask == (4+2+1))
+ {
+ /* We have found one of each type of prologue instruction */
+ break;
+ }
+ else
+ /* Something in the prolog that we don't care about or some
+ instruction from outside the prolog scheduled here for
+ optimization. */
+ continue;
+ }
+
+ return current_pc;
+}
+
+/* Advance the PC across any function entry prologue instructions to
+ reach some "real" code.
+
+ The APCS (ARM Procedure Call Standard) defines the following
+ prologue:
+
+ mov ip, sp
+ [stmfd sp!, {a1,a2,a3,a4}]
+ stmfd sp!, {...,fp,ip,lr,pc}
+ [stfe f7, [sp, #-12]!]
+ [stfe f6, [sp, #-12]!]
+ [stfe f5, [sp, #-12]!]
+ [stfe f4, [sp, #-12]!]
+ sub fp, ip, #nn @@ nn == 20 or 4 depending on second insn */
+
+static CORE_ADDR
+arm_skip_prologue (CORE_ADDR pc)
+{
+ unsigned long inst;
+ CORE_ADDR skip_pc;
+ CORE_ADDR func_addr, func_end = 0;
+ char *func_name;
+ struct symtab_and_line sal;
+
+ /* If we're in a dummy frame, don't even try to skip the prologue. */
+ if (USE_GENERIC_DUMMY_FRAMES
+ && PC_IN_CALL_DUMMY (pc, 0, 0))
+ return pc;
+
+ /* See what the symbol table says. */
+
+ if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
+ {
+ struct symbol *sym;
+
+ /* Found a function. */
+ sym = lookup_symbol (func_name, NULL, VAR_NAMESPACE, NULL, NULL);
+ if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
+ {
+ /* Don't use this trick for assembly source files. */
+ sal = find_pc_line (func_addr, 0);
+ if ((sal.line != 0) && (sal.end < func_end))
+ return sal.end;
+ }
+ }
+
+ /* Check if this is Thumb code. */
+ if (arm_pc_is_thumb (pc))
+ return thumb_skip_prologue (pc, func_end);
+
+ /* Can't find the prologue end in the symbol table, try it the hard way
+ by disassembling the instructions. */
+
+ /* Like arm_scan_prologue, stop no later than pc + 64. */
+ if (func_end == 0 || func_end > pc + 64)
+ func_end = pc + 64;
+
+ for (skip_pc = pc; skip_pc < func_end; skip_pc += 4)
+ {
+ inst = read_memory_integer (skip_pc, 4);
+
+ /* "mov ip, sp" is no longer a required part of the prologue. */
+ if (inst == 0xe1a0c00d) /* mov ip, sp */
+ continue;
+
+ /* Some prologues begin with "str lr, [sp, #-4]!". */
+ if (inst == 0xe52de004) /* str lr, [sp, #-4]! */
+ continue;
+
+ if ((inst & 0xfffffff0) == 0xe92d0000) /* stmfd sp!,{a1,a2,a3,a4} */
+ continue;
+
+ if ((inst & 0xfffff800) == 0xe92dd800) /* stmfd sp!,{fp,ip,lr,pc} */
+ continue;
+
+ /* Any insns after this point may float into the code, if it makes
+ for better instruction scheduling, so we skip them only if we
+ find them, but still consider the function to be frame-ful. */
+
+ /* We may have either one sfmfd instruction here, or several stfe
+ insns, depending on the version of floating point code we
+ support. */
+ if ((inst & 0xffbf0fff) == 0xec2d0200) /* sfmfd fn, <cnt>, [sp]! */
+ continue;
+
+ if ((inst & 0xffff8fff) == 0xed6d0103) /* stfe fn, [sp, #-12]! */
+ continue;
+
+ if ((inst & 0xfffff000) == 0xe24cb000) /* sub fp, ip, #nn */
+ continue;
+
+ if ((inst & 0xfffff000) == 0xe24dd000) /* sub sp, sp, #nn */
+ continue;
+
+ if ((inst & 0xffffc000) == 0xe54b0000 || /* strb r(0123),[r11,#-nn] */
+ (inst & 0xffffc0f0) == 0xe14b00b0 || /* strh r(0123),[r11,#-nn] */
+ (inst & 0xffffc000) == 0xe50b0000) /* str r(0123),[r11,#-nn] */
+ continue;
+
+ if ((inst & 0xffffc000) == 0xe5cd0000 || /* strb r(0123),[sp,#nn] */
+ (inst & 0xffffc0f0) == 0xe1cd00b0 || /* strh r(0123),[sp,#nn] */
+ (inst & 0xffffc000) == 0xe58d0000) /* str r(0123),[sp,#nn] */
+ continue;
+
+ /* Un-recognized instruction; stop scanning. */
+ break;
+ }
+
+ return skip_pc; /* End of prologue */
+}
+
+/* *INDENT-OFF* */
+/* Function: thumb_scan_prologue (helper function for arm_scan_prologue)
+ This function decodes a Thumb function prologue to determine:
+ 1) the size of the stack frame
+ 2) which registers are saved on it
+ 3) the offsets of saved regs
+ 4) the offset from the stack pointer to the frame pointer
+ This information is stored in the "extra" fields of the frame_info.
+
+ A typical Thumb function prologue would create this stack frame
+ (offsets relative to FP)
+ old SP -> 24 stack parameters
+ 20 LR
+ 16 R7
+ R7 -> 0 local variables (16 bytes)
+ SP -> -12 additional stack space (12 bytes)
+ The frame size would thus be 36 bytes, and the frame offset would be
+ 12 bytes. The frame register is R7.
+
+ The comments for thumb_skip_prolog() describe the algorithm we use
+ to detect the end of the prolog. */
+/* *INDENT-ON* */
+
+static void
+thumb_scan_prologue (struct frame_info *fi)
+{
+ CORE_ADDR prologue_start;
+ CORE_ADDR prologue_end;
+ CORE_ADDR current_pc;
+ /* Which register has been copied to register n? */
+ int saved_reg[16];
+ /* findmask:
+ bit 0 - push { rlist }
+ bit 1 - mov r7, sp OR add r7, sp, #imm (setting of r7)
+ bit 2 - sub sp, #simm OR add sp, #simm (adjusting of sp)
+ */
+ int findmask = 0;
+ int i;
+
+ /* Don't try to scan dummy frames. */
+ if (USE_GENERIC_DUMMY_FRAMES
+ && fi != NULL
+ && PC_IN_CALL_DUMMY (fi->pc, 0, 0))
+ return;
+
+ if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end))
+ {
+ struct symtab_and_line sal = find_pc_line (prologue_start, 0);
+
+ if (sal.line == 0) /* no line info, use current PC */
+ prologue_end = fi->pc;
+ else if (sal.end < prologue_end) /* next line begins after fn end */
+ prologue_end = sal.end; /* (probably means no prologue) */
+ }
+ else
+ /* We're in the boondocks: allow for
+ 16 pushes, an add, and "mv fp,sp". */
+ prologue_end = prologue_start + 40;
+
+ prologue_end = min (prologue_end, fi->pc);
+
+ /* Initialize the saved register map. When register H is copied to
+ register L, we will put H in saved_reg[L]. */
+ for (i = 0; i < 16; i++)
+ saved_reg[i] = i;
+
+ /* Search the prologue looking for instructions that set up the
+ frame pointer, adjust the stack pointer, and save registers.
+ Do this until all basic prolog instructions are found. */
+
+ fi->extra_info->framesize = 0;
+ for (current_pc = prologue_start;
+ (current_pc < prologue_end) && ((findmask & 7) != 7);
+ current_pc += 2)
+ {
+ unsigned short insn;
+ int regno;
+ int offset;
+
+ insn = read_memory_unsigned_integer (current_pc, 2);
+
+ if ((insn & 0xfe00) == 0xb400) /* push { rlist } */
+ {
+ int mask;
+ findmask |= 1; /* push found */
+ /* Bits 0-7 contain a mask for registers R0-R7. Bit 8 says
+ whether to save LR (R14). */
+ mask = (insn & 0xff) | ((insn & 0x100) << 6);
+
+ /* Calculate offsets of saved R0-R7 and LR. */
+ for (regno = ARM_LR_REGNUM; regno >= 0; regno--)
+ if (mask & (1 << regno))
+ {
+ fi->extra_info->framesize += 4;
+ fi->saved_regs[saved_reg[regno]] =
+ -(fi->extra_info->framesize);
+ /* Reset saved register map. */
+ saved_reg[regno] = regno;
+ }
+ }
+ else if ((insn & 0xff00) == 0xb000) /* add sp, #simm OR
+ sub sp, #simm */
+ {
+ if ((findmask & 1) == 0) /* before push? */
+ continue;
+ else
+ findmask |= 4; /* add/sub sp found */
+
+ offset = (insn & 0x7f) << 2; /* get scaled offset */
+ if (insn & 0x80) /* is it signed? (==subtracting) */
+ {
+ fi->extra_info->frameoffset += offset;
+ offset = -offset;
+ }
+ fi->extra_info->framesize -= offset;
+ }
+ else if ((insn & 0xff00) == 0xaf00) /* add r7, sp, #imm */
+ {
+ findmask |= 2; /* setting of r7 found */
+ fi->extra_info->framereg = THUMB_FP_REGNUM;
+ /* get scaled offset */
+ fi->extra_info->frameoffset = (insn & 0xff) << 2;
+ }
+ else if (insn == 0x466f) /* mov r7, sp */
+ {
+ findmask |= 2; /* setting of r7 found */
+ fi->extra_info->framereg = THUMB_FP_REGNUM;
+ fi->extra_info->frameoffset = 0;
+ saved_reg[THUMB_FP_REGNUM] = ARM_SP_REGNUM;
+ }
+ else if ((insn & 0xffc0) == 0x4640) /* mov r0-r7, r8-r15 */
+ {
+ int lo_reg = insn & 7; /* dest. register (r0-r7) */
+ int hi_reg = ((insn >> 3) & 7) + 8; /* source register (r8-15) */
+ saved_reg[lo_reg] = hi_reg; /* remember hi reg was saved */
+ }
+ else
+ /* Something in the prolog that we don't care about or some
+ instruction from outside the prolog scheduled here for
+ optimization. */
+ continue;
+ }
+}
+
+/* Check if prologue for this frame's PC has already been scanned. If
+ it has, copy the relevant information about that prologue and
+ return non-zero. Otherwise do not copy anything and return zero.
+
+ The information saved in the cache includes:
+ * the frame register number;
+ * the size of the stack frame;
+ * the offsets of saved regs (relative to the old SP); and
+ * the offset from the stack pointer to the frame pointer
+
+ The cache contains only one entry, since this is adequate for the
+ typical sequence of prologue scan requests we get. When performing
+ a backtrace, GDB will usually ask to scan the same function twice
+ in a row (once to get the frame chain, and once to fill in the
+ extra frame information). */
+
+static struct frame_info prologue_cache;
+
+static int
+check_prologue_cache (struct frame_info *fi)
+{
+ int i;
+
+ if (fi->pc == prologue_cache.pc)
+ {
+ fi->extra_info->framereg = prologue_cache.extra_info->framereg;
+ fi->extra_info->framesize = prologue_cache.extra_info->framesize;
+ fi->extra_info->frameoffset = prologue_cache.extra_info->frameoffset;
+ for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+ fi->saved_regs[i] = prologue_cache.saved_regs[i];
+ return 1;
+ }
+ else
+ return 0;
+}
+
+
+/* Copy the prologue information from fi to the prologue cache. */
+
+static void
+save_prologue_cache (struct frame_info *fi)
+{
+ int i;
+
+ prologue_cache.pc = fi->pc;
+ prologue_cache.extra_info->framereg = fi->extra_info->framereg;
+ prologue_cache.extra_info->framesize = fi->extra_info->framesize;
+ prologue_cache.extra_info->frameoffset = fi->extra_info->frameoffset;
+
+ for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+ prologue_cache.saved_regs[i] = fi->saved_regs[i];
+}
+
+
+/* This function decodes an ARM function prologue to determine:
+ 1) the size of the stack frame
+ 2) which registers are saved on it
+ 3) the offsets of saved regs
+ 4) the offset from the stack pointer to the frame pointer
+ This information is stored in the "extra" fields of the frame_info.
+
+ There are two basic forms for the ARM prologue. The fixed argument
+ function call will look like:
+
+ mov ip, sp
+ stmfd sp!, {fp, ip, lr, pc}
+ sub fp, ip, #4
+ [sub sp, sp, #4]
+
+ Which would create this stack frame (offsets relative to FP):
+ IP -> 4 (caller's stack)
+ FP -> 0 PC (points to address of stmfd instruction + 8 in callee)
+ -4 LR (return address in caller)
+ -8 IP (copy of caller's SP)
+ -12 FP (caller's FP)
+ SP -> -28 Local variables
+
+ The frame size would thus be 32 bytes, and the frame offset would be
+ 28 bytes. The stmfd call can also save any of the vN registers it
+ plans to use, which increases the frame size accordingly.
+
+ Note: The stored PC is 8 off of the STMFD instruction that stored it
+ because the ARM Store instructions always store PC + 8 when you read
+ the PC register.
+
+ A variable argument function call will look like:
+
+ mov ip, sp
+ stmfd sp!, {a1, a2, a3, a4}
+ stmfd sp!, {fp, ip, lr, pc}
+ sub fp, ip, #20
+
+ Which would create this stack frame (offsets relative to FP):
+ IP -> 20 (caller's stack)
+ 16 A4
+ 12 A3
+ 8 A2
+ 4 A1
+ FP -> 0 PC (points to address of stmfd instruction + 8 in callee)
+ -4 LR (return address in caller)
+ -8 IP (copy of caller's SP)
+ -12 FP (caller's FP)
+ SP -> -28 Local variables
+
+ The frame size would thus be 48 bytes, and the frame offset would be
+ 28 bytes.
+
+ There is another potential complication, which is that the optimizer
+ will try to separate the store of fp in the "stmfd" instruction from
+ the "sub fp, ip, #NN" instruction. Almost anything can be there, so
+ we just key on the stmfd, and then scan for the "sub fp, ip, #NN"...
+
+ Also, note, the original version of the ARM toolchain claimed that there
+ should be an
+
+ instruction at the end of the prologue. I have never seen GCC produce
+ this, and the ARM docs don't mention it. We still test for it below in
+ case it happens...
+
+ */
+
+static void
+arm_scan_prologue (struct frame_info *fi)
+{
+ int regno, sp_offset, fp_offset;
+ LONGEST return_value;
+ CORE_ADDR prologue_start, prologue_end, current_pc;
+
+ /* Check if this function is already in the cache of frame information. */
+ if (check_prologue_cache (fi))
+ return;
+
+ /* Assume there is no frame until proven otherwise. */
+ fi->extra_info->framereg = ARM_SP_REGNUM;
+ fi->extra_info->framesize = 0;
+ fi->extra_info->frameoffset = 0;
+
+ /* Check for Thumb prologue. */
+ if (arm_pc_is_thumb (fi->pc))
+ {
+ thumb_scan_prologue (fi);
+ save_prologue_cache (fi);
+ return;
+ }
+
+ /* Find the function prologue. If we can't find the function in
+ the symbol table, peek in the stack frame to find the PC. */
+ if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end))
+ {
+ /* One way to find the end of the prologue (which works well
+ for unoptimized code) is to do the following:
+
+ struct symtab_and_line sal = find_pc_line (prologue_start, 0);
+
+ if (sal.line == 0)
+ prologue_end = fi->pc;
+ else if (sal.end < prologue_end)
+ prologue_end = sal.end;
+
+ This mechanism is very accurate so long as the optimizer
+ doesn't move any instructions from the function body into the
+ prologue. If this happens, sal.end will be the last
+ instruction in the first hunk of prologue code just before
+ the first instruction that the scheduler has moved from
+ the body to the prologue.
+
+ In order to make sure that we scan all of the prologue
+ instructions, we use a slightly less accurate mechanism which
+ may scan more than necessary. To help compensate for this
+ lack of accuracy, the prologue scanning loop below contains
+ several clauses which'll cause the loop to terminate early if
+ an implausible prologue instruction is encountered.
+
+ The expression
+
+ prologue_start + 64
+
+ is a suitable endpoint since it accounts for the largest
+ possible prologue plus up to five instructions inserted by
+ the scheduler. */
+
+ if (prologue_end > prologue_start + 64)
+ {
+ prologue_end = prologue_start + 64; /* See above. */
+ }
+ }
+ else
+ {
+ /* Get address of the stmfd in the prologue of the callee;
+ the saved PC is the address of the stmfd + 8. */
+ if (!safe_read_memory_integer (fi->frame, 4, &return_value))
+ return;
+ else
+ {
+ prologue_start = ADDR_BITS_REMOVE (return_value) - 8;
+ prologue_end = prologue_start + 64; /* See above. */
+ }
+ }
+
+ /* Now search the prologue looking for instructions that set up the
+ frame pointer, adjust the stack pointer, and save registers.
+
+ Be careful, however, and if it doesn't look like a prologue,
+ don't try to scan it. If, for instance, a frameless function
+ begins with stmfd sp!, then we will tell ourselves there is
+ a frame, which will confuse stack traceback, as well as "finish"
+ and other operations that rely on a knowledge of the stack
+ traceback.
+
+ In the APCS, the prologue should start with "mov ip, sp" so
+ if we don't see this as the first insn, we will stop.
+
+ [Note: This doesn't seem to be true any longer, so it's now an
+ optional part of the prologue. - Kevin Buettner, 2001-11-20]
+
+ [Note further: The "mov ip,sp" only seems to be missing in
+ frameless functions at optimization level "-O2" or above,
+ in which case it is often (but not always) replaced by
+ "str lr, [sp, #-4]!". - Michael Snyder, 2002-04-23] */
+
+ sp_offset = fp_offset = 0;
+
+ for (current_pc = prologue_start;
+ current_pc < prologue_end;
+ current_pc += 4)
+ {
+ unsigned int insn = read_memory_unsigned_integer (current_pc, 4);
+
+ if (insn == 0xe1a0c00d) /* mov ip, sp */
+ {
+ continue;
+ }
+ else if (insn == 0xe52de004) /* str lr, [sp, #-4]! */
+ {
+ /* Function is frameless: extra_info defaults OK? */
+ continue;
+ }
+ else if ((insn & 0xffff0000) == 0xe92d0000)
+ /* stmfd sp!, {..., fp, ip, lr, pc}
+ or
+ stmfd sp!, {a1, a2, a3, a4} */
+ {
+ int mask = insn & 0xffff;
+
+ /* Calculate offsets of saved registers. */
+ for (regno = ARM_PC_REGNUM; regno >= 0; regno--)
+ if (mask & (1 << regno))
+ {
+ sp_offset -= 4;
+ fi->saved_regs[regno] = sp_offset;
+ }
+ }
+ else if ((insn & 0xffffc000) == 0xe54b0000 || /* strb rx,[r11,#-n] */
+ (insn & 0xffffc0f0) == 0xe14b00b0 || /* strh rx,[r11,#-n] */
+ (insn & 0xffffc000) == 0xe50b0000) /* str rx,[r11,#-n] */
+ {
+ /* No need to add this to saved_regs -- it's just an arg reg. */
+ continue;
+ }
+ else if ((insn & 0xffffc000) == 0xe5cd0000 || /* strb rx,[sp,#n] */
+ (insn & 0xffffc0f0) == 0xe1cd00b0 || /* strh rx,[sp,#n] */
+ (insn & 0xffffc000) == 0xe58d0000) /* str rx,[sp,#n] */
+ {
+ /* No need to add this to saved_regs -- it's just an arg reg. */
+ continue;
+ }
+ else if ((insn & 0xfffff000) == 0xe24cb000) /* sub fp, ip #n */
+ {
+ unsigned imm = insn & 0xff; /* immediate value */
+ unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
+ imm = (imm >> rot) | (imm << (32 - rot));
+ fp_offset = -imm;
+ fi->extra_info->framereg = ARM_FP_REGNUM;
+ }
+ else if ((insn & 0xfffff000) == 0xe24dd000) /* sub sp, sp #n */
+ {
+ unsigned imm = insn & 0xff; /* immediate value */
+ unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
+ imm = (imm >> rot) | (imm << (32 - rot));
+ sp_offset -= imm;
+ }
+ else if ((insn & 0xffff7fff) == 0xed6d0103) /* stfe f?, [sp, -#c]! */
+ {
+ sp_offset -= 12;
+ regno = ARM_F0_REGNUM + ((insn >> 12) & 0x07);
+ fi->saved_regs[regno] = sp_offset;
+ }
+ else if ((insn & 0xffbf0fff) == 0xec2d0200) /* sfmfd f0, 4, [sp!] */
+ {
+ int n_saved_fp_regs;
+ unsigned int fp_start_reg, fp_bound_reg;
+
+ if ((insn & 0x800) == 0x800) /* N0 is set */
+ {
+ if ((insn & 0x40000) == 0x40000) /* N1 is set */
+ n_saved_fp_regs = 3;
+ else
+ n_saved_fp_regs = 1;
+ }
+ else
+ {
+ if ((insn & 0x40000) == 0x40000) /* N1 is set */
+ n_saved_fp_regs = 2;
+ else
+ n_saved_fp_regs = 4;
+ }
+
+ fp_start_reg = ARM_F0_REGNUM + ((insn >> 12) & 0x7);
+ fp_bound_reg = fp_start_reg + n_saved_fp_regs;
+ for (; fp_start_reg < fp_bound_reg; fp_start_reg++)
+ {
+ sp_offset -= 12;
+ fi->saved_regs[fp_start_reg++] = sp_offset;
+ }
+ }
+ else if ((insn & 0xf0000000) != 0xe0000000)
+ break; /* Condition not true, exit early */
+ else if ((insn & 0xfe200000) == 0xe8200000) /* ldm? */
+ break; /* Don't scan past a block load */
+ else
+ /* The optimizer might shove anything into the prologue,
+ so we just skip what we don't recognize. */
+ continue;
+ }
+
+ /* The frame size is just the negative of the offset (from the
+ original SP) of the last thing thing we pushed on the stack.
+ The frame offset is [new FP] - [new SP]. */
+ fi->extra_info->framesize = -sp_offset;
+ if (fi->extra_info->framereg == ARM_FP_REGNUM)
+ fi->extra_info->frameoffset = fp_offset - sp_offset;
+ else
+ fi->extra_info->frameoffset = 0;
+
+ save_prologue_cache (fi);
+}
+
+/* Find REGNUM on the stack. Otherwise, it's in an active register.
+ One thing we might want to do here is to check REGNUM against the
+ clobber mask, and somehow flag it as invalid if it isn't saved on
+ the stack somewhere. This would provide a graceful failure mode
+ when trying to get the value of caller-saves registers for an inner
+ frame. */
+
+static CORE_ADDR
+arm_find_callers_reg (struct frame_info *fi, int regnum)
+{
+ /* NOTE: cagney/2002-05-03: This function really shouldn't be
+ needed. Instead the (still being written) register unwind
+ function could be called directly. */
+ for (; fi; fi = fi->next)
+ {
+ if (USE_GENERIC_DUMMY_FRAMES
+ && PC_IN_CALL_DUMMY (fi->pc, 0, 0))
+ {
+ return generic_read_register_dummy (fi->pc, fi->frame, regnum);
+ }
+ else if (fi->saved_regs[regnum] != 0)
+ {
+ /* NOTE: cagney/2002-05-03: This would normally need to
+ handle ARM_SP_REGNUM as a special case as, according to
+ the frame.h comments, saved_regs[SP_REGNUM] contains the
+ SP value not its address. It appears that the ARM isn't
+ doing this though. */
+ return read_memory_integer (fi->saved_regs[regnum],
+ REGISTER_RAW_SIZE (regnum));
+ }
+ }
+ return read_register (regnum);
+}
+/* Function: frame_chain Given a GDB frame, determine the address of
+ the calling function's frame. This will be used to create a new
+ GDB frame struct, and then INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC
+ will be called for the new frame. For ARM, we save the frame size
+ when we initialize the frame_info. */
+
+static CORE_ADDR
+arm_frame_chain (struct frame_info *fi)
+{
+ CORE_ADDR caller_pc;
+ int framereg = fi->extra_info->framereg;
+
+ if (USE_GENERIC_DUMMY_FRAMES
+ && PC_IN_CALL_DUMMY (fi->pc, 0, 0))
+ /* A generic call dummy's frame is the same as caller's. */
+ return fi->frame;
+
+ if (fi->pc < LOWEST_PC)
+ return 0;
+
+ /* If the caller is the startup code, we're at the end of the chain. */
+ caller_pc = FRAME_SAVED_PC (fi);
+
+ /* If the caller is Thumb and the caller is ARM, or vice versa,
+ the frame register of the caller is different from ours.
+ So we must scan the prologue of the caller to determine its
+ frame register number. */
+ /* XXX Fixme, we should try to do this without creating a temporary
+ caller_fi. */
+ if (arm_pc_is_thumb (caller_pc) != arm_pc_is_thumb (fi->pc))
+ {
+ struct frame_info caller_fi;
+ struct cleanup *old_chain;
+
+ /* Create a temporary frame suitable for scanning the caller's
+ prologue. (Ugh.) */
+ memset (&caller_fi, 0, sizeof (caller_fi));
+ caller_fi.extra_info = (struct frame_extra_info *)
+ xcalloc (1, sizeof (struct frame_extra_info));
+ old_chain = make_cleanup (xfree, caller_fi.extra_info);
+ caller_fi.saved_regs = (CORE_ADDR *)
+ xcalloc (1, SIZEOF_FRAME_SAVED_REGS);
+ make_cleanup (xfree, caller_fi.saved_regs);
+
+ /* Now, scan the prologue and obtain the frame register. */
+ caller_fi.pc = caller_pc;
+ arm_scan_prologue (&caller_fi);
+ framereg = caller_fi.extra_info->framereg;
+
+ /* Deallocate the storage associated with the temporary frame
+ created above. */
+ do_cleanups (old_chain);
+ }
+
+ /* If the caller used a frame register, return its value.
+ Otherwise, return the caller's stack pointer. */
+ if (framereg == ARM_FP_REGNUM || framereg == THUMB_FP_REGNUM)
+ return arm_find_callers_reg (fi, framereg);
+ else
+ return fi->frame + fi->extra_info->framesize;
+}
+
+/* This function actually figures out the frame address for a given pc
+ and sp. This is tricky because we sometimes don't use an explicit
+ frame pointer, and the previous stack pointer isn't necessarily
+ recorded on the stack. The only reliable way to get this info is
+ to examine the prologue. FROMLEAF is a little confusing, it means
+ this is the next frame up the chain AFTER a frameless function. If
+ this is true, then the frame value for this frame is still in the
+ fp register. */
+
+static void
+arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ int reg;
+ CORE_ADDR sp;
+
+ if (fi->saved_regs == NULL)
+ frame_saved_regs_zalloc (fi);
+
+ fi->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+
+ fi->extra_info->framesize = 0;
+ fi->extra_info->frameoffset = 0;
+ fi->extra_info->framereg = 0;
+
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ memset (fi->saved_regs, '\000', sizeof fi->saved_regs);
+
+ /* Compute stack pointer for this frame. We use this value for both
+ the sigtramp and call dummy cases. */
+ if (!fi->next)
+ sp = read_sp();
+ else if (USE_GENERIC_DUMMY_FRAMES
+ && PC_IN_CALL_DUMMY (fi->next->pc, 0, 0))
+ /* For generic dummy frames, pull the value direct from the frame.
+ Having an unwind function to do this would be nice. */
+ sp = generic_read_register_dummy (fi->next->pc, fi->next->frame,
+ ARM_SP_REGNUM);
+ else
+ sp = (fi->next->frame - fi->next->extra_info->frameoffset
+ + fi->next->extra_info->framesize);
+
+ /* Determine whether or not we're in a sigtramp frame.
+ Unfortunately, it isn't sufficient to test
+ fi->signal_handler_caller because this value is sometimes set
+ after invoking INIT_EXTRA_FRAME_INFO. So we test *both*
+ fi->signal_handler_caller and PC_IN_SIGTRAMP to determine if we
+ need to use the sigcontext addresses for the saved registers.
+
+ Note: If an ARM PC_IN_SIGTRAMP method ever needs to compare
+ against the name of the function, the code below will have to be
+ changed to first fetch the name of the function and then pass
+ this name to PC_IN_SIGTRAMP. */
+
+ if (SIGCONTEXT_REGISTER_ADDRESS_P ()
+ && (fi->signal_handler_caller || PC_IN_SIGTRAMP (fi->pc, (char *)0)))
+ {
+ for (reg = 0; reg < NUM_REGS; reg++)
+ fi->saved_regs[reg] = SIGCONTEXT_REGISTER_ADDRESS (sp, fi->pc, reg);
+
+ /* FIXME: What about thumb mode? */
+ fi->extra_info->framereg = ARM_SP_REGNUM;
+ fi->frame =
+ read_memory_integer (fi->saved_regs[fi->extra_info->framereg],
+ REGISTER_RAW_SIZE (fi->extra_info->framereg));
+ fi->extra_info->framesize = 0;
+ fi->extra_info->frameoffset = 0;
+
+ }
+ else if (PC_IN_CALL_DUMMY (fi->pc, sp, fi->frame))
+ {
+ CORE_ADDR rp;
+ CORE_ADDR callers_sp;
+
+ /* Set rp point at the high end of the saved registers. */
+ rp = fi->frame - REGISTER_SIZE;
+
+ /* Fill in addresses of saved registers. */
+ fi->saved_regs[ARM_PS_REGNUM] = rp;
+ rp -= REGISTER_RAW_SIZE (ARM_PS_REGNUM);
+ for (reg = ARM_PC_REGNUM; reg >= 0; reg--)
+ {
+ fi->saved_regs[reg] = rp;
+ rp -= REGISTER_RAW_SIZE (reg);
+ }
+
+ callers_sp = read_memory_integer (fi->saved_regs[ARM_SP_REGNUM],
+ REGISTER_RAW_SIZE (ARM_SP_REGNUM));
+ fi->extra_info->framereg = ARM_FP_REGNUM;
+ fi->extra_info->framesize = callers_sp - sp;
+ fi->extra_info->frameoffset = fi->frame - sp;
+ }
+ else
+ {
+ arm_scan_prologue (fi);
+
+ if (!fi->next)
+ /* This is the innermost frame? */
+ fi->frame = read_register (fi->extra_info->framereg);
+ else if (USE_GENERIC_DUMMY_FRAMES
+ && PC_IN_CALL_DUMMY (fi->next->pc, 0, 0))
+ /* Next inner most frame is a dummy, just grab its frame.
+ Dummy frames always have the same FP as their caller. */
+ fi->frame = fi->next->frame;
+ else if (fi->extra_info->framereg == ARM_FP_REGNUM
+ || fi->extra_info->framereg == THUMB_FP_REGNUM)
+ {
+ /* not the innermost frame */
+ /* If we have an FP, the callee saved it. */
+ if (fi->next->saved_regs[fi->extra_info->framereg] != 0)
+ fi->frame =
+ read_memory_integer (fi->next
+ ->saved_regs[fi->extra_info->framereg], 4);
+ else if (fromleaf)
+ /* If we were called by a frameless fn. then our frame is
+ still in the frame pointer register on the board... */
+ fi->frame = read_fp ();
+ }
+
+ /* Calculate actual addresses of saved registers using offsets
+ determined by arm_scan_prologue. */
+ for (reg = 0; reg < NUM_REGS; reg++)
+ if (fi->saved_regs[reg] != 0)
+ fi->saved_regs[reg] += (fi->frame + fi->extra_info->framesize
+ - fi->extra_info->frameoffset);
+ }
+}
+
+
+/* Find the caller of this frame. We do this by seeing if ARM_LR_REGNUM
+ is saved in the stack anywhere, otherwise we get it from the
+ registers.
+
+ The old definition of this function was a macro:
+ #define FRAME_SAVED_PC(FRAME) \
+ ADDR_BITS_REMOVE (read_memory_integer ((FRAME)->frame - 4, 4)) */
+
+static CORE_ADDR
+arm_frame_saved_pc (struct frame_info *fi)
+{
+ /* If a dummy frame, pull the PC out of the frame's register buffer. */
+ if (USE_GENERIC_DUMMY_FRAMES
+ && PC_IN_CALL_DUMMY (fi->pc, 0, 0))
+ return generic_read_register_dummy (fi->pc, fi->frame, ARM_PC_REGNUM);
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame - fi->extra_info->frameoffset,
+ fi->frame))
+ {
+ return read_memory_integer (fi->saved_regs[ARM_PC_REGNUM],
+ REGISTER_RAW_SIZE (ARM_PC_REGNUM));
+ }
+ else
+ {
+ CORE_ADDR pc = arm_find_callers_reg (fi, ARM_LR_REGNUM);
+ return IS_THUMB_ADDR (pc) ? UNMAKE_THUMB_ADDR (pc) : pc;
+ }
+}
+
+/* Return the frame address. On ARM, it is R11; on Thumb it is R7.
+ Examine the Program Status Register to decide which state we're in. */
+
+static CORE_ADDR
+arm_read_fp (void)
+{
+ if (read_register (ARM_PS_REGNUM) & 0x20) /* Bit 5 is Thumb state bit */
+ return read_register (THUMB_FP_REGNUM); /* R7 if Thumb */
+ else
+ return read_register (ARM_FP_REGNUM); /* R11 if ARM */
+}
+
+/* Store into a struct frame_saved_regs the addresses of the saved
+ registers of frame described by FRAME_INFO. This includes special
+ registers such as PC and FP saved in special ways in the stack
+ frame. SP is even more special: the address we return for it IS
+ the sp for the next frame. */
+
+static void
+arm_frame_init_saved_regs (struct frame_info *fip)
+{
+
+ if (fip->saved_regs)
+ return;
+
+ arm_init_extra_frame_info (0, fip);
+}
+
+/* Set the return address for a generic dummy frame. ARM uses the
+ entry point. */
+
+static CORE_ADDR
+arm_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ write_register (ARM_LR_REGNUM, CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+/* Push an empty stack frame, to record the current PC, etc. */
+
+static void
+arm_push_dummy_frame (void)
+{
+ CORE_ADDR old_sp = read_register (ARM_SP_REGNUM);
+ CORE_ADDR sp = old_sp;
+ CORE_ADDR fp, prologue_start;
+ int regnum;
+
+ /* Push the two dummy prologue instructions in reverse order,
+ so that they'll be in the correct low-to-high order in memory. */
+ /* sub fp, ip, #4 */
+ sp = push_word (sp, 0xe24cb004);
+ /* stmdb sp!, {r0-r10, fp, ip, lr, pc} */
+ prologue_start = sp = push_word (sp, 0xe92ddfff);
+
+ /* Push a pointer to the dummy prologue + 12, because when stm
+ instruction stores the PC, it stores the address of the stm
+ instruction itself plus 12. */
+ fp = sp = push_word (sp, prologue_start + 12);
+
+ /* Push the processor status. */
+ sp = push_word (sp, read_register (ARM_PS_REGNUM));
+
+ /* Push all 16 registers starting with r15. */
+ for (regnum = ARM_PC_REGNUM; regnum >= 0; regnum--)
+ sp = push_word (sp, read_register (regnum));
+
+ /* Update fp (for both Thumb and ARM) and sp. */
+ write_register (ARM_FP_REGNUM, fp);
+ write_register (THUMB_FP_REGNUM, fp);
+ write_register (ARM_SP_REGNUM, sp);
+}
+
+/* CALL_DUMMY_WORDS:
+ This sequence of words is the instructions
+
+ mov lr,pc
+ mov pc,r4
+ illegal
+
+ Note this is 12 bytes. */
+
+static LONGEST arm_call_dummy_words[] =
+{
+ 0xe1a0e00f, 0xe1a0f004, 0xe7ffdefe
+};
+
+/* Adjust the call_dummy_breakpoint_offset for the bp_call_dummy
+ breakpoint to the proper address in the call dummy, so that
+ `finish' after a stop in a call dummy works.
+
+ FIXME rearnsha 2002-02018: Tweeking current_gdbarch is not an
+ optimal solution, but the call to arm_fix_call_dummy is immediately
+ followed by a call to run_stack_dummy, which is the only function
+ where call_dummy_breakpoint_offset is actually used. */
+
+
+static void
+arm_set_call_dummy_breakpoint_offset (void)
+{
+ if (caller_is_thumb)
+ set_gdbarch_call_dummy_breakpoint_offset (current_gdbarch, 4);
+ else
+ set_gdbarch_call_dummy_breakpoint_offset (current_gdbarch, 8);
+}
+
+/* Fix up the call dummy, based on whether the processor is currently
+ in Thumb or ARM mode, and whether the target function is Thumb or
+ ARM. There are three different situations requiring three
+ different dummies:
+
+ * ARM calling ARM: uses the call dummy in tm-arm.h, which has already
+ been copied into the dummy parameter to this function.
+ * ARM calling Thumb: uses the call dummy in tm-arm.h, but with the
+ "mov pc,r4" instruction patched to be a "bx r4" instead.
+ * Thumb calling anything: uses the Thumb dummy defined below, which
+ works for calling both ARM and Thumb functions.
+
+ All three call dummies expect to receive the target function
+ address in R4, with the low bit set if it's a Thumb function. */
+
+static void
+arm_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+ struct value **args, struct type *type, int gcc_p)
+{
+ static short thumb_dummy[4] =
+ {
+ 0xf000, 0xf801, /* bl label */
+ 0xdf18, /* swi 24 */
+ 0x4720, /* label: bx r4 */
+ };
+ static unsigned long arm_bx_r4 = 0xe12fff14; /* bx r4 instruction */
+
+ /* Set flag indicating whether the current PC is in a Thumb function. */
+ caller_is_thumb = arm_pc_is_thumb (read_pc ());
+ arm_set_call_dummy_breakpoint_offset ();
+
+ /* If the target function is Thumb, set the low bit of the function
+ address. And if the CPU is currently in ARM mode, patch the
+ second instruction of call dummy to use a BX instruction to
+ switch to Thumb mode. */
+ target_is_thumb = arm_pc_is_thumb (fun);
+ if (target_is_thumb)
+ {
+ fun |= 1;
+ if (!caller_is_thumb)
+ store_unsigned_integer (dummy + 4, sizeof (arm_bx_r4), arm_bx_r4);
+ }
+
+ /* If the CPU is currently in Thumb mode, use the Thumb call dummy
+ instead of the ARM one that's already been copied. This will
+ work for both Thumb and ARM target functions. */
+ if (caller_is_thumb)
+ {
+ int i;
+ char *p = dummy;
+ int len = sizeof (thumb_dummy) / sizeof (thumb_dummy[0]);
+
+ for (i = 0; i < len; i++)
+ {
+ store_unsigned_integer (p, sizeof (thumb_dummy[0]), thumb_dummy[i]);
+ p += sizeof (thumb_dummy[0]);
+ }
+ }
+
+ /* Put the target address in r4; the call dummy will copy this to
+ the PC. */
+ write_register (4, fun);
+}
+
+/* Note: ScottB
+
+ This function does not support passing parameters using the FPA
+ variant of the APCS. It passes any floating point arguments in the
+ general registers and/or on the stack. */
+
+static CORE_ADDR
+arm_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ char *fp;
+ int argnum, argreg, nstack_size;
+
+ /* Walk through the list of args and determine how large a temporary
+ stack is required. Need to take care here as structs may be
+ passed on the stack, and we have to to push them. */
+ nstack_size = -4 * REGISTER_SIZE; /* Some arguments go into A1-A4. */
+ if (struct_return) /* The struct address goes in A1. */
+ nstack_size += REGISTER_SIZE;
+
+ /* Walk through the arguments and add their size to nstack_size. */
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ int len;
+ struct type *arg_type;
+
+ arg_type = check_typedef (VALUE_TYPE (args[argnum]));
+ len = TYPE_LENGTH (arg_type);
+
+ nstack_size += len;
+ }
+
+ /* Allocate room on the stack, and initialize our stack frame
+ pointer. */
+ fp = NULL;
+ if (nstack_size > 0)
+ {
+ sp -= nstack_size;
+ fp = (char *) sp;
+ }
+
+ /* Initialize the integer argument register pointer. */
+ argreg = ARM_A1_REGNUM;
+
+ /* The struct_return pointer occupies the first parameter passing
+ register. */
+ if (struct_return)
+ write_register (argreg++, struct_addr);
+
+ /* Process arguments from left to right. Store as many as allowed
+ in the parameter passing registers (A1-A4), and save the rest on
+ the temporary stack. */
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ int len;
+ char *val;
+ CORE_ADDR regval;
+ enum type_code typecode;
+ struct type *arg_type, *target_type;
+
+ arg_type = check_typedef (VALUE_TYPE (args[argnum]));
+ target_type = TYPE_TARGET_TYPE (arg_type);
+ len = TYPE_LENGTH (arg_type);
+ typecode = TYPE_CODE (arg_type);
+ val = (char *) VALUE_CONTENTS (args[argnum]);
+
+#if 1
+ /* I don't know why this code was disable. The only logical use
+ for a function pointer is to call that function, so setting
+ the mode bit is perfectly fine. FN */
+ /* If the argument is a pointer to a function, and it is a Thumb
+ function, set the low bit of the pointer. */
+ if (TYPE_CODE_PTR == typecode
+ && NULL != target_type
+ && TYPE_CODE_FUNC == TYPE_CODE (target_type))
+ {
+ CORE_ADDR regval = extract_address (val, len);
+ if (arm_pc_is_thumb (regval))
+ store_address (val, len, MAKE_THUMB_ADDR (regval));
+ }
+#endif
+ /* Copy the argument to general registers or the stack in
+ register-sized pieces. Large arguments are split between
+ registers and stack. */
+ while (len > 0)
+ {
+ int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE;
+
+ if (argreg <= ARM_LAST_ARG_REGNUM)
+ {
+ /* It's an argument being passed in a general register. */
+ regval = extract_address (val, partial_len);
+ write_register (argreg++, regval);
+ }
+ else
+ {
+ /* Push the arguments onto the stack. */
+ write_memory ((CORE_ADDR) fp, val, REGISTER_SIZE);
+ fp += REGISTER_SIZE;
+ }
+
+ len -= partial_len;
+ val += partial_len;
+ }
+ }
+
+ /* Return adjusted stack pointer. */
+ return sp;
+}
+
+/* Pop the current frame. So long as the frame info has been
+ initialized properly (see arm_init_extra_frame_info), this code
+ works for dummy frames as well as regular frames. I.e, there's no
+ need to have a special case for dummy frames. */
+static void
+arm_pop_frame (void)
+{
+ int regnum;
+ struct frame_info *frame = get_current_frame ();
+ CORE_ADDR old_SP = (frame->frame - frame->extra_info->frameoffset
+ + frame->extra_info->framesize);
+
+ if (USE_GENERIC_DUMMY_FRAMES
+ && PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ {
+ generic_pop_dummy_frame ();
+ flush_cached_frames ();
+ return;
+ }
+
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ if (frame->saved_regs[regnum] != 0)
+ write_register (regnum,
+ read_memory_integer (frame->saved_regs[regnum],
+ REGISTER_RAW_SIZE (regnum)));
+
+ write_register (ARM_PC_REGNUM, FRAME_SAVED_PC (frame));
+ write_register (ARM_SP_REGNUM, old_SP);
+
+ flush_cached_frames ();
+}
+
+static void
+print_fpu_flags (int flags)
+{
+ if (flags & (1 << 0))
+ fputs ("IVO ", stdout);
+ if (flags & (1 << 1))
+ fputs ("DVZ ", stdout);
+ if (flags & (1 << 2))
+ fputs ("OFL ", stdout);
+ if (flags & (1 << 3))
+ fputs ("UFL ", stdout);
+ if (flags & (1 << 4))
+ fputs ("INX ", stdout);
+ putchar ('\n');
+}
+
+/* Print interesting information about the floating point processor
+ (if present) or emulator. */
+static void
+arm_print_float_info (void)
+{
+ register unsigned long status = read_register (ARM_FPS_REGNUM);
+ int type;
+
+ type = (status >> 24) & 127;
+ printf ("%s FPU type %d\n",
+ (status & (1 << 31)) ? "Hardware" : "Software",
+ type);
+ fputs ("mask: ", stdout);
+ print_fpu_flags (status >> 16);
+ fputs ("flags: ", stdout);
+ print_fpu_flags (status);
+}
+
+/* Return the GDB type object for the "standard" data type of data in
+ register N. */
+
+static struct type *
+arm_register_type (int regnum)
+{
+ if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS)
+ {
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ return builtin_type_arm_ext_big;
+ else
+ return builtin_type_arm_ext_littlebyte_bigword;
+ }
+ else
+ return builtin_type_int32;
+}
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+static int
+arm_register_byte (int regnum)
+{
+ if (regnum < ARM_F0_REGNUM)
+ return regnum * INT_REGISTER_RAW_SIZE;
+ else if (regnum < ARM_PS_REGNUM)
+ return (NUM_GREGS * INT_REGISTER_RAW_SIZE
+ + (regnum - ARM_F0_REGNUM) * FP_REGISTER_RAW_SIZE);
+ else
+ return (NUM_GREGS * INT_REGISTER_RAW_SIZE
+ + NUM_FREGS * FP_REGISTER_RAW_SIZE
+ + (regnum - ARM_FPS_REGNUM) * STATUS_REGISTER_SIZE);
+}
+
+/* Number of bytes of storage in the actual machine representation for
+ register N. All registers are 4 bytes, except fp0 - fp7, which are
+ 12 bytes in length. */
+
+static int
+arm_register_raw_size (int regnum)
+{
+ if (regnum < ARM_F0_REGNUM)
+ return INT_REGISTER_RAW_SIZE;
+ else if (regnum < ARM_FPS_REGNUM)
+ return FP_REGISTER_RAW_SIZE;
+ else
+ return STATUS_REGISTER_SIZE;
+}
+
+/* Number of bytes of storage in a program's representation
+ for register N. */
+static int
+arm_register_virtual_size (int regnum)
+{
+ if (regnum < ARM_F0_REGNUM)
+ return INT_REGISTER_VIRTUAL_SIZE;
+ else if (regnum < ARM_FPS_REGNUM)
+ return FP_REGISTER_VIRTUAL_SIZE;
+ else
+ return STATUS_REGISTER_SIZE;
+}
+
+
+/* NOTE: cagney/2001-08-20: Both convert_from_extended() and
+ convert_to_extended() use floatformat_arm_ext_littlebyte_bigword.
+ It is thought that this is is the floating-point register format on
+ little-endian systems. */
+
+static void
+convert_from_extended (void *ptr, void *dbl)
+{
+ DOUBLEST d;
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ floatformat_to_doublest (&floatformat_arm_ext_big, ptr, &d);
+ else
+ floatformat_to_doublest (&floatformat_arm_ext_littlebyte_bigword,
+ ptr, &d);
+ floatformat_from_doublest (TARGET_DOUBLE_FORMAT, &d, dbl);
+}
+
+static void
+convert_to_extended (void *dbl, void *ptr)
+{
+ DOUBLEST d;
+ floatformat_to_doublest (TARGET_DOUBLE_FORMAT, ptr, &d);
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ floatformat_from_doublest (&floatformat_arm_ext_big, &d, dbl);
+ else
+ floatformat_from_doublest (&floatformat_arm_ext_littlebyte_bigword,
+ &d, dbl);
+}
+
+static int
+condition_true (unsigned long cond, unsigned long status_reg)
+{
+ if (cond == INST_AL || cond == INST_NV)
+ return 1;
+
+ switch (cond)
+ {
+ case INST_EQ:
+ return ((status_reg & FLAG_Z) != 0);
+ case INST_NE:
+ return ((status_reg & FLAG_Z) == 0);
+ case INST_CS:
+ return ((status_reg & FLAG_C) != 0);
+ case INST_CC:
+ return ((status_reg & FLAG_C) == 0);
+ case INST_MI:
+ return ((status_reg & FLAG_N) != 0);
+ case INST_PL:
+ return ((status_reg & FLAG_N) == 0);
+ case INST_VS:
+ return ((status_reg & FLAG_V) != 0);
+ case INST_VC:
+ return ((status_reg & FLAG_V) == 0);
+ case INST_HI:
+ return ((status_reg & (FLAG_C | FLAG_Z)) == FLAG_C);
+ case INST_LS:
+ return ((status_reg & (FLAG_C | FLAG_Z)) != FLAG_C);
+ case INST_GE:
+ return (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0));
+ case INST_LT:
+ return (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0));
+ case INST_GT:
+ return (((status_reg & FLAG_Z) == 0) &&
+ (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0)));
+ case INST_LE:
+ return (((status_reg & FLAG_Z) != 0) ||
+ (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0)));
+ }
+ return 1;
+}
+
+/* Support routines for single stepping. Calculate the next PC value. */
+#define submask(x) ((1L << ((x) + 1)) - 1)
+#define bit(obj,st) (((obj) >> (st)) & 1)
+#define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st)))
+#define sbits(obj,st,fn) \
+ ((long) (bits(obj,st,fn) | ((long) bit(obj,fn) * ~ submask (fn - st))))
+#define BranchDest(addr,instr) \
+ ((CORE_ADDR) (((long) (addr)) + 8 + (sbits (instr, 0, 23) << 2)))
+#define ARM_PC_32 1
+
+static unsigned long
+shifted_reg_val (unsigned long inst, int carry, unsigned long pc_val,
+ unsigned long status_reg)
+{
+ unsigned long res, shift;
+ int rm = bits (inst, 0, 3);
+ unsigned long shifttype = bits (inst, 5, 6);
+
+ if (bit (inst, 4))
+ {
+ int rs = bits (inst, 8, 11);
+ shift = (rs == 15 ? pc_val + 8 : read_register (rs)) & 0xFF;
+ }
+ else
+ shift = bits (inst, 7, 11);
+
+ res = (rm == 15
+ ? ((pc_val | (ARM_PC_32 ? 0 : status_reg))
+ + (bit (inst, 4) ? 12 : 8))
+ : read_register (rm));
+
+ switch (shifttype)
+ {
+ case 0: /* LSL */
+ res = shift >= 32 ? 0 : res << shift;
+ break;
+
+ case 1: /* LSR */
+ res = shift >= 32 ? 0 : res >> shift;
+ break;
+
+ case 2: /* ASR */
+ if (shift >= 32)
+ shift = 31;
+ res = ((res & 0x80000000L)
+ ? ~((~res) >> shift) : res >> shift);
+ break;
+
+ case 3: /* ROR/RRX */
+ shift &= 31;
+ if (shift == 0)
+ res = (res >> 1) | (carry ? 0x80000000L : 0);
+ else
+ res = (res >> shift) | (res << (32 - shift));
+ break;
+ }
+
+ return res & 0xffffffff;
+}
+
+/* Return number of 1-bits in VAL. */
+
+static int
+bitcount (unsigned long val)
+{
+ int nbits;
+ for (nbits = 0; val != 0; nbits++)
+ val &= val - 1; /* delete rightmost 1-bit in val */
+ return nbits;
+}
+
+CORE_ADDR
+thumb_get_next_pc (CORE_ADDR pc)
+{
+ unsigned long pc_val = ((unsigned long) pc) + 4; /* PC after prefetch */
+ unsigned short inst1 = read_memory_integer (pc, 2);
+ CORE_ADDR nextpc = pc + 2; /* default is next instruction */
+ unsigned long offset;
+
+ if ((inst1 & 0xff00) == 0xbd00) /* pop {rlist, pc} */
+ {
+ CORE_ADDR sp;
+
+ /* Fetch the saved PC from the stack. It's stored above
+ all of the other registers. */
+ offset = bitcount (bits (inst1, 0, 7)) * REGISTER_SIZE;
+ sp = read_register (ARM_SP_REGNUM);
+ nextpc = (CORE_ADDR) read_memory_integer (sp + offset, 4);
+ nextpc = ADDR_BITS_REMOVE (nextpc);
+ if (nextpc == pc)
+ error ("Infinite loop detected");
+ }
+ else if ((inst1 & 0xf000) == 0xd000) /* conditional branch */
+ {
+ unsigned long status = read_register (ARM_PS_REGNUM);
+ unsigned long cond = bits (inst1, 8, 11);
+ if (cond != 0x0f && condition_true (cond, status)) /* 0x0f = SWI */
+ nextpc = pc_val + (sbits (inst1, 0, 7) << 1);
+ }
+ else if ((inst1 & 0xf800) == 0xe000) /* unconditional branch */
+ {
+ nextpc = pc_val + (sbits (inst1, 0, 10) << 1);
+ }
+ else if ((inst1 & 0xf800) == 0xf000) /* long branch with link */
+ {
+ unsigned short inst2 = read_memory_integer (pc + 2, 2);
+ offset = (sbits (inst1, 0, 10) << 12) + (bits (inst2, 0, 10) << 1);
+ nextpc = pc_val + offset;
+ }
+
+ return nextpc;
+}
+
+CORE_ADDR
+arm_get_next_pc (CORE_ADDR pc)
+{
+ unsigned long pc_val;
+ unsigned long this_instr;
+ unsigned long status;
+ CORE_ADDR nextpc;
+
+ if (arm_pc_is_thumb (pc))
+ return thumb_get_next_pc (pc);
+
+ pc_val = (unsigned long) pc;
+ this_instr = read_memory_integer (pc, 4);
+ status = read_register (ARM_PS_REGNUM);
+ nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */
+
+ if (condition_true (bits (this_instr, 28, 31), status))
+ {
+ switch (bits (this_instr, 24, 27))
+ {
+ case 0x0:
+ case 0x1: /* data processing */
+ case 0x2:
+ case 0x3:
+ {
+ unsigned long operand1, operand2, result = 0;
+ unsigned long rn;
+ int c;
+
+ if (bits (this_instr, 12, 15) != 15)
+ break;
+
+ if (bits (this_instr, 22, 25) == 0
+ && bits (this_instr, 4, 7) == 9) /* multiply */
+ error ("Illegal update to pc in instruction");
+
+ /* Multiply into PC */
+ c = (status & FLAG_C) ? 1 : 0;
+ rn = bits (this_instr, 16, 19);
+ operand1 = (rn == 15) ? pc_val + 8 : read_register (rn);
+
+ if (bit (this_instr, 25))
+ {
+ unsigned long immval = bits (this_instr, 0, 7);
+ unsigned long rotate = 2 * bits (this_instr, 8, 11);
+ operand2 = ((immval >> rotate) | (immval << (32 - rotate)))
+ & 0xffffffff;
+ }
+ else /* operand 2 is a shifted register */
+ operand2 = shifted_reg_val (this_instr, c, pc_val, status);
+
+ switch (bits (this_instr, 21, 24))
+ {
+ case 0x0: /*and */
+ result = operand1 & operand2;
+ break;
+
+ case 0x1: /*eor */
+ result = operand1 ^ operand2;
+ break;
+
+ case 0x2: /*sub */
+ result = operand1 - operand2;
+ break;
+
+ case 0x3: /*rsb */
+ result = operand2 - operand1;
+ break;
+
+ case 0x4: /*add */
+ result = operand1 + operand2;
+ break;
+
+ case 0x5: /*adc */
+ result = operand1 + operand2 + c;
+ break;
+
+ case 0x6: /*sbc */
+ result = operand1 - operand2 + c;
+ break;
+
+ case 0x7: /*rsc */
+ result = operand2 - operand1 + c;
+ break;
+
+ case 0x8:
+ case 0x9:
+ case 0xa:
+ case 0xb: /* tst, teq, cmp, cmn */
+ result = (unsigned long) nextpc;
+ break;
+
+ case 0xc: /*orr */
+ result = operand1 | operand2;
+ break;
+
+ case 0xd: /*mov */
+ /* Always step into a function. */
+ result = operand2;
+ break;
+
+ case 0xe: /*bic */
+ result = operand1 & ~operand2;
+ break;
+
+ case 0xf: /*mvn */
+ result = ~operand2;
+ break;
+ }
+ nextpc = (CORE_ADDR) ADDR_BITS_REMOVE (result);
+
+ if (nextpc == pc)
+ error ("Infinite loop detected");
+ break;
+ }
+
+ case 0x4:
+ case 0x5: /* data transfer */
+ case 0x6:
+ case 0x7:
+ if (bit (this_instr, 20))
+ {
+ /* load */
+ if (bits (this_instr, 12, 15) == 15)
+ {
+ /* rd == pc */
+ unsigned long rn;
+ unsigned long base;
+
+ if (bit (this_instr, 22))
+ error ("Illegal update to pc in instruction");
+
+ /* byte write to PC */
+ rn = bits (this_instr, 16, 19);
+ base = (rn == 15) ? pc_val + 8 : read_register (rn);
+ if (bit (this_instr, 24))
+ {
+ /* pre-indexed */
+ int c = (status & FLAG_C) ? 1 : 0;
+ unsigned long offset =
+ (bit (this_instr, 25)
+ ? shifted_reg_val (this_instr, c, pc_val, status)
+ : bits (this_instr, 0, 11));
+
+ if (bit (this_instr, 23))
+ base += offset;
+ else
+ base -= offset;
+ }
+ nextpc = (CORE_ADDR) read_memory_integer ((CORE_ADDR) base,
+ 4);
+
+ nextpc = ADDR_BITS_REMOVE (nextpc);
+
+ if (nextpc == pc)
+ error ("Infinite loop detected");
+ }
+ }
+ break;
+
+ case 0x8:
+ case 0x9: /* block transfer */
+ if (bit (this_instr, 20))
+ {
+ /* LDM */
+ if (bit (this_instr, 15))
+ {
+ /* loading pc */
+ int offset = 0;
+
+ if (bit (this_instr, 23))
+ {
+ /* up */
+ unsigned long reglist = bits (this_instr, 0, 14);
+ offset = bitcount (reglist) * 4;
+ if (bit (this_instr, 24)) /* pre */
+ offset += 4;
+ }
+ else if (bit (this_instr, 24))
+ offset = -4;
+
+ {
+ unsigned long rn_val =
+ read_register (bits (this_instr, 16, 19));
+ nextpc =
+ (CORE_ADDR) read_memory_integer ((CORE_ADDR) (rn_val
+ + offset),
+ 4);
+ }
+ nextpc = ADDR_BITS_REMOVE (nextpc);
+ if (nextpc == pc)
+ error ("Infinite loop detected");
+ }
+ }
+ break;
+
+ case 0xb: /* branch & link */
+ case 0xa: /* branch */
+ {
+ nextpc = BranchDest (pc, this_instr);
+
+ nextpc = ADDR_BITS_REMOVE (nextpc);
+ if (nextpc == pc)
+ error ("Infinite loop detected");
+ break;
+ }
+
+ case 0xc:
+ case 0xd:
+ case 0xe: /* coproc ops */
+ case 0xf: /* SWI */
+ break;
+
+ default:
+ fprintf_filtered (gdb_stderr, "Bad bit-field extraction\n");
+ return (pc);
+ }
+ }
+
+ return nextpc;
+}
+
+/* single_step() is called just before we want to resume the inferior,
+ if we want to single-step it but there is no hardware or kernel
+ single-step support. We find the target of the coming instruction
+ and breakpoint it.
+
+ single_step() is also called just after the inferior stops. If we
+ had set up a simulated single-step, we undo our damage. */
+
+static void
+arm_software_single_step (enum target_signal sig, int insert_bpt)
+{
+ static int next_pc; /* State between setting and unsetting. */
+ static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt */
+
+ if (insert_bpt)
+ {
+ next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM));
+ target_insert_breakpoint (next_pc, break_mem);
+ }
+ else
+ target_remove_breakpoint (next_pc, break_mem);
+}
+
+#include "bfd-in2.h"
+#include "libcoff.h"
+
+static int
+gdb_print_insn_arm (bfd_vma memaddr, disassemble_info *info)
+{
+ if (arm_pc_is_thumb (memaddr))
+ {
+ static asymbol *asym;
+ static combined_entry_type ce;
+ static struct coff_symbol_struct csym;
+ static struct _bfd fake_bfd;
+ static bfd_target fake_target;
+
+ if (csym.native == NULL)
+ {
+ /* Create a fake symbol vector containing a Thumb symbol.
+ This is solely so that the code in print_insn_little_arm()
+ and print_insn_big_arm() in opcodes/arm-dis.c will detect
+ the presence of a Thumb symbol and switch to decoding
+ Thumb instructions. */
+
+ fake_target.flavour = bfd_target_coff_flavour;
+ fake_bfd.xvec = &fake_target;
+ ce.u.syment.n_sclass = C_THUMBEXTFUNC;
+ csym.native = &ce;
+ csym.symbol.the_bfd = &fake_bfd;
+ csym.symbol.name = "fake";
+ asym = (asymbol *) & csym;
+ }
+
+ memaddr = UNMAKE_THUMB_ADDR (memaddr);
+ info->symbols = &asym;
+ }
+ else
+ info->symbols = NULL;
+
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ return print_insn_big_arm (memaddr, info);
+ else
+ return print_insn_little_arm (memaddr, info);
+}
+
+/* The following define instruction sequences that will cause ARM
+ cpu's to take an undefined instruction trap. These are used to
+ signal a breakpoint to GDB.
+
+ The newer ARMv4T cpu's are capable of operating in ARM or Thumb
+ modes. A different instruction is required for each mode. The ARM
+ cpu's can also be big or little endian. Thus four different
+ instructions are needed to support all cases.
+
+ Note: ARMv4 defines several new instructions that will take the
+ undefined instruction trap. ARM7TDMI is nominally ARMv4T, but does
+ not in fact add the new instructions. The new undefined
+ instructions in ARMv4 are all instructions that had no defined
+ behaviour in earlier chips. There is no guarantee that they will
+ raise an exception, but may be treated as NOP's. In practice, it
+ may only safe to rely on instructions matching:
+
+ 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ C C C C 0 1 1 x x x x x x x x x x x x x x x x x x x x 1 x x x x
+
+ Even this may only true if the condition predicate is true. The
+ following use a condition predicate of ALWAYS so it is always TRUE.
+
+ There are other ways of forcing a breakpoint. GNU/Linux, RISC iX,
+ and NetBSD all use a software interrupt rather than an undefined
+ instruction to force a trap. This can be handled by by the
+ abi-specific code during establishment of the gdbarch vector. */
+
+
+/* NOTE rearnsha 2002-02-18: for now we allow a non-multi-arch gdb to
+ override these definitions. */
+#ifndef ARM_LE_BREAKPOINT
+#define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7}
+#endif
+#ifndef ARM_BE_BREAKPOINT
+#define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE}
+#endif
+#ifndef THUMB_LE_BREAKPOINT
+#define THUMB_LE_BREAKPOINT {0xfe,0xdf}
+#endif
+#ifndef THUMB_BE_BREAKPOINT
+#define THUMB_BE_BREAKPOINT {0xdf,0xfe}
+#endif
+
+static const char arm_default_arm_le_breakpoint[] = ARM_LE_BREAKPOINT;
+static const char arm_default_arm_be_breakpoint[] = ARM_BE_BREAKPOINT;
+static const char arm_default_thumb_le_breakpoint[] = THUMB_LE_BREAKPOINT;
+static const char arm_default_thumb_be_breakpoint[] = THUMB_BE_BREAKPOINT;
+
+/* Determine the type and size of breakpoint to insert at PCPTR. Uses
+ the program counter value to determine whether a 16-bit or 32-bit
+ breakpoint should be used. It returns a pointer to a string of
+ bytes that encode a breakpoint instruction, stores the length of
+ the string to *lenptr, and adjusts the program counter (if
+ necessary) to point to the actual memory location where the
+ breakpoint should be inserted. */
+
+/* XXX ??? from old tm-arm.h: if we're using RDP, then we're inserting
+ breakpoints and storing their handles instread of what was in
+ memory. It is nice that this is the same size as a handle -
+ otherwise remote-rdp will have to change. */
+
+static const unsigned char *
+arm_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (arm_pc_is_thumb (*pcptr) || arm_pc_is_thumb_dummy (*pcptr))
+ {
+ *pcptr = UNMAKE_THUMB_ADDR (*pcptr);
+ *lenptr = tdep->thumb_breakpoint_size;
+ return tdep->thumb_breakpoint;
+ }
+ else
+ {
+ *lenptr = tdep->arm_breakpoint_size;
+ return tdep->arm_breakpoint;
+ }
+}
+
+/* Extract from an array REGBUF containing the (raw) register state a
+ function return value of type TYPE, and copy that, in virtual
+ format, into VALBUF. */
+
+static void
+arm_extract_return_value (struct type *type,
+ char regbuf[REGISTER_BYTES],
+ char *valbuf)
+{
+ if (TYPE_CODE_FLT == TYPE_CODE (type))
+ {
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ switch (tdep->fp_model)
+ {
+ case ARM_FLOAT_FPA:
+ convert_from_extended (&regbuf[REGISTER_BYTE (ARM_F0_REGNUM)],
+ valbuf);
+ break;
+
+ case ARM_FLOAT_SOFT:
+ case ARM_FLOAT_SOFT_VFP:
+ memcpy (valbuf, &regbuf[REGISTER_BYTE (ARM_A1_REGNUM)],
+ TYPE_LENGTH (type));
+ break;
+
+ default:
+ internal_error
+ (__FILE__, __LINE__,
+ "arm_extract_return_value: Floating point model not supported");
+ break;
+ }
+ }
+ else
+ memcpy (valbuf, &regbuf[REGISTER_BYTE (ARM_A1_REGNUM)],
+ TYPE_LENGTH (type));
+}
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value. */
+
+static CORE_ADDR
+arm_extract_struct_value_address (char *regbuf)
+{
+ return extract_address (regbuf, REGISTER_RAW_SIZE(ARM_A1_REGNUM));
+}
+
+/* Will a function return an aggregate type in memory or in a
+ register? Return 0 if an aggregate type can be returned in a
+ register, 1 if it must be returned in memory. */
+
+static int
+arm_use_struct_convention (int gcc_p, struct type *type)
+{
+ int nRc;
+ register enum type_code code;
+
+ /* In the ARM ABI, "integer" like aggregate types are returned in
+ registers. For an aggregate type to be integer like, its size
+ must be less than or equal to REGISTER_SIZE and the offset of
+ each addressable subfield must be zero. Note that bit fields are
+ not addressable, and all addressable subfields of unions always
+ start at offset zero.
+
+ This function is based on the behaviour of GCC 2.95.1.
+ See: gcc/arm.c: arm_return_in_memory() for details.
+
+ Note: All versions of GCC before GCC 2.95.2 do not set up the
+ parameters correctly for a function returning the following
+ structure: struct { float f;}; This should be returned in memory,
+ not a register. Richard Earnshaw sent me a patch, but I do not
+ know of any way to detect if a function like the above has been
+ compiled with the correct calling convention. */
+
+ /* All aggregate types that won't fit in a register must be returned
+ in memory. */
+ if (TYPE_LENGTH (type) > REGISTER_SIZE)
+ {
+ return 1;
+ }
+
+ /* The only aggregate types that can be returned in a register are
+ structs and unions. Arrays must be returned in memory. */
+ code = TYPE_CODE (type);
+ if ((TYPE_CODE_STRUCT != code) && (TYPE_CODE_UNION != code))
+ {
+ return 1;
+ }
+
+ /* Assume all other aggregate types can be returned in a register.
+ Run a check for structures, unions and arrays. */
+ nRc = 0;
+
+ if ((TYPE_CODE_STRUCT == code) || (TYPE_CODE_UNION == code))
+ {
+ int i;
+ /* Need to check if this struct/union is "integer" like. For
+ this to be true, its size must be less than or equal to
+ REGISTER_SIZE and the offset of each addressable subfield
+ must be zero. Note that bit fields are not addressable, and
+ unions always start at offset zero. If any of the subfields
+ is a floating point type, the struct/union cannot be an
+ integer type. */
+
+ /* For each field in the object, check:
+ 1) Is it FP? --> yes, nRc = 1;
+ 2) Is it addressable (bitpos != 0) and
+ not packed (bitsize == 0)?
+ --> yes, nRc = 1
+ */
+
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
+ {
+ enum type_code field_type_code;
+ field_type_code = TYPE_CODE (TYPE_FIELD_TYPE (type, i));
+
+ /* Is it a floating point type field? */
+ if (field_type_code == TYPE_CODE_FLT)
+ {
+ nRc = 1;
+ break;
+ }
+
+ /* If bitpos != 0, then we have to care about it. */
+ if (TYPE_FIELD_BITPOS (type, i) != 0)
+ {
+ /* Bitfields are not addressable. If the field bitsize is
+ zero, then the field is not packed. Hence it cannot be
+ a bitfield or any other packed type. */
+ if (TYPE_FIELD_BITSIZE (type, i) == 0)
+ {
+ nRc = 1;
+ break;
+ }
+ }
+ }
+ }
+
+ return nRc;
+}
+
+/* Write into appropriate registers a function return value of type
+ TYPE, given in virtual format. */
+
+static void
+arm_store_return_value (struct type *type, char *valbuf)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ char buf[ARM_MAX_REGISTER_RAW_SIZE];
+
+ switch (tdep->fp_model)
+ {
+ case ARM_FLOAT_FPA:
+
+ convert_to_extended (valbuf, buf);
+ write_register_bytes (REGISTER_BYTE (ARM_F0_REGNUM), buf,
+ FP_REGISTER_RAW_SIZE);
+ break;
+
+ case ARM_FLOAT_SOFT:
+ case ARM_FLOAT_SOFT_VFP:
+ write_register_bytes (ARM_A1_REGNUM, valbuf, TYPE_LENGTH (type));
+ break;
+
+ default:
+ internal_error
+ (__FILE__, __LINE__,
+ "arm_store_return_value: Floating point model not supported");
+ break;
+ }
+ }
+ else
+ write_register_bytes (ARM_A1_REGNUM, valbuf, TYPE_LENGTH (type));
+}
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function. */
+
+static void
+arm_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ write_register (ARM_A1_REGNUM, addr);
+}
+
+static int
+arm_get_longjmp_target (CORE_ADDR *pc)
+{
+ CORE_ADDR jb_addr;
+ char buf[INT_REGISTER_RAW_SIZE];
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ jb_addr = read_register (ARM_A1_REGNUM);
+
+ if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf,
+ INT_REGISTER_RAW_SIZE))
+ return 0;
+
+ *pc = extract_address (buf, INT_REGISTER_RAW_SIZE);
+ return 1;
+}
+
+/* Return non-zero if the PC is inside a thumb call thunk. */
+
+int
+arm_in_call_stub (CORE_ADDR pc, char *name)
+{
+ CORE_ADDR start_addr;
+
+ /* Find the starting address of the function containing the PC. If
+ the caller didn't give us a name, look it up at the same time. */
+ if (0 == find_pc_partial_function (pc, name ? NULL : &name,
+ &start_addr, NULL))
+ return 0;
+
+ return strncmp (name, "_call_via_r", 11) == 0;
+}
+
+/* If PC is in a Thumb call or return stub, return the address of the
+ target PC, which is in a register. The thunk functions are called
+ _called_via_xx, where x is the register name. The possible names
+ are r0-r9, sl, fp, ip, sp, and lr. */
+
+CORE_ADDR
+arm_skip_stub (CORE_ADDR pc)
+{
+ char *name;
+ CORE_ADDR start_addr;
+
+ /* Find the starting address and name of the function containing the PC. */
+ if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0)
+ return 0;
+
+ /* Call thunks always start with "_call_via_". */
+ if (strncmp (name, "_call_via_", 10) == 0)
+ {
+ /* Use the name suffix to determine which register contains the
+ target PC. */
+ static char *table[15] =
+ {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "sl", "fp", "ip", "sp", "lr"
+ };
+ int regno;
+
+ for (regno = 0; regno <= 14; regno++)
+ if (strcmp (&name[10], table[regno]) == 0)
+ return read_register (regno);
+ }
+
+ return 0; /* not a stub */
+}
+
+/* If the user changes the register disassembly flavor used for info
+ register and other commands, we have to also switch the flavor used
+ in opcodes for disassembly output. This function is run in the set
+ disassembly_flavor command, and does that. */
+
+static void
+set_disassembly_flavor_sfunc (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ set_disassembly_flavor ();
+}
+
+/* Return the ARM register name corresponding to register I. */
+static char *
+arm_register_name (int i)
+{
+ return arm_register_names[i];
+}
+
+static void
+set_disassembly_flavor (void)
+{
+ const char *setname, *setdesc, **regnames;
+ int numregs, j;
+
+ /* Find the flavor that the user wants in the opcodes table. */
+ int current = 0;
+ numregs = get_arm_regnames (current, &setname, &setdesc, &regnames);
+ while ((disassembly_flavor != setname)
+ && (current < num_flavor_options))
+ get_arm_regnames (++current, &setname, &setdesc, &regnames);
+ current_option = current;
+
+ /* Fill our copy. */
+ for (j = 0; j < numregs; j++)
+ arm_register_names[j] = (char *) regnames[j];
+
+ /* Adjust case. */
+ if (isupper (*regnames[ARM_PC_REGNUM]))
+ {
+ arm_register_names[ARM_FPS_REGNUM] = "FPS";
+ arm_register_names[ARM_PS_REGNUM] = "CPSR";
+ }
+ else
+ {
+ arm_register_names[ARM_FPS_REGNUM] = "fps";
+ arm_register_names[ARM_PS_REGNUM] = "cpsr";
+ }
+
+ /* Synchronize the disassembler. */
+ set_arm_regname_option (current);
+}
+
+/* arm_othernames implements the "othernames" command. This is kind
+ of hacky, and I prefer the set-show disassembly-flavor which is
+ also used for the x86 gdb. I will keep this around, however, in
+ case anyone is actually using it. */
+
+static void
+arm_othernames (char *names, int n)
+{
+ /* Circle through the various flavors. */
+ current_option = (current_option + 1) % num_flavor_options;
+
+ disassembly_flavor = valid_flavors[current_option];
+ set_disassembly_flavor ();
+}
+
+/* Fetch, and possibly build, an appropriate link_map_offsets structure
+ for ARM linux targets using the struct offsets defined in <link.h>.
+ Note, however, that link.h is not actually referred to in this file.
+ Instead, the relevant structs offsets were obtained from examining
+ link.h. (We can't refer to link.h from this file because the host
+ system won't necessarily have it, or if it does, the structs which
+ it defines will refer to the host system, not the target). */
+
+struct link_map_offsets *
+arm_linux_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = 0;
+
+ if (lmp == 0)
+ {
+ lmp = &lmo;
+
+ lmo.r_debug_size = 8; /* Actual size is 20, but this is all we
+ need. */
+
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 4;
+
+ lmo.link_map_size = 20; /* Actual size is 552, but this is all we
+ need. */
+
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 4;
+
+ lmo.l_name_offset = 4;
+ lmo.l_name_size = 4;
+
+ lmo.l_next_offset = 12;
+ lmo.l_next_size = 4;
+
+ lmo.l_prev_offset = 16;
+ lmo.l_prev_size = 4;
+ }
+
+ return lmp;
+}
+
+/* Test whether the coff symbol specific value corresponds to a Thumb
+ function. */
+
+static int
+coff_sym_is_thumb (int val)
+{
+ return (val == C_THUMBEXT ||
+ val == C_THUMBSTAT ||
+ val == C_THUMBEXTFUNC ||
+ val == C_THUMBSTATFUNC ||
+ val == C_THUMBLABEL);
+}
+
+/* arm_coff_make_msymbol_special()
+ arm_elf_make_msymbol_special()
+
+ These functions test whether the COFF or ELF symbol corresponds to
+ an address in thumb code, and set a "special" bit in a minimal
+ symbol to indicate that it does. */
+
+static void
+arm_elf_make_msymbol_special(asymbol *sym, struct minimal_symbol *msym)
+{
+ /* Thumb symbols are of type STT_LOPROC, (synonymous with
+ STT_ARM_TFUNC). */
+ if (ELF_ST_TYPE (((elf_symbol_type *)sym)->internal_elf_sym.st_info)
+ == STT_LOPROC)
+ MSYMBOL_SET_SPECIAL (msym);
+}
+
+static void
+arm_coff_make_msymbol_special(int val, struct minimal_symbol *msym)
+{
+ if (coff_sym_is_thumb (val))
+ MSYMBOL_SET_SPECIAL (msym);
+}
+
+
+static enum gdb_osabi
+arm_elf_osabi_sniffer (bfd *abfd)
+{
+ unsigned int elfosabi, eflags;
+ enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
+
+ elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
+
+ switch (elfosabi)
+ {
+ case ELFOSABI_NONE:
+ /* When elfosabi is ELFOSABI_NONE (0), then the ELF structures in the
+ file are conforming to the base specification for that machine
+ (there are no OS-specific extensions). In order to determine the
+ real OS in use we must look for OS notes that have been added. */
+ bfd_map_over_sections (abfd,
+ generic_elf_osabi_sniff_abi_tag_sections,
+ &osabi);
+ if (osabi == GDB_OSABI_UNKNOWN)
+ {
+ /* Existing ARM tools don't set this field, so look at the EI_FLAGS
+ field for more information. */
+ eflags = EF_ARM_EABI_VERSION(elf_elfheader(abfd)->e_flags);
+ switch (eflags)
+ {
+ case EF_ARM_EABI_VER1:
+ osabi = GDB_OSABI_ARM_EABI_V1;
+ break;
+
+ case EF_ARM_EABI_VER2:
+ osabi = GDB_OSABI_ARM_EABI_V2;
+ break;
+
+ case EF_ARM_EABI_UNKNOWN:
+ /* Assume GNU tools. */
+ osabi = GDB_OSABI_ARM_APCS;
+ break;
+
+ default:
+ internal_error (__FILE__, __LINE__,
+ "arm_elf_osabi_sniffer: Unknown ARM EABI "
+ "version 0x%x", eflags);
+ }
+ }
+ break;
+
+ case ELFOSABI_ARM:
+ /* GNU tools use this value. Check note sections in this case,
+ as well. */
+ bfd_map_over_sections (abfd,
+ generic_elf_osabi_sniff_abi_tag_sections,
+ &osabi);
+ if (osabi == GDB_OSABI_UNKNOWN)
+ {
+ /* Assume APCS ABI. */
+ osabi = GDB_OSABI_ARM_APCS;
+ }
+ break;
+
+ case ELFOSABI_FREEBSD:
+ osabi = GDB_OSABI_FREEBSD_ELF;
+ break;
+
+ case ELFOSABI_NETBSD:
+ osabi = GDB_OSABI_NETBSD_ELF;
+ break;
+
+ case ELFOSABI_LINUX:
+ osabi = GDB_OSABI_LINUX;
+ break;
+ }
+
+ return osabi;
+}
+
+
+/* Initialize the current architecture based on INFO. If possible,
+ re-use an architecture from ARCHES, which is a list of
+ architectures already created during this debugging session.
+
+ Called e.g. at program startup, when reading a core file, and when
+ reading a binary file. */
+
+static struct gdbarch *
+arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch_tdep *tdep;
+ struct gdbarch *gdbarch;
+ enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
+
+ /* Try to deterimine the ABI of the object we are loading. */
+
+ if (info.abfd != NULL)
+ {
+ osabi = gdbarch_lookup_osabi (info.abfd);
+ if (osabi == GDB_OSABI_UNKNOWN)
+ {
+ switch (bfd_get_flavour (info.abfd))
+ {
+ case bfd_target_aout_flavour:
+ /* Assume it's an old APCS-style ABI. */
+ osabi = GDB_OSABI_ARM_APCS;
+ break;
+
+ case bfd_target_coff_flavour:
+ /* Assume it's an old APCS-style ABI. */
+ /* XXX WinCE? */
+ osabi = GDB_OSABI_ARM_APCS;
+ break;
+
+ default:
+ /* Leave it as "unknown". */
+ }
+ }
+ }
+
+ /* Find a candidate among extant architectures. */
+ for (arches = gdbarch_list_lookup_by_info (arches, &info);
+ arches != NULL;
+ arches = gdbarch_list_lookup_by_info (arches->next, &info))
+ {
+ /* Make sure the ABI selection matches. */
+ tdep = gdbarch_tdep (arches->gdbarch);
+ if (tdep && tdep->osabi == osabi)
+ return arches->gdbarch;
+ }
+
+ tdep = xmalloc (sizeof (struct gdbarch_tdep));
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ tdep->osabi = osabi;
+
+ /* This is the way it has always defaulted. */
+ tdep->fp_model = ARM_FLOAT_FPA;
+
+ /* Breakpoints. */
+ switch (info.byte_order)
+ {
+ case BFD_ENDIAN_BIG:
+ tdep->arm_breakpoint = arm_default_arm_be_breakpoint;
+ tdep->arm_breakpoint_size = sizeof (arm_default_arm_be_breakpoint);
+ tdep->thumb_breakpoint = arm_default_thumb_be_breakpoint;
+ tdep->thumb_breakpoint_size = sizeof (arm_default_thumb_be_breakpoint);
+
+ break;
+
+ case BFD_ENDIAN_LITTLE:
+ tdep->arm_breakpoint = arm_default_arm_le_breakpoint;
+ tdep->arm_breakpoint_size = sizeof (arm_default_arm_le_breakpoint);
+ tdep->thumb_breakpoint = arm_default_thumb_le_breakpoint;
+ tdep->thumb_breakpoint_size = sizeof (arm_default_thumb_le_breakpoint);
+
+ break;
+
+ default:
+ internal_error (__FILE__, __LINE__,
+ "arm_gdbarch_init: bad byte order for float format");
+ }
+
+ /* On ARM targets char defaults to unsigned. */
+ set_gdbarch_char_signed (gdbarch, 0);
+
+ /* This should be low enough for everything. */
+ tdep->lowest_pc = 0x20;
+ tdep->jb_pc = -1; /* Longjump support not enabled by default. */
+
+#if OLD_STYLE_ARM_DUMMY_FRAMES
+ /* NOTE: cagney/2002-05-07: Enable the below to restore the old ARM
+ specific (non-generic) dummy frame code. Might be useful if
+ there appears to be a problem with the generic dummy frame
+ mechanism that replaced it. */
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
+
+ /* Call dummy code. */
+ set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ /* We have to give this a value now, even though we will re-set it
+ during each call to arm_fix_call_dummy. */
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 8);
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+
+ set_gdbarch_call_dummy_words (gdbarch, arm_call_dummy_words);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (arm_call_dummy_words));
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+
+ set_gdbarch_fix_call_dummy (gdbarch, arm_fix_call_dummy);
+
+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
+#else
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+
+ set_gdbarch_call_dummy_words (gdbarch, arm_call_dummy_words);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+
+ set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
+ set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
+
+ set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
+ set_gdbarch_push_return_address (gdbarch, arm_push_return_address);
+#endif
+
+ set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+ set_gdbarch_push_arguments (gdbarch, arm_push_arguments);
+ set_gdbarch_coerce_float_to_double (gdbarch,
+ standard_coerce_float_to_double);
+
+ /* Frame handling. */
+ set_gdbarch_frame_chain_valid (gdbarch, arm_frame_chain_valid);
+ set_gdbarch_init_extra_frame_info (gdbarch, arm_init_extra_frame_info);
+ set_gdbarch_read_fp (gdbarch, arm_read_fp);
+ set_gdbarch_frame_chain (gdbarch, arm_frame_chain);
+ set_gdbarch_frameless_function_invocation
+ (gdbarch, arm_frameless_function_invocation);
+ set_gdbarch_frame_saved_pc (gdbarch, arm_frame_saved_pc);
+ set_gdbarch_frame_args_address (gdbarch, arm_frame_args_address);
+ set_gdbarch_frame_locals_address (gdbarch, arm_frame_locals_address);
+ set_gdbarch_frame_num_args (gdbarch, arm_frame_num_args);
+ set_gdbarch_frame_args_skip (gdbarch, 0);
+ set_gdbarch_frame_init_saved_regs (gdbarch, arm_frame_init_saved_regs);
+#if OLD_STYLE_ARM_DUMMY_FRAMES
+ /* NOTE: cagney/2002-05-07: Enable the below to restore the old ARM
+ specific (non-generic) dummy frame code. Might be useful if
+ there appears to be a problem with the generic dummy frame
+ mechanism that replaced it. */
+ set_gdbarch_push_dummy_frame (gdbarch, arm_push_dummy_frame);
+#else
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+#endif
+ set_gdbarch_pop_frame (gdbarch, arm_pop_frame);
+
+ /* Address manipulation. */
+ set_gdbarch_smash_text_address (gdbarch, arm_smash_text_address);
+ set_gdbarch_addr_bits_remove (gdbarch, arm_addr_bits_remove);
+
+ /* Offset from address of function to start of its code. */
+ set_gdbarch_function_start_offset (gdbarch, 0);
+
+ /* Advance PC across function entry code. */
+ set_gdbarch_skip_prologue (gdbarch, arm_skip_prologue);
+
+ /* Get the PC when a frame might not be available. */
+ set_gdbarch_saved_pc_after_call (gdbarch, arm_saved_pc_after_call);
+
+ /* The stack grows downward. */
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+
+ /* Breakpoint manipulation. */
+ set_gdbarch_breakpoint_from_pc (gdbarch, arm_breakpoint_from_pc);
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+
+ /* Information about registers, etc. */
+ set_gdbarch_print_float_info (gdbarch, arm_print_float_info);
+ set_gdbarch_fp_regnum (gdbarch, ARM_FP_REGNUM); /* ??? */
+ set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM);
+ set_gdbarch_register_byte (gdbarch, arm_register_byte);
+ set_gdbarch_register_bytes (gdbarch,
+ (NUM_GREGS * INT_REGISTER_RAW_SIZE
+ + NUM_FREGS * FP_REGISTER_RAW_SIZE
+ + NUM_SREGS * STATUS_REGISTER_SIZE));
+ set_gdbarch_num_regs (gdbarch, NUM_GREGS + NUM_FREGS + NUM_SREGS);
+ set_gdbarch_register_raw_size (gdbarch, arm_register_raw_size);
+ set_gdbarch_register_virtual_size (gdbarch, arm_register_virtual_size);
+ set_gdbarch_max_register_raw_size (gdbarch, FP_REGISTER_RAW_SIZE);
+ set_gdbarch_max_register_virtual_size (gdbarch, FP_REGISTER_VIRTUAL_SIZE);
+ set_gdbarch_register_virtual_type (gdbarch, arm_register_type);
+
+ /* Integer registers are 4 bytes. */
+ set_gdbarch_register_size (gdbarch, 4);
+ set_gdbarch_register_name (gdbarch, arm_register_name);
+
+ /* Returning results. */
+ set_gdbarch_extract_return_value (gdbarch, arm_extract_return_value);
+ set_gdbarch_store_return_value (gdbarch, arm_store_return_value);
+ set_gdbarch_store_struct_return (gdbarch, arm_store_struct_return);
+ set_gdbarch_use_struct_convention (gdbarch, arm_use_struct_convention);
+ set_gdbarch_extract_struct_value_address (gdbarch,
+ arm_extract_struct_value_address);
+
+ /* Single stepping. */
+ /* XXX For an RDI target we should ask the target if it can single-step. */
+ set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
+
+ /* Minsymbol frobbing. */
+ set_gdbarch_elf_make_msymbol_special (gdbarch, arm_elf_make_msymbol_special);
+ set_gdbarch_coff_make_msymbol_special (gdbarch,
+ arm_coff_make_msymbol_special);
+
+ /* Hook in the ABI-specific overrides, if they have been registered. */
+ gdbarch_init_osabi (info, gdbarch, osabi);
+
+ /* Now we have tuned the configuration, set a few final things,
+ based on what the OS ABI has told us. */
+
+ if (tdep->jb_pc >= 0)
+ set_gdbarch_get_longjmp_target (gdbarch, arm_get_longjmp_target);
+
+ /* Floating point sizes and format. */
+ switch (info.byte_order)
+ {
+ case BFD_ENDIAN_BIG:
+ set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big);
+ set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_big);
+ set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);
+
+ break;
+
+ case BFD_ENDIAN_LITTLE:
+ set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
+ if (tdep->fp_model == ARM_FLOAT_VFP
+ || tdep->fp_model == ARM_FLOAT_SOFT_VFP)
+ {
+ set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_little);
+ set_gdbarch_long_double_format (gdbarch,
+ &floatformat_ieee_double_little);
+ }
+ else
+ {
+ set_gdbarch_double_format
+ (gdbarch, &floatformat_ieee_double_littlebyte_bigword);
+ set_gdbarch_long_double_format
+ (gdbarch, &floatformat_ieee_double_littlebyte_bigword);
+ }
+ break;
+
+ default:
+ internal_error (__FILE__, __LINE__,
+ "arm_gdbarch_init: bad byte order for float format");
+ }
+
+ /* We can't use SIZEOF_FRAME_SAVED_REGS here, since that still
+ references the old architecture vector, not the one we are
+ building here. */
+ if (prologue_cache.saved_regs != NULL)
+ xfree (prologue_cache.saved_regs);
+
+ /* We can't use NUM_REGS nor NUM_PSEUDO_REGS here, since that still
+ references the old architecture vector, not the one we are
+ building here. */
+ prologue_cache.saved_regs = (CORE_ADDR *)
+ xcalloc (1, (sizeof (CORE_ADDR)
+ * (gdbarch_num_regs (gdbarch)
+ + gdbarch_num_pseudo_regs (gdbarch))));
+
+ return gdbarch;
+}
+
+static void
+arm_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (tdep == NULL)
+ return;
+
+ fprintf_unfiltered (file, "arm_dump_tdep: OS ABI = %s\n",
+ gdbarch_osabi_name (tdep->osabi));
+
+ fprintf_unfiltered (file, "arm_dump_tdep: Lowest pc = 0x%lx",
+ (unsigned long) tdep->lowest_pc);
+}
+
+static void
+arm_init_abi_eabi_v1 (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ /* Place-holder. */
+}
+
+static void
+arm_init_abi_eabi_v2 (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ /* Place-holder. */
+}
+
+static void
+arm_init_abi_apcs (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ /* Place-holder. */
+}
+
+void
+_initialize_arm_tdep (void)
+{
+ struct ui_file *stb;
+ long length;
+ struct cmd_list_element *new_cmd;
+ const char *setname;
+ const char *setdesc;
+ const char **regnames;
+ int numregs, i, j;
+ static char *helptext;
+
+ if (GDB_MULTI_ARCH)
+ gdbarch_register (bfd_arch_arm, arm_gdbarch_init, arm_dump_tdep);
+
+ /* Register an ELF OS ABI sniffer for ARM binaries. */
+ gdbarch_register_osabi_sniffer (bfd_arch_arm,
+ bfd_target_elf_flavour,
+ arm_elf_osabi_sniffer);
+
+ /* Register some ABI variants for embedded systems. */
+ gdbarch_register_osabi (bfd_arch_arm, GDB_OSABI_ARM_EABI_V1,
+ arm_init_abi_eabi_v1);
+ gdbarch_register_osabi (bfd_arch_arm, GDB_OSABI_ARM_EABI_V2,
+ arm_init_abi_eabi_v2);
+ gdbarch_register_osabi (bfd_arch_arm, GDB_OSABI_ARM_APCS,
+ arm_init_abi_apcs);
+
+ tm_print_insn = gdb_print_insn_arm;
+
+ /* Get the number of possible sets of register names defined in opcodes. */
+ num_flavor_options = get_arm_regname_num_options ();
+
+ /* Sync the opcode insn printer with our register viewer. */
+ parse_arm_disassembler_option ("reg-names-std");
+
+ /* Begin creating the help text. */
+ stb = mem_fileopen ();
+ fprintf_unfiltered (stb, "Set the disassembly flavor.\n\
+The valid values are:\n");
+
+ /* Initialize the array that will be passed to add_set_enum_cmd(). */
+ valid_flavors = xmalloc ((num_flavor_options + 1) * sizeof (char *));
+ for (i = 0; i < num_flavor_options; i++)
+ {
+ numregs = get_arm_regnames (i, &setname, &setdesc, &regnames);
+ valid_flavors[i] = setname;
+ fprintf_unfiltered (stb, "%s - %s\n", setname,
+ setdesc);
+ /* Copy the default names (if found) and synchronize disassembler. */
+ if (!strcmp (setname, "std"))
+ {
+ disassembly_flavor = setname;
+ current_option = i;
+ for (j = 0; j < numregs; j++)
+ arm_register_names[j] = (char *) regnames[j];
+ set_arm_regname_option (i);
+ }
+ }
+ /* Mark the end of valid options. */
+ valid_flavors[num_flavor_options] = NULL;
+
+ /* Finish the creation of the help text. */
+ fprintf_unfiltered (stb, "The default is \"std\".");
+ helptext = ui_file_xstrdup (stb, &length);
+ ui_file_delete (stb);
+
+ /* Add the disassembly-flavor command. */
+ new_cmd = add_set_enum_cmd ("disassembly-flavor", no_class,
+ valid_flavors,
+ &disassembly_flavor,
+ helptext,
+ &setlist);
+ set_cmd_sfunc (new_cmd, set_disassembly_flavor_sfunc);
+ add_show_from_set (new_cmd, &showlist);
+
+ /* ??? Maybe this should be a boolean. */
+ add_show_from_set (add_set_cmd ("apcs32", no_class,
+ var_zinteger, (char *) &arm_apcs_32,
+ "Set usage of ARM 32-bit mode.\n", &setlist),
+ &showlist);
+
+ /* Add the deprecated "othernames" command. */
+
+ add_com ("othernames", class_obscure, arm_othernames,
+ "Switch to the next set of register names.");
+
+ /* Fill in the prologue_cache fields. */
+ prologue_cache.saved_regs = NULL;
+ prologue_cache.extra_info = (struct frame_extra_info *)
+ xcalloc (1, sizeof (struct frame_extra_info));
+}
diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h
new file mode 100644
index 00000000000..a8f15148364
--- /dev/null
+++ b/gdb/arm-tdep.h
@@ -0,0 +1,156 @@
+/* Common target dependent code for GDB on ARM systems.
+ Copyright 2002 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 "osabi.h"
+
+/* Register numbers of various important registers. Note that some of
+ these values are "real" register numbers, and correspond to the
+ general registers of the machine, and some are "phony" register
+ numbers which are too large to be actual register numbers as far as
+ the user is concerned but do serve to get the desired values when
+ passed to read_register. */
+
+enum gdb_regnum {
+ ARM_A1_REGNUM = 0, /* first integer-like argument */
+ ARM_A4_REGNUM = 3, /* last integer-like argument */
+ ARM_AP_REGNUM = 11,
+ ARM_SP_REGNUM = 13, /* Contains address of top of stack */
+ ARM_LR_REGNUM = 14, /* address to return to from a function call */
+ ARM_PC_REGNUM = 15, /* Contains program counter */
+ ARM_F0_REGNUM = 16, /* first floating point register */
+ ARM_F3_REGNUM = 19, /* last floating point argument register */
+ ARM_F7_REGNUM = 23, /* last floating point register */
+ ARM_FPS_REGNUM = 24, /* floating point status register */
+ ARM_PS_REGNUM = 25, /* Contains processor status */
+ ARM_FP_REGNUM = 11, /* Frame register in ARM code, if used. */
+ THUMB_FP_REGNUM = 7, /* Frame register in Thumb code, if used. */
+ ARM_NUM_ARG_REGS = 4,
+ ARM_LAST_ARG_REGNUM = ARM_A4_REGNUM,
+ ARM_NUM_FP_ARG_REGS = 4,
+ ARM_LAST_FP_ARG_REGNUM = ARM_F3_REGNUM
+};
+
+/* Used in target-specific code when we need to know the size of the
+ largest type of register we need to handle. */
+#define ARM_MAX_REGISTER_RAW_SIZE 12
+#define ARM_MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Size of integer registers. */
+#define INT_REGISTER_RAW_SIZE 4
+#define INT_REGISTER_VIRTUAL_SIZE 4
+
+/* Say how long FP registers are. Used for documentation purposes and
+ code readability in this header. IEEE extended doubles are 80
+ bits. DWORD aligned they use 96 bits. */
+#define FP_REGISTER_RAW_SIZE 12
+
+/* GCC doesn't support long doubles (extended IEEE values). The FP
+ register virtual size is therefore 64 bits. Used for documentation
+ purposes and code readability in this header. */
+#define FP_REGISTER_VIRTUAL_SIZE 8
+
+/* Status registers are the same size as general purpose registers.
+ Used for documentation purposes and code readability in this
+ header. */
+#define STATUS_REGISTER_SIZE 4
+
+/* Number of machine registers. The only define actually required
+ is NUM_REGS. The other definitions are used for documentation
+ purposes and code readability. */
+/* For 26 bit ARM code, a fake copy of the PC is placed in register 25 (PS)
+ (and called PS for processor status) so the status bits can be cleared
+ from the PC (register 15). For 32 bit ARM code, a copy of CPSR is placed
+ in PS. */
+#define NUM_FREGS 8 /* Number of floating point registers. */
+#define NUM_SREGS 2 /* Number of status registers. */
+#define NUM_GREGS 16 /* Number of general purpose registers. */
+
+
+/* Instruction condition field values. */
+#define INST_EQ 0x0
+#define INST_NE 0x1
+#define INST_CS 0x2
+#define INST_CC 0x3
+#define INST_MI 0x4
+#define INST_PL 0x5
+#define INST_VS 0x6
+#define INST_VC 0x7
+#define INST_HI 0x8
+#define INST_LS 0x9
+#define INST_GE 0xa
+#define INST_LT 0xb
+#define INST_GT 0xc
+#define INST_LE 0xd
+#define INST_AL 0xe
+#define INST_NV 0xf
+
+#define FLAG_N 0x80000000
+#define FLAG_Z 0x40000000
+#define FLAG_C 0x20000000
+#define FLAG_V 0x10000000
+
+/* Type of floating-point code in use by inferior. There are really 3 models
+ that are traditionally supported (plus the endianness issue), but gcc can
+ only generate 2 of those. The third is APCS_FLOAT, where arguments to
+ functions are passed in floating-point registers.
+
+ In addition to the traditional models, VFP adds two more. */
+
+enum arm_float_model
+{
+ ARM_FLOAT_SOFT,
+ ARM_FLOAT_FPA,
+ ARM_FLOAT_SOFT_VFP,
+ ARM_FLOAT_VFP
+};
+
+/* Target-dependent structure in gdbarch. */
+struct gdbarch_tdep
+{
+ enum gdb_osabi osabi; /* OS/ABI of inferior. */
+
+ enum arm_float_model fp_model; /* Floating point calling conventions. */
+
+ CORE_ADDR lowest_pc; /* Lowest address at which instructions
+ will appear. */
+
+ const char *arm_breakpoint; /* Breakpoint pattern for an ARM insn. */
+ int arm_breakpoint_size; /* And its size. */
+ const char *thumb_breakpoint; /* Breakpoint pattern for an ARM insn. */
+ int thumb_breakpoint_size; /* And its size. */
+
+ int jb_pc; /* Offset to PC value in jump buffer.
+ If this is negative, longjmp support
+ will be disabled. */
+ size_t jb_elt_size; /* And the size of each entry in the buf. */
+};
+
+#ifndef LOWEST_PC
+#define LOWEST_PC (gdbarch_tdep (current_gdbarch)->lowest_pc)
+#endif
+
+/* Prototypes for internal interfaces needed by more than one MD file. */
+int arm_pc_is_thumb_dummy (CORE_ADDR);
+
+int arm_pc_is_thumb (CORE_ADDR);
+
+CORE_ADDR thumb_get_next_pc (CORE_ADDR);
+
+CORE_ADDR arm_get_next_pc (CORE_ADDR);
diff --git a/gdb/armnbsd-nat.c b/gdb/armnbsd-nat.c
new file mode 100644
index 00000000000..88396c06a14
--- /dev/null
+++ b/gdb/armnbsd-nat.c
@@ -0,0 +1,464 @@
+/* Native-dependent code for BSD Unix running on ARM's, for GDB.
+ Copyright 1988, 1989, 1991, 1992, 1994, 1996, 1999, 2002
+ 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 "defs.h"
+
+#ifndef FETCH_INFERIOR_REGISTERS
+#error Not FETCH_INFERIOR_REGISTERS
+#endif /* !FETCH_INFERIOR_REGISTERS */
+
+#include "arm-tdep.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+#include "inferior.h"
+#include "regcache.h"
+#include "gdbcore.h"
+
+extern int arm_apcs_32;
+
+static void
+supply_gregset (struct reg *gregset)
+{
+ int regno;
+ CORE_ADDR r_pc;
+
+ /* Integer registers. */
+ for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
+ supply_register (regno, (char *) &gregset->r[regno]);
+
+ supply_register (ARM_SP_REGNUM, (char *) &gregset->r_sp);
+ supply_register (ARM_LR_REGNUM, (char *) &gregset->r_lr);
+ /* This is ok: we're running native... */
+ r_pc = ADDR_BITS_REMOVE (gregset->r_pc);
+ supply_register (ARM_PC_REGNUM, (char *) &r_pc);
+
+ if (arm_apcs_32)
+ supply_register (ARM_PS_REGNUM, (char *) &gregset->r_cpsr);
+ else
+ supply_register (ARM_PS_REGNUM, (char *) &gregset->r_pc);
+}
+
+static void
+supply_fparegset (struct fpreg *fparegset)
+{
+ int regno;
+
+ for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
+ supply_register
+ (regno, (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
+
+ supply_register (ARM_FPS_REGNUM, (char *) &fparegset->fpr_fpsr);
+}
+
+static void
+fetch_register (int regno)
+{
+ struct reg inferior_registers;
+ int ret;
+
+ ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &inferior_registers, 0);
+
+ if (ret < 0)
+ {
+ warning ("unable to fetch general register");
+ return;
+ }
+
+ switch (regno)
+ {
+ case ARM_SP_REGNUM:
+ supply_register (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
+ break;
+
+ case ARM_LR_REGNUM:
+ supply_register (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
+ break;
+
+ case ARM_PC_REGNUM:
+ /* This is ok: we're running native... */
+ inferior_registers.r_pc = ADDR_BITS_REMOVE (inferior_registers.r_pc);
+ supply_register (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
+ break;
+
+ case ARM_PS_REGNUM:
+ if (arm_apcs_32)
+ supply_register (ARM_PS_REGNUM, (char *) &inferior_registers.r_cpsr);
+ else
+ supply_register (ARM_PS_REGNUM, (char *) &inferior_registers.r_pc);
+ break;
+
+ default:
+ supply_register (regno, (char *) &inferior_registers.r[regno]);
+ break;
+ }
+}
+
+static void
+fetch_regs (void)
+{
+ struct reg inferior_registers;
+ int ret;
+ int regno;
+
+ ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &inferior_registers, 0);
+
+ if (ret < 0)
+ {
+ warning ("unable to fetch general registers");
+ return;
+ }
+
+ supply_gregset (&inferior_registers);
+}
+
+static void
+fetch_fp_register (int regno)
+{
+ struct fpreg inferior_fp_registers;
+ int ret;
+
+ ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
+
+ if (ret < 0)
+ {
+ warning ("unable to fetch floating-point register");
+ return;
+ }
+
+ switch (regno)
+ {
+ case ARM_FPS_REGNUM:
+ supply_register (ARM_FPS_REGNUM,
+ (char *) &inferior_fp_registers.fpr_fpsr);
+ break;
+
+ default:
+ supply_register
+ (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
+ break;
+ }
+}
+
+static void
+fetch_fp_regs (void)
+{
+ struct fpreg inferior_fp_registers;
+ int ret;
+ int regno;
+
+ ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
+
+ if (ret < 0)
+ {
+ warning ("unable to fetch general registers");
+ return;
+ }
+
+ supply_fparegset (&inferior_fp_registers);
+}
+
+void
+fetch_inferior_registers (int regno)
+{
+ if (regno >= 0)
+ {
+ if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
+ fetch_register (regno);
+ else
+ fetch_fp_register (regno);
+ }
+ else
+ {
+ fetch_regs ();
+ fetch_fp_regs ();
+ }
+}
+
+
+static void
+store_register (int regno)
+{
+ struct reg inferior_registers;
+ int ret;
+
+ ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &inferior_registers, 0);
+
+ if (ret < 0)
+ {
+ warning ("unable to fetch general registers");
+ return;
+ }
+
+ switch (regno)
+ {
+ case ARM_SP_REGNUM:
+ regcache_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
+ break;
+
+ case ARM_LR_REGNUM:
+ regcache_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
+ break;
+
+ case ARM_PC_REGNUM:
+ if (arm_apcs_32)
+ regcache_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
+ else
+ {
+ unsigned pc_val;
+
+ regcache_collect (ARM_PC_REGNUM, (char *) &pc_val);
+
+ pc_val = ADDR_BITS_REMOVE (pc_val);
+ inferior_registers.r_pc
+ ^= ADDR_BITS_REMOVE (inferior_registers.r_pc);
+ inferior_registers.r_pc |= pc_val;
+ }
+ break;
+
+ case ARM_PS_REGNUM:
+ if (arm_apcs_32)
+ regcache_collect (ARM_PS_REGNUM, (char *) &inferior_registers.r_cpsr);
+ else
+ {
+ unsigned psr_val;
+
+ regcache_collect (ARM_PS_REGNUM, (char *) &psr_val);
+
+ psr_val ^= ADDR_BITS_REMOVE (psr_val);
+ inferior_registers.r_pc = ADDR_BITS_REMOVE (inferior_registers.r_pc);
+ inferior_registers.r_pc |= psr_val;
+ }
+ break;
+
+ default:
+ regcache_collect (regno, (char *) &inferior_registers.r[regno]);
+ break;
+ }
+
+ ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &inferior_registers, 0);
+
+ if (ret < 0)
+ warning ("unable to write register %d to inferior", regno);
+}
+
+static void
+store_regs (void)
+{
+ struct reg inferior_registers;
+ int ret;
+ int regno;
+
+
+ for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
+ regcache_collect (regno, (char *) &inferior_registers.r[regno]);
+
+ regcache_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
+ regcache_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
+
+ if (arm_apcs_32)
+ {
+ regcache_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
+ regcache_collect (ARM_PS_REGNUM, (char *) &inferior_registers.r_cpsr);
+ }
+ else
+ {
+ unsigned pc_val;
+ unsigned psr_val;
+
+ regcache_collect (ARM_PC_REGNUM, (char *) &pc_val);
+ regcache_collect (ARM_PS_REGNUM, (char *) &psr_val);
+
+ pc_val = ADDR_BITS_REMOVE (pc_val);
+ psr_val ^= ADDR_BITS_REMOVE (psr_val);
+
+ inferior_registers.r_pc = pc_val | psr_val;
+ }
+
+ ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &inferior_registers, 0);
+
+ if (ret < 0)
+ warning ("unable to store general registers");
+}
+
+static void
+store_fp_register (int regno)
+{
+ struct fpreg inferior_fp_registers;
+ int ret;
+
+ ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
+
+ if (ret < 0)
+ {
+ warning ("unable to fetch floating-point registers");
+ return;
+ }
+
+ switch (regno)
+ {
+ case ARM_FPS_REGNUM:
+ regcache_collect (ARM_FPS_REGNUM,
+ (char *) &inferior_fp_registers.fpr_fpsr);
+ break;
+
+ default:
+ regcache_collect
+ (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
+ break;
+ }
+
+ ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
+
+ if (ret < 0)
+ warning ("unable to write register %d to inferior", regno);
+}
+
+static void
+store_fp_regs (void)
+{
+ struct fpreg inferior_fp_registers;
+ int ret;
+ int regno;
+
+
+ for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
+ regcache_collect
+ (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
+
+ regcache_collect (ARM_FPS_REGNUM, (char *) &inferior_fp_registers.fpr_fpsr);
+
+ ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
+
+ if (ret < 0)
+ warning ("unable to store floating-point registers");
+}
+
+void
+store_inferior_registers (int regno)
+{
+ if (regno >= 0)
+ {
+ if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
+ store_register (regno);
+ else
+ store_fp_register (regno);
+ }
+ else
+ {
+ store_regs ();
+ store_fp_regs ();
+ }
+}
+
+struct md_core
+{
+ struct reg intreg;
+ struct fpreg freg;
+};
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR ignore)
+{
+ struct md_core *core_reg = (struct md_core *) core_reg_sect;
+ int regno;
+ CORE_ADDR r_pc;
+
+ supply_gregset (&core_reg->intreg);
+ supply_fparegset (&core_reg->freg);
+}
+
+static void
+fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR ignore)
+{
+ struct reg gregset;
+ struct fpreg fparegset;
+
+ switch (which)
+ {
+ case 0: /* Integer registers. */
+ if (core_reg_size != sizeof (struct reg))
+ warning ("wrong size of register set in core file");
+ else
+ {
+ /* The memcpy may be unnecessary, but we can't really be sure
+ of the alignment of the data in the core file. */
+ memcpy (&gregset, core_reg_sect, sizeof (gregset));
+ supply_gregset (&gregset);
+ }
+ break;
+
+ case 2:
+ if (core_reg_size != sizeof (struct fpreg))
+ warning ("wrong size of FPA register set in core file");
+ else
+ {
+ /* The memcpy may be unnecessary, but we can't really be sure
+ of the alignment of the data in the core file. */
+ memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
+ supply_fparegset (&fparegset);
+ }
+ break;
+
+ default:
+ /* Don't know what kind of register request this is; just ignore it. */
+ break;
+ }
+}
+
+static struct core_fns arm_netbsd_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flovour. */
+ default_check_format, /* check_format. */
+ default_core_sniffer, /* core_sniffer. */
+ fetch_core_registers, /* core_read_registers. */
+ NULL
+};
+
+static struct core_fns arm_netbsd_elfcore_fns =
+{
+ bfd_target_elf_flavour, /* core_flovour. */
+ default_check_format, /* check_format. */
+ default_core_sniffer, /* core_sniffer. */
+ fetch_elfcore_registers, /* core_read_registers. */
+ NULL
+};
+
+void
+_initialize_arm_netbsd_nat (void)
+{
+ add_core_fns (&arm_netbsd_core_fns);
+ add_core_fns (&arm_netbsd_elfcore_fns);
+}
diff --git a/gdb/armnbsd-tdep.c b/gdb/armnbsd-tdep.c
new file mode 100644
index 00000000000..ea920207d32
--- /dev/null
+++ b/gdb/armnbsd-tdep.c
@@ -0,0 +1,104 @@
+/* Target-specific functions for ARM running under NetBSD.
+ Copyright 2002 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 "defs.h"
+
+#include "arm-tdep.h"
+#include "nbsd-tdep.h"
+#include "solib-svr4.h"
+
+/* Description of the longjmp buffer. */
+#define JB_PC 24
+#define JB_ELEMENT_SIZE INT_REGISTER_RAW_SIZE
+
+/* For compatibility with previous implemenations of GDB on arm/NetBSD,
+ override the default little-endian breakpoint. */
+static const char arm_nbsd_arm_le_breakpoint[] = {0x11, 0x00, 0x00, 0xe6};
+
+static int
+arm_netbsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+ if (strcmp (name, "_PROCEDURE_LINKAGE_TABLE_") == 0)
+ return 1;
+
+ return 0;
+}
+
+static void
+arm_netbsd_init_abi_common (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->lowest_pc = 0x8000;
+ tdep->arm_breakpoint = arm_nbsd_arm_le_breakpoint;
+ tdep->arm_breakpoint_size = sizeof (arm_nbsd_arm_le_breakpoint);
+
+ tdep->jb_pc = JB_PC;
+ tdep->jb_elt_size = JB_ELEMENT_SIZE;
+}
+
+static void
+arm_netbsd_aout_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ arm_netbsd_init_abi_common (info, gdbarch);
+
+ set_gdbarch_in_solib_call_trampoline
+ (gdbarch, arm_netbsd_aout_in_solib_call_trampoline);
+ tdep->fp_model = ARM_FLOAT_SOFT;
+}
+
+static void
+arm_netbsd_elf_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ arm_netbsd_init_abi_common (info, gdbarch);
+
+ set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ nbsd_ilp32_solib_svr4_fetch_link_map_offsets);
+
+ tdep->fp_model = ARM_FLOAT_SOFT_VFP;
+}
+
+static enum gdb_osabi
+arm_netbsd_aout_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "a.out-arm-netbsd") == 0)
+ return GDB_OSABI_NETBSD_AOUT;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+void
+_initialize_arm_netbsd_tdep (void)
+{
+ gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_aout_flavour,
+ arm_netbsd_aout_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_arm, GDB_OSABI_NETBSD_AOUT,
+ arm_netbsd_aout_init_abi);
+ gdbarch_register_osabi (bfd_arch_arm, GDB_OSABI_NETBSD_ELF,
+ arm_netbsd_elf_init_abi);
+}
diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c
new file mode 100644
index 00000000000..71c7796443f
--- /dev/null
+++ b/gdb/avr-tdep.c
@@ -0,0 +1,1374 @@
+/* Target-dependent code for Atmel AVR, for GDB.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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. */
+
+/* Contributed by Theodore A. Roth, troth@verinet.com */
+
+/* Portions of this file were taken from the original gdb-4.18 patch developed
+ by Denis Chertykov, denisc@overta.ru */
+
+#include "defs.h"
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "symfile.h"
+#include "arch-utils.h"
+#include "regcache.h"
+
+/* AVR Background:
+
+ (AVR micros are pure Harvard Architecture processors.)
+
+ The AVR family of microcontrollers have three distinctly different memory
+ spaces: flash, sram and eeprom. The flash is 16 bits wide and is used for
+ the most part to store program instructions. The sram is 8 bits wide and is
+ used for the stack and the heap. Some devices lack sram and some can have
+ an additional external sram added on as a peripheral.
+
+ The eeprom is 8 bits wide and is used to store data when the device is
+ powered down. Eeprom is not directly accessible, it can only be accessed
+ via io-registers using a special algorithm. Accessing eeprom via gdb's
+ remote serial protocol ('m' or 'M' packets) looks difficult to do and is
+ not included at this time.
+
+ [The eeprom could be read manually via ``x/b <eaddr + AVR_EMEM_START>'' or
+ written using ``set {unsigned char}<eaddr + AVR_EMEM_START>''. For this to
+ work, the remote target must be able to handle eeprom accesses and perform
+ the address translation.]
+
+ All three memory spaces have physical addresses beginning at 0x0. In
+ addition, the flash is addressed by gcc/binutils/gdb with respect to 8 bit
+ bytes instead of the 16 bit wide words used by the real device for the
+ Program Counter.
+
+ In order for remote targets to work correctly, extra bits must be added to
+ addresses before they are send to the target or received from the target
+ via the remote serial protocol. The extra bits are the MSBs and are used to
+ decode which memory space the address is referring to. */
+
+#undef XMALLOC
+#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
+
+#undef EXTRACT_INSN
+#define EXTRACT_INSN(addr) extract_unsigned_integer(addr,2)
+
+/* Constants: prefixed with AVR_ to avoid name space clashes */
+
+enum
+{
+ AVR_REG_W = 24,
+ AVR_REG_X = 26,
+ AVR_REG_Y = 28,
+ AVR_FP_REGNUM = 28,
+ AVR_REG_Z = 30,
+
+ AVR_SREG_REGNUM = 32,
+ AVR_SP_REGNUM = 33,
+ AVR_PC_REGNUM = 34,
+
+ AVR_NUM_REGS = 32 + 1 /*SREG*/ + 1 /*SP*/ + 1 /*PC*/,
+ AVR_NUM_REG_BYTES = 32 + 1 /*SREG*/ + 2 /*SP*/ + 4 /*PC*/,
+
+ AVR_PC_REG_INDEX = 35, /* index into array of registers */
+
+ AVR_MAX_PROLOGUE_SIZE = 56, /* bytes */
+
+ /* Count of pushed registers. From r2 to r17 (inclusively), r28, r29 */
+ AVR_MAX_PUSHES = 18,
+
+ /* Number of the last pushed register. r17 for current avr-gcc */
+ AVR_LAST_PUSHED_REGNUM = 17,
+
+ /* FIXME: TRoth/2002-01-??: Can we shift all these memory masks left 8
+ bits? Do these have to match the bfd vma values?. It sure would make
+ things easier in the future if they didn't need to match.
+
+ Note: I chose these values so as to be consistent with bfd vma
+ addresses.
+
+ TRoth/2002-04-08: There is already a conflict with very large programs
+ in the mega128. The mega128 has 128K instruction bytes (64K words),
+ thus the Most Significant Bit is 0x10000 which gets masked off my
+ AVR_MEM_MASK.
+
+ The problem manifests itself when trying to set a breakpoint in a
+ function which resides in the upper half of the instruction space and
+ thus requires a 17-bit address.
+
+ For now, I've just removed the EEPROM mask and changed AVR_MEM_MASK
+ from 0x00ff0000 to 0x00f00000. Eeprom is not accessible from gdb yet,
+ but could be for some remote targets by just adding the correct offset
+ to the address and letting the remote target handle the low-level
+ details of actually accessing the eeprom. */
+
+ AVR_IMEM_START = 0x00000000, /* INSN memory */
+ AVR_SMEM_START = 0x00800000, /* SRAM memory */
+#if 1
+ /* No eeprom mask defined */
+ AVR_MEM_MASK = 0x00f00000, /* mask to determine memory space */
+#else
+ AVR_EMEM_START = 0x00810000, /* EEPROM memory */
+ AVR_MEM_MASK = 0x00ff0000, /* mask to determine memory space */
+#endif
+};
+
+/* Any function with a frame looks like this
+ ....... <-SP POINTS HERE
+ LOCALS1 <-FP POINTS HERE
+ LOCALS0
+ SAVED FP
+ SAVED R3
+ SAVED R2
+ RET PC
+ FIRST ARG
+ SECOND ARG */
+
+struct frame_extra_info
+{
+ CORE_ADDR return_pc;
+ CORE_ADDR args_pointer;
+ int locals_size;
+ int framereg;
+ int framesize;
+ int is_main;
+};
+
+struct gdbarch_tdep
+{
+ /* FIXME: TRoth: is there anything to put here? */
+ int foo;
+};
+
+/* Lookup the name of a register given it's number. */
+
+static char *
+avr_register_name (int regnum)
+{
+ static char *register_names[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "SREG", "SP", "PC"
+ };
+ if (regnum < 0)
+ return NULL;
+ if (regnum >= (sizeof (register_names) / sizeof (*register_names)))
+ return NULL;
+ return register_names[regnum];
+}
+
+/* Index within `registers' of the first byte of the space for
+ register REGNUM. */
+
+static int
+avr_register_byte (int regnum)
+{
+ if (regnum < AVR_PC_REGNUM)
+ return regnum;
+ else
+ return AVR_PC_REG_INDEX;
+}
+
+/* Number of bytes of storage in the actual machine representation for
+ register REGNUM. */
+
+static int
+avr_register_raw_size (int regnum)
+{
+ switch (regnum)
+ {
+ case AVR_PC_REGNUM:
+ return 4;
+ case AVR_SP_REGNUM:
+ case AVR_FP_REGNUM:
+ return 2;
+ default:
+ return 1;
+ }
+}
+
+/* Number of bytes of storage in the program's representation
+ for register N. */
+
+static int
+avr_register_virtual_size (int regnum)
+{
+ return TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (regnum));
+}
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+static struct type *
+avr_register_virtual_type (int regnum)
+{
+ switch (regnum)
+ {
+ case AVR_PC_REGNUM:
+ return builtin_type_unsigned_long;
+ case AVR_SP_REGNUM:
+ return builtin_type_unsigned_short;
+ default:
+ return builtin_type_unsigned_char;
+ }
+}
+
+/* Instruction address checks and convertions. */
+
+static CORE_ADDR
+avr_make_iaddr (CORE_ADDR x)
+{
+ return ((x) | AVR_IMEM_START);
+}
+
+static int
+avr_iaddr_p (CORE_ADDR x)
+{
+ return (((x) & AVR_MEM_MASK) == AVR_IMEM_START);
+}
+
+/* FIXME: TRoth: Really need to use a larger mask for instructions. Some
+ devices are already up to 128KBytes of flash space.
+
+ TRoth/2002-04-8: See comment above where AVR_IMEM_START is defined. */
+
+static CORE_ADDR
+avr_convert_iaddr_to_raw (CORE_ADDR x)
+{
+ return ((x) & 0xffffffff);
+}
+
+/* SRAM address checks and convertions. */
+
+static CORE_ADDR
+avr_make_saddr (CORE_ADDR x)
+{
+ return ((x) | AVR_SMEM_START);
+}
+
+static int
+avr_saddr_p (CORE_ADDR x)
+{
+ return (((x) & AVR_MEM_MASK) == AVR_SMEM_START);
+}
+
+static CORE_ADDR
+avr_convert_saddr_to_raw (CORE_ADDR x)
+{
+ return ((x) & 0xffffffff);
+}
+
+/* EEPROM address checks and convertions. I don't know if these will ever
+ actually be used, but I've added them just the same. TRoth */
+
+/* TRoth/2002-04-08: Commented out for now to allow fix for problem with large
+ programs in the mega128. */
+
+/* static CORE_ADDR */
+/* avr_make_eaddr (CORE_ADDR x) */
+/* { */
+/* return ((x) | AVR_EMEM_START); */
+/* } */
+
+/* static int */
+/* avr_eaddr_p (CORE_ADDR x) */
+/* { */
+/* return (((x) & AVR_MEM_MASK) == AVR_EMEM_START); */
+/* } */
+
+/* static CORE_ADDR */
+/* avr_convert_eaddr_to_raw (CORE_ADDR x) */
+/* { */
+/* return ((x) & 0xffffffff); */
+/* } */
+
+/* Convert from address to pointer and vice-versa. */
+
+static void
+avr_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr)
+{
+ /* Is it a code address? */
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
+ || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
+ {
+ store_unsigned_integer (buf, TYPE_LENGTH (type),
+ avr_convert_iaddr_to_raw (addr));
+ }
+ else
+ {
+ /* Strip off any upper segment bits. */
+ store_unsigned_integer (buf, TYPE_LENGTH (type),
+ avr_convert_saddr_to_raw (addr));
+ }
+}
+
+static CORE_ADDR
+avr_pointer_to_address (struct type *type, void *buf)
+{
+ CORE_ADDR addr = extract_address (buf, TYPE_LENGTH (type));
+
+ if (TYPE_CODE_SPACE (TYPE_TARGET_TYPE (type)))
+ {
+ fprintf_unfiltered (gdb_stderr, "CODE_SPACE ---->> ptr->addr: 0x%lx\n",
+ addr);
+ fprintf_unfiltered (gdb_stderr,
+ "+++ If you see this, please send me an email <troth@verinet.com>\n");
+ }
+
+ /* Is it a code address? */
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
+ || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD
+ || TYPE_CODE_SPACE (TYPE_TARGET_TYPE (type)))
+ return avr_make_iaddr (addr);
+ else
+ return avr_make_saddr (addr);
+}
+
+static CORE_ADDR
+avr_read_pc (ptid_t ptid)
+{
+ ptid_t save_ptid;
+ CORE_ADDR pc;
+ CORE_ADDR retval;
+
+ save_ptid = inferior_ptid;
+ inferior_ptid = ptid;
+ pc = (int) read_register (AVR_PC_REGNUM);
+ inferior_ptid = save_ptid;
+ retval = avr_make_iaddr (pc);
+ return retval;
+}
+
+static void
+avr_write_pc (CORE_ADDR val, ptid_t ptid)
+{
+ ptid_t save_ptid;
+
+ save_ptid = inferior_ptid;
+ inferior_ptid = ptid;
+ write_register (AVR_PC_REGNUM, avr_convert_iaddr_to_raw (val));
+ inferior_ptid = save_ptid;
+}
+
+static CORE_ADDR
+avr_read_sp (void)
+{
+ return (avr_make_saddr (read_register (AVR_SP_REGNUM)));
+}
+
+static void
+avr_write_sp (CORE_ADDR val)
+{
+ write_register (AVR_SP_REGNUM, avr_convert_saddr_to_raw (val));
+}
+
+static CORE_ADDR
+avr_read_fp (void)
+{
+ return (avr_make_saddr (read_register (AVR_FP_REGNUM)));
+}
+
+/* Translate a GDB virtual ADDR/LEN into a format the remote target
+ understands. Returns number of bytes that can be transfered
+ starting at TARG_ADDR. Return ZERO if no bytes can be transfered
+ (segmentation fault).
+
+ TRoth/2002-04-08: Could this be used to check for dereferencing an invalid
+ pointer? */
+
+static void
+avr_remote_translate_xfer_address (CORE_ADDR memaddr, int nr_bytes,
+ CORE_ADDR *targ_addr, int *targ_len)
+{
+ long out_addr;
+ long out_len;
+
+ /* FIXME: TRoth: Do nothing for now. Will need to examine memaddr at this
+ point and see if the high bit are set with the masks that we want. */
+
+ *targ_addr = memaddr;
+ *targ_len = nr_bytes;
+}
+
+/* Function pointers obtained from the target are half of what gdb expects so
+ multiply by 2. */
+
+static CORE_ADDR
+avr_convert_from_func_ptr_addr (CORE_ADDR addr)
+{
+ return addr * 2;
+}
+
+/* avr_scan_prologue is also used as the frame_init_saved_regs().
+
+ Put here the code to store, into fi->saved_regs, the addresses of
+ the saved registers of frame described by FRAME_INFO. This
+ includes special registers such as pc and fp saved in special ways
+ in the stack frame. sp is even more special: the address we return
+ for it IS the sp for the next frame. */
+
+/* Function: avr_scan_prologue (helper function for avr_init_extra_frame_info)
+ This function decodes a AVR function prologue to determine:
+ 1) the size of the stack frame
+ 2) which registers are saved on it
+ 3) the offsets of saved regs
+ This information is stored in the "extra_info" field of the frame_info.
+
+ A typical AVR function prologue might look like this:
+ push rXX
+ push r28
+ push r29
+ in r28,__SP_L__
+ in r29,__SP_H__
+ sbiw r28,<LOCALS_SIZE>
+ in __tmp_reg__,__SREG__
+ cli
+ out __SP_L__,r28
+ out __SREG__,__tmp_reg__
+ out __SP_H__,r29
+
+ A `-mcall-prologues' prologue look like this:
+ ldi r26,<LOCALS_SIZE>
+ ldi r27,<LOCALS_SIZE>/265
+ ldi r30,pm_lo8(.L_foo_body)
+ ldi r31,pm_hi8(.L_foo_body)
+ rjmp __prologue_saves__+RRR
+ .L_foo_body: */
+
+static void
+avr_scan_prologue (struct frame_info *fi)
+{
+ CORE_ADDR prologue_start;
+ CORE_ADDR prologue_end;
+ int i;
+ unsigned short insn;
+ int regno;
+ int scan_stage = 0;
+ char *name;
+ struct minimal_symbol *msymbol;
+ int prologue_len;
+ unsigned char prologue[AVR_MAX_PROLOGUE_SIZE];
+ int vpc = 0;
+
+ fi->extra_info->framereg = AVR_SP_REGNUM;
+
+ if (find_pc_partial_function
+ (fi->pc, &name, &prologue_start, &prologue_end))
+ {
+ struct symtab_and_line sal = find_pc_line (prologue_start, 0);
+
+ if (sal.line == 0) /* no line info, use current PC */
+ prologue_end = fi->pc;
+ else if (sal.end < prologue_end) /* next line begins after fn end */
+ prologue_end = sal.end; /* (probably means no prologue) */
+ }
+ else
+ /* We're in the boondocks: allow for */
+ /* 19 pushes, an add, and "mv fp,sp" */
+ prologue_end = prologue_start + AVR_MAX_PROLOGUE_SIZE;
+
+ prologue_end = min (prologue_end, fi->pc);
+
+ /* Search the prologue looking for instructions that set up the
+ frame pointer, adjust the stack pointer, and save registers. */
+
+ fi->extra_info->framesize = 0;
+ prologue_len = prologue_end - prologue_start;
+ read_memory (prologue_start, prologue, prologue_len);
+
+ /* Scanning main()'s prologue
+ ldi r28,lo8(<RAM_ADDR> - <LOCALS_SIZE>)
+ ldi r29,hi8(<RAM_ADDR> - <LOCALS_SIZE>)
+ out __SP_H__,r29
+ out __SP_L__,r28 */
+
+ if (name && strcmp ("main", name) == 0 && prologue_len == 8)
+ {
+ CORE_ADDR locals;
+ unsigned char img[] = {
+ 0xde, 0xbf, /* out __SP_H__,r29 */
+ 0xcd, 0xbf /* out __SP_L__,r28 */
+ };
+
+ fi->extra_info->framereg = AVR_FP_REGNUM;
+ insn = EXTRACT_INSN (&prologue[vpc]);
+ /* ldi r28,lo8(<RAM_ADDR> - <LOCALS_SIZE>) */
+ if ((insn & 0xf0f0) == 0xe0c0)
+ {
+ locals = (insn & 0xf) | ((insn & 0x0f00) >> 4);
+ insn = EXTRACT_INSN (&prologue[vpc + 2]);
+ /* ldi r29,hi8(<RAM_ADDR> - <LOCALS_SIZE>) */
+ if ((insn & 0xf0f0) == 0xe0d0)
+ {
+ locals |= ((insn & 0xf) | ((insn & 0x0f00) >> 4)) << 8;
+ if (memcmp (prologue + vpc + 4, img, sizeof (img)) == 0)
+ {
+ fi->frame = locals;
+
+ /* TRoth: Does -1 mean we're in main? */
+ fi->extra_info->is_main = 1;
+ return;
+ }
+ }
+ }
+ }
+
+ /* Scanning `-mcall-prologues' prologue
+ FIXME: mega prologue have a 12 bytes long */
+
+ while (prologue_len <= 12) /* I'm use while to avoit many goto's */
+ {
+ int loc_size;
+ int body_addr;
+ unsigned num_pushes;
+
+ insn = EXTRACT_INSN (&prologue[vpc]);
+ /* ldi r26,<LOCALS_SIZE> */
+ if ((insn & 0xf0f0) != 0xe0a0)
+ break;
+ loc_size = (insn & 0xf) | ((insn & 0x0f00) >> 4);
+
+ insn = EXTRACT_INSN (&prologue[vpc + 2]);
+ /* ldi r27,<LOCALS_SIZE> / 256 */
+ if ((insn & 0xf0f0) != 0xe0b0)
+ break;
+ loc_size |= ((insn & 0xf) | ((insn & 0x0f00) >> 4)) << 8;
+
+ insn = EXTRACT_INSN (&prologue[vpc + 4]);
+ /* ldi r30,pm_lo8(.L_foo_body) */
+ if ((insn & 0xf0f0) != 0xe0e0)
+ break;
+ body_addr = (insn & 0xf) | ((insn & 0x0f00) >> 4);
+
+ insn = EXTRACT_INSN (&prologue[vpc + 6]);
+ /* ldi r31,pm_hi8(.L_foo_body) */
+ if ((insn & 0xf0f0) != 0xe0f0)
+ break;
+ body_addr |= ((insn & 0xf) | ((insn & 0x0f00) >> 4)) << 8;
+
+ if (body_addr != (prologue_start + 10) / 2)
+ break;
+
+ msymbol = lookup_minimal_symbol ("__prologue_saves__", NULL, NULL);
+ if (!msymbol)
+ break;
+
+ /* FIXME: prologue for mega have a JMP instead of RJMP */
+ insn = EXTRACT_INSN (&prologue[vpc + 8]);
+ /* rjmp __prologue_saves__+RRR */
+ if ((insn & 0xf000) != 0xc000)
+ break;
+
+ /* Extract PC relative offset from RJMP */
+ i = (insn & 0xfff) | (insn & 0x800 ? (-1 ^ 0xfff) : 0);
+ /* Convert offset to byte addressable mode */
+ i *= 2;
+ /* Destination address */
+ i += vpc + prologue_start + 10;
+ /* Resovle offset (in words) from __prologue_saves__ symbol.
+ Which is a pushes count in `-mcall-prologues' mode */
+ num_pushes = AVR_MAX_PUSHES - (i - SYMBOL_VALUE_ADDRESS (msymbol)) / 2;
+
+ if (num_pushes > AVR_MAX_PUSHES)
+ num_pushes = 0;
+
+ if (num_pushes)
+ {
+ int from;
+ fi->saved_regs[AVR_FP_REGNUM + 1] = num_pushes;
+ if (num_pushes >= 2)
+ fi->saved_regs[AVR_FP_REGNUM] = num_pushes - 1;
+ i = 0;
+ for (from = AVR_LAST_PUSHED_REGNUM + 1 - (num_pushes - 2);
+ from <= AVR_LAST_PUSHED_REGNUM; ++from)
+ fi->saved_regs[from] = ++i;
+ }
+ fi->extra_info->locals_size = loc_size;
+ fi->extra_info->framesize = loc_size + num_pushes;
+ fi->extra_info->framereg = AVR_FP_REGNUM;
+ return;
+ }
+
+ /* Scan interrupt or signal function */
+
+ if (prologue_len >= 12)
+ {
+ unsigned char img[] = {
+ 0x78, 0x94, /* sei */
+ 0x1f, 0x92, /* push r1 */
+ 0x0f, 0x92, /* push r0 */
+ 0x0f, 0xb6, /* in r0,0x3f SREG */
+ 0x0f, 0x92, /* push r0 */
+ 0x11, 0x24 /* clr r1 */
+ };
+ if (memcmp (prologue, img, sizeof (img)) == 0)
+ {
+ vpc += sizeof (img);
+ fi->saved_regs[0] = 2;
+ fi->saved_regs[1] = 1;
+ fi->extra_info->framesize += 3;
+ }
+ else if (memcmp (img + 1, prologue, sizeof (img) - 1) == 0)
+ {
+ vpc += sizeof (img) - 1;
+ fi->saved_regs[0] = 2;
+ fi->saved_regs[1] = 1;
+ fi->extra_info->framesize += 3;
+ }
+ }
+
+ /* First stage of the prologue scanning.
+ Scan pushes */
+
+ for (; vpc <= prologue_len; vpc += 2)
+ {
+ insn = EXTRACT_INSN (&prologue[vpc]);
+ if ((insn & 0xfe0f) == 0x920f) /* push rXX */
+ {
+ /* Bits 4-9 contain a mask for registers R0-R32. */
+ regno = (insn & 0x1f0) >> 4;
+ ++fi->extra_info->framesize;
+ fi->saved_regs[regno] = fi->extra_info->framesize;
+ scan_stage = 1;
+ }
+ else
+ break;
+ }
+
+ /* Second stage of the prologue scanning.
+ Scan:
+ in r28,__SP_L__
+ in r29,__SP_H__ */
+
+ if (scan_stage == 1 && vpc + 4 <= prologue_len)
+ {
+ unsigned char img[] = {
+ 0xcd, 0xb7, /* in r28,__SP_L__ */
+ 0xde, 0xb7 /* in r29,__SP_H__ */
+ };
+ unsigned short insn1;
+
+ if (memcmp (prologue + vpc, img, sizeof (img)) == 0)
+ {
+ vpc += 4;
+ fi->extra_info->framereg = AVR_FP_REGNUM;
+ scan_stage = 2;
+ }
+ }
+
+ /* Third stage of the prologue scanning. (Really two stages)
+ Scan for:
+ sbiw r28,XX or subi r28,lo8(XX)
+ sbci r29,hi8(XX)
+ in __tmp_reg__,__SREG__
+ cli
+ out __SP_L__,r28
+ out __SREG__,__tmp_reg__
+ out __SP_H__,r29 */
+
+ if (scan_stage == 2 && vpc + 12 <= prologue_len)
+ {
+ int locals_size = 0;
+ unsigned char img[] = {
+ 0x0f, 0xb6, /* in r0,0x3f */
+ 0xf8, 0x94, /* cli */
+ 0xcd, 0xbf, /* out 0x3d,r28 ; SPL */
+ 0x0f, 0xbe, /* out 0x3f,r0 ; SREG */
+ 0xde, 0xbf /* out 0x3e,r29 ; SPH */
+ };
+ unsigned char img_sig[] = {
+ 0xcd, 0xbf, /* out 0x3d,r28 ; SPL */
+ 0xde, 0xbf /* out 0x3e,r29 ; SPH */
+ };
+ unsigned char img_int[] = {
+ 0xf8, 0x94, /* cli */
+ 0xcd, 0xbf, /* out 0x3d,r28 ; SPL */
+ 0x78, 0x94, /* sei */
+ 0xde, 0xbf /* out 0x3e,r29 ; SPH */
+ };
+
+ insn = EXTRACT_INSN (&prologue[vpc]);
+ vpc += 2;
+ if ((insn & 0xff30) == 0x9720) /* sbiw r28,XXX */
+ locals_size = (insn & 0xf) | ((insn & 0xc0) >> 2);
+ else if ((insn & 0xf0f0) == 0x50c0) /* subi r28,lo8(XX) */
+ {
+ locals_size = (insn & 0xf) | ((insn & 0xf00) >> 4);
+ insn = EXTRACT_INSN (&prologue[vpc]);
+ vpc += 2;
+ locals_size += ((insn & 0xf) | ((insn & 0xf00) >> 4) << 8);
+ }
+ else
+ return;
+ fi->extra_info->locals_size = locals_size;
+ fi->extra_info->framesize += locals_size;
+ }
+}
+
+/* This function actually figures out the frame address for a given pc and
+ sp. This is tricky because we sometimes don't use an explicit
+ frame pointer, and the previous stack pointer isn't necessarily recorded
+ on the stack. The only reliable way to get this info is to
+ examine the prologue. */
+
+static void
+avr_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ int reg;
+
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ fi->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+ frame_saved_regs_zalloc (fi);
+
+ fi->extra_info->return_pc = 0;
+ fi->extra_info->args_pointer = 0;
+ fi->extra_info->locals_size = 0;
+ fi->extra_info->framereg = 0;
+ fi->extra_info->framesize = 0;
+ fi->extra_info->is_main = 0;
+
+ avr_scan_prologue (fi);
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ /* We need to setup fi->frame here because run_stack_dummy gets it wrong
+ by assuming it's always FP. */
+ fi->frame = generic_read_register_dummy (fi->pc, fi->frame, fi->frame);
+ }
+ else if (!fi->next) /* this is the innermost frame? */
+ fi->frame = read_register (fi->extra_info->framereg);
+ else if (fi->extra_info->is_main != 1) /* not the innermost frame, not `main' */
+ /* If we have an next frame, the callee saved it. */
+ {
+ struct frame_info *next_fi = fi->next;
+ if (fi->extra_info->framereg == AVR_SP_REGNUM)
+ fi->frame =
+ next_fi->frame + 2 /* ret addr */ + next_fi->extra_info->framesize;
+ /* FIXME: I don't analyse va_args functions */
+ else
+ {
+ CORE_ADDR fp = 0;
+ CORE_ADDR fp1 = 0;
+ unsigned int fp_low, fp_high;
+
+ /* Scan all frames */
+ for (; next_fi; next_fi = next_fi->next)
+ {
+ /* look for saved AVR_FP_REGNUM */
+ if (next_fi->saved_regs[AVR_FP_REGNUM] && !fp)
+ fp = next_fi->saved_regs[AVR_FP_REGNUM];
+ /* look for saved AVR_FP_REGNUM + 1 */
+ if (next_fi->saved_regs[AVR_FP_REGNUM + 1] && !fp1)
+ fp1 = next_fi->saved_regs[AVR_FP_REGNUM + 1];
+ }
+ fp_low = (fp ? read_memory_unsigned_integer (avr_make_saddr (fp), 1)
+ : read_register (AVR_FP_REGNUM)) & 0xff;
+ fp_high =
+ (fp1 ? read_memory_unsigned_integer (avr_make_saddr (fp1), 1) :
+ read_register (AVR_FP_REGNUM + 1)) & 0xff;
+ fi->frame = fp_low | (fp_high << 8);
+ }
+ }
+
+ /* TRoth: Do we want to do this if we are in main? I don't think we should
+ since return_pc makes no sense when we are in main. */
+
+ if ((fi->pc) && (fi->extra_info->is_main == 0)) /* We are not in CALL_DUMMY */
+ {
+ CORE_ADDR addr;
+ int i;
+
+ addr = fi->frame + fi->extra_info->framesize + 1;
+
+ /* Return address in stack in different endianness */
+
+ fi->extra_info->return_pc =
+ read_memory_unsigned_integer (avr_make_saddr (addr), 1) << 8;
+ fi->extra_info->return_pc |=
+ read_memory_unsigned_integer (avr_make_saddr (addr + 1), 1);
+
+ /* This return address in words,
+ must be converted to the bytes address */
+ fi->extra_info->return_pc *= 2;
+
+ /* Resolve a pushed registers addresses */
+ for (i = 0; i < NUM_REGS; i++)
+ {
+ if (fi->saved_regs[i])
+ fi->saved_regs[i] = addr - fi->saved_regs[i];
+ }
+ }
+}
+
+/* Restore the machine to the state it had before the current frame was
+ created. Usually used either by the "RETURN" command, or by
+ call_function_by_hand after the dummy_frame is finished. */
+
+static void
+avr_pop_frame (void)
+{
+ unsigned regnum;
+ CORE_ADDR saddr;
+ struct frame_info *frame = get_current_frame ();
+
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ {
+ generic_pop_dummy_frame ();
+ }
+ else
+ {
+ /* TRoth: Why only loop over 8 registers? */
+
+ for (regnum = 0; regnum < 8; regnum++)
+ {
+ /* Don't forget AVR_SP_REGNUM in a frame_saved_regs struct is the
+ actual value we want, not the address of the value we want. */
+ if (frame->saved_regs[regnum] && regnum != AVR_SP_REGNUM)
+ {
+ saddr = avr_make_saddr (frame->saved_regs[regnum]);
+ write_register (regnum,
+ read_memory_unsigned_integer (saddr, 1));
+ }
+ else if (frame->saved_regs[regnum] && regnum == AVR_SP_REGNUM)
+ write_register (regnum, frame->frame + 2);
+ }
+
+ /* Don't forget the update the PC too! */
+ write_pc (frame->extra_info->return_pc);
+ }
+ flush_cached_frames ();
+}
+
+/* Return the saved PC from this frame. */
+
+static CORE_ADDR
+avr_frame_saved_pc (struct frame_info *frame)
+{
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ return generic_read_register_dummy (frame->pc, frame->frame,
+ AVR_PC_REGNUM);
+ else
+ return frame->extra_info->return_pc;
+}
+
+static CORE_ADDR
+avr_saved_pc_after_call (struct frame_info *frame)
+{
+ unsigned char m1, m2;
+ unsigned int sp = read_register (AVR_SP_REGNUM);
+ m1 = read_memory_unsigned_integer (avr_make_saddr (sp + 1), 1);
+ m2 = read_memory_unsigned_integer (avr_make_saddr (sp + 2), 1);
+ return (m2 | (m1 << 8)) * 2;
+}
+
+/* Figure out where in REGBUF the called function has left its return value.
+ Copy that into VALBUF. */
+
+static void
+avr_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ int wordsize, len;
+
+ wordsize = 2;
+
+ len = TYPE_LENGTH (type);
+
+ switch (len)
+ {
+ case 1: /* (char) */
+ case 2: /* (short), (int) */
+ memcpy (valbuf, regbuf + REGISTER_BYTE (24), 2);
+ break;
+ case 4: /* (long), (float) */
+ memcpy (valbuf, regbuf + REGISTER_BYTE (22), 4);
+ break;
+ case 8: /* (double) (doesn't seem to happen, which is good,
+ because this almost certainly isn't right. */
+ error ("I don't know how a double is returned.");
+ break;
+ }
+}
+
+/* Returns the return address for a dummy. */
+
+static CORE_ADDR
+avr_call_dummy_address (void)
+{
+ return entry_point_address ();
+}
+
+/* Place the appropriate value in the appropriate registers.
+ Primarily used by the RETURN command. */
+
+static void
+avr_store_return_value (struct type *type, char *valbuf)
+{
+ int wordsize, len, regval;
+
+ wordsize = 2;
+
+ len = TYPE_LENGTH (type);
+ switch (len)
+ {
+ case 1: /* char */
+ case 2: /* short, int */
+ regval = extract_address (valbuf, len);
+ write_register (0, regval);
+ break;
+ case 4: /* long, float */
+ regval = extract_address (valbuf, len);
+ write_register (0, regval >> 16);
+ write_register (1, regval & 0xffff);
+ break;
+ case 8: /* presumeably double, but doesn't seem to happen */
+ error ("I don't know how to return a double.");
+ break;
+ }
+}
+
+/* Setup the return address for a dummy frame, as called by
+ call_function_by_hand. Only necessary when you are using an empty
+ CALL_DUMMY. */
+
+static CORE_ADDR
+avr_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ unsigned char buf[2];
+ int wordsize = 2;
+ struct minimal_symbol *msymbol;
+ CORE_ADDR mon_brk;
+
+ fprintf_unfiltered (gdb_stderr, "avr_push_return_address() was called\n");
+
+ buf[0] = 0;
+ buf[1] = 0;
+ sp -= wordsize;
+ write_memory (sp + 1, buf, 2);
+
+#if 0
+ /* FIXME: TRoth/2002-02-18: This should probably be removed since it's a
+ left-over from Denis' original patch which used avr-mon for the target
+ instead of the generic remote target. */
+ if ((strcmp (target_shortname, "avr-mon") == 0)
+ && (msymbol = lookup_minimal_symbol ("gdb_break", NULL, NULL)))
+ {
+ mon_brk = SYMBOL_VALUE_ADDRESS (msymbol);
+ store_unsigned_integer (buf, wordsize, mon_brk / 2);
+ sp -= wordsize;
+ write_memory (sp + 1, buf + 1, 1);
+ write_memory (sp + 2, buf, 1);
+ }
+#endif
+ return sp;
+}
+
+static CORE_ADDR
+avr_skip_prologue (CORE_ADDR pc)
+{
+ CORE_ADDR func_addr, func_end;
+ struct symtab_and_line sal;
+
+ /* See what the symbol table says */
+
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ sal = find_pc_line (func_addr, 0);
+
+ if (sal.line != 0 && sal.end < func_end)
+ return sal.end;
+ }
+
+/* Either we didn't find the start of this function (nothing we can do),
+ or there's no line info, or the line after the prologue is after
+ the end of the function (there probably isn't a prologue). */
+
+ return pc;
+}
+
+static CORE_ADDR
+avr_frame_address (struct frame_info *fi)
+{
+ return avr_make_saddr (fi->frame);
+}
+
+/* Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+
+ For us, the frame address is its stack pointer value, so we look up
+ the function prologue to determine the caller's sp value, and return it. */
+
+static CORE_ADDR
+avr_frame_chain (struct frame_info *frame)
+{
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ {
+ /* initialize the return_pc now */
+ frame->extra_info->return_pc = generic_read_register_dummy (frame->pc,
+ frame->
+ frame,
+ AVR_PC_REGNUM);
+ return frame->frame;
+ }
+ return (frame->extra_info->is_main ? 0
+ : frame->frame + frame->extra_info->framesize + 2 /* ret addr */ );
+}
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function.
+
+ We store structs through a pointer passed in the first Argument
+ register. */
+
+static void
+avr_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ write_register (0, addr);
+}
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+
+static CORE_ADDR
+avr_extract_struct_value_address (char *regbuf)
+{
+ return (extract_address ((regbuf) + REGISTER_BYTE (0),
+ REGISTER_RAW_SIZE (0)) | AVR_SMEM_START);
+}
+
+/* Setup the function arguments for calling a function in the inferior.
+
+ On the AVR architecture, there are 18 registers (R25 to R8) which are
+ dedicated for passing function arguments. Up to the first 18 arguments
+ (depending on size) may go into these registers. The rest go on the stack.
+
+ Arguments that are larger than WORDSIZE bytes will be split between two or
+ more registers as available, but will NOT be split between a register and
+ the stack.
+
+ An exceptional case exists for struct arguments (and possibly other
+ aggregates such as arrays) -- if the size is larger than WORDSIZE bytes but
+ not a multiple of WORDSIZE bytes. In this case the argument is never split
+ between the registers and the stack, but instead is copied in its entirety
+ onto the stack, AND also copied into as many registers as there is room
+ for. In other words, space in registers permitting, two copies of the same
+ argument are passed in. As far as I can tell, only the one on the stack is
+ used, although that may be a function of the level of compiler
+ optimization. I suspect this is a compiler bug. Arguments of these odd
+ sizes are left-justified within the word (as opposed to arguments smaller
+ than WORDSIZE bytes, which are right-justified).
+
+ If the function is to return an aggregate type such as a struct, the caller
+ must allocate space into which the callee will copy the return value. In
+ this case, a pointer to the return value location is passed into the callee
+ in register R0, which displaces one of the other arguments passed in via
+ registers R0 to R2. */
+
+static CORE_ADDR
+avr_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int stack_alloc, stack_offset;
+ int wordsize;
+ int argreg;
+ int argnum;
+ struct type *type;
+ CORE_ADDR regval;
+ char *val;
+ char valbuf[4];
+ int len;
+
+ wordsize = 1;
+#if 0
+ /* Now make sure there's space on the stack */
+ for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
+ stack_alloc += TYPE_LENGTH (VALUE_TYPE (args[argnum]));
+ sp -= stack_alloc; /* make room on stack for args */
+ /* we may over-allocate a little here, but that won't hurt anything */
+#endif
+ argreg = 25;
+ if (struct_return) /* "struct return" pointer takes up one argreg */
+ {
+ write_register (--argreg, struct_addr);
+ }
+
+ /* Now load as many as possible of the first arguments into registers, and
+ push the rest onto the stack. There are 3N bytes in three registers
+ available. Loop thru args from first to last. */
+
+ for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
+ {
+ type = VALUE_TYPE (args[argnum]);
+ len = TYPE_LENGTH (type);
+ val = (char *) VALUE_CONTENTS (args[argnum]);
+
+ /* NOTE WELL!!!!! This is not an "else if" clause!!! That's because
+ some *&^%$ things get passed on the stack AND in the registers! */
+ while (len > 0)
+ { /* there's room in registers */
+ len -= wordsize;
+ regval = extract_address (val + len, wordsize);
+ write_register (argreg--, regval);
+ }
+ }
+ return sp;
+}
+
+/* Initialize the gdbarch structure for the AVR's. */
+
+static struct gdbarch *
+avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ /* FIXME: TRoth/2002-02-18: I have no idea if avr_call_dummy_words[] should
+ be bigger or not. Initial testing seems to show that `call my_func()`
+ works and backtrace from a breakpoint within the call looks correct.
+ Admittedly, I haven't tested with more than a very simple program. */
+ static LONGEST avr_call_dummy_words[] = { 0 };
+
+ struct gdbarch *gdbarch;
+ struct gdbarch_tdep *tdep;
+
+ /* Find a candidate among the list of pre-declared architectures. */
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+ if (arches != NULL)
+ return arches->gdbarch;
+
+ /* None found, create a new architecture from the information provided. */
+ tdep = XMALLOC (struct gdbarch_tdep);
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ /* If we ever need to differentiate the device types, do it here. */
+ switch (info.bfd_arch_info->mach)
+ {
+ case bfd_mach_avr1:
+ case bfd_mach_avr2:
+ case bfd_mach_avr3:
+ case bfd_mach_avr4:
+ case bfd_mach_avr5:
+ break;
+ }
+
+ set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+ set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_addr_bit (gdbarch, 32);
+ set_gdbarch_bfd_vma_bit (gdbarch, 32); /* FIXME: TRoth/2002-02-18: Is this needed? */
+
+ set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_long_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+
+ set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
+ set_gdbarch_double_format (gdbarch, &floatformat_ieee_single_little);
+ set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_single_little);
+
+ set_gdbarch_read_pc (gdbarch, avr_read_pc);
+ set_gdbarch_write_pc (gdbarch, avr_write_pc);
+ set_gdbarch_read_fp (gdbarch, avr_read_fp);
+ set_gdbarch_read_sp (gdbarch, avr_read_sp);
+ set_gdbarch_write_sp (gdbarch, avr_write_sp);
+
+ set_gdbarch_num_regs (gdbarch, AVR_NUM_REGS);
+
+ set_gdbarch_sp_regnum (gdbarch, AVR_SP_REGNUM);
+ set_gdbarch_fp_regnum (gdbarch, AVR_FP_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, AVR_PC_REGNUM);
+
+ set_gdbarch_register_name (gdbarch, avr_register_name);
+ set_gdbarch_register_size (gdbarch, 1);
+ set_gdbarch_register_bytes (gdbarch, AVR_NUM_REG_BYTES);
+ set_gdbarch_register_byte (gdbarch, avr_register_byte);
+ set_gdbarch_register_raw_size (gdbarch, avr_register_raw_size);
+ set_gdbarch_max_register_raw_size (gdbarch, 4);
+ set_gdbarch_register_virtual_size (gdbarch, avr_register_virtual_size);
+ set_gdbarch_max_register_virtual_size (gdbarch, 4);
+ set_gdbarch_register_virtual_type (gdbarch, avr_register_virtual_type);
+
+ /* We might need to define our own here or define FRAME_INIT_SAVED_REGS */
+ set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+
+ set_gdbarch_print_insn (gdbarch, print_insn_avr);
+
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_address (gdbarch, avr_call_dummy_address);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_words (gdbarch, avr_call_dummy_words);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
+
+/* set_gdbarch_believe_pcc_promotion (gdbarch, 1); // TRoth: should this be set? */
+
+ set_gdbarch_address_to_pointer (gdbarch, avr_address_to_pointer);
+ set_gdbarch_pointer_to_address (gdbarch, avr_pointer_to_address);
+ set_gdbarch_extract_return_value (gdbarch, avr_extract_return_value);
+ set_gdbarch_push_arguments (gdbarch, avr_push_arguments);
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+/* set_gdbarch_push_return_address (gdbarch, avr_push_return_address); */
+ set_gdbarch_pop_frame (gdbarch, avr_pop_frame);
+
+ set_gdbarch_store_return_value (gdbarch, avr_store_return_value);
+
+ set_gdbarch_use_struct_convention (gdbarch, generic_use_struct_convention);
+ set_gdbarch_store_struct_return (gdbarch, avr_store_struct_return);
+ set_gdbarch_extract_struct_value_address (gdbarch,
+ avr_extract_struct_value_address);
+
+ set_gdbarch_frame_init_saved_regs (gdbarch, avr_scan_prologue);
+ set_gdbarch_init_extra_frame_info (gdbarch, avr_init_extra_frame_info);
+ set_gdbarch_skip_prologue (gdbarch, avr_skip_prologue);
+/* set_gdbarch_prologue_frameless_p (gdbarch, avr_prologue_frameless_p); */
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+
+ set_gdbarch_function_start_offset (gdbarch, 0);
+ set_gdbarch_remote_translate_xfer_address (gdbarch,
+ avr_remote_translate_xfer_address);
+ set_gdbarch_frame_args_skip (gdbarch, 0);
+ set_gdbarch_frameless_function_invocation (gdbarch, frameless_look_for_prologue); /* ??? */
+ set_gdbarch_frame_chain (gdbarch, avr_frame_chain);
+ set_gdbarch_frame_chain_valid (gdbarch, generic_func_frame_chain_valid);
+ set_gdbarch_frame_saved_pc (gdbarch, avr_frame_saved_pc);
+ set_gdbarch_frame_args_address (gdbarch, avr_frame_address);
+ set_gdbarch_frame_locals_address (gdbarch, avr_frame_address);
+ set_gdbarch_saved_pc_after_call (gdbarch, avr_saved_pc_after_call);
+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+
+ set_gdbarch_convert_from_func_ptr_addr (gdbarch,
+ avr_convert_from_func_ptr_addr);
+
+ return gdbarch;
+}
+
+/* Send a query request to the avr remote target asking for values of the io
+ registers. If args parameter is not NULL, then the user has requested info
+ on a specific io register [This still needs implemented and is ignored for
+ now]. The query string should be one of these forms:
+
+ "Ravr.io_reg" -> reply is "NN" number of io registers
+
+ "Ravr.io_reg:addr,len" where addr is first register and len is number of
+ registers to be read. The reply should be "<NAME>,VV;" for each io register
+ where, <NAME> is a string, and VV is the hex value of the register.
+
+ All io registers are 8-bit. */
+
+static void
+avr_io_reg_read_command (char *args, int from_tty)
+{
+ int bufsiz = 0;
+ char buf[400];
+ char query[400];
+ char *p;
+ unsigned int nreg = 0;
+ unsigned int val;
+ int i, j, k, step;
+
+/* fprintf_unfiltered (gdb_stderr, "DEBUG: avr_io_reg_read_command (\"%s\", %d)\n", */
+/* args, from_tty); */
+
+ if (!current_target.to_query)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "ERR: info io_registers NOT supported by current target\n");
+ return;
+ }
+
+ /* Just get the maximum buffer size. */
+ target_query ((int) 'R', 0, 0, &bufsiz);
+ if (bufsiz > sizeof (buf))
+ bufsiz = sizeof (buf);
+
+ /* Find out how many io registers the target has. */
+ strcpy (query, "avr.io_reg");
+ target_query ((int) 'R', query, buf, &bufsiz);
+
+ if (strncmp (buf, "", bufsiz) == 0)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "info io_registers NOT supported by target\n");
+ return;
+ }
+
+ if (sscanf (buf, "%x", &nreg) != 1)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "Error fetching number of io registers\n");
+ return;
+ }
+
+ reinitialize_more_filter ();
+
+ printf_unfiltered ("Target has %u io registers:\n\n", nreg);
+
+ /* only fetch up to 8 registers at a time to keep the buffer small */
+ step = 8;
+
+ for (i = 0; i < nreg; i += step)
+ {
+ j = step - (nreg % step); /* how many registers this round? */
+
+ snprintf (query, sizeof (query) - 1, "avr.io_reg:%x,%x", i, j);
+ target_query ((int) 'R', query, buf, &bufsiz);
+
+ p = buf;
+ for (k = i; k < (i + j); k++)
+ {
+ if (sscanf (p, "%[^,],%x;", query, &val) == 2)
+ {
+ printf_filtered ("[%02x] %-15s : %02x\n", k, query, val);
+ while ((*p != ';') && (*p != '\0'))
+ p++;
+ p++; /* skip over ';' */
+ if (*p == '\0')
+ break;
+ }
+ }
+ }
+}
+
+void
+_initialize_avr_tdep (void)
+{
+ register_gdbarch_init (bfd_arch_avr, avr_gdbarch_init);
+
+ /* Add a new command to allow the user to query the avr remote target for
+ the values of the io space registers in a saner way than just using
+ `x/NNNb ADDR`. */
+
+ /* FIXME: TRoth/2002-02-18: This should probably be changed to 'info avr
+ io_registers' to signify it is not available on other platforms. */
+
+ add_cmd ("io_registers", class_info, avr_io_reg_read_command,
+ "query remote avr target for io space register values", &infolist);
+}
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
new file mode 100644
index 00000000000..368b9df12a1
--- /dev/null
+++ b/gdb/ax-gdb.c
@@ -0,0 +1,1859 @@
+/* GDB-specific functions for operating on agent expressions
+ Copyright 1998, 1999, 2000, 2001 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 "defs.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "gdbtypes.h"
+#include "value.h"
+#include "expression.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "frame.h"
+#include "target.h"
+#include "ax.h"
+#include "ax-gdb.h"
+
+/* To make sense of this file, you should read doc/agentexpr.texi.
+ Then look at the types and enums in ax-gdb.h. For the code itself,
+ look at gen_expr, towards the bottom; that's the main function that
+ looks at the GDB expressions and calls everything else to generate
+ code.
+
+ I'm beginning to wonder whether it wouldn't be nicer to internally
+ generate trees, with types, and then spit out the bytecode in
+ linear form afterwards; we could generate fewer `swap', `ext', and
+ `zero_ext' bytecodes that way; it would make good constant folding
+ easier, too. But at the moment, I think we should be willing to
+ pay for the simplicity of this code with less-than-optimal bytecode
+ strings.
+
+ Remember, "GBD" stands for "Great Britain, Dammit!" So be careful. */
+
+
+
+/* Prototypes for local functions. */
+
+/* There's a standard order to the arguments of these functions:
+ union exp_element ** --- pointer into expression
+ struct agent_expr * --- agent expression buffer to generate code into
+ struct axs_value * --- describes value left on top of stack */
+
+static struct value *const_var_ref (struct symbol *var);
+static struct value *const_expr (union exp_element **pc);
+static struct value *maybe_const_expr (union exp_element **pc);
+
+static void gen_traced_pop (struct agent_expr *, struct axs_value *);
+
+static void gen_sign_extend (struct agent_expr *, struct type *);
+static void gen_extend (struct agent_expr *, struct type *);
+static void gen_fetch (struct agent_expr *, struct type *);
+static void gen_left_shift (struct agent_expr *, int);
+
+
+static void gen_frame_args_address (struct agent_expr *);
+static void gen_frame_locals_address (struct agent_expr *);
+static void gen_offset (struct agent_expr *ax, int offset);
+static void gen_sym_offset (struct agent_expr *, struct symbol *);
+static void gen_var_ref (struct agent_expr *ax,
+ struct axs_value *value, struct symbol *var);
+
+
+static void gen_int_literal (struct agent_expr *ax,
+ struct axs_value *value,
+ LONGEST k, struct type *type);
+
+
+static void require_rvalue (struct agent_expr *ax, struct axs_value *value);
+static void gen_usual_unary (struct agent_expr *ax, struct axs_value *value);
+static int type_wider_than (struct type *type1, struct type *type2);
+static struct type *max_type (struct type *type1, struct type *type2);
+static void gen_conversion (struct agent_expr *ax,
+ struct type *from, struct type *to);
+static int is_nontrivial_conversion (struct type *from, struct type *to);
+static void gen_usual_arithmetic (struct agent_expr *ax,
+ struct axs_value *value1,
+ struct axs_value *value2);
+static void gen_integral_promotions (struct agent_expr *ax,
+ struct axs_value *value);
+static void gen_cast (struct agent_expr *ax,
+ struct axs_value *value, struct type *type);
+static void gen_scale (struct agent_expr *ax,
+ enum agent_op op, struct type *type);
+static void gen_add (struct agent_expr *ax,
+ struct axs_value *value,
+ struct axs_value *value1,
+ struct axs_value *value2, char *name);
+static void gen_sub (struct agent_expr *ax,
+ struct axs_value *value,
+ struct axs_value *value1, struct axs_value *value2);
+static void gen_binop (struct agent_expr *ax,
+ struct axs_value *value,
+ struct axs_value *value1,
+ struct axs_value *value2,
+ enum agent_op op,
+ enum agent_op op_unsigned, int may_carry, char *name);
+static void gen_logical_not (struct agent_expr *ax, struct axs_value *value);
+static void gen_complement (struct agent_expr *ax, struct axs_value *value);
+static void gen_deref (struct agent_expr *, struct axs_value *);
+static void gen_address_of (struct agent_expr *, struct axs_value *);
+static int find_field (struct type *type, char *name);
+static void gen_bitfield_ref (struct agent_expr *ax,
+ struct axs_value *value,
+ struct type *type, int start, int end);
+static void gen_struct_ref (struct agent_expr *ax,
+ struct axs_value *value,
+ char *field,
+ char *operator_name, char *operand_name);
+static void gen_repeat (union exp_element **pc,
+ struct agent_expr *ax, struct axs_value *value);
+static void gen_sizeof (union exp_element **pc,
+ struct agent_expr *ax, struct axs_value *value);
+static void gen_expr (union exp_element **pc,
+ struct agent_expr *ax, struct axs_value *value);
+
+static void print_axs_value (struct ui_file *f, struct axs_value * value);
+static void agent_command (char *exp, int from_tty);
+
+
+/* Detecting constant expressions. */
+
+/* If the variable reference at *PC is a constant, return its value.
+ Otherwise, return zero.
+
+ Hey, Wally! How can a variable reference be a constant?
+
+ Well, Beav, this function really handles the OP_VAR_VALUE operator,
+ not specifically variable references. GDB uses OP_VAR_VALUE to
+ refer to any kind of symbolic reference: function names, enum
+ elements, and goto labels are all handled through the OP_VAR_VALUE
+ operator, even though they're constants. It makes sense given the
+ situation.
+
+ Gee, Wally, don'cha wonder sometimes if data representations that
+ subvert commonly accepted definitions of terms in favor of heavily
+ context-specific interpretations are really just a tool of the
+ programming hegemony to preserve their power and exclude the
+ proletariat? */
+
+static struct value *
+const_var_ref (struct symbol *var)
+{
+ struct type *type = SYMBOL_TYPE (var);
+
+ switch (SYMBOL_CLASS (var))
+ {
+ case LOC_CONST:
+ return value_from_longest (type, (LONGEST) SYMBOL_VALUE (var));
+
+ case LOC_LABEL:
+ return value_from_pointer (type, (CORE_ADDR) SYMBOL_VALUE_ADDRESS (var));
+
+ default:
+ return 0;
+ }
+}
+
+
+/* If the expression starting at *PC has a constant value, return it.
+ Otherwise, return zero. If we return a value, then *PC will be
+ advanced to the end of it. If we return zero, *PC could be
+ anywhere. */
+static struct value *
+const_expr (union exp_element **pc)
+{
+ enum exp_opcode op = (*pc)->opcode;
+ struct value *v1;
+
+ switch (op)
+ {
+ case OP_LONG:
+ {
+ struct type *type = (*pc)[1].type;
+ LONGEST k = (*pc)[2].longconst;
+ (*pc) += 4;
+ return value_from_longest (type, k);
+ }
+
+ case OP_VAR_VALUE:
+ {
+ struct value *v = const_var_ref ((*pc)[2].symbol);
+ (*pc) += 4;
+ return v;
+ }
+
+ /* We could add more operators in here. */
+
+ case UNOP_NEG:
+ (*pc)++;
+ v1 = const_expr (pc);
+ if (v1)
+ return value_neg (v1);
+ else
+ return 0;
+
+ default:
+ return 0;
+ }
+}
+
+
+/* Like const_expr, but guarantee also that *PC is undisturbed if the
+ expression is not constant. */
+static struct value *
+maybe_const_expr (union exp_element **pc)
+{
+ union exp_element *tentative_pc = *pc;
+ struct value *v = const_expr (&tentative_pc);
+
+ /* If we got a value, then update the real PC. */
+ if (v)
+ *pc = tentative_pc;
+
+ return v;
+}
+
+
+/* Generating bytecode from GDB expressions: general assumptions */
+
+/* Here are a few general assumptions made throughout the code; if you
+ want to make a change that contradicts one of these, then you'd
+ better scan things pretty thoroughly.
+
+ - We assume that all values occupy one stack element. For example,
+ sometimes we'll swap to get at the left argument to a binary
+ operator. If we decide that void values should occupy no stack
+ elements, or that synthetic arrays (whose size is determined at
+ run time, created by the `@' operator) should occupy two stack
+ elements (address and length), then this will cause trouble.
+
+ - We assume the stack elements are infinitely wide, and that we
+ don't have to worry what happens if the user requests an
+ operation that is wider than the actual interpreter's stack.
+ That is, it's up to the interpreter to handle directly all the
+ integer widths the user has access to. (Woe betide the language
+ with bignums!)
+
+ - We don't support side effects. Thus, we don't have to worry about
+ GCC's generalized lvalues, function calls, etc.
+
+ - We don't support floating point. Many places where we switch on
+ some type don't bother to include cases for floating point; there
+ may be even more subtle ways this assumption exists. For
+ example, the arguments to % must be integers.
+
+ - We assume all subexpressions have a static, unchanging type. If
+ we tried to support convenience variables, this would be a
+ problem.
+
+ - All values on the stack should always be fully zero- or
+ sign-extended.
+
+ (I wasn't sure whether to choose this or its opposite --- that
+ only addresses are assumed extended --- but it turns out that
+ neither convention completely eliminates spurious extend
+ operations (if everything is always extended, then you have to
+ extend after add, because it could overflow; if nothing is
+ extended, then you end up producing extends whenever you change
+ sizes), and this is simpler.) */
+
+
+/* Generating bytecode from GDB expressions: the `trace' kludge */
+
+/* The compiler in this file is a general-purpose mechanism for
+ translating GDB expressions into bytecode. One ought to be able to
+ find a million and one uses for it.
+
+ However, at the moment it is HOPELESSLY BRAIN-DAMAGED for the sake
+ of expediency. Let he who is without sin cast the first stone.
+
+ For the data tracing facility, we need to insert `trace' bytecodes
+ before each data fetch; this records all the memory that the
+ expression touches in the course of evaluation, so that memory will
+ be available when the user later tries to evaluate the expression
+ in GDB.
+
+ This should be done (I think) in a post-processing pass, that walks
+ an arbitrary agent expression and inserts `trace' operations at the
+ appropriate points. But it's much faster to just hack them
+ directly into the code. And since we're in a crunch, that's what
+ I've done.
+
+ Setting the flag trace_kludge to non-zero enables the code that
+ emits the trace bytecodes at the appropriate points. */
+static int trace_kludge;
+
+/* Trace the lvalue on the stack, if it needs it. In either case, pop
+ the value. Useful on the left side of a comma, and at the end of
+ an expression being used for tracing. */
+static void
+gen_traced_pop (struct agent_expr *ax, struct axs_value *value)
+{
+ if (trace_kludge)
+ switch (value->kind)
+ {
+ case axs_rvalue:
+ /* We don't trace rvalues, just the lvalues necessary to
+ produce them. So just dispose of this value. */
+ ax_simple (ax, aop_pop);
+ break;
+
+ case axs_lvalue_memory:
+ {
+ int length = TYPE_LENGTH (value->type);
+
+ /* There's no point in trying to use a trace_quick bytecode
+ here, since "trace_quick SIZE pop" is three bytes, whereas
+ "const8 SIZE trace" is also three bytes, does the same
+ thing, and the simplest code which generates that will also
+ work correctly for objects with large sizes. */
+ ax_const_l (ax, length);
+ ax_simple (ax, aop_trace);
+ }
+ break;
+
+ case axs_lvalue_register:
+ /* We need to mention the register somewhere in the bytecode,
+ so ax_reqs will pick it up and add it to the mask of
+ registers used. */
+ ax_reg (ax, value->u.reg);
+ ax_simple (ax, aop_pop);
+ break;
+ }
+ else
+ /* If we're not tracing, just pop the value. */
+ ax_simple (ax, aop_pop);
+}
+
+
+
+/* Generating bytecode from GDB expressions: helper functions */
+
+/* Assume that the lower bits of the top of the stack is a value of
+ type TYPE, and the upper bits are zero. Sign-extend if necessary. */
+static void
+gen_sign_extend (struct agent_expr *ax, struct type *type)
+{
+ /* Do we need to sign-extend this? */
+ if (!TYPE_UNSIGNED (type))
+ ax_ext (ax, TYPE_LENGTH (type) * TARGET_CHAR_BIT);
+}
+
+
+/* Assume the lower bits of the top of the stack hold a value of type
+ TYPE, and the upper bits are garbage. Sign-extend or truncate as
+ needed. */
+static void
+gen_extend (struct agent_expr *ax, struct type *type)
+{
+ int bits = TYPE_LENGTH (type) * TARGET_CHAR_BIT;
+ /* I just had to. */
+ ((TYPE_UNSIGNED (type) ? ax_zero_ext : ax_ext) (ax, bits));
+}
+
+
+/* Assume that the top of the stack contains a value of type "pointer
+ to TYPE"; generate code to fetch its value. Note that TYPE is the
+ target type, not the pointer type. */
+static void
+gen_fetch (struct agent_expr *ax, struct type *type)
+{
+ if (trace_kludge)
+ {
+ /* Record the area of memory we're about to fetch. */
+ ax_trace_quick (ax, TYPE_LENGTH (type));
+ }
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ /* It's a scalar value, so we know how to dereference it. How
+ many bytes long is it? */
+ switch (TYPE_LENGTH (type))
+ {
+ case 8 / TARGET_CHAR_BIT:
+ ax_simple (ax, aop_ref8);
+ break;
+ case 16 / TARGET_CHAR_BIT:
+ ax_simple (ax, aop_ref16);
+ break;
+ case 32 / TARGET_CHAR_BIT:
+ ax_simple (ax, aop_ref32);
+ break;
+ case 64 / TARGET_CHAR_BIT:
+ ax_simple (ax, aop_ref64);
+ break;
+
+ /* Either our caller shouldn't have asked us to dereference
+ that pointer (other code's fault), or we're not
+ implementing something we should be (this code's fault).
+ In any case, it's a bug the user shouldn't see. */
+ default:
+ internal_error (__FILE__, __LINE__,
+ "gen_fetch: strange size");
+ }
+
+ gen_sign_extend (ax, type);
+ break;
+
+ default:
+ /* Either our caller shouldn't have asked us to dereference that
+ pointer (other code's fault), or we're not implementing
+ something we should be (this code's fault). In any case,
+ it's a bug the user shouldn't see. */
+ internal_error (__FILE__, __LINE__,
+ "gen_fetch: bad type code");
+ }
+}
+
+
+/* Generate code to left shift the top of the stack by DISTANCE bits, or
+ right shift it by -DISTANCE bits if DISTANCE < 0. This generates
+ unsigned (logical) right shifts. */
+static void
+gen_left_shift (struct agent_expr *ax, int distance)
+{
+ if (distance > 0)
+ {
+ ax_const_l (ax, distance);
+ ax_simple (ax, aop_lsh);
+ }
+ else if (distance < 0)
+ {
+ ax_const_l (ax, -distance);
+ ax_simple (ax, aop_rsh_unsigned);
+ }
+}
+
+
+
+/* Generating bytecode from GDB expressions: symbol references */
+
+/* Generate code to push the base address of the argument portion of
+ the top stack frame. */
+static void
+gen_frame_args_address (struct agent_expr *ax)
+{
+ int frame_reg;
+ LONGEST frame_offset;
+
+ TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
+ ax_reg (ax, frame_reg);
+ gen_offset (ax, frame_offset);
+}
+
+
+/* Generate code to push the base address of the locals portion of the
+ top stack frame. */
+static void
+gen_frame_locals_address (struct agent_expr *ax)
+{
+ int frame_reg;
+ LONGEST frame_offset;
+
+ TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
+ ax_reg (ax, frame_reg);
+ gen_offset (ax, frame_offset);
+}
+
+
+/* Generate code to add OFFSET to the top of the stack. Try to
+ generate short and readable code. We use this for getting to
+ variables on the stack, and structure members. If we were
+ programming in ML, it would be clearer why these are the same
+ thing. */
+static void
+gen_offset (struct agent_expr *ax, int offset)
+{
+ /* It would suffice to simply push the offset and add it, but this
+ makes it easier to read positive and negative offsets in the
+ bytecode. */
+ if (offset > 0)
+ {
+ ax_const_l (ax, offset);
+ ax_simple (ax, aop_add);
+ }
+ else if (offset < 0)
+ {
+ ax_const_l (ax, -offset);
+ ax_simple (ax, aop_sub);
+ }
+}
+
+
+/* In many cases, a symbol's value is the offset from some other
+ address (stack frame, base register, etc.) Generate code to add
+ VAR's value to the top of the stack. */
+static void
+gen_sym_offset (struct agent_expr *ax, struct symbol *var)
+{
+ gen_offset (ax, SYMBOL_VALUE (var));
+}
+
+
+/* Generate code for a variable reference to AX. The variable is the
+ symbol VAR. Set VALUE to describe the result. */
+
+static void
+gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var)
+{
+ /* Dereference any typedefs. */
+ value->type = check_typedef (SYMBOL_TYPE (var));
+
+ /* I'm imitating the code in read_var_value. */
+ switch (SYMBOL_CLASS (var))
+ {
+ case LOC_CONST: /* A constant, like an enum value. */
+ ax_const_l (ax, (LONGEST) SYMBOL_VALUE (var));
+ value->kind = axs_rvalue;
+ break;
+
+ case LOC_LABEL: /* A goto label, being used as a value. */
+ ax_const_l (ax, (LONGEST) SYMBOL_VALUE_ADDRESS (var));
+ value->kind = axs_rvalue;
+ break;
+
+ case LOC_CONST_BYTES:
+ internal_error (__FILE__, __LINE__,
+ "gen_var_ref: LOC_CONST_BYTES symbols are not supported");
+
+ /* Variable at a fixed location in memory. Easy. */
+ case LOC_STATIC:
+ /* Push the address of the variable. */
+ ax_const_l (ax, SYMBOL_VALUE_ADDRESS (var));
+ value->kind = axs_lvalue_memory;
+ break;
+
+ case LOC_ARG: /* var lives in argument area of frame */
+ gen_frame_args_address (ax);
+ gen_sym_offset (ax, var);
+ value->kind = axs_lvalue_memory;
+ break;
+
+ case LOC_REF_ARG: /* As above, but the frame slot really
+ holds the address of the variable. */
+ gen_frame_args_address (ax);
+ gen_sym_offset (ax, var);
+ /* Don't assume any particular pointer size. */
+ gen_fetch (ax, lookup_pointer_type (builtin_type_void));
+ value->kind = axs_lvalue_memory;
+ break;
+
+ case LOC_LOCAL: /* var lives in locals area of frame */
+ case LOC_LOCAL_ARG:
+ gen_frame_locals_address (ax);
+ gen_sym_offset (ax, var);
+ value->kind = axs_lvalue_memory;
+ break;
+
+ case LOC_BASEREG: /* relative to some base register */
+ case LOC_BASEREG_ARG:
+ ax_reg (ax, SYMBOL_BASEREG (var));
+ gen_sym_offset (ax, var);
+ value->kind = axs_lvalue_memory;
+ break;
+
+ case LOC_TYPEDEF:
+ error ("Cannot compute value of typedef `%s'.",
+ SYMBOL_SOURCE_NAME (var));
+ break;
+
+ case LOC_BLOCK:
+ ax_const_l (ax, BLOCK_START (SYMBOL_BLOCK_VALUE (var)));
+ value->kind = axs_rvalue;
+ break;
+
+ case LOC_REGISTER:
+ case LOC_REGPARM:
+ /* Don't generate any code at all; in the process of treating
+ this as an lvalue or rvalue, the caller will generate the
+ right code. */
+ value->kind = axs_lvalue_register;
+ value->u.reg = SYMBOL_VALUE (var);
+ break;
+
+ /* A lot like LOC_REF_ARG, but the pointer lives directly in a
+ register, not on the stack. Simpler than LOC_REGISTER and
+ LOC_REGPARM, because it's just like any other case where the
+ thing has a real address. */
+ case LOC_REGPARM_ADDR:
+ ax_reg (ax, SYMBOL_VALUE (var));
+ value->kind = axs_lvalue_memory;
+ break;
+
+ case LOC_UNRESOLVED:
+ {
+ struct minimal_symbol *msym
+ = lookup_minimal_symbol (SYMBOL_NAME (var), NULL, NULL);
+ if (!msym)
+ error ("Couldn't resolve symbol `%s'.", SYMBOL_SOURCE_NAME (var));
+
+ /* Push the address of the variable. */
+ ax_const_l (ax, SYMBOL_VALUE_ADDRESS (msym));
+ value->kind = axs_lvalue_memory;
+ }
+ break;
+
+ case LOC_OPTIMIZED_OUT:
+ error ("The variable `%s' has been optimized out.",
+ SYMBOL_SOURCE_NAME (var));
+ break;
+
+ default:
+ error ("Cannot find value of botched symbol `%s'.",
+ SYMBOL_SOURCE_NAME (var));
+ break;
+ }
+}
+
+
+
+/* Generating bytecode from GDB expressions: literals */
+
+static void
+gen_int_literal (struct agent_expr *ax, struct axs_value *value, LONGEST k,
+ struct type *type)
+{
+ ax_const_l (ax, k);
+ value->kind = axs_rvalue;
+ value->type = type;
+}
+
+
+
+/* Generating bytecode from GDB expressions: unary conversions, casts */
+
+/* Take what's on the top of the stack (as described by VALUE), and
+ try to make an rvalue out of it. Signal an error if we can't do
+ that. */
+static void
+require_rvalue (struct agent_expr *ax, struct axs_value *value)
+{
+ switch (value->kind)
+ {
+ case axs_rvalue:
+ /* It's already an rvalue. */
+ break;
+
+ case axs_lvalue_memory:
+ /* The top of stack is the address of the object. Dereference. */
+ gen_fetch (ax, value->type);
+ break;
+
+ case axs_lvalue_register:
+ /* There's nothing on the stack, but value->u.reg is the
+ register number containing the value.
+
+ When we add floating-point support, this is going to have to
+ change. What about SPARC register pairs, for example? */
+ ax_reg (ax, value->u.reg);
+ gen_extend (ax, value->type);
+ break;
+ }
+
+ value->kind = axs_rvalue;
+}
+
+
+/* Assume the top of the stack is described by VALUE, and perform the
+ usual unary conversions. This is motivated by ANSI 6.2.2, but of
+ course GDB expressions are not ANSI; they're the mishmash union of
+ a bunch of languages. Rah.
+
+ NOTE! This function promises to produce an rvalue only when the
+ incoming value is of an appropriate type. In other words, the
+ consumer of the value this function produces may assume the value
+ is an rvalue only after checking its type.
+
+ The immediate issue is that if the user tries to use a structure or
+ union as an operand of, say, the `+' operator, we don't want to try
+ to convert that structure to an rvalue; require_rvalue will bomb on
+ structs and unions. Rather, we want to simply pass the struct
+ lvalue through unchanged, and let `+' raise an error. */
+
+static void
+gen_usual_unary (struct agent_expr *ax, struct axs_value *value)
+{
+ /* We don't have to generate any code for the usual integral
+ conversions, since values are always represented as full-width on
+ the stack. Should we tweak the type? */
+
+ /* Some types require special handling. */
+ switch (TYPE_CODE (value->type))
+ {
+ /* Functions get converted to a pointer to the function. */
+ case TYPE_CODE_FUNC:
+ value->type = lookup_pointer_type (value->type);
+ value->kind = axs_rvalue; /* Should always be true, but just in case. */
+ break;
+
+ /* Arrays get converted to a pointer to their first element, and
+ are no longer an lvalue. */
+ case TYPE_CODE_ARRAY:
+ {
+ struct type *elements = TYPE_TARGET_TYPE (value->type);
+ value->type = lookup_pointer_type (elements);
+ value->kind = axs_rvalue;
+ /* We don't need to generate any code; the address of the array
+ is also the address of its first element. */
+ }
+ break;
+
+ /* Don't try to convert structures and unions to rvalues. Let the
+ consumer signal an error. */
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ return;
+
+ /* If the value is an enum, call it an integer. */
+ case TYPE_CODE_ENUM:
+ value->type = builtin_type_int;
+ break;
+ }
+
+ /* If the value is an lvalue, dereference it. */
+ require_rvalue (ax, value);
+}
+
+
+/* Return non-zero iff the type TYPE1 is considered "wider" than the
+ type TYPE2, according to the rules described in gen_usual_arithmetic. */
+static int
+type_wider_than (struct type *type1, struct type *type2)
+{
+ return (TYPE_LENGTH (type1) > TYPE_LENGTH (type2)
+ || (TYPE_LENGTH (type1) == TYPE_LENGTH (type2)
+ && TYPE_UNSIGNED (type1)
+ && !TYPE_UNSIGNED (type2)));
+}
+
+
+/* Return the "wider" of the two types TYPE1 and TYPE2. */
+static struct type *
+max_type (struct type *type1, struct type *type2)
+{
+ return type_wider_than (type1, type2) ? type1 : type2;
+}
+
+
+/* Generate code to convert a scalar value of type FROM to type TO. */
+static void
+gen_conversion (struct agent_expr *ax, struct type *from, struct type *to)
+{
+ /* Perhaps there is a more graceful way to state these rules. */
+
+ /* If we're converting to a narrower type, then we need to clear out
+ the upper bits. */
+ if (TYPE_LENGTH (to) < TYPE_LENGTH (from))
+ gen_extend (ax, from);
+
+ /* If the two values have equal width, but different signednesses,
+ then we need to extend. */
+ else if (TYPE_LENGTH (to) == TYPE_LENGTH (from))
+ {
+ if (TYPE_UNSIGNED (from) != TYPE_UNSIGNED (to))
+ gen_extend (ax, to);
+ }
+
+ /* If we're converting to a wider type, and becoming unsigned, then
+ we need to zero out any possible sign bits. */
+ else if (TYPE_LENGTH (to) > TYPE_LENGTH (from))
+ {
+ if (TYPE_UNSIGNED (to))
+ gen_extend (ax, to);
+ }
+}
+
+
+/* Return non-zero iff the type FROM will require any bytecodes to be
+ emitted to be converted to the type TO. */
+static int
+is_nontrivial_conversion (struct type *from, struct type *to)
+{
+ struct agent_expr *ax = new_agent_expr (0);
+ int nontrivial;
+
+ /* Actually generate the code, and see if anything came out. At the
+ moment, it would be trivial to replicate the code in
+ gen_conversion here, but in the future, when we're supporting
+ floating point and the like, it may not be. Doing things this
+ way allows this function to be independent of the logic in
+ gen_conversion. */
+ gen_conversion (ax, from, to);
+ nontrivial = ax->len > 0;
+ free_agent_expr (ax);
+ return nontrivial;
+}
+
+
+/* Generate code to perform the "usual arithmetic conversions" (ANSI C
+ 6.2.1.5) for the two operands of an arithmetic operator. This
+ effectively finds a "least upper bound" type for the two arguments,
+ and promotes each argument to that type. *VALUE1 and *VALUE2
+ describe the values as they are passed in, and as they are left. */
+static void
+gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1,
+ struct axs_value *value2)
+{
+ /* Do the usual binary conversions. */
+ if (TYPE_CODE (value1->type) == TYPE_CODE_INT
+ && TYPE_CODE (value2->type) == TYPE_CODE_INT)
+ {
+ /* The ANSI integral promotions seem to work this way: Order the
+ integer types by size, and then by signedness: an n-bit
+ unsigned type is considered "wider" than an n-bit signed
+ type. Promote to the "wider" of the two types, and always
+ promote at least to int. */
+ struct type *target = max_type (builtin_type_int,
+ max_type (value1->type, value2->type));
+
+ /* Deal with value2, on the top of the stack. */
+ gen_conversion (ax, value2->type, target);
+
+ /* Deal with value1, not on the top of the stack. Don't
+ generate the `swap' instructions if we're not actually going
+ to do anything. */
+ if (is_nontrivial_conversion (value1->type, target))
+ {
+ ax_simple (ax, aop_swap);
+ gen_conversion (ax, value1->type, target);
+ ax_simple (ax, aop_swap);
+ }
+
+ value1->type = value2->type = target;
+ }
+}
+
+
+/* Generate code to perform the integral promotions (ANSI 6.2.1.1) on
+ the value on the top of the stack, as described by VALUE. Assume
+ the value has integral type. */
+static void
+gen_integral_promotions (struct agent_expr *ax, struct axs_value *value)
+{
+ if (!type_wider_than (value->type, builtin_type_int))
+ {
+ gen_conversion (ax, value->type, builtin_type_int);
+ value->type = builtin_type_int;
+ }
+ else if (!type_wider_than (value->type, builtin_type_unsigned_int))
+ {
+ gen_conversion (ax, value->type, builtin_type_unsigned_int);
+ value->type = builtin_type_unsigned_int;
+ }
+}
+
+
+/* Generate code for a cast to TYPE. */
+static void
+gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type)
+{
+ /* GCC does allow casts to yield lvalues, so this should be fixed
+ before merging these changes into the trunk. */
+ require_rvalue (ax, value);
+ /* Dereference typedefs. */
+ type = check_typedef (type);
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_PTR:
+ /* It's implementation-defined, and I'll bet this is what GCC
+ does. */
+ break;
+
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_FUNC:
+ error ("Illegal type cast: intended type must be scalar.");
+
+ case TYPE_CODE_ENUM:
+ /* We don't have to worry about the size of the value, because
+ all our integral values are fully sign-extended, and when
+ casting pointers we can do anything we like. Is there any
+ way for us to actually know what GCC actually does with a
+ cast like this? */
+ value->type = type;
+ break;
+
+ case TYPE_CODE_INT:
+ gen_conversion (ax, value->type, type);
+ break;
+
+ case TYPE_CODE_VOID:
+ /* We could pop the value, and rely on everyone else to check
+ the type and notice that this value doesn't occupy a stack
+ slot. But for now, leave the value on the stack, and
+ preserve the "value == stack element" assumption. */
+ break;
+
+ default:
+ error ("Casts to requested type are not yet implemented.");
+ }
+
+ value->type = type;
+}
+
+
+
+/* Generating bytecode from GDB expressions: arithmetic */
+
+/* Scale the integer on the top of the stack by the size of the target
+ of the pointer type TYPE. */
+static void
+gen_scale (struct agent_expr *ax, enum agent_op op, struct type *type)
+{
+ struct type *element = TYPE_TARGET_TYPE (type);
+
+ if (TYPE_LENGTH (element) != 1)
+ {
+ ax_const_l (ax, TYPE_LENGTH (element));
+ ax_simple (ax, op);
+ }
+}
+
+
+/* Generate code for an addition; non-trivial because we deal with
+ pointer arithmetic. We set VALUE to describe the result value; we
+ assume VALUE1 and VALUE2 describe the two operands, and that
+ they've undergone the usual binary conversions. Used by both
+ BINOP_ADD and BINOP_SUBSCRIPT. NAME is used in error messages. */
+static void
+gen_add (struct agent_expr *ax, struct axs_value *value,
+ struct axs_value *value1, struct axs_value *value2, char *name)
+{
+ /* Is it INT+PTR? */
+ if (TYPE_CODE (value1->type) == TYPE_CODE_INT
+ && TYPE_CODE (value2->type) == TYPE_CODE_PTR)
+ {
+ /* Swap the values and proceed normally. */
+ ax_simple (ax, aop_swap);
+ gen_scale (ax, aop_mul, value2->type);
+ ax_simple (ax, aop_add);
+ gen_extend (ax, value2->type); /* Catch overflow. */
+ value->type = value2->type;
+ }
+
+ /* Is it PTR+INT? */
+ else if (TYPE_CODE (value1->type) == TYPE_CODE_PTR
+ && TYPE_CODE (value2->type) == TYPE_CODE_INT)
+ {
+ gen_scale (ax, aop_mul, value1->type);
+ ax_simple (ax, aop_add);
+ gen_extend (ax, value1->type); /* Catch overflow. */
+ value->type = value1->type;
+ }
+
+ /* Must be number + number; the usual binary conversions will have
+ brought them both to the same width. */
+ else if (TYPE_CODE (value1->type) == TYPE_CODE_INT
+ && TYPE_CODE (value2->type) == TYPE_CODE_INT)
+ {
+ ax_simple (ax, aop_add);
+ gen_extend (ax, value1->type); /* Catch overflow. */
+ value->type = value1->type;
+ }
+
+ else
+ error ("Illegal combination of types in %s.", name);
+
+ value->kind = axs_rvalue;
+}
+
+
+/* Generate code for an addition; non-trivial because we have to deal
+ with pointer arithmetic. We set VALUE to describe the result
+ value; we assume VALUE1 and VALUE2 describe the two operands, and
+ that they've undergone the usual binary conversions. */
+static void
+gen_sub (struct agent_expr *ax, struct axs_value *value,
+ struct axs_value *value1, struct axs_value *value2)
+{
+ if (TYPE_CODE (value1->type) == TYPE_CODE_PTR)
+ {
+ /* Is it PTR - INT? */
+ if (TYPE_CODE (value2->type) == TYPE_CODE_INT)
+ {
+ gen_scale (ax, aop_mul, value1->type);
+ ax_simple (ax, aop_sub);
+ gen_extend (ax, value1->type); /* Catch overflow. */
+ value->type = value1->type;
+ }
+
+ /* Is it PTR - PTR? Strictly speaking, the types ought to
+ match, but this is what the normal GDB expression evaluator
+ tests for. */
+ else if (TYPE_CODE (value2->type) == TYPE_CODE_PTR
+ && (TYPE_LENGTH (TYPE_TARGET_TYPE (value1->type))
+ == TYPE_LENGTH (TYPE_TARGET_TYPE (value2->type))))
+ {
+ ax_simple (ax, aop_sub);
+ gen_scale (ax, aop_div_unsigned, value1->type);
+ value->type = builtin_type_long; /* FIXME --- should be ptrdiff_t */
+ }
+ else
+ error ("\
+First argument of `-' is a pointer, but second argument is neither\n\
+an integer nor a pointer of the same type.");
+ }
+
+ /* Must be number + number. */
+ else if (TYPE_CODE (value1->type) == TYPE_CODE_INT
+ && TYPE_CODE (value2->type) == TYPE_CODE_INT)
+ {
+ ax_simple (ax, aop_sub);
+ gen_extend (ax, value1->type); /* Catch overflow. */
+ value->type = value1->type;
+ }
+
+ else
+ error ("Illegal combination of types in subtraction.");
+
+ value->kind = axs_rvalue;
+}
+
+/* Generate code for a binary operator that doesn't do pointer magic.
+ We set VALUE to describe the result value; we assume VALUE1 and
+ VALUE2 describe the two operands, and that they've undergone the
+ usual binary conversions. MAY_CARRY should be non-zero iff the
+ result needs to be extended. NAME is the English name of the
+ operator, used in error messages */
+static void
+gen_binop (struct agent_expr *ax, struct axs_value *value,
+ struct axs_value *value1, struct axs_value *value2, enum agent_op op,
+ enum agent_op op_unsigned, int may_carry, char *name)
+{
+ /* We only handle INT op INT. */
+ if ((TYPE_CODE (value1->type) != TYPE_CODE_INT)
+ || (TYPE_CODE (value2->type) != TYPE_CODE_INT))
+ error ("Illegal combination of types in %s.", name);
+
+ ax_simple (ax,
+ TYPE_UNSIGNED (value1->type) ? op_unsigned : op);
+ if (may_carry)
+ gen_extend (ax, value1->type); /* catch overflow */
+ value->type = value1->type;
+ value->kind = axs_rvalue;
+}
+
+
+static void
+gen_logical_not (struct agent_expr *ax, struct axs_value *value)
+{
+ if (TYPE_CODE (value->type) != TYPE_CODE_INT
+ && TYPE_CODE (value->type) != TYPE_CODE_PTR)
+ error ("Illegal type of operand to `!'.");
+
+ gen_usual_unary (ax, value);
+ ax_simple (ax, aop_log_not);
+ value->type = builtin_type_int;
+}
+
+
+static void
+gen_complement (struct agent_expr *ax, struct axs_value *value)
+{
+ if (TYPE_CODE (value->type) != TYPE_CODE_INT)
+ error ("Illegal type of operand to `~'.");
+
+ gen_usual_unary (ax, value);
+ gen_integral_promotions (ax, value);
+ ax_simple (ax, aop_bit_not);
+ gen_extend (ax, value->type);
+}
+
+
+
+/* Generating bytecode from GDB expressions: * & . -> @ sizeof */
+
+/* Dereference the value on the top of the stack. */
+static void
+gen_deref (struct agent_expr *ax, struct axs_value *value)
+{
+ /* The caller should check the type, because several operators use
+ this, and we don't know what error message to generate. */
+ if (TYPE_CODE (value->type) != TYPE_CODE_PTR)
+ internal_error (__FILE__, __LINE__,
+ "gen_deref: expected a pointer");
+
+ /* We've got an rvalue now, which is a pointer. We want to yield an
+ lvalue, whose address is exactly that pointer. So we don't
+ actually emit any code; we just change the type from "Pointer to
+ T" to "T", and mark the value as an lvalue in memory. Leave it
+ to the consumer to actually dereference it. */
+ value->type = check_typedef (TYPE_TARGET_TYPE (value->type));
+ value->kind = ((TYPE_CODE (value->type) == TYPE_CODE_FUNC)
+ ? axs_rvalue : axs_lvalue_memory);
+}
+
+
+/* Produce the address of the lvalue on the top of the stack. */
+static void
+gen_address_of (struct agent_expr *ax, struct axs_value *value)
+{
+ /* Special case for taking the address of a function. The ANSI
+ standard describes this as a special case, too, so this
+ arrangement is not without motivation. */
+ if (TYPE_CODE (value->type) == TYPE_CODE_FUNC)
+ /* The value's already an rvalue on the stack, so we just need to
+ change the type. */
+ value->type = lookup_pointer_type (value->type);
+ else
+ switch (value->kind)
+ {
+ case axs_rvalue:
+ error ("Operand of `&' is an rvalue, which has no address.");
+
+ case axs_lvalue_register:
+ error ("Operand of `&' is in a register, and has no address.");
+
+ case axs_lvalue_memory:
+ value->kind = axs_rvalue;
+ value->type = lookup_pointer_type (value->type);
+ break;
+ }
+}
+
+
+/* A lot of this stuff will have to change to support C++. But we're
+ not going to deal with that at the moment. */
+
+/* Find the field in the structure type TYPE named NAME, and return
+ its index in TYPE's field array. */
+static int
+find_field (struct type *type, char *name)
+{
+ int i;
+
+ CHECK_TYPEDEF (type);
+
+ /* Make sure this isn't C++. */
+ if (TYPE_N_BASECLASSES (type) != 0)
+ internal_error (__FILE__, __LINE__,
+ "find_field: derived classes supported");
+
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
+ {
+ char *this_name = TYPE_FIELD_NAME (type, i);
+
+ if (this_name && STREQ (name, this_name))
+ return i;
+
+ if (this_name[0] == '\0')
+ internal_error (__FILE__, __LINE__,
+ "find_field: anonymous unions not supported");
+ }
+
+ error ("Couldn't find member named `%s' in struct/union `%s'",
+ name, TYPE_TAG_NAME (type));
+
+ return 0;
+}
+
+
+/* Generate code to push the value of a bitfield of a structure whose
+ address is on the top of the stack. START and END give the
+ starting and one-past-ending *bit* numbers of the field within the
+ structure. */
+static void
+gen_bitfield_ref (struct agent_expr *ax, struct axs_value *value,
+ struct type *type, int start, int end)
+{
+ /* Note that ops[i] fetches 8 << i bits. */
+ static enum agent_op ops[]
+ =
+ {aop_ref8, aop_ref16, aop_ref32, aop_ref64};
+ static int num_ops = (sizeof (ops) / sizeof (ops[0]));
+
+ /* We don't want to touch any byte that the bitfield doesn't
+ actually occupy; we shouldn't make any accesses we're not
+ explicitly permitted to. We rely here on the fact that the
+ bytecode `ref' operators work on unaligned addresses.
+
+ It takes some fancy footwork to get the stack to work the way
+ we'd like. Say we're retrieving a bitfield that requires three
+ fetches. Initially, the stack just contains the address:
+ addr
+ For the first fetch, we duplicate the address
+ addr addr
+ then add the byte offset, do the fetch, and shift and mask as
+ needed, yielding a fragment of the value, properly aligned for
+ the final bitwise or:
+ addr frag1
+ then we swap, and repeat the process:
+ frag1 addr --- address on top
+ frag1 addr addr --- duplicate it
+ frag1 addr frag2 --- get second fragment
+ frag1 frag2 addr --- swap again
+ frag1 frag2 frag3 --- get third fragment
+ Notice that, since the third fragment is the last one, we don't
+ bother duplicating the address this time. Now we have all the
+ fragments on the stack, and we can simply `or' them together,
+ yielding the final value of the bitfield. */
+
+ /* The first and one-after-last bits in the field, but rounded down
+ and up to byte boundaries. */
+ int bound_start = (start / TARGET_CHAR_BIT) * TARGET_CHAR_BIT;
+ int bound_end = (((end + TARGET_CHAR_BIT - 1)
+ / TARGET_CHAR_BIT)
+ * TARGET_CHAR_BIT);
+
+ /* current bit offset within the structure */
+ int offset;
+
+ /* The index in ops of the opcode we're considering. */
+ int op;
+
+ /* The number of fragments we generated in the process. Probably
+ equal to the number of `one' bits in bytesize, but who cares? */
+ int fragment_count;
+
+ /* Dereference any typedefs. */
+ type = check_typedef (type);
+
+ /* Can we fetch the number of bits requested at all? */
+ if ((end - start) > ((1 << num_ops) * 8))
+ internal_error (__FILE__, __LINE__,
+ "gen_bitfield_ref: bitfield too wide");
+
+ /* Note that we know here that we only need to try each opcode once.
+ That may not be true on machines with weird byte sizes. */
+ offset = bound_start;
+ fragment_count = 0;
+ for (op = num_ops - 1; op >= 0; op--)
+ {
+ /* number of bits that ops[op] would fetch */
+ int op_size = 8 << op;
+
+ /* The stack at this point, from bottom to top, contains zero or
+ more fragments, then the address. */
+
+ /* Does this fetch fit within the bitfield? */
+ if (offset + op_size <= bound_end)
+ {
+ /* Is this the last fragment? */
+ int last_frag = (offset + op_size == bound_end);
+
+ if (!last_frag)
+ ax_simple (ax, aop_dup); /* keep a copy of the address */
+
+ /* Add the offset. */
+ gen_offset (ax, offset / TARGET_CHAR_BIT);
+
+ if (trace_kludge)
+ {
+ /* Record the area of memory we're about to fetch. */
+ ax_trace_quick (ax, op_size / TARGET_CHAR_BIT);
+ }
+
+ /* Perform the fetch. */
+ ax_simple (ax, ops[op]);
+
+ /* Shift the bits we have to their proper position.
+ gen_left_shift will generate right shifts when the operand
+ is negative.
+
+ A big-endian field diagram to ponder:
+ byte 0 byte 1 byte 2 byte 3 byte 4 byte 5 byte 6 byte 7
+ +------++------++------++------++------++------++------++------+
+ xxxxAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCxxxxxxxxxxx
+ ^ ^ ^ ^
+ bit number 16 32 48 53
+ These are bit numbers as supplied by GDB. Note that the
+ bit numbers run from right to left once you've fetched the
+ value!
+
+ A little-endian field diagram to ponder:
+ byte 7 byte 6 byte 5 byte 4 byte 3 byte 2 byte 1 byte 0
+ +------++------++------++------++------++------++------++------+
+ xxxxxxxxxxxAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCxxxx
+ ^ ^ ^ ^ ^
+ bit number 48 32 16 4 0
+
+ In both cases, the most significant end is on the left
+ (i.e. normal numeric writing order), which means that you
+ don't go crazy thinking about `left' and `right' shifts.
+
+ We don't have to worry about masking yet:
+ - If they contain garbage off the least significant end, then we
+ must be looking at the low end of the field, and the right
+ shift will wipe them out.
+ - If they contain garbage off the most significant end, then we
+ must be looking at the most significant end of the word, and
+ the sign/zero extension will wipe them out.
+ - If we're in the interior of the word, then there is no garbage
+ on either end, because the ref operators zero-extend. */
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ gen_left_shift (ax, end - (offset + op_size));
+ else
+ gen_left_shift (ax, offset - start);
+
+ if (!last_frag)
+ /* Bring the copy of the address up to the top. */
+ ax_simple (ax, aop_swap);
+
+ offset += op_size;
+ fragment_count++;
+ }
+ }
+
+ /* Generate enough bitwise `or' operations to combine all the
+ fragments we left on the stack. */
+ while (fragment_count-- > 1)
+ ax_simple (ax, aop_bit_or);
+
+ /* Sign- or zero-extend the value as appropriate. */
+ ((TYPE_UNSIGNED (type) ? ax_zero_ext : ax_ext) (ax, end - start));
+
+ /* This is *not* an lvalue. Ugh. */
+ value->kind = axs_rvalue;
+ value->type = type;
+}
+
+
+/* Generate code to reference the member named FIELD of a structure or
+ union. The top of the stack, as described by VALUE, should have
+ type (pointer to a)* struct/union. OPERATOR_NAME is the name of
+ the operator being compiled, and OPERAND_NAME is the kind of thing
+ it operates on; we use them in error messages. */
+static void
+gen_struct_ref (struct agent_expr *ax, struct axs_value *value, char *field,
+ char *operator_name, char *operand_name)
+{
+ struct type *type;
+ int i;
+
+ /* Follow pointers until we reach a non-pointer. These aren't the C
+ semantics, but they're what the normal GDB evaluator does, so we
+ should at least be consistent. */
+ while (TYPE_CODE (value->type) == TYPE_CODE_PTR)
+ {
+ gen_usual_unary (ax, value);
+ gen_deref (ax, value);
+ }
+ type = check_typedef (value->type);
+
+ /* This must yield a structure or a union. */
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+ && TYPE_CODE (type) != TYPE_CODE_UNION)
+ error ("The left operand of `%s' is not a %s.",
+ operator_name, operand_name);
+
+ /* And it must be in memory; we don't deal with structure rvalues,
+ or structures living in registers. */
+ if (value->kind != axs_lvalue_memory)
+ error ("Structure does not live in memory.");
+
+ i = find_field (type, field);
+
+ /* Is this a bitfield? */
+ if (TYPE_FIELD_PACKED (type, i))
+ gen_bitfield_ref (ax, value, TYPE_FIELD_TYPE (type, i),
+ TYPE_FIELD_BITPOS (type, i),
+ (TYPE_FIELD_BITPOS (type, i)
+ + TYPE_FIELD_BITSIZE (type, i)));
+ else
+ {
+ gen_offset (ax, TYPE_FIELD_BITPOS (type, i) / TARGET_CHAR_BIT);
+ value->kind = axs_lvalue_memory;
+ value->type = TYPE_FIELD_TYPE (type, i);
+ }
+}
+
+
+/* Generate code for GDB's magical `repeat' operator.
+ LVALUE @ INT creates an array INT elements long, and whose elements
+ have the same type as LVALUE, located in memory so that LVALUE is
+ its first element. For example, argv[0]@argc gives you the array
+ of command-line arguments.
+
+ Unfortunately, because we have to know the types before we actually
+ have a value for the expression, we can't implement this perfectly
+ without changing the type system, having values that occupy two
+ stack slots, doing weird things with sizeof, etc. So we require
+ the right operand to be a constant expression. */
+static void
+gen_repeat (union exp_element **pc, struct agent_expr *ax,
+ struct axs_value *value)
+{
+ struct axs_value value1;
+ /* We don't want to turn this into an rvalue, so no conversions
+ here. */
+ gen_expr (pc, ax, &value1);
+ if (value1.kind != axs_lvalue_memory)
+ error ("Left operand of `@' must be an object in memory.");
+
+ /* Evaluate the length; it had better be a constant. */
+ {
+ struct value *v = const_expr (pc);
+ int length;
+
+ if (!v)
+ error ("Right operand of `@' must be a constant, in agent expressions.");
+ if (TYPE_CODE (v->type) != TYPE_CODE_INT)
+ error ("Right operand of `@' must be an integer.");
+ length = value_as_long (v);
+ if (length <= 0)
+ error ("Right operand of `@' must be positive.");
+
+ /* The top of the stack is already the address of the object, so
+ all we need to do is frob the type of the lvalue. */
+ {
+ /* FIXME-type-allocation: need a way to free this type when we are
+ done with it. */
+ struct type *range
+ = create_range_type (0, builtin_type_int, 0, length - 1);
+ struct type *array = create_array_type (0, value1.type, range);
+
+ value->kind = axs_lvalue_memory;
+ value->type = array;
+ }
+ }
+}
+
+
+/* Emit code for the `sizeof' operator.
+ *PC should point at the start of the operand expression; we advance it
+ to the first instruction after the operand. */
+static void
+gen_sizeof (union exp_element **pc, struct agent_expr *ax,
+ struct axs_value *value)
+{
+ /* We don't care about the value of the operand expression; we only
+ care about its type. However, in the current arrangement, the
+ only way to find an expression's type is to generate code for it.
+ So we generate code for the operand, and then throw it away,
+ replacing it with code that simply pushes its size. */
+ int start = ax->len;
+ gen_expr (pc, ax, value);
+
+ /* Throw away the code we just generated. */
+ ax->len = start;
+
+ ax_const_l (ax, TYPE_LENGTH (value->type));
+ value->kind = axs_rvalue;
+ value->type = builtin_type_int;
+}
+
+
+/* Generating bytecode from GDB expressions: general recursive thingy */
+
+/* A gen_expr function written by a Gen-X'er guy.
+ Append code for the subexpression of EXPR starting at *POS_P to AX. */
+static void
+gen_expr (union exp_element **pc, struct agent_expr *ax,
+ struct axs_value *value)
+{
+ /* Used to hold the descriptions of operand expressions. */
+ struct axs_value value1, value2;
+ enum exp_opcode op = (*pc)[0].opcode;
+
+ /* If we're looking at a constant expression, just push its value. */
+ {
+ struct value *v = maybe_const_expr (pc);
+
+ if (v)
+ {
+ ax_const_l (ax, value_as_long (v));
+ value->kind = axs_rvalue;
+ value->type = check_typedef (VALUE_TYPE (v));
+ return;
+ }
+ }
+
+ /* Otherwise, go ahead and generate code for it. */
+ switch (op)
+ {
+ /* Binary arithmetic operators. */
+ case BINOP_ADD:
+ case BINOP_SUB:
+ case BINOP_MUL:
+ case BINOP_DIV:
+ case BINOP_REM:
+ case BINOP_SUBSCRIPT:
+ case BINOP_BITWISE_AND:
+ case BINOP_BITWISE_IOR:
+ case BINOP_BITWISE_XOR:
+ (*pc)++;
+ gen_expr (pc, ax, &value1);
+ gen_usual_unary (ax, &value1);
+ gen_expr (pc, ax, &value2);
+ gen_usual_unary (ax, &value2);
+ gen_usual_arithmetic (ax, &value1, &value2);
+ switch (op)
+ {
+ case BINOP_ADD:
+ gen_add (ax, value, &value1, &value2, "addition");
+ break;
+ case BINOP_SUB:
+ gen_sub (ax, value, &value1, &value2);
+ break;
+ case BINOP_MUL:
+ gen_binop (ax, value, &value1, &value2,
+ aop_mul, aop_mul, 1, "multiplication");
+ break;
+ case BINOP_DIV:
+ gen_binop (ax, value, &value1, &value2,
+ aop_div_signed, aop_div_unsigned, 1, "division");
+ break;
+ case BINOP_REM:
+ gen_binop (ax, value, &value1, &value2,
+ aop_rem_signed, aop_rem_unsigned, 1, "remainder");
+ break;
+ case BINOP_SUBSCRIPT:
+ gen_add (ax, value, &value1, &value2, "array subscripting");
+ if (TYPE_CODE (value->type) != TYPE_CODE_PTR)
+ error ("Illegal combination of types in array subscripting.");
+ gen_deref (ax, value);
+ break;
+ case BINOP_BITWISE_AND:
+ gen_binop (ax, value, &value1, &value2,
+ aop_bit_and, aop_bit_and, 0, "bitwise and");
+ break;
+
+ case BINOP_BITWISE_IOR:
+ gen_binop (ax, value, &value1, &value2,
+ aop_bit_or, aop_bit_or, 0, "bitwise or");
+ break;
+
+ case BINOP_BITWISE_XOR:
+ gen_binop (ax, value, &value1, &value2,
+ aop_bit_xor, aop_bit_xor, 0, "bitwise exclusive-or");
+ break;
+
+ default:
+ /* We should only list operators in the outer case statement
+ that we actually handle in the inner case statement. */
+ internal_error (__FILE__, __LINE__,
+ "gen_expr: op case sets don't match");
+ }
+ break;
+
+ /* Note that we need to be a little subtle about generating code
+ for comma. In C, we can do some optimizations here because
+ we know the left operand is only being evaluated for effect.
+ However, if the tracing kludge is in effect, then we always
+ need to evaluate the left hand side fully, so that all the
+ variables it mentions get traced. */
+ case BINOP_COMMA:
+ (*pc)++;
+ gen_expr (pc, ax, &value1);
+ /* Don't just dispose of the left operand. We might be tracing,
+ in which case we want to emit code to trace it if it's an
+ lvalue. */
+ gen_traced_pop (ax, &value1);
+ gen_expr (pc, ax, value);
+ /* It's the consumer's responsibility to trace the right operand. */
+ break;
+
+ case OP_LONG: /* some integer constant */
+ {
+ struct type *type = (*pc)[1].type;
+ LONGEST k = (*pc)[2].longconst;
+ (*pc) += 4;
+ gen_int_literal (ax, value, k, type);
+ }
+ break;
+
+ case OP_VAR_VALUE:
+ gen_var_ref (ax, value, (*pc)[2].symbol);
+ (*pc) += 4;
+ break;
+
+ case OP_REGISTER:
+ {
+ int reg = (int) (*pc)[1].longconst;
+ (*pc) += 3;
+ value->kind = axs_lvalue_register;
+ value->u.reg = reg;
+ value->type = REGISTER_VIRTUAL_TYPE (reg);
+ }
+ break;
+
+ case OP_INTERNALVAR:
+ error ("GDB agent expressions cannot use convenience variables.");
+
+ /* Weirdo operator: see comments for gen_repeat for details. */
+ case BINOP_REPEAT:
+ /* Note that gen_repeat handles its own argument evaluation. */
+ (*pc)++;
+ gen_repeat (pc, ax, value);
+ break;
+
+ case UNOP_CAST:
+ {
+ struct type *type = (*pc)[1].type;
+ (*pc) += 3;
+ gen_expr (pc, ax, value);
+ gen_cast (ax, value, type);
+ }
+ break;
+
+ case UNOP_MEMVAL:
+ {
+ struct type *type = check_typedef ((*pc)[1].type);
+ (*pc) += 3;
+ gen_expr (pc, ax, value);
+ /* I'm not sure I understand UNOP_MEMVAL entirely. I think
+ it's just a hack for dealing with minsyms; you take some
+ integer constant, pretend it's the address of an lvalue of
+ the given type, and dereference it. */
+ if (value->kind != axs_rvalue)
+ /* This would be weird. */
+ internal_error (__FILE__, __LINE__,
+ "gen_expr: OP_MEMVAL operand isn't an rvalue???");
+ value->type = type;
+ value->kind = axs_lvalue_memory;
+ }
+ break;
+
+ case UNOP_NEG:
+ (*pc)++;
+ /* -FOO is equivalent to 0 - FOO. */
+ gen_int_literal (ax, &value1, (LONGEST) 0, builtin_type_int);
+ gen_usual_unary (ax, &value1); /* shouldn't do much */
+ gen_expr (pc, ax, &value2);
+ gen_usual_unary (ax, &value2);
+ gen_usual_arithmetic (ax, &value1, &value2);
+ gen_sub (ax, value, &value1, &value2);
+ break;
+
+ case UNOP_LOGICAL_NOT:
+ (*pc)++;
+ gen_expr (pc, ax, value);
+ gen_logical_not (ax, value);
+ break;
+
+ case UNOP_COMPLEMENT:
+ (*pc)++;
+ gen_expr (pc, ax, value);
+ gen_complement (ax, value);
+ break;
+
+ case UNOP_IND:
+ (*pc)++;
+ gen_expr (pc, ax, value);
+ gen_usual_unary (ax, value);
+ if (TYPE_CODE (value->type) != TYPE_CODE_PTR)
+ error ("Argument of unary `*' is not a pointer.");
+ gen_deref (ax, value);
+ break;
+
+ case UNOP_ADDR:
+ (*pc)++;
+ gen_expr (pc, ax, value);
+ gen_address_of (ax, value);
+ break;
+
+ case UNOP_SIZEOF:
+ (*pc)++;
+ /* Notice that gen_sizeof handles its own operand, unlike most
+ of the other unary operator functions. This is because we
+ have to throw away the code we generate. */
+ gen_sizeof (pc, ax, value);
+ break;
+
+ case STRUCTOP_STRUCT:
+ case STRUCTOP_PTR:
+ {
+ int length = (*pc)[1].longconst;
+ char *name = &(*pc)[2].string;
+
+ (*pc) += 4 + BYTES_TO_EXP_ELEM (length + 1);
+ gen_expr (pc, ax, value);
+ if (op == STRUCTOP_STRUCT)
+ gen_struct_ref (ax, value, name, ".", "structure or union");
+ else if (op == STRUCTOP_PTR)
+ gen_struct_ref (ax, value, name, "->",
+ "pointer to a structure or union");
+ else
+ /* If this `if' chain doesn't handle it, then the case list
+ shouldn't mention it, and we shouldn't be here. */
+ internal_error (__FILE__, __LINE__,
+ "gen_expr: unhandled struct case");
+ }
+ break;
+
+ case OP_TYPE:
+ error ("Attempt to use a type name as an expression.");
+
+ default:
+ error ("Unsupported operator in expression.");
+ }
+}
+
+
+
+/* Generating bytecode from GDB expressions: driver */
+
+/* Given a GDB expression EXPR, produce a string of agent bytecode
+ which computes its value. Return the agent expression, and set
+ *VALUE to describe its type, and whether it's an lvalue or rvalue. */
+struct agent_expr *
+expr_to_agent (struct expression *expr, struct axs_value *value)
+{
+ struct cleanup *old_chain = 0;
+ struct agent_expr *ax = new_agent_expr (0);
+ union exp_element *pc;
+
+ old_chain = make_cleanup_free_agent_expr (ax);
+
+ pc = expr->elts;
+ trace_kludge = 0;
+ gen_expr (&pc, ax, value);
+
+ /* We have successfully built the agent expr, so cancel the cleanup
+ request. If we add more cleanups that we always want done, this
+ will have to get more complicated. */
+ discard_cleanups (old_chain);
+ return ax;
+}
+
+
+#if 0 /* not used */
+/* Given a GDB expression EXPR denoting an lvalue in memory, produce a
+ string of agent bytecode which will leave its address and size on
+ the top of stack. Return the agent expression.
+
+ Not sure this function is useful at all. */
+struct agent_expr *
+expr_to_address_and_size (struct expression *expr)
+{
+ struct axs_value value;
+ struct agent_expr *ax = expr_to_agent (expr, &value);
+
+ /* Complain if the result is not a memory lvalue. */
+ if (value.kind != axs_lvalue_memory)
+ {
+ free_agent_expr (ax);
+ error ("Expression does not denote an object in memory.");
+ }
+
+ /* Push the object's size on the stack. */
+ ax_const_l (ax, TYPE_LENGTH (value.type));
+
+ return ax;
+}
+#endif
+
+/* Given a GDB expression EXPR, return bytecode to trace its value.
+ The result will use the `trace' and `trace_quick' bytecodes to
+ record the value of all memory touched by the expression. The
+ caller can then use the ax_reqs function to discover which
+ registers it relies upon. */
+struct agent_expr *
+gen_trace_for_expr (CORE_ADDR scope, struct expression *expr)
+{
+ struct cleanup *old_chain = 0;
+ struct agent_expr *ax = new_agent_expr (scope);
+ union exp_element *pc;
+ struct axs_value value;
+
+ old_chain = make_cleanup_free_agent_expr (ax);
+
+ pc = expr->elts;
+ trace_kludge = 1;
+ gen_expr (&pc, ax, &value);
+
+ /* Make sure we record the final object, and get rid of it. */
+ gen_traced_pop (ax, &value);
+
+ /* Oh, and terminate. */
+ ax_simple (ax, aop_end);
+
+ /* We have successfully built the agent expr, so cancel the cleanup
+ request. If we add more cleanups that we always want done, this
+ will have to get more complicated. */
+ discard_cleanups (old_chain);
+ return ax;
+}
+
+
+
+/* The "agent" command, for testing: compile and disassemble an expression. */
+
+static void
+print_axs_value (struct ui_file *f, struct axs_value *value)
+{
+ switch (value->kind)
+ {
+ case axs_rvalue:
+ fputs_filtered ("rvalue", f);
+ break;
+
+ case axs_lvalue_memory:
+ fputs_filtered ("memory lvalue", f);
+ break;
+
+ case axs_lvalue_register:
+ fprintf_filtered (f, "register %d lvalue", value->u.reg);
+ break;
+ }
+
+ fputs_filtered (" : ", f);
+ type_print (value->type, "", f, -1);
+}
+
+
+static void
+agent_command (char *exp, int from_tty)
+{
+ struct cleanup *old_chain = 0;
+ struct expression *expr;
+ struct agent_expr *agent;
+ struct frame_info *fi = get_current_frame (); /* need current scope */
+
+ /* We don't deal with overlay debugging at the moment. We need to
+ think more carefully about this. If you copy this code into
+ another command, change the error message; the user shouldn't
+ have to know anything about agent expressions. */
+ if (overlay_debugging)
+ error ("GDB can't do agent expression translation with overlays.");
+
+ if (exp == 0)
+ error_no_arg ("expression to translate");
+
+ expr = parse_expression (exp);
+ old_chain = make_cleanup (free_current_contents, &expr);
+ agent = gen_trace_for_expr (fi->pc, expr);
+ make_cleanup_free_agent_expr (agent);
+ ax_print (gdb_stdout, agent);
+
+ /* It would be nice to call ax_reqs here to gather some general info
+ about the expression, and then print out the result. */
+
+ do_cleanups (old_chain);
+ dont_repeat ();
+}
+
+
+/* Initialization code. */
+
+void _initialize_ax_gdb (void);
+void
+_initialize_ax_gdb (void)
+{
+ add_cmd ("agent", class_maintenance, agent_command,
+ "Translate an expression into remote agent bytecode.",
+ &maintenancelist);
+}
diff --git a/gdb/ax-gdb.h b/gdb/ax-gdb.h
new file mode 100644
index 00000000000..3e1006a3112
--- /dev/null
+++ b/gdb/ax-gdb.h
@@ -0,0 +1,112 @@
+/* GDB-specific functions for operating on agent expressions
+ Copyright 1998, 1999, 2000 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. */
+
+#ifndef AX_GDB_H
+#define AX_GDB_H
+
+
+/* Types and enums */
+
+/* GDB stores expressions in the form of a flattened tree (struct
+ expression), so we just walk that tree and generate agent bytecodes
+ as we go along.
+
+ GDB's normal evaluation uses struct value, which contains the
+ expression's value as well as its address or the register it came
+ from. The `+' operator uses the value, whereas the unary `&'
+ operator will use the address portion. The `=' operator will use
+ the address or register number of its left hand side.
+
+ The issues are different when generating agent bytecode. Given a
+ variable reference expression, we should not necessarily generate
+ code to fetch its value, because the next operator may be `=' or
+ unary `&'. Instead, when we recurse on a subexpression, we
+ indicate whether we want that expression to produce an lvalue or an
+ rvalue. If we requested an lvalue, then the recursive call tells
+ us whether it generated code to compute an address on the stack, or
+ whether the lvalue lives in a register.
+
+ The `axs' prefix here means `agent expression, static', because
+ this is all static analysis of the expression, i.e. analysis which
+ doesn't depend on the contents of memory and registers. */
+
+
+/* Different kinds of agent expression static values. */
+enum axs_lvalue_kind
+ {
+ /* We generated code to compute the subexpression's value.
+ Constants and arithmetic operators yield this. */
+ axs_rvalue,
+
+ /* We generated code to yield the subexpression's value's address on
+ the top of the stack. If the caller needs an rvalue, it should
+ call require_rvalue to produce the rvalue from this address. */
+ axs_lvalue_memory,
+
+ /* We didn't generate any code, and the stack is undisturbed,
+ because the subexpression's value lives in a register; u.reg is
+ the register number. If the caller needs an rvalue, it should
+ call require_rvalue to produce the rvalue from this register
+ number. */
+ axs_lvalue_register
+ };
+
+/* Structure describing what we got from a subexpression. Think of
+ this as parallel to value.h's enum lval_type, except that we're
+ describing a value which will exist when the expression is
+ evaluated in the future, not a value we have in our hand. */
+struct axs_value
+ {
+ enum axs_lvalue_kind kind; /* see above */
+
+ /* The type of the subexpression. Even if lvalue == axs_lvalue_memory,
+ this is the type of the value itself; the value on the stack is a
+ "pointer to" an object of this type. */
+ struct type *type;
+
+ union
+ {
+ /* if kind == axs_lvalue_register, this is the register number */
+ int reg;
+ }
+ u;
+ };
+
+
+/* Translating GDB expressions into agent expressions. */
+
+/* Given a GDB expression EXPR, translate it into the agent bytecode,
+ and return it. FLAGS are from enum expr_to_agent_flags. */
+extern struct agent_expr *expr_to_agent (struct expression *EXPR,
+ struct axs_value *VALUE);
+
+/* Given a GDB expression EXPR denoting an lvalue in memory, produce a
+ string of agent bytecode which will leave its address and size on
+ the top of stack. Return the agent expression. */
+extern struct agent_expr *expr_to_address_and_size (struct expression *EXPR);
+
+/* Given a GDB expression EXPR, return bytecode to trace its value.
+ The result will use the `trace' and `trace_quick' bytecodes to
+ record the value of all memory touched by the expression, and leave
+ no values on the stack. The caller can then use the ax_reqs
+ function to discover which registers the expression uses. */
+extern struct agent_expr *gen_trace_for_expr (CORE_ADDR, struct expression *);
+
+#endif /* AX_GDB_H */
diff --git a/gdb/ax-general.c b/gdb/ax-general.c
new file mode 100644
index 00000000000..9451837b97e
--- /dev/null
+++ b/gdb/ax-general.c
@@ -0,0 +1,541 @@
+/* Functions for manipulating expressions designed to be executed on the agent
+ Copyright 1998, 1999, 2000 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. */
+
+/* Despite what the above comment says about this file being part of
+ GDB, we would like to keep these functions free of GDB
+ dependencies, since we want to be able to use them in contexts
+ outside of GDB (test suites, the stub, etc.) */
+
+#include "defs.h"
+#include "ax.h"
+
+#include "value.h"
+
+static void grow_expr (struct agent_expr *x, int n);
+
+static void append_const (struct agent_expr *x, LONGEST val, int n);
+
+static LONGEST read_const (struct agent_expr *x, int o, int n);
+
+static void generic_ext (struct agent_expr *x, enum agent_op op, int n);
+
+/* Functions for building expressions. */
+
+/* Allocate a new, empty agent expression. */
+struct agent_expr *
+new_agent_expr (CORE_ADDR scope)
+{
+ struct agent_expr *x = xmalloc (sizeof (*x));
+ x->len = 0;
+ x->size = 1; /* Change this to a larger value once
+ reallocation code is tested. */
+ x->buf = xmalloc (x->size);
+ x->scope = scope;
+
+ return x;
+}
+
+/* Free a agent expression. */
+void
+free_agent_expr (struct agent_expr *x)
+{
+ xfree (x->buf);
+ xfree (x);
+}
+
+static void
+do_free_agent_expr_cleanup (void *x)
+{
+ free_agent_expr (x);
+}
+
+struct cleanup *
+make_cleanup_free_agent_expr (struct agent_expr *x)
+{
+ return make_cleanup (do_free_agent_expr_cleanup, x);
+}
+
+
+/* Make sure that X has room for at least N more bytes. This doesn't
+ affect the length, just the allocated size. */
+static void
+grow_expr (struct agent_expr *x, int n)
+{
+ if (x->len + n > x->size)
+ {
+ x->size *= 2;
+ if (x->size < x->len + n)
+ x->size = x->len + n + 10;
+ x->buf = xrealloc (x->buf, x->size);
+ }
+}
+
+
+/* Append the low N bytes of VAL as an N-byte integer to the
+ expression X, in big-endian order. */
+static void
+append_const (struct agent_expr *x, LONGEST val, int n)
+{
+ int i;
+
+ grow_expr (x, n);
+ for (i = n - 1; i >= 0; i--)
+ {
+ x->buf[x->len + i] = val & 0xff;
+ val >>= 8;
+ }
+ x->len += n;
+}
+
+
+/* Extract an N-byte big-endian unsigned integer from expression X at
+ offset O. */
+static LONGEST
+read_const (struct agent_expr *x, int o, int n)
+{
+ int i;
+ LONGEST accum = 0;
+
+ /* Make sure we're not reading off the end of the expression. */
+ if (o + n > x->len)
+ error ("GDB bug: ax-general.c (read_const): incomplete constant");
+
+ for (i = 0; i < n; i++)
+ accum = (accum << 8) | x->buf[o + i];
+
+ return accum;
+}
+
+
+/* Append a simple operator OP to EXPR. */
+void
+ax_simple (struct agent_expr *x, enum agent_op op)
+{
+ grow_expr (x, 1);
+ x->buf[x->len++] = op;
+}
+
+
+/* Append a sign-extension or zero-extension instruction to EXPR, to
+ extend an N-bit value. */
+static void
+generic_ext (struct agent_expr *x, enum agent_op op, int n)
+{
+ /* N must fit in a byte. */
+ if (n < 0 || n > 255)
+ error ("GDB bug: ax-general.c (generic_ext): bit count out of range");
+ /* That had better be enough range. */
+ if (sizeof (LONGEST) * 8 > 255)
+ error ("GDB bug: ax-general.c (generic_ext): opcode has inadequate range");
+
+ grow_expr (x, 2);
+ x->buf[x->len++] = op;
+ x->buf[x->len++] = n;
+}
+
+
+/* Append a sign-extension instruction to EXPR, to extend an N-bit value. */
+void
+ax_ext (struct agent_expr *x, int n)
+{
+ generic_ext (x, aop_ext, n);
+}
+
+
+/* Append a zero-extension instruction to EXPR, to extend an N-bit value. */
+void
+ax_zero_ext (struct agent_expr *x, int n)
+{
+ generic_ext (x, aop_zero_ext, n);
+}
+
+
+/* Append a trace_quick instruction to EXPR, to record N bytes. */
+void
+ax_trace_quick (struct agent_expr *x, int n)
+{
+ /* N must fit in a byte. */
+ if (n < 0 || n > 255)
+ error ("GDB bug: ax-general.c (ax_trace_quick): size out of range for trace_quick");
+
+ grow_expr (x, 2);
+ x->buf[x->len++] = aop_trace_quick;
+ x->buf[x->len++] = n;
+}
+
+
+/* Append a goto op to EXPR. OP is the actual op (must be aop_goto or
+ aop_if_goto). We assume we don't know the target offset yet,
+ because it's probably a forward branch, so we leave space in EXPR
+ for the target, and return the offset in EXPR of that space, so we
+ can backpatch it once we do know the target offset. Use ax_label
+ to do the backpatching. */
+int
+ax_goto (struct agent_expr *x, enum agent_op op)
+{
+ grow_expr (x, 3);
+ x->buf[x->len + 0] = op;
+ x->buf[x->len + 1] = 0xff;
+ x->buf[x->len + 2] = 0xff;
+ x->len += 3;
+ return x->len - 2;
+}
+
+/* Suppose a given call to ax_goto returns some value PATCH. When you
+ know the offset TARGET that goto should jump to, call
+ ax_label (EXPR, PATCH, TARGET)
+ to patch TARGET into the ax_goto instruction. */
+void
+ax_label (struct agent_expr *x, int patch, int target)
+{
+ /* Make sure the value is in range. Don't accept 0xffff as an
+ offset; that's our magic sentinel value for unpatched branches. */
+ if (target < 0 || target >= 0xffff)
+ error ("GDB bug: ax-general.c (ax_label): label target out of range");
+
+ x->buf[patch] = (target >> 8) & 0xff;
+ x->buf[patch + 1] = target & 0xff;
+}
+
+
+/* Assemble code to push a constant on the stack. */
+void
+ax_const_l (struct agent_expr *x, LONGEST l)
+{
+ static enum agent_op ops[]
+ =
+ {aop_const8, aop_const16, aop_const32, aop_const64};
+ int size;
+ int op;
+
+ /* How big is the number? 'op' keeps track of which opcode to use.
+ Notice that we don't really care whether the original number was
+ signed or unsigned; we always reproduce the value exactly, and
+ use the shortest representation. */
+ for (op = 0, size = 8; size < 64; size *= 2, op++)
+ if (-((LONGEST) 1 << size) <= l && l < ((LONGEST) 1 << size))
+ break;
+
+ /* Emit the right opcode... */
+ ax_simple (x, ops[op]);
+
+ /* Emit the low SIZE bytes as an unsigned number. We know that
+ sign-extending this will yield l. */
+ append_const (x, l, size / 8);
+
+ /* Now, if it was negative, and not full-sized, sign-extend it. */
+ if (l < 0 && size < 64)
+ ax_ext (x, size);
+}
+
+
+void
+ax_const_d (struct agent_expr *x, LONGEST d)
+{
+ /* FIXME: floating-point support not present yet. */
+ error ("GDB bug: ax-general.c (ax_const_d): floating point not supported yet");
+}
+
+
+/* Assemble code to push the value of register number REG on the
+ stack. */
+void
+ax_reg (struct agent_expr *x, int reg)
+{
+ /* Make sure the register number is in range. */
+ if (reg < 0 || reg > 0xffff)
+ error ("GDB bug: ax-general.c (ax_reg): register number out of range");
+ grow_expr (x, 3);
+ x->buf[x->len] = aop_reg;
+ x->buf[x->len + 1] = (reg >> 8) & 0xff;
+ x->buf[x->len + 2] = (reg) & 0xff;
+ x->len += 3;
+}
+
+
+
+/* Functions for disassembling agent expressions, and otherwise
+ debugging the expression compiler. */
+
+struct aop_map aop_map[] =
+{
+ {0, 0, 0, 0, 0},
+ {"float", 0, 0, 0, 0}, /* 0x01 */
+ {"add", 0, 0, 2, 1}, /* 0x02 */
+ {"sub", 0, 0, 2, 1}, /* 0x03 */
+ {"mul", 0, 0, 2, 1}, /* 0x04 */
+ {"div_signed", 0, 0, 2, 1}, /* 0x05 */
+ {"div_unsigned", 0, 0, 2, 1}, /* 0x06 */
+ {"rem_signed", 0, 0, 2, 1}, /* 0x07 */
+ {"rem_unsigned", 0, 0, 2, 1}, /* 0x08 */
+ {"lsh", 0, 0, 2, 1}, /* 0x09 */
+ {"rsh_signed", 0, 0, 2, 1}, /* 0x0a */
+ {"rsh_unsigned", 0, 0, 2, 1}, /* 0x0b */
+ {"trace", 0, 0, 2, 0}, /* 0x0c */
+ {"trace_quick", 1, 0, 1, 1}, /* 0x0d */
+ {"log_not", 0, 0, 1, 1}, /* 0x0e */
+ {"bit_and", 0, 0, 2, 1}, /* 0x0f */
+ {"bit_or", 0, 0, 2, 1}, /* 0x10 */
+ {"bit_xor", 0, 0, 2, 1}, /* 0x11 */
+ {"bit_not", 0, 0, 1, 1}, /* 0x12 */
+ {"equal", 0, 0, 2, 1}, /* 0x13 */
+ {"less_signed", 0, 0, 2, 1}, /* 0x14 */
+ {"less_unsigned", 0, 0, 2, 1}, /* 0x15 */
+ {"ext", 1, 0, 1, 1}, /* 0x16 */
+ {"ref8", 0, 8, 1, 1}, /* 0x17 */
+ {"ref16", 0, 16, 1, 1}, /* 0x18 */
+ {"ref32", 0, 32, 1, 1}, /* 0x19 */
+ {"ref64", 0, 64, 1, 1}, /* 0x1a */
+ {"ref_float", 0, 0, 1, 1}, /* 0x1b */
+ {"ref_double", 0, 0, 1, 1}, /* 0x1c */
+ {"ref_long_double", 0, 0, 1, 1}, /* 0x1d */
+ {"l_to_d", 0, 0, 1, 1}, /* 0x1e */
+ {"d_to_l", 0, 0, 1, 1}, /* 0x1f */
+ {"if_goto", 2, 0, 1, 0}, /* 0x20 */
+ {"goto", 2, 0, 0, 0}, /* 0x21 */
+ {"const8", 1, 8, 0, 1}, /* 0x22 */
+ {"const16", 2, 16, 0, 1}, /* 0x23 */
+ {"const32", 4, 32, 0, 1}, /* 0x24 */
+ {"const64", 8, 64, 0, 1}, /* 0x25 */
+ {"reg", 2, 0, 0, 1}, /* 0x26 */
+ {"end", 0, 0, 0, 0}, /* 0x27 */
+ {"dup", 0, 0, 1, 2}, /* 0x28 */
+ {"pop", 0, 0, 1, 0}, /* 0x29 */
+ {"zero_ext", 1, 0, 1, 1}, /* 0x2a */
+ {"swap", 0, 0, 2, 2}, /* 0x2b */
+ {0, 0, 0, 0, 0}, /* 0x2c */
+ {0, 0, 0, 0, 0}, /* 0x2d */
+ {0, 0, 0, 0, 0}, /* 0x2e */
+ {0, 0, 0, 0, 0}, /* 0x2f */
+ {"trace16", 2, 0, 1, 1}, /* 0x30 */
+};
+
+
+/* Disassemble the expression EXPR, writing to F. */
+void
+ax_print (struct ui_file *f, struct agent_expr *x)
+{
+ int i;
+ int is_float = 0;
+
+ /* Check the size of the name array against the number of entries in
+ the enum, to catch additions that people didn't sync. */
+ if ((sizeof (aop_map) / sizeof (aop_map[0]))
+ != aop_last)
+ error ("GDB bug: ax-general.c (ax_print): opcode map out of sync");
+
+ for (i = 0; i < x->len;)
+ {
+ enum agent_op op = x->buf[i];
+
+ if (op >= (sizeof (aop_map) / sizeof (aop_map[0]))
+ || !aop_map[op].name)
+ {
+ fprintf_filtered (f, "%3d <bad opcode %02x>\n", i, op);
+ i++;
+ continue;
+ }
+ if (i + 1 + aop_map[op].op_size > x->len)
+ {
+ fprintf_filtered (f, "%3d <incomplete opcode %s>\n",
+ i, aop_map[op].name);
+ break;
+ }
+
+ fprintf_filtered (f, "%3d %s", i, aop_map[op].name);
+ if (aop_map[op].op_size > 0)
+ {
+ fputs_filtered (" ", f);
+
+ print_longest (f, 'd', 0,
+ read_const (x, i + 1, aop_map[op].op_size));
+ }
+ fprintf_filtered (f, "\n");
+ i += 1 + aop_map[op].op_size;
+
+ is_float = (op == aop_float);
+ }
+}
+
+
+/* Given an agent expression AX, fill in an agent_reqs structure REQS
+ describing it. */
+void
+ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs)
+{
+ int i;
+ int height;
+
+ /* Bit vector for registers used. */
+ int reg_mask_len = 1;
+ unsigned char *reg_mask = xmalloc (reg_mask_len * sizeof (reg_mask[0]));
+
+ /* Jump target table. targets[i] is non-zero iff there is a jump to
+ offset i. */
+ char *targets = (char *) alloca (ax->len * sizeof (targets[0]));
+
+ /* Instruction boundary table. boundary[i] is non-zero iff an
+ instruction starts at offset i. */
+ char *boundary = (char *) alloca (ax->len * sizeof (boundary[0]));
+
+ /* Stack height record. iff either targets[i] or boundary[i] is
+ non-zero, heights[i] is the height the stack should have before
+ executing the bytecode at that point. */
+ int *heights = (int *) alloca (ax->len * sizeof (heights[0]));
+
+ /* Pointer to a description of the present op. */
+ struct aop_map *op;
+
+ memset (reg_mask, 0, reg_mask_len * sizeof (reg_mask[0]));
+ memset (targets, 0, ax->len * sizeof (targets[0]));
+ memset (boundary, 0, ax->len * sizeof (boundary[0]));
+
+ reqs->max_height = reqs->min_height = height = 0;
+ reqs->flaw = agent_flaw_none;
+ reqs->max_data_size = 0;
+
+ for (i = 0; i < ax->len; i += 1 + op->op_size)
+ {
+ if (ax->buf[i] > (sizeof (aop_map) / sizeof (aop_map[0])))
+ {
+ reqs->flaw = agent_flaw_bad_instruction;
+ xfree (reg_mask);
+ return;
+ }
+
+ op = &aop_map[ax->buf[i]];
+
+ if (!op->name)
+ {
+ reqs->flaw = agent_flaw_bad_instruction;
+ xfree (reg_mask);
+ return;
+ }
+
+ if (i + 1 + op->op_size > ax->len)
+ {
+ reqs->flaw = agent_flaw_incomplete_instruction;
+ xfree (reg_mask);
+ return;
+ }
+
+ /* If this instruction is a jump target, does the current stack
+ height match the stack height at the jump source? */
+ if (targets[i] && (heights[i] != height))
+ {
+ reqs->flaw = agent_flaw_height_mismatch;
+ xfree (reg_mask);
+ return;
+ }
+
+ boundary[i] = 1;
+ heights[i] = height;
+
+ height -= op->consumed;
+ if (height < reqs->min_height)
+ reqs->min_height = height;
+ height += op->produced;
+ if (height > reqs->max_height)
+ reqs->max_height = height;
+
+ if (op->data_size > reqs->max_data_size)
+ reqs->max_data_size = op->data_size;
+
+ /* For jump instructions, check that the target is a valid
+ offset. If it is, record the fact that that location is a
+ jump target, and record the height we expect there. */
+ if (aop_goto == op - aop_map
+ || aop_if_goto == op - aop_map)
+ {
+ int target = read_const (ax, i + 1, 2);
+ if (target < 0 || target >= ax->len)
+ {
+ reqs->flaw = agent_flaw_bad_jump;
+ xfree (reg_mask);
+ return;
+ }
+ /* Have we already found other jumps to the same location? */
+ else if (targets[target])
+ {
+ if (heights[i] != height)
+ {
+ reqs->flaw = agent_flaw_height_mismatch;
+ xfree (reg_mask);
+ return;
+ }
+ }
+ else
+ {
+ targets[target] = 1;
+ heights[target] = height;
+ }
+ }
+
+ /* For unconditional jumps with a successor, check that the
+ successor is a target, and pick up its stack height. */
+ if (aop_goto == op - aop_map
+ && i + 3 < ax->len)
+ {
+ if (!targets[i + 3])
+ {
+ reqs->flaw = agent_flaw_hole;
+ xfree (reg_mask);
+ return;
+ }
+
+ height = heights[i + 3];
+ }
+
+ /* For reg instructions, record the register in the bit mask. */
+ if (aop_reg == op - aop_map)
+ {
+ int reg = read_const (ax, i + 1, 2);
+ int byte = reg / 8;
+
+ /* Grow the bit mask if necessary. */
+ if (byte >= reg_mask_len)
+ {
+ /* It's not appropriate to double here. This isn't a
+ string buffer. */
+ int new_len = byte + 1;
+ reg_mask = xrealloc (reg_mask,
+ new_len * sizeof (reg_mask[0]));
+ memset (reg_mask + reg_mask_len, 0,
+ (new_len - reg_mask_len) * sizeof (reg_mask[0]));
+ reg_mask_len = new_len;
+ }
+
+ reg_mask[byte] |= 1 << (reg % 8);
+ }
+ }
+
+ /* Check that all the targets are on boundaries. */
+ for (i = 0; i < ax->len; i++)
+ if (targets[i] && !boundary[i])
+ {
+ reqs->flaw = agent_flaw_bad_jump;
+ xfree (reg_mask);
+ return;
+ }
+
+ reqs->final_height = height;
+ reqs->reg_mask_len = reg_mask_len;
+ reqs->reg_mask = reg_mask;
+}
diff --git a/gdb/ax.h b/gdb/ax.h
new file mode 100644
index 00000000000..708dba42e7f
--- /dev/null
+++ b/gdb/ax.h
@@ -0,0 +1,292 @@
+/* Definitions for expressions designed to be executed on the agent
+ Copyright 1998, 1999, 2000 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. */
+
+#ifndef AGENTEXPR_H
+#define AGENTEXPR_H
+
+#include "doublest.h" /* For DOUBLEST. */
+
+/* It's sometimes useful to be able to debug programs that you can't
+ really stop for more than a fraction of a second. To this end, the
+ user can specify a tracepoint (like a breakpoint, but you don't
+ stop at it), and specify a bunch of expressions to record the
+ values of when that tracepoint is reached. As the program runs,
+ GDB collects the values. At any point (possibly while values are
+ still being collected), the user can display the collected values.
+
+ This is used with remote debugging; we don't really support it on
+ native configurations.
+
+ This means that expressions are being evaluated by the remote agent,
+ which doesn't have any access to the symbol table information, and
+ needs to be small and simple.
+
+ The agent_expr routines and datatypes are a bytecode language
+ designed to be executed by the agent. Agent expressions work in
+ terms of fixed-width values, operators, memory references, and
+ register references. You can evaluate a agent expression just given
+ a bunch of memory and register values to sniff at; you don't need
+ any symbolic information like variable names, types, etc.
+
+ GDB translates source expressions, whose meaning depends on
+ symbolic information, into agent bytecode expressions, whose meaning
+ is independent of symbolic information. This means the agent can
+ evaluate them on the fly without reference to data only available
+ to the host GDB. */
+
+
+/* Agent expression data structures. */
+
+/* The type of an element of the agent expression stack.
+ The bytecode operation indicates which element we should access;
+ the value itself has no typing information. GDB generates all
+ bytecode streams, so we don't have to worry about type errors. */
+
+union agent_val
+ {
+ LONGEST l;
+ DOUBLEST d;
+ };
+
+/* A buffer containing a agent expression. */
+struct agent_expr
+ {
+ unsigned char *buf;
+ int len; /* number of characters used */
+ int size; /* allocated size */
+ CORE_ADDR scope;
+ };
+
+
+
+
+/* The actual values of the various bytecode operations.
+
+ Other independent implementations of the agent bytecode engine will
+ rely on the exact values of these enums, and may not be recompiled
+ when we change this table. The numeric values should remain fixed
+ whenever possible. Thus, we assign them values explicitly here (to
+ allow gaps to form safely), and the disassembly table in
+ agentexpr.h behaves like an opcode map. If you want to see them
+ grouped logically, see doc/agentexpr.texi. */
+
+enum agent_op
+ {
+ aop_float = 0x01,
+ aop_add = 0x02,
+ aop_sub = 0x03,
+ aop_mul = 0x04,
+ aop_div_signed = 0x05,
+ aop_div_unsigned = 0x06,
+ aop_rem_signed = 0x07,
+ aop_rem_unsigned = 0x08,
+ aop_lsh = 0x09,
+ aop_rsh_signed = 0x0a,
+ aop_rsh_unsigned = 0x0b,
+ aop_trace = 0x0c,
+ aop_trace_quick = 0x0d,
+ aop_log_not = 0x0e,
+ aop_bit_and = 0x0f,
+ aop_bit_or = 0x10,
+ aop_bit_xor = 0x11,
+ aop_bit_not = 0x12,
+ aop_equal = 0x13,
+ aop_less_signed = 0x14,
+ aop_less_unsigned = 0x15,
+ aop_ext = 0x16,
+ aop_ref8 = 0x17,
+ aop_ref16 = 0x18,
+ aop_ref32 = 0x19,
+ aop_ref64 = 0x1a,
+ aop_ref_float = 0x1b,
+ aop_ref_double = 0x1c,
+ aop_ref_long_double = 0x1d,
+ aop_l_to_d = 0x1e,
+ aop_d_to_l = 0x1f,
+ aop_if_goto = 0x20,
+ aop_goto = 0x21,
+ aop_const8 = 0x22,
+ aop_const16 = 0x23,
+ aop_const32 = 0x24,
+ aop_const64 = 0x25,
+ aop_reg = 0x26,
+ aop_end = 0x27,
+ aop_dup = 0x28,
+ aop_pop = 0x29,
+ aop_zero_ext = 0x2a,
+ aop_swap = 0x2b,
+ aop_trace16 = 0x30,
+ aop_last
+ };
+
+
+
+/* Functions for building expressions. */
+
+/* Allocate a new, empty agent expression. */
+extern struct agent_expr *new_agent_expr (CORE_ADDR);
+
+/* Free a agent expression. */
+extern void free_agent_expr (struct agent_expr *);
+extern struct cleanup *make_cleanup_free_agent_expr (struct agent_expr *);
+
+/* Append a simple operator OP to EXPR. */
+extern void ax_simple (struct agent_expr *EXPR, enum agent_op OP);
+
+/* Append the floating-point prefix, for the next bytecode. */
+#define ax_float(EXPR) (ax_simple ((EXPR), aop_float))
+
+/* Append a sign-extension instruction to EXPR, to extend an N-bit value. */
+extern void ax_ext (struct agent_expr *EXPR, int N);
+
+/* Append a zero-extension instruction to EXPR, to extend an N-bit value. */
+extern void ax_zero_ext (struct agent_expr *EXPR, int N);
+
+/* Append a trace_quick instruction to EXPR, to record N bytes. */
+extern void ax_trace_quick (struct agent_expr *EXPR, int N);
+
+/* Append a goto op to EXPR. OP is the actual op (must be aop_goto or
+ aop_if_goto). We assume we don't know the target offset yet,
+ because it's probably a forward branch, so we leave space in EXPR
+ for the target, and return the offset in EXPR of that space, so we
+ can backpatch it once we do know the target offset. Use ax_label
+ to do the backpatching. */
+extern int ax_goto (struct agent_expr *EXPR, enum agent_op OP);
+
+/* Suppose a given call to ax_goto returns some value PATCH. When you
+ know the offset TARGET that goto should jump to, call
+ ax_label (EXPR, PATCH, TARGET)
+ to patch TARGET into the ax_goto instruction. */
+extern void ax_label (struct agent_expr *EXPR, int patch, int target);
+
+/* Assemble code to push a constant on the stack. */
+extern void ax_const_l (struct agent_expr *EXPR, LONGEST l);
+extern void ax_const_d (struct agent_expr *EXPR, LONGEST d);
+
+/* Assemble code to push the value of register number REG on the
+ stack. */
+extern void ax_reg (struct agent_expr *EXPR, int REG);
+
+
+/* Functions for printing out expressions, and otherwise debugging
+ things. */
+
+/* Disassemble the expression EXPR, writing to F. */
+extern void ax_print (struct ui_file *f, struct agent_expr * EXPR);
+
+/* An entry in the opcode map. */
+struct aop_map
+ {
+
+ /* The name of the opcode. Null means that this entry is not a
+ valid opcode --- a hole in the opcode space. */
+ char *name;
+
+ /* All opcodes take no operands from the bytecode stream, or take
+ unsigned integers of various sizes. If this is a positive number
+ n, then the opcode is followed by an n-byte operand, which should
+ be printed as an unsigned integer. If this is zero, then the
+ opcode takes no operands from the bytecode stream.
+
+ If we get more complicated opcodes in the future, don't add other
+ magic values of this; that's a crock. Add an `enum encoding'
+ field to this, or something like that. */
+ int op_size;
+
+ /* The size of the data operated upon, in bits, for bytecodes that
+ care about that (ref and const). Zero for all others. */
+ int data_size;
+
+ /* Number of stack elements consumed, and number produced. */
+ int consumed, produced;
+ };
+
+/* Map of the bytecodes, indexed by bytecode number. */
+extern struct aop_map aop_map[];
+
+/* Different kinds of flaws an agent expression might have, as
+ detected by agent_reqs. */
+enum agent_flaws
+ {
+ agent_flaw_none = 0, /* code is good */
+
+ /* There is an invalid instruction in the stream. */
+ agent_flaw_bad_instruction,
+
+ /* There is an incomplete instruction at the end of the expression. */
+ agent_flaw_incomplete_instruction,
+
+ /* agent_reqs was unable to prove that every jump target is to a
+ valid offset. Valid offsets are within the bounds of the
+ expression, and to a valid instruction boundary. */
+ agent_flaw_bad_jump,
+
+ /* agent_reqs was unable to prove to its satisfaction that, for each
+ jump target location, the stack will have the same height whether
+ that location is reached via a jump or by straight execution. */
+ agent_flaw_height_mismatch,
+
+ /* agent_reqs was unable to prove that every instruction following
+ an unconditional jump was the target of some other jump. */
+ agent_flaw_hole
+ };
+
+/* Structure describing the requirements of a bytecode expression. */
+struct agent_reqs
+ {
+
+ /* If the following is not equal to agent_flaw_none, the rest of the
+ information in this structure is suspect. */
+ enum agent_flaws flaw;
+
+ /* Number of elements left on stack at end; may be negative if expr
+ only consumes elements. */
+ int final_height;
+
+ /* Maximum and minimum stack height, relative to initial height. */
+ int max_height, min_height;
+
+ /* Largest `ref' or `const' opcode used, in bits. Zero means the
+ expression has no such instructions. */
+ int max_data_size;
+
+ /* Bit vector of registers used. Register R is used iff
+
+ reg_mask[R / 8] & (1 << (R % 8))
+
+ is non-zero. Note! You may not assume that this bitmask is long
+ enough to hold bits for all the registers of the machine; the
+ agent expression code has no idea how many registers the machine
+ has. However, the bitmask is reg_mask_len bytes long, so the
+ valid register numbers run from 0 to reg_mask_len * 8 - 1.
+
+ We're assuming eight-bit bytes. So sue me.
+
+ The caller should free reg_list when done. */
+ int reg_mask_len;
+ unsigned char *reg_mask;
+ };
+
+
+/* Given an agent expression AX, fill in an agent_reqs structure REQS
+ describing it. */
+extern void ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs);
+
+#endif /* AGENTEXPR_H */
diff --git a/gdb/bcache.c b/gdb/bcache.c
new file mode 100644
index 00000000000..73b86e8cf53
--- /dev/null
+++ b/gdb/bcache.c
@@ -0,0 +1,293 @@
+/* Implement a cached obstack.
+ Written by Fred Fish <fnf@cygnus.com>
+ Rewritten by Jim Blandy <jimb@cygnus.com>
+
+ Copyright 1999, 2000, 2002 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 "defs.h"
+#include "obstack.h"
+#include "bcache.h"
+#include "gdb_string.h" /* For memcpy declaration */
+
+#include <stddef.h>
+#include <stdlib.h>
+
+/* The old hash function was stolen from SDBM. This is what DB 3.0 uses now,
+ * and is better than the old one.
+ */
+
+unsigned long
+hash(const void *addr, int length)
+{
+ const unsigned char *k, *e;
+ unsigned long h;
+
+ k = (const unsigned char *)addr;
+ e = k+length;
+ for (h=0; k< e;++k)
+ {
+ h *=16777619;
+ h ^= *k;
+ }
+ return (h);
+}
+
+/* Growing the bcache's hash table. */
+
+/* If the average chain length grows beyond this, then we want to
+ resize our hash table. */
+#define CHAIN_LENGTH_THRESHOLD (5)
+
+static void
+expand_hash_table (struct bcache *bcache)
+{
+ /* A table of good hash table sizes. Whenever we grow, we pick the
+ next larger size from this table. sizes[i] is close to 1 << (i+10),
+ so we roughly double the table size each time. After we fall off
+ the end of this table, we just double. Don't laugh --- there have
+ been executables sighted with a gigabyte of debug info. */
+ static unsigned long sizes[] = {
+ 1021, 2053, 4099, 8191, 16381, 32771,
+ 65537, 131071, 262144, 524287, 1048573, 2097143,
+ 4194301, 8388617, 16777213, 33554467, 67108859, 134217757,
+ 268435459, 536870923, 1073741827, 2147483659UL
+ };
+ unsigned int new_num_buckets;
+ struct bstring **new_buckets;
+ unsigned int i;
+
+ /* Find the next size. */
+ new_num_buckets = bcache->num_buckets * 2;
+ for (i = 0; i < (sizeof (sizes) / sizeof (sizes[0])); i++)
+ if (sizes[i] > bcache->num_buckets)
+ {
+ new_num_buckets = sizes[i];
+ break;
+ }
+
+ /* Allocate the new table. */
+ {
+ size_t new_size = new_num_buckets * sizeof (new_buckets[0]);
+ new_buckets = (struct bstring **) xmalloc (new_size);
+ memset (new_buckets, 0, new_size);
+
+ bcache->structure_size -= (bcache->num_buckets
+ * sizeof (bcache->bucket[0]));
+ bcache->structure_size += new_size;
+ }
+
+ /* Rehash all existing strings. */
+ for (i = 0; i < bcache->num_buckets; i++)
+ {
+ struct bstring *s, *next;
+
+ for (s = bcache->bucket[i]; s; s = next)
+ {
+ struct bstring **new_bucket;
+ next = s->next;
+
+ new_bucket = &new_buckets[(hash (&s->d.data, s->length)
+ % new_num_buckets)];
+ s->next = *new_bucket;
+ *new_bucket = s;
+ }
+ }
+
+ /* Plug in the new table. */
+ if (bcache->bucket)
+ xfree (bcache->bucket);
+ bcache->bucket = new_buckets;
+ bcache->num_buckets = new_num_buckets;
+}
+
+
+/* Looking up things in the bcache. */
+
+/* The number of bytes needed to allocate a struct bstring whose data
+ is N bytes long. */
+#define BSTRING_SIZE(n) (offsetof (struct bstring, d.data) + (n))
+
+/* Find a copy of the LENGTH bytes at ADDR in BCACHE. If BCACHE has
+ never seen those bytes before, add a copy of them to BCACHE. In
+ either case, return a pointer to BCACHE's copy of that string. */
+void *
+bcache (const void *addr, int length, struct bcache *bcache)
+{
+ int hash_index;
+ struct bstring *s;
+
+ /* If our average chain length is too high, expand the hash table. */
+ if (bcache->unique_count >= bcache->num_buckets * CHAIN_LENGTH_THRESHOLD)
+ expand_hash_table (bcache);
+
+ bcache->total_count++;
+ bcache->total_size += length;
+
+ hash_index = hash (addr, length) % bcache->num_buckets;
+
+ /* Search the hash bucket for a string identical to the caller's. */
+ for (s = bcache->bucket[hash_index]; s; s = s->next)
+ if (s->length == length
+ && ! memcmp (&s->d.data, addr, length))
+ return &s->d.data;
+
+ /* The user's string isn't in the list. Insert it after *ps. */
+ {
+ struct bstring *new
+ = obstack_alloc (&bcache->cache, BSTRING_SIZE (length));
+ memcpy (&new->d.data, addr, length);
+ new->length = length;
+ new->next = bcache->bucket[hash_index];
+ bcache->bucket[hash_index] = new;
+
+ bcache->unique_count++;
+ bcache->unique_size += length;
+ bcache->structure_size += BSTRING_SIZE (length);
+
+ return &new->d.data;
+ }
+}
+
+
+/* Freeing bcaches. */
+
+/* Free all the storage associated with BCACHE. */
+void
+free_bcache (struct bcache *bcache)
+{
+ obstack_free (&bcache->cache, 0);
+ if (bcache->bucket)
+ xfree (bcache->bucket);
+
+ /* This isn't necessary, but at least the bcache is always in a
+ consistent state. */
+ memset (bcache, 0, sizeof (*bcache));
+}
+
+
+
+/* Printing statistics. */
+
+static int
+compare_ints (const void *ap, const void *bp)
+{
+ /* Because we know we're comparing two ints which are positive,
+ there's no danger of overflow here. */
+ return * (int *) ap - * (int *) bp;
+}
+
+
+static void
+print_percentage (int portion, int total)
+{
+ if (total == 0)
+ printf_filtered ("(not applicable)\n");
+ else
+ printf_filtered ("%3d%%\n", portion * 100 / total);
+}
+
+
+/* Print statistics on BCACHE's memory usage and efficacity at
+ eliminating duplication. NAME should describe the kind of data
+ BCACHE holds. Statistics are printed using `printf_filtered' and
+ its ilk. */
+void
+print_bcache_statistics (struct bcache *c, char *type)
+{
+ int occupied_buckets;
+ int max_chain_length;
+ int median_chain_length;
+
+ /* Count the number of occupied buckets, and measure chain lengths. */
+ {
+ unsigned int b;
+ int *chain_length
+ = (int *) alloca (c->num_buckets * sizeof (*chain_length));
+
+ occupied_buckets = 0;
+
+ for (b = 0; b < c->num_buckets; b++)
+ {
+ struct bstring *s = c->bucket[b];
+
+ chain_length[b] = 0;
+
+ if (s)
+ {
+ occupied_buckets++;
+
+ while (s)
+ {
+ chain_length[b]++;
+ s = s->next;
+ }
+ }
+ }
+
+ /* To compute the median, we need the set of chain lengths sorted. */
+ qsort (chain_length, c->num_buckets, sizeof (chain_length[0]),
+ compare_ints);
+
+ if (c->num_buckets > 0)
+ {
+ max_chain_length = chain_length[c->num_buckets - 1];
+ median_chain_length = chain_length[c->num_buckets / 2];
+ }
+ else
+ {
+ max_chain_length = 0;
+ median_chain_length = 0;
+ }
+ }
+
+ printf_filtered (" Cached '%s' statistics:\n", type);
+ printf_filtered (" Total object count: %ld\n", c->total_count);
+ printf_filtered (" Unique object count: %lu\n", c->unique_count);
+ printf_filtered (" Percentage of duplicates, by count: ");
+ print_percentage (c->total_count - c->unique_count, c->total_count);
+ printf_filtered ("\n");
+
+ printf_filtered (" Total object size: %ld\n", c->total_size);
+ printf_filtered (" Unique object size: %ld\n", c->unique_size);
+ printf_filtered (" Percentage of duplicates, by size: ");
+ print_percentage (c->total_size - c->unique_size, c->total_size);
+ printf_filtered ("\n");
+
+ printf_filtered (" Total memory used by bcache, including overhead: %ld\n",
+ c->structure_size);
+ printf_filtered (" Percentage memory overhead: ");
+ print_percentage (c->structure_size - c->unique_size, c->unique_size);
+ printf_filtered (" Net memory savings: ");
+ print_percentage (c->total_size - c->structure_size, c->total_size);
+ printf_filtered ("\n");
+
+ printf_filtered (" Hash table size: %3d\n", c->num_buckets);
+ printf_filtered (" Hash table population: ");
+ print_percentage (occupied_buckets, c->num_buckets);
+ printf_filtered (" Median hash chain length: %3d\n",
+ median_chain_length);
+ printf_filtered (" Average hash chain length: ");
+ if (c->num_buckets > 0)
+ printf_filtered ("%3lu\n", c->unique_count / c->num_buckets);
+ else
+ printf_filtered ("(not applicable)\n");
+ printf_filtered (" Maximum hash chain length: %3d\n", max_chain_length);
+ printf_filtered ("\n");
+}
diff --git a/gdb/bcache.h b/gdb/bcache.h
new file mode 100644
index 00000000000..2b03ead5a34
--- /dev/null
+++ b/gdb/bcache.h
@@ -0,0 +1,130 @@
+/* Include file cached obstack implementation.
+ Written by Fred Fish <fnf@cygnus.com>
+ Rewritten by Jim Blandy <jimb@cygnus.com>
+ Copyright 1999, 2000 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. */
+
+#ifndef BCACHE_H
+#define BCACHE_H 1
+
+/* A bcache is a data structure for factoring out duplication in
+ read-only structures. You give the bcache some string of bytes S.
+ If the bcache already contains a copy of S, it hands you back a
+ pointer to its copy. Otherwise, it makes a fresh copy of S, and
+ hands you back a pointer to that. In either case, you can throw
+ away your copy of S, and use the bcache's.
+
+ The "strings" in question are arbitrary strings of bytes --- they
+ can contain zero bytes. You pass in the length explicitly when you
+ call the bcache function.
+
+ This means that you can put ordinary C objects in a bcache.
+ However, if you do this, remember that structs can contain `holes'
+ between members, added for alignment. These bytes usually contain
+ garbage. If you try to bcache two objects which are identical from
+ your code's point of view, but have different garbage values in the
+ structure's holes, then the bcache will treat them as separate
+ strings, and you won't get the nice elimination of duplicates you
+ were hoping for. So, remember to memset your structures full of
+ zeros before bcaching them!
+
+ You shouldn't modify the strings you get from a bcache, because:
+
+ - You don't necessarily know who you're sharing space with. If I
+ stick eight bytes of text in a bcache, and then stick an
+ eight-byte structure in the same bcache, there's no guarantee
+ those two objects don't actually comprise the same sequence of
+ bytes. If they happen to, the bcache will use a single byte
+ string for both of them. Then, modifying the structure will
+ change the string. In bizarre ways.
+
+ - Even if you know for some other reason that all that's okay,
+ there's another problem. A bcache stores all its strings in a
+ hash table. If you modify a string's contents, you will probably
+ change its hash value. This means that the modified string is
+ now in the wrong place in the hash table, and future bcache
+ probes will never find it. So by mutating a string, you give up
+ any chance of sharing its space with future duplicates. */
+
+
+/* The type used to hold a single bcache string. The user data is
+ stored in d.data. Since it can be any type, it needs to have the
+ same alignment as the most strict alignment of any type on the host
+ machine. I don't know of any really correct way to do this in
+ stock ANSI C, so just do it the same way obstack.h does.
+
+ It would be nicer to have this stuff hidden away in bcache.c, but
+ struct objstack contains a struct bcache directly --- not a pointer
+ to one --- and then the memory-mapped stuff makes this a real pain.
+ We don't strictly need to expose struct bstring, but it's better to
+ have it all in one place. */
+
+struct bstring {
+ struct bstring *next;
+ size_t length;
+
+ union
+ {
+ char data[1];
+ double dummy;
+ }
+ d;
+};
+
+
+/* The structure for a bcache itself.
+ To initialize a bcache, just fill it with zeros. */
+struct bcache {
+ /* All the bstrings are allocated here. */
+ struct obstack cache;
+
+ /* How many hash buckets we're using. */
+ unsigned int num_buckets;
+
+ /* Hash buckets. This table is allocated using malloc, so when we
+ grow the table we can return the old table to the system. */
+ struct bstring **bucket;
+
+ /* Statistics. */
+ unsigned long unique_count; /* number of unique strings */
+ long total_count; /* total number of strings cached, including dups */
+ long unique_size; /* size of unique strings, in bytes */
+ long total_size; /* total number of bytes cached, including dups */
+ long structure_size; /* total size of bcache, including infrastructure */
+};
+
+
+/* Find a copy of the LENGTH bytes at ADDR in BCACHE. If BCACHE has
+ never seen those bytes before, add a copy of them to BCACHE. In
+ either case, return a pointer to BCACHE's copy of that string. */
+extern void *bcache (const void *addr, int length, struct bcache *bcache);
+
+/* Free all the storage that BCACHE refers to. The result is a valid,
+ but empty, bcache. This does not free BCACHE itself, since that
+ might be part of some larger object. */
+extern void free_bcache (struct bcache *bcache);
+
+/* Print statistics on BCACHE's memory usage and efficacity at
+ eliminating duplication. TYPE should be a string describing the
+ kind of data BCACHE holds. Statistics are printed using
+ `printf_filtered' and its ilk. */
+extern void print_bcache_statistics (struct bcache *bcache, char *type);
+/* The hash function */
+extern unsigned long hash(const void *addr, int length);
+#endif /* BCACHE_H */
diff --git a/gdb/blockframe.c b/gdb/blockframe.c
new file mode 100644
index 00000000000..706d0283cf1
--- /dev/null
+++ b/gdb/blockframe.c
@@ -0,0 +1,1369 @@
+/* Get info from stack frames; convert between frames, blocks,
+ functions and pc values.
+
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+#include "symtab.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "value.h" /* for read_register */
+#include "target.h" /* for target_has_stack */
+#include "inferior.h" /* for read_pc */
+#include "annotate.h"
+#include "regcache.h"
+
+/* Prototypes for exported functions. */
+
+void _initialize_blockframe (void);
+
+/* A default FRAME_CHAIN_VALID, in the form that is suitable for most
+ targets. If FRAME_CHAIN_VALID returns zero it means that the given
+ frame is the outermost one and has no caller. */
+
+int
+file_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
+{
+ return ((chain) != 0
+ && !inside_entry_file (FRAME_SAVED_PC (thisframe)));
+}
+
+/* Use the alternate method of avoiding running up off the end of the
+ frame chain or following frames back into the startup code. See
+ the comments in objfiles.h. */
+
+int
+func_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
+{
+ return ((chain) != 0
+ && !inside_main_func ((thisframe)->pc)
+ && !inside_entry_func ((thisframe)->pc));
+}
+
+/* A very simple method of determining a valid frame */
+
+int
+nonnull_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
+{
+ return ((chain) != 0);
+}
+
+/* Is ADDR inside the startup file? Note that if your machine
+ has a way to detect the bottom of the stack, there is no need
+ to call this function from FRAME_CHAIN_VALID; the reason for
+ doing so is that some machines have no way of detecting bottom
+ of stack.
+
+ A PC of zero is always considered to be the bottom of the stack. */
+
+int
+inside_entry_file (CORE_ADDR addr)
+{
+ if (addr == 0)
+ return 1;
+ if (symfile_objfile == 0)
+ return 0;
+ if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
+ {
+ /* Do not stop backtracing if the pc is in the call dummy
+ at the entry point. */
+ /* FIXME: Won't always work with zeros for the last two arguments */
+ if (PC_IN_CALL_DUMMY (addr, 0, 0))
+ return 0;
+ }
+ return (addr >= symfile_objfile->ei.entry_file_lowpc &&
+ addr < symfile_objfile->ei.entry_file_highpc);
+}
+
+/* Test a specified PC value to see if it is in the range of addresses
+ that correspond to the main() function. See comments above for why
+ we might want to do this.
+
+ Typically called from FRAME_CHAIN_VALID.
+
+ A PC of zero is always considered to be the bottom of the stack. */
+
+int
+inside_main_func (CORE_ADDR pc)
+{
+ if (pc == 0)
+ return 1;
+ if (symfile_objfile == 0)
+ return 0;
+
+ /* If the addr range is not set up at symbol reading time, set it up now.
+ This is for FRAME_CHAIN_VALID_ALTERNATE. I do this for coff, because
+ it is unable to set it up and symbol reading time. */
+
+ if (symfile_objfile->ei.main_func_lowpc == INVALID_ENTRY_LOWPC &&
+ symfile_objfile->ei.main_func_highpc == INVALID_ENTRY_HIGHPC)
+ {
+ struct symbol *mainsym;
+
+ mainsym = lookup_symbol (main_name (), NULL, VAR_NAMESPACE, NULL, NULL);
+ if (mainsym && SYMBOL_CLASS (mainsym) == LOC_BLOCK)
+ {
+ symfile_objfile->ei.main_func_lowpc =
+ BLOCK_START (SYMBOL_BLOCK_VALUE (mainsym));
+ symfile_objfile->ei.main_func_highpc =
+ BLOCK_END (SYMBOL_BLOCK_VALUE (mainsym));
+ }
+ }
+ return (symfile_objfile->ei.main_func_lowpc <= pc &&
+ symfile_objfile->ei.main_func_highpc > pc);
+}
+
+/* Test a specified PC value to see if it is in the range of addresses
+ that correspond to the process entry point function. See comments
+ in objfiles.h for why we might want to do this.
+
+ Typically called from FRAME_CHAIN_VALID.
+
+ A PC of zero is always considered to be the bottom of the stack. */
+
+int
+inside_entry_func (CORE_ADDR pc)
+{
+ if (pc == 0)
+ return 1;
+ if (symfile_objfile == 0)
+ return 0;
+ if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
+ {
+ /* Do not stop backtracing if the pc is in the call dummy
+ at the entry point. */
+ /* FIXME: Won't always work with zeros for the last two arguments */
+ if (PC_IN_CALL_DUMMY (pc, 0, 0))
+ return 0;
+ }
+ return (symfile_objfile->ei.entry_func_lowpc <= pc &&
+ symfile_objfile->ei.entry_func_highpc > pc);
+}
+
+/* Info about the innermost stack frame (contents of FP register) */
+
+static struct frame_info *current_frame;
+
+/* Cache for frame addresses already read by gdb. Valid only while
+ inferior is stopped. Control variables for the frame cache should
+ be local to this module. */
+
+static struct obstack frame_cache_obstack;
+
+void *
+frame_obstack_alloc (unsigned long size)
+{
+ return obstack_alloc (&frame_cache_obstack, size);
+}
+
+void
+frame_saved_regs_zalloc (struct frame_info *fi)
+{
+ fi->saved_regs = (CORE_ADDR *)
+ frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS);
+ memset (fi->saved_regs, 0, SIZEOF_FRAME_SAVED_REGS);
+}
+
+
+/* Return the innermost (currently executing) stack frame. */
+
+struct frame_info *
+get_current_frame (void)
+{
+ if (current_frame == NULL)
+ {
+ if (target_has_stack)
+ current_frame = create_new_frame (read_fp (), read_pc ());
+ else
+ error ("No stack.");
+ }
+ return current_frame;
+}
+
+void
+set_current_frame (struct frame_info *frame)
+{
+ current_frame = frame;
+}
+
+/* Create an arbitrary (i.e. address specified by user) or innermost frame.
+ Always returns a non-NULL value. */
+
+struct frame_info *
+create_new_frame (CORE_ADDR addr, CORE_ADDR pc)
+{
+ struct frame_info *fi;
+ char *name;
+
+ fi = (struct frame_info *)
+ obstack_alloc (&frame_cache_obstack,
+ sizeof (struct frame_info));
+
+ /* Zero all fields by default. */
+ memset (fi, 0, sizeof (struct frame_info));
+
+ fi->frame = addr;
+ fi->pc = pc;
+ find_pc_partial_function (pc, &name, (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
+ fi->signal_handler_caller = PC_IN_SIGTRAMP (fi->pc, name);
+
+ if (INIT_EXTRA_FRAME_INFO_P ())
+ INIT_EXTRA_FRAME_INFO (0, fi);
+
+ return fi;
+}
+
+/* Return the frame that FRAME calls (NULL if FRAME is the innermost
+ frame). */
+
+struct frame_info *
+get_next_frame (struct frame_info *frame)
+{
+ return frame->next;
+}
+
+/* Flush the entire frame cache. */
+
+void
+flush_cached_frames (void)
+{
+ /* Since we can't really be sure what the first object allocated was */
+ obstack_free (&frame_cache_obstack, 0);
+ obstack_init (&frame_cache_obstack);
+
+ current_frame = NULL; /* Invalidate cache */
+ select_frame (NULL);
+ annotate_frames_invalid ();
+}
+
+/* Flush the frame cache, and start a new one if necessary. */
+
+void
+reinit_frame_cache (void)
+{
+ flush_cached_frames ();
+
+ /* FIXME: The inferior_ptid test is wrong if there is a corefile. */
+ if (PIDGET (inferior_ptid) != 0)
+ {
+ select_frame (get_current_frame ());
+ }
+}
+
+/* Return nonzero if the function for this frame lacks a prologue. Many
+ machines can define FRAMELESS_FUNCTION_INVOCATION to just call this
+ function. */
+
+int
+frameless_look_for_prologue (struct frame_info *frame)
+{
+ CORE_ADDR func_start, after_prologue;
+
+ func_start = get_pc_function_start (frame->pc);
+ if (func_start)
+ {
+ func_start += FUNCTION_START_OFFSET;
+ /* This is faster, since only care whether there *is* a
+ prologue, not how long it is. */
+ return PROLOGUE_FRAMELESS_P (func_start);
+ }
+ else if (frame->pc == 0)
+ /* A frame with a zero PC is usually created by dereferencing a
+ NULL function pointer, normally causing an immediate core dump
+ of the inferior. Mark function as frameless, as the inferior
+ has no chance of setting up a stack frame. */
+ return 1;
+ else
+ /* If we can't find the start of the function, we don't really
+ know whether the function is frameless, but we should be able
+ to get a reasonable (i.e. best we can do under the
+ circumstances) backtrace by saying that it isn't. */
+ return 0;
+}
+
+/* Return a structure containing various interesting information
+ about the frame that called NEXT_FRAME. Returns NULL
+ if there is no such frame. */
+
+struct frame_info *
+get_prev_frame (struct frame_info *next_frame)
+{
+ CORE_ADDR address = 0;
+ struct frame_info *prev;
+ int fromleaf = 0;
+ char *name;
+
+ /* If the requested entry is in the cache, return it.
+ Otherwise, figure out what the address should be for the entry
+ we're about to add to the cache. */
+
+ if (!next_frame)
+ {
+#if 0
+ /* This screws value_of_variable, which just wants a nice clean
+ NULL return from block_innermost_frame if there are no frames.
+ I don't think I've ever seen this message happen otherwise.
+ And returning NULL here is a perfectly legitimate thing to do. */
+ if (!current_frame)
+ {
+ error ("You haven't set up a process's stack to examine.");
+ }
+#endif
+
+ return current_frame;
+ }
+
+ /* If we have the prev one, return it */
+ if (next_frame->prev)
+ return next_frame->prev;
+
+ /* On some machines it is possible to call a function without
+ setting up a stack frame for it. On these machines, we
+ define this macro to take two args; a frameinfo pointer
+ identifying a frame and a variable to set or clear if it is
+ or isn't leafless. */
+
+ /* Still don't want to worry about this except on the innermost
+ frame. This macro will set FROMLEAF if NEXT_FRAME is a
+ frameless function invocation. */
+ if (!(next_frame->next))
+ {
+ fromleaf = FRAMELESS_FUNCTION_INVOCATION (next_frame);
+ if (fromleaf)
+ address = FRAME_FP (next_frame);
+ }
+
+ if (!fromleaf)
+ {
+ /* Two macros defined in tm.h specify the machine-dependent
+ actions to be performed here.
+ First, get the frame's chain-pointer.
+ If that is zero, the frame is the outermost frame or a leaf
+ called by the outermost frame. This means that if start
+ calls main without a frame, we'll return 0 (which is fine
+ anyway).
+
+ Nope; there's a problem. This also returns when the current
+ routine is a leaf of main. This is unacceptable. We move
+ this to after the ffi test; I'd rather have backtraces from
+ start go curfluy than have an abort called from main not show
+ main. */
+ address = FRAME_CHAIN (next_frame);
+ if (!FRAME_CHAIN_VALID (address, next_frame))
+ return 0;
+ }
+ if (address == 0)
+ return 0;
+
+ prev = (struct frame_info *)
+ obstack_alloc (&frame_cache_obstack,
+ sizeof (struct frame_info));
+
+ /* Zero all fields by default. */
+ memset (prev, 0, sizeof (struct frame_info));
+
+ if (next_frame)
+ next_frame->prev = prev;
+ prev->next = next_frame;
+ prev->frame = address;
+ prev->level = next_frame->level + 1;
+
+/* This change should not be needed, FIXME! We should
+ determine whether any targets *need* INIT_FRAME_PC to happen
+ after INIT_EXTRA_FRAME_INFO and come up with a simple way to
+ express what goes on here.
+
+ INIT_EXTRA_FRAME_INFO is called from two places: create_new_frame
+ (where the PC is already set up) and here (where it isn't).
+ INIT_FRAME_PC is only called from here, always after
+ INIT_EXTRA_FRAME_INFO.
+
+ The catch is the MIPS, where INIT_EXTRA_FRAME_INFO requires the PC
+ value (which hasn't been set yet). Some other machines appear to
+ require INIT_EXTRA_FRAME_INFO before they can do INIT_FRAME_PC. Phoo.
+
+ We shouldn't need INIT_FRAME_PC_FIRST to add more complication to
+ an already overcomplicated part of GDB. gnu@cygnus.com, 15Sep92.
+
+ Assuming that some machines need INIT_FRAME_PC after
+ INIT_EXTRA_FRAME_INFO, one possible scheme:
+
+ SETUP_INNERMOST_FRAME()
+ Default version is just create_new_frame (read_fp ()),
+ read_pc ()). Machines with extra frame info would do that (or the
+ local equivalent) and then set the extra fields.
+ SETUP_ARBITRARY_FRAME(argc, argv)
+ Only change here is that create_new_frame would no longer init extra
+ frame info; SETUP_ARBITRARY_FRAME would have to do that.
+ INIT_PREV_FRAME(fromleaf, prev)
+ Replace INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC. This should
+ also return a flag saying whether to keep the new frame, or
+ whether to discard it, because on some machines (e.g. mips) it
+ is really awkward to have FRAME_CHAIN_VALID called *before*
+ INIT_EXTRA_FRAME_INFO (there is no good way to get information
+ deduced in FRAME_CHAIN_VALID into the extra fields of the new frame).
+ std_frame_pc(fromleaf, prev)
+ This is the default setting for INIT_PREV_FRAME. It just does what
+ the default INIT_FRAME_PC does. Some machines will call it from
+ INIT_PREV_FRAME (either at the beginning, the end, or in the middle).
+ Some machines won't use it.
+ kingdon@cygnus.com, 13Apr93, 31Jan94, 14Dec94. */
+
+ INIT_FRAME_PC_FIRST (fromleaf, prev);
+
+ if (INIT_EXTRA_FRAME_INFO_P ())
+ INIT_EXTRA_FRAME_INFO (fromleaf, prev);
+
+ /* This entry is in the frame queue now, which is good since
+ FRAME_SAVED_PC may use that queue to figure out its value
+ (see tm-sparc.h). We want the pc saved in the inferior frame. */
+ INIT_FRAME_PC (fromleaf, prev);
+
+ /* If ->frame and ->pc are unchanged, we are in the process of getting
+ ourselves into an infinite backtrace. Some architectures check this
+ in FRAME_CHAIN or thereabouts, but it seems like there is no reason
+ this can't be an architecture-independent check. */
+ if (next_frame != NULL)
+ {
+ if (prev->frame == next_frame->frame
+ && prev->pc == next_frame->pc)
+ {
+ next_frame->prev = NULL;
+ obstack_free (&frame_cache_obstack, prev);
+ return NULL;
+ }
+ }
+
+ find_pc_partial_function (prev->pc, &name,
+ (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
+ if (PC_IN_SIGTRAMP (prev->pc, name))
+ prev->signal_handler_caller = 1;
+
+ return prev;
+}
+
+CORE_ADDR
+get_frame_pc (struct frame_info *frame)
+{
+ return frame->pc;
+}
+
+
+#ifdef FRAME_FIND_SAVED_REGS
+/* XXX - deprecated. This is a compatibility function for targets
+ that do not yet implement FRAME_INIT_SAVED_REGS. */
+/* Find the addresses in which registers are saved in FRAME. */
+
+void
+get_frame_saved_regs (struct frame_info *frame,
+ struct frame_saved_regs *saved_regs_addr)
+{
+ if (frame->saved_regs == NULL)
+ {
+ frame->saved_regs = (CORE_ADDR *)
+ frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS);
+ }
+ if (saved_regs_addr == NULL)
+ {
+ struct frame_saved_regs saved_regs;
+ FRAME_FIND_SAVED_REGS (frame, saved_regs);
+ memcpy (frame->saved_regs, &saved_regs, SIZEOF_FRAME_SAVED_REGS);
+ }
+ else
+ {
+ FRAME_FIND_SAVED_REGS (frame, *saved_regs_addr);
+ memcpy (frame->saved_regs, saved_regs_addr, SIZEOF_FRAME_SAVED_REGS);
+ }
+}
+#endif
+
+/* Return the innermost lexical block in execution
+ in a specified stack frame. The frame address is assumed valid.
+
+ If ADDR_IN_BLOCK is non-zero, set *ADDR_IN_BLOCK to the exact code
+ address we used to choose the block. We use this to find a source
+ line, to decide which macro definitions are in scope.
+
+ The value returned in *ADDR_IN_BLOCK isn't necessarily the frame's
+ PC, and may not really be a valid PC at all. For example, in the
+ caller of a function declared to never return, the code at the
+ return address will never be reached, so the call instruction may
+ be the very last instruction in the block. So the address we use
+ to choose the block is actually one byte before the return address
+ --- hopefully pointing us at the call instruction, or its delay
+ slot instruction. */
+
+struct block *
+get_frame_block (struct frame_info *frame, CORE_ADDR *addr_in_block)
+{
+ CORE_ADDR pc;
+
+ pc = frame->pc;
+ if (frame->next != 0 && frame->next->signal_handler_caller == 0)
+ /* We are not in the innermost frame and we were not interrupted
+ by a signal. We need to subtract one to get the correct block,
+ in case the call instruction was the last instruction of the block.
+ If there are any machines on which the saved pc does not point to
+ after the call insn, we probably want to make frame->pc point after
+ the call insn anyway. */
+ --pc;
+
+ if (addr_in_block)
+ *addr_in_block = pc;
+
+ return block_for_pc (pc);
+}
+
+struct block *
+get_current_block (CORE_ADDR *addr_in_block)
+{
+ CORE_ADDR pc = read_pc ();
+
+ if (addr_in_block)
+ *addr_in_block = pc;
+
+ return block_for_pc (pc);
+}
+
+CORE_ADDR
+get_pc_function_start (CORE_ADDR pc)
+{
+ register struct block *bl;
+ register struct symbol *symbol;
+ register struct minimal_symbol *msymbol;
+ CORE_ADDR fstart;
+
+ if ((bl = block_for_pc (pc)) != NULL &&
+ (symbol = block_function (bl)) != NULL)
+ {
+ bl = SYMBOL_BLOCK_VALUE (symbol);
+ fstart = BLOCK_START (bl);
+ }
+ else if ((msymbol = lookup_minimal_symbol_by_pc (pc)) != NULL)
+ {
+ fstart = SYMBOL_VALUE_ADDRESS (msymbol);
+ }
+ else
+ {
+ fstart = 0;
+ }
+ return (fstart);
+}
+
+/* Return the symbol for the function executing in frame FRAME. */
+
+struct symbol *
+get_frame_function (struct frame_info *frame)
+{
+ register struct block *bl = get_frame_block (frame, 0);
+ if (bl == 0)
+ return 0;
+ return block_function (bl);
+}
+
+
+/* Return the blockvector immediately containing the innermost lexical block
+ containing the specified pc value and section, or 0 if there is none.
+ PINDEX is a pointer to the index value of the block. If PINDEX
+ is NULL, we don't pass this information back to the caller. */
+
+struct blockvector *
+blockvector_for_pc_sect (register CORE_ADDR pc, struct sec *section,
+ int *pindex, struct symtab *symtab)
+{
+ register struct block *b;
+ register int bot, top, half;
+ struct blockvector *bl;
+
+ if (symtab == 0) /* if no symtab specified by caller */
+ {
+ /* First search all symtabs for one whose file contains our pc */
+ if ((symtab = find_pc_sect_symtab (pc, section)) == 0)
+ return 0;
+ }
+
+ bl = BLOCKVECTOR (symtab);
+ b = BLOCKVECTOR_BLOCK (bl, 0);
+
+ /* Then search that symtab for the smallest block that wins. */
+ /* Use binary search to find the last block that starts before PC. */
+
+ bot = 0;
+ top = BLOCKVECTOR_NBLOCKS (bl);
+
+ while (top - bot > 1)
+ {
+ half = (top - bot + 1) >> 1;
+ b = BLOCKVECTOR_BLOCK (bl, bot + half);
+ if (BLOCK_START (b) <= pc)
+ bot += half;
+ else
+ top = bot + half;
+ }
+
+ /* Now search backward for a block that ends after PC. */
+
+ while (bot >= 0)
+ {
+ b = BLOCKVECTOR_BLOCK (bl, bot);
+ if (BLOCK_END (b) > pc)
+ {
+ if (pindex)
+ *pindex = bot;
+ return bl;
+ }
+ bot--;
+ }
+ return 0;
+}
+
+/* Return the blockvector immediately containing the innermost lexical block
+ containing the specified pc value, or 0 if there is none.
+ Backward compatibility, no section. */
+
+struct blockvector *
+blockvector_for_pc (register CORE_ADDR pc, int *pindex)
+{
+ return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc),
+ pindex, NULL);
+}
+
+/* Return the innermost lexical block containing the specified pc value
+ in the specified section, or 0 if there is none. */
+
+struct block *
+block_for_pc_sect (register CORE_ADDR pc, struct sec *section)
+{
+ register struct blockvector *bl;
+ int index;
+
+ bl = blockvector_for_pc_sect (pc, section, &index, NULL);
+ if (bl)
+ return BLOCKVECTOR_BLOCK (bl, index);
+ return 0;
+}
+
+/* Return the innermost lexical block containing the specified pc value,
+ or 0 if there is none. Backward compatibility, no section. */
+
+struct block *
+block_for_pc (register CORE_ADDR pc)
+{
+ return block_for_pc_sect (pc, find_pc_mapped_section (pc));
+}
+
+/* Return the function containing pc value PC in section SECTION.
+ Returns 0 if function is not known. */
+
+struct symbol *
+find_pc_sect_function (CORE_ADDR pc, struct sec *section)
+{
+ register struct block *b = block_for_pc_sect (pc, section);
+ if (b == 0)
+ return 0;
+ return block_function (b);
+}
+
+/* Return the function containing pc value PC.
+ Returns 0 if function is not known. Backward compatibility, no section */
+
+struct symbol *
+find_pc_function (CORE_ADDR pc)
+{
+ return find_pc_sect_function (pc, find_pc_mapped_section (pc));
+}
+
+/* These variables are used to cache the most recent result
+ * of find_pc_partial_function. */
+
+static CORE_ADDR cache_pc_function_low = 0;
+static CORE_ADDR cache_pc_function_high = 0;
+static char *cache_pc_function_name = 0;
+static struct sec *cache_pc_function_section = NULL;
+
+/* Clear cache, e.g. when symbol table is discarded. */
+
+void
+clear_pc_function_cache (void)
+{
+ cache_pc_function_low = 0;
+ cache_pc_function_high = 0;
+ cache_pc_function_name = (char *) 0;
+ cache_pc_function_section = NULL;
+}
+
+/* Finds the "function" (text symbol) that is smaller than PC but
+ greatest of all of the potential text symbols in SECTION. Sets
+ *NAME and/or *ADDRESS conditionally if that pointer is non-null.
+ If ENDADDR is non-null, then set *ENDADDR to be the end of the
+ function (exclusive), but passing ENDADDR as non-null means that
+ the function might cause symbols to be read. This function either
+ succeeds or fails (not halfway succeeds). If it succeeds, it sets
+ *NAME, *ADDRESS, and *ENDADDR to real information and returns 1.
+ If it fails, it sets *NAME, *ADDRESS, and *ENDADDR to zero and
+ returns 0. */
+
+int
+find_pc_sect_partial_function (CORE_ADDR pc, asection *section, char **name,
+ CORE_ADDR *address, CORE_ADDR *endaddr)
+{
+ struct partial_symtab *pst;
+ struct symbol *f;
+ struct minimal_symbol *msymbol;
+ struct partial_symbol *psb;
+ struct obj_section *osect;
+ int i;
+ CORE_ADDR mapped_pc;
+
+ mapped_pc = overlay_mapped_address (pc, section);
+
+ if (mapped_pc >= cache_pc_function_low &&
+ mapped_pc < cache_pc_function_high &&
+ section == cache_pc_function_section)
+ goto return_cached_value;
+
+ /* If sigtramp is in the u area, it counts as a function (especially
+ important for step_1). */
+#if defined SIGTRAMP_START
+ if (PC_IN_SIGTRAMP (mapped_pc, (char *) NULL))
+ {
+ cache_pc_function_low = SIGTRAMP_START (mapped_pc);
+ cache_pc_function_high = SIGTRAMP_END (mapped_pc);
+ cache_pc_function_name = "<sigtramp>";
+ cache_pc_function_section = section;
+ goto return_cached_value;
+ }
+#endif
+
+ msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section);
+ pst = find_pc_sect_psymtab (mapped_pc, section);
+ if (pst)
+ {
+ /* Need to read the symbols to get a good value for the end address. */
+ if (endaddr != NULL && !pst->readin)
+ {
+ /* Need to get the terminal in case symbol-reading produces
+ output. */
+ target_terminal_ours_for_output ();
+ PSYMTAB_TO_SYMTAB (pst);
+ }
+
+ if (pst->readin)
+ {
+ /* Checking whether the msymbol has a larger value is for the
+ "pathological" case mentioned in print_frame_info. */
+ f = find_pc_sect_function (mapped_pc, section);
+ if (f != NULL
+ && (msymbol == NULL
+ || (BLOCK_START (SYMBOL_BLOCK_VALUE (f))
+ >= SYMBOL_VALUE_ADDRESS (msymbol))))
+ {
+ cache_pc_function_low = BLOCK_START (SYMBOL_BLOCK_VALUE (f));
+ cache_pc_function_high = BLOCK_END (SYMBOL_BLOCK_VALUE (f));
+ cache_pc_function_name = SYMBOL_NAME (f);
+ cache_pc_function_section = section;
+ goto return_cached_value;
+ }
+ }
+ else
+ {
+ /* Now that static symbols go in the minimal symbol table, perhaps
+ we could just ignore the partial symbols. But at least for now
+ we use the partial or minimal symbol, whichever is larger. */
+ psb = find_pc_sect_psymbol (pst, mapped_pc, section);
+
+ if (psb
+ && (msymbol == NULL ||
+ (SYMBOL_VALUE_ADDRESS (psb)
+ >= SYMBOL_VALUE_ADDRESS (msymbol))))
+ {
+ /* This case isn't being cached currently. */
+ if (address)
+ *address = SYMBOL_VALUE_ADDRESS (psb);
+ if (name)
+ *name = SYMBOL_NAME (psb);
+ /* endaddr non-NULL can't happen here. */
+ return 1;
+ }
+ }
+ }
+
+ /* Not in the normal symbol tables, see if the pc is in a known section.
+ If it's not, then give up. This ensures that anything beyond the end
+ of the text seg doesn't appear to be part of the last function in the
+ text segment. */
+
+ osect = find_pc_sect_section (mapped_pc, section);
+
+ if (!osect)
+ msymbol = NULL;
+
+ /* Must be in the minimal symbol table. */
+ if (msymbol == NULL)
+ {
+ /* No available symbol. */
+ if (name != NULL)
+ *name = 0;
+ if (address != NULL)
+ *address = 0;
+ if (endaddr != NULL)
+ *endaddr = 0;
+ return 0;
+ }
+
+ cache_pc_function_low = SYMBOL_VALUE_ADDRESS (msymbol);
+ cache_pc_function_name = SYMBOL_NAME (msymbol);
+ cache_pc_function_section = section;
+
+ /* Use the lesser of the next minimal symbol in the same section, or
+ the end of the section, as the end of the function. */
+
+ /* Step over other symbols at this same address, and symbols in
+ other sections, to find the next symbol in this section with
+ a different address. */
+
+ for (i = 1; SYMBOL_NAME (msymbol + i) != NULL; i++)
+ {
+ if (SYMBOL_VALUE_ADDRESS (msymbol + i) != SYMBOL_VALUE_ADDRESS (msymbol)
+ && SYMBOL_BFD_SECTION (msymbol + i) == SYMBOL_BFD_SECTION (msymbol))
+ break;
+ }
+
+ if (SYMBOL_NAME (msymbol + i) != NULL
+ && SYMBOL_VALUE_ADDRESS (msymbol + i) < osect->endaddr)
+ cache_pc_function_high = SYMBOL_VALUE_ADDRESS (msymbol + i);
+ else
+ /* We got the start address from the last msymbol in the objfile.
+ So the end address is the end of the section. */
+ cache_pc_function_high = osect->endaddr;
+
+return_cached_value:
+
+ if (address)
+ {
+ if (pc_in_unmapped_range (pc, section))
+ *address = overlay_unmapped_address (cache_pc_function_low, section);
+ else
+ *address = cache_pc_function_low;
+ }
+
+ if (name)
+ *name = cache_pc_function_name;
+
+ if (endaddr)
+ {
+ if (pc_in_unmapped_range (pc, section))
+ {
+ /* Because the high address is actually beyond the end of
+ the function (and therefore possibly beyond the end of
+ the overlay), we must actually convert (high - 1)
+ and then add one to that. */
+
+ *endaddr = 1 + overlay_unmapped_address (cache_pc_function_high - 1,
+ section);
+ }
+ else
+ *endaddr = cache_pc_function_high;
+ }
+
+ return 1;
+}
+
+/* Backward compatibility, no section argument */
+
+int
+find_pc_partial_function (CORE_ADDR pc, char **name, CORE_ADDR *address,
+ CORE_ADDR *endaddr)
+{
+ asection *section;
+
+ section = find_pc_overlay (pc);
+ return find_pc_sect_partial_function (pc, section, name, address, endaddr);
+}
+
+/* Return the innermost stack frame executing inside of BLOCK,
+ or NULL if there is no such frame. If BLOCK is NULL, just return NULL. */
+
+struct frame_info *
+block_innermost_frame (struct block *block)
+{
+ struct frame_info *frame;
+ register CORE_ADDR start;
+ register CORE_ADDR end;
+
+ if (block == NULL)
+ return NULL;
+
+ start = BLOCK_START (block);
+ end = BLOCK_END (block);
+
+ frame = NULL;
+ while (1)
+ {
+ frame = get_prev_frame (frame);
+ if (frame == NULL)
+ return NULL;
+ if (frame->pc >= start && frame->pc < end)
+ return frame;
+ }
+}
+
+/* Return the full FRAME which corresponds to the given CORE_ADDR
+ or NULL if no FRAME on the chain corresponds to CORE_ADDR. */
+
+struct frame_info *
+find_frame_addr_in_frame_chain (CORE_ADDR frame_addr)
+{
+ struct frame_info *frame = NULL;
+
+ if (frame_addr == (CORE_ADDR) 0)
+ return NULL;
+
+ while (1)
+ {
+ frame = get_prev_frame (frame);
+ if (frame == NULL)
+ return NULL;
+ if (FRAME_FP (frame) == frame_addr)
+ return frame;
+ }
+}
+
+#ifdef SIGCONTEXT_PC_OFFSET
+/* Get saved user PC for sigtramp from sigcontext for BSD style sigtramp. */
+
+CORE_ADDR
+sigtramp_saved_pc (struct frame_info *frame)
+{
+ CORE_ADDR sigcontext_addr;
+ char *buf;
+ int ptrbytes = TARGET_PTR_BIT / TARGET_CHAR_BIT;
+ int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT;
+
+ buf = alloca (ptrbytes);
+ /* Get sigcontext address, it is the third parameter on the stack. */
+ if (frame->next)
+ sigcontext_addr = read_memory_integer (FRAME_ARGS_ADDRESS (frame->next)
+ + FRAME_ARGS_SKIP
+ + sigcontext_offs,
+ ptrbytes);
+ else
+ sigcontext_addr = read_memory_integer (read_register (SP_REGNUM)
+ + sigcontext_offs,
+ ptrbytes);
+
+ /* Don't cause a memory_error when accessing sigcontext in case the stack
+ layout has changed or the stack is corrupt. */
+ target_read_memory (sigcontext_addr + SIGCONTEXT_PC_OFFSET, buf, ptrbytes);
+ return extract_unsigned_integer (buf, ptrbytes);
+}
+#endif /* SIGCONTEXT_PC_OFFSET */
+
+
+/* Are we in a call dummy? The code below which allows DECR_PC_AFTER_BREAK
+ below is for infrun.c, which may give the macro a pc without that
+ subtracted out. */
+
+extern CORE_ADDR text_end;
+
+int
+pc_in_call_dummy_before_text_end (CORE_ADDR pc, CORE_ADDR sp,
+ CORE_ADDR frame_address)
+{
+ return ((pc) >= text_end - CALL_DUMMY_LENGTH
+ && (pc) <= text_end + DECR_PC_AFTER_BREAK);
+}
+
+int
+pc_in_call_dummy_after_text_end (CORE_ADDR pc, CORE_ADDR sp,
+ CORE_ADDR frame_address)
+{
+ return ((pc) >= text_end
+ && (pc) <= text_end + CALL_DUMMY_LENGTH + DECR_PC_AFTER_BREAK);
+}
+
+/* Is the PC in a call dummy? SP and FRAME_ADDRESS are the bottom and
+ top of the stack frame which we are checking, where "bottom" and
+ "top" refer to some section of memory which contains the code for
+ the call dummy. Calls to this macro assume that the contents of
+ SP_REGNUM and FP_REGNUM (or the saved values thereof), respectively,
+ are the things to pass.
+
+ This won't work on the 29k, where SP_REGNUM and FP_REGNUM don't
+ have that meaning, but the 29k doesn't use ON_STACK. This could be
+ fixed by generalizing this scheme, perhaps by passing in a frame
+ and adding a few fields, at least on machines which need them for
+ PC_IN_CALL_DUMMY.
+
+ Something simpler, like checking for the stack segment, doesn't work,
+ since various programs (threads implementations, gcc nested function
+ stubs, etc) may either allocate stack frames in another segment, or
+ allocate other kinds of code on the stack. */
+
+int
+pc_in_call_dummy_on_stack (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address)
+{
+ return (INNER_THAN ((sp), (pc))
+ && (frame_address != 0)
+ && INNER_THAN ((pc), (frame_address)));
+}
+
+int
+pc_in_call_dummy_at_entry_point (CORE_ADDR pc, CORE_ADDR sp,
+ CORE_ADDR frame_address)
+{
+ return ((pc) >= CALL_DUMMY_ADDRESS ()
+ && (pc) <= (CALL_DUMMY_ADDRESS () + DECR_PC_AFTER_BREAK));
+}
+
+
+/*
+ * GENERIC DUMMY FRAMES
+ *
+ * The following code serves to maintain the dummy stack frames for
+ * inferior function calls (ie. when gdb calls into the inferior via
+ * call_function_by_hand). This code saves the machine state before
+ * the call in host memory, so we must maintain an independent stack
+ * and keep it consistant etc. I am attempting to make this code
+ * generic enough to be used by many targets.
+ *
+ * The cheapest and most generic way to do CALL_DUMMY on a new target
+ * is probably to define CALL_DUMMY to be empty, CALL_DUMMY_LENGTH to
+ * zero, and CALL_DUMMY_LOCATION to AT_ENTRY. Then you must remember
+ * to define PUSH_RETURN_ADDRESS, because no call instruction will be
+ * being executed by the target. Also FRAME_CHAIN_VALID as
+ * generic_{file,func}_frame_chain_valid and FIX_CALL_DUMMY as
+ * generic_fix_call_dummy. */
+
+/* Dummy frame. This saves the processor state just prior to setting
+ up the inferior function call. Older targets save the registers
+ on the target stack (but that really slows down function calls). */
+
+struct dummy_frame
+{
+ struct dummy_frame *next;
+
+ CORE_ADDR pc;
+ CORE_ADDR fp;
+ CORE_ADDR sp;
+ CORE_ADDR top;
+ char *registers;
+
+ /* Address range of the call dummy code. Look for PC in the range
+ [LO..HI) (after allowing for DECR_PC_AFTER_BREAK). */
+ CORE_ADDR call_lo;
+ CORE_ADDR call_hi;
+};
+
+static struct dummy_frame *dummy_frame_stack = NULL;
+
+/* Function: find_dummy_frame(pc, fp, sp)
+
+ Search the stack of dummy frames for one matching the given PC, FP
+ and SP. Unlike PC_IN_CALL_DUMMY, this function doesn't need to
+ adjust for DECR_PC_AFTER_BREAK. This is because it is only legal
+ to call this function after the PC has been adjusted. */
+
+char *
+generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp)
+{
+ struct dummy_frame *dummyframe;
+
+ for (dummyframe = dummy_frame_stack; dummyframe != NULL;
+ dummyframe = dummyframe->next)
+ if ((pc >= dummyframe->call_lo && pc < dummyframe->call_hi)
+ && (fp == dummyframe->fp
+ || fp == dummyframe->sp
+ || fp == dummyframe->top))
+ /* The frame in question lies between the saved fp and sp, inclusive */
+ return dummyframe->registers;
+
+ return 0;
+}
+
+/* Function: pc_in_call_dummy (pc, sp, fp)
+
+ Return true if the PC falls in a dummy frame created by gdb for an
+ inferior call. The code below which allows DECR_PC_AFTER_BREAK is
+ for infrun.c, which may give the function a PC without that
+ subtracted out. */
+
+int
+generic_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR fp)
+{
+ struct dummy_frame *dummyframe;
+ for (dummyframe = dummy_frame_stack;
+ dummyframe != NULL;
+ dummyframe = dummyframe->next)
+ {
+ if ((pc >= dummyframe->call_lo)
+ && (pc < dummyframe->call_hi + DECR_PC_AFTER_BREAK))
+ return 1;
+ }
+ return 0;
+}
+
+/* Function: read_register_dummy
+ Find a saved register from before GDB calls a function in the inferior */
+
+CORE_ADDR
+generic_read_register_dummy (CORE_ADDR pc, CORE_ADDR fp, int regno)
+{
+ char *dummy_regs = generic_find_dummy_frame (pc, fp);
+
+ if (dummy_regs)
+ return extract_address (&dummy_regs[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE (regno));
+ else
+ return 0;
+}
+
+/* Save all the registers on the dummy frame stack. Most ports save the
+ registers on the target stack. This results in lots of unnecessary memory
+ references, which are slow when debugging via a serial line. Instead, we
+ save all the registers internally, and never write them to the stack. The
+ registers get restored when the called function returns to the entry point,
+ where a breakpoint is laying in wait. */
+
+void
+generic_push_dummy_frame (void)
+{
+ struct dummy_frame *dummy_frame;
+ CORE_ADDR fp = (get_current_frame ())->frame;
+
+ /* check to see if there are stale dummy frames,
+ perhaps left over from when a longjump took us out of a
+ function that was called by the debugger */
+
+ dummy_frame = dummy_frame_stack;
+ while (dummy_frame)
+ if (INNER_THAN (dummy_frame->fp, fp)) /* stale -- destroy! */
+ {
+ dummy_frame_stack = dummy_frame->next;
+ xfree (dummy_frame->registers);
+ xfree (dummy_frame);
+ dummy_frame = dummy_frame_stack;
+ }
+ else
+ dummy_frame = dummy_frame->next;
+
+ dummy_frame = xmalloc (sizeof (struct dummy_frame));
+ dummy_frame->registers = xmalloc (REGISTER_BYTES);
+
+ dummy_frame->pc = read_pc ();
+ dummy_frame->sp = read_sp ();
+ dummy_frame->top = dummy_frame->sp;
+ dummy_frame->fp = fp;
+ read_register_bytes (0, dummy_frame->registers, REGISTER_BYTES);
+ dummy_frame->next = dummy_frame_stack;
+ dummy_frame_stack = dummy_frame;
+}
+
+void
+generic_save_dummy_frame_tos (CORE_ADDR sp)
+{
+ dummy_frame_stack->top = sp;
+}
+
+/* Record the upper/lower bounds on the address of the call dummy. */
+
+void
+generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi)
+{
+ dummy_frame_stack->call_lo = lo;
+ dummy_frame_stack->call_hi = hi;
+}
+
+/* Restore the machine state from either the saved dummy stack or a
+ real stack frame. */
+
+void
+generic_pop_current_frame (void (*popper) (struct frame_info * frame))
+{
+ struct frame_info *frame = get_current_frame ();
+
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ generic_pop_dummy_frame ();
+ else
+ (*popper) (frame);
+}
+
+/* Function: pop_dummy_frame
+ Restore the machine state from a saved dummy stack frame. */
+
+void
+generic_pop_dummy_frame (void)
+{
+ struct dummy_frame *dummy_frame = dummy_frame_stack;
+
+ /* FIXME: what if the first frame isn't the right one, eg..
+ because one call-by-hand function has done a longjmp into another one? */
+
+ if (!dummy_frame)
+ error ("Can't pop dummy frame!");
+ dummy_frame_stack = dummy_frame->next;
+ write_register_bytes (0, dummy_frame->registers, REGISTER_BYTES);
+ flush_cached_frames ();
+
+ xfree (dummy_frame->registers);
+ xfree (dummy_frame);
+}
+
+/* Function: frame_chain_valid
+ Returns true for a user frame or a call_function_by_hand dummy frame,
+ and false for the CRT0 start-up frame. Purpose is to terminate backtrace */
+
+int
+generic_file_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi)
+{
+ if (PC_IN_CALL_DUMMY (FRAME_SAVED_PC (fi), fp, fp))
+ return 1; /* don't prune CALL_DUMMY frames */
+ else /* fall back to default algorithm (see frame.h) */
+ return (fp != 0
+ && (INNER_THAN (fi->frame, fp) || fi->frame == fp)
+ && !inside_entry_file (FRAME_SAVED_PC (fi)));
+}
+
+int
+generic_func_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi)
+{
+ if (PC_IN_CALL_DUMMY ((fi)->pc, fp, fp))
+ return 1; /* don't prune CALL_DUMMY frames */
+ else /* fall back to default algorithm (see frame.h) */
+ return (fp != 0
+ && (INNER_THAN (fi->frame, fp) || fi->frame == fp)
+ && !inside_main_func ((fi)->pc)
+ && !inside_entry_func ((fi)->pc));
+}
+
+/* Function: fix_call_dummy
+ Stub function. Generic dummy frames typically do not need to fix
+ the frame being created */
+
+void
+generic_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+ struct value **args, struct type *type, int gcc_p)
+{
+ return;
+}
+
+/* Function: get_saved_register
+ Find register number REGNUM relative to FRAME and put its (raw,
+ target format) contents in *RAW_BUFFER.
+
+ Set *OPTIMIZED if the variable was optimized out (and thus can't be
+ fetched). Note that this is never set to anything other than zero
+ in this implementation.
+
+ Set *LVAL to lval_memory, lval_register, or not_lval, depending on
+ whether the value was fetched from memory, from a register, or in a
+ strange and non-modifiable way (e.g. a frame pointer which was
+ calculated rather than fetched). We will use not_lval for values
+ fetched from generic dummy frames.
+
+ Set *ADDRP to the address, either in memory or as a REGISTER_BYTE
+ offset into the registers array. If the value is stored in a dummy
+ frame, set *ADDRP to zero.
+
+ To use this implementation, define a function called
+ "get_saved_register" in your target code, which simply passes all
+ of its arguments to this function.
+
+ The argument RAW_BUFFER must point to aligned memory. */
+
+void
+generic_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp,
+ struct frame_info *frame, int regnum,
+ enum lval_type *lval)
+{
+ if (!target_has_registers)
+ error ("No registers.");
+
+ /* Normal systems don't optimize out things with register numbers. */
+ if (optimized != NULL)
+ *optimized = 0;
+
+ if (addrp) /* default assumption: not found in memory */
+ *addrp = 0;
+
+ /* Note: since the current frame's registers could only have been
+ saved by frames INTERIOR TO the current frame, we skip examining
+ the current frame itself: otherwise, we would be getting the
+ previous frame's registers which were saved by the current frame. */
+
+ while (frame && ((frame = frame->next) != NULL))
+ {
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ {
+ if (lval) /* found it in a CALL_DUMMY frame */
+ *lval = not_lval;
+ if (raw_buffer)
+ memcpy (raw_buffer,
+ generic_find_dummy_frame (frame->pc, frame->frame) +
+ REGISTER_BYTE (regnum),
+ REGISTER_RAW_SIZE (regnum));
+ return;
+ }
+
+ FRAME_INIT_SAVED_REGS (frame);
+ if (frame->saved_regs != NULL
+ && frame->saved_regs[regnum] != 0)
+ {
+ if (lval) /* found it saved on the stack */
+ *lval = lval_memory;
+ if (regnum == SP_REGNUM)
+ {
+ if (raw_buffer) /* SP register treated specially */
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
+ frame->saved_regs[regnum]);
+ }
+ else
+ {
+ if (addrp) /* any other register */
+ *addrp = frame->saved_regs[regnum];
+ if (raw_buffer)
+ read_memory (frame->saved_regs[regnum], raw_buffer,
+ REGISTER_RAW_SIZE (regnum));
+ }
+ return;
+ }
+ }
+
+ /* If we get thru the loop to this point, it means the register was
+ not saved in any frame. Return the actual live-register value. */
+
+ if (lval) /* found it in a live register */
+ *lval = lval_register;
+ if (addrp)
+ *addrp = REGISTER_BYTE (regnum);
+ if (raw_buffer)
+ read_register_gen (regnum, raw_buffer);
+}
+
+void
+_initialize_blockframe (void)
+{
+ obstack_init (&frame_cache_obstack);
+}
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
new file mode 100644
index 00000000000..6f604f1961a
--- /dev/null
+++ b/gdb/breakpoint.c
@@ -0,0 +1,7741 @@
+/* Everything about breakpoints, for GDB.
+
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+#include <ctype.h>
+#include "symtab.h"
+#include "frame.h"
+#include "breakpoint.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "value.h"
+#include "command.h"
+#include "inferior.h"
+#include "gdbthread.h"
+#include "target.h"
+#include "language.h"
+#include "gdb_string.h"
+#include "demangle.h"
+#include "annotate.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "linespec.h"
+#include "completer.h"
+#include "gdb.h"
+#include "ui-out.h"
+
+#include "gdb-events.h"
+
+/* Prototypes for local functions. */
+
+static void until_break_command_continuation (struct continuation_arg *arg);
+
+static void catch_command_1 (char *, int, int);
+
+static void enable_delete_command (char *, int);
+
+static void enable_delete_breakpoint (struct breakpoint *);
+
+static void enable_once_command (char *, int);
+
+static void enable_once_breakpoint (struct breakpoint *);
+
+static void disable_command (char *, int);
+
+static void enable_command (char *, int);
+
+static void map_breakpoint_numbers (char *, void (*)(struct breakpoint *));
+
+static void ignore_command (char *, int);
+
+static int breakpoint_re_set_one (PTR);
+
+static void clear_command (char *, int);
+
+static void catch_command (char *, int);
+
+static void handle_gnu_4_16_catch_command (char *, int, int);
+
+static struct symtabs_and_lines get_catch_sals (int);
+
+static void watch_command (char *, int);
+
+static int can_use_hardware_watchpoint (struct value *);
+
+extern void break_at_finish_command (char *, int);
+extern void break_at_finish_at_depth_command (char *, int);
+
+extern void tbreak_at_finish_command (char *, int);
+
+static void break_command_1 (char *, int, int);
+
+static void mention (struct breakpoint *);
+
+struct breakpoint *set_raw_breakpoint (struct symtab_and_line, enum bptype);
+
+static void check_duplicates (struct breakpoint *);
+
+static void describe_other_breakpoints (CORE_ADDR, asection *);
+
+static void breakpoints_info (char *, int);
+
+static void breakpoint_1 (int, int);
+
+static bpstat bpstat_alloc (struct breakpoint *, bpstat);
+
+static int breakpoint_cond_eval (PTR);
+
+static void cleanup_executing_breakpoints (PTR);
+
+static void commands_command (char *, int);
+
+static void condition_command (char *, int);
+
+static int get_number_trailer (char **, int);
+
+void set_breakpoint_count (int);
+
+typedef enum
+ {
+ mark_inserted,
+ mark_uninserted
+ }
+insertion_state_t;
+
+static int remove_breakpoint (struct breakpoint *, insertion_state_t);
+
+static enum print_stop_action print_it_typical (bpstat);
+
+static enum print_stop_action print_bp_stop_message (bpstat bs);
+
+typedef struct
+ {
+ enum exception_event_kind kind;
+ int enable_p;
+ }
+args_for_catchpoint_enable;
+
+static int watchpoint_check (PTR);
+
+static int cover_target_enable_exception_callback (PTR);
+
+static void maintenance_info_breakpoints (char *, int);
+
+static void create_longjmp_breakpoint (char *);
+
+static void create_overlay_event_breakpoint (char *);
+
+static int hw_breakpoint_used_count (void);
+
+static int hw_watchpoint_used_count (enum bptype, int *);
+
+static void hbreak_command (char *, int);
+
+static void thbreak_command (char *, int);
+
+static void watch_command_1 (char *, int, int);
+
+static void rwatch_command (char *, int);
+
+static void awatch_command (char *, int);
+
+static void do_enable_breakpoint (struct breakpoint *, enum bpdisp);
+
+static void solib_load_unload_1 (char *hookname,
+ int tempflag,
+ char *dll_pathname,
+ char *cond_string, enum bptype bp_kind);
+
+static void create_fork_vfork_event_catchpoint (int tempflag,
+ char *cond_string,
+ enum bptype bp_kind);
+
+static void break_at_finish_at_depth_command_1 (char *arg,
+ int flag, int from_tty);
+
+static void break_at_finish_command_1 (char *arg, int flag, int from_tty);
+
+static void stop_command (char *arg, int from_tty);
+
+static void stopin_command (char *arg, int from_tty);
+
+static void stopat_command (char *arg, int from_tty);
+
+static char *ep_find_event_name_end (char *arg);
+
+static char *ep_parse_optional_if_clause (char **arg);
+
+static char *ep_parse_optional_filename (char **arg);
+
+#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
+static void catch_exec_command_1 (char *arg, int tempflag, int from_tty);
+#endif
+
+static void create_exception_catchpoint (int tempflag, char *cond_string,
+ enum exception_event_kind ex_event,
+ struct symtab_and_line *sal);
+
+static void catch_exception_command_1 (enum exception_event_kind ex_event,
+ char *arg, int tempflag, int from_tty);
+
+static void tcatch_command (char *arg, int from_tty);
+
+static void ep_skip_leading_whitespace (char **s);
+
+/* Prototypes for exported functions. */
+
+/* If FALSE, gdb will not use hardware support for watchpoints, even
+ if such is available. */
+static int can_use_hw_watchpoints;
+
+void _initialize_breakpoint (void);
+
+extern int addressprint; /* Print machine addresses? */
+
+/* Are we executing breakpoint commands? */
+static int executing_breakpoint_commands;
+
+/* Are overlay event breakpoints enabled? */
+static int overlay_events_enabled;
+
+/* Walk the following statement or block through all breakpoints.
+ ALL_BREAKPOINTS_SAFE does so even if the statment deletes the current
+ breakpoint. */
+
+#define ALL_BREAKPOINTS(B) for (B = breakpoint_chain; B; B = B->next)
+
+#define ALL_BREAKPOINTS_SAFE(B,TMP) \
+ for (B = breakpoint_chain; \
+ B ? (TMP=B->next, 1): 0; \
+ B = TMP)
+
+/* True if SHIFT_INST_REGS defined, false otherwise. */
+
+int must_shift_inst_regs =
+#if defined(SHIFT_INST_REGS)
+1
+#else
+0
+#endif
+ ;
+
+/* True if breakpoint hit counts should be displayed in breakpoint info. */
+
+int show_breakpoint_hit_counts = 1;
+
+/* Chain of all breakpoints defined. */
+
+struct breakpoint *breakpoint_chain;
+
+/* Number of last breakpoint made. */
+
+int breakpoint_count;
+
+/* Pointer to current exception event record */
+static struct exception_event_record *current_exception_event;
+
+/* Indicator of whether exception catchpoints should be nuked
+ between runs of a program */
+int exception_catchpoints_are_fragile = 0;
+
+/* Indicator of when exception catchpoints set-up should be
+ reinitialized -- e.g. when program is re-run */
+int exception_support_initialized = 0;
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been
+ loaded.
+
+ This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the
+ inferior has stopped in the dynamic linker hook, and becomes
+ invalid as soon as the inferior is continued. Clients should make
+ a copy of this string if they wish to continue the inferior and
+ then access the string. */
+
+#ifndef SOLIB_LOADED_LIBRARY_PATHNAME
+#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) ""
+#endif
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been
+ unloaded.
+
+ This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is
+ TRUE, or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the
+ inferior has stopped in the dynamic linker hook, and becomes
+ invalid as soon as the inferior is continued. Clients should make
+ a copy of this string if they wish to continue the inferior and
+ then access the string. */
+
+#ifndef SOLIB_UNLOADED_LIBRARY_PATHNAME
+#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) ""
+#endif
+
+/* This function is called by the "catch load" command. It allows the
+ debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is loaded. */
+
+#ifndef SOLIB_CREATE_CATCH_LOAD_HOOK
+#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag,filename,cond_string) \
+ error ("catch of library loads not yet implemented on this platform")
+#endif
+
+/* This function is called by the "catch unload" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is
+ unloaded. */
+
+#ifndef SOLIB_CREATE_CATCH_UNLOAD_HOOK
+#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename,cond_string) \
+ error ("catch of library unloads not yet implemented on this platform")
+#endif
+
+/* Set breakpoint count to NUM. */
+
+void
+set_breakpoint_count (int num)
+{
+ breakpoint_count = num;
+ set_internalvar (lookup_internalvar ("bpnum"),
+ value_from_longest (builtin_type_int, (LONGEST) num));
+}
+
+/* Used in run_command to zero the hit count when a new run starts. */
+
+void
+clear_breakpoint_hit_counts (void)
+{
+ struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ b->hit_count = 0;
+}
+
+/* Default address, symtab and line to put a breakpoint at
+ for "break" command with no arg.
+ if default_breakpoint_valid is zero, the other three are
+ not valid, and "break" with no arg is an error.
+
+ This set by print_stack_frame, which calls set_default_breakpoint. */
+
+int default_breakpoint_valid;
+CORE_ADDR default_breakpoint_address;
+struct symtab *default_breakpoint_symtab;
+int default_breakpoint_line;
+
+/* *PP is a string denoting a breakpoint. Get the number of the breakpoint.
+ Advance *PP after the string and any trailing whitespace.
+
+ Currently the string can either be a number or "$" followed by the name
+ of a convenience variable. Making it an expression wouldn't work well
+ for map_breakpoint_numbers (e.g. "4 + 5 + 6").
+
+ TRAILER is a character which can be found after the number; most
+ commonly this is `-'. If you don't want a trailer, use \0. */
+static int
+get_number_trailer (char **pp, int trailer)
+{
+ int retval = 0; /* default */
+ char *p = *pp;
+
+ if (p == NULL)
+ /* Empty line means refer to the last breakpoint. */
+ return breakpoint_count;
+ else if (*p == '$')
+ {
+ /* Make a copy of the name, so we can null-terminate it
+ to pass to lookup_internalvar(). */
+ char *varname;
+ char *start = ++p;
+ struct value *val;
+
+ while (isalnum (*p) || *p == '_')
+ p++;
+ varname = (char *) alloca (p - start + 1);
+ strncpy (varname, start, p - start);
+ varname[p - start] = '\0';
+ val = value_of_internalvar (lookup_internalvar (varname));
+ if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT)
+ retval = (int) value_as_long (val);
+ else
+ {
+ printf_filtered ("Convenience variable must have integer value.\n");
+ retval = 0;
+ }
+ }
+ else
+ {
+ if (*p == '-')
+ ++p;
+ while (*p >= '0' && *p <= '9')
+ ++p;
+ if (p == *pp)
+ /* There is no number here. (e.g. "cond a == b"). */
+ {
+ /* Skip non-numeric token */
+ while (*p && !isspace((int) *p))
+ ++p;
+ /* Return zero, which caller must interpret as error. */
+ retval = 0;
+ }
+ else
+ retval = atoi (*pp);
+ }
+ if (!(isspace (*p) || *p == '\0' || *p == trailer))
+ {
+ /* Trailing junk: return 0 and let caller print error msg. */
+ while (!(isspace (*p) || *p == '\0' || *p == trailer))
+ ++p;
+ retval = 0;
+ }
+ while (isspace (*p))
+ p++;
+ *pp = p;
+ return retval;
+}
+
+
+/* Like get_number_trailer, but don't allow a trailer. */
+int
+get_number (char **pp)
+{
+ return get_number_trailer (pp, '\0');
+}
+
+/* Parse a number or a range.
+ * A number will be of the form handled by get_number.
+ * A range will be of the form <number1> - <number2>, and
+ * will represent all the integers between number1 and number2,
+ * inclusive.
+ *
+ * While processing a range, this fuction is called iteratively;
+ * At each call it will return the next value in the range.
+ *
+ * At the beginning of parsing a range, the char pointer PP will
+ * be advanced past <number1> and left pointing at the '-' token.
+ * Subsequent calls will not advance the pointer until the range
+ * is completed. The call that completes the range will advance
+ * pointer PP past <number2>.
+ */
+
+int
+get_number_or_range (char **pp)
+{
+ static int last_retval, end_value;
+ static char *end_ptr;
+ static int in_range = 0;
+
+ if (**pp != '-')
+ {
+ /* Default case: pp is pointing either to a solo number,
+ or to the first number of a range. */
+ last_retval = get_number_trailer (pp, '-');
+ if (**pp == '-')
+ {
+ char **temp;
+
+ /* This is the start of a range (<number1> - <number2>).
+ Skip the '-', parse and remember the second number,
+ and also remember the end of the final token. */
+
+ temp = &end_ptr;
+ end_ptr = *pp + 1;
+ while (isspace ((int) *end_ptr))
+ end_ptr++; /* skip white space */
+ end_value = get_number (temp);
+ if (end_value < last_retval)
+ {
+ error ("inverted range");
+ }
+ else if (end_value == last_retval)
+ {
+ /* degenerate range (number1 == number2). Advance the
+ token pointer so that the range will be treated as a
+ single number. */
+ *pp = end_ptr;
+ }
+ else
+ in_range = 1;
+ }
+ }
+ else if (! in_range)
+ error ("negative value");
+ else
+ {
+ /* pp points to the '-' that betokens a range. All
+ number-parsing has already been done. Return the next
+ integer value (one greater than the saved previous value).
+ Do not advance the token pointer 'pp' until the end of range
+ is reached. */
+
+ if (++last_retval == end_value)
+ {
+ /* End of range reached; advance token pointer. */
+ *pp = end_ptr;
+ in_range = 0;
+ }
+ }
+ return last_retval;
+}
+
+
+
+/* condition N EXP -- set break condition of breakpoint N to EXP. */
+
+static void
+condition_command (char *arg, int from_tty)
+{
+ register struct breakpoint *b;
+ char *p;
+ register int bnum;
+
+ if (arg == 0)
+ error_no_arg ("breakpoint number");
+
+ p = arg;
+ bnum = get_number (&p);
+ if (bnum == 0)
+ error ("Bad breakpoint argument: '%s'", arg);
+
+ ALL_BREAKPOINTS (b)
+ if (b->number == bnum)
+ {
+ if (b->cond)
+ {
+ xfree (b->cond);
+ b->cond = 0;
+ }
+ if (b->cond_string != NULL)
+ xfree (b->cond_string);
+
+ if (*p == 0)
+ {
+ b->cond = 0;
+ b->cond_string = NULL;
+ if (from_tty)
+ printf_filtered ("Breakpoint %d now unconditional.\n", bnum);
+ }
+ else
+ {
+ arg = p;
+ /* I don't know if it matters whether this is the string the user
+ typed in or the decompiled expression. */
+ b->cond_string = savestring (arg, strlen (arg));
+ b->cond = parse_exp_1 (&arg, block_for_pc (b->address), 0);
+ if (*arg)
+ error ("Junk at end of expression");
+ }
+ breakpoints_changed ();
+ return;
+ }
+
+ error ("No breakpoint number %d.", bnum);
+}
+
+/* ARGSUSED */
+static void
+commands_command (char *arg, int from_tty)
+{
+ register struct breakpoint *b;
+ char *p;
+ register int bnum;
+ struct command_line *l;
+
+ /* If we allowed this, we would have problems with when to
+ free the storage, if we change the commands currently
+ being read from. */
+
+ if (executing_breakpoint_commands)
+ error ("Can't use the \"commands\" command among a breakpoint's commands.");
+
+ p = arg;
+ bnum = get_number (&p);
+
+ if (p && *p)
+ error ("Unexpected extra arguments following breakpoint number.");
+
+ ALL_BREAKPOINTS (b)
+ if (b->number == bnum)
+ {
+ char tmpbuf[128];
+ sprintf (tmpbuf,
+ "Type commands for when breakpoint %d is hit, one per line.",
+ bnum);
+ l = read_command_lines (tmpbuf, from_tty);
+ free_command_lines (&b->commands);
+ b->commands = l;
+ breakpoints_changed ();
+ return;
+ }
+ error ("No breakpoint number %d.", bnum);
+}
+
+/* Like target_read_memory() but if breakpoints are inserted, return
+ the shadow contents instead of the breakpoints themselves.
+
+ Read "memory data" from whatever target or inferior we have.
+ Returns zero if successful, errno value if not. EIO is used
+ for address out of bounds. If breakpoints are inserted, returns
+ shadow contents, not the breakpoints themselves. From breakpoint.c. */
+
+int
+read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
+{
+ int status;
+ struct breakpoint *b;
+ CORE_ADDR bp_addr = 0;
+ int bp_size = 0;
+
+ if (BREAKPOINT_FROM_PC (&bp_addr, &bp_size) == NULL)
+ /* No breakpoints on this machine. */
+ return target_read_memory (memaddr, myaddr, len);
+
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->type == bp_none)
+ warning ("reading through apparently deleted breakpoint #%d?",
+ b->number);
+
+ /* memory breakpoint? */
+ if (b->type == bp_watchpoint
+ || b->type == bp_hardware_watchpoint
+ || b->type == bp_read_watchpoint
+ || b->type == bp_access_watchpoint)
+ continue;
+ /* bp in memory? */
+ if (!b->inserted)
+ continue;
+ /* Addresses and length of the part of the breakpoint that
+ we need to copy. */
+ /* XXXX The m68k, sh and h8300 have different local and remote
+ breakpoint values. BREAKPOINT_FROM_PC still manages to
+ correctly determine the breakpoints memory address and size
+ for these targets. */
+ bp_addr = b->address;
+ bp_size = 0;
+ if (BREAKPOINT_FROM_PC (&bp_addr, &bp_size) == NULL)
+ continue;
+ if (bp_size == 0)
+ /* bp isn't valid */
+ continue;
+ if (bp_addr + bp_size <= memaddr)
+ /* The breakpoint is entirely before the chunk of memory we
+ are reading. */
+ continue;
+ if (bp_addr >= memaddr + len)
+ /* The breakpoint is entirely after the chunk of memory we are
+ reading. */
+ continue;
+ /* Copy the breakpoint from the shadow contents, and recurse for
+ the things before and after. */
+ {
+ /* Offset within shadow_contents. */
+ int bptoffset = 0;
+
+ if (bp_addr < memaddr)
+ {
+ /* Only copy the second part of the breakpoint. */
+ bp_size -= memaddr - bp_addr;
+ bptoffset = memaddr - bp_addr;
+ bp_addr = memaddr;
+ }
+
+ if (bp_addr + bp_size > memaddr + len)
+ {
+ /* Only copy the first part of the breakpoint. */
+ bp_size -= (bp_addr + bp_size) - (memaddr + len);
+ }
+
+ memcpy (myaddr + bp_addr - memaddr,
+ b->shadow_contents + bptoffset, bp_size);
+
+ if (bp_addr > memaddr)
+ {
+ /* Copy the section of memory before the breakpoint. */
+ status = read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr);
+ if (status != 0)
+ return status;
+ }
+
+ if (bp_addr + bp_size < memaddr + len)
+ {
+ /* Copy the section of memory after the breakpoint. */
+ status = read_memory_nobpt (bp_addr + bp_size,
+ myaddr + bp_addr + bp_size - memaddr,
+ memaddr + len - (bp_addr + bp_size));
+ if (status != 0)
+ return status;
+ }
+ return 0;
+ }
+ }
+ /* Nothing overlaps. Just call read_memory_noerr. */
+ return target_read_memory (memaddr, myaddr, len);
+}
+
+
+/* insert_breakpoints is used when starting or continuing the program.
+ remove_breakpoints is used when the program stops.
+ Both return zero if successful,
+ or an `errno' value if could not write the inferior. */
+
+int
+insert_breakpoints (void)
+{
+ register struct breakpoint *b, *temp;
+ int return_val = 0; /* return success code. */
+ int val = 0;
+ int disabled_breaks = 0;
+
+ static char message1[] = "Error inserting catchpoint %d:\n";
+ static char message[sizeof (message1) + 30];
+
+
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ {
+ if (b->enable_state == bp_permanent)
+ /* Permanent breakpoints cannot be inserted or removed. */
+ continue;
+ else if (b->type != bp_watchpoint
+ && b->type != bp_hardware_watchpoint
+ && b->type != bp_read_watchpoint
+ && b->type != bp_access_watchpoint
+ && b->type != bp_catch_fork
+ && b->type != bp_catch_vfork
+ && b->type != bp_catch_exec
+ && b->type != bp_catch_throw
+ && b->type != bp_catch_catch
+ && b->enable_state != bp_disabled
+ && b->enable_state != bp_shlib_disabled
+ && b->enable_state != bp_call_disabled
+ && !b->inserted
+ && !b->duplicate)
+ {
+ /* "Normal" instruction breakpoint: either the standard
+ trap-instruction bp (bp_breakpoint), or a
+ bp_hardware_breakpoint. */
+
+ /* First check to see if we have to handle an overlay. */
+ if (overlay_debugging == ovly_off
+ || b->section == NULL
+ || !(section_is_overlay (b->section)))
+ {
+ /* No overlay handling: just set the breakpoint. */
+
+ if (b->type == bp_hardware_breakpoint)
+ val = target_insert_hw_breakpoint (b->address,
+ b->shadow_contents);
+ else
+ val = target_insert_breakpoint (b->address, b->shadow_contents);
+ }
+ else
+ {
+ /* This breakpoint is in an overlay section.
+ Shall we set a breakpoint at the LMA? */
+ if (!overlay_events_enabled)
+ {
+ /* Yes -- overlay event support is not active,
+ so we must try to set a breakpoint at the LMA.
+ This will not work for a hardware breakpoint. */
+ if (b->type == bp_hardware_breakpoint)
+ warning ("hardware breakpoint %d not supported in overlay!\n",
+ b->number);
+ else
+ {
+ CORE_ADDR addr = overlay_unmapped_address (b->address,
+ b->section);
+ /* Set a software (trap) breakpoint at the LMA. */
+ val = target_insert_breakpoint (addr, b->shadow_contents);
+ if (val != 0)
+ warning ("overlay breakpoint %d failed: in ROM?",
+ b->number);
+ }
+ }
+ /* Shall we set a breakpoint at the VMA? */
+ if (section_is_mapped (b->section))
+ {
+ /* Yes. This overlay section is mapped into memory. */
+ if (b->type == bp_hardware_breakpoint)
+ val = target_insert_hw_breakpoint (b->address,
+ b->shadow_contents);
+ else
+ val = target_insert_breakpoint (b->address,
+ b->shadow_contents);
+ }
+ else
+ {
+ /* No. This breakpoint will not be inserted.
+ No error, but do not mark the bp as 'inserted'. */
+ continue;
+ }
+ }
+
+ if (val)
+ {
+ /* Can't set the breakpoint. */
+#if defined (DISABLE_UNSETTABLE_BREAK)
+ if (DISABLE_UNSETTABLE_BREAK (b->address))
+ {
+ /* See also: disable_breakpoints_in_shlibs. */
+ val = 0;
+ b->enable_state = bp_shlib_disabled;
+ if (!disabled_breaks)
+ {
+ target_terminal_ours_for_output ();
+ warning ("Cannot insert breakpoint %d:", b->number);
+ warning ("Temporarily disabling shared library breakpoints:");
+ }
+ disabled_breaks = 1;
+ warning ("breakpoint #%d ", b->number);
+ }
+ else
+#endif
+ {
+ target_terminal_ours_for_output ();
+ warning ("Cannot insert breakpoint %d:", b->number);
+#ifdef ONE_PROCESS_WRITETEXT
+ warning ("The same program may be running in another process.");
+#endif
+ memory_error (val, b->address); /* which bombs us out */
+ }
+ }
+ else
+ b->inserted = 1;
+
+ if (val)
+ return_val = val; /* remember failure */
+ }
+ else if (ep_is_exception_catchpoint (b)
+ && b->enable_state != bp_disabled
+ && b->enable_state != bp_shlib_disabled
+ && b->enable_state != bp_call_disabled
+ && !b->inserted
+ && !b->duplicate)
+
+ {
+ /* If we get here, we must have a callback mechanism for exception
+ events -- with g++ style embedded label support, we insert
+ ordinary breakpoints and not catchpoints. */
+ /* Format possible error message */
+ sprintf (message, message1, b->number);
+
+ val = target_insert_breakpoint (b->address, b->shadow_contents);
+ if (val)
+ {
+ /* Couldn't set breakpoint for some reason */
+ target_terminal_ours_for_output ();
+ warning ("Cannot insert catchpoint %d; disabling it.",
+ b->number);
+ b->enable_state = bp_disabled;
+ }
+ else
+ {
+ /* Bp set, now make sure callbacks are enabled */
+ int val;
+ args_for_catchpoint_enable args;
+ args.kind = b->type == bp_catch_catch ?
+ EX_EVENT_CATCH : EX_EVENT_THROW;
+ args.enable_p = 1;
+ val = catch_errors (cover_target_enable_exception_callback,
+ &args,
+ message, RETURN_MASK_ALL);
+ if (val != 0 && val != -1)
+ {
+ b->inserted = 1;
+ }
+ /* Check if something went wrong; val == 0 can be ignored */
+ if (val == -1)
+ {
+ /* something went wrong */
+ target_terminal_ours_for_output ();
+ warning ("Cannot insert catchpoint %d; disabling it.",
+ b->number);
+ b->enable_state = bp_disabled;
+ }
+ }
+
+ if (val)
+ return_val = val; /* remember failure */
+ }
+
+ else if ((b->type == bp_hardware_watchpoint ||
+ b->type == bp_read_watchpoint ||
+ b->type == bp_access_watchpoint)
+ && b->enable_state == bp_enabled
+ && b->disposition != disp_del_at_next_stop
+ && !b->inserted
+ && !b->duplicate)
+ {
+ struct frame_info *saved_frame;
+ int saved_level, within_current_scope;
+ struct value *mark = value_mark ();
+ struct value *v;
+
+ /* Save the current frame and level so we can restore it after
+ evaluating the watchpoint expression on its own frame. */
+ saved_frame = selected_frame;
+ saved_level = frame_relative_level (selected_frame);
+
+ /* Determine if the watchpoint is within scope. */
+ if (b->exp_valid_block == NULL)
+ within_current_scope = 1;
+ else
+ {
+ struct frame_info *fi;
+
+ /* There might be no current frame at this moment if we are
+ resuming from a step over a breakpoint.
+ Set up current frame before trying to find the watchpoint
+ frame. */
+ get_current_frame ();
+ fi = find_frame_addr_in_frame_chain (b->watchpoint_frame);
+ within_current_scope = (fi != NULL);
+ if (within_current_scope)
+ select_frame (fi);
+ }
+
+ if (within_current_scope)
+ {
+ /* Evaluate the expression and cut the chain of values
+ produced off from the value chain.
+
+ Make sure the value returned isn't lazy; we use
+ laziness to determine what memory GDB actually needed
+ in order to compute the value of the expression. */
+ v = evaluate_expression (b->exp);
+ VALUE_CONTENTS(v);
+ value_release_to_mark (mark);
+
+ b->val_chain = v;
+ b->inserted = 1;
+
+ /* Look at each value on the value chain. */
+ for (; v; v = v->next)
+ {
+ /* If it's a memory location, and GDB actually needed
+ its contents to evaluate the expression, then we
+ must watch it. */
+ if (VALUE_LVAL (v) == lval_memory
+ && ! VALUE_LAZY (v))
+ {
+ struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+ /* We only watch structs and arrays if user asked
+ for it explicitly, never if they just happen to
+ appear in the middle of some value chain. */
+ if (v == b->val_chain
+ || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+ && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+ {
+ CORE_ADDR addr;
+ int len, type;
+
+ addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+ len = TYPE_LENGTH (VALUE_TYPE (v));
+ type = hw_write;
+ if (b->type == bp_read_watchpoint)
+ type = hw_read;
+ else if (b->type == bp_access_watchpoint)
+ type = hw_access;
+
+ val = target_insert_watchpoint (addr, len, type);
+ if (val == -1)
+ {
+ /* Don't exit the loop, try to insert
+ every value on the value chain. That's
+ because we will be removing all the
+ watches below, and removing a
+ watchpoint we didn't insert could have
+ adverse effects. */
+ b->inserted = 0;
+ }
+ val = 0;
+ }
+ }
+ }
+ /* Failure to insert a watchpoint on any memory value in the
+ value chain brings us here. */
+ if (!b->inserted)
+ {
+ remove_breakpoint (b, mark_uninserted);
+ warning ("Could not insert hardware watchpoint %d.",
+ b->number);
+ val = -1;
+ }
+ }
+ else
+ {
+ printf_filtered ("Hardware watchpoint %d deleted ", b->number);
+ printf_filtered ("because the program has left the block \n");
+ printf_filtered ("in which its expression is valid.\n");
+ if (b->related_breakpoint)
+ b->related_breakpoint->disposition = disp_del_at_next_stop;
+ b->disposition = disp_del_at_next_stop;
+ }
+
+ /* Restore the frame and level. */
+ if ((saved_frame != selected_frame) ||
+ (saved_level != frame_relative_level (selected_frame)))
+ select_frame (saved_frame);
+
+ if (val)
+ return_val = val; /* remember failure */
+ }
+ else if ((b->type == bp_catch_fork
+ || b->type == bp_catch_vfork
+ || b->type == bp_catch_exec)
+ && b->enable_state == bp_enabled
+ && !b->inserted
+ && !b->duplicate)
+ {
+ val = -1;
+ switch (b->type)
+ {
+ case bp_catch_fork:
+ val = target_insert_fork_catchpoint (PIDGET (inferior_ptid));
+ break;
+ case bp_catch_vfork:
+ val = target_insert_vfork_catchpoint (PIDGET (inferior_ptid));
+ break;
+ case bp_catch_exec:
+ val = target_insert_exec_catchpoint (PIDGET (inferior_ptid));
+ break;
+ default:
+ warning ("Internal error, %s line %d.", __FILE__, __LINE__);
+ break;
+ }
+ if (val < 0)
+ {
+ target_terminal_ours_for_output ();
+ warning ("Cannot insert catchpoint %d.", b->number);
+ }
+ else
+ b->inserted = 1;
+
+ if (val)
+ return_val = val; /* remember failure */
+ }
+ }
+
+ return return_val;
+}
+
+
+int
+remove_breakpoints (void)
+{
+ register struct breakpoint *b;
+ int val;
+
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->inserted)
+ {
+ val = remove_breakpoint (b, mark_uninserted);
+ if (val != 0)
+ return val;
+ }
+ }
+ return 0;
+}
+
+int
+remove_hw_watchpoints (void)
+{
+ register struct breakpoint *b;
+ int val;
+
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->inserted
+ && (b->type == bp_hardware_watchpoint
+ || b->type == bp_read_watchpoint
+ || b->type == bp_access_watchpoint))
+ {
+ val = remove_breakpoint (b, mark_uninserted);
+ if (val != 0)
+ return val;
+ }
+ }
+ return 0;
+}
+
+int
+reattach_breakpoints (int pid)
+{
+ register struct breakpoint *b;
+ int val;
+ struct cleanup *old_chain = save_inferior_ptid ();
+
+ /* Set inferior_ptid; remove_breakpoint uses this global. */
+ inferior_ptid = pid_to_ptid (pid);
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->inserted)
+ {
+ remove_breakpoint (b, mark_inserted);
+ if (b->type == bp_hardware_breakpoint)
+ val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
+ else
+ val = target_insert_breakpoint (b->address, b->shadow_contents);
+ if (val != 0)
+ {
+ do_cleanups (old_chain);
+ return val;
+ }
+ }
+ }
+ do_cleanups (old_chain);
+ return 0;
+}
+
+void
+update_breakpoints_after_exec (void)
+{
+ struct breakpoint *b;
+ struct breakpoint *temp;
+
+ /* Doing this first prevents the badness of having delete_breakpoint()
+ write a breakpoint's current "shadow contents" to lift the bp. That
+ shadow is NOT valid after an exec()! */
+ mark_breakpoints_out ();
+
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ {
+ /* Solib breakpoints must be explicitly reset after an exec(). */
+ if (b->type == bp_shlib_event)
+ {
+ delete_breakpoint (b);
+ continue;
+ }
+
+ /* Thread event breakpoints must be set anew after an exec(),
+ as must overlay event breakpoints. */
+ if (b->type == bp_thread_event || b->type == bp_overlay_event)
+ {
+ delete_breakpoint (b);
+ continue;
+ }
+
+ /* Step-resume breakpoints are meaningless after an exec(). */
+ if (b->type == bp_step_resume)
+ {
+ delete_breakpoint (b);
+ continue;
+ }
+
+ /* Ditto the sigtramp handler breakpoints. */
+ if (b->type == bp_through_sigtramp)
+ {
+ delete_breakpoint (b);
+ continue;
+ }
+
+ /* Ditto the exception-handling catchpoints. */
+ if ((b->type == bp_catch_catch) || (b->type == bp_catch_throw))
+ {
+ delete_breakpoint (b);
+ continue;
+ }
+
+ /* Don't delete an exec catchpoint, because else the inferior
+ won't stop when it ought!
+
+ Similarly, we probably ought to keep vfork catchpoints, 'cause
+ on this target, we may not be able to stop when the vfork is
+ seen, but only when the subsequent exec is seen. (And because
+ deleting fork catchpoints here but not vfork catchpoints will
+ seem mysterious to users, keep those too.)
+
+ ??rehrauer: Let's hope that merely clearing out this catchpoint's
+ target address field, if any, is sufficient to have it be reset
+ automagically. Certainly on HP-UX that's true.
+
+ Jim Blandy <jimb@redhat.com>: Actually, zero is a perfectly
+ valid code address on some platforms (like the mn10200 and
+ mn10300 simulators). We shouldn't assign any special
+ interpretation to a breakpoint with a zero address. And in
+ fact, GDB doesn't --- I can't see what that comment above is
+ talking about. As far as I can tell, setting the address of a
+ bp_catch_exec/bp_catch_vfork/bp_catch_fork breakpoint to zero
+ is meaningless, since those are implemented with HP-UX kernel
+ hackery, not by storing breakpoint instructions somewhere. */
+ if ((b->type == bp_catch_exec) ||
+ (b->type == bp_catch_vfork) ||
+ (b->type == bp_catch_fork))
+ {
+ b->address = (CORE_ADDR) NULL;
+ continue;
+ }
+
+ /* bp_finish is a special case. The only way we ought to be able
+ to see one of these when an exec() has happened, is if the user
+ caught a vfork, and then said "finish". Ordinarily a finish just
+ carries them to the call-site of the current callee, by setting
+ a temporary bp there and resuming. But in this case, the finish
+ will carry them entirely through the vfork & exec.
+
+ We don't want to allow a bp_finish to remain inserted now. But
+ we can't safely delete it, 'cause finish_command has a handle to
+ the bp on a bpstat, and will later want to delete it. There's a
+ chance (and I've seen it happen) that if we delete the bp_finish
+ here, that its storage will get reused by the time finish_command
+ gets 'round to deleting the "use to be a bp_finish" breakpoint.
+ We really must allow finish_command to delete a bp_finish.
+
+ In the absense of a general solution for the "how do we know
+ it's safe to delete something others may have handles to?"
+ problem, what we'll do here is just uninsert the bp_finish, and
+ let finish_command delete it.
+
+ (We know the bp_finish is "doomed" in the sense that it's
+ momentary, and will be deleted as soon as finish_command sees
+ the inferior stopped. So it doesn't matter that the bp's
+ address is probably bogus in the new a.out, unlike e.g., the
+ solib breakpoints.) */
+
+ if (b->type == bp_finish)
+ {
+ continue;
+ }
+
+ /* Without a symbolic address, we have little hope of the
+ pre-exec() address meaning the same thing in the post-exec()
+ a.out. */
+ if (b->addr_string == NULL)
+ {
+ delete_breakpoint (b);
+ continue;
+ }
+
+ /* If this breakpoint has survived the above battery of checks, then
+ it must have a symbolic address. Be sure that it gets reevaluated
+ to a target address, rather than reusing the old evaluation.
+
+ Jim Blandy <jimb@redhat.com>: As explained above in the comment
+ for bp_catch_exec and friends, I'm pretty sure this is entirely
+ unnecessary. A call to breakpoint_re_set_one always recomputes
+ the breakpoint's address from scratch, or deletes it if it can't.
+ So I think this assignment could be deleted without effect. */
+ b->address = (CORE_ADDR) NULL;
+ }
+ /* FIXME what about longjmp breakpoints? Re-create them here? */
+ create_overlay_event_breakpoint ("_ovly_debug_event");
+}
+
+int
+detach_breakpoints (int pid)
+{
+ register struct breakpoint *b;
+ int val;
+ struct cleanup *old_chain = save_inferior_ptid ();
+
+ if (pid == PIDGET (inferior_ptid))
+ error ("Cannot detach breakpoints of inferior_ptid");
+
+ /* Set inferior_ptid; remove_breakpoint uses this global. */
+ inferior_ptid = pid_to_ptid (pid);
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->inserted)
+ {
+ val = remove_breakpoint (b, mark_inserted);
+ if (val != 0)
+ {
+ do_cleanups (old_chain);
+ return val;
+ }
+ }
+ }
+ do_cleanups (old_chain);
+ return 0;
+}
+
+static int
+remove_breakpoint (struct breakpoint *b, insertion_state_t is)
+{
+ int val;
+
+ if (b->enable_state == bp_permanent)
+ /* Permanent breakpoints cannot be inserted or removed. */
+ return 0;
+
+ if (b->type == bp_none)
+ warning ("attempted to remove apparently deleted breakpoint #%d?",
+ b->number);
+
+ if (b->type != bp_watchpoint
+ && b->type != bp_hardware_watchpoint
+ && b->type != bp_read_watchpoint
+ && b->type != bp_access_watchpoint
+ && b->type != bp_catch_fork
+ && b->type != bp_catch_vfork
+ && b->type != bp_catch_exec
+ && b->type != bp_catch_catch
+ && b->type != bp_catch_throw)
+ {
+ /* "Normal" instruction breakpoint: either the standard
+ trap-instruction bp (bp_breakpoint), or a
+ bp_hardware_breakpoint. */
+
+ /* First check to see if we have to handle an overlay. */
+ if (overlay_debugging == ovly_off
+ || b->section == NULL
+ || !(section_is_overlay (b->section)))
+ {
+ /* No overlay handling: just remove the breakpoint. */
+
+ if (b->type == bp_hardware_breakpoint)
+ val = target_remove_hw_breakpoint (b->address,
+ b->shadow_contents);
+ else
+ val = target_remove_breakpoint (b->address, b->shadow_contents);
+ }
+ else
+ {
+ /* This breakpoint is in an overlay section.
+ Did we set a breakpoint at the LMA? */
+ if (!overlay_events_enabled)
+ {
+ /* Yes -- overlay event support is not active, so we
+ should have set a breakpoint at the LMA. Remove it.
+ */
+ CORE_ADDR addr = overlay_unmapped_address (b->address,
+ b->section);
+ /* Ignore any failures: if the LMA is in ROM, we will
+ have already warned when we failed to insert it. */
+ if (b->type != bp_hardware_breakpoint)
+ target_remove_hw_breakpoint (addr, b->shadow_contents);
+ else
+ target_remove_breakpoint (addr, b->shadow_contents);
+ }
+ /* Did we set a breakpoint at the VMA?
+ If so, we will have marked the breakpoint 'inserted'. */
+ if (b->inserted)
+ {
+ /* Yes -- remove it. Previously we did not bother to
+ remove the breakpoint if the section had been
+ unmapped, but let's not rely on that being safe. We
+ don't know what the overlay manager might do. */
+ if (b->type == bp_hardware_breakpoint)
+ val = target_remove_hw_breakpoint (b->address,
+ b->shadow_contents);
+ else
+ val = target_remove_breakpoint (b->address,
+ b->shadow_contents);
+ }
+ else
+ {
+ /* No -- not inserted, so no need to remove. No error. */
+ val = 0;
+ }
+ }
+ if (val)
+ return val;
+ b->inserted = (is == mark_inserted);
+ }
+ else if ((b->type == bp_hardware_watchpoint ||
+ b->type == bp_read_watchpoint ||
+ b->type == bp_access_watchpoint)
+ && b->enable_state == bp_enabled
+ && !b->duplicate)
+ {
+ struct value *v;
+ struct value *n;
+
+ b->inserted = (is == mark_inserted);
+ /* Walk down the saved value chain. */
+ for (v = b->val_chain; v; v = v->next)
+ {
+ /* For each memory reference remove the watchpoint
+ at that address. */
+ if (VALUE_LVAL (v) == lval_memory
+ && ! VALUE_LAZY (v))
+ {
+ struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+ if (v == b->val_chain
+ || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+ && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+ {
+ CORE_ADDR addr;
+ int len, type;
+
+ addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+ len = TYPE_LENGTH (VALUE_TYPE (v));
+ type = hw_write;
+ if (b->type == bp_read_watchpoint)
+ type = hw_read;
+ else if (b->type == bp_access_watchpoint)
+ type = hw_access;
+
+ val = target_remove_watchpoint (addr, len, type);
+ if (val == -1)
+ b->inserted = 1;
+ val = 0;
+ }
+ }
+ }
+ /* Failure to remove any of the hardware watchpoints comes here. */
+ if ((is == mark_uninserted) && (b->inserted))
+ warning ("Could not remove hardware watchpoint %d.",
+ b->number);
+
+ /* Free the saved value chain. We will construct a new one
+ the next time the watchpoint is inserted. */
+ for (v = b->val_chain; v; v = n)
+ {
+ n = v->next;
+ value_free (v);
+ }
+ b->val_chain = NULL;
+ }
+ else if ((b->type == bp_catch_fork ||
+ b->type == bp_catch_vfork ||
+ b->type == bp_catch_exec)
+ && b->enable_state == bp_enabled
+ && !b->duplicate)
+ {
+ val = -1;
+ switch (b->type)
+ {
+ case bp_catch_fork:
+ val = target_remove_fork_catchpoint (PIDGET (inferior_ptid));
+ break;
+ case bp_catch_vfork:
+ val = target_remove_vfork_catchpoint (PIDGET (inferior_ptid));
+ break;
+ case bp_catch_exec:
+ val = target_remove_exec_catchpoint (PIDGET (inferior_ptid));
+ break;
+ default:
+ warning ("Internal error, %s line %d.", __FILE__, __LINE__);
+ break;
+ }
+ if (val)
+ return val;
+ b->inserted = (is == mark_inserted);
+ }
+ else if ((b->type == bp_catch_catch ||
+ b->type == bp_catch_throw)
+ && b->enable_state == bp_enabled
+ && !b->duplicate)
+ {
+
+ val = target_remove_breakpoint (b->address, b->shadow_contents);
+ if (val)
+ return val;
+ b->inserted = (is == mark_inserted);
+ }
+ else if (ep_is_exception_catchpoint (b)
+ && b->inserted /* sometimes previous insert doesn't happen */
+ && b->enable_state == bp_enabled
+ && !b->duplicate)
+ {
+
+ val = target_remove_breakpoint (b->address, b->shadow_contents);
+ if (val)
+ return val;
+
+ b->inserted = (is == mark_inserted);
+ }
+
+ return 0;
+}
+
+/* Clear the "inserted" flag in all breakpoints. */
+
+void
+mark_breakpoints_out (void)
+{
+ register struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ b->inserted = 0;
+}
+
+/* Clear the "inserted" flag in all breakpoints and delete any
+ breakpoints which should go away between runs of the program.
+
+ Plus other such housekeeping that has to be done for breakpoints
+ between runs.
+
+ Note: this function gets called at the end of a run (by
+ generic_mourn_inferior) and when a run begins (by
+ init_wait_for_inferior). */
+
+
+
+void
+breakpoint_init_inferior (enum inf_context context)
+{
+ register struct breakpoint *b, *temp;
+ static int warning_needed = 0;
+
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ {
+ b->inserted = 0;
+
+ switch (b->type)
+ {
+ case bp_call_dummy:
+ case bp_watchpoint_scope:
+
+ /* If the call dummy breakpoint is at the entry point it will
+ cause problems when the inferior is rerun, so we better
+ get rid of it.
+
+ Also get rid of scope breakpoints. */
+ delete_breakpoint (b);
+ break;
+
+ case bp_watchpoint:
+ case bp_hardware_watchpoint:
+ case bp_read_watchpoint:
+ case bp_access_watchpoint:
+
+ /* Likewise for watchpoints on local expressions. */
+ if (b->exp_valid_block != NULL)
+ delete_breakpoint (b);
+ break;
+ default:
+ /* Likewise for exception catchpoints in dynamic-linked
+ executables where required */
+ if (ep_is_exception_catchpoint (b) &&
+ exception_catchpoints_are_fragile)
+ {
+ warning_needed = 1;
+ delete_breakpoint (b);
+ }
+ break;
+ }
+ }
+
+ if (exception_catchpoints_are_fragile)
+ exception_support_initialized = 0;
+
+ /* Don't issue the warning unless it's really needed... */
+ if (warning_needed && (context != inf_exited))
+ {
+ warning ("Exception catchpoints from last run were deleted.");
+ warning ("You must reinsert them explicitly.");
+ warning_needed = 0;
+ }
+}
+
+/* breakpoint_here_p (PC) returns non-zero if an enabled breakpoint
+ exists at PC. It returns ordinary_breakpoint_here if it's an
+ ordinary breakpoint, or permanent_breakpoint_here if it's a
+ permanent breakpoint.
+ - When continuing from a location with an ordinary breakpoint, we
+ actually single step once before calling insert_breakpoints.
+ - When continuing from a localion with a permanent breakpoint, we
+ need to use the `SKIP_PERMANENT_BREAKPOINT' macro, provided by
+ the target, to advance the PC past the breakpoint. */
+
+enum breakpoint_here
+breakpoint_here_p (CORE_ADDR pc)
+{
+ register struct breakpoint *b;
+ int any_breakpoint_here = 0;
+
+ ALL_BREAKPOINTS (b)
+ if ((b->enable_state == bp_enabled
+ || b->enable_state == bp_permanent)
+ && b->address == pc) /* bp is enabled and matches pc */
+ {
+ if (overlay_debugging
+ && section_is_overlay (b->section)
+ && !section_is_mapped (b->section))
+ continue; /* unmapped overlay -- can't be a match */
+ else if (b->enable_state == bp_permanent)
+ return permanent_breakpoint_here;
+ else
+ any_breakpoint_here = 1;
+ }
+
+ return any_breakpoint_here ? ordinary_breakpoint_here : 0;
+}
+
+
+/* breakpoint_inserted_here_p (PC) is just like breakpoint_here_p(),
+ but it only returns true if there is actually a breakpoint inserted
+ at PC. */
+
+int
+breakpoint_inserted_here_p (CORE_ADDR pc)
+{
+ register struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ if (b->inserted
+ && b->address == pc) /* bp is inserted and matches pc */
+ {
+ if (overlay_debugging
+ && section_is_overlay (b->section)
+ && !section_is_mapped (b->section))
+ continue; /* unmapped overlay -- can't be a match */
+ else
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Return nonzero if FRAME is a dummy frame. We can't use
+ PC_IN_CALL_DUMMY because figuring out the saved SP would take too
+ much time, at least using get_saved_register on the 68k. This
+ means that for this function to work right a port must use the
+ bp_call_dummy breakpoint. */
+
+int
+frame_in_dummy (struct frame_info *frame)
+{
+ struct breakpoint *b;
+
+ if (!CALL_DUMMY_P)
+ return 0;
+
+ if (USE_GENERIC_DUMMY_FRAMES)
+ return generic_pc_in_call_dummy (frame->pc, frame->frame, frame->frame);
+
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->type == bp_call_dummy
+ && b->frame == frame->frame
+ /* We need to check the PC as well as the frame on the sparc,
+ for signals.exp in the testsuite. */
+ && (frame->pc
+ >= (b->address
+ - SIZEOF_CALL_DUMMY_WORDS / sizeof (LONGEST) * REGISTER_SIZE))
+ && frame->pc <= b->address)
+ return 1;
+ }
+ return 0;
+}
+
+/* breakpoint_thread_match (PC, PID) returns true if the breakpoint at
+ PC is valid for process/thread PID. */
+
+int
+breakpoint_thread_match (CORE_ADDR pc, ptid_t ptid)
+{
+ struct breakpoint *b;
+ int thread;
+
+ thread = pid_to_thread_id (ptid);
+
+ ALL_BREAKPOINTS (b)
+ if (b->enable_state != bp_disabled
+ && b->enable_state != bp_shlib_disabled
+ && b->enable_state != bp_call_disabled
+ && b->address == pc
+ && (b->thread == -1 || b->thread == thread))
+ {
+ if (overlay_debugging
+ && section_is_overlay (b->section)
+ && !section_is_mapped (b->section))
+ continue; /* unmapped overlay -- can't be a match */
+ else
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* bpstat stuff. External routines' interfaces are documented
+ in breakpoint.h. */
+
+int
+ep_is_catchpoint (struct breakpoint *ep)
+{
+ return
+ (ep->type == bp_catch_load)
+ || (ep->type == bp_catch_unload)
+ || (ep->type == bp_catch_fork)
+ || (ep->type == bp_catch_vfork)
+ || (ep->type == bp_catch_exec)
+ || (ep->type == bp_catch_catch)
+ || (ep->type == bp_catch_throw);
+
+ /* ??rehrauer: Add more kinds here, as are implemented... */
+}
+
+int
+ep_is_shlib_catchpoint (struct breakpoint *ep)
+{
+ return
+ (ep->type == bp_catch_load)
+ || (ep->type == bp_catch_unload);
+}
+
+int
+ep_is_exception_catchpoint (struct breakpoint *ep)
+{
+ return
+ (ep->type == bp_catch_catch)
+ || (ep->type == bp_catch_throw);
+}
+
+/* Clear a bpstat so that it says we are not at any breakpoint.
+ Also free any storage that is part of a bpstat. */
+
+void
+bpstat_clear (bpstat *bsp)
+{
+ bpstat p;
+ bpstat q;
+
+ if (bsp == 0)
+ return;
+ p = *bsp;
+ while (p != NULL)
+ {
+ q = p->next;
+ if (p->old_val != NULL)
+ value_free (p->old_val);
+ xfree (p);
+ p = q;
+ }
+ *bsp = NULL;
+}
+
+/* Return a copy of a bpstat. Like "bs1 = bs2" but all storage that
+ is part of the bpstat is copied as well. */
+
+bpstat
+bpstat_copy (bpstat bs)
+{
+ bpstat p = NULL;
+ bpstat tmp;
+ bpstat retval = NULL;
+
+ if (bs == NULL)
+ return bs;
+
+ for (; bs != NULL; bs = bs->next)
+ {
+ tmp = (bpstat) xmalloc (sizeof (*tmp));
+ memcpy (tmp, bs, sizeof (*tmp));
+ if (p == NULL)
+ /* This is the first thing in the chain. */
+ retval = tmp;
+ else
+ p->next = tmp;
+ p = tmp;
+ }
+ p->next = NULL;
+ return retval;
+}
+
+/* Find the bpstat associated with this breakpoint */
+
+bpstat
+bpstat_find_breakpoint (bpstat bsp, struct breakpoint *breakpoint)
+{
+ if (bsp == NULL)
+ return NULL;
+
+ for (; bsp != NULL; bsp = bsp->next)
+ {
+ if (bsp->breakpoint_at == breakpoint)
+ return bsp;
+ }
+ return NULL;
+}
+
+/* Find a step_resume breakpoint associated with this bpstat.
+ (If there are multiple step_resume bp's on the list, this function
+ will arbitrarily pick one.)
+
+ It is an error to use this function if BPSTAT doesn't contain a
+ step_resume breakpoint.
+
+ See wait_for_inferior's use of this function. */
+struct breakpoint *
+bpstat_find_step_resume_breakpoint (bpstat bsp)
+{
+ int current_thread;
+
+ if (bsp == NULL)
+ error ("Internal error (bpstat_find_step_resume_breakpoint)");
+
+ current_thread = pid_to_thread_id (inferior_ptid);
+
+ for (; bsp != NULL; bsp = bsp->next)
+ {
+ if ((bsp->breakpoint_at != NULL) &&
+ (bsp->breakpoint_at->type == bp_step_resume) &&
+ (bsp->breakpoint_at->thread == current_thread ||
+ bsp->breakpoint_at->thread == -1))
+ return bsp->breakpoint_at;
+ }
+
+ error ("Internal error (no step_resume breakpoint found)");
+}
+
+
+/* Return the breakpoint number of the first breakpoint we are stopped
+ at. *BSP upon return is a bpstat which points to the remaining
+ breakpoints stopped at (but which is not guaranteed to be good for
+ anything but further calls to bpstat_num).
+ Return 0 if passed a bpstat which does not indicate any breakpoints. */
+
+int
+bpstat_num (bpstat *bsp)
+{
+ struct breakpoint *b;
+
+ if ((*bsp) == NULL)
+ return 0; /* No more breakpoint values */
+ else
+ {
+ b = (*bsp)->breakpoint_at;
+ *bsp = (*bsp)->next;
+ if (b == NULL)
+ return -1; /* breakpoint that's been deleted since */
+ else
+ return b->number; /* We have its number */
+ }
+}
+
+/* Modify BS so that the actions will not be performed. */
+
+void
+bpstat_clear_actions (bpstat bs)
+{
+ for (; bs != NULL; bs = bs->next)
+ {
+ bs->commands = NULL;
+ if (bs->old_val != NULL)
+ {
+ value_free (bs->old_val);
+ bs->old_val = NULL;
+ }
+ }
+}
+
+/* Stub for cleaning up our state if we error-out of a breakpoint command */
+/* ARGSUSED */
+static void
+cleanup_executing_breakpoints (PTR ignore)
+{
+ executing_breakpoint_commands = 0;
+}
+
+/* Execute all the commands associated with all the breakpoints at this
+ location. Any of these commands could cause the process to proceed
+ beyond this point, etc. We look out for such changes by checking
+ the global "breakpoint_proceeded" after each command. */
+
+void
+bpstat_do_actions (bpstat *bsp)
+{
+ bpstat bs;
+ struct cleanup *old_chain;
+ struct command_line *cmd;
+
+ /* Avoid endless recursion if a `source' command is contained
+ in bs->commands. */
+ if (executing_breakpoint_commands)
+ return;
+
+ executing_breakpoint_commands = 1;
+ old_chain = make_cleanup (cleanup_executing_breakpoints, 0);
+
+top:
+ /* Note that (as of this writing), our callers all appear to
+ be passing us the address of global stop_bpstat. And, if
+ our calls to execute_control_command cause the inferior to
+ proceed, that global (and hence, *bsp) will change.
+
+ We must be careful to not touch *bsp unless the inferior
+ has not proceeded. */
+
+ /* This pointer will iterate over the list of bpstat's. */
+ bs = *bsp;
+
+ breakpoint_proceeded = 0;
+ for (; bs != NULL; bs = bs->next)
+ {
+ cmd = bs->commands;
+ while (cmd != NULL)
+ {
+ execute_control_command (cmd);
+
+ if (breakpoint_proceeded)
+ break;
+ else
+ cmd = cmd->next;
+ }
+ if (breakpoint_proceeded)
+ /* The inferior is proceeded by the command; bomb out now.
+ The bpstat chain has been blown away by wait_for_inferior.
+ But since execution has stopped again, there is a new bpstat
+ to look at, so start over. */
+ goto top;
+ else
+ bs->commands = NULL;
+ }
+
+ executing_breakpoint_commands = 0;
+ discard_cleanups (old_chain);
+}
+
+/* This is the normal print function for a bpstat. In the future,
+ much of this logic could (should?) be moved to bpstat_stop_status,
+ by having it set different print_it values.
+
+ Current scheme: When we stop, bpstat_print() is called. It loops
+ through the bpstat list of things causing this stop, calling the
+ print_bp_stop_message function on each one. The behavior of the
+ print_bp_stop_message function depends on the print_it field of
+ bpstat. If such field so indicates, call this function here.
+
+ Return values from this routine (ultimately used by bpstat_print()
+ and normal_stop() to decide what to do):
+ PRINT_NOTHING: Means we already printed all we needed to print,
+ don't print anything else.
+ PRINT_SRC_ONLY: Means we printed something, and we do *not* desire
+ that something to be followed by a location.
+ PRINT_SCR_AND_LOC: Means we printed something, and we *do* desire
+ that something to be followed by a location.
+ PRINT_UNKNOWN: Means we printed nothing or we need to do some more
+ analysis. */
+
+static enum print_stop_action
+print_it_typical (bpstat bs)
+{
+ struct cleanup *old_chain;
+ struct ui_stream *stb;
+ stb = ui_out_stream_new (uiout);
+ old_chain = make_cleanup_ui_out_stream_delete (stb);
+ /* bs->breakpoint_at can be NULL if it was a momentary breakpoint
+ which has since been deleted. */
+ if (bs->breakpoint_at == NULL)
+ return PRINT_UNKNOWN;
+
+ switch (bs->breakpoint_at->type)
+ {
+ case bp_breakpoint:
+ case bp_hardware_breakpoint:
+ annotate_breakpoint (bs->breakpoint_at->number);
+ ui_out_text (uiout, "\nBreakpoint ");
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "reason", "breakpoint-hit");
+ ui_out_field_int (uiout, "bkptno", bs->breakpoint_at->number);
+ ui_out_text (uiout, ", ");
+ return PRINT_SRC_AND_LOC;
+ break;
+
+ case bp_shlib_event:
+ /* Did we stop because the user set the stop_on_solib_events
+ variable? (If so, we report this as a generic, "Stopped due
+ to shlib event" message.) */
+ printf_filtered ("Stopped due to shared library event\n");
+ return PRINT_NOTHING;
+ break;
+
+ case bp_thread_event:
+ /* Not sure how we will get here.
+ GDB should not stop for these breakpoints. */
+ printf_filtered ("Thread Event Breakpoint: gdb should not stop!\n");
+ return PRINT_NOTHING;
+ break;
+
+ case bp_overlay_event:
+ /* By analogy with the thread event, GDB should not stop for these. */
+ printf_filtered ("Overlay Event Breakpoint: gdb should not stop!\n");
+ return PRINT_NOTHING;
+ break;
+
+ case bp_catch_load:
+ annotate_catchpoint (bs->breakpoint_at->number);
+ printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
+ printf_filtered ("loaded");
+ printf_filtered (" %s), ", bs->breakpoint_at->triggered_dll_pathname);
+ return PRINT_SRC_AND_LOC;
+ break;
+
+ case bp_catch_unload:
+ annotate_catchpoint (bs->breakpoint_at->number);
+ printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
+ printf_filtered ("unloaded");
+ printf_filtered (" %s), ", bs->breakpoint_at->triggered_dll_pathname);
+ return PRINT_SRC_AND_LOC;
+ break;
+
+ case bp_catch_fork:
+ annotate_catchpoint (bs->breakpoint_at->number);
+ printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
+ printf_filtered ("forked");
+ printf_filtered (" process %d), ",
+ bs->breakpoint_at->forked_inferior_pid);
+ return PRINT_SRC_AND_LOC;
+ break;
+
+ case bp_catch_vfork:
+ annotate_catchpoint (bs->breakpoint_at->number);
+ printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
+ printf_filtered ("vforked");
+ printf_filtered (" process %d), ",
+ bs->breakpoint_at->forked_inferior_pid);
+ return PRINT_SRC_AND_LOC;
+ break;
+
+ case bp_catch_exec:
+ annotate_catchpoint (bs->breakpoint_at->number);
+ printf_filtered ("\nCatchpoint %d (exec'd %s), ",
+ bs->breakpoint_at->number,
+ bs->breakpoint_at->exec_pathname);
+ return PRINT_SRC_AND_LOC;
+ break;
+
+ case bp_catch_catch:
+ if (current_exception_event &&
+ (CURRENT_EXCEPTION_KIND == EX_EVENT_CATCH))
+ {
+ annotate_catchpoint (bs->breakpoint_at->number);
+ printf_filtered ("\nCatchpoint %d (exception caught), ",
+ bs->breakpoint_at->number);
+ printf_filtered ("throw location ");
+ if (CURRENT_EXCEPTION_THROW_PC && CURRENT_EXCEPTION_THROW_LINE)
+ printf_filtered ("%s:%d",
+ CURRENT_EXCEPTION_THROW_FILE,
+ CURRENT_EXCEPTION_THROW_LINE);
+ else
+ printf_filtered ("unknown");
+
+ printf_filtered (", catch location ");
+ if (CURRENT_EXCEPTION_CATCH_PC && CURRENT_EXCEPTION_CATCH_LINE)
+ printf_filtered ("%s:%d",
+ CURRENT_EXCEPTION_CATCH_FILE,
+ CURRENT_EXCEPTION_CATCH_LINE);
+ else
+ printf_filtered ("unknown");
+
+ printf_filtered ("\n");
+ /* don't bother to print location frame info */
+ return PRINT_SRC_ONLY;
+ }
+ else
+ {
+ /* really throw, some other bpstat will handle it */
+ return PRINT_UNKNOWN;
+ }
+ break;
+
+ case bp_catch_throw:
+ if (current_exception_event &&
+ (CURRENT_EXCEPTION_KIND == EX_EVENT_THROW))
+ {
+ annotate_catchpoint (bs->breakpoint_at->number);
+ printf_filtered ("\nCatchpoint %d (exception thrown), ",
+ bs->breakpoint_at->number);
+ printf_filtered ("throw location ");
+ if (CURRENT_EXCEPTION_THROW_PC && CURRENT_EXCEPTION_THROW_LINE)
+ printf_filtered ("%s:%d",
+ CURRENT_EXCEPTION_THROW_FILE,
+ CURRENT_EXCEPTION_THROW_LINE);
+ else
+ printf_filtered ("unknown");
+
+ printf_filtered (", catch location ");
+ if (CURRENT_EXCEPTION_CATCH_PC && CURRENT_EXCEPTION_CATCH_LINE)
+ printf_filtered ("%s:%d",
+ CURRENT_EXCEPTION_CATCH_FILE,
+ CURRENT_EXCEPTION_CATCH_LINE);
+ else
+ printf_filtered ("unknown");
+
+ printf_filtered ("\n");
+ /* don't bother to print location frame info */
+ return PRINT_SRC_ONLY;
+ }
+ else
+ {
+ /* really catch, some other bpstat will handle it */
+ return PRINT_UNKNOWN;
+ }
+ break;
+
+ case bp_watchpoint:
+ case bp_hardware_watchpoint:
+ if (bs->old_val != NULL)
+ {
+ annotate_watchpoint (bs->breakpoint_at->number);
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "reason", "watchpoint-trigger");
+ mention (bs->breakpoint_at);
+ ui_out_tuple_begin (uiout, "value");
+ ui_out_text (uiout, "\nOld value = ");
+ value_print (bs->old_val, stb->stream, 0, Val_pretty_default);
+ ui_out_field_stream (uiout, "old", stb);
+ ui_out_text (uiout, "\nNew value = ");
+ value_print (bs->breakpoint_at->val, stb->stream, 0, Val_pretty_default);
+ ui_out_field_stream (uiout, "new", stb);
+ ui_out_tuple_end (uiout);
+ ui_out_text (uiout, "\n");
+ value_free (bs->old_val);
+ bs->old_val = NULL;
+ }
+ /* More than one watchpoint may have been triggered. */
+ return PRINT_UNKNOWN;
+ break;
+
+ case bp_read_watchpoint:
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "reason", "read-watchpoint-trigger");
+ mention (bs->breakpoint_at);
+ ui_out_tuple_begin (uiout, "value");
+ ui_out_text (uiout, "\nValue = ");
+ value_print (bs->breakpoint_at->val, stb->stream, 0, Val_pretty_default);
+ ui_out_field_stream (uiout, "value", stb);
+ ui_out_tuple_end (uiout);
+ ui_out_text (uiout, "\n");
+ return PRINT_UNKNOWN;
+ break;
+
+ case bp_access_watchpoint:
+ if (bs->old_val != NULL)
+ {
+ annotate_watchpoint (bs->breakpoint_at->number);
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "reason", "access-watchpoint-trigger");
+ mention (bs->breakpoint_at);
+ ui_out_tuple_begin (uiout, "value");
+ ui_out_text (uiout, "\nOld value = ");
+ value_print (bs->old_val, stb->stream, 0, Val_pretty_default);
+ ui_out_field_stream (uiout, "old", stb);
+ value_free (bs->old_val);
+ bs->old_val = NULL;
+ ui_out_text (uiout, "\nNew value = ");
+ }
+ else
+ {
+ mention (bs->breakpoint_at);
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "reason", "access-watchpoint-trigger");
+ ui_out_tuple_begin (uiout, "value");
+ ui_out_text (uiout, "\nValue = ");
+ }
+ value_print (bs->breakpoint_at->val, stb->stream, 0,Val_pretty_default);
+ ui_out_field_stream (uiout, "new", stb);
+ ui_out_tuple_end (uiout);
+ ui_out_text (uiout, "\n");
+ return PRINT_UNKNOWN;
+ break;
+
+ /* Fall through, we don't deal with these types of breakpoints
+ here. */
+
+ case bp_finish:
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "reason", "function-finished");
+ return PRINT_UNKNOWN;
+ break;
+
+ case bp_until:
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "reason", "location-reached");
+ return PRINT_UNKNOWN;
+ break;
+
+ case bp_none:
+ case bp_longjmp:
+ case bp_longjmp_resume:
+ case bp_step_resume:
+ case bp_through_sigtramp:
+ case bp_watchpoint_scope:
+ case bp_call_dummy:
+ default:
+ return PRINT_UNKNOWN;
+ }
+}
+
+/* Generic routine for printing messages indicating why we
+ stopped. The behavior of this function depends on the value
+ 'print_it' in the bpstat structure. Under some circumstances we
+ may decide not to print anything here and delegate the task to
+ normal_stop(). */
+
+static enum print_stop_action
+print_bp_stop_message (bpstat bs)
+{
+ switch (bs->print_it)
+ {
+ case print_it_noop:
+ /* Nothing should be printed for this bpstat entry. */
+ return PRINT_UNKNOWN;
+ break;
+
+ case print_it_done:
+ /* We still want to print the frame, but we already printed the
+ relevant messages. */
+ return PRINT_SRC_AND_LOC;
+ break;
+
+ case print_it_normal:
+ /* Normal case, we handle everything in print_it_typical. */
+ return print_it_typical (bs);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "print_bp_stop_message: unrecognized enum value");
+ break;
+ }
+}
+
+/* Print a message indicating what happened. This is called from
+ normal_stop(). The input to this routine is the head of the bpstat
+ list - a list of the eventpoints that caused this stop. This
+ routine calls the generic print routine for printing a message
+ about reasons for stopping. This will print (for example) the
+ "Breakpoint n," part of the output. The return value of this
+ routine is one of:
+
+ PRINT_UNKNOWN: Means we printed nothing
+ PRINT_SRC_AND_LOC: Means we printed something, and expect subsequent
+ code to print the location. An example is
+ "Breakpoint 1, " which should be followed by
+ the location.
+ PRINT_SRC_ONLY: Means we printed something, but there is no need
+ to also print the location part of the message.
+ An example is the catch/throw messages, which
+ don't require a location appended to the end.
+ PRINT_NOTHING: We have done some printing and we don't need any
+ further info to be printed.*/
+
+enum print_stop_action
+bpstat_print (bpstat bs)
+{
+ int val;
+
+ /* Maybe another breakpoint in the chain caused us to stop.
+ (Currently all watchpoints go on the bpstat whether hit or not.
+ That probably could (should) be changed, provided care is taken
+ with respect to bpstat_explains_signal). */
+ for (; bs; bs = bs->next)
+ {
+ val = print_bp_stop_message (bs);
+ if (val == PRINT_SRC_ONLY
+ || val == PRINT_SRC_AND_LOC
+ || val == PRINT_NOTHING)
+ return val;
+ }
+
+ /* We reached the end of the chain, or we got a null BS to start
+ with and nothing was printed. */
+ return PRINT_UNKNOWN;
+}
+
+/* Evaluate the expression EXP and return 1 if value is zero.
+ This is used inside a catch_errors to evaluate the breakpoint condition.
+ The argument is a "struct expression *" that has been cast to char * to
+ make it pass through catch_errors. */
+
+static int
+breakpoint_cond_eval (PTR exp)
+{
+ struct value *mark = value_mark ();
+ int i = !value_true (evaluate_expression ((struct expression *) exp));
+ value_free_to_mark (mark);
+ return i;
+}
+
+/* Allocate a new bpstat and chain it to the current one. */
+
+static bpstat
+bpstat_alloc (struct breakpoint *b, bpstat cbs /* Current "bs" value */ )
+{
+ bpstat bs;
+
+ bs = (bpstat) xmalloc (sizeof (*bs));
+ cbs->next = bs;
+ bs->breakpoint_at = b;
+ /* If the condition is false, etc., don't do the commands. */
+ bs->commands = NULL;
+ bs->old_val = NULL;
+ bs->print_it = print_it_normal;
+ return bs;
+}
+
+/* Possible return values for watchpoint_check (this can't be an enum
+ because of check_errors). */
+/* The watchpoint has been deleted. */
+#define WP_DELETED 1
+/* The value has changed. */
+#define WP_VALUE_CHANGED 2
+/* The value has not changed. */
+#define WP_VALUE_NOT_CHANGED 3
+
+#define BP_TEMPFLAG 1
+#define BP_HARDWAREFLAG 2
+
+/* Check watchpoint condition. */
+
+static int
+watchpoint_check (PTR p)
+{
+ bpstat bs = (bpstat) p;
+ struct breakpoint *b;
+ struct frame_info *fr;
+ int within_current_scope;
+
+ b = bs->breakpoint_at;
+
+ if (b->exp_valid_block == NULL)
+ within_current_scope = 1;
+ else
+ {
+ /* There is no current frame at this moment. If we're going to have
+ any chance of handling watchpoints on local variables, we'll need
+ the frame chain (so we can determine if we're in scope). */
+ reinit_frame_cache ();
+ fr = find_frame_addr_in_frame_chain (b->watchpoint_frame);
+ within_current_scope = (fr != NULL);
+ /* in_function_epilogue_p() returns a non-zero value if we're still
+ in the function but the stack frame has already been invalidated.
+ Since we can't rely on the values of local variables after the
+ stack has been destroyed, we are treating the watchpoint in that
+ state as `not changed' without further checking. */
+ if (within_current_scope && fr == get_current_frame ()
+ && gdbarch_in_function_epilogue_p (current_gdbarch, read_pc ()))
+ return WP_VALUE_NOT_CHANGED;
+ if (within_current_scope)
+ /* If we end up stopping, the current frame will get selected
+ in normal_stop. So this call to select_frame won't affect
+ the user. */
+ select_frame (fr);
+ }
+
+ if (within_current_scope)
+ {
+ /* We use value_{,free_to_}mark because it could be a
+ *long* time before we return to the command level and
+ call free_all_values. We can't call free_all_values because
+ we might be in the middle of evaluating a function call. */
+
+ struct value *mark = value_mark ();
+ struct value *new_val = evaluate_expression (bs->breakpoint_at->exp);
+ if (!value_equal (b->val, new_val))
+ {
+ release_value (new_val);
+ value_free_to_mark (mark);
+ bs->old_val = b->val;
+ b->val = new_val;
+ /* We will stop here */
+ return WP_VALUE_CHANGED;
+ }
+ else
+ {
+ /* Nothing changed, don't do anything. */
+ value_free_to_mark (mark);
+ /* We won't stop here */
+ return WP_VALUE_NOT_CHANGED;
+ }
+ }
+ else
+ {
+ /* This seems like the only logical thing to do because
+ if we temporarily ignored the watchpoint, then when
+ we reenter the block in which it is valid it contains
+ garbage (in the case of a function, it may have two
+ garbage values, one before and one after the prologue).
+ So we can't even detect the first assignment to it and
+ watch after that (since the garbage may or may not equal
+ the first value assigned). */
+ /* We print all the stop information in print_it_typical(), but
+ in this case, by the time we call print_it_typical() this bp
+ will be deleted already. So we have no choice but print the
+ information here. */
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "reason", "watchpoint-scope");
+ ui_out_text (uiout, "\nWatchpoint ");
+ ui_out_field_int (uiout, "wpnum", bs->breakpoint_at->number);
+ ui_out_text (uiout, " deleted because the program has left the block in\n\
+which its expression is valid.\n");
+
+ if (b->related_breakpoint)
+ b->related_breakpoint->disposition = disp_del_at_next_stop;
+ b->disposition = disp_del_at_next_stop;
+
+ return WP_DELETED;
+ }
+}
+
+/* Get a bpstat associated with having just stopped at address *PC
+ and frame address CORE_ADDRESS. Update *PC to point at the
+ breakpoint (if we hit a breakpoint). NOT_A_BREAKPOINT is nonzero
+ if this is known to not be a real breakpoint (it could still be a
+ watchpoint, though). */
+
+/* Determine whether we stopped at a breakpoint, etc, or whether we
+ don't understand this stop. Result is a chain of bpstat's such that:
+
+ if we don't understand the stop, the result is a null pointer.
+
+ if we understand why we stopped, the result is not null.
+
+ Each element of the chain refers to a particular breakpoint or
+ watchpoint at which we have stopped. (We may have stopped for
+ several reasons concurrently.)
+
+ Each element of the chain has valid next, breakpoint_at,
+ commands, FIXME??? fields. */
+
+bpstat
+bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint)
+{
+ register struct breakpoint *b, *temp;
+ CORE_ADDR bp_addr;
+ /* True if we've hit a breakpoint (as opposed to a watchpoint). */
+ int real_breakpoint = 0;
+ /* Root of the chain of bpstat's */
+ struct bpstats root_bs[1];
+ /* Pointer to the last thing in the chain currently. */
+ bpstat bs = root_bs;
+ static char message1[] =
+ "Error evaluating expression for watchpoint %d\n";
+ char message[sizeof (message1) + 30 /* slop */ ];
+
+ /* Get the address where the breakpoint would have been.
+ The "not_a_breakpoint" argument is meant to distinguish
+ between a breakpoint trap event and a trace/singlestep
+ trap event. For a trace/singlestep trap event, we would
+ not want to subtract DECR_PC_AFTER_BREAK from the PC. */
+
+ bp_addr = *pc - (not_a_breakpoint && !SOFTWARE_SINGLE_STEP_P () ?
+ 0 : DECR_PC_AFTER_BREAK);
+
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ {
+ if (b->enable_state == bp_disabled
+ || b->enable_state == bp_shlib_disabled
+ || b->enable_state == bp_call_disabled)
+ continue;
+
+ if (b->type != bp_watchpoint
+ && b->type != bp_hardware_watchpoint
+ && b->type != bp_read_watchpoint
+ && b->type != bp_access_watchpoint
+ && b->type != bp_hardware_breakpoint
+ && b->type != bp_catch_fork
+ && b->type != bp_catch_vfork
+ && b->type != bp_catch_exec
+ && b->type != bp_catch_catch
+ && b->type != bp_catch_throw) /* a non-watchpoint bp */
+ {
+ if (b->address != bp_addr) /* address doesn't match */
+ continue;
+ if (overlay_debugging /* unmapped overlay section */
+ && section_is_overlay (b->section)
+ && !section_is_mapped (b->section))
+ continue;
+ }
+
+ if (b->type == bp_hardware_breakpoint)
+ {
+ if (b->address != (*pc - DECR_PC_AFTER_HW_BREAK))
+ continue;
+ if (overlay_debugging /* unmapped overlay section */
+ && section_is_overlay (b->section)
+ && !section_is_mapped (b->section))
+ continue;
+ }
+
+ /* Is this a catchpoint of a load or unload? If so, did we
+ get a load or unload of the specified library? If not,
+ ignore it. */
+ if ((b->type == bp_catch_load)
+#if defined(SOLIB_HAVE_LOAD_EVENT)
+ && (!SOLIB_HAVE_LOAD_EVENT (PIDGET (inferior_ptid))
+ || ((b->dll_pathname != NULL)
+ && (strcmp (b->dll_pathname,
+ SOLIB_LOADED_LIBRARY_PATHNAME (
+ PIDGET (inferior_ptid)))
+ != 0)))
+#endif
+ )
+ continue;
+
+ if ((b->type == bp_catch_unload)
+#if defined(SOLIB_HAVE_UNLOAD_EVENT)
+ && (!SOLIB_HAVE_UNLOAD_EVENT (PIDGET (inferior_ptid))
+ || ((b->dll_pathname != NULL)
+ && (strcmp (b->dll_pathname,
+ SOLIB_UNLOADED_LIBRARY_PATHNAME (
+ PIDGET (inferior_ptid)))
+ != 0)))
+#endif
+ )
+ continue;
+
+ if ((b->type == bp_catch_fork)
+ && !target_has_forked (PIDGET (inferior_ptid),
+ &b->forked_inferior_pid))
+ continue;
+
+ if ((b->type == bp_catch_vfork)
+ && !target_has_vforked (PIDGET (inferior_ptid),
+ &b->forked_inferior_pid))
+ continue;
+
+ if ((b->type == bp_catch_exec)
+ && !target_has_execd (PIDGET (inferior_ptid), &b->exec_pathname))
+ continue;
+
+ if (ep_is_exception_catchpoint (b) &&
+ !(current_exception_event = target_get_current_exception_event ()))
+ continue;
+
+ /* Come here if it's a watchpoint, or if the break address matches */
+
+ bs = bpstat_alloc (b, bs); /* Alloc a bpstat to explain stop */
+
+ /* Watchpoints may change this, if not found to have triggered. */
+ bs->stop = 1;
+ bs->print = 1;
+
+ sprintf (message, message1, b->number);
+ if (b->type == bp_watchpoint ||
+ b->type == bp_hardware_watchpoint)
+ {
+ switch (catch_errors (watchpoint_check, bs, message,
+ RETURN_MASK_ALL))
+ {
+ case WP_DELETED:
+ /* We've already printed what needs to be printed. */
+ /* Actually this is superfluous, because by the time we
+ call print_it_typical() the wp will be already deleted,
+ and the function will return immediately. */
+ bs->print_it = print_it_done;
+ /* Stop. */
+ break;
+ case WP_VALUE_CHANGED:
+ /* Stop. */
+ ++(b->hit_count);
+ break;
+ case WP_VALUE_NOT_CHANGED:
+ /* Don't stop. */
+ bs->print_it = print_it_noop;
+ bs->stop = 0;
+ continue;
+ default:
+ /* Can't happen. */
+ /* FALLTHROUGH */
+ case 0:
+ /* Error from catch_errors. */
+ printf_filtered ("Watchpoint %d deleted.\n", b->number);
+ if (b->related_breakpoint)
+ b->related_breakpoint->disposition = disp_del_at_next_stop;
+ b->disposition = disp_del_at_next_stop;
+ /* We've already printed what needs to be printed. */
+ bs->print_it = print_it_done;
+
+ /* Stop. */
+ break;
+ }
+ }
+ else if (b->type == bp_read_watchpoint ||
+ b->type == bp_access_watchpoint)
+ {
+ CORE_ADDR addr;
+ struct value *v;
+ int found = 0;
+
+ addr = target_stopped_data_address ();
+ if (addr == 0)
+ continue;
+ for (v = b->val_chain; v; v = v->next)
+ {
+ if (VALUE_LVAL (v) == lval_memory
+ && ! VALUE_LAZY (v))
+ {
+ struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+ if (v == b->val_chain
+ || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+ && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+ {
+ CORE_ADDR vaddr;
+
+ vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+ /* Exact match not required. Within range is
+ sufficient. */
+ if (addr >= vaddr &&
+ addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v)))
+ found = 1;
+ }
+ }
+ }
+ if (found)
+ switch (catch_errors (watchpoint_check, bs, message,
+ RETURN_MASK_ALL))
+ {
+ case WP_DELETED:
+ /* We've already printed what needs to be printed. */
+ bs->print_it = print_it_done;
+ /* Stop. */
+ break;
+ case WP_VALUE_CHANGED:
+ if (b->type == bp_read_watchpoint)
+ {
+ /* Don't stop: read watchpoints shouldn't fire if
+ the value has changed. This is for targets which
+ cannot set read-only watchpoints. */
+ bs->print_it = print_it_noop;
+ bs->stop = 0;
+ continue;
+ }
+ ++(b->hit_count);
+ break;
+ case WP_VALUE_NOT_CHANGED:
+ /* Stop. */
+ ++(b->hit_count);
+ break;
+ default:
+ /* Can't happen. */
+ case 0:
+ /* Error from catch_errors. */
+ printf_filtered ("Watchpoint %d deleted.\n", b->number);
+ if (b->related_breakpoint)
+ b->related_breakpoint->disposition = disp_del_at_next_stop;
+ b->disposition = disp_del_at_next_stop;
+ /* We've already printed what needs to be printed. */
+ bs->print_it = print_it_done;
+ break;
+ }
+ else /* found == 0 */
+ {
+ /* This is a case where some watchpoint(s) triggered,
+ but not at the address of this watchpoint (FOUND
+ was left zero). So don't print anything for this
+ watchpoint. */
+ bs->print_it = print_it_noop;
+ bs->stop = 0;
+ continue;
+ }
+ }
+ else
+ {
+ /* By definition, an encountered breakpoint is a triggered
+ breakpoint. */
+ ++(b->hit_count);
+
+ real_breakpoint = 1;
+ }
+
+ if (b->frame &&
+ b->frame != (get_current_frame ())->frame)
+ bs->stop = 0;
+ else
+ {
+ int value_is_zero = 0;
+
+ if (b->cond)
+ {
+ /* Need to select the frame, with all that implies
+ so that the conditions will have the right context. */
+ select_frame (get_current_frame ());
+ value_is_zero
+ = catch_errors (breakpoint_cond_eval, (b->cond),
+ "Error in testing breakpoint condition:\n",
+ RETURN_MASK_ALL);
+ /* FIXME-someday, should give breakpoint # */
+ free_all_values ();
+ }
+ if (b->cond && value_is_zero)
+ {
+ bs->stop = 0;
+ /* Don't consider this a hit. */
+ --(b->hit_count);
+ }
+ else if (b->ignore_count > 0)
+ {
+ b->ignore_count--;
+ annotate_ignore_count_change ();
+ bs->stop = 0;
+ }
+ else
+ {
+ /* We will stop here */
+ if (b->disposition == disp_disable)
+ b->enable_state = bp_disabled;
+ bs->commands = b->commands;
+ if (b->silent)
+ bs->print = 0;
+ if (bs->commands &&
+ (STREQ ("silent", bs->commands->line) ||
+ (xdb_commands && STREQ ("Q", bs->commands->line))))
+ {
+ bs->commands = bs->commands->next;
+ bs->print = 0;
+ }
+ }
+ }
+ /* Print nothing for this entry if we dont stop or if we dont print. */
+ if (bs->stop == 0 || bs->print == 0)
+ bs->print_it = print_it_noop;
+ }
+
+ bs->next = NULL; /* Terminate the chain */
+ bs = root_bs->next; /* Re-grab the head of the chain */
+
+ if (real_breakpoint && bs)
+ {
+ if (bs->breakpoint_at->type == bp_hardware_breakpoint)
+ {
+ if (DECR_PC_AFTER_HW_BREAK != 0)
+ {
+ *pc = *pc - DECR_PC_AFTER_HW_BREAK;
+ write_pc (*pc);
+ }
+ }
+ else
+ {
+ if (DECR_PC_AFTER_BREAK != 0 || must_shift_inst_regs)
+ {
+ *pc = bp_addr;
+#if defined (SHIFT_INST_REGS)
+ SHIFT_INST_REGS ();
+#else /* No SHIFT_INST_REGS. */
+ write_pc (bp_addr);
+#endif /* No SHIFT_INST_REGS. */
+ }
+ }
+ }
+
+ /* The value of a hardware watchpoint hasn't changed, but the
+ intermediate memory locations we are watching may have. */
+ if (bs && !bs->stop &&
+ (bs->breakpoint_at->type == bp_hardware_watchpoint ||
+ bs->breakpoint_at->type == bp_read_watchpoint ||
+ bs->breakpoint_at->type == bp_access_watchpoint))
+ {
+ remove_breakpoints ();
+ insert_breakpoints ();
+ }
+ return bs;
+}
+
+/* Tell what to do about this bpstat. */
+struct bpstat_what
+bpstat_what (bpstat bs)
+{
+ /* Classify each bpstat as one of the following. */
+ enum class
+ {
+ /* This bpstat element has no effect on the main_action. */
+ no_effect = 0,
+
+ /* There was a watchpoint, stop but don't print. */
+ wp_silent,
+
+ /* There was a watchpoint, stop and print. */
+ wp_noisy,
+
+ /* There was a breakpoint but we're not stopping. */
+ bp_nostop,
+
+ /* There was a breakpoint, stop but don't print. */
+ bp_silent,
+
+ /* There was a breakpoint, stop and print. */
+ bp_noisy,
+
+ /* We hit the longjmp breakpoint. */
+ long_jump,
+
+ /* We hit the longjmp_resume breakpoint. */
+ long_resume,
+
+ /* We hit the step_resume breakpoint. */
+ step_resume,
+
+ /* We hit the through_sigtramp breakpoint. */
+ through_sig,
+
+ /* We hit the shared library event breakpoint. */
+ shlib_event,
+
+ /* We caught a shared library event. */
+ catch_shlib_event,
+
+ /* This is just used to count how many enums there are. */
+ class_last
+ };
+
+ /* Here is the table which drives this routine. So that we can
+ format it pretty, we define some abbreviations for the
+ enum bpstat_what codes. */
+#define kc BPSTAT_WHAT_KEEP_CHECKING
+#define ss BPSTAT_WHAT_STOP_SILENT
+#define sn BPSTAT_WHAT_STOP_NOISY
+#define sgl BPSTAT_WHAT_SINGLE
+#define slr BPSTAT_WHAT_SET_LONGJMP_RESUME
+#define clr BPSTAT_WHAT_CLEAR_LONGJMP_RESUME
+#define clrs BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE
+#define sr BPSTAT_WHAT_STEP_RESUME
+#define ts BPSTAT_WHAT_THROUGH_SIGTRAMP
+#define shl BPSTAT_WHAT_CHECK_SHLIBS
+#define shlr BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK
+
+/* "Can't happen." Might want to print an error message.
+ abort() is not out of the question, but chances are GDB is just
+ a bit confused, not unusable. */
+#define err BPSTAT_WHAT_STOP_NOISY
+
+ /* Given an old action and a class, come up with a new action. */
+ /* One interesting property of this table is that wp_silent is the same
+ as bp_silent and wp_noisy is the same as bp_noisy. That is because
+ after stopping, the check for whether to step over a breakpoint
+ (BPSTAT_WHAT_SINGLE type stuff) is handled in proceed() without
+ reference to how we stopped. We retain separate wp_silent and
+ bp_silent codes in case we want to change that someday.
+
+ Another possibly interesting property of this table is that
+ there's a partial ordering, priority-like, of the actions. Once
+ you've decided that some action is appropriate, you'll never go
+ back and decide something of a lower priority is better. The
+ ordering is:
+
+ kc < clr sgl shl shlr slr sn sr ss ts
+ sgl < clrs shl shlr slr sn sr ss ts
+ slr < err shl shlr sn sr ss ts
+ clr < clrs err shl shlr sn sr ss ts
+ clrs < err shl shlr sn sr ss ts
+ ss < shl shlr sn sr ts
+ sn < shl shlr sr ts
+ sr < shl shlr ts
+ shl < shlr
+ ts <
+ shlr <
+
+ What I think this means is that we don't need a damned table
+ here. If you just put the rows and columns in the right order,
+ it'd look awfully regular. We could simply walk the bpstat list
+ and choose the highest priority action we find, with a little
+ logic to handle the 'err' cases, and the CLEAR_LONGJMP_RESUME/
+ CLEAR_LONGJMP_RESUME_SINGLE distinction (which breakpoint.h says
+ is messy anyway). */
+
+ /* step_resume entries: a step resume breakpoint overrides another
+ breakpoint of signal handling (see comment in wait_for_inferior
+ at first PC_IN_SIGTRAMP where we set the step_resume breakpoint). */
+ /* We handle the through_sigtramp_breakpoint the same way; having both
+ one of those and a step_resume_breakpoint is probably very rare (?). */
+
+ static const enum bpstat_what_main_action
+ table[(int) class_last][(int) BPSTAT_WHAT_LAST] =
+ {
+ /* old action */
+ /* kc ss sn sgl slr clr clrs sr ts shl shlr
+ */
+/*no_effect */
+ {kc, ss, sn, sgl, slr, clr, clrs, sr, ts, shl, shlr},
+/*wp_silent */
+ {ss, ss, sn, ss, ss, ss, ss, sr, ts, shl, shlr},
+/*wp_noisy */
+ {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl, shlr},
+/*bp_nostop */
+ {sgl, ss, sn, sgl, slr, clrs, clrs, sr, ts, shl, shlr},
+/*bp_silent */
+ {ss, ss, sn, ss, ss, ss, ss, sr, ts, shl, shlr},
+/*bp_noisy */
+ {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl, shlr},
+/*long_jump */
+ {slr, ss, sn, slr, slr, err, err, sr, ts, shl, shlr},
+/*long_resume */
+ {clr, ss, sn, clrs, err, err, err, sr, ts, shl, shlr},
+/*step_resume */
+ {sr, sr, sr, sr, sr, sr, sr, sr, ts, shl, shlr},
+/*through_sig */
+ {ts, ts, ts, ts, ts, ts, ts, ts, ts, shl, shlr},
+/*shlib */
+ {shl, shl, shl, shl, shl, shl, shl, shl, ts, shl, shlr},
+/*catch_shlib */
+ {shlr, shlr, shlr, shlr, shlr, shlr, shlr, shlr, ts, shlr, shlr}
+ };
+
+#undef kc
+#undef ss
+#undef sn
+#undef sgl
+#undef slr
+#undef clr
+#undef clrs
+#undef err
+#undef sr
+#undef ts
+#undef shl
+#undef shlr
+ enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING;
+ struct bpstat_what retval;
+
+ retval.call_dummy = 0;
+ for (; bs != NULL; bs = bs->next)
+ {
+ enum class bs_class = no_effect;
+ if (bs->breakpoint_at == NULL)
+ /* I suspect this can happen if it was a momentary breakpoint
+ which has since been deleted. */
+ continue;
+ switch (bs->breakpoint_at->type)
+ {
+ case bp_none:
+ continue;
+
+ case bp_breakpoint:
+ case bp_hardware_breakpoint:
+ case bp_until:
+ case bp_finish:
+ if (bs->stop)
+ {
+ if (bs->print)
+ bs_class = bp_noisy;
+ else
+ bs_class = bp_silent;
+ }
+ else
+ bs_class = bp_nostop;
+ break;
+ case bp_watchpoint:
+ case bp_hardware_watchpoint:
+ case bp_read_watchpoint:
+ case bp_access_watchpoint:
+ if (bs->stop)
+ {
+ if (bs->print)
+ bs_class = wp_noisy;
+ else
+ bs_class = wp_silent;
+ }
+ else
+ /* There was a watchpoint, but we're not stopping.
+ This requires no further action. */
+ bs_class = no_effect;
+ break;
+ case bp_longjmp:
+ bs_class = long_jump;
+ break;
+ case bp_longjmp_resume:
+ bs_class = long_resume;
+ break;
+ case bp_step_resume:
+ if (bs->stop)
+ {
+ bs_class = step_resume;
+ }
+ else
+ /* It is for the wrong frame. */
+ bs_class = bp_nostop;
+ break;
+ case bp_through_sigtramp:
+ bs_class = through_sig;
+ break;
+ case bp_watchpoint_scope:
+ bs_class = bp_nostop;
+ break;
+ case bp_shlib_event:
+ bs_class = shlib_event;
+ break;
+ case bp_thread_event:
+ case bp_overlay_event:
+ bs_class = bp_nostop;
+ break;
+ case bp_catch_load:
+ case bp_catch_unload:
+ /* Only if this catchpoint triggered should we cause the
+ step-out-of-dld behaviour. Otherwise, we ignore this
+ catchpoint. */
+ if (bs->stop)
+ bs_class = catch_shlib_event;
+ else
+ bs_class = no_effect;
+ break;
+ case bp_catch_fork:
+ case bp_catch_vfork:
+ case bp_catch_exec:
+ if (bs->stop)
+ {
+ if (bs->print)
+ bs_class = bp_noisy;
+ else
+ bs_class = bp_silent;
+ }
+ else
+ /* There was a catchpoint, but we're not stopping.
+ This requires no further action. */
+ bs_class = no_effect;
+ break;
+ case bp_catch_catch:
+ if (!bs->stop || CURRENT_EXCEPTION_KIND != EX_EVENT_CATCH)
+ bs_class = bp_nostop;
+ else if (bs->stop)
+ bs_class = bs->print ? bp_noisy : bp_silent;
+ break;
+ case bp_catch_throw:
+ if (!bs->stop || CURRENT_EXCEPTION_KIND != EX_EVENT_THROW)
+ bs_class = bp_nostop;
+ else if (bs->stop)
+ bs_class = bs->print ? bp_noisy : bp_silent;
+ break;
+ case bp_call_dummy:
+ /* Make sure the action is stop (silent or noisy),
+ so infrun.c pops the dummy frame. */
+ bs_class = bp_silent;
+ retval.call_dummy = 1;
+ break;
+ }
+ current_action = table[(int) bs_class][(int) current_action];
+ }
+ retval.main_action = current_action;
+ return retval;
+}
+
+/* Nonzero if we should step constantly (e.g. watchpoints on machines
+ without hardware support). This isn't related to a specific bpstat,
+ just to things like whether watchpoints are set. */
+
+int
+bpstat_should_step (void)
+{
+ struct breakpoint *b;
+ ALL_BREAKPOINTS (b)
+ if (b->enable_state == bp_enabled && b->type == bp_watchpoint)
+ return 1;
+ return 0;
+}
+
+/* Nonzero if there are enabled hardware watchpoints. */
+int
+bpstat_have_active_hw_watchpoints (void)
+{
+ struct breakpoint *b;
+ ALL_BREAKPOINTS (b)
+ if ((b->enable_state == bp_enabled) &&
+ (b->inserted) &&
+ ((b->type == bp_hardware_watchpoint) ||
+ (b->type == bp_read_watchpoint) ||
+ (b->type == bp_access_watchpoint)))
+ return 1;
+ return 0;
+}
+
+
+/* Given a bpstat that records zero or more triggered eventpoints, this
+ function returns another bpstat which contains only the catchpoints
+ on that first list, if any. */
+void
+bpstat_get_triggered_catchpoints (bpstat ep_list, bpstat *cp_list)
+{
+ struct bpstats root_bs[1];
+ bpstat bs = root_bs;
+ struct breakpoint *ep;
+ char *dll_pathname;
+
+ bpstat_clear (cp_list);
+ root_bs->next = NULL;
+
+ for (; ep_list != NULL; ep_list = ep_list->next)
+ {
+ /* Is this eventpoint a catchpoint? If not, ignore it. */
+ ep = ep_list->breakpoint_at;
+ if (ep == NULL)
+ break;
+ if ((ep->type != bp_catch_load) &&
+ (ep->type != bp_catch_unload) &&
+ (ep->type != bp_catch_catch) &&
+ (ep->type != bp_catch_throw))
+ /* pai: (temp) ADD fork/vfork here!! */
+ continue;
+
+ /* Yes; add it to the list. */
+ bs = bpstat_alloc (ep, bs);
+ *bs = *ep_list;
+ bs->next = NULL;
+ bs = root_bs->next;
+
+#if defined(SOLIB_ADD)
+ /* Also, for each triggered catchpoint, tag it with the name of
+ the library that caused this trigger. (We copy the name now,
+ because it's only guaranteed to be available NOW, when the
+ catchpoint triggers. Clients who may wish to know the name
+ later must get it from the catchpoint itself.) */
+ if (ep->triggered_dll_pathname != NULL)
+ xfree (ep->triggered_dll_pathname);
+ if (ep->type == bp_catch_load)
+ dll_pathname = SOLIB_LOADED_LIBRARY_PATHNAME (
+ PIDGET (inferior_ptid));
+ else
+ dll_pathname = SOLIB_UNLOADED_LIBRARY_PATHNAME (
+ PIDGET (inferior_ptid));
+#else
+ dll_pathname = NULL;
+#endif
+ if (dll_pathname)
+ {
+ ep->triggered_dll_pathname = (char *)
+ xmalloc (strlen (dll_pathname) + 1);
+ strcpy (ep->triggered_dll_pathname, dll_pathname);
+ }
+ else
+ ep->triggered_dll_pathname = NULL;
+ }
+
+ *cp_list = bs;
+}
+
+/* Print B to gdb_stdout. */
+static void
+print_one_breakpoint (struct breakpoint *b,
+ CORE_ADDR *last_addr)
+{
+ register struct command_line *l;
+ register struct symbol *sym;
+ struct ep_type_description
+ {
+ enum bptype type;
+ char *description;
+ };
+ static struct ep_type_description bptypes[] =
+ {
+ {bp_none, "?deleted?"},
+ {bp_breakpoint, "breakpoint"},
+ {bp_hardware_breakpoint, "hw breakpoint"},
+ {bp_until, "until"},
+ {bp_finish, "finish"},
+ {bp_watchpoint, "watchpoint"},
+ {bp_hardware_watchpoint, "hw watchpoint"},
+ {bp_read_watchpoint, "read watchpoint"},
+ {bp_access_watchpoint, "acc watchpoint"},
+ {bp_longjmp, "longjmp"},
+ {bp_longjmp_resume, "longjmp resume"},
+ {bp_step_resume, "step resume"},
+ {bp_through_sigtramp, "sigtramp"},
+ {bp_watchpoint_scope, "watchpoint scope"},
+ {bp_call_dummy, "call dummy"},
+ {bp_shlib_event, "shlib events"},
+ {bp_thread_event, "thread events"},
+ {bp_overlay_event, "overlay events"},
+ {bp_catch_load, "catch load"},
+ {bp_catch_unload, "catch unload"},
+ {bp_catch_fork, "catch fork"},
+ {bp_catch_vfork, "catch vfork"},
+ {bp_catch_exec, "catch exec"},
+ {bp_catch_catch, "catch catch"},
+ {bp_catch_throw, "catch throw"}
+ };
+
+ static char *bpdisps[] =
+ {"del", "dstp", "dis", "keep"};
+ static char bpenables[] = "nynny";
+ char wrap_indent[80];
+ struct ui_stream *stb = ui_out_stream_new (uiout);
+ struct cleanup *old_chain = make_cleanup_ui_out_stream_delete (stb);
+
+ annotate_record ();
+ ui_out_tuple_begin (uiout, "bkpt");
+
+ /* 1 */
+ annotate_field (0);
+ ui_out_field_int (uiout, "number", b->number);
+
+ /* 2 */
+ annotate_field (1);
+ if (((int) b->type > (sizeof (bptypes) / sizeof (bptypes[0])))
+ || ((int) b->type != bptypes[(int) b->type].type))
+ internal_error (__FILE__, __LINE__,
+ "bptypes table does not describe type #%d.",
+ (int) b->type);
+ ui_out_field_string (uiout, "type", bptypes[(int) b->type].description);
+
+ /* 3 */
+ annotate_field (2);
+ ui_out_field_string (uiout, "disp", bpdisps[(int) b->disposition]);
+
+ /* 4 */
+ annotate_field (3);
+ ui_out_field_fmt (uiout, "enabled", "%c", bpenables[(int) b->enable_state]);
+ ui_out_spaces (uiout, 2);
+
+ /* 5 and 6 */
+ strcpy (wrap_indent, " ");
+ if (addressprint)
+ {
+ if (TARGET_ADDR_BIT <= 32)
+ strcat (wrap_indent, " ");
+ else
+ strcat (wrap_indent, " ");
+ }
+ switch (b->type)
+ {
+ case bp_none:
+ internal_error (__FILE__, __LINE__,
+ "print_one_breakpoint: bp_none encountered\n");
+ break;
+
+ case bp_watchpoint:
+ case bp_hardware_watchpoint:
+ case bp_read_watchpoint:
+ case bp_access_watchpoint:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+ if (addressprint)
+ ui_out_field_skip (uiout, "addr");
+ annotate_field (5);
+ print_expression (b->exp, stb->stream);
+ ui_out_field_stream (uiout, "what", stb);
+ break;
+
+ case bp_catch_load:
+ case bp_catch_unload:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+ if (addressprint)
+ ui_out_field_skip (uiout, "addr");
+ annotate_field (5);
+ if (b->dll_pathname == NULL)
+ {
+ ui_out_field_string (uiout, "what", "<any library>");
+ ui_out_spaces (uiout, 1);
+ }
+ else
+ {
+ ui_out_text (uiout, "library \"");
+ ui_out_field_string (uiout, "what", b->dll_pathname);
+ ui_out_text (uiout, "\" ");
+ }
+ break;
+
+ case bp_catch_fork:
+ case bp_catch_vfork:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+ if (addressprint)
+ ui_out_field_skip (uiout, "addr");
+ annotate_field (5);
+ if (b->forked_inferior_pid != 0)
+ {
+ ui_out_text (uiout, "process ");
+ ui_out_field_int (uiout, "what", b->forked_inferior_pid);
+ ui_out_spaces (uiout, 1);
+ }
+
+ case bp_catch_exec:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+ if (addressprint)
+ ui_out_field_skip (uiout, "addr");
+ annotate_field (5);
+ if (b->exec_pathname != NULL)
+ {
+ ui_out_text (uiout, "program \"");
+ ui_out_field_string (uiout, "what", b->exec_pathname);
+ ui_out_text (uiout, "\" ");
+ }
+ break;
+
+ case bp_catch_catch:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+ if (addressprint)
+ ui_out_field_skip (uiout, "addr");
+ annotate_field (5);
+ ui_out_field_string (uiout, "what", "exception catch");
+ ui_out_spaces (uiout, 1);
+ break;
+
+ case bp_catch_throw:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+ if (addressprint)
+ ui_out_field_skip (uiout, "addr");
+ annotate_field (5);
+ ui_out_field_string (uiout, "what", "exception throw");
+ ui_out_spaces (uiout, 1);
+ break;
+
+ case bp_breakpoint:
+ case bp_hardware_breakpoint:
+ case bp_until:
+ case bp_finish:
+ case bp_longjmp:
+ case bp_longjmp_resume:
+ case bp_step_resume:
+ case bp_through_sigtramp:
+ case bp_watchpoint_scope:
+ case bp_call_dummy:
+ case bp_shlib_event:
+ case bp_thread_event:
+ case bp_overlay_event:
+ if (addressprint)
+ {
+ annotate_field (4);
+ ui_out_field_core_addr (uiout, "addr", b->address);
+ }
+ annotate_field (5);
+ *last_addr = b->address;
+ if (b->source_file)
+ {
+ sym = find_pc_sect_function (b->address, b->section);
+ if (sym)
+ {
+ ui_out_text (uiout, "in ");
+ ui_out_field_string (uiout, "func",
+ SYMBOL_SOURCE_NAME (sym));
+ ui_out_wrap_hint (uiout, wrap_indent);
+ ui_out_text (uiout, " at ");
+ }
+ ui_out_field_string (uiout, "file", b->source_file);
+ ui_out_text (uiout, ":");
+ ui_out_field_int (uiout, "line", b->line_number);
+ }
+ else
+ {
+ print_address_symbolic (b->address, stb->stream, demangle, "");
+ ui_out_field_stream (uiout, "at", stb);
+ }
+ break;
+ }
+
+ if (b->thread != -1)
+ {
+ /* FIXME: This seems to be redundant and lost here; see the
+ "stop only in" line a little further down. */
+ ui_out_text (uiout, " thread ");
+ ui_out_field_int (uiout, "thread", b->thread);
+ }
+
+ ui_out_text (uiout, "\n");
+
+ if (b->frame)
+ {
+ annotate_field (6);
+ ui_out_text (uiout, "\tstop only in stack frame at ");
+ ui_out_field_core_addr (uiout, "frame", b->frame);
+ ui_out_text (uiout, "\n");
+ }
+
+ if (b->cond)
+ {
+ annotate_field (7);
+ ui_out_text (uiout, "\tstop only if ");
+ print_expression (b->cond, stb->stream);
+ ui_out_field_stream (uiout, "cond", stb);
+ ui_out_text (uiout, "\n");
+ }
+
+ if (b->thread != -1)
+ {
+ /* FIXME should make an annotation for this */
+ ui_out_text (uiout, "\tstop only in thread ");
+ ui_out_field_int (uiout, "thread", b->thread);
+ ui_out_text (uiout, "\n");
+ }
+
+ if (show_breakpoint_hit_counts && b->hit_count)
+ {
+ /* FIXME should make an annotation for this */
+ if (ep_is_catchpoint (b))
+ ui_out_text (uiout, "\tcatchpoint");
+ else
+ ui_out_text (uiout, "\tbreakpoint");
+ ui_out_text (uiout, " already hit ");
+ ui_out_field_int (uiout, "times", b->hit_count);
+ if (b->hit_count == 1)
+ ui_out_text (uiout, " time\n");
+ else
+ ui_out_text (uiout, " times\n");
+ }
+
+ /* Output the count also if it is zero, but only if this is
+ mi. FIXME: Should have a better test for this. */
+ if (ui_out_is_mi_like_p (uiout))
+ if (show_breakpoint_hit_counts && b->hit_count == 0)
+ ui_out_field_int (uiout, "times", b->hit_count);
+
+ if (b->ignore_count)
+ {
+ annotate_field (8);
+ ui_out_text (uiout, "\tignore next ");
+ ui_out_field_int (uiout, "ignore", b->ignore_count);
+ ui_out_text (uiout, " hits\n");
+ }
+
+ if ((l = b->commands))
+ {
+ annotate_field (9);
+ ui_out_tuple_begin (uiout, "script");
+ print_command_lines (uiout, l, 4);
+ ui_out_tuple_end (uiout);
+ }
+ ui_out_tuple_end (uiout);
+ do_cleanups (old_chain);
+}
+
+struct captured_breakpoint_query_args
+ {
+ int bnum;
+ };
+
+static int
+do_captured_breakpoint_query (struct ui_out *uiout, void *data)
+{
+ struct captured_breakpoint_query_args *args = data;
+ register struct breakpoint *b;
+ CORE_ADDR dummy_addr = 0;
+ ALL_BREAKPOINTS (b)
+ {
+ if (args->bnum == b->number)
+ {
+ print_one_breakpoint (b, &dummy_addr);
+ return GDB_RC_OK;
+ }
+ }
+ return GDB_RC_NONE;
+}
+
+enum gdb_rc
+gdb_breakpoint_query (struct ui_out *uiout, int bnum)
+{
+ struct captured_breakpoint_query_args args;
+ args.bnum = bnum;
+ /* For the moment we don't trust print_one_breakpoint() to not throw
+ an error. */
+ return catch_exceptions (uiout, do_captured_breakpoint_query, &args,
+ NULL, RETURN_MASK_ALL);
+}
+
+/* Return non-zero if B is user settable (breakpoints, watchpoints,
+ catchpoints, et.al.). */
+
+static int
+user_settable_breakpoint (const struct breakpoint *b)
+{
+ return (b->type == bp_breakpoint
+ || b->type == bp_catch_load
+ || b->type == bp_catch_unload
+ || b->type == bp_catch_fork
+ || b->type == bp_catch_vfork
+ || b->type == bp_catch_exec
+ || b->type == bp_catch_catch
+ || b->type == bp_catch_throw
+ || b->type == bp_hardware_breakpoint
+ || b->type == bp_watchpoint
+ || b->type == bp_read_watchpoint
+ || b->type == bp_access_watchpoint
+ || b->type == bp_hardware_watchpoint);
+}
+
+/* Print information on user settable breakpoint (watchpoint, etc)
+ number BNUM. If BNUM is -1 print all user settable breakpoints.
+ If ALLFLAG is non-zero, include non- user settable breakpoints. */
+
+static void
+breakpoint_1 (int bnum, int allflag)
+{
+ register struct breakpoint *b;
+ CORE_ADDR last_addr = (CORE_ADDR) -1;
+ int nr_printable_breakpoints;
+
+ /* Compute the number of rows in the table. */
+ nr_printable_breakpoints = 0;
+ ALL_BREAKPOINTS (b)
+ if (bnum == -1
+ || bnum == b->number)
+ {
+ if (allflag || user_settable_breakpoint (b))
+ nr_printable_breakpoints++;
+ }
+
+ if (addressprint)
+ ui_out_table_begin (uiout, 6, nr_printable_breakpoints, "BreakpointTable");
+ else
+ ui_out_table_begin (uiout, 5, nr_printable_breakpoints, "BreakpointTable");
+
+ if (nr_printable_breakpoints > 0)
+ annotate_breakpoints_headers ();
+ if (nr_printable_breakpoints > 0)
+ annotate_field (0);
+ ui_out_table_header (uiout, 3, ui_left, "number", "Num"); /* 1 */
+ if (nr_printable_breakpoints > 0)
+ annotate_field (1);
+ ui_out_table_header (uiout, 14, ui_left, "type", "Type"); /* 2 */
+ if (nr_printable_breakpoints > 0)
+ annotate_field (2);
+ ui_out_table_header (uiout, 4, ui_left, "disp", "Disp"); /* 3 */
+ if (nr_printable_breakpoints > 0)
+ annotate_field (3);
+ ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb"); /* 4 */
+ if (addressprint)
+ {
+ if (nr_printable_breakpoints > 0)
+ annotate_field (4);
+ if (TARGET_ADDR_BIT <= 32)
+ ui_out_table_header (uiout, 10, ui_left, "addr", "Address");/* 5 */
+ else
+ ui_out_table_header (uiout, 18, ui_left, "addr", "Address");/* 5 */
+ }
+ if (nr_printable_breakpoints > 0)
+ annotate_field (5);
+ ui_out_table_header (uiout, 40, ui_noalign, "what", "What"); /* 6 */
+ ui_out_table_body (uiout);
+ if (nr_printable_breakpoints > 0)
+ annotate_breakpoints_table ();
+
+ ALL_BREAKPOINTS (b)
+ if (bnum == -1
+ || bnum == b->number)
+ {
+ /* We only print out user settable breakpoints unless the
+ allflag is set. */
+ if (allflag || user_settable_breakpoint (b))
+ print_one_breakpoint (b, &last_addr);
+ }
+
+ ui_out_table_end (uiout);
+
+ if (nr_printable_breakpoints == 0)
+ {
+ if (bnum == -1)
+ ui_out_message (uiout, 0, "No breakpoints or watchpoints.\n");
+ else
+ ui_out_message (uiout, 0, "No breakpoint or watchpoint number %d.\n",
+ bnum);
+ }
+ else
+ {
+ /* Compare against (CORE_ADDR)-1 in case some compiler decides
+ that a comparison of an unsigned with -1 is always false. */
+ if (last_addr != (CORE_ADDR) -1)
+ set_next_address (last_addr);
+ }
+
+ /* FIXME? Should this be moved up so that it is only called when
+ there have been breakpoints? */
+ annotate_breakpoints_table_end ();
+}
+
+/* ARGSUSED */
+static void
+breakpoints_info (char *bnum_exp, int from_tty)
+{
+ int bnum = -1;
+
+ if (bnum_exp)
+ bnum = parse_and_eval_long (bnum_exp);
+
+ breakpoint_1 (bnum, 0);
+}
+
+/* ARGSUSED */
+static void
+maintenance_info_breakpoints (char *bnum_exp, int from_tty)
+{
+ int bnum = -1;
+
+ if (bnum_exp)
+ bnum = parse_and_eval_long (bnum_exp);
+
+ breakpoint_1 (bnum, 1);
+}
+
+/* Print a message describing any breakpoints set at PC. */
+
+static void
+describe_other_breakpoints (CORE_ADDR pc, asection *section)
+{
+ register int others = 0;
+ register struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ if (b->address == pc) /* address match / overlay match */
+ if (!overlay_debugging || b->section == section)
+ others++;
+ if (others > 0)
+ {
+ printf_filtered ("Note: breakpoint%s ", (others > 1) ? "s" : "");
+ ALL_BREAKPOINTS (b)
+ if (b->address == pc) /* address match / overlay match */
+ if (!overlay_debugging || b->section == section)
+ {
+ others--;
+ printf_filtered ("%d%s%s ",
+ b->number,
+ ((b->enable_state == bp_disabled ||
+ b->enable_state == bp_shlib_disabled ||
+ b->enable_state == bp_call_disabled)
+ ? " (disabled)"
+ : b->enable_state == bp_permanent
+ ? " (permanent)"
+ : ""),
+ (others > 1) ? ","
+ : ((others == 1) ? " and" : ""));
+ }
+ printf_filtered ("also set at pc ");
+ print_address_numeric (pc, 1, gdb_stdout);
+ printf_filtered (".\n");
+ }
+}
+
+/* Set the default place to put a breakpoint
+ for the `break' command with no arguments. */
+
+void
+set_default_breakpoint (int valid, CORE_ADDR addr, struct symtab *symtab,
+ int line)
+{
+ default_breakpoint_valid = valid;
+ default_breakpoint_address = addr;
+ default_breakpoint_symtab = symtab;
+ default_breakpoint_line = line;
+}
+
+/* Return true iff it is meaningful to use the address member of
+ BPT. For some breakpoint types, the address member is irrelevant
+ and it makes no sense to attempt to compare it to other addresses
+ (or use it for any other purpose either).
+
+ More specifically, each of the following breakpoint types will always
+ have a zero valued address and we don't want check_duplicates() to mark
+ breakpoints of any of these types to be a duplicate of an actual
+ breakpoint at address zero:
+
+ bp_watchpoint
+ bp_hardware_watchpoint
+ bp_read_watchpoint
+ bp_access_watchpoint
+ bp_catch_exec
+ bp_longjmp_resume
+ bp_catch_fork
+ bp_catch_vork */
+
+static int
+breakpoint_address_is_meaningful (struct breakpoint *bpt)
+{
+ enum bptype type = bpt->type;
+
+ return (type != bp_watchpoint
+ && type != bp_hardware_watchpoint
+ && type != bp_read_watchpoint
+ && type != bp_access_watchpoint
+ && type != bp_catch_exec
+ && type != bp_longjmp_resume
+ && type != bp_catch_fork
+ && type != bp_catch_vfork);
+}
+
+/* Rescan breakpoints at the same address and section as BPT,
+ marking the first one as "first" and any others as "duplicates".
+ This is so that the bpt instruction is only inserted once.
+ If we have a permanent breakpoint at the same place as BPT, make
+ that one the official one, and the rest as duplicates. */
+
+static void
+check_duplicates (struct breakpoint *bpt)
+{
+ register struct breakpoint *b;
+ register int count = 0;
+ struct breakpoint *perm_bp = 0;
+ CORE_ADDR address = bpt->address;
+ asection *section = bpt->section;
+
+ if (! breakpoint_address_is_meaningful (bpt))
+ return;
+
+ ALL_BREAKPOINTS (b)
+ if (b->enable_state != bp_disabled
+ && b->enable_state != bp_shlib_disabled
+ && b->enable_state != bp_call_disabled
+ && b->address == address /* address / overlay match */
+ && (!overlay_debugging || b->section == section)
+ && breakpoint_address_is_meaningful (b))
+ {
+ /* Have we found a permanent breakpoint? */
+ if (b->enable_state == bp_permanent)
+ {
+ perm_bp = b;
+ break;
+ }
+
+ count++;
+ b->duplicate = count > 1;
+ }
+
+ /* If we found a permanent breakpoint at this address, go over the
+ list again and declare all the other breakpoints there to be the
+ duplicates. */
+ if (perm_bp)
+ {
+ perm_bp->duplicate = 0;
+
+ /* Permanent breakpoint should always be inserted. */
+ if (! perm_bp->inserted)
+ internal_error (__FILE__, __LINE__,
+ "allegedly permanent breakpoint is not "
+ "actually inserted");
+
+ ALL_BREAKPOINTS (b)
+ if (b != perm_bp)
+ {
+ if (b->inserted)
+ internal_error (__FILE__, __LINE__,
+ "another breakpoint was inserted on top of "
+ "a permanent breakpoint");
+
+ if (b->enable_state != bp_disabled
+ && b->enable_state != bp_shlib_disabled
+ && b->enable_state != bp_call_disabled
+ && b->address == address /* address / overlay match */
+ && (!overlay_debugging || b->section == section)
+ && breakpoint_address_is_meaningful (b))
+ b->duplicate = 1;
+ }
+ }
+}
+
+/* set_raw_breakpoint() is a low level routine for allocating and
+ partially initializing a breakpoint of type BPTYPE. The newly
+ created breakpoint's address, section, source file name, and line
+ number are provided by SAL. The newly created and partially
+ initialized breakpoint is added to the breakpoint chain and
+ is also returned as the value of this function.
+
+ It is expected that the caller will complete the initialization of
+ the newly created breakpoint struct as well as output any status
+ information regarding the creation of a new breakpoint. In
+ particular, set_raw_breakpoint() does NOT set the breakpoint
+ number! Care should be taken to not allow an error() to occur
+ prior to completing the initialization of the breakpoint. If this
+ should happen, a bogus breakpoint will be left on the chain. */
+
+struct breakpoint *
+set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype)
+{
+ register struct breakpoint *b, *b1;
+
+ b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint));
+ memset (b, 0, sizeof (*b));
+ b->address = sal.pc;
+ if (sal.symtab == NULL)
+ b->source_file = NULL;
+ else
+ b->source_file = savestring (sal.symtab->filename,
+ strlen (sal.symtab->filename));
+ b->section = sal.section;
+ b->type = bptype;
+ b->language = current_language->la_language;
+ b->input_radix = input_radix;
+ b->thread = -1;
+ b->line_number = sal.line;
+ b->enable_state = bp_enabled;
+ b->next = 0;
+ b->silent = 0;
+ b->ignore_count = 0;
+ b->commands = NULL;
+ b->frame = 0;
+ b->dll_pathname = NULL;
+ b->triggered_dll_pathname = NULL;
+ b->forked_inferior_pid = 0;
+ b->exec_pathname = NULL;
+
+ /* Add this breakpoint to the end of the chain
+ so that a list of breakpoints will come out in order
+ of increasing numbers. */
+
+ b1 = breakpoint_chain;
+ if (b1 == 0)
+ breakpoint_chain = b;
+ else
+ {
+ while (b1->next)
+ b1 = b1->next;
+ b1->next = b;
+ }
+
+ check_duplicates (b);
+ breakpoints_changed ();
+
+ return b;
+}
+
+
+/* Note that the breakpoint object B describes a permanent breakpoint
+ instruction, hard-wired into the inferior's code. */
+void
+make_breakpoint_permanent (struct breakpoint *b)
+{
+ b->enable_state = bp_permanent;
+
+ /* By definition, permanent breakpoints are already present in the code. */
+ b->inserted = 1;
+}
+
+static struct breakpoint *
+create_internal_breakpoint (CORE_ADDR address, enum bptype type)
+{
+ static int internal_breakpoint_number = -1;
+ struct symtab_and_line sal;
+ struct breakpoint *b;
+
+ INIT_SAL (&sal); /* initialize to zeroes */
+
+ sal.pc = address;
+ sal.section = find_pc_overlay (sal.pc);
+
+ b = set_raw_breakpoint (sal, type);
+ b->number = internal_breakpoint_number--;
+ b->disposition = disp_donttouch;
+
+ return b;
+}
+
+
+static void
+create_longjmp_breakpoint (char *func_name)
+{
+ struct breakpoint *b;
+ struct minimal_symbol *m;
+
+ if (func_name == NULL)
+ b = create_internal_breakpoint (0, bp_longjmp_resume);
+ else
+ {
+ if ((m = lookup_minimal_symbol_text (func_name, NULL, NULL)) == NULL)
+ return;
+
+ b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m), bp_longjmp);
+ }
+
+ b->enable_state = bp_disabled;
+ b->silent = 1;
+ if (func_name)
+ b->addr_string = xstrdup (func_name);
+}
+
+/* Call this routine when stepping and nexting to enable a breakpoint
+ if we do a longjmp(). When we hit that breakpoint, call
+ set_longjmp_resume_breakpoint() to figure out where we are going. */
+
+void
+enable_longjmp_breakpoint (void)
+{
+ register struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ if (b->type == bp_longjmp)
+ {
+ b->enable_state = bp_enabled;
+ check_duplicates (b);
+ }
+}
+
+void
+disable_longjmp_breakpoint (void)
+{
+ register struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ if (b->type == bp_longjmp
+ || b->type == bp_longjmp_resume)
+ {
+ b->enable_state = bp_disabled;
+ check_duplicates (b);
+ }
+}
+
+static void
+create_overlay_event_breakpoint (char *func_name)
+{
+ struct breakpoint *b;
+ struct minimal_symbol *m;
+
+ if ((m = lookup_minimal_symbol_text (func_name, NULL, NULL)) == NULL)
+ return;
+
+ b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m),
+ bp_overlay_event);
+ b->addr_string = xstrdup (func_name);
+
+ if (overlay_debugging == ovly_auto)
+ {
+ b->enable_state = bp_enabled;
+ overlay_events_enabled = 1;
+ }
+ else
+ {
+ b->enable_state = bp_disabled;
+ overlay_events_enabled = 0;
+ }
+}
+
+void
+enable_overlay_breakpoints (void)
+{
+ register struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ if (b->type == bp_overlay_event)
+ {
+ b->enable_state = bp_enabled;
+ check_duplicates (b);
+ overlay_events_enabled = 1;
+ }
+}
+
+void
+disable_overlay_breakpoints (void)
+{
+ register struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ if (b->type == bp_overlay_event)
+ {
+ b->enable_state = bp_disabled;
+ check_duplicates (b);
+ overlay_events_enabled = 0;
+ }
+}
+
+struct breakpoint *
+create_thread_event_breakpoint (CORE_ADDR address)
+{
+ struct breakpoint *b;
+ char addr_string[80]; /* Surely an addr can't be longer than that. */
+
+ b = create_internal_breakpoint (address, bp_thread_event);
+
+ b->enable_state = bp_enabled;
+ /* addr_string has to be used or breakpoint_re_set will delete me. */
+ sprintf (addr_string, "*0x%s", paddr (b->address));
+ b->addr_string = xstrdup (addr_string);
+
+ return b;
+}
+
+void
+remove_thread_event_breakpoints (void)
+{
+ struct breakpoint *b, *temp;
+
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ if (b->type == bp_thread_event)
+ delete_breakpoint (b);
+}
+
+#ifdef SOLIB_ADD
+void
+remove_solib_event_breakpoints (void)
+{
+ register struct breakpoint *b, *temp;
+
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ if (b->type == bp_shlib_event)
+ delete_breakpoint (b);
+}
+
+struct breakpoint *
+create_solib_event_breakpoint (CORE_ADDR address)
+{
+ struct breakpoint *b;
+
+ b = create_internal_breakpoint (address, bp_shlib_event);
+ return b;
+}
+
+/* Disable any breakpoints that are on code in shared libraries. Only
+ apply to enabled breakpoints, disabled ones can just stay disabled. */
+
+void
+disable_breakpoints_in_shlibs (int silent)
+{
+ struct breakpoint *b;
+ int disabled_shlib_breaks = 0;
+
+ /* See also: insert_breakpoints, under DISABLE_UNSETTABLE_BREAK. */
+ ALL_BREAKPOINTS (b)
+ {
+#if defined (PC_SOLIB)
+ if (((b->type == bp_breakpoint) ||
+ (b->type == bp_hardware_breakpoint)) &&
+ b->enable_state == bp_enabled &&
+ !b->duplicate &&
+ PC_SOLIB (b->address))
+ {
+ b->enable_state = bp_shlib_disabled;
+ if (!silent)
+ {
+ if (!disabled_shlib_breaks)
+ {
+ target_terminal_ours_for_output ();
+ warning ("Temporarily disabling shared library breakpoints:");
+ }
+ disabled_shlib_breaks = 1;
+ warning ("breakpoint #%d ", b->number);
+ }
+ }
+#endif
+ }
+}
+
+/* Try to reenable any breakpoints in shared libraries. */
+void
+re_enable_breakpoints_in_shlibs (void)
+{
+ struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ if (b->enable_state == bp_shlib_disabled)
+ {
+ char buf[1];
+
+ /* Do not reenable the breakpoint if the shared library
+ is still not mapped in. */
+ if (target_read_memory (b->address, buf, 1) == 0)
+ b->enable_state = bp_enabled;
+ }
+}
+
+#endif
+
+static void
+solib_load_unload_1 (char *hookname, int tempflag, char *dll_pathname,
+ char *cond_string, enum bptype bp_kind)
+{
+ struct breakpoint *b;
+ struct symtabs_and_lines sals;
+ struct cleanup *old_chain;
+ struct cleanup *canonical_strings_chain = NULL;
+ char *addr_start = hookname;
+ char *addr_end = NULL;
+ char **canonical = (char **) NULL;
+ int thread = -1; /* All threads. */
+
+ /* Set a breakpoint on the specified hook. */
+ sals = decode_line_1 (&hookname, 1, (struct symtab *) NULL, 0, &canonical);
+ addr_end = hookname;
+
+ if (sals.nelts == 0)
+ {
+ warning ("Unable to set a breakpoint on dynamic linker callback.");
+ warning ("Suggest linking with /opt/langtools/lib/end.o.");
+ warning ("GDB will be unable to track shl_load/shl_unload calls");
+ return;
+ }
+ if (sals.nelts != 1)
+ {
+ warning ("Unable to set unique breakpoint on dynamic linker callback.");
+ warning ("GDB will be unable to track shl_load/shl_unload calls");
+ return;
+ }
+
+ /* Make sure that all storage allocated in decode_line_1 gets freed
+ in case the following errors out. */
+ old_chain = make_cleanup (xfree, sals.sals);
+ if (canonical != (char **) NULL)
+ {
+ make_cleanup (xfree, canonical);
+ canonical_strings_chain = make_cleanup (null_cleanup, 0);
+ if (canonical[0] != NULL)
+ make_cleanup (xfree, canonical[0]);
+ }
+
+ resolve_sal_pc (&sals.sals[0]);
+
+ /* Remove the canonical strings from the cleanup, they are needed below. */
+ if (canonical != (char **) NULL)
+ discard_cleanups (canonical_strings_chain);
+
+ b = set_raw_breakpoint (sals.sals[0], bp_kind);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+ b->cond = NULL;
+ b->cond_string = (cond_string == NULL) ?
+ NULL : savestring (cond_string, strlen (cond_string));
+ b->thread = thread;
+
+ if (canonical != (char **) NULL && canonical[0] != NULL)
+ b->addr_string = canonical[0];
+ else if (addr_start)
+ b->addr_string = savestring (addr_start, addr_end - addr_start);
+
+ b->enable_state = bp_enabled;
+ b->disposition = tempflag ? disp_del : disp_donttouch;
+
+ if (dll_pathname == NULL)
+ b->dll_pathname = NULL;
+ else
+ {
+ b->dll_pathname = (char *) xmalloc (strlen (dll_pathname) + 1);
+ strcpy (b->dll_pathname, dll_pathname);
+ }
+
+ mention (b);
+ do_cleanups (old_chain);
+}
+
+void
+create_solib_load_event_breakpoint (char *hookname, int tempflag,
+ char *dll_pathname, char *cond_string)
+{
+ solib_load_unload_1 (hookname, tempflag, dll_pathname,
+ cond_string, bp_catch_load);
+}
+
+void
+create_solib_unload_event_breakpoint (char *hookname, int tempflag,
+ char *dll_pathname, char *cond_string)
+{
+ solib_load_unload_1 (hookname,tempflag, dll_pathname,
+ cond_string, bp_catch_unload);
+}
+
+static void
+create_fork_vfork_event_catchpoint (int tempflag, char *cond_string,
+ enum bptype bp_kind)
+{
+ struct symtab_and_line sal;
+ struct breakpoint *b;
+ int thread = -1; /* All threads. */
+
+ INIT_SAL (&sal);
+ sal.pc = 0;
+ sal.symtab = NULL;
+ sal.line = 0;
+
+ b = set_raw_breakpoint (sal, bp_kind);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+ b->cond = NULL;
+ b->cond_string = (cond_string == NULL) ?
+ NULL : savestring (cond_string, strlen (cond_string));
+ b->thread = thread;
+ b->addr_string = NULL;
+ b->enable_state = bp_enabled;
+ b->disposition = tempflag ? disp_del : disp_donttouch;
+ b->forked_inferior_pid = 0;
+
+ mention (b);
+}
+
+void
+create_fork_event_catchpoint (int tempflag, char *cond_string)
+{
+ create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_fork);
+}
+
+void
+create_vfork_event_catchpoint (int tempflag, char *cond_string)
+{
+ create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_vfork);
+}
+
+void
+create_exec_event_catchpoint (int tempflag, char *cond_string)
+{
+ struct symtab_and_line sal;
+ struct breakpoint *b;
+ int thread = -1; /* All threads. */
+
+ INIT_SAL (&sal);
+ sal.pc = 0;
+ sal.symtab = NULL;
+ sal.line = 0;
+
+ b = set_raw_breakpoint (sal, bp_catch_exec);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+ b->cond = NULL;
+ b->cond_string = (cond_string == NULL) ?
+ NULL : savestring (cond_string, strlen (cond_string));
+ b->thread = thread;
+ b->addr_string = NULL;
+ b->enable_state = bp_enabled;
+ b->disposition = tempflag ? disp_del : disp_donttouch;
+
+ mention (b);
+}
+
+static int
+hw_breakpoint_used_count (void)
+{
+ register struct breakpoint *b;
+ int i = 0;
+
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->type == bp_hardware_breakpoint && b->enable_state == bp_enabled)
+ i++;
+ }
+
+ return i;
+}
+
+static int
+hw_watchpoint_used_count (enum bptype type, int *other_type_used)
+{
+ register struct breakpoint *b;
+ int i = 0;
+
+ *other_type_used = 0;
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->enable_state == bp_enabled)
+ {
+ if (b->type == type)
+ i++;
+ else if ((b->type == bp_hardware_watchpoint ||
+ b->type == bp_read_watchpoint ||
+ b->type == bp_access_watchpoint)
+ && b->enable_state == bp_enabled)
+ *other_type_used = 1;
+ }
+ }
+ return i;
+}
+
+/* Call this after hitting the longjmp() breakpoint. Use this to set
+ a new breakpoint at the target of the jmp_buf.
+
+ FIXME - This ought to be done by setting a temporary breakpoint
+ that gets deleted automatically... */
+
+void
+set_longjmp_resume_breakpoint (CORE_ADDR pc, struct frame_info *frame)
+{
+ register struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ if (b->type == bp_longjmp_resume)
+ {
+ b->address = pc;
+ b->enable_state = bp_enabled;
+ if (frame != NULL)
+ b->frame = frame->frame;
+ else
+ b->frame = 0;
+ check_duplicates (b);
+ return;
+ }
+}
+
+void
+disable_watchpoints_before_interactive_call_start (void)
+{
+ struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ {
+ if (((b->type == bp_watchpoint)
+ || (b->type == bp_hardware_watchpoint)
+ || (b->type == bp_read_watchpoint)
+ || (b->type == bp_access_watchpoint)
+ || ep_is_exception_catchpoint (b))
+ && (b->enable_state == bp_enabled))
+ {
+ b->enable_state = bp_call_disabled;
+ check_duplicates (b);
+ }
+ }
+}
+
+void
+enable_watchpoints_after_interactive_call_stop (void)
+{
+ struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ {
+ if (((b->type == bp_watchpoint)
+ || (b->type == bp_hardware_watchpoint)
+ || (b->type == bp_read_watchpoint)
+ || (b->type == bp_access_watchpoint)
+ || ep_is_exception_catchpoint (b))
+ && (b->enable_state == bp_call_disabled))
+ {
+ b->enable_state = bp_enabled;
+ check_duplicates (b);
+ }
+ }
+}
+
+
+/* Set a breakpoint that will evaporate an end of command
+ at address specified by SAL.
+ Restrict it to frame FRAME if FRAME is nonzero. */
+
+struct breakpoint *
+set_momentary_breakpoint (struct symtab_and_line sal, struct frame_info *frame,
+ enum bptype type)
+{
+ register struct breakpoint *b;
+ b = set_raw_breakpoint (sal, type);
+ b->enable_state = bp_enabled;
+ b->disposition = disp_donttouch;
+ b->frame = (frame ? frame->frame : 0);
+
+ /* If we're debugging a multi-threaded program, then we
+ want momentary breakpoints to be active in only a
+ single thread of control. */
+ if (in_thread_list (inferior_ptid))
+ b->thread = pid_to_thread_id (inferior_ptid);
+
+ return b;
+}
+
+
+/* Tell the user we have just set a breakpoint B. */
+
+static void
+mention (struct breakpoint *b)
+{
+ int say_where = 0;
+ struct cleanup *old_chain;
+ struct ui_stream *stb;
+
+ stb = ui_out_stream_new (uiout);
+ old_chain = make_cleanup_ui_out_stream_delete (stb);
+
+ /* FIXME: This is misplaced; mention() is called by things (like hitting a
+ watchpoint) other than breakpoint creation. It should be possible to
+ clean this up and at the same time replace the random calls to
+ breakpoint_changed with this hook, as has already been done for
+ delete_breakpoint_hook and so on. */
+ if (create_breakpoint_hook)
+ create_breakpoint_hook (b);
+ breakpoint_create_event (b->number);
+
+ switch (b->type)
+ {
+ case bp_none:
+ printf_filtered ("(apparently deleted?) Eventpoint %d: ", b->number);
+ break;
+ case bp_watchpoint:
+ ui_out_text (uiout, "Watchpoint ");
+ ui_out_tuple_begin (uiout, "wpt");
+ ui_out_field_int (uiout, "number", b->number);
+ ui_out_text (uiout, ": ");
+ print_expression (b->exp, stb->stream);
+ ui_out_field_stream (uiout, "exp", stb);
+ ui_out_tuple_end (uiout);
+ break;
+ case bp_hardware_watchpoint:
+ ui_out_text (uiout, "Hardware watchpoint ");
+ ui_out_tuple_begin (uiout, "wpt");
+ ui_out_field_int (uiout, "number", b->number);
+ ui_out_text (uiout, ": ");
+ print_expression (b->exp, stb->stream);
+ ui_out_field_stream (uiout, "exp", stb);
+ ui_out_tuple_end (uiout);
+ break;
+ case bp_read_watchpoint:
+ ui_out_text (uiout, "Hardware read watchpoint ");
+ ui_out_tuple_begin (uiout, "hw-rwpt");
+ ui_out_field_int (uiout, "number", b->number);
+ ui_out_text (uiout, ": ");
+ print_expression (b->exp, stb->stream);
+ ui_out_field_stream (uiout, "exp", stb);
+ ui_out_tuple_end (uiout);
+ break;
+ case bp_access_watchpoint:
+ ui_out_text (uiout, "Hardware access (read/write) watchpoint ");
+ ui_out_tuple_begin (uiout, "hw-awpt");
+ ui_out_field_int (uiout, "number", b->number);
+ ui_out_text (uiout, ": ");
+ print_expression (b->exp, stb->stream);
+ ui_out_field_stream (uiout, "exp", stb);
+ ui_out_tuple_end (uiout);
+ break;
+ case bp_breakpoint:
+ if (ui_out_is_mi_like_p (uiout))
+ {
+ say_where = 0;
+ break;
+ }
+ printf_filtered ("Breakpoint %d", b->number);
+ say_where = 1;
+ break;
+ case bp_hardware_breakpoint:
+ if (ui_out_is_mi_like_p (uiout))
+ {
+ say_where = 0;
+ break;
+ }
+ printf_filtered ("Hardware assisted breakpoint %d", b->number);
+ say_where = 1;
+ break;
+ case bp_catch_load:
+ case bp_catch_unload:
+ printf_filtered ("Catchpoint %d (%s %s)",
+ b->number,
+ (b->type == bp_catch_load) ? "load" : "unload",
+ (b->dll_pathname != NULL) ?
+ b->dll_pathname : "<any library>");
+ break;
+ case bp_catch_fork:
+ case bp_catch_vfork:
+ printf_filtered ("Catchpoint %d (%s)",
+ b->number,
+ (b->type == bp_catch_fork) ? "fork" : "vfork");
+ break;
+ case bp_catch_exec:
+ printf_filtered ("Catchpoint %d (exec)",
+ b->number);
+ break;
+ case bp_catch_catch:
+ case bp_catch_throw:
+ printf_filtered ("Catchpoint %d (%s)",
+ b->number,
+ (b->type == bp_catch_catch) ? "catch" : "throw");
+ break;
+
+ case bp_until:
+ case bp_finish:
+ case bp_longjmp:
+ case bp_longjmp_resume:
+ case bp_step_resume:
+ case bp_through_sigtramp:
+ case bp_call_dummy:
+ case bp_watchpoint_scope:
+ case bp_shlib_event:
+ case bp_thread_event:
+ case bp_overlay_event:
+ break;
+ }
+ if (say_where)
+ {
+ if (addressprint || b->source_file == NULL)
+ {
+ printf_filtered (" at ");
+ print_address_numeric (b->address, 1, gdb_stdout);
+ }
+ if (b->source_file)
+ printf_filtered (": file %s, line %d.",
+ b->source_file, b->line_number);
+ }
+ do_cleanups (old_chain);
+ if (ui_out_is_mi_like_p (uiout))
+ return;
+ printf_filtered ("\n");
+}
+
+
+/* Add SALS.nelts breakpoints to the breakpoint table. For each
+ SALS.sal[i] breakpoint, include the corresponding ADDR_STRING[i],
+ COND[i] and COND_STRING[i] values.
+
+ NOTE: If the function succeeds, the caller is expected to cleanup
+ the arrays ADDR_STRING, COND_STRING, COND and SALS (but not the
+ array contents). If the function fails (error() is called), the
+ caller is expected to cleanups both the ADDR_STRING, COND_STRING,
+ COND and SALS arrays and each of those arrays contents. */
+
+static void
+create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
+ struct expression **cond, char **cond_string,
+ enum bptype type, enum bpdisp disposition,
+ int thread, int ignore_count, int from_tty)
+{
+ if (type == bp_hardware_breakpoint)
+ {
+ int i = hw_breakpoint_used_count ();
+ int target_resources_ok =
+ TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint,
+ i + sals.nelts, 0);
+ if (target_resources_ok == 0)
+ error ("No hardware breakpoint support in the target.");
+ else if (target_resources_ok < 0)
+ error ("Hardware breakpoints used exceeds limit.");
+ }
+
+ /* Now set all the breakpoints. */
+ {
+ int i;
+ for (i = 0; i < sals.nelts; i++)
+ {
+ struct breakpoint *b;
+ struct symtab_and_line sal = sals.sals[i];
+
+ if (from_tty)
+ describe_other_breakpoints (sal.pc, sal.section);
+
+ b = set_raw_breakpoint (sal, type);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+ b->cond = cond[i];
+ b->thread = thread;
+ b->addr_string = addr_string[i];
+ b->cond_string = cond_string[i];
+ b->ignore_count = ignore_count;
+ b->enable_state = bp_enabled;
+ b->disposition = disposition;
+ mention (b);
+ }
+ }
+}
+
+/* Parse ARG which is assumed to be a SAL specification possibly
+ followed by conditionals. On return, SALS contains an array of SAL
+ addresses found. ADDR_STRING contains a vector of (canonical)
+ address strings. ARG points to the end of the SAL. */
+
+void
+parse_breakpoint_sals (char **address,
+ struct symtabs_and_lines *sals,
+ char ***addr_string)
+{
+ char *addr_start = *address;
+ *addr_string = NULL;
+ /* If no arg given, or if first arg is 'if ', use the default
+ breakpoint. */
+ if ((*address) == NULL
+ || (strncmp ((*address), "if", 2) == 0 && isspace ((*address)[2])))
+ {
+ if (default_breakpoint_valid)
+ {
+ struct symtab_and_line sal;
+ INIT_SAL (&sal); /* initialize to zeroes */
+ sals->sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ sal.pc = default_breakpoint_address;
+ sal.line = default_breakpoint_line;
+ sal.symtab = default_breakpoint_symtab;
+ sal.section = find_pc_overlay (sal.pc);
+ sals->sals[0] = sal;
+ sals->nelts = 1;
+ }
+ else
+ error ("No default breakpoint address now.");
+ }
+ else
+ {
+ /* Force almost all breakpoints to be in terms of the
+ current_source_symtab (which is decode_line_1's default). This
+ should produce the results we want almost all of the time while
+ leaving default_breakpoint_* alone. */
+ if (default_breakpoint_valid
+ && (!current_source_symtab
+ || (strchr ("+-", (*address)[0]) != NULL)))
+ *sals = decode_line_1 (address, 1, default_breakpoint_symtab,
+ default_breakpoint_line, addr_string);
+ else
+ *sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0, addr_string);
+ }
+ /* For any SAL that didn't have a canonical string, fill one in. */
+ if (sals->nelts > 0 && *addr_string == NULL)
+ *addr_string = xcalloc (sals->nelts, sizeof (char **));
+ if (addr_start != (*address))
+ {
+ int i;
+ for (i = 0; i < sals->nelts; i++)
+ {
+ /* Add the string if not present. */
+ if ((*addr_string)[i] == NULL)
+ (*addr_string)[i] = savestring (addr_start, (*address) - addr_start);
+ }
+ }
+}
+
+
+/* Convert each SAL into a real PC. Verify that the PC can be
+ inserted as a breakpoint. If it can't throw an error. */
+
+void
+breakpoint_sals_to_pc (struct symtabs_and_lines *sals,
+ char *address)
+{
+ int i;
+ for (i = 0; i < sals->nelts; i++)
+ {
+ resolve_sal_pc (&sals->sals[i]);
+
+ /* It's possible for the PC to be nonzero, but still an illegal
+ value on some targets.
+
+ For example, on HP-UX if you start gdb, and before running the
+ inferior you try to set a breakpoint on a shared library function
+ "foo" where the inferior doesn't call "foo" directly but does
+ pass its address to another function call, then we do find a
+ minimal symbol for the "foo", but it's address is invalid.
+ (Appears to be an index into a table that the loader sets up
+ when the inferior is run.)
+
+ Give the target a chance to bless sals.sals[i].pc before we
+ try to make a breakpoint for it. */
+ if (PC_REQUIRES_RUN_BEFORE_USE (sals->sals[i].pc))
+ {
+ if (address == NULL)
+ error ("Cannot break without a running program.");
+ else
+ error ("Cannot break on %s without a running program.",
+ address);
+ }
+ }
+}
+
+/* Set a breakpoint according to ARG (function, linenum or *address)
+ flag: first bit : 0 non-temporary, 1 temporary.
+ second bit : 0 normal breakpoint, 1 hardware breakpoint. */
+
+static void
+break_command_1 (char *arg, int flag, int from_tty)
+{
+ int tempflag, hardwareflag;
+ struct symtabs_and_lines sals;
+ register struct expression **cond = 0;
+ /* Pointers in arg to the start, and one past the end, of the
+ condition. */
+ char **cond_string = (char **) NULL;
+ char *addr_start = arg;
+ char **addr_string;
+ struct cleanup *old_chain;
+ struct cleanup *breakpoint_chain = NULL;
+ int i;
+ int thread = -1;
+ int ignore_count = 0;
+
+ hardwareflag = flag & BP_HARDWAREFLAG;
+ tempflag = flag & BP_TEMPFLAG;
+
+ sals.sals = NULL;
+ sals.nelts = 0;
+ addr_string = NULL;
+ parse_breakpoint_sals (&arg, &sals, &addr_string);
+
+ if (!sals.nelts)
+ return;
+
+ /* Create a chain of things that always need to be cleaned up. */
+ old_chain = make_cleanup (null_cleanup, 0);
+
+ /* Make sure that all storage allocated to SALS gets freed. */
+ make_cleanup (xfree, sals.sals);
+
+ /* Cleanup the addr_string array but not its contents. */
+ make_cleanup (xfree, addr_string);
+
+ /* Allocate space for all the cond expressions. */
+ cond = xcalloc (sals.nelts, sizeof (struct expression *));
+ make_cleanup (xfree, cond);
+
+ /* Allocate space for all the cond strings. */
+ cond_string = xcalloc (sals.nelts, sizeof (char **));
+ make_cleanup (xfree, cond_string);
+
+ /* ----------------------------- SNIP -----------------------------
+ Anything added to the cleanup chain beyond this point is assumed
+ to be part of a breakpoint. If the breakpoint create succeeds
+ then the memory is not reclaimed. */
+ breakpoint_chain = make_cleanup (null_cleanup, 0);
+
+ /* Mark the contents of the addr_string for cleanup. These go on
+ the breakpoint_chain and only occure if the breakpoint create
+ fails. */
+ for (i = 0; i < sals.nelts; i++)
+ {
+ if (addr_string[i] != NULL)
+ make_cleanup (xfree, addr_string[i]);
+ }
+
+ /* Resolve all line numbers to PC's and verify that the addresses
+ are ok for the target. */
+ breakpoint_sals_to_pc (&sals, addr_start);
+
+ /* Verify that condition can be parsed, before setting any
+ breakpoints. Allocate a separate condition expression for each
+ breakpoint. */
+ thread = -1; /* No specific thread yet */
+ for (i = 0; i < sals.nelts; i++)
+ {
+ char *tok = arg;
+ while (tok && *tok)
+ {
+ char *end_tok;
+ int toklen;
+ char *cond_start = NULL;
+ char *cond_end = NULL;
+ while (*tok == ' ' || *tok == '\t')
+ tok++;
+
+ end_tok = tok;
+
+ while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000')
+ end_tok++;
+
+ toklen = end_tok - tok;
+
+ if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
+ {
+ tok = cond_start = end_tok + 1;
+ cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
+ make_cleanup (xfree, cond[i]);
+ cond_end = tok;
+ cond_string[i] = savestring (cond_start, cond_end - cond_start);
+ make_cleanup (xfree, cond_string[i]);
+ }
+ else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0)
+ {
+ char *tmptok;
+
+ tok = end_tok + 1;
+ tmptok = tok;
+ thread = strtol (tok, &tok, 0);
+ if (tok == tmptok)
+ error ("Junk after thread keyword.");
+ if (!valid_thread_id (thread))
+ error ("Unknown thread %d\n", thread);
+ }
+ else
+ error ("Junk at end of arguments.");
+ }
+ }
+
+ create_breakpoints (sals, addr_string, cond, cond_string,
+ hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
+ tempflag ? disp_del : disp_donttouch,
+ thread, ignore_count, from_tty);
+
+ if (sals.nelts > 1)
+ {
+ warning ("Multiple breakpoints were set.");
+ warning ("Use the \"delete\" command to delete unwanted breakpoints.");
+ }
+ /* That's it. Discard the cleanups for data inserted into the
+ breakpoint. */
+ discard_cleanups (breakpoint_chain);
+ /* But cleanup everything else. */
+ do_cleanups (old_chain);
+}
+
+/* Set a breakpoint of TYPE/DISPOSITION according to ARG (function,
+ linenum or *address) with COND and IGNORE_COUNT. */
+
+struct captured_breakpoint_args
+ {
+ char *address;
+ char *condition;
+ int hardwareflag;
+ int tempflag;
+ int thread;
+ int ignore_count;
+ };
+
+static int
+do_captured_breakpoint (void *data)
+{
+ struct captured_breakpoint_args *args = data;
+ struct symtabs_and_lines sals;
+ register struct expression **cond;
+ struct cleanup *old_chain;
+ struct cleanup *breakpoint_chain = NULL;
+ int i;
+ char **addr_string;
+ char **cond_string;
+
+ char *address_end;
+
+ /* Parse the source and lines spec. Delay check that the expression
+ didn't contain trailing garbage until after cleanups are in
+ place. */
+ sals.sals = NULL;
+ sals.nelts = 0;
+ address_end = args->address;
+ addr_string = NULL;
+ parse_breakpoint_sals (&address_end, &sals, &addr_string);
+
+ if (!sals.nelts)
+ return GDB_RC_NONE;
+
+ /* Create a chain of things at always need to be cleaned up. */
+ old_chain = make_cleanup (null_cleanup, 0);
+
+ /* Always have a addr_string array, even if it is empty. */
+ make_cleanup (xfree, addr_string);
+
+ /* Make sure that all storage allocated to SALS gets freed. */
+ make_cleanup (xfree, sals.sals);
+
+ /* Allocate space for all the cond expressions. */
+ cond = xcalloc (sals.nelts, sizeof (struct expression *));
+ make_cleanup (xfree, cond);
+
+ /* Allocate space for all the cond strings. */
+ cond_string = xcalloc (sals.nelts, sizeof (char **));
+ make_cleanup (xfree, cond_string);
+
+ /* ----------------------------- SNIP -----------------------------
+ Anything added to the cleanup chain beyond this point is assumed
+ to be part of a breakpoint. If the breakpoint create goes
+ through then that memory is not cleaned up. */
+ breakpoint_chain = make_cleanup (null_cleanup, 0);
+
+ /* Mark the contents of the addr_string for cleanup. These go on
+ the breakpoint_chain and only occure if the breakpoint create
+ fails. */
+ for (i = 0; i < sals.nelts; i++)
+ {
+ if (addr_string[i] != NULL)
+ make_cleanup (xfree, addr_string[i]);
+ }
+
+ /* Wait until now before checking for garbage at the end of the
+ address. That way cleanups can take care of freeing any
+ memory. */
+ if (*address_end != '\0')
+ error ("Garbage %s following breakpoint address", address_end);
+
+ /* Resolve all line numbers to PC's. */
+ breakpoint_sals_to_pc (&sals, args->address);
+
+ /* Verify that conditions can be parsed, before setting any
+ breakpoints. */
+ for (i = 0; i < sals.nelts; i++)
+ {
+ if (args->condition != NULL)
+ {
+ char *tok = args->condition;
+ cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
+ if (*tok != '\0')
+ error ("Garbage %s follows condition", tok);
+ make_cleanup (xfree, cond[i]);
+ cond_string[i] = xstrdup (args->condition);
+ }
+ }
+
+ create_breakpoints (sals, addr_string, cond, cond_string,
+ args->hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
+ args->tempflag ? disp_del : disp_donttouch,
+ args->thread, args->ignore_count, 0/*from-tty*/);
+
+ /* That's it. Discard the cleanups for data inserted into the
+ breakpoint. */
+ discard_cleanups (breakpoint_chain);
+ /* But cleanup everything else. */
+ do_cleanups (old_chain);
+ return GDB_RC_OK;
+}
+
+enum gdb_rc
+gdb_breakpoint (char *address, char *condition,
+ int hardwareflag, int tempflag,
+ int thread, int ignore_count)
+{
+ struct captured_breakpoint_args args;
+ args.address = address;
+ args.condition = condition;
+ args.hardwareflag = hardwareflag;
+ args.tempflag = tempflag;
+ args.thread = thread;
+ args.ignore_count = ignore_count;
+ return catch_errors (do_captured_breakpoint, &args,
+ NULL, RETURN_MASK_ALL);
+}
+
+
+static void
+break_at_finish_at_depth_command_1 (char *arg, int flag, int from_tty)
+{
+ struct frame_info *frame;
+ CORE_ADDR low, high, selected_pc = 0;
+ char *extra_args = NULL;
+ char *level_arg;
+ char *addr_string;
+ int extra_args_len = 0, if_arg = 0;
+
+ if (!arg ||
+ (arg[0] == 'i' && arg[1] == 'f' && (arg[2] == ' ' || arg[2] == '\t')))
+ {
+
+ if (default_breakpoint_valid)
+ {
+ if (selected_frame)
+ {
+ selected_pc = selected_frame->pc;
+ if (arg)
+ if_arg = 1;
+ }
+ else
+ error ("No selected frame.");
+ }
+ else
+ error ("No default breakpoint address now.");
+ }
+ else
+ {
+ extra_args = strchr (arg, ' ');
+ if (extra_args)
+ {
+ extra_args++;
+ extra_args_len = strlen (extra_args);
+ level_arg = (char *) xmalloc (extra_args - arg);
+ strncpy (level_arg, arg, extra_args - arg - 1);
+ level_arg[extra_args - arg - 1] = '\0';
+ }
+ else
+ {
+ level_arg = (char *) xmalloc (strlen (arg) + 1);
+ strcpy (level_arg, arg);
+ }
+
+ frame = parse_frame_specification (level_arg);
+ if (frame)
+ selected_pc = frame->pc;
+ else
+ selected_pc = 0;
+ }
+ if (if_arg)
+ {
+ extra_args = arg;
+ extra_args_len = strlen (arg);
+ }
+
+ if (selected_pc)
+ {
+ if (find_pc_partial_function (selected_pc, (char **) NULL, &low, &high))
+ {
+ addr_string = (char *) xmalloc (26 + extra_args_len);
+ if (extra_args_len)
+ sprintf (addr_string, "*0x%s %s", paddr_nz (high), extra_args);
+ else
+ sprintf (addr_string, "*0x%s", paddr_nz (high));
+ break_command_1 (addr_string, flag, from_tty);
+ xfree (addr_string);
+ }
+ else
+ error ("No function contains the specified address");
+ }
+ else
+ error ("Unable to set breakpoint at procedure exit");
+}
+
+
+static void
+break_at_finish_command_1 (char *arg, int flag, int from_tty)
+{
+ char *addr_string, *break_string, *beg_addr_string;
+ CORE_ADDR low, high;
+ struct symtabs_and_lines sals;
+ struct symtab_and_line sal;
+ struct cleanup *old_chain;
+ char *extra_args = NULL;
+ int extra_args_len = 0;
+ int i, if_arg = 0;
+
+ if (!arg ||
+ (arg[0] == 'i' && arg[1] == 'f' && (arg[2] == ' ' || arg[2] == '\t')))
+ {
+ if (default_breakpoint_valid)
+ {
+ if (selected_frame)
+ {
+ addr_string = (char *) xmalloc (15);
+ sprintf (addr_string, "*0x%s", paddr_nz (selected_frame->pc));
+ if (arg)
+ if_arg = 1;
+ }
+ else
+ error ("No selected frame.");
+ }
+ else
+ error ("No default breakpoint address now.");
+ }
+ else
+ {
+ addr_string = (char *) xmalloc (strlen (arg) + 1);
+ strcpy (addr_string, arg);
+ }
+
+ if (if_arg)
+ {
+ extra_args = arg;
+ extra_args_len = strlen (arg);
+ }
+ else if (arg)
+ {
+ /* get the stuff after the function name or address */
+ extra_args = strchr (arg, ' ');
+ if (extra_args)
+ {
+ extra_args++;
+ extra_args_len = strlen (extra_args);
+ }
+ }
+
+ sals.sals = NULL;
+ sals.nelts = 0;
+
+ beg_addr_string = addr_string;
+ sals = decode_line_1 (&addr_string, 1, (struct symtab *) NULL, 0,
+ (char ***) NULL);
+
+ xfree (beg_addr_string);
+ old_chain = make_cleanup (xfree, sals.sals);
+ for (i = 0; (i < sals.nelts); i++)
+ {
+ sal = sals.sals[i];
+ if (find_pc_partial_function (sal.pc, (char **) NULL, &low, &high))
+ {
+ break_string = (char *) xmalloc (extra_args_len + 26);
+ if (extra_args_len)
+ sprintf (break_string, "*0x%s %s", paddr_nz (high), extra_args);
+ else
+ sprintf (break_string, "*0x%s", paddr_nz (high));
+ break_command_1 (break_string, flag, from_tty);
+ xfree (break_string);
+ }
+ else
+ error ("No function contains the specified address");
+ }
+ if (sals.nelts > 1)
+ {
+ warning ("Multiple breakpoints were set.\n");
+ warning ("Use the \"delete\" command to delete unwanted breakpoints.");
+ }
+ do_cleanups (old_chain);
+}
+
+
+/* Helper function for break_command_1 and disassemble_command. */
+
+void
+resolve_sal_pc (struct symtab_and_line *sal)
+{
+ CORE_ADDR pc;
+
+ if (sal->pc == 0 && sal->symtab != NULL)
+ {
+ if (!find_line_pc (sal->symtab, sal->line, &pc))
+ error ("No line %d in file \"%s\".",
+ sal->line, sal->symtab->filename);
+ sal->pc = pc;
+ }
+
+ if (sal->section == 0 && sal->symtab != NULL)
+ {
+ struct blockvector *bv;
+ struct block *b;
+ struct symbol *sym;
+ int index;
+
+ bv = blockvector_for_pc_sect (sal->pc, 0, &index, sal->symtab);
+ if (bv != NULL)
+ {
+ b = BLOCKVECTOR_BLOCK (bv, index);
+ sym = block_function (b);
+ if (sym != NULL)
+ {
+ fixup_symbol_section (sym, sal->symtab->objfile);
+ sal->section = SYMBOL_BFD_SECTION (sym);
+ }
+ else
+ {
+ /* It really is worthwhile to have the section, so we'll just
+ have to look harder. This case can be executed if we have
+ line numbers but no functions (as can happen in assembly
+ source). */
+
+ struct minimal_symbol *msym;
+
+ msym = lookup_minimal_symbol_by_pc (sal->pc);
+ if (msym)
+ sal->section = SYMBOL_BFD_SECTION (msym);
+ }
+ }
+ }
+}
+
+void
+break_command (char *arg, int from_tty)
+{
+ break_command_1 (arg, 0, from_tty);
+}
+
+void
+break_at_finish_command (char *arg, int from_tty)
+{
+ break_at_finish_command_1 (arg, 0, from_tty);
+}
+
+void
+break_at_finish_at_depth_command (char *arg, int from_tty)
+{
+ break_at_finish_at_depth_command_1 (arg, 0, from_tty);
+}
+
+void
+tbreak_command (char *arg, int from_tty)
+{
+ break_command_1 (arg, BP_TEMPFLAG, from_tty);
+}
+
+void
+tbreak_at_finish_command (char *arg, int from_tty)
+{
+ break_at_finish_command_1 (arg, BP_TEMPFLAG, from_tty);
+}
+
+static void
+hbreak_command (char *arg, int from_tty)
+{
+ break_command_1 (arg, BP_HARDWAREFLAG, from_tty);
+}
+
+static void
+thbreak_command (char *arg, int from_tty)
+{
+ break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty);
+}
+
+static void
+stop_command (char *arg, int from_tty)
+{
+ printf_filtered ("Specify the type of breakpoint to set.\n\
+Usage: stop in <function | address>\n\
+ stop at <line>\n");
+}
+
+static void
+stopin_command (char *arg, int from_tty)
+{
+ int badInput = 0;
+
+ if (arg == (char *) NULL)
+ badInput = 1;
+ else if (*arg != '*')
+ {
+ char *argptr = arg;
+ int hasColon = 0;
+
+ /* look for a ':'. If this is a line number specification, then
+ say it is bad, otherwise, it should be an address or
+ function/method name */
+ while (*argptr && !hasColon)
+ {
+ hasColon = (*argptr == ':');
+ argptr++;
+ }
+
+ if (hasColon)
+ badInput = (*argptr != ':'); /* Not a class::method */
+ else
+ badInput = isdigit (*arg); /* a simple line number */
+ }
+
+ if (badInput)
+ printf_filtered ("Usage: stop in <function | address>\n");
+ else
+ break_command_1 (arg, 0, from_tty);
+}
+
+static void
+stopat_command (char *arg, int from_tty)
+{
+ int badInput = 0;
+
+ if (arg == (char *) NULL || *arg == '*') /* no line number */
+ badInput = 1;
+ else
+ {
+ char *argptr = arg;
+ int hasColon = 0;
+
+ /* look for a ':'. If there is a '::' then get out, otherwise
+ it is probably a line number. */
+ while (*argptr && !hasColon)
+ {
+ hasColon = (*argptr == ':');
+ argptr++;
+ }
+
+ if (hasColon)
+ badInput = (*argptr == ':'); /* we have class::method */
+ else
+ badInput = !isdigit (*arg); /* not a line number */
+ }
+
+ if (badInput)
+ printf_filtered ("Usage: stop at <line>\n");
+ else
+ break_command_1 (arg, 0, from_tty);
+}
+
+/* ARGSUSED */
+/* accessflag: hw_write: watch write,
+ hw_read: watch read,
+ hw_access: watch access (read or write) */
+static void
+watch_command_1 (char *arg, int accessflag, int from_tty)
+{
+ struct breakpoint *b;
+ struct symtab_and_line sal;
+ struct expression *exp;
+ struct block *exp_valid_block;
+ struct value *val, *mark;
+ struct frame_info *frame;
+ struct frame_info *prev_frame = NULL;
+ char *exp_start = NULL;
+ char *exp_end = NULL;
+ char *tok, *end_tok;
+ int toklen;
+ char *cond_start = NULL;
+ char *cond_end = NULL;
+ struct expression *cond = NULL;
+ int i, other_type_used, target_resources_ok = 0;
+ enum bptype bp_type;
+ int mem_cnt = 0;
+
+ INIT_SAL (&sal); /* initialize to zeroes */
+
+ /* Parse arguments. */
+ innermost_block = NULL;
+ exp_start = arg;
+ exp = parse_exp_1 (&arg, 0, 0);
+ exp_end = arg;
+ exp_valid_block = innermost_block;
+ mark = value_mark ();
+ val = evaluate_expression (exp);
+ release_value (val);
+ if (VALUE_LAZY (val))
+ value_fetch_lazy (val);
+
+ tok = arg;
+ while (*tok == ' ' || *tok == '\t')
+ tok++;
+ end_tok = tok;
+
+ while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000')
+ end_tok++;
+
+ toklen = end_tok - tok;
+ if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
+ {
+ tok = cond_start = end_tok + 1;
+ cond = parse_exp_1 (&tok, 0, 0);
+ cond_end = tok;
+ }
+ if (*tok)
+ error ("Junk at end of command.");
+
+ if (accessflag == hw_read)
+ bp_type = bp_read_watchpoint;
+ else if (accessflag == hw_access)
+ bp_type = bp_access_watchpoint;
+ else
+ bp_type = bp_hardware_watchpoint;
+
+ mem_cnt = can_use_hardware_watchpoint (val);
+ if (mem_cnt == 0 && bp_type != bp_hardware_watchpoint)
+ error ("Expression cannot be implemented with read/access watchpoint.");
+ if (mem_cnt != 0)
+ {
+ i = hw_watchpoint_used_count (bp_type, &other_type_used);
+ target_resources_ok =
+ TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_type, i + mem_cnt,
+ other_type_used);
+ if (target_resources_ok == 0 && bp_type != bp_hardware_watchpoint)
+ error ("Target does not support this type of hardware watchpoint.");
+
+ if (target_resources_ok < 0 && bp_type != bp_hardware_watchpoint)
+ error ("Target can only support one kind of HW watchpoint at a time.");
+ }
+
+#if defined(HPUXHPPA)
+ /* On HP-UX if you set a h/w
+ watchpoint before the "run" command, the inferior dies with a e.g.,
+ SIGILL once you start it. I initially believed this was due to a
+ bad interaction between page protection traps and the initial
+ startup sequence by the dynamic linker.
+
+ However, I tried avoiding that by having HP-UX's implementation of
+ TARGET_CAN_USE_HW_WATCHPOINT return FALSE if there was no inferior_ptid
+ yet, which forced slow watches before a "run" or "attach", and it
+ still fails somewhere in the startup code.
+
+ Until I figure out what's happening, I'm disallowing watches altogether
+ before the "run" or "attach" command. We'll tell the user they must
+ set watches after getting the program started. */
+ if (!target_has_execution)
+ {
+ warning ("can't do that without a running program; try \"break main\", \"run\" first");
+ return;
+ }
+#endif /* HPUXHPPA */
+
+ /* Change the type of breakpoint to an ordinary watchpoint if a hardware
+ watchpoint could not be set. */
+ if (!mem_cnt || target_resources_ok <= 0)
+ bp_type = bp_watchpoint;
+
+ /* Now set up the breakpoint. */
+ b = set_raw_breakpoint (sal, bp_type);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+ b->disposition = disp_donttouch;
+ b->exp = exp;
+ b->exp_valid_block = exp_valid_block;
+ b->exp_string = savestring (exp_start, exp_end - exp_start);
+ b->val = val;
+ b->cond = cond;
+ if (cond_start)
+ b->cond_string = savestring (cond_start, cond_end - cond_start);
+ else
+ b->cond_string = 0;
+
+ frame = block_innermost_frame (exp_valid_block);
+ if (frame)
+ {
+ prev_frame = get_prev_frame (frame);
+ b->watchpoint_frame = frame->frame;
+ }
+ else
+ b->watchpoint_frame = (CORE_ADDR) 0;
+
+ /* If the expression is "local", then set up a "watchpoint scope"
+ breakpoint at the point where we've left the scope of the watchpoint
+ expression. */
+ if (innermost_block)
+ {
+ if (prev_frame)
+ {
+ struct breakpoint *scope_breakpoint;
+ struct symtab_and_line scope_sal;
+
+ INIT_SAL (&scope_sal); /* initialize to zeroes */
+ scope_sal.pc = get_frame_pc (prev_frame);
+ scope_sal.section = find_pc_overlay (scope_sal.pc);
+
+ scope_breakpoint = set_raw_breakpoint (scope_sal,
+ bp_watchpoint_scope);
+ set_breakpoint_count (breakpoint_count + 1);
+ scope_breakpoint->number = breakpoint_count;
+
+ scope_breakpoint->enable_state = bp_enabled;
+
+ /* Automatically delete the breakpoint when it hits. */
+ scope_breakpoint->disposition = disp_del;
+
+ /* Only break in the proper frame (help with recursion). */
+ scope_breakpoint->frame = prev_frame->frame;
+
+ /* Set the address at which we will stop. */
+ scope_breakpoint->address = get_frame_pc (prev_frame);
+
+ /* The scope breakpoint is related to the watchpoint. We
+ will need to act on them together. */
+ b->related_breakpoint = scope_breakpoint;
+ }
+ }
+ value_free_to_mark (mark);
+ mention (b);
+}
+
+/* Return count of locations need to be watched and can be handled
+ in hardware. If the watchpoint can not be handled
+ in hardware return zero. */
+
+#if !defined(TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT)
+#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(BYTE_SIZE) \
+ ((BYTE_SIZE) <= (REGISTER_SIZE))
+#endif
+
+#if !defined(TARGET_REGION_OK_FOR_HW_WATCHPOINT)
+#define TARGET_REGION_OK_FOR_HW_WATCHPOINT(ADDR,LEN) \
+ (TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(LEN))
+#endif
+
+static int
+can_use_hardware_watchpoint (struct value *v)
+{
+ int found_memory_cnt = 0;
+ struct value *head = v;
+
+ /* Did the user specifically forbid us to use hardware watchpoints? */
+ if (!can_use_hw_watchpoints)
+ return 0;
+
+ /* Make sure that the value of the expression depends only upon
+ memory contents, and values computed from them within GDB. If we
+ find any register references or function calls, we can't use a
+ hardware watchpoint.
+
+ The idea here is that evaluating an expression generates a series
+ of values, one holding the value of every subexpression. (The
+ expression a*b+c has five subexpressions: a, b, a*b, c, and
+ a*b+c.) GDB's values hold almost enough information to establish
+ the criteria given above --- they identify memory lvalues,
+ register lvalues, computed values, etcetera. So we can evaluate
+ the expression, and then scan the chain of values that leaves
+ behind to decide whether we can detect any possible change to the
+ expression's final value using only hardware watchpoints.
+
+ However, I don't think that the values returned by inferior
+ function calls are special in any way. So this function may not
+ notice that an expression involving an inferior function call
+ can't be watched with hardware watchpoints. FIXME. */
+ for (; v; v = v->next)
+ {
+ if (VALUE_LVAL (v) == lval_memory)
+ {
+ if (VALUE_LAZY (v))
+ /* A lazy memory lvalue is one that GDB never needed to fetch;
+ we either just used its address (e.g., `a' in `a.b') or
+ we never needed it at all (e.g., `a' in `a,b'). */
+ ;
+ else
+ {
+ /* Ahh, memory we actually used! Check if we can cover
+ it with hardware watchpoints. */
+ struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+ /* We only watch structs and arrays if user asked for it
+ explicitly, never if they just happen to appear in a
+ middle of some value chain. */
+ if (v == head
+ || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+ && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+ {
+ CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+ int len = TYPE_LENGTH (VALUE_TYPE (v));
+
+ if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len))
+ return 0;
+ else
+ found_memory_cnt++;
+ }
+ }
+ }
+ else if (v->lval != not_lval && v->modifiable == 0)
+ return 0; /* ??? What does this represent? */
+ else if (v->lval == lval_register)
+ return 0; /* cannot watch a register with a HW watchpoint */
+ }
+
+ /* The expression itself looks suitable for using a hardware
+ watchpoint, but give the target machine a chance to reject it. */
+ return found_memory_cnt;
+}
+
+void
+watch_command_wrapper (char *arg, int from_tty)
+{
+ watch_command (arg, from_tty);
+}
+
+static void
+watch_command (char *arg, int from_tty)
+{
+ watch_command_1 (arg, hw_write, from_tty);
+}
+
+void
+rwatch_command_wrapper (char *arg, int from_tty)
+{
+ rwatch_command (arg, from_tty);
+}
+
+static void
+rwatch_command (char *arg, int from_tty)
+{
+ watch_command_1 (arg, hw_read, from_tty);
+}
+
+void
+awatch_command_wrapper (char *arg, int from_tty)
+{
+ awatch_command (arg, from_tty);
+}
+
+static void
+awatch_command (char *arg, int from_tty)
+{
+ watch_command_1 (arg, hw_access, from_tty);
+}
+
+
+/* Helper routines for the until_command routine in infcmd.c. Here
+ because it uses the mechanisms of breakpoints. */
+
+/* This function is called by fetch_inferior_event via the
+ cmd_continuation pointer, to complete the until command. It takes
+ care of cleaning up the temporary breakpoints set up by the until
+ command. */
+static void
+until_break_command_continuation (struct continuation_arg *arg)
+{
+ struct cleanup *cleanups;
+
+ cleanups = (struct cleanup *) arg->data.pointer;
+ do_exec_cleanups (cleanups);
+}
+
+/* ARGSUSED */
+void
+until_break_command (char *arg, int from_tty)
+{
+ struct symtabs_and_lines sals;
+ struct symtab_and_line sal;
+ struct frame_info *prev_frame = get_prev_frame (selected_frame);
+ struct breakpoint *breakpoint;
+ struct cleanup *old_chain;
+ struct continuation_arg *arg1;
+
+
+ clear_proceed_status ();
+
+ /* Set a breakpoint where the user wants it and at return from
+ this function */
+
+ if (default_breakpoint_valid)
+ sals = decode_line_1 (&arg, 1, default_breakpoint_symtab,
+ default_breakpoint_line, (char ***) NULL);
+ else
+ sals = decode_line_1 (&arg, 1, (struct symtab *) NULL,
+ 0, (char ***) NULL);
+
+ if (sals.nelts != 1)
+ error ("Couldn't get information on specified line.");
+
+ sal = sals.sals[0];
+ xfree (sals.sals); /* malloc'd, so freed */
+
+ if (*arg)
+ error ("Junk at end of arguments.");
+
+ resolve_sal_pc (&sal);
+
+ breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until);
+
+ if (!event_loop_p || !target_can_async_p ())
+ old_chain = make_cleanup_delete_breakpoint (breakpoint);
+ else
+ old_chain = make_exec_cleanup_delete_breakpoint (breakpoint);
+
+ /* If we are running asynchronously, and the target supports async
+ execution, we are not waiting for the target to stop, in the call
+ tp proceed, below. This means that we cannot delete the
+ brekpoints until the target has actually stopped. The only place
+ where we get a chance to do that is in fetch_inferior_event, so
+ we must set things up for that. */
+
+ if (event_loop_p && target_can_async_p ())
+ {
+ /* In this case the arg for the continuation is just the point
+ in the exec_cleanups chain from where to start doing
+ cleanups, because all the continuation does is the cleanups in
+ the exec_cleanup_chain. */
+ arg1 =
+ (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+ arg1->next = NULL;
+ arg1->data.pointer = old_chain;
+
+ add_continuation (until_break_command_continuation, arg1);
+ }
+
+ /* Keep within the current frame */
+
+ if (prev_frame)
+ {
+ sal = find_pc_line (prev_frame->pc, 0);
+ sal.pc = prev_frame->pc;
+ breakpoint = set_momentary_breakpoint (sal, prev_frame, bp_until);
+ if (!event_loop_p || !target_can_async_p ())
+ make_cleanup_delete_breakpoint (breakpoint);
+ else
+ make_exec_cleanup_delete_breakpoint (breakpoint);
+ }
+
+ proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
+ /* Do the cleanups now, anly if we are not running asynchronously,
+ of if we are, but the target is still synchronous. */
+ if (!event_loop_p || !target_can_async_p ())
+ do_cleanups (old_chain);
+}
+
+#if 0
+/* These aren't used; I don't konw what they were for. */
+/* Set a breakpoint at the catch clause for NAME. */
+static int
+catch_breakpoint (char *name)
+{
+}
+
+static int
+disable_catch_breakpoint (void)
+{
+}
+
+static int
+delete_catch_breakpoint (void)
+{
+}
+
+static int
+enable_catch_breakpoint (void)
+{
+}
+#endif /* 0 */
+
+struct sal_chain
+{
+ struct sal_chain *next;
+ struct symtab_and_line sal;
+};
+
+#if 0
+/* Not really used -- invocation in handle_gnu_4_16_catch_command
+ had been commented out in the v.4.16 sources, and stays
+ disabled there now because "catch NAME" syntax isn't allowed.
+ pai/1997-07-11 */
+/* This isn't used; I don't know what it was for. */
+/* For each catch clause identified in ARGS, run FUNCTION
+ with that clause as an argument. */
+static struct symtabs_and_lines
+map_catch_names (char *args, int (*function) ())
+{
+ register char *p = args;
+ register char *p1;
+ struct symtabs_and_lines sals;
+#if 0
+ struct sal_chain *sal_chain = 0;
+#endif
+
+ if (p == 0)
+ error_no_arg ("one or more catch names");
+
+ sals.nelts = 0;
+ sals.sals = NULL;
+
+ while (*p)
+ {
+ p1 = p;
+ /* Don't swallow conditional part. */
+ if (p1[0] == 'i' && p1[1] == 'f'
+ && (p1[2] == ' ' || p1[2] == '\t'))
+ break;
+
+ if (isalpha (*p1))
+ {
+ p1++;
+ while (isalnum (*p1) || *p1 == '_' || *p1 == '$')
+ p1++;
+ }
+
+ if (*p1 && *p1 != ' ' && *p1 != '\t')
+ error ("Arguments must be catch names.");
+
+ *p1 = 0;
+#if 0
+ if (function (p))
+ {
+ struct sal_chain *next = (struct sal_chain *)
+ alloca (sizeof (struct sal_chain));
+ next->next = sal_chain;
+ next->sal = get_catch_sal (p);
+ sal_chain = next;
+ goto win;
+ }
+#endif
+ printf_unfiltered ("No catch clause for exception %s.\n", p);
+#if 0
+ win:
+#endif
+ p = p1;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ }
+}
+#endif
+
+/* This shares a lot of code with `print_frame_label_vars' from stack.c. */
+
+static struct symtabs_and_lines
+get_catch_sals (int this_level_only)
+{
+ register struct blockvector *bl;
+ register struct block *block;
+ int index, have_default = 0;
+ CORE_ADDR pc;
+ struct symtabs_and_lines sals;
+ struct sal_chain *sal_chain = 0;
+ char *blocks_searched;
+
+ /* Not sure whether an error message is always the correct response,
+ but it's better than a core dump. */
+ if (selected_frame == NULL)
+ error ("No selected frame.");
+ block = get_frame_block (selected_frame, 0);
+ pc = selected_frame->pc;
+
+ sals.nelts = 0;
+ sals.sals = NULL;
+
+ if (block == 0)
+ error ("No symbol table info available.\n");
+
+ bl = blockvector_for_pc (BLOCK_END (block) - 4, &index);
+ blocks_searched = (char *) alloca (BLOCKVECTOR_NBLOCKS (bl) * sizeof (char));
+ memset (blocks_searched, 0, BLOCKVECTOR_NBLOCKS (bl) * sizeof (char));
+
+ while (block != 0)
+ {
+ CORE_ADDR end = BLOCK_END (block) - 4;
+ int last_index;
+
+ if (bl != blockvector_for_pc (end, &index))
+ error ("blockvector blotch");
+ if (BLOCKVECTOR_BLOCK (bl, index) != block)
+ error ("blockvector botch");
+ last_index = BLOCKVECTOR_NBLOCKS (bl);
+ index += 1;
+
+ /* Don't print out blocks that have gone by. */
+ while (index < last_index
+ && BLOCK_END (BLOCKVECTOR_BLOCK (bl, index)) < pc)
+ index++;
+
+ while (index < last_index
+ && BLOCK_END (BLOCKVECTOR_BLOCK (bl, index)) < end)
+ {
+ if (blocks_searched[index] == 0)
+ {
+ struct block *b = BLOCKVECTOR_BLOCK (bl, index);
+ register int i;
+ register struct symbol *sym;
+
+ ALL_BLOCK_SYMBOLS (b, i, sym)
+ {
+ if (STREQ (SYMBOL_NAME (sym), "default"))
+ {
+ if (have_default)
+ continue;
+ have_default = 1;
+ }
+ if (SYMBOL_CLASS (sym) == LOC_LABEL)
+ {
+ struct sal_chain *next = (struct sal_chain *)
+ alloca (sizeof (struct sal_chain));
+ next->next = sal_chain;
+ next->sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym),
+ 0);
+ sal_chain = next;
+ }
+ }
+ blocks_searched[index] = 1;
+ }
+ index++;
+ }
+ if (have_default)
+ break;
+ if (sal_chain && this_level_only)
+ break;
+
+ /* After handling the function's top-level block, stop.
+ Don't continue to its superblock, the block of
+ per-file symbols. */
+ if (BLOCK_FUNCTION (block))
+ break;
+ block = BLOCK_SUPERBLOCK (block);
+ }
+
+ if (sal_chain)
+ {
+ struct sal_chain *tmp_chain;
+
+ /* Count the number of entries. */
+ for (index = 0, tmp_chain = sal_chain; tmp_chain;
+ tmp_chain = tmp_chain->next)
+ index++;
+
+ sals.nelts = index;
+ sals.sals = (struct symtab_and_line *)
+ xmalloc (index * sizeof (struct symtab_and_line));
+ for (index = 0; sal_chain; sal_chain = sal_chain->next, index++)
+ sals.sals[index] = sal_chain->sal;
+ }
+
+ return sals;
+}
+
+static void
+ep_skip_leading_whitespace (char **s)
+{
+ if ((s == NULL) || (*s == NULL))
+ return;
+ while (isspace (**s))
+ *s += 1;
+}
+
+/* This function examines a string, and attempts to find a token
+ that might be an event name in the leading characters. If a
+ possible match is found, a pointer to the last character of
+ the token is returned. Else, NULL is returned. */
+
+static char *
+ep_find_event_name_end (char *arg)
+{
+ char *s = arg;
+ char *event_name_end = NULL;
+
+ /* If we could depend upon the presense of strrpbrk, we'd use that... */
+ if (arg == NULL)
+ return NULL;
+
+ /* We break out of the loop when we find a token delimiter.
+ Basically, we're looking for alphanumerics and underscores;
+ anything else delimites the token. */
+ while (*s != '\0')
+ {
+ if (!isalnum (*s) && (*s != '_'))
+ break;
+ event_name_end = s;
+ s++;
+ }
+
+ return event_name_end;
+}
+
+
+/* This function attempts to parse an optional "if <cond>" clause
+ from the arg string. If one is not found, it returns NULL.
+
+ Else, it returns a pointer to the condition string. (It does not
+ attempt to evaluate the string against a particular block.) And,
+ it updates arg to point to the first character following the parsed
+ if clause in the arg string. */
+
+static char *
+ep_parse_optional_if_clause (char **arg)
+{
+ char *cond_string;
+
+ if (((*arg)[0] != 'i') || ((*arg)[1] != 'f') || !isspace ((*arg)[2]))
+ return NULL;
+
+ /* Skip the "if" keyword. */
+ (*arg) += 2;
+
+ /* Skip any extra leading whitespace, and record the start of the
+ condition string. */
+ ep_skip_leading_whitespace (arg);
+ cond_string = *arg;
+
+ /* Assume that the condition occupies the remainder of the arg string. */
+ (*arg) += strlen (cond_string);
+
+ return cond_string;
+}
+
+/* This function attempts to parse an optional filename from the arg
+ string. If one is not found, it returns NULL.
+
+ Else, it returns a pointer to the parsed filename. (This function
+ makes no attempt to verify that a file of that name exists, or is
+ accessible.) And, it updates arg to point to the first character
+ following the parsed filename in the arg string.
+
+ Note that clients needing to preserve the returned filename for
+ future access should copy it to their own buffers. */
+static char *
+ep_parse_optional_filename (char **arg)
+{
+ static char filename[1024];
+ char *arg_p = *arg;
+ int i;
+ char c;
+
+ if ((*arg_p == '\0') || isspace (*arg_p))
+ return NULL;
+
+ for (i = 0;; i++)
+ {
+ c = *arg_p;
+ if (isspace (c))
+ c = '\0';
+ filename[i] = c;
+ if (c == '\0')
+ break;
+ arg_p++;
+ }
+ *arg = arg_p;
+
+ return filename;
+}
+
+/* Commands to deal with catching events, such as signals, exceptions,
+ process start/exit, etc. */
+
+typedef enum
+{
+ catch_fork, catch_vfork
+}
+catch_fork_kind;
+
+#if defined(CHILD_INSERT_FORK_CATCHPOINT) || defined(CHILD_INSERT_VFORK_CATCHPOINT)
+static void catch_fork_command_1 (catch_fork_kind fork_kind,
+ char *arg, int tempflag, int from_tty);
+
+static void
+catch_fork_command_1 (catch_fork_kind fork_kind, char *arg, int tempflag,
+ int from_tty)
+{
+ char *cond_string = NULL;
+
+ ep_skip_leading_whitespace (&arg);
+
+ /* The allowed syntax is:
+ catch [v]fork
+ catch [v]fork if <cond>
+
+ First, check if there's an if clause. */
+ cond_string = ep_parse_optional_if_clause (&arg);
+
+ if ((*arg != '\0') && !isspace (*arg))
+ error ("Junk at end of arguments.");
+
+ /* If this target supports it, create a fork or vfork catchpoint
+ and enable reporting of such events. */
+ switch (fork_kind)
+ {
+ case catch_fork:
+ create_fork_event_catchpoint (tempflag, cond_string);
+ break;
+ case catch_vfork:
+ create_vfork_event_catchpoint (tempflag, cond_string);
+ break;
+ default:
+ error ("unsupported or unknown fork kind; cannot catch it");
+ break;
+ }
+}
+#endif
+
+#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
+static void
+catch_exec_command_1 (char *arg, int tempflag, int from_tty)
+{
+ char *cond_string = NULL;
+
+ ep_skip_leading_whitespace (&arg);
+
+ /* The allowed syntax is:
+ catch exec
+ catch exec if <cond>
+
+ First, check if there's an if clause. */
+ cond_string = ep_parse_optional_if_clause (&arg);
+
+ if ((*arg != '\0') && !isspace (*arg))
+ error ("Junk at end of arguments.");
+
+ /* If this target supports it, create an exec catchpoint
+ and enable reporting of such events. */
+ create_exec_event_catchpoint (tempflag, cond_string);
+}
+#endif
+
+#if defined(SOLIB_ADD)
+static void
+catch_load_command_1 (char *arg, int tempflag, int from_tty)
+{
+ char *dll_pathname = NULL;
+ char *cond_string = NULL;
+
+ ep_skip_leading_whitespace (&arg);
+
+ /* The allowed syntax is:
+ catch load
+ catch load if <cond>
+ catch load <filename>
+ catch load <filename> if <cond>
+
+ The user is not allowed to specify the <filename> after an
+ if clause.
+
+ We'll ignore the pathological case of a file named "if".
+
+ First, check if there's an if clause. If so, then there
+ cannot be a filename. */
+ cond_string = ep_parse_optional_if_clause (&arg);
+
+ /* If there was an if clause, then there cannot be a filename.
+ Else, there might be a filename and an if clause. */
+ if (cond_string == NULL)
+ {
+ dll_pathname = ep_parse_optional_filename (&arg);
+ ep_skip_leading_whitespace (&arg);
+ cond_string = ep_parse_optional_if_clause (&arg);
+ }
+
+ if ((*arg != '\0') && !isspace (*arg))
+ error ("Junk at end of arguments.");
+
+ /* Create a load breakpoint that only triggers when a load of
+ the specified dll (or any dll, if no pathname was specified)
+ occurs. */
+ SOLIB_CREATE_CATCH_LOAD_HOOK (PIDGET (inferior_ptid), tempflag,
+ dll_pathname, cond_string);
+}
+
+static void
+catch_unload_command_1 (char *arg, int tempflag, int from_tty)
+{
+ char *dll_pathname = NULL;
+ char *cond_string = NULL;
+
+ ep_skip_leading_whitespace (&arg);
+
+ /* The allowed syntax is:
+ catch unload
+ catch unload if <cond>
+ catch unload <filename>
+ catch unload <filename> if <cond>
+
+ The user is not allowed to specify the <filename> after an
+ if clause.
+
+ We'll ignore the pathological case of a file named "if".
+
+ First, check if there's an if clause. If so, then there
+ cannot be a filename. */
+ cond_string = ep_parse_optional_if_clause (&arg);
+
+ /* If there was an if clause, then there cannot be a filename.
+ Else, there might be a filename and an if clause. */
+ if (cond_string == NULL)
+ {
+ dll_pathname = ep_parse_optional_filename (&arg);
+ ep_skip_leading_whitespace (&arg);
+ cond_string = ep_parse_optional_if_clause (&arg);
+ }
+
+ if ((*arg != '\0') && !isspace (*arg))
+ error ("Junk at end of arguments.");
+
+ /* Create an unload breakpoint that only triggers when an unload of
+ the specified dll (or any dll, if no pathname was specified)
+ occurs. */
+ SOLIB_CREATE_CATCH_UNLOAD_HOOK (PIDGET (inferior_ptid), tempflag,
+ dll_pathname, cond_string);
+}
+#endif /* SOLIB_ADD */
+
+/* Commands to deal with catching exceptions. */
+
+/* Set a breakpoint at the specified callback routine for an
+ exception event callback */
+
+static void
+create_exception_catchpoint (int tempflag, char *cond_string,
+ enum exception_event_kind ex_event,
+ struct symtab_and_line *sal)
+{
+ struct breakpoint *b;
+ int thread = -1; /* All threads. */
+ enum bptype bptype;
+
+ if (!sal) /* no exception support? */
+ return;
+
+ switch (ex_event)
+ {
+ case EX_EVENT_THROW:
+ bptype = bp_catch_throw;
+ break;
+ case EX_EVENT_CATCH:
+ bptype = bp_catch_catch;
+ break;
+ default: /* error condition */
+ error ("Internal error -- invalid catchpoint kind");
+ }
+
+ b = set_raw_breakpoint (*sal, bptype);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+ b->cond = NULL;
+ b->cond_string = (cond_string == NULL) ?
+ NULL : savestring (cond_string, strlen (cond_string));
+ b->thread = thread;
+ b->addr_string = NULL;
+ b->enable_state = bp_enabled;
+ b->disposition = tempflag ? disp_del : disp_donttouch;
+ mention (b);
+}
+
+/* Deal with "catch catch" and "catch throw" commands */
+
+static void
+catch_exception_command_1 (enum exception_event_kind ex_event, char *arg,
+ int tempflag, int from_tty)
+{
+ char *cond_string = NULL;
+ struct symtab_and_line *sal = NULL;
+
+ ep_skip_leading_whitespace (&arg);
+
+ cond_string = ep_parse_optional_if_clause (&arg);
+
+ if ((*arg != '\0') && !isspace (*arg))
+ error ("Junk at end of arguments.");
+
+ if ((ex_event != EX_EVENT_THROW) &&
+ (ex_event != EX_EVENT_CATCH))
+ error ("Unsupported or unknown exception event; cannot catch it");
+
+ /* See if we can find a callback routine */
+ sal = target_enable_exception_callback (ex_event, 1);
+
+ if (sal)
+ {
+ /* We have callbacks from the runtime system for exceptions.
+ Set a breakpoint on the sal found, if no errors */
+ if (sal != (struct symtab_and_line *) -1)
+ create_exception_catchpoint (tempflag, cond_string, ex_event, sal);
+ else
+ return; /* something went wrong with setting up callbacks */
+ }
+ else
+ {
+ /* No callbacks from runtime system for exceptions.
+ Try GNU C++ exception breakpoints using labels in debug info. */
+ if (ex_event == EX_EVENT_CATCH)
+ {
+ handle_gnu_4_16_catch_command (arg, tempflag, from_tty);
+ }
+ else if (ex_event == EX_EVENT_THROW)
+ {
+ /* Set a breakpoint on __raise_exception () */
+
+ warning ("Unsupported with this platform/compiler combination.");
+ warning ("Perhaps you can achieve the effect you want by setting");
+ warning ("a breakpoint on __raise_exception().");
+ }
+ }
+}
+
+/* Cover routine to allow wrapping target_enable_exception_catchpoints
+ inside a catch_errors */
+
+static int
+cover_target_enable_exception_callback (PTR arg)
+{
+ args_for_catchpoint_enable *args = arg;
+ struct symtab_and_line *sal;
+ sal = target_enable_exception_callback (args->kind, args->enable_p);
+ if (sal == NULL)
+ return 0;
+ else if (sal == (struct symtab_and_line *) -1)
+ return -1;
+ else
+ return 1; /*is valid */
+}
+
+
+
+/* This is the original v.4.16 and earlier version of the
+ catch_command_1() function. Now that other flavours of "catch"
+ have been introduced, and since exception handling can be handled
+ in other ways (through target ops) also, this is used only for the
+ GNU C++ exception handling system.
+ Note: Only the "catch" flavour of GDB 4.16 is handled here. The
+ "catch NAME" is now no longer allowed in catch_command_1(). Also,
+ there was no code in GDB 4.16 for "catch throw".
+
+ Called from catch_exception_command_1 () */
+
+
+static void
+handle_gnu_4_16_catch_command (char *arg, int tempflag, int from_tty)
+{
+ /* First, translate ARG into something we can deal with in terms
+ of breakpoints. */
+
+ struct symtabs_and_lines sals;
+ struct symtab_and_line sal;
+ register struct expression *cond = 0;
+ register struct breakpoint *b;
+ char *save_arg;
+ int i;
+
+ INIT_SAL (&sal); /* initialize to zeroes */
+
+ /* If no arg given, or if first arg is 'if ', all active catch clauses
+ are breakpointed. */
+
+ if (!arg || (arg[0] == 'i' && arg[1] == 'f'
+ && (arg[2] == ' ' || arg[2] == '\t')))
+ {
+ /* Grab all active catch clauses. */
+ sals = get_catch_sals (0);
+ }
+ else
+ {
+ /* Grab selected catch clauses. */
+ error ("catch NAME not implemented");
+
+#if 0
+ /* Not sure why this code has been disabled. I'm leaving
+ it disabled. We can never come here now anyway
+ since we don't allow the "catch NAME" syntax.
+ pai/1997-07-11 */
+
+ /* This isn't used; I don't know what it was for. */
+ sals = map_catch_names (arg, catch_breakpoint);
+#endif
+ }
+
+ if (!sals.nelts)
+ return;
+
+ save_arg = arg;
+ for (i = 0; i < sals.nelts; i++)
+ {
+ resolve_sal_pc (&sals.sals[i]);
+
+ while (arg && *arg)
+ {
+ if (arg[0] == 'i' && arg[1] == 'f'
+ && (arg[2] == ' ' || arg[2] == '\t'))
+ cond = parse_exp_1 ((arg += 2, &arg),
+ block_for_pc (sals.sals[i].pc), 0);
+ else
+ error ("Junk at end of arguments.");
+ }
+ arg = save_arg;
+ }
+
+ for (i = 0; i < sals.nelts; i++)
+ {
+ sal = sals.sals[i];
+
+ if (from_tty)
+ describe_other_breakpoints (sal.pc, sal.section);
+
+ /* Important -- this is an ordinary breakpoint. For platforms
+ with callback support for exceptions,
+ create_exception_catchpoint() will create special bp types
+ (bp_catch_catch and bp_catch_throw), and there is code in
+ insert_breakpoints() and elsewhere that depends on that. */
+ b = set_raw_breakpoint (sal, bp_breakpoint);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+
+ b->cond = cond;
+ b->enable_state = bp_enabled;
+ b->disposition = tempflag ? disp_del : disp_donttouch;
+
+ mention (b);
+ }
+
+ if (sals.nelts > 1)
+ {
+ warning ("Multiple breakpoints were set.");
+ warning ("Use the \"delete\" command to delete unwanted breakpoints.");
+ }
+ xfree (sals.sals);
+}
+
+static void
+catch_command_1 (char *arg, int tempflag, int from_tty)
+{
+
+ /* The first argument may be an event name, such as "start" or "load".
+ If so, then handle it as such. If it doesn't match an event name,
+ then attempt to interpret it as an exception name. (This latter is
+ the v4.16-and-earlier GDB meaning of the "catch" command.)
+
+ First, try to find the bounds of what might be an event name. */
+ char *arg1_start = arg;
+ char *arg1_end;
+ int arg1_length;
+
+ if (arg1_start == NULL)
+ {
+ /* Old behaviour was to use pre-v-4.16 syntax */
+ /* catch_throw_command_1 (arg1_start, tempflag, from_tty); */
+ /* return; */
+ /* Now, this is not allowed */
+ error ("Catch requires an event name.");
+
+ }
+ arg1_end = ep_find_event_name_end (arg1_start);
+ if (arg1_end == NULL)
+ error ("catch requires an event");
+ arg1_length = arg1_end + 1 - arg1_start;
+
+ /* Try to match what we found against known event names. */
+ if (strncmp (arg1_start, "signal", arg1_length) == 0)
+ {
+ error ("Catch of signal not yet implemented");
+ }
+ else if (strncmp (arg1_start, "catch", arg1_length) == 0)
+ {
+ catch_exception_command_1 (EX_EVENT_CATCH, arg1_end + 1,
+ tempflag, from_tty);
+ }
+ else if (strncmp (arg1_start, "throw", arg1_length) == 0)
+ {
+ catch_exception_command_1 (EX_EVENT_THROW, arg1_end + 1,
+ tempflag, from_tty);
+ }
+ else if (strncmp (arg1_start, "thread_start", arg1_length) == 0)
+ {
+ error ("Catch of thread_start not yet implemented");
+ }
+ else if (strncmp (arg1_start, "thread_exit", arg1_length) == 0)
+ {
+ error ("Catch of thread_exit not yet implemented");
+ }
+ else if (strncmp (arg1_start, "thread_join", arg1_length) == 0)
+ {
+ error ("Catch of thread_join not yet implemented");
+ }
+ else if (strncmp (arg1_start, "start", arg1_length) == 0)
+ {
+ error ("Catch of start not yet implemented");
+ }
+ else if (strncmp (arg1_start, "exit", arg1_length) == 0)
+ {
+ error ("Catch of exit not yet implemented");
+ }
+ else if (strncmp (arg1_start, "fork", arg1_length) == 0)
+ {
+#if defined(CHILD_INSERT_FORK_CATCHPOINT)
+ catch_fork_command_1 (catch_fork, arg1_end + 1, tempflag, from_tty);
+#else
+ error ("Catch of fork not yet implemented");
+#endif
+ }
+ else if (strncmp (arg1_start, "vfork", arg1_length) == 0)
+ {
+#if defined(CHILD_INSERT_VFORK_CATCHPOINT)
+ catch_fork_command_1 (catch_vfork, arg1_end + 1, tempflag, from_tty);
+#else
+ error ("Catch of vfork not yet implemented");
+#endif
+ }
+ else if (strncmp (arg1_start, "exec", arg1_length) == 0)
+ {
+#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
+ catch_exec_command_1 (arg1_end + 1, tempflag, from_tty);
+#else
+ error ("Catch of exec not yet implemented");
+#endif
+ }
+ else if (strncmp (arg1_start, "load", arg1_length) == 0)
+ {
+#if defined(SOLIB_ADD)
+ catch_load_command_1 (arg1_end + 1, tempflag, from_tty);
+#else
+ error ("Catch of load not implemented");
+#endif
+ }
+ else if (strncmp (arg1_start, "unload", arg1_length) == 0)
+ {
+#if defined(SOLIB_ADD)
+ catch_unload_command_1 (arg1_end + 1, tempflag, from_tty);
+#else
+ error ("Catch of load not implemented");
+#endif
+ }
+ else if (strncmp (arg1_start, "stop", arg1_length) == 0)
+ {
+ error ("Catch of stop not yet implemented");
+ }
+
+ /* This doesn't appear to be an event name */
+
+ else
+ {
+ /* Pre-v.4.16 behaviour was to treat the argument
+ as the name of an exception */
+ /* catch_throw_command_1 (arg1_start, tempflag, from_tty); */
+ /* Now this is not allowed */
+ error ("Unknown event kind specified for catch");
+
+ }
+}
+
+/* Used by the gui, could be made a worker for other things. */
+
+struct breakpoint *
+set_breakpoint_sal (struct symtab_and_line sal)
+{
+ struct breakpoint *b;
+ b = set_raw_breakpoint (sal, bp_breakpoint);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+ b->cond = 0;
+ b->thread = -1;
+ return b;
+}
+
+#if 0
+/* These aren't used; I don't know what they were for. */
+/* Disable breakpoints on all catch clauses described in ARGS. */
+static void
+disable_catch (char *args)
+{
+ /* Map the disable command to catch clauses described in ARGS. */
+}
+
+/* Enable breakpoints on all catch clauses described in ARGS. */
+static void
+enable_catch (char *args)
+{
+ /* Map the disable command to catch clauses described in ARGS. */
+}
+
+/* Delete breakpoints on all catch clauses in the active scope. */
+static void
+delete_catch (char *args)
+{
+ /* Map the delete command to catch clauses described in ARGS. */
+}
+#endif /* 0 */
+
+static void
+catch_command (char *arg, int from_tty)
+{
+ catch_command_1 (arg, 0, from_tty);
+}
+
+
+static void
+tcatch_command (char *arg, int from_tty)
+{
+ catch_command_1 (arg, 1, from_tty);
+}
+
+/* Delete breakpoints by address or line. */
+
+static void
+clear_command (char *arg, int from_tty)
+{
+ struct breakpoint *b, *tmp, *prev, *found;
+ int default_match;
+ struct symtabs_and_lines sals;
+ struct symtab_and_line sal;
+ int i;
+
+ if (arg)
+ {
+ sals = decode_line_spec (arg, 1);
+ default_match = 0;
+ }
+ else
+ {
+ sals.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ make_cleanup (xfree, sals.sals);
+ INIT_SAL (&sal); /* initialize to zeroes */
+ sal.line = default_breakpoint_line;
+ sal.symtab = default_breakpoint_symtab;
+ sal.pc = default_breakpoint_address;
+ if (sal.symtab == 0)
+ error ("No source file specified.");
+
+ sals.sals[0] = sal;
+ sals.nelts = 1;
+
+ default_match = 1;
+ }
+
+ /* For each line spec given, delete bps which correspond
+ to it. Do it in two passes, solely to preserve the current
+ behavior that from_tty is forced true if we delete more than
+ one breakpoint. */
+
+ found = NULL;
+ for (i = 0; i < sals.nelts; i++)
+ {
+ /* If exact pc given, clear bpts at that pc.
+ If line given (pc == 0), clear all bpts on specified line.
+ If defaulting, clear all bpts on default line
+ or at default pc.
+
+ defaulting sal.pc != 0 tests to do
+
+ 0 1 pc
+ 1 1 pc _and_ line
+ 0 0 line
+ 1 0 <can't happen> */
+
+ sal = sals.sals[i];
+ prev = NULL;
+
+ /* Find all matching breakpoints, remove them from the
+ breakpoint chain, and add them to the 'found' chain. */
+ ALL_BREAKPOINTS_SAFE (b, tmp)
+ {
+ /* Are we going to delete b? */
+ if (b->type != bp_none
+ && b->type != bp_watchpoint
+ && b->type != bp_hardware_watchpoint
+ && b->type != bp_read_watchpoint
+ && b->type != bp_access_watchpoint
+ /* Not if b is a watchpoint of any sort... */
+ && (((sal.pc && (b->address == sal.pc))
+ && (!section_is_overlay (b->section)
+ || b->section == sal.section))
+ /* Yes, if sal.pc matches b (modulo overlays). */
+ || ((default_match || (0 == sal.pc))
+ && b->source_file != NULL
+ && sal.symtab != NULL
+ && STREQ (b->source_file, sal.symtab->filename)
+ && b->line_number == sal.line)))
+ /* Yes, if sal source file and line matches b. */
+ {
+ /* Remove it from breakpoint_chain... */
+ if (b == breakpoint_chain)
+ {
+ /* b is at the head of the list */
+ breakpoint_chain = b->next;
+ }
+ else
+ {
+ prev->next = b->next;
+ }
+ /* And add it to 'found' chain. */
+ b->next = found;
+ found = b;
+ }
+ else
+ {
+ /* Keep b, and keep a pointer to it. */
+ prev = b;
+ }
+ }
+ }
+ /* Now go thru the 'found' chain and delete them. */
+ if (found == 0)
+ {
+ if (arg)
+ error ("No breakpoint at %s.", arg);
+ else
+ error ("No breakpoint at this line.");
+ }
+
+ if (found->next)
+ from_tty = 1; /* Always report if deleted more than one */
+ if (from_tty)
+ printf_unfiltered ("Deleted breakpoint%s ", found->next ? "s" : "");
+ breakpoints_changed ();
+ while (found)
+ {
+ if (from_tty)
+ printf_unfiltered ("%d ", found->number);
+ tmp = found->next;
+ delete_breakpoint (found);
+ found = tmp;
+ }
+ if (from_tty)
+ putchar_unfiltered ('\n');
+}
+
+/* Delete breakpoint in BS if they are `delete' breakpoints and
+ all breakpoints that are marked for deletion, whether hit or not.
+ This is called after any breakpoint is hit, or after errors. */
+
+void
+breakpoint_auto_delete (bpstat bs)
+{
+ struct breakpoint *b, *temp;
+
+ for (; bs; bs = bs->next)
+ if (bs->breakpoint_at && bs->breakpoint_at->disposition == disp_del
+ && bs->stop)
+ delete_breakpoint (bs->breakpoint_at);
+
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ {
+ if (b->disposition == disp_del_at_next_stop)
+ delete_breakpoint (b);
+ }
+}
+
+/* Delete a breakpoint and clean up all traces of it in the data
+ structures. */
+
+void
+delete_breakpoint (struct breakpoint *bpt)
+{
+ register struct breakpoint *b;
+ register bpstat bs;
+
+ if (bpt == NULL)
+ error ("Internal error (attempted to delete a NULL breakpoint)");
+
+
+ /* Has this bp already been deleted? This can happen because multiple
+ lists can hold pointers to bp's. bpstat lists are especial culprits.
+
+ One example of this happening is a watchpoint's scope bp. When the
+ scope bp triggers, we notice that the watchpoint is out of scope, and
+ delete it. We also delete its scope bp. But the scope bp is marked
+ "auto-deleting", and is already on a bpstat. That bpstat is then
+ checked for auto-deleting bp's, which are deleted.
+
+ A real solution to this problem might involve reference counts in bp's,
+ and/or giving them pointers back to their referencing bpstat's, and
+ teaching delete_breakpoint to only free a bp's storage when no more
+ references were extent. A cheaper bandaid was chosen. */
+ if (bpt->type == bp_none)
+ return;
+
+ if (delete_breakpoint_hook)
+ delete_breakpoint_hook (bpt);
+ breakpoint_delete_event (bpt->number);
+
+ if (bpt->inserted)
+ remove_breakpoint (bpt, mark_inserted);
+
+ if (breakpoint_chain == bpt)
+ breakpoint_chain = bpt->next;
+
+ /* If we have callback-style exception catchpoints, don't go through
+ the adjustments to the C++ runtime library etc. if the inferior
+ isn't actually running. target_enable_exception_callback for a
+ null target ops vector gives an undesirable error message, so we
+ check here and avoid it. Since currently (1997-09-17) only HP-UX aCC's
+ exceptions are supported in this way, it's OK for now. FIXME */
+ if (ep_is_exception_catchpoint (bpt) && target_has_execution)
+ {
+ static char message1[] = "Error in deleting catchpoint %d:\n";
+ static char message[sizeof (message1) + 30];
+ args_for_catchpoint_enable args;
+
+ /* Format possible error msg */
+ sprintf (message, message1, bpt->number);
+ args.kind = bpt->type == bp_catch_catch ?
+ EX_EVENT_CATCH : EX_EVENT_THROW;
+ args.enable_p = 0;
+ catch_errors (cover_target_enable_exception_callback, &args,
+ message, RETURN_MASK_ALL);
+ }
+
+
+ ALL_BREAKPOINTS (b)
+ if (b->next == bpt)
+ {
+ b->next = bpt->next;
+ break;
+ }
+
+ check_duplicates (bpt);
+ /* If this breakpoint was inserted, and there is another breakpoint
+ at the same address, we need to insert the other breakpoint. */
+ if (bpt->inserted
+ && bpt->type != bp_hardware_watchpoint
+ && bpt->type != bp_read_watchpoint
+ && bpt->type != bp_access_watchpoint
+ && bpt->type != bp_catch_fork
+ && bpt->type != bp_catch_vfork
+ && bpt->type != bp_catch_exec)
+ {
+ ALL_BREAKPOINTS (b)
+ if (b->address == bpt->address
+ && b->section == bpt->section
+ && !b->duplicate
+ && b->enable_state != bp_disabled
+ && b->enable_state != bp_shlib_disabled
+ && b->enable_state != bp_call_disabled)
+ {
+ int val;
+
+ /* We should never reach this point if there is a permanent
+ breakpoint at the same address as the one being deleted.
+ If there is a permanent breakpoint somewhere, it should
+ always be the only one inserted. */
+ if (b->enable_state == bp_permanent)
+ internal_error (__FILE__, __LINE__,
+ "another breakpoint was inserted on top of "
+ "a permanent breakpoint");
+
+ if (b->type == bp_hardware_breakpoint)
+ val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
+ else
+ val = target_insert_breakpoint (b->address, b->shadow_contents);
+
+ if (val != 0)
+ {
+ target_terminal_ours_for_output ();
+ warning ("Cannot insert breakpoint %d:", b->number);
+ memory_error (val, b->address); /* which bombs us out */
+ }
+ else
+ b->inserted = 1;
+ }
+ }
+
+ free_command_lines (&bpt->commands);
+ if (bpt->cond)
+ xfree (bpt->cond);
+ if (bpt->cond_string != NULL)
+ xfree (bpt->cond_string);
+ if (bpt->addr_string != NULL)
+ xfree (bpt->addr_string);
+ if (bpt->exp != NULL)
+ xfree (bpt->exp);
+ if (bpt->exp_string != NULL)
+ xfree (bpt->exp_string);
+ if (bpt->val != NULL)
+ value_free (bpt->val);
+ if (bpt->source_file != NULL)
+ xfree (bpt->source_file);
+ if (bpt->dll_pathname != NULL)
+ xfree (bpt->dll_pathname);
+ if (bpt->triggered_dll_pathname != NULL)
+ xfree (bpt->triggered_dll_pathname);
+ if (bpt->exec_pathname != NULL)
+ xfree (bpt->exec_pathname);
+
+ /* Be sure no bpstat's are pointing at it after it's been freed. */
+ /* FIXME, how can we find all bpstat's?
+ We just check stop_bpstat for now. */
+ for (bs = stop_bpstat; bs; bs = bs->next)
+ if (bs->breakpoint_at == bpt)
+ {
+ bs->breakpoint_at = NULL;
+
+ /* we'd call bpstat_clear_actions, but that free's stuff and due
+ to the multiple pointers pointing to one item with no
+ reference counts found anywhere through out the bpstat's (how
+ do you spell fragile?), we don't want to free things twice --
+ better a memory leak than a corrupt malloc pool! */
+ bs->commands = NULL;
+ bs->old_val = NULL;
+ }
+ /* On the chance that someone will soon try again to delete this same
+ bp, we mark it as deleted before freeing its storage. */
+ bpt->type = bp_none;
+
+ xfree (bpt);
+}
+
+static void
+do_delete_breakpoint_cleanup (void *b)
+{
+ delete_breakpoint (b);
+}
+
+struct cleanup *
+make_cleanup_delete_breakpoint (struct breakpoint *b)
+{
+ return make_cleanup (do_delete_breakpoint_cleanup, b);
+}
+
+struct cleanup *
+make_exec_cleanup_delete_breakpoint (struct breakpoint *b)
+{
+ return make_exec_cleanup (do_delete_breakpoint_cleanup, b);
+}
+
+void
+delete_command (char *arg, int from_tty)
+{
+ struct breakpoint *b, *temp;
+
+ if (arg == 0)
+ {
+ int breaks_to_delete = 0;
+
+ /* Delete all breakpoints if no argument.
+ Do not delete internal or call-dummy breakpoints, these
+ have to be deleted with an explicit breakpoint number argument. */
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->type != bp_call_dummy &&
+ b->type != bp_shlib_event &&
+ b->type != bp_thread_event &&
+ b->type != bp_overlay_event &&
+ b->number >= 0)
+ breaks_to_delete = 1;
+ }
+
+ /* Ask user only if there are some breakpoints to delete. */
+ if (!from_tty
+ || (breaks_to_delete && query ("Delete all breakpoints? ")))
+ {
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ {
+ if (b->type != bp_call_dummy &&
+ b->type != bp_shlib_event &&
+ b->type != bp_thread_event &&
+ b->type != bp_overlay_event &&
+ b->number >= 0)
+ delete_breakpoint (b);
+ }
+ }
+ }
+ else
+ map_breakpoint_numbers (arg, delete_breakpoint);
+}
+
+/* Reset a breakpoint given it's struct breakpoint * BINT.
+ The value we return ends up being the return value from catch_errors.
+ Unused in this case. */
+
+static int
+breakpoint_re_set_one (PTR bint)
+{
+ /* get past catch_errs */
+ struct breakpoint *b = (struct breakpoint *) bint;
+ struct value *mark;
+ int i;
+ struct symtabs_and_lines sals;
+ char *s;
+ enum enable_state save_enable;
+
+ switch (b->type)
+ {
+ case bp_none:
+ warning ("attempted to reset apparently deleted breakpoint #%d?",
+ b->number);
+ return 0;
+ case bp_breakpoint:
+ case bp_hardware_breakpoint:
+ case bp_catch_load:
+ case bp_catch_unload:
+ if (b->addr_string == NULL)
+ {
+ /* Anything without a string can't be re-set. */
+ delete_breakpoint (b);
+ return 0;
+ }
+ /* HACK: cagney/2001-11-11: kettenis/2001-11-11: MarkK wrote:
+
+ ``And a hack it is, although Apple's Darwin version of GDB
+ contains an almost identical hack to implement a "future
+ break" command. It seems to work in many real world cases,
+ but it is easy to come up with a test case where the patch
+ doesn't help at all.''
+
+ ``It seems that the way GDB implements breakpoints - in -
+ shared - libraries was designed for a.out shared library
+ systems (SunOS 4) where shared libraries were loaded at a
+ fixed address in memory. Since ELF shared libraries can (and
+ will) be loaded at any address in memory, things break.
+ Fixing this is not trivial. Therefore, I'm not sure whether
+ we should add this hack to the branch only. I cannot
+ guarantee that things will be fixed on the trunk in the near
+ future.''
+
+ In case we have a problem, disable this breakpoint. We'll
+ restore its status if we succeed. Don't disable a
+ shlib_disabled breakpoint though. There's a fair chance we
+ can't re-set it if the shared library it's in hasn't been
+ loaded yet. */
+ save_enable = b->enable_state;
+ if (b->enable_state != bp_shlib_disabled)
+ b->enable_state = bp_disabled;
+
+ set_language (b->language);
+ input_radix = b->input_radix;
+ s = b->addr_string;
+ sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL);
+ for (i = 0; i < sals.nelts; i++)
+ {
+ resolve_sal_pc (&sals.sals[i]);
+
+ /* Reparse conditions, they might contain references to the
+ old symtab. */
+ if (b->cond_string != NULL)
+ {
+ s = b->cond_string;
+ if (b->cond)
+ xfree (b->cond);
+ b->cond = parse_exp_1 (&s, block_for_pc (sals.sals[i].pc), 0);
+ }
+
+ /* We need to re-set the breakpoint if the address changes... */
+ if (b->address != sals.sals[i].pc
+ /* ...or new and old breakpoints both have source files, and
+ the source file name or the line number changes... */
+ || (b->source_file != NULL
+ && sals.sals[i].symtab != NULL
+ && (!STREQ (b->source_file, sals.sals[i].symtab->filename)
+ || b->line_number != sals.sals[i].line)
+ )
+ /* ...or we switch between having a source file and not having
+ one. */
+ || ((b->source_file == NULL) != (sals.sals[i].symtab == NULL))
+ )
+ {
+ if (b->source_file != NULL)
+ xfree (b->source_file);
+ if (sals.sals[i].symtab == NULL)
+ b->source_file = NULL;
+ else
+ b->source_file =
+ savestring (sals.sals[i].symtab->filename,
+ strlen (sals.sals[i].symtab->filename));
+ b->line_number = sals.sals[i].line;
+ b->address = sals.sals[i].pc;
+
+ /* Used to check for duplicates here, but that can
+ cause trouble, as it doesn't check for disabled
+ breakpoints. */
+
+ mention (b);
+
+ /* Might be better to do this just once per breakpoint_re_set,
+ rather than once for every breakpoint. */
+ breakpoints_changed ();
+ }
+ b->section = sals.sals[i].section;
+ b->enable_state = save_enable; /* Restore it, this worked. */
+
+
+ /* Now that this is re-enabled, check_duplicates
+ can be used. */
+ check_duplicates (b);
+
+ }
+ xfree (sals.sals);
+ break;
+
+ case bp_watchpoint:
+ case bp_hardware_watchpoint:
+ case bp_read_watchpoint:
+ case bp_access_watchpoint:
+ innermost_block = NULL;
+ /* The issue arises of what context to evaluate this in. The
+ same one as when it was set, but what does that mean when
+ symbols have been re-read? We could save the filename and
+ functionname, but if the context is more local than that, the
+ best we could do would be something like how many levels deep
+ and which index at that particular level, but that's going to
+ be less stable than filenames or function names. */
+
+ /* So for now, just use a global context. */
+ if (b->exp)
+ xfree (b->exp);
+ b->exp = parse_expression (b->exp_string);
+ b->exp_valid_block = innermost_block;
+ mark = value_mark ();
+ if (b->val)
+ value_free (b->val);
+ b->val = evaluate_expression (b->exp);
+ release_value (b->val);
+ if (VALUE_LAZY (b->val))
+ value_fetch_lazy (b->val);
+
+ if (b->cond_string != NULL)
+ {
+ s = b->cond_string;
+ if (b->cond)
+ xfree (b->cond);
+ b->cond = parse_exp_1 (&s, (struct block *) 0, 0);
+ }
+ if (b->enable_state == bp_enabled)
+ mention (b);
+ value_free_to_mark (mark);
+ break;
+ case bp_catch_catch:
+ case bp_catch_throw:
+ break;
+ /* We needn't really do anything to reset these, since the mask
+ that requests them is unaffected by e.g., new libraries being
+ loaded. */
+ case bp_catch_fork:
+ case bp_catch_vfork:
+ case bp_catch_exec:
+ break;
+
+ default:
+ printf_filtered ("Deleting unknown breakpoint type %d\n", b->type);
+ /* fall through */
+ /* Delete longjmp and overlay event breakpoints; they will be
+ reset later by breakpoint_re_set. */
+ case bp_longjmp:
+ case bp_longjmp_resume:
+ case bp_overlay_event:
+ delete_breakpoint (b);
+ break;
+
+ /* This breakpoint is special, it's set up when the inferior
+ starts and we really don't want to touch it. */
+ case bp_shlib_event:
+
+ /* Like bp_shlib_event, this breakpoint type is special.
+ Once it is set up, we do not want to touch it. */
+ case bp_thread_event:
+
+ /* Keep temporary breakpoints, which can be encountered when we step
+ over a dlopen call and SOLIB_ADD is resetting the breakpoints.
+ Otherwise these should have been blown away via the cleanup chain
+ or by breakpoint_init_inferior when we rerun the executable. */
+ case bp_until:
+ case bp_finish:
+ case bp_watchpoint_scope:
+ case bp_call_dummy:
+ case bp_step_resume:
+ break;
+ }
+
+ return 0;
+}
+
+/* Re-set all breakpoints after symbols have been re-loaded. */
+void
+breakpoint_re_set (void)
+{
+ struct breakpoint *b, *temp;
+ enum language save_language;
+ int save_input_radix;
+ static char message1[] = "Error in re-setting breakpoint %d:\n";
+ char message[sizeof (message1) + 30 /* slop */ ];
+
+ save_language = current_language->la_language;
+ save_input_radix = input_radix;
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ {
+ /* Format possible error msg */
+ sprintf (message, message1, b->number);
+ catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
+ }
+ set_language (save_language);
+ input_radix = save_input_radix;
+
+ if (GET_LONGJMP_TARGET_P ())
+ {
+ create_longjmp_breakpoint ("longjmp");
+ create_longjmp_breakpoint ("_longjmp");
+ create_longjmp_breakpoint ("siglongjmp");
+ create_longjmp_breakpoint ("_siglongjmp");
+ create_longjmp_breakpoint (NULL);
+ }
+
+ create_overlay_event_breakpoint ("_ovly_debug_event");
+}
+
+/* Reset the thread number of this breakpoint:
+
+ - If the breakpoint is for all threads, leave it as-is.
+ - Else, reset it to the current thread for inferior_ptid. */
+void
+breakpoint_re_set_thread (struct breakpoint *b)
+{
+ if (b->thread != -1)
+ {
+ if (in_thread_list (inferior_ptid))
+ b->thread = pid_to_thread_id (inferior_ptid);
+ }
+}
+
+/* Set ignore-count of breakpoint number BPTNUM to COUNT.
+ If from_tty is nonzero, it prints a message to that effect,
+ which ends with a period (no newline). */
+
+void
+set_ignore_count (int bptnum, int count, int from_tty)
+{
+ register struct breakpoint *b;
+
+ if (count < 0)
+ count = 0;
+
+ ALL_BREAKPOINTS (b)
+ if (b->number == bptnum)
+ {
+ b->ignore_count = count;
+ if (!from_tty)
+ return;
+ else if (count == 0)
+ printf_filtered ("Will stop next time breakpoint %d is reached.",
+ bptnum);
+ else if (count == 1)
+ printf_filtered ("Will ignore next crossing of breakpoint %d.",
+ bptnum);
+ else
+ printf_filtered ("Will ignore next %d crossings of breakpoint %d.",
+ count, bptnum);
+ breakpoints_changed ();
+ return;
+ }
+
+ error ("No breakpoint number %d.", bptnum);
+}
+
+/* Clear the ignore counts of all breakpoints. */
+void
+breakpoint_clear_ignore_counts (void)
+{
+ struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ b->ignore_count = 0;
+}
+
+/* Command to set ignore-count of breakpoint N to COUNT. */
+
+static void
+ignore_command (char *args, int from_tty)
+{
+ char *p = args;
+ register int num;
+
+ if (p == 0)
+ error_no_arg ("a breakpoint number");
+
+ num = get_number (&p);
+ if (num == 0)
+ error ("bad breakpoint number: '%s'", args);
+ if (*p == 0)
+ error ("Second argument (specified ignore-count) is missing.");
+
+ set_ignore_count (num,
+ longest_to_int (value_as_long (parse_and_eval (p))),
+ from_tty);
+ printf_filtered ("\n");
+ breakpoints_changed ();
+}
+
+/* Call FUNCTION on each of the breakpoints
+ whose numbers are given in ARGS. */
+
+static void
+map_breakpoint_numbers (char *args, void (*function) (struct breakpoint *))
+{
+ register char *p = args;
+ char *p1;
+ register int num;
+ register struct breakpoint *b, *tmp;
+ int match;
+
+ if (p == 0)
+ error_no_arg ("one or more breakpoint numbers");
+
+ while (*p)
+ {
+ match = 0;
+ p1 = p;
+
+ num = get_number_or_range (&p1);
+ if (num == 0)
+ {
+ warning ("bad breakpoint number at or near '%s'", p);
+ }
+ else
+ {
+ ALL_BREAKPOINTS_SAFE (b, tmp)
+ if (b->number == num)
+ {
+ struct breakpoint *related_breakpoint = b->related_breakpoint;
+ match = 1;
+ function (b);
+ if (related_breakpoint)
+ function (related_breakpoint);
+ break;
+ }
+ if (match == 0)
+ printf_unfiltered ("No breakpoint number %d.\n", num);
+ }
+ p = p1;
+ }
+}
+
+/* Set ignore-count of breakpoint number BPTNUM to COUNT.
+ If from_tty is nonzero, it prints a message to that effect,
+ which ends with a period (no newline). */
+
+void
+disable_breakpoint (struct breakpoint *bpt)
+{
+ /* Never disable a watchpoint scope breakpoint; we want to
+ hit them when we leave scope so we can delete both the
+ watchpoint and its scope breakpoint at that time. */
+ if (bpt->type == bp_watchpoint_scope)
+ return;
+
+ /* You can't disable permanent breakpoints. */
+ if (bpt->enable_state == bp_permanent)
+ return;
+
+ bpt->enable_state = bp_disabled;
+
+ check_duplicates (bpt);
+
+ if (modify_breakpoint_hook)
+ modify_breakpoint_hook (bpt);
+ breakpoint_modify_event (bpt->number);
+}
+
+/* ARGSUSED */
+static void
+disable_command (char *args, int from_tty)
+{
+ register struct breakpoint *bpt;
+ if (args == 0)
+ ALL_BREAKPOINTS (bpt)
+ switch (bpt->type)
+ {
+ case bp_none:
+ warning ("attempted to disable apparently deleted breakpoint #%d?",
+ bpt->number);
+ continue;
+ case bp_breakpoint:
+ case bp_catch_load:
+ case bp_catch_unload:
+ case bp_catch_fork:
+ case bp_catch_vfork:
+ case bp_catch_exec:
+ case bp_catch_catch:
+ case bp_catch_throw:
+ case bp_hardware_breakpoint:
+ case bp_watchpoint:
+ case bp_hardware_watchpoint:
+ case bp_read_watchpoint:
+ case bp_access_watchpoint:
+ disable_breakpoint (bpt);
+ default:
+ continue;
+ }
+ else
+ map_breakpoint_numbers (args, disable_breakpoint);
+}
+
+static void
+do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition)
+{
+ struct frame_info *save_selected_frame = NULL;
+ int save_selected_frame_level = -1;
+ int target_resources_ok, other_type_used;
+ struct value *mark;
+
+ if (bpt->type == bp_hardware_breakpoint)
+ {
+ int i;
+ i = hw_breakpoint_used_count ();
+ target_resources_ok =
+ TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint,
+ i + 1, 0);
+ if (target_resources_ok == 0)
+ error ("No hardware breakpoint support in the target.");
+ else if (target_resources_ok < 0)
+ error ("Hardware breakpoints used exceeds limit.");
+ }
+
+ if (bpt->enable_state != bp_permanent)
+ bpt->enable_state = bp_enabled;
+ bpt->disposition = disposition;
+ check_duplicates (bpt);
+ breakpoints_changed ();
+
+ if (bpt->type == bp_watchpoint ||
+ bpt->type == bp_hardware_watchpoint ||
+ bpt->type == bp_read_watchpoint ||
+ bpt->type == bp_access_watchpoint)
+ {
+ if (bpt->exp_valid_block != NULL)
+ {
+ struct frame_info *fr =
+
+ /* Ensure that we have the current frame. Else, this
+ next query may pessimistically be answered as, "No,
+ not within current scope". */
+ get_current_frame ();
+ fr = find_frame_addr_in_frame_chain (bpt->watchpoint_frame);
+ if (fr == NULL)
+ {
+ printf_filtered ("\
+Cannot enable watchpoint %d because the block in which its expression\n\
+is valid is not currently in scope.\n", bpt->number);
+ bpt->enable_state = bp_disabled;
+ return;
+ }
+
+ save_selected_frame = selected_frame;
+ save_selected_frame_level = frame_relative_level (selected_frame);
+ select_frame (fr);
+ }
+
+ value_free (bpt->val);
+ mark = value_mark ();
+ bpt->val = evaluate_expression (bpt->exp);
+ release_value (bpt->val);
+ if (VALUE_LAZY (bpt->val))
+ value_fetch_lazy (bpt->val);
+
+ if (bpt->type == bp_hardware_watchpoint ||
+ bpt->type == bp_read_watchpoint ||
+ bpt->type == bp_access_watchpoint)
+ {
+ int i = hw_watchpoint_used_count (bpt->type, &other_type_used);
+ int mem_cnt = can_use_hardware_watchpoint (bpt->val);
+
+ /* Hack around 'unused var' error for some targets here */
+ (void) mem_cnt, i;
+ target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT (
+ bpt->type, i + mem_cnt, other_type_used);
+ /* we can consider of type is bp_hardware_watchpoint, convert to
+ bp_watchpoint in the following condition */
+ if (target_resources_ok < 0)
+ {
+ printf_filtered ("\
+Cannot enable watchpoint %d because target watch resources\n\
+have been allocated for other watchpoints.\n", bpt->number);
+ bpt->enable_state = bp_disabled;
+ value_free_to_mark (mark);
+ return;
+ }
+ }
+
+ if (save_selected_frame_level >= 0)
+ select_frame (save_selected_frame);
+ value_free_to_mark (mark);
+ }
+ if (modify_breakpoint_hook)
+ modify_breakpoint_hook (bpt);
+ breakpoint_modify_event (bpt->number);
+}
+
+void
+enable_breakpoint (struct breakpoint *bpt)
+{
+ do_enable_breakpoint (bpt, bpt->disposition);
+}
+
+/* The enable command enables the specified breakpoints (or all defined
+ breakpoints) so they once again become (or continue to be) effective
+ in stopping the inferior. */
+
+/* ARGSUSED */
+static void
+enable_command (char *args, int from_tty)
+{
+ register struct breakpoint *bpt;
+ if (args == 0)
+ ALL_BREAKPOINTS (bpt)
+ switch (bpt->type)
+ {
+ case bp_none:
+ warning ("attempted to enable apparently deleted breakpoint #%d?",
+ bpt->number);
+ continue;
+ case bp_breakpoint:
+ case bp_catch_load:
+ case bp_catch_unload:
+ case bp_catch_fork:
+ case bp_catch_vfork:
+ case bp_catch_exec:
+ case bp_catch_catch:
+ case bp_catch_throw:
+ case bp_hardware_breakpoint:
+ case bp_watchpoint:
+ case bp_hardware_watchpoint:
+ case bp_read_watchpoint:
+ case bp_access_watchpoint:
+ enable_breakpoint (bpt);
+ default:
+ continue;
+ }
+ else
+ map_breakpoint_numbers (args, enable_breakpoint);
+}
+
+static void
+enable_once_breakpoint (struct breakpoint *bpt)
+{
+ do_enable_breakpoint (bpt, disp_disable);
+}
+
+/* ARGSUSED */
+static void
+enable_once_command (char *args, int from_tty)
+{
+ map_breakpoint_numbers (args, enable_once_breakpoint);
+}
+
+static void
+enable_delete_breakpoint (struct breakpoint *bpt)
+{
+ do_enable_breakpoint (bpt, disp_del);
+}
+
+/* ARGSUSED */
+static void
+enable_delete_command (char *args, int from_tty)
+{
+ map_breakpoint_numbers (args, enable_delete_breakpoint);
+}
+
+/* Use default_breakpoint_'s, or nothing if they aren't valid. */
+
+struct symtabs_and_lines
+decode_line_spec_1 (char *string, int funfirstline)
+{
+ struct symtabs_and_lines sals;
+ if (string == 0)
+ error ("Empty line specification.");
+ if (default_breakpoint_valid)
+ sals = decode_line_1 (&string, funfirstline,
+ default_breakpoint_symtab,
+ default_breakpoint_line,
+ (char ***) NULL);
+ else
+ sals = decode_line_1 (&string, funfirstline,
+ (struct symtab *) NULL, 0, (char ***) NULL);
+ if (*string)
+ error ("Junk at end of line specification: %s", string);
+ return sals;
+}
+
+void
+_initialize_breakpoint (void)
+{
+ struct cmd_list_element *c;
+
+ breakpoint_chain = 0;
+ /* Don't bother to call set_breakpoint_count. $bpnum isn't useful
+ before a breakpoint is set. */
+ breakpoint_count = 0;
+
+ add_com ("ignore", class_breakpoint, ignore_command,
+ "Set ignore-count of breakpoint number N to COUNT.\n\
+Usage is `ignore N COUNT'.");
+ if (xdb_commands)
+ add_com_alias ("bc", "ignore", class_breakpoint, 1);
+
+ add_com ("commands", class_breakpoint, commands_command,
+ "Set commands to be executed when a breakpoint is hit.\n\
+Give breakpoint number as argument after \"commands\".\n\
+With no argument, the targeted breakpoint is the last one set.\n\
+The commands themselves follow starting on the next line.\n\
+Type a line containing \"end\" to indicate the end of them.\n\
+Give \"silent\" as the first line to make the breakpoint silent;\n\
+then no output is printed when it is hit, except what the commands print.");
+
+ add_com ("condition", class_breakpoint, condition_command,
+ "Specify breakpoint number N to break only if COND is true.\n\
+Usage is `condition N COND', where N is an integer and COND is an\n\
+expression to be evaluated whenever breakpoint N is reached.");
+
+ c = add_com ("tbreak", class_breakpoint, tbreak_command,
+ "Set a temporary breakpoint. Args like \"break\" command.\n\
+Like \"break\" except the breakpoint is only temporary,\n\
+so it will be deleted when hit. Equivalent to \"break\" followed\n\
+by using \"enable delete\" on the breakpoint number.");
+ set_cmd_completer (c, location_completer);
+
+ c = add_com ("hbreak", class_breakpoint, hbreak_command,
+ "Set a hardware assisted breakpoint. Args like \"break\" command.\n\
+Like \"break\" except the breakpoint requires hardware support,\n\
+some target hardware may not have this support.");
+ set_cmd_completer (c, location_completer);
+
+ c = add_com ("thbreak", class_breakpoint, thbreak_command,
+ "Set a temporary hardware assisted breakpoint. Args like \"break\" command.\n\
+Like \"hbreak\" except the breakpoint is only temporary,\n\
+so it will be deleted when hit.");
+ set_cmd_completer (c, location_completer);
+
+ add_prefix_cmd ("enable", class_breakpoint, enable_command,
+ "Enable some breakpoints.\n\
+Give breakpoint numbers (separated by spaces) as arguments.\n\
+With no subcommand, breakpoints are enabled until you command otherwise.\n\
+This is used to cancel the effect of the \"disable\" command.\n\
+With a subcommand you can enable temporarily.",
+ &enablelist, "enable ", 1, &cmdlist);
+ if (xdb_commands)
+ add_com ("ab", class_breakpoint, enable_command,
+ "Enable some breakpoints.\n\
+Give breakpoint numbers (separated by spaces) as arguments.\n\
+With no subcommand, breakpoints are enabled until you command otherwise.\n\
+This is used to cancel the effect of the \"disable\" command.\n\
+With a subcommand you can enable temporarily.");
+
+ add_com_alias ("en", "enable", class_breakpoint, 1);
+
+ add_abbrev_prefix_cmd ("breakpoints", class_breakpoint, enable_command,
+ "Enable some breakpoints.\n\
+Give breakpoint numbers (separated by spaces) as arguments.\n\
+This is used to cancel the effect of the \"disable\" command.\n\
+May be abbreviated to simply \"enable\".\n",
+ &enablebreaklist, "enable breakpoints ", 1, &enablelist);
+
+ add_cmd ("once", no_class, enable_once_command,
+ "Enable breakpoints for one hit. Give breakpoint numbers.\n\
+If a breakpoint is hit while enabled in this fashion, it becomes disabled.",
+ &enablebreaklist);
+
+ add_cmd ("delete", no_class, enable_delete_command,
+ "Enable breakpoints and delete when hit. Give breakpoint numbers.\n\
+If a breakpoint is hit while enabled in this fashion, it is deleted.",
+ &enablebreaklist);
+
+ add_cmd ("delete", no_class, enable_delete_command,
+ "Enable breakpoints and delete when hit. Give breakpoint numbers.\n\
+If a breakpoint is hit while enabled in this fashion, it is deleted.",
+ &enablelist);
+
+ add_cmd ("once", no_class, enable_once_command,
+ "Enable breakpoints for one hit. Give breakpoint numbers.\n\
+If a breakpoint is hit while enabled in this fashion, it becomes disabled.",
+ &enablelist);
+
+ add_prefix_cmd ("disable", class_breakpoint, disable_command,
+ "Disable some breakpoints.\n\
+Arguments are breakpoint numbers with spaces in between.\n\
+To disable all breakpoints, give no argument.\n\
+A disabled breakpoint is not forgotten, but has no effect until reenabled.",
+ &disablelist, "disable ", 1, &cmdlist);
+ add_com_alias ("dis", "disable", class_breakpoint, 1);
+ add_com_alias ("disa", "disable", class_breakpoint, 1);
+ if (xdb_commands)
+ add_com ("sb", class_breakpoint, disable_command,
+ "Disable some breakpoints.\n\
+Arguments are breakpoint numbers with spaces in between.\n\
+To disable all breakpoints, give no argument.\n\
+A disabled breakpoint is not forgotten, but has no effect until reenabled.");
+
+ add_cmd ("breakpoints", class_alias, disable_command,
+ "Disable some breakpoints.\n\
+Arguments are breakpoint numbers with spaces in between.\n\
+To disable all breakpoints, give no argument.\n\
+A disabled breakpoint is not forgotten, but has no effect until reenabled.\n\
+This command may be abbreviated \"disable\".",
+ &disablelist);
+
+ add_prefix_cmd ("delete", class_breakpoint, delete_command,
+ "Delete some breakpoints or auto-display expressions.\n\
+Arguments are breakpoint numbers with spaces in between.\n\
+To delete all breakpoints, give no argument.\n\
+\n\
+Also a prefix command for deletion of other GDB objects.\n\
+The \"unset\" command is also an alias for \"delete\".",
+ &deletelist, "delete ", 1, &cmdlist);
+ add_com_alias ("d", "delete", class_breakpoint, 1);
+ if (xdb_commands)
+ add_com ("db", class_breakpoint, delete_command,
+ "Delete some breakpoints.\n\
+Arguments are breakpoint numbers with spaces in between.\n\
+To delete all breakpoints, give no argument.\n");
+
+ add_cmd ("breakpoints", class_alias, delete_command,
+ "Delete some breakpoints or auto-display expressions.\n\
+Arguments are breakpoint numbers with spaces in between.\n\
+To delete all breakpoints, give no argument.\n\
+This command may be abbreviated \"delete\".",
+ &deletelist);
+
+ add_com ("clear", class_breakpoint, clear_command,
+ concat ("Clear breakpoint at specified line or function.\n\
+Argument may be line number, function name, or \"*\" and an address.\n\
+If line number is specified, all breakpoints in that line are cleared.\n\
+If function is specified, breakpoints at beginning of function are cleared.\n\
+If an address is specified, breakpoints at that address are cleared.\n\n",
+ "With no argument, clears all breakpoints in the line that the selected frame\n\
+is executing in.\n\
+\n\
+See also the \"delete\" command which clears breakpoints by number.", NULL));
+
+ c = add_com ("break", class_breakpoint, break_command,
+ concat ("Set breakpoint at specified line or function.\n\
+Argument may be line number, function name, or \"*\" and an address.\n\
+If line number is specified, break at start of code for that line.\n\
+If function is specified, break at start of code for that function.\n\
+If an address is specified, break at that exact address.\n",
+ "With no arg, uses current execution address of selected stack frame.\n\
+This is useful for breaking on return to a stack frame.\n\
+\n\
+Multiple breakpoints at one place are permitted, and useful if conditional.\n\
+\n\
+Do \"help breakpoints\" for info on other commands dealing with breakpoints.", NULL));
+ set_cmd_completer (c, location_completer);
+
+ add_com_alias ("b", "break", class_run, 1);
+ add_com_alias ("br", "break", class_run, 1);
+ add_com_alias ("bre", "break", class_run, 1);
+ add_com_alias ("brea", "break", class_run, 1);
+
+ if (xdb_commands)
+ {
+ add_com_alias ("ba", "break", class_breakpoint, 1);
+ add_com_alias ("bu", "ubreak", class_breakpoint, 1);
+ }
+
+ if (dbx_commands)
+ {
+ add_abbrev_prefix_cmd ("stop", class_breakpoint, stop_command,
+ "Break in function/address or break at a line in the current file.",
+ &stoplist, "stop ", 1, &cmdlist);
+ add_cmd ("in", class_breakpoint, stopin_command,
+ "Break in function or address.\n", &stoplist);
+ add_cmd ("at", class_breakpoint, stopat_command,
+ "Break at a line in the current file.\n", &stoplist);
+ add_com ("status", class_info, breakpoints_info,
+ concat ("Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
+The \"Type\" column indicates one of:\n\
+\tbreakpoint - normal breakpoint\n\
+\twatchpoint - watchpoint\n\
+The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
+the disposition of the breakpoint after it gets hit. \"dis\" means that the\n\
+breakpoint will be disabled. The \"Address\" and \"What\" columns indicate the\n\
+address and file/line number respectively.\n\n",
+ "Convenience variable \"$_\" and default examine address for \"x\"\n\
+are set to the address of the last breakpoint listed.\n\n\
+Convenience variable \"$bpnum\" contains the number of the last\n\
+breakpoint set.", NULL));
+ }
+
+ add_info ("breakpoints", breakpoints_info,
+ concat ("Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
+The \"Type\" column indicates one of:\n\
+\tbreakpoint - normal breakpoint\n\
+\twatchpoint - watchpoint\n\
+The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
+the disposition of the breakpoint after it gets hit. \"dis\" means that the\n\
+breakpoint will be disabled. The \"Address\" and \"What\" columns indicate the\n\
+address and file/line number respectively.\n\n",
+ "Convenience variable \"$_\" and default examine address for \"x\"\n\
+are set to the address of the last breakpoint listed.\n\n\
+Convenience variable \"$bpnum\" contains the number of the last\n\
+breakpoint set.", NULL));
+
+ if (xdb_commands)
+ add_com ("lb", class_breakpoint, breakpoints_info,
+ concat ("Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
+The \"Type\" column indicates one of:\n\
+\tbreakpoint - normal breakpoint\n\
+\twatchpoint - watchpoint\n\
+The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
+the disposition of the breakpoint after it gets hit. \"dis\" means that the\n\
+breakpoint will be disabled. The \"Address\" and \"What\" columns indicate the\n\
+address and file/line number respectively.\n\n",
+ "Convenience variable \"$_\" and default examine address for \"x\"\n\
+are set to the address of the last breakpoint listed.\n\n\
+Convenience variable \"$bpnum\" contains the number of the last\n\
+breakpoint set.", NULL));
+
+ add_cmd ("breakpoints", class_maintenance, maintenance_info_breakpoints,
+ concat ("Status of all breakpoints, or breakpoint number NUMBER.\n\
+The \"Type\" column indicates one of:\n\
+\tbreakpoint - normal breakpoint\n\
+\twatchpoint - watchpoint\n\
+\tlongjmp - internal breakpoint used to step through longjmp()\n\
+\tlongjmp resume - internal breakpoint at the target of longjmp()\n\
+\tuntil - internal breakpoint used by the \"until\" command\n\
+\tfinish - internal breakpoint used by the \"finish\" command\n",
+ "The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
+the disposition of the breakpoint after it gets hit. \"dis\" means that the\n\
+breakpoint will be disabled. The \"Address\" and \"What\" columns indicate the\n\
+address and file/line number respectively.\n\n",
+ "Convenience variable \"$_\" and default examine address for \"x\"\n\
+are set to the address of the last breakpoint listed.\n\n\
+Convenience variable \"$bpnum\" contains the number of the last\n\
+breakpoint set.", NULL),
+ &maintenanceinfolist);
+
+ add_com ("catch", class_breakpoint, catch_command,
+ "Set catchpoints to catch events.\n\
+Raised signals may be caught:\n\
+\tcatch signal - all signals\n\
+\tcatch signal <signame> - a particular signal\n\
+Raised exceptions may be caught:\n\
+\tcatch throw - all exceptions, when thrown\n\
+\tcatch throw <exceptname> - a particular exception, when thrown\n\
+\tcatch catch - all exceptions, when caught\n\
+\tcatch catch <exceptname> - a particular exception, when caught\n\
+Thread or process events may be caught:\n\
+\tcatch thread_start - any threads, just after creation\n\
+\tcatch thread_exit - any threads, just before expiration\n\
+\tcatch thread_join - any threads, just after joins\n\
+Process events may be caught:\n\
+\tcatch start - any processes, just after creation\n\
+\tcatch exit - any processes, just before expiration\n\
+\tcatch fork - calls to fork()\n\
+\tcatch vfork - calls to vfork()\n\
+\tcatch exec - calls to exec()\n\
+Dynamically-linked library events may be caught:\n\
+\tcatch load - loads of any library\n\
+\tcatch load <libname> - loads of a particular library\n\
+\tcatch unload - unloads of any library\n\
+\tcatch unload <libname> - unloads of a particular library\n\
+The act of your program's execution stopping may also be caught:\n\
+\tcatch stop\n\n\
+C++ exceptions may be caught:\n\
+\tcatch throw - all exceptions, when thrown\n\
+\tcatch catch - all exceptions, when caught\n\
+\n\
+Do \"help set follow-fork-mode\" for info on debugging your program\n\
+after a fork or vfork is caught.\n\n\
+Do \"help breakpoints\" for info on other commands dealing with breakpoints.");
+
+ add_com ("tcatch", class_breakpoint, tcatch_command,
+ "Set temporary catchpoints to catch events.\n\
+Args like \"catch\" command.\n\
+Like \"catch\" except the catchpoint is only temporary,\n\
+so it will be deleted when hit. Equivalent to \"catch\" followed\n\
+by using \"enable delete\" on the catchpoint number.");
+
+ c = add_com ("watch", class_breakpoint, watch_command,
+ "Set a watchpoint for an expression.\n\
+A watchpoint stops execution of your program whenever the value of\n\
+an expression changes.");
+ set_cmd_completer (c, location_completer);
+
+ c = add_com ("rwatch", class_breakpoint, rwatch_command,
+ "Set a read watchpoint for an expression.\n\
+A watchpoint stops execution of your program whenever the value of\n\
+an expression is read.");
+ set_cmd_completer (c, location_completer);
+
+ c = add_com ("awatch", class_breakpoint, awatch_command,
+ "Set a watchpoint for an expression.\n\
+A watchpoint stops execution of your program whenever the value of\n\
+an expression is either read or written.");
+ set_cmd_completer (c, location_completer);
+
+ add_info ("watchpoints", breakpoints_info,
+ "Synonym for ``info breakpoints''.");
+
+
+ c = add_set_cmd ("can-use-hw-watchpoints", class_support, var_zinteger,
+ (char *) &can_use_hw_watchpoints,
+ "Set debugger's willingness to use watchpoint hardware.\n\
+If zero, gdb will not use hardware for new watchpoints, even if\n\
+such is available. (However, any hardware watchpoints that were\n\
+created before setting this to nonzero, will continue to use watchpoint\n\
+hardware.)",
+ &setlist);
+ add_show_from_set (c, &showlist);
+
+ can_use_hw_watchpoints = 1;
+}
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
new file mode 100644
index 00000000000..3a58aad2487
--- /dev/null
+++ b/gdb/breakpoint.h
@@ -0,0 +1,709 @@
+/* Data structures associated with breakpoints in GDB.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+ 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. */
+
+#if !defined (BREAKPOINT_H)
+#define BREAKPOINT_H 1
+
+#include "frame.h"
+#include "value.h"
+
+#include "gdb-events.h"
+
+struct value;
+
+/* This is the maximum number of bytes a breakpoint instruction can take.
+ Feel free to increase it. It's just used in a few places to size
+ arrays that should be independent of the target architecture. */
+
+#define BREAKPOINT_MAX 16
+
+/* Type of breakpoint. */
+/* FIXME In the future, we should fold all other breakpoint-like things into
+ here. This includes:
+
+ * single-step (for machines where we have to simulate single stepping)
+ (probably, though perhaps it is better for it to look as much as
+ possible like a single-step to wait_for_inferior). */
+
+enum bptype
+ {
+ bp_none = 0, /* Eventpoint has been deleted. */
+ bp_breakpoint, /* Normal breakpoint */
+ bp_hardware_breakpoint, /* Hardware assisted breakpoint */
+ bp_until, /* used by until command */
+ bp_finish, /* used by finish command */
+ bp_watchpoint, /* Watchpoint */
+ bp_hardware_watchpoint, /* Hardware assisted watchpoint */
+ bp_read_watchpoint, /* read watchpoint, (hardware assisted) */
+ bp_access_watchpoint, /* access watchpoint, (hardware assisted) */
+ bp_longjmp, /* secret breakpoint to find longjmp() */
+ bp_longjmp_resume, /* secret breakpoint to escape longjmp() */
+
+ /* Used by wait_for_inferior for stepping over subroutine calls, for
+ stepping over signal handlers, and for skipping prologues. */
+ bp_step_resume,
+
+ /* Used by wait_for_inferior for stepping over signal handlers. */
+ bp_through_sigtramp,
+
+ /* Used to detect when a watchpoint expression has gone out of
+ scope. These breakpoints are usually not visible to the user.
+
+ This breakpoint has some interesting properties:
+
+ 1) There's always a 1:1 mapping between watchpoints
+ on local variables and watchpoint_scope breakpoints.
+
+ 2) It automatically deletes itself and the watchpoint it's
+ associated with when hit.
+
+ 3) It can never be disabled. */
+ bp_watchpoint_scope,
+
+ /* The breakpoint at the end of a call dummy. */
+ /* FIXME: What if the function we are calling longjmp()s out of the
+ call, or the user gets out with the "return" command? We currently
+ have no way of cleaning up the breakpoint in these (obscure) situations.
+ (Probably can solve this by noticing longjmp, "return", etc., it's
+ similar to noticing when a watchpoint on a local variable goes out
+ of scope (with hardware support for watchpoints)). */
+ bp_call_dummy,
+
+ /* Some dynamic linkers (HP, maybe Solaris) can arrange for special
+ code in the inferior to run when significant events occur in the
+ dynamic linker (for example a library is loaded or unloaded).
+
+ By placing a breakpoint in this magic code GDB will get control
+ when these significant events occur. GDB can then re-examine
+ the dynamic linker's data structures to discover any newly loaded
+ dynamic libraries. */
+ bp_shlib_event,
+
+ /* Some multi-threaded systems can arrange for a location in the
+ inferior to be executed when certain thread-related events occur
+ (such as thread creation or thread death).
+
+ By placing a breakpoint at one of these locations, GDB will get
+ control when these events occur. GDB can then update its thread
+ lists etc. */
+
+ bp_thread_event,
+
+ /* On the same principal, an overlay manager can arrange to call a
+ magic location in the inferior whenever there is an interesting
+ change in overlay status. GDB can update its overlay tables
+ and fiddle with breakpoints in overlays when this breakpoint
+ is hit. */
+
+ bp_overlay_event,
+
+ /* These breakpoints are used to implement the "catch load" command
+ on platforms whose dynamic linkers support such functionality. */
+ bp_catch_load,
+
+ /* These breakpoints are used to implement the "catch unload" command
+ on platforms whose dynamic linkers support such functionality. */
+ bp_catch_unload,
+
+ /* These are not really breakpoints, but are catchpoints that
+ implement the "catch fork", "catch vfork" and "catch exec" commands
+ on platforms whose kernel support such functionality. (I.e.,
+ kernels which can raise an event when a fork or exec occurs, as
+ opposed to the debugger setting breakpoints on functions named
+ "fork" or "exec".) */
+ bp_catch_fork,
+ bp_catch_vfork,
+ bp_catch_exec,
+
+ /* These are catchpoints to implement "catch catch" and "catch throw"
+ commands for C++ exception handling. */
+ bp_catch_catch,
+ bp_catch_throw
+
+
+ };
+
+/* States of enablement of breakpoint. */
+
+enum enable_state
+ {
+ bp_disabled, /* The eventpoint is inactive, and cannot trigger. */
+ bp_enabled, /* The eventpoint is active, and can trigger. */
+ bp_shlib_disabled, /* The eventpoint's address is in an unloaded solib.
+ The eventpoint will be automatically enabled
+ and reset when that solib is loaded. */
+ bp_call_disabled, /* The eventpoint has been disabled while a call
+ into the inferior is "in flight", because some
+ eventpoints interfere with the implementation of
+ a call on some targets. The eventpoint will be
+ automatically enabled and reset when the call
+ "lands" (either completes, or stops at another
+ eventpoint). */
+ bp_permanent /* There is a breakpoint instruction hard-wired into
+ the target's code. Don't try to write another
+ breakpoint instruction on top of it, or restore
+ its value. Step over it using the architecture's
+ SKIP_INSN macro. */
+ };
+
+
+/* Disposition of breakpoint. Ie: what to do after hitting it. */
+
+enum bpdisp
+ {
+ disp_del, /* Delete it */
+ disp_del_at_next_stop, /* Delete at next stop, whether hit or not */
+ disp_disable, /* Disable it */
+ disp_donttouch /* Leave it alone */
+ };
+
+enum target_hw_bp_type
+ {
+ hw_write = 0, /* Common HW watchpoint */
+ hw_read = 1, /* Read HW watchpoint */
+ hw_access = 2, /* Access HW watchpoint */
+ hw_execute = 3 /* Execute HW breakpoint */
+ };
+
+/* Note that the ->silent field is not currently used by any commands
+ (though the code is in there if it was to be, and set_raw_breakpoint
+ does set it to 0). I implemented it because I thought it would be
+ useful for a hack I had to put in; I'm going to leave it in because
+ I can see how there might be times when it would indeed be useful */
+
+/* This is for a breakpoint or a watchpoint. */
+
+struct breakpoint
+ {
+ struct breakpoint *next;
+ /* Type of breakpoint. */
+ enum bptype type;
+ /* Zero means disabled; remember the info but don't break here. */
+ enum enable_state enable_state;
+ /* What to do with this breakpoint after we hit it. */
+ enum bpdisp disposition;
+ /* Number assigned to distinguish breakpoints. */
+ int number;
+
+ /* Address to break at.
+ Note that zero is a perfectly valid code address on some
+ platforms (for example, the mn10200 and mn10300 simulators).
+ NULL is not a special value for this field. */
+ CORE_ADDR address;
+
+ /* Line number of this address. */
+
+ int line_number;
+
+ /* Source file name of this address. */
+
+ char *source_file;
+
+ /* Non-zero means a silent breakpoint (don't print frame info
+ if we stop here). */
+ unsigned char silent;
+ /* Number of stops at this breakpoint that should
+ be continued automatically before really stopping. */
+ int ignore_count;
+ /* "Real" contents of byte where breakpoint has been inserted.
+ Valid only when breakpoints are in the program. Under the complete
+ control of the target insert_breakpoint and remove_breakpoint routines.
+ No other code should assume anything about the value(s) here. */
+ char shadow_contents[BREAKPOINT_MAX];
+ /* Nonzero if this breakpoint is now inserted. */
+ char inserted;
+ /* Nonzero if this is not the first breakpoint in the list
+ for the given address. */
+ char duplicate;
+ /* Chain of command lines to execute when this breakpoint is hit. */
+ struct command_line *commands;
+ /* Stack depth (address of frame). If nonzero, break only if fp
+ equals this. */
+ CORE_ADDR frame;
+ /* Conditional. Break only if this expression's value is nonzero. */
+ struct expression *cond;
+
+ /* String we used to set the breakpoint (malloc'd). */
+ char *addr_string;
+ /* Language we used to set the breakpoint. */
+ enum language language;
+ /* Input radix we used to set the breakpoint. */
+ int input_radix;
+ /* String form of the breakpoint condition (malloc'd), or NULL if there
+ is no condition. */
+ char *cond_string;
+ /* String form of exp (malloc'd), or NULL if none. */
+ char *exp_string;
+
+ /* The expression we are watching, or NULL if not a watchpoint. */
+ struct expression *exp;
+ /* The largest block within which it is valid, or NULL if it is
+ valid anywhere (e.g. consists just of global symbols). */
+ struct block *exp_valid_block;
+ /* Value of the watchpoint the last time we checked it. */
+ struct value *val;
+
+ /* Holds the value chain for a hardware watchpoint expression. */
+ struct value *val_chain;
+
+ /* Holds the address of the related watchpoint_scope breakpoint
+ when using watchpoints on local variables (might the concept
+ of a related breakpoint be useful elsewhere, if not just call
+ it the watchpoint_scope breakpoint or something like that. FIXME). */
+ struct breakpoint *related_breakpoint;
+
+ /* Holds the frame address which identifies the frame this watchpoint
+ should be evaluated in, or NULL if the watchpoint should be evaluated
+ on the outermost frame. */
+ CORE_ADDR watchpoint_frame;
+
+ /* Thread number for thread-specific breakpoint, or -1 if don't care */
+ int thread;
+
+ /* Count of the number of times this breakpoint was taken, dumped
+ with the info, but not used for anything else. Useful for
+ seeing how many times you hit a break prior to the program
+ aborting, so you can back up to just before the abort. */
+ int hit_count;
+
+ /* Filename of a dynamically-linked library (dll), used for
+ bp_catch_load and bp_catch_unload (malloc'd), or NULL if any
+ library is significant. */
+ char *dll_pathname;
+
+ /* Filename of a dll whose state change (e.g., load or unload)
+ triggered this catchpoint. This field is only valid immediately
+ after this catchpoint has triggered. */
+ char *triggered_dll_pathname;
+
+ /* Process id of a child process whose forking triggered this
+ catchpoint. This field is only valid immediately after this
+ catchpoint has triggered. */
+ int forked_inferior_pid;
+
+ /* Filename of a program whose exec triggered this catchpoint.
+ This field is only valid immediately after this catchpoint has
+ triggered. */
+ char *exec_pathname;
+
+ asection *section;
+ };
+
+/* The following stuff is an abstract data type "bpstat" ("breakpoint
+ status"). This provides the ability to determine whether we have
+ stopped at a breakpoint, and what we should do about it. */
+
+typedef struct bpstats *bpstat;
+
+/* Interface: */
+/* Clear a bpstat so that it says we are not at any breakpoint.
+ Also free any storage that is part of a bpstat. */
+extern void bpstat_clear (bpstat *);
+
+/* Return a copy of a bpstat. Like "bs1 = bs2" but all storage that
+ is part of the bpstat is copied as well. */
+extern bpstat bpstat_copy (bpstat);
+
+extern bpstat bpstat_stop_status (CORE_ADDR *, int);
+
+/* This bpstat_what stuff tells wait_for_inferior what to do with a
+ breakpoint (a challenging task). */
+
+enum bpstat_what_main_action
+ {
+ /* Perform various other tests; that is, this bpstat does not
+ say to perform any action (e.g. failed watchpoint and nothing
+ else). */
+ BPSTAT_WHAT_KEEP_CHECKING,
+
+ /* Rather than distinguish between noisy and silent stops here, it
+ might be cleaner to have bpstat_print make that decision (also
+ taking into account stop_print_frame and source_only). But the
+ implications are a bit scary (interaction with auto-displays, etc.),
+ so I won't try it. */
+
+ /* Stop silently. */
+ BPSTAT_WHAT_STOP_SILENT,
+
+ /* Stop and print. */
+ BPSTAT_WHAT_STOP_NOISY,
+
+ /* Remove breakpoints, single step once, then put them back in and
+ go back to what we were doing. It's possible that this should be
+ removed from the main_action and put into a separate field, to more
+ cleanly handle BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE. */
+ BPSTAT_WHAT_SINGLE,
+
+ /* Set longjmp_resume breakpoint, remove all other breakpoints,
+ and continue. The "remove all other breakpoints" part is required
+ if we are also stepping over another breakpoint as well as doing
+ the longjmp handling. */
+ BPSTAT_WHAT_SET_LONGJMP_RESUME,
+
+ /* Clear longjmp_resume breakpoint, then handle as
+ BPSTAT_WHAT_KEEP_CHECKING. */
+ BPSTAT_WHAT_CLEAR_LONGJMP_RESUME,
+
+ /* Clear longjmp_resume breakpoint, then handle as BPSTAT_WHAT_SINGLE. */
+ BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE,
+
+ /* Clear step resume breakpoint, and keep checking. */
+ BPSTAT_WHAT_STEP_RESUME,
+
+ /* Clear through_sigtramp breakpoint, muck with trap_expected, and keep
+ checking. */
+ BPSTAT_WHAT_THROUGH_SIGTRAMP,
+
+ /* Check the dynamic linker's data structures for new libraries, then
+ keep checking. */
+ BPSTAT_WHAT_CHECK_SHLIBS,
+
+ /* Check the dynamic linker's data structures for new libraries, then
+ resume out of the dynamic linker's callback, stop and print. */
+ BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK,
+
+ /* This is just used to keep track of how many enums there are. */
+ BPSTAT_WHAT_LAST
+ };
+
+struct bpstat_what
+ {
+ enum bpstat_what_main_action main_action;
+
+ /* Did we hit a call dummy breakpoint? This only goes with a main_action
+ of BPSTAT_WHAT_STOP_SILENT or BPSTAT_WHAT_STOP_NOISY (the concept of
+ continuing from a call dummy without popping the frame is not a
+ useful one). */
+ int call_dummy;
+ };
+
+/* The possible return values for print_bpstat, print_it_normal,
+ print_it_done, print_it_noop. */
+enum print_stop_action
+ {
+ PRINT_UNKNOWN = -1,
+ PRINT_SRC_AND_LOC,
+ PRINT_SRC_ONLY,
+ PRINT_NOTHING
+ };
+
+/* Tell what to do about this bpstat. */
+struct bpstat_what bpstat_what (bpstat);
+
+/* Find the bpstat associated with a breakpoint. NULL otherwise. */
+bpstat bpstat_find_breakpoint (bpstat, struct breakpoint *);
+
+/* Find a step_resume breakpoint associated with this bpstat.
+ (If there are multiple step_resume bp's on the list, this function
+ will arbitrarily pick one.)
+
+ It is an error to use this function if BPSTAT doesn't contain a
+ step_resume breakpoint.
+
+ See wait_for_inferior's use of this function.
+ */
+extern struct breakpoint *bpstat_find_step_resume_breakpoint (bpstat);
+
+/* Nonzero if a signal that we got in wait() was due to circumstances
+ explained by the BS. */
+/* Currently that is true if we have hit a breakpoint, or if there is
+ a watchpoint enabled. */
+#define bpstat_explains_signal(bs) ((bs) != NULL)
+
+/* Nonzero if we should step constantly (e.g. watchpoints on machines
+ without hardware support). This isn't related to a specific bpstat,
+ just to things like whether watchpoints are set. */
+extern int bpstat_should_step (void);
+
+/* Nonzero if there are enabled hardware watchpoints. */
+extern int bpstat_have_active_hw_watchpoints (void);
+
+/* Print a message indicating what happened. Returns nonzero to
+ say that only the source line should be printed after this (zero
+ return means print the frame as well as the source line). */
+extern enum print_stop_action bpstat_print (bpstat);
+
+/* Return the breakpoint number of the first breakpoint we are stopped
+ at. *BSP upon return is a bpstat which points to the remaining
+ breakpoints stopped at (but which is not guaranteed to be good for
+ anything but further calls to bpstat_num).
+ Return 0 if passed a bpstat which does not indicate any breakpoints. */
+extern int bpstat_num (bpstat *);
+
+/* Perform actions associated with having stopped at *BSP. Actually, we just
+ use this for breakpoint commands. Perhaps other actions will go here
+ later, but this is executed at a late time (from the command loop). */
+extern void bpstat_do_actions (bpstat *);
+
+/* Modify BS so that the actions will not be performed. */
+extern void bpstat_clear_actions (bpstat);
+
+/* Given a bpstat that records zero or more triggered eventpoints, this
+ function returns another bpstat which contains only the catchpoints
+ on that first list, if any.
+ */
+extern void bpstat_get_triggered_catchpoints (bpstat, bpstat *);
+
+/* Implementation: */
+
+/* Values used to tell the printing routine how to behave for this bpstat. */
+enum bp_print_how
+ {
+ /* This is used when we want to do a normal printing of the reason
+ for stopping. The output will depend on the type of eventpoint
+ we are dealing with. This is the default value, most commonly
+ used. */
+ print_it_normal,
+ /* This is used when nothing should be printed for this bpstat entry. */
+ print_it_noop,
+ /* This is used when everything which needs to be printed has
+ already been printed. But we still want to print the frame. */
+ print_it_done
+ };
+
+struct bpstats
+ {
+ /* Linked list because there can be two breakpoints at the same
+ place, and a bpstat reflects the fact that both have been hit. */
+ bpstat next;
+ /* Breakpoint that we are at. */
+ struct breakpoint *breakpoint_at;
+ /* Commands left to be done. */
+ struct command_line *commands;
+ /* Old value associated with a watchpoint. */
+ struct value *old_val;
+
+ /* Nonzero if this breakpoint tells us to print the frame. */
+ char print;
+
+ /* Nonzero if this breakpoint tells us to stop. */
+ char stop;
+
+ /* Tell bpstat_print and print_bp_stop_message how to print stuff
+ associated with this element of the bpstat chain. */
+ enum bp_print_how print_it;
+ };
+
+enum inf_context
+ {
+ inf_starting,
+ inf_running,
+ inf_exited
+ };
+
+/* The possible return values for breakpoint_here_p.
+ We guarantee that zero always means "no breakpoint here". */
+enum breakpoint_here
+ {
+ no_breakpoint_here = 0,
+ ordinary_breakpoint_here,
+ permanent_breakpoint_here
+ };
+
+
+/* Prototypes for breakpoint-related functions. */
+
+/* Forward declarations for prototypes */
+struct frame_info;
+
+extern enum breakpoint_here breakpoint_here_p (CORE_ADDR);
+
+extern int breakpoint_inserted_here_p (CORE_ADDR);
+
+extern int frame_in_dummy (struct frame_info *);
+
+extern int breakpoint_thread_match (CORE_ADDR, ptid_t);
+
+extern void until_break_command (char *, int);
+
+extern void breakpoint_re_set (void);
+
+extern void breakpoint_re_set_thread (struct breakpoint *);
+
+extern int ep_is_exception_catchpoint (struct breakpoint *);
+
+extern struct breakpoint *set_momentary_breakpoint
+ (struct symtab_and_line, struct frame_info *, enum bptype);
+
+extern void set_ignore_count (int, int, int);
+
+extern void set_default_breakpoint (int, CORE_ADDR, struct symtab *, int);
+
+extern void mark_breakpoints_out (void);
+
+extern void breakpoint_init_inferior (enum inf_context);
+
+extern struct cleanup *make_cleanup_delete_breakpoint (struct breakpoint *);
+
+extern struct cleanup *make_exec_cleanup_delete_breakpoint (struct breakpoint *);
+
+extern void delete_breakpoint (struct breakpoint *);
+
+extern void breakpoint_auto_delete (bpstat);
+
+extern void breakpoint_clear_ignore_counts (void);
+
+extern void break_command (char *, int);
+
+extern void hbreak_command_wrapper (char *, int);
+extern void thbreak_command_wrapper (char *, int);
+extern void rbreak_command_wrapper (char *, int);
+extern void watch_command_wrapper (char *, int);
+extern void awatch_command_wrapper (char *, int);
+extern void rwatch_command_wrapper (char *, int);
+extern void tbreak_command (char *, int);
+
+extern int insert_breakpoints (void);
+
+extern int remove_breakpoints (void);
+
+/* This function can be used to physically insert eventpoints from the
+ specified traced inferior process, without modifying the breakpoint
+ package's state. This can be useful for those targets which support
+ following the processes of a fork() or vfork() system call, when both
+ of the resulting two processes are to be followed. */
+extern int reattach_breakpoints (int);
+
+/* This function can be used to update the breakpoint package's state
+ after an exec() system call has been executed.
+
+ This function causes the following:
+
+ - All eventpoints are marked "not inserted".
+ - All eventpoints with a symbolic address are reset such that
+ the symbolic address must be reevaluated before the eventpoints
+ can be reinserted.
+ - The solib breakpoints are explicitly removed from the breakpoint
+ list.
+ - A step-resume breakpoint, if any, is explicitly removed from the
+ breakpoint list.
+ - All eventpoints without a symbolic address are removed from the
+ breakpoint list. */
+extern void update_breakpoints_after_exec (void);
+
+/* This function can be used to physically remove hardware breakpoints
+ and watchpoints from the specified traced inferior process, without
+ modifying the breakpoint package's state. This can be useful for
+ those targets which support following the processes of a fork() or
+ vfork() system call, when one of the resulting two processes is to
+ be detached and allowed to run free.
+
+ It is an error to use this function on the process whose id is
+ inferior_ptid. */
+extern int detach_breakpoints (int);
+
+extern void enable_longjmp_breakpoint (void);
+extern void disable_longjmp_breakpoint (void);
+extern void enable_overlay_breakpoints (void);
+extern void disable_overlay_breakpoints (void);
+
+extern void set_longjmp_resume_breakpoint (CORE_ADDR, struct frame_info *);
+/* These functions respectively disable or reenable all currently
+ enabled watchpoints. When disabled, the watchpoints are marked
+ call_disabled. When reenabled, they are marked enabled.
+
+ The intended client of these functions is infcmd.c\run_stack_dummy.
+
+ The inferior must be stopped, and all breakpoints removed, when
+ these functions are used.
+
+ The need for these functions is that on some targets (e.g., HP-UX),
+ gdb is unable to unwind through the dummy frame that is pushed as
+ part of the implementation of a call command. Watchpoints can
+ cause the inferior to stop in places where this frame is visible,
+ and that can cause execution control to become very confused.
+
+ Note that if a user sets breakpoints in an interactively called
+ function, the call_disabled watchpoints will have been reenabled
+ when the first such breakpoint is reached. However, on targets
+ that are unable to unwind through the call dummy frame, watches
+ of stack-based storage may then be deleted, because gdb will
+ believe that their watched storage is out of scope. (Sigh.) */
+extern void disable_watchpoints_before_interactive_call_start (void);
+
+extern void enable_watchpoints_after_interactive_call_stop (void);
+
+
+extern void clear_breakpoint_hit_counts (void);
+
+extern int get_number (char **);
+
+extern int get_number_or_range (char **);
+
+/* The following are for displays, which aren't really breakpoints, but
+ here is as good a place as any for them. */
+
+extern void disable_current_display (void);
+
+extern void do_displays (void);
+
+extern void disable_display (int);
+
+extern void clear_displays (void);
+
+extern void disable_breakpoint (struct breakpoint *);
+
+extern void enable_breakpoint (struct breakpoint *);
+
+extern void make_breakpoint_permanent (struct breakpoint *);
+
+extern struct breakpoint *create_solib_event_breakpoint (CORE_ADDR);
+
+extern struct breakpoint *create_thread_event_breakpoint (CORE_ADDR);
+
+extern void remove_solib_event_breakpoints (void);
+
+extern void remove_thread_event_breakpoints (void);
+
+extern void disable_breakpoints_in_shlibs (int silent);
+
+extern void re_enable_breakpoints_in_shlibs (void);
+
+extern void create_solib_load_event_breakpoint (char *, int, char *, char *);
+
+extern void create_solib_unload_event_breakpoint (char *, int,
+ char *, char *);
+
+extern void create_fork_event_catchpoint (int, char *);
+
+extern void create_vfork_event_catchpoint (int, char *);
+
+extern void create_exec_event_catchpoint (int, char *);
+
+/* This function returns TRUE if ep is a catchpoint. */
+extern int ep_is_catchpoint (struct breakpoint *);
+
+/* This function returns TRUE if ep is a catchpoint of a
+ shared library (aka dynamically-linked library) event,
+ such as a library load or unload. */
+extern int ep_is_shlib_catchpoint (struct breakpoint *);
+
+extern struct breakpoint *set_breakpoint_sal (struct symtab_and_line);
+
+/* Enable breakpoints and delete when hit. Called with ARG == NULL
+ deletes all breakpoints. */
+extern void delete_command (char *arg, int from_tty);
+
+/* Pull all H/W watchpoints from the target. Return non-zero if the
+ remove fails. */
+extern int remove_hw_watchpoints (void);
+
+#endif /* !defined (BREAKPOINT_H) */
diff --git a/gdb/buildsym.c b/gdb/buildsym.c
new file mode 100644
index 00000000000..5078935fefe
--- /dev/null
+++ b/gdb/buildsym.c
@@ -0,0 +1,1133 @@
+/* Support routines for building symbol tables in GDB's internal format.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002 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. */
+
+/* This module provides subroutines used for creating and adding to
+ the symbol table. These routines are called from various symbol-
+ file-reading routines.
+
+ Routines to support specific debugging information formats (stabs,
+ DWARF, etc) belong somewhere else. */
+
+#include "defs.h"
+#include "bfd.h"
+#include "obstack.h"
+#include "symtab.h"
+#include "symfile.h" /* Needed for "struct complaint" */
+#include "objfiles.h"
+#include "gdbtypes.h"
+#include "complaints.h"
+#include "gdb_string.h"
+#include "expression.h" /* For "enum exp_opcode" used by... */
+#include "language.h" /* For "local_hex_string" */
+#include "bcache.h"
+#include "filenames.h" /* For DOSish file names */
+#include "macrotab.h"
+/* Ask buildsym.h to define the vars it normally declares `extern'. */
+#define EXTERN
+/**/
+#include "buildsym.h" /* Our own declarations */
+#undef EXTERN
+
+/* For cleanup_undefined_types and finish_global_stabs (somewhat
+ questionable--see comment where we call them). */
+
+#include "stabsread.h"
+
+/* List of free `struct pending' structures for reuse. */
+
+static struct pending *free_pendings;
+
+/* Non-zero if symtab has line number info. This prevents an
+ otherwise empty symtab from being tossed. */
+
+static int have_line_numbers;
+
+static int compare_line_numbers (const void *ln1p, const void *ln2p);
+
+
+/* Initial sizes of data structures. These are realloc'd larger if
+ needed, and realloc'd down to the size actually used, when
+ completed. */
+
+#define INITIAL_CONTEXT_STACK_SIZE 10
+#define INITIAL_LINE_VECTOR_LENGTH 1000
+
+
+/* Complaints about the symbols we have encountered. */
+
+struct complaint block_end_complaint =
+{"block end address less than block start address in %s (patched it)", 0, 0};
+
+struct complaint anon_block_end_complaint =
+{"block end address 0x%lx less than block start address 0x%lx (patched it)", 0, 0};
+
+struct complaint innerblock_complaint =
+{"inner block not inside outer block in %s", 0, 0};
+
+struct complaint innerblock_anon_complaint =
+{"inner block (0x%lx-0x%lx) not inside outer block (0x%lx-0x%lx)", 0, 0};
+
+struct complaint blockvector_complaint =
+{"block at %s out of order", 0, 0};
+
+/* maintain the lists of symbols and blocks */
+
+/* Add a pending list to free_pendings. */
+void
+add_free_pendings (struct pending *list)
+{
+ register struct pending *link = list;
+
+ if (list)
+ {
+ while (link->next) link = link->next;
+ link->next = free_pendings;
+ free_pendings = list;
+ }
+}
+
+/* Add a symbol to one of the lists of symbols. */
+
+void
+add_symbol_to_list (struct symbol *symbol, struct pending **listhead)
+{
+ register struct pending *link;
+
+ /* If this is an alias for another symbol, don't add it. */
+ if (symbol->ginfo.name && symbol->ginfo.name[0] == '#')
+ return;
+
+ /* We keep PENDINGSIZE symbols in each link of the list. If we
+ don't have a link with room in it, add a new link. */
+ if (*listhead == NULL || (*listhead)->nsyms == PENDINGSIZE)
+ {
+ if (free_pendings)
+ {
+ link = free_pendings;
+ free_pendings = link->next;
+ }
+ else
+ {
+ link = (struct pending *) xmalloc (sizeof (struct pending));
+ }
+
+ link->next = *listhead;
+ *listhead = link;
+ link->nsyms = 0;
+ }
+
+ (*listhead)->symbol[(*listhead)->nsyms++] = symbol;
+}
+
+/* Find a symbol named NAME on a LIST. NAME need not be
+ '\0'-terminated; LENGTH is the length of the name. */
+
+struct symbol *
+find_symbol_in_list (struct pending *list, char *name, int length)
+{
+ int j;
+ char *pp;
+
+ while (list != NULL)
+ {
+ for (j = list->nsyms; --j >= 0;)
+ {
+ pp = SYMBOL_NAME (list->symbol[j]);
+ if (*pp == *name && strncmp (pp, name, length) == 0 &&
+ pp[length] == '\0')
+ {
+ return (list->symbol[j]);
+ }
+ }
+ list = list->next;
+ }
+ return (NULL);
+}
+
+/* At end of reading syms, or in case of quit, really free as many
+ `struct pending's as we can easily find. */
+
+/* ARGSUSED */
+void
+really_free_pendings (PTR dummy)
+{
+ struct pending *next, *next1;
+
+ for (next = free_pendings; next; next = next1)
+ {
+ next1 = next->next;
+ xfree ((void *) next);
+ }
+ free_pendings = NULL;
+
+ free_pending_blocks ();
+
+ for (next = file_symbols; next != NULL; next = next1)
+ {
+ next1 = next->next;
+ xfree ((void *) next);
+ }
+ file_symbols = NULL;
+
+ for (next = global_symbols; next != NULL; next = next1)
+ {
+ next1 = next->next;
+ xfree ((void *) next);
+ }
+ global_symbols = NULL;
+
+ if (pending_macros)
+ free_macro_table (pending_macros);
+}
+
+/* This function is called to discard any pending blocks. */
+
+void
+free_pending_blocks (void)
+{
+#if 0 /* Now we make the links in the
+ symbol_obstack, so don't free
+ them. */
+ struct pending_block *bnext, *bnext1;
+
+ for (bnext = pending_blocks; bnext; bnext = bnext1)
+ {
+ bnext1 = bnext->next;
+ xfree ((void *) bnext);
+ }
+#endif
+ pending_blocks = NULL;
+}
+
+/* Take one of the lists of symbols and make a block from it. Keep
+ the order the symbols have in the list (reversed from the input
+ file). Put the block on the list of pending blocks. */
+
+void
+finish_block (struct symbol *symbol, struct pending **listhead,
+ struct pending_block *old_blocks,
+ CORE_ADDR start, CORE_ADDR end,
+ struct objfile *objfile)
+{
+ register struct pending *next, *next1;
+ register struct block *block;
+ register struct pending_block *pblock;
+ struct pending_block *opblock;
+ register int i;
+ register int j;
+
+ /* Count the length of the list of symbols. */
+
+ for (next = *listhead, i = 0;
+ next;
+ i += next->nsyms, next = next->next)
+ {
+ /* EMPTY */ ;
+ }
+
+ block = (struct block *) obstack_alloc (&objfile->symbol_obstack,
+ (sizeof (struct block) + ((i - 1) * sizeof (struct symbol *))));
+
+ /* Copy the symbols into the block. */
+
+ BLOCK_NSYMS (block) = i;
+ for (next = *listhead; next; next = next->next)
+ {
+ for (j = next->nsyms - 1; j >= 0; j--)
+ {
+ BLOCK_SYM (block, --i) = next->symbol[j];
+ }
+ }
+
+ BLOCK_START (block) = start;
+ BLOCK_END (block) = end;
+ /* Superblock filled in when containing block is made */
+ BLOCK_SUPERBLOCK (block) = NULL;
+
+ BLOCK_GCC_COMPILED (block) = processing_gcc_compilation;
+
+ /* Put the block in as the value of the symbol that names it. */
+
+ if (symbol)
+ {
+ struct type *ftype = SYMBOL_TYPE (symbol);
+ SYMBOL_BLOCK_VALUE (symbol) = block;
+ BLOCK_FUNCTION (block) = symbol;
+
+ if (TYPE_NFIELDS (ftype) <= 0)
+ {
+ /* No parameter type information is recorded with the
+ function's type. Set that from the type of the
+ parameter symbols. */
+ int nparams = 0, iparams;
+ struct symbol *sym;
+ ALL_BLOCK_SYMBOLS (block, i, sym)
+ {
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_BASEREG_ARG:
+ case LOC_LOCAL_ARG:
+ nparams++;
+ break;
+ case LOC_UNDEF:
+ case LOC_CONST:
+ case LOC_STATIC:
+ case LOC_INDIRECT:
+ case LOC_REGISTER:
+ case LOC_LOCAL:
+ case LOC_TYPEDEF:
+ case LOC_LABEL:
+ case LOC_BLOCK:
+ case LOC_CONST_BYTES:
+ case LOC_BASEREG:
+ case LOC_UNRESOLVED:
+ case LOC_OPTIMIZED_OUT:
+ default:
+ break;
+ }
+ }
+ if (nparams > 0)
+ {
+ TYPE_NFIELDS (ftype) = nparams;
+ TYPE_FIELDS (ftype) = (struct field *)
+ TYPE_ALLOC (ftype, nparams * sizeof (struct field));
+
+ for (i = iparams = 0; iparams < nparams; i++)
+ {
+ sym = BLOCK_SYM (block, i);
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_BASEREG_ARG:
+ case LOC_LOCAL_ARG:
+ TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym);
+ TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
+ iparams++;
+ break;
+ case LOC_UNDEF:
+ case LOC_CONST:
+ case LOC_STATIC:
+ case LOC_INDIRECT:
+ case LOC_REGISTER:
+ case LOC_LOCAL:
+ case LOC_TYPEDEF:
+ case LOC_LABEL:
+ case LOC_BLOCK:
+ case LOC_CONST_BYTES:
+ case LOC_BASEREG:
+ case LOC_UNRESOLVED:
+ case LOC_OPTIMIZED_OUT:
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ BLOCK_FUNCTION (block) = NULL;
+ }
+
+ /* Now "free" the links of the list, and empty the list. */
+
+ for (next = *listhead; next; next = next1)
+ {
+ next1 = next->next;
+ next->next = free_pendings;
+ free_pendings = next;
+ }
+ *listhead = NULL;
+
+#if 1
+ /* Check to be sure that the blocks have an end address that is
+ greater than starting address */
+
+ if (BLOCK_END (block) < BLOCK_START (block))
+ {
+ if (symbol)
+ {
+ complain (&block_end_complaint, SYMBOL_SOURCE_NAME (symbol));
+ }
+ else
+ {
+ complain (&anon_block_end_complaint, BLOCK_END (block), BLOCK_START (block));
+ }
+ /* Better than nothing */
+ BLOCK_END (block) = BLOCK_START (block);
+ }
+#endif
+
+ /* Install this block as the superblock of all blocks made since the
+ start of this scope that don't have superblocks yet. */
+
+ opblock = NULL;
+ for (pblock = pending_blocks; pblock != old_blocks; pblock = pblock->next)
+ {
+ if (BLOCK_SUPERBLOCK (pblock->block) == NULL)
+ {
+#if 1
+ /* Check to be sure the blocks are nested as we receive
+ them. If the compiler/assembler/linker work, this just
+ burns a small amount of time. */
+ if (BLOCK_START (pblock->block) < BLOCK_START (block) ||
+ BLOCK_END (pblock->block) > BLOCK_END (block))
+ {
+ if (symbol)
+ {
+ complain (&innerblock_complaint,
+ SYMBOL_SOURCE_NAME (symbol));
+ }
+ else
+ {
+ complain (&innerblock_anon_complaint, BLOCK_START (pblock->block),
+ BLOCK_END (pblock->block), BLOCK_START (block),
+ BLOCK_END (block));
+ }
+ if (BLOCK_START (pblock->block) < BLOCK_START (block))
+ BLOCK_START (pblock->block) = BLOCK_START (block);
+ if (BLOCK_END (pblock->block) > BLOCK_END (block))
+ BLOCK_END (pblock->block) = BLOCK_END (block);
+ }
+#endif
+ BLOCK_SUPERBLOCK (pblock->block) = block;
+ }
+ opblock = pblock;
+ }
+
+ record_pending_block (objfile, block, opblock);
+}
+
+/* Record BLOCK on the list of all blocks in the file. Put it after
+ OPBLOCK, or at the beginning if opblock is NULL. This puts the
+ block in the list after all its subblocks.
+
+ Allocate the pending block struct in the symbol_obstack to save
+ time. This wastes a little space. FIXME: Is it worth it? */
+
+void
+record_pending_block (struct objfile *objfile, struct block *block,
+ struct pending_block *opblock)
+{
+ register struct pending_block *pblock;
+
+ pblock = (struct pending_block *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct pending_block));
+ pblock->block = block;
+ if (opblock)
+ {
+ pblock->next = opblock->next;
+ opblock->next = pblock;
+ }
+ else
+ {
+ pblock->next = pending_blocks;
+ pending_blocks = pblock;
+ }
+}
+
+/* Note that this is only used in this file and in dstread.c, which
+ should be fixed to not need direct access to this function. When
+ that is done, it can be made static again. */
+
+struct blockvector *
+make_blockvector (struct objfile *objfile)
+{
+ register struct pending_block *next;
+ register struct blockvector *blockvector;
+ register int i;
+
+ /* Count the length of the list of blocks. */
+
+ for (next = pending_blocks, i = 0; next; next = next->next, i++)
+ {;
+ }
+
+ blockvector = (struct blockvector *)
+ obstack_alloc (&objfile->symbol_obstack,
+ (sizeof (struct blockvector)
+ + (i - 1) * sizeof (struct block *)));
+
+ /* Copy the blocks into the blockvector. This is done in reverse
+ order, which happens to put the blocks into the proper order
+ (ascending starting address). finish_block has hair to insert
+ each block into the list after its subblocks in order to make
+ sure this is true. */
+
+ BLOCKVECTOR_NBLOCKS (blockvector) = i;
+ for (next = pending_blocks; next; next = next->next)
+ {
+ BLOCKVECTOR_BLOCK (blockvector, --i) = next->block;
+ }
+
+#if 0 /* Now we make the links in the
+ obstack, so don't free them. */
+ /* Now free the links of the list, and empty the list. */
+
+ for (next = pending_blocks; next; next = next1)
+ {
+ next1 = next->next;
+ xfree (next);
+ }
+#endif
+ pending_blocks = NULL;
+
+#if 1 /* FIXME, shut this off after a while
+ to speed up symbol reading. */
+ /* Some compilers output blocks in the wrong order, but we depend on
+ their being in the right order so we can binary search. Check the
+ order and moan about it. FIXME. */
+ if (BLOCKVECTOR_NBLOCKS (blockvector) > 1)
+ {
+ for (i = 1; i < BLOCKVECTOR_NBLOCKS (blockvector); i++)
+ {
+ if (BLOCK_START (BLOCKVECTOR_BLOCK (blockvector, i - 1))
+ > BLOCK_START (BLOCKVECTOR_BLOCK (blockvector, i)))
+ {
+ CORE_ADDR start
+ = BLOCK_START (BLOCKVECTOR_BLOCK (blockvector, i));
+
+ complain (&blockvector_complaint,
+ local_hex_string ((LONGEST) start));
+ }
+ }
+ }
+#endif
+
+ return (blockvector);
+}
+
+/* Start recording information about source code that came from an
+ included (or otherwise merged-in) source file with a different
+ name. NAME is the name of the file (cannot be NULL), DIRNAME is
+ the directory in which it resides (or NULL if not known). */
+
+void
+start_subfile (char *name, char *dirname)
+{
+ register struct subfile *subfile;
+
+ /* See if this subfile is already known as a subfile of the current
+ main source file. */
+
+ for (subfile = subfiles; subfile; subfile = subfile->next)
+ {
+ if (FILENAME_CMP (subfile->name, name) == 0)
+ {
+ current_subfile = subfile;
+ return;
+ }
+ }
+
+ /* This subfile is not known. Add an entry for it. Make an entry
+ for this subfile in the list of all subfiles of the current main
+ source file. */
+
+ subfile = (struct subfile *) xmalloc (sizeof (struct subfile));
+ memset ((char *) subfile, 0, sizeof (struct subfile));
+ subfile->next = subfiles;
+ subfiles = subfile;
+ current_subfile = subfile;
+
+ /* Save its name and compilation directory name */
+ subfile->name = (name == NULL) ? NULL : savestring (name, strlen (name));
+ subfile->dirname =
+ (dirname == NULL) ? NULL : savestring (dirname, strlen (dirname));
+
+ /* Initialize line-number recording for this subfile. */
+ subfile->line_vector = NULL;
+
+ /* Default the source language to whatever can be deduced from the
+ filename. If nothing can be deduced (such as for a C/C++ include
+ file with a ".h" extension), then inherit whatever language the
+ previous subfile had. This kludgery is necessary because there
+ is no standard way in some object formats to record the source
+ language. Also, when symtabs are allocated we try to deduce a
+ language then as well, but it is too late for us to use that
+ information while reading symbols, since symtabs aren't allocated
+ until after all the symbols have been processed for a given
+ source file. */
+
+ subfile->language = deduce_language_from_filename (subfile->name);
+ if (subfile->language == language_unknown &&
+ subfile->next != NULL)
+ {
+ subfile->language = subfile->next->language;
+ }
+
+ /* Initialize the debug format string to NULL. We may supply it
+ later via a call to record_debugformat. */
+ subfile->debugformat = NULL;
+
+ /* cfront output is a C program, so in most ways it looks like a C
+ program. But to demangle we need to set the language to C++. We
+ can distinguish cfront code by the fact that it has #line
+ directives which specify a file name ending in .C.
+
+ So if the filename of this subfile ends in .C, then change the
+ language of any pending subfiles from C to C++. We also accept
+ any other C++ suffixes accepted by deduce_language_from_filename
+ (in particular, some people use .cxx with cfront). */
+ /* Likewise for f2c. */
+
+ if (subfile->name)
+ {
+ struct subfile *s;
+ enum language sublang = deduce_language_from_filename (subfile->name);
+
+ if (sublang == language_cplus || sublang == language_fortran)
+ for (s = subfiles; s != NULL; s = s->next)
+ if (s->language == language_c)
+ s->language = sublang;
+ }
+
+ /* And patch up this file if necessary. */
+ if (subfile->language == language_c
+ && subfile->next != NULL
+ && (subfile->next->language == language_cplus
+ || subfile->next->language == language_fortran))
+ {
+ subfile->language = subfile->next->language;
+ }
+}
+
+/* For stabs readers, the first N_SO symbol is assumed to be the
+ source file name, and the subfile struct is initialized using that
+ assumption. If another N_SO symbol is later seen, immediately
+ following the first one, then the first one is assumed to be the
+ directory name and the second one is really the source file name.
+
+ So we have to patch up the subfile struct by moving the old name
+ value to dirname and remembering the new name. Some sanity
+ checking is performed to ensure that the state of the subfile
+ struct is reasonable and that the old name we are assuming to be a
+ directory name actually is (by checking for a trailing '/'). */
+
+void
+patch_subfile_names (struct subfile *subfile, char *name)
+{
+ if (subfile != NULL && subfile->dirname == NULL && subfile->name != NULL
+ && subfile->name[strlen (subfile->name) - 1] == '/')
+ {
+ subfile->dirname = subfile->name;
+ subfile->name = savestring (name, strlen (name));
+ last_source_file = name;
+
+ /* Default the source language to whatever can be deduced from
+ the filename. If nothing can be deduced (such as for a C/C++
+ include file with a ".h" extension), then inherit whatever
+ language the previous subfile had. This kludgery is
+ necessary because there is no standard way in some object
+ formats to record the source language. Also, when symtabs
+ are allocated we try to deduce a language then as well, but
+ it is too late for us to use that information while reading
+ symbols, since symtabs aren't allocated until after all the
+ symbols have been processed for a given source file. */
+
+ subfile->language = deduce_language_from_filename (subfile->name);
+ if (subfile->language == language_unknown &&
+ subfile->next != NULL)
+ {
+ subfile->language = subfile->next->language;
+ }
+ }
+}
+
+/* Handle the N_BINCL and N_EINCL symbol types that act like N_SOL for
+ switching source files (different subfiles, as we call them) within
+ one object file, but using a stack rather than in an arbitrary
+ order. */
+
+void
+push_subfile (void)
+{
+ register struct subfile_stack *tem
+ = (struct subfile_stack *) xmalloc (sizeof (struct subfile_stack));
+
+ tem->next = subfile_stack;
+ subfile_stack = tem;
+ if (current_subfile == NULL || current_subfile->name == NULL)
+ {
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+ tem->name = current_subfile->name;
+}
+
+char *
+pop_subfile (void)
+{
+ register char *name;
+ register struct subfile_stack *link = subfile_stack;
+
+ if (link == NULL)
+ {
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+ name = link->name;
+ subfile_stack = link->next;
+ xfree ((void *) link);
+ return (name);
+}
+
+/* Add a linetable entry for line number LINE and address PC to the
+ line vector for SUBFILE. */
+
+void
+record_line (register struct subfile *subfile, int line, CORE_ADDR pc)
+{
+ struct linetable_entry *e;
+ /* Ignore the dummy line number in libg.o */
+
+ if (line == 0xffff)
+ {
+ return;
+ }
+
+ /* Make sure line vector exists and is big enough. */
+ if (!subfile->line_vector)
+ {
+ subfile->line_vector_length = INITIAL_LINE_VECTOR_LENGTH;
+ subfile->line_vector = (struct linetable *)
+ xmalloc (sizeof (struct linetable)
+ + subfile->line_vector_length * sizeof (struct linetable_entry));
+ subfile->line_vector->nitems = 0;
+ have_line_numbers = 1;
+ }
+
+ if (subfile->line_vector->nitems + 1 >= subfile->line_vector_length)
+ {
+ subfile->line_vector_length *= 2;
+ subfile->line_vector = (struct linetable *)
+ xrealloc ((char *) subfile->line_vector,
+ (sizeof (struct linetable)
+ + (subfile->line_vector_length
+ * sizeof (struct linetable_entry))));
+ }
+
+ e = subfile->line_vector->item + subfile->line_vector->nitems++;
+ e->line = line;
+ e->pc = ADDR_BITS_REMOVE(pc);
+}
+
+/* Needed in order to sort line tables from IBM xcoff files. Sigh! */
+
+static int
+compare_line_numbers (const void *ln1p, const void *ln2p)
+{
+ struct linetable_entry *ln1 = (struct linetable_entry *) ln1p;
+ struct linetable_entry *ln2 = (struct linetable_entry *) ln2p;
+
+ /* Note: this code does not assume that CORE_ADDRs can fit in ints.
+ Please keep it that way. */
+ if (ln1->pc < ln2->pc)
+ return -1;
+
+ if (ln1->pc > ln2->pc)
+ return 1;
+
+ /* If pc equal, sort by line. I'm not sure whether this is optimum
+ behavior (see comment at struct linetable in symtab.h). */
+ return ln1->line - ln2->line;
+}
+
+/* Start a new symtab for a new source file. Called, for example,
+ when a stabs symbol of type N_SO is seen, or when a DWARF
+ TAG_compile_unit DIE is seen. It indicates the start of data for
+ one original source file. */
+
+void
+start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
+{
+
+ last_source_file = name;
+ last_source_start_addr = start_addr;
+ file_symbols = NULL;
+ global_symbols = NULL;
+ within_function = 0;
+ have_line_numbers = 0;
+
+ /* Context stack is initially empty. Allocate first one with room
+ for 10 levels; reuse it forever afterward. */
+ if (context_stack == NULL)
+ {
+ context_stack_size = INITIAL_CONTEXT_STACK_SIZE;
+ context_stack = (struct context_stack *)
+ xmalloc (context_stack_size * sizeof (struct context_stack));
+ }
+ context_stack_depth = 0;
+
+ /* Initialize the list of sub source files with one entry for this
+ file (the top-level source file). */
+
+ subfiles = NULL;
+ current_subfile = NULL;
+ start_subfile (name, dirname);
+}
+
+/* Finish the symbol definitions for one main source file, close off
+ all the lexical contexts for that file (creating struct block's for
+ them), then make the struct symtab for that file and put it in the
+ list of all such.
+
+ END_ADDR is the address of the end of the file's text. SECTION is
+ the section number (in objfile->section_offsets) of the blockvector
+ and linetable.
+
+ Note that it is possible for end_symtab() to return NULL. In
+ particular, for the DWARF case at least, it will return NULL when
+ it finds a compilation unit that has exactly one DIE, a
+ TAG_compile_unit DIE. This can happen when we link in an object
+ file that was compiled from an empty source file. Returning NULL
+ is probably not the correct thing to do, because then gdb will
+ never know about this empty file (FIXME). */
+
+struct symtab *
+end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
+{
+ register struct symtab *symtab = NULL;
+ register struct blockvector *blockvector;
+ register struct subfile *subfile;
+ register struct context_stack *cstk;
+ struct subfile *nextsub;
+
+ /* Finish the lexical context of the last function in the file; pop
+ the context stack. */
+
+ if (context_stack_depth > 0)
+ {
+ cstk = pop_context ();
+ /* Make a block for the local symbols within. */
+ finish_block (cstk->name, &local_symbols, cstk->old_blocks,
+ cstk->start_addr, end_addr, objfile);
+
+ if (context_stack_depth > 0)
+ {
+ /* This is said to happen with SCO. The old coffread.c
+ code simply emptied the context stack, so we do the
+ same. FIXME: Find out why it is happening. This is not
+ believed to happen in most cases (even for coffread.c);
+ it used to be an abort(). */
+ static struct complaint msg =
+ {"Context stack not empty in end_symtab", 0, 0};
+ complain (&msg);
+ context_stack_depth = 0;
+ }
+ }
+
+ /* Reordered executables may have out of order pending blocks; if
+ OBJF_REORDERED is true, then sort the pending blocks. */
+ if ((objfile->flags & OBJF_REORDERED) && pending_blocks)
+ {
+ /* FIXME! Remove this horrid bubble sort and use merge sort!!! */
+ int swapped;
+ do
+ {
+ struct pending_block *pb, *pbnext;
+
+ pb = pending_blocks;
+ pbnext = pb->next;
+ swapped = 0;
+
+ while (pbnext)
+ {
+ /* swap blocks if unordered! */
+
+ if (BLOCK_START (pb->block) < BLOCK_START (pbnext->block))
+ {
+ struct block *tmp = pb->block;
+ pb->block = pbnext->block;
+ pbnext->block = tmp;
+ swapped = 1;
+ }
+ pb = pbnext;
+ pbnext = pbnext->next;
+ }
+ }
+ while (swapped);
+ }
+
+ /* Cleanup any undefined types that have been left hanging around
+ (this needs to be done before the finish_blocks so that
+ file_symbols is still good).
+
+ Both cleanup_undefined_types and finish_global_stabs are stabs
+ specific, but harmless for other symbol readers, since on gdb
+ startup or when finished reading stabs, the state is set so these
+ are no-ops. FIXME: Is this handled right in case of QUIT? Can
+ we make this cleaner? */
+
+ cleanup_undefined_types ();
+ finish_global_stabs (objfile);
+
+ if (pending_blocks == NULL
+ && file_symbols == NULL
+ && global_symbols == NULL
+ && have_line_numbers == 0
+ && pending_macros == NULL)
+ {
+ /* Ignore symtabs that have no functions with real debugging
+ info. */
+ blockvector = NULL;
+ }
+ else
+ {
+ /* Define the STATIC_BLOCK & GLOBAL_BLOCK, and build the
+ blockvector. */
+ finish_block (0, &file_symbols, 0, last_source_start_addr, end_addr,
+ objfile);
+ finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr,
+ objfile);
+ blockvector = make_blockvector (objfile);
+ }
+
+#ifndef PROCESS_LINENUMBER_HOOK
+#define PROCESS_LINENUMBER_HOOK()
+#endif
+ PROCESS_LINENUMBER_HOOK (); /* Needed for xcoff. */
+
+ /* Now create the symtab objects proper, one for each subfile. */
+ /* (The main file is the last one on the chain.) */
+
+ for (subfile = subfiles; subfile; subfile = nextsub)
+ {
+ int linetablesize = 0;
+ symtab = NULL;
+
+ /* If we have blocks of symbols, make a symtab. Otherwise, just
+ ignore this file and any line number info in it. */
+ if (blockvector)
+ {
+ if (subfile->line_vector)
+ {
+ linetablesize = sizeof (struct linetable) +
+ subfile->line_vector->nitems * sizeof (struct linetable_entry);
+#if 0
+ /* I think this is artifact from before it went on the
+ obstack. I doubt we'll need the memory between now
+ and when we free it later in this function. */
+ /* First, shrink the linetable to make more memory. */
+ subfile->line_vector = (struct linetable *)
+ xrealloc ((char *) subfile->line_vector, linetablesize);
+#endif
+
+ /* Like the pending blocks, the line table may be
+ scrambled in reordered executables. Sort it if
+ OBJF_REORDERED is true. */
+ if (objfile->flags & OBJF_REORDERED)
+ qsort (subfile->line_vector->item,
+ subfile->line_vector->nitems,
+ sizeof (struct linetable_entry), compare_line_numbers);
+ }
+
+ /* Now, allocate a symbol table. */
+ symtab = allocate_symtab (subfile->name, objfile);
+
+ /* Fill in its components. */
+ symtab->blockvector = blockvector;
+ symtab->macro_table = pending_macros;
+ if (subfile->line_vector)
+ {
+ /* Reallocate the line table on the symbol obstack */
+ symtab->linetable = (struct linetable *)
+ obstack_alloc (&objfile->symbol_obstack, linetablesize);
+ memcpy (symtab->linetable, subfile->line_vector, linetablesize);
+ }
+ else
+ {
+ symtab->linetable = NULL;
+ }
+ symtab->block_line_section = section;
+ if (subfile->dirname)
+ {
+ /* Reallocate the dirname on the symbol obstack */
+ symtab->dirname = (char *)
+ obstack_alloc (&objfile->symbol_obstack,
+ strlen (subfile->dirname) + 1);
+ strcpy (symtab->dirname, subfile->dirname);
+ }
+ else
+ {
+ symtab->dirname = NULL;
+ }
+ symtab->free_code = free_linetable;
+ symtab->free_ptr = NULL;
+
+ /* Use whatever language we have been using for this
+ subfile, not the one that was deduced in allocate_symtab
+ from the filename. We already did our own deducing when
+ we created the subfile, and we may have altered our
+ opinion of what language it is from things we found in
+ the symbols. */
+ symtab->language = subfile->language;
+
+ /* Save the debug format string (if any) in the symtab */
+ if (subfile->debugformat != NULL)
+ {
+ symtab->debugformat = obsavestring (subfile->debugformat,
+ strlen (subfile->debugformat),
+ &objfile->symbol_obstack);
+ }
+
+ /* All symtabs for the main file and the subfiles share a
+ blockvector, so we need to clear primary for everything
+ but the main file. */
+
+ symtab->primary = 0;
+ }
+ if (subfile->name != NULL)
+ {
+ xfree ((void *) subfile->name);
+ }
+ if (subfile->dirname != NULL)
+ {
+ xfree ((void *) subfile->dirname);
+ }
+ if (subfile->line_vector != NULL)
+ {
+ xfree ((void *) subfile->line_vector);
+ }
+ if (subfile->debugformat != NULL)
+ {
+ xfree ((void *) subfile->debugformat);
+ }
+
+ nextsub = subfile->next;
+ xfree ((void *) subfile);
+ }
+
+ /* Set this for the main source file. */
+ if (symtab)
+ {
+ symtab->primary = 1;
+ }
+
+ last_source_file = NULL;
+ current_subfile = NULL;
+ pending_macros = NULL;
+
+ return symtab;
+}
+
+/* Push a context block. Args are an identifying nesting level
+ (checkable when you pop it), and the starting PC address of this
+ context. */
+
+struct context_stack *
+push_context (int desc, CORE_ADDR valu)
+{
+ register struct context_stack *new;
+
+ if (context_stack_depth == context_stack_size)
+ {
+ context_stack_size *= 2;
+ context_stack = (struct context_stack *)
+ xrealloc ((char *) context_stack,
+ (context_stack_size * sizeof (struct context_stack)));
+ }
+
+ new = &context_stack[context_stack_depth++];
+ new->depth = desc;
+ new->locals = local_symbols;
+ new->params = param_symbols;
+ new->old_blocks = pending_blocks;
+ new->start_addr = valu;
+ new->name = NULL;
+
+ local_symbols = NULL;
+ param_symbols = NULL;
+
+ return new;
+}
+
+
+/* Compute a small integer hash code for the given name. */
+
+int
+hashname (char *name)
+{
+ return (hash(name,strlen(name)) % HASHSIZE);
+}
+
+
+void
+record_debugformat (char *format)
+{
+ current_subfile->debugformat = savestring (format, strlen (format));
+}
+
+/* Merge the first symbol list SRCLIST into the second symbol list
+ TARGETLIST by repeated calls to add_symbol_to_list(). This
+ procedure "frees" each link of SRCLIST by adding it to the
+ free_pendings list. Caller must set SRCLIST to a null list after
+ calling this function.
+
+ Void return. */
+
+void
+merge_symbol_lists (struct pending **srclist, struct pending **targetlist)
+{
+ register int i;
+
+ if (!srclist || !*srclist)
+ return;
+
+ /* Merge in elements from current link. */
+ for (i = 0; i < (*srclist)->nsyms; i++)
+ add_symbol_to_list ((*srclist)->symbol[i], targetlist);
+
+ /* Recurse on next. */
+ merge_symbol_lists (&(*srclist)->next, targetlist);
+
+ /* "Free" the current link. */
+ (*srclist)->next = free_pendings;
+ free_pendings = (*srclist);
+}
+
+/* Initialize anything that needs initializing when starting to read a
+ fresh piece of a symbol file, e.g. reading in the stuff
+ corresponding to a psymtab. */
+
+void
+buildsym_init (void)
+{
+ free_pendings = NULL;
+ file_symbols = NULL;
+ global_symbols = NULL;
+ pending_blocks = NULL;
+ pending_macros = NULL;
+}
+
+/* Initialize anything that needs initializing when a completely new
+ symbol file is specified (not just adding some symbols from another
+ file, e.g. a shared library). */
+
+void
+buildsym_new_init (void)
+{
+ buildsym_init ();
+}
diff --git a/gdb/buildsym.h b/gdb/buildsym.h
new file mode 100644
index 00000000000..d023aa3e855
--- /dev/null
+++ b/gdb/buildsym.h
@@ -0,0 +1,305 @@
+/* Build symbol tables in GDB's internal format.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1995, 1996,
+ 1997, 1998, 1999, 2000 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. */
+
+#if !defined (BUILDSYM_H)
+#define BUILDSYM_H 1
+
+/* This module provides definitions used for creating and adding to
+ the symbol table. These routines are called from various symbol-
+ file-reading routines.
+
+ They originated in dbxread.c of gdb-4.2, and were split out to
+ make xcoffread.c more maintainable by sharing code.
+
+ Variables declared in this file can be defined by #define-ing the
+ name EXTERN to null. It is used to declare variables that are
+ normally extern, but which get defined in a single module using
+ this technique. */
+
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+
+#define HASHSIZE 127 /* Size of things hashed via
+ hashname() */
+
+/* Name of source file whose symbol data we are now processing. This
+ comes from a symbol of type N_SO. */
+
+EXTERN char *last_source_file;
+
+/* Core address of start of text of current source file. This too
+ comes from the N_SO symbol. */
+
+EXTERN CORE_ADDR last_source_start_addr;
+
+/* The list of sub-source-files within the current individual
+ compilation. Each file gets its own symtab with its own linetable
+ and associated info, but they all share one blockvector. */
+
+struct subfile
+ {
+ struct subfile *next;
+ char *name;
+ char *dirname;
+ struct linetable *line_vector;
+ int line_vector_length;
+ enum language language;
+ char *debugformat;
+ };
+
+EXTERN struct subfile *subfiles;
+
+EXTERN struct subfile *current_subfile;
+
+/* Global variable which, when set, indicates that we are processing a
+ .o file compiled with gcc */
+
+EXTERN unsigned char processing_gcc_compilation;
+
+/* When set, we are processing a .o file compiled by sun acc. This is
+ misnamed; it refers to all stabs-in-elf implementations which use
+ N_UNDF the way Sun does, including Solaris gcc. Hopefully all
+ stabs-in-elf implementations ever invented will choose to be
+ compatible. */
+
+EXTERN unsigned char processing_acc_compilation;
+
+/* elz: added this flag to know when a block is compiled with HP
+ compilers (cc, aCC). This is necessary because of the macro
+ COERCE_FLOAT_TO_DOUBLE defined in tm_hppa.h, which causes a
+ coercion of float to double to always occur in parameter passing
+ for a function called by gdb (see the function value_arg_coerce in
+ valops.c). This is necessary only if the target was compiled with
+ gcc, not with HP compilers or with g++ */
+
+EXTERN unsigned char processing_hp_compilation;
+
+/* Count symbols as they are processed, for error messages. */
+
+EXTERN unsigned int symnum;
+
+/* Record the symbols defined for each context in a list. We don't
+ create a struct block for the context until we know how long to
+ make it. */
+
+#define PENDINGSIZE 100
+
+struct pending
+ {
+ struct pending *next;
+ int nsyms;
+ struct symbol *symbol[PENDINGSIZE];
+ };
+
+/* Here are the three lists that symbols are put on. */
+
+/* static at top level, and types */
+
+EXTERN struct pending *file_symbols;
+
+/* global functions and variables */
+
+EXTERN struct pending *global_symbols;
+
+/* everything local to lexical context */
+
+EXTERN struct pending *local_symbols;
+
+/* func params local to lexical context */
+
+EXTERN struct pending *param_symbols;
+
+/* Stack representing unclosed lexical contexts (that will become
+ blocks, eventually). */
+
+struct context_stack
+ {
+ /* Outer locals at the time we entered */
+
+ struct pending *locals;
+
+ /* Pending func params at the time we entered */
+
+ struct pending *params;
+
+ /* Pointer into blocklist as of entry */
+
+ struct pending_block *old_blocks;
+
+ /* Name of function, if any, defining context */
+
+ struct symbol *name;
+
+ /* PC where this context starts */
+
+ CORE_ADDR start_addr;
+
+ /* Temp slot for exception handling. */
+
+ CORE_ADDR end_addr;
+
+ /* For error-checking matching push/pop */
+
+ int depth;
+
+ };
+
+EXTERN struct context_stack *context_stack;
+
+/* Index of first unused entry in context stack. */
+
+EXTERN int context_stack_depth;
+
+/* Currently allocated size of context stack. */
+
+EXTERN int context_stack_size;
+
+/* Macro "function" for popping contexts from the stack. Pushing is
+ done by a real function, push_context. This returns a pointer to a
+ struct context_stack. */
+
+#define pop_context() (&context_stack[--context_stack_depth]);
+
+/* Nonzero if within a function (so symbols should be local, if
+ nothing says specifically). */
+
+EXTERN int within_function;
+
+/* List of blocks already made (lexical contexts already closed).
+ This is used at the end to make the blockvector. */
+
+struct pending_block
+ {
+ struct pending_block *next;
+ struct block *block;
+ };
+
+/* Pointer to the head of a linked list of symbol blocks which have
+ already been finalized (lexical contexts already closed) and which
+ are just waiting to be built into a blockvector when finalizing the
+ associated symtab. */
+
+EXTERN struct pending_block *pending_blocks;
+
+
+struct subfile_stack
+ {
+ struct subfile_stack *next;
+ char *name;
+ };
+
+EXTERN struct subfile_stack *subfile_stack;
+
+#define next_symbol_text(objfile) (*next_symbol_text_func)(objfile)
+
+/* Function to invoke get the next symbol. Return the symbol name. */
+
+EXTERN char *(*next_symbol_text_func) (struct objfile *);
+
+/* Vector of types defined so far, indexed by their type numbers.
+ Used for both stabs and coff. (In newer sun systems, dbx uses a
+ pair of numbers in parens, as in "(SUBFILENUM,NUMWITHINSUBFILE)".
+ Then these numbers must be translated through the type_translations
+ hash table to get the index into the type vector.) */
+
+EXTERN struct type **type_vector;
+
+/* Number of elements allocated for type_vector currently. */
+
+EXTERN int type_vector_length;
+
+/* Initial size of type vector. Is realloc'd larger if needed, and
+ realloc'd down to the size actually used, when completed. */
+
+#define INITIAL_TYPE_VECTOR_LENGTH 160
+
+extern void add_free_pendings (struct pending *list);
+
+extern void add_symbol_to_list (struct symbol *symbol,
+ struct pending **listhead);
+
+extern struct symbol *find_symbol_in_list (struct pending *list,
+ char *name, int length);
+
+extern void finish_block (struct symbol *symbol,
+ struct pending **listhead,
+ struct pending_block *old_blocks,
+ CORE_ADDR start, CORE_ADDR end,
+ struct objfile *objfile);
+
+extern void really_free_pendings (PTR dummy);
+
+extern void start_subfile (char *name, char *dirname);
+
+extern void patch_subfile_names (struct subfile *subfile, char *name);
+
+extern void push_subfile (void);
+
+extern char *pop_subfile (void);
+
+extern struct symtab *end_symtab (CORE_ADDR end_addr,
+ struct objfile *objfile, int section);
+
+/* Defined in stabsread.c. */
+
+extern void scan_file_globals (struct objfile *objfile);
+
+extern void buildsym_new_init (void);
+
+extern void buildsym_init (void);
+
+extern struct context_stack *push_context (int desc, CORE_ADDR valu);
+
+extern void record_line (struct subfile *subfile, int line, CORE_ADDR pc);
+
+extern void start_symtab (char *name, char *dirname, CORE_ADDR start_addr);
+
+extern int hashname (char *name);
+
+extern void free_pending_blocks (void);
+
+/* FIXME: Note that this is used only in buildsym.c and dstread.c,
+ which should be fixed to not need direct access to
+ make_blockvector. */
+
+extern struct blockvector *make_blockvector (struct objfile *objfile);
+
+/* FIXME: Note that this is used only in buildsym.c and dstread.c,
+ which should be fixed to not need direct access to
+ record_pending_block. */
+
+extern void record_pending_block (struct objfile *objfile,
+ struct block *block,
+ struct pending_block *opblock);
+
+extern void record_debugformat (char *format);
+
+extern void merge_symbol_lists (struct pending **srclist,
+ struct pending **targetlist);
+
+/* The macro table for the compilation unit whose symbols we're
+ currently reading. All the symtabs for this CU will point to this. */
+EXTERN struct macro_table *pending_macros;
+
+#undef EXTERN
+
+#endif /* defined (BUILDSYM_H) */
diff --git a/gdb/builtin-regs.c b/gdb/builtin-regs.c
new file mode 100644
index 00000000000..8c488e3a557
--- /dev/null
+++ b/gdb/builtin-regs.c
@@ -0,0 +1,77 @@
+/* Builtin registers, for GDB, the GNU debugger.
+
+ Copyright 2002 Free Software Foundation, Inc.
+
+ Contributed by Red Hat.
+
+ 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 "defs.h"
+#include "builtin-regs.h"
+#include "gdbtypes.h"
+#include "gdb_string.h"
+#include "gdb_assert.h"
+
+/* Implement builtin register types. Builtin registers have regnum's
+ that live above of the range [0 .. NUM_REGS + NUM_PSEUDO_REGS)
+ (which is controlled by the target). The target should never see a
+ builtin register's regnum value. */
+
+/* An array of builtin registers. Always append, never delete. By
+ doing this, the relative regnum (offset from NUM_REGS +
+ NUM_PSEUDO_REGS) assigned to each builtin register never changes. */
+
+struct builtin_reg
+{
+ const char *name;
+ struct value *(*value) (struct frame_info * frame);
+};
+
+static struct builtin_reg *builtin_regs;
+int nr_builtin_regs;
+
+void
+add_builtin_reg (const char *name, struct value *(*value) (struct frame_info * frame))
+{
+ nr_builtin_regs++;
+ builtin_regs = xrealloc (builtin_regs,
+ nr_builtin_regs * sizeof (builtin_regs[0]));
+ builtin_regs[nr_builtin_regs - 1].name = name;
+ builtin_regs[nr_builtin_regs - 1].value = value;
+}
+
+int
+builtin_reg_map_name_to_regnum (const char *name, int len)
+{
+ int reg;
+ for (reg = 0; reg < nr_builtin_regs; reg++)
+ {
+ if (len == strlen (builtin_regs[reg].name)
+ && strncmp (builtin_regs[reg].name, name, len) == 0)
+ return NUM_REGS + NUM_PSEUDO_REGS + reg;
+ }
+ return -1;
+}
+
+struct value *
+value_of_builtin_reg (int regnum, struct frame_info *frame)
+{
+ int reg = regnum - (NUM_REGS + NUM_PSEUDO_REGS);
+ gdb_assert (reg >= 0 && reg < nr_builtin_regs);
+ return builtin_regs[reg].value (frame);
+}
diff --git a/gdb/builtin-regs.h b/gdb/builtin-regs.h
new file mode 100644
index 00000000000..b35c4e91362
--- /dev/null
+++ b/gdb/builtin-regs.h
@@ -0,0 +1,35 @@
+/* Builtin registers, for GDB, the GNU debugger.
+
+ Copyright 2002 Free Software Foundation, Inc.
+
+ Contributed by Red Hat.
+
+ 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. */
+
+#ifndef BUILTIN_REGS_H
+#define BUILTIN_REGS_H
+
+extern int builtin_reg_map_name_to_regnum (const char *str, int len);
+
+extern struct value *value_of_builtin_reg (int regnum,
+ struct frame_info *frame);
+
+extern void add_builtin_reg (const char *name,
+ struct value *(value) (struct frame_info * frame));
+
+#endif
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
new file mode 100644
index 00000000000..f555518ea00
--- /dev/null
+++ b/gdb/c-exp.y
@@ -0,0 +1,1801 @@
+/* YACC parser for C expressions, for GDB.
+ Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000
+ 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. */
+
+/* Parse a C expression from text in a string,
+ and return the result as a struct expression pointer.
+ That structure contains arithmetic operations in reverse polish,
+ with constants represented by operations that are followed by special data.
+ See expression.h for the details of the format.
+ What is important here is that it can be built up sequentially
+ during the process of parsing; the lower levels of the tree always
+ come first in the result.
+
+ Note that malloc's and realloc's in this file are transformed to
+ xmalloc and xrealloc respectively by the same sed command in the
+ makefile that remaps any other malloc/realloc inserted by the parser
+ generator. Doing this with #defines and trying to control the interaction
+ with include files (<malloc.h> and <stdlib.h> for example) just became
+ too messy, particularly when such includes can be inserted at random
+ times by the parser generator. */
+
+%{
+
+#include "defs.h"
+#include "gdb_string.h"
+#include <ctype.h>
+#include "expression.h"
+#include "value.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "c-lang.h"
+#include "bfd.h" /* Required by objfiles.h. */
+#include "symfile.h" /* Required by objfiles.h. */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+
+/* Flag indicating we're dealing with HP-compiled objects */
+extern int hp_som_som_object_present;
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
+ as well as gratuitiously global symbol names, so we can have multiple
+ yacc generated parsers in gdb. Note that these are only the variables
+ produced by yacc. If other parser generators (bison, byacc, etc) produce
+ additional global names that conflict at link time, then those parser
+ generators need to be fixed instead of adding those names to this list. */
+
+#define yymaxdepth c_maxdepth
+#define yyparse c_parse
+#define yylex c_lex
+#define yyerror c_error
+#define yylval c_lval
+#define yychar c_char
+#define yydebug c_debug
+#define yypact c_pact
+#define yyr1 c_r1
+#define yyr2 c_r2
+#define yydef c_def
+#define yychk c_chk
+#define yypgo c_pgo
+#define yyact c_act
+#define yyexca c_exca
+#define yyerrflag c_errflag
+#define yynerrs c_nerrs
+#define yyps c_ps
+#define yypv c_pv
+#define yys c_s
+#define yy_yys c_yys
+#define yystate c_state
+#define yytmp c_tmp
+#define yyv c_v
+#define yy_yyv c_yyv
+#define yyval c_val
+#define yylloc c_lloc
+#define yyreds c_reds /* With YYDEBUG defined */
+#define yytoks c_toks /* With YYDEBUG defined */
+#define yylhs c_yylhs
+#define yylen c_yylen
+#define yydefred c_yydefred
+#define yydgoto c_yydgoto
+#define yysindex c_yysindex
+#define yyrindex c_yyrindex
+#define yygindex c_yygindex
+#define yytable c_yytable
+#define yycheck c_yycheck
+
+#ifndef YYDEBUG
+#define YYDEBUG 0 /* Default to no yydebug support */
+#endif
+
+int yyparse (void);
+
+static int yylex (void);
+
+void yyerror (char *);
+
+%}
+
+/* Although the yacc "value" of an expression is not used,
+ since the result is stored in the structure being created,
+ other node types do have values. */
+
+%union
+ {
+ LONGEST lval;
+ struct {
+ LONGEST val;
+ struct type *type;
+ } typed_val_int;
+ struct {
+ DOUBLEST dval;
+ struct type *type;
+ } typed_val_float;
+ struct symbol *sym;
+ struct type *tval;
+ struct stoken sval;
+ struct ttype tsym;
+ struct symtoken ssym;
+ int voidval;
+ struct block *bval;
+ enum exp_opcode opcode;
+ struct internalvar *ivar;
+
+ struct type **tvec;
+ int *ivec;
+ }
+
+%{
+/* YYSTYPE gets defined by %union */
+static int parse_number (char *, int, int, YYSTYPE *);
+%}
+
+%type <voidval> exp exp1 type_exp start variable qualified_name lcurly
+%type <lval> rcurly
+%type <tval> type typebase
+%type <tvec> nonempty_typelist
+/* %type <bval> block */
+
+/* Fancy type parsing. */
+%type <voidval> func_mod direct_abs_decl abs_decl
+%type <tval> ptype
+%type <lval> array_mod
+
+%token <typed_val_int> INT
+%token <typed_val_float> FLOAT
+
+/* Both NAME and TYPENAME tokens represent symbols in the input,
+ and both convey their data as strings.
+ But a TYPENAME is a string that happens to be defined as a typedef
+ or builtin type name (such as int or char)
+ and a NAME is any other symbol.
+ Contexts where this distinction is not important can use the
+ nonterminal "name", which matches either NAME or TYPENAME. */
+
+%token <sval> STRING
+%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
+%token <tsym> TYPENAME
+%type <sval> name
+%type <ssym> name_not_typename
+%type <tsym> typename
+
+/* A NAME_OR_INT is a symbol which is not known in the symbol table,
+ but which would parse as a valid number in the current input radix.
+ E.g. "c" when input_radix==16. Depending on the parse, it will be
+ turned into a name or into a number. */
+
+%token <ssym> NAME_OR_INT
+
+%token STRUCT CLASS UNION ENUM SIZEOF UNSIGNED COLONCOLON
+%token TEMPLATE
+%token ERROR
+
+/* Special type cases, put in to allow the parser to distinguish different
+ legal basetypes. */
+%token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD
+
+%token <voidval> VARIABLE
+
+%token <opcode> ASSIGN_MODIFY
+
+/* C++ */
+%token THIS
+%token TRUEKEYWORD
+%token FALSEKEYWORD
+
+
+%left ','
+%left ABOVE_COMMA
+%right '=' ASSIGN_MODIFY
+%right '?'
+%left OROR
+%left ANDAND
+%left '|'
+%left '^'
+%left '&'
+%left EQUAL NOTEQUAL
+%left '<' '>' LEQ GEQ
+%left LSH RSH
+%left '@'
+%left '+' '-'
+%left '*' '/' '%'
+%right UNARY INCREMENT DECREMENT
+%right ARROW '.' '[' '('
+%token <ssym> BLOCKNAME
+%token <bval> FILENAME
+%type <bval> block
+%left COLONCOLON
+
+
+%%
+
+start : exp1
+ | type_exp
+ ;
+
+type_exp: type
+ { write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type($1);
+ write_exp_elt_opcode(OP_TYPE);}
+ ;
+
+/* Expressions, including the comma operator. */
+exp1 : exp
+ | exp1 ',' exp
+ { write_exp_elt_opcode (BINOP_COMMA); }
+ ;
+
+/* Expressions, not including the comma operator. */
+exp : '*' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_IND); }
+
+exp : '&' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_ADDR); }
+
+exp : '-' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_NEG); }
+ ;
+
+exp : '!' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
+ ;
+
+exp : '~' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_COMPLEMENT); }
+ ;
+
+exp : INCREMENT exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_PREINCREMENT); }
+ ;
+
+exp : DECREMENT exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_PREDECREMENT); }
+ ;
+
+exp : exp INCREMENT %prec UNARY
+ { write_exp_elt_opcode (UNOP_POSTINCREMENT); }
+ ;
+
+exp : exp DECREMENT %prec UNARY
+ { write_exp_elt_opcode (UNOP_POSTDECREMENT); }
+ ;
+
+exp : SIZEOF exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_SIZEOF); }
+ ;
+
+exp : exp ARROW name
+ { write_exp_elt_opcode (STRUCTOP_PTR);
+ write_exp_string ($3);
+ write_exp_elt_opcode (STRUCTOP_PTR); }
+ ;
+
+exp : exp ARROW qualified_name
+ { /* exp->type::name becomes exp->*(&type::name) */
+ /* Note: this doesn't work if name is a
+ static member! FIXME */
+ write_exp_elt_opcode (UNOP_ADDR);
+ write_exp_elt_opcode (STRUCTOP_MPTR); }
+ ;
+
+exp : exp ARROW '*' exp
+ { write_exp_elt_opcode (STRUCTOP_MPTR); }
+ ;
+
+exp : exp '.' name
+ { write_exp_elt_opcode (STRUCTOP_STRUCT);
+ write_exp_string ($3);
+ write_exp_elt_opcode (STRUCTOP_STRUCT); }
+ ;
+
+exp : exp '.' qualified_name
+ { /* exp.type::name becomes exp.*(&type::name) */
+ /* Note: this doesn't work if name is a
+ static member! FIXME */
+ write_exp_elt_opcode (UNOP_ADDR);
+ write_exp_elt_opcode (STRUCTOP_MEMBER); }
+ ;
+
+exp : exp '.' '*' exp
+ { write_exp_elt_opcode (STRUCTOP_MEMBER); }
+ ;
+
+exp : exp '[' exp1 ']'
+ { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+ ;
+
+exp : exp '('
+ /* This is to save the value of arglist_len
+ being accumulated by an outer function call. */
+ { start_arglist (); }
+ arglist ')' %prec ARROW
+ { write_exp_elt_opcode (OP_FUNCALL);
+ write_exp_elt_longcst ((LONGEST) end_arglist ());
+ write_exp_elt_opcode (OP_FUNCALL); }
+ ;
+
+lcurly : '{'
+ { start_arglist (); }
+ ;
+
+arglist :
+ ;
+
+arglist : exp
+ { arglist_len = 1; }
+ ;
+
+arglist : arglist ',' exp %prec ABOVE_COMMA
+ { arglist_len++; }
+ ;
+
+rcurly : '}'
+ { $$ = end_arglist () - 1; }
+ ;
+exp : lcurly arglist rcurly %prec ARROW
+ { write_exp_elt_opcode (OP_ARRAY);
+ write_exp_elt_longcst ((LONGEST) 0);
+ write_exp_elt_longcst ((LONGEST) $3);
+ write_exp_elt_opcode (OP_ARRAY); }
+ ;
+
+exp : lcurly type rcurly exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_MEMVAL);
+ write_exp_elt_type ($2);
+ write_exp_elt_opcode (UNOP_MEMVAL); }
+ ;
+
+exp : '(' type ')' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type ($2);
+ write_exp_elt_opcode (UNOP_CAST); }
+ ;
+
+exp : '(' exp1 ')'
+ { }
+ ;
+
+/* Binary operators in order of decreasing precedence. */
+
+exp : exp '@' exp
+ { write_exp_elt_opcode (BINOP_REPEAT); }
+ ;
+
+exp : exp '*' exp
+ { write_exp_elt_opcode (BINOP_MUL); }
+ ;
+
+exp : exp '/' exp
+ { write_exp_elt_opcode (BINOP_DIV); }
+ ;
+
+exp : exp '%' exp
+ { write_exp_elt_opcode (BINOP_REM); }
+ ;
+
+exp : exp '+' exp
+ { write_exp_elt_opcode (BINOP_ADD); }
+ ;
+
+exp : exp '-' exp
+ { write_exp_elt_opcode (BINOP_SUB); }
+ ;
+
+exp : exp LSH exp
+ { write_exp_elt_opcode (BINOP_LSH); }
+ ;
+
+exp : exp RSH exp
+ { write_exp_elt_opcode (BINOP_RSH); }
+ ;
+
+exp : exp EQUAL exp
+ { write_exp_elt_opcode (BINOP_EQUAL); }
+ ;
+
+exp : exp NOTEQUAL exp
+ { write_exp_elt_opcode (BINOP_NOTEQUAL); }
+ ;
+
+exp : exp LEQ exp
+ { write_exp_elt_opcode (BINOP_LEQ); }
+ ;
+
+exp : exp GEQ exp
+ { write_exp_elt_opcode (BINOP_GEQ); }
+ ;
+
+exp : exp '<' exp
+ { write_exp_elt_opcode (BINOP_LESS); }
+ ;
+
+exp : exp '>' exp
+ { write_exp_elt_opcode (BINOP_GTR); }
+ ;
+
+exp : exp '&' exp
+ { write_exp_elt_opcode (BINOP_BITWISE_AND); }
+ ;
+
+exp : exp '^' exp
+ { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
+ ;
+
+exp : exp '|' exp
+ { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
+ ;
+
+exp : exp ANDAND exp
+ { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
+ ;
+
+exp : exp OROR exp
+ { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
+ ;
+
+exp : exp '?' exp ':' exp %prec '?'
+ { write_exp_elt_opcode (TERNOP_COND); }
+ ;
+
+exp : exp '=' exp
+ { write_exp_elt_opcode (BINOP_ASSIGN); }
+ ;
+
+exp : exp ASSIGN_MODIFY exp
+ { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
+ write_exp_elt_opcode ($2);
+ write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
+ ;
+
+exp : INT
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type ($1.type);
+ write_exp_elt_longcst ((LONGEST)($1.val));
+ write_exp_elt_opcode (OP_LONG); }
+ ;
+
+exp : NAME_OR_INT
+ { YYSTYPE val;
+ parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val);
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (val.typed_val_int.type);
+ write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
+ write_exp_elt_opcode (OP_LONG);
+ }
+ ;
+
+
+exp : FLOAT
+ { write_exp_elt_opcode (OP_DOUBLE);
+ write_exp_elt_type ($1.type);
+ write_exp_elt_dblcst ($1.dval);
+ write_exp_elt_opcode (OP_DOUBLE); }
+ ;
+
+exp : variable
+ ;
+
+exp : VARIABLE
+ /* Already written by write_dollar_variable. */
+ ;
+
+exp : SIZEOF '(' type ')' %prec UNARY
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_int);
+ CHECK_TYPEDEF ($3);
+ write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
+ write_exp_elt_opcode (OP_LONG); }
+ ;
+
+exp : STRING
+ { /* C strings are converted into array constants with
+ an explicit null byte added at the end. Thus
+ the array upper bound is the string length.
+ There is no such thing in C as a completely empty
+ string. */
+ char *sp = $1.ptr; int count = $1.length;
+ while (count-- > 0)
+ {
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_char);
+ write_exp_elt_longcst ((LONGEST)(*sp++));
+ write_exp_elt_opcode (OP_LONG);
+ }
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_char);
+ write_exp_elt_longcst ((LONGEST)'\0');
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_opcode (OP_ARRAY);
+ write_exp_elt_longcst ((LONGEST) 0);
+ write_exp_elt_longcst ((LONGEST) ($1.length));
+ write_exp_elt_opcode (OP_ARRAY); }
+ ;
+
+/* C++. */
+exp : THIS
+ { write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (OP_THIS); }
+ ;
+
+exp : TRUEKEYWORD
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_bool);
+ write_exp_elt_longcst ((LONGEST) 1);
+ write_exp_elt_opcode (OP_LONG); }
+ ;
+
+exp : FALSEKEYWORD
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_bool);
+ write_exp_elt_longcst ((LONGEST) 0);
+ write_exp_elt_opcode (OP_LONG); }
+ ;
+
+/* end of C++. */
+
+block : BLOCKNAME
+ {
+ if ($1.sym)
+ $$ = SYMBOL_BLOCK_VALUE ($1.sym);
+ else
+ error ("No file or function \"%s\".",
+ copy_name ($1.stoken));
+ }
+ | FILENAME
+ {
+ $$ = $1;
+ }
+ ;
+
+block : block COLONCOLON name
+ { struct symbol *tem
+ = lookup_symbol (copy_name ($3), $1,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK)
+ error ("No function \"%s\" in specified context.",
+ copy_name ($3));
+ $$ = SYMBOL_BLOCK_VALUE (tem); }
+ ;
+
+variable: block COLONCOLON name
+ { struct symbol *sym;
+ sym = lookup_symbol (copy_name ($3), $1,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ if (sym == 0)
+ error ("No symbol \"%s\" in specified context.",
+ copy_name ($3));
+
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ /* block_found is set by lookup_symbol. */
+ write_exp_elt_block (block_found);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE); }
+ ;
+
+qualified_name: typebase COLONCOLON name
+ {
+ struct type *type = $1;
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+ && TYPE_CODE (type) != TYPE_CODE_UNION)
+ error ("`%s' is not defined as an aggregate type.",
+ TYPE_NAME (type));
+
+ write_exp_elt_opcode (OP_SCOPE);
+ write_exp_elt_type (type);
+ write_exp_string ($3);
+ write_exp_elt_opcode (OP_SCOPE);
+ }
+ | typebase COLONCOLON '~' name
+ {
+ struct type *type = $1;
+ struct stoken tmp_token;
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+ && TYPE_CODE (type) != TYPE_CODE_UNION)
+ error ("`%s' is not defined as an aggregate type.",
+ TYPE_NAME (type));
+
+ tmp_token.ptr = (char*) alloca ($4.length + 2);
+ tmp_token.length = $4.length + 1;
+ tmp_token.ptr[0] = '~';
+ memcpy (tmp_token.ptr+1, $4.ptr, $4.length);
+ tmp_token.ptr[tmp_token.length] = 0;
+
+ /* Check for valid destructor name. */
+ destructor_name_p (tmp_token.ptr, type);
+ write_exp_elt_opcode (OP_SCOPE);
+ write_exp_elt_type (type);
+ write_exp_string (tmp_token);
+ write_exp_elt_opcode (OP_SCOPE);
+ }
+ ;
+
+variable: qualified_name
+ | COLONCOLON name
+ {
+ char *name = copy_name ($2);
+ struct symbol *sym;
+ struct minimal_symbol *msymbol;
+
+ sym =
+ lookup_symbol (name, (const struct block *) NULL,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ if (sym)
+ {
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ write_exp_elt_block (NULL);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ break;
+ }
+
+ msymbol = lookup_minimal_symbol (name, NULL, NULL);
+ if (msymbol != NULL)
+ {
+ write_exp_msymbol (msymbol,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
+ }
+ else
+ if (!have_full_symbols () && !have_partial_symbols ())
+ error ("No symbol table is loaded. Use the \"file\" command.");
+ else
+ error ("No symbol \"%s\" in current context.", name);
+ }
+ ;
+
+variable: name_not_typename
+ { struct symbol *sym = $1.sym;
+
+ if (sym)
+ {
+ if (symbol_read_needs_frame (sym))
+ {
+ if (innermost_block == 0 ||
+ contained_in (block_found,
+ innermost_block))
+ innermost_block = block_found;
+ }
+
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ /* We want to use the selected frame, not
+ another more inner frame which happens to
+ be in the same block. */
+ write_exp_elt_block (NULL);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ }
+ else if ($1.is_a_field_of_this)
+ {
+ /* C++: it hangs off of `this'. Must
+ not inadvertently convert from a method call
+ to data ref. */
+ if (innermost_block == 0 ||
+ contained_in (block_found, innermost_block))
+ innermost_block = block_found;
+ write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (STRUCTOP_PTR);
+ write_exp_string ($1.stoken);
+ write_exp_elt_opcode (STRUCTOP_PTR);
+ }
+ else
+ {
+ struct minimal_symbol *msymbol;
+ register char *arg = copy_name ($1.stoken);
+
+ msymbol =
+ lookup_minimal_symbol (arg, NULL, NULL);
+ if (msymbol != NULL)
+ {
+ write_exp_msymbol (msymbol,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
+ }
+ else if (!have_full_symbols () && !have_partial_symbols ())
+ error ("No symbol table is loaded. Use the \"file\" command.");
+ else
+ error ("No symbol \"%s\" in current context.",
+ copy_name ($1.stoken));
+ }
+ }
+ ;
+
+space_identifier : '@' NAME
+ { push_type_address_space (copy_name ($2.stoken));
+ push_type (tp_space_identifier);
+ }
+ ;
+
+const_or_volatile: const_or_volatile_noopt
+ |
+ ;
+
+cv_with_space_id : const_or_volatile space_identifier const_or_volatile
+ ;
+
+const_or_volatile_or_space_identifier_noopt: cv_with_space_id
+ | const_or_volatile_noopt
+ ;
+
+const_or_volatile_or_space_identifier:
+ const_or_volatile_or_space_identifier_noopt
+ |
+ ;
+
+abs_decl: '*'
+ { push_type (tp_pointer); $$ = 0; }
+ | '*' abs_decl
+ { push_type (tp_pointer); $$ = $2; }
+ | '&'
+ { push_type (tp_reference); $$ = 0; }
+ | '&' abs_decl
+ { push_type (tp_reference); $$ = $2; }
+ | direct_abs_decl
+ ;
+
+direct_abs_decl: '(' abs_decl ')'
+ { $$ = $2; }
+ | direct_abs_decl array_mod
+ {
+ push_type_int ($2);
+ push_type (tp_array);
+ }
+ | array_mod
+ {
+ push_type_int ($1);
+ push_type (tp_array);
+ $$ = 0;
+ }
+
+ | direct_abs_decl func_mod
+ { push_type (tp_function); }
+ | func_mod
+ { push_type (tp_function); }
+ ;
+
+array_mod: '[' ']'
+ { $$ = -1; }
+ | '[' INT ']'
+ { $$ = $2.val; }
+ ;
+
+func_mod: '(' ')'
+ { $$ = 0; }
+ | '(' nonempty_typelist ')'
+ { free ((PTR)$2); $$ = 0; }
+ ;
+
+/* We used to try to recognize more pointer to member types here, but
+ that didn't work (shift/reduce conflicts meant that these rules never
+ got executed). The problem is that
+ int (foo::bar::baz::bizzle)
+ is a function type but
+ int (foo::bar::baz::bizzle::*)
+ is a pointer to member type. Stroustrup loses again! */
+
+type : ptype
+ | typebase COLONCOLON '*'
+ { $$ = lookup_member_type (builtin_type_int, $1); }
+ ;
+
+typebase /* Implements (approximately): (type-qualifier)* type-specifier */
+ : TYPENAME
+ { $$ = $1.type; }
+ | INT_KEYWORD
+ { $$ = builtin_type_int; }
+ | LONG
+ { $$ = builtin_type_long; }
+ | SHORT
+ { $$ = builtin_type_short; }
+ | LONG INT_KEYWORD
+ { $$ = builtin_type_long; }
+ | LONG SIGNED_KEYWORD INT_KEYWORD
+ { $$ = builtin_type_long; }
+ | LONG SIGNED_KEYWORD
+ { $$ = builtin_type_long; }
+ | SIGNED_KEYWORD LONG INT_KEYWORD
+ { $$ = builtin_type_long; }
+ | UNSIGNED LONG INT_KEYWORD
+ { $$ = builtin_type_unsigned_long; }
+ | LONG UNSIGNED INT_KEYWORD
+ { $$ = builtin_type_unsigned_long; }
+ | LONG UNSIGNED
+ { $$ = builtin_type_unsigned_long; }
+ | LONG LONG
+ { $$ = builtin_type_long_long; }
+ | LONG LONG INT_KEYWORD
+ { $$ = builtin_type_long_long; }
+ | LONG LONG SIGNED_KEYWORD INT_KEYWORD
+ { $$ = builtin_type_long_long; }
+ | LONG LONG SIGNED_KEYWORD
+ { $$ = builtin_type_long_long; }
+ | SIGNED_KEYWORD LONG LONG
+ { $$ = builtin_type_long_long; }
+ | UNSIGNED LONG LONG
+ { $$ = builtin_type_unsigned_long_long; }
+ | UNSIGNED LONG LONG INT_KEYWORD
+ { $$ = builtin_type_unsigned_long_long; }
+ | LONG LONG UNSIGNED
+ { $$ = builtin_type_unsigned_long_long; }
+ | LONG LONG UNSIGNED INT_KEYWORD
+ { $$ = builtin_type_unsigned_long_long; }
+ | SIGNED_KEYWORD LONG LONG
+ { $$ = lookup_signed_typename ("long long"); }
+ | SIGNED_KEYWORD LONG LONG INT_KEYWORD
+ { $$ = lookup_signed_typename ("long long"); }
+ | SHORT INT_KEYWORD
+ { $$ = builtin_type_short; }
+ | SHORT SIGNED_KEYWORD INT_KEYWORD
+ { $$ = builtin_type_short; }
+ | SHORT SIGNED_KEYWORD
+ { $$ = builtin_type_short; }
+ | UNSIGNED SHORT INT_KEYWORD
+ { $$ = builtin_type_unsigned_short; }
+ | SHORT UNSIGNED
+ { $$ = builtin_type_unsigned_short; }
+ | SHORT UNSIGNED INT_KEYWORD
+ { $$ = builtin_type_unsigned_short; }
+ | DOUBLE_KEYWORD
+ { $$ = builtin_type_double; }
+ | LONG DOUBLE_KEYWORD
+ { $$ = builtin_type_long_double; }
+ | STRUCT name
+ { $$ = lookup_struct (copy_name ($2),
+ expression_context_block); }
+ | CLASS name
+ { $$ = lookup_struct (copy_name ($2),
+ expression_context_block); }
+ | UNION name
+ { $$ = lookup_union (copy_name ($2),
+ expression_context_block); }
+ | ENUM name
+ { $$ = lookup_enum (copy_name ($2),
+ expression_context_block); }
+ | UNSIGNED typename
+ { $$ = lookup_unsigned_typename (TYPE_NAME($2.type)); }
+ | UNSIGNED
+ { $$ = builtin_type_unsigned_int; }
+ | SIGNED_KEYWORD typename
+ { $$ = lookup_signed_typename (TYPE_NAME($2.type)); }
+ | SIGNED_KEYWORD
+ { $$ = builtin_type_int; }
+ /* It appears that this rule for templates is never
+ reduced; template recognition happens by lookahead
+ in the token processing code in yylex. */
+ | TEMPLATE name '<' type '>'
+ { $$ = lookup_template_type(copy_name($2), $4,
+ expression_context_block);
+ }
+ | const_or_volatile_or_space_identifier_noopt typebase
+ { $$ = follow_types ($2); }
+ | typebase const_or_volatile_or_space_identifier_noopt
+ { $$ = follow_types ($1); }
+ ;
+
+typename: TYPENAME
+ | INT_KEYWORD
+ {
+ $$.stoken.ptr = "int";
+ $$.stoken.length = 3;
+ $$.type = builtin_type_int;
+ }
+ | LONG
+ {
+ $$.stoken.ptr = "long";
+ $$.stoken.length = 4;
+ $$.type = builtin_type_long;
+ }
+ | SHORT
+ {
+ $$.stoken.ptr = "short";
+ $$.stoken.length = 5;
+ $$.type = builtin_type_short;
+ }
+ ;
+
+nonempty_typelist
+ : type
+ { $$ = (struct type **) malloc (sizeof (struct type *) * 2);
+ $<ivec>$[0] = 1; /* Number of types in vector */
+ $$[1] = $1;
+ }
+ | nonempty_typelist ',' type
+ { int len = sizeof (struct type *) * (++($<ivec>1[0]) + 1);
+ $$ = (struct type **) realloc ((char *) $1, len);
+ $$[$<ivec>$[0]] = $3;
+ }
+ ;
+
+ptype : typebase
+ | ptype const_or_volatile_or_space_identifier abs_decl const_or_volatile_or_space_identifier
+ { $$ = follow_types ($1); }
+ ;
+
+const_and_volatile: CONST_KEYWORD VOLATILE_KEYWORD
+ | VOLATILE_KEYWORD CONST_KEYWORD
+ ;
+
+const_or_volatile_noopt: const_and_volatile
+ { push_type (tp_const);
+ push_type (tp_volatile);
+ }
+ | CONST_KEYWORD
+ { push_type (tp_const); }
+ | VOLATILE_KEYWORD
+ { push_type (tp_volatile); }
+ ;
+
+name : NAME { $$ = $1.stoken; }
+ | BLOCKNAME { $$ = $1.stoken; }
+ | TYPENAME { $$ = $1.stoken; }
+ | NAME_OR_INT { $$ = $1.stoken; }
+ ;
+
+name_not_typename : NAME
+ | BLOCKNAME
+/* These would be useful if name_not_typename was useful, but it is just
+ a fake for "variable", so these cause reduce/reduce conflicts because
+ the parser can't tell whether NAME_OR_INT is a name_not_typename (=variable,
+ =exp) or just an exp. If name_not_typename was ever used in an lvalue
+ context where only a name could occur, this might be useful.
+ | NAME_OR_INT
+ */
+ ;
+
+%%
+
+/* Take care of parsing a number (anything that starts with a digit).
+ Set yylval and return the token type; update lexptr.
+ LEN is the number of characters in it. */
+
+/*** Needs some error checking for the float case ***/
+
+static int
+parse_number (p, len, parsed_float, putithere)
+ register char *p;
+ register int len;
+ int parsed_float;
+ YYSTYPE *putithere;
+{
+ /* FIXME: Shouldn't these be unsigned? We don't deal with negative values
+ here, and we do kind of silly things like cast to unsigned. */
+ register LONGEST n = 0;
+ register LONGEST prevn = 0;
+ ULONGEST un;
+
+ register int i = 0;
+ register int c;
+ register int base = input_radix;
+ int unsigned_p = 0;
+
+ /* Number of "L" suffixes encountered. */
+ int long_p = 0;
+
+ /* We have found a "L" or "U" suffix. */
+ int found_suffix = 0;
+
+ ULONGEST high_bit;
+ struct type *signed_type;
+ struct type *unsigned_type;
+
+ if (parsed_float)
+ {
+ /* It's a float since it contains a point or an exponent. */
+ char c;
+ int num = 0; /* number of tokens scanned by scanf */
+ char saved_char = p[len];
+
+ p[len] = 0; /* null-terminate the token */
+ if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
+ num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval,&c);
+ else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
+ num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval,&c);
+ else
+ {
+#ifdef SCANF_HAS_LONG_DOUBLE
+ num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval,&c);
+#else
+ /* Scan it into a double, then assign it to the long double.
+ This at least wins with values representable in the range
+ of doubles. */
+ double temp;
+ num = sscanf (p, "%lg%c", &temp,&c);
+ putithere->typed_val_float.dval = temp;
+#endif
+ }
+ p[len] = saved_char; /* restore the input stream */
+ if (num != 1) /* check scanf found ONLY a float ... */
+ return ERROR;
+ /* See if it has `f' or `l' suffix (float or long double). */
+
+ c = tolower (p[len - 1]);
+
+ if (c == 'f')
+ putithere->typed_val_float.type = builtin_type_float;
+ else if (c == 'l')
+ putithere->typed_val_float.type = builtin_type_long_double;
+ else if (isdigit (c) || c == '.')
+ putithere->typed_val_float.type = builtin_type_double;
+ else
+ return ERROR;
+
+ return FLOAT;
+ }
+
+ /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
+ if (p[0] == '0')
+ switch (p[1])
+ {
+ case 'x':
+ case 'X':
+ if (len >= 3)
+ {
+ p += 2;
+ base = 16;
+ len -= 2;
+ }
+ break;
+
+ case 't':
+ case 'T':
+ case 'd':
+ case 'D':
+ if (len >= 3)
+ {
+ p += 2;
+ base = 10;
+ len -= 2;
+ }
+ break;
+
+ default:
+ base = 8;
+ break;
+ }
+
+ while (len-- > 0)
+ {
+ c = *p++;
+ if (c >= 'A' && c <= 'Z')
+ c += 'a' - 'A';
+ if (c != 'l' && c != 'u')
+ n *= base;
+ if (c >= '0' && c <= '9')
+ {
+ if (found_suffix)
+ return ERROR;
+ n += i = c - '0';
+ }
+ else
+ {
+ if (base > 10 && c >= 'a' && c <= 'f')
+ {
+ if (found_suffix)
+ return ERROR;
+ n += i = c - 'a' + 10;
+ }
+ else if (c == 'l')
+ {
+ ++long_p;
+ found_suffix = 1;
+ }
+ else if (c == 'u')
+ {
+ unsigned_p = 1;
+ found_suffix = 1;
+ }
+ else
+ return ERROR; /* Char not a digit */
+ }
+ if (i >= base)
+ return ERROR; /* Invalid digit in this base */
+
+ /* Portably test for overflow (only works for nonzero values, so make
+ a second check for zero). FIXME: Can't we just make n and prevn
+ unsigned and avoid this? */
+ if (c != 'l' && c != 'u' && (prevn >= n) && n != 0)
+ unsigned_p = 1; /* Try something unsigned */
+
+ /* Portably test for unsigned overflow.
+ FIXME: This check is wrong; for example it doesn't find overflow
+ on 0x123456789 when LONGEST is 32 bits. */
+ if (c != 'l' && c != 'u' && n != 0)
+ {
+ if ((unsigned_p && (ULONGEST) prevn >= (ULONGEST) n))
+ error ("Numeric constant too large.");
+ }
+ prevn = n;
+ }
+
+ /* An integer constant is an int, a long, or a long long. An L
+ suffix forces it to be long; an LL suffix forces it to be long
+ long. If not forced to a larger size, it gets the first type of
+ the above that it fits in. To figure out whether it fits, we
+ shift it right and see whether anything remains. Note that we
+ can't shift sizeof (LONGEST) * HOST_CHAR_BIT bits or more in one
+ operation, because many compilers will warn about such a shift
+ (which always produces a zero result). Sometimes TARGET_INT_BIT
+ or TARGET_LONG_BIT will be that big, sometimes not. To deal with
+ the case where it is we just always shift the value more than
+ once, with fewer bits each time. */
+
+ un = (ULONGEST)n >> 2;
+ if (long_p == 0
+ && (un >> (TARGET_INT_BIT - 2)) == 0)
+ {
+ high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1);
+
+ /* A large decimal (not hex or octal) constant (between INT_MAX
+ and UINT_MAX) is a long or unsigned long, according to ANSI,
+ never an unsigned int, but this code treats it as unsigned
+ int. This probably should be fixed. GCC gives a warning on
+ such constants. */
+
+ unsigned_type = builtin_type_unsigned_int;
+ signed_type = builtin_type_int;
+ }
+ else if (long_p <= 1
+ && (un >> (TARGET_LONG_BIT - 2)) == 0)
+ {
+ high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1);
+ unsigned_type = builtin_type_unsigned_long;
+ signed_type = builtin_type_long;
+ }
+ else
+ {
+ int shift;
+ if (sizeof (ULONGEST) * HOST_CHAR_BIT < TARGET_LONG_LONG_BIT)
+ /* A long long does not fit in a LONGEST. */
+ shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1);
+ else
+ shift = (TARGET_LONG_LONG_BIT - 1);
+ high_bit = (ULONGEST) 1 << shift;
+ unsigned_type = builtin_type_unsigned_long_long;
+ signed_type = builtin_type_long_long;
+ }
+
+ putithere->typed_val_int.val = n;
+
+ /* If the high bit of the worked out type is set then this number
+ has to be unsigned. */
+
+ if (unsigned_p || (n & high_bit))
+ {
+ putithere->typed_val_int.type = unsigned_type;
+ }
+ else
+ {
+ putithere->typed_val_int.type = signed_type;
+ }
+
+ return INT;
+}
+
+struct token
+{
+ char *operator;
+ int token;
+ enum exp_opcode opcode;
+};
+
+static const struct token tokentab3[] =
+ {
+ {">>=", ASSIGN_MODIFY, BINOP_RSH},
+ {"<<=", ASSIGN_MODIFY, BINOP_LSH}
+ };
+
+static const struct token tokentab2[] =
+ {
+ {"+=", ASSIGN_MODIFY, BINOP_ADD},
+ {"-=", ASSIGN_MODIFY, BINOP_SUB},
+ {"*=", ASSIGN_MODIFY, BINOP_MUL},
+ {"/=", ASSIGN_MODIFY, BINOP_DIV},
+ {"%=", ASSIGN_MODIFY, BINOP_REM},
+ {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
+ {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
+ {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
+ {"++", INCREMENT, BINOP_END},
+ {"--", DECREMENT, BINOP_END},
+ {"->", ARROW, BINOP_END},
+ {"&&", ANDAND, BINOP_END},
+ {"||", OROR, BINOP_END},
+ {"::", COLONCOLON, BINOP_END},
+ {"<<", LSH, BINOP_END},
+ {">>", RSH, BINOP_END},
+ {"==", EQUAL, BINOP_END},
+ {"!=", NOTEQUAL, BINOP_END},
+ {"<=", LEQ, BINOP_END},
+ {">=", GEQ, BINOP_END}
+ };
+
+/* Read one token, getting characters through lexptr. */
+
+static int
+yylex ()
+{
+ int c;
+ int namelen;
+ unsigned int i;
+ char *tokstart;
+ char *tokptr;
+ int tempbufindex;
+ static char *tempbuf;
+ static int tempbufsize;
+ struct symbol * sym_class = NULL;
+ char * token_string = NULL;
+ int class_prefix = 0;
+ int unquoted_expr;
+
+ retry:
+
+ /* Check if this is a macro invocation that we need to expand. */
+ if (! scanning_macro_expansion ())
+ {
+ char *expanded = macro_expand_next (&lexptr,
+ expression_macro_lookup_func,
+ expression_macro_lookup_baton);
+
+ if (expanded)
+ scan_macro_expansion (expanded);
+ }
+
+ prev_lexptr = lexptr;
+ unquoted_expr = 1;
+
+ tokstart = lexptr;
+ /* See if it is a special token of length 3. */
+ for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
+ if (STREQN (tokstart, tokentab3[i].operator, 3))
+ {
+ lexptr += 3;
+ yylval.opcode = tokentab3[i].opcode;
+ return tokentab3[i].token;
+ }
+
+ /* See if it is a special token of length 2. */
+ for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
+ if (STREQN (tokstart, tokentab2[i].operator, 2))
+ {
+ lexptr += 2;
+ yylval.opcode = tokentab2[i].opcode;
+ return tokentab2[i].token;
+ }
+
+ switch (c = *tokstart)
+ {
+ case 0:
+ /* If we were just scanning the result of a macro expansion,
+ then we need to resume scanning the original text.
+ Otherwise, we were already scanning the original text, and
+ we're really done. */
+ if (scanning_macro_expansion ())
+ {
+ finished_macro_expansion ();
+ goto retry;
+ }
+ else
+ return 0;
+
+ case ' ':
+ case '\t':
+ case '\n':
+ lexptr++;
+ goto retry;
+
+ case '\'':
+ /* We either have a character constant ('0' or '\177' for example)
+ or we have a quoted symbol reference ('foo(int,int)' in C++
+ for example). */
+ lexptr++;
+ c = *lexptr++;
+ if (c == '\\')
+ c = parse_escape (&lexptr);
+ else if (c == '\'')
+ error ("Empty character constant.");
+
+ yylval.typed_val_int.val = c;
+ yylval.typed_val_int.type = builtin_type_char;
+
+ c = *lexptr++;
+ if (c != '\'')
+ {
+ namelen = skip_quoted (tokstart) - tokstart;
+ if (namelen > 2)
+ {
+ lexptr = tokstart + namelen;
+ unquoted_expr = 0;
+ if (lexptr[-1] != '\'')
+ error ("Unmatched single quote.");
+ namelen -= 2;
+ tokstart++;
+ goto tryname;
+ }
+ error ("Invalid character constant.");
+ }
+ return INT;
+
+ case '(':
+ paren_depth++;
+ lexptr++;
+ return c;
+
+ case ')':
+ if (paren_depth == 0)
+ return 0;
+ paren_depth--;
+ lexptr++;
+ return c;
+
+ case ',':
+ if (comma_terminates
+ && paren_depth == 0
+ && ! scanning_macro_expansion ())
+ return 0;
+ lexptr++;
+ return c;
+
+ case '.':
+ /* Might be a floating point number. */
+ if (lexptr[1] < '0' || lexptr[1] > '9')
+ goto symbol; /* Nope, must be a symbol. */
+ /* FALL THRU into number case. */
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ /* It's a number. */
+ int got_dot = 0, got_e = 0, toktype;
+ register char *p = tokstart;
+ int hex = input_radix > 10;
+
+ if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
+ {
+ p += 2;
+ hex = 1;
+ }
+ else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
+ {
+ p += 2;
+ hex = 0;
+ }
+
+ for (;; ++p)
+ {
+ /* This test includes !hex because 'e' is a valid hex digit
+ and thus does not indicate a floating point number when
+ the radix is hex. */
+ if (!hex && !got_e && (*p == 'e' || *p == 'E'))
+ got_dot = got_e = 1;
+ /* This test does not include !hex, because a '.' always indicates
+ a decimal floating point number regardless of the radix. */
+ else if (!got_dot && *p == '.')
+ got_dot = 1;
+ else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
+ && (*p == '-' || *p == '+'))
+ /* This is the sign of the exponent, not the end of the
+ number. */
+ continue;
+ /* We will take any letters or digits. parse_number will
+ complain if past the radix, or if L or U are not final. */
+ else if ((*p < '0' || *p > '9')
+ && ((*p < 'a' || *p > 'z')
+ && (*p < 'A' || *p > 'Z')))
+ break;
+ }
+ toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
+ if (toktype == ERROR)
+ {
+ char *err_copy = (char *) alloca (p - tokstart + 1);
+
+ memcpy (err_copy, tokstart, p - tokstart);
+ err_copy[p - tokstart] = 0;
+ error ("Invalid number \"%s\".", err_copy);
+ }
+ lexptr = p;
+ return toktype;
+ }
+
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '%':
+ case '|':
+ case '&':
+ case '^':
+ case '~':
+ case '!':
+ case '@':
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case '?':
+ case ':':
+ case '=':
+ case '{':
+ case '}':
+ symbol:
+ lexptr++;
+ return c;
+
+ case '"':
+
+ /* Build the gdb internal form of the input string in tempbuf,
+ translating any standard C escape forms seen. Note that the
+ buffer is null byte terminated *only* for the convenience of
+ debugging gdb itself and printing the buffer contents when
+ the buffer contains no embedded nulls. Gdb does not depend
+ upon the buffer being null byte terminated, it uses the length
+ string instead. This allows gdb to handle C strings (as well
+ as strings in other languages) with embedded null bytes */
+
+ tokptr = ++tokstart;
+ tempbufindex = 0;
+
+ do {
+ /* Grow the static temp buffer if necessary, including allocating
+ the first one on demand. */
+ if (tempbufindex + 1 >= tempbufsize)
+ {
+ tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
+ }
+ switch (*tokptr)
+ {
+ case '\0':
+ case '"':
+ /* Do nothing, loop will terminate. */
+ break;
+ case '\\':
+ tokptr++;
+ c = parse_escape (&tokptr);
+ if (c == -1)
+ {
+ continue;
+ }
+ tempbuf[tempbufindex++] = c;
+ break;
+ default:
+ tempbuf[tempbufindex++] = *tokptr++;
+ break;
+ }
+ } while ((*tokptr != '"') && (*tokptr != '\0'));
+ if (*tokptr++ != '"')
+ {
+ error ("Unterminated string in expression.");
+ }
+ tempbuf[tempbufindex] = '\0'; /* See note above */
+ yylval.sval.ptr = tempbuf;
+ yylval.sval.length = tempbufindex;
+ lexptr = tokptr;
+ return (STRING);
+ }
+
+ if (!(c == '_' || c == '$'
+ || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
+ /* We must have come across a bad character (e.g. ';'). */
+ error ("Invalid character '%c' in expression.", c);
+
+ /* It's a name. See how long it is. */
+ namelen = 0;
+ for (c = tokstart[namelen];
+ (c == '_' || c == '$' || (c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');)
+ {
+ /* Template parameter lists are part of the name.
+ FIXME: This mishandles `print $a<4&&$a>3'. */
+
+ if (c == '<')
+ {
+ /* Scan ahead to get rest of the template specification. Note
+ that we look ahead only when the '<' adjoins non-whitespace
+ characters; for comparison expressions, e.g. "a < b > c",
+ there must be spaces before the '<', etc. */
+
+ char * p = find_template_name_end (tokstart + namelen);
+ if (p)
+ namelen = p - tokstart;
+ break;
+ }
+ c = tokstart[++namelen];
+ }
+
+ /* The token "if" terminates the expression and is NOT removed from
+ the input stream. It doesn't count if it appears in the
+ expansion of a macro. */
+ if (namelen == 2
+ && tokstart[0] == 'i'
+ && tokstart[1] == 'f'
+ && ! scanning_macro_expansion ())
+ {
+ return 0;
+ }
+
+ lexptr += namelen;
+
+ tryname:
+
+ /* Catch specific keywords. Should be done with a data structure. */
+ switch (namelen)
+ {
+ case 8:
+ if (STREQN (tokstart, "unsigned", 8))
+ return UNSIGNED;
+ if (current_language->la_language == language_cplus
+ && STREQN (tokstart, "template", 8))
+ return TEMPLATE;
+ if (STREQN (tokstart, "volatile", 8))
+ return VOLATILE_KEYWORD;
+ break;
+ case 6:
+ if (STREQN (tokstart, "struct", 6))
+ return STRUCT;
+ if (STREQN (tokstart, "signed", 6))
+ return SIGNED_KEYWORD;
+ if (STREQN (tokstart, "sizeof", 6))
+ return SIZEOF;
+ if (STREQN (tokstart, "double", 6))
+ return DOUBLE_KEYWORD;
+ break;
+ case 5:
+ if (current_language->la_language == language_cplus)
+ {
+ if (STREQN (tokstart, "false", 5))
+ return FALSEKEYWORD;
+ if (STREQN (tokstart, "class", 5))
+ return CLASS;
+ }
+ if (STREQN (tokstart, "union", 5))
+ return UNION;
+ if (STREQN (tokstart, "short", 5))
+ return SHORT;
+ if (STREQN (tokstart, "const", 5))
+ return CONST_KEYWORD;
+ break;
+ case 4:
+ if (STREQN (tokstart, "enum", 4))
+ return ENUM;
+ if (STREQN (tokstart, "long", 4))
+ return LONG;
+ if (current_language->la_language == language_cplus)
+ {
+ if (STREQN (tokstart, "true", 4))
+ return TRUEKEYWORD;
+
+ if (STREQN (tokstart, "this", 4))
+ {
+ static const char this_name[] =
+ { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
+
+ if (lookup_symbol (this_name, expression_context_block,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL))
+ return THIS;
+ }
+ }
+ break;
+ case 3:
+ if (STREQN (tokstart, "int", 3))
+ return INT_KEYWORD;
+ break;
+ default:
+ break;
+ }
+
+ yylval.sval.ptr = tokstart;
+ yylval.sval.length = namelen;
+
+ if (*tokstart == '$')
+ {
+ write_dollar_variable (yylval.sval);
+ return VARIABLE;
+ }
+
+ /* Look ahead and see if we can consume more of the input
+ string to get a reasonable class/namespace spec or a
+ fully-qualified name. This is a kludge to get around the
+ HP aCC compiler's generation of symbol names with embedded
+ colons for namespace and nested classes. */
+ if (unquoted_expr)
+ {
+ /* Only do it if not inside single quotes */
+ sym_class = parse_nested_classes_for_hpacc (yylval.sval.ptr, yylval.sval.length,
+ &token_string, &class_prefix, &lexptr);
+ if (sym_class)
+ {
+ /* Replace the current token with the bigger one we found */
+ yylval.sval.ptr = token_string;
+ yylval.sval.length = strlen (token_string);
+ }
+ }
+
+ /* Use token-type BLOCKNAME for symbols that happen to be defined as
+ functions or symtabs. If this is not so, then ...
+ Use token-type TYPENAME for symbols that happen to be defined
+ currently as names of types; NAME for other symbols.
+ The caller is not constrained to care about the distinction. */
+ {
+ char *tmp = copy_name (yylval.sval);
+ struct symbol *sym;
+ int is_a_field_of_this = 0;
+ int hextype;
+
+ sym = lookup_symbol (tmp, expression_context_block,
+ VAR_NAMESPACE,
+ current_language->la_language == language_cplus
+ ? &is_a_field_of_this : (int *) NULL,
+ (struct symtab **) NULL);
+ /* Call lookup_symtab, not lookup_partial_symtab, in case there are
+ no psymtabs (coff, xcoff, or some future change to blow away the
+ psymtabs once once symbols are read). */
+ if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
+ {
+ yylval.ssym.sym = sym;
+ yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+ return BLOCKNAME;
+ }
+ else if (!sym)
+ { /* See if it's a file name. */
+ struct symtab *symtab;
+
+ symtab = lookup_symtab (tmp);
+
+ if (symtab)
+ {
+ yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
+ return FILENAME;
+ }
+ }
+
+ if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+ {
+#if 1
+ /* Despite the following flaw, we need to keep this code enabled.
+ Because we can get called from check_stub_method, if we don't
+ handle nested types then it screws many operations in any
+ program which uses nested types. */
+ /* In "A::x", if x is a member function of A and there happens
+ to be a type (nested or not, since the stabs don't make that
+ distinction) named x, then this code incorrectly thinks we
+ are dealing with nested types rather than a member function. */
+
+ char *p;
+ char *namestart;
+ struct symbol *best_sym;
+
+ /* Look ahead to detect nested types. This probably should be
+ done in the grammar, but trying seemed to introduce a lot
+ of shift/reduce and reduce/reduce conflicts. It's possible
+ that it could be done, though. Or perhaps a non-grammar, but
+ less ad hoc, approach would work well. */
+
+ /* Since we do not currently have any way of distinguishing
+ a nested type from a non-nested one (the stabs don't tell
+ us whether a type is nested), we just ignore the
+ containing type. */
+
+ p = lexptr;
+ best_sym = sym;
+ while (1)
+ {
+ /* Skip whitespace. */
+ while (*p == ' ' || *p == '\t' || *p == '\n')
+ ++p;
+ if (*p == ':' && p[1] == ':')
+ {
+ /* Skip the `::'. */
+ p += 2;
+ /* Skip whitespace. */
+ while (*p == ' ' || *p == '\t' || *p == '\n')
+ ++p;
+ namestart = p;
+ while (*p == '_' || *p == '$' || (*p >= '0' && *p <= '9')
+ || (*p >= 'a' && *p <= 'z')
+ || (*p >= 'A' && *p <= 'Z'))
+ ++p;
+ if (p != namestart)
+ {
+ struct symbol *cur_sym;
+ /* As big as the whole rest of the expression, which is
+ at least big enough. */
+ char *ncopy = alloca (strlen (tmp)+strlen (namestart)+3);
+ char *tmp1;
+
+ tmp1 = ncopy;
+ memcpy (tmp1, tmp, strlen (tmp));
+ tmp1 += strlen (tmp);
+ memcpy (tmp1, "::", 2);
+ tmp1 += 2;
+ memcpy (tmp1, namestart, p - namestart);
+ tmp1[p - namestart] = '\0';
+ cur_sym = lookup_symbol (ncopy, expression_context_block,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ if (cur_sym)
+ {
+ if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF)
+ {
+ best_sym = cur_sym;
+ lexptr = p;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+
+ yylval.tsym.type = SYMBOL_TYPE (best_sym);
+#else /* not 0 */
+ yylval.tsym.type = SYMBOL_TYPE (sym);
+#endif /* not 0 */
+ return TYPENAME;
+ }
+ if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
+ return TYPENAME;
+
+ /* Input names that aren't symbols but ARE valid hex numbers,
+ when the input radix permits them, can be names or numbers
+ depending on the parse. Note we support radixes > 16 here. */
+ if (!sym &&
+ ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
+ (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
+ {
+ YYSTYPE newlval; /* Its value is ignored. */
+ hextype = parse_number (tokstart, namelen, 0, &newlval);
+ if (hextype == INT)
+ {
+ yylval.ssym.sym = sym;
+ yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+ return NAME_OR_INT;
+ }
+ }
+
+ /* Any other kind of symbol */
+ yylval.ssym.sym = sym;
+ yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+ return NAME;
+ }
+}
+
+void
+yyerror (msg)
+ char *msg;
+{
+ if (prev_lexptr)
+ lexptr = prev_lexptr;
+
+ error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
+}
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
new file mode 100644
index 00000000000..09a2e6a968a
--- /dev/null
+++ b/gdb/c-lang.c
@@ -0,0 +1,673 @@
+/* C language support routines for GDB, the GNU debugger.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002
+ 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "c-lang.h"
+#include "valprint.h"
+#include "macroscope.h"
+#include "gdb_assert.h"
+
+extern void _initialize_c_language (void);
+static void c_emit_char (int c, struct ui_file * stream, int quoter);
+
+/* Print the character C on STREAM as part of the contents of a literal
+ string whose delimiter is QUOTER. Note that that format for printing
+ characters and strings is language specific. */
+
+static void
+c_emit_char (register int c, struct ui_file *stream, int quoter)
+{
+ c &= 0xFF; /* Avoid sign bit follies */
+
+ if (PRINT_LITERAL_FORM (c))
+ {
+ if (c == '\\' || c == quoter)
+ {
+ fputs_filtered ("\\", stream);
+ }
+ fprintf_filtered (stream, "%c", c);
+ }
+ else
+ {
+ switch (c)
+ {
+ case '\n':
+ fputs_filtered ("\\n", stream);
+ break;
+ case '\b':
+ fputs_filtered ("\\b", stream);
+ break;
+ case '\t':
+ fputs_filtered ("\\t", stream);
+ break;
+ case '\f':
+ fputs_filtered ("\\f", stream);
+ break;
+ case '\r':
+ fputs_filtered ("\\r", stream);
+ break;
+ case '\013':
+ fputs_filtered ("\\v", stream);
+ break;
+ case '\033':
+ fputs_filtered ("\\e", stream);
+ break;
+ case '\007':
+ fputs_filtered ("\\a", stream);
+ break;
+ case '\0':
+ fputs_filtered ("\\0", stream);
+ break;
+ default:
+ fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
+ break;
+ }
+ }
+}
+
+void
+c_printchar (int c, struct ui_file *stream)
+{
+ fputc_filtered ('\'', stream);
+ LA_EMIT_CHAR (c, stream, '\'');
+ fputc_filtered ('\'', stream);
+}
+
+/* Print the character string STRING, printing at most LENGTH characters.
+ LENGTH is -1 if the string is nul terminated. Each character is WIDTH bytes
+ long. Printing stops early if the number hits print_max; repeat counts are
+ printed as appropriate. Print ellipses at the end if we had to stop before
+ printing LENGTH characters, or if FORCE_ELLIPSES. */
+
+void
+c_printstr (struct ui_file *stream, char *string, unsigned int length,
+ int width, int force_ellipses)
+{
+ register unsigned int i;
+ unsigned int things_printed = 0;
+ int in_quotes = 0;
+ int need_comma = 0;
+ extern int inspect_it;
+
+ /* If the string was not truncated due to `set print elements', and
+ the last byte of it is a null, we don't print that, in traditional C
+ style. */
+ if (!force_ellipses
+ && length > 0
+ && (extract_unsigned_integer (string + (length - 1) * width, width)
+ == '\0'))
+ length--;
+
+ if (length == 0)
+ {
+ fputs_filtered ("\"\"", stream);
+ return;
+ }
+
+ for (i = 0; i < length && things_printed < print_max; ++i)
+ {
+ /* Position of the character we are examining
+ to see whether it is repeated. */
+ unsigned int rep1;
+ /* Number of repetitions we have detected so far. */
+ unsigned int reps;
+ unsigned long current_char;
+
+ QUIT;
+
+ if (need_comma)
+ {
+ fputs_filtered (", ", stream);
+ need_comma = 0;
+ }
+
+ current_char = extract_unsigned_integer (string + i * width, width);
+
+ rep1 = i + 1;
+ reps = 1;
+ while (rep1 < length
+ && extract_unsigned_integer (string + rep1 * width, width)
+ == current_char)
+ {
+ ++rep1;
+ ++reps;
+ }
+
+ if (reps > repeat_count_threshold)
+ {
+ if (in_quotes)
+ {
+ if (inspect_it)
+ fputs_filtered ("\\\", ", stream);
+ else
+ fputs_filtered ("\", ", stream);
+ in_quotes = 0;
+ }
+ LA_PRINT_CHAR (current_char, stream);
+ fprintf_filtered (stream, " <repeats %u times>", reps);
+ i = rep1 - 1;
+ things_printed += repeat_count_threshold;
+ need_comma = 1;
+ }
+ else
+ {
+ if (!in_quotes)
+ {
+ if (inspect_it)
+ fputs_filtered ("\\\"", stream);
+ else
+ fputs_filtered ("\"", stream);
+ in_quotes = 1;
+ }
+ LA_EMIT_CHAR (current_char, stream, '"');
+ ++things_printed;
+ }
+ }
+
+ /* Terminate the quotes if necessary. */
+ if (in_quotes)
+ {
+ if (inspect_it)
+ fputs_filtered ("\\\"", stream);
+ else
+ fputs_filtered ("\"", stream);
+ }
+
+ if (force_ellipses || i < length)
+ fputs_filtered ("...", stream);
+}
+
+/* Create a fundamental C type using default reasonable for the current
+ target machine.
+
+ Some object/debugging file formats (DWARF version 1, COFF, etc) do not
+ define fundamental types such as "int" or "double". Others (stabs or
+ DWARF version 2, etc) do define fundamental types. For the formats which
+ don't provide fundamental types, gdb can create such types using this
+ function.
+
+ FIXME: Some compilers distinguish explicitly signed integral types
+ (signed short, signed int, signed long) from "regular" integral types
+ (short, int, long) in the debugging information. There is some dis-
+ agreement as to how useful this feature is. In particular, gcc does
+ not support this. Also, only some debugging formats allow the
+ distinction to be passed on to a debugger. For now, we always just
+ use "short", "int", or "long" as the type name, for both the implicit
+ and explicitly signed types. This also makes life easier for the
+ gdb test suite since we don't have to account for the differences
+ in output depending upon what the compiler and debugging format
+ support. We will probably have to re-examine the issue when gdb
+ starts taking it's fundamental type information directly from the
+ debugging information supplied by the compiler. fnf@cygnus.com */
+
+struct type *
+c_create_fundamental_type (struct objfile *objfile, int typeid)
+{
+ register struct type *type = NULL;
+
+ switch (typeid)
+ {
+ default:
+ /* FIXME: For now, if we are asked to produce a type not in this
+ language, create the equivalent of a C integer type with the
+ name "<?type?>". When all the dust settles from the type
+ reconstruction work, this should probably become an error. */
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "<?type?>", objfile);
+ warning ("internal error: no C/C++ fundamental type %d", typeid);
+ break;
+ case FT_VOID:
+ type = init_type (TYPE_CODE_VOID,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "void", objfile);
+ break;
+ case FT_BOOLEAN:
+ type = init_type (TYPE_CODE_BOOL,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "bool", objfile);
+ break;
+ case FT_CHAR:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_NOSIGN, "char", objfile);
+ break;
+ case FT_SIGNED_CHAR:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "signed char", objfile);
+ break;
+ case FT_UNSIGNED_CHAR:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned char", objfile);
+ break;
+ case FT_SHORT:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ 0, "short", objfile);
+ break;
+ case FT_SIGNED_SHORT:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ 0, "short", objfile); /* FIXME-fnf */
+ break;
+ case FT_UNSIGNED_SHORT:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned short", objfile);
+ break;
+ case FT_INTEGER:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "int", objfile);
+ break;
+ case FT_SIGNED_INTEGER:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "int", objfile); /* FIXME -fnf */
+ break;
+ case FT_UNSIGNED_INTEGER:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned int", objfile);
+ break;
+ case FT_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "long", objfile);
+ break;
+ case FT_SIGNED_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "long", objfile); /* FIXME -fnf */
+ break;
+ case FT_UNSIGNED_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned long", objfile);
+ break;
+ case FT_LONG_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "long long", objfile);
+ break;
+ case FT_SIGNED_LONG_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "signed long long", objfile);
+ break;
+ case FT_UNSIGNED_LONG_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned long long", objfile);
+ break;
+ case FT_FLOAT:
+ type = init_type (TYPE_CODE_FLT,
+ TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0, "float", objfile);
+ break;
+ case FT_DBL_PREC_FLOAT:
+ type = init_type (TYPE_CODE_FLT,
+ TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "double", objfile);
+ break;
+ case FT_EXT_PREC_FLOAT:
+ type = init_type (TYPE_CODE_FLT,
+ TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "long double", objfile);
+ break;
+ case FT_COMPLEX:
+ type = init_type (TYPE_CODE_FLT,
+ 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0, "complex float", objfile);
+ TYPE_TARGET_TYPE (type)
+ = init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0, "float", objfile);
+ break;
+ case FT_DBL_PREC_COMPLEX:
+ type = init_type (TYPE_CODE_FLT,
+ 2 * TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "complex double", objfile);
+ TYPE_TARGET_TYPE (type)
+ = init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "double", objfile);
+ break;
+ case FT_EXT_PREC_COMPLEX:
+ type = init_type (TYPE_CODE_FLT,
+ 2 * TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "complex long double", objfile);
+ TYPE_TARGET_TYPE (type)
+ = init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "long double", objfile);
+ break;
+ case FT_TEMPLATE_ARG:
+ type = init_type (TYPE_CODE_TEMPLATE_ARG,
+ 0,
+ 0, "<template arg>", objfile);
+ break;
+ }
+ return (type);
+}
+
+/* Preprocessing and parsing C and C++ expressions. */
+
+
+/* When we find that lexptr (the global var defined in parse.c) is
+ pointing at a macro invocation, we expand the invocation, and call
+ scan_macro_expansion to save the old lexptr here and point lexptr
+ into the expanded text. When we reach the end of that, we call
+ end_macro_expansion to pop back to the value we saved here. The
+ macro expansion code promises to return only fully-expanded text,
+ so we don't need to "push" more than one level.
+
+ This is disgusting, of course. It would be cleaner to do all macro
+ expansion beforehand, and then hand that to lexptr. But we don't
+ really know where the expression ends. Remember, in a command like
+
+ (gdb) break *ADDRESS if CONDITION
+
+ we evaluate ADDRESS in the scope of the current frame, but we
+ evaluate CONDITION in the scope of the breakpoint's location. So
+ it's simply wrong to try to macro-expand the whole thing at once. */
+static char *macro_original_text;
+static char *macro_expanded_text;
+
+
+void
+scan_macro_expansion (char *expansion)
+{
+ /* We'd better not be trying to push the stack twice. */
+ gdb_assert (! macro_original_text);
+ gdb_assert (! macro_expanded_text);
+
+ /* Save the old lexptr value, so we can return to it when we're done
+ parsing the expanded text. */
+ macro_original_text = lexptr;
+ lexptr = expansion;
+
+ /* Save the expanded text, so we can free it when we're finished. */
+ macro_expanded_text = expansion;
+}
+
+
+int
+scanning_macro_expansion ()
+{
+ return macro_original_text != 0;
+}
+
+
+void
+finished_macro_expansion ()
+{
+ /* There'd better be something to pop back to, and we better have
+ saved a pointer to the start of the expanded text. */
+ gdb_assert (macro_original_text);
+ gdb_assert (macro_expanded_text);
+
+ /* Pop back to the original text. */
+ lexptr = macro_original_text;
+ macro_original_text = 0;
+
+ /* Free the expanded text. */
+ xfree (macro_expanded_text);
+ macro_expanded_text = 0;
+}
+
+
+static void
+scan_macro_cleanup (void *dummy)
+{
+ if (macro_original_text)
+ finished_macro_expansion ();
+}
+
+
+/* We set these global variables before calling c_parse, to tell it
+ how it to find macro definitions for the expression at hand. */
+macro_lookup_ftype *expression_macro_lookup_func;
+void *expression_macro_lookup_baton;
+
+
+static struct macro_definition *
+null_macro_lookup (const char *name, void *baton)
+{
+ return 0;
+}
+
+
+static int
+c_preprocess_and_parse ()
+{
+ /* Set up a lookup function for the macro expander. */
+ struct macro_scope *scope = 0;
+ struct cleanup *back_to = make_cleanup (free_current_contents, &scope);
+
+ if (expression_context_block)
+ scope = sal_macro_scope (find_pc_line (expression_context_pc, 0));
+ else
+ scope = default_macro_scope ();
+
+ if (scope)
+ {
+ expression_macro_lookup_func = standard_macro_lookup;
+ expression_macro_lookup_baton = (void *) scope;
+ }
+ else
+ {
+ expression_macro_lookup_func = null_macro_lookup;
+ expression_macro_lookup_baton = 0;
+ }
+
+ gdb_assert (! macro_original_text);
+ make_cleanup (scan_macro_cleanup, 0);
+
+ {
+ int result = c_parse ();
+ do_cleanups (back_to);
+ return result;
+ }
+}
+
+
+
+/* Table mapping opcodes into strings for printing operators
+ and precedences of the operators. */
+
+const struct op_print c_op_print_tab[] =
+{
+ {",", BINOP_COMMA, PREC_COMMA, 0},
+ {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
+ {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
+ {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
+ {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
+ {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
+ {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
+ {"==", BINOP_EQUAL, PREC_EQUAL, 0},
+ {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
+ {"<=", BINOP_LEQ, PREC_ORDER, 0},
+ {">=", BINOP_GEQ, PREC_ORDER, 0},
+ {">", BINOP_GTR, PREC_ORDER, 0},
+ {"<", BINOP_LESS, PREC_ORDER, 0},
+ {">>", BINOP_RSH, PREC_SHIFT, 0},
+ {"<<", BINOP_LSH, PREC_SHIFT, 0},
+ {"+", BINOP_ADD, PREC_ADD, 0},
+ {"-", BINOP_SUB, PREC_ADD, 0},
+ {"*", BINOP_MUL, PREC_MUL, 0},
+ {"/", BINOP_DIV, PREC_MUL, 0},
+ {"%", BINOP_REM, PREC_MUL, 0},
+ {"@", BINOP_REPEAT, PREC_REPEAT, 0},
+ {"-", UNOP_NEG, PREC_PREFIX, 0},
+ {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
+ {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
+ {"*", UNOP_IND, PREC_PREFIX, 0},
+ {"&", UNOP_ADDR, PREC_PREFIX, 0},
+ {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
+ {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
+ {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
+ {NULL, 0, 0, 0}
+};
+
+struct type **const (c_builtin_types[]) =
+{
+ &builtin_type_int,
+ &builtin_type_long,
+ &builtin_type_short,
+ &builtin_type_char,
+ &builtin_type_float,
+ &builtin_type_double,
+ &builtin_type_void,
+ &builtin_type_long_long,
+ &builtin_type_signed_char,
+ &builtin_type_unsigned_char,
+ &builtin_type_unsigned_short,
+ &builtin_type_unsigned_int,
+ &builtin_type_unsigned_long,
+ &builtin_type_unsigned_long_long,
+ &builtin_type_long_double,
+ &builtin_type_complex,
+ &builtin_type_double_complex,
+ 0
+};
+
+const struct language_defn c_language_defn =
+{
+ "c", /* Language name */
+ language_c,
+ c_builtin_types,
+ range_check_off,
+ type_check_off,
+ case_sensitive_on,
+ c_preprocess_and_parse,
+ c_error,
+ evaluate_subexp_standard,
+ c_printchar, /* Print a character constant */
+ c_printstr, /* Function to print string constant */
+ c_emit_char, /* Print a single char */
+ c_create_fundamental_type, /* Create fundamental type in this language */
+ c_print_type, /* Print a type using appropriate syntax */
+ c_val_print, /* Print a value using appropriate syntax */
+ c_value_print, /* Print a top-level value */
+ {"", "", "", ""}, /* Binary format info */
+ {"0%lo", "0", "o", ""}, /* Octal format info */
+ {"%ld", "", "d", ""}, /* Decimal format info */
+ {"0x%lx", "0x", "x", ""}, /* Hex format info */
+ c_op_print_tab, /* expression operators for printing */
+ 1, /* c-style arrays */
+ 0, /* String lower bound */
+ &builtin_type_char, /* Type of string elements */
+ LANG_MAGIC
+};
+
+struct type **const (cplus_builtin_types[]) =
+{
+ &builtin_type_int,
+ &builtin_type_long,
+ &builtin_type_short,
+ &builtin_type_char,
+ &builtin_type_float,
+ &builtin_type_double,
+ &builtin_type_void,
+ &builtin_type_long_long,
+ &builtin_type_signed_char,
+ &builtin_type_unsigned_char,
+ &builtin_type_unsigned_short,
+ &builtin_type_unsigned_int,
+ &builtin_type_unsigned_long,
+ &builtin_type_unsigned_long_long,
+ &builtin_type_long_double,
+ &builtin_type_complex,
+ &builtin_type_double_complex,
+ &builtin_type_bool,
+ 0
+};
+
+const struct language_defn cplus_language_defn =
+{
+ "c++", /* Language name */
+ language_cplus,
+ cplus_builtin_types,
+ range_check_off,
+ type_check_off,
+ case_sensitive_on,
+ c_preprocess_and_parse,
+ c_error,
+ evaluate_subexp_standard,
+ c_printchar, /* Print a character constant */
+ c_printstr, /* Function to print string constant */
+ c_emit_char, /* Print a single char */
+ c_create_fundamental_type, /* Create fundamental type in this language */
+ c_print_type, /* Print a type using appropriate syntax */
+ c_val_print, /* Print a value using appropriate syntax */
+ c_value_print, /* Print a top-level value */
+ {"", "", "", ""}, /* Binary format info */
+ {"0%lo", "0", "o", ""}, /* Octal format info */
+ {"%ld", "", "d", ""}, /* Decimal format info */
+ {"0x%lx", "0x", "x", ""}, /* Hex format info */
+ c_op_print_tab, /* expression operators for printing */
+ 1, /* c-style arrays */
+ 0, /* String lower bound */
+ &builtin_type_char, /* Type of string elements */
+ LANG_MAGIC
+};
+
+const struct language_defn asm_language_defn =
+{
+ "asm", /* Language name */
+ language_asm,
+ c_builtin_types,
+ range_check_off,
+ type_check_off,
+ case_sensitive_on,
+ c_preprocess_and_parse,
+ c_error,
+ evaluate_subexp_standard,
+ c_printchar, /* Print a character constant */
+ c_printstr, /* Function to print string constant */
+ c_emit_char, /* Print a single char */
+ c_create_fundamental_type, /* Create fundamental type in this language */
+ c_print_type, /* Print a type using appropriate syntax */
+ c_val_print, /* Print a value using appropriate syntax */
+ c_value_print, /* Print a top-level value */
+ {"", "", "", ""}, /* Binary format info */
+ {"0%lo", "0", "o", ""}, /* Octal format info */
+ {"%ld", "", "d", ""}, /* Decimal format info */
+ {"0x%lx", "0x", "x", ""}, /* Hex format info */
+ c_op_print_tab, /* expression operators for printing */
+ 1, /* c-style arrays */
+ 0, /* String lower bound */
+ &builtin_type_char, /* Type of string elements */
+ LANG_MAGIC
+};
+
+void
+_initialize_c_language (void)
+{
+ add_language (&c_language_defn);
+ add_language (&cplus_language_defn);
+ add_language (&asm_language_defn);
+}
diff --git a/gdb/c-lang.h b/gdb/c-lang.h
new file mode 100644
index 00000000000..e64d4c69e90
--- /dev/null
+++ b/gdb/c-lang.h
@@ -0,0 +1,92 @@
+/* C language support definitions for GDB, the GNU debugger.
+ Copyright 1992, 1994, 1995, 1996, 1997, 1998, 2000, 2002
+ 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. */
+
+
+#if !defined (C_LANG_H)
+#define C_LANG_H 1
+
+#include "value.h"
+#include "macroexp.h"
+
+
+extern int c_parse (void); /* Defined in c-exp.y */
+
+extern void c_error (char *); /* Defined in c-exp.y */
+
+/* Defined in c-typeprint.c */
+extern void c_print_type (struct type *, char *, struct ui_file *, int,
+ int);
+
+extern int c_val_print (struct type *, char *, int, CORE_ADDR,
+ struct ui_file *, int, int, int,
+ enum val_prettyprint);
+
+extern int c_value_print (struct value *, struct ui_file *, int,
+ enum val_prettyprint);
+
+/* These are in c-lang.c: */
+
+extern void c_printchar (int, struct ui_file *);
+
+extern void c_printstr (struct ui_file * stream, char *string,
+ unsigned int length, int width,
+ int force_ellipses);
+
+extern void scan_macro_expansion (char *expansion);
+extern int scanning_macro_expansion (void);
+extern void finished_macro_expansion (void);
+
+extern macro_lookup_ftype *expression_macro_lookup_func;
+extern void *expression_macro_lookup_baton;
+
+extern struct type *c_create_fundamental_type (struct objfile *, int);
+
+extern struct type **const (c_builtin_types[]);
+
+/* These are in c-typeprint.c: */
+
+extern void c_type_print_base (struct type *, struct ui_file *, int, int);
+
+extern void c_type_print_varspec_prefix (struct type *, struct ui_file *,
+ int, int);
+
+/* These are in cp-valprint.c */
+
+extern int vtblprint; /* Controls printing of vtbl's */
+
+extern int static_field_print;
+
+extern void cp_print_class_member (char *, struct type *, struct ui_file *,
+ char *);
+
+extern void cp_print_class_method (char *, struct type *, struct ui_file *);
+
+extern void cp_print_value_fields (struct type *, struct type *, char *,
+ int, CORE_ADDR, struct ui_file *, int,
+ int, enum val_prettyprint,
+ struct type **, int);
+
+extern int cp_is_vtbl_ptr_type (struct type *);
+
+extern int cp_is_vtbl_member (struct type *);
+
+
+#endif /* !defined (C_LANG_H) */
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
new file mode 100644
index 00000000000..430d5674f24
--- /dev/null
+++ b/gdb/c-typeprint.c
@@ -0,0 +1,1190 @@
+/* Support for printing C and C++ types for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
+ 1999, 2000, 2001, 2002
+ 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 "defs.h"
+#include "obstack.h"
+#include "bfd.h" /* Binary File Description */
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "language.h"
+#include "demangle.h"
+#include "c-lang.h"
+#include "typeprint.h"
+#include "cp-abi.h"
+
+#include "gdb_string.h"
+#include <errno.h>
+
+/* Flag indicating target was compiled by HP compiler */
+extern int hp_som_som_object_present;
+
+static void cp_type_print_method_args (struct type ** args, char *prefix,
+ char *varstring, int staticp,
+ struct ui_file *stream);
+
+static void c_type_print_args (struct type *, struct ui_file *);
+
+static void cp_type_print_derivation_info (struct ui_file *, struct type *);
+
+void c_type_print_varspec_prefix (struct type *, struct ui_file *, int,
+ int);
+
+/* Print "const", "volatile", or address space modifiers. */
+static void c_type_print_modifier (struct type *, struct ui_file *,
+ int, int);
+
+
+
+
+/* LEVEL is the depth to indent lines by. */
+
+void
+c_print_type (struct type *type, char *varstring, struct ui_file *stream,
+ int show, int level)
+{
+ register enum type_code code;
+ int demangled_args;
+
+ if (show > 0)
+ CHECK_TYPEDEF (type);
+
+ c_type_print_base (type, stream, show, level);
+ code = TYPE_CODE (type);
+ if ((varstring != NULL && *varstring != '\0')
+ ||
+ /* Need a space if going to print stars or brackets;
+ but not if we will print just a type name. */
+ ((show > 0 || TYPE_NAME (type) == 0)
+ &&
+ (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC
+ || code == TYPE_CODE_METHOD
+ || code == TYPE_CODE_ARRAY
+ || code == TYPE_CODE_MEMBER
+ || code == TYPE_CODE_REF)))
+ fputs_filtered (" ", stream);
+ c_type_print_varspec_prefix (type, stream, show, 0);
+
+ if (varstring != NULL)
+ {
+ fputs_filtered (varstring, stream);
+
+ /* For demangled function names, we have the arglist as part of the name,
+ so don't print an additional pair of ()'s */
+
+ demangled_args = strchr (varstring, '(') != NULL;
+ c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
+ }
+}
+
+/* If TYPE is a derived type, then print out derivation information.
+ Print only the actual base classes of this type, not the base classes
+ of the base classes. I.E. for the derivation hierarchy:
+
+ class A { int a; };
+ class B : public A {int b; };
+ class C : public B {int c; };
+
+ Print the type of class C as:
+
+ class C : public B {
+ int c;
+ }
+
+ Not as the following (like gdb used to), which is not legal C++ syntax for
+ derived types and may be confused with the multiple inheritance form:
+
+ class C : public B : public A {
+ int c;
+ }
+
+ In general, gdb should try to print the types as closely as possible to
+ the form that they appear in the source code.
+ Note that in case of protected derivation gcc will not say 'protected'
+ but 'private'. The HP's aCC compiler emits specific information for
+ derivation via protected inheritance, so gdb can print it out */
+
+static void
+cp_type_print_derivation_info (struct ui_file *stream, struct type *type)
+{
+ char *name;
+ int i;
+
+ for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
+ {
+ fputs_filtered (i == 0 ? ": " : ", ", stream);
+ fprintf_filtered (stream, "%s%s ",
+ BASETYPE_VIA_PUBLIC (type, i) ? "public"
+ : (TYPE_FIELD_PROTECTED (type, i) ? "protected" : "private"),
+ BASETYPE_VIA_VIRTUAL (type, i) ? " virtual" : "");
+ name = type_name_no_tag (TYPE_BASECLASS (type, i));
+ fprintf_filtered (stream, "%s", name ? name : "(null)");
+ }
+ if (i > 0)
+ {
+ fputs_filtered (" ", stream);
+ }
+}
+/* Print the C++ method arguments ARGS to the file STREAM. */
+
+static void
+cp_type_print_method_args (struct type **args, char *prefix, char *varstring,
+ int staticp, struct ui_file *stream)
+{
+ int i;
+
+ fprintf_symbol_filtered (stream, prefix, language_cplus, DMGL_ANSI);
+ fprintf_symbol_filtered (stream, varstring, language_cplus, DMGL_ANSI);
+ fputs_filtered ("(", stream);
+ if (args && args[!staticp] && TYPE_CODE (args[!staticp]) != TYPE_CODE_VOID)
+ {
+ i = !staticp; /* skip the class variable */
+ while (1)
+ {
+ type_print (args[i++], "", stream, 0);
+ if (!args[i])
+ {
+ fprintf_filtered (stream, " ...");
+ break;
+ }
+ else if (TYPE_CODE (args[i]) != TYPE_CODE_VOID)
+ {
+ fprintf_filtered (stream, ", ");
+ }
+ else
+ break;
+ }
+ }
+ else if (current_language->la_language == language_cplus)
+ {
+ fprintf_filtered (stream, "void");
+ }
+
+ fprintf_filtered (stream, ")");
+}
+
+
+/* Print any asterisks or open-parentheses needed before the
+ variable name (to describe its type).
+
+ On outermost call, pass 0 for PASSED_A_PTR.
+ On outermost call, SHOW > 0 means should ignore
+ any typename for TYPE and show its details.
+ SHOW is always zero on recursive calls. */
+
+void
+c_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
+ int show, int passed_a_ptr)
+{
+ char *name;
+ if (type == 0)
+ return;
+
+ if (TYPE_NAME (type) && show <= 0)
+ return;
+
+ QUIT;
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_PTR:
+ c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
+ fprintf_filtered (stream, "*");
+ c_type_print_modifier (type, stream, 1, 0);
+ break;
+
+ case TYPE_CODE_MEMBER:
+ if (passed_a_ptr)
+ fprintf_filtered (stream, "(");
+ c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+ fprintf_filtered (stream, " ");
+ name = type_name_no_tag (TYPE_DOMAIN_TYPE (type));
+ if (name)
+ fputs_filtered (name, stream);
+ else
+ c_type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, passed_a_ptr);
+ fprintf_filtered (stream, "::");
+ break;
+
+ case TYPE_CODE_METHOD:
+ if (passed_a_ptr)
+ fprintf_filtered (stream, "(");
+ c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+ if (passed_a_ptr)
+ {
+ fprintf_filtered (stream, " ");
+ c_type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, passed_a_ptr);
+ fprintf_filtered (stream, "::");
+ }
+ break;
+
+ case TYPE_CODE_REF:
+ c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
+ fprintf_filtered (stream, "&");
+ c_type_print_modifier (type, stream, 1, 0);
+ break;
+
+ case TYPE_CODE_FUNC:
+ c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+ if (passed_a_ptr)
+ fprintf_filtered (stream, "(");
+ break;
+
+ case TYPE_CODE_ARRAY:
+ c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+ if (passed_a_ptr)
+ fprintf_filtered (stream, "(");
+ break;
+
+ case TYPE_CODE_UNDEF:
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_ERROR:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_SET:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_STRING:
+ case TYPE_CODE_BITSTRING:
+ case TYPE_CODE_COMPLEX:
+ case TYPE_CODE_TYPEDEF:
+ case TYPE_CODE_TEMPLATE:
+ /* These types need no prefix. They are listed here so that
+ gcc -Wall will reveal any types that haven't been handled. */
+ break;
+ default:
+ error ("type not handled in c_type_print_varspec_prefix()");
+ break;
+ }
+}
+
+/* Print out "const" and "volatile" attributes.
+ TYPE is a pointer to the type being printed out.
+ STREAM is the output destination.
+ NEED_SPACE = 1 indicates an initial white space is needed */
+
+static void
+c_type_print_modifier (struct type *type, struct ui_file *stream,
+ int need_pre_space, int need_post_space)
+{
+ int did_print_modifier = 0;
+ char *address_space_id;
+
+ /* We don't print `const' qualifiers for references --- since all
+ operators affect the thing referenced, not the reference itself,
+ every reference is `const'. */
+ if (TYPE_CONST (type)
+ && TYPE_CODE (type) != TYPE_CODE_REF)
+ {
+ if (need_pre_space)
+ fprintf_filtered (stream, " ");
+ fprintf_filtered (stream, "const");
+ did_print_modifier = 1;
+ }
+
+ if (TYPE_VOLATILE (type))
+ {
+ if (did_print_modifier || need_pre_space)
+ fprintf_filtered (stream, " ");
+ fprintf_filtered (stream, "volatile");
+ did_print_modifier = 1;
+ }
+
+ address_space_id = address_space_int_to_name (TYPE_INSTANCE_FLAGS (type));
+ if (address_space_id)
+ {
+ if (did_print_modifier || need_pre_space)
+ fprintf_filtered (stream, " ");
+ fprintf_filtered (stream, "@%s", address_space_id);
+ did_print_modifier = 1;
+ }
+
+ if (did_print_modifier && need_post_space)
+ fprintf_filtered (stream, " ");
+}
+
+
+
+
+static void
+c_type_print_args (struct type *type, struct ui_file *stream)
+{
+ int i;
+ struct type **args;
+
+ fprintf_filtered (stream, "(");
+ args = TYPE_ARG_TYPES (type);
+ if (args != NULL)
+ {
+ if (args[1] == NULL)
+ {
+ fprintf_filtered (stream, "...");
+ }
+ else if ((TYPE_CODE (args[1]) == TYPE_CODE_VOID) &&
+ (current_language->la_language == language_cplus))
+ {
+ fprintf_filtered (stream, "void");
+ }
+ else
+ {
+ for (i = 1;
+ args[i] != NULL && TYPE_CODE (args[i]) != TYPE_CODE_VOID;
+ i++)
+ {
+ c_print_type (args[i], "", stream, -1, 0);
+ if (args[i + 1] == NULL)
+ {
+ fprintf_filtered (stream, "...");
+ }
+ else if (TYPE_CODE (args[i + 1]) != TYPE_CODE_VOID)
+ {
+ fprintf_filtered (stream, ",");
+ wrap_here (" ");
+ }
+ }
+ }
+ }
+ else if (current_language->la_language == language_cplus)
+ {
+ fprintf_filtered (stream, "void");
+ }
+
+ fprintf_filtered (stream, ")");
+}
+
+
+/* Return true iff the j'th overloading of the i'th method of TYPE
+ is a type conversion operator, like `operator int () { ... }'.
+ When listing a class's methods, we don't print the return type of
+ such operators. */
+static int
+is_type_conversion_operator (struct type *type, int i, int j)
+{
+ /* I think the whole idea of recognizing type conversion operators
+ by their name is pretty terrible. But I don't think our present
+ data structure gives us any other way to tell. If you know of
+ some other way, feel free to rewrite this function. */
+ char *name = TYPE_FN_FIELDLIST_NAME (type, i);
+
+ if (strncmp (name, "operator", 8) != 0)
+ return 0;
+
+ name += 8;
+ if (! strchr (" \t\f\n\r", *name))
+ return 0;
+
+ while (strchr (" \t\f\n\r", *name))
+ name++;
+
+ if (!('a' <= *name && *name <= 'z')
+ && !('A' <= *name && *name <= 'Z')
+ && *name != '_')
+ /* If this doesn't look like the start of an identifier, then it
+ isn't a type conversion operator. */
+ return 0;
+ else if (strncmp (name, "new", 3) == 0)
+ name += 3;
+ else if (strncmp (name, "delete", 6) == 0)
+ name += 6;
+ else
+ /* If it doesn't look like new or delete, it's a type conversion
+ operator. */
+ return 1;
+
+ /* Is that really the end of the name? */
+ if (('a' <= *name && *name <= 'z')
+ || ('A' <= *name && *name <= 'Z')
+ || ('0' <= *name && *name <= '9')
+ || *name == '_')
+ /* No, so the identifier following "operator" must be a type name,
+ and this is a type conversion operator. */
+ return 1;
+
+ /* That was indeed the end of the name, so it was `operator new' or
+ `operator delete', neither of which are type conversion operators. */
+ return 0;
+}
+
+
+/* Given a C++ qualified identifier QID, strip off the qualifiers,
+ yielding the unqualified name. The return value is a pointer into
+ the original string.
+
+ It's a pity we don't have this information in some more structured
+ form. Even the author of this function feels that writing little
+ parsers like this everywhere is stupid. */
+static char *
+remove_qualifiers (char *qid)
+{
+ int quoted = 0; /* zero if we're not in quotes;
+ '"' if we're in a double-quoted string;
+ '\'' if we're in a single-quoted string. */
+ int depth = 0; /* number of unclosed parens we've seen */
+ char *parenstack = (char *) alloca (strlen (qid));
+ char *scan;
+ char *last = 0; /* The character after the rightmost
+ `::' token we've seen so far. */
+
+ for (scan = qid; *scan; scan++)
+ {
+ if (quoted)
+ {
+ if (*scan == quoted)
+ quoted = 0;
+ else if (*scan == '\\' && *(scan + 1))
+ scan++;
+ }
+ else if (scan[0] == ':' && scan[1] == ':')
+ {
+ /* If we're inside parenthesis (i.e., an argument list) or
+ angle brackets (i.e., a list of template arguments), then
+ we don't record the position of this :: token, since it's
+ not relevant to the top-level structure we're trying
+ to operate on. */
+ if (depth == 0)
+ {
+ last = scan + 2;
+ scan++;
+ }
+ }
+ else if (*scan == '"' || *scan == '\'')
+ quoted = *scan;
+ else if (*scan == '(')
+ parenstack[depth++] = ')';
+ else if (*scan == '[')
+ parenstack[depth++] = ']';
+ /* We're going to treat <> as a pair of matching characters,
+ since we're more likely to see those in template id's than
+ real less-than characters. What a crock. */
+ else if (*scan == '<')
+ parenstack[depth++] = '>';
+ else if (*scan == ')' || *scan == ']' || *scan == '>')
+ {
+ if (depth > 0 && parenstack[depth - 1] == *scan)
+ depth--;
+ else
+ {
+ /* We're going to do a little error recovery here. If we
+ don't find a match for *scan on the paren stack, but
+ there is something lower on the stack that does match, we
+ pop the stack to that point. */
+ int i;
+
+ for (i = depth - 1; i >= 0; i--)
+ if (parenstack[i] == *scan)
+ {
+ depth = i;
+ break;
+ }
+ }
+ }
+ }
+
+ if (last)
+ return last;
+ else
+ /* We didn't find any :: tokens at the top level, so declare the
+ whole thing an unqualified identifier. */
+ return qid;
+}
+
+
+/* Print any array sizes, function arguments or close parentheses
+ needed after the variable name (to describe its type).
+ Args work like c_type_print_varspec_prefix. */
+
+void
+c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
+ int show, int passed_a_ptr, int demangled_args)
+{
+ if (type == 0)
+ return;
+
+ if (TYPE_NAME (type) && show <= 0)
+ return;
+
+ QUIT;
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ if (passed_a_ptr)
+ fprintf_filtered (stream, ")");
+
+ fprintf_filtered (stream, "[");
+ if (TYPE_LENGTH (type) >= 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
+ && TYPE_ARRAY_UPPER_BOUND_TYPE (type) != BOUND_CANNOT_BE_DETERMINED)
+ fprintf_filtered (stream, "%d",
+ (TYPE_LENGTH (type)
+ / TYPE_LENGTH (TYPE_TARGET_TYPE (type))));
+ fprintf_filtered (stream, "]");
+
+ c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0);
+ break;
+
+ case TYPE_CODE_MEMBER:
+ if (passed_a_ptr)
+ fprintf_filtered (stream, ")");
+ c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0);
+ break;
+
+ case TYPE_CODE_METHOD:
+ if (passed_a_ptr)
+ fprintf_filtered (stream, ")");
+ c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0);
+ if (passed_a_ptr)
+ {
+ c_type_print_args (type, stream);
+ }
+ break;
+
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_REF:
+ c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1, 0);
+ break;
+
+ case TYPE_CODE_FUNC:
+ if (passed_a_ptr)
+ fprintf_filtered (stream, ")");
+ if (!demangled_args)
+ {
+ int i, len = TYPE_NFIELDS (type);
+ fprintf_filtered (stream, "(");
+ if (len == 0
+ && (TYPE_PROTOTYPED (type)
+ || current_language->la_language == language_cplus))
+ {
+ fprintf_filtered (stream, "void");
+ }
+ else
+ for (i = 0; i < len; i++)
+ {
+ if (i > 0)
+ {
+ fputs_filtered (", ", stream);
+ wrap_here (" ");
+ }
+ c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
+ }
+ fprintf_filtered (stream, ")");
+ }
+ c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
+ passed_a_ptr, 0);
+ break;
+
+ case TYPE_CODE_UNDEF:
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_ERROR:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_SET:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_STRING:
+ case TYPE_CODE_BITSTRING:
+ case TYPE_CODE_COMPLEX:
+ case TYPE_CODE_TYPEDEF:
+ case TYPE_CODE_TEMPLATE:
+ /* These types do not need a suffix. They are listed so that
+ gcc -Wall will report types that may not have been considered. */
+ break;
+ default:
+ error ("type not handled in c_type_print_varspec_suffix()");
+ break;
+ }
+}
+
+/* Print the name of the type (or the ultimate pointer target,
+ function value or array element), or the description of a
+ structure or union.
+
+ SHOW positive means print details about the type (e.g. enum values),
+ and print structure elements passing SHOW - 1 for show.
+ SHOW negative means just print the type name or struct tag if there is one.
+ If there is no name, print something sensible but concise like
+ "struct {...}".
+ SHOW zero means just print the type name or struct tag if there is one.
+ If there is no name, print something sensible but not as concise like
+ "struct {int x; int y;}".
+
+ LEVEL is the number of spaces to indent by.
+ We increase it for some recursive calls. */
+
+void
+c_type_print_base (struct type *type, struct ui_file *stream, int show,
+ int level)
+{
+ int i;
+ int len, real_len;
+ int lastval;
+ char *mangled_name;
+ char *demangled_name;
+ char *demangled_no_static;
+ enum
+ {
+ s_none, s_public, s_private, s_protected
+ }
+ section_type;
+ int need_access_label = 0;
+ int j, len2;
+
+ QUIT;
+
+ wrap_here (" ");
+ if (type == NULL)
+ {
+ fputs_filtered ("<type unknown>", stream);
+ return;
+ }
+
+ /* When SHOW is zero or less, and there is a valid type name, then always
+ just print the type name directly from the type. */
+ /* If we have "typedef struct foo {. . .} bar;" do we want to print it
+ as "struct foo" or as "bar"? Pick the latter, because C++ folk tend
+ to expect things like "class5 *foo" rather than "struct class5 *foo". */
+
+ if (show <= 0
+ && TYPE_NAME (type) != NULL)
+ {
+ c_type_print_modifier (type, stream, 0, 1);
+ fputs_filtered (TYPE_NAME (type), stream);
+ return;
+ }
+
+ CHECK_TYPEDEF (type);
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_TYPEDEF:
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_MEMBER:
+ case TYPE_CODE_REF:
+ case TYPE_CODE_FUNC:
+ case TYPE_CODE_METHOD:
+ c_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
+ break;
+
+ case TYPE_CODE_STRUCT:
+ c_type_print_modifier (type, stream, 0, 1);
+ /* Note TYPE_CODE_STRUCT and TYPE_CODE_CLASS have the same value,
+ * so we use another means for distinguishing them.
+ */
+ if (HAVE_CPLUS_STRUCT (type))
+ {
+ switch (TYPE_DECLARED_TYPE (type))
+ {
+ case DECLARED_TYPE_CLASS:
+ fprintf_filtered (stream, "class ");
+ break;
+ case DECLARED_TYPE_UNION:
+ fprintf_filtered (stream, "union ");
+ break;
+ case DECLARED_TYPE_STRUCT:
+ fprintf_filtered (stream, "struct ");
+ break;
+ default:
+ /* If there is a CPLUS_STRUCT, assume class if not
+ * otherwise specified in the declared_type field.
+ */
+ fprintf_filtered (stream, "class ");
+ break;
+ } /* switch */
+ }
+ else
+ {
+ /* If not CPLUS_STRUCT, then assume it's a C struct */
+ fprintf_filtered (stream, "struct ");
+ }
+ goto struct_union;
+
+ case TYPE_CODE_UNION:
+ c_type_print_modifier (type, stream, 0, 1);
+ fprintf_filtered (stream, "union ");
+
+ struct_union:
+
+ /* Print the tag if it exists.
+ * The HP aCC compiler emits
+ * a spurious "{unnamed struct}"/"{unnamed union}"/"{unnamed enum}"
+ * tag for unnamed struct/union/enum's, which we don't
+ * want to print.
+ */
+ if (TYPE_TAG_NAME (type) != NULL &&
+ strncmp (TYPE_TAG_NAME (type), "{unnamed", 8))
+ {
+ fputs_filtered (TYPE_TAG_NAME (type), stream);
+ if (show > 0)
+ fputs_filtered (" ", stream);
+ }
+ wrap_here (" ");
+ if (show < 0)
+ {
+ /* If we just printed a tag name, no need to print anything else. */
+ if (TYPE_TAG_NAME (type) == NULL)
+ fprintf_filtered (stream, "{...}");
+ }
+ else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
+ {
+ cp_type_print_derivation_info (stream, type);
+
+ fprintf_filtered (stream, "{\n");
+ if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
+ {
+ if (TYPE_STUB (type))
+ fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
+ else
+ fprintfi_filtered (level + 4, stream, "<no data fields>\n");
+ }
+
+ /* Start off with no specific section type, so we can print
+ one for the first field we find, and use that section type
+ thereafter until we find another type. */
+
+ section_type = s_none;
+
+ /* For a class, if all members are private, there's no need
+ for a "private:" label; similarly, for a struct or union
+ masquerading as a class, if all members are public, there's
+ no need for a "public:" label. */
+
+ if ((TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_CLASS) ||
+ (TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_TEMPLATE))
+ {
+ QUIT;
+ len = TYPE_NFIELDS (type);
+ for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+ if (!TYPE_FIELD_PRIVATE (type, i))
+ {
+ need_access_label = 1;
+ break;
+ }
+ QUIT;
+ if (!need_access_label)
+ {
+ len2 = TYPE_NFN_FIELDS (type);
+ for (j = 0; j < len2; j++)
+ {
+ len = TYPE_FN_FIELDLIST_LENGTH (type, j);
+ for (i = 0; i < len; i++)
+ if (!TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type, j), i))
+ {
+ need_access_label = 1;
+ break;
+ }
+ if (need_access_label)
+ break;
+ }
+ }
+ }
+ else if ((TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_STRUCT) ||
+ (TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_UNION))
+ {
+ QUIT;
+ len = TYPE_NFIELDS (type);
+ for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+ if (TYPE_FIELD_PRIVATE (type, i) || TYPE_FIELD_PROTECTED (type, i))
+ {
+ need_access_label = 1;
+ break;
+ }
+ QUIT;
+ if (!need_access_label)
+ {
+ len2 = TYPE_NFN_FIELDS (type);
+ for (j = 0; j < len2; j++)
+ {
+ QUIT;
+ len = TYPE_FN_FIELDLIST_LENGTH (type, j);
+ for (i = 0; i < len; i++)
+ if (TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type, j), i) ||
+ TYPE_FN_FIELD_PROTECTED (TYPE_FN_FIELDLIST1 (type, j), i))
+ {
+ need_access_label = 1;
+ break;
+ }
+ if (need_access_label)
+ break;
+ }
+ }
+ }
+
+ /* If there is a base class for this type,
+ do not print the field that it occupies. */
+
+ len = TYPE_NFIELDS (type);
+ for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+ {
+ QUIT;
+ /* Don't print out virtual function table. */
+ /* HP ANSI C++ case */
+ if (TYPE_HAS_VTABLE (type) && (STREQN (TYPE_FIELD_NAME (type, i), "__vfp", 5)))
+ continue;
+ /* Other compilers */
+ if (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5)
+ && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
+ continue;
+
+ /* If this is a C++ class we can print the various C++ section
+ labels. */
+
+ if (HAVE_CPLUS_STRUCT (type) && need_access_label)
+ {
+ if (TYPE_FIELD_PROTECTED (type, i))
+ {
+ if (section_type != s_protected)
+ {
+ section_type = s_protected;
+ fprintfi_filtered (level + 2, stream,
+ "protected:\n");
+ }
+ }
+ else if (TYPE_FIELD_PRIVATE (type, i))
+ {
+ if (section_type != s_private)
+ {
+ section_type = s_private;
+ fprintfi_filtered (level + 2, stream, "private:\n");
+ }
+ }
+ else
+ {
+ if (section_type != s_public)
+ {
+ section_type = s_public;
+ fprintfi_filtered (level + 2, stream, "public:\n");
+ }
+ }
+ }
+
+ print_spaces_filtered (level + 4, stream);
+ if (TYPE_FIELD_STATIC (type, i))
+ {
+ fprintf_filtered (stream, "static ");
+ }
+ c_print_type (TYPE_FIELD_TYPE (type, i),
+ TYPE_FIELD_NAME (type, i),
+ stream, show - 1, level + 4);
+ if (!TYPE_FIELD_STATIC (type, i)
+ && TYPE_FIELD_PACKED (type, i))
+ {
+ /* It is a bitfield. This code does not attempt
+ to look at the bitpos and reconstruct filler,
+ unnamed fields. This would lead to misleading
+ results if the compiler does not put out fields
+ for such things (I don't know what it does). */
+ fprintf_filtered (stream, " : %d",
+ TYPE_FIELD_BITSIZE (type, i));
+ }
+ fprintf_filtered (stream, ";\n");
+ }
+
+ /* If there are both fields and methods, put a blank line
+ between them. Make sure to count only method that we will
+ display; artificial methods will be hidden. */
+ len = TYPE_NFN_FIELDS (type);
+ real_len = 0;
+ for (i = 0; i < len; i++)
+ {
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
+ int len2 = TYPE_FN_FIELDLIST_LENGTH (type, i);
+ int j;
+ for (j = 0; j < len2; j++)
+ if (!TYPE_FN_FIELD_ARTIFICIAL (f, j))
+ real_len++;
+ }
+ if (real_len > 0 && section_type != s_none)
+ fprintf_filtered (stream, "\n");
+
+ /* C++: print out the methods */
+ for (i = 0; i < len; i++)
+ {
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
+ int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i);
+ char *method_name = TYPE_FN_FIELDLIST_NAME (type, i);
+ char *name = type_name_no_tag (type);
+ int is_constructor = name && STREQ (method_name, name);
+ for (j = 0; j < len2; j++)
+ {
+ char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
+ int is_full_physname_constructor =
+ is_constructor_name (physname)
+ || is_destructor_name (physname)
+ || method_name[0] == '~';
+
+ /* Do not print out artificial methods. */
+ if (TYPE_FN_FIELD_ARTIFICIAL (f, j))
+ continue;
+
+ QUIT;
+ if (TYPE_FN_FIELD_PROTECTED (f, j))
+ {
+ if (section_type != s_protected)
+ {
+ section_type = s_protected;
+ fprintfi_filtered (level + 2, stream,
+ "protected:\n");
+ }
+ }
+ else if (TYPE_FN_FIELD_PRIVATE (f, j))
+ {
+ if (section_type != s_private)
+ {
+ section_type = s_private;
+ fprintfi_filtered (level + 2, stream, "private:\n");
+ }
+ }
+ else
+ {
+ if (section_type != s_public)
+ {
+ section_type = s_public;
+ fprintfi_filtered (level + 2, stream, "public:\n");
+ }
+ }
+
+ print_spaces_filtered (level + 4, stream);
+ if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
+ fprintf_filtered (stream, "virtual ");
+ else if (TYPE_FN_FIELD_STATIC_P (f, j))
+ fprintf_filtered (stream, "static ");
+ if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
+ {
+ /* Keep GDB from crashing here. */
+ fprintf_filtered (stream, "<undefined type> %s;\n",
+ TYPE_FN_FIELD_PHYSNAME (f, j));
+ break;
+ }
+ else if (!is_constructor && /* constructors don't have declared types */
+ !is_full_physname_constructor && /* " " */
+ !is_type_conversion_operator (type, i, j))
+ {
+ type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
+ "", stream, -1);
+ fputs_filtered (" ", stream);
+ }
+ if (TYPE_FN_FIELD_STUB (f, j))
+ /* Build something we can demangle. */
+ mangled_name = gdb_mangle_name (type, i, j);
+ else
+ mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j);
+
+ demangled_name =
+ cplus_demangle (mangled_name,
+ DMGL_ANSI | DMGL_PARAMS);
+ if (demangled_name == NULL)
+ {
+ /* in some cases (for instance with the HP demangling),
+ if a function has more than 10 arguments,
+ the demangling will fail.
+ Let's try to reconstruct the function signature from
+ the symbol information */
+ if (!TYPE_FN_FIELD_STUB (f, j))
+ cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "",
+ method_name,
+ TYPE_FN_FIELD_STATIC_P (f, j),
+ stream);
+ else
+ fprintf_filtered (stream, "<badly mangled name '%s'>",
+ mangled_name);
+ }
+ else
+ {
+ char *p;
+ char *demangled_no_class
+ = remove_qualifiers (demangled_name);
+
+ /* get rid of the `static' appended by the demangler */
+ p = strstr (demangled_no_class, " static");
+ if (p != NULL)
+ {
+ int length = p - demangled_no_class;
+ demangled_no_static = (char *) xmalloc (length + 1);
+ strncpy (demangled_no_static, demangled_no_class, length);
+ *(demangled_no_static + length) = '\0';
+ fputs_filtered (demangled_no_static, stream);
+ xfree (demangled_no_static);
+ }
+ else
+ fputs_filtered (demangled_no_class, stream);
+ xfree (demangled_name);
+ }
+
+ if (TYPE_FN_FIELD_STUB (f, j))
+ xfree (mangled_name);
+
+ fprintf_filtered (stream, ";\n");
+ }
+ }
+
+ fprintfi_filtered (level, stream, "}");
+
+ if (TYPE_LOCALTYPE_PTR (type) && show >= 0)
+ fprintfi_filtered (level, stream, " (Local at %s:%d)\n",
+ TYPE_LOCALTYPE_FILE (type),
+ TYPE_LOCALTYPE_LINE (type));
+ }
+ if (TYPE_CODE (type) == TYPE_CODE_TEMPLATE)
+ goto go_back;
+ break;
+
+ case TYPE_CODE_ENUM:
+ c_type_print_modifier (type, stream, 0, 1);
+ /* HP C supports sized enums */
+ if (hp_som_som_object_present)
+ switch (TYPE_LENGTH (type))
+ {
+ case 1:
+ fputs_filtered ("char ", stream);
+ break;
+ case 2:
+ fputs_filtered ("short ", stream);
+ break;
+ default:
+ break;
+ }
+ fprintf_filtered (stream, "enum ");
+ /* Print the tag name if it exists.
+ The aCC compiler emits a spurious
+ "{unnamed struct}"/"{unnamed union}"/"{unnamed enum}"
+ tag for unnamed struct/union/enum's, which we don't
+ want to print. */
+ if (TYPE_TAG_NAME (type) != NULL &&
+ strncmp (TYPE_TAG_NAME (type), "{unnamed", 8))
+ {
+ fputs_filtered (TYPE_TAG_NAME (type), stream);
+ if (show > 0)
+ fputs_filtered (" ", stream);
+ }
+
+ wrap_here (" ");
+ if (show < 0)
+ {
+ /* If we just printed a tag name, no need to print anything else. */
+ if (TYPE_TAG_NAME (type) == NULL)
+ fprintf_filtered (stream, "{...}");
+ }
+ else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
+ {
+ fprintf_filtered (stream, "{");
+ len = TYPE_NFIELDS (type);
+ lastval = 0;
+ for (i = 0; i < len; i++)
+ {
+ QUIT;
+ if (i)
+ fprintf_filtered (stream, ", ");
+ wrap_here (" ");
+ fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+ if (lastval != TYPE_FIELD_BITPOS (type, i))
+ {
+ fprintf_filtered (stream, " = %d", TYPE_FIELD_BITPOS (type, i));
+ lastval = TYPE_FIELD_BITPOS (type, i);
+ }
+ lastval++;
+ }
+ fprintf_filtered (stream, "}");
+ }
+ break;
+
+ case TYPE_CODE_VOID:
+ fprintf_filtered (stream, "void");
+ break;
+
+ case TYPE_CODE_UNDEF:
+ fprintf_filtered (stream, "struct <unknown>");
+ break;
+
+ case TYPE_CODE_ERROR:
+ fprintf_filtered (stream, "<unknown type>");
+ break;
+
+ case TYPE_CODE_RANGE:
+ /* This should not occur */
+ fprintf_filtered (stream, "<range type>");
+ break;
+
+ case TYPE_CODE_TEMPLATE:
+ /* Called on "ptype t" where "t" is a template.
+ Prints the template header (with args), e.g.:
+ template <class T1, class T2> class "
+ and then merges with the struct/union/class code to
+ print the rest of the definition. */
+ c_type_print_modifier (type, stream, 0, 1);
+ fprintf_filtered (stream, "template <");
+ for (i = 0; i < TYPE_NTEMPLATE_ARGS (type); i++)
+ {
+ struct template_arg templ_arg;
+ templ_arg = TYPE_TEMPLATE_ARG (type, i);
+ fprintf_filtered (stream, "class %s", templ_arg.name);
+ if (i < TYPE_NTEMPLATE_ARGS (type) - 1)
+ fprintf_filtered (stream, ", ");
+ }
+ fprintf_filtered (stream, "> class ");
+ /* Yuck, factor this out to a subroutine so we can call
+ it and return to the point marked with the "goback:" label... - RT */
+ goto struct_union;
+ go_back:
+ if (TYPE_NINSTANTIATIONS (type) > 0)
+ {
+ fprintf_filtered (stream, "\ntemplate instantiations:\n");
+ for (i = 0; i < TYPE_NINSTANTIATIONS (type); i++)
+ {
+ fprintf_filtered (stream, " ");
+ c_type_print_base (TYPE_INSTANTIATION (type, i), stream, 0, level);
+ if (i < TYPE_NINSTANTIATIONS (type) - 1)
+ fprintf_filtered (stream, "\n");
+ }
+ }
+ break;
+
+ default:
+ /* Handle types not explicitly handled by the other cases,
+ such as fundamental types. For these, just print whatever
+ the type name is, as recorded in the type itself. If there
+ is no type name, then complain. */
+ if (TYPE_NAME (type) != NULL)
+ {
+ c_type_print_modifier (type, stream, 0, 1);
+ fputs_filtered (TYPE_NAME (type), stream);
+ }
+ else
+ {
+ /* At least for dump_symtab, it is important that this not be
+ an error (). */
+ fprintf_filtered (stream, "<invalid type code %d>",
+ TYPE_CODE (type));
+ }
+ break;
+ }
+}
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
new file mode 100644
index 00000000000..9361067ceaa
--- /dev/null
+++ b/gdb/c-valprint.c
@@ -0,0 +1,598 @@
+/* Support for printing C values for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "valprint.h"
+#include "language.h"
+#include "c-lang.h"
+#include "cp-abi.h"
+
+
+/* Print function pointer with inferior address ADDRESS onto stdio
+ stream STREAM. */
+
+static void
+print_function_pointer_address (CORE_ADDR address, struct ui_file *stream)
+{
+ CORE_ADDR func_addr = CONVERT_FROM_FUNC_PTR_ADDR (address);
+
+ /* If the function pointer is represented by a description, print the
+ address of the description. */
+ if (addressprint && func_addr != address)
+ {
+ fputs_filtered ("@", stream);
+ print_address_numeric (address, 1, stream);
+ fputs_filtered (": ", stream);
+ }
+ print_address_demangle (func_addr, stream, demangle);
+}
+
+
+/* Print data of type TYPE located at VALADDR (within GDB), which came from
+ the inferior at address ADDRESS, onto stdio stream STREAM according to
+ FORMAT (a letter or 0 for natural format). The data at VALADDR is in
+ target byte order.
+
+ If the data are a string pointer, returns the number of string characters
+ printed.
+
+ If DEREF_REF is nonzero, then dereference references, otherwise just print
+ them like pointers.
+
+ The PRETTY parameter controls prettyprinting. */
+
+int
+c_val_print (struct type *type, char *valaddr, int embedded_offset,
+ CORE_ADDR address, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
+{
+ register unsigned int i = 0; /* Number of characters printed */
+ unsigned len;
+ struct type *elttype;
+ unsigned eltlen;
+ LONGEST val;
+ CORE_ADDR addr;
+
+ CHECK_TYPEDEF (type);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ elttype = check_typedef (TYPE_TARGET_TYPE (type));
+ if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
+ {
+ eltlen = TYPE_LENGTH (elttype);
+ len = TYPE_LENGTH (type) / eltlen;
+ if (prettyprint_arrays)
+ {
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ /* For an array of chars, print with string syntax. */
+ if (eltlen == 1 &&
+ ((TYPE_CODE (elttype) == TYPE_CODE_INT)
+ || ((current_language->la_language == language_m2)
+ && (TYPE_CODE (elttype) == TYPE_CODE_CHAR)))
+ && (format == 0 || format == 's'))
+ {
+ /* If requested, look for the first null char and only print
+ elements up to it. */
+ if (stop_print_at_null)
+ {
+ unsigned int temp_len;
+
+ /* Look for a NULL char. */
+ for (temp_len = 0;
+ (valaddr + embedded_offset)[temp_len]
+ && temp_len < len && temp_len < print_max;
+ temp_len++);
+ len = temp_len;
+ }
+
+ LA_PRINT_STRING (stream, valaddr + embedded_offset, len, eltlen, 0);
+ i = len;
+ }
+ else
+ {
+ fprintf_filtered (stream, "{");
+ /* If this is a virtual function table, print the 0th
+ entry specially, and the rest of the members normally. */
+ if (cp_is_vtbl_ptr_type (elttype))
+ {
+ i = 1;
+ fprintf_filtered (stream, "%d vtable entries", len - 1);
+ }
+ else
+ {
+ i = 0;
+ }
+ val_print_array_elements (type, valaddr + embedded_offset, address, stream,
+ format, deref_ref, recurse, pretty, i);
+ fprintf_filtered (stream, "}");
+ }
+ break;
+ }
+ /* Array of unspecified length: treat like pointer to first elt. */
+ addr = address;
+ goto print_unpacked_pointer;
+
+ case TYPE_CODE_PTR:
+ if (format && format != 's')
+ {
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+ break;
+ }
+ if (vtblprint && cp_is_vtbl_ptr_type (type))
+ {
+ /* Print the unmangled name if desired. */
+ /* Print vtable entry - we only get here if we ARE using
+ -fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */
+ CORE_ADDR addr
+ = extract_typed_address (valaddr + embedded_offset, type);
+ print_function_pointer_address (addr, stream);
+ break;
+ }
+ elttype = check_typedef (TYPE_TARGET_TYPE (type));
+ if (TYPE_CODE (elttype) == TYPE_CODE_METHOD)
+ {
+ cp_print_class_method (valaddr + embedded_offset, type, stream);
+ }
+ else if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
+ {
+ cp_print_class_member (valaddr + embedded_offset,
+ TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),
+ stream, "&");
+ }
+ else
+ {
+ addr = unpack_pointer (type, valaddr + embedded_offset);
+ print_unpacked_pointer:
+
+ if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
+ {
+ /* Try to print what function it points to. */
+ print_function_pointer_address (addr, stream);
+ /* Return value is irrelevant except for string pointers. */
+ return (0);
+ }
+
+ if (addressprint && format != 's')
+ {
+ print_address_numeric (addr, 1, stream);
+ }
+
+ /* For a pointer to char or unsigned char, also print the string
+ pointed to, unless pointer is null. */
+ /* FIXME: need to handle wchar_t here... */
+
+ if (TYPE_LENGTH (elttype) == 1
+ && TYPE_CODE (elttype) == TYPE_CODE_INT
+ && (format == 0 || format == 's')
+ && addr != 0)
+ {
+ i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream);
+ }
+ else if (cp_is_vtbl_member (type))
+ {
+ /* print vtbl's nicely */
+ CORE_ADDR vt_address = unpack_pointer (type, valaddr + embedded_offset);
+
+ struct minimal_symbol *msymbol =
+ lookup_minimal_symbol_by_pc (vt_address);
+ if ((msymbol != NULL) &&
+ (vt_address == SYMBOL_VALUE_ADDRESS (msymbol)))
+ {
+ fputs_filtered (" <", stream);
+ fputs_filtered (SYMBOL_SOURCE_NAME (msymbol), stream);
+ fputs_filtered (">", stream);
+ }
+ if (vt_address && vtblprint)
+ {
+ struct value *vt_val;
+ struct symbol *wsym = (struct symbol *) NULL;
+ struct type *wtype;
+ struct symtab *s;
+ struct block *block = (struct block *) NULL;
+ int is_this_fld;
+
+ if (msymbol != NULL)
+ wsym = lookup_symbol (SYMBOL_NAME (msymbol), block,
+ VAR_NAMESPACE, &is_this_fld, &s);
+
+ if (wsym)
+ {
+ wtype = SYMBOL_TYPE (wsym);
+ }
+ else
+ {
+ wtype = TYPE_TARGET_TYPE (type);
+ }
+ vt_val = value_at (wtype, vt_address, NULL);
+ val_print (VALUE_TYPE (vt_val), VALUE_CONTENTS (vt_val), 0,
+ VALUE_ADDRESS (vt_val), stream, format,
+ deref_ref, recurse + 1, pretty);
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ }
+ }
+
+ /* Return number of characters printed, including the terminating
+ '\0' if we reached the end. val_print_string takes care including
+ the terminating '\0' if necessary. */
+ return i;
+ }
+ break;
+
+ case TYPE_CODE_MEMBER:
+ error ("not implemented: member type in c_val_print");
+ break;
+
+ case TYPE_CODE_REF:
+ elttype = check_typedef (TYPE_TARGET_TYPE (type));
+ if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
+ {
+ cp_print_class_member (valaddr + embedded_offset,
+ TYPE_DOMAIN_TYPE (elttype),
+ stream, "");
+ break;
+ }
+ if (addressprint)
+ {
+ CORE_ADDR addr
+ = extract_typed_address (valaddr + embedded_offset, type);
+ fprintf_filtered (stream, "@");
+ print_address_numeric (addr, 1, stream);
+ if (deref_ref)
+ fputs_filtered (": ", stream);
+ }
+ /* De-reference the reference. */
+ if (deref_ref)
+ {
+ if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
+ {
+ struct value *deref_val =
+ value_at
+ (TYPE_TARGET_TYPE (type),
+ unpack_pointer (lookup_pointer_type (builtin_type_void),
+ valaddr + embedded_offset),
+ NULL);
+ val_print (VALUE_TYPE (deref_val),
+ VALUE_CONTENTS (deref_val),
+ 0,
+ VALUE_ADDRESS (deref_val),
+ stream,
+ format,
+ deref_ref,
+ recurse,
+ pretty);
+ }
+ else
+ fputs_filtered ("???", stream);
+ }
+ break;
+
+ case TYPE_CODE_UNION:
+ if (recurse && !unionprint)
+ {
+ fprintf_filtered (stream, "{...}");
+ break;
+ }
+ /* Fall through. */
+ case TYPE_CODE_STRUCT:
+ /*FIXME: Abstract this away */
+ if (vtblprint && cp_is_vtbl_ptr_type (type))
+ {
+ /* Print the unmangled name if desired. */
+ /* Print vtable entry - we only get here if NOT using
+ -fvtable_thunks. (Otherwise, look under TYPE_CODE_PTR.) */
+ int offset = (embedded_offset +
+ TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8);
+ struct type *field_type = TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET);
+ CORE_ADDR addr
+ = extract_typed_address (valaddr + offset, field_type);
+
+ print_function_pointer_address (addr, stream);
+ }
+ else
+ cp_print_value_fields (type, type, valaddr, embedded_offset, address, stream, format,
+ recurse, pretty, NULL, 0);
+ break;
+
+ case TYPE_CODE_ENUM:
+ if (format)
+ {
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+ break;
+ }
+ len = TYPE_NFIELDS (type);
+ val = unpack_long (type, valaddr + embedded_offset);
+ for (i = 0; i < len; i++)
+ {
+ QUIT;
+ if (val == TYPE_FIELD_BITPOS (type, i))
+ {
+ break;
+ }
+ }
+ if (i < len)
+ {
+ fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+ }
+ else
+ {
+ print_longest (stream, 'd', 0, val);
+ }
+ break;
+
+ case TYPE_CODE_FUNC:
+ if (format)
+ {
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+ break;
+ }
+ /* FIXME, we should consider, at least for ANSI C language, eliminating
+ the distinction made between FUNCs and POINTERs to FUNCs. */
+ fprintf_filtered (stream, "{");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, "} ");
+ /* Try to print what function it points to, and its address. */
+ print_address_demangle (address, stream, demangle);
+ break;
+
+ case TYPE_CODE_BOOL:
+ format = format ? format : output_format;
+ if (format)
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+ else
+ {
+ val = unpack_long (type, valaddr + embedded_offset);
+ if (val == 0)
+ fputs_filtered ("false", stream);
+ else if (val == 1)
+ fputs_filtered ("true", stream);
+ else
+ print_longest (stream, 'd', 0, val);
+ }
+ break;
+
+ case TYPE_CODE_RANGE:
+ /* FIXME: create_range_type does not set the unsigned bit in a
+ range type (I think it probably should copy it from the target
+ type), so we won't print values which are too large to
+ fit in a signed integer correctly. */
+ /* FIXME: Doesn't handle ranges of enums correctly. (Can't just
+ print with the target type, though, because the size of our type
+ and the target type might differ). */
+ /* FALLTHROUGH */
+
+ case TYPE_CODE_INT:
+ format = format ? format : output_format;
+ if (format)
+ {
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+ }
+ else
+ {
+ val_print_type_code_int (type, valaddr + embedded_offset, stream);
+ /* C and C++ has no single byte int type, char is used instead.
+ Since we don't know whether the value is really intended to
+ be used as an integer or a character, print the character
+ equivalent as well. */
+ if (TYPE_LENGTH (type) == 1)
+ {
+ fputs_filtered (" ", stream);
+ LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr + embedded_offset),
+ stream);
+ }
+ }
+ break;
+
+ case TYPE_CODE_CHAR:
+ format = format ? format : output_format;
+ if (format)
+ {
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+ }
+ else
+ {
+ val = unpack_long (type, valaddr + embedded_offset);
+ if (TYPE_UNSIGNED (type))
+ fprintf_filtered (stream, "%u", (unsigned int) val);
+ else
+ fprintf_filtered (stream, "%d", (int) val);
+ fputs_filtered (" ", stream);
+ LA_PRINT_CHAR ((unsigned char) val, stream);
+ }
+ break;
+
+ case TYPE_CODE_FLT:
+ if (format)
+ {
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+ }
+ else
+ {
+ print_floating (valaddr + embedded_offset, type, stream);
+ }
+ break;
+
+ case TYPE_CODE_METHOD:
+ {
+ struct value *v = value_at (type, address, NULL);
+ cp_print_class_method (VALUE_CONTENTS (value_addr (v)),
+ lookup_pointer_type (type), stream);
+ break;
+ }
+
+ case TYPE_CODE_VOID:
+ fprintf_filtered (stream, "void");
+ break;
+
+ case TYPE_CODE_ERROR:
+ fprintf_filtered (stream, "<error type>");
+ break;
+
+ case TYPE_CODE_UNDEF:
+ /* This happens (without TYPE_FLAG_STUB set) on systems which don't use
+ dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
+ and no complete type for struct foo in that file. */
+ fprintf_filtered (stream, "<incomplete type>");
+ break;
+
+ case TYPE_CODE_COMPLEX:
+ if (format)
+ print_scalar_formatted (valaddr + embedded_offset,
+ TYPE_TARGET_TYPE (type),
+ format, 0, stream);
+ else
+ print_floating (valaddr + embedded_offset, TYPE_TARGET_TYPE (type),
+ stream);
+ fprintf_filtered (stream, " + ");
+ if (format)
+ print_scalar_formatted (valaddr + embedded_offset
+ + TYPE_LENGTH (TYPE_TARGET_TYPE (type)),
+ TYPE_TARGET_TYPE (type),
+ format, 0, stream);
+ else
+ print_floating (valaddr + embedded_offset
+ + TYPE_LENGTH (TYPE_TARGET_TYPE (type)),
+ TYPE_TARGET_TYPE (type),
+ stream);
+ fprintf_filtered (stream, " * I");
+ break;
+
+ default:
+ error ("Invalid C/C++ type code %d in symbol table.", TYPE_CODE (type));
+ }
+ gdb_flush (stream);
+ return (0);
+}
+
+int
+c_value_print (struct value *val, struct ui_file *stream, int format,
+ enum val_prettyprint pretty)
+{
+ struct type *type = VALUE_TYPE (val);
+ struct type *real_type;
+ int full, top, using_enc;
+
+ /* If it is a pointer, indicate what it points to.
+
+ Print type also if it is a reference.
+
+ C++: if it is a member pointer, we will take care
+ of that when we print it. */
+ if (TYPE_CODE (type) == TYPE_CODE_PTR ||
+ TYPE_CODE (type) == TYPE_CODE_REF)
+ {
+ /* Hack: remove (char *) for char strings. Their
+ type is indicated by the quoted string anyway. */
+ if (TYPE_CODE (type) == TYPE_CODE_PTR &&
+ TYPE_NAME (type) == NULL &&
+ TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL &&
+ STREQ (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char"))
+ {
+ /* Print nothing */
+ }
+ else if (objectprint && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
+ {
+
+ if (TYPE_CODE(type) == TYPE_CODE_REF)
+ {
+ /* Copy value, change to pointer, so we don't get an
+ * error about a non-pointer type in value_rtti_target_type
+ */
+ struct value *temparg;
+ temparg=value_copy(val);
+ VALUE_TYPE (temparg) = lookup_pointer_type(TYPE_TARGET_TYPE(type));
+ val=temparg;
+ }
+ /* Pointer to class, check real type of object */
+ fprintf_filtered (stream, "(");
+ real_type = value_rtti_target_type (val, &full, &top, &using_enc);
+ if (real_type)
+ {
+ /* RTTI entry found */
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ /* create a pointer type pointing to the real type */
+ type = lookup_pointer_type (real_type);
+ }
+ else
+ {
+ /* create a reference type referencing the real type */
+ type = lookup_reference_type (real_type);
+ }
+ /* JYG: Need to adjust pointer value. */
+ val->aligner.contents[0] -= top;
+
+ /* Note: When we look up RTTI entries, we don't get any
+ information on const or volatile attributes */
+ }
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, ") ");
+ }
+ else
+ {
+ /* normal case */
+ fprintf_filtered (stream, "(");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, ") ");
+ }
+ }
+ if (objectprint && (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_CLASS))
+ {
+ /* Attempt to determine real type of object */
+ real_type = value_rtti_type (val, &full, &top, &using_enc);
+ if (real_type)
+ {
+ /* We have RTTI information, so use it */
+ val = value_full_object (val, real_type, full, top, using_enc);
+ fprintf_filtered (stream, "(%s%s) ",
+ TYPE_NAME (real_type),
+ full ? "" : " [incomplete object]");
+ /* Print out object: enclosing type is same as real_type if full */
+ return val_print (VALUE_ENCLOSING_TYPE (val), VALUE_CONTENTS_ALL (val), 0,
+ VALUE_ADDRESS (val), stream, format, 1, 0, pretty);
+ /* Note: When we look up RTTI entries, we don't get any information on
+ const or volatile attributes */
+ }
+ else if (type != VALUE_ENCLOSING_TYPE (val))
+ {
+ /* No RTTI information, so let's do our best */
+ fprintf_filtered (stream, "(%s ?) ",
+ TYPE_NAME (VALUE_ENCLOSING_TYPE (val)));
+ return val_print (VALUE_ENCLOSING_TYPE (val), VALUE_CONTENTS_ALL (val), 0,
+ VALUE_ADDRESS (val), stream, format, 1, 0, pretty);
+ }
+ /* Otherwise, we end up at the return outside this "if" */
+ }
+
+ return val_print (type, VALUE_CONTENTS_ALL (val), VALUE_EMBEDDED_OFFSET (val),
+ VALUE_ADDRESS (val),
+ stream, format, 1, 0, pretty);
+}
diff --git a/gdb/call-cmds.h b/gdb/call-cmds.h
new file mode 100644
index 00000000000..3d2cda103c8
--- /dev/null
+++ b/gdb/call-cmds.h
@@ -0,0 +1,35 @@
+/* ***DEPRECATED*** The gdblib files must not be calling/using things in any
+ of the possible command languages. If necessary, a hook (that may be
+ present or not) must be used and set to the appropriate routine by any
+ command language that cares about it. If you are having to include this
+ file you are possibly doing things the old way. This file will disapear.
+ 2000-12-01 fnasser@redhat.com */
+
+/* Prototypes for GDB commands that are called internally by other functions.
+ Copyright 1992, 2000, 2001 Free Software Foundation, Inc.
+
+ 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. */
+
+#ifndef CALL_CMDS_H
+#define CALL_CMDS_H
+
+extern void initialize_all_files (void);
+
+extern void core_file_command (char *, int);
+
+extern void break_command (char *, int);
+
+#endif
diff --git a/gdb/ch-exp.c b/gdb/ch-exp.c
new file mode 100644
index 00000000000..e96a6f8e5f8
--- /dev/null
+++ b/gdb/ch-exp.c
@@ -0,0 +1,2233 @@
+/* Parser for GNU CHILL (CCITT High-Level Language) -*- C -*-
+ Copyright 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001
+ 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. */
+
+/* Parse a Chill expression from text in a string,
+ and return the result as a struct expression pointer.
+ That structure contains arithmetic operations in reverse polish,
+ with constants represented by operations that are followed by special data.
+ See expression.h for the details of the format.
+ What is important here is that it can be built up sequentially
+ during the process of parsing; the lower levels of the tree always
+ come first in the result.
+
+ Note that the language accepted by this parser is more liberal
+ than the one accepted by an actual Chill compiler. For example, the
+ language rule that a simple name string can not be one of the reserved
+ simple name strings is not enforced (e.g "case" is not treated as a
+ reserved name). Another example is that Chill is a strongly typed
+ language, and certain expressions that violate the type constraints
+ may still be evaluated if gdb can do so in a meaningful manner, while
+ such expressions would be rejected by the compiler. The reason for
+ this more liberal behavior is the philosophy that the debugger
+ is intended to be a tool that is used by the programmer when things
+ go wrong, and as such, it should provide as few artificial barriers
+ to it's use as possible. If it can do something meaningful, even
+ something that violates language contraints that are enforced by the
+ compiler, it should do so without complaint.
+
+ */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include <ctype.h>
+#include "expression.h"
+#include "language.h"
+#include "value.h"
+#include "parser-defs.h"
+#include "ch-lang.h"
+#include "bfd.h" /* Required by objfiles.h. */
+#include "symfile.h" /* Required by objfiles.h. */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+
+#ifdef __GNUC__
+#define INLINE __inline__
+#endif
+
+typedef union
+
+ {
+ LONGEST lval;
+ ULONGEST ulval;
+ struct
+ {
+ LONGEST val;
+ struct type *type;
+ }
+ typed_val;
+ double dval;
+ struct symbol *sym;
+ struct type *tval;
+ struct stoken sval;
+ struct ttype tsym;
+ struct symtoken ssym;
+ }
+YYSTYPE;
+
+enum ch_terminal
+ {
+ END_TOKEN = 0,
+ /* '\001' ... '\xff' come first. */
+ OPEN_PAREN = '(',
+ TOKEN_NOT_READ = 999,
+ INTEGER_LITERAL,
+ BOOLEAN_LITERAL,
+ CHARACTER_LITERAL,
+ FLOAT_LITERAL,
+ GENERAL_PROCEDURE_NAME,
+ LOCATION_NAME,
+ EMPTINESS_LITERAL,
+ CHARACTER_STRING_LITERAL,
+ BIT_STRING_LITERAL,
+ TYPENAME,
+ DOT_FIELD_NAME, /* '.' followed by <field name> */
+ CASE,
+ OF,
+ ESAC,
+ LOGIOR,
+ ORIF,
+ LOGXOR,
+ LOGAND,
+ ANDIF,
+ NOTEQUAL,
+ GEQ,
+ LEQ,
+ IN,
+ SLASH_SLASH,
+ MOD,
+ REM,
+ NOT,
+ POINTER,
+ RECEIVE,
+ UP,
+ IF,
+ THEN,
+ ELSE,
+ FI,
+ ELSIF,
+ ILLEGAL_TOKEN,
+ NUM,
+ PRED,
+ SUCC,
+ ABS,
+ CARD,
+ MAX_TOKEN,
+ MIN_TOKEN,
+ ADDR_TOKEN,
+ SIZE,
+ UPPER,
+ LOWER,
+ LENGTH,
+ ARRAY,
+ GDB_VARIABLE,
+ GDB_ASSIGNMENT
+ };
+
+/* Forward declarations. */
+
+static void write_lower_upper_value (enum exp_opcode, struct type *);
+static enum ch_terminal match_bitstring_literal (void);
+static enum ch_terminal match_integer_literal (void);
+static enum ch_terminal match_character_literal (void);
+static enum ch_terminal match_string_literal (void);
+static enum ch_terminal match_float_literal (void);
+static int decode_integer_literal (LONGEST *, char **);
+static int decode_integer_value (int, char **, LONGEST *);
+static char *match_simple_name_string (void);
+static void growbuf_by_size (int);
+static void parse_case_label (void);
+static void parse_untyped_expr (void);
+static void parse_if_expression (void);
+static void parse_if_expression_body (void);
+static void parse_else_alternative (void);
+static void parse_then_alternative (void);
+static void parse_expr (void);
+static void parse_operand0 (void);
+static void parse_operand1 (void);
+static void parse_operand2 (void);
+static void parse_operand3 (void);
+static void parse_operand4 (void);
+static void parse_operand5 (void);
+static void parse_operand6 (void);
+static void parse_primval (void);
+static void parse_tuple (struct type *);
+static void parse_opt_element_list (struct type *);
+static void parse_tuple_element (struct type *);
+static void parse_named_record_element (void);
+static void parse_call (void);
+static struct type *parse_mode_or_normal_call (void);
+#if 0
+static struct type *parse_mode_call (void);
+#endif
+static void parse_unary_call (void);
+static int parse_opt_untyped_expr (void);
+static int expect (enum ch_terminal, char *);
+static enum ch_terminal ch_lex (void);
+INLINE static enum ch_terminal PEEK_TOKEN (void);
+static enum ch_terminal peek_token_ (int);
+static void forward_token_ (void);
+static void require (enum ch_terminal);
+static int check_token (enum ch_terminal);
+
+#define MAX_LOOK_AHEAD 2
+static enum ch_terminal terminal_buffer[MAX_LOOK_AHEAD + 1] =
+{
+ TOKEN_NOT_READ, TOKEN_NOT_READ, TOKEN_NOT_READ};
+static YYSTYPE yylval;
+static YYSTYPE val_buffer[MAX_LOOK_AHEAD + 1];
+
+/*int current_token, lookahead_token; */
+
+INLINE static enum ch_terminal
+PEEK_TOKEN (void)
+{
+ if (terminal_buffer[0] == TOKEN_NOT_READ)
+ {
+ terminal_buffer[0] = ch_lex ();
+ val_buffer[0] = yylval;
+ }
+ return terminal_buffer[0];
+}
+#define PEEK_LVAL() val_buffer[0]
+#define PEEK_TOKEN1() peek_token_(1)
+#define PEEK_TOKEN2() peek_token_(2)
+static enum ch_terminal
+peek_token_ (int i)
+{
+ if (i > MAX_LOOK_AHEAD)
+ internal_error (__FILE__, __LINE__,
+ "too much lookahead");
+ if (terminal_buffer[i] == TOKEN_NOT_READ)
+ {
+ terminal_buffer[i] = ch_lex ();
+ val_buffer[i] = yylval;
+ }
+ return terminal_buffer[i];
+}
+
+#if 0
+
+static void
+pushback_token (enum ch_terminal code, YYSTYPE node)
+{
+ int i;
+ if (terminal_buffer[MAX_LOOK_AHEAD] != TOKEN_NOT_READ)
+ internal_error (__FILE__, __LINE__,
+ "cannot pushback token");
+ for (i = MAX_LOOK_AHEAD; i > 0; i--)
+ {
+ terminal_buffer[i] = terminal_buffer[i - 1];
+ val_buffer[i] = val_buffer[i - 1];
+ }
+ terminal_buffer[0] = code;
+ val_buffer[0] = node;
+}
+
+#endif
+
+static void
+forward_token_ (void)
+{
+ int i;
+ for (i = 0; i < MAX_LOOK_AHEAD; i++)
+ {
+ terminal_buffer[i] = terminal_buffer[i + 1];
+ val_buffer[i] = val_buffer[i + 1];
+ }
+ terminal_buffer[MAX_LOOK_AHEAD] = TOKEN_NOT_READ;
+}
+#define FORWARD_TOKEN() forward_token_()
+
+/* Skip the next token.
+ if it isn't TOKEN, the parser is broken. */
+
+static void
+require (enum ch_terminal token)
+{
+ if (PEEK_TOKEN () != token)
+ {
+ internal_error (__FILE__, __LINE__,
+ "expected token %d", (int) token);
+ }
+ FORWARD_TOKEN ();
+}
+
+static int
+check_token (enum ch_terminal token)
+{
+ if (PEEK_TOKEN () != token)
+ return 0;
+ FORWARD_TOKEN ();
+ return 1;
+}
+
+/* return 0 if expected token was not found,
+ else return 1.
+ */
+static int
+expect (enum ch_terminal token, char *message)
+{
+ if (PEEK_TOKEN () != token)
+ {
+ if (message)
+ error (message);
+ else if (token < 256)
+ error ("syntax error - expected a '%c' here \"%s\"", token, lexptr);
+ else
+ error ("syntax error");
+ return 0;
+ }
+ else
+ FORWARD_TOKEN ();
+ return 1;
+}
+
+#if 0
+/* Parse a name string. If ALLOW_ALL is 1, ALL is allowed as a postfix. */
+
+static tree
+parse_opt_name_string (int allow_all)
+{
+ int token = PEEK_TOKEN ();
+ tree name;
+ if (token != NAME)
+ {
+ if (token == ALL && allow_all)
+ {
+ FORWARD_TOKEN ();
+ return ALL_POSTFIX;
+ }
+ return NULL_TREE;
+ }
+ name = PEEK_LVAL ();
+ for (;;)
+ {
+ FORWARD_TOKEN ();
+ token = PEEK_TOKEN ();
+ if (token != '!')
+ return name;
+ FORWARD_TOKEN ();
+ token = PEEK_TOKEN ();
+ if (token == ALL && allow_all)
+ return get_identifier3 (IDENTIFIER_POINTER (name), "!", "*");
+ if (token != NAME)
+ {
+ if (pass == 1)
+ error ("'%s!' is not followed by an identifier",
+ IDENTIFIER_POINTER (name));
+ return name;
+ }
+ name = get_identifier3 (IDENTIFIER_POINTER (name),
+ "!", IDENTIFIER_POINTER (PEEK_LVAL ()));
+ }
+}
+
+static tree
+parse_simple_name_string (void)
+{
+ int token = PEEK_TOKEN ();
+ tree name;
+ if (token != NAME)
+ {
+ error ("expected a name here");
+ return error_mark_node;
+ }
+ name = PEEK_LVAL ();
+ FORWARD_TOKEN ();
+ return name;
+}
+
+static tree
+parse_name_string (void)
+{
+ tree name = parse_opt_name_string (0);
+ if (name)
+ return name;
+ if (pass == 1)
+ error ("expected a name string here");
+ return error_mark_node;
+}
+
+/* Matches: <name_string>
+ Returns if pass 1: the identifier.
+ Returns if pass 2: a decl or value for identifier. */
+
+static tree
+parse_name (void)
+{
+ tree name = parse_name_string ();
+ if (pass == 1 || ignoring)
+ return name;
+ else
+ {
+ tree decl = lookup_name (name);
+ if (decl == NULL_TREE)
+ {
+ error ("`%s' undeclared", IDENTIFIER_POINTER (name));
+ return error_mark_node;
+ }
+ else if (TREE_CODE (TREE_TYPE (decl)) == ERROR_MARK)
+ return error_mark_node;
+ else if (TREE_CODE (decl) == CONST_DECL)
+ return DECL_INITIAL (decl);
+ else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
+ return convert_from_reference (decl);
+ else
+ return decl;
+ }
+}
+#endif
+
+#if 0
+static void
+pushback_paren_expr (tree expr)
+{
+ if (pass == 1 && !ignoring)
+ expr = build1 (PAREN_EXPR, NULL_TREE, expr);
+ pushback_token (EXPR, expr);
+}
+#endif
+
+/* Matches: <case label> */
+
+static void
+parse_case_label (void)
+{
+ if (check_token (ELSE))
+ error ("ELSE in tuples labels not implemented");
+ /* Does not handle the case of a mode name. FIXME */
+ parse_expr ();
+ if (check_token (':'))
+ {
+ parse_expr ();
+ write_exp_elt_opcode (BINOP_RANGE);
+ }
+}
+
+static int
+parse_opt_untyped_expr (void)
+{
+ switch (PEEK_TOKEN ())
+ {
+ case ',':
+ case ':':
+ case ')':
+ return 0;
+ default:
+ parse_untyped_expr ();
+ return 1;
+ }
+}
+
+static void
+parse_unary_call (void)
+{
+ FORWARD_TOKEN ();
+ expect ('(', NULL);
+ parse_expr ();
+ expect (')', NULL);
+}
+
+/* Parse NAME '(' MODENAME ')'. */
+
+#if 0
+
+static struct type *
+parse_mode_call (void)
+{
+ struct type *type;
+ FORWARD_TOKEN ();
+ expect ('(', NULL);
+ if (PEEK_TOKEN () != TYPENAME)
+ error ("expect MODENAME here `%s'", lexptr);
+ type = PEEK_LVAL ().tsym.type;
+ FORWARD_TOKEN ();
+ expect (')', NULL);
+ return type;
+}
+
+#endif
+
+static struct type *
+parse_mode_or_normal_call (void)
+{
+ struct type *type;
+ FORWARD_TOKEN ();
+ expect ('(', NULL);
+ if (PEEK_TOKEN () == TYPENAME)
+ {
+ type = PEEK_LVAL ().tsym.type;
+ FORWARD_TOKEN ();
+ }
+ else
+ {
+ parse_expr ();
+ type = NULL;
+ }
+ expect (')', NULL);
+ return type;
+}
+
+/* Parse something that looks like a function call.
+ Assume we have parsed the function, and are at the '('. */
+
+static void
+parse_call (void)
+{
+ int arg_count;
+ require ('(');
+ /* This is to save the value of arglist_len
+ being accumulated for each dimension. */
+ start_arglist ();
+ if (parse_opt_untyped_expr ())
+ {
+ int tok = PEEK_TOKEN ();
+ arglist_len = 1;
+ if (tok == UP || tok == ':')
+ {
+ FORWARD_TOKEN ();
+ parse_expr ();
+ expect (')', "expected ')' to terminate slice");
+ end_arglist ();
+ write_exp_elt_opcode (tok == UP ? TERNOP_SLICE_COUNT
+ : TERNOP_SLICE);
+ return;
+ }
+ while (check_token (','))
+ {
+ parse_untyped_expr ();
+ arglist_len++;
+ }
+ }
+ else
+ arglist_len = 0;
+ expect (')', NULL);
+ arg_count = end_arglist ();
+ write_exp_elt_opcode (MULTI_SUBSCRIPT);
+ write_exp_elt_longcst (arg_count);
+ write_exp_elt_opcode (MULTI_SUBSCRIPT);
+}
+
+static void
+parse_named_record_element (void)
+{
+ struct stoken label;
+ char buf[256];
+
+ label = PEEK_LVAL ().sval;
+ sprintf (buf, "expected a field name here `%s'", lexptr);
+ expect (DOT_FIELD_NAME, buf);
+ if (check_token (','))
+ parse_named_record_element ();
+ else if (check_token (':'))
+ parse_expr ();
+ else
+ error ("syntax error near `%s' in named record tuple element", lexptr);
+ write_exp_elt_opcode (OP_LABELED);
+ write_exp_string (label);
+ write_exp_elt_opcode (OP_LABELED);
+}
+
+/* Returns one or more TREE_LIST nodes, in reverse order. */
+
+static void
+parse_tuple_element (struct type *type)
+{
+ if (PEEK_TOKEN () == DOT_FIELD_NAME)
+ {
+ /* Parse a labelled structure tuple. */
+ parse_named_record_element ();
+ return;
+ }
+
+ if (check_token ('('))
+ {
+ if (check_token ('*'))
+ {
+ expect (')', "missing ')' after '*' case label list");
+ if (type)
+ {
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ /* do this as a range from low to high */
+ struct type *range_type = TYPE_FIELD_TYPE (type, 0);
+ LONGEST low_bound, high_bound;
+ if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+ error ("cannot determine bounds for (*)");
+ /* lower bound */
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (range_type);
+ write_exp_elt_longcst (low_bound);
+ write_exp_elt_opcode (OP_LONG);
+ /* upper bound */
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (range_type);
+ write_exp_elt_longcst (high_bound);
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_opcode (BINOP_RANGE);
+ }
+ else
+ error ("(*) in invalid context");
+ }
+ else
+ error ("(*) only possible with modename in front of tuple (mode[..])");
+ }
+ else
+ {
+ parse_case_label ();
+ while (check_token (','))
+ {
+ parse_case_label ();
+ write_exp_elt_opcode (BINOP_COMMA);
+ }
+ expect (')', NULL);
+ }
+ }
+ else
+ parse_untyped_expr ();
+ if (check_token (':'))
+ {
+ /* A powerset range or a labeled Array. */
+ parse_untyped_expr ();
+ write_exp_elt_opcode (BINOP_RANGE);
+ }
+}
+
+/* Matches: a COMMA-separated list of tuple elements.
+ Returns a list (of TREE_LIST nodes). */
+static void
+parse_opt_element_list (struct type *type)
+{
+ arglist_len = 0;
+ if (PEEK_TOKEN () == ']')
+ return;
+ for (;;)
+ {
+ parse_tuple_element (type);
+ arglist_len++;
+ if (PEEK_TOKEN () == ']')
+ break;
+ if (!check_token (','))
+ error ("bad syntax in tuple");
+ }
+}
+
+/* Parses: '[' elements ']'
+ If modename is non-NULL it prefixed the tuple. */
+
+static void
+parse_tuple (struct type *mode)
+{
+ struct type *type;
+ if (mode)
+ type = check_typedef (mode);
+ else
+ type = 0;
+ require ('[');
+ start_arglist ();
+ parse_opt_element_list (type);
+ expect (']', "missing ']' after tuple");
+ write_exp_elt_opcode (OP_ARRAY);
+ write_exp_elt_longcst ((LONGEST) 0);
+ write_exp_elt_longcst ((LONGEST) end_arglist () - 1);
+ write_exp_elt_opcode (OP_ARRAY);
+ if (type)
+ {
+ if (TYPE_CODE (type) != TYPE_CODE_ARRAY
+ && TYPE_CODE (type) != TYPE_CODE_STRUCT
+ && TYPE_CODE (type) != TYPE_CODE_SET)
+ error ("invalid tuple mode");
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (mode);
+ write_exp_elt_opcode (UNOP_CAST);
+ }
+}
+
+static void
+parse_primval (void)
+{
+ struct type *type;
+ enum exp_opcode op;
+ char *op_name;
+ switch (PEEK_TOKEN ())
+ {
+ case INTEGER_LITERAL:
+ case CHARACTER_LITERAL:
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (PEEK_LVAL ().typed_val.type);
+ write_exp_elt_longcst (PEEK_LVAL ().typed_val.val);
+ write_exp_elt_opcode (OP_LONG);
+ FORWARD_TOKEN ();
+ break;
+ case BOOLEAN_LITERAL:
+ write_exp_elt_opcode (OP_BOOL);
+ write_exp_elt_longcst ((LONGEST) PEEK_LVAL ().ulval);
+ write_exp_elt_opcode (OP_BOOL);
+ FORWARD_TOKEN ();
+ break;
+ case FLOAT_LITERAL:
+ write_exp_elt_opcode (OP_DOUBLE);
+ write_exp_elt_type (builtin_type_double);
+ write_exp_elt_dblcst (PEEK_LVAL ().dval);
+ write_exp_elt_opcode (OP_DOUBLE);
+ FORWARD_TOKEN ();
+ break;
+ case EMPTINESS_LITERAL:
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (lookup_pointer_type (builtin_type_void));
+ write_exp_elt_longcst (0);
+ write_exp_elt_opcode (OP_LONG);
+ FORWARD_TOKEN ();
+ break;
+ case CHARACTER_STRING_LITERAL:
+ write_exp_elt_opcode (OP_STRING);
+ write_exp_string (PEEK_LVAL ().sval);
+ write_exp_elt_opcode (OP_STRING);
+ FORWARD_TOKEN ();
+ break;
+ case BIT_STRING_LITERAL:
+ write_exp_elt_opcode (OP_BITSTRING);
+ write_exp_bitstring (PEEK_LVAL ().sval);
+ write_exp_elt_opcode (OP_BITSTRING);
+ FORWARD_TOKEN ();
+ break;
+ case ARRAY:
+ FORWARD_TOKEN ();
+ /* This is pseudo-Chill, similar to C's '(TYPE[])EXPR'
+ which casts to an artificial array. */
+ expect ('(', NULL);
+ expect (')', NULL);
+ if (PEEK_TOKEN () != TYPENAME)
+ error ("missing MODENAME after ARRAY()");
+ type = PEEK_LVAL ().tsym.type;
+ FORWARD_TOKEN ();
+ expect ('(', NULL);
+ parse_expr ();
+ expect (')', "missing right parenthesis");
+ type = create_array_type ((struct type *) NULL, type,
+ create_range_type ((struct type *) NULL,
+ builtin_type_int, 0, 0));
+ TYPE_ARRAY_UPPER_BOUND_TYPE (type) = BOUND_CANNOT_BE_DETERMINED;
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (type);
+ write_exp_elt_opcode (UNOP_CAST);
+ break;
+#if 0
+ case CONST:
+ case EXPR:
+ val = PEEK_LVAL ();
+ FORWARD_TOKEN ();
+ break;
+#endif
+ case '(':
+ FORWARD_TOKEN ();
+ parse_expr ();
+ expect (')', "missing right parenthesis");
+ break;
+ case '[':
+ parse_tuple (NULL);
+ break;
+ case GENERAL_PROCEDURE_NAME:
+ case LOCATION_NAME:
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ write_exp_elt_block (NULL);
+ write_exp_elt_sym (PEEK_LVAL ().ssym.sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ FORWARD_TOKEN ();
+ break;
+ case GDB_VARIABLE: /* gdb specific */
+ FORWARD_TOKEN ();
+ break;
+ case NUM:
+ parse_unary_call ();
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (builtin_type_int);
+ write_exp_elt_opcode (UNOP_CAST);
+ break;
+ case CARD:
+ parse_unary_call ();
+ write_exp_elt_opcode (UNOP_CARD);
+ break;
+ case MAX_TOKEN:
+ parse_unary_call ();
+ write_exp_elt_opcode (UNOP_CHMAX);
+ break;
+ case MIN_TOKEN:
+ parse_unary_call ();
+ write_exp_elt_opcode (UNOP_CHMIN);
+ break;
+ case PRED:
+ op_name = "PRED";
+ goto unimplemented_unary_builtin;
+ case SUCC:
+ op_name = "SUCC";
+ goto unimplemented_unary_builtin;
+ case ABS:
+ op_name = "ABS";
+ goto unimplemented_unary_builtin;
+ unimplemented_unary_builtin:
+ parse_unary_call ();
+ error ("not implemented: %s builtin function", op_name);
+ break;
+ case ADDR_TOKEN:
+ parse_unary_call ();
+ write_exp_elt_opcode (UNOP_ADDR);
+ break;
+ case SIZE:
+ type = parse_mode_or_normal_call ();
+ if (type)
+ {
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_int);
+ CHECK_TYPEDEF (type);
+ write_exp_elt_longcst ((LONGEST) TYPE_LENGTH (type));
+ write_exp_elt_opcode (OP_LONG);
+ }
+ else
+ write_exp_elt_opcode (UNOP_SIZEOF);
+ break;
+ case LOWER:
+ op = UNOP_LOWER;
+ goto lower_upper;
+ case UPPER:
+ op = UNOP_UPPER;
+ goto lower_upper;
+ lower_upper:
+ type = parse_mode_or_normal_call ();
+ write_lower_upper_value (op, type);
+ break;
+ case LENGTH:
+ parse_unary_call ();
+ write_exp_elt_opcode (UNOP_LENGTH);
+ break;
+ case TYPENAME:
+ type = PEEK_LVAL ().tsym.type;
+ FORWARD_TOKEN ();
+ switch (PEEK_TOKEN ())
+ {
+ case '[':
+ parse_tuple (type);
+ break;
+ case '(':
+ FORWARD_TOKEN ();
+ parse_expr ();
+ expect (')', "missing right parenthesis");
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (type);
+ write_exp_elt_opcode (UNOP_CAST);
+ break;
+ default:
+ error ("typename in invalid context");
+ }
+ break;
+
+ default:
+ error ("invalid expression syntax at `%s'", lexptr);
+ }
+ for (;;)
+ {
+ switch (PEEK_TOKEN ())
+ {
+ case DOT_FIELD_NAME:
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ write_exp_string (PEEK_LVAL ().sval);
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ FORWARD_TOKEN ();
+ continue;
+ case POINTER:
+ FORWARD_TOKEN ();
+ if (PEEK_TOKEN () == TYPENAME)
+ {
+ type = PEEK_LVAL ().tsym.type;
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (lookup_pointer_type (type));
+ write_exp_elt_opcode (UNOP_CAST);
+ FORWARD_TOKEN ();
+ }
+ write_exp_elt_opcode (UNOP_IND);
+ continue;
+ case OPEN_PAREN:
+ parse_call ();
+ continue;
+ case CHARACTER_STRING_LITERAL:
+ case CHARACTER_LITERAL:
+ case BIT_STRING_LITERAL:
+ /* Handle string repetition. (See comment in parse_operand5.) */
+ parse_primval ();
+ write_exp_elt_opcode (MULTI_SUBSCRIPT);
+ write_exp_elt_longcst (1);
+ write_exp_elt_opcode (MULTI_SUBSCRIPT);
+ continue;
+ case END_TOKEN:
+ case TOKEN_NOT_READ:
+ case INTEGER_LITERAL:
+ case BOOLEAN_LITERAL:
+ case FLOAT_LITERAL:
+ case GENERAL_PROCEDURE_NAME:
+ case LOCATION_NAME:
+ case EMPTINESS_LITERAL:
+ case TYPENAME:
+ case CASE:
+ case OF:
+ case ESAC:
+ case LOGIOR:
+ case ORIF:
+ case LOGXOR:
+ case LOGAND:
+ case ANDIF:
+ case NOTEQUAL:
+ case GEQ:
+ case LEQ:
+ case IN:
+ case SLASH_SLASH:
+ case MOD:
+ case REM:
+ case NOT:
+ case RECEIVE:
+ case UP:
+ case IF:
+ case THEN:
+ case ELSE:
+ case FI:
+ case ELSIF:
+ case ILLEGAL_TOKEN:
+ case NUM:
+ case PRED:
+ case SUCC:
+ case ABS:
+ case CARD:
+ case MAX_TOKEN:
+ case MIN_TOKEN:
+ case ADDR_TOKEN:
+ case SIZE:
+ case UPPER:
+ case LOWER:
+ case LENGTH:
+ case ARRAY:
+ case GDB_VARIABLE:
+ case GDB_ASSIGNMENT:
+ break;
+ }
+ break;
+ }
+ return;
+}
+
+static void
+parse_operand6 (void)
+{
+ if (check_token (RECEIVE))
+ {
+ parse_primval ();
+ error ("not implemented: RECEIVE expression");
+ }
+ else if (check_token (POINTER))
+ {
+ parse_primval ();
+ write_exp_elt_opcode (UNOP_ADDR);
+ }
+ else
+ parse_primval ();
+}
+
+static void
+parse_operand5 (void)
+{
+ enum exp_opcode op;
+ /* We are supposed to be looking for a <string repetition operator>,
+ but in general we can't distinguish that from a parenthesized
+ expression. This is especially difficult if we allow the
+ string operand to be a constant expression (as requested by
+ some users), and not just a string literal.
+ Consider: LPRN expr RPRN LPRN expr RPRN
+ Is that a function call or string repetition?
+ Instead, we handle string repetition in parse_primval,
+ and build_generalized_call. */
+ switch (PEEK_TOKEN ())
+ {
+ case NOT:
+ op = UNOP_LOGICAL_NOT;
+ break;
+ case '-':
+ op = UNOP_NEG;
+ break;
+ default:
+ op = OP_NULL;
+ }
+ if (op != OP_NULL)
+ FORWARD_TOKEN ();
+ parse_operand6 ();
+ if (op != OP_NULL)
+ write_exp_elt_opcode (op);
+}
+
+static void
+parse_operand4 (void)
+{
+ enum exp_opcode op;
+ parse_operand5 ();
+ for (;;)
+ {
+ switch (PEEK_TOKEN ())
+ {
+ case '*':
+ op = BINOP_MUL;
+ break;
+ case '/':
+ op = BINOP_DIV;
+ break;
+ case MOD:
+ op = BINOP_MOD;
+ break;
+ case REM:
+ op = BINOP_REM;
+ break;
+ default:
+ return;
+ }
+ FORWARD_TOKEN ();
+ parse_operand5 ();
+ write_exp_elt_opcode (op);
+ }
+}
+
+static void
+parse_operand3 (void)
+{
+ enum exp_opcode op;
+ parse_operand4 ();
+ for (;;)
+ {
+ switch (PEEK_TOKEN ())
+ {
+ case '+':
+ op = BINOP_ADD;
+ break;
+ case '-':
+ op = BINOP_SUB;
+ break;
+ case SLASH_SLASH:
+ op = BINOP_CONCAT;
+ break;
+ default:
+ return;
+ }
+ FORWARD_TOKEN ();
+ parse_operand4 ();
+ write_exp_elt_opcode (op);
+ }
+}
+
+static void
+parse_operand2 (void)
+{
+ enum exp_opcode op;
+ parse_operand3 ();
+ for (;;)
+ {
+ if (check_token (IN))
+ {
+ parse_operand3 ();
+ write_exp_elt_opcode (BINOP_IN);
+ }
+ else
+ {
+ switch (PEEK_TOKEN ())
+ {
+ case '>':
+ op = BINOP_GTR;
+ break;
+ case GEQ:
+ op = BINOP_GEQ;
+ break;
+ case '<':
+ op = BINOP_LESS;
+ break;
+ case LEQ:
+ op = BINOP_LEQ;
+ break;
+ case '=':
+ op = BINOP_EQUAL;
+ break;
+ case NOTEQUAL:
+ op = BINOP_NOTEQUAL;
+ break;
+ default:
+ return;
+ }
+ FORWARD_TOKEN ();
+ parse_operand3 ();
+ write_exp_elt_opcode (op);
+ }
+ }
+}
+
+static void
+parse_operand1 (void)
+{
+ enum exp_opcode op;
+ parse_operand2 ();
+ for (;;)
+ {
+ switch (PEEK_TOKEN ())
+ {
+ case LOGAND:
+ op = BINOP_BITWISE_AND;
+ break;
+ case ANDIF:
+ op = BINOP_LOGICAL_AND;
+ break;
+ default:
+ return;
+ }
+ FORWARD_TOKEN ();
+ parse_operand2 ();
+ write_exp_elt_opcode (op);
+ }
+}
+
+static void
+parse_operand0 (void)
+{
+ enum exp_opcode op;
+ parse_operand1 ();
+ for (;;)
+ {
+ switch (PEEK_TOKEN ())
+ {
+ case LOGIOR:
+ op = BINOP_BITWISE_IOR;
+ break;
+ case LOGXOR:
+ op = BINOP_BITWISE_XOR;
+ break;
+ case ORIF:
+ op = BINOP_LOGICAL_OR;
+ break;
+ default:
+ return;
+ }
+ FORWARD_TOKEN ();
+ parse_operand1 ();
+ write_exp_elt_opcode (op);
+ }
+}
+
+static void
+parse_expr (void)
+{
+ parse_operand0 ();
+ if (check_token (GDB_ASSIGNMENT))
+ {
+ parse_expr ();
+ write_exp_elt_opcode (BINOP_ASSIGN);
+ }
+}
+
+static void
+parse_then_alternative (void)
+{
+ expect (THEN, "missing 'THEN' in 'IF' expression");
+ parse_expr ();
+}
+
+static void
+parse_else_alternative (void)
+{
+ if (check_token (ELSIF))
+ parse_if_expression_body ();
+ else if (check_token (ELSE))
+ parse_expr ();
+ else
+ error ("missing ELSE/ELSIF in IF expression");
+}
+
+/* Matches: <boolean expression> <then alternative> <else alternative> */
+
+static void
+parse_if_expression_body (void)
+{
+ parse_expr ();
+ parse_then_alternative ();
+ parse_else_alternative ();
+ write_exp_elt_opcode (TERNOP_COND);
+}
+
+static void
+parse_if_expression (void)
+{
+ require (IF);
+ parse_if_expression_body ();
+ expect (FI, "missing 'FI' at end of conditional expression");
+}
+
+/* An <untyped_expr> is a superset of <expr>. It also includes
+ <conditional expressions> and untyped <tuples>, whose types
+ are not given by their constituents. Hence, these are only
+ allowed in certain contexts that expect a certain type.
+ You should call convert() to fix up the <untyped_expr>. */
+
+static void
+parse_untyped_expr (void)
+{
+ switch (PEEK_TOKEN ())
+ {
+ case IF:
+ parse_if_expression ();
+ return;
+ case CASE:
+ error ("not implemented: CASE expression");
+ case '(':
+ switch (PEEK_TOKEN1 ())
+ {
+ case IF:
+ case CASE:
+ goto skip_lprn;
+ case '[':
+ skip_lprn:
+ FORWARD_TOKEN ();
+ parse_untyped_expr ();
+ expect (')', "missing ')'");
+ return;
+ default:;
+ /* fall through */
+ }
+ default:
+ parse_operand0 ();
+ }
+}
+
+int
+chill_parse (void)
+{
+ terminal_buffer[0] = TOKEN_NOT_READ;
+ if (PEEK_TOKEN () == TYPENAME && PEEK_TOKEN1 () == END_TOKEN)
+ {
+ write_exp_elt_opcode (OP_TYPE);
+ write_exp_elt_type (PEEK_LVAL ().tsym.type);
+ write_exp_elt_opcode (OP_TYPE);
+ FORWARD_TOKEN ();
+ }
+ else
+ parse_expr ();
+ if (terminal_buffer[0] != END_TOKEN)
+ {
+ if (comma_terminates && terminal_buffer[0] == ',')
+ lexptr--; /* Put the comma back. */
+ else
+ error ("Junk after end of expression.");
+ }
+ return 0;
+}
+
+
+/* Implementation of a dynamically expandable buffer for processing input
+ characters acquired through lexptr and building a value to return in
+ yylval. */
+
+static char *tempbuf; /* Current buffer contents */
+static int tempbufsize; /* Size of allocated buffer */
+static int tempbufindex; /* Current index into buffer */
+
+#define GROWBY_MIN_SIZE 64 /* Minimum amount to grow buffer by */
+
+#define CHECKBUF(size) \
+ do { \
+ if (tempbufindex + (size) >= tempbufsize) \
+ { \
+ growbuf_by_size (size); \
+ } \
+ } while (0);
+
+/* Grow the static temp buffer if necessary, including allocating the first one
+ on demand. */
+
+static void
+growbuf_by_size (int count)
+{
+ int growby;
+
+ growby = max (count, GROWBY_MIN_SIZE);
+ tempbufsize += growby;
+ if (tempbuf == NULL)
+ {
+ tempbuf = (char *) xmalloc (tempbufsize);
+ }
+ else
+ {
+ tempbuf = (char *) xrealloc (tempbuf, tempbufsize);
+ }
+}
+
+/* Try to consume a simple name string token. If successful, returns
+ a pointer to a nullbyte terminated copy of the name that can be used
+ in symbol table lookups. If not successful, returns NULL. */
+
+static char *
+match_simple_name_string (void)
+{
+ char *tokptr = lexptr;
+
+ if (isalpha (*tokptr) || *tokptr == '_')
+ {
+ char *result;
+ do
+ {
+ tokptr++;
+ }
+ while (isalnum (*tokptr) || (*tokptr == '_'));
+ yylval.sval.ptr = lexptr;
+ yylval.sval.length = tokptr - lexptr;
+ lexptr = tokptr;
+ result = copy_name (yylval.sval);
+ return result;
+ }
+ return (NULL);
+}
+
+/* Start looking for a value composed of valid digits as set by the base
+ in use. Note that '_' characters are valid anywhere, in any quantity,
+ and are simply ignored. Since we must find at least one valid digit,
+ or reject this token as an integer literal, we keep track of how many
+ digits we have encountered. */
+
+static int
+decode_integer_value (int base, char **tokptrptr, LONGEST *ivalptr)
+{
+ char *tokptr = *tokptrptr;
+ int temp;
+ int digits = 0;
+
+ while (*tokptr != '\0')
+ {
+ temp = *tokptr;
+ if (isupper (temp))
+ temp = tolower (temp);
+ tokptr++;
+ switch (temp)
+ {
+ case '_':
+ continue;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ temp -= '0';
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ temp -= 'a';
+ temp += 10;
+ break;
+ default:
+ temp = base;
+ break;
+ }
+ if (temp < base)
+ {
+ digits++;
+ *ivalptr *= base;
+ *ivalptr += temp;
+ }
+ else
+ {
+ /* Found something not in domain for current base. */
+ tokptr--; /* Unconsume what gave us indigestion. */
+ break;
+ }
+ }
+
+ /* If we didn't find any digits, then we don't have a valid integer
+ value, so reject the entire token. Otherwise, update the lexical
+ scan pointer, and return non-zero for success. */
+
+ if (digits == 0)
+ {
+ return (0);
+ }
+ else
+ {
+ *tokptrptr = tokptr;
+ return (1);
+ }
+}
+
+static int
+decode_integer_literal (LONGEST *valptr, char **tokptrptr)
+{
+ char *tokptr = *tokptrptr;
+ int base = 0;
+ LONGEST ival = 0;
+ int explicit_base = 0;
+
+ /* Look for an explicit base specifier, which is optional. */
+
+ switch (*tokptr)
+ {
+ case 'd':
+ case 'D':
+ explicit_base++;
+ base = 10;
+ tokptr++;
+ break;
+ case 'b':
+ case 'B':
+ explicit_base++;
+ base = 2;
+ tokptr++;
+ break;
+ case 'h':
+ case 'H':
+ explicit_base++;
+ base = 16;
+ tokptr++;
+ break;
+ case 'o':
+ case 'O':
+ explicit_base++;
+ base = 8;
+ tokptr++;
+ break;
+ default:
+ base = 10;
+ break;
+ }
+
+ /* If we found an explicit base ensure that the character after the
+ explicit base is a single quote. */
+
+ if (explicit_base && (*tokptr++ != '\''))
+ {
+ return (0);
+ }
+
+ /* Attempt to decode whatever follows as an integer value in the
+ indicated base, updating the token pointer in the process and
+ computing the value into ival. Also, if we have an explicit
+ base, then the next character must not be a single quote, or we
+ have a bitstring literal, so reject the entire token in this case.
+ Otherwise, update the lexical scan pointer, and return non-zero
+ for success. */
+
+ if (!decode_integer_value (base, &tokptr, &ival))
+ {
+ return (0);
+ }
+ else if (explicit_base && (*tokptr == '\''))
+ {
+ return (0);
+ }
+ else
+ {
+ *valptr = ival;
+ *tokptrptr = tokptr;
+ return (1);
+ }
+}
+
+/* If it wasn't for the fact that floating point values can contain '_'
+ characters, we could just let strtod do all the hard work by letting it
+ try to consume as much of the current token buffer as possible and
+ find a legal conversion. Unfortunately we need to filter out the '_'
+ characters before calling strtod, which we do by copying the other
+ legal chars to a local buffer to be converted. However since we also
+ need to keep track of where the last unconsumed character in the input
+ buffer is, we have transfer only as many characters as may compose a
+ legal floating point value. */
+
+static enum ch_terminal
+match_float_literal (void)
+{
+ char *tokptr = lexptr;
+ char *buf;
+ char *copy;
+ double dval;
+ extern double strtod ();
+
+ /* Make local buffer in which to build the string to convert. This is
+ required because underscores are valid in chill floating point numbers
+ but not in the string passed to strtod to convert. The string will be
+ no longer than our input string. */
+
+ copy = buf = (char *) alloca (strlen (tokptr) + 1);
+
+ /* Transfer all leading digits to the conversion buffer, discarding any
+ underscores. */
+
+ while (isdigit (*tokptr) || *tokptr == '_')
+ {
+ if (*tokptr != '_')
+ {
+ *copy++ = *tokptr;
+ }
+ tokptr++;
+ }
+
+ /* Now accept either a '.', or one of [eEdD]. Dot is legal regardless
+ of whether we found any leading digits, and we simply accept it and
+ continue on to look for the fractional part and/or exponent. One of
+ [eEdD] is legal only if we have seen digits, and means that there
+ is no fractional part. If we find neither of these, then this is
+ not a floating point number, so return failure. */
+
+ switch (*tokptr++)
+ {
+ case '.':
+ /* Accept and then look for fractional part and/or exponent. */
+ *copy++ = '.';
+ break;
+
+ case 'e':
+ case 'E':
+ case 'd':
+ case 'D':
+ if (copy == buf)
+ {
+ return (0);
+ }
+ *copy++ = 'e';
+ goto collect_exponent;
+ break;
+
+ default:
+ return (0);
+ break;
+ }
+
+ /* We found a '.', copy any fractional digits to the conversion buffer, up
+ to the first nondigit, non-underscore character. */
+
+ while (isdigit (*tokptr) || *tokptr == '_')
+ {
+ if (*tokptr != '_')
+ {
+ *copy++ = *tokptr;
+ }
+ tokptr++;
+ }
+
+ /* Look for an exponent, which must start with one of [eEdD]. If none
+ is found, jump directly to trying to convert what we have collected
+ so far. */
+
+ switch (*tokptr)
+ {
+ case 'e':
+ case 'E':
+ case 'd':
+ case 'D':
+ *copy++ = 'e';
+ tokptr++;
+ break;
+ default:
+ goto convert_float;
+ break;
+ }
+
+ /* Accept an optional '-' or '+' following one of [eEdD]. */
+
+collect_exponent:
+ if (*tokptr == '+' || *tokptr == '-')
+ {
+ *copy++ = *tokptr++;
+ }
+
+ /* Now copy an exponent into the conversion buffer. Note that at the
+ moment underscores are *not* allowed in exponents. */
+
+ while (isdigit (*tokptr))
+ {
+ *copy++ = *tokptr++;
+ }
+
+ /* If we transfered any chars to the conversion buffer, try to interpret its
+ contents as a floating point value. If any characters remain, then we
+ must not have a valid floating point string. */
+
+convert_float:
+ *copy = '\0';
+ if (copy != buf)
+ {
+ dval = strtod (buf, &copy);
+ if (*copy == '\0')
+ {
+ yylval.dval = dval;
+ lexptr = tokptr;
+ return (FLOAT_LITERAL);
+ }
+ }
+ return (0);
+}
+
+/* Recognize a string literal. A string literal is a sequence
+ of characters enclosed in matching single or double quotes, except that
+ a single character inside single quotes is a character literal, which
+ we reject as a string literal. To embed the terminator character inside
+ a string, it is simply doubled (I.E. "this""is""one""string") */
+
+static enum ch_terminal
+match_string_literal (void)
+{
+ char *tokptr = lexptr;
+ int in_ctrlseq = 0;
+ LONGEST ival;
+
+ for (tempbufindex = 0, tokptr++; *tokptr != '\0'; tokptr++)
+ {
+ CHECKBUF (1);
+ tryagain:;
+ if (in_ctrlseq)
+ {
+ /* skip possible whitespaces */
+ while ((*tokptr == ' ' || *tokptr == '\t') && *tokptr)
+ tokptr++;
+ if (*tokptr == ')')
+ {
+ in_ctrlseq = 0;
+ tokptr++;
+ goto tryagain;
+ }
+ else if (*tokptr != ',')
+ error ("Invalid control sequence");
+ tokptr++;
+ /* skip possible whitespaces */
+ while ((*tokptr == ' ' || *tokptr == '\t') && *tokptr)
+ tokptr++;
+ if (!decode_integer_literal (&ival, &tokptr))
+ error ("Invalid control sequence");
+ tokptr--;
+ }
+ else if (*tokptr == *lexptr)
+ {
+ if (*(tokptr + 1) == *lexptr)
+ {
+ ival = *tokptr++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ else if (*tokptr == '^')
+ {
+ if (*(tokptr + 1) == '(')
+ {
+ in_ctrlseq = 1;
+ tokptr += 2;
+ if (!decode_integer_literal (&ival, &tokptr))
+ error ("Invalid control sequence");
+ tokptr--;
+ }
+ else if (*(tokptr + 1) == '^')
+ ival = *tokptr++;
+ else
+ error ("Invalid control sequence");
+ }
+ else
+ ival = *tokptr;
+ tempbuf[tempbufindex++] = ival;
+ }
+ if (in_ctrlseq)
+ error ("Invalid control sequence");
+
+ if (*tokptr == '\0' /* no terminator */
+ || (tempbufindex == 1 && *tokptr == '\'')) /* char literal */
+ {
+ return (0);
+ }
+ else
+ {
+ tempbuf[tempbufindex] = '\0';
+ yylval.sval.ptr = tempbuf;
+ yylval.sval.length = tempbufindex;
+ lexptr = ++tokptr;
+ return (CHARACTER_STRING_LITERAL);
+ }
+}
+
+/* Recognize a character literal. A character literal is single character
+ or a control sequence, enclosed in single quotes. A control sequence
+ is a comma separated list of one or more integer literals, enclosed
+ in parenthesis and introduced with a circumflex character.
+
+ EX: 'a' '^(7)' '^(7,8)'
+
+ As a GNU chill extension, the syntax C'xx' is also recognized as a
+ character literal, where xx is a hex value for the character.
+
+ Note that more than a single character, enclosed in single quotes, is
+ a string literal.
+
+ Returns CHARACTER_LITERAL if a match is found.
+ */
+
+static enum ch_terminal
+match_character_literal (void)
+{
+ char *tokptr = lexptr;
+ LONGEST ival = 0;
+
+ if ((*tokptr == 'c' || *tokptr == 'C') && (*(tokptr + 1) == '\''))
+ {
+ /* We have a GNU chill extension form, so skip the leading "C'",
+ decode the hex value, and then ensure that we have a trailing
+ single quote character. */
+ tokptr += 2;
+ if (!decode_integer_value (16, &tokptr, &ival) || (*tokptr != '\''))
+ {
+ return (0);
+ }
+ tokptr++;
+ }
+ else if (*tokptr == '\'')
+ {
+ tokptr++;
+
+ /* Determine which form we have, either a control sequence or the
+ single character form. */
+
+ if (*tokptr == '^')
+ {
+ if (*(tokptr + 1) == '(')
+ {
+ /* Match and decode a control sequence. Return zero if we don't
+ find a valid integer literal, or if the next unconsumed character
+ after the integer literal is not the trailing ')'. */
+ tokptr += 2;
+ if (!decode_integer_literal (&ival, &tokptr) || (*tokptr++ != ')'))
+ {
+ return (0);
+ }
+ }
+ else if (*(tokptr + 1) == '^')
+ {
+ ival = *tokptr;
+ tokptr += 2;
+ }
+ else
+ /* fail */
+ error ("Invalid control sequence");
+ }
+ else if (*tokptr == '\'')
+ {
+ /* this must be duplicated */
+ ival = *tokptr;
+ tokptr += 2;
+ }
+ else
+ {
+ ival = *tokptr++;
+ }
+
+ /* The trailing quote has not yet been consumed. If we don't find
+ it, then we have no match. */
+
+ if (*tokptr++ != '\'')
+ {
+ return (0);
+ }
+ }
+ else
+ {
+ /* Not a character literal. */
+ return (0);
+ }
+ yylval.typed_val.val = ival;
+ yylval.typed_val.type = builtin_type_chill_char;
+ lexptr = tokptr;
+ return (CHARACTER_LITERAL);
+}
+
+/* Recognize an integer literal, as specified in Z.200 sec 5.2.4.2.
+ Note that according to 5.2.4.2, a single "_" is also a valid integer
+ literal, however GNU-chill requires there to be at least one "digit"
+ in any integer literal. */
+
+static enum ch_terminal
+match_integer_literal (void)
+{
+ char *tokptr = lexptr;
+ LONGEST ival;
+
+ if (!decode_integer_literal (&ival, &tokptr))
+ {
+ return (0);
+ }
+ else
+ {
+ yylval.typed_val.val = ival;
+#if defined(CC_HAS_LONG_LONG)
+ if (ival > (LONGEST) 2147483647U || ival < -(LONGEST) 2147483648U)
+ yylval.typed_val.type = builtin_type_long_long;
+ else
+#endif
+ yylval.typed_val.type = builtin_type_int;
+ lexptr = tokptr;
+ return (INTEGER_LITERAL);
+ }
+}
+
+/* Recognize a bit-string literal, as specified in Z.200 sec 5.2.4.8
+ Note that according to 5.2.4.8, a single "_" is also a valid bit-string
+ literal, however GNU-chill requires there to be at least one "digit"
+ in any bit-string literal. */
+
+static enum ch_terminal
+match_bitstring_literal (void)
+{
+ register char *tokptr = lexptr;
+ int bitoffset = 0;
+ int bitcount = 0;
+ int bits_per_char;
+ int digit;
+
+ tempbufindex = 0;
+ CHECKBUF (1);
+ tempbuf[0] = 0;
+
+ /* Look for the required explicit base specifier. */
+
+ switch (*tokptr++)
+ {
+ case 'b':
+ case 'B':
+ bits_per_char = 1;
+ break;
+ case 'o':
+ case 'O':
+ bits_per_char = 3;
+ break;
+ case 'h':
+ case 'H':
+ bits_per_char = 4;
+ break;
+ default:
+ return (0);
+ break;
+ }
+
+ /* Ensure that the character after the explicit base is a single quote. */
+
+ if (*tokptr++ != '\'')
+ {
+ return (0);
+ }
+
+ while (*tokptr != '\0' && *tokptr != '\'')
+ {
+ digit = *tokptr;
+ if (isupper (digit))
+ digit = tolower (digit);
+ tokptr++;
+ switch (digit)
+ {
+ case '_':
+ continue;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ digit -= '0';
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ digit -= 'a';
+ digit += 10;
+ break;
+ default:
+ /* this is not a bitstring literal, probably an integer */
+ return 0;
+ }
+ if (digit >= 1 << bits_per_char)
+ {
+ /* Found something not in domain for current base. */
+ error ("Too-large digit in bitstring or integer.");
+ }
+ else
+ {
+ /* Extract bits from digit, packing them into the bitstring byte. */
+ int k = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? bits_per_char - 1 : 0;
+ for (; TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? k >= 0 : k < bits_per_char;
+ TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? k-- : k++)
+ {
+ bitcount++;
+ if (digit & (1 << k))
+ {
+ tempbuf[tempbufindex] |=
+ (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ ? (1 << (HOST_CHAR_BIT - 1 - bitoffset))
+ : (1 << bitoffset);
+ }
+ bitoffset++;
+ if (bitoffset == HOST_CHAR_BIT)
+ {
+ bitoffset = 0;
+ tempbufindex++;
+ CHECKBUF (1);
+ tempbuf[tempbufindex] = 0;
+ }
+ }
+ }
+ }
+
+ /* Verify that we consumed everything up to the trailing single quote,
+ and that we found some bits (IE not just underbars). */
+
+ if (*tokptr++ != '\'')
+ {
+ return (0);
+ }
+ else
+ {
+ yylval.sval.ptr = tempbuf;
+ yylval.sval.length = bitcount;
+ lexptr = tokptr;
+ return (BIT_STRING_LITERAL);
+ }
+}
+
+struct token
+{
+ char *operator;
+ int token;
+};
+
+static const struct token idtokentab[] =
+{
+ {"array", ARRAY},
+ {"length", LENGTH},
+ {"lower", LOWER},
+ {"upper", UPPER},
+ {"andif", ANDIF},
+ {"pred", PRED},
+ {"succ", SUCC},
+ {"card", CARD},
+ {"size", SIZE},
+ {"orif", ORIF},
+ {"num", NUM},
+ {"abs", ABS},
+ {"max", MAX_TOKEN},
+ {"min", MIN_TOKEN},
+ {"mod", MOD},
+ {"rem", REM},
+ {"not", NOT},
+ {"xor", LOGXOR},
+ {"and", LOGAND},
+ {"in", IN},
+ {"or", LOGIOR},
+ {"up", UP},
+ {"addr", ADDR_TOKEN},
+ {"null", EMPTINESS_LITERAL}
+};
+
+static const struct token tokentab2[] =
+{
+ {":=", GDB_ASSIGNMENT},
+ {"//", SLASH_SLASH},
+ {"->", POINTER},
+ {"/=", NOTEQUAL},
+ {"<=", LEQ},
+ {">=", GEQ}
+};
+
+/* Read one token, getting characters through lexptr. */
+/* This is where we will check to make sure that the language and the
+ operators used are compatible. */
+
+static enum ch_terminal
+ch_lex (void)
+{
+ unsigned int i;
+ enum ch_terminal token;
+ char *inputname;
+ struct symbol *sym;
+
+ /* Skip over any leading whitespace. */
+ while (isspace (*lexptr))
+ {
+ lexptr++;
+ }
+ /* Look for special single character cases which can't be the first
+ character of some other multicharacter token. */
+ switch (*lexptr)
+ {
+ case '\0':
+ return END_TOKEN;
+ case ',':
+ case '=':
+ case ';':
+ case '!':
+ case '+':
+ case '*':
+ case '(':
+ case ')':
+ case '[':
+ case ']':
+ return (*lexptr++);
+ }
+ /* Look for characters which start a particular kind of multicharacter
+ token, such as a character literal, register name, convenience
+ variable name, string literal, etc. */
+ switch (*lexptr)
+ {
+ case '\'':
+ case '\"':
+ /* First try to match a string literal, which is any
+ sequence of characters enclosed in matching single or double
+ quotes, except that a single character inside single quotes
+ is a character literal, so we have to catch that case also. */
+ token = match_string_literal ();
+ if (token != 0)
+ {
+ return (token);
+ }
+ if (*lexptr == '\'')
+ {
+ token = match_character_literal ();
+ if (token != 0)
+ {
+ return (token);
+ }
+ }
+ break;
+ case 'C':
+ case 'c':
+ token = match_character_literal ();
+ if (token != 0)
+ {
+ return (token);
+ }
+ break;
+ case '$':
+ yylval.sval.ptr = lexptr;
+ do
+ {
+ lexptr++;
+ }
+ while (isalnum (*lexptr) || *lexptr == '_' || *lexptr == '$');
+ yylval.sval.length = lexptr - yylval.sval.ptr;
+ write_dollar_variable (yylval.sval);
+ return GDB_VARIABLE;
+ break;
+ }
+ /* See if it is a special token of length 2. */
+ for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++)
+ {
+ if (STREQN (lexptr, tokentab2[i].operator, 2))
+ {
+ lexptr += 2;
+ return (tokentab2[i].token);
+ }
+ }
+ /* Look for single character cases which which could be the first
+ character of some other multicharacter token, but aren't, or we
+ would already have found it. */
+ switch (*lexptr)
+ {
+ case '-':
+ case ':':
+ case '/':
+ case '<':
+ case '>':
+ return (*lexptr++);
+ }
+ /* Look for a float literal before looking for an integer literal, so
+ we match as much of the input stream as possible. */
+ token = match_float_literal ();
+ if (token != 0)
+ {
+ return (token);
+ }
+ token = match_bitstring_literal ();
+ if (token != 0)
+ {
+ return (token);
+ }
+ token = match_integer_literal ();
+ if (token != 0)
+ {
+ return (token);
+ }
+
+ /* Try to match a simple name string, and if a match is found, then
+ further classify what sort of name it is and return an appropriate
+ token. Note that attempting to match a simple name string consumes
+ the token from lexptr, so we can't back out if we later find that
+ we can't classify what sort of name it is. */
+
+ inputname = match_simple_name_string ();
+
+ if (inputname != NULL)
+ {
+ char *simplename = (char *) alloca (strlen (inputname) + 1);
+
+ char *dptr = simplename, *sptr = inputname;
+ for (; *sptr; sptr++)
+ *dptr++ = isupper (*sptr) ? tolower (*sptr) : *sptr;
+ *dptr = '\0';
+
+ /* See if it is a reserved identifier. */
+ for (i = 0; i < sizeof (idtokentab) / sizeof (idtokentab[0]); i++)
+ {
+ if (STREQ (simplename, idtokentab[i].operator))
+ {
+ return (idtokentab[i].token);
+ }
+ }
+
+ /* Look for other special tokens. */
+ if (STREQ (simplename, "true"))
+ {
+ yylval.ulval = 1;
+ return (BOOLEAN_LITERAL);
+ }
+ if (STREQ (simplename, "false"))
+ {
+ yylval.ulval = 0;
+ return (BOOLEAN_LITERAL);
+ }
+
+ sym = lookup_symbol (inputname, expression_context_block,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ if (sym == NULL && strcmp (inputname, simplename) != 0)
+ {
+ sym = lookup_symbol (simplename, expression_context_block,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ }
+ if (sym != NULL)
+ {
+ yylval.ssym.stoken.ptr = NULL;
+ yylval.ssym.stoken.length = 0;
+ yylval.ssym.sym = sym;
+ yylval.ssym.is_a_field_of_this = 0; /* FIXME, C++'ism */
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_BLOCK:
+ /* Found a procedure name. */
+ return (GENERAL_PROCEDURE_NAME);
+ case LOC_STATIC:
+ /* Found a global or local static variable. */
+ return (LOCATION_NAME);
+ case LOC_REGISTER:
+ case LOC_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_LOCAL:
+ case LOC_LOCAL_ARG:
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
+ if (innermost_block == NULL
+ || contained_in (block_found, innermost_block))
+ {
+ innermost_block = block_found;
+ }
+ return (LOCATION_NAME);
+ break;
+ case LOC_CONST:
+ case LOC_LABEL:
+ return (LOCATION_NAME);
+ break;
+ case LOC_TYPEDEF:
+ yylval.tsym.type = SYMBOL_TYPE (sym);
+ return TYPENAME;
+ case LOC_UNDEF:
+ case LOC_CONST_BYTES:
+ case LOC_OPTIMIZED_OUT:
+ error ("Symbol \"%s\" names no location.", inputname);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "unhandled SYMBOL_CLASS in ch_lex()");
+ break;
+ }
+ }
+ else if (!have_full_symbols () && !have_partial_symbols ())
+ {
+ error ("No symbol table is loaded. Use the \"file\" command.");
+ }
+ else
+ {
+ error ("No symbol \"%s\" in current context.", inputname);
+ }
+ }
+
+ /* Catch single character tokens which are not part of some
+ longer token. */
+
+ switch (*lexptr)
+ {
+ case '.': /* Not float for example. */
+ lexptr++;
+ while (isspace (*lexptr))
+ lexptr++;
+ inputname = match_simple_name_string ();
+ if (!inputname)
+ return '.';
+ return DOT_FIELD_NAME;
+ }
+
+ return (ILLEGAL_TOKEN);
+}
+
+static void
+write_lower_upper_value (enum exp_opcode opcode, /* Either UNOP_LOWER or UNOP_UPPER */
+ struct type *type)
+{
+ if (type == NULL)
+ write_exp_elt_opcode (opcode);
+ else
+ {
+ struct type *result_type;
+ LONGEST val = type_lower_upper (opcode, type, &result_type);
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (result_type);
+ write_exp_elt_longcst (val);
+ write_exp_elt_opcode (OP_LONG);
+ }
+}
+
+void
+chill_error (char *msg)
+{
+ /* Never used. */
+}
diff --git a/gdb/ch-lang.c b/gdb/ch-lang.c
new file mode 100644
index 00000000000..b46dce01454
--- /dev/null
+++ b/gdb/ch-lang.c
@@ -0,0 +1,663 @@
+/* Chill language support routines for GDB, the GNU debugger.
+ Copyright 1992, 1993, 1994, 1995, 1996, 2000, 2001, 2002
+ 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "value.h"
+#include "expression.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "ch-lang.h"
+#include "valprint.h"
+
+extern void _initialize_chill_language (void);
+
+static struct value *evaluate_subexp_chill (struct type *, struct expression *,
+ int *, enum noside);
+
+static struct value *value_chill_max_min (enum exp_opcode, struct value *);
+
+static struct value *value_chill_card (struct value *);
+
+static struct value *value_chill_length (struct value *);
+
+static struct type *chill_create_fundamental_type (struct objfile *, int);
+
+static void chill_printstr (struct ui_file * stream, char *string,
+ unsigned int length, int width,
+ int force_ellipses);
+
+static void chill_printchar (int, struct ui_file *);
+
+/* For now, Chill uses a simple mangling algorithm whereby you simply
+ discard everything after the occurance of two successive CPLUS_MARKER
+ characters to derive the demangled form. */
+
+char *
+chill_demangle (const char *mangled)
+{
+ const char *joiner = NULL;
+ char *demangled;
+ const char *cp = mangled;
+
+ while (*cp)
+ {
+ if (is_cplus_marker (*cp))
+ {
+ joiner = cp;
+ break;
+ }
+ cp++;
+ }
+ if (joiner != NULL && *(joiner + 1) == *joiner)
+ {
+ demangled = savestring (mangled, joiner - mangled);
+ }
+ else
+ {
+ demangled = NULL;
+ }
+ return (demangled);
+}
+
+static void
+chill_printchar (register int c, struct ui_file *stream)
+{
+ c &= 0xFF; /* Avoid sign bit follies */
+
+ if (PRINT_LITERAL_FORM (c))
+ {
+ if (c == '\'' || c == '^')
+ fprintf_filtered (stream, "'%c%c'", c, c);
+ else
+ fprintf_filtered (stream, "'%c'", c);
+ }
+ else
+ {
+ fprintf_filtered (stream, "'^(%u)'", (unsigned int) c);
+ }
+}
+
+/* Print the character string STRING, printing at most LENGTH characters.
+ Printing stops early if the number hits print_max; repeat counts
+ are printed as appropriate. Print ellipses at the end if we
+ had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.
+ Note that gdb maintains the length of strings without counting the
+ terminating null byte, while chill strings are typically written with
+ an explicit null byte. So we always assume an implied null byte
+ until gdb is able to maintain non-null terminated strings as well
+ as null terminated strings (FIXME).
+ */
+
+static void
+chill_printstr (struct ui_file *stream, char *string, unsigned int length,
+ int width, int force_ellipses)
+{
+ register unsigned int i;
+ unsigned int things_printed = 0;
+ int in_literal_form = 0;
+ int in_control_form = 0;
+ int need_slashslash = 0;
+ unsigned int c;
+
+ if (length == 0)
+ {
+ fputs_filtered ("\"\"", stream);
+ return;
+ }
+
+ for (i = 0; i < length && things_printed < print_max; ++i)
+ {
+ /* Position of the character we are examining
+ to see whether it is repeated. */
+ unsigned int rep1;
+ /* Number of repetitions we have detected so far. */
+ unsigned int reps;
+
+ QUIT;
+
+ if (need_slashslash)
+ {
+ fputs_filtered ("//", stream);
+ need_slashslash = 0;
+ }
+
+ rep1 = i + 1;
+ reps = 1;
+ while (rep1 < length && string[rep1] == string[i])
+ {
+ ++rep1;
+ ++reps;
+ }
+
+ c = string[i];
+ if (reps > repeat_count_threshold)
+ {
+ if (in_control_form || in_literal_form)
+ {
+ if (in_control_form)
+ fputs_filtered (")", stream);
+ fputs_filtered ("\"//", stream);
+ in_control_form = in_literal_form = 0;
+ }
+ chill_printchar (c, stream);
+ fprintf_filtered (stream, "<repeats %u times>", reps);
+ i = rep1 - 1;
+ things_printed += repeat_count_threshold;
+ need_slashslash = 1;
+ }
+ else
+ {
+ if (!in_literal_form && !in_control_form)
+ fputs_filtered ("\"", stream);
+ if (PRINT_LITERAL_FORM (c))
+ {
+ if (!in_literal_form)
+ {
+ if (in_control_form)
+ {
+ fputs_filtered (")", stream);
+ in_control_form = 0;
+ }
+ in_literal_form = 1;
+ }
+ fprintf_filtered (stream, "%c", c);
+ if (c == '"' || c == '^')
+ /* duplicate this one as must be done at input */
+ fprintf_filtered (stream, "%c", c);
+ }
+ else
+ {
+ if (!in_control_form)
+ {
+ if (in_literal_form)
+ {
+ in_literal_form = 0;
+ }
+ fputs_filtered ("^(", stream);
+ in_control_form = 1;
+ }
+ else
+ fprintf_filtered (stream, ",");
+ c = c & 0xff;
+ fprintf_filtered (stream, "%u", (unsigned int) c);
+ }
+ ++things_printed;
+ }
+ }
+
+ /* Terminate the quotes if necessary. */
+ if (in_control_form)
+ {
+ fputs_filtered (")", stream);
+ }
+ if (in_literal_form || in_control_form)
+ {
+ fputs_filtered ("\"", stream);
+ }
+ if (force_ellipses || (i < length))
+ {
+ fputs_filtered ("...", stream);
+ }
+}
+
+static struct type *
+chill_create_fundamental_type (struct objfile *objfile, int typeid)
+{
+ register struct type *type = NULL;
+
+ switch (typeid)
+ {
+ default:
+ /* FIXME: For now, if we are asked to produce a type not in this
+ language, create the equivalent of a C integer type with the
+ name "<?type?>". When all the dust settles from the type
+ reconstruction work, this should probably become an error. */
+ type = init_type (TYPE_CODE_INT, 2, 0, "<?type?>", objfile);
+ warning ("internal error: no chill fundamental type %d", typeid);
+ break;
+ case FT_VOID:
+ /* FIXME: Currently the GNU Chill compiler emits some DWARF entries for
+ typedefs, unrelated to anything directly in the code being compiled,
+ that have some FT_VOID types. Just fake it for now. */
+ type = init_type (TYPE_CODE_VOID, 0, 0, "<?VOID?>", objfile);
+ break;
+ case FT_BOOLEAN:
+ type = init_type (TYPE_CODE_BOOL, 1, TYPE_FLAG_UNSIGNED, "BOOL", objfile);
+ break;
+ case FT_CHAR:
+ type = init_type (TYPE_CODE_CHAR, 1, TYPE_FLAG_UNSIGNED, "CHAR", objfile);
+ break;
+ case FT_SIGNED_CHAR:
+ type = init_type (TYPE_CODE_INT, 1, 0, "BYTE", objfile);
+ break;
+ case FT_UNSIGNED_CHAR:
+ type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED, "UBYTE", objfile);
+ break;
+ case FT_SHORT: /* Chill ints are 2 bytes */
+ type = init_type (TYPE_CODE_INT, 2, 0, "INT", objfile);
+ break;
+ case FT_UNSIGNED_SHORT: /* Chill ints are 2 bytes */
+ type = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_UNSIGNED, "UINT", objfile);
+ break;
+ case FT_INTEGER: /* FIXME? */
+ case FT_SIGNED_INTEGER: /* FIXME? */
+ case FT_LONG: /* Chill longs are 4 bytes */
+ case FT_SIGNED_LONG: /* Chill longs are 4 bytes */
+ type = init_type (TYPE_CODE_INT, 4, 0, "LONG", objfile);
+ break;
+ case FT_UNSIGNED_INTEGER: /* FIXME? */
+ case FT_UNSIGNED_LONG: /* Chill longs are 4 bytes */
+ type = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_UNSIGNED, "ULONG", objfile);
+ break;
+ case FT_FLOAT:
+ type = init_type (TYPE_CODE_FLT, 4, 0, "REAL", objfile);
+ break;
+ case FT_DBL_PREC_FLOAT:
+ type = init_type (TYPE_CODE_FLT, 8, 0, "LONG_REAL", objfile);
+ break;
+ }
+ return (type);
+}
+
+
+/* Table of operators and their precedences for printing expressions. */
+
+static const struct op_print chill_op_print_tab[] =
+{
+ {"AND", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
+ {"OR", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
+ {"NOT", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
+ {"MOD", BINOP_MOD, PREC_MUL, 0},
+ {"REM", BINOP_REM, PREC_MUL, 0},
+ {"SIZE", UNOP_SIZEOF, PREC_BUILTIN_FUNCTION, 0},
+ {"LOWER", UNOP_LOWER, PREC_BUILTIN_FUNCTION, 0},
+ {"UPPER", UNOP_UPPER, PREC_BUILTIN_FUNCTION, 0},
+ {"CARD", UNOP_CARD, PREC_BUILTIN_FUNCTION, 0},
+ {"MAX", UNOP_CHMAX, PREC_BUILTIN_FUNCTION, 0},
+ {"MIN", UNOP_CHMIN, PREC_BUILTIN_FUNCTION, 0},
+ {":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
+ {"=", BINOP_EQUAL, PREC_EQUAL, 0},
+ {"/=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
+ {"<=", BINOP_LEQ, PREC_ORDER, 0},
+ {">=", BINOP_GEQ, PREC_ORDER, 0},
+ {">", BINOP_GTR, PREC_ORDER, 0},
+ {"<", BINOP_LESS, PREC_ORDER, 0},
+ {"+", BINOP_ADD, PREC_ADD, 0},
+ {"-", BINOP_SUB, PREC_ADD, 0},
+ {"*", BINOP_MUL, PREC_MUL, 0},
+ {"/", BINOP_DIV, PREC_MUL, 0},
+ {"//", BINOP_CONCAT, PREC_PREFIX, 0}, /* FIXME: precedence? */
+ {"-", UNOP_NEG, PREC_PREFIX, 0},
+ {"->", UNOP_IND, PREC_SUFFIX, 1},
+ {"->", UNOP_ADDR, PREC_PREFIX, 0},
+ {":", BINOP_RANGE, PREC_ASSIGN, 0},
+ {NULL, 0, 0, 0}
+};
+
+/* The built-in types of Chill. */
+
+struct type *builtin_type_chill_bool;
+struct type *builtin_type_chill_char;
+struct type *builtin_type_chill_long;
+struct type *builtin_type_chill_ulong;
+struct type *builtin_type_chill_real;
+
+struct type **const (chill_builtin_types[]) =
+{
+ &builtin_type_chill_bool,
+ &builtin_type_chill_char,
+ &builtin_type_chill_long,
+ &builtin_type_chill_ulong,
+ &builtin_type_chill_real,
+ 0
+};
+
+/* Calculate LOWER or UPPER of TYPE.
+ Returns the result as an integer.
+ *RESULT_TYPE is the appropriate type for the result. */
+
+LONGEST
+type_lower_upper (enum exp_opcode op, /* Either UNOP_LOWER or UNOP_UPPER */
+ struct type *type, struct type **result_type)
+{
+ LONGEST low, high;
+ *result_type = type;
+ CHECK_TYPEDEF (type);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_STRUCT:
+ *result_type = builtin_type_int;
+ if (chill_varying_type (type))
+ return type_lower_upper (op, TYPE_FIELD_TYPE (type, 1), result_type);
+ break;
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_BITSTRING:
+ case TYPE_CODE_STRING:
+ type = TYPE_FIELD_TYPE (type, 0); /* Get index type */
+
+ /* ... fall through ... */
+ case TYPE_CODE_RANGE:
+ *result_type = TYPE_TARGET_TYPE (type);
+ return op == UNOP_LOWER ? TYPE_LOW_BOUND (type) : TYPE_HIGH_BOUND (type);
+
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ if (get_discrete_bounds (type, &low, &high) >= 0)
+ {
+ *result_type = type;
+ return op == UNOP_LOWER ? low : high;
+ }
+ break;
+ case TYPE_CODE_UNDEF:
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_FUNC:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_SET:
+ case TYPE_CODE_ERROR:
+ case TYPE_CODE_MEMBER:
+ case TYPE_CODE_METHOD:
+ case TYPE_CODE_REF:
+ case TYPE_CODE_COMPLEX:
+ default:
+ break;
+ }
+ error ("unknown mode for LOWER/UPPER builtin");
+}
+
+static struct value *
+value_chill_length (struct value *val)
+{
+ LONGEST tmp;
+ struct type *type = VALUE_TYPE (val);
+ struct type *ttype;
+ CHECK_TYPEDEF (type);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_BITSTRING:
+ case TYPE_CODE_STRING:
+ tmp = type_lower_upper (UNOP_UPPER, type, &ttype)
+ - type_lower_upper (UNOP_LOWER, type, &ttype) + 1;
+ break;
+ case TYPE_CODE_STRUCT:
+ if (chill_varying_type (type))
+ {
+ tmp = unpack_long (TYPE_FIELD_TYPE (type, 0), VALUE_CONTENTS (val));
+ break;
+ }
+ /* ... else fall through ... */
+ default:
+ error ("bad argument to LENGTH builtin");
+ }
+ return value_from_longest (builtin_type_int, tmp);
+}
+
+static struct value *
+value_chill_card (struct value *val)
+{
+ LONGEST tmp = 0;
+ struct type *type = VALUE_TYPE (val);
+ CHECK_TYPEDEF (type);
+
+ if (TYPE_CODE (type) == TYPE_CODE_SET)
+ {
+ struct type *range_type = TYPE_INDEX_TYPE (type);
+ LONGEST lower_bound, upper_bound;
+ int i;
+
+ get_discrete_bounds (range_type, &lower_bound, &upper_bound);
+ for (i = lower_bound; i <= upper_bound; i++)
+ if (value_bit_index (type, VALUE_CONTENTS (val), i) > 0)
+ tmp++;
+ }
+ else
+ error ("bad argument to CARD builtin");
+
+ return value_from_longest (builtin_type_int, tmp);
+}
+
+static struct value *
+value_chill_max_min (enum exp_opcode op, struct value *val)
+{
+ LONGEST tmp = 0;
+ struct type *type = VALUE_TYPE (val);
+ struct type *elttype;
+ CHECK_TYPEDEF (type);
+
+ if (TYPE_CODE (type) == TYPE_CODE_SET)
+ {
+ LONGEST lower_bound, upper_bound;
+ int i, empty = 1;
+
+ elttype = TYPE_INDEX_TYPE (type);
+ CHECK_TYPEDEF (elttype);
+ get_discrete_bounds (elttype, &lower_bound, &upper_bound);
+
+ if (op == UNOP_CHMAX)
+ {
+ for (i = upper_bound; i >= lower_bound; i--)
+ {
+ if (value_bit_index (type, VALUE_CONTENTS (val), i) > 0)
+ {
+ tmp = i;
+ empty = 0;
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (i = lower_bound; i <= upper_bound; i++)
+ {
+ if (value_bit_index (type, VALUE_CONTENTS (val), i) > 0)
+ {
+ tmp = i;
+ empty = 0;
+ break;
+ }
+ }
+ }
+ if (empty)
+ error ("%s for empty powerset", op == UNOP_CHMAX ? "MAX" : "MIN");
+ }
+ else
+ error ("bad argument to %s builtin", op == UNOP_CHMAX ? "MAX" : "MIN");
+
+ return value_from_longest (TYPE_CODE (elttype) == TYPE_CODE_RANGE
+ ? TYPE_TARGET_TYPE (elttype)
+ : elttype,
+ tmp);
+}
+
+static struct value *
+evaluate_subexp_chill (struct type *expect_type,
+ register struct expression *exp, register int *pos,
+ enum noside noside)
+{
+ int pc = *pos;
+ struct type *type;
+ int tem, nargs;
+ struct value *arg1;
+ struct value **argvec;
+ enum exp_opcode op = exp->elts[*pos].opcode;
+ switch (op)
+ {
+ case MULTI_SUBSCRIPT:
+ if (noside == EVAL_SKIP)
+ break;
+ (*pos) += 3;
+ nargs = longest_to_int (exp->elts[pc + 1].longconst);
+ arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+ type = check_typedef (VALUE_TYPE (arg1));
+
+ if (nargs == 1 && TYPE_CODE (type) == TYPE_CODE_INT)
+ {
+ /* Looks like string repetition. */
+ struct value *string = evaluate_subexp_with_coercion (exp, pos,
+ noside);
+ return value_concat (arg1, string);
+ }
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_PTR:
+ type = check_typedef (TYPE_TARGET_TYPE (type));
+ if (!type || TYPE_CODE (type) != TYPE_CODE_FUNC)
+ error ("reference value used as function");
+ /* ... fall through ... */
+ case TYPE_CODE_FUNC:
+ /* It's a function call. */
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ break;
+
+ /* Allocate arg vector, including space for the function to be
+ called in argvec[0] and a terminating NULL */
+ argvec = (struct value **) alloca (sizeof (struct value *)
+ * (nargs + 2));
+ argvec[0] = arg1;
+ tem = 1;
+ for (; tem <= nargs && tem <= TYPE_NFIELDS (type); tem++)
+ {
+ argvec[tem]
+ = evaluate_subexp_chill (TYPE_FIELD_TYPE (type, tem - 1),
+ exp, pos, noside);
+ }
+ for (; tem <= nargs; tem++)
+ argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
+ argvec[tem] = 0; /* signal end of arglist */
+
+ return call_function_by_hand (argvec[0], nargs, argvec + 1);
+ default:
+ break;
+ }
+
+ while (nargs-- > 0)
+ {
+ struct value *index = evaluate_subexp_with_coercion (exp, pos,
+ noside);
+ arg1 = value_subscript (arg1, index);
+ }
+ return (arg1);
+
+ case UNOP_LOWER:
+ case UNOP_UPPER:
+ (*pos)++;
+ if (noside == EVAL_SKIP)
+ {
+ (*exp->language_defn->evaluate_exp) (NULL_TYPE, exp, pos, EVAL_SKIP);
+ goto nosideret;
+ }
+ arg1 = (*exp->language_defn->evaluate_exp) (NULL_TYPE, exp, pos,
+ EVAL_AVOID_SIDE_EFFECTS);
+ tem = type_lower_upper (op, VALUE_TYPE (arg1), &type);
+ return value_from_longest (type, tem);
+
+ case UNOP_LENGTH:
+ (*pos)++;
+ arg1 = (*exp->language_defn->evaluate_exp) (NULL_TYPE, exp, pos, noside);
+ return value_chill_length (arg1);
+
+ case UNOP_CARD:
+ (*pos)++;
+ arg1 = (*exp->language_defn->evaluate_exp) (NULL_TYPE, exp, pos, noside);
+ return value_chill_card (arg1);
+
+ case UNOP_CHMAX:
+ case UNOP_CHMIN:
+ (*pos)++;
+ arg1 = (*exp->language_defn->evaluate_exp) (NULL_TYPE, exp, pos, noside);
+ return value_chill_max_min (op, arg1);
+
+ case BINOP_COMMA:
+ error ("',' operator used in invalid context");
+
+ default:
+ break;
+ }
+
+ return evaluate_subexp_standard (expect_type, exp, pos, noside);
+nosideret:
+ return value_from_longest (builtin_type_long, (LONGEST) 1);
+}
+
+const struct language_defn chill_language_defn =
+{
+ "chill",
+ language_chill,
+ chill_builtin_types,
+ range_check_on,
+ type_check_on,
+ case_sensitive_on,
+ chill_parse, /* parser */
+ chill_error, /* parser error function */
+ evaluate_subexp_chill,
+ chill_printchar, /* print a character constant */
+ chill_printstr, /* function to print a string constant */
+ NULL, /* Function to print a single char */
+ chill_create_fundamental_type, /* Create fundamental type in this language */
+ chill_print_type, /* Print a type using appropriate syntax */
+ chill_val_print, /* Print a value using appropriate syntax */
+ chill_value_print, /* Print a top-levl value */
+ {"", "B'", "", ""}, /* Binary format info */
+ {"O'%lo", "O'", "o", ""}, /* Octal format info */
+ {"D'%ld", "D'", "d", ""}, /* Decimal format info */
+ {"H'%lx", "H'", "x", ""}, /* Hex format info */
+ chill_op_print_tab, /* expression operators for printing */
+ 0, /* arrays are first-class (not c-style) */
+ 0, /* String lower bound */
+ &builtin_type_chill_char, /* Type of string elements */
+ LANG_MAGIC
+};
+
+/* Initialization for Chill */
+
+void
+_initialize_chill_language (void)
+{
+ builtin_type_chill_bool =
+ init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "BOOL", (struct objfile *) NULL);
+ builtin_type_chill_char =
+ init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "CHAR", (struct objfile *) NULL);
+ builtin_type_chill_long =
+ init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ 0,
+ "LONG", (struct objfile *) NULL);
+ builtin_type_chill_ulong =
+ init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "ULONG", (struct objfile *) NULL);
+ builtin_type_chill_real =
+ init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0,
+ "LONG_REAL", (struct objfile *) NULL);
+
+ add_language (&chill_language_defn);
+}
diff --git a/gdb/ch-lang.h b/gdb/ch-lang.h
new file mode 100644
index 00000000000..b55e2dd075c
--- /dev/null
+++ b/gdb/ch-lang.h
@@ -0,0 +1,41 @@
+/* Chill language support definitions for GDB, the GNU debugger.
+ Copyright 1992, 1994, 1996, 1998, 1999, 2000
+ 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. */
+
+/* Forward decls for prototypes */
+struct value;
+
+extern int chill_parse (void); /* Defined in ch-exp.y */
+
+extern void chill_error (char *); /* Defined in ch-exp.y */
+
+/* Defined in ch-typeprint.c */
+extern void chill_print_type (struct type *, char *, struct ui_file *, int,
+ int);
+
+extern int chill_val_print (struct type *, char *, int, CORE_ADDR,
+ struct ui_file *, int, int, int,
+ enum val_prettyprint);
+
+extern int chill_value_print (struct value *, struct ui_file *,
+ int, enum val_prettyprint);
+
+extern LONGEST
+type_lower_upper (enum exp_opcode, struct type *, struct type **);
diff --git a/gdb/ch-typeprint.c b/gdb/ch-typeprint.c
new file mode 100644
index 00000000000..011bd125d2a
--- /dev/null
+++ b/gdb/ch-typeprint.c
@@ -0,0 +1,340 @@
+/* Support for printing Chill types for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 2000
+ 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 "defs.h"
+#include "obstack.h"
+#include "bfd.h" /* Binary File Description */
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "language.h"
+#include "ch-lang.h"
+#include "typeprint.h"
+
+#include "gdb_string.h"
+#include <errno.h>
+
+static void chill_type_print_base (struct type *, struct ui_file *, int, int);
+
+void
+chill_print_type (struct type *type, char *varstring, struct ui_file *stream,
+ int show, int level)
+{
+ if (varstring != NULL && *varstring != '\0')
+ {
+ fputs_filtered (varstring, stream);
+ fputs_filtered (" ", stream);
+ }
+ chill_type_print_base (type, stream, show, level);
+}
+
+/* Print the name of the type (or the ultimate pointer target,
+ function value or array element).
+
+ SHOW nonzero means don't print this type as just its name;
+ show its real definition even if it has a name.
+ SHOW zero means print just typename or tag if there is one
+ SHOW negative means abbreviate structure elements.
+ SHOW is decremented for printing of structure elements.
+
+ LEVEL is the depth to indent by.
+ We increase it for some recursive calls. */
+
+static void
+chill_type_print_base (struct type *type, struct ui_file *stream, int show,
+ int level)
+{
+ register int len;
+ register int i;
+ struct type *index_type;
+ struct type *range_type;
+ LONGEST low_bound;
+ LONGEST high_bound;
+
+ QUIT;
+
+ wrap_here (" ");
+ if (type == NULL)
+ {
+ fputs_filtered ("<type unknown>", stream);
+ return;
+ }
+
+ /* When SHOW is zero or less, and there is a valid type name, then always
+ just print the type name directly from the type. */
+
+ if ((show <= 0) && (TYPE_NAME (type) != NULL))
+ {
+ fputs_filtered (TYPE_NAME (type), stream);
+ return;
+ }
+
+ if (TYPE_CODE (type) != TYPE_CODE_TYPEDEF)
+ CHECK_TYPEDEF (type);
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_TYPEDEF:
+ chill_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level);
+ break;
+ case TYPE_CODE_PTR:
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID)
+ {
+ fprintf_filtered (stream,
+ TYPE_NAME (type) ? TYPE_NAME (type) : "PTR");
+ break;
+ }
+ fprintf_filtered (stream, "REF ");
+ chill_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level);
+ break;
+
+ case TYPE_CODE_BOOL:
+ /* FIXME: we should probably just print the TYPE_NAME, in case
+ anyone ever fixes the compiler to give us the real names
+ in the presence of the chill equivalent of typedef (assuming
+ there is one). */
+ fprintf_filtered (stream,
+ TYPE_NAME (type) ? TYPE_NAME (type) : "BOOL");
+ break;
+
+ case TYPE_CODE_ARRAY:
+ fputs_filtered ("ARRAY (", stream);
+ range_type = TYPE_FIELD_TYPE (type, 0);
+ if (TYPE_CODE (range_type) != TYPE_CODE_RANGE)
+ chill_print_type (range_type, "", stream, 0, level);
+ else
+ {
+ index_type = TYPE_TARGET_TYPE (range_type);
+ low_bound = TYPE_FIELD_BITPOS (range_type, 0);
+ high_bound = TYPE_FIELD_BITPOS (range_type, 1);
+ print_type_scalar (index_type, low_bound, stream);
+ fputs_filtered (":", stream);
+ print_type_scalar (index_type, high_bound, stream);
+ }
+ fputs_filtered (") ", stream);
+ chill_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, level);
+ break;
+
+ case TYPE_CODE_BITSTRING:
+ fprintf_filtered (stream, "BOOLS (%d)",
+ TYPE_FIELD_BITPOS (TYPE_FIELD_TYPE (type, 0), 1) + 1);
+ break;
+
+ case TYPE_CODE_SET:
+ fputs_filtered ("POWERSET ", stream);
+ chill_print_type (TYPE_INDEX_TYPE (type), "", stream,
+ show - 1, level);
+ break;
+
+ case TYPE_CODE_STRING:
+ range_type = TYPE_FIELD_TYPE (type, 0);
+ index_type = TYPE_TARGET_TYPE (range_type);
+ high_bound = TYPE_FIELD_BITPOS (range_type, 1);
+ fputs_filtered ("CHARS (", stream);
+ print_type_scalar (index_type, high_bound + 1, stream);
+ fputs_filtered (")", stream);
+ break;
+
+ case TYPE_CODE_MEMBER:
+ fprintf_filtered (stream, "MEMBER ");
+ chill_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level);
+ break;
+ case TYPE_CODE_REF:
+ fprintf_filtered (stream, "/*LOC*/ ");
+ chill_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
+ break;
+ case TYPE_CODE_FUNC:
+ fprintf_filtered (stream, "PROC (");
+ len = TYPE_NFIELDS (type);
+ for (i = 0; i < len; i++)
+ {
+ struct type *param_type = TYPE_FIELD_TYPE (type, i);
+ if (i > 0)
+ {
+ fputs_filtered (", ", stream);
+ wrap_here (" ");
+ }
+ if (TYPE_CODE (param_type) == TYPE_CODE_REF)
+ {
+ chill_type_print_base (TYPE_TARGET_TYPE (param_type),
+ stream, 0, level);
+ fputs_filtered (" LOC", stream);
+ }
+ else
+ chill_type_print_base (param_type, stream, show, level);
+ }
+ fprintf_filtered (stream, ")");
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+ {
+ fputs_filtered (" RETURNS (", stream);
+ chill_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level);
+ fputs_filtered (")", stream);
+ }
+ break;
+
+ case TYPE_CODE_STRUCT:
+ if (chill_varying_type (type))
+ {
+ chill_type_print_base (TYPE_FIELD_TYPE (type, 1),
+ stream, 0, level);
+ fputs_filtered (" VARYING", stream);
+ }
+ else
+ {
+ fprintf_filtered (stream, "STRUCT ");
+
+ fprintf_filtered (stream, "(\n");
+ if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
+ {
+ if (TYPE_STUB (type))
+ {
+ fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
+ }
+ else
+ {
+ fprintfi_filtered (level + 4, stream, "<no data fields>\n");
+ }
+ }
+ else
+ {
+ len = TYPE_NFIELDS (type);
+ for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+ {
+ struct type *field_type = TYPE_FIELD_TYPE (type, i);
+ QUIT;
+ print_spaces_filtered (level + 4, stream);
+ if (TYPE_CODE (field_type) == TYPE_CODE_UNION)
+ {
+ int j; /* variant number */
+ fputs_filtered ("CASE OF\n", stream);
+ for (j = 0; j < TYPE_NFIELDS (field_type); j++)
+ {
+ int k; /* variant field index */
+ struct type *variant_type
+ = TYPE_FIELD_TYPE (field_type, j);
+ int var_len = TYPE_NFIELDS (variant_type);
+ print_spaces_filtered (level + 4, stream);
+ if (strcmp (TYPE_FIELD_NAME (field_type, j),
+ "else") == 0)
+ fputs_filtered ("ELSE\n", stream);
+ else
+ fputs_filtered (":\n", stream);
+ if (TYPE_CODE (variant_type) != TYPE_CODE_STRUCT)
+ error ("variant record confusion");
+ for (k = 0; k < var_len; k++)
+ {
+ print_spaces_filtered (level + 8, stream);
+ chill_print_type (TYPE_FIELD_TYPE (variant_type, k),
+ TYPE_FIELD_NAME (variant_type, k),
+ stream, show - 1, level + 8);
+ if (k < (var_len - 1))
+ fputs_filtered (",", stream);
+ fputs_filtered ("\n", stream);
+ }
+ }
+ print_spaces_filtered (level + 4, stream);
+ fputs_filtered ("ESAC", stream);
+ }
+ else
+ chill_print_type (field_type,
+ TYPE_FIELD_NAME (type, i),
+ stream, show - 1, level + 4);
+ if (i < (len - 1))
+ {
+ fputs_filtered (",", stream);
+ }
+ fputs_filtered ("\n", stream);
+ }
+ }
+ fprintfi_filtered (level, stream, ")");
+ }
+ break;
+
+ case TYPE_CODE_RANGE:
+ {
+ struct type *target = TYPE_TARGET_TYPE (type);
+ if (target && TYPE_NAME (target))
+ fputs_filtered (TYPE_NAME (target), stream);
+ else
+ fputs_filtered ("RANGE", stream);
+ if (target == NULL)
+ target = builtin_type_long;
+ fputs_filtered (" (", stream);
+ print_type_scalar (target, TYPE_LOW_BOUND (type), stream);
+ fputs_filtered (":", stream);
+ print_type_scalar (target, TYPE_HIGH_BOUND (type), stream);
+ fputs_filtered (")", stream);
+ }
+ break;
+
+ case TYPE_CODE_ENUM:
+ {
+ register int lastval = 0;
+ fprintf_filtered (stream, "SET (");
+ len = TYPE_NFIELDS (type);
+ for (i = 0; i < len; i++)
+ {
+ QUIT;
+ if (i)
+ fprintf_filtered (stream, ", ");
+ wrap_here (" ");
+ fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+ if (lastval != TYPE_FIELD_BITPOS (type, i))
+ {
+ fprintf_filtered (stream, " = %d", TYPE_FIELD_BITPOS (type, i));
+ lastval = TYPE_FIELD_BITPOS (type, i);
+ }
+ lastval++;
+ }
+ fprintf_filtered (stream, ")");
+ }
+ break;
+
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_UNDEF:
+ case TYPE_CODE_ERROR:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_METHOD:
+ error ("missing language support in chill_type_print_base");
+ break;
+
+ default:
+
+ /* Handle types not explicitly handled by the other cases,
+ such as fundamental types. For these, just print whatever
+ the type name is, as recorded in the type itself. If there
+ is no type name, then complain. */
+
+ if (TYPE_NAME (type) != NULL)
+ {
+ fputs_filtered (TYPE_NAME (type), stream);
+ }
+ else
+ {
+ error ("Unrecognized type code (%d) in symbol table.",
+ TYPE_CODE (type));
+ }
+ break;
+ }
+}
diff --git a/gdb/ch-valprint.c b/gdb/ch-valprint.c
new file mode 100644
index 00000000000..44b1c534311
--- /dev/null
+++ b/gdb/ch-valprint.c
@@ -0,0 +1,605 @@
+/* Support for printing Chill values for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 2000, 2001
+ 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 "defs.h"
+#include "obstack.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "valprint.h"
+#include "expression.h"
+#include "value.h"
+#include "language.h"
+#include "demangle.h"
+#include "c-lang.h" /* For c_val_print */
+#include "typeprint.h"
+#include "ch-lang.h"
+#include "annotate.h"
+
+static void chill_print_value_fields (struct type *, char *,
+ struct ui_file *, int, int,
+ enum val_prettyprint, struct type **);
+
+static void chill_print_type_scalar (struct type *, LONGEST,
+ struct ui_file *);
+
+static void chill_val_print_array_elements (struct type *, char *,
+ CORE_ADDR, struct ui_file *,
+ int, int, int,
+ enum val_prettyprint);
+
+
+/* Print integral scalar data VAL, of type TYPE, onto stdio stream STREAM.
+ Used to print data from type structures in a specified type. For example,
+ array bounds may be characters or booleans in some languages, and this
+ allows the ranges to be printed in their "natural" form rather than as
+ decimal integer values. */
+
+static void
+chill_print_type_scalar (struct type *type, LONGEST val, struct ui_file *stream)
+{
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_RANGE:
+ if (TYPE_TARGET_TYPE (type))
+ {
+ chill_print_type_scalar (TYPE_TARGET_TYPE (type), val, stream);
+ return;
+ }
+ break;
+ case TYPE_CODE_UNDEF:
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_FUNC:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_SET:
+ case TYPE_CODE_STRING:
+ case TYPE_CODE_BITSTRING:
+ case TYPE_CODE_ERROR:
+ case TYPE_CODE_MEMBER:
+ case TYPE_CODE_METHOD:
+ case TYPE_CODE_REF:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_COMPLEX:
+ case TYPE_CODE_TYPEDEF:
+ default:
+ break;
+ }
+ print_type_scalar (type, val, stream);
+}
+
+/* Print the elements of an array.
+ Similar to val_print_array_elements, but prints
+ element indexes (in Chill syntax). */
+
+static void
+chill_val_print_array_elements (struct type *type, char *valaddr,
+ CORE_ADDR address, struct ui_file *stream,
+ int format, int deref_ref, int recurse,
+ enum val_prettyprint pretty)
+{
+ unsigned int i = 0;
+ unsigned int things_printed = 0;
+ unsigned len;
+ struct type *elttype;
+ struct type *range_type = TYPE_FIELD_TYPE (type, 0);
+ struct type *index_type = TYPE_TARGET_TYPE (range_type);
+ unsigned eltlen;
+ /* Position of the array element we are examining to see
+ whether it is repeated. */
+ unsigned int rep1;
+ /* Number of repetitions we have detected so far. */
+ unsigned int reps;
+ LONGEST low_bound = TYPE_FIELD_BITPOS (range_type, 0);
+
+ elttype = check_typedef (TYPE_TARGET_TYPE (type));
+ eltlen = TYPE_LENGTH (elttype);
+ len = TYPE_LENGTH (type) / eltlen;
+
+ annotate_array_section_begin (i, elttype);
+
+ for (; i < len && things_printed < print_max; i++)
+ {
+ if (i != 0)
+ {
+ if (prettyprint_arrays)
+ {
+ fprintf_filtered (stream, ",\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ else
+ {
+ fprintf_filtered (stream, ", ");
+ }
+ }
+ wrap_here (n_spaces (2 + 2 * recurse));
+
+ rep1 = i + 1;
+ reps = 1;
+ while ((rep1 < len) &&
+ !memcmp (valaddr + i * eltlen, valaddr + rep1 * eltlen, eltlen))
+ {
+ ++reps;
+ ++rep1;
+ }
+
+ fputs_filtered ("(", stream);
+ chill_print_type_scalar (index_type, low_bound + i, stream);
+ if (reps > 1)
+ {
+ fputs_filtered (":", stream);
+ chill_print_type_scalar (index_type, low_bound + i + reps - 1,
+ stream);
+ fputs_filtered ("): ", stream);
+ val_print (elttype, valaddr + i * eltlen, 0, 0, stream, format,
+ deref_ref, recurse + 1, pretty);
+
+ i = rep1 - 1;
+ things_printed += 1;
+ }
+ else
+ {
+ fputs_filtered ("): ", stream);
+ val_print (elttype, valaddr + i * eltlen, 0, 0, stream, format,
+ deref_ref, recurse + 1, pretty);
+ annotate_elt ();
+ things_printed++;
+ }
+ }
+ annotate_array_section_end ();
+ if (i < len)
+ {
+ fprintf_filtered (stream, "...");
+ }
+}
+
+/* Print data of type TYPE located at VALADDR (within GDB), which came from
+ the inferior at address ADDRESS, onto stdio stream STREAM according to
+ FORMAT (a letter or 0 for natural format). The data at VALADDR is in
+ target byte order.
+
+ If the data are a string pointer, returns the number of string characters
+ printed.
+
+ If DEREF_REF is nonzero, then dereference references, otherwise just print
+ them like pointers.
+
+ The PRETTY parameter controls prettyprinting. */
+
+int
+chill_val_print (struct type *type, char *valaddr, int embedded_offset,
+ CORE_ADDR address, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
+{
+ LONGEST val;
+ unsigned int i = 0; /* Number of characters printed. */
+ struct type *elttype;
+ CORE_ADDR addr;
+
+ CHECK_TYPEDEF (type);
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
+ {
+ if (prettyprint_arrays)
+ {
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ fprintf_filtered (stream, "[");
+ chill_val_print_array_elements (type, valaddr, address, stream,
+ format, deref_ref, recurse, pretty);
+ fprintf_filtered (stream, "]");
+ }
+ else
+ {
+ error ("unimplemented in chill_val_print; unspecified array length");
+ }
+ break;
+
+ case TYPE_CODE_INT:
+ format = format ? format : output_format;
+ if (format)
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ }
+ else
+ {
+ val_print_type_code_int (type, valaddr, stream);
+ }
+ break;
+
+ case TYPE_CODE_CHAR:
+ format = format ? format : output_format;
+ if (format)
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ }
+ else
+ {
+ LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr),
+ stream);
+ }
+ break;
+
+ case TYPE_CODE_FLT:
+ if (format)
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ }
+ else
+ {
+ print_floating (valaddr, type, stream);
+ }
+ break;
+
+ case TYPE_CODE_BOOL:
+ format = format ? format : output_format;
+ if (format)
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ }
+ else
+ {
+ /* FIXME: Why is this using builtin_type_chill_bool not type? */
+ val = unpack_long (builtin_type_chill_bool, valaddr);
+ fprintf_filtered (stream, val ? "TRUE" : "FALSE");
+ }
+ break;
+
+ case TYPE_CODE_UNDEF:
+ /* This happens (without TYPE_FLAG_STUB set) on systems which don't use
+ dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
+ and no complete type for struct foo in that file. */
+ fprintf_filtered (stream, "<incomplete type>");
+ break;
+
+ case TYPE_CODE_PTR:
+ if (format && format != 's')
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ break;
+ }
+ addr = unpack_pointer (type, valaddr);
+ elttype = check_typedef (TYPE_TARGET_TYPE (type));
+
+ /* We assume a NULL pointer is all zeros ... */
+ if (addr == 0)
+ {
+ fputs_filtered ("NULL", stream);
+ return 0;
+ }
+
+ if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
+ {
+ /* Try to print what function it points to. */
+ print_address_demangle (addr, stream, demangle);
+ /* Return value is irrelevant except for string pointers. */
+ return (0);
+ }
+ if (addressprint && format != 's')
+ {
+ print_address_numeric (addr, 1, stream);
+ }
+
+ /* For a pointer to char or unsigned char, also print the string
+ pointed to, unless pointer is null. */
+ if (TYPE_LENGTH (elttype) == 1
+ && TYPE_CODE (elttype) == TYPE_CODE_CHAR
+ && (format == 0 || format == 's')
+ && addr != 0
+ && /* If print_max is UINT_MAX, the alloca below will fail.
+ In that case don't try to print the string. */
+ print_max < UINT_MAX)
+ i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream);
+
+ /* Return number of characters printed, plus one for the
+ terminating null if we have "reached the end". */
+ return (i + (print_max && i != print_max));
+ break;
+
+ case TYPE_CODE_STRING:
+ i = TYPE_LENGTH (type);
+ LA_PRINT_STRING (stream, valaddr, i, 1, 0);
+ /* Return number of characters printed, plus one for the terminating
+ null if we have "reached the end". */
+ return (i + (print_max && i != print_max));
+ break;
+
+ case TYPE_CODE_BITSTRING:
+ case TYPE_CODE_SET:
+ elttype = TYPE_INDEX_TYPE (type);
+ CHECK_TYPEDEF (elttype);
+ if (TYPE_STUB (elttype))
+ {
+ fprintf_filtered (stream, "<incomplete type>");
+ gdb_flush (stream);
+ break;
+ }
+ {
+ struct type *range = elttype;
+ LONGEST low_bound, high_bound;
+ int i;
+ int is_bitstring = TYPE_CODE (type) == TYPE_CODE_BITSTRING;
+ int need_comma = 0;
+
+ if (is_bitstring)
+ fputs_filtered ("B'", stream);
+ else
+ fputs_filtered ("[", stream);
+
+ i = get_discrete_bounds (range, &low_bound, &high_bound);
+ maybe_bad_bstring:
+ if (i < 0)
+ {
+ fputs_filtered ("<error value>", stream);
+ goto done;
+ }
+
+ for (i = low_bound; i <= high_bound; i++)
+ {
+ int element = value_bit_index (type, valaddr, i);
+ if (element < 0)
+ {
+ i = element;
+ goto maybe_bad_bstring;
+ }
+ if (is_bitstring)
+ fprintf_filtered (stream, "%d", element);
+ else if (element)
+ {
+ if (need_comma)
+ fputs_filtered (", ", stream);
+ chill_print_type_scalar (range, (LONGEST) i, stream);
+ need_comma = 1;
+
+ /* Look for a continuous range of true elements. */
+ if (i + 1 <= high_bound && value_bit_index (type, valaddr, ++i))
+ {
+ int j = i; /* j is the upper bound so far of the range */
+ fputs_filtered (":", stream);
+ while (i + 1 <= high_bound
+ && value_bit_index (type, valaddr, ++i))
+ j = i;
+ chill_print_type_scalar (range, (LONGEST) j, stream);
+ }
+ }
+ }
+ done:
+ if (is_bitstring)
+ fputs_filtered ("'", stream);
+ else
+ fputs_filtered ("]", stream);
+ }
+ break;
+
+ case TYPE_CODE_STRUCT:
+ if (chill_varying_type (type))
+ {
+ struct type *inner = check_typedef (TYPE_FIELD_TYPE (type, 1));
+ long length = unpack_long (TYPE_FIELD_TYPE (type, 0), valaddr);
+ char *data_addr = valaddr + TYPE_FIELD_BITPOS (type, 1) / 8;
+
+ switch (TYPE_CODE (inner))
+ {
+ case TYPE_CODE_STRING:
+ if (length > TYPE_LENGTH (type) - 2)
+ {
+ fprintf_filtered (stream,
+ "<dynamic length %ld > static length %d> *invalid*",
+ length, TYPE_LENGTH (type));
+
+ /* Don't print the string; doing so might produce a
+ segfault. */
+ return length;
+ }
+ LA_PRINT_STRING (stream, data_addr, length, 1, 0);
+ return length;
+ default:
+ break;
+ }
+ }
+ chill_print_value_fields (type, valaddr, stream, format, recurse, pretty,
+ 0);
+ break;
+
+ case TYPE_CODE_REF:
+ if (addressprint)
+ {
+ fprintf_filtered (stream, "LOC(");
+ print_address_numeric
+ (extract_address (valaddr, TARGET_PTR_BIT / HOST_CHAR_BIT),
+ 1,
+ stream);
+ fprintf_filtered (stream, ")");
+ if (deref_ref)
+ fputs_filtered (": ", stream);
+ }
+ /* De-reference the reference. */
+ if (deref_ref)
+ {
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_UNDEF)
+ {
+ struct value *deref_val =
+ value_at
+ (TYPE_TARGET_TYPE (type),
+ unpack_pointer (lookup_pointer_type (builtin_type_void),
+ valaddr),
+ NULL);
+ val_print (VALUE_TYPE (deref_val),
+ VALUE_CONTENTS (deref_val),
+ 0,
+ VALUE_ADDRESS (deref_val), stream, format,
+ deref_ref, recurse + 1, pretty);
+ }
+ else
+ fputs_filtered ("???", stream);
+ }
+ break;
+
+ case TYPE_CODE_ENUM:
+ c_val_print (type, valaddr, 0, address, stream, format,
+ deref_ref, recurse, pretty);
+ break;
+
+ case TYPE_CODE_RANGE:
+ if (TYPE_TARGET_TYPE (type))
+ chill_val_print (TYPE_TARGET_TYPE (type), valaddr, 0, address, stream,
+ format, deref_ref, recurse, pretty);
+ break;
+
+ case TYPE_CODE_MEMBER:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_FUNC:
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_ERROR:
+ default:
+ /* Let's defer printing to the C printer, rather than
+ print an error message. FIXME! */
+ c_val_print (type, valaddr, 0, address, stream, format,
+ deref_ref, recurse, pretty);
+ }
+ gdb_flush (stream);
+ return (0);
+}
+
+/* Mutually recursive subroutines of cplus_print_value and c_val_print to
+ print out a structure's fields: cp_print_value_fields and cplus_print_value.
+
+ TYPE, VALADDR, STREAM, RECURSE, and PRETTY have the
+ same meanings as in cplus_print_value and c_val_print.
+
+ DONT_PRINT is an array of baseclass types that we
+ should not print, or zero if called from top level. */
+
+static void
+chill_print_value_fields (struct type *type, char *valaddr,
+ struct ui_file *stream, int format, int recurse,
+ enum val_prettyprint pretty, struct type **dont_print)
+{
+ int i, len;
+ int fields_seen = 0;
+
+ CHECK_TYPEDEF (type);
+
+ fprintf_filtered (stream, "[");
+ len = TYPE_NFIELDS (type);
+ if (len == 0)
+ {
+ fprintf_filtered (stream, "<No data fields>");
+ }
+ else
+ {
+ for (i = 0; i < len; i++)
+ {
+ if (fields_seen)
+ {
+ fprintf_filtered (stream, ", ");
+ }
+ fields_seen = 1;
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ else
+ {
+ wrap_here (n_spaces (2 + 2 * recurse));
+ }
+ fputs_filtered (".", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_chill, DMGL_NO_OPTS);
+ fputs_filtered (": ", stream);
+ if (TYPE_FIELD_PACKED (type, i))
+ {
+ struct value *v;
+
+ /* Bitfields require special handling, especially due to byte
+ order problems. */
+ v = value_from_longest (TYPE_FIELD_TYPE (type, i),
+ unpack_field_as_long (type, valaddr, i));
+
+ chill_val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0, 0,
+ stream, format, 0, recurse + 1, pretty);
+ }
+ else
+ {
+ chill_val_print (TYPE_FIELD_TYPE (type, i),
+ valaddr + TYPE_FIELD_BITPOS (type, i) / 8, 0,
+ 0, stream, format, 0, recurse + 1, pretty);
+ }
+ }
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 * recurse, stream);
+ }
+ }
+ fprintf_filtered (stream, "]");
+}
+
+int
+chill_value_print (struct value *val, struct ui_file *stream, int format,
+ enum val_prettyprint pretty)
+{
+ struct type *type = VALUE_TYPE (val);
+ struct type *real_type = check_typedef (type);
+
+ /* If it is a pointer, indicate what it points to.
+
+ Print type also if it is a reference. */
+
+ if (TYPE_CODE (real_type) == TYPE_CODE_PTR ||
+ TYPE_CODE (real_type) == TYPE_CODE_REF)
+ {
+ char *valaddr = VALUE_CONTENTS (val);
+ CORE_ADDR addr = unpack_pointer (type, valaddr);
+ if (TYPE_CODE (type) != TYPE_CODE_PTR || addr != 0)
+ {
+ int i;
+ char *name = TYPE_NAME (type);
+ if (name)
+ fputs_filtered (name, stream);
+ else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID)
+ fputs_filtered ("PTR", stream);
+ else
+ {
+ fprintf_filtered (stream, "(");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, ")");
+ }
+ fprintf_filtered (stream, "(");
+ i = val_print (type, valaddr, 0, VALUE_ADDRESS (val),
+ stream, format, 1, 0, pretty);
+ fprintf_filtered (stream, ")");
+ return i;
+ }
+ }
+ return (val_print (type, VALUE_CONTENTS (val), 0,
+ VALUE_ADDRESS (val), stream, format, 1, 0, pretty));
+}
diff --git a/gdb/cli-out.c b/gdb/cli-out.c
new file mode 100644
index 00000000000..bd079f250bb
--- /dev/null
+++ b/gdb/cli-out.c
@@ -0,0 +1,373 @@
+/* Output generating routines for GDB CLI.
+
+ Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Solutions.
+ Written by Fernando Nasser for Cygnus.
+
+ 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 "defs.h"
+#include "ui-out.h"
+#include "cli-out.h"
+#include "gdb_string.h"
+#include "gdb_assert.h"
+
+struct ui_out_data
+ {
+ struct ui_file *stream;
+ int suppress_output;
+ };
+
+/* These are the CLI output functions */
+
+static void cli_table_begin (struct ui_out *uiout, int nbrofcols,
+ int nr_rows, const char *tblid);
+static void cli_table_body (struct ui_out *uiout);
+static void cli_table_end (struct ui_out *uiout);
+static void cli_table_header (struct ui_out *uiout, int width,
+ enum ui_align alig, const char *col_name,
+ const char *colhdr);
+static void cli_begin (struct ui_out *uiout, enum ui_out_type type,
+ int level, const char *lstid);
+static void cli_end (struct ui_out *uiout, enum ui_out_type type, int level);
+static void cli_field_int (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alig, const char *fldname, int value);
+static void cli_field_skip (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alig, const char *fldname);
+static void cli_field_string (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alig, const char *fldname,
+ const char *string);
+static void cli_field_fmt (struct ui_out *uiout, int fldno,
+ int width, enum ui_align align,
+ const char *fldname, const char *format,
+ va_list args);
+static void cli_spaces (struct ui_out *uiout, int numspaces);
+static void cli_text (struct ui_out *uiout, const char *string);
+static void cli_message (struct ui_out *uiout, int verbosity,
+ const char *format, va_list args);
+static void cli_wrap_hint (struct ui_out *uiout, char *identstring);
+static void cli_flush (struct ui_out *uiout);
+
+/* This is the CLI ui-out implementation functions vector */
+
+/* FIXME: This can be initialized dynamically after default is set to
+ handle initial output in main.c */
+
+static struct ui_out_impl cli_ui_out_impl =
+{
+ cli_table_begin,
+ cli_table_body,
+ cli_table_end,
+ cli_table_header,
+ cli_begin,
+ cli_end,
+ cli_field_int,
+ cli_field_skip,
+ cli_field_string,
+ cli_field_fmt,
+ cli_spaces,
+ cli_text,
+ cli_message,
+ cli_wrap_hint,
+ cli_flush,
+ 0, /* Does not need MI hacks (i.e. needs CLI hacks). */
+};
+
+/* Prototypes for local functions */
+
+extern void _initialize_cli_out (void);
+
+static void field_separator (void);
+
+static void out_field_fmt (struct ui_out *uiout, int fldno,
+ const char *fldname,
+ const char *format,...);
+
+/* local variables */
+
+/* (none yet) */
+
+/* Mark beginning of a table */
+
+void
+cli_table_begin (struct ui_out *uiout, int nbrofcols,
+ int nr_rows,
+ const char *tblid)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (nr_rows == 0)
+ data->suppress_output = 1;
+ else
+ /* Only the table suppresses the output and, fortunatly, a table
+ is not a recursive data structure. */
+ gdb_assert (data->suppress_output == 0);
+}
+
+/* Mark beginning of a table body */
+
+void
+cli_table_body (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ /* first, close the table header line */
+ cli_text (uiout, "\n");
+}
+
+/* Mark end of a table */
+
+void
+cli_table_end (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ data->suppress_output = 0;
+}
+
+/* Specify table header */
+
+void
+cli_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
+ const char *col_name,
+ const char *colhdr)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ cli_field_string (uiout, 0, width, alignment, 0, colhdr);
+}
+
+/* Mark beginning of a list */
+
+void
+cli_begin (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level,
+ const char *id)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+}
+
+/* Mark end of a list */
+
+void
+cli_end (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+}
+
+/* output an int field */
+
+void
+cli_field_int (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alignment,
+ const char *fldname, int value)
+{
+ char buffer[20]; /* FIXME: how many chars long a %d can become? */
+
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ sprintf (buffer, "%d", value);
+ cli_field_string (uiout, fldno, width, alignment, fldname, buffer);
+}
+
+/* used to ommit a field */
+
+void
+cli_field_skip (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alignment,
+ const char *fldname)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ cli_field_string (uiout, fldno, width, alignment, fldname, "");
+}
+
+/* other specific cli_field_* end up here so alignment and field
+ separators are both handled by cli_field_string */
+
+void
+cli_field_string (struct ui_out *uiout,
+ int fldno,
+ int width,
+ enum ui_align align,
+ const char *fldname,
+ const char *string)
+{
+ int before = 0;
+ int after = 0;
+
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+
+ if ((align != ui_noalign) && string)
+ {
+ before = width - strlen (string);
+ if (before <= 0)
+ before = 0;
+ else
+ {
+ if (align == ui_right)
+ after = 0;
+ else if (align == ui_left)
+ {
+ after = before;
+ before = 0;
+ }
+ else
+ /* ui_center */
+ {
+ after = before / 2;
+ before -= after;
+ }
+ }
+ }
+
+ if (before)
+ ui_out_spaces (uiout, before);
+ if (string)
+ out_field_fmt (uiout, fldno, fldname, "%s", string);
+ if (after)
+ ui_out_spaces (uiout, after);
+
+ if (align != ui_noalign)
+ field_separator ();
+}
+
+/* This is the only field function that does not align */
+
+void
+cli_field_fmt (struct ui_out *uiout, int fldno,
+ int width, enum ui_align align,
+ const char *fldname,
+ const char *format,
+ va_list args)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+
+ vfprintf_filtered (data->stream, format, args);
+
+ if (align != ui_noalign)
+ field_separator ();
+}
+
+void
+cli_spaces (struct ui_out *uiout, int numspaces)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ print_spaces_filtered (numspaces, data->stream);
+}
+
+void
+cli_text (struct ui_out *uiout, const char *string)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ fputs_filtered (string, data->stream);
+}
+
+void
+cli_message (struct ui_out *uiout, int verbosity,
+ const char *format, va_list args)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ if (ui_out_get_verblvl (uiout) >= verbosity)
+ vfprintf_unfiltered (data->stream, format, args);
+}
+
+void
+cli_wrap_hint (struct ui_out *uiout, char *identstring)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ wrap_here (identstring);
+}
+
+void
+cli_flush (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ gdb_flush (data->stream);
+}
+
+/* local functions */
+
+/* Like cli_field_fmt, but takes a variable number of args
+ and makes a va_list and does not insert a separator */
+
+/* VARARGS */
+static void
+out_field_fmt (struct ui_out *uiout, int fldno,
+ const char *fldname,
+ const char *format,...)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ va_list args;
+
+ va_start (args, format);
+ vfprintf_filtered (data->stream, format, args);
+
+ va_end (args);
+}
+
+/* access to ui_out format private members */
+
+static void
+field_separator (void)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ fputc_filtered (' ', data->stream);
+}
+
+/* initalize private members at startup */
+
+struct ui_out *
+cli_out_new (struct ui_file *stream)
+{
+ int flags = ui_source_list;
+
+ struct ui_out_data *data = XMALLOC (struct ui_out_data);
+ data->stream = stream;
+ data->suppress_output = 0;
+ return ui_out_new (&cli_ui_out_impl, data, flags);
+}
+
+/* standard gdb initialization hook */
+void
+_initialize_cli_out (void)
+{
+ /* nothing needs to be done */
+}
diff --git a/gdb/cli-out.h b/gdb/cli-out.h
new file mode 100644
index 00000000000..723b7260cbf
--- /dev/null
+++ b/gdb/cli-out.h
@@ -0,0 +1,27 @@
+/* Output generating routines for GDB CLI.
+ Copyright 1999, 2000 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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. */
+
+#ifndef CLI_OUT_H
+#define CLI_OUT_H
+
+extern struct ui_out *cli_out_new (struct ui_file *stream);
+
+#endif
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
new file mode 100644
index 00000000000..bcd9a42e1b5
--- /dev/null
+++ b/gdb/cli/cli-cmds.c
@@ -0,0 +1,838 @@
+/* GDB CLI commands.
+
+ Copyright 2000, 2001, 2002 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 "defs.h"
+#include "completer.h"
+#include "target.h" /* For baud_rate, remote_debug and remote_timeout */
+#include "gdb_wait.h" /* For shell escape implementation */
+#include "gdb_regex.h" /* Used by apropos_command */
+#include "filenames.h" /* for DOSish file names */
+
+#include "ui-out.h"
+
+#include "top.h"
+#include "cli/cli-decode.h"
+#include "cli/cli-script.h"
+#include "cli/cli-setshow.h"
+#include "cli/cli-cmds.h"
+
+#ifndef GDBINIT_FILENAME
+#define GDBINIT_FILENAME ".gdbinit"
+#endif
+
+/* From gdb/top.c */
+
+extern void dont_repeat (void);
+
+extern void set_verbose (char *, int, struct cmd_list_element *);
+
+extern void show_history (char *, int);
+
+extern void set_history (char *, int);
+
+extern void show_commands (char *, int);
+
+/* Prototypes for local functions */
+
+static void complete_command (char *, int);
+
+static void echo_command (char *, int);
+
+static void pwd_command (char *, int);
+
+static void show_version (char *, int);
+
+static void validate_comname (char *);
+
+static void help_command (char *, int);
+
+static void show_command (char *, int);
+
+static void info_command (char *, int);
+
+static void show_debug (char *, int);
+
+static void set_debug (char *, int);
+
+static void show_user (char *, int);
+
+static void make_command (char *, int);
+
+static void shell_escape (char *, int);
+
+void apropos_command (char *, int);
+
+/* Limit the call depth of user-defined commands */
+int max_user_call_depth;
+
+/* Define all cmd_list_elements. */
+
+/* Chain containing all defined commands. */
+
+struct cmd_list_element *cmdlist;
+
+/* Chain containing all defined info subcommands. */
+
+struct cmd_list_element *infolist;
+
+/* Chain containing all defined enable subcommands. */
+
+struct cmd_list_element *enablelist;
+
+/* Chain containing all defined disable subcommands. */
+
+struct cmd_list_element *disablelist;
+
+/* Chain containing all defined toggle subcommands. */
+
+struct cmd_list_element *togglelist;
+
+/* Chain containing all defined stop subcommands. */
+
+struct cmd_list_element *stoplist;
+
+/* Chain containing all defined delete subcommands. */
+
+struct cmd_list_element *deletelist;
+
+/* Chain containing all defined "enable breakpoint" subcommands. */
+
+struct cmd_list_element *enablebreaklist;
+
+/* Chain containing all defined set subcommands */
+
+struct cmd_list_element *setlist;
+
+/* Chain containing all defined unset subcommands */
+
+struct cmd_list_element *unsetlist;
+
+/* Chain containing all defined show subcommands. */
+
+struct cmd_list_element *showlist;
+
+/* Chain containing all defined \"set history\". */
+
+struct cmd_list_element *sethistlist;
+
+/* Chain containing all defined \"show history\". */
+
+struct cmd_list_element *showhistlist;
+
+/* Chain containing all defined \"unset history\". */
+
+struct cmd_list_element *unsethistlist;
+
+/* Chain containing all defined maintenance subcommands. */
+
+struct cmd_list_element *maintenancelist;
+
+/* Chain containing all defined "maintenance info" subcommands. */
+
+struct cmd_list_element *maintenanceinfolist;
+
+/* Chain containing all defined "maintenance print" subcommands. */
+
+struct cmd_list_element *maintenanceprintlist;
+
+struct cmd_list_element *setprintlist;
+
+struct cmd_list_element *showprintlist;
+
+struct cmd_list_element *setdebuglist;
+
+struct cmd_list_element *showdebuglist;
+
+struct cmd_list_element *setchecklist;
+
+struct cmd_list_element *showchecklist;
+
+/* Utility used everywhere when at least one argument is needed and
+ none is supplied. */
+
+void
+error_no_arg (char *why)
+{
+ error ("Argument required (%s).", why);
+}
+
+/* The "info" command is defined as a prefix, with allow_unknown = 0.
+ Therefore, its own definition is called only for "info" with no args. */
+
+/* ARGSUSED */
+static void
+info_command (char *arg, int from_tty)
+{
+ printf_unfiltered ("\"info\" must be followed by the name of an info command.\n");
+ help_list (infolist, "info ", -1, gdb_stdout);
+}
+
+/* The "show" command with no arguments shows all the settings. */
+
+/* ARGSUSED */
+static void
+show_command (char *arg, int from_tty)
+{
+ cmd_show_list (showlist, from_tty, "");
+}
+
+/* Provide documentation on command or list given by COMMAND. FROM_TTY
+ is ignored. */
+
+/* ARGSUSED */
+static void
+help_command (char *command, int from_tty)
+{
+ help_cmd (command, gdb_stdout);
+}
+
+/* String compare function for qsort. */
+static int
+compare_strings (const void *arg1, const void *arg2)
+{
+ const char **s1 = (const char **) arg1;
+ const char **s2 = (const char **) arg2;
+ return strcmp (*s1, *s2);
+}
+
+/* The "complete" command is used by Emacs to implement completion. */
+
+/* ARGSUSED */
+static void
+complete_command (char *arg, int from_tty)
+{
+ int i;
+ int argpoint;
+ char **completions;
+
+ dont_repeat ();
+
+ if (arg == NULL)
+ arg = "";
+ argpoint = strlen (arg);
+
+ completions = complete_line (arg, arg, argpoint);
+
+ if (completions)
+ {
+ int item, size;
+
+ for (size = 0; completions[size]; ++size)
+ ;
+ qsort (completions, size, sizeof (char *), compare_strings);
+
+ /* We do extra processing here since we only want to print each
+ unique item once. */
+ item = 0;
+ while (item < size)
+ {
+ int next_item;
+ printf_unfiltered ("%s\n", completions[item]);
+ next_item = item + 1;
+ while (next_item < size
+ && ! strcmp (completions[item], completions[next_item]))
+ {
+ xfree (completions[next_item]);
+ ++next_item;
+ }
+
+ xfree (completions[item]);
+ item = next_item;
+ }
+
+ xfree (completions);
+ }
+}
+
+int
+is_complete_command (struct cmd_list_element *c)
+{
+ return cmd_cfunc_eq (c, complete_command);
+}
+
+/* ARGSUSED */
+static void
+show_version (char *args, int from_tty)
+{
+ immediate_quit++;
+ print_gdb_version (gdb_stdout);
+ printf_filtered ("\n");
+ immediate_quit--;
+}
+
+/* Handle the quit command. */
+
+void
+quit_command (char *args, int from_tty)
+{
+ if (!quit_confirm ())
+ error ("Not confirmed.");
+ quit_force (args, from_tty);
+}
+
+/* ARGSUSED */
+static void
+pwd_command (char *args, int from_tty)
+{
+ if (args)
+ error ("The \"pwd\" command does not take an argument: %s", args);
+ getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
+
+ if (!STREQ (gdb_dirbuf, current_directory))
+ printf_unfiltered ("Working directory %s\n (canonically %s).\n",
+ current_directory, gdb_dirbuf);
+ else
+ printf_unfiltered ("Working directory %s.\n", current_directory);
+}
+
+void
+cd_command (char *dir, int from_tty)
+{
+ int len;
+ /* Found something other than leading repetitions of "/..". */
+ int found_real_path;
+ char *p;
+
+ /* If the new directory is absolute, repeat is a no-op; if relative,
+ repeat might be useful but is more likely to be a mistake. */
+ dont_repeat ();
+
+ if (dir == 0)
+ error_no_arg ("new working directory");
+
+ dir = tilde_expand (dir);
+ make_cleanup (xfree, dir);
+
+ if (chdir (dir) < 0)
+ perror_with_name (dir);
+
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ /* There's too much mess with DOSish names like "d:", "d:.",
+ "d:./foo" etc. Instead of having lots of special #ifdef'ed code,
+ simply get the canonicalized name of the current directory. */
+ dir = getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
+#endif
+
+ len = strlen (dir);
+ if (IS_DIR_SEPARATOR (dir[len - 1]))
+ {
+ /* Remove the trailing slash unless this is a root directory
+ (including a drive letter on non-Unix systems). */
+ if (!(len == 1) /* "/" */
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ && !(len == 3 && dir[1] == ':') /* "d:/" */
+#endif
+ )
+ len--;
+ }
+
+ dir = savestring (dir, len);
+ if (IS_ABSOLUTE_PATH (dir))
+ current_directory = dir;
+ else
+ {
+ if (IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1]))
+ current_directory = concat (current_directory, dir, NULL);
+ else
+ current_directory = concat (current_directory, SLASH_STRING, dir, NULL);
+ xfree (dir);
+ }
+
+ /* Now simplify any occurrences of `.' and `..' in the pathname. */
+
+ found_real_path = 0;
+ for (p = current_directory; *p;)
+ {
+ if (IS_DIR_SEPARATOR (p[0]) && p[1] == '.'
+ && (p[2] == 0 || IS_DIR_SEPARATOR (p[2])))
+ strcpy (p, p + 2);
+ else if (IS_DIR_SEPARATOR (p[0]) && p[1] == '.' && p[2] == '.'
+ && (p[3] == 0 || IS_DIR_SEPARATOR (p[3])))
+ {
+ if (found_real_path)
+ {
+ /* Search backwards for the directory just before the "/.."
+ and obliterate it and the "/..". */
+ char *q = p;
+ while (q != current_directory && !IS_DIR_SEPARATOR (q[-1]))
+ --q;
+
+ if (q == current_directory)
+ /* current_directory is
+ a relative pathname ("can't happen"--leave it alone). */
+ ++p;
+ else
+ {
+ strcpy (q - 1, p + 3);
+ p = q - 1;
+ }
+ }
+ else
+ /* We are dealing with leading repetitions of "/..", for example
+ "/../..", which is the Mach super-root. */
+ p += 3;
+ }
+ else
+ {
+ found_real_path = 1;
+ ++p;
+ }
+ }
+
+ forget_cached_source_info ();
+
+ if (from_tty)
+ pwd_command ((char *) 0, 1);
+}
+
+void
+source_command (char *args, int from_tty)
+{
+ FILE *stream;
+ struct cleanup *old_cleanups;
+ char *file = args;
+
+ if (file == NULL)
+ {
+ error ("source command requires pathname of file to source.");
+ }
+
+ file = tilde_expand (file);
+ old_cleanups = make_cleanup (xfree, file);
+
+ stream = fopen (file, FOPEN_RT);
+ if (!stream)
+ {
+ if (from_tty)
+ perror_with_name (file);
+ else
+ return;
+ }
+
+ script_from_file (stream, file);
+
+ do_cleanups (old_cleanups);
+}
+
+/* ARGSUSED */
+static void
+echo_command (char *text, int from_tty)
+{
+ char *p = text;
+ register int c;
+
+ if (text)
+ while ((c = *p++) != '\0')
+ {
+ if (c == '\\')
+ {
+ /* \ at end of argument is used after spaces
+ so they won't be lost. */
+ if (*p == 0)
+ return;
+
+ c = parse_escape (&p);
+ if (c >= 0)
+ printf_filtered ("%c", c);
+ }
+ else
+ printf_filtered ("%c", c);
+ }
+
+ /* Force this output to appear now. */
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+}
+
+/* ARGSUSED */
+static void
+shell_escape (char *arg, int from_tty)
+{
+#ifdef CANT_FORK
+ /* If ARG is NULL, they want an inferior shell, but `system' just
+ reports if the shell is available when passed a NULL arg. */
+ int rc = system (arg ? arg : "");
+
+ if (!arg)
+ arg = "inferior shell";
+
+ if (rc == -1)
+ {
+ fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", arg,
+ safe_strerror (errno));
+ gdb_flush (gdb_stderr);
+ }
+ else if (rc)
+ {
+ fprintf_unfiltered (gdb_stderr, "%s exited with status %d\n", arg, rc);
+ gdb_flush (gdb_stderr);
+ }
+#ifdef GLOBAL_CURDIR
+ /* Make sure to return to the directory GDB thinks it is, in case the
+ shell command we just ran changed it. */
+ chdir (current_directory);
+#endif
+#else /* Can fork. */
+ int rc, status, pid;
+ char *p, *user_shell;
+
+ if ((user_shell = (char *) getenv ("SHELL")) == NULL)
+ user_shell = "/bin/sh";
+
+ /* Get the name of the shell for arg0 */
+ if ((p = strrchr (user_shell, '/')) == NULL)
+ p = user_shell;
+ else
+ p++; /* Get past '/' */
+
+ if ((pid = fork ()) == 0)
+ {
+ if (!arg)
+ execl (user_shell, p, 0);
+ else
+ execl (user_shell, p, "-c", arg, 0);
+
+ fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", user_shell,
+ safe_strerror (errno));
+ gdb_flush (gdb_stderr);
+ _exit (0177);
+ }
+
+ if (pid != -1)
+ while ((rc = wait (&status)) != pid && rc != -1)
+ ;
+ else
+ error ("Fork failed");
+#endif /* Can fork. */
+}
+
+static void
+make_command (char *arg, int from_tty)
+{
+ char *p;
+
+ if (arg == 0)
+ p = "make";
+ else
+ {
+ p = xmalloc (sizeof ("make ") + strlen (arg));
+ strcpy (p, "make ");
+ strcpy (p + sizeof ("make ") - 1, arg);
+ }
+
+ shell_escape (p, from_tty);
+}
+
+/* ARGSUSED */
+static void
+show_user (char *args, int from_tty)
+{
+ struct cmd_list_element *c;
+ extern struct cmd_list_element *cmdlist;
+
+ if (args)
+ {
+ c = lookup_cmd (&args, cmdlist, "", 0, 1);
+ if (c->class != class_user)
+ error ("Not a user command.");
+ show_user_1 (c, gdb_stdout);
+ }
+ else
+ {
+ for (c = cmdlist; c; c = c->next)
+ {
+ if (c->class == class_user)
+ show_user_1 (c, gdb_stdout);
+ }
+ }
+}
+
+/* Search through names of commands and documentations for a certain
+ regular expression.
+*/
+void
+apropos_command (char *searchstr, int from_tty)
+{
+ extern struct cmd_list_element *cmdlist; /*This is the main command list*/
+ regex_t pattern;
+ char *pattern_fastmap;
+ char errorbuffer[512];
+ pattern_fastmap = xcalloc (256, sizeof (char));
+ if (searchstr == NULL)
+ error("REGEXP string is empty");
+
+ if (regcomp(&pattern,searchstr,REG_ICASE) == 0)
+ {
+ pattern.fastmap=pattern_fastmap;
+ re_compile_fastmap(&pattern);
+ apropos_cmd (gdb_stdout,cmdlist,&pattern,"");
+ }
+ else
+ {
+ regerror(regcomp(&pattern,searchstr,REG_ICASE),NULL,errorbuffer,512);
+ error("Error in regular expression:%s",errorbuffer);
+ }
+ xfree (pattern_fastmap);
+}
+
+static void
+set_debug (char *arg, int from_tty)
+{
+ printf_unfiltered ("\"set debug\" must be followed by the name of a print subcommand.\n");
+ help_list (setdebuglist, "set debug ", -1, gdb_stdout);
+}
+
+static void
+show_debug (char *args, int from_tty)
+{
+ cmd_show_list (showdebuglist, from_tty, "");
+}
+
+void
+init_cmd_lists (void)
+{
+ max_user_call_depth = 1024;
+
+ cmdlist = NULL;
+ infolist = NULL;
+ enablelist = NULL;
+ disablelist = NULL;
+ togglelist = NULL;
+ stoplist = NULL;
+ deletelist = NULL;
+ enablebreaklist = NULL;
+ setlist = NULL;
+ unsetlist = NULL;
+ showlist = NULL;
+ sethistlist = NULL;
+ showhistlist = NULL;
+ unsethistlist = NULL;
+ maintenancelist = NULL;
+ maintenanceinfolist = NULL;
+ maintenanceprintlist = NULL;
+ setprintlist = NULL;
+ showprintlist = NULL;
+ setchecklist = NULL;
+ showchecklist = NULL;
+}
+
+
+void
+init_cli_cmds (void)
+{
+ struct cmd_list_element *c;
+
+ /* Define the classes of commands.
+ They will appear in the help list in the reverse of this order. */
+
+ add_cmd ("internals", class_maintenance, NULL,
+ "Maintenance commands.\n\
+Some gdb commands are provided just for use by gdb maintainers.\n\
+These commands are subject to frequent change, and may not be as\n\
+well documented as user commands.",
+ &cmdlist);
+ add_cmd ("obscure", class_obscure, NULL, "Obscure features.", &cmdlist);
+ add_cmd ("aliases", class_alias, NULL, "Aliases of other commands.", &cmdlist);
+ add_cmd ("user-defined", class_user, NULL, "User-defined commands.\n\
+The commands in this class are those defined by the user.\n\
+Use the \"define\" command to define a command.", &cmdlist);
+ add_cmd ("support", class_support, NULL, "Support facilities.", &cmdlist);
+ if (!dbx_commands)
+ add_cmd ("status", class_info, NULL, "Status inquiries.", &cmdlist);
+ add_cmd ("files", class_files, NULL, "Specifying and examining files.", &cmdlist);
+ add_cmd ("breakpoints", class_breakpoint, NULL, "Making program stop at certain points.", &cmdlist);
+ add_cmd ("data", class_vars, NULL, "Examining data.", &cmdlist);
+ add_cmd ("stack", class_stack, NULL, "Examining the stack.\n\
+The stack is made up of stack frames. Gdb assigns numbers to stack frames\n\
+counting from zero for the innermost (currently executing) frame.\n\n\
+At any time gdb identifies one frame as the \"selected\" frame.\n\
+Variable lookups are done with respect to the selected frame.\n\
+When the program being debugged stops, gdb selects the innermost frame.\n\
+The commands below can be used to select other frames by number or address.",
+ &cmdlist);
+ add_cmd ("running", class_run, NULL, "Running the program.", &cmdlist);
+
+ /* Define general commands. */
+
+ add_com ("pwd", class_files, pwd_command,
+ "Print working directory. This is used for your program as well.");
+ c = add_cmd ("cd", class_files, cd_command,
+ "Set working directory to DIR for debugger and program being debugged.\n\
+The change does not take effect for the program being debugged\n\
+until the next time it is started.", &cmdlist);
+ set_cmd_completer (c, filename_completer);
+
+ add_com ("echo", class_support, echo_command,
+ "Print a constant string. Give string as argument.\n\
+C escape sequences may be used in the argument.\n\
+No newline is added at the end of the argument;\n\
+use \"\\n\" if you want a newline to be printed.\n\
+Since leading and trailing whitespace are ignored in command arguments,\n\
+if you want to print some you must use \"\\\" before leading whitespace\n\
+to be printed or after trailing whitespace.");
+ add_com ("document", class_support, document_command,
+ "Document a user-defined command.\n\
+Give command name as argument. Give documentation on following lines.\n\
+End with a line of just \"end\".");
+ add_com ("define", class_support, define_command,
+ "Define a new command name. Command name is argument.\n\
+Definition appears on following lines, one command per line.\n\
+End with a line of just \"end\".\n\
+Use the \"document\" command to give documentation for the new command.\n\
+Commands defined in this way may have up to ten arguments.");
+
+ c = add_cmd ("source", class_support, source_command,
+ "Read commands from a file named FILE.\n\
+Note that the file \"" GDBINIT_FILENAME "\" is read automatically in this way\n\
+when gdb is started.", &cmdlist);
+ set_cmd_completer (c, filename_completer);
+
+ add_com ("quit", class_support, quit_command, "Exit gdb.");
+ c = add_com ("help", class_support, help_command, "Print list of commands.");
+ set_cmd_completer (c, command_completer);
+ add_com_alias ("q", "quit", class_support, 1);
+ add_com_alias ("h", "help", class_support, 1);
+
+ c = add_set_cmd ("verbose", class_support, var_boolean, (char *) &info_verbose,
+ "Set ",
+ &setlist),
+ add_show_from_set (c, &showlist);
+ set_cmd_sfunc (c, set_verbose);
+ set_verbose (NULL, 0, c);
+
+ add_prefix_cmd ("history", class_support, set_history,
+ "Generic command for setting command history parameters.",
+ &sethistlist, "set history ", 0, &setlist);
+ add_prefix_cmd ("history", class_support, show_history,
+ "Generic command for showing command history parameters.",
+ &showhistlist, "show history ", 0, &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("expansion", no_class, var_boolean, (char *) &history_expansion_p,
+ "Set history expansion on command input.\n\
+Without an argument, history expansion is enabled.", &sethistlist),
+ &showhistlist);
+
+ add_prefix_cmd ("info", class_info, info_command,
+ "Generic command for showing things about the program being debugged.",
+ &infolist, "info ", 0, &cmdlist);
+ add_com_alias ("i", "info", class_info, 1);
+
+ add_com ("complete", class_obscure, complete_command,
+ "List the completions for the rest of the line as a command.");
+
+ add_prefix_cmd ("show", class_info, show_command,
+ "Generic command for showing things about the debugger.",
+ &showlist, "show ", 0, &cmdlist);
+ /* Another way to get at the same thing. */
+ add_info ("set", show_command, "Show all GDB settings.");
+
+ add_cmd ("commands", no_class, show_commands,
+ "Show the history of commands you typed.\n\
+You can supply a command number to start with, or a `+' to start after\n\
+the previous command number shown.",
+ &showlist);
+
+ add_cmd ("version", no_class, show_version,
+ "Show what version of GDB this is.", &showlist);
+
+ add_com ("while", class_support, while_command,
+ "Execute nested commands WHILE the conditional expression is non zero.\n\
+The conditional expression must follow the word `while' and must in turn be\n\
+followed by a new line. The nested commands must be entered one per line,\n\
+and should be terminated by the word `end'.");
+
+ add_com ("if", class_support, if_command,
+ "Execute nested commands once IF the conditional expression is non zero.\n\
+The conditional expression must follow the word `if' and must in turn be\n\
+followed by a new line. The nested commands must be entered one per line,\n\
+and should be terminated by the word 'else' or `end'. If an else clause\n\
+is used, the same rules apply to its nested commands as to the first ones.");
+
+ /* If target is open when baud changes, it doesn't take effect until the
+ next open (I think, not sure). */
+ add_show_from_set (add_set_cmd ("remotebaud", no_class,
+ var_zinteger, (char *) &baud_rate,
+ "Set baud rate for remote serial I/O.\n\
+This value is used to set the speed of the serial port when debugging\n\
+using remote targets.", &setlist),
+ &showlist);
+
+ c = add_set_cmd ("remotedebug", no_class, var_zinteger,
+ (char *) &remote_debug,
+ "Set debugging of remote protocol.\n\
+When enabled, each packet sent or received with the remote target\n\
+is displayed.", &setlist);
+ deprecate_cmd (c, "set debug remote");
+ deprecate_cmd (add_show_from_set (c, &showlist), "show debug remote");
+
+ add_show_from_set (add_set_cmd ("remote", no_class, var_zinteger,
+ (char *) &remote_debug,
+ "Set debugging of remote protocol.\n\
+When enabled, each packet sent or received with the remote target\n\
+is displayed.", &setdebuglist),
+ &showdebuglist);
+
+ add_show_from_set (
+ add_set_cmd ("remotetimeout", no_class, var_integer, (char *) &remote_timeout,
+ "Set timeout limit to wait for target to respond.\n\
+This value is used to set the time limit for gdb to wait for a response\n\
+from the target.", &setlist),
+ &showlist);
+
+ add_prefix_cmd ("debug", no_class, set_debug,
+ "Generic command for setting gdb debugging flags",
+ &setdebuglist, "set debug ", 0, &setlist);
+
+ add_prefix_cmd ("debug", no_class, show_debug,
+ "Generic command for showing gdb debugging flags",
+ &showdebuglist, "show debug ", 0, &showlist);
+
+ c = add_com ("shell", class_support, shell_escape,
+ "Execute the rest of the line as a shell command.\n\
+With no arguments, run an inferior shell.");
+ set_cmd_completer (c, filename_completer);
+
+ /* NOTE: cagney/2000-03-20: Being able to enter ``(gdb) !ls'' would
+ be a really useful feature. Unfortunately, the below wont do
+ this. Instead it adds support for the form ``(gdb) ! ls''
+ (i.e. the space is required). If the ``!'' command below is
+ added the complains about no ``!'' command would be replaced by
+ complains about how the ``!'' command is broken :-) */
+ if (xdb_commands)
+ add_com_alias ("!", "shell", class_support, 0);
+
+ c = add_com ("make", class_support, make_command,
+ "Run the ``make'' program using the rest of the line as arguments.");
+ set_cmd_completer (c, filename_completer);
+ add_cmd ("user", no_class, show_user,
+ "Show definitions of user defined commands.\n\
+Argument is the name of the user defined command.\n\
+With no argument, show definitions of all user defined commands.", &showlist);
+ add_com ("apropos", class_support, apropos_command, "Search for commands matching a REGEXP");
+
+ add_show_from_set (
+ add_set_cmd ("max-user-call-depth", no_class, var_integer,
+ (char *) &max_user_call_depth,
+ "Set the max call depth for user-defined commands.\n",
+ &setlist),
+ &showlist);
+}
diff --git a/gdb/cli/cli-cmds.h b/gdb/cli/cli-cmds.h
new file mode 100644
index 00000000000..a6e574edd71
--- /dev/null
+++ b/gdb/cli/cli-cmds.h
@@ -0,0 +1,125 @@
+/* Header file for GDB CLI command implementation library.
+ Copyright 2000 Free Software Foundation, Inc.
+
+ 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. */
+
+#if !defined (CLI_CMDS_H)
+#define CLI_CMDS_H 1
+
+/* Chain containing all defined commands. */
+
+extern struct cmd_list_element *cmdlist;
+
+/* Chain containing all defined info subcommands. */
+
+extern struct cmd_list_element *infolist;
+
+/* Chain containing all defined enable subcommands. */
+
+extern struct cmd_list_element *enablelist;
+
+/* Chain containing all defined disable subcommands. */
+
+extern struct cmd_list_element *disablelist;
+
+/* Chain containing all defined delete subcommands. */
+
+extern struct cmd_list_element *deletelist;
+
+/* Chain containing all defined toggle subcommands. */
+
+extern struct cmd_list_element *togglelist;
+
+/* Chain containing all defined stop subcommands. */
+
+extern struct cmd_list_element *stoplist;
+
+/* Chain containing all defined "enable breakpoint" subcommands. */
+
+extern struct cmd_list_element *enablebreaklist;
+
+/* Chain containing all defined set subcommands */
+
+extern struct cmd_list_element *setlist;
+
+/* Chain containing all defined unset subcommands */
+
+extern struct cmd_list_element *unsetlist;
+
+/* Chain containing all defined show subcommands. */
+
+extern struct cmd_list_element *showlist;
+
+/* Chain containing all defined \"set history\". */
+
+extern struct cmd_list_element *sethistlist;
+
+/* Chain containing all defined \"show history\". */
+
+extern struct cmd_list_element *showhistlist;
+
+/* Chain containing all defined \"unset history\". */
+
+extern struct cmd_list_element *unsethistlist;
+
+/* Chain containing all defined maintenance subcommands. */
+
+extern struct cmd_list_element *maintenancelist;
+
+/* Chain containing all defined "maintenance info" subcommands. */
+
+extern struct cmd_list_element *maintenanceinfolist;
+
+/* Chain containing all defined "maintenance print" subcommands. */
+
+extern struct cmd_list_element *maintenanceprintlist;
+
+extern struct cmd_list_element *setprintlist;
+
+extern struct cmd_list_element *showprintlist;
+
+extern struct cmd_list_element *setdebuglist;
+
+extern struct cmd_list_element *showdebuglist;
+
+extern struct cmd_list_element *setchecklist;
+
+extern struct cmd_list_element *showchecklist;
+
+/* Exported to gdb/top.c */
+
+void init_cmd_lists (void);
+
+void init_cli_cmds (void);
+
+int is_complete_command (struct cmd_list_element *cmd);
+
+/* Exported to gdb/main.c */
+
+extern void cd_command (char *, int);
+
+/* Exported to gdb/top.c and gdb/main.c */
+
+extern void quit_command (char *, int);
+
+extern void source_command (char *, int);
+
+/* Used everywhere whenever at least one parameter is required and
+ none is specified. */
+
+extern NORETURN void error_no_arg (char *) ATTR_NORETURN;
+
+#endif /* !defined (CLI_CMDS_H) */
diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
new file mode 100644
index 00000000000..3f510ac87d1
--- /dev/null
+++ b/gdb/cli/cli-decode.c
@@ -0,0 +1,1447 @@
+/* Handle lists of commands, their decoding and documentation, for GDB.
+
+ Copyright 1986, 1989, 1990, 1991, 1998, 2000, 2001, 2002 Free
+ Software Foundation, Inc.
+
+ 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 "defs.h"
+#include "symtab.h"
+#include <ctype.h>
+#include "gdb_regex.h"
+
+#include "ui-out.h"
+
+#include "cli/cli-cmds.h"
+#include "cli/cli-decode.h"
+
+#include "gdb_assert.h"
+
+/* Prototypes for local functions */
+
+static void undef_cmd_error (char *, char *);
+
+static struct cmd_list_element *find_cmd (char *command,
+ int len,
+ struct cmd_list_element *clist,
+ int ignore_help_classes,
+ int *nfound);
+
+static void help_all (struct ui_file *stream);
+
+/* Set the callback function for the specified command. For each both
+ the commands callback and func() are set. The latter set to a
+ bounce function (unless cfunc / sfunc is NULL that is). */
+
+static void
+do_cfunc (struct cmd_list_element *c, char *args, int from_tty)
+{
+ c->function.cfunc (args, from_tty); /* Ok. */
+}
+
+void
+set_cmd_cfunc (struct cmd_list_element *cmd,
+ void (*cfunc) (char *args, int from_tty))
+{
+ if (cfunc == NULL)
+ cmd->func = NULL;
+ else
+ cmd->func = do_cfunc;
+ cmd->function.cfunc = cfunc; /* Ok. */
+}
+
+static void
+do_sfunc (struct cmd_list_element *c, char *args, int from_tty)
+{
+ c->function.sfunc (args, from_tty, c); /* Ok. */
+}
+
+void
+set_cmd_sfunc (struct cmd_list_element *cmd,
+ void (*sfunc) (char *args, int from_tty,
+ struct cmd_list_element * c))
+{
+ if (sfunc == NULL)
+ cmd->func = NULL;
+ else
+ cmd->func = do_sfunc;
+ cmd->function.sfunc = sfunc; /* Ok. */
+}
+
+int
+cmd_cfunc_eq (struct cmd_list_element *cmd,
+ void (*cfunc) (char *args, int from_tty))
+{
+ return cmd->func == do_cfunc && cmd->function.cfunc == cfunc;
+}
+
+void
+set_cmd_context (struct cmd_list_element *cmd, void *context)
+{
+ cmd->context = context;
+}
+
+void *
+get_cmd_context (struct cmd_list_element *cmd)
+{
+ return cmd->context;
+}
+
+enum cmd_types
+cmd_type (struct cmd_list_element *cmd)
+{
+ return cmd->type;
+}
+
+void
+set_cmd_completer (struct cmd_list_element *cmd,
+ char **(*completer) (char *text, char *word))
+{
+ cmd->completer = completer; /* Ok. */
+}
+
+
+/* Add element named NAME.
+ CLASS is the top level category into which commands are broken down
+ for "help" purposes.
+ FUN should be the function to execute the command;
+ it will get a character string as argument, with leading
+ and trailing blanks already eliminated.
+
+ DOC is a documentation string for the command.
+ Its first line should be a complete sentence.
+ It should start with ? for a command that is an abbreviation
+ or with * for a command that most users don't need to know about.
+
+ Add this command to command list *LIST.
+
+ Returns a pointer to the added command (not necessarily the head
+ of *LIST). */
+
+struct cmd_list_element *
+add_cmd (char *name, enum command_class class, void (*fun) (char *, int),
+ char *doc, struct cmd_list_element **list)
+{
+ register struct cmd_list_element *c
+ = (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element));
+ struct cmd_list_element *p;
+
+ delete_cmd (name, list);
+
+ if (*list == NULL || strcmp ((*list)->name, name) >= 0)
+ {
+ c->next = *list;
+ *list = c;
+ }
+ else
+ {
+ p = *list;
+ while (p->next && strcmp (p->next->name, name) <= 0)
+ {
+ p = p->next;
+ }
+ c->next = p->next;
+ p->next = c;
+ }
+
+ c->name = name;
+ c->class = class;
+ set_cmd_cfunc (c, fun);
+ set_cmd_context (c, NULL);
+ c->doc = doc;
+ c->flags = 0;
+ c->replacement = NULL;
+ c->pre_show_hook = NULL;
+ c->hook_pre = NULL;
+ c->hook_post = NULL;
+ c->hook_in = 0;
+ c->prefixlist = NULL;
+ c->prefixname = NULL;
+ c->allow_unknown = 0;
+ c->abbrev_flag = 0;
+ set_cmd_completer (c, make_symbol_completion_list);
+ c->type = not_set_cmd;
+ c->var = NULL;
+ c->var_type = var_boolean;
+ c->enums = NULL;
+ c->user_commands = NULL;
+ c->hookee_pre = NULL;
+ c->hookee_post = NULL;
+ c->cmd_pointer = NULL;
+
+ return c;
+}
+
+/* Same as above, except that the abbrev_flag is set. */
+/* Note: Doesn't seem to be used anywhere currently. */
+
+struct cmd_list_element *
+add_abbrev_cmd (char *name, enum command_class class, void (*fun) (char *, int),
+ char *doc, struct cmd_list_element **list)
+{
+ register struct cmd_list_element *c
+ = add_cmd (name, class, fun, doc, list);
+
+ c->abbrev_flag = 1;
+ return c;
+}
+
+/* Deprecates a command CMD.
+ REPLACEMENT is the name of the command which should be used in place
+ of this command, or NULL if no such command exists.
+
+ This function does not check to see if command REPLACEMENT exists
+ since gdb may not have gotten around to adding REPLACEMENT when this
+ function is called.
+
+ Returns a pointer to the deprecated command. */
+
+struct cmd_list_element *
+deprecate_cmd (struct cmd_list_element *cmd, char *replacement)
+{
+ cmd->flags |= (CMD_DEPRECATED | DEPRECATED_WARN_USER);
+
+ if (replacement != NULL)
+ cmd->replacement = replacement;
+ else
+ cmd->replacement = NULL;
+
+ return cmd;
+}
+
+struct cmd_list_element *
+add_alias_cmd (char *name, char *oldname, enum command_class class,
+ int abbrev_flag, struct cmd_list_element **list)
+{
+ /* Must do this since lookup_cmd tries to side-effect its first arg */
+ char *copied_name;
+ register struct cmd_list_element *old;
+ register struct cmd_list_element *c;
+ copied_name = (char *) alloca (strlen (oldname) + 1);
+ strcpy (copied_name, oldname);
+ old = lookup_cmd (&copied_name, *list, "", 1, 1);
+
+ if (old == 0)
+ {
+ delete_cmd (name, list);
+ return 0;
+ }
+
+ c = add_cmd (name, class, NULL, old->doc, list);
+ /* NOTE: Both FUNC and all the FUNCTIONs need to be copied. */
+ c->func = old->func;
+ c->function = old->function;
+ c->prefixlist = old->prefixlist;
+ c->prefixname = old->prefixname;
+ c->allow_unknown = old->allow_unknown;
+ c->abbrev_flag = abbrev_flag;
+ c->cmd_pointer = old;
+ return c;
+}
+
+/* Like add_cmd but adds an element for a command prefix:
+ a name that should be followed by a subcommand to be looked up
+ in another command list. PREFIXLIST should be the address
+ of the variable containing that list. */
+
+struct cmd_list_element *
+add_prefix_cmd (char *name, enum command_class class, void (*fun) (char *, int),
+ char *doc, struct cmd_list_element **prefixlist,
+ char *prefixname, int allow_unknown,
+ struct cmd_list_element **list)
+{
+ register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list);
+ c->prefixlist = prefixlist;
+ c->prefixname = prefixname;
+ c->allow_unknown = allow_unknown;
+ return c;
+}
+
+/* Like add_prefix_cmd but sets the abbrev_flag on the new command. */
+
+struct cmd_list_element *
+add_abbrev_prefix_cmd (char *name, enum command_class class,
+ void (*fun) (char *, int), char *doc,
+ struct cmd_list_element **prefixlist, char *prefixname,
+ int allow_unknown, struct cmd_list_element **list)
+{
+ register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list);
+ c->prefixlist = prefixlist;
+ c->prefixname = prefixname;
+ c->allow_unknown = allow_unknown;
+ c->abbrev_flag = 1;
+ return c;
+}
+
+/* This is an empty "cfunc". */
+void
+not_just_help_class_command (char *args, int from_tty)
+{
+}
+
+/* This is an empty "sfunc". */
+static void empty_sfunc (char *, int, struct cmd_list_element *);
+
+static void
+empty_sfunc (char *args, int from_tty, struct cmd_list_element *c)
+{
+}
+
+/* Add element named NAME to command list LIST (the list for set/show
+ or some sublist thereof).
+ TYPE is set_cmd or show_cmd.
+ CLASS is as in add_cmd.
+ VAR_TYPE is the kind of thing we are setting.
+ VAR is address of the variable being controlled by this command.
+ DOC is the documentation string. */
+
+static struct cmd_list_element *
+add_set_or_show_cmd (char *name,
+ enum cmd_types type,
+ enum command_class class,
+ var_types var_type,
+ void *var,
+ char *doc,
+ struct cmd_list_element **list)
+{
+ struct cmd_list_element *c = add_cmd (name, class, NULL, doc, list);
+ gdb_assert (type == set_cmd || type == show_cmd);
+ c->type = type;
+ c->var_type = var_type;
+ c->var = var;
+ /* This needs to be something besides NULL so that this isn't
+ treated as a help class. */
+ set_cmd_sfunc (c, empty_sfunc);
+ return c;
+}
+
+
+struct cmd_list_element *
+add_set_cmd (char *name,
+ enum command_class class,
+ var_types var_type,
+ void *var,
+ char *doc,
+ struct cmd_list_element **list)
+{
+ return add_set_or_show_cmd (name, set_cmd, class, var_type, var, doc, list);
+}
+
+/* Add element named NAME to command list LIST (the list for set
+ or some sublist thereof).
+ CLASS is as in add_cmd.
+ ENUMLIST is a list of strings which may follow NAME.
+ VAR is address of the variable which will contain the matching string
+ (from ENUMLIST).
+ DOC is the documentation string. */
+
+struct cmd_list_element *
+add_set_enum_cmd (char *name,
+ enum command_class class,
+ const char *enumlist[],
+ const char **var,
+ char *doc,
+ struct cmd_list_element **list)
+{
+ struct cmd_list_element *c
+ = add_set_cmd (name, class, var_enum, var, doc, list);
+ c->enums = enumlist;
+
+ return c;
+}
+
+/* Add element named NAME to command list LIST (the list for set
+ or some sublist thereof).
+ CLASS is as in add_cmd.
+ VAR is address of the variable which will contain the value.
+ DOC is the documentation string. */
+struct cmd_list_element *
+add_set_auto_boolean_cmd (char *name,
+ enum command_class class,
+ enum cmd_auto_boolean *var,
+ char *doc,
+ struct cmd_list_element **list)
+{
+ static const char *auto_boolean_enums[] = { "on", "off", "auto", NULL };
+ struct cmd_list_element *c;
+ c = add_set_cmd (name, class, var_auto_boolean, var, doc, list);
+ c->enums = auto_boolean_enums;
+ return c;
+}
+
+/* Add element named NAME to command list LIST (the list for set
+ or some sublist thereof).
+ CLASS is as in add_cmd.
+ VAR is address of the variable which will contain the value.
+ DOC is the documentation string. */
+struct cmd_list_element *
+add_set_boolean_cmd (char *name,
+ enum command_class class,
+ int *var,
+ char *doc,
+ struct cmd_list_element **list)
+{
+ static const char *boolean_enums[] = { "on", "off", NULL };
+ struct cmd_list_element *c;
+ c = add_set_cmd (name, class, var_boolean, var, doc, list);
+ c->enums = boolean_enums;
+ return c;
+}
+
+/* Where SETCMD has already been added, add the corresponding show
+ command to LIST and return a pointer to the added command (not
+ necessarily the head of LIST). */
+/* NOTE: cagney/2002-03-17: The original version of add_show_from_set
+ used memcpy() to clone `set' into `show'. This ment that in
+ addition to all the needed fields (var, name, et.al.) some
+ unnecessary fields were copied (namely the callback function). The
+ function explictly copies relevant fields. For a `set' and `show'
+ command to share the same callback, the caller must set both
+ explicitly. */
+struct cmd_list_element *
+add_show_from_set (struct cmd_list_element *setcmd,
+ struct cmd_list_element **list)
+{
+ char *doc;
+ const static char setstring[] = "Set ";
+
+ /* Create a doc string by replacing "Set " at the start of the
+ `set'' command's doco with "Show ". */
+ gdb_assert (strncmp (setcmd->doc, setstring, sizeof (setstring) - 1) == 0);
+ doc = concat ("Show ", setcmd->doc + sizeof (setstring) - 1, NULL);
+
+ /* Insert the basic command. */
+ return add_set_or_show_cmd (setcmd->name, show_cmd, setcmd->class,
+ setcmd->var_type, setcmd->var, doc, list);
+}
+
+/* Remove the command named NAME from the command list. */
+
+void
+delete_cmd (char *name, struct cmd_list_element **list)
+{
+ register struct cmd_list_element *c;
+ struct cmd_list_element *p;
+
+ while (*list && STREQ ((*list)->name, name))
+ {
+ if ((*list)->hookee_pre)
+ (*list)->hookee_pre->hook_pre = 0; /* Hook slips out of its mouth */
+ if ((*list)->hookee_post)
+ (*list)->hookee_post->hook_post = 0; /* Hook slips out of its bottom */
+ p = (*list)->next;
+ xfree (* list);
+ *list = p;
+ }
+
+ if (*list)
+ for (c = *list; c->next;)
+ {
+ if (STREQ (c->next->name, name))
+ {
+ if (c->next->hookee_pre)
+ c->next->hookee_pre->hook_pre = 0; /* hooked cmd gets away. */
+ if (c->next->hookee_post)
+ c->next->hookee_post->hook_post = 0; /* remove post hook */
+ /* :( no fishing metaphore */
+ p = c->next->next;
+ xfree (c->next);
+ c->next = p;
+ }
+ else
+ c = c->next;
+ }
+}
+
+/* Shorthands to the commands above. */
+
+/* Add an element to the list of info subcommands. */
+
+struct cmd_list_element *
+add_info (char *name, void (*fun) (char *, int), char *doc)
+{
+ return add_cmd (name, no_class, fun, doc, &infolist);
+}
+
+/* Add an alias to the list of info subcommands. */
+
+struct cmd_list_element *
+add_info_alias (char *name, char *oldname, int abbrev_flag)
+{
+ return add_alias_cmd (name, oldname, 0, abbrev_flag, &infolist);
+}
+
+/* Add an element to the list of commands. */
+
+struct cmd_list_element *
+add_com (char *name, enum command_class class, void (*fun) (char *, int),
+ char *doc)
+{
+ return add_cmd (name, class, fun, doc, &cmdlist);
+}
+
+/* Add an alias or abbreviation command to the list of commands. */
+
+struct cmd_list_element *
+add_com_alias (char *name, char *oldname, enum command_class class,
+ int abbrev_flag)
+{
+ return add_alias_cmd (name, oldname, class, abbrev_flag, &cmdlist);
+}
+
+/* Recursively walk the commandlist structures, and print out the
+ documentation of commands that match our regex in either their
+ name, or their documentation.
+*/
+void
+apropos_cmd (struct ui_file *stream, struct cmd_list_element *commandlist,
+ struct re_pattern_buffer *regex, char *prefix)
+{
+ register struct cmd_list_element *c;
+ int returnvalue=1; /*Needed to avoid double printing*/
+ /* Walk through the commands */
+ for (c=commandlist;c;c=c->next)
+ {
+ if (c->name != NULL)
+ {
+ /* Try to match against the name*/
+ returnvalue=re_search(regex,c->name,strlen(c->name),0,strlen(c->name),NULL);
+ if (returnvalue >= 0)
+ {
+ /* Stolen from help_cmd_list. We don't directly use
+ * help_cmd_list because it doesn't let us print out
+ * single commands
+ */
+ fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
+ print_doc_line (stream, c->doc);
+ fputs_filtered ("\n", stream);
+ returnvalue=0; /*Set this so we don't print it again.*/
+ }
+ }
+ if (c->doc != NULL && returnvalue != 0)
+ {
+ /* Try to match against documentation */
+ if (re_search(regex,c->doc,strlen(c->doc),0,strlen(c->doc),NULL) >=0)
+ {
+ /* Stolen from help_cmd_list. We don't directly use
+ * help_cmd_list because it doesn't let us print out
+ * single commands
+ */
+ fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
+ print_doc_line (stream, c->doc);
+ fputs_filtered ("\n", stream);
+ }
+ }
+ /* Check if this command has subcommands */
+ if (c->prefixlist != NULL)
+ {
+ /* Recursively call ourselves on the subcommand list,
+ passing the right prefix in.
+ */
+ apropos_cmd (stream,*c->prefixlist,regex,c->prefixname);
+ }
+ }
+}
+
+/* This command really has to deal with two things:
+ * 1) I want documentation on *this string* (usually called by
+ * "help commandname").
+ * 2) I want documentation on *this list* (usually called by
+ * giving a command that requires subcommands. Also called by saying
+ * just "help".)
+ *
+ * I am going to split this into two seperate comamnds, help_cmd and
+ * help_list.
+ */
+
+void
+help_cmd (char *command, struct ui_file *stream)
+{
+ struct cmd_list_element *c;
+ extern struct cmd_list_element *cmdlist;
+
+ if (!command)
+ {
+ help_list (cmdlist, "", all_classes, stream);
+ return;
+ }
+
+ if (strcmp (command, "all") == 0)
+ {
+ help_all (stream);
+ return;
+ }
+
+ c = lookup_cmd (&command, cmdlist, "", 0, 0);
+
+ if (c == 0)
+ return;
+
+ /* There are three cases here.
+ If c->prefixlist is nonzero, we have a prefix command.
+ Print its documentation, then list its subcommands.
+
+ If c->func is non NULL, we really have a command. Print its
+ documentation and return.
+
+ If c->func is NULL, we have a class name. Print its
+ documentation (as if it were a command) and then set class to the
+ number of this class so that the commands in the class will be
+ listed. */
+
+ fputs_filtered (c->doc, stream);
+ fputs_filtered ("\n", stream);
+
+ if (c->prefixlist == 0 && c->func != NULL)
+ return;
+ fprintf_filtered (stream, "\n");
+
+ /* If this is a prefix command, print it's subcommands */
+ if (c->prefixlist)
+ help_list (*c->prefixlist, c->prefixname, all_commands, stream);
+
+ /* If this is a class name, print all of the commands in the class */
+ if (c->func == NULL)
+ help_list (cmdlist, "", c->class, stream);
+
+ if (c->hook_pre || c->hook_post)
+ fprintf_filtered (stream,
+ "\nThis command has a hook (or hooks) defined:\n");
+
+ if (c->hook_pre)
+ fprintf_filtered (stream,
+ "\tThis command is run after : %s (pre hook)\n",
+ c->hook_pre->name);
+ if (c->hook_post)
+ fprintf_filtered (stream,
+ "\tThis command is run before : %s (post hook)\n",
+ c->hook_post->name);
+}
+
+/*
+ * Get a specific kind of help on a command list.
+ *
+ * LIST is the list.
+ * CMDTYPE is the prefix to use in the title string.
+ * CLASS is the class with which to list the nodes of this list (see
+ * documentation for help_cmd_list below), As usual, ALL_COMMANDS for
+ * everything, ALL_CLASSES for just classes, and non-negative for only things
+ * in a specific class.
+ * and STREAM is the output stream on which to print things.
+ * If you call this routine with a class >= 0, it recurses.
+ */
+void
+help_list (struct cmd_list_element *list, char *cmdtype,
+ enum command_class class, struct ui_file *stream)
+{
+ int len;
+ char *cmdtype1, *cmdtype2;
+
+ /* If CMDTYPE is "foo ", CMDTYPE1 gets " foo" and CMDTYPE2 gets "foo sub" */
+ len = strlen (cmdtype);
+ cmdtype1 = (char *) alloca (len + 1);
+ cmdtype1[0] = 0;
+ cmdtype2 = (char *) alloca (len + 4);
+ cmdtype2[0] = 0;
+ if (len)
+ {
+ cmdtype1[0] = ' ';
+ strncpy (cmdtype1 + 1, cmdtype, len - 1);
+ cmdtype1[len] = 0;
+ strncpy (cmdtype2, cmdtype, len - 1);
+ strcpy (cmdtype2 + len - 1, " sub");
+ }
+
+ if (class == all_classes)
+ fprintf_filtered (stream, "List of classes of %scommands:\n\n", cmdtype2);
+ else
+ fprintf_filtered (stream, "List of %scommands:\n\n", cmdtype2);
+
+ help_cmd_list (list, class, cmdtype, (int) class >= 0, stream);
+
+ if (class == all_classes)
+ {
+ fprintf_filtered (stream, "\n\
+Type \"help%s\" followed by a class name for a list of commands in ",
+ cmdtype1);
+ wrap_here ("");
+ fprintf_filtered (stream, "that class.");
+ }
+
+ fprintf_filtered (stream, "\nType \"help%s\" followed by %scommand name ",
+ cmdtype1, cmdtype2);
+ wrap_here ("");
+ fputs_filtered ("for ", stream);
+ wrap_here ("");
+ fputs_filtered ("full ", stream);
+ wrap_here ("");
+ fputs_filtered ("documentation.\n", stream);
+ fputs_filtered ("Command name abbreviations are allowed if unambiguous.\n",
+ stream);
+}
+
+static void
+help_all (struct ui_file *stream)
+{
+ struct cmd_list_element *c;
+ extern struct cmd_list_element *cmdlist;
+
+ for (c = cmdlist; c; c = c->next)
+ {
+ if (c->abbrev_flag)
+ continue;
+ /* If this is a prefix command, print it's subcommands */
+ if (c->prefixlist)
+ help_cmd_list (*c->prefixlist, all_commands, c->prefixname, 0, stream);
+
+ /* If this is a class name, print all of the commands in the class */
+ else if (c->func == NULL)
+ help_cmd_list (cmdlist, c->class, "", 0, stream);
+ }
+}
+
+/* Print only the first line of STR on STREAM. */
+void
+print_doc_line (struct ui_file *stream, char *str)
+{
+ static char *line_buffer = 0;
+ static int line_size;
+ register char *p;
+
+ if (!line_buffer)
+ {
+ line_size = 80;
+ line_buffer = (char *) xmalloc (line_size);
+ }
+
+ p = str;
+ while (*p && *p != '\n' && *p != '.' && *p != ',')
+ p++;
+ if (p - str > line_size - 1)
+ {
+ line_size = p - str + 1;
+ xfree (line_buffer);
+ line_buffer = (char *) xmalloc (line_size);
+ }
+ strncpy (line_buffer, str, p - str);
+ line_buffer[p - str] = '\0';
+ if (islower (line_buffer[0]))
+ line_buffer[0] = toupper (line_buffer[0]);
+ ui_out_text (uiout, line_buffer);
+}
+
+/*
+ * Implement a help command on command list LIST.
+ * RECURSE should be non-zero if this should be done recursively on
+ * all sublists of LIST.
+ * PREFIX is the prefix to print before each command name.
+ * STREAM is the stream upon which the output should be written.
+ * CLASS should be:
+ * A non-negative class number to list only commands in that
+ * class.
+ * ALL_COMMANDS to list all commands in list.
+ * ALL_CLASSES to list all classes in list.
+ *
+ * Note that RECURSE will be active on *all* sublists, not just the
+ * ones selected by the criteria above (ie. the selection mechanism
+ * is at the low level, not the high-level).
+ */
+void
+help_cmd_list (struct cmd_list_element *list, enum command_class class,
+ char *prefix, int recurse, struct ui_file *stream)
+{
+ register struct cmd_list_element *c;
+
+ for (c = list; c; c = c->next)
+ {
+ if (c->abbrev_flag == 0 &&
+ (class == all_commands
+ || (class == all_classes && c->func == NULL)
+ || (class == c->class && c->func != NULL)))
+ {
+ fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
+ print_doc_line (stream, c->doc);
+ fputs_filtered ("\n", stream);
+ }
+ if (recurse
+ && c->prefixlist != 0
+ && c->abbrev_flag == 0)
+ help_cmd_list (*c->prefixlist, class, c->prefixname, 1, stream);
+ }
+}
+
+
+/* Search the input clist for 'command'. Return the command if
+ found (or NULL if not), and return the number of commands
+ found in nfound */
+
+static struct cmd_list_element *
+find_cmd (char *command, int len, struct cmd_list_element *clist,
+ int ignore_help_classes, int *nfound)
+{
+ struct cmd_list_element *found, *c;
+
+ found = (struct cmd_list_element *) NULL;
+ *nfound = 0;
+ for (c = clist; c; c = c->next)
+ if (!strncmp (command, c->name, len)
+ && (!ignore_help_classes || c->func))
+ {
+ found = c;
+ (*nfound)++;
+ if (c->name[len] == '\0')
+ {
+ *nfound = 1;
+ break;
+ }
+ }
+ return found;
+}
+
+/* This routine takes a line of TEXT and a CLIST in which to start the
+ lookup. When it returns it will have incremented the text pointer past
+ the section of text it matched, set *RESULT_LIST to point to the list in
+ which the last word was matched, and will return a pointer to the cmd
+ list element which the text matches. It will return NULL if no match at
+ all was possible. It will return -1 (cast appropriately, ick) if ambigous
+ matches are possible; in this case *RESULT_LIST will be set to point to
+ the list in which there are ambiguous choices (and *TEXT will be set to
+ the ambiguous text string).
+
+ If the located command was an abbreviation, this routine returns the base
+ command of the abbreviation.
+
+ It does no error reporting whatsoever; control will always return
+ to the superior routine.
+
+ In the case of an ambiguous return (-1), *RESULT_LIST will be set to point
+ at the prefix_command (ie. the best match) *or* (special case) will be NULL
+ if no prefix command was ever found. For example, in the case of "info a",
+ "info" matches without ambiguity, but "a" could be "args" or "address", so
+ *RESULT_LIST is set to the cmd_list_element for "info". So in this case
+ RESULT_LIST should not be interpeted as a pointer to the beginning of a
+ list; it simply points to a specific command. In the case of an ambiguous
+ return *TEXT is advanced past the last non-ambiguous prefix (e.g.
+ "info t" can be "info types" or "info target"; upon return *TEXT has been
+ advanced past "info ").
+
+ If RESULT_LIST is NULL, don't set *RESULT_LIST (but don't otherwise
+ affect the operation).
+
+ This routine does *not* modify the text pointed to by TEXT.
+
+ If IGNORE_HELP_CLASSES is nonzero, ignore any command list elements which
+ are actually help classes rather than commands (i.e. the function field of
+ the struct cmd_list_element is NULL). */
+
+struct cmd_list_element *
+lookup_cmd_1 (char **text, struct cmd_list_element *clist,
+ struct cmd_list_element **result_list, int ignore_help_classes)
+{
+ char *p, *command;
+ int len, tmp, nfound;
+ struct cmd_list_element *found, *c;
+ char *line = *text;
+
+ while (**text == ' ' || **text == '\t')
+ (*text)++;
+
+ /* Treating underscores as part of command words is important
+ so that "set args_foo()" doesn't get interpreted as
+ "set args _foo()". */
+ for (p = *text;
+ *p && (isalnum (*p) || *p == '-' || *p == '_' ||
+ (tui_version &&
+ (*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||
+ (xdb_commands && (*p == '!' || *p == '/' || *p == '?')));
+ p++)
+ ;
+
+ /* If nothing but whitespace, return 0. */
+ if (p == *text)
+ return 0;
+
+ len = p - *text;
+
+ /* *text and p now bracket the first command word to lookup (and
+ it's length is len). We copy this into a local temporary */
+
+
+ command = (char *) alloca (len + 1);
+ for (tmp = 0; tmp < len; tmp++)
+ {
+ char x = (*text)[tmp];
+ command[tmp] = x;
+ }
+ command[len] = '\0';
+
+ /* Look it up. */
+ found = 0;
+ nfound = 0;
+ found = find_cmd (command, len, clist, ignore_help_classes, &nfound);
+
+ /*
+ ** We didn't find the command in the entered case, so lower case it
+ ** and search again.
+ */
+ if (!found || nfound == 0)
+ {
+ for (tmp = 0; tmp < len; tmp++)
+ {
+ char x = command[tmp];
+ command[tmp] = isupper (x) ? tolower (x) : x;
+ }
+ found = find_cmd (command, len, clist, ignore_help_classes, &nfound);
+ }
+
+ /* If nothing matches, we have a simple failure. */
+ if (nfound == 0)
+ return 0;
+
+ if (nfound > 1)
+ {
+ if (result_list != NULL)
+ /* Will be modified in calling routine
+ if we know what the prefix command is. */
+ *result_list = 0;
+ return (struct cmd_list_element *) -1; /* Ambiguous. */
+ }
+
+ /* We've matched something on this list. Move text pointer forward. */
+
+ *text = p;
+
+ if (found->cmd_pointer)
+ {
+ /* We drop the alias (abbreviation) in favor of the command it is
+ pointing to. If the alias is deprecated, though, we need to
+ warn the user about it before we drop it. Note that while we
+ are warning about the alias, we may also warn about the command
+ itself and we will adjust the appropriate DEPRECATED_WARN_USER
+ flags */
+
+ if (found->flags & DEPRECATED_WARN_USER)
+ deprecated_cmd_warning (&line);
+ found = found->cmd_pointer;
+ }
+ /* If we found a prefix command, keep looking. */
+
+ if (found->prefixlist)
+ {
+ c = lookup_cmd_1 (text, *found->prefixlist, result_list,
+ ignore_help_classes);
+ if (!c)
+ {
+ /* Didn't find anything; this is as far as we got. */
+ if (result_list != NULL)
+ *result_list = clist;
+ return found;
+ }
+ else if (c == (struct cmd_list_element *) -1)
+ {
+ /* We've gotten this far properly, but the next step
+ is ambiguous. We need to set the result list to the best
+ we've found (if an inferior hasn't already set it). */
+ if (result_list != NULL)
+ if (!*result_list)
+ /* This used to say *result_list = *found->prefixlist
+ If that was correct, need to modify the documentation
+ at the top of this function to clarify what is supposed
+ to be going on. */
+ *result_list = found;
+ return c;
+ }
+ else
+ {
+ /* We matched! */
+ return c;
+ }
+ }
+ else
+ {
+ if (result_list != NULL)
+ *result_list = clist;
+ return found;
+ }
+}
+
+/* All this hair to move the space to the front of cmdtype */
+
+static void
+undef_cmd_error (char *cmdtype, char *q)
+{
+ error ("Undefined %scommand: \"%s\". Try \"help%s%.*s\".",
+ cmdtype,
+ q,
+ *cmdtype ? " " : "",
+ (int) strlen (cmdtype) - 1,
+ cmdtype);
+}
+
+/* Look up the contents of *LINE as a command in the command list LIST.
+ LIST is a chain of struct cmd_list_element's.
+ If it is found, return the struct cmd_list_element for that command
+ and update *LINE to point after the command name, at the first argument.
+ If not found, call error if ALLOW_UNKNOWN is zero
+ otherwise (or if error returns) return zero.
+ Call error if specified command is ambiguous,
+ unless ALLOW_UNKNOWN is negative.
+ CMDTYPE precedes the word "command" in the error message.
+
+ If INGNORE_HELP_CLASSES is nonzero, ignore any command list
+ elements which are actually help classes rather than commands (i.e.
+ the function field of the struct cmd_list_element is 0). */
+
+struct cmd_list_element *
+lookup_cmd (char **line, struct cmd_list_element *list, char *cmdtype,
+ int allow_unknown, int ignore_help_classes)
+{
+ struct cmd_list_element *last_list = 0;
+ struct cmd_list_element *c =
+ lookup_cmd_1 (line, list, &last_list, ignore_help_classes);
+
+ /* Note: Do not remove trailing whitespace here because this
+ would be wrong for complete_command. Jim Kingdon */
+
+ if (!c)
+ {
+ if (!allow_unknown)
+ {
+ if (!*line)
+ error ("Lack of needed %scommand", cmdtype);
+ else
+ {
+ char *p = *line, *q;
+
+ while (isalnum (*p) || *p == '-')
+ p++;
+
+ q = (char *) alloca (p - *line + 1);
+ strncpy (q, *line, p - *line);
+ q[p - *line] = '\0';
+ undef_cmd_error (cmdtype, q);
+ }
+ }
+ else
+ return 0;
+ }
+ else if (c == (struct cmd_list_element *) -1)
+ {
+ /* Ambigous. Local values should be off prefixlist or called
+ values. */
+ int local_allow_unknown = (last_list ? last_list->allow_unknown :
+ allow_unknown);
+ char *local_cmdtype = last_list ? last_list->prefixname : cmdtype;
+ struct cmd_list_element *local_list =
+ (last_list ? *(last_list->prefixlist) : list);
+
+ if (local_allow_unknown < 0)
+ {
+ if (last_list)
+ return last_list; /* Found something. */
+ else
+ return 0; /* Found nothing. */
+ }
+ else
+ {
+ /* Report as error. */
+ int amb_len;
+ char ambbuf[100];
+
+ for (amb_len = 0;
+ ((*line)[amb_len] && (*line)[amb_len] != ' '
+ && (*line)[amb_len] != '\t');
+ amb_len++)
+ ;
+
+ ambbuf[0] = 0;
+ for (c = local_list; c; c = c->next)
+ if (!strncmp (*line, c->name, amb_len))
+ {
+ if (strlen (ambbuf) + strlen (c->name) + 6 < (int) sizeof ambbuf)
+ {
+ if (strlen (ambbuf))
+ strcat (ambbuf, ", ");
+ strcat (ambbuf, c->name);
+ }
+ else
+ {
+ strcat (ambbuf, "..");
+ break;
+ }
+ }
+ error ("Ambiguous %scommand \"%s\": %s.", local_cmdtype,
+ *line, ambbuf);
+ return 0; /* lint */
+ }
+ }
+ else
+ {
+ /* We've got something. It may still not be what the caller
+ wants (if this command *needs* a subcommand). */
+ while (**line == ' ' || **line == '\t')
+ (*line)++;
+
+ if (c->prefixlist && **line && !c->allow_unknown)
+ undef_cmd_error (c->prefixname, *line);
+
+ /* Seems to be what he wants. Return it. */
+ return c;
+ }
+ return 0;
+}
+
+/* We are here presumably because an alias or command in *TEXT is
+ deprecated and a warning message should be generated. This function
+ decodes *TEXT and potentially generates a warning message as outlined
+ below.
+
+ Example for 'set endian big' which has a fictitious alias 'seb'.
+
+ If alias wasn't used in *TEXT, and the command is deprecated:
+ "warning: 'set endian big' is deprecated."
+
+ If alias was used, and only the alias is deprecated:
+ "warning: 'seb' an alias for the command 'set endian big' is deprecated."
+
+ If alias was used and command is deprecated (regardless of whether the
+ alias itself is deprecated:
+
+ "warning: 'set endian big' (seb) is deprecated."
+
+ After the message has been sent, clear the appropriate flags in the
+ command and/or the alias so the user is no longer bothered.
+
+*/
+void
+deprecated_cmd_warning (char **text)
+{
+ struct cmd_list_element *alias = NULL;
+ struct cmd_list_element *prefix_cmd = NULL;
+ struct cmd_list_element *cmd = NULL;
+ struct cmd_list_element *c;
+ char *type;
+
+ if (!lookup_cmd_composition (*text, &alias, &prefix_cmd, &cmd))
+ /* return if text doesn't evaluate to a command */
+ return;
+
+ if (!((alias ? (alias->flags & DEPRECATED_WARN_USER) : 0)
+ || (cmd->flags & DEPRECATED_WARN_USER) ) )
+ /* return if nothing is deprecated */
+ return;
+
+ printf_filtered ("Warning:");
+
+ if (alias && !(cmd->flags & CMD_DEPRECATED))
+ printf_filtered (" '%s', an alias for the", alias->name);
+
+ printf_filtered (" command '");
+
+ if (prefix_cmd)
+ printf_filtered ("%s", prefix_cmd->prefixname);
+
+ printf_filtered ("%s", cmd->name);
+
+ if (alias && (cmd->flags & CMD_DEPRECATED))
+ printf_filtered ("' (%s) is deprecated.\n", alias->name);
+ else
+ printf_filtered ("' is deprecated.\n");
+
+
+ /* if it is only the alias that is deprecated, we want to indicate the
+ new alias, otherwise we'll indicate the new command */
+
+ if (alias && !(cmd->flags & CMD_DEPRECATED))
+ {
+ if (alias->replacement)
+ printf_filtered ("Use '%s'.\n\n", alias->replacement);
+ else
+ printf_filtered ("No alternative known.\n\n");
+ }
+ else
+ {
+ if (cmd->replacement)
+ printf_filtered ("Use '%s'.\n\n", cmd->replacement);
+ else
+ printf_filtered ("No alternative known.\n\n");
+ }
+
+ /* We've warned you, now we'll keep quiet */
+ if (alias)
+ alias->flags &= ~DEPRECATED_WARN_USER;
+
+ cmd->flags &= ~DEPRECATED_WARN_USER;
+}
+
+
+
+/* Look up the contents of LINE as a command in the command list 'cmdlist'.
+ Return 1 on success, 0 on failure.
+
+ If LINE refers to an alias, *alias will point to that alias.
+
+ If LINE is a postfix command (i.e. one that is preceeded by a prefix
+ command) set *prefix_cmd.
+
+ Set *cmd to point to the command LINE indicates.
+
+ If any of *alias, *prefix_cmd, or *cmd cannot be determined or do not
+ exist, they are NULL when we return.
+
+*/
+int
+lookup_cmd_composition (char *text,
+ struct cmd_list_element **alias,
+ struct cmd_list_element **prefix_cmd,
+ struct cmd_list_element **cmd)
+{
+ char *p, *command;
+ int len, tmp, nfound;
+ struct cmd_list_element *cur_list;
+ struct cmd_list_element *prev_cmd;
+ *alias = NULL;
+ *prefix_cmd = NULL;
+ *cmd = NULL;
+
+ cur_list = cmdlist;
+
+ while (1)
+ {
+ /* Go through as many command lists as we need to
+ to find the command TEXT refers to. */
+
+ prev_cmd = *cmd;
+
+ while (*text == ' ' || *text == '\t')
+ (text)++;
+
+ /* Treating underscores as part of command words is important
+ so that "set args_foo()" doesn't get interpreted as
+ "set args _foo()". */
+ for (p = text;
+ *p && (isalnum (*p) || *p == '-' || *p == '_' ||
+ (tui_version &&
+ (*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||
+ (xdb_commands && (*p == '!' || *p == '/' || *p == '?')));
+ p++)
+ ;
+
+ /* If nothing but whitespace, return. */
+ if (p == text)
+ return 0;
+
+ len = p - text;
+
+ /* text and p now bracket the first command word to lookup (and
+ it's length is len). We copy this into a local temporary */
+
+ command = (char *) alloca (len + 1);
+ for (tmp = 0; tmp < len; tmp++)
+ {
+ char x = text[tmp];
+ command[tmp] = x;
+ }
+ command[len] = '\0';
+
+ /* Look it up. */
+ *cmd = 0;
+ nfound = 0;
+ *cmd = find_cmd (command, len, cur_list, 1, &nfound);
+
+ /* We didn't find the command in the entered case, so lower case it
+ and search again.
+ */
+ if (!*cmd || nfound == 0)
+ {
+ for (tmp = 0; tmp < len; tmp++)
+ {
+ char x = command[tmp];
+ command[tmp] = isupper (x) ? tolower (x) : x;
+ }
+ *cmd = find_cmd (command, len, cur_list, 1, &nfound);
+ }
+
+ if (*cmd == (struct cmd_list_element *) -1)
+ {
+ return 0; /* ambiguous */
+ }
+
+ if (*cmd == NULL)
+ return 0; /* nothing found */
+ else
+ {
+ if ((*cmd)->cmd_pointer)
+ {
+ /* cmd was actually an alias, we note that an alias was used
+ (by assigning *alais) and we set *cmd.
+ */
+ *alias = *cmd;
+ *cmd = (*cmd)->cmd_pointer;
+ }
+ *prefix_cmd = prev_cmd;
+ }
+ if ((*cmd)->prefixlist)
+ cur_list = *(*cmd)->prefixlist;
+ else
+ return 1;
+
+ text = p;
+ }
+}
+
+/* Helper function for SYMBOL_COMPLETION_FUNCTION. */
+
+/* Return a vector of char pointers which point to the different
+ possible completions in LIST of TEXT.
+
+ WORD points in the same buffer as TEXT, and completions should be
+ returned relative to this position. For example, suppose TEXT is "foo"
+ and we want to complete to "foobar". If WORD is "oo", return
+ "oobar"; if WORD is "baz/foo", return "baz/foobar". */
+
+char **
+complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
+{
+ struct cmd_list_element *ptr;
+ char **matchlist;
+ int sizeof_matchlist;
+ int matches;
+ int textlen = strlen (text);
+
+ sizeof_matchlist = 10;
+ matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
+ matches = 0;
+
+ for (ptr = list; ptr; ptr = ptr->next)
+ if (!strncmp (ptr->name, text, textlen)
+ && !ptr->abbrev_flag
+ && (ptr->func
+ || ptr->prefixlist))
+ {
+ if (matches == sizeof_matchlist)
+ {
+ sizeof_matchlist *= 2;
+ matchlist = (char **) xrealloc ((char *) matchlist,
+ (sizeof_matchlist
+ * sizeof (char *)));
+ }
+
+ matchlist[matches] = (char *)
+ xmalloc (strlen (word) + strlen (ptr->name) + 1);
+ if (word == text)
+ strcpy (matchlist[matches], ptr->name);
+ else if (word > text)
+ {
+ /* Return some portion of ptr->name. */
+ strcpy (matchlist[matches], ptr->name + (word - text));
+ }
+ else
+ {
+ /* Return some of text plus ptr->name. */
+ strncpy (matchlist[matches], word, text - word);
+ matchlist[matches][text - word] = '\0';
+ strcat (matchlist[matches], ptr->name);
+ }
+ ++matches;
+ }
+
+ if (matches == 0)
+ {
+ xfree (matchlist);
+ matchlist = 0;
+ }
+ else
+ {
+ matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
+ * sizeof (char *)));
+ matchlist[matches] = (char *) 0;
+ }
+
+ return matchlist;
+}
+
+/* Helper function for SYMBOL_COMPLETION_FUNCTION. */
+
+/* Return a vector of char pointers which point to the different
+ possible completions in CMD of TEXT.
+
+ WORD points in the same buffer as TEXT, and completions should be
+ returned relative to this position. For example, suppose TEXT is "foo"
+ and we want to complete to "foobar". If WORD is "oo", return
+ "oobar"; if WORD is "baz/foo", return "baz/foobar". */
+
+char **
+complete_on_enum (const char *enumlist[],
+ char *text,
+ char *word)
+{
+ char **matchlist;
+ int sizeof_matchlist;
+ int matches;
+ int textlen = strlen (text);
+ int i;
+ const char *name;
+
+ sizeof_matchlist = 10;
+ matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
+ matches = 0;
+
+ for (i = 0; (name = enumlist[i]) != NULL; i++)
+ if (strncmp (name, text, textlen) == 0)
+ {
+ if (matches == sizeof_matchlist)
+ {
+ sizeof_matchlist *= 2;
+ matchlist = (char **) xrealloc ((char *) matchlist,
+ (sizeof_matchlist
+ * sizeof (char *)));
+ }
+
+ matchlist[matches] = (char *)
+ xmalloc (strlen (word) + strlen (name) + 1);
+ if (word == text)
+ strcpy (matchlist[matches], name);
+ else if (word > text)
+ {
+ /* Return some portion of name. */
+ strcpy (matchlist[matches], name + (word - text));
+ }
+ else
+ {
+ /* Return some of text plus name. */
+ strncpy (matchlist[matches], word, text - word);
+ matchlist[matches][text - word] = '\0';
+ strcat (matchlist[matches], name);
+ }
+ ++matches;
+ }
+
+ if (matches == 0)
+ {
+ xfree (matchlist);
+ matchlist = 0;
+ }
+ else
+ {
+ matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
+ * sizeof (char *)));
+ matchlist[matches] = (char *) 0;
+ }
+
+ return matchlist;
+}
+
diff --git a/gdb/cli/cli-decode.h b/gdb/cli/cli-decode.h
new file mode 100644
index 00000000000..72436f04657
--- /dev/null
+++ b/gdb/cli/cli-decode.h
@@ -0,0 +1,334 @@
+/* Header file for GDB command decoding library.
+ Copyright 2000 Free Software Foundation, Inc.
+
+ 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. */
+
+#if !defined (CLI_DECODE_H)
+#define CLI_DECODE_H 1
+
+#include "gdb_regex.h" /* Needed by apropos_cmd. */
+#include "command.h"
+
+#if 0
+/* FIXME: cagney/2002-03-17: Once cmd_type() has been removed, ``enum
+ cmd_types'' can be moved from "command.h" to "cli-decode.h". */
+/* Not a set/show command. Note that some commands which begin with
+ "set" or "show" might be in this category, if their syntax does
+ not fall into one of the following categories. */
+typedef enum cmd_types
+ {
+ not_set_cmd,
+ set_cmd,
+ show_cmd
+ }
+cmd_types;
+#endif
+
+/* This structure records one command'd definition. */
+
+
+/* This flag is used by the code executing commands to warn the user
+ the first time a deprecated command is used, see the 'flags' field in
+ the following struct.
+*/
+#define CMD_DEPRECATED 0x1
+#define DEPRECATED_WARN_USER 0x2
+#define MALLOCED_REPLACEMENT 0x4
+
+struct cmd_list_element
+ {
+ /* Points to next command in this list. */
+ struct cmd_list_element *next;
+
+ /* Name of this command. */
+ char *name;
+
+ /* Command class; class values are chosen by application program. */
+ enum command_class class;
+
+ /* Function definition of this command. NULL for command class
+ names and for help topics that are not really commands. NOTE:
+ cagney/2002-02-02: This function signature is evolving. For
+ the moment suggest sticking with either set_cmd_cfunc() or
+ set_cmd_sfunc(). */
+ void (*func) (struct cmd_list_element *c, char *args, int from_tty);
+ /* The command's real callback. At present func() bounces through
+ to one of the below. */
+ union
+ {
+ /* If type is not_set_cmd, call it like this: */
+ void (*cfunc) (char *args, int from_tty);
+
+ /* If type is set_cmd or show_cmd, first set the variables, and
+ then call this. */
+ void (*sfunc) (char *args, int from_tty, struct cmd_list_element * c);
+ }
+ function;
+
+ /* Local state (context) for this command. This can be anything. */
+ void *context;
+
+ /* Documentation of this command (or help topic).
+ First line is brief documentation; remaining lines form, with it,
+ the full documentation. First line should end with a period.
+ Entire string should also end with a period, not a newline. */
+ char *doc;
+
+ /* flags : a bitfield
+
+ bit 0: (LSB) CMD_DEPRECATED, when 1 indicated that this command
+ is deprecated. It may be removed from gdb's command set in the
+ future.
+
+ bit 1: DEPRECATED_WARN_USER, the user needs to be warned that
+ this is a deprecated command. The user should only be warned
+ the first time a command is used.
+
+ bit 2: MALLOCED_REPLACEMENT, when functions are deprecated at
+ compile time (this is the way it should, in general, be done)
+ the memory containing the replacement string is statically
+ allocated. In some cases it makes sense to deprecate commands
+ at runtime (the testsuite is one example). In this case the
+ memory for replacement is malloc'ed. When a command is
+ undeprecated or re-deprecated at runtime we don't want to risk
+ calling free on statically allocated memory, so we check this
+ flag.
+ */
+ int flags;
+
+ /* if this command is deprecated, this is the replacement name */
+ char *replacement;
+
+ /* If this command represents a show command, then this function
+ is called before the variable's value is examined. */
+ void (*pre_show_hook) (struct cmd_list_element *c);
+
+ /* Hook for another command to be executed before this command. */
+ struct cmd_list_element *hook_pre;
+
+ /* Hook for another command to be executed after this command. */
+ struct cmd_list_element *hook_post;
+
+ /* Flag that specifies if this command is already running it's hook. */
+ /* Prevents the possibility of hook recursion. */
+ int hook_in;
+
+ /* Nonzero identifies a prefix command. For them, the address
+ of the variable containing the list of subcommands. */
+ struct cmd_list_element **prefixlist;
+
+ /* For prefix commands only:
+ String containing prefix commands to get here: this one
+ plus any others needed to get to it. Should end in a space.
+ It is used before the word "command" in describing the
+ commands reached through this prefix. */
+ char *prefixname;
+
+ /* For prefix commands only:
+ nonzero means do not get an error if subcommand is not
+ recognized; call the prefix's own function in that case. */
+ char allow_unknown;
+
+ /* Nonzero says this is an abbreviation, and should not
+ be mentioned in lists of commands.
+ This allows "br<tab>" to complete to "break", which it
+ otherwise wouldn't. */
+ char abbrev_flag;
+
+ /* Completion routine for this command. TEXT is the text beyond
+ what was matched for the command itself (leading whitespace is
+ skipped). It stops where we are supposed to stop completing
+ (rl_point) and is '\0' terminated.
+
+ Return value is a malloc'd vector of pointers to possible completions
+ terminated with NULL. If there are no completions, returning a pointer
+ to a NULL would work but returning NULL itself is also valid.
+ WORD points in the same buffer as TEXT, and completions should be
+ returned relative to this position. For example, suppose TEXT is "foo"
+ and we want to complete to "foobar". If WORD is "oo", return
+ "oobar"; if WORD is "baz/foo", return "baz/foobar". */
+ char **(*completer) (char *text, char *word);
+
+ /* Type of "set" or "show" command (or SET_NOT_SET if not "set"
+ or "show"). */
+ cmd_types type;
+
+ /* Pointer to variable affected by "set" and "show". Doesn't matter
+ if type is not_set. */
+ void *var;
+
+ /* What kind of variable is *VAR? */
+ var_types var_type;
+
+ /* Pointer to NULL terminated list of enumerated values (like argv). */
+ const char **enums;
+
+ /* Pointer to command strings of user-defined commands */
+ struct command_line *user_commands;
+
+ /* Pointer to command that is hooked by this one, (by hook_pre)
+ so the hook can be removed when this one is deleted. */
+ struct cmd_list_element *hookee_pre;
+
+ /* Pointer to command that is hooked by this one, (by hook_post)
+ so the hook can be removed when this one is deleted. */
+ struct cmd_list_element *hookee_post;
+
+ /* Pointer to command that is aliased by this one, so the
+ aliased command can be located in case it has been hooked. */
+ struct cmd_list_element *cmd_pointer;
+ };
+
+/* API to the manipulation of command lists. */
+
+extern struct cmd_list_element *add_cmd (char *, enum command_class,
+ void (*fun) (char *, int), char *,
+ struct cmd_list_element **);
+
+extern struct cmd_list_element *add_alias_cmd (char *, char *,
+ enum command_class, int,
+ struct cmd_list_element **);
+
+extern struct cmd_list_element *add_prefix_cmd (char *, enum command_class,
+ void (*fun) (char *, int),
+ char *,
+ struct cmd_list_element **,
+ char *, int,
+ struct cmd_list_element **);
+
+extern struct cmd_list_element *add_abbrev_prefix_cmd (char *,
+ enum command_class,
+ void (*fun) (char *,
+ int),
+ char *,
+ struct cmd_list_element
+ **, char *, int,
+ struct cmd_list_element
+ **);
+
+/* Set the commands corresponding callback. */
+
+extern void set_cmd_cfunc (struct cmd_list_element *cmd,
+ void (*cfunc) (char *args, int from_tty));
+
+extern void set_cmd_sfunc (struct cmd_list_element *cmd,
+ void (*sfunc) (char *args, int from_tty,
+ struct cmd_list_element * c));
+
+extern void set_cmd_completer (struct cmd_list_element *cmd,
+ char **(*completer) (char *text, char *word));
+
+/* HACK: cagney/2002-02-23: Code, mostly in tracepoints.c, grubs
+ around in cmd objects to test the value of the commands sfunc(). */
+extern int cmd_cfunc_eq (struct cmd_list_element *cmd,
+ void (*cfunc) (char *args, int from_tty));
+
+/* Access to the command's local context. */
+extern void set_cmd_context (struct cmd_list_element *cmd, void *context);
+extern void *get_cmd_context (struct cmd_list_element *cmd);
+
+extern struct cmd_list_element *lookup_cmd (char **,
+ struct cmd_list_element *, char *,
+ int, int);
+
+extern struct cmd_list_element *lookup_cmd_1 (char **,
+ struct cmd_list_element *,
+ struct cmd_list_element **,
+ int);
+
+extern struct cmd_list_element *
+ deprecate_cmd (struct cmd_list_element *, char * );
+
+extern void
+ deprecated_cmd_warning (char **);
+
+extern int
+ lookup_cmd_composition (char *text,
+ struct cmd_list_element **alias,
+ struct cmd_list_element **prefix_cmd,
+ struct cmd_list_element **cmd);
+
+extern struct cmd_list_element *add_com (char *, enum command_class,
+ void (*fun) (char *, int), char *);
+
+extern struct cmd_list_element *add_com_alias (char *, char *,
+ enum command_class, int);
+
+extern struct cmd_list_element *add_info (char *, void (*fun) (char *, int),
+ char *);
+
+extern struct cmd_list_element *add_info_alias (char *, char *, int);
+
+extern char **complete_on_cmdlist (struct cmd_list_element *, char *, char *);
+
+extern char **complete_on_enum (const char *enumlist[], char *, char *);
+
+extern void delete_cmd (char *, struct cmd_list_element **);
+
+extern void help_cmd_list (struct cmd_list_element *, enum command_class,
+ char *, int, struct ui_file *);
+
+extern struct cmd_list_element *add_set_cmd (char *name, enum
+ command_class class,
+ var_types var_type, void *var,
+ char *doc,
+ struct cmd_list_element **list);
+
+extern struct cmd_list_element *add_set_enum_cmd (char *name,
+ enum command_class class,
+ const char *enumlist[],
+ const char **var,
+ char *doc,
+ struct cmd_list_element **list);
+
+extern struct cmd_list_element *add_set_auto_boolean_cmd (char *name,
+ enum command_class class,
+ enum cmd_auto_boolean *var,
+ char *doc,
+ struct cmd_list_element **list);
+
+extern struct cmd_list_element *add_set_boolean_cmd (char *name,
+ enum command_class class,
+ int *var,
+ char *doc,
+ struct cmd_list_element **list);
+
+extern struct cmd_list_element *add_show_from_set (struct cmd_list_element *,
+ struct cmd_list_element
+ **);
+
+/* Functions that implement commands about CLI commands. */
+
+extern void help_cmd (char *, struct ui_file *);
+
+extern void help_list (struct cmd_list_element *, char *,
+ enum command_class, struct ui_file *);
+
+extern void apropos_cmd (struct ui_file *, struct cmd_list_element *,
+ struct re_pattern_buffer *, char *);
+
+/* Used to mark commands that don't do anything. If we just leave the
+ function field NULL, the command is interpreted as a help topic, or
+ as a class of commands. */
+
+extern void not_just_help_class_command (char *arg, int from_tty);
+
+/* Exported to cli/cli-setshow.c */
+
+extern void print_doc_line (struct ui_file *, char *);
+
+
+#endif /* !defined (CLI_DECODE_H) */
diff --git a/gdb/cli/cli-dump.c b/gdb/cli/cli-dump.c
new file mode 100644
index 00000000000..36c1d2db2be
--- /dev/null
+++ b/gdb/cli/cli-dump.c
@@ -0,0 +1,821 @@
+/* Dump-to-file commands, for GDB, the GNU debugger.
+
+ Copyright 2002 Free Software Foundation, Inc.
+
+ Contributed by Red Hat.
+
+ 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 "defs.h"
+#include "gdb_string.h"
+#include "cli/cli-decode.h"
+#include "cli/cli-cmds.h"
+#include "value.h"
+#include "completer.h"
+#include "cli/cli-dump.h"
+#include "gdb_assert.h"
+#include <ctype.h>
+#include "target.h"
+
+#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
+
+
+char *
+skip_spaces (char *chp)
+{
+ if (chp == NULL)
+ return NULL;
+ while (isspace (*chp))
+ chp++;
+ return chp;
+}
+
+char *
+scan_expression_with_cleanup (char **cmd, const char *def)
+{
+ if ((*cmd) == NULL || (**cmd) == '\0')
+ {
+ char *exp = xstrdup (def);
+ make_cleanup (xfree, exp);
+ return exp;
+ }
+ else
+ {
+ char *exp;
+ char *end;
+
+ end = (*cmd) + strcspn (*cmd, " \t");
+ exp = savestring ((*cmd), end - (*cmd));
+ make_cleanup (xfree, exp);
+ (*cmd) = skip_spaces (end);
+ return exp;
+ }
+}
+
+
+static void
+do_fclose_cleanup (void *arg)
+{
+ FILE *file = arg;
+ fclose (arg);
+}
+
+static struct cleanup *
+make_cleanup_fclose (FILE *file)
+{
+ return make_cleanup (do_fclose_cleanup, file);
+}
+
+char *
+scan_filename_with_cleanup (char **cmd, const char *defname)
+{
+ char *filename;
+ char *fullname;
+
+ /* FIXME: Need to get the ``/a(ppend)'' flag from somewhere. */
+
+ /* File. */
+ if ((*cmd) == NULL)
+ {
+ if (defname == NULL)
+ error ("Missing filename.");
+ filename = xstrdup (defname);
+ make_cleanup (xfree, filename);
+ }
+ else
+ {
+ /* FIXME: should parse a possibly quoted string. */
+ char *end;
+
+ (*cmd) = skip_spaces (*cmd);
+ end = *cmd + strcspn (*cmd, " \t");
+ filename = savestring ((*cmd), end - (*cmd));
+ make_cleanup (xfree, filename);
+ (*cmd) = skip_spaces (end);
+ }
+ gdb_assert (filename != NULL);
+
+ fullname = tilde_expand (filename);
+ make_cleanup (xfree, fullname);
+
+ return fullname;
+}
+
+FILE *
+fopen_with_cleanup (char *filename, const char *mode)
+{
+ FILE *file = fopen (filename, mode);
+ if (file == NULL)
+ perror_with_name (filename);
+ make_cleanup_fclose (file);
+ return file;
+}
+
+static bfd *
+bfd_openr_with_cleanup (const char *filename, const char *target)
+{
+ bfd *ibfd;
+
+ if ((ibfd = bfd_openr (filename, target)) == NULL)
+ error ("Failed to open %s: %s.", filename,
+ bfd_errmsg (bfd_get_error ()));
+
+ make_cleanup_bfd_close (ibfd);
+ if (!bfd_check_format (ibfd, bfd_object))
+ error ("'%s' is not a recognized file format.", filename);
+
+ return ibfd;
+}
+
+static bfd *
+bfd_openw_with_cleanup (char *filename, const char *target, char *mode)
+{
+ bfd *obfd;
+
+ if (*mode == 'w') /* Write: create new file */
+ {
+ if ((obfd = bfd_openw (filename, target)) == NULL)
+ error ("Failed to open %s: %s.", filename,
+ bfd_errmsg (bfd_get_error ()));
+ make_cleanup_bfd_close (obfd);
+ if (!bfd_set_format (obfd, bfd_object))
+ error ("bfd_openw_with_cleanup: %s.", bfd_errmsg (bfd_get_error ()));
+ }
+ else if (*mode == 'a') /* Append to existing file */
+ { /* FIXME -- doesn't work... */
+ error ("bfd_openw does not work with append.");
+ }
+ else
+ error ("bfd_openw_with_cleanup: unknown mode %s.", mode);
+
+ return obfd;
+}
+
+struct cmd_list_element *dump_cmdlist;
+struct cmd_list_element *append_cmdlist;
+struct cmd_list_element *srec_cmdlist;
+struct cmd_list_element *ihex_cmdlist;
+struct cmd_list_element *tekhex_cmdlist;
+struct cmd_list_element *binary_dump_cmdlist;
+struct cmd_list_element *binary_append_cmdlist;
+
+static void
+dump_command (char *cmd, int from_tty)
+{
+ printf_unfiltered ("\"dump\" must be followed by a subcommand.\n\n");
+ help_list (dump_cmdlist, "dump ", -1, gdb_stdout);
+}
+
+static void
+append_command (char *cmd, int from_tty)
+{
+ printf_unfiltered ("\"append\" must be followed by a subcommand.\n\n");
+ help_list (dump_cmdlist, "append ", -1, gdb_stdout);
+}
+
+static void
+dump_binary_file (char *filename, char *mode,
+ char *buf, int len)
+{
+ FILE *file;
+ int status;
+
+ file = fopen_with_cleanup (filename, mode);
+ status = fwrite (buf, len, 1, file);
+ if (status != 1)
+ perror_with_name (filename);
+}
+
+static void
+dump_bfd_file (char *filename, char *mode,
+ char *target, CORE_ADDR vaddr,
+ char *buf, int len)
+{
+ bfd *obfd;
+ asection *osection;
+
+ obfd = bfd_openw_with_cleanup (filename, target, mode);
+ osection = bfd_make_section_anyway (obfd, ".newsec");
+ bfd_set_section_size (obfd, osection, len);
+ bfd_set_section_vma (obfd, osection, vaddr);
+ bfd_set_section_alignment (obfd, osection, 0);
+ bfd_set_section_flags (obfd, osection, 0x203);
+ osection->entsize = 0;
+ bfd_set_section_contents (obfd, osection, buf, 0, len);
+}
+
+static void
+dump_memory_to_file (char *cmd, char *mode, char *file_format)
+{
+ struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);
+ CORE_ADDR lo;
+ CORE_ADDR hi;
+ ULONGEST count;
+ char *filename;
+ void *buf;
+ char *lo_exp;
+ char *hi_exp;
+ int len;
+
+ /* Open the file. */
+ filename = scan_filename_with_cleanup (&cmd, NULL);
+
+ /* Find the low address. */
+ if (cmd == NULL || *cmd == '\0')
+ error ("Missing start address.");
+ lo_exp = scan_expression_with_cleanup (&cmd, NULL);
+
+ /* Find the second address - rest of line. */
+ if (cmd == NULL || *cmd == '\0')
+ error ("Missing stop address.");
+ hi_exp = cmd;
+
+ lo = parse_and_eval_address (lo_exp);
+ hi = parse_and_eval_address (hi_exp);
+ if (hi <= lo)
+ error ("Invalid memory address range (start >= end).");
+ count = hi - lo;
+
+ /* FIXME: Should use read_memory_partial() and a magic blocking
+ value. */
+ buf = xmalloc (count);
+ make_cleanup (xfree, buf);
+ target_read_memory (lo, buf, count);
+
+ /* Have everything. Open/write the data. */
+ if (file_format == NULL || strcmp (file_format, "binary") == 0)
+ {
+ dump_binary_file (filename, mode, buf, count);
+ }
+ else
+ {
+ dump_bfd_file (filename, mode, file_format, lo, buf, count);
+ }
+
+ do_cleanups (old_cleanups);
+}
+
+static void
+dump_memory_command (char *cmd, char *mode)
+{
+ dump_memory_to_file (cmd, mode, "binary");
+}
+
+static void
+dump_value_to_file (char *cmd, char *mode, char *file_format)
+{
+ struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);
+ struct value *val;
+ char *filename;
+
+ /* Open the file. */
+ filename = scan_filename_with_cleanup (&cmd, NULL);
+
+ /* Find the value. */
+ if (cmd == NULL || *cmd == '\0')
+ error ("No value to %s.", *mode == 'a' ? "append" : "dump");
+ val = parse_and_eval (cmd);
+ if (val == NULL)
+ error ("Invalid expression.");
+
+ /* Have everything. Open/write the data. */
+ if (file_format == NULL || strcmp (file_format, "binary") == 0)
+ {
+ dump_binary_file (filename, mode, VALUE_CONTENTS (val),
+ TYPE_LENGTH (VALUE_TYPE (val)));
+ }
+ else
+ {
+ CORE_ADDR vaddr;
+
+ if (VALUE_LVAL (val))
+ {
+ vaddr = VALUE_ADDRESS (val);
+ }
+ else
+ {
+ vaddr = 0;
+ warning ("value is not an lval: address assumed to be zero");
+ }
+
+ dump_bfd_file (filename, mode, file_format, vaddr,
+ VALUE_CONTENTS (val),
+ TYPE_LENGTH (VALUE_TYPE (val)));
+ }
+
+ do_cleanups (old_cleanups);
+}
+
+static void
+dump_value_command (char *cmd, char *mode)
+{
+ dump_value_to_file (cmd, mode, "binary");
+}
+
+static void
+dump_filetype (char *cmd, char *mode, char *filetype)
+{
+ char *suffix = cmd;
+
+ if (cmd == NULL || *cmd == '\0')
+ error ("Missing subcommand: try 'help %s %s'.",
+ mode[0] == 'a' ? "append" : "dump",
+ filetype);
+
+ suffix += strcspn (cmd, " \t");
+
+ if (suffix != cmd)
+ {
+ if (strncmp ("memory", cmd, suffix - cmd) == 0)
+ {
+ dump_memory_to_file (suffix, mode, filetype);
+ return;
+ }
+ else if (strncmp ("value", cmd, suffix - cmd) == 0)
+ {
+ dump_value_to_file (suffix, mode, filetype);
+ return;
+ }
+ }
+
+ error ("dump %s: unknown subcommand '%s' -- try 'value' or 'memory'.",
+ filetype, cmd);
+}
+
+static void
+dump_srec_memory (char *args, int from_tty)
+{
+ dump_memory_to_file (args, "w", "srec");
+}
+
+static void
+dump_srec_value (char *args, int from_tty)
+{
+ dump_value_to_file (args, "w", "srec");
+}
+
+static void
+dump_ihex_memory (char *args, int from_tty)
+{
+ dump_memory_to_file (args, "w", "ihex");
+}
+
+static void
+dump_ihex_value (char *args, int from_tty)
+{
+ dump_value_to_file (args, "w", "ihex");
+}
+
+static void
+dump_tekhex_memory (char *args, int from_tty)
+{
+ dump_memory_to_file (args, "w", "tekhex");
+}
+
+static void
+dump_tekhex_value (char *args, int from_tty)
+{
+ dump_value_to_file (args, "w", "tekhex");
+}
+
+static void
+dump_binary_memory (char *args, int from_tty)
+{
+ dump_memory_to_file (args, "w", "binary");
+}
+
+static void
+dump_binary_value (char *args, int from_tty)
+{
+ dump_value_to_file (args, "w", "binary");
+}
+
+static void
+append_binary_memory (char *args, int from_tty)
+{
+ dump_memory_to_file (args, "a", "binary");
+}
+
+static void
+append_binary_value (char *args, int from_tty)
+{
+ dump_value_to_file (args, "a", "binary");
+}
+
+struct dump_context
+{
+ void (*func) (char *cmd, char *mode);
+ char *mode;
+};
+
+static void
+call_dump_func (struct cmd_list_element *c, char *args, int from_tty)
+{
+ struct dump_context *d = get_cmd_context (c);
+ d->func (args, d->mode);
+}
+
+void
+add_dump_command (char *name, void (*func) (char *args, char *mode),
+ char *descr)
+
+{
+ struct cmd_list_element *c;
+ struct dump_context *d;
+
+ c = add_cmd (name, all_commands, NULL, descr, &dump_cmdlist);
+ c->completer = filename_completer;
+ d = XMALLOC (struct dump_context);
+ d->func = func;
+ d->mode = "w";
+ set_cmd_context (c, d);
+ c->func = call_dump_func;
+
+ c = add_cmd (name, all_commands, NULL, descr, &append_cmdlist);
+ c->completer = filename_completer;
+ d = XMALLOC (struct dump_context);
+ d->func = func;
+ d->mode = "a";
+ set_cmd_context (c, d);
+ c->func = call_dump_func;
+
+ /* Replace "Dump " at start of docstring with "Append "
+ (borrowed from add_show_from_set). */
+ if ( c->doc[0] == 'W'
+ && c->doc[1] == 'r'
+ && c->doc[2] == 'i'
+ && c->doc[3] == 't'
+ && c->doc[4] == 'e'
+ && c->doc[5] == ' ')
+ c->doc = concat ("Append ", c->doc + 6, NULL);
+}
+
+/* Opaque data for restore_section_callback. */
+struct callback_data {
+ unsigned long load_offset;
+ CORE_ADDR load_start;
+ CORE_ADDR load_end;
+};
+
+/* Function: restore_section_callback.
+
+ Callback function for bfd_map_over_sections.
+ Selectively loads the sections into memory. */
+
+static void
+restore_section_callback (bfd *ibfd, asection *isec, void *args)
+{
+ struct callback_data *data = args;
+ bfd_vma sec_start = bfd_section_vma (ibfd, isec);
+ bfd_size_type size = bfd_section_size (ibfd, isec);
+ bfd_vma sec_end = sec_start + size;
+ bfd_size_type sec_offset = 0;
+ bfd_size_type sec_load_count = size;
+ struct cleanup *old_chain;
+ char *buf;
+ int ret;
+
+ /* Ignore non-loadable sections, eg. from elf files. */
+ if (!(bfd_get_section_flags (ibfd, isec) & SEC_LOAD))
+ return;
+
+ /* Does the section overlap with the desired restore range? */
+ if (sec_end <= data->load_start
+ || (data->load_end > 0 && sec_start >= data->load_end))
+ {
+ /* No, no useable data in this section. */
+ printf_filtered ("skipping section %s...\n",
+ bfd_section_name (ibfd, isec));
+ return;
+ }
+
+ /* Compare section address range with user-requested
+ address range (if any). Compute where the actual
+ transfer should start and end. */
+ if (sec_start < data->load_start)
+ sec_offset = data->load_start - sec_start;
+ /* Size of a partial transfer: */
+ sec_load_count -= sec_offset;
+ if (data->load_end > 0 && sec_end > data->load_end)
+ sec_load_count -= sec_end - data->load_end;
+
+ /* Get the data. */
+ buf = xmalloc (size);
+ old_chain = make_cleanup (xfree, buf);
+ if (!bfd_get_section_contents (ibfd, isec, buf, 0, size))
+ error ("Failed to read bfd file %s: '%s'.", bfd_get_filename (ibfd),
+ bfd_errmsg (bfd_get_error ()));
+
+ printf_filtered ("Restoring section %s (0x%lx to 0x%lx)",
+ bfd_section_name (ibfd, isec),
+ (unsigned long) sec_start,
+ (unsigned long) sec_end);
+
+ if (data->load_offset != 0 || data->load_start != 0 || data->load_end != 0)
+ printf_filtered (" into memory (0x%s to 0x%s)\n",
+ paddr_nz ((unsigned long) sec_start
+ + sec_offset + data->load_offset),
+ paddr_nz ((unsigned long) sec_start + sec_offset
+ + data->load_offset + sec_load_count));
+ else
+ puts_filtered ("\n");
+
+ /* Write the data. */
+ ret = target_write_memory (sec_start + sec_offset + data->load_offset,
+ buf + sec_offset, sec_load_count);
+ if (ret != 0)
+ warning ("restore: memory write failed (%s).", safe_strerror (ret));
+ do_cleanups (old_chain);
+ return;
+}
+
+static void
+restore_binary_file (char *filename, struct callback_data *data)
+{
+ FILE *file = fopen_with_cleanup (filename, "r");
+ int status;
+ char *buf;
+ long len;
+
+ /* Get the file size for reading. */
+ if (fseek (file, 0, SEEK_END) == 0)
+ len = ftell (file);
+ else
+ perror_with_name (filename);
+
+ if (len <= data->load_start)
+ error ("Start address is greater than length of binary file %s.",
+ filename);
+
+ /* Chop off "len" if it exceeds the requested load_end addr. */
+ if (data->load_end != 0 && data->load_end < len)
+ len = data->load_end;
+ /* Chop off "len" if the requested load_start addr skips some bytes. */
+ if (data->load_start > 0)
+ len -= data->load_start;
+
+ printf_filtered
+ ("Restoring binary file %s into memory (0x%lx to 0x%lx)\n",
+ filename,
+ (unsigned long) data->load_start + data->load_offset,
+ (unsigned long) data->load_start + data->load_offset + len);
+
+ /* Now set the file pos to the requested load start pos. */
+ if (fseek (file, data->load_start, SEEK_SET) != 0)
+ perror_with_name (filename);
+
+ /* Now allocate a buffer and read the file contents. */
+ buf = xmalloc (len);
+ make_cleanup (xfree, buf);
+ if (fread (buf, 1, len, file) != len)
+ perror_with_name (filename);
+
+ /* Now write the buffer into target memory. */
+ len = target_write_memory (data->load_start + data->load_offset, buf, len);
+ if (len != 0)
+ warning ("restore: memory write failed (%s).", safe_strerror (len));
+ return;
+}
+
+static void
+restore_command (char *args, int from_tty)
+{
+ char *filename;
+ struct callback_data data;
+ bfd *ibfd;
+ int binary_flag = 0;
+
+ if (!target_has_execution)
+ noprocess ();
+
+ data.load_offset = 0;
+ data.load_start = 0;
+ data.load_end = 0;
+
+ /* Parse the input arguments. First is filename (required). */
+ filename = scan_filename_with_cleanup (&args, NULL);
+ if (args != NULL && *args != '\0')
+ {
+ char *binary_string = "binary";
+
+ /* Look for optional "binary" flag. */
+ if (strncmp (args, binary_string, strlen (binary_string)) == 0)
+ {
+ binary_flag = 1;
+ args += strlen (binary_string);
+ args = skip_spaces (args);
+ }
+ /* Parse offset (optional). */
+ if (args != NULL && *args != '\0')
+ data.load_offset =
+ parse_and_eval_long (scan_expression_with_cleanup (&args, NULL));
+ if (args != NULL && *args != '\0')
+ {
+ /* Parse start address (optional). */
+ data.load_start =
+ parse_and_eval_long (scan_expression_with_cleanup (&args, NULL));
+ if (args != NULL && *args != '\0')
+ {
+ /* Parse end address (optional). */
+ data.load_end = parse_and_eval_long (args);
+ if (data.load_end <= data.load_start)
+ error ("Start must be less than end.");
+ }
+ }
+ }
+
+ if (info_verbose)
+ printf_filtered ("Restore file %s offset 0x%lx start 0x%lx end 0x%lx\n",
+ filename, (unsigned long) data.load_offset,
+ (unsigned long) data.load_start,
+ (unsigned long) data.load_end);
+
+ if (binary_flag)
+ {
+ restore_binary_file (filename, &data);
+ }
+ else
+ {
+ /* Open the file for loading. */
+ ibfd = bfd_openr_with_cleanup (filename, NULL);
+
+ /* Process the sections. */
+ bfd_map_over_sections (ibfd, restore_section_callback, &data);
+ }
+ return;
+}
+
+static void
+srec_dump_command (char *cmd, int from_tty)
+{
+ printf_unfiltered ("\"dump srec\" must be followed by a subcommand.\n");
+ help_list (srec_cmdlist, "dump srec ", -1, gdb_stdout);
+}
+
+static void
+ihex_dump_command (char *cmd, int from_tty)
+{
+ printf_unfiltered ("\"dump ihex\" must be followed by a subcommand.\n");
+ help_list (ihex_cmdlist, "dump ihex ", -1, gdb_stdout);
+}
+
+static void
+tekhex_dump_command (char *cmd, int from_tty)
+{
+ printf_unfiltered ("\"dump tekhex\" must be followed by a subcommand.\n");
+ help_list (tekhex_cmdlist, "dump tekhex ", -1, gdb_stdout);
+}
+
+static void
+binary_dump_command (char *cmd, int from_tty)
+{
+ printf_unfiltered ("\"dump binary\" must be followed by a subcommand.\n");
+ help_list (binary_dump_cmdlist, "dump binary ", -1, gdb_stdout);
+}
+
+static void
+binary_append_command (char *cmd, int from_tty)
+{
+ printf_unfiltered ("\"append binary\" must be followed by a subcommand.\n");
+ help_list (binary_append_cmdlist, "append binary ", -1, gdb_stdout);
+}
+
+void
+_initialize_cli_dump (void)
+{
+ struct cmd_list_element *c;
+ add_prefix_cmd ("dump", class_vars, dump_command, "\
+Dump target code/data to a local file.",
+ &dump_cmdlist, "dump ",
+ 0/*allow-unknown*/,
+ &cmdlist);
+ add_prefix_cmd ("append", class_vars, append_command, "\
+Append target code/data to a local file.",
+ &append_cmdlist, "append ",
+ 0/*allow-unknown*/,
+ &cmdlist);
+
+ add_dump_command ("memory", dump_memory_command, "\
+Write contents of memory to a raw binary file.\n\
+Arguments are FILE START STOP. Writes the contents of memory within the\n\
+range [START .. STOP) to the specifed FILE in raw target ordered bytes.");
+
+ add_dump_command ("value", dump_value_command, "\
+Write the value of an expression to a raw binary file.\n\
+Arguments are FILE EXPRESSION. Writes the value of EXPRESSION to\n\
+the specified FILE in raw target ordered bytes.");
+
+ add_prefix_cmd ("srec", all_commands, srec_dump_command, "\
+Write target code/data to an srec file.",
+ &srec_cmdlist, "dump srec ",
+ 0 /*allow-unknown*/,
+ &dump_cmdlist);
+
+ add_prefix_cmd ("ihex", all_commands, ihex_dump_command, "\
+Write target code/data to an intel hex file.",
+ &ihex_cmdlist, "dump ihex ",
+ 0 /*allow-unknown*/,
+ &dump_cmdlist);
+
+ add_prefix_cmd ("tekhex", all_commands, tekhex_dump_command, "\
+Write target code/data to a tekhex file.",
+ &tekhex_cmdlist, "dump tekhex ",
+ 0 /*allow-unknown*/,
+ &dump_cmdlist);
+
+ add_prefix_cmd ("binary", all_commands, binary_dump_command, "\
+Write target code/data to a raw binary file.",
+ &binary_dump_cmdlist, "dump binary ",
+ 0 /*allow-unknown*/,
+ &dump_cmdlist);
+
+ add_prefix_cmd ("binary", all_commands, binary_append_command, "\
+Append target code/data to a raw binary file.",
+ &binary_append_cmdlist, "append binary ",
+ 0 /*allow-unknown*/,
+ &append_cmdlist);
+
+ add_cmd ("memory", all_commands, dump_srec_memory, "\
+Write contents of memory to an srec file.\n\
+Arguments are FILE START STOP. Writes the contents of memory\n\
+within the range [START .. STOP) to the specifed FILE in srec format.",
+ &srec_cmdlist);
+
+ add_cmd ("value", all_commands, dump_srec_value, "\
+Write the value of an expression to an srec file.\n\
+Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
+to the specified FILE in srec format.",
+ &srec_cmdlist);
+
+ add_cmd ("memory", all_commands, dump_ihex_memory, "\
+Write contents of memory to an ihex file.\n\
+Arguments are FILE START STOP. Writes the contents of memory within\n\
+the range [START .. STOP) to the specifed FILE in intel hex format.",
+ &ihex_cmdlist);
+
+ add_cmd ("value", all_commands, dump_ihex_value, "\
+Write the value of an expression to an ihex file.\n\
+Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
+to the specified FILE in intel hex format.",
+ &ihex_cmdlist);
+
+ add_cmd ("memory", all_commands, dump_tekhex_memory, "\
+Write contents of memory to a tekhex file.\n\
+Arguments are FILE START STOP. Writes the contents of memory\n\
+within the range [START .. STOP) to the specifed FILE in tekhex format.",
+ &tekhex_cmdlist);
+
+ add_cmd ("value", all_commands, dump_tekhex_value, "\
+Write the value of an expression to a tekhex file.\n\
+Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
+to the specified FILE in tekhex format.",
+ &tekhex_cmdlist);
+
+ add_cmd ("memory", all_commands, dump_binary_memory, "\
+Write contents of memory to a raw binary file.\n\
+Arguments are FILE START STOP. Writes the contents of memory\n\
+within the range [START .. STOP) to the specifed FILE in binary format.",
+ &binary_dump_cmdlist);
+
+ add_cmd ("value", all_commands, dump_binary_value, "\
+Write the value of an expression to a raw binary file.\n\
+Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
+to the specified FILE in raw target ordered bytes.",
+ &binary_dump_cmdlist);
+
+ add_cmd ("memory", all_commands, append_binary_memory, "\
+Append contents of memory to a raw binary file.\n\
+Arguments are FILE START STOP. Writes the contents of memory within the\n\
+range [START .. STOP) to the specifed FILE in raw target ordered bytes.",
+ &binary_append_cmdlist);
+
+ add_cmd ("value", all_commands, append_binary_value, "\
+Append the value of an expression to a raw binary file.\n\
+Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
+to the specified FILE in raw target ordered bytes.",
+ &binary_append_cmdlist);
+
+ c = add_com ("restore", class_vars, restore_command,
+ "Restore the contents of FILE to target memory.\n\
+Arguments are FILE OFFSET START END where all except FILE are optional.\n\
+OFFSET will be added to the base address of the file (default zero).\n\
+If START and END are given, only the file contents within that range\n\
+(file relative) will be restored to target memory.");
+ c->completer = filename_completer;
+ /* FIXME: completers for other commands. */
+}
diff --git a/gdb/cli/cli-dump.h b/gdb/cli/cli-dump.h
new file mode 100644
index 00000000000..187e0e0a12e
--- /dev/null
+++ b/gdb/cli/cli-dump.h
@@ -0,0 +1,40 @@
+/* Dump-to-file commands, for GDB, the GNU debugger.
+
+ Copyright 2001 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. */
+
+#ifndef CLI_DUMP_H
+#define CLI_DUMP_H
+
+extern void add_dump_command (char *name,
+ void (*func) (char *args, char *mode),
+ char *descr);
+
+/* Utilities for doing the dump. */
+extern char *scan_filename_with_cleanup (char **cmd, const char *defname);
+
+extern char *scan_expression_with_cleanup (char **cmd, const char *defname);
+
+extern FILE *fopen_with_cleanup (char *filename, const char *mode);
+
+extern char *skip_spaces (char *inp);
+
+extern struct value *parse_and_eval_with_error (char *exp, const char *fmt, ...) ATTR_FORMAT (printf, 2, 3);
+
+#endif
diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
new file mode 100644
index 00000000000..fc3261c7ade
--- /dev/null
+++ b/gdb/cli/cli-script.c
@@ -0,0 +1,1279 @@
+/* GDB CLI command scripting.
+
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+#include "value.h"
+#include "language.h" /* For value_true */
+#include <ctype.h>
+
+#include "ui-out.h"
+
+#include "top.h"
+#include "cli/cli-cmds.h"
+#include "cli/cli-decode.h"
+#include "cli/cli-script.h"
+
+/* From gdb/top.c */
+
+extern void dont_repeat (void);
+
+extern void do_restore_instream_cleanup (void *stream);
+
+/* Prototypes for local functions */
+
+static struct cleanup *
+ make_cleanup_free_command_lines (struct command_line **arg);
+
+static enum command_control_type
+ recurse_read_control_structure (struct command_line *current_cmd);
+
+static char *insert_args (char *line);
+
+static struct cleanup * setup_user_args (char *p);
+
+static void validate_comname (char *);
+
+/* Level of control structure. */
+static int control_level;
+
+/* Source command state variable. */
+static int source_error_allocated;
+
+/* Structure for arguments to user defined functions. */
+#define MAXUSERARGS 10
+struct user_args
+ {
+ struct user_args *next;
+ struct
+ {
+ char *arg;
+ int len;
+ }
+ a[MAXUSERARGS];
+ int count;
+ }
+ *user_args;
+
+
+/* Allocate, initialize a new command line structure for one of the
+ control commands (if/while). */
+
+static struct command_line *
+build_command_line (enum command_control_type type, char *args)
+{
+ struct command_line *cmd;
+
+ if (args == NULL)
+ error ("if/while commands require arguments.\n");
+
+ cmd = (struct command_line *) xmalloc (sizeof (struct command_line));
+ cmd->next = NULL;
+ cmd->control_type = type;
+
+ cmd->body_count = 1;
+ cmd->body_list
+ = (struct command_line **) xmalloc (sizeof (struct command_line *)
+ * cmd->body_count);
+ memset (cmd->body_list, 0, sizeof (struct command_line *) * cmd->body_count);
+ cmd->line = savestring (args, strlen (args));
+ return cmd;
+}
+
+/* Build and return a new command structure for the control commands
+ such as "if" and "while". */
+
+static struct command_line *
+get_command_line (enum command_control_type type, char *arg)
+{
+ struct command_line *cmd;
+ struct cleanup *old_chain = NULL;
+
+ /* Allocate and build a new command line structure. */
+ cmd = build_command_line (type, arg);
+
+ old_chain = make_cleanup_free_command_lines (&cmd);
+
+ /* Read in the body of this command. */
+ if (recurse_read_control_structure (cmd) == invalid_control)
+ {
+ warning ("error reading in control structure\n");
+ do_cleanups (old_chain);
+ return NULL;
+ }
+
+ discard_cleanups (old_chain);
+ return cmd;
+}
+
+/* Recursively print a command (including full control structures). */
+
+void
+print_command_lines (struct ui_out *uiout, struct command_line *cmd,
+ unsigned int depth)
+{
+ struct command_line *list;
+
+ list = cmd;
+ while (list)
+ {
+
+ if (depth)
+ ui_out_spaces (uiout, 2 * depth);
+
+ /* A simple command, print it and continue. */
+ if (list->control_type == simple_control)
+ {
+ ui_out_field_string (uiout, NULL, list->line);
+ ui_out_text (uiout, "\n");
+ list = list->next;
+ continue;
+ }
+
+ /* loop_continue to jump to the start of a while loop, print it
+ and continue. */
+ if (list->control_type == continue_control)
+ {
+ ui_out_field_string (uiout, NULL, "loop_continue");
+ ui_out_text (uiout, "\n");
+ list = list->next;
+ continue;
+ }
+
+ /* loop_break to break out of a while loop, print it and continue. */
+ if (list->control_type == break_control)
+ {
+ ui_out_field_string (uiout, NULL, "loop_break");
+ ui_out_text (uiout, "\n");
+ list = list->next;
+ continue;
+ }
+
+ /* A while command. Recursively print its subcommands and continue. */
+ if (list->control_type == while_control)
+ {
+ ui_out_field_fmt (uiout, NULL, "while %s", list->line);
+ ui_out_text (uiout, "\n");
+ print_command_lines (uiout, *list->body_list, depth + 1);
+ if (depth)
+ ui_out_spaces (uiout, 2 * depth);
+ ui_out_field_string (uiout, NULL, "end");
+ ui_out_text (uiout, "\n");
+ list = list->next;
+ continue;
+ }
+
+ /* An if command. Recursively print both arms before continueing. */
+ if (list->control_type == if_control)
+ {
+ ui_out_field_fmt (uiout, NULL, "if %s", list->line);
+ ui_out_text (uiout, "\n");
+ /* The true arm. */
+ print_command_lines (uiout, list->body_list[0], depth + 1);
+
+ /* Show the false arm if it exists. */
+ if (list->body_count == 2)
+ {
+ if (depth)
+ ui_out_spaces (uiout, 2 * depth);
+ ui_out_field_string (uiout, NULL, "else");
+ ui_out_text (uiout, "\n");
+ print_command_lines (uiout, list->body_list[1], depth + 1);
+ }
+
+ if (depth)
+ ui_out_spaces (uiout, 2 * depth);
+ ui_out_field_string (uiout, NULL, "end");
+ ui_out_text (uiout, "\n");
+ list = list->next;
+ continue;
+ }
+
+ /* ignore illegal command type and try next */
+ list = list->next;
+ } /* while (list) */
+}
+
+/* Handle pre-post hooks. */
+
+void
+clear_hook_in_cleanup (void *data)
+{
+ struct cmd_list_element *c = data;
+ c->hook_in = 0; /* Allow hook to work again once it is complete */
+}
+
+void
+execute_cmd_pre_hook (struct cmd_list_element *c)
+{
+ if ((c->hook_pre) && (!c->hook_in))
+ {
+ struct cleanup *cleanups = make_cleanup (clear_hook_in_cleanup, c);
+ c->hook_in = 1; /* Prevent recursive hooking */
+ execute_user_command (c->hook_pre, (char *) 0);
+ do_cleanups (cleanups);
+ }
+}
+
+void
+execute_cmd_post_hook (struct cmd_list_element *c)
+{
+ if ((c->hook_post) && (!c->hook_in))
+ {
+ struct cleanup *cleanups = make_cleanup (clear_hook_in_cleanup, c);
+ c->hook_in = 1; /* Prevent recursive hooking */
+ execute_user_command (c->hook_post, (char *) 0);
+ do_cleanups (cleanups);
+ }
+}
+
+/* Execute the command in CMD. */
+void
+do_restore_user_call_depth (void * call_depth)
+{
+ int * depth = call_depth;
+ /* We will be returning_to_top_level() at this point, so we want to
+ reset our depth. */
+ (*depth) = 0;
+}
+
+
+void
+execute_user_command (struct cmd_list_element *c, char *args)
+{
+ register struct command_line *cmdlines;
+ struct cleanup *old_chain;
+ enum command_control_type ret;
+ static int user_call_depth = 0;
+ extern int max_user_call_depth;
+
+ old_chain = setup_user_args (args);
+
+ cmdlines = c->user_commands;
+ if (cmdlines == 0)
+ /* Null command */
+ return;
+
+ if (++user_call_depth > max_user_call_depth)
+ error ("Max user call depth exceeded -- command aborted\n");
+
+ old_chain = make_cleanup (do_restore_user_call_depth, &user_call_depth);
+
+ /* Set the instream to 0, indicating execution of a
+ user-defined function. */
+ old_chain = make_cleanup (do_restore_instream_cleanup, instream);
+ instream = (FILE *) 0;
+ while (cmdlines)
+ {
+ ret = execute_control_command (cmdlines);
+ if (ret != simple_control && ret != break_control)
+ {
+ warning ("Error in control structure.\n");
+ break;
+ }
+ cmdlines = cmdlines->next;
+ }
+ do_cleanups (old_chain);
+
+ user_call_depth--;
+}
+
+enum command_control_type
+execute_control_command (struct command_line *cmd)
+{
+ struct expression *expr;
+ struct command_line *current;
+ struct cleanup *old_chain = 0;
+ struct value *val;
+ struct value *val_mark;
+ int loop;
+ enum command_control_type ret;
+ char *new_line;
+
+ switch (cmd->control_type)
+ {
+ case simple_control:
+ /* A simple command, execute it and return. */
+ new_line = insert_args (cmd->line);
+ if (!new_line)
+ return invalid_control;
+ old_chain = make_cleanup (free_current_contents, &new_line);
+ execute_command (new_line, 0);
+ ret = cmd->control_type;
+ break;
+
+ case continue_control:
+ case break_control:
+ /* Return for "continue", and "break" so we can either
+ continue the loop at the top, or break out. */
+ ret = cmd->control_type;
+ break;
+
+ case while_control:
+ {
+ /* Parse the loop control expression for the while statement. */
+ new_line = insert_args (cmd->line);
+ if (!new_line)
+ return invalid_control;
+ old_chain = make_cleanup (free_current_contents, &new_line);
+ expr = parse_expression (new_line);
+ make_cleanup (free_current_contents, &expr);
+
+ ret = simple_control;
+ loop = 1;
+
+ /* Keep iterating so long as the expression is true. */
+ while (loop == 1)
+ {
+ int cond_result;
+
+ QUIT;
+
+ /* Evaluate the expression. */
+ val_mark = value_mark ();
+ val = evaluate_expression (expr);
+ cond_result = value_true (val);
+ value_free_to_mark (val_mark);
+
+ /* If the value is false, then break out of the loop. */
+ if (!cond_result)
+ break;
+
+ /* Execute the body of the while statement. */
+ current = *cmd->body_list;
+ while (current)
+ {
+ ret = execute_control_command (current);
+
+ /* If we got an error, or a "break" command, then stop
+ looping. */
+ if (ret == invalid_control || ret == break_control)
+ {
+ loop = 0;
+ break;
+ }
+
+ /* If we got a "continue" command, then restart the loop
+ at this point. */
+ if (ret == continue_control)
+ break;
+
+ /* Get the next statement. */
+ current = current->next;
+ }
+ }
+
+ /* Reset RET so that we don't recurse the break all the way down. */
+ if (ret == break_control)
+ ret = simple_control;
+
+ break;
+ }
+
+ case if_control:
+ {
+ new_line = insert_args (cmd->line);
+ if (!new_line)
+ return invalid_control;
+ old_chain = make_cleanup (free_current_contents, &new_line);
+ /* Parse the conditional for the if statement. */
+ expr = parse_expression (new_line);
+ make_cleanup (free_current_contents, &expr);
+
+ current = NULL;
+ ret = simple_control;
+
+ /* Evaluate the conditional. */
+ val_mark = value_mark ();
+ val = evaluate_expression (expr);
+
+ /* Choose which arm to take commands from based on the value of the
+ conditional expression. */
+ if (value_true (val))
+ current = *cmd->body_list;
+ else if (cmd->body_count == 2)
+ current = *(cmd->body_list + 1);
+ value_free_to_mark (val_mark);
+
+ /* Execute commands in the given arm. */
+ while (current)
+ {
+ ret = execute_control_command (current);
+
+ /* If we got an error, get out. */
+ if (ret != simple_control)
+ break;
+
+ /* Get the next statement in the body. */
+ current = current->next;
+ }
+
+ break;
+ }
+
+ default:
+ warning ("Invalid control type in command structure.");
+ return invalid_control;
+ }
+
+ if (old_chain)
+ do_cleanups (old_chain);
+
+ return ret;
+}
+
+/* "while" command support. Executes a body of statements while the
+ loop condition is nonzero. */
+
+void
+while_command (char *arg, int from_tty)
+{
+ struct command_line *command = NULL;
+
+ control_level = 1;
+ command = get_command_line (while_control, arg);
+
+ if (command == NULL)
+ return;
+
+ execute_control_command (command);
+ free_command_lines (&command);
+}
+
+/* "if" command support. Execute either the true or false arm depending
+ on the value of the if conditional. */
+
+void
+if_command (char *arg, int from_tty)
+{
+ struct command_line *command = NULL;
+
+ control_level = 1;
+ command = get_command_line (if_control, arg);
+
+ if (command == NULL)
+ return;
+
+ execute_control_command (command);
+ free_command_lines (&command);
+}
+
+/* Cleanup */
+static void
+arg_cleanup (void *ignore)
+{
+ struct user_args *oargs = user_args;
+ if (!user_args)
+ internal_error (__FILE__, __LINE__,
+ "arg_cleanup called with no user args.\n");
+
+ user_args = user_args->next;
+ xfree (oargs);
+}
+
+/* Bind the incomming arguments for a user defined command to
+ $arg0, $arg1 ... $argMAXUSERARGS. */
+
+static struct cleanup *
+setup_user_args (char *p)
+{
+ struct user_args *args;
+ struct cleanup *old_chain;
+ unsigned int arg_count = 0;
+
+ args = (struct user_args *) xmalloc (sizeof (struct user_args));
+ memset (args, 0, sizeof (struct user_args));
+
+ args->next = user_args;
+ user_args = args;
+
+ old_chain = make_cleanup (arg_cleanup, 0/*ignored*/);
+
+ if (p == NULL)
+ return old_chain;
+
+ while (*p)
+ {
+ char *start_arg;
+ int squote = 0;
+ int dquote = 0;
+ int bsquote = 0;
+
+ if (arg_count >= MAXUSERARGS)
+ {
+ error ("user defined function may only have %d arguments.\n",
+ MAXUSERARGS);
+ return old_chain;
+ }
+
+ /* Strip whitespace. */
+ while (*p == ' ' || *p == '\t')
+ p++;
+
+ /* P now points to an argument. */
+ start_arg = p;
+ user_args->a[arg_count].arg = p;
+
+ /* Get to the end of this argument. */
+ while (*p)
+ {
+ if (((*p == ' ' || *p == '\t')) && !squote && !dquote && !bsquote)
+ break;
+ else
+ {
+ if (bsquote)
+ bsquote = 0;
+ else if (*p == '\\')
+ bsquote = 1;
+ else if (squote)
+ {
+ if (*p == '\'')
+ squote = 0;
+ }
+ else if (dquote)
+ {
+ if (*p == '"')
+ dquote = 0;
+ }
+ else
+ {
+ if (*p == '\'')
+ squote = 1;
+ else if (*p == '"')
+ dquote = 1;
+ }
+ p++;
+ }
+ }
+
+ user_args->a[arg_count].len = p - start_arg;
+ arg_count++;
+ user_args->count++;
+ }
+ return old_chain;
+}
+
+/* Given character string P, return a point to the first argument ($arg),
+ or NULL if P contains no arguments. */
+
+static char *
+locate_arg (char *p)
+{
+ while ((p = strchr (p, '$')))
+ {
+ if (strncmp (p, "$arg", 4) == 0 && isdigit (p[4]))
+ return p;
+ p++;
+ }
+ return NULL;
+}
+
+/* Insert the user defined arguments stored in user_arg into the $arg
+ arguments found in line, with the updated copy being placed into nline. */
+
+static char *
+insert_args (char *line)
+{
+ char *p, *save_line, *new_line;
+ unsigned len, i;
+
+ /* First we need to know how much memory to allocate for the new line. */
+ save_line = line;
+ len = 0;
+ while ((p = locate_arg (line)))
+ {
+ len += p - line;
+ i = p[4] - '0';
+
+ if (i >= user_args->count)
+ {
+ error ("Missing argument %d in user function.\n", i);
+ return NULL;
+ }
+ len += user_args->a[i].len;
+ line = p + 5;
+ }
+
+ /* Don't forget the tail. */
+ len += strlen (line);
+
+ /* Allocate space for the new line and fill it in. */
+ new_line = (char *) xmalloc (len + 1);
+ if (new_line == NULL)
+ return NULL;
+
+ /* Restore pointer to beginning of old line. */
+ line = save_line;
+
+ /* Save pointer to beginning of new line. */
+ save_line = new_line;
+
+ while ((p = locate_arg (line)))
+ {
+ int i, len;
+
+ memcpy (new_line, line, p - line);
+ new_line += p - line;
+ i = p[4] - '0';
+
+ len = user_args->a[i].len;
+ if (len)
+ {
+ memcpy (new_line, user_args->a[i].arg, len);
+ new_line += len;
+ }
+ line = p + 5;
+ }
+ /* Don't forget the tail. */
+ strcpy (new_line, line);
+
+ /* Return a pointer to the beginning of the new line. */
+ return save_line;
+}
+
+
+/* Expand the body_list of COMMAND so that it can hold NEW_LENGTH
+ code bodies. This is typically used when we encounter an "else"
+ clause for an "if" command. */
+
+static void
+realloc_body_list (struct command_line *command, int new_length)
+{
+ int n;
+ struct command_line **body_list;
+
+ n = command->body_count;
+
+ /* Nothing to do? */
+ if (new_length <= n)
+ return;
+
+ body_list = (struct command_line **)
+ xmalloc (sizeof (struct command_line *) * new_length);
+
+ memcpy (body_list, command->body_list, sizeof (struct command_line *) * n);
+
+ xfree (command->body_list);
+ command->body_list = body_list;
+ command->body_count = new_length;
+}
+
+/* Read one line from the input stream. If the command is an "else" or
+ "end", return such an indication to the caller. */
+
+static enum misc_command_type
+read_next_line (struct command_line **command)
+{
+ char *p, *p1, *prompt_ptr, control_prompt[256];
+ int i = 0;
+
+ if (control_level >= 254)
+ error ("Control nesting too deep!\n");
+
+ /* Set a prompt based on the nesting of the control commands. */
+ if (instream == stdin || (instream == 0 && readline_hook != NULL))
+ {
+ for (i = 0; i < control_level; i++)
+ control_prompt[i] = ' ';
+ control_prompt[i] = '>';
+ control_prompt[i + 1] = '\0';
+ prompt_ptr = (char *) &control_prompt[0];
+ }
+ else
+ prompt_ptr = NULL;
+
+ p = command_line_input (prompt_ptr, instream == stdin, "commands");
+
+ /* Not sure what to do here. */
+ if (p == NULL)
+ return end_command;
+
+ /* Strip leading and trailing whitespace. */
+ while (*p == ' ' || *p == '\t')
+ p++;
+
+ p1 = p + strlen (p);
+ while (p1 != p && (p1[-1] == ' ' || p1[-1] == '\t'))
+ p1--;
+
+ /* Blanks and comments don't really do anything, but we need to
+ distinguish them from else, end and other commands which can be
+ executed. */
+ if (p1 == p || p[0] == '#')
+ return nop_command;
+
+ /* Is this the end of a simple, while, or if control structure? */
+ if (p1 - p == 3 && !strncmp (p, "end", 3))
+ return end_command;
+
+ /* Is the else clause of an if control structure? */
+ if (p1 - p == 4 && !strncmp (p, "else", 4))
+ return else_command;
+
+ /* Check for while, if, break, continue, etc and build a new command
+ line structure for them. */
+ if (p1 - p > 5 && !strncmp (p, "while", 5))
+ *command = build_command_line (while_control, p + 6);
+ else if (p1 - p > 2 && !strncmp (p, "if", 2))
+ *command = build_command_line (if_control, p + 3);
+ else if (p1 - p == 10 && !strncmp (p, "loop_break", 10))
+ {
+ *command = (struct command_line *)
+ xmalloc (sizeof (struct command_line));
+ (*command)->next = NULL;
+ (*command)->line = NULL;
+ (*command)->control_type = break_control;
+ (*command)->body_count = 0;
+ (*command)->body_list = NULL;
+ }
+ else if (p1 - p == 13 && !strncmp (p, "loop_continue", 13))
+ {
+ *command = (struct command_line *)
+ xmalloc (sizeof (struct command_line));
+ (*command)->next = NULL;
+ (*command)->line = NULL;
+ (*command)->control_type = continue_control;
+ (*command)->body_count = 0;
+ (*command)->body_list = NULL;
+ }
+ else
+ {
+ /* A normal command. */
+ *command = (struct command_line *)
+ xmalloc (sizeof (struct command_line));
+ (*command)->next = NULL;
+ (*command)->line = savestring (p, p1 - p);
+ (*command)->control_type = simple_control;
+ (*command)->body_count = 0;
+ (*command)->body_list = NULL;
+ }
+
+ /* Nothing special. */
+ return ok_command;
+}
+
+/* Recursively read in the control structures and create a command_line
+ structure from them.
+
+ The parent_control parameter is the control structure in which the
+ following commands are nested. */
+
+static enum command_control_type
+recurse_read_control_structure (struct command_line *current_cmd)
+{
+ int current_body, i;
+ enum misc_command_type val;
+ enum command_control_type ret;
+ struct command_line **body_ptr, *child_tail, *next;
+
+ child_tail = NULL;
+ current_body = 1;
+
+ /* Sanity checks. */
+ if (current_cmd->control_type == simple_control)
+ {
+ error ("Recursed on a simple control type\n");
+ return invalid_control;
+ }
+
+ if (current_body > current_cmd->body_count)
+ {
+ error ("Allocated body is smaller than this command type needs\n");
+ return invalid_control;
+ }
+
+ /* Read lines from the input stream and build control structures. */
+ while (1)
+ {
+ dont_repeat ();
+
+ next = NULL;
+ val = read_next_line (&next);
+
+ /* Just skip blanks and comments. */
+ if (val == nop_command)
+ continue;
+
+ if (val == end_command)
+ {
+ if (current_cmd->control_type == while_control
+ || current_cmd->control_type == if_control)
+ {
+ /* Success reading an entire control structure. */
+ ret = simple_control;
+ break;
+ }
+ else
+ {
+ ret = invalid_control;
+ break;
+ }
+ }
+
+ /* Not the end of a control structure. */
+ if (val == else_command)
+ {
+ if (current_cmd->control_type == if_control
+ && current_body == 1)
+ {
+ realloc_body_list (current_cmd, 2);
+ current_body = 2;
+ child_tail = NULL;
+ continue;
+ }
+ else
+ {
+ ret = invalid_control;
+ break;
+ }
+ }
+
+ if (child_tail)
+ {
+ child_tail->next = next;
+ }
+ else
+ {
+ body_ptr = current_cmd->body_list;
+ for (i = 1; i < current_body; i++)
+ body_ptr++;
+
+ *body_ptr = next;
+
+ }
+
+ child_tail = next;
+
+ /* If the latest line is another control structure, then recurse
+ on it. */
+ if (next->control_type == while_control
+ || next->control_type == if_control)
+ {
+ control_level++;
+ ret = recurse_read_control_structure (next);
+ control_level--;
+
+ if (ret != simple_control)
+ break;
+ }
+ }
+
+ dont_repeat ();
+
+ return ret;
+}
+
+/* Read lines from the input stream and accumulate them in a chain of
+ struct command_line's, which is then returned. For input from a
+ terminal, the special command "end" is used to mark the end of the
+ input, and is not included in the returned chain of commands. */
+
+#define END_MESSAGE "End with a line saying just \"end\"."
+
+struct command_line *
+read_command_lines (char *prompt_arg, int from_tty)
+{
+ struct command_line *head, *tail, *next;
+ struct cleanup *old_chain;
+ enum command_control_type ret;
+ enum misc_command_type val;
+
+ control_level = 0;
+ if (readline_begin_hook)
+ {
+ /* Note - intentional to merge messages with no newline */
+ (*readline_begin_hook) ("%s %s\n", prompt_arg, END_MESSAGE);
+ }
+ else if (from_tty && input_from_terminal_p ())
+ {
+ printf_unfiltered ("%s\n%s\n", prompt_arg, END_MESSAGE);
+ gdb_flush (gdb_stdout);
+ }
+
+ head = tail = NULL;
+ old_chain = NULL;
+
+ while (1)
+ {
+ val = read_next_line (&next);
+
+ /* Ignore blank lines or comments. */
+ if (val == nop_command)
+ continue;
+
+ if (val == end_command)
+ {
+ ret = simple_control;
+ break;
+ }
+
+ if (val != ok_command)
+ {
+ ret = invalid_control;
+ break;
+ }
+
+ if (next->control_type == while_control
+ || next->control_type == if_control)
+ {
+ control_level++;
+ ret = recurse_read_control_structure (next);
+ control_level--;
+
+ if (ret == invalid_control)
+ break;
+ }
+
+ if (tail)
+ {
+ tail->next = next;
+ }
+ else
+ {
+ head = next;
+ old_chain = make_cleanup_free_command_lines (&head);
+ }
+ tail = next;
+ }
+
+ dont_repeat ();
+
+ if (head)
+ {
+ if (ret != invalid_control)
+ {
+ discard_cleanups (old_chain);
+ }
+ else
+ do_cleanups (old_chain);
+ }
+
+ if (readline_end_hook)
+ {
+ (*readline_end_hook) ();
+ }
+ return (head);
+}
+
+/* Free a chain of struct command_line's. */
+
+void
+free_command_lines (struct command_line **lptr)
+{
+ register struct command_line *l = *lptr;
+ register struct command_line *next;
+ struct command_line **blist;
+ int i;
+
+ while (l)
+ {
+ if (l->body_count > 0)
+ {
+ blist = l->body_list;
+ for (i = 0; i < l->body_count; i++, blist++)
+ free_command_lines (blist);
+ }
+ next = l->next;
+ xfree (l->line);
+ xfree (l);
+ l = next;
+ }
+ *lptr = NULL;
+}
+
+static void
+do_free_command_lines_cleanup (void *arg)
+{
+ free_command_lines (arg);
+}
+
+static struct cleanup *
+make_cleanup_free_command_lines (struct command_line **arg)
+{
+ return make_cleanup (do_free_command_lines_cleanup, arg);
+}
+
+static void
+validate_comname (char *comname)
+{
+ register char *p;
+
+ if (comname == 0)
+ error_no_arg ("name of command to define");
+
+ p = comname;
+ while (*p)
+ {
+ if (!isalnum (*p) && *p != '-' && *p != '_')
+ error ("Junk in argument list: \"%s\"", p);
+ p++;
+ }
+}
+
+/* This is just a placeholder in the command data structures. */
+static void
+user_defined_command (char *ignore, int from_tty)
+{
+}
+
+void
+define_command (char *comname, int from_tty)
+{
+#define MAX_TMPBUF 128
+ enum cmd_hook_type
+ {
+ CMD_NO_HOOK = 0,
+ CMD_PRE_HOOK,
+ CMD_POST_HOOK
+ };
+ register struct command_line *cmds;
+ register struct cmd_list_element *c, *newc, *oldc, *hookc = 0;
+ char *tem = comname;
+ char *tem2;
+ char tmpbuf[MAX_TMPBUF];
+ int hook_type = CMD_NO_HOOK;
+ int hook_name_size = 0;
+
+#define HOOK_STRING "hook-"
+#define HOOK_LEN 5
+#define HOOK_POST_STRING "hookpost-"
+#define HOOK_POST_LEN 9
+
+ validate_comname (comname);
+
+ /* Look it up, and verify that we got an exact match. */
+ c = lookup_cmd (&tem, cmdlist, "", -1, 1);
+ if (c && !STREQ (comname, c->name))
+ c = 0;
+
+ if (c)
+ {
+ if (c->class == class_user || c->class == class_alias)
+ tem = "Redefine command \"%s\"? ";
+ else
+ tem = "Really redefine built-in command \"%s\"? ";
+ if (!query (tem, c->name))
+ error ("Command \"%s\" not redefined.", c->name);
+ }
+
+ /* If this new command is a hook, then mark the command which it
+ is hooking. Note that we allow hooking `help' commands, so that
+ we can hook the `stop' pseudo-command. */
+
+ if (!strncmp (comname, HOOK_STRING, HOOK_LEN))
+ {
+ hook_type = CMD_PRE_HOOK;
+ hook_name_size = HOOK_LEN;
+ }
+ else if (!strncmp (comname, HOOK_POST_STRING, HOOK_POST_LEN))
+ {
+ hook_type = CMD_POST_HOOK;
+ hook_name_size = HOOK_POST_LEN;
+ }
+
+ if (hook_type != CMD_NO_HOOK)
+ {
+ /* Look up cmd it hooks, and verify that we got an exact match. */
+ tem = comname + hook_name_size;
+ hookc = lookup_cmd (&tem, cmdlist, "", -1, 0);
+ if (hookc && !STREQ (comname + hook_name_size, hookc->name))
+ hookc = 0;
+ if (!hookc)
+ {
+ warning ("Your new `%s' command does not hook any existing command.",
+ comname);
+ if (!query ("Proceed? "))
+ error ("Not confirmed.");
+ }
+ }
+
+ comname = savestring (comname, strlen (comname));
+
+ /* If the rest of the commands will be case insensitive, this one
+ should behave in the same manner. */
+ for (tem = comname; *tem; tem++)
+ if (isupper (*tem))
+ *tem = tolower (*tem);
+
+ sprintf (tmpbuf, "Type commands for definition of \"%s\".", comname);
+ cmds = read_command_lines (tmpbuf, from_tty);
+
+ if (c && c->class == class_user)
+ free_command_lines (&c->user_commands);
+
+ newc = add_cmd (comname, class_user, user_defined_command,
+ (c && c->class == class_user)
+ ? c->doc : savestring ("User-defined.", 13), &cmdlist);
+ newc->user_commands = cmds;
+
+ /* If this new command is a hook, then mark both commands as being
+ tied. */
+ if (hookc)
+ {
+ switch (hook_type)
+ {
+ case CMD_PRE_HOOK:
+ hookc->hook_pre = newc; /* Target gets hooked. */
+ newc->hookee_pre = hookc; /* We are marked as hooking target cmd. */
+ break;
+ case CMD_POST_HOOK:
+ hookc->hook_post = newc; /* Target gets hooked. */
+ newc->hookee_post = hookc; /* We are marked as hooking target cmd. */
+ break;
+ default:
+ /* Should never come here as hookc would be 0. */
+ internal_error (__FILE__, __LINE__, "bad switch");
+ }
+ }
+}
+
+void
+document_command (char *comname, int from_tty)
+{
+ struct command_line *doclines;
+ register struct cmd_list_element *c;
+ char *tem = comname;
+ char tmpbuf[128];
+
+ validate_comname (comname);
+
+ c = lookup_cmd (&tem, cmdlist, "", 0, 1);
+
+ if (c->class != class_user)
+ error ("Command \"%s\" is built-in.", comname);
+
+ sprintf (tmpbuf, "Type documentation for \"%s\".", comname);
+ doclines = read_command_lines (tmpbuf, from_tty);
+
+ if (c->doc)
+ xfree (c->doc);
+
+ {
+ register struct command_line *cl1;
+ register int len = 0;
+
+ for (cl1 = doclines; cl1; cl1 = cl1->next)
+ len += strlen (cl1->line) + 1;
+
+ c->doc = (char *) xmalloc (len + 1);
+ *c->doc = 0;
+
+ for (cl1 = doclines; cl1; cl1 = cl1->next)
+ {
+ strcat (c->doc, cl1->line);
+ if (cl1->next)
+ strcat (c->doc, "\n");
+ }
+ }
+
+ free_command_lines (&doclines);
+}
+
+struct source_cleanup_lines_args
+{
+ int old_line;
+ char *old_file;
+ char *old_pre_error;
+ char *old_error_pre_print;
+};
+
+static void
+source_cleanup_lines (PTR args)
+{
+ struct source_cleanup_lines_args *p =
+ (struct source_cleanup_lines_args *) args;
+ source_line_number = p->old_line;
+ source_file_name = p->old_file;
+ source_pre_error = p->old_pre_error;
+ error_pre_print = p->old_error_pre_print;
+}
+
+/* ARGSUSED */
+static void
+do_fclose_cleanup (void *stream)
+{
+ fclose (stream);
+}
+
+/* Used to implement source_command */
+
+void
+script_from_file (FILE *stream, char *file)
+{
+ struct cleanup *old_cleanups;
+ struct source_cleanup_lines_args old_lines;
+ int needed_length;
+
+ if (stream == NULL)
+ {
+ internal_error (__FILE__, __LINE__, "called with NULL file pointer!");
+ }
+
+ old_cleanups = make_cleanup (do_fclose_cleanup, stream);
+
+ old_lines.old_line = source_line_number;
+ old_lines.old_file = source_file_name;
+ old_lines.old_pre_error = source_pre_error;
+ old_lines.old_error_pre_print = error_pre_print;
+ make_cleanup (source_cleanup_lines, &old_lines);
+ source_line_number = 0;
+ source_file_name = file;
+ source_pre_error = error_pre_print == NULL ? "" : error_pre_print;
+ source_pre_error = savestring (source_pre_error, strlen (source_pre_error));
+ make_cleanup (xfree, source_pre_error);
+ /* This will get set every time we read a line. So it won't stay "" for
+ long. */
+ error_pre_print = "";
+
+ needed_length = strlen (source_file_name) + strlen (source_pre_error) + 80;
+ if (source_error_allocated < needed_length)
+ {
+ source_error_allocated *= 2;
+ if (source_error_allocated < needed_length)
+ source_error_allocated = needed_length;
+ if (source_error == NULL)
+ source_error = xmalloc (source_error_allocated);
+ else
+ source_error = xrealloc (source_error, source_error_allocated);
+ }
+
+ read_command_file (stream);
+
+ do_cleanups (old_cleanups);
+}
+
+void
+show_user_1 (struct cmd_list_element *c, struct ui_file *stream)
+{
+ register struct command_line *cmdlines;
+
+ cmdlines = c->user_commands;
+ if (!cmdlines)
+ return;
+ fputs_filtered ("User command ", stream);
+ fputs_filtered (c->name, stream);
+ fputs_filtered (":\n", stream);
+
+ print_command_lines (uiout, cmdlines, 1);
+ fputs_filtered ("\n", stream);
+}
+
diff --git a/gdb/cli/cli-script.h b/gdb/cli/cli-script.h
new file mode 100644
index 00000000000..f8604c6cb71
--- /dev/null
+++ b/gdb/cli/cli-script.h
@@ -0,0 +1,48 @@
+/* Header file for GDB CLI command implementation library.
+ Copyright 2000, 2002 Free Software Foundation, Inc.
+
+ 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. */
+
+#if !defined (CLI_SCRIPT_H)
+#define CLI_SCRIPT_H 1
+
+/* Exported to cli/cli-cmds.c */
+
+extern void script_from_file (FILE *stream, char *file);
+
+extern void document_command (char *, int);
+
+extern void define_command (char *, int);
+
+extern void while_command (char *arg, int from_tty);
+
+extern void if_command (char *arg, int from_tty);
+
+extern void show_user_1 (struct cmd_list_element *c, struct ui_file *stream);
+
+/* Exported to gdb/breakpoint.c */
+
+extern enum command_control_type
+ execute_control_command (struct command_line *cmd);
+
+extern void print_command_lines (struct ui_out *,
+ struct command_line *, unsigned int);
+
+/* Exported to gdb/infrun.c */
+
+extern void execute_user_command (struct cmd_list_element *c, char *args);
+
+#endif /* !defined (CLI_SCRIPT_H) */
diff --git a/gdb/cli/cli-setshow.c b/gdb/cli/cli-setshow.c
new file mode 100644
index 00000000000..f967b0c3eba
--- /dev/null
+++ b/gdb/cli/cli-setshow.c
@@ -0,0 +1,382 @@
+/* Handle set and show GDB commands.
+
+ Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ 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 "defs.h"
+#include "value.h"
+#include <ctype.h>
+#if 0
+#include "gdb_string.h"
+#endif
+
+#include "ui-out.h"
+
+#include "cli/cli-decode.h"
+#include "cli/cli-cmds.h"
+#include "cli/cli-setshow.h"
+
+/* Prototypes for local functions */
+
+static int parse_binary_operation (char *);
+
+static enum cmd_auto_boolean parse_auto_binary_operation (const char *arg);
+
+static enum cmd_auto_boolean
+parse_auto_binary_operation (const char *arg)
+{
+ if (arg != NULL && *arg != '\0')
+ {
+ int length = strlen (arg);
+ while (isspace (arg[length - 1]) && length > 0)
+ length--;
+ if (strncmp (arg, "on", length) == 0
+ || strncmp (arg, "1", length) == 0
+ || strncmp (arg, "yes", length) == 0
+ || strncmp (arg, "enable", length) == 0)
+ return CMD_AUTO_BOOLEAN_TRUE;
+ else if (strncmp (arg, "off", length) == 0
+ || strncmp (arg, "0", length) == 0
+ || strncmp (arg, "no", length) == 0
+ || strncmp (arg, "disable", length) == 0)
+ return CMD_AUTO_BOOLEAN_FALSE;
+ else if (strncmp (arg, "auto", length) == 0
+ || (strncmp (arg, "-1", length) == 0 && length > 1))
+ return CMD_AUTO_BOOLEAN_AUTO;
+ }
+ error ("\"on\", \"off\" or \"auto\" expected.");
+ return CMD_AUTO_BOOLEAN_AUTO; /* pacify GCC */
+}
+
+static int
+parse_binary_operation (char *arg)
+{
+ int length;
+
+ if (!arg || !*arg)
+ return 1;
+
+ length = strlen (arg);
+
+ while (arg[length - 1] == ' ' || arg[length - 1] == '\t')
+ length--;
+
+ if (strncmp (arg, "on", length) == 0
+ || strncmp (arg, "1", length) == 0
+ || strncmp (arg, "yes", length) == 0
+ || strncmp (arg, "enable", length) == 0)
+ return 1;
+ else if (strncmp (arg, "off", length) == 0
+ || strncmp (arg, "0", length) == 0
+ || strncmp (arg, "no", length) == 0
+ || strncmp (arg, "disable", length) == 0)
+ return 0;
+ else
+ {
+ error ("\"on\" or \"off\" expected.");
+ return 0;
+ }
+}
+
+/* Do a "set" or "show" command. ARG is NULL if no argument, or the text
+ of the argument, and FROM_TTY is nonzero if this command is being entered
+ directly by the user (i.e. these are just like any other
+ command). C is the command list element for the command. */
+
+void
+do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c)
+{
+ if (c->type == set_cmd)
+ {
+ switch (c->var_type)
+ {
+ case var_string:
+ {
+ char *new;
+ char *p;
+ char *q;
+ int ch;
+
+ if (arg == NULL)
+ arg = "";
+ new = (char *) xmalloc (strlen (arg) + 2);
+ p = arg;
+ q = new;
+ while ((ch = *p++) != '\000')
+ {
+ if (ch == '\\')
+ {
+ /* \ at end of argument is used after spaces
+ so they won't be lost. */
+ /* This is obsolete now that we no longer strip
+ trailing whitespace and actually, the backslash
+ didn't get here in my test, readline or
+ something did something funky with a backslash
+ right before a newline. */
+ if (*p == 0)
+ break;
+ ch = parse_escape (&p);
+ if (ch == 0)
+ break; /* C loses */
+ else if (ch > 0)
+ *q++ = ch;
+ }
+ else
+ *q++ = ch;
+ }
+#if 0
+ if (*(p - 1) != '\\')
+ *q++ = ' ';
+#endif
+ *q++ = '\0';
+ new = (char *) xrealloc (new, q - new);
+ if (*(char **) c->var != NULL)
+ xfree (*(char **) c->var);
+ *(char **) c->var = new;
+ }
+ break;
+ case var_string_noescape:
+ if (arg == NULL)
+ arg = "";
+ if (*(char **) c->var != NULL)
+ xfree (*(char **) c->var);
+ *(char **) c->var = savestring (arg, strlen (arg));
+ break;
+ case var_filename:
+ if (arg == NULL)
+ error_no_arg ("filename to set it to.");
+ if (*(char **) c->var != NULL)
+ xfree (*(char **) c->var);
+ *(char **) c->var = tilde_expand (arg);
+ break;
+ case var_boolean:
+ *(int *) c->var = parse_binary_operation (arg);
+ break;
+ case var_auto_boolean:
+ *(enum cmd_auto_boolean *) c->var = parse_auto_binary_operation (arg);
+ break;
+ case var_uinteger:
+ if (arg == NULL)
+ error_no_arg ("integer to set it to.");
+ *(unsigned int *) c->var = parse_and_eval_long (arg);
+ if (*(unsigned int *) c->var == 0)
+ *(unsigned int *) c->var = UINT_MAX;
+ break;
+ case var_integer:
+ {
+ unsigned int val;
+ if (arg == NULL)
+ error_no_arg ("integer to set it to.");
+ val = parse_and_eval_long (arg);
+ if (val == 0)
+ *(int *) c->var = INT_MAX;
+ else if (val >= INT_MAX)
+ error ("integer %u out of range", val);
+ else
+ *(int *) c->var = val;
+ break;
+ }
+ case var_zinteger:
+ if (arg == NULL)
+ error_no_arg ("integer to set it to.");
+ *(int *) c->var = parse_and_eval_long (arg);
+ break;
+ case var_enum:
+ {
+ int i;
+ int len;
+ int nmatches;
+ const char *match = NULL;
+ char *p;
+
+ /* if no argument was supplied, print an informative error message */
+ if (arg == NULL)
+ {
+ char msg[1024];
+ strcpy (msg, "Requires an argument. Valid arguments are ");
+ for (i = 0; c->enums[i]; i++)
+ {
+ if (i != 0)
+ strcat (msg, ", ");
+ strcat (msg, c->enums[i]);
+ }
+ strcat (msg, ".");
+ error (msg);
+ }
+
+ p = strchr (arg, ' ');
+
+ if (p)
+ len = p - arg;
+ else
+ len = strlen (arg);
+
+ nmatches = 0;
+ for (i = 0; c->enums[i]; i++)
+ if (strncmp (arg, c->enums[i], len) == 0)
+ {
+ if (c->enums[i][len] == '\0')
+ {
+ match = c->enums[i];
+ nmatches = 1;
+ break; /* exact match. */
+ }
+ else
+ {
+ match = c->enums[i];
+ nmatches++;
+ }
+ }
+
+ if (nmatches <= 0)
+ error ("Undefined item: \"%s\".", arg);
+
+ if (nmatches > 1)
+ error ("Ambiguous item \"%s\".", arg);
+
+ *(const char **) c->var = match;
+ }
+ break;
+ default:
+ error ("gdb internal error: bad var_type in do_setshow_command");
+ }
+ }
+ else if (c->type == show_cmd)
+ {
+ struct cleanup *old_chain;
+ struct ui_stream *stb;
+ int quote;
+
+ stb = ui_out_stream_new (uiout);
+ old_chain = make_cleanup_ui_out_stream_delete (stb);
+
+ /* Possibly call the pre hook. */
+ if (c->pre_show_hook)
+ (c->pre_show_hook) (c);
+
+ /* Print doc minus "show" at start. */
+ print_doc_line (gdb_stdout, c->doc + 5);
+
+ ui_out_text (uiout, " is ");
+ ui_out_wrap_hint (uiout, " ");
+ quote = 0;
+ switch (c->var_type)
+ {
+ case var_string:
+ {
+ unsigned char *p;
+
+ if (*(unsigned char **) c->var)
+ fputstr_filtered (*(unsigned char **) c->var, '"', stb->stream);
+ quote = 1;
+ }
+ break;
+ case var_string_noescape:
+ case var_filename:
+ case var_enum:
+ if (*(char **) c->var)
+ fputs_filtered (*(char **) c->var, stb->stream);
+ quote = 1;
+ break;
+ case var_boolean:
+ fputs_filtered (*(int *) c->var ? "on" : "off", stb->stream);
+ break;
+ case var_auto_boolean:
+ switch (*(enum cmd_auto_boolean*) c->var)
+ {
+ case CMD_AUTO_BOOLEAN_TRUE:
+ fputs_filtered ("on", stb->stream);
+ break;
+ case CMD_AUTO_BOOLEAN_FALSE:
+ fputs_filtered ("off", stb->stream);
+ break;
+ case CMD_AUTO_BOOLEAN_AUTO:
+ fputs_filtered ("auto", stb->stream);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "do_setshow_command: invalid var_auto_boolean");
+ break;
+ }
+ break;
+ case var_uinteger:
+ if (*(unsigned int *) c->var == UINT_MAX)
+ {
+ fputs_filtered ("unlimited", stb->stream);
+ break;
+ }
+ /* else fall through */
+ case var_zinteger:
+ fprintf_filtered (stb->stream, "%u", *(unsigned int *) c->var);
+ break;
+ case var_integer:
+ if (*(int *) c->var == INT_MAX)
+ {
+ fputs_filtered ("unlimited", stb->stream);
+ }
+ else
+ fprintf_filtered (stb->stream, "%d", *(int *) c->var);
+ break;
+
+ default:
+ error ("gdb internal error: bad var_type in do_setshow_command");
+ }
+ if (quote)
+ ui_out_text (uiout, "\"");
+ ui_out_field_stream (uiout, "value", stb);
+ if (quote)
+ ui_out_text (uiout, "\"");
+ ui_out_text (uiout, ".\n");
+ do_cleanups (old_chain);
+ }
+ else
+ error ("gdb internal error: bad cmd_type in do_setshow_command");
+ c->func (c, NULL, from_tty);
+ if (c->type == set_cmd && set_hook)
+ set_hook (c);
+}
+
+/* Show all the settings in a list of show commands. */
+
+void
+cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix)
+{
+ ui_out_tuple_begin (uiout, "showlist");
+ for (; list != NULL; list = list->next)
+ {
+ /* If we find a prefix, run its list, prefixing our output by its
+ prefix (with "show " skipped). */
+ if (list->prefixlist && !list->abbrev_flag)
+ {
+ ui_out_tuple_begin (uiout, "optionlist");
+ ui_out_field_string (uiout, "prefix", list->prefixname + 5);
+ cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5);
+ ui_out_tuple_end (uiout);
+ }
+ if (list->type == show_cmd)
+ {
+ ui_out_tuple_begin (uiout, "option");
+ ui_out_text (uiout, prefix);
+ ui_out_field_string (uiout, "name", list->name);
+ ui_out_text (uiout, ": ");
+ do_setshow_command ((char *) NULL, from_tty, list);
+ ui_out_tuple_end (uiout);
+ }
+ }
+ ui_out_tuple_end (uiout);
+}
+
diff --git a/gdb/cli/cli-setshow.h b/gdb/cli/cli-setshow.h
new file mode 100644
index 00000000000..393612a8177
--- /dev/null
+++ b/gdb/cli/cli-setshow.h
@@ -0,0 +1,36 @@
+/* Header file for GDB CLI set and show commands implementation.
+ Copyright 2000, 2001 Free Software Foundation, Inc.
+
+ 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. */
+
+#if !defined (CLI_SETSHOW_H)
+#define CLI_SETSHOW_H 1
+
+/* Exported to cli/cli-cmds.c and gdb/top.c */
+
+/* Do a "set" or "show" command. ARG is NULL if no argument, or the text
+ of the argument, and FROM_TTY is nonzero if this command is being entered
+ directly by the user (i.e. these are just like any other
+ command). C is the command list element for the command. */
+extern void do_setshow_command (char *arg, int from_tty,
+ struct cmd_list_element *c);
+
+/* Exported to cli/cli-cmds.c and gdb/top.c, language.c and valprint.c */
+
+extern void cmd_show_list (struct cmd_list_element *list, int from_tty,
+ char *prefix);
+
+#endif /* !defined (CLI_SETSHOW_H) */
diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c
new file mode 100644
index 00000000000..396d6ead5eb
--- /dev/null
+++ b/gdb/cli/cli-utils.c
@@ -0,0 +1,21 @@
+/* GDB CLI utility library.
+ Copyright 2001 Free Software Foundation, Inc.
+
+ 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 "defs.h"
+#include "cli/cli-utils.h"
+
diff --git a/gdb/cli/cli-utils.h b/gdb/cli/cli-utils.h
new file mode 100644
index 00000000000..7c318af38a4
--- /dev/null
+++ b/gdb/cli/cli-utils.h
@@ -0,0 +1,22 @@
+/* Header file for GDB CLI utility library.
+ Copyright 2001 Free Software Foundation, Inc.
+
+ 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. */
+
+#if !defined (CLI_UTILS_H)
+# define CLI_UTILS_H 1
+
+#endif /* !defined (CLI_UTILS_H) */
diff --git a/gdb/coff-solib.c b/gdb/coff-solib.c
new file mode 100644
index 00000000000..64dca7bbefd
--- /dev/null
+++ b/gdb/coff-solib.c
@@ -0,0 +1,134 @@
+/* Handle COFF SVR3 shared libraries for GDB, the GNU Debugger.
+ Copyright 1993, 1994, 1998, 1999, 2000 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 "defs.h"
+
+#include "frame.h"
+#include "bfd.h"
+#include "gdbcore.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+
+/*
+
+ GLOBAL FUNCTION
+
+ coff_solib_add -- add a shared library files to the symtab list. We
+ examine the `.lib' section of the exec file and determine the names of
+ the shared libraries.
+
+ This function is responsible for discovering those names and
+ addresses, and saving sufficient information about them to allow
+ their symbols to be read at a later time.
+
+ SYNOPSIS
+
+ void coff_solib_add (char *arg_string, int from_tty,
+ struct target_ops *target, int readsyms)
+
+ DESCRIPTION
+
+ */
+
+void
+coff_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms)
+{
+ asection *libsect;
+
+ if (!readsyms)
+ return;
+
+ libsect = bfd_get_section_by_name (exec_bfd, ".lib");
+
+ if (libsect)
+ {
+ int libsize;
+ unsigned char *lib;
+ struct libent
+ {
+ bfd_byte len[4];
+ bfd_byte nameoffset[4];
+ };
+
+ libsize = bfd_section_size (exec_bfd, libsect);
+
+ lib = (unsigned char *) alloca (libsize);
+
+ bfd_get_section_contents (exec_bfd, libsect, lib, 0, libsize);
+
+ while (libsize > 0)
+ {
+ struct libent *ent;
+ struct objfile *objfile;
+ int len, nameoffset;
+ char *filename;
+
+ ent = (struct libent *) lib;
+
+ len = bfd_get_32 (exec_bfd, ent->len);
+
+ nameoffset = bfd_get_32 (exec_bfd, ent->nameoffset);
+
+ if (len <= 0)
+ break;
+
+ filename = (char *) ent + nameoffset * 4;
+
+ objfile = symbol_file_add (filename, from_tty,
+ NULL, /* no offsets */
+ 0, /* not mainline */
+ OBJF_SHARED); /* flags */
+
+ libsize -= len * 4;
+ lib += len * 4;
+ }
+
+ /* Getting new symbols may change our opinion about what is
+ frameless. */
+ reinit_frame_cache ();
+ }
+}
+
+/*
+
+ GLOBAL FUNCTION
+
+ coff_solib_create_inferior_hook -- shared library startup support
+
+ SYNOPSIS
+
+ void coff_solib_create_inferior_hook()
+
+ DESCRIPTION
+
+ When gdb starts up the inferior, the kernel maps in the shared
+ libraries. We get here with the target stopped at it's first
+ instruction, and the libraries already mapped. At this point, this
+ function gets called via expansion of the macro
+ SOLIB_CREATE_INFERIOR_HOOK.
+ */
+
+void
+coff_solib_create_inferior_hook (void)
+{
+ coff_solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
+}
diff --git a/gdb/coff-solib.h b/gdb/coff-solib.h
new file mode 100644
index 00000000000..144f36df700
--- /dev/null
+++ b/gdb/coff-solib.h
@@ -0,0 +1,186 @@
+/* COFF (SVR3) Shared library declarations for GDB, the GNU Debugger.
+ Copyright 1992, 1993, 1998, 1999, 2000 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. */
+
+/* Forward decl's for prototypes */
+struct target_ops;
+
+/* Called when we free all symtabs, to free the shared library information
+ as well. */
+
+#if 0
+#define CLEAR_SOLIB coff_clear_solib
+
+extern void coff_clear_solib (void);
+#endif
+
+/* Called to add symbols from a shared library to gdb's symbol table. */
+
+#define SOLIB_ADD(filename, from_tty, targ, readsyms) \
+ coff_solib_add (filename, from_tty, targ, readsyms)
+
+extern void coff_solib_add (char *, int, struct target_ops *, int);
+
+/* Function to be called when the inferior starts up, to discover the names
+ of shared libraries that are dynamically linked, the base addresses to
+ which they are linked, and sufficient information to read in their symbols
+ at a later time. */
+
+#define SOLIB_CREATE_INFERIOR_HOOK(PID) coff_solib_create_inferior_hook()
+
+extern void coff_solib_create_inferior_hook (void); /* solib.c */
+
+/* Function to be called to remove the connection between debugger and
+ dynamic linker that was established by SOLIB_CREATE_INFERIOR_HOOK.
+ (This operation does not remove shared library information from
+ the debugger, as CLEAR_SOLIB does.)
+
+ This functionality is presently not implemented for this target.
+ */
+#define SOLIB_REMOVE_INFERIOR_HOOK(PID) (0)
+
+/* This function is called by the "catch load" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is loaded.
+
+ Presently, this functionality is not implemented.
+ */
+#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag,filename,cond_string) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+
+/* This function is called by the "catch unload" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is unloaded.
+
+ Presently, this functionality is not implemented.
+ */
+#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename,cond_string) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+
+/* This function returns TRUE if the dynamic linker has just reported
+ a load of a library.
+
+ This function must be used only when the inferior has stopped in
+ the dynamic linker hook, or undefined results are guaranteed.
+
+ Presently, this functionality is not implemented.
+ */
+/*
+ #define SOLIB_HAVE_LOAD_EVENT(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+ */
+
+#define SOLIB_HAVE_LOAD_EVENT(pid) \
+(0)
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been loaded.
+
+ This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the inferior
+ has stopped in the dynamic linker hook, and becomes invalid as soon
+ as the inferior is continued. Clients should make a copy of this
+ string if they wish to continue the inferior and then access the string.
+
+ Presently, this functionality is not implemented.
+ */
+
+/*
+ #define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+ */
+
+#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \
+(0)
+
+/* This function returns TRUE if the dynamic linker has just reported
+ an unload of a library.
+
+ This function must be used only when the inferior has stopped in
+ the dynamic linker hook, or undefined results are guaranteed.
+
+ Presently, this functionality is not implemented.
+ */
+/*
+ #define SOLIB_HAVE_UNLOAD_EVENT(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+ */
+
+#define SOLIB_HAVE_UNLOAD_EVENT(pid) \
+(0)
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been unloaded.
+
+ This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the inferior
+ has stopped in the dynamic linker hook, and becomes invalid as soon
+ as the inferior is continued. Clients should make a copy of this
+ string if they wish to continue the inferior and then access the string.
+
+ Presently, this functionality is not implemented.
+ */
+/*
+ #define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+ */
+
+#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \
+(0)
+
+/* This function returns TRUE if pc is the address of an instruction that
+ lies within the dynamic linker (such as the event hook, or the dld
+ itself).
+
+ This function must be used only when a dynamic linker event has been
+ caught, and the inferior is being stepped out of the hook, or undefined
+ results are guaranteed.
+
+ Presently, this functionality is not implemented.
+ */
+
+/*
+ #define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+ */
+
+#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \
+(0)
+
+/* This function must be called when the inferior is killed, and the program
+ restarted. This is not the same as CLEAR_SOLIB, in that it doesn't discard
+ any symbol tables.
+
+ Presently, this functionality is not implemented.
+ */
+#define SOLIB_RESTART() \
+ (0)
+
+/* If we can't set a breakpoint, and it's in a shared library, just
+ disable it. */
+
+#if 0
+#define DISABLE_UNSETTABLE_BREAK(addr) coff_solib_address(addr)
+
+extern int solib_address (CORE_ADDR); /* solib.c */
+#endif
diff --git a/gdb/coffread.c b/gdb/coffread.c
new file mode 100644
index 00000000000..84b3761cf55
--- /dev/null
+++ b/gdb/coffread.c
@@ -0,0 +1,2149 @@
+/* Read coff symbol tables and convert to internal format, for GDB.
+ Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
+
+ 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "demangle.h"
+#include "breakpoint.h"
+
+#include "bfd.h"
+#include "obstack.h"
+
+#include "gdb_string.h"
+#include <ctype.h>
+
+#include "coff/internal.h" /* Internal format of COFF symbols in BFD */
+#include "libcoff.h" /* FIXME secret internal data from BFD */
+
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "gdb-stabs.h"
+#include "stabsread.h"
+#include "complaints.h"
+#include "target.h"
+#include "gdb_assert.h"
+
+extern void _initialize_coffread (void);
+
+struct coff_symfile_info
+ {
+ file_ptr min_lineno_offset; /* Where in file lowest line#s are */
+ file_ptr max_lineno_offset; /* 1+last byte of line#s in file */
+
+ CORE_ADDR textaddr; /* Addr of .text section. */
+ unsigned int textsize; /* Size of .text section. */
+ struct stab_section_list *stabsects; /* .stab sections. */
+ asection *stabstrsect; /* Section pointer for .stab section */
+ char *stabstrdata;
+ };
+
+/* Translate an external name string into a user-visible name. */
+#define EXTERNAL_NAME(string, abfd) \
+ (string[0] == bfd_get_symbol_leading_char(abfd)? string+1: string)
+
+/* To be an sdb debug type, type must have at least a basic or primary
+ derived type. Using this rather than checking against T_NULL is
+ said to prevent core dumps if we try to operate on Michael Bloom
+ dbx-in-coff file. */
+
+#define SDB_TYPE(type) (BTYPE(type) | (type & N_TMASK))
+
+/* Core address of start and end of text of current source file.
+ This comes from a ".text" symbol where x_nlinno > 0. */
+
+static CORE_ADDR current_source_start_addr;
+static CORE_ADDR current_source_end_addr;
+
+/* The addresses of the symbol table stream and number of symbols
+ of the object file we are reading (as copied into core). */
+
+static bfd *nlist_bfd_global;
+static int nlist_nsyms_global;
+
+
+/* Pointers to scratch storage, used for reading raw symbols and auxents. */
+
+static char *temp_sym;
+static char *temp_aux;
+
+/* Local variables that hold the shift and mask values for the
+ COFF file that we are currently reading. These come back to us
+ from BFD, and are referenced by their macro names, as well as
+ internally to the BTYPE, ISPTR, ISFCN, ISARY, ISTAG, and DECREF
+ macros from include/coff/internal.h . */
+
+static unsigned local_n_btmask;
+static unsigned local_n_btshft;
+static unsigned local_n_tmask;
+static unsigned local_n_tshift;
+
+#define N_BTMASK local_n_btmask
+#define N_BTSHFT local_n_btshft
+#define N_TMASK local_n_tmask
+#define N_TSHIFT local_n_tshift
+
+/* Local variables that hold the sizes in the file of various COFF structures.
+ (We only need to know this to read them from the file -- BFD will then
+ translate the data in them, into `internal_xxx' structs in the right
+ byte order, alignment, etc.) */
+
+static unsigned local_linesz;
+static unsigned local_symesz;
+static unsigned local_auxesz;
+
+/* This is set if this is a PE format file. */
+
+static int pe_file;
+
+/* Chain of typedefs of pointers to empty struct/union types.
+ They are chained thru the SYMBOL_VALUE_CHAIN. */
+
+static struct symbol *opaque_type_chain[HASHSIZE];
+
+/* Complaints about various problems in the file being read */
+
+struct complaint ef_complaint =
+{"Unmatched .ef symbol(s) ignored starting at symnum %d", 0, 0};
+
+struct complaint ef_stack_complaint =
+{"`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d", 0, 0};
+
+struct complaint eb_stack_complaint =
+{"`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d", 0, 0};
+
+struct complaint bf_no_aux_complaint =
+{"`.bf' symbol %d has no aux entry", 0, 0};
+
+struct complaint ef_no_aux_complaint =
+{"`.ef' symbol %d has no aux entry", 0, 0};
+
+struct complaint lineno_complaint =
+{"Line number pointer %d lower than start of line numbers", 0, 0};
+
+struct complaint unexpected_type_complaint =
+{"Unexpected type for symbol %s", 0, 0};
+
+struct complaint bad_sclass_complaint =
+{"Bad n_sclass for symbol %s", 0, 0};
+
+struct complaint misordered_blocks_complaint =
+{"Blocks out of order at address %x", 0, 0};
+
+struct complaint tagndx_bad_complaint =
+{"Symbol table entry for %s has bad tagndx value", 0, 0};
+
+struct complaint eb_complaint =
+{"Mismatched .eb symbol ignored starting at symnum %d", 0, 0};
+
+/* Simplified internal version of coff symbol table information */
+
+struct coff_symbol
+ {
+ char *c_name;
+ int c_symnum; /* symbol number of this entry */
+ int c_naux; /* 0 if syment only, 1 if syment + auxent, etc */
+ long c_value;
+ int c_sclass;
+ int c_secnum;
+ unsigned int c_type;
+ };
+
+extern void stabsread_clear_cache (void);
+
+static struct type *coff_read_struct_type (int, int, int);
+
+static struct type *decode_base_type (struct coff_symbol *,
+ unsigned int, union internal_auxent *);
+
+static struct type *decode_type (struct coff_symbol *, unsigned int,
+ union internal_auxent *);
+
+static struct type *decode_function_type (struct coff_symbol *,
+ unsigned int,
+ union internal_auxent *);
+
+static struct type *coff_read_enum_type (int, int, int);
+
+static struct symbol *process_coff_symbol (struct coff_symbol *,
+ union internal_auxent *,
+ struct objfile *);
+
+static void patch_opaque_types (struct symtab *);
+
+static void enter_linenos (long, int, int, struct objfile *);
+
+static void free_linetab (void);
+
+static void free_linetab_cleanup (void *ignore);
+
+static int init_lineno (bfd *, long, int);
+
+static char *getsymname (struct internal_syment *);
+
+static char *coff_getfilename (union internal_auxent *);
+
+static void free_stringtab (void);
+
+static void free_stringtab_cleanup (void *ignore);
+
+static int init_stringtab (bfd *, long);
+
+static void read_one_sym (struct coff_symbol *,
+ struct internal_syment *, union internal_auxent *);
+
+static void coff_symtab_read (long, unsigned int, struct objfile *);
+
+/* We are called once per section from coff_symfile_read. We
+ need to examine each section we are passed, check to see
+ if it is something we are interested in processing, and
+ if so, stash away some access information for the section.
+
+ FIXME: The section names should not be hardwired strings (what
+ should they be? I don't think most object file formats have enough
+ section flags to specify what kind of debug section it is
+ -kingdon). */
+
+static void
+coff_locate_sections (bfd *abfd, asection *sectp, void *csip)
+{
+ register struct coff_symfile_info *csi;
+ const char *name;
+
+ csi = (struct coff_symfile_info *) csip;
+ name = bfd_get_section_name (abfd, sectp);
+ if (STREQ (name, ".text"))
+ {
+ csi->textaddr = bfd_section_vma (abfd, sectp);
+ csi->textsize += bfd_section_size (abfd, sectp);
+ }
+ else if (strncmp (name, ".text", sizeof ".text" - 1) == 0)
+ {
+ csi->textsize += bfd_section_size (abfd, sectp);
+ }
+ else if (STREQ (name, ".stabstr"))
+ {
+ csi->stabstrsect = sectp;
+ }
+ else if (strncmp (name, ".stab", sizeof ".stab" - 1) == 0)
+ {
+ const char *s;
+
+ /* We can have multiple .stab sections if linked with
+ --split-by-reloc. */
+ for (s = name + sizeof ".stab" - 1; *s != '\0'; s++)
+ if (!isdigit (*s))
+ break;
+ if (*s == '\0')
+ {
+ struct stab_section_list *n, **pn;
+
+ n = ((struct stab_section_list *)
+ xmalloc (sizeof (struct stab_section_list)));
+ n->section = sectp;
+ n->next = NULL;
+ for (pn = &csi->stabsects; *pn != NULL; pn = &(*pn)->next)
+ ;
+ *pn = n;
+
+ /* This will be run after coffstab_build_psymtabs is called
+ in coff_symfile_read, at which point we no longer need
+ the information. */
+ make_cleanup (xfree, n);
+ }
+ }
+}
+
+/* Return the section_offsets* that CS points to. */
+static int cs_to_section (struct coff_symbol *, struct objfile *);
+
+struct find_targ_sec_arg
+ {
+ int targ_index;
+ asection **resultp;
+ };
+
+static void
+find_targ_sec (bfd *abfd, asection *sect, void *obj)
+{
+ struct find_targ_sec_arg *args = (struct find_targ_sec_arg *) obj;
+ if (sect->target_index == args->targ_index)
+ *args->resultp = sect;
+}
+
+/* Return the section number (SECT_OFF_*) that CS points to. */
+static int
+cs_to_section (struct coff_symbol *cs, struct objfile *objfile)
+{
+ asection *sect = NULL;
+ struct find_targ_sec_arg args;
+ int off = SECT_OFF_TEXT (objfile);
+
+ args.targ_index = cs->c_secnum;
+ args.resultp = &sect;
+ bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
+ if (sect != NULL)
+ {
+ /* This is the section. Figure out what SECT_OFF_* code it is. */
+ if (bfd_get_section_flags (abfd, sect) & SEC_CODE)
+ off = SECT_OFF_TEXT (objfile);
+ else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
+ off = SECT_OFF_DATA (objfile);
+ else
+ /* Just return the bfd section index. */
+ off = sect->index;
+ }
+ return off;
+}
+
+/* Return the address of the section of a COFF symbol. */
+
+static CORE_ADDR cs_section_address (struct coff_symbol *, bfd *);
+
+static CORE_ADDR
+cs_section_address (struct coff_symbol *cs, bfd *abfd)
+{
+ asection *sect = NULL;
+ struct find_targ_sec_arg args;
+ CORE_ADDR addr = 0;
+
+ args.targ_index = cs->c_secnum;
+ args.resultp = &sect;
+ bfd_map_over_sections (abfd, find_targ_sec, &args);
+ if (sect != NULL)
+ addr = bfd_get_section_vma (objfile->obfd, sect);
+ return addr;
+}
+
+/* Look up a coff type-number index. Return the address of the slot
+ where the type for that index is stored.
+ The type-number is in INDEX.
+
+ This can be used for finding the type associated with that index
+ or for associating a new type with the index. */
+
+static struct type **
+coff_lookup_type (register int index)
+{
+ if (index >= type_vector_length)
+ {
+ int old_vector_length = type_vector_length;
+
+ type_vector_length *= 2;
+ if (index /* is still */ >= type_vector_length)
+ type_vector_length = index * 2;
+
+ type_vector = (struct type **)
+ xrealloc ((char *) type_vector,
+ type_vector_length * sizeof (struct type *));
+ memset (&type_vector[old_vector_length], 0,
+ (type_vector_length - old_vector_length) * sizeof (struct type *));
+ }
+ return &type_vector[index];
+}
+
+/* Make sure there is a type allocated for type number index
+ and return the type object.
+ This can create an empty (zeroed) type object. */
+
+static struct type *
+coff_alloc_type (int index)
+{
+ register struct type **type_addr = coff_lookup_type (index);
+ register struct type *type = *type_addr;
+
+ /* If we are referring to a type not known at all yet,
+ allocate an empty type for it.
+ We will fill it in later if we find out how. */
+ if (type == NULL)
+ {
+ type = alloc_type (current_objfile);
+ *type_addr = type;
+ }
+ return type;
+}
+
+/* Start a new symtab for a new source file.
+ This is called when a COFF ".file" symbol is seen;
+ it indicates the start of data for one original source file. */
+
+static void
+coff_start_symtab (char *name)
+{
+ start_symtab (
+ /* We fill in the filename later. start_symtab puts
+ this pointer into last_source_file and we put it in
+ subfiles->name, which end_symtab frees; that's why
+ it must be malloc'd. */
+ savestring (name, strlen (name)),
+ /* We never know the directory name for COFF. */
+ NULL,
+ /* The start address is irrelevant, since we set
+ last_source_start_addr in coff_end_symtab. */
+ 0);
+ record_debugformat ("COFF");
+}
+
+/* Save the vital information from when starting to read a file,
+ for use when closing off the current file.
+ NAME is the file name the symbols came from, START_ADDR is the first
+ text address for the file, and SIZE is the number of bytes of text. */
+
+static void
+complete_symtab (char *name, CORE_ADDR start_addr, unsigned int size)
+{
+ if (last_source_file != NULL)
+ xfree (last_source_file);
+ last_source_file = savestring (name, strlen (name));
+ current_source_start_addr = start_addr;
+ current_source_end_addr = start_addr + size;
+
+ if (current_objfile->ei.entry_point >= current_source_start_addr &&
+ current_objfile->ei.entry_point < current_source_end_addr)
+ {
+ current_objfile->ei.entry_file_lowpc = current_source_start_addr;
+ current_objfile->ei.entry_file_highpc = current_source_end_addr;
+ }
+}
+
+/* Finish the symbol definitions for one main source file,
+ close off all the lexical contexts for that file
+ (creating struct block's for them), then make the
+ struct symtab for that file and put it in the list of all such. */
+
+static void
+coff_end_symtab (struct objfile *objfile)
+{
+ struct symtab *symtab;
+
+ last_source_start_addr = current_source_start_addr;
+
+ symtab = end_symtab (current_source_end_addr, objfile, SECT_OFF_TEXT (objfile));
+
+ if (symtab != NULL)
+ free_named_symtabs (symtab->filename);
+
+ /* Reinitialize for beginning of new file. */
+ last_source_file = NULL;
+}
+
+static void
+record_minimal_symbol (char *name, CORE_ADDR address,
+ enum minimal_symbol_type type, struct objfile *objfile)
+{
+ /* We don't want TDESC entry points in the minimal symbol table */
+ if (name[0] == '@')
+ return;
+
+ prim_record_minimal_symbol (name, address, type, objfile);
+}
+
+/* coff_symfile_init ()
+ is the coff-specific initialization routine for reading symbols.
+ It is passed a struct objfile which contains, among other things,
+ the BFD for the file whose symbols are being read, and a slot for
+ a pointer to "private data" which we fill with cookies and other
+ treats for coff_symfile_read ().
+
+ We will only be called if this is a COFF or COFF-like file.
+ BFD handles figuring out the format of the file, and code in symtab.c
+ uses BFD's determination to vector to us.
+
+ The ultimate result is a new symtab (or, FIXME, eventually a psymtab). */
+
+static void
+coff_symfile_init (struct objfile *objfile)
+{
+ /* Allocate struct to keep track of stab reading. */
+ objfile->sym_stab_info = (struct dbx_symfile_info *)
+ xmmalloc (objfile->md, sizeof (struct dbx_symfile_info));
+
+ memset (objfile->sym_stab_info, 0,
+ sizeof (struct dbx_symfile_info));
+
+ /* Allocate struct to keep track of the symfile */
+ objfile->sym_private = xmmalloc (objfile->md,
+ sizeof (struct coff_symfile_info));
+
+ memset (objfile->sym_private, 0, sizeof (struct coff_symfile_info));
+
+ /* COFF objects may be reordered, so set OBJF_REORDERED. If we
+ find this causes a significant slowdown in gdb then we could
+ set it in the debug symbol readers only when necessary. */
+ objfile->flags |= OBJF_REORDERED;
+
+ init_entry_point_info (objfile);
+}
+
+/* This function is called for every section; it finds the outer limits
+ of the line table (minimum and maximum file offset) so that the
+ mainline code can read the whole thing for efficiency. */
+
+/* ARGSUSED */
+static void
+find_linenos (bfd *abfd, sec_ptr asect, void *vpinfo)
+{
+ struct coff_symfile_info *info;
+ int size, count;
+ file_ptr offset, maxoff;
+
+/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
+ count = asect->lineno_count;
+/* End of warning */
+
+ if (count == 0)
+ return;
+ size = count * local_linesz;
+
+ info = (struct coff_symfile_info *) vpinfo;
+/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
+ offset = asect->line_filepos;
+/* End of warning */
+
+ if (offset < info->min_lineno_offset || info->min_lineno_offset == 0)
+ info->min_lineno_offset = offset;
+
+ maxoff = offset + size;
+ if (maxoff > info->max_lineno_offset)
+ info->max_lineno_offset = maxoff;
+}
+
+
+/* The BFD for this file -- only good while we're actively reading
+ symbols into a psymtab or a symtab. */
+
+static bfd *symfile_bfd;
+
+/* Read a symbol file, after initialization by coff_symfile_init. */
+
+/* ARGSUSED */
+static void
+coff_symfile_read (struct objfile *objfile, int mainline)
+{
+ struct coff_symfile_info *info;
+ struct dbx_symfile_info *dbxinfo;
+ bfd *abfd = objfile->obfd;
+ coff_data_type *cdata = coff_data (abfd);
+ char *name = bfd_get_filename (abfd);
+ register int val;
+ unsigned int num_symbols;
+ int symtab_offset;
+ int stringtab_offset;
+ struct cleanup *back_to;
+ int stabstrsize;
+ int len;
+ char * target;
+
+ info = (struct coff_symfile_info *) objfile->sym_private;
+ dbxinfo = objfile->sym_stab_info;
+ symfile_bfd = abfd; /* Kludge for swap routines */
+
+/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
+ num_symbols = bfd_get_symcount (abfd); /* How many syms */
+ symtab_offset = cdata->sym_filepos; /* Symbol table file offset */
+ stringtab_offset = symtab_offset + /* String table file offset */
+ num_symbols * cdata->local_symesz;
+
+ /* Set a few file-statics that give us specific information about
+ the particular COFF file format we're reading. */
+ local_n_btmask = cdata->local_n_btmask;
+ local_n_btshft = cdata->local_n_btshft;
+ local_n_tmask = cdata->local_n_tmask;
+ local_n_tshift = cdata->local_n_tshift;
+ local_linesz = cdata->local_linesz;
+ local_symesz = cdata->local_symesz;
+ local_auxesz = cdata->local_auxesz;
+
+ /* Allocate space for raw symbol and aux entries, based on their
+ space requirements as reported by BFD. */
+ temp_sym = (char *) xmalloc
+ (cdata->local_symesz + cdata->local_auxesz);
+ temp_aux = temp_sym + cdata->local_symesz;
+ back_to = make_cleanup (free_current_contents, &temp_sym);
+
+ /* We need to know whether this is a PE file, because in PE files,
+ unlike standard COFF files, symbol values are stored as offsets
+ from the section address, rather than as absolute addresses.
+ FIXME: We should use BFD to read the symbol table, and thus avoid
+ this problem. */
+ pe_file =
+ strncmp (bfd_get_target (objfile->obfd), "pe", 2) == 0
+ || strncmp (bfd_get_target (objfile->obfd), "epoc-pe", 7) == 0;
+
+/* End of warning */
+
+ /* Read the line number table, all at once. */
+ info->min_lineno_offset = 0;
+ info->max_lineno_offset = 0;
+ bfd_map_over_sections (abfd, find_linenos, (void *) info);
+
+ make_cleanup (free_linetab_cleanup, 0 /*ignore*/);
+ val = init_lineno (abfd, info->min_lineno_offset,
+ info->max_lineno_offset - info->min_lineno_offset);
+ if (val < 0)
+ error ("\"%s\": error reading line numbers\n", name);
+
+ /* Now read the string table, all at once. */
+
+ make_cleanup (free_stringtab_cleanup, 0 /*ignore*/);
+ val = init_stringtab (abfd, stringtab_offset);
+ if (val < 0)
+ error ("\"%s\": can't get string table", name);
+
+ init_minimal_symbol_collection ();
+ make_cleanup_discard_minimal_symbols ();
+
+ /* Now that the executable file is positioned at symbol table,
+ process it and define symbols accordingly. */
+
+ coff_symtab_read ((long) symtab_offset, num_symbols, objfile);
+
+ /* Sort symbols alphabetically within each block. */
+
+ {
+ struct symtab *s;
+
+ for (s = objfile->symtabs; s != NULL; s = s->next)
+ sort_symtab_syms (s);
+ }
+
+ /* Install any minimal symbols that have been collected as the current
+ minimal symbols for this objfile. */
+
+ install_minimal_symbols (objfile);
+
+ bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);
+
+ if (info->stabsects)
+ {
+ if (!info->stabstrsect)
+ {
+ error (("The debugging information in `%s' is corrupted.\n"
+ "The file has a `.stabs' section, but no `.stabstr' "
+ "section."),
+ name);
+ }
+
+ /* FIXME: dubious. Why can't we use something normal like
+ bfd_get_section_contents? */
+ bfd_seek (abfd, abfd->where, 0);
+
+ stabstrsize = bfd_section_size (abfd, info->stabstrsect);
+
+ coffstab_build_psymtabs (objfile,
+ mainline,
+ info->textaddr, info->textsize,
+ info->stabsects,
+ info->stabstrsect->filepos, stabstrsize);
+ }
+ if (dwarf2_has_info (abfd))
+ {
+ /* DWARF2 sections. */
+ dwarf2_build_psymtabs (objfile, mainline);
+ }
+
+ do_cleanups (back_to);
+}
+
+static void
+coff_new_init (struct objfile *ignore)
+{
+}
+
+/* Perform any local cleanups required when we are done with a particular
+ objfile. I.E, we are in the process of discarding all symbol information
+ for an objfile, freeing up all memory held for it, and unlinking the
+ objfile struct from the global list of known objfiles. */
+
+static void
+coff_symfile_finish (struct objfile *objfile)
+{
+ if (objfile->sym_private != NULL)
+ {
+ xmfree (objfile->md, objfile->sym_private);
+ }
+
+ /* Let stabs reader clean up */
+ stabsread_clear_cache ();
+}
+
+
+/* Given pointers to a symbol table in coff style exec file,
+ analyze them and create struct symtab's describing the symbols.
+ NSYMS is the number of symbols in the symbol table.
+ We read them one at a time using read_one_sym (). */
+
+static void
+coff_symtab_read (long symtab_offset, unsigned int nsyms,
+ struct objfile *objfile)
+{
+ register struct context_stack *new;
+ struct coff_symbol coff_symbol;
+ register struct coff_symbol *cs = &coff_symbol;
+ static struct internal_syment main_sym;
+ static union internal_auxent main_aux;
+ struct coff_symbol fcn_cs_saved;
+ static struct internal_syment fcn_sym_saved;
+ static union internal_auxent fcn_aux_saved;
+ struct symtab *s;
+ /* A .file is open. */
+ int in_source_file = 0;
+ int next_file_symnum = -1;
+ /* Name of the current file. */
+ char *filestring = "";
+ int depth = 0;
+ int fcn_first_line = 0;
+ CORE_ADDR fcn_first_line_addr = 0;
+ int fcn_last_line = 0;
+ int fcn_start_addr = 0;
+ long fcn_line_ptr = 0;
+ int val;
+ CORE_ADDR tmpaddr;
+
+ /* Work around a stdio bug in SunOS4.1.1 (this makes me nervous....
+ it's hard to know I've really worked around it. The fix should be
+ harmless, anyway). The symptom of the bug is that the first
+ fread (in read_one_sym), will (in my example) actually get data
+ from file offset 268, when the fseek was to 264 (and ftell shows
+ 264). This causes all hell to break loose. I was unable to
+ reproduce this on a short test program which operated on the same
+ file, performing (I think) the same sequence of operations.
+
+ It stopped happening when I put in this (former) rewind().
+
+ FIXME: Find out if this has been reported to Sun, whether it has
+ been fixed in a later release, etc. */
+
+ bfd_seek (objfile->obfd, 0, 0);
+
+ /* Position to read the symbol table. */
+ val = bfd_seek (objfile->obfd, (long) symtab_offset, 0);
+ if (val < 0)
+ perror_with_name (objfile->name);
+
+ current_objfile = objfile;
+ nlist_bfd_global = objfile->obfd;
+ nlist_nsyms_global = nsyms;
+ last_source_file = NULL;
+ memset (opaque_type_chain, 0, sizeof opaque_type_chain);
+
+ if (type_vector) /* Get rid of previous one */
+ xfree (type_vector);
+ type_vector_length = 160;
+ type_vector = (struct type **)
+ xmalloc (type_vector_length * sizeof (struct type *));
+ memset (type_vector, 0, type_vector_length * sizeof (struct type *));
+
+ coff_start_symtab ("");
+
+ symnum = 0;
+ while (symnum < nsyms)
+ {
+ QUIT; /* Make this command interruptable. */
+
+ read_one_sym (cs, &main_sym, &main_aux);
+
+ if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
+ {
+ if (last_source_file)
+ coff_end_symtab (objfile);
+
+ coff_start_symtab ("_globals_");
+ complete_symtab ("_globals_", 0, 0);
+ /* done with all files, everything from here on out is globals */
+ }
+
+ /* Special case for file with type declarations only, no text. */
+ if (!last_source_file && SDB_TYPE (cs->c_type)
+ && cs->c_secnum == N_DEBUG)
+ complete_symtab (filestring, 0, 0);
+
+ /* Typedefs should not be treated as symbol definitions. */
+ if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
+ {
+ /* Record all functions -- external and static -- in minsyms. */
+ tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ record_minimal_symbol (cs->c_name, tmpaddr, mst_text, objfile);
+
+ fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
+ fcn_start_addr = tmpaddr;
+ fcn_cs_saved = *cs;
+ fcn_sym_saved = main_sym;
+ fcn_aux_saved = main_aux;
+ continue;
+ }
+
+ switch (cs->c_sclass)
+ {
+ case C_EFCN:
+ case C_EXTDEF:
+ case C_ULABEL:
+ case C_USTATIC:
+ case C_LINE:
+ case C_ALIAS:
+ case C_HIDDEN:
+ complain (&bad_sclass_complaint, cs->c_name);
+ break;
+
+ case C_FILE:
+ /* c_value field contains symnum of next .file entry in table
+ or symnum of first global after last .file. */
+ next_file_symnum = cs->c_value;
+ if (cs->c_naux > 0)
+ filestring = coff_getfilename (&main_aux);
+ else
+ filestring = "";
+
+ /* Complete symbol table for last object file
+ containing debugging information. */
+ if (last_source_file)
+ {
+ coff_end_symtab (objfile);
+ coff_start_symtab (filestring);
+ }
+ in_source_file = 1;
+ break;
+
+ /* C_LABEL is used for labels and static functions. Including
+ it here allows gdb to see static functions when no debug
+ info is available. */
+ case C_LABEL:
+ /* However, labels within a function can make weird backtraces,
+ so filter them out (from phdm@macqel.be). */
+ if (within_function)
+ break;
+ case C_STAT:
+ case C_THUMBLABEL:
+ case C_THUMBSTAT:
+ case C_THUMBSTATFUNC:
+ if (cs->c_name[0] == '.')
+ {
+ if (STREQ (cs->c_name, ".text"))
+ {
+ /* FIXME: don't wire in ".text" as section name
+ or symbol name! */
+ /* Check for in_source_file deals with case of
+ a file with debugging symbols
+ followed by a later file with no symbols. */
+ if (in_source_file)
+ complete_symtab (filestring,
+ cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
+ main_aux.x_scn.x_scnlen);
+ in_source_file = 0;
+ }
+ /* flush rest of '.' symbols */
+ break;
+ }
+ else if (!SDB_TYPE (cs->c_type)
+ && cs->c_name[0] == 'L'
+ && (strncmp (cs->c_name, "LI%", 3) == 0
+ || strncmp (cs->c_name, "LF%", 3) == 0
+ || strncmp (cs->c_name, "LC%", 3) == 0
+ || strncmp (cs->c_name, "LP%", 3) == 0
+ || strncmp (cs->c_name, "LPB%", 4) == 0
+ || strncmp (cs->c_name, "LBB%", 4) == 0
+ || strncmp (cs->c_name, "LBE%", 4) == 0
+ || strncmp (cs->c_name, "LPBX%", 5) == 0))
+ /* At least on a 3b1, gcc generates swbeg and string labels
+ that look like this. Ignore them. */
+ break;
+ /* fall in for static symbols that don't start with '.' */
+ case C_THUMBEXT:
+ case C_THUMBEXTFUNC:
+ case C_EXT:
+ {
+ /* Record it in the minimal symbols regardless of
+ SDB_TYPE. This parallels what we do for other debug
+ formats, and probably is needed to make
+ print_address_symbolic work right without the (now
+ gone) "set fast-symbolic-addr off" kludge. */
+
+ /* FIXME: should use mst_abs, and not relocate, if absolute. */
+ enum minimal_symbol_type ms_type;
+ int sec;
+
+ if (cs->c_secnum == N_UNDEF)
+ {
+ /* This is a common symbol. See if the target
+ environment knows where it has been relocated to. */
+ CORE_ADDR reladdr;
+ if (target_lookup_symbol (cs->c_name, &reladdr))
+ {
+ /* Error in lookup; ignore symbol. */
+ break;
+ }
+ tmpaddr = reladdr;
+ /* The address has already been relocated; make sure that
+ objfile_relocate doesn't relocate it again. */
+ sec = -2;
+ ms_type = cs->c_sclass == C_EXT
+ || cs->c_sclass == C_THUMBEXT ?
+ mst_bss : mst_file_bss;
+ }
+ else
+ {
+ sec = cs_to_section (cs, objfile);
+ tmpaddr = cs->c_value;
+ if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
+ || cs->c_sclass == C_THUMBEXT)
+ tmpaddr += ANOFFSET (objfile->section_offsets, sec);
+
+ if (sec == SECT_OFF_TEXT (objfile))
+ {
+ ms_type =
+ cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
+ || cs->c_sclass == C_THUMBEXT ?
+ mst_text : mst_file_text;
+ tmpaddr = SMASH_TEXT_ADDRESS (tmpaddr);
+ }
+ else if (sec == SECT_OFF_DATA (objfile))
+ {
+ ms_type =
+ cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
+ mst_data : mst_file_data;
+ }
+ else if (sec == SECT_OFF_BSS (objfile))
+ {
+ ms_type =
+ cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
+ mst_data : mst_file_data;
+ }
+ else
+ ms_type = mst_unknown;
+ }
+
+ if (cs->c_name[0] != '@' /* Skip tdesc symbols */ )
+ {
+ struct minimal_symbol *msym;
+
+ /* FIXME: cagney/2001-02-01: The nasty (int) -> (long)
+ -> (void*) cast is to ensure that that the value of
+ cs->c_sclass can be correctly stored in a void
+ pointer in MSYMBOL_INFO. Better solutions
+ welcome. */
+ gdb_assert (sizeof (void *) >= sizeof (cs->c_sclass));
+ msym = prim_record_minimal_symbol_and_info
+ (cs->c_name, tmpaddr, ms_type, (void *) (long) cs->c_sclass,
+ sec, NULL, objfile);
+ if (msym)
+ COFF_MAKE_MSYMBOL_SPECIAL (cs->c_sclass, msym);
+ }
+ if (SDB_TYPE (cs->c_type))
+ {
+ struct symbol *sym;
+ sym = process_coff_symbol
+ (cs, &main_aux, objfile);
+ SYMBOL_VALUE (sym) = tmpaddr;
+ SYMBOL_SECTION (sym) = sec;
+ }
+ }
+ break;
+
+ case C_FCN:
+ if (STREQ (cs->c_name, ".bf"))
+ {
+ within_function = 1;
+
+ /* value contains address of first non-init type code */
+ /* main_aux.x_sym.x_misc.x_lnsz.x_lnno
+ contains line number of '{' } */
+ if (cs->c_naux != 1)
+ complain (&bf_no_aux_complaint, cs->c_symnum);
+ fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
+ fcn_first_line_addr = cs->c_value;
+
+ /* Might want to check that locals are 0 and
+ context_stack_depth is zero, and complain if not. */
+
+ depth = 0;
+ new = push_context (depth, fcn_start_addr);
+ fcn_cs_saved.c_name = getsymname (&fcn_sym_saved);
+ new->name =
+ process_coff_symbol (&fcn_cs_saved, &fcn_aux_saved, objfile);
+ }
+ else if (STREQ (cs->c_name, ".ef"))
+ {
+ if (!within_function)
+ error ("Bad coff function information\n");
+ /* the value of .ef is the address of epilogue code;
+ not useful for gdb. */
+ /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
+ contains number of lines to '}' */
+
+ if (context_stack_depth <= 0)
+ { /* We attempted to pop an empty context stack */
+ complain (&ef_stack_complaint, cs->c_symnum);
+ within_function = 0;
+ break;
+ }
+
+ new = pop_context ();
+ /* Stack must be empty now. */
+ if (context_stack_depth > 0 || new == NULL)
+ {
+ complain (&ef_complaint, cs->c_symnum);
+ within_function = 0;
+ break;
+ }
+ if (cs->c_naux != 1)
+ {
+ complain (&ef_no_aux_complaint, cs->c_symnum);
+ fcn_last_line = 0x7FFFFFFF;
+ }
+ else
+ {
+ fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
+ }
+ /* fcn_first_line is the line number of the opening '{'.
+ Do not record it - because it would affect gdb's idea
+ of the line number of the first statement of the function -
+ except for one-line functions, for which it is also the line
+ number of all the statements and of the closing '}', and
+ for which we do not have any other statement-line-number. */
+ if (fcn_last_line == 1)
+ record_line (current_subfile, fcn_first_line,
+ fcn_first_line_addr);
+ else
+ enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line,
+ objfile);
+
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ new->start_addr,
+#if defined (FUNCTION_EPILOGUE_SIZE)
+ /* This macro should be defined only on
+ machines where the
+ fcn_aux_saved.x_sym.x_misc.x_fsize
+ field is always zero.
+ So use the .bf record information that
+ points to the epilogue and add the size
+ of the epilogue. */
+ cs->c_value
+ + FUNCTION_EPILOGUE_SIZE
+ + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
+#else
+ fcn_cs_saved.c_value
+ + fcn_aux_saved.x_sym.x_misc.x_fsize
+ + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
+#endif
+ objfile
+ );
+ within_function = 0;
+ }
+ break;
+
+ case C_BLOCK:
+ if (STREQ (cs->c_name, ".bb"))
+ {
+ tmpaddr = cs->c_value;
+ tmpaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ push_context (++depth, tmpaddr);
+ }
+ else if (STREQ (cs->c_name, ".eb"))
+ {
+ if (context_stack_depth <= 0)
+ { /* We attempted to pop an empty context stack */
+ complain (&eb_stack_complaint, cs->c_symnum);
+ break;
+ }
+
+ new = pop_context ();
+ if (depth-- != new->depth)
+ {
+ complain (&eb_complaint, symnum);
+ break;
+ }
+ if (local_symbols && context_stack_depth > 0)
+ {
+ tmpaddr =
+ cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ /* Make a block for the local symbols within. */
+ finish_block (0, &local_symbols, new->old_blocks,
+ new->start_addr, tmpaddr, objfile);
+ }
+ /* Now pop locals of block just finished. */
+ local_symbols = new->locals;
+ }
+ break;
+
+ default:
+ process_coff_symbol (cs, &main_aux, objfile);
+ break;
+ }
+ }
+
+ if (last_source_file)
+ coff_end_symtab (objfile);
+
+ /* Patch up any opaque types (references to types that are not defined
+ in the file where they are referenced, e.g. "struct foo *bar"). */
+ ALL_OBJFILE_SYMTABS (objfile, s)
+ patch_opaque_types (s);
+
+ current_objfile = NULL;
+}
+
+/* Routines for reading headers and symbols from executable. */
+
+/* Read the next symbol, swap it, and return it in both internal_syment
+ form, and coff_symbol form. Also return its first auxent, if any,
+ in internal_auxent form, and skip any other auxents. */
+
+static void
+read_one_sym (register struct coff_symbol *cs,
+ register struct internal_syment *sym,
+ register union internal_auxent *aux)
+{
+ int i;
+
+ cs->c_symnum = symnum;
+ bfd_bread (temp_sym, local_symesz, nlist_bfd_global);
+ bfd_coff_swap_sym_in (symfile_bfd, temp_sym, (char *) sym);
+ cs->c_naux = sym->n_numaux & 0xff;
+ if (cs->c_naux >= 1)
+ {
+ bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+ bfd_coff_swap_aux_in (symfile_bfd, temp_aux, sym->n_type, sym->n_sclass,
+ 0, cs->c_naux, (char *) aux);
+ /* If more than one aux entry, read past it (only the first aux
+ is important). */
+ for (i = 1; i < cs->c_naux; i++)
+ bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+ }
+ cs->c_name = getsymname (sym);
+ cs->c_value = sym->n_value;
+ cs->c_sclass = (sym->n_sclass & 0xff);
+ cs->c_secnum = sym->n_scnum;
+ cs->c_type = (unsigned) sym->n_type;
+ if (!SDB_TYPE (cs->c_type))
+ cs->c_type = 0;
+
+#if 0
+ if (cs->c_sclass & 128)
+ printf ("thumb symbol %s, class 0x%x\n", cs->c_name, cs->c_sclass);
+#endif
+
+ symnum += 1 + cs->c_naux;
+
+ /* The PE file format stores symbol values as offsets within the
+ section, rather than as absolute addresses. We correct that
+ here, if the symbol has an appropriate storage class. FIXME: We
+ should use BFD to read the symbols, rather than duplicating the
+ work here. */
+ if (pe_file)
+ {
+ switch (cs->c_sclass)
+ {
+ case C_EXT:
+ case C_THUMBEXT:
+ case C_THUMBEXTFUNC:
+ case C_SECTION:
+ case C_NT_WEAK:
+ case C_STAT:
+ case C_THUMBSTAT:
+ case C_THUMBSTATFUNC:
+ case C_LABEL:
+ case C_THUMBLABEL:
+ case C_BLOCK:
+ case C_FCN:
+ case C_EFCN:
+ if (cs->c_secnum != 0)
+ cs->c_value += cs_section_address (cs, symfile_bfd);
+ break;
+ }
+ }
+}
+
+/* Support for string table handling */
+
+static char *stringtab = NULL;
+
+static int
+init_stringtab (bfd *abfd, long offset)
+{
+ long length;
+ int val;
+ unsigned char lengthbuf[4];
+
+ free_stringtab ();
+
+ /* If the file is stripped, the offset might be zero, indicating no
+ string table. Just return with `stringtab' set to null. */
+ if (offset == 0)
+ return 0;
+
+ if (bfd_seek (abfd, offset, 0) < 0)
+ return -1;
+
+ val = bfd_bread ((char *) lengthbuf, sizeof lengthbuf, abfd);
+ length = bfd_h_get_32 (symfile_bfd, lengthbuf);
+
+ /* If no string table is needed, then the file may end immediately
+ after the symbols. Just return with `stringtab' set to null. */
+ if (val != sizeof lengthbuf || length < sizeof lengthbuf)
+ return 0;
+
+ stringtab = (char *) xmalloc (length);
+ /* This is in target format (probably not very useful, and not currently
+ used), not host format. */
+ memcpy (stringtab, lengthbuf, sizeof lengthbuf);
+ if (length == sizeof length) /* Empty table -- just the count */
+ return 0;
+
+ val = bfd_bread (stringtab + sizeof lengthbuf, length - sizeof lengthbuf,
+ abfd);
+ if (val != length - sizeof lengthbuf || stringtab[length - 1] != '\0')
+ return -1;
+
+ return 0;
+}
+
+static void
+free_stringtab (void)
+{
+ if (stringtab)
+ xfree (stringtab);
+ stringtab = NULL;
+}
+
+static void
+free_stringtab_cleanup (void *ignore)
+{
+ free_stringtab ();
+}
+
+static char *
+getsymname (struct internal_syment *symbol_entry)
+{
+ static char buffer[SYMNMLEN + 1];
+ char *result;
+
+ if (symbol_entry->_n._n_n._n_zeroes == 0)
+ {
+ /* FIXME: Probably should be detecting corrupt symbol files by
+ seeing whether offset points to within the stringtab. */
+ result = stringtab + symbol_entry->_n._n_n._n_offset;
+ }
+ else
+ {
+ strncpy (buffer, symbol_entry->_n._n_name, SYMNMLEN);
+ buffer[SYMNMLEN] = '\0';
+ result = buffer;
+ }
+ return result;
+}
+
+/* Extract the file name from the aux entry of a C_FILE symbol. Return
+ only the last component of the name. Result is in static storage and
+ is only good for temporary use. */
+
+static char *
+coff_getfilename (union internal_auxent *aux_entry)
+{
+ static char buffer[BUFSIZ];
+ register char *temp;
+ char *result;
+
+ if (aux_entry->x_file.x_n.x_zeroes == 0)
+ strcpy (buffer, stringtab + aux_entry->x_file.x_n.x_offset);
+ else
+ {
+ strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN);
+ buffer[FILNMLEN] = '\0';
+ }
+ result = buffer;
+
+ /* FIXME: We should not be throwing away the information about what
+ directory. It should go into dirname of the symtab, or some such
+ place. */
+ if ((temp = strrchr (result, '/')) != NULL)
+ result = temp + 1;
+ return (result);
+}
+
+/* Support for line number handling. */
+
+static char *linetab = NULL;
+static long linetab_offset;
+static unsigned long linetab_size;
+
+/* Read in all the line numbers for fast lookups later. Leave them in
+ external (unswapped) format in memory; we'll swap them as we enter
+ them into GDB's data structures. */
+
+static int
+init_lineno (bfd *abfd, long offset, int size)
+{
+ int val;
+
+ linetab_offset = offset;
+ linetab_size = size;
+
+ free_linetab ();
+
+ if (size == 0)
+ return 0;
+
+ if (bfd_seek (abfd, offset, 0) < 0)
+ return -1;
+
+ /* Allocate the desired table, plus a sentinel */
+ linetab = (char *) xmalloc (size + local_linesz);
+
+ val = bfd_bread (linetab, size, abfd);
+ if (val != size)
+ return -1;
+
+ /* Terminate it with an all-zero sentinel record */
+ memset (linetab + size, 0, local_linesz);
+
+ return 0;
+}
+
+static void
+free_linetab (void)
+{
+ if (linetab)
+ xfree (linetab);
+ linetab = NULL;
+}
+
+static void
+free_linetab_cleanup (void *ignore)
+{
+ free_linetab ();
+}
+
+#if !defined (L_LNNO32)
+#define L_LNNO32(lp) ((lp)->l_lnno)
+#endif
+
+static void
+enter_linenos (long file_offset, register int first_line,
+ register int last_line, struct objfile *objfile)
+{
+ register char *rawptr;
+ struct internal_lineno lptr;
+
+ if (!linetab)
+ return;
+ if (file_offset < linetab_offset)
+ {
+ complain (&lineno_complaint, file_offset);
+ if (file_offset > linetab_size) /* Too big to be an offset? */
+ return;
+ file_offset += linetab_offset; /* Try reading at that linetab offset */
+ }
+
+ rawptr = &linetab[file_offset - linetab_offset];
+
+ /* skip first line entry for each function */
+ rawptr += local_linesz;
+ /* line numbers start at one for the first line of the function */
+ first_line--;
+
+ for (;;)
+ {
+ bfd_coff_swap_lineno_in (symfile_bfd, rawptr, &lptr);
+ rawptr += local_linesz;
+ /* The next function, or the sentinel, will have L_LNNO32 zero; we exit. */
+ if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
+ record_line (current_subfile, first_line + L_LNNO32 (&lptr),
+ lptr.l_addr.l_paddr
+ + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)));
+ else
+ break;
+ }
+}
+
+static void
+patch_type (struct type *type, struct type *real_type)
+{
+ register struct type *target = TYPE_TARGET_TYPE (type);
+ register struct type *real_target = TYPE_TARGET_TYPE (real_type);
+ int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field);
+
+ TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
+ TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target);
+ TYPE_FIELDS (target) = (struct field *) TYPE_ALLOC (target, field_size);
+
+ memcpy (TYPE_FIELDS (target), TYPE_FIELDS (real_target), field_size);
+
+ if (TYPE_NAME (real_target))
+ {
+ if (TYPE_NAME (target))
+ xfree (TYPE_NAME (target));
+ TYPE_NAME (target) = concat (TYPE_NAME (real_target), NULL);
+ }
+}
+
+/* Patch up all appropriate typedef symbols in the opaque_type_chains
+ so that they can be used to print out opaque data structures properly. */
+
+static void
+patch_opaque_types (struct symtab *s)
+{
+ register struct block *b;
+ register int i;
+ register struct symbol *real_sym;
+
+ /* Go through the per-file symbols only */
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+ for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--)
+ {
+ /* Find completed typedefs to use to fix opaque ones.
+ Remove syms from the chain when their types are stored,
+ but search the whole chain, as there may be several syms
+ from different files with the same name. */
+ real_sym = BLOCK_SYM (b, i);
+ if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&
+ SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE &&
+ TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
+ TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
+ {
+ register char *name = SYMBOL_NAME (real_sym);
+ register int hash = hashname (name);
+ register struct symbol *sym, *prev;
+
+ prev = 0;
+ for (sym = opaque_type_chain[hash]; sym;)
+ {
+ if (name[0] == SYMBOL_NAME (sym)[0] &&
+ STREQ (name + 1, SYMBOL_NAME (sym) + 1))
+ {
+ if (prev)
+ {
+ SYMBOL_VALUE_CHAIN (prev) = SYMBOL_VALUE_CHAIN (sym);
+ }
+ else
+ {
+ opaque_type_chain[hash] = SYMBOL_VALUE_CHAIN (sym);
+ }
+
+ patch_type (SYMBOL_TYPE (sym), SYMBOL_TYPE (real_sym));
+
+ if (prev)
+ {
+ sym = SYMBOL_VALUE_CHAIN (prev);
+ }
+ else
+ {
+ sym = opaque_type_chain[hash];
+ }
+ }
+ else
+ {
+ prev = sym;
+ sym = SYMBOL_VALUE_CHAIN (sym);
+ }
+ }
+ }
+ }
+}
+
+static struct symbol *
+process_coff_symbol (register struct coff_symbol *cs,
+ register union internal_auxent *aux,
+ struct objfile *objfile)
+{
+ register struct symbol *sym
+ = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ char *name;
+
+ memset (sym, 0, sizeof (struct symbol));
+ name = cs->c_name;
+ name = EXTERNAL_NAME (name, objfile->obfd);
+ SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+ &objfile->symbol_obstack);
+ SYMBOL_LANGUAGE (sym) = language_auto;
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+
+ /* default assumptions */
+ SYMBOL_VALUE (sym) = cs->c_value;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_SECTION (sym) = cs_to_section (cs, objfile);
+
+ if (ISFCN (cs->c_type))
+ {
+ SYMBOL_VALUE (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ SYMBOL_TYPE (sym) =
+ lookup_function_type (decode_function_type (cs, cs->c_type, aux));
+
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+ if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
+ || cs->c_sclass == C_THUMBSTATFUNC)
+ add_symbol_to_list (sym, &file_symbols);
+ else if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
+ || cs->c_sclass == C_THUMBEXTFUNC)
+ add_symbol_to_list (sym, &global_symbols);
+ }
+ else
+ {
+ SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux);
+ switch (cs->c_sclass)
+ {
+ case C_NULL:
+ break;
+
+ case C_AUTO:
+ SYMBOL_CLASS (sym) = LOC_LOCAL;
+ add_symbol_to_list (sym, &local_symbols);
+ break;
+
+ case C_THUMBEXT:
+ case C_THUMBEXTFUNC:
+ case C_EXT:
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
+ SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ add_symbol_to_list (sym, &global_symbols);
+ break;
+
+ case C_THUMBSTAT:
+ case C_THUMBSTATFUNC:
+ case C_STAT:
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
+ SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ if (within_function)
+ {
+ /* Static symbol of local scope */
+ add_symbol_to_list (sym, &local_symbols);
+ }
+ else
+ {
+ /* Static symbol at top level of file */
+ add_symbol_to_list (sym, &file_symbols);
+ }
+ break;
+
+#ifdef C_GLBLREG /* AMD coff */
+ case C_GLBLREG:
+#endif
+ case C_REG:
+ SYMBOL_CLASS (sym) = LOC_REGISTER;
+ SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM (cs->c_value);
+ add_symbol_to_list (sym, &local_symbols);
+ break;
+
+ case C_THUMBLABEL:
+ case C_LABEL:
+ break;
+
+ case C_ARG:
+ SYMBOL_CLASS (sym) = LOC_ARG;
+ add_symbol_to_list (sym, &local_symbols);
+#if !defined (BELIEVE_PCC_PROMOTION)
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ /* If PCC says a parameter is a short or a char,
+ aligned on an int boundary, realign it to the
+ "little end" of the int. */
+ struct type *temptype;
+ temptype = lookup_fundamental_type (current_objfile,
+ FT_INTEGER);
+ if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
+ && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT
+ && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (temptype))
+ {
+ SYMBOL_VALUE (sym) +=
+ TYPE_LENGTH (temptype)
+ - TYPE_LENGTH (SYMBOL_TYPE (sym));
+ }
+ }
+#endif
+ break;
+
+ case C_REGPARM:
+ SYMBOL_CLASS (sym) = LOC_REGPARM;
+ SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM (cs->c_value);
+ add_symbol_to_list (sym, &local_symbols);
+#if !defined (BELIEVE_PCC_PROMOTION)
+ /* FIXME: This should retain the current type, since it's just
+ a register value. gnu@adobe, 26Feb93 */
+ {
+ /* If PCC says a parameter is a short or a char,
+ it is really an int. */
+ struct type *temptype;
+ temptype =
+ lookup_fundamental_type (current_objfile, FT_INTEGER);
+ if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
+ && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)
+ {
+ SYMBOL_TYPE (sym) =
+ (TYPE_UNSIGNED (SYMBOL_TYPE (sym))
+ ? lookup_fundamental_type (current_objfile,
+ FT_UNSIGNED_INTEGER)
+ : temptype);
+ }
+ }
+#endif
+ break;
+
+ case C_TPDEF:
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+
+ /* If type has no name, give it one */
+ if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
+ {
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
+ || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC)
+ {
+ /* If we are giving a name to a type such as "pointer to
+ foo" or "function returning foo", we better not set
+ the TYPE_NAME. If the program contains "typedef char
+ *caddr_t;", we don't want all variables of type char
+ * to print as caddr_t. This is not just a
+ consequence of GDB's type management; CC and GCC (at
+ least through version 2.4) both output variables of
+ either type char * or caddr_t with the type
+ refering to the C_TPDEF symbol for caddr_t. If a future
+ compiler cleans this up it GDB is not ready for it
+ yet, but if it becomes ready we somehow need to
+ disable this check (without breaking the PCC/GCC2.4
+ case).
+
+ Sigh.
+
+ Fortunately, this check seems not to be necessary
+ for anything except pointers or functions. */
+ ;
+ }
+ else
+ TYPE_NAME (SYMBOL_TYPE (sym)) =
+ concat (SYMBOL_NAME (sym), NULL);
+ }
+#ifdef CXUX_TARGET
+ /* Ignore vendor section for Harris CX/UX targets. */
+ else if (cs->c_name[0] == '$')
+ break;
+#endif /* CXUX_TARGET */
+
+ /* Keep track of any type which points to empty structured type,
+ so it can be filled from a definition from another file. A
+ simple forward reference (TYPE_CODE_UNDEF) is not an
+ empty structured type, though; the forward references
+ work themselves out via the magic of coff_lookup_type. */
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR &&
+ TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0 &&
+ TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) !=
+ TYPE_CODE_UNDEF)
+ {
+ register int i = hashname (SYMBOL_NAME (sym));
+
+ SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];
+ opaque_type_chain[i] = sym;
+ }
+ add_symbol_to_list (sym, &file_symbols);
+ break;
+
+ case C_STRTAG:
+ case C_UNTAG:
+ case C_ENTAG:
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+
+ /* Some compilers try to be helpful by inventing "fake"
+ names for anonymous enums, structures, and unions, like
+ "~0fake" or ".0fake". Thanks, but no thanks... */
+ if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
+ if (SYMBOL_NAME (sym) != NULL
+ && *SYMBOL_NAME (sym) != '~'
+ && *SYMBOL_NAME (sym) != '.')
+ TYPE_TAG_NAME (SYMBOL_TYPE (sym)) =
+ concat (SYMBOL_NAME (sym), NULL);
+
+ add_symbol_to_list (sym, &file_symbols);
+ break;
+
+ default:
+ break;
+ }
+ }
+ return sym;
+}
+
+/* Decode a coff type specifier; return the type that is meant. */
+
+static struct type *
+decode_type (register struct coff_symbol *cs, unsigned int c_type,
+ register union internal_auxent *aux)
+{
+ register struct type *type = 0;
+ unsigned int new_c_type;
+
+ if (c_type & ~N_BTMASK)
+ {
+ new_c_type = DECREF (c_type);
+ if (ISPTR (c_type))
+ {
+ type = decode_type (cs, new_c_type, aux);
+ type = lookup_pointer_type (type);
+ }
+ else if (ISFCN (c_type))
+ {
+ type = decode_type (cs, new_c_type, aux);
+ type = lookup_function_type (type);
+ }
+ else if (ISARY (c_type))
+ {
+ int i, n;
+ register unsigned short *dim;
+ struct type *base_type, *index_type, *range_type;
+
+ /* Define an array type. */
+ /* auxent refers to array, not base type */
+ if (aux->x_sym.x_tagndx.l == 0)
+ cs->c_naux = 0;
+
+ /* shift the indices down */
+ dim = &aux->x_sym.x_fcnary.x_ary.x_dimen[0];
+ i = 1;
+ n = dim[0];
+ for (i = 0; *dim && i < DIMNUM - 1; i++, dim++)
+ *dim = *(dim + 1);
+ *dim = 0;
+
+ base_type = decode_type (cs, new_c_type, aux);
+ index_type = lookup_fundamental_type (current_objfile, FT_INTEGER);
+ range_type =
+ create_range_type ((struct type *) NULL, index_type, 0, n - 1);
+ type =
+ create_array_type ((struct type *) NULL, base_type, range_type);
+ }
+ return type;
+ }
+
+ /* Reference to existing type. This only occurs with the
+ struct, union, and enum types. EPI a29k coff
+ fakes us out by producing aux entries with a nonzero
+ x_tagndx for definitions of structs, unions, and enums, so we
+ have to check the c_sclass field. SCO 3.2v4 cc gets confused
+ with pointers to pointers to defined structs, and generates
+ negative x_tagndx fields. */
+ if (cs->c_naux > 0 && aux->x_sym.x_tagndx.l != 0)
+ {
+ if (cs->c_sclass != C_STRTAG
+ && cs->c_sclass != C_UNTAG
+ && cs->c_sclass != C_ENTAG
+ && aux->x_sym.x_tagndx.l >= 0)
+ {
+ type = coff_alloc_type (aux->x_sym.x_tagndx.l);
+ return type;
+ }
+ else
+ {
+ complain (&tagndx_bad_complaint, cs->c_name);
+ /* And fall through to decode_base_type... */
+ }
+ }
+
+ return decode_base_type (cs, BTYPE (c_type), aux);
+}
+
+/* Decode a coff type specifier for function definition;
+ return the type that the function returns. */
+
+static struct type *
+decode_function_type (register struct coff_symbol *cs, unsigned int c_type,
+ register union internal_auxent *aux)
+{
+ if (aux->x_sym.x_tagndx.l == 0)
+ cs->c_naux = 0; /* auxent refers to function, not base type */
+
+ return decode_type (cs, DECREF (c_type), aux);
+}
+
+/* basic C types */
+
+static struct type *
+decode_base_type (register struct coff_symbol *cs, unsigned int c_type,
+ register union internal_auxent *aux)
+{
+ struct type *type;
+
+ switch (c_type)
+ {
+ case T_NULL:
+ /* shows up with "void (*foo)();" structure members */
+ return lookup_fundamental_type (current_objfile, FT_VOID);
+
+#if 0
+/* DGUX actually defines both T_ARG and T_VOID to the same value. */
+#ifdef T_ARG
+ case T_ARG:
+ /* Shows up in DGUX, I think. Not sure where. */
+ return lookup_fundamental_type (current_objfile, FT_VOID); /* shouldn't show up here */
+#endif
+#endif /* 0 */
+
+#ifdef T_VOID
+ case T_VOID:
+ /* Intel 960 COFF has this symbol and meaning. */
+ return lookup_fundamental_type (current_objfile, FT_VOID);
+#endif
+
+ case T_CHAR:
+ return lookup_fundamental_type (current_objfile, FT_CHAR);
+
+ case T_SHORT:
+ return lookup_fundamental_type (current_objfile, FT_SHORT);
+
+ case T_INT:
+ return lookup_fundamental_type (current_objfile, FT_INTEGER);
+
+ case T_LONG:
+ if (cs->c_sclass == C_FIELD
+ && aux->x_sym.x_misc.x_lnsz.x_size > TARGET_LONG_BIT)
+ return lookup_fundamental_type (current_objfile, FT_LONG_LONG);
+ else
+ return lookup_fundamental_type (current_objfile, FT_LONG);
+
+ case T_FLOAT:
+ return lookup_fundamental_type (current_objfile, FT_FLOAT);
+
+ case T_DOUBLE:
+ return lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
+
+ case T_LNGDBL:
+ return lookup_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
+
+ case T_STRUCT:
+ if (cs->c_naux != 1)
+ {
+ /* anonymous structure type */
+ type = coff_alloc_type (cs->c_symnum);
+ TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ TYPE_NAME (type) = NULL;
+ /* This used to set the tag to "<opaque>". But I think setting it
+ to NULL is right, and the printing code can print it as
+ "struct {...}". */
+ TYPE_TAG_NAME (type) = NULL;
+ INIT_CPLUS_SPECIFIC (type);
+ TYPE_LENGTH (type) = 0;
+ TYPE_FIELDS (type) = 0;
+ TYPE_NFIELDS (type) = 0;
+ }
+ else
+ {
+ type = coff_read_struct_type (cs->c_symnum,
+ aux->x_sym.x_misc.x_lnsz.x_size,
+ aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+ }
+ return type;
+
+ case T_UNION:
+ if (cs->c_naux != 1)
+ {
+ /* anonymous union type */
+ type = coff_alloc_type (cs->c_symnum);
+ TYPE_NAME (type) = NULL;
+ /* This used to set the tag to "<opaque>". But I think setting it
+ to NULL is right, and the printing code can print it as
+ "union {...}". */
+ TYPE_TAG_NAME (type) = NULL;
+ INIT_CPLUS_SPECIFIC (type);
+ TYPE_LENGTH (type) = 0;
+ TYPE_FIELDS (type) = 0;
+ TYPE_NFIELDS (type) = 0;
+ }
+ else
+ {
+ type = coff_read_struct_type (cs->c_symnum,
+ aux->x_sym.x_misc.x_lnsz.x_size,
+ aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+ }
+ TYPE_CODE (type) = TYPE_CODE_UNION;
+ return type;
+
+ case T_ENUM:
+ if (cs->c_naux != 1)
+ {
+ /* anonymous enum type */
+ type = coff_alloc_type (cs->c_symnum);
+ TYPE_CODE (type) = TYPE_CODE_ENUM;
+ TYPE_NAME (type) = NULL;
+ /* This used to set the tag to "<opaque>". But I think setting it
+ to NULL is right, and the printing code can print it as
+ "enum {...}". */
+ TYPE_TAG_NAME (type) = NULL;
+ TYPE_LENGTH (type) = 0;
+ TYPE_FIELDS (type) = 0;
+ TYPE_NFIELDS (type) = 0;
+ }
+ else
+ {
+ type = coff_read_enum_type (cs->c_symnum,
+ aux->x_sym.x_misc.x_lnsz.x_size,
+ aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+ }
+ return type;
+
+ case T_MOE:
+ /* shouldn't show up here */
+ break;
+
+ case T_UCHAR:
+ return lookup_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
+
+ case T_USHORT:
+ return lookup_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
+
+ case T_UINT:
+ return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
+
+ case T_ULONG:
+ if (cs->c_sclass == C_FIELD
+ && aux->x_sym.x_misc.x_lnsz.x_size > TARGET_LONG_BIT)
+ return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG);
+ else
+ return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
+ }
+ complain (&unexpected_type_complaint, cs->c_name);
+ return lookup_fundamental_type (current_objfile, FT_VOID);
+}
+
+/* This page contains subroutines of read_type. */
+
+/* Read the description of a structure (or union type) and return an
+ object describing the type. */
+
+static struct type *
+coff_read_struct_type (int index, int length, int lastsym)
+{
+ struct nextfield
+ {
+ struct nextfield *next;
+ struct field field;
+ };
+
+ register struct type *type;
+ register struct nextfield *list = 0;
+ struct nextfield *new;
+ int nfields = 0;
+ register int n;
+ char *name;
+ struct coff_symbol member_sym;
+ register struct coff_symbol *ms = &member_sym;
+ struct internal_syment sub_sym;
+ union internal_auxent sub_aux;
+ int done = 0;
+
+ type = coff_alloc_type (index);
+ TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ INIT_CPLUS_SPECIFIC (type);
+ TYPE_LENGTH (type) = length;
+
+ while (!done && symnum < lastsym && symnum < nlist_nsyms_global)
+ {
+ read_one_sym (ms, &sub_sym, &sub_aux);
+ name = ms->c_name;
+ name = EXTERNAL_NAME (name, current_objfile->obfd);
+
+ switch (ms->c_sclass)
+ {
+ case C_MOS:
+ case C_MOU:
+
+ /* Get space to record the next field's data. */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+
+ /* Save the data. */
+ list->field.name =
+ obsavestring (name,
+ strlen (name),
+ &current_objfile->symbol_obstack);
+ FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
+ FIELD_BITPOS (list->field) = 8 * ms->c_value;
+ FIELD_BITSIZE (list->field) = 0;
+ nfields++;
+ break;
+
+ case C_FIELD:
+
+ /* Get space to record the next field's data. */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+
+ /* Save the data. */
+ list->field.name =
+ obsavestring (name,
+ strlen (name),
+ &current_objfile->symbol_obstack);
+ FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
+ FIELD_BITPOS (list->field) = ms->c_value;
+ FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size;
+ nfields++;
+ break;
+
+ case C_EOS:
+ done = 1;
+ break;
+ }
+ }
+ /* Now create the vector of fields, and record how big it is. */
+
+ TYPE_NFIELDS (type) = nfields;
+ TYPE_FIELDS (type) = (struct field *)
+ TYPE_ALLOC (type, sizeof (struct field) * nfields);
+
+ /* Copy the saved-up fields into the field vector. */
+
+ for (n = nfields; list; list = list->next)
+ TYPE_FIELD (type, --n) = list->field;
+
+ return type;
+}
+
+/* Read a definition of an enumeration type,
+ and create and return a suitable type object.
+ Also defines the symbols that represent the values of the type. */
+
+/* ARGSUSED */
+static struct type *
+coff_read_enum_type (int index, int length, int lastsym)
+{
+ register struct symbol *sym;
+ register struct type *type;
+ int nsyms = 0;
+ int done = 0;
+ struct pending **symlist;
+ struct coff_symbol member_sym;
+ register struct coff_symbol *ms = &member_sym;
+ struct internal_syment sub_sym;
+ union internal_auxent sub_aux;
+ struct pending *osyms, *syms;
+ int o_nsyms;
+ register int n;
+ char *name;
+ int unsigned_enum = 1;
+
+ type = coff_alloc_type (index);
+ if (within_function)
+ symlist = &local_symbols;
+ else
+ symlist = &file_symbols;
+ osyms = *symlist;
+ o_nsyms = osyms ? osyms->nsyms : 0;
+
+ while (!done && symnum < lastsym && symnum < nlist_nsyms_global)
+ {
+ read_one_sym (ms, &sub_sym, &sub_aux);
+ name = ms->c_name;
+ name = EXTERNAL_NAME (name, current_objfile->obfd);
+
+ switch (ms->c_sclass)
+ {
+ case C_MOE:
+ sym = (struct symbol *) obstack_alloc
+ (&current_objfile->symbol_obstack,
+ sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
+
+ SYMBOL_NAME (sym) =
+ obsavestring (name, strlen (name),
+ &current_objfile->symbol_obstack);
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_VALUE (sym) = ms->c_value;
+ add_symbol_to_list (sym, symlist);
+ nsyms++;
+ break;
+
+ case C_EOS:
+ /* Sometimes the linker (on 386/ix 2.0.2 at least) screws
+ up the count of how many symbols to read. So stop
+ on .eos. */
+ done = 1;
+ break;
+ }
+ }
+
+ /* Now fill in the fields of the type-structure. */
+
+ if (length > 0)
+ TYPE_LENGTH (type) = length;
+ else
+ TYPE_LENGTH (type) = TARGET_INT_BIT / TARGET_CHAR_BIT; /* Assume ints */
+ TYPE_CODE (type) = TYPE_CODE_ENUM;
+ TYPE_NFIELDS (type) = nsyms;
+ TYPE_FIELDS (type) = (struct field *)
+ TYPE_ALLOC (type, sizeof (struct field) * nsyms);
+
+ /* Find the symbols for the values and put them into the type.
+ The symbols can be found in the symlist that we put them on
+ to cause them to be defined. osyms contains the old value
+ of that symlist; everything up to there was defined by us. */
+ /* Note that we preserve the order of the enum constants, so
+ that in something like "enum {FOO, LAST_THING=FOO}" we print
+ FOO, not LAST_THING. */
+
+ for (syms = *symlist, n = 0; syms; syms = syms->next)
+ {
+ int j = 0;
+
+ if (syms == osyms)
+ j = o_nsyms;
+ for (; j < syms->nsyms; j++, n++)
+ {
+ struct symbol *xsym = syms->symbol[j];
+ SYMBOL_TYPE (xsym) = type;
+ TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+ TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
+ if (SYMBOL_VALUE (xsym) < 0)
+ unsigned_enum = 0;
+ TYPE_FIELD_BITSIZE (type, n) = 0;
+ }
+ if (syms == osyms)
+ break;
+ }
+
+ if (unsigned_enum)
+ TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+
+ return type;
+}
+
+/* Register our ability to parse symbols for coff BFD files. */
+
+static struct sym_fns coff_sym_fns =
+{
+ bfd_target_coff_flavour,
+ coff_new_init, /* sym_new_init: init anything gbl to entire symtab */
+ coff_symfile_init, /* sym_init: read initial info, setup for sym_read() */
+ coff_symfile_read, /* sym_read: read a symbol file into symtab */
+ coff_symfile_finish, /* sym_finish: finished with file, cleanup */
+ default_symfile_offsets, /* sym_offsets: xlate external to internal form */
+ NULL /* next: pointer to next struct sym_fns */
+};
+
+void
+_initialize_coffread (void)
+{
+ add_symtab_fns (&coff_sym_fns);
+}
diff --git a/gdb/command.h b/gdb/command.h
new file mode 100644
index 00000000000..db7a7402584
--- /dev/null
+++ b/gdb/command.h
@@ -0,0 +1,262 @@
+/* Header file for command-reading library command.c.
+
+ Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1999,
+ 2000, 2002 Free Software Foundation, Inc.
+
+ 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. */
+
+#if !defined (COMMAND_H)
+#define COMMAND_H 1
+
+/* Command classes are top-level categories into which commands are broken
+ down for "help" purposes.
+ Notes on classes: class_alias is for alias commands which are not
+ abbreviations of the original command. class-pseudo is for
+ commands which are not really commands nor help topics ("stop"). */
+
+enum command_class
+{
+ /* Special args to help_list */
+ class_deprecated, all_classes = -2, all_commands = -1,
+ /* Classes of commands */
+ no_class = -1, class_run = 0, class_vars, class_stack,
+ class_files, class_support, class_info, class_breakpoint, class_trace,
+ class_alias, class_obscure, class_user, class_maintenance,
+ class_pseudo, class_tui, class_xdb
+};
+
+/* FIXME: cagney/2002-03-17: Once cmd_type() has been removed, ``enum
+ cmd_types'' can be moved from "command.h" to "cli-decode.h". */
+/* Not a set/show command. Note that some commands which begin with
+ "set" or "show" might be in this category, if their syntax does
+ not fall into one of the following categories. */
+typedef enum cmd_types
+ {
+ not_set_cmd,
+ set_cmd,
+ show_cmd
+ }
+cmd_types;
+
+/* Reasonable values for an AUTO_BOOLEAN variable. */
+enum cmd_auto_boolean
+{
+ CMD_AUTO_BOOLEAN_TRUE,
+ CMD_AUTO_BOOLEAN_FALSE,
+ CMD_AUTO_BOOLEAN_AUTO
+};
+
+/* Types of "set" or "show" command. */
+typedef enum var_types
+ {
+ /* "on" or "off". *VAR is an integer which is nonzero for on,
+ zero for off. */
+ var_boolean,
+
+ /* "on" / "true" / "enable" or "off" / "false" / "disable" or
+ "auto. *VAR is an ``enum cmd_auto_boolean''. NOTE: In general
+ a custom show command will need to be implemented - one that
+ for "auto" prints both the "auto" and the current auto-selected
+ value. */
+ var_auto_boolean,
+
+ /* Unsigned Integer. *VAR is an unsigned int. The user can type 0
+ to mean "unlimited", which is stored in *VAR as UINT_MAX. */
+ var_uinteger,
+
+ /* Like var_uinteger but signed. *VAR is an int. The user can type 0
+ to mean "unlimited", which is stored in *VAR as INT_MAX. */
+ var_integer,
+
+ /* String which the user enters with escapes (e.g. the user types \n and
+ it is a real newline in the stored string).
+ *VAR is a malloc'd string, or NULL if the string is empty. */
+ var_string,
+ /* String which stores what the user types verbatim.
+ *VAR is a malloc'd string, or NULL if the string is empty. */
+ var_string_noescape,
+ /* String which stores a filename.
+ *VAR is a malloc'd string, or NULL if the string is empty. */
+ var_filename,
+ /* ZeroableInteger. *VAR is an int. Like Unsigned Integer except
+ that zero really means zero. */
+ var_zinteger,
+ /* Enumerated type. Can only have one of the specified values. *VAR is a
+ char pointer to the name of the element that we find. */
+ var_enum
+ }
+var_types;
+
+/* This structure records one command'd definition. */
+struct cmd_list_element;
+
+/* Forward-declarations of the entry-points of cli/cli-decode.c. */
+
+extern struct cmd_list_element *add_cmd (char *, enum command_class,
+ void (*fun) (char *, int), char *,
+ struct cmd_list_element **);
+
+extern struct cmd_list_element *add_alias_cmd (char *, char *,
+ enum command_class, int,
+ struct cmd_list_element **);
+
+extern struct cmd_list_element *add_prefix_cmd (char *, enum command_class,
+ void (*fun) (char *, int),
+ char *,
+ struct cmd_list_element **,
+ char *, int,
+ struct cmd_list_element **);
+
+extern struct cmd_list_element *add_abbrev_prefix_cmd (char *,
+ enum command_class,
+ void (*fun) (char *,
+ int),
+ char *,
+ struct cmd_list_element
+ **, char *, int,
+ struct cmd_list_element
+ **);
+
+/* Set the commands corresponding callback. */
+
+extern void set_cmd_cfunc (struct cmd_list_element *cmd,
+ void (*cfunc) (char *args, int from_tty));
+
+extern void set_cmd_sfunc (struct cmd_list_element *cmd,
+ void (*sfunc) (char *args, int from_tty,
+ struct cmd_list_element * c));
+
+extern void set_cmd_completer (struct cmd_list_element *cmd,
+ char **(*completer) (char *text, char *word));
+
+/* HACK: cagney/2002-02-23: Code, mostly in tracepoints.c, grubs
+ around in cmd objects to test the value of the commands sfunc(). */
+extern int cmd_cfunc_eq (struct cmd_list_element *cmd,
+ void (*cfunc) (char *args, int from_tty));
+
+/* Each command object has a local context attached to it. . */
+extern void set_cmd_context (struct cmd_list_element *cmd, void *context);
+extern void *get_cmd_context (struct cmd_list_element *cmd);
+
+
+/* Execute CMD's pre/post hook. Throw an error if the command fails.
+ If already executing this pre/post hook, or there is no pre/post
+ hook, the call is silently ignored. */
+extern void execute_cmd_pre_hook (struct cmd_list_element *cmd);
+extern void execute_cmd_post_hook (struct cmd_list_element *cmd);
+
+/* Return the type of the command. */
+/* NOTE: cagney/2002-03-17: The add_show_from_set() function clones
+ the set command passed as a parameter. The clone operation will
+ include (BUG?) any ``set'' command callback, if present. Commands
+ like ``info set'' call all the ``show'' command callbacks.
+ Unfortunatly, for ``show'' commands cloned from ``set'', this
+ includes callbacks belonging to ``set'' commands. Making this
+ worse, this only occures if add_show_from_set() is called after
+ add_cmd_sfunc() (BUG?). */
+extern enum cmd_types cmd_type (struct cmd_list_element *cmd);
+
+
+extern struct cmd_list_element *lookup_cmd (char **,
+ struct cmd_list_element *, char *,
+ int, int);
+
+extern struct cmd_list_element *lookup_cmd_1 (char **,
+ struct cmd_list_element *,
+ struct cmd_list_element **,
+ int);
+
+extern struct cmd_list_element *
+ deprecate_cmd (struct cmd_list_element *, char * );
+
+extern void
+ deprecated_cmd_warning (char **);
+
+extern int
+ lookup_cmd_composition (char *text,
+ struct cmd_list_element **alias,
+ struct cmd_list_element **prefix_cmd,
+ struct cmd_list_element **cmd);
+
+extern struct cmd_list_element *add_com (char *, enum command_class,
+ void (*fun) (char *, int), char *);
+
+extern struct cmd_list_element *add_com_alias (char *, char *,
+ enum command_class, int);
+
+extern struct cmd_list_element *add_info (char *, void (*fun) (char *, int),
+ char *);
+
+extern struct cmd_list_element *add_info_alias (char *, char *, int);
+
+extern char **complete_on_cmdlist (struct cmd_list_element *, char *, char *);
+
+extern char **complete_on_enum (const char *enumlist[], char *, char *);
+
+extern void delete_cmd (char *, struct cmd_list_element **);
+
+extern void help_cmd (char *, struct ui_file *);
+
+extern void help_list (struct cmd_list_element *, char *,
+ enum command_class, struct ui_file *);
+
+extern void help_cmd_list (struct cmd_list_element *, enum command_class,
+ char *, int, struct ui_file *);
+
+extern struct cmd_list_element *add_set_cmd (char *name, enum
+ command_class class,
+ var_types var_type, void *var,
+ char *doc,
+ struct cmd_list_element **list);
+
+extern struct cmd_list_element *add_set_enum_cmd (char *name,
+ enum command_class class,
+ const char *enumlist[],
+ const char **var,
+ char *doc,
+ struct cmd_list_element **list);
+
+extern struct cmd_list_element *add_set_auto_boolean_cmd (char *name,
+ enum command_class class,
+ enum cmd_auto_boolean *var,
+ char *doc,
+ struct cmd_list_element **list);
+
+extern struct cmd_list_element *add_set_boolean_cmd (char *name,
+ enum command_class class,
+ int *var,
+ char *doc,
+ struct cmd_list_element **list);
+
+extern struct cmd_list_element *add_show_from_set (struct cmd_list_element *,
+ struct cmd_list_element
+ **);
+
+/* Do a "show" command for each thing on a command list. */
+
+extern void cmd_show_list (struct cmd_list_element *, int, char *);
+
+extern NORETURN void error_no_arg (char *) ATTR_NORETURN;
+
+extern void dont_repeat (void);
+
+/* Used to mark commands that don't do anything. If we just leave the
+ function field NULL, the command is interpreted as a help topic, or
+ as a class of commands. */
+
+extern void not_just_help_class_command (char *, int);
+
+#endif /* !defined (COMMAND_H) */
diff --git a/gdb/complaints.c b/gdb/complaints.c
new file mode 100644
index 00000000000..04e49a23979
--- /dev/null
+++ b/gdb/complaints.c
@@ -0,0 +1,168 @@
+/* Support for complaint handling during symbol reading in GDB.
+ Copyright 1990, 1991, 1992, 1993, 1995, 1998, 1999, 2000
+ 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 "defs.h"
+#include "complaints.h"
+#include "gdbcmd.h"
+
+extern void _initialize_complaints (void);
+
+/* Structure to manage complaints about symbol file contents. */
+
+struct complaint complaint_root[1] =
+{
+ {
+ (char *) NULL, /* Complaint message */
+ 0, /* Complaint counter */
+ complaint_root /* Next complaint. */
+ }
+};
+
+/* How many complaints about a particular thing should be printed before
+ we stop whining about it? Default is no whining at all, since so many
+ systems have ill-constructed symbol files. */
+
+static unsigned int stop_whining = 0;
+
+/* Should each complaint be self explanatory, or should we assume that
+ a series of complaints is being produced?
+ case 0: self explanatory message.
+ case 1: First message of a series that must start off with explanation.
+ case 2: Subsequent message, when user already knows we are reading
+ symbols and we can just state our piece. */
+
+static int complaint_series = 0;
+
+
+
+/* Functions to handle complaints during symbol reading. */
+
+/* Print a complaint about the input symbols, and link the complaint block
+ into a chain for later handling. */
+
+void
+complain (struct complaint *complaint,...)
+{
+ va_list args;
+ va_start (args, complaint);
+
+ complaint->counter++;
+ if (complaint->next == NULL)
+ {
+ complaint->next = complaint_root->next;
+ complaint_root->next = complaint;
+ }
+ if (complaint->counter > stop_whining)
+ {
+ return;
+ }
+ wrap_here ("");
+
+ switch (complaint_series + (info_verbose << 1))
+ {
+
+ /* Isolated messages, must be self-explanatory. */
+ case 0:
+ if (warning_hook)
+ (*warning_hook) (complaint->message, args);
+ else
+ {
+ begin_line ();
+ fputs_filtered ("During symbol reading, ", gdb_stderr);
+ wrap_here ("");
+ vfprintf_filtered (gdb_stderr, complaint->message, args);
+ fputs_filtered (".\n", gdb_stderr);
+ }
+ break;
+
+ /* First of a series, without `set verbose'. */
+ case 1:
+ if (warning_hook)
+ (*warning_hook) (complaint->message, args);
+ else
+ {
+ begin_line ();
+ fputs_filtered ("During symbol reading...", gdb_stderr);
+ vfprintf_filtered (gdb_stderr, complaint->message, args);
+ fputs_filtered ("...", gdb_stderr);
+ wrap_here ("");
+ complaint_series++;
+ }
+ break;
+
+ /* Subsequent messages of a series, or messages under `set verbose'.
+ (We'll already have produced a "Reading in symbols for XXX..."
+ message and will clean up at the end with a newline.) */
+ default:
+ if (warning_hook)
+ (*warning_hook) (complaint->message, args);
+ else
+ {
+ vfprintf_filtered (gdb_stderr, complaint->message, args);
+ fputs_filtered ("...", gdb_stderr);
+ wrap_here ("");
+ }
+ }
+ /* If GDB dumps core, we'd like to see the complaints first. Presumably
+ GDB will not be sending so many complaints that this becomes a
+ performance hog. */
+ gdb_flush (gdb_stderr);
+ va_end (args);
+}
+
+/* Clear out all complaint counters that have ever been incremented.
+ If sym_reading is 1, be less verbose about successive complaints,
+ since the messages are appearing all together during a command that
+ reads symbols (rather than scattered around as psymtabs get fleshed
+ out into symtabs at random times). If noisy is 1, we are in a
+ noisy symbol reading command, and our caller will print enough
+ context for the user to figure it out. */
+
+void
+clear_complaints (int sym_reading, int noisy)
+{
+ struct complaint *p;
+
+ for (p = complaint_root->next; p != complaint_root; p = p->next)
+ {
+ p->counter = 0;
+ }
+
+ if (!sym_reading && !noisy && complaint_series > 1 && !warning_hook)
+ {
+ /* Terminate previous series, since caller won't. */
+ puts_filtered ("\n");
+ }
+
+ complaint_series = sym_reading ? 1 + noisy : 0;
+}
+
+void
+_initialize_complaints (void)
+{
+ add_show_from_set
+ (add_set_cmd ("complaints", class_support, var_zinteger,
+ (char *) &stop_whining,
+ "Set max number of complaints about incorrect symbols.",
+ &setlist),
+ &showlist);
+
+}
diff --git a/gdb/complaints.h b/gdb/complaints.h
new file mode 100644
index 00000000000..ecd822f5b04
--- /dev/null
+++ b/gdb/complaints.h
@@ -0,0 +1,53 @@
+/* Definitions for complaint handling during symbol reading in GDB.
+ Copyright 1990, 1991, 1992, 1995, 1998, 2000
+ 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. */
+
+
+#if !defined (COMPLAINTS_H)
+#define COMPLAINTS_H
+
+
+/* Support for complaining about things in the symbol file that aren't
+ catastrophic.
+
+ Each such thing gets a counter. The first time we have the problem,
+ during a symbol read, we report it. At the end of symbol reading,
+ if verbose, we report how many of each problem we had. */
+
+struct complaint
+ {
+ char *message;
+ unsigned counter;
+ struct complaint *next;
+ };
+
+/* Root of the chain of complaints that have at some point been issued.
+ This is used to reset the counters, and/or report the total counts. */
+
+extern struct complaint complaint_root[1];
+
+/* Functions that handle complaints. (in complaints.c) */
+
+extern void complain (struct complaint *, ...);
+
+extern void clear_complaints (int, int);
+
+
+#endif /* !defined (COMPLAINTS_H) */
diff --git a/gdb/completer.c b/gdb/completer.c
new file mode 100644
index 00000000000..67ea300f14b
--- /dev/null
+++ b/gdb/completer.c
@@ -0,0 +1,715 @@
+/* Line completion stuff for GDB, the GNU debugger.
+ Copyright 2000, 2001 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "filenames.h" /* for DOSish file names */
+
+#include "cli/cli-decode.h"
+
+/* FIXME: This is needed because of lookup_cmd_1().
+ We should be calling a hook instead so we eliminate the CLI dependency. */
+#include "gdbcmd.h"
+
+/* Needed for rl_completer_word_break_characters() and for
+ filename_completion_function. */
+#include <readline/readline.h>
+
+/* readline defines this. */
+#undef savestring
+
+#include "completer.h"
+
+/* Prototypes for local functions */
+char *line_completion_function (char *text, int matches, char *line_buffer,
+ int point);
+
+/* readline uses the word breaks for two things:
+ (1) In figuring out where to point the TEXT parameter to the
+ rl_completion_entry_function. Since we don't use TEXT for much,
+ it doesn't matter a lot what the word breaks are for this purpose, but
+ it does affect how much stuff M-? lists.
+ (2) If one of the matches contains a word break character, readline
+ will quote it. That's why we switch between
+ gdb_completer_word_break_characters and
+ gdb_completer_command_word_break_characters. I'm not sure when
+ we need this behavior (perhaps for funky characters in C++ symbols?). */
+
+/* Variables which are necessary for fancy command line editing. */
+static char *gdb_completer_word_break_characters =
+" \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,-";
+
+/* When completing on command names, we remove '-' from the list of
+ word break characters, since we use it in command names. If the
+ readline library sees one in any of the current completion strings,
+ it thinks that the string needs to be quoted and automatically supplies
+ a leading quote. */
+static char *gdb_completer_command_word_break_characters =
+" \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,";
+
+/* When completing on file names, we remove from the list of word
+ break characters any characters that are commonly used in file
+ names, such as '-', '+', '~', etc. Otherwise, readline displays
+ incorrect completion candidates. */
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+/* MS-DOS and MS-Windows use colon as part of the drive spec, and most
+ programs support @foo style response files. */
+static char *gdb_completer_file_name_break_characters = " \t\n*|\"';?><@";
+#else
+static char *gdb_completer_file_name_break_characters = " \t\n*|\"';:?><";
+#endif
+
+/* These are used when completing on locations, which can mix file
+ names and symbol names separated by a colon. */
+static char *gdb_completer_loc_break_characters = " \t\n*|\"';:?><,";
+
+/* Characters that can be used to quote completion strings. Note that we
+ can't include '"' because the gdb C parser treats such quoted sequences
+ as strings. */
+static char *gdb_completer_quote_characters = "'";
+
+/* Accessor for some completer data that may interest other files. */
+
+char *
+get_gdb_completer_word_break_characters (void)
+{
+ return gdb_completer_word_break_characters;
+}
+
+char *
+get_gdb_completer_quote_characters (void)
+{
+ return gdb_completer_quote_characters;
+}
+
+/* Line completion interface function for readline. */
+
+char *
+readline_line_completion_function (char *text, int matches)
+{
+ return line_completion_function (text, matches, rl_line_buffer, rl_point);
+}
+
+/* This can be used for functions which don't want to complete on symbols
+ but don't want to complete on anything else either. */
+char **
+noop_completer (char *text, char *prefix)
+{
+ return NULL;
+}
+
+/* Complete on filenames. */
+char **
+filename_completer (char *text, char *word)
+{
+ int subsequent_name;
+ char **return_val;
+ int return_val_used;
+ int return_val_alloced;
+
+ return_val_used = 0;
+ /* Small for testing. */
+ return_val_alloced = 1;
+ return_val = (char **) xmalloc (return_val_alloced * sizeof (char *));
+
+ subsequent_name = 0;
+ while (1)
+ {
+ char *p;
+ p = filename_completion_function (text, subsequent_name);
+ if (return_val_used >= return_val_alloced)
+ {
+ return_val_alloced *= 2;
+ return_val =
+ (char **) xrealloc (return_val,
+ return_val_alloced * sizeof (char *));
+ }
+ if (p == NULL)
+ {
+ return_val[return_val_used++] = p;
+ break;
+ }
+ /* We need to set subsequent_name to a non-zero value before the
+ continue line below, because otherwise, if the first file seen
+ by GDB is a backup file whose name ends in a `~', we will loop
+ indefinitely. */
+ subsequent_name = 1;
+ /* Like emacs, don't complete on old versions. Especially useful
+ in the "source" command. */
+ if (p[strlen (p) - 1] == '~')
+ continue;
+
+ {
+ char *q;
+ if (word == text)
+ /* Return exactly p. */
+ return_val[return_val_used++] = p;
+ else if (word > text)
+ {
+ /* Return some portion of p. */
+ q = xmalloc (strlen (p) + 5);
+ strcpy (q, p + (word - text));
+ return_val[return_val_used++] = q;
+ xfree (p);
+ }
+ else
+ {
+ /* Return some of TEXT plus p. */
+ q = xmalloc (strlen (p) + (text - word) + 5);
+ strncpy (q, word, text - word);
+ q[text - word] = '\0';
+ strcat (q, p);
+ return_val[return_val_used++] = q;
+ xfree (p);
+ }
+ }
+ }
+#if 0
+ /* There is no way to do this just long enough to affect quote inserting
+ without also affecting the next completion. This should be fixed in
+ readline. FIXME. */
+ /* Insure that readline does the right thing
+ with respect to inserting quotes. */
+ rl_completer_word_break_characters = "";
+#endif
+ return return_val;
+}
+
+/* Complete on locations, which might be of two possible forms:
+
+ file:line
+ or
+ symbol+offset
+
+ This is intended to be used in commands that set breakpoints etc. */
+char **
+location_completer (char *text, char *word)
+{
+ int n_syms = 0, n_files = 0;
+ char ** fn_list = NULL;
+ char ** list = NULL;
+ char *p;
+ int quote_found = 0;
+ int quoted = *text == '\'' || *text == '"';
+ int quote_char = '\0';
+ char *colon = NULL;
+ char *file_to_match = NULL;
+ char *symbol_start = text;
+ char *orig_text = text;
+ size_t text_len;
+
+ /* Do we have an unquoted colon, as in "break foo.c::bar"? */
+ for (p = text; *p != '\0'; ++p)
+ {
+ if (*p == '\\' && p[1] == '\'')
+ p++;
+ else if (*p == '\'' || *p == '"')
+ {
+ quote_found = *p;
+ quote_char = *p++;
+ while (*p != '\0' && *p != quote_found)
+ {
+ if (*p == '\\' && p[1] == quote_found)
+ p++;
+ p++;
+ }
+
+ if (*p == quote_found)
+ quote_found = 0;
+ else
+ break; /* hit the end of text */
+ }
+#if HAVE_DOS_BASED_FILE_SYSTEM
+ /* If we have a DOS-style absolute file name at the beginning of
+ TEXT, and the colon after the drive letter is the only colon
+ we found, pretend the colon is not there. */
+ else if (p < text + 3 && *p == ':' && p == text + 1 + quoted)
+ ;
+#endif
+ else if (*p == ':' && !colon)
+ {
+ colon = p;
+ symbol_start = p + 1;
+ }
+ else if (strchr (gdb_completer_word_break_characters, *p))
+ symbol_start = p + 1;
+ }
+
+ if (quoted)
+ text++;
+ text_len = strlen (text);
+
+ /* Where is the file name? */
+ if (colon)
+ {
+ char *s;
+
+ file_to_match = (char *) xmalloc (colon - text + 1);
+ strncpy (file_to_match, text, colon - text + 1);
+ /* Remove trailing colons and quotes from the file name. */
+ for (s = file_to_match + (colon - text);
+ s > file_to_match;
+ s--)
+ if (*s == ':' || *s == quote_char)
+ *s = '\0';
+ }
+ /* If the text includes a colon, they want completion only on a
+ symbol name after the colon. Otherwise, we need to complete on
+ symbols as well as on files. */
+ if (colon)
+ {
+ list = make_file_symbol_completion_list (symbol_start, word,
+ file_to_match);
+ xfree (file_to_match);
+ }
+ else
+ {
+ list = make_symbol_completion_list (symbol_start, word);
+ /* If text includes characters which cannot appear in a file
+ name, they cannot be asking for completion on files. */
+ if (strcspn (text, gdb_completer_file_name_break_characters) == text_len)
+ fn_list = make_source_files_completion_list (text, text);
+ }
+
+ /* How many completions do we have in both lists? */
+ if (fn_list)
+ for ( ; fn_list[n_files]; n_files++)
+ ;
+ if (list)
+ for ( ; list[n_syms]; n_syms++)
+ ;
+
+ /* Make list[] large enough to hold both lists, then catenate
+ fn_list[] onto the end of list[]. */
+ if (n_syms && n_files)
+ {
+ list = xrealloc (list, (n_syms + n_files + 1) * sizeof (char *));
+ memcpy (list + n_syms, fn_list, (n_files + 1) * sizeof (char *));
+ xfree (fn_list);
+ }
+ else if (n_files)
+ {
+ /* If we only have file names as possible completion, we should
+ bring them in sync with what rl_complete expects. The
+ problem is that if the user types "break /foo/b TAB", and the
+ possible completions are "/foo/bar" and "/foo/baz"
+ rl_complete expects us to return "bar" and "baz", without the
+ leading directories, as possible completions, because `word'
+ starts at the "b". But we ignore the value of `word' when we
+ call make_source_files_completion_list above (because that
+ would not DTRT when the completion results in both symbols
+ and file names), so make_source_files_completion_list returns
+ the full "/foo/bar" and "/foo/baz" strings. This produces
+ wrong results when, e.g., there's only one possible
+ completion, because rl_complete will prepend "/foo/" to each
+ candidate completion. The loop below removes that leading
+ part. */
+ for (n_files = 0; fn_list[n_files]; n_files++)
+ {
+ memmove (fn_list[n_files], fn_list[n_files] + (word - text),
+ strlen (fn_list[n_files]) + 1 - (word - text));
+ }
+ /* Return just the file-name list as the result. */
+ list = fn_list;
+ }
+ else if (!n_syms)
+ {
+ /* No completions at all. As the final resort, try completing
+ on the entire text as a symbol. */
+ list = make_symbol_completion_list (orig_text, word);
+ }
+
+ return list;
+}
+
+/* Complete on command names. Used by "help". */
+char **
+command_completer (char *text, char *word)
+{
+ return complete_on_cmdlist (cmdlist, text, word);
+}
+
+
+/* Here are some useful test cases for completion. FIXME: These should
+ be put in the test suite. They should be tested with both M-? and TAB.
+
+ "show output-" "radix"
+ "show output" "-radix"
+ "p" ambiguous (commands starting with p--path, print, printf, etc.)
+ "p " ambiguous (all symbols)
+ "info t foo" no completions
+ "info t " no completions
+ "info t" ambiguous ("info target", "info terminal", etc.)
+ "info ajksdlfk" no completions
+ "info ajksdlfk " no completions
+ "info" " "
+ "info " ambiguous (all info commands)
+ "p \"a" no completions (string constant)
+ "p 'a" ambiguous (all symbols starting with a)
+ "p b-a" ambiguous (all symbols starting with a)
+ "p b-" ambiguous (all symbols)
+ "file Make" "file" (word break hard to screw up here)
+ "file ../gdb.stabs/we" "ird" (needs to not break word at slash)
+ */
+
+/* Generate completions all at once. Returns a NULL-terminated array
+ of strings. Both the array and each element are allocated with
+ xmalloc. It can also return NULL if there are no completions.
+
+ TEXT is the caller's idea of the "word" we are looking at.
+
+ LINE_BUFFER is available to be looked at; it contains the entire text
+ of the line. POINT is the offset in that line of the cursor. You
+ should pretend that the line ends at POINT. */
+
+char **
+complete_line (char *text, char *line_buffer, int point)
+{
+ char **list = NULL;
+ char *tmp_command, *p;
+ /* Pointer within tmp_command which corresponds to text. */
+ char *word;
+ struct cmd_list_element *c, *result_list;
+
+ /* Choose the default set of word break characters to break completions.
+ If we later find out that we are doing completions on command strings
+ (as opposed to strings supplied by the individual command completer
+ functions, which can be any string) then we will switch to the
+ special word break set for command strings, which leaves out the
+ '-' character used in some commands. */
+
+ rl_completer_word_break_characters =
+ gdb_completer_word_break_characters;
+
+ /* Decide whether to complete on a list of gdb commands or on symbols. */
+ tmp_command = (char *) alloca (point + 1);
+ p = tmp_command;
+
+ strncpy (tmp_command, line_buffer, point);
+ tmp_command[point] = '\0';
+ /* Since text always contains some number of characters leading up
+ to point, we can find the equivalent position in tmp_command
+ by subtracting that many characters from the end of tmp_command. */
+ word = tmp_command + point - strlen (text);
+
+ if (point == 0)
+ {
+ /* An empty line we want to consider ambiguous; that is, it
+ could be any command. */
+ c = (struct cmd_list_element *) -1;
+ result_list = 0;
+ }
+ else
+ {
+ c = lookup_cmd_1 (&p, cmdlist, &result_list, 1);
+ }
+
+ /* Move p up to the next interesting thing. */
+ while (*p == ' ' || *p == '\t')
+ {
+ p++;
+ }
+
+ if (!c)
+ {
+ /* It is an unrecognized command. So there are no
+ possible completions. */
+ list = NULL;
+ }
+ else if (c == (struct cmd_list_element *) -1)
+ {
+ char *q;
+
+ /* lookup_cmd_1 advances p up to the first ambiguous thing, but
+ doesn't advance over that thing itself. Do so now. */
+ q = p;
+ while (*q && (isalnum (*q) || *q == '-' || *q == '_'))
+ ++q;
+ if (q != tmp_command + point)
+ {
+ /* There is something beyond the ambiguous
+ command, so there are no possible completions. For
+ example, "info t " or "info t foo" does not complete
+ to anything, because "info t" can be "info target" or
+ "info terminal". */
+ list = NULL;
+ }
+ else
+ {
+ /* We're trying to complete on the command which was ambiguous.
+ This we can deal with. */
+ if (result_list)
+ {
+ list = complete_on_cmdlist (*result_list->prefixlist, p,
+ word);
+ }
+ else
+ {
+ list = complete_on_cmdlist (cmdlist, p, word);
+ }
+ /* Insure that readline does the right thing with respect to
+ inserting quotes. */
+ rl_completer_word_break_characters =
+ gdb_completer_command_word_break_characters;
+ }
+ }
+ else
+ {
+ /* We've recognized a full command. */
+
+ if (p == tmp_command + point)
+ {
+ /* There is no non-whitespace in the line beyond the command. */
+
+ if (p[-1] == ' ' || p[-1] == '\t')
+ {
+ /* The command is followed by whitespace; we need to complete
+ on whatever comes after command. */
+ if (c->prefixlist)
+ {
+ /* It is a prefix command; what comes after it is
+ a subcommand (e.g. "info "). */
+ list = complete_on_cmdlist (*c->prefixlist, p, word);
+
+ /* Insure that readline does the right thing
+ with respect to inserting quotes. */
+ rl_completer_word_break_characters =
+ gdb_completer_command_word_break_characters;
+ }
+ else if (c->enums)
+ {
+ list = complete_on_enum (c->enums, p, word);
+ rl_completer_word_break_characters =
+ gdb_completer_command_word_break_characters;
+ }
+ else
+ {
+ /* It is a normal command; what comes after it is
+ completed by the command's completer function. */
+ if (c->completer == filename_completer)
+ {
+ /* Many commands which want to complete on
+ file names accept several file names, as
+ in "run foo bar >>baz". So we don't want
+ to complete the entire text after the
+ command, just the last word. To this
+ end, we need to find the beginning of the
+ file name by starting at `word' and going
+ backwards. */
+ for (p = word;
+ p > tmp_command
+ && strchr (gdb_completer_file_name_break_characters, p[-1]) == NULL;
+ p--)
+ ;
+ rl_completer_word_break_characters =
+ gdb_completer_file_name_break_characters;
+ }
+ else if (c->completer == location_completer)
+ {
+ /* Commands which complete on locations want to
+ see the entire argument. */
+ for (p = word;
+ p > tmp_command
+ && p[-1] != ' ' && p[-1] != '\t';
+ p--)
+ ;
+ }
+ list = (*c->completer) (p, word);
+ }
+ }
+ else
+ {
+ /* The command is not followed by whitespace; we need to
+ complete on the command itself. e.g. "p" which is a
+ command itself but also can complete to "print", "ptype"
+ etc. */
+ char *q;
+
+ /* Find the command we are completing on. */
+ q = p;
+ while (q > tmp_command)
+ {
+ if (isalnum (q[-1]) || q[-1] == '-' || q[-1] == '_')
+ --q;
+ else
+ break;
+ }
+
+ list = complete_on_cmdlist (result_list, q, word);
+
+ /* Insure that readline does the right thing
+ with respect to inserting quotes. */
+ rl_completer_word_break_characters =
+ gdb_completer_command_word_break_characters;
+ }
+ }
+ else
+ {
+ /* There is non-whitespace beyond the command. */
+
+ if (c->prefixlist && !c->allow_unknown)
+ {
+ /* It is an unrecognized subcommand of a prefix command,
+ e.g. "info adsfkdj". */
+ list = NULL;
+ }
+ else if (c->enums)
+ {
+ list = complete_on_enum (c->enums, p, word);
+ }
+ else
+ {
+ /* It is a normal command. */
+ if (c->completer == filename_completer)
+ {
+ /* See the commentary above about the specifics
+ of file-name completion. */
+ for (p = word;
+ p > tmp_command
+ && strchr (gdb_completer_file_name_break_characters, p[-1]) == NULL;
+ p--)
+ ;
+ rl_completer_word_break_characters =
+ gdb_completer_file_name_break_characters;
+ }
+ else if (c->completer == location_completer)
+ {
+ for (p = word;
+ p > tmp_command
+ && p[-1] != ' ' && p[-1] != '\t';
+ p--)
+ ;
+ }
+ list = (*c->completer) (p, word);
+ }
+ }
+ }
+
+ return list;
+}
+
+/* Generate completions one by one for the completer. Each time we are
+ called return another potential completion to the caller.
+ line_completion just completes on commands or passes the buck to the
+ command's completer function, the stuff specific to symbol completion
+ is in make_symbol_completion_list.
+
+ TEXT is the caller's idea of the "word" we are looking at.
+
+ MATCHES is the number of matches that have currently been collected from
+ calling this completion function. When zero, then we need to initialize,
+ otherwise the initialization has already taken place and we can just
+ return the next potential completion string.
+
+ LINE_BUFFER is available to be looked at; it contains the entire text
+ of the line. POINT is the offset in that line of the cursor. You
+ should pretend that the line ends at POINT.
+
+ Returns NULL if there are no more completions, else a pointer to a string
+ which is a possible completion, it is the caller's responsibility to
+ free the string. */
+
+char *
+line_completion_function (char *text, int matches, char *line_buffer, int point)
+{
+ static char **list = (char **) NULL; /* Cache of completions */
+ static int index; /* Next cached completion */
+ char *output = NULL;
+
+ if (matches == 0)
+ {
+ /* The caller is beginning to accumulate a new set of completions, so
+ we need to find all of them now, and cache them for returning one at
+ a time on future calls. */
+
+ if (list)
+ {
+ /* Free the storage used by LIST, but not by the strings inside.
+ This is because rl_complete_internal () frees the strings. */
+ xfree (list);
+ }
+ index = 0;
+ list = complete_line (text, line_buffer, point);
+ }
+
+ /* If we found a list of potential completions during initialization then
+ dole them out one at a time. The vector of completions is NULL
+ terminated, so after returning the last one, return NULL (and continue
+ to do so) each time we are called after that, until a new list is
+ available. */
+
+ if (list)
+ {
+ output = list[index];
+ if (output)
+ {
+ index++;
+ }
+ }
+
+#if 0
+ /* Can't do this because readline hasn't yet checked the word breaks
+ for figuring out whether to insert a quote. */
+ if (output == NULL)
+ /* Make sure the word break characters are set back to normal for the
+ next time that readline tries to complete something. */
+ rl_completer_word_break_characters =
+ gdb_completer_word_break_characters;
+#endif
+
+ return (output);
+}
+/* Skip over a possibly quoted word (as defined by the quote characters
+ and word break characters the completer uses). Returns pointer to the
+ location after the "word". */
+
+char *
+skip_quoted (char *str)
+{
+ char quote_char = '\0';
+ char *scan;
+
+ for (scan = str; *scan != '\0'; scan++)
+ {
+ if (quote_char != '\0')
+ {
+ /* Ignore everything until the matching close quote char */
+ if (*scan == quote_char)
+ {
+ /* Found matching close quote. */
+ scan++;
+ break;
+ }
+ }
+ else if (strchr (gdb_completer_quote_characters, *scan))
+ {
+ /* Found start of a quoted string. */
+ quote_char = *scan;
+ }
+ else if (strchr (gdb_completer_word_break_characters, *scan))
+ {
+ break;
+ }
+ }
+ return (scan);
+}
+
diff --git a/gdb/completer.h b/gdb/completer.h
new file mode 100644
index 00000000000..98b9ed83745
--- /dev/null
+++ b/gdb/completer.h
@@ -0,0 +1,44 @@
+/* Header for GDB line completion.
+ Copyright 2000 Free Software Foundation, Inc.
+
+ 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. */
+
+#if !defined (COMPLETER_H)
+#define COMPLETER_H 1
+
+extern char **complete_line (char *text, char *line_buffer, int point);
+
+extern char *line_completion_function (char *, int, char *, int);
+
+extern char *readline_line_completion_function (char *text, int matches);
+
+extern char **noop_completer (char *, char *);
+
+extern char **filename_completer (char *, char *);
+
+extern char **location_completer (char *, char *);
+
+extern char **command_completer (char *, char *);
+
+extern char *get_gdb_completer_word_break_characters (void);
+
+extern char *get_gdb_completer_quote_characters (void);
+
+/* Exported to linespec.c */
+
+extern char *skip_quoted (char *str);
+
+#endif /* defined (COMPLETER_H) */
diff --git a/gdb/config.in b/gdb/config.in
new file mode 100644
index 00000000000..750a8aea949
--- /dev/null
+++ b/gdb/config.in
@@ -0,0 +1,507 @@
+/* config.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if on AIX 3.
+ System headers sometimes define this.
+ We just want to avoid a redefinition error message. */
+#ifndef _ALL_SOURCE
+#undef _ALL_SOURCE
+#endif
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if the `long double' type works. */
+#undef HAVE_LONG_DOUBLE
+
+/* Define if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define if you have <vfork.h>. */
+#undef HAVE_VFORK_H
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef pid_t
+
+/* Define as the return type of signal handlers (int or void). */
+#undef RETSIGTYPE
+
+/* Define if the `setpgrp' function takes no argument. */
+#undef SETPGRP_VOID
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+#undef STAT_MACROS_BROKEN
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define vfork as fork if vfork does not work. */
+#undef vfork
+
+/* Define if compiling on Solaris 7. */
+#undef _MSE_INT_H
+
+/* Define if your struct reg has r_fs. */
+#undef HAVE_STRUCT_REG_R_FS
+
+/* Define if your struct reg has r_gs. */
+#undef HAVE_STRUCT_REG_R_GS
+
+/* Define if <link.h> exists and defines struct link_map which has
+ members with an ``l_'' prefix. (For Solaris, SVR4, and
+ SVR4-like systems.) */
+#undef HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS
+
+/* Define if <link.h> exists and defines struct link_map which has
+ members with an ``lm_'' prefix. (For SunOS.) */
+#undef HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS
+
+/* Define if <link.h> exists and defines a struct so_map which has
+ members with an ``som_'' prefix. (Found on older *BSD systems.) */
+#undef HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS
+
+/* Define if <sys/link.h> has struct link_map32 */
+#undef HAVE_STRUCT_LINK_MAP32
+
+/* Define if <sys/link.h> has link_map32 (solaris sparc-64 target) */
+#undef _SYSCALL32
+
+/* Define if the prfpregset_t type is broken. */
+#undef PRFPREGSET_T_BROKEN
+
+/* Define if you want to use new multi-fd /proc interface
+ (replaces HAVE_MULTIPLE_PROC_FDS as well as other macros). */
+#undef NEW_PROC_API
+
+/* Define if ioctl argument PIOCSET is available. */
+#undef HAVE_PROCFS_PIOCSET
+
+/* Define if the `long long' type works. */
+#undef CC_HAS_LONG_LONG
+
+/* Define if the "ll" format works to print long long ints. */
+#undef PRINTF_HAS_LONG_LONG
+
+/* Define if the "%Lg" format works to print long doubles. */
+#undef PRINTF_HAS_LONG_DOUBLE
+
+/* Define if the "%Lg" format works to scan long doubles. */
+#undef SCANF_HAS_LONG_DOUBLE
+
+/* Define if using Solaris thread debugging. */
+#undef HAVE_THREAD_DB_LIB
+
+/* Define on a GNU/Linux system to work around problems in sys/procfs.h. */
+#undef START_INFERIOR_TRAPS_EXPECTED
+#undef sys_quotactl
+
+/* Define if you have HPUX threads */
+#undef HAVE_HPUX_THREAD_SUPPORT
+
+/* Define if you want to use the memory mapped malloc package (mmalloc). */
+#undef USE_MMALLOC
+
+/* Define if the runtime uses a routine from mmalloc before gdb has a chance
+ to initialize mmalloc, and we want to force checking to be used anyway.
+ This may cause spurious memory corruption messages if the runtime tries
+ to explicitly deallocate that memory when gdb calls exit. */
+#undef MMCHECK_FORCE
+
+/* Define if <proc_service.h> on solaris uses int instead of
+ size_t, and assorted other type changes. */
+#undef PROC_SERVICE_IS_OLD
+
+/* If you want to specify a default CPU variant, define this to be its
+ name, as a C string. */
+#undef TARGET_CPU_DEFAULT
+
+/* Define if the simulator is being linked in. */
+#undef WITH_SIM
+
+/* Set to true if the save_state_t structure is present */
+#undef HAVE_STRUCT_SAVE_STATE_T
+
+/* Set to true if the save_state_t structure has the ss_wide member */
+#undef HAVE_STRUCT_MEMBER_SS_WIDE
+
+/* Define if <sys/ptrace.h> defines the PTRACE_GETREGS request. */
+#undef HAVE_PTRACE_GETREGS
+
+/* Define if <sys/ptrace.h> defines the PTRACE_GETFPXREGS request. */
+#undef HAVE_PTRACE_GETFPXREGS
+
+/* Define if <sys/ptrace.h> defines the PT_GETDBREGS request. */
+#undef HAVE_PT_GETDBREGS
+
+/* Define if <sys/ptrace.h> defines the PT_GETXMMREGS request. */
+#undef HAVE_PT_GETXMMREGS
+
+/* Define if gnu-regex.c included with GDB should be used. */
+#undef USE_INCLUDED_REGEX
+
+/* BFD's default architecture. */
+#undef DEFAULT_BFD_ARCH
+
+/* BFD's default target vector. */
+#undef DEFAULT_BFD_VEC
+
+/* Multi-arch enabled. */
+#undef GDB_MULTI_ARCH
+
+/* hostfile */
+#undef GDB_XM_FILE
+
+/* targetfile */
+#undef GDB_TM_FILE
+
+/* nativefile */
+#undef GDB_NM_FILE
+
+/* Define if you have the __argz_count function. */
+#undef HAVE___ARGZ_COUNT
+
+/* Define if you have the __argz_next function. */
+#undef HAVE___ARGZ_NEXT
+
+/* Define if you have the __argz_stringify function. */
+#undef HAVE___ARGZ_STRINGIFY
+
+/* Define if you have the bcopy function. */
+#undef HAVE_BCOPY
+
+/* Define if you have the btowc function. */
+#undef HAVE_BTOWC
+
+/* Define if you have the bzero function. */
+#undef HAVE_BZERO
+
+/* Define if you have the canonicalize_file_name function. */
+#undef HAVE_CANONICALIZE_FILE_NAME
+
+/* Define if you have the dcgettext function. */
+#undef HAVE_DCGETTEXT
+
+/* Define if you have the getcwd function. */
+#undef HAVE_GETCWD
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the isascii function. */
+#undef HAVE_ISASCII
+
+/* Define if you have the munmap function. */
+#undef HAVE_MUNMAP
+
+/* Define if you have the poll function. */
+#undef HAVE_POLL
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
+/* Define if you have the realpath function. */
+#undef HAVE_REALPATH
+
+/* Define if you have the sbrk function. */
+#undef HAVE_SBRK
+
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
+
+/* Define if you have the setpgid function. */
+#undef HAVE_SETPGID
+
+/* Define if you have the setpgrp function. */
+#undef HAVE_SETPGRP
+
+/* Define if you have the sigaction function. */
+#undef HAVE_SIGACTION
+
+/* Define if you have the sigprocmask function. */
+#undef HAVE_SIGPROCMASK
+
+/* Define if you have the sigsetmask function. */
+#undef HAVE_SIGSETMASK
+
+/* Define if you have the socketpair function. */
+#undef HAVE_SOCKETPAIR
+
+/* Define if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define if you have the <asm/debugreg.h> header file. */
+#undef HAVE_ASM_DEBUGREG_H
+
+/* Define if you have the <ctype.h> header file. */
+#undef HAVE_CTYPE_H
+
+/* Define if you have the <curses.h> header file. */
+#undef HAVE_CURSES_H
+
+/* Define if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <link.h> header file. */
+#undef HAVE_LINK_H
+
+/* Define if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <ncurses.h> header file. */
+#undef HAVE_NCURSES_H
+
+/* Define if you have the <ndir.h> header file. */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* Define if you have the <nlist.h> header file. */
+#undef HAVE_NLIST_H
+
+/* Define if you have the <objlist.h> header file. */
+#undef HAVE_OBJLIST_H
+
+/* Define if you have the <poll.h> header file. */
+#undef HAVE_POLL_H
+
+/* Define if you have the <proc_service.h> header file. */
+#undef HAVE_PROC_SERVICE_H
+
+/* Define if you have the <ptrace.h> header file. */
+#undef HAVE_PTRACE_H
+
+/* Define if you have the <sgtty.h> header file. */
+#undef HAVE_SGTTY_H
+
+/* Define if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/debugreg.h> header file. */
+#undef HAVE_SYS_DEBUGREG_H
+
+/* Define if you have the <sys/dir.h> header file. */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/fault.h> header file. */
+#undef HAVE_SYS_FAULT_H
+
+/* Define if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define if you have the <sys/filio.h> header file. */
+#undef HAVE_SYS_FILIO_H
+
+/* Define if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define if you have the <sys/ndir.h> header file. */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/poll.h> header file. */
+#undef HAVE_SYS_POLL_H
+
+/* Define if you have the <sys/procfs.h> header file. */
+#undef HAVE_SYS_PROCFS_H
+
+/* Define if you have the <sys/ptrace.h> header file. */
+#undef HAVE_SYS_PTRACE_H
+
+/* Define if you have the <sys/reg.h> header file. */
+#undef HAVE_SYS_REG_H
+
+/* Define if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define if you have the <sys/syscall.h> header file. */
+#undef HAVE_SYS_SYSCALL_H
+
+/* Define if you have the <sys/user.h> header file. */
+#undef HAVE_SYS_USER_H
+
+/* Define if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if you have the <term.h> header file. */
+#undef HAVE_TERM_H
+
+/* Define if you have the <termio.h> header file. */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define if you have the <thread_db.h> header file. */
+#undef HAVE_THREAD_DB_H
+
+/* Define if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the <values.h> header file. */
+#undef HAVE_VALUES_H
+
+/* Define if you have the <wait.h> header file. */
+#undef HAVE_WAIT_H
+
+/* Define if you have the <wchar.h> header file. */
+#undef HAVE_WCHAR_H
+
+/* Define if you have the <wctype.h> header file. */
+#undef HAVE_WCTYPE_H
+
+/* Define if you have the dl library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define if you have the m library (-lm). */
+#undef HAVE_LIBM
+
+/* Define if you have the socket library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define if you have the w library (-lw). */
+#undef HAVE_LIBW
+
+/* Define if you have the stpcpy function */
+#undef HAVE_STPCPY
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define to 1 if NLS is requested */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Define if sigsetjmp is available. */
+#undef HAVE_SIGSETJMP
+
+/* Define if malloc is not declared in system header files. */
+#undef NEED_DECLARATION_MALLOC
+
+/* Define if realloc is not declared in system header files. */
+#undef NEED_DECLARATION_REALLOC
+
+/* Define if free is not declared in system header files. */
+#undef NEED_DECLARATION_FREE
+
+/* Define if strerror is not declared in system header files. */
+#undef NEED_DECLARATION_STRERROR
+
+/* Define if strdup is not declared in system header files. */
+#undef NEED_DECLARATION_STRDUP
+
+/* Define if strstr is not declared in system header files. */
+#undef NEED_DECLARATION_STRSTR
+
+/* Define if canonicalize_file_name is not declared in system header files. */
+#undef NEED_DECLARATION_CANONICALIZE_FILE_NAME
+
+/* Define if <sys/procfs.h> has pstatus_t. */
+#undef HAVE_PSTATUS_T
+
+/* Define if <sys/procfs.h> has prrun_t. */
+#undef HAVE_PRRUN_T
+
+/* Define if <sys/procfs.h> has gregset_t. */
+#undef HAVE_GREGSET_T
+
+/* Define if <sys/procfs.h> has fpregset_t. */
+#undef HAVE_FPREGSET_T
+
+/* Define if <sys/procfs.h> has prgregset_t. */
+#undef HAVE_PRGREGSET_T
+
+/* Define if <sys/procfs.h> has prfpregset_t. */
+#undef HAVE_PRFPREGSET_T
+
+/* Define if <sys/procfs.h> has prgregset32_t. */
+#undef HAVE_PRGREGSET32_T
+
+/* Define if <sys/procfs.h> has prfpregset32_t. */
+#undef HAVE_PRFPREGSET32_T
+
+/* Define if <sys/procfs.h> has lwpid_t. */
+#undef HAVE_LWPID_T
+
+/* Define if <sys/procfs.h> has psaddr_t. */
+#undef HAVE_PSADDR_T
+
+/* Define if <sys/procfs.h> has prsysent_t. */
+#undef HAVE_PRSYSENT_T
+
+/* Define if <sys/procfs.h> has pr_sigset_t. */
+#undef HAVE_PR_SIGSET_T
+
+/* Define if <sys/procfs.h> has pr_sigaction64_t. */
+#undef HAVE_PR_SIGACTION64_T
+
+/* Define if <sys/procfs.h> has pr_siginfo64_t. */
+#undef HAVE_PR_SIGINFO64_T
+
diff --git a/gdb/config/alpha/alpha-linux.mh b/gdb/config/alpha/alpha-linux.mh
new file mode 100644
index 00000000000..39f35320188
--- /dev/null
+++ b/gdb/config/alpha/alpha-linux.mh
@@ -0,0 +1,10 @@
+# Host: Little-endian Alpha running Linux
+XM_FILE= xm-alphalinux.h
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o corelow.o alpha-nat.o linux-proc.o \
+ fork-child.o proc-service.o thread-db.o lin-lwp.o gcore.o
+
+LOADLIBES = -ldl -rdynamic
+
+MMALLOC =
+MMALLOC_CFLAGS = -DNO_MMALLOC
diff --git a/gdb/config/alpha/alpha-linux.mt b/gdb/config/alpha/alpha-linux.mt
new file mode 100644
index 00000000000..25538b34589
--- /dev/null
+++ b/gdb/config/alpha/alpha-linux.mt
@@ -0,0 +1,3 @@
+# Target: Little-endian Alpha
+TDEPFILES= alpha-tdep.o alpha-linux-tdep.o solib.o solib-svr4.o solib-legacy.o
+TM_FILE= tm-alphalinux.h
diff --git a/gdb/config/alpha/alpha-osf1.mh b/gdb/config/alpha/alpha-osf1.mh
new file mode 100644
index 00000000000..6d53b44505b
--- /dev/null
+++ b/gdb/config/alpha/alpha-osf1.mh
@@ -0,0 +1,5 @@
+# Host: Little-endian Alpha running OSF/1-1.x
+XM_FILE= xm-alphaosf.h
+NAT_FILE= nm-osf.h
+NATDEPFILES= infptrace.o inftarg.o corelow.o alpha-nat.o fork-child.o \
+ solib-osf.o solib.o
diff --git a/gdb/config/alpha/alpha-osf1.mt b/gdb/config/alpha/alpha-osf1.mt
new file mode 100644
index 00000000000..29212c9a957
--- /dev/null
+++ b/gdb/config/alpha/alpha-osf1.mt
@@ -0,0 +1,3 @@
+# Target: Little-endian Alpha
+TDEPFILES= alpha-tdep.o alpha-osf1-tdep.o
+TM_FILE= tm-alpha.h
diff --git a/gdb/config/alpha/alpha-osf2.mh b/gdb/config/alpha/alpha-osf2.mh
new file mode 100644
index 00000000000..b853ebb30a9
--- /dev/null
+++ b/gdb/config/alpha/alpha-osf2.mh
@@ -0,0 +1,6 @@
+# Host: Little-endian Alpha running OSF/1-2.x using procfs
+XM_FILE= xm-alphaosf.h
+NAT_FILE= nm-osf2.h
+NATDEPFILES= infptrace.o inftarg.o corelow.o alpha-nat.o fork-child.o \
+ solib-osf.o solib.o procfs.o proc-api.o proc-events.o proc-flags.o \
+ proc-why.o
diff --git a/gdb/config/alpha/alpha-osf3.mh b/gdb/config/alpha/alpha-osf3.mh
new file mode 100644
index 00000000000..f074444fae0
--- /dev/null
+++ b/gdb/config/alpha/alpha-osf3.mh
@@ -0,0 +1,6 @@
+# Host: Little-endian Alpha running OSF/1-3.x and higher using procfs
+XM_FILE= xm-alphaosf.h
+NAT_FILE= nm-osf3.h
+NATDEPFILES= infptrace.o inftarg.o corelow.o alpha-nat.o fork-child.o \
+ solib-osf.o solib.o procfs.o proc-api.o proc-events.o proc-flags.o \
+ proc-why.o
diff --git a/gdb/config/alpha/fbsd.mh b/gdb/config/alpha/fbsd.mh
new file mode 100644
index 00000000000..7e036e43a47
--- /dev/null
+++ b/gdb/config/alpha/fbsd.mh
@@ -0,0 +1,5 @@
+# Host: FreeBSD/Alpha
+NATDEPFILES= fork-child.o infptrace.o inftarg.o \
+ solib.o solib-svr4.o solib-legacy.o \
+ corelow.o core-regset.o alphabsd-nat.o
+NAT_FILE= nm-fbsd.h
diff --git a/gdb/config/alpha/fbsd.mt b/gdb/config/alpha/fbsd.mt
new file mode 100644
index 00000000000..4b4ecbf6235
--- /dev/null
+++ b/gdb/config/alpha/fbsd.mt
@@ -0,0 +1,3 @@
+# Target: FreeBSD/Alpha
+TDEPFILES= alpha-tdep.o alphabsd-tdep.o alphafbsd-tdep.o
+TM_FILE= tm-fbsd.h
diff --git a/gdb/config/alpha/nbsd.mh b/gdb/config/alpha/nbsd.mh
new file mode 100644
index 00000000000..52754a3065d
--- /dev/null
+++ b/gdb/config/alpha/nbsd.mh
@@ -0,0 +1,4 @@
+# Host: Alpha running NetBSD
+NAT_CLIBS=
+NATDEPFILES= infptrace.o inftarg.o fork-child.o alphabsd-nat.o
+NAT_FILE= nm-nbsd.h
diff --git a/gdb/config/alpha/nbsd.mt b/gdb/config/alpha/nbsd.mt
new file mode 100644
index 00000000000..7fd9c503255
--- /dev/null
+++ b/gdb/config/alpha/nbsd.mt
@@ -0,0 +1,4 @@
+# Target: Alpha running NetBSD
+TDEPFILES= alpha-tdep.o alphabsd-tdep.o alphanbsd-tdep.o corelow.o \
+ nbsd-tdep.o solib.o solib-svr4.o
+TM_FILE= tm-nbsd.h
diff --git a/gdb/config/alpha/nm-fbsd.h b/gdb/config/alpha/nm-fbsd.h
new file mode 100644
index 00000000000..f3fb129997c
--- /dev/null
+++ b/gdb/config/alpha/nm-fbsd.h
@@ -0,0 +1,45 @@
+/* Native-dependent definitions for FreeBSD/Alpha.
+ Copyright 1986, 1987, 1989, 1992, 1996, 2000
+ 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. */
+
+#ifndef NM_FBSD_H
+#define NM_FBSD_H
+
+/* Type of the third argument to the `ptrace' system call. */
+#define PTRACE_ARG3_TYPE caddr_t
+
+/* Override copies of {fetch,store}_inferior_registers in `infptrace.c'. */
+#define FETCH_INFERIOR_REGISTERS
+
+/* We can attach and detach. */
+#define ATTACH_DETACH
+
+/* The Alpha does not step over a breakpoint. */
+#define CANNOT_STEP_BREAKPOINT
+
+
+/* Shared library support. */
+
+#define SVR4_SHARED_LIBS
+
+#include "solib.h" /* Support for shared libraries. */
+#include "elf/common.h" /* Additional ELF shared library info. */
+
+#endif /* NM_FBSD_H */
diff --git a/gdb/config/alpha/nm-linux.h b/gdb/config/alpha/nm-linux.h
new file mode 100644
index 00000000000..c59b88cb21e
--- /dev/null
+++ b/gdb/config/alpha/nm-linux.h
@@ -0,0 +1,48 @@
+/* Native definitions for alpha running GNU/Linux.
+
+ Copyright 1993, 1994, 1996, 1998, 2000, 2001, 2002 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. */
+
+#ifndef NM_LINUX_H
+#define NM_LINUX_H
+
+#include "nm-linux.h"
+
+/* ptrace register ``addresses'' are absolute. */
+
+#define U_REGS_OFFSET 0
+
+/* FIXME: This is probably true, or should be, on all GNU/Linux ports.
+ IA64? Sparc64? */
+#define PTRACE_ARG3_TYPE long
+
+/* ptrace transfers longs, the ptrace man page is lying. */
+
+#define PTRACE_XFER_TYPE long
+
+/* The alpha does not step over a breakpoint, the manpage is lying again. */
+
+#define CANNOT_STEP_BREAKPOINT
+
+/* Given a pointer to either a gregset_t or fpregset_t, return a
+ pointer to the first register. */
+#define ALPHA_REGSET_BASE(regsetp) ((long *) (regsetp))
+
+#endif /* NM_LINUX_H */
diff --git a/gdb/config/alpha/nm-nbsd.h b/gdb/config/alpha/nm-nbsd.h
new file mode 100644
index 00000000000..caf1c237cfb
--- /dev/null
+++ b/gdb/config/alpha/nm-nbsd.h
@@ -0,0 +1,31 @@
+/* Native-dependent definitions for Alpha running NetBSD, for GDB.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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. */
+
+#ifndef NM_NBSD_H
+#define NM_NBSD_H
+
+/* Get generic NetBSD native definitions. */
+#include "config/nm-nbsd.h"
+
+/* The Alpha does not step over a breakpoint. */
+#define CANNOT_STEP_BREAKPOINT
+
+#endif /* NM_NBSD_H */
diff --git a/gdb/config/alpha/nm-osf.h b/gdb/config/alpha/nm-osf.h
new file mode 100644
index 00000000000..20b5ae4a39a
--- /dev/null
+++ b/gdb/config/alpha/nm-osf.h
@@ -0,0 +1,43 @@
+/* Native definitions for alpha running OSF/1.
+ Copyright 1993, 1994, 1995, 1998, 2000 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. */
+
+/* ptrace register ``addresses'' are absolute. */
+
+#define U_REGS_OFFSET 0
+
+/* FIXME: Shouldn't the default definition in inferior.h be int* ? */
+
+#define PTRACE_ARG3_TYPE int*
+
+/* ptrace transfers longs, the ptrace man page is lying. */
+
+#define PTRACE_XFER_TYPE long
+
+/* The alpha does not step over a breakpoint, the manpage is lying again. */
+
+#define CANNOT_STEP_BREAKPOINT
+
+/* Support for shared libraries. */
+
+#include "solib.h"
+
+/* Given a pointer to either a gregset_t or fpregset_t, return a
+ pointer to the first register. */
+#define ALPHA_REGSET_BASE(regsetp) ((regsetp)->regs)
diff --git a/gdb/config/alpha/nm-osf2.h b/gdb/config/alpha/nm-osf2.h
new file mode 100644
index 00000000000..4b225af237f
--- /dev/null
+++ b/gdb/config/alpha/nm-osf2.h
@@ -0,0 +1,55 @@
+/* Native definitions for alpha running OSF/1-2.x, using procfs.
+ Copyright 1995, 1996, 2000 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. */
+
+/* Get generic OSF/1 definitions. */
+#include "alpha/nm-osf.h"
+
+/* OSF/1-2.x has optional /proc support, try to use it instead of ptrace. */
+#define USE_PROC_FS
+#define HAVE_OPTIONAL_PROC_FS
+
+/* OSF/1 doesn't provide the standard fault definitions, so don't use them. */
+#define FAULTED_USE_SIGINFO
+
+/* Don't trace faults under OSF/1, rely on the posting of the appropriate
+ signal if fault tracing is disabled.
+ Tracing T_IFAULT under Alpha OSF/1 causes a `floating point enable'
+ fault from which we cannot continue (except by disabling the
+ tracing).
+ And as OSF/1 doesn't provide the standard fault definitions, the
+ mapping of faults to appropriate signals in procfs_wait is difficult. */
+#define PROCFS_DONT_TRACE_FAULTS
+
+/* Work around some peculiarities in the OSF/1 procfs implementation. */
+#define PROCFS_SIGPEND_OFFSET
+#define PROCFS_NEED_PIOCSSIG_FOR_KILL
+#define PROCFS_DONT_PIOCSSIG_CURSIG
+
+/* Return sizeof user struct to callers in less machine dependent routines */
+
+#define KERNEL_U_SIZE kernel_u_size()
+extern int kernel_u_size (void);
+
+/* poll() doesn't seem to work properly for /proc in this version of the OS.
+ If we only specify POLLPRI, things hang. It seems to get better when we set
+ POLLOUT, but that always returns POLLNVAL!!! Also, POLLOUT causes problems
+ on other OSes. */
+
+#define LOSING_POLL
diff --git a/gdb/config/alpha/nm-osf3.h b/gdb/config/alpha/nm-osf3.h
new file mode 100644
index 00000000000..e2818d51afc
--- /dev/null
+++ b/gdb/config/alpha/nm-osf3.h
@@ -0,0 +1,27 @@
+/* Native definitions for alpha running OSF/1-3.x and higher, using procfs.
+ 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. */
+
+/* OSF/1-3.x fixes some OSF/1-2.x procfs peculiarities and adds
+ a new one. */
+#include "alpha/nm-osf2.h"
+
+#undef PROCFS_NEED_PIOCSSIG_FOR_KILL
+#undef PROCFS_DONT_PIOCSSIG_CURSIG
+#define PROCFS_NEED_CLEAR_CURSIG_FOR_KILL
diff --git a/gdb/config/alpha/tm-alpha.h b/gdb/config/alpha/tm-alpha.h
new file mode 100644
index 00000000000..feb752a1495
--- /dev/null
+++ b/gdb/config/alpha/tm-alpha.h
@@ -0,0 +1,86 @@
+/* Definitions to make GDB run on an Alpha box under OSF1. This is
+ also used by the Alpha/Netware and Alpha GNU/Linux targets.
+
+ Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002 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. */
+
+#ifndef TM_ALPHA_H
+#define TM_ALPHA_H
+
+#define GDB_MULTI_ARCH GDB_MULTI_ARCH_PARTIAL
+
+#include "bfd.h"
+#include "coff/sym.h" /* Needed for PDR below. */
+#include "coff/symconst.h"
+
+struct frame_info;
+struct symbol;
+
+/* Number of traps that happen between exec'ing the shell
+ to run an inferior, and when we finally get to
+ the inferior code. This is 2 on most implementations. */
+#define START_INFERIOR_TRAPS_EXPECTED 3
+
+/* Special symbol found in blocks associated with routines. We can hang
+ alpha_extra_func_info_t's off of this. */
+
+#define MIPS_EFI_SYMBOL_NAME "__GDB_EFI_INFO__"
+extern void ecoff_relocate_efi (struct symbol *, CORE_ADDR);
+
+#define RA_REGNUM 26 /* XXXJRT needed by mdebugread.c */
+
+/* Specific information about a procedure.
+ This overlays the ALPHA's PDR records,
+ alpharead.c (ab)uses this to save memory */
+
+typedef struct alpha_extra_func_info
+ {
+ long numargs; /* number of args to procedure (was iopt) */
+ PDR pdr; /* Procedure descriptor record */
+ }
+ *alpha_extra_func_info_t;
+
+/* Define the extra_func_info that mipsread.c needs.
+ FIXME: We should define our own PDR interface, perhaps in a separate
+ header file. This would get rid of the <bfd.h> inclusion in all sources
+ and would abstract the mips/alpha interface from ecoff. */
+#define mips_extra_func_info alpha_extra_func_info
+#define mips_extra_func_info_t alpha_extra_func_info_t
+
+
+#define PRINT_EXTRA_FRAME_INFO(fi) alpha_print_extra_frame_info ((fi))
+extern void alpha_print_extra_frame_info (struct frame_info *);
+
+
+/* It takes two values to specify a frame on the ALPHA. Sigh.
+
+ In fact, at the moment, the *PC* is the primary value that sets up
+ a frame. The PC is looked up to see what function it's in; symbol
+ information from that function tells us which register is the frame
+ pointer base, and what offset from there is the "virtual frame pointer".
+ (This is usually an offset from SP.) FIXME -- this should be cleaned
+ up so that the primary value is the SP, and the PC is used to disambiguate
+ multiple functions with the same SP that are at different stack levels. */
+
+#define SETUP_ARBITRARY_FRAME(argc, argv) \
+ alpha_setup_arbitrary_frame (argc, argv)
+extern struct frame_info *alpha_setup_arbitrary_frame (int, CORE_ADDR *);
+
+#endif /* TM_ALPHA_H */
diff --git a/gdb/config/alpha/tm-alphalinux.h b/gdb/config/alpha/tm-alphalinux.h
new file mode 100644
index 00000000000..27ff45722af
--- /dev/null
+++ b/gdb/config/alpha/tm-alphalinux.h
@@ -0,0 +1,45 @@
+/* Definitions to make GDB run on an Alpha box under GNU/Linux. The
+ definitions here are used when the _target_ system is running
+ GNU/Linux.
+
+ Copyright 1996, 1998, 1999, 2000, 2002 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. */
+
+#ifndef TM_LINUXALPHA_H
+#define TM_LINUXALPHA_H
+
+#include "alpha/tm-alpha.h"
+
+/* Get start and end address of sigtramp handler. */
+
+extern LONGEST alpha_linux_sigtramp_offset (CORE_ADDR);
+#define SIGTRAMP_START(pc) (pc - alpha_linux_sigtramp_offset (pc))
+#define SIGTRAMP_END(pc) (SIGTRAMP_START(pc) + 3*4)
+
+
+/* Number of traps that happen between exec'ing the shell to run an
+ inferior, and when we finally get to the inferior code. This is 2
+ on GNU/Linux and most implementations. */
+#undef START_INFERIOR_TRAPS_EXPECTED
+#define START_INFERIOR_TRAPS_EXPECTED 2
+
+#include "tm-linux.h"
+
+#endif /* TM_LINUXALPHA_H */
diff --git a/gdb/config/alpha/tm-fbsd.h b/gdb/config/alpha/tm-fbsd.h
new file mode 100644
index 00000000000..d1d525466ec
--- /dev/null
+++ b/gdb/config/alpha/tm-fbsd.h
@@ -0,0 +1,32 @@
+/* Target-dependent definitions for FreeBSD/Alpha.
+ Copyright 2000, 2001, 2002 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. */
+
+#ifndef TM_FBSD_H
+#define TM_FBSD_H
+
+#include "alpha/tm-alpha.h"
+
+/* Number of traps that happen between exec'ing the shell to run an
+ inferior, and when we finally get to the inferior code. The
+ default is right for FreeBSD. */
+
+#undef START_INFERIOR_TRAPS_EXPECTED
+
+#endif /* TM_FBSD_H */
diff --git a/gdb/config/alpha/tm-nbsd.h b/gdb/config/alpha/tm-nbsd.h
new file mode 100644
index 00000000000..90a75a78fd6
--- /dev/null
+++ b/gdb/config/alpha/tm-nbsd.h
@@ -0,0 +1,33 @@
+/* Target-dependent definitions for NetBSD/Alpha.
+ Copyright 2002 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. */
+
+#ifndef TM_NBSD_H
+#define TM_NBSD_H
+
+#include "alpha/tm-alpha.h"
+#include "solib.h"
+
+/* Number of traps that happen between exec'ing the shell to run an
+ inferior, and when we finally get to the inferior code. The
+ default is right for NetBSD. */
+
+#undef START_INFERIOR_TRAPS_EXPECTED
+
+#endif /* TM_NBSD_H */
diff --git a/gdb/config/alpha/xm-alphalinux.h b/gdb/config/alpha/xm-alphalinux.h
new file mode 100644
index 00000000000..f1bc14da4bd
--- /dev/null
+++ b/gdb/config/alpha/xm-alphalinux.h
@@ -0,0 +1,26 @@
+/* Host definitions for GDB running on an Alpha under GNU/Linux.
+
+ Copyright 1996, 2001, 2002 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. */
+
+/* The alpha has no siginterrupt routine. */
+#define NO_SIGINTERRUPT
+
+#define HAVE_TERMIOS
+#define USG
diff --git a/gdb/config/alpha/xm-alphaosf.h b/gdb/config/alpha/xm-alphaosf.h
new file mode 100644
index 00000000000..67d3cc4af8a
--- /dev/null
+++ b/gdb/config/alpha/xm-alphaosf.h
@@ -0,0 +1,24 @@
+/* Host definitions for GDB running on an alpha under OSF/1
+ Copyright 1992, 1993, 1996 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. */
+
+/* The alpha has no siginterrupt routine. */
+#define NO_SIGINTERRUPT
+
+#define HAVE_TERMIOS
diff --git a/gdb/config/arc/arc.mt b/gdb/config/arc/arc.mt
new file mode 100644
index 00000000000..8ee8c3d0619
--- /dev/null
+++ b/gdb/config/arc/arc.mt
@@ -0,0 +1,3 @@
+# Target: ARC processor
+TDEPFILES = arc-tdep.o
+TM_FILE = tm-arc.h
diff --git a/gdb/config/arc/tm-arc.h b/gdb/config/arc/tm-arc.h
new file mode 100644
index 00000000000..cbdcf41e0e9
--- /dev/null
+++ b/gdb/config/arc/tm-arc.h
@@ -0,0 +1,336 @@
+/* Parameters for target machine ARC, for GDB, the GNU debugger.
+ Copyright 1995, 1996, 1998, 1999, 2000 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 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 "regcache.h"
+
+/* Used by arc-tdep.c to set the default cpu type. */
+#define DEFAULT_ARC_CPU_TYPE "base"
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code. */
+
+#define SKIP_PROLOGUE(pc) (arc_skip_prologue (pc, 0))
+extern CORE_ADDR arc_skip_prologue (CORE_ADDR, int);
+
+#define PROLOGUE_FRAMELESS_P(pc) arc_prologue_frameless_p(pc)
+extern int arc_prologue_frameless_p (CORE_ADDR);
+
+/* Sequence of bytes for breakpoint instruction.
+ ??? The current value is "sr -1,[-1]" and is for the simulator only.
+ The simulator watches for this and does the right thing.
+ The hardware version will have to associate with each breakpoint
+ the sequence "flag 1; nop; nop; nop". IE: The breakpoint insn will not
+ be a fixed set of bits but instead will be a branch to a semi-random
+ address. Presumably this will be cleaned up for "second silicon". */
+#define BIG_BREAKPOINT { 0x12, 0x1f, 0xff, 0xff }
+#define LITTLE_BREAKPOINT { 0xff, 0xff, 0x1f, 0x12 }
+
+/* Given the exposed pipeline, there isn't any one correct value.
+ However, this value must be 4. GDB can't handle any other value (other than
+ zero). See for example infrun.c:
+ "prev_pc != stop_pc - DECR_PC_AFTER_BREAK" */
+/* FIXME */
+#define DECR_PC_AFTER_BREAK 8
+
+/* We don't have a reliable single step facility.
+ ??? We do have a cycle single step facility, but that won't work. */
+#define SOFTWARE_SINGLE_STEP_P() 1
+extern void arc_software_single_step (enum target_signal, int);
+#define SOFTWARE_SINGLE_STEP(sig,bp_p) arc_software_single_step (sig, bp_p)
+
+/* FIXME: Need to set STEP_SKIPS_DELAY. */
+
+/* Given a pc value as defined by the hardware, return the real address.
+ Remember that on the ARC blink contains that status register which
+ includes PC + flags (so we have to mask out the flags). */
+#define ARC_PC_TO_REAL_ADDRESS(pc) (((pc) & 0xffffff) << 2)
+
+/* Immediately after a function call, return the saved pc.
+ Can't always go through the frames for this because on some machines
+ the new frame is not set up until the new function
+ executes some instructions. */
+
+#define SAVED_PC_AFTER_CALL(frame) \
+ (ARC_PC_TO_REAL_ADDRESS (read_register (BLINK_REGNUM)))
+
+/* Stack grows upward */
+
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+/* Say how long (ordinary) registers are. This is a piece of bogosity
+ used in push_word and a few other places; REGISTER_RAW_SIZE is the
+ real way to know how big a register is. */
+#define REGISTER_SIZE 4
+
+/* Number of machine registers */
+#define NUM_REGS 92
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer. */
+
+#define REGISTER_NAMES \
+{ \
+ /* 0 */ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ /* 8 */ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
+ /* 16 */ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
+ /* 24 */ "r24", "r25", "r26", "fp", "sp", "ilink1", "ilink2", "blink", \
+ /* 32 */ "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", \
+ /* 40 */ "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", \
+ /* 48 */ "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", \
+ /* 56 */ "r56", "mlo", "mmid", "mhi", "lp_count", \
+ /* 61 */ "status", "sema", "lp_start", "lp_end", "identity", "debug", \
+ /* 67 */ "aux10", "aux11", "aux12", "aux13", "aux14", \
+ /* 72 */ "aux15", "aux16", "aux17", "aux18", "aux19", \
+ /* 77 */ "aux1a", "aux1b", "aux1c", "aux1d", "aux1e", \
+ /* 82 */ "aux1f", "aux20", "aux21", "aux22", \
+ /* 86 */ "aux30", "aux31", "aux32", "aux33", "aux40", \
+ /* 91 */ "pc" \
+}
+
+/* Register numbers of various important registers (used to index
+ into arrays of register names and register values). */
+
+#define R0_REGNUM 0 /* First local register */
+#define R59_REGNUM 59 /* Last local register */
+#define FP_REGNUM 27 /* Contains address of executing stack frame */
+#define SP_REGNUM 28 /* stack pointer */
+#define BLINK_REGNUM 31 /* link register */
+#define STA_REGNUM 61 /* processor status word */
+#define PC_REGNUM 91 /* instruction pointer */
+#define AUX_BEG_REGNUM 61 /* aux reg begins */
+#define AUX_END_REGNUM 90 /* aux reg ends, pc not real aux reg */
+
+/* Fake registers used to mark immediate data. */
+#define SHIMM_FLAG_REGNUM 61
+#define LIMM_REGNUM 62
+#define SHIMM_REGNUM 63
+
+#define AUX_REG_MAP \
+{ \
+ { 0, 1, 2, 3, 4, 5, \
+ 16, -1, -1, -1, -1, \
+ -1, -1, -1, -1, -1, \
+ -1, -1, -1, -1, 30, \
+ -1, 32, 33, -1, \
+ 48, 49, 50, 51, 64, \
+ 0 \
+ }, \
+ { 0, 1, 2, 3, 4, 5, \
+ 16, -1, -1, -1, -1, \
+ -1, -1, -1, -1, -1, \
+ -1, -1, -1, -1, 30, \
+ 31, 32, 33, -1, \
+ -1, -1, -1, -1, -1, \
+ 0 \
+ }, \
+ { 0, 1, 2, 3, 4, 5, \
+ 16, 17, 18, 19, 20, \
+ 21, 22, 23, 24, 25, \
+ 26, 27, 28, 29, 30, \
+ 31, 32, 33, 34, \
+ -1, -1, -1, -1, -1, \
+ 0 \
+ } \
+}
+
+#define PFP_REGNUM R0_REGNUM /* Previous frame pointer */
+
+/* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'. */
+#define REGISTER_BYTES (NUM_REGS * 4)
+
+/* Index within `registers' of the first byte of the space for register N. */
+#define REGISTER_BYTE(N) (4*(N))
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. */
+#define REGISTER_RAW_SIZE(N) 4
+
+/* Number of bytes of storage in the program's representation for register N. */
+#define REGISTER_VIRTUAL_SIZE(N) 4
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+#define MAX_REGISTER_RAW_SIZE 4
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+#define MAX_REGISTER_VIRTUAL_SIZE 4
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+#define REGISTER_VIRTUAL_TYPE(N) (builtin_type_int)
+
+
+/* Macros for understanding function return values... */
+
+/* Does the specified function use the "struct returning" convention
+ or the "value returning" convention? The "value returning" convention
+ almost invariably returns the entire value in registers. The
+ "struct returning" convention often returns the entire value in
+ memory, and passes a pointer (out of or into the function) saying
+ where the value (is or should go).
+
+ Since this sometimes depends on whether it was compiled with GCC,
+ this is also an argument. This is used in call_function to build a
+ stack, and in value_being_returned to print return values.
+
+ On arc, a structure is always retunred with pointer in r0. */
+
+#define USE_STRUCT_CONVENTION(gcc_p, type) 1
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. This is only called if USE_STRUCT_CONVENTION for this
+ type is 0.
+ */
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ memcpy(VALBUF, REGBUF+REGISTER_BYTE(R0_REGNUM), TYPE_LENGTH (TYPE))
+
+/* If USE_STRUCT_CONVENTION produces a 1,
+ extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+ (error("Don't know where large structure is returned on arc"), 0)
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format, for "value returning" functions.
+ For 'return' command: not (yet) implemented for arc. */
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ error ("Returning values from functions is not implemented in arc gdb")
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function. */
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+ error ("Returning values from functions is not implemented in arc gdb")
+
+
+/* Describe the pointer in each stack frame to the previous stack frame
+ (its caller). */
+
+/* We cache information about saved registers in the frame structure,
+ to save us from having to re-scan function prologues every time
+ a register in a non-current frame is accessed. */
+
+#define EXTRA_FRAME_INFO \
+ struct frame_saved_regs *fsr; \
+ CORE_ADDR arg_pointer;
+
+/* Zero the frame_saved_regs pointer when the frame is initialized,
+ so that FRAME_FIND_SAVED_REGS () will know to allocate and
+ initialize a frame_saved_regs struct the first time it is called.
+ Set the arg_pointer to -1, which is not valid; 0 and other values
+ indicate real, cached values. */
+
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \
+ ((fi)->fsr = 0, (fi)->arg_pointer = -1)
+
+/* FRAME_CHAIN takes a frame's nominal address
+ and produces the frame's chain-pointer.
+ However, if FRAME_CHAIN_VALID returns zero,
+ it means the given frame is the outermost one and has no caller. */
+/* On the arc, we get the chain pointer by reading the PFP saved
+ on the stack. */
+/* The PFP and RPC is in fp and fp+4. */
+
+#define FRAME_CHAIN(thisframe) \
+ (read_memory_integer (FRAME_FP (thisframe), 4))
+
+/* FRAME_CHAIN_VALID returns zero if the given frame is the outermost one
+ and has no caller. */
+#define FRAME_CHAIN_VALID(chain, thisframe) nonnull_frame_chain_valid (chain, thisframe)
+
+/* An expression that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. */
+
+#define FRAMELESS_FUNCTION_INVOCATION(FI) \
+ (((FI)->signal_handler_caller) ? 0 : frameless_look_for_prologue (FI))
+
+/* Where is the PC for a specific frame.
+ A leaf function may never save blink, so we have to check for that here. */
+
+#define FRAME_SAVED_PC(frame) (arc_frame_saved_pc (frame))
+struct frame_info; /* in case frame.h not included yet */
+CORE_ADDR arc_frame_saved_pc (struct frame_info *);
+
+/* If the argument is on the stack, it will be here.
+ We cache this value in the frame info if we've already looked it up. */
+/* ??? Is the arg_pointer check necessary? */
+
+#define FRAME_ARGS_ADDRESS(fi) \
+ (((fi)->arg_pointer != -1) ? (fi)->arg_pointer : (fi)->frame)
+
+/* This is the same except it should return 0 when
+ it does not really know where the args are, rather than guessing.
+ This value is not cached since it is only used infrequently. */
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Set NUMARGS to the number of args passed to a frame.
+ Can return -1, meaning no way to tell. */
+
+#define FRAME_NUM_ARGS(fi) (-1)
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Produce the positions of the saved registers in a stack frame. */
+
+#define FRAME_FIND_SAVED_REGS(frame_info_addr, sr) \
+ frame_find_saved_regs (frame_info_addr, &sr)
+extern void frame_find_saved_regs (); /* See arc-tdep.c */
+
+
+/* Things needed for making calls to functions in the inferior process */
+void arc_push_dummy_frame (void);
+#define PUSH_DUMMY_FRAME \
+ arc_push_dummy_frame ()
+
+/* Discard from the stack the innermost frame, restoring all registers. */
+void arc_pop_frame (void);
+#define POP_FRAME \
+ arc_pop_frame ()
+
+/* This sequence of words is the instructions bl xxxx, flag 1 */
+#define CALL_DUMMY { 0x28000000, 0x1fbe8001 }
+#define CALL_DUMMY_LENGTH 8
+
+/* Start execution at beginning of dummy */
+#define CALL_DUMMY_START_OFFSET 0
+
+/* Insert the specified number of args and function address
+ into a call sequence of the above form stored at 'dummyname'. */
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \
+{ \
+ int from, to, delta, loc; \
+ loc = (int)(read_register (SP_REGNUM) - CALL_DUMMY_LENGTH); \
+ from = loc + 4; \
+ to = (int)(fun); \
+ delta = (to - from) >> 2; \
+ *((char *)(dummyname) + 1) = (delta & 0x1); \
+ *((char *)(dummyname) + 2) = ((delta >> 1) & 0xff); \
+ *((char *)(dummyname) + 3) = ((delta >> 9) & 0xff); \
+ *((char *)(dummyname) + 4) = ((delta >> 17) & 0x7); \
+}
diff --git a/gdb/config/arm/embed.mt b/gdb/config/arm/embed.mt
new file mode 100644
index 00000000000..c854d17a71a
--- /dev/null
+++ b/gdb/config/arm/embed.mt
@@ -0,0 +1,7 @@
+# Target: ARM embedded system
+TDEPFILES= arm-tdep.o remote-rdp.o remote-rdi.o
+TDEPLIBS= rdi-share/libangsd.a
+TM_FILE= tm-embed.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/arm/libsim.a
diff --git a/gdb/config/arm/linux.mh b/gdb/config/arm/linux.mh
new file mode 100644
index 00000000000..fa1eb63d67f
--- /dev/null
+++ b/gdb/config/arm/linux.mh
@@ -0,0 +1,11 @@
+# Host: ARM based machine running GNU/Linux
+
+XM_FILE= xm-linux.h
+
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \
+ core-regset.o arm-linux-nat.o linux-proc.o gcore.o \
+ proc-service.o thread-db.o lin-lwp.o
+
+LOADLIBES= -ldl -rdynamic
+
diff --git a/gdb/config/arm/linux.mt b/gdb/config/arm/linux.mt
new file mode 100644
index 00000000000..e1996ab0639
--- /dev/null
+++ b/gdb/config/arm/linux.mt
@@ -0,0 +1,5 @@
+# Target: ARM based machine running GNU/Linux
+TM_FILE= tm-linux.h
+TDEPFILES= arm-tdep.o arm-linux-tdep.o solib.o solib-svr4.o solib-legacy.o
+
+GDBSERVER_DEPFILES = linux-low.o linux-arm-low.o reg-arm.o
diff --git a/gdb/config/arm/nbsd.mt b/gdb/config/arm/nbsd.mt
new file mode 100644
index 00000000000..94971369506
--- /dev/null
+++ b/gdb/config/arm/nbsd.mt
@@ -0,0 +1,2 @@
+# Target: ARM running NetBSD
+TDEPFILES= arm-tdep.o armnbsd-tdep.o solib.o solib-svr4.o nbsd-tdep.o
diff --git a/gdb/config/arm/nbsdaout.mh b/gdb/config/arm/nbsdaout.mh
new file mode 100644
index 00000000000..100e40b42bb
--- /dev/null
+++ b/gdb/config/arm/nbsdaout.mh
@@ -0,0 +1,5 @@
+# Host ARM running NetBSD
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o armnbsd-nat.o \
+ solib-sunos.o
+XM_FILE=xm-nbsd.h
+NAT_FILE=nm-nbsdaout.h
diff --git a/gdb/config/arm/nbsdelf.mh b/gdb/config/arm/nbsdelf.mh
new file mode 100644
index 00000000000..481d5cc92a5
--- /dev/null
+++ b/gdb/config/arm/nbsdelf.mh
@@ -0,0 +1,4 @@
+# Host ARM running NetBSD
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o armnbsd-nat.o
+XM_FILE=xm-nbsd.h
+NAT_FILE=nm-nbsd.h
diff --git a/gdb/config/arm/nm-linux.h b/gdb/config/arm/nm-linux.h
new file mode 100644
index 00000000000..2a0ebb3804b
--- /dev/null
+++ b/gdb/config/arm/nm-linux.h
@@ -0,0 +1,42 @@
+/* Definitions to make GDB run on an ARM based machine under GNU/Linux.
+ Copyright 1999, 2000, 2001 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. */
+
+#ifndef NM_ARMLINUX_H
+#define NM_ARMLINUX_H
+
+#include "nm-linux.h"
+
+/* ptrace register ``addresses'' are absolute. */
+
+#define U_REGS_OFFSET 0
+
+#ifdef GDBSERVER
+#define REGISTER_U_ADDR(addr,blockend,regno) \
+ (addr) = arm_register_u_addr ((blockend),(regno))
+#endif /* GDBSERVER */
+
+/* Return sizeof user struct to callers in less machine dependent routines */
+extern int kernel_u_size (void);
+#define KERNEL_U_SIZE arm_linux_kernel_u_size()
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
+#define FETCH_INFERIOR_REGISTERS
+
+#endif /* NM_ARMLINUX_H */
diff --git a/gdb/config/arm/nm-nbsd.h b/gdb/config/arm/nm-nbsd.h
new file mode 100644
index 00000000000..63be920092f
--- /dev/null
+++ b/gdb/config/arm/nm-nbsd.h
@@ -0,0 +1,27 @@
+/* Native-dependent definitions for ARM running NetBSD, for GDB.
+ Copyright 1986, 1987, 1989, 1992, 1994, 1999 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. */
+
+#ifndef NM_NBSD_H
+#define NM_NBSD_H
+
+/* Get generic NetBSD native definitions. */
+#include "config/nm-nbsd.h"
+
+#endif /* NM_NBSD_H */
diff --git a/gdb/config/arm/nm-nbsdaout.h b/gdb/config/arm/nm-nbsdaout.h
new file mode 100644
index 00000000000..3f7fee9de1a
--- /dev/null
+++ b/gdb/config/arm/nm-nbsdaout.h
@@ -0,0 +1,29 @@
+/* Native-dependent definitions for ARM running NetBSD, for GDB.
+ Copyright 1986, 1987, 1989, 1992, 1994, 1999 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. */
+
+#ifndef NM_NBSDAOUT_H
+#define NM_NBSDAOUT_H
+
+#include "arm/nm-nbsd.h"
+
+/* Get generic NetBSD a.out native definitions. */
+#include "config/nm-nbsdaout.h"
+
+#endif /* NM_NBSDAOUT_H */
diff --git a/gdb/config/arm/tm-arm.h b/gdb/config/arm/tm-arm.h
new file mode 100644
index 00000000000..369917524d4
--- /dev/null
+++ b/gdb/config/arm/tm-arm.h
@@ -0,0 +1,34 @@
+/* Definitions to target GDB to ARM targets.
+ Copyright 1986, 1987, 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001, 2002 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. */
+
+#ifndef TM_ARM_H
+#define TM_ARM_H
+
+#ifndef GDB_MULTI_ARCH
+#define GDB_MULTI_ARCH 1
+#endif
+
+/* Specify that for the native compiler variables for a particular
+ lexical context are listed after the beginning LBRAC instead of
+ before in the executables list of symbols. */
+#define VARIABLES_INSIDE_BLOCK(desc, gcc_p) (!(gcc_p))
+
+#endif /* TM_ARM_H */
diff --git a/gdb/config/arm/tm-embed.h b/gdb/config/arm/tm-embed.h
new file mode 100644
index 00000000000..5990311e4a6
--- /dev/null
+++ b/gdb/config/arm/tm-embed.h
@@ -0,0 +1,52 @@
+/* Definitions to target GDB to ARM embedded systems.
+ Copyright 1986, 1987, 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000 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. */
+
+#ifndef TM_ARMEMBED_H
+#define TM_ARMEMBED_H
+
+/* Include the common ARM definitions. */
+#include "arm/tm-arm.h"
+
+/* The remote stub should be able to single-step. */
+#undef SOFTWARE_SINGLE_STEP_P
+#define SOFTWARE_SINGLE_STEP_P() 0
+
+/* The first 0x20 bytes are the trap vectors. */
+#undef LOWEST_PC
+#define LOWEST_PC 0x20
+
+/* Override defaults. */
+
+#undef THUMB_LE_BREAKPOINT
+#define THUMB_LE_BREAKPOINT {0xbe,0xbe}
+#undef THUMB_BE_BREAKPOINT
+#define THUMB_BE_BREAKPOINT {0xbe,0xbe}
+
+/* Functions for dealing with Thumb call thunks. */
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) arm_in_call_stub (pc, name)
+#define SKIP_TRAMPOLINE_CODE(pc) arm_skip_stub (pc)
+extern int arm_in_call_stub (CORE_ADDR pc, char *name);
+extern CORE_ADDR arm_skip_stub (CORE_ADDR pc);
+
+#undef IN_SIGTRAMP
+#define IN_SIGTRAMP(pc, name) 0
+
+#endif /* TM_ARMEMBED_H */
diff --git a/gdb/config/arm/tm-linux.h b/gdb/config/arm/tm-linux.h
new file mode 100644
index 00000000000..6a0d0e42c96
--- /dev/null
+++ b/gdb/config/arm/tm-linux.h
@@ -0,0 +1,94 @@
+/* Target definitions for GNU/Linux on ARM, for GDB.
+ Copyright 1999, 2000 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. */
+
+#ifndef TM_ARMLINUX_H
+#define TM_ARMLINUX_H
+
+#ifdef GDBSERVER
+#define ARM_GNULINUX_TARGET
+#endif
+
+/* Include the common ARM target definitions. */
+#include "arm/tm-arm.h"
+
+#include "tm-linux.h"
+
+/* Use target-specific function to define link map offsets. */
+extern struct link_map_offsets *arm_linux_svr4_fetch_link_map_offsets (void);
+#define SVR4_FETCH_LINK_MAP_OFFSETS() arm_linux_svr4_fetch_link_map_offsets ()
+
+/* Offset to saved PC in sigcontext structure, from <asm/sigcontext.h> */
+#define SIGCONTEXT_PC_OFFSET (sizeof(unsigned long) * 18)
+
+/* We've multi-arched this. */
+#undef IN_SOLIB_CALL_TRAMPOLINE
+
+/* On ARM GNU/Linux, a call to a library routine does not have to go
+ through any trampoline code. */
+#define IN_SOLIB_RETURN_TRAMPOLINE(pc, name) 0
+
+/* We've multi-arched this. */
+#undef SKIP_TRAMPOLINE_CODE
+
+/* When we call a function in a shared library, and the PLT sends us
+ into the dynamic linker to find the function's real address, we
+ need to skip over the dynamic linker call. This function decides
+ when to skip, and where to skip to. See the comments for
+ SKIP_SOLIB_RESOLVER at the top of infrun.c. */
+extern CORE_ADDR arm_linux_skip_solib_resolver (CORE_ADDR pc);
+#define SKIP_SOLIB_RESOLVER arm_linux_skip_solib_resolver
+
+/* When we call a function in a shared library, and the PLT sends us
+ into the dynamic linker to find the function's real address, we
+ need to skip over the dynamic linker call. This function decides
+ when to skip, and where to skip to. See the comments for
+ SKIP_SOLIB_RESOLVER at the top of infrun.c. */
+#if 0
+#undef IN_SOLIB_DYNSYM_RESOLVE_CODE
+extern CORE_ADDR arm_in_solib_dynsym_resolve_code (CORE_ADDR pc, char *name);
+#define IN_SOLIB_DYNSYM_RESOLVE_CODE arm_in_solib_dynsym_resolve_code
+/* ScottB: Current definition is
+extern CORE_ADDR in_svr4_dynsym_resolve_code (CORE_ADDR pc, char *name);
+#define IN_SOLIB_DYNSYM_RESOLVE_CODE in_svr4_dynsym_resolve_code */
+#endif
+
+/* When the ARM Linux kernel invokes a signal handler, the return
+ address points at a special instruction which'll trap back into
+ the kernel. These definitions are used to identify this bit of
+ code as a signal trampoline in order to support backtracing
+ through calls to signal handlers. */
+
+int arm_linux_in_sigtramp (CORE_ADDR pc, char *name);
+#define IN_SIGTRAMP(pc, name) arm_linux_in_sigtramp (pc, name)
+
+/* Each OS has different mechanisms for accessing the various
+ registers stored in the sigcontext structure. These definitions
+ provide a mechanism by which the generic code in arm-tdep.c can
+ find the addresses at which various registers are saved at in the
+ sigcontext structure. If SIGCONTEXT_REGISTER_ADDRESS is not
+ defined, arm-tdep.c will define it to be 0. (See ia64-tdep.c and
+ ia64-linux-tdep.c to see what a similar mechanism looks like when
+ multi-arched.) */
+
+extern CORE_ADDR arm_linux_sigcontext_register_address (CORE_ADDR, CORE_ADDR,
+ int);
+#define SIGCONTEXT_REGISTER_ADDRESS arm_linux_sigcontext_register_address
+
+#endif /* TM_ARMLINUX_H */
diff --git a/gdb/config/arm/tm-wince.h b/gdb/config/arm/tm-wince.h
new file mode 100644
index 00000000000..82f97ad7b8f
--- /dev/null
+++ b/gdb/config/arm/tm-wince.h
@@ -0,0 +1,34 @@
+/* Definitions to target GDB for Windows CE target
+ Copyright 2000 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. */
+
+#ifndef TM_WINCE_H
+#define TM_WINCE_H
+
+#include "arm/tm-arm.h"
+
+#undef SOFTWARE_SINGLE_STEP_P
+#define SOFTWARE_SINGLE_STEP_P() 1
+
+#undef SOFTWARE_SINGLE_STEP
+#define SOFTWARE_SINGLE_STEP(sig, bp_p) wince_software_single_step (sig, bp_p)
+
+void wince_software_single_step (unsigned int, int);
+
+#endif /* TM_WINCE_H */
diff --git a/gdb/config/arm/wince.mt b/gdb/config/arm/wince.mt
new file mode 100644
index 00000000000..10fe0eb3f38
--- /dev/null
+++ b/gdb/config/arm/wince.mt
@@ -0,0 +1,5 @@
+# Target: Acorn RISC machine (ARM) with simulator
+TDEPFILES= arm-tdep.o wince.o
+TM_FILE= tm-wince.h
+MT_CFLAGS=-DARM -U_X86_ -U_M_IX86 -U__i386__ -U__i486__ -U__i586__ -U__i686__ -DUNICODE -D_WIN32_WCE -DWINCE_STUB='"${target_alias}-stub.exe"'
+WIN32LIBS=-lrapi
diff --git a/gdb/config/arm/xm-linux.h b/gdb/config/arm/xm-linux.h
new file mode 100644
index 00000000000..fa82a1e8f39
--- /dev/null
+++ b/gdb/config/arm/xm-linux.h
@@ -0,0 +1,28 @@
+/* Host definitions for ARM GNU/Linux, for GDB, the GNU debugger.
+ Copyright 1999, 2001 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. */
+
+#ifndef XM_ARMLINUX_H
+#define XM_ARMLINUX_H
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+#define KERNEL_U_ADDR 0x0
+
+#endif /* XM_ARMLINUX_H */
diff --git a/gdb/config/arm/xm-nbsd.h b/gdb/config/arm/xm-nbsd.h
new file mode 100644
index 00000000000..c5348d39629
--- /dev/null
+++ b/gdb/config/arm/xm-nbsd.h
@@ -0,0 +1,22 @@
+/* Parameters for execution on an ARM running NetBSD, for GDB.
+ Copyright 1994 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. */
+
+/* Get generic NetBSD host definitions. */
+#include "xm-nbsd.h"
diff --git a/gdb/config/avr/avr.mt b/gdb/config/avr/avr.mt
new file mode 100644
index 00000000000..0354a421101
--- /dev/null
+++ b/gdb/config/avr/avr.mt
@@ -0,0 +1,12 @@
+# Target: AVR
+TDEPFILES= avr-tdep.o
+
+#
+# There is no simulator provided with gdb (yet).
+#
+# See <http://savannah.gnu.org/projects/simulavr/> for the simulator
+# used during development of avr support for gdb.
+#
+# Simulator: AVR
+#SIM_OBS = remote-sim.o
+#SIM = ../sim/avr/libsim.a
diff --git a/gdb/config/cris/cris.mt b/gdb/config/cris/cris.mt
new file mode 100644
index 00000000000..9304d365960
--- /dev/null
+++ b/gdb/config/cris/cris.mt
@@ -0,0 +1,2 @@
+TDEPFILES= cris-tdep.o corelow.o solib.o solib-svr4.o
+TM_FILE= tm-cris.h
diff --git a/gdb/config/cris/tm-cris.h b/gdb/config/cris/tm-cris.h
new file mode 100644
index 00000000000..fed260112c3
--- /dev/null
+++ b/gdb/config/cris/tm-cris.h
@@ -0,0 +1,2 @@
+#define GDB_MULTI_ARCH 1
+#include "solib.h"
diff --git a/gdb/config/d10v/d10v.mt b/gdb/config/d10v/d10v.mt
new file mode 100644
index 00000000000..72680e22dfb
--- /dev/null
+++ b/gdb/config/d10v/d10v.mt
@@ -0,0 +1,4 @@
+# Target: Mitsubishi D10V processor
+TDEPFILES= d10v-tdep.o
+SIM_OBS= remote-sim.o
+SIM= ../sim/d10v/libsim.a
diff --git a/gdb/config/d30v/d30v.mt b/gdb/config/d30v/d30v.mt
new file mode 100644
index 00000000000..da0af2fd2eb
--- /dev/null
+++ b/gdb/config/d30v/d30v.mt
@@ -0,0 +1,5 @@
+# Target: Mitsubishi D30V processor
+TDEPFILES= d30v-tdep.o
+TM_FILE= tm-d30v.h
+SIM_OBS= remote-sim.o
+SIM= ../sim/d30v/libsim.a
diff --git a/gdb/config/d30v/tm-d30v.h b/gdb/config/d30v/tm-d30v.h
new file mode 100644
index 00000000000..7a14e39132c
--- /dev/null
+++ b/gdb/config/d30v/tm-d30v.h
@@ -0,0 +1,323 @@
+/* Target-specific definition for the Mitsubishi D30V
+ Copyright 1997, 1998, 1999, 2000 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. */
+
+#ifndef TM_D30V_H
+#define TM_D30V_H
+
+#include "regcache.h"
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+
+#define FUNCTION_START_OFFSET 0
+
+/* these are the addresses the D30V-EVA board maps data */
+/* and instruction memory to. */
+
+#define DMEM_START 0x20000000
+#define IMEM_START 0x00000000 /* was 0x10000000 */
+#define STACK_START 0x20007ffe
+
+/* Forward decls for prototypes */
+struct frame_info;
+struct frame_saved_regs;
+struct type;
+struct value;
+
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code. */
+
+extern CORE_ADDR d30v_skip_prologue (CORE_ADDR);
+#define SKIP_PROLOGUE(ip) (d30v_skip_prologue (ip))
+
+
+/* Stack grows downward. */
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+/* for a breakpoint, use "dbt || nop" */
+#define BREAKPOINT {0x00, 0xb0, 0x00, 0x00,\
+ 0x00, 0xf0, 0x00, 0x00}
+
+/* If your kernel resets the pc after the trap happens you may need to
+ define this before including this file. */
+#define DECR_PC_AFTER_BREAK 0
+
+#define REGISTER_NAMES \
+{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \
+ "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", \
+ "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", \
+ "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", \
+ "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63", \
+ "spi", "spu", \
+ "psw", "bpsw", "pc", "bpc", "dpsw", "dpc", "cr6", "rpt_c", \
+ "rpt_s", "rpt_e", "mod_s", "mod_e", "cr12", "cr13", "iba", "eit_vb",\
+ "int_s", "int_m", "a0", "a1" \
+ }
+
+#define NUM_REGS 86
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define R0_REGNUM 0
+#define FP_REGNUM 61
+#define LR_REGNUM 62
+#define SP_REGNUM 63
+#define SPI_REGNUM 64 /* Interrupt stack pointer */
+#define SPU_REGNUM 65 /* User stack pointer */
+#define CREGS_START 66
+
+#define PSW_REGNUM (CREGS_START + 0) /* psw, bpsw, or dpsw??? */
+#define PSW_SM (((unsigned long)0x80000000) >> 0) /* Stack mode: 0/SPI */
+ /* 1/SPU */
+#define PSW_EA (((unsigned long)0x80000000) >> 2) /* Execution status */
+#define PSW_DB (((unsigned long)0x80000000) >> 3) /* Debug mode */
+#define PSW_DS (((unsigned long)0x80000000) >> 4) /* Debug EIT status */
+#define PSW_IE (((unsigned long)0x80000000) >> 5) /* Interrupt enable */
+#define PSW_RP (((unsigned long)0x80000000) >> 6) /* Repeat enable */
+#define PSW_MD (((unsigned long)0x80000000) >> 7) /* Modulo enable */
+#define PSW_F0 (((unsigned long)0x80000000) >> 17) /* F0 flag */
+#define PSW_F1 (((unsigned long)0x80000000) >> 19) /* F1 flag */
+#define PSW_F2 (((unsigned long)0x80000000) >> 21) /* F2 flag */
+#define PSW_F3 (((unsigned long)0x80000000) >> 23) /* F3 flag */
+#define PSW_S (((unsigned long)0x80000000) >> 25) /* Saturation flag */
+#define PSW_V (((unsigned long)0x80000000) >> 27) /* Overflow flag */
+#define PSW_VA (((unsigned long)0x80000000) >> 29) /* Accum. overflow */
+#define PSW_C (((unsigned long)0x80000000) >> 31) /* Carry/Borrow flag */
+
+#define BPSW_REGNUM (CREGS_START + 1) /* Backup PSW (on interrupt) */
+#define PC_REGNUM (CREGS_START + 2) /* pc, bpc, or dpc??? */
+#define BPC_REGNUM (CREGS_START + 3) /* Backup PC (on interrupt) */
+#define DPSW_REGNUM (CREGS_START + 4) /* Backup PSW (on debug trap) */
+#define DPC_REGNUM (CREGS_START + 5) /* Backup PC (on debug trap) */
+#define RPT_C_REGNUM (CREGS_START + 7) /* Loop count */
+#define RPT_S_REGNUM (CREGS_START + 8) /* Loop start address */
+#define RPT_E_REGNUM (CREGS_START + 9) /* Loop end address */
+#define MOD_S_REGNUM (CREGS_START + 10)
+#define MOD_E_REGNUM (CREGS_START + 11)
+#define IBA_REGNUM (CREGS_START + 14) /* Instruction break address */
+#define EIT_VB_REGNUM (CREGS_START + 15) /* Vector base address */
+#define INT_S_REGNUM (CREGS_START + 16) /* Interrupt status */
+#define INT_M_REGNUM (CREGS_START + 17) /* Interrupt mask */
+#define A0_REGNUM 84
+#define A1_REGNUM 85
+
+/* Say how much memory is needed to store a copy of the register set */
+#define REGISTER_BYTES ((NUM_REGS - 2) * 4 + 2 * 8)
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#define REGISTER_BYTE(N) \
+( ((N) >= A0_REGNUM) ? ( ((N) - A0_REGNUM) * 8 + A0_REGNUM * 4 ) : ((N) * 4) )
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. */
+
+#define REGISTER_RAW_SIZE(N) ( ((N) >= A0_REGNUM) ? 8 : 4 )
+
+/* Number of bytes of storage in the program's representation
+ for register N. */
+#define REGISTER_VIRTUAL_SIZE(N) REGISTER_RAW_SIZE(N)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#define MAX_REGISTER_RAW_SIZE 8
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+( ((N) < A0_REGNUM ) ? builtin_type_long : builtin_type_long_long)
+
+/* Writing to r0 is a noop (not an error or exception or anything like
+ that, however). */
+
+#define CANNOT_STORE_REGISTER(regno) ((regno) == R0_REGNUM)
+
+void d30v_do_registers_info (int regnum, int fpregs);
+
+#define DO_REGISTERS_INFO d30v_do_registers_info
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function.
+
+ We store structs through a pointer passed in R2 */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+ { write_register (2, (ADDR)); }
+
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format.
+
+ Things always get returned in R2/R3 */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ write_register_bytes (REGISTER_BYTE(2), VALBUF, TYPE_LENGTH (TYPE))
+
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (((CORE_ADDR *)(REGBUF))[2])
+
+
+/* Define other aspects of the stack frame.
+ we keep a copy of the worked out return pc lying around, since it
+ is a useful bit of info */
+
+#define EXTRA_FRAME_INFO \
+ CORE_ADDR return_pc; \
+ CORE_ADDR dummy; \
+ int frameless; \
+ int size;
+
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \
+ d30v_init_extra_frame_info(fromleaf, fi)
+
+extern void d30v_init_extra_frame_info (int fromleaf, struct frame_info *fi);
+
+/* A macro that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. If it
+ does not, FRAMELESS is set to 1, else 0. */
+
+#define FRAMELESS_FUNCTION_INVOCATION(FI) \
+ (frameless_look_for_prologue (FI))
+
+CORE_ADDR d30v_frame_chain (struct frame_info *frame);
+#define FRAME_CHAIN(FRAME) d30v_frame_chain(FRAME)
+extern int d30v_frame_chain_valid (CORE_ADDR, struct frame_info *);
+#define FRAME_CHAIN_VALID(chain, thisframe) d30v_frame_chain_valid (chain, thisframe)
+#define FRAME_SAVED_PC(FRAME) ((FRAME)->return_pc)
+#define FRAME_ARGS_ADDRESS(fi) (fi)->frame
+#define FRAME_LOCALS_ADDRESS(fi) (fi)->frame
+
+void d30v_init_frame_pc (int fromleaf, struct frame_info *prev);
+#define INIT_FRAME_PC_FIRST(fromleaf, prev) d30v_init_frame_pc(fromleaf, prev)
+#define INIT_FRAME_PC(fromleaf, prev) /* nada */
+
+/* Immediately after a function call, return the saved pc. We can't */
+/* use frame->return_pc beause that is determined by reading R62 off the */
+/* stack and that may not be written yet. */
+
+#define SAVED_PC_AFTER_CALL(frame) (read_register(LR_REGNUM))
+
+/* Set VAL to the number of args passed to frame described by FI.
+ Can set VAL to -1, meaning no way to tell. */
+/* We can't tell how many args there are */
+
+#define FRAME_NUM_ARGS(fi) (-1)
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#define FRAME_ARGS_SKIP 0
+
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame. */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+ d30v_frame_find_saved_regs(frame_info, &(frame_saved_regs))
+
+extern void d30v_frame_find_saved_regs (struct frame_info *,
+ struct frame_saved_regs *);
+
+/* DUMMY FRAMES. Need these to support inferior function calls.
+ They work like this on D30V:
+ First we set a breakpoint at 0 or __start.
+ Then we push all the registers onto the stack.
+ Then put the function arguments in the proper registers and set r13
+ to our breakpoint address.
+ Finally call the function directly.
+ When it hits the breakpoint, clear the break point and pop the old
+ register contents off the stack. */
+
+#define CALL_DUMMY { 0 }
+#define PUSH_DUMMY_FRAME
+#define CALL_DUMMY_START_OFFSET 0
+#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
+#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
+
+extern CORE_ADDR d30v_call_dummy_address (void);
+#define CALL_DUMMY_ADDRESS() d30v_call_dummy_address()
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \
+sp = d30v_fix_call_dummy (dummyname, pc, fun, nargs, args, type, gcc_p)
+
+#define PC_IN_CALL_DUMMY(pc, sp, frame_address) ( pc == IMEM_START + 4 )
+
+extern CORE_ADDR d30v_fix_call_dummy (char *, CORE_ADDR, CORE_ADDR,
+ int, struct value **,
+ struct type *, int);
+#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
+ (d30v_push_arguments((nargs), (args), (sp), (struct_return), (struct_addr)))
+extern CORE_ADDR d30v_push_arguments (int, struct value **, CORE_ADDR, int,
+ CORE_ADDR);
+
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+d30v_extract_return_value(TYPE, REGBUF, VALBUF)
+extern void d30v_extract_return_value (struct type *, char *, char *);
+
+
+/* Discard from the stack the innermost frame,
+ restoring all saved registers. */
+#define POP_FRAME d30v_pop_frame();
+extern void d30v_pop_frame (void);
+
+#define REGISTER_SIZE 4
+
+/* Need to handle SP special, as we need to select between spu and spi. */
+#if 0 /* XXX until the simulator is fixed */
+#define TARGET_READ_SP() ((read_register (PSW_REGNUM) & PSW_SM) \
+ ? read_register (SPU_REGNUM) \
+ : read_register (SPI_REGNUM))
+
+#define TARGET_WRITE_SP(val) ((read_register (PSW_REGNUM) & PSW_SM) \
+ ? write_register (SPU_REGNUM, (val)) \
+ : write_register (SPI_REGNUM, (val)))
+#endif
+
+#define STACK_ALIGN(len) (((len) + 7 ) & ~7)
+
+/* Turn this on to cause remote-sim.c to use sim_set/clear_breakpoint. */
+
+#define SIM_HAS_BREAKPOINTS
+
+#endif /* TM_D30V_H */
diff --git a/gdb/config/djgpp/README b/gdb/config/djgpp/README
new file mode 100644
index 00000000000..805e1df1f8f
--- /dev/null
+++ b/gdb/config/djgpp/README
@@ -0,0 +1,189 @@
+
+ How to build and install the DJGPP native version of GDB
+ ********************************************************
+
+General
+=======
+
+GDB built with DJGPP supports native DJGPP debugging, whereby you run
+gdb.exe and the program being debugged on the same machine. In
+addition, this version supports remote debugging via a serial port,
+provided that the target machine has a GDB-compatible debugging stub
+which can be linked with the target program (see the section "Remote
+Serial" in the GDB manual for more details).
+
+
+Installation of the binary distribution
+=======================================
+
+Simply unzip the gdbNNNb.zip file (where NNN is the version number)
+from the top DJGPP installation directory. Be sure to preserve the
+directory structure while you unzip (use -d switch if you do this with
+PKUNZIP). On Windows 9X and Windows 2000, use an unzip program which
+supports long file names; one such program is unzip32.exe, available
+from the DJGPP sites.
+
+If you need the libraries which are built as part of GDB, install the
+companion file gdbNNNa.zip. This allows to develop applications which
+use the same functions as GDB. For example, you can build your own
+front end to the debugger.
+
+
+Rebuilding GDB from sources
+===========================
+
+1. Prerequisites
+ -------------
+To build the package, you will need the DJGPP development environment
+(GCC, header files, and the libraries), and also DJGPP ports of the
+following tools:
+
+ - GNU Make 3.79.1 or later
+ - Bash 2.03 or later
+ - GNU Sed
+ - GNU Fileutils
+ - GNU Textutils 2.0 or later
+ - GNU Sh-utils
+ - GNU Grep 2.4 or later
+ - GNU Findutils
+ - GNU Awk 3.04 or later
+ - GNU Bison (only if you change one of the gdb/*.y files)
+ - Groff (only if you need to format the man pages)
+ - GNU Diffutils (only if you run the test suite)
+
+These programs should be available from the DJGPP sites, in the v2gnu
+directory. In addition, the configuration script invokes the `update'
+and `utod' utilities which are part of the basic DJGPP development kit
+(djdevNNN.zip).
+
+
+2. Unpacking the sources
+ ---------------------
+If you download the source distribution from one of the DJGPP sites,
+just unzip it while preserving the directory structure (I suggest to
+use unzip32.exe available with the rest of DJGPP), and proceed to the
+section "How to build", below.
+
+Source distributions downloaded from one of the GNU FTP sites need
+some more work to unpack. First, you MUST use the `djunpack' batch
+file to unzip the package. That's because some file names in the
+official distributions need to be changed to avoid problems on the
+various platforms supported by DJGPP. `djunpack' invokes the `djtar'
+program (that is part of the basic DJGPP development kit) to rename
+these files on the fly given a file with name mappings; the
+distribution includes a file `gdb/config/djgpp/fnchange.lst' with the
+necessary mappings. So you need first to retrieve that batch file,
+and then invoke it to unpack the distribution. Here's how:
+
+ djtar -x -p -o gdb-5.2/djunpack.bat gdb-5.2.tar.gz > djunpack.bat
+ djunpack gdb-5.2.tar.gz
+
+(The name of the distribution archive and the leading directory of the
+path to `djunpack.bat' in the distribution will be different for
+versions of GDB other than 5.2.)
+
+If the argument to `djunpack.bat' include leading directories, it MUST
+be given with the DOS-style backslashes; Unix-style forward slashes
+will NOT work.
+
+If the distribution comes as a .tar.bz2 archive, and your version of
+`djtar' doesn't support bzip2 decompression, you need to unpack it as
+follows:
+
+ bnzip2 gdb-5.2.tar.bz2
+ djtar -x -p -o gdb-5.2/djunpack.bat gdb-5.2.tar > djunpack.bat
+ djunpack gdb-5.2.tar
+
+
+3. How to build
+ ------------
+
+If the source distribution available from DJGPP archives is already
+configured for DJGPP v2.x (if it is, you will find files named
+`Makefile' in each subdirectory), then just invoke Make:
+
+ make
+
+To build a package that is not yet configured, or if you downloaded
+GDB from a GNU FTP site, you will need to configure it first. You
+will also need to configure it if you want to change the configuration
+options (e.g., compile without support for the GDBMI interface). To
+configure GDB, type this command:
+
+ sh ./gdb/config/djgpp/djconfig.sh
+
+This script checks the unpacked distribution, then edits the configure
+scripts in the various subdirectories, to make them suitable for
+DJGPP, and finally invokes the top-level configure script, which
+recursively configures all the subdirectories.
+
+You may pass optional switches to djconfig.sh. It accepts all the
+switches accepted by the original GDB configure script. These
+switches are described in the file gdb/README, and their full list can
+be displayed by running the following command:
+
+ sh ./gdb/configure --help
+
+NOTE: if you *do* use optional command-line switches, you MUST pass
+to the script the name of the directory where GDB sources are
+unpacked--even if you are building GDB in-place! For example:
+
+ sh ./gdb/config/djgpp/djconfig.sh . --disable-gdbmi
+
+It is also possible to build GDB in a directory that is different from
+the one where the sources were unpacked. In that case, you have to
+pass the source directory as the first argument to the script:
+
+ sh ./gdb/config/djgpp/djconfig.sh d:/gnu/gdb-5.2
+
+You MUST use forward slashes in the first argument.
+
+After the configure script finishes, run Make:
+
+ make
+
+If you want to produce the documentation (for example, if you changed
+some of the Texinfo sources), type this:
+
+ make info
+
+When Make finishes, you can install the package:
+
+ make install prefix='${DJDIR}' INSTALL='ginstall -c'
+
+The above doesn't install the docs; for that you will need to say
+this:
+
+ make install-info prefix='${DJDIR}' INSTALL='ginstall -c'
+
+The test suite has been made to work with DJGPP. If you make a change
+in some of the programs, or want to be sure you have a fully
+functional GDB executable, it is a good idea to run the test suite.
+You cannot use "make check" for that, since it will want to run the
+`dejagnu' utility which GDB doesn't support. Instead, use the special
+script gdb/config/djgpp/djcheck.sh, like this:
+
+ cd gdb/testsuite
+ sh ../config/djgpp/djcheck.sh
+
+This will run for a while and should not print anything, except the
+messages "Running tests in DIR", where DIR is one of the
+subdirectories of the testsuite. Any test that fails to produce the
+expected output will cause the diffs between the expected and the
+actual output be printed, and in addition will leave behind a file
+SOMETHING.tst (where SOMETHING is the name of the failed test). You
+should compare each of the *.tst files with the corresponding *.out
+file and convince yourself that the differences do not indicate a real
+problem. Examples of differences you can disregard are changes in the
+copyright blurb printed by GDB, values of unitialized variables,
+addresses of global variables like argv[] and envp[] (which depend on
+the size of your environment), etc.
+
+Note that djcheck.sh only recurses into those of the subdirectories of
+the test suite which test features supported by the DJGPP port of GDB.
+For example, the tests in the gdb.gdbtk, gdb.threads, and gdb.hp
+directories are not run.
+
+
+Enjoy,
+ Eli Zaretskii <eliz@is.elta.co.il>
diff --git a/gdb/config/djgpp/config.sed b/gdb/config/djgpp/config.sed
new file mode 100644
index 00000000000..7cc9d3f3e48
--- /dev/null
+++ b/gdb/config/djgpp/config.sed
@@ -0,0 +1,34 @@
+s|po2tbl\.sed\.in|po2tblsed.in|g
+s|gdb\.c++|gdb.cxx|g
+/ac_rel_source/s|ln -s|cp -p|
+s|\.gdbinit|gdb.ini|g
+
+/ac_given_INSTALL=/,/^CEOF/ {
+ /^s%@prefix@%/a\
+ s,\\([yp*]\\)\\.tab,\\1_tab,g\
+ /^ @rm -f/s,\\$@-\\[0-9\\]\\[0-9\\],& *.i[1-9] *.i[1-9][0-9],\
+ s,standards\\.info\\*,standard*.inf*,\
+ s,configure\\.info\\*,configur*.inf*,\
+ s,\\.info\\*,.inf* *.i[1-9] *.i[1-9][0-9],\
+ s,\\.gdbinit,gdb.ini,g\
+ /TEXINPUTS=/s,:,';',g\
+ /VPATH *=/s,\\([^A-z]\\):,\1;,g\
+ /\\$\\$file-\\[0-9\\]/s,echo,& *.i[1-9] *.i[1-9][0-9],\
+ /\\$\\$file-\\[0-9\\]/s,rm -f \\$\\$file,& \\${PACKAGE}.i[1-9] \\${PACKAGE}.i[1-9][0-9],\
+ s,config\\.h\\.in,config.h-in,g\
+ s,po2tbl\\.sed\\.in,po2tblsed.in,g
+}
+
+/^CONFIG_FILES=/,/^EOF/ {
+ s|po/Makefile.in\([^-:]\)|po/Makefile.in:po/Makefile.in-in\1|
+}
+
+/^ *CONFIG_HEADERS=/,/^EOF/ {
+ s|config.h\([^-:]\)|config.h:config.h-in\1|
+}
+
+/^[ ]*\/\*)/s,/\*,/*|[A-z]:/*,
+/\$]\*) INSTALL=/s,\[/\$\]\*,&|[A-z]:/*,
+/\$]\*) ac_rel_source=/s,\[/\$\]\*,&|[A-z]:/*,
+/ac_file_inputs=/s,\( -e "s%\^%\$ac_given_srcdir/%"\)\( -e "s%:% $ac_given_srcdir/%g"\),\2\1,
+/^[ ]*if test "x`echo /s,sed 's@/,sed -e 's@^[A-z]:@@' -e 's@/,
diff --git a/gdb/config/djgpp/djcheck.sh b/gdb/config/djgpp/djcheck.sh
new file mode 100644
index 00000000000..36f2e019080
--- /dev/null
+++ b/gdb/config/djgpp/djcheck.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# A shell script to run the test suite on the DJGPP version of GDB.
+
+ORIGDIR=`pwd`
+GDB=${ORIGDIR}/../gdb.exe
+SUBDIRS=`find $ORIGDIR -type d ! -ipath $ORIGDIR`
+
+for d in $SUBDIRS
+do
+ cd $d
+ echo "Running tests in $d..."
+ for f in *.out
+ do
+ test -f $f || break
+ base=`basename $f .out`
+ if test "${base}" = "dbx" ; then
+ options=-dbx
+ else
+ options=
+ fi
+ $GDB ${options} < ${base}.in 2>&1 \
+ | sed -e '/GNU gdb /s/ [.0-9][.0-9]*//' \
+ -e '/^Copyright/s/[12][0-9][0-9][0-9]/XYZZY/g' \
+ -e '/Starting program: /s|[A-z]:/.*/||' \
+ -e '/main (/s/=0x[0-9a-f][0-9a-f]*/=XYZ/g' \
+ > ${base}.tst
+ if diff --binary -u ${base}.out ${base}.tst ; then
+ rm -f ${base}.tst
+ fi
+ done
+done
+
diff --git a/gdb/config/djgpp/djconfig.sh b/gdb/config/djgpp/djconfig.sh
new file mode 100644
index 00000000000..23be0d5fdad
--- /dev/null
+++ b/gdb/config/djgpp/djconfig.sh
@@ -0,0 +1,163 @@
+#!/bin/sh
+#
+# This shell script is a wrapper to the main configure script when
+# configuring GDB for DJGPP. 99% of it can also be used when
+# configuring other GNU programs for DJGPP.
+#
+#=====================================================================
+# Copyright 1997, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+#
+# Originally written by Robert Hoehne, revised by Eli Zaretskii.
+# 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. */
+#=====================================================================
+#
+# Call this script like the main configure script with one exception. If you
+# want to pass parameters to configure, you have to pass as the first
+# argument the srcdir, even when it is `.' !!!!!
+#
+# First, undo any CDPATH settings; they will get in our way when we
+# chdir to directories.
+unset CDPATH
+
+# Where are the sources? If you are used to having the sources
+# in a separate directory and the objects in another, then set
+# here the full path to the source directory and run this script
+# in the directory where you want to build gdb!!
+# You might give the source directory on commandline, but use
+# then only forward slashes (/) in the directories. It should be
+# an absolute path.
+
+if [ x$1 = x ]; then
+ srcdir=`pwd`
+else
+ srcdir=`cd $1 && pwd`
+ shift
+fi
+
+# Make sure they don't have some file names mangled by untarring.
+echo -n "Checking the unpacked distribution..."
+if ( ! test -f ${srcdir}/intl/po2tblsed.in || \
+ ! test -d ${srcdir}/gdb/testsuite/gdb.cxx || \
+ ! test -f ${srcdir}/readline/config.h-in ) ; then
+ echo " FAILED."
+ echo ""
+ echo "You MUST unpack the sources with the DJTAR command, like this:"
+ echo ""
+ echo " djtar -x -n fnchange.lst gdb-X.YZ.tar.gz"
+ echo ""
+ echo "where X.YZ is the GDB version, and fnchange.lst can be found"
+ echo "in the gdb/config/djgpp/ directory in the GDB distribution."
+ echo "configure FAILED!"
+ exit 1
+else
+ echo " ok."
+fi
+
+# Where is the directory with DJGPP-specific scripts?
+DJGPPDIR=${srcdir}/gdb/config/djgpp
+
+echo "Editing configure scripts for DJGPP..."
+TMPFILE="${TMPDIR-.}/cfg.tmp"
+
+# We need to skip the build directory if it is a subdirectory of $srcdir,
+# otherwise we will have an infinite recursion on our hands...
+if test "`pwd`" == "${srcdir}" ; then
+ SKIPDIR=""
+ SKIPFILES=""
+else
+ SKIPDIR=`pwd | sed -e "s|${srcdir}|.|"`
+ SKIPFILES="${SKIPDIR}/*"
+fi
+
+# We use explicit /dev/env/DJDIR/bin/find to avoid catching
+# an incompatible DOS/Windows version that might be on their PATH.
+for fix_dir in \
+ `cd $srcdir && /dev/env/DJDIR/bin/find . -type d ! -ipath "${SKIPDIR}" ! -ipath "${SKIPFILES}"`
+do
+ if test ! -f ${fix_dir}/configure.orig ; then
+ if test -f ${srcdir}/${fix_dir}/configure ; then
+ mkdir -p ${fix_dir}
+ cp -p ${srcdir}/${fix_dir}/configure ${fix_dir}/configure.orig
+ fi
+ fi
+ if test -f ${fix_dir}/configure.orig ; then
+ sed -f ${DJGPPDIR}/config.sed ${fix_dir}/configure.orig > $TMPFILE
+ update $TMPFILE ${fix_dir}/configure
+ touch ./${fix_dir}/configure -r ${fix_dir}/configure.orig
+ rm -f $TMPFILE
+ fi
+ if test -f ${fix_dir}/INSTALL ; then
+ mv ${fix_dir}/INSTALL ${fix_dir}/INSTALL.txt
+ fi
+done
+
+# Now set the config shell. It is really needed, that the shell
+# points to a shell with full path and also it must conatain the
+# .exe suffix. I assume here, that bash is installed. If not,
+# install it. Additionally, the pathname must not contain a
+# drive letter, so use the /dev/x/foo format supported by versions
+# of Bash 2.03 and later, and by all DJGPP programs compiled with
+# v2.03 (or later) library.
+export CONFIG_SHELL=/dev/env/DJDIR/bin/sh.exe
+
+# force to have the ltmain.sh script to be in DOS text format,
+# otherwise the resulting ltconfig script will have mixed
+# (UNIX/DOS) format and is unusable with Bash ports before v2.03.
+utod $srcdir/ltmain.sh
+
+# Give the configure script some hints:
+export LD=ld
+export NM=nm
+export CC=gcc
+export CFLAGS="-O2 -g"
+export RANLIB=ranlib
+export DEFAULT_YACC="bison -y"
+export YACC="bison -y"
+export DEFAULT_LEX=flex
+# Define explicitly the .exe extension because on W95 with LFN=y
+# the check might fail
+export am_cv_exeext=.exe
+# ltconfig wants to compute the maximum command-line length, but
+# Bash 2.04 doesn't like that (it doesn't have any limit ;-), and
+# reboots the system. We know our limit in advance, so we don't
+# need all that crap. Assuming that the environment size is less
+# than 4KB, we can afford 12KB of command-line arguments.
+export lt_cv_sys_max_cmd_len=12288
+
+# The configure script needs to see the `install-sh' script, otherwise
+# it decides the source installation is broken. But "make install" will
+# fail on 8+3 filesystems if it finds a file `install-', since there
+# are numerous "install-foo" targets in Makefile's. So we rename the
+# offending file after the configure step is done.
+if test ! -f ${srcdir}/install-sh ; then
+ if test -f ${srcdir}/install-.sh ; then
+ mv ${srcdir}/install-.sh ${srcdir}/install-sh
+ fi
+fi
+
+# Now run the configure script while disabling some things like the NLS
+# support, which is nearly impossible to be supported in the current way,
+# since it relies on file names which will never work on DOS.
+echo "Running the configure script..."
+$srcdir/configure --srcdir="$srcdir" --prefix='${DJDIR}' \
+ --disable-shared --disable-nls --verbose --enable-build-warnings=\
+-Wimplicit,-Wcomment,-Wformat,-Wparentheses,-Wpointer-arith $*
+
+if test -f ${srcdir}/install- ; then
+ mv ${srcdir}/install- ${srcdir}/install-.sh
+fi
diff --git a/gdb/config/djgpp/fnchange.lst b/gdb/config/djgpp/fnchange.lst
new file mode 100644
index 00000000000..e5368446db5
--- /dev/null
+++ b/gdb/config/djgpp/fnchange.lst
@@ -0,0 +1,446 @@
+@V@/bfd/ChangeLog-0001 @V@/bfd/ChangeLog.0001
+@V@/bfd/ChangeLog-9193 @V@/bfd/ChangeLog.9193
+@V@/bfd/ChangeLog-9495 @V@/bfd/ChangeLog.9495
+@V@/bfd/ChangeLog-9697 @V@/bfd/ChangeLog.9697
+@V@/bfd/ChangeLog-9899 @V@/bfd/ChangeLog.9899
+@V@/bfd/coff-tic54x.c @V@/bfd/coff-tc54x.c
+@V@/bfd/coff-tic80.c @V@/bfd/coff-tc80.c
+@V@/bfd/cpu-ia64-opc.c @V@/bfd/cpuia64-opc.c
+@V@/bfd/cpu-m68hc11.c @V@/bfd/cm68hc11.c
+@V@/bfd/cpu-m68hc12.c @V@/bfd/cm68hc12.c
+@V@/bfd/efi-app-ia32.c @V@/bfd/efi-ia32-app.c
+@V@/bfd/efi-app-ia64.c @V@/bfd/efi-ia64-app.c
+@V@/bfd/elf32-i370.c @V@/bfd/elf32-i7.c
+@V@/bfd/elf32-m68hc11.c @V@/bfd/em68hc11.c
+@V@/bfd/elf32-m68hc12.c @V@/bfd/em68hc12.c
+@V@/bfd/elf32-m68k.c @V@/bfd/em68k.c
+@V@/bfd/elf32-sh-lin.c @V@/bfd/elf32shlin.c
+@V@/bfd/elf32-sh-nbsd.c @V@/bfd/elf32shnb.c
+@V@/bfd/elf32-sh64.c @V@/bfd/elf32sh64.c
+@V@/dejagnu/baseboards/mn10200-cygmon.exp @V@/dejagnu/baseboards/mn10200cygmon.exp
+@V@/dejagnu/baseboards/mn10200-sim.exp @V@/dejagnu/baseboards/mn10200sim.exp
+@V@/dejagnu/baseboards/mn10300-cygmon.exp @V@/dejagnu/baseboards/mn10300cygmon.exp
+@V@/dejagnu/baseboards/mn10300-sim.exp @V@/dejagnu/baseboards/mn10300sim.exp
+@V@/dejagnu/baseboards/powerpc-bug1.exp @V@/dejagnu/baseboards/powerpc1-bug.exp
+@V@/dejagnu/baseboards/powerpc-sim.exp @V@/dejagnu/baseboards/powerpcsim.exp
+@V@/dejagnu/baseboards/sparclite-coff.exp @V@/dejagnu/baseboards/sl-coff.exp
+@V@/dejagnu/baseboards/sparclite-cygmon.exp @V@/dejagnu/baseboards/sl-cygmon.exp
+@V@/dejagnu/baseboards/sparclite-sim-le.exp @V@/dejagnu/baseboards/sl-sim-le.exp
+@V@/dejagnu/baseboards/sparclite-sim.exp @V@/dejagnu/baseboards/sl-sim.exp
+@V@/dejagnu/contrib/test-g++ @V@/dejagnu/contrib/test-gxx
+@V@/dejagnu/doc/.cvsignore @V@/dejagnu/doc/_cvsignore
+@V@/dejagnu/example/calc/calc.h.in @V@/dejagnu/example/calc/calc.h-in
+@V@/expect/Dbg_cf.h.in @V@/expect/Dbg_cf.h-in
+@V@/expect/example/beer.exp.out @V@/expect/example/beer_exp.out
+@V@/expect/example/chesslib++.c @V@/expect/example/chesslibxx.c
+@V@/expect/example/chesslib.c @V@/expect/example/chesslb.c
+@V@/expect/example/chesslib2.c @V@/expect/example/chesslb2.c
+@V@/expect/example/chesslibxx.c @V@/expect/example/chesslbxx.c
+@V@/expect/exp_main_sub.c @V@/expect/exp_m_sub.c
+@V@/expect/exp_main_tk.c @V@/expect/exp_m_tk.c
+@V@/expect/expect_cf.h.in @V@/expect/expect_cf.h-in
+@V@/gdb/ChangeLog-1990 @V@/gdb/ChangeLog.90
+@V@/gdb/ChangeLog-1991 @V@/gdb/ChangeLog.91
+@V@/gdb/ChangeLog-1992 @V@/gdb/ChangeLog.92
+@V@/gdb/ChangeLog-1993 @V@/gdb/ChangeLog.93
+@V@/gdb/ChangeLog-1994 @V@/gdb/ChangeLog.94
+@V@/gdb/ChangeLog-1995 @V@/gdb/ChangeLog.95
+@V@/gdb/ChangeLog-1996 @V@/gdb/ChangeLog.96
+@V@/gdb/ChangeLog-1997 @V@/gdb/ChangeLog.97
+@V@/gdb/ChangeLog-1998 @V@/gdb/ChangeLog.98
+@V@/gdb/ChangeLog-1999 @V@/gdb/ChangeLog.99
+@V@/gdb/ChangeLog-2000 @V@/gdb/ChangeLog.000
+@V@/gdb/ChangeLog-2001 @V@/gdb/ChangeLog.001
+@V@/gdb/ChangeLog-3.x @V@/gdb/ChangeLog.3-x
+@V@/gdb/alphabsd-nat.c @V@/gdb/alphb-nat.c
+@V@/gdb/alphabsd-tdep.c @V@/gdb/alphb-tdep.c
+@V@/gdb/alphanbsd-nat.c @V@/gdb/alphnb-nat.c
+@V@/gdb/alphanbsd-tdep.c @V@/gdb/alphnb-tdep.c
+@V@/gdb/arm-linux-nat.c @V@/gdb/armlin-nat.c
+@V@/gdb/arm-linux-tdep.c @V@/gdb/armlin-tdep.c
+@V@/gdb/armnbsd-nat.c @V@/gdb/armnbd-nat.c
+@V@/gdb/armnbsd-tdep.c @V@/gdb/armnbd-tdep.c
+@V@/gdb/c-exp.tab.c @V@/gdb/c-exp_tab.c
+@V@/gdb/config/alpha/alpha-osf1.mh @V@/gdb/config/alpha/alphosf1.mh
+@V@/gdb/config/alpha/alpha-osf2.mh @V@/gdb/config/alpha/alphosf2.mh
+@V@/gdb/config/alpha/alpha-osf3.mh @V@/gdb/config/alpha/alphosf3.mh
+@V@/gdb/config/alpha/tm-alphalinux.h @V@/gdb/config/alpha/tm-alplinux.h
+@V@/gdb/config/alpha/xm-alphalinux.h @V@/gdb/config/alpha/xm-alplinux.h
+@V@/gdb/config/i386/nm-i386sco4.h @V@/gdb/config/i386/nm-sco4.h
+@V@/gdb/config/i386/nm-i386sco5.h @V@/gdb/config/i386/nm-sco5.h
+@V@/gdb/config/i386/nm-i386sol2.h @V@/gdb/config/i386/nm-sol2.h
+@V@/gdb/config/i386/nm-i386v4.h @V@/gdb/config/i386/nm-v4.h
+@V@/gdb/config/i386/nm-i386v42mp.h @V@/gdb/config/i386/nm-v42mp.h
+@V@/gdb/config/i386/tm-i386mk.h @V@/gdb/config/i386/tm-mk.h
+@V@/gdb/config/i386/tm-i386sol2.h @V@/gdb/config/i386/tm-sol2.h
+@V@/gdb/config/i386/tm-i386v4.h @V@/gdb/config/i386/tm-v4.h
+@V@/gdb/config/i386/tm-i386v42mp.h @V@/gdb/config/i386/tm-v42mp.h
+@V@/gdb/config/i386/xm-i386mach.h @V@/gdb/config/i386/xm-mach.h
+@V@/gdb/config/i386/xm-i386mk.h @V@/gdb/config/i386/xm-mk.h
+@V@/gdb/config/i386/xm-i386v32.h @V@/gdb/config/i386/xm-v32.h
+@V@/gdb/config/i386/xm-i386v4.h @V@/gdb/config/i386/xm-v4.h
+@V@/gdb/config/m68k/apollo68v.mh @V@/gdb/config/m68k/apollo-v.mh
+@V@/gdb/config/m68k/nm-apollo68v.h @V@/gdb/config/m68k/nm-apolv.h
+@V@/gdb/config/m68k/nm-hp300hpux.h @V@/gdb/config/m68k/nm-300ux.h
+@V@/gdb/config/m68k/tm-hp300hpux.h @V@/gdb/config/m68k/tm-300ux.h
+@V@/gdb/config/m68k/xm-apollo68v.h @V@/gdb/config/m68k/xm-apolv.h
+@V@/gdb/config/m68k/xm-hp300hpux.h @V@/gdb/config/m68k/xm-300ux.h
+@V@/gdb/config/m88k/tm-delta88v4.h @V@/gdb/config/m88k/tm-d88v4.h
+@V@/gdb/config/m88k/xm-delta88v4.h @V@/gdb/config/m88k/xm-d88v4.h
+@V@/gdb/config/mips/tm-bigmips64.h @V@/gdb/config/mips/tm-bigm64.h
+@V@/gdb/config/mips/tm-embed64.h @V@/gdb/config/mips/tm-emb64.h
+@V@/gdb/config/mips/tm-embedl.h @V@/gdb/config/mips/tm-embdl.h
+@V@/gdb/config/mips/tm-embedl64.h @V@/gdb/config/mips/tm-embl64.h
+@V@/gdb/config/mips/tm-vr4300el.h @V@/gdb/config/mips/tm-v43el.h
+@V@/gdb/config/mips/tm-vr4xxxel.h @V@/gdb/config/mips/tm-v4xel.h
+@V@/gdb/config/mips/tm-vr5000el.h @V@/gdb/config/mips/tm-vr5kel.h
+@V@/gdb/config/pa/nm-hppah11.h @V@/gdb/config/pa/nm-hppa11.h
+@V@/gdb/config/powerpc/tm-ppcle-sim.h @V@/gdb/config/powerpc/tm-ppcl-sim.h
+@V@/gdb/config/rs6000/nm-rs6000ly.h @V@/gdb/config/rs6000/nm-rs6kly.h
+@V@/gdb/config/rs6000/tm-rs6000.h @V@/gdb/config/rs6000/tm-rs6k.h
+@V@/gdb/config/rs6000/tm-rs6000ly.h @V@/gdb/config/rs6000/tm-rs6kly.h
+@V@/gdb/config/sparc/tm-sparclet.h @V@/gdb/config/sparc/tm-splet.h
+@V@/gdb/config/sparc/tm-sparclite.h @V@/gdb/config/sparc/tm-splite.h
+@V@/gdb/config/sparc/tm-sparclynx.h @V@/gdb/config/sparc/tm-splynx.h
+@V@/gdb/config/vax/xm-vaxult2.h @V@/gdb/config/vax/xm-vaxut2.h
+@V@/gdb/f-exp.tab.c @V@/gdb/f-exp_tab.c
+@V@/gdb/gdbtk/generic/ChangeLog-1997 @V@/gdb/gdbtk/generic/ChangeLog.97
+@V@/gdb/gdbtk/generic/ChangeLog-1998 @V@/gdb/gdbtk/generic/ChangeLog.98
+@V@/gdb/gdbtk/generic/ChangeLog-1999 @V@/gdb/gdbtk/generic/ChangeLog.99
+@V@/gdb/gdbtk/generic/ChangeLog-2000 @V@/gdb/gdbtk/generic/ChangeLog.000
+@V@/gdb/gdbtk/generic/ChangeLog-2001 @V@/gdb/gdbtk/generic/ChangeLog.001
+@V@/gdb/gdbtk/generic/gdbtk-varobj.c @V@/gdb/gdbtk/generic/gdbtk-vobj.c
+@V@/gdb/gdbtk/library/ChangeLog-1997 @V@/gdb/gdbtk/library/ChangeLog.97
+@V@/gdb/gdbtk/library/ChangeLog-1998 @V@/gdb/gdbtk/library/ChangeLog.98
+@V@/gdb/gdbtk/library/ChangeLog-1999 @V@/gdb/gdbtk/library/ChangeLog.99
+@V@/gdb/gdbtk/library/ChangeLog-2000 @V@/gdb/gdbtk/library/ChangeLog.000
+@V@/gdb/gdbtk/library/ChangeLog-2001 @V@/gdb/gdbtk/library/ChangeLog.001
+@V@/gdb/i386-linux-tdep.c @V@/gdb/i386linux-tdep.c
+@V@/gdb/i386bsd-nat.c @V@/gdb/i3bsd-nat.c
+@V@/gdb/i386bsd-tdep.c @V@/gdb/i3bsd-tdep.c
+@V@/gdb/i386nbsd-nat.c @V@/gdb/i3nbsd-nat.c
+@V@/gdb/i386nbsd-tdep.c @V@/gdb/i3nbsd-tdep.c
+@V@/gdb/ia64-aix-nat.c @V@/gdb/ia64aix-nat.c
+@V@/gdb/ia64-linux-nat.c @V@/gdb/ia64linux-nat.c
+@V@/gdb/jv-exp.tab.c @V@/gdb/jv-exp_tab.c
+@V@/gdb/m2-exp.tab.c @V@/gdb/m2-exp_tab.c
+@V@/gdb/m68knbsd-nat.c @V@/gdb/m6nbsd-nat.c
+@V@/gdb/m68knbsd-tdep.c @V@/gdb/m6nbsd-tdep.c
+@V@/gdb/mips-linux-nat.c @V@/gdb/mipslnxnat.c
+@V@/gdb/mips-linux-tdep.c @V@/gdb/mipslnxtdep.c
+@V@/gdb/mipsnbsd-nat.c @V@/gdb/mipsnbnat.c
+@V@/gdb/mipsnbsd-tdep.c @V@/gdb/mipsnbtdep.c
+@V@/gdb/nindy-share/b.out.h @V@/gdb/nindy-share/b_out.h
+@V@/gdb/osf-share/cma_stack_int.h @V@/gdb/osf-share/cma_stkint.h
+@V@/gdb/p-exp.tab.c @V@/gdb/p-exp_tab.c
+@V@/gdb/ppc-linux-tdep.c @V@/gdb/ppc-linx-tdep.c
+@V@/gdb/regformats/reg-i386-linux.dat @V@/gdb/regformats/r-i386-lnx.dat
+@V@/gdb/regformats/reg-s390x.dat @V@/gdb/regformats/r-s390x.dat
+@V@/gdb/remote-adapt.c @V@/gdb/rmt-adapt.c
+@V@/gdb/remote-array.c @V@/gdb/rmt-array.c
+@V@/gdb/remote-e7000.c @V@/gdb/rmt-e7000.c
+@V@/gdb/remote-eb.c @V@/gdb/rmt-eb.c
+@V@/gdb/remote-es.c @V@/gdb/rmt-es.c
+@V@/gdb/remote-est.c @V@/gdb/rmt-est.c
+@V@/gdb/remote-mips.c @V@/gdb/emt-mips.c
+@V@/gdb/remote-mm.c @V@/gdb/emt-mm.c
+@V@/gdb/remote-nindy.c @V@/gdb/rmt-nindy.c
+@V@/gdb/remote-nrom.c @V@/gdb/rmt-nrom.c
+@V@/gdb/remote-rdi.c @V@/gdb/rmt-rdi.c
+@V@/gdb/remote-rdp.c @V@/gdb/rmt-rdp.c
+@V@/gdb/remote-sds.c @V@/gdb/rmt-sds.c
+@V@/gdb/remote-sim.c @V@/gdb/rmt-sim.c
+@V@/gdb/remote-st.c @V@/gdb/rmt-st.c
+@V@/gdb/remote-udi.c @V@/gdb/rmt-udi.c
+@V@/gdb/remote-vx.c @V@/gdb/rmt-vx.c
+@V@/gdb/remote-vx29k.c @V@/gdb/rmt-vx29k.c
+@V@/gdb/remote-vx68.c @V@/gdb/rmt-vx68.c
+@V@/gdb/remote-vx960.c @V@/gdb/rmt-vx960.c
+@V@/gdb/remote-vxmips.c @V@/gdb/rmt-vxmips.c
+@V@/gdb/remote-vxsparc.c @V@/gdb/rmt-vxsparc.c
+@V@/gdb/sparclet-rom.c @V@/gdb/splet-rom.c
+@V@/gdb/sparclet-stub.c @V@/gdb/splet-stub.c
+@V@/gdb/testsuite/.gdbinit @V@/gdb/testsuite/gdb.ini
+@V@/gdb/testsuite/gdb.base/coremaker2.c @V@/gdb/testsuite/gdb.base/core2maker.c
+@V@/gdb/testsuite/gdb.c++ @V@/gdb/testsuite/gdb.cxx
+@V@/gdb/testsuite/gdb.c++/Makefile.in @V@/gdb/testsuite/gdb.cxx/Makefile.in
+@V@/gdb/testsuite/gdb.c++/ambiguous.cc @V@/gdb/testsuite/gdb.cxx/ambiguous.cc
+@V@/gdb/testsuite/gdb.c++/ambiguous.exp @V@/gdb/testsuite/gdb.cxx/ambiguous.exp
+@V@/gdb/testsuite/gdb.c++/annota2.cc @V@/gdb/testsuite/gdb.cxx/annota2.cc
+@V@/gdb/testsuite/gdb.c++/annota2.exp @V@/gdb/testsuite/gdb.cxx/annota2.exp
+@V@/gdb/testsuite/gdb.c++/anon-union.cc @V@/gdb/testsuite/gdb.cxx/anon-union.cc
+@V@/gdb/testsuite/gdb.c++/anon-union.exp @V@/gdb/testsuite/gdb.cxx/anon-union.exp
+@V@/gdb/testsuite/gdb.c++/classes.exp @V@/gdb/testsuite/gdb.cxx/classes.exp
+@V@/gdb/testsuite/gdb.c++/configure @V@/gdb/testsuite/gdb.cxx/configure
+@V@/gdb/testsuite/gdb.c++/configure.in @V@/gdb/testsuite/gdb.cxx/configure.in
+@V@/gdb/testsuite/gdb.c++/cplusfuncs.cc @V@/gdb/testsuite/gdb.cxx/cplusfuncs.cc
+@V@/gdb/testsuite/gdb.c++/cplusfuncs.exp @V@/gdb/testsuite/gdb.cxx/cplusfuncs.exp
+@V@/gdb/testsuite/gdb.c++/ctti.exp @V@/gdb/testsuite/gdb.cxx/ctti.exp
+@V@/gdb/testsuite/gdb.c++/cttiadd.cc @V@/gdb/testsuite/gdb.cxx/cttiadd.cc
+@V@/gdb/testsuite/gdb.c++/cttiadd1.cc @V@/gdb/testsuite/gdb.cxx/cttiadd1.cc
+@V@/gdb/testsuite/gdb.c++/cttiadd2.cc @V@/gdb/testsuite/gdb.cxx/cttiadd2.cc
+@V@/gdb/testsuite/gdb.c++/cttiadd3.cc @V@/gdb/testsuite/gdb.cxx/cttiadd3.cc
+@V@/gdb/testsuite/gdb.c++/demangle.exp @V@/gdb/testsuite/gdb.cxx/demangle.exp
+@V@/gdb/testsuite/gdb.c++/derivation.cc @V@/gdb/testsuite/gdb.cxx/derivation.cc
+@V@/gdb/testsuite/gdb.c++/derivation.exp @V@/gdb/testsuite/gdb.cxx/derivation.exp
+@V@/gdb/testsuite/gdb.c++/inherit.exp @V@/gdb/testsuite/gdb.cxx/inherit.exp
+@V@/gdb/testsuite/gdb.c++/local.cc @V@/gdb/testsuite/gdb.cxx/local.cc
+@V@/gdb/testsuite/gdb.c++/local.exp @V@/gdb/testsuite/gdb.cxx/local.exp
+@V@/gdb/testsuite/gdb.c++/member-ptr.cc @V@/gdb/testsuite/gdb.cxx/member-ptr.cc
+@V@/gdb/testsuite/gdb.c++/member-ptr.exp @V@/gdb/testsuite/gdb.cxx/member-ptr.exp
+@V@/gdb/testsuite/gdb.c++/method.cc @V@/gdb/testsuite/gdb.cxx/method.cc
+@V@/gdb/testsuite/gdb.c++/method.exp @V@/gdb/testsuite/gdb.cxx/method.exp
+@V@/gdb/testsuite/gdb.c++/misc.cc @V@/gdb/testsuite/gdb.cxx/misc.cc
+@V@/gdb/testsuite/gdb.c++/misc.exp @V@/gdb/testsuite/gdb.cxx/misc.exp
+@V@/gdb/testsuite/gdb.c++/namespace.cc @V@/gdb/testsuite/gdb.cxx/namespace.cc
+@V@/gdb/testsuite/gdb.c++/namespace.exp @V@/gdb/testsuite/gdb.cxx/namespace.exp
+@V@/gdb/testsuite/gdb.c++/overload.cc @V@/gdb/testsuite/gdb.cxx/overload.cc
+@V@/gdb/testsuite/gdb.c++/overload.exp @V@/gdb/testsuite/gdb.cxx/overload.exp
+@V@/gdb/testsuite/gdb.c++/ovldbreak.cc @V@/gdb/testsuite/gdb.cxx/ovldbreak.cc
+@V@/gdb/testsuite/gdb.c++/ovldbreak.exp @V@/gdb/testsuite/gdb.cxx/ovldbreak.exp
+@V@/gdb/testsuite/gdb.c++/ref-types.cc @V@/gdb/testsuite/gdb.cxx/ref-types.cc
+@V@/gdb/testsuite/gdb.c++/ref-types.exp @V@/gdb/testsuite/gdb.cxx/ref-types.exp
+@V@/gdb/testsuite/gdb.c++/templates.cc @V@/gdb/testsuite/gdb.cxx/templates.cc
+@V@/gdb/testsuite/gdb.c++/templates.exp @V@/gdb/testsuite/gdb.cxx/templates.exp
+@V@/gdb/testsuite/gdb.c++/userdef.cc @V@/gdb/testsuite/gdb.cxx/userdef.cc
+@V@/gdb/testsuite/gdb.c++/userdef.exp @V@/gdb/testsuite/gdb.cxx/userdef.exp
+@V@/gdb/testsuite/gdb.c++/virtfunc.cc @V@/gdb/testsuite/gdb.cxx/virtfunc.cc
+@V@/gdb/testsuite/gdb.c++/virtfunc.exp @V@/gdb/testsuite/gdb.cxx/virtfunc.exp
+@V@/gdb/testsuite/gdb.mi/mi-var-cmd.exp @V@/gdb/testsuite/gdb.mi/mi-varcmd.exp
+@V@/gdb/testsuite/gdb.mi/mi0-var-block.exp @V@/gdb/testsuite/gdb.mi/mi0varblock.exp
+@V@/gdb/testsuite/gdb.mi/mi0-var-child.exp @V@/gdb/testsuite/gdb.mi/mi0varchild.exp
+@V@/gdb/testsuite/gdb.mi/mi0-var-cmd.exp @V@/gdb/testsuite/gdb.mi/mi0varcmd.exp
+@V@/gdb/testsuite/gdb.mi/mi0-var-display.exp @V@/gdb/testsuite/gdb.mi/mi0vardisplay.exp
+@V@/gdb/tui/tuiSourceWin.c @V@/gdb/tui/tuiWinSource.c
+@V@/gdb/tui/tuiSourceWin.h @V@/gdb/tui/tuiWinSource.h
+@V@/gdb/x86-64-linux-tdep.c @V@/gdb/x8664-ltdep.c
+@V@/gdb/x86-64-linux-nat.c @V@/gdb/x8664-lnat.c
+@V@/intl/intlh.inst.in @V@/intl/intlh_inst.in
+@V@/intl/po2tbl.sed.in @V@/intl/po2tblsed.in
+@V@/itcl/itcl/itclConfig.sh.in @V@/itcl/itcl/itclConfig.sh-in
+@V@/itcl/itcl/unix/pkgIndex.tcl.in @V@/itcl/itcl/unix/pkgIndex.t-in
+@V@/itcl/itk/itkConfig.sh.in @V@/itcl/itk/itkConfig.sh-in
+@V@/itcl/itk/unix/pkgIndex.tcl.in @V@/itcl/itk/unix/pkgIndex.t-in
+@V@/itcl/iwidgets3.0.0 @V@/itcl/iwidgets3.0-0
+@V@/itcl/iwidgets3.0.0/demos/extfileselectionbox @V@/itcl/iwidgets3.0-0/demos/efselbox
+@V@/itcl/iwidgets3.0.0/demos/extfileselectiondialog @V@/itcl/iwidgets3.0-0/demos/efseldialog
+@V@/itcl/iwidgets3.0.0/demos/fileselectionbox @V@/itcl/iwidgets3.0-0/demos/fselectbox
+@V@/itcl/iwidgets3.0.0/demos/fileselectiondialog @V@/itcl/iwidgets3.0-0/demos/fselectdialog
+@V@/itcl/iwidgets3.0.0/demos/html/buttonbox.n.html @V@/itcl/iwidgets3.0-0/demos/html/buttonbox.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/canvasprintbox.n.html @V@/itcl/iwidgets3.0-0/demos/html/cprintbox.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/canvasprintdialog.n.html @V@/itcl/iwidgets3.0-0/demos/html/cprintdialog.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/combobox.n.html @V@/itcl/iwidgets3.0-0/demos/html/combobox.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/dialog.n.html @V@/itcl/iwidgets3.0-0/demos/html/dialog.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/dialogshell.n.html @V@/itcl/iwidgets3.0-0/demos/html/dialogshell.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/entryfield.n.html @V@/itcl/iwidgets3.0-0/demos/html/entryfield.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/feedback.n.html @V@/itcl/iwidgets3.0-0/demos/html/feedback.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/fileselectionbox.n.html @V@/itcl/iwidgets3.0-0/demos/html/fselectbox.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/fileselectiondialog.n.html @V@/itcl/iwidgets3.0-0/demos/html/fselectdialog.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/hyperhelp.n.html @V@/itcl/iwidgets3.0-0/demos/html/hyperhelp.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/iwidgets2.2.0UserCmds.html @V@/itcl/iwidgets3.0-0/demos/html/iw220UserCmds.html
+@V@/itcl/iwidgets3.0.0/demos/html/labeledwidget.n.html @V@/itcl/iwidgets3.0-0/demos/html/labeledwidget.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/menubar.n.html @V@/itcl/iwidgets3.0-0/demos/html/menubar.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/messagedialog.n.html @V@/itcl/iwidgets3.0-0/demos/html/messagedialog.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/notebook.n.html @V@/itcl/iwidgets3.0-0/demos/html/notebook.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/optionmenu.n.html @V@/itcl/iwidgets3.0-0/demos/html/optionmenu.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/panedwindow.n.html @V@/itcl/iwidgets3.0-0/demos/html/panedwindow.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/promptdialog.n.html @V@/itcl/iwidgets3.0-0/demos/html/promptdialog.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/pushbutton.n.html @V@/itcl/iwidgets3.0-0/demos/html/pushbutton.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/radiobox.n.html @V@/itcl/iwidgets3.0-0/demos/html/radiobox.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/scrolledcanvas.n.html @V@/itcl/iwidgets3.0-0/demos/html/scrolcanvas.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/scrolledframe.n.html @V@/itcl/iwidgets3.0-0/demos/html/scrolframe.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/scrolledhtml.n.html @V@/itcl/iwidgets3.0-0/demos/html/scrolhtml.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/scrolledlistbox.n.html @V@/itcl/iwidgets3.0-0/demos/html/scrollistbox.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/scrolledtext.n.html @V@/itcl/iwidgets3.0-0/demos/html/scroltext.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/selectionbox.n.html @V@/itcl/iwidgets3.0-0/demos/html/selectbox.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/selectiondialog.n.html @V@/itcl/iwidgets3.0-0/demos/html/selectdialog.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/shell.n.html @V@/itcl/iwidgets3.0-0/demos/html/shell.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/spindate.n.html @V@/itcl/iwidgets3.0-0/demos/html/spindate.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/spinint.n.html @V@/itcl/iwidgets3.0-0/demos/html/spinint.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/spinner.n.html @V@/itcl/iwidgets3.0-0/demos/html/spinner.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/spintime.n.html @V@/itcl/iwidgets3.0-0/demos/html/spintime.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/tabnotebook.n.html @V@/itcl/iwidgets3.0-0/demos/html/tabnotebook.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/tabset.n.html @V@/itcl/iwidgets3.0-0/demos/html/tabset.n-html
+@V@/itcl/iwidgets3.0.0/demos/html/toolbar.n.html @V@/itcl/iwidgets3.0-0/demos/html/toolbar.n-html
+@V@/itcl/iwidgets3.0.0/demos/scrolledcanvas @V@/itcl/iwidgets3.0-0/demos/scrolcanvas
+@V@/itcl/iwidgets3.0.0/demos/scrolledframe @V@/itcl/iwidgets3.0-0/demos/scrolframe
+@V@/itcl/iwidgets3.0.0/demos/scrolledhtml @V@/itcl/iwidgets3.0-0/demos/scrolhtml
+@V@/itcl/iwidgets3.0.0/demos/scrolledlistbox @V@/itcl/iwidgets3.0-0/demos/scroldlistbox
+@V@/itcl/iwidgets3.0.0/demos/scrolledtext @V@/itcl/iwidgets3.0-0/demos/scroltext
+@V@/itcl/iwidgets3.0.0/demos/selectionbox @V@/itcl/iwidgets3.0-0/demos/selectbox
+@V@/itcl/iwidgets3.0.0/demos/selectiondialog @V@/itcl/iwidgets3.0-0/demos/selectdialog
+@V@/itcl/iwidgets3.0.0/doc/canvasprintbox.n @V@/itcl/iwidgets3.0-0/doc/cprintbox.n
+@V@/itcl/iwidgets3.0.0/doc/canvasprintdialog.n @V@/itcl/iwidgets3.0-0/doc/cprintdialog.n
+@V@/itcl/iwidgets3.0.0/doc/extfileselectionbox.n @V@/itcl/iwidgets3.0-0/doc/efselbox.n
+@V@/itcl/iwidgets3.0.0/doc/extfileselectiondialog.n @V@/itcl/iwidgets3.0-0/doc/efseldialog.n
+@V@/itcl/iwidgets3.0.0/doc/fileselectionbox.n @V@/itcl/iwidgets3.0-0/doc/fselectbox.n
+@V@/itcl/iwidgets3.0.0/doc/fileselectiondialog.n @V@/itcl/iwidgets3.0-0/doc/fselectdialog.n
+@V@/itcl/iwidgets3.0.0/doc/scopedobject.n.backup @V@/itcl/iwidgets3.0-0/doc/scopedobject.n-backup
+@V@/itcl/iwidgets3.0.0/doc/scrolledcanvas.n @V@/itcl/iwidgets3.0-0/doc/scrolcanvas.n
+@V@/itcl/iwidgets3.0.0/doc/scrolledframe.n @V@/itcl/iwidgets3.0-0/doc/scrolframe.n
+@V@/itcl/iwidgets3.0.0/doc/scrolledhtml.n @V@/itcl/iwidgets3.0-0/doc/scrolhtml.n
+@V@/itcl/iwidgets3.0.0/doc/scrolledlistbox.n @V@/itcl/iwidgets3.0-0/doc/scrollistbox.n
+@V@/itcl/iwidgets3.0.0/doc/scrolledtext.n @V@/itcl/iwidgets3.0-0/doc/scroltext.n
+@V@/itcl/iwidgets3.0.0/doc/selectionbox.n @V@/itcl/iwidgets3.0-0/doc/selectbox.n
+@V@/itcl/iwidgets3.0.0/doc/selectiondialog.n @V@/itcl/iwidgets3.0-0/doc/selectdialog.n
+@V@/itcl/iwidgets3.0.0/generic/canvasprintbox.itk @V@/itcl/iwidgets3.0-0/generic/cprintbox.itk
+@V@/itcl/iwidgets3.0.0/generic/canvasprintdialog.itk @V@/itcl/iwidgets3.0-0/generic/cprintdialog.itk
+@V@/itcl/iwidgets3.0.0/generic/extfileselectionbox.itk @V@/itcl/iwidgets3.0-0/generic/efselbox.itk
+@V@/itcl/iwidgets3.0.0/generic/extfileselectiondialog.itk @V@/itcl/iwidgets3.0-0/generic/efseldialog.itk
+@V@/itcl/iwidgets3.0.0/generic/fileselectionbox.itk @V@/itcl/iwidgets3.0-0/generic/fselectbox.itk
+@V@/itcl/iwidgets3.0.0/generic/fileselectiondialog.itk @V@/itcl/iwidgets3.0-0/generic/fselectdialog.itk
+@V@/itcl/iwidgets3.0.0/generic/scrolledcanvas.itk @V@/itcl/iwidgets3.0-0/generic/scrolcanvas.itk
+@V@/itcl/iwidgets3.0.0/generic/scrolledframe.itk @V@/itcl/iwidgets3.0-0/generic/scrolframe.itk
+@V@/itcl/iwidgets3.0.0/generic/scrolledhtml.itk @V@/itcl/iwidgets3.0-0/generic/scrolhtml.itk
+@V@/itcl/iwidgets3.0.0/generic/scrolledlistbox.itk @V@/itcl/iwidgets3.0-0/generic/scrollistbox.itk
+@V@/itcl/iwidgets3.0.0/generic/scrolledtext.itk @V@/itcl/iwidgets3.0-0/generic/scroltext.itk
+@V@/itcl/iwidgets3.0.0/generic/scrolledwidget.itk @V@/itcl/iwidgets3.0-0/generic/scrolwidget.itk
+@V@/itcl/iwidgets3.0.0/generic/selectionbox.itk @V@/itcl/iwidgets3.0-0/generic/selectbox.itk
+@V@/itcl/iwidgets3.0.0/generic/selectiondialog.itk @V@/itcl/iwidgets3.0-0/generic/selectdialog.itk
+@V@/itcl/iwidgets3.0.0/tests/canvasprintbox.test @V@/itcl/iwidgets3.0-0/tests/cprintbox.test
+@V@/itcl/iwidgets3.0.0/tests/canvasprintdialog.test @V@/itcl/iwidgets3.0-0/tests/cprintdialog.test
+@V@/itcl/iwidgets3.0.0/tests/extfileselectionbox.test @V@/itcl/iwidgets3.0-0/tests/efselbox.test
+@V@/itcl/iwidgets3.0.0/tests/extfileselectiondialog.test @V@/itcl/iwidgets3.0-0/tests/efseldialog.test
+@V@/itcl/iwidgets3.0.0/tests/fileselectionbox.test @V@/itcl/iwidgets3.0-0/tests/fselectbox.test
+@V@/itcl/iwidgets3.0.0/tests/fileselectiondialog.test @V@/itcl/iwidgets3.0-0/tests/fselectdialog.test
+@V@/itcl/iwidgets3.0.0/tests/scrolledcanvas.test @V@/itcl/iwidgets3.0-0/tests/scrolcanvas.test
+@V@/itcl/iwidgets3.0.0/tests/scrolledframe.test @V@/itcl/iwidgets3.0-0/tests/scrolframe.test
+@V@/itcl/iwidgets3.0.0/tests/scrolledhtml.test @V@/itcl/iwidgets3.0-0/tests/scrolhtml.test
+@V@/itcl/iwidgets3.0.0/tests/scrolledlistbox.test @V@/itcl/iwidgets3.0-0/tests/scrollistbox.test
+@V@/itcl/iwidgets3.0.0/tests/scrolledtext.test @V@/itcl/iwidgets3.0-0/tests/scroltext.test
+@V@/itcl/iwidgets3.0.0/tests/selectionbox.test @V@/itcl/iwidgets3.0-0/tests/selectbox.test
+@V@/itcl/iwidgets3.0.0/tests/selectiondialog.test @V@/itcl/iwidgets3.0-0/tests/selectdialog.test
+@V@/itcl/iwidgets3.0.0/unix/iwidgets.tcl.in @V@/itcl/iwidgets3.0-0/unix/iwidgets.t-in
+@V@/itcl/iwidgets3.0.0/unix/pkgIndex.tcl.in @V@/itcl/iwidgets3.0-0/unix/pkgIndex.t-in
+@V@/libgui/config.h.in @V@/libgui/config.h-in
+@V@/libgui/src/tkTableCell.c @V@/libgui/src/tkTabCell.c
+@V@/libgui/src/tkTableCmd.c @V@/libgui/src/tkTabCmd.c
+@V@/libgui/src/tkWinPrintCanvas.c @V@/libgui/src/tkWPrtCanvas.c
+@V@/libgui/src/tkWinPrintText.c @V@/libgui/src/tkWPrtText.c
+@V@/opcodes/ChangeLog-9297 @V@/opcodes/ChangeLog.9297
+@V@/opcodes/ChangeLog-9899 @V@/opcodes/ChangeLog.9899
+@V@/opcodes/ia64-opc-a.c @V@/opcodes/ia64opca.c
+@V@/opcodes/ia64-opc-b.c @V@/opcodes/ia64opcb.c
+@V@/opcodes/ia64-opc-d.c @V@/opcodes/ia64opcd.c
+@V@/opcodes/ia64-opc-f.c @V@/opcodes/ia64opcf.c
+@V@/opcodes/ia64-opc-i.c @V@/opcodes/ia64opci.c
+@V@/opcodes/ia64-opc-m.c @V@/opcodes/ia64opcm.c
+@V@/opcodes/ia64-opc-x.c @V@/opcodes/ia64opcx.c
+@V@/opcodes/ia64-opc.c @V@/opcodes/ia64-opc.c
+@V@/opcodes/m68hc11-dis.c @V@/opcodes/m68hc11dis.c
+@V@/opcodes/m68hc11-opc.c @V@/opcodes/m68hc11opc.c
+@V@/opcodes/openris-dis.c @V@/opcodes/orisc-dis.c
+@V@/opcodes/openrisc-asm.c @V@/opcodes/orisc-asm.c
+@V@/opcodes/openrisc-desc.c @V@/opcodes/orisc-desc.c
+@V@/opcodes/openrisc-ibld.c @V@/opcodes/orisc-ibld.c
+@V@/opcodes/openrisc-opc.c @V@/opcodes/orisc-opc.c
+@V@/opcodes/openrisc-opc.h @V@/opcodes/orisc-opc.h
+@V@/readline/config.h.bot @V@/readline/config.h-bot
+@V@/readline/config.h.in @V@/readline/config.h-in
+@V@/sim/m68hc11/dv-m68hc11eepr.c @V@/sim/m68hc11/dv-eepr.c
+@V@/sim/m68hc11/dv-m68hc11sio.c @V@/sim/m68hc11/dv-sio.c
+@V@/sim/m68hc11/dv-m68hc11spi.c @V@/sim/m68hc11/dv-spi.c
+@V@/sim/m68hc11/dv-m68hc11tim.c @V@/sim/m68hc11/dv-tim.c
+@V@/sim/mips/dv-tx3904irc.c @V@/sim/mips/dv-tx3irc.c
+@V@/sim/mips/dv-tx3904sio.c @V@/sim/mips/dv-tx3sio.c
+@V@/sim/mips/dv-tx3904tmr.c @V@/sim/mips/dv-tx3tmr.c
+@V@/sim/mn10300/dv-mn103int.c @V@/sim/mn10300/dv-mn1int.c
+@V@/sim/mn10300/dv-mn103iop.c @V@/sim/mn10300/dv-mn1iop.c
+@V@/sim/mn10300/dv-mn103ser.c @V@/sim/mn10300/dv-mn1ser.c
+@V@/sim/mn10300/dv-mn103tim.c @V@/sim/mn10300/dv-mn1tim.c
+@V@/sim/ppc/.gdbinit @V@/sim/ppc/gdb.ini
+@V@/sim/ppc/corefile-n.h @V@/sim/ppc/corefle-n.h
+@V@/sim/ppc/idecode_branch.h @V@/sim/ppc/idec_branch.h
+@V@/sim/ppc/idecode_expression.h @V@/sim/ppc/idec_expression.h
+@V@/sim/ppc/idecode_fields.h @V@/sim/ppc/idec_fields.h
+@V@/sim/ppc/sim-endian-n.h @V@/sim/ppc/sim-endn.h
+@V@/sim/testsuite/d10v-elf/t-ae-ld-d.s @V@/sim/testsuite/d10v-elf/t-ld-d.s
+@V@/sim/testsuite/d10v-elf/t-ae-ld-i.s @V@/sim/testsuite/d10v-elf/t-ld-i.s
+@V@/sim/testsuite/d10v-elf/t-ae-ld-id.s @V@/sim/testsuite/d10v-elf/t-ld-id.s
+@V@/sim/testsuite/d10v-elf/t-ae-ld-im.s @V@/sim/testsuite/d10v-elf/t-ld-im.s
+@V@/sim/testsuite/d10v-elf/t-ae-ld-ip.s @V@/sim/testsuite/d10v-elf/t-ld-ip.s
+@V@/sim/testsuite/d10v-elf/t-ae-ld2w-d.s @V@/sim/testsuite/d10v-elf/t-ld2-d.s
+@V@/sim/testsuite/d10v-elf/t-ae-ld2w-i.s @V@/sim/testsuite/d10v-elf/t-ld2-i.s
+@V@/sim/testsuite/d10v-elf/t-ae-ld2w-id.s @V@/sim/testsuite/d10v-elf/t-ld2-id.s
+@V@/sim/testsuite/d10v-elf/t-ae-ld2w-im.s @V@/sim/testsuite/d10v-elf/t-ld2-im.s
+@V@/sim/testsuite/d10v-elf/t-ae-ld2w-ip.s @V@/sim/testsuite/d10v-elf/t-ld2-ip.s
+@V@/sim/testsuite/d10v-elf/t-ae-st-d.s @V@/sim/testsuite/d10v-elf/t-st-d.s
+@V@/sim/testsuite/d10v-elf/t-ae-st-i.s @V@/sim/testsuite/d10v-elf/t-st-i.s
+@V@/sim/testsuite/d10v-elf/t-ae-st-id.s @V@/sim/testsuite/d10v-elf/t-st-id.s
+@V@/sim/testsuite/d10v-elf/t-ae-st-im.s @V@/sim/testsuite/d10v-elf/t-st-im.s
+@V@/sim/testsuite/d10v-elf/t-ae-st-ip.s @V@/sim/testsuite/d10v-elf/t-st-ip.s
+@V@/sim/testsuite/d10v-elf/t-ae-st-is.s @V@/sim/testsuite/d10v-elf/t-st-is.s
+@V@/sim/testsuite/d10v-elf/t-ae-st2w-d.s @V@/sim/testsuite/d10v-elf/t-st2-d.s
+@V@/sim/testsuite/d10v-elf/t-ae-st2w-i.s @V@/sim/testsuite/d10v-elf/t-st2-i.s
+@V@/sim/testsuite/d10v-elf/t-ae-st2w-id.s @V@/sim/testsuite/d10v-elf/t-st2-id.s
+@V@/sim/testsuite/d10v-elf/t-ae-st2w-im.s @V@/sim/testsuite/d10v-elf/t-st2-im.s
+@V@/sim/testsuite/d10v-elf/t-ae-st2w-ip.s @V@/sim/testsuite/d10v-elf/t-st2-ip.s
+@V@/sim/testsuite/d10v-elf/t-ae-st2w-is.s @V@/sim/testsuite/d10v-elf/t-st2-is.s
+@V@/sim/testsuite/d30v-elf/ls-ld4bhu.S @V@/sim/testsuite/d30v-elf/ls-ld4bu.S
+@V@/tcl/cygwin/tclConfig.sh.in @V@/tcl/cygwin/tclConfig.sh-in
+@V@/tcl/doc/ExprLongObj.3 @V@/tcl/doc/ExprLObj.3
+@V@/tcl/mac/tclMacBOAAppInit.c @V@/tcl/mac/tclBOAAppInit.c
+@V@/tcl/mac/tclMacBOAMain.c @V@/tcl/mac/tclBOAMain.c
+@V@/tcl/mac/tclMacInit.c @V@/tcl/mac/tclInit.c
+@V@/tcl/mac/tclMacInterupt.c @V@/tcl/mac/tclInterupt.c
+@V@/tcl/mac/tclMacProjects.sea.hqx @V@/tcl/mac/tclMacProjects.shqx
+@V@/tcl/tests/namespace-old.test @V@/tcl/tests/namespace.otest
+@V@/tcl/unix/tclConfig.sh.in @V@/tcl/unix/tclConfig.sh-in
+@V@/tcl/unix/tclLoadAix.c @V@/tcl/unix/tclLdAix.c
+@V@/tcl/unix/tclLoadAout.c @V@/tcl/unix/tclLdAout.c
+@V@/tcl/unix/tclLoadDl.c @V@/tcl/unix/tclLdDl.c
+@V@/tcl/unix/tclLoadDld.c @V@/tcl/unix/tclLdDld.c
+@V@/tcl/unix/tclUnixFCmd.c @V@/tcl/unix/tclFCmd.c
+@V@/tcl/unix/tclUnixFile.c @V@/tcl/unix/tclFile.c
+@V@/tcl/unix/tclUnixTest.c @V@/tcl/unix/tclTest.c
+@V@/tcl/unix/tclUnixTime.c @V@/tcl/unix/tclTime.c
+@V@/tix/docs/Release-4.1.0.html @V@/tix/docs/Rel4_10.html
+@V@/tix/docs/Release-4.1.0.txt @V@/tix/docs/Rel4_10.txt
+@V@/tix/docs/Release-4.1a2.html @V@/tix/docs/Rel4_1a2.html
+@V@/tix/docs/Release-4.1a2.txt @V@/tix/docs/Rel4_1a2.txt
+@V@/tix/docs/Release-4.1a3.html @V@/tix/docs/Rel4_1a3.html
+@V@/tix/docs/Release-4.1a3.txt @V@/tix/docs/Rel4_1a3.txt
+@V@/tix/docs/Release-4.1b1.html @V@/tix/docs/Rel4_1b1.html
+@V@/tix/docs/Release-4.1b1.txt @V@/tix/docs/Rel4_1b1.txt
+@V@/tix/docs/Release-4.1b2.html @V@/tix/docs/Rel4_1b2.html
+@V@/tix/docs/Release-4.1b2.txt @V@/tix/docs/Rel4_1b2.txt
+@V@/tix/tixConfig.sh.in @V@/tix/tixConfig.sh-in
+@V@/tix/unix/tk4.2/pkgIndex.tcl.in @V@/tix/unix/tk4.2/pkgIndex.t-in
+@V@/tix/unix/tk8.0/pkgIndex.tcl.in @V@/tix/unix/tk8.0/pkgIndex.t-in
+@V@/tix/unix/tk8.0/pkgIndex.tcl.in @V@/tix/unix/tk8.0/pkgIndex.t-in
+@V@/tix/unix/tk8.1/pkgIndex.tcl.in @V@/tix/unix/tk8.1/pkgIndex.t-in
+@V@/tix/win/tkConsole41.c @V@/tix/win/tkCon41.c
+@V@/tix/win/tkConsole42.c @V@/tix/win/tkCon42.c
+@V@/tix/win/tkConsole80a1.c @V@/tix/win/tkCon80a1.c
+@V@/tix/win/tkConsole80b1.c @V@/tix/win/tkCon80b1.c
+@V@/tix/win/tkConsole81.c @V@/tix/win/tkCon81.c
+@V@/tk/doc/ConfigWidg.3 @V@/tk/doc/CfgWidg.3
+@V@/tk/doc/ConfigWind.3 @V@/tk/doc/CfgWind.3
+@V@/tk/doc/tk4.0.ps @V@/tk/doc/tk4-0.ps
+@V@/tk/library/images/pwrdLogo100.gif @V@/tk/library/images/pwLogo100.gif
+@V@/tk/library/images/pwrdLogo150.gif @V@/tk/library/images/pwLogo150.gif
+@V@/tk/library/images/pwrdLogo175.gif @V@/tk/library/images/pwLogo175.gif
+@V@/tk/library/images/pwrdLogo200.gif @V@/tk/library/images/pwLogo200.gif
+@V@/tk/library/images/pwrdLogo75.gif @V@/tk/library/images/pwLogo75.gif
+@V@/tk/mac/tkMacMenu.c @V@/tk/mac/tkMenu.c
+@V@/tk/mac/tkMacMenubutton.c @V@/tk/mac/tkMenubutton.c
+@V@/tk/mac/tkMacMenus.c @V@/tk/mac/tkMenus.c
+@V@/tk/mac/tkMacProjects.sit.hqx @V@/tk/mac/tkMacProjects.shqx
+@V@/tk/tests/option.file1 @V@/tk/tests/option1.file
+@V@/tk/tests/option.file2 @V@/tk/tests/option2.file
+@V@/tk/unix/tkConfig.sh.in @V@/tk/unix/tkConfig.sh-in
+@V@/tk/unix/tkUnixFocus.c @V@/tk/unix/tkFocus.c
+@V@/tk/unix/tkUnixFont.c @V@/tk/unix/tkFont.c
+@V@/tk/unix/tkUnixMenu.c @V@/tk/unix/tkMenu.c
+@V@/tk/unix/tkUnixMenubu.c @V@/tk/unix/tkMenubu.c
+@V@/tk/unix/tkUnixScale.c @V@/tk/unix/tkScale.c
+@V@/tk/unix/tkUnixScrlbr.c @V@/tk/unix/tkScrlbr.c
+@V@/tk/unix/tkUnixSelect.c @V@/tk/unix/tkSelect.c
+@V@/tk/unix/tkUnixSend.c @V@/tk/unix/tkSend.c
+@V@/opcodes/xstormy16-asm.c @V@/opcodes/xst16asm.c
+@V@/opcodes/xstormy16-desc.c @V@/opcodes/xst16dsc.c
+@V@/opcodes/xstormy16-desc.h @V@/opcodes/xst16dsc.h
+@V@/opcodes/xstormy16-dis.c @V@/opcodes/xst16dis.c
+@V@/opcodes/xstormy16-ibld.c @V@/opcodes/xst16ibd.c
+@V@/opcodes/xstormy16-opc.c @V@/opcodes/xst16opc.c
+@V@/opcodes/xstormy16-opc.h @V@/opcodes/xst16opc.h
diff --git a/gdb/config/fr30/fr30.mt b/gdb/config/fr30/fr30.mt
new file mode 100644
index 00000000000..fac307ea01c
--- /dev/null
+++ b/gdb/config/fr30/fr30.mt
@@ -0,0 +1,5 @@
+# Target: Fujitsu FR30 processor
+TDEPFILES= fr30-tdep.o
+TM_FILE= tm-fr30.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/fr30/libsim.a
diff --git a/gdb/config/fr30/tm-fr30.h b/gdb/config/fr30/tm-fr30.h
new file mode 100644
index 00000000000..22ddd046a8e
--- /dev/null
+++ b/gdb/config/fr30/tm-fr30.h
@@ -0,0 +1,233 @@
+/* Parameters for execution on a Fujitsu FR30 processor.
+ Copyright 1999, 2000 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 "regcache.h"
+
+#define FR30_GENREGS 16
+#define FR30_DEDICATEDREGS 8
+#define FR30_REGSIZE 4 /* bytes */
+
+#define NUM_REGS (FR30_GENREGS + FR30_DEDICATEDREGS)
+#define REGISTER_BYTES ((FR30_GENREGS + FR30_DEDICATEDREGS)*FR30_REGSIZE)
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+#define REGISTER_BYTE(N) ((N) * FR30_REGSIZE)
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer. */
+#define REGISTER_NAMES \
+{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", \
+ "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
+ "pc", "ps", "tbr", "rp", "ssp", "usp", "mdh", "mdl" }
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+#define FUNCTION_START_OFFSET 0
+
+/* Amount PC must be decremented by after a breakpoint.
+ This is often the number of bytes in BREAKPOINT
+ but not always. */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Stack grows downward. */
+
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+#define R0_REGNUM 0
+#define R1_REGNUM 1
+#define R2_REGNUM 2
+#define R3_REGNUM 3
+#define R4_REGNUM 4
+#define R5_REGNUM 5
+#define R6_REGNUM 6
+#define R7_REGNUM 7
+#define R8_REGNUM 8
+#define R9_REGNUM 9
+#define R10_REGNUM 10
+#define R11_REGNUM 11
+#define R12_REGNUM 12
+#define R13_REGNUM 13
+#define FP_REGNUM 14 /* Frame pointer */
+#define SP_REGNUM 15 /* Stack pointer */
+#define PC_REGNUM 16 /* Program counter */
+#define RP_REGNUM 19 /* Return pointer */
+
+#define FIRST_ARGREG R4_REGNUM /* first arg (or struct ret val addr) */
+#define LAST_ARGREG R7_REGNUM /* fourth (or third arg) */
+#define RETVAL_REG R4_REGNUM /* return vaue */
+
+/* Say how long (ordinary) registers are. This is a piece of bogosity
+ used in push_word and a few other places; REGISTER_RAW_SIZE is the
+ real way to know how big a register is. */
+#define REGISTER_SIZE FR30_REGSIZE
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. */
+#define REGISTER_RAW_SIZE(N) FR30_REGSIZE
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+#define MAX_REGISTER_RAW_SIZE FR30_REGSIZE
+
+/* Number of bytes of storage in the program's representation
+ for register N. */
+#define REGISTER_VIRTUAL_SIZE(N) REGISTER_RAW_SIZE(N)
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+#define MAX_REGISTER_VIRTUAL_SIZE FR30_REGSIZE
+
+extern void fr30_pop_frame (void);
+#define POP_FRAME fr30_pop_frame()
+
+#define USE_GENERIC_DUMMY_FRAMES 1
+#define CALL_DUMMY {0}
+#define CALL_DUMMY_START_OFFSET (0)
+#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
+#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
+#define FIX_CALL_DUMMY(DUMMY, START, FUNADDR, NARGS, ARGS, TYPE, GCCP)
+#define CALL_DUMMY_ADDRESS() entry_point_address ()
+#define PUSH_RETURN_ADDRESS(PC, SP) (write_register(RP_REGNUM, CALL_DUMMY_ADDRESS()), SP)
+#define PUSH_DUMMY_FRAME generic_push_dummy_frame ()
+
+/* Number of bytes at start of arglist that are not really args. */
+#define FRAME_ARGS_SKIP 0
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+#define REGISTER_VIRTUAL_TYPE(REG) builtin_type_int
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. */
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ memcpy (VALBUF, REGBUF + REGISTER_BYTE(RETVAL_REG) + \
+ (TYPE_LENGTH(TYPE) < 4 ? 4 - TYPE_LENGTH(TYPE) : 0), TYPE_LENGTH (TYPE))
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+ extract_address (REGBUF + REGISTER_BYTE (RETVAL_REG), \
+ REGISTER_RAW_SIZE (RETVAL_REG))
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+ { write_register (RETVAL_REG, (ADDR)); }
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Return number of args passed to a frame.
+ Can return -1, meaning no way to tell. */
+#define FRAME_NUM_ARGS(fi) (-1)
+
+/* Forward decls for prototypes */
+struct frame_info;
+struct frame_saved_regs;
+struct type;
+struct value;
+
+#define EXTRA_FRAME_INFO \
+ struct frame_saved_regs fsr; \
+ int framesize; \
+ int frameoffset; \
+ int framereg;
+
+extern CORE_ADDR fr30_frame_chain (struct frame_info *fi);
+#define FRAME_CHAIN(fi) fr30_frame_chain (fi)
+
+extern CORE_ADDR fr30_frame_saved_pc (struct frame_info *);
+#define FRAME_SAVED_PC(fi) (fr30_frame_saved_pc (fi))
+
+#define SAVED_PC_AFTER_CALL(fi) read_register (RP_REGNUM)
+
+extern CORE_ADDR fr30_skip_prologue (CORE_ADDR pc);
+#define SKIP_PROLOGUE(pc) (fr30_skip_prologue (pc))
+
+/* Write into appropriate registers a function return value of type
+ TYPE, given in virtual format. VALBUF is in the target byte order;
+ it's typically the VALUE_CONTENTS of some struct value, and those
+ are in the target's byte order. */
+extern void fr30_store_return_value (struct type *type, char *valbuf);
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ (fr30_store_return_value ((TYPE), (VALBUF)))
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame. */
+#define FRAME_FIND_SAVED_REGS(fi, regaddr) regaddr = fi->fsr
+
+/* Use INT #BREAKPOINT_INTNUM instruction for breakpoint */
+#define FR30_BREAKOP 0x1f /* opcode, type D instruction */
+#define BREAKPOINT_INTNUM 9 /* one of the reserved traps */
+#define BREAKPOINT {FR30_BREAKOP, BREAKPOINT_INTNUM}
+
+/* Define this for Wingdb */
+#define TARGET_FR30
+
+/* Define other aspects of the stack frame. */
+
+/* An expression that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. */
+extern int fr30_frameless_function_invocation (struct frame_info *frame);
+#define FRAMELESS_FUNCTION_INVOCATION(FI) (fr30_frameless_function_invocation (FI));
+
+extern void fr30_init_extra_frame_info (struct frame_info *fi);
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) fr30_init_extra_frame_info (fi)
+
+#define FRAME_CHAIN_VALID(FP, FI) generic_file_frame_chain_valid (FP, FI)
+
+extern CORE_ADDR
+fr30_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr);
+#define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \
+ (fr30_push_arguments (NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR))
+
+#define PC_IN_CALL_DUMMY(PC, SP, FP) generic_pc_in_call_dummy (PC, SP, FP)
+
+/* Fujitsu's ABI requires all structs to be passed using a pointer.
+ That is obviously not very efficient, so I am leaving the definitions
+ to make gdb work with GCC style struct passing, in case we decide
+ to go for better performance, rather than for compatibility with
+ Fujitsu (just change STRUCT_ALWAYS_BY_ADDR to 0) */
+
+#define STRUCT_ALWAYS_BY_ADDR 1
+
+#if(STRUCT_ALWAYS_BY_ADDR)
+#define REG_STRUCT_HAS_ADDR(gcc_p,type) 1
+#else
+/* more standard GCC (optimized) */
+#define REG_STRUCT_HAS_ADDR(gcc_p,type) \
+ ((TYPE_LENGTH(type) > 4) && (TYPE_LENGTH(type) & 0x3))
+#endif
+/* alway return struct by value by input pointer */
+#define USE_STRUCT_CONVENTION(GCC_P, TYPE) 1
+
+/* The stack should always be aligned on a four-word boundary. */
+#define STACK_ALIGN(len) (((len) + 3) & ~3)
+
+/* I think the comment about this in value_arg_coerce is wrong; this
+ should be true on any system where you can rely on the prototyping
+ information. When this is true, value_arg_coerce will promote
+ floats to doubles iff the function is not prototyped. */
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (1)
diff --git a/gdb/config/h8300/h8300.mt b/gdb/config/h8300/h8300.mt
new file mode 100644
index 00000000000..c6e25ab8ced
--- /dev/null
+++ b/gdb/config/h8300/h8300.mt
@@ -0,0 +1,6 @@
+# Target: H8300 with HMS monitor, E7000 ICE and H8 simulator
+TDEPFILES= h8300-tdep.o remote-e7000.o ser-e7kpc.o monitor.o remote-hms.o dsrec.o
+TM_FILE= tm-h8300.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/h8300/libsim.a
diff --git a/gdb/config/h8300/tm-h8300.h b/gdb/config/h8300/tm-h8300.h
new file mode 100644
index 00000000000..08c8cbd808a
--- /dev/null
+++ b/gdb/config/h8300/tm-h8300.h
@@ -0,0 +1,314 @@
+/* Parameters for execution on a H8/300 series machine.
+ Copyright 1992, 1993, 1994, 1996, 1998, 1999, 2000
+ 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 "regcache.h"
+
+/* Contributed by Steve Chamberlain sac@cygnus.com */
+
+struct frame_info;
+struct frame_saved_regs;
+struct value;
+struct type;
+
+/* 1 if debugging H8/300H application */
+
+/* NOTE: ezannoni 2000-07-18: these variables are part of sim, defined
+ in sim/h8300/compile.c. They really should not be used this
+ way. Because of this we cannot get rid of the macro
+ GDB_TARGET_IS_H8300 in remote-e7000.c */
+extern int h8300hmode;
+extern int h8300smode;
+
+/* Number of bytes in a word */
+
+#define BINWORD (h8300hmode?4:2)
+
+#define EXTRA_FRAME_INFO \
+ struct frame_saved_regs *fsr; \
+ CORE_ADDR from_pc; \
+ CORE_ADDR args_pointer;\
+ CORE_ADDR locals_pointer ;
+
+/* Zero the frame_saved_regs pointer when the frame is initialized,
+ so that FRAME_FIND_SAVED_REGS () will know to allocate and
+ initialize a frame_saved_regs struct the first time it is called.
+ Set the arg_pointer to -1, which is not valid; 0 and other values
+ indicate real, cached values. */
+
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \
+ h8300_init_extra_frame_info (fromleaf, fi)
+
+extern void h8300_init_extra_frame_info ();
+
+#undef TARGET_INT_BIT
+#define TARGET_INT_BIT 16
+#undef TARGET_LONG_BIT
+#define TARGET_LONG_BIT 32
+#undef TARGET_PTR_BIT
+#define TARGET_PTR_BIT (h8300hmode ? 32:16)
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code. */
+
+#define SKIP_PROLOGUE(ip) (h8300_skip_prologue(ip))
+extern CORE_ADDR h8300_skip_prologue ();
+
+/* Immediately after a function call, return the saved pc.
+ Can't always go through the frames for this because on some machines
+ the new frame is not set up until the new function executes
+ some instructions. */
+
+#define SAVED_PC_AFTER_CALL(frame) \
+ read_memory_unsigned_integer (read_register (SP_REGNUM), BINWORD)
+
+/* Stack grows downward. */
+
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+/*#define BREAKPOINT {0x7A, 0xFF} */
+#define BREAKPOINT {0x01, 0x80} /* Sleep */
+#define REMOTE_BREAKPOINT { 0x57, 0x30} /* trapa #3 */
+/* If your kernel resets the pc after the trap happens you may need to
+ define this before including this file. */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Say how long registers are. */
+
+#define REGISTER_SIZE 4
+
+#define NUM_REGS 14
+
+#define REGISTER_BYTES (NUM_REGS * 4)
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#define REGISTER_BYTE(N) ((N) * 4)
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. On the H8/300, all regs are 2 bytes. */
+
+#define REGISTER_RAW_SIZE(N) (h8300hmode ? 4 : 2)
+
+/* Number of bytes of storage in the program's representation
+ for register N. */
+
+#define REGISTER_VIRTUAL_SIZE(N) (h8300hmode ? 4 : 2)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#define MAX_REGISTER_RAW_SIZE 4
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 4
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+(h8300hmode ? builtin_type_unsigned_long : builtin_type_unsigned_short)
+
+/* Initializer for an array of names of registers.
+ Entries beyond the first NUM_REGS are ignored. */
+
+#define REGISTER_NAMES \
+ {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "sp", "ccr","pc","cycles","tick","inst",""}
+
+/* An array of names of registers. */
+
+extern char **h8300_register_names;
+#define REGISTER_NAME(i) h8300_register_names[i]
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define ARG0_REGNUM 0 /* first reg in which an arg may be passed */
+#define ARGLAST_REGNUM 2 /* last reg in which an arg may be passed */
+#define FP_REGNUM 6 /* Contain saddress of executing stack frame */
+#define SP_REGNUM 7 /* Contains address of top of stack */
+#define CCR_REGNUM 8 /* Contains processor status */
+#define PC_REGNUM 9 /* Contains program counter */
+#define EXR_REGNUM 11 /* Contains processor status */
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. */
+
+/* FIXME: Won't work with both h8/300's. */
+
+extern void h8300_extract_return_value (struct type *, char *, char *);
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ h8300_extract_return_value (TYPE, (char *)(REGBUF), (char *)(VALBUF))
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format. Assumes floats are passed
+ in d0/d1. */
+/* FIXME: Won't work with both h8/300's. */
+
+extern void h8300_store_return_value (struct type *, char *);
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ h8300_store_return_value(TYPE, (char *) (VALBUF))
+
+/* struct passing and returning stuff */
+#define STORE_STRUCT_RETURN(STRUCT_ADDR, SP) \
+ write_register (0, STRUCT_ADDR)
+
+#define USE_STRUCT_CONVENTION(gcc_p, type) (1)
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+ extract_address (REGBUF + REGISTER_BYTE (0), \
+ REGISTER_RAW_SIZE (0))
+
+/* Describe the pointer in each stack frame to the previous stack frame
+ (its caller). */
+
+/* FRAME_CHAIN takes a frame's nominal address
+ and produces the frame's chain-pointer.
+
+ However, if FRAME_CHAIN_VALID returns zero,
+ it means the given frame is the outermost one and has no caller. */
+
+#define FRAME_CHAIN(FRAME) h8300_frame_chain(FRAME)
+CORE_ADDR h8300_frame_chain (struct frame_info *);
+
+/* In the case of the H8/300, the frame's nominal address
+ is the address of a 2-byte word containing the calling frame's address. */
+
+/* Use the alternate method of avoiding running up off the end of
+ the frame chain or following frames back into the startup code.
+ See the comments in objfile.h */
+
+#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi)
+
+/* Define other aspects of the stack frame. */
+
+/* A macro that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. If it
+ does not, FRAMELESS is set to 1, else 0. */
+#define FRAMELESS_FUNCTION_INVOCATION(FI) \
+ (frameless_look_for_prologue (FI))
+
+/* Any function with a frame looks like this
+ SECOND ARG
+ FIRST ARG
+ RET PC
+ SAVED R2
+ SAVED R3
+ SAVED FP <-FP POINTS HERE
+ LOCALS0
+ LOCALS1 <-SP POINTS HERE
+ */
+
+#define FRAME_SAVED_PC(FRAME) h8300_frame_saved_pc(FRAME)
+extern CORE_ADDR h8300_frame_saved_pc (struct frame_info *);
+
+#define FRAME_ARGS_ADDRESS(fi) h8300_frame_args_address(fi)
+extern CORE_ADDR h8300_frame_args_address (struct frame_info *);
+
+#define FRAME_LOCALS_ADDRESS(fi) h8300_frame_locals_address(fi)
+extern CORE_ADDR h8300_frame_locals_address (struct frame_info *);
+
+/* Set VAL to the number of args passed to frame described by FI.
+ Can set VAL to -1, meaning no way to tell. */
+
+/* We can't tell how many args there are
+ now that the C compiler delays popping them. */
+
+#define FRAME_NUM_ARGS(fi) (-1)
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame. */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+ h8300_frame_find_saved_regs(frame_info, &(frame_saved_regs))
+extern void h8300_frame_find_saved_regs (struct frame_info *,
+ struct frame_saved_regs *);
+
+
+typedef unsigned short INSN_WORD;
+
+
+#define PRINT_REGISTER_HOOK(regno) h8300_print_register_hook(regno)
+extern void h8300_print_register_hook (int);
+
+#define GDB_TARGET_IS_H8300
+
+#define NUM_REALREGS (h8300smode?11:10)
+#define NOP { 0x01, 0x80} /* A sleep insn */
+
+#define BELIEVE_PCC_PROMOTION 1
+
+/*
+ * CALL_DUMMY stuff:
+ */
+
+#define USE_GENERIC_DUMMY_FRAMES 1
+#define CALL_DUMMY {0}
+#define CALL_DUMMY_LENGTH (0)
+#define CALL_DUMMY_ADDRESS() entry_point_address ()
+#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
+#define CALL_DUMMY_START_OFFSET (0)
+#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
+
+extern CORE_ADDR h8300_push_arguments (int nargs,
+ struct value **args,
+ CORE_ADDR sp,
+ unsigned char struct_return,
+ CORE_ADDR struct_addr);
+extern CORE_ADDR h8300_push_return_address (CORE_ADDR, CORE_ADDR);
+extern void h8300_pop_frame (void);
+
+#define PC_IN_CALL_DUMMY(PC, SP, FP) generic_pc_in_call_dummy (PC, SP, FP)
+#define FIX_CALL_DUMMY(DUMMY, START_SP, FUNADDR, NARGS, ARGS, TYPE, GCCP)
+#define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \
+ (h8300_push_arguments (NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR))
+/* Push an empty stack frame, to record the current PC, etc. */
+#define PUSH_DUMMY_FRAME generic_push_dummy_frame ()
+/* Discard from the stack the innermost frame, restoring all registers. */
+#define POP_FRAME h8300_pop_frame ()
+#define PUSH_RETURN_ADDRESS(PC, SP) h8300_push_return_address (PC, SP)
+
+/* override the standard get_saved_register function with
+ one that takes account of generic CALL_DUMMY frames */
+#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \
+ generic_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
diff --git a/gdb/config/h8500/h8500.mt b/gdb/config/h8500/h8500.mt
new file mode 100644
index 00000000000..35f6b4ddc86
--- /dev/null
+++ b/gdb/config/h8500/h8500.mt
@@ -0,0 +1,6 @@
+# Target: H8500 with HMS monitor and H8 simulator
+TDEPFILES= h8500-tdep.o monitor.o remote-hms.o dsrec.o
+TM_FILE= tm-h8500.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/h8500/libsim.a
diff --git a/gdb/config/h8500/tm-h8500.h b/gdb/config/h8500/tm-h8500.h
new file mode 100644
index 00000000000..fae6704c637
--- /dev/null
+++ b/gdb/config/h8500/tm-h8500.h
@@ -0,0 +1,288 @@
+/* Parameters for execution on a H8/500 series machine.
+ Copyright 1993, 1994, 1995, 1998, 1999, 2000, 2001
+ 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 "regcache.h"
+
+/* Contributed by Steve Chamberlain sac@cygnus.com */
+
+#define GDB_TARGET_IS_H8500
+
+/* Define the sizes of integers and pointers. */
+
+#define TARGET_INT_BIT 16
+
+#define TARGET_LONG_BIT 32
+
+#define TARGET_PTR_BIT (minimum_mode ? 16 : 32)
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code. */
+
+#define SKIP_PROLOGUE(ip) (h8500_skip_prologue (ip))
+extern CORE_ADDR h8500_skip_prologue (CORE_ADDR);
+
+/* Immediately after a function call, return the saved pc.
+ Can't always go through the frames for this because on some machines
+ the new frame is not set up until the new function executes
+ some instructions. */
+
+#define SAVED_PC_AFTER_CALL(frame) saved_pc_after_call()
+extern CORE_ADDR saved_pc_after_call (void);
+
+/* Stack grows downward. */
+
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+/* Illegal instruction - used by the simulator for breakpoint
+ detection */
+
+#define BREAKPOINT {0x0b}
+
+/* If your kernel resets the pc after the trap happens you may need to
+ define this before including this file. */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Say how long registers are. */
+
+#define REGISTER_TYPE unsigned long
+
+/* Say how much memory is needed to store a copy of the register set */
+
+#define REGISTER_BYTES (NUM_REGS * 4)
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#define REGISTER_BYTE(N) ((N)*4)
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. */
+
+#define REGISTER_RAW_SIZE(N) h8500_register_size(N)
+extern int h8500_register_size (int regno);
+
+#define REGISTER_SIZE 4
+
+#define REGISTER_VIRTUAL_SIZE(N) h8500_register_size(N)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#define MAX_REGISTER_RAW_SIZE 4
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 4
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+#define REGISTER_VIRTUAL_TYPE(N) h8500_register_virtual_type(N)
+extern struct type *h8500_register_virtual_type (int regno);
+
+/* Initializer for an array of names of registers.
+ Entries beyond the first NUM_REGS are ignored. */
+
+#define REGISTER_NAMES \
+ { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "pr0","pr1","pr2","pr3","pr4","pr5","pr6","pr7", \
+ "cp", "dp", "ep", "tp", "sr", "pc"}
+
+/* Register numbers of various important registers. Note that some of
+ these values are "real" register numbers, and correspond to the
+ general registers of the machine, and some are "phony" register
+ numbers which are too large to be actual register numbers as far as
+ the user is concerned but do serve to get the desired values when
+ passed to read_register. */
+
+#define R0_REGNUM 0
+#define R1_REGNUM 1
+#define R2_REGNUM 2
+#define R3_REGNUM 3
+#define R4_REGNUM 4
+#define R5_REGNUM 5
+#define R6_REGNUM 6
+#define R7_REGNUM 7
+
+#define PR0_REGNUM 8
+#define PR1_REGNUM 9
+#define PR2_REGNUM 10
+#define PR3_REGNUM 11
+#define PR4_REGNUM 12
+#define PR5_REGNUM 13
+#define PR6_REGNUM 14
+#define PR7_REGNUM 15
+
+#define SEG_C_REGNUM 16 /* Segment registers */
+#define SEG_D_REGNUM 17
+#define SEG_E_REGNUM 18
+#define SEG_T_REGNUM 19
+
+#define CCR_REGNUM 20 /* Contains processor status */
+#define PC_REGNUM 21 /* Contains program counter */
+
+#define NUM_REGS 22
+
+#define SP_REGNUM PR7_REGNUM /* Contains address of top of stack */
+#define FP_REGNUM PR6_REGNUM /* Contains address of executing stack frame */
+
+#define PTR_SIZE (minimum_mode ? 2 : 4)
+#define PTR_MASK (minimum_mode ? 0x0000ffff : 0x00ffffff)
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function. */
+
+/*#define STORE_STRUCT_RETURN(ADDR, SP) \
+ { write_register (0, (ADDR)); internal_error (__FILE__, __LINE__, "failed internal consistency check"); } */
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ memcpy (VALBUF, (char *)(REGBUF), TYPE_LENGTH(TYPE))
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format. */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(CORE_ADDR *)(REGBUF))
+
+
+/* Define other aspects of the stack frame. */
+
+/* A macro that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. If it
+ does not, FRAMELESS is set to 1, else 0. */
+
+#define FRAMELESS_FUNCTION_INVOCATION(FI) \
+ (frameless_look_for_prologue (FI))
+
+/* Any function with a frame looks like this
+ SECOND ARG
+ FIRST ARG
+ RET PC
+ SAVED R2
+ SAVED R3
+ SAVED FP <-FP POINTS HERE
+ LOCALS0
+ LOCALS1 <-SP POINTS HERE
+
+ */
+
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fci) ;
+/* (fci)->frame |= read_register(SEG_T_REGNUM) << 16; */
+
+#define FRAME_CHAIN(FRAME) h8500_frame_chain(FRAME)
+struct frame_info;
+extern CORE_ADDR h8500_frame_chain (struct frame_info *);
+
+#define FRAME_SAVED_PC(FRAME) frame_saved_pc(FRAME)
+extern CORE_ADDR frame_saved_pc (struct frame_info *frame);
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Set VAL to the number of args passed to frame described by FI.
+ Can set VAL to -1, meaning no way to tell. */
+
+/* We can't tell how many args there are
+ now that the C compiler delays popping them. */
+
+#define FRAME_NUM_ARGS(fi) (-1)
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame. */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+ frame_find_saved_regs(frame_info, &(frame_saved_regs))
+struct frame_saved_regs;
+extern void frame_find_saved_regs (struct frame_info *frame_info,
+ struct frame_saved_regs *frame_saved_regs);
+
+
+/* Discard from the stack the innermost frame, restoring all registers. */
+
+#define POP_FRAME { h8500_pop_frame (); }
+extern void h8500_pop_frame (void);
+
+#define SHORT_INT_MAX 32767
+#define SHORT_INT_MIN -32768
+
+typedef unsigned short INSN_WORD;
+
+extern CORE_ADDR h8500_addr_bits_remove (CORE_ADDR);
+#define ADDR_BITS_REMOVE(addr) h8500_addr_bits_remove (addr)
+
+#define read_memory_short(x) (read_memory_integer(x,2) & 0xffff)
+
+#define PRINT_REGISTER_HOOK(regno) print_register_hook(regno)
+extern void print_register_hook (int);
+
+extern int minimum_mode;
+
+#define CALL_DUMMY_LENGTH 10
+
+/* Fake variables to make it easy to use 24 bit register pointers */
+
+#define IS_TRAPPED_INTERNALVAR h8500_is_trapped_internalvar
+extern int h8500_is_trapped_internalvar (char *name);
+
+#define VALUE_OF_TRAPPED_INTERNALVAR h8500_value_of_trapped_internalvar
+extern struct value *h8500_value_of_trapped_internalvar ( /* struct internalvar *var */ );
+
+#define SET_TRAPPED_INTERNALVAR h8500_set_trapped_internalvar
+extern void h8500_set_trapped_internalvar ( /* struct internalvar *var, value newval, int bitpos, int bitsize, int offset */ );
+
+extern CORE_ADDR h8500_read_sp (void);
+extern void h8500_write_sp (CORE_ADDR);
+
+extern CORE_ADDR h8500_read_fp (void);
+
+extern CORE_ADDR h8500_read_pc (ptid_t);
+extern void h8500_write_pc (CORE_ADDR, ptid_t);
+
+#define TARGET_READ_SP() h8500_read_sp()
+#define TARGET_WRITE_SP(x) h8500_write_sp(x)
+
+#define TARGET_READ_PC(pid) h8500_read_pc(pid)
+#define TARGET_WRITE_PC(x,pid) h8500_write_pc(x,pid)
+
+#define TARGET_READ_FP() h8500_read_fp()
diff --git a/gdb/config/i386/cygwin.mh b/gdb/config/i386/cygwin.mh
new file mode 100644
index 00000000000..ce4656f6f51
--- /dev/null
+++ b/gdb/config/i386/cygwin.mh
@@ -0,0 +1,5 @@
+MH_CFLAGS=
+XM_FILE=xm-cygwin.h
+NATDEPFILES= i386-nat.o win32-nat.o corelow.o
+NAT_FILE=nm-cygwin.h
+XM_CLIBS=
diff --git a/gdb/config/i386/cygwin.mt b/gdb/config/i386/cygwin.mt
new file mode 100644
index 00000000000..4dfc0c23721
--- /dev/null
+++ b/gdb/config/i386/cygwin.mt
@@ -0,0 +1,6 @@
+# Target: Intel 386 run win32
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-cygwin.h
+
+
+
diff --git a/gdb/config/i386/embed.mt b/gdb/config/i386/embed.mt
new file mode 100644
index 00000000000..6925a83501d
--- /dev/null
+++ b/gdb/config/i386/embed.mt
@@ -0,0 +1,3 @@
+# Target: Embedded Intel 386
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-i386.h
diff --git a/gdb/config/i386/fbsd.mh b/gdb/config/i386/fbsd.mh
new file mode 100644
index 00000000000..08d9e7db0c8
--- /dev/null
+++ b/gdb/config/i386/fbsd.mh
@@ -0,0 +1,7 @@
+# Host: Intel 386 running FreeBSD
+
+XM_FILE= xm-i386.h
+
+NAT_FILE= nm-fbsd.h
+# NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make.
+NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o core-aout.o core-regset.o i386-nat.o i386bsd-nat.o i386fbsd-nat.o gcore.o fbsd-proc.o
diff --git a/gdb/config/i386/fbsd.mt b/gdb/config/i386/fbsd.mt
new file mode 100644
index 00000000000..7a95e00d6b9
--- /dev/null
+++ b/gdb/config/i386/fbsd.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running FreeBSD
+TDEPFILES= i386-tdep.o i387-tdep.o i386bsd-tdep.o
+TM_FILE= tm-fbsd.h
diff --git a/gdb/config/i386/gdbserve.mt b/gdb/config/i386/gdbserve.mt
new file mode 100644
index 00000000000..d8a7cbaf43d
--- /dev/null
+++ b/gdb/config/i386/gdbserve.mt
@@ -0,0 +1,3 @@
+# Target: GDBSERVE.NLM running on a i386
+TDEPFILES= i386.o
+CPU_FILE= i386
diff --git a/gdb/config/i386/go32.mh b/gdb/config/i386/go32.mh
new file mode 100644
index 00000000000..94a7a9df24c
--- /dev/null
+++ b/gdb/config/i386/go32.mh
@@ -0,0 +1,17 @@
+# Host: Intel x86 running DJGPP
+# we don't need mmalloc on DJGPP
+MH_CFLAGS= -DNO_MMALLOC
+MMALLOC=
+MMALLOC_CFLAGS=
+
+XM_FILE= xm-go32.h
+
+NAT_FILE= nm-go32.h
+NATDEPFILES= go32-nat.o i386-nat.o
+
+TERMCAP=
+HOST_IPC=
+CC= gcc
+XM_CLIBS= -ldbg
+
+
diff --git a/gdb/config/i386/go32.mt b/gdb/config/i386/go32.mt
new file mode 100644
index 00000000000..9b82c6426b4
--- /dev/null
+++ b/gdb/config/i386/go32.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running DJGPP
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-go32.h
diff --git a/gdb/config/i386/i386aix.mh b/gdb/config/i386/i386aix.mh
new file mode 100644
index 00000000000..af88729a45c
--- /dev/null
+++ b/gdb/config/i386/i386aix.mh
@@ -0,0 +1,9 @@
+# Host: IBM PS/2 (i386) running AIX PS/2
+
+XM_FILE= xm-i386aix.h
+
+NAT_FILE= nm-i386aix.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o i386aix-nat.o
+
+# Use gcc. Only coff output can be debugged
+CC=gcc
diff --git a/gdb/config/i386/i386aix.mt b/gdb/config/i386/i386aix.mt
new file mode 100644
index 00000000000..12e0e1fc79a
--- /dev/null
+++ b/gdb/config/i386/i386aix.mt
@@ -0,0 +1,7 @@
+# This port, for aix ps/2 (i386), will allow you to debug the coff
+# output generated gcc-2.3.3 + gas. It will not understand IBM's
+# proprietary debug info.
+#
+# Target: IBM PS/2 (i386) running AIX PS/2
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-i386aix.h
diff --git a/gdb/config/i386/i386aout.mt b/gdb/config/i386/i386aout.mt
new file mode 100644
index 00000000000..1c94ba5216c
--- /dev/null
+++ b/gdb/config/i386/i386aout.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 with a.out
+TDEPFILES= i386-tdep.o
+TM_FILE= tm-i386v.h
diff --git a/gdb/config/i386/i386bsd.mh b/gdb/config/i386/i386bsd.mh
new file mode 100644
index 00000000000..01457d479b8
--- /dev/null
+++ b/gdb/config/i386/i386bsd.mh
@@ -0,0 +1,6 @@
+# Host: Intel 386 running 386BSD
+
+XM_FILE= xm-i386bsd.h
+
+NAT_FILE= nm-i386bsd.h
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o core-aout.o i386b-nat.o
diff --git a/gdb/config/i386/i386bsd.mt b/gdb/config/i386/i386bsd.mt
new file mode 100644
index 00000000000..ef617311115
--- /dev/null
+++ b/gdb/config/i386/i386bsd.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running BSD
+TM_FILE= tm-i386bsd.h
+TDEPFILES= i386-tdep.o
diff --git a/gdb/config/i386/i386dgux.mh b/gdb/config/i386/i386dgux.mh
new file mode 100644
index 00000000000..fd7f56c1e46
--- /dev/null
+++ b/gdb/config/i386/i386dgux.mh
@@ -0,0 +1,10 @@
+# Host: Intel 386 running DGUX, cloned from SVR4
+
+XM_FILE= xm-i386v4.h
+# for network communication
+XM_CLIBS= -lsocket -lnsl
+
+NAT_FILE= nm-i386v4.h
+NATDEPFILES= corelow.o core-regset.o fork-child.o i386v4-nat.o \
+ solib.o solib-svr4.o solib-legacy.o \
+ procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o
diff --git a/gdb/config/i386/i386gnu.mh b/gdb/config/i386/i386gnu.mh
new file mode 100644
index 00000000000..da444a587b6
--- /dev/null
+++ b/gdb/config/i386/i386gnu.mh
@@ -0,0 +1,33 @@
+# Host: Intel 386 running the GNU Hurd
+NATDEPFILES= i386gnu-nat.o gnu-nat.o corelow.o core-regset.o \
+ fork-child.o solib.o solib-svr4.o solib-legacy.o \
+ notify_S.o process_reply_S.o msg_reply_S.o \
+ msg_U.o exc_request_U.o exc_request_S.o
+
+XM_FILE= xm-i386gnu.h
+NAT_FILE= nm-gnu.h
+MH_CFLAGS = -D_GNU_SOURCE
+
+XM_CLIBS = -lshouldbeinlibc
+
+# Use our own user stubs for the msg rpcs, so we can make them time out, in
+# case the program is fucked, or we guess the wrong signal thread.
+msg-MIGUFLAGS = -D'MSG_IMPORTS=waittime 1000;'
+
+# ick
+MIGCOM = $(MIG) -cc cat - /dev/null
+
+# Reply servers need special massaging of the code mig generates, to make
+# them work correctly for error returns in some cases.
+%_reply_S.h %_reply_S.c: %_reply.defs
+ $(CPP) $(CPPFLAGS) -DSERVERPREFIX=S_ -x c $< \
+ | $(MIGCOM) -sheader $*_reply_S.h -server $*_reply_S.raw -user /dev/null -header /dev/null \
+ && $(AWK) -f $(srcdir)/reply_mig_hack.awk < $*_reply_S.raw > $*_reply_S.c
+# Normal servers
+%_S.h %_S.c: %.defs
+ $(CPP) $(CPPFLAGS) -DSERVERPREFIX=S_ -x c $< \
+ | $(MIGCOM) -sheader $*_S.h -server $*_S.c -user /dev/null -header /dev/null
+# User rpc stubs
+%_U.h %_U.c: %.defs
+ $(CPP) $(CPPFLAGS) $($*-MIGUFLAGS) -x c $< \
+ | $(MIGCOM) -sheader /dev/null -server /dev/null -user $*_U.c -header $*_U.h
diff --git a/gdb/config/i386/i386gnu.mt b/gdb/config/i386/i386gnu.mt
new file mode 100644
index 00000000000..e08e2a25f91
--- /dev/null
+++ b/gdb/config/i386/i386gnu.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386/elf/GNU Hurd
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-i386gnu.h
diff --git a/gdb/config/i386/i386lynx.mh b/gdb/config/i386/i386lynx.mh
new file mode 100644
index 00000000000..edfb1b0752b
--- /dev/null
+++ b/gdb/config/i386/i386lynx.mh
@@ -0,0 +1,6 @@
+# Host: Intel 386 running LynxOS
+
+XM_CLIBS= -lbsd
+
+NAT_FILE= nm-i386lynx.h
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o lynx-nat.o
diff --git a/gdb/config/i386/i386lynx.mt b/gdb/config/i386/i386lynx.mt
new file mode 100644
index 00000000000..6704b43e5b9
--- /dev/null
+++ b/gdb/config/i386/i386lynx.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running LynxOS
+TDEPFILES= coff-solib.o i386-tdep.o i386ly-tdep.o
+TM_FILE= tm-i386lynx.h
diff --git a/gdb/config/i386/i386m3.mh b/gdb/config/i386/i386m3.mh
new file mode 100644
index 00000000000..41ea30c44b3
--- /dev/null
+++ b/gdb/config/i386/i386m3.mh
@@ -0,0 +1,6 @@
+# Host: Intel 386 running Mach3
+
+NATDEPFILES= i386m3-nat.o m3-nat.o fork-child.o i387-tdep.o core-aout.o
+NAT_CLIBS= -lmachid -lnetname -lmach
+XM_FILE= xm-i386m3.h
+NAT_FILE= nm-m3.h
diff --git a/gdb/config/i386/i386m3.mt b/gdb/config/i386/i386m3.mt
new file mode 100644
index 00000000000..e985ae345d9
--- /dev/null
+++ b/gdb/config/i386/i386m3.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 with a.out under Mach 3
+TDEPFILES= i386-tdep.o
+TM_FILE= tm-i386m3.h
diff --git a/gdb/config/i386/i386mach.mh b/gdb/config/i386/i386mach.mh
new file mode 100644
index 00000000000..90dbdf4096a
--- /dev/null
+++ b/gdb/config/i386/i386mach.mh
@@ -0,0 +1,9 @@
+# Host: Intel 386 running Mach
+
+# This is for mach2, maybe, or is obsolete (and seems to have only
+# host and native, not target). Once we get the mach3 stuff working,
+# I think it can go away.
+
+XM_FILE= xm-i386mach.h
+NAT_FILE= nm-i386mach.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o i386mach-nat.o
diff --git a/gdb/config/i386/i386mk.mh b/gdb/config/i386/i386mk.mh
new file mode 100644
index 00000000000..0c119becfda
--- /dev/null
+++ b/gdb/config/i386/i386mk.mh
@@ -0,0 +1,4 @@
+# Host: Intel 386 running Mach3 with OSF 1/MK
+
+NATDEPFILES= os-mach3.o i386mach3-xdep.o i387-tdep.o
+XM_FILE= xm-i386osf1mk.h
diff --git a/gdb/config/i386/i386mk.mt b/gdb/config/i386/i386mk.mt
new file mode 100644
index 00000000000..fc59442ac0d
--- /dev/null
+++ b/gdb/config/i386/i386mk.mt
@@ -0,0 +1,6 @@
+# Target: Intel 386 with a.out in osf 1/mk
+TDEPFILES= i386-tdep.o
+TM_FILE= tm-i386osf1mk.h
+
+TM_CFLAGS= -I/usr/mach3/include
+TM_CLIBS= /usr/mach3/ccs/lib/libmachid.a /usr/mach3/ccs/lib/libnetname.a /usr/mach3/ccs/lib/libmach.a
diff --git a/gdb/config/i386/i386nw.mt b/gdb/config/i386/i386nw.mt
new file mode 100644
index 00000000000..3109c42149e
--- /dev/null
+++ b/gdb/config/i386/i386nw.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running NetWare
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-i386nw.h
diff --git a/gdb/config/i386/i386os9k.mt b/gdb/config/i386/i386os9k.mt
new file mode 100644
index 00000000000..5a8794db58f
--- /dev/null
+++ b/gdb/config/i386/i386os9k.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running OS9000
+TDEPFILES= i386-tdep.o remote-os9k.o
+TM_FILE= tm-i386os9k.h
diff --git a/gdb/config/i386/i386sco.mh b/gdb/config/i386/i386sco.mh
new file mode 100644
index 00000000000..d03994486d0
--- /dev/null
+++ b/gdb/config/i386/i386sco.mh
@@ -0,0 +1,12 @@
+# Host: Intel 386 running SCO Unix (pre-SVR4)
+
+XM_FILE= xm-i386sco.h
+XM_CLIBS= -lPW
+
+NAT_FILE= nm-i386sco.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o core-aout.o i386v-nat.o
+
+#msg The SCO C compiler cannot parse symtab.h when value.h has been included.
+#msg This is a bug in the compiler; the code is valid.
+#msg Therefore, you must use GCC to compile GDB on SCO machines.
+CC=gcc -D_POSIX_SOURCE=1
diff --git a/gdb/config/i386/i386sco4.mh b/gdb/config/i386/i386sco4.mh
new file mode 100644
index 00000000000..2507e07ec28
--- /dev/null
+++ b/gdb/config/i386/i386sco4.mh
@@ -0,0 +1,11 @@
+# Host: Intel 386 running SCO Unix 3.2v4
+
+XM_FILE= xm-i386sco.h
+XM_CLIBS= -lPW
+
+NAT_FILE= nm-i386sco4.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o core-aout.o i386v-nat.o
+
+# The cc compiler mishandles const in cases like
+# struct type ** const (c_builtin_types[]) =
+MH_CFLAGS=-Dconst=
diff --git a/gdb/config/i386/i386sco5.mh b/gdb/config/i386/i386sco5.mh
new file mode 100644
index 00000000000..7b8b8274250
--- /dev/null
+++ b/gdb/config/i386/i386sco5.mh
@@ -0,0 +1,16 @@
+# Host: Intel 386 running SCO OpenServer 5
+# Much like 3.2v4, except we don't have to avoid problems with const
+
+XM_FILE= xm-i386sco.h
+
+#
+# Not all configurations of SCO OpenServer 5 come with the TCP/IP
+# runtime, but all come with the development system, so we always
+# have socket(), gethostbyname(), and friends.
+#
+XM_CLIBS= -lPW -lsocket
+
+NAT_FILE= nm-i386sco5.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corefile.o core-aout.o \
+ corelow.o i386v-nat.o solib.o solib-svr4.o solib-legacy.o
+
diff --git a/gdb/config/i386/i386sco5.mt b/gdb/config/i386/i386sco5.mt
new file mode 100644
index 00000000000..54dc68d16ca
--- /dev/null
+++ b/gdb/config/i386/i386sco5.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running SCO Open Server 5
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-i386sco5.h
diff --git a/gdb/config/i386/i386sol2.mh b/gdb/config/i386/i386sol2.mh
new file mode 100644
index 00000000000..ec93f4a75b9
--- /dev/null
+++ b/gdb/config/i386/i386sol2.mh
@@ -0,0 +1,8 @@
+# Host: Intel 386 running Solaris 2 (SVR4)
+
+XM_FILE= xm-i386v4.h
+XM_CLIBS= -lsocket -lnsl
+
+NAT_FILE= nm-i386sol2.h
+NATDEPFILES= core-regset.o fork-child.o i386v4-nat.o corelow.o \
+ procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o gcore.o
diff --git a/gdb/config/i386/i386sol2.mt b/gdb/config/i386/i386sol2.mt
new file mode 100644
index 00000000000..86d93a378b1
--- /dev/null
+++ b/gdb/config/i386/i386sol2.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running SVR4
+TDEPFILES= i386-tdep.o i387-tdep.o solib.o solib-svr4.o solib-legacy.o
+TM_FILE= tm-i386sol2.h
diff --git a/gdb/config/i386/i386v.mh b/gdb/config/i386/i386v.mh
new file mode 100644
index 00000000000..7f0ea6eae72
--- /dev/null
+++ b/gdb/config/i386/i386v.mh
@@ -0,0 +1,7 @@
+# Host: Intel 386 running System V
+
+XM_FILE= xm-i386v.h
+XM_CLIBS= -lPW
+
+NAT_FILE= nm-i386v.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o core-aout.o i386v-nat.o
diff --git a/gdb/config/i386/i386v.mt b/gdb/config/i386/i386v.mt
new file mode 100644
index 00000000000..7242d3e8f38
--- /dev/null
+++ b/gdb/config/i386/i386v.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running System V
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-i386v.h
diff --git a/gdb/config/i386/i386v32.mh b/gdb/config/i386/i386v32.mh
new file mode 100644
index 00000000000..f39437276bb
--- /dev/null
+++ b/gdb/config/i386/i386v32.mh
@@ -0,0 +1,8 @@
+# Host: Intel 386 running System V release 3.2
+
+XM_FILE= xm-i386v32.h
+XM_CLIBS= -lPW
+
+NAT_FILE= nm-i386v.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o core-aout.o i386v-nat.o
+
diff --git a/gdb/config/i386/i386v4.mh b/gdb/config/i386/i386v4.mh
new file mode 100644
index 00000000000..a3952bc6213
--- /dev/null
+++ b/gdb/config/i386/i386v4.mh
@@ -0,0 +1,10 @@
+# Host: Intel 386 running SVR4
+
+XM_FILE= xm-i386v4.h
+# for network communication
+XM_CLIBS= -lsocket -lnsl
+
+NAT_FILE= nm-i386v4.h
+NATDEPFILES= corelow.o core-regset.o fork-child.o i386v4-nat.o \
+ solib.o solib-svr4.o solib-legacy.o \
+ procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o
diff --git a/gdb/config/i386/i386v4.mt b/gdb/config/i386/i386v4.mt
new file mode 100644
index 00000000000..c22b6755985
--- /dev/null
+++ b/gdb/config/i386/i386v4.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running SVR4
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-i386v4.h
diff --git a/gdb/config/i386/i386v42mp.mh b/gdb/config/i386/i386v42mp.mh
new file mode 100644
index 00000000000..4aac5d97b84
--- /dev/null
+++ b/gdb/config/i386/i386v42mp.mh
@@ -0,0 +1,20 @@
+# Host: Intel 386 running SVR4
+
+XM_FILE= xm-i386v4.h
+# for network communication
+XM_CLIBS= -lsocket -lnsl
+
+# we don't want nm-i386v4.h since that defines LOSING_POLL which isn't
+# appropriate for i386v42mp
+NAT_FILE= nm-i386v42mp.h
+
+# NATDEPFILES must remain entirely on one line. When building a cross
+# debugger, configure will cause this line to be commented out in the
+# Makefile. Many non-GNU versions of make don't permit the use of a
+# continuation character (backslash) to extend a commented line. As a
+# consequence, make considers subsequent tab-indented lines to be
+# some sort of error.
+NATDEPFILES= corelow.o core-regset.o fork-child.o i386v4-nat.o \
+ gcore.o solib.o solib-svr4.o solib-legacy.o procfs.o proc-api.o \
+ proc-events.o proc-flags.o proc-why.o uw-thread.o
+
diff --git a/gdb/config/i386/i386v42mp.mt b/gdb/config/i386/i386v42mp.mt
new file mode 100644
index 00000000000..0b2dea8af04
--- /dev/null
+++ b/gdb/config/i386/i386v42mp.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running SVR4.2MP
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-i386v42mp.h
diff --git a/gdb/config/i386/linux.mh b/gdb/config/i386/linux.mh
new file mode 100644
index 00000000000..494ccf1a4a4
--- /dev/null
+++ b/gdb/config/i386/linux.mh
@@ -0,0 +1,12 @@
+# Host: Intel 386 running GNU/Linux.
+
+XM_FILE= xm-i386.h
+
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o linux-proc.o \
+ core-aout.o i386-nat.o i386-linux-nat.o \
+ proc-service.o thread-db.o lin-lwp.o linux-proc.o gcore.o
+
+# The dynamically loaded libthread_db needs access to symbols in the
+# gdb executable.
+LOADLIBES = -ldl -rdynamic
diff --git a/gdb/config/i386/linux.mt b/gdb/config/i386/linux.mt
new file mode 100644
index 00000000000..43bc2d26b73
--- /dev/null
+++ b/gdb/config/i386/linux.mt
@@ -0,0 +1,6 @@
+# Target: Intel 386 running GNU/Linux
+TDEPFILES= i386-tdep.o i386-linux-tdep.o i387-tdep.o \
+ solib.o solib-svr4.o solib-legacy.o
+TM_FILE= tm-linux.h
+
+GDBSERVER_DEPFILES = linux-low.o linux-i386-low.o reg-i386.o
diff --git a/gdb/config/i386/nbsdaout.mh b/gdb/config/i386/nbsdaout.mh
new file mode 100644
index 00000000000..e52f38a5b21
--- /dev/null
+++ b/gdb/config/i386/nbsdaout.mh
@@ -0,0 +1,6 @@
+# Host: Intel 386 running NetBSD
+NATDEPFILES= fork-child.o infptrace.o inftarg.o i386bsd-nat.o \
+ solib.o solib-sunos.o
+
+XM_FILE= xm-nbsd.h
+NAT_FILE= nm-nbsdaout.h
diff --git a/gdb/config/i386/nbsdaout.mt b/gdb/config/i386/nbsdaout.mt
new file mode 100644
index 00000000000..aa88957b9ea
--- /dev/null
+++ b/gdb/config/i386/nbsdaout.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running NetBSD
+TDEPFILES= i386-tdep.o i387-tdep.o i386bsd-tdep.o i386nbsd-tdep.o corelow.o
+TM_FILE= tm-nbsdaout.h
diff --git a/gdb/config/i386/nbsdelf.mh b/gdb/config/i386/nbsdelf.mh
new file mode 100644
index 00000000000..0d1c4d1badc
--- /dev/null
+++ b/gdb/config/i386/nbsdelf.mh
@@ -0,0 +1,5 @@
+# Host: Intel 386 running NetBSD
+NATDEPFILES= fork-child.o infptrace.o inftarg.o i386bsd-nat.o \
+ solib.o solib-svr4.o solib-legacy.o
+XM_FILE= xm-nbsd.h
+NAT_FILE= nm-nbsd.h
diff --git a/gdb/config/i386/nbsdelf.mt b/gdb/config/i386/nbsdelf.mt
new file mode 100644
index 00000000000..fc80608e01e
--- /dev/null
+++ b/gdb/config/i386/nbsdelf.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running NetBSD
+TDEPFILES= i386-tdep.o i387-tdep.o i386bsd-tdep.o i386nbsd-tdep.o corelow.o
+TM_FILE= tm-nbsd.h
diff --git a/gdb/config/i386/ncr3000.mh b/gdb/config/i386/ncr3000.mh
new file mode 100644
index 00000000000..4e669ba4ad6
--- /dev/null
+++ b/gdb/config/i386/ncr3000.mh
@@ -0,0 +1,16 @@
+# Host: NCR 3000 (Intel 386 running SVR4)
+
+# The NCR 3000 ships with a MetaWare compiler installed as /bin/cc.
+# This compiler not only emits obnoxious copyright messages every time
+# you run it, but it chokes and dies on a whole bunch of GNU source
+# files. Default to using the AT&T compiler installed in /usr/ccs/ATT/cc.
+# Unfortunately though, the AT&T compiler sometimes generates code that
+# the assembler barfs on if -g is used, so disable it by default as well.
+CC = /usr/ccs/ATT/cc
+CFLAGS =
+
+XM_FILE= xm-i386v4.h
+
+NAT_FILE= nm-i386v4.h
+NATDEPFILES= corelow.o core-regset.o fork-child.o i386v4-nat.o procfs.o \
+ proc-api.o proc-events.o proc-flags.o proc-why.o
diff --git a/gdb/config/i386/ncr3000.mt b/gdb/config/i386/ncr3000.mt
new file mode 100644
index 00000000000..11bc47426e6
--- /dev/null
+++ b/gdb/config/i386/ncr3000.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running SVR4
+TDEPFILES= i386-tdep.o i387-tdep.o solib.o solib-svr4.o solib-legacy.o
+TM_FILE= tm-i386v4.h
diff --git a/gdb/config/i386/nm-cygwin.h b/gdb/config/i386/nm-cygwin.h
new file mode 100644
index 00000000000..7eac99ba3fd
--- /dev/null
+++ b/gdb/config/i386/nm-cygwin.h
@@ -0,0 +1,36 @@
+/* Native definitions for Intel x86 running CYGWIN.
+ Copyright 2002 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. */
+
+#define I386_USE_GENERIC_WATCHPOINTS
+
+#include "i386/nm-i386.h"
+
+/* Support for hardware-assisted breakpoints and watchpoints. */
+
+#define I386_DR_LOW_SET_CONTROL(VAL) cygwin_set_dr7 (VAL)
+extern void cygwin_set_dr7 (unsigned);
+
+#define I386_DR_LOW_SET_ADDR(N,ADDR) cygwin_set_dr (N,ADDR)
+extern void cygwin_set_dr (int, CORE_ADDR);
+
+#define I386_DR_LOW_RESET_ADDR(N)
+
+#define I386_DR_LOW_GET_STATUS() cygwin_get_dr6 ()
+extern unsigned cygwin_get_dr6 (void);
diff --git a/gdb/config/i386/nm-fbsd.h b/gdb/config/i386/nm-fbsd.h
new file mode 100644
index 00000000000..b7919036199
--- /dev/null
+++ b/gdb/config/i386/nm-fbsd.h
@@ -0,0 +1,155 @@
+/* Native-dependent definitions for FreeBSD/i386.
+ Copyright 1986, 1987, 1989, 1992, 1994, 1996, 1997, 2000, 2001
+ 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. */
+
+#ifndef NM_FBSD_H
+#define NM_FBSD_H
+
+#ifdef HAVE_PT_GETDBREGS
+#define I386_USE_GENERIC_WATCHPOINTS
+#endif
+
+#include "i386/nm-i386.h"
+
+/* Provide access to the i386 hardware debugging registers. */
+
+#define I386_DR_LOW_SET_CONTROL(control) \
+ i386bsd_dr_set_control (control)
+extern void i386bsd_dr_set_control (unsigned long control);
+
+#define I386_DR_LOW_SET_ADDR(regnum, addr) \
+ i386bsd_dr_set_addr (regnum, addr)
+extern void i386bsd_dr_set_addr (int regnum, CORE_ADDR addr);
+
+#define I386_DR_LOW_RESET_ADDR(regnum) \
+ i386bsd_dr_reset_addr (regnum)
+extern void i386bsd_dr_reset_addr (int regnum);
+
+#define I386_DR_LOW_GET_STATUS() \
+ i386bsd_dr_get_status ()
+extern unsigned long i386bsd_dr_get_status (void);
+
+
+/* Type of the third argument to the `ptrace' system call. */
+#define PTRACE_ARG3_TYPE caddr_t
+
+/* Override copies of {fetch,store}_inferior_registers in `infptrace.c'. */
+#define FETCH_INFERIOR_REGISTERS
+
+/* Override child_resume in `infptrace.c' to work around a kernel bug. */
+#define CHILD_RESUME
+
+/* Override child_pid_to_exec_file in 'inftarg.c'. */
+#define CHILD_PID_TO_EXEC_FILE
+
+/* We can attach and detach. */
+#define ATTACH_DETACH
+
+
+/* Support for the user struct. */
+
+/* Return the size of the user struct. */
+
+#define KERNEL_U_SIZE kernel_u_size ()
+extern int kernel_u_size (void);
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+
+#include <machine/vmparam.h>
+#define KERNEL_U_ADDR USRSTACK
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = register_u_addr ((blockend), (regno))
+extern CORE_ADDR register_u_addr (CORE_ADDR blockend, int regno);
+
+
+/* Shared library support. */
+
+/* The FreeBSD <link.h> uses the same condition to distinguish ELF
+ from a.out. ELF implies SVR4 shared libraries. */
+#if (defined (FREEBSD_ELF) || defined (__ELF__)) && !defined (FREEBSD_AOUT)
+#define SVR4_SHARED_LIBS
+#endif
+
+#include "solib.h" /* Support for shared libraries. */
+#ifdef SVR4_SHARED_LIBS
+#include "elf/common.h" /* Additional ELF shared library info. */
+#endif
+
+#ifndef SVR4_SHARED_LIBS
+
+/* Make structure definitions match up with those expected in `solib.c'. */
+
+#define link_object sod
+#define lo_name sod_name
+#define lo_library sod_library
+#define lo_unused sod_reserved
+#define lo_major sod_major
+#define lo_minor sod_minor
+#define lo_next sod_next
+
+#define link_map so_map
+#define lm_addr som_addr
+#define lm_name som_path
+#define lm_next som_next
+#define lm_lop som_sod
+#define lm_lob som_sodbase
+#define lm_rwt som_write
+#define lm_ld som_dynamic
+#define lm_lpd som_spd
+
+#define link_dynamic_2 section_dispatch_table
+#define ld_loaded sdt_loaded
+#define ld_need sdt_sods
+#define ld_rules sdt_filler1
+#define ld_got sdt_got
+#define ld_plt sdt_plt
+#define ld_rel sdt_rel
+#define ld_hash sdt_hash
+#define ld_stab sdt_nzlist
+#define ld_stab_hash sdt_filler2
+#define ld_buckets sdt_buckets
+#define ld_symbols sdt_strings
+#define ld_symb_size sdt_str_sz
+#define ld_text sdt_text_sz
+#define ld_plt_sz sdt_plt_sz
+
+#define rtc_symb rt_symbol
+#define rtc_sp rt_sp
+#define rtc_next rt_next
+
+#define ld_debug so_debug
+#define ldd_version dd_version
+#define ldd_in_debugger dd_in_debugger
+#define ldd_sym_loaded dd_sym_loaded
+#define ldd_bp_addr dd_bpt_addr
+#define ldd_bp_inst dd_bpt_shadow
+#define ldd_cp dd_cc
+
+#define link_dynamic _dynamic
+#define ld_version d_version
+#define ldd d_debug
+#define ld_un d_un
+#define ld_2 d_sdt
+
+#endif /* !SVR4_SHARED_LIBS */
+
+#endif /* NM_FBSD_H */
diff --git a/gdb/config/i386/nm-gnu.h b/gdb/config/i386/nm-gnu.h
new file mode 100644
index 00000000000..fa6d829345d
--- /dev/null
+++ b/gdb/config/i386/nm-gnu.h
@@ -0,0 +1,23 @@
+/* Native-dependent definitions for Intel 386 running the GNU Hurd
+ Copyright 1994, 1995, 1996 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 the generic hurd definitions. */
+
+#include "nm-gnu.h"
diff --git a/gdb/config/i386/nm-go32.h b/gdb/config/i386/nm-go32.h
new file mode 100644
index 00000000000..5947b745c0e
--- /dev/null
+++ b/gdb/config/i386/nm-go32.h
@@ -0,0 +1,36 @@
+/* Native definitions for Intel x86 running DJGPP.
+ Copyright 1997, 1998, 1999, 2001, 2002 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. */
+
+#define I386_USE_GENERIC_WATCHPOINTS
+
+#include "i386/nm-i386.h"
+
+/* Support for hardware-assisted breakpoints and watchpoints. */
+
+#define I386_DR_LOW_SET_CONTROL(VAL) go32_set_dr7 (VAL)
+extern void go32_set_dr7 (unsigned);
+
+#define I386_DR_LOW_SET_ADDR(N,ADDR) go32_set_dr (N,ADDR)
+extern void go32_set_dr (int, CORE_ADDR);
+
+#define I386_DR_LOW_RESET_ADDR(N)
+
+#define I386_DR_LOW_GET_STATUS() go32_get_dr6 ()
+extern unsigned go32_get_dr6 (void);
diff --git a/gdb/config/i386/nm-i386.h b/gdb/config/i386/nm-i386.h
new file mode 100644
index 00000000000..500bf7b5942
--- /dev/null
+++ b/gdb/config/i386/nm-i386.h
@@ -0,0 +1,120 @@
+/* Native macro definitions for GDB on an Intel i[3456]86.
+ Copyright 2001 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. */
+
+#ifndef NM_I386_H
+#define NM_I386_H 1
+
+/* Hardware-assisted breakpoints and watchpoints. */
+
+/* Targets should define this to use the generic x86 watchpoint support. */
+#ifdef I386_USE_GENERIC_WATCHPOINTS
+
+#ifndef TARGET_HAS_HARDWARE_WATCHPOINTS
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+#endif
+
+/* Clear the reference counts and forget everything we knew about DRi. */
+extern void i386_cleanup_dregs (void);
+
+/* Insert a watchpoint to watch a memory region which starts at
+ address ADDR and whose length is LEN bytes. Watch memory accesses
+ of the type TYPE. Return 0 on success, -1 on failure. */
+extern int i386_insert_watchpoint (CORE_ADDR addr, int len, int type);
+
+/* Remove a watchpoint that watched the memory region which starts at
+ address ADDR, whose length is LEN bytes, and for accesses of the
+ type TYPE. Return 0 on success, -1 on failure. */
+extern int i386_remove_watchpoint (CORE_ADDR addr, int len, int type);
+
+/* Return non-zero if we can watch a memory region that starts at
+ address ADDR and whose length is LEN bytes. */
+extern int i386_region_ok_for_watchpoint (CORE_ADDR addr, int len);
+
+/* Return non-zero if the inferior has some break/watchpoint that
+ triggered. */
+extern int i386_stopped_by_hwbp (void);
+
+/* If the inferior has some break/watchpoint that triggered, return
+ the address associated with that break/watchpoint. Otherwise,
+ return zero. */
+extern CORE_ADDR i386_stopped_data_address (void);
+
+/* Insert a hardware-assisted breakpoint at address ADDR. SHADOW is
+ unused. Return 0 on success, EBUSY on failure. */
+extern int i386_insert_hw_breakpoint (CORE_ADDR addr, void *shadow);
+
+/* Remove a hardware-assisted breakpoint at address ADDR. SHADOW is
+ unused. Return 0 on success, -1 on failure. */
+extern int i386_remove_hw_breakpoint (CORE_ADDR addr, void *shadow);
+
+/* Returns the number of hardware watchpoints of type TYPE that we can
+ set. Value is positive if we can set CNT watchpoints, zero if
+ setting watchpoints of type TYPE is not supported, and negative if
+ CNT is more than the maximum number of watchpoints of type TYPE
+ that we can support. TYPE is one of bp_hardware_watchpoint,
+ bp_read_watchpoint, bp_write_watchpoint, or bp_hardware_breakpoint.
+ CNT is the number of such watchpoints used so far (including this
+ one). OTHERTYPE is non-zero if other types of watchpoints are
+ currently enabled.
+
+ We always return 1 here because we don't have enough information
+ about possible overlap of addresses that they want to watch. As an
+ extreme example, consider the case where all the watchpoints watch
+ the same address and the same region length: then we can handle a
+ virtually unlimited number of watchpoints, due to debug register
+ sharing implemented via reference counts in i386-nat.c. */
+
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1
+
+/* Returns non-zero if we can use hardware watchpoints to watch a
+ region whose address is ADDR and whose length is LEN. */
+
+#define TARGET_REGION_OK_FOR_HW_WATCHPOINT(addr, len) \
+ i386_region_ok_for_watchpoint (addr, len)
+
+/* After a watchpoint trap, the PC points to the instruction after the
+ one that caused the trap. Therefore we don't need to step over it.
+ But we do need to reset the status register to avoid another trap. */
+
+#define HAVE_CONTINUABLE_WATCHPOINT
+
+#define STOPPED_BY_WATCHPOINT(W) (i386_stopped_data_address () != 0)
+
+#define target_stopped_data_address() i386_stopped_data_address ()
+
+/* Use these macros for watchpoint insertion/removal. */
+
+#define target_insert_watchpoint(addr, len, type) \
+ i386_insert_watchpoint (addr, len, type)
+
+#define target_remove_watchpoint(addr, len, type) \
+ i386_remove_watchpoint (addr, len, type)
+
+#define target_insert_hw_breakpoint(addr, shadow) \
+ i386_insert_hw_breakpoint (addr, shadow)
+
+#define target_remove_hw_breakpoint(addr, shadow) \
+ i386_remove_hw_breakpoint (addr, shadow)
+
+#define DECR_PC_AFTER_HW_BREAK 0
+
+#endif /* I386_USE_GENERIC_WATCHPOINTS */
+
+#endif /* NM_I386_H */
diff --git a/gdb/config/i386/nm-i386aix.h b/gdb/config/i386/nm-i386aix.h
new file mode 100644
index 00000000000..4a6ffc1acfa
--- /dev/null
+++ b/gdb/config/i386/nm-i386aix.h
@@ -0,0 +1,43 @@
+/* Native support for i386 aix ps/2.
+ Copyright 1986, 1987, 1989, 1992, 1993 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. */
+
+/*
+ * Changes for IBM AIX PS/2 by Minh Tran-Le (tranle@intellicorp.com)
+ * Revision: 5-May-93 00:11:35
+ */
+
+#ifndef NM_I386AIX_H
+#define NM_I386AIX_H 1
+
+/* code to execute to print interesting information about the
+ * floating point processor (if any)
+ * No need to define if there is nothing to do.
+ */
+#define FLOAT_INFO { i386_float_info (); }
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+#undef KERNEL_U_ADDR
+#define KERNEL_U_ADDR 0xf03fd000
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
+#define FETCH_INFERIOR_REGISTERS
+
+#endif /* NM_I386AIX_H */
diff --git a/gdb/config/i386/nm-i386bsd.h b/gdb/config/i386/nm-i386bsd.h
new file mode 100644
index 00000000000..0015af2ffb0
--- /dev/null
+++ b/gdb/config/i386/nm-i386bsd.h
@@ -0,0 +1,40 @@
+/* Native-dependent definitions for Intel 386 running BSD Unix, for GDB.
+ Copyright 1986, 1987, 1989, 1992, 1993, 2000
+ 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. */
+
+#ifndef NM_I386BSD_H
+#define NM_I386BSD_H
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+
+#include <machine/vmparam.h>
+#define KERNEL_U_ADDR USRSTACK
+
+#undef FLOAT_INFO /* No float info yet */
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = i386_register_u_addr ((blockend),(regno));
+
+extern int i386_register_u_addr (int, int);
+
+#define PTRACE_ARG3_TYPE char*
+
+#endif /* NM_I386BSD_H */
diff --git a/gdb/config/i386/nm-i386lynx.h b/gdb/config/i386/nm-i386lynx.h
new file mode 100644
index 00000000000..5d0d41de267
--- /dev/null
+++ b/gdb/config/i386/nm-i386lynx.h
@@ -0,0 +1,26 @@
+/* Native-dependent definitions for Intel 386 running LynxOS.
+ Copyright 1993 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. */
+
+#ifndef NM_I386LYNX_H
+#define NM_I386LYNX_H
+
+#include "nm-lynx.h"
+
+#endif /* NM_I386LYNX_H */
diff --git a/gdb/config/i386/nm-i386mach.h b/gdb/config/i386/nm-i386mach.h
new file mode 100644
index 00000000000..ef10a28cf8f
--- /dev/null
+++ b/gdb/config/i386/nm-i386mach.h
@@ -0,0 +1,30 @@
+/* Native definitions for Mach on an Intel 386
+ Copyright 1986, 1987, 1989, 1991, 1992, 1996
+ 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 "regcache.h"
+
+/* Do implement the attach and detach commands. */
+/* #define ATTACH_DETACH 1 */
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
+#define FETCH_INFERIOR_REGISTERS
+
+#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
diff --git a/gdb/config/i386/nm-i386sco.h b/gdb/config/i386/nm-i386sco.h
new file mode 100644
index 00000000000..b46776151b3
--- /dev/null
+++ b/gdb/config/i386/nm-i386sco.h
@@ -0,0 +1,42 @@
+/* Native support for i386.
+ Copyright 1986, 1987, 1989, 1992, 1994, 1998, 2000
+ Free Software Foundation, Inc.
+ Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu), July 1988.
+
+ 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. */
+
+#if 0
+/* code to execute to print interesting information about the
+ floating point processor (if any)
+ No need to define if there is nothing to do.
+ On the 386, unfortunately this code is host-dependent (and lives
+ in the i386-xdep.c file), so we can't
+ do this unless we *know* we aren't cross-debugging. FIXME.
+ */
+#define FLOAT_INFO { i386_float_info (); }
+#endif /*0 */
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = i386_register_u_addr ((blockend),(regno));
+
+extern int i386_register_u_addr (int, int);
+
+/* When calling functions on SCO, sometimes we get an error writing some
+ of the segment registers. This would appear to be a kernel
+ bug/non-feature. */
+#define CANNOT_STORE_REGISTER(regno) ((regno) == 14 || (regno) == 15)
diff --git a/gdb/config/i386/nm-i386sco4.h b/gdb/config/i386/nm-i386sco4.h
new file mode 100644
index 00000000000..6947f3febb1
--- /dev/null
+++ b/gdb/config/i386/nm-i386sco4.h
@@ -0,0 +1,33 @@
+/* Native support for SCO 3.2v4.
+ Copyright 1993 Free Software Foundation, Inc.
+ Contributed by Cygnus Support. By Ian Lance Taylor
+ <ian@cygnus.com> based on work by Martin Walker <maw@netcom.com>.
+
+ 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. */
+
+/* SCO 3.2v4 is actually just like SCO 3.2v2, except that it
+ additionally supports attaching to a process. */
+
+#include "i386/nm-i386sco.h"
+
+#define ATTACH_DETACH
+
+/* SCO, in its wisdom, does not provide <sys/ptrace.h>. infptrace.c
+ does not have defaults for these values. */
+#define PTRACE_ATTACH 10
+#define PTRACE_DETACH 11
diff --git a/gdb/config/i386/nm-i386sco5.h b/gdb/config/i386/nm-i386sco5.h
new file mode 100644
index 00000000000..db2880c01ba
--- /dev/null
+++ b/gdb/config/i386/nm-i386sco5.h
@@ -0,0 +1,38 @@
+/* Native support for SCO OpenServer 5
+ Copyright 1996, 1998 Free Software Foundation, Inc.
+ Re-written by J. Kean Johnston <jkj@sco.com>.
+ Originally written by Robert Lipe <robertl@dgii.com>, based on
+ work by Ian Lance Taylor <ian@cygnus.com> and
+ Martin Walker <maw@netcom.com>.
+
+ 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. */
+
+/* Basically, its a lot like the older versions ... */
+#include "i386/nm-i386sco.h"
+
+/* ... but it can do a lot of SVR4 type stuff too. */
+#define SVR4_SHARED_LIBS
+#include "solib.h" /* Pick up shared library support */
+
+#define ATTACH_DETACH
+
+/* SCO does not provide <sys/ptrace.h>. infptrace.c does not
+ have defaults for these values. */
+
+#define PTRACE_ATTACH 10
+#define PTRACE_DETACH 11
diff --git a/gdb/config/i386/nm-i386sol2.h b/gdb/config/i386/nm-i386sol2.h
new file mode 100644
index 00000000000..0e6b3ef4c7f
--- /dev/null
+++ b/gdb/config/i386/nm-i386sol2.h
@@ -0,0 +1,60 @@
+/* Native support for i386 running Solaris 2.
+ Copyright 1998, 1999, 2000 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 "nm-sysv4.h"
+
+#ifdef NEW_PROC_API /* Solaris 6 and above can do HW watchpoints */
+
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+
+/* The man page for proc4 on solaris 6 and 7 says that the system
+ can support "thousands" of hardware watchpoints, but gives no
+ method for finding out how many. So just tell GDB 'yes'. */
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE, CNT, OT) 1
+
+/* When a hardware watchpoint fires off the PC will be left at the
+ instruction following the one which caused the watchpoint.
+ It will *NOT* be necessary for GDB to step over the watchpoint. */
+#define HAVE_CONTINUABLE_WATCHPOINT
+
+/* Solaris x86 2.6 and 2.7 targets have a kernel bug when stepping
+ over an instruction that causes a page fault without triggering
+ a hardware watchpoint. The kernel properly notices that it shouldn't
+ stop, because the hardware watchpoint is not triggered, but it forgets
+ the step request and continues the program normally.
+ Work around the problem by removing hardware watchpoints if a step is
+ requested, GDB will check for a hardware watchpoint trigger after the
+ step anyway. */
+#define CANNOT_STEP_HW_WATCHPOINTS
+
+extern int procfs_stopped_by_watchpoint (ptid_t);
+#define STOPPED_BY_WATCHPOINT(W) \
+ procfs_stopped_by_watchpoint(inferior_ptid)
+
+/* Use these macros for watchpoint insertion/deletion. */
+/* type can be 0: write watch, 1: read watch, 2: access watch (read/write) */
+
+extern int procfs_set_watchpoint (ptid_t, CORE_ADDR, int, int, int);
+#define target_insert_watchpoint(ADDR, LEN, TYPE) \
+ procfs_set_watchpoint (inferior_ptid, ADDR, LEN, TYPE, 1)
+#define target_remove_watchpoint(ADDR, LEN, TYPE) \
+ procfs_set_watchpoint (inferior_ptid, ADDR, 0, 0, 0)
+
+#endif /* NEW_PROC_API */
diff --git a/gdb/config/i386/nm-i386v.h b/gdb/config/i386/nm-i386v.h
new file mode 100644
index 00000000000..e7bfca4ea57
--- /dev/null
+++ b/gdb/config/i386/nm-i386v.h
@@ -0,0 +1,37 @@
+/* Native support for i386.
+ Copyright 1986, 1987, 1989, 1992, 1993, 1998, 2000
+ Free Software Foundation, Inc.
+ Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu), July 1988.
+
+ 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. */
+
+#if 0
+/* code to execute to print interesting information about the
+ floating point processor (if any)
+ No need to define if there is nothing to do.
+ On the 386, unfortunately this code is host-dependent (and lives
+ in the i386-xdep.c file), so we can't
+ do this unless we *know* we aren't cross-debugging. FIXME.
+ */
+#define FLOAT_INFO { i386_float_info (); }
+#endif /*0 */
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = i386_register_u_addr ((blockend),(regno));
+
+extern int i386_register_u_addr (int, int);
diff --git a/gdb/config/i386/nm-i386v4.h b/gdb/config/i386/nm-i386v4.h
new file mode 100644
index 00000000000..02d445e8bc3
--- /dev/null
+++ b/gdb/config/i386/nm-i386v4.h
@@ -0,0 +1,26 @@
+/* Native support for i386 running SVR4.
+ Copyright 1986, 1987, 1989, 1992, 1993, 1996
+ Free Software Foundation, Inc.
+ Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu), July 1988.
+
+ 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 "nm-sysv4.h"
+
+/* Poll causes GDB to hang, at least under Unixware 1.1.2. */
+#define LOSING_POLL
diff --git a/gdb/config/i386/nm-i386v42mp.h b/gdb/config/i386/nm-i386v42mp.h
new file mode 100644
index 00000000000..72e440d0cc4
--- /dev/null
+++ b/gdb/config/i386/nm-i386v42mp.h
@@ -0,0 +1,23 @@
+/* Native support for i386 running SVR4.
+ Copyright 1986, 1987, 1989, 1992, 1996, 1997, 1998
+ Free Software Foundation, Inc.
+ Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu), July 1988.
+
+ 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 "nm-sysv4.h"
diff --git a/gdb/config/i386/nm-linux.h b/gdb/config/i386/nm-linux.h
new file mode 100644
index 00000000000..8ae3eceec98
--- /dev/null
+++ b/gdb/config/i386/nm-linux.h
@@ -0,0 +1,83 @@
+/* Native support for GNU/Linux x86.
+
+ Copyright 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001, 2002 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. */
+
+#ifndef NM_LINUX_H
+#define NM_LINUX_H
+
+/* GNU/Linux supports the i386 hardware debugging registers. */
+#define I386_USE_GENERIC_WATCHPOINTS
+
+#include "i386/nm-i386.h"
+#include "nm-linux.h"
+
+/* Support for the user area. */
+
+/* Return the size of the user struct. */
+extern int kernel_u_size (void);
+#define KERNEL_U_SIZE kernel_u_size()
+
+/* This is the amount to substract from u.u_ar0 to get the offset in
+ the core file of the register values. */
+#define KERNEL_U_ADDR 0
+
+/* Offset of the registers within the user area. */
+#define U_REGS_OFFSET 0
+
+extern CORE_ADDR register_u_addr (CORE_ADDR blockend, int regnum);
+#define REGISTER_U_ADDR(addr, blockend, regnum) \
+ (addr) = register_u_addr (blockend, regnum)
+
+/* Provide access to the i386 hardware debugging registers. */
+
+extern void i386_linux_dr_set_control (unsigned long control);
+#define I386_DR_LOW_SET_CONTROL(control) \
+ i386_linux_dr_set_control (control)
+
+extern void i386_linux_dr_set_addr (int regnum, CORE_ADDR addr);
+#define I386_DR_LOW_SET_ADDR(regnum, addr) \
+ i386_linux_dr_set_addr (regnum, addr)
+
+extern void i386_linux_dr_reset_addr (int regnum);
+#define I386_DR_LOW_RESET_ADDR(regnum) \
+ i386_linux_dr_reset_addr (regnum)
+
+extern unsigned long i386_linux_dr_get_status (void);
+#define I386_DR_LOW_GET_STATUS() \
+ i386_linux_dr_get_status ()
+
+
+/* Override copies of {fetch,store}_inferior_registers in `infptrace.c'. */
+#define FETCH_INFERIOR_REGISTERS
+
+/* Nevertheless, define CANNOT_{FETCH,STORE}_REGISTER, because we
+ might fall back on the code `infptrace.c' (well a copy of that code
+ in `i386-linux-nat.c' for now) and we can access only the
+ general-purpose registers in that way. */
+extern int cannot_fetch_register (int regno);
+extern int cannot_store_register (int regno);
+#define CANNOT_FETCH_REGISTER(regno) cannot_fetch_register (regno)
+#define CANNOT_STORE_REGISTER(regno) cannot_store_register (regno)
+
+/* Override child_resume in `infptrace.c'. */
+#define CHILD_RESUME
+
+#endif /* nm-linux.h */
diff --git a/gdb/config/i386/nm-m3.h b/gdb/config/i386/nm-m3.h
new file mode 100644
index 00000000000..00128cf9ce8
--- /dev/null
+++ b/gdb/config/i386/nm-m3.h
@@ -0,0 +1,23 @@
+/* Native-dependent definitions for Intel 386 running Mach 3.
+ Copyright 1994 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 the generic Mach 3 definitions. */
+
+#include "nm-m3.h"
diff --git a/gdb/config/i386/nm-nbsd.h b/gdb/config/i386/nm-nbsd.h
new file mode 100644
index 00000000000..2e5adb82b3d
--- /dev/null
+++ b/gdb/config/i386/nm-nbsd.h
@@ -0,0 +1,28 @@
+/* Native-dependent definitions for Intel 386 running NetBSD, for GDB.
+ Copyright 1986, 1987, 1989, 1992, 1994, 2000, 2002
+ 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. */
+
+#ifndef NM_NBSD_H
+#define NM_NBSD_H
+
+/* Get generic NetBSD native definitions. */
+#include "config/nm-nbsd.h"
+
+#endif /* NM_NBSD_H */
diff --git a/gdb/config/i386/nm-nbsdaout.h b/gdb/config/i386/nm-nbsdaout.h
new file mode 100644
index 00000000000..dc8aac961c4
--- /dev/null
+++ b/gdb/config/i386/nm-nbsdaout.h
@@ -0,0 +1,30 @@
+/* Native-dependent definitions for Intel 386 running NetBSD, for GDB.
+ Copyright 1986, 1987, 1989, 1992, 1994, 1996, 2000
+ 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. */
+
+#ifndef NM_NBSDAOUT_H
+#define NM_NBSDAOUT_H
+
+#include "i386/nm-nbsd.h"
+
+/* Get generic NetBSD a.out native definitions. */
+#include "config/nm-nbsdaout.h"
+
+#endif /* NM_NBSDAOUT_H */
diff --git a/gdb/config/i386/nm-obsd.h b/gdb/config/i386/nm-obsd.h
new file mode 100644
index 00000000000..6113e140088
--- /dev/null
+++ b/gdb/config/i386/nm-obsd.h
@@ -0,0 +1,110 @@
+/* Native-dependent definitions for OpenBSD/i386.
+ Copyright 2001 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. */
+
+#ifndef NM_OBSD_H
+#define NM_OBSD_H
+
+/* Type of the third argument to the `ptrace' system call. */
+#define PTRACE_ARG3_TYPE caddr_t
+
+/* Override copies of {fetch,store}_inferior_registers in `infptrace.c'. */
+#define FETCH_INFERIOR_REGISTERS
+
+/* We can attach and detach. */
+#define ATTACH_DETACH
+
+
+/* Support for the user struct. */
+
+/* Return the size of the user struct. */
+
+#define KERNEL_U_SIZE kernel_u_size ()
+extern int kernel_u_size (void);
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+
+#include <machine/vmparam.h>
+#define KERNEL_U_ADDR USRSTACK
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = register_u_addr ((blockend), (regno))
+extern CORE_ADDR register_u_addr (CORE_ADDR blockend, int regno);
+
+
+/* Shared library support. */
+
+#include "solib.h" /* Support for shared libraries. */
+
+/* Make structure definitions match up with those expected in `solib.c'. */
+
+#define link_object sod
+#define lo_name sod_name
+#define lo_library sod_library
+#define lo_unused sod_reserved
+#define lo_major sod_major
+#define lo_minor sod_minor
+#define lo_next sod_next
+
+#define link_map so_map
+#define lm_addr som_addr
+#define lm_name som_path
+#define lm_next som_next
+#define lm_lop som_sod
+#define lm_lob som_sodbase
+#define lm_rwt som_write
+#define lm_ld som_dynamic
+#define lm_lpd som_spd
+
+#define link_dynamic_2 section_dispatch_table
+#define ld_loaded sdt_loaded
+#define ld_need sdt_sods
+#define ld_rules sdt_filler1
+#define ld_got sdt_got
+#define ld_plt sdt_plt
+#define ld_rel sdt_rel
+#define ld_hash sdt_hash
+#define ld_stab sdt_nzlist
+#define ld_stab_hash sdt_filler2
+#define ld_buckets sdt_buckets
+#define ld_symbols sdt_strings
+#define ld_symb_size sdt_str_sz
+#define ld_text sdt_text_sz
+#define ld_plt_sz sdt_plt_sz
+
+#define rtc_symb rt_symbol
+#define rtc_sp rt_sp
+#define rtc_next rt_next
+
+#define ld_debug so_debug
+#define ldd_version dd_version
+#define ldd_in_debugger dd_in_debugger
+#define ldd_sym_loaded dd_sym_loaded
+#define ldd_bp_addr dd_bpt_addr
+#define ldd_bp_inst dd_bpt_shadow
+#define ldd_cp dd_cc
+
+#define link_dynamic _dynamic
+#define ld_version d_version
+#define ldd d_debug
+#define ld_un d_un
+#define ld_2 d_sdt
+
+#endif /* nm-obsd.h */
diff --git a/gdb/config/i386/nm-ptx4.h b/gdb/config/i386/nm-ptx4.h
new file mode 100644
index 00000000000..32b76d24256
--- /dev/null
+++ b/gdb/config/i386/nm-ptx4.h
@@ -0,0 +1,66 @@
+/* Definitions to make GDB run on a Sequent Symmetry under ptx
+ with Weitek 1167 and i387 support.
+ Copyright 1986, 1987, 1989, 1992, 1994, 1996, 2000
+ 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 "regcache.h"
+
+#include "nm-sysv4.h"
+
+#undef USE_PROC_FS
+
+#include "nm-symmetry.h"
+
+#define PTRACE_READ_REGS(pid,regaddr) mptrace (XPT_RREGS, (pid), (regaddr), 0)
+#define PTRACE_WRITE_REGS(pid,regaddr) \
+ mptrace (XPT_WREGS, (pid), (regaddr), 0)
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
+
+#define FETCH_INFERIOR_REGISTERS
+
+/* We must fetch all the regs before storing, since we store all at once. */
+
+#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
+
+#define CHILD_WAIT
+struct target_waitstatus;
+extern ptid_t child_wait (ptid_t, struct target_waitstatus *);
+
+/*
+ * ptx does attach as of ptx version 2.1. Prior to that, the interface
+ * exists but does not work.
+ *
+ * FIXME: Using attach/detach requires using the ptx MPDEBUGGER
+ * interface. There are still problems with that, so for now don't
+ * enable attach/detach. If you turn it on anyway, it will mostly
+ * work, but has a number of bugs. -fubar, 2/94.
+ */
+/*#define ATTACH_DETACH 1 */
+#undef ATTACH_DETACH
+#define PTRACE_ATTACH XPT_DEBUG
+#define PTRACE_DETACH XPT_UNDEBUG
+/*
+ * The following drivel is needed because there are two ptrace-ish
+ * calls on ptx: ptrace() and mptrace(), each of which does about half
+ * of the ptrace functions.
+ */
+#define PTRACE_ATTACH_CALL(pid) ptx_do_attach(pid)
+#define PTRACE_DETACH_CALL(pid, signo) ptx_do_detach(pid, signo)
diff --git a/gdb/config/i386/nm-symmetry.h b/gdb/config/i386/nm-symmetry.h
new file mode 100644
index 00000000000..a589a3de0d5
--- /dev/null
+++ b/gdb/config/i386/nm-symmetry.h
@@ -0,0 +1,50 @@
+/* Definitions to make GDB run on a Sequent Symmetry under dynix 3.0,
+ with Weitek 1167 and i387 support.
+ Copyright 1986, 1987, 1989, 1992, 1994, 1996, 1998, 2000
+ 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 "regcache.h"
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
+
+#define FETCH_INFERIOR_REGISTERS
+
+/* We must fetch all the regs before storing, since we store all at once. */
+
+#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
+
+#ifdef _SEQUENT_
+#define CHILD_WAIT
+extern ptid_t child_wait (ptid_t, struct target_waitstatus *);
+#endif
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+
+#ifdef _SEQUENT_
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/mc_vmparam.h>
+/* VA_UAREA is defined in <sys/mc_vmparam.h>, and is dependant upon
+ sizeof(struct user) */
+#define KERNEL_U_ADDR (VA_UAREA) /* ptx */
+#else
+#define KERNEL_U_ADDR (0x80000000 - (UPAGES * NBPG)) /* dynix */
+#endif
diff --git a/gdb/config/i386/nm-x86-64.h b/gdb/config/i386/nm-x86-64.h
new file mode 100644
index 00000000000..30e37310222
--- /dev/null
+++ b/gdb/config/i386/nm-x86-64.h
@@ -0,0 +1,90 @@
+/* Native support for GNU/Linux x86-64.
+
+ Copyright 2001, 2002 Free Software Foundation, Inc. Contributed by
+ Jiri Smid, SuSE Labs.
+
+ 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. */
+
+#ifndef NM_X86_64_H
+#define NM_X86_64_H
+
+#include "nm-linux.h"
+
+#define I386_USE_GENERIC_WATCHPOINTS
+#include "i386/nm-i386.h"
+
+/* Support for 8-byte wide hw watchpoints. */
+#define TARGET_HAS_DR_LEN_8 1
+
+/* Provide access to the i386 hardware debugging registers. */
+
+extern void x86_64_linux_dr_set_control (unsigned long control);
+#define I386_DR_LOW_SET_CONTROL(control) \
+ x86_64_linux_dr_set_control (control)
+
+extern void x86_64_linux_dr_set_addr (int regnum, CORE_ADDR addr);
+#define I386_DR_LOW_SET_ADDR(regnum, addr) \
+ x86_64_linux_dr_set_addr (regnum, addr)
+
+extern void x86_64_linux_dr_reset_addr (int regnum);
+#define I386_DR_LOW_RESET_ADDR(regnum) \
+ x86_64_linux_dr_reset_addr (regnum)
+
+extern unsigned long x86_64_linux_dr_get_status (void);
+#define I386_DR_LOW_GET_STATUS() \
+ x86_64_linux_dr_get_status ()
+
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = x86_64_register_u_addr ((blockend),(regno));
+CORE_ADDR x86_64_register_u_addr (CORE_ADDR, int);
+
+/* Return the size of the user struct. */
+#define KERNEL_U_SIZE kernel_u_size()
+extern int kernel_u_size (void);
+
+/* Offset of the registers within the user area. */
+#define U_REGS_OFFSET 0
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+#define KERNEL_U_ADDR 0x0
+
+#define PTRACE_ARG3_TYPE void*
+#define PTRACE_XFER_TYPE unsigned long
+
+
+/* We define this if link.h is available, because with ELF we use SVR4 style
+ shared libraries. */
+
+#ifdef HAVE_LINK_H
+#define SVR4_SHARED_LIBS
+#include "solib.h" /* Support for shared libraries. */
+#endif
+
+/* Override copies of {fetch,store}_inferior_registers in `infptrace.c'. */
+#define FETCH_INFERIOR_REGISTERS
+
+#undef PREPARE_TO_PROCEED
+
+#include <signal.h>
+
+extern void lin_thread_get_thread_signals (sigset_t * mask);
+#define GET_THREAD_SIGNALS(mask) lin_thread_get_thread_signals (mask)
+
+#endif /* NM_X86_64.h */
diff --git a/gdb/config/i386/obsd.mh b/gdb/config/i386/obsd.mh
new file mode 100644
index 00000000000..d9593ceb846
--- /dev/null
+++ b/gdb/config/i386/obsd.mh
@@ -0,0 +1,7 @@
+# Host: Intel 386 running OpenBSD
+
+XM_FILE= xm-i386.h
+
+NAT_FILE= nm-obsd.h
+# NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make.
+NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-sunos.o corelow.o core-aout.o i386-nat.o i386bsd-nat.o
diff --git a/gdb/config/i386/obsd.mt b/gdb/config/i386/obsd.mt
new file mode 100644
index 00000000000..5c96426b96d
--- /dev/null
+++ b/gdb/config/i386/obsd.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running OpenBSD
+TDEPFILES= i386-tdep.o i387-tdep.o i386bsd-tdep.o
+TM_FILE= tm-obsd.h
diff --git a/gdb/config/i386/ptx.mh b/gdb/config/i386/ptx.mh
new file mode 100644
index 00000000000..554b4119c76
--- /dev/null
+++ b/gdb/config/i386/ptx.mh
@@ -0,0 +1,7 @@
+# Host: Sequent Symmetry running ptx 1.3, with Weitek 1167 or i387
+
+XM_FILE= xm-ptx.h
+NATDEPFILES= inftarg.o fork-child.o symm-nat.o corelow.o core-aout.o
+XM_CLIBS= -lPW -lseq
+
+NAT_FILE= nm-symmetry.h
diff --git a/gdb/config/i386/ptx.mt b/gdb/config/i386/ptx.mt
new file mode 100644
index 00000000000..757df3328fc
--- /dev/null
+++ b/gdb/config/i386/ptx.mt
@@ -0,0 +1,3 @@
+# Target: Sequent Symmetry running ptx 2.0, with Weitek 1167 or i387.
+TDEPFILES= symm-tdep.o i387-tdep.o i386-tdep.o
+TM_FILE= tm-ptx.h
diff --git a/gdb/config/i386/ptx4.mh b/gdb/config/i386/ptx4.mh
new file mode 100644
index 00000000000..e4aa55e88a0
--- /dev/null
+++ b/gdb/config/i386/ptx4.mh
@@ -0,0 +1,8 @@
+# Host: Sequent Symmetry running ptx 1.3, with Weitek 1167 or i387
+
+XM_FILE= xm-ptx4.h
+NATDEPFILES= inftarg.o fork-child.o symm-nat.o corelow.o core-aout.o \
+ core-regset.o solib.o solib-svr4.o solib-legacy.o
+XM_CLIBS= -lseq
+
+NAT_FILE= nm-ptx4.h
diff --git a/gdb/config/i386/ptx4.mt b/gdb/config/i386/ptx4.mt
new file mode 100644
index 00000000000..f3478091996
--- /dev/null
+++ b/gdb/config/i386/ptx4.mt
@@ -0,0 +1,3 @@
+# Target: Sequent Symmetry running ptx 4.0, with Weitek 1167 or i387.
+TDEPFILES= symm-tdep.o i387-tdep.o i386-tdep.o
+TM_FILE= tm-ptx4.h
diff --git a/gdb/config/i386/symmetry.mh b/gdb/config/i386/symmetry.mh
new file mode 100644
index 00000000000..486a2fbe170
--- /dev/null
+++ b/gdb/config/i386/symmetry.mh
@@ -0,0 +1,4 @@
+# Host: Sequent Symmetry running Dynix 3.0, with Weitek 1167 or i387.
+XM_FILE= xm-symmetry.h
+NAT_FILE= nm-symmetry.h
+NATDEPFILES= inftarg.o fork-child.o corelow.o core-aout.o symm-nat.o
diff --git a/gdb/config/i386/symmetry.mt b/gdb/config/i386/symmetry.mt
new file mode 100644
index 00000000000..a3dba70bd82
--- /dev/null
+++ b/gdb/config/i386/symmetry.mt
@@ -0,0 +1,3 @@
+# Target: Sequent Symmetry running Dynix 3.0, with Weitek 1167 or i387.
+TDEPFILES= i386-tdep.o symm-tdep.o i387-tdep.o
+TM_FILE= tm-symmetry.h
diff --git a/gdb/config/i386/tm-cygwin.h b/gdb/config/i386/tm-cygwin.h
new file mode 100644
index 00000000000..1d49133a05b
--- /dev/null
+++ b/gdb/config/i386/tm-cygwin.h
@@ -0,0 +1,49 @@
+/* Macro definitions for i386 running under the win32 API Unix.
+ Copyright 1995, 1996, 1997, 1998, 1999, 2000
+ 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. */
+
+/* Use SSE registers if winnt.h contains information about them. */
+#ifdef HAVE_CONTEXT_EXTENDED_REGISTERS
+#define HAVE_SSE_REGS
+#else
+#undef HAVE_SSE_REGS
+#endif /* CONTEXT_EXTENDED_REGISTERS */
+#define HAVE_I387_REGS
+
+#include "i386/tm-i386.h"
+
+#if 0
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) skip_trampoline_code (pc, name)
+#define SKIP_TRAMPOLINE_CODE(pc) skip_trampoline_code (pc, 0)
+extern CORE_ADDR skip_trampoline_code (CORE_ADDR pc, char *name);
+#endif
+
+#define ATTACH_NO_WAIT
+#define SOLIB_ADD(filename, from_tty, targ, readsyms) child_solib_add(filename, from_tty, targ, readsyms)
+#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) child_solib_loaded_library_pathname(pid)
+#define CLEAR_SOLIB child_clear_solibs
+#define ADD_SHARED_SYMBOL_FILES dll_symbol_command
+
+struct target_ops;
+char *cygwin_pid_to_str (ptid_t ptid);
+void child_solib_add (char *, int, struct target_ops *, int);
+char *child_solib_loaded_library_pathname(int);
+void child_clear_solibs (void);
+void dll_symbol_command (char *, int);
diff --git a/gdb/config/i386/tm-fbsd.h b/gdb/config/i386/tm-fbsd.h
new file mode 100644
index 00000000000..61f5de57f4a
--- /dev/null
+++ b/gdb/config/i386/tm-fbsd.h
@@ -0,0 +1,89 @@
+/* Target-dependent definitions for FreeBSD/i386.
+ Copyright 1997, 1999, 2000, 2001 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. */
+
+#ifndef TM_FBSD_H
+#define TM_FBSD_H
+
+#define HAVE_I387_REGS
+#include "i386/tm-i386.h"
+
+/* FreeBSD/ELF uses stabs-in-ELF with the DWARF register numbering
+ scheme by default, so we must redefine STAB_REG_TO_REGNUM. This
+ messes up the floating-point registers for a.out, but there is not
+ much we can do about that. */
+
+#undef STAB_REG_TO_REGNUM
+#define STAB_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg))
+
+/* FreeBSD uses the old gcc convention for struct returns. */
+
+#define USE_STRUCT_CONVENTION(gcc_p, type) \
+ generic_use_struct_convention (1, type)
+
+
+/* Support for longjmp. */
+
+/* Details about jmp_buf. It's supposed to be an array of integers. */
+
+#define JB_ELEMENT_SIZE 4 /* Size of elements in jmp_buf. */
+#define JB_PC 0 /* Array index of saved PC. */
+
+/* Figure out where the longjmp will land. Store the address that
+ longjmp will jump to in *ADDR, and return non-zero if successful. */
+
+#define GET_LONGJMP_TARGET(addr) get_longjmp_target (addr)
+extern int get_longjmp_target (CORE_ADDR *addr);
+
+
+/* Support for signal handlers. */
+
+#define IN_SIGTRAMP(pc, name) i386bsd_in_sigtramp (pc, name)
+extern int i386bsd_in_sigtramp (CORE_ADDR pc, char *name);
+
+/* These defines allow the recognition of sigtramps as a function name
+ <sigtramp>.
+
+ FIXME: kettenis/2001-07-13: These should be added to the target
+ vector and turned into functions when we go "multi-arch". */
+
+#define SIGTRAMP_START(pc) i386bsd_sigtramp_start
+#define SIGTRAMP_END(pc) i386bsd_sigtramp_end
+extern CORE_ADDR i386bsd_sigtramp_start;
+extern CORE_ADDR i386bsd_sigtramp_end;
+
+/* Override FRAME_SAVED_PC to enable the recognition of signal handlers. */
+
+#undef FRAME_SAVED_PC
+#define FRAME_SAVED_PC(frame) i386bsd_frame_saved_pc (frame)
+extern CORE_ADDR i386bsd_frame_saved_pc (struct frame_info *frame);
+
+
+/* Shared library support. */
+
+#ifndef SVR4_SHARED_LIBS
+
+/* Return non-zero if we are in a shared library trampoline code stub. */
+
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
+ (name && !strcmp(name, "_DYNAMIC"))
+
+#endif /* !SVR4_SHARED_LIBS */
+
+#endif /* TM_FBSD_H */
diff --git a/gdb/config/i386/tm-go32.h b/gdb/config/i386/tm-go32.h
new file mode 100644
index 00000000000..b660827bd66
--- /dev/null
+++ b/gdb/config/i386/tm-go32.h
@@ -0,0 +1,68 @@
+/* Target-dependent definitions for Intel x86 running DJGPP.
+ Copyright 1995, 1996, 1997, 1999, 2000 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. */
+
+#ifndef TM_GO32_H
+#define TM_GO32_H
+
+#undef HAVE_SSE_REGS /* FIXME! go32-nat.c needs to support XMMi registers */
+#define HAVE_I387_REGS
+
+#include "i386/tm-i386.h"
+
+/* FRAME_CHAIN takes a frame's nominal address and produces the frame's
+ chain-pointer.
+ In the case of the i386, the frame's nominal address
+ is the address of a 4-byte word containing the calling frame's address.
+ DJGPP doesn't have any special frames for signal handlers, they are
+ just normal C functions. */
+#undef FRAME_CHAIN
+#define FRAME_CHAIN(thisframe) \
+ (!inside_entry_file ((thisframe)->pc) ? \
+ read_memory_integer ((thisframe)->frame, 4) :\
+ 0)
+
+/* A macro that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. If it
+ does not, FRAMELESS is set to 1, else 0. */
+#undef FRAMELESS_FUNCTION_INVOCATION
+#define FRAMELESS_FUNCTION_INVOCATION(FI) \
+ (frameless_look_for_prologue(FI))
+
+extern CORE_ADDR i386go32_frame_saved_pc (struct frame_info *frame);
+#undef FRAME_SAVED_PC
+#define FRAME_SAVED_PC(FRAME) (i386go32_frame_saved_pc ((FRAME)))
+
+/* Support for longjmp. */
+
+/* Details about jmp_buf. It's supposed to be an array of integers. */
+
+#define JB_ELEMENT_SIZE 4 /* Size of elements in jmp_buf. */
+#define JB_PC 8 /* Array index of saved PC inside jmp_buf. */
+
+/* Figure out where the longjmp will land. Slurp the args out of the
+ stack. We expect the first arg to be a pointer to the jmp_buf
+ structure from which we extract the pc (JB_PC) that we will land
+ at. The pc is copied into ADDR. This routine returns true on
+ success. */
+
+#define GET_LONGJMP_TARGET(addr) get_longjmp_target (addr)
+extern int get_longjmp_target (CORE_ADDR *addr);
+
+#endif /* TM_GO32_H */
diff --git a/gdb/config/i386/tm-i386.h b/gdb/config/i386/tm-i386.h
new file mode 100644
index 00000000000..f9326fecb9a
--- /dev/null
+++ b/gdb/config/i386/tm-i386.h
@@ -0,0 +1,379 @@
+/* Macro definitions for GDB on an Intel i[345]86.
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001
+ 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. */
+
+#ifndef TM_I386_H
+#define TM_I386_H 1
+
+#define GDB_MULTI_ARCH GDB_MULTI_ARCH_PARTIAL
+
+#include "regcache.h"
+
+/* Forward declarations for prototypes. */
+struct frame_info;
+struct frame_saved_regs;
+struct value;
+struct type;
+
+/* The format used for `long double' on almost all i386 targets is the
+ i387 extended floating-point format. In fact, of all targets in the
+ GCC 2.95 tree, only OSF/1 does it different, and insists on having
+ a `long double' that's not `long' at all. */
+
+#define TARGET_LONG_DOUBLE_FORMAT &floatformat_i387_ext
+
+/* Although the i386 extended floating-point has only 80 significant
+ bits, a `long double' actually takes up 96, probably to enforce
+ alignment. */
+
+#define TARGET_LONG_DOUBLE_BIT 96
+
+/* Number of traps that happen between exec'ing the shell to run an
+ inferior, and when we finally get to the inferior code. This is 2
+ on most implementations. */
+
+#define START_INFERIOR_TRAPS_EXPECTED 2
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions to reach some
+ "real" code. */
+
+#define SKIP_PROLOGUE(frompc) (i386_skip_prologue (frompc))
+
+extern int i386_skip_prologue (int);
+
+/* Immediately after a function call, return the saved pc. */
+
+#define SAVED_PC_AFTER_CALL(frame) i386_saved_pc_after_call (frame)
+extern CORE_ADDR i386_saved_pc_after_call (struct frame_info *frame);
+
+/* Stack grows downward. */
+
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+/* Sequence of bytes for breakpoint instruction. */
+
+#define BREAKPOINT {0xcc}
+
+/* Amount PC must be decremented by after a breakpoint. This is often the
+ number of bytes in BREAKPOINT but not always. */
+
+#define DECR_PC_AFTER_BREAK 1
+
+/* Say how long (ordinary) registers are. This is a piece of bogosity
+ used in push_word and a few other places; REGISTER_RAW_SIZE is the
+ real way to know how big a register is. */
+
+#define REGISTER_SIZE 4
+
+/* This register file is parameterized by two macros:
+ HAVE_I387_REGS --- register file should include i387 registers
+ HAVE_SSE_REGS --- register file should include SSE registers
+ If HAVE_SSE_REGS is #defined, then HAVE_I387_REGS must also be #defined.
+
+ However, GDB code should not test those macros with #ifdef, since
+ that makes code which is annoying to multi-arch. Instead, GDB code
+ should check the values of NUM_GREGS, NUM_FREGS, and NUM_SSE_REGS,
+ which will eventually get mapped onto architecture vector entries.
+
+ It's okay to use the macros in tm-*.h files, though, since those
+ files will get completely replaced when we multi-arch anyway. */
+
+/* Number of general registers, present on every 32-bit x86 variant. */
+#define NUM_GREGS (16)
+
+/* Number of floating-point unit registers. */
+#ifdef HAVE_I387_REGS
+#define NUM_FREGS (16)
+#else
+#define NUM_FREGS (0)
+#endif
+
+/* Number of SSE registers. */
+#ifdef HAVE_SSE_REGS
+#define NUM_SSE_REGS (9)
+#else
+#define NUM_SSE_REGS (0)
+#endif
+
+/* Largest number of registers we could have in any configuration. */
+#define MAX_NUM_REGS (16 + 16 + 9)
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define FP_REGNUM 5 /* (ebp) Contains address of executing stack
+ frame */
+#define SP_REGNUM 4 /* (usp) Contains address of top of stack */
+#define PC_REGNUM 8 /* (eip) Contains program counter */
+#define PS_REGNUM 9 /* (ps) Contains processor status */
+
+/* First FPU data register. */
+#ifdef HAVE_I387_REGS
+#define FP0_REGNUM 16
+#else
+#define FP0_REGNUM 0
+#endif
+
+/* Return the name of register REG. */
+
+#define REGISTER_NAME(reg) i386_register_name ((reg))
+extern char *i386_register_name (int reg);
+
+/* Use the "default" register numbering scheme for stabs and COFF. */
+
+#define STAB_REG_TO_REGNUM(reg) i386_stab_reg_to_regnum ((reg))
+#define SDB_REG_TO_REGNUM(reg) i386_stab_reg_to_regnum ((reg))
+extern int i386_stab_reg_to_regnum (int reg);
+
+/* Use the DWARF register numbering scheme for DWARF and DWARF 2. */
+
+#define DWARF_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg))
+#define DWARF2_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg))
+extern int i386_dwarf_reg_to_regnum (int reg);
+
+/* We don't define ECOFF_REG_TO_REGNUM, since ECOFF doesn't seem to be
+ in use on any of the supported i386 targets. */
+
+
+/* Sizes of individual register sets. These cover the entire register
+ file, so summing up the sizes of those portions actually present
+ yields REGISTER_BYTES. */
+#define SIZEOF_GREGS (NUM_GREGS * 4)
+#define SIZEOF_FPU_REGS (8 * 10)
+#define SIZEOF_FPU_CTRL_REGS (8 * 4)
+#define SIZEOF_SSE_REGS (8 * 16 + 4)
+
+
+/* Total amount of space needed to store our copies of the machine's register
+ state, the array `registers'. */
+#ifdef HAVE_SSE_REGS
+#define REGISTER_BYTES \
+ (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS + SIZEOF_SSE_REGS)
+#else
+#ifdef HAVE_I387_REGS
+#define REGISTER_BYTES (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS)
+#else
+#define REGISTER_BYTES (SIZEOF_GREGS)
+#endif
+#endif
+
+/* Return the offset into the register array of the start of register
+ number REG. */
+#define REGISTER_BYTE(reg) i386_register_byte ((reg))
+extern int i386_register_byte (int reg);
+
+/* Return the number of bytes of storage in GDB's register array
+ occupied by register REG. */
+#define REGISTER_RAW_SIZE(reg) i386_register_raw_size ((reg))
+extern int i386_register_raw_size (int reg);
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+#define MAX_REGISTER_RAW_SIZE 16
+
+/* Return the size in bytes of the virtual type of register REG. */
+#define REGISTER_VIRTUAL_SIZE(reg) i386_register_virtual_size ((reg))
+extern int i386_register_virtual_size (int reg);
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+#define MAX_REGISTER_VIRTUAL_SIZE 16
+
+/* Return the GDB type object for the "standard" data type of data in
+ register REGNUM. */
+
+#define REGISTER_VIRTUAL_TYPE(regnum) i386_register_virtual_type (regnum)
+extern struct type *i386_register_virtual_type (int regnum);
+
+/* Return true iff register REGNUM's virtual format is different from
+ its raw format. */
+
+#define REGISTER_CONVERTIBLE(regnum) i386_register_convertible (regnum)
+extern int i386_register_convertible (int regnum);
+
+/* Convert data from raw format for register REGNUM in buffer FROM to
+ virtual format with type TYPE in buffer TO. */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(regnum, type, from, to) \
+ i386_register_convert_to_virtual ((regnum), (type), (from), (to))
+extern void i386_register_convert_to_virtual (int regnum, struct type *type,
+ char *from, char *to);
+
+/* Convert data from virtual format with type TYPE in buffer FROM to
+ raw format for register REGNUM in buffer TO. */
+
+#define REGISTER_CONVERT_TO_RAW(type, regnum, from, to) \
+ i386_register_convert_to_raw ((type), (regnum), (from), (to))
+extern void i386_register_convert_to_raw (struct type *type, int regnum,
+ char *from, char *to);
+
+/* Print out the i387 floating point state. */
+#ifdef HAVE_I387_REGS
+extern void i387_float_info (void);
+#define FLOAT_INFO { i387_float_info (); }
+#endif
+
+
+#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
+ i386_push_arguments ((nargs), (args), (sp), (struct_return), (struct_addr))
+extern CORE_ADDR i386_push_arguments (int nargs, struct value **args,
+ CORE_ADDR sp, int struct_return,
+ CORE_ADDR struct_addr);
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(addr, sp) \
+ i386_store_struct_return ((addr), (sp))
+extern void i386_store_struct_return (CORE_ADDR addr, CORE_ADDR sp);
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. */
+
+#define EXTRACT_RETURN_VALUE(type, regbuf, valbuf) \
+ i386_extract_return_value ((type), (regbuf), (valbuf))
+extern void i386_extract_return_value (struct type *type, char *regbuf,
+ char *valbuf);
+
+/* Write into the appropriate registers a function return value stored
+ in VALBUF of type TYPE, given in virtual format. */
+
+#define STORE_RETURN_VALUE(type, valbuf) \
+ i386_store_return_value ((type), (valbuf))
+extern void i386_store_return_value (struct type *type, char *valbuf);
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR. */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(regbuf) \
+ i386_extract_struct_value_address ((regbuf))
+extern CORE_ADDR i386_extract_struct_value_address (char *regbuf);
+
+/* The following redefines make backtracing through sigtramp work.
+ They manufacture a fake sigtramp frame and obtain the saved pc in sigtramp
+ from the sigcontext structure which is pushed by the kernel on the
+ user stack, along with a pointer to it. */
+
+/* Return the chain-pointer for FRAME. In the case of the i386, the
+ frame's nominal address is the address of a 4-byte word containing
+ the calling frame's address. */
+
+#define FRAME_CHAIN(frame) i386_frame_chain ((frame))
+extern CORE_ADDR i386_frame_chain (struct frame_info *frame);
+
+/* Determine whether the function invocation represented by FRAME does
+ not have a from on the stack associated with it. If it does not,
+ return non-zero, otherwise return zero. */
+
+#define FRAMELESS_FUNCTION_INVOCATION(frame) \
+ i386_frameless_function_invocation (frame)
+extern int i386_frameless_function_invocation (struct frame_info *frame);
+
+/* Return the saved program counter for FRAME. */
+
+#define FRAME_SAVED_PC(frame) i386_frame_saved_pc (frame)
+extern CORE_ADDR i386_frame_saved_pc (struct frame_info *frame);
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Return number of args passed to a frame. Can return -1, meaning no way
+ to tell, which is typical now that the C compiler delays popping them. */
+
+#define FRAME_NUM_ARGS(fi) (i386_frame_num_args(fi))
+
+extern int i386_frame_num_args (struct frame_info *);
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#define FRAME_ARGS_SKIP 8
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame. */
+
+extern void i386_frame_init_saved_regs (struct frame_info *);
+#define FRAME_INIT_SAVED_REGS(FI) i386_frame_init_saved_regs (FI)
+
+
+
+/* Things needed for making the inferior call functions. */
+
+/* "An argument's size is increased, if necessary, to make it a
+ multiple of [32 bit] words. This may require tail padding,
+ depending on the size of the argument" - from the x86 ABI. */
+#define PARM_BOUNDARY 32
+
+/* Push an empty stack frame, to record the current PC, etc. */
+
+#define PUSH_DUMMY_FRAME { i386_push_dummy_frame (); }
+
+extern void i386_push_dummy_frame (void);
+
+/* Discard from the stack the innermost frame, restoring all registers. */
+
+#define POP_FRAME { i386_pop_frame (); }
+
+extern void i386_pop_frame (void);
+
+
+/* this is
+ * call 11223344 (32 bit relative)
+ * int3
+ */
+
+#define CALL_DUMMY { 0x223344e8, 0xcc11 }
+
+#define CALL_DUMMY_LENGTH 8
+
+#define CALL_DUMMY_START_OFFSET 0 /* Start execution at beginning of dummy */
+
+#define CALL_DUMMY_BREAKPOINT_OFFSET 5
+
+/* Insert the specified number of args and function address
+ into a call sequence of the above form stored at DUMMYNAME. */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \
+ i386_fix_call_dummy (dummyname, pc, fun, nargs, args, type, gcc_p)
+extern void i386_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun,
+ int nargs, struct value **args,
+ struct type *type, int gcc_p);
+
+/* FIXME: kettenis/2000-06-12: These do not belong here. */
+extern void print_387_control_word (unsigned int);
+extern void print_387_status_word (unsigned int);
+
+/* Offset from SP to first arg on stack at first instruction of a function */
+
+#define SP_ARG0 (1 * 4)
+
+#endif /* ifndef TM_I386_H */
diff --git a/gdb/config/i386/tm-i386aix.h b/gdb/config/i386/tm-i386aix.h
new file mode 100644
index 00000000000..a8f24eda035
--- /dev/null
+++ b/gdb/config/i386/tm-i386aix.h
@@ -0,0 +1,48 @@
+/* Macro defintions for IBM AIX PS/2 (i386).
+ Copyright 1986, 1987, 1989, 1992, 1993, 1994, 1995, 2000
+ 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. */
+
+/* Changes for IBM AIX PS/2 by Minh Tran-Le (tranle@intellicorp.com). */
+
+#ifndef TM_I386AIX_H
+#define TM_I386AIX_H 1
+
+#include "i386/tm-i386.h"
+#include <sys/reg.h>
+
+#ifndef I386
+#define I386 1
+#endif
+
+/* AIX/i386 has FPU support. However, the native configuration (which
+ is the only supported configuration) doesn't make the FPU control
+ registers available. Override the appropriate symbols such that
+ only the normal FPU registers are included in GDB's register array. */
+
+#undef NUM_FPREGS
+#define NUM_FPREGS (8)
+
+#undef NUM_REGS
+#define NUM_REGS (NUM_GREGS + NUM_FPREGS)
+
+#undef REGISTER_BYTES
+#define REGISTER_BYTES (SIZEOF_GREGS + SIZEOF_FPU_REGS)
+
+#endif /* TM_I386AIX_H */
diff --git a/gdb/config/i386/tm-i386bsd.h b/gdb/config/i386/tm-i386bsd.h
new file mode 100644
index 00000000000..e2b2229efa7
--- /dev/null
+++ b/gdb/config/i386/tm-i386bsd.h
@@ -0,0 +1,45 @@
+/* Macro definitions for i386 running under BSD Unix.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996
+ 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. */
+
+#ifndef TM_I386BSD_H
+#define TM_I386BSD_H 1
+
+#include "i386/tm-i386.h"
+
+/* 386BSD cannot handle the segment registers. */
+/* BSDI can't handle them either. */
+
+#undef NUM_REGS
+#define NUM_REGS 10
+
+/* On 386 bsd, sigtramp is above the user stack and immediately below
+ the user area. Using constants here allows for cross debugging.
+ These are tested for BSDI but should work on 386BSD. */
+
+#define SIGTRAMP_START(pc) 0xfdbfdfc0
+#define SIGTRAMP_END(pc) 0xfdbfe000
+
+/* Saved Pc. Get it from sigcontext if within sigtramp. */
+
+/* Offset to saved PC in sigcontext, from <sys/signal.h>. */
+#define SIGCONTEXT_PC_OFFSET 20
+
+#endif /* ifndef TM_I386BSD_H */
diff --git a/gdb/config/i386/tm-i386gnu.h b/gdb/config/i386/tm-i386gnu.h
new file mode 100644
index 00000000000..00cb5a9f100
--- /dev/null
+++ b/gdb/config/i386/tm-i386gnu.h
@@ -0,0 +1,56 @@
+/* Macro definitions for i386 running the GNU Hurd.
+ Copyright 1992, 1999, 2000 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. */
+
+#ifndef TM_I386GNU_H
+#define TM_I386GNU_H 1
+
+/* Include common definitions for GNU systems.
+ FIXME: This does not belong here since this is supposed to contain
+ only native-dependent information. */
+#include "nm-gnu.h"
+
+/* Thread flavors used in re-setting the T bit.
+ FIXME: This is native-dependent. */
+#define THREAD_STATE_FLAVOR i386_REGS_SEGS_STATE
+#define THREAD_STATE_SIZE i386_THREAD_STATE_COUNT
+#define THREAD_STATE_SET_TRACED(state) \
+ ((struct i386_thread_state *)state)->efl |= 0x100
+#define THREAD_STATE_CLEAR_TRACED(state) \
+ ((((struct i386_thread_state *)state)->efl &= ~0x100), 1)
+
+/* We can attach and detach.
+ FIXME: This is probably native-dependent too. */
+#define ATTACH_DETACH 1
+
+#define HAVE_I387_REGS
+#include "i386/tm-i386.h"
+
+/* We use stabs-in-ELF with the DWARF register numbering scheme. */
+
+#undef STAB_REG_TO_REGNUM
+#define STAB_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg))
+
+/* Offset to saved PC in sigcontext. */
+#define SIGCONTEXT_PC_OFFSET 68
+
+/* We need this file for the SOLIB_TRAMPOLINE stuff. */
+#include "tm-sysv4.h"
+
+#endif /* TM_I386GNU_H */
diff --git a/gdb/config/i386/tm-i386lynx.h b/gdb/config/i386/tm-i386lynx.h
new file mode 100644
index 00000000000..842f9a7738d
--- /dev/null
+++ b/gdb/config/i386/tm-i386lynx.h
@@ -0,0 +1,34 @@
+/* Macro definitions for Intel 386 running under LynxOS.
+ Copyright 1993, 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. */
+
+#ifndef TM_I386LYNX_H
+#define TM_I386LYNX_H
+
+#include "tm-lynx.h"
+
+/* Most definitions from sysv could be used. */
+#include "i386/tm-i386.h"
+
+#undef SAVED_PC_AFTER_CALL
+
+#define SAVED_PC_AFTER_CALL i386lynx_saved_pc_after_call
+CORE_ADDR i386lynx_saved_pc_after_call ();
+
+#endif /* TM_I386LYNX_H */
diff --git a/gdb/config/i386/tm-i386m3.h b/gdb/config/i386/tm-i386m3.h
new file mode 100644
index 00000000000..edc301da446
--- /dev/null
+++ b/gdb/config/i386/tm-i386m3.h
@@ -0,0 +1,56 @@
+/* Macro definitions for i386, Mach 3.0
+ Copyright 1992, 1993, 1995, 1999 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 common definitions for Mach3 systems */
+#include "nm-m3.h"
+
+/* Define offsets to access CPROC stack when it does not have
+ * a kernel thread.
+ */
+#define MACHINE_CPROC_SP_OFFSET 20
+#define MACHINE_CPROC_PC_OFFSET 16
+#define MACHINE_CPROC_FP_OFFSET 12
+
+/* Thread flavors used in re-setting the T bit.
+ * @@ this is also bad for cross debugging.
+ */
+#define TRACE_FLAVOR i386_THREAD_STATE
+#define TRACE_FLAVOR_SIZE i386_THREAD_STATE_COUNT
+#define TRACE_SET(x,state) \
+ ((struct i386_thread_state *)state)->efl |= 0x100
+#define TRACE_CLEAR(x,state) \
+ ((((struct i386_thread_state *)state)->efl &= ~0x100), 1)
+
+/* we can do it */
+#define ATTACH_DETACH 1
+
+/* Sigh. There should be a file for i386 but no sysv stuff in it */
+#include "i386/tm-i386.h"
+
+/* I want to test this float info code. See comment in tm-i386v.h */
+#undef FLOAT_INFO
+#define FLOAT_INFO { i386_mach3_float_info (); }
+
+/* Address of end of stack space.
+ * for MACH, see <machine/vmparam.h>
+ * @@@ I don't know what is in the 5 ints...
+ */
+#undef STACK_END_ADDR
+#define STACK_END_ADDR (0xc0000000-sizeof(int [5]))
diff --git a/gdb/config/i386/tm-i386mk.h b/gdb/config/i386/tm-i386mk.h
new file mode 100644
index 00000000000..e46ca55395b
--- /dev/null
+++ b/gdb/config/i386/tm-i386mk.h
@@ -0,0 +1,38 @@
+/* Macro definitions for i386, Mach 3.0, OSF 1/MK
+ Copyright 1992, 1993, 2000 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. */
+
+/* Until OSF switches to a newer Mach kernel that has
+ * a different get_emul_vector() interface.
+ */
+#define MK67 1
+
+#include "i386/tm-i386m3.h"
+
+/* FIMXE: kettenis/2000-03-26: On OSF 1, `long double' is equivalent
+ to `double'. However, I'm not sure what is the consequence of:
+
+ #define TARGET_LONG_DOUBLE_FORMAT TARGET_DOUBLE_FORMAT
+ #define TARGET_LONG_DOUBLE_BIT TARGET_DOUBLE_BIT
+
+ So I'll go with the current status quo instead. It looks like this
+ target won't compile anyway. Perhaps it should be obsoleted? */
+
+#undef TARGET_LONG_DOUBLE_FORMAT
+#undef TARGET_LONG_DOUBLE_BIT
diff --git a/gdb/config/i386/tm-i386nw.h b/gdb/config/i386/tm-i386nw.h
new file mode 100644
index 00000000000..9ede2c040e0
--- /dev/null
+++ b/gdb/config/i386/tm-i386nw.h
@@ -0,0 +1,49 @@
+/* Macro definitions for i386 running NetWare.
+ Copyright 1993, 1994, 1995, 1998, 1999, 2000
+ 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. */
+
+#ifndef TM_I386NW_H
+#define TM_I386NW_H 1
+
+#include "i386/tm-i386.h"
+
+/* Stop backtracing when we wander into main. */
+
+#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi)
+
+
+/* Offsets (in target ints) into jmp_buf. Not defined in any system header
+ file, so we have to step through setjmp/longjmp with a debugger and figure
+ them out. */
+
+#define JB_ELEMENT_SIZE 4 /* jmp_buf[] is array of ints */
+
+#define JB_PC 6 /* Setjmp()'s return PC saved here */
+
+/* Figure out where the longjmp will land. Slurp the args out of the stack.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+extern int get_longjmp_target (CORE_ADDR *);
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+
+#endif /* ifndef TM_I386NW_H */
diff --git a/gdb/config/i386/tm-i386os9k.h b/gdb/config/i386/tm-i386os9k.h
new file mode 100644
index 00000000000..78fbc21a7c6
--- /dev/null
+++ b/gdb/config/i386/tm-i386os9k.h
@@ -0,0 +1,65 @@
+/* Macro definitions for i386 running under BSD Unix.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996
+ Free Software Foundation, Inc.
+
+
+ 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. */
+
+#ifndef TM_I386OS9K_H
+#define TM_I386OS9K_H 1
+
+#include "i386/tm-i386.h"
+
+/* Number of machine registers */
+
+#undef NUM_REGS
+#define NUM_REGS (16) /* Basic i*86 regs */
+
+/* Initializer for an array of names of registers. There should be at least
+ NUM_REGS strings in this initializer. Any excess ones are simply ignored.
+ The order of the first 8 registers must match the compiler's numbering
+ scheme (which is the same as the 386 scheme) and also regmap in the various
+ *-nat.c files. */
+
+#undef REGISTER_NAME
+#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \
+ "esp", "ebp", "esi", "edi", \
+ "eip", "eflags", "cs", "ss", \
+ "ds", "es", "fs", "gs", \
+ }
+
+#define DATABASE_REG 3 /* ebx */
+
+/* Amount PC must be decremented by after a breakpoint. This is often the
+ number of bytes in BREAKPOINT but not always (such as now). */
+
+#undef DECR_PC_AFTER_BREAK
+#define DECR_PC_AFTER_BREAK 0
+
+/* On 386 bsd, sigtramp is above the user stack and immediately below
+ the user area. Using constants here allows for cross debugging.
+ These are tested for BSDI but should work on 386BSD. */
+#define SIGTRAMP_START(pc) 0xfdbfdfc0
+#define SIGTRAMP_END(pc) 0xfdbfe000
+
+/* Saved Pc. Get it from sigcontext if within sigtramp. */
+
+/* Offset to saved PC in sigcontext, from <sys/signal.h>. */
+#define SIGCONTEXT_PC_OFFSET 20
+
+#define BELIEVE_PCC_PROMOTION 1
+
+#endif /* #ifndef TM_I386OS9K_H */
diff --git a/gdb/config/i386/tm-i386sco5.h b/gdb/config/i386/tm-i386sco5.h
new file mode 100644
index 00000000000..e4cb014e990
--- /dev/null
+++ b/gdb/config/i386/tm-i386sco5.h
@@ -0,0 +1,63 @@
+/* Macro definitions for GDB on an Intel i386 running SCO Open Server 5.
+ Copyright 1998 Free Software Foundation, Inc.
+ Written by J. Kean Johnston (jkj@sco.com).
+
+ 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. */
+
+#ifndef TM_I386SCO5_H
+#define TM_I386SCO5_H 1
+
+/* Pick up most of what we need from the generic i386 target include file. */
+
+#include "i386/tm-i386.h"
+
+/* Pick up more stuff from the generic SYSV and SVR4 host include files. */
+#include "i386/tm-i386v.h"
+#include "tm-sysv4.h"
+
+#define KERNEL_U_SIZE kernel_u_size()
+
+/*
+ * SCO is unlike other SVR3 targets in that it has SVR4 style shared
+ * libs, with a slight twist. We expect 3 traps (2 for the exec and
+ * one for the dynamic loader). After the third trap we insert the
+ * SOLIB breakpoints, then wait for the 4th trap.
+ */
+#undef START_INFERIOR_TRAPS_EXPECTED
+#define START_INFERIOR_TRAPS_EXPECTED 3
+
+/* We can also do hardware watchpoints */
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1
+
+/* After a watchpoint trap, the PC points to the instruction which
+ caused the trap. But we can continue over it without disabling the
+ trap. */
+#define HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_STEPPABLE_WATCHPOINT
+
+#define STOPPED_BY_WATCHPOINT(W) \
+ i386_stopped_by_watchpoint (PIDGET (inferior_ptid))
+
+#define target_insert_watchpoint(addr, len, type) \
+ i386_insert_watchpoint (PIDGET (inferior_ptid), addr, len, type)
+
+#define target_remove_watchpoint(addr, len, type) \
+ i386_remove_watchpoint (PIDGET (inferior_ptid), addr, len)
+
+#endif /* ifndef TM_I386SCO5_H */
diff --git a/gdb/config/i386/tm-i386sol2.h b/gdb/config/i386/tm-i386sol2.h
new file mode 100644
index 00000000000..c90e0d475ae
--- /dev/null
+++ b/gdb/config/i386/tm-i386sol2.h
@@ -0,0 +1,59 @@
+/* Macro definitions for GDB on an Intel i386 running Solaris 2.
+ Copyright 1998, 1999, 2000 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. */
+
+#ifndef TM_I386SOL2_H
+#define TM_I386SOL2_H 1
+
+#define HAVE_I387_REGS
+#include "i386/tm-i386v4.h"
+
+/* We use stabs-in-ELF with the DWARF register numbering scheme. */
+
+#undef STAB_REG_TO_REGNUM
+#define STAB_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg))
+
+/* If the current gcc for for this target does not produce correct
+ debugging information for float parameters, both prototyped and
+ unprototyped, then define this macro. This forces gdb to always
+ assume that floats are passed as doubles and then converted in the
+ callee. */
+
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (1)
+
+/* Signal handler frames under Solaris 2 are recognized by a return address
+ of 0xFFFFFFFF, the third parameter on the signal handler stack is
+ a pointer to an ucontext. */
+#undef sigtramp_saved_pc
+#undef I386V4_SIGTRAMP_SAVED_PC
+#define SIGCONTEXT_PC_OFFSET (36 + 14 * 4)
+#undef IN_SIGTRAMP
+#define IN_SIGTRAMP(pc, name) (pc == 0xFFFFFFFF)
+
+/* The SunPRO compiler puts out 0 instead of the address in N_SO symbols,
+ and for SunPRO 3.0, N_FUN symbols too. */
+#define SOFUN_ADDRESS_MAYBE_MISSING
+
+extern char *sunpro_static_transform_name (char *);
+#define STATIC_TRANSFORM_NAME(x) sunpro_static_transform_name (x)
+#define IS_STATIC_TRANSFORM_NAME(name) ((name)[0] == '.')
+
+#define FAULTED_USE_SIGINFO
+
+#endif /* ifndef TM_I386SOL2_H */
diff --git a/gdb/config/i386/tm-i386v.h b/gdb/config/i386/tm-i386v.h
new file mode 100644
index 00000000000..d524652e247
--- /dev/null
+++ b/gdb/config/i386/tm-i386v.h
@@ -0,0 +1,36 @@
+/* Macro definitions for i386, Unix System V.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1998, 1999,
+ 2000, 2001 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. */
+
+#ifndef TM_I386V_H
+#define TM_I386V_H 1
+
+/* First pick up the generic *86 target file. */
+
+#include "i386/tm-i386.h"
+
+/* Number of traps that happen between exec'ing the shell to run an
+ inferior, and when we finally get to the inferior code. This is
+ 2 on most implementations. Override here to 4. */
+
+#undef START_INFERIOR_TRAPS_EXPECTED
+#define START_INFERIOR_TRAPS_EXPECTED 4
+
+#endif /* ifndef TM_I386V_H */
diff --git a/gdb/config/i386/tm-i386v4.h b/gdb/config/i386/tm-i386v4.h
new file mode 100644
index 00000000000..2003b96de2e
--- /dev/null
+++ b/gdb/config/i386/tm-i386v4.h
@@ -0,0 +1,79 @@
+/* Macro definitions for GDB on an Intel i386 running SVR4.
+ Copyright 1991, 1994, 1995, 1998, 1999, 2000
+ Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus Support (fnf@cygnus.com)
+
+ 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. */
+
+#ifndef TM_I386V4_H
+#define TM_I386V4_H 1
+
+/* Pick up most of what we need from the generic i386 target include file. */
+#define HAVE_I387_REGS
+#include "i386/tm-i386.h"
+
+/* Pick up more stuff from the generic SVR4 host include file. */
+
+#include "tm-sysv4.h"
+
+/* Use the alternate method of determining valid frame chains. */
+
+#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi)
+
+/* Offsets (in target ints) into jmp_buf. Not defined in any system header
+ file, so we have to step through setjmp/longjmp with a debugger and figure
+ them out. Note that <setjmp> defines _JBLEN as 10, which is the default
+ if no specific machine is selected, even though we only use 6 slots. */
+
+#define JB_ELEMENT_SIZE sizeof(int) /* jmp_buf[_JBLEN] is array of ints */
+
+#define JB_EBX 0
+#define JB_ESI 1
+#define JB_EDI 2
+#define JB_EBP 3
+#define JB_ESP 4
+#define JB_EDX 5
+
+#define JB_PC JB_EDX /* Setjmp()'s return PC saved in EDX */
+
+/* Figure out where the longjmp will land. Slurp the args out of the stack.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+extern int get_longjmp_target (CORE_ADDR *);
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+
+/* The following redefines make backtracing through sigtramp work.
+ They manufacture a fake sigtramp frame and obtain the saved pc in sigtramp
+ from the ucontext structure which is pushed by the kernel on the
+ user stack. Unfortunately there are three variants of sigtramp handlers. */
+
+#define I386V4_SIGTRAMP_SAVED_PC
+#define IN_SIGTRAMP(pc, name) ((name) \
+ && (STREQ ("_sigreturn", name) \
+ || STREQ ("_sigacthandler", name) \
+ || STREQ ("sigvechandler", name)))
+
+/* Saved Pc. Get it from ucontext if within sigtramp. */
+
+#define sigtramp_saved_pc i386v4_sigtramp_saved_pc
+extern CORE_ADDR i386v4_sigtramp_saved_pc (struct frame_info *);
+
+#endif /* ifndef TM_I386V4_H */
diff --git a/gdb/config/i386/tm-i386v42mp.h b/gdb/config/i386/tm-i386v42mp.h
new file mode 100644
index 00000000000..5671e42944c
--- /dev/null
+++ b/gdb/config/i386/tm-i386v42mp.h
@@ -0,0 +1,93 @@
+/* Macro definitions for GDB on an Intel i386 running SVR4.2MP
+ Copyright 1991, 1994, 1997, 1999, 2000 Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus Support (fnf@cygnus.com)
+
+ 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. */
+
+#ifndef TM_I386V42MP_H
+#define TM_I386V42MP_H 1
+
+/* pick up more generic x86 sysv4 stuff */
+
+#include "i386/tm-i386v4.h"
+
+/* define to select for other sysv4.2mp weirdness (see procfs.c) */
+
+#define UNIXWARE
+
+#if 0
+/* The following macros extract process and lwp/thread ids from a
+ composite id.
+
+ For consistency with UnixWare core files, allocate bits 0-15 for
+ process ids and bits 16 and up for lwp ids. Reserve bit 31 for
+ negative return values to indicate exceptions, and use bit 30 as a
+ flag to indicate a user-mode thread, leaving 14 bits for lwp
+ ids. */
+
+/* Number of bits in composite id allocated to process number. */
+#define PIDBITS 16
+
+/* Return the process id stored in composite PID. */
+#define PIDGET(PID) (((PID) & ((1 << PIDBITS) - 1)))
+
+/* Return the thread or lwp id stored in composite PID. */
+#define TIDGET(PID) (((PID) & 0x3fffffff) >> PIDBITS)
+#define LIDGET(PID) TIDGET(PID)
+
+/* Construct a composite id from lwp LID and the process portion of
+ composite PID. */
+#define MERGEPID(PID, LID) (PIDGET(PID) | ((LID) << PIDBITS))
+#define MKLID(PID, LID) MERGEPID(PID, LID)
+
+/* Construct a composite id from thread TID and the process portion of
+ composite PID. */
+#define MKTID(PID, TID) (MERGEPID(PID, TID) | 0x40000000)
+
+/* Return whether PID contains a user-space thread id. */
+#define ISTID(PID) ((PID) & 0x40000000)
+#endif
+
+/* New definitions of the ptid stuff. Due to the way the
+ code is structured in uw-thread.c, I'm overloading the thread id
+ and lwp id onto the lwp field. The tid field is used to indicate
+ whether the lwp is a tid or not.
+
+ FIXME: Check that core file support is not broken. (See original
+ #if 0'd comments above.)
+ FIXME: Restructure uw-thread.c so that the struct ptid fields
+ can be used as intended. */
+
+/* Return the process id stored in composite PID. */
+#define PIDGET(PID) (ptid_get_pid (PID))
+
+/* Return the thread or lwp id stored in composite PID. */
+#define TIDGET(PID) (ptid_get_lwp (PID))
+#define LIDGET(PID) TIDGET(PID)
+
+#define MERGEPID(PID, LID) (ptid_build ((PID), (LID), 0))
+#define MKLID(PID, LID) (ptid_build ((PID), (LID), 0))
+
+/* Construct a composite id from thread TID and the process portion of
+ composite PID. */
+#define MKTID(PID, TID) (ptid_build ((PID), (TID), 1))
+
+/* Return whether PID contains a user-space thread id. */
+#define ISTID(PID) (ptid_get_tid (PID))
+
+#endif /* ifndef TM_I386V42MP_H */
diff --git a/gdb/config/i386/tm-linux.h b/gdb/config/i386/tm-linux.h
new file mode 100644
index 00000000000..60c4b1e3e39
--- /dev/null
+++ b/gdb/config/i386/tm-linux.h
@@ -0,0 +1,131 @@
+/* Definitions to target GDB to GNU/Linux on 386.
+
+ Copyright 1992, 1993, 1995, 1996, 1998, 1999, 2000, 2001, 2002 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. */
+
+#ifndef TM_LINUX_H
+#define TM_LINUX_H
+
+#define I386_GNULINUX_TARGET
+#define HAVE_I387_REGS
+#ifdef HAVE_PTRACE_GETFPXREGS
+#define FILL_FPXREGSET
+#define HAVE_SSE_REGS
+#endif
+
+#include "i386/tm-i386.h"
+#include "tm-linux.h"
+
+/* Register number for the "orig_eax" pseudo-register. If this
+ pseudo-register contains a value >= 0 it is interpreted as the
+ system call number that the kernel is supposed to restart. */
+#define I386_LINUX_ORIG_EAX_REGNUM (NUM_GREGS + NUM_FREGS + NUM_SSE_REGS)
+
+/* Adjust a few macros to deal with this extra register. */
+
+#undef NUM_REGS
+#define NUM_REGS (NUM_GREGS + NUM_FREGS + NUM_SSE_REGS + 1)
+
+#undef MAX_NUM_REGS
+#define MAX_NUM_REGS (16 + 16 + 9 + 1)
+
+#undef REGISTER_BYTES
+#define REGISTER_BYTES \
+ (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS + SIZEOF_SSE_REGS + 4)
+
+#undef REGISTER_NAME
+#define REGISTER_NAME(reg) i386_linux_register_name ((reg))
+extern char *i386_linux_register_name (int reg);
+
+#undef REGISTER_BYTE
+#define REGISTER_BYTE(reg) i386_linux_register_byte ((reg))
+extern int i386_linux_register_byte (int reg);
+
+#undef REGISTER_RAW_SIZE
+#define REGISTER_RAW_SIZE(reg) i386_linux_register_raw_size ((reg))
+extern int i386_linux_register_raw_size (int reg);
+
+/* GNU/Linux ELF uses stabs-in-ELF with the DWARF register numbering
+ scheme by default, so we must redefine STAB_REG_TO_REGNUM. This
+ messes up the floating-point registers for a.out, but there is not
+ much we can do about that. */
+#undef STAB_REG_TO_REGNUM
+#define STAB_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg))
+
+/* Use target_specific function to define link map offsets. */
+extern struct link_map_offsets *i386_linux_svr4_fetch_link_map_offsets (void);
+#define SVR4_FETCH_LINK_MAP_OFFSETS() i386_linux_svr4_fetch_link_map_offsets ()
+
+/* The following works around a problem with /usr/include/sys/procfs.h */
+#define sys_quotactl 1
+
+/* When the i386 Linux kernel calls a signal handler, the return
+ address points to a bit of code on the stack. These definitions
+ are used to identify this bit of code as a signal trampoline in
+ order to support backtracing through calls to signal handlers. */
+
+#define IN_SIGTRAMP(pc, name) i386_linux_in_sigtramp (pc, name)
+extern int i386_linux_in_sigtramp (CORE_ADDR, char *);
+
+#undef FRAME_CHAIN
+#define FRAME_CHAIN(frame) i386_linux_frame_chain (frame)
+extern CORE_ADDR i386_linux_frame_chain (struct frame_info *frame);
+
+#undef FRAME_SAVED_PC
+#define FRAME_SAVED_PC(frame) i386_linux_frame_saved_pc (frame)
+extern CORE_ADDR i386_linux_frame_saved_pc (struct frame_info *frame);
+
+#undef SAVED_PC_AFTER_CALL
+#define SAVED_PC_AFTER_CALL(frame) i386_linux_saved_pc_after_call (frame)
+extern CORE_ADDR i386_linux_saved_pc_after_call (struct frame_info *);
+
+#define TARGET_WRITE_PC(pc, ptid) i386_linux_write_pc (pc, ptid)
+extern void i386_linux_write_pc (CORE_ADDR pc, ptid_t ptid);
+
+/* When we call a function in a shared library, and the PLT sends us
+ into the dynamic linker to find the function's real address, we
+ need to skip over the dynamic linker call. This function decides
+ when to skip, and where to skip to. See the comments for
+ SKIP_SOLIB_RESOLVER at the top of infrun.c. */
+#define SKIP_SOLIB_RESOLVER i386_linux_skip_solib_resolver
+extern CORE_ADDR i386_linux_skip_solib_resolver (CORE_ADDR pc);
+
+/* N_FUN symbols in shared libaries have 0 for their values and need
+ to be relocated. */
+#define SOFUN_ADDRESS_MAYBE_MISSING
+
+
+/* Support for longjmp. */
+
+/* Details about jmp_buf. It's supposed to be an array of integers. */
+
+#define JB_ELEMENT_SIZE 4 /* Size of elements in jmp_buf. */
+#define JB_PC 5 /* Array index of saved PC. */
+
+/* Figure out where the longjmp will land. Slurp the args out of the
+ stack. We expect the first arg to be a pointer to the jmp_buf
+ structure from which we extract the pc (JB_PC) that we will land
+ at. The pc is copied into ADDR. This routine returns true on
+ success. */
+
+#define GET_LONGJMP_TARGET(addr) get_longjmp_target (addr)
+extern int get_longjmp_target (CORE_ADDR *addr);
+
+#endif /* #ifndef TM_LINUX_H */
diff --git a/gdb/config/i386/tm-nbsd.h b/gdb/config/i386/tm-nbsd.h
new file mode 100644
index 00000000000..b4fb7542830
--- /dev/null
+++ b/gdb/config/i386/tm-nbsd.h
@@ -0,0 +1,64 @@
+/* Macro definitions for i386 running under NetBSD.
+ Copyright 1994, 1996, 2000, 2002 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. */
+
+#ifndef TM_NBSD_H
+#define TM_NBSD_H
+
+#define HAVE_I387_REGS
+#define HAVE_SSE_REGS
+
+#include "i386/tm-i386.h"
+
+#define JB_ELEMENT_SIZE sizeof(int) /* jmp_buf[_JBLEN] is array of ints */
+#define JB_PC 0 /* Setjmp()'s return PC saved here */
+
+/* Figure out where the longjmp will land. Slurp the args out of the stack.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+extern int get_longjmp_target (CORE_ADDR *);
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+
+
+/* Support for signal handlers. */
+
+#define IN_SIGTRAMP(pc, name) i386bsd_in_sigtramp (pc, name)
+extern int i386bsd_in_sigtramp (CORE_ADDR pc, char *name);
+
+/* These defines allow the recognition of sigtramps as a function name
+ <sigtramp>.
+
+ FIXME: kettenis/2001-07-13: These should be added to the target
+ vector and turned into functions when we go "multi-arch". */
+
+#define SIGTRAMP_START(pc) i386bsd_sigtramp_start
+#define SIGTRAMP_END(pc) i386bsd_sigtramp_end
+extern CORE_ADDR i386bsd_sigtramp_start;
+extern CORE_ADDR i386bsd_sigtramp_end;
+
+/* Override FRAME_SAVED_PC to enable the recognition of signal handlers. */
+
+#undef FRAME_SAVED_PC
+#define FRAME_SAVED_PC(frame) i386bsd_frame_saved_pc (frame)
+extern CORE_ADDR i386bsd_frame_saved_pc (struct frame_info *frame);
+
+#endif /* TM_NBSD_H */
diff --git a/gdb/config/i386/tm-nbsdaout.h b/gdb/config/i386/tm-nbsdaout.h
new file mode 100644
index 00000000000..95fe2e74a5b
--- /dev/null
+++ b/gdb/config/i386/tm-nbsdaout.h
@@ -0,0 +1,34 @@
+/* Macro definitions for i386 running under NetBSD.
+ Copyright 2000, 2002 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. */
+
+#ifndef TM_NBSDAOUT_H
+#define TM_NBSDAOUT_H
+
+#include "i386/tm-nbsd.h"
+
+/* Return non-zero if we are in a shared library trampoline code stub. */
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
+ (name && !strcmp(name, "_DYNAMIC"))
+
+extern use_struct_convention_fn i386nbsd_aout_use_struct_convention;
+#define USE_STRUCT_CONVENTION(gcc_p, type) \
+ i386nbsd_aout_use_struct_convention(gcc_p, type)
+
+#endif /* TM_NBSDAOUT_H */
diff --git a/gdb/config/i386/tm-obsd.h b/gdb/config/i386/tm-obsd.h
new file mode 100644
index 00000000000..d26b03bf41d
--- /dev/null
+++ b/gdb/config/i386/tm-obsd.h
@@ -0,0 +1,77 @@
+/* Target-dependent definitions for OpenBSD/i386.
+ Copyright 2001 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. */
+
+#ifndef TM_OBSD_H
+#define TM_OBSD_H
+
+#define HAVE_I387_REGS
+#include "i386/tm-i386.h"
+
+/* OpenBSD uses the old gcc convention for struct returns. */
+
+#define USE_STRUCT_CONVENTION(gcc_p, type) \
+ generic_use_struct_convention (1, type)
+
+
+/* Support for longjmp. */
+
+/* Details about jmp_buf. It's supposed to be an array of integers. */
+
+#define JB_ELEMENT_SIZE 4 /* Size of elements in jmp_buf. */
+#define JB_PC 0 /* Array index of saved PC. */
+
+/* Figure out where the longjmp will land. Store the address that
+ longjmp will jump to in *ADDR, and return non-zero if successful. */
+
+#define GET_LONGJMP_TARGET(addr) get_longjmp_target (addr)
+extern int get_longjmp_target (CORE_ADDR *addr);
+
+
+/* Support for signal handlers. */
+
+#define IN_SIGTRAMP(pc, name) i386bsd_in_sigtramp (pc, name)
+extern int i386bsd_in_sigtramp (CORE_ADDR pc, char *name);
+
+/* These defines allow the recognition of sigtramps as a function name
+ <sigtramp>.
+
+ FIXME: kettenis/2001-07-13: These should be added to the target
+ vector and turned into functions when we go "multi-arch". */
+
+#define SIGTRAMP_START(pc) i386bsd_sigtramp_start
+#define SIGTRAMP_END(pc) i386bsd_sigtramp_end
+extern CORE_ADDR i386bsd_sigtramp_start;
+extern CORE_ADDR i386bsd_sigtramp_end;
+
+/* Override FRAME_SAVED_PC to enable the recognition of signal handlers. */
+
+#undef FRAME_SAVED_PC
+#define FRAME_SAVED_PC(frame) i386bsd_frame_saved_pc (frame)
+extern CORE_ADDR i386bsd_frame_saved_pc (struct frame_info *frame);
+
+
+/* Shared library support. */
+
+/* Return non-zero if we are in a shared library trampoline code stub. */
+
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
+ (name && !strcmp(name, "_DYNAMIC"))
+
+#endif /* tm-obsd.h */
diff --git a/gdb/config/i386/tm-ptx.h b/gdb/config/i386/tm-ptx.h
new file mode 100644
index 00000000000..2a1731a161c
--- /dev/null
+++ b/gdb/config/i386/tm-ptx.h
@@ -0,0 +1,233 @@
+/* Target machine definitions for GDB on a Sequent Symmetry under ptx
+ with Weitek 1167 and i387 support.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 2000
+ Free Software Foundation, Inc.
+ Symmetry version by Jay Vosburgh (fubar@sequent.com).
+
+ 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. */
+
+#ifndef TM_PTX_H
+#define TM_PTX_H 1
+
+/* I don't know if this will work for cross-debugging, even if you do get
+ a copy of the right include file. */
+
+#include <sys/reg.h>
+
+#ifdef SEQUENT_PTX4
+#include "i386/tm-i386v4.h"
+#else /* !SEQUENT_PTX4 */
+#include "i386/tm-i386v.h"
+#endif
+
+/* Number of traps that happen between exec'ing the shell to run an
+ inferior, and when we finally get to the inferior code. This is 2
+ on most implementations. Here we have to undo what tm-i386v.h gave
+ us and restore the default. */
+
+#undef START_INFERIOR_TRAPS_EXPECTED
+#define START_INFERIOR_TRAPS_EXPECTED 2
+
+/* Amount PC must be decremented by after a breakpoint. This is often the
+ number of bytes in BREAKPOINT but not always (such as now). */
+
+#undef DECR_PC_AFTER_BREAK
+#define DECR_PC_AFTER_BREAK 0
+
+#if 0
+-- -this code can 't be used unless we know we are running native,
+since it uses host specific ptrace calls.
+/* code for 80387 fpu. Functions are from i386-dep.c, copied into
+ * symm-dep.c.
+ */
+#define FLOAT_INFO { i386_float_info(); }
+#endif
+
+/* Number of machine registers */
+
+#undef NUM_REGS
+#define NUM_REGS 49
+
+/* Initializer for an array of names of registers. There should be at least
+ NUM_REGS strings in this initializer. Any excess ones are simply ignored.
+ The order of the first 8 registers must match the compiler's numbering
+ scheme (which is the same as the 386 scheme) and also regmap in the various
+ *-nat.c files. */
+
+#undef REGISTER_NAME
+#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \
+ "esp", "ebp", "esi", "edi", \
+ "eip", "eflags", "st0", "st1", \
+ "st2", "st3", "st4", "st5", \
+ "st6", "st7", "fp1", "fp2", \
+ "fp3", "fp4", "fp5", "fp6", \
+ "fp7", "fp8", "fp9", "fp10", \
+ "fp11", "fp12", "fp13", "fp14", \
+ "fp15", "fp16", "fp17", "fp18", \
+ "fp19", "fp20", "fp21", "fp22", \
+ "fp23", "fp24", "fp25", "fp26", \
+ "fp27", "fp28", "fp29", "fp30", \
+ "fp31" }
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define EAX_REGNUM 0
+#define ECX_REGNUM 1
+#define EDX_REGNUM 2
+#define EBX_REGNUM 3
+
+#define ESP_REGNUM 4
+#define EBP_REGNUM 5
+
+#define ESI_REGNUM 6
+#define EDI_REGNUM 7
+
+#define EIP_REGNUM 8
+#define EFLAGS_REGNUM 9
+
+#define ST0_REGNUM 10
+#define ST1_REGNUM 11
+#define ST2_REGNUM 12
+#define ST3_REGNUM 13
+
+#define ST4_REGNUM 14
+#define ST5_REGNUM 15
+#define ST6_REGNUM 16
+#define ST7_REGNUM 17
+
+#define FP1_REGNUM 18 /* first 1167 register */
+/* Get %fp2 - %fp31 by addition, since they are contiguous */
+
+#undef SP_REGNUM
+#define SP_REGNUM ESP_REGNUM /* Contains address of top of stack */
+#undef FP_REGNUM
+#define FP_REGNUM EBP_REGNUM /* Contains address of executing stack frame */
+#undef PC_REGNUM
+#define PC_REGNUM EIP_REGNUM /* Contains program counter */
+#undef PS_REGNUM
+#define PS_REGNUM EFLAGS_REGNUM /* Contains processor status */
+
+/*
+ * For ptx, this is a little bit bizarre, since the register block
+ * is below the u area in memory. This means that blockend here ends
+ * up being negative (for the call from coredep.c) since the value in
+ * u.u_ar0 will be less than KERNEL_U_ADDR (and coredep.c passes us
+ * u.u_ar0 - KERNEL_U_ADDR in blockend). Since we also define
+ * FETCH_INFERIOR_REGISTERS (and supply our own functions for that),
+ * the core file case will be the only use of this function.
+ */
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+{ (addr) = ptx_register_u_addr((blockend), (regno)); }
+
+extern int ptx_register_u_addr (int, int);
+
+/* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'. 10 i*86 registers, 8 i387
+ registers, and 31 Weitek 1167 registers */
+
+#undef REGISTER_BYTES
+#define REGISTER_BYTES ((10 * 4) + (8 * 10) + (31 * 4))
+
+/* Index within `registers' of the first byte of the space for register N. */
+
+#undef REGISTER_BYTE
+#define REGISTER_BYTE(N) \
+(((N) < ST0_REGNUM) ? ((N) * 4) : \
+ ((N) < FP1_REGNUM) ? (40 + (((N) - ST0_REGNUM) * 10)) : \
+ (40 + 80 + (((N) - FP1_REGNUM) * 4)))
+
+/* Number of bytes of storage in the actual machine representation for
+ register N. All registers are 4 bytes, except 387 st(0) - st(7),
+ which are 80 bits each. */
+
+#undef REGISTER_RAW_SIZE
+#define REGISTER_RAW_SIZE(N) \
+(((N) < ST0_REGNUM) ? 4 : \
+ ((N) < FP1_REGNUM) ? 10 : \
+ 4)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#undef MAX_REGISTER_RAW_SIZE
+#define MAX_REGISTER_RAW_SIZE 10
+
+/* Nonzero if register N requires conversion
+ from raw format to virtual format. */
+
+#undef REGISTER_CONVERTIBLE
+#define REGISTER_CONVERTIBLE(N) \
+((N < ST0_REGNUM) ? 0 : \
+ (N < FP1_REGNUM) ? 1 : \
+ 0)
+
+/* Convert data from raw format for register REGNUM
+ to virtual format for register REGNUM. */
+extern const struct floatformat floatformat_i387_ext; /* from floatformat.h */
+
+#undef REGISTER_CONVERT_TO_VIRTUAL
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
+((REGNUM < ST0_REGNUM) ? (void)memcpy ((TO), (FROM), 4) : \
+ (REGNUM < FP1_REGNUM) ? (void)floatformat_to_double(&floatformat_i387_ext, \
+ (FROM),(TO)) : \
+ (void)memcpy ((TO), (FROM), 4))
+
+/* Convert data from virtual format for register REGNUM
+ to raw format for register REGNUM. */
+
+#undef REGISTER_CONVERT_TO_RAW
+#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \
+((REGNUM < ST0_REGNUM) ? (void)memcpy ((TO), (FROM), 4) : \
+ (REGNUM < FP1_REGNUM) ? (void)floatformat_from_double(&floatformat_i387_ext, \
+ (FROM),(TO)) : \
+ (void)memcpy ((TO), (FROM), 4))
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+/*
+ * Note: the 1167 registers (the last line, builtin_type_float) are
+ * generally used in pairs, with each pair being treated as a double.
+ * It it also possible to use them singly as floats. I'm not sure how
+ * in gdb to treat the register pair pseudo-doubles. -fubar
+ */
+#undef REGISTER_VIRTUAL_TYPE
+#define REGISTER_VIRTUAL_TYPE(N) \
+((N < ST0_REGNUM) ? builtin_type_int : \
+ (N < FP1_REGNUM) ? builtin_type_double : \
+ builtin_type_float)
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. */
+
+#undef EXTRACT_RETURN_VALUE
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ symmetry_extract_return_value(TYPE, REGBUF, VALBUF)
+
+/*
+ #undef FRAME_FIND_SAVED_REGS
+ #define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+ { ptx_frame_find_saved_regs((frame_info), &(frame_saved_regs)); }
+ */
+
+#endif /* ifndef TM_PTX_H */
diff --git a/gdb/config/i386/tm-ptx4.h b/gdb/config/i386/tm-ptx4.h
new file mode 100644
index 00000000000..1f221ba8e2b
--- /dev/null
+++ b/gdb/config/i386/tm-ptx4.h
@@ -0,0 +1,26 @@
+/* Target machine definitions for GDB on a Sequent Symmetry under ptx
+ with Weitek 1167 and i387 support.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994
+ Free Software Foundation, Inc.
+ Symmetry version by Jay Vosburgh (fubar@sequent.com).
+
+ 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. */
+
+#define SEQUENT_PTX4
+
+#include "tm-ptx.h"
diff --git a/gdb/config/i386/tm-symmetry.h b/gdb/config/i386/tm-symmetry.h
new file mode 100644
index 00000000000..78281819dfa
--- /dev/null
+++ b/gdb/config/i386/tm-symmetry.h
@@ -0,0 +1,325 @@
+/* Target machine definitions for GDB on a Sequent Symmetry under dynix 3.0,
+ with Weitek 1167 and i387 support.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995
+ Free Software Foundation, Inc.
+ Symmetry version by Jay Vosburgh (fubar@sequent.com).
+
+ 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. */
+
+#ifndef TM_SYMMETRY_H
+#define TM_SYMMETRY_H 1
+
+#include "regcache.h"
+#include "doublest.h"
+
+/* I don't know if this will work for cross-debugging, even if you do get
+ a copy of the right include file. */
+#include <machine/reg.h>
+
+#include "i386/tm-i386v.h"
+
+#undef START_INFERIOR_TRAPS_EXPECTED
+#define START_INFERIOR_TRAPS_EXPECTED 2
+
+/* Amount PC must be decremented by after a breakpoint. This is often the
+ number of bytes in BREAKPOINT but not always (such as now). */
+
+#undef DECR_PC_AFTER_BREAK
+#define DECR_PC_AFTER_BREAK 0
+
+#if 0
+/* --- this code can't be used unless we know we are running native,
+ since it uses host specific ptrace calls. */
+/* code for 80387 fpu. Functions are from i386-dep.c, copied into
+ * symm-dep.c.
+ */
+#define FLOAT_INFO { i386_float_info(); }
+#endif
+
+/* Number of machine registers */
+
+#undef NUM_REGS
+#define NUM_REGS 49
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer. */
+
+/* Initializer for an array of names of registers. There should be at least
+ NUM_REGS strings in this initializer. Any excess ones are simply ignored.
+ Symmetry registers are in this weird order to match the register numbers
+ in the symbol table entries. If you change the order, things will probably
+ break mysteriously for no apparent reason. Also note that the st(0)...
+ st(7) 387 registers are represented as st0...st7. */
+
+#undef REGISTER_NAME
+#define REGISTER_NAMES { "eax", "edx", "ecx", "st0", "st1", \
+ "ebx", "esi", "edi", "st2", "st3", \
+ "st4", "st5", "st6", "st7", "esp", \
+ "ebp", "eip", "eflags","fp1", "fp2", \
+ "fp3", "fp4", "fp5", "fp6", "fp7", \
+ "fp8", "fp9", "fp10", "fp11", "fp12", \
+ "fp13", "fp14", "fp15", "fp16", "fp17", \
+ "fp18", "fp19", "fp20", "fp21", "fp22", \
+ "fp23", "fp24", "fp25", "fp26", "fp27", \
+ "fp28", "fp29", "fp30", "fp31" }
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define EAX_REGNUM 0
+#define EDX_REGNUM 1
+#define ECX_REGNUM 2
+#define ST0_REGNUM 3
+#define ST1_REGNUM 4
+#define EBX_REGNUM 5
+#define ESI_REGNUM 6
+#define EDI_REGNUM 7
+#define ST2_REGNUM 8
+#define ST3_REGNUM 9
+
+#define ST4_REGNUM 10
+#define ST5_REGNUM 11
+#define ST6_REGNUM 12
+#define ST7_REGNUM 13
+
+#define FP1_REGNUM 18 /* first 1167 register */
+/* Get %fp2 - %fp31 by addition, since they are contiguous */
+
+#undef SP_REGNUM
+#define SP_REGNUM 14 /* (usp) Contains address of top of stack */
+#define ESP_REGNUM 14
+#undef FP_REGNUM
+#define FP_REGNUM 15 /* (ebp) Contains address of executing stack frame */
+#define EBP_REGNUM 15
+#undef PC_REGNUM
+#define PC_REGNUM 16 /* (eip) Contains program counter */
+#define EIP_REGNUM 16
+#undef PS_REGNUM
+#define PS_REGNUM 17 /* (ps) Contains processor status */
+#define EFLAGS_REGNUM 17
+
+/*
+ * Following macro translates i386 opcode register numbers to Symmetry
+ * register numbers. This is used by i386_frame_find_saved_regs.
+ *
+ * %eax %ecx %edx %ebx %esp %ebp %esi %edi
+ * i386 0 1 2 3 4 5 6 7
+ * Symmetry 0 2 1 5 14 15 6 7
+ *
+ */
+#define I386_REGNO_TO_SYMMETRY(n) \
+((n)==0?0 :(n)==1?2 :(n)==2?1 :(n)==3?5 :(n)==4?14 :(n)==5?15 :(n))
+
+/* The magic numbers below are offsets into u_ar0 in the user struct.
+ * They live in <machine/reg.h>. Gdb calls this macro with blockend
+ * holding u.u_ar0 - KERNEL_U_ADDR. Only the registers listed are
+ * saved in the u area (along with a few others that aren't useful
+ * here. See <machine/reg.h>).
+ */
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+{ struct user foo; /* needed for finding fpu regs */ \
+switch (regno) { \
+ case 0: \
+ addr = blockend + EAX * sizeof(int); break; \
+ case 1: \
+ addr = blockend + EDX * sizeof(int); break; \
+ case 2: \
+ addr = blockend + ECX * sizeof(int); break; \
+ case 3: /* st(0) */ \
+ addr = ((int)&foo.u_fpusave.fpu_stack[0][0] - (int)&foo); \
+ break; \
+ case 4: /* st(1) */ \
+ addr = ((int) &foo.u_fpusave.fpu_stack[1][0] - (int)&foo); \
+ break; \
+ case 5: \
+ addr = blockend + EBX * sizeof(int); break; \
+ case 6: \
+ addr = blockend + ESI * sizeof(int); break; \
+ case 7: \
+ addr = blockend + EDI * sizeof(int); break; \
+ case 8: /* st(2) */ \
+ addr = ((int) &foo.u_fpusave.fpu_stack[2][0] - (int)&foo); \
+ break; \
+ case 9: /* st(3) */ \
+ addr = ((int) &foo.u_fpusave.fpu_stack[3][0] - (int)&foo); \
+ break; \
+ case 10: /* st(4) */ \
+ addr = ((int) &foo.u_fpusave.fpu_stack[4][0] - (int)&foo); \
+ break; \
+ case 11: /* st(5) */ \
+ addr = ((int) &foo.u_fpusave.fpu_stack[5][0] - (int)&foo); \
+ break; \
+ case 12: /* st(6) */ \
+ addr = ((int) &foo.u_fpusave.fpu_stack[6][0] - (int)&foo); \
+ break; \
+ case 13: /* st(7) */ \
+ addr = ((int) &foo.u_fpusave.fpu_stack[7][0] - (int)&foo); \
+ break; \
+ case 14: \
+ addr = blockend + ESP * sizeof(int); break; \
+ case 15: \
+ addr = blockend + EBP * sizeof(int); break; \
+ case 16: \
+ addr = blockend + EIP * sizeof(int); break; \
+ case 17: \
+ addr = blockend + FLAGS * sizeof(int); break; \
+ case 18: /* fp1 */ \
+ case 19: /* fp2 */ \
+ case 20: /* fp3 */ \
+ case 21: /* fp4 */ \
+ case 22: /* fp5 */ \
+ case 23: /* fp6 */ \
+ case 24: /* fp7 */ \
+ case 25: /* fp8 */ \
+ case 26: /* fp9 */ \
+ case 27: /* fp10 */ \
+ case 28: /* fp11 */ \
+ case 29: /* fp12 */ \
+ case 30: /* fp13 */ \
+ case 31: /* fp14 */ \
+ case 32: /* fp15 */ \
+ case 33: /* fp16 */ \
+ case 34: /* fp17 */ \
+ case 35: /* fp18 */ \
+ case 36: /* fp19 */ \
+ case 37: /* fp20 */ \
+ case 38: /* fp21 */ \
+ case 39: /* fp22 */ \
+ case 40: /* fp23 */ \
+ case 41: /* fp24 */ \
+ case 42: /* fp25 */ \
+ case 43: /* fp26 */ \
+ case 44: /* fp27 */ \
+ case 45: /* fp28 */ \
+ case 46: /* fp29 */ \
+ case 47: /* fp30 */ \
+ case 48: /* fp31 */ \
+ addr = ((int) &foo.u_fpasave.fpa_regs[(regno)-18] - (int)&foo); \
+ } \
+}
+
+/* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'. 10 i*86 registers, 8 i387
+ registers, and 31 Weitek 1167 registers */
+
+#undef REGISTER_BYTES
+#define REGISTER_BYTES ((10 * 4) + (8 * 10) + (31 * 4))
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#undef REGISTER_BYTE
+#define REGISTER_BYTE(N) \
+(((N) < 3) ? ((N) * 4) : \
+((N) < 5) ? ((((N) - 2) * 10) + 2) : \
+((N) < 8) ? ((((N) - 5) * 4) + 32) : \
+((N) < 14) ? ((((N) - 8) * 10) + 44) : \
+ ((((N) - 14) * 4) + 104))
+
+/* Number of bytes of storage in the actual machine representation
+ * for register N. All registers are 4 bytes, except 387 st(0) - st(7),
+ * which are 80 bits each.
+ */
+
+#undef REGISTER_RAW_SIZE
+#define REGISTER_RAW_SIZE(N) \
+(((N) < 3) ? 4 : \
+((N) < 5) ? 10 : \
+((N) < 8) ? 4 : \
+((N) < 14) ? 10 : \
+ 4)
+
+/* Nonzero if register N requires conversion
+ from raw format to virtual format. */
+
+#undef REGISTER_CONVERTIBLE
+#define REGISTER_CONVERTIBLE(N) \
+(((N) < 3) ? 0 : \
+((N) < 5) ? 1 : \
+((N) < 8) ? 0 : \
+((N) < 14) ? 1 : \
+ 0)
+
+#include "floatformat.h"
+
+/* Convert data from raw format for register REGNUM in buffer FROM
+ to virtual format with type TYPE in buffer TO. */
+
+#undef REGISTER_CONVERT_TO_VIRTUAL
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
+{ \
+ DOUBLEST val; \
+ floatformat_to_doublest (&floatformat_i387_ext, (FROM), &val); \
+ store_floating ((TO), TYPE_LENGTH (TYPE), val); \
+}
+
+/* Convert data from virtual format with type TYPE in buffer FROM
+ to raw format for register REGNUM in buffer TO. */
+
+#undef REGISTER_CONVERT_TO_RAW
+#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \
+{ \
+ DOUBLEST val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \
+ floatformat_from_doublest (&floatformat_i387_ext, &val, (TO)); \
+}
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+#undef REGISTER_VIRTUAL_TYPE
+#define REGISTER_VIRTUAL_TYPE(N) \
+((N < 3) ? builtin_type_int : \
+(N < 5) ? builtin_type_double : \
+(N < 8) ? builtin_type_int : \
+(N < 14) ? builtin_type_double : \
+ builtin_type_int)
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function.
+ Native cc passes the address in eax, gcc (up to version 2.5.8)
+ passes it on the stack. gcc should be fixed in future versions to
+ adopt native cc conventions. */
+
+#undef PUSH_ARGUMENTS
+#undef STORE_STRUCT_RETURN
+#define STORE_STRUCT_RETURN(ADDR, SP) write_register(0, (ADDR))
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. */
+
+#undef EXTRACT_RETURN_VALUE
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ symmetry_extract_return_value(TYPE, REGBUF, VALBUF)
+
+/* The following redefines make backtracing through sigtramp work.
+ They manufacture a fake sigtramp frame and obtain the saved pc in sigtramp
+ from the sigcontext structure which is pushed by the kernel on the
+ user stack, along with a pointer to it. */
+
+#define IN_SIGTRAMP(pc, name) ((name) && STREQ ("_sigcode", name))
+
+/* Offset to saved PC in sigcontext, from <signal.h>. */
+#define SIGCONTEXT_PC_OFFSET 16
+
+#endif /* ifndef TM_SYMMETRY_H */
diff --git a/gdb/config/i386/tm-vxworks.h b/gdb/config/i386/tm-vxworks.h
new file mode 100644
index 00000000000..6434a6ea2f5
--- /dev/null
+++ b/gdb/config/i386/tm-vxworks.h
@@ -0,0 +1,28 @@
+/* Target machine description for VxWorks on the 80[3456]86,
+ for GDB, the GNU debugger.
+ Copyright 1999 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. */
+
+#ifndef TM_VXWORKS_H
+#define TM_VXWORKS_H
+
+#include "i386/tm-i386v.h"
+#include "tm-vxworks.h"
+
+#endif /* ifndef TM_VXWORKS_H */
diff --git a/gdb/config/i386/vxworks.mt b/gdb/config/i386/vxworks.mt
new file mode 100644
index 00000000000..a14aacc8cd0
--- /dev/null
+++ b/gdb/config/i386/vxworks.mt
@@ -0,0 +1,3 @@
+# Target: i386 running VxWorks
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-vxworks.h
diff --git a/gdb/config/i386/x86-64linux.mh b/gdb/config/i386/x86-64linux.mh
new file mode 100644
index 00000000000..bc79f3f235c
--- /dev/null
+++ b/gdb/config/i386/x86-64linux.mh
@@ -0,0 +1,11 @@
+# Host: AMD x86-64 running GNU/Linux
+
+XM_FILE= xm-i386.h
+
+NAT_FILE= nm-x86-64.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \
+ core-aout.o i386-nat.o x86-64-linux-nat.o \
+ proc-service.o thread-db.o lin-lwp.o \
+ linux-proc.o gcore.o
+
+LOADLIBES = -ldl -rdynamic
diff --git a/gdb/config/i386/x86-64linux.mt b/gdb/config/i386/x86-64linux.mt
new file mode 100644
index 00000000000..85f1972531d
--- /dev/null
+++ b/gdb/config/i386/x86-64linux.mt
@@ -0,0 +1,3 @@
+# Target: AMD x86-64 running GNU/Linux
+TDEPFILES= x86-64-tdep.o x86-64-linux-tdep.o i387-tdep.o dwarf2cfi.o \
+ solib.o solib-svr4.o solib-legacy.o
diff --git a/gdb/config/i386/xm-cygwin.h b/gdb/config/i386/xm-cygwin.h
new file mode 100644
index 00000000000..647072758fe
--- /dev/null
+++ b/gdb/config/i386/xm-cygwin.h
@@ -0,0 +1,24 @@
+/* Definitions for hosting on WIN32, for GDB.
+ Copyright 1995, 1996, 1997, 1998, 2001 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 "fopen-bin.h"
+
+/* Define this if source files use \r\n rather than just \n. */
+#define CRLF_SOURCE_FILES
diff --git a/gdb/config/i386/xm-go32.h b/gdb/config/i386/xm-go32.h
new file mode 100644
index 00000000000..dead9f69e42
--- /dev/null
+++ b/gdb/config/i386/xm-go32.h
@@ -0,0 +1,26 @@
+/* Host-dependent definitions for Intel x86 running DJGPP.
+ Copyright 1993-1996 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/xm-i386.h"
+#include "fopen-bin.h"
+
+#define GDBINIT_FILENAME "gdb.ini"
+#define CRLF_SOURCE_FILES
+#define DIRNAME_SEPARATOR ';'
diff --git a/gdb/config/i386/xm-i386.h b/gdb/config/i386/xm-i386.h
new file mode 100644
index 00000000000..151e7a6b556
--- /dev/null
+++ b/gdb/config/i386/xm-i386.h
@@ -0,0 +1,30 @@
+/* Host-dependent definitions for i386.
+ Copyright 2001 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. */
+
+#ifndef XM_I386_H
+#define XM_I386_H
+
+#include "floatformat.h"
+
+#define HOST_FLOAT_FORMAT &floatformat_ieee_single_little
+#define HOST_DOUBLE_FORMAT &floatformat_ieee_double_little
+#define HOST_LONG_DOUBLE_FORMAT &floatformat_i387_ext
+
+#endif /* XM_386_H */
diff --git a/gdb/config/i386/xm-i386aix.h b/gdb/config/i386/xm-i386aix.h
new file mode 100644
index 00000000000..842eadf0632
--- /dev/null
+++ b/gdb/config/i386/xm-i386aix.h
@@ -0,0 +1,29 @@
+/* Macro defintions for AIX PS/2 (i386)
+ Copyright 1986, 1987, 1989, 1992, 1993 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. */
+
+/*
+ * Changed for IBM AIX ps/2 by Minh Tran Le (tranle@intellicorp.com)
+ * Revision: 23-Oct-92 17:42:49
+ */
+
+#include "i386/xm-i386v.h"
+
+#undef HAVE_TERMIO
+#define HAVE_SGTTY
diff --git a/gdb/config/i386/xm-i386bsd.h b/gdb/config/i386/xm-i386bsd.h
new file mode 100644
index 00000000000..ca0ffb2ab8f
--- /dev/null
+++ b/gdb/config/i386/xm-i386bsd.h
@@ -0,0 +1,22 @@
+/* Host-dependent definitions for Intel 386 running BSD Unix, for GDB.
+ Copyright 1986, 1987, 1989, 1992, 1995, 1996
+ 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 <machine/limits.h> /* for INT_MIN */
diff --git a/gdb/config/i386/xm-i386gnu.h b/gdb/config/i386/xm-i386gnu.h
new file mode 100644
index 00000000000..711aeebccfb
--- /dev/null
+++ b/gdb/config/i386/xm-i386gnu.h
@@ -0,0 +1,25 @@
+/* Definitions to make GDB run on the GNU Hurd on an Intel 386
+ Copyright 1986, 1987, 1989, 1991, 1996, 2000
+ 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. */
+
+#define HOST_LONG_DOUBLE_FORMAT &floatformat_i387_ext
+
+/* Do implement the attach and detach commands. */
+#define ATTACH_DETACH 1
diff --git a/gdb/config/i386/xm-i386m3.h b/gdb/config/i386/xm-i386m3.h
new file mode 100644
index 00000000000..f25b3891210
--- /dev/null
+++ b/gdb/config/i386/xm-i386m3.h
@@ -0,0 +1,33 @@
+/* Definitions to make GDB run on Mach 3 on an Intel 386
+ Copyright 1986, 1987, 1989, 1991, 1993, 1994, 1996
+ 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. */
+
+/* Do implement the attach and detach commands. */
+#define ATTACH_DETACH 1
+
+/* Not needeed */
+#define KERNEL_U_ADDR 0
+
+#ifndef EMULATOR_BASE
+/* For EMULATOR_BASE and EMULATOR_END.
+ * OSF 1/MK has different values in some other place.
+ */
+#include <machine/vmparam.h>
+#endif /* EMULATOR_BASE */
diff --git a/gdb/config/i386/xm-i386mach.h b/gdb/config/i386/xm-i386mach.h
new file mode 100644
index 00000000000..e0a5d651376
--- /dev/null
+++ b/gdb/config/i386/xm-i386mach.h
@@ -0,0 +1,28 @@
+/* Definitions to make GDB run on Mach on an Intel 386
+ Copyright 1986, 1987, 1989, 1991, 1992, 1994, 1996, 2001
+ 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. */
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+
+#define KERNEL_U_ADDR (0x80000000 - (UPAGES * NBPG))
+
+/* <errno.h> only defines this if __STDC__!!! */
+extern int errno;
diff --git a/gdb/config/i386/xm-i386mk.h b/gdb/config/i386/xm-i386mk.h
new file mode 100644
index 00000000000..cbf62710db5
--- /dev/null
+++ b/gdb/config/i386/xm-i386mk.h
@@ -0,0 +1,26 @@
+/* Definitions to make GDB run on Mach 3 OSF 1/MK on an Intel 386
+ Copyright 1992, 1993, 1998 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. */
+
+#define HAVE_TERMIO 1
+
+#define EMULATOR_BASE 0xa0000000
+#define EMULATOR_END 0xa0040000
+
+#include "i386/xm-i386m3.h"
diff --git a/gdb/config/i386/xm-i386sco.h b/gdb/config/i386/xm-i386sco.h
new file mode 100644
index 00000000000..920ebbb3c4d
--- /dev/null
+++ b/gdb/config/i386/xm-i386sco.h
@@ -0,0 +1,40 @@
+/* Macro defintions for i386, running SCO Unix System V/386 3.2.
+ Copyright 1989, 1993, 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. */
+
+/* In 3.2v4 <sys/user.h> requires on <sys/dir.h>. */
+#include <sys/types.h>
+#include <sys/dir.h>
+
+#include "i386/xm-i386v.h"
+
+/* Apparently there is inconsistency among various System V's about what
+ the name of this field is. */
+#define U_FPSTATE(u) u.u_fps.u_fpstate
+
+/* SCO 3.2v2 and later have job control. */
+/* SCO 3.2v4 I know has termios; I'm not sure about earlier versions.
+ GDB does not currently support the termio/job control combination. */
+#undef HAVE_TERMIO
+#define HAVE_TERMIOS
+
+/* SCO's assembler doesn't grok dollar signs in identifiers.
+ So we use dots instead. This item must be coordinated with G++. */
+#undef CPLUS_MARKER
+#define CPLUS_MARKER '.'
diff --git a/gdb/config/i386/xm-i386v.h b/gdb/config/i386/xm-i386v.h
new file mode 100644
index 00000000000..1c329054f22
--- /dev/null
+++ b/gdb/config/i386/xm-i386v.h
@@ -0,0 +1,43 @@
+/* Host support for i386.
+ Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
+ Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu), July 1988.
+
+ 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. */
+
+/* I'm running gdb 3.4 under 386/ix 2.0.2, which is a derivative of AT&T's
+ Sys V/386 3.2.
+
+ On some machines, gdb crashes when it's starting up while calling the
+ vendor's termio tgetent() routine. It always works when run under
+ itself (actually, under 3.2, it's not an infinitely recursive bug.)
+ After some poking around, it appears that depending on the environment
+ size, or whether you're running YP, or the phase of the moon or something,
+ the stack is not always long-aligned when main() is called, and tgetent()
+ takes strong offense at that. On some machines this bug never appears, but
+ on those where it does, it occurs quite reliably. */
+#define ALIGN_STACK_ON_STARTUP
+
+/* define USG if you are using sys5 /usr/include's */
+#define USG
+
+#define HAVE_TERMIO
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+
+#define KERNEL_U_ADDR 0xe0000000
diff --git a/gdb/config/i386/xm-i386v32.h b/gdb/config/i386/xm-i386v32.h
new file mode 100644
index 00000000000..706822f30dd
--- /dev/null
+++ b/gdb/config/i386/xm-i386v32.h
@@ -0,0 +1,25 @@
+/* Macro defintions for i386, running System V 3.2.
+ Copyright (C) 1989 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/xm-i386v.h"
+
+/* Apparently there is inconsistency among various System V's about what
+ the name of this field is. */
+#define U_FPSTATE(u) u.u_fps.u_fpstate
diff --git a/gdb/config/i386/xm-i386v4.h b/gdb/config/i386/xm-i386v4.h
new file mode 100644
index 00000000000..c3241100bf7
--- /dev/null
+++ b/gdb/config/i386/xm-i386v4.h
@@ -0,0 +1,28 @@
+/* Macro definitions for GDB on an Intel i386 running SVR4.
+ Copyright 1991, 1992, 1994, 1996 Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus Support (fnf@cygnus.com).
+
+ 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. */
+
+/* Pick up most of what we need from the generic i386 host include file. */
+
+#include "i386/xm-i386v.h"
+
+/* Pick up more stuff from the generic SVR4 host include file. */
+
+#include "xm-sysv4.h"
diff --git a/gdb/config/i386/xm-nbsd.h b/gdb/config/i386/xm-nbsd.h
new file mode 100644
index 00000000000..415d0fa4ffd
--- /dev/null
+++ b/gdb/config/i386/xm-nbsd.h
@@ -0,0 +1,24 @@
+/* Parameters for execution on a i386 running NetBSD, for GDB.
+ Copyright 1994, 2000 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. */
+
+/* Get generic NetBSD host definitions. */
+#include "xm-nbsd.h"
+
+#define HOST_LONG_DOUBLE_FORMAT &floatformat_i387_ext
diff --git a/gdb/config/i386/xm-ptx.h b/gdb/config/i386/xm-ptx.h
new file mode 100644
index 00000000000..6dfb9d6d4e3
--- /dev/null
+++ b/gdb/config/i386/xm-ptx.h
@@ -0,0 +1,38 @@
+/* Definitions to make GDB run on a Sequent Symmetry under ptx, with
+ Weitek 1167 and i387 support.
+ Copyright 1986, 1987, 1989, 1992, 1993, 1994, 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. */
+
+/* Symmetry version by Jay Vosburgh (fubar@sequent.com) */
+
+#ifdef _SEQUENT_PTX4_
+#include "xm-sysv4.h"
+#endif /* _SEQUENT_PTX4_ */
+
+/* This machine doesn't have the siginterrupt call. */
+#define NO_SIGINTERRUPT
+
+#define HAVE_WAIT_STRUCT
+
+#undef HAVE_TERMIO
+#define HAVE_TERMIOS
+#define USG
+
+#define USE_O_NOCTTY
diff --git a/gdb/config/i386/xm-ptx4.h b/gdb/config/i386/xm-ptx4.h
new file mode 100644
index 00000000000..2f466e62d70
--- /dev/null
+++ b/gdb/config/i386/xm-ptx4.h
@@ -0,0 +1,27 @@
+/* Definitions to make GDB run on a Sequent Symmetry under ptx, with
+ Weitek 1167 and i387 support.
+ Copyright 1986, 1987, 1989, 1992, 1993, 1994
+ 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. */
+
+/* Symmetry version by Jay Vosburgh (fubar@sequent.com) */
+
+#include "xm-sysv4.h"
+
+#include "xm-ptx.h"
diff --git a/gdb/config/i386/xm-symmetry.h b/gdb/config/i386/xm-symmetry.h
new file mode 100644
index 00000000000..781a343961a
--- /dev/null
+++ b/gdb/config/i386/xm-symmetry.h
@@ -0,0 +1,28 @@
+/* Definitions to make GDB run on a Sequent Symmetry under
+ dynix 3.1, with Weitek 1167 and i387 support.
+ Copyright 1986, 1987, 1989, 1992, 1993, 1994
+ 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. */
+
+/* Symmetry version by Jay Vosburgh (fubar@sequent.com) */
+
+/* This machine doesn't have the siginterrupt call. */
+#define NO_SIGINTERRUPT
+
+#define HAVE_WAIT_STRUCT
diff --git a/gdb/config/i960/mon960.mt b/gdb/config/i960/mon960.mt
new file mode 100644
index 00000000000..6cd73459f7e
--- /dev/null
+++ b/gdb/config/i960/mon960.mt
@@ -0,0 +1,6 @@
+# Target: Intel 960 rom monitor
+TDEPFILES= i960-tdep.o monitor.o mon960-rom.o ttyflush.o xmodem.o dsrec.o
+TM_FILE= tm-mon960.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/i960/libsim.a
+
diff --git a/gdb/config/i960/nindy960.mt b/gdb/config/i960/nindy960.mt
new file mode 100644
index 00000000000..f37c1da4b7c
--- /dev/null
+++ b/gdb/config/i960/nindy960.mt
@@ -0,0 +1,3 @@
+# Target: Intel 80960, in an embedded system under the NINDY monitor
+TDEPFILES= i960-tdep.o nindy-tdep.o remote-nindy.o nindy.o Onindy.o ttyflush.o
+TM_FILE= tm-nindy960.h
diff --git a/gdb/config/i960/tm-i960.h b/gdb/config/i960/tm-i960.h
new file mode 100644
index 00000000000..a62e35da7e7
--- /dev/null
+++ b/gdb/config/i960/tm-i960.h
@@ -0,0 +1,345 @@
+/* Parameters for target machine Intel 960, for GDB, the GNU debugger.
+
+ Copyright 1990, 1991, 1993, 1994, 1996, 1998, 1999, 2000, 2002 Free
+ Software Foundation, Inc.
+
+ Contributed by Intel Corporation.
+ 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. */
+
+/* Definitions to target GDB to any i960. */
+
+#ifndef I80960
+#define I80960
+#endif
+
+#include "doublest.h"
+
+/* Hook for the SYMBOL_CLASS of a parameter when decoding DBX symbol
+ information. In the i960, parameters can be stored as locals or as
+ args, depending on the type of the debug record.
+
+ From empirical observation, gcc960 uses N_LSYM to indicate
+ arguments passed in registers and then copied immediately
+ to the frame, and N_PSYM to indicate arguments passed in a
+ g14-relative argument block. */
+
+#define DBX_PARM_SYMBOL_CLASS(type) ((type == N_LSYM)? LOC_LOCAL_ARG: LOC_ARG)
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance ip across any function entry prologue instructions
+ to reach some "real" code. */
+
+#define SKIP_PROLOGUE(ip) (i960_skip_prologue (ip))
+extern CORE_ADDR i960_skip_prologue ();
+
+/* Immediately after a function call, return the saved ip.
+ Can't always go through the frames for this because on some machines
+ the new frame is not set up until the new function
+ executes some instructions. */
+
+#define SAVED_PC_AFTER_CALL(frame) (saved_pc_after_call (frame))
+extern CORE_ADDR saved_pc_after_call ();
+
+/* Stack grows upward */
+
+#define INNER_THAN(lhs,rhs) ((lhs) > (rhs))
+
+/* Say how long (ordinary) registers are. This is a piece of bogosity
+ used in push_word and a few other places; REGISTER_RAW_SIZE is the
+ real way to know how big a register is. */
+
+#define REGISTER_SIZE 4
+
+/* Number of machine registers */
+#define NUM_REGS 40
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer. */
+
+#define REGISTER_NAMES { \
+ /* 0 */ "pfp", "sp", "rip", "r3", "r4", "r5", "r6", "r7", \
+ /* 8 */ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",\
+ /* 16 */ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \
+ /* 24 */ "g8", "g9", "g10", "g11", "g12", "g13", "g14", "fp", \
+ /* 32 */ "pcw", "ac", "tc", "ip", "fp0", "fp1", "fp2", "fp3",\
+}
+
+/* Register numbers of various important registers (used to index
+ into arrays of register names and register values). */
+
+#define R0_REGNUM 0 /* First local register */
+#define SP_REGNUM 1 /* Contains address of top of stack */
+#define RIP_REGNUM 2 /* Return instruction pointer (local r2) */
+#define R15_REGNUM 15 /* Last local register */
+#define G0_REGNUM 16 /* First global register */
+#define G13_REGNUM 29 /* g13 - holds struct return address */
+#define G14_REGNUM 30 /* g14 - ptr to arg block / leafproc return address */
+#define FP_REGNUM 31 /* Contains address of executing stack frame */
+#define PCW_REGNUM 32 /* process control word */
+#define ACW_REGNUM 33 /* arithmetic control word */
+#define TCW_REGNUM 34 /* trace control word */
+#define IP_REGNUM 35 /* instruction pointer */
+#define FP0_REGNUM 36 /* First floating point register */
+
+/* Some registers have more than one name */
+
+#define PC_REGNUM IP_REGNUM /* GDB refers to ip as the Program Counter */
+#define PFP_REGNUM R0_REGNUM /* Previous frame pointer */
+
+/* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'. */
+#define REGISTER_BYTES ((36*4) + (4*10))
+
+/* Index within `registers' of the first byte of the space for register N. */
+
+#define REGISTER_BYTE(N) ( (N) < FP0_REGNUM ? \
+ (4*(N)) : ((10*(N)) - (6*FP0_REGNUM)) )
+
+/* The i960 has register windows, sort of. */
+
+extern void i960_get_saved_register (char *raw_buffer,
+ int *optimized,
+ CORE_ADDR *addrp,
+ struct frame_info *frame,
+ int regnum,
+ enum lval_type *lval);
+
+#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \
+ i960_get_saved_register(raw_buffer, optimized, addrp, frame, regnum, lval)
+
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. On the i960, all regs are 4 bytes except for floating
+ point, which are 10. NINDY only sends us 8 byte values for these,
+ which is a pain, but VxWorks handles this correctly, so we must. */
+
+#define REGISTER_RAW_SIZE(N) ( (N) < FP0_REGNUM ? 4 : 10 )
+
+/* Number of bytes of storage in the program's representation for register N. */
+
+#define REGISTER_VIRTUAL_SIZE(N) ( (N) < FP0_REGNUM ? 4 : 8 )
+
+/* 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 8
+
+#include "floatformat.h"
+
+#define TARGET_LONG_DOUBLE_FORMAT &floatformat_i960_ext
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+struct type *i960_register_type (int regnum);
+#define REGISTER_VIRTUAL_TYPE(N) i960_register_type (N)
+
+/* Macros for understanding function return values... */
+
+/* Does the specified function use the "struct returning" convention
+ or the "value returning" convention? The "value returning" convention
+ almost invariably returns the entire value in registers. The
+ "struct returning" convention often returns the entire value in
+ memory, and passes a pointer (out of or into the function) saying
+ where the value (is or should go).
+
+ Since this sometimes depends on whether it was compiled with GCC,
+ this is also an argument. This is used in call_function to build a
+ stack, and in value_being_returned to print return values.
+
+ On i960, a structure is returned in registers g0-g3, if it will fit.
+ If it's more than 16 bytes long, g13 pointed to it on entry. */
+
+extern use_struct_convention_fn i960_use_struct_convention;
+#define USE_STRUCT_CONVENTION(gcc_p, type) i960_use_struct_convention (gcc_p, type)
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. This is only called if USE_STRUCT_CONVENTION for this
+ type is 0.
+
+ On the i960 we just take as many bytes as we need from G0 through G3. */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ memcpy(VALBUF, REGBUF+REGISTER_BYTE(G0_REGNUM), TYPE_LENGTH (TYPE))
+
+/* If USE_STRUCT_CONVENTION produces a 1,
+ extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one).
+
+ Address of where to put structure was passed in in global
+ register g13 on entry. God knows what's in g13 now. The
+ (..., 0) below is to make it appear to return a value, though
+ actually all it does is call error(). */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+ (error("Don't know where large structure is returned on i960"), 0)
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format, for "value returning" functions.
+
+ For 'return' command: not (yet) implemented for i960. */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ error ("Returning values from functions is not implemented in i960 gdb")
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+ error ("Returning values from functions is not implemented in i960 gdb")
+
+/* Describe the pointer in each stack frame to the previous stack frame
+ (its caller). */
+
+/* FRAME_CHAIN takes a frame's nominal address
+ and produces the frame's chain-pointer.
+
+ However, if FRAME_CHAIN_VALID returns zero,
+ it means the given frame is the outermost one and has no caller. */
+
+/* We cache information about saved registers in the frame structure,
+ to save us from having to re-scan function prologues every time
+ a register in a non-current frame is accessed. */
+
+#define EXTRA_FRAME_INFO \
+ struct frame_saved_regs *fsr; \
+ CORE_ADDR arg_pointer;
+
+/* Zero the frame_saved_regs pointer when the frame is initialized,
+ so that FRAME_FIND_SAVED_REGS () will know to allocate and
+ initialize a frame_saved_regs struct the first time it is called.
+ Set the arg_pointer to -1, which is not valid; 0 and other values
+ indicate real, cached values. */
+
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \
+ ((fi)->fsr = 0, (fi)->arg_pointer = -1)
+
+/* On the i960, we get the chain pointer by reading the PFP saved
+ on the stack and clearing the status bits. */
+
+#define FRAME_CHAIN(thisframe) \
+ (read_memory_integer (FRAME_FP(thisframe), 4) & ~0xf)
+
+/* FRAME_CHAIN_VALID returns zero if the given frame is the outermost one
+ and has no caller.
+
+ On the i960, each various target system type must define FRAME_CHAIN_VALID,
+ since it differs between NINDY and VxWorks, the two currently supported
+ targets types. We leave it undefined here. */
+
+
+/* A macro that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. If it
+ does not, FRAMELESS is set to 1, else 0. */
+
+CORE_ADDR leafproc_return (CORE_ADDR ip);
+#define FRAMELESS_FUNCTION_INVOCATION(FI) \
+ (leafproc_return ((FI)->pc) != 0)
+
+/* Note that in the i960 architecture the return pointer is saved in the
+ *caller's* stack frame.
+
+ Make sure to zero low-order bits because of bug in 960CA A-step part
+ (instruction addresses should always be word-aligned anyway). */
+
+#define FRAME_SAVED_PC(frame) \
+ ((read_memory_integer(FRAME_CHAIN(frame)+8,4)) & ~3)
+
+/* On the i960, FRAME_ARGS_ADDRESS should return the value of
+ g14 as passed into the frame, if known. We need a function for this.
+ We cache this value in the frame info if we've already looked it up. */
+
+#define FRAME_ARGS_ADDRESS(fi) \
+ (((fi)->arg_pointer != -1)? (fi)->arg_pointer: frame_args_address (fi, 0))
+extern CORE_ADDR frame_args_address (); /* i960-tdep.c */
+
+/* This is the same except it should return 0 when
+ it does not really know where the args are, rather than guessing.
+ This value is not cached since it is only used infrequently. */
+
+#define FRAME_ARGS_ADDRESS_CORRECT(fi) (frame_args_address (fi, 1))
+
+#define FRAME_LOCALS_ADDRESS(fi) (fi)->frame
+
+/* Set NUMARGS to the number of args passed to a frame.
+ Can return -1, meaning no way to tell. */
+
+#define FRAME_NUM_ARGS(fi) (-1)
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Produce the positions of the saved registers in a stack frame. */
+
+#define FRAME_FIND_SAVED_REGS(frame_info_addr, sr) \
+ frame_find_saved_regs (frame_info_addr, &sr)
+extern void frame_find_saved_regs (); /* See i960-tdep.c */
+
+/* Things needed for making calls to functions in the inferior process */
+
+/* Push an empty stack frame, to record the current ip, etc.
+
+ Not (yet?) implemented for i960. */
+
+#define PUSH_DUMMY_FRAME \
+error("Function calls into the inferior process are not supported on the i960")
+
+/* Discard from the stack the innermost frame, restoring all registers. */
+
+
+void i960_pop_frame (void);
+#define POP_FRAME \
+ i960_pop_frame ()
+
+
+/* This sequence of words is the instructions
+
+ callx 0x00000000
+ fmark
+ */
+
+/* #define CALL_DUMMY { 0x86003000, 0x00000000, 0x66003e00 } */
+
+ /* #define CALL_DUMMY_START_OFFSET 0 *//* Start execution at beginning of dummy */
+
+/* Indicate that we don't support calling inferior child functions. */
+
+#undef CALL_DUMMY
+
+/* Insert the specified number of args and function address
+ into a call sequence of the above form stored at 'dummyname'.
+
+ Ignore arg count on i960. */
+
+/* #define FIX_CALL_DUMMY(dummyname, fun, nargs) *(((int *)dummyname)+1) = fun */
+
+#undef FIX_CALL_DUMMY
+
+
+/* Interface definitions for kernel debugger KDB */
+/* (Not relevant to i960.) */
diff --git a/gdb/config/i960/tm-mon960.h b/gdb/config/i960/tm-mon960.h
new file mode 100644
index 00000000000..98c03b137eb
--- /dev/null
+++ b/gdb/config/i960/tm-mon960.h
@@ -0,0 +1,69 @@
+/* Parameters for Intel 960 running MON960 monitor, for GDB, the GNU debugger.
+ Copyright 1990, 1991, 1996, 1999, 2000 Free Software Foundation, Inc.
+ Contributed by Intel Corporation and 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 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. */
+
+/*****************************************************************************
+ * Definitions to target GDB to an i960 debugged over a serial line.
+ ******************************************************************************/
+
+#include "i960/tm-i960.h"
+
+/* forward declarations */
+struct frame_info;
+
+/* redefined from tm-i960.h */
+/* Number of machine registers */
+#undef NUM_REGS
+#define NUM_REGS 40
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer. */
+#undef REGISTER_NAMES
+#define REGISTER_NAMES { \
+ /* 0 */ "pfp", "sp", "rip", "r3", "r4", "r5", "r6", "r7", \
+ /* 8 */ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",\
+ /* 16 */ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \
+ /* 24 */ "g8", "g9", "g10", "g11", "g12", "g13", "g14", "fp", \
+ /* 32 */ "pc", "ac", "tc", "ip", "fp0", "fp1", "fp2", "fp3",\
+}
+
+/* Override the standard gdb prompt when compiled for this target. */
+
+#define DEFAULT_PROMPT "(gdb960) "
+
+/* FRAME_CHAIN_VALID returns zero if the given frame is the outermost one
+ and has no caller.
+
+ On the i960, each various target system type defines FRAME_CHAIN_VALID,
+ since it differs between Nindy, Mon960 and VxWorks, the currently supported
+ target types. */
+
+extern int mon960_frame_chain_valid (CORE_ADDR, struct frame_info *);
+#define FRAME_CHAIN_VALID(chain, thisframe) mon960_frame_chain_valid (chain, thisframe)
+
+/* Sequence of bytes for breakpoint instruction */
+
+#define BREAKPOINT {0x00, 0x3e, 0x00, 0x66}
+
+/* Amount ip must be decremented by after a breakpoint.
+ * This is often the number of bytes in BREAKPOINT but not always.
+ */
+
+#define DECR_PC_AFTER_BREAK 4
diff --git a/gdb/config/i960/tm-nindy960.h b/gdb/config/i960/tm-nindy960.h
new file mode 100644
index 00000000000..e9cb99c9f4b
--- /dev/null
+++ b/gdb/config/i960/tm-nindy960.h
@@ -0,0 +1,106 @@
+/* Parameters for Intel 960 running NINDY monitor, for GDB, the GNU debugger.
+ Copyright 1990, 1991, 1996, 1999, 2000 Free Software Foundation, Inc.
+ Contributed by Intel Corporation and 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 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. */
+
+/*****************************************************************************
+ * Definitions to target GDB to an i960 debugged over a serial line.
+ ******************************************************************************/
+
+#include "i960/tm-i960.h"
+
+/* forward declarations */
+struct frame_info;
+
+/* Override the standard gdb prompt when compiled for this target. */
+
+#define DEFAULT_PROMPT "(gdb960) "
+
+/* Additional command line options accepted by nindy gdb's, for handling
+ the remote-nindy.c interface. These should really be target-specific
+ rather than architecture-specific. */
+
+extern int nindy_old_protocol; /* nonzero if old NINDY serial protocol */
+extern int nindy_initial_brk; /* Send a BREAK to reset board first */
+extern char *nindy_ttyname; /* Name of serial port to talk to nindy */
+
+#define ADDITIONAL_OPTIONS \
+ {"O", no_argument, &nindy_old_protocol, 1}, \
+ {"brk", no_argument, &nindy_initial_brk, 1}, \
+ {"ser", required_argument, 0, 1004}, /* 1004 is magic cookie for ADDL_CASES */
+
+#define ADDITIONAL_OPTION_CASES \
+ case 1004: /* -ser option: remote nindy auto-start */ \
+ nindy_ttyname = optarg; \
+ break;
+
+#define ADDITIONAL_OPTION_HELP \
+ "\
+ -O Use old protocol to talk to a Nindy target\n\
+ -brk Send a break to a Nindy target to reset it.\n\
+ -ser SERIAL Open remote Nindy session to SERIAL port.\n\
+"
+
+/* If specified on the command line, open tty for talking to nindy,
+ and download the executable file if one was specified. */
+
+extern void nindy_open (char *name, int from_tty);
+#define ADDITIONAL_OPTION_HANDLER \
+ if (nindy_ttyname != NULL) \
+ { \
+ if (catch_command_errors (nindy_open, nindy_ttyname, \
+ !batch, RETURN_MASK_ALL)) \
+ { \
+ if (execarg != NULL) \
+ catch_command_errors (target_load, execarg, !batch, \
+ RETURN_MASK_ALL); \
+ } \
+ }
+
+/* If configured for i960 target, we take control before main loop
+ and demand that we configure for a nindy target. */
+
+#define BEFORE_MAIN_LOOP_HOOK \
+ nindy_before_main_loop();
+
+extern void
+ nindy_before_main_loop (); /* In remote-nindy.c */
+
+/* FRAME_CHAIN_VALID returns zero if the given frame is the outermost one
+ and has no caller.
+
+ On the i960, each various target system type defines FRAME_CHAIN_VALID,
+ since it differs between NINDY and VxWorks, the two currently supported
+ targets types. */
+
+extern int nindy_frame_chain_valid (CORE_ADDR, struct frame_info *);
+#define FRAME_CHAIN_VALID(chain, thisframe) nindy_frame_chain_valid (chain, thisframe)
+
+extern int
+ nindy_frame_chain_valid (); /* See nindy-tdep.c */
+
+/* Sequence of bytes for breakpoint instruction */
+
+#define BREAKPOINT {0x00, 0x3e, 0x00, 0x66}
+
+/* Amount ip must be decremented by after a breakpoint.
+ * This is often the number of bytes in BREAKPOINT but not always.
+ */
+
+#define DECR_PC_AFTER_BREAK 0
diff --git a/gdb/config/i960/tm-vx960.h b/gdb/config/i960/tm-vx960.h
new file mode 100644
index 00000000000..16fc62ac6bb
--- /dev/null
+++ b/gdb/config/i960/tm-vx960.h
@@ -0,0 +1,52 @@
+/* Parameters for VxWorks Intel 960's, for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1993, 1998, 1999
+ 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 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 "i960/tm-i960.h"
+#include "tm-vxworks.h"
+
+/* Under VxWorks the IP isn't filled in. Skip it, go with RIP, which has
+ the real value. */
+#undef PC_REGNUM
+#define PC_REGNUM RIP_REGNUM
+
+/* We have more complex, useful breakpoints on the target.
+ Amount ip must be decremented by after a breakpoint. */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* We are guaranteed to have a zero frame pointer at bottom of stack, too. */
+
+#define FRAME_CHAIN_VALID(chain, thisframe) nonnull_frame_chain_valid (chain, thisframe)
+
+/* Breakpoint patching is handled at the target end in VxWorks. */
+/* #define BREAKPOINT {0x00, 0x3e, 0x00, 0x66} */
+
+/* Number of registers in a ptrace_getregs call. */
+
+#define VX_NUM_REGS (16 + 16 + 3)
+
+/* Number of registers in a ptrace_getfpregs call. */
+
+ /* @@ Can't use this -- the rdb library for the 960 target
+ doesn't support setting or retrieving FP regs. KR */
+
+/* #define VX_SIZE_FPREGS (REGISTER_RAW_SIZE (FP0_REGNUM) * 4) */
diff --git a/gdb/config/i960/vxworks960.mt b/gdb/config/i960/vxworks960.mt
new file mode 100644
index 00000000000..ad3293421f7
--- /dev/null
+++ b/gdb/config/i960/vxworks960.mt
@@ -0,0 +1,6 @@
+# Target: VxWorks running on an Intel 960
+TDEPFILES= i960-tdep.o remote-vx.o remote-vx960.o xdr_ld.o xdr_ptrace.o xdr_rdb.o
+TM_FILE= tm-vx960.h
+
+# Define this for the vx-share routines, which don't see param.h.
+MT_CFLAGS= -DI80960
diff --git a/gdb/config/ia64/aix.mh b/gdb/config/ia64/aix.mh
new file mode 100644
index 00000000000..e1805946970
--- /dev/null
+++ b/gdb/config/ia64/aix.mh
@@ -0,0 +1,8 @@
+# Host: Intel IA-64 running AIX
+
+XM_FILE= xm-aix.h
+
+NAT_FILE= nm-aix.h
+NATDEPFILES= corelow.o core-regset.o solib.o solib-aix5.o fork-child.o \
+ procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o \
+ ia64-aix-nat.o
diff --git a/gdb/config/ia64/aix.mt b/gdb/config/ia64/aix.mt
new file mode 100644
index 00000000000..0348146c3f5
--- /dev/null
+++ b/gdb/config/ia64/aix.mt
@@ -0,0 +1,4 @@
+# Target: Intel IA-64 running AIX
+
+TDEPFILES= ia64-tdep.o ia64-linux-tdep.o ia64-aix-tdep.o
+TM_FILE= tm-aix.h
diff --git a/gdb/config/ia64/linux.mh b/gdb/config/ia64/linux.mh
new file mode 100644
index 00000000000..65f30284e1c
--- /dev/null
+++ b/gdb/config/ia64/linux.mh
@@ -0,0 +1,10 @@
+# Host: Intel IA-64 running GNU/Linux
+
+XM_FILE= xm-linux.h
+
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o gcore.o \
+ core-aout.o core-regset.o ia64-linux-nat.o linux-proc.o \
+ proc-service.o thread-db.o lin-lwp.o
+
+LOADLIBES = -ldl -rdynamic
diff --git a/gdb/config/ia64/linux.mt b/gdb/config/ia64/linux.mt
new file mode 100644
index 00000000000..d841f75f37f
--- /dev/null
+++ b/gdb/config/ia64/linux.mt
@@ -0,0 +1,6 @@
+# Target: Intel IA-64 running GNU/Linux
+TDEPFILES= ia64-tdep.o ia64-aix-tdep.o ia64-linux-tdep.o \
+ solib.o solib-svr4.o solib-legacy.o
+TM_FILE= tm-linux.h
+
+GDBSERVER_DEPFILES = linux-low.o linux-ia64-low.o reg-ia64.o
diff --git a/gdb/config/ia64/nm-aix.h b/gdb/config/ia64/nm-aix.h
new file mode 100644
index 00000000000..3f6764c3027
--- /dev/null
+++ b/gdb/config/ia64/nm-aix.h
@@ -0,0 +1,37 @@
+/* Native support for AIX, for GDB, the GNU debugger.
+ Copyright 2000, 2001 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. */
+
+#ifndef NM_AIX_H
+#define NM_AIX_H
+
+#include "nm-sysv4.h"
+
+#ifndef AIX5
+#define AIX5 1
+#endif
+
+/* Type of the operation code for sending control messages to the
+ /proc/PID/ctl file */
+#define PROC_CTL_WORD_TYPE int
+
+#define GDB_GREGSET_T prgregset_t
+#define GDB_FPREGSET_T prfpregset_t
+
+#endif /* #ifndef NM_AIX_H */
diff --git a/gdb/config/ia64/nm-linux.h b/gdb/config/ia64/nm-linux.h
new file mode 100644
index 00000000000..2c980c0ad9a
--- /dev/null
+++ b/gdb/config/ia64/nm-linux.h
@@ -0,0 +1,79 @@
+/* Native support for GNU/Linux, for GDB, the GNU debugger.
+ Copyright 1999, 2000, 2001
+ 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. */
+
+#ifndef NM_LINUX_H
+#define NM_LINUX_H
+
+#include "nm-linux.h"
+
+/* Note: It seems likely that we'll have to eventually define
+ FETCH_INFERIOR_REGISTERS. But until that time, we'll make do
+ with the following. */
+
+#define CANNOT_FETCH_REGISTER(regno) ia64_cannot_fetch_register(regno)
+extern int ia64_cannot_fetch_register (int regno);
+
+#define CANNOT_STORE_REGISTER(regno) ia64_cannot_store_register(regno)
+extern int ia64_cannot_store_register (int regno);
+
+#ifdef GDBSERVER
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = ia64_register_u_addr ((blockend),(regno));
+
+extern int ia64_register_u_addr(int, int);
+#endif /* GDBSERVER */
+
+#define U_REGS_OFFSET 0
+
+#define PTRACE_ARG3_TYPE long
+#define PTRACE_XFER_TYPE long
+
+/* Hardware watchpoints */
+
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1
+
+/* The IA-64 architecture can step over a watch point (without triggering
+ it again) if the "dd" (data debug fault disable) bit in the processor
+ status word is set.
+
+ This PSR bit is set in ia64_linux_stopped_by_watchpoint when the
+ code there has determined that a hardware watchpoint has indeed
+ been hit. The CPU will then be able to execute one instruction
+ without triggering a watchpoint. */
+#define HAVE_STEPPABLE_WATCHPOINT 1
+
+#define STOPPED_BY_WATCHPOINT(W) \
+ ia64_linux_stopped_by_watchpoint (inferior_ptid)
+extern CORE_ADDR ia64_linux_stopped_by_watchpoint (ptid_t ptid);
+
+#define target_insert_watchpoint(addr, len, type) \
+ ia64_linux_insert_watchpoint (inferior_ptid, addr, len, type)
+extern int ia64_linux_insert_watchpoint (ptid_t ptid, CORE_ADDR addr,
+ int len, int rw);
+
+#define target_remove_watchpoint(addr, len, type) \
+ ia64_linux_remove_watchpoint (inferior_ptid, addr, len)
+extern int ia64_linux_remove_watchpoint (ptid_t ptid, CORE_ADDR addr,
+ int len);
+
+#endif /* #ifndef NM_LINUX_H */
diff --git a/gdb/config/ia64/tm-aix.h b/gdb/config/ia64/tm-aix.h
new file mode 100644
index 00000000000..0160140c680
--- /dev/null
+++ b/gdb/config/ia64/tm-aix.h
@@ -0,0 +1,32 @@
+/* Definitions to target GDB to GNU/Linux on IA-64 running AIX.
+ Copyright 2000, 2001 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. */
+
+#ifndef TM_AIX_H
+#define TM_AIX_H
+
+#include "ia64/tm-ia64.h"
+#include "tm-sysv4.h"
+
+#define TARGET_ELF64
+
+extern int ia64_aix_in_sigtramp (CORE_ADDR pc, char *func_name);
+#define IN_SIGTRAMP(pc,func_name) ia64_aix_in_sigtramp (pc, func_name)
+
+#endif /* #ifndef TM_AIX_H */
diff --git a/gdb/config/ia64/tm-ia64.h b/gdb/config/ia64/tm-ia64.h
new file mode 100644
index 00000000000..d08e59bccd5
--- /dev/null
+++ b/gdb/config/ia64/tm-ia64.h
@@ -0,0 +1,252 @@
+/* Definitions to target GDB to GNU/Linux on an ia64 architecture.
+ Copyright 1992, 1993, 2000 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. */
+
+#ifndef TM_IA64_H
+#define TM_IA64_H
+
+#if !defined(GDBSERVER)
+
+#define GDB_MULTI_ARCH 1
+
+#else /* defines needed for GDBSERVER */
+
+/* Say how long (ordinary) registers are. This is a piece of bogosity
+ used in push_word and a few other places; REGISTER_RAW_SIZE is the
+ real way to know how big a register is. */
+
+#define REGISTER_SIZE 8
+
+#undef NUM_REGS
+#define NUM_REGS 590
+
+/* Some pseudo register numbers */
+
+#define PC_REGNUM IA64_IP_REGNUM
+#define SP_REGNUM IA64_GR12_REGNUM
+#define FP_REGNUM IA64_VFP_REGNUM
+
+/* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'. On the ia64, all registers
+ fit in 64 bits except for the floating point registers which require
+ 84 bits. But 84 isn't a nice number, so we'll just allocate 128
+ bits for each of these. The expression below says that we
+ need 8 bytes for each register, plus an additional 8 bytes for each
+ of the 128 floating point registers. */
+
+#define REGISTER_BYTES (NUM_REGS*8+128*8)
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#define REGISTER_BYTE(N) (((N) * 8) \
+ + ((N) <= IA64_FR0_REGNUM ? 0 : 8 * (((N) > IA64_FR127_REGNUM) ? 128 : (N) - IA64_FR0_REGNUM)))
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. */
+
+#define REGISTER_RAW_SIZE(N) \
+ ((IA64_FR0_REGNUM <= (N) && (N) <= IA64_FR127_REGNUM) ? 16 : 8)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#define MAX_REGISTER_RAW_SIZE 16
+
+
+#define GDBSERVER_RESUME_REGS { IA64_IP_REGNUM, IA64_PSR_REGNUM, SP_REGNUM, IA64_BSP_REGNUM, IA64_CFM_REGNUM }
+
+#endif /* GDBSERVER */
+
+
+/* Register numbers of various important registers */
+
+/* General registers; there are 128 of these 64 bit wide registers. The
+ first 32 are static and the last 96 are stacked. */
+#define IA64_GR0_REGNUM 0
+#define IA64_GR1_REGNUM (IA64_GR0_REGNUM+1)
+#define IA64_GR2_REGNUM (IA64_GR0_REGNUM+2)
+#define IA64_GR3_REGNUM (IA64_GR0_REGNUM+3)
+#define IA64_GR4_REGNUM (IA64_GR0_REGNUM+4)
+#define IA64_GR5_REGNUM (IA64_GR0_REGNUM+5)
+#define IA64_GR6_REGNUM (IA64_GR0_REGNUM+6)
+#define IA64_GR7_REGNUM (IA64_GR0_REGNUM+7)
+#define IA64_GR8_REGNUM (IA64_GR0_REGNUM+8)
+#define IA64_GR9_REGNUM (IA64_GR0_REGNUM+9)
+#define IA64_GR10_REGNUM (IA64_GR0_REGNUM+10)
+#define IA64_GR11_REGNUM (IA64_GR0_REGNUM+11)
+#define IA64_GR12_REGNUM (IA64_GR0_REGNUM+12)
+#define IA64_GR31_REGNUM (IA64_GR0_REGNUM+31)
+#define IA64_GR32_REGNUM (IA64_GR0_REGNUM+32)
+#define IA64_GR127_REGNUM (IA64_GR0_REGNUM+127)
+
+/* Floating point registers; 128 82-bit wide registers */
+#define IA64_FR0_REGNUM 128
+#define IA64_FR1_REGNUM (IA64_FR0_REGNUM+1)
+#define IA64_FR2_REGNUM (IA64_FR0_REGNUM+2)
+#define IA64_FR8_REGNUM (IA64_FR0_REGNUM+8)
+#define IA64_FR9_REGNUM (IA64_FR0_REGNUM+9)
+#define IA64_FR10_REGNUM (IA64_FR0_REGNUM+10)
+#define IA64_FR11_REGNUM (IA64_FR0_REGNUM+11)
+#define IA64_FR12_REGNUM (IA64_FR0_REGNUM+12)
+#define IA64_FR13_REGNUM (IA64_FR0_REGNUM+13)
+#define IA64_FR14_REGNUM (IA64_FR0_REGNUM+14)
+#define IA64_FR15_REGNUM (IA64_FR0_REGNUM+15)
+#define IA64_FR16_REGNUM (IA64_FR0_REGNUM+16)
+#define IA64_FR31_REGNUM (IA64_FR0_REGNUM+31)
+#define IA64_FR32_REGNUM (IA64_FR0_REGNUM+32)
+#define IA64_FR127_REGNUM (IA64_FR0_REGNUM+127)
+
+/* Predicate registers; There are 64 of these one bit registers.
+ It'd be more convenient (implementation-wise) to use a single
+ 64 bit word with all of these register in them. Note that there's
+ also a IA64_PR_REGNUM below which contains all the bits and is used for
+ communicating the actual values to the target. */
+
+#define IA64_PR0_REGNUM 256
+#define IA64_PR1_REGNUM (IA64_PR0_REGNUM+1)
+#define IA64_PR2_REGNUM (IA64_PR0_REGNUM+2)
+#define IA64_PR3_REGNUM (IA64_PR0_REGNUM+3)
+#define IA64_PR4_REGNUM (IA64_PR0_REGNUM+4)
+#define IA64_PR5_REGNUM (IA64_PR0_REGNUM+5)
+#define IA64_PR6_REGNUM (IA64_PR0_REGNUM+6)
+#define IA64_PR7_REGNUM (IA64_PR0_REGNUM+7)
+#define IA64_PR8_REGNUM (IA64_PR0_REGNUM+8)
+#define IA64_PR9_REGNUM (IA64_PR0_REGNUM+9)
+#define IA64_PR10_REGNUM (IA64_PR0_REGNUM+10)
+#define IA64_PR11_REGNUM (IA64_PR0_REGNUM+11)
+#define IA64_PR12_REGNUM (IA64_PR0_REGNUM+12)
+#define IA64_PR13_REGNUM (IA64_PR0_REGNUM+13)
+#define IA64_PR14_REGNUM (IA64_PR0_REGNUM+14)
+#define IA64_PR15_REGNUM (IA64_PR0_REGNUM+15)
+#define IA64_PR16_REGNUM (IA64_PR0_REGNUM+16)
+#define IA64_PR17_REGNUM (IA64_PR0_REGNUM+17)
+#define IA64_PR18_REGNUM (IA64_PR0_REGNUM+18)
+#define IA64_PR19_REGNUM (IA64_PR0_REGNUM+19)
+#define IA64_PR20_REGNUM (IA64_PR0_REGNUM+20)
+#define IA64_PR21_REGNUM (IA64_PR0_REGNUM+21)
+#define IA64_PR22_REGNUM (IA64_PR0_REGNUM+22)
+#define IA64_PR23_REGNUM (IA64_PR0_REGNUM+23)
+#define IA64_PR24_REGNUM (IA64_PR0_REGNUM+24)
+#define IA64_PR25_REGNUM (IA64_PR0_REGNUM+25)
+#define IA64_PR26_REGNUM (IA64_PR0_REGNUM+26)
+#define IA64_PR27_REGNUM (IA64_PR0_REGNUM+27)
+#define IA64_PR28_REGNUM (IA64_PR0_REGNUM+28)
+#define IA64_PR29_REGNUM (IA64_PR0_REGNUM+29)
+#define IA64_PR30_REGNUM (IA64_PR0_REGNUM+30)
+#define IA64_PR31_REGNUM (IA64_PR0_REGNUM+31)
+#define IA64_PR32_REGNUM (IA64_PR0_REGNUM+32)
+#define IA64_PR33_REGNUM (IA64_PR0_REGNUM+33)
+#define IA64_PR34_REGNUM (IA64_PR0_REGNUM+34)
+#define IA64_PR35_REGNUM (IA64_PR0_REGNUM+35)
+#define IA64_PR36_REGNUM (IA64_PR0_REGNUM+36)
+#define IA64_PR37_REGNUM (IA64_PR0_REGNUM+37)
+#define IA64_PR38_REGNUM (IA64_PR0_REGNUM+38)
+#define IA64_PR39_REGNUM (IA64_PR0_REGNUM+39)
+#define IA64_PR40_REGNUM (IA64_PR0_REGNUM+40)
+#define IA64_PR41_REGNUM (IA64_PR0_REGNUM+41)
+#define IA64_PR42_REGNUM (IA64_PR0_REGNUM+42)
+#define IA64_PR43_REGNUM (IA64_PR0_REGNUM+43)
+#define IA64_PR44_REGNUM (IA64_PR0_REGNUM+44)
+#define IA64_PR45_REGNUM (IA64_PR0_REGNUM+45)
+#define IA64_PR46_REGNUM (IA64_PR0_REGNUM+46)
+#define IA64_PR47_REGNUM (IA64_PR0_REGNUM+47)
+#define IA64_PR48_REGNUM (IA64_PR0_REGNUM+48)
+#define IA64_PR49_REGNUM (IA64_PR0_REGNUM+49)
+#define IA64_PR50_REGNUM (IA64_PR0_REGNUM+50)
+#define IA64_PR51_REGNUM (IA64_PR0_REGNUM+51)
+#define IA64_PR52_REGNUM (IA64_PR0_REGNUM+52)
+#define IA64_PR53_REGNUM (IA64_PR0_REGNUM+53)
+#define IA64_PR54_REGNUM (IA64_PR0_REGNUM+54)
+#define IA64_PR55_REGNUM (IA64_PR0_REGNUM+55)
+#define IA64_PR56_REGNUM (IA64_PR0_REGNUM+56)
+#define IA64_PR57_REGNUM (IA64_PR0_REGNUM+57)
+#define IA64_PR58_REGNUM (IA64_PR0_REGNUM+58)
+#define IA64_PR59_REGNUM (IA64_PR0_REGNUM+59)
+#define IA64_PR60_REGNUM (IA64_PR0_REGNUM+60)
+#define IA64_PR61_REGNUM (IA64_PR0_REGNUM+61)
+#define IA64_PR62_REGNUM (IA64_PR0_REGNUM+62)
+#define IA64_PR63_REGNUM (IA64_PR0_REGNUM+63)
+
+
+/* Branch registers: 8 64-bit registers for holding branch targets */
+#define IA64_BR0_REGNUM 320
+#define IA64_BR1_REGNUM (IA64_BR0_REGNUM+1)
+#define IA64_BR2_REGNUM (IA64_BR0_REGNUM+2)
+#define IA64_BR3_REGNUM (IA64_BR0_REGNUM+3)
+#define IA64_BR4_REGNUM (IA64_BR0_REGNUM+4)
+#define IA64_BR5_REGNUM (IA64_BR0_REGNUM+5)
+#define IA64_BR6_REGNUM (IA64_BR0_REGNUM+6)
+#define IA64_BR7_REGNUM (IA64_BR0_REGNUM+7)
+
+/* Virtual frame pointer; this matches IA64_FRAME_POINTER_REGNUM in
+ gcc/config/ia64/ia64.h. */
+#define IA64_VFP_REGNUM 328
+
+/* Virtual return address pointer; this matches IA64_RETURN_ADDRESS_POINTER_REGNUM
+ in gcc/config/ia64/ia64.h. */
+#define IA64_VRAP_REGNUM 329
+
+/* Predicate registers: There are 64 of these 1-bit registers. We
+ define a single register which is used to communicate these values
+ to/from the target. We will somehow contrive to make it appear that
+ IA64_PR0_REGNUM thru IA64_PR63_REGNUM hold the actual values. */
+#define IA64_PR_REGNUM 330
+
+/* Instruction pointer: 64 bits wide */
+#define IA64_IP_REGNUM 331
+
+/* Process Status Register */
+#define IA64_PSR_REGNUM 332
+
+/* Current Frame Marker (Raw form may be the cr.ifs) */
+#define IA64_CFM_REGNUM 333
+
+/* Application registers; 128 64-bit wide registers possible, but some
+ of them are reserved */
+#define IA64_AR0_REGNUM 334
+#define IA64_KR0_REGNUM (IA64_AR0_REGNUM+0)
+#define IA64_KR7_REGNUM (IA64_KR0_REGNUM+7)
+
+#define IA64_RSC_REGNUM (IA64_AR0_REGNUM+16)
+#define IA64_BSP_REGNUM (IA64_AR0_REGNUM+17)
+#define IA64_BSPSTORE_REGNUM (IA64_AR0_REGNUM+18)
+#define IA64_RNAT_REGNUM (IA64_AR0_REGNUM+19)
+#define IA64_FCR_REGNUM (IA64_AR0_REGNUM+21)
+#define IA64_EFLAG_REGNUM (IA64_AR0_REGNUM+24)
+#define IA64_CSD_REGNUM (IA64_AR0_REGNUM+25)
+#define IA64_SSD_REGNUM (IA64_AR0_REGNUM+26)
+#define IA64_CFLG_REGNUM (IA64_AR0_REGNUM+27)
+#define IA64_FSR_REGNUM (IA64_AR0_REGNUM+28)
+#define IA64_FIR_REGNUM (IA64_AR0_REGNUM+29)
+#define IA64_FDR_REGNUM (IA64_AR0_REGNUM+30)
+#define IA64_CCV_REGNUM (IA64_AR0_REGNUM+32)
+#define IA64_UNAT_REGNUM (IA64_AR0_REGNUM+36)
+#define IA64_FPSR_REGNUM (IA64_AR0_REGNUM+40)
+#define IA64_ITC_REGNUM (IA64_AR0_REGNUM+44)
+#define IA64_PFS_REGNUM (IA64_AR0_REGNUM+64)
+#define IA64_LC_REGNUM (IA64_AR0_REGNUM+65)
+#define IA64_EC_REGNUM (IA64_AR0_REGNUM+66)
+
+/* NAT (Not A Thing) Bits for the general registers; there are 128 of these */
+#define IA64_NAT0_REGNUM 462
+#define IA64_NAT31_REGNUM (IA64_NAT0_REGNUM+31)
+#define IA64_NAT32_REGNUM (IA64_NAT0_REGNUM+32)
+#define IA64_NAT127_REGNUM (IA64_NAT0_REGNUM+127)
+
+#endif /* TM_IA64_H */
diff --git a/gdb/config/ia64/tm-linux.h b/gdb/config/ia64/tm-linux.h
new file mode 100644
index 00000000000..f716d83ae41
--- /dev/null
+++ b/gdb/config/ia64/tm-linux.h
@@ -0,0 +1,34 @@
+/* Definitions to target GDB to GNU/Linux on IA-64 Linux.
+ Copyright 1992, 1993, 2000 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. */
+
+#ifndef TM_LINUX_H
+#define TM_LINUX_H
+
+#define IA64_GNULINUX_TARGET
+
+#include "ia64/tm-ia64.h"
+#include "tm-linux.h"
+
+#define TARGET_ELF64
+
+extern int ia64_linux_in_sigtramp (CORE_ADDR pc, char *func_name);
+#define IN_SIGTRAMP(pc,func_name) ia64_linux_in_sigtramp (pc, func_name)
+
+#endif /* #ifndef TM_LINUX_H */
diff --git a/gdb/config/ia64/xm-aix.h b/gdb/config/ia64/xm-aix.h
new file mode 100644
index 00000000000..6ca026d493f
--- /dev/null
+++ b/gdb/config/ia64/xm-aix.h
@@ -0,0 +1,28 @@
+/* Native support for AIX, for GDB, the GNU debugger.
+ Copyright 2000, 2001 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. */
+
+#ifndef XM_AIX_H
+#define XM_AIX_H
+
+/* Pick up more stuff from the generic SVR4 host include file. */
+
+#include "xm-sysv4.h"
+
+#endif /* #ifndef XM_AIX_H */
diff --git a/gdb/config/ia64/xm-linux.h b/gdb/config/ia64/xm-linux.h
new file mode 100644
index 00000000000..adf6b21b4cc
--- /dev/null
+++ b/gdb/config/ia64/xm-linux.h
@@ -0,0 +1,28 @@
+/* Native support for GNU/Linux, for GDB, the GNU debugger.
+ Copyright 1999, 2000, 2001 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. */
+
+#ifndef XM_LINUX_H
+#define XM_LINUX_H
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+#define KERNEL_U_ADDR 0x0
+
+#endif /* #ifndef XM_LINUX_H */
diff --git a/gdb/config/m32r/m32r.mt b/gdb/config/m32r/m32r.mt
new file mode 100644
index 00000000000..a200853b602
--- /dev/null
+++ b/gdb/config/m32r/m32r.mt
@@ -0,0 +1,5 @@
+# Target: Mitsubishi m32r processor
+TDEPFILES= m32r-tdep.o monitor.o m32r-rom.o dsrec.o
+TM_FILE= tm-m32r.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/m32r/libsim.a
diff --git a/gdb/config/m32r/tm-m32r.h b/gdb/config/m32r/tm-m32r.h
new file mode 100644
index 00000000000..75bc7b231a6
--- /dev/null
+++ b/gdb/config/m32r/tm-m32r.h
@@ -0,0 +1,234 @@
+/* Parameters for execution on a Mitsubishi m32r processor.
+ Copyright 1996, 1997 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 "regcache.h"
+
+/* Used by mswin. */
+#define TARGET_M32R 1
+
+/* mvs_check REGISTER_NAMES */
+#define REGISTER_NAMES \
+{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "r8", "r9", "r10", "r11", "r12", "fp", "lr", "sp", \
+ "psw", "cbr", "spi", "spu", "bpc", "pc", "accl", "acch", \
+ /* "cond", "sm", "bsm", "ie", "bie", "bcarry", */ \
+}
+/* mvs_check NUM_REGS */
+#define NUM_REGS 24
+
+/* mvs_check REGISTER_SIZE */
+#define REGISTER_SIZE 4
+/* mvs_check MAX_REGISTER_RAW_SIZE */
+#define MAX_REGISTER_RAW_SIZE 4
+
+/* mvs_check *_REGNUM */
+#define R0_REGNUM 0
+#define STRUCT_RETURN_REGNUM 0
+#define ARG0_REGNUM 0
+#define ARGLAST_REGNUM 3
+#define V0_REGNUM 0
+#define V1_REGNUM 1
+#define FP_REGNUM 13
+#define RP_REGNUM 14
+#define SP_REGNUM 15
+#define PSW_REGNUM 16
+#define CBR_REGNUM 17
+#define SPI_REGNUM 18
+#define SPU_REGNUM 19
+#define BPC_REGNUM 20
+#define PC_REGNUM 21
+#define ACCL_REGNUM 22
+#define ACCH_REGNUM 23
+
+/* mvs_check REGISTER_BYTES */
+#define REGISTER_BYTES (NUM_REGS * 4)
+
+/* mvs_check REGISTER_VIRTUAL_TYPE */
+#define REGISTER_VIRTUAL_TYPE(REG) builtin_type_int
+
+/* mvs_check REGISTER_BYTE */
+#define REGISTER_BYTE(REG) ((REG) * 4)
+/* mvs_check REGISTER_VIRTUAL_SIZE */
+#define REGISTER_VIRTUAL_SIZE(REG) 4
+/* mvs_check REGISTER_RAW_SIZE */
+#define REGISTER_RAW_SIZE(REG) 4
+
+/* mvs_check MAX_REGISTER_VIRTUAL_SIZE */
+#define MAX_REGISTER_VIRTUAL_SIZE 4
+
+/* mvs_check BREAKPOINT */
+#define BREAKPOINT {0x10, 0xf1}
+
+/* mvs_no_check FUNCTION_START_OFFSET */
+#define FUNCTION_START_OFFSET 0
+
+/* mvs_check DECR_PC_AFTER_BREAK */
+#define DECR_PC_AFTER_BREAK 0
+
+/* mvs_check INNER_THAN */
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+/* mvs_check SAVED_PC_AFTER_CALL */
+#define SAVED_PC_AFTER_CALL(fi) read_register (RP_REGNUM)
+
+struct frame_info;
+struct frame_saved_regs;
+struct type;
+struct value;
+
+/* Define other aspects of the stack frame.
+ We keep the offsets of all saved registers, 'cause we need 'em a lot!
+ We also keep the current size of the stack frame, and whether
+ the frame pointer is valid (for frameless functions, and when we're
+ still in the prologue of a function with a frame) */
+
+/* mvs_check EXTRA_FRAME_INFO */
+#define EXTRA_FRAME_INFO \
+ struct frame_saved_regs fsr; \
+ int framesize; \
+ int using_frame_pointer;
+
+
+extern void m32r_init_extra_frame_info (struct frame_info *fi);
+/* mvs_check INIT_EXTRA_FRAME_INFO */
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) m32r_init_extra_frame_info (fi)
+/* mvs_no_check INIT_FRAME_PC */
+#define INIT_FRAME_PC /* Not necessary */
+
+extern void
+m32r_frame_find_saved_regs (struct frame_info *fi,
+ struct frame_saved_regs *regaddr);
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame. */
+
+/* mvs_check FRAME_FIND_SAVED_REGS */
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+ m32r_frame_find_saved_regs(frame_info, &(frame_saved_regs))
+
+extern CORE_ADDR m32r_frame_chain (struct frame_info *fi);
+/* mvs_check FRAME_CHAIN */
+#define FRAME_CHAIN(fi) m32r_frame_chain (fi)
+
+#define FRAME_CHAIN_VALID(fp, frame) generic_file_frame_chain_valid (fp, frame)
+
+extern CORE_ADDR m32r_find_callers_reg (struct frame_info *fi, int regnum);
+extern CORE_ADDR m32r_frame_saved_pc (struct frame_info *);
+/* mvs_check FRAME_SAVED_PC */
+#define FRAME_SAVED_PC(fi) m32r_frame_saved_pc (fi)
+
+/* mvs_check EXTRACT_RETURN_VALUE */
+#define EXTRACT_RETURN_VALUE(TYPE, REGBUF, VALBUF) \
+ memcpy ((VALBUF), \
+ (char *)(REGBUF) + REGISTER_BYTE (V0_REGNUM) + \
+ ((TYPE_LENGTH (TYPE) > 4 ? 8 : 4) - TYPE_LENGTH (TYPE)), \
+ TYPE_LENGTH (TYPE))
+
+/* mvs_check STORE_RETURN_VALUE */
+#define STORE_RETURN_VALUE(TYPE, VALBUF) \
+ write_register_bytes(REGISTER_BYTE (V0_REGNUM) + \
+ ((TYPE_LENGTH (TYPE) > 4 ? 8:4) - TYPE_LENGTH (TYPE)),\
+ (VALBUF), TYPE_LENGTH (TYPE));
+
+extern CORE_ADDR m32r_skip_prologue (CORE_ADDR pc);
+/* mvs_check SKIP_PROLOGUE */
+#define SKIP_PROLOGUE(pc) (m32r_skip_prologue (pc))
+
+/* mvs_no_check FRAME_ARGS_SKIP */
+#define FRAME_ARGS_SKIP 0
+
+/* mvs_no_check FRAME_ARGS_ADDRESS */
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+/* mvs_no_check FRAME_LOCALS_ADDRESS */
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+/* mvs_no_check FRAME_NUM_ARGS */
+#define FRAME_NUM_ARGS(fi) (-1)
+
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (1)
+
+extern void m32r_write_sp (CORE_ADDR val);
+#define TARGET_WRITE_SP m32r_write_sp
+
+
+
+
+
+
+/* struct passing and returning stuff */
+#define STORE_STRUCT_RETURN(STRUCT_ADDR, SP) \
+ write_register (0, STRUCT_ADDR)
+
+extern use_struct_convention_fn m32r_use_struct_convention;
+#define USE_STRUCT_CONVENTION(GCC_P, TYPE) m32r_use_struct_convention (GCC_P, TYPE)
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+ extract_address (REGBUF + REGISTER_BYTE (V0_REGNUM), \
+ REGISTER_RAW_SIZE (V0_REGNUM))
+
+#define REG_STRUCT_HAS_ADDR(gcc_p,type) (TYPE_LENGTH (type) > 8)
+
+
+/* generic dummy frame stuff */
+
+#define PUSH_DUMMY_FRAME generic_push_dummy_frame ()
+#define PC_IN_CALL_DUMMY(PC, SP, FP) generic_pc_in_call_dummy (PC, SP, FP)
+
+
+/* target-specific dummy_frame stuff */
+
+extern struct frame_info *m32r_pop_frame (struct frame_info *frame);
+/* mvs_check POP_FRAME */
+#define POP_FRAME m32r_pop_frame (get_current_frame ())
+
+/* mvs_no_check STACK_ALIGN */
+/* #define STACK_ALIGN(x) ((x + 3) & ~3) */
+
+extern CORE_ADDR m32r_push_return_address (CORE_ADDR, CORE_ADDR);
+extern CORE_ADDR m32r_push_arguments (int nargs,
+ struct value **args,
+ CORE_ADDR sp,
+ unsigned char struct_return,
+ CORE_ADDR struct_addr);
+
+
+
+/* mvs_no_check PUSH_ARGUMENTS */
+#define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \
+ (m32r_push_arguments (NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR))
+
+#define PUSH_RETURN_ADDRESS(PC, SP) m32r_push_return_address (PC, SP)
+
+/* override the standard get_saved_register function with
+ one that takes account of generic CALL_DUMMY frames */
+#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \
+ generic_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
+
+
+#define USE_GENERIC_DUMMY_FRAMES 1
+#define CALL_DUMMY {0}
+#define CALL_DUMMY_LENGTH (0)
+#define CALL_DUMMY_START_OFFSET (0)
+#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
+#define FIX_CALL_DUMMY(DUMMY1, STARTADDR, FUNADDR, NARGS, ARGS, TYPE, GCCP)
+#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
+#define CALL_DUMMY_ADDRESS() entry_point_address ()
diff --git a/gdb/config/m68hc11/m68hc11.mt b/gdb/config/m68hc11/m68hc11.mt
new file mode 100644
index 00000000000..5e25eeec673
--- /dev/null
+++ b/gdb/config/m68hc11/m68hc11.mt
@@ -0,0 +1,6 @@
+# Target: Motorola 68HC11 processor
+TDEPFILES= m68hc11-tdep.o
+TM_FILE= tm-m68hc11.h
+SIM_OBS= remote-sim.o
+SIM= ../sim/m68hc11/libsim.a -lm
+
diff --git a/gdb/config/m68k/3b1.mh b/gdb/config/m68k/3b1.mh
new file mode 100644
index 00000000000..e305e672d6c
--- /dev/null
+++ b/gdb/config/m68k/3b1.mh
@@ -0,0 +1,12 @@
+# Host: AT&T 3b1/Unix pc
+# I don't think cc has been tried. -traditional for <sys/ioctl.h>
+# (not sure whether necessary).
+CC= gcc -traditional
+# GCC runs out of virtual memory.
+# A separate CC for pinsn routines is no longer supported, though.
+# FIXME -- someone unlucky enough to have a 3B1, let bug-gcc@prep.ai.mit.edu
+# know what works and what fails on the 3B1.
+#PINSN_CC= cc
+
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o core-aout.o
+XM_FILE= xm-3b1.h
diff --git a/gdb/config/m68k/3b1.mt b/gdb/config/m68k/3b1.mt
new file mode 100644
index 00000000000..4c5d9d4bb07
--- /dev/null
+++ b/gdb/config/m68k/3b1.mt
@@ -0,0 +1,3 @@
+# Target: AT&T 3b1/Unix pc
+TDEPFILES= m68k-tdep.o
+TM_FILE= tm-3b1.h
diff --git a/gdb/config/m68k/apollo68b.mh b/gdb/config/m68k/apollo68b.mh
new file mode 100644
index 00000000000..cf2770b35ad
--- /dev/null
+++ b/gdb/config/m68k/apollo68b.mh
@@ -0,0 +1,5 @@
+# Host: Apollo m68k, BSD mode.
+
+XM_FILE= xm-apollo68b.h
+NAT_FILE= nm-apollo68b.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o a68v-nat.o
diff --git a/gdb/config/m68k/apollo68b.mt b/gdb/config/m68k/apollo68b.mt
new file mode 100644
index 00000000000..2383d3b6156
--- /dev/null
+++ b/gdb/config/m68k/apollo68b.mt
@@ -0,0 +1,3 @@
+# Target: Apollo m68k in BSD mode
+TDEPFILES= m68k-tdep.o dstread.o
+TM_FILE= tm-apollo68b.h
diff --git a/gdb/config/m68k/apollo68v.mh b/gdb/config/m68k/apollo68v.mh
new file mode 100644
index 00000000000..6610e665f48
--- /dev/null
+++ b/gdb/config/m68k/apollo68v.mh
@@ -0,0 +1,10 @@
+# Host: Apollo, System V mode (?)
+
+XM_FILE= xm-apollo68v.h
+XM_CLIBS= -lPW
+
+NAT_FILE= nm-apollo68v.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o a68v-nat.o
+
+RANLIB=echo >/dev/null
+CC= cc -A ansi -A runtype,any -A systype,any -U__STDC__ -DNO_SYS_FILE
diff --git a/gdb/config/m68k/cisco.mt b/gdb/config/m68k/cisco.mt
new file mode 100644
index 00000000000..bc2e9214d7f
--- /dev/null
+++ b/gdb/config/m68k/cisco.mt
@@ -0,0 +1,3 @@
+# Target: Cisco Router with 68K processor
+TDEPFILES= m68k-tdep.o corelow.o core-aout.o
+TM_FILE= tm-cisco.h
diff --git a/gdb/config/m68k/delta68.mh b/gdb/config/m68k/delta68.mh
new file mode 100644
index 00000000000..5492af08d73
--- /dev/null
+++ b/gdb/config/m68k/delta68.mh
@@ -0,0 +1,5 @@
+# Host: Motorola Delta Series sysV68 R3V7.1
+
+XM_FILE= xm-delta68.h
+NAT_FILE= nm-delta68.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o core-aout.o delta68-nat.o
diff --git a/gdb/config/m68k/delta68.mt b/gdb/config/m68k/delta68.mt
new file mode 100644
index 00000000000..2761329f2c8
--- /dev/null
+++ b/gdb/config/m68k/delta68.mt
@@ -0,0 +1,3 @@
+# Motorola Delta Series sysV68 R3V7.1
+TDEPFILES= m68k-tdep.o
+TM_FILE= tm-delta68.h
diff --git a/gdb/config/m68k/dpx2.mh b/gdb/config/m68k/dpx2.mh
new file mode 100644
index 00000000000..25ed85ee6fd
--- /dev/null
+++ b/gdb/config/m68k/dpx2.mh
@@ -0,0 +1,6 @@
+# Host: Bull DPX2 (68k, System V release 3)
+
+XM_FILE= xm-dpx2.h
+
+NAT_FILE= nm-dpx2.h
+NATDEPFILES= infptrace.o corelow.o core-aout.o inftarg.o dpx2-nat.o fork-child.o
diff --git a/gdb/config/m68k/dpx2.mt b/gdb/config/m68k/dpx2.mt
new file mode 100644
index 00000000000..5bbbbe6fd8d
--- /dev/null
+++ b/gdb/config/m68k/dpx2.mt
@@ -0,0 +1,3 @@
+# Target: Bull DPX2 (68k, System V release 3)
+TDEPFILES= m68k-tdep.o
+TM_FILE= tm-dpx2.h
diff --git a/gdb/config/m68k/es1800.mt b/gdb/config/m68k/es1800.mt
new file mode 100644
index 00000000000..d809c610718
--- /dev/null
+++ b/gdb/config/m68k/es1800.mt
@@ -0,0 +1,9 @@
+# Target: Ericsson ES-1800 emulator (remote) for m68k.
+
+# remote-es.o should perhaps be part of the standard monitor.mt
+# configuration, if it is desirable to reduce the number of different
+# configurations. However, before that happens remote-es.c has to be
+# fixed to compile on a DOS host.
+
+TDEPFILES= m68k-tdep.o remote-es.o
+TM_FILE= tm-es1800.h
diff --git a/gdb/config/m68k/hp300bsd.mh b/gdb/config/m68k/hp300bsd.mh
new file mode 100644
index 00000000000..b0b186d671e
--- /dev/null
+++ b/gdb/config/m68k/hp300bsd.mh
@@ -0,0 +1,6 @@
+# Host: Hewlett-Packard 9000 series 300, running BSD
+
+XM_FILE= xm-hp300bsd.h
+
+NAT_FILE= nm-hp300bsd.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o core-aout.o
diff --git a/gdb/config/m68k/hp300bsd.mt b/gdb/config/m68k/hp300bsd.mt
new file mode 100644
index 00000000000..cbcc5edb7db
--- /dev/null
+++ b/gdb/config/m68k/hp300bsd.mt
@@ -0,0 +1,3 @@
+# Target: Hewlett-Packard 9000 series 300, running BSD
+TDEPFILES= m68k-tdep.o
+TM_FILE= tm-hp300bsd.h
diff --git a/gdb/config/m68k/hp300hpux.mh b/gdb/config/m68k/hp300hpux.mh
new file mode 100644
index 00000000000..8ceb1872ca5
--- /dev/null
+++ b/gdb/config/m68k/hp300hpux.mh
@@ -0,0 +1,8 @@
+# Host: Hewlett-Packard 9000 series 300, running HPUX
+# The following is true because gcc uses a different .o file format
+# than the native HPUX compiler
+
+XM_FILE= xm-hp300hpux.h
+
+NAT_FILE= nm-hp300hpux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o hp300ux-nat.o corelow.o core-aout.o
diff --git a/gdb/config/m68k/hp300hpux.mt b/gdb/config/m68k/hp300hpux.mt
new file mode 100644
index 00000000000..0fa801dee25
--- /dev/null
+++ b/gdb/config/m68k/hp300hpux.mt
@@ -0,0 +1,8 @@
+# Target: Hewlett-Packard 9000 series 300, running HPUX
+
+#msg Note that GDB can only read symbols from programs that were
+#msg compiled with GCC using GAS.
+#msg
+
+TDEPFILES= m68k-tdep.o
+TM_FILE= tm-hp300hpux.h
diff --git a/gdb/config/m68k/linux.mh b/gdb/config/m68k/linux.mh
new file mode 100644
index 00000000000..f94df64c104
--- /dev/null
+++ b/gdb/config/m68k/linux.mh
@@ -0,0 +1,14 @@
+# Host: Motorola m68k running GNU/Linux.
+
+XM_FILE= xm-linux.h
+
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o \
+ corelow.o core-aout.o m68klinux-nat.o linux-proc.o gcore.o \
+ proc-service.o thread-db.o lin-lwp.o
+
+# The dynamically loaded libthread_db needs access to symbols in the
+# gdb executable.
+LOADLIBES = -ldl -rdynamic
+
+GDBSERVER_DEPFILES = linux-low.o linux-m68k-low.o reg-m68k.o
diff --git a/gdb/config/m68k/linux.mt b/gdb/config/m68k/linux.mt
new file mode 100644
index 00000000000..7598fc5331c
--- /dev/null
+++ b/gdb/config/m68k/linux.mt
@@ -0,0 +1,3 @@
+# Target: Motorola m68k with a.out and ELF
+TDEPFILES= m68k-tdep.o solib.o solib-svr4.o solib-legacy.o
+TM_FILE= tm-linux.h
diff --git a/gdb/config/m68k/m68klynx.mh b/gdb/config/m68k/m68klynx.mh
new file mode 100644
index 00000000000..3838012a801
--- /dev/null
+++ b/gdb/config/m68k/m68klynx.mh
@@ -0,0 +1,6 @@
+# Host: Motorola 680x0 running LynxOS
+
+XM_CLIBS= -lbsd
+
+NAT_FILE= nm-m68klynx.h
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o lynx-nat.o
diff --git a/gdb/config/m68k/m68klynx.mt b/gdb/config/m68k/m68klynx.mt
new file mode 100644
index 00000000000..4aeac96d881
--- /dev/null
+++ b/gdb/config/m68k/m68klynx.mt
@@ -0,0 +1,4 @@
+# Target: Motorola 680x0 running LynxOS
+TDEPFILES= coff-solib.o m68k-tdep.o
+# m68kly-tdep.o
+TM_FILE= tm-m68klynx.h
diff --git a/gdb/config/m68k/m68kv4.mh b/gdb/config/m68k/m68kv4.mh
new file mode 100644
index 00000000000..7deb1309c08
--- /dev/null
+++ b/gdb/config/m68k/m68kv4.mh
@@ -0,0 +1,7 @@
+# Host: Motorola 680x0 running SVR4 (Commodore Amiga amix or Atari TT ASV)
+
+XM_FILE= xm-m68kv4.h
+
+NAT_FILE= nm-sysv4.h
+NATDEPFILES= corelow.o core-regset.o solib.o solib-svr4.o solib-legacy.o \
+ fork-child.o procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o
diff --git a/gdb/config/m68k/m68kv4.mt b/gdb/config/m68k/m68kv4.mt
new file mode 100644
index 00000000000..fcabb172d50
--- /dev/null
+++ b/gdb/config/m68k/m68kv4.mt
@@ -0,0 +1,3 @@
+# Target: Motorola 680x0 running SVR4 (Commodore Amiga amix or Atari TT ASV)
+TDEPFILES= m68k-tdep.o
+TM_FILE= tm-m68kv4.h
diff --git a/gdb/config/m68k/monitor.mt b/gdb/config/m68k/monitor.mt
new file mode 100644
index 00000000000..46b1c55ad63
--- /dev/null
+++ b/gdb/config/m68k/monitor.mt
@@ -0,0 +1,3 @@
+# Target: Motorola m68k embedded (EST emulator, rom68k and bug monitors)
+TDEPFILES= m68k-tdep.o monitor.o remote-est.o cpu32bug-rom.o rom68k-rom.o abug-rom.o dbug-rom.o dsrec.o
+TM_FILE= tm-monitor.h
diff --git a/gdb/config/m68k/nbsdaout.mh b/gdb/config/m68k/nbsdaout.mh
new file mode 100644
index 00000000000..7ce279b332e
--- /dev/null
+++ b/gdb/config/m68k/nbsdaout.mh
@@ -0,0 +1,5 @@
+# Host: Motorola m68k running NetBSD
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o m68knbsd-nat.o \
+ solib.o solib-sunos.o
+XM_FILE= xm-nbsd.h
+NAT_FILE= nm-nbsdaout.h
diff --git a/gdb/config/m68k/nbsdaout.mt b/gdb/config/m68k/nbsdaout.mt
new file mode 100644
index 00000000000..b6ac5a000e1
--- /dev/null
+++ b/gdb/config/m68k/nbsdaout.mt
@@ -0,0 +1,3 @@
+# Target: Motorola m68k running NetBSD
+TDEPFILES= m68k-tdep.o m68knbsd-tdep.o
+TM_FILE= tm-nbsd.h
diff --git a/gdb/config/m68k/nm-apollo68b.h b/gdb/config/m68k/nm-apollo68b.h
new file mode 100644
index 00000000000..eca8bfa7ce6
--- /dev/null
+++ b/gdb/config/m68k/nm-apollo68b.h
@@ -0,0 +1,42 @@
+/* Macro defintions for an Apollo m68k in BSD mode
+ Copyright 1992, 1993, 1995, 1998 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. */
+
+#define FETCH_INFERIOR_REGISTERS
+
+/* Tell gdb that we can attach and detach other processes */
+#define ATTACH_DETACH
+
+#define U_REGS_OFFSET 6
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+
+#define KERNEL_U_ADDR 0
+
+#undef FLOAT_INFO /* No float info yet */
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = (6 + 4 * (regno))
+
+/* Apollos don't really have a USER area,so trying to read it from the
+ * process address space will fail. It does support a read from a faked
+ * USER area using the "PEEKUSER" ptrace call.
+ */
+#define PT_READ_U 3
diff --git a/gdb/config/m68k/nm-apollo68v.h b/gdb/config/m68k/nm-apollo68v.h
new file mode 100644
index 00000000000..496e105d303
--- /dev/null
+++ b/gdb/config/m68k/nm-apollo68v.h
@@ -0,0 +1,21 @@
+/* Macro defintions for an Apollo.
+ Copyright (C) 1986, 1987, 1989, 1992 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. */
+
+#define FETCH_INFERIOR_REGISTERS
diff --git a/gdb/config/m68k/nm-delta68.h b/gdb/config/m68k/nm-delta68.h
new file mode 100644
index 00000000000..78871a06a97
--- /dev/null
+++ b/gdb/config/m68k/nm-delta68.h
@@ -0,0 +1,22 @@
+/* Macro definitions for a Motorola Delta Series sysV68 R3V7.1.
+ Copyright 1993, 1998 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. */
+
+
+#define KERNEL_U_SIZE kernel_u_size()
diff --git a/gdb/config/m68k/nm-dpx2.h b/gdb/config/m68k/nm-dpx2.h
new file mode 100644
index 00000000000..4c88a6c8a1e
--- /dev/null
+++ b/gdb/config/m68k/nm-dpx2.h
@@ -0,0 +1,29 @@
+/* Native support for a Bull DPX2.
+ Copyright 1986, 1987, 1989, 1993, 2000 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. */
+
+/* KERNEL_U_ADDR is determined upon startup in dpx2-xdep.c. */
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = dpx2_register_u_addr ((blockend),(regno));
+
+extern int dpx2_register_u_addr (int, int);
+
+/* Kernel is a bit tenacious about sharing text segments, disallowing bpts. */
+#define ONE_PROCESS_WRITETEXT
diff --git a/gdb/config/m68k/nm-hp300bsd.h b/gdb/config/m68k/nm-hp300bsd.h
new file mode 100644
index 00000000000..e0f7a1124bf
--- /dev/null
+++ b/gdb/config/m68k/nm-hp300bsd.h
@@ -0,0 +1,90 @@
+/* Parameters for Hewlett-Packard 9000/300 native support under bsd.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993
+ 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. */
+
+/* Detect whether this is 4.3 or 4.4. */
+
+#include <errno.h>
+#include <sys/param.h>
+#ifdef BSD4_4
+
+/* BSD 4.4 alpha or better */
+
+/* We can attach to processes using ptrace. */
+
+#define ATTACH_DETACH
+#define PTRACE_ATTACH 10
+#define PTRACE_DETACH 11
+
+/* The third argument of ptrace is declared as this type. */
+
+#define PTRACE_ARG3_TYPE caddr_t
+
+/* U_REGS_OFFSET is the offset of the registers within the u area for
+ ptrace purposes. */
+#define U_REGS_OFFSET \
+ ptrace (PT_READ_U, PIDGET (inferior_ptid), \
+ (PTRACE_ARG3_TYPE) \
+ (offsetof (struct user, u_kproc.kp_proc.p_md.md_regs)), 0) \
+ - USRSTACK
+
+/* No user structure in 4.4, registers are relative to kernel stack
+ which is fixed. */
+#define KERNEL_U_ADDR 0xFFF00000
+
+/* FIXME: Is ONE_PROCESS_WRITETEXT still true now that the kernel has
+ copy-on-write? It not, move it to the 4.3-specific section below
+ (now it is in xm-hp300bsd.h). */
+
+#else
+
+/* This is BSD 4.3 or something like it. */
+
+/* Get kernel u area address at run-time using BSD style nlist (). */
+#define KERNEL_U_ADDR_BSD
+
+#endif
+
+/* This was once broken for 4.4, but probably because we had the wrong
+ KERNEL_U_ADDR. */
+
+/* This is a piece of magic that is given a register number REGNO
+ and as BLOCKEND the address in the system of the end of the user structure
+ and stores in ADDR the address in the kernel or core dump
+ of that register. */
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+{ \
+ if (regno < PS_REGNUM) \
+ addr = (int) &((struct frame *)(blockend))->f_regs[regno]; \
+ else if (regno == PS_REGNUM) \
+ addr = (int) &((struct frame *)(blockend))->f_stackadj; \
+ else if (regno == PC_REGNUM) \
+ addr = (int) &((struct frame *)(blockend))->f_pc; \
+ else if (regno < FPC_REGNUM) \
+ addr = (int) \
+ &((struct user *)0)->u_pcb.pcb_fpregs.fpf_regs[((regno)-FP0_REGNUM)*3];\
+ else if (regno == FPC_REGNUM) \
+ addr = (int) &((struct user *)0)->u_pcb.pcb_fpregs.fpf_fpcr; \
+ else if (regno == FPS_REGNUM) \
+ addr = (int) &((struct user *)0)->u_pcb.pcb_fpregs.fpf_fpsr; \
+ else \
+ addr = (int) &((struct user *)0)->u_pcb.pcb_fpregs.fpf_fpiar; \
+}
diff --git a/gdb/config/m68k/nm-hp300hpux.h b/gdb/config/m68k/nm-hp300hpux.h
new file mode 100644
index 00000000000..b9547581ae8
--- /dev/null
+++ b/gdb/config/m68k/nm-hp300hpux.h
@@ -0,0 +1,55 @@
+/* Parameters for native support on HP 9000 model 320, for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1992, 1993, 1996
+ 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. */
+
+/* Do implement the attach and detach commands. */
+
+#define ATTACH_DETACH
+
+/* fetch_inferior_registers is in nat-hp300hpux.c. */
+#define FETCH_INFERIOR_REGISTERS
+
+/* Get registers from a core file. The floating point stuff is just
+ guesses. */
+#define NEED_SYS_CORE_H
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+{ \
+ if (regno < PS_REGNUM) \
+ addr = (int) (&((struct proc_regs *)(blockend))->d0 + regno); \
+ else if (regno == PS_REGNUM) \
+ addr = (int) ((char *) (&((struct proc_regs *)(blockend))->ps) - 2); \
+ else if (regno == PC_REGNUM) \
+ addr = (int) &((struct proc_regs *)(blockend))->pc; \
+ else if (regno < FPC_REGNUM) \
+ addr = (int) (((struct proc_regs *)(blockend))->mc68881 \
+ + ((regno) - FP0_REGNUM) / 2); \
+ else \
+ addr = (int) (((struct proc_regs *)(blockend))->p_float \
+ + (regno) - FPC_REGNUM); \
+}
+
+/* HPUX 8.0, in its infinite wisdom, has chosen to prototype ptrace
+ with five arguments, so programs written for normal ptrace lose.
+
+ Idiots.
+
+ (They should have just made it varadic). */
+
+#define FIVE_ARG_PTRACE
diff --git a/gdb/config/m68k/nm-linux.h b/gdb/config/m68k/nm-linux.h
new file mode 100644
index 00000000000..5c37af9ca12
--- /dev/null
+++ b/gdb/config/m68k/nm-linux.h
@@ -0,0 +1,41 @@
+/* Native support for linux, for GDB, the GNU debugger.
+ Copyright 1996, 1998, 2000 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. */
+
+#ifndef NM_LINUX_H
+#define NM_LINUX_H
+
+#include "nm-linux.h"
+
+/* Return sizeof user struct to callers in less machine dependent routines */
+
+#define KERNEL_U_SIZE kernel_u_size()
+extern int kernel_u_size (void);
+
+#define U_REGS_OFFSET 0
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = m68k_linux_register_u_addr ((blockend),(regno));
+
+extern int m68k_linux_register_u_addr (int, int);
+
+/* Override copies of {fetch,store}_inferior_registers in `infptrace.c'. */
+#define FETCH_INFERIOR_REGISTERS
+
+#endif /* #ifndef NM_LINUX_H */
diff --git a/gdb/config/m68k/nm-m68klynx.h b/gdb/config/m68k/nm-m68klynx.h
new file mode 100644
index 00000000000..49114fc4df9
--- /dev/null
+++ b/gdb/config/m68k/nm-m68klynx.h
@@ -0,0 +1,26 @@
+/* Native-dependent definitions for Motorola 680x0 running LynxOS.
+ Copyright 1993 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. */
+
+#ifndef NM_M68KLYNX_H
+#define NM_M68KLYNX_H
+
+#include "nm-lynx.h"
+
+#endif /* NM_M68KLYNX_H */
diff --git a/gdb/config/m68k/nm-nbsd.h b/gdb/config/m68k/nm-nbsd.h
new file mode 100644
index 00000000000..72c98895a78
--- /dev/null
+++ b/gdb/config/m68k/nm-nbsd.h
@@ -0,0 +1,27 @@
+/* Native-dependent definitions for Motorola m68k running NetBSD, for GDB.
+ Copyright 1996 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. */
+
+#ifndef NM_NBSD_H
+#define NM_NBSD_H
+
+/* Get generic NetBSD native definitions. */
+#include "config/nm-nbsd.h"
+
+#endif /* NM_NBSD_H */
diff --git a/gdb/config/m68k/nm-nbsdaout.h b/gdb/config/m68k/nm-nbsdaout.h
new file mode 100644
index 00000000000..cb755f0bed2
--- /dev/null
+++ b/gdb/config/m68k/nm-nbsdaout.h
@@ -0,0 +1,29 @@
+/* Native-dependent definitions for Motorola m68k running NetBSD, for GDB.
+ Copyright 1996, 2002 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. */
+
+#ifndef NM_NBSDAOUT_H
+#define NM_NBSDAOUT_H
+
+#include "m68k/nm-nbsd.h"
+
+/* Get generic NetBSD a.out native definitions. */
+#include "config/nm-nbsdaout.h"
+
+#endif /* NM_NBSDAOUT_H */
diff --git a/gdb/config/m68k/nm-sun2.h b/gdb/config/m68k/nm-sun2.h
new file mode 100644
index 00000000000..5d55caf2165
--- /dev/null
+++ b/gdb/config/m68k/nm-sun2.h
@@ -0,0 +1,34 @@
+/* Parameters for execution on a Sun2, for GDB, the GNU debugger.
+ Copyright (C) 1986, 1987, 1989, 1992 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. */
+
+/* Do implement the attach and detach commands. */
+
+#define ATTACH_DETACH
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
+#define FETCH_INFERIOR_REGISTERS
+
+/* This is a piece of magic that is given a register number REGNO
+ and as BLOCKEND the address in the system of the end of the user structure
+ and stores in ADDR the address in the kernel or core dump
+ of that register. */
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+{ addr = blockend + regno * 4; }
diff --git a/gdb/config/m68k/nm-sun3.h b/gdb/config/m68k/nm-sun3.h
new file mode 100644
index 00000000000..ba40db74b0b
--- /dev/null
+++ b/gdb/config/m68k/nm-sun3.h
@@ -0,0 +1,34 @@
+/* Native-only definitions for Sun-3 for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1996
+ 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 "regcache.h"
+
+/* Do implement the attach and detach commands. */
+
+#define ATTACH_DETACH
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
+
+#define FETCH_INFERIOR_REGISTERS
+
+/* We have to grab the regs since we store all regs at once. */
+
+#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
diff --git a/gdb/config/m68k/nm-sysv4.h b/gdb/config/m68k/nm-sysv4.h
new file mode 100644
index 00000000000..a7d0bdd3bda
--- /dev/null
+++ b/gdb/config/m68k/nm-sysv4.h
@@ -0,0 +1,23 @@
+/* Native-dependent definitions for Motorola 680x0 running SVR4.
+ Copyright 1994 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 the generic SVR4 definitions. */
+
+#include "nm-sysv4.h"
diff --git a/gdb/config/m68k/os68k.mt b/gdb/config/m68k/os68k.mt
new file mode 100644
index 00000000000..391dd894366
--- /dev/null
+++ b/gdb/config/m68k/os68k.mt
@@ -0,0 +1,3 @@
+# Target: VxWorks running on a 68000
+TDEPFILES= m68k-tdep.o
+TM_FILE= tm-os68k.h
diff --git a/gdb/config/m68k/st2000.mt b/gdb/config/m68k/st2000.mt
new file mode 100644
index 00000000000..06dfe5cbc0d
--- /dev/null
+++ b/gdb/config/m68k/st2000.mt
@@ -0,0 +1,3 @@
+# Target: Tandem ST-2000 phone switch
+TDEPFILES= m68k-tdep.o remote-st.o
+TM_FILE= tm-st2000.h
diff --git a/gdb/config/m68k/sun2os3.mh b/gdb/config/m68k/sun2os3.mh
new file mode 100644
index 00000000000..3d868daa4d6
--- /dev/null
+++ b/gdb/config/m68k/sun2os3.mh
@@ -0,0 +1,4 @@
+# Host: Sun 2, running SunOS 3
+XM_FILE= xm-sun2.h
+NAT_FILE= nm-sun2.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o sun3-nat.o
diff --git a/gdb/config/m68k/sun2os3.mt b/gdb/config/m68k/sun2os3.mt
new file mode 100644
index 00000000000..12b7c7fec8a
--- /dev/null
+++ b/gdb/config/m68k/sun2os3.mt
@@ -0,0 +1,7 @@
+# Target: Sun 2, running SunOS 3
+# The system-supplied assembler re-orders the symbols so that gdb
+# can't find "gcc_compiled.".
+#msg If you compile your program with GCC, use the GNU assembler.
+#msg
+TDEPFILES= m68k-tdep.o
+TM_FILE= tm-sun2.h
diff --git a/gdb/config/m68k/sun2os4.mh b/gdb/config/m68k/sun2os4.mh
new file mode 100644
index 00000000000..29fe1e89c82
--- /dev/null
+++ b/gdb/config/m68k/sun2os4.mh
@@ -0,0 +1,4 @@
+# Host: Sun 2, running SunOS 4
+XM_FILE= xm-sun2.h
+NAT_FILE= nm-sun2.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o sun3-nat.o
diff --git a/gdb/config/m68k/sun2os4.mt b/gdb/config/m68k/sun2os4.mt
new file mode 100644
index 00000000000..4d8e6decebe
--- /dev/null
+++ b/gdb/config/m68k/sun2os4.mt
@@ -0,0 +1,3 @@
+# Target: Sun 2, running SunOS 4
+TDEPFILES= solib.o solib-sunos.o m68k-tdep.o
+TM_FILE= tm-sun2os4.h
diff --git a/gdb/config/m68k/sun3os3.mh b/gdb/config/m68k/sun3os3.mh
new file mode 100644
index 00000000000..bf036229216
--- /dev/null
+++ b/gdb/config/m68k/sun3os3.mh
@@ -0,0 +1,4 @@
+# Host: Sun 3, running SunOS 3
+XM_FILE= xm-sun3.h
+NAT_FILE= nm-sun3.h
+NATDEPFILES= fork-child.o inftarg.o infptrace.o corelow.o sun3-nat.o
diff --git a/gdb/config/m68k/sun3os3.mt b/gdb/config/m68k/sun3os3.mt
new file mode 100644
index 00000000000..8f9dac85e0e
--- /dev/null
+++ b/gdb/config/m68k/sun3os3.mt
@@ -0,0 +1,8 @@
+# Target: Sun 3, running SunOS 3
+# The system-supplied assembler re-orders the symbols so that gdb
+# can't find "gcc_compiled.".
+#msg If you compile your program with GCC, use the GNU assembler.
+#msg
+
+TDEPFILES= m68k-tdep.o
+TM_FILE= tm-sun3.h
diff --git a/gdb/config/m68k/sun3os4.mh b/gdb/config/m68k/sun3os4.mh
new file mode 100644
index 00000000000..18b1f081258
--- /dev/null
+++ b/gdb/config/m68k/sun3os4.mh
@@ -0,0 +1,4 @@
+# Host: Sun 3, running SunOS 4
+XM_FILE= xm-sun3os4.h
+NAT_FILE= nm-sun3.h
+NATDEPFILES= fork-child.o inftarg.o infptrace.o corelow.o sun3-nat.o
diff --git a/gdb/config/m68k/sun3os4.mt b/gdb/config/m68k/sun3os4.mt
new file mode 100644
index 00000000000..64f1a300dbc
--- /dev/null
+++ b/gdb/config/m68k/sun3os4.mt
@@ -0,0 +1,3 @@
+# Target: Sun 3, running SunOS 4, as a target system
+TDEPFILES= solib.o solib-sunos.o m68k-tdep.o
+TM_FILE= tm-sun3os4.h
diff --git a/gdb/config/m68k/tm-3b1.h b/gdb/config/m68k/tm-3b1.h
new file mode 100644
index 00000000000..90888c66655
--- /dev/null
+++ b/gdb/config/m68k/tm-3b1.h
@@ -0,0 +1,33 @@
+/* Parameters for targeting GDB to a 3b1.
+ Copyright 1986, 1987, 1989, 1991, 1993 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. */
+
+/* The child target can't deal with floating registers. */
+#define CANNOT_STORE_REGISTER(regno) ((regno) >= FP0_REGNUM)
+
+/* Define BPT_VECTOR if it is different than the default.
+ This is the vector number used by traps to indicate a breakpoint. */
+
+#define BPT_VECTOR 0x1
+
+/* Address of end of stack space. */
+
+#define STACK_END_ADDR 0x300000
+
+#include "m68k/tm-m68k.h"
diff --git a/gdb/config/m68k/tm-apollo68b.h b/gdb/config/m68k/tm-apollo68b.h
new file mode 100644
index 00000000000..d43eec9d6cf
--- /dev/null
+++ b/gdb/config/m68k/tm-apollo68b.h
@@ -0,0 +1,61 @@
+/* Parameters for execution on Apollo 68k running BSD.
+ Copyright 1986, 1987, 1989, 1991, 1993, 1994, 1998
+ 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 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. */
+
+/* Apollos use vector 0xb for the breakpoint vector */
+
+#define BPT_VECTOR 0xb
+
+#include "m68k/tm-m68k.h"
+
+#define FRAME_CHAIN_VALID(chain, thisframe) nonnull_frame_chain_valid (chain, thisframe)
+
+/* These are the jmp_buf registers I could guess. There are 13 registers
+ * in the buffer. There are 8 data registers, 6 general address registers,
+ * the Frame Pointer, the Stack Pointer, the PC and the SR in the chip. I would
+ * guess that 12 is the SR, but we don't need that anyway. 0 and 1 have
+ * me stumped. 4 appears to be a5 for some unknown reason. If you care
+ * about this, disassemble setjmp to find out. But don't do it with gdb :)
+ */
+
+#undef JB_SP
+#undef JB_FP
+#undef JB_PC
+#undef JB_D0
+#undef JB_D1
+#undef JB_D2
+#undef JB_D3
+#undef JB_D4
+#undef JB_D5
+
+#define JB_SP 2
+#define JB_FP 3
+#define JB_PC 5
+#define JB_D0 6
+#define JB_D1 7
+#define JB_D2 8
+#define JB_D3 9
+#define JB_D4 10
+#define JB_D5 11
+
+/* How to decide if we're in a shared library function. (Probably a wrong
+ definintion inherited from the VxWorks config file). */
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) (name && strcmp(name, "<end_of_program>") == 0)
diff --git a/gdb/config/m68k/tm-cisco.h b/gdb/config/m68k/tm-cisco.h
new file mode 100644
index 00000000000..24db025bccf
--- /dev/null
+++ b/gdb/config/m68k/tm-cisco.h
@@ -0,0 +1,55 @@
+/* Parameters for CISCO m68k.
+ Copyright 1994, 1996, 2000 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. */
+
+#define GDBINIT_FILENAME ".cisco-gdbinit" /* Init file */
+
+#define DEFAULT_PROMPT "(cisco-68k-gdb) " /* Default prompt */
+
+#include "m68k/tm-m68k.h"
+
+/* Offsets (in target ints) into jmp_buf. Defined in /csc/sys/sun/asm.S. */
+
+#define JB_ELEMENT_SIZE 4
+
+#define JB_PC 0
+#define JB_D2 1
+#define JB_D3 2
+#define JB_D4 3
+#define JB_D5 4
+#define JB_D6 5
+#define JB_D7 6
+#define JB_A2 7
+#define JB_A3 8
+#define JB_A4 9
+#define JB_A5 10
+#define JB_A6 11
+#define JB_SP 12
+
+/* Figure out where the longjmp will land. Slurp the args out of the stack.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+#define GET_LONGJMP_TARGET(ADDR) m68k_get_longjmp_target(ADDR)
+
+/* BFD handles finding the registers in the core file, so they are at
+ the start of the BFD .reg section. */
+#define REGISTER_U_ADDR(addr,blockend,regno) (addr = REGISTER_BYTE (regno))
+#define KERNEL_U_ADDR 0
diff --git a/gdb/config/m68k/tm-delta68.h b/gdb/config/m68k/tm-delta68.h
new file mode 100644
index 00000000000..a38baea2020
--- /dev/null
+++ b/gdb/config/m68k/tm-delta68.h
@@ -0,0 +1,107 @@
+/* Target definitions for delta68.
+ Copyright 1993, 1994, 1998, 1999, 2000 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 "regcache.h"
+
+/* Define BPT_VECTOR if it is different than the default.
+ This is the vector number used by traps to indicate a breakpoint. */
+
+#define BPT_VECTOR 0x1
+
+#define GCC_COMPILED_FLAG_SYMBOL "gcc_compiled%"
+#define GCC2_COMPILED_FLAG_SYMBOL "gcc2_compiled%"
+
+/* Amount PC must be decremented by after a breakpoint.
+ On the Delta, the kernel decrements it for us. */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Not sure what happens if we try to store this register, but
+ phdm@info.ucl.ac.be says we need this define. */
+
+#define CANNOT_STORE_REGISTER(regno) (regno == FPI_REGNUM)
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. */
+
+/* When it returns a float/double value, use fp0 in sysV68. */
+/* When it returns a pointer value, use a0 in sysV68. */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) \
+ REGISTER_CONVERT_TO_VIRTUAL (FP0_REGNUM, TYPE, \
+ &REGBUF[REGISTER_BYTE (FP0_REGNUM)], \
+ VALBUF); \
+ else \
+ memcpy ((VALBUF), \
+ (char *) ((REGBUF) + \
+ (TYPE_CODE(TYPE) == TYPE_CODE_PTR ? 8 * 4 : \
+ (TYPE_LENGTH(TYPE) >= 4 ? 0 : 4 - TYPE_LENGTH(TYPE)))), \
+ TYPE_LENGTH(TYPE))
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format. */
+
+/* When it returns a float/double value, use fp0 in sysV68. */
+/* When it returns a pointer value, use a0 in sysV68. */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) \
+ { \
+ char raw_buf[REGISTER_RAW_SIZE (FP0_REGNUM)]; \
+ REGISTER_CONVERT_TO_RAW (TYPE, FP0_REGNUM, VALBUF, raw_buf); \
+ write_register_bytes (REGISTER_BYTE (FP0_REGNUM), \
+ raw_buf, REGISTER_RAW_SIZE (FP0_REGNUM)); \
+ } \
+ else \
+ write_register_bytes ((TYPE_CODE(TYPE) == TYPE_CODE_PTR ? 8 * 4 : 0), \
+ VALBUF, TYPE_LENGTH (TYPE))
+
+/* Return number of args passed to a frame.
+ Can return -1, meaning no way to tell. */
+
+extern int delta68_frame_num_args (struct frame_info *fi);
+#define FRAME_NUM_ARGS(fi) (delta68_frame_num_args ((fi)))
+
+/* On M68040 versions of sysV68 R3V7.1, ptrace(PT_WRITE_I) does not clear
+ the processor's instruction cache as it should. */
+#define CLEAR_INSN_CACHE() clear_insn_cache()
+
+#include "m68k/tm-m68k.h"
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+
+#undef EXTRACT_STRUCT_VALUE_ADDRESS
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF)\
+ (*(CORE_ADDR *)((char*)(REGBUF) + 8 * 4))
+
+extern int delta68_in_sigtramp (CORE_ADDR pc, char *name);
+#define IN_SIGTRAMP(pc,name) delta68_in_sigtramp (pc, name)
+
+extern CORE_ADDR delta68_frame_saved_pc (struct frame_info *fi);
+#undef FRAME_SAVED_PC
+#define FRAME_SAVED_PC(fi) delta68_frame_saved_pc (fi)
+
+extern CORE_ADDR delta68_frame_args_address (struct frame_info *fi);
+#undef FRAME_ARGS_ADDRESS
+#define FRAME_ARGS_ADDRESS(fi) delta68_frame_args_address (fi)
diff --git a/gdb/config/m68k/tm-dpx2.h b/gdb/config/m68k/tm-dpx2.h
new file mode 100644
index 00000000000..96b1c324d5a
--- /dev/null
+++ b/gdb/config/m68k/tm-dpx2.h
@@ -0,0 +1,35 @@
+/* Parameters for targeting to a Bull DPX2.
+ Copyright 1986, 1987, 1989, 1991, 1993, 1994
+ 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. */
+
+/* Define BPT_VECTOR if it is different than the default.
+ This is the vector number used by traps to indicate a breakpoint. */
+
+#define BPT_VECTOR 0xe
+
+/* Need to get function ends by adding this to epilogue address from .bf
+ record, not using x_fsize field. */
+#define FUNCTION_EPILOGUE_SIZE 4
+
+/* The child target can't deal with writing floating registers. */
+#define CANNOT_STORE_REGISTER(regno) ((regno) >= FP0_REGNUM)
+
+#include <sys/types.h>
+#include "m68k/tm-m68k.h"
diff --git a/gdb/config/m68k/tm-es1800.h b/gdb/config/m68k/tm-es1800.h
new file mode 100644
index 00000000000..46e4a641f08
--- /dev/null
+++ b/gdb/config/m68k/tm-es1800.h
@@ -0,0 +1,60 @@
+/* Parameters for execution on ES-1800 emulator for 68000.
+ The code was originally written by Johan Holmberg TT/SJ Ericsson Telecom
+ AB and later modified by Johan Henriksson TT/SJ. It was adapted to GDB 4.0
+ by Jan Norden TX/DK.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1996, 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ GDB 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 1, or (at your option)
+ any later version.
+
+ GDB 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. */
+
+#define GDBINIT_FILENAME ".esgdbinit"
+
+#define DEFAULT_PROMPT "(esgdb) "
+
+#include "m68k/tm-m68k.h"
+
+/* Longjmp stuff borrowed from sun3 configuration. Don't know if correct.
+ FIXME. */
+/* Offsets (in target ints) into jmp_buf. Not defined by Sun, but at least
+ documented in a comment in <machine/setjmp.h>! */
+
+#define JB_ELEMENT_SIZE 4
+
+#define JB_ONSSTACK 0
+#define JB_SIGMASK 1
+#define JB_SP 2
+#define JB_PC 3
+#define JB_PSL 4
+#define JB_D2 5
+#define JB_D3 6
+#define JB_D4 7
+#define JB_D5 8
+#define JB_D6 9
+#define JB_D7 10
+#define JB_A2 11
+#define JB_A3 12
+#define JB_A4 13
+#define JB_A5 14
+#define JB_A6 15
+
+/* Figure out where the longjmp will land. Slurp the args out of the stack.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+#define GET_LONGJMP_TARGET(ADDR) m68k_get_longjmp_target(ADDR)
diff --git a/gdb/config/m68k/tm-hp300bsd.h b/gdb/config/m68k/tm-hp300bsd.h
new file mode 100644
index 00000000000..0a033873f81
--- /dev/null
+++ b/gdb/config/m68k/tm-hp300bsd.h
@@ -0,0 +1,64 @@
+/* Parameters for target machine Hewlett-Packard 9000/300, running bsd.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1996
+ 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. */
+
+/* Configuration file for HP9000/300 series machine running BSD,
+ including Utah, Mt. Xinu or Berkeley variants. This is NOT for HP-UX.
+ Problems to hpbsd-bugs@cs.utah.edu. */
+
+/* GCC is the only compiler used on this OS. So get this right even if
+ the code which detects gcc2_compiled. is still broken. */
+
+#define BELIEVE_PCC_PROMOTION 1
+
+/* Define BPT_VECTOR if it is different than the default.
+ This is the vector number used by traps to indicate a breakpoint.
+
+ For hp300bsd the normal breakpoint vector is 0x2 (for debugging via
+ ptrace); for remote kernel debugging the breakpoint vector is 0xf. */
+
+#define BPT_VECTOR 0x2
+#define REMOTE_BPT_VECTOR 0xf
+
+#define TARGET_NBPG 4096
+
+/* For 4.4 this would be 2, but it is OK for us to detect an area a
+ bit bigger than necessary. This way the same gdb binary can target
+ either 4.3 or 4.4. */
+
+#define TARGET_UPAGES 3
+
+/* On the HP300, sigtramp is in the u area. Gak! User struct is not
+ mapped to the same virtual address in user/kernel address space
+ (hence STACK_END_ADDR as opposed to KERNEL_U_ADDR). This tests
+ for the whole u area, since we don't necessarily have hp300bsd
+ include files around. */
+
+/* For 4.4, it is actually right 20 bytes *before* STACK_END_ADDR, so
+ include that in the area we test for. */
+
+#define SIGTRAMP_START(pc) (STACK_END_ADDR - 20)
+#define SIGTRAMP_END(pc) (STACK_END_ADDR + TARGET_UPAGES * TARGET_NBPG)
+
+/* Address of end of stack space. */
+
+#define STACK_END_ADDR 0xfff00000
+
+#include "m68k/tm-m68k.h"
diff --git a/gdb/config/m68k/tm-hp300hpux.h b/gdb/config/m68k/tm-hp300hpux.h
new file mode 100644
index 00000000000..860653208f2
--- /dev/null
+++ b/gdb/config/m68k/tm-hp300hpux.h
@@ -0,0 +1,33 @@
+/* Parameters for execution on an HP 9000 model 320, for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993
+ 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. */
+
+/* GCC is the only compiler used for stabs on this OS. So get this
+ right even if the code which detects gcc2_compiled. is still
+ broken. */
+
+#define BELIEVE_PCC_PROMOTION 1
+
+/* Define BPT_VECTOR if it is different than the default.
+ This is the vector number used by traps to indicate a breakpoint. */
+
+#define BPT_VECTOR 0x1
+
+#include "m68k/tm-m68k.h"
diff --git a/gdb/config/m68k/tm-linux.h b/gdb/config/m68k/tm-linux.h
new file mode 100644
index 00000000000..94b2c2c3504
--- /dev/null
+++ b/gdb/config/m68k/tm-linux.h
@@ -0,0 +1,107 @@
+/* Definitions to target GDB to GNU/Linux on m680x0.
+
+ Copyright 1996, 1998, 1999, 2000, 2002 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 "regcache.h"
+
+/* Number of traps that happen between exec'ing the shell to run an
+ inferior, and when we finally get to the inferior code. This is 2
+ on most implementations. */
+
+#define START_INFERIOR_TRAPS_EXPECTED 2
+
+/* The following definitions are appropriate when using the ELF
+ format, where floating point values are returned in fp0, pointer
+ values in a0 and other values in d0. */
+
+/* Extract from an array REGBUF containing the (raw) register state a
+ function return value of type TYPE, and copy that, in virtual
+ format, into VALBUF. */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+{ \
+ if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) \
+ { \
+ REGISTER_CONVERT_TO_VIRTUAL (FP0_REGNUM, TYPE, \
+ ((char *) (REGBUF) \
+ + REGISTER_BYTE (FP0_REGNUM)), \
+ VALBUF); \
+ } \
+ else if (TYPE_CODE (TYPE) == TYPE_CODE_PTR) \
+ memcpy (VALBUF, (char *) (REGBUF) + REGISTER_BYTE (A0_REGNUM), \
+ TYPE_LENGTH (TYPE)); \
+ else \
+ memcpy (VALBUF, \
+ ((char *) (REGBUF) \
+ + (TYPE_LENGTH (TYPE) >= 4 ? 0 : 4 - TYPE_LENGTH (TYPE))), \
+ TYPE_LENGTH (TYPE)); \
+}
+
+/* Write into appropriate registers a function return value of type
+ TYPE, given in virtual format. */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+{ \
+ if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) \
+ { \
+ char raw_buffer[REGISTER_RAW_SIZE (FP0_REGNUM)]; \
+ REGISTER_CONVERT_TO_RAW (TYPE, FP0_REGNUM, VALBUF, raw_buffer); \
+ write_register_bytes (REGISTER_BYTE (FP0_REGNUM), \
+ raw_buffer, TYPE_LENGTH (TYPE)); \
+ } \
+ else \
+ { \
+ if (TYPE_CODE (TYPE) == TYPE_CODE_PTR) \
+ write_register_bytes (REGISTER_BYTE (A0_REGNUM), VALBUF, \
+ TYPE_LENGTH (TYPE)); \
+ write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE)); \
+ } \
+}
+
+#include "tm-linux.h"
+#include "m68k/tm-m68k.h"
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+
+#undef EXTRACT_STRUCT_VALUE_ADDRESS
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+ (*(CORE_ADDR *)((char *) (REGBUF) + REGISTER_BYTE (A0_REGNUM)))
+
+/* Offsets (in target ints) into jmp_buf. */
+
+#define JB_ELEMENT_SIZE 4
+#define JB_PC 7
+
+/* Figure out where the longjmp will land. Slurp the args out of the stack.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+#define GET_LONGJMP_TARGET(ADDR) m68k_get_longjmp_target(ADDR)
+
+#undef FRAME_SAVED_PC
+#define FRAME_SAVED_PC(frame) m68k_linux_frame_saved_pc (frame)
+extern CORE_ADDR m68k_linux_frame_saved_pc (struct frame_info *);
+
+#define IN_SIGTRAMP(pc,name) m68k_linux_in_sigtramp (pc)
+extern int m68k_linux_in_sigtramp (CORE_ADDR pc);
diff --git a/gdb/config/m68k/tm-m68k.h b/gdb/config/m68k/tm-m68k.h
new file mode 100644
index 00000000000..5b23df0a0be
--- /dev/null
+++ b/gdb/config/m68k/tm-m68k.h
@@ -0,0 +1,368 @@
+/* Parameters for execution on a 68000 series machine.
+ Copyright 1986, 1987, 1989, 1990, 1992, 1993, 1994, 1995, 1996, 1998,
+ 1999, 2000 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 "regcache.h"
+
+/* Generic 68000 stuff, to be included by other tm-*.h files. */
+
+#define TARGET_LONG_DOUBLE_FORMAT &floatformat_m68881_ext
+
+#define TARGET_LONG_DOUBLE_BIT 96
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code. */
+
+#if !defined(SKIP_PROLOGUE)
+#define SKIP_PROLOGUE(ip) (m68k_skip_prologue (ip))
+#endif
+extern CORE_ADDR m68k_skip_prologue (CORE_ADDR ip);
+
+/* Immediately after a function call, return the saved pc.
+ Can't always go through the frames for this because on some machines
+ the new frame is not set up until the new function executes
+ some instructions. */
+
+struct frame_info;
+struct frame_saved_regs;
+
+extern CORE_ADDR m68k_saved_pc_after_call (struct frame_info *);
+extern void m68k_find_saved_regs (struct frame_info *,
+ struct frame_saved_regs *);
+
+#define SAVED_PC_AFTER_CALL(frame) \
+ m68k_saved_pc_after_call(frame)
+
+/* Stack grows downward. */
+
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+/* Stack must be kept short aligned when doing function calls. */
+
+#define STACK_ALIGN(ADDR) (((ADDR) + 1) & ~1)
+
+/* Sequence of bytes for breakpoint instruction.
+ This is a TRAP instruction. The last 4 bits (0xf below) is the
+ vector. Systems which don't use 0xf should define BPT_VECTOR
+ themselves before including this file. */
+
+#if !defined (BPT_VECTOR)
+#define BPT_VECTOR 0xf
+#endif
+
+#if !defined (BREAKPOINT)
+#define BREAKPOINT {0x4e, (0x40 | BPT_VECTOR)}
+#endif
+
+/* We default to vector 1 for the "remote" target, but allow targets
+ to override. */
+#if !defined (REMOTE_BPT_VECTOR)
+#define REMOTE_BPT_VECTOR 1
+#endif
+
+#if !defined (REMOTE_BREAKPOINT)
+#define REMOTE_BREAKPOINT {0x4e, (0x40 | REMOTE_BPT_VECTOR)}
+#endif
+
+/* If your kernel resets the pc after the trap happens you may need to
+ define this before including this file. */
+
+#if !defined (DECR_PC_AFTER_BREAK)
+#define DECR_PC_AFTER_BREAK 2
+#endif
+
+/* Say how long (ordinary) registers are. This is a piece of bogosity
+ used in push_word and a few other places; REGISTER_RAW_SIZE is the
+ real way to know how big a register is. */
+
+#define REGISTER_SIZE 4
+
+#define REGISTER_BYTES_FP (16*4 + 8 + 8*12 + 3*4)
+#define REGISTER_BYTES_NOFP (16*4 + 8)
+
+#ifndef NUM_REGS
+#define NUM_REGS 29
+#endif
+
+#define NUM_FREGS (NUM_REGS-24)
+
+#ifndef REGISTER_BYTES_OK
+#define REGISTER_BYTES_OK(b) \
+ ((b) == REGISTER_BYTES_FP \
+ || (b) == REGISTER_BYTES_NOFP)
+#endif
+
+#ifndef REGISTER_BYTES
+#define REGISTER_BYTES (16*4 + 8 + 8*12 + 3*4)
+#endif
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#define REGISTER_BYTE(N) \
+ ((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168 \
+ : (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \
+ : (N) * 4)
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. On the 68000, all regs are 4 bytes
+ except the floating point regs which are 12 bytes. */
+/* Note that the unsigned cast here forces the result of the
+ subtraction to very high positive values if N < FP0_REGNUM */
+
+#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4)
+
+/* Number of bytes of storage in the program's representation
+ for register N. On the 68000, all regs are 4 bytes
+ except the floating point regs which are 12-byte long doubles. */
+
+#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#define MAX_REGISTER_RAW_SIZE 12
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 12
+
+/* Return the GDB type object for the "standard" data type of data
+ in register N. This should be int for D0-D7, long double for FP0-FP7,
+ and void pointer for all others (A0-A7, PC, SR, FPCONTROL etc).
+ Note, for registers which contain addresses return pointer to void,
+ not pointer to char, because we don't want to attempt to print
+ the string after printing the address. */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+ ((unsigned) (N) >= FPC_REGNUM ? lookup_pointer_type (builtin_type_void) : \
+ (unsigned) (N) >= FP0_REGNUM ? builtin_type_long_double : \
+ (unsigned) (N) >= A0_REGNUM ? lookup_pointer_type (builtin_type_void) : \
+ builtin_type_int)
+
+/* Initializer for an array of names of registers.
+ Entries beyond the first NUM_REGS are ignored. */
+
+#define REGISTER_NAMES \
+ {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
+ "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \
+ "ps", "pc", \
+ "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \
+ "fpcontrol", "fpstatus", "fpiaddr", "fpcode", "fpflags" }
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define D0_REGNUM 0
+#define A0_REGNUM 8
+#define A1_REGNUM 9
+#define FP_REGNUM 14 /* Contains address of executing stack frame */
+#define SP_REGNUM 15 /* Contains address of top of stack */
+#define PS_REGNUM 16 /* Contains processor status */
+#define PC_REGNUM 17 /* Contains program counter */
+#define FP0_REGNUM 18 /* Floating point register 0 */
+#define FPC_REGNUM 26 /* 68881 control register */
+#define FPS_REGNUM 27 /* 68881 status register */
+#define FPI_REGNUM 28 /* 68881 iaddr register */
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+ { write_register (A1_REGNUM, (ADDR)); }
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. This is assuming that floating point values are returned
+ as doubles in d0/d1. */
+
+#if !defined (EXTRACT_RETURN_VALUE)
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ memcpy ((VALBUF), \
+ (char *)(REGBUF) + \
+ (TYPE_LENGTH(TYPE) >= 4 ? 0 : 4 - TYPE_LENGTH(TYPE)), \
+ TYPE_LENGTH(TYPE))
+#endif
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format. Assumes floats are passed
+ in d0/d1. */
+
+#if !defined (STORE_RETURN_VALUE)
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
+#endif
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(CORE_ADDR *)(REGBUF))
+
+/* Describe the pointer in each stack frame to the previous stack frame
+ (its caller). */
+
+/* FRAME_CHAIN takes a frame's nominal address and produces the frame's
+ chain-pointer.
+ In the case of the 68000, the frame's nominal address
+ is the address of a 4-byte word containing the calling frame's address. */
+
+/* If we are chaining from sigtramp, then manufacture a sigtramp frame
+ (which isn't really on the stack. I'm not sure this is right for anything
+ but BSD4.3 on an hp300. */
+#define FRAME_CHAIN(thisframe) \
+ (thisframe->signal_handler_caller \
+ ? thisframe->frame \
+ : (!inside_entry_file ((thisframe)->pc) \
+ ? read_memory_integer ((thisframe)->frame, 4) \
+ : 0))
+
+/* Define other aspects of the stack frame. */
+
+/* A macro that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. If it
+ does not, FRAMELESS is set to 1, else 0. */
+#define FRAMELESS_FUNCTION_INVOCATION(FI) \
+ (((FI)->signal_handler_caller) ? 0 : frameless_look_for_prologue(FI))
+
+/* This was determined by experimentation on hp300 BSD 4.3. Perhaps
+ it corresponds to some offset in /usr/include/sys/user.h or
+ something like that. Using some system include file would
+ have the advantage of probably being more robust in the face
+ of OS upgrades, but the disadvantage of being wrong for
+ cross-debugging. */
+
+#define SIG_PC_FP_OFFSET 530
+
+#define FRAME_SAVED_PC(FRAME) \
+ (((FRAME)->signal_handler_caller \
+ ? ((FRAME)->next \
+ ? read_memory_integer ((FRAME)->next->frame + SIG_PC_FP_OFFSET, 4) \
+ : read_memory_integer (read_register (SP_REGNUM) \
+ + SIG_PC_FP_OFFSET - 8, 4) \
+ ) \
+ : read_memory_integer ((FRAME)->frame + 4, 4)) \
+ )
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Set VAL to the number of args passed to frame described by FI.
+ Can set VAL to -1, meaning no way to tell. */
+
+/* We can't tell how many args there are
+ now that the C compiler delays popping them. */
+#if !defined (FRAME_NUM_ARGS)
+#define FRAME_NUM_ARGS(fi) (-1)
+#endif
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#define FRAME_ARGS_SKIP 8
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame. */
+
+#if !defined (FRAME_FIND_SAVED_REGS)
+#define FRAME_FIND_SAVED_REGS(fi,fsr) m68k_find_saved_regs ((fi), &(fsr))
+#endif /* no FIND_FRAME_SAVED_REGS. */
+
+
+/* Things needed for making the inferior call functions. */
+
+/* The CALL_DUMMY macro is the sequence of instructions, as disassembled
+ by gdb itself:
+
+ These instructions exist only so that m68k_find_saved_regs can parse
+ them as a "prologue"; they are never executed.
+
+ fmovemx fp0-fp7,sp@- 0xf227 0xe0ff
+ moveml d0-a5,sp@- 0x48e7 0xfffc
+ clrw sp@- 0x4267
+ movew ccr,sp@- 0x42e7
+
+ The arguments are pushed at this point by GDB; no code is needed in
+ the dummy for this. The CALL_DUMMY_START_OFFSET gives the position
+ of the following jsr instruction. That is where we start
+ executing.
+
+ jsr @#0x32323232 0x4eb9 0x3232 0x3232
+ addal #0x69696969,sp 0xdffc 0x6969 0x6969
+ trap #<your BPT_VECTOR number here> 0x4e4?
+ nop 0x4e71
+
+ Note this is CALL_DUMMY_LENGTH bytes (28 for the above example).
+
+ The dummy frame always saves the floating-point registers, whether they
+ actually exist on this target or not. */
+
+/* FIXME: Wrong to hardwire this as BPT_VECTOR when sometimes it
+ should be REMOTE_BPT_VECTOR. Best way to fix it would be to define
+ CALL_DUMMY_BREAKPOINT_OFFSET. */
+
+#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, (0x4e404e71 | (BPT_VECTOR << 16))}
+#define CALL_DUMMY_LENGTH 28 /* Size of CALL_DUMMY */
+#define CALL_DUMMY_START_OFFSET 12 /* Offset to jsr instruction */
+#define CALL_DUMMY_BREAKPOINT_OFFSET (CALL_DUMMY_START_OFFSET + 12)
+
+/* Insert the specified number of args and function address
+ into a call sequence of the above form stored at DUMMYNAME.
+ We use the BFD routines to store a big-endian value of known size. */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \
+{ bfd_putb32 (fun, (unsigned char *) dummyname + CALL_DUMMY_START_OFFSET + 2); \
+ bfd_putb32 (nargs*4, (unsigned char *) dummyname + CALL_DUMMY_START_OFFSET + 8); }
+
+/* Push an empty stack frame, to record the current PC, etc. */
+
+#define PUSH_DUMMY_FRAME { m68k_push_dummy_frame (); }
+
+extern void m68k_push_dummy_frame (void);
+
+extern void m68k_pop_frame (void);
+
+/* Discard from the stack the innermost frame, restoring all registers. */
+
+#define POP_FRAME { m68k_pop_frame (); }
+
+/* Offset from SP to first arg on stack at first instruction of a function */
+
+#define SP_ARG0 (1 * 4)
+
+#define TARGET_M68K
+
+/* Figure out where the longjmp will land. Slurp the args out of the stack.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+extern int m68k_get_longjmp_target (CORE_ADDR *);
diff --git a/gdb/config/m68k/tm-m68klynx.h b/gdb/config/m68k/tm-m68klynx.h
new file mode 100644
index 00000000000..cfc462f54a4
--- /dev/null
+++ b/gdb/config/m68k/tm-m68klynx.h
@@ -0,0 +1,39 @@
+/* Macro definitions for Motorola 680x0 running under LynxOS.
+ Copyright 1993 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. */
+
+#ifndef TM_M68KLYNX_H
+#define TM_M68KLYNX_H
+
+#include "tm-lynx.h"
+
+/* If PC-2 contains this instruction, then we know what we are in a system
+ call stub, and the return PC is is at SP+4, instead of SP. */
+
+#define SYSCALL_TRAP 0x4e4a /* trap #10 */
+#define SYSCALL_TRAP_OFFSET 2 /* PC is after trap instruction */
+
+/* Use the generic 68k definitions. */
+
+#include "m68k/tm-m68k.h"
+
+/* Disable dumbshit alternate breakpoint mechanism needed by 68k stub. */
+#undef REMOTE_BREAKPOINT
+
+#endif /* TM_M68KLYNX_H */
diff --git a/gdb/config/m68k/tm-m68kv4.h b/gdb/config/m68k/tm-m68kv4.h
new file mode 100644
index 00000000000..18bf5a2187a
--- /dev/null
+++ b/gdb/config/m68k/tm-m68kv4.h
@@ -0,0 +1,71 @@
+/* Target definitions for GDB on a Motorola 680x0 running SVR4.
+ (Commodore Amiga with amix or Atari TT with ASV)
+ Copyright 1991, 1994, 1995, 1996, 1998, 1999, 2000
+ Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus Support (fnf@cygint)
+
+ 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. */
+
+/* Define BPT_VECTOR if it is different than the default.
+ This is the vector number used by traps to indicate a breakpoint. */
+
+#define BPT_VECTOR 0x1
+
+/* How much to decrement the PC after a trap. Depends on kernel. */
+
+#define DECR_PC_AFTER_BREAK 0 /* No decrement required */
+
+/* Use the alternate method of determining valid frame chains. */
+
+#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi)
+
+#include "tm-sysv4.h"
+#include "m68k/tm-m68k.h"
+
+/* Offsets (in target ints) into jmp_buf. Not defined in any system header
+ file, so we have to step through setjmp/longjmp with a debugger and figure
+ them out. As a double check, note that <setjmp> defines _JBLEN as 13,
+ which matches the number of elements we see saved by setjmp(). */
+
+#define JB_ELEMENT_SIZE sizeof(int) /* jmp_buf[_JBLEN] is array of ints */
+
+#define JB_D2 0
+#define JB_D3 1
+#define JB_D4 2
+#define JB_D5 3
+#define JB_D6 4
+#define JB_D7 5
+#define JB_A1 6
+#define JB_A2 7
+#define JB_A3 8
+#define JB_A4 9
+#define JB_A5 10
+#define JB_A6 11
+#define JB_A7 12
+
+#define JB_PC JB_A1 /* Setjmp()'s return PC saved in A1 */
+
+/* Figure out where the longjmp will land. Slurp the args out of the stack.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+#define GET_LONGJMP_TARGET(ADDR) m68k_get_longjmp_target(ADDR)
+
+/* Convert a DWARF register number to a gdb REGNUM. */
+#define DWARF_REG_TO_REGNUM(num) ((num) < 16 ? (num) : (num)+FP0_REGNUM-16)
diff --git a/gdb/config/m68k/tm-mac.h b/gdb/config/m68k/tm-mac.h
new file mode 100644
index 00000000000..270f353297d
--- /dev/null
+++ b/gdb/config/m68k/tm-mac.h
@@ -0,0 +1,21 @@
+/* Target-dependent definitions for Mac running MacOS.
+ Copyright 1994, 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 "m68k/tm-m68k.h"
diff --git a/gdb/config/m68k/tm-monitor.h b/gdb/config/m68k/tm-monitor.h
new file mode 100644
index 00000000000..6d38b5513b1
--- /dev/null
+++ b/gdb/config/m68k/tm-monitor.h
@@ -0,0 +1,46 @@
+/* Target machine definitions for a generic m68k monitor/emulator.
+ Copyright 1986, 1987, 1989, 1993, 1994, 1995, 1996, 1998, 1999
+ 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. */
+
+/* The definitions here are appropriate for several embedded m68k-based
+ targets, including IDP (rom68k), BCC (cpu32bug), and EST's emulator. */
+
+/* GCC is probably the only compiler used on this configuration. So
+ get this right even if the code which detects gcc2_compiled. is
+ still broken. */
+
+#define BELIEVE_PCC_PROMOTION 1
+
+/* The target system handles breakpoints. */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* No float registers. */
+
+/*#define NUM_REGS 18 */
+
+#include "m68k/tm-m68k.h"
+
+/* Need to do this for ELF targets, where we can't figure out the boundaries of
+ the entry file. This method stops the backtrace when we reach main. */
+
+#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi)
+
+/* FIXME, should do GET_LONGJMP_TARGET for newlib. */
diff --git a/gdb/config/m68k/tm-nbsd.h b/gdb/config/m68k/tm-nbsd.h
new file mode 100644
index 00000000000..62f008c7249
--- /dev/null
+++ b/gdb/config/m68k/tm-nbsd.h
@@ -0,0 +1,49 @@
+/* Macro definitions for m68k running under NetBSD.
+ Copyright 1994, 1996, 2001 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. */
+
+#ifndef TM_NBSD_H
+#define TM_NBSD_H
+
+#include <sys/param.h>
+#include <machine/vmparam.h>
+
+/* Define BPT_VECTOR if it is different than the default.
+ This is the vector number used by traps to indicate a breakpoint. */
+#define BPT_VECTOR 0xf
+#define REMOTE_BPT_VECTOR 0xf
+
+/* Address of end of stack space. */
+#define STACK_END_ADDR USRSTACK
+
+/* For NetBSD, sigtramp is 32 bytes before STACK_END_ADDR. */
+#define SIGTRAMP_START(pc) (STACK_END_ADDR - 32)
+#define SIGTRAMP_END(pc) (STACK_END_ADDR)
+
+#include "m68k/tm-m68k.h"
+
+/* Return non-zero if we are in a shared library trampoline code stub. */
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
+ (name && !strcmp(name, "_DYNAMIC"))
+
+extern use_struct_convention_fn m68knbsd_use_struct_convention;
+#define USE_STRUCT_CONVENTION(gcc_p, type) \
+ m68knbsd_use_struct_convention(gcc_p, type)
+
+#endif /* TM_NBSD_H */
diff --git a/gdb/config/m68k/tm-os68k.h b/gdb/config/m68k/tm-os68k.h
new file mode 100644
index 00000000000..ed1d5c89902
--- /dev/null
+++ b/gdb/config/m68k/tm-os68k.h
@@ -0,0 +1,47 @@
+/* Parameters for execution on VxWorks m68k's, for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1998 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 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. */
+
+#define GDBINIT_FILENAME ".os68gdbinit"
+
+#define DEFAULT_PROMPT "(os68k) "
+
+#include "m68k/tm-m68k.h"
+
+/* We have more complex, useful breakpoints on the target. */
+#undef DECR_PC_AFTER_BREAK
+#define DECR_PC_AFTER_BREAK 0
+
+/* Takes the current frame-struct pointer and returns the chain-pointer
+ to get to the calling frame.
+
+ If our current frame pointer is zero, we're at the top; else read out
+ the saved FP from memory pointed to by the current FP. */
+
+#undef FRAME_CHAIN
+#define FRAME_CHAIN(thisframe) ((thisframe)->frame? read_memory_integer ((thisframe)->frame, 4): 0)
+
+/* If the chain pointer is zero (either because the saved value fetched
+ by FRAME_CHAIN was zero, or because the current FP was zero so FRAME_CHAIN
+ never fetched anything), we are at the top of the stack. */
+/* We are guaranteed to have a zero frame pointer at bottom of stack, too. */
+
+#undef FRAME_CHAIN_VALID
+#define FRAME_CHAIN_VALID(chain, thisframe) nonnull_frame_chain_valid (chain, thisframe)
diff --git a/gdb/config/m68k/tm-st2000.h b/gdb/config/m68k/tm-st2000.h
new file mode 100644
index 00000000000..4d7a2b19bf9
--- /dev/null
+++ b/gdb/config/m68k/tm-st2000.h
@@ -0,0 +1,21 @@
+/* Parameters for a Tandem ST2000 phone switch.
+ Copyright (C) 1986, 1987, 1989, 199 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 "m68k/tm-m68k.h"
diff --git a/gdb/config/m68k/tm-sun2.h b/gdb/config/m68k/tm-sun2.h
new file mode 100644
index 00000000000..e839bea7f5a
--- /dev/null
+++ b/gdb/config/m68k/tm-sun2.h
@@ -0,0 +1,24 @@
+/* Parameters for execution on a Sun, for GDB, the GNU debugger.
+ Copyright (C) 1986, 1987, 1989, 1992 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. */
+
+/* The child target can't deal with floating registers. */
+#define CANNOT_STORE_REGISTER(regno) ((regno) >= FP0_REGNUM)
+
+#include "m68k/tm-m68k.h"
diff --git a/gdb/config/m68k/tm-sun2os4.h b/gdb/config/m68k/tm-sun2os4.h
new file mode 100644
index 00000000000..496c32955b3
--- /dev/null
+++ b/gdb/config/m68k/tm-sun2os4.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 1990, 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 "m68k/tm-sun2.h"
+#include "tm-sunos.h"
diff --git a/gdb/config/m68k/tm-sun3.h b/gdb/config/m68k/tm-sun3.h
new file mode 100644
index 00000000000..d7581ddd91d
--- /dev/null
+++ b/gdb/config/m68k/tm-sun3.h
@@ -0,0 +1,108 @@
+/* Parameters for execution on a Sun, for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1992, 1993, 1994, 1996, 2000
+ 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. */
+
+#ifndef TM_SUN3_H
+#define TM_SUN3_H
+
+/* Sun3 status includes fpflags, which shows whether the FPU has been used
+ by the process, and whether the FPU was done with an instruction or
+ was interrupted in the middle of a long instruction. See
+ <machine/reg.h>. */
+/* a&d, pc,sr, fp, fpstat, fpflags */
+
+#define REGISTER_BYTES (16*4 + 8 + 8*12 + 3*4 + 4)
+
+#define NUM_REGS 31
+
+#define REGISTER_BYTES_OK(b) \
+ ((b) == REGISTER_BYTES \
+ || (b) == REGISTER_BYTES_FP \
+ || (b) == REGISTER_BYTES_NOFP)
+
+/* If PC contains this instruction, then we know what we are in a system
+ call stub, and the return PC is is at SP+4, instead of SP. */
+
+#define SYSCALL_TRAP 0x4e40 /* trap #0 */
+#define SYSCALL_TRAP_OFFSET 0 /* PC points at trap instruction */
+
+#include "m68k/tm-m68k.h"
+
+/* Disable alternate breakpoint mechanism needed by 68k stub. */
+#undef REMOTE_BREAKPOINT
+
+/* Offsets (in target ints) into jmp_buf. Not defined by Sun, but at least
+ documented in a comment in <machine/setjmp.h>! */
+
+#define JB_ELEMENT_SIZE 4
+
+#define JB_ONSSTACK 0
+#define JB_SIGMASK 1
+#define JB_SP 2
+#define JB_PC 3
+#define JB_PSL 4
+#define JB_D2 5
+#define JB_D3 6
+#define JB_D4 7
+#define JB_D5 8
+#define JB_D6 9
+#define JB_D7 10
+#define JB_A2 11
+#define JB_A3 12
+#define JB_A4 13
+#define JB_A5 14
+#define JB_A6 15
+
+/* Figure out where the longjmp will land. Slurp the args out of the stack.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+#define GET_LONGJMP_TARGET(ADDR) m68k_get_longjmp_target(ADDR)
+
+/* If sun3 pcc says that a parameter is a short, it's a short. */
+#define BELIEVE_PCC_PROMOTION_TYPE
+
+/* Can't define BELIEVE_PCC_PROMOTION for SunOS /bin/cc of SunOS 4.1.1.
+ Apparently Sun fixed this for the sparc but not the sun3. */
+
+/* The code which tries to deal with this bug is never harmful on a sun3. */
+#define SUN_FIXED_LBRAC_BUG (0)
+
+/* On the sun3 the kernel pushes a sigcontext on the user stack and then
+ `calls' _sigtramp in user code. _sigtramp saves the floating point status
+ on the stack and calls the signal handler function. The stack does not
+ contain enough information to allow a normal backtrace, but sigcontext
+ contains the saved user pc/sp. FRAME_CHAIN and friends in tm-m68k.h and
+ m68k_find_saved_regs deal with this situation by manufacturing a fake frame
+ for _sigtramp.
+ SIG_PC_FP_OFFSET is the offset from the signal handler frame to the
+ saved pc in sigcontext.
+ SIG_SP_FP_OFFSET is the offset from the signal handler frame to the end
+ of sigcontext which is identical to the saved sp at SIG_PC_FP_OFFSET - 4.
+
+ Please note that it is impossible to correctly backtrace from a breakpoint
+ in _sigtramp as _sigtramp modifies the stack pointer a few times. */
+
+#undef SIG_PC_FP_OFFSET
+#define SIG_PC_FP_OFFSET 324
+#define SIG_SP_FP_OFFSET 332
+
+#endif /* TM_SUN3_H */
diff --git a/gdb/config/m68k/tm-sun3os4.h b/gdb/config/m68k/tm-sun3os4.h
new file mode 100644
index 00000000000..d4bc74fd8e7
--- /dev/null
+++ b/gdb/config/m68k/tm-sun3os4.h
@@ -0,0 +1,22 @@
+/* Target machine parameters for Sun-3 under SunOS 4.x, for GDB.
+ Copyright (C) 1986, 1987, 1989, 1992 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 "m68k/tm-sun3.h"
+#include "tm-sunos.h"
diff --git a/gdb/config/m68k/tm-vx68.h b/gdb/config/m68k/tm-vx68.h
new file mode 100644
index 00000000000..988b4bb4b9e
--- /dev/null
+++ b/gdb/config/m68k/tm-vx68.h
@@ -0,0 +1,89 @@
+/* Target machine description for VxWorks m68k's, for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1996, 1998, 1999, 2000
+ 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 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. */
+
+/* GCC is probably the only compiler used on this configuration. So
+ get this right even if the code which detects gcc2_compiled. is
+ still broken. */
+
+#define BELIEVE_PCC_PROMOTION 1
+
+/* We have more complex, useful breakpoints on the target. */
+#define DECR_PC_AFTER_BREAK 0
+
+#include "m68k/tm-m68k.h"
+#include "tm-vxworks.h"
+
+/* Takes the current frame-struct pointer and returns the chain-pointer
+ to get to the calling frame.
+
+ If our current frame pointer is zero, we're at the top; else read out
+ the saved FP from memory pointed to by the current FP. */
+
+#undef FRAME_CHAIN
+#define FRAME_CHAIN(thisframe) ((thisframe)->frame? read_memory_integer ((thisframe)->frame, 4): 0)
+
+/* If the chain pointer is zero (either because the saved value fetched
+ by FRAME_CHAIN was zero, or because the current FP was zero so FRAME_CHAIN
+ never fetched anything), we are at the top of the stack. */
+/* We are guaranteed to have a zero frame pointer at bottom of stack, too. */
+
+#undef FRAME_CHAIN_VALID
+#define FRAME_CHAIN_VALID(chain, thisframe) nonnull_frame_chain_valid (chain, thisframe)
+
+/* FIXME, Longjmp information stolen from Sun-3 config. Dunno if right. */
+/* Offsets (in target ints) into jmp_buf. Not defined by Sun, but at least
+ documented in a comment in <machine/setjmp.h>! */
+
+#define JB_ELEMENT_SIZE 4
+
+#define JB_ONSSTACK 0
+#define JB_SIGMASK 1
+#define JB_SP 2
+#define JB_PC 3
+#define JB_PSL 4
+#define JB_D2 5
+#define JB_D3 6
+#define JB_D4 7
+#define JB_D5 8
+#define JB_D6 9
+#define JB_D7 10
+#define JB_A2 11
+#define JB_A3 12
+#define JB_A4 13
+#define JB_A5 14
+#define JB_A6 15
+
+/* Figure out where the longjmp will land. Slurp the args out of the stack.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+#define GET_LONGJMP_TARGET(ADDR) m68k_get_longjmp_target(ADDR)
+
+/* Number of registers in a ptrace_getregs call. */
+
+#define VX_NUM_REGS (18)
+
+/* Number of registers in a ptrace_getfpregs call. */
+
+#define VX_SIZE_FPREGS (8 * REGISTER_RAW_SIZE (FP0_REGNUM) \
+ + (3 * REGISTER_SIZE))
diff --git a/gdb/config/m68k/vxworks68.mt b/gdb/config/m68k/vxworks68.mt
new file mode 100644
index 00000000000..8c9774496cb
--- /dev/null
+++ b/gdb/config/m68k/vxworks68.mt
@@ -0,0 +1,3 @@
+# Target: Motorola m68k running VxWorks
+TDEPFILES= m68k-tdep.o remote-vx.o remote-vx68.o xdr_ld.o xdr_ptrace.o xdr_rdb.o
+TM_FILE= tm-vx68.h
diff --git a/gdb/config/m68k/xm-3b1.h b/gdb/config/m68k/xm-3b1.h
new file mode 100644
index 00000000000..acf72e98201
--- /dev/null
+++ b/gdb/config/m68k/xm-3b1.h
@@ -0,0 +1,82 @@
+/* Parameters for execution on a 3b1.
+ Copyright 1986, 1987, 1989, 1999 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. */
+
+#define HAVE_TERMIO
+#define USG
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+
+#define KERNEL_U_ADDR 0x70000
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+{ addr = blockend + regno * 4; }
+
+/* Interface definitions for kernel debugger KDB. */
+
+/* Map machine fault codes into signal numbers.
+ First subtract 0, divide by 4, then index in a table.
+ Faults for which the entry in this table is 0
+ are not handled by KDB; the program's own trap handler
+ gets to handle then. */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+ 0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+ SIGILL }
+
+/* Start running with a stack stretching from BEG to END.
+ BEG and END should be symbols meaningful to the assembler.
+ This is used only for kdb. */
+
+#define INIT_STACK(beg, end) \
+{ asm (".globl end"); \
+ asm ("movel $ end, sp"); \
+ asm ("clrl fp"); }
+
+/* Push the frame pointer register on the stack. */
+#define PUSH_FRAME_PTR \
+ asm ("movel fp, -(sp)");
+
+/* Copy the top-of-stack to the frame pointer register. */
+#define POP_FRAME_PTR \
+ asm ("movl (sp), fp");
+
+/* After KDB is entered by a fault, push all registers
+ that GDB thinks about (all NUM_REGS of them),
+ so that they appear in order of ascending GDB register number.
+ The fault code will be on the stack beyond the last register. */
+
+#define PUSH_REGISTERS \
+{ asm ("clrw -(sp)"); \
+ asm ("pea 10(sp)"); \
+ asm ("movem $ 0xfffe,-(sp)"); }
+
+/* Assuming the registers (including processor status) have been
+ pushed on the stack in order of ascending GDB register number,
+ restore them and return to the address in the saved PC register. */
+
+#define POP_REGISTERS \
+{ asm ("subil $8,28(sp)"); \
+ asm ("movem (sp),$ 0xffff"); \
+ asm ("rte"); }
diff --git a/gdb/config/m68k/xm-apollo68b.h b/gdb/config/m68k/xm-apollo68b.h
new file mode 100644
index 00000000000..d77509d5a0d
--- /dev/null
+++ b/gdb/config/m68k/xm-apollo68b.h
@@ -0,0 +1,21 @@
+/* Macro definitions for an Apollo m68k in BSD mode
+ Copyright 1992, 2001 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. */
+
+#define ALIGN_STACK_ON_STARTUP
diff --git a/gdb/config/m68k/xm-apollo68v.h b/gdb/config/m68k/xm-apollo68v.h
new file mode 100644
index 00000000000..8919088b4f2
--- /dev/null
+++ b/gdb/config/m68k/xm-apollo68v.h
@@ -0,0 +1,42 @@
+/* Macro defintions for an Apollo.
+ Copyright (C) 1986, 1987, 1989, 1992 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. */
+
+/*
+ * Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu)
+ * July 1988
+ */
+
+/* I'm running gdb 3.4 under 386/ix 2.0.2, which is a derivative of AT&T's
+ Sys V/386 3.2.
+
+ On some machines, gdb crashes when it's starting up while calling the
+ vendor's termio tgetent() routine. It always works when run under
+ itself (actually, under 3.2, it's not an infinitely recursive bug.)
+ After some poking around, it appears that depending on the environment
+ size, or whether you're running YP, or the phase of the moon or something,
+ the stack is not always long-aligned when main() is called, and tgetent()
+ takes strong offense at that. On some machines this bug never appears, but
+ on those where it does, it occurs quite reliably. */
+#define ALIGN_STACK_ON_STARTUP
+
+/* define USG if you are using sys5 /usr/include's */
+#define USG
+
+#define HAVE_TERMIO
diff --git a/gdb/config/m68k/xm-delta68.h b/gdb/config/m68k/xm-delta68.h
new file mode 100644
index 00000000000..f691c387db2
--- /dev/null
+++ b/gdb/config/m68k/xm-delta68.h
@@ -0,0 +1,35 @@
+/* Macro definitions for a Delta.
+ Copyright (C) 1986, 1987, 1989, 1992 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. */
+
+/* I'm running gdb 4.9 under sysV68 R3V7.1.
+
+ On some machines, gdb crashes when it's starting up while calling the
+ vendor's termio tgetent() routine. It always works when run under
+ itself (actually, under 3.2, it's not an infinitely recursive bug.)
+ After some poking around, it appears that depending on the environment
+ size, or whether you're running YP, or the phase of the moon or something,
+ the stack is not always long-aligned when main() is called, and tgetent()
+ takes strong offense at that. On some machines this bug never appears, but
+ on those where it does, it occurs quite reliably. */
+#define ALIGN_STACK_ON_STARTUP
+
+#define USG
+
+#define HAVE_TERMIO
diff --git a/gdb/config/m68k/xm-dpx2.h b/gdb/config/m68k/xm-dpx2.h
new file mode 100644
index 00000000000..4083c9dbc19
--- /dev/null
+++ b/gdb/config/m68k/xm-dpx2.h
@@ -0,0 +1,22 @@
+/* Parameters for execution on a Bull DPX2.
+ Copyright 1986, 1987, 1989, 1993 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. */
+
+#define HAVE_TERMIOS
+#define USG
diff --git a/gdb/config/m68k/xm-hp300bsd.h b/gdb/config/m68k/xm-hp300bsd.h
new file mode 100644
index 00000000000..b938353b5f7
--- /dev/null
+++ b/gdb/config/m68k/xm-hp300bsd.h
@@ -0,0 +1,83 @@
+/* Parameters for hosting on a Hewlett-Packard 9000/300, running bsd.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1995, 1996, 2000, 2001
+ 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. */
+
+/*
+ * Configuration file for HP9000/300 series machine running
+ * University of Utah's 4.3bsd (or 4.4BSD) port. This is NOT for HP-UX.
+ * Problems to hpbsd-bugs@cs.utah.edu
+ */
+
+#include <sys/param.h> /* For INT_MIN */
+
+/* Kernel is a bit tenacious about sharing text segments, disallowing bpts. */
+#define ONE_PROCESS_WRITETEXT
+
+/* Interface definitions for kernel debugger KDB. */
+
+/* Map machine fault codes into signal numbers.
+ First subtract 0, divide by 4, then index in a table.
+ Faults for which the entry in this table is 0
+ are not handled by KDB; the program's own trap handler
+ gets to handle then. */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+ 0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+ SIGILL }
+
+/* Start running with a stack stretching from BEG to END.
+ BEG and END should be symbols meaningful to the assembler.
+ This is used only for kdb. */
+
+#define INIT_STACK(beg, end) \
+{ asm (".globl end"); \
+ asm ("movel #end, sp"); \
+ asm ("movel #0,a6"); }
+
+/* Push the frame pointer register on the stack. */
+#define PUSH_FRAME_PTR \
+ asm ("movel a6,sp@-");
+
+/* Copy the top-of-stack to the frame pointer register. */
+#define POP_FRAME_PTR \
+ asm ("movl sp@,a6");
+
+/* After KDB is entered by a fault, push all registers
+ that GDB thinks about (all NUM_REGS of them),
+ so that they appear in order of ascending GDB register number.
+ The fault code will be on the stack beyond the last register. */
+
+#define PUSH_REGISTERS \
+{ asm ("clrw -(sp)"); \
+ asm ("pea sp@(10)"); \
+ asm ("movem #0xfffe,sp@-"); }
+
+/* Assuming the registers (including processor status) have been
+ pushed on the stack in order of ascending GDB register number,
+ restore them and return to the address in the saved PC register. */
+
+#define POP_REGISTERS \
+{ asm ("subil #8,sp@(28)"); \
+ asm ("movem sp@,#0xffff"); \
+ asm ("rte"); }
diff --git a/gdb/config/m68k/xm-hp300hpux.h b/gdb/config/m68k/xm-hp300hpux.h
new file mode 100644
index 00000000000..f5982b4491a
--- /dev/null
+++ b/gdb/config/m68k/xm-hp300hpux.h
@@ -0,0 +1,150 @@
+/* Parameters for HP 9000 model 320 hosting, for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996
+ 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. */
+
+/* Define this to indicate problems with traps after continuing. */
+#define HP_OS_BUG
+
+/* Set flag to indicate whether HP's assembler is in use. */
+#ifdef __GNUC__
+#ifdef __HPUX_ASM__
+#define HPUX_ASM
+#endif
+#else /* not GNU C. */
+#define HPUX_ASM
+#endif /* not GNU C. */
+
+/* Define this for versions of hp-ux older than 6.0 */
+/* #define HPUX_VERSION_5 */
+
+/* define USG if you are using sys5 /usr/include's */
+#undef USG /* In case it was defined in the Makefile for cplus-dem.c */
+#define USG
+
+#define HAVE_TERMIOS
+
+#define REGISTER_ADDR(u_ar0, regno) \
+ (unsigned int) \
+ (((regno) < PS_REGNUM) \
+ ? (&((struct exception_stack *) (u_ar0))->e_regs[(regno + R0)]) \
+ : (((regno) == PS_REGNUM) \
+ ? ((int *) (&((struct exception_stack *) (u_ar0))->e_PS)) \
+ : (&((struct exception_stack *) (u_ar0))->e_PC)))
+
+#define FP_REGISTER_ADDR(u, regno) \
+ (((char *) \
+ (((regno) < FPC_REGNUM) \
+ ? (&u.u_pcb.pcb_mc68881[FMC68881_R0 + (((regno) - FP0_REGNUM) * 3)]) \
+ : (&u.u_pcb.pcb_mc68881[FMC68881_C + ((regno) - FPC_REGNUM)]))) \
+ - ((char *) (& u)))
+
+/* Interface definitions for kernel debugger KDB. */
+
+/* Map machine fault codes into signal numbers.
+ First subtract 0, divide by 4, then index in a table.
+ Faults for which the entry in this table is 0
+ are not handled by KDB; the program's own trap handler
+ gets to handle then. */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+ 0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+ SIGILL }
+
+#ifndef HPUX_ASM
+
+/* Start running with a stack stretching from BEG to END.
+ BEG and END should be symbols meaningful to the assembler.
+ This is used only for kdb. */
+
+#define INIT_STACK(beg, end) \
+{ asm (".globl end"); \
+ asm ("movel $ end, sp"); \
+ asm ("clrl fp"); }
+
+/* Push the frame pointer register on the stack. */
+#define PUSH_FRAME_PTR \
+ asm ("movel fp, -(sp)");
+
+/* Copy the top-of-stack to the frame pointer register. */
+#define POP_FRAME_PTR \
+ asm ("movl (sp), fp");
+
+/* After KDB is entered by a fault, push all registers
+ that GDB thinks about (all NUM_REGS of them),
+ so that they appear in order of ascending GDB register number.
+ The fault code will be on the stack beyond the last register. */
+
+#define PUSH_REGISTERS \
+{ asm ("clrw -(sp)"); \
+ asm ("pea 10(sp)"); \
+ asm ("movem $ 0xfffe,-(sp)"); }
+
+/* Assuming the registers (including processor status) have been
+ pushed on the stack in order of ascending GDB register number,
+ restore them and return to the address in the saved PC register. */
+
+#define POP_REGISTERS \
+{ asm ("subil $8,28(sp)"); \
+ asm ("movem (sp),$ 0xffff"); \
+ asm ("rte"); }
+
+#else /* HPUX_ASM */
+
+/* Start running with a stack stretching from BEG to END.
+ BEG and END should be symbols meaningful to the assembler.
+ This is used only for kdb. */
+
+#define INIT_STACK(beg, end) \
+{ asm ("global end"); \
+ asm ("mov.l &end,%sp"); \
+ asm ("clr.l %a6"); }
+
+/* Push the frame pointer register on the stack. */
+#define PUSH_FRAME_PTR \
+ asm ("mov.l %fp,-(%sp)");
+
+/* Copy the top-of-stack to the frame pointer register. */
+#define POP_FRAME_PTR \
+ asm ("mov.l (%sp),%fp");
+
+/* After KDB is entered by a fault, push all registers
+ that GDB thinks about (all NUM_REGS of them),
+ so that they appear in order of ascending GDB register number.
+ The fault code will be on the stack beyond the last register. */
+
+#define PUSH_REGISTERS \
+{ asm ("clr.w -(%sp)"); \
+ asm ("pea 10(%sp)"); \
+ asm ("movm.l &0xfffe,-(%sp)"); }
+
+/* Assuming the registers (including processor status) have been
+ pushed on the stack in order of ascending GDB register number,
+ restore them and return to the address in the saved PC register. */
+
+#define POP_REGISTERS \
+{ asm ("subi.l &8,28(%sp)"); \
+ asm ("mov.m (%sp),&0xffff"); \
+ asm ("rte"); }
+
+#endif /* HPUX_ASM */
diff --git a/gdb/config/m68k/xm-linux.h b/gdb/config/m68k/xm-linux.h
new file mode 100644
index 00000000000..e5839b99bbf
--- /dev/null
+++ b/gdb/config/m68k/xm-linux.h
@@ -0,0 +1,34 @@
+/* Native support for linux, for GDB, the GNU debugger.
+ Copyright 1996, 1998, 2001 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. */
+
+#ifndef XM_LINUX_H
+#define XM_LINUX_H
+
+/* Pick up most of what we need from the generic m68k host include file. */
+
+#include "m68k/xm-m68k.h"
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+#define KERNEL_U_ADDR 0x0
+
+#define HOST_LONG_DOUBLE_FORMAT &floatformat_m68881_ext
+
+#endif /* #ifndef XM_LINUX_H */
diff --git a/gdb/config/m68k/xm-m68k.h b/gdb/config/m68k/xm-m68k.h
new file mode 100644
index 00000000000..5dc40ecb8f7
--- /dev/null
+++ b/gdb/config/m68k/xm-m68k.h
@@ -0,0 +1,21 @@
+/* Macro definitions for running gdb on host machines with m68k cpu's.
+ Copyright (C) 1991, Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus Support (fnf@cygint)
+
+ 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. */
+
diff --git a/gdb/config/m68k/xm-m68kv4.h b/gdb/config/m68k/xm-m68kv4.h
new file mode 100644
index 00000000000..11679a965eb
--- /dev/null
+++ b/gdb/config/m68k/xm-m68kv4.h
@@ -0,0 +1,29 @@
+/* Host definitions for GDB on a Motorola 680x0 running SVR4.
+ (Commodore Amiga with amix or Atari TT with ASV)
+ Copyright 1991, 1992, 1994, 1996 Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus Support (fnf@cygnus.com)
+
+ 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. */
+
+/* Pick up most of what we need from the generic m68k host include file. */
+
+#include "m68k/xm-m68k.h"
+
+/* Pick up more stuff from the generic SVR4 host include file. */
+
+#include "xm-sysv4.h"
diff --git a/gdb/config/m68k/xm-nbsd.h b/gdb/config/m68k/xm-nbsd.h
new file mode 100644
index 00000000000..c266a99e628
--- /dev/null
+++ b/gdb/config/m68k/xm-nbsd.h
@@ -0,0 +1,22 @@
+/* Parameters for execution on a Motorola m68k running NetBSD, for GDB.
+ Copyright 1996 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. */
+
+/* Get generic NetBSD host definitions. */
+#include "xm-nbsd.h"
diff --git a/gdb/config/m68k/xm-sun2.h b/gdb/config/m68k/xm-sun2.h
new file mode 100644
index 00000000000..cf846192491
--- /dev/null
+++ b/gdb/config/m68k/xm-sun2.h
@@ -0,0 +1,77 @@
+/* Parameters for execution on a Sun, for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1996 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. */
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+
+#define KERNEL_U_ADDR 0x2800
+
+
+/* Interface definitions for kernel debugger KDB. */
+
+/* Map machine fault codes into signal numbers.
+ First subtract 0, divide by 4, then index in a table.
+ Faults for which the entry in this table is 0
+ are not handled by KDB; the program's own trap handler
+ gets to handle then. */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+ 0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+ SIGILL }
+
+/* Start running with a stack stretching from BEG to END.
+ BEG and END should be symbols meaningful to the assembler.
+ This is used only for kdb. */
+
+#define INIT_STACK(beg, end) \
+{ asm (".globl end"); \
+ asm ("movel $ end, sp"); \
+ asm ("clrl fp"); }
+
+/* Push the frame pointer register on the stack. */
+#define PUSH_FRAME_PTR \
+ asm ("movel fp, -(sp)");
+
+/* Copy the top-of-stack to the frame pointer register. */
+#define POP_FRAME_PTR \
+ asm ("movl (sp), fp");
+
+/* After KDB is entered by a fault, push all registers
+ that GDB thinks about (all NUM_REGS of them),
+ so that they appear in order of ascending GDB register number.
+ The fault code will be on the stack beyond the last register. */
+
+#define PUSH_REGISTERS \
+{ asm ("clrw -(sp)"); \
+ asm ("pea 10(sp)"); \
+ asm ("movem $ 0xfffe,-(sp)"); }
+
+/* Assuming the registers (including processor status) have been
+ pushed on the stack in order of ascending GDB register number,
+ restore them and return to the address in the saved PC register. */
+
+#define POP_REGISTERS \
+{ asm ("subil $8,28(sp)"); \
+ asm ("movem (sp),$ 0xffff"); \
+ asm ("rte"); }
diff --git a/gdb/config/m68k/xm-sun3.h b/gdb/config/m68k/xm-sun3.h
new file mode 100644
index 00000000000..6a5a560e1c3
--- /dev/null
+++ b/gdb/config/m68k/xm-sun3.h
@@ -0,0 +1,71 @@
+/* Parameters for execution on a Sun, for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1996 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. */
+
+/* Interface definitions for kernel debugger KDB. */
+
+/* Map machine fault codes into signal numbers.
+ First subtract 0, divide by 4, then index in a table.
+ Faults for which the entry in this table is 0
+ are not handled by KDB; the program's own trap handler
+ gets to handle then. */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+ 0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+ SIGILL }
+
+/* Start running with a stack stretching from BEG to END.
+ BEG and END should be symbols meaningful to the assembler.
+ This is used only for kdb. */
+
+#define INIT_STACK(beg, end) \
+{ asm (".globl end"); \
+ asm ("movel #end, sp"); \
+ asm ("movel #0,a6"); }
+
+/* Push the frame pointer register on the stack. */
+#define PUSH_FRAME_PTR \
+ asm ("movel a6,sp@-");
+
+/* Copy the top-of-stack to the frame pointer register. */
+#define POP_FRAME_PTR \
+ asm ("movl sp@,a6");
+
+/* After KDB is entered by a fault, push all registers
+ that GDB thinks about (all NUM_REGS of them),
+ so that they appear in order of ascending GDB register number.
+ The fault code will be on the stack beyond the last register. */
+
+#define PUSH_REGISTERS \
+{ asm ("clrw -(sp)"); \
+ asm ("pea sp@(10)"); \
+ asm ("movem #0xfffe,sp@-"); }
+
+/* Assuming the registers (including processor status) have been
+ pushed on the stack in order of ascending GDB register number,
+ restore them and return to the address in the saved PC register. */
+
+#define POP_REGISTERS \
+{ asm ("subil #8,sp@(28)"); \
+ asm ("movem sp@,#0xffff"); \
+ asm ("rte"); }
diff --git a/gdb/config/m68k/xm-sun3os4.h b/gdb/config/m68k/xm-sun3os4.h
new file mode 100644
index 00000000000..1a819c32a9a
--- /dev/null
+++ b/gdb/config/m68k/xm-sun3os4.h
@@ -0,0 +1,22 @@
+/* Macro definitions for a sun 3 running os 4.
+ Copyright 1989, 1996, 1998 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 "m68k/xm-sun3.h"
+#define FPU
diff --git a/gdb/config/m88k/delta88.mh b/gdb/config/m88k/delta88.mh
new file mode 100644
index 00000000000..13dc6c27e8d
--- /dev/null
+++ b/gdb/config/m88k/delta88.mh
@@ -0,0 +1,6 @@
+# Host: Motorola 88k running SVR3
+
+XM_FILE= xm-delta88.h
+
+NAT_FILE= nm-m88k.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o m88k-nat.o corelow.o core-aout.o
diff --git a/gdb/config/m88k/delta88.mt b/gdb/config/m88k/delta88.mt
new file mode 100644
index 00000000000..c8e669b687c
--- /dev/null
+++ b/gdb/config/m88k/delta88.mt
@@ -0,0 +1,3 @@
+# Target: Motorola 88k running SVR3
+TDEPFILES= m88k-tdep.o
+TM_FILE= tm-delta88.h
diff --git a/gdb/config/m88k/delta88v4.mh b/gdb/config/m88k/delta88v4.mh
new file mode 100644
index 00000000000..ba3dd7b6993
--- /dev/null
+++ b/gdb/config/m88k/delta88v4.mh
@@ -0,0 +1,8 @@
+# Host: Motorola 88k running SVR4
+
+XM_FILE= xm-delta88v4.h
+
+NAT_FILE= nm-delta88v4.h
+NATDEPFILES= fork-child.o m88k-nat.o corelow.o core-regset.o \
+ solib.o solib-svr4.o solib-legacy.o \
+ procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o
diff --git a/gdb/config/m88k/delta88v4.mt b/gdb/config/m88k/delta88v4.mt
new file mode 100644
index 00000000000..7797d4b6295
--- /dev/null
+++ b/gdb/config/m88k/delta88v4.mt
@@ -0,0 +1,3 @@
+# Target: Motorola 88k running SVR4
+TDEPFILES= m88k-tdep.o
+TM_FILE= tm-delta88v4.h
diff --git a/gdb/config/m88k/m88k.mh b/gdb/config/m88k/m88k.mh
new file mode 100644
index 00000000000..5d4350bb20b
--- /dev/null
+++ b/gdb/config/m88k/m88k.mh
@@ -0,0 +1,4 @@
+# Host: Motorola 88000 running DGUX
+XM_FILE= xm-dgux.h
+NAT_FILE= nm-m88k.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o m88k-nat.o
diff --git a/gdb/config/m88k/m88k.mt b/gdb/config/m88k/m88k.mt
new file mode 100644
index 00000000000..ca3fab41165
--- /dev/null
+++ b/gdb/config/m88k/m88k.mt
@@ -0,0 +1,3 @@
+# Target: Motorola 88k Binary Compatibility Standard
+TDEPFILES= m88k-tdep.o remote-bug.o
+TM_FILE= tm-m88k.h
diff --git a/gdb/config/m88k/nm-delta88v4.h b/gdb/config/m88k/nm-delta88v4.h
new file mode 100644
index 00000000000..90ee391b2b6
--- /dev/null
+++ b/gdb/config/m88k/nm-delta88v4.h
@@ -0,0 +1,23 @@
+/* Native machine description for Motorola Delta 88 box, for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1993
+ 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 "m88k/nm-m88k.h"
+#include "nm-sysv4.h"
diff --git a/gdb/config/m88k/nm-m88k.h b/gdb/config/m88k/nm-m88k.h
new file mode 100644
index 00000000000..4c402bd1127
--- /dev/null
+++ b/gdb/config/m88k/nm-m88k.h
@@ -0,0 +1,25 @@
+/* Native support macros for m88k, for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992
+ 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. */
+
+#define FETCH_INFERIOR_REGISTERS
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = m88k_register_u_addr ((blockend),(regno));
diff --git a/gdb/config/m88k/tm-delta88.h b/gdb/config/m88k/tm-delta88.h
new file mode 100644
index 00000000000..f44b1f79cff
--- /dev/null
+++ b/gdb/config/m88k/tm-delta88.h
@@ -0,0 +1,28 @@
+/* Target machine description for Motorola Delta 88 box, for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1993, 1994
+ 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 "m88k/tm-m88k.h"
+
+#define DELTA88
+
+#define IN_SIGTRAMP(pc, name) ((name) && STREQ ("_sigcode", (name)))
+#define SIGTRAMP_FRAME_FIXUP(frame) (frame) += 0x20
+#define SIGTRAMP_SP_FIXUP(sp) (sp) = read_memory_integer((sp), 4)
diff --git a/gdb/config/m88k/tm-delta88v4.h b/gdb/config/m88k/tm-delta88v4.h
new file mode 100644
index 00000000000..35a605d3536
--- /dev/null
+++ b/gdb/config/m88k/tm-delta88v4.h
@@ -0,0 +1,32 @@
+/* Target machine description for Motorola Delta 88 box, for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1993, 1994, 1998, 1999
+ 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. */
+
+#define DELTA88
+
+#include "m88k/tm-m88k.h"
+#include "tm-sysv4.h"
+
+/* If we don't define this, backtraces go on forever. */
+#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi)
+
+#define IN_SIGTRAMP(pc, name) ((name) && (STREQ ("signalhandler", (name)) \
+ || STREQ("sigacthandler", (name))))
+#define SIGTRAMP_SP_FIXUP(sp) (sp) = read_memory_integer((sp)+0xcd8, 4)
diff --git a/gdb/config/m88k/tm-m88k.h b/gdb/config/m88k/tm-m88k.h
new file mode 100644
index 00000000000..7405c1294f1
--- /dev/null
+++ b/gdb/config/m88k/tm-m88k.h
@@ -0,0 +1,587 @@
+/* Target machine description for generic Motorola 88000, for GDB.
+
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1993, 1994, 1996,
+ 1998, 1999, 2000, 2002 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 "doublest.h"
+#include "regcache.h"
+
+/* g++ support is not yet included. */
+
+/* We cache information about saved registers in the frame structure,
+ to save us from having to re-scan function prologues every time
+ a register in a non-current frame is accessed. */
+
+#define EXTRA_FRAME_INFO \
+ struct frame_saved_regs *fsr; \
+ CORE_ADDR locals_pointer; \
+ CORE_ADDR args_pointer;
+
+/* Zero the frame_saved_regs pointer when the frame is initialized,
+ so that FRAME_FIND_SAVED_REGS () will know to allocate and
+ initialize a frame_saved_regs struct the first time it is called.
+ Set the arg_pointer to -1, which is not valid; 0 and other values
+ indicate real, cached values. */
+
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \
+ init_extra_frame_info (fromleaf, fi)
+extern void init_extra_frame_info ();
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code. */
+
+extern CORE_ADDR m88k_skip_prologue (CORE_ADDR);
+#define SKIP_PROLOGUE(frompc) (m88k_skip_prologue (frompc))
+
+/* The m88k kernel aligns all instructions on 4-byte boundaries. The
+ kernel also uses the least significant two bits for its own hocus
+ pocus. When gdb receives an address from the kernel, it needs to
+ preserve those right-most two bits, but gdb also needs to be careful
+ to realize that those two bits are not really a part of the address
+ of an instruction. Shrug. */
+
+extern CORE_ADDR m88k_addr_bits_remove (CORE_ADDR);
+#define ADDR_BITS_REMOVE(addr) m88k_addr_bits_remove (addr)
+
+/* Immediately after a function call, return the saved pc.
+ Can't always go through the frames for this because on some machines
+ the new frame is not set up until the new function executes
+ some instructions. */
+
+#define SAVED_PC_AFTER_CALL(frame) \
+ (ADDR_BITS_REMOVE (read_register (SRP_REGNUM)))
+
+/* Stack grows downward. */
+
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+/* Sequence of bytes for breakpoint instruction. */
+
+/* instruction 0xF000D1FF is 'tb0 0,r0,511'
+ If Bit bit 0 of r0 is clear (always true),
+ initiate exception processing (trap).
+ */
+#define BREAKPOINT {0xF0, 0x00, 0xD1, 0xFF}
+
+/* Amount PC must be decremented by after a breakpoint.
+ This is often the number of bytes in BREAKPOINT
+ but not always. */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Say how long (ordinary) registers are. This is a piece of bogosity
+ used in push_word and a few other places; REGISTER_RAW_SIZE is the
+ real way to know how big a register is. */
+
+#define REGISTER_SIZE 4
+
+/* Number of machine registers */
+
+#define GP_REGS (38)
+#define FP_REGS (32)
+#define NUM_REGS (GP_REGS + FP_REGS)
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer. */
+
+#define REGISTER_NAMES {\
+ "r0",\
+ "r1",\
+ "r2",\
+ "r3",\
+ "r4",\
+ "r5",\
+ "r6",\
+ "r7",\
+ "r8",\
+ "r9",\
+ "r10",\
+ "r11",\
+ "r12",\
+ "r13",\
+ "r14",\
+ "r15",\
+ "r16",\
+ "r17",\
+ "r18",\
+ "r19",\
+ "r20",\
+ "r21",\
+ "r22",\
+ "r23",\
+ "r24",\
+ "r25",\
+ "r26",\
+ "r27",\
+ "r28",\
+ "r29",\
+ "r30",\
+ "r31",\
+ "psr",\
+ "fpsr",\
+ "fpcr",\
+ "sxip",\
+ "snip",\
+ "sfip",\
+ "x0",\
+ "x1",\
+ "x2",\
+ "x3",\
+ "x4",\
+ "x5",\
+ "x6",\
+ "x7",\
+ "x8",\
+ "x9",\
+ "x10",\
+ "x11",\
+ "x12",\
+ "x13",\
+ "x14",\
+ "x15",\
+ "x16",\
+ "x17",\
+ "x18",\
+ "x19",\
+ "x20",\
+ "x21",\
+ "x22",\
+ "x23",\
+ "x24",\
+ "x25",\
+ "x26",\
+ "x27",\
+ "x28",\
+ "x29",\
+ "x30",\
+ "x31",\
+ "vbr",\
+ "dmt0",\
+ "dmd0",\
+ "dma0",\
+ "dmt1",\
+ "dmd1",\
+ "dma1",\
+ "dmt2",\
+ "dmd2",\
+ "dma2",\
+ "sr0",\
+ "sr1",\
+ "sr2",\
+ "sr3",\
+ "fpecr",\
+ "fphs1",\
+ "fpls1",\
+ "fphs2",\
+ "fpls2",\
+ "fppt",\
+ "fprh",\
+ "fprl",\
+ "fpit",\
+ "fpsr",\
+ "fpcr",\
+ }
+
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define R0_REGNUM 0 /* Contains the constant zero */
+#define SRP_REGNUM 1 /* Contains subroutine return pointer */
+#define RV_REGNUM 2 /* Contains simple return values */
+#define SRA_REGNUM 12 /* Contains address of struct return values */
+#define SP_REGNUM 31 /* Contains address of top of stack */
+
+/* Instruction pointer notes...
+
+ On the m88100:
+
+ * cr04 = sxip. On exception, contains the excepting pc (probably).
+ On rte, is ignored.
+
+ * cr05 = snip. On exception, contains the NPC (next pc). On rte,
+ pc is loaded from here.
+
+ * cr06 = sfip. On exception, contains the NNPC (next next pc). On
+ rte, the NPC is loaded from here.
+
+ * lower two bits of each are flag bits. Bit 1 is V means address
+ is valid. If address is not valid, bit 0 is ignored. Otherwise,
+ bit 0 is E and asks for an exception to be taken if this
+ instruction is executed.
+
+ On the m88110:
+
+ * cr04 = exip. On exception, contains the address of the excepting
+ pc (always). On rte, pc is loaded from here. Bit 0, aka the D
+ bit, is a flag saying that the offending instruction was in a
+ branch delay slot. If set, then cr05 contains the NPC.
+
+ * cr05 = enip. On exception, if the instruction pointed to by cr04
+ was in a delay slot as indicated by the bit 0 of cr04, aka the D
+ bit, the cr05 contains the NPC. Otherwise ignored.
+
+ * cr06 is invalid */
+
+/* Note that the Harris Unix kernels emulate the m88100's behavior on
+ the m88110. */
+
+#define SXIP_REGNUM 35 /* On m88100, Contains Shadow Execute
+ Instruction Pointer. */
+#define SNIP_REGNUM 36 /* On m88100, Contains Shadow Next
+ Instruction Pointer. */
+#define SFIP_REGNUM 37 /* On m88100, Contains Shadow Fetched
+ Intruction pointer. */
+
+#define EXIP_REGNUM 35 /* On m88110, Contains Exception
+ Executing Instruction Pointer. */
+#define ENIP_REGNUM 36 /* On m88110, Contains the Exception
+ Next Instruction Pointer. */
+
+#define PC_REGNUM SXIP_REGNUM /* Program Counter */
+#define NPC_REGNUM SNIP_REGNUM /* Next Program Counter */
+#define M88K_NNPC_REGNUM SFIP_REGNUM /* Next Next Program Counter */
+
+
+#define PSR_REGNUM 32 /* Processor Status Register */
+#define FPSR_REGNUM 33 /* Floating Point Status Register */
+#define FPCR_REGNUM 34 /* Floating Point Control Register */
+#define XFP_REGNUM 38 /* First Extended Float Register */
+#define X0_REGNUM XFP_REGNUM /* Which also contains the constant zero */
+
+/* This is rather a confusing lie. Our m88k port using a stack pointer value
+ for the frame address. Hence, the frame address and the frame pointer are
+ only indirectly related. The value of this macro is the register number
+ fetched by the machine "independent" portions of gdb when they want to know
+ about a frame address. Thus, we lie here and claim that FP_REGNUM is
+ SP_REGNUM. */
+#define FP_REGNUM SP_REGNUM /* Reg fetched to locate frame when pgm stops */
+#define ACTUAL_FP_REGNUM 30
+
+/* PSR status bit definitions. */
+
+#define PSR_MODE 0x80000000
+#define PSR_BYTE_ORDER 0x40000000
+#define PSR_SERIAL_MODE 0x20000000
+#define PSR_CARRY 0x10000000
+#define PSR_SFU_DISABLE 0x000003f0
+#define PSR_SFU1_DISABLE 0x00000008
+#define PSR_MXM 0x00000004
+#define PSR_IND 0x00000002
+#define PSR_SFRZ 0x00000001
+
+
+
+/* The following two comments come from the days prior to the m88110
+ port. The m88110 handles the instruction pointers differently. I
+ do not know what any m88110 kernels do as the m88110 port I'm
+ working with is for an embedded system. rich@cygnus.com
+ 13-sept-93. */
+
+/* BCS requires that the SXIP_REGNUM (or PC_REGNUM) contain the
+ address of the next instr to be executed when a breakpoint occurs.
+ Because the kernel gets the next instr (SNIP_REGNUM), the instr in
+ SNIP needs to be put back into SFIP, and the instr in SXIP should
+ be shifted to SNIP */
+
+/* Are you sitting down? It turns out that the 88K BCS (binary
+ compatibility standard) folks originally felt that the debugger
+ should be responsible for backing up the IPs, not the kernel (as is
+ usually done). Well, they have reversed their decision, and in
+ future releases our kernel will be handling the backing up of the
+ IPs. So, eventually, we won't need to do the SHIFT_INST_REGS
+ stuff. But, for now, since there are 88K systems out there that do
+ need the debugger to do the IP shifting, and since there will be
+ systems where the kernel does the shifting, the code is a little
+ more complex than perhaps it needs to be (we still go inside
+ SHIFT_INST_REGS, and if the shifting hasn't occurred then gdb goes
+ ahead and shifts). */
+
+extern int target_is_m88110;
+#define SHIFT_INST_REGS() \
+if (!target_is_m88110) \
+{ \
+ CORE_ADDR pc = read_register (PC_REGNUM); \
+ CORE_ADDR npc = read_register (NPC_REGNUM); \
+ if (pc != npc) \
+ { \
+ write_register (M88K_NNPC_REGNUM, npc); \
+ write_register (NPC_REGNUM, pc); \
+ } \
+}
+
+ /* Storing the following registers is a no-op. */
+#define CANNOT_STORE_REGISTER(regno) (((regno) == R0_REGNUM) \
+ || ((regno) == X0_REGNUM))
+
+ /* Number of bytes of storage in the actual machine representation
+ for register N. On the m88k, the general purpose registers are 4
+ bytes and the 88110 extended registers are 10 bytes. */
+
+#define REGISTER_RAW_SIZE(N) ((N) < XFP_REGNUM ? 4 : 10)
+
+ /* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'. */
+
+#define REGISTER_BYTES ((GP_REGS * REGISTER_RAW_SIZE(0)) \
+ + (FP_REGS * REGISTER_RAW_SIZE(XFP_REGNUM)))
+
+ /* Index within `registers' of the first byte of the space for
+ register N. */
+
+#define REGISTER_BYTE(N) (((N) * REGISTER_RAW_SIZE(0)) \
+ + ((N) >= XFP_REGNUM \
+ ? (((N) - XFP_REGNUM) \
+ * REGISTER_RAW_SIZE(XFP_REGNUM)) \
+ : 0))
+
+ /* Number of bytes of storage in the program's representation for
+ register N. On the m88k, all registers are 4 bytes excepting the
+ m88110 extended registers which are 8 byte doubles. */
+
+#define REGISTER_VIRTUAL_SIZE(N) ((N) < XFP_REGNUM ? 4 : 8)
+
+ /* Largest value REGISTER_RAW_SIZE can have. */
+
+#define MAX_REGISTER_RAW_SIZE (REGISTER_RAW_SIZE(XFP_REGNUM))
+
+ /* Largest value REGISTER_VIRTUAL_SIZE can have.
+ Are FPS1, FPS2, FPR "virtual" regisers? */
+
+#define MAX_REGISTER_VIRTUAL_SIZE (REGISTER_RAW_SIZE(XFP_REGNUM))
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+struct type *m88k_register_type (int regnum);
+#define REGISTER_VIRTUAL_TYPE(N) m88k_register_type (N)
+
+/* The 88k call/return conventions call for "small" values to be returned
+ into consecutive registers starting from r2. */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ memcpy ((VALBUF), &(((char *)REGBUF)[REGISTER_BYTE(RV_REGNUM)]), TYPE_LENGTH (TYPE))
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format. */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ write_register_bytes (2*REGISTER_RAW_SIZE(0), (VALBUF), TYPE_LENGTH (TYPE))
+
+/* In COFF, if PCC says a parameter is a short or a char, do not
+ change it to int (it seems the convention is to change it). */
+
+#define BELIEVE_PCC_PROMOTION 1
+
+/* Describe the pointer in each stack frame to the previous stack frame
+ (its caller). */
+
+/* FRAME_CHAIN takes a frame's nominal address
+ and produces the frame's chain-pointer.
+
+ However, if FRAME_CHAIN_VALID returns zero,
+ it means the given frame is the outermost one and has no caller. */
+
+extern CORE_ADDR frame_chain ();
+extern int frame_chain_valid ();
+extern int frameless_function_invocation ();
+
+#define FRAME_CHAIN(thisframe) \
+ frame_chain (thisframe)
+
+#define FRAMELESS_FUNCTION_INVOCATION(frame) \
+ (frameless_function_invocation (frame))
+
+/* Define other aspects of the stack frame. */
+
+#define FRAME_SAVED_PC(FRAME) \
+ frame_saved_pc (FRAME)
+extern CORE_ADDR frame_saved_pc ();
+
+#define FRAME_ARGS_ADDRESS(fi) \
+ frame_args_address (fi)
+extern CORE_ADDR frame_args_address ();
+
+#define FRAME_LOCALS_ADDRESS(fi) \
+ frame_locals_address (fi)
+extern CORE_ADDR frame_locals_address ();
+
+/* Return number of args passed to a frame.
+ Can return -1, meaning no way to tell. */
+
+#define FRAME_NUM_ARGS(fi) (-1)
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame. */
+
+/* On the 88k, parameter registers get stored into the so called "homing"
+ area. This *always* happens when you compiled with GCC and use -g.
+ Also, (with GCC and -g) the saving of the parameter register values
+ always happens right within the function prologue code, so these register
+ values can generally be relied upon to be already copied into their
+ respective homing slots by the time you will normally try to look at
+ them (we hope).
+
+ Note that homing area stack slots are always at *positive* offsets from
+ the frame pointer. Thus, the homing area stack slots for the parameter
+ registers (passed values) for a given function are actually part of the
+ frame area of the caller. This is unusual, but it should not present
+ any special problems for GDB.
+
+ Note also that on the 88k, we are only interested in finding the
+ registers that might have been saved in memory. This is a subset of
+ the whole set of registers because the standard calling sequence allows
+ the called routine to clobber many registers.
+
+ We could manage to locate values for all of the so called "preserved"
+ registers (some of which may get saved within any particular frame) but
+ that would require decoding all of the tdesc information. That would be
+ nice information for GDB to have, but it is not strictly manditory if we
+ can live without the ability to look at values within (or backup to)
+ previous frames.
+ */
+
+struct frame_saved_regs;
+struct frame_info;
+
+void frame_find_saved_regs (struct frame_info *fi,
+ struct frame_saved_regs *fsr);
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+ frame_find_saved_regs (frame_info, &frame_saved_regs)
+
+
+#define POP_FRAME pop_frame ()
+extern void pop_frame ();
+
+/* Call function stuff contributed by Kevin Buettner of Motorola. */
+
+#define CALL_DUMMY_LOCATION AFTER_TEXT_END
+
+extern void m88k_push_dummy_frame ();
+#define PUSH_DUMMY_FRAME m88k_push_dummy_frame()
+
+#define CALL_DUMMY { \
+0x67ff00c0, /* 0: subu #sp,#sp,0xc0 */ \
+0x243f0004, /* 4: st #r1,#sp,0x4 */ \
+0x245f0008, /* 8: st #r2,#sp,0x8 */ \
+0x247f000c, /* c: st #r3,#sp,0xc */ \
+0x249f0010, /* 10: st #r4,#sp,0x10 */ \
+0x24bf0014, /* 14: st #r5,#sp,0x14 */ \
+0x24df0018, /* 18: st #r6,#sp,0x18 */ \
+0x24ff001c, /* 1c: st #r7,#sp,0x1c */ \
+0x251f0020, /* 20: st #r8,#sp,0x20 */ \
+0x253f0024, /* 24: st #r9,#sp,0x24 */ \
+0x255f0028, /* 28: st #r10,#sp,0x28 */ \
+0x257f002c, /* 2c: st #r11,#sp,0x2c */ \
+0x259f0030, /* 30: st #r12,#sp,0x30 */ \
+0x25bf0034, /* 34: st #r13,#sp,0x34 */ \
+0x25df0038, /* 38: st #r14,#sp,0x38 */ \
+0x25ff003c, /* 3c: st #r15,#sp,0x3c */ \
+0x261f0040, /* 40: st #r16,#sp,0x40 */ \
+0x263f0044, /* 44: st #r17,#sp,0x44 */ \
+0x265f0048, /* 48: st #r18,#sp,0x48 */ \
+0x267f004c, /* 4c: st #r19,#sp,0x4c */ \
+0x269f0050, /* 50: st #r20,#sp,0x50 */ \
+0x26bf0054, /* 54: st #r21,#sp,0x54 */ \
+0x26df0058, /* 58: st #r22,#sp,0x58 */ \
+0x26ff005c, /* 5c: st #r23,#sp,0x5c */ \
+0x271f0060, /* 60: st #r24,#sp,0x60 */ \
+0x273f0064, /* 64: st #r25,#sp,0x64 */ \
+0x275f0068, /* 68: st #r26,#sp,0x68 */ \
+0x277f006c, /* 6c: st #r27,#sp,0x6c */ \
+0x279f0070, /* 70: st #r28,#sp,0x70 */ \
+0x27bf0074, /* 74: st #r29,#sp,0x74 */ \
+0x27df0078, /* 78: st #r30,#sp,0x78 */ \
+0x63df0000, /* 7c: addu #r30,#sp,0x0 */ \
+0x145f0000, /* 80: ld #r2,#sp,0x0 */ \
+0x147f0004, /* 84: ld #r3,#sp,0x4 */ \
+0x149f0008, /* 88: ld #r4,#sp,0x8 */ \
+0x14bf000c, /* 8c: ld #r5,#sp,0xc */ \
+0x14df0010, /* 90: ld #r6,#sp,0x10 */ \
+0x14ff0014, /* 94: ld #r7,#sp,0x14 */ \
+0x151f0018, /* 98: ld #r8,#sp,0x18 */ \
+0x153f001c, /* 9c: ld #r9,#sp,0x1c */ \
+0x5c200000, /* a0: or.u #r1,#r0,0x0 */ \
+0x58210000, /* a4: or #r1,#r1,0x0 */ \
+0xf400c801, /* a8: jsr #r1 */ \
+0xf000d1ff /* ac: tb0 0x0,#r0,0x1ff */ \
+}
+
+#define CALL_DUMMY_START_OFFSET 0x80
+#define CALL_DUMMY_LENGTH 0xb0
+
+/* FIXME: byteswapping. */
+#define FIX_CALL_DUMMY(dummy, pc, fun, nargs, args, type, gcc_p) \
+{ \
+ *(unsigned long *)((char *) (dummy) + 0xa0) |= \
+ (((unsigned long) (fun)) >> 16); \
+ *(unsigned long *)((char *) (dummy) + 0xa4) |= \
+ (((unsigned long) (fun)) & 0xffff); \
+}
+
+/* Stack must be aligned on 64-bit boundaries when synthesizing
+ function calls. */
+
+#define STACK_ALIGN(addr) (((addr) + 7) & -8)
+
+#define STORE_STRUCT_RETURN(addr, sp) \
+ write_register (SRA_REGNUM, (addr))
+
+#define NEED_TEXT_START_END 1
+
+/* According to the MC88100 RISC Microprocessor User's Manual, section
+ 6.4.3.1.2:
+
+ ... can be made to return to a particular instruction by placing a
+ valid instruction address in the SNIP and the next sequential
+ instruction address in the SFIP (with V bits set and E bits clear).
+ The rte resumes execution at the instruction pointed to by the
+ SNIP, then the SFIP.
+
+ The E bit is the least significant bit (bit 0). The V (valid) bit is
+ bit 1. This is why we logical or 2 into the values we are writing
+ below. It turns out that SXIP plays no role when returning from an
+ exception so nothing special has to be done with it. We could even
+ (presumably) give it a totally bogus value.
+
+ -- Kevin Buettner
+ */
+
+extern void m88k_target_write_pc (CORE_ADDR pc, ptid_t ptid);
+#define TARGET_WRITE_PC(VAL, PID) m88k_target_write_pc (VAL, PID)
diff --git a/gdb/config/m88k/xm-delta88.h b/gdb/config/m88k/xm-delta88.h
new file mode 100644
index 00000000000..27c8fe28d22
--- /dev/null
+++ b/gdb/config/m88k/xm-delta88.h
@@ -0,0 +1,44 @@
+/* Host machine description for Motorola Delta 88 system, for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993
+ 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. */
+
+#if !defined (USG)
+#define USG 1
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+
+#define HAVE_TERMIO
+
+/*#define USIZE 2048 */
+/*#define NBPG NBPC */
+/* Might be defined in <sys/param.h>. I suspect this define was a relic
+ from before when BFD did core files. */
+/* #define UPAGES USIZE */
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+
+/* Since registers r0 through r31 are stored directly in the struct ptrace_user,
+ (for m88k BCS)
+ the ptrace_user offsets are sufficient and KERNEL_U_ADDRESS can be 0 */
+
+#define KERNEL_U_ADDR 0
diff --git a/gdb/config/m88k/xm-delta88v4.h b/gdb/config/m88k/xm-delta88v4.h
new file mode 100644
index 00000000000..b09a02dd335
--- /dev/null
+++ b/gdb/config/m88k/xm-delta88v4.h
@@ -0,0 +1,22 @@
+/* Host machine description for Motorola Delta 88 box, for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1993
+ 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 "xm-sysv4.h"
diff --git a/gdb/config/m88k/xm-dgux.h b/gdb/config/m88k/xm-dgux.h
new file mode 100644
index 00000000000..b6f7f996d75
--- /dev/null
+++ b/gdb/config/m88k/xm-dgux.h
@@ -0,0 +1,55 @@
+/* Host-machine dependent parameters for Motorola 88000, for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1993, 1998
+ 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. */
+
+#if !defined (USG)
+#define USG 1
+#endif
+
+#include <sys/param.h>
+
+#ifdef __GNUC__
+#define memcpy __builtin_memcpy
+/* gcc doesn't have this, at least not gcc 1.92. */
+/* #define memset __builtin_memset */
+#define strcmp __builtin_strcmp
+#endif
+
+#define x_foff _x_x._x_offset
+#define x_fname _x_name
+#define USER ptrace_user
+#define _BSD_WAIT_FLAVOR
+
+#define HAVE_TERMIO
+
+#ifndef USIZE
+#define USIZE 2048
+#endif
+#define NBPG NBPC
+#define UPAGES USIZE
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+
+/* Since registers r0 through r31 are stored directly in the struct ptrace_user,
+ (for m88k BCS)
+ the ptrace_user offsets are sufficient and KERNEL_U_ADDRESS can be 0 */
+
+#define KERNEL_U_ADDR 0
diff --git a/gdb/config/mcore/mcore.mt b/gdb/config/mcore/mcore.mt
new file mode 100644
index 00000000000..ed9a9231099
--- /dev/null
+++ b/gdb/config/mcore/mcore.mt
@@ -0,0 +1,5 @@
+# Target: Motorola MCore processor
+TDEPFILES= mcore-tdep.o mcore-rom.o monitor.o dsrec.o
+TM_FILE= tm-mcore.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/mcore/libsim.a
diff --git a/gdb/config/mcore/tm-mcore.h b/gdb/config/mcore/tm-mcore.h
new file mode 100644
index 00000000000..1da21b76e64
--- /dev/null
+++ b/gdb/config/mcore/tm-mcore.h
@@ -0,0 +1,161 @@
+/* Parameters for execution on a Motorola MCore.
+
+ Copyright 1995, 1999, 2000, 2002 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 "regcache.h"
+#include "symtab.h" /* For namespace_enum. */
+#include "symfile.h" /* For entry_point_address(). */
+
+/* All registers are 32 bits */
+#define REGISTER_SIZE 4
+#define MAX_REGISTER_RAW_SIZE 4
+
+#define REGISTER_VIRTUAL_TYPE(REG) builtin_type_int
+
+#define REGISTER_BYTE(REG) ((REG) * REGISTER_SIZE)
+#define REGISTER_VIRTUAL_SIZE(REG) 4
+#define REGISTER_RAW_SIZE(REG) 4
+
+#define MAX_REGISTER_VIRTUAL_SIZE 4
+
+#define REGISTER_BYTES (NUM_REGS * REGISTER_SIZE)
+
+extern char *mcore_register_names[];
+#define REGISTER_NAME(I) mcore_register_names[I]
+
+/* Registers. The Motorola MCore contains:
+
+ 16 32-bit general purpose registers (r0-r15)
+ 16 32-bit alternate file registers (ar0-ar15)
+ 32 32-bit control registers (cr0-cr31)
+ + 1 pc
+ ------
+ 65 registers */
+#define NUM_REGS 65
+#define PC_REGNUM 64
+#define SP_REGNUM 0
+#define FP_REGNUM (SP_REGNUM)
+#define PR_REGNUM 15
+#define FIRST_ARGREG 2
+#define LAST_ARGREG 7
+#define RETVAL_REGNUM 2
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+#define FUNCTION_START_OFFSET 0
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* BREAKPOINT_FROM_PC uses the program counter value to determine
+ the breakpoint that should be used. */
+extern const unsigned char *mcore_breakpoint_from_pc (CORE_ADDR *pcptr,
+ int *lenptr);
+#define BREAKPOINT_FROM_PC(PCPTR, LENPTR) mcore_breakpoint_from_pc (PCPTR, LENPTR)
+
+#define INNER_THAN(LHS,RHS) ((LHS) < (RHS))
+
+#define SAVED_PC_AFTER_CALL(FRAME) read_register (PR_REGNUM)
+
+struct frame_info;
+struct type;
+struct value;
+
+extern void mcore_init_extra_frame_info (struct frame_info *fi);
+#define INIT_EXTRA_FRAME_INFO(FROMLEAF, FI) mcore_init_extra_frame_info ((FI))
+#define INIT_FRAME_PC /* Not necessary */
+#define FRAME_INIT_SAVED_REGS(FI) /* handled by init_extra_frame_info */
+
+extern CORE_ADDR mcore_frame_chain (struct frame_info *fi);
+#define FRAME_CHAIN(FI) mcore_frame_chain ((FI))
+#define FRAME_CHAIN_VALID(FP, FI) generic_file_frame_chain_valid ((FP), (FI))
+
+extern CORE_ADDR mcore_frame_saved_pc (struct frame_info *);
+#define FRAME_SAVED_PC(FI) (mcore_frame_saved_pc ((FI)))
+
+/* Extracting/storing return values. */
+extern void mcore_store_return_value (struct type *type, char *valbuf);
+#define STORE_RETURN_VALUE(TYPE, VALBUF) mcore_store_return_value ((TYPE), (VALBUF))
+
+extern void mcore_extract_return_value (struct type *type, char *regbut, char *valbuf);
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ mcore_extract_return_value ((TYPE), (REGBUF), (VALBUF));
+
+#define STORE_STRUCT_RETURN(ADDR, SP) /* handled by mcore_push_arguments */
+
+extern CORE_ADDR mcore_extract_struct_value_address (char *regbuf);
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+ mcore_extract_struct_value_address (REGBUF)
+
+extern CORE_ADDR mcore_skip_prologue (CORE_ADDR pc);
+#define SKIP_PROLOGUE(PC) mcore_skip_prologue (PC)
+
+#define FRAME_ARGS_SKIP 0
+extern CORE_ADDR mcore_frame_args_address (struct frame_info *fi);
+#define FRAME_ARGS_ADDRESS(FI) mcore_frame_args_address ((FI))
+extern CORE_ADDR mcore_frame_locals_address (struct frame_info *fi);
+#define FRAME_LOCALS_ADDRESS(FI) mcore_frame_locals_address ((FI))
+#define FRAME_NUM_ARGS(FI) (-1)
+
+
+extern void mcore_pop_frame (struct frame_info *fi);
+#define POP_FRAME mcore_pop_frame (get_current_frame ())
+
+#define USE_GENERIC_DUMMY_FRAMES 1
+#define CALL_DUMMY {0}
+#define CALL_DUMMY_START_OFFSET (0)
+#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
+#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
+#define FIX_CALL_DUMMY(DUMMY, START, FUNADDR, NARGS, ARGS, TYPE, GCCP)
+#define CALL_DUMMY_ADDRESS() entry_point_address ()
+#define SIZEOF_CALL_DUMMY_WORDS 0
+#define SAVE_DUMMY_FRAME_TOS(SP) generic_save_dummy_frame_tos (SP)
+
+extern CORE_ADDR mcore_push_return_address (CORE_ADDR, CORE_ADDR);
+#define PUSH_RETURN_ADDRESS(PC, SP) mcore_push_return_address (PC, SP)
+
+#define PUSH_DUMMY_FRAME generic_push_dummy_frame ()
+
+extern CORE_ADDR mcore_push_arguments (int, struct value **, CORE_ADDR,
+ unsigned char, CORE_ADDR);
+#define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \
+ (SP) = mcore_push_arguments (NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR)
+
+#define PC_IN_CALL_DUMMY(PC, SP, FP) generic_pc_in_call_dummy (PC, SP, FP)
+
+/* MCore will never pass a sturcture by reference. It will always be split
+ between registers and stack. */
+#define REG_STRUCT_HAS_ADDR(GCC_P, TYPE) 0
+
+extern use_struct_convention_fn mcore_use_struct_convention;
+#define USE_STRUCT_CONVENTION(GCC_P, TYPE) mcore_use_struct_convention (GCC_P, TYPE)
+
+/* override the default get_saved_register function with
+ one that takes account of generic CALL_DUMMY frames */
+#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \
+ generic_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
+
+/* Cons up virtual frame pointer for trace */
+extern void mcore_virtual_frame_pointer (CORE_ADDR, int *, LONGEST *);
+#define TARGET_VIRTUAL_FRAME_POINTER(PC, REGP, OFFP) \
+ mcore_virtual_frame_pointer ((PC), (REGP), (OFFP))
+
+/* For PE, gcc will tell us what th real type of
+ arguments are when it promotes arguments. */
+#define BELIEVE_PCC_PROMOTION 1
diff --git a/gdb/config/mips/bigmips.mt b/gdb/config/mips/bigmips.mt
new file mode 100644
index 00000000000..38f03f2f8e4
--- /dev/null
+++ b/gdb/config/mips/bigmips.mt
@@ -0,0 +1,3 @@
+# Target: Big-endian MIPS machine such as Sony News
+TDEPFILES= mips-tdep.o
+TM_FILE= tm-bigmips.h
diff --git a/gdb/config/mips/bigmips64.mt b/gdb/config/mips/bigmips64.mt
new file mode 100644
index 00000000000..fcb7b21dae5
--- /dev/null
+++ b/gdb/config/mips/bigmips64.mt
@@ -0,0 +1,3 @@
+# Target: Big-endian MIPS machine such as Sony News
+TDEPFILES= mips-tdep.o
+TM_FILE= tm-bigmips64.h
diff --git a/gdb/config/mips/decstation.mh b/gdb/config/mips/decstation.mh
new file mode 100644
index 00000000000..89ce310b6fa
--- /dev/null
+++ b/gdb/config/mips/decstation.mh
@@ -0,0 +1,4 @@
+# Host: Little-endian MIPS machine such as DECstation.
+XM_FILE= xm-mips.h
+NAT_FILE= nm-mips.h
+NATDEPFILES= infptrace.o inftarg.o corelow.o mips-nat.o fork-child.o
diff --git a/gdb/config/mips/decstation.mt b/gdb/config/mips/decstation.mt
new file mode 100644
index 00000000000..19847224d2f
--- /dev/null
+++ b/gdb/config/mips/decstation.mt
@@ -0,0 +1,3 @@
+# Target: Little-endian MIPS machine such as DECstation.
+TDEPFILES= mips-tdep.o
+TM_FILE= tm-mips.h
diff --git a/gdb/config/mips/embed.mt b/gdb/config/mips/embed.mt
new file mode 100644
index 00000000000..42ab4aa47b9
--- /dev/null
+++ b/gdb/config/mips/embed.mt
@@ -0,0 +1,5 @@
+# Target: Big-endian mips board, typically an IDT.
+TDEPFILES= mips-tdep.o remote-mips.o remote-array.o
+TM_FILE= tm-embed.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/embed64.mt b/gdb/config/mips/embed64.mt
new file mode 100644
index 00000000000..ed60fd25031
--- /dev/null
+++ b/gdb/config/mips/embed64.mt
@@ -0,0 +1,5 @@
+# Target: Big-endian mips board, typically an IDT.
+TDEPFILES= mips-tdep.o remote-mips.o remote-array.o
+TM_FILE= tm-embed64.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/embedl.mt b/gdb/config/mips/embedl.mt
new file mode 100644
index 00000000000..0ed8b8d5021
--- /dev/null
+++ b/gdb/config/mips/embedl.mt
@@ -0,0 +1,5 @@
+# Target: Big-endian mips board, typically an IDT.
+TDEPFILES= mips-tdep.o remote-mips.o remote-array.o
+TM_FILE= tm-embedl.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/embedl64.mt b/gdb/config/mips/embedl64.mt
new file mode 100644
index 00000000000..28c41be48fb
--- /dev/null
+++ b/gdb/config/mips/embedl64.mt
@@ -0,0 +1,5 @@
+# Target: Big-endian mips board, typically an IDT.
+TDEPFILES= mips-tdep.o remote-mips.o remote-array.o
+TM_FILE= tm-embedl64.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/irix3.mh b/gdb/config/mips/irix3.mh
new file mode 100644
index 00000000000..fcb30ed3dcb
--- /dev/null
+++ b/gdb/config/mips/irix3.mh
@@ -0,0 +1,5 @@
+# Host: SGI Iris running irix 3.x
+XM_FILE= xm-irix3.h
+NAT_FILE= nm-irix3.h
+NATDEPFILES= fork-child.o corelow.o infptrace.o inftarg.o mips-nat.o
+XM_CLIBS=-lbsd
diff --git a/gdb/config/mips/irix3.mt b/gdb/config/mips/irix3.mt
new file mode 100644
index 00000000000..b3fa4dda384
--- /dev/null
+++ b/gdb/config/mips/irix3.mt
@@ -0,0 +1,3 @@
+# Target: MIPS SGI running Irix 3
+TDEPFILES= mips-tdep.o
+TM_FILE= tm-irix3.h
diff --git a/gdb/config/mips/irix4.mh b/gdb/config/mips/irix4.mh
new file mode 100644
index 00000000000..4153a0ec2ac
--- /dev/null
+++ b/gdb/config/mips/irix4.mh
@@ -0,0 +1,10 @@
+# Host: SGI Iris running irix 4.x
+XM_FILE= xm-irix4.h
+NAT_FILE= nm-irix4.h
+NATDEPFILES= fork-child.o irix4-nat.o corelow.o procfs.o \
+ proc-api.o proc-events.o proc-flags.o proc-why.o
+
+
+XM_CLIBS=-lbsd -lsun
+# use cc in K&R mode, bump up some static compiler tables.
+CC = cc -cckr -Wf,-XNg1500 -Wf,-XNk1000 -Wf,-XNh1100
diff --git a/gdb/config/mips/irix5.mh b/gdb/config/mips/irix5.mh
new file mode 100644
index 00000000000..12690b0bc8b
--- /dev/null
+++ b/gdb/config/mips/irix5.mh
@@ -0,0 +1,7 @@
+# Host: SGI Iris running irix 5.x
+XM_FILE= xm-irix5.h
+NAT_FILE= nm-irix5.h
+NATDEPFILES= fork-child.o irix5-nat.o corelow.o procfs.o \
+ proc-api.o proc-events.o proc-flags.o proc-why.o
+
+XM_CLIBS=-lbsd -lsun
diff --git a/gdb/config/mips/irix5.mt b/gdb/config/mips/irix5.mt
new file mode 100644
index 00000000000..5b17bcdf1dd
--- /dev/null
+++ b/gdb/config/mips/irix5.mt
@@ -0,0 +1,3 @@
+# Target: MIPS SGI running Irix 5
+TDEPFILES= mips-tdep.o
+TM_FILE= tm-irix5.h
diff --git a/gdb/config/mips/irix6.mh b/gdb/config/mips/irix6.mh
new file mode 100644
index 00000000000..99b47374906
--- /dev/null
+++ b/gdb/config/mips/irix6.mh
@@ -0,0 +1,7 @@
+# Host: SGI Iris running irix 6.x
+XM_FILE= xm-irix6.h
+NAT_FILE= nm-irix6.h
+NATDEPFILES= fork-child.o solib.o irix5-nat.o corelow.o procfs.o \
+ proc-api.o proc-events.o proc-flags.o proc-why.o
+
+XM_CLIBS=-lbsd
diff --git a/gdb/config/mips/irix6.mt b/gdb/config/mips/irix6.mt
new file mode 100644
index 00000000000..c5c5ccea8aa
--- /dev/null
+++ b/gdb/config/mips/irix6.mt
@@ -0,0 +1,3 @@
+# Target: MIPS SGI running Irix 6.x
+TDEPFILES= mips-tdep.o
+TM_FILE= tm-irix6.h
diff --git a/gdb/config/mips/linux.mh b/gdb/config/mips/linux.mh
new file mode 100644
index 00000000000..991fd6c0dee
--- /dev/null
+++ b/gdb/config/mips/linux.mh
@@ -0,0 +1,7 @@
+# Host: Linux/MIPS
+XM_FILE= xm-linux.h
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o mips-linux-nat.o \
+ thread-db.o lin-lwp.o proc-service.o linux-proc.o gcore.o
+
+LOADLIBES = -ldl -rdynamic
diff --git a/gdb/config/mips/linux.mt b/gdb/config/mips/linux.mt
new file mode 100644
index 00000000000..60bbfb25212
--- /dev/null
+++ b/gdb/config/mips/linux.mt
@@ -0,0 +1,9 @@
+# Target: Linux/MIPS
+TDEPFILES= mips-tdep.o mips-linux-tdep.o corelow.o \
+ solib.o solib-svr4.o
+TM_FILE= tm-linux.h
+
+GDBSERVER_DEPFILES = linux-low.o linux-mips-low.o reg-mips.o
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/littlemips.mh b/gdb/config/mips/littlemips.mh
new file mode 100644
index 00000000000..581a9084e3f
--- /dev/null
+++ b/gdb/config/mips/littlemips.mh
@@ -0,0 +1,3 @@
+# Host: Little-endian MIPS machine such as DECstation.
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o core-aout.o
+XM_FILE= xm-mips.h
diff --git a/gdb/config/mips/littlemips.mt b/gdb/config/mips/littlemips.mt
new file mode 100644
index 00000000000..19847224d2f
--- /dev/null
+++ b/gdb/config/mips/littlemips.mt
@@ -0,0 +1,3 @@
+# Target: Little-endian MIPS machine such as DECstation.
+TDEPFILES= mips-tdep.o
+TM_FILE= tm-mips.h
diff --git a/gdb/config/mips/mipsm3.mh b/gdb/config/mips/mipsm3.mh
new file mode 100644
index 00000000000..864ad57e24d
--- /dev/null
+++ b/gdb/config/mips/mipsm3.mh
@@ -0,0 +1,6 @@
+# Host: Little endian MIPS machine such as pmax
+# running Mach 3.0 operating system
+
+NATDEPFILES= mipsm3-nat.o m3-nat.o core-aout.o
+XM_FILE= xm-mipsm3.h
+NAT_FILE= ../nm-m3.h
diff --git a/gdb/config/mips/mipsm3.mt b/gdb/config/mips/mipsm3.mt
new file mode 100644
index 00000000000..66856d16c04
--- /dev/null
+++ b/gdb/config/mips/mipsm3.mt
@@ -0,0 +1,4 @@
+# Target: Little-endian MIPS machine such as pmax
+# running Mach 3.0 operating system
+TDEPFILES= mips-tdep.o
+TM_FILE= tm-mipsm3.h
diff --git a/gdb/config/mips/mipsv4.mh b/gdb/config/mips/mipsv4.mh
new file mode 100644
index 00000000000..1a6104b3f94
--- /dev/null
+++ b/gdb/config/mips/mipsv4.mh
@@ -0,0 +1,6 @@
+# Host: Mips running SVR4
+XM_FILE= xm-mipsv4.h
+NAT_FILE= ../nm-sysv4.h
+NATDEPFILES= fork-child.o mipsv4-nat.o corelow.o core-regset.o \
+ solib.o solib-svr4.o solib-legacy.o \
+ procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o
diff --git a/gdb/config/mips/mipsv4.mt b/gdb/config/mips/mipsv4.mt
new file mode 100644
index 00000000000..6d3b47d024a
--- /dev/null
+++ b/gdb/config/mips/mipsv4.mt
@@ -0,0 +1,3 @@
+# Target: MIPS running SVR4
+TDEPFILES= mips-tdep.o
+TM_FILE= tm-mipsv4.h
diff --git a/gdb/config/mips/nbsd.mh b/gdb/config/mips/nbsd.mh
new file mode 100644
index 00000000000..4556fc60b27
--- /dev/null
+++ b/gdb/config/mips/nbsd.mh
@@ -0,0 +1,4 @@
+# Host: MIPS running NetBSD
+NAT_CLIBS=
+NATDEPFILES= infptrace.o inftarg.o fork-child.o mipsnbsd-nat.o
+NAT_FILE= nm-nbsd.h
diff --git a/gdb/config/mips/nbsd.mt b/gdb/config/mips/nbsd.mt
new file mode 100644
index 00000000000..de529166c56
--- /dev/null
+++ b/gdb/config/mips/nbsd.mt
@@ -0,0 +1,6 @@
+# Target: MIPS running NetBSD
+TDEPFILES= mips-tdep.o mipsnbsd-tdep.o corelow.o solib.o solib-svr4.o
+TM_FILE= tm-nbsd.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/news-mips.mh b/gdb/config/mips/news-mips.mh
new file mode 100644
index 00000000000..5cc138f38e4
--- /dev/null
+++ b/gdb/config/mips/news-mips.mh
@@ -0,0 +1,3 @@
+# Host: Big-endian MIPS machine such as Sony News
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o mips-nat.o
+NAT_FILE= nm-news-mips.h
diff --git a/gdb/config/mips/nm-irix3.h b/gdb/config/mips/nm-irix3.h
new file mode 100644
index 00000000000..5cd2da35b6e
--- /dev/null
+++ b/gdb/config/mips/nm-irix3.h
@@ -0,0 +1,38 @@
+/* Definitions for SGI irix3 native support.
+ Copyright 1991, 1992, 1993, 1996, 2000 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. */
+
+/* Don't need special routines for Irix v3 -- we can use infptrace.c */
+#undef FETCH_INFERIOR_REGISTERS
+
+#define U_REGS_OFFSET 0
+
+/* Figure out where the longjmp will land. We expect that we have just entered
+ longjmp and haven't yet setup the stack frame, so the args are still in the
+ argument regs. a0 (CALL_ARG0) points at the jmp_buf structure from which we
+ extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+extern int get_longjmp_target (CORE_ADDR *);
+
+/* Is this really true or is this just a leftover from a DECstation
+ config file? */
+
+#define ONE_PROCESS_WRITETEXT
diff --git a/gdb/config/mips/nm-irix4.h b/gdb/config/mips/nm-irix4.h
new file mode 100644
index 00000000000..9c02eb3573b
--- /dev/null
+++ b/gdb/config/mips/nm-irix4.h
@@ -0,0 +1,67 @@
+/* Definitions for native support of irix4.
+
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000
+ 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. */
+
+/*
+ * Let's use /debug instead of all this dangerous mucking about
+ * with ptrace(), which seems *extremely* fragile, anyway.
+ */
+#define USE_PROC_FS
+#define CTL_PROC_NAME_FMT "/debug/%d"
+#define AS_PROC_NAME_FMT "/debug/%d"
+#define MAP_PROC_NAME_FMT "/debug/%d"
+#define STATUS_PROC_NAME_FMT "/debug/%d"
+
+/* Don't need special routines for the SGI -- we can use infptrace.c */
+#undef FETCH_INFERIOR_REGISTERS
+
+#define U_REGS_OFFSET 0
+
+/* Is this really true or is this just a leftover from a DECstation
+ config file? */
+
+#define ONE_PROCESS_WRITETEXT
+
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+
+/* Temporary new watchpoint stuff */
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \
+ ((type) == bp_hardware_watchpoint)
+
+/* When a hardware watchpoint fires off the PC will be left at the
+ instruction which caused the watchpoint. It will be necessary for
+ GDB to step over the watchpoint. */
+
+#define STOPPED_BY_WATCHPOINT(W) \
+ procfs_stopped_by_watchpoint(inferior_ptid)
+extern int procfs_stopped_by_watchpoint (ptid_t);
+
+#define HAVE_NONSTEPPABLE_WATCHPOINT
+
+/* Use these macros for watchpoint insertion/deletion. */
+/* type can be 0: write watch, 1: read watch, 2: access watch (read/write) */
+#define target_insert_watchpoint(ADDR, LEN, TYPE) \
+ procfs_set_watchpoint (inferior_ptid, ADDR, LEN, TYPE, 0)
+#define target_remove_watchpoint(ADDR, LEN, TYPE) \
+ procfs_set_watchpoint (inferior_ptid, ADDR, 0, 0, 0)
+extern int procfs_set_watchpoint (ptid_t, CORE_ADDR, int, int, int);
+
+#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(SIZE) 1
diff --git a/gdb/config/mips/nm-irix5.h b/gdb/config/mips/nm-irix5.h
new file mode 100644
index 00000000000..bed3144530d
--- /dev/null
+++ b/gdb/config/mips/nm-irix5.h
@@ -0,0 +1,47 @@
+/* Definitions for native support of irix5.
+
+ Copyright 1993, 1996, 1998, 1999, 2000 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 "nm-sysv4.h"
+#undef IN_SOLIB_DYNSYM_RESOLVE_CODE
+
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1
+
+/* When a hardware watchpoint fires off the PC will be left at the
+ instruction which caused the watchpoint. It will be necessary for
+ GDB to step over the watchpoint. */
+
+#define STOPPED_BY_WATCHPOINT(W) \
+ procfs_stopped_by_watchpoint(inferior_ptid)
+extern int procfs_stopped_by_watchpoint (ptid_t);
+
+#define HAVE_NONSTEPPABLE_WATCHPOINT
+
+/* Use these macros for watchpoint insertion/deletion. */
+/* type can be 0: write watch, 1: read watch, 2: access watch (read/write) */
+#define target_insert_watchpoint(ADDR, LEN, TYPE) \
+ procfs_set_watchpoint (inferior_ptid, ADDR, LEN, TYPE, 0)
+#define target_remove_watchpoint(ADDR, LEN, TYPE) \
+ procfs_set_watchpoint (inferior_ptid, ADDR, 0, 0, 0)
+extern int procfs_set_watchpoint (ptid_t, CORE_ADDR, int, int, int);
+
+#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(SIZE) 1
diff --git a/gdb/config/mips/nm-irix6.h b/gdb/config/mips/nm-irix6.h
new file mode 100644
index 00000000000..301b62922db
--- /dev/null
+++ b/gdb/config/mips/nm-irix6.h
@@ -0,0 +1,22 @@
+/* Definitions for native support of irix6.
+
+ Copyright 2001 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 "mips/nm-irix5.h"
diff --git a/gdb/config/mips/nm-linux.h b/gdb/config/mips/nm-linux.h
new file mode 100644
index 00000000000..c43ecd68393
--- /dev/null
+++ b/gdb/config/mips/nm-linux.h
@@ -0,0 +1,51 @@
+/* Native-dependent definitions for GNU/Linux on MIPS.
+
+ Copyright 1996, 2001, 2002 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. */
+
+#ifndef NM_MIPSLINUX_H
+#define NM_MIPSLINUX_H
+
+#define MIPS_GNULINUX_TARGET
+
+#include "nm-linux.h"
+
+/* Return sizeof user struct to callers in less machine dependent
+ routines. Hard coded for cross-compilation friendliness. */
+
+#define KERNEL_U_SIZE 504
+
+/* ptrace register ``addresses'' are absolute. */
+
+#define U_REGS_OFFSET 0
+
+/* ptrace transfers longs, and expects addresses as longs. */
+
+#define PTRACE_ARG3_TYPE long
+#define PTRACE_XFER_TYPE long
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = mips_register_addr ((regno),(blockend))
+
+int mips_linux_cannot_fetch_register (int regno);
+int mips_linux_cannot_store_register (int regno);
+#define CANNOT_FETCH_REGISTER(regno) mips_linux_cannot_fetch_register (regno)
+#define CANNOT_STORE_REGISTER(regno) mips_linux_cannot_store_register (regno)
+
+#endif /* NM_MIPSLINUX_H */
diff --git a/gdb/config/mips/nm-mips.h b/gdb/config/mips/nm-mips.h
new file mode 100644
index 00000000000..7b61d83e6b9
--- /dev/null
+++ b/gdb/config/mips/nm-mips.h
@@ -0,0 +1,34 @@
+/* Native definitions for GDB on DECstations, Sony News. and MIPS Riscos systems
+ Copyright 1986, 1987, 1989, 1992, 1995, 1996, 2000
+ Free Software Foundation, Inc.
+ Contributed by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin
+ and by Alessandro Forin(af@cs.cmu.edu) at CMU
+
+ 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. */
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
+#define FETCH_INFERIOR_REGISTERS
+
+/* Figure out where the longjmp will land. We expect that we have just entered
+ longjmp and haven't yet setup the stack frame, so the args are still in the
+ argument regs. a0 (CALL_ARG0) points at the jmp_buf structure from which we
+ extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+extern int get_longjmp_target (CORE_ADDR *);
diff --git a/gdb/config/mips/nm-nbsd.h b/gdb/config/mips/nm-nbsd.h
new file mode 100644
index 00000000000..67628c2fa97
--- /dev/null
+++ b/gdb/config/mips/nm-nbsd.h
@@ -0,0 +1,28 @@
+/* Native-dependent definitions for NetBSD/mips.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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. */
+
+#ifndef NM_NBSD_H
+#define NM_NBSD_H
+
+/* Get generic NetBSD native definitions. */
+#include "config/nm-nbsd.h"
+
+#endif /* NM_NBSD_H */
diff --git a/gdb/config/mips/nm-news-mips.h b/gdb/config/mips/nm-news-mips.h
new file mode 100644
index 00000000000..9f80eb55709
--- /dev/null
+++ b/gdb/config/mips/nm-news-mips.h
@@ -0,0 +1,43 @@
+/* Definitions to make GDB run on a mips box under 4.3bsd.
+ Copyright 1986, 1987, 1989, 1993, 1996 Free Software Foundation, Inc.
+ Contributed by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin
+ and by Alessandro Forin(af@cs.cmu.edu) at CMU
+
+ 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. */
+
+#ifndef NM_NEWS_MIPS_H
+#define NM_NEWS_MIPS_H 1
+
+/* Needed for RISC NEWS core files. */
+#include <machine/machparam.h>
+#include <sys/types.h>
+#define KERNEL_U_ADDR UADDR
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ if (regno < 38) addr = (NBPG*UPAGES) + (regno - 38)*sizeof(int);\
+ else addr = 0; /* ..somewhere in the pcb */
+
+/* Kernel is a bit tenacious about sharing text segments, disallowing bpts. */
+#define ONE_PROCESS_WRITETEXT
+
+#include "mips/nm-mips.h"
+
+/* Apparently not in <sys/types.h> */
+typedef int pid_t;
+
+#endif /* NM_NEWS_MIPS_H */
diff --git a/gdb/config/mips/nm-riscos.h b/gdb/config/mips/nm-riscos.h
new file mode 100644
index 00000000000..7f68b677092
--- /dev/null
+++ b/gdb/config/mips/nm-riscos.h
@@ -0,0 +1,60 @@
+/* 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. */
+
+/* MIPS running RISC/os 4.52C. */
+
+#define PCB_OFFSET(FIELD) ((int)&((struct user*)0)->u_pcb.FIELD)
+
+/* RISC/os 5.0 defines this in machparam.h. */
+#include <bsd43/machine/machparam.h>
+#define NBPG BSD43_NBPG
+#define UPAGES BSD43_UPAGES
+
+/* Where is this used? I don't see any uses in mips-nat.c, and I don't think
+ the uses in infptrace.c are used if FETCH_INFERIOR_REGISTERS is defined.
+ Does the compiler react badly to "extern CORE_ADDR kernel_u_addr" (even
+ if never referenced)? */
+#define KERNEL_U_ADDR BSD43_UADDR
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ if (regno < FP0_REGNUM) \
+ addr = UPAGES*NBPG-EF_SIZE+4*((regno)+EF_AT-1); \
+ else if (regno < PC_REGNUM) \
+ addr = PCB_OFFSET(pcb_fpregs[0]) + 4*(regno-FP0_REGNUM); \
+ else if (regno == PS_REGNUM) \
+ addr = UPAGES*NBPG-EF_SIZE+4*EF_SR; \
+ else if (regno == BADVADDR_REGNUM) \
+ addr = UPAGES*NBPG-EF_SIZE+4*EF_BADVADDR; \
+ else if (regno == LO_REGNUM) \
+ addr = UPAGES*NBPG-EF_SIZE+4*EF_MDLO; \
+ else if (regno == HI_REGNUM) \
+ addr = UPAGES*NBPG-EF_SIZE+4*EF_MDHI; \
+ else if (regno == CAUSE_REGNUM) \
+ addr = UPAGES*NBPG-EF_SIZE+4*EF_CAUSE; \
+ else if (regno == PC_REGNUM) \
+ addr = UPAGES*NBPG-EF_SIZE+4*EF_EPC; \
+ else if (regno < FCRCS_REGNUM) \
+ addr = PCB_OFFSET(pcb_fpregs[0]) + 4*(regno-FP0_REGNUM); \
+ else if (regno == FCRCS_REGNUM) \
+ addr = PCB_OFFSET(pcb_fpc_csr); \
+ else if (regno == FCRIR_REGNUM) \
+ addr = PCB_OFFSET(pcb_fpc_eir); \
+ else \
+ addr = 0;
+
+#include "mips/nm-mips.h"
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
+#define FETCH_INFERIOR_REGISTERS
diff --git a/gdb/config/mips/riscos.mh b/gdb/config/mips/riscos.mh
new file mode 100644
index 00000000000..6a3192f382b
--- /dev/null
+++ b/gdb/config/mips/riscos.mh
@@ -0,0 +1,16 @@
+# Host: MIPS running RISC/os
+
+XM_FILE= xm-riscos.h
+
+NAT_FILE= nm-riscos.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o mips-nat.o
+
+MH_CFLAGS=-Wf,-XNh10000
+
+# ptrace(2) apparently has problems in the BSD environment. No workaround is
+# known except to select the sysv environment. Could we use /proc instead?
+# These "sysv environments" and "bsd environments" often end up being a pain.
+#
+# This is not part of CFLAGS because perhaps not all C compilers have this
+# option.
+CC= cc -systype sysv
diff --git a/gdb/config/mips/tm-bigmips.h b/gdb/config/mips/tm-bigmips.h
new file mode 100644
index 00000000000..7a5a6b816c1
--- /dev/null
+++ b/gdb/config/mips/tm-bigmips.h
@@ -0,0 +1,20 @@
+/* Copyright 1990, 1994, 2000 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 "mips/tm-mips.h"
diff --git a/gdb/config/mips/tm-bigmips64.h b/gdb/config/mips/tm-bigmips64.h
new file mode 100644
index 00000000000..9f171eef11c
--- /dev/null
+++ b/gdb/config/mips/tm-bigmips64.h
@@ -0,0 +1,22 @@
+/* Target machine parameters for MIPS r4000
+ Copyright 1994, 2000 Free Software Foundation, Inc.
+ Contributed by Ian Lance Taylor (ian@cygnus.com)
+
+ 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 "mips/tm-mips64.h"
diff --git a/gdb/config/mips/tm-embed.h b/gdb/config/mips/tm-embed.h
new file mode 100644
index 00000000000..300e549aea1
--- /dev/null
+++ b/gdb/config/mips/tm-embed.h
@@ -0,0 +1,49 @@
+/* Copyright 1993, 1997, 1998, 1999, 2000 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 "mips/tm-bigmips.h"
+
+#undef DEFAULT_MIPS_TYPE
+#define DEFAULT_MIPS_TYPE "r3051"
+
+/* Watchpoint support */
+
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+
+/* Use these macros for watchpoint insertion/deletion. */
+/* type can be 0: write watch, 1: read watch, 2: access watch (read/write) */
+
+#define target_insert_watchpoint(addr, len, type) \
+ remote_mips_set_watchpoint (addr, len, type)
+int remote_mips_set_watchpoint (CORE_ADDR addr, int len, int type);
+
+#define target_remove_watchpoint(addr, len, type) \
+ remote_mips_remove_watchpoint (addr, len, type)
+int remote_mips_remove_watchpoint (CORE_ADDR addr, int len, int type);
+
+/* We need to remove watchpoints when stepping, else we hit them again! */
+
+#define HAVE_NONSTEPPABLE_WATCHPOINT
+
+int remote_mips_stopped_by_watchpoint (void);
+#define STOPPED_BY_WATCHPOINT(w) remote_mips_stopped_by_watchpoint ()
+
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \
+ remote_mips_can_use_hardware_watchpoint(cnt)
+int remote_mips_can_use_hardware_watchpoint (int cnt);
diff --git a/gdb/config/mips/tm-embed64.h b/gdb/config/mips/tm-embed64.h
new file mode 100644
index 00000000000..630b8e02516
--- /dev/null
+++ b/gdb/config/mips/tm-embed64.h
@@ -0,0 +1,20 @@
+/* Copyright 1993, 2000 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 "mips/tm-bigmips64.h"
diff --git a/gdb/config/mips/tm-embedl.h b/gdb/config/mips/tm-embedl.h
new file mode 100644
index 00000000000..d53f5c86228
--- /dev/null
+++ b/gdb/config/mips/tm-embedl.h
@@ -0,0 +1,20 @@
+/* Copyright 1993, 2000 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 "mips/tm-mips.h"
diff --git a/gdb/config/mips/tm-embedl64.h b/gdb/config/mips/tm-embedl64.h
new file mode 100644
index 00000000000..c76c612ac9d
--- /dev/null
+++ b/gdb/config/mips/tm-embedl64.h
@@ -0,0 +1,20 @@
+/* Copyright 1993, 2000 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 "mips/tm-mips64.h"
diff --git a/gdb/config/mips/tm-irix3.h b/gdb/config/mips/tm-irix3.h
new file mode 100644
index 00000000000..11859e59a5d
--- /dev/null
+++ b/gdb/config/mips/tm-irix3.h
@@ -0,0 +1,82 @@
+/* Target machine description for SGI Iris under Irix, for GDB.
+ Copyright 1990, 1991, 1992, 1993, 1995, 1999
+ 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 "mips/tm-bigmips.h"
+
+/* SGI's assembler doesn't grok dollar signs in identifiers.
+ So we use dots instead. This item must be coordinated with G++. */
+#undef CPLUS_MARKER
+#define CPLUS_MARKER '.'
+
+/* Redefine register numbers for SGI. */
+
+#undef NUM_REGS
+#undef MIPS_REGISTER_NAMES
+#undef FP0_REGNUM
+#undef PC_REGNUM
+#undef HI_REGNUM
+#undef LO_REGNUM
+#undef CAUSE_REGNUM
+#undef BADVADDR_REGNUM
+#undef FCRCS_REGNUM
+#undef FCRIR_REGNUM
+
+/* Number of machine registers */
+
+#define NUM_REGS 71
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer. */
+
+#define MIPS_REGISTER_NAMES \
+ { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
+ "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra", \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
+ "pc", "cause", "bad", "hi", "lo", "fsr", "fir" \
+ }
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define FP0_REGNUM 32 /* Floating point register 0 (single float) */
+#define PC_REGNUM 64 /* Contains program counter */
+#define CAUSE_REGNUM 65 /* describes last exception */
+#define BADVADDR_REGNUM 66 /* bad vaddr for addressing exception */
+#define HI_REGNUM 67 /* Multiple/divide temp */
+#define LO_REGNUM 68 /* ... */
+#define FCRCS_REGNUM 69 /* FP control/status */
+#define FCRIR_REGNUM 70 /* FP implementation/revision */
+
+/* Offsets for register values in _sigtramp frame.
+ sigcontext is immediately above the _sigtramp frame on Irix. */
+#define SIGFRAME_BASE 0x0
+#define SIGFRAME_PC_OFF (SIGFRAME_BASE + 2 * 4)
+#define SIGFRAME_REGSAVE_OFF (SIGFRAME_BASE + 3 * 4)
+#define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_BASE + 3 * 4 + 32 * 4 + 4)
diff --git a/gdb/config/mips/tm-irix5.h b/gdb/config/mips/tm-irix5.h
new file mode 100644
index 00000000000..49b842fb7f1
--- /dev/null
+++ b/gdb/config/mips/tm-irix5.h
@@ -0,0 +1,85 @@
+/* Target machine description for SGI Iris under Irix 5, for GDB.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1998, 2000
+ 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 "mips/tm-irix3.h"
+
+/* FIXME: cagney/2000-04-04: Testing the _MIPS_SIM_NABI32 and
+ _MIPS_SIM in a tm-*.h file is simply wrong! Those are
+ host-dependant macros (provided by /usr/include) and stop any
+ chance of the target being cross compiled */
+#if defined (_MIPS_SIM_NABI32) && _MIPS_SIM == _MIPS_SIM_NABI32
+/*
+ * Irix 6 (n32 ABI) has 32-bit GP regs and 64-bit FP regs
+ */
+
+#undef REGISTER_BYTES
+#define REGISTER_BYTES (MIPS_NUMREGS * 8 + (NUM_REGS - MIPS_NUMREGS) * MIPS_REGSIZE)
+
+#undef REGISTER_BYTE
+#define REGISTER_BYTE(N) \
+ (((N) < FP0_REGNUM) ? (N) * MIPS_REGSIZE : \
+ ((N) < FP0_REGNUM + 32) ? \
+ FP0_REGNUM * MIPS_REGSIZE + \
+ ((N) - FP0_REGNUM) * sizeof(double) : \
+ 32 * sizeof(double) + ((N) - 32) * MIPS_REGSIZE)
+
+#undef REGISTER_VIRTUAL_TYPE
+#define REGISTER_VIRTUAL_TYPE(N) \
+ (((N) >= FP0_REGNUM && (N) < FP0_REGNUM+32) ? builtin_type_double \
+ : ((N) == 32 /*SR*/) ? builtin_type_uint32 \
+ : ((N) >= 70 && (N) <= 89) ? builtin_type_uint32 \
+ : builtin_type_int)
+
+#undef MIPS_LAST_ARG_REGNUM
+#define MIPS_LAST_ARG_REGNUM 11 /* N32 uses R4 through R11 for args */
+
+/* MIPS_STACK_ARGSIZE -- how many bytes does a pushed function arg take
+ up on the stack? For the n32 ABI, eight bytes are reserved for each
+ register. Like MIPS_SAVED_REGSIZE but different. */
+#define MIPS_DEFAULT_STACK_ARGSIZE 8
+
+/* N32 does not reserve home space for registers used to carry
+ parameters. */
+#define MIPS_REGS_HAVE_HOME_P 0
+
+/* Force N32 ABI as the default. */
+#define MIPS_DEFAULT_ABI MIPS_ABI_N32
+
+#endif /* N32 */
+
+
+/* The signal handler trampoline is called _sigtramp. */
+#undef IN_SIGTRAMP
+#define IN_SIGTRAMP(pc, name) ((name) && STREQ ("_sigtramp", name))
+
+/* Irix 5 saves a full 64 bits for each register. We skip 2 * 4 to
+ get to the saved PC (the register mask and status register are both
+ 32 bits) and then another 4 to get to the lower 32 bits. We skip
+ the same 4 bytes, plus the 8 bytes for the PC to get to the
+ registers, and add another 4 to get to the lower 32 bits. We skip
+ 8 bytes per register. */
+#undef SIGFRAME_PC_OFF
+#define SIGFRAME_PC_OFF (SIGFRAME_BASE + 2 * 4 + 4)
+#undef SIGFRAME_REGSAVE_OFF
+#define SIGFRAME_REGSAVE_OFF (SIGFRAME_BASE + 2 * 4 + 8 + 4)
+#undef SIGFRAME_FPREGSAVE_OFF
+#define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_BASE + 2 * 4 + 8 + 32 * 8 + 4)
+#define SIGFRAME_REG_SIZE 8
diff --git a/gdb/config/mips/tm-irix6.h b/gdb/config/mips/tm-irix6.h
new file mode 100644
index 00000000000..2d90b2ef998
--- /dev/null
+++ b/gdb/config/mips/tm-irix6.h
@@ -0,0 +1,139 @@
+/* Target machine description for SGI Iris under Irix 6.x, for GDB.
+ Copyright 2001
+ 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 "mips/tm-bigmips.h"
+
+/* SGI's assembler doesn't grok dollar signs in identifiers.
+ So we use dots instead. This item must be coordinated with G++. */
+#undef CPLUS_MARKER
+#define CPLUS_MARKER '.'
+
+/* Redefine register numbers for SGI. */
+
+#undef NUM_REGS
+#undef MIPS_REGISTER_NAMES
+#undef FP0_REGNUM
+#undef PC_REGNUM
+#undef HI_REGNUM
+#undef LO_REGNUM
+#undef CAUSE_REGNUM
+#undef BADVADDR_REGNUM
+#undef FCRCS_REGNUM
+#undef FCRIR_REGNUM
+#undef FP_REGNUM
+
+/* Number of machine registers */
+
+#define NUM_REGS 71
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer. */
+
+#define MIPS_REGISTER_NAMES \
+ { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
+ "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", \
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
+ "pc", "cause", "bad", "hi", "lo", "fsr", "fir" \
+ }
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define FP0_REGNUM 32 /* Floating point register 0 (single float) */
+#define PC_REGNUM 64 /* Contains program counter */
+#define CAUSE_REGNUM 65 /* describes last exception */
+#define BADVADDR_REGNUM 66 /* bad vaddr for addressing exception */
+#define HI_REGNUM 67 /* Multiple/divide temp */
+#define LO_REGNUM 68 /* ... */
+#define FCRCS_REGNUM 69 /* FP control/status */
+#define FCRIR_REGNUM 70 /* FP implementation/revision */
+#define FP_REGNUM 30 /* S8 register is the Frame Pointer */
+
+
+#undef REGISTER_BYTES
+#define REGISTER_BYTES (MIPS_NUMREGS * 8 + (NUM_REGS - MIPS_NUMREGS) * MIPS_REGSIZE)
+
+#undef REGISTER_BYTE
+#define REGISTER_BYTE(N) \
+ (((N) < FP0_REGNUM) ? (N) * MIPS_REGSIZE : \
+ ((N) < FP0_REGNUM + 32) ? \
+ FP0_REGNUM * MIPS_REGSIZE + \
+ ((N) - FP0_REGNUM) * sizeof(double) : \
+ 32 * sizeof(double) + ((N) - 32) * MIPS_REGSIZE)
+
+#undef REGISTER_VIRTUAL_TYPE
+#define REGISTER_VIRTUAL_TYPE(N) \
+ (((N) >= FP0_REGNUM && (N) < FP0_REGNUM+32) ? builtin_type_double \
+ : ((N) == 32 /*SR*/) ? builtin_type_uint32 \
+ : ((N) >= 70 && (N) <= 89) ? builtin_type_uint32 \
+ : builtin_type_int)
+
+#undef MIPS_LAST_ARG_REGNUM
+#define MIPS_LAST_ARG_REGNUM 11 /* N32 uses R4 through R11 for args */
+
+/* MIPS_STACK_ARGSIZE -- how many bytes does a pushed function arg take
+ up on the stack? For the n32 ABI, eight bytes are reserved for each
+ register. Like MIPS_SAVED_REGSIZE but different. */
+#define MIPS_DEFAULT_STACK_ARGSIZE 8
+
+/* N32 does not reserve home space for registers used to carry
+ parameters. */
+#define MIPS_REGS_HAVE_HOME_P 0
+
+/* Force N32 ABI as the default. */
+#define MIPS_DEFAULT_ABI MIPS_ABI_N32
+
+
+/* The signal handler trampoline is called _sigtramp. */
+#undef IN_SIGTRAMP
+#define IN_SIGTRAMP(pc, name) ((name) && STREQ ("_sigtramp", name))
+
+/* Offsets for register values in _sigtramp frame.
+ sigcontext is immediately above the _sigtramp frame on Irix. */
+#undef SIGFRAME_BASE
+#define SIGFRAME_BASE 0
+
+/* Irix 5 saves a full 64 bits for each register. We skip 2 * 4 to
+ get to the saved PC (the register mask and status register are both
+ 32 bits) and then another 4 to get to the lower 32 bits. We skip
+ the same 4 bytes, plus the 8 bytes for the PC to get to the
+ registers, and add another 4 to get to the lower 32 bits. We skip
+ 8 bytes per register. */
+#undef SIGFRAME_PC_OFF
+#define SIGFRAME_PC_OFF (SIGFRAME_BASE + 2 * 4 + 4)
+#undef SIGFRAME_REGSAVE_OFF
+#define SIGFRAME_REGSAVE_OFF (SIGFRAME_BASE + 2 * 4 + 8 + 4)
+#undef SIGFRAME_FPREGSAVE_OFF
+#define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_BASE + 2 * 4 + 8 + 32 * 8 + 4)
+#define SIGFRAME_REG_SIZE 8
+
+/* Select the disassembler */
+#undef TM_PRINT_INSN_MACH
+#define TM_PRINT_INSN_MACH bfd_mach_mips8000
diff --git a/gdb/config/mips/tm-linux.h b/gdb/config/mips/tm-linux.h
new file mode 100644
index 00000000000..0e9de3cbb26
--- /dev/null
+++ b/gdb/config/mips/tm-linux.h
@@ -0,0 +1,75 @@
+/* Target-dependent definitions for GNU/Linux MIPS.
+
+ Copyright 2001, 2002 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. */
+
+#ifndef TM_MIPSLINUX_H
+#define TM_MIPSLINUX_H
+
+#include "mips/tm-mips.h"
+
+/* We don't want to inherit tm-mips.h's shared library trampoline code. */
+
+#undef IN_SOLIB_CALL_TRAMPOLINE
+#undef IN_SOLIB_RETURN_TRAMPOLINE
+#undef SKIP_TRAMPOLINE_CODE
+#undef IGNORE_HELPER_CALL
+
+/* GNU/Linux MIPS has __SIGRTMAX == 127. */
+
+#define REALTIME_LO 32
+#define REALTIME_HI 128
+
+#include "tm-linux.h"
+
+/* There's an E_MIPS_ABI_O32 flag in e_flags, but we don't use it - in
+ fact, using it may violate the o32 ABI. */
+
+#define MIPS_DEFAULT_ABI MIPS_ABI_O32
+
+/* Use target_specific function to define link map offsets. */
+
+extern struct link_map_offsets *mips_linux_svr4_fetch_link_map_offsets (void);
+#define SVR4_FETCH_LINK_MAP_OFFSETS() \
+ mips_linux_svr4_fetch_link_map_offsets ()
+
+/* Details about jmp_buf. */
+
+#define JB_ELEMENT_SIZE 4
+#define JB_PC 0
+
+/* Figure out where the longjmp will land. Slurp the arguments out of the
+ stack. We expect the first arg to be a pointer to the jmp_buf structure
+ from which we extract the pc (JB_PC) that we will land at. The pc is
+ copied into ADDR. This routine returns 1 on success. */
+
+#define GET_LONGJMP_TARGET(ADDR) mips_linux_get_longjmp_target(ADDR)
+extern int mips_linux_get_longjmp_target (CORE_ADDR *);
+
+/* We do single stepping in software. */
+
+#define SOFTWARE_SINGLE_STEP_P() 1
+#define SOFTWARE_SINGLE_STEP(sig,bp_p) mips_software_single_step (sig, bp_p)
+
+/* FIXME: This still needs to be implemented. */
+
+#undef IN_SIGTRAMP
+#define IN_SIGTRAMP(pc, name) (0)
+
+#endif /* TM_MIPSLINUX_H */
diff --git a/gdb/config/mips/tm-mips.h b/gdb/config/mips/tm-mips.h
new file mode 100644
index 00000000000..8403ef87153
--- /dev/null
+++ b/gdb/config/mips/tm-mips.h
@@ -0,0 +1,493 @@
+/* Definitions to make GDB run on a mips box under 4.3bsd.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000
+ Free Software Foundation, Inc.
+ Contributed by Per Bothner (bothner@cs.wisc.edu) at U.Wisconsin
+ and by Alessandro Forin (af@cs.cmu.edu) at CMU..
+
+ 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. */
+
+#ifndef TM_MIPS_H
+#define TM_MIPS_H 1
+
+#define GDB_MULTI_ARCH 1
+
+#include "regcache.h"
+
+struct frame_info;
+struct symbol;
+struct type;
+struct value;
+
+#include <bfd.h>
+#include "coff/sym.h" /* Needed for PDR below. */
+#include "coff/symconst.h"
+
+#if !defined (MIPS_EABI)
+#define MIPS_EABI 0
+#endif
+
+/* PC should be masked to remove possible MIPS16 flag */
+#if !defined (GDB_TARGET_MASK_DISAS_PC)
+#define GDB_TARGET_MASK_DISAS_PC(addr) UNMAKE_MIPS16_ADDR(addr)
+#endif
+#if !defined (GDB_TARGET_UNMASK_DISAS_PC)
+#define GDB_TARGET_UNMASK_DISAS_PC(addr) MAKE_MIPS16_ADDR(addr)
+#endif
+
+/* The name of the usual type of MIPS processor that is in the target
+ system. */
+
+#define DEFAULT_MIPS_TYPE "generic"
+
+/* Remove useless bits from the stack pointer. */
+
+#define TARGET_READ_SP() ADDR_BITS_REMOVE (read_register (SP_REGNUM))
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Return non-zero if PC points to an instruction which will cause a step
+ to execute both the instruction at PC and an instruction at PC+4. */
+extern int mips_step_skips_delay (CORE_ADDR);
+#define STEP_SKIPS_DELAY_P (1)
+#define STEP_SKIPS_DELAY(pc) (mips_step_skips_delay (pc))
+
+/* Are we currently handling a signal */
+
+extern int in_sigtramp (CORE_ADDR, char *);
+#define IN_SIGTRAMP(pc, name) in_sigtramp(pc, name)
+
+/* Say how long (ordinary) registers are. This is a piece of bogosity
+ used in push_word and a few other places; REGISTER_RAW_SIZE is the
+ real way to know how big a register is. */
+
+#define REGISTER_SIZE 4
+
+/* The size of a register. This is predefined in tm-mips64.h. We
+ can't use REGISTER_SIZE because that is used for various other
+ things. */
+
+#ifndef MIPS_REGSIZE
+#define MIPS_REGSIZE 4
+#endif
+
+/* Number of machine registers */
+
+#ifndef NUM_REGS
+#define NUM_REGS 90
+#endif
+
+/* Given the register index, return the name of the corresponding
+ register. */
+extern char *mips_register_name (int regnr);
+#define REGISTER_NAME(i) mips_register_name (i)
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer. */
+
+#ifndef MIPS_REGISTER_NAMES
+#define MIPS_REGISTER_NAMES \
+ { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", \
+ "sr", "lo", "hi", "bad", "cause","pc", \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
+ "fsr", "fir", "fp", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ }
+#endif
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define ZERO_REGNUM 0 /* read-only register, always 0 */
+#define V0_REGNUM 2 /* Function integer return value */
+#define A0_REGNUM 4 /* Loc of first arg during a subr call */
+#if MIPS_EABI
+#define MIPS_LAST_ARG_REGNUM 11 /* EABI uses R4 through R11 for args */
+#else
+#define MIPS_LAST_ARG_REGNUM 7 /* old ABI uses R4 through R7 for args */
+#endif
+#define T9_REGNUM 25 /* Contains address of callee in PIC */
+#define SP_REGNUM 29 /* Contains address of top of stack */
+#define RA_REGNUM 31 /* Contains return address value */
+#define PS_REGNUM 32 /* Contains processor status */
+#define HI_REGNUM 34 /* Multiple/divide temp */
+#define LO_REGNUM 33 /* ... */
+#define BADVADDR_REGNUM 35 /* bad vaddr for addressing exception */
+#define CAUSE_REGNUM 36 /* describes last exception */
+#define PC_REGNUM 37 /* Contains program counter */
+#define FP0_REGNUM 38 /* Floating point register 0 (single float) */
+#define FPA0_REGNUM (FP0_REGNUM+12) /* First float argument register */
+#if MIPS_EABI /* EABI uses F12 through F19 for args */
+#define MIPS_LAST_FP_ARG_REGNUM (FP0_REGNUM+19)
+#else /* old ABI uses F12 through F15 for args */
+#define MIPS_LAST_FP_ARG_REGNUM (FP0_REGNUM+15)
+#endif
+#define FCRCS_REGNUM 70 /* FP control/status */
+#define FCRIR_REGNUM 71 /* FP implementation/revision */
+#define FP_REGNUM 72 /* Pseudo register that contains true address of executing stack frame */
+#define UNUSED_REGNUM 73 /* Never used, FIXME */
+#define FIRST_EMBED_REGNUM 74 /* First CP0 register for embedded use */
+#define PRID_REGNUM 89 /* Processor ID */
+#define LAST_EMBED_REGNUM 89 /* Last one */
+
+/* Define DO_REGISTERS_INFO() to do machine-specific formatting
+ of register dumps. */
+
+#define DO_REGISTERS_INFO(_regnum, fp) mips_do_registers_info(_regnum, fp)
+extern void mips_do_registers_info (int, int);
+
+/* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'. */
+
+#define REGISTER_BYTES (NUM_REGS*MIPS_REGSIZE)
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#define REGISTER_BYTE(N) ((N) * MIPS_REGSIZE)
+
+/* Covert between the RAW and VIRTUAL registers.
+
+ Some MIPS (SR, FSR, FIR) have a `raw' size of MIPS_REGSIZE but are
+ really 32 bit registers. This is a legacy of the 64 bit MIPS GDB
+ protocol which transfers 64 bits for 32 bit registers. */
+
+extern int mips_register_convertible (int reg_nr);
+#define REGISTER_CONVERTIBLE(N) (mips_register_convertible ((N)))
+
+
+void mips_register_convert_to_virtual (int reg_nr, struct type *virtual_type,
+ char *raw_buf, char *virt_buf);
+#define REGISTER_CONVERT_TO_VIRTUAL(N,VIRTUAL_TYPE,RAW_BUF,VIRT_BUF) \
+ mips_register_convert_to_virtual (N,VIRTUAL_TYPE,RAW_BUF,VIRT_BUF)
+
+void mips_register_convert_to_raw (struct type *virtual_type, int reg_nr,
+ char *virt_buf, char *raw_buf);
+#define REGISTER_CONVERT_TO_RAW(VIRTUAL_TYPE,N,VIRT_BUF,RAW_BUF) \
+ mips_register_convert_to_raw (VIRTUAL_TYPE,N,VIRT_BUF,RAW_BUF)
+
+/* Number of bytes of storage in the program's representation
+ for register N. */
+
+#define REGISTER_VIRTUAL_SIZE(N) TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (N))
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#define MAX_REGISTER_RAW_SIZE 8
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Return the GDB type object for the "standard" data type of data in
+ register N. */
+
+#ifndef REGISTER_VIRTUAL_TYPE
+#define REGISTER_VIRTUAL_TYPE(N) \
+ (((N) >= FP0_REGNUM && (N) < FP0_REGNUM+32) ? builtin_type_float \
+ : ((N) == 32 /*SR*/) ? builtin_type_uint32 \
+ : ((N) >= 70 && (N) <= 89) ? builtin_type_uint32 \
+ : builtin_type_int)
+#endif
+
+/* All mips targets store doubles in a register pair with the least
+ significant register in the lower numbered register.
+ If the target is big endian, double register values need conversion
+ between memory and register formats. */
+
+#define REGISTER_CONVERT_TO_TYPE(n, type, buffer) \
+ do {if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG \
+ && REGISTER_RAW_SIZE (n) == 4 \
+ && (n) >= FP0_REGNUM && (n) < FP0_REGNUM + 32 \
+ && TYPE_CODE(type) == TYPE_CODE_FLT \
+ && TYPE_LENGTH(type) == 8) { \
+ char __temp[4]; \
+ memcpy (__temp, ((char *)(buffer))+4, 4); \
+ memcpy (((char *)(buffer))+4, (buffer), 4); \
+ memcpy (((char *)(buffer)), __temp, 4); }} while (0)
+
+#define REGISTER_CONVERT_FROM_TYPE(n, type, buffer) \
+ do {if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG \
+ && REGISTER_RAW_SIZE (n) == 4 \
+ && (n) >= FP0_REGNUM && (n) < FP0_REGNUM + 32 \
+ && TYPE_CODE(type) == TYPE_CODE_FLT \
+ && TYPE_LENGTH(type) == 8) { \
+ char __temp[4]; \
+ memcpy (__temp, ((char *)(buffer))+4, 4); \
+ memcpy (((char *)(buffer))+4, (buffer), 4); \
+ memcpy (((char *)(buffer)), __temp, 4); }} while (0)
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. Handled by mips_push_arguments. */
+
+#define STORE_STRUCT_RETURN(addr, sp)
+/**/
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. XXX floats */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ mips_extract_return_value(TYPE, REGBUF, VALBUF)
+extern void mips_extract_return_value (struct type *, char[], char *);
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format. */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ mips_store_return_value(TYPE, VALBUF)
+extern void mips_store_return_value (struct type *, char *);
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+/* The address is passed in a0 upon entry to the function, but when
+ the function exits, the compiler has copied the value to v0. This
+ convention is specified by the System V ABI, so I think we can rely
+ on it. */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+ (extract_address (REGBUF + REGISTER_BYTE (V0_REGNUM), \
+ REGISTER_RAW_SIZE (V0_REGNUM)))
+
+extern use_struct_convention_fn mips_use_struct_convention;
+#define USE_STRUCT_CONVENTION(gcc_p, type) mips_use_struct_convention (gcc_p, type)
+
+/* Describe the pointer in each stack frame to the previous stack frame
+ (its caller). */
+
+/* FRAME_CHAIN takes a frame's nominal address
+ and produces the frame's chain-pointer. */
+
+#define FRAME_CHAIN(thisframe) (CORE_ADDR) mips_frame_chain (thisframe)
+extern CORE_ADDR mips_frame_chain (struct frame_info *);
+
+/* Define other aspects of the stack frame. */
+
+
+/* A macro that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. If it
+ does not, FRAMELESS is set to 1, else 0. */
+/* We handle this differently for mips, and maybe we should not */
+
+#define FRAMELESS_FUNCTION_INVOCATION(FI) (0)
+
+/* Saved Pc. */
+
+#define FRAME_SAVED_PC(FRAME) (mips_frame_saved_pc(FRAME))
+extern CORE_ADDR mips_frame_saved_pc (struct frame_info *);
+
+#define FRAME_ARGS_ADDRESS(fi) (fi)->frame
+
+#define FRAME_LOCALS_ADDRESS(fi) (fi)->frame
+
+/* Return number of args passed to a frame.
+ Can return -1, meaning no way to tell. */
+
+#define FRAME_NUM_ARGS(fi) (mips_frame_num_args(fi))
+extern int mips_frame_num_args (struct frame_info *);
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame. */
+
+#define FRAME_INIT_SAVED_REGS(frame_info) \
+ do { \
+ if ((frame_info)->saved_regs == NULL) \
+ mips_find_saved_regs (frame_info); \
+ (frame_info)->saved_regs[SP_REGNUM] = (frame_info)->frame; \
+ } while (0)
+extern void mips_find_saved_regs (struct frame_info *);
+
+
+/* Things needed for making the inferior call functions. */
+
+/* Stack must be aligned on 32-bit boundaries when synthesizing
+ function calls. We don't need STACK_ALIGN, PUSH_ARGUMENTS will
+ handle it. */
+
+extern CORE_ADDR mips_push_arguments (int, struct value **, CORE_ADDR, int,
+ CORE_ADDR);
+#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
+ (mips_push_arguments((nargs), (args), (sp), (struct_return), (struct_addr)))
+
+extern CORE_ADDR mips_push_return_address (CORE_ADDR pc, CORE_ADDR sp);
+#define PUSH_RETURN_ADDRESS(PC, SP) (mips_push_return_address ((PC), (SP)))
+
+/* Push an empty stack frame, to record the current PC, etc. */
+
+#define PUSH_DUMMY_FRAME mips_push_dummy_frame()
+extern void mips_push_dummy_frame (void);
+
+/* Discard from the stack the innermost frame, restoring all registers. */
+
+#define POP_FRAME mips_pop_frame()
+extern void mips_pop_frame (void);
+
+#define CALL_DUMMY_START_OFFSET (0)
+
+#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
+
+/* When calling functions on Irix 5 (or any MIPS SVR4 ABI compliant
+ platform), $t9 ($25) (Dest_Reg) contains the address of the callee
+ (used for PIC). It doesn't hurt to do this on other systems; $t9
+ will be ignored. */
+#define FIX_CALL_DUMMY(dummyname, start_sp, fun, nargs, args, rettype, gcc_p) \
+ write_register(T9_REGNUM, fun)
+
+#define CALL_DUMMY_ADDRESS() (mips_call_dummy_address ())
+extern CORE_ADDR mips_call_dummy_address (void);
+
+/* Special symbol found in blocks associated with routines. We can hang
+ mips_extra_func_info_t's off of this. */
+
+#define MIPS_EFI_SYMBOL_NAME "__GDB_EFI_INFO__"
+extern void ecoff_relocate_efi (struct symbol *, CORE_ADDR);
+
+/* Specific information about a procedure.
+ This overlays the MIPS's PDR records,
+ mipsread.c (ab)uses this to save memory */
+
+typedef struct mips_extra_func_info
+ {
+ long numargs; /* number of args to procedure (was iopt) */
+ bfd_vma high_addr; /* upper address bound */
+ long frame_adjust; /* offset of FP from SP (used on MIPS16) */
+ PDR pdr; /* Procedure descriptor record */
+ }
+ *mips_extra_func_info_t;
+
+extern void mips_init_extra_frame_info (int fromleaf, struct frame_info *);
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fci) \
+ mips_init_extra_frame_info(fromleaf, fci)
+
+extern void mips_print_extra_frame_info (struct frame_info *frame);
+#define PRINT_EXTRA_FRAME_INFO(fi) \
+ mips_print_extra_frame_info (fi)
+
+/* It takes two values to specify a frame on the MIPS.
+
+ In fact, the *PC* is the primary value that sets up a frame. The
+ PC is looked up to see what function it's in; symbol information
+ from that function tells us which register is the frame pointer
+ base, and what offset from there is the "virtual frame pointer".
+ (This is usually an offset from SP.) On most non-MIPS machines,
+ the primary value is the SP, and the PC, if needed, disambiguates
+ multiple functions with the same SP. But on the MIPS we can't do
+ that since the PC is not stored in the same part of the frame every
+ time. This does not seem to be a very clever way to set up frames,
+ but there is nothing we can do about that. */
+
+#define SETUP_ARBITRARY_FRAME(argc, argv) setup_arbitrary_frame (argc, argv)
+extern struct frame_info *setup_arbitrary_frame (int, CORE_ADDR *);
+
+/* Select the default mips disassembler */
+
+#define TM_PRINT_INSN_MACH 0
+
+
+/* These are defined in mdebugread.c and are used in mips-tdep.c */
+extern CORE_ADDR sigtramp_address, sigtramp_end;
+extern void fixup_sigtramp (void);
+
+/* Defined in mips-tdep.c and used in remote-mips.c */
+extern char *mips_read_processor_type (void);
+
+/* Functions for dealing with MIPS16 call and return stubs. */
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) mips_in_call_stub (pc, name)
+#define IN_SOLIB_RETURN_TRAMPOLINE(pc, name) mips_in_return_stub (pc, name)
+#define SKIP_TRAMPOLINE_CODE(pc) mips_skip_stub (pc)
+#define IGNORE_HELPER_CALL(pc) mips_ignore_helper (pc)
+extern int mips_in_call_stub (CORE_ADDR pc, char *name);
+extern int mips_in_return_stub (CORE_ADDR pc, char *name);
+extern CORE_ADDR mips_skip_stub (CORE_ADDR pc);
+extern int mips_ignore_helper (CORE_ADDR pc);
+
+#ifndef TARGET_MIPS
+#define TARGET_MIPS
+#endif
+
+/* Definitions and declarations used by mips-tdep.c and remote-mips.c */
+#define MIPS_INSTLEN 4 /* Length of an instruction */
+#define MIPS16_INSTLEN 2 /* Length of an instruction on MIPS16 */
+#define MIPS_NUMREGS 32 /* Number of integer or float registers */
+typedef unsigned long t_inst; /* Integer big enough to hold an instruction */
+
+/* MIPS16 function addresses are odd (bit 0 is set). Here are some
+ macros to test, set, or clear bit 0 of addresses. */
+#define IS_MIPS16_ADDR(addr) ((addr) & 1)
+#define MAKE_MIPS16_ADDR(addr) ((addr) | 1)
+#define UNMAKE_MIPS16_ADDR(addr) ((addr) & ~1)
+
+#endif /* TM_MIPS_H */
+
+/* Macros for setting and testing a bit in a minimal symbol that
+ marks it as 16-bit function. The MSB of the minimal symbol's
+ "info" field is used for this purpose. This field is already
+ being used to store the symbol size, so the assumption is
+ that the symbol size cannot exceed 2^31.
+
+ ELF_MAKE_MSYMBOL_SPECIAL
+ tests whether an ELF symbol is "special", i.e. refers
+ to a 16-bit function, and sets a "special" bit in a
+ minimal symbol to mark it as a 16-bit function
+ MSYMBOL_IS_SPECIAL tests the "special" bit in a minimal symbol
+ MSYMBOL_SIZE returns the size of the minimal symbol, i.e.
+ the "info" field with the "special" bit masked out
+ */
+
+#define ELF_MAKE_MSYMBOL_SPECIAL(sym,msym) \
+ { \
+ if (((elf_symbol_type *)(sym))->internal_elf_sym.st_other == STO_MIPS16) { \
+ MSYMBOL_INFO (msym) = (char *) (((long) MSYMBOL_INFO (msym)) | 0x80000000); \
+ SYMBOL_VALUE_ADDRESS (msym) |= 1; \
+ } \
+ }
+
+#define MSYMBOL_IS_SPECIAL(msym) \
+ (((long) MSYMBOL_INFO (msym) & 0x80000000) != 0)
+#define MSYMBOL_SIZE(msym) \
+ ((long) MSYMBOL_INFO (msym) & 0x7fffffff)
+
+
+/* Command to set the processor type. */
+extern void mips_set_processor_type_command (char *, int);
+
+
+/* Single step based on where the current instruction will take us. */
+extern void mips_software_single_step (enum target_signal, int);
diff --git a/gdb/config/mips/tm-mips64.h b/gdb/config/mips/tm-mips64.h
new file mode 100644
index 00000000000..510ad05c0bc
--- /dev/null
+++ b/gdb/config/mips/tm-mips64.h
@@ -0,0 +1,37 @@
+/* Target machine parameters for MIPS r4000
+ Copyright 1994, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+ Contributed by Ian Lance Taylor (ian@cygnus.com)
+
+ 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. */
+
+/* Use eight byte registers. */
+#define MIPS_REGSIZE 8
+
+/* define 8 byte register type */
+#define REGISTER_VIRTUAL_TYPE(N) \
+ (((N) >= FP0_REGNUM && (N) < FP0_REGNUM+32) ? builtin_type_double \
+ : ((N) == 32 /*SR*/) ? builtin_type_uint32 \
+ : ((N) >= 70 && (N) <= 89) ? builtin_type_uint32 \
+ : builtin_type_long_long)
+
+/* Load double words in CALL_DUMMY. */
+#define OP_LDFPR 065 /* ldc1 */
+#define OP_LDGPR 067 /* ld */
+
+/* Get the basic MIPS definitions. */
+#include "tm-mips.h"
diff --git a/gdb/config/mips/tm-mipsm3.h b/gdb/config/mips/tm-mipsm3.h
new file mode 100644
index 00000000000..19ae028c604
--- /dev/null
+++ b/gdb/config/mips/tm-mipsm3.h
@@ -0,0 +1,67 @@
+/* Definitions to make GDB run on a mips box under Mach 3.0
+ Copyright 1992, 1993, 1998 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. */
+
+/* Mach specific definitions for little endian mips (e.g. pmax)
+ * running Mach 3.0
+ *
+ * Author: Jukka Virtanen <jtv@hut.fi>
+ */
+
+/* Include common definitions for Mach3 systems */
+#include "nm-m3.h"
+
+/* Define offsets to access CPROC stack when it does not have
+ * a kernel thread.
+ */
+
+/* From mk/user/threads/mips/csw.s */
+#define SAVED_FP (12*4)
+#define SAVED_PC (13*4)
+#define SAVED_BYTES (14*4)
+
+/* Using these, define our offsets to items strored in
+ * cproc_switch in csw.s
+ */
+#define MACHINE_CPROC_SP_OFFSET SAVED_BYTES
+#define MACHINE_CPROC_PC_OFFSET SAVED_PC
+#define MACHINE_CPROC_FP_OFFSET SAVED_FP
+
+/* Thread flavors used in setting the Trace state.
+
+ * In <mach/machine/thread_status.h>
+ */
+#define TRACE_FLAVOR MIPS_EXC_STATE
+#define TRACE_FLAVOR_SIZE MIPS_EXC_STATE_COUNT
+#define TRACE_SET(x,state) ((struct mips_exc_state *)state)->cause = EXC_SST;
+#define TRACE_CLEAR(x,state) 0
+
+/* Mach supports attach/detach */
+#define ATTACH_DETACH 1
+
+#include "mips/tm-mips.h"
+
+/* Address of end of user stack space.
+ * for MACH, see <machine/vmparam.h>
+ */
+#undef STACK_END_ADDR
+#define STACK_END_ADDR USRSTACK
+
+/* Output registers in tabular format */
+#define TABULAR_REGISTER_OUTPUT
diff --git a/gdb/config/mips/tm-mipsv4.h b/gdb/config/mips/tm-mipsv4.h
new file mode 100644
index 00000000000..d1cc21ca1e8
--- /dev/null
+++ b/gdb/config/mips/tm-mipsv4.h
@@ -0,0 +1,40 @@
+/* Target machine description for MIPS running SVR4, for GDB.
+ Copyright 1994, 1995, 1998, 1999, 2000 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 "mips/tm-bigmips.h"
+#include "tm-sysv4.h"
+
+/* The signal handler trampoline is called _sigtramp. */
+#undef IN_SIGTRAMP
+#define IN_SIGTRAMP(pc, name) ((name) && STREQ ("_sigtramp", name))
+
+/* On entry to the signal handler trampoline, an ucontext is already
+ pushed on the stack. We can get at the saved registers via the
+ mcontext which is contained within the ucontext. */
+#define SIGFRAME_BASE 0
+#define SIGFRAME_REGSAVE_OFF (SIGFRAME_BASE + 40)
+#define SIGFRAME_PC_OFF (SIGFRAME_BASE + 40 + 35 * 4)
+#define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_BASE + 40 + 36 * 4)
+
+/* Use the alternate method of determining valid frame chains. */
+#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi)
+
+/* Convert a DWARF register number to a gdb REGNUM. */
+#define DWARF_REG_TO_REGNUM(num) ((num) < 32 ? (num) : (num)+FP0_REGNUM-32)
diff --git a/gdb/config/mips/tm-nbsd.h b/gdb/config/mips/tm-nbsd.h
new file mode 100644
index 00000000000..fc7448665e1
--- /dev/null
+++ b/gdb/config/mips/tm-nbsd.h
@@ -0,0 +1,45 @@
+/* Target-dependent definitions for NetBSD/mips.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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. */
+
+#ifndef TM_NBSD_H
+#define TM_NBSD_H
+
+/* Saved Pc. Get it from sigcontext if within sigtramp. */
+#define SIGCONTEXT_PC_OFFSET 8
+
+#include "mips/tm-mips.h"
+#include "solib.h"
+
+/* There's an E_MIPS_ABI_O32 flag in e_flags, but we don't use it - in
+ fact, using it may violate the o32 ABI. */
+
+#define MIPS_DEFAULT_ABI MIPS_ABI_O32
+
+/* We don't want to inherit tm-mips.h's shared library trampoline code. */
+#undef IN_SOLIB_CALL_TRAMPOLINE
+#undef IN_SOLIB_RETURN_TRAMPOLINE
+#undef SKIP_TRAMPOLINE_CODE
+#undef IGNORE_HELPER_CALL
+
+/* XXX undef a bunch of stuff we want to use multi-arch */
+#undef IN_SIGTRAMP
+
+#endif /* TM_NBSD_H */
diff --git a/gdb/config/mips/tm-tx39.h b/gdb/config/mips/tm-tx39.h
new file mode 100644
index 00000000000..d6fbd29ad33
--- /dev/null
+++ b/gdb/config/mips/tm-tx39.h
@@ -0,0 +1,36 @@
+/* Copyright 1993, 1997, 1999, 2000 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 "mips/tm-bigmips.h"
+
+#undef MIPS_REGISTER_NAMES
+#define MIPS_REGISTER_NAMES \
+ { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", \
+ "sr", "lo", "hi", "bad", "cause","pc", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "config", "cache", "debug", "depc", "epc", "" \
+ }
diff --git a/gdb/config/mips/tm-tx39l.h b/gdb/config/mips/tm-tx39l.h
new file mode 100644
index 00000000000..0c6d32b85f1
--- /dev/null
+++ b/gdb/config/mips/tm-tx39l.h
@@ -0,0 +1,36 @@
+/* Copyright 1993, 1997, 1999, 2000 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 "mips/tm-mips.h"
+
+#undef MIPS_REGISTER_NAMES
+#define MIPS_REGISTER_NAMES \
+ { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", \
+ "sr", "lo", "hi", "bad", "cause","pc", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "config", "cache", "debug", "depc", "epc", "" \
+ }
diff --git a/gdb/config/mips/tm-vr4100.h b/gdb/config/mips/tm-vr4100.h
new file mode 100644
index 00000000000..9c4472b0510
--- /dev/null
+++ b/gdb/config/mips/tm-vr4100.h
@@ -0,0 +1,20 @@
+/* Copyright 1998, 2000 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 "mips/tm-bigmips64.h"
diff --git a/gdb/config/mips/tm-vr4300.h b/gdb/config/mips/tm-vr4300.h
new file mode 100644
index 00000000000..728c73135e5
--- /dev/null
+++ b/gdb/config/mips/tm-vr4300.h
@@ -0,0 +1,20 @@
+/* Copyright 1993, 1995, 1996, 2000 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 "mips/tm-bigmips64.h"
diff --git a/gdb/config/mips/tm-vr4300el.h b/gdb/config/mips/tm-vr4300el.h
new file mode 100644
index 00000000000..e7e56805dfb
--- /dev/null
+++ b/gdb/config/mips/tm-vr4300el.h
@@ -0,0 +1,20 @@
+/* Copyright 1993, 1995, 1996, 2000 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 "mips/tm-mips64.h"
diff --git a/gdb/config/mips/tm-vr4xxx.h b/gdb/config/mips/tm-vr4xxx.h
new file mode 100644
index 00000000000..9c4472b0510
--- /dev/null
+++ b/gdb/config/mips/tm-vr4xxx.h
@@ -0,0 +1,20 @@
+/* Copyright 1998, 2000 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 "mips/tm-bigmips64.h"
diff --git a/gdb/config/mips/tm-vr4xxxel.h b/gdb/config/mips/tm-vr4xxxel.h
new file mode 100644
index 00000000000..7f2e4cd2d04
--- /dev/null
+++ b/gdb/config/mips/tm-vr4xxxel.h
@@ -0,0 +1,20 @@
+/* Copyright 1998, 2000 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 "mips/tm-mips64.h"
diff --git a/gdb/config/mips/tm-vr5000.h b/gdb/config/mips/tm-vr5000.h
new file mode 100644
index 00000000000..0d68345d093
--- /dev/null
+++ b/gdb/config/mips/tm-vr5000.h
@@ -0,0 +1,20 @@
+/* Copyright 1996, 2000 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 "mips/tm-bigmips64.h"
diff --git a/gdb/config/mips/tm-vr5000el.h b/gdb/config/mips/tm-vr5000el.h
new file mode 100644
index 00000000000..7fae087d24b
--- /dev/null
+++ b/gdb/config/mips/tm-vr5000el.h
@@ -0,0 +1,20 @@
+/* Copyright 1996, 2000 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 "mips/tm-mips64.h"
diff --git a/gdb/config/mips/tm-vxmips.h b/gdb/config/mips/tm-vxmips.h
new file mode 100644
index 00000000000..e4ef2b6a2bd
--- /dev/null
+++ b/gdb/config/mips/tm-vxmips.h
@@ -0,0 +1,29 @@
+/* Target machine description for VxWorks MIPS's, for GDB, the GNU debugger.
+ Copyright 1996, 1999 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 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 "mips/tm-mips.h"
+#include "tm-vxworks.h"
+
+/* FIXME: These are almost certainly wrong. */
+
+/* Number of registers in a ptrace_getregs call. */
+
+#define VX_NUM_REGS (NUM_REGS)
diff --git a/gdb/config/mips/tm-wince.h b/gdb/config/mips/tm-wince.h
new file mode 100644
index 00000000000..3ea179b56e6
--- /dev/null
+++ b/gdb/config/mips/tm-wince.h
@@ -0,0 +1,33 @@
+/* Definitions to make GDB run on a Windows CE system.
+
+ Copyright 2000 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. */
+
+#ifndef TM_WINCE_H
+#define TM_WINCE_H 1
+
+#include "mips/tm-mips.h"
+
+#undef SOFTWARE_SINGLE_STEP_P
+#define SOFTWARE_SINGLE_STEP_P() 1
+#define SOFTWARE_SINGLE_STEP(sig, bp_p) wince_software_single_step (sig, bp_p)
+
+void wince_software_single_step (unsigned int, int);
+
+#endif /* TM_WINCE_H */
diff --git a/gdb/config/mips/tx39.mt b/gdb/config/mips/tx39.mt
new file mode 100644
index 00000000000..8b4c1a92c24
--- /dev/null
+++ b/gdb/config/mips/tx39.mt
@@ -0,0 +1,5 @@
+# Target: Big-endian mips board, typically an IDT.
+TDEPFILES= mips-tdep.o remote-mips.o dve3900-rom.o monitor.o dsrec.o
+TM_FILE= tm-tx39.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/tx39l.mt b/gdb/config/mips/tx39l.mt
new file mode 100644
index 00000000000..35083293d45
--- /dev/null
+++ b/gdb/config/mips/tx39l.mt
@@ -0,0 +1,5 @@
+# Target: Big-endian mips board, typically an IDT.
+TDEPFILES= mips-tdep.o remote-mips.o dve3900-rom.o monitor.o dsrec.o
+TM_FILE= tm-tx39l.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/vr4100.mt b/gdb/config/mips/vr4100.mt
new file mode 100644
index 00000000000..c5ae4f94a6d
--- /dev/null
+++ b/gdb/config/mips/vr4100.mt
@@ -0,0 +1,5 @@
+# Target: Big-endian SIM monitor board.
+TDEPFILES= mips-tdep.o remote-mips.o
+TM_FILE= tm-vr4100.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/vr4300.mt b/gdb/config/mips/vr4300.mt
new file mode 100644
index 00000000000..22cb25eb425
--- /dev/null
+++ b/gdb/config/mips/vr4300.mt
@@ -0,0 +1,5 @@
+# Target: Big-endian SIM monitor board.
+TDEPFILES= mips-tdep.o remote-mips.o
+TM_FILE= tm-vr4300.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/vr4300el.mt b/gdb/config/mips/vr4300el.mt
new file mode 100644
index 00000000000..cff7241597b
--- /dev/null
+++ b/gdb/config/mips/vr4300el.mt
@@ -0,0 +1,5 @@
+# Target: Little-endian SIM monitor board.
+TDEPFILES= mips-tdep.o remote-mips.o
+TM_FILE= tm-vr4300el.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/vr4xxx.mt b/gdb/config/mips/vr4xxx.mt
new file mode 100644
index 00000000000..4c79ec7552d
--- /dev/null
+++ b/gdb/config/mips/vr4xxx.mt
@@ -0,0 +1,5 @@
+# Target: Big-endian SIM monitor board.
+TDEPFILES= mips-tdep.o remote-mips.o
+TM_FILE= tm-vr4xxx.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/vr4xxxel.mt b/gdb/config/mips/vr4xxxel.mt
new file mode 100644
index 00000000000..5124dd75461
--- /dev/null
+++ b/gdb/config/mips/vr4xxxel.mt
@@ -0,0 +1,5 @@
+# Target: Big-endian SIM monitor board.
+TDEPFILES= mips-tdep.o remote-mips.o
+TM_FILE= tm-vr4xxxel.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/vr5000.mt b/gdb/config/mips/vr5000.mt
new file mode 100644
index 00000000000..7a4a915a12c
--- /dev/null
+++ b/gdb/config/mips/vr5000.mt
@@ -0,0 +1,5 @@
+# Target: Big-endian SIM monitor board.
+TDEPFILES= mips-tdep.o remote-mips.o
+TM_FILE= tm-vr5000.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/vr5000el.mt b/gdb/config/mips/vr5000el.mt
new file mode 100644
index 00000000000..99687edcefc
--- /dev/null
+++ b/gdb/config/mips/vr5000el.mt
@@ -0,0 +1,5 @@
+# Target: Little-endian SIM monitor board.
+TDEPFILES= mips-tdep.o remote-mips.o
+TM_FILE= tm-vr5000el.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/vxmips.mt b/gdb/config/mips/vxmips.mt
new file mode 100644
index 00000000000..a20cf96ab72
--- /dev/null
+++ b/gdb/config/mips/vxmips.mt
@@ -0,0 +1,3 @@
+# Target: MIPS running VxWorks
+TDEPFILES= mips-tdep.o remote-vx.o remote-vxmips.o xdr_ld.o xdr_ptrace.o xdr_rdb.o
+TM_FILE= tm-vxmips.h
diff --git a/gdb/config/mips/wince.mt b/gdb/config/mips/wince.mt
new file mode 100644
index 00000000000..a404b1cec8b
--- /dev/null
+++ b/gdb/config/mips/wince.mt
@@ -0,0 +1,5 @@
+# Target: Little-endian MIPS machine such as DECstation.
+TDEPFILES= mips-tdep.o wince.o
+TM_FILE= tm-wince.h
+MT_CFLAGS=-DMIPS -U_X86_ -U_M_IX86 -U__i386__ -U__i486__ -U__i586__ -U__i686__ -DUNICODE -D_WIN32_WCE -DWINCE_STUB='"${target_alias}-stub.exe"'
+WIN32LIBS=-lrapi
diff --git a/gdb/config/mips/xm-irix3.h b/gdb/config/mips/xm-irix3.h
new file mode 100644
index 00000000000..27da9a53880
--- /dev/null
+++ b/gdb/config/mips/xm-irix3.h
@@ -0,0 +1,30 @@
+/* Copyright 1991, 1993, 1994, 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. */
+
+/* This is for the iris. */
+
+#define HAVE_TERMIO
+
+/* Override register locations in upage for SGI machines */
+#undef REGISTER_U_ADDR
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ if (regno < PC_REGNUM) \
+ addr = regno; \
+ else \
+ addr = regno + NSIG_HNDLRS; /* Skip over signal handlers */
diff --git a/gdb/config/mips/xm-irix4.h b/gdb/config/mips/xm-irix4.h
new file mode 100644
index 00000000000..8e0bfb539ef
--- /dev/null
+++ b/gdb/config/mips/xm-irix4.h
@@ -0,0 +1,34 @@
+/* Definitions for irix4 hosting support.
+
+ Copyright 1991, 1992, 1993, 1994, 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. */
+
+/* This is for the iris. */
+
+#include "mips/xm-irix3.h"
+
+#define BROKEN_SIGINFO_H /* <sys/siginfo.h> si_pid & si_uid are bogus */
+
+/* Irix 4.0.1 and later have termios. Not sure about earlier versions. */
+#undef HAVE_TERMIO
+#define HAVE_TERMIOS
+
+/* This enables reliable signals (and the associated setjmp/longjmp), and gives
+ bsdish prototypes for getpgrp/setpgrg/setgroups and initgroups. */
+#define _BSD_COMPAT
diff --git a/gdb/config/mips/xm-irix5.h b/gdb/config/mips/xm-irix5.h
new file mode 100644
index 00000000000..78c3a071e10
--- /dev/null
+++ b/gdb/config/mips/xm-irix5.h
@@ -0,0 +1,34 @@
+/* Definitions for irix5 hosting support.
+
+ Copyright 1993, 1994, 1995, 1996 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 "xm-sysv4.h"
+
+/* Override register locations in upage for SGI machines */
+#undef REGISTER_U_ADDR
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ if (regno < PC_REGNUM) \
+ addr = regno; \
+ else \
+ addr = regno + NSIG_HNDLRS; /* Skip over signal handlers */
+
+/* This enables reliable signals (and the associated setjmp/longjmp), and gives
+ bsdish prototypes for getpgrp/setpgrg/setgroups and initgroups. */
+#define _BSD_COMPAT
diff --git a/gdb/config/mips/xm-irix6.h b/gdb/config/mips/xm-irix6.h
new file mode 100644
index 00000000000..a8a4c68de54
--- /dev/null
+++ b/gdb/config/mips/xm-irix6.h
@@ -0,0 +1,22 @@
+/* Definitions for irix6 hosting support.
+
+ Copyright 2001 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 "mips/xm-irix5.h"
diff --git a/gdb/config/mips/xm-linux.h b/gdb/config/mips/xm-linux.h
new file mode 100644
index 00000000000..4db6201bc7d
--- /dev/null
+++ b/gdb/config/mips/xm-linux.h
@@ -0,0 +1,25 @@
+/* Host definitions for GNU/Linux on MIPS.
+
+ Copyright 2001, 2002 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. */
+
+#ifndef XM_MIPSLINUX_H
+#define XM_MIPSLINUX_H
+
+#endif /* XM_MIPSLINUX_H */
diff --git a/gdb/config/mips/xm-mips.h b/gdb/config/mips/xm-mips.h
new file mode 100644
index 00000000000..c1f53b53ed9
--- /dev/null
+++ b/gdb/config/mips/xm-mips.h
@@ -0,0 +1,59 @@
+/* Definitions to make GDB run on a mips box under 4.3bsd.
+ Copyright 1986, 1987, 1989, 1993, 1994, 1995, 1996, 1998
+ Free Software Foundation, Inc.
+ Contributed by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin
+ and by Alessandro Forin(af@cs.cmu.edu) at CMU
+
+ 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. */
+
+#ifdef ultrix
+/* Needed for DECstation core files. */
+#include <machine/param.h>
+#define KERNEL_U_ADDR UADDR
+
+/* Native Ultrix cc has broken long long support. */
+#ifndef __GNUC__
+#undef CC_HAS_LONG_LONG
+#endif
+#endif
+
+#if ! defined (__GNUC__) && ! defined (offsetof)
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+#endif
+
+/* Only used for core files on DECstations.
+ First four registers at u.u_ar0 are saved arguments, and
+ there is no r0 saved. Float registers are saved
+ in u_pcb.pcb_fpregs, not relative to u.u_ar0. */
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ { \
+ if (regno < FP0_REGNUM) \
+ addr = blockend + sizeof(int) * (4 + regno - 1); \
+ else \
+ addr = offsetof (struct user, u_pcb.pcb_fpregs[0]) + \
+ sizeof (int) * (regno - FP0_REGNUM); \
+ }
+
+/* Kernel is a bit tenacious about sharing text segments, disallowing bpts. */
+#define ONE_PROCESS_WRITETEXT
+
+/* HAVE_SGTTY also works, last we tried.
+
+ But we have termios, at least as of Ultrix 4.2A, so use it. */
+#define HAVE_TERMIOS
diff --git a/gdb/config/mips/xm-mipsm3.h b/gdb/config/mips/xm-mipsm3.h
new file mode 100644
index 00000000000..b2e9f4d5330
--- /dev/null
+++ b/gdb/config/mips/xm-mipsm3.h
@@ -0,0 +1,29 @@
+/* Definitions to make GDB run on a mips box under 4.3bsd.
+ Copyright 1986, 1987, 1989, 1993 Free Software Foundation, Inc.
+ Contributed by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin
+ and by Alessandro Forin(af@cs.cmu.edu) at CMU
+
+ 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. */
+
+#define KERNEL_U_ADDR 0 /* Not needed. */
+
+/* Only used for core files on DECstations. */
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ if (regno < 38) addr = (NBPG*UPAGES) + (regno - 38)*sizeof(int);\
+ else addr = 0; /* ..somewhere in the pcb */
diff --git a/gdb/config/mips/xm-mipsv4.h b/gdb/config/mips/xm-mipsv4.h
new file mode 100644
index 00000000000..76fa5da19db
--- /dev/null
+++ b/gdb/config/mips/xm-mipsv4.h
@@ -0,0 +1,22 @@
+/* Definitions for MIPS running SVR4 hosting support.
+
+ Copyright 1994 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 "xm-sysv4.h"
diff --git a/gdb/config/mips/xm-riscos.h b/gdb/config/mips/xm-riscos.h
new file mode 100644
index 00000000000..1f03c5a00a8
--- /dev/null
+++ b/gdb/config/mips/xm-riscos.h
@@ -0,0 +1,25 @@
+/* Copyright 1993, 1994, 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. */
+
+#define HAVE_TERMIO
+
+#define USG 1
+
+/* setjmp.h requires uid_t. */
+#include <sys/types.h>
diff --git a/gdb/config/mn10200/mn10200.mt b/gdb/config/mn10200/mn10200.mt
new file mode 100644
index 00000000000..c85a2fb6884
--- /dev/null
+++ b/gdb/config/mn10200/mn10200.mt
@@ -0,0 +1,6 @@
+# Target: Matsushita mn10200
+TDEPFILES= mn10200-tdep.o
+TM_FILE= tm-mn10200.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/mn10200/libsim.a
diff --git a/gdb/config/mn10200/tm-mn10200.h b/gdb/config/mn10200/tm-mn10200.h
new file mode 100644
index 00000000000..4402b78ba79
--- /dev/null
+++ b/gdb/config/mn10200/tm-mn10200.h
@@ -0,0 +1,220 @@
+/* Parameters for execution on a Matsushita mn10200 processor.
+
+ Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software
+ Foundation, Inc.
+
+ Contributed by Geoffrey Noer <noer@cygnus.com>
+
+ 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. */
+
+/* FIXME: cagney/2001-03-01: The below macros refer to functions
+ declared in "regcache.h". The ``correct fix'' is to convert those
+ macros into functions. */
+#include "regcache.h"
+#include "symtab.h" /* For namespace_enum. */
+#include "symfile.h" /* For entry_point_address(). */
+
+/* ints are only 16bits on the mn10200. */
+#undef TARGET_INT_BIT
+#define TARGET_INT_BIT 16
+
+/* The mn10200 doesn't support long long types. */
+#undef TARGET_LONG_LONG_BIT
+#define TARGET_LONG_LONG_BIT 32
+
+/* The mn10200 doesn't support double or long double either. */
+#undef TARGET_DOUBLE_BIT
+#undef TARGET_LONG_DOUBLE_BIT
+#define TARGET_DOUBLE_BIT 32
+#define TARGET_LONG_DOUBLE_BIT 32
+
+/* Not strictly correct, but the machine independent code is not
+ ready to handle any of the basic sizes not being a power of two. */
+#undef TARGET_PTR_BIT
+#define TARGET_PTR_BIT 32
+
+/* The mn10200 really has 24 bit registers but the simulator reads/writes
+ them as 32bit values, so we claim they're 32bits each. This may have
+ to be tweaked if the Matsushita emulator/board really deals with them
+ as 24bits each. */
+#define REGISTER_SIZE 4
+
+#define MAX_REGISTER_RAW_SIZE REGISTER_SIZE
+#define NUM_REGS 11
+
+#define REGISTER_BYTES (NUM_REGS * REGISTER_SIZE)
+
+#define REGISTER_NAMES \
+{ "d0", "d1", "d2", "d3", "a0", "a1", "a2", "sp", \
+ "pc", "mdr", "psw"}
+
+#define FP_REGNUM 6
+#define SP_REGNUM 7
+#define PC_REGNUM 8
+#define MDR_REGNUM 9
+#define PSW_REGNUM 10
+
+/* Treat the registers as 32bit values. */
+#define REGISTER_VIRTUAL_TYPE(REG) builtin_type_long
+
+#define REGISTER_BYTE(REG) ((REG) * REGISTER_SIZE)
+#define REGISTER_VIRTUAL_SIZE(REG) REGISTER_SIZE
+#define REGISTER_RAW_SIZE(REG) REGISTER_SIZE
+
+#define MAX_REGISTER_VIRTUAL_SIZE REGISTER_SIZE
+
+/* The breakpoint instruction must be the same size as te smallest
+ instruction in the instruction set.
+
+ The Matsushita mn10x00 processors have single byte instructions
+ so we need a single byte breakpoint. Matsushita hasn't defined
+ one, so we defined it ourselves.
+
+ 0xff is the only available single byte insn left on the mn10200. */
+#define BREAKPOINT {0xff}
+
+#define FUNCTION_START_OFFSET 0
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Stacks grow the normal way. */
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+#define SAVED_PC_AFTER_CALL(frame) \
+ (read_memory_integer (read_register (SP_REGNUM), REGISTER_SIZE) & 0xffffff)
+
+struct frame_info;
+struct frame_saved_regs;
+struct type;
+struct value;
+
+#define EXTRA_FRAME_INFO struct frame_saved_regs fsr; int status; int stack_size;
+
+extern void mn10200_init_extra_frame_info (struct frame_info *);
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) mn10200_init_extra_frame_info (fi)
+#define INIT_FRAME_PC(x,y)
+
+extern void mn10200_frame_find_saved_regs (struct frame_info *,
+ struct frame_saved_regs *);
+#define FRAME_FIND_SAVED_REGS(fi, regaddr) regaddr = fi->fsr
+
+extern CORE_ADDR mn10200_frame_chain (struct frame_info *);
+#define FRAME_CHAIN(fi) mn10200_frame_chain (fi)
+#define FRAME_CHAIN_VALID(FP, FI) generic_file_frame_chain_valid (FP, FI)
+
+extern CORE_ADDR mn10200_find_callers_reg (struct frame_info *, int);
+extern CORE_ADDR mn10200_frame_saved_pc (struct frame_info *);
+#define FRAME_SAVED_PC(FI) (mn10200_frame_saved_pc (FI))
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. */
+
+#define EXTRACT_RETURN_VALUE(TYPE, REGBUF, VALBUF) \
+ { \
+ if (TYPE_LENGTH (TYPE) > 8) \
+ internal_error (__FILE__, __LINE__, "failed internal consistency check"); \
+ else if (TYPE_LENGTH (TYPE) > 2 && TYPE_CODE (TYPE) != TYPE_CODE_PTR) \
+ { \
+ memcpy (VALBUF, REGBUF + REGISTER_BYTE (0), 2); \
+ memcpy (VALBUF + 2, REGBUF + REGISTER_BYTE (1), 2); \
+ } \
+ else if (TYPE_CODE (TYPE) == TYPE_CODE_PTR)\
+ { \
+ memcpy (VALBUF, REGBUF + REGISTER_BYTE (4), TYPE_LENGTH (TYPE)); \
+ } \
+ else \
+ { \
+ memcpy (VALBUF, REGBUF + REGISTER_BYTE (0), TYPE_LENGTH (TYPE)); \
+ } \
+ }
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+ extract_address (REGBUF + REGISTER_BYTE (4), \
+ REGISTER_RAW_SIZE (4))
+
+#define STORE_RETURN_VALUE(TYPE, VALBUF) \
+ { \
+ if (TYPE_LENGTH (TYPE) > 8) \
+ internal_error (__FILE__, __LINE__, "failed internal consistency check"); \
+ else if (TYPE_LENGTH (TYPE) > 2 && TYPE_CODE (TYPE) != TYPE_CODE_PTR) \
+ { \
+ write_register_bytes (REGISTER_BYTE (0), VALBUF, 2); \
+ write_register_bytes (REGISTER_BYTE (1), VALBUF + 2, 2); \
+ } \
+ else if (TYPE_CODE (TYPE) == TYPE_CODE_PTR)\
+ { \
+ write_register_bytes (REGISTER_BYTE (4), VALBUF, TYPE_LENGTH (TYPE)); \
+ } \
+ else \
+ { \
+ write_register_bytes (REGISTER_BYTE (0), VALBUF, TYPE_LENGTH (TYPE)); \
+ } \
+ }
+
+
+extern CORE_ADDR mn10200_store_struct_return (CORE_ADDR addr, CORE_ADDR sp);
+#define STORE_STRUCT_RETURN(STRUCT_ADDR, SP) \
+ (SP) = mn10200_store_struct_return (STRUCT_ADDR, SP)
+
+extern CORE_ADDR mn10200_skip_prologue (CORE_ADDR);
+#define SKIP_PROLOGUE(pc) (mn10200_skip_prologue (pc))
+
+#define FRAME_ARGS_SKIP 0
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+#define FRAME_NUM_ARGS(fi) (-1)
+
+extern void mn10200_pop_frame (struct frame_info *);
+#define POP_FRAME mn10200_pop_frame (get_current_frame ())
+
+#define USE_GENERIC_DUMMY_FRAMES 1
+#define CALL_DUMMY {0}
+#define CALL_DUMMY_START_OFFSET (0)
+#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
+#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
+#define FIX_CALL_DUMMY(DUMMY, START, FUNADDR, NARGS, ARGS, TYPE, GCCP)
+#define CALL_DUMMY_ADDRESS() entry_point_address ()
+
+extern CORE_ADDR mn10200_push_return_address (CORE_ADDR, CORE_ADDR);
+#define PUSH_RETURN_ADDRESS(PC, SP) mn10200_push_return_address (PC, SP)
+
+#define PUSH_DUMMY_FRAME generic_push_dummy_frame ()
+
+extern CORE_ADDR
+mn10200_push_arguments (int, struct value **, CORE_ADDR,
+ unsigned char, CORE_ADDR);
+#define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \
+ (mn10200_push_arguments (NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR))
+
+#define PC_IN_CALL_DUMMY(PC, SP, FP) generic_pc_in_call_dummy (PC, SP, FP)
+
+#define REG_STRUCT_HAS_ADDR(gcc_p,TYPE) \
+ (TYPE_LENGTH (TYPE) > 8)
+
+extern use_struct_convention_fn mn10200_use_struct_convention;
+#define USE_STRUCT_CONVENTION(GCC_P, TYPE) mn10200_use_struct_convention (GCC_P, TYPE)
+
+/* Override the default get_saved_register function with
+ one that takes account of generic CALL_DUMMY frames. */
+#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \
+ generic_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
+
+/* Define this for Wingdb */
+#define TARGET_MN10200
diff --git a/gdb/config/mn10300/mn10300.mt b/gdb/config/mn10300/mn10300.mt
new file mode 100644
index 00000000000..0b54fd5afdc
--- /dev/null
+++ b/gdb/config/mn10300/mn10300.mt
@@ -0,0 +1,4 @@
+# Target: Matsushita mn10300
+TDEPFILES= mn10300-tdep.o
+SIM_OBS = remote-sim.o
+SIM = ../sim/mn10300/libsim.a
diff --git a/gdb/config/nm-gnu.h b/gdb/config/nm-gnu.h
new file mode 100644
index 00000000000..8f17406abc2
--- /dev/null
+++ b/gdb/config/nm-gnu.h
@@ -0,0 +1,43 @@
+/* Common declarations for the GNU Hurd
+
+ Copyright 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ The GNU Hurd 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, or (at
+ your option) any later version.
+
+ The GNU Hurd 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. */
+
+#ifndef __NM_GNU_H__
+#define __NM_GNU_H__
+
+#include <unistd.h>
+#include <mach.h>
+#include <mach/exception.h>
+#include "regcache.h"
+
+extern char *gnu_target_pid_to_str (int pid);
+
+/* Before storing, we need to read all the registers. */
+#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
+
+/* Don't do wait_for_inferior on attach. */
+#define ATTACH_NO_WAIT
+
+/* Use SVR4 style shared library support */
+#define SVR4_SHARED_LIBS
+#include "solib.h"
+#define NO_CORE_OPS
+
+#endif /* __NM_GNU_H__ */
diff --git a/gdb/config/nm-linux.h b/gdb/config/nm-linux.h
new file mode 100644
index 00000000000..a2d429214d9
--- /dev/null
+++ b/gdb/config/nm-linux.h
@@ -0,0 +1,74 @@
+/* Native support for GNU/Linux.
+
+ Copyright 1999, 2000, 2001, 2002 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. */
+
+/* GNU/Linux is SVR4-ish but its /proc file system isn't. */
+#undef USE_PROC_FS
+
+/* Tell GDB that we can attach and detach other processes. */
+#define ATTACH_DETACH
+
+/* Since we're building a native debugger, we can include <signal.h>
+ to find the range of real-time signals. */
+
+#include <signal.h>
+
+#ifdef __SIGRTMIN
+#define REALTIME_LO __SIGRTMIN
+#define REALTIME_HI (__SIGRTMAX + 1)
+#endif
+
+/* We define this if link.h is available, because with ELF we use SVR4
+ style shared libraries. */
+
+#ifdef HAVE_LINK_H
+#define SVR4_SHARED_LIBS
+#include "solib.h" /* Support for shared libraries. */
+#endif
+
+
+/* Override child_wait in `inftarg.c'. */
+struct target_waitstatus;
+extern ptid_t child_wait (ptid_t ptid, struct target_waitstatus *ourstatus);
+#define CHILD_WAIT
+
+extern int lin_lwp_prepare_to_proceed (void);
+#define PREPARE_TO_PROCEED(select_it) lin_lwp_prepare_to_proceed ()
+
+extern void lin_lwp_attach_lwp (ptid_t ptid, int verbose);
+#define ATTACH_LWP(ptid, verbose) lin_lwp_attach_lwp ((ptid), (verbose))
+
+extern void lin_thread_get_thread_signals (sigset_t *mask);
+#define GET_THREAD_SIGNALS(mask) lin_thread_get_thread_signals (mask)
+
+/* Defined to make stepping-over-breakpoints be thread-atomic. */
+#define USE_THREAD_STEP_NEEDED 1
+
+
+/* Use elf_gregset_t and elf_fpregset_t, rather than
+ gregset_t and fpregset_t. */
+
+#define GDB_GREGSET_T elf_gregset_t
+#define GDB_FPREGSET_T elf_fpregset_t
+
+/* Override child_pid_to_exec_file in 'inftarg.c'. */
+#define CHILD_PID_TO_EXEC_FILE
+
+
diff --git a/gdb/config/nm-lynx.h b/gdb/config/nm-lynx.h
new file mode 100644
index 00000000000..1cd2bd1ceb1
--- /dev/null
+++ b/gdb/config/nm-lynx.h
@@ -0,0 +1,85 @@
+/* Native-dependent definitions for LynxOS.
+ Copyright 1993, 1994, 1995, 1996, 1999, 2000
+ 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. */
+
+#ifndef NM_LYNX_H
+#define NM_LYNX_H
+
+#include <sys/conf.h>
+#include <sys/kernel.h>
+/* sys/kernel.h should define this, but doesn't always, sigh. */
+#ifndef __LYNXOS
+#define __LYNXOS
+#endif
+#include <sys/mem.h>
+#include <sys/signal.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/itimer.h>
+#include <sys/file.h>
+#include <sys/proc.h>
+#include "gdbthread.h"
+
+/* This is the amount to subtract from u.u_ar0 to get the offset in
+ the core file of the register values. */
+
+#define KERNEL_U_ADDR USRSTACK
+
+#undef FLOAT_INFO /* No float info yet */
+
+/* As of LynxOS 2.2.2 (beta 8/15/94), this is int. Previous versions seem to
+ have had no prototype, so I'm not sure why GDB used to define this to
+ char *. */
+#define PTRACE_ARG3_TYPE int
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
+
+#define FETCH_INFERIOR_REGISTERS
+
+/* Thread ID of stopped thread. */
+
+#define WIFTID(x) (((union wait *)&x)->w_tid)
+
+/* Override child_wait in inftarg.c */
+
+#define CHILD_WAIT
+
+/* Override child_resume in infptrace.c */
+
+#define CHILD_RESUME
+
+/* Override child_thread_alive in intarg.c */
+
+#define CHILD_THREAD_ALIVE
+
+#include "target.h"
+
+extern ptid_t child_wait (ptid_t ptid,
+ struct target_waitstatus *status);
+
+/* Lynx needs a special definition of this so that we can
+ print out the pid and thread number seperately. */
+
+
+/* override child_pid_to_str in inftarg.c */
+#define CHILD_PID_TO_STR
+extern char *lynx_pid_to_str (ptid_t ptid);
+
+#endif /* NM_LYNX_H */
diff --git a/gdb/config/nm-m3.h b/gdb/config/nm-m3.h
new file mode 100644
index 00000000000..f89838ed967
--- /dev/null
+++ b/gdb/config/nm-m3.h
@@ -0,0 +1,126 @@
+/* Mach 3.0 common definitions and global vars.
+
+ Copyright 1992, 1993, 1994, 1996 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. */
+
+#ifndef NM_M3_H
+#define NM_M3_H
+
+#include <mach.h>
+#include "regcache.h"
+
+/* Mach3 doesn't declare errno in <errno.h>. */
+extern int errno;
+
+/* Task port of our debugged inferior. */
+
+extern task_t inferior_task;
+
+/* Thread port of the current thread in the inferior. */
+
+extern thread_t current_thread;
+
+/* If nonzero, we must suspend/abort && resume threads
+ * when setting or getting the state.
+ */
+extern int must_suspend_thread;
+
+#define PREPARE_TO_PROCEED(select_it) mach3_prepare_to_proceed(select_it)
+
+/* Try to get the privileged host port for authentication to machid
+
+ * If you can get this, you may debug anything on this host.
+ *
+ * If you can't, gdb gives it's own task port as the
+ * authentication port
+ */
+#define mach_privileged_host_port() task_by_pid(-1)
+
+/*
+ * This is the MIG ID number of the emulator/server bsd_execve() RPC call.
+ *
+ * It SHOULD never change, but if it does, gdb `run'
+ * command won't work until you fix this define.
+ *
+ */
+#define MIG_EXEC_SYSCALL_ID 101000
+
+/* If our_message_port gets a msg with this ID,
+ * GDB suspends it's inferior and enters command level.
+ * (Useful at least if ^C does not work)
+ */
+#define GDB_MESSAGE_ID_STOP 0x41151
+
+/* wait3 WNOHANG is defined in <sys/wait.h> but
+ * for some reason gdb does not want to include
+ * that file.
+ *
+ * If your system defines WNOHANG differently, this has to be changed.
+ */
+#define WNOHANG 1
+
+/* Before storing, we need to read all the registers. */
+
+#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
+
+/* Check if the inferior exists */
+#define MACH_ERROR_NO_INFERIOR \
+ do if (!MACH_PORT_VALID (inferior_task)) \
+ error ("Inferior task does not exist."); while(0)
+
+/* Error handler for mach calls */
+#define CHK(str,ret) \
+ do if (ret != KERN_SUCCESS) \
+ error ("Gdb %s [%d] %s : %s\n",__FILE__,__LINE__,str, \
+ mach_error_string(ret)); while(0)
+
+/* This is from POE9 emulator/emul_stack.h
+ */
+/*
+ * Top of emulator stack holds link and reply port.
+ */
+struct emul_stack_top
+ {
+ struct emul_stack_top *link;
+ mach_port_t reply_port;
+ };
+
+#define EMULATOR_STACK_SIZE (4096*4)
+
+#define THREAD_ALLOWED_TO_BREAK(mid) mach_thread_for_breakpoint (mid)
+
+#define THREAD_PARSE_ID(arg) mach_thread_parse_id (arg)
+
+#define THREAD_OUTPUT_ID(mid) mach_thread_output_id (mid)
+
+#define ATTACH_TO_THREAD attach_to_thread
+
+/* Don't do wait_for_inferior on attach. */
+#define ATTACH_NO_WAIT
+
+/* Do Mach 3 dependent operations when ^C or a STOP is requested */
+#define DO_QUIT() mach3_quit ()
+
+#if 0
+/* This is bogus. It is NOT OK to quit out of target_wait. */
+/* If in mach_msg() and ^C is typed set immediate_quit */
+#define REQUEST_QUIT() mach3_request_quit ()
+#endif
+
+#endif /* NM_M3_H */
diff --git a/gdb/config/nm-nbsd.h b/gdb/config/nm-nbsd.h
new file mode 100644
index 00000000000..5078c567968
--- /dev/null
+++ b/gdb/config/nm-nbsd.h
@@ -0,0 +1,27 @@
+/* Native-dependent definitions for NetBSD.
+ Copyright 1994, 1996, 1999 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. */
+
+#define PTRACE_ARG3_TYPE char*
+
+#define FETCH_INFERIOR_REGISTERS
+
+#define ATTACH_DETACH
+
+#include "solib.h" /* Support for shared libraries. */
diff --git a/gdb/config/nm-nbsdaout.h b/gdb/config/nm-nbsdaout.h
new file mode 100644
index 00000000000..026f1ed8d50
--- /dev/null
+++ b/gdb/config/nm-nbsdaout.h
@@ -0,0 +1,72 @@
+/* Native-dependent definitions for NetBSD a.out.
+ Copyright 1994, 1996, 1999 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. */
+
+/* make structure definitions match up with those expected in solib.c */
+#define link_object sod
+#define lo_name sod_name
+#define lo_library sod_library
+#define lo_unused sod_reserved
+#define lo_major sod_major
+#define lo_minor sod_minor
+#define lo_next sod_next
+
+#define link_map so_map
+#define lm_addr som_addr
+#define lm_name som_path
+#define lm_next som_next
+#define lm_lop som_sod
+#define lm_lob som_sodbase
+#define lm_rwt som_write
+#define lm_ld som_dynamic
+#define lm_lpd som_spd
+
+#define link_dynamic_2 section_dispatch_table
+#define ld_loaded sdt_loaded
+#define ld_need sdt_sods
+#define ld_rules sdt_filler1
+#define ld_got sdt_got
+#define ld_plt sdt_plt
+#define ld_rel sdt_rel
+#define ld_hash sdt_hash
+#define ld_stab sdt_nzlist
+#define ld_stab_hash sdt_filler2
+#define ld_buckets sdt_buckets
+#define ld_symbols sdt_strings
+#define ld_symb_size sdt_str_sz
+#define ld_text sdt_text_sz
+#define ld_plt_sz sdt_plt_sz
+
+#define rtc_symb rt_symbol
+#define rtc_sp rt_sp
+#define rtc_next rt_next
+
+#define ld_debug so_debug
+#define ldd_version dd_version
+#define ldd_in_debugger dd_in_debugger
+#define ldd_sym_loaded dd_sym_loaded
+#define ldd_bp_addr dd_bpt_addr
+#define ldd_bp_inst dd_bpt_shadow
+#define ldd_cp dd_cc
+
+#define link_dynamic _dynamic
+#define ld_version d_version
+#define ldd d_debug
+#define ld_un d_un
+#define ld_2 d_sdt
diff --git a/gdb/config/nm-sysv4.h b/gdb/config/nm-sysv4.h
new file mode 100644
index 00000000000..4b4f09897bc
--- /dev/null
+++ b/gdb/config/nm-sysv4.h
@@ -0,0 +1,34 @@
+/* Definitions for running gdb on a host machine running any flavor of SVR4.
+ Copyright 1991, 1992, 1993, 1998 Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus Support (fnf@cygnus.com).
+
+ 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. */
+
+/* Use SVR4 style shared library support */
+
+#define SVR4_SHARED_LIBS
+#include "solib.h"
+
+/* SVR4 has /proc support, so use it instead of ptrace. */
+
+#define USE_PROC_FS
+
+/* SVR4 machines can easily do attach and detach via /proc (procfs.c)
+ support */
+
+#define ATTACH_DETACH
diff --git a/gdb/config/none/nm-none.h b/gdb/config/none/nm-none.h
new file mode 100644
index 00000000000..7647bdb1d6d
--- /dev/null
+++ b/gdb/config/none/nm-none.h
@@ -0,0 +1,19 @@
+/* Defines needed when configuring for "none".
+ Copyright 1993 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. */
diff --git a/gdb/config/none/none.mh b/gdb/config/none/none.mh
new file mode 100644
index 00000000000..33d5e4a3768
--- /dev/null
+++ b/gdb/config/none/none.mh
@@ -0,0 +1,5 @@
+# Host: "no target". This can be used to build you
+# a Makefile that only runs administrative commands like 'clean',
+# 'gdb.tar.Z', etc.
+NAT_FILE= nm-none.h
+XM_FILE= xm-none.h
diff --git a/gdb/config/none/none.mt b/gdb/config/none/none.mt
new file mode 100644
index 00000000000..300e2dcd05f
--- /dev/null
+++ b/gdb/config/none/none.mt
@@ -0,0 +1,4 @@
+# Target: "no target".
+# This can be used to build you a Makefile that only runs administrative
+# commands like 'clean', 'gdb.tar.Z', etc.
+TM_FILE= tm-none.h
diff --git a/gdb/config/none/tm-none.h b/gdb/config/none/tm-none.h
new file mode 100644
index 00000000000..3db049a2cd4
--- /dev/null
+++ b/gdb/config/none/tm-none.h
@@ -0,0 +1,24 @@
+/* Defines needed when configuring for "none".
+ Copyright 1993, 1998 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. */
+
+/* This define is needed so that "gcc -MM" doesn't get errors and fail on
+ source files that use the value of INNER_THAN in preprocessor lines. */
+
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
diff --git a/gdb/config/none/xm-none.h b/gdb/config/none/xm-none.h
new file mode 100644
index 00000000000..7647bdb1d6d
--- /dev/null
+++ b/gdb/config/none/xm-none.h
@@ -0,0 +1,19 @@
+/* Defines needed when configuring for "none".
+ Copyright 1993 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. */
diff --git a/gdb/config/ns32k/nbsdaout.mh b/gdb/config/ns32k/nbsdaout.mh
new file mode 100644
index 00000000000..8cf47816a1e
--- /dev/null
+++ b/gdb/config/ns32k/nbsdaout.mh
@@ -0,0 +1,5 @@
+# Host: PC532 running NetBSD
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o ns32knbsd-nat.o \
+ solib.o solib-sunos.o
+XM_FILE= xm-nbsd.h
+NAT_FILE= nm-nbsdaout.h
diff --git a/gdb/config/ns32k/nbsdaout.mt b/gdb/config/ns32k/nbsdaout.mt
new file mode 100644
index 00000000000..24418f4e8dc
--- /dev/null
+++ b/gdb/config/ns32k/nbsdaout.mt
@@ -0,0 +1,3 @@
+# Target: PC532 running NetBSD
+TDEPFILES= ns32k-tdep.o ns32knbsd-tdep.o
+TM_FILE= tm-nbsd.h
diff --git a/gdb/config/ns32k/nm-nbsd.h b/gdb/config/ns32k/nm-nbsd.h
new file mode 100644
index 00000000000..4e1e13b9e3e
--- /dev/null
+++ b/gdb/config/ns32k/nm-nbsd.h
@@ -0,0 +1,37 @@
+/* Native-dependent definitions for ns32k running NetBSD, for GDB.
+ Copyright 1986, 1987, 1989, 1992, 1994, 2000
+ 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. */
+
+#ifndef NM_NBSD_H
+#define NM_NBSD_H
+
+/* Get generic NetBSD native definitions. */
+#include "config/nm-nbsd.h"
+
+#if 0
+#define FLOAT_INFO { extern ns32k_float_info(); ns32k_float_info(); }
+#endif
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = ns32k_register_u_addr ((blockend),(regno));
+
+extern int ns32k_register_u_addr (int, int);
+
+#endif /* NM_NBSD_H */
diff --git a/gdb/config/ns32k/nm-nbsdaout.h b/gdb/config/ns32k/nm-nbsdaout.h
new file mode 100644
index 00000000000..aed3c7f3562
--- /dev/null
+++ b/gdb/config/ns32k/nm-nbsdaout.h
@@ -0,0 +1,30 @@
+/* Native-dependent definitions for ns32k running NetBSD, for GDB.
+ Copyright 1986, 1987, 1989, 1992, 1994, 2000, 2002
+ 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. */
+
+#ifndef NM_NBSDAOUT_H
+#define NM_NBSDAOUT_H
+
+#include "ns32k/nm-nbsd.h"
+
+/* Get generic NetBSD native definitions. */
+#include "config/nm-nbsdaout.h"
+
+#endif /* NM_NBSDAOUT_H */
diff --git a/gdb/config/ns32k/tm-nbsd.h b/gdb/config/ns32k/tm-nbsd.h
new file mode 100644
index 00000000000..88b4e226942
--- /dev/null
+++ b/gdb/config/ns32k/tm-nbsd.h
@@ -0,0 +1,37 @@
+/* Macro definitions for ns32k running under NetBSD.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994
+ 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. */
+
+#ifndef TM_NBSD_H
+#define TM_NBSD_H
+
+/* Override number of expected traps from sysv. */
+#define START_INFERIOR_TRAPS_EXPECTED 2
+
+/* Most definitions from umax could be used. */
+
+#include "ns32k/tm-ns32k.h"
+
+/* Saved Pc. Get it from sigcontext if within sigtramp. */
+
+/* Offset to saved PC in sigcontext, from <machine/signal.h>. */
+#define SIGCONTEXT_PC_OFFSET 20
+
+#endif /* TM_NBSD_H */
diff --git a/gdb/config/ns32k/tm-ns32k.h b/gdb/config/ns32k/tm-ns32k.h
new file mode 100644
index 00000000000..cd1594294fc
--- /dev/null
+++ b/gdb/config/ns32k/tm-ns32k.h
@@ -0,0 +1,39 @@
+/* Definitions to make GDB run on an encore under umax 4.2
+ Copyright 1987, 1989, 1991, 1993, 1994, 1998, 1999, 2000, 2001, 2002
+ 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. */
+
+#ifndef TM_NS32K_H
+#define TM_NS32K_H
+
+#define GDB_MULTI_ARCH GDB_MULTI_ARCH_PARTIAL
+
+/* Need to get function ends by adding this to epilogue address from .bf
+ record, not using x_fsize field. */
+#define FUNCTION_EPILOGUE_SIZE 4
+
+/* Address of end of stack space. */
+
+#ifndef STACK_END_ADDR
+#define STACK_END_ADDR (0xfffff000)
+#endif
+
+#define NUM_GENERAL_REGS 8
+
+#endif /* TM_NS32K_H */
diff --git a/gdb/config/ns32k/xm-nbsd.h b/gdb/config/ns32k/xm-nbsd.h
new file mode 100644
index 00000000000..23a0650d280
--- /dev/null
+++ b/gdb/config/ns32k/xm-nbsd.h
@@ -0,0 +1,22 @@
+/* Parameters for execution on a ns32k running NetBSD, for GDB.
+ Copyright 1994 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. */
+
+/* Get generic NetBSD host definitions. */
+#include "xm-nbsd.h"
diff --git a/gdb/config/pa/hppa64.mt b/gdb/config/pa/hppa64.mt
new file mode 100644
index 00000000000..d55da773422
--- /dev/null
+++ b/gdb/config/pa/hppa64.mt
@@ -0,0 +1,4 @@
+# Target: HP PA-RISC 2.0 running HPUX 11.00 in wide mode
+TDEPFILES= hppa-tdep.o
+TM_FILE= tm-hppa64.h
+TM_CLIBS=
diff --git a/gdb/config/pa/hppabsd.mh b/gdb/config/pa/hppabsd.mh
new file mode 100644
index 00000000000..d4a152d03e5
--- /dev/null
+++ b/gdb/config/pa/hppabsd.mh
@@ -0,0 +1,4 @@
+# Host: Hewlett-Packard PA-RISC machine, running BSD
+XM_FILE= xm-hppab.h
+NAT_FILE= nm-hppab.h
+NATDEPFILES= hppab-nat.o corelow.o core-aout.o inftarg.o fork-child.o somread.o infptrace.o hpread.o somsolib.o
diff --git a/gdb/config/pa/hppabsd.mt b/gdb/config/pa/hppabsd.mt
new file mode 100644
index 00000000000..0fc0380c26a
--- /dev/null
+++ b/gdb/config/pa/hppabsd.mt
@@ -0,0 +1,3 @@
+# Target: HP PA-RISC running bsd
+TDEPFILES= hppa-tdep.o
+TM_FILE= tm-hppab.h
diff --git a/gdb/config/pa/hppahpux.mh b/gdb/config/pa/hppahpux.mh
new file mode 100644
index 00000000000..c0520576afb
--- /dev/null
+++ b/gdb/config/pa/hppahpux.mh
@@ -0,0 +1,8 @@
+# Host: Hewlett-Packard PA-RISC machine, running HPUX
+
+XM_FILE= xm-hppah.h
+
+NAT_FILE= nm-hppah.h
+NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o somread.o infptrace.o hpread.o somsolib.o
+
+HOST_IPC=-DBSD_IPC -DPOSIX_WAIT
diff --git a/gdb/config/pa/hppahpux.mt b/gdb/config/pa/hppahpux.mt
new file mode 100644
index 00000000000..dddb3f569a2
--- /dev/null
+++ b/gdb/config/pa/hppahpux.mt
@@ -0,0 +1,3 @@
+# Target: HP PA-RISC running hpux
+TDEPFILES= hppa-tdep.o
+TM_FILE= tm-hppah.h
diff --git a/gdb/config/pa/hppaosf.mh b/gdb/config/pa/hppaosf.mh
new file mode 100644
index 00000000000..d6dd2822d35
--- /dev/null
+++ b/gdb/config/pa/hppaosf.mh
@@ -0,0 +1,5 @@
+# Host: Hewlett-Packard PA-RISC machine, running BSD
+XM_FILE= xm-hppab.h
+NAT_FILE= nm-hppao.h
+NATDEPFILES= fork-child.o m3-nat.o hppam3-nat.o somread.o hpread.o somsolib.o
+NAT_CLIBS= -lmachid -lnetname -lmach
diff --git a/gdb/config/pa/hppaosf.mt b/gdb/config/pa/hppaosf.mt
new file mode 100644
index 00000000000..675402387b6
--- /dev/null
+++ b/gdb/config/pa/hppaosf.mt
@@ -0,0 +1,3 @@
+# Target: HP PA-RISC running OSF1
+TDEPFILES= hppa-tdep.o
+TM_FILE= tm-hppao.h
diff --git a/gdb/config/pa/hppapro.mt b/gdb/config/pa/hppapro.mt
new file mode 100644
index 00000000000..4851b1896e7
--- /dev/null
+++ b/gdb/config/pa/hppapro.mt
@@ -0,0 +1,3 @@
+# Target: PA based debug monitor
+TDEPFILES= hppa-tdep.o op50-rom.o w89k-rom.o monitor.o xmodem.o dsrec.o
+TM_FILE= tm-pro.h
diff --git a/gdb/config/pa/hpux1020.mh b/gdb/config/pa/hpux1020.mh
new file mode 100644
index 00000000000..18f542ee885
--- /dev/null
+++ b/gdb/config/pa/hpux1020.mh
@@ -0,0 +1,14 @@
+# Host: Hewlett-Packard PA-RISC machine, running HPUX 10.20
+
+# FIXME: cagney/2002-04-07: gdb/366: The -Dvfork=fork hack below is
+# stop GDB hanging on HP/UX. For some reason vfork() hangs yet fork()
+# doesn't ....
+
+MH_CFLAGS = -D__HP_CURSES -Dvfork=fork
+
+XM_FILE= xm-hppah.h
+
+NAT_FILE= nm-hppah.h
+NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o infptrace.o somread.o hpread.o somsolib.o
+
+HOST_IPC=-DBSD_IPC -DPOSIX_WAIT
diff --git a/gdb/config/pa/hpux1020.mt b/gdb/config/pa/hpux1020.mt
new file mode 100644
index 00000000000..a856d8c1d1d
--- /dev/null
+++ b/gdb/config/pa/hpux1020.mt
@@ -0,0 +1,3 @@
+# Target: HP PA-RISC running hpux
+TDEPFILES= hppa-tdep.o remote-pa.o somsolib.o corelow.o
+TM_FILE= tm-hppah.h
diff --git a/gdb/config/pa/hpux11.mh b/gdb/config/pa/hpux11.mh
new file mode 100644
index 00000000000..25504e030c9
--- /dev/null
+++ b/gdb/config/pa/hpux11.mh
@@ -0,0 +1,14 @@
+# Host: Hewlett-Packard PA-RISC machine, running HPUX 11.00
+
+# FIXME: cagney/2002-04-07: gdb/366: The -Dvfork=fork hack below is
+# stop GDB hanging on HP/UX. For some reason vfork() hangs yet fork()
+# doesn't ....
+
+MH_CFLAGS = -D__HP_CURSES -Dvfork=fork
+
+XM_FILE= xm-hppah.h
+
+NAT_FILE= nm-hppah11.h
+NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o infttrace.o somread.o hpread.o somsolib.o
+
+HOST_IPC=-DBSD_IPC -DPOSIX_WAIT
diff --git a/gdb/config/pa/hpux11.mt b/gdb/config/pa/hpux11.mt
new file mode 100644
index 00000000000..405f73a791a
--- /dev/null
+++ b/gdb/config/pa/hpux11.mt
@@ -0,0 +1,3 @@
+# Target: HP PA-RISC running HPUX 11.00
+TDEPFILES= hppa-tdep.o remote-pa.o somsolib.o
+TM_FILE= tm-hppah.h
diff --git a/gdb/config/pa/hpux11w.mh b/gdb/config/pa/hpux11w.mh
new file mode 100644
index 00000000000..cd897aa866b
--- /dev/null
+++ b/gdb/config/pa/hpux11w.mh
@@ -0,0 +1,14 @@
+# Host: Hewlett-Packard PA-RISC machine, running HPUX 11.00
+
+# FIXME: cagney/2002-04-07: gdb/366: The -Dvfork=fork hack below is
+# stop GDB hanging on HP/UX. For some reason vfork() hangs yet fork()
+# doesn't ....
+
+MH_CFLAGS = -D__HP_CURSES -Dvfork=fork
+
+XM_FILE= xm-hppah.h
+
+NAT_FILE= nm-hppah11.h
+NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o infttrace.o hpread.o pa64solib.o solib.o
+
+HOST_IPC=-DBSD_IPC -DPOSIX_WAIT
diff --git a/gdb/config/pa/hpux11w.mt b/gdb/config/pa/hpux11w.mt
new file mode 100644
index 00000000000..4064d20fa75
--- /dev/null
+++ b/gdb/config/pa/hpux11w.mt
@@ -0,0 +1,3 @@
+# Target: HP PA-RISC running HPUX 11.00
+TDEPFILES= hppa-tdep.o remote-pa.o
+TM_FILE= tm-hppah.h
diff --git a/gdb/config/pa/nm-hppab.h b/gdb/config/pa/nm-hppab.h
new file mode 100644
index 00000000000..995e8e773d5
--- /dev/null
+++ b/gdb/config/pa/nm-hppab.h
@@ -0,0 +1,137 @@
+/* HPPA PA-RISC machine native support for BSD, for GDB.
+ Copyright 1991, 1992, 1993, 1994, 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 "somsolib.h"
+#include "regcache.h"
+
+#define U_REGS_OFFSET 0
+
+#define KERNEL_U_ADDR 0
+
+/* What a coincidence! */
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+{ addr = (int)(blockend) + REGISTER_BYTE (regno);}
+
+/* 3rd argument to ptrace is supposed to be a caddr_t. */
+
+#define PTRACE_ARG3_TYPE caddr_t
+
+/* HPUX 8.0, in its infinite wisdom, has chosen to prototype ptrace
+ with five arguments, so programs written for normal ptrace lose. */
+#define FIVE_ARG_PTRACE
+
+
+/* This macro defines the register numbers (from REGISTER_NAMES) that
+ are effectively unavailable to the user through ptrace(). It allows
+ us to include the whole register set in REGISTER_NAMES (inorder to
+ better support remote debugging). If it is used in
+ fetch/store_inferior_registers() gdb will not complain about I/O errors
+ on fetching these registers. If all registers in REGISTER_NAMES
+ are available, then return false (0). */
+
+#define CANNOT_STORE_REGISTER(regno) \
+ ((regno) == 0) || \
+ ((regno) == PCSQ_HEAD_REGNUM) || \
+ ((regno) >= PCSQ_TAIL_REGNUM && (regno) < IPSW_REGNUM) || \
+ ((regno) > IPSW_REGNUM && (regno) < FP4_REGNUM)
+
+/* fetch_inferior_registers is in hppab-nat.c. */
+#define FETCH_INFERIOR_REGISTERS
+
+/* attach/detach works to some extent under BSD and HPUX. So long
+ as the process you're attaching to isn't blocked waiting on io,
+ blocked waiting on a signal, or in a system call things work
+ fine. (The problems in those cases are related to the fact that
+ the kernel can't provide complete register information for the
+ target process... Which really pisses off GDB.) */
+
+#define ATTACH_DETACH
+
+/* The PA-BSD kernel has support for using the data memory break bit
+ to implement fast watchpoints.
+
+ Watchpoints on the PA act much like traditional page protection
+ schemes, but with some notable differences.
+
+ First, a special bit in the page table entry is used to cause
+ a trap when a specific page is written to. This avoids having
+ to overload watchpoints on the page protection bits. This makes
+ it possible for the kernel to easily decide if a trap was caused
+ by a watchpoint or by the user writing to protected memory and can
+ signal the user program differently in each case.
+
+ Second, the PA has a bit in the processor status word which causes
+ data memory breakpoints (aka watchpoints) to be disabled for a single
+ instruction. This bit can be used to avoid the overhead of unprotecting
+ and reprotecting pages when it becomes necessary to step over a watchpoint.
+
+
+ When the kernel receives a trap indicating a write to a page which
+ is being watched, the kernel performs a couple of simple actions. First
+ is sets the magic "disable memory breakpoint" bit in the processor
+ status word, it then sends a SIGTRAP to the process which caused the
+ trap.
+
+ GDB will take control and catch the signal for the inferior. GDB then
+ examines the PSW-X bit to determine if the SIGTRAP was caused by a
+ watchpoint firing. If so GDB single steps the inferior over the
+ instruction which caused the watchpoint to trigger (note because the
+ kernel disabled the data memory break bit for one instruction no trap
+ will be taken!). GDB will then determines the appropriate action to
+ take. (this may include restarting the inferior if the watchpoint
+ fired because of a write to an address on the same page as a watchpoint,
+ but no write to the watched address occured). */
+
+#define TARGET_HAS_HARDWARE_WATCHPOINTS /* Enable the code in procfs.c */
+
+/* The PA can watch any number of locations, there's no need for it to reject
+ anything (generic routines already check that all intermediates are
+ in memory). */
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \
+ ((type) == bp_hardware_watchpoint)
+
+/* When a hardware watchpoint fires off the PC will be left at the
+ instruction which caused the watchpoint. It will be necessary for
+ GDB to step over the watchpoint.
+
+ On a PA running BSD, it is trivial to identify when it will be
+ necessary to step over a hardware watchpoint as we can examine
+ the PSW-X bit. If the bit is on, then we trapped because of a
+ watchpoint, else we trapped for some other reason. */
+#define STOPPED_BY_WATCHPOINT(W) \
+ ((W).kind == TARGET_WAITKIND_STOPPED \
+ && (W).value.sig == TARGET_SIGNAL_TRAP \
+ && ((int) read_register (IPSW_REGNUM) & 0x00100000))
+
+/* The PA can single step over a watchpoint if the kernel has set the
+ "X" bit in the processor status word (disable data memory breakpoint
+ for one instruction).
+
+ The kernel will always set this bit before notifying the inferior
+ that it hit a watchpoint. Thus, the inferior can single step over
+ the instruction which caused the watchpoint to fire. This avoids
+ the traditional need to disable the watchpoint, step the inferior,
+ then enable the watchpoint again. */
+#define HAVE_STEPPABLE_WATCHPOINT
+
+/* Use these macros for watchpoint insertion/deletion. */
+/* type can be 0: write watch, 1: read watch, 2: access watch (read/write) */
+#define target_insert_watchpoint(addr, len, type) hppa_set_watchpoint (addr, len, 1)
+#define target_remove_watchpoint(addr, len, type) hppa_set_watchpoint (addr, len, 0)
diff --git a/gdb/config/pa/nm-hppah.h b/gdb/config/pa/nm-hppah.h
new file mode 100644
index 00000000000..4894a049a08
--- /dev/null
+++ b/gdb/config/pa/nm-hppah.h
@@ -0,0 +1,287 @@
+/* Native support for HPPA-RISC machine running HPUX, for GDB.
+ Copyright 1991, 1992, 1994, 1996, 1998, 1999, 2000
+ 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. */
+
+#define U_REGS_OFFSET 0
+
+#define KERNEL_U_ADDR 0
+
+/* What a coincidence! */
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+{ addr = (int)(blockend) + REGISTER_BYTE (regno);}
+
+/* This isn't really correct, because ptrace is actually a 32-bit
+ interface. However, the modern HP-UX targets all really use
+ ttrace, which is a 64-bit interface --- a debugger running in
+ either 32- or 64-bit mode can debug a 64-bit process. BUT, the
+ code doesn't use ttrace directly --- it calls call_ptrace instead,
+ which is supposed to be drop-in substitute for ptrace. In other
+ words, they access a 64-bit system call (ttrace) through a
+ compatibility layer which is allegedly a 32-bit interface.
+
+ So I don't feel the least bit guilty about this. */
+#define PTRACE_ARG3_TYPE CORE_ADDR
+
+/* HPUX 8.0, in its infinite wisdom, has chosen to prototype ptrace
+ with five arguments, so programs written for normal ptrace lose. */
+#define FIVE_ARG_PTRACE
+
+/* We need to figure out where the text region is so that we use the
+ appropriate ptrace operator to manipulate text. Simply reading/writing
+ user space will crap out HPUX. */
+#define NEED_TEXT_START_END 1
+
+/* This macro defines the register numbers (from REGISTER_NAMES) that
+ are effectively unavailable to the user through ptrace(). It allows
+ us to include the whole register set in REGISTER_NAMES (inorder to
+ better support remote debugging). If it is used in
+ fetch/store_inferior_registers() gdb will not complain about I/O errors
+ on fetching these registers. If all registers in REGISTER_NAMES
+ are available, then return false (0). */
+
+#define CANNOT_STORE_REGISTER(regno) \
+ ((regno) == 0) || \
+ ((regno) == PCSQ_HEAD_REGNUM) || \
+ ((regno) >= PCSQ_TAIL_REGNUM && (regno) < IPSW_REGNUM) || \
+ ((regno) > IPSW_REGNUM && (regno) < FP4_REGNUM)
+
+/* In hppah-nat.c: */
+#define FETCH_INFERIOR_REGISTERS
+#define CHILD_XFER_MEMORY
+#define CHILD_POST_FOLLOW_INFERIOR_BY_CLONE
+#define CHILD_POST_FOLLOW_VFORK
+
+/* While this is for use by threaded programs, it doesn't appear
+ * to hurt non-threaded ones. This is used in infrun.c: */
+#define PREPARE_TO_PROCEED(select_it) hppa_prepare_to_proceed()
+extern int hppa_prepare_to_proceed (void);
+
+/* In infptrace.c or infttrace.c: */
+#define CHILD_PID_TO_EXEC_FILE
+#define CHILD_POST_STARTUP_INFERIOR
+#define CHILD_ACKNOWLEDGE_CREATED_INFERIOR
+#define CHILD_INSERT_FORK_CATCHPOINT
+#define CHILD_REMOVE_FORK_CATCHPOINT
+#define CHILD_INSERT_VFORK_CATCHPOINT
+#define CHILD_REMOVE_VFORK_CATCHPOINT
+#define CHILD_HAS_FORKED
+#define CHILD_HAS_VFORKED
+#define CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC
+#define CHILD_INSERT_EXEC_CATCHPOINT
+#define CHILD_REMOVE_EXEC_CATCHPOINT
+#define CHILD_HAS_EXECD
+#define CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL
+#define CHILD_HAS_SYSCALL_EVENT
+#define CHILD_POST_ATTACH
+#define CHILD_THREAD_ALIVE
+#define CHILD_PID_TO_STR
+
+#define REQUIRE_ATTACH(pid) hppa_require_attach(pid)
+extern int hppa_require_attach (int);
+
+#define REQUIRE_DETACH(pid,signal) hppa_require_detach(pid,signal)
+extern int hppa_require_detach (int, int);
+
+/* So we can cleanly use code in infptrace.c. */
+#define PT_KILL PT_EXIT
+#define PT_STEP PT_SINGLE
+#define PT_CONTINUE PT_CONTIN
+
+/* FIXME HP MERGE : Previously, PT_RDUAREA. this is actually fixed
+ in gdb-hp-snapshot-980509 */
+#define PT_READ_U PT_RUAREA
+#define PT_WRITE_U PT_WUAREA
+#define PT_READ_I PT_RIUSER
+#define PT_READ_D PT_RDUSER
+#define PT_WRITE_I PT_WIUSER
+#define PT_WRITE_D PT_WDUSER
+
+/* attach/detach works to some extent under BSD and HPUX. So long
+ as the process you're attaching to isn't blocked waiting on io,
+ blocked waiting on a signal, or in a system call things work
+ fine. (The problems in those cases are related to the fact that
+ the kernel can't provide complete register information for the
+ target process... Which really pisses off GDB.) */
+
+#define ATTACH_DETACH
+
+/* In infptrace or infttrace.c: */
+
+/* Starting with HP-UX 10.30, support is provided (in the form of
+ ttrace requests) for memory-protection-based hardware watchpoints.
+
+ The 10.30 implementation of these functions reside in infttrace.c.
+
+ Stubs of these functions will be provided in infptrace.c, so that
+ 10.20 will at least link. However, the "can I use a fast watchpoint?"
+ query will always return "No" for 10.20. */
+
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+
+/* The PA can watch any number of locations (generic routines already check
+ that all intermediates are in watchable memory locations). */
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \
+ hppa_can_use_hw_watchpoint(type, cnt, ot)
+
+/* The PA can also watch memory regions of arbitrary size, since we're using
+ a page-protection scheme. (On some targets, apparently watch registers
+ are used, which can only accomodate regions of REGISTER_SIZE.) */
+#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(byte_count) \
+ (1)
+
+/* However, some addresses may not be profitable to use hardware to watch,
+ or may be difficult to understand when the addressed object is out of
+ scope, and hence should be unwatched. On some targets, this may have
+ severe performance penalties, such that we might as well use regular
+ watchpoints, and save (possibly precious) hardware watchpoints for other
+ locations.
+
+ On HP-UX, we choose not to watch stack-based addresses, because
+
+ [1] Our implementation relies on page protection traps. The granularity
+ of these is large and so can generate many false hits, which are expensive
+ to respond to.
+
+ [2] Watches of "*p" where we may not know the symbol that p points to,
+ make it difficult to know when the addressed object is out of scope, and
+ hence shouldn't be watched. Page protection that isn't removed when the
+ addressed object is out of scope will either degrade execution speed
+ (false hits) or give false triggers (when the address is recycled by
+ other calls).
+
+ Since either of these points results in a slow-running inferior, we might
+ as well use normal watchpoints, aka single-step & test. */
+#define TARGET_RANGE_PROFITABLE_FOR_HW_WATCHPOINT(pid,start,len) \
+ hppa_range_profitable_for_hw_watchpoint(pid, start, (LONGEST)(len))
+
+/* On HP-UX, we're using page-protection to implement hardware watchpoints.
+ When an instruction attempts to write to a write-protected memory page,
+ a SIGBUS is raised. At that point, the write has not actually occurred.
+
+ We must therefore remove page-protections; single-step the inferior (to
+ allow the write to happen); restore page-protections; and check whether
+ any watchpoint triggered.
+
+ If none did, then the write was to a "nearby" location that just happens
+ to fall on the same page as a watched location, and so can be ignored.
+
+ The only intended client of this macro is wait_for_inferior(), in infrun.c.
+ When HAVE_NONSTEPPABLE_WATCHPOINT is true, that function will take care
+ of the stepping & etc. */
+
+#define STOPPED_BY_WATCHPOINT(W) \
+ ((W.kind == TARGET_WAITKIND_STOPPED) && \
+ (stop_signal == TARGET_SIGNAL_BUS) && \
+ ! stepped_after_stopped_by_watchpoint && \
+ bpstat_have_active_hw_watchpoints ())
+
+/* When a hardware watchpoint triggers, we'll move the inferior past it
+ by removing all eventpoints; stepping past the instruction that caused
+ the trigger; reinserting eventpoints; and checking whether any watched
+ location changed. */
+#define HAVE_NONSTEPPABLE_WATCHPOINT
+
+/* Our implementation of "hardware" watchpoints uses memory page-protection
+ faults. However, HP-UX has unfortunate interactions between these and
+ system calls; basically, it's unsafe to have page protections on when a
+ syscall is running. Therefore, we also ask for notification of syscall
+ entries and returns. When the inferior enters a syscall, we disable
+ h/w watchpoints. When the inferior returns from a syscall, we reenable
+ h/w watchpoints.
+
+ infptrace.c supplies dummy versions of these; infttrace.c is where the
+ meaningful implementations are.
+ */
+#define TARGET_ENABLE_HW_WATCHPOINTS(pid) \
+ hppa_enable_page_protection_events (pid)
+extern void hppa_enable_page_protection_events (int);
+
+#define TARGET_DISABLE_HW_WATCHPOINTS(pid) \
+ hppa_disable_page_protection_events (pid)
+extern void hppa_disable_page_protection_events (int);
+
+/* Use these macros for watchpoint insertion/deletion. */
+#define target_insert_watchpoint(addr, len, type) \
+ hppa_insert_hw_watchpoint (PIDGET (inferior_ptid), addr, (LONGEST)(len), type)
+
+#define target_remove_watchpoint(addr, len, type) \
+ hppa_remove_hw_watchpoint (PIDGET (inferior_ptid), addr, (LONGEST)(len), type)
+
+/* We call our k-thread processes "threads", rather
+ * than processes. So we need a new way to print
+ * the string. Code is in hppah-nat.c.
+ */
+
+extern char *child_pid_to_str (ptid_t);
+
+#define target_tid_to_str( ptid ) \
+ hppa_tid_to_str( ptid )
+extern char *hppa_tid_to_str (ptid_t);
+
+/* For this, ID can be either a process or thread ID, and the function
+ will describe it appropriately, returning the description as a printable
+ string.
+
+ The function that implements this macro is defined in infptrace.c and
+ infttrace.c.
+ */
+#define target_pid_or_tid_to_str(ID) \
+ hppa_pid_or_tid_to_str (ID)
+extern char *hppa_pid_or_tid_to_str (ptid_t);
+
+/* This is used when handling events caused by a call to vfork(). On ptrace-
+ based HP-UXs, when you resume the vforked child, the parent automagically
+ begins running again. To prevent this runaway, this function is used.
+
+ Note that for vfork on HP-UX, we receive three events of interest:
+
+ 1. the vfork event for the new child process
+ 2. the exit or exec event of the new child process (actually, you get
+ two exec events on ptrace-based HP-UXs)
+ 3. the vfork event for the original parent process
+
+ The first is always received first. The other two may be received in any
+ order; HP-UX doesn't guarantee an order.
+ */
+#define ENSURE_VFORKING_PARENT_REMAINS_STOPPED(PID) \
+ hppa_ensure_vforking_parent_remains_stopped (PID)
+extern void hppa_ensure_vforking_parent_remains_stopped (int);
+
+/* This is used when handling events caused by a call to vfork().
+
+ On ttrace-based HP-UXs, the parent vfork and child exec arrive more or less
+ together. That is, you could do two wait()s without resuming either parent
+ or child, and get both events.
+
+ On ptrace-based HP-UXs, you must resume the child after its exec event is
+ delivered or you won't get the parent's vfork. I.e., you can't just wait()
+ and get the parent vfork, after receiving the child exec.
+ */
+#define RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK() \
+ hppa_resume_execd_vforking_child_to_get_parent_vfork ()
+extern int hppa_resume_execd_vforking_child_to_get_parent_vfork (void);
+
+#define HPUXHPPA
+
+#define MAY_SWITCH_FROM_INFERIOR_PID (1)
+
+#define MAY_FOLLOW_EXEC (1)
+
+#define USE_THREAD_STEP_NEEDED (1)
diff --git a/gdb/config/pa/nm-hppah11.h b/gdb/config/pa/nm-hppah11.h
new file mode 100644
index 00000000000..2c2b507a436
--- /dev/null
+++ b/gdb/config/pa/nm-hppah11.h
@@ -0,0 +1,23 @@
+/* Native support for HPPA-RISC machine running HPUX 11.x, for GDB.
+ Copyright 1998 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. */
+
+#define GDB_NATIVE_HPUX_11
+
+#include "pa/nm-hppah.h"
diff --git a/gdb/config/pa/nm-hppao.h b/gdb/config/pa/nm-hppao.h
new file mode 100644
index 00000000000..11e13e7dbca
--- /dev/null
+++ b/gdb/config/pa/nm-hppao.h
@@ -0,0 +1,57 @@
+/* HPPA PA-RISC machine native support for Lites, for GDB.
+ 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 "nm-m3.h"
+#define U_REGS_OFFSET 0
+
+#define KERNEL_U_ADDR 0
+
+/* What a coincidence! */
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+{ addr = (int)(blockend) + REGISTER_BYTE (regno);}
+
+/* This macro defines the register numbers (from REGISTER_NAMES) that
+ are effectively unavailable to the user through ptrace(). It allows
+ us to include the whole register set in REGISTER_NAMES (inorder to
+ better support remote debugging). If it is used in
+ fetch/store_inferior_registers() gdb will not complain about I/O errors
+ on fetching these registers. If all registers in REGISTER_NAMES
+ are available, then return false (0). */
+
+#define CANNOT_STORE_REGISTER(regno) \
+ ((regno) == 0) || \
+ ((regno) == PCSQ_HEAD_REGNUM) || \
+ ((regno) >= PCSQ_TAIL_REGNUM && (regno) < IPSW_REGNUM) || \
+ ((regno) > IPSW_REGNUM && (regno) < FP4_REGNUM)
+
+/* fetch_inferior_registers is in hppab-nat.c. */
+#define FETCH_INFERIOR_REGISTERS
+
+/* attach/detach works to some extent under BSD and HPUX. So long
+ as the process you're attaching to isn't blocked waiting on io,
+ blocked waiting on a signal, or in a system call things work
+ fine. (The problems in those cases are related to the fact that
+ the kernel can't provide complete register information for the
+ target process... Which really pisses off GDB.) */
+
+#define ATTACH_DETACH
+
+#define EMULATOR_BASE 0x90100000
+#define EMULATOR_END 0x90200000
diff --git a/gdb/config/pa/tm-hppa.h b/gdb/config/pa/tm-hppa.h
new file mode 100644
index 00000000000..227108f49ef
--- /dev/null
+++ b/gdb/config/pa/tm-hppa.h
@@ -0,0 +1,762 @@
+/* Parameters for execution on any Hewlett-Packard PA-RISC machine.
+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1998, 1999, 2000 Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+ 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 "regcache.h"
+
+/* Forward declarations of some types we use in prototypes */
+
+struct frame_info;
+struct frame_saved_regs;
+struct value;
+struct type;
+struct inferior_status;
+
+/* By default assume we don't have to worry about software floating point. */
+#ifndef SOFT_FLOAT
+#define SOFT_FLOAT 0
+#endif
+
+/* Get at various relevent fields of an instruction word. */
+
+#define MASK_5 0x1f
+#define MASK_11 0x7ff
+#define MASK_14 0x3fff
+#define MASK_21 0x1fffff
+
+/* This macro gets bit fields using HP's numbering (MSB = 0) */
+#ifndef GET_FIELD
+#define GET_FIELD(X, FROM, TO) \
+ ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
+#endif
+
+/* On the PA, any pass-by-value structure > 8 bytes is actually
+ passed via a pointer regardless of its type or the compiler
+ used. */
+
+#define REG_STRUCT_HAS_ADDR(gcc_p,type) \
+ (TYPE_LENGTH (type) > 8)
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code. */
+
+extern CORE_ADDR hppa_skip_prologue (CORE_ADDR);
+#define SKIP_PROLOGUE(pc) (hppa_skip_prologue (pc))
+
+/* If PC is in some function-call trampoline code, return the PC
+ where the function itself actually starts. If not, return NULL. */
+
+#define SKIP_TRAMPOLINE_CODE(pc) skip_trampoline_code (pc, NULL)
+extern CORE_ADDR skip_trampoline_code (CORE_ADDR, char *);
+
+/* Return non-zero if we are in an appropriate trampoline. */
+
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
+ in_solib_call_trampoline (pc, name)
+extern int in_solib_call_trampoline (CORE_ADDR, char *);
+
+#define IN_SOLIB_RETURN_TRAMPOLINE(pc, name) \
+ in_solib_return_trampoline (pc, name)
+extern int in_solib_return_trampoline (CORE_ADDR, char *);
+
+/* Immediately after a function call, return the saved pc.
+ Can't go through the frames for this because on some machines
+ the new frame is not set up until the new function executes
+ some instructions. */
+
+#undef SAVED_PC_AFTER_CALL
+#define SAVED_PC_AFTER_CALL(frame) saved_pc_after_call (frame)
+extern CORE_ADDR saved_pc_after_call (struct frame_info *);
+
+/* Stack grows upward */
+#define INNER_THAN(lhs,rhs) ((lhs) > (rhs))
+
+/* elz: adjust the quantity to the next highest value which is 64-bit aligned.
+ This is used in valops.c, when the sp is adjusted.
+ On hppa the sp must always be kept 64-bit aligned */
+
+#define STACK_ALIGN(arg) ( ((arg)%8) ? (((arg)+7)&-8) : (arg))
+#define EXTRA_STACK_ALIGNMENT_NEEDED 0
+
+/* Sequence of bytes for breakpoint instruction. */
+
+#define BREAKPOINT {0x00, 0x01, 0x00, 0x04}
+#define BREAKPOINT32 0x10004
+
+/* Amount PC must be decremented by after a breakpoint.
+ This is often the number of bytes in BREAKPOINT
+ but not always.
+
+ Not on the PA-RISC */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Sometimes we may pluck out a minimal symbol that has a negative
+ address.
+
+ An example of this occurs when an a.out is linked against a foo.sl.
+ The foo.sl defines a global bar(), and the a.out declares a signature
+ for bar(). However, the a.out doesn't directly call bar(), but passes
+ its address in another call.
+
+ If you have this scenario and attempt to "break bar" before running,
+ gdb will find a minimal symbol for bar() in the a.out. But that
+ symbol's address will be negative. What this appears to denote is
+ an index backwards from the base of the procedure linkage table (PLT)
+ into the data linkage table (DLT), the end of which is contiguous
+ with the start of the PLT. This is clearly not a valid address for
+ us to set a breakpoint on.
+
+ Note that one must be careful in how one checks for a negative address.
+ 0xc0000000 is a legitimate address of something in a shared text
+ segment, for example. Since I don't know what the possible range
+ is of these "really, truly negative" addresses that come from the
+ minimal symbols, I'm resorting to the gross hack of checking the
+ top byte of the address for all 1's. Sigh.
+ */
+#define PC_REQUIRES_RUN_BEFORE_USE(pc) \
+ (! target_has_stack && (pc & 0xFF000000))
+
+/* return instruction is bv r0(rp) or bv,n r0(rp) */
+
+#define ABOUT_TO_RETURN(pc) ((read_memory_integer (pc, 4) | 0x2) == 0xE840C002)
+
+/* Say how long (ordinary) registers are. This is a piece of bogosity
+ used in push_word and a few other places; REGISTER_RAW_SIZE is the
+ real way to know how big a register is. */
+
+#define REGISTER_SIZE 4
+
+/* Number of machine registers */
+
+#define NUM_REGS 128
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer.
+ They are in rows of eight entries */
+
+#define REGISTER_NAMES \
+ {"flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", \
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
+ "r24", "r25", "r26", "dp", "ret0", "ret1", "sp", "r31", \
+ "sar", "pcoqh", "pcsqh", "pcoqt", "pcsqt", "eiem", "iir", "isr", \
+ "ior", "ipsw", "goto", "sr4", "sr0", "sr1", "sr2", "sr3", \
+ "sr5", "sr6", "sr7", "cr0", "cr8", "cr9", "ccr", "cr12", \
+ "cr13", "cr24", "cr25", "cr26", "mpsfu_high","mpsfu_low","mpsfu_ovflo","pad",\
+ "fpsr", "fpe1", "fpe2", "fpe3", "fpe4", "fpe5", "fpe6", "fpe7", \
+ "fr4", "fr4R", "fr5", "fr5R", "fr6", "fr6R", "fr7", "fr7R", \
+ "fr8", "fr8R", "fr9", "fr9R", "fr10", "fr10R", "fr11", "fr11R", \
+ "fr12", "fr12R", "fr13", "fr13R", "fr14", "fr14R", "fr15", "fr15R", \
+ "fr16", "fr16R", "fr17", "fr17R", "fr18", "fr18R", "fr19", "fr19R", \
+ "fr20", "fr20R", "fr21", "fr21R", "fr22", "fr22R", "fr23", "fr23R", \
+ "fr24", "fr24R", "fr25", "fr25R", "fr26", "fr26R", "fr27", "fr27R", \
+ "fr28", "fr28R", "fr29", "fr29R", "fr30", "fr30R", "fr31", "fr31R"}
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define R0_REGNUM 0 /* Doesn't actually exist, used as base for
+ other r registers. */
+#define FLAGS_REGNUM 0 /* Various status flags */
+#define RP_REGNUM 2 /* return pointer */
+#define FP_REGNUM 3 /* Contains address of executing stack */
+ /* frame */
+#define SP_REGNUM 30 /* Contains address of top of stack */
+#define SAR_REGNUM 32 /* Shift Amount Register */
+#define IPSW_REGNUM 41 /* Interrupt Processor Status Word */
+#define PCOQ_HEAD_REGNUM 33 /* instruction offset queue head */
+#define PCSQ_HEAD_REGNUM 34 /* instruction space queue head */
+#define PCOQ_TAIL_REGNUM 35 /* instruction offset queue tail */
+#define PCSQ_TAIL_REGNUM 36 /* instruction space queue tail */
+#define EIEM_REGNUM 37 /* External Interrupt Enable Mask */
+#define IIR_REGNUM 38 /* Interrupt Instruction Register */
+#define IOR_REGNUM 40 /* Interrupt Offset Register */
+#define SR4_REGNUM 43 /* space register 4 */
+#define RCR_REGNUM 51 /* Recover Counter (also known as cr0) */
+#define CCR_REGNUM 54 /* Coprocessor Configuration Register */
+#define TR0_REGNUM 57 /* Temporary Registers (cr24 -> cr31) */
+#define CR27_REGNUM 60 /* Base register for thread-local storage, cr27 */
+#define FP0_REGNUM 64 /* floating point reg. 0 (fspr) */
+#define FP4_REGNUM 72
+
+#define ARG0_REGNUM 26 /* The first argument of a callee. */
+#define ARG1_REGNUM 25 /* The second argument of a callee. */
+#define ARG2_REGNUM 24 /* The third argument of a callee. */
+#define ARG3_REGNUM 23 /* The fourth argument of a callee. */
+
+/* compatibility with the rest of gdb. */
+#define PC_REGNUM PCOQ_HEAD_REGNUM
+#define NPC_REGNUM PCOQ_TAIL_REGNUM
+
+/*
+ * Processor Status Word Masks
+ */
+
+#define PSW_T 0x01000000 /* Taken Branch Trap Enable */
+#define PSW_H 0x00800000 /* Higher-Privilege Transfer Trap Enable */
+#define PSW_L 0x00400000 /* Lower-Privilege Transfer Trap Enable */
+#define PSW_N 0x00200000 /* PC Queue Front Instruction Nullified */
+#define PSW_X 0x00100000 /* Data Memory Break Disable */
+#define PSW_B 0x00080000 /* Taken Branch in Previous Cycle */
+#define PSW_C 0x00040000 /* Code Address Translation Enable */
+#define PSW_V 0x00020000 /* Divide Step Correction */
+#define PSW_M 0x00010000 /* High-Priority Machine Check Disable */
+#define PSW_CB 0x0000ff00 /* Carry/Borrow Bits */
+#define PSW_R 0x00000010 /* Recovery Counter Enable */
+#define PSW_Q 0x00000008 /* Interruption State Collection Enable */
+#define PSW_P 0x00000004 /* Protection ID Validation Enable */
+#define PSW_D 0x00000002 /* Data Address Translation Enable */
+#define PSW_I 0x00000001 /* External, Power Failure, Low-Priority */
+ /* Machine Check Interruption Enable */
+
+/* When fetching register values from an inferior or a core file,
+ clean them up using this macro. BUF is a char pointer to
+ the raw value of the register in the registers[] array. */
+
+#define DEPRECATED_CLEAN_UP_REGISTER_VALUE(regno, buf) \
+ do { \
+ if ((regno) == PCOQ_HEAD_REGNUM || (regno) == PCOQ_TAIL_REGNUM) \
+ (buf)[sizeof(CORE_ADDR) -1] &= ~0x3; \
+ } while (0)
+
+/* Define DO_REGISTERS_INFO() to do machine-specific formatting
+ of register dumps. */
+
+#define DO_REGISTERS_INFO(_regnum, fp) pa_do_registers_info (_regnum, fp)
+extern void pa_do_registers_info (int, int);
+
+#if 0
+#define STRCAT_REGISTER(regnum, fpregs, stream, precision) pa_do_strcat_registers_info (regnum, fpregs, stream, precision)
+extern void pa_do_strcat_registers_info (int, int, struct ui_file *, enum precision_type);
+#endif
+
+/* PA specific macro to see if the current instruction is nullified. */
+#ifndef INSTRUCTION_NULLIFIED
+#define INSTRUCTION_NULLIFIED \
+ (((int)read_register (IPSW_REGNUM) & 0x00200000) && \
+ !((int)read_register (FLAGS_REGNUM) & 0x2))
+#endif
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. On the PA-RISC, all regs are 4 bytes, including
+ the FP registers (they're accessed as two 4 byte halves). */
+
+#define REGISTER_RAW_SIZE(N) 4
+
+/* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'. */
+#define REGISTER_BYTES (NUM_REGS * 4)
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#define REGISTER_BYTE(N) (N) * 4
+
+/* Number of bytes of storage in the program's representation
+ for register N. */
+
+#define REGISTER_VIRTUAL_SIZE(N) REGISTER_RAW_SIZE(N)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#define MAX_REGISTER_RAW_SIZE 4
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+ ((N) < FP4_REGNUM ? builtin_type_int : builtin_type_float)
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) {write_register (28, (ADDR)); }
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ hppa_extract_return_value (TYPE, REGBUF, VALBUF);
+
+ /* elz: decide whether the function returning a value of type type
+ will put it on the stack or in the registers.
+ The pa calling convention says that:
+ register 28 (called ret0 by gdb) contains any ASCII char,
+ and any non_floating point value up to 32-bits.
+ reg 28 and 29 contain non-floating point up tp 64 bits and larger
+ than 32 bits. (higer order word in reg 28).
+ fr4: floating point up to 64 bits
+ sr1: space identifier (32-bit)
+ stack: any lager than 64-bit, with the address in r28
+ */
+extern use_struct_convention_fn hppa_use_struct_convention;
+#define USE_STRUCT_CONVENTION(gcc_p,type) hppa_use_struct_convention (gcc_p,type)
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format. */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ hppa_store_return_value (TYPE, VALBUF);
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+ (*(int *)((REGBUF) + REGISTER_BYTE (28)))
+
+/* elz: Return a large value, which is stored on the stack at addr.
+ This is defined only for the hppa, at this moment.
+ The above macro EXTRACT_STRUCT_VALUE_ADDRESS is not called anymore,
+ because it assumes that on exit from a called function which returns
+ a large structure on the stack, the address of the ret structure is
+ still in register 28. Unfortunately this register is usually overwritten
+ by the called function itself, on hppa. This is specified in the calling
+ convention doc. As far as I know, the only way to get the return value
+ is to have the caller tell us where it told the callee to put it, rather
+ than have the callee tell us.
+ */
+#define VALUE_RETURNED_FROM_STACK(valtype,addr) \
+ hppa_value_returned_from_stack (valtype, addr)
+
+/*
+ * This macro defines the register numbers (from REGISTER_NAMES) that
+ * are effectively unavailable to the user through ptrace(). It allows
+ * us to include the whole register set in REGISTER_NAMES (inorder to
+ * better support remote debugging). If it is used in
+ * fetch/store_inferior_registers() gdb will not complain about I/O errors
+ * on fetching these registers. If all registers in REGISTER_NAMES
+ * are available, then return false (0).
+ */
+
+#define CANNOT_STORE_REGISTER(regno) \
+ ((regno) == 0) || \
+ ((regno) == PCSQ_HEAD_REGNUM) || \
+ ((regno) >= PCSQ_TAIL_REGNUM && (regno) < IPSW_REGNUM) || \
+ ((regno) > IPSW_REGNUM && (regno) < FP4_REGNUM)
+
+#define INIT_EXTRA_FRAME_INFO(fromleaf, frame) init_extra_frame_info (fromleaf, frame)
+extern void init_extra_frame_info (int, struct frame_info *);
+
+/* Describe the pointer in each stack frame to the previous stack frame
+ (its caller). */
+
+/* FRAME_CHAIN takes a frame's nominal address and produces the
+ frame's chain-pointer. */
+
+/* In the case of the PA-RISC, the frame's nominal address
+ is the address of a 4-byte word containing the calling frame's
+ address (previous FP). */
+
+#define FRAME_CHAIN(thisframe) frame_chain (thisframe)
+extern CORE_ADDR frame_chain (struct frame_info *);
+
+extern int hppa_frame_chain_valid (CORE_ADDR, struct frame_info *);
+#define FRAME_CHAIN_VALID(chain, thisframe) hppa_frame_chain_valid (chain, thisframe)
+
+/* Define other aspects of the stack frame. */
+
+/* A macro that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. If it
+ does not, FRAMELESS is set to 1, else 0. */
+#define FRAMELESS_FUNCTION_INVOCATION(FI) \
+ (frameless_function_invocation (FI))
+extern int frameless_function_invocation (struct frame_info *);
+
+extern CORE_ADDR hppa_frame_saved_pc (struct frame_info *frame);
+#define FRAME_SAVED_PC(FRAME) hppa_frame_saved_pc (FRAME)
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+/* Set VAL to the number of args passed to frame described by FI.
+ Can set VAL to -1, meaning no way to tell. */
+
+/* We can't tell how many args there are
+ now that the C compiler delays popping them. */
+#define FRAME_NUM_ARGS(fi) (-1)
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#define FRAME_ARGS_SKIP 0
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+ hppa_frame_find_saved_regs (frame_info, &frame_saved_regs)
+extern void
+hppa_frame_find_saved_regs (struct frame_info *, struct frame_saved_regs *);
+
+
+/* Things needed for making the inferior call functions. */
+
+/* Push an empty stack frame, to record the current PC, etc. */
+
+#define PUSH_DUMMY_FRAME push_dummy_frame (inf_status)
+extern void push_dummy_frame (struct inferior_status *);
+
+/* Discard from the stack the innermost frame,
+ restoring all saved registers. */
+#define POP_FRAME hppa_pop_frame ()
+extern void hppa_pop_frame (void);
+
+#define INSTRUCTION_SIZE 4
+
+#ifndef PA_LEVEL_0
+
+/* Non-level zero PA's have space registers (but they don't always have
+ floating-point, do they???? */
+
+/* This sequence of words is the instructions
+
+ ; Call stack frame has already been built by gdb. Since we could be calling
+ ; a varargs function, and we do not have the benefit of a stub to put things in
+ ; the right place, we load the first 4 word of arguments into both the general
+ ; and fp registers.
+ call_dummy
+ ldw -36(sp), arg0
+ ldw -40(sp), arg1
+ ldw -44(sp), arg2
+ ldw -48(sp), arg3
+ ldo -36(sp), r1
+ fldws 0(0, r1), fr4
+ fldds -4(0, r1), fr5
+ fldws -8(0, r1), fr6
+ fldds -12(0, r1), fr7
+ ldil 0, r22 ; FUNC_LDIL_OFFSET must point here
+ ldo 0(r22), r22 ; FUNC_LDO_OFFSET must point here
+ ldsid (0,r22), r4
+ ldil 0, r1 ; SR4EXPORT_LDIL_OFFSET must point here
+ ldo 0(r1), r1 ; SR4EXPORT_LDO_OFFSET must point here
+ ldsid (0,r1), r20
+ combt,=,n r4, r20, text_space ; If target is in data space, do a
+ ble 0(sr5, r22) ; "normal" procedure call
+ copy r31, r2
+ break 4, 8
+ mtsp r21, sr0
+ ble,n 0(sr0, r22)
+ text_space ; Otherwise, go through _sr4export,
+ ble (sr4, r1) ; which will return back here.
+ stw r31,-24(r30)
+ break 4, 8
+ mtsp r21, sr0
+ ble,n 0(sr0, r22)
+ nop ; To avoid kernel bugs
+ nop ; and keep the dummy 8 byte aligned
+
+ The dummy decides if the target is in text space or data space. If
+ it's in data space, there's no problem because the target can
+ return back to the dummy. However, if the target is in text space,
+ the dummy calls the secret, undocumented routine _sr4export, which
+ calls a function in text space and can return to any space. Instead
+ of including fake instructions to represent saved registers, we
+ know that the frame is associated with the call dummy and treat it
+ specially.
+
+ The trailing NOPs are needed to avoid a bug in HPUX, BSD and OSF1
+ kernels. If the memory at the location pointed to by the PC is
+ 0xffffffff then a ptrace step call will fail (even if the instruction
+ is nullified).
+
+ The code to pop a dummy frame single steps three instructions
+ starting with the last mtsp. This includes the nullified "instruction"
+ following the ble (which is uninitialized junk). If the
+ "instruction" following the last BLE is 0xffffffff, then the ptrace
+ will fail and the dummy frame is not correctly popped.
+
+ By placing a NOP in the delay slot of the BLE instruction we can be
+ sure that we never try to execute a 0xffffffff instruction and
+ avoid the kernel bug. The second NOP is needed to keep the call
+ dummy 8 byte aligned. */
+
+/* Define offsets into the call dummy for the target function address */
+#define FUNC_LDIL_OFFSET (INSTRUCTION_SIZE * 9)
+#define FUNC_LDO_OFFSET (INSTRUCTION_SIZE * 10)
+
+/* Define offsets into the call dummy for the _sr4export address */
+#define SR4EXPORT_LDIL_OFFSET (INSTRUCTION_SIZE * 12)
+#define SR4EXPORT_LDO_OFFSET (INSTRUCTION_SIZE * 13)
+
+#define CALL_DUMMY {0x4BDA3FB9, 0x4BD93FB1, 0x4BD83FA9, 0x4BD73FA1,\
+ 0x37C13FB9, 0x24201004, 0x2C391005, 0x24311006,\
+ 0x2C291007, 0x22C00000, 0x36D60000, 0x02C010A4,\
+ 0x20200000, 0x34210000, 0x002010b4, 0x82842022,\
+ 0xe6c06000, 0x081f0242, 0x00010004, 0x00151820,\
+ 0xe6c00002, 0xe4202000, 0x6bdf3fd1, 0x00010004,\
+ 0x00151820, 0xe6c00002, 0x08000240, 0x08000240}
+
+#define CALL_DUMMY_LENGTH (INSTRUCTION_SIZE * 28)
+#define REG_PARM_STACK_SPACE 16
+
+#else /* defined PA_LEVEL_0 */
+
+/* This is the call dummy for a level 0 PA. Level 0's don't have space
+ registers (or floating point?), so we skip all that inter-space call stuff,
+ and avoid touching the fp regs.
+
+ call_dummy
+
+ ldw -36(%sp), %arg0
+ ldw -40(%sp), %arg1
+ ldw -44(%sp), %arg2
+ ldw -48(%sp), %arg3
+ ldil 0, %r31 ; FUNC_LDIL_OFFSET must point here
+ ldo 0(%r31), %r31 ; FUNC_LDO_OFFSET must point here
+ ble 0(%sr0, %r31)
+ copy %r31, %r2
+ break 4, 8
+ nop ; restore_pc_queue expects these
+ bv,n 0(%r22) ; instructions to be here...
+ nop
+ */
+
+/* Define offsets into the call dummy for the target function address */
+#define FUNC_LDIL_OFFSET (INSTRUCTION_SIZE * 4)
+#define FUNC_LDO_OFFSET (INSTRUCTION_SIZE * 5)
+
+#define CALL_DUMMY {0x4bda3fb9, 0x4bd93fb1, 0x4bd83fa9, 0x4bd73fa1,\
+ 0x23e00000, 0x37ff0000, 0xe7e00000, 0x081f0242,\
+ 0x00010004, 0x08000240, 0xeac0c002, 0x08000240}
+
+#define CALL_DUMMY_LENGTH (INSTRUCTION_SIZE * 12)
+
+#endif
+
+#define CALL_DUMMY_START_OFFSET 0
+
+/* If we've reached a trap instruction within the call dummy, then
+ we'll consider that to mean that we've reached the call dummy's
+ end after its successful completion. */
+#define CALL_DUMMY_HAS_COMPLETED(pc, sp, frame_address) \
+ (PC_IN_CALL_DUMMY((pc), (sp), (frame_address)) && \
+ (read_memory_integer((pc), 4) == BREAKPOINT32))
+
+/*
+ * Insert the specified number of args and function address
+ * into a call sequence of the above form stored at DUMMYNAME.
+ *
+ * On the hppa we need to call the stack dummy through $$dyncall.
+ * Therefore our version of FIX_CALL_DUMMY takes an extra argument,
+ * real_pc, which is the location where gdb should start up the
+ * inferior to do the function call.
+ */
+
+#define FIX_CALL_DUMMY hppa_fix_call_dummy
+
+extern CORE_ADDR
+hppa_fix_call_dummy (char *, CORE_ADDR, CORE_ADDR, int,
+ struct value **, struct type *, int);
+
+#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
+ (hppa_push_arguments((nargs), (args), (sp), (struct_return), (struct_addr)))
+extern CORE_ADDR
+hppa_push_arguments (int, struct value **, CORE_ADDR, int, CORE_ADDR);
+
+/* The low two bits of the PC on the PA contain the privilege level. Some
+ genius implementing a (non-GCC) compiler apparently decided this means
+ that "addresses" in a text section therefore include a privilege level,
+ and thus symbol tables should contain these bits. This seems like a
+ bonehead thing to do--anyway, it seems to work for our purposes to just
+ ignore those bits. */
+#define SMASH_TEXT_ADDRESS(addr) ((addr) &= ~0x3)
+
+#define GDB_TARGET_IS_HPPA
+
+#define BELIEVE_PCC_PROMOTION 1
+
+/*
+ * Unwind table and descriptor.
+ */
+
+struct unwind_table_entry
+ {
+ CORE_ADDR region_start;
+ CORE_ADDR region_end;
+
+ unsigned int Cannot_unwind:1; /* 0 */
+ unsigned int Millicode:1; /* 1 */
+ unsigned int Millicode_save_sr0:1; /* 2 */
+ unsigned int Region_description:2; /* 3..4 */
+ unsigned int reserved1:1; /* 5 */
+ unsigned int Entry_SR:1; /* 6 */
+ unsigned int Entry_FR:4; /* number saved *//* 7..10 */
+ unsigned int Entry_GR:5; /* number saved *//* 11..15 */
+ unsigned int Args_stored:1; /* 16 */
+ unsigned int Variable_Frame:1; /* 17 */
+ unsigned int Separate_Package_Body:1; /* 18 */
+ unsigned int Frame_Extension_Millicode:1; /* 19 */
+ unsigned int Stack_Overflow_Check:1; /* 20 */
+ unsigned int Two_Instruction_SP_Increment:1; /* 21 */
+ unsigned int Ada_Region:1; /* 22 */
+ unsigned int cxx_info:1; /* 23 */
+ unsigned int cxx_try_catch:1; /* 24 */
+ unsigned int sched_entry_seq:1; /* 25 */
+ unsigned int reserved2:1; /* 26 */
+ unsigned int Save_SP:1; /* 27 */
+ unsigned int Save_RP:1; /* 28 */
+ unsigned int Save_MRP_in_frame:1; /* 29 */
+ unsigned int extn_ptr_defined:1; /* 30 */
+ unsigned int Cleanup_defined:1; /* 31 */
+
+ unsigned int MPE_XL_interrupt_marker:1; /* 0 */
+ unsigned int HP_UX_interrupt_marker:1; /* 1 */
+ unsigned int Large_frame:1; /* 2 */
+ unsigned int Pseudo_SP_Set:1; /* 3 */
+ unsigned int reserved4:1; /* 4 */
+ unsigned int Total_frame_size:27; /* 5..31 */
+
+ /* This is *NOT* part of an actual unwind_descriptor in an object
+ file. It is *ONLY* part of the "internalized" descriptors that
+ we create from those in a file.
+ */
+ struct
+ {
+ unsigned int stub_type:4; /* 0..3 */
+ unsigned int padding:28; /* 4..31 */
+ }
+ stub_unwind;
+ };
+
+/* HP linkers also generate unwinds for various linker-generated stubs.
+ GDB reads in the stubs from the $UNWIND_END$ subspace, then
+ "converts" them into normal unwind entries using some of the reserved
+ fields to store the stub type. */
+
+struct stub_unwind_entry
+ {
+ /* The offset within the executable for the associated stub. */
+ unsigned stub_offset;
+
+ /* The type of stub this unwind entry describes. */
+ char type;
+
+ /* Unknown. Not needed by GDB at this time. */
+ char prs_info;
+
+ /* Length (in instructions) of the associated stub. */
+ short stub_length;
+ };
+
+/* Sizes (in bytes) of the native unwind entries. */
+#define UNWIND_ENTRY_SIZE 16
+#define STUB_UNWIND_ENTRY_SIZE 8
+
+/* The gaps represent linker stubs used in MPE and space for future
+ expansion. */
+enum unwind_stub_types
+ {
+ LONG_BRANCH = 1,
+ PARAMETER_RELOCATION = 2,
+ EXPORT = 10,
+ IMPORT = 11,
+ IMPORT_SHLIB = 12,
+ };
+
+/* We use the objfile->obj_private pointer for two things:
+
+ * 1. An unwind table;
+ *
+ * 2. A pointer to any associated shared library object.
+ *
+ * #defines are used to help refer to these objects.
+ */
+
+/* Info about the unwind table associated with an object file.
+
+ * This is hung off of the "objfile->obj_private" pointer, and
+ * is allocated in the objfile's psymbol obstack. This allows
+ * us to have unique unwind info for each executable and shared
+ * library that we are debugging.
+ */
+struct obj_unwind_info
+ {
+ struct unwind_table_entry *table; /* Pointer to unwind info */
+ struct unwind_table_entry *cache; /* Pointer to last entry we found */
+ int last; /* Index of last entry */
+ };
+
+typedef struct obj_private_struct
+ {
+ struct obj_unwind_info *unwind_info; /* a pointer */
+ struct so_list *so_info; /* a pointer */
+ CORE_ADDR dp;
+ }
+obj_private_data_t;
+
+#if 0
+extern void target_write_pc (CORE_ADDR, int);
+extern CORE_ADDR target_read_pc (int);
+extern CORE_ADDR skip_trampoline_code (CORE_ADDR, char *);
+#endif
+
+#define TARGET_READ_PC(pid) target_read_pc (pid)
+extern CORE_ADDR target_read_pc (ptid_t);
+
+#define TARGET_WRITE_PC(v,pid) target_write_pc (v,pid)
+extern void target_write_pc (CORE_ADDR, ptid_t);
+
+#define TARGET_READ_FP() target_read_fp (PIDGET (inferior_ptid))
+extern CORE_ADDR target_read_fp (int);
+
+/* For a number of horrible reasons we may have to adjust the location
+ of variables on the stack. Ugh. */
+#define HPREAD_ADJUST_STACK_ADDRESS(ADDR) hpread_adjust_stack_address(ADDR)
+
+extern int hpread_adjust_stack_address (CORE_ADDR);
+
+/* If the current gcc for for this target does not produce correct debugging
+ information for float parameters, both prototyped and unprototyped, then
+ define this macro. This forces gdb to always assume that floats are
+ passed as doubles and then converted in the callee.
+
+ For the pa, it appears that the debug info marks the parameters as
+ floats regardless of whether the function is prototyped, but the actual
+ values are passed as doubles for the non-prototyped case and floats for
+ the prototyped case. Thus we choose to make the non-prototyped case work
+ for C and break the prototyped case, since the non-prototyped case is
+ probably much more common. (FIXME). */
+
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (current_language -> la_language == language_c)
+
+/* Here's how to step off a permanent breakpoint. */
+#define SKIP_PERMANENT_BREAKPOINT (hppa_skip_permanent_breakpoint)
+extern void hppa_skip_permanent_breakpoint (void);
+
+/* On HP-UX, certain system routines (millicode) have names beginning
+ with $ or $$, e.g. $$dyncall, which handles inter-space procedure
+ calls on PA-RISC. Tell the expression parser to check for those
+ when parsing tokens that begin with "$". */
+#define SYMBOLS_CAN_START_WITH_DOLLAR (1)
diff --git a/gdb/config/pa/tm-hppa64.h b/gdb/config/pa/tm-hppa64.h
new file mode 100644
index 00000000000..10fdeede69d
--- /dev/null
+++ b/gdb/config/pa/tm-hppa64.h
@@ -0,0 +1,333 @@
+/* Parameters for execution on any Hewlett-Packard PA-RISC machine.
+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1995, 1999, 2000
+ Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+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. */
+
+/* PA 64-bit specific definitions. Override those which are in
+ tm-hppa.h */
+
+/* jimb: this must go. I'm just using it to disable code I haven't
+ gotten working yet. */
+#define GDB_TARGET_IS_HPPA_20W
+
+#include "pa/tm-hppah.h"
+
+#define HPUX_1100 1
+
+/* The low two bits of the IA are the privilege level of the instruction. */
+#define ADDR_BITS_REMOVE(addr) ((CORE_ADDR)addr & (CORE_ADDR)~3)
+
+/* Say how long (ordinary) registers are. This is used in
+ push_word and a few other places, but REGISTER_RAW_SIZE is
+ the real way to know how big a register is. */
+
+#undef REGISTER_SIZE
+#define REGISTER_SIZE 8
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. On the PA-RISC 2.0, all regs are 8 bytes, including
+ the FP registers (they're accessed as two 4 byte halves). */
+
+#undef REGISTER_RAW_SIZE
+#define REGISTER_RAW_SIZE(N) 8
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#undef MAX_REGISTER_RAW_SIZE
+#define MAX_REGISTER_RAW_SIZE 8
+
+/* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'. */
+
+#undef REGISTER_BYTES
+#define REGISTER_BYTES (NUM_REGS * 8)
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#undef REGISTER_BYTE
+#define REGISTER_BYTE(N) ((N) * 8)
+
+#undef REGISTER_VIRTUAL_TYPE
+#define REGISTER_VIRTUAL_TYPE(N) \
+ ((N) < FP4_REGNUM ? builtin_type_unsigned_long_long : builtin_type_double)
+
+
+/* Number of machine registers */
+#undef NUM_REGS
+#define NUM_REGS 96
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer.
+ They are in rows of eight entries */
+#undef REGISTER_NAMES
+#define REGISTER_NAMES \
+ {"flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", \
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
+ "r24", "r25", "r26", "dp", "ret0", "ret1", "sp", "r31", \
+ "sar", "pcoqh", "pcsqh", "pcoqt", "pcsqt", "eiem", "iir", "isr", \
+ "ior", "ipsw", "goto", "sr4", "sr0", "sr1", "sr2", "sr3", \
+ "sr5", "sr6", "sr7", "cr0", "cr8", "cr9", "ccr", "cr12", \
+ "cr13", "cr24", "cr25", "cr26", "mpsfu_high","mpsfu_low","mpsfu_ovflo","pad",\
+ "fpsr", "fpe1", "fpe2", "fpe3", "fr4", "fr5", "fr6", "fr7", \
+ "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", \
+ "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23", \
+ "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31"}
+
+#undef FP0_REGNUM
+#undef FP4_REGNUM
+#define FP0_REGNUM 64 /* floating point reg. 0 (fspr)*/
+#define FP4_REGNUM 68
+
+/* Redefine some target bit sizes from the default. */
+
+/* Number of bits in a long or unsigned long for the target machine. */
+
+#define TARGET_LONG_BIT 64
+
+/* Number of bits in a long long or unsigned long long for the
+ target machine. */
+
+#define TARGET_LONG_LONG_BIT 64
+
+/* Number of bits in a pointer for the target machine */
+
+#define TARGET_PTR_BIT 64
+
+/* Argument Pointer Register */
+#define AP_REGNUM 29
+
+#define DP_REGNUM 27
+
+#define FP5_REGNUM 70
+
+#define SR5_REGNUM 48
+
+#undef FRAME_ARGS_ADDRESS
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->ap)
+
+/* We access locals from SP. This may not work for frames which call
+ alloca; for those, we may need to consult unwind tables.
+ jimb: FIXME. */
+#undef FRAME_LOCALS_ADDRESS
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+#define INIT_FRAME_AP init_frame_ap
+
+#define EXTRA_FRAME_INFO \
+ CORE_ADDR ap;
+
+/* For a number of horrible reasons we may have to adjust the location
+ of variables on the stack. Ugh. jimb: why? */
+#define HPREAD_ADJUST_STACK_ADDRESS(ADDR) hpread_adjust_stack_address(ADDR)
+
+extern int hpread_adjust_stack_address (CORE_ADDR);
+
+
+/* jimb: omitted dynamic linking stuff here */
+
+/* This sequence of words is the instructions
+
+; Call stack frame has already been built by gdb. Since we could be calling
+; a varargs function, and we do not have the benefit of a stub to put things in
+; the right place, we load the first 8 word of arguments into both the general
+; and fp registers.
+call_dummy
+ nop
+ copy %r4,%r29
+ copy %r5,%r22
+ copy %r6,%r27
+ fldd -64(0,%r29),%fr4
+ fldd -56(0,%r29),%fr5
+ fldd -48(0,%r29),%fr6
+ fldd -40(0,%r29),%fr7
+ fldd -32(0,%r29),%fr8
+ fldd -24(0,%r29),%fr9
+ fldd -16(0,%r29),%fr10
+ fldd -8(0,%r29),%fr11
+ copy %r22,%r1
+ ldd -64(%r29), %r26
+ ldd -56(%r29), %r25
+ ldd -48(%r29), %r24
+ ldd -40(%r29), %r23
+ ldd -32(%r29), %r22
+ ldd -24(%r29), %r21
+ ldd -16(%r29), %r20
+ bve,l (%r1),%r2
+ ldd -8(%r29), %r19
+ break 4, 8
+ mtsp %r21, %sr0
+ ble 0(%sr0, %r22)
+ nop
+*/
+
+/* Call dummys are sized and written out in word sized hunks. So we have
+ to pack the instructions into words. Ugh. */
+#undef CALL_DUMMY
+#define CALL_DUMMY {0x08000240349d0000LL, 0x34b6000034db0000LL, \
+ 0x53a43f8353a53f93LL, 0x53a63fa353a73fb3LL,\
+ 0x53a83fc353a93fd3LL, 0x2fa1100a2fb1100bLL,\
+ 0x36c1000053ba3f81LL, 0x53b93f9153b83fa1LL,\
+ 0x53b73fb153b63fc1LL, 0x53b53fd10fa110d4LL,\
+ 0xe820f0000fb110d3LL, 0x0001000400151820LL,\
+ 0xe6c0000008000240LL}
+
+#define CALL_DUMMY_BREAKPOINT_OFFSET_P 1
+#define CALL_DUMMY_BREAKPOINT_OFFSET 22 * 4
+
+/* CALL_DUMMY_LENGTH is computed based on the size of a word on the target
+ machine, not the size of an instruction. Since a word on this target
+ holds two instructions we have to divide the instruction size by two to
+ get the word size of the dummy. */
+#undef CALL_DUMMY_LENGTH
+#define CALL_DUMMY_LENGTH (INSTRUCTION_SIZE * 26 / 2)
+
+/* The PA64 ABI mandates a 16 byte stack alignment. */
+#undef STACK_ALIGN
+#define STACK_ALIGN(arg) ( ((arg)%16) ? (((arg)+15)&-16) : (arg))
+
+/* The PA64 ABI reserves 64 bytes of stack space for outgoing register
+ parameters. */
+#undef REG_PARM_STACK_SPACE
+#define REG_PARM_STACK_SPACE 64
+
+/* Use the 64-bit calling conventions designed for the PA2.0 in wide mode. */
+#define PA20W_CALLING_CONVENTIONS
+
+#undef FUNC_LDIL_OFFSET
+#undef FUNC_LDO_OFFSET
+#undef SR4EXPORT_LDIL_OFFSET
+#undef SR4EXPORT_LDO_OFFSET
+#undef CALL_DUMMY_LOCATION
+
+#undef REG_STRUCT_HAS_ADDR
+
+#undef EXTRACT_RETURN_VALUE
+/* RM: floats are returned in FR4R, doubles in FR4
+ * integral values are in r28, padded on the left
+ * aggregates less that 65 bits are in r28, right padded
+ * aggregates upto 128 bits are in r28 and r29, right padded
+ */
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ { \
+ if (TYPE_CODE (TYPE) == TYPE_CODE_FLT && !SOFT_FLOAT) \
+ memcpy ((VALBUF), \
+ ((char *)(REGBUF)) + REGISTER_BYTE (FP4_REGNUM) + \
+ (REGISTER_SIZE - TYPE_LENGTH (TYPE)), \
+ TYPE_LENGTH (TYPE)); \
+ else if (is_integral_type(TYPE) || SOFT_FLOAT) \
+ memcpy ((VALBUF), \
+ (char *)(REGBUF) + REGISTER_BYTE (28) + \
+ (REGISTER_SIZE - TYPE_LENGTH (TYPE)), \
+ TYPE_LENGTH (TYPE)); \
+ else if (TYPE_LENGTH (TYPE) <= 8) \
+ memcpy ((VALBUF), \
+ (char *)(REGBUF) + REGISTER_BYTE (28), \
+ TYPE_LENGTH (TYPE)); \
+ else if (TYPE_LENGTH (TYPE) <= 16) \
+ { \
+ memcpy ((VALBUF), \
+ (char *)(REGBUF) + REGISTER_BYTE (28), \
+ 8); \
+ memcpy (((char *) VALBUF + 8), \
+ (char *)(REGBUF) + REGISTER_BYTE (29), \
+ TYPE_LENGTH (TYPE) - 8); \
+ } \
+ }
+
+/* RM: struct upto 128 bits are returned in registers */
+#undef USE_STRUCT_CONVENTION
+#define USE_STRUCT_CONVENTION(gcc_p, value_type)\
+ (TYPE_LENGTH (value_type) > 16)
+
+/* RM: for return command */
+#undef STORE_RETURN_VALUE
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ { \
+ if (TYPE_CODE (TYPE) == TYPE_CODE_FLT && !SOFT_FLOAT) \
+ write_register_bytes \
+ (REGISTER_BYTE (FP4_REGNUM) + \
+ (REGISTER_SIZE - TYPE_LENGTH (TYPE)), \
+ (VALBUF), \
+ TYPE_LENGTH (TYPE)); \
+ else if (is_integral_type(TYPE) || SOFT_FLOAT) \
+ write_register_bytes \
+ (REGISTER_BYTE (28) + \
+ (REGISTER_SIZE - TYPE_LENGTH (TYPE)), \
+ (VALBUF), \
+ TYPE_LENGTH (TYPE)); \
+ else if (TYPE_LENGTH (TYPE) <= 8) \
+ write_register_bytes \
+ ( REGISTER_BYTE (28), \
+ (VALBUF), \
+ TYPE_LENGTH (TYPE)); \
+ else if (TYPE_LENGTH (TYPE) <= 16) \
+ { \
+ write_register_bytes \
+ (REGISTER_BYTE (28), \
+ (VALBUF), \
+ 8); \
+ write_register_bytes \
+ (REGISTER_BYTE (29), \
+ ((char *) VALBUF + 8), \
+ TYPE_LENGTH (TYPE) - 8); \
+ } \
+ }
+
+/* RM: these are the PA64 equivalents of the macros in tm-hppah.h --
+ * see comments there. For PA64, the save_state structure is at an
+ * offset of 24 32-bit words from the sigcontext structure. The 64 bit
+ * general registers are at an offset of 640 bytes from the beginning of the
+ * save_state structure, and the floating pointer register are at an offset
+ * of 256 bytes from the beginning of the save_state structure.
+ */
+#undef FRAME_SAVED_PC_IN_SIGTRAMP
+#define FRAME_SAVED_PC_IN_SIGTRAMP(FRAME, TMP) \
+{ \
+ *(TMP) = read_memory_integer ((FRAME)->frame + (24 * 4) + 640 + (33 * 8), 8); \
+}
+
+#undef FRAME_BASE_BEFORE_SIGTRAMP
+#define FRAME_BASE_BEFORE_SIGTRAMP(FRAME, TMP) \
+{ \
+ *(TMP) = read_memory_integer ((FRAME)->frame + (24 * 4) + 640 + (30 * 8), 8); \
+}
+
+#undef FRAME_FIND_SAVED_REGS_IN_SIGTRAMP
+#define FRAME_FIND_SAVED_REGS_IN_SIGTRAMP(FRAME, FSR) \
+{ \
+ int i; \
+ CORE_ADDR TMP1, TMP2; \
+ TMP1 = (FRAME)->frame + (24 * 4) + 640; \
+ TMP2 = (FRAME)->frame + (24 * 4) + 256; \
+ for (i = 0; i < NUM_REGS; i++) \
+ { \
+ if (i == SP_REGNUM) \
+ (FSR)->regs[SP_REGNUM] = read_memory_integer (TMP1 + SP_REGNUM * 8, 8); \
+ else if (i >= FP0_REGNUM) \
+ (FSR)->regs[i] = TMP2 + (i - FP0_REGNUM) * 8; \
+ else \
+ (FSR)->regs[i] = TMP1 + i * 8; \
+ } \
+}
+
+/* jimb: omitted purify call support */
diff --git a/gdb/config/pa/tm-hppab.h b/gdb/config/pa/tm-hppab.h
new file mode 100644
index 00000000000..1cd438df75e
--- /dev/null
+++ b/gdb/config/pa/tm-hppab.h
@@ -0,0 +1,47 @@
+/* Parameters for execution on an HP PA-RISC machine running BSD, for GDB.
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu). */
+
+/* For BSD:
+
+ The signal context structure pointer is always saved at the base
+ of the frame + 0x4.
+
+ We get the PC & SP directly from the sigcontext structure itself.
+ For other registers we have to dive in a little deeper:
+
+ The hardware save state pointer is at offset 0x10 within the
+ signal context structure.
+
+ Within the hardware save state, registers are found in the same order
+ as the register numbers in GDB. */
+
+#define FRAME_SAVED_PC_IN_SIGTRAMP(FRAME, TMP) \
+{ \
+ *(TMP) = read_memory_integer ((FRAME)->frame + 0x4, 4); \
+ *(TMP) = read_memory_integer (*(TMP) + 0x18, 4); \
+}
+
+#define FRAME_BASE_BEFORE_SIGTRAMP(FRAME, TMP) \
+{ \
+ *(TMP) = read_memory_integer ((FRAME)->frame + 0x4, 4); \
+ *(TMP) = read_memory_integer (*(TMP) + 0x8, 4); \
+}
+
+#define FRAME_FIND_SAVED_REGS_IN_SIGTRAMP(FRAME, FSR) \
+{ \
+ int i; \
+ CORE_ADDR TMP; \
+ TMP = read_memory_integer ((FRAME)->frame + 0x4, 4); \
+ TMP = read_memory_integer (TMP + 0x10, 4); \
+ for (i = 0; i < NUM_REGS; i++) \
+ { \
+ if (i == SP_REGNUM) \
+ (FSR)->regs[SP_REGNUM] = read_memory_integer (TMP + SP_REGNUM * 4, 4); \
+ else \
+ (FSR)->regs[i] = TMP + i * 4; \
+ } \
+}
+
+/* It's mostly just the common stuff. */
+#include "pa/tm-hppa.h"
diff --git a/gdb/config/pa/tm-hppah.h b/gdb/config/pa/tm-hppah.h
new file mode 100644
index 00000000000..022e1249d7a
--- /dev/null
+++ b/gdb/config/pa/tm-hppah.h
@@ -0,0 +1,90 @@
+/* Parameters for execution on an HP PA-RISC machine, running HPUX, for GDB.
+ Copyright 1991, 1992, 1995, 1998 Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+ 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. */
+
+#define HPUX_SNAP1
+#define HPUX_SNAP2
+
+/* The solib hooks are not really designed to have a list of hook
+ and handler routines. So until we clean up those interfaces you
+ either get SOM shared libraries or HP's unusual PA64 ELF shared
+ libraries, but not both. */
+#ifdef GDB_TARGET_IS_HPPA_20W
+#include "pa64solib.h"
+#endif
+
+#ifndef GDB_TARGET_IS_HPPA_20W
+#include "somsolib.h"
+#endif
+
+/* Actually, for a PA running HPUX the kernel calls the signal handler
+ without an intermediate trampoline. Luckily the kernel always sets
+ the return pointer for the signal handler to point to _sigreturn. */
+#define IN_SIGTRAMP(pc, name) (name && STREQ ("_sigreturn", name))
+
+/* For HPUX:
+
+ The signal context structure pointer is always saved at the base
+ of the frame which "calls" the signal handler. We only want to find
+ the hardware save state structure, which lives 10 32bit words into
+ sigcontext structure.
+
+ Within the hardware save state structure, registers are found in the
+ same order as the register numbers in GDB.
+
+ At one time we peeked at %r31 rather than the PC queues to determine
+ what instruction took the fault. This was done on purpose, but I don't
+ remember why. Looking at the PC queues is really the right way, and
+ I don't remember why that didn't work when this code was originally
+ written. */
+
+#define FRAME_SAVED_PC_IN_SIGTRAMP(FRAME, TMP) \
+{ \
+ *(TMP) = read_memory_integer ((FRAME)->frame + (43 * 4) , 4); \
+}
+
+#define FRAME_BASE_BEFORE_SIGTRAMP(FRAME, TMP) \
+{ \
+ *(TMP) = read_memory_integer ((FRAME)->frame + (40 * 4), 4); \
+}
+
+#define FRAME_FIND_SAVED_REGS_IN_SIGTRAMP(FRAME, FSR) \
+{ \
+ int i; \
+ CORE_ADDR TMP; \
+ TMP = (FRAME)->frame + (10 * 4); \
+ for (i = 0; i < NUM_REGS; i++) \
+ { \
+ if (i == SP_REGNUM) \
+ (FSR)->regs[SP_REGNUM] = read_memory_integer (TMP + SP_REGNUM * 4, 4); \
+ else \
+ (FSR)->regs[i] = TMP + i * 4; \
+ } \
+}
+
+/* For HP-UX on PA-RISC we have an implementation
+ for the exception handling target op (in hppa-tdep.c) */
+#define CHILD_ENABLE_EXCEPTION_CALLBACK
+#define CHILD_GET_CURRENT_EXCEPTION_EVENT
+
+/* Mostly it's common to all HPPA's. */
+#include "pa/tm-hppa.h"
diff --git a/gdb/config/pa/tm-hppao.h b/gdb/config/pa/tm-hppao.h
new file mode 100644
index 00000000000..e6fae89b85b
--- /dev/null
+++ b/gdb/config/pa/tm-hppao.h
@@ -0,0 +1,98 @@
+/* Parameters for execution on an HP PA-RISC machine running OSF1, for GDB.
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu). */
+
+#include "regcache.h"
+
+/* Define offsets to access CPROC stack when it does not have
+ * a kernel thread.
+ */
+#define MACHINE_CPROC_SP_OFFSET 20
+#define MACHINE_CPROC_PC_OFFSET 16
+#define MACHINE_CPROC_FP_OFFSET 12
+
+/*
+ * Software defined PSW masks.
+ */
+#define PSW_SS 0x10000000 /* Kernel managed single step */
+
+/* Thread flavors used in re-setting the T bit.
+ * @@ this is also bad for cross debugging.
+ */
+#define TRACE_FLAVOR HP800_THREAD_STATE
+#define TRACE_FLAVOR_SIZE HP800_THREAD_STATE_COUNT
+#define TRACE_SET(x,state) \
+ ((struct hp800_thread_state *)state)->cr22 |= PSW_SS
+#define TRACE_CLEAR(x,state) \
+ ((((struct hp800_thread_state *)state)->cr22 &= ~PSW_SS), 1)
+
+/* For OSF1 (Should be close if not identical to BSD, but I haven't
+ tested it yet):
+
+ The signal context structure pointer is always saved at the base
+ of the frame + 0x4.
+
+ We get the PC & SP directly from the sigcontext structure itself.
+ For other registers we have to dive in a little deeper:
+
+ The hardware save state pointer is at offset 0x10 within the
+ signal context structure.
+
+ Within the hardware save state, registers are found in the same order
+ as the register numbers in GDB. */
+
+#define FRAME_SAVED_PC_IN_SIGTRAMP(FRAME, TMP) \
+{ \
+ *(TMP) = read_memory_integer ((FRAME)->frame + 0x4, 4); \
+ *(TMP) = read_memory_integer (*(TMP) + 0x18, 4); \
+}
+
+#define FRAME_BASE_BEFORE_SIGTRAMP(FRAME, TMP) \
+{ \
+ *(TMP) = read_memory_integer ((FRAME)->frame + 0x4, 4); \
+ *(TMP) = read_memory_integer (*(TMP) + 0x8, 4); \
+}
+
+#define FRAME_FIND_SAVED_REGS_IN_SIGTRAMP(FRAME, FSR) \
+{ \
+ int i; \
+ CORE_ADDR TMP; \
+ TMP = read_memory_integer ((FRAME)->frame + 0x4, 4); \
+ TMP = read_memory_integer (TMP + 0x10, 4); \
+ for (i = 0; i < NUM_REGS; i++) \
+ { \
+ if (i == SP_REGNUM) \
+ (FSR)->regs[SP_REGNUM] = read_memory_integer (TMP + SP_REGNUM * 4, 4); \
+ else \
+ (FSR)->regs[i] = TMP + i * 4; \
+ } \
+}
+
+/* OSF1 does not need the pc space queue restored. */
+#define NO_PC_SPACE_QUEUE_RESTORE
+
+/* The mach kernel uses the recovery counter to implement single
+ stepping. While this greatly simplifies the kernel support
+ necessary for single stepping, it unfortunately does the wrong
+ thing in the presense of a nullified instruction (gives control
+ back two insns after the nullifed insn). This is an artifact
+ of the HP architecture (recovery counter doesn't tick for
+ nullified insns).
+
+ Do our best to avoid losing in such situations. */
+#define INSTRUCTION_NULLIFIED \
+(({ \
+ int ipsw = (int)read_register(IPSW_REGNUM); \
+ if (ipsw & PSW_N) \
+ { \
+ int pcoqt = (int)read_register(PCOQ_TAIL_REGNUM); \
+ write_register(PCOQ_HEAD_REGNUM, pcoqt); \
+ write_register(PCOQ_TAIL_REGNUM, pcoqt + 0x4); \
+ write_register(IPSW_REGNUM, ipsw & ~(PSW_N | PSW_B | PSW_X)); \
+ stop_pc = pcoqt; \
+ } \
+ }), 0)
+
+/* It's mostly just the common stuff. */
+
+#include "pa/tm-hppa.h"
diff --git a/gdb/config/pa/tm-pro.h b/gdb/config/pa/tm-pro.h
new file mode 100644
index 00000000000..05ecb62f7dc
--- /dev/null
+++ b/gdb/config/pa/tm-pro.h
@@ -0,0 +1,14 @@
+/* Parameters for execution on an HP PA-RISC level 0 embedded system.
+ This is based on tm-hppab.h.
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu). */
+
+#define PA_LEVEL_0 /* Disables touching space regs and fp */
+
+/* All the PRO targets use software floating point at the moment. */
+#define SOFT_FLOAT 1
+
+/* It's mostly just the common stuff. */
+#include "pa/tm-hppa.h"
+
+#define GDB_TARGET_IS_PA_ELF
diff --git a/gdb/config/pa/xm-hppab.h b/gdb/config/pa/xm-hppab.h
new file mode 100644
index 00000000000..d2561dfcf69
--- /dev/null
+++ b/gdb/config/pa/xm-hppab.h
@@ -0,0 +1,24 @@
+/* Parameters for hosting on an HPPA PA-RISC machine, running BSD, for GDB.
+ Copyright 1991, 1992, 1993, 1996, 1998 Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+ 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 "pa/xm-pa.h"
diff --git a/gdb/config/pa/xm-hppah.h b/gdb/config/pa/xm-hppah.h
new file mode 100644
index 00000000000..b1c26dd4de8
--- /dev/null
+++ b/gdb/config/pa/xm-hppah.h
@@ -0,0 +1,29 @@
+/* Parameters for hosting on an HPPA-RISC machine running HPUX, for GDB.
+ Copyright 1991, 1992, 1993, 1995, 1996, 2000
+ Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+ 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 "pa/xm-pa.h"
+
+#define USG
+
+#define HAVE_TERMIOS
diff --git a/gdb/config/pa/xm-pa.h b/gdb/config/pa/xm-pa.h
new file mode 100644
index 00000000000..979609d4776
--- /dev/null
+++ b/gdb/config/pa/xm-pa.h
@@ -0,0 +1,5 @@
+/* Definitions for all PA machines. */
+
+/* This was created for "makeva", which is obsolete. This file can
+ probably go away (unless someone can think of some other host thing
+ which is common to various pa machines). */
diff --git a/gdb/config/powerpc/aix.mh b/gdb/config/powerpc/aix.mh
new file mode 100644
index 00000000000..d0913b70289
--- /dev/null
+++ b/gdb/config/powerpc/aix.mh
@@ -0,0 +1,16 @@
+# Host: IBM PowerPC running AIX
+
+XM_FILE= xm-aix.h
+
+NAT_FILE= nm-aix.h
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o rs6000-nat.o \
+ xcoffread.o xcoffsolib.o
+
+# When compiled with cc, for debugging, this argument should be passed.
+# We have no idea who our current compiler is though, so we skip it.
+# MH_CFLAGS = -bnodelcsect
+
+# gdb is too big for all of its external symbols to fit in a small TOC
+# It looks like the GNU linker doesn't understand the -bbigtoc switch.
+# This switch may be needed for some vendor compilers.
+# MH_LDFLAGS = -Wl,-bbigtoc
diff --git a/gdb/config/powerpc/aix.mt b/gdb/config/powerpc/aix.mt
new file mode 100644
index 00000000000..706129ae2c7
--- /dev/null
+++ b/gdb/config/powerpc/aix.mt
@@ -0,0 +1,3 @@
+# Target: PowerPC running AIX
+TDEPFILES= rs6000-tdep.o xcoffread.o ppc-linux-tdep.o solib.o solib-svr4.o
+TM_FILE= tm-ppc-aix.h
diff --git a/gdb/config/powerpc/gdbserve.mt b/gdb/config/powerpc/gdbserve.mt
new file mode 100644
index 00000000000..77284077db6
--- /dev/null
+++ b/gdb/config/powerpc/gdbserve.mt
@@ -0,0 +1,3 @@
+# Target: GDBSERVE.NLM running on a Power-PC
+TDEPFILES= ppc.o
+CPU_FILE= ppc
diff --git a/gdb/config/powerpc/linux.mh b/gdb/config/powerpc/linux.mh
new file mode 100644
index 00000000000..0e3c2a68feb
--- /dev/null
+++ b/gdb/config/powerpc/linux.mh
@@ -0,0 +1,13 @@
+# Host: PowerPC, running Linux
+
+XM_FILE= xm-linux.h
+XM_CLIBS=
+
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o linux-proc.o \
+ core-regset.o ppc-linux-nat.o proc-service.o thread-db.o lin-lwp.o \
+ gcore.o
+
+LOADLIBES = -ldl -rdynamic
+
+GDBSERVER_DEPFILES = linux-low.o linux-ppc-low.o reg-ppc.o
diff --git a/gdb/config/powerpc/linux.mt b/gdb/config/powerpc/linux.mt
new file mode 100644
index 00000000000..01160b98704
--- /dev/null
+++ b/gdb/config/powerpc/linux.mt
@@ -0,0 +1,6 @@
+# Target: Motorola PPC on Linux
+TDEPFILES= rs6000-tdep.o ppc-linux-tdep.o solib.o solib-svr4.o solib-legacy.o
+TM_FILE= tm-linux.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/ppc/libsim.a
diff --git a/gdb/config/powerpc/nbsd.mh b/gdb/config/powerpc/nbsd.mh
new file mode 100644
index 00000000000..9d29986d996
--- /dev/null
+++ b/gdb/config/powerpc/nbsd.mh
@@ -0,0 +1,3 @@
+# Host: PowerPC, running NetBSD
+NATDEPFILES= fork-child.o infptrace.o inftarg.o ppcnbsd-nat.o solib-legacy.o
+NAT_FILE= nm-nbsd.h
diff --git a/gdb/config/powerpc/nbsd.mt b/gdb/config/powerpc/nbsd.mt
new file mode 100644
index 00000000000..cbf559b658d
--- /dev/null
+++ b/gdb/config/powerpc/nbsd.mt
@@ -0,0 +1,7 @@
+# Target: PowerPC, running NetBSD
+TDEPFILES= rs6000-tdep.o ppcnbsd-tdep.o nbsd-tdep.o ppc-linux-tdep.o corelow.o \
+ solib.o solib-svr4.o
+TM_FILE= tm-nbsd.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/ppc/libsim.a
diff --git a/gdb/config/powerpc/nm-aix.h b/gdb/config/powerpc/nm-aix.h
new file mode 100644
index 00000000000..8c8a939cca2
--- /dev/null
+++ b/gdb/config/powerpc/nm-aix.h
@@ -0,0 +1,23 @@
+/* IBM PowerPC native-dependent macros for GDB, the GNU debugger.
+ Copyright 1995, 1996 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 "rs6000/nm-rs6000.h"
+
+#define PTRACE_ARG3_TYPE int*
diff --git a/gdb/config/powerpc/nm-linux.h b/gdb/config/powerpc/nm-linux.h
new file mode 100644
index 00000000000..dee39b4efaf
--- /dev/null
+++ b/gdb/config/powerpc/nm-linux.h
@@ -0,0 +1,33 @@
+/* IBM PowerPC native-dependent macros for GDB, the GNU debugger.
+ Copyright 1995, 2000 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef NM_LINUX_H
+
+#include "nm-linux.h"
+
+#define NM_LINUX_H
+
+/* Return sizeof user struct to callers in less machine dependent routines */
+
+#define KERNEL_U_SIZE kernel_u_size()
+extern int kernel_u_size (void);
+
+#define FETCH_INFERIOR_REGISTERS
+
+#endif /* #ifndef NM_LINUX_H */
diff --git a/gdb/config/powerpc/nm-nbsd.h b/gdb/config/powerpc/nm-nbsd.h
new file mode 100644
index 00000000000..5de6c9a0d21
--- /dev/null
+++ b/gdb/config/powerpc/nm-nbsd.h
@@ -0,0 +1,27 @@
+/* Native-dependent definitions for PowerPC running NetBSD ELF, for GDB.
+ Copyright 2000, 2002 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. */
+
+#ifndef NM_NBSD_H
+#define NM_NBSD_H
+
+/* Get generic NetBSD native definitions. */
+#include "config/nm-nbsd.h"
+
+#endif
diff --git a/gdb/config/powerpc/ppc-eabi.mt b/gdb/config/powerpc/ppc-eabi.mt
new file mode 100644
index 00000000000..2d4a77fcdef
--- /dev/null
+++ b/gdb/config/powerpc/ppc-eabi.mt
@@ -0,0 +1,3 @@
+# Target: PowerPC running eabi
+TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o dink32-rom.o ppc-bdm.o ocd.o remote-sds.o ppc-linux-tdep.o solib.o solib-svr4.o
+TM_FILE= tm-ppc-eabi.h
diff --git a/gdb/config/powerpc/ppc-sim.mt b/gdb/config/powerpc/ppc-sim.mt
new file mode 100644
index 00000000000..f2ad1f0b2c4
--- /dev/null
+++ b/gdb/config/powerpc/ppc-sim.mt
@@ -0,0 +1,6 @@
+# Target: PowerPC running eabi and including the simulator
+TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o dink32-rom.o ppc-bdm.o ocd.o remote-sds.o ppc-linux-tdep.o solib.o solib-svr4.o
+TM_FILE= tm-ppc-eabi.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/ppc/libsim.a
diff --git a/gdb/config/powerpc/ppcle-eabi.mt b/gdb/config/powerpc/ppcle-eabi.mt
new file mode 100644
index 00000000000..e7480975730
--- /dev/null
+++ b/gdb/config/powerpc/ppcle-eabi.mt
@@ -0,0 +1,3 @@
+# Target: PowerPC running eabi in little endian mode
+TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o ppc-bdm.o ocd.o ppc-linux-tdep.o solib.o solib-svr4.o
+TM_FILE= tm-ppcle-eabi.h
diff --git a/gdb/config/powerpc/ppcle-sim.mt b/gdb/config/powerpc/ppcle-sim.mt
new file mode 100644
index 00000000000..558c0dc885e
--- /dev/null
+++ b/gdb/config/powerpc/ppcle-sim.mt
@@ -0,0 +1,6 @@
+# Target: PowerPC running eabi in little endian mode under the simulator
+TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o ppc-bdm.o ocd.o ppc-linux-tdep.o solib.o solib-svr4.o
+TM_FILE= tm-ppcle-eabi.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/ppc/libsim.a
diff --git a/gdb/config/powerpc/tm-linux.h b/gdb/config/powerpc/tm-linux.h
new file mode 100644
index 00000000000..5fe8d76bce0
--- /dev/null
+++ b/gdb/config/powerpc/tm-linux.h
@@ -0,0 +1,70 @@
+/* Definitions to target GDB to GNU/Linux on PowerPC.
+
+ Copyright 1992, 1993, 2000, 2002 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. */
+
+#ifndef TM_LINUX_H
+#define TM_LINUX_H
+
+#include "powerpc/tm-ppc-eabi.h"
+/* Avoid warning from redefinition in tm-sysv4.h (included from tm-linux.h) */
+#undef SKIP_TRAMPOLINE_CODE
+#include "tm-linux.h"
+
+/* We can single step on linux */
+#undef SOFTWARE_SINGLE_STEP
+#define SOFTWARE_SINGLE_STEP(p,q) internal_error (__FILE__, __LINE__, "Will never execute!")
+#undef SOFTWARE_SINGLE_STEP_P
+#define SOFTWARE_SINGLE_STEP_P() 0
+
+/* Make sure nexti gets the help it needs for debugging assembly code
+ without symbols */
+
+#define AT_SUBROUTINE_CALL_INSTRUCTION_TARGET(prevpc,stoppc) \
+ at_subroutine_call_instruction_target(prevpc,stoppc)
+extern int at_subroutine_call_instruction_target();
+
+/* We _want_ the SVR4 section offset calculations (see syms_from_objfile()
+ in symfile.c) */
+#undef IBM6000_TARGET
+
+extern CORE_ADDR ppc_linux_skip_trampoline_code (CORE_ADDR pc);
+#undef SKIP_TRAMPOLINE_CODE
+#define SKIP_TRAMPOLINE_CODE(pc) ppc_linux_skip_trampoline_code (pc)
+
+extern int ppc_linux_in_sigtramp (CORE_ADDR pc, char *func_name);
+#undef IN_SIGTRAMP
+#define IN_SIGTRAMP(pc,func_name) ppc_linux_in_sigtramp (pc,func_name)
+
+#if 0
+#define CANNOT_FETCH_REGISTER(regno) ((regno) >= MQ_REGNUM)
+#define CANNOT_STORE_REGISTER(regno) ((regno) >= MQ_REGNUM)
+#endif
+
+#if 0 /* If skip_prologue() isn't too greedy, we don't need this */
+/* There is some problem with the debugging symbols generated by the
+ compiler such that the debugging symbol for the first line of a
+ function overlap with the function prologue. */
+#define PROLOGUE_FIRSTLINE_OVERLAP
+#endif
+
+/* N_FUN symbols in shared libaries have 0 for their values and need
+ to be relocated. */
+#define SOFUN_ADDRESS_MAYBE_MISSING
+
+#endif /* #ifndef TM_LINUX_H */
diff --git a/gdb/config/powerpc/tm-nbsd.h b/gdb/config/powerpc/tm-nbsd.h
new file mode 100644
index 00000000000..2b7acb8b4b8
--- /dev/null
+++ b/gdb/config/powerpc/tm-nbsd.h
@@ -0,0 +1,26 @@
+/* Macro definitions for PowerPC running under NetBSD.
+ Copyright 2000 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. */
+
+#ifndef TM_NBSD_H
+#define TM_NBSD_H
+
+#include "powerpc/tm-ppc-eabi.h"
+
+#endif /* TM_NBSD_H */
diff --git a/gdb/config/powerpc/tm-ppc-aix.h b/gdb/config/powerpc/tm-ppc-aix.h
new file mode 100644
index 00000000000..03809c9e696
--- /dev/null
+++ b/gdb/config/powerpc/tm-ppc-aix.h
@@ -0,0 +1,27 @@
+/* Macro definitions for Power PC running AIX.
+ Copyright 1995, 2000 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. */
+
+#ifndef TM_PPC_AIX_H
+#define TM_PPC_AIX_H
+
+/* Use generic RS6000 definitions. */
+#include "rs6000/tm-rs6000.h"
+
+#endif /* TM_PPC_AIX_H */
diff --git a/gdb/config/powerpc/tm-ppc-eabi.h b/gdb/config/powerpc/tm-ppc-eabi.h
new file mode 100644
index 00000000000..e49b2bd0c97
--- /dev/null
+++ b/gdb/config/powerpc/tm-ppc-eabi.h
@@ -0,0 +1,43 @@
+/* Macro definitions for Power PC running embedded ABI.
+ Copyright 1995, 1996, 1997, 1998, 1999, 2000
+ 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. */
+
+#ifndef TM_PPC_EABI_H
+#define TM_PPC_EABI_H
+
+/* Use generic RS6000 definitions. */
+#include "rs6000/tm-rs6000.h"
+/* except we want to allow single stepping */
+#undef SOFTWARE_SINGLE_STEP_P
+#define SOFTWARE_SINGLE_STEP_P() 0
+
+#undef PROCESS_LINENUMBER_HOOK
+
+#undef TEXT_SEGMENT_BASE
+#define TEXT_SEGMENT_BASE 1
+
+/* The value of symbols of type N_SO and N_FUN maybe null when
+ it shouldn't be. */
+#define SOFUN_ADDRESS_MAYBE_MISSING
+
+/* Use generic shared library machinery. */
+#include "solib.h"
+
+#endif /* TM_PPC_EABI_H */
diff --git a/gdb/config/powerpc/tm-ppc-sim.h b/gdb/config/powerpc/tm-ppc-sim.h
new file mode 100644
index 00000000000..9fa11861e1a
--- /dev/null
+++ b/gdb/config/powerpc/tm-ppc-sim.h
@@ -0,0 +1,26 @@
+/* Macro definitions for Power PC running embedded ABI under the simulator.
+ 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. */
+
+#ifndef TM_PPC_SIM_H
+#define TM_PPC_SIM_H
+
+#include "powerpc/tm-ppc-eabi.h"
+
+#endif /* TM_PPC_SIM_H */
diff --git a/gdb/config/powerpc/tm-ppcle-eabi.h b/gdb/config/powerpc/tm-ppcle-eabi.h
new file mode 100644
index 00000000000..cc4c752e396
--- /dev/null
+++ b/gdb/config/powerpc/tm-ppcle-eabi.h
@@ -0,0 +1,28 @@
+/* Macro definitions for Power PC running embedded ABI
+ in little endian mode.
+ Copyright 1995, 1998 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. */
+
+#ifndef TM_PPCLE_EABI_H
+#define TM_PPCLE_EABI_H
+
+/* Use normal ppc-eabi definitions */
+#include "powerpc/tm-ppc-eabi.h"
+
+#endif /* TM_PPCLE_EABI_H */
diff --git a/gdb/config/powerpc/tm-ppcle-sim.h b/gdb/config/powerpc/tm-ppcle-sim.h
new file mode 100644
index 00000000000..02707f40019
--- /dev/null
+++ b/gdb/config/powerpc/tm-ppcle-sim.h
@@ -0,0 +1,26 @@
+/* Macro definitions for Power PC running embedded ABI under the simulator.
+ 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. */
+
+#ifndef TM_PPCLE_SIM_H
+#define TM_PPCLE_SIM_H
+
+#include "powerpc/tm-ppcle-eabi.h"
+
+#endif /* TM_PPCLE_SIM_H */
diff --git a/gdb/config/powerpc/tm-vxworks.h b/gdb/config/powerpc/tm-vxworks.h
new file mode 100644
index 00000000000..a31846a802f
--- /dev/null
+++ b/gdb/config/powerpc/tm-vxworks.h
@@ -0,0 +1,28 @@
+/* Target machine description for VxWorks on the PowerPC,
+ for GDB, the GNU debugger.
+ Copyright 1999 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. */
+
+#ifndef TM_VXWORKS_H
+#define TM_VXWORKS_H
+
+#include "powerpc/tm-ppc-eabi.h"
+#include "tm-vxworks.h"
+
+#endif /* ifndef TM_VXWORKS_H */
diff --git a/gdb/config/powerpc/vxworks.mt b/gdb/config/powerpc/vxworks.mt
new file mode 100644
index 00000000000..ba6e17bcb1c
--- /dev/null
+++ b/gdb/config/powerpc/vxworks.mt
@@ -0,0 +1,3 @@
+# Target: Powerpc running VxWorks
+TDEPFILES= rs6000-tdep.o ppc-linux-tdep.o solib.o solib-svr4.o
+TM_FILE= tm-vxworks.h
diff --git a/gdb/config/powerpc/xm-aix.h b/gdb/config/powerpc/xm-aix.h
new file mode 100644
index 00000000000..cc986502b77
--- /dev/null
+++ b/gdb/config/powerpc/xm-aix.h
@@ -0,0 +1,31 @@
+/* Parameters for hosting on an PowerPC, for GDB, the GNU debugger.
+ Copyright 1995, 1996, 2000 Free Software Foundation, Inc.
+ Contributed by Cygnus Corporation.
+
+ 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 "xm-aix4.h"
+
+/* This doesn't seem to be declared in any header file I can find. */
+char *termdef (int, int);
+
+/* UINT_MAX is defined in <sys/limits.h> as a decimal constant (4294967295)
+ which is too large to fit in a signed int when it is parsed by the
+ compiler, so it issues a diagnostic. Just undef it here so that we
+ use gdb's version in defs.h */
+#undef UINT_MAX
diff --git a/gdb/config/powerpc/xm-linux.h b/gdb/config/powerpc/xm-linux.h
new file mode 100644
index 00000000000..c8a029d1010
--- /dev/null
+++ b/gdb/config/powerpc/xm-linux.h
@@ -0,0 +1,38 @@
+/* Native support for linux, for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1992, 1996, 2000, 2001
+ 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. */
+
+#ifndef XM_LINUX_H
+#define XM_LINUX_H
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+#define KERNEL_U_ADDR 0x0
+
+/* If you expect to use the mmalloc package to obtain mapped symbol files,
+ for now you have to specify some parameters that determine how gdb places
+ the mappings in it's address space. See the comments in map_to_address()
+ for details. This is expected to only be a short term solution. Yes it
+ is a kludge.
+ FIXME: Make this more automatic. */
+
+#define MMAP_BASE_ADDRESS 0x20000000 /* First mapping here */
+#define MMAP_INCREMENT 0x01000000 /* Increment to next mapping */
+
+#endif /* #ifndef XM_LINUX_H */
diff --git a/gdb/config/romp/rtbsd.mh b/gdb/config/romp/rtbsd.mh
new file mode 100644
index 00000000000..1efa116fa18
--- /dev/null
+++ b/gdb/config/romp/rtbsd.mh
@@ -0,0 +1,8 @@
+# IBM RT/PC running BSD unix.
+# This file contributed at NYU, where we are using the RT to remote
+# debug an a29k running unix. No attempt, as of 7/16/91, has been made
+# to support debugging of RT executables.
+NATDEPFILES corelow.o core-aout.o infptrace.o inftarg.o fork-child.o
+MH_CFLAGS=-DHOSTING_ONLY # No debugging of RT executables
+XM_FILE= xm-rtbsd.h
+CC=gcc -traditional # hc/pcc just can't cut it.
diff --git a/gdb/config/romp/xm-rtbsd.h b/gdb/config/romp/xm-rtbsd.h
new file mode 100644
index 00000000000..e7918163ee2
--- /dev/null
+++ b/gdb/config/romp/xm-rtbsd.h
@@ -0,0 +1,37 @@
+/* Definitions to host GDB on an IBM RT/PC running BSD Unix.
+ Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
+ Contributed by David Wood @ New York University (wood@lab.ultra.nyu.edu).
+
+ 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. */
+
+/* This OS has the wait structure */
+#define HAVE_WAIT_STRUCT
+
+#ifdef HOSTING_ONLY
+/*
+ * This next two defines are to get GDB up and running as a host to
+ * do remote debugging. I know there is a gdb for the RT, but there wasn't
+ * an xconfig/rt* file.
+ */
+#define KERNEL_U_ADDR_BSD /* This may be correct, but hasn't been tested */
+#define REGISTER_U_ADDR(a,b,c) \
+ (printf("GDB can not debug IBM RT/PC BSD executables (yet)\n"),\
+ quit(),0)
+#else
+#include "GDB for the RT is not included in the distribution"
+#endif
diff --git a/gdb/config/rs6000/aix4.mh b/gdb/config/rs6000/aix4.mh
new file mode 100644
index 00000000000..e6253be9a22
--- /dev/null
+++ b/gdb/config/rs6000/aix4.mh
@@ -0,0 +1,11 @@
+# Host: IBM RS/6000 running AIX4
+
+XM_FILE= xm-aix4.h
+
+NAT_FILE= nm-rs6000.h
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o rs6000-nat.o \
+ xcoffsolib.o
+
+# When compiled with cc, for debugging, this argument should be passed.
+# We have no idea who our current compiler is though, so we skip it.
+# MH_CFLAGS = -bnodelcsect
diff --git a/gdb/config/rs6000/aix4.mt b/gdb/config/rs6000/aix4.mt
new file mode 100644
index 00000000000..fb9d0033fef
--- /dev/null
+++ b/gdb/config/rs6000/aix4.mt
@@ -0,0 +1,3 @@
+# Target: IBM RS/6000 running AIX4
+TDEPFILES= rs6000-tdep.o xcoffread.o ppc-linux-tdep.o solib.o solib-svr4.o
+TM_FILE= tm-rs6000-aix4.h
diff --git a/gdb/config/rs6000/nm-rs6000.h b/gdb/config/rs6000/nm-rs6000.h
new file mode 100644
index 00000000000..728497e7871
--- /dev/null
+++ b/gdb/config/rs6000/nm-rs6000.h
@@ -0,0 +1,66 @@
+/* IBM RS/6000 native-dependent macros for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1994, 1996, 1999, 2000, 2001
+ 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. */
+
+/* Do implement the attach and detach commands. */
+
+#define ATTACH_DETACH
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
+
+#define FETCH_INFERIOR_REGISTERS
+
+/* Override child_xfer_memory in infptrace.c. */
+
+#define CHILD_XFER_MEMORY
+
+/* When a child process is just starting, we sneak in and relocate
+ the symbol table (and other stuff) after the dynamic linker has
+ figured out where they go. */
+
+#define SOLIB_CREATE_INFERIOR_HOOK(PID) \
+ do { \
+ xcoff_relocate_symtab (PID); \
+ } while (0)
+
+/* When a target process or core-file has been attached, we sneak in
+ and figure out where the shared libraries have got to. */
+
+#define SOLIB_ADD(a, b, c, d) \
+ if (PIDGET (inferior_ptid)) \
+ /* Attach to process. */ \
+ xcoff_relocate_symtab (PIDGET (inferior_ptid)); \
+ else \
+ /* Core file. */ \
+ xcoff_relocate_core (c);
+
+extern void xcoff_relocate_symtab (unsigned int);
+struct target_ops;
+extern void xcoff_relocate_core (struct target_ops *);
+
+/* If ADDR lies in a shared library, return its name. */
+
+#define PC_SOLIB(PC) xcoff_solib_address(PC)
+extern char *xcoff_solib_address (CORE_ADDR);
+
+/* Return sizeof user struct to callers in less machine dependent routines */
+
+#define KERNEL_U_SIZE kernel_u_size()
+extern int kernel_u_size (void);
diff --git a/gdb/config/rs6000/nm-rs6000ly.h b/gdb/config/rs6000/nm-rs6000ly.h
new file mode 100644
index 00000000000..7bc1267d266
--- /dev/null
+++ b/gdb/config/rs6000/nm-rs6000ly.h
@@ -0,0 +1,26 @@
+/* Native-dependent definitions for RS6000 running LynxOS.
+ Copyright 1993 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. */
+
+#ifndef NM_RS6000LYNX_H
+#define NM_RS6000LYNX_H
+
+#include "nm-lynx.h"
+
+#endif /* NM_RS6000LYNX_H */
diff --git a/gdb/config/rs6000/rs6000.mh b/gdb/config/rs6000/rs6000.mh
new file mode 100644
index 00000000000..c57319be4fc
--- /dev/null
+++ b/gdb/config/rs6000/rs6000.mh
@@ -0,0 +1,11 @@
+# Host: IBM RS/6000 running AIX
+
+XM_FILE= xm-rs6000.h
+
+NAT_FILE= nm-rs6000.h
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o rs6000-nat.o \
+ xcoffsolib.o
+
+# When compiled with cc, for debugging, this argument should be passed.
+# We have no idea who our current compiler is though, so we skip it.
+# MH_CFLAGS = -bnodelcsect
diff --git a/gdb/config/rs6000/rs6000.mt b/gdb/config/rs6000/rs6000.mt
new file mode 100644
index 00000000000..5ffcc0165a4
--- /dev/null
+++ b/gdb/config/rs6000/rs6000.mt
@@ -0,0 +1,3 @@
+# Target: IBM RS/6000 running AIX
+TDEPFILES= rs6000-tdep.o xcoffread.o ppc-linux-tdep.o solib.o solib-svr4.o
+TM_FILE= tm-rs6000.h
diff --git a/gdb/config/rs6000/rs6000lynx.mh b/gdb/config/rs6000/rs6000lynx.mh
new file mode 100644
index 00000000000..096473f1a60
--- /dev/null
+++ b/gdb/config/rs6000/rs6000lynx.mh
@@ -0,0 +1,6 @@
+# Host: RS6000 running LynxOS
+
+XM_CLIBS= -lbsd
+
+NAT_FILE= nm-rs6000ly.h
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o lynx-nat.o xcoffread.o
diff --git a/gdb/config/rs6000/rs6000lynx.mt b/gdb/config/rs6000/rs6000lynx.mt
new file mode 100644
index 00000000000..69aeb60c221
--- /dev/null
+++ b/gdb/config/rs6000/rs6000lynx.mt
@@ -0,0 +1,3 @@
+# Target: IBM RS6000 running LynxOS
+TDEPFILES= coff-solib.o rs6000-tdep.o ppc-linux-tdep.o solib.o solib-svr4.o
+TM_FILE= tm-rs6000ly.h
diff --git a/gdb/config/rs6000/tm-rs6000-aix4.h b/gdb/config/rs6000/tm-rs6000-aix4.h
new file mode 100644
index 00000000000..243befe7d6f
--- /dev/null
+++ b/gdb/config/rs6000/tm-rs6000-aix4.h
@@ -0,0 +1,27 @@
+/* Macro definitions for RS/6000 running AIX4.
+ Copyright 1995, 1997 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. */
+
+#ifndef TM_RS6000_AIX4_H
+#define TM_RS6000_AIX4_H
+
+/* Use generic RS6000 definitions. */
+#include "rs6000/tm-rs6000.h"
+
+#endif /* TM_RS6000_AIX4_H */
diff --git a/gdb/config/rs6000/tm-rs6000.h b/gdb/config/rs6000/tm-rs6000.h
new file mode 100644
index 00000000000..202ac7751a7
--- /dev/null
+++ b/gdb/config/rs6000/tm-rs6000.h
@@ -0,0 +1,125 @@
+/* Parameters for target execution on an RS6000, for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000
+ Free Software Foundation, Inc.
+ Contributed by IBM Corporation.
+
+ 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. */
+
+#define GDB_MULTI_ARCH 1
+
+/* Minimum possible text address in AIX */
+
+#define TEXT_SEGMENT_BASE 0x10000000
+
+/* AIX's assembler doesn't grok dollar signs in identifiers.
+ So we use dots instead. This item must be coordinated with G++. */
+#undef CPLUS_MARKER
+#define CPLUS_MARKER '.'
+
+/* Return whether PC in function NAME is in code that should be skipped when
+ single-stepping. */
+
+#define IN_SOLIB_RETURN_TRAMPOLINE(pc, name) \
+ rs6000_in_solib_return_trampoline (pc, name)
+extern int rs6000_in_solib_return_trampoline (CORE_ADDR, char *);
+
+/* If PC is in some function-call trampoline code, return the PC
+ where the function itself actually starts. If not, return NULL. */
+
+#define SKIP_TRAMPOLINE_CODE(pc) rs6000_skip_trampoline_code (pc)
+extern CORE_ADDR rs6000_skip_trampoline_code (CORE_ADDR);
+
+/* Number of trap signals we need to skip over, once the inferior process
+ starts running. */
+
+#define START_INFERIOR_TRAPS_EXPECTED 2
+
+/* AIX has a couple of strange returns from wait(). */
+
+#define CHILD_SPECIAL_WAITSTATUS(ourstatus, hoststatus) ( \
+ /* "stop after load" status. */ \
+ (hoststatus) == 0x57c ? (ourstatus)->kind = TARGET_WAITKIND_LOADED, 1 : \
+ \
+ /* signal 0. I have no idea why wait(2) returns with this status word. */ \
+ /* It looks harmless. */ \
+ (hoststatus) == 0x7f ? (ourstatus)->kind = TARGET_WAITKIND_SPURIOUS, 1 : \
+ \
+ /* A normal waitstatus. Let the usual macros deal with it. */ \
+ 0)
+
+/* In xcoff, we cannot process line numbers when we see them. This is
+ mainly because we don't know the boundaries of the include files. So,
+ we postpone that, and then enter and sort(?) the whole line table at
+ once, when we are closing the current symbol table in end_symtab(). */
+
+#define PROCESS_LINENUMBER_HOOK() aix_process_linenos ()
+extern void aix_process_linenos (void);
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define FP0_REGNUM 32 /* Floating point register 0 */
+#define FPLAST_REGNUM 63 /* Last floating point register */
+
+/* These #defines are used to parse core files and talk to ptrace, so they
+ must remain fixed. */
+#define FIRST_UISA_SP_REGNUM 64 /* first special register number */
+#define LAST_UISA_SP_REGNUM 70 /* last special register number */
+
+/* Define other aspects of the stack frame. */
+
+#define INIT_FRAME_PC_FIRST(fromleaf, prev) \
+ prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (prev->next) : \
+ prev->next ? FRAME_SAVED_PC (prev->next) : read_pc ());
+#define INIT_FRAME_PC(fromleaf, prev) /* nothing */
+
+/* Flag for machine-specific stuff in shared files. FIXME */
+#define IBM6000_TARGET
+
+/* RS6000/AIX does not support PT_STEP. Has to be simulated. */
+
+#define SOFTWARE_SINGLE_STEP_P() 1
+extern void rs6000_software_single_step (enum target_signal, int);
+#define SOFTWARE_SINGLE_STEP(sig,bp_p) rs6000_software_single_step (sig, bp_p)
+
+/* Notice when a new child process is started. */
+
+#define TARGET_CREATE_INFERIOR_HOOK rs6000_create_inferior
+extern void rs6000_create_inferior (int);
+
+/* Hook in rs6000-tdep.c for determining the TOC address when
+ calling functions in the inferior. */
+
+extern CORE_ADDR (*rs6000_find_toc_address_hook) (CORE_ADDR);
+
+/* Hook in rs6000-tdep.c to set the current architecture when starting a
+ child process. */
+
+extern void (*rs6000_set_host_arch_hook) (int);
+
+/* We need solib.h for building cross debuggers. However, we don't want
+ to clobber any special solib support required by native debuggers, so
+ only include solib.h if SOLIB_ADD is not defined. */
+#ifndef SOLIB_ADD
+#include "solib.h"
+#endif
diff --git a/gdb/config/rs6000/tm-rs6000ly.h b/gdb/config/rs6000/tm-rs6000ly.h
new file mode 100644
index 00000000000..ca7dc0d41ee
--- /dev/null
+++ b/gdb/config/rs6000/tm-rs6000ly.h
@@ -0,0 +1,31 @@
+/* Macro definitions for RS6000 running under LynxOS.
+ Copyright 1993, 2000 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. */
+
+#ifndef TM_RS6000LYNX_H
+#define TM_RS6000LYNX_H
+
+#include "tm-lynx.h"
+
+/* Use generic RS6000 definitions. */
+#include "rs6000/tm-rs6000.h"
+
+#define CANNOT_STORE_REGISTER(regno) (regno == PS_REGNUM)
+
+#endif /* TM_RS6000LYNX_H */
diff --git a/gdb/config/rs6000/xm-aix4.h b/gdb/config/rs6000/xm-aix4.h
new file mode 100644
index 00000000000..5f7aa778f45
--- /dev/null
+++ b/gdb/config/rs6000/xm-aix4.h
@@ -0,0 +1,27 @@
+/* Parameters for hosting on an RS6000, for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1996
+ Free Software Foundation, Inc.
+ Contributed by IBM Corporation.
+
+ 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 "xm-aix4.h"
+
+/* AIX 4.x uses nonstandard "int *" as type of third argument to ptrace() */
+
+#define PTRACE_ARG3_TYPE int*
diff --git a/gdb/config/rs6000/xm-rs6000.h b/gdb/config/rs6000/xm-rs6000.h
new file mode 100644
index 00000000000..51096e643b0
--- /dev/null
+++ b/gdb/config/rs6000/xm-rs6000.h
@@ -0,0 +1,94 @@
+/* Parameters for hosting on an RS6000, for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
+ 2000, 2001 Free Software Foundation, Inc.
+ Contributed by IBM Corporation.
+
+ 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. */
+
+/* The following text is taken from config/rs6000.mh:
+ * # The IBM version of /usr/include/rpc/rpc.h has a bug -- it says
+ * # `extern fd_set svc_fdset;' without ever defining the type fd_set.
+ * # Unfortunately this occurs in the vx-share code, which is not configured
+ * # like the rest of GDB (e.g. it doesn't include "defs.h").
+ * # We circumvent this bug by #define-ing fd_set here, but undefining it in
+ * # the xm-rs6000.h file before ordinary modules try to use it. FIXME, IBM!
+ * MH_CFLAGS='-Dfd_set=int'
+ * So, here we do the undefine...which has to occur before we include
+ * <sys/select.h> below.
+ */
+#undef fd_set
+
+#include <sys/select.h>
+
+/* Big end is at the low address */
+
+/* At least as of AIX 3.2, we have termios. */
+#define HAVE_TERMIOS 1
+/* #define HAVE_TERMIO 1 */
+
+#define USG 1
+
+#define FIVE_ARG_PTRACE
+
+/* This system requires that we open a terminal with O_NOCTTY for it to
+ not become our controlling terminal. */
+
+#define USE_O_NOCTTY
+
+/* Brain death inherited from PC's pervades. */
+#undef NULL
+#define NULL 0
+
+/* The IBM compiler requires this in order to properly compile alloca(). */
+#pragma alloca
+
+/* There is no vfork. */
+
+#define vfork fork
+
+/* Signal handler for SIGWINCH `window size changed'. */
+
+#define SIGWINCH_HANDLER aix_resizewindow
+extern void aix_resizewindow (int);
+
+/* This doesn't seem to be declared in any header file I can find. */
+char *termdef (int, int);
+
+/* `lines_per_page' and `chars_per_line' are local to utils.c. Rectify this. */
+
+#define SIGWINCH_HANDLER_BODY \
+ \
+/* Respond to SIGWINCH `window size changed' signal, and reset GDB's \
+ window settings appropriately. */ \
+ \
+void \
+aix_resizewindow (signo) \
+ int signo; \
+{ \
+ int fd = fileno (stdout); \
+ if (isatty (fd)) { \
+ int val; \
+ \
+ val = atoi (termdef (fd, 'l')); \
+ if (val > 0) \
+ lines_per_page = val; \
+ val = atoi (termdef (fd, 'c')); \
+ if (val > 0) \
+ chars_per_line = val; \
+ } \
+}
diff --git a/gdb/config/s390/nm-linux.h b/gdb/config/s390/nm-linux.h
new file mode 100644
index 00000000000..3846579923f
--- /dev/null
+++ b/gdb/config/s390/nm-linux.h
@@ -0,0 +1,84 @@
+/* Native support for GNU/Linux on S390.
+
+ Copyright 2001, 2002 Free Software Foundation, Inc.
+
+ Ported by D.J. Barrow for IBM Deutschland Entwicklung GmbH, IBM
+ Corporation. derived from i390-nmlinux.h
+
+ 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. */
+
+#ifndef NM_LINUX_H
+#define NM_LINUX_H
+
+#include "config/nm-linux.h"
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = s390_register_u_addr((blockend),(regno));
+extern int s390_register_u_addr (int, int);
+
+/* Return sizeof user struct to callers in less machine dependent routines */
+
+#define KERNEL_U_SIZE kernel_u_size()
+extern int kernel_u_size (void);
+
+#define U_REGS_OFFSET 0
+
+
+/* We define this if link.h is available, because with ELF we use SVR4 style
+ shared libraries. */
+
+#ifdef HAVE_LINK_H
+#define SVR4_SHARED_LIBS
+#include "solib.h" /* Support for shared libraries. */
+#endif
+
+
+/* WATCHPOINT SPECIFIC STUFF */
+
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+#define HAVE_CONTINUABLE_WATCHPOINT
+#define target_insert_watchpoint(addr, len, type) \
+ s390_insert_watchpoint (PIDGET (inferior_ptid), addr, len, type)
+
+#define target_remove_watchpoint(addr, len, type) \
+ s390_remove_watchpoint (PIDGET (inferior_ptid), addr, len)
+
+extern int watch_area_cnt;
+/* gdb if really stupid & calls this all the time without a
+ watchpoint even being set */
+#define STOPPED_BY_WATCHPOINT(W) \
+ (watch_area_cnt&&s390_stopped_by_watchpoint (PIDGET(inferior_ptid)))
+
+extern CORE_ADDR s390_stopped_by_watchpoint (int);
+
+/*
+ Type can be 1 for a read_watchpoint or 2 for an access watchpoint.
+ */
+extern int s390_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw);
+extern int s390_remove_watchpoint (int pid, CORE_ADDR addr, int len);
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \
+ (((type) == bp_hardware_watchpoint)|| \
+ ((type) == bp_watchpoint)|| \
+ ((type) == bp_read_watchpoint) || \
+ ((type) == bp_access_watchpoint))
+
+
+/* Needed for s390x */
+#define PTRACE_ARG3_TYPE long
+#define PTRACE_XFER_TYPE long
+#endif /* nm_linux.h */
diff --git a/gdb/config/s390/s390.mh b/gdb/config/s390/s390.mh
new file mode 100644
index 00000000000..300a5e3c1ce
--- /dev/null
+++ b/gdb/config/s390/s390.mh
@@ -0,0 +1,13 @@
+# Host: S390, running Linux
+
+XM_FILE= xm-linux.h
+XM_CLIBS=
+
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o s390-nat.o \
+ core-aout.o core-regset.o linux-proc.o gcore.o thread-db.o lin-lwp.o \
+ proc-service.o
+LOADLIBES = -ldl -rdynamic
+
+
+
diff --git a/gdb/config/s390/s390.mt b/gdb/config/s390/s390.mt
new file mode 100644
index 00000000000..6b8d91fc83f
--- /dev/null
+++ b/gdb/config/s390/s390.mt
@@ -0,0 +1,6 @@
+# Target: S390 running Linux
+TM_FILE= tm-linux.h
+TDEPFILES=s390-tdep.o solib.o
+# Post 5.0 tdep-files
+TDEPFILES+=solib-svr4.o solib-legacy.o
+GDB_MULTI_ARCH=GDB_MULTI_ARCH_PARTIAL
diff --git a/gdb/config/s390/s390x.mt b/gdb/config/s390/s390x.mt
new file mode 100644
index 00000000000..7b23cad60cb
--- /dev/null
+++ b/gdb/config/s390/s390x.mt
@@ -0,0 +1,9 @@
+# Target: S390 running Linux
+TM_FILE= tm-linux.h
+TDEPFILES=s390-tdep.o solib.o
+# Post 5.0 tdep-files
+TDEPFILES+=solib-svr4.o solib-legacy.o
+GDB_MULTI_ARCH=GDB_MULTI_ARCH_PARTIAL
+
+# needed for gdbserver.
+MT_CFLAGS= -DCONFIG_ARCH_S390X
diff --git a/gdb/config/s390/tm-linux.h b/gdb/config/s390/tm-linux.h
new file mode 100644
index 00000000000..c1b4a294ad8
--- /dev/null
+++ b/gdb/config/s390/tm-linux.h
@@ -0,0 +1,44 @@
+/* Target definitions for GDB for a s390 running GNU/Linux.
+
+ Copyright 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ for IBM Deutschland Entwicklung GmbH, IBM Corporation.
+
+ 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. */
+
+#ifndef TM_LINUX_H
+#define TM_LINUX_H
+#ifdef GDBSERVER
+#define S390_GNULINUX_TARGET
+#endif /* GDBSERVER */
+#undef TARGET_ELF64
+#define TARGET_ELF64 (gdbarch_tdep (current_gdbarch)->intreg_size==8)
+
+#include "config/tm-linux.h"
+
+/* Zap several macros defined in the above header so that multi-arch
+ can safely re-define them. The ``correct fix'' involves
+ eliminating either the above include or even this file. */
+#undef SKIP_TRAMPOLINE_CODE
+
+#include "s390/tm-s390.h"
+
+
+
+#endif /* TM_LINUX_H */
diff --git a/gdb/config/s390/tm-s390.h b/gdb/config/s390/tm-s390.h
new file mode 100644
index 00000000000..1c6e6787099
--- /dev/null
+++ b/gdb/config/s390/tm-s390.h
@@ -0,0 +1,115 @@
+/* Macro definitions for GDB on an S390.
+ Copyright 2001 Free Software Foundation, Inc.
+ Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ for IBM Deutschland Entwicklung GmbH, IBM Corporation.
+
+ 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. */
+
+#if !defined(TM_S390_H)
+#define TM_S390_H 1
+
+#define S390_NUM_GPRS (16)
+#define S390_GPR_SIZE REGISTER_SIZE
+#define S390_PSW_MASK_SIZE REGISTER_SIZE
+#define S390_PSW_ADDR_SIZE REGISTER_SIZE
+#define S390_NUM_FPRS (16)
+#define S390_FPR_SIZE (8)
+#define S390_FPC_SIZE (4)
+#define S390_FPC_PAD_SIZE (4) /* gcc insists on aligning the fpregs */
+#define S390_NUM_CRS (16)
+#define S390_CR_SIZE REGISTER_SIZE
+#define S390_NUM_ACRS (16)
+#define S390_ACR_SIZE (4)
+
+#define S390_NUM_REGS (2+S390_NUM_GPRS+S390_NUM_ACRS+S390_NUM_CRS+1+S390_NUM_FPRS)
+#define S390_FIRST_ACR (2+S390_NUM_GPRS)
+#define S390_LAST_ACR (S390_FIRST_ACR+S390_NUM_ACRS-1)
+#define S390_FIRST_CR (S390_FIRST_ACR+S390_NUM_ACRS)
+#define S390_LAST_CR (S390_FIRST_CR+S390_NUM_CRS-1)
+
+#define S390_PSWM_REGNUM 0
+#define S390_PC_REGNUM 1
+#define S390_GP0_REGNUM 2 /* GPR register 0 */
+#define S390_GP_LAST_REGNUM (S390_GP0_REGNUM+S390_NUM_GPRS-1)
+/* Usually return address */
+#define S390_RETADDR_REGNUM (S390_GP0_REGNUM+14)
+/* Contains address of top of stack */
+#define S390_SP_REGNUM (S390_GP0_REGNUM+15)
+/* needed in findvar.c still */
+#define S390_FP_REGNUM S390_SP_REGNUM
+#define S390_FRAME_REGNUM (S390_GP0_REGNUM+11)
+#define S390_FPC_REGNUM (S390_GP0_REGNUM+S390_NUM_GPRS+S390_NUM_ACRS+S390_NUM_CRS)
+/* FPR (Floating point) register 0 */
+#define S390_FP0_REGNUM (S390_FPC_REGNUM+1)
+/* Last floating point register */
+#define S390_FPLAST_REGNUM (S390_FP0_REGNUM+S390_NUM_FPRS-1)
+#define S390_LAST_REGNUM S390_FPLAST_REGNUM
+
+
+#define S390_ACR0_OFFSET ((S390_PSW_MASK_SIZE+S390_PSW_ADDR_SIZE)+(S390_GPR_SIZE*S390_NUM_GPRS))
+#define S390_CR0_OFFSET (S390_ACR0_OFFSET+(S390_ACR_SIZE*S390_NUM_ACRS))
+#define S390_FPC_OFFSET (S390_CR0_OFFSET+(S390_CR_SIZE*S390_NUM_CRS))
+#define S390_FP0_OFFSET (S390_FPC_OFFSET+(S390_FPC_SIZE+S390_FPC_PAD_SIZE))
+#define S390_GPR6_STACK_OFFSET (GDB_TARGET_IS_ESAME ? 48:24)
+
+#define S390_REGISTER_BYTES ((4+4)+(4*S390_NUM_GPRS)+(4*S390_NUM_ACRS)+ \
+(4*S390_NUM_CRS)+(S390_FPC_SIZE+S390_FPC_PAD_SIZE)+(S390_FPR_SIZE*S390_NUM_FPRS))
+
+#define S390X_REGISTER_BYTES ((8+8)+(8*S390_NUM_GPRS)+(4*S390_NUM_ACRS)+ \
+(8*S390_NUM_CRS)+(S390_FPC_SIZE+S390_FPC_PAD_SIZE)+(S390_FPR_SIZE*S390_NUM_FPRS))
+
+#ifdef GDBSERVER
+
+int s390_register_byte (int reg_nr);
+#define REGISTER_BYTE(reg_nr) s390_register_byte(reg_nr)
+#define PC_REGNUM S390_PC_REGNUM
+#define NUM_REGS S390_NUM_REGS
+#define NUM_FREGS S390_NUM_FPRS
+#define FP_REGNUM S390_FP_REGNUM
+#define SP_REGNUM S390_SP_REGNUM
+/* Obviously ptrace for user program tracing cannot be allowed
+ mess with control registers (except per registers for hardware watchpoints),
+ when we add kernel debugging we may need to alter these macros. */
+int s390_cannot_fetch_register (int regno);
+#define CANNOT_FETCH_REGISTER(regno) s390_cannot_fetch_register(regno)
+#define CANNOT_STORE_REGISTER(regno) s390_cannot_fetch_register(regno)
+
+#if CONFIG_ARCH_S390X
+
+int s390x_register_raw_size (int reg_nr);
+#define REGISTER_RAW_SIZE(reg_nr) s390x_register_raw_size(reg_nr)
+#define GDB_TARGET_IS_ESAME (1)
+#define REGISTER_SIZE (8)
+#define REGISTER_BYTES S390X_REGISTER_BYTES
+
+#else /* CONFIG_ARCH_S390X */
+
+int s390_register_raw_size (int reg_nr);
+#define REGISTER_RAW_SIZE(reg_nr) s390_register_raw_size(reg_nr)
+#define GDB_TARGET_IS_ESAME (0)
+#define REGISTER_SIZE (4)
+#define REGISTER_BYTES S390_REGISTER_BYTES
+
+#endif /* CONFIG_ARCH_S390X */
+
+#else /* GDBSERVER */
+
+#define GDB_TARGET_IS_ESAME (TARGET_ARCHITECTURE->mach == bfd_mach_s390_64)
+
+#endif /* GDBSERVER */
+#endif /* ifndef TM_S390_H */
diff --git a/gdb/config/s390/xm-linux.h b/gdb/config/s390/xm-linux.h
new file mode 100644
index 00000000000..d059d4097f4
--- /dev/null
+++ b/gdb/config/s390/xm-linux.h
@@ -0,0 +1,30 @@
+/* Native support for GNU/Linux, for GDB, the GNU debugger.
+ Copyright 2001 Free Software Foundation, Inc.
+ Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ for IBM Deutschland Entwicklung GmbH, IBM Corporation.
+
+ 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. */
+
+#ifndef XM_LINUX_H
+#define XM_LINUX_H
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+#define KERNEL_U_ADDR 0x0
+
+#endif /* #ifndef XM_LINUX_H */
diff --git a/gdb/config/sh/embed.mt b/gdb/config/sh/embed.mt
new file mode 100644
index 00000000000..0f37e43d915
--- /dev/null
+++ b/gdb/config/sh/embed.mt
@@ -0,0 +1,6 @@
+# Target: Embedded Hitachi Super-H with ICE and simulator
+TDEPFILES= sh-tdep.o monitor.o sh3-rom.o remote-e7000.o ser-e7kpc.o dsrec.o
+TM_FILE= tm-sh.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/sh/libsim.a
diff --git a/gdb/config/sh/linux.mt b/gdb/config/sh/linux.mt
new file mode 100644
index 00000000000..ea8460cdee9
--- /dev/null
+++ b/gdb/config/sh/linux.mt
@@ -0,0 +1,8 @@
+# Target: Hitachi Super-H running GNU/Linux
+TDEPFILES= sh-tdep.o monitor.o sh3-rom.o remote-e7000.o ser-e7kpc.o dsrec.o solib.o solib-svr4.o solib-legacy.o
+TM_FILE= tm-linux.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/sh/libsim.a
+
+GDBSERVER_DEPFILES = linux-low.o linux-sh-low.o reg-sh.o
diff --git a/gdb/config/sh/nbsd.mh b/gdb/config/sh/nbsd.mh
new file mode 100644
index 00000000000..dd677b60e4b
--- /dev/null
+++ b/gdb/config/sh/nbsd.mh
@@ -0,0 +1,4 @@
+# Host: SuperH running NetBSD
+NAT_CLIBS=
+NATDEPFILES= infptrace.o inftarg.o fork-child.o shnbsd-nat.o
+NAT_FILE= nm-nbsd.h
diff --git a/gdb/config/sh/nbsd.mt b/gdb/config/sh/nbsd.mt
new file mode 100644
index 00000000000..62d0c5ce3e8
--- /dev/null
+++ b/gdb/config/sh/nbsd.mt
@@ -0,0 +1,6 @@
+# Target: SuperH running NetBSD
+TDEPFILES= sh-tdep.o shnbsd-tdep.o corelow.o nbsd-tdep.o solib.o solib-svr4.o
+TM_FILE= tm-nbsd.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/sh/libsim.a
diff --git a/gdb/config/sh/nm-nbsd.h b/gdb/config/sh/nm-nbsd.h
new file mode 100644
index 00000000000..eb38d6b49ea
--- /dev/null
+++ b/gdb/config/sh/nm-nbsd.h
@@ -0,0 +1,28 @@
+/* Native-dependent definitions for SuperH running NetBSD, for GDB.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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. */
+
+#ifndef NM_NBSD_H
+#define NM_NBSD_H
+
+/* Get generic NetBSD native definitions. */
+#include "config/nm-nbsd.h"
+
+#endif /* NM_NBSD_H */
diff --git a/gdb/config/sh/tm-linux.h b/gdb/config/sh/tm-linux.h
new file mode 100644
index 00000000000..ab1d4d86f21
--- /dev/null
+++ b/gdb/config/sh/tm-linux.h
@@ -0,0 +1,32 @@
+/* Target-specific definitions for GNU/Linux running on a Hitachi
+ Super-H.
+
+ Copyright 2000, 2002 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. */
+
+/* Pull in GNU/Linux generic defs. */
+#include "tm-linux.h"
+
+/* Pull in sh-target defs */
+#include "sh/tm-sh.h"
+
+/* Use target_specific function to define link map offsets. */
+extern struct link_map_offsets *sh_linux_svr4_fetch_link_map_offsets (void);
+#define SVR4_FETCH_LINK_MAP_OFFSETS() sh_linux_svr4_fetch_link_map_offsets ()
+
diff --git a/gdb/config/sh/tm-nbsd.h b/gdb/config/sh/tm-nbsd.h
new file mode 100644
index 00000000000..37dfe3452e2
--- /dev/null
+++ b/gdb/config/sh/tm-nbsd.h
@@ -0,0 +1,28 @@
+/* Target-dependent definitions for SuperH running NetBSD, for GDB.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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. */
+
+#ifndef TM_NBSD_H
+#define TM_NBSD_H
+
+#include "sh/tm-sh.h"
+#include "solib.h"
+
+#endif /* TM_NBSD_H */
diff --git a/gdb/config/sh/tm-sh.h b/gdb/config/sh/tm-sh.h
new file mode 100644
index 00000000000..6ae6085d9b7
--- /dev/null
+++ b/gdb/config/sh/tm-sh.h
@@ -0,0 +1,33 @@
+/* Target-specific definition for a Hitachi Super-H.
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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. */
+
+/* Contributed by Steve Chamberlain sac@cygnus.com */
+
+#define GDB_MULTI_ARCH 1
+
+#define NUM_REALREGS 59 /* used in remote-e7000.c which is not multiarched. */
+
+#define REGISTER_TYPE long /* used in standalone.c */
+
+#define BIG_REMOTE_BREAKPOINT { 0xc3, 0x20 } /* Used in remote.c */
+#define LITTLE_REMOTE_BREAKPOINT { 0x20, 0xc3 } /* Used in remote.c */
+
+/*#define NOP {0x20, 0x0b}*/ /* Who uses this???*/
diff --git a/gdb/config/sh/tm-wince.h b/gdb/config/sh/tm-wince.h
new file mode 100644
index 00000000000..cbe570b16d0
--- /dev/null
+++ b/gdb/config/sh/tm-wince.h
@@ -0,0 +1,32 @@
+/* Target-specific definition for Window CE
+ Copyright 2000 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. */
+
+#ifndef TM_WINCE_H
+#define TM_WINCE_H 1
+
+#include "sh/tm-sh.h"
+#undef SOFTWARE_SINGLE_STEP_P
+#define SOFTWARE_SINGLE_STEP_P() 1
+
+#undef SOFTWARE_SINGLE_STEP
+#define SOFTWARE_SINGLE_STEP(sig, bp_p) wince_software_single_step (sig, bp_p)
+void wince_software_single_step (unsigned int, int);
+
+#endif /* TM_WINCE_H */
diff --git a/gdb/config/sh/wince.mt b/gdb/config/sh/wince.mt
new file mode 100644
index 00000000000..237a0bc3428
--- /dev/null
+++ b/gdb/config/sh/wince.mt
@@ -0,0 +1,5 @@
+# Target: Hitachi Super-H running on Windows CE
+TDEPFILES= sh-tdep.o wince.o
+TM_FILE= tm-wince.h
+MT_CFLAGS=-DSHx -U_X86_ -U_M_IX86 -U__i386__ -U__i486__ -U__i586__ -U__i686__ -DUNICODE -D_WIN32_WCE -DWINCE_STUB='"${target_alias}-stub.exe"'
+WIN32LIBS=-lrapi
diff --git a/gdb/config/sparc/fbsd.mh b/gdb/config/sparc/fbsd.mh
new file mode 100644
index 00000000000..33c6dc7d7a1
--- /dev/null
+++ b/gdb/config/sparc/fbsd.mh
@@ -0,0 +1,25 @@
+# Host-dependent settings for FreeBSD/sparc64.
+# Copyright 2002 Free Software Foundation, Inc.
+# Contributed by David E. O'Brien <obrien@FreeBSD.org>.
+#
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+# Host: FreeBSD/sparc64
+NATDEPFILES= sparc-nat.o \
+ corelow.o fork-child.o infptrace.o inftarg.o \
+ solib.o solib-svr4.o solib-legacy.o
+NAT_FILE= nm-fbsd.h
diff --git a/gdb/config/sparc/fbsd.mt b/gdb/config/sparc/fbsd.mt
new file mode 100644
index 00000000000..317c290f9c4
--- /dev/null
+++ b/gdb/config/sparc/fbsd.mt
@@ -0,0 +1,23 @@
+# Target-dependent settings for FreeBSD/sparc64.
+# Copyright 2002 Free Software Foundation, Inc.
+# Contributed by David E. O'Brien <obrien@FreeBSD.org>.
+#
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+# Target: FreeBSD/sparc64
+TDEPFILES= sparc-tdep.o solib.o solib-svr4.o solib-legacy.o
+TM_FILE= tm-fbsd.h
diff --git a/gdb/config/sparc/linux.mh b/gdb/config/sparc/linux.mh
new file mode 100644
index 00000000000..4a2c41f38c4
--- /dev/null
+++ b/gdb/config/sparc/linux.mh
@@ -0,0 +1,14 @@
+# Host: Sparcstation, running GNU/Linux.
+
+XM_FILE= xm-linux.h
+
+NAT_FILE= nm-linux.h
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparc-nat.o \
+ proc-service.o thread-db.o lin-lwp.o sparc-linux-nat.o \
+ linux-proc.o gcore.o
+
+# The dynamically loaded libthread_db needs access to symbols in the
+# gdb executable.
+LOADLIBES = -ldl -rdynamic
+
+HOST_IPC=-DBSD_IPC
diff --git a/gdb/config/sparc/linux.mt b/gdb/config/sparc/linux.mt
new file mode 100644
index 00000000000..d6cf773a8ee
--- /dev/null
+++ b/gdb/config/sparc/linux.mt
@@ -0,0 +1,3 @@
+# Target: Sparcstation, running Linux
+TDEPFILES= sparc-tdep.o solib.o solib-svr4.o solib-legacy.o
+TM_FILE= tm-linux.h
diff --git a/gdb/config/sparc/nbsd64.mh b/gdb/config/sparc/nbsd64.mh
new file mode 100644
index 00000000000..eb54e489eb8
--- /dev/null
+++ b/gdb/config/sparc/nbsd64.mh
@@ -0,0 +1,3 @@
+# Host: UltraSPARC running NetBSD
+NATDEPFILES= fork-child.o infptrace.o inftarg.o sparc64nbsd-nat.o
+NAT_FILE= nm-nbsd.h
diff --git a/gdb/config/sparc/nbsd64.mt b/gdb/config/sparc/nbsd64.mt
new file mode 100644
index 00000000000..93b8f7841d4
--- /dev/null
+++ b/gdb/config/sparc/nbsd64.mt
@@ -0,0 +1,4 @@
+# Target: UltraSPARC running NetBSD
+TDEPFILES= sparc-tdep.o sparcnbsd-tdep.o nbsd-tdep.o corelow.o solib.o \
+ solib-svr4.o
+TM_FILE= tm-nbsd64.h
diff --git a/gdb/config/sparc/nbsdaout.mh b/gdb/config/sparc/nbsdaout.mh
new file mode 100644
index 00000000000..ecb69e473da
--- /dev/null
+++ b/gdb/config/sparc/nbsdaout.mh
@@ -0,0 +1,6 @@
+# Host: Sun 4 or Sparcstation, running NetBSD
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparc-nat.o \
+ solib.o solib-sunos.o
+XM_FILE= xm-nbsd.h
+NAT_FILE= nm-nbsdaout.h
+HOST_IPC=-DBSD_IPC
diff --git a/gdb/config/sparc/nbsdaout.mt b/gdb/config/sparc/nbsdaout.mt
new file mode 100644
index 00000000000..c603f363fb5
--- /dev/null
+++ b/gdb/config/sparc/nbsdaout.mt
@@ -0,0 +1,3 @@
+# Target: Sun 4 or Sparcstation, running NetBSD
+TDEPFILES= sparc-tdep.o
+TM_FILE= tm-nbsdaout.h
diff --git a/gdb/config/sparc/nbsdelf.mh b/gdb/config/sparc/nbsdelf.mh
new file mode 100644
index 00000000000..8581c1b92ab
--- /dev/null
+++ b/gdb/config/sparc/nbsdelf.mh
@@ -0,0 +1,6 @@
+# Host: Sun 4 or Sparcstation, running NetBSD
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparc-nat.o \
+ solib.o solib-svr4.o solib-legacy.o
+XM_FILE= xm-nbsd.h
+NAT_FILE= nm-nbsd.h
+HOST_IPC=-DBSD_IPC
diff --git a/gdb/config/sparc/nbsdelf.mt b/gdb/config/sparc/nbsdelf.mt
new file mode 100644
index 00000000000..5c89318bfe9
--- /dev/null
+++ b/gdb/config/sparc/nbsdelf.mt
@@ -0,0 +1,3 @@
+# Target: Sun 4 or Sparcstation, running NetBSD
+TDEPFILES= sparc-tdep.o
+TM_FILE= tm-nbsd.h
diff --git a/gdb/config/sparc/nm-fbsd.h b/gdb/config/sparc/nm-fbsd.h
new file mode 100644
index 00000000000..87b9622348c
--- /dev/null
+++ b/gdb/config/sparc/nm-fbsd.h
@@ -0,0 +1,67 @@
+/* Native-dependent definitions for FreeBSD/sparc64.
+ Copyright 2002
+ Free Software Foundation, Inc.
+ Contributed by David E. O'Brien <obrien@FreeBSD.org>.
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef NM_FBSD_H
+#define NM_FBSD_H
+
+/* Type of the third argument to the `ptrace' system call. */
+#define PTRACE_ARG3_TYPE caddr_t
+
+/* Override copies of {fetch,store}_inferior_registers in `infptrace.c'. */
+#define FETCH_INFERIOR_REGISTERS
+
+/* We can attach and detach. */
+#define ATTACH_DETACH
+
+
+/* Shared library support. */
+
+#define SVR4_SHARED_LIBS
+
+#include "solib.h" /* Support for shared libraries. */
+#include "elf/common.h" /* Additional ELF shared library info. */
+
+/* Make things match up with what is expected in sparc-nat.c. */
+
+#define PTRACE_GETREGS PT_GETREGS
+#define PTRACE_SETREGS PT_SETREGS
+#define PTRACE_GETFPREGS PT_GETFPREGS
+#define PTRACE_SETFPREGS PT_SETFPREGS
+
+#define GDB_GREGSET_T struct reg
+#define GDB_FPREGSET_T struct fpreg
+
+#define regs trapframe
+#define r_g1 tf_global[1]
+#define r_ps tf_tstate
+#define r_pc tf_tpc
+#define r_npc tf_tnpc
+#define r_y tf_y
+
+#define FPU_FSR_TYPE unsigned long
+#define fp_status fpreg /* our reg.h */
+#define fpu fpreg /* our reg.h */
+#define fpu_regs fr_regs /* one field of fpu_fr on Solaris */
+#define fpu_fr fr_regs /* a union w/in struct fpu on Solaris */
+#define fpu_fsr fr_fsr
+#define Fpu_fsr fr_fsr
+
+#endif /* NM_FBSD_H */
diff --git a/gdb/config/sparc/nm-linux.h b/gdb/config/sparc/nm-linux.h
new file mode 100644
index 00000000000..80ab0423cd0
--- /dev/null
+++ b/gdb/config/sparc/nm-linux.h
@@ -0,0 +1,32 @@
+/* Macro definitions for running gdb on a Sparc running GNU/Linux.
+
+ Copyright 1989, 1992, 1996, 1998, 1999, 2000, 2002 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 <nm-sysv4.h>
+#include "nm-linux.h"
+#include "solib.h"
+
+#define FETCH_INFERIOR_REGISTERS
+
+/* Return sizeof user struct to callers in less machine dependent routines */
+
+#define KERNEL_U_SIZE kernel_u_size()
+extern int kernel_u_size (void);
diff --git a/gdb/config/sparc/nm-nbsd.h b/gdb/config/sparc/nm-nbsd.h
new file mode 100644
index 00000000000..653be852d85
--- /dev/null
+++ b/gdb/config/sparc/nm-nbsd.h
@@ -0,0 +1,61 @@
+/* Native-dependent definitions for Sparc running NetBSD, for GDB.
+ Copyright 1986, 1987, 1989, 1992, 1994, 1996, 1999, 2000
+ 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. */
+
+#ifndef NM_NBSD_H
+#define NM_NBSD_H
+
+#include "regcache.h"
+
+/* Get generic NetBSD native definitions. */
+
+#include "config/nm-nbsd.h"
+
+/* Before storing, we need to read all the registers. */
+
+#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
+
+/* Make things match up with what is expected in sparc-nat.c. */
+
+#define regs trapframe
+#define fp_status fpstate
+
+#define r_g1 tf_global[1]
+#define r_ps tf_psr
+#define r_pc tf_pc
+#define r_npc tf_npc
+#define r_y tf_y
+
+#define fpu fpstate
+#define fpu_regs fs_regs
+#define fpu_fsr fs_fsr
+#define fpu_fr fs_regs
+#define Fpu_fsr fs_fsr
+#define FPU_FSR_TYPE int
+
+#define PTRACE_GETREGS PT_GETREGS
+#define PTRACE_GETFPREGS PT_GETFPREGS
+#define PTRACE_SETREGS PT_SETREGS
+#define PTRACE_SETFPREGS PT_SETFPREGS
+
+#define GDB_GREGSET_T struct reg
+#define GDB_FPREGSET_T struct fpreg
+
+#endif /* NM_NBSD_H */
diff --git a/gdb/config/sparc/nm-nbsdaout.h b/gdb/config/sparc/nm-nbsdaout.h
new file mode 100644
index 00000000000..730759153e0
--- /dev/null
+++ b/gdb/config/sparc/nm-nbsdaout.h
@@ -0,0 +1,30 @@
+/* Native-dependent definitions for Sparc running NetBSD a.out, for GDB.
+ Copyright 1999 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. */
+
+#ifndef NM_NBSDAOUT_H
+#define NM_NBSDAOUT_H
+
+#include "sparc/nm-nbsd.h"
+
+/* Get generic NetBSD a.out native definitions. */
+
+#include "config/nm-nbsdaout.h"
+
+#endif /* NM_NBSDAOUT_H */
diff --git a/gdb/config/sparc/nm-sparclynx.h b/gdb/config/sparc/nm-sparclynx.h
new file mode 100644
index 00000000000..74304be36d3
--- /dev/null
+++ b/gdb/config/sparc/nm-sparclynx.h
@@ -0,0 +1,26 @@
+/* Native-dependent definitions for Sparc running LynxOS.
+ Copyright 1993, 1994 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. */
+
+#ifndef NM_SPARCLYNX_H
+#define NM_SPARCLYNX_H
+
+#include "nm-lynx.h"
+
+#endif /* NM_SPARCLYNX_H */
diff --git a/gdb/config/sparc/nm-sun4os4.h b/gdb/config/sparc/nm-sun4os4.h
new file mode 100644
index 00000000000..d874d582418
--- /dev/null
+++ b/gdb/config/sparc/nm-sun4os4.h
@@ -0,0 +1,42 @@
+/* Macro definitions for running gdb on a Sun 4 running sunos 4.
+ Copyright 1989, 1992, 1996, 2000 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 "regcache.h"
+
+/* Do implement the attach and detach commands. */
+
+#define ATTACH_DETACH
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
+
+#define FETCH_INFERIOR_REGISTERS
+
+/* Before storing, we need to read all the registers. */
+
+#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
+
+/* Return sizeof user struct to callers in less machine dependent routines */
+
+#define KERNEL_U_SIZE kernel_u_size()
+extern int kernel_u_size (void);
+
+/* SunOS 4.x uses nonstandard "char *" as type of third argument to ptrace() */
+
+#define PTRACE_ARG3_TYPE char*
diff --git a/gdb/config/sparc/nm-sun4sol2.h b/gdb/config/sparc/nm-sun4sol2.h
new file mode 100644
index 00000000000..adc8231f8e8
--- /dev/null
+++ b/gdb/config/sparc/nm-sun4sol2.h
@@ -0,0 +1,69 @@
+/* Native-dependent definitions for Sparc running SVR4.
+ Copyright 1994, 1996, 1997, 1999, 2000 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 "regcache.h"
+
+/* Include the generic SVR4 definitions. */
+
+#include <nm-sysv4.h>
+
+/* Before storing, we need to read all the registers. */
+
+#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
+
+/* Solaris PSRVADDR support does not seem to include a place for nPC. */
+
+#define PRSVADDR_BROKEN
+
+/* gdb wants to use the prgregset_t interface rather than
+ the gregset_t interface, partly because that's what's
+ used in core-sol2.c */
+
+#define GDB_GREGSET_T prgregset_t
+#define GDB_FPREGSET_T prfpregset_t
+
+#ifdef NEW_PROC_API /* Solaris 6 and above can do HW watchpoints */
+
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+
+/* The man page for proc4 on solaris 6 and 7 says that the system
+ can support "thousands" of hardware watchpoints, but gives no
+ method for finding out how many. So just tell GDB 'yes'. */
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE, CNT, OT) 1
+
+/* When a hardware watchpoint fires off the PC will be left at the
+ instruction following the one which caused the watchpoint.
+ It will *NOT* be necessary for GDB to step over the watchpoint. */
+#define HAVE_CONTINUABLE_WATCHPOINT
+
+extern int procfs_stopped_by_watchpoint (ptid_t);
+#define STOPPED_BY_WATCHPOINT(W) \
+ procfs_stopped_by_watchpoint(inferior_ptid)
+
+/* Use these macros for watchpoint insertion/deletion. */
+/* type can be 0: write watch, 1: read watch, 2: access watch (read/write) */
+
+extern int procfs_set_watchpoint (ptid_t, CORE_ADDR, int, int, int);
+#define target_insert_watchpoint(ADDR, LEN, TYPE) \
+ procfs_set_watchpoint (inferior_ptid, ADDR, LEN, TYPE, 1)
+#define target_remove_watchpoint(ADDR, LEN, TYPE) \
+ procfs_set_watchpoint (inferior_ptid, ADDR, 0, 0, 0)
+
+#endif /* NEW_PROC_API */
diff --git a/gdb/config/sparc/sp64.mt b/gdb/config/sparc/sp64.mt
new file mode 100644
index 00000000000..8bb1e07ed1c
--- /dev/null
+++ b/gdb/config/sparc/sp64.mt
@@ -0,0 +1,9 @@
+# Target: SPARC64
+# solib.o and procfs.o taken out for now. We don't have shared libraries yet,
+# and the elf version requires procfs.o but the a.out version doesn't.
+# Then again, having procfs.o in a target makefile fragment seems wrong.
+TDEPFILES = sparc-tdep.o
+TM_FILE= tm-sp64.h
+
+# Need gcc for long long support.
+CC = gcc
diff --git a/gdb/config/sparc/sp64linux.mt b/gdb/config/sparc/sp64linux.mt
new file mode 100644
index 00000000000..d7d642ead71
--- /dev/null
+++ b/gdb/config/sparc/sp64linux.mt
@@ -0,0 +1,3 @@
+# Target: UltraSPARC, running Linux 64bit programs
+TDEPFILES= sparc-tdep.o solib.o solib-svr4.o solib-legacy.o
+TM_FILE= tm-sp64linux.h
diff --git a/gdb/config/sparc/sp64sim.mt b/gdb/config/sparc/sp64sim.mt
new file mode 100644
index 00000000000..a9c5ac94cd4
--- /dev/null
+++ b/gdb/config/sparc/sp64sim.mt
@@ -0,0 +1,13 @@
+# Target: SPARC64 (with simulator)
+# solib.o and procfs.o taken out for now. We don't have shared libraries yet,
+# and the elf version requires procfs.o but the a.out version doesn't.
+# Then again, having procfs.o in a target makefile fragment seems wrong.
+TDEPFILES = sparc-tdep.o
+TM_FILE= tm-sp64.h
+
+# Need gcc for long long support.
+CC = gcc
+
+MH_CFLAGS = -I${srcdir}/../sim/sp64
+SIM_OBS = remote-sim.o
+SIM = ../sim/sp64/libsim.a
diff --git a/gdb/config/sparc/sp64sol2.mt b/gdb/config/sparc/sp64sol2.mt
new file mode 100644
index 00000000000..ce2f0d82df0
--- /dev/null
+++ b/gdb/config/sparc/sp64sol2.mt
@@ -0,0 +1,3 @@
+# Target: Ultrasparc, running Solaris 2
+TDEPFILES= sparc-tdep.o
+TM_FILE= tm-sun4sol2.h
diff --git a/gdb/config/sparc/sparc-em.mt b/gdb/config/sparc/sparc-em.mt
new file mode 100644
index 00000000000..13b0c6a29e2
--- /dev/null
+++ b/gdb/config/sparc/sparc-em.mt
@@ -0,0 +1,3 @@
+# Target: SPARC embedded
+TDEPFILES= sparc-tdep.o
+TM_FILE= tm-spc-em.h
diff --git a/gdb/config/sparc/sparclet.mt b/gdb/config/sparc/sparclet.mt
new file mode 100644
index 00000000000..f08cfd70e5b
--- /dev/null
+++ b/gdb/config/sparc/sparclet.mt
@@ -0,0 +1,3 @@
+# Target: SPARC embedded Sparclet monitor
+TDEPFILES= sparc-tdep.o monitor.o sparclet-rom.o dsrec.o
+TM_FILE= tm-sparclet.h
diff --git a/gdb/config/sparc/sparclite.mt b/gdb/config/sparc/sparclite.mt
new file mode 100644
index 00000000000..43cb38cafa6
--- /dev/null
+++ b/gdb/config/sparc/sparclite.mt
@@ -0,0 +1,5 @@
+# Target: Fujitsu SPARClite processor
+TDEPFILES= sparc-tdep.o sparcl-tdep.o
+TM_FILE= tm-sparclite.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/erc32/libsim.a
diff --git a/gdb/config/sparc/sparclynx.mh b/gdb/config/sparc/sparclynx.mh
new file mode 100644
index 00000000000..c573604b66a
--- /dev/null
+++ b/gdb/config/sparc/sparclynx.mh
@@ -0,0 +1,6 @@
+# Host: Sparc running LynxOS
+
+XM_CLIBS= -lbsd
+
+NAT_FILE= nm-sparclynx.h
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o lynx-nat.o
diff --git a/gdb/config/sparc/sparclynx.mt b/gdb/config/sparc/sparclynx.mt
new file mode 100644
index 00000000000..5e61645caaa
--- /dev/null
+++ b/gdb/config/sparc/sparclynx.mt
@@ -0,0 +1,3 @@
+# Target: Sparc running LynxOS
+TDEPFILES= coff-solib.o sparc-tdep.o
+TM_FILE= tm-sparclynx.h
diff --git a/gdb/config/sparc/sun4os4.mh b/gdb/config/sparc/sun4os4.mh
new file mode 100644
index 00000000000..4e664d71ccb
--- /dev/null
+++ b/gdb/config/sparc/sun4os4.mh
@@ -0,0 +1,9 @@
+# Host: Sun 4 or Sparcstation, running SunOS 4
+NAT_FILE= nm-sun4os4.h
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparc-nat.o
+HOST_IPC=-DBSD_IPC
+
+# Setting XM_CLIBS=-lresolv would let us use the DNS, but that would screw
+# anyone who wants to use NIS, which includes at least one Cygnus customer
+# (PR 3593). So leave it this way until/unless we find a resolver which can
+# get names from either DNS or NIS from the same GDB binary.
diff --git a/gdb/config/sparc/sun4os4.mt b/gdb/config/sparc/sun4os4.mt
new file mode 100644
index 00000000000..342d6f73537
--- /dev/null
+++ b/gdb/config/sparc/sun4os4.mt
@@ -0,0 +1,3 @@
+# Target: Sun 4 or Sparcstation, running SunOS 4
+TDEPFILES= sparc-tdep.o solib.o solib-sunos.o
+TM_FILE= tm-sun4os4.h
diff --git a/gdb/config/sparc/sun4sol2.mh b/gdb/config/sparc/sun4sol2.mh
new file mode 100644
index 00000000000..4e77b9234cd
--- /dev/null
+++ b/gdb/config/sparc/sun4sol2.mh
@@ -0,0 +1,22 @@
+# Host: Sun 4 or Sparcstation, running Solaris 2
+
+XM_FILE= xm-sun4sol2.h
+XM_CLIBS= -lsocket -lnsl
+
+NAT_FILE= nm-sun4sol2.h
+NATDEPFILES= corelow.o core-sol2.o solib.o solib-svr4.o solib-legacy.o \
+ fork-child.o procfs.o gcore.o \
+ proc-api.o proc-events.o proc-flags.o proc-why.o
+
+# /usr/include/v9 is needed only by core-sol2.c when including
+# v9/sys/privregs.h, or rather the headers it in turn includes.
+MH_CFLAGS=-I/usr/include/v9
+# If you are compiling with Sun's compiler, add the -xs option to CC
+# (e.g. `make CC="cc -xs"').
+# Sun's compilers require the -xs option to produce debug information
+# in the final linked executable. Otherwise they leave it in the .o
+# files only, with undocumented pointers to it in the linked executable.
+# This is commented out because we don't assume that the Sun compiler
+# is in use.
+#MH_CFLAGS=-xs -I/usr/include/v9
+HOST_IPC=-DBSD_IPC
diff --git a/gdb/config/sparc/sun4sol2.mt b/gdb/config/sparc/sun4sol2.mt
new file mode 100644
index 00000000000..af70e9f9f9f
--- /dev/null
+++ b/gdb/config/sparc/sun4sol2.mt
@@ -0,0 +1,3 @@
+# Target: Sun 4 or Sparcstation, running Solaris 2
+TDEPFILES= sparc-tdep.o
+TM_FILE= tm-sun4sol2.h
diff --git a/gdb/config/sparc/tm-fbsd.h b/gdb/config/sparc/tm-fbsd.h
new file mode 100644
index 00000000000..c84dfc4075b
--- /dev/null
+++ b/gdb/config/sparc/tm-fbsd.h
@@ -0,0 +1,34 @@
+/* Target-dependent definitions for FreeBSD/sparc64.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by David E. O'Brien <obrien@FreeBSD.org>.
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef TM_FBSD_H
+#define TM_FBSD_H
+
+#define SVR4_SHARED_LIBS
+#include "solib.h" /* Support for shared libraries. */
+#include "sparc/tm-sp64.h"
+
+/* Number of traps that happen between exec'ing the shell to run an
+ inferior, and when we finally get to the inferior code. The
+ default is right for FreeBSD. */
+
+#undef START_INFERIOR_TRAPS_EXPECTED
+
+#endif /* TM_FBSD_H */
diff --git a/gdb/config/sparc/tm-linux.h b/gdb/config/sparc/tm-linux.h
new file mode 100644
index 00000000000..34d901f5f9b
--- /dev/null
+++ b/gdb/config/sparc/tm-linux.h
@@ -0,0 +1,34 @@
+/* Macro definitions for GDB for a Sparc running GNU/Linux.
+
+ Copyright 1989, 1992, 1994, 1995, 1998, 1999, 2002 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. */
+
+#ifndef TM_SPARCLINUX_H
+#define TM_SPARCLINUX_H
+
+#define GDB_MULTI_ARCH GDB_MULTI_ARCH_PARTIAL
+
+#include "sparc/tm-sparc.h"
+
+#define SIGCONTEXT_PC_OFFSET 12
+
+#include "tm-linux.h"
+
+#endif /* TM_SPARCLINUX_H */
diff --git a/gdb/config/sparc/tm-nbsd.h b/gdb/config/sparc/tm-nbsd.h
new file mode 100644
index 00000000000..289e705f0a9
--- /dev/null
+++ b/gdb/config/sparc/tm-nbsd.h
@@ -0,0 +1,26 @@
+/* Macro definitions for Sparc running under NetBSD.
+ Copyright 1994 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. */
+
+#ifndef TM_NBSD_H
+#define TM_NBSD_H
+
+#include "sparc/tm-sparc.h"
+
+#endif /* TM_NBSD_H */
diff --git a/gdb/config/sparc/tm-nbsd64.h b/gdb/config/sparc/tm-nbsd64.h
new file mode 100644
index 00000000000..cc1d6b32297
--- /dev/null
+++ b/gdb/config/sparc/tm-nbsd64.h
@@ -0,0 +1,27 @@
+/* Macro definitions for UltraSPARC running under NetBSD.
+ Copyright 1994, 2002 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. */
+
+#ifndef TM_NBSD64_H
+#define TM_NBSD64_H
+
+#include "sparc/tm-sp64.h" /* sets GDB_MULTI_ARCH */
+#include "solib.h"
+
+#endif /* TM_NBSD64_H */
diff --git a/gdb/config/sparc/tm-nbsdaout.h b/gdb/config/sparc/tm-nbsdaout.h
new file mode 100644
index 00000000000..a62e53551ea
--- /dev/null
+++ b/gdb/config/sparc/tm-nbsdaout.h
@@ -0,0 +1,30 @@
+/* Macro definitions for Sparc running under NetBSD.
+ Copyright 1994, 2002 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. */
+
+#ifndef TM_NBSDAOUT_H
+#define TM_NBSDAOUT_H
+
+#include "sparc/tm-nbsd.h"
+
+/* Return non-zero if we are in a shared library trampoline code stub. */
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
+ (name && !strcmp(name, "_DYNAMIC"))
+
+#endif /* TM_NBSDAOUT_H */
diff --git a/gdb/config/sparc/tm-sp64.h b/gdb/config/sparc/tm-sp64.h
new file mode 100644
index 00000000000..8486c860831
--- /dev/null
+++ b/gdb/config/sparc/tm-sp64.h
@@ -0,0 +1,467 @@
+/* Target machine sub-parameters for SPARC64, for GDB, the GNU debugger.
+ This is included by other tm-*.h files to define SPARC64 cpu-related info.
+ Copyright 1994, 1995, 1996, 1998, 1999, 2000
+ Free Software Foundation, Inc.
+ This is (obviously) based on the SPARC Vn (n<9) port.
+ Contributed by Doug Evans (dje@cygnus.com).
+ Further modified by Bob Manson (manson@cygnus.com).
+
+ 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. */
+
+#define GDB_MULTI_ARCH GDB_MULTI_ARCH_PARTIAL
+
+#ifndef GDB_TARGET_IS_SPARC64
+#define GDB_TARGET_IS_SPARC64 1
+#endif
+
+#include "sparc/tm-sparc.h"
+
+/* Eeeew. Ok, we have to assume (for now) that the processor really is
+ in sparc64 mode. While this is the same instruction sequence as
+ on the Sparc, the stack frames are offset by +2047 (and the arguments
+ are 8 bytes instead of 4). */
+/* Instructions are:
+ std %f10, [ %fp + 0x7a7 ]
+ std %f8, [ %fp + 0x79f ]
+ std %f6, [ %fp + 0x797 ]
+ std %f4, [ %fp + 0x78f ]
+ std %f2, [ %fp + 0x787 ]
+ std %f0, [ %fp + 0x77f ]
+ std %g6, [ %fp + 0x777 ]
+ std %g4, [ %fp + 0x76f ]
+ std %g2, [ %fp + 0x767 ]
+ std %g0, [ %fp + 0x75f ]
+ std %fp, [ %fp + 0x757 ]
+ std %i4, [ %fp + 0x74f ]
+ std %i2, [ %fp + 0x747 ]
+ std %i0, [ %fp + 0x73f ]
+ nop
+ nop
+ nop
+ nop
+ rd %tbr, %o0
+ st %o0, [ %fp + 0x72b ]
+ rd %tpc, %o0
+ st %o0, [ %fp + 0x727 ]
+ rd %psr, %o0
+ st %o0, [ %fp + 0x723 ]
+ rd %y, %o0
+ st %o0, [ %fp + 0x71f ]
+ ldx [ %sp + 0x8a7 ], %o5
+ ldx [ %sp + 0x89f ], %o4
+ ldx [ %sp + 0x897 ], %o3
+ ldx [ %sp + 0x88f ], %o2
+ ldx [ %sp + 0x887 ], %o1
+ call %g0
+ ldx [ %sp + 0x87f ], %o0
+ nop
+ ta 1
+ nop
+ nop
+ */
+
+#if !defined (GDB_MULTI_ARCH) || (GDB_MULTI_ARCH == 0)
+/*
+ * The following defines must go away for MULTI_ARCH.
+ */
+
+#ifndef DO_CALL_DUMMY_ON_STACK
+
+/*
+ * These defines will suffice for the AT_ENTRY_POINT call dummy method.
+ */
+
+#undef CALL_DUMMY
+#define CALL_DUMMY {0}
+#undef CALL_DUMMY_LENGTH
+#define CALL_DUMMY_LENGTH 0
+#undef CALL_DUMMY_CALL_OFFSET
+#define CALL_DUMMY_CALL_OFFSET 0
+#undef CALL_DUMMY_START_OFFSET
+#define CALL_DUMMY_START_OFFSET 0
+#undef CALL_DUMMY_BREAKPOINT_OFFSET
+#define CALL_DUMMY_BREAKPOINT_OFFSET 0
+#undef CALL_DUMMY_BREAKPOINT_OFFSET_P
+#define CALL_DUMMY_BREAKPOINT_OFFSET_P 1
+#undef CALL_DUMMY_LOCATION
+#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
+#undef CALL_DUMMY_STACK_ADJUST
+#define CALL_DUMMY_STACK_ADJUST 128
+#undef SIZEOF_CALL_DUMMY_WORDS
+#define SIZEOF_CALL_DUMMY_WORDS 0
+#undef CALL_DUMMY_ADDRESS
+#define CALL_DUMMY_ADDRESS() entry_point_address()
+#undef FIX_CALL_DUMMY
+#define FIX_CALL_DUMMY(DUMMYNAME, PC, FUN, NARGS, ARGS, TYPE, GCC_P)
+#undef PUSH_RETURN_ADDRESS
+#define PUSH_RETURN_ADDRESS(PC, SP) sparc_at_entry_push_return_address (PC, SP)
+extern CORE_ADDR
+sparc_at_entry_push_return_address (CORE_ADDR pc, CORE_ADDR sp);
+
+#undef STORE_STRUCT_RETURN
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+ sparc_at_entry_store_struct_return (ADDR, SP)
+extern void
+sparc_at_entry_store_struct_return (CORE_ADDR addr, CORE_ADDR sp);
+
+
+#else
+/*
+ * Old call dummy method, with CALL_DUMMY on the stack.
+ */
+
+#undef CALL_DUMMY
+#define CALL_DUMMY { 0x9de3bec0fd3fa7f7LL, 0xf93fa7eff53fa7e7LL,\
+ 0xf13fa7dfed3fa7d7LL, 0xe93fa7cfe53fa7c7LL,\
+ 0xe13fa7bfdd3fa7b7LL, 0xd93fa7afd53fa7a7LL,\
+ 0xd13fa79fcd3fa797LL, 0xc93fa78fc53fa787LL,\
+ 0xc13fa77fcc3fa777LL, 0xc83fa76fc43fa767LL,\
+ 0xc03fa75ffc3fa757LL, 0xf83fa74ff43fa747LL,\
+ 0xf03fa73f01000000LL, 0x0100000001000000LL,\
+ 0x0100000091580000LL, 0xd027a72b93500000LL,\
+ 0xd027a72791480000LL, 0xd027a72391400000LL,\
+ 0xd027a71fda5ba8a7LL, 0xd85ba89fd65ba897LL,\
+ 0xd45ba88fd25ba887LL, 0x9fc02000d05ba87fLL,\
+ 0x0100000091d02001LL, 0x0100000001000000LL }
+
+
+/* 128 is to reserve space to write the %i/%l registers that will be restored
+ when we resume. */
+#undef CALL_DUMMY_STACK_ADJUST
+#define CALL_DUMMY_STACK_ADJUST 128
+
+/* Size of the call dummy in bytes. */
+#undef CALL_DUMMY_LENGTH
+#define CALL_DUMMY_LENGTH 192
+
+/* Offset within CALL_DUMMY of the 'call' instruction. */
+#undef CALL_DUMMY_START_OFFSET
+#define CALL_DUMMY_START_OFFSET 148
+
+/* Offset within CALL_DUMMY of the 'call' instruction. */
+#undef CALL_DUMMY_CALL_OFFSET
+#define CALL_DUMMY_CALL_OFFSET (CALL_DUMMY_START_OFFSET + (5 * 4))
+
+/* Offset within CALL_DUMMY of the 'ta 1' instruction. */
+#undef CALL_DUMMY_BREAKPOINT_OFFSET
+#define CALL_DUMMY_BREAKPOINT_OFFSET (CALL_DUMMY_START_OFFSET + (8 * 4))
+
+/* Let's GDB know that it can make a call_dummy breakpoint. */
+#undef CALL_DUMMY_BREAKPOINT_OFFSET_P
+#define CALL_DUMMY_BREAKPOINT_OFFSET_P 1
+
+/* Call dummy will be located on the stack. */
+#undef CALL_DUMMY_LOCATION
+#define CALL_DUMMY_LOCATION ON_STACK
+
+/* Insert the function address into the call dummy. */
+#undef FIX_CALL_DUMMY
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \
+ sparc_fix_call_dummy (dummyname, pc, fun, type, gcc_p)
+void sparc_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun,
+ struct type *value_type, int using_gcc);
+
+
+/* The remainder of these will accept the default definition. */
+#undef SIZEOF_CALL_DUMMY_WORDS
+#undef PUSH_RETURN_ADDRESS
+#undef CALL_DUMMY_ADDRESS
+#undef STORE_STRUCT_RETURN
+
+#endif
+
+/* Does the specified function use the "struct returning" convention
+ or the "value returning" convention? The "value returning" convention
+ almost invariably returns the entire value in registers. The
+ "struct returning" convention often returns the entire value in
+ memory, and passes a pointer (out of or into the function) saying
+ where the value (is or should go).
+
+ Since this sometimes depends on whether it was compiled with GCC,
+ this is also an argument. This is used in call_function to build a
+ stack, and in value_being_returned to print return values.
+
+ On Sparc64, we only pass pointers to structs if they're larger than
+ 32 bytes. Otherwise they're stored in %o0-%o3 (floating-point
+ values go into %fp0-%fp3). */
+
+#undef USE_STRUCT_CONVENTION
+#define USE_STRUCT_CONVENTION(gcc_p, type) (TYPE_LENGTH (type) > 32)
+
+CORE_ADDR sparc64_push_arguments (int,
+ struct value **, CORE_ADDR, int, CORE_ADDR);
+#undef PUSH_ARGUMENTS
+#define PUSH_ARGUMENTS(A,B,C,D,E) \
+ (sparc64_push_arguments ((A), (B), (C), (D), (E)))
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function. */
+/* FIXME: V9 uses %o0 for this. */
+
+#undef STORE_STRUCT_RETURN
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+ { target_write_memory ((SP)+(16*8), (char *)&(ADDR), 8); }
+
+/* Stack must be aligned on 128-bit boundaries when synthesizing
+ function calls. */
+
+#undef STACK_ALIGN
+#define STACK_ALIGN(ADDR) (((ADDR) + 15 ) & -16)
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer. */
+/* Some of these registers are only accessible from priviledged mode.
+ They are here for kernel debuggers, etc. */
+/* FIXME: icc and xcc are currently considered separate registers.
+ This may have to change and consider them as just one (ccr).
+ Let's postpone this as long as we can. It's nice to be able to set
+ them individually. */
+/* FIXME: fcc0-3 are currently separate, even though they are also part of
+ fsr. May have to remove them but let's postpone this as long as
+ possible. It's nice to be able to set them individually. */
+/* FIXME: Whether to include f33, f35, etc. here is not clear.
+ There are advantages and disadvantages. */
+
+#undef REGISTER_NAMES
+#define REGISTER_NAMES \
+{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \
+ "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", \
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", \
+ "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", \
+ \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
+ "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \
+ "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", \
+ \
+ "pc", "npc", "ccr", "fsr", "fprs", "y", "asi", \
+ "ver", "tick", "pil", "pstate", \
+ "tstate", "tba", "tl", "tt", "tpc", "tnpc", "wstate", \
+ "cwp", "cansave", "canrestore", "cleanwin", "otherwin", \
+ "asr16", "asr17", "asr18", "asr19", "asr20", "asr21", \
+ "asr22", "asr23", "asr24", "asr25", "asr26", "asr27", \
+ "asr28", "asr29", "asr30", "asr31", \
+ /* These are here at the end to simplify removing them if we have to. */ \
+ "icc", "xcc", "fcc0", "fcc1", "fcc2", "fcc3" \
+}
+
+#undef REG_STRUCT_HAS_ADDR
+#define REG_STRUCT_HAS_ADDR(gcc_p,type) (TYPE_LENGTH (type) > 32)
+
+extern CORE_ADDR sparc64_read_sp ();
+extern CORE_ADDR sparc64_read_fp ();
+extern void sparc64_write_sp (CORE_ADDR);
+
+#define TARGET_READ_SP() (sparc64_read_sp ())
+#define TARGET_READ_FP() (sparc64_read_fp ())
+#define TARGET_WRITE_SP(X) (sparc64_write_sp (X))
+
+#undef EXTRACT_RETURN_VALUE
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ sp64_extract_return_value(TYPE, REGBUF, VALBUF, 0)
+extern void sp64_extract_return_value (struct type *, char[], char *, int);
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#if 0 /* defined in tm-sparc.h, replicated
+ for doc purposes */
+#define G0_REGNUM 0 /* %g0 */
+#define G1_REGNUM 1 /* %g1 */
+#define O0_REGNUM 8 /* %o0 */
+#define SP_REGNUM 14 /* Contains address of top of stack, \
+ which is also the bottom of the frame. */
+#define RP_REGNUM 15 /* Contains return address value, *before* \
+ any windows get switched. */
+#define O7_REGNUM 15 /* Last local reg not saved on stack frame */
+#define L0_REGNUM 16 /* First local reg that's saved on stack frame
+ rather than in machine registers */
+#define I0_REGNUM 24 /* %i0 */
+#define FP_REGNUM 30 /* Contains address of executing stack frame */
+#define I7_REGNUM 31 /* Last local reg saved on stack frame */
+#define FP0_REGNUM 32 /* Floating point register 0 */
+#endif
+
+/*#define FP_MAX_REGNUM 80*/ /* 1 + last fp reg number */
+
+/* #undef v8 misc. regs */
+
+#undef Y_REGNUM
+#undef PS_REGNUM
+#undef WIM_REGNUM
+#undef TBR_REGNUM
+#undef PC_REGNUM
+#undef NPC_REGNUM
+#undef FPS_REGNUM
+#undef CPS_REGNUM
+
+/* v9 misc. and priv. regs */
+
+#define C0_REGNUM 80 /* Start of control registers */
+
+#define PC_REGNUM (C0_REGNUM + 0) /* Current PC */
+#define NPC_REGNUM (C0_REGNUM + 1) /* Next PC */
+#define CCR_REGNUM (C0_REGNUM + 2) /* Condition Code Register (%xcc,%icc) */
+#define FSR_REGNUM (C0_REGNUM + 3) /* Floating Point State */
+#define FPRS_REGNUM (C0_REGNUM + 4) /* Floating Point Registers State */
+#define Y_REGNUM (C0_REGNUM + 5) /* Temp register for multiplication, etc. */
+#define ASI_REGNUM (C0_REGNUM + 6) /* Alternate Space Identifier */
+#define VER_REGNUM (C0_REGNUM + 7) /* Version register */
+#define TICK_REGNUM (C0_REGNUM + 8) /* Tick register */
+#define PIL_REGNUM (C0_REGNUM + 9) /* Processor Interrupt Level */
+#define PSTATE_REGNUM (C0_REGNUM + 10) /* Processor State */
+#define TSTATE_REGNUM (C0_REGNUM + 11) /* Trap State */
+#define TBA_REGNUM (C0_REGNUM + 12) /* Trap Base Address */
+#define TL_REGNUM (C0_REGNUM + 13) /* Trap Level */
+#define TT_REGNUM (C0_REGNUM + 14) /* Trap Type */
+#define TPC_REGNUM (C0_REGNUM + 15) /* Trap pc */
+#define TNPC_REGNUM (C0_REGNUM + 16) /* Trap npc */
+#define WSTATE_REGNUM (C0_REGNUM + 17) /* Window State */
+#define CWP_REGNUM (C0_REGNUM + 18) /* Current Window Pointer */
+#define CANSAVE_REGNUM (C0_REGNUM + 19) /* Savable Windows */
+#define CANRESTORE_REGNUM (C0_REGNUM + 20) /* Restorable Windows */
+#define CLEANWIN_REGNUM (C0_REGNUM + 21) /* Clean Windows */
+#define OTHERWIN_REGNUM (C0_REGNUM + 22) /* Other Windows */
+#define ASR_REGNUM(n) (C0_REGNUM+(23-16)+(n)) /* Ancillary State Register
+ (n = 16...31) */
+#define ICC_REGNUM (C0_REGNUM + 39) /* 32 bit condition codes */
+#define XCC_REGNUM (C0_REGNUM + 40) /* 64 bit condition codes */
+#define FCC0_REGNUM (C0_REGNUM + 41) /* fp cc reg 0 */
+#define FCC1_REGNUM (C0_REGNUM + 42) /* fp cc reg 1 */
+#define FCC2_REGNUM (C0_REGNUM + 43) /* fp cc reg 2 */
+#define FCC3_REGNUM (C0_REGNUM + 44) /* fp cc reg 3 */
+
+/* Number of machine registers. */
+
+#undef NUM_REGS
+#define NUM_REGS 125
+
+/* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'.
+ Some of the registers aren't 64 bits, but it's a lot simpler just to assume
+ they all are (since most of them are). */
+#undef REGISTER_BYTES
+#define REGISTER_BYTES (32*8+32*8+45*8)
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+#undef REGISTER_BYTE
+#define REGISTER_BYTE(N) \
+ ((N) < 32 ? (N)*8 \
+ : (N) < 64 ? 32*8 + ((N)-32)*4 \
+ : (N) < C0_REGNUM ? 32*8 + 32*4 + ((N)-64)*8 \
+ : 64*8 + ((N)-C0_REGNUM)*8)
+
+/* Say how long (ordinary) registers are. This is a piece of bogosity
+ used in push_word and a few other places; REGISTER_RAW_SIZE is the
+ real way to know how big a register is. */
+
+#undef REGISTER_SIZE
+#define REGISTER_SIZE 8
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. */
+
+#undef REGISTER_RAW_SIZE
+#define REGISTER_RAW_SIZE(N) \
+ ((N) < 32 ? 8 : (N) < 64 ? 4 : 8)
+
+/* Number of bytes of storage in the program's representation
+ for register N. */
+
+#undef REGISTER_VIRTUAL_SIZE
+#define REGISTER_VIRTUAL_SIZE(N) \
+ ((N) < 32 ? 8 : (N) < 64 ? 4 : 8)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+/* tm-sparc.h defines this as 8, but play it safe. */
+
+#undef MAX_REGISTER_RAW_SIZE
+#define MAX_REGISTER_RAW_SIZE 8
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+/* tm-sparc.h defines this as 8, but play it safe. */
+
+#undef MAX_REGISTER_VIRTUAL_SIZE
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+#undef REGISTER_VIRTUAL_TYPE
+#define REGISTER_VIRTUAL_TYPE(N) \
+ ((N) < 32 ? builtin_type_long_long \
+ : (N) < 64 ? builtin_type_float \
+ : (N) < 80 ? builtin_type_double \
+ : builtin_type_long_long)
+
+/* We use to support both 32 bit and 64 bit pointers.
+ We can't anymore because TARGET_PTR_BIT must now be a constant. */
+#undef TARGET_PTR_BIT
+#define TARGET_PTR_BIT 64
+
+/* Longs are 64 bits. */
+#undef TARGET_LONG_BIT
+#define TARGET_LONG_BIT 64
+
+#undef TARGET_LONG_LONG_BIT
+#define TARGET_LONG_LONG_BIT 64
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#undef FRAME_ARGS_SKIP
+#define FRAME_ARGS_SKIP 136
+
+#endif /* GDB_MULTI_ARCH */
+
+/* Offsets into jmp_buf.
+ FIXME: This was borrowed from the v8 stuff and will probably have to change
+ for v9. */
+
+#define JB_ELEMENT_SIZE 8 /* Size of each element in jmp_buf */
+
+#define JB_ONSSTACK 0
+#define JB_SIGMASK 1
+#define JB_SP 2
+#define JB_PC 3
+#define JB_NPC 4
+#define JB_PSR 5
+#define JB_G1 6
+#define JB_O0 7
+#define JB_WBCNT 8
+
+/* Figure out where the longjmp will land. We expect that we have
+ just entered longjmp and haven't yet setup the stack frame, so the
+ args are still in the output regs. %o0 (O0_REGNUM) points at the
+ jmp_buf structure from which we extract the pc (JB_PC) that we will
+ land at. The pc is copied into ADDR. This routine returns true on
+ success */
+
+extern int get_longjmp_target (CORE_ADDR *);
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+
+#undef TM_PRINT_INSN_MACH
+#define TM_PRINT_INSN_MACH bfd_mach_sparc_v9a
+
diff --git a/gdb/config/sparc/tm-sp64linux.h b/gdb/config/sparc/tm-sp64linux.h
new file mode 100644
index 00000000000..56b56208652
--- /dev/null
+++ b/gdb/config/sparc/tm-sp64linux.h
@@ -0,0 +1,36 @@
+/* Macro definitions for GDB for a UltraSparc running GNU/Linux.
+
+ Copyright 2001, 2002 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. */
+
+#ifndef TM_SPARC_LIN64_H
+#define TM_SPARC_LIN64_H
+
+#include "sparc/tm-sp64.h"
+
+#define SIGCONTEXT_PC_OFFSET 16 /* See asm-sparc64/sigcontext.h */
+
+/* We always want full V9 + Ultra VIS stuff... */
+#undef TM_PRINT_INSN_MACH
+#define TM_PRINT_INSN_MACH bfd_mach_sparc_v9a
+
+#define GDB_PTRACE_REGS64
+
+#include "tm-sysv4.h"
+
+#endif TM_SPARC_LIN64_H
diff --git a/gdb/config/sparc/tm-sp64sim.h b/gdb/config/sparc/tm-sp64sim.h
new file mode 100644
index 00000000000..c8d115cd635
--- /dev/null
+++ b/gdb/config/sparc/tm-sp64sim.h
@@ -0,0 +1,50 @@
+/* Macro definitions for GDB with the SPARC64 Simulator.
+ Copyright 1993, 2000 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. */
+
+/* ??? This file is based on tm-spc-em.h. Our contents are probably bogus
+ but it's a good start. */
+
+#include "sparc/tm-sp64.h"
+#include "tm-sunos.h"
+
+/* Offsets into jmp_buf. Not defined by Sun, but at least documented in a
+ comment in <machine/setjmp.h>! */
+
+#define JB_ELEMENT_SIZE 8 /* Size of each element in jmp_buf */
+
+#define JB_ONSSTACK 0
+#define JB_SIGMASK 1
+#define JB_SP 2
+#define JB_PC 3
+#define JB_NPC 4
+#define JB_PSR 5
+#define JB_G1 6
+#define JB_O0 7
+#define JB_WBCNT 8
+
+/* Figure out where the longjmp will land. We expect that we have just entered
+ longjmp and haven't yet setup the stack frame, so the args are still in the
+ output regs. %o0 (O0_REGNUM) points at the jmp_buf structure from which we
+ extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+extern int get_longjmp_target (CORE_ADDR *);
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
diff --git a/gdb/config/sparc/tm-sparc.h b/gdb/config/sparc/tm-sparc.h
new file mode 100644
index 00000000000..4a5358036be
--- /dev/null
+++ b/gdb/config/sparc/tm-sparc.h
@@ -0,0 +1,766 @@
+/* Target machine sub-parameters for SPARC, for GDB, the GNU debugger.
+ This is included by other tm-*.h files to define SPARC cpu-related info.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000
+ Free Software Foundation, Inc.
+ Contributed by Michael Tiemann (tiemann@mcc.com)
+
+ 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 "regcache.h"
+
+struct type;
+struct value;
+struct frame_info;
+
+/*
+ * The following enums are purely for the convenience of the GDB
+ * developer, when debugging GDB.
+ */
+
+enum { /* Sparc general registers, for all sparc versions. */
+ G0_REGNUM, G1_REGNUM, G2_REGNUM, G3_REGNUM,
+ G4_REGNUM, G5_REGNUM, G6_REGNUM, G7_REGNUM,
+ O0_REGNUM, O1_REGNUM, O2_REGNUM, O3_REGNUM,
+ O4_REGNUM, O5_REGNUM, O6_REGNUM, O7_REGNUM,
+ L0_REGNUM, L1_REGNUM, L2_REGNUM, L3_REGNUM,
+ L4_REGNUM, L5_REGNUM, L6_REGNUM, L7_REGNUM,
+ I0_REGNUM, I1_REGNUM, I2_REGNUM, I3_REGNUM,
+ I4_REGNUM, I5_REGNUM, I6_REGNUM, I7_REGNUM,
+ FP0_REGNUM /* Floating point register 0 */
+};
+
+enum { /* Sparc general registers, alternate names. */
+ R0_REGNUM, R1_REGNUM, R2_REGNUM, R3_REGNUM,
+ R4_REGNUM, R5_REGNUM, R6_REGNUM, R7_REGNUM,
+ R8_REGNUM, R9_REGNUM, R10_REGNUM, R11_REGNUM,
+ R12_REGNUM, R13_REGNUM, R14_REGNUM, R15_REGNUM,
+ R16_REGNUM, R17_REGNUM, R18_REGNUM, R19_REGNUM,
+ R20_REGNUM, R21_REGNUM, R22_REGNUM, R23_REGNUM,
+ R24_REGNUM, R25_REGNUM, R26_REGNUM, R27_REGNUM,
+ R28_REGNUM, R29_REGNUM, R30_REGNUM, R31_REGNUM
+};
+
+enum { /* Sparc32 control registers. */
+ PS_REGNUM = 65, /* PC, NPC, and Y are omitted because */
+ WIM_REGNUM = 66, /* they have different values depending on */
+ TBR_REGNUM = 67, /* 32-bit / 64-bit mode. */
+ FPS_REGNUM = 70,
+ CPS_REGNUM = 71
+};
+
+/* v9 misc. and priv. regs */
+
+/* Note: specifying values explicitly for documentation purposes. */
+enum { /* Sparc64 control registers, excluding Y, PC, and NPC. */
+ CCR_REGNUM = 82, /* Condition Code Register (%xcc,%icc) */
+ FSR_REGNUM = 83, /* Floating Point State */
+ FPRS_REGNUM = 84, /* Floating Point Registers State */
+ ASI_REGNUM = 86, /* Alternate Space Identifier */
+ VER_REGNUM = 87, /* Version register */
+ TICK_REGNUM = 88, /* Tick register */
+ PIL_REGNUM = 89, /* Processor Interrupt Level */
+ PSTATE_REGNUM = 90, /* Processor State */
+ TSTATE_REGNUM = 91, /* Trap State */
+ TBA_REGNUM = 92, /* Trap Base Address */
+ TL_REGNUM = 93, /* Trap Level */
+ TT_REGNUM = 94, /* Trap Type */
+ TPC_REGNUM = 95, /* Trap pc */
+ TNPC_REGNUM = 96, /* Trap npc */
+ WSTATE_REGNUM = 97, /* Window State */
+ CWP_REGNUM = 98, /* Current Window Pointer */
+ CANSAVE_REGNUM = 99, /* Savable Windows */
+ CANRESTORE_REGNUM = 100, /* Restorable Windows */
+ CLEANWIN_REGNUM = 101, /* Clean Windows */
+ OTHERWIN_REGNUM = 102, /* Other Windows */
+ ASR16_REGNUM = 103, /* Ancillary State Registers */
+ ASR17_REGNUM = 104,
+ ASR18_REGNUM = 105,
+ ASR19_REGNUM = 106,
+ ASR20_REGNUM = 107,
+ ASR21_REGNUM = 108,
+ ASR22_REGNUM = 109,
+ ASR23_REGNUM = 110,
+ ASR24_REGNUM = 111,
+ ASR25_REGNUM = 112,
+ ASR26_REGNUM = 113,
+ ASR27_REGNUM = 114,
+ ASR28_REGNUM = 115,
+ ASR29_REGNUM = 116,
+ ASR30_REGNUM = 117,
+ ASR31_REGNUM = 118,
+ ICC_REGNUM = 119, /* 32 bit condition codes */
+ XCC_REGNUM = 120, /* 64 bit condition codes */
+ FCC0_REGNUM = 121, /* fp cc reg 0 */
+ FCC1_REGNUM = 122, /* fp cc reg 1 */
+ FCC2_REGNUM = 123, /* fp cc reg 2 */
+ FCC3_REGNUM = 124 /* fp cc reg 3 */
+};
+
+/*
+ * Make sparc target multi-archable: April 2000
+ */
+
+#if defined (GDB_MULTI_ARCH) && (GDB_MULTI_ARCH > 0)
+
+/* Multi-arch definition of TARGET_IS_SPARC64, TARGET_ELF64 */
+#undef GDB_TARGET_IS_SPARC64
+#define GDB_TARGET_IS_SPARC64 \
+ (sparc_intreg_size () == 8)
+#undef TARGET_ELF64
+#define TARGET_ELF64 \
+ (sparc_intreg_size () == 8)
+extern int sparc_intreg_size (void);
+#else
+
+/* Non-multi-arch: if it isn't defined, define it to zero. */
+#ifndef GDB_TARGET_IS_SPARC64
+#define GDB_TARGET_IS_SPARC64 0
+#endif
+#ifndef TARGET_ELF64
+#define TARGET_ELF64 0
+#endif
+#endif
+
+#if !defined (GDB_MULTI_ARCH) || (GDB_MULTI_ARCH == 0)
+/*
+ * The following defines must go away for MULTI_ARCH
+ */
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer. */
+
+#define REGISTER_NAMES \
+{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \
+ "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", \
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", \
+ "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", \
+ \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
+ \
+ "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" \
+}
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Amount PC must be decremented by after a breakpoint.
+ This is often the number of bytes in BREAKPOINT
+ but not always. */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Say how long (ordinary) registers are. This is a piece of bogosity
+ used in push_word and a few other places; REGISTER_RAW_SIZE is the
+ real way to know how big a register is. */
+
+#define REGISTER_SIZE 4
+
+/* Number of machine registers */
+
+#define NUM_REGS 72
+
+#define SP_REGNUM 14 /* Contains address of top of stack, \
+ which is also the bottom of the frame. */
+#define FP_REGNUM 30 /* Contains address of executing stack frame */
+
+#define FP0_REGNUM 32 /* Floating point register 0 */
+
+#define Y_REGNUM 64 /* Temp register for multiplication, etc. */
+
+#define PC_REGNUM 68 /* Contains program counter */
+
+#define NPC_REGNUM 69 /* Contains next PC */
+
+
+/* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'. On the sparc, `registers'
+ contains the ins and locals, even though they are saved on the
+ stack rather than with the other registers, and this causes hair
+ and confusion in places like pop_frame. It might be better to
+ remove the ins and locals from `registers', make sure that
+ get_saved_register can get them from the stack (even in the
+ innermost frame), and make this the way to access them. For the
+ frame pointer we would do that via TARGET_READ_FP. On the other
+ hand, that is likely to be confusing or worse for flat frames. */
+
+#define REGISTER_BYTES (32*4+32*4+8*4)
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#define REGISTER_BYTE(N) ((N)*4)
+
+/* Number of bytes of storage in the actual machine representation for
+ register N. */
+
+/* On the SPARC, all regs are 4 bytes (except Sparc64, where they're 8). */
+
+#define REGISTER_RAW_SIZE(N) (4)
+
+/* Number of bytes of storage in the program's representation
+ for register N. */
+
+/* On the SPARC, all regs are 4 bytes (except Sparc64, where they're 8). */
+
+#define REGISTER_VIRTUAL_SIZE(N) (4)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#define MAX_REGISTER_RAW_SIZE 8
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+ ((N) < 32 ? builtin_type_int : (N) < 64 ? builtin_type_float : \
+ builtin_type_int)
+
+/* Sun /bin/cc gets this right as of SunOS 4.1.x. We need to define
+ BELIEVE_PCC_PROMOTION to get this right now that the code which
+ detects gcc2_compiled. is broken. This loses for SunOS 4.0.x and
+ earlier. */
+
+#define BELIEVE_PCC_PROMOTION 1
+
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code. */
+
+extern CORE_ADDR sparc_skip_prologue (CORE_ADDR);
+#define SKIP_PROLOGUE(PC) sparc_skip_prologue (PC)
+
+/* Immediately after a function call, return the saved pc.
+ Can't go through the frames for this because on some machines
+ the new frame is not set up until the new function executes
+ some instructions. */
+
+#define SAVED_PC_AFTER_CALL(FRAME) PC_ADJUST (read_register (RP_REGNUM))
+
+/* Stack grows downward. */
+
+#define INNER_THAN(LHS,RHS) ((LHS) < (RHS))
+
+/* Write into appropriate registers a function return value of type
+ TYPE, given in virtual format. */
+
+#define STORE_RETURN_VALUE(TYPE, VALBUF) \
+ sparc_store_return_value (TYPE, VALBUF)
+extern void sparc_store_return_value (struct type *, char *);
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+ sparc_extract_struct_value_address (REGBUF)
+
+extern CORE_ADDR sparc_extract_struct_value_address (char *);
+
+/* If the current gcc for for this target does not produce correct
+ debugging information for float parameters, both prototyped and
+ unprototyped, then define this macro. This forces gdb to always
+ assume that floats are passed as doubles and then converted in the
+ callee. */
+
+#define COERCE_FLOAT_TO_DOUBLE(FORMAL, ACTUAL) (1)
+
+/* Stack must be aligned on 64-bit boundaries when synthesizing
+ function calls (128-bit for sparc64). */
+
+#define STACK_ALIGN(ADDR) sparc32_stack_align (ADDR)
+extern CORE_ADDR sparc32_stack_align (CORE_ADDR addr);
+
+/* The Sparc returns long doubles on the stack. */
+
+#define RETURN_VALUE_ON_STACK(TYPE) \
+ (TYPE_CODE(TYPE) == TYPE_CODE_FLT \
+ && TYPE_LENGTH(TYPE) > 8)
+
+/* When passing a structure to a function, Sun cc passes the address
+ not the structure itself. It (under SunOS4) creates two symbols,
+ which we need to combine to a LOC_REGPARM. Gcc version two (as of
+ 1.92) behaves like sun cc. REG_STRUCT_HAS_ADDR is smart enough to
+ distinguish between Sun cc, gcc version 1 and gcc version 2. */
+
+#define REG_STRUCT_HAS_ADDR(GCC_P, TYPE) \
+ sparc_reg_struct_has_addr (GCC_P, TYPE)
+extern int sparc_reg_struct_has_addr (int, struct type *);
+
+/* Is the prologue at PC frameless? */
+#define PROLOGUE_FRAMELESS_P(PC) sparc_prologue_frameless_p (PC)
+extern int sparc_prologue_frameless_p (CORE_ADDR);
+
+#endif /* GDB_MULTI_ARCH */
+
+#if defined (GDB_MULTI_ARCH) && (GDB_MULTI_ARCH > 0)
+/*
+ * The following defines should ONLY appear for MULTI_ARCH.
+ */
+
+/* Multi-arch the nPC and Y registers. */
+#define Y_REGNUM (sparc_y_regnum ())
+extern int sparc_npc_regnum (void);
+extern int sparc_y_regnum (void);
+
+#endif /* GDB_MULTI_ARCH */
+
+/* On the Sun 4 under SunOS, the compile will leave a fake insn which
+ encodes the structure size being returned. If we detect such
+ a fake insn, step past it. */
+
+#define PC_ADJUST(PC) sparc_pc_adjust (PC)
+extern CORE_ADDR sparc_pc_adjust (CORE_ADDR);
+
+/* If an argument is declared "register", Sun cc will keep it in a register,
+ never saving it onto the stack. So we better not believe the "p" symbol
+ descriptor stab. */
+
+#define USE_REGISTER_NOT_ARG
+
+/* For acc, there's no need to correct LBRAC entries by guessing how
+ they should work. In fact, this is harmful because the LBRAC
+ entries now all appear at the end of the function, not intermixed
+ with the SLINE entries. n_opt_found detects acc for Solaris binaries;
+ function_stab_type detects acc for SunOS4 binaries.
+
+ For binary from SunOS4 /bin/cc, need to correct LBRAC's.
+
+ For gcc, like acc, don't correct. */
+
+#define SUN_FIXED_LBRAC_BUG \
+ (n_opt_found \
+ || function_stab_type == N_STSYM \
+ || function_stab_type == N_GSYM \
+ || processing_gcc_compilation)
+
+/* Do variables in the debug stabs occur after the N_LBRAC or before it?
+ acc: after, gcc: before, SunOS4 /bin/cc: before. */
+
+#define VARIABLES_INSIDE_BLOCK(desc, gcc_p) \
+ (!(gcc_p) \
+ && (n_opt_found \
+ || function_stab_type == N_STSYM \
+ || function_stab_type == N_GSYM))
+
+/* Sequence of bytes for breakpoint instruction (ta 1). */
+
+#define BREAKPOINT {0x91, 0xd0, 0x20, 0x01}
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define G0_REGNUM 0 /* %g0 */
+#define G1_REGNUM 1 /* %g1 */
+#define O0_REGNUM 8 /* %o0 */
+#define RP_REGNUM 15 /* Contains return address value, *before* \
+ any windows get switched. */
+#define O7_REGNUM 15 /* Last local reg not saved on stack frame */
+#define L0_REGNUM 16 /* First local reg that's saved on stack frame
+ rather than in machine registers */
+#define I0_REGNUM 24 /* %i0 */
+#define I7_REGNUM 31 /* Last local reg saved on stack frame */
+#define PS_REGNUM 65 /* Contains processor status */
+#define PS_FLAG_CARRY 0x100000 /* Carry bit in PS */
+#define WIM_REGNUM 66 /* Window Invalid Mask (not really supported) */
+#define TBR_REGNUM 67 /* Trap Base Register (not really supported) */
+#define FPS_REGNUM 70 /* Floating point status register */
+#define CPS_REGNUM 71 /* Coprocessor status register */
+
+/* Writing to %g0 is a noop (not an error or exception or anything like
+ that, however). */
+
+#define CANNOT_STORE_REGISTER(regno) ((regno) == G0_REGNUM)
+
+/*
+ * FRAME_CHAIN and FRAME_INFO definitions, collected here for convenience.
+ */
+
+#if !defined (GDB_MULTI_ARCH) || (GDB_MULTI_ARCH == 0)
+/*
+ * The following defines must go away for MULTI_ARCH.
+ */
+
+/* Describe the pointer in each stack frame to the previous stack frame
+ (its caller). */
+
+/* FRAME_CHAIN takes a frame's nominal address
+ and produces the frame's chain-pointer. */
+
+/* In the case of the Sun 4, the frame-chain's nominal address
+ is held in the frame pointer register.
+
+ On the Sun4, the frame (in %fp) is %sp for the previous frame.
+ From the previous frame's %sp, we can find the previous frame's
+ %fp: it is in the save area just above the previous frame's %sp.
+
+ If we are setting up an arbitrary frame, we'll need to know where
+ it ends. Hence the following. This part of the frame cache
+ structure should be checked before it is assumed that this frame's
+ bottom is in the stack pointer.
+
+ If there isn't a frame below this one, the bottom of this frame is
+ in the stack pointer.
+
+ If there is a frame below this one, and the frame pointers are
+ identical, it's a leaf frame and the bottoms are the same also.
+
+ Otherwise the bottom of this frame is the top of the next frame.
+
+ The bottom field is misnamed, since it might imply that memory from
+ bottom to frame contains this frame. That need not be true if
+ stack frames are allocated in different segments (e.g. some on a
+ stack, some on a heap in the data segment).
+
+ GCC 2.6 and later can generate ``flat register window'' code that
+ makes frames by explicitly saving those registers that need to be
+ saved. %i7 is used as the frame pointer, and the frame is laid out
+ so that flat and non-flat calls can be intermixed freely within a
+ program. Unfortunately for GDB, this means it must detect and
+ record the flatness of frames.
+
+ Since the prologue in a flat frame also tells us where fp and pc
+ have been stashed (the frame is of variable size, so their location
+ is not fixed), it's convenient to record them in the frame info. */
+
+#define EXTRA_FRAME_INFO \
+ CORE_ADDR bottom; \
+ int in_prologue; \
+ int flat; \
+ /* Following fields only relevant for flat frames. */ \
+ CORE_ADDR pc_addr; \
+ CORE_ADDR fp_addr; \
+ /* Add this to ->frame to get the value of the stack pointer at the */ \
+ /* time of the register saves. */ \
+ int sp_offset;
+
+/* We need to override GET_SAVED_REGISTER so that we can deal with the
+ way outs change into ins in different frames. */
+
+void sparc_get_saved_register (char *raw_buffer,
+ int *optimized,
+ CORE_ADDR * addrp,
+ struct frame_info *frame,
+ int regnum, enum lval_type *lvalp);
+
+#define GET_SAVED_REGISTER(RAW_BUFFER, OPTIMIZED, ADDRP, FRAME, REGNUM, LVAL) \
+ sparc_get_saved_register (RAW_BUFFER, OPTIMIZED, ADDRP, \
+ FRAME, REGNUM, LVAL)
+
+#define FRAME_INIT_SAVED_REGS(FP) /*no-op */
+
+#define INIT_EXTRA_FRAME_INFO(FROMLEAF, FCI) \
+ sparc_init_extra_frame_info (FROMLEAF, FCI)
+extern void sparc_init_extra_frame_info (int, struct frame_info *);
+
+#define FRAME_CHAIN(THISFRAME) (sparc_frame_chain (THISFRAME))
+extern CORE_ADDR sparc_frame_chain (struct frame_info *);
+
+/* A macro that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. If it
+ does not, FRAMELESS is set to 1, else 0. */
+
+#define FRAMELESS_FUNCTION_INVOCATION(FI) \
+ frameless_look_for_prologue (FI)
+
+/* Where is the PC for a specific frame */
+
+#define FRAME_SAVED_PC(FRAME) sparc_frame_saved_pc (FRAME)
+extern CORE_ADDR sparc_frame_saved_pc (struct frame_info *);
+
+/* If the argument is on the stack, it will be here. */
+#define FRAME_ARGS_ADDRESS(FI) ((FI)->frame)
+
+#define FRAME_LOCALS_ADDRESS(FI) ((FI)->frame)
+
+/* Set VAL to the number of args passed to frame described by FI.
+ Can set VAL to -1, meaning no way to tell. */
+
+/* We can't tell how many args there are
+ now that the C compiler delays popping them. */
+#define FRAME_NUM_ARGS(FI) (-1)
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#define FRAME_ARGS_SKIP 68
+
+#endif /* GDB_MULTI_ARCH */
+
+#define PRINT_EXTRA_FRAME_INFO(FI) \
+ sparc_print_extra_frame_info (FI)
+extern void sparc_print_extra_frame_info (struct frame_info *);
+
+/* INIT_EXTRA_FRAME_INFO needs the PC to detect flat frames. */
+
+#define INIT_FRAME_PC(FROMLEAF, PREV) /* nothing */
+#define INIT_FRAME_PC_FIRST(FROMLEAF, PREV) \
+ (PREV)->pc = ((FROMLEAF) ? SAVED_PC_AFTER_CALL ((PREV)->next) : \
+ (PREV)->next ? FRAME_SAVED_PC ((PREV)->next) : read_pc ());
+
+/* Define other aspects of the stack frame. */
+
+/* The location of I0 w.r.t SP. This is actually dependent on how the
+ system's window overflow/underflow routines are written. Most
+ vendors save the L regs followed by the I regs (at the higher
+ address). Some vendors get it wrong. */
+
+#define FRAME_SAVED_L0 0
+#define FRAME_SAVED_I0 (8 * REGISTER_RAW_SIZE (L0_REGNUM))
+
+#define FRAME_STRUCT_ARGS_ADDRESS(FI) ((FI)->frame)
+
+/* Things needed for making the inferior call functions. */
+/*
+ * First of all, let me give my opinion of what the DUMMY_FRAME
+ * actually looks like.
+ *
+ * | |
+ * | |
+ * + - - - - - - - - - - - - - - - - +<-- fp (level 0)
+ * | |
+ * | |
+ * | |
+ * | |
+ * | Frame of innermost program |
+ * | function |
+ * | |
+ * | |
+ * | |
+ * | |
+ * | |
+ * |---------------------------------|<-- sp (level 0), fp (c)
+ * | |
+ * DUMMY | fp0-31 |
+ * | |
+ * | ------ |<-- fp - 0x80
+ * FRAME | g0-7 |<-- fp - 0xa0
+ * | i0-7 |<-- fp - 0xc0
+ * | other |<-- fp - 0xe0
+ * | ? |
+ * | ? |
+ * |---------------------------------|<-- sp' = fp - 0x140
+ * | |
+ * xcution start | |
+ * sp' + 0x94 -->| CALL_DUMMY (x code) |
+ * | |
+ * | |
+ * |---------------------------------|<-- sp'' = fp - 0x200
+ * | align sp to 8 byte boundary |
+ * | ==> args to fn <== |
+ * Room for | |
+ * i & l's + agg | CALL_DUMMY_STACK_ADJUST = 0x0x44|
+ * |---------------------------------|<-- final sp (variable)
+ * | |
+ * | Where function called will |
+ * | build frame. |
+ * | |
+ * | |
+ *
+ * I understand everything in this picture except what the space
+ * between fp - 0xe0 and fp - 0x140 is used for. Oh, and I don't
+ * understand why there's a large chunk of CALL_DUMMY that never gets
+ * executed (its function is superceeded by PUSH_DUMMY_FRAME; they
+ * are designed to do the same thing).
+ *
+ * PUSH_DUMMY_FRAME saves the registers above sp' and pushes the
+ * register file stack down one.
+ *
+ * call_function then writes CALL_DUMMY, pushes the args onto the
+ * stack, and adjusts the stack pointer.
+ *
+ * run_stack_dummy then starts execution (in the middle of
+ * CALL_DUMMY, as directed by call_function).
+ */
+
+#ifndef CALL_DUMMY
+/* This sequence of words is the instructions
+
+ 00: bc 10 00 01 mov %g1, %fp
+ 04: 9d e3 80 00 save %sp, %g0, %sp
+ 08: bc 10 00 02 mov %g2, %fp
+ 0c: be 10 00 03 mov %g3, %i7
+ 10: da 03 a0 58 ld [ %sp + 0x58 ], %o5
+ 14: d8 03 a0 54 ld [ %sp + 0x54 ], %o4
+ 18: d6 03 a0 50 ld [ %sp + 0x50 ], %o3
+ 1c: d4 03 a0 4c ld [ %sp + 0x4c ], %o2
+ 20: d2 03 a0 48 ld [ %sp + 0x48 ], %o1
+ 24: 40 00 00 00 call <fun>
+ 28: d0 03 a0 44 ld [ %sp + 0x44 ], %o0
+ 2c: 01 00 00 00 nop
+ 30: 91 d0 20 01 ta 1
+ 34: 01 00 00 00 nop
+
+ NOTES:
+ * the first four instructions are necessary only on the simulator.
+ * this is a multiple of 8 (not only 4) bytes.
+ * the `call' insn is a relative, not an absolute call.
+ * the `nop' at the end is needed to keep the trap from
+ clobbering things (if NPC pointed to garbage instead).
+ */
+
+#if !defined (GDB_MULTI_ARCH) || (GDB_MULTI_ARCH == 0)
+/*
+ * The following defines must go away for MULTI_ARCH.
+ */
+
+#define CALL_DUMMY { 0xbc100001, 0x9de38000, 0xbc100002, 0xbe100003, \
+ 0xda03a058, 0xd803a054, 0xd603a050, 0xd403a04c, \
+ 0xd203a048, 0x40000000, 0xd003a044, 0x01000000, \
+ 0x91d02001, 0x01000000 }
+
+
+/* Size of the call dummy in bytes. */
+
+#define CALL_DUMMY_LENGTH 0x38
+
+/* Offset within call dummy of first instruction to execute. */
+
+#define CALL_DUMMY_START_OFFSET 0
+
+/* Offset within CALL_DUMMY of the 'call' instruction. */
+
+#define CALL_DUMMY_CALL_OFFSET (CALL_DUMMY_START_OFFSET + 0x24)
+
+/* Offset within CALL_DUMMY of the 'ta 1' trap instruction. */
+
+#define CALL_DUMMY_BREAKPOINT_OFFSET (CALL_DUMMY_START_OFFSET + 0x30)
+
+#define CALL_DUMMY_STACK_ADJUST 68
+
+/* Call dummy method (eg. on stack, at entry point, etc.) */
+
+#define CALL_DUMMY_LOCATION ON_STACK
+
+/* Method for detecting dummy frames. */
+
+#define PC_IN_CALL_DUMMY(PC, SP, FRAME_ADDRESS) \
+ pc_in_call_dummy_on_stack (PC, SP, FRAME_ADDRESS)
+
+#endif /* GDB_MULTI_ARCH */
+
+#endif /* CALL_DUMMY */
+
+#if !defined (GDB_MULTI_ARCH) || (GDB_MULTI_ARCH == 0)
+/*
+ * The following defines must go away for MULTI_ARCH.
+ */
+
+/* Insert the specified number of args and function address
+ into a call sequence of the above form stored at DUMMYNAME. */
+
+#define FIX_CALL_DUMMY(DUMMYNAME, PC, FUN, NARGS, ARGS, TYPE, GCC_P) \
+ sparc_fix_call_dummy (DUMMYNAME, PC, FUN, TYPE, GCC_P)
+void sparc_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun,
+ struct type *value_type, int using_gcc);
+
+/* Arguments smaller than an int must be promoted to ints when
+ synthesizing function calls. */
+
+/* Push an empty stack frame, to record the current PC, etc. */
+
+#define PUSH_DUMMY_FRAME sparc_push_dummy_frame ()
+#define POP_FRAME sparc_pop_frame ()
+
+void sparc_push_dummy_frame (void);
+void sparc_pop_frame (void);
+
+#define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \
+ sparc32_push_arguments (NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR)
+
+extern CORE_ADDR
+sparc32_push_arguments (int, struct value **, CORE_ADDR, int, CORE_ADDR);
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function_by_hand.
+ The ultimate mystery is, tho, what is the value "16"? */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+ { char val[4]; \
+ store_unsigned_integer (val, 4, (ADDR)); \
+ write_memory ((SP)+(16*4), val, 4); }
+
+/* Default definition of USE_STRUCT_CONVENTION. */
+
+#ifndef USE_STRUCT_CONVENTION
+#define USE_STRUCT_CONVENTION(GCC_P, TYPE) \
+ generic_use_struct_convention (GCC_P, TYPE)
+#endif
+
+/* Extract from an array REGBUF containing the (raw) register state a
+ function return value of type TYPE, and copy that, in virtual
+ format, into VALBUF. */
+
+#define EXTRACT_RETURN_VALUE(TYPE, REGBUF, VALBUF) \
+ sparc32_extract_return_value (TYPE, REGBUF, VALBUF)
+extern void sparc32_extract_return_value (struct type *, char[], char *);
+
+#endif /* GDB_MULTI_ARCH */
+
+
+/* Sparc has no reliable single step ptrace call */
+
+#define SOFTWARE_SINGLE_STEP_P() 1
+extern void sparc_software_single_step (enum target_signal, int);
+#define SOFTWARE_SINGLE_STEP(sig,bp_p) sparc_software_single_step (sig,bp_p)
+
+/* We need more arguments in a frame specification for the
+ "frame" or "info frame" command. */
+
+#define SETUP_ARBITRARY_FRAME(argc, argv) setup_arbitrary_frame (argc, argv)
+extern struct frame_info *setup_arbitrary_frame (int, CORE_ADDR *);
+
+/* To print every pair of float registers as a double, we use this hook.
+ We also print the condition code registers in a readable format
+ (FIXME: can expand this to all control regs). */
+
+#undef PRINT_REGISTER_HOOK
+#define PRINT_REGISTER_HOOK(regno) \
+ sparc_print_register_hook (regno)
+extern void sparc_print_register_hook (int regno);
+
+/* Optimization for storing registers to the inferior. The hook
+ DO_DEFERRED_STORES
+ actually executes any deferred stores. It is called any time
+ we are going to proceed the child, or read its registers.
+ The hook CLEAR_DEFERRED_STORES is called when we want to throw
+ away the inferior process, e.g. when it dies or we kill it.
+ FIXME, this does not handle remote debugging cleanly. */
+
+extern int deferred_stores;
+#define DO_DEFERRED_STORES \
+ if (deferred_stores) \
+ target_store_registers (-2);
+#define CLEAR_DEFERRED_STORES \
+ deferred_stores = 0;
+
+/* Select the sparc disassembler */
+
+#define TM_PRINT_INSN_MACH bfd_mach_sparc
+
diff --git a/gdb/config/sparc/tm-sparclet.h b/gdb/config/sparc/tm-sparclet.h
new file mode 100644
index 00000000000..cc52d5a26d5
--- /dev/null
+++ b/gdb/config/sparc/tm-sparclet.h
@@ -0,0 +1,156 @@
+/* Target machine definitions for GDB for an embedded SPARC.
+ Copyright 1996, 1997, 2000 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 "regcache.h"
+
+#define TARGET_SPARCLET 1 /* Still needed for non-multi-arch case */
+
+#include "sparc/tm-sparc.h"
+
+/* Note: we are not defining GDB_MULTI_ARCH for the sparclet target
+ at this time, because we have not figured out how to detect the
+ sparclet target from the bfd structure. */
+
+/* Sparclet regs, for debugging purposes. */
+
+enum {
+ CCSR_REGNUM = 72,
+ CCPR_REGNUM = 73,
+ CCCRCR_REGNUM = 74,
+ CCOR_REGNUM = 75,
+ CCOBR_REGNUM = 76,
+ CCIBR_REGNUM = 77,
+ CCIR_REGNUM = 78
+};
+
+/* Select the sparclet disassembler. Slightly different instruction set from
+ the V8 sparc. */
+
+#undef TM_PRINT_INSN_MACH
+#define TM_PRINT_INSN_MACH bfd_mach_sparc_sparclet
+
+/* overrides of tm-sparc.h */
+
+#undef TARGET_BYTE_ORDER
+
+/* Sequence of bytes for breakpoint instruction (ta 1). */
+#undef BREAKPOINT
+#define BIG_BREAKPOINT {0x91, 0xd0, 0x20, 0x01}
+#define LITTLE_BREAKPOINT {0x01, 0x20, 0xd0, 0x91}
+
+#if !defined (GDB_MULTI_ARCH) || (GDB_MULTI_ARCH == 0)
+/*
+ * The following defines must go away for MULTI_ARCH.
+ */
+
+#undef NUM_REGS /* formerly "72" */
+/* WIN FP CPU CCP ASR AWR APSR */
+#define NUM_REGS (32 + 32 + 8 + 8 + 8/*+ 32 + 1*/)
+
+#undef REGISTER_BYTES /* formerly "(32*4 + 32*4 + 8*4)" */
+#define REGISTER_BYTES (32*4 + 32*4 + 8*4 + 8*4 + 8*4/* + 32*4 + 1*4*/)
+
+/* Initializer for an array of names of registers.
+ There should be NUM_REGS strings in this initializer. */
+/* Sparclet has no fp! */
+/* Compiler maps types for floats by number, so can't
+ change the numbers here. */
+
+#undef REGISTER_NAMES
+#define REGISTER_NAMES \
+{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \
+ "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7", \
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", \
+ "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7", \
+ \
+ "", "", "", "", "", "", "", "", /* no FPU regs */ \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ /* no CPSR, FPSR */ \
+ "y", "psr", "wim", "tbr", "pc", "npc", "", "", \
+ \
+ "ccsr", "ccpr", "cccrcr", "ccor", "ccobr", "ccibr", "ccir", "", \
+ \
+ /* ASR15 ASR19 (don't display them) */ \
+ "asr1", "", "asr17", "asr18", "", "asr20", "asr21", "asr22", \
+/* \
+ "awr0", "awr1", "awr2", "awr3", "awr4", "awr5", "awr6", "awr7", \
+ "awr8", "awr9", "awr10", "awr11", "awr12", "awr13", "awr14", "awr15", \
+ "awr16", "awr17", "awr18", "awr19", "awr20", "awr21", "awr22", "awr23", \
+ "awr24", "awr25", "awr26", "awr27", "awr28", "awr29", "awr30", "awr31", \
+ "apsr", \
+ */ \
+}
+
+/* Remove FP dependant code which was defined in tm-sparc.h */
+#undef FP0_REGNUM /* Floating point register 0 */
+#undef FPS_REGNUM /* Floating point status register */
+#undef CPS_REGNUM /* Coprocessor status register */
+
+/* sparclet register numbers */
+#define CCSR_REGNUM 72
+
+#undef EXTRACT_RETURN_VALUE
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ { \
+ memcpy ((VALBUF), \
+ (char *)(REGBUF) + REGISTER_RAW_SIZE (O0_REGNUM) * 8 + \
+ (TYPE_LENGTH(TYPE) >= REGISTER_RAW_SIZE (O0_REGNUM) \
+ ? 0 : REGISTER_RAW_SIZE (O0_REGNUM) - TYPE_LENGTH(TYPE)), \
+ TYPE_LENGTH(TYPE)); \
+ }
+#undef STORE_RETURN_VALUE
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ { \
+ /* Other values are returned in register %o0. */ \
+ write_register_bytes (REGISTER_BYTE (O0_REGNUM), (VALBUF), \
+ TYPE_LENGTH (TYPE)); \
+ }
+
+#endif /* GDB_MULTI_ARCH */
+
+#undef PRINT_REGISTER_HOOK
+#define PRINT_REGISTER_HOOK(regno)
+
+/* Offsets into jmp_buf. Not defined by Sun, but at least documented in a
+ comment in <machine/setjmp.h>! */
+
+#define JB_ELEMENT_SIZE 4 /* Size of each element in jmp_buf */
+
+#define JB_ONSSTACK 0
+#define JB_SIGMASK 1
+#define JB_SP 2
+#define JB_PC 3
+#define JB_NPC 4
+#define JB_PSR 5
+#define JB_G1 6
+#define JB_O0 7
+#define JB_WBCNT 8
+
+/* Figure out where the longjmp will land. We expect that we have just entered
+ longjmp and haven't yet setup the stack frame, so the args are still in the
+ output regs. %o0 (O0_REGNUM) points at the jmp_buf structure from which we
+ extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+extern int get_longjmp_target (CORE_ADDR *);
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
diff --git a/gdb/config/sparc/tm-sparclite.h b/gdb/config/sparc/tm-sparclite.h
new file mode 100644
index 00000000000..8fafe5e3b4f
--- /dev/null
+++ b/gdb/config/sparc/tm-sparclite.h
@@ -0,0 +1,126 @@
+/* Macro definitions for GDB for a Fujitsu SPARClite.
+ Copyright 1993, 1994, 1995, 1998, 1999, 2000
+ 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 "regcache.h"
+
+#define TARGET_SPARCLITE 1 /* Still needed for non-multi-arch case */
+
+#include "sparc/tm-sparc.h"
+
+/* Note: we are not defining GDB_MULTI_ARCH for the sparclet target
+ at this time, because we have not figured out how to detect the
+ sparclet target from the bfd structure. */
+
+/* Sparclite regs, for debugging purposes */
+
+enum {
+ DIA1_REGNUM = 72, /* debug instr address register 1 */
+ DIA2_REGNUM = 73, /* debug instr address register 2 */
+ DDA1_REGNUM = 74, /* debug data address register 1 */
+ DDA2_REGNUM = 75, /* debug data address register 2 */
+ DDV1_REGNUM = 76, /* debug data value register 1 */
+ DDV2_REGNUM = 77, /* debug data value register 2 */
+ DCR_REGNUM = 78, /* debug control register */
+ DSR_REGNUM = 79 /* debug status regsiter */
+};
+
+/* overrides of tm-sparc.h */
+
+#undef TARGET_BYTE_ORDER
+
+/* Select the sparclite disassembler. Slightly different instruction set from
+ the V8 sparc. */
+
+#undef TM_PRINT_INSN_MACH
+#define TM_PRINT_INSN_MACH bfd_mach_sparc_sparclite
+
+/* Amount PC must be decremented by after a hardware instruction breakpoint.
+ This is often the number of bytes in BREAKPOINT
+ but not always. */
+
+#define DECR_PC_AFTER_HW_BREAK 4
+
+#if !defined (GDB_MULTI_ARCH) || (GDB_MULTI_ARCH == 0)
+/*
+ * The following defines must go away for MULTI_ARCH.
+ */
+
+#undef FRAME_CHAIN_VALID
+#define FRAME_CHAIN_VALID(FP,FI) func_frame_chain_valid (FP, FI)
+
+#undef NUM_REGS
+#define NUM_REGS 80
+
+#undef REGISTER_BYTES
+#define REGISTER_BYTES (32*4+32*4+8*4+8*4)
+
+#undef REGISTER_NAMES
+#define REGISTER_NAMES \
+{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \
+ "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", \
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", \
+ "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", \
+ \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
+ \
+ "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr", \
+ "dia1", "dia2", "dda1", "dda2", "ddv1", "ddv2", "dcr", "dsr" }
+
+#define DIA1_REGNUM 72 /* debug instr address register 1 */
+#define DIA2_REGNUM 73 /* debug instr address register 2 */
+#define DDA1_REGNUM 74 /* debug data address register 1 */
+#define DDA2_REGNUM 75 /* debug data address register 2 */
+#define DDV1_REGNUM 76 /* debug data value register 1 */
+#define DDV2_REGNUM 77 /* debug data value register 2 */
+#define DCR_REGNUM 78 /* debug control register */
+#define DSR_REGNUM 79 /* debug status regsiter */
+
+#endif /* GDB_MULTI_ARCH */
+
+#define TARGET_HW_BREAK_LIMIT 2
+#define TARGET_HW_WATCH_LIMIT 2
+
+/* Enable watchpoint macro's */
+
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \
+ sparclite_check_watch_resources (type, cnt, ot)
+
+/* When a hardware watchpoint fires off the PC will be left at the
+ instruction which caused the watchpoint. It will be necessary for
+ GDB to step over the watchpoint. ***
+
+ #define STOPPED_BY_WATCHPOINT(W) \
+ ((W).kind == TARGET_WAITKIND_STOPPED \
+ && (W).value.sig == TARGET_SIGNAL_TRAP \
+ && ((int) read_register (IPSW_REGNUM) & 0x00100000))
+ */
+
+/* Use these macros for watchpoint insertion/deletion. */
+#define target_insert_watchpoint(addr, len, type) sparclite_insert_watchpoint (addr, len, type)
+#define target_remove_watchpoint(addr, len, type) sparclite_remove_watchpoint (addr, len, type)
+#define target_insert_hw_breakpoint(addr, len) sparclite_insert_hw_breakpoint (addr, len)
+#define target_remove_hw_breakpoint(addr, len) sparclite_remove_hw_breakpoint (addr, len)
+#define target_stopped_data_address() sparclite_stopped_data_address()
diff --git a/gdb/config/sparc/tm-sparclynx.h b/gdb/config/sparc/tm-sparclynx.h
new file mode 100644
index 00000000000..1a28621c065
--- /dev/null
+++ b/gdb/config/sparc/tm-sparclynx.h
@@ -0,0 +1,37 @@
+/* Macro definitions for Sparc running under LynxOS.
+ Copyright 1993, 1994 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. */
+
+#ifndef TM_SPARCLYNX_H
+#define TM_SPARCLYNX_H
+
+#include "tm-lynx.h"
+
+/* Use generic Sparc definitions. */
+#include "sparc/tm-sparc.h"
+
+/* Lynx does this backwards from everybody else */
+
+#undef FRAME_SAVED_I0
+#undef FRAME_SAVED_L0
+
+#define FRAME_SAVED_I0 0
+#define FRAME_SAVED_L0 (8 * REGISTER_RAW_SIZE (I0_REGNUM))
+
+#endif /* TM_SPARCLYNX_H */
diff --git a/gdb/config/sparc/tm-spc-em.h b/gdb/config/sparc/tm-spc-em.h
new file mode 100644
index 00000000000..760e7a4258a
--- /dev/null
+++ b/gdb/config/sparc/tm-spc-em.h
@@ -0,0 +1,46 @@
+/* Target machine definitions for GDB for an embedded SPARC.
+ Copyright 1989, 1992, 1993, 2000 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 "sparc/tm-sparc.h"
+
+/* Offsets into jmp_buf. Not defined by Sun, but at least documented in a
+ comment in <machine/setjmp.h>! */
+
+#define JB_ELEMENT_SIZE 4 /* Size of each element in jmp_buf */
+
+#define JB_ONSSTACK 0
+#define JB_SIGMASK 1
+#define JB_SP 2
+#define JB_PC 3
+#define JB_NPC 4
+#define JB_PSR 5
+#define JB_G1 6
+#define JB_O0 7
+#define JB_WBCNT 8
+
+/* Figure out where the longjmp will land. We expect that we have just entered
+ longjmp and haven't yet setup the stack frame, so the args are still in the
+ output regs. %o0 (O0_REGNUM) points at the jmp_buf structure from which we
+ extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+extern int get_longjmp_target (CORE_ADDR *);
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
diff --git a/gdb/config/sparc/tm-sun4os4.h b/gdb/config/sparc/tm-sun4os4.h
new file mode 100644
index 00000000000..b561b13adc7
--- /dev/null
+++ b/gdb/config/sparc/tm-sun4os4.h
@@ -0,0 +1,59 @@
+/* Macro definitions for GDB for a Sun 4 running sunos 4.
+ Copyright 1989, 1992, 1994, 1995, 1998, 2000
+ 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 "sparc/tm-sparc.h"
+#include "tm-sunos.h"
+
+/* Redefine SKIP_TRAMPOLINE_CODE to handle PIC compiled modules
+ in main executables. */
+
+#undef SKIP_TRAMPOLINE_CODE
+#define SKIP_TRAMPOLINE_CODE(pc) sunos4_skip_trampoline_code (pc)
+extern CORE_ADDR sunos4_skip_trampoline_code (CORE_ADDR);
+
+/* Offsets into jmp_buf. Not defined by Sun, but at least documented in a
+ comment in <machine/setjmp.h>! */
+
+#define JB_ELEMENT_SIZE 4 /* Size of each element in jmp_buf */
+
+#define JB_ONSSTACK 0
+#define JB_SIGMASK 1
+#define JB_SP 2
+#define JB_PC 3
+#define JB_NPC 4
+#define JB_PSR 5
+#define JB_G1 6
+#define JB_O0 7
+#define JB_WBCNT 8
+
+/* Figure out where the longjmp will land. We expect that we have just entered
+ longjmp and haven't yet setup the stack frame, so the args are still in the
+ output regs. %o0 (O0_REGNUM) points at the jmp_buf structure from which we
+ extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+extern int get_longjmp_target (CORE_ADDR *);
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+
+extern char *sunpro_static_transform_name (char *);
+#define STATIC_TRANSFORM_NAME(x) sunpro_static_transform_name (x)
+#define IS_STATIC_TRANSFORM_NAME(name) ((name)[0] == '$')
diff --git a/gdb/config/sparc/tm-sun4sol2.h b/gdb/config/sparc/tm-sun4sol2.h
new file mode 100644
index 00000000000..e3c59f630de
--- /dev/null
+++ b/gdb/config/sparc/tm-sun4sol2.h
@@ -0,0 +1,82 @@
+/* Macro definitions for GDB for a Sun 4 running Solaris 2
+ Copyright 1989, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000
+ 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. */
+
+#define GDB_MULTI_ARCH GDB_MULTI_ARCH_PARTIAL
+
+#include "sparc/tm-sparc.h"
+#include "tm-sysv4.h"
+
+/* With Sol2 it is no longer necessary to enable software single-step,
+ since the /proc interface can take care of it for us in hardware. */
+#undef SOFTWARE_SINGLE_STEP
+#undef SOFTWARE_SINGLE_STEP_P
+
+/* There are two different signal handler trampolines in Solaris2. */
+#define IN_SIGTRAMP(pc, name) \
+ ((name) \
+ && (STREQ ("sigacthandler", name) || STREQ ("ucbsigvechandler", name)))
+
+/* The signal handler gets a pointer to an ucontext as third argument
+ if it is called from sigacthandler. This is the offset to the saved
+ PC within it. sparc_frame_saved_pc knows how to deal with
+ ucbsigvechandler. */
+#define SIGCONTEXT_PC_OFFSET 44
+
+#if 0 /* FIXME Setjmp/longjmp are not as well doc'd in SunOS 5.x yet */
+
+/* Offsets into jmp_buf. Not defined by Sun, but at least documented in a
+ comment in <machine/setjmp.h>! */
+
+#define JB_ELEMENT_SIZE 4 /* Size of each element in jmp_buf */
+
+#define JB_ONSSTACK 0
+#define JB_SIGMASK 1
+#define JB_SP 2
+#define JB_PC 3
+#define JB_NPC 4
+#define JB_PSR 5
+#define JB_G1 6
+#define JB_O0 7
+#define JB_WBCNT 8
+
+/* Figure out where the longjmp will land. We expect that we have just entered
+ longjmp and haven't yet setup the stack frame, so the args are still in the
+ output regs. %o0 (O0_REGNUM) points at the jmp_buf structure from which we
+ extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+extern int get_longjmp_target (CORE_ADDR *);
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+#endif /* 0 */
+
+/* The SunPRO compiler puts out 0 instead of the address in N_SO symbols,
+ and for SunPRO 3.0, N_FUN symbols too. */
+#define SOFUN_ADDRESS_MAYBE_MISSING
+
+extern char *sunpro_static_transform_name (char *);
+#define STATIC_TRANSFORM_NAME(x) sunpro_static_transform_name (x)
+#define IS_STATIC_TRANSFORM_NAME(name) ((name)[0] == '$')
+
+#define FAULTED_USE_SIGINFO
+
+/* Enable handling of shared libraries for a.out executables. */
+#define HANDLE_SVR4_EXEC_EMULATORS
diff --git a/gdb/config/sparc/tm-vxsparc.h b/gdb/config/sparc/tm-vxsparc.h
new file mode 100644
index 00000000000..b6529f75b7f
--- /dev/null
+++ b/gdb/config/sparc/tm-vxsparc.h
@@ -0,0 +1,33 @@
+/* Target machine description for VxWorks sparc's, for GDB, the GNU debugger.
+ Copyright 1993, 1999 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 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 "sparc/tm-spc-em.h"
+#include "tm-vxworks.h"
+
+/* FIXME: These are almost certainly wrong. */
+
+/* Number of registers in a ptrace_getregs call. */
+
+#define VX_NUM_REGS (NUM_REGS)
+
+/* Number of registers in a ptrace_getfpregs call. */
+
+/* #define VX_SIZE_FPREGS (don't know how many) */
diff --git a/gdb/config/sparc/vxsparc.mt b/gdb/config/sparc/vxsparc.mt
new file mode 100644
index 00000000000..9eadd17451d
--- /dev/null
+++ b/gdb/config/sparc/vxsparc.mt
@@ -0,0 +1,3 @@
+# Target: SPARC running VxWorks
+TDEPFILES= sparc-tdep.o remote-vx.o remote-vxsparc.o xdr_ld.o xdr_ptrace.o xdr_rdb.o
+TM_FILE= tm-vxsparc.h
diff --git a/gdb/config/sparc/xm-linux.h b/gdb/config/sparc/xm-linux.h
new file mode 100644
index 00000000000..b0518e650e9
--- /dev/null
+++ b/gdb/config/sparc/xm-linux.h
@@ -0,0 +1,42 @@
+/* Macro definitions for running gdb on a Sparc running GNU/Linux.
+
+ Copyright 1989, 1993, 1994, 1995, 1996, 1998, 2001, 2002 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. */
+
+#ifndef XM_SPARCLINUX_H
+#define XM_SPARCLINUX_H
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+#define KERNEL_U_ADDR 0x0
+
+#define U_REGS_OFFSET 0
+
+/* If you expect to use the mmalloc package to obtain mapped symbol files,
+ for now you have to specify some parameters that determine how gdb places
+ the mappings in it's address space. See the comments in map_to_address()
+ for details. This is expected to only be a short term solution. Yes it
+ is a kludge.
+ FIXME: Make this more automatic. */
+
+#define MMAP_BASE_ADDRESS 0xE0000000 /* First mapping here */
+#define MMAP_INCREMENT 0x01000000 /* Increment to next mapping */
+
+#endif /* _XM_SPARCLINUX_H */
diff --git a/gdb/config/sparc/xm-nbsd.h b/gdb/config/sparc/xm-nbsd.h
new file mode 100644
index 00000000000..e469aabc1b4
--- /dev/null
+++ b/gdb/config/sparc/xm-nbsd.h
@@ -0,0 +1,22 @@
+/* Parameters for execution on a Sparc running NetBSD, for GDB.
+ Copyright 1994 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. */
+
+/* Get generic NetBSD host definitions. */
+#include "xm-nbsd.h"
diff --git a/gdb/config/sparc/xm-sun4sol2.h b/gdb/config/sparc/xm-sun4sol2.h
new file mode 100644
index 00000000000..b775f7cdba0
--- /dev/null
+++ b/gdb/config/sparc/xm-sun4sol2.h
@@ -0,0 +1,37 @@
+/* Macro definitions for running gdb on a Sun 4 running Solaris 2.
+ Copyright 1989, 1992, 1993, 1994, 1995, 1996, 1998, 2000
+ 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. */
+
+/* Pick up more stuff from the generic SVR4 host include file. */
+
+#include "xm-sysv4.h"
+
+/* These are not currently used in SVR4 (but should be, FIXME!). */
+#undef DO_DEFERRED_STORES
+#undef CLEAR_DEFERRED_STORES
+
+/* solaris doesn't have siginterrupt, though it has sigaction; however,
+ in this case siginterrupt would just be setting the default. */
+#define NO_SIGINTERRUPT
+
+/* On sol2.7, <curses.h> emits a bunch of 'macro redefined'
+ warnings, which makes autoconf think curses.h doesn't
+ exist. Compensate for that here. */
+#define HAVE_CURSES_H 1
diff --git a/gdb/config/tm-linux.h b/gdb/config/tm-linux.h
new file mode 100644
index 00000000000..938987270b7
--- /dev/null
+++ b/gdb/config/tm-linux.h
@@ -0,0 +1,42 @@
+/* Native support for GNU/Linux, for GDB, the GNU debugger.
+ Copyright 1999, 2000
+ 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. */
+
+/* Pick reasonable defaults for the number of real-time signals. */
+
+#ifndef REALTIME_LO
+#define REALTIME_LO 32
+#endif
+#ifndef REALTIME_HI
+#define REALTIME_HI 64
+#endif
+
+/* We need this file for the SOLIB_TRAMPOLINE stuff. */
+
+#include "tm-sysv4.h"
+
+/* We define SVR4_SHARED_LIBS unconditionally, on the assumption that
+ link.h is available on all linux platforms. For I386 and SH3/4,
+ we hard-code the information rather than use link.h anyway (for
+ the benefit of cross-debugging). We may move to doing that for
+ other architectures as well. */
+
+#define SVR4_SHARED_LIBS
+#include "solib.h" /* Support for shared libraries. */
diff --git a/gdb/config/tm-lynx.h b/gdb/config/tm-lynx.h
new file mode 100644
index 00000000000..13aeca1c3f7
--- /dev/null
+++ b/gdb/config/tm-lynx.h
@@ -0,0 +1,35 @@
+/* Macro definitions for LynxOS targets.
+ Copyright 1993, 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. */
+
+#ifndef TM_LYNX_H
+#define TM_LYNX_H
+
+/* Override number of expected traps from sysv. */
+#define START_INFERIOR_TRAPS_EXPECTED 2
+
+#include "coff-solib.h" /* COFF shared library support */
+
+/* Lynx's signal.h doesn't seem to have any macros for what signal numbers
+ the real-time events are. */
+#define REALTIME_LO 33
+/* One more than the last one. */
+#define REALTIME_HI 64
+
+#endif /* TM_LYNX_H */
diff --git a/gdb/config/tm-sunos.h b/gdb/config/tm-sunos.h
new file mode 100644
index 00000000000..c8db07e865e
--- /dev/null
+++ b/gdb/config/tm-sunos.h
@@ -0,0 +1,32 @@
+/* Target machine sub-description for SunOS version 4.
+ This is included by other tm-*.h files to specify SunOS-specific stuff.
+ Copyright 1990, 1991, 1992, 1993, 1994 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 "solib.h" /* Support for shared libraries. */
+
+/* Return non-zero if we are in a shared library trampoline code stub. */
+
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
+ lookup_solib_trampoline_symbol_by_pc (pc)
+
+/* If PC is in a shared library trampoline code, return the PC
+ where the function itself actually starts. If not, return 0. */
+
+#define SKIP_TRAMPOLINE_CODE(pc) find_solib_trampoline_target (pc)
diff --git a/gdb/config/tm-sysv4.h b/gdb/config/tm-sysv4.h
new file mode 100644
index 00000000000..35b95eb71f8
--- /dev/null
+++ b/gdb/config/tm-sysv4.h
@@ -0,0 +1,47 @@
+/* Macro definitions for GDB on all SVR4 target systems.
+ Copyright 1991, 1992, 1993, 1994, 1996, 1997, 2000
+ Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus Support (fnf@cygnus.com).
+
+ 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. */
+
+/* For SVR4 shared libraries, each call to a library routine goes through
+ a small piece of trampoline code in the ".plt" section.
+ The horribly ugly wait_for_inferior() routine uses this macro to detect
+ when we have stepped into one of these fragments.
+ We do not use lookup_solib_trampoline_symbol_by_pc, because
+ we cannot always find the shared library trampoline symbols
+ (e.g. on Irix5). */
+
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) in_plt_section((pc), (name))
+extern int in_plt_section (CORE_ADDR, char *);
+
+/* If PC is in a shared library trampoline code, return the PC
+ where the function itself actually starts. If not, return 0. */
+
+#define SKIP_TRAMPOLINE_CODE(pc) find_solib_trampoline_target (pc)
+
+/* It is unknown which, if any, SVR4 assemblers do not accept dollar signs
+ in identifiers. The default in G++ is to use dots instead, for all SVR4
+ systems, so we make that our default also. FIXME: There should be some
+ way to get G++ to tell us what CPLUS_MARKER it is using, perhaps by
+ stashing it in the debugging information as part of the name of an
+ invented symbol ("gcc_cplus_marker$" for example). */
+
+#undef CPLUS_MARKER
+#define CPLUS_MARKER '.'
diff --git a/gdb/config/tm-vxworks.h b/gdb/config/tm-vxworks.h
new file mode 100644
index 00000000000..9afc0b4fc79
--- /dev/null
+++ b/gdb/config/tm-vxworks.h
@@ -0,0 +1,23 @@
+/* Target machine description for VxWorks, for GDB, the GNU debugger.
+ Copyright 1999 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. */
+
+#define GDBINIT_FILENAME ".vxgdbinit"
+
+#define DEFAULT_PROMPT "(vxgdb) "
diff --git a/gdb/config/v850/v850.mt b/gdb/config/v850/v850.mt
new file mode 100644
index 00000000000..867f8e68429
--- /dev/null
+++ b/gdb/config/v850/v850.mt
@@ -0,0 +1,5 @@
+# Target: NEC V850 processor
+TDEPFILES= v850-tdep.o
+# TM_FILE= tm-v850.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/v850/libsim.a
diff --git a/gdb/config/vax/nm-vax.h b/gdb/config/vax/nm-vax.h
new file mode 100644
index 00000000000..c2baef18fa6
--- /dev/null
+++ b/gdb/config/vax/nm-vax.h
@@ -0,0 +1,27 @@
+/* Common definitions for GDB native support on Vaxen under 4.2bsd and Ultrix.
+ Copyright (C) 1986, 1987, 1989, 1992 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. */
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+{ addr = blockend - 0110 + regno * 4; \
+ if (regno == PC_REGNUM) addr = blockend - 8; \
+ if (regno == PS_REGNUM) addr = blockend - 4; \
+ if (regno == FP_REGNUM) addr = blockend - 0120; \
+ if (regno == AP_REGNUM) addr = blockend - 0124; \
+ if (regno == SP_REGNUM) addr = blockend - 20; }
diff --git a/gdb/config/vax/tm-vax.h b/gdb/config/vax/tm-vax.h
new file mode 100644
index 00000000000..204d155ab6d
--- /dev/null
+++ b/gdb/config/vax/tm-vax.h
@@ -0,0 +1,48 @@
+/* Definitions to make GDB run on a vax under 4.2bsd.
+ Copyright 1986, 1987, 1989, 1991, 1993, 1994, 1996, 1998, 1999, 2000, 2002
+ 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. */
+
+#define GDB_MULTI_ARCH GDB_MULTI_ARCH_PARTIAL
+
+#define TARGET_UPAGES 14
+#define TARGET_NBPG 512
+#define STACK_END_ADDR (0x80000000 - (TARGET_UPAGES * TARGET_NBPG))
+
+/* On the VAX, sigtramp is in the u area. Can't check the exact
+ addresses because for cross-debugging we don't have VAX include
+ files around. This should be close enough. */
+#define SIGTRAMP_START(pc) STACK_END_ADDR
+#define SIGTRAMP_END(pc) 0x80000000
+
+/* Sequence of bytes for breakpoint instruction. */
+#define BREAKPOINT {3}
+
+#define AP_REGNUM 12 /* XXXJRT */
+
+/* Offset to saved PC in sigcontext, from <sys/signal.h>. */
+/* XXXJRT should go away */
+#define SIGCONTEXT_PC_OFFSET 12
+
+/* XXXJRT not yet under gdbarch control */
+#define FRAME_ARGS_ADDRESS_CORRECT(fi) vax_frame_args_address_correct ((fi))
+extern CORE_ADDR vax_frame_args_address_correct (struct frame_info *);
+
+/* If vax pcc says CHAR or SHORT, it provides the correct address. */
+#define BELIEVE_PCC_PROMOTION 1
diff --git a/gdb/config/vax/vax.mt b/gdb/config/vax/vax.mt
new file mode 100644
index 00000000000..ebdf942b3d9
--- /dev/null
+++ b/gdb/config/vax/vax.mt
@@ -0,0 +1,3 @@
+# Target: DEC VAX running BSD or Ultrix
+TDEPFILES= vax-tdep.o
+TM_FILE= tm-vax.h
diff --git a/gdb/config/vax/vaxbsd.mh b/gdb/config/vax/vaxbsd.mh
new file mode 100644
index 00000000000..db1e1d4371d
--- /dev/null
+++ b/gdb/config/vax/vaxbsd.mh
@@ -0,0 +1,13 @@
+# Host: DEC VAX running BSD
+
+# The following types of /bin/cc failures have been observed:
+# 1. Something in readline.c which I have never seen
+# 2. ``"values.c", line 816: compiler error: schain botch''
+#msg /bin/cc has been known to fail on VAXen running BSD4.3
+#msg If this occurs, use gcc
+#msg (but see comments in Makefile.dist about compiling with gcc).
+
+XM_FILE= xm-vaxbsd.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o core-aout.o
+
+NAT_FILE= nm-vax.h
diff --git a/gdb/config/vax/vaxult.mh b/gdb/config/vax/vaxult.mh
new file mode 100644
index 00000000000..f05a33fa198
--- /dev/null
+++ b/gdb/config/vax/vaxult.mh
@@ -0,0 +1,6 @@
+# Host: DEC VAX running Ultrix
+
+XM_FILE= xm-vaxult.h
+
+NAT_FILE= nm-vax.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o core-aout.o
diff --git a/gdb/config/vax/vaxult2.mh b/gdb/config/vax/vaxult2.mh
new file mode 100644
index 00000000000..4170a841257
--- /dev/null
+++ b/gdb/config/vax/vaxult2.mh
@@ -0,0 +1,6 @@
+# Host: DEC VAX running Ultrix
+
+XM_FILE= xm-vaxult2.h
+
+NAT_FILE= nm-vax.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o core-aout.o
diff --git a/gdb/config/vax/xm-vax.h b/gdb/config/vax/xm-vax.h
new file mode 100644
index 00000000000..9924f260140
--- /dev/null
+++ b/gdb/config/vax/xm-vax.h
@@ -0,0 +1,80 @@
+/* Common definitions to make GDB run on Vaxen under 4.2bsd and Ultrix.
+ Copyright (C) 1986, 1987, 1989, 1992 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. */
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+
+#define KERNEL_U_ADDR (0x80000000 - (UPAGES * NBPG))
+
+/* Kernel is a bit tenacious about sharing text segments, disallowing bpts. */
+#define ONE_PROCESS_WRITETEXT
+
+/* Interface definitions for kernel debugger KDB. */
+
+/* Map machine fault codes into signal numbers.
+ First subtract 0, divide by 4, then index in a table.
+ Faults for which the entry in this table is 0
+ are not handled by KDB; the program's own trap handler
+ gets to handle then. */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE \
+{ 0, SIGKILL, SIGSEGV, 0, 0, 0, 0, 0, \
+ 0, 0, SIGTRAP, SIGTRAP, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0}
+
+/* Start running with a stack stretching from BEG to END.
+ BEG and END should be symbols meaningful to the assembler.
+ This is used only for kdb. */
+
+#define INIT_STACK(beg, end) \
+{ asm (".globl end"); \
+ asm ("movl $ end, sp"); \
+ asm ("clrl fp"); }
+
+/* Push the frame pointer register on the stack. */
+#define PUSH_FRAME_PTR \
+ asm ("pushl fp");
+
+/* Copy the top-of-stack to the frame pointer register. */
+#define POP_FRAME_PTR \
+ asm ("movl (sp), fp");
+
+/* After KDB is entered by a fault, push all registers
+ that GDB thinks about (all NUM_REGS of them),
+ so that they appear in order of ascending GDB register number.
+ The fault code will be on the stack beyond the last register. */
+
+#define PUSH_REGISTERS \
+{ asm ("pushl 8(sp)"); \
+ asm ("pushl 8(sp)"); \
+ asm ("pushal 0x14(sp)"); \
+ asm ("pushr $037777"); }
+
+/* Assuming the registers (including processor status) have been
+ pushed on the stack in order of ascending GDB register number,
+ restore them and return to the address in the saved PC register. */
+
+#define POP_REGISTERS \
+{ asm ("popr $037777"); \
+ asm ("subl2 $8,(sp)"); \
+ asm ("movl (sp),sp"); \
+ asm ("rei"); }
diff --git a/gdb/config/vax/xm-vaxbsd.h b/gdb/config/vax/xm-vaxbsd.h
new file mode 100644
index 00000000000..6defcc6e079
--- /dev/null
+++ b/gdb/config/vax/xm-vaxbsd.h
@@ -0,0 +1,7 @@
+/* Definitions to make GDB run on a vax under BSD, 4.3 or 4.4. */
+
+/* This should exist on either 4.3 or 4.4. 4.3 doesn't have limits.h
+ or machine/limits.h. */
+#include <sys/param.h>
+
+#include "vax/xm-vax.h"
diff --git a/gdb/config/vax/xm-vaxult.h b/gdb/config/vax/xm-vaxult.h
new file mode 100644
index 00000000000..576a44fde57
--- /dev/null
+++ b/gdb/config/vax/xm-vaxult.h
@@ -0,0 +1,10 @@
+/* Definitions to make GDB run on a vax under Ultrix. */
+
+#include "vax/xm-vax.h"
+/* This is required for Ultrix 3.1b, not for later versions. Ultrix
+ 3.1b can't just use xm-vaxult2.h because Ultrix 3.1b does define
+ FD_SET. Sure, we could have separate configurations for vaxult2,
+ vaxult3, and vaxult, but why bother? Defining the ptrace constants
+ in infptrace.c isn't going to do any harm; it's not like they are
+ going to change. */
+#define NO_PTRACE_H
diff --git a/gdb/config/vax/xm-vaxult2.h b/gdb/config/vax/xm-vaxult2.h
new file mode 100644
index 00000000000..a46669830cd
--- /dev/null
+++ b/gdb/config/vax/xm-vaxult2.h
@@ -0,0 +1,9 @@
+/* Definitions to make GDB run on a vax under Ultrix. */
+
+#include "vax/xm-vax.h"
+#define NO_PTRACE_H
+
+/* Old versions of ultrix have fd_set but not the FD_* macros. */
+
+#define FD_SET(bit,fdsetp) ((fdsetp)->fds_bits[(n) / 32] |= (1 << ((n) % 32)))
+#define FD_ZERO(fdsetp) memset (fdsetp, 0, sizeof (*fdsetp))
diff --git a/gdb/config/xm-aix4.h b/gdb/config/xm-aix4.h
new file mode 100644
index 00000000000..bea086a371b
--- /dev/null
+++ b/gdb/config/xm-aix4.h
@@ -0,0 +1,91 @@
+/* Parameters for hosting on an PowerPC, for GDB, the GNU debugger.
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Corporation.
+
+ 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. */
+
+/* The following text is taken from config/rs6000.mh:
+ * # The IBM version of /usr/include/rpc/rpc.h has a bug -- it says
+ * # `extern fd_set svc_fdset;' without ever defining the type fd_set.
+ * # Unfortunately this occurs in the vx-share code, which is not configured
+ * # like the rest of GDB (e.g. it doesn't include "defs.h").
+ * # We circumvent this bug by #define-ing fd_set here, but undefining it in
+ * # the xm-rs6000.h file before ordinary modules try to use it. FIXME, IBM!
+ * MH_CFLAGS='-Dfd_set=int'
+ * So, here we do the undefine...which has to occur before we include
+ * <sys/select.h> below.
+ */
+#undef fd_set
+
+#include <sys/select.h>
+
+/* At least as of AIX 3.2, we have termios. */
+#define HAVE_TERMIOS 1
+/* #define HAVE_TERMIO 1 */
+
+#define USG 1
+
+#define FIVE_ARG_PTRACE
+
+/* This system requires that we open a terminal with O_NOCTTY for it to
+ not become our controlling terminal. */
+
+#define USE_O_NOCTTY
+
+/* Brain death inherited from PC's pervades. */
+#undef NULL
+#define NULL 0
+
+/* The IBM compiler requires this in order to properly compile alloca(). */
+#pragma alloca
+
+/* There is no vfork. */
+
+#define vfork fork
+
+char *termdef ();
+
+/* Signal handler for SIGWINCH `window size changed'. */
+
+#define SIGWINCH_HANDLER aix_resizewindow
+extern void aix_resizewindow (int);
+
+/* `lines_per_page' and `chars_per_line' are local to utils.c. Rectify this. */
+
+#define SIGWINCH_HANDLER_BODY \
+ \
+/* Respond to SIGWINCH `window size changed' signal, and reset GDB's \
+ window settings appropriately. */ \
+ \
+void \
+aix_resizewindow (signo) \
+ int signo; \
+{ \
+ int fd = fileno (stdout); \
+ if (isatty (fd)) { \
+ int val; \
+ \
+ val = atoi (termdef (fd, 'l')); \
+ if (val > 0) \
+ lines_per_page = val; \
+ val = atoi (termdef (fd, 'c')); \
+ if (val > 0) \
+ chars_per_line = val; \
+ } \
+}
diff --git a/gdb/config/xm-nbsd.h b/gdb/config/xm-nbsd.h
new file mode 100644
index 00000000000..c8d00f6dd63
--- /dev/null
+++ b/gdb/config/xm-nbsd.h
@@ -0,0 +1,26 @@
+/* Host-dependent definitions for any CPU running NetBSD.
+ Copyright 1993, 1994, 1995, 1996, 1999 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 this to get things like NGROUPS which <limits.h> doesn't
+ define on some systems. */
+#include <sys/param.h>
+
+/* NetBSD has termios facilities. */
+#define HAVE_TERMIOS
diff --git a/gdb/config/xm-sysv4.h b/gdb/config/xm-sysv4.h
new file mode 100644
index 00000000000..614d4032772
--- /dev/null
+++ b/gdb/config/xm-sysv4.h
@@ -0,0 +1,29 @@
+/* Definitions for running gdb on a host machine running any flavor of SVR4.
+ Copyright 1991, 1992, 1993, 1995, 1998 Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus Support (fnf@cygnus.com).
+
+ 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. */
+
+/* SVR4 has termios facilities. */
+
+#undef HAVE_TERMIO
+#define HAVE_TERMIOS
+
+/* SVR4 is a derivative of System V Release 3 (USG) */
+
+#define USG
diff --git a/gdb/config/xstormy16/xstormy16.mt b/gdb/config/xstormy16/xstormy16.mt
new file mode 100644
index 00000000000..c4b57514f85
--- /dev/null
+++ b/gdb/config/xstormy16/xstormy16.mt
@@ -0,0 +1,5 @@
+# Target: Sanyo Xstormy16a processor
+TDEPFILES = xstormy16-tdep.o
+# No simulator objects or libraries are needed -- target uses SID.
+# SIM_OBS = remote-sim.o
+# SIM = ../sim/xstormy16/libsim.a
diff --git a/gdb/config/z8k/tm-z8k.h b/gdb/config/z8k/tm-z8k.h
new file mode 100644
index 00000000000..44058554627
--- /dev/null
+++ b/gdb/config/z8k/tm-z8k.h
@@ -0,0 +1,287 @@
+/* Parameters for execution on a z8000 series machine.
+ Copyright 1992, 1993, 1994, 1998, 1999, 2000, 2001
+ 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. */
+
+#undef TARGET_INT_BIT
+#undef TARGET_LONG_BIT
+#undef TARGET_SHORT_BIT
+#undef TARGET_PTR_BIT
+
+#define TARGET_SHORT_BIT 16
+#define TARGET_INT_BIT 16
+#define TARGET_LONG_BIT 32
+#define TARGET_PTR_BIT (BIG ? 32: 16)
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code. */
+
+#define SKIP_PROLOGUE(ip) (z8k_skip_prologue (ip))
+extern CORE_ADDR z8k_skip_prologue (CORE_ADDR ip);
+
+
+/* Immediately after a function call, return the saved pc.
+ Can't always go through the frames for this because on some machines
+ the new frame is not set up until the new function executes
+ some instructions. */
+
+
+extern int z8k_saved_pc_after_call (struct frame_info *frame);
+#define SAVED_PC_AFTER_CALL(frame) z8k_saved_pc_after_call(frame)
+
+/* Stack grows downward. */
+
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+/* Sequence of bytes for breakpoint instruction. */
+
+#define BREAKPOINT {0x36,0x00}
+
+/* If your kernel resets the pc after the trap happens you may need to
+ define this before including this file. */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Say how long registers are. */
+
+#define REGISTER_TYPE unsigned int
+
+#define NUM_REGS 23 /* 16 registers + 1 ccr + 1 pc + 3 debug
+ regs + fake fp + fake sp */
+#define REGISTER_BYTES (NUM_REGS *4)
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#define REGISTER_BYTE(N) ((N)*4)
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. On the z8k, all but the pc are 2 bytes, but we
+ keep them all as 4 bytes and trim them on I/O */
+
+
+#define REGISTER_RAW_SIZE(N) (((N) < 16)? 2:4)
+
+/* Number of bytes of storage in the program's representation
+ for register N. */
+
+#define REGISTER_VIRTUAL_SIZE(N) REGISTER_RAW_SIZE(N)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#define MAX_REGISTER_RAW_SIZE 4
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 4
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+ (REGISTER_VIRTUAL_SIZE(N) == 2? builtin_type_unsigned_int : builtin_type_long)
+
+/*#define INIT_FRAME_PC(x,y) init_frame_pc(x,y) */
+/* Initializer for an array of names of registers.
+ Entries beyond the first NUM_REGS are ignored. */
+
+#define REGISTER_NAMES \
+ {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
+ "ccr", "pc", "cycles","insts","time","fp","sp"}
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define CCR_REGNUM 16 /* Contains processor status */
+#define PC_REGNUM 17 /* Contains program counter */
+#define CYCLES_REGNUM 18
+#define INSTS_REGNUM 19
+#define TIME_REGNUM 20
+#define FP_REGNUM 21 /* Contains fp, whatever memory model */
+#define SP_REGNUM 22 /* Conatins sp, whatever memory model */
+
+
+
+#define PTR_SIZE (BIG ? 4: 2)
+#define PTR_MASK (BIG ? 0xff00ffff : 0x0000ffff)
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. This is assuming that floating point values are returned
+ as doubles in d0/d1. */
+
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ memcpy(VALBUF, REGBUF + REGISTER_BYTE(2), TYPE_LENGTH(TYPE));
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format. */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(CORE_ADDR *)(REGBUF))
+
+/* Describe the pointer in each stack frame to the previous stack frame
+ (its caller). */
+
+/* FRAME_CHAIN takes a frame's nominal address and produces the frame's
+ chain-pointer.
+ In the case of the Z8000, the frame's nominal address
+ is the address of a ptr sized byte word containing the calling
+ frame's address. */
+
+extern CORE_ADDR z8k_frame_chain (struct frame_info *thisframe);
+#define FRAME_CHAIN(thisframe) z8k_frame_chain(thisframe);
+
+
+
+/* Define other aspects of the stack frame. */
+
+/* A macro that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. If it
+ does not, FRAMELESS is set to 1, else 0. */
+#define FRAMELESS_FUNCTION_INVOCATION(FI) \
+ (frameless_look_for_prologue (FI))
+
+extern CORE_ADDR z8k_frame_saved_pc (struct frame_info *frame);
+#define FRAME_SAVED_PC(FRAME) z8k_frame_saved_pc(FRAME)
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Set VAL to the number of args passed to frame described by FI.
+ Can set VAL to -1, meaning no way to tell. */
+
+/* We can't tell how many args there are
+ now that the C compiler delays popping them. */
+#if !defined (FRAME_NUM_ARGS)
+#define FRAME_NUM_ARGS(fi) (-1)
+#endif
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#define FRAME_ARGS_SKIP 8
+
+struct frame_info;
+extern void z8k_frame_init_saved_regs (struct frame_info *);
+#define FRAME_INIT_SAVED_REGS(fi) z8k_frame_init_saved_regs (fi)
+
+
+/* Things needed for making the inferior call functions.
+ It seems like every m68k based machine has almost identical definitions
+ in the individual machine's configuration files. Most other cpu types
+ (mips, i386, etc) have routines in their *-tdep.c files to handle this
+ for most configurations. The m68k family should be able to do this as
+ well. These macros can still be overridden when necessary. */
+
+/* The CALL_DUMMY macro is the sequence of instructions, as disassembled
+ by gdb itself:
+
+ fmovemx fp0-fp7,sp@- 0xf227 0xe0ff
+ moveml d0-a5,sp@- 0x48e7 0xfffc
+ clrw sp@- 0x4267
+ movew ccr,sp@- 0x42e7
+
+ /..* The arguments are pushed at this point by GDB;
+ no code is needed in the dummy for this.
+ The CALL_DUMMY_START_OFFSET gives the position of
+ the following jsr instruction. *../
+
+ jsr @#0x32323232 0x4eb9 0x3232 0x3232
+ addal #0x69696969,sp 0xdffc 0x6969 0x6969
+ trap #<your BPT_VECTOR number here> 0x4e4?
+ nop 0x4e71
+
+ Note this is CALL_DUMMY_LENGTH bytes (28 for the above example).
+ We actually start executing at the jsr, since the pushing of the
+ registers is done by PUSH_DUMMY_FRAME. If this were real code,
+ the arguments for the function called by the jsr would be pushed
+ between the moveml and the jsr, and we could allow it to execute through.
+ But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is
+ done, and we cannot allow the moveml to push the registers again lest
+ they be taken for the arguments. */
+
+
+#define CALL_DUMMY { 0 }
+#define CALL_DUMMY_LENGTH 24 /* Size of CALL_DUMMY */
+#define CALL_DUMMY_START_OFFSET 8 /* Offset to jsr instruction */
+
+
+/* Insert the specified number of args and function address
+ into a call sequence of the above form stored at DUMMYNAME.
+ We use the BFD routines to store a big-endian value of known size. */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \
+{ bfd_putb32 (fun, (char *) dummyname + CALL_DUMMY_START_OFFSET + 2); \
+ bfd_putb32 (nargs*4, (char *) dummyname + CALL_DUMMY_START_OFFSET + 8); }
+
+/* Push an empty stack frame, to record the current PC, etc. */
+
+#define PUSH_DUMMY_FRAME { z8k_push_dummy_frame (); }
+
+extern void z8k_push_dummy_frame (void);
+
+extern void z8k_pop_frame (void);
+
+/* Discard from the stack the innermost frame, restoring all registers. */
+
+#define POP_FRAME { z8k_pop_frame (); }
+
+/* Offset from SP to first arg on stack at first instruction of a function */
+
+#define SP_ARG0 (1 * 4)
+
+extern CORE_ADDR z8k_addr_bits_remove (CORE_ADDR);
+#define ADDR_BITS_REMOVE(addr) z8k_addr_bits_remove (addr)
+int sim_z8001_mode;
+#define BIG (sim_z8001_mode)
+
+#define read_memory_short(x) (read_memory_integer(x,2) & 0xffff)
+
+#define NO_STD_REGS
+
+extern void z8k_print_register_hook (int regno);
+#define PRINT_REGISTER_HOOK(regno) z8k_print_register_hook(regno)
+
+
+extern void z8k_set_pointer_size (int newsize);
+#define INIT_EXTRA_SYMTAB_INFO \
+ z8k_set_pointer_size(objfile->obfd->arch_info->bits_per_address);
+
+#define REGISTER_SIZE 4
diff --git a/gdb/config/z8k/z8k.mt b/gdb/config/z8k/z8k.mt
new file mode 100644
index 00000000000..cb8d04376e7
--- /dev/null
+++ b/gdb/config/z8k/z8k.mt
@@ -0,0 +1,7 @@
+# Target: Z8000 with simulator
+TDEPFILES= z8k-tdep.o
+TM_FILE= tm-z8k.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/z8k/libsim.a
+
diff --git a/gdb/configure b/gdb/configure
new file mode 100755
index 00000000000..d8493a9f21d
--- /dev/null
+++ b/gdb/configure
@@ -0,0 +1,9468 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer"
+ac_help="$ac_help
+ --disable-nls do not use Native Language Support"
+ac_help="$ac_help
+ --with-included-gettext use the GNU gettext library included here"
+ac_help="$ac_help
+ --enable-multi-ice Build the multi-ice-gdb-server"
+ac_help="$ac_help
+ --enable-gdbcli Enable GDB-CLI interface"
+ac_help="$ac_help
+ --enable-gdbmi Enable GDB-MI interface"
+ac_help="$ac_help
+ --with-uiout Use new uiout functions instead of *printf's"
+ac_help="$ac_help
+ --enable-tui Enable full-screen terminal user interface"
+ac_help="$ac_help
+ --enable-netrom Enable NetROM support"
+ac_help="$ac_help
+ --enable-build-warnings Enable build-time compiler warnings if gcc is used"
+ac_help="$ac_help
+ --enable-gdb-build-warnings Enable GDB specific build-time compiler warnings if gcc is used"
+ac_help="$ac_help
+ --with-mmalloc Use memory mapped malloc package"
+ac_help="$ac_help
+ --with-included-regex Use included regex"
+ac_help="$ac_help
+ --with-cpu=CPU Set the default CPU variant to debug"
+ac_help="$ac_help
+ --enable-gdbtk Enable GDBTK GUI front end"
+ac_help="$ac_help
+ --with-tclconfig=DIR Directory containing tcl configuration (tclConfig.sh)"
+ac_help="$ac_help
+ --with-tkconfig=DIR Directory containing tk configuration (tkConfig.sh)"
+ac_help="$ac_help
+ --with-tclinclude=DIR Directory where tcl private headers are"
+ac_help="$ac_help
+ --with-tkinclude=DIR Directory where tk private headers are"
+ac_help="$ac_help
+ --with-itclconfig Directory containing itcl configuration (itclConfig.sh)"
+ac_help="$ac_help
+ --with-itkconfig Directory containing itk configuration (itkConfig.sh)"
+ac_help="$ac_help
+ --with-tixconfig Directory containing tix configuration (tixConfig.sh)"
+ac_help="$ac_help
+ --with-x use the X Window System"
+ac_help="$ac_help
+ --enable-sim Link gdb with simulator"
+ac_help="$ac_help
+ --enable-shared Use shared libraries"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=main.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:578: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:604: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:634: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:685: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:717: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 728 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:733: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:759: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:764: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:773: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+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
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:792: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:824: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 839 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:845: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 856 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:862: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 873 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:879: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for AIX""... $ac_c" 1>&6
+echo "configure:904: checking for AIX" >&5
+cat > conftest.$ac_ext <<EOF
+#line 906 "configure"
+#include "confdefs.h"
+#ifdef _AIX
+ yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&6; cat >> confdefs.h <<\EOF
+#define _ALL_SOURCE 1
+EOF
+
+else
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+
+
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:928: checking for POSIXized ISC" >&5
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&6
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&6
+ ISC=
+fi
+
+
+
+
+echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6
+echo "configure:952: checking for ${CC-cc} option to accept ANSI C" >&5
+if eval "test \"`echo '$''{'am_cv_prog_cc_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ cat > conftest.$ac_ext <<EOF
+#line 969 "configure"
+#include "confdefs.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+
+int main() {
+
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+
+; return 0; }
+EOF
+if { (eval echo configure:1006: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ am_cv_prog_cc_stdc="$ac_arg"; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+CC="$ac_save_CC"
+
+fi
+
+if test -z "$am_cv_prog_cc_stdc"; then
+ echo "$ac_t""none needed" 1>&6
+else
+ echo "$ac_t""$am_cv_prog_cc_stdc" 1>&6
+fi
+case "x$am_cv_prog_cc_stdc" in
+ x|xno) ;;
+ *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/.. $srcdir/`cd $srcdir;pwd`/..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/.. $srcdir/`cd $srcdir;pwd`/.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:1077: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:1098: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:1116: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+ALL_LINGUAS=
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:1141: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1170: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1198: checking for ANSI C header files" >&5
+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 1203 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1211: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+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 1228 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+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 1246 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1267 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1278: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1302: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1307 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1356: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:1377: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 1384 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:1391: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:1417: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1422 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_off_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+ cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:1450: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1455 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:1485: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1490 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:1497: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:1518: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1523 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:1551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:1583: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1588 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1613: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1618 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1641: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:1668: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1676 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:1695: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1720: checking for $ac_hdr" >&5
+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 1725 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1730: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+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 | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1759: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1764 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1787: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:1812: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1820 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:1960: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+
+ for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1988: checking for $ac_hdr" >&5
+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 1993 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1998: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+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 | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2028: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2033 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2056: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ for ac_func in stpcpy
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2085: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2090 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2113: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STPCPY 1
+EOF
+
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
+echo "configure:2147: checking for LC_MESSAGES" >&5
+if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2152 "configure"
+#include "confdefs.h"
+#include <locale.h>
+int main() {
+return LC_MESSAGES
+; return 0; }
+EOF
+if { (eval echo configure:2159: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LC_MESSAGES 1
+EOF
+
+ fi
+ fi
+ echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
+echo "configure:2180: checking whether NLS is requested" >&5
+ # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi
+
+ echo "$ac_t""$USE_NLS" 1>&6
+
+
+ USE_INCLUDED_LIBINTL=no
+
+ if test "$USE_NLS" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define ENABLE_NLS 1
+EOF
+
+ echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
+echo "configure:2200: checking whether included gettext is requested" >&5
+ # Check whether --with-included-gettext or --without-included-gettext was given.
+if test "${with_included_gettext+set}" = set; then
+ withval="$with_included_gettext"
+ nls_cv_force_use_gnu_gettext=$withval
+else
+ nls_cv_force_use_gnu_gettext=no
+fi
+
+ echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
+echo "configure:2219: checking for libintl.h" >&5
+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 2224 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2229: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
+echo "configure:2246: checking for gettext in libc" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2251 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:2258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
+echo "configure:2274: checking for bindtextdomain in -lintl" >&5
+ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__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="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2282 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char bindtextdomain();
+
+int main() {
+bindtextdomain()
+; return 0; }
+EOF
+if { (eval echo configure:2293: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
+echo "configure:2309: checking for gettext in libintl" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2314 "configure"
+#include "confdefs.h"
+
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:2321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GETTEXT 1
+EOF
+
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2349: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ if test "$MSGFMT" != "no"; then
+ for ac_func in dcgettext
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2383: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2388 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2411: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2438: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2474: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ cat > conftest.$ac_ext <<EOF
+#line 2506 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr
+; return 0; }
+EOF
+if { (eval echo configure:2514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ CATOBJEXT=.gmo
+ DATADIRNAME=share
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CATOBJEXT=.mo
+ DATADIRNAME=lib
+fi
+rm -f conftest*
+ INSTOBJEXT=.mo
+ fi
+ fi
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+ if test "$CATOBJEXT" = "NONE"; then
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ INTLOBJS="\$(GETTOBJS)"
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2546: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2580: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2616: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ echo "$ac_t""found xgettext programs is not GNU xgettext; ignore it" 1>&6
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
+echo "configure:2706: checking for catalogs to be installed" >&5
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ echo "$ac_t""$LINGUAS" 1>&6
+ fi
+
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+
+
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
+echo "configure:2734: checking for linux/version.h" >&5
+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 2739 "configure"
+#include "confdefs.h"
+#include <linux/version.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2744: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ msgformat=linux
+else
+ echo "$ac_t""no" 1>&6
+msgformat=xopen
+fi
+
+
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+
+
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+
+
+ l=
+
+
+ if test -f $srcdir/po/POTFILES.in; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+
+
+
+CONFIG_OBS=
+CONFIG_LIB_OBS=
+CONFIG_DEPS=
+CONFIG_SRCS=
+CONFIG_INITS=
+ENABLE_CFLAGS=
+CONFIG_ALL=
+CONFIG_CLEAN=
+CONFIG_INSTALL=
+CONFIG_UNINSTALL=
+
+configdirs="doc testsuite"
+
+# Check whether --enable-multi-ice or --disable-multi-ice was given.
+if test "${enable_multi_ice+set}" = set; then
+ enableval="$enable_multi_ice"
+ case "${enableval}" in
+ yes ) enable_multi_ice="yes" ;;
+ no) enable_multi_ice="no" ;;
+ *) { echo "configure: error: Bad value for --enable-multi-ice: ${enableval}" 1>&2; exit 1; } ;;
+ esac
+
+fi
+
+
+if test "${enable_multi_ice}" = "yes"; then
+ configdirs="${configdirs} multi-ice"
+fi
+
+
+. ${srcdir}/configure.host
+
+. ${srcdir}/configure.tgt
+
+targ=${target} ; . ${srcdir}/../bfd/config.bfd
+
+
+targ=${target}
+. ${srcdir}/../bfd/config.bfd
+
+targ_archs=`echo ${targ_archs} | sed -e 's/ .*//;'`
+
+if test x"${targ_archs}" != x ; then
+ cat >> confdefs.h <<EOF
+#define DEFAULT_BFD_ARCH ${targ_archs}
+EOF
+
+fi
+if test x"${targ_defvec}" != x ; then
+ cat >> confdefs.h <<EOF
+#define DEFAULT_BFD_VEC ${targ_defvec}
+EOF
+
+fi
+
+for ac_prog in mawk gawk nawk awk
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2867: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AWK="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+AWK="$ac_cv_prog_AWK"
+if test -n "$AWK"; then
+ echo "$ac_t""$AWK" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AWK" && break
+done
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:2908: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ 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
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+if test $host != $build; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2969: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar"
+fi
+fi
+AR="$ac_cv_prog_AR"
+if test -n "$AR"; then
+ echo "$ac_t""$AR" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3001: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_RANLIB"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3033: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ RANLIB=":"
+fi
+fi
+
+# Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3068: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_DLLTOOL" && ac_cv_prog_DLLTOOL="dlltool"
+fi
+fi
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+ echo "$ac_t""$DLLTOOL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+# Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args.
+set dummy ${ac_tool_prefix}windres; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3100: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_WINDRES'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$WINDRES"; then
+ ac_cv_prog_WINDRES="$WINDRES" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_WINDRES="${ac_tool_prefix}windres"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_WINDRES" && ac_cv_prog_WINDRES="windres"
+fi
+fi
+WINDRES="$ac_cv_prog_WINDRES"
+if test -n "$WINDRES"; then
+ echo "$ac_t""$WINDRES" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+for ac_prog in 'bison -y' byacc
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3134: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_YACC="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+YACC="$ac_cv_prog_YACC"
+if test -n "$YACC"; then
+ echo "$ac_t""$YACC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+
+# Extract the first word of "${ac_tool_prefix}mig", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mig; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3168: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_MIG'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$MIG"; then
+ ac_cv_prog_MIG="$MIG" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_MIG="${ac_tool_prefix}mig"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_MIG" && ac_cv_prog_MIG="mig"
+fi
+fi
+MIG="$ac_cv_prog_MIG"
+if test -n "$MIG"; then
+ echo "$ac_t""$MIG" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:3219: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3224 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:3241: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_signal=void
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:3261: checking for ANSI C header files" >&5
+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 3266 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3274: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+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 3291 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+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 3309 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3330 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:3341: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+
+
+case $host_os in solaris2.7 | solaris2.8) case "$GCC" in yes)
+ cat >> confdefs.h <<\EOF
+#define _MSE_INT_H 1
+EOF
+
+esac; esac
+
+for ac_hdr in ctype.h nlist.h link.h thread_db.h proc_service.h \
+ memory.h objlist.h ptrace.h sgtty.h stddef.h stdlib.h \
+ string.h sys/procfs.h sys/ptrace.h sys/reg.h stdint.h \
+ term.h termio.h termios.h unistd.h wait.h sys/wait.h \
+ wchar.h wctype.h asm/debugreg.h sys/debugreg.h sys/select.h \
+ time.h sys/file.h sys/ioctl.h sys/user.h sys/fault.h sys/syscall.h \
+ dirent.h sys/ndir.h sys/dir.h ndir.h sys/filio.h \
+ curses.h ncurses.h \
+ poll.h sys/poll.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3385: checking for $ac_hdr" >&5
+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 3390 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3395: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+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 | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
+echo "configure:3422: checking whether stat file-mode macros are broken" >&5
+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 3427 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined(S_ISBLK) && defined(S_IFDIR)
+# if S_ISBLK (S_IFDIR)
+You lose.
+# endif
+#endif
+
+#if defined(S_ISBLK) && defined(S_IFCHR)
+# if S_ISBLK (S_IFCHR)
+You lose.
+# endif
+#endif
+
+#if defined(S_ISLNK) && defined(S_IFREG)
+# if S_ISLNK (S_IFREG)
+You lose.
+# endif
+#endif
+
+#if defined(S_ISSOCK) && defined(S_IFREG)
+# if S_ISSOCK (S_IFREG)
+You lose.
+# endif
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "You lose" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_header_stat_broken=yes
+else
+ rm -rf conftest*
+ ac_cv_header_stat_broken=no
+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
+#define STAT_MACROS_BROKEN 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:3479: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3484 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:3533: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:3554: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 3561 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:3568: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+
+for ac_func in bcopy btowc bzero canonicalize_file_name isascii poll \
+ realpath sbrk setpgid setpgrp sigaction sigprocmask sigsetmask
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3598: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3603 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3626: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:3653: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3658 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:3665: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:3686: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3691 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:3719: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:3751: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3756 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3781: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3786 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3809: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:3836: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3844 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:3863: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+echo $ac_n "checking for pid_t""... $ac_c" 1>&6
+echo "configure:3885: checking for pid_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3890 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_pid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_pid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_pid_t" 1>&6
+if test $ac_cv_type_pid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define pid_t int
+EOF
+
+fi
+
+ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for vfork.h""... $ac_c" 1>&6
+echo "configure:3919: checking for vfork.h" >&5
+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 3924 "configure"
+#include "confdefs.h"
+#include <vfork.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3929: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_VFORK_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for working vfork""... $ac_c" 1>&6
+echo "configure:3954: checking for working vfork" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ echo $ac_n "checking for vfork""... $ac_c" 1>&6
+echo "configure:3960: checking for vfork" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3965 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char vfork(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char vfork();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_vfork) || defined (__stub___vfork)
+choke me
+#else
+vfork();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3988: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_vfork=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_vfork=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'vfork`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_cv_func_vfork_works=$ac_cv_func_vfork
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4010 "configure"
+#include "confdefs.h"
+/* Thanks to Paul Eggert for this test. */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_VFORK_H
+#include <vfork.h>
+#endif
+/* On some sparc systems, changes by the child to local and incoming
+ argument registers are propagated back to the parent.
+ The compiler is told about this with #include <vfork.h>,
+ but some compilers (e.g. gcc -O) don't grok <vfork.h>.
+ Test for this by using a static variable whose address
+ is put into a register that is clobbered by the vfork. */
+static
+#ifdef __cplusplus
+sparc_address_test (int arg)
+#else
+sparc_address_test (arg) int arg;
+#endif
+{
+ static pid_t child;
+ if (!child) {
+ child = vfork ();
+ if (child < 0) {
+ perror ("vfork");
+ _exit(2);
+ }
+ if (!child) {
+ arg = getpid();
+ write(-1, "", 0);
+ _exit (arg);
+ }
+ }
+}
+main() {
+ pid_t parent = getpid ();
+ pid_t child;
+
+ sparc_address_test ();
+
+ child = vfork ();
+
+ if (child == 0) {
+ /* Here is another test for sparc vfork register problems.
+ This test uses lots of local variables, at least
+ as many local variables as main has allocated so far
+ including compiler temporaries. 4 locals are enough for
+ gcc 1.40.3 on a Solaris 4.1.3 sparc, but we use 8 to be safe.
+ A buggy compiler should reuse the register of parent
+ for one of the local variables, since it will think that
+ parent can't possibly be used any more in this routine.
+ Assigning to the local variable will thus munge parent
+ in the parent process. */
+ pid_t
+ p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+ p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+ /* Convince the compiler that p..p7 are live; otherwise, it might
+ use the same hardware register for all 8 local variables. */
+ if (p != p1 || p != p2 || p != p3 || p != p4
+ || p != p5 || p != p6 || p != p7)
+ _exit(1);
+
+ /* On some systems (e.g. IRIX 3.3),
+ vfork doesn't separate parent from child file descriptors.
+ If the child closes a descriptor before it execs or exits,
+ this munges the parent's descriptor as well.
+ Test for this by closing stdout in the child. */
+ _exit(close(fileno(stdout)) != 0);
+ } else {
+ int status;
+ struct stat st;
+
+ while (wait(&status) != child)
+ ;
+ exit(
+ /* Was there some problem with vforking? */
+ child < 0
+
+ /* Did the child fail? (This shouldn't happen.) */
+ || status
+
+ /* Did the vfork/compiler bug occur? */
+ || parent != getpid()
+
+ /* Did the file descriptor bug occur? */
+ || fstat(fileno(stdout), &st) != 0
+ );
+ }
+}
+EOF
+if { (eval echo configure:4105: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_vfork_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_vfork_works=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_vfork_works" 1>&6
+if test $ac_cv_func_vfork_works = no; then
+ cat >> confdefs.h <<\EOF
+#define vfork fork
+EOF
+
+fi
+
+if test "$cross_compiling" = no; then
+ echo $ac_n "checking whether setpgrp takes no argument""... $ac_c" 1>&6
+echo "configure:4129: checking whether setpgrp takes no argument" >&5
+if eval "test \"`echo '$''{'ac_cv_func_setpgrp_void'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: cannot check setpgrp if cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4137 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/*
+ * If this system has a BSD-style setpgrp, which takes arguments, exit
+ * successfully.
+ */
+main()
+{
+ if (setpgrp(1,1) == -1)
+ exit(0);
+ else
+ exit(1);
+}
+
+EOF
+if { (eval echo configure:4157: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_setpgrp_void=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_setpgrp_void=yes
+fi
+rm -fr conftest*
+fi
+
+
+fi
+
+echo "$ac_t""$ac_cv_func_setpgrp_void" 1>&6
+if test $ac_cv_func_setpgrp_void = yes; then
+ cat >> confdefs.h <<\EOF
+#define SETPGRP_VOID 1
+EOF
+
+fi
+
+else
+ echo $ac_n "checking whether setpgrp takes no argument""... $ac_c" 1>&6
+echo "configure:4182: checking whether setpgrp takes no argument" >&5
+if eval "test \"`echo '$''{'ac_cv_func_setpgrp_void'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4187 "configure"
+#include "confdefs.h"
+
+#include <unistd.h>
+
+int main() {
+
+ if (setpgrp(1,1) == -1)
+ exit (0);
+ else
+ exit (1);
+
+; return 0; }
+EOF
+if { (eval echo configure:4201: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_func_setpgrp_void=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_setpgrp_void=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_setpgrp_void" 1>&6
+if test $ac_cv_func_setpgrp_void = yes; then
+ cat >> confdefs.h <<\EOF
+#define SETPGRP_VOID 1
+EOF
+
+fi
+fi
+
+# Check if sigsetjmp is available. Using AC_CHECK_FUNCS won't do
+# since sigsetjmp might only be defined as a macro.
+echo $ac_n "checking for sigsetjmp""... $ac_c" 1>&6
+echo "configure:4225: checking for sigsetjmp" >&5
+if eval "test \"`echo '$''{'gdb_cv_func_sigsetjmp'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4230 "configure"
+#include "confdefs.h"
+
+#include <setjmp.h>
+
+int main() {
+sigjmp_buf env; while (! sigsetjmp (env, 1)) siglongjmp (env, 1);
+; return 0; }
+EOF
+if { (eval echo configure:4239: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_func_sigsetjmp=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_func_sigsetjmp=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gdb_cv_func_sigsetjmp" 1>&6
+if test $gdb_cv_func_sigsetjmp = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SIGSETJMP 1
+EOF
+
+fi
+
+# See if <machine/reg.h> supports the %fs and %gs i386 segment registers.
+# Older i386 BSD's don't have the r_fs and r_gs members of `struct reg'.
+echo $ac_n "checking for r_fs in struct reg""... $ac_c" 1>&6
+echo "configure:4262: checking for r_fs in struct reg" >&5
+if eval "test \"`echo '$''{'gdb_cv_struct_reg_r_fs'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4267 "configure"
+#include "confdefs.h"
+#include <machine/reg.h>
+int main() {
+struct reg r; r.r_fs;
+; return 0; }
+EOF
+if { (eval echo configure:4274: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_struct_reg_r_fs=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_struct_reg_r_fs=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gdb_cv_struct_reg_r_fs" 1>&6
+if test $gdb_cv_struct_reg_r_fs = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_REG_R_FS 1
+EOF
+
+fi
+echo $ac_n "checking for r_gs in struct reg""... $ac_c" 1>&6
+echo "configure:4294: checking for r_gs in struct reg" >&5
+if eval "test \"`echo '$''{'gdb_cv_struct_reg_r_gs'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4299 "configure"
+#include "confdefs.h"
+#include <machine/reg.h>
+int main() {
+struct reg r; r.r_gs;
+; return 0; }
+EOF
+if { (eval echo configure:4306: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_struct_reg_r_gs=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_struct_reg_r_gs=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gdb_cv_struct_reg_r_gs" 1>&6
+if test $gdb_cv_struct_reg_r_gs = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_REG_R_GS 1
+EOF
+
+fi
+
+# See if <sys/ptrace.h> provides the PTRACE_GETREGS request.
+echo $ac_n "checking for PTRACE_GETREGS""... $ac_c" 1>&6
+echo "configure:4328: checking for PTRACE_GETREGS" >&5
+if eval "test \"`echo '$''{'gdb_cv_have_ptrace_getregs'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4333 "configure"
+#include "confdefs.h"
+#include <sys/ptrace.h>
+int main() {
+PTRACE_GETREGS;
+; return 0; }
+EOF
+if { (eval echo configure:4340: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_have_ptrace_getregs=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_have_ptrace_getregs=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gdb_cv_have_ptrace_getregs" 1>&6
+if test $gdb_cv_have_ptrace_getregs = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PTRACE_GETREGS 1
+EOF
+
+fi
+
+# See if <sys/ptrace.h> provides the PTRACE_GETFPXREGS request.
+echo $ac_n "checking for PTRACE_GETFPXREGS""... $ac_c" 1>&6
+echo "configure:4362: checking for PTRACE_GETFPXREGS" >&5
+if eval "test \"`echo '$''{'gdb_cv_have_ptrace_getfpxregs'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4367 "configure"
+#include "confdefs.h"
+#include <sys/ptrace.h>
+int main() {
+PTRACE_GETFPXREGS;
+; return 0; }
+EOF
+if { (eval echo configure:4374: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_have_ptrace_getfpxregs=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_have_ptrace_getfpxregs=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gdb_cv_have_ptrace_getfpxregs" 1>&6
+if test $gdb_cv_have_ptrace_getfpxregs = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PTRACE_GETFPXREGS 1
+EOF
+
+fi
+
+# See if <sys/ptrace.h> provides the PT_GETDBREGS request.
+echo $ac_n "checking for PT_GETDBREGS""... $ac_c" 1>&6
+echo "configure:4396: checking for PT_GETDBREGS" >&5
+if eval "test \"`echo '$''{'gdb_cv_have_pt_getdbregs'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4401 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/ptrace.h>
+int main() {
+PT_GETDBREGS;
+; return 0; }
+EOF
+if { (eval echo configure:4409: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_have_pt_getdbregs=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_have_pt_getdbregs=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gdb_cv_have_pt_getdbregs" 1>&6
+if test $gdb_cv_have_pt_getdbregs = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PT_GETDBREGS 1
+EOF
+
+fi
+
+# See if <sys/ptrace.h> provides the PT_GETXMMREGS request.
+echo $ac_n "checking for PT_GETXMMREGS""... $ac_c" 1>&6
+echo "configure:4431: checking for PT_GETXMMREGS" >&5
+if eval "test \"`echo '$''{'gdb_cv_have_pt_getxmmregs'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4436 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/ptrace.h>
+int main() {
+PT_GETXMMREGS;
+; return 0; }
+EOF
+if { (eval echo configure:4444: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_have_pt_getxmmregs=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_have_pt_getxmmregs=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gdb_cv_have_pt_getxmmregs" 1>&6
+if test $gdb_cv_have_pt_getxmmregs = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PT_GETXMMREGS 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for socketpair in -lsocket""... $ac_c" 1>&6
+echo "configure:4466: checking for socketpair in -lsocket" >&5
+ac_lib_var=`echo socket'_'socketpair | sed 'y%./+-%__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 4474 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char socketpair();
+
+int main() {
+socketpair()
+; return 0; }
+EOF
+if { (eval echo configure:4485: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lsocket $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+for ac_func in socketpair
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:4515: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4520 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4543: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+echo $ac_n "checking whether malloc must be declared""... $ac_c" 1>&6
+echo "configure:4570: checking whether malloc must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_malloc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4575 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) malloc
+; return 0; }
+EOF
+if { (eval echo configure:4596: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_malloc=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_malloc=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_malloc" 1>&6
+if test $bfd_cv_decl_needed_malloc = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_MALLOC 1
+EOF
+
+fi
+
+echo $ac_n "checking whether realloc must be declared""... $ac_c" 1>&6
+echo "configure:4617: checking whether realloc must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_realloc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4622 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) realloc
+; return 0; }
+EOF
+if { (eval echo configure:4643: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_realloc=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_realloc=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_realloc" 1>&6
+if test $bfd_cv_decl_needed_realloc = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_REALLOC 1
+EOF
+
+fi
+
+echo $ac_n "checking whether free must be declared""... $ac_c" 1>&6
+echo "configure:4664: checking whether free must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_free'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4669 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) free
+; return 0; }
+EOF
+if { (eval echo configure:4690: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_free=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_free=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_free" 1>&6
+if test $bfd_cv_decl_needed_free = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_FREE 1
+EOF
+
+fi
+
+echo $ac_n "checking whether strerror must be declared""... $ac_c" 1>&6
+echo "configure:4711: checking whether strerror must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_strerror'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4716 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) strerror
+; return 0; }
+EOF
+if { (eval echo configure:4737: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_strerror=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_strerror=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_strerror" 1>&6
+if test $bfd_cv_decl_needed_strerror = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_STRERROR 1
+EOF
+
+fi
+
+echo $ac_n "checking whether strdup must be declared""... $ac_c" 1>&6
+echo "configure:4758: checking whether strdup must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_strdup'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4763 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) strdup
+; return 0; }
+EOF
+if { (eval echo configure:4784: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_strdup=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_strdup=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_strdup" 1>&6
+if test $bfd_cv_decl_needed_strdup = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_STRDUP 1
+EOF
+
+fi
+
+echo $ac_n "checking whether strstr must be declared""... $ac_c" 1>&6
+echo "configure:4805: checking whether strstr must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_strstr'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4810 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) strstr
+; return 0; }
+EOF
+if { (eval echo configure:4831: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_strstr=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_strstr=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_strstr" 1>&6
+if test $bfd_cv_decl_needed_strstr = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_STRSTR 1
+EOF
+
+fi
+
+echo $ac_n "checking whether canonicalize_file_name must be declared""... $ac_c" 1>&6
+echo "configure:4852: checking whether canonicalize_file_name must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_canonicalize_file_name'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4857 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) canonicalize_file_name
+; return 0; }
+EOF
+if { (eval echo configure:4878: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_canonicalize_file_name=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_canonicalize_file_name=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_canonicalize_file_name" 1>&6
+if test $bfd_cv_decl_needed_canonicalize_file_name = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_CANONICALIZE_FILE_NAME 1
+EOF
+
+fi
+
+
+# The following save_state_t checkery is only necessary for HPUX
+# versions earlier than 10.20. When those fade from memory, this
+# could be expunged. --jsm 1999-03-22
+
+echo $ac_n "checking for HPUX save_state structure""... $ac_c" 1>&6
+echo "configure:4904: checking for HPUX save_state structure" >&5
+cat > conftest.$ac_ext <<EOF
+#line 4906 "configure"
+#include "confdefs.h"
+#include <machine/save_state.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "save_state_t" >/dev/null 2>&1; then
+ rm -rf conftest*
+ gdb_cv_hpux_savestate=yes
+else
+ rm -rf conftest*
+ gdb_cv_hpux_savestate=no
+fi
+rm -f conftest*
+
+cat > conftest.$ac_ext <<EOF
+#line 4921 "configure"
+#include "confdefs.h"
+#include <machine/save_state.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "ss_wide" >/dev/null 2>&1; then
+ rm -rf conftest*
+ gdb_cv_hpux_sswide=yes
+else
+ rm -rf conftest*
+ gdb_cv_hpux_sswide=no
+fi
+rm -f conftest*
+
+if test $gdb_cv_hpux_savestate = yes
+then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_SAVE_STATE_T 1
+EOF
+
+fi
+if test $gdb_cv_hpux_sswide = yes
+then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_MEMBER_SS_WIDE 1
+EOF
+
+fi
+echo "$ac_t""$gdb_cv_hpux_sswide" 1>&6
+
+
+# If we are configured native on GNU/Linux, work around problems with
+# sys/procfs.h
+# Also detect which type of /proc is in use, such as for Unixware or Solaris.
+
+if test "${target}" = "${host}"; then
+ case "${host}" in
+ i[3456]86-*-linux*)
+ cat >> confdefs.h <<\EOF
+#define START_INFERIOR_TRAPS_EXPECTED 2
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define sys_quotactl 1
+EOF
+
+ ;;
+ ia64-*-aix*)
+ cat >> confdefs.h <<\EOF
+#define NEW_PROC_API 1
+EOF
+
+ ;;
+ *-*-unixware* | *-*-sysv4.2* | *-*-sysv5*)
+ cat >> confdefs.h <<\EOF
+#define NEW_PROC_API 1
+EOF
+
+ ;;
+ *-*-solaris2.[678])
+ cat >> confdefs.h <<\EOF
+#define NEW_PROC_API 1
+EOF
+
+ ;;
+ esac
+fi
+
+if test "$ac_cv_header_sys_procfs_h" = yes; then
+ echo $ac_n "checking for pstatus_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:4991: checking for pstatus_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_pstatus_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4996 "configure"
+#include "confdefs.h"
+
+#define _SYSCALL32
+#include <sys/procfs.h>
+int main() {
+pstatus_t avar
+; return 0; }
+EOF
+if { (eval echo configure:5005: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_pstatus_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_pstatus_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_pstatus_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PSTATUS_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_pstatus_t" 1>&6
+
+ echo $ac_n "checking for prrun_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:5027: checking for prrun_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prrun_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5032 "configure"
+#include "confdefs.h"
+
+#define _SYSCALL32
+#include <sys/procfs.h>
+int main() {
+prrun_t avar
+; return 0; }
+EOF
+if { (eval echo configure:5041: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prrun_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prrun_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_prrun_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PRRUN_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_prrun_t" 1>&6
+
+ echo $ac_n "checking for gregset_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:5063: checking for gregset_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_gregset_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5068 "configure"
+#include "confdefs.h"
+
+#define _SYSCALL32
+#include <sys/procfs.h>
+int main() {
+gregset_t avar
+; return 0; }
+EOF
+if { (eval echo configure:5077: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_gregset_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_gregset_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_gregset_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GREGSET_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_gregset_t" 1>&6
+
+ echo $ac_n "checking for fpregset_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:5099: checking for fpregset_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_fpregset_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5104 "configure"
+#include "confdefs.h"
+
+#define _SYSCALL32
+#include <sys/procfs.h>
+int main() {
+fpregset_t avar
+; return 0; }
+EOF
+if { (eval echo configure:5113: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_fpregset_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_fpregset_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_fpregset_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_FPREGSET_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_fpregset_t" 1>&6
+
+ echo $ac_n "checking for prgregset_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:5135: checking for prgregset_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prgregset_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5140 "configure"
+#include "confdefs.h"
+
+#define _SYSCALL32
+#include <sys/procfs.h>
+int main() {
+prgregset_t avar
+; return 0; }
+EOF
+if { (eval echo configure:5149: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prgregset_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prgregset_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_prgregset_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PRGREGSET_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_prgregset_t" 1>&6
+
+ echo $ac_n "checking for prfpregset_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:5171: checking for prfpregset_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prfpregset_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5176 "configure"
+#include "confdefs.h"
+
+#define _SYSCALL32
+#include <sys/procfs.h>
+int main() {
+prfpregset_t avar
+; return 0; }
+EOF
+if { (eval echo configure:5185: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prfpregset_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prfpregset_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_prfpregset_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PRFPREGSET_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_prfpregset_t" 1>&6
+
+ echo $ac_n "checking for prgregset32_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:5207: checking for prgregset32_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prgregset32_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5212 "configure"
+#include "confdefs.h"
+
+#define _SYSCALL32
+#include <sys/procfs.h>
+int main() {
+prgregset32_t avar
+; return 0; }
+EOF
+if { (eval echo configure:5221: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prgregset32_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prgregset32_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_prgregset32_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PRGREGSET32_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_prgregset32_t" 1>&6
+
+ echo $ac_n "checking for prfpregset32_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:5243: checking for prfpregset32_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prfpregset32_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5248 "configure"
+#include "confdefs.h"
+
+#define _SYSCALL32
+#include <sys/procfs.h>
+int main() {
+prfpregset32_t avar
+; return 0; }
+EOF
+if { (eval echo configure:5257: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prfpregset32_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prfpregset32_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_prfpregset32_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PRFPREGSET32_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_prfpregset32_t" 1>&6
+
+ echo $ac_n "checking for lwpid_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:5279: checking for lwpid_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_lwpid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5284 "configure"
+#include "confdefs.h"
+
+#define _SYSCALL32
+#include <sys/procfs.h>
+int main() {
+lwpid_t avar
+; return 0; }
+EOF
+if { (eval echo configure:5293: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_lwpid_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_lwpid_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_lwpid_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LWPID_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_lwpid_t" 1>&6
+
+ echo $ac_n "checking for psaddr_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:5315: checking for psaddr_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_psaddr_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5320 "configure"
+#include "confdefs.h"
+
+#define _SYSCALL32
+#include <sys/procfs.h>
+int main() {
+psaddr_t avar
+; return 0; }
+EOF
+if { (eval echo configure:5329: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_psaddr_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_psaddr_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_psaddr_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PSADDR_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_psaddr_t" 1>&6
+
+ echo $ac_n "checking for prsysent_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:5351: checking for prsysent_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prsysent_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5356 "configure"
+#include "confdefs.h"
+
+#define _SYSCALL32
+#include <sys/procfs.h>
+int main() {
+prsysent_t avar
+; return 0; }
+EOF
+if { (eval echo configure:5365: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prsysent_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prsysent_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_prsysent_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PRSYSENT_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_prsysent_t" 1>&6
+
+ echo $ac_n "checking for pr_sigset_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:5387: checking for pr_sigset_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_pr_sigset_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5392 "configure"
+#include "confdefs.h"
+
+#define _SYSCALL32
+#include <sys/procfs.h>
+int main() {
+pr_sigset_t avar
+; return 0; }
+EOF
+if { (eval echo configure:5401: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_pr_sigset_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_pr_sigset_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_pr_sigset_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PR_SIGSET_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_pr_sigset_t" 1>&6
+
+ echo $ac_n "checking for pr_sigaction64_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:5423: checking for pr_sigaction64_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_pr_sigaction64_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5428 "configure"
+#include "confdefs.h"
+
+#define _SYSCALL32
+#include <sys/procfs.h>
+int main() {
+pr_sigaction64_t avar
+; return 0; }
+EOF
+if { (eval echo configure:5437: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_pr_sigaction64_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_pr_sigaction64_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_pr_sigaction64_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PR_SIGACTION64_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_pr_sigaction64_t" 1>&6
+
+ echo $ac_n "checking for pr_siginfo64_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:5459: checking for pr_siginfo64_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_pr_siginfo64_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5464 "configure"
+#include "confdefs.h"
+
+#define _SYSCALL32
+#include <sys/procfs.h>
+int main() {
+pr_siginfo64_t avar
+; return 0; }
+EOF
+if { (eval echo configure:5473: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_pr_siginfo64_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_pr_siginfo64_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_pr_siginfo64_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PR_SIGINFO64_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_pr_siginfo64_t" 1>&6
+
+
+
+
+
+ if test $bfd_cv_have_sys_procfs_type_prfpregset_t = yes; then
+ echo $ac_n "checking whether prfpregset_t type is broken""... $ac_c" 1>&6
+echo "configure:5500: checking whether prfpregset_t type is broken" >&5
+ if eval "test \"`echo '$''{'gdb_cv_prfpregset_t_broken'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ gdb_cv_prfpregset_t_broken=yes
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5508 "configure"
+#include "confdefs.h"
+#include <sys/procfs.h>
+ int main ()
+ {
+ if (sizeof (prfpregset_t) == sizeof (void *))
+ return 1;
+ return 0;
+ }
+EOF
+if { (eval echo configure:5518: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ gdb_cv_prfpregset_t_broken=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ gdb_cv_prfpregset_t_broken=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+
+ echo "$ac_t""$gdb_cv_prfpregset_t_broken" 1>&6
+ if test $gdb_cv_prfpregset_t_broken = yes; then
+ cat >> confdefs.h <<\EOF
+#define PRFPREGSET_T_BROKEN 1
+EOF
+
+ fi
+ fi
+
+
+ echo $ac_n "checking for PIOCSET ioctl entry in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:5543: checking for PIOCSET ioctl entry in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'gdb_cv_have_procfs_piocset'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5548 "configure"
+#include "confdefs.h"
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/procfs.h>
+
+int main() {
+
+ int dummy;;
+ dummy = ioctl(0, PIOCSET, &dummy);
+
+; return 0; }
+EOF
+if { (eval echo configure:5561: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_have_procfs_piocset=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_have_procfs_piocset=no
+fi
+rm -f conftest*
+fi
+
+ echo "$ac_t""$gdb_cv_have_procfs_piocset" 1>&6
+ if test $gdb_cv_have_procfs_piocset = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PROCFS_PIOCSET 1
+EOF
+
+ fi
+fi
+
+if test ${host} = ${target} ; then
+
+ echo $ac_n "checking for member l_addr in struct link_map""... $ac_c" 1>&6
+echo "configure:5585: checking for member l_addr in struct link_map" >&5
+ if eval "test \"`echo '$''{'gdb_cv_have_struct_link_map_with_l_members'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5590 "configure"
+#include "confdefs.h"
+#include <link.h>
+int main() {
+struct link_map lm; (void) lm.l_addr;
+; return 0; }
+EOF
+if { (eval echo configure:5597: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_have_struct_link_map_with_l_members=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_have_struct_link_map_with_l_members=no
+fi
+rm -f conftest*
+fi
+
+ echo "$ac_t""$gdb_cv_have_struct_link_map_with_l_members" 1>&6
+ if test $gdb_cv_have_struct_link_map_with_l_members = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS 1
+EOF
+
+ fi
+
+
+ echo $ac_n "checking for member lm_addr in struct link_map""... $ac_c" 1>&6
+echo "configure:5619: checking for member lm_addr in struct link_map" >&5
+ if eval "test \"`echo '$''{'gdb_cv_have_struct_link_map_with_lm_members'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5624 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <link.h>
+int main() {
+struct link_map lm; (void) lm.lm_addr;
+; return 0; }
+EOF
+if { (eval echo configure:5632: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_have_struct_link_map_with_lm_members=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_have_struct_link_map_with_lm_members=no
+fi
+rm -f conftest*
+fi
+
+ echo "$ac_t""$gdb_cv_have_struct_link_map_with_lm_members" 1>&6
+ if test $gdb_cv_have_struct_link_map_with_lm_members = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS 1
+EOF
+
+ fi
+
+
+ echo $ac_n "checking for member som_addr in struct so_map""... $ac_c" 1>&6
+echo "configure:5654: checking for member som_addr in struct so_map" >&5
+ if eval "test \"`echo '$''{'gdb_cv_have_struct_so_map_with_som_members'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5659 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#ifdef HAVE_NLIST_H
+#include <nlist.h>
+#endif
+#include <link.h>
+int main() {
+struct so_map lm; (void) lm.som_addr;
+; return 0; }
+EOF
+if { (eval echo configure:5670: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_have_struct_so_map_with_som_members=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_have_struct_so_map_with_som_members=no
+fi
+rm -f conftest*
+fi
+
+ echo "$ac_t""$gdb_cv_have_struct_so_map_with_som_members" 1>&6
+ if test $gdb_cv_have_struct_so_map_with_som_members = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS 1
+EOF
+
+ fi
+
+
+ echo $ac_n "checking for struct link_map32 in sys/link.h""... $ac_c" 1>&6
+echo "configure:5692: checking for struct link_map32 in sys/link.h" >&5
+ if eval "test \"`echo '$''{'gdb_cv_have_struct_link_map32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5697 "configure"
+#include "confdefs.h"
+#define _SYSCALL32
+#include <sys/link.h>
+int main() {
+struct link_map32 l;
+; return 0; }
+EOF
+if { (eval echo configure:5705: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_have_struct_link_map32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_have_struct_link_map32=no
+fi
+rm -f conftest*
+fi
+
+ echo "$ac_t""$gdb_cv_have_struct_link_map32" 1>&6
+ if test $gdb_cv_have_struct_link_map32 = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_LINK_MAP32 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define _SYSCALL32 1
+EOF
+
+ fi
+fi
+
+echo $ac_n "checking for main in -lm""... $ac_c" 1>&6
+echo "configure:5731: checking for main in -lm" >&5
+ac_lib_var=`echo m'_'main | sed 'y%./+-%__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="-lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5739 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:5746: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lm $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking for wctype in -lc""... $ac_c" 1>&6
+echo "configure:5775: checking for wctype in -lc" >&5
+ac_lib_var=`echo c'_'wctype | sed 'y%./+-%__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="-lc $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5783 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char wctype();
+
+int main() {
+wctype()
+; return 0; }
+EOF
+if { (eval echo configure:5794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for wctype in -lw""... $ac_c" 1>&6
+echo "configure:5813: checking for wctype in -lw" >&5
+ac_lib_var=`echo w'_'wctype | sed 'y%./+-%__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="-lw $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5821 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char wctype();
+
+int main() {
+wctype()
+; return 0; }
+EOF
+if { (eval echo configure:5832: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo w | sed -e 's/^a-zA-Z0-9_/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lw $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+
+echo $ac_n "checking for long long support in compiler""... $ac_c" 1>&6
+echo "configure:5864: checking for long long support in compiler" >&5
+if eval "test \"`echo '$''{'gdb_cv_c_long_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5869 "configure"
+#include "confdefs.h"
+
+int main() {
+
+ extern long long foo;
+ switch (foo & 2) { case 0: return 1; }
+
+; return 0; }
+EOF
+if { (eval echo configure:5879: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_c_long_long=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_c_long_long=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gdb_cv_c_long_long" 1>&6
+if test $gdb_cv_c_long_long = yes; then
+ cat >> confdefs.h <<\EOF
+#define CC_HAS_LONG_LONG 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for long long support in printf""... $ac_c" 1>&6
+echo "configure:5901: checking for long long support in printf" >&5
+if eval "test \"`echo '$''{'gdb_cv_printf_has_long_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ gdb_cv_printf_has_long_long=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5909 "configure"
+#include "confdefs.h"
+
+int main () {
+ char buf[32];
+ long long l = 0;
+ l = (l << 16) + 0x0123;
+ l = (l << 16) + 0x4567;
+ l = (l << 16) + 0x89ab;
+ l = (l << 16) + 0xcdef;
+ sprintf (buf, "0x%016llx", l);
+ return (strcmp ("0x0123456789abcdef", buf));
+}
+EOF
+if { (eval echo configure:5923: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ gdb_cv_printf_has_long_long=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ gdb_cv_printf_has_long_long=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+if test $gdb_cv_printf_has_long_long = yes; then
+ cat >> confdefs.h <<\EOF
+#define PRINTF_HAS_LONG_LONG 1
+EOF
+
+fi
+echo "$ac_t""$gdb_cv_printf_has_long_long" 1>&6
+
+
+echo $ac_n "checking for long double support in compiler""... $ac_c" 1>&6
+echo "configure:5947: checking for long double support in compiler" >&5
+if eval "test \"`echo '$''{'ac_cv_c_long_double'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5952 "configure"
+#include "confdefs.h"
+
+int main() {
+long double foo;
+; return 0; }
+EOF
+if { (eval echo configure:5959: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_long_double=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_long_double=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_long_double" 1>&6
+if test $ac_cv_c_long_double = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LONG_DOUBLE 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for long double support in printf""... $ac_c" 1>&6
+echo "configure:5981: checking for long double support in printf" >&5
+if eval "test \"`echo '$''{'gdb_cv_printf_has_long_double'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ gdb_cv_printf_has_long_double=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5989 "configure"
+#include "confdefs.h"
+
+int main () {
+ char buf[16];
+ long double f = 3.141592653;
+ sprintf (buf, "%Lg", f);
+ return (strncmp ("3.14159", buf, 7));
+}
+EOF
+if { (eval echo configure:5999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ gdb_cv_printf_has_long_double=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ gdb_cv_printf_has_long_double=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+if test $gdb_cv_printf_has_long_double = yes; then
+ cat >> confdefs.h <<\EOF
+#define PRINTF_HAS_LONG_DOUBLE 1
+EOF
+
+fi
+echo "$ac_t""$gdb_cv_printf_has_long_double" 1>&6
+
+
+echo $ac_n "checking for long double support in scanf""... $ac_c" 1>&6
+echo "configure:6023: checking for long double support in scanf" >&5
+if eval "test \"`echo '$''{'gdb_cv_scanf_has_long_double'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ gdb_cv_scanf_has_long_double=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6031 "configure"
+#include "confdefs.h"
+
+int main () {
+ char *buf = "3.141592653";
+ long double f = 0;
+ sscanf (buf, "%Lg", &f);
+ return !(f > 3.14159 && f < 3.14160);
+}
+EOF
+if { (eval echo configure:6041: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ gdb_cv_scanf_has_long_double=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ gdb_cv_scanf_has_long_double=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+if test $gdb_cv_scanf_has_long_double = yes; then
+ cat >> confdefs.h <<\EOF
+#define SCANF_HAS_LONG_DOUBLE 1
+EOF
+
+fi
+echo "$ac_t""$gdb_cv_scanf_has_long_double" 1>&6
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:6067: checking for $ac_hdr" >&5
+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 6072 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6077: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+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 | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:6106: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6111 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:6134: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:6159: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6167 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:6307: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+
+case ${host_os} in
+aix*)
+ echo $ac_n "checking for -bbigtoc option""... $ac_c" 1>&6
+echo "configure:6333: checking for -bbigtoc option" >&5
+if eval "test \"`echo '$''{'gdb_cv_bigtoc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ SAVE_LDFLAGS=$LDFLAGS
+
+ case $GCC in
+ yes) gdb_cv_bigtoc=-Wl,-bbigtoc ;;
+ *) gdb_cv_bigtoc=-bbigtoc ;;
+ esac
+
+ LDFLAGS=$LDFLAGS\ $gdb_cv_bigtoc
+ cat > conftest.$ac_ext <<EOF
+#line 6347 "configure"
+#include "confdefs.h"
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:6354: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_bigtoc=
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$gdb_cv_bigtoc" 1>&6
+ CONFIG_LDFLAGS="${CONFIG_LDFLAGS} ${gdb_cv_bigtoc}"
+ ;;
+esac
+
+
+
+if test ${build} = ${host} -a ${host} = ${target} ; then
+ case ${host_os} in
+ hpux*)
+ echo $ac_n "checking for HPUX/OSF thread support""... $ac_c" 1>&6
+echo "configure:6377: checking for HPUX/OSF thread support" >&5
+ if test -f /usr/include/dce/cma_config.h ; then
+ if test "$GCC" = "yes" ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_HPUX_THREAD_SUPPORT 1
+EOF
+
+ CONFIG_LIB_OBS="${CONFIG_LIB_OBS} hpux-thread.o"
+ CONFIG_SRCS="${CONFIG_SRCS} hpux-thread.c"
+ else
+ echo "$ac_t""no (suppressed because you are not using GCC)" 1>&6
+ fi
+ else
+ echo "$ac_t""no" 1>&6
+ fi
+ ;;
+ solaris*)
+ echo $ac_n "checking for Solaris thread debugging library""... $ac_c" 1>&6
+echo "configure:6396: checking for Solaris thread debugging library" >&5
+ if test -f /usr/lib/libthread_db.so.1 ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_THREAD_DB_LIB 1
+EOF
+
+ CONFIG_LIB_OBS="${CONFIG_LIB_OBS} sol-thread.o"
+ CONFIG_SRCS="${CONFIG_SRCS} sol-thread.c"
+ echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:6406: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__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="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6414 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:6425: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-ldl $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test "$GCC" = "yes" ; then
+ # The GNU linker requires the -export-dynamic option to make
+ # all symbols visible in the dynamic symbol table.
+ hold_ldflags=$LDFLAGS
+ echo $ac_n "checking for the ld -export-dynamic flag""... $ac_c" 1>&6
+echo "configure:6457: checking for the ld -export-dynamic flag" >&5
+ LDFLAGS="${LDFLAGS} -Wl,-export-dynamic"
+ cat > conftest.$ac_ext <<EOF
+#line 6460 "configure"
+#include "confdefs.h"
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:6467: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ found=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ found=no
+fi
+rm -f conftest*
+ LDFLAGS=$hold_ldflags
+ echo "$ac_t""$found" 1>&6
+ if test $found = yes; then
+ CONFIG_LDFLAGS="${CONFIG_LDFLAGS} -Wl,-export-dynamic"
+ fi
+ fi
+ # Sun randomly tweaked the prototypes in <proc_service.h>
+ # at one point.
+ echo $ac_n "checking if <proc_service.h> is old""... $ac_c" 1>&6
+echo "configure:6486: checking if <proc_service.h> is old" >&5
+ if eval "test \"`echo '$''{'gdb_cv_proc_service_is_old'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ cat > conftest.$ac_ext <<EOF
+#line 6492 "configure"
+#include "confdefs.h"
+
+ #include <proc_service.h>
+ ps_err_e ps_pdwrite
+ (struct ps_prochandle*, psaddr_t, const void*, size_t);
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:6503: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_proc_service_is_old=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_proc_service_is_old=yes
+fi
+rm -f conftest*
+
+fi
+
+ echo "$ac_t""$gdb_cv_proc_service_is_old" 1>&6
+ if test $gdb_cv_proc_service_is_old = yes; then
+ cat >> confdefs.h <<\EOF
+#define PROC_SERVICE_IS_OLD 1
+EOF
+
+ fi
+ else
+ echo "$ac_t""no" 1>&6
+ fi
+ ;;
+ esac
+
+fi
+
+
+# Check whether --enable-gdbcli or --disable-gdbcli was given.
+if test "${enable_gdbcli+set}" = set; then
+ enableval="$enable_gdbcli"
+
+ case "${enableval}" in
+ yes) enable_gdbcli=yes ;;
+ "") enable_gdbcli=yes ;;
+ no)
+ { echo "configure: error: The CLI cannot be disabled yet" 1>&2; exit 1; }
+ ;;
+ *)
+ { echo "configure: error: Bad value for --enable-gdbcli: ${enableval}" 1>&2; exit 1; }
+ ;;
+ esac
+
+else
+ enable_gdbcli=yes
+fi
+
+case ${enable_gdbcli} in
+ "yes" )
+ if test -d "${srcdir}/cli" ; then
+ CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_CLI_OBS)"
+ CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_CLI_DEPS)"
+ CONFIG_SRCS="${CONFIG_SRCS} \$(SUBDIR_CLI_SRCS)"
+ CONFIG_INITS="${CONFIG_INITS} \$(SUBDIR_CLI_INITS)"
+ ENABLE_CFLAGS="${ENABLE_CFLAGS} \$(SUBDIR_CLI_CFLAGS)"
+ CONFIG_ALL="${CONFIG_ALL} \$(SUBDIR_CLI_ALL)"
+ CONFIG_CLEAN="${CONFIG_CLEAN} \$(SUBDIR_CLI_CLEAN)"
+ CONFIG_INSTALL="${CONFIG_INSTALL} \$(SUBDIR_CLI_INSTALL)"
+ CONFIG_UNINSTALL="${CONFIG_UNINSTALL} \$(SUBDIR_CLI_UNINSTALL)"
+ fi
+ ;;
+esac
+
+
+# Check whether --enable-gdbmi or --disable-gdbmi was given.
+if test "${enable_gdbmi+set}" = set; then
+ enableval="$enable_gdbmi"
+
+ case "${enable_gdbmi}" in
+ yes | no) ;;
+ "") enable_gdbmi=yes ;;
+ *)
+ { echo "configure: error: Bad value for --enable-gdbmi: ${enableval}" 1>&2; exit 1; }
+ ;;
+ esac
+
+else
+ enable_gdbmi=yes
+fi
+
+case ${enable_gdbmi} in
+ "yes" )
+ if test -d "${srcdir}/mi" ; then
+ CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_MI_OBS)"
+ CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_MI_DEPS)"
+ CONFIG_SRCS="${CONFIG_SRCS} \$(SUBDIR_MI_SRCS)"
+ CONFIG_INITS="${CONFIG_INITS} \$(SUBDIR_MI_INITS)"
+ ENABLE_CFLAGS="${ENABLE_CFLAGS} \$(SUBDIR_MI_CFLAGS)"
+ CONFIG_ALL="${CONFIG_ALL} \$(SUBDIR_MI_ALL)"
+ CONFIG_CLEAN="${CONFIG_CLEAN} \$(SUBDIR_MI_CLEAN)"
+ CONFIG_INSTALL="${CONFIG_INSTALL} \$(SUBDIR_MI_INSTALL)"
+ CONFIG_UNINSTALL="${CONFIG_UNINSTALL} \$(SUBDIR_MI_UNINSTALL)"
+ fi
+ ;;
+esac
+
+# Configure UI_OUT by default (before 5.2 it can be disabled)
+# It must be configured if gdbmi is configured
+
+UIOUT_CFLAGS=
+
+
+# Check whether --with-uiout or --without-uiout was given.
+if test "${with_uiout+set}" = set; then
+ withval="$with_uiout"
+ case "${withval}" in
+ yes) want_uiout=true ;;
+ no) if test $enable_gdbmi = yes; then
+ { echo "configure: error: uiout is needed for MI and cannot be disabled" 1>&2; exit 1; }
+ else
+ want_uiout=false
+ fi ;;
+ *) { echo "configure: error: bad value ${withval} for GDB with-uiout option" 1>&2; exit 1; } ;;
+esac
+else
+ want_uiout=true
+fi
+
+if test $want_uiout = true; then
+ UIOUT_CFLAGS="-DUI_OUT=1"
+fi
+
+# Check whether --enable-tui or --disable-tui was given.
+if test "${enable_tui+set}" = set; then
+ enableval="$enable_tui"
+
+ case "${enable_tui}" in
+ yes | no) ;;
+ "") enable_tui=yes ;;
+ *)
+ { echo "configure: error: Bad value for --enable-tui: ${enableval}" 1>&2; exit 1; }
+ ;;
+ esac
+
+fi
+
+case ${enable_tui} in
+ "yes" )
+ if test -d "${srcdir}/tui" ; then
+ CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_TUI_OBS)"
+ CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_TUI_DEPS)"
+ CONFIG_SRCS="${CONFIG_SRCS} \$(SUBDIR_TUI_SRCS)"
+ CONFIG_INITS="${CONFIG_INITS} \$(SUBDIR_TUI_INITS)"
+ ENABLE_CFLAGS="${ENABLE_CFLAGS} \$(SUBDIR_TUI_CFLAGS)"
+ CONFIG_ALL="${CONFIG_ALL} \$(SUBDIR_TUI_ALL)"
+ CONFIG_CLEAN="${CONFIG_CLEAN} \$(SUBDIR_TUI_CLEAN)"
+ CONFIG_INSTALL="${CONFIG_INSTALL} \$(SUBDIR_TUI_INSTALL)"
+ CONFIG_UNINSTALL="${CONFIG_UNINSTALL} \$(SUBDIR_TUI_UNINSTALL)"
+ fi
+ ;;
+esac
+
+# Check whether --enable-netrom or --disable-netrom was given.
+if test "${enable_netrom+set}" = set; then
+ enableval="$enable_netrom"
+ case "${enableval}" in
+yes) enable_netrom=yes ;;
+no) enable_netrom=no ;;
+*) { echo "configure: error: bad value ${enableval} given for netrom option" 1>&2; exit 1; } ;;
+esac
+fi
+
+
+if test "${enable_netrom}" = "yes"; then
+ CONFIG_LIB_OBS="${CONFIG_LIB_OBS} remote-nrom.o"
+ CONFIG_SRCS="${CONFIG_SRCS} remote-nrom.c"
+fi
+
+
+# NOTE: Don't add -Wall or -Wunused, they both include
+# -Wunused-parameter which reports bogus warnings.
+# NOTE: If you add to this list, remember to update
+# gdb/doc/gdbint.texinfo.
+build_warnings="-Wimplicit -Wreturn-type -Wcomment -Wtrigraphs \
+-Wformat -Wparentheses -Wpointer-arith -Wuninitialized"
+# Up for debate: -Wswitch -Wcomment -trigraphs -Wtrigraphs
+# -Wunused-function -Wunused-label -Wunused-variable -Wunused-value
+# -Wchar-subscripts -Wtraditional -Wshadow -Wcast-qual
+# -Wcast-align -Wwrite-strings -Wconversion -Wstrict-prototypes
+# -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls
+# -Woverloaded-virtual -Winline -Werror"
+# Check whether --enable-build-warnings or --disable-build-warnings was given.
+if test "${enable_build_warnings+set}" = set; then
+ enableval="$enable_build_warnings"
+ case "${enableval}" in
+ yes) ;;
+ no) build_warnings="-w";;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${build_warnings} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${t} ${build_warnings}";;
+ *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then
+ echo "Setting compiler warning flags = $build_warnings" 6>&1
+fi
+fi
+# Check whether --enable-gdb-build-warnings or --disable-gdb-build-warnings was given.
+if test "${enable_gdb_build_warnings+set}" = set; then
+ enableval="$enable_gdb_build_warnings"
+ case "${enableval}" in
+ yes) ;;
+ no) build_warnings="-w";;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${build_warnings} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${t} ${build_warnings}";;
+ *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then
+ echo "Setting GDB specific compiler warning flags = $build_warnings" 6>&1
+fi
+fi
+WARN_CFLAGS=""
+WERROR_CFLAGS=""
+if test "x${build_warnings}" != x -a "x$GCC" = xyes
+then
+ echo $ac_n "checking compiler warning flags""... $ac_c" 1>&6
+echo "configure:6722: checking compiler warning flags" >&5
+ # Separate out the -Werror flag as some files just cannot be
+ # compiled with it enabled.
+ for w in ${build_warnings}; do
+ case $w in
+ -Werr*) WERROR_CFLAGS=-Werror ;;
+ *) # Check that GCC accepts it
+ saved_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $w"
+ cat > conftest.$ac_ext <<EOF
+#line 6732 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:6739: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ WARN_CFLAGS="${WARN_CFLAGS} $w"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ CFLAGS="$saved_CFLAGS"
+ esac
+ done
+ echo "$ac_t""${WARN_CFLAGS}${WERROR_CFLAGS}" 1>&6
+fi
+
+
+
+MMALLOC_CFLAGS=
+MMALLOC=
+
+
+
+# Check whether --with-mmalloc or --without-mmalloc was given.
+if test "${with_mmalloc+set}" = set; then
+ withval="$with_mmalloc"
+ case "${withval}" in
+ yes) want_mmalloc=true ;;
+ no) want_mmalloc=false;;
+ *) { echo "configure: error: bad value ${withval} for GDB with-mmalloc option" 1>&2; exit 1; } ;;
+esac
+else
+ want_mmalloc=false
+fi
+
+if test x$want_mmalloc = xtrue; then
+ cat >> confdefs.h <<\EOF
+#define USE_MMALLOC 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define MMCHECK_FORCE 1
+EOF
+
+ MMALLOC_CFLAGS="-I$srcdir/../mmalloc"
+ MMALLOC='../mmalloc/libmmalloc.a'
+fi
+
+# Check whether --with-included-regex or --without-included-regex was given.
+if test "${with_included_regex+set}" = set; then
+ withval="$with_included_regex"
+ case "${withval}" in
+ yes) want_included_regex=true ;;
+ no) want_included_regex=false;;
+ *) { echo "configure: error: bad value ${withval} for GDB with-included-regex option" 1>&2; exit 1; } ;;
+esac
+else
+ want_included_regex=true
+fi
+
+if test $want_included_regex = false; then
+ echo $ac_n "checking for GNU regex""... $ac_c" 1>&6
+echo "configure:6799: checking for GNU regex" >&5
+ if eval "test \"`echo '$''{'gdb_cv_have_gnu_regex'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6804 "configure"
+#include "confdefs.h"
+#include <gnu-versions.h>
+#include <sys/types.h>
+#include <regex.h>
+int main() {
+#if !defined _GNU_REGEX_INTERFACE_VERSION || !defined __GLIBC__ || __GLIBC__ < 2
+#error No valid GNU regex.
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:6816: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdb_cv_have_gnu_regex=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdb_cv_have_gnu_regex=no
+fi
+rm -f conftest*
+fi
+
+ echo "$ac_t""$gdb_cv_have_gnu_regex" 1>&6
+ if test $gdb_cv_have_gnu_regex = no; then
+ want_included_regex=true
+ fi
+fi
+
+if test x${want_included_regex} = xtrue; then
+ REGEX="gnu-regex.o"
+ cat >> confdefs.h <<\EOF
+#define USE_INCLUDED_REGEX 1
+EOF
+
+fi
+
+
+# In the Cygwin environment, we need some additional flags.
+echo $ac_n "checking for cygwin""... $ac_c" 1>&6
+echo "configure:6845: checking for cygwin" >&5
+if eval "test \"`echo '$''{'gdb_cv_os_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6850 "configure"
+#include "confdefs.h"
+
+#if defined (__CYGWIN__) || defined (__CYGWIN32__)
+lose
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "lose" >/dev/null 2>&1; then
+ rm -rf conftest*
+ gdb_cv_os_cygwin=yes
+else
+ rm -rf conftest*
+ gdb_cv_os_cygwin=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$gdb_cv_os_cygwin" 1>&6
+
+
+SER_HARDWIRE="ser-unix.o ser-pipe.o ser-tcp.o"
+case ${host} in
+ *go32* ) SER_HARDWIRE=ser-go32.o ;;
+ *djgpp* ) SER_HARDWIRE=ser-go32.o ;;
+esac
+
+
+
+if test x$gdb_host = xgo32; then
+ TERM_LIB=
+else
+if test x$gdb_cv_os_cygwin = xyes; then
+ TERM_LIB='`if test -r ../libtermcap/libtermcap.a; then echo ../libtermcap/libtermcap.a; else echo -ltermcap; fi`'
+else
+ TERM_LIB=
+ echo $ac_n "checking for tgetent in -lncurses""... $ac_c" 1>&6
+echo "configure:6888: checking for tgetent in -lncurses" >&5
+ac_lib_var=`echo ncurses'_'tgetent | sed 'y%./+-%__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="-lncurses $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6896 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tgetent();
+
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:6907: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ TERM_LIB=-lncurses
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for tgetent in -lHcurses""... $ac_c" 1>&6
+echo "configure:6926: checking for tgetent in -lHcurses" >&5
+ac_lib_var=`echo Hcurses'_'tgetent | sed 'y%./+-%__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="-lHcurses $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6934 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tgetent();
+
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:6945: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ TERM_LIB=-lHcurses
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for tgetent in -ltermlib""... $ac_c" 1>&6
+echo "configure:6964: checking for tgetent in -ltermlib" >&5
+ac_lib_var=`echo termlib'_'tgetent | sed 'y%./+-%__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="-ltermlib $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6972 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tgetent();
+
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:6983: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ TERM_LIB=-ltermlib
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6
+echo "configure:7002: checking for tgetent in -ltermcap" >&5
+ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__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="-ltermcap $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7010 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tgetent();
+
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:7021: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ TERM_LIB=-ltermcap
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for tgetent in -lcurses""... $ac_c" 1>&6
+echo "configure:7040: checking for tgetent in -lcurses" >&5
+ac_lib_var=`echo curses'_'tgetent | sed 'y%./+-%__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="-lcurses $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7048 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tgetent();
+
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:7059: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ TERM_LIB=-lcurses
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for tgetent in -lterminfo""... $ac_c" 1>&6
+echo "configure:7078: checking for tgetent in -lterminfo" >&5
+ac_lib_var=`echo terminfo'_'tgetent | sed 'y%./+-%__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="-lterminfo $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7086 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tgetent();
+
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:7097: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ TERM_LIB=-lterminfo
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+fi
+
+fi
+
+fi
+
+fi
+
+
+ if test "x$TERM_LIB" = x
+ then
+ { echo "configure: error: Could not find a term library" 1>&2; exit 1; }
+ fi
+fi
+fi
+
+
+# libreadline needs libuser32.a in a cygwin environment
+WIN32LIBS=
+if test x$gdb_cv_os_cygwin = xyes; then
+ WIN32LIBS="-luser32"
+ case "${target}" in
+ *cygwin*) WIN32LIBS="$WIN32LIBS -limagehlp"
+ ;;
+ esac
+fi
+
+
+LIBGUI="../libgui/src/libgui.a"
+GUI_CFLAGS_X="-I${srcdir}/../libgui/src"
+
+
+
+# Check whether --with-cpu or --without-cpu was given.
+if test "${with_cpu+set}" = set; then
+ withval="$with_cpu"
+ case "${target}" in
+ powerpc-* | powerpcle-* )
+ ## It would be nice to keep this table in sync with the one in
+ ## gcc/configure.
+ case "${with_cpu}" in
+ ppc-uisa | rs6000 | 403 | 403GC | 505 | 860 | 601 | 602 | 603 \
+ | 604 | 750 )
+ ## Those are all handled in variants in rs6000-tdep.c, so they're fine.
+ ;;
+ common | power | power2 | rios | rios1 | rios2 | rsc | rsc1 )
+ ## These are all RS6000 variants, as far as GDB is concerned.
+ with_cpu=rs6000
+ ;;
+ 603e | ec603e )
+ with_cpu=603
+ ;;
+ 604e )
+ with_cpu=604
+ ;;
+ * )
+ echo "configure: warning: GDB: unknown --with-cpu value: \`${with_cpu}'; using \`ppc-uisa'." 1>&2
+ with_cpu=ppc-uisa
+ ;;
+ esac
+ ;;
+ * )
+ echo "configure: warning: GDB may ignore the --with-cpu flag for ${target} targets" 1>&2
+ ;;
+esac
+cat >> confdefs.h <<EOF
+#define TARGET_CPU_DEFAULT "${with_cpu}"
+EOF
+
+
+fi
+
+
+
+# Check whether --enable-gdbtk or --disable-gdbtk was given.
+if test "${enable_gdbtk+set}" = set; then
+ enableval="$enable_gdbtk"
+ case "${enableval}" in
+ yes)
+ case "$host" in
+ *go32*)
+ echo "configure: warning: GDB does not support GDBtk on host ${host}. GDBtk will be disabled." 1>&2
+ enable_gdbtk=no ;;
+ *windows*)
+ echo "configure: warning: GDB does not support GDBtk on host ${host}. GDBtk will be disabled." 1>&2
+ enable_gdbtk=no ;;
+ *)
+ enable_gdbtk=yes ;;
+ esac ;;
+ no)
+ enable_gdbtk=no ;;
+ *)
+ { echo "configure: error: bad value ${enableval} given for gdbtk option" 1>&2; exit 1; } ;;
+esac
+else
+
+# Default is on for everything but go32 and Cygwin
+case "$host" in
+ *go32* | *windows*)
+ ;;
+ *)
+ if test -d "${srcdir}/gdbtk" ; then
+ enable_gdbtk=yes
+ fi
+ ;;
+esac
+
+fi
+
+
+WIN32LDAPP=
+
+
+
+configdir="unix"
+
+GDBTKLIBS=
+if test "${enable_gdbtk}" = "yes"; then
+
+ # Gdbtk must have an absolute path to srcdir in order to run
+ # properly when not installed.
+ here=`pwd`
+ cd ${srcdir}
+ GDBTK_SRC_DIR=`pwd`
+ cd $here
+
+
+#
+# Ok, lets find the tcl configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tclconfig
+#
+
+if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+ # Check whether --with-tclconfig or --without-tclconfig was given.
+if test "${with_tclconfig+set}" = set; then
+ withval="$with_tclconfig"
+ with_tclconfig=${withval}
+fi
+
+ echo $ac_n "checking for Tcl configuration""... $ac_c" 1>&6
+echo "configure:7262: checking for Tcl configuration" >&5
+ if eval "test \"`echo '$''{'ac_cv_c_tclconfig'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+
+ # First check to see if --with-tclconfig was specified.
+ if test x"${with_tclconfig}" != x ; then
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+ else
+ { echo "configure: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" 1>&2; exit 1; }
+ fi
+ fi
+
+ # then check for a private Tcl installation
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[7-9]* 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[7-9]* 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[7-9]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[7-9]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+
+fi
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCLCONFIG="# no Tcl configs found"
+ echo "configure: warning: Can't find Tcl configuration definitions" 1>&2
+ else
+ no_tcl=
+ TCLCONFIG=${ac_cv_c_tclconfig}/tclConfig.sh
+ echo "$ac_t""found $TCLCONFIG" 1>&6
+ fi
+fi
+
+ if test -z "${no_tcl}"; then
+
+ . $TCLCONFIG
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Ok, lets find the tk configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tkconfig
+#
+
+if test x"${no_tk}" = x ; then
+ # we reset no_tk in case something fails here
+ no_tk=true
+ # Check whether --with-tkconfig or --without-tkconfig was given.
+if test "${with_tkconfig+set}" = set; then
+ withval="$with_tkconfig"
+ with_tkconfig=${withval}
+fi
+
+ echo $ac_n "checking for Tk configuration""... $ac_c" 1>&6
+echo "configure:7370: checking for Tk configuration" >&5
+ if eval "test \"`echo '$''{'ac_cv_c_tkconfig'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+
+ # First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
+ else
+ { echo "configure: error: ${with_tkconfig} directory doesn't contain tkConfig.sh" 1>&2; exit 1; }
+ fi
+ fi
+
+ # then check for a private Tk library
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ../tk \
+ `ls -dr ../tk[4-9]* 2>/dev/null` \
+ ../../tk \
+ `ls -dr ../../tk[4-9]* 2>/dev/null` \
+ ../../../tk \
+ `ls -dr ../../../tk[4-9]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[4-9]* 2>/dev/null` ; do
+ if test -f "$i/${configdir}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+
+fi
+
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TKCONFIG="# no Tk configs found"
+ echo "configure: warning: Can't find Tk configuration definitions" 1>&2
+ else
+ no_tk=
+ TKCONFIG=${ac_cv_c_tkconfig}/tkConfig.sh
+ echo "$ac_t""found $TKCONFIG" 1>&6
+ fi
+fi
+
+
+
+ # now look for Tcl library stuff
+
+ case "${host}" in
+ *-*-cygwin*)
+ tcldir=../tcl/win/
+ ;;
+ *)
+ tcldir=../tcl/unix/
+ ;;
+ esac
+
+ TCL_DEPS="${tcldir}${TCL_LIB_FILE}"
+
+ # If $no_tk is nonempty, then we can't do Tk, and there is no
+ # point to doing Tcl.
+ if test -z "${no_tk}"; then
+
+ if test -f "$TKCONFIG" ; then
+ . $TKCONFIG
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Ok, lets find the tcl source trees so we can use the headers
+# Warning: transition of version 9 to 10 will break this algorithm
+# because 10 sorts before 9. We also look for just tcl. We have to
+# be careful that we don't match stuff like tclX by accident.
+# the alternative search directory is involked by --with-tclinclude
+#
+
+no_tcl=true
+echo $ac_n "checking for Tcl private headers. dir=${configdir}""... $ac_c" 1>&6
+echo "configure:7479: checking for Tcl private headers. dir=${configdir}" >&5
+# Check whether --with-tclinclude or --without-tclinclude was given.
+if test "${with_tclinclude+set}" = set; then
+ withval="$with_tclinclude"
+ with_tclinclude=${withval}
+fi
+
+if eval "test \"`echo '$''{'ac_cv_c_tclh'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+# first check to see if --with-tclinclude was specified
+if test x"${with_tclinclude}" != x ; then
+ if test -f ${with_tclinclude}/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}; pwd)`
+ elif test -f ${with_tclinclude}/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}/generic; pwd)`
+ else
+ { echo "configure: error: ${with_tclinclude} directory doesn't contain private headers" 1>&2; exit 1; }
+ fi
+fi
+
+# next check if it came with Tcl configuration file
+if test x"${ac_cv_c_tclconfig}" = x ; then
+ if test -f $ac_cv_c_tclconfig/../generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $ac_cv_c_tclconfig/..; pwd)`
+ fi
+fi
+
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[7-9]* 2>/dev/null` \
+ ${srcdir}/../../tcl \
+ `ls -dr ${srcdir}/../../tcl[7-9]* 2>/dev/null` \
+ ${srcdir}/../../../tcl \
+ `ls -dr ${srcdir}/../../../tcl[7-9]* 2>/dev/null ` ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tcl[7-9]* 2>/dev/null` \
+ `ls -dr /usr/local/lib/tcl[7-9]* 2>/dev/null` \
+ /usr/local/src/tcl \
+ /usr/local/lib/tcl \
+ ${prefix}/include ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# see if one is installed
+if test x"${ac_cv_c_tclh}" = x ; then
+ ac_safe=`echo "tclInt.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for tclInt.h""... $ac_c" 1>&6
+echo "configure:7545: checking for tclInt.h" >&5
+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 7550 "configure"
+#include "confdefs.h"
+#include <tclInt.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:7555: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_cv_c_tclh=installed
+else
+ echo "$ac_t""no" 1>&6
+ac_cv_c_tclh=""
+fi
+
+fi
+
+fi
+
+if test x"${ac_cv_c_tclh}" = x ; then
+ TCLHDIR="# no Tcl private headers found"
+ { echo "configure: error: Can't find Tcl private headers" 1>&2; exit 1; }
+fi
+if test x"${ac_cv_c_tclh}" != x ; then
+ no_tcl=""
+ if test x"${ac_cv_c_tclh}" = x"installed" ; then
+ echo "$ac_t""is installed" 1>&6
+ TCLHDIR=""
+ else
+ echo "$ac_t""found in ${ac_cv_c_tclh}" 1>&6
+ # this hack is cause the TCLHDIR won't print if there is a "-I" in it.
+ TCLHDIR="-I${ac_cv_c_tclh}"
+ fi
+fi
+
+
+
+
+#
+# Ok, lets find the tk source trees so we can use the headers
+# If the directory (presumably symlink) named "tk" exists, use that one
+# in preference to any others. Same logic is used when choosing library
+# and again with Tcl. The search order is the best place to look first, then in
+# decreasing significance. The loop breaks if the trigger file is found.
+# Note the gross little conversion here of srcdir by cd'ing to the found
+# directory. This converts the path from a relative to an absolute, so
+# recursive cache variables for the path will work right. We check all
+# the possible paths in one loop rather than many seperate loops to speed
+# things up.
+# the alternative search directory is involked by --with-tkinclude
+#
+no_tk=true
+echo $ac_n "checking for Tk private headers""... $ac_c" 1>&6
+echo "configure:7615: checking for Tk private headers" >&5
+# Check whether --with-tkinclude or --without-tkinclude was given.
+if test "${with_tkinclude+set}" = set; then
+ withval="$with_tkinclude"
+ with_tkinclude=${withval}
+fi
+
+if eval "test \"`echo '$''{'ac_cv_c_tkh'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+# first check to see if --with-tkinclude was specified
+if test x"${with_tkinclude}" != x ; then
+ if test -f ${with_tkinclude}/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}; pwd)`
+ elif test -f ${with_tkinclude}/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}/generic; pwd)`
+ else
+ { echo "configure: error: ${with_tkinclude} directory doesn't contain private headers" 1>&2; exit 1; }
+ fi
+fi
+
+# next check if it came with Tk configuration file
+if test x"${ac_cv_c_tkconfig}" = x ; then
+ if test -f $ac_cv_c_tkconfig/../generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $ac_cv_c_tkconfig/..; pwd)`
+ fi
+fi
+
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tkh}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[4-9]* 2>/dev/null` \
+ ${srcdir}/../../tk \
+ `ls -dr ${srcdir}/../../tk[4-9]* 2>/dev/null` \
+ ${srcdir}/../../../tk \
+ `ls -dr ${srcdir}/../../../tk[4-9]* 2>/dev/null ` ; do
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tkh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tk[4-9]* 2>/dev/null` \
+ `ls -dr /usr/local/lib/tk[4-9]* 2>/dev/null` \
+ /usr/local/src/tk \
+ /usr/local/lib/tk \
+ ${prefix}/include ; do
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# see if one is installed
+if test x"${ac_cv_c_tkh}" = x ; then
+ ac_safe=`echo "tk.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for tk.h""... $ac_c" 1>&6
+echo "configure:7681: checking for tk.h" >&5
+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 7686 "configure"
+#include "confdefs.h"
+#include <tk.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:7691: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_cv_c_tkh=installed
+else
+ echo "$ac_t""no" 1>&6
+ac_cv_c_tkh=""
+fi
+
+fi
+
+fi
+
+if test x"${ac_cv_c_tkh}" != x ; then
+ no_tk=""
+ if test x"${ac_cv_c_tkh}" = x"installed" ; then
+ echo "$ac_t""is installed" 1>&6
+ TKHDIR=""
+ else
+ echo "$ac_t""found in ${ac_cv_c_tkh}" 1>&6
+ # this hack is cause the TKHDIR won't print if there is a "-I" in it.
+ TKHDIR="-I${ac_cv_c_tkh}"
+ fi
+else
+ TKHDIR="# no Tk directory found"
+ echo "configure: warning: Can't find Tk private headers" 1>&2
+ no_tk=true
+fi
+
+
+
+
+echo $ac_n "checking for Itcl private headers. srcdir=${srcdir}""... $ac_c" 1>&6
+echo "configure:7737: checking for Itcl private headers. srcdir=${srcdir}" >&5
+if test x"${ac_cv_c_itclh}" = x ; then
+ for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ${srcdir}/../itcl/itcl; do
+ if test -f $i/generic/itcl.h ; then
+ ac_cv_c_itclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_itclh}" = x ; then
+ ITCLHDIR="# no Itcl private headers found"
+ { echo "configure: error: Can't find Itcl private headers" 1>&2; exit 1; }
+fi
+if test x"${ac_cv_c_itclh}" != x ; then
+ ITCLHDIR="-I${ac_cv_c_itclh}"
+fi
+# should always be here
+# ITCLLIB="../itcl/itcl/unix/libitcl.a"
+
+#AC_SUBST(ITCLLIB)
+
+
+echo $ac_n "checking for Itk private headers. srcdir=${srcdir}""... $ac_c" 1>&6
+echo "configure:7760: checking for Itk private headers. srcdir=${srcdir}" >&5
+if test x"${ac_cv_c_itkh}" = x ; then
+ for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ${srcdir}/../itcl/itk; do
+ if test -f $i/generic/itk.h ; then
+ ac_cv_c_itkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_itkh}" = x ; then
+ ITKHDIR="# no Itk private headers found"
+ { echo "configure: error: Can't find Itk private headers" 1>&2; exit 1; }
+fi
+if test x"${ac_cv_c_itkh}" != x ; then
+ ITKHDIR="-I${ac_cv_c_itkh}"
+fi
+# should always be here
+# ITKLIB="../itcl/itk/unix/libitk.a"
+
+#AC_SUBST(ITKLIB)
+
+
+echo $ac_n "checking for Tix private headers. srcdir=${srcdir}""... $ac_c" 1>&6
+echo "configure:7783: checking for Tix private headers. srcdir=${srcdir}" >&5
+if test x"${ac_cv_c_tixh}" = x ; then
+ for i in ${srcdir}/../tix ${srcdir}/../../tix ${srcdir}/../../../tix ; do
+ if test -f $i/generic/tix.h ; then
+ ac_cv_c_tixh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_tixh}" = x ; then
+ TIXHDIR="# no Tix private headers found"
+ { echo "configure: error: Can't find Tix private headers" 1>&2; exit 1; }
+fi
+if test x"${ac_cv_c_tixh}" != x ; then
+ TIXHDIR="-I${ac_cv_c_tixh}"
+fi
+
+
+
+
+ # now look for Tk library stuff
+
+ case "${host}" in
+ *-*-cygwin*)
+ tkdir=../tk/win/
+ ;;
+ *)
+ tkdir=../tk/unix/
+ ;;
+ esac
+
+ TK_DEPS="${tkdir}${TK_LIB_FILE}"
+
+ # now look for Itcl library stuff
+
+
+#
+# Ok, lets find the itcl configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itclconfig
+#
+
+if test x"${no_itcl}" = x ; then
+ # we reset no_itcl in case something fails here
+ no_itcl=true
+ # Check whether --with-itclconfig or --without-itclconfig was given.
+if test "${with_itclconfig+set}" = set; then
+ withval="$with_itclconfig"
+ with_itclconfig=${withval}
+fi
+
+ echo $ac_n "checking for Itcl configuration""... $ac_c" 1>&6
+echo "configure:7835: checking for Itcl configuration" >&5
+ if eval "test \"`echo '$''{'ac_cv_c_itclconfig'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+
+ # First check to see if --with-itclconfig was specified.
+ if test x"${with_itclconfig}" != x ; then
+ if test -f "${with_itclconfig}/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd ${with_itclconfig}; pwd)`
+ else
+ { echo "configure: error: ${with_itclconfig} directory doesn't contain itclConfig.sh" 1>&2; exit 1; }
+ fi
+ fi
+
+ # then check for a private Itcl library
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in \
+ ../itcl/itcl \
+ `ls -dr ../itcl[4-9]*/itcl 2>/dev/null` \
+ ../../itcl \
+ `ls -dr ../../itcl[4-9]*/itcl 2>/dev/null` \
+ ../../../itcl \
+ `ls -dr ../../../itcl[4-9]*/itcl 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../itcl/itcl \
+ `ls -dr ${srcdir}/../itcl[4-9]*/itcl 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+
+fi
+
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ ITCLCONFIG="# no Itcl configs found"
+ echo "configure: warning: Can't find Itcl configuration definitions" 1>&2
+ else
+ no_itcl=
+ ITCLCONFIG=${ac_cv_c_itclconfig}/itclConfig.sh
+ echo "$ac_t""found $ITCLCONFIG" 1>&6
+ fi
+fi
+
+ if test -z "${no_itcl}"; then
+
+ if test -f "$ITCLCONFIG" ; then
+ . $ITCLCONFIG
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+ ITCLLIB="${ITCL_BUILD_LIB_SPEC}"
+ ITCL_DEPS="${ITCL_LIB_FULL_PATH}"
+ fi
+
+
+ # now look for Itk library stuff
+
+#
+# Ok, lets find the itk configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itkconfig
+#
+
+if test x"${no_itk}" = x ; then
+ # we reset no_itk in case something fails here
+ no_itk=true
+ # Check whether --with-itkconfig or --without-itkconfig was given.
+if test "${with_itkconfig+set}" = set; then
+ withval="$with_itkconfig"
+ with_itkconfig=${withval}
+fi
+
+ echo $ac_n "checking for Itk configuration""... $ac_c" 1>&6
+echo "configure:7938: checking for Itk configuration" >&5
+ if eval "test \"`echo '$''{'ac_cv_c_itkconfig'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+
+ # First check to see if --with-itkconfig was specified.
+ if test x"${with_itkconfig}" != x ; then
+ if test -f "${with_itkconfig}/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd ${with_itkconfig}; pwd)`
+ else
+ { echo "configure: error: ${with_itkconfig} directory doesn't contain itkConfig.sh" 1>&2; exit 1; }
+ fi
+ fi
+
+ # then check for a private Itk library
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in \
+ ../itcl/itk \
+ `ls -dr ../itcl[4-9]*/itk 2>/dev/null` \
+ ../../itk \
+ `ls -dr ../../itcl[4-9]*/itk 2>/dev/null` \
+ ../../../itk \
+ `ls -dr ../../../itcl[4-9]*/itk 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../itcl/itk \
+ `ls -dr ${srcdir}/../itcl[4-9]*/itk 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+
+fi
+
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ ITKCONFIG="# no Itk configs found"
+ echo "configure: warning: Can't find Itk configuration definitions" 1>&2
+ else
+ no_itk=
+ ITKCONFIG=${ac_cv_c_itkconfig}/itkConfig.sh
+ echo "$ac_t""found $ITKCONFIG" 1>&6
+ fi
+fi
+
+
+ if test -z "${no_itcl}"; then
+
+ if test -f "$ITKCONFIG" ; then
+ . $ITKCONFIG
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+ ITKLIB="${ITK_BUILD_LIB_SPEC}"
+ ITK_DEPS="${ITK_LIB_FULL_PATH}"
+ fi
+
+ # now look for Tix library stuff
+
+#
+# Ok, lets find the tix configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itkconfig
+#
+
+if test x"${no_tix}" = x ; then
+ # we reset no_tix in case something fails here
+ no_tix=true
+ # Check whether --with-tixconfig or --without-tixconfig was given.
+if test "${with_tixconfig+set}" = set; then
+ withval="$with_tixconfig"
+ with_tixconfig=${withval}
+fi
+
+ echo $ac_n "checking for Tix configuration""... $ac_c" 1>&6
+echo "configure:8041: checking for Tix configuration" >&5
+ if eval "test \"`echo '$''{'ac_cv_c_tixconfig'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+
+ # First check to see if --with-tixconfig was specified.
+ if test x"${with_tixconfig}" != x ; then
+ if test -f "${with_tixconfig}/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd ${with_tixconfig}; pwd)`
+ else
+ { echo "configure: error: ${with_tixconfig} directory doesn't contain tixConfig.sh" 1>&2; exit 1; }
+ fi
+ fi
+
+ # then check for a private Tix library
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in \
+ ../tix \
+ `ls -dr ../tix 2>/dev/null` \
+ ../../tix \
+ `ls -dr ../../tix 2>/dev/null` \
+ ../../../tix \
+ `ls -dr ../../../tix 2>/dev/null` ; do
+ echo "**** Looking at $i - with ${configdir}"
+ if test -f "$i/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ echo "**** Looking at $i"
+ if test -f "$i/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ echo "**** Other private locations"
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tix \
+ `ls -dr ${srcdir}/../tix 2>/dev/null` ; do
+ echo "**** Looking at $i - with ${configdir}"
+ if test -f "$i/${configdir}/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i/${configdir}; pwd)`
+ break
+ fi
+ done
+ fi
+
+fi
+
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ TIXCONFIG="# no Tix configs found"
+ echo "configure: warning: Can't find Tix configuration definitions" 1>&2
+ else
+ no_tix=
+ TIXCONFIG=${ac_cv_c_tixconfig}/tixConfig.sh
+ echo "$ac_t""found $TIXCONFIG" 1>&6
+ fi
+fi
+
+
+ if test -z "${no_tix}"; then
+
+ if test -f "$TIXCONFIG" ; then
+ . $TIXCONFIG
+ fi
+
+
+
+
+
+
+
+
+ TIXLIB="${TIX_BUILD_LIB_SPEC}"
+ TIX_DEPS="${TIX_BUILD_LOCATION}/${TIX_LIB_FILE}"
+ fi
+
+ ENABLE_CFLAGS="${ENABLE_CFLAGS} \$(SUBDIR_GDBTK_CFLAGS)"
+ # Tcl/Tk 8.1 require -fwritable strings. I don't
+ # know whether 8.2 will or not, but I bet it will.
+ # I don't have to worry about 7.x since we don't support it.
+ GDBTK_CFLAGS=""
+ if test "$GCC" = "yes"; then
+ if test "$TCL_VERSION" != "8.0" ; then
+ GDBTK_CFLAGS="-fwritable-strings"
+ fi
+ fi
+
+ # Include some libraries that Tcl and Tk want.
+ TCL_LIBS='$(LIBGUI) $(ITCL) $(ITK) $(TIX) $(TK) $(TCL) $(X11_LDFLAGS) $(X11_LIBS)'
+ # Yes, the ordering seems wrong here. But it isn't.
+ # TK_LIBS is the list of libraries that need to be linked
+ # after Tcl/Tk. Note that this isn't put into LIBS. If it
+ # were in LIBS then any link tests after this point would
+ # try to include things like `$(LIBGUI)', which wouldn't work.
+ GDBTKLIBS="${TCL_LIBS} ${TK_LIBS}"
+
+ CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_GDBTK_OBS)"
+ CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_GDBTK_DEPS)"
+ CONFIG_SRCS="${CONFIG_SRCS} \$(SUBDIR_GDBTK_SRCS)"
+ CONFIG_INITS="${CONFIG_INITS} \$(SUBDIR_GDBTK_INITS)"
+ CONFIG_ALL="${CONFIG_ALL} \$(SUBDIR_GDBTK_ALL)"
+ CONFIG_CLEAN="${CONFIG_CLEAN} \$(SUBDIR_GDBTK_CLEAN)"
+ CONFIG_INSTALL="${CONFIG_INSTALL} \$(SUBDIR_GDBTK_INSTALL)"
+ CONFIG_UNINSTALL="${CONFIG_UNINSTALL} \$(SUBDIR_GDBTK_UNINSTALL)"
+
+ if test x$gdb_cv_os_cygwin = xyes; then
+ WIN32LIBS="${WIN32LIBS} -lshell32 -lgdi32 -lcomdlg32 -ladvapi32"
+ WIN32LDAPP="-Wl,--subsystem,console"
+ CONFIG_OBS="${CONFIG_OBS} gdbres.o"
+ fi
+ fi
+ fi
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If we find X, set shell vars x_includes and x_libraries to the
+# paths, otherwise set no_x=yes.
+# Uses ac_ vars as temps to allow command line to override cache and checks.
+# --without-x overrides everything else, but does not touch the cache.
+echo $ac_n "checking for X""... $ac_c" 1>&6
+echo "configure:8184: checking for X" >&5
+
+# Check whether --with-x or --without-x was given.
+if test "${with_x+set}" = set; then
+ withval="$with_x"
+ :
+fi
+
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+ # The user explicitly disabled X.
+ have_x=disabled
+else
+ if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then
+ # Both variables are already set.
+ have_x=yes
+ else
+if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=NO ac_x_libraries=NO
+rm -fr conftestdir
+if mkdir conftestdir; then
+ cd conftestdir
+ # Make sure to not put "make" in the Imakefile rules, since we grep it out.
+ cat > Imakefile <<'EOF'
+acfindx:
+ @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"'
+EOF
+ if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then
+ # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+ eval `${MAKE-make} acfindx 2>/dev/null | grep -v make`
+ # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+ for ac_extension in a so sl; do
+ if test ! -f $ac_im_usrlibdir/libX11.$ac_extension &&
+ test -f $ac_im_libdir/libX11.$ac_extension; then
+ ac_im_usrlibdir=$ac_im_libdir; break
+ fi
+ done
+ # Screen out bogus values from the imake configuration. They are
+ # bogus both because they are the default anyway, and because
+ # using them would break gcc on systems where it needs fixed includes.
+ case "$ac_im_incroot" in
+ /usr/include) ;;
+ *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;;
+ esac
+ case "$ac_im_usrlibdir" in
+ /usr/lib | /lib) ;;
+ *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;;
+ esac
+ fi
+ cd ..
+ rm -fr conftestdir
+fi
+
+if test "$ac_x_includes" = NO; then
+ # Guess where to find include files, by looking for this one X11 .h file.
+ test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+
+ # First, try using that file with no special directory specified.
+cat > conftest.$ac_ext <<EOF
+#line 8246 "configure"
+#include "confdefs.h"
+#include <$x_direct_test_include>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:8251: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ # Look for the header file in a standard set of common directories.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ for ac_dir in \
+ /usr/X11/include \
+ /usr/X11R6/include \
+ /usr/X11R5/include \
+ /usr/X11R4/include \
+ \
+ /usr/include/X11 \
+ /usr/include/X11R6 \
+ /usr/include/X11R5 \
+ /usr/include/X11R4 \
+ \
+ /usr/local/X11/include \
+ /usr/local/X11R6/include \
+ /usr/local/X11R5/include \
+ /usr/local/X11R4/include \
+ \
+ /usr/local/include/X11 \
+ /usr/local/include/X11R6 \
+ /usr/local/include/X11R5 \
+ /usr/local/include/X11R4 \
+ \
+ /usr/X386/include \
+ /usr/x386/include \
+ /usr/XFree86/include/X11 \
+ \
+ /usr/include \
+ /usr/local/include \
+ /usr/unsupported/include \
+ /usr/athena/include \
+ /usr/local/x11r5/include \
+ /usr/lpp/Xamples/include \
+ \
+ /usr/openwin/include \
+ /usr/openwin/share/include \
+ ; \
+ do
+ if test -r "$ac_dir/$x_direct_test_include"; then
+ ac_x_includes=$ac_dir
+ break
+ fi
+ done
+fi
+rm -f conftest*
+fi # $ac_x_includes = NO
+
+if test "$ac_x_libraries" = NO; then
+ # Check for the libraries.
+
+ test -z "$x_direct_test_library" && x_direct_test_library=Xt
+ test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
+
+ # See if we find them without any special options.
+ # Don't add to $LIBS permanently.
+ ac_save_LIBS="$LIBS"
+ LIBS="-l$x_direct_test_library $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 8320 "configure"
+#include "confdefs.h"
+
+int main() {
+${x_direct_test_function}()
+; return 0; }
+EOF
+if { (eval echo configure:8327: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ LIBS="$ac_save_LIBS"
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ LIBS="$ac_save_LIBS"
+# First see if replacing the include by lib works.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \
+ /usr/X11/lib \
+ /usr/X11R6/lib \
+ /usr/X11R5/lib \
+ /usr/X11R4/lib \
+ \
+ /usr/lib/X11 \
+ /usr/lib/X11R6 \
+ /usr/lib/X11R5 \
+ /usr/lib/X11R4 \
+ \
+ /usr/local/X11/lib \
+ /usr/local/X11R6/lib \
+ /usr/local/X11R5/lib \
+ /usr/local/X11R4/lib \
+ \
+ /usr/local/lib/X11 \
+ /usr/local/lib/X11R6 \
+ /usr/local/lib/X11R5 \
+ /usr/local/lib/X11R4 \
+ \
+ /usr/X386/lib \
+ /usr/x386/lib \
+ /usr/XFree86/lib/X11 \
+ \
+ /usr/lib \
+ /usr/local/lib \
+ /usr/unsupported/lib \
+ /usr/athena/lib \
+ /usr/local/x11r5/lib \
+ /usr/lpp/Xamples/lib \
+ /lib/usr/lib/X11 \
+ \
+ /usr/openwin/lib \
+ /usr/openwin/share/lib \
+ ; \
+do
+ for ac_extension in a so sl; do
+ if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then
+ ac_x_libraries=$ac_dir
+ break 2
+ fi
+ done
+done
+fi
+rm -f conftest*
+fi # $ac_x_libraries = NO
+
+if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then
+ # Didn't find X anywhere. Cache the known absence of X.
+ ac_cv_have_x="have_x=no"
+else
+ # Record where we found X for the cache.
+ ac_cv_have_x="have_x=yes \
+ ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
+fi
+fi
+ fi
+ eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+ echo "$ac_t""$have_x" 1>&6
+ no_x=yes
+else
+ # If each of the values was on the command line, it overrides each guess.
+ test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+ test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+ # Update the cache value to reflect the command line values.
+ ac_cv_have_x="have_x=yes \
+ ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
+ echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6
+fi
+
+
+
+# Unlike the sim directory, whether a simulator is linked is controlled by
+# presence of a SIM= and a SIM_OBS= definition in the target '.mt' file.
+# This code just checks for a few cases where we'd like to ignore those
+# definitions, even when they're present in the '.mt' file. These cases
+# are when --disable-sim is specified, or if the simulator directory is
+# not part of the source tree.
+#
+# Check whether --enable-sim or --disable-sim was given.
+if test "${enable_sim+set}" = set; then
+ enableval="$enable_sim"
+ echo "enable_sim = $enable_sim";
+ echo "enableval = ${enableval}";
+ case "${enableval}" in
+ yes) ignore_sim=false ;;
+ no) ignore_sim=true ;;
+ *) ignore_sim=false ;;
+ esac
+else
+ ignore_sim=false
+fi
+
+
+if test ! -d "${srcdir}/../sim"; then
+ ignore_sim=true
+fi
+
+if test "${ignore_sim}" = "true"; then
+ IGNORE_SIM="SIM="
+ IGNORE_SIM_OBS="SIM_OBS="
+else
+ IGNORE_SIM=""
+ IGNORE_SIM_OBS=""
+ cat >> confdefs.h <<\EOF
+#define WITH_SIM 1
+EOF
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Begin stuff to support --enable-shared
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ case "${enableval}" in
+ yes) shared=true ;;
+ no) shared=false ;;
+ *) shared=true ;;
+esac
+fi
+
+HLDFLAGS=
+HLDENV=
+# If we have shared libraries, try to set rpath reasonably.
+if test "${shared}" = "true"; then
+ case "${host}" in
+ *-*-hpux*)
+ HLDFLAGS='-Wl,+s,+b,$(libdir)'
+ ;;
+ *-*-irix5* | *-*-irix6*)
+ HLDFLAGS='-Wl,-rpath,$(libdir)'
+ ;;
+ *-*-linux*aout*)
+ ;;
+ *-*-linux* | *-pc-linux-gnu*)
+ HLDFLAGS='-Wl,-rpath,$(libdir)'
+ ;;
+ *-*-solaris*)
+ HLDFLAGS='-R $(libdir)'
+ ;;
+ *-*-sysv4*)
+ HLDENV='if test -z "$${LD_RUN_PATH}"; then LD_RUN_PATH=$(libdir); else LD_RUN_PATH=$${LD_RUN_PATH}:$(libdir); fi; export LD_RUN_PATH;'
+ ;;
+ esac
+fi
+
+# On SunOS, if the linker supports the -rpath option, use it to
+# prevent ../bfd and ../opcodes from being included in the run time
+# search path.
+case "${host}" in
+ *-*-sunos*)
+ echo 'main () { }' > conftest.c
+ ${CC} -o conftest -Wl,-rpath= conftest.c >/dev/null 2>conftest.t
+ if grep 'unrecognized' conftest.t >/dev/null 2>&1; then
+ :
+ elif grep 'No such file' conftest.t >/dev/null 2>&1; then
+ :
+ elif grep 'do not mix' conftest.t >/dev/null 2>&1; then
+ :
+ elif grep 'some text already loaded' conftest.t >/dev/null 2>&1; then
+ :
+ elif test "${shared}" = "true"; then
+ HLDFLAGS='-Wl,-rpath=$(libdir)'
+ else
+ HLDFLAGS='-Wl,-rpath='
+ fi
+ rm -f conftest.t conftest.c conftest
+ ;;
+esac
+
+
+# End stuff to support --enable-shared
+
+# target_subdir is used by the testsuite to find the target libraries.
+target_subdir=
+if test "${host}" != "${target}"; then
+ target_subdir="${target_alias}/"
+fi
+
+
+frags=
+host_makefile_frag=${srcdir}/config/${gdb_host_cpu}/${gdb_host}.mh
+if test ! -f ${host_makefile_frag}; then
+ # When building a native debuger the .mh file containing things
+ # like NATDEPFILES is needed. Cross debuggers don't need .mh
+ # since it no longer contains anything useful.
+ if test "${target}" = "${host}"; then
+ { echo "configure: error: "*** Gdb does not support native target ${host}"" 1>&2; exit 1; }
+ else
+ host_makefile_frag=/dev/null
+ fi
+fi
+frags="$frags $host_makefile_frag"
+
+target_makefile_frag=${srcdir}/config/${gdb_target_cpu}/${gdb_target}.mt
+if test ! -f ${target_makefile_frag}; then
+{ echo "configure: error: "*** Gdb does not support target ${target}"" 1>&2; exit 1; }
+fi
+frags="$frags $target_makefile_frag"
+
+
+
+
+
+hostfile=`sed -n '
+s/XM_FILE[ ]*=[ ]*\([^ ]*\)/\1/p
+' ${host_makefile_frag}`
+
+targetfile=`sed -n '
+s/TM_FILE[ ]*=[ ]*\([^ ]*\)/\1/p
+' ${target_makefile_frag}`
+
+GDB_MULTI_ARCH=`sed -n '
+s/GDB_MULTI_ARCH[ ]*=[ ]*\([^ ]*\)[ ]*/\1/p
+' ${target_makefile_frag}`
+
+if test "${target}" = "${host}"; then
+# We pick this up from the host configuration file (.mh) because we
+# do not have a native configuration Makefile fragment.
+nativefile=`sed -n '
+s/NAT_FILE[ ]*=[ ]*\([^ ]*\)/\1/p
+' ${host_makefile_frag}`
+fi
+
+
+# New targets should just set gdb_multi_arch=yes in configure.tgt.
+# Old targets being converted can either do that or set GDB_MULTI_ARCH
+# in the target specific makefile frag. Eventually gdb_multi_arch=yes
+# will be the default.
+if test x"${GDB_MULTI_ARCH}" = x ; then
+ case "${gdb_multi_arch}" in
+ yes ) GDB_MULTI_ARCH=GDB_MULTI_ARCH_PURE ;;
+ no ) GDB_MULTI_ARCH=0 ;;
+ 0|1|2 ) GDB_MULTI_ARCH=${gdb_multi_arch} ;;
+ esac
+fi
+if test x"${GDB_MULTI_ARCH}" != x ; then
+ cat >> confdefs.h <<EOF
+#define GDB_MULTI_ARCH ${GDB_MULTI_ARCH}
+EOF
+
+fi
+# Warn the user when they use an old practice
+case "${GDB_MULTI_ARCH}" in
+ "" ) ;;
+ 0 | GDB_MULTI_ARCH_PARTIAL | 1 | GDB_MULTI_ARCH_TM | 2 )
+ echo "configure: warning: "GDB: Target is not pure multi-arch"" 1>&2 ;;
+ GDB_MULTI_ARCH_PURE )
+ if test x"${targetfile}" != x ; then
+ echo "configure: warning: "GDB: Ignoring TM_FILE in ${target_makefile_frag}"" 1>&2
+ targetfile=""
+ fi ;;
+ *) { echo "configure: error: "GDB: Unknown GDB_MULTI_ARCH value ${GDB_MULTI_ARCH}"" 1>&2; exit 1; };;
+esac
+
+SUBDIRS="doc testsuite nlm"
+if test "${enable_multi_ice}" = "yes"; then
+ SUBDIRS="${SUBDIRS} multi-ice"
+fi
+
+# ``gdbserver'' can only be built in a native configuration.
+if test x"${target}" = x"${host}"; then
+ echo $ac_n "checking whether gdbserver is supported on this host""... $ac_c" 1>&6
+echo "configure:8620: checking whether gdbserver is supported on this host" >&5
+ if test x"${build_gdbserver}" = xyes ; then
+ configdirs="${configdirs} gdbserver"
+ SUBDIRS="${SUBDIRS} gdbserver"
+ echo "$ac_t""yes" 1>&6
+ else
+ echo "$ac_t""no" 1>&6
+ fi
+fi
+
+
+
+# If hostfile (XM_FILE) and/or targetfile (TM_FILE) and/or nativefile
+# (NAT_FILE) is not set in config/*/*.m[ht] files, we link to an empty
+# version.
+
+files=
+links=
+
+rm -f xm.h
+xm_h=""
+if test "${hostfile}" != ""; then
+ xm_h=xm.h
+ GDB_XM_FILE="config/${gdb_host_cpu}/${hostfile}"
+ files="${files} ${GDB_XM_FILE}"
+ links="${links} xm.h"
+ cat >> confdefs.h <<EOF
+#define GDB_XM_FILE ${GDB_XM_FILE}
+EOF
+
+fi
+
+
+rm -f tm.h
+tm_h=""
+if test "${targetfile}" != ""; then
+ tm_h=tm.h
+ GDB_TM_FILE="config/${gdb_target_cpu}/${targetfile}"
+ files="${files} ${GDB_TM_FILE}"
+ links="${links} tm.h"
+ cat >> confdefs.h <<EOF
+#define GDB_TM_FILE ${GDB_TM_FILE}
+EOF
+
+fi
+
+
+rm -f nm.h
+nm_h=""
+if test "${nativefile}" != ""; then
+ nm_h=nm.h
+ GDB_NM_FILE="config/${gdb_host_cpu}/${nativefile}"
+ files="${files} ${GDB_NM_FILE}"
+ links="${links} nm.h"
+ cat >> confdefs.h <<EOF
+#define GDB_NM_FILE ${GDB_NM_FILE}
+EOF
+
+fi
+
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:8682: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:8706: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8711 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:8722: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:8739: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8744 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:8751: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:8770: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:8780: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+
+subdirs="$configdirs"
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile .gdbinit:gdbinit.in config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@RANLIB@%$RANLIB%g
+s%@ALLOCA@%$ALLOCA%g
+s%@USE_NLS@%$USE_NLS%g
+s%@MSGFMT@%$MSGFMT%g
+s%@GMSGFMT@%$GMSGFMT%g
+s%@XGETTEXT@%$XGETTEXT%g
+s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g
+s%@CATALOGS@%$CATALOGS%g
+s%@CATOBJEXT@%$CATOBJEXT%g
+s%@DATADIRNAME@%$DATADIRNAME%g
+s%@GMOFILES@%$GMOFILES%g
+s%@INSTOBJEXT@%$INSTOBJEXT%g
+s%@INTLDEPS@%$INTLDEPS%g
+s%@INTLLIBS@%$INTLLIBS%g
+s%@INTLOBJS@%$INTLOBJS%g
+s%@POFILES@%$POFILES%g
+s%@POSUB@%$POSUB%g
+s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g
+s%@GT_NO@%$GT_NO%g
+s%@GT_YES@%$GT_YES%g
+s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g
+s%@l@%$l%g
+s%@AWK@%$AWK%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@AR@%$AR%g
+s%@DLLTOOL@%$DLLTOOL%g
+s%@WINDRES@%$WINDRES%g
+s%@YACC@%$YACC%g
+s%@MIG@%$MIG%g
+s%@CONFIG_LDFLAGS@%$CONFIG_LDFLAGS%g
+s%@UIOUT_CFLAGS@%$UIOUT_CFLAGS%g
+s%@WARN_CFLAGS@%$WARN_CFLAGS%g
+s%@WERROR_CFLAGS@%$WERROR_CFLAGS%g
+s%@MMALLOC_CFLAGS@%$MMALLOC_CFLAGS%g
+s%@MMALLOC@%$MMALLOC%g
+s%@REGEX@%$REGEX%g
+s%@SER_HARDWIRE@%$SER_HARDWIRE%g
+s%@TERM_LIB@%$TERM_LIB%g
+s%@WIN32LIBS@%$WIN32LIBS%g
+s%@LIBGUI@%$LIBGUI%g
+s%@GUI_CFLAGS_X@%$GUI_CFLAGS_X%g
+s%@WIN32LDAPP@%$WIN32LDAPP%g
+s%@TCL_VERSION@%$TCL_VERSION%g
+s%@TCL_MAJOR_VERSION@%$TCL_MAJOR_VERSION%g
+s%@TCL_MINOR_VERSION@%$TCL_MINOR_VERSION%g
+s%@TCL_CC@%$TCL_CC%g
+s%@TCL_DEFS@%$TCL_DEFS%g
+s%@TCL_SHLIB_CFLAGS@%$TCL_SHLIB_CFLAGS%g
+s%@TCL_SHLIB_LD@%$TCL_SHLIB_LD%g
+s%@TCL_SHLIB_LD_LIBS@%$TCL_SHLIB_LD_LIBS%g
+s%@TCL_SHLIB_SUFFIX@%$TCL_SHLIB_SUFFIX%g
+s%@TCL_DL_LIBS@%$TCL_DL_LIBS%g
+s%@TCL_LD_FLAGS@%$TCL_LD_FLAGS%g
+s%@TCL_LD_SEARCH_FLAGS@%$TCL_LD_SEARCH_FLAGS%g
+s%@TCL_COMPAT_OBJS@%$TCL_COMPAT_OBJS%g
+s%@TCL_RANLIB@%$TCL_RANLIB%g
+s%@TCL_BUILD_LIB_SPEC@%$TCL_BUILD_LIB_SPEC%g
+s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g
+s%@TCL_LIB_VERSIONS_OK@%$TCL_LIB_VERSIONS_OK%g
+s%@TK_VERSION@%$TK_VERSION%g
+s%@TK_DEFS@%$TK_DEFS%g
+s%@TK_BUILD_INCLUDES@%$TK_BUILD_INCLUDES%g
+s%@TK_XINCLUDES@%$TK_XINCLUDES%g
+s%@TK_XLIBSW@%$TK_XLIBSW%g
+s%@TK_BUILD_LIB_SPEC@%$TK_BUILD_LIB_SPEC%g
+s%@TK_LIB_SPEC@%$TK_LIB_SPEC%g
+s%@TCLHDIR@%$TCLHDIR%g
+s%@TKHDIR@%$TKHDIR%g
+s%@ITCLHDIR@%$ITCLHDIR%g
+s%@ITKHDIR@%$ITKHDIR%g
+s%@TIXHDIR@%$TIXHDIR%g
+s%@ITCL_VERSION@%$ITCL_VERSION%g
+s%@ITCL_DEFS@%$ITCL_DEFS%g
+s%@ITCL_BUILD_INCLUDES@%$ITCL_BUILD_INCLUDES%g
+s%@ITCL_BUILD_LIB_SPEC@%$ITCL_BUILD_LIB_SPEC%g
+s%@ITCL_LIB_SPEC@%$ITCL_LIB_SPEC%g
+s%@ITK_VERSION@%$ITK_VERSION%g
+s%@ITK_DEFS@%$ITK_DEFS%g
+s%@ITK_BUILD_INCLUDES@%$ITK_BUILD_INCLUDES%g
+s%@ITK_BUILD_LIB_SPEC@%$ITK_BUILD_LIB_SPEC%g
+s%@ITK_LIB_SPEC@%$ITK_LIB_SPEC%g
+s%@TIX_VERSION@%$TIX_VERSION%g
+s%@TIX_BUILD_LIB_SPEC@%$TIX_BUILD_LIB_SPEC%g
+s%@X_CFLAGS@%$X_CFLAGS%g
+s%@X_LDFLAGS@%$X_LDFLAGS%g
+s%@X_LIBS@%$X_LIBS%g
+s%@TCL_DEPS@%$TCL_DEPS%g
+s%@TK_DEPS@%$TK_DEPS%g
+s%@ITCLLIB@%$ITCLLIB%g
+s%@ITCL_DEPS@%$ITCL_DEPS%g
+s%@ITKLIB@%$ITKLIB%g
+s%@ITK_DEPS@%$ITK_DEPS%g
+s%@TIXLIB@%$TIXLIB%g
+s%@TIX_DEPS@%$TIX_DEPS%g
+s%@GDBTKLIBS@%$GDBTKLIBS%g
+s%@GDBTK_CFLAGS@%$GDBTK_CFLAGS%g
+s%@GDBTK_SRC_DIR@%$GDBTK_SRC_DIR%g
+s%@IGNORE_SIM@%$IGNORE_SIM%g
+s%@IGNORE_SIM_OBS@%$IGNORE_SIM_OBS%g
+s%@ENABLE_CFLAGS@%$ENABLE_CFLAGS%g
+s%@CONFIG_OBS@%$CONFIG_OBS%g
+s%@CONFIG_LIB_OBS@%$CONFIG_LIB_OBS%g
+s%@CONFIG_DEPS@%$CONFIG_DEPS%g
+s%@CONFIG_SRCS@%$CONFIG_SRCS%g
+s%@CONFIG_INITS@%$CONFIG_INITS%g
+s%@CONFIG_ALL@%$CONFIG_ALL%g
+s%@CONFIG_CLEAN@%$CONFIG_CLEAN%g
+s%@CONFIG_INSTALL@%$CONFIG_INSTALL%g
+s%@CONFIG_UNINSTALL@%$CONFIG_UNINSTALL%g
+s%@HLDFLAGS@%$HLDFLAGS%g
+s%@HLDENV@%$HLDENV%g
+s%@target_subdir@%$target_subdir%g
+/@host_makefile_frag@/r $host_makefile_frag
+s%@host_makefile_frag@%%g
+/@target_makefile_frag@/r $target_makefile_frag
+s%@target_makefile_frag@%%g
+s%@frags@%$frags%g
+s%@SUBDIRS@%$SUBDIRS%g
+s%@xm_h@%$xm_h%g
+s%@tm_h@%$tm_h%g
+s%@nm_h@%$nm_h%g
+s%@LN_S@%$LN_S%g
+s%@EXEEXT@%$EXEEXT%g
+s%@subdirs@%$subdirs%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile .gdbinit:gdbinit.in"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+ac_sources="$files"
+ac_dests="$links"
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+srcdir=$ac_given_srcdir
+while test -n "$ac_sources"; do
+ set $ac_dests; ac_dest=$1; shift; ac_dests=$*
+ set $ac_sources; ac_source=$1; shift; ac_sources=$*
+
+ echo "linking $srcdir/$ac_source to $ac_dest"
+
+ if test ! -r $srcdir/$ac_source; then
+ { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; }
+ fi
+ rm -f $ac_dest
+
+ # Make relative symlinks.
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then
+ # The dest file is in a subdirectory.
+ test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir"
+ ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dest_dir_suffix.
+ ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dest_dir_suffix= ac_dots=
+ fi
+
+ case "$srcdir" in
+ [/$]*) ac_rel_source="$srcdir/$ac_source" ;;
+ *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;;
+ esac
+
+ # Make a symlink if possible; otherwise try a hard link.
+ if ln -s $ac_rel_source $ac_dest 2>/dev/null ||
+ ln $srcdir/$ac_source $ac_dest; then :
+ else
+ { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; }
+ fi
+done
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+gdb_host_cpu=$gdb_host_cpu
+gdb_target_cpu=$gdb_target_cpu
+nativefile=$nativefile
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+if test "${nativefile}" = ""; then
+ < Makefile \
+ sed -e '/^NATDEPFILES[ ]*=.*\\$/,/[^\\]$/s/^/# /' \
+ -e '/^NATDEPFILES[ ]*=/s/^/# /' \
+ | sed -e '/^\(NATDEPFILES[ ]*[+]=[ ]*\)/s//# \1/' \
+ > Makefile.tem
+mv -f Makefile.tem Makefile
+fi
+
+sed -e '/^TM_FILE[ ]*=/s,^TM_FILE[ ]*=[ ]*,&config/'"${gdb_target_cpu}"'/,
+/^XM_FILE[ ]*=/s,^XM_FILE[ ]*=[ ]*,&config/'"${gdb_host_cpu}"'/,
+/^NAT_FILE[ ]*=/s,^NAT_FILE[ ]*=[ ]*,&config/'"${gdb_host_cpu}"'/,' <Makefile >Makefile.tmp
+mv -f Makefile.tmp Makefile
+
+
+case x$CONFIG_HEADERS in
+xconfig.h:config.in)
+echo > stamp-h ;;
+esac
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+if test "$no_recursion" != yes; then
+
+ # Remove --cache-file and --srcdir arguments so they do not pile up.
+ ac_sub_configure_args=
+ ac_prev=
+ for ac_arg in $ac_configure_args; do
+ if test -n "$ac_prev"; then
+ ac_prev=
+ continue
+ fi
+ case "$ac_arg" in
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ ;;
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ ;;
+ *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;;
+ esac
+ done
+
+ for ac_config_dir in $configdirs; do
+
+ # Do not complain, so a configure script can configure whichever
+ # parts of a large source tree are present.
+ if test ! -d $srcdir/$ac_config_dir; then
+ continue
+ fi
+
+ echo configuring in $ac_config_dir
+
+ case "$srcdir" in
+ .) ;;
+ *)
+ if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :;
+ else
+ { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; }
+ fi
+ ;;
+ esac
+
+ ac_popdir=`pwd`
+ cd $ac_config_dir
+
+ # A "../" for each directory in /$ac_config_dir.
+ ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
+
+ case "$srcdir" in
+ .) # No --srcdir option. We are building in place.
+ ac_sub_srcdir=$srcdir ;;
+ /*) # Absolute path.
+ ac_sub_srcdir=$srcdir/$ac_config_dir ;;
+ *) # Relative path.
+ ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;;
+ esac
+
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_sub_srcdir/configure; then
+ ac_sub_configure=$ac_sub_srcdir/configure
+ elif test -f $ac_sub_srcdir/configure.in; then
+ ac_sub_configure=$ac_configure
+ else
+ echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2
+ ac_sub_configure=
+ fi
+
+ # The recursion is here.
+ if test -n "$ac_sub_configure"; then
+
+ # Make the cache file name correct relative to the subdirectory.
+ case "$cache_file" in
+ /*) ac_sub_cache_file=$cache_file ;;
+ *) # Relative path.
+ ac_sub_cache_file="$ac_dots$cache_file" ;;
+ esac
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir"
+ # The eval makes quoting arguments work.
+ if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir
+ then :
+ else
+ { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; }
+ fi
+ fi
+
+ cd $ac_popdir
+ done
+fi
+
+
+exit 0
diff --git a/gdb/configure.host b/gdb/configure.host
new file mode 100644
index 00000000000..16f6a52c164
--- /dev/null
+++ b/gdb/configure.host
@@ -0,0 +1,167 @@
+# Mapping of configurations into GDB host definitions. This is
+# invoked from the autoconf generated configure script.
+
+# This file sets the following shell variables:
+# gdb_host_cpu generic name of host's CPU
+# gdb_host name of GDB host definition to use
+
+# Map host cpu into the config cpu subdirectory name.
+# The default is $host_cpu.
+
+case "${host_cpu}" in
+
+alpha*) gdb_host_cpu=alpha ;;
+arm*) gdb_host_cpu=arm ;;
+hppa*) gdb_host_cpu=pa ;;
+i[3456]86*) gdb_host_cpu=i386 ;;
+m68*) gdb_host_cpu=m68k ;;
+m88*) gdb_host_cpu=m88k ;;
+mips*) gdb_host_cpu=mips ;;
+powerpc*) gdb_host_cpu=powerpc ;;
+sparcv9 | sparc64) gdb_host_cpu=sparc ;;
+s390*) gdb_host_cpu=s390 ;;
+sh*) gdb_host_cpu=sh ;;
+x86_64*) gdb_host_cpu=i386 ;;
+*) gdb_host_cpu=$host_cpu ;;
+
+esac
+
+# map host info into gdb names.
+
+case "${host}" in
+
+alpha*-*-osf1*) gdb_host=alpha-osf1 ;;
+alpha*-*-osf2*) gdb_host=alpha-osf2 ;;
+alpha*-*-osf[3456789]*) gdb_host=alpha-osf3 ;;
+alpha*-*-linux*) gdb_host=alpha-linux ;;
+alpha*-*-freebsd*) gdb_host=fbsd ;;
+alpha*-*-netbsd*) gdb_host=nbsd ;;
+
+arm*-*-linux*) gdb_host=linux ;;
+arm*-*-netbsdelf*) gdb_host=nbsdelf ;;
+arm*-*-netbsd*) gdb_host=nbsdaout ;;
+arm*-*-*) gdb_host=arm ;;
+
+hppa*-*-bsd*) gdb_host=hppabsd ;;
+hppa*-*-hiux*) gdb_host=hppahpux ;;
+hppa*-*-hpux10.20) gdb_host=hpux1020 ;;
+hppa*64*-*-hpux11*) gdb_host=hpux11w ;;
+hppa*-*-hpux11*) gdb_host=hpux11 ;;
+hppa*-*-hpux*) gdb_host=hppahpux ;;
+hppa*-*-osf*) gdb_host=hppaosf ;;
+
+i[3456]86-ncr-*) gdb_host=ncr3000 ;;
+i[3456]86-sequent-bsd*) gdb_host=symmetry ;; # dynix
+i[3456]86-sequent-sysv4*) gdb_host=ptx4 ;;
+i[3456]86-sequent-sysv*) gdb_host=ptx ;;
+i[3456]86-*-aix*) gdb_host=i386aix ;;
+i[3456]86-*-bsd*) gdb_host=i386bsd ;;
+i[3456]86-*-dgux*) gdb_host=i386dgux ;;
+i[3456]86-*-freebsd*) gdb_host=fbsd ;;
+i[3456]86-*-netbsdelf*) gdb_host=nbsdelf ;;
+i[3456]86-*-netbsdaout*) gdb_host=nbsdaout ;;
+i[3456]86-*-netbsd*) gdb_host=nbsdaout ;;
+i[3456]86-*-go32*) gdb_host=go32 ;;
+i[3456]86-*-msdosdjgpp*) gdb_host=go32 ;;
+i[3456]86-*-linux*) gdb_host=linux ;;
+i[3456]86-*-lynxos*) gdb_host=i386lynx ;;
+i[3456]86-*-mach3*) gdb_host=i386m3 ;;
+i[3456]86-*-mach*) gdb_host=i386mach ;;
+i[3456]86-*-gnu*) gdb_host=i386gnu ;;
+i[3456]86-*-openbsd*) gdb_host=obsd ;;
+i[3456]86-*-osf1mk*) gdb_host=i386mk ;;
+i[3456]86-*-sco3.2v5*) gdb_host=i386sco5 ;;
+i[3456]86-*-sco3.2v4*) gdb_host=i386sco4 ;;
+i[3456]86-*-sco*) gdb_host=i386sco ;;
+i[3456]86-*-solaris*) gdb_host=i386sol2 ;;
+i[3456]86-*-sysv3.2*) gdb_host=i386v32 ;;
+i[3456]86-*-sysv32*) gdb_host=i386v32 ;;
+i[3456]86-*-sysv4.2*) gdb_host=i386v42mp ;;
+i[3456]86-*-sysv4*) gdb_host=i386v4 ;;
+i[3456]86-*-sysv5*) gdb_host=i386v42mp ;;
+i[3456]86-*-unixware2*) gdb_host=i386v42mp ;;
+i[3456]86-*-unixware*) gdb_host=i386v4 ;;
+i[3456]86-*-sysv*) gdb_host=i386v ;;
+i[3456]86-*-isc*) gdb_host=i386v32 ;;
+i[3456]86-*-cygwin*) gdb_host=cygwin ;;
+
+ia64-*-aix*) gdb_host=aix ;;
+ia64-*-linux*) gdb_host=linux ;;
+
+m680[01]0-sun-sunos3*) gdb_host=sun2os3 ;;
+m680[01]0-sun-sunos4*) gdb_host=sun2os4 ;;
+
+m68*-apollo*-sysv*) gdb_host=apollo68v ;;
+m68*-apollo*-bsd*) gdb_host=apollo68b ;;
+m68*-att-*) gdb_host=3b1 ;;
+m68*-bull*-sysv*) gdb_host=dpx2 ;;
+m68*-hp-bsd*) gdb_host=hp300bsd ;;
+m68*-hp-hpux*) gdb_host=hp300hpux ;;
+m68*-*-linux*) gdb_host=linux ;;
+m68*-*-lynxos*) gdb_host=m68klynx ;;
+m68*-*-netbsd*) gdb_host=nbsdaout ;;
+m68*-*-sysv4*) gdb_host=m68kv4 ;;
+m68*-motorola-*) gdb_host=delta68 ;;
+m68*-sun-sunos3*) gdb_host=sun3os3 ;;
+m68*-sun-sunos4*) gdb_host=sun3os4 ;;
+m68*-sun-*) gdb_host=sun3os4 ;;
+
+m88*-motorola-sysv4*) gdb_host=delta88v4 ;;
+m88*-motorola-sysv*) gdb_host=delta88 ;;
+m88*-*-*) gdb_host=m88k ;;
+
+mips-dec-mach3*) gdb_host=mipsm3 ;;
+mips-dec-*) gdb_host=decstation ;;
+mips-little-*) gdb_host=littlemips ;;
+mips-sgi-irix3*) gdb_host=irix3 ;;
+mips-sgi-irix4*) gdb_host=irix4 ;;
+mips-sgi-irix5*) gdb_host=irix5 ;;
+mips-sgi-irix6*) gdb_host=irix6 ;;
+mips-sony-*) gdb_host=news-mips ;;
+mips*-*-linux*) gdb_host=linux ;;
+mips*-*-netbsd*) gdb_host=nbsd ;;
+mips-*-mach3*) gdb_host=mipsm3 ;;
+mips-*-sysv4*) gdb_host=mipsv4 ;;
+mips-*-sysv*) gdb_host=riscos ;;
+mips-*-riscos*) gdb_host=riscos ;;
+
+none-*-*) gdb_host=none ;;
+
+ns32k-*-netbsd*) gdb_host=nbsdaout ;;
+
+powerpc-*-aix*) gdb_host=aix ;;
+powerpc-*-linux*) gdb_host=linux ;;
+powerpc-*-netbsd*) gdb_host=nbsd ;;
+
+rs6000-*-lynxos*) gdb_host=rs6000lynx ;;
+rs6000-*-aix4*) gdb_host=aix4 ;;
+rs6000-*-*) gdb_host=rs6000 ;;
+
+s390*-*-*) gdb_host=s390 ;;
+
+sh*-*-netbsdelf*) gdb_host=nbsd ;;
+
+sparc-*-linux*) gdb_host=linux ;;
+sparc-*-lynxos*) gdb_host=sparclynx ;;
+sparc-*-netbsdelf*) gdb_host=nbsdelf ;;
+sparc-*-netbsdaout*) gdb_host=nbsdaout ;;
+sparc-*-netbsd*) gdb_host=nbsdaout ;;
+sparc-*-solaris2*) gdb_host=sun4sol2 ;;
+sparc-*-sunos4*) gdb_host=sun4os4 ;;
+sparc-*-sunos5*) gdb_host=sun4sol2 ;;
+sparc-*-*) gdb_host=sun4os4 ;;
+sparc64-*-freebsd*|ultrasparc-*-freebsd*|sparcv9-*-freebsd*)
+ gdb_host=fbsd ;;
+sparc64-*-linux*) gdb_host=linux ;;
+sparcv9-*-* | sparc64-*-*) gdb_host=sun4sol2 ;;
+
+strongarm-*-*) gdb_host=arm ;;
+xscale-*-*) gdb_host=arm ;;
+
+vax-*-bsd*) gdb_host=vaxbsd ;;
+vax-*-ultrix2*) gdb_host=vaxult2 ;;
+vax-*-ultrix*) gdb_host=vaxult ;;
+
+x86_64-*-linux*) gdb_host=x86-64linux ;;
+
+esac
diff --git a/gdb/configure.in b/gdb/configure.in
new file mode 100644
index 00000000000..8d304594f3a
--- /dev/null
+++ b/gdb/configure.in
@@ -0,0 +1,1395 @@
+dnl Autoconf configure script for GDB, the GNU debugger.
+dnl Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+dnl Free Software Foundation, Inc.
+dnl
+dnl This file is part of GDB.
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+dnl Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.13)dnl
+AC_INIT(main.c)
+AC_CONFIG_HEADER(config.h:config.in)
+AM_MAINTAINER_MODE
+
+AC_PROG_CC
+AC_AIX
+AC_ISC_POSIX
+AM_PROG_CC_STDC
+
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/..)
+AC_CANONICAL_SYSTEM
+
+dnl gdb doesn't use gettext, but bfd does. We call this to ensure we
+dnl link with the correct libraries.
+ALL_LINGUAS=
+CY_GNU_GETTEXT
+
+dnl List of object files added by configure.
+
+CONFIG_OBS=
+CONFIG_LIB_OBS=
+CONFIG_DEPS=
+CONFIG_SRCS=
+CONFIG_INITS=
+ENABLE_CFLAGS=
+CONFIG_ALL=
+CONFIG_CLEAN=
+CONFIG_INSTALL=
+CONFIG_UNINSTALL=
+
+configdirs="doc testsuite"
+
+AC_ARG_ENABLE(multi-ice,
+[ --enable-multi-ice Build the multi-ice-gdb-server],
+[case "${enableval}" in
+ yes ) enable_multi_ice="yes" ;;
+ no) enable_multi_ice="no" ;;
+ *) AC_MSG_ERROR(Bad value for --enable-multi-ice: ${enableval}) ;;
+ esac
+])
+
+if test "${enable_multi_ice}" = "yes"; then
+ configdirs="${configdirs} multi-ice"
+fi
+
+dnl
+changequote(,)dnl
+
+. ${srcdir}/configure.host
+
+. ${srcdir}/configure.tgt
+
+targ=${target} ; . ${srcdir}/../bfd/config.bfd
+
+dnl
+changequote([,])dnl
+
+dnl use BFD to determine the default architecture and byte order
+dnl (bfd_vec->byteorder provides the latter).
+targ=${target}
+. ${srcdir}/../bfd/config.bfd
+
+dnl We only want the first arch, if there is more than one.
+targ_archs=`echo ${targ_archs} | sed -e 's/ .*//;'`
+
+if test x"${targ_archs}" != x ; then
+ AC_DEFINE_UNQUOTED(DEFAULT_BFD_ARCH, ${targ_archs})
+fi
+if test x"${targ_defvec}" != x ; then
+ AC_DEFINE_UNQUOTED(DEFAULT_BFD_VEC, ${targ_defvec})
+fi
+
+AC_PROG_AWK
+AC_PROG_INSTALL
+AC_CHECK_TOOL(AR, ar)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(DLLTOOL, dlltool)
+AC_CHECK_TOOL(WINDRES, windres)
+AC_PROG_YACC
+
+dnl MiG is needed for the Hurd.
+AC_CHECK_TOOL(MIG, mig)
+
+AC_ARG_PROGRAM
+
+AC_TYPE_SIGNAL
+
+AC_HEADER_STDC
+
+dnl Solaris 7 needs _MSE_INT_H defined to avoid a clash between <widec.h>
+dnl and <wchar.h> that causes AC_CHECK_HEADERS to think <curses.h> doesn't
+dnl exist.
+
+case $host_os in solaris2.7 | solaris2.8) case "$GCC" in yes)
+ AC_DEFINE(_MSE_INT_H)
+esac; esac
+
+AC_CHECK_HEADERS(ctype.h nlist.h link.h thread_db.h proc_service.h \
+ memory.h objlist.h ptrace.h sgtty.h stddef.h stdlib.h \
+ string.h sys/procfs.h sys/ptrace.h sys/reg.h stdint.h \
+ term.h termio.h termios.h unistd.h wait.h sys/wait.h \
+ wchar.h wctype.h asm/debugreg.h sys/debugreg.h sys/select.h \
+ time.h sys/file.h sys/ioctl.h sys/user.h sys/fault.h sys/syscall.h \
+ dirent.h sys/ndir.h sys/dir.h ndir.h sys/filio.h \
+ curses.h ncurses.h \
+ poll.h sys/poll.h)
+AC_HEADER_STAT
+
+AC_C_CONST
+AC_C_INLINE
+
+AC_CHECK_FUNCS(bcopy btowc bzero canonicalize_file_name isascii poll \
+ realpath sbrk setpgid setpgrp sigaction sigprocmask sigsetmask )
+AC_FUNC_ALLOCA
+AC_FUNC_VFORK
+dnl AC_FUNC_SETPGRP does not work when cross compiling
+dnl Instead, assume we will have a prototype for setpgrp if cross compiling.
+if test "$cross_compiling" = no; then
+ AC_FUNC_SETPGRP
+else
+ AC_CACHE_CHECK([whether setpgrp takes no argument], ac_cv_func_setpgrp_void,
+ [AC_TRY_COMPILE([
+#include <unistd.h>
+], [
+ if (setpgrp(1,1) == -1)
+ exit (0);
+ else
+ exit (1);
+], ac_cv_func_setpgrp_void=no, ac_cv_func_setpgrp_void=yes)])
+if test $ac_cv_func_setpgrp_void = yes; then
+ AC_DEFINE(SETPGRP_VOID, 1)
+fi
+fi
+
+# Check if sigsetjmp is available. Using AC_CHECK_FUNCS won't do
+# since sigsetjmp might only be defined as a macro.
+AC_CACHE_CHECK([for sigsetjmp], gdb_cv_func_sigsetjmp,
+[AC_TRY_COMPILE([
+#include <setjmp.h>
+], [sigjmp_buf env; while (! sigsetjmp (env, 1)) siglongjmp (env, 1);],
+gdb_cv_func_sigsetjmp=yes, gdb_cv_func_sigsetjmp=no)])
+if test $gdb_cv_func_sigsetjmp = yes; then
+ AC_DEFINE(HAVE_SIGSETJMP, 1, [Define if sigsetjmp is available. ])
+fi
+
+# See if <machine/reg.h> supports the %fs and %gs i386 segment registers.
+# Older i386 BSD's don't have the r_fs and r_gs members of `struct reg'.
+AC_CACHE_CHECK([for r_fs in struct reg], gdb_cv_struct_reg_r_fs,
+[AC_TRY_COMPILE([#include <machine/reg.h>], [struct reg r; r.r_fs;],
+gdb_cv_struct_reg_r_fs=yes, gdb_cv_struct_reg_r_fs=no)])
+if test $gdb_cv_struct_reg_r_fs = yes; then
+ AC_DEFINE(HAVE_STRUCT_REG_R_FS)
+fi
+AC_CACHE_CHECK([for r_gs in struct reg], gdb_cv_struct_reg_r_gs,
+[AC_TRY_COMPILE([#include <machine/reg.h>], [struct reg r; r.r_gs;],
+gdb_cv_struct_reg_r_gs=yes, gdb_cv_struct_reg_r_gs=no)])
+if test $gdb_cv_struct_reg_r_gs = yes; then
+ AC_DEFINE(HAVE_STRUCT_REG_R_GS)
+fi
+
+# See if <sys/ptrace.h> provides the PTRACE_GETREGS request.
+AC_MSG_CHECKING(for PTRACE_GETREGS)
+AC_CACHE_VAL(gdb_cv_have_ptrace_getregs,
+[AC_TRY_COMPILE([#include <sys/ptrace.h>],
+ [PTRACE_GETREGS;],
+ [gdb_cv_have_ptrace_getregs=yes],
+ [gdb_cv_have_ptrace_getregs=no])])
+AC_MSG_RESULT($gdb_cv_have_ptrace_getregs)
+if test $gdb_cv_have_ptrace_getregs = yes; then
+ AC_DEFINE(HAVE_PTRACE_GETREGS)
+fi
+
+# See if <sys/ptrace.h> provides the PTRACE_GETFPXREGS request.
+AC_MSG_CHECKING(for PTRACE_GETFPXREGS)
+AC_CACHE_VAL(gdb_cv_have_ptrace_getfpxregs,
+[AC_TRY_COMPILE([#include <sys/ptrace.h>],
+ [PTRACE_GETFPXREGS;],
+ [gdb_cv_have_ptrace_getfpxregs=yes],
+ [gdb_cv_have_ptrace_getfpxregs=no])])
+AC_MSG_RESULT($gdb_cv_have_ptrace_getfpxregs)
+if test $gdb_cv_have_ptrace_getfpxregs = yes; then
+ AC_DEFINE(HAVE_PTRACE_GETFPXREGS)
+fi
+
+# See if <sys/ptrace.h> provides the PT_GETDBREGS request.
+AC_MSG_CHECKING(for PT_GETDBREGS)
+AC_CACHE_VAL(gdb_cv_have_pt_getdbregs,
+[AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/ptrace.h>],
+ [PT_GETDBREGS;],
+ [gdb_cv_have_pt_getdbregs=yes],
+ [gdb_cv_have_pt_getdbregs=no])])
+AC_MSG_RESULT($gdb_cv_have_pt_getdbregs)
+if test $gdb_cv_have_pt_getdbregs = yes; then
+ AC_DEFINE(HAVE_PT_GETDBREGS)
+fi
+
+# See if <sys/ptrace.h> provides the PT_GETXMMREGS request.
+AC_MSG_CHECKING(for PT_GETXMMREGS)
+AC_CACHE_VAL(gdb_cv_have_pt_getxmmregs,
+[AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/ptrace.h>],
+ [PT_GETXMMREGS;],
+ [gdb_cv_have_pt_getxmmregs=yes],
+ [gdb_cv_have_pt_getxmmregs=no])])
+AC_MSG_RESULT($gdb_cv_have_pt_getxmmregs)
+if test $gdb_cv_have_pt_getxmmregs = yes; then
+ AC_DEFINE(HAVE_PT_GETXMMREGS)
+fi
+
+
+AC_CHECK_LIB(socket, socketpair)
+AC_CHECK_FUNCS(socketpair)
+
+
+BFD_NEED_DECLARATION(malloc)
+BFD_NEED_DECLARATION(realloc)
+BFD_NEED_DECLARATION(free)
+BFD_NEED_DECLARATION(strerror)
+BFD_NEED_DECLARATION(strdup)
+BFD_NEED_DECLARATION(strstr)
+BFD_NEED_DECLARATION(canonicalize_file_name)
+
+# The following save_state_t checkery is only necessary for HPUX
+# versions earlier than 10.20. When those fade from memory, this
+# could be expunged. --jsm 1999-03-22
+
+AC_MSG_CHECKING(for HPUX save_state structure)
+AC_EGREP_HEADER(save_state_t, machine/save_state.h,
+ gdb_cv_hpux_savestate=yes, gdb_cv_hpux_savestate=no)
+AC_EGREP_HEADER(ss_wide, machine/save_state.h, gdb_cv_hpux_sswide=yes,
+ gdb_cv_hpux_sswide=no)
+if test $gdb_cv_hpux_savestate = yes
+then
+ AC_DEFINE(HAVE_STRUCT_SAVE_STATE_T, 1)
+fi
+if test $gdb_cv_hpux_sswide = yes
+then
+ AC_DEFINE(HAVE_STRUCT_MEMBER_SS_WIDE, 1)
+fi
+AC_MSG_RESULT($gdb_cv_hpux_sswide)
+
+
+# If we are configured native on GNU/Linux, work around problems with
+# sys/procfs.h
+# Also detect which type of /proc is in use, such as for Unixware or Solaris.
+
+if test "${target}" = "${host}"; then
+ case "${host}" in
+ i[[3456]]86-*-linux*)
+ AC_DEFINE(START_INFERIOR_TRAPS_EXPECTED,2)
+ AC_DEFINE(sys_quotactl)
+ ;;
+ ia64-*-aix*)
+ AC_DEFINE(NEW_PROC_API)
+ ;;
+ *-*-unixware* | *-*-sysv4.2* | *-*-sysv5*)
+ AC_DEFINE(NEW_PROC_API)
+ ;;
+ *-*-solaris2.[[678]])
+ AC_DEFINE(NEW_PROC_API)
+ ;;
+ esac
+fi
+
+if test "$ac_cv_header_sys_procfs_h" = yes; then
+ BFD_HAVE_SYS_PROCFS_TYPE(pstatus_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(prrun_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(gregset_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(fpregset_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(prgregset_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(prfpregset_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(prgregset32_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(prfpregset32_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(lwpid_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(psaddr_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(prsysent_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(pr_sigset_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(pr_sigaction64_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(pr_siginfo64_t)
+
+
+ dnl Check for broken prfpregset_t type
+
+ dnl For Linux/i386, glibc 2.1.3 was released with a bogus
+ dnl prfpregset_t type (it's a typedef for the pointer to a struct
+ dnl instead of the struct itself). We detect this here, and work
+ dnl around it in gdb_proc_service.h.
+
+ if test $bfd_cv_have_sys_procfs_type_prfpregset_t = yes; then
+ AC_MSG_CHECKING(whether prfpregset_t type is broken)
+ AC_CACHE_VAL(gdb_cv_prfpregset_t_broken,
+ [AC_TRY_RUN([#include <sys/procfs.h>
+ int main ()
+ {
+ if (sizeof (prfpregset_t) == sizeof (void *))
+ return 1;
+ return 0;
+ }],
+ gdb_cv_prfpregset_t_broken=no,
+ gdb_cv_prfpregset_t_broken=yes,
+ gdb_cv_prfpregset_t_broken=yes)])
+ AC_MSG_RESULT($gdb_cv_prfpregset_t_broken)
+ if test $gdb_cv_prfpregset_t_broken = yes; then
+ AC_DEFINE(PRFPREGSET_T_BROKEN)
+ fi
+ fi
+
+ dnl Check for PIOCSET ioctl entry
+
+ AC_MSG_CHECKING(for PIOCSET ioctl entry in sys/procfs.h)
+ AC_CACHE_VAL(gdb_cv_have_procfs_piocset,
+ [AC_TRY_COMPILE([#include <unistd.h>
+#include <sys/types.h>
+#include <sys/procfs.h>
+], [
+ int dummy;;
+ dummy = ioctl(0, PIOCSET, &dummy);
+ ],
+ gdb_cv_have_procfs_piocset=yes, gdb_cv_have_procfs_piocset=no)])
+ AC_MSG_RESULT($gdb_cv_have_procfs_piocset)
+ if test $gdb_cv_have_procfs_piocset = yes; then
+ AC_DEFINE(HAVE_PROCFS_PIOCSET)
+ fi
+fi
+
+dnl For native ports (host == target), check to see what kind of
+dnl legacy link.h support is needed. (See solib-legacy.c.)
+if test ${host} = ${target} ; then
+ dnl Check for struct link_map with l_ members which are indicative
+ dnl of SVR4-like shared libraries
+
+ AC_MSG_CHECKING(for member l_addr in struct link_map)
+ AC_CACHE_VAL(gdb_cv_have_struct_link_map_with_l_members,
+ [AC_TRY_COMPILE([#include <link.h>],
+ [struct link_map lm; (void) lm.l_addr;],
+ gdb_cv_have_struct_link_map_with_l_members=yes,
+ gdb_cv_have_struct_link_map_with_l_members=no)])
+ AC_MSG_RESULT($gdb_cv_have_struct_link_map_with_l_members)
+ if test $gdb_cv_have_struct_link_map_with_l_members = yes; then
+ AC_DEFINE(HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS)
+ fi
+
+ dnl Check for struct link_map with lm_ members which are indicative
+ dnl of SunOS-like shared libraries
+
+ AC_MSG_CHECKING(for member lm_addr in struct link_map)
+ AC_CACHE_VAL(gdb_cv_have_struct_link_map_with_lm_members,
+ [AC_TRY_COMPILE([#include <sys/types.h>
+#include <link.h>],
+ [struct link_map lm; (void) lm.lm_addr;],
+ gdb_cv_have_struct_link_map_with_lm_members=yes,
+ gdb_cv_have_struct_link_map_with_lm_members=no)])
+ AC_MSG_RESULT($gdb_cv_have_struct_link_map_with_lm_members)
+ if test $gdb_cv_have_struct_link_map_with_lm_members = yes; then
+ AC_DEFINE(HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS)
+ fi
+
+ dnl Check for struct so_map with som_ members which are found on
+ dnl some *BSD systems.
+
+ AC_MSG_CHECKING(for member som_addr in struct so_map)
+ AC_CACHE_VAL(gdb_cv_have_struct_so_map_with_som_members,
+ [AC_TRY_COMPILE([#include <sys/types.h>
+#ifdef HAVE_NLIST_H
+#include <nlist.h>
+#endif
+#include <link.h>],
+ [struct so_map lm; (void) lm.som_addr;],
+ gdb_cv_have_struct_so_map_with_som_members=yes,
+ gdb_cv_have_struct_so_map_with_som_members=no)])
+ AC_MSG_RESULT($gdb_cv_have_struct_so_map_with_som_members)
+ if test $gdb_cv_have_struct_so_map_with_som_members = yes; then
+ AC_DEFINE(HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS)
+ fi
+
+ dnl Check for struct link_map32 type, which allows a 64-bit Solaris
+ dnl debugger to debug a 32-bit Solaris app with 32-bit shared libraries.
+
+ AC_MSG_CHECKING(for struct link_map32 in sys/link.h)
+ AC_CACHE_VAL(gdb_cv_have_struct_link_map32,
+ [AC_TRY_COMPILE([#define _SYSCALL32
+#include <sys/link.h>], [struct link_map32 l;],
+ gdb_cv_have_struct_link_map32=yes,
+ gdb_cv_have_struct_link_map32=no)])
+ AC_MSG_RESULT($gdb_cv_have_struct_link_map32)
+ if test $gdb_cv_have_struct_link_map32 = yes; then
+ AC_DEFINE(HAVE_STRUCT_LINK_MAP32)
+ AC_DEFINE(_SYSCALL32)
+ fi
+fi
+
+dnl See if host has libm. This is usually needed by simulators.
+AC_CHECK_LIB(m, main)
+
+dnl Solaris puts wctype in /usr/lib/libw.a before Solaris 2.6.
+dnl
+dnl A bug in GNU ld 2.9.1 causes a problem if we link in -lw
+dnl under Solaris 2.6 because it is some funky empty library.
+dnl So only link in libw if we have to.
+AC_CHECK_LIB(c, wctype,: ,AC_CHECK_LIB(w, wctype))
+
+dnl See if compiler supports "long long" type.
+
+AC_MSG_CHECKING(for long long support in compiler)
+AC_CACHE_VAL(gdb_cv_c_long_long,
+[AC_TRY_COMPILE(, [
+ extern long long foo;
+ switch (foo & 2) { case 0: return 1; }
+],
+gdb_cv_c_long_long=yes, gdb_cv_c_long_long=no)])
+AC_MSG_RESULT($gdb_cv_c_long_long)
+if test $gdb_cv_c_long_long = yes; then
+ AC_DEFINE(CC_HAS_LONG_LONG)
+fi
+
+dnl See if the compiler and runtime support printing long long
+
+AC_MSG_CHECKING(for long long support in printf)
+AC_CACHE_VAL(gdb_cv_printf_has_long_long,
+[AC_TRY_RUN([
+int main () {
+ char buf[32];
+ long long l = 0;
+ l = (l << 16) + 0x0123;
+ l = (l << 16) + 0x4567;
+ l = (l << 16) + 0x89ab;
+ l = (l << 16) + 0xcdef;
+ sprintf (buf, "0x%016llx", l);
+ return (strcmp ("0x0123456789abcdef", buf));
+}],
+gdb_cv_printf_has_long_long=yes,
+gdb_cv_printf_has_long_long=no,
+gdb_cv_printf_has_long_long=no)])
+if test $gdb_cv_printf_has_long_long = yes; then
+ AC_DEFINE(PRINTF_HAS_LONG_LONG)
+fi
+AC_MSG_RESULT($gdb_cv_printf_has_long_long)
+
+dnl See if compiler supports "long double" type. Can't use AC_C_LONG_DOUBLE
+dnl because autoconf complains about cross-compilation issues. However, this
+dnl code uses the same variables as the macro for compatibility.
+
+AC_MSG_CHECKING(for long double support in compiler)
+AC_CACHE_VAL(ac_cv_c_long_double,
+[AC_TRY_COMPILE(, [long double foo;],
+ac_cv_c_long_double=yes, ac_cv_c_long_double=no)])
+AC_MSG_RESULT($ac_cv_c_long_double)
+if test $ac_cv_c_long_double = yes; then
+ AC_DEFINE(HAVE_LONG_DOUBLE)
+fi
+
+dnl See if the compiler and runtime support printing long doubles
+
+AC_MSG_CHECKING(for long double support in printf)
+AC_CACHE_VAL(gdb_cv_printf_has_long_double,
+[AC_TRY_RUN([
+int main () {
+ char buf[16];
+ long double f = 3.141592653;
+ sprintf (buf, "%Lg", f);
+ return (strncmp ("3.14159", buf, 7));
+}],
+gdb_cv_printf_has_long_double=yes,
+gdb_cv_printf_has_long_double=no,
+gdb_cv_printf_has_long_double=no)])
+if test $gdb_cv_printf_has_long_double = yes; then
+ AC_DEFINE(PRINTF_HAS_LONG_DOUBLE)
+fi
+AC_MSG_RESULT($gdb_cv_printf_has_long_double)
+
+dnl See if the compiler and runtime support scanning long doubles
+
+AC_MSG_CHECKING(for long double support in scanf)
+AC_CACHE_VAL(gdb_cv_scanf_has_long_double,
+[AC_TRY_RUN([
+int main () {
+ char *buf = "3.141592653";
+ long double f = 0;
+ sscanf (buf, "%Lg", &f);
+ return !(f > 3.14159 && f < 3.14160);
+}],
+gdb_cv_scanf_has_long_double=yes,
+gdb_cv_scanf_has_long_double=no,
+gdb_cv_scanf_has_long_double=no)])
+if test $gdb_cv_scanf_has_long_double = yes; then
+ AC_DEFINE(SCANF_HAS_LONG_DOUBLE)
+fi
+AC_MSG_RESULT($gdb_cv_scanf_has_long_double)
+
+AC_FUNC_MMAP
+
+case ${host_os} in
+aix*)
+ AC_CACHE_CHECK([for -bbigtoc option], [gdb_cv_bigtoc], [
+ SAVE_LDFLAGS=$LDFLAGS
+
+ case $GCC in
+ yes) gdb_cv_bigtoc=-Wl,-bbigtoc ;;
+ *) gdb_cv_bigtoc=-bbigtoc ;;
+ esac
+
+ LDFLAGS=$LDFLAGS\ $gdb_cv_bigtoc
+ AC_TRY_LINK([], [int i;], [], [gdb_cv_bigtoc=])
+ ])
+ CONFIG_LDFLAGS="${CONFIG_LDFLAGS} ${gdb_cv_bigtoc}"
+ ;;
+esac
+
+dnl See if thread_db library is around for Solaris thread debugging. Note that
+dnl we must explicitly test for version 1 of the library because version 0
+dnl (present on Solaris 2.4 or earlier) doesn't have the same API.
+
+dnl Note that we only want this if we are both native (host == target), and
+dnl not doing a canadian cross build (build == host).
+
+if test ${build} = ${host} -a ${host} = ${target} ; then
+ case ${host_os} in
+ hpux*)
+ AC_MSG_CHECKING(for HPUX/OSF thread support)
+ if test -f /usr/include/dce/cma_config.h ; then
+ if test "$GCC" = "yes" ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_HPUX_THREAD_SUPPORT)
+ CONFIG_LIB_OBS="${CONFIG_LIB_OBS} hpux-thread.o"
+ CONFIG_SRCS="${CONFIG_SRCS} hpux-thread.c"
+ else
+ AC_MSG_RESULT(no (suppressed because you are not using GCC))
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+ ;;
+ solaris*)
+ AC_MSG_CHECKING(for Solaris thread debugging library)
+ if test -f /usr/lib/libthread_db.so.1 ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_THREAD_DB_LIB)
+ CONFIG_LIB_OBS="${CONFIG_LIB_OBS} sol-thread.o"
+ CONFIG_SRCS="${CONFIG_SRCS} sol-thread.c"
+ AC_CHECK_LIB(dl, dlopen)
+ if test "$GCC" = "yes" ; then
+ # The GNU linker requires the -export-dynamic option to make
+ # all symbols visible in the dynamic symbol table.
+ hold_ldflags=$LDFLAGS
+ AC_MSG_CHECKING(for the ld -export-dynamic flag)
+ LDFLAGS="${LDFLAGS} -Wl,-export-dynamic"
+ AC_TRY_LINK(, [int i;], found=yes, found=no)
+ LDFLAGS=$hold_ldflags
+ AC_MSG_RESULT($found)
+ if test $found = yes; then
+ CONFIG_LDFLAGS="${CONFIG_LDFLAGS} -Wl,-export-dynamic"
+ fi
+ fi
+ # Sun randomly tweaked the prototypes in <proc_service.h>
+ # at one point.
+ AC_MSG_CHECKING(if <proc_service.h> is old)
+ AC_CACHE_VAL(gdb_cv_proc_service_is_old,[
+ AC_TRY_COMPILE([
+ #include <proc_service.h>
+ ps_err_e ps_pdwrite
+ (struct ps_prochandle*, psaddr_t, const void*, size_t);
+ ],, gdb_cv_proc_service_is_old=no,
+ gdb_cv_proc_service_is_old=yes)
+ ])
+ AC_MSG_RESULT($gdb_cv_proc_service_is_old)
+ if test $gdb_cv_proc_service_is_old = yes; then
+ AC_DEFINE(PROC_SERVICE_IS_OLD)
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+ ;;
+ esac
+ AC_SUBST(CONFIG_LDFLAGS)
+fi
+
+dnl The CLI cannot be disabled yet, but may be in the future
+
+dnl Handle CLI sub-directory configury.
+AC_ARG_ENABLE(gdbcli,
+[ --enable-gdbcli Enable GDB-CLI interface],
+[
+ case "${enableval}" in
+ yes) enable_gdbcli=yes ;;
+ "") enable_gdbcli=yes ;;
+ no)
+ AC_MSG_ERROR(The CLI cannot be disabled yet)
+ ;;
+ *)
+ AC_MSG_ERROR(Bad value for --enable-gdbcli: ${enableval})
+ ;;
+ esac
+],
+[enable_gdbcli=yes])
+case ${enable_gdbcli} in
+ "yes" )
+ if test -d "${srcdir}/cli" ; then
+ CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_CLI_OBS)"
+ CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_CLI_DEPS)"
+ CONFIG_SRCS="${CONFIG_SRCS} \$(SUBDIR_CLI_SRCS)"
+ CONFIG_INITS="${CONFIG_INITS} \$(SUBDIR_CLI_INITS)"
+ ENABLE_CFLAGS="${ENABLE_CFLAGS} \$(SUBDIR_CLI_CFLAGS)"
+ CONFIG_ALL="${CONFIG_ALL} \$(SUBDIR_CLI_ALL)"
+ CONFIG_CLEAN="${CONFIG_CLEAN} \$(SUBDIR_CLI_CLEAN)"
+ CONFIG_INSTALL="${CONFIG_INSTALL} \$(SUBDIR_CLI_INSTALL)"
+ CONFIG_UNINSTALL="${CONFIG_UNINSTALL} \$(SUBDIR_CLI_UNINSTALL)"
+ fi
+ ;;
+esac
+
+dnl Handle optional features that can be enabled.
+
+dnl Handle MI sub-directory configury.
+AC_ARG_ENABLE(gdbmi,
+[ --enable-gdbmi Enable GDB-MI interface],
+[
+ case "${enable_gdbmi}" in
+ yes | no) ;;
+ "") enable_gdbmi=yes ;;
+ *)
+ AC_MSG_ERROR(Bad value for --enable-gdbmi: ${enableval})
+ ;;
+ esac
+],
+[enable_gdbmi=yes])
+case ${enable_gdbmi} in
+ "yes" )
+ if test -d "${srcdir}/mi" ; then
+ CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_MI_OBS)"
+ CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_MI_DEPS)"
+ CONFIG_SRCS="${CONFIG_SRCS} \$(SUBDIR_MI_SRCS)"
+ CONFIG_INITS="${CONFIG_INITS} \$(SUBDIR_MI_INITS)"
+ ENABLE_CFLAGS="${ENABLE_CFLAGS} \$(SUBDIR_MI_CFLAGS)"
+ CONFIG_ALL="${CONFIG_ALL} \$(SUBDIR_MI_ALL)"
+ CONFIG_CLEAN="${CONFIG_CLEAN} \$(SUBDIR_MI_CLEAN)"
+ CONFIG_INSTALL="${CONFIG_INSTALL} \$(SUBDIR_MI_INSTALL)"
+ CONFIG_UNINSTALL="${CONFIG_UNINSTALL} \$(SUBDIR_MI_UNINSTALL)"
+ fi
+ ;;
+esac
+
+# Configure UI_OUT by default (before 5.2 it can be disabled)
+# It must be configured if gdbmi is configured
+
+UIOUT_CFLAGS=
+AC_SUBST(UIOUT_CFLAGS)
+
+AC_ARG_WITH(uiout,
+[ --with-uiout Use new uiout functions instead of *printf's],
+[case "${withval}" in
+ yes) want_uiout=true ;;
+ no) if test $enable_gdbmi = yes; then
+ AC_MSG_ERROR(uiout is needed for MI and cannot be disabled)
+ else
+ want_uiout=false
+ fi ;;
+ *) AC_MSG_ERROR(bad value ${withval} for GDB with-uiout option) ;;
+esac],
+[want_uiout=true])dnl
+
+if test $want_uiout = true; then
+ UIOUT_CFLAGS="-DUI_OUT=1"
+fi
+
+AC_ARG_ENABLE(tui,
+[ --enable-tui Enable full-screen terminal user interface],
+[
+ case "${enable_tui}" in
+ yes | no) ;;
+ "") enable_tui=yes ;;
+ *)
+ AC_MSG_ERROR(Bad value for --enable-tui: ${enableval})
+ ;;
+ esac
+])
+case ${enable_tui} in
+ "yes" )
+ if test -d "${srcdir}/tui" ; then
+ CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_TUI_OBS)"
+ CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_TUI_DEPS)"
+ CONFIG_SRCS="${CONFIG_SRCS} \$(SUBDIR_TUI_SRCS)"
+ CONFIG_INITS="${CONFIG_INITS} \$(SUBDIR_TUI_INITS)"
+ ENABLE_CFLAGS="${ENABLE_CFLAGS} \$(SUBDIR_TUI_CFLAGS)"
+ CONFIG_ALL="${CONFIG_ALL} \$(SUBDIR_TUI_ALL)"
+ CONFIG_CLEAN="${CONFIG_CLEAN} \$(SUBDIR_TUI_CLEAN)"
+ CONFIG_INSTALL="${CONFIG_INSTALL} \$(SUBDIR_TUI_INSTALL)"
+ CONFIG_UNINSTALL="${CONFIG_UNINSTALL} \$(SUBDIR_TUI_UNINSTALL)"
+ fi
+ ;;
+esac
+
+AC_ARG_ENABLE(netrom,
+[ --enable-netrom Enable NetROM support],
+[case "${enableval}" in
+yes) enable_netrom=yes ;;
+no) enable_netrom=no ;;
+*) AC_MSG_ERROR(bad value ${enableval} given for netrom option) ;;
+esac])
+
+if test "${enable_netrom}" = "yes"; then
+ CONFIG_LIB_OBS="${CONFIG_LIB_OBS} remote-nrom.o"
+ CONFIG_SRCS="${CONFIG_SRCS} remote-nrom.c"
+fi
+
+
+# NOTE: Don't add -Wall or -Wunused, they both include
+# -Wunused-parameter which reports bogus warnings.
+# NOTE: If you add to this list, remember to update
+# gdb/doc/gdbint.texinfo.
+build_warnings="-Wimplicit -Wreturn-type -Wcomment -Wtrigraphs \
+-Wformat -Wparentheses -Wpointer-arith -Wuninitialized"
+# Up for debate: -Wswitch -Wcomment -trigraphs -Wtrigraphs
+# -Wunused-function -Wunused-label -Wunused-variable -Wunused-value
+# -Wchar-subscripts -Wtraditional -Wshadow -Wcast-qual
+# -Wcast-align -Wwrite-strings -Wconversion -Wstrict-prototypes
+# -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls
+# -Woverloaded-virtual -Winline -Werror"
+AC_ARG_ENABLE(build-warnings,
+[ --enable-build-warnings Enable build-time compiler warnings if gcc is used],
+[case "${enableval}" in
+ yes) ;;
+ no) build_warnings="-w";;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${build_warnings} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${t} ${build_warnings}";;
+ *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then
+ echo "Setting compiler warning flags = $build_warnings" 6>&1
+fi])dnl
+AC_ARG_ENABLE(gdb-build-warnings,
+[ --enable-gdb-build-warnings Enable GDB specific build-time compiler warnings if gcc is used],
+[case "${enableval}" in
+ yes) ;;
+ no) build_warnings="-w";;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${build_warnings} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${t} ${build_warnings}";;
+ *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then
+ echo "Setting GDB specific compiler warning flags = $build_warnings" 6>&1
+fi])dnl
+WARN_CFLAGS=""
+WERROR_CFLAGS=""
+if test "x${build_warnings}" != x -a "x$GCC" = xyes
+then
+ AC_MSG_CHECKING(compiler warning flags)
+ # Separate out the -Werror flag as some files just cannot be
+ # compiled with it enabled.
+ for w in ${build_warnings}; do
+ case $w in
+ -Werr*) WERROR_CFLAGS=-Werror ;;
+ *) # Check that GCC accepts it
+ saved_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $w"
+ AC_TRY_COMPILE([],[],WARN_CFLAGS="${WARN_CFLAGS} $w",)
+ CFLAGS="$saved_CFLAGS"
+ esac
+ done
+ AC_MSG_RESULT(${WARN_CFLAGS}${WERROR_CFLAGS})
+fi
+AC_SUBST(WARN_CFLAGS)
+AC_SUBST(WERROR_CFLAGS)
+
+MMALLOC_CFLAGS=
+MMALLOC=
+AC_SUBST(MMALLOC_CFLAGS)
+AC_SUBST(MMALLOC)
+
+AC_ARG_WITH(mmalloc,
+[ --with-mmalloc Use memory mapped malloc package],
+[case "${withval}" in
+ yes) want_mmalloc=true ;;
+ no) want_mmalloc=false;;
+ *) AC_MSG_ERROR(bad value ${withval} for GDB with-mmalloc option) ;;
+esac],[want_mmalloc=false])dnl
+
+if test x$want_mmalloc = xtrue; then
+ AC_DEFINE(USE_MMALLOC)
+ AC_DEFINE(MMCHECK_FORCE)
+ MMALLOC_CFLAGS="-I$srcdir/../mmalloc"
+ MMALLOC='../mmalloc/libmmalloc.a'
+fi
+
+AC_ARG_WITH(included-regex,
+[ --with-included-regex Use included regex],
+[case "${withval}" in
+ yes) want_included_regex=true ;;
+ no) want_included_regex=false;;
+ *) AC_MSG_ERROR(bad value ${withval} for GDB with-included-regex option) ;;
+esac],[want_included_regex=true])dnl
+
+if test $want_included_regex = false; then
+ AC_MSG_CHECKING(for GNU regex)
+ AC_CACHE_VAL(gdb_cv_have_gnu_regex,
+[AC_TRY_COMPILE([#include <gnu-versions.h>
+#include <sys/types.h>
+#include <regex.h>],
+[#if !defined _GNU_REGEX_INTERFACE_VERSION || !defined __GLIBC__ || __GLIBC__ < 2
+#error No valid GNU regex.
+#endif
+],
+ [gdb_cv_have_gnu_regex=yes],
+ [gdb_cv_have_gnu_regex=no])])
+ AC_MSG_RESULT($gdb_cv_have_gnu_regex)
+ if test $gdb_cv_have_gnu_regex = no; then
+ want_included_regex=true
+ fi
+fi
+
+if test x${want_included_regex} = xtrue; then
+ REGEX="gnu-regex.o"
+ AC_DEFINE(USE_INCLUDED_REGEX)
+fi
+AC_SUBST(REGEX)
+
+# In the Cygwin environment, we need some additional flags.
+AC_CACHE_CHECK([for cygwin], gdb_cv_os_cygwin,
+[AC_EGREP_CPP(lose, [
+#if defined (__CYGWIN__) || defined (__CYGWIN32__)
+lose
+#endif],[gdb_cv_os_cygwin=yes],[gdb_cv_os_cygwin=no])])
+
+
+dnl Figure out which of the many generic ser-*.c files the _host_ supports.
+SER_HARDWIRE="ser-unix.o ser-pipe.o ser-tcp.o"
+case ${host} in
+ *go32* ) SER_HARDWIRE=ser-go32.o ;;
+ *djgpp* ) SER_HARDWIRE=ser-go32.o ;;
+esac
+AC_SUBST(SER_HARDWIRE)
+
+
+dnl Figure out which term library to use.
+if test x$gdb_host = xgo32; then
+ TERM_LIB=
+else
+if test x$gdb_cv_os_cygwin = xyes; then
+ TERM_LIB='`if test -r ../libtermcap/libtermcap.a; then echo ../libtermcap/libtermcap.a; else echo -ltermcap; fi`'
+else
+ TERM_LIB=
+ AC_CHECK_LIB(ncurses, tgetent, TERM_LIB=-lncurses,
+ AC_CHECK_LIB(Hcurses, tgetent, TERM_LIB=-lHcurses,
+ AC_CHECK_LIB(termlib, tgetent, TERM_LIB=-ltermlib,
+ AC_CHECK_LIB(termcap, tgetent, TERM_LIB=-ltermcap,
+ AC_CHECK_LIB(curses, tgetent, TERM_LIB=-lcurses,
+ AC_CHECK_LIB(terminfo, tgetent, TERM_LIB=-lterminfo))))))
+
+ if test "x$TERM_LIB" = x
+ then
+ AC_MSG_ERROR(Could not find a term library, e.g. termcap or termlib!)
+ fi
+fi
+fi
+AC_SUBST(TERM_LIB)
+
+# libreadline needs libuser32.a in a cygwin environment
+WIN32LIBS=
+if test x$gdb_cv_os_cygwin = xyes; then
+ WIN32LIBS="-luser32"
+ case "${target}" in
+ *cygwin*) WIN32LIBS="$WIN32LIBS -limagehlp"
+ ;;
+ esac
+fi
+AC_SUBST(WIN32LIBS)
+
+LIBGUI="../libgui/src/libgui.a"
+GUI_CFLAGS_X="-I${srcdir}/../libgui/src"
+AC_SUBST(LIBGUI)
+AC_SUBST(GUI_CFLAGS_X)
+
+AC_ARG_WITH(cpu,
+[ --with-cpu=CPU Set the default CPU variant to debug],
+[case "${target}" in
+ powerpc-* | powerpcle-* )
+ ## It would be nice to keep this table in sync with the one in
+ ## gcc/configure.
+ case "${with_cpu}" in
+ ppc-uisa | rs6000 | 403 | 403GC | 505 | 860 | 601 | 602 | 603 \
+ | 604 | 750 )
+ ## Those are all handled in variants in rs6000-tdep.c, so they're fine.
+ ;;
+ common | power | power2 | rios | rios1 | rios2 | rsc | rsc1 )
+ ## These are all RS6000 variants, as far as GDB is concerned.
+ with_cpu=rs6000
+ ;;
+ 603e | ec603e )
+ with_cpu=603
+ ;;
+ 604e )
+ with_cpu=604
+ ;;
+ * )
+ AC_MSG_WARN(GDB: unknown --with-cpu value: \`${with_cpu}'; using \`ppc-uisa'.)
+ with_cpu=ppc-uisa
+ ;;
+ esac
+ ;;
+ * )
+ AC_MSG_WARN(GDB may ignore the --with-cpu flag for ${target} targets)
+ ;;
+esac
+AC_DEFINE_UNQUOTED(TARGET_CPU_DEFAULT, "${with_cpu}")
+],)
+
+
+AC_ARG_ENABLE(gdbtk,
+[ --enable-gdbtk Enable GDBTK GUI front end],
+[case "${enableval}" in
+ yes)
+ case "$host" in
+ *go32*)
+ AC_MSG_WARN([GDB does not support GDBtk on host ${host}. GDBtk will be disabled.])
+ enable_gdbtk=no ;;
+ *windows*)
+ AC_MSG_WARN([GDB does not support GDBtk on host ${host}. GDBtk will be disabled.])
+ enable_gdbtk=no ;;
+ *)
+ enable_gdbtk=yes ;;
+ esac ;;
+ no)
+ enable_gdbtk=no ;;
+ *)
+ AC_MSG_ERROR(bad value ${enableval} given for gdbtk option) ;;
+esac],
+[
+# Default is on for everything but go32 and Cygwin
+case "$host" in
+ *go32* | *windows*)
+ ;;
+ *)
+ if test -d "${srcdir}/gdbtk" ; then
+ enable_gdbtk=yes
+ fi
+ ;;
+esac
+])
+
+WIN32LDAPP=
+AC_SUBST(WIN32LIBS)
+AC_SUBST(WIN32LDAPP)
+
+configdir="unix"
+
+GDBTKLIBS=
+if test "${enable_gdbtk}" = "yes"; then
+
+ # Gdbtk must have an absolute path to srcdir in order to run
+ # properly when not installed.
+ here=`pwd`
+ cd ${srcdir}
+ GDBTK_SRC_DIR=`pwd`
+ cd $here
+
+ CY_AC_PATH_TCLCONFIG
+ if test -z "${no_tcl}"; then
+ CY_AC_LOAD_TCLCONFIG
+ CY_AC_PATH_TKCONFIG
+
+ # now look for Tcl library stuff
+
+ case "${host}" in
+ *-*-cygwin*)
+ tcldir=../tcl/win/
+ ;;
+ *)
+ tcldir=../tcl/unix/
+ ;;
+ esac
+
+ TCL_DEPS="${tcldir}${TCL_LIB_FILE}"
+
+ # If $no_tk is nonempty, then we can't do Tk, and there is no
+ # point to doing Tcl.
+ if test -z "${no_tk}"; then
+ CY_AC_LOAD_TKCONFIG
+ CY_AC_PATH_TCLH
+ CY_AC_PATH_TKH
+ CY_AC_PATH_ITCLH
+ CY_AC_PATH_ITKH
+ CY_AC_PATH_TIXH
+
+
+ # now look for Tk library stuff
+
+ case "${host}" in
+ *-*-cygwin*)
+ tkdir=../tk/win/
+ ;;
+ *)
+ tkdir=../tk/unix/
+ ;;
+ esac
+
+ TK_DEPS="${tkdir}${TK_LIB_FILE}"
+
+ # now look for Itcl library stuff
+
+ CY_AC_PATH_ITCLCONFIG
+ if test -z "${no_itcl}"; then
+ CY_AC_LOAD_ITCLCONFIG
+
+ ITCLLIB="${ITCL_BUILD_LIB_SPEC}"
+ ITCL_DEPS="${ITCL_LIB_FULL_PATH}"
+ fi
+
+
+ # now look for Itk library stuff
+ CY_AC_PATH_ITKCONFIG
+ if test -z "${no_itcl}"; then
+ CY_AC_LOAD_ITKCONFIG
+
+ ITKLIB="${ITK_BUILD_LIB_SPEC}"
+ ITK_DEPS="${ITK_LIB_FULL_PATH}"
+ fi
+
+ # now look for Tix library stuff
+ CY_AC_PATH_TIXCONFIG
+ if test -z "${no_tix}"; then
+ CY_AC_LOAD_TIXCONFIG
+ TIXLIB="${TIX_BUILD_LIB_SPEC}"
+ TIX_DEPS="${TIX_BUILD_LOCATION}/${TIX_LIB_FILE}"
+ fi
+
+ ENABLE_CFLAGS="${ENABLE_CFLAGS} \$(SUBDIR_GDBTK_CFLAGS)"
+ # Tcl/Tk 8.1 require -fwritable strings. I don't
+ # know whether 8.2 will or not, but I bet it will.
+ # I don't have to worry about 7.x since we don't support it.
+ GDBTK_CFLAGS=""
+ if test "$GCC" = "yes"; then
+ if test "$TCL_VERSION" != "8.0" ; then
+ GDBTK_CFLAGS="-fwritable-strings"
+ fi
+ fi
+
+ # Include some libraries that Tcl and Tk want.
+ TCL_LIBS='$(LIBGUI) $(ITCL) $(ITK) $(TIX) $(TK) $(TCL) $(X11_LDFLAGS) $(X11_LIBS)'
+ # Yes, the ordering seems wrong here. But it isn't.
+ # TK_LIBS is the list of libraries that need to be linked
+ # after Tcl/Tk. Note that this isn't put into LIBS. If it
+ # were in LIBS then any link tests after this point would
+ # try to include things like `$(LIBGUI)', which wouldn't work.
+ GDBTKLIBS="${TCL_LIBS} ${TK_LIBS}"
+
+ CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_GDBTK_OBS)"
+ CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_GDBTK_DEPS)"
+ CONFIG_SRCS="${CONFIG_SRCS} \$(SUBDIR_GDBTK_SRCS)"
+ CONFIG_INITS="${CONFIG_INITS} \$(SUBDIR_GDBTK_INITS)"
+ CONFIG_ALL="${CONFIG_ALL} \$(SUBDIR_GDBTK_ALL)"
+ CONFIG_CLEAN="${CONFIG_CLEAN} \$(SUBDIR_GDBTK_CLEAN)"
+ CONFIG_INSTALL="${CONFIG_INSTALL} \$(SUBDIR_GDBTK_INSTALL)"
+ CONFIG_UNINSTALL="${CONFIG_UNINSTALL} \$(SUBDIR_GDBTK_UNINSTALL)"
+
+ if test x$gdb_cv_os_cygwin = xyes; then
+ WIN32LIBS="${WIN32LIBS} -lshell32 -lgdi32 -lcomdlg32 -ladvapi32"
+ WIN32LDAPP="-Wl,--subsystem,console"
+ CONFIG_OBS="${CONFIG_OBS} gdbres.o"
+ fi
+ fi
+ fi
+fi
+
+AC_SUBST(X_CFLAGS)
+AC_SUBST(X_LDFLAGS)
+AC_SUBST(X_LIBS)
+AC_SUBST(TCL_DEPS)
+AC_SUBST(TK_DEPS)
+AC_SUBST(ITCLLIB)
+AC_SUBST(ITCL_DEPS)
+AC_SUBST(ITKLIB)
+AC_SUBST(ITK_DEPS)
+AC_SUBST(TIXLIB)
+AC_SUBST(TIX_DEPS)
+AC_SUBST(GDBTKLIBS)
+AC_SUBST(GDBTK_CFLAGS)
+AC_SUBST(GDBTK_SRC_DIR)
+
+AC_PATH_X
+
+
+# Unlike the sim directory, whether a simulator is linked is controlled by
+# presence of a SIM= and a SIM_OBS= definition in the target '.mt' file.
+# This code just checks for a few cases where we'd like to ignore those
+# definitions, even when they're present in the '.mt' file. These cases
+# are when --disable-sim is specified, or if the simulator directory is
+# not part of the source tree.
+#
+AC_ARG_ENABLE(sim,
+[ --enable-sim Link gdb with simulator],
+[echo "enable_sim = $enable_sim";
+ echo "enableval = ${enableval}";
+ case "${enableval}" in
+ yes) ignore_sim=false ;;
+ no) ignore_sim=true ;;
+ *) ignore_sim=false ;;
+ esac],
+[ignore_sim=false])
+
+if test ! -d "${srcdir}/../sim"; then
+ ignore_sim=true
+fi
+
+if test "${ignore_sim}" = "true"; then
+ IGNORE_SIM="SIM="
+ IGNORE_SIM_OBS="SIM_OBS="
+else
+ IGNORE_SIM=""
+ IGNORE_SIM_OBS=""
+ AC_DEFINE(WITH_SIM)
+fi
+AC_SUBST(IGNORE_SIM)
+AC_SUBST(IGNORE_SIM_OBS)
+
+AC_SUBST(ENABLE_CFLAGS)
+
+AC_SUBST(CONFIG_OBS)
+AC_SUBST(CONFIG_LIB_OBS)
+AC_SUBST(CONFIG_DEPS)
+AC_SUBST(CONFIG_SRCS)
+AC_SUBST(CONFIG_INITS)
+AC_SUBST(CONFIG_ALL)
+AC_SUBST(CONFIG_CLEAN)
+AC_SUBST(CONFIG_INSTALL)
+AC_SUBST(CONFIG_UNINSTALL)
+
+# Begin stuff to support --enable-shared
+AC_ARG_ENABLE(shared,
+[ --enable-shared Use shared libraries],
+[case "${enableval}" in
+ yes) shared=true ;;
+ no) shared=false ;;
+ *) shared=true ;;
+esac])dnl
+
+HLDFLAGS=
+HLDENV=
+# If we have shared libraries, try to set rpath reasonably.
+if test "${shared}" = "true"; then
+ case "${host}" in
+ *-*-hpux*)
+ HLDFLAGS='-Wl,+s,+b,$(libdir)'
+ ;;
+ *-*-irix5* | *-*-irix6*)
+ HLDFLAGS='-Wl,-rpath,$(libdir)'
+ ;;
+ *-*-linux*aout*)
+ ;;
+ *-*-linux* | *-pc-linux-gnu*)
+ HLDFLAGS='-Wl,-rpath,$(libdir)'
+ ;;
+ *-*-solaris*)
+ HLDFLAGS='-R $(libdir)'
+ ;;
+ *-*-sysv4*)
+ HLDENV='if test -z "$${LD_RUN_PATH}"; then LD_RUN_PATH=$(libdir); else LD_RUN_PATH=$${LD_RUN_PATH}:$(libdir); fi; export LD_RUN_PATH;'
+ ;;
+ esac
+fi
+
+# On SunOS, if the linker supports the -rpath option, use it to
+# prevent ../bfd and ../opcodes from being included in the run time
+# search path.
+case "${host}" in
+ *-*-sunos*)
+ echo 'main () { }' > conftest.c
+ ${CC} -o conftest -Wl,-rpath= conftest.c >/dev/null 2>conftest.t
+ if grep 'unrecognized' conftest.t >/dev/null 2>&1; then
+ :
+ elif grep 'No such file' conftest.t >/dev/null 2>&1; then
+ :
+ elif grep 'do not mix' conftest.t >/dev/null 2>&1; then
+ :
+ elif grep 'some text already loaded' conftest.t >/dev/null 2>&1; then
+ :
+ elif test "${shared}" = "true"; then
+ HLDFLAGS='-Wl,-rpath=$(libdir)'
+ else
+ HLDFLAGS='-Wl,-rpath='
+ fi
+ rm -f conftest.t conftest.c conftest
+ ;;
+esac
+AC_SUBST(HLDFLAGS)
+AC_SUBST(HLDENV)
+# End stuff to support --enable-shared
+
+# target_subdir is used by the testsuite to find the target libraries.
+target_subdir=
+if test "${host}" != "${target}"; then
+ target_subdir="${target_alias}/"
+fi
+AC_SUBST(target_subdir)
+
+frags=
+host_makefile_frag=${srcdir}/config/${gdb_host_cpu}/${gdb_host}.mh
+if test ! -f ${host_makefile_frag}; then
+ # When building a native debuger the .mh file containing things
+ # like NATDEPFILES is needed. Cross debuggers don't need .mh
+ # since it no longer contains anything useful.
+ if test "${target}" = "${host}"; then
+ AC_MSG_ERROR("*** Gdb does not support native target ${host}")
+ else
+ host_makefile_frag=/dev/null
+ fi
+fi
+frags="$frags $host_makefile_frag"
+
+target_makefile_frag=${srcdir}/config/${gdb_target_cpu}/${gdb_target}.mt
+if test ! -f ${target_makefile_frag}; then
+AC_MSG_ERROR("*** Gdb does not support target ${target}")
+fi
+frags="$frags $target_makefile_frag"
+
+AC_SUBST_FILE(host_makefile_frag)
+AC_SUBST_FILE(target_makefile_frag)
+AC_SUBST(frags)
+
+changequote(,)dnl
+hostfile=`sed -n '
+s/XM_FILE[ ]*=[ ]*\([^ ]*\)/\1/p
+' ${host_makefile_frag}`
+
+targetfile=`sed -n '
+s/TM_FILE[ ]*=[ ]*\([^ ]*\)/\1/p
+' ${target_makefile_frag}`
+
+GDB_MULTI_ARCH=`sed -n '
+s/GDB_MULTI_ARCH[ ]*=[ ]*\([^ ]*\)[ ]*/\1/p
+' ${target_makefile_frag}`
+
+if test "${target}" = "${host}"; then
+# We pick this up from the host configuration file (.mh) because we
+# do not have a native configuration Makefile fragment.
+nativefile=`sed -n '
+s/NAT_FILE[ ]*=[ ]*\([^ ]*\)/\1/p
+' ${host_makefile_frag}`
+fi
+changequote([,])
+
+# New targets should just set gdb_multi_arch=yes in configure.tgt.
+# Old targets being converted can either do that or set GDB_MULTI_ARCH
+# in the target specific makefile frag. Eventually gdb_multi_arch=yes
+# will be the default.
+if test x"${GDB_MULTI_ARCH}" = x ; then
+ case "${gdb_multi_arch}" in
+ yes ) GDB_MULTI_ARCH=GDB_MULTI_ARCH_PURE ;;
+ no ) GDB_MULTI_ARCH=0 ;;
+ 0|1|2 ) GDB_MULTI_ARCH=${gdb_multi_arch} ;;
+ esac
+fi
+if test x"${GDB_MULTI_ARCH}" != x ; then
+ AC_DEFINE_UNQUOTED(GDB_MULTI_ARCH, ${GDB_MULTI_ARCH})
+fi
+# Warn the user when they use an old practice
+case "${GDB_MULTI_ARCH}" in
+ "" ) ;;
+ 0 | GDB_MULTI_ARCH_PARTIAL | 1 | GDB_MULTI_ARCH_TM | 2 )
+ AC_MSG_WARN("GDB: Target is not pure multi-arch") ;;
+ GDB_MULTI_ARCH_PURE )
+ if test x"${targetfile}" != x ; then
+ AC_MSG_WARN("GDB: Ignoring TM_FILE in ${target_makefile_frag}")
+ targetfile=""
+ fi ;;
+ *) AC_MSG_ERROR("GDB: Unknown GDB_MULTI_ARCH value ${GDB_MULTI_ARCH}");;
+esac
+
+SUBDIRS="doc testsuite nlm"
+if test "${enable_multi_ice}" = "yes"; then
+ SUBDIRS="${SUBDIRS} multi-ice"
+fi
+
+# ``gdbserver'' can only be built in a native configuration.
+if test x"${target}" = x"${host}"; then
+ AC_MSG_CHECKING(whether gdbserver is supported on this host)
+ if test x"${build_gdbserver}" = xyes ; then
+ configdirs="${configdirs} gdbserver"
+ SUBDIRS="${SUBDIRS} gdbserver"
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+
+AC_SUBST(SUBDIRS)
+
+# If hostfile (XM_FILE) and/or targetfile (TM_FILE) and/or nativefile
+# (NAT_FILE) is not set in config/*/*.m[ht] files, we link to an empty
+# version.
+
+files=
+links=
+
+rm -f xm.h
+xm_h=""
+if test "${hostfile}" != ""; then
+ xm_h=xm.h
+ GDB_XM_FILE="config/${gdb_host_cpu}/${hostfile}"
+ files="${files} ${GDB_XM_FILE}"
+ links="${links} xm.h"
+ AC_DEFINE_UNQUOTED(GDB_XM_FILE, ${GDB_XM_FILE})
+fi
+AC_SUBST(xm_h)
+
+rm -f tm.h
+tm_h=""
+if test "${targetfile}" != ""; then
+ tm_h=tm.h
+ GDB_TM_FILE="config/${gdb_target_cpu}/${targetfile}"
+ files="${files} ${GDB_TM_FILE}"
+ links="${links} tm.h"
+ AC_DEFINE_UNQUOTED(GDB_TM_FILE, ${GDB_TM_FILE})
+fi
+AC_SUBST(tm_h)
+
+rm -f nm.h
+nm_h=""
+if test "${nativefile}" != ""; then
+ nm_h=nm.h
+ GDB_NM_FILE="config/${gdb_host_cpu}/${nativefile}"
+ files="${files} ${GDB_NM_FILE}"
+ links="${links} nm.h"
+ AC_DEFINE_UNQUOTED(GDB_NM_FILE, ${GDB_NM_FILE})
+fi
+AC_SUBST(nm_h)
+
+AC_PROG_LN_S
+
+AC_LINK_FILES($files, $links)
+
+dnl Check for exe extension set on certain hosts (e.g. Win32)
+AC_EXEEXT
+
+AC_CONFIG_SUBDIRS($configdirs)
+AC_OUTPUT(Makefile .gdbinit:gdbinit.in,
+[
+dnl Autoconf doesn't provide a mechanism for modifying definitions
+dnl provided by makefile fragments.
+dnl
+if test "${nativefile}" = ""; then
+ < Makefile \
+ sed -e '/^NATDEPFILES[[ ]]*=.*\\$/,/[[^\\]]$/s/^/# /' \
+ -e '/^NATDEPFILES[[ ]]*=/s/^/# /' \
+ | sed -e '/^\(NATDEPFILES[[ ]]*[[+]]=[[ ]]*\)/s//# \1/' \
+ > Makefile.tem
+mv -f Makefile.tem Makefile
+fi
+
+changequote(,)dnl
+sed -e '/^TM_FILE[ ]*=/s,^TM_FILE[ ]*=[ ]*,&config/'"${gdb_target_cpu}"'/,
+/^XM_FILE[ ]*=/s,^XM_FILE[ ]*=[ ]*,&config/'"${gdb_host_cpu}"'/,
+/^NAT_FILE[ ]*=/s,^NAT_FILE[ ]*=[ ]*,&config/'"${gdb_host_cpu}"'/,' <Makefile >Makefile.tmp
+mv -f Makefile.tmp Makefile
+changequote([,])dnl
+
+
+case x$CONFIG_HEADERS in
+xconfig.h:config.in)
+echo > stamp-h ;;
+esac
+],
+[
+gdb_host_cpu=$gdb_host_cpu
+gdb_target_cpu=$gdb_target_cpu
+nativefile=$nativefile
+])
+
+exit 0
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
new file mode 100644
index 00000000000..8861967e16b
--- /dev/null
+++ b/gdb/configure.tgt
@@ -0,0 +1,317 @@
+# Mappings from configurations to GDB target definitions. This is
+# invoked from the autoconf generated configure script.
+
+# This file sets the following shell variables:
+# gdb_target_cpu generic name of CPU
+# gdb_target name of GDB target definition to use
+
+# This file may also modify configdirs.
+
+# Map target cpu into the config cpu subdirectory name.
+# The default is $target_cpu.
+
+case "${target_cpu}" in
+
+alpha*) gdb_target_cpu=alpha ;;
+arm*) gdb_target_cpu=arm ;;
+avr*) gdb_target_cpu=avr ;;
+hppa*) gdb_target_cpu=pa ;;
+i[3456]86*) gdb_target_cpu=i386 ;;
+m68hc11*|m6811*) gdb_target_cpu=m68hc11 ;;
+m68*) gdb_target_cpu=m68k ;;
+m88*) gdb_target_cpu=m88k ;;
+mips*) gdb_target_cpu=mips ;;
+powerpc*) gdb_target_cpu=powerpc ;;
+sparc*) gdb_target_cpu=sparc ;;
+thumb*) gdb_target_cpu=arm ;;
+s390*) gdb_target_cpu=s390 ;;
+sh*) gdb_target_cpu=sh ;;
+strongarm*) gdb_target_cpu=arm ;;
+xscale*) gdb_target_cpu=arm ;;
+v850*) gdb_target_cpu=v850 ;;
+x86_64*) gdb_target_cpu=i386 ;;
+*) gdb_target_cpu=$target_cpu ;;
+
+esac
+
+# map target info into gdb names.
+
+case "${target}" in
+
+alpha*-*-osf*) gdb_target=alpha-osf1 ;;
+alpha*-*-linux*) gdb_target=alpha-linux ;;
+alpha*-*-freebsd*) gdb_target=fbsd ;;
+alpha*-*-netbsd*) gdb_target=nbsd ;;
+
+arc-*-*) gdb_target=arc ;;
+
+arm*-wince-pe) gdb_target=wince ;;
+arm*-*-linux*) gdb_target=linux
+ build_gdbserver=yes
+ ;;
+arm*-*-netbsd*) gdb_target=nbsd
+ gdb_multi_arch=yes ;;
+arm*-*-* | thumb*-*-* | strongarm*-*-*)
+ gdb_target=embed
+ configdirs="$configdirs rdi-share"
+ ;;
+xscale-*-*) gdb_target=embed
+ configdirs="$configdirs rdi-share"
+ ;;
+
+avr-*-*) gdb_target=avr
+ gdb_multi_arch=yes
+ ;;
+
+cris*) gdb_target=cris ;;
+
+d10v-*-*) gdb_target=d10v ;;
+d30v-*-*) gdb_target=d30v ;;
+
+h8300-*-*) gdb_target=h8300 ;;
+h8500-*-*) gdb_target=h8500 ;;
+
+
+fr30-*-elf*) gdb_target=fr30 ;;
+
+
+hppa*-*-bsd*) gdb_target=hppabsd ;;
+hppa*-*-pro*) gdb_target=hppapro ;;
+hppa*64*-*-hpux11*) gdb_target=hppa64 ;;
+hppa*-*-hpux*) gdb_target=hppahpux ;;
+hppa*-*-hiux*) gdb_target=hppahpux ;;
+hppa*-*-osf*) gdb_target=hppaosf ;;
+
+i[3456]86-sequent-bsd*) gdb_target=symmetry ;;
+i[3456]86-sequent-sysv4*) gdb_target=ptx4 ;;
+i[3456]86-sequent-sysv*) gdb_target=ptx ;;
+i[3456]86-ncr-*) gdb_target=ncr3000 ;;
+i[3456]86-*-aout*) gdb_target=embed ;;
+i[3456]86-*-coff*) gdb_target=embed ;;
+i[3456]86-*-elf*) gdb_target=embed ;;
+i[3456]86-*-aix*) gdb_target=i386aix ;;
+i[3456]86-*-bsd*) gdb_target=i386bsd ;;
+i[3456]86-*-freebsd*) gdb_target=fbsd ;;
+i[3456]86-*-netbsdelf*) gdb_target=nbsdelf ;;
+i[3456]86-*-netbsd*) gdb_target=nbsdaout ;;
+i[3456]86-*-os9k) gdb_target=i386os9k ;;
+i[3456]86-*-go32*) gdb_target=i386aout ;;
+i[3456]86-*-msdosdjgpp*) gdb_target=go32 ;;
+i[3456]86-*-lynxos*) gdb_target=i386lynx ;;
+i[3456]86-*-openbsd*) gdb_target=obsd ;;
+i[3456]86-*-solaris*) gdb_target=i386sol2 ;;
+i[3456]86-*-sysv4.2*) gdb_target=i386v42mp ;;
+i[3456]86-*-sysv4*) gdb_target=i386v4 ;;
+i[3456]86-*-sysv5*) gdb_target=i386v42mp ;;
+i[3456]86-*-sco3.2v4*) gdb_target=i386sco4 ;;
+i[3456]86-*-sco3.2v5*) gdb_target=i386sco5 ;;
+i[3456]86-*-sco*) gdb_target=i386v ;;
+i[3456]86-*-sysv*) gdb_target=i386v ;;
+i[3456]86-*-linux*) gdb_target=linux
+ build_gdbserver=yes
+ ;;
+i[3456]86-*-isc*) gdb_target=i386v ;;
+i[3456]86-*-mach3*) gdb_target=i386m3 ;;
+i[3456]86-*-gnu*) gdb_target=i386gnu ;;
+i[3456]86-*-netware*) gdb_target=i386nw
+ configdirs="${configdirs} nlm" ;;
+i[3456]86-*-osf1mk*) gdb_target=i386mk ;;
+i[3456]86-*-cygwin*) gdb_target=cygwin ;;
+i[3456]86-*-pe*) gdb_target=embed ;;
+i[3456]86-*-vxworks*) gdb_target=vxworks ;;
+
+i960-*-bout*) gdb_target=vxworks960 ;;
+i960-nindy-coff*) gdb_target=nindy960 ;;
+i960-*-coff*) gdb_target=mon960 ;;
+i960-nindy-elf*) gdb_target=nindy960 ;;
+i960-*-elf*) gdb_target=mon960 ;;
+i960-*-nindy*) gdb_target=nindy960 ;;
+i960-*-vxworks*) gdb_target=vxworks960 ;;
+
+ia64-*-aix*) gdb_target=aix ;;
+ia64-*-linux*) gdb_target=linux
+ build_gdbserver=yes
+ ;;
+
+m32r-*-elf*) gdb_target=m32r ;;
+
+m68hc11*-*-*|m6811*-*-*) gdb_target=m68hc11 ;;
+
+m68000-*-sunos3*) gdb_target=sun2os3 ;;
+m68000-*-sunos4*) gdb_target=sun2os4 ;;
+
+m68*-apollo*-bsd*) gdb_target=apollo68b ;;
+m68*-bull-sysv*) gdb_target=dpx2 ;;
+m68*-hp-bsd*) gdb_target=hp300bsd ;;
+m68*-hp-hpux*) gdb_target=hp300hpux ;;
+m68*-att-*) gdb_target=3b1 ;;
+m68*-cisco*-*) gdb_target=cisco ;;
+m68*-ericsson-*) gdb_target=es1800 ;;
+m68*-motorola-*) gdb_target=delta68 ;;
+m68*-netx-*) gdb_target=vxworks68 ;;
+m68*-tandem-*) gdb_target=st2000 ;;
+m68*-*-aout*) gdb_target=monitor ;;
+m68*-*-coff*) gdb_target=monitor ;;
+m68*-*-elf*) gdb_target=monitor ;;
+m68*-*-linux*) gdb_target=linux
+ build_gdbserver=yes
+ ;;
+m68*-*-lynxos*) gdb_target=m68klynx ;;
+m68*-*-netbsd*) gdb_target=nbsdaout ;;
+m68*-*-os68k*) gdb_target=os68k ;;
+m68*-*-sunos3*) gdb_target=sun3os3 ;;
+m68*-*-sunos4*) gdb_target=sun3os4 ;;
+m68*-*-sysv4*) gdb_target=m68kv4 ;;
+m68*-*-vxworks*) gdb_target=vxworks68 ;;
+
+m88*-motorola-sysv4*) gdb_target=delta88v4 ;;
+m88*-motorola-*) gdb_target=delta88 ;;
+m88*-*-*) gdb_target=m88k ;;
+
+mcore*-*-*) gdb_target=mcore ;;
+mips64*-big-*) gdb_target=bigmips64 ;;
+mips*-big-*) gdb_target=bigmips ;;
+mips*-dec-mach3*) gdb_target=mach3 ;;
+mips*-dec-*) gdb_target=decstation ;;
+mips*-*-pe) gdb_target=wince ;;
+mips64*el-*-ecoff*) gdb_target=embedl64 ;;
+mips64*-*-ecoff*) gdb_target=embed64 ;;
+mips64*vr4xxx*el-*-elf*)gdb_target=vr4xxxel ;;
+mips64*vr4xxx*-*-elf*) gdb_target=vr4xxx ;;
+mips64*vr4300*el-*-elf*) gdb_target=vr4300el ;;
+mips64*vr4300*-*-elf*) gdb_target=vr4300 ;;
+mips64*vr4100*el-*-elf*) gdb_target=vr4300el ;;
+mips64*vr4100*-*-elf*) gdb_target=vr4100 ;;
+mips64*vr5000*el-*-elf*) gdb_target=vr5000el ;;
+mips64*vr5000*-*-elf*) gdb_target=vr5000 ;;
+mips*tx39*el*-elf*) gdb_target=tx39l ;;
+mips*tx39*-elf*) gdb_target=tx39 ;;
+mips64*el-*-elf*) gdb_target=embedl64 ;;
+mips64*-*-elf*) gdb_target=embed64 ;;
+mips*el-*-ecoff*) gdb_target=embedl ;;
+mips*-*-ecoff*) gdb_target=embed ;;
+mips*el-*-elf*) gdb_target=embedl ;;
+mips*-*-elf*) gdb_target=embed ;;
+mips*-little-*) gdb_target=littlemips ;;
+mips*-*-lnews*) gdb_target=embedl ;;
+mips*-sgi-irix5*) gdb_target=irix5 ;;
+mips*-sgi-irix6*) gdb_target=irix6 ;;
+mips*-sgi-*) gdb_target=irix3 ;;
+mips*-sony-*) gdb_target=bigmips ;;
+mips*-*-linux*) gdb_target=linux
+ build_gdbserver=yes
+ ;;
+mips*-*-netbsd*) gdb_target=nbsd ;;
+mips*-*-mach3*) gdb_target=mipsm3 ;;
+mips*-*-sysv4*) gdb_target=mipsv4 ;;
+mips*-*-sysv*) gdb_target=bigmips ;;
+mips*-*-riscos*) gdb_target=bigmips ;;
+mips*-*-vxworks*) gdb_target=vxmips ;;
+
+mn10200-*-*) gdb_target=mn10200 ;;
+mn10300-*-*) gdb_target=mn10300 ;;
+
+none-*-*) gdb_target=none ;;
+
+ns32k-*-netbsd*) gdb_target=nbsdaout ;;
+
+powerpc-*-netbsd*) gdb_target=nbsd ;;
+powerpc-*-aix*) gdb_target=aix ;;
+powerpc-*-eabi* | powerpc-*-sysv* | powerpc-*-elf*)
+ if test -f ../sim/ppc/Makefile; then
+ gdb_target=ppc-sim
+ else
+ gdb_target=ppc-eabi
+ fi ;;
+powerpcle-*-eabi* | powerpcle-*-sysv* | powerpcle-*-elf*)
+ if test -f ../sim/ppc/Makefile; then
+ gdb_target=ppcle-sim
+ else
+ gdb_target=ppcle-eabi
+ fi ;;
+powerpc-*-linux*) gdb_target=linux
+ build_gdbserver=yes
+ ;;
+powerpc-*-vxworks*) gdb_target=vxworks ;;
+
+rs6000-*-lynxos*) gdb_target=rs6000lynx ;;
+rs6000-*-aix4*) gdb_target=aix4 ;;
+rs6000-*-*) gdb_target=rs6000 ;;
+
+s390-*-*) gdb_target=s390
+ build_gdbserver=yes
+ ;;
+s390x-*-*) gdb_target=s390x
+ build_gdbserver=yes
+ ;;
+
+sh*-*-pe) gdb_target=wince ;;
+sh-*-coff*) gdb_target=embed ;;
+sh-*-elf*) gdb_target=embed ;;
+sh-*-linux*) gdb_target=linux
+ build_gdbserver=yes
+ ;;
+sh*-*-netbsdelf*) gdb_target=nbsd ;;
+sh*) gdb_target=embed ;;
+
+sparc-*-aout*) gdb_target=sparc-em ;;
+sparc-*-coff*) gdb_target=sparc-em ;;
+sparc-*-elf*) gdb_target=sparc-em ;;
+sparc-*-linux*) gdb_target=linux ;;
+sparc-*-lynxos*) gdb_target=sparclynx ;;
+sparc-*-netbsdelf*) gdb_target=nbsdelf ;;
+sparc-*-netbsd*) gdb_target=nbsdaout ;;
+sparc-*-solaris2*) gdb_target=sun4sol2 ;;
+sparc-*-sunos4*) gdb_target=sun4os4 ;;
+sparc-*-sunos5*) gdb_target=sun4sol2 ;;
+sparc-*-vxworks*) gdb_target=vxsparc ;;
+sparc-*-*) gdb_target=sun4os4 ;;
+sparclet-*-*) gdb_target=sparclet;;
+sparclite-*-*) gdb_target=sparclite ;;
+sparc86x-*-*) gdb_target=sparclite ;;
+# It's not clear what the right solution for "v8plus" systems is yet.
+# For now, stick with sparc-sun-solaris2 since that's what config.guess
+# should return. Work is still needed to get gdb to print the 64 bit
+# regs (some of which are usable in v8plus) so sp64sol.mt hasn't been
+# deleted though presumably it should be eventually.
+#sparc64-*-solaris2*) gdb_target=sp64sol2 ;;
+sparc64-*-freebsd*|ultrasparc-*-freebsd*|sparcv9-*-freebsd*)
+ gdb_target=fbsd ;;
+sparc64-*-linux*) gdb_target=sp64linux ;;
+sparcv9-*-* | sparc64-*-*) gdb_target=sp64 ;;
+
+xstormy16-*-*) gdb_target=xstormy16 ;;
+
+vax-*-*) gdb_target=vax ;;
+
+fr30-*-*) gdb_target=fr30
+ ;;
+
+v850*-*-*) gdb_target=v850
+ case ${gdb_host} in
+ cygwin*)
+ CONFIG_OBS="${CONFIG_OBS} v850ice.o" ;;
+ * ) ;;
+ esac
+ ;;
+
+x86_64-*-linux*) gdb_target=x86-64linux
+ build_gdbserver=yes
+ ;;
+
+
+z8k-*-coff*) gdb_target=z8k ;;
+
+esac
+
+
+# map GDB target onto multi-arch support
+
+case "${gdb_target}" in
+d10v) gdb_multi_arch=yes ;;
+m68hc11) gdb_multi_arch=yes ;;
+mn10300) gdb_multi_arch=yes ;;
+x86-64linux) gdb_multi_arch=yes ;;
+v850) gdb_multi_arch=yes ;;
+xstormy16) gdb_multi_arch=yes ;;
+esac
diff --git a/gdb/copying.awk b/gdb/copying.awk
new file mode 100644
index 00000000000..53f7a6f518d
--- /dev/null
+++ b/gdb/copying.awk
@@ -0,0 +1,77 @@
+BEGIN {
+ FS="\"";
+ print "/* ==> Do not modify this file!! It is created automatically";
+ print " by copying.awk. Modify copying.awk instead. <== */";
+ print ""
+ print "#include \"defs.h\""
+ print "#include \"command.h\""
+ print "#include \"gdbcmd.h\""
+ print ""
+ print "static void show_copying_command (char *, int);"
+ print ""
+ print "static void show_warranty_command (char *, int);"
+ print ""
+ print "void _initialize_copying (void);"
+ print ""
+ print "extern int immediate_quit;";
+ print "static void";
+ print "show_copying_command (ignore, from_tty)";
+ print " char *ignore;";
+ print " int from_tty;";
+ print "{";
+ print " immediate_quit++;";
+ }
+NR == 1,/^[ ]*NO WARRANTY[ ]*$/ {
+ if ($0 ~ / /)
+ {
+ printf " printf_filtered (\"\\n\");\n";
+ }
+ else if ($0 !~ /^[ ]*NO WARRANTY[ ]*$/)
+ {
+ printf " printf_filtered (\"";
+ for (i = 1; i < NF; i++)
+ printf "%s\\\"", $i;
+ printf "%s\\n\");\n", $NF;
+ }
+ }
+/^[ ]*NO WARRANTY[ ]*$/ {
+ print " immediate_quit--;";
+ print "}";
+ print "";
+ print "static void";
+ print "show_warranty_command (ignore, from_tty)";
+ print " char *ignore;";
+ print " int from_tty;";
+ print "{";
+ print " immediate_quit++;";
+ }
+/^[ ]*NO WARRANTY[ ]*$/, /^[ ]*END OF TERMS AND CONDITIONS[ ]*$/{
+ if (! ($0 ~ /^[ ]*END OF TERMS AND CONDITIONS[ ]*$/))
+ {
+ printf " printf_filtered (\"";
+ for (i = 1; i < NF; i++)
+ printf "%s\\\"", $i;
+ printf "%s\\n\");\n", $NF;
+ }
+ }
+END {
+ print " immediate_quit--;";
+ print "}";
+ print "";
+ print "void"
+ print "_initialize_copying ()";
+ print "{";
+ print " add_cmd (\"copying\", no_class, show_copying_command,";
+ print " \"Conditions for redistributing copies of GDB.\",";
+ print " &showlist);";
+ print " add_cmd (\"warranty\", no_class, show_warranty_command,";
+ print " \"Various kinds of warranty you do not have.\",";
+ print " &showlist);";
+ print "";
+ print " /* For old-timers, allow \"info copying\", etc. */";
+ print " add_info (\"copying\", show_copying_command,";
+ print " \"Conditions for redistributing copies of GDB.\");";
+ print " add_info (\"warranty\", show_warranty_command,";
+ print " \"Various kinds of warranty you do not have.\");";
+ print "}";
+ }
diff --git a/gdb/copying.c b/gdb/copying.c
new file mode 100644
index 00000000000..a78a862b97d
--- /dev/null
+++ b/gdb/copying.c
@@ -0,0 +1,323 @@
+/* ==> Do not modify this file!! It is created automatically
+ by copying.awk. Modify copying.awk instead. <== */
+
+#include "defs.h"
+#include "command.h"
+#include "gdbcmd.h"
+
+static void show_copying_command (char *, int);
+
+static void show_warranty_command (char *, int);
+
+void _initialize_copying (void);
+
+extern int immediate_quit;
+static void
+show_copying_command (char *ignore, int from_tty)
+{
+ immediate_quit++;
+ printf_filtered (" GNU GENERAL PUBLIC LICENSE\n");
+ printf_filtered (" Version 2, June 1991\n");
+ printf_filtered ("\n");
+ printf_filtered (" Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n");
+ printf_filtered (" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n");
+ printf_filtered (" Everyone is permitted to copy and distribute verbatim copies\n");
+ printf_filtered (" of this license document, but changing it is not allowed.\n");
+ printf_filtered ("\n");
+ printf_filtered (" Preamble\n");
+ printf_filtered ("\n");
+ printf_filtered (" The licenses for most software are designed to take away your\n");
+ printf_filtered ("freedom to share and change it. By contrast, the GNU General Public\n");
+ printf_filtered ("License is intended to guarantee your freedom to share and change free\n");
+ printf_filtered ("software--to make sure the software is free for all its users. This\n");
+ printf_filtered ("General Public License applies to most of the Free Software\n");
+ printf_filtered ("Foundation's software and to any other program whose authors commit to\n");
+ printf_filtered ("using it. (Some other Free Software Foundation software is covered by\n");
+ printf_filtered ("the GNU Library General Public License instead.) You can apply it to\n");
+ printf_filtered ("your programs, too.\n");
+ printf_filtered ("\n");
+ printf_filtered (" When we speak of free software, we are referring to freedom, not\n");
+ printf_filtered ("price. Our General Public Licenses are designed to make sure that you\n");
+ printf_filtered ("have the freedom to distribute copies of free software (and charge for\n");
+ printf_filtered ("this service if you wish), that you receive source code or can get it\n");
+ printf_filtered ("if you want it, that you can change the software or use pieces of it\n");
+ printf_filtered ("in new free programs; and that you know you can do these things.\n");
+ printf_filtered ("\n");
+ printf_filtered (" To protect your rights, we need to make restrictions that forbid\n");
+ printf_filtered ("anyone to deny you these rights or to ask you to surrender the rights.\n");
+ printf_filtered ("These restrictions translate to certain responsibilities for you if you\n");
+ printf_filtered ("distribute copies of the software, or if you modify it.\n");
+ printf_filtered ("\n");
+ printf_filtered (" For example, if you distribute copies of such a program, whether\n");
+ printf_filtered ("gratis or for a fee, you must give the recipients all the rights that\n");
+ printf_filtered ("you have. You must make sure that they, too, receive or can get the\n");
+ printf_filtered ("source code. And you must show them these terms so they know their\n");
+ printf_filtered ("rights.\n");
+ printf_filtered ("\n");
+ printf_filtered (" We protect your rights with two steps: (1) copyright the software, and\n");
+ printf_filtered ("(2) offer you this license which gives you legal permission to copy,\n");
+ printf_filtered ("distribute and/or modify the software.\n");
+ printf_filtered ("\n");
+ printf_filtered (" Also, for each author's protection and ours, we want to make certain\n");
+ printf_filtered ("that everyone understands that there is no warranty for this free\n");
+ printf_filtered ("software. If the software is modified by someone else and passed on, we\n");
+ printf_filtered ("want its recipients to know that what they have is not the original, so\n");
+ printf_filtered ("that any problems introduced by others will not reflect on the original\n");
+ printf_filtered ("authors' reputations.\n");
+ printf_filtered ("\n");
+ printf_filtered (" Finally, any free program is threatened constantly by software\n");
+ printf_filtered ("patents. We wish to avoid the danger that redistributors of a free\n");
+ printf_filtered ("program will individually obtain patent licenses, in effect making the\n");
+ printf_filtered ("program proprietary. To prevent this, we have made it clear that any\n");
+ printf_filtered ("patent must be licensed for everyone's free use or not licensed at all.\n");
+ printf_filtered ("\n");
+ printf_filtered (" The precise terms and conditions for copying, distribution and\n");
+ printf_filtered ("modification follow.\n");
+ printf_filtered ("\n");
+ printf_filtered (" GNU GENERAL PUBLIC LICENSE\n");
+ printf_filtered (" TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n");
+ printf_filtered ("\n");
+ printf_filtered (" 0. This License applies to any program or other work which contains\n");
+ printf_filtered ("a notice placed by the copyright holder saying it may be distributed\n");
+ printf_filtered ("under the terms of this General Public License. The \"Program\", below,\n");
+ printf_filtered ("refers to any such program or work, and a \"work based on the Program\"\n");
+ printf_filtered ("means either the Program or any derivative work under copyright law:\n");
+ printf_filtered ("that is to say, a work containing the Program or a portion of it,\n");
+ printf_filtered ("either verbatim or with modifications and/or translated into another\n");
+ printf_filtered ("language. (Hereinafter, translation is included without limitation in\n");
+ printf_filtered ("the term \"modification\".) Each licensee is addressed as \"you\".\n");
+ printf_filtered ("\n");
+ printf_filtered ("Activities other than copying, distribution and modification are not\n");
+ printf_filtered ("covered by this License; they are outside its scope. The act of\n");
+ printf_filtered ("running the Program is not restricted, and the output from the Program\n");
+ printf_filtered ("is covered only if its contents constitute a work based on the\n");
+ printf_filtered ("Program (independent of having been made by running the Program).\n");
+ printf_filtered ("Whether that is true depends on what the Program does.\n");
+ printf_filtered ("\n");
+ printf_filtered (" 1. You may copy and distribute verbatim copies of the Program's\n");
+ printf_filtered ("source code as you receive it, in any medium, provided that you\n");
+ printf_filtered ("conspicuously and appropriately publish on each copy an appropriate\n");
+ printf_filtered ("copyright notice and disclaimer of warranty; keep intact all the\n");
+ printf_filtered ("notices that refer to this License and to the absence of any warranty;\n");
+ printf_filtered ("and give any other recipients of the Program a copy of this License\n");
+ printf_filtered ("along with the Program.\n");
+ printf_filtered ("\n");
+ printf_filtered ("You may charge a fee for the physical act of transferring a copy, and\n");
+ printf_filtered ("you may at your option offer warranty protection in exchange for a fee.\n");
+ printf_filtered ("\n");
+ printf_filtered (" 2. You may modify your copy or copies of the Program or any portion\n");
+ printf_filtered ("of it, thus forming a work based on the Program, and copy and\n");
+ printf_filtered ("distribute such modifications or work under the terms of Section 1\n");
+ printf_filtered ("above, provided that you also meet all of these conditions:\n");
+ printf_filtered ("\n");
+ printf_filtered (" a) You must cause the modified files to carry prominent notices\n");
+ printf_filtered (" stating that you changed the files and the date of any change.\n");
+ printf_filtered ("\n");
+ printf_filtered (" b) You must cause any work that you distribute or publish, that in\n");
+ printf_filtered (" whole or in part contains or is derived from the Program or any\n");
+ printf_filtered (" part thereof, to be licensed as a whole at no charge to all third\n");
+ printf_filtered (" parties under the terms of this License.\n");
+ printf_filtered ("\n");
+ printf_filtered (" c) If the modified program normally reads commands interactively\n");
+ printf_filtered (" when run, you must cause it, when started running for such\n");
+ printf_filtered (" interactive use in the most ordinary way, to print or display an\n");
+ printf_filtered (" announcement including an appropriate copyright notice and a\n");
+ printf_filtered (" notice that there is no warranty (or else, saying that you provide\n");
+ printf_filtered (" a warranty) and that users may redistribute the program under\n");
+ printf_filtered (" these conditions, and telling the user how to view a copy of this\n");
+ printf_filtered (" License. (Exception: if the Program itself is interactive but\n");
+ printf_filtered (" does not normally print such an announcement, your work based on\n");
+ printf_filtered (" the Program is not required to print an announcement.)\n");
+ printf_filtered ("\n");
+ printf_filtered ("These requirements apply to the modified work as a whole. If\n");
+ printf_filtered ("identifiable sections of that work are not derived from the Program,\n");
+ printf_filtered ("and can be reasonably considered independent and separate works in\n");
+ printf_filtered ("themselves, then this License, and its terms, do not apply to those\n");
+ printf_filtered ("sections when you distribute them as separate works. But when you\n");
+ printf_filtered ("distribute the same sections as part of a whole which is a work based\n");
+ printf_filtered ("on the Program, the distribution of the whole must be on the terms of\n");
+ printf_filtered ("this License, whose permissions for other licensees extend to the\n");
+ printf_filtered ("entire whole, and thus to each and every part regardless of who wrote it.\n");
+ printf_filtered ("\n");
+ printf_filtered ("Thus, it is not the intent of this section to claim rights or contest\n");
+ printf_filtered ("your rights to work written entirely by you; rather, the intent is to\n");
+ printf_filtered ("exercise the right to control the distribution of derivative or\n");
+ printf_filtered ("collective works based on the Program.\n");
+ printf_filtered ("\n");
+ printf_filtered ("In addition, mere aggregation of another work not based on the Program\n");
+ printf_filtered ("with the Program (or with a work based on the Program) on a volume of\n");
+ printf_filtered ("a storage or distribution medium does not bring the other work under\n");
+ printf_filtered ("the scope of this License.\n");
+ printf_filtered ("\n");
+ printf_filtered (" 3. You may copy and distribute the Program (or a work based on it,\n");
+ printf_filtered ("under Section 2) in object code or executable form under the terms of\n");
+ printf_filtered ("Sections 1 and 2 above provided that you also do one of the following:\n");
+ printf_filtered ("\n");
+ printf_filtered (" a) Accompany it with the complete corresponding machine-readable\n");
+ printf_filtered (" source code, which must be distributed under the terms of Sections\n");
+ printf_filtered (" 1 and 2 above on a medium customarily used for software interchange; or,\n");
+ printf_filtered ("\n");
+ printf_filtered (" b) Accompany it with a written offer, valid for at least three\n");
+ printf_filtered (" years, to give any third party, for a charge no more than your\n");
+ printf_filtered (" cost of physically performing source distribution, a complete\n");
+ printf_filtered (" machine-readable copy of the corresponding source code, to be\n");
+ printf_filtered (" distributed under the terms of Sections 1 and 2 above on a medium\n");
+ printf_filtered (" customarily used for software interchange; or,\n");
+ printf_filtered ("\n");
+ printf_filtered (" c) Accompany it with the information you received as to the offer\n");
+ printf_filtered (" to distribute corresponding source code. (This alternative is\n");
+ printf_filtered (" allowed only for noncommercial distribution and only if you\n");
+ printf_filtered (" received the program in object code or executable form with such\n");
+ printf_filtered (" an offer, in accord with Subsection b above.)\n");
+ printf_filtered ("\n");
+ printf_filtered ("The source code for a work means the preferred form of the work for\n");
+ printf_filtered ("making modifications to it. For an executable work, complete source\n");
+ printf_filtered ("code means all the source code for all modules it contains, plus any\n");
+ printf_filtered ("associated interface definition files, plus the scripts used to\n");
+ printf_filtered ("control compilation and installation of the executable. However, as a\n");
+ printf_filtered ("special exception, the source code distributed need not include\n");
+ printf_filtered ("anything that is normally distributed (in either source or binary\n");
+ printf_filtered ("form) with the major components (compiler, kernel, and so on) of the\n");
+ printf_filtered ("operating system on which the executable runs, unless that component\n");
+ printf_filtered ("itself accompanies the executable.\n");
+ printf_filtered ("\n");
+ printf_filtered ("If distribution of executable or object code is made by offering\n");
+ printf_filtered ("access to copy from a designated place, then offering equivalent\n");
+ printf_filtered ("access to copy the source code from the same place counts as\n");
+ printf_filtered ("distribution of the source code, even though third parties are not\n");
+ printf_filtered ("compelled to copy the source along with the object code.\n");
+ printf_filtered ("\n");
+ printf_filtered (" 4. You may not copy, modify, sublicense, or distribute the Program\n");
+ printf_filtered ("except as expressly provided under this License. Any attempt\n");
+ printf_filtered ("otherwise to copy, modify, sublicense or distribute the Program is\n");
+ printf_filtered ("void, and will automatically terminate your rights under this License.\n");
+ printf_filtered ("However, parties who have received copies, or rights, from you under\n");
+ printf_filtered ("this License will not have their licenses terminated so long as such\n");
+ printf_filtered ("parties remain in full compliance.\n");
+ printf_filtered ("\n");
+ printf_filtered (" 5. You are not required to accept this License, since you have not\n");
+ printf_filtered ("signed it. However, nothing else grants you permission to modify or\n");
+ printf_filtered ("distribute the Program or its derivative works. These actions are\n");
+ printf_filtered ("prohibited by law if you do not accept this License. Therefore, by\n");
+ printf_filtered ("modifying or distributing the Program (or any work based on the\n");
+ printf_filtered ("Program), you indicate your acceptance of this License to do so, and\n");
+ printf_filtered ("all its terms and conditions for copying, distributing or modifying\n");
+ printf_filtered ("the Program or works based on it.\n");
+ printf_filtered ("\n");
+ printf_filtered (" 6. Each time you redistribute the Program (or any work based on the\n");
+ printf_filtered ("Program), the recipient automatically receives a license from the\n");
+ printf_filtered ("original licensor to copy, distribute or modify the Program subject to\n");
+ printf_filtered ("these terms and conditions. You may not impose any further\n");
+ printf_filtered ("restrictions on the recipients' exercise of the rights granted herein.\n");
+ printf_filtered ("You are not responsible for enforcing compliance by third parties to\n");
+ printf_filtered ("this License.\n");
+ printf_filtered ("\n");
+ printf_filtered (" 7. If, as a consequence of a court judgment or allegation of patent\n");
+ printf_filtered ("infringement or for any other reason (not limited to patent issues),\n");
+ printf_filtered ("conditions are imposed on you (whether by court order, agreement or\n");
+ printf_filtered ("otherwise) that contradict the conditions of this License, they do not\n");
+ printf_filtered ("excuse you from the conditions of this License. If you cannot\n");
+ printf_filtered ("distribute so as to satisfy simultaneously your obligations under this\n");
+ printf_filtered ("License and any other pertinent obligations, then as a consequence you\n");
+ printf_filtered ("may not distribute the Program at all. For example, if a patent\n");
+ printf_filtered ("license would not permit royalty-free redistribution of the Program by\n");
+ printf_filtered ("all those who receive copies directly or indirectly through you, then\n");
+ printf_filtered ("the only way you could satisfy both it and this License would be to\n");
+ printf_filtered ("refrain entirely from distribution of the Program.\n");
+ printf_filtered ("\n");
+ printf_filtered ("If any portion of this section is held invalid or unenforceable under\n");
+ printf_filtered ("any particular circumstance, the balance of the section is intended to\n");
+ printf_filtered ("apply and the section as a whole is intended to apply in other\n");
+ printf_filtered ("circumstances.\n");
+ printf_filtered ("\n");
+ printf_filtered ("It is not the purpose of this section to induce you to infringe any\n");
+ printf_filtered ("patents or other property right claims or to contest validity of any\n");
+ printf_filtered ("such claims; this section has the sole purpose of protecting the\n");
+ printf_filtered ("integrity of the free software distribution system, which is\n");
+ printf_filtered ("implemented by public license practices. Many people have made\n");
+ printf_filtered ("generous contributions to the wide range of software distributed\n");
+ printf_filtered ("through that system in reliance on consistent application of that\n");
+ printf_filtered ("system; it is up to the author/donor to decide if he or she is willing\n");
+ printf_filtered ("to distribute software through any other system and a licensee cannot\n");
+ printf_filtered ("impose that choice.\n");
+ printf_filtered ("\n");
+ printf_filtered ("This section is intended to make thoroughly clear what is believed to\n");
+ printf_filtered ("be a consequence of the rest of this License.\n");
+ printf_filtered ("\n");
+ printf_filtered (" 8. If the distribution and/or use of the Program is restricted in\n");
+ printf_filtered ("certain countries either by patents or by copyrighted interfaces, the\n");
+ printf_filtered ("original copyright holder who places the Program under this License\n");
+ printf_filtered ("may add an explicit geographical distribution limitation excluding\n");
+ printf_filtered ("those countries, so that distribution is permitted only in or among\n");
+ printf_filtered ("countries not thus excluded. In such case, this License incorporates\n");
+ printf_filtered ("the limitation as if written in the body of this License.\n");
+ printf_filtered ("\n");
+ printf_filtered (" 9. The Free Software Foundation may publish revised and/or new versions\n");
+ printf_filtered ("of the General Public License from time to time. Such new versions will\n");
+ printf_filtered ("be similar in spirit to the present version, but may differ in detail to\n");
+ printf_filtered ("address new problems or concerns.\n");
+ printf_filtered ("\n");
+ printf_filtered ("Each version is given a distinguishing version number. If the Program\n");
+ printf_filtered ("specifies a version number of this License which applies to it and \"any\n");
+ printf_filtered ("later version\", you have the option of following the terms and conditions\n");
+ printf_filtered ("either of that version or of any later version published by the Free\n");
+ printf_filtered ("Software Foundation. If the Program does not specify a version number of\n");
+ printf_filtered ("this License, you may choose any version ever published by the Free Software\n");
+ printf_filtered ("Foundation.\n");
+ printf_filtered ("\n");
+ printf_filtered (" 10. If you wish to incorporate parts of the Program into other free\n");
+ printf_filtered ("programs whose distribution conditions are different, write to the author\n");
+ printf_filtered ("to ask for permission. For software which is copyrighted by the Free\n");
+ printf_filtered ("Software Foundation, write to the Free Software Foundation; we sometimes\n");
+ printf_filtered ("make exceptions for this. Our decision will be guided by the two goals\n");
+ printf_filtered ("of preserving the free status of all derivatives of our free software and\n");
+ printf_filtered ("of promoting the sharing and reuse of software generally.\n");
+ printf_filtered ("\n");
+ immediate_quit--;
+}
+
+static void
+show_warranty_command (char *ignore, int from_tty)
+{
+ immediate_quit++;
+ printf_filtered (" NO WARRANTY\n");
+ printf_filtered ("\n");
+ printf_filtered (" 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n");
+ printf_filtered ("FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n");
+ printf_filtered ("OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n");
+ printf_filtered ("PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n");
+ printf_filtered ("OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n");
+ printf_filtered ("MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n");
+ printf_filtered ("TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n");
+ printf_filtered ("PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n");
+ printf_filtered ("REPAIR OR CORRECTION.\n");
+ printf_filtered ("\n");
+ printf_filtered (" 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n");
+ printf_filtered ("WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n");
+ printf_filtered ("REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n");
+ printf_filtered ("INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n");
+ printf_filtered ("OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n");
+ printf_filtered ("TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n");
+ printf_filtered ("YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n");
+ printf_filtered ("PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n");
+ printf_filtered ("POSSIBILITY OF SUCH DAMAGES.\n");
+ printf_filtered ("\n");
+ immediate_quit--;
+}
+
+void
+_initialize_copying (void)
+{
+ add_cmd ("copying", no_class, show_copying_command,
+ "Conditions for redistributing copies of GDB.",
+ &showlist);
+ add_cmd ("warranty", no_class, show_warranty_command,
+ "Various kinds of warranty you do not have.",
+ &showlist);
+
+ /* For old-timers, allow "info copying", etc. */
+ add_info ("copying", show_copying_command,
+ "Conditions for redistributing copies of GDB.");
+ add_info ("warranty", show_warranty_command,
+ "Various kinds of warranty you do not have.");
+}
diff --git a/gdb/core-aout.c b/gdb/core-aout.c
new file mode 100644
index 00000000000..0329302dc1e
--- /dev/null
+++ b/gdb/core-aout.c
@@ -0,0 +1,146 @@
+/* Extract registers from a "standard" core file, for GDB.
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
+ 1999, 2000, 2001 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. */
+
+/* Typically used on systems that have a.out format executables.
+ corefile.c is supposed to contain the more machine-independent
+ aspects of reading registers from core files, while this file is
+ more machine specific. */
+
+#include "defs.h"
+
+#ifdef HAVE_PTRACE_H
+#include <ptrace.h>
+#else
+#ifdef HAVE_SYS_PTRACE_H
+#include <sys/ptrace.h>
+#endif
+#endif
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include "gdbcore.h"
+#include "value.h" /* For supply_register. */
+#include "regcache.h"
+
+/* These are needed on various systems to expand REGISTER_U_ADDR. */
+#ifndef USG
+#include "gdb_dirent.h"
+#include <sys/file.h>
+#include "gdb_stat.h"
+#include <sys/user.h>
+#endif
+
+#ifndef CORE_REGISTER_ADDR
+#define CORE_REGISTER_ADDR(regno, regptr) register_addr(regno, regptr)
+#endif /* CORE_REGISTER_ADDR */
+
+#ifdef NEED_SYS_CORE_H
+#include <sys/core.h>
+#endif
+
+static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
+
+void _initialize_core_aout (void);
+
+/* Extract the register values out of the core file and store
+ them where `read_register' will find them.
+
+ CORE_REG_SECT points to the register values themselves, read into memory.
+ CORE_REG_SIZE is the size of that area.
+ WHICH says which set of registers we are handling (0 = int, 2 = float
+ on machines where they are discontiguous).
+ REG_ADDR is the offset from u.u_ar0 to the register values relative to
+ core_reg_sect. This is used with old-fashioned core files to
+ locate the registers in a large upage-plus-stack ".reg" section.
+ Original upage address X is at location core_reg_sect+x+reg_addr.
+ */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR reg_addr)
+{
+ int regno;
+ CORE_ADDR addr;
+ int bad_reg = -1;
+ CORE_ADDR reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */
+ int numregs = NUM_REGS;
+
+ /* If u.u_ar0 was an absolute address in the core file, relativize it now,
+ so we can use it as an offset into core_reg_sect. When we're done,
+ "register 0" will be at core_reg_sect+reg_ptr, and we can use
+ CORE_REGISTER_ADDR to offset to the other registers. If this is a modern
+ core file without a upage, reg_ptr will be zero and this is all a big
+ NOP. */
+ if (reg_ptr > core_reg_size)
+ reg_ptr -= KERNEL_U_ADDR;
+
+ for (regno = 0; regno < numregs; regno++)
+ {
+ addr = CORE_REGISTER_ADDR (regno, reg_ptr);
+ if (addr >= core_reg_size
+ && bad_reg < 0)
+ bad_reg = regno;
+ else
+ supply_register (regno, core_reg_sect + addr);
+ }
+
+ if (bad_reg >= 0)
+ error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
+}
+
+
+#ifdef REGISTER_U_ADDR
+
+/* Return the address in the core dump or inferior of register REGNO.
+ BLOCKEND is the address of the end of the user structure. */
+
+CORE_ADDR
+register_addr (int regno, CORE_ADDR blockend)
+{
+ CORE_ADDR addr;
+
+ if (regno < 0 || regno >= NUM_REGS)
+ error ("Invalid register number %d.", regno);
+
+ REGISTER_U_ADDR (addr, blockend, regno);
+
+ return addr;
+}
+
+#endif /* REGISTER_U_ADDR */
+
+
+/* Register that we are able to handle aout (trad-core) file formats. */
+
+static struct core_fns aout_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_aout (void)
+{
+ add_core_fns (&aout_core_fns);
+}
diff --git a/gdb/core-regset.c b/gdb/core-regset.c
new file mode 100644
index 00000000000..16cfde5be66
--- /dev/null
+++ b/gdb/core-regset.c
@@ -0,0 +1,134 @@
+/* Machine independent GDB support for core files on systems using "regsets".
+ Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000
+ 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. */
+
+
+/* N O T E S
+
+ This file is used by most systems that implement /proc. For these systems,
+ the general registers are laid out the same way in both the core file and
+ the gregset_p structure. The current exception to this is Irix-4.*, where
+ the gregset_p structure is split up into two pieces in the core file.
+
+ The general register and floating point register sets are manipulated by
+ separate ioctl's. This file makes the assumption that if FP0_REGNUM is
+ defined, then support for the floating point register set is desired,
+ regardless of whether or not the actual target has floating point hardware.
+
+ */
+
+#include "defs.h"
+
+#include <time.h>
+#ifdef HAVE_SYS_PROCFS_H
+#include <sys/procfs.h>
+#endif
+#include <fcntl.h>
+#include <errno.h>
+#include "gdb_string.h"
+
+#include "inferior.h"
+#include "target.h"
+#include "command.h"
+#include "gdbcore.h"
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
+
+void _initialize_core_regset (void);
+
+/*
+
+ GLOBAL FUNCTION
+
+ fetch_core_registers -- fetch current registers from core file
+
+ SYNOPSIS
+
+ void fetch_core_registers (char *core_reg_sect,
+ unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+
+ DESCRIPTION
+
+ Read the values of either the general register set (WHICH equals 0)
+ or the floating point register set (WHICH equals 2) from the core
+ file data (pointed to by CORE_REG_SECT), and update gdb's idea of
+ their current values. The CORE_REG_SIZE parameter is compared to
+ the size of the gregset or fpgregset structures (as appropriate) to
+ validate the size of the structure from the core file. The
+ REG_ADDR parameter is ignored.
+
+ */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR reg_addr)
+{
+ gdb_gregset_t gregset;
+ gdb_fpregset_t fpregset;
+
+ if (which == 0)
+ {
+ if (core_reg_size != sizeof (gregset))
+ {
+ warning ("wrong size gregset struct in core file");
+ }
+ else
+ {
+ memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset));
+ supply_gregset (&gregset);
+ }
+ }
+ else if (which == 2)
+ {
+ if (core_reg_size != sizeof (fpregset))
+ {
+ warning ("wrong size fpregset struct in core file");
+ }
+ else
+ {
+ memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset));
+ if (FP0_REGNUM >= 0)
+ supply_fpregset (&fpregset);
+ }
+ }
+}
+
+
+/* Register that we are able to handle ELF file formats using standard
+ procfs "regset" structures. */
+
+static struct core_fns regset_core_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_regset (void)
+{
+ add_core_fns (&regset_core_fns);
+}
diff --git a/gdb/core-sol2.c b/gdb/core-sol2.c
new file mode 100644
index 00000000000..0123cf4b5e1
--- /dev/null
+++ b/gdb/core-sol2.c
@@ -0,0 +1,194 @@
+/* Machine independent support for Solaris 2 core files for GDB.
+ Copyright 1994, 1995, 1996, 1998, 1999, 2000, 2001
+ 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. */
+
+
+/* Solaris comes with two flavours of core files, cores generated by
+ an ELF executable and cores generated by programs that were
+ run under BCP (the part of Solaris which allows it to run SunOS4
+ a.out files).
+ This file combines the core register fetching from core-regset.c
+ and sparc-nat.c to be able to read both flavours. */
+
+#include "defs.h"
+
+#if defined (__sparcv9)
+/* Fails to get included by the Solaris system header files. */
+# include <v9/sys/privregs.h>
+#endif
+
+#include <time.h>
+#include <sys/types.h>
+#include <sys/regset.h>
+#include <sys/procfs.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "gdb_string.h"
+#include "regcache.h"
+
+#include "inferior.h"
+#include "target.h"
+#include "command.h"
+#include "gdbcore.h"
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
+
+/* Fetch registers from core file data pointed to by CORE_REG_SECT. When
+ WHICH is 0, the the general register set is fetched; when WHICH is
+ 2, the floating point registers are fetched. CORE_REG_SIZE is used
+ to validate the size of the data pointed to by CORE_REG_SECT. REG_ADDR
+ is unused. */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR reg_addr)
+{
+ int i;
+
+ if (which == 0)
+ {
+ prgregset_t prgregset;
+
+ if (core_reg_size == sizeof (prgregset_t))
+ {
+ memcpy ((char *) &prgregset, core_reg_sect, sizeof (prgregset));
+ supply_gregset (&prgregset);
+ }
+#if defined (HAVE_PRGREGSET32_T)
+ /* 32-bit corefile, 64-bit debugger. */
+ else if (core_reg_size == sizeof (prgregset32_t))
+ {
+ prgreg32_t *core_gregs;
+
+ /* Can't use memcpy here, because the core file contains
+ 32-bit regs; supply_register expects 64-bit regs. */
+ core_gregs = (prgreg32_t *) core_reg_sect;
+ for (i = 0; i < NPRGREG; i++)
+ prgregset[i] = core_gregs[i];
+
+ supply_gregset (&prgregset);
+ }
+#endif /* HAVE_PRGREGSET32_T */
+ else if (core_reg_size == sizeof (struct regs))
+ {
+ struct regs *gregs = (struct regs *) core_reg_sect;
+
+ /* G0 *always* holds 0. */
+ *(int *) &registers[REGISTER_BYTE (0)] = 0;
+
+ /* The globals and output registers. */
+ memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &gregs->r_g1,
+ 15 * REGISTER_RAW_SIZE (G1_REGNUM));
+ *(int *) &registers[REGISTER_BYTE (PS_REGNUM)] = gregs->r_ps;
+ *(int *) &registers[REGISTER_BYTE (PC_REGNUM)] = gregs->r_pc;
+ *(int *) &registers[REGISTER_BYTE (NPC_REGNUM)] = gregs->r_npc;
+ *(int *) &registers[REGISTER_BYTE (Y_REGNUM)] = gregs->r_y;
+
+ /* My best guess at where to get the locals and input
+ registers is exactly where they usually are, right above
+ the stack pointer. If the core dump was caused by a bus error
+ from blowing away the stack pointer (as is possible) then this
+ won't work, but it's worth the try. */
+ {
+ int sp;
+
+ sp = *(int *) &registers[REGISTER_BYTE (SP_REGNUM)];
+ if (0 != target_read_memory (sp,
+ &registers[REGISTER_BYTE (L0_REGNUM)],
+ 16 * REGISTER_RAW_SIZE (L0_REGNUM)))
+ {
+ warning ("couldn't read input and local registers from core file\n");
+ }
+ }
+ }
+ else
+ {
+ warning ("wrong size gregset struct in core file");
+ }
+ }
+ else if (which == 2)
+ {
+ prfpregset_t prfpregset;
+
+ if (core_reg_size == sizeof (prfpregset_t))
+ {
+ memcpy ((char *) &prfpregset, core_reg_sect, sizeof (prfpregset));
+ supply_fpregset (&prfpregset);
+ }
+#if defined (HAVE_PRFPREGSET32_T)
+ /* 32-bit corefile, 64-bit debugger. */
+ else if (core_reg_size == sizeof (prfpregset32_t))
+ {
+ prfpregset32_t *core_fpregset;
+
+ /* Can't use memcpy here, because the core file contains
+ 32-bit regs; supply_fpregset expects 64-bit regs. */
+
+ core_fpregset = (prfpregset32_t *) core_reg_sect;
+ for (i = 0; i < 16; i++)
+ prfpregset.pr_fr.pr_dregs[i] = core_fpregset->pr_fr.pr_dregs[i];
+ while (i < 32)
+ prfpregset.pr_fr.pr_dregs[i++] = 0;
+
+ prfpregset.pr_fsr = core_fpregset->pr_fsr;
+ prfpregset.pr_qcnt = core_fpregset->pr_qcnt;
+ prfpregset.pr_q_entrysize = core_fpregset->pr_q_entrysize;
+ prfpregset.pr_en = core_fpregset->pr_en;
+ /* We will not use the pr_q array. */
+
+ supply_fpregset (&prfpregset);
+ }
+#endif /* HAVE_PRFPREGSET32_T */
+ else if (core_reg_size >= sizeof (struct fpu))
+ {
+ struct fpu *fpuregs = (struct fpu *) core_reg_sect;
+
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &fpuregs->fpu_fr,
+ sizeof (fpuregs->fpu_fr));
+ memcpy (&registers[REGISTER_BYTE (FPS_REGNUM)], &fpuregs->fpu_fsr,
+ sizeof (FPU_FSR_TYPE));
+ }
+ else
+ {
+ warning ("wrong size fpregset struct in core file");
+ }
+ }
+}
+
+
+/* Register that we are able to handle solaris core file formats. */
+
+static struct core_fns solaris_core_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_solaris (void)
+{
+ add_core_fns (&solaris_core_fns);
+}
diff --git a/gdb/corefile.c b/gdb/corefile.c
new file mode 100644
index 00000000000..29eeac87ebe
--- /dev/null
+++ b/gdb/corefile.c
@@ -0,0 +1,458 @@
+/* Core dump and executable file functions above target vector, for GDB.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
+ 1999, 2000, 2001
+ 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 "defs.h"
+#include "gdb_string.h"
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include "inferior.h"
+#include "symtab.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "bfd.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "dis-asm.h"
+#include "gdb_stat.h"
+#include "completer.h"
+
+/* Local function declarations. */
+
+extern void _initialize_core (void);
+static void call_extra_exec_file_hooks (char *filename);
+
+/* You can have any number of hooks for `exec_file_command' command to call.
+ If there's only one hook, it is set in exec_file_display hook.
+ If there are two or more hooks, they are set in exec_file_extra_hooks[],
+ and exec_file_display_hook is set to a function that calls all of them.
+ This extra complexity is needed to preserve compatibility with
+ old code that assumed that only one hook could be set, and which called
+ exec_file_display_hook directly. */
+
+typedef void (*hook_type) (char *);
+
+hook_type exec_file_display_hook; /* the original hook */
+static hook_type *exec_file_extra_hooks; /* array of additional hooks */
+static int exec_file_hook_count = 0; /* size of array */
+
+/* Binary file diddling handle for the core file. */
+
+bfd *core_bfd = NULL;
+
+
+/* Backward compatability with old way of specifying core files. */
+
+void
+core_file_command (char *filename, int from_tty)
+{
+ struct target_ops *t;
+
+ dont_repeat (); /* Either way, seems bogus. */
+
+ t = find_core_target ();
+ if (t == NULL)
+ error ("GDB can't read core files on this machine.");
+
+ if (!filename)
+ (t->to_detach) (filename, from_tty);
+ else
+ (t->to_open) (filename, from_tty);
+}
+
+
+/* If there are two or more functions that wish to hook into exec_file_command,
+ * this function will call all of the hook functions. */
+
+static void
+call_extra_exec_file_hooks (char *filename)
+{
+ int i;
+
+ for (i = 0; i < exec_file_hook_count; i++)
+ (*exec_file_extra_hooks[i]) (filename);
+}
+
+/* Call this to specify the hook for exec_file_command to call back.
+ This is called from the x-window display code. */
+
+void
+specify_exec_file_hook (void (*hook) (char *))
+{
+ hook_type *new_array;
+
+ if (exec_file_display_hook != NULL)
+ {
+ /* There's already a hook installed. Arrange to have both it
+ * and the subsequent hooks called. */
+ if (exec_file_hook_count == 0)
+ {
+ /* If this is the first extra hook, initialize the hook array. */
+ exec_file_extra_hooks = (hook_type *) xmalloc (sizeof (hook_type));
+ exec_file_extra_hooks[0] = exec_file_display_hook;
+ exec_file_display_hook = call_extra_exec_file_hooks;
+ exec_file_hook_count = 1;
+ }
+
+ /* Grow the hook array by one and add the new hook to the end.
+ Yes, it's inefficient to grow it by one each time but since
+ this is hardly ever called it's not a big deal. */
+ exec_file_hook_count++;
+ new_array =
+ (hook_type *) xrealloc (exec_file_extra_hooks,
+ exec_file_hook_count * sizeof (hook_type));
+ exec_file_extra_hooks = new_array;
+ exec_file_extra_hooks[exec_file_hook_count - 1] = hook;
+ }
+ else
+ exec_file_display_hook = hook;
+}
+
+/* The exec file must be closed before running an inferior.
+ If it is needed again after the inferior dies, it must
+ be reopened. */
+
+void
+close_exec_file (void)
+{
+#if 0 /* FIXME */
+ if (exec_bfd)
+ bfd_tempclose (exec_bfd);
+#endif
+}
+
+void
+reopen_exec_file (void)
+{
+#if 0 /* FIXME */
+ if (exec_bfd)
+ bfd_reopen (exec_bfd);
+#else
+ char *filename;
+ int res;
+ struct stat st;
+ long mtime;
+
+ /* Don't do anything if the current target isn't exec. */
+ if (exec_bfd == NULL || strcmp (target_shortname, "exec") != 0)
+ return;
+
+ /* If the timestamp of the exec file has changed, reopen it. */
+ filename = xstrdup (bfd_get_filename (exec_bfd));
+ make_cleanup (xfree, filename);
+ mtime = bfd_get_mtime (exec_bfd);
+ res = stat (filename, &st);
+
+ if (mtime && mtime != st.st_mtime)
+ {
+ exec_open (filename, 0);
+ }
+#endif
+}
+
+/* If we have both a core file and an exec file,
+ print a warning if they don't go together. */
+
+void
+validate_files (void)
+{
+ if (exec_bfd && core_bfd)
+ {
+ if (!core_file_matches_executable_p (core_bfd, exec_bfd))
+ warning ("core file may not match specified executable file.");
+ else if (bfd_get_mtime (exec_bfd) > bfd_get_mtime (core_bfd))
+ warning ("exec file is newer than core file.");
+ }
+}
+
+/* Return the name of the executable file as a string.
+ ERR nonzero means get error if there is none specified;
+ otherwise return 0 in that case. */
+
+char *
+get_exec_file (int err)
+{
+ if (exec_bfd)
+ return bfd_get_filename (exec_bfd);
+ if (!err)
+ return NULL;
+
+ error ("No executable file specified.\n\
+Use the \"file\" or \"exec-file\" command.");
+ return NULL;
+}
+
+
+/* Report a memory error with error(). */
+
+void
+memory_error (int status, CORE_ADDR memaddr)
+{
+ struct ui_file *tmp_stream = mem_fileopen ();
+ make_cleanup_ui_file_delete (tmp_stream);
+
+ if (status == EIO)
+ {
+ /* Actually, address between memaddr and memaddr + len
+ was out of bounds. */
+ fprintf_unfiltered (tmp_stream, "Cannot access memory at address ");
+ print_address_numeric (memaddr, 1, tmp_stream);
+ }
+ else
+ {
+ fprintf_filtered (tmp_stream, "Error accessing memory address ");
+ print_address_numeric (memaddr, 1, tmp_stream);
+ fprintf_filtered (tmp_stream, ": %s.",
+ safe_strerror (status));
+ }
+
+ error_stream (tmp_stream);
+}
+
+/* Same as target_read_memory, but report an error if can't read. */
+void
+read_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ int status;
+ status = target_read_memory (memaddr, myaddr, len);
+ if (status != 0)
+ memory_error (status, memaddr);
+}
+
+/* Like target_read_memory, but slightly different parameters. */
+int
+dis_asm_read_memory (bfd_vma memaddr, bfd_byte *myaddr, unsigned int len,
+ disassemble_info *info)
+{
+ return target_read_memory (memaddr, (char *) myaddr, len);
+}
+
+/* Like memory_error with slightly different parameters. */
+void
+dis_asm_memory_error (int status, bfd_vma memaddr, disassemble_info *info)
+{
+ memory_error (status, memaddr);
+}
+
+/* Like print_address with slightly different parameters. */
+void
+dis_asm_print_address (bfd_vma addr, struct disassemble_info *info)
+{
+ print_address (addr, info->stream);
+}
+
+/* Read an integer from debugged memory, given address and number of bytes. */
+
+struct captured_read_memory_integer_arguments
+{
+ CORE_ADDR memaddr;
+ int len;
+ LONGEST result;
+};
+
+static int
+do_captured_read_memory_integer (void *data)
+{
+ struct captured_read_memory_integer_arguments *args = (struct captured_read_memory_integer_arguments*) data;
+ CORE_ADDR memaddr = args->memaddr;
+ int len = args->len;
+
+ args->result = read_memory_integer (memaddr, len);
+
+ return 0;
+}
+
+int
+safe_read_memory_integer (CORE_ADDR memaddr, int len, LONGEST *return_value)
+{
+ int status;
+ struct captured_read_memory_integer_arguments args;
+ args.memaddr = memaddr;
+ args.len = len;
+
+ status = catch_errors (do_captured_read_memory_integer, &args,
+ "", RETURN_MASK_ALL);
+ if (!status)
+ *return_value = args.result;
+
+ return status;
+}
+
+LONGEST
+read_memory_integer (CORE_ADDR memaddr, int len)
+{
+ char buf[sizeof (LONGEST)];
+
+ read_memory (memaddr, buf, len);
+ return extract_signed_integer (buf, len);
+}
+
+ULONGEST
+read_memory_unsigned_integer (CORE_ADDR memaddr, int len)
+{
+ char buf[sizeof (ULONGEST)];
+
+ read_memory (memaddr, buf, len);
+ return extract_unsigned_integer (buf, len);
+}
+
+void
+read_memory_string (CORE_ADDR memaddr, char *buffer, int max_len)
+{
+ register char *cp;
+ register int i;
+ int cnt;
+
+ cp = buffer;
+ while (1)
+ {
+ if (cp - buffer >= max_len)
+ {
+ buffer[max_len - 1] = '\0';
+ break;
+ }
+ cnt = max_len - (cp - buffer);
+ if (cnt > 8)
+ cnt = 8;
+ read_memory (memaddr + (int) (cp - buffer), cp, cnt);
+ for (i = 0; i < cnt && *cp; i++, cp++)
+ ; /* null body */
+
+ if (i < cnt && !*cp)
+ break;
+ }
+}
+
+/* Same as target_write_memory, but report an error if can't write. */
+void
+write_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ int status;
+
+ status = target_write_memory (memaddr, myaddr, len);
+ if (status != 0)
+ memory_error (status, memaddr);
+}
+
+/* Store VALUE at ADDR in the inferior as a LEN-byte unsigned integer. */
+void
+write_memory_unsigned_integer (CORE_ADDR addr, int len, ULONGEST value)
+{
+ char *buf = alloca (len);
+ store_unsigned_integer (buf, len, value);
+ write_memory (addr, buf, len);
+}
+
+/* Store VALUE at ADDR in the inferior as a LEN-byte signed integer. */
+void
+write_memory_signed_integer (CORE_ADDR addr, int len, LONGEST value)
+{
+ char *buf = alloca (len);
+ store_signed_integer (buf, len, value);
+ write_memory (addr, buf, len);
+}
+
+
+
+#if 0
+/* Enable after 4.12. It is not tested. */
+
+/* Search code. Targets can just make this their search function, or
+ if the protocol has a less general search function, they can call this
+ in the cases it can't handle. */
+void
+generic_search (int len, char *data, char *mask, CORE_ADDR startaddr,
+ int increment, CORE_ADDR lorange, CORE_ADDR hirange,
+ CORE_ADDR *addr_found, char *data_found)
+{
+ int i;
+ CORE_ADDR curaddr = startaddr;
+
+ while (curaddr >= lorange && curaddr < hirange)
+ {
+ read_memory (curaddr, data_found, len);
+ for (i = 0; i < len; ++i)
+ if ((data_found[i] & mask[i]) != data[i])
+ goto try_again;
+ /* It matches. */
+ *addr_found = curaddr;
+ return;
+
+ try_again:
+ curaddr += increment;
+ }
+ *addr_found = (CORE_ADDR) 0;
+ return;
+}
+#endif /* 0 */
+
+/* The current default bfd target. Points to storage allocated for
+ gnutarget_string. */
+char *gnutarget;
+
+/* Same thing, except it is "auto" not NULL for the default case. */
+static char *gnutarget_string;
+
+static void set_gnutarget_command (char *, int, struct cmd_list_element *);
+
+static void
+set_gnutarget_command (char *ignore, int from_tty, struct cmd_list_element *c)
+{
+ if (STREQ (gnutarget_string, "auto"))
+ gnutarget = NULL;
+ else
+ gnutarget = gnutarget_string;
+}
+
+/* Set the gnutarget. */
+void
+set_gnutarget (char *newtarget)
+{
+ if (gnutarget_string != NULL)
+ xfree (gnutarget_string);
+ gnutarget_string = savestring (newtarget, strlen (newtarget));
+ set_gnutarget_command (NULL, 0, NULL);
+}
+
+void
+_initialize_core (void)
+{
+ struct cmd_list_element *c;
+ c = add_cmd ("core-file", class_files, core_file_command,
+ "Use FILE as core dump for examining memory and registers.\n\
+No arg means have no core file. This command has been superseded by the\n\
+`target core' and `detach' commands.", &cmdlist);
+ set_cmd_completer (c, filename_completer);
+
+ c = add_set_cmd ("gnutarget", class_files, var_string_noescape,
+ (char *) &gnutarget_string,
+ "Set the current BFD target.\n\
+Use `set gnutarget auto' to specify automatic detection.",
+ &setlist);
+ set_cmd_sfunc (c, set_gnutarget_command);
+ add_show_from_set (c, &showlist);
+
+ if (getenv ("GNUTARGET"))
+ set_gnutarget (getenv ("GNUTARGET"));
+ else
+ set_gnutarget ("auto");
+}
diff --git a/gdb/corelow.c b/gdb/corelow.c
new file mode 100644
index 00000000000..785b8e14323
--- /dev/null
+++ b/gdb/corelow.c
@@ -0,0 +1,545 @@
+/* Core dump and executable file functions below target vector, for GDB.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "gdb_string.h"
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h> /* needed for F_OK and friends */
+#endif
+#include "frame.h" /* required by inferior.h */
+#include "inferior.h"
+#include "symtab.h"
+#include "command.h"
+#include "bfd.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "gdbthread.h"
+#include "regcache.h"
+#include "symfile.h"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/* List of all available core_fns. On gdb startup, each core file register
+ reader calls add_core_fns() to register information on each core format it
+ is prepared to read. */
+
+static struct core_fns *core_file_fns = NULL;
+
+/* The core_fns for a core file handler that is prepared to read the core
+ file currently open on core_bfd. */
+
+static struct core_fns *core_vec = NULL;
+
+static void core_files_info (struct target_ops *);
+
+#ifdef SOLIB_ADD
+static int solib_add_stub (PTR);
+#endif
+
+static struct core_fns *sniff_core_bfd (bfd *);
+
+static boolean gdb_check_format (bfd *);
+
+static void core_open (char *, int);
+
+static void core_detach (char *, int);
+
+static void core_close (int);
+
+static void core_close_cleanup (void *ignore);
+
+static void get_core_registers (int);
+
+static void add_to_thread_list (bfd *, asection *, PTR);
+
+static int ignore (CORE_ADDR, char *);
+
+static int core_file_thread_alive (ptid_t tid);
+
+static void init_core_ops (void);
+
+void _initialize_corelow (void);
+
+struct target_ops core_ops;
+
+/* Link a new core_fns into the global core_file_fns list. Called on gdb
+ startup by the _initialize routine in each core file register reader, to
+ register information about each format the the reader is prepared to
+ handle. */
+
+void
+add_core_fns (struct core_fns *cf)
+{
+ cf->next = core_file_fns;
+ core_file_fns = cf;
+}
+
+/* The default function that core file handlers can use to examine a
+ core file BFD and decide whether or not to accept the job of
+ reading the core file. */
+
+int
+default_core_sniffer (struct core_fns *our_fns, bfd *abfd)
+{
+ int result;
+
+ result = (bfd_get_flavour (abfd) == our_fns -> core_flavour);
+ return (result);
+}
+
+/* Walk through the list of core functions to find a set that can
+ handle the core file open on ABFD. Default to the first one in the
+ list if nothing matches. Returns pointer to set that is
+ selected. */
+
+static struct core_fns *
+sniff_core_bfd (bfd *abfd)
+{
+ struct core_fns *cf;
+ struct core_fns *yummy = NULL;
+ int matches = 0;;
+
+ for (cf = core_file_fns; cf != NULL; cf = cf->next)
+ {
+ if (cf->core_sniffer (cf, abfd))
+ {
+ yummy = cf;
+ matches++;
+ }
+ }
+ if (matches > 1)
+ {
+ warning ("\"%s\": ambiguous core format, %d handlers match",
+ bfd_get_filename (abfd), matches);
+ }
+ else if (matches == 0)
+ {
+ warning ("\"%s\": no core file handler recognizes format, using default",
+ bfd_get_filename (abfd));
+ }
+ if (yummy == NULL)
+ {
+ yummy = core_file_fns;
+ }
+ return (yummy);
+}
+
+/* The default is to reject every core file format we see. Either
+ BFD has to recognize it, or we have to provide a function in the
+ core file handler that recognizes it. */
+
+int
+default_check_format (bfd *abfd)
+{
+ return (0);
+}
+
+/* Attempt to recognize core file formats that BFD rejects. */
+
+static boolean
+gdb_check_format (bfd *abfd)
+{
+ struct core_fns *cf;
+
+ for (cf = core_file_fns; cf != NULL; cf = cf->next)
+ {
+ if (cf->check_format (abfd))
+ {
+ return (1);
+ }
+ }
+ return (0);
+}
+
+/* Discard all vestiges of any previous core file and mark data and stack
+ spaces as empty. */
+
+/* ARGSUSED */
+static void
+core_close (int quitting)
+{
+ char *name;
+
+ if (core_bfd)
+ {
+ inferior_ptid = null_ptid; /* Avoid confusion from thread stuff */
+
+ /* Clear out solib state while the bfd is still open. See
+ comments in clear_solib in solib.c. */
+#ifdef CLEAR_SOLIB
+ CLEAR_SOLIB ();
+#endif
+
+ name = bfd_get_filename (core_bfd);
+ if (!bfd_close (core_bfd))
+ warning ("cannot close \"%s\": %s",
+ name, bfd_errmsg (bfd_get_error ()));
+ xfree (name);
+ core_bfd = NULL;
+ if (core_ops.to_sections)
+ {
+ xfree (core_ops.to_sections);
+ core_ops.to_sections = NULL;
+ core_ops.to_sections_end = NULL;
+ }
+ }
+ core_vec = NULL;
+}
+
+static void
+core_close_cleanup (void *ignore)
+{
+ core_close (0/*ignored*/);
+}
+
+#ifdef SOLIB_ADD
+/* Stub function for catch_errors around shared library hacking. FROM_TTYP
+ is really an int * which points to from_tty. */
+
+static int
+solib_add_stub (PTR from_ttyp)
+{
+ SOLIB_ADD (NULL, *(int *) from_ttyp, &current_target, auto_solib_add);
+ re_enable_breakpoints_in_shlibs ();
+ return 0;
+}
+#endif /* SOLIB_ADD */
+
+/* Look for sections whose names start with `.reg/' so that we can extract the
+ list of threads in a core file. */
+
+static void
+add_to_thread_list (bfd *abfd, asection *asect, PTR reg_sect_arg)
+{
+ int thread_id;
+ asection *reg_sect = (asection *) reg_sect_arg;
+
+ if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
+ return;
+
+ thread_id = atoi (bfd_section_name (abfd, asect) + 5);
+
+ add_thread (pid_to_ptid (thread_id));
+
+/* Warning, Will Robinson, looking at BFD private data! */
+
+ if (reg_sect != NULL
+ && asect->filepos == reg_sect->filepos) /* Did we find .reg? */
+ inferior_ptid = pid_to_ptid (thread_id); /* Yes, make it current */
+}
+
+/* This routine opens and sets up the core file bfd. */
+
+static void
+core_open (char *filename, int from_tty)
+{
+ const char *p;
+ int siggy;
+ struct cleanup *old_chain;
+ char *temp;
+ bfd *temp_bfd;
+ int ontop;
+ int scratch_chan;
+
+ target_preopen (from_tty);
+ if (!filename)
+ {
+ error (core_bfd ?
+ "No core file specified. (Use `detach' to stop debugging a core file.)"
+ : "No core file specified.");
+ }
+
+ filename = tilde_expand (filename);
+ if (filename[0] != '/')
+ {
+ temp = concat (current_directory, "/", filename, NULL);
+ xfree (filename);
+ filename = temp;
+ }
+
+ old_chain = make_cleanup (xfree, filename);
+
+ scratch_chan = open (filename, O_BINARY | ( write_files ? O_RDWR : O_RDONLY ), 0);
+ if (scratch_chan < 0)
+ perror_with_name (filename);
+
+ temp_bfd = bfd_fdopenr (filename, gnutarget, scratch_chan);
+ if (temp_bfd == NULL)
+ perror_with_name (filename);
+
+ if (!bfd_check_format (temp_bfd, bfd_core) &&
+ !gdb_check_format (temp_bfd))
+ {
+ /* Do it after the err msg */
+ /* FIXME: should be checking for errors from bfd_close (for one thing,
+ on error it does not free all the storage associated with the
+ bfd). */
+ make_cleanup_bfd_close (temp_bfd);
+ error ("\"%s\" is not a core dump: %s",
+ filename, bfd_errmsg (bfd_get_error ()));
+ }
+
+ /* Looks semi-reasonable. Toss the old core file and work on the new. */
+
+ discard_cleanups (old_chain); /* Don't free filename any more */
+ unpush_target (&core_ops);
+ core_bfd = temp_bfd;
+ old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/);
+
+ /* Find a suitable core file handler to munch on core_bfd */
+ core_vec = sniff_core_bfd (core_bfd);
+
+ validate_files ();
+
+ /* Find the data section */
+ if (build_section_table (core_bfd, &core_ops.to_sections,
+ &core_ops.to_sections_end))
+ error ("\"%s\": Can't find sections: %s",
+ bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));
+
+ /* If we have no exec file, try to set the architecture from the
+ core file. We don't do this unconditionally since an exec file
+ typically contains more information that helps us determine the
+ architecture than a core file. */
+ if (!exec_bfd)
+ set_gdbarch_from_file (core_bfd);
+
+ ontop = !push_target (&core_ops);
+ discard_cleanups (old_chain);
+
+ p = bfd_core_file_failing_command (core_bfd);
+ if (p)
+ printf_filtered ("Core was generated by `%s'.\n", p);
+
+ siggy = bfd_core_file_failing_signal (core_bfd);
+ if (siggy > 0)
+ /* NOTE: target_signal_from_host() converts a target signal value
+ into gdb's internal signal value. Unfortunately gdb's internal
+ value is called ``target_signal'' and this function got the
+ name ..._from_host(). */
+ printf_filtered ("Program terminated with signal %d, %s.\n", siggy,
+ target_signal_to_string (target_signal_from_host (siggy)));
+
+ /* Build up thread list from BFD sections. */
+
+ init_thread_list ();
+ bfd_map_over_sections (core_bfd, add_to_thread_list,
+ bfd_get_section_by_name (core_bfd, ".reg"));
+
+ if (ontop)
+ {
+ /* Fetch all registers from core file. */
+ target_fetch_registers (-1);
+
+ /* Add symbols and section mappings for any shared libraries. */
+#ifdef SOLIB_ADD
+ catch_errors (solib_add_stub, &from_tty, (char *) 0,
+ RETURN_MASK_ALL);
+#endif
+
+ /* Now, set up the frame cache, and print the top of stack. */
+ flush_cached_frames ();
+ select_frame (get_current_frame ());
+ print_stack_frame (selected_frame,
+ frame_relative_level (selected_frame), 1);
+ }
+ else
+ {
+ warning (
+ "you won't be able to access this core file until you terminate\n\
+your %s; do ``info files''", target_longname);
+ }
+}
+
+static void
+core_detach (char *args, int from_tty)
+{
+ if (args)
+ error ("Too many arguments");
+ unpush_target (&core_ops);
+ reinit_frame_cache ();
+ if (from_tty)
+ printf_filtered ("No core file now.\n");
+}
+
+
+/* Try to retrieve registers from a section in core_bfd, and supply
+ them to core_vec->core_read_registers, as the register set numbered
+ WHICH.
+
+ If inferior_ptid is zero, do the single-threaded thing: look for a
+ section named NAME. If inferior_ptid is non-zero, do the
+ multi-threaded thing: look for a section named "NAME/PID", where
+ PID is the shortest ASCII decimal representation of inferior_ptid.
+
+ HUMAN_NAME is a human-readable name for the kind of registers the
+ NAME section contains, for use in error messages.
+
+ If REQUIRED is non-zero, print an error if the core file doesn't
+ have a section by the appropriate name. Otherwise, just do nothing. */
+
+static void
+get_core_register_section (char *name,
+ int which,
+ char *human_name,
+ int required)
+{
+ char section_name[100];
+ sec_ptr section;
+ bfd_size_type size;
+ char *contents;
+
+ if (PIDGET (inferior_ptid))
+ sprintf (section_name, "%s/%d", name, PIDGET (inferior_ptid));
+ else
+ strcpy (section_name, name);
+
+ section = bfd_get_section_by_name (core_bfd, section_name);
+ if (! section)
+ {
+ if (required)
+ warning ("Couldn't find %s registers in core file.\n", human_name);
+ return;
+ }
+
+ size = bfd_section_size (core_bfd, section);
+ contents = alloca (size);
+ if (! bfd_get_section_contents (core_bfd, section, contents,
+ (file_ptr) 0, size))
+ {
+ warning ("Couldn't read %s registers from `%s' section in core file.\n",
+ human_name, name);
+ return;
+ }
+
+ core_vec->core_read_registers (contents, size, which,
+ ((CORE_ADDR)
+ bfd_section_vma (core_bfd, section)));
+}
+
+
+/* Get the registers out of a core file. This is the machine-
+ independent part. Fetch_core_registers is the machine-dependent
+ part, typically implemented in the xm-file for each architecture. */
+
+/* We just get all the registers, so we don't use regno. */
+
+/* ARGSUSED */
+static void
+get_core_registers (int regno)
+{
+ int status;
+
+ if (core_vec == NULL
+ || core_vec->core_read_registers == NULL)
+ {
+ fprintf_filtered (gdb_stderr,
+ "Can't fetch registers from this type of core file\n");
+ return;
+ }
+
+ get_core_register_section (".reg", 0, "general-purpose", 1);
+ get_core_register_section (".reg2", 2, "floating-point", 0);
+ get_core_register_section (".reg-xfp", 3, "extended floating-point", 0);
+
+ registers_fetched ();
+}
+
+static void
+core_files_info (struct target_ops *t)
+{
+ print_section_info (t, core_bfd);
+}
+
+/* If mourn is being called in all the right places, this could be say
+ `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */
+
+static int
+ignore (CORE_ADDR addr, char *contents)
+{
+ return 0;
+}
+
+
+/* Okay, let's be honest: threads gleaned from a core file aren't
+ exactly lively, are they? On the other hand, if we don't claim
+ that each & every one is alive, then we don't get any of them
+ to appear in an "info thread" command, which is quite a useful
+ behaviour.
+ */
+static int
+core_file_thread_alive (ptid_t tid)
+{
+ return 1;
+}
+
+/* Fill in core_ops with its defined operations and properties. */
+
+static void
+init_core_ops (void)
+{
+ core_ops.to_shortname = "core";
+ core_ops.to_longname = "Local core dump file";
+ core_ops.to_doc =
+ "Use a core file as a target. Specify the filename of the core file.";
+ core_ops.to_open = core_open;
+ core_ops.to_close = core_close;
+ core_ops.to_attach = find_default_attach;
+ core_ops.to_require_attach = find_default_require_attach;
+ core_ops.to_detach = core_detach;
+ core_ops.to_require_detach = find_default_require_detach;
+ core_ops.to_fetch_registers = get_core_registers;
+ core_ops.to_xfer_memory = xfer_memory;
+ core_ops.to_files_info = core_files_info;
+ core_ops.to_insert_breakpoint = ignore;
+ core_ops.to_remove_breakpoint = ignore;
+ core_ops.to_create_inferior = find_default_create_inferior;
+ core_ops.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior;
+ core_ops.to_thread_alive = core_file_thread_alive;
+ core_ops.to_stratum = core_stratum;
+ core_ops.to_has_memory = 1;
+ core_ops.to_has_stack = 1;
+ core_ops.to_has_registers = 1;
+ core_ops.to_magic = OPS_MAGIC;
+}
+
+/* non-zero if we should not do the add_target call in
+ _initialize_corelow; not initialized (i.e., bss) so that
+ the target can initialize it (i.e., data) if appropriate.
+ This needs to be set at compile time because we don't know
+ for sure whether the target's initialize routine is called
+ before us or after us. */
+int coreops_suppress_target;
+
+void
+_initialize_corelow (void)
+{
+ init_core_ops ();
+
+ if (!coreops_suppress_target)
+ add_target (&core_ops);
+}
diff --git a/gdb/cp-abi.c b/gdb/cp-abi.c
new file mode 100644
index 00000000000..d4eb0a00d08
--- /dev/null
+++ b/gdb/cp-abi.c
@@ -0,0 +1,109 @@
+/* Generic code for supporting multiple C++ ABI's
+ Copyright 2001 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 "defs.h"
+#include "value.h"
+#include "cp-abi.h"
+
+struct cp_abi_ops current_cp_abi;
+
+struct cp_abi_ops *cp_abis;
+
+int num_cp_abis = 0;
+
+enum ctor_kinds
+is_constructor_name (const char *name)
+{
+ if ((current_cp_abi.is_constructor_name) == NULL)
+ error ("ABI doesn't define required function is_constructor_name");
+ return (*current_cp_abi.is_constructor_name) (name);
+}
+
+enum dtor_kinds
+is_destructor_name (const char *name)
+{
+ if ((current_cp_abi.is_destructor_name) == NULL)
+ error ("ABI doesn't define required function is_destructor_name");
+ return (*current_cp_abi.is_destructor_name) (name);
+}
+
+int
+is_vtable_name (const char *name)
+{
+ if ((current_cp_abi.is_vtable_name) == NULL)
+ error ("ABI doesn't define required function is_vtable_name");
+ return (*current_cp_abi.is_vtable_name) (name);
+}
+
+int
+is_operator_name (const char *name)
+{
+ if ((current_cp_abi.is_operator_name) == NULL)
+ error ("ABI doesn't define required function is_operator_name");
+ return (*current_cp_abi.is_operator_name) (name);
+}
+
+int
+baseclass_offset (struct type *type, int index, char *valaddr,
+ CORE_ADDR address)
+{
+ if (current_cp_abi.baseclass_offset == NULL)
+ error ("ABI doesn't define required function baseclass_offset");
+ return (*current_cp_abi.baseclass_offset) (type, index, valaddr, address);
+}
+
+struct value *
+value_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j,
+ struct type * type, int offset)
+{
+ if ((current_cp_abi.virtual_fn_field) == NULL)
+ return NULL;
+ return (*current_cp_abi.virtual_fn_field) (arg1p, f, j, type, offset);
+}
+
+struct type *
+value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
+{
+ if ((current_cp_abi.rtti_type) == NULL)
+ return NULL;
+ return (*current_cp_abi.rtti_type) (v, full, top, using_enc);
+}
+
+int
+register_cp_abi (struct cp_abi_ops abi)
+{
+ cp_abis =
+ xrealloc (cp_abis, (num_cp_abis + 1) * sizeof (struct cp_abi_ops));
+ cp_abis[num_cp_abis++] = abi;
+
+ return 1;
+
+}
+
+int
+switch_to_cp_abi (const char *short_name)
+{
+ int i;
+ for (i = 0; i < num_cp_abis; i++)
+ if (strcmp (cp_abis[i].shortname, short_name) == 0)
+ current_cp_abi = cp_abis[i];
+ return 1;
+}
+
diff --git a/gdb/cp-abi.h b/gdb/cp-abi.h
new file mode 100644
index 00000000000..7c1e9521e03
--- /dev/null
+++ b/gdb/cp-abi.h
@@ -0,0 +1,173 @@
+/* Abstraction of various C++ ABI's we support, and the info we need
+ to get from them.
+ Contributed by Daniel Berlin <dberlin@redhat.com>
+ Copyright 2001 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. */
+
+#ifndef CP_ABI_H_
+#define CP_ABI_H_ 1
+
+struct value;
+
+/* The functions here that attempt to determine what sort of thing a
+ mangled name refers to may well be revised in the future. It would
+ certainly be cleaner to carry this information explicitly in GDB's
+ data structures than to derive it from the mangled name. */
+
+
+/* Kinds of constructors. All these values are guaranteed to be
+ non-zero. */
+enum ctor_kinds {
+
+ /* Initialize a complete object, including virtual bases, using
+ memory provided by caller. */
+ complete_object_ctor = 1,
+
+ /* Initialize a base object of some larger object. */
+ base_object_ctor,
+
+ /* An allocating complete-object constructor. */
+ complete_object_allocating_ctor
+};
+
+/* Return non-zero iff NAME is the mangled name of a constructor.
+ Actually, return an `enum ctor_kind' value describing what *kind*
+ of constructor it is. */
+extern enum ctor_kinds is_constructor_name (const char *name);
+
+
+/* Kinds of destructors. All these values are guaranteed to be
+ non-zero. */
+enum dtor_kinds {
+
+ /* A destructor which finalizes the entire object, and then calls
+ `delete' on its storage. */
+ deleting_dtor = 1,
+
+ /* A destructor which finalizes the entire object, but does not call
+ `delete'. */
+ complete_object_dtor,
+
+ /* A destructor which finalizes a subobject of some larger object. */
+ base_object_dtor
+};
+
+/* Return non-zero iff NAME is the mangled name of a destructor.
+ Actually, return an `enum dtor_kind' value describing what *kind*
+ of destructor it is. */
+extern enum dtor_kinds is_destructor_name (const char *name);
+
+
+/* Return non-zero iff NAME is the mangled name of a vtable. */
+extern int is_vtable_name (const char *name);
+
+
+/* Return non-zero iff NAME is the un-mangled name of an operator,
+ perhaps scoped within some class. */
+extern int is_operator_name (const char *name);
+
+
+/* Return an object's virtual function as a value.
+
+ VALUEP is a pointer to a pointer to a value, holding the object
+ whose virtual function we want to invoke. If the ABI requires a
+ virtual function's caller to adjust the `this' pointer by an amount
+ retrieved from the vtable before invoking the function (i.e., we're
+ not using "vtable thunks" to do the adjustment automatically), then
+ this function may set *VALUEP to point to a new object with an
+ appropriately tweaked address.
+
+ The J'th element of the overload set F is the virtual function of
+ *VALUEP we want to invoke.
+
+ TYPE is the base type of *VALUEP whose method we're invoking ---
+ this is the type containing F. OFFSET is the offset of that base
+ type within *VALUEP. */
+extern struct value *value_virtual_fn_field (struct value **valuep,
+ struct fn_field *f, int j,
+ struct type *type, int offset);
+
+
+/* Try to find the run-time type of VALUE, using C++ run-time type
+ information. Return the run-time type, or zero if we can't figure
+ it out.
+
+ If we do find the run-time type:
+ - Set *FULL to non-zero if VALUE already contains the complete
+ run-time object, not just some embedded base class of the object.
+ - Set *TOP and *USING_ENC to indicate where the enclosing object
+ starts relative to VALUE:
+ - If *USING_ENC is zero, then *TOP is the offset from the start
+ of the complete object to the start of the embedded subobject
+ VALUE represents. In other words, the enclosing object starts
+ at VALUE_ADDR (VALUE) + VALUE_OFFSET (VALUE) +
+ VALUE_EMBEDDED_OFFSET (VALUE) + *TOP
+ - If *USING_ENC is non-zero, then *TOP is the offset from the
+ address of the complete object to the enclosing object stored
+ in VALUE. In other words, the enclosing object starts at
+ VALUE_ADDR (VALUE) + VALUE_OFFSET (VALUE) + *TOP.
+ If VALUE's type and enclosing type are the same, then these two
+ cases are equivalent.
+
+ FULL, TOP, and USING_ENC can each be zero, in which case we don't
+ provide the corresponding piece of information. */
+extern struct type *value_rtti_type (struct value *value,
+ int *full, int *top, int *using_enc);
+
+/* Compute the offset of the baseclass which is
+ the INDEXth baseclass of class TYPE,
+ for value at VALADDR (in host) at ADDRESS (in target).
+ The result is the offset of the baseclass value relative
+ to (the address of)(ARG) + OFFSET.
+
+ -1 is returned on error. */
+
+extern int baseclass_offset (struct type *type, int index, char *valaddr,
+ CORE_ADDR address);
+
+struct cp_abi_ops
+{
+ const char *shortname;
+ const char *longname;
+ const char *doc;
+
+ /* ABI-specific implementations for the functions declared above. */
+ enum ctor_kinds (*is_constructor_name) (const char *name);
+ enum dtor_kinds (*is_destructor_name) (const char *name);
+ int (*is_vtable_name) (const char *name);
+ int (*is_operator_name) (const char *name);
+ struct value *(*virtual_fn_field) (struct value **arg1p, struct fn_field * f,
+ int j, struct type * type, int offset);
+ struct type *(*rtti_type) (struct value *v, int *full, int *top,
+ int *using_enc);
+ int (*baseclass_offset) (struct type *type, int index, char *valaddr,
+ CORE_ADDR address);
+};
+
+
+extern struct cp_abi_ops *cp_abis;
+extern int num_cp_abis;
+extern struct cp_abi_ops current_cp_abi;
+extern int register_cp_abi (struct cp_abi_ops abi);
+extern int switch_to_cp_abi (const char *short_name);
+
+#endif
+
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
new file mode 100644
index 00000000000..7ea9f3f94e9
--- /dev/null
+++ b/gdb/cp-valprint.c
@@ -0,0 +1,853 @@
+/* Support for printing C++ values for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 2000, 2001, 2002
+ 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 "defs.h"
+#include "obstack.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "demangle.h"
+#include "annotate.h"
+#include "gdb_string.h"
+#include "c-lang.h"
+#include "target.h"
+#include "cp-abi.h"
+
+/* Indication of presence of HP-compiled object files */
+extern int hp_som_som_object_present; /* defined in symtab.c */
+
+
+int vtblprint; /* Controls printing of vtbl's */
+int objectprint; /* Controls looking up an object's derived type
+ using what we find in its vtables. */
+int static_field_print; /* Controls printing of static fields. */
+
+static struct obstack dont_print_vb_obstack;
+static struct obstack dont_print_statmem_obstack;
+
+extern void _initialize_cp_valprint (void);
+
+static void cp_print_static_field (struct type *, struct value *,
+ struct ui_file *, int, int,
+ enum val_prettyprint);
+
+static void cp_print_value (struct type *, struct type *, char *, int,
+ CORE_ADDR, struct ui_file *, int, int,
+ enum val_prettyprint, struct type **);
+
+static void cp_print_hpacc_virtual_table_entries (struct type *, int *,
+ struct value *,
+ struct ui_file *, int,
+ int,
+ enum val_prettyprint);
+
+
+void
+cp_print_class_method (char *valaddr,
+ struct type *type,
+ struct ui_file *stream)
+{
+ struct type *domain;
+ struct fn_field *f = NULL;
+ int j = 0;
+ int len2;
+ int offset;
+ char *kind = "";
+ CORE_ADDR addr;
+ struct symbol *sym;
+ unsigned len;
+ unsigned int i;
+ struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
+
+ domain = TYPE_DOMAIN_TYPE (target_type);
+ if (domain == (struct type *) NULL)
+ {
+ fprintf_filtered (stream, "<unknown>");
+ return;
+ }
+ addr = unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr);
+ if (METHOD_PTR_IS_VIRTUAL (addr))
+ {
+ offset = METHOD_PTR_TO_VOFFSET (addr);
+ len = TYPE_NFN_FIELDS (domain);
+ for (i = 0; i < len; i++)
+ {
+ f = TYPE_FN_FIELDLIST1 (domain, i);
+ len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
+
+ for (j = 0; j < len2; j++)
+ {
+ QUIT;
+ if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
+ {
+ if (TYPE_FN_FIELD_STUB (f, j))
+ check_stub_method (domain, i, j);
+ kind = "virtual ";
+ goto common;
+ }
+ }
+ }
+ }
+ else
+ {
+ sym = find_pc_function (addr);
+ if (sym == 0)
+ {
+ /* 1997-08-01 Currently unsupported with HP aCC */
+ if (hp_som_som_object_present)
+ {
+ fputs_filtered ("?? <not supported with HP aCC>", stream);
+ return;
+ }
+ error ("invalid pointer to member function");
+ }
+ len = TYPE_NFN_FIELDS (domain);
+ for (i = 0; i < len; i++)
+ {
+ f = TYPE_FN_FIELDLIST1 (domain, i);
+ len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
+
+ for (j = 0; j < len2; j++)
+ {
+ QUIT;
+ if (TYPE_FN_FIELD_STUB (f, j))
+ check_stub_method (domain, i, j);
+ if (STREQ (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
+ {
+ goto common;
+ }
+ }
+ }
+ }
+ common:
+ if (i < len)
+ {
+ char *demangled_name;
+
+ fprintf_filtered (stream, "&");
+ fprintf_filtered (stream, kind);
+ demangled_name = cplus_demangle (TYPE_FN_FIELD_PHYSNAME (f, j),
+ DMGL_ANSI | DMGL_PARAMS);
+ if (demangled_name == NULL)
+ fprintf_filtered (stream, "<badly mangled name %s>",
+ TYPE_FN_FIELD_PHYSNAME (f, j));
+ else
+ {
+ fputs_filtered (demangled_name, stream);
+ xfree (demangled_name);
+ }
+ }
+ else
+ {
+ fprintf_filtered (stream, "(");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, ") %d", (int) addr >> 3);
+ }
+}
+
+/* This was what it was for gcc 2.4.5 and earlier. */
+static const char vtbl_ptr_name_old[] =
+{
+ CPLUS_MARKER, 'v', 't', 'b', 'l', '_', 'p', 't', 'r', '_',
+ 't', 'y', 'p', 'e', 0
+};
+
+/* It was changed to this after 2.4.5. */
+const char vtbl_ptr_name[] = "__vtbl_ptr_type";
+
+/* HP aCC uses different names */
+const char hpacc_vtbl_ptr_name[] = "__vfp";
+const char hpacc_vtbl_ptr_type_name[] = "__vftyp";
+
+
+/* Return truth value for assertion that TYPE is of the type
+ "pointer to virtual function". */
+
+int
+cp_is_vtbl_ptr_type (struct type *type)
+{
+ char *typename = type_name_no_tag (type);
+
+ return (typename != NULL
+ && (STREQ (typename, vtbl_ptr_name)
+ || STREQ (typename, vtbl_ptr_name_old)));
+}
+
+/* Return truth value for the assertion that TYPE is of the type
+ "pointer to virtual function table". */
+
+int
+cp_is_vtbl_member (struct type *type)
+{
+ /* With older versions of g++, the vtbl field pointed to an array
+ of structures. Nowadays it points directly to the structure. */
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ type = TYPE_TARGET_TYPE (type);
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ type = TYPE_TARGET_TYPE (type);
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT /* if not using thunks */
+ || TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */
+ {
+ /* Virtual functions tables are full of pointers
+ to virtual functions. */
+ return cp_is_vtbl_ptr_type (type);
+ }
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_STRUCT) /* if not using thunks */
+ {
+ return cp_is_vtbl_ptr_type (type);
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */
+ {
+ /* The type name of the thunk pointer is NULL when using dwarf2.
+ We could test for a pointer to a function, but there is
+ no type info for the virtual table either, so it wont help. */
+ return cp_is_vtbl_ptr_type (type);
+ }
+ }
+ return 0;
+}
+
+/* Mutually recursive subroutines of cp_print_value and c_val_print to
+ print out a structure's fields: cp_print_value_fields and cp_print_value.
+
+ TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the
+ same meanings as in cp_print_value and c_val_print.
+
+ 2nd argument REAL_TYPE is used to carry over the type of the derived
+ class across the recursion to base classes.
+
+ DONT_PRINT is an array of baseclass types that we
+ should not print, or zero if called from top level. */
+
+void
+cp_print_value_fields (struct type *type, struct type *real_type, char *valaddr,
+ int offset, CORE_ADDR address, struct ui_file *stream,
+ int format, int recurse, enum val_prettyprint pretty,
+ struct type **dont_print_vb, int dont_print_statmem)
+{
+ int i, len, n_baseclasses;
+ struct obstack tmp_obstack;
+ char *last_dont_print = obstack_next_free (&dont_print_statmem_obstack);
+ int fields_seen = 0;
+
+ CHECK_TYPEDEF (type);
+
+ fprintf_filtered (stream, "{");
+ len = TYPE_NFIELDS (type);
+ n_baseclasses = TYPE_N_BASECLASSES (type);
+
+ /* First, print out baseclasses such that we don't print
+ duplicates of virtual baseclasses. */
+
+ if (n_baseclasses > 0)
+ cp_print_value (type, real_type, valaddr, offset, address, stream,
+ format, recurse + 1, pretty, dont_print_vb);
+
+ /* Second, print out data fields */
+
+ /* If there are no data fields, or if the only field is the
+ * vtbl pointer, skip this part */
+ if ((len == n_baseclasses)
+ || ((len - n_baseclasses == 1)
+ && TYPE_HAS_VTABLE (type)
+ && STREQN (TYPE_FIELD_NAME (type, n_baseclasses),
+ hpacc_vtbl_ptr_name, 5))
+ || !len)
+ fprintf_filtered (stream, "<No data fields>");
+ else
+ {
+ extern int inspect_it;
+
+ if (dont_print_statmem == 0)
+ {
+ /* If we're at top level, carve out a completely fresh
+ chunk of the obstack and use that until this particular
+ invocation returns. */
+ tmp_obstack = dont_print_statmem_obstack;
+ obstack_finish (&dont_print_statmem_obstack);
+ }
+
+ for (i = n_baseclasses; i < len; i++)
+ {
+ /* If requested, skip printing of static fields. */
+ if (!static_field_print && TYPE_FIELD_STATIC (type, i))
+ continue;
+
+ /* If a vtable pointer appears, we'll print it out later */
+ if (TYPE_HAS_VTABLE (type)
+ && STREQN (TYPE_FIELD_NAME (type, i), hpacc_vtbl_ptr_name, 5))
+ continue;
+
+ if (fields_seen)
+ fprintf_filtered (stream, ", ");
+ else if (n_baseclasses > 0)
+ {
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ fputs_filtered ("members of ", stream);
+ fputs_filtered (type_name_no_tag (type), stream);
+ fputs_filtered (": ", stream);
+ }
+ }
+ fields_seen = 1;
+
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ else
+ {
+ wrap_here (n_spaces (2 + 2 * recurse));
+ }
+ if (inspect_it)
+ {
+ if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)
+ fputs_filtered ("\"( ptr \"", stream);
+ else
+ fputs_filtered ("\"( nodef \"", stream);
+ if (TYPE_FIELD_STATIC (type, i))
+ fputs_filtered ("static ", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
+ fputs_filtered ("\" \"", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
+ fputs_filtered ("\") \"", stream);
+ }
+ else
+ {
+ annotate_field_begin (TYPE_FIELD_TYPE (type, i));
+
+ if (TYPE_FIELD_STATIC (type, i))
+ fputs_filtered ("static ", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
+ annotate_field_name_end ();
+ /* do not print leading '=' in case of anonymous unions */
+ if (strcmp (TYPE_FIELD_NAME (type, i), ""))
+ fputs_filtered (" = ", stream);
+ annotate_field_value ();
+ }
+
+ if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i))
+ {
+ struct value *v;
+
+ /* Bitfields require special handling, especially due to byte
+ order problems. */
+ if (TYPE_FIELD_IGNORE (type, i))
+ {
+ fputs_filtered ("<optimized out or zero length>", stream);
+ }
+ else
+ {
+ v = value_from_longest
+ (TYPE_FIELD_TYPE (type, i),
+ unpack_field_as_long (type, valaddr + offset, i));
+
+ val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v),
+ 0, 0, stream, format, 0, recurse + 1, pretty);
+ }
+ }
+ else
+ {
+ if (TYPE_FIELD_IGNORE (type, i))
+ {
+ fputs_filtered ("<optimized out or zero length>", stream);
+ }
+ else if (TYPE_FIELD_STATIC (type, i))
+ {
+ struct value *v = value_static_field (type, i);
+ if (v == NULL)
+ fputs_filtered ("<optimized out>", stream);
+ else
+ cp_print_static_field (TYPE_FIELD_TYPE (type, i), v,
+ stream, format, recurse + 1,
+ pretty);
+ }
+ else
+ {
+ val_print (TYPE_FIELD_TYPE (type, i),
+ valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8,
+ address + TYPE_FIELD_BITPOS (type, i) / 8,
+ stream, format, 0, recurse + 1, pretty);
+ }
+ }
+ annotate_field_end ();
+ }
+
+ if (dont_print_statmem == 0)
+ {
+ /* Free the space used to deal with the printing
+ of the members from top level. */
+ obstack_free (&dont_print_statmem_obstack, last_dont_print);
+ dont_print_statmem_obstack = tmp_obstack;
+ }
+
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 * recurse, stream);
+ }
+ } /* if there are data fields */
+ /* Now print out the virtual table pointer if there is one */
+ if (TYPE_HAS_VTABLE (type)
+ && STREQN (TYPE_FIELD_NAME (type, n_baseclasses),
+ hpacc_vtbl_ptr_name,
+ 5))
+ {
+ struct value *v;
+ /* First get the virtual table pointer and print it out */
+
+#if 0
+ fputs_filtered ("__vfp = ", stream);
+#endif
+
+ fputs_filtered (", Virtual table at ", stream);
+
+ /* pai: FIXME 32x64 problem? */
+ /* Not sure what the best notation is in the case where there is no
+ baseclass name. */
+ v = value_from_pointer (lookup_pointer_type (builtin_type_unsigned_long),
+ *(unsigned long *) (valaddr + offset));
+
+ val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0,
+ stream, format, 0, recurse + 1, pretty);
+ fields_seen = 1;
+
+ if (vtblprint)
+ {
+ /* Print out function pointers in vtable. */
+
+ /* FIXME: then-clause is for non-RRBC layout of virtual
+ * table. The RRBC case in the else-clause is yet to be
+ * implemented. The if (1) below should be changed to a
+ * test for whether the executable we have was compiled
+ * with a version of HP aCC that doesn't have RRBC
+ * support. */
+
+ if (1)
+ {
+ /* no RRBC support; function pointers embedded directly
+ in vtable */
+
+ int vfuncs = count_virtual_fns (real_type);
+
+ fputs_filtered (" {", stream);
+
+ /* FIXME : doesn't work at present */
+#if 0
+ fprintf_filtered (stream, "%d entr%s: ", vfuncs,
+ vfuncs == 1 ? "y" : "ies");
+#else
+ fputs_filtered ("not implemented", stream);
+
+
+#endif
+
+ /* recursive function that prints all virtual function entries */
+#if 0
+ cp_print_hpacc_virtual_table_entries (real_type, &vfuncs, v,
+ stream, format, recurse,
+ pretty);
+#endif
+ fputs_filtered ("}", stream);
+ } /* non-RRBC case */
+ else
+ {
+ /* FIXME -- see comments above */
+ /* RRBC support present; function pointers are found
+ * by indirection through the class segment entries. */
+
+
+ } /* RRBC case */
+ } /* if vtblprint */
+
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 * recurse, stream);
+ }
+
+ } /* if vtable exists */
+
+ fprintf_filtered (stream, "}");
+}
+
+/* Special val_print routine to avoid printing multiple copies of virtual
+ baseclasses. */
+
+static void
+cp_print_value (struct type *type, struct type *real_type, char *valaddr,
+ int offset, CORE_ADDR address, struct ui_file *stream,
+ int format, int recurse, enum val_prettyprint pretty,
+ struct type **dont_print_vb)
+{
+ struct obstack tmp_obstack;
+ struct type **last_dont_print
+ = (struct type **) obstack_next_free (&dont_print_vb_obstack);
+ int i, n_baseclasses = TYPE_N_BASECLASSES (type);
+ int thisoffset;
+ struct type *thistype;
+
+ if (dont_print_vb == 0)
+ {
+ /* If we're at top level, carve out a completely fresh
+ chunk of the obstack and use that until this particular
+ invocation returns. */
+ tmp_obstack = dont_print_vb_obstack;
+ /* Bump up the high-water mark. Now alpha is omega. */
+ obstack_finish (&dont_print_vb_obstack);
+ }
+
+ for (i = 0; i < n_baseclasses; i++)
+ {
+ int boffset;
+ int skip;
+ struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
+ char *basename = TYPE_NAME (baseclass);
+ char *base_valaddr;
+
+ if (BASETYPE_VIA_VIRTUAL (type, i))
+ {
+ struct type **first_dont_print
+ = (struct type **) obstack_base (&dont_print_vb_obstack);
+
+ int j = (struct type **) obstack_next_free (&dont_print_vb_obstack)
+ - first_dont_print;
+
+ while (--j >= 0)
+ if (baseclass == first_dont_print[j])
+ goto flush_it;
+
+ obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
+ }
+
+ thisoffset = offset;
+ thistype = real_type;
+ if (TYPE_HAS_VTABLE (type) && BASETYPE_VIA_VIRTUAL (type, i))
+ {
+ /* Assume HP/Taligent runtime convention */
+ find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
+ valaddr, offset, &boffset, &skip);
+ if (skip >= 0)
+ error ("Virtual base class offset not found from vtable while"
+ " printing");
+ base_valaddr = valaddr;
+ }
+ else
+ {
+ boffset = baseclass_offset (type, i,
+ valaddr + offset,
+ address + offset);
+ skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1;
+
+ if (BASETYPE_VIA_VIRTUAL (type, i))
+ {
+ /* The virtual base class pointer might have been
+ clobbered by the user program. Make sure that it
+ still points to a valid memory location. */
+
+ if (boffset != -1
+ && ((boffset + offset) < 0
+ || (boffset + offset) >= TYPE_LENGTH (type)))
+ {
+ /* FIXME (alloca): unsafe if baseclass is really really large. */
+ base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
+ if (target_read_memory (address + offset + boffset, base_valaddr,
+ TYPE_LENGTH (baseclass)) != 0)
+ skip = 1;
+ thisoffset = 0;
+ boffset = 0;
+ thistype = baseclass;
+ }
+ else
+ base_valaddr = valaddr;
+ }
+ else
+ base_valaddr = valaddr;
+ }
+
+ /* now do the printing */
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 * recurse, stream);
+ }
+ fputs_filtered ("<", stream);
+ /* Not sure what the best notation is in the case where there is no
+ baseclass name. */
+ fputs_filtered (basename ? basename : "", stream);
+ fputs_filtered ("> = ", stream);
+
+
+ if (skip >= 1)
+ fprintf_filtered (stream, "<invalid address>");
+ else
+ cp_print_value_fields (baseclass, thistype, base_valaddr,
+ thisoffset + boffset, address, stream, format,
+ recurse, pretty,
+ ((struct type **)
+ obstack_base (&dont_print_vb_obstack)),
+ 0);
+ fputs_filtered (", ", stream);
+
+ flush_it:
+ ;
+ }
+
+ if (dont_print_vb == 0)
+ {
+ /* Free the space used to deal with the printing
+ of this type from top level. */
+ obstack_free (&dont_print_vb_obstack, last_dont_print);
+ /* Reset watermark so that we can continue protecting
+ ourselves from whatever we were protecting ourselves. */
+ dont_print_vb_obstack = tmp_obstack;
+ }
+}
+
+/* Print value of a static member.
+ To avoid infinite recursion when printing a class that contains
+ a static instance of the class, we keep the addresses of all printed
+ static member classes in an obstack and refuse to print them more
+ than once.
+
+ VAL contains the value to print, TYPE, STREAM, RECURSE, and PRETTY
+ have the same meanings as in c_val_print. */
+
+static void
+cp_print_static_field (struct type *type,
+ struct value *val,
+ struct ui_file *stream,
+ int format,
+ int recurse,
+ enum val_prettyprint pretty)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+ {
+ CORE_ADDR *first_dont_print;
+ int i;
+
+ first_dont_print
+ = (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack);
+ i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack)
+ - first_dont_print;
+
+ while (--i >= 0)
+ {
+ if (VALUE_ADDRESS (val) == first_dont_print[i])
+ {
+ fputs_filtered ("<same as static member of an already"
+ " seen type>",
+ stream);
+ return;
+ }
+ }
+
+ obstack_grow (&dont_print_statmem_obstack, (char *) &VALUE_ADDRESS (val),
+ sizeof (CORE_ADDR));
+
+ CHECK_TYPEDEF (type);
+ cp_print_value_fields (type, type, VALUE_CONTENTS_ALL (val),
+ VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val),
+ stream, format, recurse, pretty, NULL, 1);
+ return;
+ }
+ val_print (type, VALUE_CONTENTS_ALL (val),
+ VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val),
+ stream, format, 0, recurse, pretty);
+}
+
+void
+cp_print_class_member (char *valaddr, struct type *domain,
+ struct ui_file *stream, char *prefix)
+{
+
+ /* VAL is a byte offset into the structure type DOMAIN.
+ Find the name of the field for that offset and
+ print it. */
+ int extra = 0;
+ int bits = 0;
+ register unsigned int i;
+ unsigned len = TYPE_NFIELDS (domain);
+
+ /* @@ Make VAL into bit offset */
+
+ /* Note: HP aCC generates offsets that are the real byte offsets added
+ to a constant bias 0x20000000 (1 << 29). This constant bias gets
+ shifted out in the code below -- joyous happenstance! */
+
+ /* Note: HP cfront uses a constant bias of 1; if we support this
+ compiler ever, we will have to adjust the computation below */
+
+ LONGEST val = unpack_long (builtin_type_int, valaddr) << 3;
+ for (i = TYPE_N_BASECLASSES (domain); i < len; i++)
+ {
+ int bitpos = TYPE_FIELD_BITPOS (domain, i);
+ QUIT;
+ if (val == bitpos)
+ break;
+ if (val < bitpos && i != 0)
+ {
+ /* Somehow pointing into a field. */
+ i -= 1;
+ extra = (val - TYPE_FIELD_BITPOS (domain, i));
+ if (extra & 0x7)
+ bits = 1;
+ else
+ extra >>= 3;
+ break;
+ }
+ }
+ if (i < len)
+ {
+ char *name;
+ fprintf_filtered (stream, prefix);
+ name = type_name_no_tag (domain);
+ if (name)
+ fputs_filtered (name, stream);
+ else
+ c_type_print_base (domain, stream, 0, 0);
+ fprintf_filtered (stream, "::");
+ fputs_filtered (TYPE_FIELD_NAME (domain, i), stream);
+ if (extra)
+ fprintf_filtered (stream, " + %d bytes", extra);
+ if (bits)
+ fprintf_filtered (stream, " (offset in bits)");
+ }
+ else
+ fprintf_filtered (stream, "%ld", (long) (val >> 3));
+}
+
+
+/* This function prints out virtual table entries for a class; it
+ * recurses on the base classes to find all virtual functions
+ * available in a class.
+ *
+ * pai/1997-05-21 Note: As the name suggests, it's currently
+ * implemented for HP aCC runtime only. g++ objects are handled
+ * differently and I have made no attempt to fold that logic in
+ * here. The runtime layout is different for the two cases. Also,
+ * this currently has only the code for non-RRBC layouts generated by
+ * the HP aCC compiler; RRBC code is stubbed out and will have to be
+ * added later. */
+
+
+static void
+cp_print_hpacc_virtual_table_entries (struct type *type, int *vfuncs,
+ struct value *v, struct ui_file *stream,
+ int format, int recurse,
+ enum val_prettyprint pretty)
+{
+ int fn, oi;
+
+ /* pai: FIXME this function doesn't work. It should handle a given
+ * virtual function only once (latest redefinition in class hierarchy)
+ */
+
+ /* Recursion on other classes that can share the same vtable */
+ struct type *pbc = primary_base_class (type);
+ if (pbc)
+ cp_print_hpacc_virtual_table_entries (pbc, vfuncs, v, stream, format,
+ recurse, pretty);
+
+ /* Now deal with vfuncs declared in this class */
+ for (fn = 0; fn < TYPE_NFN_FIELDS (type); fn++)
+ for (oi = 0; oi < TYPE_FN_FIELDLIST_LENGTH (type, fn); oi++)
+ if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (type, fn), oi))
+ {
+ char *vf_name;
+ const char *field_physname;
+
+ /* virtual function offset */
+ int vx = (TYPE_FN_FIELD_VOFFSET (TYPE_FN_FIELDLIST1 (type, fn), oi)
+ - 1);
+
+ /* Get the address of the vfunction entry */
+ struct value *vf = value_copy (v);
+ if (VALUE_LAZY (vf))
+ (void) value_fetch_lazy (vf);
+ /* adjust by offset */
+ vf->aligner.contents[0] += 4 * (HP_ACC_VFUNC_START + vx);
+ vf = value_ind (vf); /* get the entry */
+ VALUE_TYPE (vf) = VALUE_TYPE (v); /* make it a pointer */
+
+ /* print out the entry */
+ val_print (VALUE_TYPE (vf), VALUE_CONTENTS (vf), 0, 0,
+ stream, format, 0, recurse + 1, pretty);
+ field_physname
+ = TYPE_FN_FIELD_PHYSNAME (TYPE_FN_FIELDLIST1 (type, fn), oi);
+ /* pai: (temp) FIXME Maybe this should be DMGL_ANSI */
+ vf_name = cplus_demangle (field_physname, DMGL_ARM);
+ fprintf_filtered (stream, " %s", vf_name);
+ if (--(*vfuncs) > 0)
+ fputs_filtered (", ", stream);
+ }
+}
+
+
+
+void
+_initialize_cp_valprint (void)
+{
+ add_show_from_set
+ (add_set_cmd ("static-members", class_support, var_boolean,
+ (char *) &static_field_print,
+ "Set printing of C++ static members.",
+ &setprintlist),
+ &showprintlist);
+ /* Turn on printing of static fields. */
+ static_field_print = 1;
+
+ add_show_from_set
+ (add_set_cmd ("vtbl", class_support, var_boolean, (char *) &vtblprint,
+ "Set printing of C++ virtual function tables.",
+ &setprintlist),
+ &showprintlist);
+
+ add_show_from_set
+ (add_set_cmd ("object", class_support, var_boolean, (char *) &objectprint,
+ "Set printing of object's derived type based on vtable info.",
+ &setprintlist),
+ &showprintlist);
+
+ /* Give people the defaults which they are used to. */
+ objectprint = 0;
+ vtblprint = 0;
+ obstack_begin (&dont_print_vb_obstack, 32 * sizeof (struct type *));
+ obstack_specify_allocation (&dont_print_statmem_obstack,
+ 32 * sizeof (CORE_ADDR), sizeof (CORE_ADDR),
+ xmalloc, xfree);
+}
diff --git a/gdb/cpu32bug-rom.c b/gdb/cpu32bug-rom.c
new file mode 100644
index 00000000000..2801be9ea0f
--- /dev/null
+++ b/gdb/cpu32bug-rom.c
@@ -0,0 +1,165 @@
+/* Remote debugging interface for CPU32Bug Rom monitor for GDB, the GNU debugger.
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+
+ Written by Stu Grossman of 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 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "regcache.h"
+
+static void cpu32bug_open (char *args, int from_tty);
+
+static void
+cpu32bug_supply_register (char *regname, int regnamelen, char *val, int vallen)
+{
+ int regno;
+
+ if (regnamelen != 2)
+ return;
+
+ switch (regname[0])
+ {
+ case 'S':
+ if (regname[1] != 'R')
+ return;
+ regno = PS_REGNUM;
+ break;
+ case 'P':
+ if (regname[1] != 'C')
+ return;
+ regno = PC_REGNUM;
+ break;
+ case 'D':
+ if (regname[1] < '0' || regname[1] > '7')
+ return;
+ regno = regname[1] - '0' + D0_REGNUM;
+ break;
+ case 'A':
+ if (regname[1] < '0' || regname[1] > '7')
+ return;
+ regno = regname[1] - '0' + A0_REGNUM;
+ break;
+ default:
+ return;
+ }
+
+ monitor_supply_register (regno, val);
+}
+
+/*
+ * This array of registers needs to match the indexes used by GDB. The
+ * whole reason this exists is because the various ROM monitors use
+ * different names than GDB does, and don't support all the
+ * registers either. So, typing "info reg sp" becomes an "A7".
+ */
+
+static char *cpu32bug_regnames[NUM_REGS] =
+{
+ "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
+ "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
+ "SR", "PC",
+};
+
+/*
+ * Define the monitor command strings. Since these are passed directly
+ * through to a printf style function, we need can include formatting
+ * strings. We also need a CR or LF on the end.
+ */
+
+static struct target_ops cpu32bug_ops;
+
+static char *cpu32bug_inits[] =
+{"\r", NULL};
+
+static struct monitor_ops cpu32bug_cmds;
+
+static void
+init_cpu32bug_cmds (void)
+{
+ cpu32bug_cmds.flags = MO_CLR_BREAK_USES_ADDR;
+ cpu32bug_cmds.init = cpu32bug_inits; /* Init strings */
+ cpu32bug_cmds.cont = "g\r"; /* continue command */
+ cpu32bug_cmds.step = "t\r"; /* single step */
+ cpu32bug_cmds.stop = NULL; /* interrupt command */
+ cpu32bug_cmds.set_break = "br %x\r"; /* set a breakpoint */
+ cpu32bug_cmds.clr_break = "nobr %x\r"; /* clear a breakpoint */
+ cpu32bug_cmds.clr_all_break = "nobr\r"; /* clear all breakpoints */
+ cpu32bug_cmds.fill = "bf %x:%x %x;b\r"; /* fill (start count val) */
+ cpu32bug_cmds.setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */
+ cpu32bug_cmds.setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */
+ cpu32bug_cmds.setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */
+ cpu32bug_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ cpu32bug_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
+ cpu32bug_cmds.setmem.term = NULL; /* setreg.term */
+ cpu32bug_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
+ cpu32bug_cmds.getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */
+ cpu32bug_cmds.getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */
+ cpu32bug_cmds.getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */
+ cpu32bug_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ cpu32bug_cmds.getmem.resp_delim = " "; /* getmem.resp_delim */
+ cpu32bug_cmds.getmem.term = NULL; /* getmem.term */
+ cpu32bug_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
+ cpu32bug_cmds.setreg.cmd = "rs %s %x\r"; /* setreg.cmd (name, value) */
+ cpu32bug_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ cpu32bug_cmds.setreg.term = NULL; /* setreg.term */
+ cpu32bug_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
+ cpu32bug_cmds.getreg.cmd = "rs %s\r"; /* getreg.cmd (name) */
+ cpu32bug_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */
+ cpu32bug_cmds.getreg.term = NULL; /* getreg.term */
+ cpu32bug_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
+ cpu32bug_cmds.dump_registers = "rd\r"; /* dump_registers */
+ cpu32bug_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
+ cpu32bug_cmds.supply_register = cpu32bug_supply_register; /* supply_register */
+ cpu32bug_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ cpu32bug_cmds.load = "lo\r"; /* download command */
+ cpu32bug_cmds.loadresp = "\n"; /* load response */
+ cpu32bug_cmds.prompt = "CPU32Bug>"; /* monitor command prompt */
+ cpu32bug_cmds.line_term = "\r"; /* end-of-line terminator */
+ cpu32bug_cmds.cmd_end = NULL; /* optional command terminator */
+ cpu32bug_cmds.target = &cpu32bug_ops; /* target operations */
+ cpu32bug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ cpu32bug_cmds.regnames = cpu32bug_regnames; /* registers names */
+ cpu32bug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+}; /* init_cpu32bug_cmds */
+
+static void
+cpu32bug_open (char *args, int from_tty)
+{
+ monitor_open (args, &cpu32bug_cmds, from_tty);
+}
+
+void
+_initialize_cpu32bug_rom (void)
+{
+ init_cpu32bug_cmds ();
+ init_monitor_ops (&cpu32bug_ops);
+
+ cpu32bug_ops.to_shortname = "cpu32bug";
+ cpu32bug_ops.to_longname = "CPU32Bug monitor";
+ cpu32bug_ops.to_doc = "Debug via the CPU32Bug monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ cpu32bug_ops.to_open = cpu32bug_open;
+
+ add_target (&cpu32bug_ops);
+}
diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c
new file mode 100644
index 00000000000..e85ac129f33
--- /dev/null
+++ b/gdb/cris-tdep.c
@@ -0,0 +1,4347 @@
+/* Target dependent code for CRIS, for GDB, the GNU debugger.
+ Copyright 2001 Free Software Foundation, Inc.
+ Contributed by Axis Communications AB.
+ Written by Hendrik Ruijter, Stefan Andersson, and Orjan Friberg.
+
+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 "defs.h"
+#include "frame.h"
+#include "symtab.h"
+#include "inferior.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "value.h"
+#include "opcode/cris.h"
+#include "arch-utils.h"
+#include "regcache.h"
+
+/* To get entry_point_address. */
+#include "symfile.h"
+
+#include "solib.h" /* Support for shared libraries. */
+#include "solib-svr4.h" /* For struct link_map_offsets. */
+
+
+enum cris_num_regs
+{
+ /* There are no floating point registers. Used in gdbserver low-linux.c. */
+ NUM_FREGS = 0,
+
+ /* There are 16 general registers. */
+ NUM_GENREGS = 16,
+
+ /* There are 16 special registers. */
+ NUM_SPECREGS = 16
+};
+
+/* Register numbers of various important registers.
+ FP_REGNUM Contains address of executing stack frame.
+ STR_REGNUM Contains the address of structure return values.
+ RET_REGNUM Contains the return value when shorter than or equal to 32 bits
+ ARG1_REGNUM Contains the first parameter to a function.
+ ARG2_REGNUM Contains the second parameter to a function.
+ ARG3_REGNUM Contains the third parameter to a function.
+ ARG4_REGNUM Contains the fourth parameter to a function. Rest on stack.
+ SP_REGNUM Contains address of top of stack.
+ PC_REGNUM Contains address of next instruction.
+ SRP_REGNUM Subroutine return pointer register.
+ BRP_REGNUM Breakpoint return pointer register. */
+
+/* FP_REGNUM = 8, SP_REGNUM = 14, and PC_REGNUM = 15 have been incorporated
+ into the multi-arch framework. */
+
+enum cris_regnums
+{
+ /* Enums with respect to the general registers, valid for all
+ CRIS versions. */
+ STR_REGNUM = 9,
+ RET_REGNUM = 10,
+ ARG1_REGNUM = 10,
+ ARG2_REGNUM = 11,
+ ARG3_REGNUM = 12,
+ ARG4_REGNUM = 13,
+
+ /* Enums with respect to the special registers, some of which may not be
+ applicable to all CRIS versions. */
+ P0_REGNUM = 16,
+ VR_REGNUM = 17,
+ P2_REGNUM = 18,
+ P3_REGNUM = 19,
+ P4_REGNUM = 20,
+ CCR_REGNUM = 21,
+ MOF_REGNUM = 23,
+ P8_REGNUM = 24,
+ IBR_REGNUM = 25,
+ IRP_REGNUM = 26,
+ SRP_REGNUM = 27,
+ BAR_REGNUM = 28,
+ DCCR_REGNUM = 29,
+ BRP_REGNUM = 30,
+ USP_REGNUM = 31
+};
+
+extern const struct cris_spec_reg cris_spec_regs[];
+
+/* CRIS version, set via the user command 'set cris-version'. Affects
+ register names and sizes.*/
+static int usr_cmd_cris_version;
+
+/* Indicates whether to trust the above variable. */
+static int usr_cmd_cris_version_valid = 0;
+
+/* CRIS mode, set via the user command 'set cris-mode'. Affects availability
+ of some registers. */
+static const char *usr_cmd_cris_mode;
+
+/* Indicates whether to trust the above variable. */
+static int usr_cmd_cris_mode_valid = 0;
+
+static const char CRIS_MODE_USER[] = "CRIS_MODE_USER";
+static const char CRIS_MODE_SUPERVISOR[] = "CRIS_MODE_SUPERVISOR";
+static const char *cris_mode_enums[] =
+{
+ CRIS_MODE_USER,
+ CRIS_MODE_SUPERVISOR,
+ 0
+};
+
+/* CRIS ABI, set via the user command 'set cris-abi'.
+ There are two flavours:
+ 1. Original ABI with 32-bit doubles, where arguments <= 4 bytes are
+ passed by value.
+ 2. New ABI with 64-bit doubles, where arguments <= 8 bytes are passed by
+ value. */
+static const char *usr_cmd_cris_abi;
+
+/* Indicates whether to trust the above variable. */
+static int usr_cmd_cris_abi_valid = 0;
+
+/* These variables are strings instead of enums to make them usable as
+ parameters to add_set_enum_cmd. */
+static const char CRIS_ABI_ORIGINAL[] = "CRIS_ABI_ORIGINAL";
+static const char CRIS_ABI_V2[] = "CRIS_ABI_V2";
+static const char CRIS_ABI_SYMBOL[] = ".$CRIS_ABI_V2";
+static const char *cris_abi_enums[] =
+{
+ CRIS_ABI_ORIGINAL,
+ CRIS_ABI_V2,
+ 0
+};
+
+/* CRIS architecture specific information. */
+struct gdbarch_tdep
+{
+ int cris_version;
+ const char *cris_mode;
+ const char *cris_abi;
+};
+
+/* Functions for accessing target dependent data. */
+
+static int
+cris_version (void)
+{
+ return (gdbarch_tdep (current_gdbarch)->cris_version);
+}
+
+static const char *
+cris_mode (void)
+{
+ return (gdbarch_tdep (current_gdbarch)->cris_mode);
+}
+
+static const char *
+cris_abi (void)
+{
+ return (gdbarch_tdep (current_gdbarch)->cris_abi);
+}
+
+/* For saving call-clobbered contents in R9 when returning structs. */
+static CORE_ADDR struct_return_address;
+
+struct frame_extra_info
+{
+ CORE_ADDR return_pc;
+ int leaf_function;
+};
+
+/* The instruction environment needed to find single-step breakpoints. */
+typedef
+struct instruction_environment
+{
+ unsigned long reg[NUM_GENREGS];
+ unsigned long preg[NUM_SPECREGS];
+ unsigned long branch_break_address;
+ unsigned long delay_slot_pc;
+ unsigned long prefix_value;
+ int branch_found;
+ int prefix_found;
+ int invalid;
+ int slot_needed;
+ int delay_slot_pc_active;
+ int xflag_found;
+ int disable_interrupt;
+} inst_env_type;
+
+/* Save old breakpoints in order to restore the state before a single_step.
+ At most, two breakpoints will have to be remembered. */
+typedef
+char binsn_quantum[BREAKPOINT_MAX];
+static binsn_quantum break_mem[2];
+static CORE_ADDR next_pc = 0;
+static CORE_ADDR branch_target_address = 0;
+static unsigned char branch_break_inserted = 0;
+
+/* Machine-dependencies in CRIS for opcodes. */
+
+/* Instruction sizes. */
+enum cris_instruction_sizes
+{
+ INST_BYTE_SIZE = 0,
+ INST_WORD_SIZE = 1,
+ INST_DWORD_SIZE = 2
+};
+
+/* Addressing modes. */
+enum cris_addressing_modes
+{
+ REGISTER_MODE = 1,
+ INDIRECT_MODE = 2,
+ AUTOINC_MODE = 3
+};
+
+/* Prefix addressing modes. */
+enum cris_prefix_addressing_modes
+{
+ PREFIX_INDEX_MODE = 2,
+ PREFIX_ASSIGN_MODE = 3,
+
+ /* Handle immediate byte offset addressing mode prefix format. */
+ PREFIX_OFFSET_MODE = 2
+};
+
+/* Masks for opcodes. */
+enum cris_opcode_masks
+{
+ BRANCH_SIGNED_SHORT_OFFSET_MASK = 0x1,
+ SIGNED_EXTEND_BIT_MASK = 0x2,
+ SIGNED_BYTE_MASK = 0x80,
+ SIGNED_BYTE_EXTEND_MASK = 0xFFFFFF00,
+ SIGNED_WORD_MASK = 0x8000,
+ SIGNED_WORD_EXTEND_MASK = 0xFFFF0000,
+ SIGNED_DWORD_MASK = 0x80000000,
+ SIGNED_QUICK_VALUE_MASK = 0x20,
+ SIGNED_QUICK_VALUE_EXTEND_MASK = 0xFFFFFFC0
+};
+
+/* Functions for opcodes. The general form of the ETRAX 16-bit instruction:
+ Bit 15 - 12 Operand2
+ 11 - 10 Mode
+ 9 - 6 Opcode
+ 5 - 4 Size
+ 3 - 0 Operand1 */
+
+static int
+cris_get_operand2 (unsigned short insn)
+{
+ return ((insn & 0xF000) >> 12);
+}
+
+static int
+cris_get_mode (unsigned short insn)
+{
+ return ((insn & 0x0C00) >> 10);
+}
+
+static int
+cris_get_opcode (unsigned short insn)
+{
+ return ((insn & 0x03C0) >> 6);
+}
+
+static int
+cris_get_size (unsigned short insn)
+{
+ return ((insn & 0x0030) >> 4);
+}
+
+static int
+cris_get_operand1 (unsigned short insn)
+{
+ return (insn & 0x000F);
+}
+
+/* Additional functions in order to handle opcodes. */
+
+static int
+cris_get_wide_opcode (unsigned short insn)
+{
+ return ((insn & 0x03E0) >> 5);
+}
+
+static int
+cris_get_short_size (unsigned short insn)
+{
+ return ((insn & 0x0010) >> 4);
+}
+
+static int
+cris_get_quick_value (unsigned short insn)
+{
+ return (insn & 0x003F);
+}
+
+static int
+cris_get_bdap_quick_offset (unsigned short insn)
+{
+ return (insn & 0x00FF);
+}
+
+static int
+cris_get_branch_short_offset (unsigned short insn)
+{
+ return (insn & 0x00FF);
+}
+
+static int
+cris_get_asr_shift_steps (unsigned long value)
+{
+ return (value & 0x3F);
+}
+
+static int
+cris_get_asr_quick_shift_steps (unsigned short insn)
+{
+ return (insn & 0x1F);
+}
+
+static int
+cris_get_clear_size (unsigned short insn)
+{
+ return ((insn) & 0xC000);
+}
+
+static int
+cris_is_signed_extend_bit_on (unsigned short insn)
+{
+ return (((insn) & 0x20) == 0x20);
+}
+
+static int
+cris_is_xflag_bit_on (unsigned short insn)
+{
+ return (((insn) & 0x1000) == 0x1000);
+}
+
+static void
+cris_set_size_to_dword (unsigned short *insn)
+{
+ *insn &= 0xFFCF;
+ *insn |= 0x20;
+}
+
+static signed char
+cris_get_signed_offset (unsigned short insn)
+{
+ return ((signed char) (insn & 0x00FF));
+}
+
+/* Calls an op function given the op-type, working on the insn and the
+ inst_env. */
+static void cris_gdb_func (enum cris_op_type, unsigned short, inst_env_type *);
+
+static CORE_ADDR cris_skip_prologue_main (CORE_ADDR pc, int frameless_p);
+
+static struct gdbarch *cris_gdbarch_init (struct gdbarch_info,
+ struct gdbarch_list *);
+
+static int cris_delayed_get_disassembler (bfd_vma, disassemble_info *);
+
+static void cris_dump_tdep (struct gdbarch *, struct ui_file *);
+
+static void cris_version_update (char *ignore_args, int from_tty,
+ struct cmd_list_element *c);
+
+static void cris_mode_update (char *ignore_args, int from_tty,
+ struct cmd_list_element *c);
+
+static void cris_abi_update (char *ignore_args, int from_tty,
+ struct cmd_list_element *c);
+
+static CORE_ADDR bfd_lookup_symbol (bfd *, const char *);
+
+/* Frames information. The definition of the struct frame_info is
+
+ CORE_ADDR frame
+ CORE_ADDR pc
+ int signal_handler_caller
+ CORE_ADDR return_pc
+ int leaf_function
+
+ If the compilation option -fno-omit-frame-pointer is present the
+ variable frame will be set to the content of R8 which is the frame
+ pointer register.
+
+ The variable pc contains the address where execution is performed
+ in the present frame. The innermost frame contains the current content
+ of the register PC. All other frames contain the content of the
+ register PC in the next frame.
+
+ The variable signal_handler_caller is non-zero when the frame is
+ associated with the call of a signal handler.
+
+ The variable return_pc contains the address where execution should be
+ resumed when the present frame has finished, the return address.
+
+ The variable leaf_function is 1 if the return address is in the register
+ SRP, and 0 if it is on the stack.
+
+ Prologue instructions C-code.
+ The prologue may consist of (-fno-omit-frame-pointer)
+ 1) 2)
+ push srp
+ push r8 push r8
+ move.d sp,r8 move.d sp,r8
+ subq X,sp subq X,sp
+ movem rY,[sp] movem rY,[sp]
+ move.S rZ,[r8-U] move.S rZ,[r8-U]
+
+ where 1 is a non-terminal function, and 2 is a leaf-function.
+
+ Note that this assumption is extremely brittle, and will break at the
+ slightest change in GCC's prologue.
+
+ If local variables are declared or register contents are saved on stack
+ the subq-instruction will be present with X as the number of bytes
+ needed for storage. The reshuffle with respect to r8 may be performed
+ with any size S (b, w, d) and any of the general registers Z={0..13}.
+ The offset U should be representable by a signed 8-bit value in all cases.
+ Thus, the prefix word is assumed to be immediate byte offset mode followed
+ by another word containing the instruction.
+
+ Degenerate cases:
+ 3)
+ push r8
+ move.d sp,r8
+ move.d r8,sp
+ pop r8
+
+ Prologue instructions C++-code.
+ Case 1) and 2) in the C-code may be followed by
+
+ move.d r10,rS ; this
+ move.d r11,rT ; P1
+ move.d r12,rU ; P2
+ move.d r13,rV ; P3
+ move.S [r8+U],rZ ; P4
+
+ if any of the call parameters are stored. The host expects these
+ instructions to be executed in order to get the call parameters right. */
+
+/* Examine the prologue of a function. The variable ip is the address of
+ the first instruction of the prologue. The variable limit is the address
+ of the first instruction after the prologue. The variable fi contains the
+ information in struct frame_info. The variable frameless_p controls whether
+ the entire prologue is examined (0) or just enough instructions to
+ determine that it is a prologue (1). */
+
+CORE_ADDR
+cris_examine (CORE_ADDR ip, CORE_ADDR limit, struct frame_info *fi,
+ int frameless_p)
+{
+ /* Present instruction. */
+ unsigned short insn;
+
+ /* Next instruction, lookahead. */
+ unsigned short insn_next;
+ int regno;
+
+ /* Is there a push fp? */
+ int have_fp;
+
+ /* Number of byte on stack used for local variables and movem. */
+ int val;
+
+ /* Highest register number in a movem. */
+ int regsave;
+
+ /* move.d r<source_register>,rS */
+ short source_register;
+
+ /* This frame is with respect to a leaf until a push srp is found. */
+ fi->extra_info->leaf_function = 1;
+
+ /* This frame is without the FP until a push fp is found. */
+ have_fp = 0;
+
+ /* Assume nothing on stack. */
+ val = 0;
+ regsave = -1;
+
+ /* No information about register contents so far. */
+
+ /* We only want to know the end of the prologue when fi->saved_regs == 0.
+ When the saved registers are allocated full information is required. */
+ if (fi->saved_regs)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ fi->saved_regs[regno] = 0;
+ }
+
+ /* Find the prologue instructions. */
+ do
+ {
+ insn = read_memory_unsigned_integer (ip, sizeof (short));
+ ip += sizeof (short);
+ if (insn == 0xE1FC)
+ {
+ /* push <reg> 32 bit instruction */
+ insn_next = read_memory_unsigned_integer (ip, sizeof (short));
+ ip += sizeof (short);
+ regno = cris_get_operand2 (insn_next);
+
+ /* This check, meant to recognize srp, used to be regno ==
+ (SRP_REGNUM - NUM_GENREGS), but that covers r11 also. */
+ if (insn_next == 0xBE7E)
+ {
+ if (frameless_p)
+ {
+ return ip;
+ }
+ fi->extra_info->leaf_function = 0;
+ }
+ else if (regno == FP_REGNUM)
+ {
+ have_fp = 1;
+ }
+ }
+ else if (insn == 0x866E)
+ {
+ /* move.d sp,r8 */
+ if (frameless_p)
+ {
+ return ip;
+ }
+ continue;
+ }
+ else if (cris_get_operand2 (insn) == SP_REGNUM
+ && cris_get_mode (insn) == 0x0000
+ && cris_get_opcode (insn) == 0x000A)
+ {
+ /* subq <val>,sp */
+ val = cris_get_quick_value (insn);
+ }
+ else if (cris_get_mode (insn) == 0x0002
+ && cris_get_opcode (insn) == 0x000F
+ && cris_get_size (insn) == 0x0003
+ && cris_get_operand1 (insn) == SP_REGNUM)
+ {
+ /* movem r<regsave>,[sp] */
+ if (frameless_p)
+ {
+ return ip;
+ }
+ regsave = cris_get_operand2 (insn);
+ }
+ else if (cris_get_operand2 (insn) == SP_REGNUM
+ && ((insn & 0x0F00) >> 8) == 0x0001
+ && (cris_get_signed_offset (insn) < 0))
+ {
+ /* Immediate byte offset addressing prefix word with sp as base
+ register. Used for CRIS v8 i.e. ETRAX 100 and newer if <val>
+ is between 64 and 128.
+ movem r<regsave>,[sp=sp-<val>] */
+ val = -cris_get_signed_offset (insn);
+ insn_next = read_memory_unsigned_integer (ip, sizeof (short));
+ ip += sizeof (short);
+ if (cris_get_mode (insn_next) == PREFIX_ASSIGN_MODE
+ && cris_get_opcode (insn_next) == 0x000F
+ && cris_get_size (insn_next) == 0x0003
+ && cris_get_operand1 (insn_next) == SP_REGNUM)
+ {
+ if (frameless_p)
+ {
+ return ip;
+ }
+ regsave = cris_get_operand2 (insn_next);
+ }
+ else
+ {
+ /* The prologue ended before the limit was reached. */
+ ip -= 2 * sizeof (short);
+ break;
+ }
+ }
+ else if (cris_get_mode (insn) == 0x0001
+ && cris_get_opcode (insn) == 0x0009
+ && cris_get_size (insn) == 0x0002)
+ {
+ /* move.d r<10..13>,r<0..15> */
+ if (frameless_p)
+ {
+ return ip;
+ }
+ source_register = cris_get_operand1 (insn);
+
+ /* FIXME? In the glibc solibs, the prologue might contain something
+ like (this example taken from relocate_doit):
+ move.d $pc,$r0
+ sub.d 0xfffef426,$r0
+ which isn't covered by the source_register check below. Question
+ is whether to add a check for this combo, or make better use of
+ the limit variable instead. */
+ if (source_register < ARG1_REGNUM || source_register > ARG4_REGNUM)
+ {
+ /* The prologue ended before the limit was reached. */
+ ip -= sizeof (short);
+ break;
+ }
+ }
+ else if (cris_get_operand2 (insn) == FP_REGNUM
+ /* The size is a fixed-size. */
+ && ((insn & 0x0F00) >> 8) == 0x0001
+ /* A negative offset. */
+ && (cris_get_signed_offset (insn) < 0))
+ {
+ /* move.S rZ,[r8-U] (?) */
+ insn_next = read_memory_unsigned_integer (ip, sizeof (short));
+ ip += sizeof (short);
+ regno = cris_get_operand2 (insn_next);
+ if ((regno >= 0 && regno < SP_REGNUM)
+ && cris_get_mode (insn_next) == PREFIX_OFFSET_MODE
+ && cris_get_opcode (insn_next) == 0x000F)
+ {
+ /* move.S rZ,[r8-U] */
+ continue;
+ }
+ else
+ {
+ /* The prologue ended before the limit was reached. */
+ ip -= 2 * sizeof (short);
+ break;
+ }
+ }
+ else if (cris_get_operand2 (insn) == FP_REGNUM
+ /* The size is a fixed-size. */
+ && ((insn & 0x0F00) >> 8) == 0x0001
+ /* A positive offset. */
+ && (cris_get_signed_offset (insn) > 0))
+ {
+ /* move.S [r8+U],rZ (?) */
+ insn_next = read_memory_unsigned_integer (ip, sizeof (short));
+ ip += sizeof (short);
+ regno = cris_get_operand2 (insn_next);
+ if ((regno >= 0 && regno < SP_REGNUM)
+ && cris_get_mode (insn_next) == PREFIX_OFFSET_MODE
+ && cris_get_opcode (insn_next) == 0x0009
+ && cris_get_operand1 (insn_next) == regno)
+ {
+ /* move.S [r8+U],rZ */
+ continue;
+ }
+ else
+ {
+ /* The prologue ended before the limit was reached. */
+ ip -= 2 * sizeof (short);
+ break;
+ }
+ }
+ else
+ {
+ /* The prologue ended before the limit was reached. */
+ ip -= sizeof (short);
+ break;
+ }
+ }
+ while (ip < limit);
+
+ /* We only want to know the end of the prologue when
+ fi->saved_regs == 0. */
+ if (!fi->saved_regs)
+ return ip;
+
+ if (have_fp)
+ {
+ fi->saved_regs[FP_REGNUM] = FRAME_FP (fi);
+
+ /* Calculate the addresses. */
+ for (regno = regsave; regno >= 0; regno--)
+ {
+ fi->saved_regs[regno] = FRAME_FP (fi) - val;
+ val -= 4;
+ }
+ if (fi->extra_info->leaf_function)
+ {
+ /* Set the register SP to contain the stack pointer of
+ the caller. */
+ fi->saved_regs[SP_REGNUM] = FRAME_FP (fi) + 4;
+ }
+ else
+ {
+ /* Set the register SP to contain the stack pointer of
+ the caller. */
+ fi->saved_regs[SP_REGNUM] = FRAME_FP (fi) + 8;
+
+ /* Set the register SRP to contain the return address of
+ the caller. */
+ fi->saved_regs[SRP_REGNUM] = FRAME_FP (fi) + 4;
+ }
+ }
+ return ip;
+}
+
+/* Advance pc beyond any function entry prologue instructions at pc
+ to reach some "real" code. */
+
+CORE_ADDR
+cris_skip_prologue (CORE_ADDR pc)
+{
+ return cris_skip_prologue_main (pc, 0);
+}
+
+/* As cris_skip_prologue, but stops as soon as it knows that the function
+ has a frame. Its result is equal to its input pc if the function is
+ frameless, unequal otherwise. */
+
+CORE_ADDR
+cris_skip_prologue_frameless_p (CORE_ADDR pc)
+{
+ return cris_skip_prologue_main (pc, 1);
+}
+
+/* Given a PC value corresponding to the start of a function, return the PC
+ of the first instruction after the function prologue. */
+
+CORE_ADDR
+cris_skip_prologue_main (CORE_ADDR pc, int frameless_p)
+{
+ struct frame_info fi;
+ static struct frame_extra_info fei;
+ struct symtab_and_line sal = find_pc_line (pc, 0);
+ int best_limit;
+ CORE_ADDR pc_after_prologue;
+
+ /* frame_info now contains dynamic memory. Since fi is a dummy here,
+ I use static memory for extra_info, and don't bother allocating
+ memory for saved_regs. */
+ fi.saved_regs = 0;
+ fi.extra_info = &fei;
+
+ /* If there is no symbol information then sal.end == 0, and we end up
+ examining only the first instruction in the function prologue.
+ Exaggerating the limit seems to be harmless. */
+ if (sal.end > 0)
+ best_limit = sal.end;
+ else
+ best_limit = pc + 100;
+
+ pc_after_prologue = cris_examine (pc, best_limit, &fi, frameless_p);
+ return pc_after_prologue;
+}
+
+/* Use the program counter to determine the contents and size of a breakpoint
+ instruction. It returns a pointer to a string of bytes that encode a
+ breakpoint instruction, stores the length of the string to *lenptr, and
+ adjusts pcptr (if necessary) to point to the actual memory location where
+ the breakpoint should be inserted. */
+
+unsigned char *
+cris_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+ static unsigned char break_insn[] = {0x38, 0xe9};
+ *lenptr = 2;
+
+ return break_insn;
+}
+
+/* Returns the register SRP (subroutine return pointer) which must contain
+ the content of the register PC after a function call. */
+
+CORE_ADDR
+cris_saved_pc_after_call ()
+{
+ return read_register (SRP_REGNUM);
+}
+
+/* Returns 1 if spec_reg is applicable to the current gdbarch's CRIS version,
+ 0 otherwise. */
+
+int
+cris_spec_reg_applicable (struct cris_spec_reg spec_reg)
+{
+ int version = cris_version ();
+
+ switch (spec_reg.applicable_version)
+ {
+ case cris_ver_version_all:
+ return 1;
+ case cris_ver_warning:
+ /* Indeterminate/obsolete. */
+ return 0;
+ case cris_ver_sim:
+ /* Simulator only. */
+ return 0;
+ case cris_ver_v0_3:
+ return (version >= 0 && version <= 3);
+ case cris_ver_v3p:
+ return (version >= 3);
+ case cris_ver_v8:
+ return (version == 8 || version == 9);
+ case cris_ver_v8p:
+ return (version >= 8);
+ case cris_ver_v10p:
+ return (version >= 10);
+ default:
+ /* Invalid cris version. */
+ return 0;
+ }
+}
+
+/* Returns the register size in unit byte. Returns 0 for an unimplemented
+ register, -1 for an invalid register. */
+
+int
+cris_register_size (int regno)
+{
+ int i;
+ int spec_regno;
+
+ if (regno >= 0 && regno < NUM_GENREGS)
+ {
+ /* General registers (R0 - R15) are 32 bits. */
+ return 4;
+ }
+ else if (regno >= NUM_GENREGS && regno < NUM_REGS)
+ {
+ /* Special register (R16 - R31). cris_spec_regs is zero-based.
+ Adjust regno accordingly. */
+ spec_regno = regno - NUM_GENREGS;
+
+ /* The entries in cris_spec_regs are stored in register number order,
+ which means we can shortcut into the array when searching it. */
+ for (i = spec_regno; cris_spec_regs[i].name != NULL; i++)
+ {
+ if (cris_spec_regs[i].number == spec_regno
+ && cris_spec_reg_applicable (cris_spec_regs[i]))
+ /* Go with the first applicable register. */
+ return cris_spec_regs[i].reg_size;
+ }
+ /* Special register not applicable to this CRIS version. */
+ return 0;
+ }
+ else
+ {
+ /* Invalid register. */
+ return -1;
+ }
+}
+
+/* Nonzero if regno should not be fetched from the target. This is the case
+ for unimplemented (size 0) and non-existant registers. */
+
+int
+cris_cannot_fetch_register (int regno)
+{
+ return ((regno < 0 || regno >= NUM_REGS)
+ || (cris_register_size (regno) == 0));
+}
+
+/* Nonzero if regno should not be written to the target, for various
+ reasons. */
+
+int
+cris_cannot_store_register (int regno)
+{
+ /* There are three kinds of registers we refuse to write to.
+ 1. Those that not implemented.
+ 2. Those that are read-only (depends on the processor mode).
+ 3. Those registers to which a write has no effect.
+ */
+
+ if (regno < 0 || regno >= NUM_REGS || cris_register_size (regno) == 0)
+ /* Not implemented. */
+ return 1;
+
+ else if (regno == VR_REGNUM)
+ /* Read-only. */
+ return 1;
+
+ else if (regno == P0_REGNUM || regno == P4_REGNUM || regno == P8_REGNUM)
+ /* Writing has no effect. */
+ return 1;
+
+ else if (cris_mode () == CRIS_MODE_USER)
+ {
+ if (regno == IBR_REGNUM || regno == BAR_REGNUM || regno == BRP_REGNUM
+ || regno == IRP_REGNUM)
+ /* Read-only in user mode. */
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Returns the register offset for the first byte of register regno's space
+ in the saved register state. Returns -1 for an invalid or unimplemented
+ register. */
+
+int
+cris_register_offset (int regno)
+{
+ int i;
+ int reg_size;
+ int offset = 0;
+
+ if (regno >= 0 && regno < NUM_REGS)
+ {
+ /* FIXME: The offsets should be cached and calculated only once,
+ when the architecture being debugged has changed. */
+ for (i = 0; i < regno; i++)
+ offset += cris_register_size (i);
+
+ return offset;
+ }
+ else
+ {
+ /* Invalid register. */
+ return -1;
+ }
+}
+
+/* Return the GDB type (defined in gdbtypes.c) for the "standard" data type
+ of data in register regno. */
+
+struct type *
+cris_register_virtual_type (int regno)
+{
+ if (regno == SP_REGNUM || regno == PC_REGNUM
+ || (regno > P8_REGNUM && regno < USP_REGNUM))
+ {
+ /* SP, PC, IBR, IRP, SRP, BAR, DCCR, BRP */
+ return lookup_pointer_type (builtin_type_void);
+ }
+ else if (regno == P8_REGNUM || regno == USP_REGNUM
+ || (regno >= 0 && regno < SP_REGNUM))
+ {
+ /* R0 - R13, P8, P15 */
+ return builtin_type_unsigned_long;
+ }
+ else if (regno > P3_REGNUM && regno < P8_REGNUM)
+ {
+ /* P4, CCR, DCR0, DCR1 */
+ return builtin_type_unsigned_short;
+ }
+ else if (regno > PC_REGNUM && regno < P4_REGNUM)
+ {
+ /* P0, P1, P2, P3 */
+ return builtin_type_unsigned_char;
+ }
+ else
+ {
+ /* Invalid register. */
+ return builtin_type_void;
+ }
+}
+
+/* Stores a function return value of type type, where valbuf is the address
+ of the value to be stored. */
+
+/* In the original CRIS ABI, R10 is used to store return values. */
+
+void
+cris_abi_original_store_return_value (struct type *type, char *valbuf)
+{
+ int len = TYPE_LENGTH (type);
+
+ if (len <= REGISTER_SIZE)
+ write_register_bytes (REGISTER_BYTE (RET_REGNUM), valbuf, len);
+ else
+ internal_error (__FILE__, __LINE__, "cris_abi_original_store_return_value: type length too large.");
+}
+
+/* In the CRIS ABI V2, R10 and R11 are used to store return values. */
+
+void
+cris_abi_v2_store_return_value (struct type *type, char *valbuf)
+{
+ int len = TYPE_LENGTH (type);
+
+ if (len <= 2 * REGISTER_SIZE)
+ {
+ /* Note that this works since R10 and R11 are consecutive registers. */
+ write_register_bytes (REGISTER_BYTE (RET_REGNUM), valbuf, len);
+ }
+ else
+ internal_error (__FILE__, __LINE__, "cris_abi_v2_store_return_value: type length too large.");
+}
+
+/* Return the name of register regno as a string. Return NULL for an invalid or
+ unimplemented register. */
+
+char *
+cris_register_name (int regno)
+{
+ static char *cris_genreg_names[] =
+ { "r0", "r1", "r2", "r3", \
+ "r4", "r5", "r6", "r7", \
+ "r8", "r9", "r10", "r11", \
+ "r12", "r13", "sp", "pc" };
+
+ int i;
+ int spec_regno;
+
+ if (regno >= 0 && regno < NUM_GENREGS)
+ {
+ /* General register. */
+ return cris_genreg_names[regno];
+ }
+ else if (regno >= NUM_GENREGS && regno < NUM_REGS)
+ {
+ /* Special register (R16 - R31). cris_spec_regs is zero-based.
+ Adjust regno accordingly. */
+ spec_regno = regno - NUM_GENREGS;
+
+ /* The entries in cris_spec_regs are stored in register number order,
+ which means we can shortcut into the array when searching it. */
+ for (i = spec_regno; cris_spec_regs[i].name != NULL; i++)
+ {
+ if (cris_spec_regs[i].number == spec_regno
+ && cris_spec_reg_applicable (cris_spec_regs[i]))
+ /* Go with the first applicable register. */
+ return cris_spec_regs[i].name;
+ }
+ /* Special register not applicable to this CRIS version. */
+ return NULL;
+ }
+ else
+ {
+ /* Invalid register. */
+ return NULL;
+ }
+}
+
+int
+cris_register_bytes_ok (long bytes)
+{
+ return (bytes == REGISTER_BYTES);
+}
+
+/* Extract from an array regbuf containing the raw register state a function
+ return value of type type, and copy that, in virtual format, into
+ valbuf. */
+
+/* In the original CRIS ABI, R10 is used to return values. */
+
+void
+cris_abi_original_extract_return_value (struct type *type, char *regbuf,
+ char *valbuf)
+{
+ int len = TYPE_LENGTH (type);
+
+ if (len <= REGISTER_SIZE)
+ memcpy (valbuf, regbuf + REGISTER_BYTE (RET_REGNUM), len);
+ else
+ internal_error (__FILE__, __LINE__, "cris_abi_original_extract_return_value: type length too large");
+}
+
+/* In the CRIS ABI V2, R10 and R11 are used to store return values. */
+
+void
+cris_abi_v2_extract_return_value (struct type *type, char *regbuf,
+ char *valbuf)
+{
+ int len = TYPE_LENGTH (type);
+
+ if (len <= 2 * REGISTER_SIZE)
+ memcpy (valbuf, regbuf + REGISTER_BYTE (RET_REGNUM), len);
+ else
+ internal_error (__FILE__, __LINE__, "cris_abi_v2_extract_return_value: type length too large");
+}
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. In the CRIS ABI, R9 is used in order to pass
+ the address of the allocated area where a structure return value must
+ be stored. R9 is call-clobbered, which means we must save it here for
+ later use. */
+
+void
+cris_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ write_register (STR_REGNUM, addr);
+ struct_return_address = addr;
+}
+
+/* Extract from regbuf the address where a function should return a
+ structure value. It's not there in the CRIS ABI, so we must do it another
+ way. */
+
+CORE_ADDR
+cris_extract_struct_value_address (char *regbuf)
+{
+ return struct_return_address;
+}
+
+/* Returns 1 if a value of the given type being returned from a function
+ must have space allocated for it on the stack. gcc_p is true if the
+ function being considered is known to have been compiled by GCC.
+ In the CRIS ABI, structure return values are passed to the called
+ function by reference in register R9 to a caller-allocated area, so
+ this is always true. */
+
+int
+cris_use_struct_convention (int gcc_p, struct type *type)
+{
+ return 1;
+}
+
+/* Returns 1 if the given type will be passed by pointer rather than
+ directly. */
+
+/* In the original CRIS ABI, arguments shorter than or equal to 32 bits are
+ passed by value. */
+
+int
+cris_abi_original_reg_struct_has_addr (int gcc_p, struct type *type)
+{
+ return (TYPE_LENGTH (type) > 4);
+}
+
+/* In the CRIS ABI V2, arguments shorter than or equal to 64 bits are passed
+ by value. */
+
+int
+cris_abi_v2_reg_struct_has_addr (int gcc_p, struct type *type)
+{
+ return (TYPE_LENGTH (type) > 8);
+}
+
+/* Returns 1 if the function invocation represented by fi does not have a
+ stack frame associated with it. Otherwise return 0. */
+
+int
+cris_frameless_function_invocation (struct frame_info *fi)
+{
+ if (fi->signal_handler_caller)
+ return 0;
+ else
+ return frameless_look_for_prologue (fi);
+}
+
+/* See frame.h. Determines the address of all registers in the current stack
+ frame storing each in frame->saved_regs. Space for frame->saved_regs shall
+ be allocated by FRAME_INIT_SAVED_REGS using either frame_saved_regs_zalloc
+ or frame_obstack_alloc. */
+
+void
+cris_frame_init_saved_regs (struct frame_info *fi)
+{
+ CORE_ADDR ip;
+ struct symtab_and_line sal;
+ int best_limit;
+ char *dummy_regs = generic_find_dummy_frame (fi->pc, fi->frame);
+
+ /* Examine the entire prologue. */
+ register int frameless_p = 0;
+
+ /* Has this frame's registers already been initialized? */
+ if (fi->saved_regs)
+ return;
+
+ frame_saved_regs_zalloc (fi);
+
+ if (dummy_regs)
+ {
+ /* I don't see this ever happening, considering the context in which
+ cris_frame_init_saved_regs is called (always when we're not in
+ a dummy frame). */
+ memcpy (&fi->saved_regs, dummy_regs, sizeof (fi->saved_regs));
+ }
+ else
+ {
+ ip = get_pc_function_start (fi->pc);
+ sal = find_pc_line (ip, 0);
+
+ /* If there is no symbol information then sal.end == 0, and we end up
+ examining only the first instruction in the function prologue.
+ Exaggerating the limit seems to be harmless. */
+ if (sal.end > 0)
+ best_limit = sal.end;
+ else
+ best_limit = ip + 100;
+
+ cris_examine (ip, best_limit, fi, frameless_p);
+ }
+}
+
+/* Initialises the extra frame information at the creation of a new frame.
+ The inparameter fromleaf is 0 when the call is from create_new_frame.
+ When the call is from get_prev_frame_info, fromleaf is determined by
+ cris_frameless_function_invocation. */
+
+void
+cris_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ if (fi->next)
+ {
+ /* Called from get_prev_frame. */
+ fi->pc = FRAME_SAVED_PC (fi->next);
+ }
+
+ fi->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+
+ fi->extra_info->return_pc = 0;
+ fi->extra_info->leaf_function = 0;
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ /* We need to setup fi->frame here because run_stack_dummy gets it wrong
+ by assuming it's always FP. */
+ fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
+ fi->extra_info->return_pc =
+ generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
+
+ /* FIXME: Is this necessarily true? */
+ fi->extra_info->leaf_function = 0;
+ }
+ else
+ {
+ cris_frame_init_saved_regs (fi);
+
+ /* Check fromleaf/frameless_function_invocation. (FIXME) */
+
+ if (fi->saved_regs[SRP_REGNUM] != 0)
+ {
+ /* SRP was saved on the stack; non-leaf function. */
+ fi->extra_info->return_pc =
+ read_memory_integer (fi->saved_regs[SRP_REGNUM],
+ REGISTER_RAW_SIZE (SRP_REGNUM));
+ }
+ else
+ {
+ /* SRP is still in a register; leaf function. */
+ fi->extra_info->return_pc = read_register (SRP_REGNUM);
+ /* FIXME: Should leaf_function be set to 1 here? */
+ fi->extra_info->leaf_function = 1;
+ }
+ }
+}
+
+/* Return the content of the frame pointer in the present frame. In other
+ words, determine the address of the calling function's frame. */
+
+CORE_ADDR
+cris_frame_chain (struct frame_info *fi)
+{
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ return fi->frame;
+ }
+ else if (!inside_entry_file (fi->pc))
+ {
+ return read_memory_unsigned_integer (FRAME_FP (fi), 4);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/* Return the saved PC (which equals the return address) of this frame. */
+
+CORE_ADDR
+cris_frame_saved_pc (struct frame_info *fi)
+{
+ return fi->extra_info->return_pc;
+}
+
+/* Return the address of the argument block for the frame described
+ by struct frame_info. */
+
+CORE_ADDR
+cris_frame_args_address (struct frame_info *fi)
+{
+ return FRAME_FP (fi);
+}
+
+/* Return the address of the locals block for the frame
+ described by struct frame_info. */
+
+CORE_ADDR
+cris_frame_locals_address (struct frame_info *fi)
+{
+ return FRAME_FP (fi);
+}
+
+/* Setup the function arguments for calling a function in the inferior. */
+
+CORE_ADDR
+cris_abi_original_push_arguments (int nargs, struct value **args,
+ CORE_ADDR sp, int struct_return,
+ CORE_ADDR struct_addr)
+{
+ int stack_alloc;
+ int stack_offset;
+ int argreg;
+ int argnum;
+ struct type *type;
+ int len;
+ CORE_ADDR regval;
+ char *val;
+
+ /* Data and parameters reside in different areas on the stack.
+ Both frame pointers grow toward higher addresses. */
+ CORE_ADDR fp_params;
+ CORE_ADDR fp_data;
+
+ /* Are we returning a value using a structure return or a normal value
+ return? struct_addr is the address of the reserved space for the return
+ structure to be written on the stack. */
+ if (struct_return)
+ {
+ write_register (STR_REGNUM, struct_addr);
+ }
+
+ /* Make sure there's space on the stack. Allocate space for data and a
+ parameter to refer to that data. */
+ for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
+ stack_alloc += (TYPE_LENGTH (VALUE_TYPE (args[argnum])) + REGISTER_SIZE);
+ sp -= stack_alloc;
+ /* We may over-allocate a little here, but that won't hurt anything. */
+
+ /* Initialize stack frame pointers. */
+ fp_params = sp;
+ fp_data = sp + (nargs * REGISTER_SIZE);
+
+ /* Now load as many as possible of the first arguments into
+ registers, and push the rest onto the stack. */
+ argreg = ARG1_REGNUM;
+ stack_offset = 0;
+
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ type = VALUE_TYPE (args[argnum]);
+ len = TYPE_LENGTH (type);
+ val = (char *) VALUE_CONTENTS (args[argnum]);
+
+ if (len <= REGISTER_SIZE && argreg <= ARG4_REGNUM)
+ {
+ /* Data fits in a register; put it in the first available
+ register. */
+ write_register (argreg, *(unsigned long *) val);
+ argreg++;
+ }
+ else if (len > REGISTER_SIZE && argreg <= ARG4_REGNUM)
+ {
+ /* Data does not fit in register; pass it on the stack and
+ put its address in the first available register. */
+ write_memory (fp_data, val, len);
+ write_register (argreg, fp_data);
+ fp_data += len;
+ argreg++;
+ }
+ else if (len > REGISTER_SIZE)
+ {
+ /* Data does not fit in register; put both data and
+ parameter on the stack. */
+ write_memory (fp_data, val, len);
+ write_memory (fp_params, (char *) (&fp_data), REGISTER_SIZE);
+ fp_data += len;
+ fp_params += REGISTER_SIZE;
+ }
+ else
+ {
+ /* Data fits in a register, but we are out of registers;
+ put the parameter on the stack. */
+ write_memory (fp_params, val, REGISTER_SIZE);
+ fp_params += REGISTER_SIZE;
+ }
+ }
+
+ return sp;
+}
+
+CORE_ADDR
+cris_abi_v2_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int stack_alloc;
+ int stack_offset;
+ int argreg;
+ int argnum;
+
+ CORE_ADDR regval;
+
+ /* The function's arguments and memory allocated by gdb for the arguments to
+ point at reside in separate areas on the stack.
+ Both frame pointers grow toward higher addresses. */
+ CORE_ADDR fp_arg;
+ CORE_ADDR fp_mem;
+
+ /* Are we returning a value using a structure return or a normal value
+ return? struct_addr is the address of the reserved space for the return
+ structure to be written on the stack. */
+ if (struct_return)
+ {
+ write_register (STR_REGNUM, struct_addr);
+ }
+
+ /* Allocate enough to keep things word-aligned on both parts of the
+ stack. */
+ stack_alloc = 0;
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ int len;
+ int reg_demand;
+
+ len = TYPE_LENGTH (VALUE_TYPE (args[argnum]));
+ reg_demand = (len / REGISTER_SIZE) + (len % REGISTER_SIZE != 0 ? 1 : 0);
+
+ /* reg_demand * REGISTER_SIZE is the amount of memory we might need to
+ allocate for this argument. 2 * REGISTER_SIZE is the amount of stack
+ space we might need to pass the argument itself (either by value or by
+ reference). */
+ stack_alloc += (reg_demand * REGISTER_SIZE + 2 * REGISTER_SIZE);
+ }
+ sp -= stack_alloc;
+ /* We may over-allocate a little here, but that won't hurt anything. */
+
+ /* Initialize frame pointers. */
+ fp_arg = sp;
+ fp_mem = sp + (nargs * (2 * REGISTER_SIZE));
+
+ /* Now load as many as possible of the first arguments into registers,
+ and push the rest onto the stack. */
+ argreg = ARG1_REGNUM;
+ stack_offset = 0;
+
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ int len;
+ char *val;
+ int reg_demand;
+ int i;
+
+ len = TYPE_LENGTH (VALUE_TYPE (args[argnum]));
+ val = (char *) VALUE_CONTENTS (args[argnum]);
+
+ /* How may registers worth of storage do we need for this argument? */
+ reg_demand = (len / REGISTER_SIZE) + (len % REGISTER_SIZE != 0 ? 1 : 0);
+
+ if (len <= (2 * REGISTER_SIZE)
+ && (argreg + reg_demand - 1 <= ARG4_REGNUM))
+ {
+ /* Data passed by value. Fits in available register(s). */
+ for (i = 0; i < reg_demand; i++)
+ {
+ write_register (argreg, *(unsigned long *) val);
+ argreg++;
+ val += REGISTER_SIZE;
+ }
+ }
+ else if (len <= (2 * REGISTER_SIZE) && argreg <= ARG4_REGNUM)
+ {
+ /* Data passed by value. Does not fit in available register(s).
+ Use the register(s) first, then the stack. */
+ for (i = 0; i < reg_demand; i++)
+ {
+ if (argreg <= ARG4_REGNUM)
+ {
+ write_register (argreg, *(unsigned long *) val);
+ argreg++;
+ val += REGISTER_SIZE;
+ }
+ else
+ {
+ /* I guess this memory write could write the remaining data
+ all at once instead of in REGISTER_SIZE chunks. */
+ write_memory (fp_arg, val, REGISTER_SIZE);
+ fp_arg += REGISTER_SIZE;
+ val += REGISTER_SIZE;
+ }
+ }
+ }
+ else if (len > (2 * REGISTER_SIZE))
+ {
+ /* Data passed by reference. Put it on the stack. */
+ write_memory (fp_mem, val, len);
+ write_memory (fp_arg, (char *) (&fp_mem), REGISTER_SIZE);
+
+ /* fp_mem need not be word-aligned since it's just a chunk of
+ memory being pointed at. That is, += len would do. */
+ fp_mem += reg_demand * REGISTER_SIZE;
+ fp_arg += REGISTER_SIZE;
+ }
+ else
+ {
+ /* Data passed by value. No available registers. Put it on
+ the stack. */
+ write_memory (fp_arg, val, len);
+
+ /* fp_arg must be word-aligned (i.e., don't += len) to match
+ the function prologue. */
+ fp_arg += reg_demand * REGISTER_SIZE;
+ }
+ }
+
+ return sp;
+}
+
+/* Never put the return address on the stack. The register SRP is pushed
+ by the called function unless it is a leaf-function. Due to the BRP
+ register the PC will change when continue is sent. */
+
+CORE_ADDR
+cris_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ write_register (SRP_REGNUM, CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+/* Restore the machine to the state it had before the current frame
+ was created. Discard the innermost frame from the stack and restore
+ all saved registers. */
+
+void
+cris_pop_frame ()
+{
+ register struct frame_info *fi = get_current_frame ();
+ register int regno;
+ register int stack_offset = 0;
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ /* This happens when we hit a breakpoint set at the entry point,
+ when returning from a dummy frame. */
+ generic_pop_dummy_frame ();
+ }
+ else
+ {
+ cris_frame_init_saved_regs (fi);
+
+ /* For each register, the address of where it was saved on entry to
+ the frame now lies in fi->saved_regs[regno], or zero if it was not
+ saved. This includes special registers such as PC and FP saved in
+ special ways in the stack frame. The SP_REGNUM is even more
+ special, the address here is the SP for the next frame, not the
+ address where the SP was saved. */
+
+ /* Restore general registers R0 - R7. They were pushed on the stack
+ after SP was saved. */
+ for (regno = 0; regno < FP_REGNUM; regno++)
+ {
+ if (fi->saved_regs[regno])
+ {
+ write_register (regno,
+ read_memory_integer (fi->saved_regs[regno], 4));
+ }
+ }
+
+ if (fi->saved_regs[FP_REGNUM])
+ {
+ /* Pop the frame pointer (R8). It was pushed before SP
+ was saved. */
+ write_register (FP_REGNUM,
+ read_memory_integer (fi->saved_regs[FP_REGNUM], 4));
+ stack_offset += 4;
+
+ /* Not a leaf function. */
+ if (fi->saved_regs[SRP_REGNUM])
+ {
+ /* SRP was pushed before SP was saved. */
+ stack_offset += 4;
+ }
+
+ /* Restore the SP and adjust for R8 and (possibly) SRP. */
+ write_register (SP_REGNUM, fi->saved_regs[FP_REGNUM] + stack_offset);
+ }
+ else
+ {
+ /* Currently, we can't get the correct info into fi->saved_regs
+ without a frame pointer. */
+ }
+
+ /* Restore the PC. */
+ write_register (PC_REGNUM, fi->extra_info->return_pc);
+ }
+ flush_cached_frames ();
+}
+
+/* Calculates a value that measures how good inst_args constraints an
+ instruction. It stems from cris_constraint, found in cris-dis.c. */
+
+static int
+constraint (unsigned int insn, const signed char *inst_args,
+ inst_env_type *inst_env)
+{
+ int retval = 0;
+ int tmp, i;
+
+ const char *s = inst_args;
+
+ for (; *s; s++)
+ switch (*s)
+ {
+ case 'm':
+ if ((insn & 0x30) == 0x30)
+ return -1;
+ break;
+
+ case 'S':
+ /* A prefix operand. */
+ if (inst_env->prefix_found)
+ break;
+ else
+ return -1;
+
+ case 'B':
+ /* A "push" prefix. (This check was REMOVED by san 970921.) Check for
+ valid "push" size. In case of special register, it may be != 4. */
+ if (inst_env->prefix_found)
+ break;
+ else
+ return -1;
+
+ case 'D':
+ retval = (((insn >> 0xC) & 0xF) == (insn & 0xF));
+ if (!retval)
+ return -1;
+ else
+ retval += 4;
+ break;
+
+ case 'P':
+ tmp = (insn >> 0xC) & 0xF;
+
+ for (i = 0; cris_spec_regs[i].name != NULL; i++)
+ {
+ /* Since we match four bits, we will give a value of
+ 4 - 1 = 3 in a match. If there is a corresponding
+ exact match of a special register in another pattern, it
+ will get a value of 4, which will be higher. This should
+ be correct in that an exact pattern would match better that
+ a general pattern.
+ Note that there is a reason for not returning zero; the
+ pattern for "clear" is partly matched in the bit-pattern
+ (the two lower bits must be zero), while the bit-pattern
+ for a move from a special register is matched in the
+ register constraint.
+ This also means we will will have a race condition if
+ there is a partly match in three bits in the bit pattern. */
+ if (tmp == cris_spec_regs[i].number)
+ {
+ retval += 3;
+ break;
+ }
+ }
+
+ if (cris_spec_regs[i].name == NULL)
+ return -1;
+ break;
+ }
+ return retval;
+}
+
+/* Returns the number of bits set in the variable value. */
+
+static int
+number_of_bits (unsigned int value)
+{
+ int number_of_bits = 0;
+
+ while (value != 0)
+ {
+ number_of_bits += 1;
+ value &= (value - 1);
+ }
+ return number_of_bits;
+}
+
+/* Finds the address that should contain the single step breakpoint(s).
+ It stems from code in cris-dis.c. */
+
+static int
+find_cris_op (unsigned short insn, inst_env_type *inst_env)
+{
+ int i;
+ int max_level_of_match = -1;
+ int max_matched = -1;
+ int level_of_match;
+
+ for (i = 0; cris_opcodes[i].name != NULL; i++)
+ {
+ if (((cris_opcodes[i].match & insn) == cris_opcodes[i].match)
+ && ((cris_opcodes[i].lose & insn) == 0))
+ {
+ level_of_match = constraint (insn, cris_opcodes[i].args, inst_env);
+ if (level_of_match >= 0)
+ {
+ level_of_match +=
+ number_of_bits (cris_opcodes[i].match | cris_opcodes[i].lose);
+ if (level_of_match > max_level_of_match)
+ {
+ max_matched = i;
+ max_level_of_match = level_of_match;
+ if (level_of_match == 16)
+ {
+ /* All bits matched, cannot find better. */
+ break;
+ }
+ }
+ }
+ }
+ }
+ return max_matched;
+}
+
+/* Attempts to find single-step breakpoints. Returns -1 on failure which is
+ actually an internal error. */
+
+static int
+find_step_target (inst_env_type *inst_env)
+{
+ int i;
+ int offset;
+ unsigned short insn;
+
+ /* Create a local register image and set the initial state. */
+ for (i = 0; i < NUM_GENREGS; i++)
+ {
+ inst_env->reg[i] = (unsigned long) read_register (i);
+ }
+ offset = NUM_GENREGS;
+ for (i = 0; i < NUM_SPECREGS; i++)
+ {
+ inst_env->preg[i] = (unsigned long) read_register (offset + i);
+ }
+ inst_env->branch_found = 0;
+ inst_env->slot_needed = 0;
+ inst_env->delay_slot_pc_active = 0;
+ inst_env->prefix_found = 0;
+ inst_env->invalid = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+
+ /* Look for a step target. */
+ do
+ {
+ /* Read an instruction from the client. */
+ insn = read_memory_unsigned_integer (inst_env->reg[PC_REGNUM], 2);
+
+ /* If the instruction is not in a delay slot the new content of the
+ PC is [PC] + 2. If the instruction is in a delay slot it is not
+ that simple. Since a instruction in a delay slot cannot change
+ the content of the PC, it does not matter what value PC will have.
+ Just make sure it is a valid instruction. */
+ if (!inst_env->delay_slot_pc_active)
+ {
+ inst_env->reg[PC_REGNUM] += 2;
+ }
+ else
+ {
+ inst_env->delay_slot_pc_active = 0;
+ inst_env->reg[PC_REGNUM] = inst_env->delay_slot_pc;
+ }
+ /* Analyse the present instruction. */
+ i = find_cris_op (insn, inst_env);
+ if (i == -1)
+ {
+ inst_env->invalid = 1;
+ }
+ else
+ {
+ cris_gdb_func (cris_opcodes[i].op, insn, inst_env);
+ }
+ } while (!inst_env->invalid
+ && (inst_env->prefix_found || inst_env->xflag_found
+ || inst_env->slot_needed));
+ return i;
+}
+
+/* There is no hardware single-step support. The function find_step_target
+ digs through the opcodes in order to find all possible targets.
+ Either one ordinary target or two targets for branches may be found. */
+
+void
+cris_software_single_step (enum target_signal ignore, int insert_breakpoints)
+{
+ inst_env_type inst_env;
+
+ if (insert_breakpoints)
+ {
+ /* Analyse the present instruction environment and insert
+ breakpoints. */
+ int status = find_step_target (&inst_env);
+ if (status == -1)
+ {
+ /* Could not find a target. FIXME: Should do something. */
+ }
+ else
+ {
+ /* Insert at most two breakpoints. One for the next PC content
+ and possibly another one for a branch, jump, etc. */
+ next_pc = (CORE_ADDR) inst_env.reg[PC_REGNUM];
+ target_insert_breakpoint (next_pc, break_mem[0]);
+ if (inst_env.branch_found
+ && (CORE_ADDR) inst_env.branch_break_address != next_pc)
+ {
+ branch_target_address =
+ (CORE_ADDR) inst_env.branch_break_address;
+ target_insert_breakpoint (branch_target_address, break_mem[1]);
+ branch_break_inserted = 1;
+ }
+ }
+ }
+ else
+ {
+ /* Remove breakpoints. */
+ target_remove_breakpoint (next_pc, break_mem[0]);
+ if (branch_break_inserted)
+ {
+ target_remove_breakpoint (branch_target_address, break_mem[1]);
+ branch_break_inserted = 0;
+ }
+ }
+}
+
+/* Calculates the prefix value for quick offset addressing mode. */
+
+void
+quick_mode_bdap_prefix (unsigned short inst, inst_env_type *inst_env)
+{
+ /* It's invalid to be in a delay slot. You can't have a prefix to this
+ instruction (not 100% sure). */
+ if (inst_env->slot_needed || inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ inst_env->prefix_value = inst_env->reg[cris_get_operand2 (inst)];
+ inst_env->prefix_value += cris_get_bdap_quick_offset (inst);
+
+ /* A prefix doesn't change the xflag_found. But the rest of the flags
+ need updating. */
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 1;
+}
+
+/* Updates the autoincrement register. The size of the increment is derived
+ from the size of the operation. The PC is always kept aligned on even
+ word addresses. */
+
+void
+process_autoincrement (int size, unsigned short inst, inst_env_type *inst_env)
+{
+ if (size == INST_BYTE_SIZE)
+ {
+ inst_env->reg[cris_get_operand1 (inst)] += 1;
+
+ /* The PC must be word aligned, so increase the PC with one
+ word even if the size is byte. */
+ if (cris_get_operand1 (inst) == REG_PC)
+ {
+ inst_env->reg[REG_PC] += 1;
+ }
+ }
+ else if (size == INST_WORD_SIZE)
+ {
+ inst_env->reg[cris_get_operand1 (inst)] += 2;
+ }
+ else if (size == INST_DWORD_SIZE)
+ {
+ inst_env->reg[cris_get_operand1 (inst)] += 4;
+ }
+ else
+ {
+ /* Invalid size. */
+ inst_env->invalid = 1;
+ }
+}
+
+/* Just a forward declaration. */
+
+unsigned long
+get_data_from_address (unsigned short *inst, CORE_ADDR address);
+
+/* Calculates the prefix value for the general case of offset addressing
+ mode. */
+
+void
+bdap_prefix (unsigned short inst, inst_env_type *inst_env)
+{
+
+ long offset;
+
+ /* It's invalid to be in a delay slot. */
+ if (inst_env->slot_needed || inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* The calculation of prefix_value used to be after process_autoincrement,
+ but that fails for an instruction such as jsr [$r0+12] which is encoded
+ as 5f0d 0c00 30b9 when compiled with -fpic. Since PC is operand1 it
+ mustn't be incremented until we have read it and what it points at. */
+ inst_env->prefix_value = inst_env->reg[cris_get_operand2 (inst)];
+
+ /* The offset is an indirection of the contents of the operand1 register. */
+ inst_env->prefix_value +=
+ get_data_from_address (&inst, inst_env->reg[cris_get_operand1 (inst)]);
+
+ if (cris_get_mode (inst) == AUTOINC_MODE)
+ {
+ process_autoincrement (cris_get_size (inst), inst, inst_env);
+ }
+
+ /* A prefix doesn't change the xflag_found. But the rest of the flags
+ need updating. */
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 1;
+}
+
+/* Calculates the prefix value for the index addressing mode. */
+
+void
+biap_prefix (unsigned short inst, inst_env_type *inst_env)
+{
+ /* It's invalid to be in a delay slot. I can't see that it's possible to
+ have a prefix to this instruction. So I will treat this as invalid. */
+ if (inst_env->slot_needed || inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ inst_env->prefix_value = inst_env->reg[cris_get_operand1 (inst)];
+
+ /* The offset is the operand2 value shifted the size of the instruction
+ to the left. */
+ inst_env->prefix_value +=
+ inst_env->reg[cris_get_operand2 (inst)] << cris_get_size (inst);
+
+ /* If the PC is operand1 (base) the address used is the address after
+ the main instruction, i.e. address + 2 (the PC is already compensated
+ for the prefix operation). */
+ if (cris_get_operand1 (inst) == REG_PC)
+ {
+ inst_env->prefix_value += 2;
+ }
+
+ /* A prefix doesn't change the xflag_found. But the rest of the flags
+ need updating. */
+ inst_env->slot_needed = 0;
+ inst_env->xflag_found = 0;
+ inst_env->prefix_found = 1;
+}
+
+/* Calculates the prefix value for the double indirect addressing mode. */
+
+void
+dip_prefix (unsigned short inst, inst_env_type *inst_env)
+{
+
+ CORE_ADDR address;
+
+ /* It's invalid to be in a delay slot. */
+ if (inst_env->slot_needed || inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* The prefix value is one dereference of the contents of the operand1
+ register. */
+ address = (CORE_ADDR) inst_env->reg[cris_get_operand1 (inst)];
+ inst_env->prefix_value = read_memory_unsigned_integer (address, 4);
+
+ /* Check if the mode is autoincrement. */
+ if (cris_get_mode (inst) == AUTOINC_MODE)
+ {
+ inst_env->reg[cris_get_operand1 (inst)] += 4;
+ }
+
+ /* A prefix doesn't change the xflag_found. But the rest of the flags
+ need updating. */
+ inst_env->slot_needed = 0;
+ inst_env->xflag_found = 0;
+ inst_env->prefix_found = 1;
+}
+
+/* Finds the destination for a branch with 8-bits offset. */
+
+void
+eight_bit_offset_branch_op (unsigned short inst, inst_env_type *inst_env)
+{
+
+ short offset;
+
+ /* If we have a prefix or are in a delay slot it's bad. */
+ if (inst_env->slot_needed || inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* We have a branch, find out where the branch will land. */
+ offset = cris_get_branch_short_offset (inst);
+
+ /* Check if the offset is signed. */
+ if (offset & BRANCH_SIGNED_SHORT_OFFSET_MASK)
+ {
+ offset |= 0xFF00;
+ }
+
+ /* The offset ends with the sign bit, set it to zero. The address
+ should always be word aligned. */
+ offset &= ~BRANCH_SIGNED_SHORT_OFFSET_MASK;
+
+ inst_env->branch_found = 1;
+ inst_env->branch_break_address = inst_env->reg[REG_PC] + offset;
+
+ inst_env->slot_needed = 1;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 1;
+}
+
+/* Finds the destination for a branch with 16-bits offset. */
+
+void
+sixteen_bit_offset_branch_op (unsigned short inst, inst_env_type *inst_env)
+{
+ short offset;
+
+ /* If we have a prefix or is in a delay slot it's bad. */
+ if (inst_env->slot_needed || inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* We have a branch, find out the offset for the branch. */
+ offset = read_memory_integer (inst_env->reg[REG_PC], 2);
+
+ /* The instruction is one word longer than normal, so add one word
+ to the PC. */
+ inst_env->reg[REG_PC] += 2;
+
+ inst_env->branch_found = 1;
+ inst_env->branch_break_address = inst_env->reg[REG_PC] + offset;
+
+
+ inst_env->slot_needed = 1;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 1;
+}
+
+/* Handles the ABS instruction. */
+
+void
+abs_op (unsigned short inst, inst_env_type *inst_env)
+{
+
+ long value;
+
+ /* ABS can't have a prefix, so it's bad if it does. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* Check if the operation affects the PC. */
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+
+ /* It's invalid to change to the PC if we are in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ value = (long) inst_env->reg[REG_PC];
+
+ /* The value of abs (SIGNED_DWORD_MASK) is SIGNED_DWORD_MASK. */
+ if (value != SIGNED_DWORD_MASK)
+ {
+ value = -value;
+ inst_env->reg[REG_PC] = (long) value;
+ }
+ }
+
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the ADDI instruction. */
+
+void
+addi_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* It's invalid to have the PC as base register. And ADDI can't have
+ a prefix. */
+ if (inst_env->prefix_found || (cris_get_operand1 (inst) == REG_PC))
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the ASR instruction. */
+
+void
+asr_op (unsigned short inst, inst_env_type *inst_env)
+{
+ int shift_steps;
+ unsigned long value;
+ unsigned long signed_extend_mask = 0;
+
+ /* ASR can't have a prefix, so check that it doesn't. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* Check if the PC is the target register. */
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+ /* It's invalid to change the PC in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ /* Get the number of bits to shift. */
+ shift_steps = cris_get_asr_shift_steps (inst_env->reg[cris_get_operand1 (inst)]);
+ value = inst_env->reg[REG_PC];
+
+ /* Find out how many bits the operation should apply to. */
+ if (cris_get_size (inst) == INST_BYTE_SIZE)
+ {
+ if (value & SIGNED_BYTE_MASK)
+ {
+ signed_extend_mask = 0xFF;
+ signed_extend_mask = signed_extend_mask >> shift_steps;
+ signed_extend_mask = ~signed_extend_mask;
+ }
+ value = value >> shift_steps;
+ value |= signed_extend_mask;
+ value &= 0xFF;
+ inst_env->reg[REG_PC] &= 0xFFFFFF00;
+ inst_env->reg[REG_PC] |= value;
+ }
+ else if (cris_get_size (inst) == INST_WORD_SIZE)
+ {
+ if (value & SIGNED_WORD_MASK)
+ {
+ signed_extend_mask = 0xFFFF;
+ signed_extend_mask = signed_extend_mask >> shift_steps;
+ signed_extend_mask = ~signed_extend_mask;
+ }
+ value = value >> shift_steps;
+ value |= signed_extend_mask;
+ value &= 0xFFFF;
+ inst_env->reg[REG_PC] &= 0xFFFF0000;
+ inst_env->reg[REG_PC] |= value;
+ }
+ else if (cris_get_size (inst) == INST_DWORD_SIZE)
+ {
+ if (value & SIGNED_DWORD_MASK)
+ {
+ signed_extend_mask = 0xFFFFFFFF;
+ signed_extend_mask = signed_extend_mask >> shift_steps;
+ signed_extend_mask = ~signed_extend_mask;
+ }
+ value = value >> shift_steps;
+ value |= signed_extend_mask;
+ inst_env->reg[REG_PC] = value;
+ }
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the ASRQ instruction. */
+
+void
+asrq_op (unsigned short inst, inst_env_type *inst_env)
+{
+
+ int shift_steps;
+ unsigned long value;
+ unsigned long signed_extend_mask = 0;
+
+ /* ASRQ can't have a prefix, so check that it doesn't. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* Check if the PC is the target register. */
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+
+ /* It's invalid to change the PC in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ /* The shift size is given as a 5 bit quick value, i.e. we don't
+ want the the sign bit of the quick value. */
+ shift_steps = cris_get_asr_shift_steps (inst);
+ value = inst_env->reg[REG_PC];
+ if (value & SIGNED_DWORD_MASK)
+ {
+ signed_extend_mask = 0xFFFFFFFF;
+ signed_extend_mask = signed_extend_mask >> shift_steps;
+ signed_extend_mask = ~signed_extend_mask;
+ }
+ value = value >> shift_steps;
+ value |= signed_extend_mask;
+ inst_env->reg[REG_PC] = value;
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the AX, EI and SETF instruction. */
+
+void
+ax_ei_setf_op (unsigned short inst, inst_env_type *inst_env)
+{
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ /* Check if the instruction is setting the X flag. */
+ if (cris_is_xflag_bit_on (inst))
+ {
+ inst_env->xflag_found = 1;
+ }
+ else
+ {
+ inst_env->xflag_found = 0;
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->disable_interrupt = 1;
+}
+
+/* Checks if the instruction is in assign mode. If so, it updates the assign
+ register. Note that check_assign assumes that the caller has checked that
+ there is a prefix to this instruction. The mode check depends on this. */
+
+void
+check_assign (unsigned short inst, inst_env_type *inst_env)
+{
+ /* Check if it's an assign addressing mode. */
+ if (cris_get_mode (inst) == PREFIX_ASSIGN_MODE)
+ {
+ /* Assign the prefix value to operand 1. */
+ inst_env->reg[cris_get_operand1 (inst)] = inst_env->prefix_value;
+ }
+}
+
+/* Handles the 2-operand BOUND instruction. */
+
+void
+two_operand_bound_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* It's invalid to have the PC as the index operand. */
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ /* Check if we have a prefix. */
+ if (inst_env->prefix_found)
+ {
+ check_assign (inst, inst_env);
+ }
+ /* Check if this is an autoincrement mode. */
+ else if (cris_get_mode (inst) == AUTOINC_MODE)
+ {
+ /* It's invalid to change the PC in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ process_autoincrement (cris_get_size (inst), inst, inst_env);
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the 3-operand BOUND instruction. */
+
+void
+three_operand_bound_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* It's an error if we haven't got a prefix. And it's also an error
+ if the PC is the destination register. */
+ if ((!inst_env->prefix_found) || (cris_get_operand1 (inst) == REG_PC))
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Clears the status flags in inst_env. */
+
+void
+btst_nop_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* It's an error if we have got a prefix. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Clears the status flags in inst_env. */
+
+void
+clearf_di_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* It's an error if we have got a prefix. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 1;
+}
+
+/* Handles the CLEAR instruction if it's in register mode. */
+
+void
+reg_mode_clear_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* Check if the target is the PC. */
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+ /* The instruction will clear the instruction's size bits. */
+ int clear_size = cris_get_clear_size (inst);
+ if (clear_size == INST_BYTE_SIZE)
+ {
+ inst_env->delay_slot_pc = inst_env->reg[REG_PC] & 0xFFFFFF00;
+ }
+ if (clear_size == INST_WORD_SIZE)
+ {
+ inst_env->delay_slot_pc = inst_env->reg[REG_PC] & 0xFFFF0000;
+ }
+ if (clear_size == INST_DWORD_SIZE)
+ {
+ inst_env->delay_slot_pc = 0x0;
+ }
+ /* The jump will be delayed with one delay slot. So we need a delay
+ slot. */
+ inst_env->slot_needed = 1;
+ inst_env->delay_slot_pc_active = 1;
+ }
+ else
+ {
+ /* The PC will not change => no delay slot. */
+ inst_env->slot_needed = 0;
+ }
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the TEST instruction if it's in register mode. */
+
+void
+reg_mode_test_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* It's an error if we have got a prefix. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+
+}
+
+/* Handles the CLEAR and TEST instruction if the instruction isn't
+ in register mode. */
+
+void
+none_reg_mode_clear_test_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* Check if we are in a prefix mode. */
+ if (inst_env->prefix_found)
+ {
+ /* The only way the PC can change is if this instruction is in
+ assign addressing mode. */
+ check_assign (inst, inst_env);
+ }
+ /* Indirect mode can't change the PC so just check if the mode is
+ autoincrement. */
+ else if (cris_get_mode (inst) == AUTOINC_MODE)
+ {
+ process_autoincrement (cris_get_size (inst), inst, inst_env);
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Checks that the PC isn't the destination register or the instructions has
+ a prefix. */
+
+void
+dstep_logshift_mstep_neg_not_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* It's invalid to have the PC as the destination. The instruction can't
+ have a prefix. */
+ if ((cris_get_operand2 (inst) == REG_PC) || inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Checks that the instruction doesn't have a prefix. */
+
+void
+break_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* The instruction can't have a prefix. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 1;
+}
+
+/* Checks that the PC isn't the destination register and that the instruction
+ doesn't have a prefix. */
+
+void
+scc_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* It's invalid to have the PC as the destination. The instruction can't
+ have a prefix. */
+ if ((cris_get_operand2 (inst) == REG_PC) || inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 1;
+}
+
+/* Handles the register mode JUMP instruction. */
+
+void
+reg_mode_jump_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* It's invalid to do a JUMP in a delay slot. The mode is register, so
+ you can't have a prefix. */
+ if ((inst_env->slot_needed) || (inst_env->prefix_found))
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* Just change the PC. */
+ inst_env->reg[REG_PC] = inst_env->reg[cris_get_operand1 (inst)];
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 1;
+}
+
+/* Handles the JUMP instruction for all modes except register. */
+
+void none_reg_mode_jump_op (unsigned short inst, inst_env_type *inst_env)
+{
+ unsigned long newpc;
+ CORE_ADDR address;
+
+ /* It's invalid to do a JUMP in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ }
+ else
+ {
+ /* Check if we have a prefix. */
+ if (inst_env->prefix_found)
+ {
+ check_assign (inst, inst_env);
+
+ /* Get the new value for the the PC. */
+ newpc =
+ read_memory_unsigned_integer ((CORE_ADDR) inst_env->prefix_value,
+ 4);
+ }
+ else
+ {
+ /* Get the new value for the PC. */
+ address = (CORE_ADDR) inst_env->reg[cris_get_operand1 (inst)];
+ newpc = read_memory_unsigned_integer (address, 4);
+
+ /* Check if we should increment a register. */
+ if (cris_get_mode (inst) == AUTOINC_MODE)
+ {
+ inst_env->reg[cris_get_operand1 (inst)] += 4;
+ }
+ }
+ inst_env->reg[REG_PC] = newpc;
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 1;
+}
+
+/* Handles moves to special registers (aka P-register) for all modes. */
+
+void
+move_to_preg_op (unsigned short inst, inst_env_type *inst_env)
+{
+ if (inst_env->prefix_found)
+ {
+ /* The instruction has a prefix that means we are only interested if
+ the instruction is in assign mode. */
+ if (cris_get_mode (inst) == PREFIX_ASSIGN_MODE)
+ {
+ /* The prefix handles the problem if we are in a delay slot. */
+ if (cris_get_operand1 (inst) == REG_PC)
+ {
+ /* Just take care of the assign. */
+ check_assign (inst, inst_env);
+ }
+ }
+ }
+ else if (cris_get_mode (inst) == AUTOINC_MODE)
+ {
+ /* The instruction doesn't have a prefix, the only case left that we
+ are interested in is the autoincrement mode. */
+ if (cris_get_operand1 (inst) == REG_PC)
+ {
+ /* If the PC is to be incremented it's invalid to be in a
+ delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* The increment depends on the size of the special register. */
+ if (cris_register_size (cris_get_operand2 (inst)) == 1)
+ {
+ process_autoincrement (INST_BYTE_SIZE, inst, inst_env);
+ }
+ else if (cris_register_size (cris_get_operand2 (inst)) == 2)
+ {
+ process_autoincrement (INST_WORD_SIZE, inst, inst_env);
+ }
+ else
+ {
+ process_autoincrement (INST_DWORD_SIZE, inst, inst_env);
+ }
+ }
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 1;
+}
+
+/* Handles moves from special registers (aka P-register) for all modes
+ except register. */
+
+void
+none_reg_mode_move_from_preg_op (unsigned short inst, inst_env_type *inst_env)
+{
+ if (inst_env->prefix_found)
+ {
+ /* The instruction has a prefix that means we are only interested if
+ the instruction is in assign mode. */
+ if (cris_get_mode (inst) == PREFIX_ASSIGN_MODE)
+ {
+ /* The prefix handles the problem if we are in a delay slot. */
+ if (cris_get_operand1 (inst) == REG_PC)
+ {
+ /* Just take care of the assign. */
+ check_assign (inst, inst_env);
+ }
+ }
+ }
+ /* The instruction doesn't have a prefix, the only case left that we
+ are interested in is the autoincrement mode. */
+ else if (cris_get_mode (inst) == AUTOINC_MODE)
+ {
+ if (cris_get_operand1 (inst) == REG_PC)
+ {
+ /* If the PC is to be incremented it's invalid to be in a
+ delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* The increment depends on the size of the special register. */
+ if (cris_register_size (cris_get_operand2 (inst)) == 1)
+ {
+ process_autoincrement (INST_BYTE_SIZE, inst, inst_env);
+ }
+ else if (cris_register_size (cris_get_operand2 (inst)) == 2)
+ {
+ process_autoincrement (INST_WORD_SIZE, inst, inst_env);
+ }
+ else
+ {
+ process_autoincrement (INST_DWORD_SIZE, inst, inst_env);
+ }
+ }
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 1;
+}
+
+/* Handles moves from special registers (aka P-register) when the mode
+ is register. */
+
+void
+reg_mode_move_from_preg_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* Register mode move from special register can't have a prefix. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ if (cris_get_operand1 (inst) == REG_PC)
+ {
+ /* It's invalid to change the PC in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ /* The destination is the PC, the jump will have a delay slot. */
+ inst_env->delay_slot_pc = inst_env->preg[cris_get_operand2 (inst)];
+ inst_env->slot_needed = 1;
+ inst_env->delay_slot_pc_active = 1;
+ }
+ else
+ {
+ /* If the destination isn't PC, there will be no jump. */
+ inst_env->slot_needed = 0;
+ }
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 1;
+}
+
+/* Handles the MOVEM from memory to general register instruction. */
+
+void
+move_mem_to_reg_movem_op (unsigned short inst, inst_env_type *inst_env)
+{
+ if (inst_env->prefix_found)
+ {
+ /* The prefix handles the problem if we are in a delay slot. Is the
+ MOVEM instruction going to change the PC? */
+ if (cris_get_operand2 (inst) >= REG_PC)
+ {
+ inst_env->reg[REG_PC] =
+ read_memory_unsigned_integer (inst_env->prefix_value, 4);
+ }
+ /* The assign value is the value after the increment. Normally, the
+ assign value is the value before the increment. */
+ if ((cris_get_operand1 (inst) == REG_PC)
+ && (cris_get_mode (inst) == PREFIX_ASSIGN_MODE))
+ {
+ inst_env->reg[REG_PC] = inst_env->prefix_value;
+ inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
+ }
+ }
+ else
+ {
+ /* Is the MOVEM instruction going to change the PC? */
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+ /* It's invalid to change the PC in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ inst_env->reg[REG_PC] =
+ read_memory_unsigned_integer (inst_env->reg[cris_get_operand1 (inst)],
+ 4);
+ }
+ /* The increment is not depending on the size, instead it's depending
+ on the number of registers loaded from memory. */
+ if ((cris_get_operand1 (inst) == REG_PC) && (cris_get_mode (inst) == AUTOINC_MODE))
+ {
+ /* It's invalid to change the PC in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
+ }
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the MOVEM to memory from general register instruction. */
+
+void
+move_reg_to_mem_movem_op (unsigned short inst, inst_env_type *inst_env)
+{
+ if (inst_env->prefix_found)
+ {
+ /* The assign value is the value after the increment. Normally, the
+ assign value is the value before the increment. */
+ if ((cris_get_operand1 (inst) == REG_PC) &&
+ (cris_get_mode (inst) == PREFIX_ASSIGN_MODE))
+ {
+ /* The prefix handles the problem if we are in a delay slot. */
+ inst_env->reg[REG_PC] = inst_env->prefix_value;
+ inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
+ }
+ }
+ else
+ {
+ /* The increment is not depending on the size, instead it's depending
+ on the number of registers loaded to memory. */
+ if ((cris_get_operand1 (inst) == REG_PC) && (cris_get_mode (inst) == AUTOINC_MODE))
+ {
+ /* It's invalid to change the PC in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ inst_env->reg[REG_PC] += 4 * (cris_get_operand2 (inst) + 1);
+ }
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the pop instruction to a general register.
+ POP is a assembler macro for MOVE.D [SP+], Rd. */
+
+void
+reg_pop_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* POP can't have a prefix. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+ /* It's invalid to change the PC in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ inst_env->reg[REG_PC] =
+ read_memory_unsigned_integer (inst_env->reg[REG_SP], 4);
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles moves from register to memory. */
+
+void
+move_reg_to_mem_index_inc_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* Check if we have a prefix. */
+ if (inst_env->prefix_found)
+ {
+ /* The only thing that can change the PC is an assign. */
+ check_assign (inst, inst_env);
+ }
+ else if ((cris_get_operand1 (inst) == REG_PC)
+ && (cris_get_mode (inst) == AUTOINC_MODE))
+ {
+ /* It's invalid to change the PC in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ process_autoincrement (cris_get_size (inst), inst, inst_env);
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the intructions that's not yet implemented, by setting
+ inst_env->invalid to true. */
+
+void
+not_implemented_op (unsigned short inst, inst_env_type *inst_env)
+{
+ inst_env->invalid = 1;
+}
+
+/* Handles the XOR instruction. */
+
+void
+xor_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* XOR can't have a prefix. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* Check if the PC is the target. */
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+ /* It's invalid to change the PC in a delay slot. */
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ inst_env->reg[REG_PC] ^= inst_env->reg[cris_get_operand1 (inst)];
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the MULS instruction. */
+
+void
+muls_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* MULS/U can't have a prefix. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* Consider it invalid if the PC is the target. */
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the MULU instruction. */
+
+void
+mulu_op (unsigned short inst, inst_env_type *inst_env)
+{
+ /* MULS/U can't have a prefix. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* Consider it invalid if the PC is the target. */
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Calculate the result of the instruction for ADD, SUB, CMP AND, OR and MOVE.
+ The MOVE instruction is the move from source to register. */
+
+void
+add_sub_cmp_and_or_move_action (unsigned short inst, inst_env_type *inst_env,
+ unsigned long source1, unsigned long source2)
+{
+ unsigned long pc_mask;
+ unsigned long operation_mask;
+
+ /* Find out how many bits the operation should apply to. */
+ if (cris_get_size (inst) == INST_BYTE_SIZE)
+ {
+ pc_mask = 0xFFFFFF00;
+ operation_mask = 0xFF;
+ }
+ else if (cris_get_size (inst) == INST_WORD_SIZE)
+ {
+ pc_mask = 0xFFFF0000;
+ operation_mask = 0xFFFF;
+ }
+ else if (cris_get_size (inst) == INST_DWORD_SIZE)
+ {
+ pc_mask = 0x0;
+ operation_mask = 0xFFFFFFFF;
+ }
+ else
+ {
+ /* The size is out of range. */
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* The instruction just works on uw_operation_mask bits. */
+ source2 &= operation_mask;
+ source1 &= operation_mask;
+
+ /* Now calculate the result. The opcode's 3 first bits separates
+ the different actions. */
+ switch (cris_get_opcode (inst) & 7)
+ {
+ case 0: /* add */
+ source1 += source2;
+ break;
+
+ case 1: /* move */
+ source1 = source2;
+ break;
+
+ case 2: /* subtract */
+ source1 -= source2;
+ break;
+
+ case 3: /* compare */
+ break;
+
+ case 4: /* and */
+ source1 &= source2;
+ break;
+
+ case 5: /* or */
+ source1 |= source2;
+ break;
+
+ default:
+ inst_env->invalid = 1;
+ return;
+
+ break;
+ }
+
+ /* Make sure that the result doesn't contain more than the instruction
+ size bits. */
+ source2 &= operation_mask;
+
+ /* Calculate the new breakpoint address. */
+ inst_env->reg[REG_PC] &= pc_mask;
+ inst_env->reg[REG_PC] |= source1;
+
+}
+
+/* Extends the value from either byte or word size to a dword. If the mode
+ is zero extend then the value is extended with zero. If instead the mode
+ is signed extend the sign bit of the value is taken into consideration. */
+
+unsigned long
+do_sign_or_zero_extend (unsigned long value, unsigned short *inst)
+{
+ /* The size can be either byte or word, check which one it is.
+ Don't check the highest bit, it's indicating if it's a zero
+ or sign extend. */
+ if (cris_get_size (*inst) & INST_WORD_SIZE)
+ {
+ /* Word size. */
+ value &= 0xFFFF;
+
+ /* Check if the instruction is signed extend. If so, check if value has
+ the sign bit on. */
+ if (cris_is_signed_extend_bit_on (*inst) && (value & SIGNED_WORD_MASK))
+ {
+ value |= SIGNED_WORD_EXTEND_MASK;
+ }
+ }
+ else
+ {
+ /* Byte size. */
+ value &= 0xFF;
+
+ /* Check if the instruction is signed extend. If so, check if value has
+ the sign bit on. */
+ if (cris_is_signed_extend_bit_on (*inst) && (value & SIGNED_BYTE_MASK))
+ {
+ value |= SIGNED_BYTE_EXTEND_MASK;
+ }
+ }
+ /* The size should now be dword. */
+ cris_set_size_to_dword (inst);
+ return value;
+}
+
+/* Handles the register mode for the ADD, SUB, CMP, AND, OR and MOVE
+ instruction. The MOVE instruction is the move from source to register. */
+
+void
+reg_mode_add_sub_cmp_and_or_move_op (unsigned short inst,
+ inst_env_type *inst_env)
+{
+ unsigned long operand1;
+ unsigned long operand2;
+
+ /* It's invalid to have a prefix to the instruction. This is a register
+ mode instruction and can't have a prefix. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ /* Check if the instruction has PC as its target. */
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ /* The instruction has the PC as its target register. */
+ operand1 = inst_env->reg[cris_get_operand1 (inst)];
+ operand2 = inst_env->reg[REG_PC];
+
+ /* Check if it's a extend, signed or zero instruction. */
+ if (cris_get_opcode (inst) < 4)
+ {
+ operand1 = do_sign_or_zero_extend (operand1, &inst);
+ }
+ /* Calculate the PC value after the instruction, i.e. where the
+ breakpoint should be. The order of the udw_operands is vital. */
+ add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand1);
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Returns the data contained at address. The size of the data is derived from
+ the size of the operation. If the instruction is a zero or signed
+ extend instruction, the size field is changed in instruction. */
+
+unsigned long
+get_data_from_address (unsigned short *inst, CORE_ADDR address)
+{
+ int size = cris_get_size (*inst);
+ unsigned long value;
+
+ /* If it's an extend instruction we don't want the signed extend bit,
+ because it influences the size. */
+ if (cris_get_opcode (*inst) < 4)
+ {
+ size &= ~SIGNED_EXTEND_BIT_MASK;
+ }
+ /* Is there a need for checking the size? Size should contain the number of
+ bytes to read. */
+ size = 1 << size;
+ value = read_memory_unsigned_integer (address, size);
+
+ /* Check if it's an extend, signed or zero instruction. */
+ if (cris_get_opcode (*inst) < 4)
+ {
+ value = do_sign_or_zero_extend (value, inst);
+ }
+ return value;
+}
+
+/* Handles the assign addresing mode for the ADD, SUB, CMP, AND, OR and MOVE
+ instructions. The MOVE instruction is the move from source to register. */
+
+void
+handle_prefix_assign_mode_for_aritm_op (unsigned short inst,
+ inst_env_type *inst_env)
+{
+ unsigned long operand2;
+ unsigned long operand3;
+
+ check_assign (inst, inst_env);
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+ operand2 = inst_env->reg[REG_PC];
+
+ /* Get the value of the third operand. */
+ operand3 = get_data_from_address (&inst, inst_env->prefix_value);
+
+ /* Calculate the PC value after the instruction, i.e. where the
+ breakpoint should be. The order of the udw_operands is vital. */
+ add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand3);
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the three-operand addressing mode for the ADD, SUB, CMP, AND and
+ OR instructions. Note that for this to work as expected, the calling
+ function must have made sure that there is a prefix to this instruction. */
+
+void
+three_operand_add_sub_cmp_and_or_op (unsigned short inst,
+ inst_env_type *inst_env)
+{
+ unsigned long operand2;
+ unsigned long operand3;
+
+ if (cris_get_operand1 (inst) == REG_PC)
+ {
+ /* The PC will be changed by the instruction. */
+ operand2 = inst_env->reg[cris_get_operand2 (inst)];
+
+ /* Get the value of the third operand. */
+ operand3 = get_data_from_address (&inst, inst_env->prefix_value);
+
+ /* Calculate the PC value after the instruction, i.e. where the
+ breakpoint should be. */
+ add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand3);
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the index addresing mode for the ADD, SUB, CMP, AND, OR and MOVE
+ instructions. The MOVE instruction is the move from source to register. */
+
+void
+handle_prefix_index_mode_for_aritm_op (unsigned short inst,
+ inst_env_type *inst_env)
+{
+ if (cris_get_operand1 (inst) != cris_get_operand2 (inst))
+ {
+ /* If the instruction is MOVE it's invalid. If the instruction is ADD,
+ SUB, AND or OR something weird is going on (if everything works these
+ instructions should end up in the three operand version). */
+ inst_env->invalid = 1;
+ return;
+ }
+ else
+ {
+ /* three_operand_add_sub_cmp_and_or does the same as we should do here
+ so use it. */
+ three_operand_add_sub_cmp_and_or_op (inst, inst_env);
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the autoincrement and indirect addresing mode for the ADD, SUB,
+ CMP, AND OR and MOVE instruction. The MOVE instruction is the move from
+ source to register. */
+
+void
+handle_inc_and_index_mode_for_aritm_op (unsigned short inst,
+ inst_env_type *inst_env)
+{
+ unsigned long operand1;
+ unsigned long operand2;
+ unsigned long operand3;
+ int size;
+
+ /* The instruction is either an indirect or autoincrement addressing mode.
+ Check if the destination register is the PC. */
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+ /* Must be done here, get_data_from_address may change the size
+ field. */
+ size = cris_get_size (inst);
+ operand2 = inst_env->reg[REG_PC];
+
+ /* Get the value of the third operand, i.e. the indirect operand. */
+ operand1 = inst_env->reg[cris_get_operand1 (inst)];
+ operand3 = get_data_from_address (&inst, operand1);
+
+ /* Calculate the PC value after the instruction, i.e. where the
+ breakpoint should be. The order of the udw_operands is vital. */
+ add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand3);
+ }
+ /* If this is an autoincrement addressing mode, check if the increment
+ changes the PC. */
+ if ((cris_get_operand1 (inst) == REG_PC) && (cris_get_mode (inst) == AUTOINC_MODE))
+ {
+ /* Get the size field. */
+ size = cris_get_size (inst);
+
+ /* If it's an extend instruction we don't want the signed extend bit,
+ because it influences the size. */
+ if (cris_get_opcode (inst) < 4)
+ {
+ size &= ~SIGNED_EXTEND_BIT_MASK;
+ }
+ process_autoincrement (size, inst, inst_env);
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the two-operand addressing mode, all modes except register, for
+ the ADD, SUB CMP, AND and OR instruction. */
+
+void
+none_reg_mode_add_sub_cmp_and_or_move_op (unsigned short inst,
+ inst_env_type *inst_env)
+{
+ if (inst_env->prefix_found)
+ {
+ if (cris_get_mode (inst) == PREFIX_INDEX_MODE)
+ {
+ handle_prefix_index_mode_for_aritm_op (inst, inst_env);
+ }
+ else if (cris_get_mode (inst) == PREFIX_ASSIGN_MODE)
+ {
+ handle_prefix_assign_mode_for_aritm_op (inst, inst_env);
+ }
+ else
+ {
+ /* The mode is invalid for a prefixed base instruction. */
+ inst_env->invalid = 1;
+ return;
+ }
+ }
+ else
+ {
+ handle_inc_and_index_mode_for_aritm_op (inst, inst_env);
+ }
+}
+
+/* Handles the quick addressing mode for the ADD and SUB instruction. */
+
+void
+quick_mode_add_sub_op (unsigned short inst, inst_env_type *inst_env)
+{
+ unsigned long operand1;
+ unsigned long operand2;
+
+ /* It's a bad idea to be in a prefix instruction now. This is a quick mode
+ instruction and can't have a prefix. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+
+ /* Check if the instruction has PC as its target. */
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ operand1 = cris_get_quick_value (inst);
+ operand2 = inst_env->reg[REG_PC];
+
+ /* The size should now be dword. */
+ cris_set_size_to_dword (&inst);
+
+ /* Calculate the PC value after the instruction, i.e. where the
+ breakpoint should be. */
+ add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand1);
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Handles the quick addressing mode for the CMP, AND and OR instruction. */
+
+void
+quick_mode_and_cmp_move_or_op (unsigned short inst, inst_env_type *inst_env)
+{
+ unsigned long operand1;
+ unsigned long operand2;
+
+ /* It's a bad idea to be in a prefix instruction now. This is a quick mode
+ instruction and can't have a prefix. */
+ if (inst_env->prefix_found)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ /* Check if the instruction has PC as its target. */
+ if (cris_get_operand2 (inst) == REG_PC)
+ {
+ if (inst_env->slot_needed)
+ {
+ inst_env->invalid = 1;
+ return;
+ }
+ /* The instruction has the PC as its target register. */
+ operand1 = cris_get_quick_value (inst);
+ operand2 = inst_env->reg[REG_PC];
+
+ /* The quick value is signed, so check if we must do a signed extend. */
+ if (operand1 & SIGNED_QUICK_VALUE_MASK)
+ {
+ /* sign extend */
+ operand1 |= SIGNED_QUICK_VALUE_EXTEND_MASK;
+ }
+ /* The size should now be dword. */
+ cris_set_size_to_dword (&inst);
+
+ /* Calculate the PC value after the instruction, i.e. where the
+ breakpoint should be. */
+ add_sub_cmp_and_or_move_action (inst, inst_env, operand2, operand1);
+ }
+ inst_env->slot_needed = 0;
+ inst_env->prefix_found = 0;
+ inst_env->xflag_found = 0;
+ inst_env->disable_interrupt = 0;
+}
+
+/* Translate op_type to a function and call it. */
+
+static void cris_gdb_func (enum cris_op_type op_type, unsigned short inst,
+ inst_env_type *inst_env)
+{
+ switch (op_type)
+ {
+ case cris_not_implemented_op:
+ not_implemented_op (inst, inst_env);
+ break;
+
+ case cris_abs_op:
+ abs_op (inst, inst_env);
+ break;
+
+ case cris_addi_op:
+ addi_op (inst, inst_env);
+ break;
+
+ case cris_asr_op:
+ asr_op (inst, inst_env);
+ break;
+
+ case cris_asrq_op:
+ asrq_op (inst, inst_env);
+ break;
+
+ case cris_ax_ei_setf_op:
+ ax_ei_setf_op (inst, inst_env);
+ break;
+
+ case cris_bdap_prefix:
+ bdap_prefix (inst, inst_env);
+ break;
+
+ case cris_biap_prefix:
+ biap_prefix (inst, inst_env);
+ break;
+
+ case cris_break_op:
+ break_op (inst, inst_env);
+ break;
+
+ case cris_btst_nop_op:
+ btst_nop_op (inst, inst_env);
+ break;
+
+ case cris_clearf_di_op:
+ clearf_di_op (inst, inst_env);
+ break;
+
+ case cris_dip_prefix:
+ dip_prefix (inst, inst_env);
+ break;
+
+ case cris_dstep_logshift_mstep_neg_not_op:
+ dstep_logshift_mstep_neg_not_op (inst, inst_env);
+ break;
+
+ case cris_eight_bit_offset_branch_op:
+ eight_bit_offset_branch_op (inst, inst_env);
+ break;
+
+ case cris_move_mem_to_reg_movem_op:
+ move_mem_to_reg_movem_op (inst, inst_env);
+ break;
+
+ case cris_move_reg_to_mem_movem_op:
+ move_reg_to_mem_movem_op (inst, inst_env);
+ break;
+
+ case cris_move_to_preg_op:
+ move_to_preg_op (inst, inst_env);
+ break;
+
+ case cris_muls_op:
+ muls_op (inst, inst_env);
+ break;
+
+ case cris_mulu_op:
+ mulu_op (inst, inst_env);
+ break;
+
+ case cris_none_reg_mode_add_sub_cmp_and_or_move_op:
+ none_reg_mode_add_sub_cmp_and_or_move_op (inst, inst_env);
+ break;
+
+ case cris_none_reg_mode_clear_test_op:
+ none_reg_mode_clear_test_op (inst, inst_env);
+ break;
+
+ case cris_none_reg_mode_jump_op:
+ none_reg_mode_jump_op (inst, inst_env);
+ break;
+
+ case cris_none_reg_mode_move_from_preg_op:
+ none_reg_mode_move_from_preg_op (inst, inst_env);
+ break;
+
+ case cris_quick_mode_add_sub_op:
+ quick_mode_add_sub_op (inst, inst_env);
+ break;
+
+ case cris_quick_mode_and_cmp_move_or_op:
+ quick_mode_and_cmp_move_or_op (inst, inst_env);
+ break;
+
+ case cris_quick_mode_bdap_prefix:
+ quick_mode_bdap_prefix (inst, inst_env);
+ break;
+
+ case cris_reg_mode_add_sub_cmp_and_or_move_op:
+ reg_mode_add_sub_cmp_and_or_move_op (inst, inst_env);
+ break;
+
+ case cris_reg_mode_clear_op:
+ reg_mode_clear_op (inst, inst_env);
+ break;
+
+ case cris_reg_mode_jump_op:
+ reg_mode_jump_op (inst, inst_env);
+ break;
+
+ case cris_reg_mode_move_from_preg_op:
+ reg_mode_move_from_preg_op (inst, inst_env);
+ break;
+
+ case cris_reg_mode_test_op:
+ reg_mode_test_op (inst, inst_env);
+ break;
+
+ case cris_scc_op:
+ scc_op (inst, inst_env);
+ break;
+
+ case cris_sixteen_bit_offset_branch_op:
+ sixteen_bit_offset_branch_op (inst, inst_env);
+ break;
+
+ case cris_three_operand_add_sub_cmp_and_or_op:
+ three_operand_add_sub_cmp_and_or_op (inst, inst_env);
+ break;
+
+ case cris_three_operand_bound_op:
+ three_operand_bound_op (inst, inst_env);
+ break;
+
+ case cris_two_operand_bound_op:
+ two_operand_bound_op (inst, inst_env);
+ break;
+
+ case cris_xor_op:
+ xor_op (inst, inst_env);
+ break;
+ }
+}
+
+/* This wrapper is to avoid cris_get_assembler being called before
+ exec_bfd has been set. */
+
+static int
+cris_delayed_get_disassembler (bfd_vma addr, disassemble_info *info)
+{
+ tm_print_insn = cris_get_disassembler (exec_bfd);
+ return TARGET_PRINT_INSN (addr, info);
+}
+
+/* Copied from <asm/elf.h>. */
+typedef unsigned long elf_greg_t;
+
+/* Same as user_regs_struct struct in <asm/user.h>. */
+typedef elf_greg_t elf_gregset_t[35];
+
+/* Unpack an elf_gregset_t into GDB's register cache. */
+
+void
+supply_gregset (elf_gregset_t *gregsetp)
+{
+ int i;
+ elf_greg_t *regp = *gregsetp;
+ static char zerobuf[4] = {0};
+
+ /* The kernel dumps all 32 registers as unsigned longs, but supply_register
+ knows about the actual size of each register so that's no problem. */
+ for (i = 0; i < NUM_GENREGS + NUM_SPECREGS; i++)
+ {
+ supply_register (i, (char *)&regp[i]);
+ }
+}
+
+/* Use a local version of this function to get the correct types for
+ regsets, until multi-arch core support is ready. */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+ elf_gregset_t gregset;
+
+ switch (which)
+ {
+ case 0:
+ if (core_reg_size != sizeof (gregset))
+ {
+ warning ("wrong size gregset struct in core file");
+ }
+ else
+ {
+ memcpy (&gregset, core_reg_sect, sizeof (gregset));
+ supply_gregset (&gregset);
+ }
+
+ default:
+ /* We've covered all the kinds of registers we know about here,
+ so this must be something we wouldn't know what to do with
+ anyway. Just ignore it. */
+ break;
+ }
+}
+
+static struct core_fns cris_elf_core_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+/* Fetch (and possibly build) an appropriate link_map_offsets
+ structure for native GNU/Linux CRIS targets using the struct
+ offsets defined in link.h (but without actual reference to that
+ file).
+
+ This makes it possible to access GNU/Linux CRIS shared libraries
+ from a GDB that was not built on an GNU/Linux CRIS host (for cross
+ debugging).
+
+ See gdb/solib-svr4.h for an explanation of these fields. */
+
+struct link_map_offsets *
+cris_linux_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_debug_size = 8; /* The actual size is 20 bytes, but
+ this is all we need. */
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 4;
+
+ lmo.link_map_size = 20;
+
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 4;
+
+ lmo.l_name_offset = 4;
+ lmo.l_name_size = 4;
+
+ lmo.l_next_offset = 12;
+ lmo.l_next_size = 4;
+
+ lmo.l_prev_offset = 16;
+ lmo.l_prev_size = 4;
+ }
+
+ return lmp;
+}
+
+static void
+cris_fpless_backtrace (char *noargs, int from_tty)
+{
+ /* Points at the instruction after the jsr (except when in innermost frame
+ where it points at the original pc). */
+ CORE_ADDR pc = 0;
+
+ /* Temporary variable, used for parsing from the start of the function that
+ the pc is in, up to the pc. */
+ CORE_ADDR tmp_pc = 0;
+ CORE_ADDR sp = 0;
+
+ /* Information about current frame. */
+ struct symtab_and_line sal;
+ char* func_name;
+
+ /* Present instruction. */
+ unsigned short insn;
+
+ /* Next instruction, lookahead. */
+ unsigned short insn_next;
+
+ /* This is to store the offset between sp at start of function and until we
+ reach push srp (if any). */
+ int sp_add_later = 0;
+ int push_srp_found = 0;
+
+ int val = 0;
+
+ /* Frame counter. */
+ int frame = 0;
+
+ /* For the innermost frame, we want to look at srp in case it's a leaf
+ function (since there's no push srp in that case). */
+ int innermost_frame = 1;
+
+ read_register_gen (PC_REGNUM, (char *) &pc);
+ read_register_gen (SP_REGNUM, (char *) &sp);
+
+ /* We make an explicit return when we can't find an outer frame. */
+ while (1)
+ {
+ /* Get file name and line number. */
+ sal = find_pc_line (pc, 0);
+
+ /* Get function name. */
+ find_pc_partial_function (pc, &func_name, (CORE_ADDR *) NULL,
+ (CORE_ADDR *) NULL);
+
+ /* Print information about current frame. */
+ printf_unfiltered ("#%i 0x%08lx in %s", frame++, pc, func_name);
+ if (sal.symtab)
+ {
+ printf_unfiltered (" at %s:%i", sal.symtab->filename, sal.line);
+ }
+ printf_unfiltered ("\n");
+
+ /* Get the start address of this function. */
+ tmp_pc = get_pc_function_start (pc);
+
+ /* Mini parser, only meant to find push sp and sub ...,sp from the start
+ of the function, up to the pc. */
+ while (tmp_pc < pc)
+ {
+ insn = read_memory_unsigned_integer (tmp_pc, sizeof (short));
+ tmp_pc += sizeof (short);
+ if (insn == 0xE1FC)
+ {
+ /* push <reg> 32 bit instruction */
+ insn_next = read_memory_unsigned_integer (tmp_pc,
+ sizeof (short));
+ tmp_pc += sizeof (short);
+
+ /* Recognize srp. */
+ if (insn_next == 0xBE7E)
+ {
+ /* For subsequent (not this one though) push or sub which
+ affects sp, adjust sp immediately. */
+ push_srp_found = 1;
+
+ /* Note: this will break if we ever encounter a
+ push vr (1 byte) or push ccr (2 bytes). */
+ sp_add_later += 4;
+ }
+ else
+ {
+ /* Some other register was pushed. */
+ if (push_srp_found)
+ {
+ sp += 4;
+ }
+ else
+ {
+ sp_add_later += 4;
+ }
+ }
+ }
+ else if (cris_get_operand2 (insn) == SP_REGNUM
+ && cris_get_mode (insn) == 0x0000
+ && cris_get_opcode (insn) == 0x000A)
+ {
+ /* subq <val>,sp */
+ val = cris_get_quick_value (insn);
+
+ if (push_srp_found)
+ {
+ sp += val;
+ }
+ else
+ {
+ sp_add_later += val;
+ }
+
+ }
+ else if (cris_get_operand2 (insn) == SP_REGNUM
+ /* Autoincrement addressing mode. */
+ && cris_get_mode (insn) == 0x0003
+ /* Opcode. */
+ && ((insn) & 0x03E0) >> 5 == 0x0004)
+ {
+ /* subu <val>,sp */
+ val = get_data_from_address (&insn, tmp_pc);
+
+ if (push_srp_found)
+ {
+ sp += val;
+ }
+ else
+ {
+ sp_add_later += val;
+ }
+ }
+ else if (cris_get_operand2 (insn) == SP_REGNUM
+ && ((insn & 0x0F00) >> 8) == 0x0001
+ && (cris_get_signed_offset (insn) < 0))
+ {
+ /* Immediate byte offset addressing prefix word with sp as base
+ register. Used for CRIS v8 i.e. ETRAX 100 and newer if <val>
+ is between 64 and 128.
+ movem r<regsave>,[sp=sp-<val>] */
+ val = -cris_get_signed_offset (insn);
+ insn_next = read_memory_unsigned_integer (tmp_pc,
+ sizeof (short));
+ tmp_pc += sizeof (short);
+
+ if (cris_get_mode (insn_next) == PREFIX_ASSIGN_MODE
+ && cris_get_opcode (insn_next) == 0x000F
+ && cris_get_size (insn_next) == 0x0003
+ && cris_get_operand1 (insn_next) == SP_REGNUM)
+ {
+ if (push_srp_found)
+ {
+ sp += val;
+ }
+ else
+ {
+ sp_add_later += val;
+ }
+ }
+ }
+ }
+
+ if (push_srp_found)
+ {
+ /* Reset flag. */
+ push_srp_found = 0;
+
+ /* sp should now point at where srp is stored on the stack. Update
+ the pc to the srp. */
+ pc = read_memory_unsigned_integer (sp, 4);
+ }
+ else if (innermost_frame)
+ {
+ /* We couldn't find a push srp in the prologue, so this must be
+ a leaf function, and thus we use the srp register directly.
+ This should happen at most once, for the innermost function. */
+ read_register_gen (SRP_REGNUM, (char *) &pc);
+ }
+ else
+ {
+ /* Couldn't find an outer frame. */
+ return;
+ }
+
+ /* Reset flag. (In case the innermost frame wasn't a leaf, we don't
+ want to look at the srp register later either). */
+ innermost_frame = 0;
+
+ /* Now, add the offset for everything up to, and including push srp,
+ that was held back during the prologue parsing. */
+ sp += sp_add_later;
+ sp_add_later = 0;
+ }
+}
+
+void
+_initialize_cris_tdep (void)
+{
+ struct cmd_list_element *c;
+
+ gdbarch_register (bfd_arch_cris, cris_gdbarch_init, cris_dump_tdep);
+
+ /* Used in disassembly. */
+ tm_print_insn = cris_delayed_get_disassembler;
+
+ /* CRIS-specific user-commands. */
+ c = add_set_cmd ("cris-version", class_support, var_integer,
+ (char *) &usr_cmd_cris_version,
+ "Set the current CRIS version.", &setlist);
+ set_cmd_sfunc (c, cris_version_update);
+ add_show_from_set (c, &showlist);
+
+ c = add_set_enum_cmd ("cris-mode", class_support, cris_mode_enums,
+ &usr_cmd_cris_mode,
+ "Set the current CRIS mode.", &setlist);
+ set_cmd_sfunc (c, cris_mode_update);
+ add_show_from_set (c, &showlist);
+
+ c = add_set_enum_cmd ("cris-abi", class_support, cris_abi_enums,
+ &usr_cmd_cris_abi,
+ "Set the current CRIS ABI version.", &setlist);
+ set_cmd_sfunc (c, cris_abi_update);
+ add_show_from_set (c, &showlist);
+
+ c = add_cmd ("cris-fpless-backtrace", class_support, cris_fpless_backtrace,
+ "Display call chain using the subroutine return pointer.\n"
+ "Note that this displays the address after the jump to the "
+ "subroutine.", &cmdlist);
+
+ add_core_fns (&cris_elf_core_fns);
+
+}
+
+/* Prints out all target specific values. */
+
+static void
+cris_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ if (tdep != NULL)
+ {
+ fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_version = %i\n",
+ tdep->cris_version);
+ fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_mode = %s\n",
+ tdep->cris_mode);
+ fprintf_unfiltered (file, "cris_dump_tdep: tdep->cris_abi = %s\n",
+ tdep->cris_abi);
+
+ }
+}
+
+static void
+cris_version_update (char *ignore_args, int from_tty,
+ struct cmd_list_element *c)
+{
+ struct gdbarch_info info;
+
+ /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones
+ the set command passed as a parameter. The clone operation will
+ include (BUG?) any ``set'' command callback, if present.
+ Commands like ``info set'' call all the ``show'' command
+ callbacks. Unfortunatly, for ``show'' commands cloned from
+ ``set'', this includes callbacks belonging to ``set'' commands.
+ Making this worse, this only occures if add_show_from_set() is
+ called after add_cmd_sfunc() (BUG?). */
+
+ /* From here on, trust the user's CRIS version setting. */
+ if (cmd_type (c) == set_cmd)
+ {
+ usr_cmd_cris_version_valid = 1;
+
+ /* Update the current architecture, if needed. */
+ gdbarch_info_init (&info);
+ if (!gdbarch_update_p (info))
+ internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to update architecture.");
+ }
+}
+
+static void
+cris_mode_update (char *ignore_args, int from_tty,
+ struct cmd_list_element *c)
+{
+ struct gdbarch_info info;
+
+ /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones
+ the set command passed as a parameter. The clone operation will
+ include (BUG?) any ``set'' command callback, if present.
+ Commands like ``info set'' call all the ``show'' command
+ callbacks. Unfortunatly, for ``show'' commands cloned from
+ ``set'', this includes callbacks belonging to ``set'' commands.
+ Making this worse, this only occures if add_show_from_set() is
+ called after add_cmd_sfunc() (BUG?). */
+
+ /* From here on, trust the user's CRIS mode setting. */
+ if (cmd_type (c) == set_cmd)
+ {
+ usr_cmd_cris_mode_valid = 1;
+
+ /* Update the current architecture, if needed. */
+ gdbarch_info_init (&info);
+ if (!gdbarch_update_p (info))
+ internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to update architecture.");
+ }
+}
+
+static void
+cris_abi_update (char *ignore_args, int from_tty,
+ struct cmd_list_element *c)
+{
+ struct gdbarch_info info;
+
+ /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones
+ the set command passed as a parameter. The clone operation will
+ include (BUG?) any ``set'' command callback, if present.
+ Commands like ``info set'' call all the ``show'' command
+ callbacks. Unfortunatly, for ``show'' commands cloned from
+ ``set'', this includes callbacks belonging to ``set'' commands.
+ Making this worse, this only occures if add_show_from_set() is
+ called after add_cmd_sfunc() (BUG?). */
+
+ /* From here on, trust the user's CRIS ABI setting. */
+ if (cmd_type (c) == set_cmd)
+ {
+ usr_cmd_cris_abi_valid = 1;
+
+ /* Update the current architecture, if needed. */
+ gdbarch_info_init (&info);
+ if (!gdbarch_update_p (info))
+ internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to update architecture.");
+ }
+}
+
+/* Copied from pa64solib.c, with a couple of minor changes. */
+
+static CORE_ADDR
+bfd_lookup_symbol (bfd *abfd, const char *symname)
+{
+ unsigned int storage_needed;
+ asymbol *sym;
+ asymbol **symbol_table;
+ unsigned int number_of_symbols;
+ unsigned int i;
+ struct cleanup *back_to;
+ CORE_ADDR symaddr = 0;
+
+ storage_needed = bfd_get_symtab_upper_bound (abfd);
+
+ if (storage_needed > 0)
+ {
+ symbol_table = (asymbol **) xmalloc (storage_needed);
+ back_to = make_cleanup (free, (PTR) symbol_table);
+ number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
+
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ sym = *symbol_table++;
+ if (!strcmp (sym->name, symname))
+ {
+ /* Bfd symbols are section relative. */
+ symaddr = sym->value + sym->section->vma;
+ break;
+ }
+ }
+ do_cleanups (back_to);
+ }
+ return (symaddr);
+}
+
+static struct gdbarch *
+cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch *gdbarch;
+ struct gdbarch_tdep *tdep;
+ int cris_version;
+ const char *cris_mode;
+ const char *cris_abi;
+ CORE_ADDR cris_abi_sym = 0;
+ int register_bytes;
+
+ if (usr_cmd_cris_version_valid)
+ {
+ /* Trust the user's CRIS version setting. */
+ cris_version = usr_cmd_cris_version;
+ }
+ else
+ {
+ /* Assume it's CRIS version 10. */
+ cris_version = 10;
+ }
+
+ if (usr_cmd_cris_mode_valid)
+ {
+ /* Trust the user's CRIS mode setting. */
+ cris_mode = usr_cmd_cris_mode;
+ }
+ else if (cris_version == 10)
+ {
+ /* Assume CRIS version 10 is in user mode. */
+ cris_mode = CRIS_MODE_USER;
+ }
+ else
+ {
+ /* Strictly speaking, older CRIS version don't have a supervisor mode,
+ but we regard its only mode as supervisor mode. */
+ cris_mode = CRIS_MODE_SUPERVISOR;
+ }
+
+ if (usr_cmd_cris_abi_valid)
+ {
+ /* Trust the user's ABI setting. */
+ cris_abi = usr_cmd_cris_abi;
+ }
+ else if (info.abfd)
+ {
+ if (bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
+ {
+ /* An elf target uses the new ABI. */
+ cris_abi = CRIS_ABI_V2;
+ }
+ else if (bfd_get_flavour (info.abfd) == bfd_target_aout_flavour)
+ {
+ /* An a.out target may use either ABI. Look for hints in the
+ symbol table. */
+ cris_abi_sym = bfd_lookup_symbol (info.abfd, CRIS_ABI_SYMBOL);
+ cris_abi = cris_abi_sym ? CRIS_ABI_V2 : CRIS_ABI_ORIGINAL;
+ }
+ else
+ {
+ /* Unknown bfd flavour. Assume it's the new ABI. */
+ cris_abi = CRIS_ABI_V2;
+ }
+ }
+ else if (arches != NULL)
+ {
+ /* No bfd available. Stick with the ABI from the most recently
+ selected architecture of this same family (the head of arches
+ always points to this). (This is to avoid changing the ABI
+ when the user updates the architecture with the 'set
+ cris-version' command.) */
+ cris_abi = gdbarch_tdep (arches->gdbarch)->cris_abi;
+ }
+ else
+ {
+ /* No bfd, and no previously selected architecture available.
+ Assume it's the new ABI. */
+ cris_abi = CRIS_ABI_V2;
+ }
+
+ /* Make the current settings visible to the user. */
+ usr_cmd_cris_version = cris_version;
+ usr_cmd_cris_mode = cris_mode;
+ usr_cmd_cris_abi = cris_abi;
+
+ /* Find a candidate among the list of pre-declared architectures. Both
+ CRIS version and ABI must match. */
+ for (arches = gdbarch_list_lookup_by_info (arches, &info);
+ arches != NULL;
+ arches = gdbarch_list_lookup_by_info (arches->next, &info))
+ {
+ if ((gdbarch_tdep (arches->gdbarch)->cris_version == cris_version)
+ && (gdbarch_tdep (arches->gdbarch)->cris_mode == cris_mode)
+ && (gdbarch_tdep (arches->gdbarch)->cris_abi == cris_abi))
+ return arches->gdbarch;
+ }
+
+ /* No matching architecture was found. Create a new one. */
+ tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ tdep->cris_version = cris_version;
+ tdep->cris_mode = cris_mode;
+ tdep->cris_abi = cris_abi;
+
+ /* INIT shall ensure that the INFO.BYTE_ORDER is non-zero. */
+ switch (info.byte_order)
+ {
+ case BFD_ENDIAN_LITTLE:
+ /* Ok. */
+ break;
+
+ case BFD_ENDIAN_BIG:
+ internal_error (__FILE__, __LINE__, "cris_gdbarch_init: big endian byte order in info");
+ break;
+
+ default:
+ internal_error (__FILE__, __LINE__, "cris_gdbarch_init: unknown byte order in info");
+ }
+
+ /* Initialize the ABI dependent things. */
+ if (tdep->cris_abi == CRIS_ABI_ORIGINAL)
+ {
+ set_gdbarch_double_bit (gdbarch, 32);
+ set_gdbarch_push_arguments (gdbarch, cris_abi_original_push_arguments);
+ set_gdbarch_store_return_value (gdbarch,
+ cris_abi_original_store_return_value);
+ set_gdbarch_extract_return_value
+ (gdbarch, cris_abi_original_extract_return_value);
+ set_gdbarch_reg_struct_has_addr
+ (gdbarch, cris_abi_original_reg_struct_has_addr);
+ }
+ else if (tdep->cris_abi == CRIS_ABI_V2)
+ {
+ set_gdbarch_double_bit (gdbarch, 64);
+ set_gdbarch_push_arguments (gdbarch, cris_abi_v2_push_arguments);
+ set_gdbarch_store_return_value (gdbarch, cris_abi_v2_store_return_value);
+ set_gdbarch_extract_return_value (gdbarch,
+ cris_abi_v2_extract_return_value);
+ set_gdbarch_reg_struct_has_addr (gdbarch,
+ cris_abi_v2_reg_struct_has_addr);
+ }
+ else
+ internal_error (__FILE__, __LINE__, "cris_gdbarch_init: unknown CRIS ABI");
+
+ /* The default definition of a long double is 2 * TARGET_DOUBLE_BIT,
+ which means we have to set this explicitly. */
+ set_gdbarch_long_double_bit (gdbarch, 64);
+
+ /* There are 32 registers (some of which may not be implemented). */
+ set_gdbarch_num_regs (gdbarch, 32);
+ set_gdbarch_sp_regnum (gdbarch, 14);
+ set_gdbarch_fp_regnum (gdbarch, 8);
+ set_gdbarch_pc_regnum (gdbarch, 15);
+
+ set_gdbarch_register_name (gdbarch, cris_register_name);
+
+ /* Length of ordinary registers used in push_word and a few other places.
+ REGISTER_RAW_SIZE is the real way to know how big a register is. */
+ set_gdbarch_register_size (gdbarch, 4);
+
+ /* NEW */
+ set_gdbarch_register_bytes_ok (gdbarch, cris_register_bytes_ok);
+ set_gdbarch_software_single_step (gdbarch, cris_software_single_step);
+
+
+ set_gdbarch_cannot_store_register (gdbarch, cris_cannot_store_register);
+ set_gdbarch_cannot_fetch_register (gdbarch, cris_cannot_fetch_register);
+
+
+ /* The total amount of space needed to store (in an array called registers)
+ GDB's copy of the machine's register state. Note: We can not use
+ cris_register_size at this point, since it relies on current_gdbarch
+ being set. */
+ switch (tdep->cris_version)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ /* Support for these may be added later. */
+ internal_error (__FILE__, __LINE__, "cris_gdbarch_init: unsupported CRIS version");
+ break;
+
+ case 8:
+ case 9:
+ /* CRIS v8 and v9, a.k.a. ETRAX 100. General registers R0 - R15
+ (32 bits), special registers P0 - P1 (8 bits), P4 - P5 (16 bits),
+ and P8 - P14 (32 bits). */
+ register_bytes = (16 * 4) + (2 * 1) + (2 * 2) + (7 * 4);
+ break;
+
+ case 10:
+ case 11:
+ /* CRIS v10 and v11, a.k.a. ETRAX 100LX. In addition to ETRAX 100,
+ P7 (32 bits), and P15 (32 bits) have been implemented. */
+ register_bytes = (16 * 4) + (2 * 1) + (2 * 2) + (9 * 4);
+ break;
+
+ default:
+ internal_error (__FILE__, __LINE__, "cris_gdbarch_init: unknown CRIS version");
+ }
+
+ set_gdbarch_register_bytes (gdbarch, register_bytes);
+
+ /* Returns the register offset for the first byte of register regno's space
+ in the saved register state. */
+ set_gdbarch_register_byte (gdbarch, cris_register_offset);
+
+ /* The length of the registers in the actual machine representation. */
+ set_gdbarch_register_raw_size (gdbarch, cris_register_size);
+
+ /* The largest value REGISTER_RAW_SIZE can have. */
+ set_gdbarch_max_register_raw_size (gdbarch, 32);
+
+ /* The length of the registers in the program's representation. */
+ set_gdbarch_register_virtual_size (gdbarch, cris_register_size);
+
+ /* The largest value REGISTER_VIRTUAL_SIZE can have. */
+ set_gdbarch_max_register_virtual_size (gdbarch, 32);
+
+ set_gdbarch_register_virtual_type (gdbarch, cris_register_virtual_type);
+
+ /* Use generic dummy frames. */
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+
+ /* Where to execute the call in the memory segments. */
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
+
+ /* Start execution at the beginning of dummy. */
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+
+ /* Set to 1 since call_dummy_breakpoint_offset was defined. */
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+
+ /* Read all about dummy frames in blockframe.c. */
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
+
+ /* Defined to 1 to indicate that the target supports inferior function
+ calls. */
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_words (gdbarch, 0);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
+
+ /* No stack adjustment needed when peforming an inferior function call. */
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
+
+ set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+
+ /* No register requires conversion from raw format to virtual format. */
+ set_gdbarch_register_convertible (gdbarch, generic_register_convertible_not);
+
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+ set_gdbarch_push_return_address (gdbarch, cris_push_return_address);
+ set_gdbarch_pop_frame (gdbarch, cris_pop_frame);
+
+ set_gdbarch_store_struct_return (gdbarch, cris_store_struct_return);
+ set_gdbarch_extract_struct_value_address (gdbarch,
+ cris_extract_struct_value_address);
+ set_gdbarch_use_struct_convention (gdbarch, cris_use_struct_convention);
+
+ set_gdbarch_frame_init_saved_regs (gdbarch, cris_frame_init_saved_regs);
+ set_gdbarch_init_extra_frame_info (gdbarch, cris_init_extra_frame_info);
+ set_gdbarch_skip_prologue (gdbarch, cris_skip_prologue);
+ set_gdbarch_prologue_frameless_p (gdbarch, generic_prologue_frameless_p);
+
+ /* The stack grows downward. */
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+
+ set_gdbarch_breakpoint_from_pc (gdbarch, cris_breakpoint_from_pc);
+
+ /* The PC must not be decremented after a breakpoint. (The breakpoint
+ handler takes care of that.) */
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+
+ /* Offset from address of function to start of its code. */
+ set_gdbarch_function_start_offset (gdbarch, 0);
+
+ /* The number of bytes at the start of arglist that are not really args,
+ 0 in the CRIS ABI. */
+ set_gdbarch_frame_args_skip (gdbarch, 0);
+ set_gdbarch_frameless_function_invocation
+ (gdbarch, cris_frameless_function_invocation);
+ set_gdbarch_frame_chain (gdbarch, cris_frame_chain);
+ set_gdbarch_frame_chain_valid (gdbarch, generic_file_frame_chain_valid);
+
+ set_gdbarch_frame_saved_pc (gdbarch, cris_frame_saved_pc);
+ set_gdbarch_frame_args_address (gdbarch, cris_frame_args_address);
+ set_gdbarch_frame_locals_address (gdbarch, cris_frame_locals_address);
+ set_gdbarch_saved_pc_after_call (gdbarch, cris_saved_pc_after_call);
+
+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+
+ /* No extra stack alignment needed. Set to 1 by default. */
+ set_gdbarch_extra_stack_alignment_needed (gdbarch, 0);
+
+ /* Helpful for backtracing and returning in a call dummy. */
+ set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
+
+ /* Use target_specific function to define link map offsets. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, cris_linux_svr4_fetch_link_map_offsets);
+
+ return gdbarch;
+}
diff --git a/gdb/cxux-nat.c b/gdb/cxux-nat.c
new file mode 100644
index 00000000000..742f89cdb19
--- /dev/null
+++ b/gdb/cxux-nat.c
@@ -0,0 +1,537 @@
+/* Native support for Motorola 88k running Harris CX/UX.
+ Copyright 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000,
+ 2001 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include "gdbcore.h"
+#include <sys/user.h>
+
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "symtab.h"
+#include "regcache.h"
+
+#ifndef USER /* added to support BCS ptrace_user */
+#define USER ptrace_user
+#endif
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <sys/file.h>
+#include "gdb_stat.h"
+
+#include "symtab.h"
+#include "setjmp.h"
+#include "value.h"
+
+#include <sys/ptrace.h>
+
+/* CX/UX provides them already, but as word offsets instead of char offsets */
+#define SXIP_OFFSET (PT_SXIP * 4)
+#define SNIP_OFFSET (PT_SNIP * 4)
+#define SFIP_OFFSET (PT_SFIP * 4)
+#define PSR_OFFSET (PT_PSR * sizeof(int))
+#define FPSR_OFFSET (PT_FPSR * sizeof(int))
+#define FPCR_OFFSET (PT_FPCR * sizeof(int))
+
+#define XREGADDR(r) (((char *)&u.pt_x0-(char *)&u) + \
+ ((r)-X0_REGNUM)*sizeof(X_REGISTER_RAW_TYPE))
+
+extern int have_symbol_file_p ();
+
+extern jmp_buf stack_jmp;
+
+extern int errno;
+
+void
+fetch_inferior_registers (int regno)
+{
+ register unsigned int regaddr;
+ char buf[MAX_REGISTER_RAW_SIZE];
+ register int i;
+
+ struct USER u;
+ unsigned int offset;
+
+ offset = (char *) &u.pt_r0 - (char *) &u;
+ regaddr = offset; /* byte offset to r0; */
+
+/* offset = ptrace (3, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) offset, 0) - KERNEL_U_ADDR; */
+ for (regno = 0; regno < PC_REGNUM; regno++)
+ {
+ /*regaddr = register_addr (regno, offset); */
+ /* 88k enhancement */
+
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+ {
+ *(int *) &buf[i] = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) regaddr, 0);
+ regaddr += sizeof (int);
+ }
+ supply_register (regno, buf);
+ }
+ /* now load up registers 32-37; special pc registers */
+ *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) PSR_OFFSET, 0);
+ supply_register (PSR_REGNUM, buf);
+ *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) FPSR_OFFSET, 0);
+ supply_register (FPSR_REGNUM, buf);
+ *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) FPCR_OFFSET, 0);
+ supply_register (FPCR_REGNUM, buf);
+ *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SXIP_OFFSET, 0);
+ supply_register (SXIP_REGNUM, buf);
+ *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SNIP_OFFSET, 0);
+ supply_register (SNIP_REGNUM, buf);
+ *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SFIP_OFFSET, 0);
+ supply_register (SFIP_REGNUM, buf);
+
+ if (target_is_m88110)
+ {
+ for (regaddr = XREGADDR (X0_REGNUM), regno = X0_REGNUM;
+ regno < NUM_REGS;
+ regno++, regaddr += 16)
+ {
+ X_REGISTER_RAW_TYPE xval;
+
+ *(int *) &xval.w1 = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) regaddr, 0);
+ *(int *) &xval.w2 = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) (regaddr + 4), 0);
+ *(int *) &xval.w3 = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) (regaddr + 8), 0);
+ *(int *) &xval.w4 = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) (regaddr + 12), 0);
+ supply_register (regno, (void *) &xval);
+ }
+ }
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ register unsigned int regaddr;
+ char buf[80];
+
+ struct USER u;
+
+ unsigned int offset = (char *) &u.pt_r0 - (char *) &u;
+
+ regaddr = offset;
+
+ /* Don't try to deal with EXIP_REGNUM or ENIP_REGNUM, because I think either
+ svr3 doesn't run on an 88110, or the kernel isolates the different (not
+ completely sure this is true, but seems to be. */
+ if (regno >= 0)
+ {
+ /* regaddr = register_addr (regno, offset); */
+ if (regno < PC_REGNUM)
+ {
+ regaddr = offset + regno * sizeof (int);
+ errno = 0;
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) regaddr, read_register (regno));
+ if (errno != 0)
+ {
+ sprintf (buf, "writing register number %d", regno);
+ perror_with_name (buf);
+ }
+ }
+ else if (regno == PSR_REGNUM)
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) PSR_OFFSET, read_register (regno));
+ else if (regno == FPSR_REGNUM)
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) FPSR_OFFSET, read_register (regno));
+ else if (regno == FPCR_REGNUM)
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) FPCR_OFFSET, read_register (regno));
+ else if (regno == SXIP_REGNUM)
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register (regno));
+ else if (regno == SNIP_REGNUM)
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register (regno));
+ else if (regno == SFIP_REGNUM)
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register (regno));
+ else if (target_is_m88110 && regno < NUM_REGS)
+ {
+ X_REGISTER_RAW_TYPE xval;
+
+ read_register_bytes (REGISTER_BYTE (regno), (char *) &xval,
+ sizeof (X_REGISTER_RAW_TYPE));
+ regaddr = XREGADDR (regno);
+ ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr, xval.w1);
+ ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr + 4, xval.w2);
+ ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr + 8, xval.w3);
+ ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr + 12, xval.w4);
+ }
+ else
+ printf_unfiltered ("Bad register number for store_inferior routine\n");
+ }
+ else
+ {
+ for (regno = 0; regno < PC_REGNUM; regno++)
+ {
+ /* regaddr = register_addr (regno, offset); */
+ errno = 0;
+ regaddr = offset + regno * sizeof (int);
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) regaddr, read_register (regno));
+ if (errno != 0)
+ {
+ sprintf (buf, "writing register number %d", regno);
+ perror_with_name (buf);
+ }
+ }
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) PSR_OFFSET, read_register (regno));
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) FPSR_OFFSET, read_register (regno));
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) FPCR_OFFSET, read_register (regno));
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register (SXIP_REGNUM));
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register (SNIP_REGNUM));
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register (SFIP_REGNUM));
+ if (target_is_m88110)
+ {
+ for (regno = X0_REGNUM; regno < NUM_REGS; regno++)
+ {
+ X_REGISTER_RAW_TYPE xval;
+
+ read_register_bytes (REGISTER_BYTE (regno), (char *) &xval,
+ sizeof (X_REGISTER_RAW_TYPE));
+ regaddr = XREGADDR (regno);
+ ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr, xval.w1);
+ ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) (regaddr + 4), xval.w2);
+ ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) (regaddr + 8), xval.w3);
+ ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) (regaddr + 12), xval.w4);
+ }
+ }
+ }
+}
+
+/* blockend is the address of the end of the user structure */
+
+m88k_register_u_addr (int blockend, int regnum)
+{
+ struct USER u;
+ int ustart = blockend - sizeof (struct USER);
+
+ if (regnum < PSR_REGNUM)
+ return (ustart + ((int) &u.pt_r0 - (int) &u) +
+ REGISTER_SIZE * regnum);
+ else if (regnum == PSR_REGNUM)
+ return (ustart + ((int) &u.pt_psr) - (int) &u);
+ else if (regnum == FPSR_REGNUM)
+ return (ustart + ((int) &u.pt_fpsr) - (int) &u);
+ else if (regnum == FPCR_REGNUM)
+ return (ustart + ((int) &u.pt_fpcr) - (int) &u);
+ else if (regnum == SXIP_REGNUM)
+ return (ustart + SXIP_OFFSET);
+ else if (regnum == SNIP_REGNUM)
+ return (ustart + SNIP_OFFSET);
+ else if (regnum == SFIP_REGNUM)
+ return (ustart + SFIP_OFFSET);
+ else if (target_is_m88110)
+ return (ustart + ((int) &u.pt_x0 - (int) &u) + /* Must be X register */
+ sizeof (u.pt_x0) * (regnum - X0_REGNUM));
+ else
+ return (blockend + REGISTER_SIZE * regnum);
+}
+
+#ifdef USE_PROC_FS
+
+#include <sys/procfs.h>
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* Given a pointer to a general register set in /proc format (gregset_t *),
+ unpack the register contents and supply them as gdb's idea of the current
+ register values. */
+
+void
+supply_gregset (gregset_t *gregsetp)
+{
+ register int regi;
+ register greg_t *regp = (greg_t *) gregsetp;
+
+ for (regi = 0; regi <= SP_REGNUM; regi++)
+ supply_register (regi, (char *) (regp + regi));
+
+ supply_register (SXIP_REGNUM, (char *) (regp + R_XIP));
+ supply_register (SNIP_REGNUM, (char *) (regp + R_NIP));
+ supply_register (SFIP_REGNUM, (char *) (regp + R_FIP));
+ supply_register (PSR_REGNUM, (char *) (regp + R_PSR));
+ supply_register (FPSR_REGNUM, (char *) (regp + R_FPSR));
+ supply_register (FPCR_REGNUM, (char *) (regp + R_FPCR));
+}
+
+void
+fill_gregset (gregset_t *gregsetp, int regno)
+{
+ int regi;
+ register greg_t *regp = (greg_t *) gregsetp;
+
+ for (regi = 0; regi <= R_R31; regi++)
+ if ((regno == -1) || (regno == regi))
+ *(regp + regi) = *(int *) &registers[REGISTER_BYTE (regi)];
+
+ if ((regno == -1) || (regno == SXIP_REGNUM))
+ *(regp + R_XIP) = *(int *) &registers[REGISTER_BYTE (SXIP_REGNUM)];
+ if ((regno == -1) || (regno == SNIP_REGNUM))
+ *(regp + R_NIP) = *(int *) &registers[REGISTER_BYTE (SNIP_REGNUM)];
+ if ((regno == -1) || (regno == SFIP_REGNUM))
+ *(regp + R_FIP) = *(int *) &registers[REGISTER_BYTE (SFIP_REGNUM)];
+ if ((regno == -1) || (regno == PSR_REGNUM))
+ *(regp + R_PSR) = *(int *) &registers[REGISTER_BYTE (PSR_REGNUM)];
+ if ((regno == -1) || (regno == FPSR_REGNUM))
+ *(regp + R_FPSR) = *(int *) &registers[REGISTER_BYTE (FPSR_REGNUM)];
+ if ((regno == -1) || (regno == FPCR_REGNUM))
+ *(regp + R_FPCR) = *(int *) &registers[REGISTER_BYTE (FPCR_REGNUM)];
+}
+
+#endif /* USE_PROC_FS */
+
+/* This support adds the equivalent of adb's % command. When
+ the `add-shared-symbol-files' command is given, this routine scans
+ the dynamic linker's link map and reads the minimal symbols
+ from each shared object file listed in the map. */
+
+struct link_map
+{
+ unsigned long l_addr; /* address at which object is mapped */
+ char *l_name; /* full name of loaded object */
+ void *l_ld; /* dynamic structure of object */
+ struct link_map *l_next; /* next link object */
+ struct link_map *l_prev; /* previous link object */
+};
+
+#define LINKS_MAP_POINTER "_ld_tail"
+#define LIBC_FILE "/usr/lib/libc.so.1"
+#define SHARED_OFFSET 0xf0001000
+
+#ifndef PATH_MAX
+#define PATH_MAX 1023 /* maximum size of path name on OS */
+#endif
+
+void
+add_shared_symbol_files (void)
+{
+ void *desc;
+ struct link_map *ld_map, *lm, lms;
+ struct minimal_symbol *minsym;
+ struct objfile *objfile;
+ char *path_name;
+
+ if (ptid_equal (inferior_ptid, null_ptid))
+ {
+ warning ("The program has not yet been started.");
+ return;
+ }
+
+ objfile = symbol_file_add (LIBC_FILE, 0, NULL, 0, OBJF_READNOW);
+ minsym = lookup_minimal_symbol (LINKS_MAP_POINTER, objfile);
+
+ ld_map = (struct link_map *)
+ read_memory_integer (((int) SYMBOL_VALUE_ADDRESS (minsym) + SHARED_OFFSET), 4);
+ lm = ld_map;
+ while (lm)
+ {
+ int local_errno = 0;
+
+ read_memory ((CORE_ADDR) lm, (char *) &lms, sizeof (struct link_map));
+ if (lms.l_name)
+ {
+ if (target_read_string ((CORE_ADDR) lms.l_name, &path_name,
+ PATH_MAX, &local_errno))
+ {
+ struct section_addr_info section_addrs;
+ memset (&section_addrs, 0, sizeof (section_addrs));
+ section_addrs.other[0].addr = lms.l_addr;
+ section_addrs.other[0].name = ".text";
+ symbol_file_add (path_name, 1, &section_addrs, 0, 0);
+ xfree (path_name);
+ }
+ }
+ /* traverse links in reverse order so that we get the
+ the symbols the user actually gets. */
+ lm = lms.l_prev;
+ }
+
+ /* Getting new symbols may change our opinion about what is
+ frameless. */
+ reinit_frame_cache ();
+}
+
+#if defined(_ES_MP)
+
+#include <sys/regset.h>
+
+unsigned int
+m88k_harris_core_register_addr (int regno, int reg_ptr)
+{
+ unsigned int word_offset;
+
+ switch (regno)
+ {
+ case PSR_REGNUM:
+ word_offset = R_EPSR;
+ break;
+ case FPSR_REGNUM:
+ word_offset = R_FPSR;
+ break;
+ case FPCR_REGNUM:
+ word_offset = R_FPCR;
+ break;
+ case SXIP_REGNUM:
+ word_offset = R_EXIP;
+ break;
+ case SNIP_REGNUM:
+ word_offset = R_ENIP;
+ break;
+ case SFIP_REGNUM:
+ word_offset = R_EFIP;
+ break;
+ default:
+ if (regno <= FP_REGNUM)
+ word_offset = regno;
+ else
+ word_offset = ((regno - X0_REGNUM) * 4);
+ }
+ return (word_offset * 4);
+}
+
+#endif /* _ES_MP */
+
+void
+_initialize_m88k_nat (void)
+{
+#ifdef _ES_MP
+ /* Enable 88110 support, as we don't support the 88100 under ES/MP. */
+
+ target_is_m88110 = 1;
+#elif defined(_CX_UX)
+ /* Determine whether we're running on an 88100 or an 88110. */
+ target_is_m88110 = (sinfo (SYSMACHINE, 0) == SYS5800);
+#endif /* _CX_UX */
+}
+
+#ifdef _ES_MP
+/* Given a pointer to a general register set in /proc format (gregset_t *),
+ unpack the register contents and supply them as gdb's idea of the current
+ register values. */
+
+void
+supply_gregset (gregset_t *gregsetp)
+{
+ register int regi;
+ register greg_t *regp = (greg_t *) gregsetp;
+
+ for (regi = 0; regi < R_R31; regi++)
+ {
+ supply_register (regi, (char *) (regp + regi));
+ }
+ supply_register (PSR_REGNUM, (char *) (regp + R_EPSR));
+ supply_register (FPSR_REGNUM, (char *) (regp + R_FPSR));
+ supply_register (FPCR_REGNUM, (char *) (regp + R_FPCR));
+ supply_register (SXIP_REGNUM, (char *) (regp + R_EXIP));
+ supply_register (SNIP_REGNUM, (char *) (regp + R_ENIP));
+ supply_register (SFIP_REGNUM, (char *) (regp + R_EFIP));
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), unpack the register contents and supply them as gdb's
+ idea of the current floating point register values. */
+
+void
+supply_fpregset (fpregset_t *fpregsetp)
+{
+ register int regi;
+ char *from;
+
+ for (regi = FP0_REGNUM; regi <= FPLAST_REGNUM; regi++)
+ {
+ from = (char *) &((*fpregsetp)[regi - FP0_REGNUM]);
+ supply_register (regi, from);
+ }
+}
+
+#endif /* _ES_MP */
+
+#ifdef _CX_UX
+
+#include <sys/regset.h>
+
+unsigned int
+m88k_harris_core_register_addr (int regno, int reg_ptr)
+{
+ unsigned int word_offset;
+
+ switch (regno)
+ {
+ case PSR_REGNUM:
+ word_offset = R_PSR;
+ break;
+ case FPSR_REGNUM:
+ word_offset = R_FPSR;
+ break;
+ case FPCR_REGNUM:
+ word_offset = R_FPCR;
+ break;
+ case SXIP_REGNUM:
+ word_offset = R_XIP;
+ break;
+ case SNIP_REGNUM:
+ word_offset = R_NIP;
+ break;
+ case SFIP_REGNUM:
+ word_offset = R_FIP;
+ break;
+ default:
+ if (regno <= FP_REGNUM)
+ word_offset = regno;
+ else
+ word_offset = ((regno - X0_REGNUM) * 4) + R_X0;
+ }
+ return (word_offset * 4);
+}
+
+#endif /* _CX_UX */
diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c
new file mode 100644
index 00000000000..cd260da8086
--- /dev/null
+++ b/gdb/d10v-tdep.c
@@ -0,0 +1,1657 @@
+/* Target-dependent code for Mitsubishi D10V, for GDB.
+
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 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. */
+
+/* Contributed by Martin Hunt, hunt@cygnus.com */
+
+#include "defs.h"
+#include "frame.h"
+#include "obstack.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "gdb_string.h"
+#include "value.h"
+#include "inferior.h"
+#include "dis-asm.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "language.h"
+#include "arch-utils.h"
+#include "regcache.h"
+
+#include "floatformat.h"
+#include "gdb/sim-d10v.h"
+
+struct frame_extra_info
+ {
+ CORE_ADDR return_pc;
+ int frameless;
+ int size;
+ };
+
+struct gdbarch_tdep
+ {
+ int a0_regnum;
+ int nr_dmap_regs;
+ unsigned long (*dmap_register) (int nr);
+ unsigned long (*imap_register) (int nr);
+ };
+
+/* These are the addresses the D10V-EVA board maps data and
+ instruction memory to. */
+
+enum memspace {
+ DMEM_START = 0x2000000,
+ IMEM_START = 0x1000000,
+ STACK_START = 0x200bffe
+};
+
+/* d10v register names. */
+
+enum
+ {
+ R0_REGNUM = 0,
+ R3_REGNUM = 3,
+ _FP_REGNUM = 11,
+ LR_REGNUM = 13,
+ _SP_REGNUM = 15,
+ PSW_REGNUM = 16,
+ _PC_REGNUM = 18,
+ NR_IMAP_REGS = 2,
+ NR_A_REGS = 2,
+ TS2_NUM_REGS = 37,
+ TS3_NUM_REGS = 42,
+ /* d10v calling convention. */
+ ARG1_REGNUM = R0_REGNUM,
+ ARGN_REGNUM = R3_REGNUM,
+ RET1_REGNUM = R0_REGNUM,
+ };
+
+#define NR_DMAP_REGS (gdbarch_tdep (current_gdbarch)->nr_dmap_regs)
+#define A0_REGNUM (gdbarch_tdep (current_gdbarch)->a0_regnum)
+
+/* Local functions */
+
+extern void _initialize_d10v_tdep (void);
+
+static void d10v_eva_prepare_to_trace (void);
+
+static void d10v_eva_get_trace_data (void);
+
+static int prologue_find_regs (unsigned short op, struct frame_info *fi,
+ CORE_ADDR addr);
+
+static void d10v_frame_init_saved_regs (struct frame_info *);
+
+static void do_d10v_pop_frame (struct frame_info *fi);
+
+static int
+d10v_frame_chain_valid (CORE_ADDR chain, struct frame_info *frame)
+{
+ if (chain != 0 && frame != NULL)
+ {
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ return 1; /* Path back from a call dummy must be valid. */
+ return ((frame)->pc > IMEM_START
+ && !inside_main_func (frame->pc));
+ }
+ else return 0;
+}
+
+static CORE_ADDR
+d10v_stack_align (CORE_ADDR len)
+{
+ return (len + 1) & ~1;
+}
+
+/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of
+ EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc
+ and TYPE is the type (which is known to be struct, union or array).
+
+ The d10v returns anything less than 8 bytes in size in
+ registers. */
+
+static int
+d10v_use_struct_convention (int gcc_p, struct type *type)
+{
+ long alignment;
+ int i;
+ /* The d10v only passes a struct in a register when that structure
+ has an alignment that matches the size of a register. */
+ /* If the structure doesn't fit in 4 registers, put it on the
+ stack. */
+ if (TYPE_LENGTH (type) > 8)
+ return 1;
+ /* If the struct contains only one field, don't put it on the stack
+ - gcc can fit it in one or more registers. */
+ if (TYPE_NFIELDS (type) == 1)
+ return 0;
+ alignment = TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0));
+ for (i = 1; i < TYPE_NFIELDS (type); i++)
+ {
+ /* If the alignment changes, just assume it goes on the
+ stack. */
+ if (TYPE_LENGTH (TYPE_FIELD_TYPE (type, i)) != alignment)
+ return 1;
+ }
+ /* If the alignment is suitable for the d10v's 16 bit registers,
+ don't put it on the stack. */
+ if (alignment == 2 || alignment == 4)
+ return 0;
+ return 1;
+}
+
+
+static const unsigned char *
+d10v_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+ static unsigned char breakpoint[] =
+ {0x2f, 0x90, 0x5e, 0x00};
+ *lenptr = sizeof (breakpoint);
+ return breakpoint;
+}
+
+/* Map the REG_NR onto an ascii name. Return NULL or an empty string
+ when the reg_nr isn't valid. */
+
+enum ts2_regnums
+ {
+ TS2_IMAP0_REGNUM = 32,
+ TS2_DMAP_REGNUM = 34,
+ TS2_NR_DMAP_REGS = 1,
+ TS2_A0_REGNUM = 35
+ };
+
+static char *
+d10v_ts2_register_name (int reg_nr)
+{
+ static char *register_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "psw", "bpsw", "pc", "bpc", "cr4", "cr5", "cr6", "rpt_c",
+ "rpt_s", "rpt_e", "mod_s", "mod_e", "cr12", "cr13", "iba", "cr15",
+ "imap0", "imap1", "dmap", "a0", "a1"
+ };
+ if (reg_nr < 0)
+ return NULL;
+ if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
+ return NULL;
+ return register_names[reg_nr];
+}
+
+enum ts3_regnums
+ {
+ TS3_IMAP0_REGNUM = 36,
+ TS3_DMAP0_REGNUM = 38,
+ TS3_NR_DMAP_REGS = 4,
+ TS3_A0_REGNUM = 32
+ };
+
+static char *
+d10v_ts3_register_name (int reg_nr)
+{
+ static char *register_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "psw", "bpsw", "pc", "bpc", "cr4", "cr5", "cr6", "rpt_c",
+ "rpt_s", "rpt_e", "mod_s", "mod_e", "cr12", "cr13", "iba", "cr15",
+ "a0", "a1",
+ "spi", "spu",
+ "imap0", "imap1",
+ "dmap0", "dmap1", "dmap2", "dmap3"
+ };
+ if (reg_nr < 0)
+ return NULL;
+ if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
+ return NULL;
+ return register_names[reg_nr];
+}
+
+/* Access the DMAP/IMAP registers in a target independent way.
+
+ Divide the D10V's 64k data space into four 16k segments:
+ 0x0000 -- 0x3fff, 0x4000 -- 0x7fff, 0x8000 -- 0xbfff, and
+ 0xc000 -- 0xffff.
+
+ On the TS2, the first two segments (0x0000 -- 0x3fff, 0x4000 --
+ 0x7fff) always map to the on-chip data RAM, and the fourth always
+ maps to I/O space. The third (0x8000 - 0xbfff) can be mapped into
+ unified memory or instruction memory, under the control of the
+ single DMAP register.
+
+ On the TS3, there are four DMAP registers, each of which controls
+ one of the segments. */
+
+static unsigned long
+d10v_ts2_dmap_register (int reg_nr)
+{
+ switch (reg_nr)
+ {
+ case 0:
+ case 1:
+ return 0x2000;
+ case 2:
+ return read_register (TS2_DMAP_REGNUM);
+ default:
+ return 0;
+ }
+}
+
+static unsigned long
+d10v_ts3_dmap_register (int reg_nr)
+{
+ return read_register (TS3_DMAP0_REGNUM + reg_nr);
+}
+
+static unsigned long
+d10v_dmap_register (int reg_nr)
+{
+ return gdbarch_tdep (current_gdbarch)->dmap_register (reg_nr);
+}
+
+static unsigned long
+d10v_ts2_imap_register (int reg_nr)
+{
+ return read_register (TS2_IMAP0_REGNUM + reg_nr);
+}
+
+static unsigned long
+d10v_ts3_imap_register (int reg_nr)
+{
+ return read_register (TS3_IMAP0_REGNUM + reg_nr);
+}
+
+static unsigned long
+d10v_imap_register (int reg_nr)
+{
+ return gdbarch_tdep (current_gdbarch)->imap_register (reg_nr);
+}
+
+/* MAP GDB's internal register numbering (determined by the layout fo
+ the REGISTER_BYTE array) onto the simulator's register
+ numbering. */
+
+static int
+d10v_ts2_register_sim_regno (int nr)
+{
+ if (nr >= TS2_IMAP0_REGNUM
+ && nr < TS2_IMAP0_REGNUM + NR_IMAP_REGS)
+ return nr - TS2_IMAP0_REGNUM + SIM_D10V_IMAP0_REGNUM;
+ if (nr == TS2_DMAP_REGNUM)
+ return nr - TS2_DMAP_REGNUM + SIM_D10V_TS2_DMAP_REGNUM;
+ if (nr >= TS2_A0_REGNUM
+ && nr < TS2_A0_REGNUM + NR_A_REGS)
+ return nr - TS2_A0_REGNUM + SIM_D10V_A0_REGNUM;
+ return nr;
+}
+
+static int
+d10v_ts3_register_sim_regno (int nr)
+{
+ if (nr >= TS3_IMAP0_REGNUM
+ && nr < TS3_IMAP0_REGNUM + NR_IMAP_REGS)
+ return nr - TS3_IMAP0_REGNUM + SIM_D10V_IMAP0_REGNUM;
+ if (nr >= TS3_DMAP0_REGNUM
+ && nr < TS3_DMAP0_REGNUM + TS3_NR_DMAP_REGS)
+ return nr - TS3_DMAP0_REGNUM + SIM_D10V_DMAP0_REGNUM;
+ if (nr >= TS3_A0_REGNUM
+ && nr < TS3_A0_REGNUM + NR_A_REGS)
+ return nr - TS3_A0_REGNUM + SIM_D10V_A0_REGNUM;
+ return nr;
+}
+
+/* Index within `registers' of the first byte of the space for
+ register REG_NR. */
+
+static int
+d10v_register_byte (int reg_nr)
+{
+ if (reg_nr < A0_REGNUM)
+ return (reg_nr * 2);
+ else if (reg_nr < (A0_REGNUM + NR_A_REGS))
+ return (A0_REGNUM * 2
+ + (reg_nr - A0_REGNUM) * 8);
+ else
+ return (A0_REGNUM * 2
+ + NR_A_REGS * 8
+ + (reg_nr - A0_REGNUM - NR_A_REGS) * 2);
+}
+
+/* Number of bytes of storage in the actual machine representation for
+ register REG_NR. */
+
+static int
+d10v_register_raw_size (int reg_nr)
+{
+ if (reg_nr < A0_REGNUM)
+ return 2;
+ else if (reg_nr < (A0_REGNUM + NR_A_REGS))
+ return 8;
+ else
+ return 2;
+}
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+static struct type *
+d10v_register_virtual_type (int reg_nr)
+{
+ if (reg_nr == PC_REGNUM)
+ return builtin_type_void_func_ptr;
+ else if (reg_nr >= A0_REGNUM
+ && reg_nr < (A0_REGNUM + NR_A_REGS))
+ return builtin_type_int64;
+ else
+ return builtin_type_int16;
+}
+
+static int
+d10v_daddr_p (CORE_ADDR x)
+{
+ return (((x) & 0x3000000) == DMEM_START);
+}
+
+static int
+d10v_iaddr_p (CORE_ADDR x)
+{
+ return (((x) & 0x3000000) == IMEM_START);
+}
+
+static CORE_ADDR
+d10v_make_daddr (CORE_ADDR x)
+{
+ return ((x) | DMEM_START);
+}
+
+static CORE_ADDR
+d10v_make_iaddr (CORE_ADDR x)
+{
+ if (d10v_iaddr_p (x))
+ return x; /* Idempotency -- x is already in the IMEM space. */
+ else
+ return (((x) << 2) | IMEM_START);
+}
+
+static CORE_ADDR
+d10v_convert_iaddr_to_raw (CORE_ADDR x)
+{
+ return (((x) >> 2) & 0xffff);
+}
+
+static CORE_ADDR
+d10v_convert_daddr_to_raw (CORE_ADDR x)
+{
+ return ((x) & 0xffff);
+}
+
+static void
+d10v_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr)
+{
+ /* Is it a code address? */
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
+ || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
+ {
+ store_unsigned_integer (buf, TYPE_LENGTH (type),
+ d10v_convert_iaddr_to_raw (addr));
+ }
+ else
+ {
+ /* Strip off any upper segment bits. */
+ store_unsigned_integer (buf, TYPE_LENGTH (type),
+ d10v_convert_daddr_to_raw (addr));
+ }
+}
+
+static CORE_ADDR
+d10v_pointer_to_address (struct type *type, void *buf)
+{
+ CORE_ADDR addr = extract_address (buf, TYPE_LENGTH (type));
+
+ /* Is it a code address? */
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
+ || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD
+ || TYPE_CODE_SPACE (TYPE_TARGET_TYPE (type)))
+ return d10v_make_iaddr (addr);
+ else
+ return d10v_make_daddr (addr);
+}
+
+static CORE_ADDR
+d10v_integer_to_address (struct type *type, void *buf)
+{
+ LONGEST val;
+ val = unpack_long (type, buf);
+ if (TYPE_CODE (type) == TYPE_CODE_INT
+ && TYPE_LENGTH (type) <= TYPE_LENGTH (builtin_type_void_data_ptr))
+ /* Convert small integers that would would be directly copied into
+ a pointer variable into an address pointing into data space. */
+ return d10v_make_daddr (val & 0xffff);
+ else
+ /* The value is too large to fit in a pointer. Assume this was
+ intentional and that the user in fact specified a raw address. */
+ return val;
+}
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function.
+
+ We store structs through a pointer passed in the first Argument
+ register. */
+
+static void
+d10v_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ write_register (ARG1_REGNUM, (addr));
+}
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format.
+
+ Things always get returned in RET1_REGNUM, RET2_REGNUM, ... */
+
+static void
+d10v_store_return_value (struct type *type, char *valbuf)
+{
+ write_register_bytes (REGISTER_BYTE (RET1_REGNUM),
+ valbuf,
+ TYPE_LENGTH (type));
+}
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+
+static CORE_ADDR
+d10v_extract_struct_value_address (char *regbuf)
+{
+ return (extract_address ((regbuf) + REGISTER_BYTE (ARG1_REGNUM),
+ REGISTER_RAW_SIZE (ARG1_REGNUM))
+ | DMEM_START);
+}
+
+static CORE_ADDR
+d10v_frame_saved_pc (struct frame_info *frame)
+{
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ return d10v_make_iaddr (generic_read_register_dummy (frame->pc,
+ frame->frame,
+ PC_REGNUM));
+ else
+ return ((frame)->extra_info->return_pc);
+}
+
+/* Immediately after a function call, return the saved pc. We can't
+ use frame->return_pc beause that is determined by reading R13 off
+ the stack and that may not be written yet. */
+
+static CORE_ADDR
+d10v_saved_pc_after_call (struct frame_info *frame)
+{
+ return ((read_register (LR_REGNUM) << 2)
+ | IMEM_START);
+}
+
+/* Discard from the stack the innermost frame, restoring all saved
+ registers. */
+
+static void
+d10v_pop_frame (void)
+{
+ generic_pop_current_frame (do_d10v_pop_frame);
+}
+
+static void
+do_d10v_pop_frame (struct frame_info *fi)
+{
+ CORE_ADDR fp;
+ int regnum;
+ char raw_buffer[8];
+
+ fp = FRAME_FP (fi);
+ /* fill out fsr with the address of where each */
+ /* register was stored in the frame */
+ d10v_frame_init_saved_regs (fi);
+
+ /* now update the current registers with the old values */
+ for (regnum = A0_REGNUM; regnum < A0_REGNUM + NR_A_REGS; regnum++)
+ {
+ if (fi->saved_regs[regnum])
+ {
+ read_memory (fi->saved_regs[regnum], raw_buffer, REGISTER_RAW_SIZE (regnum));
+ write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, REGISTER_RAW_SIZE (regnum));
+ }
+ }
+ for (regnum = 0; regnum < SP_REGNUM; regnum++)
+ {
+ if (fi->saved_regs[regnum])
+ {
+ write_register (regnum, read_memory_unsigned_integer (fi->saved_regs[regnum], REGISTER_RAW_SIZE (regnum)));
+ }
+ }
+ if (fi->saved_regs[PSW_REGNUM])
+ {
+ write_register (PSW_REGNUM, read_memory_unsigned_integer (fi->saved_regs[PSW_REGNUM], REGISTER_RAW_SIZE (PSW_REGNUM)));
+ }
+
+ write_register (PC_REGNUM, read_register (LR_REGNUM));
+ write_register (SP_REGNUM, fp + fi->extra_info->size);
+ target_store_registers (-1);
+ flush_cached_frames ();
+}
+
+static int
+check_prologue (unsigned short op)
+{
+ /* st rn, @-sp */
+ if ((op & 0x7E1F) == 0x6C1F)
+ return 1;
+
+ /* st2w rn, @-sp */
+ if ((op & 0x7E3F) == 0x6E1F)
+ return 1;
+
+ /* subi sp, n */
+ if ((op & 0x7FE1) == 0x01E1)
+ return 1;
+
+ /* mv r11, sp */
+ if (op == 0x417E)
+ return 1;
+
+ /* nop */
+ if (op == 0x5E00)
+ return 1;
+
+ /* st rn, @sp */
+ if ((op & 0x7E1F) == 0x681E)
+ return 1;
+
+ /* st2w rn, @sp */
+ if ((op & 0x7E3F) == 0x3A1E)
+ return 1;
+
+ return 0;
+}
+
+static CORE_ADDR
+d10v_skip_prologue (CORE_ADDR pc)
+{
+ unsigned long op;
+ unsigned short op1, op2;
+ CORE_ADDR func_addr, func_end;
+ struct symtab_and_line sal;
+
+ /* If we have line debugging information, then the end of the */
+ /* prologue should the first assembly instruction of the first source line */
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ sal = find_pc_line (func_addr, 0);
+ if (sal.end && sal.end < func_end)
+ return sal.end;
+ }
+
+ if (target_read_memory (pc, (char *) &op, 4))
+ return pc; /* Can't access it -- assume no prologue. */
+
+ while (1)
+ {
+ op = (unsigned long) read_memory_integer (pc, 4);
+ if ((op & 0xC0000000) == 0xC0000000)
+ {
+ /* long instruction */
+ if (((op & 0x3FFF0000) != 0x01FF0000) && /* add3 sp,sp,n */
+ ((op & 0x3F0F0000) != 0x340F0000) && /* st rn, @(offset,sp) */
+ ((op & 0x3F1F0000) != 0x350F0000)) /* st2w rn, @(offset,sp) */
+ break;
+ }
+ else
+ {
+ /* short instructions */
+ if ((op & 0xC0000000) == 0x80000000)
+ {
+ op2 = (op & 0x3FFF8000) >> 15;
+ op1 = op & 0x7FFF;
+ }
+ else
+ {
+ op1 = (op & 0x3FFF8000) >> 15;
+ op2 = op & 0x7FFF;
+ }
+ if (check_prologue (op1))
+ {
+ if (!check_prologue (op2))
+ {
+ /* if the previous opcode was really part of the prologue */
+ /* and not just a NOP, then we want to break after both instructions */
+ if (op1 != 0x5E00)
+ pc += 4;
+ break;
+ }
+ }
+ else
+ break;
+ }
+ pc += 4;
+ }
+ return pc;
+}
+
+/* Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+ */
+
+static CORE_ADDR
+d10v_frame_chain (struct frame_info *fi)
+{
+ CORE_ADDR addr;
+
+ /* A generic call dummy's frame is the same as caller's. */
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return fi->frame;
+
+ d10v_frame_init_saved_regs (fi);
+
+
+ if (fi->extra_info->return_pc == IMEM_START
+ || inside_entry_file (fi->extra_info->return_pc))
+ {
+ /* This is meant to halt the backtrace at "_start".
+ Make sure we don't halt it at a generic dummy frame. */
+ if (!PC_IN_CALL_DUMMY (fi->extra_info->return_pc, 0, 0))
+ return (CORE_ADDR) 0;
+ }
+
+ if (!fi->saved_regs[FP_REGNUM])
+ {
+ if (!fi->saved_regs[SP_REGNUM]
+ || fi->saved_regs[SP_REGNUM] == STACK_START)
+ return (CORE_ADDR) 0;
+
+ return fi->saved_regs[SP_REGNUM];
+ }
+
+ addr = read_memory_unsigned_integer (fi->saved_regs[FP_REGNUM],
+ REGISTER_RAW_SIZE (FP_REGNUM));
+ if (addr == 0)
+ return (CORE_ADDR) 0;
+
+ return d10v_make_daddr (addr);
+}
+
+static int next_addr, uses_frame;
+
+static int
+prologue_find_regs (unsigned short op, struct frame_info *fi, CORE_ADDR addr)
+{
+ int n;
+
+ /* st rn, @-sp */
+ if ((op & 0x7E1F) == 0x6C1F)
+ {
+ n = (op & 0x1E0) >> 5;
+ next_addr -= 2;
+ fi->saved_regs[n] = next_addr;
+ return 1;
+ }
+
+ /* st2w rn, @-sp */
+ else if ((op & 0x7E3F) == 0x6E1F)
+ {
+ n = (op & 0x1E0) >> 5;
+ next_addr -= 4;
+ fi->saved_regs[n] = next_addr;
+ fi->saved_regs[n + 1] = next_addr + 2;
+ return 1;
+ }
+
+ /* subi sp, n */
+ if ((op & 0x7FE1) == 0x01E1)
+ {
+ n = (op & 0x1E) >> 1;
+ if (n == 0)
+ n = 16;
+ next_addr -= n;
+ return 1;
+ }
+
+ /* mv r11, sp */
+ if (op == 0x417E)
+ {
+ uses_frame = 1;
+ return 1;
+ }
+
+ /* nop */
+ if (op == 0x5E00)
+ return 1;
+
+ /* st rn, @sp */
+ if ((op & 0x7E1F) == 0x681E)
+ {
+ n = (op & 0x1E0) >> 5;
+ fi->saved_regs[n] = next_addr;
+ return 1;
+ }
+
+ /* st2w rn, @sp */
+ if ((op & 0x7E3F) == 0x3A1E)
+ {
+ n = (op & 0x1E0) >> 5;
+ fi->saved_regs[n] = next_addr;
+ fi->saved_regs[n + 1] = next_addr + 2;
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Put here the code to store, into fi->saved_regs, the addresses of
+ the saved registers of frame described by FRAME_INFO. This
+ includes special registers such as pc and fp saved in special ways
+ in the stack frame. sp is even more special: the address we return
+ for it IS the sp for the next frame. */
+
+static void
+d10v_frame_init_saved_regs (struct frame_info *fi)
+{
+ CORE_ADDR fp, pc;
+ unsigned long op;
+ unsigned short op1, op2;
+ int i;
+
+ fp = fi->frame;
+ memset (fi->saved_regs, 0, SIZEOF_FRAME_SAVED_REGS);
+ next_addr = 0;
+
+ pc = get_pc_function_start (fi->pc);
+
+ uses_frame = 0;
+ while (1)
+ {
+ op = (unsigned long) read_memory_integer (pc, 4);
+ if ((op & 0xC0000000) == 0xC0000000)
+ {
+ /* long instruction */
+ if ((op & 0x3FFF0000) == 0x01FF0000)
+ {
+ /* add3 sp,sp,n */
+ short n = op & 0xFFFF;
+ next_addr += n;
+ }
+ else if ((op & 0x3F0F0000) == 0x340F0000)
+ {
+ /* st rn, @(offset,sp) */
+ short offset = op & 0xFFFF;
+ short n = (op >> 20) & 0xF;
+ fi->saved_regs[n] = next_addr + offset;
+ }
+ else if ((op & 0x3F1F0000) == 0x350F0000)
+ {
+ /* st2w rn, @(offset,sp) */
+ short offset = op & 0xFFFF;
+ short n = (op >> 20) & 0xF;
+ fi->saved_regs[n] = next_addr + offset;
+ fi->saved_regs[n + 1] = next_addr + offset + 2;
+ }
+ else
+ break;
+ }
+ else
+ {
+ /* short instructions */
+ if ((op & 0xC0000000) == 0x80000000)
+ {
+ op2 = (op & 0x3FFF8000) >> 15;
+ op1 = op & 0x7FFF;
+ }
+ else
+ {
+ op1 = (op & 0x3FFF8000) >> 15;
+ op2 = op & 0x7FFF;
+ }
+ if (!prologue_find_regs (op1, fi, pc)
+ || !prologue_find_regs (op2, fi, pc))
+ break;
+ }
+ pc += 4;
+ }
+
+ fi->extra_info->size = -next_addr;
+
+ if (!(fp & 0xffff))
+ fp = d10v_make_daddr (read_register (SP_REGNUM));
+
+ for (i = 0; i < NUM_REGS - 1; i++)
+ if (fi->saved_regs[i])
+ {
+ fi->saved_regs[i] = fp - (next_addr - fi->saved_regs[i]);
+ }
+
+ if (fi->saved_regs[LR_REGNUM])
+ {
+ CORE_ADDR return_pc
+ = read_memory_unsigned_integer (fi->saved_regs[LR_REGNUM],
+ REGISTER_RAW_SIZE (LR_REGNUM));
+ fi->extra_info->return_pc = d10v_make_iaddr (return_pc);
+ }
+ else
+ {
+ fi->extra_info->return_pc = d10v_make_iaddr (read_register (LR_REGNUM));
+ }
+
+ /* The SP is not normally (ever?) saved, but check anyway */
+ if (!fi->saved_regs[SP_REGNUM])
+ {
+ /* if the FP was saved, that means the current FP is valid, */
+ /* otherwise, it isn't being used, so we use the SP instead */
+ if (uses_frame)
+ fi->saved_regs[SP_REGNUM]
+ = read_register (FP_REGNUM) + fi->extra_info->size;
+ else
+ {
+ fi->saved_regs[SP_REGNUM] = fp + fi->extra_info->size;
+ fi->extra_info->frameless = 1;
+ fi->saved_regs[FP_REGNUM] = 0;
+ }
+ }
+}
+
+static void
+d10v_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ fi->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+ frame_saved_regs_zalloc (fi);
+
+ fi->extra_info->frameless = 0;
+ fi->extra_info->size = 0;
+ fi->extra_info->return_pc = 0;
+
+ /* If fi->pc is zero, but this is not the outermost frame,
+ then let's snatch the return_pc from the callee, so that
+ PC_IN_CALL_DUMMY will work. */
+ if (fi->pc == 0 && fi->level != 0 && fi->next != NULL)
+ fi->pc = d10v_frame_saved_pc (fi->next);
+
+ /* The call dummy doesn't save any registers on the stack, so we can
+ return now. */
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ return;
+ }
+ else
+ {
+ d10v_frame_init_saved_regs (fi);
+ }
+}
+
+static void
+show_regs (char *args, int from_tty)
+{
+ int a;
+ printf_filtered ("PC=%04lx (0x%lx) PSW=%04lx RPT_S=%04lx RPT_E=%04lx RPT_C=%04lx\n",
+ (long) read_register (PC_REGNUM),
+ (long) d10v_make_iaddr (read_register (PC_REGNUM)),
+ (long) read_register (PSW_REGNUM),
+ (long) read_register (24),
+ (long) read_register (25),
+ (long) read_register (23));
+ printf_filtered ("R0-R7 %04lx %04lx %04lx %04lx %04lx %04lx %04lx %04lx\n",
+ (long) read_register (0),
+ (long) read_register (1),
+ (long) read_register (2),
+ (long) read_register (3),
+ (long) read_register (4),
+ (long) read_register (5),
+ (long) read_register (6),
+ (long) read_register (7));
+ printf_filtered ("R8-R15 %04lx %04lx %04lx %04lx %04lx %04lx %04lx %04lx\n",
+ (long) read_register (8),
+ (long) read_register (9),
+ (long) read_register (10),
+ (long) read_register (11),
+ (long) read_register (12),
+ (long) read_register (13),
+ (long) read_register (14),
+ (long) read_register (15));
+ for (a = 0; a < NR_IMAP_REGS; a++)
+ {
+ if (a > 0)
+ printf_filtered (" ");
+ printf_filtered ("IMAP%d %04lx", a, d10v_imap_register (a));
+ }
+ if (NR_DMAP_REGS == 1)
+ printf_filtered (" DMAP %04lx\n", d10v_dmap_register (2));
+ else
+ {
+ for (a = 0; a < NR_DMAP_REGS; a++)
+ {
+ printf_filtered (" DMAP%d %04lx", a, d10v_dmap_register (a));
+ }
+ printf_filtered ("\n");
+ }
+ printf_filtered ("A0-A%d", NR_A_REGS - 1);
+ for (a = A0_REGNUM; a < A0_REGNUM + NR_A_REGS; a++)
+ {
+ char num[MAX_REGISTER_RAW_SIZE];
+ int i;
+ printf_filtered (" ");
+ read_register_gen (a, (char *) &num);
+ for (i = 0; i < MAX_REGISTER_RAW_SIZE; i++)
+ {
+ printf_filtered ("%02x", (num[i] & 0xff));
+ }
+ }
+ printf_filtered ("\n");
+}
+
+static CORE_ADDR
+d10v_read_pc (ptid_t ptid)
+{
+ ptid_t save_ptid;
+ CORE_ADDR pc;
+ CORE_ADDR retval;
+
+ save_ptid = inferior_ptid;
+ inferior_ptid = ptid;
+ pc = (int) read_register (PC_REGNUM);
+ inferior_ptid = save_ptid;
+ retval = d10v_make_iaddr (pc);
+ return retval;
+}
+
+static void
+d10v_write_pc (CORE_ADDR val, ptid_t ptid)
+{
+ ptid_t save_ptid;
+
+ save_ptid = inferior_ptid;
+ inferior_ptid = ptid;
+ write_register (PC_REGNUM, d10v_convert_iaddr_to_raw (val));
+ inferior_ptid = save_ptid;
+}
+
+static CORE_ADDR
+d10v_read_sp (void)
+{
+ return (d10v_make_daddr (read_register (SP_REGNUM)));
+}
+
+static void
+d10v_write_sp (CORE_ADDR val)
+{
+ write_register (SP_REGNUM, d10v_convert_daddr_to_raw (val));
+}
+
+static CORE_ADDR
+d10v_read_fp (void)
+{
+ return (d10v_make_daddr (read_register (FP_REGNUM)));
+}
+
+/* Function: push_return_address (pc)
+ Set up the return address for the inferior function call.
+ Needed for targets where we don't actually execute a JSR/BSR instruction */
+
+static CORE_ADDR
+d10v_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ write_register (LR_REGNUM, d10v_convert_iaddr_to_raw (CALL_DUMMY_ADDRESS ()));
+ return sp;
+}
+
+
+/* When arguments must be pushed onto the stack, they go on in reverse
+ order. The below implements a FILO (stack) to do this. */
+
+struct stack_item
+{
+ int len;
+ struct stack_item *prev;
+ void *data;
+};
+
+static struct stack_item *push_stack_item (struct stack_item *prev,
+ void *contents, int len);
+static struct stack_item *
+push_stack_item (struct stack_item *prev, void *contents, int len)
+{
+ struct stack_item *si;
+ si = xmalloc (sizeof (struct stack_item));
+ si->data = xmalloc (len);
+ si->len = len;
+ si->prev = prev;
+ memcpy (si->data, contents, len);
+ return si;
+}
+
+static struct stack_item *pop_stack_item (struct stack_item *si);
+static struct stack_item *
+pop_stack_item (struct stack_item *si)
+{
+ struct stack_item *dead = si;
+ si = si->prev;
+ xfree (dead->data);
+ xfree (dead);
+ return si;
+}
+
+
+static CORE_ADDR
+d10v_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int i;
+ int regnum = ARG1_REGNUM;
+ struct stack_item *si = NULL;
+
+ /* Fill in registers and arg lists */
+ for (i = 0; i < nargs; i++)
+ {
+ struct value *arg = args[i];
+ struct type *type = check_typedef (VALUE_TYPE (arg));
+ char *contents = VALUE_CONTENTS (arg);
+ int len = TYPE_LENGTH (type);
+ /* printf ("push: type=%d len=%d\n", TYPE_CODE (type), len); */
+ {
+ int aligned_regnum = (regnum + 1) & ~1;
+ if (len <= 2 && regnum <= ARGN_REGNUM)
+ /* fits in a single register, do not align */
+ {
+ long val = extract_unsigned_integer (contents, len);
+ write_register (regnum++, val);
+ }
+ else if (len <= (ARGN_REGNUM - aligned_regnum + 1) * 2)
+ /* value fits in remaining registers, store keeping left
+ aligned */
+ {
+ int b;
+ regnum = aligned_regnum;
+ for (b = 0; b < (len & ~1); b += 2)
+ {
+ long val = extract_unsigned_integer (&contents[b], 2);
+ write_register (regnum++, val);
+ }
+ if (b < len)
+ {
+ long val = extract_unsigned_integer (&contents[b], 1);
+ write_register (regnum++, (val << 8));
+ }
+ }
+ else
+ {
+ /* arg will go onto stack */
+ regnum = ARGN_REGNUM + 1;
+ si = push_stack_item (si, contents, len);
+ }
+ }
+ }
+
+ while (si)
+ {
+ sp = (sp - si->len) & ~1;
+ write_memory (sp, si->data, si->len);
+ si = pop_stack_item (si);
+ }
+
+ return sp;
+}
+
+
+/* Given a return value in `regbuf' with a type `valtype',
+ extract and copy its value into `valbuf'. */
+
+static void
+d10v_extract_return_value (struct type *type, char regbuf[REGISTER_BYTES],
+ char *valbuf)
+{
+ int len;
+ /* printf("RET: TYPE=%d len=%d r%d=0x%x\n", TYPE_CODE (type), TYPE_LENGTH (type), RET1_REGNUM - R0_REGNUM, (int) extract_unsigned_integer (regbuf + REGISTER_BYTE(RET1_REGNUM), REGISTER_RAW_SIZE (RET1_REGNUM))); */
+ {
+ len = TYPE_LENGTH (type);
+ if (len == 1)
+ {
+ unsigned short c = extract_unsigned_integer (regbuf + REGISTER_BYTE (RET1_REGNUM), REGISTER_RAW_SIZE (RET1_REGNUM));
+ store_unsigned_integer (valbuf, 1, c);
+ }
+ else if ((len & 1) == 0)
+ memcpy (valbuf, regbuf + REGISTER_BYTE (RET1_REGNUM), len);
+ else
+ {
+ /* For return values of odd size, the first byte is in the
+ least significant part of the first register. The
+ remaining bytes in remaining registers. Interestingly,
+ when such values are passed in, the last byte is in the
+ most significant byte of that same register - wierd. */
+ memcpy (valbuf, regbuf + REGISTER_BYTE (RET1_REGNUM) + 1, len);
+ }
+ }
+}
+
+/* Translate a GDB virtual ADDR/LEN into a format the remote target
+ understands. Returns number of bytes that can be transfered
+ starting at TARG_ADDR. Return ZERO if no bytes can be transfered
+ (segmentation fault). Since the simulator knows all about how the
+ VM system works, we just call that to do the translation. */
+
+static void
+remote_d10v_translate_xfer_address (CORE_ADDR memaddr, int nr_bytes,
+ CORE_ADDR *targ_addr, int *targ_len)
+{
+ long out_addr;
+ long out_len;
+ out_len = sim_d10v_translate_addr (memaddr, nr_bytes,
+ &out_addr,
+ d10v_dmap_register,
+ d10v_imap_register);
+ *targ_addr = out_addr;
+ *targ_len = out_len;
+}
+
+
+/* The following code implements access to, and display of, the D10V's
+ instruction trace buffer. The buffer consists of 64K or more
+ 4-byte words of data, of which each words includes an 8-bit count,
+ an 8-bit segment number, and a 16-bit instruction address.
+
+ In theory, the trace buffer is continuously capturing instruction
+ data that the CPU presents on its "debug bus", but in practice, the
+ ROMified GDB stub only enables tracing when it continues or steps
+ the program, and stops tracing when the program stops; so it
+ actually works for GDB to read the buffer counter out of memory and
+ then read each trace word. The counter records where the tracing
+ stops, but there is no record of where it started, so we remember
+ the PC when we resumed and then search backwards in the trace
+ buffer for a word that includes that address. This is not perfect,
+ because you will miss trace data if the resumption PC is the target
+ of a branch. (The value of the buffer counter is semi-random, any
+ trace data from a previous program stop is gone.) */
+
+/* The address of the last word recorded in the trace buffer. */
+
+#define DBBC_ADDR (0xd80000)
+
+/* The base of the trace buffer, at least for the "Board_0". */
+
+#define TRACE_BUFFER_BASE (0xf40000)
+
+static void trace_command (char *, int);
+
+static void untrace_command (char *, int);
+
+static void trace_info (char *, int);
+
+static void tdisassemble_command (char *, int);
+
+static void display_trace (int, int);
+
+/* True when instruction traces are being collected. */
+
+static int tracing;
+
+/* Remembered PC. */
+
+static CORE_ADDR last_pc;
+
+/* True when trace output should be displayed whenever program stops. */
+
+static int trace_display;
+
+/* True when trace listing should include source lines. */
+
+static int default_trace_show_source = 1;
+
+struct trace_buffer
+ {
+ int size;
+ short *counts;
+ CORE_ADDR *addrs;
+ }
+trace_data;
+
+static void
+trace_command (char *args, int from_tty)
+{
+ /* Clear the host-side trace buffer, allocating space if needed. */
+ trace_data.size = 0;
+ if (trace_data.counts == NULL)
+ trace_data.counts = (short *) xmalloc (65536 * sizeof (short));
+ if (trace_data.addrs == NULL)
+ trace_data.addrs = (CORE_ADDR *) xmalloc (65536 * sizeof (CORE_ADDR));
+
+ tracing = 1;
+
+ printf_filtered ("Tracing is now on.\n");
+}
+
+static void
+untrace_command (char *args, int from_tty)
+{
+ tracing = 0;
+
+ printf_filtered ("Tracing is now off.\n");
+}
+
+static void
+trace_info (char *args, int from_tty)
+{
+ int i;
+
+ if (trace_data.size)
+ {
+ printf_filtered ("%d entries in trace buffer:\n", trace_data.size);
+
+ for (i = 0; i < trace_data.size; ++i)
+ {
+ printf_filtered ("%d: %d instruction%s at 0x%s\n",
+ i,
+ trace_data.counts[i],
+ (trace_data.counts[i] == 1 ? "" : "s"),
+ paddr_nz (trace_data.addrs[i]));
+ }
+ }
+ else
+ printf_filtered ("No entries in trace buffer.\n");
+
+ printf_filtered ("Tracing is currently %s.\n", (tracing ? "on" : "off"));
+}
+
+/* Print the instruction at address MEMADDR in debugged memory,
+ on STREAM. Returns length of the instruction, in bytes. */
+
+static int
+print_insn (CORE_ADDR memaddr, struct ui_file *stream)
+{
+ /* If there's no disassembler, something is very wrong. */
+ if (tm_print_insn == NULL)
+ internal_error (__FILE__, __LINE__,
+ "print_insn: no disassembler");
+
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ tm_print_insn_info.endian = BFD_ENDIAN_BIG;
+ else
+ tm_print_insn_info.endian = BFD_ENDIAN_LITTLE;
+ return TARGET_PRINT_INSN (memaddr, &tm_print_insn_info);
+}
+
+static void
+d10v_eva_prepare_to_trace (void)
+{
+ if (!tracing)
+ return;
+
+ last_pc = read_register (PC_REGNUM);
+}
+
+/* Collect trace data from the target board and format it into a form
+ more useful for display. */
+
+static void
+d10v_eva_get_trace_data (void)
+{
+ int count, i, j, oldsize;
+ int trace_addr, trace_seg, trace_cnt, next_cnt;
+ unsigned int last_trace, trace_word, next_word;
+ unsigned int *tmpspace;
+
+ if (!tracing)
+ return;
+
+ tmpspace = xmalloc (65536 * sizeof (unsigned int));
+
+ last_trace = read_memory_unsigned_integer (DBBC_ADDR, 2) << 2;
+
+ /* Collect buffer contents from the target, stopping when we reach
+ the word recorded when execution resumed. */
+
+ count = 0;
+ while (last_trace > 0)
+ {
+ QUIT;
+ trace_word =
+ read_memory_unsigned_integer (TRACE_BUFFER_BASE + last_trace, 4);
+ trace_addr = trace_word & 0xffff;
+ last_trace -= 4;
+ /* Ignore an apparently nonsensical entry. */
+ if (trace_addr == 0xffd5)
+ continue;
+ tmpspace[count++] = trace_word;
+ if (trace_addr == last_pc)
+ break;
+ if (count > 65535)
+ break;
+ }
+
+ /* Move the data to the host-side trace buffer, adjusting counts to
+ include the last instruction executed and transforming the address
+ into something that GDB likes. */
+
+ for (i = 0; i < count; ++i)
+ {
+ trace_word = tmpspace[i];
+ next_word = ((i == 0) ? 0 : tmpspace[i - 1]);
+ trace_addr = trace_word & 0xffff;
+ next_cnt = (next_word >> 24) & 0xff;
+ j = trace_data.size + count - i - 1;
+ trace_data.addrs[j] = (trace_addr << 2) + 0x1000000;
+ trace_data.counts[j] = next_cnt + 1;
+ }
+
+ oldsize = trace_data.size;
+ trace_data.size += count;
+
+ xfree (tmpspace);
+
+ if (trace_display)
+ display_trace (oldsize, trace_data.size);
+}
+
+static void
+tdisassemble_command (char *arg, int from_tty)
+{
+ int i, count;
+ CORE_ADDR low, high;
+ char *space_index;
+
+ if (!arg)
+ {
+ low = 0;
+ high = trace_data.size;
+ }
+ else if (!(space_index = (char *) strchr (arg, ' ')))
+ {
+ low = parse_and_eval_address (arg);
+ high = low + 5;
+ }
+ else
+ {
+ /* Two arguments. */
+ *space_index = '\0';
+ low = parse_and_eval_address (arg);
+ high = parse_and_eval_address (space_index + 1);
+ if (high < low)
+ high = low;
+ }
+
+ printf_filtered ("Dump of trace from %s to %s:\n", paddr_u (low), paddr_u (high));
+
+ display_trace (low, high);
+
+ printf_filtered ("End of trace dump.\n");
+ gdb_flush (gdb_stdout);
+}
+
+static void
+display_trace (int low, int high)
+{
+ int i, count, trace_show_source, first, suppress;
+ CORE_ADDR next_address;
+
+ trace_show_source = default_trace_show_source;
+ if (!have_full_symbols () && !have_partial_symbols ())
+ {
+ trace_show_source = 0;
+ printf_filtered ("No symbol table is loaded. Use the \"file\" command.\n");
+ printf_filtered ("Trace will not display any source.\n");
+ }
+
+ first = 1;
+ suppress = 0;
+ for (i = low; i < high; ++i)
+ {
+ next_address = trace_data.addrs[i];
+ count = trace_data.counts[i];
+ while (count-- > 0)
+ {
+ QUIT;
+ if (trace_show_source)
+ {
+ struct symtab_and_line sal, sal_prev;
+
+ sal_prev = find_pc_line (next_address - 4, 0);
+ sal = find_pc_line (next_address, 0);
+
+ if (sal.symtab)
+ {
+ if (first || sal.line != sal_prev.line)
+ print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
+ suppress = 0;
+ }
+ else
+ {
+ if (!suppress)
+ /* FIXME-32x64--assumes sal.pc fits in long. */
+ printf_filtered ("No source file for address %s.\n",
+ local_hex_string ((unsigned long) sal.pc));
+ suppress = 1;
+ }
+ }
+ first = 0;
+ print_address (next_address, gdb_stdout);
+ printf_filtered (":");
+ printf_filtered ("\t");
+ wrap_here (" ");
+ next_address = next_address + print_insn (next_address, gdb_stdout);
+ printf_filtered ("\n");
+ gdb_flush (gdb_stdout);
+ }
+ }
+}
+
+
+static gdbarch_init_ftype d10v_gdbarch_init;
+
+static struct gdbarch *
+d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ static LONGEST d10v_call_dummy_words[] =
+ {0};
+ struct gdbarch *gdbarch;
+ int d10v_num_regs;
+ struct gdbarch_tdep *tdep;
+ gdbarch_register_name_ftype *d10v_register_name;
+ gdbarch_register_sim_regno_ftype *d10v_register_sim_regno;
+
+ /* Find a candidate among the list of pre-declared architectures. */
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+ if (arches != NULL)
+ return arches->gdbarch;
+
+ /* None found, create a new architecture from the information
+ provided. */
+ tdep = XMALLOC (struct gdbarch_tdep);
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ switch (info.bfd_arch_info->mach)
+ {
+ case bfd_mach_d10v_ts2:
+ d10v_num_regs = 37;
+ d10v_register_name = d10v_ts2_register_name;
+ d10v_register_sim_regno = d10v_ts2_register_sim_regno;
+ tdep->a0_regnum = TS2_A0_REGNUM;
+ tdep->nr_dmap_regs = TS2_NR_DMAP_REGS;
+ tdep->dmap_register = d10v_ts2_dmap_register;
+ tdep->imap_register = d10v_ts2_imap_register;
+ break;
+ default:
+ case bfd_mach_d10v_ts3:
+ d10v_num_regs = 42;
+ d10v_register_name = d10v_ts3_register_name;
+ d10v_register_sim_regno = d10v_ts3_register_sim_regno;
+ tdep->a0_regnum = TS3_A0_REGNUM;
+ tdep->nr_dmap_regs = TS3_NR_DMAP_REGS;
+ tdep->dmap_register = d10v_ts3_dmap_register;
+ tdep->imap_register = d10v_ts3_imap_register;
+ break;
+ }
+
+ set_gdbarch_read_pc (gdbarch, d10v_read_pc);
+ set_gdbarch_write_pc (gdbarch, d10v_write_pc);
+ set_gdbarch_read_fp (gdbarch, d10v_read_fp);
+ set_gdbarch_read_sp (gdbarch, d10v_read_sp);
+ set_gdbarch_write_sp (gdbarch, d10v_write_sp);
+
+ set_gdbarch_num_regs (gdbarch, d10v_num_regs);
+ set_gdbarch_sp_regnum (gdbarch, 15);
+ set_gdbarch_fp_regnum (gdbarch, 11);
+ set_gdbarch_pc_regnum (gdbarch, 18);
+ set_gdbarch_register_name (gdbarch, d10v_register_name);
+ set_gdbarch_register_size (gdbarch, 2);
+ set_gdbarch_register_bytes (gdbarch, (d10v_num_regs - 2) * 2 + 16);
+ set_gdbarch_register_byte (gdbarch, d10v_register_byte);
+ set_gdbarch_register_raw_size (gdbarch, d10v_register_raw_size);
+ set_gdbarch_max_register_raw_size (gdbarch, 8);
+ set_gdbarch_register_virtual_size (gdbarch, generic_register_size);
+ set_gdbarch_max_register_virtual_size (gdbarch, 8);
+ set_gdbarch_register_virtual_type (gdbarch, d10v_register_virtual_type);
+
+ set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_addr_bit (gdbarch, 32);
+ set_gdbarch_address_to_pointer (gdbarch, d10v_address_to_pointer);
+ set_gdbarch_pointer_to_address (gdbarch, d10v_pointer_to_address);
+ set_gdbarch_integer_to_address (gdbarch, d10v_integer_to_address);
+ set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+ /* NOTE: The d10v as a 32 bit ``float'' and ``double''. ``long
+ double'' is 64 bits. */
+ set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+ switch (info.byte_order)
+ {
+ case BFD_ENDIAN_BIG:
+ set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big);
+ set_gdbarch_double_format (gdbarch, &floatformat_ieee_single_big);
+ set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);
+ break;
+ case BFD_ENDIAN_LITTLE:
+ set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
+ set_gdbarch_double_format (gdbarch, &floatformat_ieee_single_little);
+ set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_little);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "d10v_gdbarch_init: bad byte order for float format");
+ }
+
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
+ set_gdbarch_call_dummy_words (gdbarch, d10v_call_dummy_words);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (d10v_call_dummy_words));
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+ set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
+
+ set_gdbarch_extract_return_value (gdbarch, d10v_extract_return_value);
+ set_gdbarch_push_arguments (gdbarch, d10v_push_arguments);
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+ set_gdbarch_push_return_address (gdbarch, d10v_push_return_address);
+
+ set_gdbarch_store_struct_return (gdbarch, d10v_store_struct_return);
+ set_gdbarch_store_return_value (gdbarch, d10v_store_return_value);
+ set_gdbarch_extract_struct_value_address (gdbarch, d10v_extract_struct_value_address);
+ set_gdbarch_use_struct_convention (gdbarch, d10v_use_struct_convention);
+
+ set_gdbarch_frame_init_saved_regs (gdbarch, d10v_frame_init_saved_regs);
+ set_gdbarch_init_extra_frame_info (gdbarch, d10v_init_extra_frame_info);
+
+ set_gdbarch_pop_frame (gdbarch, d10v_pop_frame);
+
+ set_gdbarch_skip_prologue (gdbarch, d10v_skip_prologue);
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+ set_gdbarch_decr_pc_after_break (gdbarch, 4);
+ set_gdbarch_function_start_offset (gdbarch, 0);
+ set_gdbarch_breakpoint_from_pc (gdbarch, d10v_breakpoint_from_pc);
+
+ set_gdbarch_remote_translate_xfer_address (gdbarch, remote_d10v_translate_xfer_address);
+
+ set_gdbarch_frame_args_skip (gdbarch, 0);
+ set_gdbarch_frameless_function_invocation (gdbarch, frameless_look_for_prologue);
+ set_gdbarch_frame_chain (gdbarch, d10v_frame_chain);
+ set_gdbarch_frame_chain_valid (gdbarch, d10v_frame_chain_valid);
+ set_gdbarch_frame_saved_pc (gdbarch, d10v_frame_saved_pc);
+ set_gdbarch_frame_args_address (gdbarch, default_frame_address);
+ set_gdbarch_frame_locals_address (gdbarch, default_frame_address);
+ set_gdbarch_saved_pc_after_call (gdbarch, d10v_saved_pc_after_call);
+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+ set_gdbarch_stack_align (gdbarch, d10v_stack_align);
+
+ set_gdbarch_register_sim_regno (gdbarch, d10v_register_sim_regno);
+ set_gdbarch_extra_stack_alignment_needed (gdbarch, 0);
+
+ return gdbarch;
+}
+
+
+extern void (*target_resume_hook) (void);
+extern void (*target_wait_loop_hook) (void);
+
+void
+_initialize_d10v_tdep (void)
+{
+ register_gdbarch_init (bfd_arch_d10v, d10v_gdbarch_init);
+
+ tm_print_insn = print_insn_d10v;
+
+ target_resume_hook = d10v_eva_prepare_to_trace;
+ target_wait_loop_hook = d10v_eva_get_trace_data;
+
+ add_com ("regs", class_vars, show_regs, "Print all registers");
+
+ add_com ("itrace", class_support, trace_command,
+ "Enable tracing of instruction execution.");
+
+ add_com ("iuntrace", class_support, untrace_command,
+ "Disable tracing of instruction execution.");
+
+ add_com ("itdisassemble", class_vars, tdisassemble_command,
+ "Disassemble the trace buffer.\n\
+Two optional arguments specify a range of trace buffer entries\n\
+as reported by info trace (NOT addresses!).");
+
+ add_info ("itrace", trace_info,
+ "Display info about the trace data buffer.");
+
+ add_show_from_set (add_set_cmd ("itracedisplay", no_class,
+ var_integer, (char *) &trace_display,
+ "Set automatic display of trace.\n", &setlist),
+ &showlist);
+ add_show_from_set (add_set_cmd ("itracesource", no_class,
+ var_integer, (char *) &default_trace_show_source,
+ "Set display of source code with trace.\n", &setlist),
+ &showlist);
+
+}
diff --git a/gdb/d30v-tdep.c b/gdb/d30v-tdep.c
new file mode 100644
index 00000000000..b5d3a3b4b93
--- /dev/null
+++ b/gdb/d30v-tdep.c
@@ -0,0 +1,1365 @@
+/* Target-dependent code for Mitsubishi D30V, for GDB.
+
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 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. */
+
+/* Contributed by Martin Hunt, hunt@cygnus.com */
+
+#include "defs.h"
+#include "frame.h"
+#include "obstack.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "gdb_string.h"
+#include "value.h"
+#include "inferior.h"
+#include "dis-asm.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "regcache.h"
+
+#include "language.h" /* For local_hex_string() */
+
+void d30v_frame_find_saved_regs (struct frame_info *fi,
+ struct frame_saved_regs *fsr);
+void d30v_frame_find_saved_regs_offsets (struct frame_info *fi,
+ struct frame_saved_regs *fsr);
+static void d30v_pop_dummy_frame (struct frame_info *fi);
+static void d30v_print_flags (void);
+static void print_flags_command (char *, int);
+
+/* the following defines assume:
+ fp is r61, lr is r62, sp is r63, and ?? is r22
+ if that changes, they will need to be updated */
+
+#define OP_MASK_ALL_BUT_RA 0x0ffc0fff /* throw away Ra, keep the rest */
+
+#define OP_STW_SPM 0x054c0fc0 /* stw Ra, @(sp-) */
+#define OP_STW_SP_R0 0x05400fc0 /* stw Ra, @(sp,r0) */
+#define OP_STW_SP_IMM0 0x05480fc0 /* st Ra, @(sp, 0x0) */
+#define OP_STW_R22P_R0 0x05440580 /* stw Ra, @(r22+,r0) */
+
+#define OP_ST2W_SPM 0x056c0fc0 /* st2w Ra, @(sp-) */
+#define OP_ST2W_SP_R0 0x05600fc0 /* st2w Ra, @(sp, r0) */
+#define OP_ST2W_SP_IMM0 0x05680fc0 /* st2w Ra, @(sp, 0x0) */
+#define OP_ST2W_R22P_R0 0x05640580 /* st2w Ra, @(r22+, r0) */
+
+#define OP_MASK_OPCODE 0x0ffc0000 /* just the opcode, ign operands */
+#define OP_NOP 0x00f00000 /* nop */
+
+#define OP_MASK_ALL_BUT_IMM 0x0fffffc0 /* throw away imm, keep the rest */
+#define OP_SUB_SP_IMM 0x082bffc0 /* sub sp,sp,imm */
+#define OP_ADD_SP_IMM 0x080bffc0 /* add sp,sp,imm */
+#define OP_ADD_R22_SP_IMM 0x08096fc0 /* add r22,sp,imm */
+#define OP_STW_FP_SP_IMM 0x054bdfc0 /* stw fp,@(sp,imm) */
+#define OP_OR_SP_R0_IMM 0x03abf000 /* or sp,r0,imm */
+
+/* no mask */
+#define OP_OR_FP_R0_SP 0x03a3d03f /* or fp,r0,sp */
+#define OP_OR_FP_SP_R0 0x03a3dfc0 /* or fp,sp,r0 */
+#define OP_OR_FP_IMM0_SP 0x03abd03f /* or fp,0x0,sp */
+#define OP_STW_FP_R22P_R0 0x0547d580 /* stw fp,@(r22+,r0) */
+#define OP_STW_LR_R22P_R0 0x0547e580 /* stw lr,@(r22+,r0) */
+
+#define OP_MASK_OP_AND_RB 0x0ff80fc0 /* keep op and rb,throw away rest */
+#define OP_STW_SP_IMM 0x05480fc0 /* stw Ra,@(sp,imm) */
+#define OP_ST2W_SP_IMM 0x05680fc0 /* st2w Ra,@(sp,imm) */
+#define OP_STW_FP_IMM 0x05480f40 /* stw Ra,@(fp,imm) */
+#define OP_STW_FP_R0 0x05400f40 /* stw Ra,@(fp,r0) */
+
+#define OP_MASK_FM_BIT 0x80000000
+#define OP_MASK_CC_BITS 0x70000000
+#define OP_MASK_SUB_INST 0x0fffffff
+
+#define EXTRACT_RA(op) (((op) >> 12) & 0x3f)
+#define EXTRACT_RB(op) (((op) >> 6) & 0x3f)
+#define EXTRACT_RC(op) (((op) & 0x3f)
+#define EXTRACT_UIMM6(op) ((op) & 0x3f)
+#define EXTRACT_IMM6(op) ((((int)EXTRACT_UIMM6(op)) << 26) >> 26)
+#define EXTRACT_IMM26(op) ((((op)&0x0ff00000) >> 2) | ((op)&0x0003ffff))
+#define EXTRACT_IMM32(opl, opr) ((EXTRACT_UIMM6(opl) << 26)|EXTRACT_IMM26(opr))
+
+
+int
+d30v_frame_chain_valid (CORE_ADDR chain, struct frame_info *fi)
+{
+#if 0
+ return ((chain) != 0 && (fi) != 0 && (fi)->return_pc != 0);
+#else
+ return ((chain) != 0 && (fi) != 0 && (fi)->frame <= chain);
+#endif
+}
+
+/* Discard from the stack the innermost frame, restoring all saved
+ registers. */
+
+void
+d30v_pop_frame (void)
+{
+ struct frame_info *frame = get_current_frame ();
+ CORE_ADDR fp;
+ int regnum;
+ struct frame_saved_regs fsr;
+ char raw_buffer[8];
+
+ fp = FRAME_FP (frame);
+ if (frame->dummy)
+ {
+ d30v_pop_dummy_frame (frame);
+ return;
+ }
+
+ /* fill out fsr with the address of where each */
+ /* register was stored in the frame */
+ get_frame_saved_regs (frame, &fsr);
+
+ /* now update the current registers with the old values */
+ for (regnum = A0_REGNUM; regnum < A0_REGNUM + 2; regnum++)
+ {
+ if (fsr.regs[regnum])
+ {
+ read_memory (fsr.regs[regnum], raw_buffer, 8);
+ write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 8);
+ }
+ }
+ for (regnum = 0; regnum < SP_REGNUM; regnum++)
+ {
+ if (fsr.regs[regnum])
+ {
+ write_register (regnum, read_memory_unsigned_integer (fsr.regs[regnum], 4));
+ }
+ }
+ if (fsr.regs[PSW_REGNUM])
+ {
+ write_register (PSW_REGNUM, read_memory_unsigned_integer (fsr.regs[PSW_REGNUM], 4));
+ }
+
+ write_register (PC_REGNUM, read_register (LR_REGNUM));
+ write_register (SP_REGNUM, fp + frame->size);
+ target_store_registers (-1);
+ flush_cached_frames ();
+}
+
+static int
+check_prologue (unsigned long op)
+{
+ /* add sp,sp,imm -- observed */
+ if ((op & OP_MASK_ALL_BUT_IMM) == OP_ADD_SP_IMM)
+ return 1;
+
+ /* add r22,sp,imm -- observed */
+ if ((op & OP_MASK_ALL_BUT_IMM) == OP_ADD_R22_SP_IMM)
+ return 1;
+
+ /* or fp,r0,sp -- observed */
+ if (op == OP_OR_FP_R0_SP)
+ return 1;
+
+ /* nop */
+ if ((op & OP_MASK_OPCODE) == OP_NOP)
+ return 1;
+
+ /* stw Ra,@(sp,r0) */
+ if ((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_R0)
+ return 1;
+
+ /* stw Ra,@(sp,0x0) */
+ if ((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_IMM0)
+ return 1;
+
+ /* st2w Ra,@(sp,r0) */
+ if ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SP_R0)
+ return 1;
+
+ /* st2w Ra,@(sp,0x0) */
+ if ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SP_IMM0)
+ return 1;
+
+ /* stw fp, @(r22+,r0) -- observed */
+ if (op == OP_STW_FP_R22P_R0)
+ return 1;
+
+ /* stw r62, @(r22+,r0) -- observed */
+ if (op == OP_STW_LR_R22P_R0)
+ return 1;
+
+ /* stw Ra, @(fp,r0) -- observed */
+ if ((op & OP_MASK_ALL_BUT_RA) == OP_STW_FP_R0)
+ return 1; /* first arg */
+
+ /* stw Ra, @(fp,imm) -- observed */
+ if ((op & OP_MASK_OP_AND_RB) == OP_STW_FP_IMM)
+ return 1; /* second and subsequent args */
+
+ /* stw fp,@(sp,imm) -- observed */
+ if ((op & OP_MASK_ALL_BUT_IMM) == OP_STW_FP_SP_IMM)
+ return 1;
+
+ /* st2w Ra,@(r22+,r0) */
+ if ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_R22P_R0)
+ return 1;
+
+ /* stw Ra, @(sp-) */
+ if ((op & OP_MASK_ALL_BUT_RA) == OP_STW_SPM)
+ return 1;
+
+ /* st2w Ra, @(sp-) */
+ if ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SPM)
+ return 1;
+
+ /* sub.? sp,sp,imm */
+ if ((op & OP_MASK_ALL_BUT_IMM) == OP_SUB_SP_IMM)
+ return 1;
+
+ return 0;
+}
+
+CORE_ADDR
+d30v_skip_prologue (CORE_ADDR pc)
+{
+ unsigned long op[2];
+ unsigned long opl, opr; /* left / right sub operations */
+ unsigned long fm0, fm1; /* left / right mode bits */
+ unsigned long cc0, cc1;
+ unsigned long op1, op2;
+ CORE_ADDR func_addr, func_end;
+ struct symtab_and_line sal;
+
+ /* If we have line debugging information, then the end of the */
+ /* prologue should the first assembly instruction of the first source line */
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ sal = find_pc_line (func_addr, 0);
+ if (sal.end && sal.end < func_end)
+ return sal.end;
+ }
+
+ if (target_read_memory (pc, (char *) &op[0], 8))
+ return pc; /* Can't access it -- assume no prologue. */
+
+ while (1)
+ {
+ opl = (unsigned long) read_memory_integer (pc, 4);
+ opr = (unsigned long) read_memory_integer (pc + 4, 4);
+
+ fm0 = (opl & OP_MASK_FM_BIT);
+ fm1 = (opr & OP_MASK_FM_BIT);
+
+ cc0 = (opl & OP_MASK_CC_BITS);
+ cc1 = (opr & OP_MASK_CC_BITS);
+
+ opl = (opl & OP_MASK_SUB_INST);
+ opr = (opr & OP_MASK_SUB_INST);
+
+ if (fm0 && fm1)
+ {
+ /* long instruction (opl contains the opcode) */
+ if (((opl & OP_MASK_ALL_BUT_IMM) != OP_ADD_SP_IMM) && /* add sp,sp,imm */
+ ((opl & OP_MASK_ALL_BUT_IMM) != OP_ADD_R22_SP_IMM) && /* add r22,sp,imm */
+ ((opl & OP_MASK_OP_AND_RB) != OP_STW_SP_IMM) && /* stw Ra, @(sp,imm) */
+ ((opl & OP_MASK_OP_AND_RB) != OP_ST2W_SP_IMM)) /* st2w Ra, @(sp,imm) */
+ break;
+ }
+ else
+ {
+ /* short instructions */
+ if (fm0 && !fm1)
+ {
+ op1 = opr;
+ op2 = opl;
+ }
+ else
+ {
+ op1 = opl;
+ op2 = opr;
+ }
+ if (check_prologue (op1))
+ {
+ if (!check_prologue (op2))
+ {
+ /* if the previous opcode was really part of the prologue */
+ /* and not just a NOP, then we want to break after both instructions */
+ if ((op1 & OP_MASK_OPCODE) != OP_NOP)
+ pc += 8;
+ break;
+ }
+ }
+ else
+ break;
+ }
+ pc += 8;
+ }
+ return pc;
+}
+
+static int end_of_stack;
+
+/* Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+ */
+
+CORE_ADDR
+d30v_frame_chain (struct frame_info *frame)
+{
+ struct frame_saved_regs fsr;
+
+ d30v_frame_find_saved_regs (frame, &fsr);
+
+ if (end_of_stack)
+ return (CORE_ADDR) 0;
+
+ if (frame->return_pc == IMEM_START)
+ return (CORE_ADDR) 0;
+
+ if (!fsr.regs[FP_REGNUM])
+ {
+ if (!fsr.regs[SP_REGNUM] || fsr.regs[SP_REGNUM] == STACK_START)
+ return (CORE_ADDR) 0;
+
+ return fsr.regs[SP_REGNUM];
+ }
+
+ if (!read_memory_unsigned_integer (fsr.regs[FP_REGNUM], 4))
+ return (CORE_ADDR) 0;
+
+ return read_memory_unsigned_integer (fsr.regs[FP_REGNUM], 4);
+}
+
+static int next_addr, uses_frame;
+static int frame_size;
+
+static int
+prologue_find_regs (unsigned long op, struct frame_saved_regs *fsr,
+ CORE_ADDR addr)
+{
+ int n;
+ int offset;
+
+ /* add sp,sp,imm -- observed */
+ if ((op & OP_MASK_ALL_BUT_IMM) == OP_ADD_SP_IMM)
+ {
+ offset = EXTRACT_IMM6 (op);
+ /*next_addr += offset; */
+ frame_size += -offset;
+ return 1;
+ }
+
+ /* add r22,sp,imm -- observed */
+ if ((op & OP_MASK_ALL_BUT_IMM) == OP_ADD_R22_SP_IMM)
+ {
+ offset = EXTRACT_IMM6 (op);
+ next_addr = (offset - frame_size);
+ return 1;
+ }
+
+ /* stw Ra, @(fp, offset) -- observed */
+ if ((op & OP_MASK_OP_AND_RB) == OP_STW_FP_IMM)
+ {
+ n = EXTRACT_RA (op);
+ offset = EXTRACT_IMM6 (op);
+ fsr->regs[n] = (offset - frame_size);
+ return 1;
+ }
+
+ /* stw Ra, @(fp, r0) -- observed */
+ if ((op & OP_MASK_ALL_BUT_RA) == OP_STW_FP_R0)
+ {
+ n = EXTRACT_RA (op);
+ fsr->regs[n] = (-frame_size);
+ return 1;
+ }
+
+ /* or fp,0,sp -- observed */
+ if ((op == OP_OR_FP_R0_SP) ||
+ (op == OP_OR_FP_SP_R0) ||
+ (op == OP_OR_FP_IMM0_SP))
+ {
+ uses_frame = 1;
+ return 1;
+ }
+
+ /* nop */
+ if ((op & OP_MASK_OPCODE) == OP_NOP)
+ return 1;
+
+ /* stw Ra,@(r22+,r0) -- observed */
+ if ((op & OP_MASK_ALL_BUT_RA) == OP_STW_R22P_R0)
+ {
+ n = EXTRACT_RA (op);
+ fsr->regs[n] = next_addr;
+ next_addr += 4;
+ return 1;
+ }
+#if 0 /* subsumed in pattern above */
+ /* stw fp,@(r22+,r0) -- observed */
+ if (op == OP_STW_FP_R22P_R0)
+ {
+ fsr->regs[FP_REGNUM] = next_addr; /* XXX */
+ next_addr += 4;
+ return 1;
+ }
+
+ /* stw r62,@(r22+,r0) -- observed */
+ if (op == OP_STW_LR_R22P_R0)
+ {
+ fsr->regs[LR_REGNUM] = next_addr;
+ next_addr += 4;
+ return 1;
+ }
+#endif
+ /* st2w Ra,@(r22+,r0) -- observed */
+ if ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_R22P_R0)
+ {
+ n = EXTRACT_RA (op);
+ fsr->regs[n] = next_addr;
+ fsr->regs[n + 1] = next_addr + 4;
+ next_addr += 8;
+ return 1;
+ }
+
+ /* stw rn, @(sp-) */
+ if ((op & OP_MASK_ALL_BUT_RA) == OP_STW_SPM)
+ {
+ n = EXTRACT_RA (op);
+ fsr->regs[n] = next_addr;
+ next_addr -= 4;
+ return 1;
+ }
+
+ /* st2w Ra, @(sp-) */
+ else if ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SPM)
+ {
+ n = EXTRACT_RA (op);
+ fsr->regs[n] = next_addr;
+ fsr->regs[n + 1] = next_addr + 4;
+ next_addr -= 8;
+ return 1;
+ }
+
+ /* sub sp,sp,imm */
+ if ((op & OP_MASK_ALL_BUT_IMM) == OP_SUB_SP_IMM)
+ {
+ offset = EXTRACT_IMM6 (op);
+ frame_size += -offset;
+ return 1;
+ }
+
+ /* st rn, @(sp,0) -- observed */
+ if (((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_R0) ||
+ ((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_IMM0))
+ {
+ n = EXTRACT_RA (op);
+ fsr->regs[n] = (-frame_size);
+ return 1;
+ }
+
+ /* st2w rn, @(sp,0) */
+ if (((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SP_R0) ||
+ ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SP_IMM0))
+ {
+ n = EXTRACT_RA (op);
+ fsr->regs[n] = (-frame_size);
+ fsr->regs[n + 1] = (-frame_size) + 4;
+ return 1;
+ }
+
+ /* stw fp,@(sp,imm) -- observed */
+ if ((op & OP_MASK_ALL_BUT_IMM) == OP_STW_FP_SP_IMM)
+ {
+ offset = EXTRACT_IMM6 (op);
+ fsr->regs[FP_REGNUM] = (offset - frame_size);
+ return 1;
+ }
+ return 0;
+}
+
+/* Put here the code to store, into a struct frame_saved_regs, the
+ addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special: the address we
+ return for it IS the sp for the next frame. */
+void
+d30v_frame_find_saved_regs (struct frame_info *fi, struct frame_saved_regs *fsr)
+{
+ CORE_ADDR fp, pc;
+ unsigned long opl, opr;
+ unsigned long op1, op2;
+ unsigned long fm0, fm1;
+ int i;
+
+ fp = fi->frame;
+ memset (fsr, 0, sizeof (*fsr));
+ next_addr = 0;
+ frame_size = 0;
+ end_of_stack = 0;
+
+ uses_frame = 0;
+
+ d30v_frame_find_saved_regs_offsets (fi, fsr);
+
+ fi->size = frame_size;
+
+ if (!fp)
+ fp = read_register (SP_REGNUM);
+
+ for (i = 0; i < NUM_REGS - 1; i++)
+ if (fsr->regs[i])
+ {
+ fsr->regs[i] = fsr->regs[i] + fp + frame_size;
+ }
+
+ if (fsr->regs[LR_REGNUM])
+ fi->return_pc = read_memory_unsigned_integer (fsr->regs[LR_REGNUM], 4);
+ else
+ fi->return_pc = read_register (LR_REGNUM);
+
+ /* the SP is not normally (ever?) saved, but check anyway */
+ if (!fsr->regs[SP_REGNUM])
+ {
+ /* if the FP was saved, that means the current FP is valid, */
+ /* otherwise, it isn't being used, so we use the SP instead */
+ if (uses_frame)
+ fsr->regs[SP_REGNUM] = read_register (FP_REGNUM) + fi->size;
+ else
+ {
+ fsr->regs[SP_REGNUM] = fp + fi->size;
+ fi->frameless = 1;
+ fsr->regs[FP_REGNUM] = 0;
+ }
+ }
+}
+
+void
+d30v_frame_find_saved_regs_offsets (struct frame_info *fi,
+ struct frame_saved_regs *fsr)
+{
+ CORE_ADDR fp, pc;
+ unsigned long opl, opr;
+ unsigned long op1, op2;
+ unsigned long fm0, fm1;
+ int i;
+
+ fp = fi->frame;
+ memset (fsr, 0, sizeof (*fsr));
+ next_addr = 0;
+ frame_size = 0;
+ end_of_stack = 0;
+
+ pc = get_pc_function_start (fi->pc);
+
+ uses_frame = 0;
+ while (pc < fi->pc)
+ {
+ opl = (unsigned long) read_memory_integer (pc, 4);
+ opr = (unsigned long) read_memory_integer (pc + 4, 4);
+
+ fm0 = (opl & OP_MASK_FM_BIT);
+ fm1 = (opr & OP_MASK_FM_BIT);
+
+ opl = (opl & OP_MASK_SUB_INST);
+ opr = (opr & OP_MASK_SUB_INST);
+
+ if (fm0 && fm1)
+ {
+ /* long instruction */
+ if ((opl & OP_MASK_ALL_BUT_IMM) == OP_ADD_SP_IMM)
+ {
+ /* add sp,sp,n */
+ long offset = EXTRACT_IMM32 (opl, opr);
+ frame_size += -offset;
+ }
+ else if ((opl & OP_MASK_ALL_BUT_IMM) == OP_ADD_R22_SP_IMM)
+ {
+ /* add r22,sp,offset */
+ long offset = EXTRACT_IMM32 (opl, opr);
+ next_addr = (offset - frame_size);
+ }
+ else if ((opl & OP_MASK_OP_AND_RB) == OP_STW_SP_IMM)
+ {
+ /* st Ra, @(sp,imm) */
+ long offset = EXTRACT_IMM32 (opl, opr);
+ short n = EXTRACT_RA (opl);
+ fsr->regs[n] = (offset - frame_size);
+ }
+ else if ((opl & OP_MASK_OP_AND_RB) == OP_ST2W_SP_IMM)
+ {
+ /* st2w Ra, @(sp,offset) */
+ long offset = EXTRACT_IMM32 (opl, opr);
+ short n = EXTRACT_RA (opl);
+ fsr->regs[n] = (offset - frame_size);
+ fsr->regs[n + 1] = (offset - frame_size) + 4;
+ }
+ else if ((opl & OP_MASK_ALL_BUT_IMM) == OP_OR_SP_R0_IMM)
+ {
+ end_of_stack = 1;
+ }
+ else
+ break;
+ }
+ else
+ {
+ /* short instructions */
+ if (fm0 && !fm1)
+ {
+ op2 = opl;
+ op1 = opr;
+ }
+ else
+ {
+ op1 = opl;
+ op2 = opr;
+ }
+ if (!prologue_find_regs (op1, fsr, pc) || !prologue_find_regs (op2, fsr, pc))
+ break;
+ }
+ pc += 8;
+ }
+
+#if 0
+ fi->size = frame_size;
+
+ if (!fp)
+ fp = read_register (SP_REGNUM);
+
+ for (i = 0; i < NUM_REGS - 1; i++)
+ if (fsr->regs[i])
+ {
+ fsr->regs[i] = fsr->regs[i] + fp + frame_size;
+ }
+
+ if (fsr->regs[LR_REGNUM])
+ fi->return_pc = read_memory_unsigned_integer (fsr->regs[LR_REGNUM], 4);
+ else
+ fi->return_pc = read_register (LR_REGNUM);
+
+ /* the SP is not normally (ever?) saved, but check anyway */
+ if (!fsr->regs[SP_REGNUM])
+ {
+ /* if the FP was saved, that means the current FP is valid, */
+ /* otherwise, it isn't being used, so we use the SP instead */
+ if (uses_frame)
+ fsr->regs[SP_REGNUM] = read_register (FP_REGNUM) + fi->size;
+ else
+ {
+ fsr->regs[SP_REGNUM] = fp + fi->size;
+ fi->frameless = 1;
+ fsr->regs[FP_REGNUM] = 0;
+ }
+ }
+#endif
+}
+
+void
+d30v_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ struct frame_saved_regs dummy;
+
+ if (fi->next && (fi->pc == 0))
+ fi->pc = fi->next->return_pc;
+
+ d30v_frame_find_saved_regs_offsets (fi, &dummy);
+
+ if (uses_frame == 0)
+ fi->frameless = 1;
+ else
+ fi->frameless = 0;
+
+ if ((fi->next == 0) && (uses_frame == 0))
+ /* innermost frame and it's "frameless",
+ so the fi->frame field is wrong, fix it! */
+ fi->frame = read_sp ();
+
+ if (dummy.regs[LR_REGNUM])
+ {
+ /* it was saved, grab it! */
+ dummy.regs[LR_REGNUM] += (fi->frame + frame_size);
+ fi->return_pc = read_memory_unsigned_integer (dummy.regs[LR_REGNUM], 4);
+ }
+ else
+ fi->return_pc = read_register (LR_REGNUM);
+}
+
+void
+d30v_init_frame_pc (int fromleaf, struct frame_info *prev)
+{
+ /* default value, put here so we can breakpoint on it and
+ see if the default value is really the right thing to use */
+ prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (prev->next) : \
+ prev->next ? FRAME_SAVED_PC (prev->next) : read_pc ());
+}
+
+static void d30v_print_register (int regnum, int tabular);
+
+static void
+d30v_print_register (int regnum, int tabular)
+{
+ if (regnum < A0_REGNUM)
+ {
+ if (tabular)
+ printf_filtered ("%08lx", (long) read_register (regnum));
+ else
+ printf_filtered ("0x%lx %ld",
+ (long) read_register (regnum),
+ (long) read_register (regnum));
+ }
+ else
+ {
+ char regbuf[MAX_REGISTER_RAW_SIZE];
+
+ frame_register_read (selected_frame, regnum, regbuf);
+
+ val_print (REGISTER_VIRTUAL_TYPE (regnum), regbuf, 0, 0,
+ gdb_stdout, 'x', 1, 0, Val_pretty_default);
+
+ if (!tabular)
+ {
+ printf_filtered (" ");
+ val_print (REGISTER_VIRTUAL_TYPE (regnum), regbuf, 0, 0,
+ gdb_stdout, 'd', 1, 0, Val_pretty_default);
+ }
+ }
+}
+
+static void
+d30v_print_flags (void)
+{
+ long psw = read_register (PSW_REGNUM);
+ printf_filtered ("flags #1");
+ printf_filtered (" (sm) %d", (psw & PSW_SM) != 0);
+ printf_filtered (" (ea) %d", (psw & PSW_EA) != 0);
+ printf_filtered (" (db) %d", (psw & PSW_DB) != 0);
+ printf_filtered (" (ds) %d", (psw & PSW_DS) != 0);
+ printf_filtered (" (ie) %d", (psw & PSW_IE) != 0);
+ printf_filtered (" (rp) %d", (psw & PSW_RP) != 0);
+ printf_filtered (" (md) %d\n", (psw & PSW_MD) != 0);
+
+ printf_filtered ("flags #2");
+ printf_filtered (" (f0) %d", (psw & PSW_F0) != 0);
+ printf_filtered (" (f1) %d", (psw & PSW_F1) != 0);
+ printf_filtered (" (f2) %d", (psw & PSW_F2) != 0);
+ printf_filtered (" (f3) %d", (psw & PSW_F3) != 0);
+ printf_filtered (" (s) %d", (psw & PSW_S) != 0);
+ printf_filtered (" (v) %d", (psw & PSW_V) != 0);
+ printf_filtered (" (va) %d", (psw & PSW_VA) != 0);
+ printf_filtered (" (c) %d\n", (psw & PSW_C) != 0);
+}
+
+static void
+print_flags_command (char *args, int from_tty)
+{
+ d30v_print_flags ();
+}
+
+void
+d30v_do_registers_info (int regnum, int fpregs)
+{
+ long long num1, num2;
+ long psw;
+
+ if (regnum != -1)
+ {
+ if (REGISTER_NAME (0) == NULL || REGISTER_NAME (0)[0] == '\000')
+ return;
+
+ printf_filtered ("%s ", REGISTER_NAME (regnum));
+ d30v_print_register (regnum, 0);
+
+ printf_filtered ("\n");
+ return;
+ }
+
+ /* Have to print all the registers. Format them nicely. */
+
+ printf_filtered ("PC=");
+ print_address (read_pc (), gdb_stdout);
+
+ printf_filtered (" PSW=");
+ d30v_print_register (PSW_REGNUM, 1);
+
+ printf_filtered (" BPC=");
+ print_address (read_register (BPC_REGNUM), gdb_stdout);
+
+ printf_filtered (" BPSW=");
+ d30v_print_register (BPSW_REGNUM, 1);
+ printf_filtered ("\n");
+
+ printf_filtered ("DPC=");
+ print_address (read_register (DPC_REGNUM), gdb_stdout);
+
+ printf_filtered (" DPSW=");
+ d30v_print_register (DPSW_REGNUM, 1);
+
+ printf_filtered (" IBA=");
+ print_address (read_register (IBA_REGNUM), gdb_stdout);
+ printf_filtered ("\n");
+
+ printf_filtered ("RPT_C=");
+ d30v_print_register (RPT_C_REGNUM, 1);
+
+ printf_filtered (" RPT_S=");
+ print_address (read_register (RPT_S_REGNUM), gdb_stdout);
+
+ printf_filtered (" RPT_E=");
+ print_address (read_register (RPT_E_REGNUM), gdb_stdout);
+ printf_filtered ("\n");
+
+ printf_filtered ("MOD_S=");
+ print_address (read_register (MOD_S_REGNUM), gdb_stdout);
+
+ printf_filtered (" MOD_E=");
+ print_address (read_register (MOD_E_REGNUM), gdb_stdout);
+ printf_filtered ("\n");
+
+ printf_filtered ("EIT_VB=");
+ print_address (read_register (EIT_VB_REGNUM), gdb_stdout);
+
+ printf_filtered (" INT_S=");
+ d30v_print_register (INT_S_REGNUM, 1);
+
+ printf_filtered (" INT_M=");
+ d30v_print_register (INT_M_REGNUM, 1);
+ printf_filtered ("\n");
+
+ d30v_print_flags ();
+ for (regnum = 0; regnum <= 63;)
+ {
+ int i;
+
+ printf_filtered ("R%d-R%d ", regnum, regnum + 7);
+ if (regnum < 10)
+ printf_filtered (" ");
+ if (regnum + 7 < 10)
+ printf_filtered (" ");
+
+ for (i = 0; i < 8; i++)
+ {
+ printf_filtered (" ");
+ d30v_print_register (regnum++, 1);
+ }
+
+ printf_filtered ("\n");
+ }
+
+ printf_filtered ("A0-A1 ");
+
+ d30v_print_register (A0_REGNUM, 1);
+ printf_filtered (" ");
+ d30v_print_register (A1_REGNUM, 1);
+ printf_filtered ("\n");
+}
+
+CORE_ADDR
+d30v_fix_call_dummy (char *dummyname, CORE_ADDR start_sp, CORE_ADDR fun,
+ int nargs, struct value **args,
+ struct type *type, int gcc_p)
+{
+ int regnum;
+ CORE_ADDR sp;
+ char buffer[MAX_REGISTER_RAW_SIZE];
+ struct frame_info *frame = get_current_frame ();
+ frame->dummy = start_sp;
+ /*start_sp |= DMEM_START; */
+
+ sp = start_sp;
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ {
+ sp -= REGISTER_RAW_SIZE (regnum);
+ store_address (buffer, REGISTER_RAW_SIZE (regnum), read_register (regnum));
+ write_memory (sp, buffer, REGISTER_RAW_SIZE (regnum));
+ }
+ write_register (SP_REGNUM, (LONGEST) sp);
+ /* now we need to load LR with the return address */
+ write_register (LR_REGNUM, (LONGEST) d30v_call_dummy_address ());
+ return sp;
+}
+
+static void
+d30v_pop_dummy_frame (struct frame_info *fi)
+{
+ CORE_ADDR sp = fi->dummy;
+ int regnum;
+
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ {
+ sp -= REGISTER_RAW_SIZE (regnum);
+ write_register (regnum, read_memory_unsigned_integer (sp, REGISTER_RAW_SIZE (regnum)));
+ }
+ flush_cached_frames (); /* needed? */
+}
+
+
+CORE_ADDR
+d30v_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int i, len, index = 0, regnum = 2;
+ char buffer[4], *contents;
+ LONGEST val;
+ CORE_ADDR ptrs[10];
+
+#if 0
+ /* Pass 1. Put all large args on stack */
+ for (i = 0; i < nargs; i++)
+ {
+ struct value *arg = args[i];
+ struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+ len = TYPE_LENGTH (arg_type);
+ contents = VALUE_CONTENTS (arg);
+ val = extract_signed_integer (contents, len);
+ if (len > 4)
+ {
+ /* put on stack and pass pointers */
+ sp -= len;
+ write_memory (sp, contents, len);
+ ptrs[index++] = sp;
+ }
+ }
+#endif
+ index = 0;
+
+ for (i = 0; i < nargs; i++)
+ {
+ struct value *arg = args[i];
+ struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+ len = TYPE_LENGTH (arg_type);
+ contents = VALUE_CONTENTS (arg);
+ if (len > 4)
+ {
+ /* we need multiple registers */
+ int ndx;
+
+ for (ndx = 0; len > 0; ndx += 8, len -= 8)
+ {
+ if (regnum & 1)
+ regnum++; /* all args > 4 bytes start in even register */
+
+ if (regnum < 18)
+ {
+ val = extract_signed_integer (&contents[ndx], 4);
+ write_register (regnum++, val);
+
+ if (len >= 8)
+ val = extract_signed_integer (&contents[ndx + 4], 4);
+ else
+ val = extract_signed_integer (&contents[ndx + 4], len - 4);
+ write_register (regnum++, val);
+ }
+ else
+ {
+ /* no more registers available. put it on the stack */
+
+ /* all args > 4 bytes are padded to a multiple of 8 bytes
+ and start on an 8 byte boundary */
+ if (sp & 7)
+ sp -= (sp & 7); /* align it */
+
+ sp -= ((len + 7) & ~7); /* allocate space */
+ write_memory (sp, &contents[ndx], len);
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (regnum < 18)
+ {
+ val = extract_signed_integer (contents, len);
+ write_register (regnum++, val);
+ }
+ else
+ {
+ /* all args are padded to a multiple of 4 bytes (at least) */
+ sp -= ((len + 3) & ~3);
+ write_memory (sp, contents, len);
+ }
+ }
+ }
+ if (sp & 7)
+ /* stack pointer is not on an 8 byte boundary -- align it */
+ sp -= (sp & 7);
+ return sp;
+}
+
+
+/* pick an out-of-the-way place to set the return value */
+/* for an inferior function call. The link register is set to this */
+/* value and a momentary breakpoint is set there. When the breakpoint */
+/* is hit, the dummy frame is popped and the previous environment is */
+/* restored. */
+
+CORE_ADDR
+d30v_call_dummy_address (void)
+{
+ CORE_ADDR entry;
+ struct minimal_symbol *sym;
+
+ entry = entry_point_address ();
+
+ if (entry != 0)
+ return entry;
+
+ sym = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
+
+ if (!sym || MSYMBOL_TYPE (sym) != mst_text)
+ return 0;
+ else
+ return SYMBOL_VALUE_ADDRESS (sym);
+}
+
+/* Given a return value in `regbuf' with a type `valtype',
+ extract and copy its value into `valbuf'. */
+
+void
+d30v_extract_return_value (struct type *valtype, char regbuf[REGISTER_BYTES],
+ char *valbuf)
+{
+ memcpy (valbuf, regbuf + REGISTER_BYTE (2), TYPE_LENGTH (valtype));
+}
+
+/* The following code implements access to, and display of, the D30V's
+ instruction trace buffer. The buffer consists of 64K or more
+ 4-byte words of data, of which each words includes an 8-bit count,
+ an 8-bit segment number, and a 16-bit instruction address.
+
+ In theory, the trace buffer is continuously capturing instruction
+ data that the CPU presents on its "debug bus", but in practice, the
+ ROMified GDB stub only enables tracing when it continues or steps
+ the program, and stops tracing when the program stops; so it
+ actually works for GDB to read the buffer counter out of memory and
+ then read each trace word. The counter records where the tracing
+ stops, but there is no record of where it started, so we remember
+ the PC when we resumed and then search backwards in the trace
+ buffer for a word that includes that address. This is not perfect,
+ because you will miss trace data if the resumption PC is the target
+ of a branch. (The value of the buffer counter is semi-random, any
+ trace data from a previous program stop is gone.) */
+
+/* The address of the last word recorded in the trace buffer. */
+
+#define DBBC_ADDR (0xd80000)
+
+/* The base of the trace buffer, at least for the "Board_0". */
+
+#define TRACE_BUFFER_BASE (0xf40000)
+
+static void trace_command (char *, int);
+
+static void untrace_command (char *, int);
+
+static void trace_info (char *, int);
+
+static void tdisassemble_command (char *, int);
+
+static void display_trace (int, int);
+
+/* True when instruction traces are being collected. */
+
+static int tracing;
+
+/* Remembered PC. */
+
+static CORE_ADDR last_pc;
+
+/* True when trace output should be displayed whenever program stops. */
+
+static int trace_display;
+
+/* True when trace listing should include source lines. */
+
+static int default_trace_show_source = 1;
+
+struct trace_buffer
+ {
+ int size;
+ short *counts;
+ CORE_ADDR *addrs;
+ }
+trace_data;
+
+static void
+trace_command (char *args, int from_tty)
+{
+ /* Clear the host-side trace buffer, allocating space if needed. */
+ trace_data.size = 0;
+ if (trace_data.counts == NULL)
+ trace_data.counts = (short *) xmalloc (65536 * sizeof (short));
+ if (trace_data.addrs == NULL)
+ trace_data.addrs = (CORE_ADDR *) xmalloc (65536 * sizeof (CORE_ADDR));
+
+ tracing = 1;
+
+ printf_filtered ("Tracing is now on.\n");
+}
+
+static void
+untrace_command (char *args, int from_tty)
+{
+ tracing = 0;
+
+ printf_filtered ("Tracing is now off.\n");
+}
+
+static void
+trace_info (char *args, int from_tty)
+{
+ int i;
+
+ if (trace_data.size)
+ {
+ printf_filtered ("%d entries in trace buffer:\n", trace_data.size);
+
+ for (i = 0; i < trace_data.size; ++i)
+ {
+ printf_filtered ("%d: %d instruction%s at 0x%s\n",
+ i, trace_data.counts[i],
+ (trace_data.counts[i] == 1 ? "" : "s"),
+ paddr_nz (trace_data.addrs[i]));
+ }
+ }
+ else
+ printf_filtered ("No entries in trace buffer.\n");
+
+ printf_filtered ("Tracing is currently %s.\n", (tracing ? "on" : "off"));
+}
+
+/* Print the instruction at address MEMADDR in debugged memory,
+ on STREAM. Returns length of the instruction, in bytes. */
+
+static int
+print_insn (CORE_ADDR memaddr, struct ui_file *stream)
+{
+ /* If there's no disassembler, something is very wrong. */
+ if (tm_print_insn == NULL)
+ internal_error (__FILE__, __LINE__,
+ "print_insn: no disassembler");
+
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ tm_print_insn_info.endian = BFD_ENDIAN_BIG;
+ else
+ tm_print_insn_info.endian = BFD_ENDIAN_LITTLE;
+ return TARGET_PRINT_INSN (memaddr, &tm_print_insn_info);
+}
+
+void
+d30v_eva_prepare_to_trace (void)
+{
+ if (!tracing)
+ return;
+
+ last_pc = read_register (PC_REGNUM);
+}
+
+/* Collect trace data from the target board and format it into a form
+ more useful for display. */
+
+void
+d30v_eva_get_trace_data (void)
+{
+ int count, i, j, oldsize;
+ int trace_addr, trace_seg, trace_cnt, next_cnt;
+ unsigned int last_trace, trace_word, next_word;
+ unsigned int *tmpspace;
+
+ if (!tracing)
+ return;
+
+ tmpspace = xmalloc (65536 * sizeof (unsigned int));
+
+ last_trace = read_memory_unsigned_integer (DBBC_ADDR, 2) << 2;
+
+ /* Collect buffer contents from the target, stopping when we reach
+ the word recorded when execution resumed. */
+
+ count = 0;
+ while (last_trace > 0)
+ {
+ QUIT;
+ trace_word =
+ read_memory_unsigned_integer (TRACE_BUFFER_BASE + last_trace, 4);
+ trace_addr = trace_word & 0xffff;
+ last_trace -= 4;
+ /* Ignore an apparently nonsensical entry. */
+ if (trace_addr == 0xffd5)
+ continue;
+ tmpspace[count++] = trace_word;
+ if (trace_addr == last_pc)
+ break;
+ if (count > 65535)
+ break;
+ }
+
+ /* Move the data to the host-side trace buffer, adjusting counts to
+ include the last instruction executed and transforming the address
+ into something that GDB likes. */
+
+ for (i = 0; i < count; ++i)
+ {
+ trace_word = tmpspace[i];
+ next_word = ((i == 0) ? 0 : tmpspace[i - 1]);
+ trace_addr = trace_word & 0xffff;
+ next_cnt = (next_word >> 24) & 0xff;
+ j = trace_data.size + count - i - 1;
+ trace_data.addrs[j] = (trace_addr << 2) + 0x1000000;
+ trace_data.counts[j] = next_cnt + 1;
+ }
+
+ oldsize = trace_data.size;
+ trace_data.size += count;
+
+ xfree (tmpspace);
+
+ if (trace_display)
+ display_trace (oldsize, trace_data.size);
+}
+
+static void
+tdisassemble_command (char *arg, int from_tty)
+{
+ int i, count;
+ CORE_ADDR low, high;
+ char *space_index;
+
+ if (!arg)
+ {
+ low = 0;
+ high = trace_data.size;
+ }
+ else if (!(space_index = (char *) strchr (arg, ' ')))
+ {
+ low = parse_and_eval_address (arg);
+ high = low + 5;
+ }
+ else
+ {
+ /* Two arguments. */
+ *space_index = '\0';
+ low = parse_and_eval_address (arg);
+ high = parse_and_eval_address (space_index + 1);
+ if (high < low)
+ high = low;
+ }
+
+ printf_filtered ("Dump of trace from %s to %s:\n",
+ paddr_u (low),
+ paddr_u (high));
+
+ display_trace (low, high);
+
+ printf_filtered ("End of trace dump.\n");
+ gdb_flush (gdb_stdout);
+}
+
+static void
+display_trace (int low, int high)
+{
+ int i, count, trace_show_source, first, suppress;
+ CORE_ADDR next_address;
+
+ trace_show_source = default_trace_show_source;
+ if (!have_full_symbols () && !have_partial_symbols ())
+ {
+ trace_show_source = 0;
+ printf_filtered ("No symbol table is loaded. Use the \"file\" command.\n");
+ printf_filtered ("Trace will not display any source.\n");
+ }
+
+ first = 1;
+ suppress = 0;
+ for (i = low; i < high; ++i)
+ {
+ next_address = trace_data.addrs[i];
+ count = trace_data.counts[i];
+ while (count-- > 0)
+ {
+ QUIT;
+ if (trace_show_source)
+ {
+ struct symtab_and_line sal, sal_prev;
+
+ sal_prev = find_pc_line (next_address - 4, 0);
+ sal = find_pc_line (next_address, 0);
+
+ if (sal.symtab)
+ {
+ if (first || sal.line != sal_prev.line)
+ print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
+ suppress = 0;
+ }
+ else
+ {
+ if (!suppress)
+ /* FIXME-32x64--assumes sal.pc fits in long. */
+ printf_filtered ("No source file for address %s.\n",
+ local_hex_string ((unsigned long) sal.pc));
+ suppress = 1;
+ }
+ }
+ first = 0;
+ print_address (next_address, gdb_stdout);
+ printf_filtered (":");
+ printf_filtered ("\t");
+ wrap_here (" ");
+ next_address = next_address + print_insn (next_address, gdb_stdout);
+ printf_filtered ("\n");
+ gdb_flush (gdb_stdout);
+ }
+ }
+}
+
+extern void (*target_resume_hook) (void);
+extern void (*target_wait_loop_hook) (void);
+
+void
+_initialize_d30v_tdep (void)
+{
+ tm_print_insn = print_insn_d30v;
+
+ target_resume_hook = d30v_eva_prepare_to_trace;
+ target_wait_loop_hook = d30v_eva_get_trace_data;
+
+ add_info ("flags", print_flags_command, "Print d30v flags.");
+
+ add_com ("trace", class_support, trace_command,
+ "Enable tracing of instruction execution.");
+
+ add_com ("untrace", class_support, untrace_command,
+ "Disable tracing of instruction execution.");
+
+ add_com ("tdisassemble", class_vars, tdisassemble_command,
+ "Disassemble the trace buffer.\n\
+Two optional arguments specify a range of trace buffer entries\n\
+as reported by info trace (NOT addresses!).");
+
+ add_info ("trace", trace_info,
+ "Display info about the trace data buffer.");
+
+ add_show_from_set (add_set_cmd ("tracedisplay", no_class,
+ var_integer, (char *) &trace_display,
+ "Set automatic display of trace.\n", &setlist),
+ &showlist);
+ add_show_from_set (add_set_cmd ("tracesource", no_class,
+ var_integer, (char *) &default_trace_show_source,
+ "Set display of source code with trace.\n", &setlist),
+ &showlist);
+
+}
diff --git a/gdb/dbug-rom.c b/gdb/dbug-rom.c
new file mode 100644
index 00000000000..f31555738eb
--- /dev/null
+++ b/gdb/dbug-rom.c
@@ -0,0 +1,161 @@
+/* Remote debugging interface to dBUG ROM monitor for GDB, the GNU debugger.
+ Copyright 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+ Written by Stan Shebs of 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 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. */
+
+/* dBUG is a monitor supplied on various Motorola boards, including
+ m68k, ColdFire, and PowerPC-based designs. The code here assumes
+ the ColdFire, and (as of 9/25/96) has only been tested with a
+ ColdFire IDP board. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "regcache.h"
+
+static void dbug_open (char *args, int from_tty);
+
+static void
+dbug_supply_register (char *regname, int regnamelen, char *val, int vallen)
+{
+ int regno;
+
+ if (regnamelen != 2)
+ return;
+
+ switch (regname[0])
+ {
+ case 'S':
+ if (regname[1] != 'R')
+ return;
+ regno = PS_REGNUM;
+ break;
+ case 'P':
+ if (regname[1] != 'C')
+ return;
+ regno = PC_REGNUM;
+ break;
+ case 'D':
+ if (regname[1] < '0' || regname[1] > '7')
+ return;
+ regno = regname[1] - '0' + D0_REGNUM;
+ break;
+ case 'A':
+ if (regname[1] < '0' || regname[1] > '7')
+ return;
+ regno = regname[1] - '0' + A0_REGNUM;
+ break;
+ default:
+ return;
+ }
+
+ monitor_supply_register (regno, val);
+}
+
+/* This array of registers needs to match the indexes used by GDB. The
+ whole reason this exists is because the various ROM monitors use
+ different names than GDB does, and don't support all the registers
+ either. So, typing "info reg sp" becomes an "A7". */
+
+static char *dbug_regnames[NUM_REGS] =
+{
+ "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
+ "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
+ "SR", "PC"
+ /* no float registers */
+};
+static struct target_ops dbug_ops;
+static struct monitor_ops dbug_cmds;
+
+static char *dbug_inits[] =
+{"\r", NULL};
+
+
+static void
+init_dbug_cmds (void)
+{
+ dbug_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_GETMEM_NEEDS_RANGE | MO_FILL_USES_ADDR;
+ dbug_cmds.init = dbug_inits; /* Init strings */
+ dbug_cmds.cont = "go\r"; /* continue command */
+ dbug_cmds.step = "trace\r"; /* single step */
+ dbug_cmds.stop = NULL; /* interrupt command */
+ dbug_cmds.set_break = "br %x\r"; /* set a breakpoint */
+ dbug_cmds.clr_break = "br -r %x\r"; /* clear a breakpoint */
+ dbug_cmds.clr_all_break = "br -r\r"; /* clear all breakpoints */
+ dbug_cmds.fill = "bf.b %x %x %x\r"; /* fill (start end val) */
+ dbug_cmds.setmem.cmdb = "mm.b %x %x\r"; /* setmem.cmdb (addr, value) */
+ dbug_cmds.setmem.cmdw = "mm.w %x %x\r"; /* setmem.cmdw (addr, value) */
+ dbug_cmds.setmem.cmdl = "mm.l %x %x\r"; /* setmem.cmdl (addr, value) */
+ dbug_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ dbug_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */
+ dbug_cmds.setmem.term = NULL; /* setmem.term */
+ dbug_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */
+ dbug_cmds.getmem.cmdb = "md.b %x %x\r"; /* getmem.cmdb (addr, addr2) */
+ dbug_cmds.getmem.cmdw = "md.w %x %x\r"; /* getmem.cmdw (addr, addr2) */
+ dbug_cmds.getmem.cmdl = "md.l %x %x\r"; /* getmem.cmdl (addr, addr2) */
+ dbug_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, addr2) */
+ dbug_cmds.getmem.resp_delim = ":"; /* getmem.resp_delim */
+ dbug_cmds.getmem.term = NULL; /* getmem.term */
+ dbug_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
+ dbug_cmds.setreg.cmd = "rm %s %x\r"; /* setreg.cmd (name, value) */
+ dbug_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ dbug_cmds.setreg.term = NULL; /* setreg.term */
+ dbug_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
+ dbug_cmds.getreg.cmd = "rd %s\r"; /* getreg.cmd (name) */
+ dbug_cmds.getreg.resp_delim = ":"; /* getreg.resp_delim */
+ dbug_cmds.getreg.term = NULL; /* getreg.term */
+ dbug_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
+ dbug_cmds.dump_registers = "rd\r"; /* dump_registers */
+ dbug_cmds.register_pattern = "\\(\\w+\\) +:\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
+ dbug_cmds.supply_register = dbug_supply_register; /* supply_register */
+ dbug_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ dbug_cmds.load = "dl\r"; /* download command */
+ dbug_cmds.loadresp = "\n"; /* load response */
+ dbug_cmds.prompt = "dBUG>"; /* monitor command prompt */
+ dbug_cmds.line_term = "\r"; /* end-of-line terminator */
+ dbug_cmds.cmd_end = NULL; /* optional command terminator */
+ dbug_cmds.target = &dbug_ops; /* target operations */
+ dbug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ dbug_cmds.regnames = dbug_regnames; /* registers names */
+ dbug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+} /* init_debug_ops */
+
+static void
+dbug_open (char *args, int from_tty)
+{
+ monitor_open (args, &dbug_cmds, from_tty);
+}
+
+void
+_initialize_dbug_rom (void)
+{
+ init_dbug_cmds ();
+ init_monitor_ops (&dbug_ops);
+
+ dbug_ops.to_shortname = "dbug";
+ dbug_ops.to_longname = "dBUG monitor";
+ dbug_ops.to_doc = "Debug via the dBUG monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ dbug_ops.to_open = dbug_open;
+
+ add_target (&dbug_ops);
+}
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
new file mode 100644
index 00000000000..430e3f51f29
--- /dev/null
+++ b/gdb/dbxread.c
@@ -0,0 +1,3624 @@
+/* Read dbx symbol tables and convert to internal format, for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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. */
+
+/* This module provides three functions: dbx_symfile_init,
+ which initializes to read a symbol file; dbx_new_init, which
+ discards existing cached information when all symbols are being
+ discarded; and dbx_symfile_read, which reads a symbol table
+ from a file.
+
+ dbx_symfile_read only does the minimum work necessary for letting the
+ user "name" things symbolically; it does not read the entire symtab.
+ Instead, it reads the external and static symbols and puts them in partial
+ symbol tables. When more extensive information is requested of a
+ file, the corresponding partial symbol table is mutated into a full
+ fledged symbol table by going back and reading the symbols
+ for real. dbx_psymtab_to_symtab() is the function that does this */
+
+#include "defs.h"
+#include "gdb_string.h"
+
+#if defined(USG) || defined(__CYGNUSCLIB__)
+#include <sys/types.h>
+#include <fcntl.h>
+#endif
+
+#include "obstack.h"
+#include "gdb_stat.h"
+#include "symtab.h"
+#include "breakpoint.h"
+#include "target.h"
+#include "gdbcore.h" /* for bfd stuff */
+#include "libaout.h" /* FIXME Secret internal BFD stuff for a.out */
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "stabsread.h"
+#include "gdb-stabs.h"
+#include "demangle.h"
+#include "language.h" /* Needed for local_hex_string */
+#include "complaints.h"
+#include "cp-abi.h"
+
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h" /* We always use GNU stabs, not native, now */
+
+
+/* This macro returns the size field of a minimal symbol, which is normally
+ stored in the "info" field. The macro can be overridden for specific
+ targets (e.g. MIPS16) that use the info field for other purposes. */
+#ifndef MSYMBOL_SIZE
+#define MSYMBOL_SIZE(msym) ((long) MSYMBOL_INFO (msym))
+#endif
+
+
+/* We put a pointer to this structure in the read_symtab_private field
+ of the psymtab. */
+
+struct symloc
+ {
+ /* The start (inclusive) and end (exclusive) addresses for this
+ partial symtab's text. STABS doesn't reliably give us nice
+ start and end addresses for each function. Instead, we are
+ told the addresses of various boundary points, and we have to
+ gather those together to build ranges. These are our running
+ best guess as to the range of text addresses for this psymtab. */
+ CORE_ADDR textlow, texthigh;
+
+ /* Offset within the file symbol table of first local symbol for this
+ file. */
+
+ int ldsymoff;
+
+ /* Length (in bytes) of the section of the symbol table devoted to
+ this file's symbols (actually, the section bracketed may contain
+ more than just this file's symbols). If ldsymlen is 0, the only
+ reason for this thing's existence is the dependency list. Nothing
+ else will happen when it is read in. */
+
+ int ldsymlen;
+
+ /* The size of each symbol in the symbol file (in external form). */
+
+ int symbol_size;
+
+ /* Further information needed to locate the symbols if they are in
+ an ELF file. */
+
+ int symbol_offset;
+ int string_offset;
+ int file_string_offset;
+ };
+
+#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
+#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen)
+#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private))
+#define TEXTLOW(p) (SYMLOC(p)->textlow)
+#define TEXTHIGH(p) (SYMLOC(p)->texthigh)
+#define SYMBOL_SIZE(p) (SYMLOC(p)->symbol_size)
+#define SYMBOL_OFFSET(p) (SYMLOC(p)->symbol_offset)
+#define STRING_OFFSET(p) (SYMLOC(p)->string_offset)
+#define FILE_STRING_OFFSET(p) (SYMLOC(p)->file_string_offset)
+
+
+/* Remember what we deduced to be the source language of this psymtab. */
+
+static enum language psymtab_language = language_unknown;
+
+/* The BFD for this file -- implicit parameter to next_symbol_text. */
+
+static bfd *symfile_bfd;
+
+/* The size of each symbol in the symbol file (in external form).
+ This is set by dbx_symfile_read when building psymtabs, and by
+ dbx_psymtab_to_symtab when building symtabs. */
+
+static unsigned symbol_size;
+
+/* This is the offset of the symbol table in the executable file. */
+
+static unsigned symbol_table_offset;
+
+/* This is the offset of the string table in the executable file. */
+
+static unsigned string_table_offset;
+
+/* For elf+stab executables, the n_strx field is not a simple index
+ into the string table. Instead, each .o file has a base offset in
+ the string table, and the associated symbols contain offsets from
+ this base. The following two variables contain the base offset for
+ the current and next .o files. */
+
+static unsigned int file_string_table_offset;
+static unsigned int next_file_string_table_offset;
+
+/* .o and NLM files contain unrelocated addresses which are based at
+ 0. When non-zero, this flag disables some of the special cases for
+ Solaris elf+stab text addresses at location 0. */
+
+static int symfile_relocatable = 0;
+
+/* If this is nonzero, N_LBRAC, N_RBRAC, and N_SLINE entries are
+ relative to the function start address. */
+
+static int block_address_function_relative = 0;
+
+/* The lowest text address we have yet encountered. This is needed
+ because in an a.out file, there is no header field which tells us
+ what address the program is actually going to be loaded at, so we
+ need to make guesses based on the symbols (which *are* relocated to
+ reflect the address it will be loaded at). */
+
+static CORE_ADDR lowest_text_address;
+
+/* Non-zero if there is any line number info in the objfile. Prevents
+ end_psymtab from discarding an otherwise empty psymtab. */
+
+static int has_line_numbers;
+
+/* Complaints about the symbols we have encountered. */
+
+struct complaint lbrac_complaint =
+{"bad block start address patched", 0, 0};
+
+struct complaint string_table_offset_complaint =
+{"bad string table offset in symbol %d", 0, 0};
+
+struct complaint unknown_symtype_complaint =
+{"unknown symbol type %s", 0, 0};
+
+struct complaint unknown_symchar_complaint =
+{"unknown symbol descriptor `%c'", 0, 0};
+
+struct complaint lbrac_rbrac_complaint =
+{"block start larger than block end", 0, 0};
+
+struct complaint lbrac_unmatched_complaint =
+{"unmatched N_LBRAC before symtab pos %d", 0, 0};
+
+struct complaint lbrac_mismatch_complaint =
+{"N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d", 0, 0};
+
+struct complaint repeated_header_complaint =
+{"\"repeated\" header file %s not previously seen, at symtab pos %d", 0, 0};
+
+struct complaint unclaimed_bincl_complaint =
+{"N_BINCL %s not in entries for any file, at symtab pos %d", 0, 0};
+
+struct complaint discarding_local_symbols_complaint =
+{"misplaced N_LBRAC entry; discarding local symbols which have no enclosing block", 0, 0};
+
+/* find_text_range --- find start and end of loadable code sections
+
+ The find_text_range function finds the shortest address range that
+ encloses all sections containing executable code, and stores it in
+ objfile's text_addr and text_size members.
+
+ dbx_symfile_read will use this to finish off the partial symbol
+ table, in some cases. */
+
+static void
+find_text_range (bfd * sym_bfd, struct objfile *objfile)
+{
+ asection *sec;
+ int found_any = 0;
+ CORE_ADDR start = 0;
+ CORE_ADDR end = 0;
+
+ for (sec = sym_bfd->sections; sec; sec = sec->next)
+ if (bfd_get_section_flags (sym_bfd, sec) & SEC_CODE)
+ {
+ CORE_ADDR sec_start = bfd_section_vma (sym_bfd, sec);
+ CORE_ADDR sec_end = sec_start + bfd_section_size (sym_bfd, sec);
+
+ if (found_any)
+ {
+ if (sec_start < start)
+ start = sec_start;
+ if (sec_end > end)
+ end = sec_end;
+ }
+ else
+ {
+ start = sec_start;
+ end = sec_end;
+ }
+
+ found_any = 1;
+ }
+
+ if (!found_any)
+ error ("Can't find any code sections in symbol file");
+
+ DBX_TEXT_ADDR (objfile) = start;
+ DBX_TEXT_SIZE (objfile) = end - start;
+}
+
+
+
+/* During initial symbol readin, we need to have a structure to keep
+ track of which psymtabs have which bincls in them. This structure
+ is used during readin to setup the list of dependencies within each
+ partial symbol table. */
+
+struct header_file_location
+{
+ char *name; /* Name of header file */
+ int instance; /* See above */
+ struct partial_symtab *pst; /* Partial symtab that has the
+ BINCL/EINCL defs for this file */
+};
+
+/* The actual list and controling variables */
+static struct header_file_location *bincl_list, *next_bincl;
+static int bincls_allocated;
+
+/* Local function prototypes */
+
+extern void _initialize_dbxread (void);
+
+static void process_now (struct objfile *);
+
+static void read_ofile_symtab (struct partial_symtab *);
+
+static void dbx_psymtab_to_symtab (struct partial_symtab *);
+
+static void dbx_psymtab_to_symtab_1 (struct partial_symtab *);
+
+static void read_dbx_dynamic_symtab (struct objfile *objfile);
+
+static void read_dbx_symtab (struct objfile *);
+
+static void free_bincl_list (struct objfile *);
+
+static struct partial_symtab *find_corresponding_bincl_psymtab (char *, int);
+
+static void add_bincl_to_list (struct partial_symtab *, char *, int);
+
+static void init_bincl_list (int, struct objfile *);
+
+static char *dbx_next_symbol_text (struct objfile *);
+
+static void fill_symbuf (bfd *);
+
+static void dbx_symfile_init (struct objfile *);
+
+static void dbx_new_init (struct objfile *);
+
+static void dbx_symfile_read (struct objfile *, int);
+
+static void dbx_symfile_finish (struct objfile *);
+
+static void record_minimal_symbol (char *, CORE_ADDR, int, struct objfile *);
+
+static void add_new_header_file (char *, int);
+
+static void add_old_header_file (char *, int);
+
+static void add_this_object_header_file (int);
+
+static struct partial_symtab *start_psymtab (struct objfile *, char *,
+ CORE_ADDR, int,
+ struct partial_symbol **,
+ struct partial_symbol **);
+
+/* Free up old header file tables */
+
+void
+free_header_files (void)
+{
+ if (this_object_header_files)
+ {
+ xfree (this_object_header_files);
+ this_object_header_files = NULL;
+ }
+ n_allocated_this_object_header_files = 0;
+}
+
+/* Allocate new header file tables */
+
+void
+init_header_files (void)
+{
+ n_allocated_this_object_header_files = 10;
+ this_object_header_files = (int *) xmalloc (10 * sizeof (int));
+}
+
+/* Add header file number I for this object file
+ at the next successive FILENUM. */
+
+static void
+add_this_object_header_file (int i)
+{
+ if (n_this_object_header_files == n_allocated_this_object_header_files)
+ {
+ n_allocated_this_object_header_files *= 2;
+ this_object_header_files
+ = (int *) xrealloc ((char *) this_object_header_files,
+ n_allocated_this_object_header_files * sizeof (int));
+ }
+
+ this_object_header_files[n_this_object_header_files++] = i;
+}
+
+/* Add to this file an "old" header file, one already seen in
+ a previous object file. NAME is the header file's name.
+ INSTANCE is its instance code, to select among multiple
+ symbol tables for the same header file. */
+
+static void
+add_old_header_file (char *name, int instance)
+{
+ register struct header_file *p = HEADER_FILES (current_objfile);
+ register int i;
+
+ for (i = 0; i < N_HEADER_FILES (current_objfile); i++)
+ if (STREQ (p[i].name, name) && instance == p[i].instance)
+ {
+ add_this_object_header_file (i);
+ return;
+ }
+ complain (&repeated_header_complaint, name, symnum);
+}
+
+/* Add to this file a "new" header file: definitions for its types follow.
+ NAME is the header file's name.
+ Most often this happens only once for each distinct header file,
+ but not necessarily. If it happens more than once, INSTANCE has
+ a different value each time, and references to the header file
+ use INSTANCE values to select among them.
+
+ dbx output contains "begin" and "end" markers for each new header file,
+ but at this level we just need to know which files there have been;
+ so we record the file when its "begin" is seen and ignore the "end". */
+
+static void
+add_new_header_file (char *name, int instance)
+{
+ register int i;
+ register struct header_file *hfile;
+
+ /* Make sure there is room for one more header file. */
+
+ i = N_ALLOCATED_HEADER_FILES (current_objfile);
+
+ if (N_HEADER_FILES (current_objfile) == i)
+ {
+ if (i == 0)
+ {
+ N_ALLOCATED_HEADER_FILES (current_objfile) = 10;
+ HEADER_FILES (current_objfile) = (struct header_file *)
+ xmalloc (10 * sizeof (struct header_file));
+ }
+ else
+ {
+ i *= 2;
+ N_ALLOCATED_HEADER_FILES (current_objfile) = i;
+ HEADER_FILES (current_objfile) = (struct header_file *)
+ xrealloc ((char *) HEADER_FILES (current_objfile),
+ (i * sizeof (struct header_file)));
+ }
+ }
+
+ /* Create an entry for this header file. */
+
+ i = N_HEADER_FILES (current_objfile)++;
+ hfile = HEADER_FILES (current_objfile) + i;
+ hfile->name = savestring (name, strlen (name));
+ hfile->instance = instance;
+ hfile->length = 10;
+ hfile->vector
+ = (struct type **) xmalloc (10 * sizeof (struct type *));
+ memset (hfile->vector, 0, 10 * sizeof (struct type *));
+
+ add_this_object_header_file (i);
+}
+
+#if 0
+static struct type **
+explicit_lookup_type (int real_filenum, int index)
+{
+ register struct header_file *f = &HEADER_FILES (current_objfile)[real_filenum];
+
+ if (index >= f->length)
+ {
+ f->length *= 2;
+ f->vector = (struct type **)
+ xrealloc (f->vector, f->length * sizeof (struct type *));
+ memset (&f->vector[f->length / 2],
+ '\0', f->length * sizeof (struct type *) / 2);
+ }
+ return &f->vector[index];
+}
+#endif
+
+static void
+record_minimal_symbol (char *name, CORE_ADDR address, int type,
+ struct objfile *objfile)
+{
+ enum minimal_symbol_type ms_type;
+ int section;
+ asection *bfd_section;
+
+ switch (type)
+ {
+ case N_TEXT | N_EXT:
+ ms_type = mst_text;
+ section = SECT_OFF_TEXT (objfile);
+ bfd_section = DBX_TEXT_SECTION (objfile);
+ break;
+ case N_DATA | N_EXT:
+ ms_type = mst_data;
+ section = SECT_OFF_DATA (objfile);
+ bfd_section = DBX_DATA_SECTION (objfile);
+ break;
+ case N_BSS | N_EXT:
+ ms_type = mst_bss;
+ section = SECT_OFF_BSS (objfile);
+ bfd_section = DBX_BSS_SECTION (objfile);
+ break;
+ case N_ABS | N_EXT:
+ ms_type = mst_abs;
+ section = -1;
+ bfd_section = NULL;
+ break;
+#ifdef N_SETV
+ case N_SETV | N_EXT:
+ ms_type = mst_data;
+ section = SECT_OFF_DATA (objfile);
+ bfd_section = DBX_DATA_SECTION (objfile);
+ break;
+ case N_SETV:
+ /* I don't think this type actually exists; since a N_SETV is the result
+ of going over many .o files, it doesn't make sense to have one
+ file local. */
+ ms_type = mst_file_data;
+ section = SECT_OFF_DATA (objfile);
+ bfd_section = DBX_DATA_SECTION (objfile);
+ break;
+#endif
+ case N_TEXT:
+ case N_NBTEXT:
+ case N_FN:
+ case N_FN_SEQ:
+ ms_type = mst_file_text;
+ section = SECT_OFF_TEXT (objfile);
+ bfd_section = DBX_TEXT_SECTION (objfile);
+ break;
+ case N_DATA:
+ ms_type = mst_file_data;
+
+ /* Check for __DYNAMIC, which is used by Sun shared libraries.
+ Record it as global even if it's local, not global, so
+ lookup_minimal_symbol can find it. We don't check symbol_leading_char
+ because for SunOS4 it always is '_'. */
+ if (name[8] == 'C' && STREQ ("__DYNAMIC", name))
+ ms_type = mst_data;
+
+ /* Same with virtual function tables, both global and static. */
+ {
+ char *tempstring = name;
+ if (tempstring[0] == bfd_get_symbol_leading_char (objfile->obfd))
+ ++tempstring;
+ if (is_vtable_name (tempstring))
+ ms_type = mst_data;
+ }
+ section = SECT_OFF_DATA (objfile);
+ bfd_section = DBX_DATA_SECTION (objfile);
+ break;
+ case N_BSS:
+ ms_type = mst_file_bss;
+ section = SECT_OFF_BSS (objfile);
+ bfd_section = DBX_BSS_SECTION (objfile);
+ break;
+ default:
+ ms_type = mst_unknown;
+ section = -1;
+ bfd_section = NULL;
+ break;
+ }
+
+ if ((ms_type == mst_file_text || ms_type == mst_text)
+ && address < lowest_text_address)
+ lowest_text_address = address;
+
+ prim_record_minimal_symbol_and_info
+ (name, address, ms_type, NULL, section, bfd_section, objfile);
+}
+
+/* Scan and build partial symbols for a symbol file.
+ We have been initialized by a call to dbx_symfile_init, which
+ put all the relevant info into a "struct dbx_symfile_info",
+ hung off the objfile structure.
+
+ MAINLINE is true if we are reading the main symbol
+ table (as opposed to a shared lib or dynamically loaded file). */
+
+static void
+dbx_symfile_read (struct objfile *objfile, int mainline)
+{
+ bfd *sym_bfd;
+ int val;
+ struct cleanup *back_to;
+
+ sym_bfd = objfile->obfd;
+
+ /* .o and .nlm files are relocatables with text, data and bss segs based at
+ 0. This flag disables special (Solaris stabs-in-elf only) fixups for
+ symbols with a value of 0. */
+
+ symfile_relocatable = bfd_get_file_flags (sym_bfd) & HAS_RELOC;
+
+ /* This is true for Solaris (and all other systems which put stabs
+ in sections, hopefully, since it would be silly to do things
+ differently from Solaris), and false for SunOS4 and other a.out
+ file formats. */
+ block_address_function_relative =
+ ((0 == strncmp (bfd_get_target (sym_bfd), "elf", 3))
+ || (0 == strncmp (bfd_get_target (sym_bfd), "som", 3))
+ || (0 == strncmp (bfd_get_target (sym_bfd), "coff", 4))
+ || (0 == strncmp (bfd_get_target (sym_bfd), "pe", 2))
+ || (0 == strncmp (bfd_get_target (sym_bfd), "epoc-pe", 7))
+ || (0 == strncmp (bfd_get_target (sym_bfd), "nlm", 3)));
+
+ val = bfd_seek (sym_bfd, DBX_SYMTAB_OFFSET (objfile), SEEK_SET);
+ if (val < 0)
+ perror_with_name (objfile->name);
+
+ /* If we are reinitializing, or if we have never loaded syms yet, init */
+ if (mainline
+ || (objfile->global_psymbols.size == 0
+ && objfile->static_psymbols.size == 0))
+ init_psymbol_list (objfile, DBX_SYMCOUNT (objfile));
+
+ symbol_size = DBX_SYMBOL_SIZE (objfile);
+ symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
+
+ free_pending_blocks ();
+ back_to = make_cleanup (really_free_pendings, 0);
+
+ init_minimal_symbol_collection ();
+ make_cleanup_discard_minimal_symbols ();
+
+ /* Read stabs data from executable file and define symbols. */
+
+ read_dbx_symtab (objfile);
+
+ /* Add the dynamic symbols. */
+
+ read_dbx_dynamic_symtab (objfile);
+
+ /* Take the text ranges the STABS partial symbol scanner computed
+ for each of the psymtabs and convert it into the canonical form
+ for psymtabs. */
+ {
+ struct partial_symtab *p;
+
+ ALL_OBJFILE_PSYMTABS (objfile, p)
+ {
+ p->textlow = TEXTLOW (p);
+ p->texthigh = TEXTHIGH (p);
+ }
+ }
+
+ /* Install any minimal symbols that have been collected as the current
+ minimal symbols for this objfile. */
+
+ install_minimal_symbols (objfile);
+
+ do_cleanups (back_to);
+}
+
+/* Initialize anything that needs initializing when a completely new
+ symbol file is specified (not just adding some symbols from another
+ file, e.g. a shared library). */
+
+static void
+dbx_new_init (struct objfile *ignore)
+{
+ stabsread_new_init ();
+ buildsym_new_init ();
+ init_header_files ();
+}
+
+
+/* dbx_symfile_init ()
+ is the dbx-specific initialization routine for reading symbols.
+ It is passed a struct objfile which contains, among other things,
+ the BFD for the file whose symbols are being read, and a slot for a pointer
+ to "private data" which we fill with goodies.
+
+ We read the string table into malloc'd space and stash a pointer to it.
+
+ Since BFD doesn't know how to read debug symbols in a format-independent
+ way (and may never do so...), we have to do it ourselves. We will never
+ be called unless this is an a.out (or very similar) file.
+ FIXME, there should be a cleaner peephole into the BFD environment here. */
+
+#define DBX_STRINGTAB_SIZE_SIZE sizeof(long) /* FIXME */
+
+static void
+dbx_symfile_init (struct objfile *objfile)
+{
+ int val;
+ bfd *sym_bfd = objfile->obfd;
+ char *name = bfd_get_filename (sym_bfd);
+ asection *text_sect;
+ unsigned char size_temp[DBX_STRINGTAB_SIZE_SIZE];
+
+ /* Allocate struct to keep track of the symfile */
+ objfile->sym_stab_info = (struct dbx_symfile_info *)
+ xmmalloc (objfile->md, sizeof (struct dbx_symfile_info));
+ memset ((PTR) objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
+
+ DBX_TEXT_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".text");
+ DBX_DATA_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".data");
+ DBX_BSS_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".bss");
+
+ /* FIXME POKING INSIDE BFD DATA STRUCTURES */
+#define STRING_TABLE_OFFSET (sym_bfd->origin + obj_str_filepos (sym_bfd))
+#define SYMBOL_TABLE_OFFSET (sym_bfd->origin + obj_sym_filepos (sym_bfd))
+
+ /* FIXME POKING INSIDE BFD DATA STRUCTURES */
+
+ DBX_SYMFILE_INFO (objfile)->stab_section_info = NULL;
+
+ text_sect = bfd_get_section_by_name (sym_bfd, ".text");
+ if (!text_sect)
+ error ("Can't find .text section in symbol file");
+ DBX_TEXT_ADDR (objfile) = bfd_section_vma (sym_bfd, text_sect);
+ DBX_TEXT_SIZE (objfile) = bfd_section_size (sym_bfd, text_sect);
+
+ DBX_SYMBOL_SIZE (objfile) = obj_symbol_entry_size (sym_bfd);
+ DBX_SYMCOUNT (objfile) = bfd_get_symcount (sym_bfd);
+ DBX_SYMTAB_OFFSET (objfile) = SYMBOL_TABLE_OFFSET;
+
+ /* Read the string table and stash it away in the psymbol_obstack. It is
+ only needed as long as we need to expand psymbols into full symbols,
+ so when we blow away the psymbol the string table goes away as well.
+ Note that gdb used to use the results of attempting to malloc the
+ string table, based on the size it read, as a form of sanity check
+ for botched byte swapping, on the theory that a byte swapped string
+ table size would be so totally bogus that the malloc would fail. Now
+ that we put in on the psymbol_obstack, we can't do this since gdb gets
+ a fatal error (out of virtual memory) if the size is bogus. We can
+ however at least check to see if the size is less than the size of
+ the size field itself, or larger than the size of the entire file.
+ Note that all valid string tables have a size greater than zero, since
+ the bytes used to hold the size are included in the count. */
+
+ if (STRING_TABLE_OFFSET == 0)
+ {
+ /* It appears that with the existing bfd code, STRING_TABLE_OFFSET
+ will never be zero, even when there is no string table. This
+ would appear to be a bug in bfd. */
+ DBX_STRINGTAB_SIZE (objfile) = 0;
+ DBX_STRINGTAB (objfile) = NULL;
+ }
+ else
+ {
+ val = bfd_seek (sym_bfd, STRING_TABLE_OFFSET, SEEK_SET);
+ if (val < 0)
+ perror_with_name (name);
+
+ memset ((PTR) size_temp, 0, sizeof (size_temp));
+ val = bfd_bread ((PTR) size_temp, sizeof (size_temp), sym_bfd);
+ if (val < 0)
+ {
+ perror_with_name (name);
+ }
+ else if (val == 0)
+ {
+ /* With the existing bfd code, STRING_TABLE_OFFSET will be set to
+ EOF if there is no string table, and attempting to read the size
+ from EOF will read zero bytes. */
+ DBX_STRINGTAB_SIZE (objfile) = 0;
+ DBX_STRINGTAB (objfile) = NULL;
+ }
+ else
+ {
+ /* Read some data that would appear to be the string table size.
+ If there really is a string table, then it is probably the right
+ size. Byteswap if necessary and validate the size. Note that
+ the minimum is DBX_STRINGTAB_SIZE_SIZE. If we just read some
+ random data that happened to be at STRING_TABLE_OFFSET, because
+ bfd can't tell us there is no string table, the sanity checks may
+ or may not catch this. */
+ DBX_STRINGTAB_SIZE (objfile) = bfd_h_get_32 (sym_bfd, size_temp);
+
+ if (DBX_STRINGTAB_SIZE (objfile) < sizeof (size_temp)
+ || DBX_STRINGTAB_SIZE (objfile) > bfd_get_size (sym_bfd))
+ error ("ridiculous string table size (%d bytes).",
+ DBX_STRINGTAB_SIZE (objfile));
+
+ DBX_STRINGTAB (objfile) =
+ (char *) obstack_alloc (&objfile->psymbol_obstack,
+ DBX_STRINGTAB_SIZE (objfile));
+ OBJSTAT (objfile, sz_strtab += DBX_STRINGTAB_SIZE (objfile));
+
+ /* Now read in the string table in one big gulp. */
+
+ val = bfd_seek (sym_bfd, STRING_TABLE_OFFSET, SEEK_SET);
+ if (val < 0)
+ perror_with_name (name);
+ val = bfd_bread (DBX_STRINGTAB (objfile),
+ DBX_STRINGTAB_SIZE (objfile),
+ sym_bfd);
+ if (val != DBX_STRINGTAB_SIZE (objfile))
+ perror_with_name (name);
+ }
+ }
+}
+
+/* Perform any local cleanups required when we are done with a particular
+ objfile. I.E, we are in the process of discarding all symbol information
+ for an objfile, freeing up all memory held for it, and unlinking the
+ objfile struct from the global list of known objfiles. */
+
+static void
+dbx_symfile_finish (struct objfile *objfile)
+{
+ if (objfile->sym_stab_info != NULL)
+ {
+ if (HEADER_FILES (objfile) != NULL)
+ {
+ register int i = N_HEADER_FILES (objfile);
+ register struct header_file *hfiles = HEADER_FILES (objfile);
+
+ while (--i >= 0)
+ {
+ xfree (hfiles[i].name);
+ xfree (hfiles[i].vector);
+ }
+ xfree (hfiles);
+ }
+ xmfree (objfile->md, objfile->sym_stab_info);
+ }
+ free_header_files ();
+}
+
+
+/* Buffer for reading the symbol table entries. */
+static struct external_nlist symbuf[4096];
+static int symbuf_idx;
+static int symbuf_end;
+
+/* cont_elem is used for continuing information in cfront.
+ It saves information about which types need to be fixed up and
+ completed after all the stabs are read. */
+struct cont_elem
+ {
+ /* sym and stabstring for continuing information in cfront */
+ struct symbol *sym;
+ char *stabs;
+ /* state dependencies (statics that must be preserved) */
+ int sym_idx;
+ int sym_end;
+ int symnum;
+ int (*func) (struct objfile *, struct symbol *, char *);
+ /* other state dependencies include:
+ (assumption is that these will not change since process_now FIXME!!)
+ stringtab_global
+ n_stabs
+ objfile
+ symfile_bfd */
+ };
+
+static struct cont_elem *cont_list = 0;
+static int cont_limit = 0;
+static int cont_count = 0;
+
+/* Arrange for function F to be called with arguments SYM and P later
+ in the stabs reading process. */
+void
+process_later (struct symbol *sym, char *p,
+ int (*f) (struct objfile *, struct symbol *, char *))
+{
+
+ /* Allocate more space for the deferred list. */
+ if (cont_count >= cont_limit - 1)
+ {
+ cont_limit += 32; /* chunk size */
+
+ cont_list
+ = (struct cont_elem *) xrealloc (cont_list,
+ (cont_limit
+ * sizeof (struct cont_elem)));
+ if (!cont_list)
+ error ("Virtual memory exhausted\n");
+ }
+
+ /* Save state variables so we can process these stabs later. */
+ cont_list[cont_count].sym_idx = symbuf_idx;
+ cont_list[cont_count].sym_end = symbuf_end;
+ cont_list[cont_count].symnum = symnum;
+ cont_list[cont_count].sym = sym;
+ cont_list[cont_count].stabs = p;
+ cont_list[cont_count].func = f;
+ cont_count++;
+}
+
+/* Call deferred funtions in CONT_LIST. */
+
+static void
+process_now (struct objfile *objfile)
+{
+ int i;
+ int save_symbuf_idx;
+ int save_symbuf_end;
+ int save_symnum;
+ struct symbol *sym;
+ char *stabs;
+ int err;
+ int (*func) (struct objfile *, struct symbol *, char *);
+
+ /* Save the state of our caller, we'll want to restore it before
+ returning. */
+ save_symbuf_idx = symbuf_idx;
+ save_symbuf_end = symbuf_end;
+ save_symnum = symnum;
+
+ /* Iterate over all the deferred stabs. */
+ for (i = 0; i < cont_count; i++)
+ {
+ /* Restore the state for this deferred stab. */
+ symbuf_idx = cont_list[i].sym_idx;
+ symbuf_end = cont_list[i].sym_end;
+ symnum = cont_list[i].symnum;
+ sym = cont_list[i].sym;
+ stabs = cont_list[i].stabs;
+ func = cont_list[i].func;
+
+ /* Call the function to handle this deferrd stab. */
+ err = (*func) (objfile, sym, stabs);
+ if (err)
+ error ("Internal error: unable to resolve stab.\n");
+ }
+
+ /* Restore our caller's state. */
+ symbuf_idx = save_symbuf_idx;
+ symbuf_end = save_symbuf_end;
+ symnum = save_symnum;
+ cont_count = 0;
+}
+
+
+/* Name of last function encountered. Used in Solaris to approximate
+ object file boundaries. */
+static char *last_function_name;
+
+/* The address in memory of the string table of the object file we are
+ reading (which might not be the "main" object file, but might be a
+ shared library or some other dynamically loaded thing). This is
+ set by read_dbx_symtab when building psymtabs, and by
+ read_ofile_symtab when building symtabs, and is used only by
+ next_symbol_text. FIXME: If that is true, we don't need it when
+ building psymtabs, right? */
+static char *stringtab_global;
+
+/* These variables are used to control fill_symbuf when the stabs
+ symbols are not contiguous (as may be the case when a COFF file is
+ linked using --split-by-reloc). */
+static struct stab_section_list *symbuf_sections;
+static unsigned int symbuf_left;
+static unsigned int symbuf_read;
+
+/* Refill the symbol table input buffer
+ and set the variables that control fetching entries from it.
+ Reports an error if no data available.
+ This function can read past the end of the symbol table
+ (into the string table) but this does no harm. */
+
+static void
+fill_symbuf (bfd *sym_bfd)
+{
+ unsigned int count;
+ int nbytes;
+
+ if (symbuf_sections == NULL)
+ count = sizeof (symbuf);
+ else
+ {
+ if (symbuf_left <= 0)
+ {
+ file_ptr filepos = symbuf_sections->section->filepos;
+ if (bfd_seek (sym_bfd, filepos, SEEK_SET) != 0)
+ perror_with_name (bfd_get_filename (sym_bfd));
+ symbuf_left = bfd_section_size (sym_bfd, symbuf_sections->section);
+ symbol_table_offset = filepos - symbuf_read;
+ symbuf_sections = symbuf_sections->next;
+ }
+
+ count = symbuf_left;
+ if (count > sizeof (symbuf))
+ count = sizeof (symbuf);
+ }
+
+ nbytes = bfd_bread ((PTR) symbuf, count, sym_bfd);
+ if (nbytes < 0)
+ perror_with_name (bfd_get_filename (sym_bfd));
+ else if (nbytes == 0)
+ error ("Premature end of file reading symbol table");
+ symbuf_end = nbytes / symbol_size;
+ symbuf_idx = 0;
+ symbuf_left -= nbytes;
+ symbuf_read += nbytes;
+}
+
+#define INTERNALIZE_SYMBOL(intern, extern, abfd) \
+ { \
+ (intern).n_type = bfd_h_get_8 (abfd, (extern)->e_type); \
+ (intern).n_strx = bfd_h_get_32 (abfd, (extern)->e_strx); \
+ (intern).n_desc = bfd_h_get_16 (abfd, (extern)->e_desc); \
+ if (bfd_get_sign_extend_vma (abfd)) \
+ (intern).n_value = bfd_h_get_signed_32 (abfd, (extern)->e_value); \
+ else \
+ (intern).n_value = bfd_h_get_32 (abfd, (extern)->e_value); \
+ }
+
+/* Invariant: The symbol pointed to by symbuf_idx is the first one
+ that hasn't been swapped. Swap the symbol at the same time
+ that symbuf_idx is incremented. */
+
+/* dbx allows the text of a symbol name to be continued into the
+ next symbol name! When such a continuation is encountered
+ (a \ at the end of the text of a name)
+ call this function to get the continuation. */
+
+static char *
+dbx_next_symbol_text (struct objfile *objfile)
+{
+ struct internal_nlist nlist;
+
+ if (symbuf_idx == symbuf_end)
+ fill_symbuf (symfile_bfd);
+
+ symnum++;
+ INTERNALIZE_SYMBOL (nlist, &symbuf[symbuf_idx], symfile_bfd);
+ OBJSTAT (objfile, n_stabs++);
+
+ symbuf_idx++;
+
+ return nlist.n_strx + stringtab_global + file_string_table_offset;
+}
+
+/* Initialize the list of bincls to contain none and have some
+ allocated. */
+
+static void
+init_bincl_list (int number, struct objfile *objfile)
+{
+ bincls_allocated = number;
+ next_bincl = bincl_list = (struct header_file_location *)
+ xmmalloc (objfile->md, bincls_allocated * sizeof (struct header_file_location));
+}
+
+/* Add a bincl to the list. */
+
+static void
+add_bincl_to_list (struct partial_symtab *pst, char *name, int instance)
+{
+ if (next_bincl >= bincl_list + bincls_allocated)
+ {
+ int offset = next_bincl - bincl_list;
+ bincls_allocated *= 2;
+ bincl_list = (struct header_file_location *)
+ xmrealloc (pst->objfile->md, (char *) bincl_list,
+ bincls_allocated * sizeof (struct header_file_location));
+ next_bincl = bincl_list + offset;
+ }
+ next_bincl->pst = pst;
+ next_bincl->instance = instance;
+ next_bincl++->name = name;
+}
+
+/* Given a name, value pair, find the corresponding
+ bincl in the list. Return the partial symtab associated
+ with that header_file_location. */
+
+static struct partial_symtab *
+find_corresponding_bincl_psymtab (char *name, int instance)
+{
+ struct header_file_location *bincl;
+
+ for (bincl = bincl_list; bincl < next_bincl; bincl++)
+ if (bincl->instance == instance
+ && STREQ (name, bincl->name))
+ return bincl->pst;
+
+ complain (&repeated_header_complaint, name, symnum);
+ return (struct partial_symtab *) 0;
+}
+
+/* Free the storage allocated for the bincl list. */
+
+static void
+free_bincl_list (struct objfile *objfile)
+{
+ xmfree (objfile->md, (PTR) bincl_list);
+ bincls_allocated = 0;
+}
+
+static void
+do_free_bincl_list_cleanup (void *objfile)
+{
+ free_bincl_list (objfile);
+}
+
+static struct cleanup *
+make_cleanup_free_bincl_list (struct objfile *objfile)
+{
+ return make_cleanup (do_free_bincl_list_cleanup, objfile);
+}
+
+/* Set namestring based on nlist. If the string table index is invalid,
+ give a fake name, and print a single error message per symbol file read,
+ rather than abort the symbol reading or flood the user with messages. */
+
+static char *
+set_namestring (struct objfile *objfile, struct internal_nlist nlist)
+{
+ char *namestring;
+
+ if (((unsigned) nlist.n_strx + file_string_table_offset) >=
+ DBX_STRINGTAB_SIZE (objfile))
+ {
+ complain (&string_table_offset_complaint, symnum);
+ namestring = "<bad string table offset>";
+ }
+ else
+ namestring = nlist.n_strx + file_string_table_offset +
+ DBX_STRINGTAB (objfile);
+ return namestring;
+}
+
+/* Scan a SunOs dynamic symbol table for symbols of interest and
+ add them to the minimal symbol table. */
+
+static void
+read_dbx_dynamic_symtab (struct objfile *objfile)
+{
+ bfd *abfd = objfile->obfd;
+ struct cleanup *back_to;
+ int counter;
+ long dynsym_size;
+ long dynsym_count;
+ asymbol **dynsyms;
+ asymbol **symptr;
+ arelent **relptr;
+ long dynrel_size;
+ long dynrel_count;
+ arelent **dynrels;
+ CORE_ADDR sym_value;
+ char *name;
+
+ /* Check that the symbol file has dynamic symbols that we know about.
+ bfd_arch_unknown can happen if we are reading a sun3 symbol file
+ on a sun4 host (and vice versa) and bfd is not configured
+ --with-target=all. This would trigger an assertion in bfd/sunos.c,
+ so we ignore the dynamic symbols in this case. */
+ if (bfd_get_flavour (abfd) != bfd_target_aout_flavour
+ || (bfd_get_file_flags (abfd) & DYNAMIC) == 0
+ || bfd_get_arch (abfd) == bfd_arch_unknown)
+ return;
+
+ dynsym_size = bfd_get_dynamic_symtab_upper_bound (abfd);
+ if (dynsym_size < 0)
+ return;
+
+ dynsyms = (asymbol **) xmalloc (dynsym_size);
+ back_to = make_cleanup (xfree, dynsyms);
+
+ dynsym_count = bfd_canonicalize_dynamic_symtab (abfd, dynsyms);
+ if (dynsym_count < 0)
+ {
+ do_cleanups (back_to);
+ return;
+ }
+
+ /* Enter dynamic symbols into the minimal symbol table
+ if this is a stripped executable. */
+ if (bfd_get_symcount (abfd) <= 0)
+ {
+ symptr = dynsyms;
+ for (counter = 0; counter < dynsym_count; counter++, symptr++)
+ {
+ asymbol *sym = *symptr;
+ asection *sec;
+ int type;
+
+ sec = bfd_get_section (sym);
+
+ /* BFD symbols are section relative. */
+ sym_value = sym->value + sec->vma;
+
+ if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
+ {
+ sym_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ type = N_TEXT;
+ }
+ else if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
+ {
+ sym_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ type = N_DATA;
+ }
+ else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+ {
+ sym_value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+ type = N_BSS;
+ }
+ else
+ continue;
+
+ if (sym->flags & BSF_GLOBAL)
+ type |= N_EXT;
+
+ record_minimal_symbol ((char *) bfd_asymbol_name (sym), sym_value,
+ type, objfile);
+ }
+ }
+
+ /* Symbols from shared libraries have a dynamic relocation entry
+ that points to the associated slot in the procedure linkage table.
+ We make a mininal symbol table entry with type mst_solib_trampoline
+ at the address in the procedure linkage table. */
+ dynrel_size = bfd_get_dynamic_reloc_upper_bound (abfd);
+ if (dynrel_size < 0)
+ {
+ do_cleanups (back_to);
+ return;
+ }
+
+ dynrels = (arelent **) xmalloc (dynrel_size);
+ make_cleanup (xfree, dynrels);
+
+ dynrel_count = bfd_canonicalize_dynamic_reloc (abfd, dynrels, dynsyms);
+ if (dynrel_count < 0)
+ {
+ do_cleanups (back_to);
+ return;
+ }
+
+ for (counter = 0, relptr = dynrels;
+ counter < dynrel_count;
+ counter++, relptr++)
+ {
+ arelent *rel = *relptr;
+ CORE_ADDR address =
+ rel->address + ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_sparc:
+ if (rel->howto->type != RELOC_JMP_SLOT)
+ continue;
+ break;
+ case bfd_arch_m68k:
+ /* `16' is the type BFD produces for a jump table relocation. */
+ if (rel->howto->type != 16)
+ continue;
+
+ /* Adjust address in the jump table to point to
+ the start of the bsr instruction. */
+ address -= 2;
+ break;
+ default:
+ continue;
+ }
+
+ name = (char *) bfd_asymbol_name (*rel->sym_ptr_ptr);
+ prim_record_minimal_symbol (name, address, mst_solib_trampoline,
+ objfile);
+ }
+
+ do_cleanups (back_to);
+}
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+CORE_ADDR
+find_stab_function_addr (char *namestring, char *filename,
+ struct objfile *objfile)
+{
+ struct minimal_symbol *msym;
+ char *p;
+ int n;
+
+ p = strchr (namestring, ':');
+ if (p == NULL)
+ p = namestring;
+ n = p - namestring;
+ p = alloca (n + 2);
+ strncpy (p, namestring, n);
+ p[n] = 0;
+
+ msym = lookup_minimal_symbol (p, filename, objfile);
+ if (msym == NULL)
+ {
+ /* Sun Fortran appends an underscore to the minimal symbol name,
+ try again with an appended underscore if the minimal symbol
+ was not found. */
+ p[n] = '_';
+ p[n + 1] = 0;
+ msym = lookup_minimal_symbol (p, filename, objfile);
+ }
+
+ if (msym == NULL && filename != NULL)
+ {
+ /* Try again without the filename. */
+ p[n] = 0;
+ msym = lookup_minimal_symbol (p, NULL, objfile);
+ }
+ if (msym == NULL && filename != NULL)
+ {
+ /* And try again for Sun Fortran, but without the filename. */
+ p[n] = '_';
+ p[n + 1] = 0;
+ msym = lookup_minimal_symbol (p, NULL, objfile);
+ }
+
+ return msym == NULL ? 0 : SYMBOL_VALUE_ADDRESS (msym);
+}
+#endif /* SOFUN_ADDRESS_MAYBE_MISSING */
+
+/* Setup partial_symtab's describing each source file for which
+ debugging information is available. */
+
+static void
+read_dbx_symtab (struct objfile *objfile)
+{
+ register struct external_nlist *bufp = 0; /* =0 avoids gcc -Wall glitch */
+ struct internal_nlist nlist;
+ CORE_ADDR text_addr;
+ int text_size;
+
+ register char *namestring;
+ int nsl;
+ int past_first_source_file = 0;
+ CORE_ADDR last_o_file_start = 0;
+ CORE_ADDR last_function_start = 0;
+ struct cleanup *back_to;
+ bfd *abfd;
+ int textlow_not_set;
+
+ /* Current partial symtab */
+ struct partial_symtab *pst;
+
+ /* List of current psymtab's include files */
+ char **psymtab_include_list;
+ int includes_allocated;
+ int includes_used;
+
+ /* Index within current psymtab dependency list */
+ struct partial_symtab **dependency_list;
+ int dependencies_used, dependencies_allocated;
+
+ text_addr = DBX_TEXT_ADDR (objfile);
+ text_size = DBX_TEXT_SIZE (objfile);
+
+ /* FIXME. We probably want to change stringtab_global rather than add this
+ while processing every symbol entry. FIXME. */
+ file_string_table_offset = 0;
+ next_file_string_table_offset = 0;
+
+ stringtab_global = DBX_STRINGTAB (objfile);
+
+ pst = (struct partial_symtab *) 0;
+
+ includes_allocated = 30;
+ includes_used = 0;
+ psymtab_include_list = (char **) alloca (includes_allocated *
+ sizeof (char *));
+
+ dependencies_allocated = 30;
+ dependencies_used = 0;
+ dependency_list =
+ (struct partial_symtab **) alloca (dependencies_allocated *
+ sizeof (struct partial_symtab *));
+
+ /* Init bincl list */
+ init_bincl_list (20, objfile);
+ back_to = make_cleanup_free_bincl_list (objfile);
+
+ last_source_file = NULL;
+
+ lowest_text_address = (CORE_ADDR) -1;
+
+ symfile_bfd = objfile->obfd; /* For next_text_symbol */
+ abfd = objfile->obfd;
+ symbuf_end = symbuf_idx = 0;
+ next_symbol_text_func = dbx_next_symbol_text;
+ textlow_not_set = 1;
+ has_line_numbers = 0;
+
+ for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)
+ {
+ /* Get the symbol for this run and pull out some info */
+ QUIT; /* allow this to be interruptable */
+ if (symbuf_idx == symbuf_end)
+ fill_symbuf (abfd);
+ bufp = &symbuf[symbuf_idx++];
+
+ /*
+ * Special case to speed up readin.
+ */
+ if (bfd_h_get_8 (abfd, bufp->e_type) == N_SLINE)
+ {
+ has_line_numbers = 1;
+ continue;
+ }
+
+ INTERNALIZE_SYMBOL (nlist, bufp, abfd);
+ OBJSTAT (objfile, n_stabs++);
+
+ /* Ok. There is a lot of code duplicated in the rest of this
+ switch statement (for efficiency reasons). Since I don't
+ like duplicating code, I will do my penance here, and
+ describe the code which is duplicated:
+
+ *) The assignment to namestring.
+ *) The call to strchr.
+ *) The addition of a partial symbol the the two partial
+ symbol lists. This last is a large section of code, so
+ I've imbedded it in the following macro.
+ */
+
+ switch (nlist.n_type)
+ {
+ static struct complaint function_outside_compilation_unit = {
+ "function `%s' appears to be defined outside of all compilation units", 0, 0
+ };
+ char *p;
+ /*
+ * Standard, external, non-debugger, symbols
+ */
+
+ case N_TEXT | N_EXT:
+ case N_NBTEXT | N_EXT:
+ nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ goto record_it;
+
+ case N_DATA | N_EXT:
+ case N_NBDATA | N_EXT:
+ nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ goto record_it;
+
+ case N_BSS:
+ case N_BSS | N_EXT:
+ case N_NBBSS | N_EXT:
+ case N_SETV | N_EXT: /* FIXME, is this in BSS? */
+ nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+ goto record_it;
+
+ case N_ABS | N_EXT:
+ record_it:
+ namestring = set_namestring (objfile, nlist);
+
+ bss_ext_symbol:
+ record_minimal_symbol (namestring, nlist.n_value,
+ nlist.n_type, objfile); /* Always */
+ continue;
+
+ /* Standard, local, non-debugger, symbols */
+
+ case N_NBTEXT:
+
+ /* We need to be able to deal with both N_FN or N_TEXT,
+ because we have no way of knowing whether the sys-supplied ld
+ or GNU ld was used to make the executable. Sequents throw
+ in another wrinkle -- they renumbered N_FN. */
+
+ case N_FN:
+ case N_FN_SEQ:
+ case N_TEXT:
+ nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ namestring = set_namestring (objfile, nlist);
+
+ if ((namestring[0] == '-' && namestring[1] == 'l')
+ || (namestring[(nsl = strlen (namestring)) - 1] == 'o'
+ && namestring[nsl - 2] == '.'))
+ {
+ if (objfile->ei.entry_point < nlist.n_value &&
+ objfile->ei.entry_point >= last_o_file_start)
+ {
+ objfile->ei.entry_file_lowpc = last_o_file_start;
+ objfile->ei.entry_file_highpc = nlist.n_value;
+ }
+ if (past_first_source_file && pst
+ /* The gould NP1 uses low values for .o and -l symbols
+ which are not the address. */
+ && nlist.n_value >= TEXTLOW (pst))
+ {
+ end_psymtab (pst, psymtab_include_list, includes_used,
+ symnum * symbol_size,
+ nlist.n_value > TEXTHIGH (pst)
+ ? nlist.n_value : TEXTHIGH (pst),
+ dependency_list, dependencies_used, textlow_not_set);
+ pst = (struct partial_symtab *) 0;
+ includes_used = 0;
+ dependencies_used = 0;
+ }
+ else
+ past_first_source_file = 1;
+ last_o_file_start = nlist.n_value;
+ }
+ else
+ goto record_it;
+ continue;
+
+ case N_DATA:
+ nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ goto record_it;
+
+ case N_UNDF | N_EXT:
+ if (nlist.n_value != 0)
+ {
+ /* This is a "Fortran COMMON" symbol. See if the target
+ environment knows where it has been relocated to. */
+
+ CORE_ADDR reladdr;
+
+ namestring = set_namestring (objfile, nlist);
+ if (target_lookup_symbol (namestring, &reladdr))
+ {
+ continue; /* Error in lookup; ignore symbol for now. */
+ }
+ nlist.n_type ^= (N_BSS ^ N_UNDF); /* Define it as a bss-symbol */
+ nlist.n_value = reladdr;
+ goto bss_ext_symbol;
+ }
+ continue; /* Just undefined, not COMMON */
+
+ case N_UNDF:
+ if (processing_acc_compilation && nlist.n_strx == 1)
+ {
+ /* Deal with relative offsets in the string table
+ used in ELF+STAB under Solaris. If we want to use the
+ n_strx field, which contains the name of the file,
+ we must adjust file_string_table_offset *before* calling
+ set_namestring(). */
+ past_first_source_file = 1;
+ file_string_table_offset = next_file_string_table_offset;
+ next_file_string_table_offset =
+ file_string_table_offset + nlist.n_value;
+ if (next_file_string_table_offset < file_string_table_offset)
+ error ("string table offset backs up at %d", symnum);
+ /* FIXME -- replace error() with complaint. */
+ continue;
+ }
+ continue;
+
+ /* Lots of symbol types we can just ignore. */
+
+ case N_ABS:
+ case N_NBDATA:
+ case N_NBBSS:
+ continue;
+
+ /* Keep going . . . */
+
+ /*
+ * Special symbol types for GNU
+ */
+ case N_INDR:
+ case N_INDR | N_EXT:
+ case N_SETA:
+ case N_SETA | N_EXT:
+ case N_SETT:
+ case N_SETT | N_EXT:
+ case N_SETD:
+ case N_SETD | N_EXT:
+ case N_SETB:
+ case N_SETB | N_EXT:
+ case N_SETV:
+ continue;
+
+ /*
+ * Debugger symbols
+ */
+
+ case N_SO:
+ {
+ CORE_ADDR valu;
+ static int prev_so_symnum = -10;
+ static int first_so_symnum;
+ char *p;
+ int prev_textlow_not_set;
+
+ valu = nlist.n_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+ prev_textlow_not_set = textlow_not_set;
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ /* A zero value is probably an indication for the SunPRO 3.0
+ compiler. end_psymtab explicitly tests for zero, so
+ don't relocate it. */
+
+ if (nlist.n_value == 0)
+ {
+ textlow_not_set = 1;
+ valu = 0;
+ }
+ else
+ textlow_not_set = 0;
+#else
+ textlow_not_set = 0;
+#endif
+ past_first_source_file = 1;
+
+ if (prev_so_symnum != symnum - 1)
+ { /* Here if prev stab wasn't N_SO */
+ first_so_symnum = symnum;
+
+ if (pst)
+ {
+ end_psymtab (pst, psymtab_include_list, includes_used,
+ symnum * symbol_size,
+ valu > TEXTHIGH (pst) ? valu : TEXTHIGH (pst),
+ dependency_list, dependencies_used,
+ prev_textlow_not_set);
+ pst = (struct partial_symtab *) 0;
+ includes_used = 0;
+ dependencies_used = 0;
+ }
+ }
+
+ prev_so_symnum = symnum;
+
+ /* End the current partial symtab and start a new one */
+
+ namestring = set_namestring (objfile, nlist);
+
+ /* Null name means end of .o file. Don't start a new one. */
+ if (*namestring == '\000')
+ continue;
+
+ /* Some compilers (including gcc) emit a pair of initial N_SOs.
+ The first one is a directory name; the second the file name.
+ If pst exists, is empty, and has a filename ending in '/',
+ we assume the previous N_SO was a directory name. */
+
+ p = strrchr (namestring, '/');
+ if (p && *(p + 1) == '\000')
+ continue; /* Simply ignore directory name SOs */
+
+ /* Some other compilers (C++ ones in particular) emit useless
+ SOs for non-existant .c files. We ignore all subsequent SOs that
+ immediately follow the first. */
+
+ if (!pst)
+ pst = start_psymtab (objfile,
+ namestring, valu,
+ first_so_symnum * symbol_size,
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ continue;
+ }
+
+ case N_BINCL:
+ {
+ enum language tmp_language;
+ /* Add this bincl to the bincl_list for future EXCLs. No
+ need to save the string; it'll be around until
+ read_dbx_symtab function returns */
+
+ namestring = set_namestring (objfile, nlist);
+ tmp_language = deduce_language_from_filename (namestring);
+
+ /* Only change the psymtab's language if we've learned
+ something useful (eg. tmp_language is not language_unknown).
+ In addition, to match what start_subfile does, never change
+ from C++ to C. */
+ if (tmp_language != language_unknown
+ && (tmp_language != language_c
+ || psymtab_language != language_cplus))
+ psymtab_language = tmp_language;
+
+ if (pst == NULL)
+ {
+ /* FIXME: we should not get here without a PST to work on.
+ Attempt to recover. */
+ complain (&unclaimed_bincl_complaint, namestring, symnum);
+ continue;
+ }
+ add_bincl_to_list (pst, namestring, nlist.n_value);
+
+ /* Mark down an include file in the current psymtab */
+
+ goto record_include_file;
+ }
+
+ case N_SOL:
+ {
+ enum language tmp_language;
+ /* Mark down an include file in the current psymtab */
+
+ namestring = set_namestring (objfile, nlist);
+ tmp_language = deduce_language_from_filename (namestring);
+
+ /* Only change the psymtab's language if we've learned
+ something useful (eg. tmp_language is not language_unknown).
+ In addition, to match what start_subfile does, never change
+ from C++ to C. */
+ if (tmp_language != language_unknown
+ && (tmp_language != language_c
+ || psymtab_language != language_cplus))
+ psymtab_language = tmp_language;
+
+ /* In C++, one may expect the same filename to come round many
+ times, when code is coming alternately from the main file
+ and from inline functions in other files. So I check to see
+ if this is a file we've seen before -- either the main
+ source file, or a previously included file.
+
+ This seems to be a lot of time to be spending on N_SOL, but
+ things like "break c-exp.y:435" need to work (I
+ suppose the psymtab_include_list could be hashed or put
+ in a binary tree, if profiling shows this is a major hog). */
+ if (pst && STREQ (namestring, pst->filename))
+ continue;
+ {
+ register int i;
+ for (i = 0; i < includes_used; i++)
+ if (STREQ (namestring, psymtab_include_list[i]))
+ {
+ i = -1;
+ break;
+ }
+ if (i == -1)
+ continue;
+ }
+
+ record_include_file:
+
+ psymtab_include_list[includes_used++] = namestring;
+ if (includes_used >= includes_allocated)
+ {
+ char **orig = psymtab_include_list;
+
+ psymtab_include_list = (char **)
+ alloca ((includes_allocated *= 2) *
+ sizeof (char *));
+ memcpy ((PTR) psymtab_include_list, (PTR) orig,
+ includes_used * sizeof (char *));
+ }
+ continue;
+ }
+ case N_LSYM: /* Typedef or automatic variable. */
+ case N_STSYM: /* Data seg var -- static */
+ case N_LCSYM: /* BSS " */
+ case N_ROSYM: /* Read-only data seg var -- static. */
+ case N_NBSTS: /* Gould nobase. */
+ case N_NBLCS: /* symbols. */
+ case N_FUN:
+ case N_GSYM: /* Global (extern) variable; can be
+ data or bss (sigh FIXME). */
+
+ /* Following may probably be ignored; I'll leave them here
+ for now (until I do Pascal and Modula 2 extensions). */
+
+ case N_PC: /* I may or may not need this; I
+ suspect not. */
+ case N_M2C: /* I suspect that I can ignore this here. */
+ case N_SCOPE: /* Same. */
+
+ namestring = set_namestring (objfile, nlist);
+
+ /* See if this is an end of function stab. */
+ if (pst && nlist.n_type == N_FUN && *namestring == '\000')
+ {
+ CORE_ADDR valu;
+
+ /* It's value is the size (in bytes) of the function for
+ function relative stabs, or the address of the function's
+ end for old style stabs. */
+ valu = nlist.n_value + last_function_start;
+ if (TEXTHIGH (pst) == 0 || valu > TEXTHIGH (pst))
+ TEXTHIGH (pst) = valu;
+ break;
+ }
+
+ p = (char *) strchr (namestring, ':');
+ if (!p)
+ continue; /* Not a debugging symbol. */
+
+
+
+ /* Main processing section for debugging symbols which
+ the initial read through the symbol tables needs to worry
+ about. If we reach this point, the symbol which we are
+ considering is definitely one we are interested in.
+ p must also contain the (valid) index into the namestring
+ which indicates the debugging type symbol. */
+
+ switch (p[1])
+ {
+ case 'S':
+ nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+#ifdef STATIC_TRANSFORM_NAME
+ namestring = STATIC_TRANSFORM_NAME (namestring);
+#endif
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->static_psymbols,
+ 0, nlist.n_value,
+ psymtab_language, objfile);
+ continue;
+ case 'G':
+ nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ /* The addresses in these entries are reported to be
+ wrong. See the code that reads 'G's for symtabs. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->global_psymbols,
+ 0, nlist.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ case 'T':
+ /* When a 'T' entry is defining an anonymous enum, it
+ may have a name which is the empty string, or a
+ single space. Since they're not really defining a
+ symbol, those shouldn't go in the partial symbol
+ table. We do pick up the elements of such enums at
+ 'check_enum:', below. */
+ if (p >= namestring + 2
+ || (p == namestring + 1
+ && namestring[0] != ' '))
+ {
+ add_psymbol_to_list (namestring, p - namestring,
+ STRUCT_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ nlist.n_value, 0,
+ psymtab_language, objfile);
+ if (p[2] == 't')
+ {
+ /* Also a typedef with the same name. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ nlist.n_value, 0,
+ psymtab_language, objfile);
+ p += 1;
+ }
+ /* The semantics of C++ state that "struct foo { ... }"
+ also defines a typedef for "foo". Unfortuantely, cfront
+ never makes the typedef when translating from C++ to C.
+ We make the typedef here so that "ptype foo" works as
+ expected for cfront translated code. */
+ else if (psymtab_language == language_cplus)
+ {
+ /* Also a typedef with the same name. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ nlist.n_value, 0,
+ psymtab_language, objfile);
+ }
+ }
+ goto check_enum;
+ case 't':
+ if (p != namestring) /* a name is there, not just :T... */
+ {
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ nlist.n_value, 0,
+ psymtab_language, objfile);
+ }
+ check_enum:
+ /* If this is an enumerated type, we need to
+ add all the enum constants to the partial symbol
+ table. This does not cover enums without names, e.g.
+ "enum {a, b} c;" in C, but fortunately those are
+ rare. There is no way for GDB to find those from the
+ enum type without spending too much time on it. Thus
+ to solve this problem, the compiler needs to put out the
+ enum in a nameless type. GCC2 does this. */
+
+ /* We are looking for something of the form
+ <name> ":" ("t" | "T") [<number> "="] "e"
+ {<constant> ":" <value> ","} ";". */
+
+ /* Skip over the colon and the 't' or 'T'. */
+ p += 2;
+ /* This type may be given a number. Also, numbers can come
+ in pairs like (0,26). Skip over it. */
+ while ((*p >= '0' && *p <= '9')
+ || *p == '(' || *p == ',' || *p == ')'
+ || *p == '=')
+ p++;
+
+ if (*p++ == 'e')
+ {
+ /* The aix4 compiler emits extra crud before the members. */
+ if (*p == '-')
+ {
+ /* Skip over the type (?). */
+ while (*p != ':')
+ p++;
+
+ /* Skip over the colon. */
+ p++;
+ }
+
+ /* We have found an enumerated type. */
+ /* According to comments in read_enum_type
+ a comma could end it instead of a semicolon.
+ I don't know where that happens.
+ Accept either. */
+ while (*p && *p != ';' && *p != ',')
+ {
+ char *q;
+
+ /* Check for and handle cretinous dbx symbol name
+ continuation! */
+ if (*p == '\\' || (*p == '?' && p[1] == '\0'))
+ p = next_symbol_text (objfile);
+
+ /* Point to the character after the name
+ of the enum constant. */
+ for (q = p; *q && *q != ':'; q++)
+ ;
+ /* Note that the value doesn't matter for
+ enum constants in psymtabs, just in symtabs. */
+ add_psymbol_to_list (p, q - p,
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols, 0,
+ 0, psymtab_language, objfile);
+ /* Point past the name. */
+ p = q;
+ /* Skip over the value. */
+ while (*p && *p != ',')
+ p++;
+ /* Advance past the comma. */
+ if (*p)
+ p++;
+ }
+ }
+ continue;
+ case 'c':
+ /* Constant, e.g. from "const" in Pascal. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols, nlist.n_value,
+ 0, psymtab_language, objfile);
+ continue;
+
+ case 'f':
+ if (! pst)
+ {
+ int name_len = p - namestring;
+ char *name = xmalloc (name_len + 1);
+ memcpy (name, namestring, name_len);
+ name[name_len] = '\0';
+ complain (&function_outside_compilation_unit, name);
+ xfree (name);
+ }
+ nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ /* Kludges for ELF/STABS with Sun ACC */
+ last_function_name = namestring;
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ /* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
+ value for the bottom of the text seg in those cases. */
+ if (nlist.n_value == ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile)))
+ {
+ CORE_ADDR minsym_valu =
+ find_stab_function_addr (namestring, pst->filename, objfile);
+ /* find_stab_function_addr will return 0 if the minimal
+ symbol wasn't found. (Unfortunately, this might also
+ be a valid address.) Anyway, if it *does* return 0,
+ it is likely that the value was set correctly to begin
+ with... */
+ if (minsym_valu != 0)
+ nlist.n_value = minsym_valu;
+ }
+ if (pst && textlow_not_set)
+ {
+ TEXTLOW (pst) = nlist.n_value;
+ textlow_not_set = 0;
+ }
+#endif
+ /* End kludge. */
+
+ /* Keep track of the start of the last function so we
+ can handle end of function symbols. */
+ last_function_start = nlist.n_value;
+
+ /* In reordered executables this function may lie outside
+ the bounds created by N_SO symbols. If that's the case
+ use the address of this function as the low bound for
+ the partial symbol table. */
+ if (pst
+ && (textlow_not_set
+ || (nlist.n_value < TEXTLOW (pst)
+ && (nlist.n_value
+ != ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile))))))
+ {
+ TEXTLOW (pst) = nlist.n_value;
+ textlow_not_set = 0;
+ }
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->static_psymbols,
+ 0, nlist.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ /* Global functions were ignored here, but now they
+ are put into the global psymtab like one would expect.
+ They're also in the minimal symbol table. */
+ case 'F':
+ if (! pst)
+ {
+ int name_len = p - namestring;
+ char *name = xmalloc (name_len + 1);
+ memcpy (name, namestring, name_len);
+ name[name_len] = '\0';
+ complain (&function_outside_compilation_unit, name);
+ xfree (name);
+ }
+ nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ /* Kludges for ELF/STABS with Sun ACC */
+ last_function_name = namestring;
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ /* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
+ value for the bottom of the text seg in those cases. */
+ if (nlist.n_value == ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile)))
+ {
+ CORE_ADDR minsym_valu =
+ find_stab_function_addr (namestring, pst->filename, objfile);
+ /* find_stab_function_addr will return 0 if the minimal
+ symbol wasn't found. (Unfortunately, this might also
+ be a valid address.) Anyway, if it *does* return 0,
+ it is likely that the value was set correctly to begin
+ with... */
+ if (minsym_valu != 0)
+ nlist.n_value = minsym_valu;
+ }
+ if (pst && textlow_not_set)
+ {
+ TEXTLOW (pst) = nlist.n_value;
+ textlow_not_set = 0;
+ }
+#endif
+ /* End kludge. */
+
+ /* Keep track of the start of the last function so we
+ can handle end of function symbols. */
+ last_function_start = nlist.n_value;
+
+ /* In reordered executables this function may lie outside
+ the bounds created by N_SO symbols. If that's the case
+ use the address of this function as the low bound for
+ the partial symbol table. */
+ if (pst
+ && (textlow_not_set
+ || (nlist.n_value < TEXTLOW (pst)
+ && (nlist.n_value
+ != ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile))))))
+ {
+ TEXTLOW (pst) = nlist.n_value;
+ textlow_not_set = 0;
+ }
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->global_psymbols,
+ 0, nlist.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ /* Two things show up here (hopefully); static symbols of
+ local scope (static used inside braces) or extensions
+ of structure symbols. We can ignore both. */
+ case 'V':
+ case '(':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ case '#': /* for symbol identification (used in live ranges) */
+ /* added to support cfront stabs strings */
+ case 'Z': /* for definition continuations */
+ case 'P': /* for prototypes */
+ continue;
+
+ case ':':
+ /* It is a C++ nested symbol. We don't need to record it
+ (I don't think); if we try to look up foo::bar::baz,
+ then symbols for the symtab containing foo should get
+ read in, I think. */
+ /* Someone says sun cc puts out symbols like
+ /foo/baz/maclib::/usr/local/bin/maclib,
+ which would get here with a symbol type of ':'. */
+ continue;
+
+ default:
+ /* Unexpected symbol descriptor. The second and subsequent stabs
+ of a continued stab can show up here. The question is
+ whether they ever can mimic a normal stab--it would be
+ nice if not, since we certainly don't want to spend the
+ time searching to the end of every string looking for
+ a backslash. */
+
+ complain (&unknown_symchar_complaint, p[1]);
+
+ /* Ignore it; perhaps it is an extension that we don't
+ know about. */
+ continue;
+ }
+
+ case N_EXCL:
+
+ namestring = set_namestring (objfile, nlist);
+
+ /* Find the corresponding bincl and mark that psymtab on the
+ psymtab dependency list */
+ {
+ struct partial_symtab *needed_pst =
+ find_corresponding_bincl_psymtab (namestring, nlist.n_value);
+
+ /* If this include file was defined earlier in this file,
+ leave it alone. */
+ if (needed_pst == pst)
+ continue;
+
+ if (needed_pst)
+ {
+ int i;
+ int found = 0;
+
+ for (i = 0; i < dependencies_used; i++)
+ if (dependency_list[i] == needed_pst)
+ {
+ found = 1;
+ break;
+ }
+
+ /* If it's already in the list, skip the rest. */
+ if (found)
+ continue;
+
+ dependency_list[dependencies_used++] = needed_pst;
+ if (dependencies_used >= dependencies_allocated)
+ {
+ struct partial_symtab **orig = dependency_list;
+ dependency_list =
+ (struct partial_symtab **)
+ alloca ((dependencies_allocated *= 2)
+ * sizeof (struct partial_symtab *));
+ memcpy ((PTR) dependency_list, (PTR) orig,
+ (dependencies_used
+ * sizeof (struct partial_symtab *)));
+#ifdef DEBUG_INFO
+ fprintf_unfiltered (gdb_stderr, "Had to reallocate dependency list.\n");
+ fprintf_unfiltered (gdb_stderr, "New dependencies allocated: %d\n",
+ dependencies_allocated);
+#endif
+ }
+ }
+ }
+ continue;
+
+ case N_ENDM:
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ /* Solaris 2 end of module, finish current partial symbol table.
+ end_psymtab will set TEXTHIGH (pst) to the proper value, which
+ is necessary if a module compiled without debugging info
+ follows this module. */
+ if (pst)
+ {
+ end_psymtab (pst, psymtab_include_list, includes_used,
+ symnum * symbol_size,
+ (CORE_ADDR) 0,
+ dependency_list, dependencies_used, textlow_not_set);
+ pst = (struct partial_symtab *) 0;
+ includes_used = 0;
+ dependencies_used = 0;
+ }
+#endif
+ continue;
+
+ case N_RBRAC:
+#ifdef HANDLE_RBRAC
+ HANDLE_RBRAC (nlist.n_value);
+ continue;
+#endif
+ case N_EINCL:
+ case N_DSLINE:
+ case N_BSLINE:
+ case N_SSYM: /* Claim: Structure or union element.
+ Hopefully, I can ignore this. */
+ case N_ENTRY: /* Alternate entry point; can ignore. */
+ case N_MAIN: /* Can definitely ignore this. */
+ case N_CATCH: /* These are GNU C++ extensions */
+ case N_EHDECL: /* that can safely be ignored here. */
+ case N_LENG:
+ case N_BCOMM:
+ case N_ECOMM:
+ case N_ECOML:
+ case N_FNAME:
+ case N_SLINE:
+ case N_RSYM:
+ case N_PSYM:
+ case N_LBRAC:
+ case N_NSYMS: /* Ultrix 4.0: symbol count */
+ case N_DEFD: /* GNU Modula-2 */
+ case N_ALIAS: /* SunPro F77: alias name, ignore for now. */
+
+ case N_OBJ: /* useless types from Solaris */
+ case N_OPT:
+ /* These symbols aren't interesting; don't worry about them */
+
+ continue;
+
+ default:
+ /* If we haven't found it yet, ignore it. It's probably some
+ new type we don't know about yet. */
+ complain (&unknown_symtype_complaint,
+ local_hex_string (nlist.n_type));
+ continue;
+ }
+ }
+
+ /* If there's stuff to be cleaned up, clean it up. */
+ if (DBX_SYMCOUNT (objfile) > 0 /* We have some syms */
+ /*FIXME, does this have a bug at start address 0? */
+ && last_o_file_start
+ && objfile->ei.entry_point < nlist.n_value
+ && objfile->ei.entry_point >= last_o_file_start)
+ {
+ objfile->ei.entry_file_lowpc = last_o_file_start;
+ objfile->ei.entry_file_highpc = nlist.n_value;
+ }
+
+ if (pst)
+ {
+ /* Don't set pst->texthigh lower than it already is. */
+ CORE_ADDR text_end =
+ (lowest_text_address == (CORE_ADDR) -1
+ ? (text_addr + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)))
+ : lowest_text_address)
+ + text_size;
+
+ end_psymtab (pst, psymtab_include_list, includes_used,
+ symnum * symbol_size,
+ text_end > TEXTHIGH (pst) ? text_end : TEXTHIGH (pst),
+ dependency_list, dependencies_used, textlow_not_set);
+ }
+
+ do_cleanups (back_to);
+}
+
+/* Allocate and partially fill a partial symtab. It will be
+ completely filled at the end of the symbol list.
+
+ SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
+ is the address relative to which its symbols are (incremental) or 0
+ (normal). */
+
+
+static struct partial_symtab *
+start_psymtab (struct objfile *objfile, char *filename, CORE_ADDR textlow,
+ int ldsymoff, struct partial_symbol **global_syms,
+ struct partial_symbol **static_syms)
+{
+ struct partial_symtab *result =
+ start_psymtab_common (objfile, objfile->section_offsets,
+ filename, textlow, global_syms, static_syms);
+
+ result->read_symtab_private = (char *)
+ obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
+ TEXTLOW (result) = result->textlow;
+ TEXTHIGH (result) = result->texthigh;
+ LDSYMOFF (result) = ldsymoff;
+ result->read_symtab = dbx_psymtab_to_symtab;
+ SYMBOL_SIZE (result) = symbol_size;
+ SYMBOL_OFFSET (result) = symbol_table_offset;
+ STRING_OFFSET (result) = string_table_offset;
+ FILE_STRING_OFFSET (result) = file_string_table_offset;
+
+ /* If we're handling an ELF file, drag some section-relocation info
+ for this source file out of the ELF symbol table, to compensate for
+ Sun brain death. This replaces the section_offsets in this psymtab,
+ if successful. */
+ elfstab_offset_sections (objfile, result);
+
+ /* Deduce the source language from the filename for this psymtab. */
+ psymtab_language = deduce_language_from_filename (filename);
+
+ return result;
+}
+
+/* Close off the current usage of PST.
+ Returns PST or NULL if the partial symtab was empty and thrown away.
+
+ FIXME: List variables and peculiarities of same. */
+
+struct partial_symtab *
+end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes,
+ int capping_symbol_offset, CORE_ADDR capping_text,
+ struct partial_symtab **dependency_list, int number_dependencies,
+ int textlow_not_set)
+{
+ int i;
+ struct objfile *objfile = pst->objfile;
+
+ if (capping_symbol_offset != -1)
+ LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
+ TEXTHIGH (pst) = capping_text;
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ /* Under Solaris, the N_SO symbols always have a value of 0,
+ instead of the usual address of the .o file. Therefore,
+ we have to do some tricks to fill in texthigh and textlow.
+ The first trick is: if we see a static
+ or global function, and the textlow for the current pst
+ is not set (ie: textlow_not_set), then we use that function's
+ address for the textlow of the pst. */
+
+ /* Now, to fill in texthigh, we remember the last function seen
+ in the .o file. Also, there's a hack in
+ bfd/elf.c and gdb/elfread.c to pass the ELF st_size field
+ to here via the misc_info field. Therefore, we can fill in
+ a reliable texthigh by taking the address plus size of the
+ last function in the file. */
+
+ if (TEXTHIGH (pst) == 0 && last_function_name)
+ {
+ char *p;
+ int n;
+ struct minimal_symbol *minsym;
+
+ p = strchr (last_function_name, ':');
+ if (p == NULL)
+ p = last_function_name;
+ n = p - last_function_name;
+ p = alloca (n + 2);
+ strncpy (p, last_function_name, n);
+ p[n] = 0;
+
+ minsym = lookup_minimal_symbol (p, pst->filename, objfile);
+ if (minsym == NULL)
+ {
+ /* Sun Fortran appends an underscore to the minimal symbol name,
+ try again with an appended underscore if the minimal symbol
+ was not found. */
+ p[n] = '_';
+ p[n + 1] = 0;
+ minsym = lookup_minimal_symbol (p, pst->filename, objfile);
+ }
+
+ if (minsym)
+ TEXTHIGH (pst) = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym);
+
+ last_function_name = NULL;
+ }
+
+ /* this test will be true if the last .o file is only data */
+ if (textlow_not_set)
+ TEXTLOW (pst) = TEXTHIGH (pst);
+ else
+ {
+ struct partial_symtab *p1;
+
+ /* If we know our own starting text address, then walk through all other
+ psymtabs for this objfile, and if any didn't know their ending text
+ address, set it to our starting address. Take care to not set our
+ own ending address to our starting address, nor to set addresses on
+ `dependency' files that have both textlow and texthigh zero. */
+
+ ALL_OBJFILE_PSYMTABS (objfile, p1)
+ {
+ if (TEXTHIGH (p1) == 0 && TEXTLOW (p1) != 0 && p1 != pst)
+ {
+ TEXTHIGH (p1) = TEXTLOW (pst);
+ /* if this file has only data, then make textlow match texthigh */
+ if (TEXTLOW (p1) == 0)
+ TEXTLOW (p1) = TEXTHIGH (p1);
+ }
+ }
+ }
+
+ /* End of kludge for patching Solaris textlow and texthigh. */
+#endif /* SOFUN_ADDRESS_MAYBE_MISSING. */
+
+ pst->n_global_syms =
+ objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
+ pst->n_static_syms =
+ objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset);
+
+ pst->number_of_dependencies = number_dependencies;
+ if (number_dependencies)
+ {
+ pst->dependencies = (struct partial_symtab **)
+ obstack_alloc (&objfile->psymbol_obstack,
+ number_dependencies * sizeof (struct partial_symtab *));
+ memcpy (pst->dependencies, dependency_list,
+ number_dependencies * sizeof (struct partial_symtab *));
+ }
+ else
+ pst->dependencies = 0;
+
+ for (i = 0; i < num_includes; i++)
+ {
+ struct partial_symtab *subpst =
+ allocate_psymtab (include_list[i], objfile);
+
+ /* Copy the sesction_offsets array from the main psymtab. */
+ subpst->section_offsets = pst->section_offsets;
+ subpst->read_symtab_private =
+ (char *) obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct symloc));
+ LDSYMOFF (subpst) =
+ LDSYMLEN (subpst) =
+ TEXTLOW (subpst) =
+ TEXTHIGH (subpst) = 0;
+
+ /* We could save slight bits of space by only making one of these,
+ shared by the entire set of include files. FIXME-someday. */
+ subpst->dependencies = (struct partial_symtab **)
+ obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct partial_symtab *));
+ subpst->dependencies[0] = pst;
+ subpst->number_of_dependencies = 1;
+
+ subpst->globals_offset =
+ subpst->n_global_syms =
+ subpst->statics_offset =
+ subpst->n_static_syms = 0;
+
+ subpst->readin = 0;
+ subpst->symtab = 0;
+ subpst->read_symtab = pst->read_symtab;
+ }
+
+ sort_pst_symbols (pst);
+
+ /* If there is already a psymtab or symtab for a file of this name, remove it.
+ (If there is a symtab, more drastic things also happen.)
+ This happens in VxWorks. */
+ free_named_symtabs (pst->filename);
+
+ if (num_includes == 0
+ && number_dependencies == 0
+ && pst->n_global_syms == 0
+ && pst->n_static_syms == 0
+ && has_line_numbers == 0)
+ {
+ /* Throw away this psymtab, it's empty. We can't deallocate it, since
+ it is on the obstack, but we can forget to chain it on the list. */
+ /* Empty psymtabs happen as a result of header files which don't have
+ any symbols in them. There can be a lot of them. But this check
+ is wrong, in that a psymtab with N_SLINE entries but nothing else
+ is not empty, but we don't realize that. Fixing that without slowing
+ things down might be tricky. */
+
+ discard_psymtab (pst);
+
+ /* Indicate that psymtab was thrown away. */
+ pst = (struct partial_symtab *) NULL;
+ }
+ return pst;
+}
+
+static void
+dbx_psymtab_to_symtab_1 (struct partial_symtab *pst)
+{
+ struct cleanup *old_chain;
+ int i;
+
+ if (!pst)
+ return;
+
+ if (pst->readin)
+ {
+ fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
+ pst->filename);
+ return;
+ }
+
+ /* Read in all partial symtabs on which this one is dependent */
+ for (i = 0; i < pst->number_of_dependencies; i++)
+ if (!pst->dependencies[i]->readin)
+ {
+ /* Inform about additional files that need to be read in. */
+ if (info_verbose)
+ {
+ fputs_filtered (" ", gdb_stdout);
+ wrap_here ("");
+ fputs_filtered ("and ", gdb_stdout);
+ wrap_here ("");
+ printf_filtered ("%s...", pst->dependencies[i]->filename);
+ wrap_here (""); /* Flush output */
+ gdb_flush (gdb_stdout);
+ }
+ dbx_psymtab_to_symtab_1 (pst->dependencies[i]);
+ }
+
+ if (LDSYMLEN (pst)) /* Otherwise it's a dummy */
+ {
+ /* Init stuff necessary for reading in symbols */
+ stabsread_init ();
+ buildsym_init ();
+ old_chain = make_cleanup (really_free_pendings, 0);
+ file_string_table_offset = FILE_STRING_OFFSET (pst);
+ symbol_size = SYMBOL_SIZE (pst);
+
+ /* Read in this file's symbols */
+ bfd_seek (pst->objfile->obfd, SYMBOL_OFFSET (pst), SEEK_SET);
+ read_ofile_symtab (pst);
+ sort_symtab_syms (pst->symtab);
+
+ do_cleanups (old_chain);
+ }
+
+ pst->readin = 1;
+}
+
+/* Read in all of the symbols for a given psymtab for real.
+ Be verbose about it if the user wants that. */
+
+static void
+dbx_psymtab_to_symtab (struct partial_symtab *pst)
+{
+ bfd *sym_bfd;
+
+ if (!pst)
+ return;
+
+ if (pst->readin)
+ {
+ fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
+ pst->filename);
+ return;
+ }
+
+ if (LDSYMLEN (pst) || pst->number_of_dependencies)
+ {
+ /* Print the message now, before reading the string table,
+ to avoid disconcerting pauses. */
+ if (info_verbose)
+ {
+ printf_filtered ("Reading in symbols for %s...", pst->filename);
+ gdb_flush (gdb_stdout);
+ }
+
+ sym_bfd = pst->objfile->obfd;
+
+ next_symbol_text_func = dbx_next_symbol_text;
+
+ dbx_psymtab_to_symtab_1 (pst);
+
+ /* Match with global symbols. This only needs to be done once,
+ after all of the symtabs and dependencies have been read in. */
+ scan_file_globals (pst->objfile);
+
+ /* Finish up the debug error message. */
+ if (info_verbose)
+ printf_filtered ("done.\n");
+ }
+}
+
+/* Read in a defined section of a specific object file's symbols. */
+
+static void
+read_ofile_symtab (struct partial_symtab *pst)
+{
+ register char *namestring;
+ register struct external_nlist *bufp;
+ struct internal_nlist nlist;
+ unsigned char type;
+ unsigned max_symnum;
+ register bfd *abfd;
+ struct objfile *objfile;
+ int sym_offset; /* Offset to start of symbols to read */
+ int sym_size; /* Size of symbols to read */
+ CORE_ADDR text_offset; /* Start of text segment for symbols */
+ int text_size; /* Size of text segment for symbols */
+ struct section_offsets *section_offsets;
+
+ objfile = pst->objfile;
+ sym_offset = LDSYMOFF (pst);
+ sym_size = LDSYMLEN (pst);
+ text_offset = TEXTLOW (pst);
+ text_size = TEXTHIGH (pst) - TEXTLOW (pst);
+ /* This cannot be simply objfile->section_offsets because of
+ elfstab_offset_sections() which initializes the psymtab section
+ offsets information in a special way, and that is different from
+ objfile->section_offsets. */
+ section_offsets = pst->section_offsets;
+
+ current_objfile = objfile;
+ subfile_stack = NULL;
+
+ stringtab_global = DBX_STRINGTAB (objfile);
+ last_source_file = NULL;
+
+ abfd = objfile->obfd;
+ symfile_bfd = objfile->obfd; /* Implicit param to next_text_symbol */
+ symbuf_end = symbuf_idx = 0;
+
+ /* It is necessary to actually read one symbol *before* the start
+ of this symtab's symbols, because the GCC_COMPILED_FLAG_SYMBOL
+ occurs before the N_SO symbol.
+
+ Detecting this in read_dbx_symtab
+ would slow down initial readin, so we look for it here instead. */
+ if (!processing_acc_compilation && sym_offset >= (int) symbol_size)
+ {
+ bfd_seek (symfile_bfd, sym_offset - symbol_size, SEEK_CUR);
+ fill_symbuf (abfd);
+ bufp = &symbuf[symbuf_idx++];
+ INTERNALIZE_SYMBOL (nlist, bufp, abfd);
+ OBJSTAT (objfile, n_stabs++);
+
+ namestring = set_namestring (objfile, nlist);
+
+ processing_gcc_compilation = 0;
+ if (nlist.n_type == N_TEXT)
+ {
+ const char *tempstring = namestring;
+
+ if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL))
+ processing_gcc_compilation = 1;
+ else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL))
+ processing_gcc_compilation = 2;
+ if (tempstring[0] == bfd_get_symbol_leading_char (symfile_bfd))
+ ++tempstring;
+ if (STREQN (tempstring, "__gnu_compiled", 14))
+ processing_gcc_compilation = 2;
+ }
+
+ /* Try to select a C++ demangling based on the compilation unit
+ producer. */
+
+#if 0
+ /* For now, stay with AUTO_DEMANGLING for g++ output, as we don't
+ know whether it will use the old style or v3 mangling. */
+ if (processing_gcc_compilation)
+ {
+ if (AUTO_DEMANGLING)
+ {
+ set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+ }
+ }
+#endif
+ }
+ else
+ {
+ /* The N_SO starting this symtab is the first symbol, so we
+ better not check the symbol before it. I'm not this can
+ happen, but it doesn't hurt to check for it. */
+ bfd_seek (symfile_bfd, sym_offset, SEEK_CUR);
+ processing_gcc_compilation = 0;
+ }
+
+ if (symbuf_idx == symbuf_end)
+ fill_symbuf (abfd);
+ bufp = &symbuf[symbuf_idx];
+ if (bfd_h_get_8 (abfd, bufp->e_type) != N_SO)
+ error ("First symbol in segment of executable not a source symbol");
+
+ max_symnum = sym_size / symbol_size;
+
+ for (symnum = 0;
+ symnum < max_symnum;
+ symnum++)
+ {
+ QUIT; /* Allow this to be interruptable */
+ if (symbuf_idx == symbuf_end)
+ fill_symbuf (abfd);
+ bufp = &symbuf[symbuf_idx++];
+ INTERNALIZE_SYMBOL (nlist, bufp, abfd);
+ OBJSTAT (objfile, n_stabs++);
+
+ type = bfd_h_get_8 (abfd, bufp->e_type);
+
+ namestring = set_namestring (objfile, nlist);
+
+ if (type & N_STAB)
+ {
+ process_one_symbol (type, nlist.n_desc, nlist.n_value,
+ namestring, section_offsets, objfile);
+ }
+ /* We skip checking for a new .o or -l file; that should never
+ happen in this routine. */
+ else if (type == N_TEXT)
+ {
+ /* I don't think this code will ever be executed, because
+ the GCC_COMPILED_FLAG_SYMBOL usually is right before
+ the N_SO symbol which starts this source file.
+ However, there is no reason not to accept
+ the GCC_COMPILED_FLAG_SYMBOL anywhere. */
+
+ if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL))
+ processing_gcc_compilation = 1;
+ else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL))
+ processing_gcc_compilation = 2;
+
+#if 0
+ /* For now, stay with AUTO_DEMANGLING for g++ output, as we don't
+ know whether it will use the old style or v3 mangling. */
+ if (AUTO_DEMANGLING)
+ {
+ set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+ }
+#endif
+ }
+ else if (type & N_EXT || type == (unsigned char) N_TEXT
+ || type == (unsigned char) N_NBTEXT
+ )
+ {
+ /* Global symbol: see if we came across a dbx defintion for
+ a corresponding symbol. If so, store the value. Remove
+ syms from the chain when their values are stored, but
+ search the whole chain, as there may be several syms from
+ different files with the same name. */
+ /* This is probably not true. Since the files will be read
+ in one at a time, each reference to a global symbol will
+ be satisfied in each file as it appears. So we skip this
+ section. */
+ ;
+ }
+ }
+
+ current_objfile = NULL;
+
+ /* In a Solaris elf file, this variable, which comes from the
+ value of the N_SO symbol, will still be 0. Luckily, text_offset,
+ which comes from TEXTLOW (pst) is correct. */
+ if (last_source_start_addr == 0)
+ last_source_start_addr = text_offset;
+
+ /* In reordered executables last_source_start_addr may not be the
+ lower bound for this symtab, instead use text_offset which comes
+ from TEXTLOW (pst) which is correct. */
+ if (last_source_start_addr > text_offset)
+ last_source_start_addr = text_offset;
+
+ pst->symtab = end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT (objfile));
+
+ /* Process items which we had to "process_later" due to dependencies
+ on other stabs. */
+ process_now (objfile);
+
+ end_stabs ();
+}
+
+
+/* This handles a single symbol from the symbol-file, building symbols
+ into a GDB symtab. It takes these arguments and an implicit argument.
+
+ TYPE is the type field of the ".stab" symbol entry.
+ DESC is the desc field of the ".stab" entry.
+ VALU is the value field of the ".stab" entry.
+ NAME is the symbol name, in our address space.
+ SECTION_OFFSETS is a set of amounts by which the sections of this object
+ file were relocated when it was loaded into memory.
+ Note that these section_offsets are not the
+ objfile->section_offsets but the pst->section_offsets.
+ All symbols that refer
+ to memory locations need to be offset by these amounts.
+ OBJFILE is the object file from which we are reading symbols.
+ It is used in end_symtab. */
+
+void
+process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
+ struct section_offsets *section_offsets,
+ struct objfile *objfile)
+{
+#ifdef SUN_FIXED_LBRAC_BUG
+ /* If SUN_FIXED_LBRAC_BUG is defined, then it tells us whether we need
+ to correct the address of N_LBRAC's. If it is not defined, then
+ we never need to correct the addresses. */
+
+ /* This records the last pc address we've seen. We depend on there being
+ an SLINE or FUN or SO before the first LBRAC, since the variable does
+ not get reset in between reads of different symbol files. */
+ static CORE_ADDR last_pc_address;
+#endif
+
+ register struct context_stack *new;
+ /* This remembers the address of the start of a function. It is used
+ because in Solaris 2, N_LBRAC, N_RBRAC, and N_SLINE entries are
+ relative to the current function's start address. On systems
+ other than Solaris 2, this just holds the SECT_OFF_TEXT value, and is
+ used to relocate these symbol types rather than SECTION_OFFSETS. */
+ static CORE_ADDR function_start_offset;
+
+ /* This holds the address of the start of a function, without the system
+ peculiarities of function_start_offset. */
+ static CORE_ADDR last_function_start;
+
+ /* If this is nonzero, we've seen an N_SLINE since the start of the current
+ function. Initialized to nonzero to assure that last_function_start
+ is never used uninitialized. */
+ static int sline_found_in_function = 1;
+
+ /* If this is nonzero, we've seen a non-gcc N_OPT symbol for this source
+ file. Used to detect the SunPRO solaris compiler. */
+ static int n_opt_found;
+
+ /* The stab type used for the definition of the last function.
+ N_STSYM or N_GSYM for SunOS4 acc; N_FUN for other compilers. */
+ static int function_stab_type = 0;
+
+ if (!block_address_function_relative)
+ /* N_LBRAC, N_RBRAC and N_SLINE entries are not relative to the
+ function start address, so just use the text offset. */
+ function_start_offset = ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+
+ /* Something is wrong if we see real data before
+ seeing a source file name. */
+
+ if (last_source_file == NULL && type != (unsigned char) N_SO)
+ {
+ /* Ignore any symbols which appear before an N_SO symbol.
+ Currently no one puts symbols there, but we should deal
+ gracefully with the case. A complain()t might be in order,
+ but this should not be an error (). */
+ return;
+ }
+
+ switch (type)
+ {
+ case N_FUN:
+ case N_FNAME:
+
+ if (*name == '\000')
+ {
+ /* This N_FUN marks the end of a function. This closes off the
+ current block. */
+ record_line (current_subfile, 0, function_start_offset + valu);
+ within_function = 0;
+ new = pop_context ();
+
+ /* Make a block for the local symbols within. */
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ new->start_addr, new->start_addr + valu,
+ objfile);
+
+ /* May be switching to an assembler file which may not be using
+ block relative stabs, so reset the offset. */
+ if (block_address_function_relative)
+ function_start_offset = 0;
+
+ break;
+ }
+
+ sline_found_in_function = 0;
+
+ /* Relocate for dynamic loading */
+ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+ valu = SMASH_TEXT_ADDRESS (valu);
+ last_function_start = valu;
+
+ goto define_a_symbol;
+
+ case N_LBRAC:
+ /* This "symbol" just indicates the start of an inner lexical
+ context within a function. */
+
+ /* Ignore extra outermost context from SunPRO cc and acc. */
+ if (n_opt_found && desc == 1)
+ break;
+
+ if (block_address_function_relative)
+ /* Relocate for Sun ELF acc fn-relative syms. */
+ valu += function_start_offset;
+ else
+ /* On most machines, the block addresses are relative to the
+ N_SO, the linker did not relocate them (sigh). */
+ valu += last_source_start_addr;
+
+#ifdef SUN_FIXED_LBRAC_BUG
+ if (!SUN_FIXED_LBRAC_BUG && valu < last_pc_address)
+ {
+ /* Patch current LBRAC pc value to match last handy pc value */
+ complain (&lbrac_complaint);
+ valu = last_pc_address;
+ }
+#endif
+ new = push_context (desc, valu);
+ break;
+
+ case N_RBRAC:
+ /* This "symbol" just indicates the end of an inner lexical
+ context that was started with N_LBRAC. */
+
+ /* Ignore extra outermost context from SunPRO cc and acc. */
+ if (n_opt_found && desc == 1)
+ break;
+
+ if (block_address_function_relative)
+ /* Relocate for Sun ELF acc fn-relative syms. */
+ valu += function_start_offset;
+ else
+ /* On most machines, the block addresses are relative to the
+ N_SO, the linker did not relocate them (sigh). */
+ valu += last_source_start_addr;
+
+ new = pop_context ();
+ if (desc != new->depth)
+ complain (&lbrac_mismatch_complaint, symnum);
+
+ /* Some compilers put the variable decls inside of an
+ LBRAC/RBRAC block. This macro should be nonzero if this
+ is true. DESC is N_DESC from the N_RBRAC symbol.
+ GCC_P is true if we've detected the GCC_COMPILED_SYMBOL
+ or the GCC2_COMPILED_SYMBOL. */
+#if !defined (VARIABLES_INSIDE_BLOCK)
+#define VARIABLES_INSIDE_BLOCK(desc, gcc_p) 0
+#endif
+
+ /* Can only use new->locals as local symbols here if we're in
+ gcc or on a machine that puts them before the lbrack. */
+ if (!VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
+ {
+ if (local_symbols != NULL)
+ {
+ /* GCC development snapshots from March to December of
+ 2000 would output N_LSYM entries after N_LBRAC
+ entries. As a consequence, these symbols are simply
+ discarded. Complain if this is the case. Note that
+ there are some compilers which legitimately put local
+ symbols within an LBRAC/RBRAC block; this complaint
+ might also help sort out problems in which
+ VARIABLES_INSIDE_BLOCK is incorrectly defined. */
+ complain (&discarding_local_symbols_complaint);
+ }
+ local_symbols = new->locals;
+ }
+
+ if (context_stack_depth
+ > !VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
+ {
+ /* This is not the outermost LBRAC...RBRAC pair in the function,
+ its local symbols preceded it, and are the ones just recovered
+ from the context stack. Define the block for them (but don't
+ bother if the block contains no symbols. Should we complain
+ on blocks without symbols? I can't think of any useful purpose
+ for them). */
+ if (local_symbols != NULL)
+ {
+ /* Muzzle a compiler bug that makes end < start. (which
+ compilers? Is this ever harmful?). */
+ if (new->start_addr > valu)
+ {
+ complain (&lbrac_rbrac_complaint);
+ new->start_addr = valu;
+ }
+ /* Make a block for the local symbols within. */
+ finish_block (0, &local_symbols, new->old_blocks,
+ new->start_addr, valu, objfile);
+ }
+ }
+ else
+ {
+ /* This is the outermost LBRAC...RBRAC pair. There is no
+ need to do anything; leave the symbols that preceded it
+ to be attached to the function's own block. We need to
+ indicate that we just moved outside of the function. */
+ within_function = 0;
+ }
+
+ if (VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
+ /* Now pop locals of block just finished. */
+ local_symbols = new->locals;
+ break;
+
+ case N_FN:
+ case N_FN_SEQ:
+ /* This kind of symbol indicates the start of an object file. */
+ /* Relocate for dynamic loading */
+ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+ break;
+
+ case N_SO:
+ /* This type of symbol indicates the start of data
+ for one source file.
+ Finish the symbol table of the previous source file
+ (if any) and start accumulating a new symbol table. */
+ /* Relocate for dynamic loading */
+ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+
+ n_opt_found = 0;
+
+#ifdef SUN_FIXED_LBRAC_BUG
+ last_pc_address = valu; /* Save for SunOS bug circumcision */
+#endif
+
+#ifdef PCC_SOL_BROKEN
+ /* pcc bug, occasionally puts out SO for SOL. */
+ if (context_stack_depth > 0)
+ {
+ start_subfile (name, NULL);
+ break;
+ }
+#endif
+ if (last_source_file)
+ {
+ /* Check if previous symbol was also an N_SO (with some
+ sanity checks). If so, that one was actually the directory
+ name, and the current one is the real file name.
+ Patch things up. */
+ if (previous_stab_code == (unsigned char) N_SO)
+ {
+ patch_subfile_names (current_subfile, name);
+ break; /* Ignore repeated SOs */
+ }
+ end_symtab (valu, objfile, SECT_OFF_TEXT (objfile));
+ end_stabs ();
+ }
+
+ /* Null name means this just marks the end of text for this .o file.
+ Don't start a new symtab in this case. */
+ if (*name == '\000')
+ break;
+
+ if (block_address_function_relative)
+ function_start_offset = 0;
+
+ start_stabs ();
+ start_symtab (name, NULL, valu);
+ record_debugformat ("stabs");
+ break;
+
+ case N_SOL:
+ /* This type of symbol indicates the start of data for
+ a sub-source-file, one whose contents were copied or
+ included in the compilation of the main source file
+ (whose name was given in the N_SO symbol.) */
+ /* Relocate for dynamic loading */
+ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+ start_subfile (name, current_subfile->dirname);
+ break;
+
+ case N_BINCL:
+ push_subfile ();
+ add_new_header_file (name, valu);
+ start_subfile (name, current_subfile->dirname);
+ break;
+
+ case N_EINCL:
+ start_subfile (pop_subfile (), current_subfile->dirname);
+ break;
+
+ case N_EXCL:
+ add_old_header_file (name, valu);
+ break;
+
+ case N_SLINE:
+ /* This type of "symbol" really just records
+ one line-number -- core-address correspondence.
+ Enter it in the line list for this symbol table. */
+
+ /* Relocate for dynamic loading and for ELF acc fn-relative syms. */
+ valu += function_start_offset;
+
+#ifdef SUN_FIXED_LBRAC_BUG
+ last_pc_address = valu; /* Save for SunOS bug circumcision */
+#endif
+ /* If this is the first SLINE note in the function, record it at
+ the start of the function instead of at the listed location. */
+ if (within_function && sline_found_in_function == 0)
+ {
+ record_line (current_subfile, desc, last_function_start);
+ sline_found_in_function = 1;
+ }
+ else
+ record_line (current_subfile, desc, valu);
+ break;
+
+ case N_BCOMM:
+ common_block_start (name, objfile);
+ break;
+
+ case N_ECOMM:
+ common_block_end (objfile);
+ break;
+
+ /* The following symbol types need to have the appropriate offset added
+ to their value; then we process symbol definitions in the name. */
+
+ case N_STSYM: /* Static symbol in data seg */
+ case N_LCSYM: /* Static symbol in BSS seg */
+ case N_ROSYM: /* Static symbol in Read-only data seg */
+ /* HORRID HACK DEPT. However, it's Sun's furgin' fault.
+ Solaris2's stabs-in-elf makes *most* symbols relative
+ but leaves a few absolute (at least for Solaris 2.1 and version
+ 2.0.1 of the SunPRO compiler). N_STSYM and friends sit on the fence.
+ .stab "foo:S...",N_STSYM is absolute (ld relocates it)
+ .stab "foo:V...",N_STSYM is relative (section base subtracted).
+ This leaves us no choice but to search for the 'S' or 'V'...
+ (or pass the whole section_offsets stuff down ONE MORE function
+ call level, which we really don't want to do). */
+ {
+ char *p;
+
+ /* .o files and NLMs have non-zero text seg offsets, but don't need
+ their static syms offset in this fashion. XXX - This is really a
+ crock that should be fixed in the solib handling code so that I
+ don't have to work around it here. */
+
+ if (!symfile_relocatable)
+ {
+ p = strchr (name, ':');
+ if (p != 0 && p[1] == 'S')
+ {
+ /* The linker relocated it. We don't want to add an
+ elfstab_offset_sections-type offset, but we *do* want
+ to add whatever solib.c passed to symbol_file_add as
+ addr (this is known to affect SunOS4, and I suspect ELF
+ too). Since elfstab_offset_sections currently does not
+ muck with the text offset (there is no Ttext.text
+ symbol), we can get addr from the text offset. If
+ elfstab_offset_sections ever starts dealing with the
+ text offset, and we still need to do this, we need to
+ invent a SECT_OFF_ADDR_KLUDGE or something. */
+ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+ goto define_a_symbol;
+ }
+ }
+ /* Since it's not the kludge case, re-dispatch to the right handler. */
+ switch (type)
+ {
+ case N_STSYM:
+ goto case_N_STSYM;
+ case N_LCSYM:
+ goto case_N_LCSYM;
+ case N_ROSYM:
+ goto case_N_ROSYM;
+ default:
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+ }
+
+ case_N_STSYM: /* Static symbol in data seg */
+ case N_DSLINE: /* Source line number, data seg */
+ valu += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
+ goto define_a_symbol;
+
+ case_N_LCSYM: /* Static symbol in BSS seg */
+ case N_BSLINE: /* Source line number, bss seg */
+ /* N_BROWS: overlaps with N_BSLINE */
+ valu += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
+ goto define_a_symbol;
+
+ case_N_ROSYM: /* Static symbol in Read-only data seg */
+ valu += ANOFFSET (section_offsets, SECT_OFF_RODATA (objfile));
+ goto define_a_symbol;
+
+ case N_ENTRY: /* Alternate entry point */
+ /* Relocate for dynamic loading */
+ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+ goto define_a_symbol;
+
+ /* The following symbol types we don't know how to process. Handle
+ them in a "default" way, but complain to people who care. */
+ default:
+ case N_CATCH: /* Exception handler catcher */
+ case N_EHDECL: /* Exception handler name */
+ case N_PC: /* Global symbol in Pascal */
+ case N_M2C: /* Modula-2 compilation unit */
+ /* N_MOD2: overlaps with N_EHDECL */
+ case N_SCOPE: /* Modula-2 scope information */
+ case N_ECOML: /* End common (local name) */
+ case N_NBTEXT: /* Gould Non-Base-Register symbols??? */
+ case N_NBDATA:
+ case N_NBBSS:
+ case N_NBSTS:
+ case N_NBLCS:
+ complain (&unknown_symtype_complaint, local_hex_string (type));
+ /* FALLTHROUGH */
+
+ /* The following symbol types don't need the address field relocated,
+ since it is either unused, or is absolute. */
+ define_a_symbol:
+ case N_GSYM: /* Global variable */
+ case N_NSYMS: /* Number of symbols (ultrix) */
+ case N_NOMAP: /* No map? (ultrix) */
+ case N_RSYM: /* Register variable */
+ case N_DEFD: /* Modula-2 GNU module dependency */
+ case N_SSYM: /* Struct or union element */
+ case N_LSYM: /* Local symbol in stack */
+ case N_PSYM: /* Parameter variable */
+ case N_LENG: /* Length of preceding symbol type */
+ if (name)
+ {
+ int deftype;
+ char *colon_pos = strchr (name, ':');
+ if (colon_pos == NULL)
+ deftype = '\0';
+ else
+ deftype = colon_pos[1];
+
+ switch (deftype)
+ {
+ case 'f':
+ case 'F':
+ function_stab_type = type;
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ /* Deal with the SunPRO 3.0 compiler which omits the address
+ from N_FUN symbols. */
+ if (type == N_FUN
+ && valu == ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile)))
+ {
+ CORE_ADDR minsym_valu =
+ find_stab_function_addr (name, last_source_file, objfile);
+
+ /* find_stab_function_addr will return 0 if the minimal
+ symbol wasn't found. (Unfortunately, this might also
+ be a valid address.) Anyway, if it *does* return 0,
+ it is likely that the value was set correctly to begin
+ with... */
+ if (minsym_valu != 0)
+ valu = minsym_valu;
+ }
+#endif
+
+#ifdef SUN_FIXED_LBRAC_BUG
+ /* The Sun acc compiler, under SunOS4, puts out
+ functions with N_GSYM or N_STSYM. The problem is
+ that the address of the symbol is no good (for N_GSYM
+ it doesn't even attept an address; for N_STSYM it
+ puts out an address but then it gets relocated
+ relative to the data segment, not the text segment).
+ Currently we can't fix this up later as we do for
+ some types of symbol in scan_file_globals.
+ Fortunately we do have a way of finding the address -
+ we know that the value in last_pc_address is either
+ the one we want (if we're dealing with the first
+ function in an object file), or somewhere in the
+ previous function. This means that we can use the
+ minimal symbol table to get the address. */
+
+ /* Starting with release 3.0, the Sun acc compiler,
+ under SunOS4, puts out functions with N_FUN and a value
+ of zero. This gets relocated to the start of the text
+ segment of the module, which is no good either.
+ Under SunOS4 we can deal with this as N_SLINE and N_SO
+ entries contain valid absolute addresses.
+ Release 3.0 acc also puts out N_OPT entries, which makes
+ it possible to discern acc from cc or gcc. */
+
+ if (type == N_GSYM || type == N_STSYM
+ || (type == N_FUN
+ && n_opt_found && !block_address_function_relative))
+ {
+ struct minimal_symbol *m;
+ int l = colon_pos - name;
+
+ m = lookup_minimal_symbol_by_pc (last_pc_address);
+ if (m && STREQN (SYMBOL_NAME (m), name, l)
+ && SYMBOL_NAME (m)[l] == '\0')
+ /* last_pc_address was in this function */
+ valu = SYMBOL_VALUE (m);
+ else if (m && SYMBOL_NAME (m + 1)
+ && STREQN (SYMBOL_NAME (m + 1), name, l)
+ && SYMBOL_NAME (m + 1)[l] == '\0')
+ /* last_pc_address was in last function */
+ valu = SYMBOL_VALUE (m + 1);
+ else
+ /* Not found - use last_pc_address (for finish_block) */
+ valu = last_pc_address;
+ }
+
+ last_pc_address = valu; /* Save for SunOS bug circumcision */
+#endif
+
+ if (block_address_function_relative)
+ /* For Solaris 2.0 compilers, the block addresses and
+ N_SLINE's are relative to the start of the
+ function. On normal systems, and when using gcc on
+ Solaris 2.0, these addresses are just absolute, or
+ relative to the N_SO, depending on
+ BLOCK_ADDRESS_ABSOLUTE. */
+ function_start_offset = valu;
+
+ within_function = 1;
+
+ if (context_stack_depth > 1)
+ {
+ complain (&lbrac_unmatched_complaint, symnum);
+ break;
+ }
+
+ if (context_stack_depth > 0)
+ {
+ new = pop_context ();
+ /* Make a block for the local symbols within. */
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ new->start_addr, valu, objfile);
+ }
+
+ new = push_context (0, valu);
+ new->name = define_symbol (valu, name, desc, type, objfile);
+ break;
+
+ default:
+ define_symbol (valu, name, desc, type, objfile);
+ break;
+ }
+ }
+ break;
+
+ /* We use N_OPT to carry the gcc2_compiled flag. Sun uses it
+ for a bunch of other flags, too. Someday we may parse their
+ flags; for now we ignore theirs and hope they'll ignore ours. */
+ case N_OPT: /* Solaris 2: Compiler options */
+ if (name)
+ {
+ if (STREQ (name, GCC2_COMPILED_FLAG_SYMBOL))
+ {
+ processing_gcc_compilation = 2;
+#if 0 /* Works, but is experimental. -fnf */
+ /* For now, stay with AUTO_DEMANGLING for g++ output, as we don't
+ know whether it will use the old style or v3 mangling. */
+ if (AUTO_DEMANGLING)
+ {
+ set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+ }
+#endif
+ }
+ else
+ n_opt_found = 1;
+ }
+ break;
+
+ case N_MAIN: /* Name of main routine. */
+ /* FIXME: If one has a symbol file with N_MAIN and then replaces
+ it with a symbol file with "main" and without N_MAIN. I'm
+ not sure exactly what rule to follow but probably something
+ like: N_MAIN takes precedence over "main" no matter what
+ objfile it is in; If there is more than one N_MAIN, choose
+ the one in the symfile_objfile; If there is more than one
+ N_MAIN within a given objfile, complain() and choose
+ arbitrarily. (kingdon) */
+ if (name != NULL)
+ set_main_name (name);
+ break;
+
+ /* The following symbol types can be ignored. */
+ case N_OBJ: /* Solaris 2: Object file dir and name */
+ /* N_UNDF: Solaris 2: file separator mark */
+ /* N_UNDF: -- we will never encounter it, since we only process one
+ file's symbols at once. */
+ case N_ENDM: /* Solaris 2: End of module */
+ case N_ALIAS: /* SunPro F77: alias name, ignore for now. */
+ break;
+ }
+
+ /* '#' is a GNU C extension to allow one symbol to refer to another
+ related symbol.
+
+ Generally this is used so that an alias can refer to its main
+ symbol. */
+ if (name[0] == '#')
+ {
+ /* Initialize symbol reference names and determine if this is
+ a definition. If symbol reference is being defined, go
+ ahead and add it. Otherwise, just return sym. */
+
+ char *s = name;
+ int refnum;
+
+ /* If this stab defines a new reference ID that is not on the
+ reference list, then put it on the reference list.
+
+ We go ahead and advance NAME past the reference, even though
+ it is not strictly necessary at this time. */
+ refnum = symbol_reference_defined (&s);
+ if (refnum >= 0)
+ if (!ref_search (refnum))
+ ref_add (refnum, 0, name, valu);
+ name = s;
+ }
+
+
+ previous_stab_code = type;
+}
+
+/* FIXME: The only difference between this and elfstab_build_psymtabs
+ is the call to install_minimal_symbols for elf, and the support for
+ split sections. If the differences are really that small, the code
+ should be shared. */
+
+/* Scan and build partial symbols for an coff symbol file.
+ The coff file has already been processed to get its minimal symbols.
+
+ This routine is the equivalent of dbx_symfile_init and dbx_symfile_read
+ rolled into one.
+
+ OBJFILE is the object file we are reading symbols from.
+ ADDR is the address relative to which the symbols are (e.g.
+ the base address of the text segment).
+ MAINLINE is true if we are reading the main symbol
+ table (as opposed to a shared lib or dynamically loaded file).
+ TEXTADDR is the address of the text section.
+ TEXTSIZE is the size of the text section.
+ STABSECTS is the list of .stab sections in OBJFILE.
+ STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the
+ .stabstr section exists.
+
+ This routine is mostly copied from dbx_symfile_init and dbx_symfile_read,
+ adjusted for coff details. */
+
+void
+coffstab_build_psymtabs (struct objfile *objfile, int mainline,
+ CORE_ADDR textaddr, unsigned int textsize,
+ struct stab_section_list *stabsects,
+ file_ptr stabstroffset, unsigned int stabstrsize)
+{
+ int val;
+ bfd *sym_bfd = objfile->obfd;
+ char *name = bfd_get_filename (sym_bfd);
+ struct dbx_symfile_info *info;
+ unsigned int stabsize;
+
+ /* There is already a dbx_symfile_info allocated by our caller.
+ It might even contain some info from the coff symtab to help us. */
+ info = objfile->sym_stab_info;
+
+ DBX_TEXT_ADDR (objfile) = textaddr;
+ DBX_TEXT_SIZE (objfile) = textsize;
+
+#define COFF_STABS_SYMBOL_SIZE 12 /* XXX FIXME XXX */
+ DBX_SYMBOL_SIZE (objfile) = COFF_STABS_SYMBOL_SIZE;
+ DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
+
+ if (stabstrsize > bfd_get_size (sym_bfd))
+ error ("ridiculous string table size: %d bytes", stabstrsize);
+ DBX_STRINGTAB (objfile) = (char *)
+ obstack_alloc (&objfile->psymbol_obstack, stabstrsize + 1);
+ OBJSTAT (objfile, sz_strtab += stabstrsize + 1);
+
+ /* Now read in the string table in one big gulp. */
+
+ val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
+ if (val < 0)
+ perror_with_name (name);
+ val = bfd_bread (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
+ if (val != stabstrsize)
+ perror_with_name (name);
+
+ stabsread_new_init ();
+ buildsym_new_init ();
+ free_header_files ();
+ init_header_files ();
+
+ processing_acc_compilation = 1;
+
+ /* In a coff file, we've already installed the minimal symbols that came
+ from the coff (non-stab) symbol table, so always act like an
+ incremental load here. */
+ if (stabsects->next == NULL)
+ {
+ stabsize = bfd_section_size (sym_bfd, stabsects->section);
+ DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile);
+ DBX_SYMTAB_OFFSET (objfile) = stabsects->section->filepos;
+ }
+ else
+ {
+ struct stab_section_list *stabsect;
+
+ DBX_SYMCOUNT (objfile) = 0;
+ for (stabsect = stabsects; stabsect != NULL; stabsect = stabsect->next)
+ {
+ stabsize = bfd_section_size (sym_bfd, stabsect->section);
+ DBX_SYMCOUNT (objfile) += stabsize / DBX_SYMBOL_SIZE (objfile);
+ }
+
+ DBX_SYMTAB_OFFSET (objfile) = stabsects->section->filepos;
+
+ symbuf_sections = stabsects->next;
+ symbuf_left = bfd_section_size (sym_bfd, stabsects->section);
+ symbuf_read = 0;
+ }
+
+ dbx_symfile_read (objfile, 0);
+}
+
+/* Scan and build partial symbols for an ELF symbol file.
+ This ELF file has already been processed to get its minimal symbols,
+ and any DWARF symbols that were in it.
+
+ This routine is the equivalent of dbx_symfile_init and dbx_symfile_read
+ rolled into one.
+
+ OBJFILE is the object file we are reading symbols from.
+ ADDR is the address relative to which the symbols are (e.g.
+ the base address of the text segment).
+ MAINLINE is true if we are reading the main symbol
+ table (as opposed to a shared lib or dynamically loaded file).
+ STABOFFSET and STABSIZE define the location in OBJFILE where the .stab
+ section exists.
+ STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the
+ .stabstr section exists.
+
+ This routine is mostly copied from dbx_symfile_init and dbx_symfile_read,
+ adjusted for elf details. */
+
+void
+elfstab_build_psymtabs (struct objfile *objfile, int mainline,
+ file_ptr staboffset, unsigned int stabsize,
+ file_ptr stabstroffset, unsigned int stabstrsize)
+{
+ int val;
+ bfd *sym_bfd = objfile->obfd;
+ char *name = bfd_get_filename (sym_bfd);
+ struct dbx_symfile_info *info;
+
+ /* There is already a dbx_symfile_info allocated by our caller.
+ It might even contain some info from the ELF symtab to help us. */
+ info = objfile->sym_stab_info;
+
+ /* Find the first and last text address. dbx_symfile_read seems to
+ want this. */
+ find_text_range (sym_bfd, objfile);
+
+#define ELF_STABS_SYMBOL_SIZE 12 /* XXX FIXME XXX */
+ DBX_SYMBOL_SIZE (objfile) = ELF_STABS_SYMBOL_SIZE;
+ DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile);
+ DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
+ DBX_SYMTAB_OFFSET (objfile) = staboffset;
+
+ if (stabstrsize > bfd_get_size (sym_bfd))
+ error ("ridiculous string table size: %d bytes", stabstrsize);
+ DBX_STRINGTAB (objfile) = (char *)
+ obstack_alloc (&objfile->psymbol_obstack, stabstrsize + 1);
+ OBJSTAT (objfile, sz_strtab += stabstrsize + 1);
+
+ /* Now read in the string table in one big gulp. */
+
+ val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
+ if (val < 0)
+ perror_with_name (name);
+ val = bfd_bread (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
+ if (val != stabstrsize)
+ perror_with_name (name);
+
+ stabsread_new_init ();
+ buildsym_new_init ();
+ free_header_files ();
+ init_header_files ();
+ install_minimal_symbols (objfile);
+
+ processing_acc_compilation = 1;
+
+ /* In an elf file, we've already installed the minimal symbols that came
+ from the elf (non-stab) symbol table, so always act like an
+ incremental load here. */
+ dbx_symfile_read (objfile, 0);
+}
+
+/* Scan and build partial symbols for a file with special sections for stabs
+ and stabstrings. The file has already been processed to get its minimal
+ symbols, and any other symbols that might be necessary to resolve GSYMs.
+
+ This routine is the equivalent of dbx_symfile_init and dbx_symfile_read
+ rolled into one.
+
+ OBJFILE is the object file we are reading symbols from.
+ ADDR is the address relative to which the symbols are (e.g. the base address
+ of the text segment).
+ MAINLINE is true if we are reading the main symbol table (as opposed to a
+ shared lib or dynamically loaded file).
+ STAB_NAME is the name of the section that contains the stabs.
+ STABSTR_NAME is the name of the section that contains the stab strings.
+
+ This routine is mostly copied from dbx_symfile_init and dbx_symfile_read. */
+
+void
+stabsect_build_psymtabs (struct objfile *objfile, int mainline, char *stab_name,
+ char *stabstr_name, char *text_name)
+{
+ int val;
+ bfd *sym_bfd = objfile->obfd;
+ char *name = bfd_get_filename (sym_bfd);
+ asection *stabsect;
+ asection *stabstrsect;
+ asection *text_sect;
+
+ stabsect = bfd_get_section_by_name (sym_bfd, stab_name);
+ stabstrsect = bfd_get_section_by_name (sym_bfd, stabstr_name);
+
+ if (!stabsect)
+ return;
+
+ if (!stabstrsect)
+ error ("stabsect_build_psymtabs: Found stabs (%s), but not string section (%s)",
+ stab_name, stabstr_name);
+
+ objfile->sym_stab_info = (struct dbx_symfile_info *)
+ xmalloc (sizeof (struct dbx_symfile_info));
+ memset (objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
+
+ text_sect = bfd_get_section_by_name (sym_bfd, text_name);
+ if (!text_sect)
+ error ("Can't find %s section in symbol file", text_name);
+ DBX_TEXT_ADDR (objfile) = bfd_section_vma (sym_bfd, text_sect);
+ DBX_TEXT_SIZE (objfile) = bfd_section_size (sym_bfd, text_sect);
+
+ DBX_SYMBOL_SIZE (objfile) = sizeof (struct external_nlist);
+ DBX_SYMCOUNT (objfile) = bfd_section_size (sym_bfd, stabsect)
+ / DBX_SYMBOL_SIZE (objfile);
+ DBX_STRINGTAB_SIZE (objfile) = bfd_section_size (sym_bfd, stabstrsect);
+ DBX_SYMTAB_OFFSET (objfile) = stabsect->filepos; /* XXX - FIXME: POKING INSIDE BFD DATA STRUCTURES */
+
+ if (DBX_STRINGTAB_SIZE (objfile) > bfd_get_size (sym_bfd))
+ error ("ridiculous string table size: %d bytes", DBX_STRINGTAB_SIZE (objfile));
+ DBX_STRINGTAB (objfile) = (char *)
+ obstack_alloc (&objfile->psymbol_obstack, DBX_STRINGTAB_SIZE (objfile) + 1);
+ OBJSTAT (objfile, sz_strtab += DBX_STRINGTAB_SIZE (objfile) + 1);
+
+ /* Now read in the string table in one big gulp. */
+
+ val = bfd_get_section_contents (sym_bfd, /* bfd */
+ stabstrsect, /* bfd section */
+ DBX_STRINGTAB (objfile), /* input buffer */
+ 0, /* offset into section */
+ DBX_STRINGTAB_SIZE (objfile)); /* amount to read */
+
+ if (!val)
+ perror_with_name (name);
+
+ stabsread_new_init ();
+ buildsym_new_init ();
+ free_header_files ();
+ init_header_files ();
+ install_minimal_symbols (objfile);
+
+ /* Now, do an incremental load */
+
+ processing_acc_compilation = 1;
+ dbx_symfile_read (objfile, 0);
+}
+
+static struct sym_fns aout_sym_fns =
+{
+ bfd_target_aout_flavour,
+ dbx_new_init, /* sym_new_init: init anything gbl to entire symtab */
+ dbx_symfile_init, /* sym_init: read initial info, setup for sym_read() */
+ dbx_symfile_read, /* sym_read: read a symbol file into symtab */
+ dbx_symfile_finish, /* sym_finish: finished with file, cleanup */
+ default_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
+ NULL /* next: pointer to next struct sym_fns */
+};
+
+void
+_initialize_dbxread (void)
+{
+ add_symtab_fns (&aout_sym_fns);
+}
diff --git a/gdb/dcache.c b/gdb/dcache.c
new file mode 100644
index 00000000000..6e742746363
--- /dev/null
+++ b/gdb/dcache.c
@@ -0,0 +1,603 @@
+/* Caching code.
+ Copyright 1992, 1993, 1995, 1996, 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "dcache.h"
+#include "gdbcmd.h"
+#include "gdb_string.h"
+#include "gdbcore.h"
+#include "target.h"
+
+/* The data cache could lead to incorrect results because it doesn't
+ know about volatile variables, thus making it impossible to debug
+ functions which use memory mapped I/O devices. Set the nocache
+ memory region attribute in those cases.
+
+ In general the dcache speeds up performance, some speed improvement
+ comes from the actual caching mechanism, but the major gain is in
+ the reduction of the remote protocol overhead; instead of reading
+ or writing a large area of memory in 4 byte requests, the cache
+ bundles up the requests into 32 byte (actually LINE_SIZE) chunks.
+ Reducing the overhead to an eighth of what it was. This is very
+ obvious when displaying a large amount of data,
+
+ eg, x/200x 0
+
+ caching | no yes
+ ----------------------------
+ first time | 4 sec 2 sec improvement due to chunking
+ second time | 4 sec 0 sec improvement due to caching
+
+ The cache structure is unusual, we keep a number of cache blocks
+ (DCACHE_SIZE) and each one caches a LINE_SIZEed area of memory.
+ Within each line we remember the address of the line (always a
+ multiple of the LINE_SIZE) and a vector of bytes over the range.
+ There's another vector which contains the state of the bytes.
+
+ ENTRY_BAD means that the byte is just plain wrong, and has no
+ correspondence with anything else (as it would when the cache is
+ turned on, but nothing has been done to it.
+
+ ENTRY_DIRTY means that the byte has some data in it which should be
+ written out to the remote target one day, but contains correct
+ data.
+
+ ENTRY_OK means that the data is the same in the cache as it is in
+ remote memory.
+
+
+ The ENTRY_DIRTY state is necessary because GDB likes to write large
+ lumps of memory in small bits. If the caching mechanism didn't
+ maintain the DIRTY information, then something like a two byte
+ write would mean that the entire cache line would have to be read,
+ the two bytes modified and then written out again. The alternative
+ would be to not read in the cache line in the first place, and just
+ write the two bytes directly into target memory. The trouble with
+ that is that it really nails performance, because of the remote
+ protocol overhead. This way, all those little writes are bundled
+ up into an entire cache line write in one go, without having to
+ read the cache line in the first place.
+ */
+
+/* NOTE: Interaction of dcache and memory region attributes
+
+ As there is no requirement that memory region attributes be aligned
+ to or be a multiple of the dcache page size, dcache_read_line() and
+ dcache_write_line() must break up the page by memory region. If a
+ chunk does not have the cache attribute set, an invalid memory type
+ is set, etc., then the chunk is skipped. Those chunks are handled
+ in target_xfer_memory() (or target_xfer_memory_partial()).
+
+ This doesn't occur very often. The most common occurance is when
+ the last bit of the .text segment and the first bit of the .data
+ segment fall within the same dcache page with a ro/cacheable memory
+ region defined for the .text segment and a rw/non-cacheable memory
+ region defined for the .data segment. */
+
+/* This value regulates the number of cache blocks stored.
+ Smaller values reduce the time spent searching for a cache
+ line, and reduce memory requirements, but increase the risk
+ of a line not being in memory */
+
+#define DCACHE_SIZE 64
+
+/* This value regulates the size of a cache line. Smaller values
+ reduce the time taken to read a single byte, but reduce overall
+ throughput. */
+
+#define LINE_SIZE_POWER (5)
+#define LINE_SIZE (1 << LINE_SIZE_POWER)
+
+/* Each cache block holds LINE_SIZE bytes of data
+ starting at a multiple-of-LINE_SIZE address. */
+
+#define LINE_SIZE_MASK ((LINE_SIZE - 1))
+#define XFORM(x) ((x) & LINE_SIZE_MASK)
+#define MASK(x) ((x) & ~LINE_SIZE_MASK)
+
+
+#define ENTRY_BAD 0 /* data at this byte is wrong */
+#define ENTRY_DIRTY 1 /* data at this byte needs to be written back */
+#define ENTRY_OK 2 /* data at this byte is same as in memory */
+
+
+struct dcache_block
+ {
+ struct dcache_block *p; /* next in list */
+ CORE_ADDR addr; /* Address for which data is recorded. */
+ char data[LINE_SIZE]; /* bytes at given address */
+ unsigned char state[LINE_SIZE]; /* what state the data is in */
+
+ /* whether anything in state is dirty - used to speed up the
+ dirty scan. */
+ int anydirty;
+
+ int refs;
+ };
+
+
+/* FIXME: dcache_struct used to have a cache_has_stuff field that was
+ used to record whether the cache had been accessed. This was used
+ to invalidate the cache whenever caching was (re-)enabled (if the
+ cache was disabled and later re-enabled, it could contain stale
+ data). This was not needed because the cache is write through and
+ the code that enables, disables, and deletes memory region all
+ invalidate the cache.
+
+ This is overkill, since it also invalidates cache lines from
+ unrelated regions. One way this could be addressed by adding a
+ new function that takes an address and a length and invalidates
+ only those cache lines that match. */
+
+struct dcache_struct
+ {
+ /* free list */
+ struct dcache_block *free_head;
+ struct dcache_block *free_tail;
+
+ /* in use list */
+ struct dcache_block *valid_head;
+ struct dcache_block *valid_tail;
+
+ /* The cache itself. */
+ struct dcache_block *the_cache;
+ };
+
+static int dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr);
+
+static int dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr);
+
+static struct dcache_block *dcache_hit (DCACHE *dcache, CORE_ADDR addr);
+
+static int dcache_write_line (DCACHE *dcache, struct dcache_block *db);
+
+static int dcache_read_line (DCACHE *dcache, struct dcache_block *db);
+
+static struct dcache_block *dcache_alloc (DCACHE *dcache, CORE_ADDR addr);
+
+static int dcache_writeback (DCACHE *dcache);
+
+static void dcache_info (char *exp, int tty);
+
+void _initialize_dcache (void);
+
+static int dcache_enabled_p = 0;
+
+DCACHE *last_cache; /* Used by info dcache */
+
+
+/* Free all the data cache blocks, thus discarding all cached data. */
+
+void
+dcache_invalidate (DCACHE *dcache)
+{
+ int i;
+ dcache->valid_head = 0;
+ dcache->valid_tail = 0;
+
+ dcache->free_head = 0;
+ dcache->free_tail = 0;
+
+ for (i = 0; i < DCACHE_SIZE; i++)
+ {
+ struct dcache_block *db = dcache->the_cache + i;
+
+ if (!dcache->free_head)
+ dcache->free_head = db;
+ else
+ dcache->free_tail->p = db;
+ dcache->free_tail = db;
+ db->p = 0;
+ }
+
+ return;
+}
+
+/* If addr is present in the dcache, return the address of the block
+ containing it. */
+
+static struct dcache_block *
+dcache_hit (DCACHE *dcache, CORE_ADDR addr)
+{
+ register struct dcache_block *db;
+
+ /* Search all cache blocks for one that is at this address. */
+ db = dcache->valid_head;
+
+ while (db)
+ {
+ if (MASK (addr) == db->addr)
+ {
+ db->refs++;
+ return db;
+ }
+ db = db->p;
+ }
+
+ return NULL;
+}
+
+/* Make sure that anything in this line which needs to
+ be written is. */
+
+static int
+dcache_write_line (DCACHE *dcache, register struct dcache_block *db)
+{
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ int res;
+ int reg_len;
+ struct mem_region *region;
+
+ if (!db->anydirty)
+ return 1;
+
+ len = LINE_SIZE;
+ memaddr = db->addr;
+ myaddr = db->data;
+
+ while (len > 0)
+ {
+ int s;
+ int e;
+ int dirty_len;
+
+ region = lookup_mem_region(memaddr);
+ if (memaddr + len < region->hi)
+ reg_len = len;
+ else
+ reg_len = region->hi - memaddr;
+
+ if (!region->attrib.cache || region->attrib.mode == MEM_RO)
+ {
+ memaddr += reg_len;
+ myaddr += reg_len;
+ len -= reg_len;
+ continue;
+ }
+
+ while (reg_len > 0)
+ {
+ s = XFORM(memaddr);
+ while (reg_len > 0) {
+ if (db->state[s] == ENTRY_DIRTY)
+ break;
+ s++;
+ reg_len--;
+
+ memaddr++;
+ myaddr++;
+ len--;
+ }
+
+ e = s;
+ while (reg_len > 0) {
+ if (db->state[e] != ENTRY_DIRTY)
+ break;
+ e++;
+ reg_len--;
+ }
+
+ dirty_len = e - s;
+ while (dirty_len > 0)
+ {
+ res = do_xfer_memory(memaddr, myaddr, dirty_len, 1,
+ &region->attrib);
+ if (res <= 0)
+ return 0;
+
+ memset (&db->state[XFORM(memaddr)], ENTRY_OK, res);
+ memaddr += res;
+ myaddr += res;
+ len -= res;
+ dirty_len -= res;
+ }
+ }
+ }
+
+ db->anydirty = 0;
+ return 1;
+}
+
+/* Read cache line */
+static int
+dcache_read_line (DCACHE *dcache, struct dcache_block *db)
+{
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ int res;
+ int reg_len;
+ struct mem_region *region;
+
+ /* If there are any dirty bytes in the line, it must be written
+ before a new line can be read */
+ if (db->anydirty)
+ {
+ if (!dcache_write_line (dcache, db))
+ return 0;
+ }
+
+ len = LINE_SIZE;
+ memaddr = db->addr;
+ myaddr = db->data;
+
+ while (len > 0)
+ {
+ region = lookup_mem_region(memaddr);
+ if (memaddr + len < region->hi)
+ reg_len = len;
+ else
+ reg_len = region->hi - memaddr;
+
+ if (!region->attrib.cache || region->attrib.mode == MEM_WO)
+ {
+ memaddr += reg_len;
+ myaddr += reg_len;
+ len -= reg_len;
+ continue;
+ }
+
+ while (reg_len > 0)
+ {
+ res = do_xfer_memory (memaddr, myaddr, reg_len, 0,
+ &region->attrib);
+ if (res <= 0)
+ return 0;
+
+ memaddr += res;
+ myaddr += res;
+ len -= res;
+ reg_len -= res;
+ }
+ }
+
+ memset (db->state, ENTRY_OK, sizeof (db->data));
+ db->anydirty = 0;
+
+ return 1;
+}
+
+/* Get a free cache block, put or keep it on the valid list,
+ and return its address. */
+
+static struct dcache_block *
+dcache_alloc (DCACHE *dcache, CORE_ADDR addr)
+{
+ register struct dcache_block *db;
+
+ /* Take something from the free list */
+ db = dcache->free_head;
+ if (db)
+ {
+ dcache->free_head = db->p;
+ }
+ else
+ {
+ /* Nothing left on free list, so grab one from the valid list */
+ db = dcache->valid_head;
+
+ if (!dcache_write_line (dcache, db))
+ return NULL;
+
+ dcache->valid_head = db->p;
+ }
+
+ db->addr = MASK(addr);
+ db->refs = 0;
+ db->anydirty = 0;
+ memset (db->state, ENTRY_BAD, sizeof (db->data));
+
+ /* append this line to end of valid list */
+ if (!dcache->valid_head)
+ dcache->valid_head = db;
+ else
+ dcache->valid_tail->p = db;
+ dcache->valid_tail = db;
+ db->p = 0;
+
+ return db;
+}
+
+/* Writeback any dirty lines. */
+static int
+dcache_writeback (DCACHE *dcache)
+{
+ struct dcache_block *db;
+
+ db = dcache->valid_head;
+
+ while (db)
+ {
+ if (!dcache_write_line (dcache, db))
+ return 0;
+ db = db->p;
+ }
+ return 1;
+}
+
+
+/* Using the data cache DCACHE return the contents of the byte at
+ address ADDR in the remote machine.
+
+ Returns 0 on error. */
+
+static int
+dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr)
+{
+ register struct dcache_block *db = dcache_hit (dcache, addr);
+
+ if (!db)
+ {
+ db = dcache_alloc (dcache, addr);
+ if (!db)
+ return 0;
+ }
+
+ if (db->state[XFORM (addr)] == ENTRY_BAD)
+ {
+ if (!dcache_read_line(dcache, db))
+ return 0;
+ }
+
+ *ptr = db->data[XFORM (addr)];
+ return 1;
+}
+
+
+/* Write the byte at PTR into ADDR in the data cache.
+ Return zero on write error.
+ */
+
+static int
+dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr)
+{
+ register struct dcache_block *db = dcache_hit (dcache, addr);
+
+ if (!db)
+ {
+ db = dcache_alloc (dcache, addr);
+ if (!db)
+ return 0;
+ }
+
+ db->data[XFORM (addr)] = *ptr;
+ db->state[XFORM (addr)] = ENTRY_DIRTY;
+ db->anydirty = 1;
+ return 1;
+}
+
+/* Initialize the data cache. */
+DCACHE *
+dcache_init (void)
+{
+ int csize = sizeof (struct dcache_block) * DCACHE_SIZE;
+ DCACHE *dcache;
+
+ dcache = (DCACHE *) xmalloc (sizeof (*dcache));
+
+ dcache->the_cache = (struct dcache_block *) xmalloc (csize);
+ memset (dcache->the_cache, 0, csize);
+
+ dcache_invalidate (dcache);
+
+ last_cache = dcache;
+ return dcache;
+}
+
+/* Free a data cache */
+void
+dcache_free (DCACHE *dcache)
+{
+ if (last_cache == dcache)
+ last_cache = NULL;
+
+ xfree (dcache->the_cache);
+ xfree (dcache);
+}
+
+/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
+ to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
+ nonzero.
+
+ Returns length of data written or read; 0 for error.
+
+ This routine is indended to be called by remote_xfer_ functions. */
+
+int
+dcache_xfer_memory (DCACHE *dcache, CORE_ADDR memaddr, char *myaddr, int len,
+ int should_write)
+{
+ int i;
+ int (*xfunc) (DCACHE *dcache, CORE_ADDR addr, char *ptr);
+ xfunc = should_write ? dcache_poke_byte : dcache_peek_byte;
+
+ for (i = 0; i < len; i++)
+ {
+ if (!xfunc (dcache, memaddr + i, myaddr + i))
+ return 0;
+ }
+
+ /* FIXME: There may be some benefit from moving the cache writeback
+ to a higher layer, as it could occur after a sequence of smaller
+ writes have been completed (as when a stack frame is constructed
+ for an inferior function call). Note that only moving it up one
+ level to target_xfer_memory() (also target_xfer_memory_partial())
+ is not sufficent, since we want to coalesce memory transfers that
+ are "logically" connected but not actually a single call to one
+ of the memory transfer functions. */
+
+ if (should_write)
+ dcache_writeback (dcache);
+
+ return len;
+}
+
+static void
+dcache_info (char *exp, int tty)
+{
+ struct dcache_block *p;
+
+ printf_filtered ("Dcache line width %d, depth %d\n",
+ LINE_SIZE, DCACHE_SIZE);
+
+ if (last_cache)
+ {
+ printf_filtered ("Cache state:\n");
+
+ for (p = last_cache->valid_head; p; p = p->p)
+ {
+ int j;
+ printf_filtered ("Line at %s, referenced %d times\n",
+ paddr (p->addr), p->refs);
+
+ for (j = 0; j < LINE_SIZE; j++)
+ printf_filtered ("%02x", p->data[j] & 0xFF);
+ printf_filtered ("\n");
+
+ for (j = 0; j < LINE_SIZE; j++)
+ printf_filtered ("%2x", p->state[j]);
+ printf_filtered ("\n");
+ }
+ }
+}
+
+void
+_initialize_dcache (void)
+{
+ add_show_from_set
+ (add_set_cmd ("remotecache", class_support, var_boolean,
+ (char *) &dcache_enabled_p,
+ "\
+Set cache use for remote targets.\n\
+When on, use data caching for remote targets. For many remote targets\n\
+this option can offer better throughput for reading target memory.\n\
+Unfortunately, gdb does not currently know anything about volatile\n\
+registers and thus data caching will produce incorrect results with\n\
+volatile registers are in use. By default, this option is off.",
+ &setlist),
+ &showlist);
+
+ add_info ("dcache", dcache_info,
+ "Print information on the dcache performance.");
+
+}
diff --git a/gdb/dcache.h b/gdb/dcache.h
new file mode 100644
index 00000000000..5f9da65e222
--- /dev/null
+++ b/gdb/dcache.h
@@ -0,0 +1,43 @@
+/* Declarations for caching. Typically used by remote back ends for
+ caching remote memory.
+
+ Copyright 1992, 1993, 1995, 1999, 2000, 2001
+ 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. */
+
+#ifndef DCACHE_H
+#define DCACHE_H
+
+typedef struct dcache_struct DCACHE;
+
+/* Invalidate DCACHE. */
+void dcache_invalidate (DCACHE *dcache);
+
+/* Initialize DCACHE. */
+DCACHE *dcache_init (void);
+
+/* Free a DCACHE */
+void dcache_free (DCACHE *);
+
+/* Simple to call from <remote>_xfer_memory */
+
+int dcache_xfer_memory (DCACHE *cache, CORE_ADDR mem, char *my, int len,
+ int should_write);
+
+#endif /* DCACHE_H */
diff --git a/gdb/delta68-nat.c b/gdb/delta68-nat.c
new file mode 100644
index 00000000000..e74a51bf048
--- /dev/null
+++ b/gdb/delta68-nat.c
@@ -0,0 +1,90 @@
+/* Functions specific to running gdb native on a Motorola Delta Series sysV68.
+ Copyright 1993, 1996, 1998, 2000 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 "defs.h"
+#include <sys/signal.h> /* for MAXSIG in sys/user.h */
+#include <sys/types.h> /* for ushort in sys/dir.h */
+#include <sys/dir.h> /* for struct direct in sys/user.h */
+#include <sys/user.h>
+
+#include <nlist.h>
+
+#if !defined (offsetof)
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+#endif
+
+/* Return the address in the core dump or inferior of register REGNO.
+ BLOCKEND is the address of the end of the user structure. */
+
+CORE_ADDR
+register_addr (int regno, CORE_ADDR blockend)
+{
+ static int sysv68reg[] =
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, 15, 16};
+
+ if (regno >= 0 && regno < sizeof (sysv68reg) / sizeof (sysv68reg[0]))
+ return blockend + sysv68reg[regno] * 4;
+ else if (regno < FPC_REGNUM)
+ return offsetof (struct user, u_fpu.regs.reg[regno - FP0_REGNUM][0]);
+ else if (regno == FPC_REGNUM)
+ return offsetof (struct user, u_fpu.regs.control);
+ else if (regno == FPS_REGNUM)
+ return offsetof (struct user, u_fpu.regs.status);
+ else if (regno == FPI_REGNUM)
+ return offsetof (struct user, u_fpu.regs.iaddr);
+ else
+ {
+ fprintf_unfiltered (gdb_stderr, "\
+Internal error: invalid register number %d in REGISTER_U_ADDR\n",
+ regno);
+ return blockend;
+ }
+}
+
+CORE_ADDR kernel_u_addr;
+
+/* Read the value of the u area from the kernel. */
+void
+_initialize_delta68_nat (void)
+{
+ struct nlist nl[2];
+
+ nl[0].n_name = "u";
+ nl[1].n_name = NULL;
+ if (nlist ("/sysV68", nl) == 0 && nl[0].n_scnum != 0)
+ kernel_u_addr = nl[0].n_value;
+ else
+ {
+ perror ("Cannot get kernel u area address");
+ exit (1);
+ }
+}
+
+clear_insn_cache (void)
+{
+#ifdef MCT_TEXT /* in sys/signal.h on sysV68 R3V7.1 */
+ memctl (0, 4096, MCT_TEXT);
+#endif
+}
+
+kernel_u_size (void)
+{
+ return sizeof (struct user);
+}
diff --git a/gdb/demangle.c b/gdb/demangle.c
new file mode 100644
index 00000000000..1fd69be4c58
--- /dev/null
+++ b/gdb/demangle.c
@@ -0,0 +1,208 @@
+/* Basic C++ demangling support for GDB.
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+ Written by Fred Fish at 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 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. */
+
+
+/* This file contains support code for C++ demangling that is common
+ to a styles of demangling, and GDB specific. */
+
+#include "defs.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "demangle.h"
+#include "gdb_string.h"
+
+/* Select the default C++ demangling style to use. The default is "auto",
+ which allows gdb to attempt to pick an appropriate demangling style for
+ the executable it has loaded. It can be set to a specific style ("gnu",
+ "lucid", "arm", "hp", etc.) in which case gdb will never attempt to do auto
+ selection of the style unless you do an explicit "set demangle auto".
+ To select one of these as the default, set DEFAULT_DEMANGLING_STYLE in
+ the appropriate target configuration file. */
+
+#ifndef DEFAULT_DEMANGLING_STYLE
+#define DEFAULT_DEMANGLING_STYLE AUTO_DEMANGLING_STYLE_STRING
+#endif
+
+extern void _initialize_demangler (void);
+
+/* String name for the current demangling style. Set by the
+ "set demangle-style" command, printed as part of the output by the
+ "show demangle-style" command. */
+
+static char *current_demangling_style_string;
+
+/* The array of names of the known demanglyng styles. Generated by
+ _initialize_demangler from libiberty_demanglers[] array. */
+
+static const char **demangling_style_names;
+
+static void set_demangling_command (char *, int, struct cmd_list_element *);
+
+/* Set current demangling style. Called by the "set demangle-style"
+ command after it has updated the current_demangling_style_string to
+ match what the user has entered.
+
+ If the user has entered a string that matches a known demangling style
+ name in the demanglers[] array then just leave the string alone and update
+ the current_demangling_style enum value to match.
+
+ If the user has entered a string that doesn't match, including an empty
+ string, then print a list of the currently known styles and restore
+ the current_demangling_style_string to match the current_demangling_style
+ enum value.
+
+ Note: Assumes that current_demangling_style_string always points to
+ a malloc'd string, even if it is a null-string. */
+
+static void
+set_demangling_command (char *ignore, int from_tty, struct cmd_list_element *c)
+{
+ const struct demangler_engine *dem;
+
+ /* First just try to match whatever style name the user supplied with
+ one of the known ones. Don't bother special casing for an empty
+ name, we just treat it as any other style name that doesn't match.
+ If we match, update the current demangling style enum. */
+
+ for (dem = libiberty_demanglers;
+ dem->demangling_style != unknown_demangling;
+ dem++)
+ {
+ if (STREQ (current_demangling_style_string,
+ dem->demangling_style_name))
+ {
+ current_demangling_style = dem->demangling_style;
+ break;
+ }
+ }
+
+ /* Check to see if we found a match. If not, gripe about any non-empty
+ style name and supply a list of valid ones. FIXME: This should
+ probably be done with some sort of completion and with help. */
+
+ if (dem->demangling_style == unknown_demangling)
+ {
+ if (*current_demangling_style_string != '\0')
+ {
+ printf_unfiltered ("Unknown demangling style `%s'.\n",
+ current_demangling_style_string);
+ }
+ printf_unfiltered ("The currently understood settings are:\n\n");
+ for (dem = libiberty_demanglers;
+ dem->demangling_style != unknown_demangling;
+ dem++)
+ {
+ printf_unfiltered ("%-10s %s\n", dem->demangling_style_name,
+ dem->demangling_style_doc);
+ if (dem->demangling_style == current_demangling_style)
+ {
+ xfree (current_demangling_style_string);
+ current_demangling_style_string =
+ savestring (dem->demangling_style_name,
+ strlen (dem->demangling_style_name));
+ }
+ }
+ if (current_demangling_style == unknown_demangling)
+ {
+ /* This can happen during initialization if gdb is compiled with
+ a DEMANGLING_STYLE value that is unknown, so pick the first
+ one as the default. */
+ current_demangling_style = libiberty_demanglers[0].demangling_style;
+ current_demangling_style_string =
+ savestring (
+ libiberty_demanglers[0].demangling_style_name,
+ strlen (libiberty_demanglers[0].demangling_style_name));
+ warning ("`%s' style demangling chosen as the default.\n",
+ current_demangling_style_string);
+ }
+ }
+}
+
+/* Fake a "set demangle-style" command. */
+
+void
+set_demangling_style (char *style)
+{
+ if (current_demangling_style_string != NULL)
+ {
+ xfree (current_demangling_style_string);
+ }
+ current_demangling_style_string = savestring (style, strlen (style));
+ set_demangling_command ((char *) NULL, 0, (struct cmd_list_element *) NULL);
+}
+
+/* In order to allow a single demangler executable to demangle strings
+ using various common values of CPLUS_MARKER, as well as any specific
+ one set at compile time, we maintain a string containing all the
+ commonly used ones, and check to see if the marker we are looking for
+ is in that string. CPLUS_MARKER is usually '$' on systems where the
+ assembler can deal with that. Where the assembler can't, it's usually
+ '.' (but on many systems '.' is used for other things). We put the
+ current defined CPLUS_MARKER first (which defaults to '$'), followed
+ by the next most common value, followed by an explicit '$' in case
+ the value of CPLUS_MARKER is not '$'.
+
+ We could avoid this if we could just get g++ to tell us what the actual
+ cplus marker character is as part of the debug information, perhaps by
+ ensuring that it is the character that terminates the gcc<n>_compiled
+ marker symbol (FIXME). */
+
+static char cplus_markers[] =
+{CPLUS_MARKER, '.', '$', '\0'};
+
+int
+is_cplus_marker (int c)
+{
+ return c && strchr (cplus_markers, c) != NULL;
+}
+
+void
+_initialize_demangler (void)
+{
+ struct cmd_list_element *set, *show;
+ int i, ndems;
+
+ /* Fill the demangling_style_names[] array. */
+ for (ndems = 0;
+ libiberty_demanglers[ndems].demangling_style != unknown_demangling;
+ ndems++)
+ ;
+ demangling_style_names = xcalloc (ndems + 1, sizeof (char *));
+ for (i = 0;
+ libiberty_demanglers[i].demangling_style != unknown_demangling;
+ i++)
+ demangling_style_names[i] =
+ xstrdup (libiberty_demanglers[i].demangling_style_name);
+
+ set = add_set_enum_cmd ("demangle-style", class_support,
+ demangling_style_names,
+ (const char **) &current_demangling_style_string,
+ "Set the current C++ demangling style.\n\
+Use `set demangle-style' without arguments for a list of demangling styles.",
+ &setlist);
+ show = add_show_from_set (set, &showlist);
+ set_cmd_sfunc (set, set_demangling_command);
+
+ /* Set the default demangling style chosen at compilation time. */
+ set_demangling_style (DEFAULT_DEMANGLING_STYLE);
+ set_cplus_marker_for_demangling (CPLUS_MARKER);
+}
diff --git a/gdb/dink32-rom.c b/gdb/dink32-rom.c
new file mode 100644
index 00000000000..f62e7129c36
--- /dev/null
+++ b/gdb/dink32-rom.c
@@ -0,0 +1,192 @@
+/* Remote debugging interface for DINK32 (PowerPC) ROM monitor for
+ GDB, the GNU debugger.
+ Copyright 1997, 1999, 2000, 2001 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "symfile.h" /* For generic_load() */
+#include "inferior.h" /* For write_pc() */
+#include "regcache.h"
+
+static void dink32_open (char *args, int from_tty);
+
+static void
+dink32_supply_register (char *regname, int regnamelen, char *val, int vallen)
+{
+ int regno = 0;
+
+ if (regnamelen < 2 || regnamelen > 4)
+ return;
+
+ switch (regname[0])
+ {
+ case 'R':
+ if (regname[1] < '0' || regname[1] > '9')
+ return;
+ if (regnamelen == 2)
+ regno = regname[1] - '0';
+ else if (regnamelen == 3 && regname[2] >= '0' && regname[2] <= '9')
+ regno = (regname[1] - '0') * 10 + (regname[2] - '0');
+ else
+ return;
+ break;
+ case 'F':
+ if (regname[1] != 'R' || regname[2] < '0' || regname[2] > '9')
+ return;
+ if (regnamelen == 3)
+ regno = 32 + regname[2] - '0';
+ else if (regnamelen == 4 && regname[3] >= '0' && regname[3] <= '9')
+ regno = 32 + (regname[2] - '0') * 10 + (regname[3] - '0');
+ else
+ return;
+ break;
+ case 'I':
+ if (regnamelen != 2 || regname[1] != 'P')
+ return;
+ regno = 64;
+ break;
+ case 'M':
+ if (regnamelen != 3 || regname[1] != 'S' || regname[2] != 'R')
+ return;
+ regno = 65;
+ break;
+ case 'C':
+ if (regnamelen != 2 || regname[1] != 'R')
+ return;
+ regno = 66;
+ break;
+ case 'S':
+ if (regnamelen != 4 || regname[1] != 'P' || regname[2] != 'R')
+ return;
+ else if (regname[3] == '8')
+ regno = 67;
+ else if (regname[3] == '9')
+ regno = 68;
+ else if (regname[3] == '1')
+ regno = 69;
+ else if (regname[3] == '0')
+ regno = 70;
+ else
+ return;
+ break;
+ default:
+ return;
+ }
+
+ monitor_supply_register (regno, val);
+}
+
+static void
+dink32_load (struct monitor_ops *monops, char *filename, int from_tty)
+{
+ generic_load (filename, from_tty);
+
+ /* Finally, make the PC point at the start address */
+ if (exec_bfd)
+ write_pc (bfd_get_start_address (exec_bfd));
+
+ inferior_ptid = null_ptid; /* No process now */
+}
+
+
+/* This array of registers needs to match the indexes used by GDB. The
+ whole reason this exists is because the various ROM monitors use
+ different names than GDB does, and don't support all the registers
+ either. */
+
+static char *dink32_regnames[] =
+{
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+
+ "srr0", "msr", "cr", "lr", "ctr", "xer", "xer"
+};
+
+static struct target_ops dink32_ops;
+
+static char *dink32_inits[] =
+{"\r", NULL};
+
+static struct monitor_ops dink32_cmds;
+
+static void
+dink32_open (char *args, int from_tty)
+{
+ monitor_open (args, &dink32_cmds, from_tty);
+}
+
+void
+_initialize_dink32_rom (void)
+{
+ dink32_cmds.flags = MO_HEX_PREFIX | MO_GETMEM_NEEDS_RANGE | MO_FILL_USES_ADDR | MO_HANDLE_NL | MO_32_REGS_PAIRED | MO_SETREG_INTERACTIVE | MO_SETMEM_INTERACTIVE | MO_GETMEM_16_BOUNDARY | MO_CLR_BREAK_1_BASED | MO_SREC_ACK | MO_SREC_ACK_ROTATE;
+ dink32_cmds.init = dink32_inits;
+ dink32_cmds.cont = "go +\r";
+ dink32_cmds.step = "tr +\r";
+ dink32_cmds.set_break = "bp 0x%x\r";
+ dink32_cmds.clr_break = "bp %d\r";
+#if 0 /* Would need to follow strict alignment rules.. */
+ dink32_cmds.fill = "mf %x %x %x\r";
+#endif
+ dink32_cmds.setmem.cmdb = "mm -b %x\r";
+ dink32_cmds.setmem.cmdw = "mm -w %x\r";
+ dink32_cmds.setmem.cmdl = "mm %x\r";
+ dink32_cmds.setmem.term = " ? ";
+ dink32_cmds.getmem.cmdb = "md %x\r";
+ dink32_cmds.getmem.resp_delim = " ";
+ dink32_cmds.setreg.cmd = "rm %s\r";
+ dink32_cmds.setreg.term = " ? ";
+ dink32_cmds.getreg.cmd = "rd %s\r";
+ dink32_cmds.getreg.resp_delim = ": ";
+ dink32_cmds.dump_registers = "rd r\r";
+ dink32_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)";
+ dink32_cmds.supply_register = dink32_supply_register;
+ /* S-record download, via "keyboard port". */
+ dink32_cmds.load = "dl -k\r";
+ dink32_cmds.loadresp = "Set Input Port : set to Keyboard Port\r";
+#if 0 /* slow load routine not needed if S-records work... */
+ dink32_cmds.load_routine = dink32_load;
+#endif
+ dink32_cmds.prompt = "DINK32_603 >>";
+ dink32_cmds.line_term = "\r";
+ dink32_cmds.target = &dink32_ops;
+ dink32_cmds.stopbits = SERIAL_1_STOPBITS;
+ dink32_cmds.regnames = dink32_regnames;
+ dink32_cmds.magic = MONITOR_OPS_MAGIC;
+
+ init_monitor_ops (&dink32_ops);
+
+ dink32_ops.to_shortname = "dink32";
+ dink32_ops.to_longname = "DINK32 monitor";
+ dink32_ops.to_doc = "Debug using the DINK32 monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ dink32_ops.to_open = dink32_open;
+
+ add_target (&dink32_ops);
+}
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
new file mode 100644
index 00000000000..577ddb146bc
--- /dev/null
+++ b/gdb/doc/ChangeLog
@@ -0,0 +1,2709 @@
+2002-05-17 Jim Blandy <jimb@redhat.com>
+
+ * gdb.texinfo (C Preprocessor Macros): New chapter.
+ Include it in the main menu.
+ (Contributors): Credit Jim Blandy with macro support.
+ (Compilation): Explain how to get macro information into the
+ executable.
+ (Expressions): Note that preprocessor macros are expanded.
+
+2002-05-14 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.texinfo (Debug Session): Document new `udp:' and `tcp:'
+ options for `target remote'.
+
+2002-05-13 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Delete
+ documentation on NNPC_REGNUM.
+
+2002-05-11 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Document
+ REGISTER_TO_VALUE and VALUE_TO_REGISTER and CONVERT_REGISTER_P.
+ (Target Architecture Definition): Revise section `Using Different
+ Register and Memory Data Representations'. Add section `Raw and
+ Virtual Register Representations'.
+
+2002-05-11 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Mention
+ defaults for REGISTER_VIRTUAL_SIZE and REGISTER_RAW_SIZE.
+ (Target Architecture Definition): Mention same. Add references to
+ web pages.
+
+2002-05-08 Michael Snyder <msnyder@redhat.com>
+
+ * stabs.texinfo (Attributes): Document new "vector" attribute.
+
+2002-05-04 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Releasing GDB): Revise `Create a Release'.
+
+2002-05-04 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.texinfo: Delete obsolete references to a29k.
+
+2002-04-24 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Replace
+ IN_SIGTRAMP with PC_IN_SIGTRAMP.
+
+2002-04-24 David S. Miller <davem@redhat.com>
+
+ * gdbint.texinfo (REGISTER_IN_WINDOW): Delete definition.
+
+2002-04-21 David S. Miller <davem@redhat.com>
+
+ * gdbint.texinfo (SKIP_PROLOGUE_FRAMELESS_P): Delete definition.
+
+2002-04-21 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Delete
+ definition of HAVE_REGISTER_WINDOWS.
+
+2002-04-19 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdbint.texinfo (Releasing GDB, Coding): Fix typos. Reported by
+ "Theodore A. Roth" <troth@verinet.com>.
+
+2002-04-15 Don Howard <dhoward@redhat.com>
+
+ From Eli Zaretskii <eliz@is.elta.co.il>
+ * gdb.texinfo (show max-user-call-depth): Correct formatting.
+ Provide a better explaination of this feature.
+
+2002-04-14 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Remove
+ FRAME_CHAIN_COMBINE.
+
+2002-04-12 Michael Chastain <mec@shout.net>
+
+ * gdbint.texinfo (Obsolete Conditionals): Remove reference to
+ REG_STACK_SEGMENT.
+
+2002-04-09 Michael Chastain <mec@shout.net>
+
+ * gdbint.texinfo (Obsolete Conditionals): Remove references to
+ PYRAMID_* macros.
+
+2002-04-07 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.texinfo (Bug Reporting): Document that the web is the
+ prefered way of submitting bug reports.
+ (Bug Reporting): Delete the s-mail address as the last resort.
+
+2002-04-05 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Delete
+ references to TARGET_WRITE_FP and write_fp.
+
+2002-03-27 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.texinfo: Document new commands dump, append, and restore.
+
+2002-03-27 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Releasing GDB): Revise the section `Before the
+ Branch'.
+
+2002-03-18 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.texinfo: Change all examples to @smallexample.
+ * gdbint.texinfo: Ditto.
+
+2002-03-18 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Releasing GDB): Add section ``Versions and
+ Branches''.
+
+2002-03-18 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Releasing GDB): Add the section``Branch Commit
+ Policy''.
+
+2002-03-04 Fred Fish <fnf@redhat.com>
+
+ * gdbint.texinfo: Fix a bunch of typos (alsways, mirrorred,
+ expresson, suports, dependant, trhe, perhaphs, situtations,
+ explictily, taged, oportunity, unfortunatly).
+
+2002-02-24 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in (gdb.info): Add explicit path to gdb.texinfo.
+ Remove reference to 3.12.
+
+2002-02-23 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo: Include fdl.texi.
+ (Top): Add GNU Free Documentation License.
+ * Makefile.in (SFILES_INCLUDED): Add gpl.texi.
+ (gdbint.dvi, gdbint.pdf, gdbint.info): Add dependency on fdl.texi.
+ (gdbint_toc.html): Add dependency on gdb-cfg.texi and fdl.texi.
+ (gdbint.info): Add srcdir to include path.
+ * gdb.texinfo: Include gpl.texi.
+ (Top): Add Copying.
+ * gpl.texi: New file.
+
+2002-02-23 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Debugging GDB): Remove references to cygnus.com.
+
+2002-02-19 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * gdb.texinfo: Document Cygwin native specific commands.
+
+2002-02-15 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.texinfo: Document gdbserver ``--attach'' command.
+
+2002-02-07 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.texinfo (overlays): Change @var(_ovly_debug_event)
+ to @code(_ovly_debug_event).
+
+2002-02-07 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.texinfo (How Overlays Work): Shrink the overlay diagram.
+
+2002-02-06 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.texinfo (overlays): Mention new magic symbol
+ '_ovly_debug_event', which allows GDB to keep better track
+ of overlays.
+
+2002-02-03 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo (Memory Region Attributes): Fix the wording.
+ Suggested by Dmitry Sivachenko.
+
+ * (<many nodes>): Fix the spelling and punctuation of "i.e.".
+
+2002-02-01 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.texinfo (set trust-readonly): Change value{gdbn} to value{GDBN}.
+
+2002-01-30 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.texinfo: (remote protocol): Gramatical fix-up.
+ (set trust-readonly-sections): Document.
+
+2002-01-29 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Releasing GDB): Revise and update.
+
+2002-01-28 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Delete
+ description of TARGET_BYTE_ORDER_DEFAULT.
+
+2002-01-27 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo: Fix typos and markup. From Dmitry Sivachenko
+ <mitya@cavia.pp.ru>.
+
+2002-01-23 Andrew Cagney <ac131313@redhat.com>
+
+ * libgdb.texinfo: Delete file.
+
+2002-01-22 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.texinfo: Remove makeinfo 3.12 hacks.
+ * gdbint.texinfo: Ditto.
+
+Tue Jan 22 11:57:38 2002 Andrew Cagney <cagney@redhat.com>
+
+ * gdb.texinfo: Fix typo ``Remove' -> ``Remote''.
+
+2002-01-22 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in: Update copyright.
+ (TEXI2DVI): Define.
+ (gdb.dvi, gdb.pdf, stabs.dvi, stabs.pdf): Use TEXI2DVI.
+ (gdbint.dvi, gdbint.pdf): Use TEXI2DVI. Add dependency on
+ gdb-cfg.texi.
+ (TEXINDEX, PDFTEX): Delete makefile variables.
+
+2002-01-22 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.texinfo (Protocol): Move section to appendix.
+
+2002-01-21 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.texinfo (Remote Debugging): Create a menu.
+ (Top): Add ``Remote Debugging'' to menu.
+
+2002-01-21 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.texinfo (Remote): Move the sub-section ``The GDB remote
+ serial protocol'' from here.
+ (Remote Debugging): To here. New chapter.
+
+2002-01-20 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Delete
+ description of TARGET_BYTE_ORDER_SELECTABLE_P.
+
+2002-01-20 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Host Definition): Revise. xm-xyz.h and xyz.mh
+ are no longer needed.
+ (Porting GDB): Add maintainer note about configure.host.
+
+2002-01-20 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Remove
+ definition of IEEE_FLOAT.
+
+2002-01-20 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo: Beautify copyright years; fix a typo.
+ (DJGPP Native): Fix overfull hboxes in examples. From Brian Youmans
+ <3diff@gnu.org>
+
+2002-01-19 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Host Definition): Remove references to
+ MALLOC_INCOMPATIBLE.
+
+2002-01-17 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Host Definition): Remove references to XDEPFILES
+ and xyz-xdep.o.
+
+2002-01-17 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.texinfo (Maintenance Commands): Add appendix.
+ (Set Breaks): Copy ``maint info breakpoint'' doco to
+ ``Maintenance Commands'' appendix. Add reference.
+
+2002-01-17 Andrew Cagney <ac131313@redhat.com>
+
+ * fdl.texi: Remove next/prev from @node.
+
+2002-01-17 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo: @include fdl.texi. Fixes for overfull hboxes and
+ for monstrous @multitable (from Brian Youmans).
+
+ * fdl.texi: New file.
+
+ * Makefile.in (SFILES_INCLUDED): Add fdl.texi.
+
+2002-01-15 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Releasing GDB): New chapter.
+
+2002-01-14 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.texinfo (Embedded Processors, Calling program functions):
+ Obsolete references to a29k.
+
+2002-01-13 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Coding): Review Cleanups section. Examples
+ examples. Document that a code-block should do or discard its
+ cleanups before exit.
+
+2002-01-11 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.texinfo (Choosing files): Change @samp to @file.
+
+2002-01-05 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.texinfo (--pid): Document new command line option (attach).
+
+2002-01-07 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo (Tracepoints): Clarify that tracepoints need support
+ in the stub.
+
+2002-01-04 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Replace
+ BIG_ENDIAN with BFD_ENDIAN_BIG.
+
+2002-01-03 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Replace
+ value_ptr with struct value pointer.
+
+2002-01-02 Eli Zaretskii <eliz@gnu.org>
+
+ * gdb.texinfo (Free Software): Fix wording.
+
+2001-12-31 Eli Zaretskii <eliz@gnu.org>
+
+ * gdb.texinfo (Free Software): New section ``Free Software Needs
+ Free Documentation''.
+
+2001-12-30 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * stabs.texinfo:
+ * gdb.texinfo:
+ * gdbint.texinfo:
+ * libgdb.texinfo:
+ * annotate.texi: Fix the application of GFDL in the Copyright notice.
+
+2001-12-29 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.texinfo (maint info sections): Fix typo.
+
+2001-12-26 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.texinfo (maint info sections): Document.
+
+ * gdb.texinfo (info proc): Comment out documentation for
+ 'info proc' sub-options that are currently not implemented.
+
+2001-12-20 Jim Blandy <jimb@redhat.com>
+
+ * gdbint.texinfo (TARGET_CHAR_SIGNED): Document.
+
+2001-12-15 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Replace
+ LITTLE_ENDIAN with BFD_ENDIAN_LITTLE.
+
+2001-12-01 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Host Definition): Delete documentation on
+ HOST_BYTE_ORDER.
+
+2001-11-30 Jim Blandy <jimb@redhat.com>
+
+ * gdb.texinfo (Overlays): New chapter, documenting GDB's
+ overlay support. Add to top-level menu.
+
+2001-11-26 Tom Tromey <tromey@redhat.com>
+
+ * gdb.texinfo (Command Syntax): Document C-o binding.
+
+2001-07-26 Christopher Faylor <cgf@redhat.com>
+
+ * gdb.texinfo (Options): Eliminate attempt to explain .gdbinit/gdb.ini
+ use since it is described in the referenced section.
+
+ From Eli Zaretskii <eliz@is.elta.co.il>
+ * gdb.texinfo (Command Files): Reword to make gdb.ini requirement
+ clearer when using DJGPP.
+
+2001-11-24 Christopher Faylor <cgf@redhat.com>
+
+ * gdb.texinfo (File Options): Change description of -nx and gdb.ini to
+ specifically refer to MS-DOS.
+ (command files): Mention gdb.ini is only used on MS-DOS.
+
+2001-11-21 Tom Tromey <tromey@redhat.com>
+
+ * gdb.texinfo (Invoking GDB): Document --args.
+ (Mode Options): Likewise.
+
+2001-11-21 Jim Blandy <jimb@redhat.com>
+
+ * gdbint.texinfo (TARGET_RANGE_PROFITABLE_FOR_HW_WATCHPOINT):
+ Delete documentation; this macro has been removed from the
+ sources.
+
+2001-11-13 Jim Blandy <jimb@redhat.com>
+
+ * gdbint.texinfo (COERCE_FLOAT_TO_DOUBLE): Clarify.
+
+2001-11-06 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.texinfo (gdbarch_in_function_epilogue_p): Add documentation.
+
+2001-11-05 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.texinfo (info functions): Document use of backslash to
+ quote regexp chars in function names such as "operator*()".
+
+2001-11-01 Fred Fish <fnf@redhat.com>
+
+ * gdbint.texinfo (SOLIB_ADD): Document additional new
+ "readsyms" arg.
+
+2001-10-30 Don Howard <dhoward@redhat.com>
+
+ * gdb.texinfo: (Command Files) Added documentation for the
+ behavior of gdb with input redirected from a file.
+
+2001-10-28 Fred Fish <fnf@redhat.com>
+
+ * gdb.texinfo (auto-solib-add): Change docs to match
+ implementation change.
+ (auto-solib-limit): Add docs for new variable.
+
+2001-10-15 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Function
+ value_as_pointer renamed to value_as_address.
+
+2001-10-15 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Default
+ POINTER_TO_ADDRESS functions assume unsigned addresses.
+ (INTEGER_TO_ADDRESS): Document. Derive pragmatics section from a
+ posting by Jim Blandy.
+
+2001-10-12 Jim Blandy <jimb@redhat.com>
+
+ * Makefile.in (MAKEHTMLFLAGS): Remove -glossary; the most recent
+ version of texi2html (1.64) doesn't support this flag any more.
+
+2001-09-08 Mark Kettenis <kettenis@gnu.org>
+
+ * gdbint.texinfo (Host Definition): Remove description of
+ MEM_FNS_DECLARED.
+
+ * gdbint.texinfo (Host Definition): Remove description of R_OK.
+
+ * gdbint.texinfo (Host Definition): Remove description of
+ HAVE_SIGSETMASK.
+
+2001-09-04 Elena Zannoni <ezannoni@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Add
+ explanation of TARGET_PRINT_INSN macro.
+
+2001-08-30 Jim Blandy <jimb@redhat.com>
+
+ * gdb.texinfo (`add-symbol-file'): Correct synopsis.
+ Explain what it means to load relocatable files.
+
+2001-08-28 Jim Blandy <jimb@redhat.com>
+
+ * gdbint.texinfo: Bring the HTML `top' menu into sync with the
+ info `top' menu.
+
+Wed Aug 15 10:47:28 2001 Christopher Faylor <cgf@cygnus.com>
+
+ * gdbint.texinfo: Add a cautionary note about macro use.
+
+2001-08-02 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.texinfo: Explain omitting the hostname in the
+ `target remote' command.
+
+2001-07-30 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdbint.texinfo: Remove extraneous START-INFO-DIR-ENTRY
+ and END-INFO-DIR-ENTRY.
+
+2001-07-28 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * gdb.texinfo (TUI Configuration): Rename tui configuration variables.
+
+2001-07-25 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (libgdb): Rewrite.
+
+2001-07-26 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * Makefile.in (gdbgui.dvi, gdb-gui, gdbgui.info): Targets deleted.
+
+2001-07-24 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * gdb.texinfo (TUI): New chapter, document the TUI.
+ (Mode Options): Document the -tui option.
+
+2001-07-23 Mark Kettenis <kettenis@gnu.org>
+
+ * gdbint.texinfo (Host Definition): Remove description of
+ NEED_POSIX_SETPGID.
+
+2001-07-23 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.tex (DJGPP Native): New node, with descriptions of
+ DJGPP-specific commands.
+
+2001-07-19 John R. Moore <jmoore@redhat.com>
+
+ * gdbint.texinfo: Three misspellings.
+
+2001-07-06 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in (refcard.dvi): Rewrite to avoid problems with empty
+ `test` expressions on bash. Problem reported by Colin Walters.
+
+2001-07-04 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (User Interface): Update ui-out documentation to
+ refelect recent UI/MI updates.
+
+2001-07-04 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.texinfo (Mode Options): Mention the mi0 and mi1
+ interpreters.
+
+2001-06-15 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): GDBARCH is a C
+ structure and not macros.
+ (Host Definition): Document that much of this chapter is obsolete.
+ (Target Architecture Definition): Update list of files that make
+ up a target architecture.
+ (Coding): Update.
+
+2001-06-28 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Update
+ EXTRACT_STRUCT_VALUE_ADDRESS and EXTRACT_STRUCT_VALUE_ADDRESS_P.
+ The latter has been changed to a true predicate.
+
+2001-06-17 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * annotate.texi: Add @noindent where needed. From Dmitry
+ Sivachenko <dima@Chg.RU>.
+ * gdb.texinfo: Indexing fix. From Dmitry Sivachenko.
+
+2001-06-16 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.texinfo (Protocol): Fix typo. Extra parenthesis.
+
+2001-06-14 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.texinfo (Remote Protocol): Document that the ``!'' packet
+ returns ``OK''. Document that the ``R'' packet does not reply.
+
+2001-06-13 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.texinfo (Protocol): Add doc for new packet "qSymbol:".
+
+2001-06-13 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo (Signals): Clarify the default setting of signal
+ handling.
+
+2001-05-14 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (CLEAR_DEFERRED_STORES): Delete stray @item
+ (FRAME_ARGS_ADDRESS_CORRECT): Ditto.
+
+2001-05-12 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.in (GDBvn.texi): Set GDBVN from ../version.in.
+
+2001-05-10 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdbint.texinfo (Clean Design and Portable Implementation):
+ Renamed from "Clean Design".
+ (Clean Design and Portable Implementation): Document portable
+ methods of handling file names, and the associated macros.
+
+2001-04-02 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo (Tracepoint Actions): Mention the "info scope"
+ command and provide a cross-reference to its description.
+ (Symbols): Note that "info scope" is useful for trace experiments.
+
+2001-04-01 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo (Symbols): Document "info scope".
+ (Tracepoints): New chapter.
+ (Contributors): Update for v5.1.
+ <All nodes>: Change "C++" to "C@t{++}".
+
+ * gdbint.texinfo (User Interface): A new section about ui_out
+ functions, based on text written by Fernando Nasser.
+
+ * stabs.texinfo: Change Permissions to GFDL. Update Copyright.
+
+2001-03-26 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo: Change Permissions to GFDL. Update Copyright.
+
+ * gdbint.texinfo: Change Permissions to GFDL. Update Copyright.
+
+ * gdbgui.texinfo: Change Permissions to GFDL. Update Copyright.
+ Replace "GDB" with "@value{GDBN}". Fix markup.
+
+ * annotate.texi: Change Permissions to GFDL. Update Copyright.
+
+ * gdb.texinfo (Output Formats): Mention "info symbol" and provide
+ a cross-reference to its description.
+ (Symbols): Document "info symbol".
+
+2001-03-21 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdbint.texinfo (Algorithms): New section "Watchpoints" and new
+ subsection "x86 Watchpoints".
+ (Target Architecture Definition): Document the macros
+ I386_USE_GENERIC_WATCHPOINTS and TARGET_HAS_HARDWARE_WATCHPOINTS.
+ (Native Debugging): Document I386_USE_GENERIC_WATCHPOINTS.
+
+2001-03-20 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Update
+ definition of SOFTWARE_SINGLE_STEP_P to include empty parameter
+ list.
+
+2001-03-06 Kevin Buettner <kevinb@redhat.com>
+
+ * Makefile.in, all-cfg.texi, annotate.texi, gdb.texinfo,
+ gdbint.texinfo, refcard.tex: Update/correct copyright notices.
+
+2001-02-21 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo (Signals): Document "ignore", "noignore", and "all".
+
+2001-02-11 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo (Environment): Document that `path' does not change
+ the value of PATH in GDB's own environment (it did in the past,
+ but that was changed on March 15, 1994). Reported by Doug Evans
+ <dje@transmeta.com>.
+
+ * gdbint.texinfo: Fix up @itemize lists so that @item is alone on
+ its line. Fix markup of commands and macros. Add an Index node
+ and index entries.
+
+2001-01-23 J.T. Conklin <jtc@redback.com>
+
+ * gdb.texinfo (Memory region attributes): New manual section.
+
+2001-01-04 Nicholas Duffek <nsd@redhat.com>
+
+ * gdbint.texinfo (POP_FRAME): Document use by return_command.
+
+2000-12-25 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * refcard.tex: Version and copyright fixed. From Phil Edwards
+ <pedwards@disaster.jaj.com>.
+
+Thu Nov 30 16:57:19 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (ECOFF_REG_TO_REGNUM, DWARF_REG_TO_REGNUM,
+ DWARF2_REG_TO_REGNUM): Document.
+
+Mon Nov 20 21:29:35 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (Coding): Update current value of
+ --enable-build-warnings. Mention --enable-gdb-build-warnings.
+
+2000-11-19 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo (Continuing and Stepping): Fixed markup and typos,
+ as suggested by Dmitry Sivachenko <dima@Chg.RU>.
+
+2000-11-10 Christopher Faylor <cgf@cygnus.com>
+
+ * gdb.texinfo: Document new 'set step-mode' command.
+
+2000-10-16 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo (Contributors, MIPS Embedded): Minor spelling
+ changes from Dmitry Sivachenko <dima@Chg.RU>.
+
+2000-09-26 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo (Hooks): Document the new post-hook functionality.
+ From Steven Johnson <sbjohnson@ozemail.com.au>.
+
+2000-08-10 Mark Kettenis <kettenis@gnu.org>
+
+ * gdbint.texinfo (Overall Structure): Spelling fix.
+
+2000-08-10 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdbint.texinfo (Target Architecture Definition): Document that
+ REGISTER_CONVERT_TO_VIRTUAL should only be called on a register
+ for which REGISTER_CONVERTIBLE returns a zero value.
+
+2000-07-08 Christopher Faylor <cgf@cygnus.com>
+
+ * Makefile.in (install-info): Find files to install in either the
+ build or source directories (adapted from Makefile.am).
+
+2000-07-07 Nicholas Duffek <nsd@redhat.com>
+
+ * stabs.texinfo: Fix spelling errors.
+ (String Field): FILE-NUMBER starts from 0, not 1.
+
+2000-07-05 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * refcard.tex: Remove \centerline from the blurb. Patch from
+ Brian Youmans.
+
+2000-06-25 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * Makefile.in (install-info): Support installation from outside of
+ the source directory. Reported by Mark Harig
+ <markh@frazier.landmark.com>.
+
+2000-06-20 J.T. Conklin <jtc@redback.com>
+
+ * gdb.texinfo: Fix typo, $bpnum is set to last breakpoint number.
+
+Fri May 26 15:55:33 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (pdf, gdbint.pdf, gdb.pdf, stabs.pdf): New targets.
+ Generate using pdftex.
+ (PDFTEX): Define.
+ (STAGESTUFF, maintainer-clean realclean): Add *.pdf.
+ (gdb.texinfo, gdbint.texinfo, stabs.texinfo): When TeX insert the
+ @contents at the start.
+
+2000-05-24 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo: Remove duplicate @syncodeindex. From Brian
+ Youmans.
+
+Wed May 24 21:27:58 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Brian Youmans:
+ * gdb.texinfo: Fix ``et al.''.
+
+Tue May 23 22:57:41 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (refcard.dvi): Remove quotes around REFEDITS in for
+ loop.
+
+2000-05-19 Jimmy Guo <guo@cup.hp.com>
+
+ * configure: Regenerate.
+
+2000-05-17 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * Makefile.in (install-info): Run install-info on installed Info
+ files.
+
+Fri May 12 20:18:04 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.texinfo: Add Stan Shebs, et.al. as authors. Mention
+ Andrew Cagney.
+
+2000-05-09 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo: Proofreading changes from Brian Youmans.
+
+2000-05-01 Nick Duffek <nsd@cygnus.com>
+
+ * gdb.texinfo (Command Files): Mention -x, use @enumerate for
+ startup sequence, minor edits.
+
+2000-05-01 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * annotate.texi: Remove "@syncodeindex fn cp", it causes grief in
+ TeX.
+
+ * gdb.texinfo: Add "@syncodeindex fn cp". Convert all entries
+ "@kindex f" into "@kindex f (foo)", otherwise we get index entries
+ like `n' and `s' which look weird. Convert some of the @kindex to
+ @vindex, when they refer to variables, not commands.
+
+Sat Apr 29 17:01:04 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (Hints): Do not use @value{GDBN in @nodes.
+
+2000-04-23 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * Makefile.in (GDBMI_DIR): New variable.
+ (SET_TEXINPUTS): Add $(GDBMI_DIR).
+ (SFILES_DOC): Add $(GDBMI_DIR)/gdbmi.texinfo.
+ (gdbmi.texinfo): New target, for texi2roff.
+ (gdb.me, gdb.ms, gdb.mm): Depend on gdbmi.texinfo.
+ (gdb.info, gdb_toc.html): Add "-I ${GDBMI_DIR}".
+
+ * gdb.texinfo (Top): Add GDB/MI to the main menu and @include
+ gdbmi.texinfo.
+ (Mode Options): Add xref to GDB/MI docs and remove a FIXME
+ comment.
+
+2000-04-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.texinfo (Files): Update description of add-symbol-file
+ command.
+
+2000-04-17 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo (Porting GDB): Don't use @value in the node name, it
+ prevents the build (and is generally a Bad Idea).
+
+2000-04-17 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo (Protocol): Prevent makeinfo from complaining about
+ a comma inside @var.
+ (Command Files): Index markup changes from Dmitry Sivachenko
+ <dima@Chg.RU>.
+
+2000-04-16 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * Makefile.in (LN_S): Define.
+ (gdb-cfg.texi, gdb.dvi, links2roff, inc-hist.texinfo): Don't
+ invoke "ln -s" unless it is known to work.
+
+ * configure.in (AC_PROG_LN_S): Add.
+
+2000-04-14 Jim Blandy <jimb@redhat.com>
+
+ * gdbint.texinfo (Pointers Are Not Always Addresses): New manual
+ section.
+ (Target Conditionals): Document ADDRESS_TO_POINTER,
+ POINTER_TO_ADDRESS.
+
+2000-04-11 Daniel Berlin <dan@cgsoftware.com>
+
+ * gdbint.texinfo: Replaced GDB with @value{GDBN}, @include
+ gdb-cfg.texi to get the value.
+
+2000-04-10 Jim Blandy <jimb@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Fix
+ cross-references.
+
+2000-04-08 Jim Blandy <jimb@redhat.com>
+
+ * gdbint.texinfo (Using Different Register and Memory Data
+ Representations): New section.
+ (REGISTER_CONVERTIBLE, REGISTER_RAW_SIZE, REGISTER_VIRTUAL_SIZE,
+ REGISTER_VIRTUAL_TYPE, REGISTER_CONVERT_TO_VIRTUAL,
+ REGISTER_CONVERT_TO_RAW): Document.
+
+Mon Apr 3 19:16:32 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.texinfo (Protocol): Deprecate the sequence-id. Add cindex
+ for acknowledgments.
+
+Tue Mar 28 18:28:45 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.texinfo (Protocol): Replace ``qfThreadExtraInfo'' with
+ qThreadExtraInfo.
+
+2000-03-28 J.T. Conklin <jtc@redback.com>
+
+ * gdb.texinfo: Clarify which remote debug protocol commands are
+ required and which are optional.
+
+Tue Mar 28 16:06:22 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.texinfo: Revert remainder of Fri Mar 24 18:06:34 2000 Andrew
+ Cagney <cagney@b1.cygnus.com>. Move @chapter and @node entries
+ back to annotate.texi, rluser.texinfo and inc-hist.texinfo.
+ * annotate.texi: Update.
+
+2000-03-28 Stan Shebs <shebs@apple.com>
+
+ * gdb.texinfo: Update dates, bump to Eighth Edition (note
+ expectation of additional changes before release), update
+ ISBN, add copy of top-level menu for @ifhtml, remove explicit
+ node links, rephrase and/or shorten lines to fix formatting
+ problem in both regular and @smallbook formats.
+ * annotate.texi: Shorten lines in example, use smallexample
+ consistently everywhere.
+ * Makefile.in: Add comment about texinfo 4.0 html generation.
+ (SFILES_INCLUDED): Add annotate.texi.
+
+2000-03-27 Daniel Berlin <dan@cgsoftware.com>
+
+ * gdb.texinfo (Debugging Output): Added new section, documenting
+ the "set/show debug" commands.
+
+Fri Mar 24 18:06:34 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * annotate.texi (Annotations): When GDBN omit @chapter and @node
+ entry.
+
+ * gdb.texinfo: Check for @ifinfo instead of @ifnottex.
+ (rluser.texinfo, inc-hist.texinfo, annotate.texi): Add local
+ @chapter and @node entries.
+
+ * gdb.texinfo: Link all top-level nodes.
+
+Fri Mar 24 17:56:48 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (install-info): Create $(infodir) before installing
+ files.
+
+2000-03-23 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From David Whedon <dwhedon@gordian.com>
+ * gdbint.texinfo : Added paragraphs about command deprecation.
+
+2000-03-22 Daniel Berlin <dan@cgsoftware.com>
+
+ * gdb.texinfo: Add documentation for the apropos command.
+
+2000-03-20 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * gdb.texinfo: Add new queries ThreadInfo and ThreadExtraInfo.
+
+2000-03-20 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * gdb.texinfo: Add white space to prevent overprinting in
+ two places.
+
+2000-03-17 Stan Shebs <shebs@apple.com>
+
+ * gdb.texinfo: Many minor changes from Dmitry Sivachenko
+ <dima@Chg.RU>, also clarification of allowed content for
+ string constants.
+
+2000-03-16 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo (main menu): Add Annotations.
+ (File Options): Add @cindex entries for each command-line option.
+ Document --epoch, --annotate, --async, --interpreter, --write,
+ --statistics, and --version.
+
+ * annotate.texi: Convert to a chapter. Use @value{GDBN} instead
+ of GDB.
+
+2000-02-23 Jim Blandy <jimb@redhat.com>
+
+ * gdbint.texinfo (FUNCTION_START_OFFSET): Document.
+
+2000-02-22 Jim Blandy <jimb@redhat.com>
+
+ * gdbint.texinfo: Document COERCE_FLOAT_TO_DOUBLE --- the new form.
+
+2000-02-15 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * Makefile.in (diststuff): New target.
+
+2000-02-15 Kevin Buettner <kevinb@redhat.com>
+
+ * agentexpr.texi: Fix wording regarding Intel's IA-64
+ architecture. [From Jim Wilson.]
+
+2000-01-16 Tom Tromey <tromey@cygnus.com>
+
+ * gdb.texinfo (Breakpoints): Mention breakpoint ranges.
+ (Delete Breaks): Mention range arguments.
+ (Disabling): Likewise.
+
+2000-01-05 Dmitry Sivachenko <dima@Chg.RU>
+
+ * gdb.texinfo: Wrap "ASCII" in @sc{}; clarify a few sentences.
+
+Wed Dec 8 19:53:08 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (FRAME_CHAIN_VALID): Add the generic frame-chain
+ valid functions.
+
+1999-11-05 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo: Clarify regular expressions used in rbreak.
+
+1999-10-15 Kevin Buettner <kevinb@cygnus.com>
+
+ * gdbint.texinfo (MEMORY_INSERT_BREAKPOINT,
+ MEMORY_REMOVE_BREAKPOINT): Document.
+
+Thu Oct 14 21:17:17 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.texinfo (remote): Document how GDB ignores the qOffsets BSS
+ offset re-using the DATA offset instead.
+
+1999-10-11 Jim Kingdon <kingdon@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Add PARM_BOUNDARY.
+
+1999-10-05 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Dmitry Sivachenko <demon@gpad.ac.ru>:
+ * gdb.texinfo: Use GDBP and GDBN everywhere, fix a couple other
+ typos.
+
+ * gdb.texinfo: Various minor wording and formatting improvements,
+ mentions of additional command-line options.
+
+1999-09-30 Fred Fish <fnf@cygnus.com>
+
+ * gdb.texinfo: Document additional forms of specifying section
+ names and addresses for the add-symbol-file command.
+
+1999-09-14 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * gdbint.texinfo: Fix typo, add the word "have".
+
+1999-09-14 Jim Blandy <jimb@cris.red-bean.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Document the
+ SKIP_PERMANENT_BREAKPOINT macro.
+
+1999-09-07 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo: Fiks speling errers.
+
+ * gdb.texinfo: Fix uses of @multitable.
+
+ From Eli Zaretskii <eliz@is.elta.co.il>:
+ * gdb.texinfo: Include details specific to DOS host, clarify
+ some confusing language, fix @ref/@xref/@pxref usages, add
+ comments about using with optimization, add more indexing,
+ fix info about disassembly-flavor.
+
+Tue Sep 7 09:11:24 1999 Kevin Buettner <kevinb@cygnus.com>
+
+ * gdbint.texinfo (IN_SOLIB_DYNSYM_RESOLVE_CODE,
+ SKIP_SOLIB_RESOLVER): Define.
+
+Fri Sep 3 18:05:14 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.texinfo (Protocol): Review. Add tables describing ``q'' and
+ ``g'' packets.
+
+1999-08-30 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo: Create a new "Configurations" chapter with
+ platform-specific info, inline remote.texi and move sections of it
+ into the new chapter, move bits about info proc, heuristic search,
+ and register stack into the new chapter.
+ * remote.texi: Remove, now part of gdb.texinfo.
+ * Makefile.in (SFILES_INCLUDED): Remove ref to remote.texi.
+
+1999-08-27 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * gdbint.texinfo (GDB_TARGET_IS_SUN3, GDB_TARGET_IS_SUN386,
+ GDB_TARGET_IS_MACH386): These kludges have gone away.
+
+Wed Aug 25 10:47:03 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Mention
+ TDEPLIBS.
+
+1999-08-20 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo: Remove remaining "HPPA" conditionals, rewrite
+ surrounding text to fit HP-UX bits into general info.
+ (HPPA-cfg.texi): Remove, no longer useful.
+
+ * gdb.texinfo: Remove explicit links from @node lines, remove
+ HP-added "Detailed Node Listing" from main menu which confuses
+ things.
+
+ From Dmitry Sivachenko <dima@Chg.RU>:
+ * gdb.texinfo: Use @value{GDBN} instead of plain GDB, fix grouping
+ in description of `set environment'.
+
+1999-08-17 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdbint.texinfo: Update coding standard to allow pure ANSI/ISO C.
+
+1999-08-12 Ben Elliston <bje@cygnus.com>
+
+ * gdbint.texinfo (Breakpoint Handling): Add missing words.
+
+1999-08-10 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdb.texinfo (Set Watchpoints): Explain some subtleties about
+ watch, awatch, and rwatch. Explain why the latter two cannot be
+ set as software watchpoints. Document that watchpoints for local
+ variables are deleted when the debuggee terminates.
+
+Wed Aug 11 13:18:14 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * remote.texi (Protocol): Further clarification of the "qRcmd"
+ packet. Allow E.. response packet. "qRcmd" packet is no longer
+ reserved.
+
+1999-08-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * Makefile.in: Rename inc-hist.texi to inc-hist.texinfo.
+ * gdb.texinfo: Ditto.
+
+1999-08-06 Tom Tromey <tromey@cygnus.com>
+
+ * gdb.texinfo (KOD): New node.
+
+Fri Aug 6 17:05:48 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.texi (Rcmd): Fix minor formatting typos.
+
+Thu Aug 5 17:57:41 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.texi (protocol qRcmd): Allow ``OK'' and ``O...'' response
+ packets.
+
+1999-07-14 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdbint.texinfo (PREPARE_TO_PROCEED, ADDR_BITS_REMOVE): Doc
+ fixes.
+
+Tue Jun 29 11:43:55 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (SAVE_DUMMY_FRAME_TOS): Define.
+
+Fri Jun 25 11:47:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.texi (Communication Protocol): ``v'' is in use. Fix
+ numerous formatting errors. Clarify ``i''. Mark ``i'', ``Z'',
+ ``z'' and ``qRcmd'' as draft instead of reserved. Identify
+ packets that are not supported on all hosts. Expand examples.
+ Spell check.
+
+1999-06-24 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * Makefile.in: Recognize html, install-html. Add targets
+ to build HTML versions of documentation via texi2html.
+
+Thu Jun 24 15:59:03 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdbint.texinfo (Testsuite): New chapter, information about the
+ testsuite.
+
+Fri Jun 25 02:40:34 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote.texi (Communication Protocol): Rewrite.
+
+Thu Jun 24 16:59:54 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * stabs.texinfo: Fix uses of xref.
+
+Thu Jun 17 17:23:25 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdbint.texinfo: Add an anti-printf exhortation, and update the
+ info about patch submission.
+
+Mon Jun 7 15:49:40 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Per Bothner <bothner@cygnus.com>:
+ * gdb.texinfo: Document Chill support.
+
+Fri Jun 4 16:58:22 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (SP_REGNUM, FP_REGNUM, PC_REGNUM): Add reference
+ to corresponding TARGET_READ_reg TARGET_WRITE_reg macros.
+ Document that the value should be greater-than or equal-to zero.
+ (NO_STD_REGS): Document. Deprecate.
+
+Tue Jun 1 15:04:15 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (TARGET_COMPLEX_BIT, TARGET_DOUBLE_COMPLEX_BIT):
+ Document that these are not used.
+
+Thu May 27 09:28:15 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (EXTRACT_STRUCT_VALUE_ADDRESS_P): Document.
+
+Mon May 24 10:07:39 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (FRAME_NUM_ARGS): Update definition. Parameter
+ numargs was dropped.
+
+Thu May 20 12:26:59 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (FRAMELESS_FUNCTION_INVOCATION): Update.
+
+Tue Apr 27 19:14:20 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (SKIP_PROLOGUE, SKIP_PROLOGUE_FRAMELESS_P):
+ Update.
+
+Thu Apr 22 13:07:37 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (USE_GENERIC_DUMMY_FRAMES): Document.
+ (GET_SAVED_REGISTER): Update, not just the a29k uses this.
+
+Wed Apr 21 13:59:01 1999 Dave Brolley <brolley@cygnus.com>
+
+ * gdbint.texinfo: Fix typos: $ -> @.
+
+Tue Apr 20 11:59:38 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (REGISTER_NAMES, BREAKPOINT, BIG_BREAKPOINT,
+ LITTLE_BREAKPOINT, LITTLE_REMOTE_BREAKPOINT,
+ BIG_REMOTE_BREAKPOINT): Deprecate in favor of REGISTER_NAME and
+ BREAKPOINT_FROM_PC.
+
+Mon Apr 12 16:00:44 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (CALL_DUMMY_STACK_ADJUST_P,
+ CALL_DUMMY_STACK_ADJUST): Document.
+
+Thu Apr 8 17:23:15 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (CALL_DUMMY_P, CALL_DUMMY_WORDS,
+ SIZEOF_CALL_DUMMY_WORDS, CALL_DUMMY): Define.
+
+1999-04-02 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdbint.texinfo (MAINTENANCE_CMDS): Remove ref, since it no
+ longer exists.
+
+Tue Mar 9 19:25:11 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo, remote.texi, all-cfg.texi, HPPA-cfg.texi: Remove
+ nearly all @ifset/@ifclear conditionals; nobody uses them, and
+ they make the manual source incomprehensible.
+ * h8-cfg.texi: Remove, hasn't been used in years.
+
+Thu Feb 11 18:00:59 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo: Update the credits.
+
+Mon Feb 8 17:33:57 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo: Fix mistakes noticed in printout of last
+ draft, add Alpha to discussion of heuristic fence post.
+
+Fri Feb 5 17:20:00 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo, remote.texi: Many changes; update to Seventh
+ Edition, merge some HP changes into mainline, describe some
+ previously undocumented features, describe more of the target
+ commands available, eliminate obsolete section on renamed
+ commands.
+ * all-cfg.texi, HPPA-cfg.texi: Remove some obsolete conditionals.
+
+Wed Jan 20 17:47:45 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo: Make many HPPA conditionals unconditional,
+ including catchpoint description, since now on for all configs.
+ * all-cfg.texi: @clear HPPA, since is mainly for very HP-specific
+ specializations.
+
+Thu Jan 14 17:10:12 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * Makefile.in (GDBvn.texi): Fix match expression to work with
+ current format of VERSION in gdb/Makefile.in.
+ * gdb.texinfo: Fix node ref to match new readline.
+
+Wed Jan 13 10:38:40 1999 Edith Epstein <eepstein@sophia.cygnus.com>
+
+ * gdb.texinfo: Changes made as part of a project to merge in
+ changes made by HP. Documentation makes extensive use of
+ @ifclear HPPA and @ifset HPPA. The HP manual omits doumentation
+ on remote debugging. There are differences in documentation
+ (HP vs. non-HP) on C++ support (aCC vs. gnu gcc++). Also,
+ the HP manual discusses catchpoints, hardware watchpoints, and
+ some HPUX specific limitations for shared library support.
+
+ There are also a number of @node changes.
+
+1999-01-12 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * gdbint.texinfo (Formatting): Disambiguate a sentence.
+ (C Usage): Same.
+
+Wed Jan 6 11:55:34 1999 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by Edith Epstein
+ <eepstein@cygnus.com> as part of a project to merge in changes
+ made by HP.
+
+ * HPPA-cfg.texi: new file.
+
+ * all-cfg.texi: set HPPA for HP PA-RISC targets.
+
+ * refcard.tex: change documentation about catch.
+ removed info catch.
+
+Mon Jan 4 18:29:18 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdbint.texinfo: Expand on GDB's coding standards,
+ specify the use of arg names with prototypes.
+
+1998-12-14 J.T. Conklin <jtc@redbacknetworks.com>
+
+ * gdb.texinfo: Fix tipo.
+
+Sun Dec 13 10:27:59 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo: Document TARGET_BYTE_ORDER_DEFAULT and
+ TARGET_BYTE_ORDER_SELECTABLE_P.
+
+Thu Dec 10 16:07:09 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (FRAME_FIND_SAVED_REGS): Document.
+
+1998-12-09 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * agentexpr.texi: New file.
+
+Wed Dec 9 21:13:57 1998 Andrew Cagney <cagney@chook>
+
+ * gdbint.texinfo (REGISTER_NAME): Replace REGISTER_NAMES.
+
+1998-12-03 J.T. Conklin <jtc@redbacknetworks.com>
+
+ * remote.texi: Changed wording that implied that the GDB remote
+ protocol caches register values instead of GDB itself.
+
+Tue Dec 1 17:45:43 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdbint.texinfo: Add some info about symbol readers.
+ (CHILL_PRODUCER, etc): Comment out descriptions, not useful.
+ (IN_SOLIB_CALL_TRAMPOLINE): Rename info from IN_SOLIB_TRAMPOLINE.
+ (IN_SOLIB_RETURN_TRAMPOLINE): Describe.
+ (KERNEL_DEBUGGING, MIPSEL): No info about these, remove.
+
+Mon Nov 30 11:32:21 1998 Andrew Cagney <cagney@chook>
+
+ * gdbint.texinfo (FRAME_CHAIN_VALID_ALTERNATE):
+
+Sat Nov 28 13:45:53 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (INNER_THAN): Update, now takes parameters.
+
+Fri Nov 27 12:39:45 1998 Andrew Cagney <cagney@chook>
+
+ * gdbint.texinfo (NO_SINGLE_STEP): Replace with
+ SOFTWARE_SINGLE_STEP_P and SOFTWARE_SINGLE_STEP.
+
+Wed Oct 14 10:02:40 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo: Fix minor typos.
+
+Wed Sep 30 18:03:19 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdbint.texinfo: Complete overhaul. Group descriptions more
+ logically, add more info on generic algorithms, remove much
+ obsolete and/or wrong material.
+
+Fri Jul 24 17:51:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.texinfo (Method Type Descriptor): Expand and correct.
+
+Mon May 4 10:37:12 1998 Brian Youmans (3diff@gnu.org)
+
+ * refcard.tex: Copyright, address updates.
+
+Tue Apr 21 18:09:56 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo (EDITION, DATE): Update and change to use ordinals
+ for the edition instead of confusing GDB-version-like numbers.
+
+Mon Apr 13 14:05:00 1998 Fred Fish <fnf@cygnus.com>
+
+ * gdb.texinfo (hbreak, watch): Fix typo, "date" -> "data".
+
+Thu Apr 2 16:52:44 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * LRS: Reformat a bit to keep text under 80 columns.
+
+Thu Apr 2 16:10:36 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo: Add some credits, mention bug monitor.
+ * remote.texi: Mention mips monitor targets.
+ * gdbint.texinfo: Describe SP_REGNUM, STEP_SKIPS_DELAY.
+
+Mon Feb 2 17:13:03 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdbint.texinfo: Remove obsolete mentions of pinsn.c and opcode.h
+ files, finish sorting of host vs target vs native macros, describe
+ some more of them.
+
+Tue Jan 13 16:44:50 1998 Fred Fish <fnf@cygnus.com>
+
+ * gdbint.texinfo (Host Conditionals): Document change from
+ using NO_MMALLOC to it's inverse, USE_MMALLOC.
+
+Mon Nov 24 13:55:21 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbint.texinfo (Host Conditionals): Document
+ PRINTF_HAS_LONG_DOUBLE, SCANF_HAS_LONG_DOUBLE, HAVE_LONG_DOUBLE.
+
+Fri Jul 4 14:52:31 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gdbint.texinfo (Host Conditionals): Add CRLF_SOURCE_LINES.
+ Document LSEEK_NOT_LINEAR.
+
+Tue Mar 25 14:44:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.texinfo (Stab Section Basics): Make it clear that only
+ some versions of the GNU linker remove the leading N_UNDF symbol.
+
+Thu Feb 27 17:45:19 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.texinfo (String Field): Document type number pairs here,
+ instead of in the Sun specific section.
+ (Include Files): The GNU linker supports the N_BINCL
+ optimization. Clarify the N_BINCL value, and what it is used
+ for.
+ (Procedures): Document N_FUN with an empty string to mark the end
+ of a function.
+ (Typedefs): Mention that Sun compilers may use N_GSYM for a type.
+ (Sun Differences): Remove this node, as the information is now
+ elsewhere in the main document.
+ (Stab Section Basics): Mention that the GNU linker may optimize
+ stabs and remove the leading N_UNDF symbol.
+
+Mon Dec 9 12:23:32 1996 Roland Pesch <roland@wrs.com>
+
+ * gdb.texinfo, refcard.tex: Restore author credit
+
+Wed Oct 2 22:01:36 1996 Fred Fish <fnf@fishfood.ninemoons.com>
+
+ * gdbint.texinfo (SIGTRAMP_START, SIGTRAMP_END): Update
+ documentation to account for START and END macros taking
+ one arg.
+
+Thu Aug 22 17:59:03 1996 Fred Fish <fnf@cygnus.com>
+
+ From: Eberhard Mattes <mattes@azu.informatik.uni-stuttgart.de>
+ * gdb.texinfo (Frames): Fix typo.
+
+Tue Jul 23 10:06:20 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdbint.texinfo (NO_SINGLE_STEP): Document that single_step takes
+ a target_signal as arg type, not a pid.
+
+Fri Jul 12 11:10:05 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * gdb.texinfo: Document `set assembly-language'.
+
+Thu Jul 11 13:50:28 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * remote.texi: Update list of stubs in the GDB distribution.
+
+Fri Jul 5 15:38:54 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdbint.texinfo (NO_MMCHECK): Renamed from NO_MMALLOC_CHECK.
+ Also document that some systems can use mmalloc but must define
+ this if their C runtime allocates memory that is later freed.
+ (MMCHECK_FORCE): Document new macro.
+
+Fri Jun 28 22:17:10 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * remote.texi: Add documentation for target Sparclet.
+
+Mon Jun 24 18:12:22 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (srcdir, VPATH, prefix, infodir, INSTALL,
+ INSTALL_PROGRAM, INSTALL_DATA): Use autoconf set values.
+ * configure.in: Rewritten for autoconf.
+ * configure: New.
+
+Mon Jun 17 10:43:41 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (DVIPS): New define, set to dvips.
+ (dvi): Add stabs.dvi.
+ (ps): New target.
+ (all-doc): Depend on info, dvi, and ps targets.
+ (STAGESTUFF): Add *.ps and *.dvi files.
+ (clean-info, clean-dvi): Remove.
+ (mostlyclean): Does not depend upon clean-info or clean-dvi,
+ rules completely rewritten.
+ (maintainer-clean): Remove clean-info and clean-dvi
+ dependencies and put their actions in the rules.
+ (gdb.ps): New target
+ (gdb.dvi, gdbgui.dvi, gdbint.dvi, stabs.dvi): Remove
+ intermediate TeX files, whether they have 2 or 3 character
+ extensions.
+ (gdbint.ps): Add target and rules.
+ (gdb-internals): Delete unused target.
+ (Makefile): Depends upon config.status also.
+
+Sat Mar 30 15:46:58 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdbint.texinfo (CC_HAS_LONG_LONG): Clarify when/how this is
+ set.
+
+Sat Mar 16 15:10:20 1996 Fred Fish <fnf@cygnus.com>
+
+ From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
+ * gdb.texinfo (Expressions): Fix erroneous array constant example.
+
+Sat Mar 16 13:28:45 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.texinfo: Add missing "@bullet" to some "@itemize" commands.
+
+Sat Feb 10 03:28:36 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.texinfo (Print settings): Document
+ `set/show print static-members' commands.
+
+Wed Jan 10 14:16:37 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdbint.texinfo (Native): Document name change, coredep.c to
+ core-aout.c.
+
+Wed Dec 13 12:35:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.texinfo (Include Files): Document the values the SunOS4
+ linker creates for N_BINCL/N_EINCL/N_EXCL stabs.
+
+Fri Dec 8 21:08:44 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdbint.texinfo (Releases): Change gdb.tar.Z to gdb.tar.gz.
+ Fix typo.
+
+Fri Dec 1 11:07:50 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdbint.texinfo (Releases): Make "gdb.tar.gz" rather than
+ "gdb.tar.Z".
+
+Wed Sep 20 13:14:10 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean): New target, synonym for
+ realclean.
+
+Thu Aug 3 10:45:37 1995 Fred Fish <fnf@cygnus.com>
+
+ * Update all FSF addresses except those in COPYING* files.
+
+Wed Jul 19 18:43:03 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Richard Earnshaw (rearnsha@armltd.co.uk):
+ * gdb.texinfo (convenience variables): Document $_exitcode.
+ (quit): Document optional expression to use as exit code.
+
+Thu Jun 22 21:27:33 1995 Victoria Mixon <victoria@cygnus.com>
+
+ * gdb.texinfo, remote.texi: Brought up to date with various
+ GDB changes.
+
+Tue Jun 20 14:35:38 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.texinfo: Update dates and versions, fix comments about
+ hardware watchpoints in future releases and about the
+ sharedlibrary command.
+
+Mon May 8 09:30:36 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo: Remove node `XCOFF differences'. Describe value of
+ C_FUN stab. Other cleanups.
+
+Wed Apr 19 07:02:19 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote.texi (Bootstrapping): Clarify that flush_i_cache is only
+ for the sparc stub.
+
+Tue Apr 11 11:41:49 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * annotate.texi: Clarify which addresses have differing formats
+ depending on the language and which do not.
+
+Tue Mar 28 16:56:22 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * remote.texi (NetWare): Changed example to use BOARD= instead of
+ NODE= argument to reflect correspoding change to gdbserve.nlm.
+
+Fri Mar 17 06:47:02 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Negative Type Numbers): Mention the fact that
+ GDB, as well as AIX dbx, supports the size type attribute.
+
+Thu Mar 16 12:11:32 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Negative Type Numbers): Document types -31 to -34.
+
+Mon Mar 13 16:49:13 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * gdb.texinfo (Define): Document $arg0... arguments to commands,
+ and new 'if' and 'while' commands.
+
+Fri Feb 17 15:24:35 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * gdb.texinfo (Artificial arrays): Note use of coerce-to-array-type.
+
+Wed Feb 15 11:59:18 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * all-cfg.texi: New flag, GDBSERVE, for NetWare's gdbserve.nlm.
+ * remote.texi (NetWare): New node, how to use gdbserve.nlm on
+ NetWare targets. Mostly stolen from the Server node.
+
+Fri Feb 10 20:20:08 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.texinfo (Setting): Talk about the language of a source file
+ versus the working language. The old documentation did not match
+ what GDB did.
+
+Wed Feb 1 20:26:36 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Source Files): Document N_SO used to mark the end
+ of a source file.
+
+Mon Jan 23 14:23:37 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.texinfo (Processes): New node.
+
+Tue Jan 17 14:09:03 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * remote.texi: Update documentation of set/show mipsfpu.
+
+Fri Jan 6 17:17:28 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdbgui.texinfo: New file, manual for GUI (gdbtk) users.
+ * Makefile.in (gdbgui.dvi, gdbgui.info): New actions.
+
+Sun Sep 4 16:47:21 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * gdbint.texinfo: Removed mentions of some incorrectly placed and
+ obsolete conditionals, described some others.
+
+Mon Aug 1 15:42:39 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbint.texinfo: Remove references to BROKEN_LARGE_ALLOCA and
+ SET_STACK_LIMIT_HUGE; they were removed from GDB 14 May 1994.
+
+Mon Aug 1 15:12:02 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * gdbint.texinfo: Put regex conditionals in their own table.
+
+Tue Jul 26 18:32:52 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * gdbint.texinfo: Removed mentions of many obsolete conditionals,
+ described or fixed the descriptions of many others.
+
+Sun Jul 17 14:14:03 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * gdb.texinfo: Add some more credits.
+ * gdbint.texinfo: Capitalize GDB consistently, describe some
+ macros and remove some.
+
+Thu Jul 14 18:43:17 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * gdbint.texinfo: Removed mentions of many incorrectly placed and
+ obsolete conditionals, described some others.
+
+Tue Jul 12 12:23:15 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.texinfo (help targets): Changed to `help target', which
+ is the correct gdb command.
+
+Wed Jun 22 18:00:51 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * annotate.texi (TODO): New node, for keeping track of annotations
+ suggested but not yet implemented.
+
+Wed Jun 1 16:10:45 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Statics): Value of xcoff C_BSTAT points to
+ another symbol, it is not the address itself.
+
+Thu May 5 20:23:36 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * stabs.texinfo (Stab Section Basics): Add comment about alignment
+ of stabs-in-coff sections.
+
+Wed May 4 06:26:11 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * annotate.texi: Change edition to 0.5 and date to May 1994.
+ Add index.
+ (Frames): New node, for frame annotation.
+ (Displays): New node, for display annotation.
+
+ * remote.texi (MIPS Remote): Say that set timeout doesn't apply
+ when waiting for your program to stop.
+
+Fri Apr 29 18:24:46 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * annotate.texi (Breakpoint Info): Document annotation of header
+ fields and record annotation.
+
+Thu Apr 28 07:44:28 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * annotate.texi: New file, to document annotations.
+
+Thu Apr 21 14:20:51 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (clean): Don't remove GDBvn.texi (apparently on Jan
+ 16 I meant to make this change but did not). Do remove gdb-cfg.texi.
+
+Wed Apr 20 11:22:48 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Stab Section Basics): Say what is in .stab
+ section, and say n_strx field is compilation unit relative.
+ * stabs.texinfo: Don't use @code for a.out when it is the name of
+ an object file format.
+
+Wed Apr 13 20:29:54 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * gdb.texinfo: Refer to file names, not path names, per rms
+ convention.
+ (Arguments): Fix typo.
+
+Thu Mar 24 08:09:12 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Global Variables): Talk about stabs in files
+ where variables are referenced, but not defined.
+
+Wed Mar 23 07:16:36 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo: Move stuff on @ and # type descriptors from node
+ Cplusplus to new nodes Member Type Descriptor and Method Type
+ Descriptor. Re-write stuff for #.
+
+Wed Mar 16 08:20:19 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.texinfo (Print Settings): Don't document "set print
+ fast-symbolic-addr off". The bug which it worked around was fixed
+ on 25 Feb 94 in coffread.c, so I'm nuking the command.
+
+ * stabs.texinfo (Alternate Entry Points): New node, rewritten from
+ N_ENTRY node.
+
+ * stabs.texinfo (Type Descriptors): Add 'Y' type descriptor.
+
+Tue Mar 15 08:43:02 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbint.texinfo (Host Conditionals, Target Conditionals): Remove
+ references to ieee-float.c.
+
+Fri Mar 11 08:09:40 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.texinfo (Set Breaks): Update documentation for tbreak to
+ match what the code actually does.
+
+Wed Mar 9 19:43:05 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Symbol Descriptors): Add OS9000 symbol descriptor s.
+
+Tue Mar 1 17:04:43 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * stabs.texinfo (Type Descriptors): Add OS9000 type descriptors c,
+ i, and b.
+
+Wed Feb 23 10:44:18 1994 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * stabs.texinfo: Document N_RBRAC as function relative for COFF as
+ well as for ELF and SOM. Unify the descriptions of ELF and SOM
+ as "stabs in sections" rather than just saying "ELF and SOM".
+ Also make that stuff apply to COFF.
+
+Fri Feb 18 08:25:58 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.texinfo (Formatting Documentation): Change GhostScript to
+ Ghostscript.
+
+Fri Feb 4 06:31:31 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.texinfo (Continuing and Stepping): When talking about "step"
+ versus functions without line numbers, also mention stepping into
+ them as well as "step" when you are in them. Tell the user how to
+ deal with the situation. Add comment about "debugging information".
+
+Thu Feb 3 11:39:59 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Enumerations): Document restriction on where
+ enumeration types can appear and still win with GDB.
+
+Wed Feb 2 11:29:17 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Negative Type Numbers): Document format for type
+ -16.
+
+Thu Jan 27 16:53:56 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.texinfo (Selection, Frame Info): Update information about
+ arbitrary frame specficiations.
+
+Wed Jan 26 15:31:57 1994 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo, remote.texi: general editing pass prior to Net release
+
+Tue Jan 25 12:12:04 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (String Field): Discuss continuing stabs with ?.
+
+Wed Jan 19 06:39:24 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * stabs.texinfo (Non-Stab Symbol Types): Mention N_SET* | N_EXT.
+
+Sun Jan 16 12:43:32 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo: Re-do stuff about C_BSTAT and move from XCOFF
+ Differences node to Statics node.
+ (Statics): Discuss XCOFF use of V symbol descriptor.
+
+ * Makefile.in: Remove refcard.dvi and GDBvn.texi in realclean,
+ not clean.
+
+Wed Jan 12 21:29:54 1994 John Gilmore (gnu@cygnus.com)
+
+ * gdb.texinfo (Print Settings): Document `set print
+ fast-symbolic-addr' and improve the doc for some other
+ `set print's.
+
+Mon Jan 3 17:23:07 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (String Field): Talk about defining several type
+ numbers at once.
+ Fix lint regarding changing node ELF Transformations to
+ ELF and SOM Transformations.
+
+Fri Dec 31 00:42:43 1993 John Gilmore (gnu@cygnus.com)
+
+ * stabs.texinfo: Insert Peter Kessler's name as inventor (I think).
+
+Tue Dec 28 09:30:40 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Cross-References): `::' is for nested types only
+ within <>.
+ (Structures): Document static members.
+
+Mon Dec 27 13:55:04 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo: Document S type attribute.
+
+Sun Dec 26 20:46:36 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * stabs.texinfo: Add notes about stabs-in-som where appropriate.
+
+Fri Dec 3 19:13:19 1993 John Gilmore (gnu@cygnus.com)
+
+ * gdbint.texinfo: Fix a few typos.
+
+Sun Nov 28 18:06:25 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo, remote.texi: formatting improvements
+
+ * gdb.texinfo (New Features): mention threads.
+ (Summary, C): fix xrefs in newly contributed text.
+ (Threads): index entries, clarifications, example
+ (passim): minor typos fixed, phrasing improvements
+
+ * remote.texi (Bootstrapping): rephrase text on ^C and add index
+ entries; (Server): explain use of gdbserver w/real-time systems,
+ add example of conflicting TCP port; (MIPS Remote) break up
+ running text into table, highlighting commands, and add example.
+
+Wed Nov 24 14:15:56 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * refcard.tex: avoid bad linebreaks even when REFEDITS=psrc.sed
+
+Fri Nov 12 16:10:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Nested Symbols): New node.
+ (String Field, Symbol Descriptors, Cross-References): Refer to it.
+
+Thu Nov 11 13:26:45 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Stabs in ELF): Clarify how Bbss.bss work with respect
+ to picking which Bbss.bss symbol to use, and (because there seems to
+ be no good way of doing it) re-write some of the text to make it
+ sound like Bbss.bss isn't such a great idea after all (as currently
+ designed).
+
+ * gdb.texinfo (C): In addition to saying people have to use g++ for
+ good results, say they have to use stabs. Specifically say cfront
+ doesn't work well.
+ (Summary): Merge in information on Modula-2, Pascal, and Chill from
+ the gdb README. Add xrefs to places where the support for the various
+ languages is described in detail.
+
+Mon Nov 8 11:47:34 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo: Clean up stuff about visibility and virtual
+ characters.
+
+ * stabs.texinfo (N_M2C): Cite Sun doc.
+
+Fri Nov 5 16:27:27 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo: updates re threads.
+ * remote.texinfo: avoid index entries starting with digits.
+
+Tue Nov 2 09:08:37 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Enumerations): Talk about large, negative and
+ octal values. Clean up cross reference to type attributes.
+ (String Field): Say that GDB 4.11 supports size attribute.
+
+Sun Oct 31 13:31:10 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote.texi (VxWorks Remote): Clarify that rebuilding VxWorks kernel
+ is a mandatory step. Make the stuff about that more concise.
+
+Wed Oct 27 00:25:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Class Names): New node.
+
+ * gdb.texinfo (Command Files): Explain order of init file reading.
+
+ * remote.texi (Bootstrapping): Talk about getting the serial driver
+ to deal with ^C sent by gdb to stop the remote system.
+
+Mon Oct 25 03:25:41 1993 Tom Lord (lord@cygnus.com)
+
+ * libgdb.texinfo (I/O): incorporated better phrasing from rich.
+
+ * libgdb.texinfo (Defining Commands): made the DOC arg
+ to gdb_define_app_command a char * instead of char **
+ per a suggestion from kingdon.
+
+ * libgdb.texinfo: total rewrite from a different starting
+ premise.
+
+Wed Oct 20 18:07:44 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Local Variable Parameters): Re-write paragraph on
+ floats passed as doubles (to improve clarity).
+
+Tue Oct 19 14:21:18 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo (Source Path): index entries for $cwd, $pdir
+
+ * a4rc.sed: update to work with Andreas Vogel papersize params
+
+ * refcard.tex: use Andreas Vogel simplifications of papersize
+ params; remove useless version info; update copyright date.
+
+Tue Oct 19 10:46:22 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.texinfo (Symbols): Add class NAME to doc for ptype.
+
+Tue Oct 12 09:11:45 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.texinfo (Files): Say what address the load command loads it at.
+
+ * stabs.texinfo (Common Blocks): Minor cleanups.
+
+ * stabs.texinfo: Update ld stabs in elf relocation to reflect the fact
+ that Sun has backed away from the linker kludge and thus the relevant
+ issue is changes to the SunPRO tools, not the Solaris linker.
+
+ * stabs.texinfo (Traditional Integer Types): Clean up description
+ of octal bounds a little bit. Document extra leading zeroes.
+
+Thu Oct 7 16:15:37 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.texinfo (Signaling): Update for symbolic symbol names
+ and add a section explaining the difference between the GDB
+ signal command and the shell kill utility.
+
+Wed Oct 6 13:23:01 1993 Tom Lord (lord@rtl.cygnus.com)
+
+ * libgdb.texinfo: added `@' to braces that were unescaped.
+
+Mon Oct 4 10:42:18 1993 Tom Lord (lord@rtl.cygnus.com)
+
+ * libgdb.texinfo: new file. Spec for the gdb library.
+
+Sun Oct 3 15:26:56 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Include Files): Fix typo (start -> end).
+
+Thu Sep 30 18:24:56 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo, remote.texi: assorted small improvements, mostly
+ from Melissa at FSF's editing pass.
+
+Thu Sep 30 11:54:38 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.texinfo: Remove stuff about ar and 14 character filenames.
+ I believe this was fixed by the 13 Sep 89 change to print_frame_info.
+ Also, modern versions of ar like BSD 4.4 or SVR4 don't have this bug.
+
+Wed Sep 22 21:22:11 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * remote.texi (Bootstrapping): Discuss 386 call gates.
+
+Sat Sep 18 17:10:44 1993 Jim Kingdon (kingdon@poseidon.cygnus.com)
+
+ * stabs.texinfo (Based Variables): New node.
+
+Thu Sep 16 17:48:55 1993 Jim Kingdon (kingdon@cirdan.cygnus.com)
+
+ * stabs.texinfo (Negative Type Numbers): Re-write discussions of
+ names, sizes, and formats to suggest how not to lose.
+
+Sat Sep 11 09:35:11 1993 Jim Kingdon (kingdon@poseidon.cygnus.com)
+
+ * stabs.texinfo (Methods): Fix typo.
+
+Fri Sep 10 06:34:20 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * gdb.texinfo: Fix a few typos.
+
+Wed Sep 8 09:11:52 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.texinfo: Clarify how well it works with Fortran.
+
+ * stabs.texinfo (Stabs In ELF, Statics, ELF Transformations):
+ More on relocating stabs in ELF files.
+
+Tue Sep 7 13:45:02 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Stabs In ELF): Talk about N_FUN value.
+
+Mon Sep 6 19:23:18 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Local Variable Parameters): Talk about nameless
+ parameters on VAX.
+
+Fri Sep 3 17:06:08 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo: @up/@down -> @raisesections/@lowersections
+
+Fri Sep 3 12:04:15 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo: Make info author notice match the TeX author notice.
+
+Tue Aug 31 13:21:06 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * stabs.texinfo: Initial-caps all words in node names and
+ non-trivial words in section names.
+
+Mon Aug 30 11:13:16 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo: Many minor cleanups.
+
+ * stabs.texinfo: Remove @deffn except from Expanded Reference node.
+
+Sat Aug 28 12:08:09 1993 David J. MacKenzie (djm@edison.eng.umd.edu)
+
+ * stabs.texinfo: Remove full description of big example.
+ It's not really helpful; just use pieces of it where appropriate.
+ Add more Texinfo formatting directives (@samp, etc.).
+ Use @deffn to define stab types.
+ Eliminate some wordiness. Break up some nodes.
+ Add an (alphabetized) index of symbol types.
+ Use consistent capitalization style in node and section names.
+
+Thu Aug 26 06:36:31 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * gdb.texinfo: Change typo "Two two" to "The two".
+
+Sun Aug 22 12:15:18 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (XCOFF-differences): Remove references to
+ non-existent types N_DECL and N_RPSYM.
+
+ * stabs.texinfo (String Field): Say that type attributes bug is
+ fixed in GDB 4.10, since it is.
+
+ * stabs.texinfo: Clean up djm cleanups, and more cleanups of my own.
+
+Sat Aug 21 04:32:28 1993 David MacKenzie (djm@cygnus.com)
+
+ * stabs.texinfo: Formatting cleanups.
+
+Fri Aug 20 20:49:53 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo: When explaining the n_type of a stab, standardize
+ how we do it ('#' as a comment indicator, "36 is N_FUN" as text,
+ no tabs, use @r).
+ (Global Variables): Clean up.
+
+Tue Aug 17 15:57:27 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Stack Variables): Re-write.
+
+Mon Aug 16 21:20:08 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Stabs-in-elf): Talk about getting the start
+ addresses of a source file. Also revise formatting.
+ Change "object module" or "object file" to "source file".
+ Various: Miscellaneous cleanups.
+
+Thu Aug 12 15:11:51 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo: Point to mangling info in gcc's gpcompare.texi.
+
+Tue Aug 10 16:57:49 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * gdbint.texinfo: Removed many nonsensical machine-collected
+ host and target conditionals, described some of the remainder.
+
+Tue Aug 10 13:28:30 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbint.texinfo (Getting Started): Use @itemize, not @table.
+
+ * gdbint.texinfo (Top): Add name to @top line, and re-write the
+ paragraph which follows.
+
+ * gdbint.texinfo (Host): Use @code not @samp for Makefile
+ variables. Looks better and avoids overful hbox.
+
+Fri Jul 30 18:26:21 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Procedures): Improve stuff on nested functions.
+
+Thu Jul 29 15:10:58 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * remote.texi: (MIPS Remote) clearer doc for set/show timeout,
+ retransmit-timeout
+
+Thu Jul 29 13:16:09 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbint.texinfo: Update statement about `some ancient Unix
+ systems, like Ultrix 4.0' to Ultrix 4.2.
+
+Wed Jul 28 15:26:53 1993 Roland H. Pesch (pesch@el_bosque.cygnus.com)
+
+ * h8-cfg.texi, all-cfg.texi: new flag GDBSERVER
+
+ * Makefile.in: depend on remote.texi rather than gdbinv-s.texi
+
+ * remote.texi: (Server) New node on gdbserver. (Remote Serial,
+ ST2000 Remote, MIPS Remote): mention `host:port' syntax for TCP.
+
+ * remote.texi: new name for former gdbinv-s.texi
+
+ * gdb.texinfo: use remote.texi rather than gdbinv-s.texi
+
+Wed Jul 28 08:26:24 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * gdbinv-s.texi: Documented timeout and retransmit-timeout
+ variables for MIPS remote debugging protocol.
+
+Mon Jul 26 13:00:09 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Negative Type Numbers): FORTRAN LOGICAL fix.
+
+Tue Jul 20 16:30:41 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * Makefile.in (refcard.dvi): Use srcdir where necessary.
+
+Mon Jul 19 12:02:50 1993 Roland H. Pesch (pesch@cygnus.com)
+
+ * gdb.texinfo: repair conditional bugs in text markup
+
+Fri Jul 16 18:57:50 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo, all-cfg.texi, h8-cfg.texi: introduce MOD2 switch
+ to select Modula-2 material.
+
+Thu Jul 15 13:15:01 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo: Cleanups regarding statics.
+
+ * gdbinv-s.texi (Bootstrapping): Document exceptionHandler.
+ (Debug Session): Mention exceptionHandler. Add xref to Bootstrapping.
+
+Mon Jul 12 13:37:02 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo: N_MAIN is sometimes used for C.
+
+Fri Jul 9 09:47:02 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdbint.texinfo (Host, Target Conditionals): Remove TM_FILE_OVERRIDE.
+
+Tue Jul 6 12:41:28 1993 John Gilmore (gnu@cygnus.com)
+
+ * gdbint.texinfo (Target Conditionals): Remove NO_TYPEDEFS,
+ removed from the code by Kingdon.
+
+Tue Jul 6 12:24:34 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.texinfo (Break Commands): Remove stuff about flushing terminal
+ input when evaluating breakpoint conditions; the bug has been fixed.
+
+ * gdb.texinfo (Continuing and Stepping): Argument to "continue"
+ sets the ignore count to N-1, not to N.
+
+Thu Jul 1 14:57:42 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * refcard.tex (\hoffset): correct longstanding error to match
+ intended offset; avoids cutting off edge on some printers
+
+Wed Jun 30 18:23:06 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Parameters): Say that order of stabs is significant.
+
+Fri Jun 25 21:34:52 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Common Blocks): Say what Sun FORTRAN does.
+
+Fri Jun 25 16:15:10 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * Makefile.in: (REFEDITS) new var to control whether PS or CM
+ fonts and whether US or A4 paper for GDB refcard; (refcard.dvi)
+ collect sed edits if any, apply to refcard before formatting;
+ (refcard.ps) stop implying PS fonts if PS output requested;
+ (lrefcard.ps) delete extra target for variant PS fonts
+
+ * refcard.tex: parametrize papersize dependent info, collect
+ in easily replaced spot
+
+ * a4rc.sed: new file, edits to refcard for A4 paper
+
+Fri Jun 25 14:21:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Negative Type Numbers): Type -16 is 4 bytes.
+
+Wed Jun 23 15:02:50 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Negative Type Numbers): Minor character cleanups.
+
+Tue Jun 22 16:31:52 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo: Express disapproval of 'D' symbol descriptor
+ politely rather than rudely.
+
+Fri Jun 18 19:42:09 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo: Document common blocks.
+
+Fri Jun 18 12:12:57 1993 Fred Fish (fnf@cygnus.com)
+
+ * stabs.texinfo: Add some basic info about stabs-in-elf.
+
+Fri Jun 18 13:57:09 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Top): Minor cleanup.
+
+Mon Jun 14 16:16:51 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com)
+
+ * Makefile.in (install-info): remove parentdir support
+
+Tue Jun 15 18:11:39 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo (Copying): delete this node and references to it;
+ RMS says this manual need not carry GPL. (passim): Improvements
+ from last round at FSF, largely due to Ian Taylor review, and
+ minor formatting improvements.
+
+ * gdbinv-s.texi (passim): Improvements from last round at FSF,
+ largely due to Ian Taylor review. (Debug Session): minor edits to
+ new text.
+
+Sun Jun 13 12:52:39 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Makefile.in (realclean): Remove info and dvi files too.
+
+Sat Jun 12 16:09:22 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * {all,h8}-config.texi: Rename to *-cfg.texi for 14 char filenames.
+ * Makefile.in: Change accordingly. gdb-config.texi -> gdb-cfg.texi.
+ * gdb.texinfo: Change accordingly.
+
+ * stabs.texinfo: Clean up N_{L,R}BRAC. Discuss what addresses of
+ N_{L,R}BRAC,N_SLINE are relative to.
+
+Fri Jun 11 15:15:55 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Makefile.in (GDBvn.texi): Update atomically.
+
+Wed Jun 9 10:58:16 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * gdbinv-s.texi (Debug Session): Document exceptionHook.
+
+Tue Jun 8 13:42:04 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * gdb.texinfo (Print Settings): Move all stuff relating to symbolic
+ addresses together. Also motivate the set print symbol-filename
+ command and suggest other solutions.
+
+Tue Jun 1 22:46:43 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.texinfo (set print elements): Note that the number of
+ elements is set to unlimited by "set print elements 0".
+
+Mon May 31 08:06:55 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * stabs.texinfo (Builtin Type Descriptors): Try to clarify what
+ NF_LDOUBLE means.
+ (Stab Types): Include Solaris stab types.
+ (Procedures): Document Solaris extensions.
+
+Thu May 27 06:20:42 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.texinfo: Add `set print symbol-filename' doc.
+
+Wed May 26 00:26:42 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Arrays): Talk about type definition vs. type
+ information.
+
+ * stabs.texinfo (Builtin Type Descriptors): Talk about omitting
+ the trailing semicolon.
+
+Tue May 25 14:49:42 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Line Numbers, Source Files): Re-write these two nodes
+ and merge in other parts of the document addressing these subjects.
+ gdbint.texinfo (XCOFF): Remove info which is now in stabs.texinfo.
+
+ * stabs.texinfo (Subranges, Arrays): Try to explain about the semicolon
+ at the end of a range type.
+
+ * stabs.texinfo (Subranges): "A offset" and "T offset" are not
+ AIX extensions.
+
+Mon May 24 09:00:33 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Stabs Format): Misc fixes.
+
+Sat May 22 10:40:56 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Constants): Allow an `e' constant to be non-enum.
+ (Traditional builtin types): Document convex convention for long long.
+ (Negative builtin types): Discuss type names, and misc fixes.
+
+Fri May 21 11:20:31 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Builtin Type Descriptors): Document the floating
+ point types used with @samp{R} type descriptor.
+ (Symbol Descriptors): Describe how to handle conflict between
+ different meanings of @samp{P} symbol descriptor.
+
+Thu May 20 13:35:10 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo: Remove node Quick Reference and put its children
+ directly under the main menu.
+
+ * stabs.texinfo: Many more changes to bring it into line with
+ AIX documentation and reality. I think it now has all the
+ information from the AIX documentation, except that I burned
+ out when I got to variant records (Pascal and Modula-2) and
+ all the COBOL types. Oh well, we can add them later when we're
+ worrying more about those languages.
+
+ * stabs.texinfo (Automatic variables): Talk about what it means
+ to omit the symbol descriptor.
+
+Tue May 18 17:59:18 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stabs.texinfo (Parameters): Add "(sometimes)" when describing
+ gcc2 behavior with promoted args.
+
+Fri May 14 21:35:29 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo: include readline appendices in info version of manual
+
+Fri May 7 11:56:18 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdbinv-s.texi (Remote Serial): describe new ^C behavior in
+ target remote.
+
+ * gdb.texinfo (Machine Code): more index entries for disassemble
+
+Fri May 7 10:12:30 1993 Fred Fish (fnf@cygnus.com)
+
+ * Clarify the intended use of the gdb-testers and gdb-patches
+ mailing lists, and shrink gzip comment.
+
+Thu May 6 16:39:50 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo (Shell Commands): do not mention SHELL env var in
+ DOSHOST configuration of manual.
+
+ * gdb.texinfo (MIPS Stack): new node.
+
+ * all-config.texi (MIPS) new switch.
+
+ * gdbinv-s.texi (Nindy Options) Remove two instances of future
+ tense; (MIPS Remote) new node.
+
+ * gdb.texinfo (passim) rephrases to work around makeinfo @value
+ bug; (Environment) less passive, other small cleanups in text about
+ .cshrc/.bashrc; (Invoking GDB) new MIPS Remote menu entry;
+ (Remote) new MIPS Remote menu entry.
+
+Thu Apr 29 09:36:25 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * stabs.texinfo: Many changes to include information from the
+ AIX documentation.
+
+ * gdb.texinfo (Environment): Mention pitfall with .cshrc.
+
+Tue Apr 27 14:02:57 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * gdbint.texinfo (new node Debugging GDB, elsewhere):
+ Move a bunch of information from ../README.
+ (Getting Started): New node.
+
+Fri Apr 23 17:21:13 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdbinv-s.texi, gdb.texinfo: include Hitachi SH target
+
+ * gdb.texinfo: advance manual revision dates to present
+
+ * gdbinv-s.texi, gdb.texinfo, all-config.texi, h8-config.texi:
+ stop using silly Roman numerals in @set variable names
+
+Fri Apr 23 07:30:01 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * stabs.texinfo (Parameters): Keep trying to get this right.
+
+Wed Apr 21 15:18:47 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * stabs.texinfo (Parameters): More on "local parameters".
+
+Mon Apr 19 08:00:51 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * stabs.texinfo (Parameters): Re-do "local parameters" section.
+
+Sun Apr 18 09:47:45 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * stabs.texinfo (Symbol descriptors): Re-do using @table and @xref.
+ (Parameters): Rewrite.
+ (xcoff-differences, Sun-differences): Minor changes.
+
+Thu Apr 15 02:35:24 1993 John Gilmore (gnu@cacophony.cygnus.com)
+
+ * stabs.texinfo: Minor cleanup.
+
+Wed Apr 14 17:31:00 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * gdbint.texinfo: Minor xcoff stuff.
+
+Wed Apr 7 14:11:07 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdbint.texinfo: Update for new config directory structure.
+ Add info about internal type data structures.
+
+Mon Apr 5 09:06:30 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (SFILES_INCLUDED): gdb-config.texi is no longer in
+ $(srcdir).
+ (gdb-config.texi): Depend on file in $(srcdir).
+
+Fri Apr 2 16:55:13 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * stabs.texinfo: Fixes about N_SO.
+
+Fri Mar 26 18:00:35 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo: include list of nonstandard init file names
+
+ * *-config.texi: new switch GENERIC for text that applies *only*
+ to (usual) multiple-target version of manual
+
+ * gdb.texinfo, gdbinv-s.texi: Update conditional markup to correct
+ h8 config
+
+ * gdb.texinfo: depend on latest fixed makeinfo, use conditionals
+ in menus (rather than conditionally selected multiple alternative
+ menus).
+
+ * Makefile.in: define and use DOC_CONFIG var to select
+ configuration for GDB user manual.
+
+ * gdb-config.texi: delete from repository, generate from Makefile.
+
+ * all-config.texi: normal `generic' configuration file, formerly
+ stored as gdb-config.texi
+
+Wed Mar 24 14:03:19 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com)
+
+ * Makefile.in: add dvi target to build all .dvi files
+
+Tue Mar 23 16:03:24 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo, gdvinv-s.texinfo: formatting improvements.
+
+Fri Mar 19 21:46:50 1993 John Gilmore (gnu@cygnus.com)
+
+ * gdbint.texinfo: Doc NO_MMALLOC and NO_MMALLOC_CHECK as
+ host conditionals.
+ * stabs.texinfo: More array fixes inspired by Jim's.
+
+Fri Mar 19 10:23:34 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * stabs.texinfo: Fixes re arrays and continuations.
+
+ * gdbint.texinfo: Add XCOFF node.
+
+Mon Mar 8 15:52:18 1993 John Gilmore (gnu@cygnus.com)
+
+ * gdb.texinfo: Add `set print max-symbolic-offset' doc.
+
+Sun Feb 21 17:09:38 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * stabs.texinfo: Fix for array types to mention lower bounds.
+
+Thu Feb 18 01:19:49 1993 John Gilmore (gnu@cygnus.com)
+
+ * gdbint.texinfo: Update PTRACE_ARG3_TYPE doc, pull PT_*.
+
+Wed Feb 17 08:15:24 1993 John Gilmore (gnu@cygnus.com)
+
+ * gdbint.texinfo: Remove SET_STACK_LIMIT_HUGE from target defines.
+
+Thu Feb 11 10:38:40 1993 John Gilmore (gnu@cygnus.com)
+
+ * gdbint.texinfo: Fix thinko (NM_FILE => NAT_FILE). Found
+ by Michael Ben-Gershon <mybg@CS.HUJI.AC.IL>.
+
+Wed Feb 10 23:59:19 1993 John Gilmore (gnu@cygnus.com)
+
+ * gdbint.texinfo: Eliminate IBM6000_HOST, document IBM6000_TARGET.
+
+Tue Feb 9 18:26:21 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo, gdbinv-s.texi: misc updates
+
+Sat Feb 6 10:25:47 1993 John Gilmore (gnu@cygnus.com)
+
+ * gdbint.texinfo: Brief documentation for longjmp support,
+ from an email msg by Stu.
+
+Fri Feb 5 14:10:15 1993 John Gilmore (gnu@cygnus.com)
+
+ * stabs.texinfo: Fix description of floating point "range"
+ types (which really define basic types). Reported by Jim Meehan,
+ <meehan@src.dec.com>.
+
+ * gdbint.texinfo: Remove COFF_NO_LONG_FILE_NAMES define, now gone.
+
+Thu Feb 4 13:56:46 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * gdbint.texinfo: Slightly expand section on supporting a new
+ object file format.
+
+Thu Feb 4 01:49:04 1993 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (refcard.ps, lrefcard.ps): Remove psref.tex
+ intermediate file.
+
+Tue Feb 2 12:18:06 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo, gdbinv-s.texi: miscellaneous stylistic cleanups
+
+Mon Feb 1 15:35:47 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdbinv-s.texi: z8000 simulator target name is just "sim"
+
+ * gdbinv-s.texi: Mention that Z8000 simulator can simulate Z8001
+ as well as Z8002.
+
+Sat Nov 28 06:51:35 1992 John Gilmore (gnu@cygnus.com)
+
+ * gdbint.texinfo: Add sections on clean design and on how to send
+ in changes.
+
+Mon Nov 9 23:57:02 1992 John Gilmore (gnu@cygnus.com)
+
+ * gdbint.texinfo: Add how to declare the result of make_cleanup.
+
+Mon Oct 26 11:09:47 1992 John Gilmore (gnu@cygnus.com)
+
+ * gdb.texinfo: Fix typo, reported by Karl Berry.
+
+Fri Oct 23 00:41:21 1992 John Gilmore (gnu@cygnus.com)
+
+ * gdb.texinfo: Add opcodes dir to GDB distribution description.
+
+Sat Oct 10 18:04:58 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * gdbint.texinfo: fixed a stray email address (needs @@),
+ added @table @code to node "Native Conditionals"
+
+Tue Sep 22 00:34:15 1992 John Gilmore (gnu@cygnus.com)
+
+ * gdbint.texinfo: Describe coding style of GDB.
+
+Mon Sep 21 19:32:16 1992 John Gilmore (gnu@cygnus.com)
+
+ * stabs.texinfo: Minor wording changes.
+
+Tue Sep 15 02:57:09 1992 John Gilmore (gnu@cygnus.com)
+
+ * gdbint.texinfo: Improve release doc slightly.
+
+Fri Sep 11 01:34:25 1992 John Gilmore (gnu@sphagnum.cygnus.com)
+
+ * gdbint.texinfo: Improve doc of GDB config macros.
+
+Wed Sep 9 16:52:06 1992 John Gilmore (gnu@cygnus.com)
+
+ * stabs.texinfo: Remove Bothner's changes for C++ nested types.
+ These will be reinserted when examined.
+
+Mon Aug 24 01:17:55 1992 John Gilmore (gnu@cygnus.com)
+
+ * gdbint.texinfo: Make a start at documenting all the #if macros
+ in GDB. At least list them all, and start separating them into
+ host-specific and target-specific.
+
+Tue Aug 18 15:59:13 1992 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdbinv-s.m4.in: refrain from using @cartouche for just a few
+ examples (not consistent w others).
+ gdb.texinfo: issue disclaimer paragraph on cmdline options only
+ for generic vn of doc
+
+Tue Aug 18 14:53:27 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: always create installation directories.
+
+Tue Aug 18 14:11:50 1992 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo: in h8 config, do not describe searching commands.
+
+Mon Aug 17 18:07:59 1992 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo, none.m4, h8.m4, gdbinv-s.m4.in: improve H8/300
+ conditionals; introduce a few generic switches that may be
+ useful for other cross-dev or dos-hosted configs.
+
+ * gdb.texinfo: fix typo in "info reg" description
+
+Sun Aug 16 01:16:18 1992 John Gilmore (gnu@cygnus.com)
+
+ * stabs.texinfo: Minor updates from running TeX over it.
+ * Makefile.in (stabs.dvi, stabs.ps): Add.
+
+Sat Aug 15 20:52:24 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * stabs.texinfo: Stabs documentation, written by Julia Menapace.
+ First pass at converting it to texinfo.
+
+Sat Aug 15 03:14:59 1992 John Gilmore (gnu@cygnus.com)
+
+ * gdb.texinfo, refcard.tex: Document mult args on `info reg'.
+ * Makefile.in (refcard.ps, lrefcard.ps): Add missing $(srdir).
+
+Fri Aug 14 21:08:47 1992 John Gilmore (gnu@cygnus.com)
+
+ * gdbint.texinfo: Add section on partial symbol tables.
+
+Sat Jun 20 16:31:10 1992 John Gilmore (gnu at cygnus.com)
+
+ * gdb.texinfo: document `set remotedebug' and `set
+ rstack_high_address'.
+
+Thu May 14 17:09:48 1992 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * gdb.texinfo: slight expansion of new text on reading info files
+ * gdbinv-s.m4.in: correct and expand info on cross-debugging
+ H8/300 from DOS.
+
+Tue May 12 12:22:47 1992 John Gilmore (gnu at cygnus.com)
+
+ * gdb.texinfo: `info user' => `show user'. Noticed by David Taylor.
+
+Mon May 11 19:06:27 1992 John Gilmore (gnu at cygnus.com)
+
+ * gdb.texinfo: Say how to read the `info' files.
+
+Tue May 5 12:11:38 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: gm4 -> m4.
+
+Fri Apr 10 17:50:43 1992 John Gilmore (gnu at rtl.cygnus.com)
+
+ * gdb.texinfo: Update for GDB-4.5. Move `Formatting
+ Documentation' ahead of `Installing GDB' to match README.
+ Update shared library doc, -readnow and -mapped, and directory
+ structure (add glob and mmalloc). Update configure doc.
+
+Tue Mar 24 23:28:38 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: remove $(srcdir) from gdb.info rule.
+
+Sat Mar 7 18:44:50 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: commented out gdb-all.texinfo rule. This is
+ temporary.
+
+Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in, configure.in: removed traces of namesubdir,
+ -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced
+ copyrights to '92, changed some from Cygnus to FSF.
+
+Fri Dec 13 09:47:31 1991 John Gilmore (gnu at cygnus.com)
+
+ * gdb.texinfo: Improve how we ask for bug reports.
+
+Tue Dec 10 04:07:21 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: infodir belongs in datadir.
+
+Fri Dec 6 23:57:34 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: remove spaces following hyphens, bsd make can't
+ cope. install using INSTALL_DATA. added clean-info. added
+ standards.text support.
+
+Thu Dec 5 22:46:12 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: idestdir and ddestdir go away. Added copyrights
+ and shift gpl to v2. Added ChangeLog if it didn't exist. docdir
+ and mandir now keyed off datadir by default.
+
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/doc/LRS b/gdb/doc/LRS
new file mode 100644
index 00000000000..7e25d432a3e
--- /dev/null
+++ b/gdb/doc/LRS
@@ -0,0 +1,197 @@
+What's LRS?
+===========
+
+LRS, or Live Range Splitting is an optimization technique which allows
+a user variable to reside in different locations during different parts
+of a function.
+
+For example, a variable might reside in the stack for part of a function
+and in a register during a loop and in a different register during
+another loop.
+
+Clearly, if a variable may reside in different locations, then the
+compiler must describe to the debugger where the variable resides for
+any given part of the function.
+
+This document describes the debug format for encoding these extensions
+in stabs.
+
+Since these extensions are gcc specific, these additional symbols and
+stabs can be disabled by the gcc command option -gstabs.
+
+
+GNU extensions for LRS under stabs:
+===================================
+
+
+range symbols:
+-------------
+
+ A range symbol will be used to mark the beginning or end of a
+ live range (the range which describes where a symbol is active,
+ or live). These symbols will later be referenced in the stabs for
+ debug purposes. For simplicity, we'll use the terms "range_start"
+ and "range_end" to identify the range symbols which mark the beginning
+ and end of a live range respectively.
+
+ Any text symbol which would normally appear in the symbol table
+ (eg. a function name) can be used as range symbol. If an address
+ is needed to delimit a live range and does not match any of the
+ values of symbols which would normally appear in the symbol table,
+ a new symbol will be added to the table whose value is that address.
+
+ The three new symbol types described below have been added for this
+ purpose.
+
+ For efficiency, the compiler should use existing symbols as range
+ symbols whenever possible; this reduces the number of additional
+ symbols which need to be added to the symbol table.
+
+
+New debug symbol type for defining ranges:
+------------------------------------------
+
+ range_off - contains PC function offset for start/end of a live range.
+ Its location is relative to the function start and therefore
+ eliminates the need for additional relocation.
+
+ This symbol has a values in the text section, and does not have a name.
+
+ NOTE: the following may not be needed but are included here just
+ in case.
+ range - contains PC value of beginning or end of a live range
+ (relocs required).
+
+ NOTE: the following will be required if we desire LRS debugging
+ to work with old style a.out stabs.
+ range_abs - contains absolute PC value of start/end of a live
+ range. The range_abs debug symbol is provided for
+ completeness, in case there is a need to describe addresses
+ in ROM, etc.
+
+
+Live range:
+-----------
+
+ The compiler and debugger view a variable with multiple homes as
+ a primary symbol and aliases for that symbol. The primary symbol
+ describes the default home of the variable while aliases describe
+ alternate homes for the variable.
+
+ A live range defines the interval of instructions beginning with
+ range_start and ending at range_end-1, and is used to specify a
+ range of instructions where an alias is active or "live". So,
+ the actual end of the range will be one less than the value of the
+ range_end symbol.
+
+ Ranges do not have to be nested. Eg. Two ranges may intersect while
+ each range contains subranges which are not in the other range.
+
+ There does not have to be a 1-1 mapping from range_start to
+ range_end symbols. Eg. Two range_starts can share the same
+ range_end, while one symbol's range_start can be another symbol's
+ range_end.
+
+ When a variable's storage class changes (eg. from stack to register,
+ or from one register to another), a new symbol entry will be
+ added to the symbol table with stabs describing the new type,
+ and appropriate live ranges refering to the variable's initial
+ symbol index.
+
+ For variables which are defined in the source but optimized away,
+ a symbol should be emitted with the live range l(0,0).
+
+ Live ranges for aliases of a particular variable should always
+ be disjoint. Overlapping ranges for aliases of the same variable
+ will be treated as an error by the debugger, and the overlapping
+ range will be ignored.
+
+ If no live range information is given, the live range will be assumed to
+ span the symbol's entire lexical scope.
+
+
+New stabs string identifiers:
+-----------------------------
+
+ "id" in "#id" in the following section refers to a numeric value.
+
+ New stab syntax for live range: l(<ref_from>,<ref_to>)
+
+ <ref_from> - "#id" where #id identifies the text symbol (range symbol) to
+ use as the start of live range (range_start). The value for
+ the referenced text symbol is the starting address of the
+ live range.
+
+ <ref_to> - "#id" where #id identifies the text symbol (range symbol) to
+ use as the end of live range (range_end). The value for
+ the referenced text symbol is ONE BYTE PAST the ending
+ address of the live range.
+
+
+ New stab syntax for identifying symbols.
+
+ <def> - "#id="
+
+ Uses:
+ <def><name>:<typedef1>...
+ When used in front of a symbol name, "#id=" defines a
+ unique reference number for this symbol. The reference
+ number can be used later when defining aliases for this
+ symbol.
+ <def>
+ When used as the entire stab string, "#id=" identifies this
+ nameless symbol as being the symbol for which "#id" refers to.
+
+
+ <ref> - "#id" where "#id" refers to the symbol for which the string
+ "#id=" identifies.
+ Uses:
+ <ref>:<typedef2>;<liverange>;<liverange>...
+ Defines an alias for the symbol identified by the reference
+ number ID.
+ l(<ref1>,<ref2>)
+ When used within a live range, "#id" refers to the text
+ symbol identified by "#id=" to use as the range symbol.
+
+ <liverange> - "l(<ref_from>,<ref_to>)" - specifies a live range for a
+ symbol. Multiple "l" specifiers can be combined to represent
+ mutiple live ranges, separated by semicolons.
+
+
+
+
+Example:
+========
+
+Consider a program of the form:
+
+ void foo(){
+ int a = ...;
+ ...
+ while (b--)
+ c += a;
+ ..
+ d = a;
+ ..
+ }
+
+Assume that "a" lives in the stack at offset -8, except for inside the
+loop where "a" resides in register "r5".
+
+The way to describe this is to create a stab for the variable "a" which
+describes "a" as living in the stack and an alias for the variable "a"
+which describes it as living in register "r5" in the loop.
+
+Let's assume that "#1" and "#2" are symbols which bound the area where
+"a" lives in a register.
+
+The stabs to describe "a" and its alias would look like this:
+
+ .stabs "#3=a:1",128,0,8,-8
+ .stabs "#3:r1;l(#1,#2)",64,0,0,5
+
+
+This design implies that the debugger will keep a chain of aliases for
+any given variable with aliases and that chain will be searched first
+to find out if an alias is active. If no alias is active, then the
+debugger will assume that the main variable is active.
diff --git a/gdb/doc/Makefile.in b/gdb/doc/Makefile.in
new file mode 100644
index 00000000000..3b549b84763
--- /dev/null
+++ b/gdb/doc/Makefile.in
@@ -0,0 +1,415 @@
+##Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2002
+##Free Software Foundation, Inc.
+
+# Makefile for GDB documentation.
+# 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.
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+
+infodir = @infodir@
+htmldir = $(prefix)/html
+
+SHELL = @SHELL@
+
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+# main GDB source directory
+gdbdir = $(srcdir)/..
+
+# where to find texinfo; GDB dist should include a recent one
+TEXIDIR=${gdbdir}/../texinfo
+
+# where to find makeinfo, preferably one designed for texinfo-2
+MAKEINFO=makeinfo
+
+# Note that texinfo 4.0's makeinfo --html can only generate a
+# single file, which would be too large, so continue to use
+# texi2html. -sts 2000-03-28
+
+MAKEHTML = texi2html
+MAKEHTMLFLAGS = -menu -split_chapter
+
+# where to find texi2roff, ditto
+TEXI2ROFF=texi2roff
+
+# where to find texi2dvi, ditto
+TEXI2DVI=texi2dvi
+
+# Where is the source dir for the READLINE library doc?
+# Traditionally readline is in .. or .
+READLINE_DIR = ${gdbdir}/../readline/doc
+
+# The GDB/MI docs come from a sibling directory ../mi
+GDBMI_DIR = ${gdbdir}/mi
+
+SET_TEXINPUTS = \
+ TEXINPUTS=${TEXIDIR}:.:$(srcdir):$(READLINE_DIR):$(GDBMI_DIR):$$TEXINPUTS
+
+# Files which should be generated via 'info' and installed by 'install-info'
+INFO_DEPS = gdb.info gdbint.info stabs.info
+
+# There may be alternate predefined collections of switches to configure
+# the GDB manual. Normally this is not done in synch with the software
+# config system, since this choice tends to be independent; most people
+# want a doc config of `all' for a generic manual, regardless of sw config.
+DOC_CONFIG = all
+
+# This list of sed edits will edit the GDB reference card
+# for what fonts and what papersize to use.
+# By default (NO edits applied), the refcard uses:
+# - Computer Modern (CM) fonts
+# - US letter paper (8.5x11in)
+# List some of the following files for alternative fonts and paper:
+# a4rc.sed use A4 paper (297 x 210 mm)
+# psrc.sed use PostScript fonts (Karl Berry short TeX names)
+# lpsrc.sed use PostScript fonts (full PostScript names in TeX)
+# e.g. for A4, Postscript: REFEDITS = a4rc.sed psrc.sed
+# for A4, CM fonts: REFEDITS = a4rc.sed
+# for US, PS fonts: REFEDITS = psrc.sed
+# for default:
+REFEDITS =
+
+# Don Knuth's TeX formatter
+TEX = tex
+
+# Program to generate Postscript files from DVI files.
+DVIPS = dvips
+
+# Main GDB manual's source files
+SFILES_INCLUDED = gdb-cfg.texi \
+ $(srcdir)/annotate.texi \
+ $(srcdir)/fdl.texi \
+ $(srcdir)/gpl.texi
+
+SFILES_LOCAL = $(srcdir)/gdb.texinfo GDBvn.texi $(SFILES_INCLUDED)
+
+SFILES_DOC = $(SFILES_LOCAL) $(GDBMI_DIR)/gdbmi.texinfo \
+ $(READLINE_DIR)/rluser.texinfo $(READLINE_DIR)/inc-hist.texinfo
+
+#### Host, target, and site specific Makefile fragments come in here.
+###
+
+all install:
+
+info: $(INFO_DEPS)
+dvi: gdb.dvi gdbint.dvi stabs.dvi refcard.dvi
+ps: gdb.ps gdbint.ps stabs.ps refcard.ps
+html: gdb_toc.html gdbint_toc.html stabs_toc.html
+pdf: gdb.pdf gdbint.pdf stabs.pdf
+all-doc: info dvi ps # pdf
+diststuff: info
+
+install-info: $(INFO_DEPS)
+ $(SHELL) $(srcdir)/../../mkinstalldirs $(infodir)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \
+ if test -f $$d/$$ifile; then \
+ echo " $(INSTALL_DATA) $$d/$$ifile $(infodir)/$$ifile"; \
+ $(INSTALL_DATA) $$d/$$ifile $(infodir)/$$ifile; \
+ else : ; fi; \
+ done; \
+ done
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ echo " install-info --info-dir=$(infodir) $(infodir)/$$file";\
+ install-info --info-dir=$(infodir) $(infodir)/$$file || :;\
+ done; \
+ else : ; fi
+
+install-html: html
+ for i in *.html ; do \
+ $(INSTALL_DATA) $$i $(htmldir)/$$i ; \
+ done
+
+STAGESTUFF = *.info* gdb-all.texi GDBvn.texi *.ps *.dvi *.pdf
+
+# Copy the object files from a particular stage into a subdirectory.
+stage1: force
+ -mkdir stage1
+ -mv $(STAGESTUFF) stage1
+
+stage2: force
+ -mkdir stage2
+ -mv $(STAGESTUFF) stage2
+
+stage3: force
+ -mkdir stage3
+ -mv $(STAGESTUFF) stage3
+
+against=stage2
+
+comparison: force
+ for i in $(STAGESTUFF) ; do cmp $$i $(against)/$$i ; done
+
+de-stage1: force
+ -(cd stage1 ; mv -f * ..)
+ -rmdir stage1
+
+de-stage2: force
+ -(cd stage2 ; mv -f * ..)
+ -rmdir stage2
+
+de-stage3: force
+ -(cd stage3 ; mv -f * ..)
+ -rmdir stage3
+
+# The "least clean" level of cleaning. Get rid of files which are
+# automatically generated files that are just intermediate files,
+#
+mostlyclean:
+ rm -f gdb.mm gdb.ms gdb.me links2roff
+ rm -f *.aux *.cp* *.fn* *.ky* *.log *.pg* *.toc *.tp* *.vr*
+ rm -f sedref.dvi sedref.tex tmp.sed
+
+clean: mostlyclean
+ rm -f rluser.texinfo inc-hist.texinfo gdb-cfg.texi
+
+distclean: clean
+ rm -f Makefile config.status
+
+# GDBvn.texi, the dvi files, the info files, and the postscript files,
+# are all part of the distribution, so it should not be removed by
+# "clean" or "distclean". Use maintainer-clean to remove them.
+
+maintainer-clean realclean: distclean
+ rm -f GDBvn.texi *.info* *.dvi *.ps *.html *.pdf
+
+# GDB QUICK REFERENCE (dvi output)
+refcard.dvi : refcard.tex $(REFEDITS)
+ echo > tmp.sed
+ for f in x $(REFEDITS) ; do \
+ test x$$f = xx && continue ; \
+ cat $(srcdir)/$$f >>tmp.sed ; \
+ done
+ sed -f tmp.sed $(srcdir)/refcard.tex >sedref.tex
+ $(SET_TEXINPUTS) $(TEX) sedref.tex
+ mv sedref.dvi refcard.dvi
+ rm -f sedref.log sedref.tex tmp.sed
+
+refcard.ps : refcard.dvi
+ $(DVIPS) -t landscape -o $@ $?
+
+# File to record current GDB version number (copied from main dir version.in)
+GDBvn.texi : ${gdbdir}/version.in
+ echo "@set GDBVN `head -1 $(srcdir)/../version.in`" > ./GDBvn.new
+ mv GDBvn.new GDBvn.texi
+
+# Updated atomically
+.PRECIOUS: GDBvn.texi
+
+# Choose configuration for GDB manual (normally `all'; normally not tied into
+# `configure' script because most users prefer generic version of manual,
+# not one for their binary config---which may not be specifically
+# defined anyways).
+gdb-cfg.texi: ${srcdir}/${DOC_CONFIG}-cfg.texi
+ (test "$$LN_S" = "ln -s" && \
+ ln -s ${srcdir}/${DOC_CONFIG}-cfg.texi gdb-cfg.texi) || \
+ ln ${srcdir}/${DOC_CONFIG}-cfg.texi gdb-cfg.texi || \
+ cp ${srcdir}/${DOC_CONFIG}-cfg.texi gdb-cfg.texi
+
+# GDB MANUAL: texinfo source, using @set/@clear/@value/@ifset/@ifclear
+# If your texinfo or makeinfo don't support these, get a new texinfo release
+#
+# The nonsense with GDBvn.texi gets this to run with both Sun and GNU make.
+# Note that we can *generate* GDBvn.texi, but since we distribute one in the
+# source directory for the benefit of people who *don't* use this makefile,
+# VPATH will often tell make not to bother building it, because the one
+# in the srcdir is up to date. (if not, then make should build one here).
+
+# GDB MANUAL: TeX dvi file
+gdb.dvi: ${SFILES_DOC}
+ if [ ! -f ./GDBvn.texi ]; then \
+ (test "$$LN_S" = "ln -s" && ln -s $(srcdir)/GDBvn.texi .) || \
+ ln $(srcdir)/GDBvn.texi . || \
+ cp $(srcdir)/GDBvn.texi . ; else true; fi
+ $(SET_TEXINPUTS) $(TEXI2DVI) $(srcdir)/gdb.texinfo
+ rm -f gdb.aux gdb.cp* gdb.fn* gdb.ky* gdb.log gdb.pg* gdb.toc \
+ gdb.tp* gdb.vr*
+
+gdb.ps: gdb.dvi
+ $(DVIPS) -o $@ $?
+
+gdb.pdf: ${SFILES_DOC}
+ if [ ! -f ./GDBvn.texi ]; then \
+ (test "$$LN_S" = "ln -s" && ln -s $(srcdir)/GDBvn.texi .) || \
+ ln $(srcdir)/GDBvn.texi . || \
+ cp $(srcdir)/GDBvn.texi . ; else true; fi
+ $(SET_TEXINPUTS) $(TEXI2DVI) --pdf $(srcdir)/gdb.texinfo
+ rm -f gdb.aux gdb.cp* gdb.fn* gdb.ky* gdb.log gdb.pg* gdb.toc \
+ gdb.tp* gdb.vr*
+
+# GDB MANUAL: info file
+gdb.info: ${SFILES_DOC}
+ $(MAKEINFO) -I ${READLINE_DIR} -I ${GDBMI_DIR} -I $(srcdir) \
+ -o gdb.info $(srcdir)/gdb.texinfo
+
+# GDB MANUAL: roff translations
+# Try to use a recent texi2roff. v2 was put on prep in jan91.
+# If you want an index, see texi2roff doc for postprocessing
+# and add -i to texi2roff invocations below.
+# Workarounds for texi2roff-2 (probably fixed in later texi2roff's, delete
+# corresponding -e lines when later texi2roff's are current)
+# + @ifinfo's deleted explicitly due to texi2roff-2 bug w nested constructs.
+# + @c's deleted explicitly because texi2roff sees texinfo commands in them
+# + @ (that's at-BLANK) not recognized by texi2roff, turned into blank
+# + @alphaenumerate is ridiculously new, turned into @enumerate
+
+# texi2roff doesn't have a notion of include dirs, so we have to fake
+# it out for gdb manual's include files---but only if not configured
+# in main sourcedir.
+links2roff: $(SFILES_INCLUDED)
+ if [ ! -f gdb.texinfo ]; then \
+ (test "$$LN_S" = "ln -s" && ln -s $(SFILES_INCLUDED) .) || \
+ ln $(SFILES_INCLUDED) . || \
+ cp $(SFILES_INCLUDED) . ; \
+ fi
+ touch links2roff
+
+# "Readline" appendices. Get them also due to lack of includes,
+# regardless of whether or not configuring in main sourcedir.
+# @ftable removed due to bug in texi2roff-2; if your texi2roff
+# is newer, try just ln or cp
+rluser.texinfo: ${READLINE_DIR}/rluser.texinfo
+ sed -e 's/^@ftable/@table/g' \
+ -e 's/^@end ftable/@end table/g' \
+ ${READLINE_DIR}/rluser.texinfo > ./rluser.texinfo
+
+inc-hist.texinfo: ${READLINE_DIR}/inc-hist.texinfo
+ (test "$$LN_S" = "ln -s" && \
+ ln -s ${READLINE_DIR}/inc-hist.texinfo .) || \
+ ln ${READLINE_DIR}/inc-hist.texinfo . || \
+ cp ${READLINE_DIR}/inc-hist.texinfo .
+
+gdbmi.texinfo: ${GDBMI_DIR}/gdbmi.texinfo
+ (test "$$LN_S" = "ln -s" && \
+ ln -s ${GDBMI_DIR}/gdbmi.texinfo .) || \
+ ln ${GDBMI_DIR}/gdbmi.texinfo . || \
+ cp ${GDBMI_DIR}/gdbmi.texinfo .
+
+# gdb manual suitable for [gtn]roff -me
+gdb.me: $(SFILES_LOCAL) links2roff rluser.texinfo inc-hist.texinfo gdbmi.texinfo
+ sed -e '/\\input texinfo/d' \
+ -e '/@c TEXI2ROFF-KILL/,/@c END TEXI2ROFF-KILL/d' \
+ -e '/^@ifinfo/,/^@end ifinfo/d' \
+ -e '/^@c /d' \
+ -e 's/{.*,,/{/' \
+ -e 's/@ / /g' \
+ -e 's/^@alphaenumerate/@enumerate/g' \
+ -e 's/^@end alphaenumerate/@end enumerate/g' \
+ $(srcdir)/gdb.texinfo | \
+ $(TEXI2ROFF) -me | \
+ sed -e 's/---/\\(em/g' \
+ >gdb.me
+
+# gdb manual suitable for [gtn]roff -ms
+gdb.ms: $(SFILES_LOCAL) links2roff rluser.texinfo inc-hist.texinfo gdbmi.texinfo
+ sed -e '/\\input texinfo/d' \
+ -e '/@c TEXI2ROFF-KILL/,/@c END TEXI2ROFF-KILL/d' \
+ -e '/^@ifinfo/,/^@end ifinfo/d' \
+ -e '/^@c /d' \
+ -e 's/{.*,,/{/' \
+ -e 's/@ / /g' \
+ -e 's/^@alphaenumerate/@enumerate/g' \
+ -e 's/^@end alphaenumerate/@end enumerate/g' \
+ $(srcdir)/gdb.texinfo | \
+ $(TEXI2ROFF) -ms | \
+ sed -e 's/---/\\(em/g' \
+ >gdb.ms
+
+# gdb manual suitable for [tn]roff -mm
+# '@noindent's removed due to texi2roff-2 mm bug; if yours is newer,
+# try leaving them in
+gdb.mm: $(SFILES_LOCAL) links2roff rluser.texinfo inc-hist.texinfo gdbmi.texinfo
+ sed -e '/\\input texinfo/d' \
+ -e '/@c TEXI2ROFF-KILL/,/@c END TEXI2ROFF-KILL/d' \
+ -e '/^@ifinfo/,/^@end ifinfo/d' \
+ -e '/^@c /d' \
+ -e 's/{.*,,/{/' \
+ -e '/@noindent/d' \
+ -e 's/@ / /g' \
+ -e 's/^@alphaenumerate/@enumerate/g' \
+ -e 's/^@end alphaenumerate/@end enumerate/g' \
+ $(srcdir)/gdb.texinfo | \
+ $(TEXI2ROFF) -mm | \
+ sed -e 's/---/\\(em/g' \
+ >gdb.mm
+
+# GDB MANUAL: HTML file
+
+gdb_toc.html: ${SFILES_DOC}
+ $(MAKEHTML) $(MAKEHTMLFLAGS) -I ${READLINE_DIR} -I ${GDBMI_DIR} -I $(srcdir) $(srcdir)/gdb.texinfo
+
+# GDB INTERNALS MANUAL: TeX dvi file
+gdbint.dvi: gdbint.texinfo gdb-cfg.texi fdl.texi
+ $(SET_TEXINPUTS) $(TEXI2DVI) $(srcdir)/gdbint.texinfo
+ rm -f gdbint.aux gdbint.cp* gdbint.fn* gdbint.ky* \
+ gdbint.log gdbint.pg* gdbint.toc gdbint.tp* gdbint.vr*
+
+gdbint.ps : gdbint.dvi
+ $(DVIPS) -o $@ $?
+
+gdbint.pdf: gdbint.texinfo gdb-cfg.texi fdl.texi
+ $(SET_TEXINPUTS) $(TEXI2DVI) --pdf $(srcdir)/gdbint.texinfo
+ rm -f gdbint.aux gdbint.cp* gdbint.fn* gdbint.ky* \
+ gdbint.log gdbint.pg* gdbint.toc gdbint.tp* gdbint.vr*
+
+# GDB INTERNALS MANUAL: info file
+
+gdbint.info: gdbint.texinfo fdl.texi
+ $(MAKEINFO) -I $(srcdir) -o gdbint.info $(srcdir)/gdbint.texinfo
+
+# GDB INTERNALS MANUAL: HTML file
+
+gdbint_toc.html: gdbint.texinfo gdb-cfg.texi fdl.texi
+ $(MAKEHTML) $(MAKEHTMLFLAGS) $(srcdir)/gdbint.texinfo
+
+stabs.info: stabs.texinfo
+ $(MAKEINFO) -o stabs.info $(srcdir)/stabs.texinfo
+
+# STABS DOCUMENTATION: HTML file
+
+stabs_toc.html: stabs.texinfo
+ $(MAKEHTML) $(MAKEHTMLFLAGS) $(srcdir)/stabs.texinfo
+
+# STABS DOCUMENTATION: TeX dvi file
+stabs.dvi : stabs.texinfo
+ $(SET_TEXINPUTS) $(TEXI2DVI) $(srcdir)/stabs.texinfo
+ rm -f stabs.aux stabs.cp* stabs.fn* stabs.ky* \
+ stabs.log stabs.pg* stabs.toc stabs.tp* stabs.vr*
+
+stabs.ps: stabs.dvi
+ $(DVIPS) -o $@ $?
+
+stabs.pdf: stabs.dvi
+ $(SET_TEXINPUTS) $(TEXI2DVI) --pdf $(srcdir)/stabs.texinfo
+ rm -f stabs.aux stabs.cp* stabs.fn* stabs.ky* \
+ stabs.log stabs.pg* stabs.toc stabs.tp* stabs.vr*
+
+force:
+
+Makefile: Makefile.in $(host_makefile_frag) $(target_makefile_frag) config.status
+ $(SHELL) ./config.status
diff --git a/gdb/doc/a4rc.sed b/gdb/doc/a4rc.sed
new file mode 100644
index 00000000000..22922904efc
--- /dev/null
+++ b/gdb/doc/a4rc.sed
@@ -0,0 +1,11 @@
+/--- Papersize params:/,/--- end papersize params/c\
+%------- Papersize params:\
+%% A4 paper (297x210mm)\
+%%\
+\\totalwidth=297mm % total width of paper\
+\\totalheight=210mm % total height of paper\
+\\hmargin=5mm % horizontal margin width\
+\\vmargin=10mm % vertical margin width\
+\\secskip=.6pc % space between refcard secs\
+\\lskip=1pt % extra skip between \\sec entries\
+%------- end papersize params
diff --git a/gdb/doc/agentexpr.texi b/gdb/doc/agentexpr.texi
new file mode 100644
index 00000000000..54186675e28
--- /dev/null
+++ b/gdb/doc/agentexpr.texi
@@ -0,0 +1,839 @@
+\input texinfo
+@c %**start of header
+@setfilename agentexpr.info
+@settitle GDB Agent Expressions
+@setchapternewpage off
+@c %**end of header
+
+Revision: $Id$
+
+@node The GDB Agent Expression Mechanism
+@chapter The GDB Agent Expression Mechanism
+
+In some applications, it is not feasable for the debugger to interrupt
+the program's execution long enough for the developer to learn anything
+helpful about its behavior. If the program's correctness depends on its
+real-time behavior, delays introduced by a debugger might cause the
+program to fail, even when the code itself is correct. It is useful to
+be able to observe the program's behavior without interrupting it.
+
+Using GDB's @code{trace} and @code{collect} commands, the user can
+specify locations in the program, and arbitrary expressions to evaluate
+when those locations are reached. Later, using the @code{tfind}
+command, she can examine the values those expressions had when the
+program hit the trace points. The expressions may also denote objects
+in memory --- structures or arrays, for example --- whose values GDB
+should record; while visiting a particular tracepoint, the user may
+inspect those objects as if they were in memory at that moment.
+However, because GDB records these values without interacting with the
+user, it can do so quickly and unobtrusively, hopefully not disturbing
+the program's behavior.
+
+When GDB is debugging a remote target, the GDB @dfn{agent} code running
+on the target computes the values of the expressions itself. To avoid
+having a full symbolic expression evaluator on the agent, GDB translates
+expressions in the source language into a simpler bytecode language, and
+then sends the bytecode to the agent; the agent then executes the
+bytecode, and records the values for GDB to retrieve later.
+
+The bytecode language is simple; there are forty-odd opcodes, the bulk
+of which are the usual vocabulary of C operands (addition, subtraction,
+shifts, and so on) and various sizes of literals and memory reference
+operations. The bytecode interpreter operates strictly on machine-level
+values --- various sizes of integers and floating point numbers --- and
+requires no information about types or symbols; thus, the interpreter's
+internal data structures are simple, and each bytecode requires only a
+few native machine instructions to implement it. The interpreter is
+small, and strict limits on the memory and time required to evaluate an
+expression are easy to determine, making it suitable for use by the
+debugging agent in real-time applications.
+
+@menu
+* General Bytecode Design:: Overview of the interpreter.
+* Bytecode Descriptions:: What each one does.
+* Using Agent Expressions:: How agent expressions fit into the big picture.
+* Varying Target Capabilities:: How to discover what the target can do.
+* Tracing on Symmetrix:: Special info for implementation on EMC's
+ boxes.
+* Rationale:: Why we did it this way.
+@end menu
+
+
+@c @node Rationale
+@c @section Rationale
+
+
+@node General Bytecode Design
+@section General Bytecode Design
+
+The agent represents bytecode expressions as an array of bytes. Each
+instruction is one byte long (thus the term @dfn{bytecode}). Some
+instructions are followed by operand bytes; for example, the @code{goto}
+instruction is followed by a destination for the jump.
+
+The bytecode interpreter is a stack-based machine; most instructions pop
+their operands off the stack, perform some operation, and push the
+result back on the stack for the next instruction to consume. Each
+element of the stack may contain either a integer or a floating point
+value; these values are as many bits wide as the largest integer that
+can be directly manipulated in the source language. Stack elements
+carry no record of their type; bytecode could push a value as an
+integer, then pop it as a floating point value. However, GDB will not
+generate code which does this. In C, one might define the type of a
+stack element as follows:
+@example
+union agent_val @{
+ LONGEST l;
+ DOUBLEST d;
+@};
+@end example
+@noindent
+where @code{LONGEST} and @code{DOUBLEST} are @code{typedef} names for
+the largest integer and floating point types on the machine.
+
+By the time the bytecode interpreter reaches the end of the expression,
+the value of the expression should be the only value left on the stack.
+For tracing applications, @code{trace} bytecodes in the expression will
+have recorded the necessary data, and the value on the stack may be
+discarded. For other applications, like conditional breakpoints, the
+value may be useful.
+
+Separate from the stack, the interpreter has two registers:
+@table @code
+@item pc
+The address of the next bytecode to execute.
+
+@item start
+The address of the start of the bytecode expression, necessary for
+interpreting the @code{goto} and @code{if_goto} instructions.
+
+@end table
+@noindent
+Neither of these registers is directly visible to the bytecode language
+itself, but they are useful for defining the meanings of the bytecode
+operations.
+
+There are no instructions to perform side effects on the running
+program, or call the program's functions; we assume that these
+expressions are only used for unobtrusive debugging, not for patching
+the running code.
+
+Most bytecode instructions do not distinguish between the various sizes
+of values, and operate on full-width values; the upper bits of the
+values are simply ignored, since they do not usually make a difference
+to the value computed. The exceptions to this rule are:
+@table @asis
+
+@item memory reference instructions (@code{ref}@var{n})
+There are distinct instructions to fetch different word sizes from
+memory. Once on the stack, however, the values are treated as full-size
+integers. They may need to be sign-extended; the @code{ext} instruction
+exists for this purpose.
+
+@item the sign-extension instruction (@code{ext} @var{n})
+These clearly need to know which portion of their operand is to be
+extended to occupy the full length of the word.
+
+@end table
+
+If the interpreter is unable to evaluate an expression completely for
+some reason (a memory location is inaccessible, or a divisor is zero,
+for example), we say that interpretation ``terminates with an error''.
+This means that the problem is reported back to the interpreter's caller
+in some helpful way. In general, code using agent expressions should
+assume that they may attempt to divide by zero, fetch arbitrary memory
+locations, and misbehave in other ways.
+
+Even complicated C expressions compile to a few bytecode instructions;
+for example, the expression @code{x + y * z} would typically produce
+code like the following, assuming that @code{x} and @code{y} live in
+registers, and @code{z} is a global variable holding a 32-bit
+@code{int}:
+@example
+reg 1
+reg 2
+const32 @i{address of z}
+ref32
+ext 32
+mul
+add
+end
+@end example
+
+In detail, these mean:
+@table @code
+
+@item reg 1
+Push the value of register 1 (presumably holding @code{x}) onto the
+stack.
+
+@item reg 2
+Push the value of register 2 (holding @code{y}).
+
+@item const32 @i{address of z}
+Push the address of @code{z} onto the stack.
+
+@item ref32
+Fetch a 32-bit word from the address at the top of the stack; replace
+the address on the stack with the value. Thus, we replace the address
+of @code{z} with @code{z}'s value.
+
+@item ext 32
+Sign-extend the value on the top of the stack from 32 bits to full
+length. This is necessary because @code{z} is a signed integer.
+
+@item mul
+Pop the top two numbers on the stack, multiply them, and push their
+product. Now the top of the stack contains the value of the expression
+@code{y * z}.
+
+@item add
+Pop the top two numbers, add them, and push the sum. Now the top of the
+stack contains the value of @code{x + y * z}.
+
+@item end
+Stop executing; the value left on the stack top is the value to be
+recorded.
+
+@end table
+
+
+@node Bytecode Descriptions
+@section Bytecode Descriptions
+
+Each bytecode description has the following form:
+
+@table @asis
+
+@item @code{add} (0x02): @var{a} @var{b} @result{} @var{a+b}
+
+Pop the top two stack items, @var{a} and @var{b}, as integers; push
+their sum, as an integer.
+
+@end table
+
+In this example, @code{add} is the name of the bytecode, and
+@code{(0x02)} is the one-byte value used to encode the bytecode, in
+hexidecimal. The phrase ``@var{a} @var{b} @result{} @var{a+b}'' shows
+the stack before and after the bytecode executes. Beforehand, the stack
+must contain at least two values, @var{a} and @var{b}; since the top of
+the stack is to the right, @var{b} is on the top of the stack, and
+@var{a} is underneath it. After execution, the bytecode will have
+popped @var{a} and @var{b} from the stack, and replaced them with a
+single value, @var{a+b}. There may be other values on the stack below
+those shown, but the bytecode affects only those shown.
+
+Here is another example:
+
+@table @asis
+
+@item @code{const8} (0x22) @var{n}: @result{} @var{n}
+Push the 8-bit integer constant @var{n} on the stack, without sign
+extension.
+
+@end table
+
+In this example, the bytecode @code{const8} takes an operand @var{n}
+directly from the bytecode stream; the operand follows the @code{const8}
+bytecode itself. We write any such operands immediately after the name
+of the bytecode, before the colon, and describe the exact encoding of
+the operand in the bytecode stream in the body of the bytecode
+description.
+
+For the @code{const8} bytecode, there are no stack items given before
+the @result{}; this simply means that the bytecode consumes no values
+from the stack. If a bytecode consumes no values, or produces no
+values, the list on either side of the @result{} may be empty.
+
+If a value is written as @var{a}, @var{b}, or @var{n}, then the bytecode
+treats it as an integer. If a value is written is @var{addr}, then the
+bytecode treats it as an address.
+
+We do not fully describe the floating point operations here; although
+this design can be extended in a clean way to handle floating point
+values, they are not of immediate interest to the customer, so we avoid
+describing them, to save time.
+
+
+@table @asis
+
+@item @code{float} (0x01): @result{}
+
+Prefix for floating-point bytecodes. Not implemented yet.
+
+@item @code{add} (0x02): @var{a} @var{b} @result{} @var{a+b}
+Pop two integers from the stack, and push their sum, as an integer.
+
+@item @code{sub} (0x03): @var{a} @var{b} @result{} @var{a-b}
+Pop two integers from the stack, subtract the top value from the
+next-to-top value, and push the difference.
+
+@item @code{mul} (0x04): @var{a} @var{b} @result{} @var{a*b}
+Pop two integers from the stack, multiply them, and push the product on
+the stack. Note that, when one multiplies two @var{n}-bit numbers
+yielding another @var{n}-bit number, it is irrelevant whether the
+numbers are signed or not; the results are the same.
+
+@item @code{div_signed} (0x05): @var{a} @var{b} @result{} @var{a/b}
+Pop two signed integers from the stack; divide the next-to-top value by
+the top value, and push the quotient. If the divisor is zero, terminate
+with an error.
+
+@item @code{div_unsigned} (0x06): @var{a} @var{b} @result{} @var{a/b}
+Pop two unsigned integers from the stack; divide the next-to-top value
+by the top value, and push the quotient. If the divisor is zero,
+terminate with an error.
+
+@item @code{rem_signed} (0x07): @var{a} @var{b} @result{} @var{a modulo b}
+Pop two signed integers from the stack; divide the next-to-top value by
+the top value, and push the remainder. If the divisor is zero,
+terminate with an error.
+
+@item @code{rem_unsigned} (0x08): @var{a} @var{b} @result{} @var{a modulo b}
+Pop two unsigned integers from the stack; divide the next-to-top value
+by the top value, and push the remainder. If the divisor is zero,
+terminate with an error.
+
+@item @code{lsh} (0x09): @var{a} @var{b} @result{} @var{a<<b}
+Pop two integers from the stack; let @var{a} be the next-to-top value,
+and @var{b} be the top value. Shift @var{a} left by @var{b} bits, and
+push the result.
+
+@item @code{rsh_signed} (0x0a): @var{a} @var{b} @result{} @var{@code{(signed)}a>>b}
+Pop two integers from the stack; let @var{a} be the next-to-top value,
+and @var{b} be the top value. Shift @var{a} right by @var{b} bits,
+inserting copies of the top bit at the high end, and push the result.
+
+@item @code{rsh_unsigned} (0x0b): @var{a} @var{b} @result{} @var{a>>b}
+Pop two integers from the stack; let @var{a} be the next-to-top value,
+and @var{b} be the top value. Shift @var{a} right by @var{b} bits,
+inserting zero bits at the high end, and push the result.
+
+@item @code{log_not} (0x0e): @var{a} @result{} @var{!a}
+Pop an integer from the stack; if it is zero, push the value one;
+otherwise, push the value zero.
+
+@item @code{bit_and} (0x0f): @var{a} @var{b} @result{} @var{a&b}
+Pop two integers from the stack, and push their bitwise @code{and}.
+
+@item @code{bit_or} (0x10): @var{a} @var{b} @result{} @var{a|b}
+Pop two integers from the stack, and push their bitwise @code{or}.
+
+@item @code{bit_xor} (0x11): @var{a} @var{b} @result{} @var{a^b}
+Pop two integers from the stack, and push their bitwise
+exclusive-@code{or}.
+
+@item @code{bit_not} (0x12): @var{a} @result{} @var{~a}
+Pop an integer from the stack, and push its bitwise complement.
+
+@item @code{equal} (0x13): @var{a} @var{b} @result{} @var{a=b}
+Pop two integers from the stack; if they are equal, push the value one;
+otherwise, push the value zero.
+
+@item @code{less_signed} (0x14): @var{a} @var{b} @result{} @var{a<b}
+Pop two signed integers from the stack; if the next-to-top value is less
+than the top value, push the value one; otherwise, push the value zero.
+
+@item @code{less_unsigned} (0x15): @var{a} @var{b} @result{} @var{a<b}
+Pop two unsigned integers from the stack; if the next-to-top value is less
+than the top value, push the value one; otherwise, push the value zero.
+
+@item @code{ext} (0x16) @var{n}: @var{a} @result{} @var{a}, sign-extended from @var{n} bits
+Pop an unsigned value from the stack; treating it as an @var{n}-bit
+twos-complement value, extend it to full length. This means that all
+bits to the left of bit @var{n-1} (where the least significant bit is bit
+0) are set to the value of bit @var{n-1}. Note that @var{n} may be
+larger than or equal to the width of the stack elements of the bytecode
+engine; in this case, the bytecode should have no effect.
+
+The number of source bits to preserve, @var{n}, is encoded as a single
+byte unsigned integer following the @code{ext} bytecode.
+
+@item @code{zero_ext} (0x2a) @var{n}: @var{a} @result{} @var{a}, zero-extended from @var{n} bits
+Pop an unsigned value from the stack; zero all but the bottom @var{n}
+bits. This means that all bits to the left of bit @var{n-1} (where the
+least significant bit is bit 0) are set to the value of bit @var{n-1}.
+
+The number of source bits to preserve, @var{n}, is encoded as a single
+byte unsigned integer following the @code{zero_ext} bytecode.
+
+@item @code{ref8} (0x17): @var{addr} @result{} @var{a}
+@itemx @code{ref16} (0x18): @var{addr} @result{} @var{a}
+@itemx @code{ref32} (0x19): @var{addr} @result{} @var{a}
+@itemx @code{ref64} (0x1a): @var{addr} @result{} @var{a}
+Pop an address @var{addr} from the stack. For bytecode
+@code{ref}@var{n}, fetch an @var{n}-bit value from @var{addr}, using the
+natural target endianness. Push the fetched value as an unsigned
+integer.
+
+Note that @var{addr} may not be aligned in any particular way; the
+@code{ref@var{n}} bytecodes should operate correctly for any address.
+
+If attempting to access memory at @var{addr} would cause a processor
+exception of some sort, terminate with an error.
+
+@item @code{ref_float} (0x1b): @var{addr} @result{} @var{d}
+@itemx @code{ref_double} (0x1c): @var{addr} @result{} @var{d}
+@itemx @code{ref_long_double} (0x1d): @var{addr} @result{} @var{d}
+@itemx @code{l_to_d} (0x1e): @var{a} @result{} @var{d}
+@itemx @code{d_to_l} (0x1f): @var{d} @result{} @var{a}
+Not implemented yet.
+
+@item @code{dup} (0x28): @var{a} => @var{a} @var{a}
+Push another copy of the stack's top element.
+
+@item @code{swap} (0x2b): @var{a} @var{b} => @var{b} @var{a}
+Exchange the top two items on the stack.
+
+@item @code{pop} (0x29): @var{a} =>
+Discard the top value on the stack.
+
+@item @code{if_goto} (0x20) @var{offset}: @var{a} @result{}
+Pop an integer off the stack; if it is non-zero, branch to the given
+offset in the bytecode string. Otherwise, continue to the next
+instruction in the bytecode stream. In other words, if @var{a} is
+non-zero, set the @code{pc} register to @code{start} + @var{offset}.
+Thus, an offset of zero denotes the beginning of the expression.
+
+The @var{offset} is stored as a sixteen-bit unsigned value, stored
+immediately following the @code{if_goto} bytecode. It is always stored
+most signficant byte first, regardless of the target's normal
+endianness. The offset is not guaranteed to fall at any particular
+alignment within the bytecode stream; thus, on machines where fetching a
+16-bit on an unaligned address raises an exception, you should fetch the
+offset one byte at a time.
+
+@item @code{goto} (0x21) @var{offset}: @result{}
+Branch unconditionally to @var{offset}; in other words, set the
+@code{pc} register to @code{start} + @var{offset}.
+
+The offset is stored in the same way as for the @code{if_goto} bytecode.
+
+@item @code{const8} (0x22) @var{n}: @result{} @var{n}
+@itemx @code{const16} (0x23) @var{n}: @result{} @var{n}
+@itemx @code{const32} (0x24) @var{n}: @result{} @var{n}
+@itemx @code{const64} (0x25) @var{n}: @result{} @var{n}
+Push the integer constant @var{n} on the stack, without sign extension.
+To produce a small negative value, push a small twos-complement value,
+and then sign-extend it using the @code{ext} bytecode.
+
+The constant @var{n} is stored in the appropriate number of bytes
+following the @code{const}@var{b} bytecode. The constant @var{n} is
+always stored most significant byte first, regardless of the target's
+normal endianness. The constant is not guaranteed to fall at any
+particular alignment within the bytecode stream; thus, on machines where
+fetching a 16-bit on an unaligned address raises an exception, you
+should fetch @var{n} one byte at a time.
+
+@item @code{reg} (0x26) @var{n}: @result{} @var{a}
+Push the value of register number @var{n}, without sign extension. The
+registers are numbered following GDB's conventions.
+
+The register number @var{n} is encoded as a 16-bit unsigned integer
+immediately following the @code{reg} bytecode. It is always stored most
+signficant byte first, regardless of the target's normal endianness.
+The register number is not guaranteed to fall at any particular
+alignment within the bytecode stream; thus, on machines where fetching a
+16-bit on an unaligned address raises an exception, you should fetch the
+register number one byte at a time.
+
+@item @code{trace} (0x0c): @var{addr} @var{size} @result{}
+Record the contents of the @var{size} bytes at @var{addr} in a trace
+buffer, for later retrieval by GDB.
+
+@item @code{trace_quick} (0x0d) @var{size}: @var{addr} @result{} @var{addr}
+Record the contents of the @var{size} bytes at @var{addr} in a trace
+buffer, for later retrieval by GDB. @var{size} is a single byte
+unsigned integer following the @code{trace} opcode.
+
+This bytecode is equivalent to the sequence @code{dup const8 @var{size}
+trace}, but we provide it anyway to save space in bytecode strings.
+
+@item @code{trace16} (0x30) @var{size}: @var{addr} @result{} @var{addr}
+Identical to trace_quick, except that @var{size} is a 16-bit big-endian
+unsigned integer, not a single byte. This should probably have been
+named @code{trace_quick16}, for consistency.
+
+@item @code{end} (0x27): @result{}
+Stop executing bytecode; the result should be the top element of the
+stack. If the purpose of the expression was to compute an lvalue or a
+range of memory, then the next-to-top of the stack is the lvalue's
+address, and the top of the stack is the lvalue's size, in bytes.
+
+@end table
+
+
+@node Using Agent Expressions
+@section Using Agent Expressions
+
+Here is a sketch of a full non-stop debugging cycle, showing how agent
+expressions fit into the process.
+
+@itemize @bullet
+
+@item
+The user selects trace points in the program's code at which GDB should
+collect data.
+
+@item
+The user specifies expressions to evaluate at each trace point. These
+expressions may denote objects in memory, in which case those objects'
+contents are recorded as the program runs, or computed values, in which
+case the values themselves are recorded.
+
+@item
+GDB transmits the tracepoints and their associated expressions to the
+GDB agent, running on the debugging target.
+
+@item
+The agent arranges to be notified when a trace point is hit. Note that,
+on some systems, the target operating system is completely responsible
+for collecting the data; see @ref{Tracing on Symmetrix}.
+
+@item
+When execution on the target reaches a trace point, the agent evaluates
+the expressions associated with that trace point, and records the
+resulting values and memory ranges.
+
+@item
+Later, when the user selects a given trace event and inspects the
+objects and expression values recorded, GDB talks to the agent to
+retrieve recorded data as necessary to meet the user's requests. If the
+user asks to see an object whose contents have not been recorded, GDB
+reports an error.
+
+@end itemize
+
+
+@node Varying Target Capabilities
+@section Varying Target Capabilities
+
+Some targets don't support floating-point, and some would rather not
+have to deal with @code{long long} operations. Also, different targets
+will have different stack sizes, and different bytecode buffer lengths.
+
+Thus, GDB needs a way to ask the target about itself. We haven't worked
+out the details yet, but in general, GDB should be able to send the
+target a packet asking it to describe itself. The reply should be a
+packet whose length is explicit, so we can add new information to the
+packet in future revisions of the agent, without confusing old versions
+of GDB, and it should contain a version number. It should contain at
+least the following information:
+
+@itemize @bullet
+
+@item
+whether floating point is supported
+
+@item
+whether @code{long long} is supported
+
+@item
+maximum acceptable size of bytecode stack
+
+@item
+maximum acceptable length of bytecode expressions
+
+@item
+which registers are actually available for collection
+
+@item
+whether the target supports disabled tracepoints
+
+@end itemize
+
+
+
+@node Tracing on Symmetrix
+@section Tracing on Symmetrix
+
+This section documents the API used by the GDB agent to collect data on
+Symmetrix systems.
+
+Cygnus originally implemented these tracing features to help EMC
+Corporation debug their Symmetrix high-availability disk drives. The
+Symmetrix application code already includes substantial tracing
+facilities; the GDB agent for the Symmetrix system uses those facilities
+for its own data collection, via the API described here.
+
+@deftypefn Function DTC_RESPONSE adbg_find_memory_in_frame (FRAME_DEF *@var{frame}, char *@var{address}, char **@var{buffer}, unsigned int *@var{size})
+Search the trace frame @var{frame} for memory saved from @var{address}.
+If the memory is available, provide the address of the buffer holding
+it; otherwise, provide the address of the next saved area.
+
+@itemize @bullet
+
+@item
+If the memory at @var{address} was saved in @var{frame}, set
+@code{*@var{buffer}} to point to the buffer in which that memory was
+saved, set @code{*@var{size}} to the number of bytes from @var{address}
+that are saved at @code{*@var{buffer}}, and return
+@code{OK_TARGET_RESPONSE}. (Clearly, in this case, the function will
+always set @code{*@var{size}} to a value greater than zero.)
+
+@item
+If @var{frame} does not record any memory at @var{address}, set
+@code{*@var{size}} to the distance from @var{address} to the start of
+the saved region with the lowest address higher than @var{address}. If
+there is no memory saved from any higher address, set @code{*@var{size}}
+to zero. Return @code{NOT_FOUND_TARGET_RESPONSE}.
+@end itemize
+
+These two possibilities allow the caller to either retrieve the data, or
+walk the address space to the next saved area.
+@end deftypefn
+
+This function allows the GDB agent to map the regions of memory saved in
+a particular frame, and retrieve their contents efficiently.
+
+This function also provides a clean interface between the GDB agent and
+the Symmetrix tracing structures, making it easier to adapt the GDB
+agent to future versions of the Symmetrix system, and vice versa. This
+function searches all data saved in @var{frame}, whether the data is
+there at the request of a bytecode expression, or because it falls in
+one of the format's memory ranges, or because it was saved from the top
+of the stack. EMC can arbitrarily change and enhance the tracing
+mechanism, but as long as this function works properly, all collected
+memory is visible to GDB.
+
+The function itself is straightforward to implement. A single pass over
+the trace frame's stack area, memory ranges, and expression blocks can
+yield the address of the buffer (if the requested address was saved),
+and also note the address of the next higher range of memory, to be
+returned when the search fails.
+
+As an example, suppose the trace frame @code{f} has saved sixteen bytes
+from address @code{0x8000} in a buffer at @code{0x1000}, and thirty-two
+bytes from address @code{0xc000} in a buffer at @code{0x1010}. Here are
+some sample calls, and the effect each would have:
+
+@table @code
+
+@item adbg_find_memory_in_frame (f, (char*) 0x8000, &buffer, &size)
+This would set @code{buffer} to @code{0x1000}, set @code{size} to
+sixteen, and return @code{OK_TARGET_RESPONSE}, since @code{f} saves
+sixteen bytes from @code{0x8000} at @code{0x1000}.
+
+@item adbg_find_memory_in_frame (f, (char *) 0x8004, &buffer, &size)
+This would set @code{buffer} to @code{0x1004}, set @code{size} to
+twelve, and return @code{OK_TARGET_RESPONSE}, since @file{f} saves the
+twelve bytes from @code{0x8004} starting four bytes into the buffer at
+@code{0x1000}. This shows that request addresses may fall in the middle
+of saved areas; the function should return the address and size of the
+remainder of the buffer.
+
+@item adbg_find_memory_in_frame (f, (char *) 0x8100, &buffer, &size)
+This would set @code{size} to @code{0x3f00} and return
+@code{NOT_FOUND_TARGET_RESPONSE}, since there is no memory saved in
+@code{f} from the address @code{0x8100}, and the next memory available
+is at @code{0x8100 + 0x3f00}, or @code{0xc000}. This shows that request
+addresses may fall outside of all saved memory ranges; the function
+should indicate the next saved area, if any.
+
+@item adbg_find_memory_in_frame (f, (char *) 0x7000, &buffer, &size)
+This would set @code{size} to @code{0x1000} and return
+@code{NOT_FOUND_TARGET_RESPONSE}, since the next saved memory is at
+@code{0x7000 + 0x1000}, or @code{0x8000}.
+
+@item adbg_find_memory_in_frame (f, (char *) 0xf000, &buffer, &size)
+This would set @code{size} to zero, and return
+@code{NOT_FOUND_TARGET_RESPONSE}. This shows how the function tells the
+caller that no further memory ranges have been saved.
+
+@end table
+
+As another example, here is a function which will print out the
+addresses of all memory saved in the trace frame @code{frame} on the
+Symmetrix INLINES console:
+@example
+void
+print_frame_addresses (FRAME_DEF *frame)
+@{
+ char *addr;
+ char *buffer;
+ unsigned long size;
+
+ addr = 0;
+ for (;;)
+ @{
+ /* Either find out how much memory we have here, or discover
+ where the next saved region is. */
+ if (adbg_find_memory_in_frame (frame, addr, &buffer, &size)
+ == OK_TARGET_RESPONSE)
+ printp ("saved %x to %x\n", addr, addr + size);
+ if (size == 0)
+ break;
+ addr += size;
+ @}
+@}
+@end example
+
+Note that there is not necessarily any connection between the order in
+which the data is saved in the trace frame, and the order in which
+@code{adbg_find_memory_in_frame} will return those memory ranges. The
+code above will always print the saved memory regions in order of
+increasing address, while the underlying frame structure might store the
+data in a random order.
+
+[[This section should cover the rest of the Symmetrix functions the stub
+relies upon, too.]]
+
+@node Rationale
+@section Rationale
+
+Some of the design decisions apparent above are arguable.
+
+@table @b
+
+@item What about stack overflow/underflow?
+GDB should be able to query the target to discover its stack size.
+Given that information, GDB can determine at translation time whether a
+given expression will overflow the stack. But this spec isn't about
+what kinds of error-checking GDB ought to do.
+
+@item Why are you doing everything in LONGEST?
+
+Speed isn't important, but agent code size is; using LONGEST brings in a
+bunch of support code to do things like division, etc. So this is a
+serious concern.
+
+First, note that you don't need different bytecodes for different
+operand sizes. You can generate code without @emph{knowing} how big the
+stack elements actually are on the target. If the target only supports
+32-bit ints, and you don't send any 64-bit bytecodes, everything just
+works. The observation here is that the MIPS and the Alpha have only
+fixed-size registers, and you can still get C's semantics even though
+most instructions only operate on full-sized words. You just need to
+make sure everything is properly sign-extended at the right times. So
+there is no need for 32- and 64-bit variants of the bytecodes. Just
+implement everything using the largest size you support.
+
+GDB should certainly check to see what sizes the target supports, so the
+user can get an error earlier, rather than later. But this information
+is not necessary for correctness.
+
+
+@item Why don't you have @code{>} or @code{<=} operators?
+I want to keep the interpreter small, and we don't need them. We can
+combine the @code{less_} opcodes with @code{log_not}, and swap the order
+of the operands, yielding all four asymmetrical comparison operators.
+For example, @code{(x <= y)} is @code{! (x > y)}, which is @code{! (y <
+x)}.
+
+@item Why do you have @code{log_not}?
+@itemx Why do you have @code{ext}?
+@itemx Why do you have @code{zero_ext}?
+These are all easily synthesized from other instructions, but I expect
+them to be used frequently, and they're simple, so I include them to
+keep bytecode strings short.
+
+@code{log_not} is equivalent to @code{const8 0 equal}; it's used in half
+the relational operators.
+
+@code{ext @var{n}} is equivalent to @code{const8 @var{s-n} lsh const8
+@var{s-n} rsh_signed}, where @var{s} is the size of the stack elements;
+it follows @code{ref@var{m}} and @var{reg} bytecodes when the value
+should be signed. See the next bulleted item.
+
+@code{zero_ext @var{n}} is equivalent to @code{const@var{m} @var{mask}
+log_and}; it's used whenever we push the value of a register, because we
+can't assume the upper bits of the register aren't garbage.
+
+@item Why not have sign-extending variants of the @code{ref} operators?
+Because that would double the number of @code{ref} operators, and we
+need the @code{ext} bytecode anyway for accessing bitfields.
+
+@item Why not have constant-address variants of the @code{ref} operators?
+Because that would double the number of @code{ref} operators again, and
+@code{const32 @var{address} ref32} is only one byte longer.
+
+@item Why do the @code{ref@var{n}} operators have to support unaligned fetches?
+GDB will generate bytecode that fetches multi-byte values at unaligned
+addresses whenever the executable's debugging information tells it to.
+Furthermore, GDB does not know the value the pointer will have when GDB
+generates the bytecode, so it cannot determine whether a particular
+fetch will be aligned or not.
+
+In particular, structure bitfields may be several bytes long, but follow
+no alignment rules; members of packed structures are not necessarily
+aligned either.
+
+In general, there are many cases where unaligned references occur in
+correct C code, either at the programmer's explicit request, or at the
+compiler's discretion. Thus, it is simpler to make the GDB agent
+bytecodes work correctly in all circumstances than to make GDB guess in
+each case whether the compiler did the usual thing.
+
+@item Why are there no side-effecting operators?
+Because our current client doesn't want them? That's a cheap answer. I
+think the real answer is that I'm afraid of implementing function
+calls. We should re-visit this issue after the present contract is
+delivered.
+
+@item Why aren't the @code{goto} ops PC-relative?
+The interpreter has the base address around anyway for PC bounds
+checking, and it seemed simpler.
+
+@item Why is there only one offset size for the @code{goto} ops?
+Offsets are currently sixteen bits. I'm not happy with this situation
+either:
+
+Suppose we have multiple branch ops with different offset sizes. As I
+generate code left-to-right, all my jumps are forward jumps (there are
+no loops in expressions), so I never know the target when I emit the
+jump opcode. Thus, I have to either always assume the largest offset
+size, or do jump relaxation on the code after I generate it, which seems
+like a big waste of time.
+
+I can imagine a reasonable expression being longer than 256 bytes. I
+can't imagine one being longer than 64k. Thus, we need 16-bit offsets.
+This kind of reasoning is so bogus, but relaxation is pathetic.
+
+The other approach would be to generate code right-to-left. Then I'd
+always know my offset size. That might be fun.
+
+@item Where is the function call bytecode?
+
+When we add side-effects, we should add this.
+
+@item Why does the @code{reg} bytecode take a 16-bit register number?
+
+Intel's IA-64 architecture has 128 general-purpose registers,
+and 128 floating-point registers, and I'm sure it has some random
+control registers.
+
+@item Why do we need @code{trace} and @code{trace_quick}?
+Because GDB needs to record all the memory contents and registers an
+expression touches. If the user wants to evaluate an expression
+@code{x->y->z}, the agent must record the values of @code{x} and
+@code{x->y} as well as the value of @code{x->y->z}.
+
+@item Don't the @code{trace} bytecodes make the interpreter less general?
+They do mean that the interpreter contains special-purpose code, but
+that doesn't mean the interpreter can only be used for that purpose. If
+an expression doesn't use the @code{trace} bytecodes, they don't get in
+its way.
+
+@item Why doesn't @code{trace_quick} consume its arguments the way everything else does?
+In general, you do want your operators to consume their arguments; it's
+consistent, and generally reduces the amount of stack rearrangement
+necessary. However, @code{trace_quick} is a kludge to save space; it
+only exists so we needn't write @code{dup const8 @var{SIZE} trace}
+before every memory reference. Therefore, it's okay for it not to
+consume its arguments; it's meant for a specific context in which we
+know exactly what it should do with the stack. If we're going to have a
+kludge, it should be an effective kludge.
+
+@item Why does @code{trace16} exist?
+That opcode was added by the customer that contracted Cygnus for the
+data tracing work. I personally think it is unnecessary; objects that
+large will be quite rare, so it is okay to use @code{dup const16
+@var{size} trace} in those cases.
+
+Whatever we decide to do with @code{trace16}, we should at least leave
+opcode 0x30 reserved, to remain compatible with the customer who added
+it.
+
+@end table
+
+@bye
diff --git a/gdb/doc/all-cfg.texi b/gdb/doc/all-cfg.texi
new file mode 100644
index 00000000000..6dee4e4ef67
--- /dev/null
+++ b/gdb/doc/all-cfg.texi
@@ -0,0 +1,45 @@
+@c GDB MANUAL configuration file.
+@c Copyright 1993, 1995, 1999 Free Software Foundation, Inc.
+@c
+@c NOTE: While the GDB manual is configurable (by changing these
+@c switches), its configuration is ***NOT*** automatically tied in to
+@c source configuration---because the authors expect that, save in
+@c unusual cases, the most inclusive form of the manual is appropriate
+@c no matter how the program itself is configured.
+@c
+@c The only automatically-varying variable is the GDB version number,
+@c which the Makefile rewrites based on the VERSION variable from
+@c `../Makefile.in'.
+@c
+@c GDB version number is recorded in the variable GDBVN
+@include GDBvn.texi
+@c
+@c ----------------------------------------------------------------------
+@c PLATFORM FLAGS:
+@set GENERIC
+@c
+@c HP PA-RISC target ONLY:
+@clear HPPA
+@c
+@c Refrain from discussing how to configure sw and format doc?
+@clear PRECONFIGURED
+@c
+@c ----------------------------------------------------------------------
+@c STRINGS:
+@c
+@c Name of GDB program. Used also for (gdb) prompt string.
+@set GDBP gdb
+@c
+@c Name of GDB product. Used in running text.
+@set GDBN GDB
+@c
+@c Name of host. Should not be used in generic configs, but generic
+@c value may catch some flubs.
+@set HOST machine specific
+@c
+@c Name of GCC product
+@set NGCC GCC
+@c
+@c Name of GCC program
+@set GCC gcc
+
diff --git a/gdb/doc/annotate.texi b/gdb/doc/annotate.texi
new file mode 100644
index 00000000000..59d599b5ff4
--- /dev/null
+++ b/gdb/doc/annotate.texi
@@ -0,0 +1,741 @@
+@c \input texinfo @c -*-texinfo-*-
+@c @c %**start of header
+@c @setfilename annotate.info
+@c @settitle GDB Annotations
+@c @setchapternewpage off
+@c @c %**end of header
+
+@c @set EDITION 0.5
+@c @set DATE May 1994
+
+@c @ifinfo
+@c This file documents GDB annotations.
+
+@c This is Edition @value{EDITION}, @value{DATE}, of @cite{GDB
+@c Annotations}. Copyright 1994,1995,2000,2001 Free Software Foundation, Inc.
+
+@c Permission is granted to copy, distribute and/or modify this document
+@c under the terms of the GNU Free Documentation License, Version 1.1 or
+@c any later version published by the Free Software Foundation; with no
+@c Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
+@c and with the Back-Cover Texts as in (a) below.
+
+@c (a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
+@c this GNU Manual, like GNU software. Copies published by the Free
+@c Software Foundation raise funds for GNU development.''
+@c @end ifinfo
+
+@c @titlepage
+@c @title GDB Annotations
+@c @subtitle Edition @value{EDITION}
+@c @subtitle @value{DATE}
+@c @author Cygnus Support
+@c @page
+@c @vskip 0pt plus 1filll
+@c Permission is granted to make and distribute verbatim copies of
+@c this manual provided the copyright notice and this permission notice
+@c are preserved on all copies.
+
+@c Copyright @copyright{} 1994,1995,2000,2001 Free Software Foundation
+@c @end titlepage
+
+@c @ifinfo
+@c @node Top
+@c @top GDB Annotations
+
+@c @syncodeindex fn cp
+
+@node Annotations
+@chapter @value{GDBN} Annotations
+
+This chapter describes annotations in @value{GDBN}. Annotations are
+designed to interface @value{GDBN} to graphical user interfaces or
+other similar programs which want to interact with @value{GDBN} at a
+relatively high level.
+
+@ignore
+This is Edition @value{EDITION}, @value{DATE}.
+@end ignore
+
+@menu
+* Annotations Overview:: What annotations are; the general syntax.
+* Server Prefix:: Issuing a command without affecting user state.
+* Value Annotations:: Values are marked as such.
+* Frame Annotations:: Stack frames are annotated.
+* Displays:: @value{GDBN} can be told to display something periodically.
+* Prompting:: Annotations marking @value{GDBN}'s need for input.
+* Errors:: Annotations for error messages.
+* Breakpoint Info:: Information on breakpoints.
+* Invalidation:: Some annotations describe things now invalid.
+* Annotations for Running::
+ Whether the program is running, how it stopped, etc.
+* Source Annotations:: Annotations describing source code.
+* TODO:: Annotations which might be added in the future.
+@end menu
+
+@node Annotations Overview
+@section What is an Annotation?
+@cindex annotations
+
+To produce annotations, start @value{GDBN} with the @code{--annotate=2} option.
+
+Annotations start with a newline character, two @samp{control-z}
+characters, and the name of the annotation. If there is no additional
+information associated with this annotation, the name of the annotation
+is followed immediately by a newline. If there is additional
+information, the name of the annotation is followed by a space, the
+additional information, and a newline. The additional information
+cannot contain newline characters.
+
+Any output not beginning with a newline and two @samp{control-z}
+characters denotes literal output from @value{GDBN}. Currently there is
+no need for @value{GDBN} to output a newline followed by two
+@samp{control-z} characters, but if there was such a need, the
+annotations could be extended with an @samp{escape} annotation which
+means those three characters as output.
+
+A simple example of starting up @value{GDBN} with annotations is:
+
+@smallexample
+$ gdb --annotate=2
+GNU GDB 5.0
+Copyright 2000 Free Software Foundation, Inc.
+GDB is free software, covered by the GNU General Public License,
+and you are welcome to change it and/or distribute copies of it
+under certain conditions.
+Type "show copying" to see the conditions.
+There is absolutely no warranty for GDB. Type "show warranty"
+for details.
+This GDB was configured as "sparc-sun-sunos4.1.3"
+
+^Z^Zpre-prompt
+(gdb)
+^Z^Zprompt
+quit
+
+^Z^Zpost-prompt
+$
+@end smallexample
+
+Here @samp{quit} is input to @value{GDBN}; the rest is output from
+@value{GDBN}. The three lines beginning @samp{^Z^Z} (where @samp{^Z}
+denotes a @samp{control-z} character) are annotations; the rest is
+output from @value{GDBN}.
+
+@node Server Prefix
+@section The Server Prefix
+@cindex server prefix for annotations
+
+To issue a command to @value{GDBN} without affecting certain aspects of
+the state which is seen by users, prefix it with @samp{server }. This
+means that this command will not affect the command history, nor will it
+affect @value{GDBN}'s notion of which command to repeat if @key{RET} is
+pressed on a line by itself.
+
+The server prefix does not affect the recording of values into the value
+history; to print a value without recording it into the value history,
+use the @code{output} command instead of the @code{print} command.
+
+@node Value Annotations
+@section Values
+
+@cindex annotations for values
+When a value is printed in various contexts, @value{GDBN} uses
+annotations to delimit the value from the surrounding text.
+
+@findex value-history-begin
+@findex value-history-value
+@findex value-history-end
+If a value is printed using @code{print} and added to the value history,
+the annotation looks like
+
+@smallexample
+^Z^Zvalue-history-begin @var{history-number} @var{value-flags}
+@var{history-string}
+^Z^Zvalue-history-value
+@var{the-value}
+^Z^Zvalue-history-end
+@end smallexample
+
+@noindent
+where @var{history-number} is the number it is getting in the value
+history, @var{history-string} is a string, such as @samp{$5 = }, which
+introduces the value to the user, @var{the-value} is the output
+corresponding to the value itself, and @var{value-flags} is @samp{*} for
+a value which can be dereferenced and @samp{-} for a value which cannot.
+
+@findex value-begin
+@findex value-end
+If the value is not added to the value history (it is an invalid float
+or it is printed with the @code{output} command), the annotation is similar:
+
+@smallexample
+^Z^Zvalue-begin @var{value-flags}
+@var{the-value}
+^Z^Zvalue-end
+@end smallexample
+
+@findex arg-begin
+@findex arg-name-end
+@findex arg-value
+@findex arg-end
+When @value{GDBN} prints an argument to a function (for example, in the output
+from the @code{backtrace} command), it annotates it as follows:
+
+@smallexample
+^Z^Zarg-begin
+@var{argument-name}
+^Z^Zarg-name-end
+@var{separator-string}
+^Z^Zarg-value @var{value-flags}
+@var{the-value}
+^Z^Zarg-end
+@end smallexample
+
+@noindent
+where @var{argument-name} is the name of the argument,
+@var{separator-string} is text which separates the name from the value
+for the user's benefit (such as @samp{=}), and @var{value-flags} and
+@var{the-value} have the same meanings as in a
+@code{value-history-begin} annotation.
+
+@findex field-begin
+@findex field-name-end
+@findex field-value
+@findex field-end
+When printing a structure, @value{GDBN} annotates it as follows:
+
+@smallexample
+^Z^Zfield-begin @var{value-flags}
+@var{field-name}
+^Z^Zfield-name-end
+@var{separator-string}
+^Z^Zfield-value
+@var{the-value}
+^Z^Zfield-end
+@end smallexample
+
+@noindent
+where @var{field-name} is the name of the field, @var{separator-string}
+is text which separates the name from the value for the user's benefit
+(such as @samp{=}), and @var{value-flags} and @var{the-value} have the
+same meanings as in a @code{value-history-begin} annotation.
+
+When printing an array, @value{GDBN} annotates it as follows:
+
+@smallexample
+^Z^Zarray-section-begin @var{array-index} @var{value-flags}
+@end smallexample
+
+@noindent
+where @var{array-index} is the index of the first element being
+annotated and @var{value-flags} has the same meaning as in a
+@code{value-history-begin} annotation. This is followed by any number
+of elements, where is element can be either a single element:
+
+@findex elt
+@smallexample
+@samp{,} @var{whitespace} ; @r{omitted for the first element}
+@var{the-value}
+^Z^Zelt
+@end smallexample
+
+or a repeated element
+
+@findex elt-rep
+@findex elt-rep-end
+@smallexample
+@samp{,} @var{whitespace} ; @r{omitted for the first element}
+@var{the-value}
+^Z^Zelt-rep @var{number-of-repititions}
+@var{repetition-string}
+^Z^Zelt-rep-end
+@end smallexample
+
+In both cases, @var{the-value} is the output for the value of the
+element and @var{whitespace} can contain spaces, tabs, and newlines. In
+the repeated case, @var{number-of-repititons} is the number of
+consecutive array elements which contain that value, and
+@var{repetition-string} is a string which is designed to convey to the
+user that repitition is being depicted.
+
+@findex array-section-end
+Once all the array elements have been output, the array annotation is
+ended with
+
+@smallexample
+^Z^Zarray-section-end
+@end smallexample
+
+@node Frame Annotations
+@section Frames
+
+@cindex annotations for frames
+Whenever @value{GDBN} prints a frame, it annotates it. For example, this applies
+to frames printed when @value{GDBN} stops, output from commands such as
+@code{backtrace} or @code{up}, etc.
+
+@findex frame-begin
+The frame annotation begins with
+
+@smallexample
+^Z^Zframe-begin @var{level} @var{address}
+@var{level-string}
+@end smallexample
+
+@noindent
+where @var{level} is the number of the frame (0 is the innermost frame,
+and other frames have positive numbers), @var{address} is the address of
+the code executing in that frame, and @var{level-string} is a string
+designed to convey the level to the user. @var{address} is in the form
+@samp{0x} followed by one or more lowercase hex digits (note that this
+does not depend on the language). The frame ends with
+
+@findex frame-end
+@smallexample
+^Z^Zframe-end
+@end smallexample
+
+Between these annotations is the main body of the frame, which can
+consist of
+
+@itemize @bullet
+@item
+@findex function-call
+@smallexample
+^Z^Zfunction-call
+@var{function-call-string}
+@end smallexample
+
+where @var{function-call-string} is text designed to convey to the user
+that this frame is associated with a function call made by @value{GDBN} to a
+function in the program being debugged.
+
+@item
+@findex signal-handler-caller
+@smallexample
+^Z^Zsignal-handler-caller
+@var{signal-handler-caller-string}
+@end smallexample
+
+where @var{signal-handler-caller-string} is text designed to convey to
+the user that this frame is associated with whatever mechanism is used
+by this operating system to call a signal handler (it is the frame which
+calls the signal handler, not the frame for the signal handler itself).
+
+@item
+A normal frame.
+
+@findex frame-address
+@findex frame-address-end
+This can optionally (depending on whether this is thought of as
+interesting information for the user to see) begin with
+
+@smallexample
+^Z^Zframe-address
+@var{address}
+^Z^Zframe-address-end
+@var{separator-string}
+@end smallexample
+
+where @var{address} is the address executing in the frame (the same
+address as in the @code{frame-begin} annotation, but printed in a form
+which is intended for user consumption---in particular, the syntax varies
+depending on the language), and @var{separator-string} is a string
+intended to separate this address from what follows for the user's
+benefit.
+
+@findex frame-function-name
+@findex frame-args
+Then comes
+
+@smallexample
+^Z^Zframe-function-name
+@var{function-name}
+^Z^Zframe-args
+@var{arguments}
+@end smallexample
+
+where @var{function-name} is the name of the function executing in the
+frame, or @samp{??} if not known, and @var{arguments} are the arguments
+to the frame, with parentheses around them (each argument is annotated
+individually as well, @pxref{Value Annotations}).
+
+@findex frame-source-begin
+@findex frame-source-file
+@findex frame-source-file-end
+@findex frame-source-line
+@findex frame-source-end
+If source information is available, a reference to it is then printed:
+
+@smallexample
+^Z^Zframe-source-begin
+@var{source-intro-string}
+^Z^Zframe-source-file
+@var{filename}
+^Z^Zframe-source-file-end
+:
+^Z^Zframe-source-line
+@var{line-number}
+^Z^Zframe-source-end
+@end smallexample
+
+where @var{source-intro-string} separates for the user's benefit the
+reference from the text which precedes it, @var{filename} is the name of
+the source file, and @var{line-number} is the line number within that
+file (the first line is line 1).
+
+@findex frame-where
+If @value{GDBN} prints some information about where the frame is from (which
+library, which load segment, etc.; currently only done on the RS/6000),
+it is annotated with
+
+@smallexample
+^Z^Zframe-where
+@var{information}
+@end smallexample
+
+Then, if source is to actually be displayed for this frame (for example,
+this is not true for output from the @code{backtrace} command), then a
+@code{source} annotation (@pxref{Source Annotations}) is displayed. Unlike
+most annotations, this is output instead of the normal text which would be
+output, not in addition.
+@end itemize
+
+@node Displays
+@section Displays
+
+@findex display-begin
+@findex display-number-end
+@findex display-format
+@findex display-expression
+@findex display-expression-end
+@findex display-value
+@findex display-end
+@cindex annotations for display
+When @value{GDBN} is told to display something using the @code{display} command,
+the results of the display are annotated:
+
+@smallexample
+^Z^Zdisplay-begin
+@var{number}
+^Z^Zdisplay-number-end
+@var{number-separator}
+^Z^Zdisplay-format
+@var{format}
+^Z^Zdisplay-expression
+@var{expression}
+^Z^Zdisplay-expression-end
+@var{expression-separator}
+^Z^Zdisplay-value
+@var{value}
+^Z^Zdisplay-end
+@end smallexample
+
+@noindent
+where @var{number} is the number of the display, @var{number-separator}
+is intended to separate the number from what follows for the user,
+@var{format} includes information such as the size, format, or other
+information about how the value is being displayed, @var{expression} is
+the expression being displayed, @var{expression-separator} is intended
+to separate the expression from the text that follows for the user,
+and @var{value} is the actual value being displayed.
+
+@node Prompting
+@section Annotation for @value{GDBN} Input
+
+@cindex annotations for prompts
+When @value{GDBN} prompts for input, it annotates this fact so it is possible
+to know when to send output, when the output from a given command is
+over, etc.
+
+Different kinds of input each have a different @dfn{input type}. Each
+input type has three annotations: a @code{pre-} annotation, which
+denotes the beginning of any prompt which is being output, a plain
+annotation, which denotes the end of the prompt, and then a @code{post-}
+annotation which denotes the end of any echo which may (or may not) be
+associated with the input. For example, the @code{prompt} input type
+features the following annotations:
+
+@smallexample
+^Z^Zpre-prompt
+^Z^Zprompt
+^Z^Zpost-prompt
+@end smallexample
+
+The input types are
+
+@table @code
+@findex pre-prompt
+@findex prompt
+@findex post-prompt
+@item prompt
+When @value{GDBN} is prompting for a command (the main @value{GDBN} prompt).
+
+@findex pre-commands
+@findex commands
+@findex post-commands
+@item commands
+When @value{GDBN} prompts for a set of commands, like in the @code{commands}
+command. The annotations are repeated for each command which is input.
+
+@findex pre-overload-choice
+@findex overload-choice
+@findex post-overload-choice
+@item overload-choice
+When @value{GDBN} wants the user to select between various overloaded functions.
+
+@findex pre-query
+@findex query
+@findex post-query
+@item query
+When @value{GDBN} wants the user to confirm a potentially dangerous operation.
+
+@findex pre-prompt-for-continue
+@findex prompt-for-continue
+@findex post-prompt-for-continue
+@item prompt-for-continue
+When @value{GDBN} is asking the user to press return to continue. Note: Don't
+expect this to work well; instead use @code{set height 0} to disable
+prompting. This is because the counting of lines is buggy in the
+presence of annotations.
+@end table
+
+@node Errors
+@section Errors
+@cindex annotations for errors, warnings and interrupts
+
+@findex quit
+@smallexample
+^Z^Zquit
+@end smallexample
+
+This annotation occurs right before @value{GDBN} responds to an interrupt.
+
+@findex error
+@smallexample
+^Z^Zerror
+@end smallexample
+
+This annotation occurs right before @value{GDBN} responds to an error.
+
+Quit and error annotations indicate that any annotations which @value{GDBN} was
+in the middle of may end abruptly. For example, if a
+@code{value-history-begin} annotation is followed by a @code{error}, one
+cannot expect to receive the matching @code{value-history-end}. One
+cannot expect not to receive it either, however; an error annotation
+does not necessarily mean that @value{GDBN} is immediately returning all the way
+to the top level.
+
+@findex error-begin
+A quit or error annotation may be preceded by
+
+@smallexample
+^Z^Zerror-begin
+@end smallexample
+
+Any output between that and the quit or error annotation is the error
+message.
+
+Warning messages are not yet annotated.
+@c If we want to change that, need to fix warning(), type_error(),
+@c range_error(), and possibly other places.
+
+@node Breakpoint Info
+@section Information on Breakpoints
+
+@cindex annotations for breakpoints
+The output from the @code{info breakpoints} command is annotated as follows:
+
+@findex breakpoints-headers
+@findex breakpoints-table
+@smallexample
+^Z^Zbreakpoints-headers
+@var{header-entry}
+^Z^Zbreakpoints-table
+@end smallexample
+
+@noindent
+where @var{header-entry} has the same syntax as an entry (see below) but
+instead of containing data, it contains strings which are intended to
+convey the meaning of each field to the user. This is followed by any
+number of entries. If a field does not apply for this entry, it is
+omitted. Fields may contain trailing whitespace. Each entry consists
+of:
+
+@findex record
+@findex field
+@smallexample
+^Z^Zrecord
+^Z^Zfield 0
+@var{number}
+^Z^Zfield 1
+@var{type}
+^Z^Zfield 2
+@var{disposition}
+^Z^Zfield 3
+@var{enable}
+^Z^Zfield 4
+@var{address}
+^Z^Zfield 5
+@var{what}
+^Z^Zfield 6
+@var{frame}
+^Z^Zfield 7
+@var{condition}
+^Z^Zfield 8
+@var{ignore-count}
+^Z^Zfield 9
+@var{commands}
+@end smallexample
+
+Note that @var{address} is intended for user consumption---the syntax
+varies depending on the language.
+
+The output ends with
+
+@findex breakpoints-table-end
+@smallexample
+^Z^Zbreakpoints-table-end
+@end smallexample
+
+@node Invalidation
+@section Invalidation Notices
+
+@cindex annotations for invalidation messages
+The following annotations say that certain pieces of state may have
+changed.
+
+@table @code
+@findex frames-invalid
+@item ^Z^Zframes-invalid
+
+The frames (for example, output from the @code{backtrace} command) may
+have changed.
+
+@findex breakpoints-invalid
+@item ^Z^Zbreakpoints-invalid
+
+The breakpoints may have changed. For example, the user just added or
+deleted a breakpoint.
+@end table
+
+@node Annotations for Running
+@section Running the Program
+@cindex annotations for running programs
+
+@findex starting
+@findex stopping
+When the program starts executing due to a @value{GDBN} command such as
+@code{step} or @code{continue},
+
+@smallexample
+^Z^Zstarting
+@end smallexample
+
+is output. When the program stops,
+
+@smallexample
+^Z^Zstopped
+@end smallexample
+
+is output. Before the @code{stopped} annotation, a variety of
+annotations describe how the program stopped.
+
+@table @code
+@findex exited
+@item ^Z^Zexited @var{exit-status}
+The program exited, and @var{exit-status} is the exit status (zero for
+successful exit, otherwise nonzero).
+
+@findex signalled
+@findex signal-name
+@findex signal-name-end
+@findex signal-string
+@findex signal-string-end
+@item ^Z^Zsignalled
+The program exited with a signal. After the @code{^Z^Zsignalled}, the
+annotation continues:
+
+@smallexample
+@var{intro-text}
+^Z^Zsignal-name
+@var{name}
+^Z^Zsignal-name-end
+@var{middle-text}
+^Z^Zsignal-string
+@var{string}
+^Z^Zsignal-string-end
+@var{end-text}
+@end smallexample
+
+@noindent
+where @var{name} is the name of the signal, such as @code{SIGILL} or
+@code{SIGSEGV}, and @var{string} is the explanation of the signal, such
+as @code{Illegal Instruction} or @code{Segmentation fault}.
+@var{intro-text}, @var{middle-text}, and @var{end-text} are for the
+user's benefit and have no particular format.
+
+@findex signal
+@item ^Z^Zsignal
+The syntax of this annotation is just like @code{signalled}, but @value{GDBN} is
+just saying that the program received the signal, not that it was
+terminated with it.
+
+@findex breakpoint
+@item ^Z^Zbreakpoint @var{number}
+The program hit breakpoint number @var{number}.
+
+@findex watchpoint
+@item ^Z^Zwatchpoint @var{number}
+The program hit watchpoint number @var{number}.
+@end table
+
+@node Source Annotations
+@section Displaying Source
+@cindex annotations for source display
+
+@findex source
+The following annotation is used instead of displaying source code:
+
+@smallexample
+^Z^Zsource @var{filename}:@var{line}:@var{character}:@var{middle}:@var{addr}
+@end smallexample
+
+where @var{filename} is an absolute file name indicating which source
+file, @var{line} is the line number within that file (where 1 is the
+first line in the file), @var{character} is the character position
+within the file (where 0 is the first character in the file) (for most
+debug formats this will necessarily point to the beginning of a line),
+@var{middle} is @samp{middle} if @var{addr} is in the middle of the
+line, or @samp{beg} if @var{addr} is at the beginning of the line, and
+@var{addr} is the address in the target program associated with the
+source which is being displayed. @var{addr} is in the form @samp{0x}
+followed by one or more lowercase hex digits (note that this does not
+depend on the language).
+
+@node TODO
+@section Annotations We Might Want in the Future
+
+@format
+ - target-invalid
+ the target might have changed (registers, heap contents, or
+ execution status). For performance, we might eventually want
+ to hit `registers-invalid' and `all-registers-invalid' with
+ greater precision
+
+ - systematic annotation for set/show parameters (including
+ invalidation notices).
+
+ - similarly, `info' returns a list of candidates for invalidation
+ notices.
+@end format
+
+@ignore
+@node Index
+@unnumbered Index
+
+@printindex fn
+@end ignore
+
+@c @bye
diff --git a/gdb/doc/configure b/gdb/doc/configure
new file mode 100755
index 00000000000..2f9ade3e547
--- /dev/null
+++ b/gdb/doc/configure
@@ -0,0 +1,888 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=refcard.tex
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:556: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ 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
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:609: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@LN_S@%$LN_S%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/doc/configure.in b/gdb/doc/configure.in
new file mode 100644
index 00000000000..fee9eced522
--- /dev/null
+++ b/gdb/doc/configure.in
@@ -0,0 +1,5 @@
+AC_PREREQ(2.12.1)
+AC_INIT(refcard.tex)
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_OUTPUT(Makefile)
diff --git a/gdb/doc/fdl.texi b/gdb/doc/fdl.texi
new file mode 100644
index 00000000000..f4726b9b149
--- /dev/null
+++ b/gdb/doc/fdl.texi
@@ -0,0 +1,368 @@
+@c -*-texinfo-*-
+@node GNU Free Documentation License
+
+@appendix GNU Free Documentation License
+@center Version 1.1, March 2000
+
+@display
+Copyright (C) 2000 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+@sp 1
+@enumerate 0
+@item
+PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+written document ``free'' in the sense of freedom: to assure everyone
+the effective freedom to copy and redistribute it, with or without
+modifying it, either commercially or noncommercially. Secondarily,
+this License preserves for the author and publisher a way to get
+credit for their work, while not being considered responsible for
+modifications made by others.
+
+This License is a kind of ``copyleft'', which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+@sp 1
+@item
+APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work that contains a
+notice placed by the copyright holder saying it can be distributed
+under the terms of this License. The ``Document'', below, refers to any
+such manual or work. Any member of the public is a licensee, and is
+addressed as ``you.''
+
+A ``Modified Version'' of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A ``Secondary Section'' is a named appendix or a front-matter section of
+the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall subject
+(or to related matters) and contains nothing that could fall directly
+within that overall subject. (For example, if the Document is in part a
+textbook of mathematics, a Secondary Section may not explain any
+mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The ``Invariant Sections'' are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License.
+
+The ``Cover Texts'' are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License.
+
+A ``Transparent'' copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, whose contents can be viewed and edited directly and
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup has been designed to thwart or discourage
+subsequent modification by readers is not Transparent. A copy that is
+not ``Transparent'' is called ``Opaque.''
+
+Examples of suitable formats for Transparent copies include plain
+ASCII without markup, Texinfo input format, LaTeX input format, SGML
+or XML using a publicly available DTD, and standard-conforming simple
+HTML designed for human modification. Opaque formats include
+PostScript, PDF, proprietary formats that can be read and edited only
+by proprietary word processors, SGML or XML for which the DTD and/or
+processing tools are not generally available, and the
+machine-generated HTML produced by some word processors for output
+purposes only.
+
+The ``Title Page'' means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, ``Title Page'' means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+@sp 1
+@item
+VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+@sp 1
+@item
+COPYING IN QUANTITY
+
+If you publish printed copies of the Document numbering more than 100,
+and the Document's license notice requires Cover Texts, you must enclose
+the copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a publicly-accessible computer-network location containing a complete
+Transparent copy of the Document, free of added material, which the
+general network-using public has access to download anonymously at no
+charge using public-standard network protocols. If you use the latter
+option, you must take reasonably prudent steps, when you begin
+distribution of Opaque copies in quantity, to ensure that this
+Transparent copy will remain thus accessible at the stated location
+until at least one year after the last time you distribute an Opaque
+copy (directly or through your agents or retailers) of that edition to
+the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+@sp 1
+@item
+MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+A. Use in the Title Page (and on the covers, if any) a title distinct
+ from that of the Document, and from those of previous versions
+ (which should, if there were any, be listed in the History section
+ of the Document). You may use the same title as a previous version
+ if the original publisher of that version gives permission.@*
+B. List on the Title Page, as authors, one or more persons or entities
+ responsible for authorship of the modifications in the Modified
+ Version, together with at least five of the principal authors of the
+ Document (all of its principal authors, if it has less than five).@*
+C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.@*
+D. Preserve all the copyright notices of the Document.@*
+E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.@*
+F. Include, immediately after the copyright notices, a license notice
+ giving the public permission to use the Modified Version under the
+ terms of this License, in the form shown in the Addendum below.@*
+G. Preserve in that license notice the full lists of Invariant Sections
+ and required Cover Texts given in the Document's license notice.@*
+H. Include an unaltered copy of this License.@*
+I. Preserve the section entitled ``History'', and its title, and add to
+ it an item stating at least the title, year, new authors, and
+ publisher of the Modified Version as given on the Title Page. If
+ there is no section entitled ``History'' in the Document, create one
+ stating the title, year, authors, and publisher of the Document as
+ given on its Title Page, then add an item describing the Modified
+ Version as stated in the previous sentence.@*
+J. Preserve the network location, if any, given in the Document for
+ public access to a Transparent copy of the Document, and likewise
+ the network locations given in the Document for previous versions
+ it was based on. These may be placed in the ``History'' section.
+ You may omit a network location for a work that was published at
+ least four years before the Document itself, or if the original
+ publisher of the version it refers to gives permission.@*
+K. In any section entitled ``Acknowledgements'' or ``Dedications'',
+ preserve the section's title, and preserve in the section all the
+ substance and tone of each of the contributor acknowledgements
+ and/or dedications given therein.@*
+L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section titles.@*
+M. Delete any section entitled ``Endorsements.'' Such a section
+ may not be included in the Modified Version.@*
+N. Do not retitle any existing section as ``Endorsements''
+ or to conflict in title with any Invariant Section.@*
+@sp 1
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section entitled ``Endorsements'', provided it contains
+nothing but endorsements of your Modified Version by various
+parties--for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+@sp 1
+@item
+COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections entitled ``History''
+in the various original documents, forming one section entitled
+``History''; likewise combine any sections entitled ``Acknowledgements'',
+and any sections entitled ``Dedications.'' You must delete all sections
+entitled ``Endorsements.''
+@sp 1
+@item
+COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+@sp 1
+@item
+AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, does not as a whole count as a Modified Version
+of the Document, provided no compilation copyright is claimed for the
+compilation. Such a compilation is called an ``aggregate'', and this
+License does not apply to the other self-contained works thus compiled
+with the Document, on account of their being thus compiled, if they
+are not themselves derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one quarter
+of the entire aggregate, the Document's Cover Texts may be placed on
+covers that surround only the Document within the aggregate.
+Otherwise they must appear on covers around the whole aggregate.
+@sp 1
+@item
+TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License provided that you also include the
+original English version of this License. In case of a disagreement
+between the translation and the original English version of this
+License, the original English version will prevail.
+@sp 1
+@item
+TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document except
+as expressly provided for under this License. Any other attempt to
+copy, modify, sublicense or distribute the Document is void, and will
+automatically terminate your rights under this License. However,
+parties who have received copies, or rights, from you under this
+License will not have their licenses terminated so long as such
+parties remain in full compliance.
+@sp 1
+@item
+FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+http://www.gnu.org/copyleft/.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License ``or any later version'' applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.
+
+@end enumerate
+
+@unnumberedsec ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+@smallexample
+@group
+Copyright (C) @var{year} @var{your name}.
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1
+or any later version published by the Free Software Foundation;
+with the Invariant Sections being @var{list their titles}, with the
+Front-Cover Texts being @var{list}, and with the Back-Cover Texts being @var{list}.
+A copy of the license is included in the section entitled "GNU
+Free Documentation License."
+@end group
+@end smallexample
+
+If you have no Invariant Sections, write ``with no Invariant Sections''
+instead of saying which ones are invariant. If you have no
+Front-Cover Texts, write ``no Front-Cover Texts'' instead of
+``Front-Cover Texts being @var{list}''; likewise for Back-Cover Texts.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
new file mode 100644
index 00000000000..5d840479bfd
--- /dev/null
+++ b/gdb/doc/gdb.texinfo
@@ -0,0 +1,15053 @@
+\input texinfo @c -*-texinfo-*-
+@c Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
+@c 1999, 2000, 2001, 2002
+@c Free Software Foundation, Inc.
+@c
+@c %**start of header
+@c makeinfo ignores cmds prev to setfilename, so its arg cannot make use
+@c of @set vars. However, you can override filename with makeinfo -o.
+@setfilename gdb.info
+@c
+@include gdb-cfg.texi
+@c
+@settitle Debugging with @value{GDBN}
+@setchapternewpage odd
+@c %**end of header
+
+@iftex
+@c @smallbook
+@c @cropmarks
+@end iftex
+
+@finalout
+@syncodeindex ky cp
+
+@c readline appendices use @vindex, @findex and @ftable,
+@c annotate.texi and gdbmi use @findex.
+@syncodeindex vr cp
+@syncodeindex fn cp
+
+@c !!set GDB manual's edition---not the same as GDB version!
+@set EDITION Ninth
+
+@c !!set GDB manual's revision date
+@set DATE December 2001
+
+@c THIS MANUAL REQUIRES TEXINFO 4.0 OR LATER.
+
+@c This is a dir.info fragment to support semi-automated addition of
+@c manuals to an info tree.
+@dircategory Programming & development tools.
+@direntry
+* Gdb: (gdb). The @sc{gnu} debugger.
+@end direntry
+
+@ifinfo
+This file documents the @sc{gnu} debugger @value{GDBN}.
+
+
+This is the @value{EDITION} Edition, @value{DATE},
+of @cite{Debugging with @value{GDBN}: the @sc{gnu} Source-Level Debugger}
+for @value{GDBN} Version @value{GDBVN}.
+
+Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,@*
+ 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``Free Software'' and ``Free Software Needs
+Free Documentation'', with the Front-Cover Texts being ``A GNU Manual,''
+and with the Back-Cover Texts as in (a) below.
+
+(a) The Free Software Foundation's Back-Cover Text is: ``You have
+freedom to copy and modify this GNU Manual, like GNU software. Copies
+published by the Free Software Foundation raise funds for GNU
+development.''
+@end ifinfo
+
+@titlepage
+@title Debugging with @value{GDBN}
+@subtitle The @sc{gnu} Source-Level Debugger
+@sp 1
+@subtitle @value{EDITION} Edition, for @value{GDBN} version @value{GDBVN}
+@subtitle @value{DATE}
+@author Richard Stallman, Roland Pesch, Stan Shebs, et al.
+@page
+@tex
+{\parskip=0pt
+\hfill (Send bugs and comments on @value{GDBN} to bug-gdb\@gnu.org.)\par
+\hfill {\it Debugging with @value{GDBN}}\par
+\hfill \TeX{}info \texinfoversion\par
+}
+@end tex
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+@sp 2
+Published by the Free Software Foundation @*
+59 Temple Place - Suite 330, @*
+Boston, MA 02111-1307 USA @*
+ISBN 1-882114-77-9 @*
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``Free Software'' and ``Free Software Needs
+Free Documentation'', with the Front-Cover Texts being ``A GNU Manual,''
+and with the Back-Cover Texts as in (a) below.
+
+(a) The Free Software Foundation's Back-Cover Text is: ``You have
+freedom to copy and modify this GNU Manual, like GNU software. Copies
+published by the Free Software Foundation raise funds for GNU
+development.''
+@end titlepage
+@page
+
+@ifnottex
+@node Top, Summary, (dir), (dir)
+
+@top Debugging with @value{GDBN}
+
+This file describes @value{GDBN}, the @sc{gnu} symbolic debugger.
+
+This is the @value{EDITION} Edition, @value{DATE}, for @value{GDBN} Version
+@value{GDBVN}.
+
+Copyright (C) 1988-2002 Free Software Foundation, Inc.
+
+@menu
+* Summary:: Summary of @value{GDBN}
+* Sample Session:: A sample @value{GDBN} session
+
+* Invocation:: Getting in and out of @value{GDBN}
+* Commands:: @value{GDBN} commands
+* Running:: Running programs under @value{GDBN}
+* Stopping:: Stopping and continuing
+* Stack:: Examining the stack
+* Source:: Examining source files
+* Data:: Examining data
+* Macros:: Preprocessor Macros
+* Tracepoints:: Debugging remote targets non-intrusively
+* Overlays:: Debugging programs that use overlays
+
+* Languages:: Using @value{GDBN} with different languages
+
+* Symbols:: Examining the symbol table
+* Altering:: Altering execution
+* GDB Files:: @value{GDBN} files
+* Targets:: Specifying a debugging target
+* Remote Debugging:: Debugging remote programs
+* Configurations:: Configuration-specific information
+* Controlling GDB:: Controlling @value{GDBN}
+* Sequences:: Canned sequences of commands
+* TUI:: @value{GDBN} Text User Interface
+* Emacs:: Using @value{GDBN} under @sc{gnu} Emacs
+* Annotations:: @value{GDBN}'s annotation interface.
+* GDB/MI:: @value{GDBN}'s Machine Interface.
+
+* GDB Bugs:: Reporting bugs in @value{GDBN}
+* Formatting Documentation:: How to format and print @value{GDBN} documentation
+
+* Command Line Editing:: Command Line Editing
+* Using History Interactively:: Using History Interactively
+* Installing GDB:: Installing GDB
+* Maintenance Commands:: Maintenance Commands
+* Remote Protocol:: GDB Remote Serial Protocol
+* Copying:: GNU General Public License says
+ how you can copy and share GDB
+* GNU Free Documentation License:: The license for this documentation
+* Index:: Index
+@end menu
+
+@end ifnottex
+
+@contents
+
+@node Summary
+@unnumbered Summary of @value{GDBN}
+
+The purpose of a debugger such as @value{GDBN} is to allow you to see what is
+going on ``inside'' another program while it executes---or what another
+program was doing at the moment it crashed.
+
+@value{GDBN} can do four main kinds of things (plus other things in support of
+these) to help you catch bugs in the act:
+
+@itemize @bullet
+@item
+Start your program, specifying anything that might affect its behavior.
+
+@item
+Make your program stop on specified conditions.
+
+@item
+Examine what has happened, when your program has stopped.
+
+@item
+Change things in your program, so you can experiment with correcting the
+effects of one bug and go on to learn about another.
+@end itemize
+
+You can use @value{GDBN} to debug programs written in C and C++.
+For more information, see @ref{Support,,Supported languages}.
+For more information, see @ref{C,,C and C++}.
+
+@cindex Chill
+@cindex Modula-2
+Support for Modula-2 and Chill is partial. For information on Modula-2,
+see @ref{Modula-2,,Modula-2}. For information on Chill, see @ref{Chill}.
+
+@cindex Pascal
+Debugging Pascal programs which use sets, subranges, file variables, or
+nested functions does not currently work. @value{GDBN} does not support
+entering expressions, printing values, or similar features using Pascal
+syntax.
+
+@cindex Fortran
+@value{GDBN} can be used to debug programs written in Fortran, although
+it may be necessary to refer to some variables with a trailing
+underscore.
+
+@menu
+* Free Software:: Freely redistributable software
+* Contributors:: Contributors to GDB
+@end menu
+
+@node Free Software
+@unnumberedsec Free software
+
+@value{GDBN} is @dfn{free software}, protected by the @sc{gnu}
+General Public License
+(GPL). The GPL gives you the freedom to copy or adapt a licensed
+program---but every person getting a copy also gets with it the
+freedom to modify that copy (which means that they must get access to
+the source code), and the freedom to distribute further copies.
+Typical software companies use copyrights to limit your freedoms; the
+Free Software Foundation uses the GPL to preserve these freedoms.
+
+Fundamentally, the General Public License is a license which says that
+you have these freedoms and that you cannot take these freedoms away
+from anyone else.
+
+@unnumberedsec Free Software Needs Free Documentation
+
+The biggest deficiency in the free software community today is not in
+the software---it is the lack of good free documentation that we can
+include with the free software. Many of our most important
+programs do not come with free reference manuals and free introductory
+texts. Documentation is an essential part of any software package;
+when an important free software package does not come with a free
+manual and a free tutorial, that is a major gap. We have many such
+gaps today.
+
+Consider Perl, for instance. The tutorial manuals that people
+normally use are non-free. How did this come about? Because the
+authors of those manuals published them with restrictive terms---no
+copying, no modification, source files not available---which exclude
+them from the free software world.
+
+That wasn't the first time this sort of thing happened, and it was far
+from the last. Many times we have heard a GNU user eagerly describe a
+manual that he is writing, his intended contribution to the community,
+only to learn that he had ruined everything by signing a publication
+contract to make it non-free.
+
+Free documentation, like free software, is a matter of freedom, not
+price. The problem with the non-free manual is not that publishers
+charge a price for printed copies---that in itself is fine. (The Free
+Software Foundation sells printed copies of manuals, too.) The
+problem is the restrictions on the use of the manual. Free manuals
+are available in source code form, and give you permission to copy and
+modify. Non-free manuals do not allow this.
+
+The criteria of freedom for a free manual are roughly the same as for
+free software. Redistribution (including the normal kinds of
+commercial redistribution) must be permitted, so that the manual can
+accompany every copy of the program, both on-line and on paper.
+
+Permission for modification of the technical content is crucial too.
+When people modify the software, adding or changing features, if they
+are conscientious they will change the manual too---so they can
+provide accurate and clear documentation for the modified program. A
+manual that leaves you no choice but to write a new manual to document
+a changed version of the program is not really available to our
+community.
+
+Some kinds of limits on the way modification is handled are
+acceptable. For example, requirements to preserve the original
+author's copyright notice, the distribution terms, or the list of
+authors, are ok. It is also no problem to require modified versions
+to include notice that they were modified. Even entire sections that
+may not be deleted or changed are acceptable, as long as they deal
+with nontechnical topics (like this one). These kinds of restrictions
+are acceptable because they don't obstruct the community's normal use
+of the manual.
+
+However, it must be possible to modify all the @emph{technical}
+content of the manual, and then distribute the result in all the usual
+media, through all the usual channels. Otherwise, the restrictions
+obstruct the use of the manual, it is not free, and we need another
+manual to replace it.
+
+Please spread the word about this issue. Our community continues to
+lose manuals to proprietary publishing. If we spread the word that
+free software needs free reference manuals and free tutorials, perhaps
+the next person who wants to contribute by writing documentation will
+realize, before it is too late, that only free manuals contribute to
+the free software community.
+
+If you are writing documentation, please insist on publishing it under
+the GNU Free Documentation License or another free documentation
+license. Remember that this decision requires your approval---you
+don't have to let the publisher decide. Some commercial publishers
+will use a free license if you insist, but they will not propose the
+option; it is up to you to raise the issue and say firmly that this is
+what you want. If the publisher you are dealing with refuses, please
+try other publishers. If you're not sure whether a proposed license
+is free, write to @email{licensing@@gnu.org}.
+
+You can encourage commercial publishers to sell more free, copylefted
+manuals and tutorials by buying them, and particularly by buying
+copies from the publishers that paid for their writing or for major
+improvements. Meanwhile, try to avoid buying non-free documentation
+at all. Check the distribution terms of a manual before you buy it,
+and insist that whoever seeks your business must respect your freedom.
+Check the history of the book, and try to reward the publishers that
+have paid or pay the authors to work on it.
+
+The Free Software Foundation maintains a list of free documentation
+published by other publishers, at
+@url{http://www.fsf.org/doc/other-free-books.html}.
+
+@node Contributors
+@unnumberedsec Contributors to @value{GDBN}
+
+Richard Stallman was the original author of @value{GDBN}, and of many
+other @sc{gnu} programs. Many others have contributed to its
+development. This section attempts to credit major contributors. One
+of the virtues of free software is that everyone is free to contribute
+to it; with regret, we cannot actually acknowledge everyone here. The
+file @file{ChangeLog} in the @value{GDBN} distribution approximates a
+blow-by-blow account.
+
+Changes much prior to version 2.0 are lost in the mists of time.
+
+@quotation
+@emph{Plea:} Additions to this section are particularly welcome. If you
+or your friends (or enemies, to be evenhanded) have been unfairly
+omitted from this list, we would like to add your names!
+@end quotation
+
+So that they may not regard their many labors as thankless, we
+particularly thank those who shepherded @value{GDBN} through major
+releases:
+Andrew Cagney (releases 5.0 and 5.1);
+Jim Blandy (release 4.18);
+Jason Molenda (release 4.17);
+Stan Shebs (release 4.14);
+Fred Fish (releases 4.16, 4.15, 4.13, 4.12, 4.11, 4.10, and 4.9);
+Stu Grossman and John Gilmore (releases 4.8, 4.7, 4.6, 4.5, and 4.4);
+John Gilmore (releases 4.3, 4.2, 4.1, 4.0, and 3.9);
+Jim Kingdon (releases 3.5, 3.4, and 3.3);
+and Randy Smith (releases 3.2, 3.1, and 3.0).
+
+Richard Stallman, assisted at various times by Peter TerMaat, Chris
+Hanson, and Richard Mlynarik, handled releases through 2.8.
+
+Michael Tiemann is the author of most of the @sc{gnu} C@t{++} support
+in @value{GDBN}, with significant additional contributions from Per
+Bothner and Daniel Berlin. James Clark wrote the @sc{gnu} C@t{++}
+demangler. Early work on C@t{++} was by Peter TerMaat (who also did
+much general update work leading to release 3.0).
+
+@value{GDBN} uses the BFD subroutine library to examine multiple
+object-file formats; BFD was a joint project of David V.
+Henkel-Wallace, Rich Pixley, Steve Chamberlain, and John Gilmore.
+
+David Johnson wrote the original COFF support; Pace Willison did
+the original support for encapsulated COFF.
+
+Brent Benson of Harris Computer Systems contributed DWARF2 support.
+
+Adam de Boor and Bradley Davis contributed the ISI Optimum V support.
+Per Bothner, Noboyuki Hikichi, and Alessandro Forin contributed MIPS
+support.
+Jean-Daniel Fekete contributed Sun 386i support.
+Chris Hanson improved the HP9000 support.
+Noboyuki Hikichi and Tomoyuki Hasei contributed Sony/News OS 3 support.
+David Johnson contributed Encore Umax support.
+Jyrki Kuoppala contributed Altos 3068 support.
+Jeff Law contributed HP PA and SOM support.
+Keith Packard contributed NS32K support.
+Doug Rabson contributed Acorn Risc Machine support.
+Bob Rusk contributed Harris Nighthawk CX-UX support.
+Chris Smith contributed Convex support (and Fortran debugging).
+Jonathan Stone contributed Pyramid support.
+Michael Tiemann contributed SPARC support.
+Tim Tucker contributed support for the Gould NP1 and Gould Powernode.
+Pace Willison contributed Intel 386 support.
+Jay Vosburgh contributed Symmetry support.
+
+Andreas Schwab contributed M68K Linux support.
+
+Rich Schaefer and Peter Schauer helped with support of SunOS shared
+libraries.
+
+Jay Fenlason and Roland McGrath ensured that @value{GDBN} and GAS agree
+about several machine instruction sets.
+
+Patrick Duval, Ted Goldstein, Vikram Koka and Glenn Engel helped develop
+remote debugging. Intel Corporation, Wind River Systems, AMD, and ARM
+contributed remote debugging modules for the i960, VxWorks, A29K UDI,
+and RDI targets, respectively.
+
+Brian Fox is the author of the readline libraries providing
+command-line editing and command history.
+
+Andrew Beers of SUNY Buffalo wrote the language-switching code, the
+Modula-2 support, and contributed the Languages chapter of this manual.
+
+Fred Fish wrote most of the support for Unix System Vr4.
+He also enhanced the command-completion support to cover C@t{++} overloaded
+symbols.
+
+Hitachi America, Ltd. sponsored the support for H8/300, H8/500, and
+Super-H processors.
+
+NEC sponsored the support for the v850, Vr4xxx, and Vr5xxx processors.
+
+Mitsubishi sponsored the support for D10V, D30V, and M32R/D processors.
+
+Toshiba sponsored the support for the TX39 Mips processor.
+
+Matsushita sponsored the support for the MN10200 and MN10300 processors.
+
+Fujitsu sponsored the support for SPARClite and FR30 processors.
+
+Kung Hsu, Jeff Law, and Rick Sladkey added support for hardware
+watchpoints.
+
+Michael Snyder added support for tracepoints.
+
+Stu Grossman wrote gdbserver.
+
+Jim Kingdon, Peter Schauer, Ian Taylor, and Stu Grossman made
+nearly innumerable bug fixes and cleanups throughout @value{GDBN}.
+
+The following people at the Hewlett-Packard Company contributed
+support for the PA-RISC 2.0 architecture, HP-UX 10.20, 10.30, and 11.0
+(narrow mode), HP's implementation of kernel threads, HP's aC@t{++}
+compiler, and the terminal user interface: Ben Krepp, Richard Title,
+John Bishop, Susan Macchia, Kathy Mann, Satish Pai, India Paul, Steve
+Rehrauer, and Elena Zannoni. Kim Haase provided HP-specific
+information in this manual.
+
+DJ Delorie ported @value{GDBN} to MS-DOS, for the DJGPP project.
+Robert Hoehne made significant contributions to the DJGPP port.
+
+Cygnus Solutions has sponsored @value{GDBN} maintenance and much of its
+development since 1991. Cygnus engineers who have worked on @value{GDBN}
+fulltime include Mark Alexander, Jim Blandy, Per Bothner, Kevin
+Buettner, Edith Epstein, Chris Faylor, Fred Fish, Martin Hunt, Jim
+Ingham, John Gilmore, Stu Grossman, Kung Hsu, Jim Kingdon, John Metzler,
+Fernando Nasser, Geoffrey Noer, Dawn Perchik, Rich Pixley, Zdenek
+Radouch, Keith Seitz, Stan Shebs, David Taylor, and Elena Zannoni. In
+addition, Dave Brolley, Ian Carmichael, Steve Chamberlain, Nick Clifton,
+JT Conklin, Stan Cox, DJ Delorie, Ulrich Drepper, Frank Eigler, Doug
+Evans, Sean Fagan, David Henkel-Wallace, Richard Henderson, Jeff
+Holcomb, Jeff Law, Jim Lemke, Tom Lord, Bob Manson, Michael Meissner,
+Jason Merrill, Catherine Moore, Drew Moseley, Ken Raeburn, Gavin
+Romig-Koch, Rob Savoye, Jamie Smith, Mike Stump, Ian Taylor, Angela
+Thomas, Michael Tiemann, Tom Tromey, Ron Unrau, Jim Wilson, and David
+Zuhn have made contributions both large and small.
+
+Jim Blandy added support for preprocessor macros, while working for Red
+Hat.
+
+@node Sample Session
+@chapter A Sample @value{GDBN} Session
+
+You can use this manual at your leisure to read all about @value{GDBN}.
+However, a handful of commands are enough to get started using the
+debugger. This chapter illustrates those commands.
+
+@iftex
+In this sample session, we emphasize user input like this: @b{input},
+to make it easier to pick out from the surrounding output.
+@end iftex
+
+@c FIXME: this example may not be appropriate for some configs, where
+@c FIXME...primary interest is in remote use.
+
+One of the preliminary versions of @sc{gnu} @code{m4} (a generic macro
+processor) exhibits the following bug: sometimes, when we change its
+quote strings from the default, the commands used to capture one macro
+definition within another stop working. In the following short @code{m4}
+session, we define a macro @code{foo} which expands to @code{0000}; we
+then use the @code{m4} built-in @code{defn} to define @code{bar} as the
+same thing. However, when we change the open quote string to
+@code{<QUOTE>} and the close quote string to @code{<UNQUOTE>}, the same
+procedure fails to define a new synonym @code{baz}:
+
+@smallexample
+$ @b{cd gnu/m4}
+$ @b{./m4}
+@b{define(foo,0000)}
+
+@b{foo}
+0000
+@b{define(bar,defn(`foo'))}
+
+@b{bar}
+0000
+@b{changequote(<QUOTE>,<UNQUOTE>)}
+
+@b{define(baz,defn(<QUOTE>foo<UNQUOTE>))}
+@b{baz}
+@b{C-d}
+m4: End of input: 0: fatal error: EOF in string
+@end smallexample
+
+@noindent
+Let us use @value{GDBN} to try to see what is going on.
+
+@smallexample
+$ @b{@value{GDBP} m4}
+@c FIXME: this falsifies the exact text played out, to permit smallbook
+@c FIXME... format to come out better.
+@value{GDBN} is free software and you are welcome to distribute copies
+ of it under certain conditions; type "show copying" to see
+ the conditions.
+There is absolutely no warranty for @value{GDBN}; type "show warranty"
+ for details.
+
+@value{GDBN} @value{GDBVN}, Copyright 1999 Free Software Foundation, Inc...
+(@value{GDBP})
+@end smallexample
+
+@noindent
+@value{GDBN} reads only enough symbol data to know where to find the
+rest when needed; as a result, the first prompt comes up very quickly.
+We now tell @value{GDBN} to use a narrower display width than usual, so
+that examples fit in this manual.
+
+@smallexample
+(@value{GDBP}) @b{set width 70}
+@end smallexample
+
+@noindent
+We need to see how the @code{m4} built-in @code{changequote} works.
+Having looked at the source, we know the relevant subroutine is
+@code{m4_changequote}, so we set a breakpoint there with the @value{GDBN}
+@code{break} command.
+
+@smallexample
+(@value{GDBP}) @b{break m4_changequote}
+Breakpoint 1 at 0x62f4: file builtin.c, line 879.
+@end smallexample
+
+@noindent
+Using the @code{run} command, we start @code{m4} running under @value{GDBN}
+control; as long as control does not reach the @code{m4_changequote}
+subroutine, the program runs as usual:
+
+@smallexample
+(@value{GDBP}) @b{run}
+Starting program: /work/Editorial/gdb/gnu/m4/m4
+@b{define(foo,0000)}
+
+@b{foo}
+0000
+@end smallexample
+
+@noindent
+To trigger the breakpoint, we call @code{changequote}. @value{GDBN}
+suspends execution of @code{m4}, displaying information about the
+context where it stops.
+
+@smallexample
+@b{changequote(<QUOTE>,<UNQUOTE>)}
+
+Breakpoint 1, m4_changequote (argc=3, argv=0x33c70)
+ at builtin.c:879
+879 if (bad_argc(TOKEN_DATA_TEXT(argv[0]),argc,1,3))
+@end smallexample
+
+@noindent
+Now we use the command @code{n} (@code{next}) to advance execution to
+the next line of the current function.
+
+@smallexample
+(@value{GDBP}) @b{n}
+882 set_quotes((argc >= 2) ? TOKEN_DATA_TEXT(argv[1])\
+ : nil,
+@end smallexample
+
+@noindent
+@code{set_quotes} looks like a promising subroutine. We can go into it
+by using the command @code{s} (@code{step}) instead of @code{next}.
+@code{step} goes to the next line to be executed in @emph{any}
+subroutine, so it steps into @code{set_quotes}.
+
+@smallexample
+(@value{GDBP}) @b{s}
+set_quotes (lq=0x34c78 "<QUOTE>", rq=0x34c88 "<UNQUOTE>")
+ at input.c:530
+530 if (lquote != def_lquote)
+@end smallexample
+
+@noindent
+The display that shows the subroutine where @code{m4} is now
+suspended (and its arguments) is called a stack frame display. It
+shows a summary of the stack. We can use the @code{backtrace}
+command (which can also be spelled @code{bt}), to see where we are
+in the stack as a whole: the @code{backtrace} command displays a
+stack frame for each active subroutine.
+
+@smallexample
+(@value{GDBP}) @b{bt}
+#0 set_quotes (lq=0x34c78 "<QUOTE>", rq=0x34c88 "<UNQUOTE>")
+ at input.c:530
+#1 0x6344 in m4_changequote (argc=3, argv=0x33c70)
+ at builtin.c:882
+#2 0x8174 in expand_macro (sym=0x33320) at macro.c:242
+#3 0x7a88 in expand_token (obs=0x0, t=209696, td=0xf7fffa30)
+ at macro.c:71
+#4 0x79dc in expand_input () at macro.c:40
+#5 0x2930 in main (argc=0, argv=0xf7fffb20) at m4.c:195
+@end smallexample
+
+@noindent
+We step through a few more lines to see what happens. The first two
+times, we can use @samp{s}; the next two times we use @code{n} to avoid
+falling into the @code{xstrdup} subroutine.
+
+@smallexample
+(@value{GDBP}) @b{s}
+0x3b5c 532 if (rquote != def_rquote)
+(@value{GDBP}) @b{s}
+0x3b80 535 lquote = (lq == nil || *lq == '\0') ? \
+def_lquote : xstrdup(lq);
+(@value{GDBP}) @b{n}
+536 rquote = (rq == nil || *rq == '\0') ? def_rquote\
+ : xstrdup(rq);
+(@value{GDBP}) @b{n}
+538 len_lquote = strlen(rquote);
+@end smallexample
+
+@noindent
+The last line displayed looks a little odd; we can examine the variables
+@code{lquote} and @code{rquote} to see if they are in fact the new left
+and right quotes we specified. We use the command @code{p}
+(@code{print}) to see their values.
+
+@smallexample
+(@value{GDBP}) @b{p lquote}
+$1 = 0x35d40 "<QUOTE>"
+(@value{GDBP}) @b{p rquote}
+$2 = 0x35d50 "<UNQUOTE>"
+@end smallexample
+
+@noindent
+@code{lquote} and @code{rquote} are indeed the new left and right quotes.
+To look at some context, we can display ten lines of source
+surrounding the current line with the @code{l} (@code{list}) command.
+
+@smallexample
+(@value{GDBP}) @b{l}
+533 xfree(rquote);
+534
+535 lquote = (lq == nil || *lq == '\0') ? def_lquote\
+ : xstrdup (lq);
+536 rquote = (rq == nil || *rq == '\0') ? def_rquote\
+ : xstrdup (rq);
+537
+538 len_lquote = strlen(rquote);
+539 len_rquote = strlen(lquote);
+540 @}
+541
+542 void
+@end smallexample
+
+@noindent
+Let us step past the two lines that set @code{len_lquote} and
+@code{len_rquote}, and then examine the values of those variables.
+
+@smallexample
+(@value{GDBP}) @b{n}
+539 len_rquote = strlen(lquote);
+(@value{GDBP}) @b{n}
+540 @}
+(@value{GDBP}) @b{p len_lquote}
+$3 = 9
+(@value{GDBP}) @b{p len_rquote}
+$4 = 7
+@end smallexample
+
+@noindent
+That certainly looks wrong, assuming @code{len_lquote} and
+@code{len_rquote} are meant to be the lengths of @code{lquote} and
+@code{rquote} respectively. We can set them to better values using
+the @code{p} command, since it can print the value of
+any expression---and that expression can include subroutine calls and
+assignments.
+
+@smallexample
+(@value{GDBP}) @b{p len_lquote=strlen(lquote)}
+$5 = 7
+(@value{GDBP}) @b{p len_rquote=strlen(rquote)}
+$6 = 9
+@end smallexample
+
+@noindent
+Is that enough to fix the problem of using the new quotes with the
+@code{m4} built-in @code{defn}? We can allow @code{m4} to continue
+executing with the @code{c} (@code{continue}) command, and then try the
+example that caused trouble initially:
+
+@smallexample
+(@value{GDBP}) @b{c}
+Continuing.
+
+@b{define(baz,defn(<QUOTE>foo<UNQUOTE>))}
+
+baz
+0000
+@end smallexample
+
+@noindent
+Success! The new quotes now work just as well as the default ones. The
+problem seems to have been just the two typos defining the wrong
+lengths. We allow @code{m4} exit by giving it an EOF as input:
+
+@smallexample
+@b{C-d}
+Program exited normally.
+@end smallexample
+
+@noindent
+The message @samp{Program exited normally.} is from @value{GDBN}; it
+indicates @code{m4} has finished executing. We can end our @value{GDBN}
+session with the @value{GDBN} @code{quit} command.
+
+@smallexample
+(@value{GDBP}) @b{quit}
+@end smallexample
+
+@node Invocation
+@chapter Getting In and Out of @value{GDBN}
+
+This chapter discusses how to start @value{GDBN}, and how to get out of it.
+The essentials are:
+@itemize @bullet
+@item
+type @samp{@value{GDBP}} to start @value{GDBN}.
+@item
+type @kbd{quit} or @kbd{C-d} to exit.
+@end itemize
+
+@menu
+* Invoking GDB:: How to start @value{GDBN}
+* Quitting GDB:: How to quit @value{GDBN}
+* Shell Commands:: How to use shell commands inside @value{GDBN}
+@end menu
+
+@node Invoking GDB
+@section Invoking @value{GDBN}
+
+Invoke @value{GDBN} by running the program @code{@value{GDBP}}. Once started,
+@value{GDBN} reads commands from the terminal until you tell it to exit.
+
+You can also run @code{@value{GDBP}} with a variety of arguments and options,
+to specify more of your debugging environment at the outset.
+
+The command-line options described here are designed
+to cover a variety of situations; in some environments, some of these
+options may effectively be unavailable.
+
+The most usual way to start @value{GDBN} is with one argument,
+specifying an executable program:
+
+@smallexample
+@value{GDBP} @var{program}
+@end smallexample
+
+@noindent
+You can also start with both an executable program and a core file
+specified:
+
+@smallexample
+@value{GDBP} @var{program} @var{core}
+@end smallexample
+
+You can, instead, specify a process ID as a second argument, if you want
+to debug a running process:
+
+@smallexample
+@value{GDBP} @var{program} 1234
+@end smallexample
+
+@noindent
+would attach @value{GDBN} to process @code{1234} (unless you also have a file
+named @file{1234}; @value{GDBN} does check for a core file first).
+
+Taking advantage of the second command-line argument requires a fairly
+complete operating system; when you use @value{GDBN} as a remote
+debugger attached to a bare board, there may not be any notion of
+``process'', and there is often no way to get a core dump. @value{GDBN}
+will warn you if it is unable to attach or to read core dumps.
+
+You can optionally have @code{@value{GDBP}} pass any arguments after the
+executable file to the inferior using @code{--args}. This option stops
+option processing.
+@smallexample
+gdb --args gcc -O2 -c foo.c
+@end smallexample
+This will cause @code{@value{GDBP}} to debug @code{gcc}, and to set
+@code{gcc}'s command-line arguments (@pxref{Arguments}) to @samp{-O2 -c foo.c}.
+
+You can run @code{@value{GDBP}} without printing the front material, which describes
+@value{GDBN}'s non-warranty, by specifying @code{-silent}:
+
+@smallexample
+@value{GDBP} -silent
+@end smallexample
+
+@noindent
+You can further control how @value{GDBN} starts up by using command-line
+options. @value{GDBN} itself can remind you of the options available.
+
+@noindent
+Type
+
+@smallexample
+@value{GDBP} -help
+@end smallexample
+
+@noindent
+to display all available options and briefly describe their use
+(@samp{@value{GDBP} -h} is a shorter equivalent).
+
+All options and command line arguments you give are processed
+in sequential order. The order makes a difference when the
+@samp{-x} option is used.
+
+
+@menu
+* File Options:: Choosing files
+* Mode Options:: Choosing modes
+@end menu
+
+@node File Options
+@subsection Choosing files
+
+When @value{GDBN} starts, it reads any arguments other than options as
+specifying an executable file and core file (or process ID). This is
+the same as if the arguments were specified by the @samp{-se} and
+@samp{-c} (or @samp{-p} options respectively. (@value{GDBN} reads the
+first argument that does not have an associated option flag as
+equivalent to the @samp{-se} option followed by that argument; and the
+second argument that does not have an associated option flag, if any, as
+equivalent to the @samp{-c}/@samp{-p} option followed by that argument.)
+If the second argument begins with a decimal digit, @value{GDBN} will
+first attempt to attach to it as a process, and if that fails, attempt
+to open it as a corefile. If you have a corefile whose name begins with
+a digit, you can prevent @value{GDBN} from treating it as a pid by
+prefixing it with @file{./}, eg. @file{./12345}.
+
+If @value{GDBN} has not been configured to included core file support,
+such as for most embedded targets, then it will complain about a second
+argument and ignore it.
+
+Many options have both long and short forms; both are shown in the
+following list. @value{GDBN} also recognizes the long forms if you truncate
+them, so long as enough of the option is present to be unambiguous.
+(If you prefer, you can flag option arguments with @samp{--} rather
+than @samp{-}, though we illustrate the more usual convention.)
+
+@c NOTE: the @cindex entries here use double dashes ON PURPOSE. This
+@c way, both those who look for -foo and --foo in the index, will find
+@c it.
+
+@table @code
+@item -symbols @var{file}
+@itemx -s @var{file}
+@cindex @code{--symbols}
+@cindex @code{-s}
+Read symbol table from file @var{file}.
+
+@item -exec @var{file}
+@itemx -e @var{file}
+@cindex @code{--exec}
+@cindex @code{-e}
+Use file @var{file} as the executable file to execute when appropriate,
+and for examining pure data in conjunction with a core dump.
+
+@item -se @var{file}
+@cindex @code{--se}
+Read symbol table from file @var{file} and use it as the executable
+file.
+
+@item -core @var{file}
+@itemx -c @var{file}
+@cindex @code{--core}
+@cindex @code{-c}
+Use file @var{file} as a core dump to examine.
+
+@item -c @var{number}
+@item -pid @var{number}
+@itemx -p @var{number}
+@cindex @code{--pid}
+@cindex @code{-p}
+Connect to process ID @var{number}, as with the @code{attach} command.
+If there is no such process, @value{GDBN} will attempt to open a core
+file named @var{number}.
+
+@item -command @var{file}
+@itemx -x @var{file}
+@cindex @code{--command}
+@cindex @code{-x}
+Execute @value{GDBN} commands from file @var{file}. @xref{Command
+Files,, Command files}.
+
+@item -directory @var{directory}
+@itemx -d @var{directory}
+@cindex @code{--directory}
+@cindex @code{-d}
+Add @var{directory} to the path to search for source files.
+
+@item -m
+@itemx -mapped
+@cindex @code{--mapped}
+@cindex @code{-m}
+@emph{Warning: this option depends on operating system facilities that are not
+supported on all systems.}@*
+If memory-mapped files are available on your system through the @code{mmap}
+system call, you can use this option
+to have @value{GDBN} write the symbols from your
+program into a reusable file in the current directory. If the program you are debugging is
+called @file{/tmp/fred}, the mapped symbol file is @file{/tmp/fred.syms}.
+Future @value{GDBN} debugging sessions notice the presence of this file,
+and can quickly map in symbol information from it, rather than reading
+the symbol table from the executable program.
+
+The @file{.syms} file is specific to the host machine where @value{GDBN}
+is run. It holds an exact image of the internal @value{GDBN} symbol
+table. It cannot be shared across multiple host platforms.
+
+@item -r
+@itemx -readnow
+@cindex @code{--readnow}
+@cindex @code{-r}
+Read each symbol file's entire symbol table immediately, rather than
+the default, which is to read it incrementally as it is needed.
+This makes startup slower, but makes future operations faster.
+
+@end table
+
+You typically combine the @code{-mapped} and @code{-readnow} options in
+order to build a @file{.syms} file that contains complete symbol
+information. (@xref{Files,,Commands to specify files}, for information
+on @file{.syms} files.) A simple @value{GDBN} invocation to do nothing
+but build a @file{.syms} file for future use is:
+
+@smallexample
+gdb -batch -nx -mapped -readnow programname
+@end smallexample
+
+@node Mode Options
+@subsection Choosing modes
+
+You can run @value{GDBN} in various alternative modes---for example, in
+batch mode or quiet mode.
+
+@table @code
+@item -nx
+@itemx -n
+@cindex @code{--nx}
+@cindex @code{-n}
+Do not execute commands found in any initialization files. Normally,
+@value{GDBN} executes the commands in these files after all the command
+options and arguments have been processed. @xref{Command Files,,Command
+files}.
+
+@item -quiet
+@itemx -silent
+@itemx -q
+@cindex @code{--quiet}
+@cindex @code{--silent}
+@cindex @code{-q}
+``Quiet''. Do not print the introductory and copyright messages. These
+messages are also suppressed in batch mode.
+
+@item -batch
+@cindex @code{--batch}
+Run in batch mode. Exit with status @code{0} after processing all the
+command files specified with @samp{-x} (and all commands from
+initialization files, if not inhibited with @samp{-n}). Exit with
+nonzero status if an error occurs in executing the @value{GDBN} commands
+in the command files.
+
+Batch mode may be useful for running @value{GDBN} as a filter, for
+example to download and run a program on another computer; in order to
+make this more useful, the message
+
+@smallexample
+Program exited normally.
+@end smallexample
+
+@noindent
+(which is ordinarily issued whenever a program running under
+@value{GDBN} control terminates) is not issued when running in batch
+mode.
+
+@item -nowindows
+@itemx -nw
+@cindex @code{--nowindows}
+@cindex @code{-nw}
+``No windows''. If @value{GDBN} comes with a graphical user interface
+(GUI) built in, then this option tells @value{GDBN} to only use the command-line
+interface. If no GUI is available, this option has no effect.
+
+@item -windows
+@itemx -w
+@cindex @code{--windows}
+@cindex @code{-w}
+If @value{GDBN} includes a GUI, then this option requires it to be
+used if possible.
+
+@item -cd @var{directory}
+@cindex @code{--cd}
+Run @value{GDBN} using @var{directory} as its working directory,
+instead of the current directory.
+
+@item -fullname
+@itemx -f
+@cindex @code{--fullname}
+@cindex @code{-f}
+@sc{gnu} Emacs sets this option when it runs @value{GDBN} as a
+subprocess. It tells @value{GDBN} to output the full file name and line
+number in a standard, recognizable fashion each time a stack frame is
+displayed (which includes each time your program stops). This
+recognizable format looks like two @samp{\032} characters, followed by
+the file name, line number and character position separated by colons,
+and a newline. The Emacs-to-@value{GDBN} interface program uses the two
+@samp{\032} characters as a signal to display the source code for the
+frame.
+
+@item -epoch
+@cindex @code{--epoch}
+The Epoch Emacs-@value{GDBN} interface sets this option when it runs
+@value{GDBN} as a subprocess. It tells @value{GDBN} to modify its print
+routines so as to allow Epoch to display values of expressions in a
+separate window.
+
+@item -annotate @var{level}
+@cindex @code{--annotate}
+This option sets the @dfn{annotation level} inside @value{GDBN}. Its
+effect is identical to using @samp{set annotate @var{level}}
+(@pxref{Annotations}).
+Annotation level controls how much information does @value{GDBN} print
+together with its prompt, values of expressions, source lines, and other
+types of output. Level 0 is the normal, level 1 is for use when
+@value{GDBN} is run as a subprocess of @sc{gnu} Emacs, level 2 is the
+maximum annotation suitable for programs that control @value{GDBN}.
+
+@item -async
+@cindex @code{--async}
+Use the asynchronous event loop for the command-line interface.
+@value{GDBN} processes all events, such as user keyboard input, via a
+special event loop. This allows @value{GDBN} to accept and process user
+commands in parallel with the debugged process being
+run@footnote{@value{GDBN} built with @sc{djgpp} tools for
+MS-DOS/MS-Windows supports this mode of operation, but the event loop is
+suspended when the debuggee runs.}, so you don't need to wait for
+control to return to @value{GDBN} before you type the next command.
+(@emph{Note:} as of version 5.1, the target side of the asynchronous
+operation is not yet in place, so @samp{-async} does not work fully
+yet.)
+@c FIXME: when the target side of the event loop is done, the above NOTE
+@c should be removed.
+
+When the standard input is connected to a terminal device, @value{GDBN}
+uses the asynchronous event loop by default, unless disabled by the
+@samp{-noasync} option.
+
+@item -noasync
+@cindex @code{--noasync}
+Disable the asynchronous event loop for the command-line interface.
+
+@item --args
+@cindex @code{--args}
+Change interpretation of command line so that arguments following the
+executable file are passed as command line arguments to the inferior.
+This option stops option processing.
+
+@item -baud @var{bps}
+@itemx -b @var{bps}
+@cindex @code{--baud}
+@cindex @code{-b}
+Set the line speed (baud rate or bits per second) of any serial
+interface used by @value{GDBN} for remote debugging.
+
+@item -tty @var{device}
+@itemx -t @var{device}
+@cindex @code{--tty}
+@cindex @code{-t}
+Run using @var{device} for your program's standard input and output.
+@c FIXME: kingdon thinks there is more to -tty. Investigate.
+
+@c resolve the situation of these eventually
+@item -tui
+@cindex @code{--tui}
+Activate the Terminal User Interface when starting.
+The Terminal User Interface manages several text windows on the terminal,
+showing source, assembly, registers and @value{GDBN} command outputs
+(@pxref{TUI, ,@value{GDBN} Text User Interface}).
+Do not use this option if you run @value{GDBN} from Emacs
+(@pxref{Emacs, ,Using @value{GDBN} under @sc{gnu} Emacs}).
+
+@c @item -xdb
+@c @cindex @code{--xdb}
+@c Run in XDB compatibility mode, allowing the use of certain XDB commands.
+@c For information, see the file @file{xdb_trans.html}, which is usually
+@c installed in the directory @code{/opt/langtools/wdb/doc} on HP-UX
+@c systems.
+
+@item -interpreter @var{interp}
+@cindex @code{--interpreter}
+Use the interpreter @var{interp} for interface with the controlling
+program or device. This option is meant to be set by programs which
+communicate with @value{GDBN} using it as a back end.
+
+@samp{--interpreter=mi} (or @samp{--interpreter=mi1}) causes
+@value{GDBN} to use the @dfn{gdb/mi interface} (@pxref{GDB/MI, , The
+@sc{gdb/mi} Interface}). The older @sc{gdb/mi} interface, included in
+@value{GDBN} version 5.0 can be selected with @samp{--interpreter=mi0}.
+
+@item -write
+@cindex @code{--write}
+Open the executable and core files for both reading and writing. This
+is equivalent to the @samp{set write on} command inside @value{GDBN}
+(@pxref{Patching}).
+
+@item -statistics
+@cindex @code{--statistics}
+This option causes @value{GDBN} to print statistics about time and
+memory usage after it completes each command and returns to the prompt.
+
+@item -version
+@cindex @code{--version}
+This option causes @value{GDBN} to print its version number and
+no-warranty blurb, and exit.
+
+@end table
+
+@node Quitting GDB
+@section Quitting @value{GDBN}
+@cindex exiting @value{GDBN}
+@cindex leaving @value{GDBN}
+
+@table @code
+@kindex quit @r{[}@var{expression}@r{]}
+@kindex q @r{(@code{quit})}
+@item quit @r{[}@var{expression}@r{]}
+@itemx q
+To exit @value{GDBN}, use the @code{quit} command (abbreviated
+@code{q}), or type an end-of-file character (usually @kbd{C-d}). If you
+do not supply @var{expression}, @value{GDBN} will terminate normally;
+otherwise it will terminate using the result of @var{expression} as the
+error code.
+@end table
+
+@cindex interrupt
+An interrupt (often @kbd{C-c}) does not exit from @value{GDBN}, but rather
+terminates the action of any @value{GDBN} command that is in progress and
+returns to @value{GDBN} command level. It is safe to type the interrupt
+character at any time because @value{GDBN} does not allow it to take effect
+until a time when it is safe.
+
+If you have been using @value{GDBN} to control an attached process or
+device, you can release it with the @code{detach} command
+(@pxref{Attach, ,Debugging an already-running process}).
+
+@node Shell Commands
+@section Shell commands
+
+If you need to execute occasional shell commands during your
+debugging session, there is no need to leave or suspend @value{GDBN}; you can
+just use the @code{shell} command.
+
+@table @code
+@kindex shell
+@cindex shell escape
+@item shell @var{command string}
+Invoke a standard shell to execute @var{command string}.
+If it exists, the environment variable @code{SHELL} determines which
+shell to run. Otherwise @value{GDBN} uses the default shell
+(@file{/bin/sh} on Unix systems, @file{COMMAND.COM} on MS-DOS, etc.).
+@end table
+
+The utility @code{make} is often needed in development environments.
+You do not have to use the @code{shell} command for this purpose in
+@value{GDBN}:
+
+@table @code
+@kindex make
+@cindex calling make
+@item make @var{make-args}
+Execute the @code{make} program with the specified
+arguments. This is equivalent to @samp{shell make @var{make-args}}.
+@end table
+
+@node Commands
+@chapter @value{GDBN} Commands
+
+You can abbreviate a @value{GDBN} command to the first few letters of the command
+name, if that abbreviation is unambiguous; and you can repeat certain
+@value{GDBN} commands by typing just @key{RET}. You can also use the @key{TAB}
+key to get @value{GDBN} to fill out the rest of a word in a command (or to
+show you the alternatives available, if there is more than one possibility).
+
+@menu
+* Command Syntax:: How to give commands to @value{GDBN}
+* Completion:: Command completion
+* Help:: How to ask @value{GDBN} for help
+@end menu
+
+@node Command Syntax
+@section Command syntax
+
+A @value{GDBN} command is a single line of input. There is no limit on
+how long it can be. It starts with a command name, which is followed by
+arguments whose meaning depends on the command name. For example, the
+command @code{step} accepts an argument which is the number of times to
+step, as in @samp{step 5}. You can also use the @code{step} command
+with no arguments. Some commands do not allow any arguments.
+
+@cindex abbreviation
+@value{GDBN} command names may always be truncated if that abbreviation is
+unambiguous. Other possible command abbreviations are listed in the
+documentation for individual commands. In some cases, even ambiguous
+abbreviations are allowed; for example, @code{s} is specially defined as
+equivalent to @code{step} even though there are other commands whose
+names start with @code{s}. You can test abbreviations by using them as
+arguments to the @code{help} command.
+
+@cindex repeating commands
+@kindex RET @r{(repeat last command)}
+A blank line as input to @value{GDBN} (typing just @key{RET}) means to
+repeat the previous command. Certain commands (for example, @code{run})
+will not repeat this way; these are commands whose unintentional
+repetition might cause trouble and which you are unlikely to want to
+repeat.
+
+The @code{list} and @code{x} commands, when you repeat them with
+@key{RET}, construct new arguments rather than repeating
+exactly as typed. This permits easy scanning of source or memory.
+
+@value{GDBN} can also use @key{RET} in another way: to partition lengthy
+output, in a way similar to the common utility @code{more}
+(@pxref{Screen Size,,Screen size}). Since it is easy to press one
+@key{RET} too many in this situation, @value{GDBN} disables command
+repetition after any command that generates this sort of display.
+
+@kindex # @r{(a comment)}
+@cindex comment
+Any text from a @kbd{#} to the end of the line is a comment; it does
+nothing. This is useful mainly in command files (@pxref{Command
+Files,,Command files}).
+
+@cindex repeating command sequences
+@kindex C-o @r{(operate-and-get-next)}
+The @kbd{C-o} binding is useful for repeating a complex sequence of
+commands. This command accepts the current line, like @kbd{RET}, and
+then fetches the next line relative to the current line from the history
+for editing.
+
+@node Completion
+@section Command completion
+
+@cindex completion
+@cindex word completion
+@value{GDBN} can fill in the rest of a word in a command for you, if there is
+only one possibility; it can also show you what the valid possibilities
+are for the next word in a command, at any time. This works for @value{GDBN}
+commands, @value{GDBN} subcommands, and the names of symbols in your program.
+
+Press the @key{TAB} key whenever you want @value{GDBN} to fill out the rest
+of a word. If there is only one possibility, @value{GDBN} fills in the
+word, and waits for you to finish the command (or press @key{RET} to
+enter it). For example, if you type
+
+@c FIXME "@key" does not distinguish its argument sufficiently to permit
+@c complete accuracy in these examples; space introduced for clarity.
+@c If texinfo enhancements make it unnecessary, it would be nice to
+@c replace " @key" by "@key" in the following...
+@smallexample
+(@value{GDBP}) info bre @key{TAB}
+@end smallexample
+
+@noindent
+@value{GDBN} fills in the rest of the word @samp{breakpoints}, since that is
+the only @code{info} subcommand beginning with @samp{bre}:
+
+@smallexample
+(@value{GDBP}) info breakpoints
+@end smallexample
+
+@noindent
+You can either press @key{RET} at this point, to run the @code{info
+breakpoints} command, or backspace and enter something else, if
+@samp{breakpoints} does not look like the command you expected. (If you
+were sure you wanted @code{info breakpoints} in the first place, you
+might as well just type @key{RET} immediately after @samp{info bre},
+to exploit command abbreviations rather than command completion).
+
+If there is more than one possibility for the next word when you press
+@key{TAB}, @value{GDBN} sounds a bell. You can either supply more
+characters and try again, or just press @key{TAB} a second time;
+@value{GDBN} displays all the possible completions for that word. For
+example, you might want to set a breakpoint on a subroutine whose name
+begins with @samp{make_}, but when you type @kbd{b make_@key{TAB}} @value{GDBN}
+just sounds the bell. Typing @key{TAB} again displays all the
+function names in your program that begin with those characters, for
+example:
+
+@smallexample
+(@value{GDBP}) b make_ @key{TAB}
+@exdent @value{GDBN} sounds bell; press @key{TAB} again, to see:
+make_a_section_from_file make_environ
+make_abs_section make_function_type
+make_blockvector make_pointer_type
+make_cleanup make_reference_type
+make_command make_symbol_completion_list
+(@value{GDBP}) b make_
+@end smallexample
+
+@noindent
+After displaying the available possibilities, @value{GDBN} copies your
+partial input (@samp{b make_} in the example) so you can finish the
+command.
+
+If you just want to see the list of alternatives in the first place, you
+can press @kbd{M-?} rather than pressing @key{TAB} twice. @kbd{M-?}
+means @kbd{@key{META} ?}. You can type this either by holding down a
+key designated as the @key{META} shift on your keyboard (if there is
+one) while typing @kbd{?}, or as @key{ESC} followed by @kbd{?}.
+
+@cindex quotes in commands
+@cindex completion of quoted strings
+Sometimes the string you need, while logically a ``word'', may contain
+parentheses or other characters that @value{GDBN} normally excludes from
+its notion of a word. To permit word completion to work in this
+situation, you may enclose words in @code{'} (single quote marks) in
+@value{GDBN} commands.
+
+The most likely situation where you might need this is in typing the
+name of a C@t{++} function. This is because C@t{++} allows function
+overloading (multiple definitions of the same function, distinguished
+by argument type). For example, when you want to set a breakpoint you
+may need to distinguish whether you mean the version of @code{name}
+that takes an @code{int} parameter, @code{name(int)}, or the version
+that takes a @code{float} parameter, @code{name(float)}. To use the
+word-completion facilities in this situation, type a single quote
+@code{'} at the beginning of the function name. This alerts
+@value{GDBN} that it may need to consider more information than usual
+when you press @key{TAB} or @kbd{M-?} to request word completion:
+
+@smallexample
+(@value{GDBP}) b 'bubble( @kbd{M-?}
+bubble(double,double) bubble(int,int)
+(@value{GDBP}) b 'bubble(
+@end smallexample
+
+In some cases, @value{GDBN} can tell that completing a name requires using
+quotes. When this happens, @value{GDBN} inserts the quote for you (while
+completing as much as it can) if you do not type the quote in the first
+place:
+
+@smallexample
+(@value{GDBP}) b bub @key{TAB}
+@exdent @value{GDBN} alters your input line to the following, and rings a bell:
+(@value{GDBP}) b 'bubble(
+@end smallexample
+
+@noindent
+In general, @value{GDBN} can tell that a quote is needed (and inserts it) if
+you have not yet started typing the argument list when you ask for
+completion on an overloaded symbol.
+
+For more information about overloaded functions, see @ref{C plus plus
+expressions, ,C@t{++} expressions}. You can use the command @code{set
+overload-resolution off} to disable overload resolution;
+see @ref{Debugging C plus plus, ,@value{GDBN} features for C@t{++}}.
+
+
+@node Help
+@section Getting help
+@cindex online documentation
+@kindex help
+
+You can always ask @value{GDBN} itself for information on its commands,
+using the command @code{help}.
+
+@table @code
+@kindex h @r{(@code{help})}
+@item help
+@itemx h
+You can use @code{help} (abbreviated @code{h}) with no arguments to
+display a short list of named classes of commands:
+
+@smallexample
+(@value{GDBP}) help
+List of classes of commands:
+
+aliases -- Aliases of other commands
+breakpoints -- Making program stop at certain points
+data -- Examining data
+files -- Specifying and examining files
+internals -- Maintenance commands
+obscure -- Obscure features
+running -- Running the program
+stack -- Examining the stack
+status -- Status inquiries
+support -- Support facilities
+tracepoints -- Tracing of program execution without@*
+ stopping the program
+user-defined -- User-defined commands
+
+Type "help" followed by a class name for a list of
+commands in that class.
+Type "help" followed by command name for full
+documentation.
+Command name abbreviations are allowed if unambiguous.
+(@value{GDBP})
+@end smallexample
+@c the above line break eliminates huge line overfull...
+
+@item help @var{class}
+Using one of the general help classes as an argument, you can get a
+list of the individual commands in that class. For example, here is the
+help display for the class @code{status}:
+
+@smallexample
+(@value{GDBP}) help status
+Status inquiries.
+
+List of commands:
+
+@c Line break in "show" line falsifies real output, but needed
+@c to fit in smallbook page size.
+info -- Generic command for showing things
+ about the program being debugged
+show -- Generic command for showing things
+ about the debugger
+
+Type "help" followed by command name for full
+documentation.
+Command name abbreviations are allowed if unambiguous.
+(@value{GDBP})
+@end smallexample
+
+@item help @var{command}
+With a command name as @code{help} argument, @value{GDBN} displays a
+short paragraph on how to use that command.
+
+@kindex apropos
+@item apropos @var{args}
+The @code{apropos @var{args}} command searches through all of the @value{GDBN}
+commands, and their documentation, for the regular expression specified in
+@var{args}. It prints out all matches found. For example:
+
+@smallexample
+apropos reload
+@end smallexample
+
+@noindent
+results in:
+
+@smallexample
+@c @group
+set symbol-reloading -- Set dynamic symbol table reloading
+ multiple times in one run
+show symbol-reloading -- Show dynamic symbol table reloading
+ multiple times in one run
+@c @end group
+@end smallexample
+
+@kindex complete
+@item complete @var{args}
+The @code{complete @var{args}} command lists all the possible completions
+for the beginning of a command. Use @var{args} to specify the beginning of the
+command you want completed. For example:
+
+@smallexample
+complete i
+@end smallexample
+
+@noindent results in:
+
+@smallexample
+@group
+if
+ignore
+info
+inspect
+@end group
+@end smallexample
+
+@noindent This is intended for use by @sc{gnu} Emacs.
+@end table
+
+In addition to @code{help}, you can use the @value{GDBN} commands @code{info}
+and @code{show} to inquire about the state of your program, or the state
+of @value{GDBN} itself. Each command supports many topics of inquiry; this
+manual introduces each of them in the appropriate context. The listings
+under @code{info} and under @code{show} in the Index point to
+all the sub-commands. @xref{Index}.
+
+@c @group
+@table @code
+@kindex info
+@kindex i @r{(@code{info})}
+@item info
+This command (abbreviated @code{i}) is for describing the state of your
+program. For example, you can list the arguments given to your program
+with @code{info args}, list the registers currently in use with @code{info
+registers}, or list the breakpoints you have set with @code{info breakpoints}.
+You can get a complete list of the @code{info} sub-commands with
+@w{@code{help info}}.
+
+@kindex set
+@item set
+You can assign the result of an expression to an environment variable with
+@code{set}. For example, you can set the @value{GDBN} prompt to a $-sign with
+@code{set prompt $}.
+
+@kindex show
+@item show
+In contrast to @code{info}, @code{show} is for describing the state of
+@value{GDBN} itself.
+You can change most of the things you can @code{show}, by using the
+related command @code{set}; for example, you can control what number
+system is used for displays with @code{set radix}, or simply inquire
+which is currently in use with @code{show radix}.
+
+@kindex info set
+To display all the settable parameters and their current
+values, you can use @code{show} with no arguments; you may also use
+@code{info set}. Both commands produce the same display.
+@c FIXME: "info set" violates the rule that "info" is for state of
+@c FIXME...program. Ck w/ GNU: "info set" to be called something else,
+@c FIXME...or change desc of rule---eg "state of prog and debugging session"?
+@end table
+@c @end group
+
+Here are three miscellaneous @code{show} subcommands, all of which are
+exceptional in lacking corresponding @code{set} commands:
+
+@table @code
+@kindex show version
+@cindex version number
+@item show version
+Show what version of @value{GDBN} is running. You should include this
+information in @value{GDBN} bug-reports. If multiple versions of
+@value{GDBN} are in use at your site, you may need to determine which
+version of @value{GDBN} you are running; as @value{GDBN} evolves, new
+commands are introduced, and old ones may wither away. Also, many
+system vendors ship variant versions of @value{GDBN}, and there are
+variant versions of @value{GDBN} in @sc{gnu}/Linux distributions as well.
+The version number is the same as the one announced when you start
+@value{GDBN}.
+
+@kindex show copying
+@item show copying
+Display information about permission for copying @value{GDBN}.
+
+@kindex show warranty
+@item show warranty
+Display the @sc{gnu} ``NO WARRANTY'' statement, or a warranty,
+if your version of @value{GDBN} comes with one.
+
+@end table
+
+@node Running
+@chapter Running Programs Under @value{GDBN}
+
+When you run a program under @value{GDBN}, you must first generate
+debugging information when you compile it.
+
+You may start @value{GDBN} with its arguments, if any, in an environment
+of your choice. If you are doing native debugging, you may redirect
+your program's input and output, debug an already running process, or
+kill a child process.
+
+@menu
+* Compilation:: Compiling for debugging
+* Starting:: Starting your program
+* Arguments:: Your program's arguments
+* Environment:: Your program's environment
+
+* Working Directory:: Your program's working directory
+* Input/Output:: Your program's input and output
+* Attach:: Debugging an already-running process
+* Kill Process:: Killing the child process
+
+* Threads:: Debugging programs with multiple threads
+* Processes:: Debugging programs with multiple processes
+@end menu
+
+@node Compilation
+@section Compiling for debugging
+
+In order to debug a program effectively, you need to generate
+debugging information when you compile it. This debugging information
+is stored in the object file; it describes the data type of each
+variable or function and the correspondence between source line numbers
+and addresses in the executable code.
+
+To request debugging information, specify the @samp{-g} option when you run
+the compiler.
+
+Most compilers do not include information about preprocessor macros in
+the debugging information if you specify the @option{-g} flag alone,
+because this information is rather large. Version 3.1 of @value{NGCC},
+the @sc{gnu} C compiler, provides macro information if you specify the
+options @option{-gdwarf-2} and @option{-g3}; the former option requests
+debugging information in the Dwarf 2 format, and the latter requests
+``extra information''. In the future, we hope to find more compact ways
+to represent macro information, so that it can be included with
+@option{-g} alone.
+
+Many C compilers are unable to handle the @samp{-g} and @samp{-O}
+options together. Using those compilers, you cannot generate optimized
+executables containing debugging information.
+
+@value{NGCC}, the @sc{gnu} C compiler, supports @samp{-g} with or
+without @samp{-O}, making it possible to debug optimized code. We
+recommend that you @emph{always} use @samp{-g} whenever you compile a
+program. You may think your program is correct, but there is no sense
+in pushing your luck.
+
+@cindex optimized code, debugging
+@cindex debugging optimized code
+When you debug a program compiled with @samp{-g -O}, remember that the
+optimizer is rearranging your code; the debugger shows you what is
+really there. Do not be too surprised when the execution path does not
+exactly match your source file! An extreme example: if you define a
+variable, but never use it, @value{GDBN} never sees that
+variable---because the compiler optimizes it out of existence.
+
+Some things do not work as well with @samp{-g -O} as with just
+@samp{-g}, particularly on machines with instruction scheduling. If in
+doubt, recompile with @samp{-g} alone, and if this fixes the problem,
+please report it to us as a bug (including a test case!).
+
+Older versions of the @sc{gnu} C compiler permitted a variant option
+@w{@samp{-gg}} for debugging information. @value{GDBN} no longer supports this
+format; if your @sc{gnu} C compiler has this option, do not use it.
+
+@need 2000
+@node Starting
+@section Starting your program
+@cindex starting
+@cindex running
+
+@table @code
+@kindex run
+@kindex r @r{(@code{run})}
+@item run
+@itemx r
+Use the @code{run} command to start your program under @value{GDBN}.
+You must first specify the program name (except on VxWorks) with an
+argument to @value{GDBN} (@pxref{Invocation, ,Getting In and Out of
+@value{GDBN}}), or by using the @code{file} or @code{exec-file} command
+(@pxref{Files, ,Commands to specify files}).
+
+@end table
+
+If you are running your program in an execution environment that
+supports processes, @code{run} creates an inferior process and makes
+that process run your program. (In environments without processes,
+@code{run} jumps to the start of your program.)
+
+The execution of a program is affected by certain information it
+receives from its superior. @value{GDBN} provides ways to specify this
+information, which you must do @emph{before} starting your program. (You
+can change it after starting your program, but such changes only affect
+your program the next time you start it.) This information may be
+divided into four categories:
+
+@table @asis
+@item The @emph{arguments.}
+Specify the arguments to give your program as the arguments of the
+@code{run} command. If a shell is available on your target, the shell
+is used to pass the arguments, so that you may use normal conventions
+(such as wildcard expansion or variable substitution) in describing
+the arguments.
+In Unix systems, you can control which shell is used with the
+@code{SHELL} environment variable.
+@xref{Arguments, ,Your program's arguments}.
+
+@item The @emph{environment.}
+Your program normally inherits its environment from @value{GDBN}, but you can
+use the @value{GDBN} commands @code{set environment} and @code{unset
+environment} to change parts of the environment that affect
+your program. @xref{Environment, ,Your program's environment}.
+
+@item The @emph{working directory.}
+Your program inherits its working directory from @value{GDBN}. You can set
+the @value{GDBN} working directory with the @code{cd} command in @value{GDBN}.
+@xref{Working Directory, ,Your program's working directory}.
+
+@item The @emph{standard input and output.}
+Your program normally uses the same device for standard input and
+standard output as @value{GDBN} is using. You can redirect input and output
+in the @code{run} command line, or you can use the @code{tty} command to
+set a different device for your program.
+@xref{Input/Output, ,Your program's input and output}.
+
+@cindex pipes
+@emph{Warning:} While input and output redirection work, you cannot use
+pipes to pass the output of the program you are debugging to another
+program; if you attempt this, @value{GDBN} is likely to wind up debugging the
+wrong program.
+@end table
+
+When you issue the @code{run} command, your program begins to execute
+immediately. @xref{Stopping, ,Stopping and continuing}, for discussion
+of how to arrange for your program to stop. Once your program has
+stopped, you may call functions in your program, using the @code{print}
+or @code{call} commands. @xref{Data, ,Examining Data}.
+
+If the modification time of your symbol file has changed since the last
+time @value{GDBN} read its symbols, @value{GDBN} discards its symbol
+table, and reads it again. When it does this, @value{GDBN} tries to retain
+your current breakpoints.
+
+@node Arguments
+@section Your program's arguments
+
+@cindex arguments (to your program)
+The arguments to your program can be specified by the arguments of the
+@code{run} command.
+They are passed to a shell, which expands wildcard characters and
+performs redirection of I/O, and thence to your program. Your
+@code{SHELL} environment variable (if it exists) specifies what shell
+@value{GDBN} uses. If you do not define @code{SHELL}, @value{GDBN} uses
+the default shell (@file{/bin/sh} on Unix).
+
+On non-Unix systems, the program is usually invoked directly by
+@value{GDBN}, which emulates I/O redirection via the appropriate system
+calls, and the wildcard characters are expanded by the startup code of
+the program, not by the shell.
+
+@code{run} with no arguments uses the same arguments used by the previous
+@code{run}, or those set by the @code{set args} command.
+
+@table @code
+@kindex set args
+@item set args
+Specify the arguments to be used the next time your program is run. If
+@code{set args} has no arguments, @code{run} executes your program
+with no arguments. Once you have run your program with arguments,
+using @code{set args} before the next @code{run} is the only way to run
+it again without arguments.
+
+@kindex show args
+@item show args
+Show the arguments to give your program when it is started.
+@end table
+
+@node Environment
+@section Your program's environment
+
+@cindex environment (of your program)
+The @dfn{environment} consists of a set of environment variables and
+their values. Environment variables conventionally record such things as
+your user name, your home directory, your terminal type, and your search
+path for programs to run. Usually you set up environment variables with
+the shell and they are inherited by all the other programs you run. When
+debugging, it can be useful to try running your program with a modified
+environment without having to start @value{GDBN} over again.
+
+@table @code
+@kindex path
+@item path @var{directory}
+Add @var{directory} to the front of the @code{PATH} environment variable
+(the search path for executables) that will be passed to your program.
+The value of @code{PATH} used by @value{GDBN} does not change.
+You may specify several directory names, separated by whitespace or by a
+system-dependent separator character (@samp{:} on Unix, @samp{;} on
+MS-DOS and MS-Windows). If @var{directory} is already in the path, it
+is moved to the front, so it is searched sooner.
+
+You can use the string @samp{$cwd} to refer to whatever is the current
+working directory at the time @value{GDBN} searches the path. If you
+use @samp{.} instead, it refers to the directory where you executed the
+@code{path} command. @value{GDBN} replaces @samp{.} in the
+@var{directory} argument (with the current path) before adding
+@var{directory} to the search path.
+@c 'path' is explicitly nonrepeatable, but RMS points out it is silly to
+@c document that, since repeating it would be a no-op.
+
+@kindex show paths
+@item show paths
+Display the list of search paths for executables (the @code{PATH}
+environment variable).
+
+@kindex show environment
+@item show environment @r{[}@var{varname}@r{]}
+Print the value of environment variable @var{varname} to be given to
+your program when it starts. If you do not supply @var{varname},
+print the names and values of all environment variables to be given to
+your program. You can abbreviate @code{environment} as @code{env}.
+
+@kindex set environment
+@item set environment @var{varname} @r{[}=@var{value}@r{]}
+Set environment variable @var{varname} to @var{value}. The value
+changes for your program only, not for @value{GDBN} itself. @var{value} may
+be any string; the values of environment variables are just strings, and
+any interpretation is supplied by your program itself. The @var{value}
+parameter is optional; if it is eliminated, the variable is set to a
+null value.
+@c "any string" here does not include leading, trailing
+@c blanks. Gnu asks: does anyone care?
+
+For example, this command:
+
+@smallexample
+set env USER = foo
+@end smallexample
+
+@noindent
+tells the debugged program, when subsequently run, that its user is named
+@samp{foo}. (The spaces around @samp{=} are used for clarity here; they
+are not actually required.)
+
+@kindex unset environment
+@item unset environment @var{varname}
+Remove variable @var{varname} from the environment to be passed to your
+program. This is different from @samp{set env @var{varname} =};
+@code{unset environment} removes the variable from the environment,
+rather than assigning it an empty value.
+@end table
+
+@emph{Warning:} On Unix systems, @value{GDBN} runs your program using
+the shell indicated
+by your @code{SHELL} environment variable if it exists (or
+@code{/bin/sh} if not). If your @code{SHELL} variable names a shell
+that runs an initialization file---such as @file{.cshrc} for C-shell, or
+@file{.bashrc} for BASH---any variables you set in that file affect
+your program. You may wish to move setting of environment variables to
+files that are only run when you sign on, such as @file{.login} or
+@file{.profile}.
+
+@node Working Directory
+@section Your program's working directory
+
+@cindex working directory (of your program)
+Each time you start your program with @code{run}, it inherits its
+working directory from the current working directory of @value{GDBN}.
+The @value{GDBN} working directory is initially whatever it inherited
+from its parent process (typically the shell), but you can specify a new
+working directory in @value{GDBN} with the @code{cd} command.
+
+The @value{GDBN} working directory also serves as a default for the commands
+that specify files for @value{GDBN} to operate on. @xref{Files, ,Commands to
+specify files}.
+
+@table @code
+@kindex cd
+@item cd @var{directory}
+Set the @value{GDBN} working directory to @var{directory}.
+
+@kindex pwd
+@item pwd
+Print the @value{GDBN} working directory.
+@end table
+
+@node Input/Output
+@section Your program's input and output
+
+@cindex redirection
+@cindex i/o
+@cindex terminal
+By default, the program you run under @value{GDBN} does input and output to
+the same terminal that @value{GDBN} uses. @value{GDBN} switches the terminal
+to its own terminal modes to interact with you, but it records the terminal
+modes your program was using and switches back to them when you continue
+running your program.
+
+@table @code
+@kindex info terminal
+@item info terminal
+Displays information recorded by @value{GDBN} about the terminal modes your
+program is using.
+@end table
+
+You can redirect your program's input and/or output using shell
+redirection with the @code{run} command. For example,
+
+@smallexample
+run > outfile
+@end smallexample
+
+@noindent
+starts your program, diverting its output to the file @file{outfile}.
+
+@kindex tty
+@cindex controlling terminal
+Another way to specify where your program should do input and output is
+with the @code{tty} command. This command accepts a file name as
+argument, and causes this file to be the default for future @code{run}
+commands. It also resets the controlling terminal for the child
+process, for future @code{run} commands. For example,
+
+@smallexample
+tty /dev/ttyb
+@end smallexample
+
+@noindent
+directs that processes started with subsequent @code{run} commands
+default to do input and output on the terminal @file{/dev/ttyb} and have
+that as their controlling terminal.
+
+An explicit redirection in @code{run} overrides the @code{tty} command's
+effect on the input/output device, but not its effect on the controlling
+terminal.
+
+When you use the @code{tty} command or redirect input in the @code{run}
+command, only the input @emph{for your program} is affected. The input
+for @value{GDBN} still comes from your terminal.
+
+@node Attach
+@section Debugging an already-running process
+@kindex attach
+@cindex attach
+
+@table @code
+@item attach @var{process-id}
+This command attaches to a running process---one that was started
+outside @value{GDBN}. (@code{info files} shows your active
+targets.) The command takes as argument a process ID. The usual way to
+find out the process-id of a Unix process is with the @code{ps} utility,
+or with the @samp{jobs -l} shell command.
+
+@code{attach} does not repeat if you press @key{RET} a second time after
+executing the command.
+@end table
+
+To use @code{attach}, your program must be running in an environment
+which supports processes; for example, @code{attach} does not work for
+programs on bare-board targets that lack an operating system. You must
+also have permission to send the process a signal.
+
+When you use @code{attach}, the debugger finds the program running in
+the process first by looking in the current working directory, then (if
+the program is not found) by using the source file search path
+(@pxref{Source Path, ,Specifying source directories}). You can also use
+the @code{file} command to load the program. @xref{Files, ,Commands to
+Specify Files}.
+
+The first thing @value{GDBN} does after arranging to debug the specified
+process is to stop it. You can examine and modify an attached process
+with all the @value{GDBN} commands that are ordinarily available when
+you start processes with @code{run}. You can insert breakpoints; you
+can step and continue; you can modify storage. If you would rather the
+process continue running, you may use the @code{continue} command after
+attaching @value{GDBN} to the process.
+
+@table @code
+@kindex detach
+@item detach
+When you have finished debugging the attached process, you can use the
+@code{detach} command to release it from @value{GDBN} control. Detaching
+the process continues its execution. After the @code{detach} command,
+that process and @value{GDBN} become completely independent once more, and you
+are ready to @code{attach} another process or start one with @code{run}.
+@code{detach} does not repeat if you press @key{RET} again after
+executing the command.
+@end table
+
+If you exit @value{GDBN} or use the @code{run} command while you have an
+attached process, you kill that process. By default, @value{GDBN} asks
+for confirmation if you try to do either of these things; you can
+control whether or not you need to confirm by using the @code{set
+confirm} command (@pxref{Messages/Warnings, ,Optional warnings and
+messages}).
+
+@node Kill Process
+@section Killing the child process
+
+@table @code
+@kindex kill
+@item kill
+Kill the child process in which your program is running under @value{GDBN}.
+@end table
+
+This command is useful if you wish to debug a core dump instead of a
+running process. @value{GDBN} ignores any core dump file while your program
+is running.
+
+On some operating systems, a program cannot be executed outside @value{GDBN}
+while you have breakpoints set on it inside @value{GDBN}. You can use the
+@code{kill} command in this situation to permit running your program
+outside the debugger.
+
+The @code{kill} command is also useful if you wish to recompile and
+relink your program, since on many systems it is impossible to modify an
+executable file while it is running in a process. In this case, when you
+next type @code{run}, @value{GDBN} notices that the file has changed, and
+reads the symbol table again (while trying to preserve your current
+breakpoint settings).
+
+@node Threads
+@section Debugging programs with multiple threads
+
+@cindex threads of execution
+@cindex multiple threads
+@cindex switching threads
+In some operating systems, such as HP-UX and Solaris, a single program
+may have more than one @dfn{thread} of execution. The precise semantics
+of threads differ from one operating system to another, but in general
+the threads of a single program are akin to multiple processes---except
+that they share one address space (that is, they can all examine and
+modify the same variables). On the other hand, each thread has its own
+registers and execution stack, and perhaps private memory.
+
+@value{GDBN} provides these facilities for debugging multi-thread
+programs:
+
+@itemize @bullet
+@item automatic notification of new threads
+@item @samp{thread @var{threadno}}, a command to switch among threads
+@item @samp{info threads}, a command to inquire about existing threads
+@item @samp{thread apply [@var{threadno}] [@var{all}] @var{args}},
+a command to apply a command to a list of threads
+@item thread-specific breakpoints
+@end itemize
+
+@quotation
+@emph{Warning:} These facilities are not yet available on every
+@value{GDBN} configuration where the operating system supports threads.
+If your @value{GDBN} does not support threads, these commands have no
+effect. For example, a system without thread support shows no output
+from @samp{info threads}, and always rejects the @code{thread} command,
+like this:
+
+@smallexample
+(@value{GDBP}) info threads
+(@value{GDBP}) thread 1
+Thread ID 1 not known. Use the "info threads" command to
+see the IDs of currently known threads.
+@end smallexample
+@c FIXME to implementors: how hard would it be to say "sorry, this GDB
+@c doesn't support threads"?
+@end quotation
+
+@cindex focus of debugging
+@cindex current thread
+The @value{GDBN} thread debugging facility allows you to observe all
+threads while your program runs---but whenever @value{GDBN} takes
+control, one thread in particular is always the focus of debugging.
+This thread is called the @dfn{current thread}. Debugging commands show
+program information from the perspective of the current thread.
+
+@cindex @code{New} @var{systag} message
+@cindex thread identifier (system)
+@c FIXME-implementors!! It would be more helpful if the [New...] message
+@c included GDB's numeric thread handle, so you could just go to that
+@c thread without first checking `info threads'.
+Whenever @value{GDBN} detects a new thread in your program, it displays
+the target system's identification for the thread with a message in the
+form @samp{[New @var{systag}]}. @var{systag} is a thread identifier
+whose form varies depending on the particular system. For example, on
+LynxOS, you might see
+
+@smallexample
+[New process 35 thread 27]
+@end smallexample
+
+@noindent
+when @value{GDBN} notices a new thread. In contrast, on an SGI system,
+the @var{systag} is simply something like @samp{process 368}, with no
+further qualifier.
+
+@c FIXME!! (1) Does the [New...] message appear even for the very first
+@c thread of a program, or does it only appear for the
+@c second---i.e.@: when it becomes obvious we have a multithread
+@c program?
+@c (2) *Is* there necessarily a first thread always? Or do some
+@c multithread systems permit starting a program with multiple
+@c threads ab initio?
+
+@cindex thread number
+@cindex thread identifier (GDB)
+For debugging purposes, @value{GDBN} associates its own thread
+number---always a single integer---with each thread in your program.
+
+@table @code
+@kindex info threads
+@item info threads
+Display a summary of all threads currently in your
+program. @value{GDBN} displays for each thread (in this order):
+
+@enumerate
+@item the thread number assigned by @value{GDBN}
+
+@item the target system's thread identifier (@var{systag})
+
+@item the current stack frame summary for that thread
+@end enumerate
+
+@noindent
+An asterisk @samp{*} to the left of the @value{GDBN} thread number
+indicates the current thread.
+
+For example,
+@end table
+@c end table here to get a little more width for example
+
+@smallexample
+(@value{GDBP}) info threads
+ 3 process 35 thread 27 0x34e5 in sigpause ()
+ 2 process 35 thread 23 0x34e5 in sigpause ()
+* 1 process 35 thread 13 main (argc=1, argv=0x7ffffff8)
+ at threadtest.c:68
+@end smallexample
+
+On HP-UX systems:
+
+@cindex thread number
+@cindex thread identifier (GDB)
+For debugging purposes, @value{GDBN} associates its own thread
+number---a small integer assigned in thread-creation order---with each
+thread in your program.
+
+@cindex @code{New} @var{systag} message, on HP-UX
+@cindex thread identifier (system), on HP-UX
+@c FIXME-implementors!! It would be more helpful if the [New...] message
+@c included GDB's numeric thread handle, so you could just go to that
+@c thread without first checking `info threads'.
+Whenever @value{GDBN} detects a new thread in your program, it displays
+both @value{GDBN}'s thread number and the target system's identification for the thread with a message in the
+form @samp{[New @var{systag}]}. @var{systag} is a thread identifier
+whose form varies depending on the particular system. For example, on
+HP-UX, you see
+
+@smallexample
+[New thread 2 (system thread 26594)]
+@end smallexample
+
+@noindent
+when @value{GDBN} notices a new thread.
+
+@table @code
+@kindex info threads
+@item info threads
+Display a summary of all threads currently in your
+program. @value{GDBN} displays for each thread (in this order):
+
+@enumerate
+@item the thread number assigned by @value{GDBN}
+
+@item the target system's thread identifier (@var{systag})
+
+@item the current stack frame summary for that thread
+@end enumerate
+
+@noindent
+An asterisk @samp{*} to the left of the @value{GDBN} thread number
+indicates the current thread.
+
+For example,
+@end table
+@c end table here to get a little more width for example
+
+@smallexample
+(@value{GDBP}) info threads
+ * 3 system thread 26607 worker (wptr=0x7b09c318 "@@") \@*
+ at quicksort.c:137
+ 2 system thread 26606 0x7b0030d8 in __ksleep () \@*
+ from /usr/lib/libc.2
+ 1 system thread 27905 0x7b003498 in _brk () \@*
+ from /usr/lib/libc.2
+@end smallexample
+
+@table @code
+@kindex thread @var{threadno}
+@item thread @var{threadno}
+Make thread number @var{threadno} the current thread. The command
+argument @var{threadno} is the internal @value{GDBN} thread number, as
+shown in the first field of the @samp{info threads} display.
+@value{GDBN} responds by displaying the system identifier of the thread
+you selected, and its current stack frame summary:
+
+@smallexample
+@c FIXME!! This example made up; find a @value{GDBN} w/threads and get real one
+(@value{GDBP}) thread 2
+[Switching to process 35 thread 23]
+0x34e5 in sigpause ()
+@end smallexample
+
+@noindent
+As with the @samp{[New @dots{}]} message, the form of the text after
+@samp{Switching to} depends on your system's conventions for identifying
+threads.
+
+@kindex thread apply
+@item thread apply [@var{threadno}] [@var{all}] @var{args}
+The @code{thread apply} command allows you to apply a command to one or
+more threads. Specify the numbers of the threads that you want affected
+with the command argument @var{threadno}. @var{threadno} is the internal
+@value{GDBN} thread number, as shown in the first field of the @samp{info
+threads} display. To apply a command to all threads, use
+@code{thread apply all} @var{args}.
+@end table
+
+@cindex automatic thread selection
+@cindex switching threads automatically
+@cindex threads, automatic switching
+Whenever @value{GDBN} stops your program, due to a breakpoint or a
+signal, it automatically selects the thread where that breakpoint or
+signal happened. @value{GDBN} alerts you to the context switch with a
+message of the form @samp{[Switching to @var{systag}]} to identify the
+thread.
+
+@xref{Thread Stops,,Stopping and starting multi-thread programs}, for
+more information about how @value{GDBN} behaves when you stop and start
+programs with multiple threads.
+
+@xref{Set Watchpoints,,Setting watchpoints}, for information about
+watchpoints in programs with multiple threads.
+
+@node Processes
+@section Debugging programs with multiple processes
+
+@cindex fork, debugging programs which call
+@cindex multiple processes
+@cindex processes, multiple
+On most systems, @value{GDBN} has no special support for debugging
+programs which create additional processes using the @code{fork}
+function. When a program forks, @value{GDBN} will continue to debug the
+parent process and the child process will run unimpeded. If you have
+set a breakpoint in any code which the child then executes, the child
+will get a @code{SIGTRAP} signal which (unless it catches the signal)
+will cause it to terminate.
+
+However, if you want to debug the child process there is a workaround
+which isn't too painful. Put a call to @code{sleep} in the code which
+the child process executes after the fork. It may be useful to sleep
+only if a certain environment variable is set, or a certain file exists,
+so that the delay need not occur when you don't want to run @value{GDBN}
+on the child. While the child is sleeping, use the @code{ps} program to
+get its process ID. Then tell @value{GDBN} (a new invocation of
+@value{GDBN} if you are also debugging the parent process) to attach to
+the child process (@pxref{Attach}). From that point on you can debug
+the child process just like any other process which you attached to.
+
+On HP-UX (11.x and later only?), @value{GDBN} provides support for
+debugging programs that create additional processes using the
+@code{fork} or @code{vfork} function.
+
+By default, when a program forks, @value{GDBN} will continue to debug
+the parent process and the child process will run unimpeded.
+
+If you want to follow the child process instead of the parent process,
+use the command @w{@code{set follow-fork-mode}}.
+
+@table @code
+@kindex set follow-fork-mode
+@item set follow-fork-mode @var{mode}
+Set the debugger response to a program call of @code{fork} or
+@code{vfork}. A call to @code{fork} or @code{vfork} creates a new
+process. The @var{mode} can be:
+
+@table @code
+@item parent
+The original process is debugged after a fork. The child process runs
+unimpeded. This is the default.
+
+@item child
+The new process is debugged after a fork. The parent process runs
+unimpeded.
+
+@item ask
+The debugger will ask for one of the above choices.
+@end table
+
+@item show follow-fork-mode
+Display the current debugger response to a @code{fork} or @code{vfork} call.
+@end table
+
+If you ask to debug a child process and a @code{vfork} is followed by an
+@code{exec}, @value{GDBN} executes the new target up to the first
+breakpoint in the new target. If you have a breakpoint set on
+@code{main} in your original program, the breakpoint will also be set on
+the child process's @code{main}.
+
+When a child process is spawned by @code{vfork}, you cannot debug the
+child or parent until an @code{exec} call completes.
+
+If you issue a @code{run} command to @value{GDBN} after an @code{exec}
+call executes, the new target restarts. To restart the parent process,
+use the @code{file} command with the parent executable name as its
+argument.
+
+You can use the @code{catch} command to make @value{GDBN} stop whenever
+a @code{fork}, @code{vfork}, or @code{exec} call is made. @xref{Set
+Catchpoints, ,Setting catchpoints}.
+
+@node Stopping
+@chapter Stopping and Continuing
+
+The principal purposes of using a debugger are so that you can stop your
+program before it terminates; or so that, if your program runs into
+trouble, you can investigate and find out why.
+
+Inside @value{GDBN}, your program may stop for any of several reasons,
+such as a signal, a breakpoint, or reaching a new line after a
+@value{GDBN} command such as @code{step}. You may then examine and
+change variables, set new breakpoints or remove old ones, and then
+continue execution. Usually, the messages shown by @value{GDBN} provide
+ample explanation of the status of your program---but you can also
+explicitly request this information at any time.
+
+@table @code
+@kindex info program
+@item info program
+Display information about the status of your program: whether it is
+running or not, what process it is, and why it stopped.
+@end table
+
+@menu
+* Breakpoints:: Breakpoints, watchpoints, and catchpoints
+* Continuing and Stepping:: Resuming execution
+* Signals:: Signals
+* Thread Stops:: Stopping and starting multi-thread programs
+@end menu
+
+@node Breakpoints
+@section Breakpoints, watchpoints, and catchpoints
+
+@cindex breakpoints
+A @dfn{breakpoint} makes your program stop whenever a certain point in
+the program is reached. For each breakpoint, you can add conditions to
+control in finer detail whether your program stops. You can set
+breakpoints with the @code{break} command and its variants (@pxref{Set
+Breaks, ,Setting breakpoints}), to specify the place where your program
+should stop by line number, function name or exact address in the
+program.
+
+In HP-UX, SunOS 4.x, SVR4, and Alpha OSF/1 configurations, you can set
+breakpoints in shared libraries before the executable is run. There is
+a minor limitation on HP-UX systems: you must wait until the executable
+is run in order to set breakpoints in shared library routines that are
+not called directly by the program (for example, routines that are
+arguments in a @code{pthread_create} call).
+
+@cindex watchpoints
+@cindex memory tracing
+@cindex breakpoint on memory address
+@cindex breakpoint on variable modification
+A @dfn{watchpoint} is a special breakpoint that stops your program
+when the value of an expression changes. You must use a different
+command to set watchpoints (@pxref{Set Watchpoints, ,Setting
+watchpoints}), but aside from that, you can manage a watchpoint like
+any other breakpoint: you enable, disable, and delete both breakpoints
+and watchpoints using the same commands.
+
+You can arrange to have values from your program displayed automatically
+whenever @value{GDBN} stops at a breakpoint. @xref{Auto Display,,
+Automatic display}.
+
+@cindex catchpoints
+@cindex breakpoint on events
+A @dfn{catchpoint} is another special breakpoint that stops your program
+when a certain kind of event occurs, such as the throwing of a C@t{++}
+exception or the loading of a library. As with watchpoints, you use a
+different command to set a catchpoint (@pxref{Set Catchpoints, ,Setting
+catchpoints}), but aside from that, you can manage a catchpoint like any
+other breakpoint. (To stop when your program receives a signal, use the
+@code{handle} command; see @ref{Signals, ,Signals}.)
+
+@cindex breakpoint numbers
+@cindex numbers for breakpoints
+@value{GDBN} assigns a number to each breakpoint, watchpoint, or
+catchpoint when you create it; these numbers are successive integers
+starting with one. In many of the commands for controlling various
+features of breakpoints you use the breakpoint number to say which
+breakpoint you want to change. Each breakpoint may be @dfn{enabled} or
+@dfn{disabled}; if disabled, it has no effect on your program until you
+enable it again.
+
+@cindex breakpoint ranges
+@cindex ranges of breakpoints
+Some @value{GDBN} commands accept a range of breakpoints on which to
+operate. A breakpoint range is either a single breakpoint number, like
+@samp{5}, or two such numbers, in increasing order, separated by a
+hyphen, like @samp{5-7}. When a breakpoint range is given to a command,
+all breakpoint in that range are operated on.
+
+@menu
+* Set Breaks:: Setting breakpoints
+* Set Watchpoints:: Setting watchpoints
+* Set Catchpoints:: Setting catchpoints
+* Delete Breaks:: Deleting breakpoints
+* Disabling:: Disabling breakpoints
+* Conditions:: Break conditions
+* Break Commands:: Breakpoint command lists
+* Breakpoint Menus:: Breakpoint menus
+* Error in Breakpoints:: ``Cannot insert breakpoints''
+@end menu
+
+@node Set Breaks
+@subsection Setting breakpoints
+
+@c FIXME LMB what does GDB do if no code on line of breakpt?
+@c consider in particular declaration with/without initialization.
+@c
+@c FIXME 2 is there stuff on this already? break at fun start, already init?
+
+@kindex break
+@kindex b @r{(@code{break})}
+@vindex $bpnum@r{, convenience variable}
+@cindex latest breakpoint
+Breakpoints are set with the @code{break} command (abbreviated
+@code{b}). The debugger convenience variable @samp{$bpnum} records the
+number of the breakpoint you've set most recently; see @ref{Convenience
+Vars,, Convenience variables}, for a discussion of what you can do with
+convenience variables.
+
+You have several ways to say where the breakpoint should go.
+
+@table @code
+@item break @var{function}
+Set a breakpoint at entry to function @var{function}.
+When using source languages that permit overloading of symbols, such as
+C@t{++}, @var{function} may refer to more than one possible place to break.
+@xref{Breakpoint Menus,,Breakpoint menus}, for a discussion of that situation.
+
+@item break +@var{offset}
+@itemx break -@var{offset}
+Set a breakpoint some number of lines forward or back from the position
+at which execution stopped in the currently selected @dfn{stack frame}.
+(@xref{Frames, ,Frames}, for a description of stack frames.)
+
+@item break @var{linenum}
+Set a breakpoint at line @var{linenum} in the current source file.
+The current source file is the last file whose source text was printed.
+The breakpoint will stop your program just before it executes any of the
+code on that line.
+
+@item break @var{filename}:@var{linenum}
+Set a breakpoint at line @var{linenum} in source file @var{filename}.
+
+@item break @var{filename}:@var{function}
+Set a breakpoint at entry to function @var{function} found in file
+@var{filename}. Specifying a file name as well as a function name is
+superfluous except when multiple files contain similarly named
+functions.
+
+@item break *@var{address}
+Set a breakpoint at address @var{address}. You can use this to set
+breakpoints in parts of your program which do not have debugging
+information or source files.
+
+@item break
+When called without any arguments, @code{break} sets a breakpoint at
+the next instruction to be executed in the selected stack frame
+(@pxref{Stack, ,Examining the Stack}). In any selected frame but the
+innermost, this makes your program stop as soon as control
+returns to that frame. This is similar to the effect of a
+@code{finish} command in the frame inside the selected frame---except
+that @code{finish} does not leave an active breakpoint. If you use
+@code{break} without an argument in the innermost frame, @value{GDBN} stops
+the next time it reaches the current location; this may be useful
+inside loops.
+
+@value{GDBN} normally ignores breakpoints when it resumes execution, until at
+least one instruction has been executed. If it did not do this, you
+would be unable to proceed past a breakpoint without first disabling the
+breakpoint. This rule applies whether or not the breakpoint already
+existed when your program stopped.
+
+@item break @dots{} if @var{cond}
+Set a breakpoint with condition @var{cond}; evaluate the expression
+@var{cond} each time the breakpoint is reached, and stop only if the
+value is nonzero---that is, if @var{cond} evaluates as true.
+@samp{@dots{}} stands for one of the possible arguments described
+above (or no argument) specifying where to break. @xref{Conditions,
+,Break conditions}, for more information on breakpoint conditions.
+
+@kindex tbreak
+@item tbreak @var{args}
+Set a breakpoint enabled only for one stop. @var{args} are the
+same as for the @code{break} command, and the breakpoint is set in the same
+way, but the breakpoint is automatically deleted after the first time your
+program stops there. @xref{Disabling, ,Disabling breakpoints}.
+
+@kindex hbreak
+@item hbreak @var{args}
+Set a hardware-assisted breakpoint. @var{args} are the same as for the
+@code{break} command and the breakpoint is set in the same way, but the
+breakpoint requires hardware support and some target hardware may not
+have this support. The main purpose of this is EPROM/ROM code
+debugging, so you can set a breakpoint at an instruction without
+changing the instruction. This can be used with the new trap-generation
+provided by SPARClite DSU and some x86-based targets. These targets
+will generate traps when a program accesses some data or instruction
+address that is assigned to the debug registers. However the hardware
+breakpoint registers can take a limited number of breakpoints. For
+example, on the DSU, only two data breakpoints can be set at a time, and
+@value{GDBN} will reject this command if more than two are used. Delete
+or disable unused hardware breakpoints before setting new ones
+(@pxref{Disabling, ,Disabling}). @xref{Conditions, ,Break conditions}.
+
+@kindex thbreak
+@item thbreak @var{args}
+Set a hardware-assisted breakpoint enabled only for one stop. @var{args}
+are the same as for the @code{hbreak} command and the breakpoint is set in
+the same way. However, like the @code{tbreak} command,
+the breakpoint is automatically deleted after the
+first time your program stops there. Also, like the @code{hbreak}
+command, the breakpoint requires hardware support and some target hardware
+may not have this support. @xref{Disabling, ,Disabling breakpoints}.
+See also @ref{Conditions, ,Break conditions}.
+
+@kindex rbreak
+@cindex regular expression
+@item rbreak @var{regex}
+Set breakpoints on all functions matching the regular expression
+@var{regex}. This command sets an unconditional breakpoint on all
+matches, printing a list of all breakpoints it set. Once these
+breakpoints are set, they are treated just like the breakpoints set with
+the @code{break} command. You can delete them, disable them, or make
+them conditional the same way as any other breakpoint.
+
+The syntax of the regular expression is the standard one used with tools
+like @file{grep}. Note that this is different from the syntax used by
+shells, so for instance @code{foo*} matches all functions that include
+an @code{fo} followed by zero or more @code{o}s. There is an implicit
+@code{.*} leading and trailing the regular expression you supply, so to
+match only functions that begin with @code{foo}, use @code{^foo}.
+
+When debugging C@t{++} programs, @code{rbreak} is useful for setting
+breakpoints on overloaded functions that are not members of any special
+classes.
+
+@kindex info breakpoints
+@cindex @code{$_} and @code{info breakpoints}
+@item info breakpoints @r{[}@var{n}@r{]}
+@itemx info break @r{[}@var{n}@r{]}
+@itemx info watchpoints @r{[}@var{n}@r{]}
+Print a table of all breakpoints, watchpoints, and catchpoints set and
+not deleted, with the following columns for each breakpoint:
+
+@table @emph
+@item Breakpoint Numbers
+@item Type
+Breakpoint, watchpoint, or catchpoint.
+@item Disposition
+Whether the breakpoint is marked to be disabled or deleted when hit.
+@item Enabled or Disabled
+Enabled breakpoints are marked with @samp{y}. @samp{n} marks breakpoints
+that are not enabled.
+@item Address
+Where the breakpoint is in your program, as a memory address.
+@item What
+Where the breakpoint is in the source for your program, as a file and
+line number.
+@end table
+
+@noindent
+If a breakpoint is conditional, @code{info break} shows the condition on
+the line following the affected breakpoint; breakpoint commands, if any,
+are listed after that.
+
+@noindent
+@code{info break} with a breakpoint
+number @var{n} as argument lists only that breakpoint. The
+convenience variable @code{$_} and the default examining-address for
+the @code{x} command are set to the address of the last breakpoint
+listed (@pxref{Memory, ,Examining memory}).
+
+@noindent
+@code{info break} displays a count of the number of times the breakpoint
+has been hit. This is especially useful in conjunction with the
+@code{ignore} command. You can ignore a large number of breakpoint
+hits, look at the breakpoint info to see how many times the breakpoint
+was hit, and then run again, ignoring one less than that number. This
+will get you quickly to the last hit of that breakpoint.
+@end table
+
+@value{GDBN} allows you to set any number of breakpoints at the same place in
+your program. There is nothing silly or meaningless about this. When
+the breakpoints are conditional, this is even useful
+(@pxref{Conditions, ,Break conditions}).
+
+@cindex negative breakpoint numbers
+@cindex internal @value{GDBN} breakpoints
+@value{GDBN} itself sometimes sets breakpoints in your program for
+special purposes, such as proper handling of @code{longjmp} (in C
+programs). These internal breakpoints are assigned negative numbers,
+starting with @code{-1}; @samp{info breakpoints} does not display them.
+You can see these breakpoints with the @value{GDBN} maintenance command
+@samp{maint info breakpoints} (@pxref{maint info breakpoints}).
+
+
+@node Set Watchpoints
+@subsection Setting watchpoints
+
+@cindex setting watchpoints
+@cindex software watchpoints
+@cindex hardware watchpoints
+You can use a watchpoint to stop execution whenever the value of an
+expression changes, without having to predict a particular place where
+this may happen.
+
+Depending on your system, watchpoints may be implemented in software or
+hardware. @value{GDBN} does software watchpointing by single-stepping your
+program and testing the variable's value each time, which is hundreds of
+times slower than normal execution. (But this may still be worth it, to
+catch errors where you have no clue what part of your program is the
+culprit.)
+
+On some systems, such as HP-UX, Linux and some other x86-based targets,
+@value{GDBN} includes support for
+hardware watchpoints, which do not slow down the running of your
+program.
+
+@table @code
+@kindex watch
+@item watch @var{expr}
+Set a watchpoint for an expression. @value{GDBN} will break when @var{expr}
+is written into by the program and its value changes.
+
+@kindex rwatch
+@item rwatch @var{expr}
+Set a watchpoint that will break when watch @var{expr} is read by the program.
+
+@kindex awatch
+@item awatch @var{expr}
+Set a watchpoint that will break when @var{expr} is either read or written into
+by the program.
+
+@kindex info watchpoints
+@item info watchpoints
+This command prints a list of watchpoints, breakpoints, and catchpoints;
+it is the same as @code{info break}.
+@end table
+
+@value{GDBN} sets a @dfn{hardware watchpoint} if possible. Hardware
+watchpoints execute very quickly, and the debugger reports a change in
+value at the exact instruction where the change occurs. If @value{GDBN}
+cannot set a hardware watchpoint, it sets a software watchpoint, which
+executes more slowly and reports the change in value at the next
+statement, not the instruction, after the change occurs.
+
+When you issue the @code{watch} command, @value{GDBN} reports
+
+@smallexample
+Hardware watchpoint @var{num}: @var{expr}
+@end smallexample
+
+@noindent
+if it was able to set a hardware watchpoint.
+
+Currently, the @code{awatch} and @code{rwatch} commands can only set
+hardware watchpoints, because accesses to data that don't change the
+value of the watched expression cannot be detected without examining
+every instruction as it is being executed, and @value{GDBN} does not do
+that currently. If @value{GDBN} finds that it is unable to set a
+hardware breakpoint with the @code{awatch} or @code{rwatch} command, it
+will print a message like this:
+
+@smallexample
+Expression cannot be implemented with read/access watchpoint.
+@end smallexample
+
+Sometimes, @value{GDBN} cannot set a hardware watchpoint because the
+data type of the watched expression is wider than what a hardware
+watchpoint on the target machine can handle. For example, some systems
+can only watch regions that are up to 4 bytes wide; on such systems you
+cannot set hardware watchpoints for an expression that yields a
+double-precision floating-point number (which is typically 8 bytes
+wide). As a work-around, it might be possible to break the large region
+into a series of smaller ones and watch them with separate watchpoints.
+
+If you set too many hardware watchpoints, @value{GDBN} might be unable
+to insert all of them when you resume the execution of your program.
+Since the precise number of active watchpoints is unknown until such
+time as the program is about to be resumed, @value{GDBN} might not be
+able to warn you about this when you set the watchpoints, and the
+warning will be printed only when the program is resumed:
+
+@smallexample
+Hardware watchpoint @var{num}: Could not insert watchpoint
+@end smallexample
+
+@noindent
+If this happens, delete or disable some of the watchpoints.
+
+The SPARClite DSU will generate traps when a program accesses some data
+or instruction address that is assigned to the debug registers. For the
+data addresses, DSU facilitates the @code{watch} command. However the
+hardware breakpoint registers can only take two data watchpoints, and
+both watchpoints must be the same kind. For example, you can set two
+watchpoints with @code{watch} commands, two with @code{rwatch} commands,
+@strong{or} two with @code{awatch} commands, but you cannot set one
+watchpoint with one command and the other with a different command.
+@value{GDBN} will reject the command if you try to mix watchpoints.
+Delete or disable unused watchpoint commands before setting new ones.
+
+If you call a function interactively using @code{print} or @code{call},
+any watchpoints you have set will be inactive until @value{GDBN} reaches another
+kind of breakpoint or the call completes.
+
+@value{GDBN} automatically deletes watchpoints that watch local
+(automatic) variables, or expressions that involve such variables, when
+they go out of scope, that is, when the execution leaves the block in
+which these variables were defined. In particular, when the program
+being debugged terminates, @emph{all} local variables go out of scope,
+and so only watchpoints that watch global variables remain set. If you
+rerun the program, you will need to set all such watchpoints again. One
+way of doing that would be to set a code breakpoint at the entry to the
+@code{main} function and when it breaks, set all the watchpoints.
+
+@quotation
+@cindex watchpoints and threads
+@cindex threads and watchpoints
+@emph{Warning:} In multi-thread programs, watchpoints have only limited
+usefulness. With the current watchpoint implementation, @value{GDBN}
+can only watch the value of an expression @emph{in a single thread}. If
+you are confident that the expression can only change due to the current
+thread's activity (and if you are also confident that no other thread
+can become current), then you can use watchpoints as usual. However,
+@value{GDBN} may not notice when a non-current thread's activity changes
+the expression.
+
+@c FIXME: this is almost identical to the previous paragraph.
+@emph{HP-UX Warning:} In multi-thread programs, software watchpoints
+have only limited usefulness. If @value{GDBN} creates a software
+watchpoint, it can only watch the value of an expression @emph{in a
+single thread}. If you are confident that the expression can only
+change due to the current thread's activity (and if you are also
+confident that no other thread can become current), then you can use
+software watchpoints as usual. However, @value{GDBN} may not notice
+when a non-current thread's activity changes the expression. (Hardware
+watchpoints, in contrast, watch an expression in all threads.)
+@end quotation
+
+@node Set Catchpoints
+@subsection Setting catchpoints
+@cindex catchpoints, setting
+@cindex exception handlers
+@cindex event handling
+
+You can use @dfn{catchpoints} to cause the debugger to stop for certain
+kinds of program events, such as C@t{++} exceptions or the loading of a
+shared library. Use the @code{catch} command to set a catchpoint.
+
+@table @code
+@kindex catch
+@item catch @var{event}
+Stop when @var{event} occurs. @var{event} can be any of the following:
+@table @code
+@item throw
+@kindex catch throw
+The throwing of a C@t{++} exception.
+
+@item catch
+@kindex catch catch
+The catching of a C@t{++} exception.
+
+@item exec
+@kindex catch exec
+A call to @code{exec}. This is currently only available for HP-UX.
+
+@item fork
+@kindex catch fork
+A call to @code{fork}. This is currently only available for HP-UX.
+
+@item vfork
+@kindex catch vfork
+A call to @code{vfork}. This is currently only available for HP-UX.
+
+@item load
+@itemx load @var{libname}
+@kindex catch load
+The dynamic loading of any shared library, or the loading of the library
+@var{libname}. This is currently only available for HP-UX.
+
+@item unload
+@itemx unload @var{libname}
+@kindex catch unload
+The unloading of any dynamically loaded shared library, or the unloading
+of the library @var{libname}. This is currently only available for HP-UX.
+@end table
+
+@item tcatch @var{event}
+Set a catchpoint that is enabled only for one stop. The catchpoint is
+automatically deleted after the first time the event is caught.
+
+@end table
+
+Use the @code{info break} command to list the current catchpoints.
+
+There are currently some limitations to C@t{++} exception handling
+(@code{catch throw} and @code{catch catch}) in @value{GDBN}:
+
+@itemize @bullet
+@item
+If you call a function interactively, @value{GDBN} normally returns
+control to you when the function has finished executing. If the call
+raises an exception, however, the call may bypass the mechanism that
+returns control to you and cause your program either to abort or to
+simply continue running until it hits a breakpoint, catches a signal
+that @value{GDBN} is listening for, or exits. This is the case even if
+you set a catchpoint for the exception; catchpoints on exceptions are
+disabled within interactive calls.
+
+@item
+You cannot raise an exception interactively.
+
+@item
+You cannot install an exception handler interactively.
+@end itemize
+
+@cindex raise exceptions
+Sometimes @code{catch} is not the best way to debug exception handling:
+if you need to know exactly where an exception is raised, it is better to
+stop @emph{before} the exception handler is called, since that way you
+can see the stack before any unwinding takes place. If you set a
+breakpoint in an exception handler instead, it may not be easy to find
+out where the exception was raised.
+
+To stop just before an exception handler is called, you need some
+knowledge of the implementation. In the case of @sc{gnu} C@t{++}, exceptions are
+raised by calling a library function named @code{__raise_exception}
+which has the following ANSI C interface:
+
+@smallexample
+ /* @var{addr} is where the exception identifier is stored.
+ @var{id} is the exception identifier. */
+ void __raise_exception (void **addr, void *id);
+@end smallexample
+
+@noindent
+To make the debugger catch all exceptions before any stack
+unwinding takes place, set a breakpoint on @code{__raise_exception}
+(@pxref{Breakpoints, ,Breakpoints; watchpoints; and exceptions}).
+
+With a conditional breakpoint (@pxref{Conditions, ,Break conditions})
+that depends on the value of @var{id}, you can stop your program when
+a specific exception is raised. You can use multiple conditional
+breakpoints to stop your program when any of a number of exceptions are
+raised.
+
+
+@node Delete Breaks
+@subsection Deleting breakpoints
+
+@cindex clearing breakpoints, watchpoints, catchpoints
+@cindex deleting breakpoints, watchpoints, catchpoints
+It is often necessary to eliminate a breakpoint, watchpoint, or
+catchpoint once it has done its job and you no longer want your program
+to stop there. This is called @dfn{deleting} the breakpoint. A
+breakpoint that has been deleted no longer exists; it is forgotten.
+
+With the @code{clear} command you can delete breakpoints according to
+where they are in your program. With the @code{delete} command you can
+delete individual breakpoints, watchpoints, or catchpoints by specifying
+their breakpoint numbers.
+
+It is not necessary to delete a breakpoint to proceed past it. @value{GDBN}
+automatically ignores breakpoints on the first instruction to be executed
+when you continue execution without changing the execution address.
+
+@table @code
+@kindex clear
+@item clear
+Delete any breakpoints at the next instruction to be executed in the
+selected stack frame (@pxref{Selection, ,Selecting a frame}). When
+the innermost frame is selected, this is a good way to delete a
+breakpoint where your program just stopped.
+
+@item clear @var{function}
+@itemx clear @var{filename}:@var{function}
+Delete any breakpoints set at entry to the function @var{function}.
+
+@item clear @var{linenum}
+@itemx clear @var{filename}:@var{linenum}
+Delete any breakpoints set at or within the code of the specified line.
+
+@cindex delete breakpoints
+@kindex delete
+@kindex d @r{(@code{delete})}
+@item delete @r{[}breakpoints@r{]} @r{[}@var{range}@dots{}@r{]}
+Delete the breakpoints, watchpoints, or catchpoints of the breakpoint
+ranges specified as arguments. If no argument is specified, delete all
+breakpoints (@value{GDBN} asks confirmation, unless you have @code{set
+confirm off}). You can abbreviate this command as @code{d}.
+@end table
+
+@node Disabling
+@subsection Disabling breakpoints
+
+@kindex disable breakpoints
+@kindex enable breakpoints
+Rather than deleting a breakpoint, watchpoint, or catchpoint, you might
+prefer to @dfn{disable} it. This makes the breakpoint inoperative as if
+it had been deleted, but remembers the information on the breakpoint so
+that you can @dfn{enable} it again later.
+
+You disable and enable breakpoints, watchpoints, and catchpoints with
+the @code{enable} and @code{disable} commands, optionally specifying one
+or more breakpoint numbers as arguments. Use @code{info break} or
+@code{info watch} to print a list of breakpoints, watchpoints, and
+catchpoints if you do not know which numbers to use.
+
+A breakpoint, watchpoint, or catchpoint can have any of four different
+states of enablement:
+
+@itemize @bullet
+@item
+Enabled. The breakpoint stops your program. A breakpoint set
+with the @code{break} command starts out in this state.
+@item
+Disabled. The breakpoint has no effect on your program.
+@item
+Enabled once. The breakpoint stops your program, but then becomes
+disabled.
+@item
+Enabled for deletion. The breakpoint stops your program, but
+immediately after it does so it is deleted permanently. A breakpoint
+set with the @code{tbreak} command starts out in this state.
+@end itemize
+
+You can use the following commands to enable or disable breakpoints,
+watchpoints, and catchpoints:
+
+@table @code
+@kindex disable breakpoints
+@kindex disable
+@kindex dis @r{(@code{disable})}
+@item disable @r{[}breakpoints@r{]} @r{[}@var{range}@dots{}@r{]}
+Disable the specified breakpoints---or all breakpoints, if none are
+listed. A disabled breakpoint has no effect but is not forgotten. All
+options such as ignore-counts, conditions and commands are remembered in
+case the breakpoint is enabled again later. You may abbreviate
+@code{disable} as @code{dis}.
+
+@kindex enable breakpoints
+@kindex enable
+@item enable @r{[}breakpoints@r{]} @r{[}@var{range}@dots{}@r{]}
+Enable the specified breakpoints (or all defined breakpoints). They
+become effective once again in stopping your program.
+
+@item enable @r{[}breakpoints@r{]} once @var{range}@dots{}
+Enable the specified breakpoints temporarily. @value{GDBN} disables any
+of these breakpoints immediately after stopping your program.
+
+@item enable @r{[}breakpoints@r{]} delete @var{range}@dots{}
+Enable the specified breakpoints to work once, then die. @value{GDBN}
+deletes any of these breakpoints as soon as your program stops there.
+@end table
+
+@c FIXME: I think the following ``Except for [...] @code{tbreak}'' is
+@c confusing: tbreak is also initially enabled.
+Except for a breakpoint set with @code{tbreak} (@pxref{Set Breaks,
+,Setting breakpoints}), breakpoints that you set are initially enabled;
+subsequently, they become disabled or enabled only when you use one of
+the commands above. (The command @code{until} can set and delete a
+breakpoint of its own, but it does not change the state of your other
+breakpoints; see @ref{Continuing and Stepping, ,Continuing and
+stepping}.)
+
+@node Conditions
+@subsection Break conditions
+@cindex conditional breakpoints
+@cindex breakpoint conditions
+
+@c FIXME what is scope of break condition expr? Context where wanted?
+@c in particular for a watchpoint?
+The simplest sort of breakpoint breaks every time your program reaches a
+specified place. You can also specify a @dfn{condition} for a
+breakpoint. A condition is just a Boolean expression in your
+programming language (@pxref{Expressions, ,Expressions}). A breakpoint with
+a condition evaluates the expression each time your program reaches it,
+and your program stops only if the condition is @emph{true}.
+
+This is the converse of using assertions for program validation; in that
+situation, you want to stop when the assertion is violated---that is,
+when the condition is false. In C, if you want to test an assertion expressed
+by the condition @var{assert}, you should set the condition
+@samp{! @var{assert}} on the appropriate breakpoint.
+
+Conditions are also accepted for watchpoints; you may not need them,
+since a watchpoint is inspecting the value of an expression anyhow---but
+it might be simpler, say, to just set a watchpoint on a variable name,
+and specify a condition that tests whether the new value is an interesting
+one.
+
+Break conditions can have side effects, and may even call functions in
+your program. This can be useful, for example, to activate functions
+that log program progress, or to use your own print functions to
+format special data structures. The effects are completely predictable
+unless there is another enabled breakpoint at the same address. (In
+that case, @value{GDBN} might see the other breakpoint first and stop your
+program without checking the condition of this one.) Note that
+breakpoint commands are usually more convenient and flexible than break
+conditions for the
+purpose of performing side effects when a breakpoint is reached
+(@pxref{Break Commands, ,Breakpoint command lists}).
+
+Break conditions can be specified when a breakpoint is set, by using
+@samp{if} in the arguments to the @code{break} command. @xref{Set
+Breaks, ,Setting breakpoints}. They can also be changed at any time
+with the @code{condition} command.
+
+You can also use the @code{if} keyword with the @code{watch} command.
+The @code{catch} command does not recognize the @code{if} keyword;
+@code{condition} is the only way to impose a further condition on a
+catchpoint.
+
+@table @code
+@kindex condition
+@item condition @var{bnum} @var{expression}
+Specify @var{expression} as the break condition for breakpoint,
+watchpoint, or catchpoint number @var{bnum}. After you set a condition,
+breakpoint @var{bnum} stops your program only if the value of
+@var{expression} is true (nonzero, in C). When you use
+@code{condition}, @value{GDBN} checks @var{expression} immediately for
+syntactic correctness, and to determine whether symbols in it have
+referents in the context of your breakpoint. If @var{expression} uses
+symbols not referenced in the context of the breakpoint, @value{GDBN}
+prints an error message:
+
+@smallexample
+No symbol "foo" in current context.
+@end smallexample
+
+@noindent
+@value{GDBN} does
+not actually evaluate @var{expression} at the time the @code{condition}
+command (or a command that sets a breakpoint with a condition, like
+@code{break if @dots{}}) is given, however. @xref{Expressions, ,Expressions}.
+
+@item condition @var{bnum}
+Remove the condition from breakpoint number @var{bnum}. It becomes
+an ordinary unconditional breakpoint.
+@end table
+
+@cindex ignore count (of breakpoint)
+A special case of a breakpoint condition is to stop only when the
+breakpoint has been reached a certain number of times. This is so
+useful that there is a special way to do it, using the @dfn{ignore
+count} of the breakpoint. Every breakpoint has an ignore count, which
+is an integer. Most of the time, the ignore count is zero, and
+therefore has no effect. But if your program reaches a breakpoint whose
+ignore count is positive, then instead of stopping, it just decrements
+the ignore count by one and continues. As a result, if the ignore count
+value is @var{n}, the breakpoint does not stop the next @var{n} times
+your program reaches it.
+
+@table @code
+@kindex ignore
+@item ignore @var{bnum} @var{count}
+Set the ignore count of breakpoint number @var{bnum} to @var{count}.
+The next @var{count} times the breakpoint is reached, your program's
+execution does not stop; other than to decrement the ignore count, @value{GDBN}
+takes no action.
+
+To make the breakpoint stop the next time it is reached, specify
+a count of zero.
+
+When you use @code{continue} to resume execution of your program from a
+breakpoint, you can specify an ignore count directly as an argument to
+@code{continue}, rather than using @code{ignore}. @xref{Continuing and
+Stepping,,Continuing and stepping}.
+
+If a breakpoint has a positive ignore count and a condition, the
+condition is not checked. Once the ignore count reaches zero,
+@value{GDBN} resumes checking the condition.
+
+You could achieve the effect of the ignore count with a condition such
+as @w{@samp{$foo-- <= 0}} using a debugger convenience variable that
+is decremented each time. @xref{Convenience Vars, ,Convenience
+variables}.
+@end table
+
+Ignore counts apply to breakpoints, watchpoints, and catchpoints.
+
+
+@node Break Commands
+@subsection Breakpoint command lists
+
+@cindex breakpoint commands
+You can give any breakpoint (or watchpoint or catchpoint) a series of
+commands to execute when your program stops due to that breakpoint. For
+example, you might want to print the values of certain expressions, or
+enable other breakpoints.
+
+@table @code
+@kindex commands
+@kindex end
+@item commands @r{[}@var{bnum}@r{]}
+@itemx @dots{} @var{command-list} @dots{}
+@itemx end
+Specify a list of commands for breakpoint number @var{bnum}. The commands
+themselves appear on the following lines. Type a line containing just
+@code{end} to terminate the commands.
+
+To remove all commands from a breakpoint, type @code{commands} and
+follow it immediately with @code{end}; that is, give no commands.
+
+With no @var{bnum} argument, @code{commands} refers to the last
+breakpoint, watchpoint, or catchpoint set (not to the breakpoint most
+recently encountered).
+@end table
+
+Pressing @key{RET} as a means of repeating the last @value{GDBN} command is
+disabled within a @var{command-list}.
+
+You can use breakpoint commands to start your program up again. Simply
+use the @code{continue} command, or @code{step}, or any other command
+that resumes execution.
+
+Any other commands in the command list, after a command that resumes
+execution, are ignored. This is because any time you resume execution
+(even with a simple @code{next} or @code{step}), you may encounter
+another breakpoint---which could have its own command list, leading to
+ambiguities about which list to execute.
+
+@kindex silent
+If the first command you specify in a command list is @code{silent}, the
+usual message about stopping at a breakpoint is not printed. This may
+be desirable for breakpoints that are to print a specific message and
+then continue. If none of the remaining commands print anything, you
+see no sign that the breakpoint was reached. @code{silent} is
+meaningful only at the beginning of a breakpoint command list.
+
+The commands @code{echo}, @code{output}, and @code{printf} allow you to
+print precisely controlled output, and are often useful in silent
+breakpoints. @xref{Output, ,Commands for controlled output}.
+
+For example, here is how you could use breakpoint commands to print the
+value of @code{x} at entry to @code{foo} whenever @code{x} is positive.
+
+@smallexample
+break foo if x>0
+commands
+silent
+printf "x is %d\n",x
+cont
+end
+@end smallexample
+
+One application for breakpoint commands is to compensate for one bug so
+you can test for another. Put a breakpoint just after the erroneous line
+of code, give it a condition to detect the case in which something
+erroneous has been done, and give it commands to assign correct values
+to any variables that need them. End with the @code{continue} command
+so that your program does not stop, and start with the @code{silent}
+command so that no output is produced. Here is an example:
+
+@smallexample
+break 403
+commands
+silent
+set x = y + 4
+cont
+end
+@end smallexample
+
+@node Breakpoint Menus
+@subsection Breakpoint menus
+@cindex overloading
+@cindex symbol overloading
+
+Some programming languages (notably C@t{++}) permit a single function name
+to be defined several times, for application in different contexts.
+This is called @dfn{overloading}. When a function name is overloaded,
+@samp{break @var{function}} is not enough to tell @value{GDBN} where you want
+a breakpoint. If you realize this is a problem, you can use
+something like @samp{break @var{function}(@var{types})} to specify which
+particular version of the function you want. Otherwise, @value{GDBN} offers
+you a menu of numbered choices for different possible breakpoints, and
+waits for your selection with the prompt @samp{>}. The first two
+options are always @samp{[0] cancel} and @samp{[1] all}. Typing @kbd{1}
+sets a breakpoint at each definition of @var{function}, and typing
+@kbd{0} aborts the @code{break} command without setting any new
+breakpoints.
+
+For example, the following session excerpt shows an attempt to set a
+breakpoint at the overloaded symbol @code{String::after}.
+We choose three particular definitions of that function name:
+
+@c FIXME! This is likely to change to show arg type lists, at least
+@smallexample
+@group
+(@value{GDBP}) b String::after
+[0] cancel
+[1] all
+[2] file:String.cc; line number:867
+[3] file:String.cc; line number:860
+[4] file:String.cc; line number:875
+[5] file:String.cc; line number:853
+[6] file:String.cc; line number:846
+[7] file:String.cc; line number:735
+> 2 4 6
+Breakpoint 1 at 0xb26c: file String.cc, line 867.
+Breakpoint 2 at 0xb344: file String.cc, line 875.
+Breakpoint 3 at 0xafcc: file String.cc, line 846.
+Multiple breakpoints were set.
+Use the "delete" command to delete unwanted
+ breakpoints.
+(@value{GDBP})
+@end group
+@end smallexample
+
+@c @ifclear BARETARGET
+@node Error in Breakpoints
+@subsection ``Cannot insert breakpoints''
+@c
+@c FIXME!! 14/6/95 Is there a real example of this? Let's use it.
+@c
+Under some operating systems, breakpoints cannot be used in a program if
+any other process is running that program. In this situation,
+attempting to run or continue a program with a breakpoint causes
+@value{GDBN} to print an error message:
+
+@smallexample
+Cannot insert breakpoints.
+The same program may be running in another process.
+@end smallexample
+
+When this happens, you have three ways to proceed:
+
+@enumerate
+@item
+Remove or disable the breakpoints, then continue.
+
+@item
+Suspend @value{GDBN}, and copy the file containing your program to a new
+name. Resume @value{GDBN} and use the @code{exec-file} command to specify
+that @value{GDBN} should run your program under that name.
+Then start your program again.
+
+@item
+Relink your program so that the text segment is nonsharable, using the
+linker option @samp{-N}. The operating system limitation may not apply
+to nonsharable executables.
+@end enumerate
+@c @end ifclear
+
+A similar message can be printed if you request too many active
+hardware-assisted breakpoints and watchpoints:
+
+@c FIXME: the precise wording of this message may change; the relevant
+@c source change is not committed yet (Sep 3, 1999).
+@smallexample
+Stopped; cannot insert breakpoints.
+You may have requested too many hardware breakpoints and watchpoints.
+@end smallexample
+
+@noindent
+This message is printed when you attempt to resume the program, since
+only then @value{GDBN} knows exactly how many hardware breakpoints and
+watchpoints it needs to insert.
+
+When this message is printed, you need to disable or remove some of the
+hardware-assisted breakpoints and watchpoints, and then continue.
+
+
+@node Continuing and Stepping
+@section Continuing and stepping
+
+@cindex stepping
+@cindex continuing
+@cindex resuming execution
+@dfn{Continuing} means resuming program execution until your program
+completes normally. In contrast, @dfn{stepping} means executing just
+one more ``step'' of your program, where ``step'' may mean either one
+line of source code, or one machine instruction (depending on what
+particular command you use). Either when continuing or when stepping,
+your program may stop even sooner, due to a breakpoint or a signal. (If
+it stops due to a signal, you may want to use @code{handle}, or use
+@samp{signal 0} to resume execution. @xref{Signals, ,Signals}.)
+
+@table @code
+@kindex continue
+@kindex c @r{(@code{continue})}
+@kindex fg @r{(resume foreground execution)}
+@item continue @r{[}@var{ignore-count}@r{]}
+@itemx c @r{[}@var{ignore-count}@r{]}
+@itemx fg @r{[}@var{ignore-count}@r{]}
+Resume program execution, at the address where your program last stopped;
+any breakpoints set at that address are bypassed. The optional argument
+@var{ignore-count} allows you to specify a further number of times to
+ignore a breakpoint at this location; its effect is like that of
+@code{ignore} (@pxref{Conditions, ,Break conditions}).
+
+The argument @var{ignore-count} is meaningful only when your program
+stopped due to a breakpoint. At other times, the argument to
+@code{continue} is ignored.
+
+The synonyms @code{c} and @code{fg} (for @dfn{foreground}, as the
+debugged program is deemed to be the foreground program) are provided
+purely for convenience, and have exactly the same behavior as
+@code{continue}.
+@end table
+
+To resume execution at a different place, you can use @code{return}
+(@pxref{Returning, ,Returning from a function}) to go back to the
+calling function; or @code{jump} (@pxref{Jumping, ,Continuing at a
+different address}) to go to an arbitrary location in your program.
+
+A typical technique for using stepping is to set a breakpoint
+(@pxref{Breakpoints, ,Breakpoints; watchpoints; and catchpoints}) at the
+beginning of the function or the section of your program where a problem
+is believed to lie, run your program until it stops at that breakpoint,
+and then step through the suspect area, examining the variables that are
+interesting, until you see the problem happen.
+
+@table @code
+@kindex step
+@kindex s @r{(@code{step})}
+@item step
+Continue running your program until control reaches a different source
+line, then stop it and return control to @value{GDBN}. This command is
+abbreviated @code{s}.
+
+@quotation
+@c "without debugging information" is imprecise; actually "without line
+@c numbers in the debugging information". (gcc -g1 has debugging info but
+@c not line numbers). But it seems complex to try to make that
+@c distinction here.
+@emph{Warning:} If you use the @code{step} command while control is
+within a function that was compiled without debugging information,
+execution proceeds until control reaches a function that does have
+debugging information. Likewise, it will not step into a function which
+is compiled without debugging information. To step through functions
+without debugging information, use the @code{stepi} command, described
+below.
+@end quotation
+
+The @code{step} command only stops at the first instruction of a source
+line. This prevents the multiple stops that could otherwise occur in
+@code{switch} statements, @code{for} loops, etc. @code{step} continues
+to stop if a function that has debugging information is called within
+the line. In other words, @code{step} @emph{steps inside} any functions
+called within the line.
+
+Also, the @code{step} command only enters a function if there is line
+number information for the function. Otherwise it acts like the
+@code{next} command. This avoids problems when using @code{cc -gl}
+on MIPS machines. Previously, @code{step} entered subroutines if there
+was any debugging information about the routine.
+
+@item step @var{count}
+Continue running as in @code{step}, but do so @var{count} times. If a
+breakpoint is reached, or a signal not related to stepping occurs before
+@var{count} steps, stepping stops right away.
+
+@kindex next
+@kindex n @r{(@code{next})}
+@item next @r{[}@var{count}@r{]}
+Continue to the next source line in the current (innermost) stack frame.
+This is similar to @code{step}, but function calls that appear within
+the line of code are executed without stopping. Execution stops when
+control reaches a different line of code at the original stack level
+that was executing when you gave the @code{next} command. This command
+is abbreviated @code{n}.
+
+An argument @var{count} is a repeat count, as for @code{step}.
+
+
+@c FIX ME!! Do we delete this, or is there a way it fits in with
+@c the following paragraph? --- Vctoria
+@c
+@c @code{next} within a function that lacks debugging information acts like
+@c @code{step}, but any function calls appearing within the code of the
+@c function are executed without stopping.
+
+The @code{next} command only stops at the first instruction of a
+source line. This prevents multiple stops that could otherwise occur in
+@code{switch} statements, @code{for} loops, etc.
+
+@kindex set step-mode
+@item set step-mode
+@cindex functions without line info, and stepping
+@cindex stepping into functions with no line info
+@itemx set step-mode on
+The @code{set step-mode on} command causes the @code{step} command to
+stop at the first instruction of a function which contains no debug line
+information rather than stepping over it.
+
+This is useful in cases where you may be interested in inspecting the
+machine instructions of a function which has no symbolic info and do not
+want @value{GDBN} to automatically skip over this function.
+
+@item set step-mode off
+Causes the @code{step} command to step over any functions which contains no
+debug information. This is the default.
+
+@kindex finish
+@item finish
+Continue running until just after function in the selected stack frame
+returns. Print the returned value (if any).
+
+Contrast this with the @code{return} command (@pxref{Returning,
+,Returning from a function}).
+
+@kindex until
+@kindex u @r{(@code{until})}
+@item until
+@itemx u
+Continue running until a source line past the current line, in the
+current stack frame, is reached. This command is used to avoid single
+stepping through a loop more than once. It is like the @code{next}
+command, except that when @code{until} encounters a jump, it
+automatically continues execution until the program counter is greater
+than the address of the jump.
+
+This means that when you reach the end of a loop after single stepping
+though it, @code{until} makes your program continue execution until it
+exits the loop. In contrast, a @code{next} command at the end of a loop
+simply steps back to the beginning of the loop, which forces you to step
+through the next iteration.
+
+@code{until} always stops your program if it attempts to exit the current
+stack frame.
+
+@code{until} may produce somewhat counterintuitive results if the order
+of machine code does not match the order of the source lines. For
+example, in the following excerpt from a debugging session, the @code{f}
+(@code{frame}) command shows that execution is stopped at line
+@code{206}; yet when we use @code{until}, we get to line @code{195}:
+
+@smallexample
+(@value{GDBP}) f
+#0 main (argc=4, argv=0xf7fffae8) at m4.c:206
+206 expand_input();
+(@value{GDBP}) until
+195 for ( ; argc > 0; NEXTARG) @{
+@end smallexample
+
+This happened because, for execution efficiency, the compiler had
+generated code for the loop closure test at the end, rather than the
+start, of the loop---even though the test in a C @code{for}-loop is
+written before the body of the loop. The @code{until} command appeared
+to step back to the beginning of the loop when it advanced to this
+expression; however, it has not really gone to an earlier
+statement---not in terms of the actual machine code.
+
+@code{until} with no argument works by means of single
+instruction stepping, and hence is slower than @code{until} with an
+argument.
+
+@item until @var{location}
+@itemx u @var{location}
+Continue running your program until either the specified location is
+reached, or the current stack frame returns. @var{location} is any of
+the forms of argument acceptable to @code{break} (@pxref{Set Breaks,
+,Setting breakpoints}). This form of the command uses breakpoints,
+and hence is quicker than @code{until} without an argument.
+
+@kindex stepi
+@kindex si @r{(@code{stepi})}
+@item stepi
+@itemx stepi @var{arg}
+@itemx si
+Execute one machine instruction, then stop and return to the debugger.
+
+It is often useful to do @samp{display/i $pc} when stepping by machine
+instructions. This makes @value{GDBN} automatically display the next
+instruction to be executed, each time your program stops. @xref{Auto
+Display,, Automatic display}.
+
+An argument is a repeat count, as in @code{step}.
+
+@need 750
+@kindex nexti
+@kindex ni @r{(@code{nexti})}
+@item nexti
+@itemx nexti @var{arg}
+@itemx ni
+Execute one machine instruction, but if it is a function call,
+proceed until the function returns.
+
+An argument is a repeat count, as in @code{next}.
+@end table
+
+@node Signals
+@section Signals
+@cindex signals
+
+A signal is an asynchronous event that can happen in a program. The
+operating system defines the possible kinds of signals, and gives each
+kind a name and a number. For example, in Unix @code{SIGINT} is the
+signal a program gets when you type an interrupt character (often @kbd{C-c});
+@code{SIGSEGV} is the signal a program gets from referencing a place in
+memory far away from all the areas in use; @code{SIGALRM} occurs when
+the alarm clock timer goes off (which happens only if your program has
+requested an alarm).
+
+@cindex fatal signals
+Some signals, including @code{SIGALRM}, are a normal part of the
+functioning of your program. Others, such as @code{SIGSEGV}, indicate
+errors; these signals are @dfn{fatal} (they kill your program immediately) if the
+program has not specified in advance some other way to handle the signal.
+@code{SIGINT} does not indicate an error in your program, but it is normally
+fatal so it can carry out the purpose of the interrupt: to kill the program.
+
+@value{GDBN} has the ability to detect any occurrence of a signal in your
+program. You can tell @value{GDBN} in advance what to do for each kind of
+signal.
+
+@cindex handling signals
+Normally, @value{GDBN} is set up to let the non-erroneous signals like
+@code{SIGALRM} be silently passed to your program
+(so as not to interfere with their role in the program's functioning)
+but to stop your program immediately whenever an error signal happens.
+You can change these settings with the @code{handle} command.
+
+@table @code
+@kindex info signals
+@item info signals
+@itemx info handle
+Print a table of all the kinds of signals and how @value{GDBN} has been told to
+handle each one. You can use this to see the signal numbers of all
+the defined types of signals.
+
+@code{info handle} is an alias for @code{info signals}.
+
+@kindex handle
+@item handle @var{signal} @var{keywords}@dots{}
+Change the way @value{GDBN} handles signal @var{signal}. @var{signal}
+can be the number of a signal or its name (with or without the
+@samp{SIG} at the beginning); a list of signal numbers of the form
+@samp{@var{low}-@var{high}}; or the word @samp{all}, meaning all the
+known signals. The @var{keywords} say what change to make.
+@end table
+
+@c @group
+The keywords allowed by the @code{handle} command can be abbreviated.
+Their full names are:
+
+@table @code
+@item nostop
+@value{GDBN} should not stop your program when this signal happens. It may
+still print a message telling you that the signal has come in.
+
+@item stop
+@value{GDBN} should stop your program when this signal happens. This implies
+the @code{print} keyword as well.
+
+@item print
+@value{GDBN} should print a message when this signal happens.
+
+@item noprint
+@value{GDBN} should not mention the occurrence of the signal at all. This
+implies the @code{nostop} keyword as well.
+
+@item pass
+@itemx noignore
+@value{GDBN} should allow your program to see this signal; your program
+can handle the signal, or else it may terminate if the signal is fatal
+and not handled. @code{pass} and @code{noignore} are synonyms.
+
+@item nopass
+@itemx ignore
+@value{GDBN} should not allow your program to see this signal.
+@code{nopass} and @code{ignore} are synonyms.
+@end table
+@c @end group
+
+When a signal stops your program, the signal is not visible to the
+program until you
+continue. Your program sees the signal then, if @code{pass} is in
+effect for the signal in question @emph{at that time}. In other words,
+after @value{GDBN} reports a signal, you can use the @code{handle}
+command with @code{pass} or @code{nopass} to control whether your
+program sees that signal when you continue.
+
+The default is set to @code{nostop}, @code{noprint}, @code{pass} for
+non-erroneous signals such as @code{SIGALRM}, @code{SIGWINCH} and
+@code{SIGCHLD}, and to @code{stop}, @code{print}, @code{pass} for the
+erroneous signals.
+
+You can also use the @code{signal} command to prevent your program from
+seeing a signal, or cause it to see a signal it normally would not see,
+or to give it any signal at any time. For example, if your program stopped
+due to some sort of memory reference error, you might store correct
+values into the erroneous variables and continue, hoping to see more
+execution; but your program would probably terminate immediately as
+a result of the fatal signal once it saw the signal. To prevent this,
+you can continue with @samp{signal 0}. @xref{Signaling, ,Giving your
+program a signal}.
+
+@node Thread Stops
+@section Stopping and starting multi-thread programs
+
+When your program has multiple threads (@pxref{Threads,, Debugging
+programs with multiple threads}), you can choose whether to set
+breakpoints on all threads, or on a particular thread.
+
+@table @code
+@cindex breakpoints and threads
+@cindex thread breakpoints
+@kindex break @dots{} thread @var{threadno}
+@item break @var{linespec} thread @var{threadno}
+@itemx break @var{linespec} thread @var{threadno} if @dots{}
+@var{linespec} specifies source lines; there are several ways of
+writing them, but the effect is always to specify some source line.
+
+Use the qualifier @samp{thread @var{threadno}} with a breakpoint command
+to specify that you only want @value{GDBN} to stop the program when a
+particular thread reaches this breakpoint. @var{threadno} is one of the
+numeric thread identifiers assigned by @value{GDBN}, shown in the first
+column of the @samp{info threads} display.
+
+If you do not specify @samp{thread @var{threadno}} when you set a
+breakpoint, the breakpoint applies to @emph{all} threads of your
+program.
+
+You can use the @code{thread} qualifier on conditional breakpoints as
+well; in this case, place @samp{thread @var{threadno}} before the
+breakpoint condition, like this:
+
+@smallexample
+(@value{GDBP}) break frik.c:13 thread 28 if bartab > lim
+@end smallexample
+
+@end table
+
+@cindex stopped threads
+@cindex threads, stopped
+Whenever your program stops under @value{GDBN} for any reason,
+@emph{all} threads of execution stop, not just the current thread. This
+allows you to examine the overall state of the program, including
+switching between threads, without worrying that things may change
+underfoot.
+
+@cindex continuing threads
+@cindex threads, continuing
+Conversely, whenever you restart the program, @emph{all} threads start
+executing. @emph{This is true even when single-stepping} with commands
+like @code{step} or @code{next}.
+
+In particular, @value{GDBN} cannot single-step all threads in lockstep.
+Since thread scheduling is up to your debugging target's operating
+system (not controlled by @value{GDBN}), other threads may
+execute more than one statement while the current thread completes a
+single step. Moreover, in general other threads stop in the middle of a
+statement, rather than at a clean statement boundary, when the program
+stops.
+
+You might even find your program stopped in another thread after
+continuing or even single-stepping. This happens whenever some other
+thread runs into a breakpoint, a signal, or an exception before the
+first thread completes whatever you requested.
+
+On some OSes, you can lock the OS scheduler and thus allow only a single
+thread to run.
+
+@table @code
+@item set scheduler-locking @var{mode}
+Set the scheduler locking mode. If it is @code{off}, then there is no
+locking and any thread may run at any time. If @code{on}, then only the
+current thread may run when the inferior is resumed. The @code{step}
+mode optimizes for single-stepping. It stops other threads from
+``seizing the prompt'' by preempting the current thread while you are
+stepping. Other threads will only rarely (or never) get a chance to run
+when you step. They are more likely to run when you @samp{next} over a
+function call, and they are completely free to run when you use commands
+like @samp{continue}, @samp{until}, or @samp{finish}. However, unless another
+thread hits a breakpoint during its timeslice, they will never steal the
+@value{GDBN} prompt away from the thread that you are debugging.
+
+@item show scheduler-locking
+Display the current scheduler locking mode.
+@end table
+
+
+@node Stack
+@chapter Examining the Stack
+
+When your program has stopped, the first thing you need to know is where it
+stopped and how it got there.
+
+@cindex call stack
+Each time your program performs a function call, information about the call
+is generated.
+That information includes the location of the call in your program,
+the arguments of the call,
+and the local variables of the function being called.
+The information is saved in a block of data called a @dfn{stack frame}.
+The stack frames are allocated in a region of memory called the @dfn{call
+stack}.
+
+When your program stops, the @value{GDBN} commands for examining the
+stack allow you to see all of this information.
+
+@cindex selected frame
+One of the stack frames is @dfn{selected} by @value{GDBN} and many
+@value{GDBN} commands refer implicitly to the selected frame. In
+particular, whenever you ask @value{GDBN} for the value of a variable in
+your program, the value is found in the selected frame. There are
+special @value{GDBN} commands to select whichever frame you are
+interested in. @xref{Selection, ,Selecting a frame}.
+
+When your program stops, @value{GDBN} automatically selects the
+currently executing frame and describes it briefly, similar to the
+@code{frame} command (@pxref{Frame Info, ,Information about a frame}).
+
+@menu
+* Frames:: Stack frames
+* Backtrace:: Backtraces
+* Selection:: Selecting a frame
+* Frame Info:: Information on a frame
+
+@end menu
+
+@node Frames
+@section Stack frames
+
+@cindex frame, definition
+@cindex stack frame
+The call stack is divided up into contiguous pieces called @dfn{stack
+frames}, or @dfn{frames} for short; each frame is the data associated
+with one call to one function. The frame contains the arguments given
+to the function, the function's local variables, and the address at
+which the function is executing.
+
+@cindex initial frame
+@cindex outermost frame
+@cindex innermost frame
+When your program is started, the stack has only one frame, that of the
+function @code{main}. This is called the @dfn{initial} frame or the
+@dfn{outermost} frame. Each time a function is called, a new frame is
+made. Each time a function returns, the frame for that function invocation
+is eliminated. If a function is recursive, there can be many frames for
+the same function. The frame for the function in which execution is
+actually occurring is called the @dfn{innermost} frame. This is the most
+recently created of all the stack frames that still exist.
+
+@cindex frame pointer
+Inside your program, stack frames are identified by their addresses. A
+stack frame consists of many bytes, each of which has its own address; each
+kind of computer has a convention for choosing one byte whose
+address serves as the address of the frame. Usually this address is kept
+in a register called the @dfn{frame pointer register} while execution is
+going on in that frame.
+
+@cindex frame number
+@value{GDBN} assigns numbers to all existing stack frames, starting with
+zero for the innermost frame, one for the frame that called it,
+and so on upward. These numbers do not really exist in your program;
+they are assigned by @value{GDBN} to give you a way of designating stack
+frames in @value{GDBN} commands.
+
+@c The -fomit-frame-pointer below perennially causes hbox overflow
+@c underflow problems.
+@cindex frameless execution
+Some compilers provide a way to compile functions so that they operate
+without stack frames. (For example, the @value{GCC} option
+@smallexample
+@samp{-fomit-frame-pointer}
+@end smallexample
+generates functions without a frame.)
+This is occasionally done with heavily used library functions to save
+the frame setup time. @value{GDBN} has limited facilities for dealing
+with these function invocations. If the innermost function invocation
+has no stack frame, @value{GDBN} nevertheless regards it as though
+it had a separate frame, which is numbered zero as usual, allowing
+correct tracing of the function call chain. However, @value{GDBN} has
+no provision for frameless functions elsewhere in the stack.
+
+@table @code
+@kindex frame@r{, command}
+@cindex current stack frame
+@item frame @var{args}
+The @code{frame} command allows you to move from one stack frame to another,
+and to print the stack frame you select. @var{args} may be either the
+address of the frame or the stack frame number. Without an argument,
+@code{frame} prints the current stack frame.
+
+@kindex select-frame
+@cindex selecting frame silently
+@item select-frame
+The @code{select-frame} command allows you to move from one stack frame
+to another without printing the frame. This is the silent version of
+@code{frame}.
+@end table
+
+@node Backtrace
+@section Backtraces
+
+@cindex backtraces
+@cindex tracebacks
+@cindex stack traces
+A backtrace is a summary of how your program got where it is. It shows one
+line per frame, for many frames, starting with the currently executing
+frame (frame zero), followed by its caller (frame one), and on up the
+stack.
+
+@table @code
+@kindex backtrace
+@kindex bt @r{(@code{backtrace})}
+@item backtrace
+@itemx bt
+Print a backtrace of the entire stack: one line per frame for all
+frames in the stack.
+
+You can stop the backtrace at any time by typing the system interrupt
+character, normally @kbd{C-c}.
+
+@item backtrace @var{n}
+@itemx bt @var{n}
+Similar, but print only the innermost @var{n} frames.
+
+@item backtrace -@var{n}
+@itemx bt -@var{n}
+Similar, but print only the outermost @var{n} frames.
+@end table
+
+@kindex where
+@kindex info stack
+@kindex info s @r{(@code{info stack})}
+The names @code{where} and @code{info stack} (abbreviated @code{info s})
+are additional aliases for @code{backtrace}.
+
+Each line in the backtrace shows the frame number and the function name.
+The program counter value is also shown---unless you use @code{set
+print address off}. The backtrace also shows the source file name and
+line number, as well as the arguments to the function. The program
+counter value is omitted if it is at the beginning of the code for that
+line number.
+
+Here is an example of a backtrace. It was made with the command
+@samp{bt 3}, so it shows the innermost three frames.
+
+@smallexample
+@group
+#0 m4_traceon (obs=0x24eb0, argc=1, argv=0x2b8c8)
+ at builtin.c:993
+#1 0x6e38 in expand_macro (sym=0x2b600) at macro.c:242
+#2 0x6840 in expand_token (obs=0x0, t=177664, td=0xf7fffb08)
+ at macro.c:71
+(More stack frames follow...)
+@end group
+@end smallexample
+
+@noindent
+The display for frame zero does not begin with a program counter
+value, indicating that your program has stopped at the beginning of the
+code for line @code{993} of @code{builtin.c}.
+
+@node Selection
+@section Selecting a frame
+
+Most commands for examining the stack and other data in your program work on
+whichever stack frame is selected at the moment. Here are the commands for
+selecting a stack frame; all of them finish by printing a brief description
+of the stack frame just selected.
+
+@table @code
+@kindex frame@r{, selecting}
+@kindex f @r{(@code{frame})}
+@item frame @var{n}
+@itemx f @var{n}
+Select frame number @var{n}. Recall that frame zero is the innermost
+(currently executing) frame, frame one is the frame that called the
+innermost one, and so on. The highest-numbered frame is the one for
+@code{main}.
+
+@item frame @var{addr}
+@itemx f @var{addr}
+Select the frame at address @var{addr}. This is useful mainly if the
+chaining of stack frames has been damaged by a bug, making it
+impossible for @value{GDBN} to assign numbers properly to all frames. In
+addition, this can be useful when your program has multiple stacks and
+switches between them.
+
+On the SPARC architecture, @code{frame} needs two addresses to
+select an arbitrary frame: a frame pointer and a stack pointer.
+
+On the MIPS and Alpha architecture, it needs two addresses: a stack
+pointer and a program counter.
+
+On the 29k architecture, it needs three addresses: a register stack
+pointer, a program counter, and a memory stack pointer.
+@c note to future updaters: this is conditioned on a flag
+@c SETUP_ARBITRARY_FRAME in the tm-*.h files. The above is up to date
+@c as of 27 Jan 1994.
+
+@kindex up
+@item up @var{n}
+Move @var{n} frames up the stack. For positive numbers @var{n}, this
+advances toward the outermost frame, to higher frame numbers, to frames
+that have existed longer. @var{n} defaults to one.
+
+@kindex down
+@kindex do @r{(@code{down})}
+@item down @var{n}
+Move @var{n} frames down the stack. For positive numbers @var{n}, this
+advances toward the innermost frame, to lower frame numbers, to frames
+that were created more recently. @var{n} defaults to one. You may
+abbreviate @code{down} as @code{do}.
+@end table
+
+All of these commands end by printing two lines of output describing the
+frame. The first line shows the frame number, the function name, the
+arguments, and the source file and line number of execution in that
+frame. The second line shows the text of that source line.
+
+@need 1000
+For example:
+
+@smallexample
+@group
+(@value{GDBP}) up
+#1 0x22f0 in main (argc=1, argv=0xf7fffbf4, env=0xf7fffbfc)
+ at env.c:10
+10 read_input_file (argv[i]);
+@end group
+@end smallexample
+
+After such a printout, the @code{list} command with no arguments
+prints ten lines centered on the point of execution in the frame.
+@xref{List, ,Printing source lines}.
+
+@table @code
+@kindex down-silently
+@kindex up-silently
+@item up-silently @var{n}
+@itemx down-silently @var{n}
+These two commands are variants of @code{up} and @code{down},
+respectively; they differ in that they do their work silently, without
+causing display of the new frame. They are intended primarily for use
+in @value{GDBN} command scripts, where the output might be unnecessary and
+distracting.
+@end table
+
+@node Frame Info
+@section Information about a frame
+
+There are several other commands to print information about the selected
+stack frame.
+
+@table @code
+@item frame
+@itemx f
+When used without any argument, this command does not change which
+frame is selected, but prints a brief description of the currently
+selected stack frame. It can be abbreviated @code{f}. With an
+argument, this command is used to select a stack frame.
+@xref{Selection, ,Selecting a frame}.
+
+@kindex info frame
+@kindex info f @r{(@code{info frame})}
+@item info frame
+@itemx info f
+This command prints a verbose description of the selected stack frame,
+including:
+
+@itemize @bullet
+@item
+the address of the frame
+@item
+the address of the next frame down (called by this frame)
+@item
+the address of the next frame up (caller of this frame)
+@item
+the language in which the source code corresponding to this frame is written
+@item
+the address of the frame's arguments
+@item
+the address of the frame's local variables
+@item
+the program counter saved in it (the address of execution in the caller frame)
+@item
+which registers were saved in the frame
+@end itemize
+
+@noindent The verbose description is useful when
+something has gone wrong that has made the stack format fail to fit
+the usual conventions.
+
+@item info frame @var{addr}
+@itemx info f @var{addr}
+Print a verbose description of the frame at address @var{addr}, without
+selecting that frame. The selected frame remains unchanged by this
+command. This requires the same kind of address (more than one for some
+architectures) that you specify in the @code{frame} command.
+@xref{Selection, ,Selecting a frame}.
+
+@kindex info args
+@item info args
+Print the arguments of the selected frame, each on a separate line.
+
+@item info locals
+@kindex info locals
+Print the local variables of the selected frame, each on a separate
+line. These are all variables (declared either static or automatic)
+accessible at the point of execution of the selected frame.
+
+@kindex info catch
+@cindex catch exceptions, list active handlers
+@cindex exception handlers, how to list
+@item info catch
+Print a list of all the exception handlers that are active in the
+current stack frame at the current point of execution. To see other
+exception handlers, visit the associated frame (using the @code{up},
+@code{down}, or @code{frame} commands); then type @code{info catch}.
+@xref{Set Catchpoints, , Setting catchpoints}.
+
+@end table
+
+
+@node Source
+@chapter Examining Source Files
+
+@value{GDBN} can print parts of your program's source, since the debugging
+information recorded in the program tells @value{GDBN} what source files were
+used to build it. When your program stops, @value{GDBN} spontaneously prints
+the line where it stopped. Likewise, when you select a stack frame
+(@pxref{Selection, ,Selecting a frame}), @value{GDBN} prints the line where
+execution in that frame has stopped. You can print other portions of
+source files by explicit command.
+
+If you use @value{GDBN} through its @sc{gnu} Emacs interface, you may
+prefer to use Emacs facilities to view source; see @ref{Emacs, ,Using
+@value{GDBN} under @sc{gnu} Emacs}.
+
+@menu
+* List:: Printing source lines
+* Search:: Searching source files
+* Source Path:: Specifying source directories
+* Machine Code:: Source and machine code
+@end menu
+
+@node List
+@section Printing source lines
+
+@kindex list
+@kindex l @r{(@code{list})}
+To print lines from a source file, use the @code{list} command
+(abbreviated @code{l}). By default, ten lines are printed.
+There are several ways to specify what part of the file you want to print.
+
+Here are the forms of the @code{list} command most commonly used:
+
+@table @code
+@item list @var{linenum}
+Print lines centered around line number @var{linenum} in the
+current source file.
+
+@item list @var{function}
+Print lines centered around the beginning of function
+@var{function}.
+
+@item list
+Print more lines. If the last lines printed were printed with a
+@code{list} command, this prints lines following the last lines
+printed; however, if the last line printed was a solitary line printed
+as part of displaying a stack frame (@pxref{Stack, ,Examining the
+Stack}), this prints lines centered around that line.
+
+@item list -
+Print lines just before the lines last printed.
+@end table
+
+By default, @value{GDBN} prints ten source lines with any of these forms of
+the @code{list} command. You can change this using @code{set listsize}:
+
+@table @code
+@kindex set listsize
+@item set listsize @var{count}
+Make the @code{list} command display @var{count} source lines (unless
+the @code{list} argument explicitly specifies some other number).
+
+@kindex show listsize
+@item show listsize
+Display the number of lines that @code{list} prints.
+@end table
+
+Repeating a @code{list} command with @key{RET} discards the argument,
+so it is equivalent to typing just @code{list}. This is more useful
+than listing the same lines again. An exception is made for an
+argument of @samp{-}; that argument is preserved in repetition so that
+each repetition moves up in the source file.
+
+@cindex linespec
+In general, the @code{list} command expects you to supply zero, one or two
+@dfn{linespecs}. Linespecs specify source lines; there are several ways
+of writing them, but the effect is always to specify some source line.
+Here is a complete description of the possible arguments for @code{list}:
+
+@table @code
+@item list @var{linespec}
+Print lines centered around the line specified by @var{linespec}.
+
+@item list @var{first},@var{last}
+Print lines from @var{first} to @var{last}. Both arguments are
+linespecs.
+
+@item list ,@var{last}
+Print lines ending with @var{last}.
+
+@item list @var{first},
+Print lines starting with @var{first}.
+
+@item list +
+Print lines just after the lines last printed.
+
+@item list -
+Print lines just before the lines last printed.
+
+@item list
+As described in the preceding table.
+@end table
+
+Here are the ways of specifying a single source line---all the
+kinds of linespec.
+
+@table @code
+@item @var{number}
+Specifies line @var{number} of the current source file.
+When a @code{list} command has two linespecs, this refers to
+the same source file as the first linespec.
+
+@item +@var{offset}
+Specifies the line @var{offset} lines after the last line printed.
+When used as the second linespec in a @code{list} command that has
+two, this specifies the line @var{offset} lines down from the
+first linespec.
+
+@item -@var{offset}
+Specifies the line @var{offset} lines before the last line printed.
+
+@item @var{filename}:@var{number}
+Specifies line @var{number} in the source file @var{filename}.
+
+@item @var{function}
+Specifies the line that begins the body of the function @var{function}.
+For example: in C, this is the line with the open brace.
+
+@item @var{filename}:@var{function}
+Specifies the line of the open-brace that begins the body of the
+function @var{function} in the file @var{filename}. You only need the
+file name with a function name to avoid ambiguity when there are
+identically named functions in different source files.
+
+@item *@var{address}
+Specifies the line containing the program address @var{address}.
+@var{address} may be any expression.
+@end table
+
+@node Search
+@section Searching source files
+@cindex searching
+@kindex reverse-search
+
+There are two commands for searching through the current source file for a
+regular expression.
+
+@table @code
+@kindex search
+@kindex forward-search
+@item forward-search @var{regexp}
+@itemx search @var{regexp}
+The command @samp{forward-search @var{regexp}} checks each line,
+starting with the one following the last line listed, for a match for
+@var{regexp}. It lists the line that is found. You can use the
+synonym @samp{search @var{regexp}} or abbreviate the command name as
+@code{fo}.
+
+@item reverse-search @var{regexp}
+The command @samp{reverse-search @var{regexp}} checks each line, starting
+with the one before the last line listed and going backward, for a match
+for @var{regexp}. It lists the line that is found. You can abbreviate
+this command as @code{rev}.
+@end table
+
+@node Source Path
+@section Specifying source directories
+
+@cindex source path
+@cindex directories for source files
+Executable programs sometimes do not record the directories of the source
+files from which they were compiled, just the names. Even when they do,
+the directories could be moved between the compilation and your debugging
+session. @value{GDBN} has a list of directories to search for source files;
+this is called the @dfn{source path}. Each time @value{GDBN} wants a source file,
+it tries all the directories in the list, in the order they are present
+in the list, until it finds a file with the desired name. Note that
+the executable search path is @emph{not} used for this purpose. Neither is
+the current working directory, unless it happens to be in the source
+path.
+
+If @value{GDBN} cannot find a source file in the source path, and the
+object program records a directory, @value{GDBN} tries that directory
+too. If the source path is empty, and there is no record of the
+compilation directory, @value{GDBN} looks in the current directory as a
+last resort.
+
+Whenever you reset or rearrange the source path, @value{GDBN} clears out
+any information it has cached about where source files are found and where
+each line is in the file.
+
+@kindex directory
+@kindex dir
+When you start @value{GDBN}, its source path includes only @samp{cdir}
+and @samp{cwd}, in that order.
+To add other directories, use the @code{directory} command.
+
+@table @code
+@item directory @var{dirname} @dots{}
+@item dir @var{dirname} @dots{}
+Add directory @var{dirname} to the front of the source path. Several
+directory names may be given to this command, separated by @samp{:}
+(@samp{;} on MS-DOS and MS-Windows, where @samp{:} usually appears as
+part of absolute file names) or
+whitespace. You may specify a directory that is already in the source
+path; this moves it forward, so @value{GDBN} searches it sooner.
+
+@kindex cdir
+@kindex cwd
+@vindex $cdir@r{, convenience variable}
+@vindex $cwdr@r{, convenience variable}
+@cindex compilation directory
+@cindex current directory
+@cindex working directory
+@cindex directory, current
+@cindex directory, compilation
+You can use the string @samp{$cdir} to refer to the compilation
+directory (if one is recorded), and @samp{$cwd} to refer to the current
+working directory. @samp{$cwd} is not the same as @samp{.}---the former
+tracks the current working directory as it changes during your @value{GDBN}
+session, while the latter is immediately expanded to the current
+directory at the time you add an entry to the source path.
+
+@item directory
+Reset the source path to empty again. This requires confirmation.
+
+@c RET-repeat for @code{directory} is explicitly disabled, but since
+@c repeating it would be a no-op we do not say that. (thanks to RMS)
+
+@item show directories
+@kindex show directories
+Print the source path: show which directories it contains.
+@end table
+
+If your source path is cluttered with directories that are no longer of
+interest, @value{GDBN} may sometimes cause confusion by finding the wrong
+versions of source. You can correct the situation as follows:
+
+@enumerate
+@item
+Use @code{directory} with no argument to reset the source path to empty.
+
+@item
+Use @code{directory} with suitable arguments to reinstall the
+directories you want in the source path. You can add all the
+directories in one command.
+@end enumerate
+
+@node Machine Code
+@section Source and machine code
+
+You can use the command @code{info line} to map source lines to program
+addresses (and vice versa), and the command @code{disassemble} to display
+a range of addresses as machine instructions. When run under @sc{gnu} Emacs
+mode, the @code{info line} command causes the arrow to point to the
+line specified. Also, @code{info line} prints addresses in symbolic form as
+well as hex.
+
+@table @code
+@kindex info line
+@item info line @var{linespec}
+Print the starting and ending addresses of the compiled code for
+source line @var{linespec}. You can specify source lines in any of
+the ways understood by the @code{list} command (@pxref{List, ,Printing
+source lines}).
+@end table
+
+For example, we can use @code{info line} to discover the location of
+the object code for the first line of function
+@code{m4_changequote}:
+
+@c FIXME: I think this example should also show the addresses in
+@c symbolic form, as they usually would be displayed.
+@smallexample
+(@value{GDBP}) info line m4_changequote
+Line 895 of "builtin.c" starts at pc 0x634c and ends at 0x6350.
+@end smallexample
+
+@noindent
+We can also inquire (using @code{*@var{addr}} as the form for
+@var{linespec}) what source line covers a particular address:
+@smallexample
+(@value{GDBP}) info line *0x63ff
+Line 926 of "builtin.c" starts at pc 0x63e4 and ends at 0x6404.
+@end smallexample
+
+@cindex @code{$_} and @code{info line}
+@kindex x@r{(examine), and} info line
+After @code{info line}, the default address for the @code{x} command
+is changed to the starting address of the line, so that @samp{x/i} is
+sufficient to begin examining the machine code (@pxref{Memory,
+,Examining memory}). Also, this address is saved as the value of the
+convenience variable @code{$_} (@pxref{Convenience Vars, ,Convenience
+variables}).
+
+@table @code
+@kindex disassemble
+@cindex assembly instructions
+@cindex instructions, assembly
+@cindex machine instructions
+@cindex listing machine instructions
+@item disassemble
+This specialized command dumps a range of memory as machine
+instructions. The default memory range is the function surrounding the
+program counter of the selected frame. A single argument to this
+command is a program counter value; @value{GDBN} dumps the function
+surrounding this value. Two arguments specify a range of addresses
+(first inclusive, second exclusive) to dump.
+@end table
+
+The following example shows the disassembly of a range of addresses of
+HP PA-RISC 2.0 code:
+
+@smallexample
+(@value{GDBP}) disas 0x32c4 0x32e4
+Dump of assembler code from 0x32c4 to 0x32e4:
+0x32c4 <main+204>: addil 0,dp
+0x32c8 <main+208>: ldw 0x22c(sr0,r1),r26
+0x32cc <main+212>: ldil 0x3000,r31
+0x32d0 <main+216>: ble 0x3f8(sr4,r31)
+0x32d4 <main+220>: ldo 0(r31),rp
+0x32d8 <main+224>: addil -0x800,dp
+0x32dc <main+228>: ldo 0x588(r1),r26
+0x32e0 <main+232>: ldil 0x3000,r31
+End of assembler dump.
+@end smallexample
+
+Some architectures have more than one commonly-used set of instruction
+mnemonics or other syntax.
+
+@table @code
+@kindex set disassembly-flavor
+@cindex assembly instructions
+@cindex instructions, assembly
+@cindex machine instructions
+@cindex listing machine instructions
+@cindex Intel disassembly flavor
+@cindex AT&T disassembly flavor
+@item set disassembly-flavor @var{instruction-set}
+Select the instruction set to use when disassembling the
+program via the @code{disassemble} or @code{x/i} commands.
+
+Currently this command is only defined for the Intel x86 family. You
+can set @var{instruction-set} to either @code{intel} or @code{att}.
+The default is @code{att}, the AT&T flavor used by default by Unix
+assemblers for x86-based targets.
+@end table
+
+
+@node Data
+@chapter Examining Data
+
+@cindex printing data
+@cindex examining data
+@kindex print
+@kindex inspect
+@c "inspect" is not quite a synonym if you are using Epoch, which we do not
+@c document because it is nonstandard... Under Epoch it displays in a
+@c different window or something like that.
+The usual way to examine data in your program is with the @code{print}
+command (abbreviated @code{p}), or its synonym @code{inspect}. It
+evaluates and prints the value of an expression of the language your
+program is written in (@pxref{Languages, ,Using @value{GDBN} with
+Different Languages}).
+
+@table @code
+@item print @var{expr}
+@itemx print /@var{f} @var{expr}
+@var{expr} is an expression (in the source language). By default the
+value of @var{expr} is printed in a format appropriate to its data type;
+you can choose a different format by specifying @samp{/@var{f}}, where
+@var{f} is a letter specifying the format; see @ref{Output Formats,,Output
+formats}.
+
+@item print
+@itemx print /@var{f}
+If you omit @var{expr}, @value{GDBN} displays the last value again (from the
+@dfn{value history}; @pxref{Value History, ,Value history}). This allows you to
+conveniently inspect the same value in an alternative format.
+@end table
+
+A more low-level way of examining data is with the @code{x} command.
+It examines data in memory at a specified address and prints it in a
+specified format. @xref{Memory, ,Examining memory}.
+
+If you are interested in information about types, or about how the
+fields of a struct or a class are declared, use the @code{ptype @var{exp}}
+command rather than @code{print}. @xref{Symbols, ,Examining the Symbol
+Table}.
+
+@menu
+* Expressions:: Expressions
+* Variables:: Program variables
+* Arrays:: Artificial arrays
+* Output Formats:: Output formats
+* Memory:: Examining memory
+* Auto Display:: Automatic display
+* Print Settings:: Print settings
+* Value History:: Value history
+* Convenience Vars:: Convenience variables
+* Registers:: Registers
+* Floating Point Hardware:: Floating point hardware
+* Memory Region Attributes:: Memory region attributes
+* Dump/Restore Files:: Copy between memory and a file
+@end menu
+
+@node Expressions
+@section Expressions
+
+@cindex expressions
+@code{print} and many other @value{GDBN} commands accept an expression and
+compute its value. Any kind of constant, variable or operator defined
+by the programming language you are using is valid in an expression in
+@value{GDBN}. This includes conditional expressions, function calls,
+casts, and string constants. It also includes preprocessor macros, if
+you compiled your program to include this information; see
+@ref{Compilation}.
+
+@value{GDBN} supports array constants in expressions input by
+the user. The syntax is @{@var{element}, @var{element}@dots{}@}. For example,
+you can use the command @code{print @{1, 2, 3@}} to build up an array in
+memory that is @code{malloc}ed in the target program.
+
+Because C is so widespread, most of the expressions shown in examples in
+this manual are in C. @xref{Languages, , Using @value{GDBN} with Different
+Languages}, for information on how to use expressions in other
+languages.
+
+In this section, we discuss operators that you can use in @value{GDBN}
+expressions regardless of your programming language.
+
+Casts are supported in all languages, not just in C, because it is so
+useful to cast a number into a pointer in order to examine a structure
+at that address in memory.
+@c FIXME: casts supported---Mod2 true?
+
+@value{GDBN} supports these operators, in addition to those common
+to programming languages:
+
+@table @code
+@item @@
+@samp{@@} is a binary operator for treating parts of memory as arrays.
+@xref{Arrays, ,Artificial arrays}, for more information.
+
+@item ::
+@samp{::} allows you to specify a variable in terms of the file or
+function where it is defined. @xref{Variables, ,Program variables}.
+
+@cindex @{@var{type}@}
+@cindex type casting memory
+@cindex memory, viewing as typed object
+@cindex casts, to view memory
+@item @{@var{type}@} @var{addr}
+Refers to an object of type @var{type} stored at address @var{addr} in
+memory. @var{addr} may be any expression whose value is an integer or
+pointer (but parentheses are required around binary operators, just as in
+a cast). This construct is allowed regardless of what kind of data is
+normally supposed to reside at @var{addr}.
+@end table
+
+@node Variables
+@section Program variables
+
+The most common kind of expression to use is the name of a variable
+in your program.
+
+Variables in expressions are understood in the selected stack frame
+(@pxref{Selection, ,Selecting a frame}); they must be either:
+
+@itemize @bullet
+@item
+global (or file-static)
+@end itemize
+
+@noindent or
+
+@itemize @bullet
+@item
+visible according to the scope rules of the
+programming language from the point of execution in that frame
+@end itemize
+
+@noindent This means that in the function
+
+@smallexample
+foo (a)
+ int a;
+@{
+ bar (a);
+ @{
+ int b = test ();
+ bar (b);
+ @}
+@}
+@end smallexample
+
+@noindent
+you can examine and use the variable @code{a} whenever your program is
+executing within the function @code{foo}, but you can only use or
+examine the variable @code{b} while your program is executing inside
+the block where @code{b} is declared.
+
+@cindex variable name conflict
+There is an exception: you can refer to a variable or function whose
+scope is a single source file even if the current execution point is not
+in this file. But it is possible to have more than one such variable or
+function with the same name (in different source files). If that
+happens, referring to that name has unpredictable effects. If you wish,
+you can specify a static variable in a particular function or file,
+using the colon-colon notation:
+
+@cindex colon-colon, context for variables/functions
+@iftex
+@c info cannot cope with a :: index entry, but why deprive hard copy readers?
+@cindex @code{::}, context for variables/functions
+@end iftex
+@smallexample
+@var{file}::@var{variable}
+@var{function}::@var{variable}
+@end smallexample
+
+@noindent
+Here @var{file} or @var{function} is the name of the context for the
+static @var{variable}. In the case of file names, you can use quotes to
+make sure @value{GDBN} parses the file name as a single word---for example,
+to print a global value of @code{x} defined in @file{f2.c}:
+
+@smallexample
+(@value{GDBP}) p 'f2.c'::x
+@end smallexample
+
+@cindex C@t{++} scope resolution
+This use of @samp{::} is very rarely in conflict with the very similar
+use of the same notation in C@t{++}. @value{GDBN} also supports use of the C@t{++}
+scope resolution operator in @value{GDBN} expressions.
+@c FIXME: Um, so what happens in one of those rare cases where it's in
+@c conflict?? --mew
+
+@cindex wrong values
+@cindex variable values, wrong
+@quotation
+@emph{Warning:} Occasionally, a local variable may appear to have the
+wrong value at certain points in a function---just after entry to a new
+scope, and just before exit.
+@end quotation
+You may see this problem when you are stepping by machine instructions.
+This is because, on most machines, it takes more than one instruction to
+set up a stack frame (including local variable definitions); if you are
+stepping by machine instructions, variables may appear to have the wrong
+values until the stack frame is completely built. On exit, it usually
+also takes more than one machine instruction to destroy a stack frame;
+after you begin stepping through that group of instructions, local
+variable definitions may be gone.
+
+This may also happen when the compiler does significant optimizations.
+To be sure of always seeing accurate values, turn off all optimization
+when compiling.
+
+@cindex ``No symbol "foo" in current context''
+Another possible effect of compiler optimizations is to optimize
+unused variables out of existence, or assign variables to registers (as
+opposed to memory addresses). Depending on the support for such cases
+offered by the debug info format used by the compiler, @value{GDBN}
+might not be able to display values for such local variables. If that
+happens, @value{GDBN} will print a message like this:
+
+@smallexample
+No symbol "foo" in current context.
+@end smallexample
+
+To solve such problems, either recompile without optimizations, or use a
+different debug info format, if the compiler supports several such
+formats. For example, @value{NGCC}, the @sc{gnu} C/C@t{++} compiler usually
+supports the @samp{-gstabs} option. @samp{-gstabs} produces debug info
+in a format that is superior to formats such as COFF. You may be able
+to use DWARF2 (@samp{-gdwarf-2}), which is also an effective form for
+debug info. See @ref{Debugging Options,,Options for Debugging Your
+Program or @sc{gnu} CC, gcc.info, Using @sc{gnu} CC}, for more
+information.
+
+
+@node Arrays
+@section Artificial arrays
+
+@cindex artificial array
+@kindex @@@r{, referencing memory as an array}
+It is often useful to print out several successive objects of the
+same type in memory; a section of an array, or an array of
+dynamically determined size for which only a pointer exists in the
+program.
+
+You can do this by referring to a contiguous span of memory as an
+@dfn{artificial array}, using the binary operator @samp{@@}. The left
+operand of @samp{@@} should be the first element of the desired array
+and be an individual object. The right operand should be the desired length
+of the array. The result is an array value whose elements are all of
+the type of the left argument. The first element is actually the left
+argument; the second element comes from bytes of memory immediately
+following those that hold the first element, and so on. Here is an
+example. If a program says
+
+@smallexample
+int *array = (int *) malloc (len * sizeof (int));
+@end smallexample
+
+@noindent
+you can print the contents of @code{array} with
+
+@smallexample
+p *array@@len
+@end smallexample
+
+The left operand of @samp{@@} must reside in memory. Array values made
+with @samp{@@} in this way behave just like other arrays in terms of
+subscripting, and are coerced to pointers when used in expressions.
+Artificial arrays most often appear in expressions via the value history
+(@pxref{Value History, ,Value history}), after printing one out.
+
+Another way to create an artificial array is to use a cast.
+This re-interprets a value as if it were an array.
+The value need not be in memory:
+@smallexample
+(@value{GDBP}) p/x (short[2])0x12345678
+$1 = @{0x1234, 0x5678@}
+@end smallexample
+
+As a convenience, if you leave the array length out (as in
+@samp{(@var{type}[])@var{value}}) @value{GDBN} calculates the size to fill
+the value (as @samp{sizeof(@var{value})/sizeof(@var{type})}:
+@smallexample
+(@value{GDBP}) p/x (short[])0x12345678
+$2 = @{0x1234, 0x5678@}
+@end smallexample
+
+Sometimes the artificial array mechanism is not quite enough; in
+moderately complex data structures, the elements of interest may not
+actually be adjacent---for example, if you are interested in the values
+of pointers in an array. One useful work-around in this situation is
+to use a convenience variable (@pxref{Convenience Vars, ,Convenience
+variables}) as a counter in an expression that prints the first
+interesting value, and then repeat that expression via @key{RET}. For
+instance, suppose you have an array @code{dtab} of pointers to
+structures, and you are interested in the values of a field @code{fv}
+in each structure. Here is an example of what you might type:
+
+@smallexample
+set $i = 0
+p dtab[$i++]->fv
+@key{RET}
+@key{RET}
+@dots{}
+@end smallexample
+
+@node Output Formats
+@section Output formats
+
+@cindex formatted output
+@cindex output formats
+By default, @value{GDBN} prints a value according to its data type. Sometimes
+this is not what you want. For example, you might want to print a number
+in hex, or a pointer in decimal. Or you might want to view data in memory
+at a certain address as a character string or as an instruction. To do
+these things, specify an @dfn{output format} when you print a value.
+
+The simplest use of output formats is to say how to print a value
+already computed. This is done by starting the arguments of the
+@code{print} command with a slash and a format letter. The format
+letters supported are:
+
+@table @code
+@item x
+Regard the bits of the value as an integer, and print the integer in
+hexadecimal.
+
+@item d
+Print as integer in signed decimal.
+
+@item u
+Print as integer in unsigned decimal.
+
+@item o
+Print as integer in octal.
+
+@item t
+Print as integer in binary. The letter @samp{t} stands for ``two''.
+@footnote{@samp{b} cannot be used because these format letters are also
+used with the @code{x} command, where @samp{b} stands for ``byte'';
+see @ref{Memory,,Examining memory}.}
+
+@item a
+@cindex unknown address, locating
+@cindex locate address
+Print as an address, both absolute in hexadecimal and as an offset from
+the nearest preceding symbol. You can use this format used to discover
+where (in what function) an unknown address is located:
+
+@smallexample
+(@value{GDBP}) p/a 0x54320
+$3 = 0x54320 <_initialize_vx+396>
+@end smallexample
+
+@noindent
+The command @code{info symbol 0x54320} yields similar results.
+@xref{Symbols, info symbol}.
+
+@item c
+Regard as an integer and print it as a character constant.
+
+@item f
+Regard the bits of the value as a floating point number and print
+using typical floating point syntax.
+@end table
+
+For example, to print the program counter in hex (@pxref{Registers}), type
+
+@smallexample
+p/x $pc
+@end smallexample
+
+@noindent
+Note that no space is required before the slash; this is because command
+names in @value{GDBN} cannot contain a slash.
+
+To reprint the last value in the value history with a different format,
+you can use the @code{print} command with just a format and no
+expression. For example, @samp{p/x} reprints the last value in hex.
+
+@node Memory
+@section Examining memory
+
+You can use the command @code{x} (for ``examine'') to examine memory in
+any of several formats, independently of your program's data types.
+
+@cindex examining memory
+@table @code
+@kindex x @r{(examine memory)}
+@item x/@var{nfu} @var{addr}
+@itemx x @var{addr}
+@itemx x
+Use the @code{x} command to examine memory.
+@end table
+
+@var{n}, @var{f}, and @var{u} are all optional parameters that specify how
+much memory to display and how to format it; @var{addr} is an
+expression giving the address where you want to start displaying memory.
+If you use defaults for @var{nfu}, you need not type the slash @samp{/}.
+Several commands set convenient defaults for @var{addr}.
+
+@table @r
+@item @var{n}, the repeat count
+The repeat count is a decimal integer; the default is 1. It specifies
+how much memory (counting by units @var{u}) to display.
+@c This really is **decimal**; unaffected by 'set radix' as of GDB
+@c 4.1.2.
+
+@item @var{f}, the display format
+The display format is one of the formats used by @code{print},
+@samp{s} (null-terminated string), or @samp{i} (machine instruction).
+The default is @samp{x} (hexadecimal) initially.
+The default changes each time you use either @code{x} or @code{print}.
+
+@item @var{u}, the unit size
+The unit size is any of
+
+@table @code
+@item b
+Bytes.
+@item h
+Halfwords (two bytes).
+@item w
+Words (four bytes). This is the initial default.
+@item g
+Giant words (eight bytes).
+@end table
+
+Each time you specify a unit size with @code{x}, that size becomes the
+default unit the next time you use @code{x}. (For the @samp{s} and
+@samp{i} formats, the unit size is ignored and is normally not written.)
+
+@item @var{addr}, starting display address
+@var{addr} is the address where you want @value{GDBN} to begin displaying
+memory. The expression need not have a pointer value (though it may);
+it is always interpreted as an integer address of a byte of memory.
+@xref{Expressions, ,Expressions}, for more information on expressions. The default for
+@var{addr} is usually just after the last address examined---but several
+other commands also set the default address: @code{info breakpoints} (to
+the address of the last breakpoint listed), @code{info line} (to the
+starting address of a line), and @code{print} (if you use it to display
+a value from memory).
+@end table
+
+For example, @samp{x/3uh 0x54320} is a request to display three halfwords
+(@code{h}) of memory, formatted as unsigned decimal integers (@samp{u}),
+starting at address @code{0x54320}. @samp{x/4xw $sp} prints the four
+words (@samp{w}) of memory above the stack pointer (here, @samp{$sp};
+@pxref{Registers, ,Registers}) in hexadecimal (@samp{x}).
+
+Since the letters indicating unit sizes are all distinct from the
+letters specifying output formats, you do not have to remember whether
+unit size or format comes first; either order works. The output
+specifications @samp{4xw} and @samp{4wx} mean exactly the same thing.
+(However, the count @var{n} must come first; @samp{wx4} does not work.)
+
+Even though the unit size @var{u} is ignored for the formats @samp{s}
+and @samp{i}, you might still want to use a count @var{n}; for example,
+@samp{3i} specifies that you want to see three machine instructions,
+including any operands. The command @code{disassemble} gives an
+alternative way of inspecting machine instructions; see @ref{Machine
+Code,,Source and machine code}.
+
+All the defaults for the arguments to @code{x} are designed to make it
+easy to continue scanning memory with minimal specifications each time
+you use @code{x}. For example, after you have inspected three machine
+instructions with @samp{x/3i @var{addr}}, you can inspect the next seven
+with just @samp{x/7}. If you use @key{RET} to repeat the @code{x} command,
+the repeat count @var{n} is used again; the other arguments default as
+for successive uses of @code{x}.
+
+@cindex @code{$_}, @code{$__}, and value history
+The addresses and contents printed by the @code{x} command are not saved
+in the value history because there is often too much of them and they
+would get in the way. Instead, @value{GDBN} makes these values available for
+subsequent use in expressions as values of the convenience variables
+@code{$_} and @code{$__}. After an @code{x} command, the last address
+examined is available for use in expressions in the convenience variable
+@code{$_}. The contents of that address, as examined, are available in
+the convenience variable @code{$__}.
+
+If the @code{x} command has a repeat count, the address and contents saved
+are from the last memory unit printed; this is not the same as the last
+address printed if several units were printed on the last line of output.
+
+@node Auto Display
+@section Automatic display
+@cindex automatic display
+@cindex display of expressions
+
+If you find that you want to print the value of an expression frequently
+(to see how it changes), you might want to add it to the @dfn{automatic
+display list} so that @value{GDBN} prints its value each time your program stops.
+Each expression added to the list is given a number to identify it;
+to remove an expression from the list, you specify that number.
+The automatic display looks like this:
+
+@smallexample
+2: foo = 38
+3: bar[5] = (struct hack *) 0x3804
+@end smallexample
+
+@noindent
+This display shows item numbers, expressions and their current values. As with
+displays you request manually using @code{x} or @code{print}, you can
+specify the output format you prefer; in fact, @code{display} decides
+whether to use @code{print} or @code{x} depending on how elaborate your
+format specification is---it uses @code{x} if you specify a unit size,
+or one of the two formats (@samp{i} and @samp{s}) that are only
+supported by @code{x}; otherwise it uses @code{print}.
+
+@table @code
+@kindex display
+@item display @var{expr}
+Add the expression @var{expr} to the list of expressions to display
+each time your program stops. @xref{Expressions, ,Expressions}.
+
+@code{display} does not repeat if you press @key{RET} again after using it.
+
+@item display/@var{fmt} @var{expr}
+For @var{fmt} specifying only a display format and not a size or
+count, add the expression @var{expr} to the auto-display list but
+arrange to display it each time in the specified format @var{fmt}.
+@xref{Output Formats,,Output formats}.
+
+@item display/@var{fmt} @var{addr}
+For @var{fmt} @samp{i} or @samp{s}, or including a unit-size or a
+number of units, add the expression @var{addr} as a memory address to
+be examined each time your program stops. Examining means in effect
+doing @samp{x/@var{fmt} @var{addr}}. @xref{Memory, ,Examining memory}.
+@end table
+
+For example, @samp{display/i $pc} can be helpful, to see the machine
+instruction about to be executed each time execution stops (@samp{$pc}
+is a common name for the program counter; @pxref{Registers, ,Registers}).
+
+@table @code
+@kindex delete display
+@kindex undisplay
+@item undisplay @var{dnums}@dots{}
+@itemx delete display @var{dnums}@dots{}
+Remove item numbers @var{dnums} from the list of expressions to display.
+
+@code{undisplay} does not repeat if you press @key{RET} after using it.
+(Otherwise you would just get the error @samp{No display number @dots{}}.)
+
+@kindex disable display
+@item disable display @var{dnums}@dots{}
+Disable the display of item numbers @var{dnums}. A disabled display
+item is not printed automatically, but is not forgotten. It may be
+enabled again later.
+
+@kindex enable display
+@item enable display @var{dnums}@dots{}
+Enable display of item numbers @var{dnums}. It becomes effective once
+again in auto display of its expression, until you specify otherwise.
+
+@item display
+Display the current values of the expressions on the list, just as is
+done when your program stops.
+
+@kindex info display
+@item info display
+Print the list of expressions previously set up to display
+automatically, each one with its item number, but without showing the
+values. This includes disabled expressions, which are marked as such.
+It also includes expressions which would not be displayed right now
+because they refer to automatic variables not currently available.
+@end table
+
+If a display expression refers to local variables, then it does not make
+sense outside the lexical context for which it was set up. Such an
+expression is disabled when execution enters a context where one of its
+variables is not defined. For example, if you give the command
+@code{display last_char} while inside a function with an argument
+@code{last_char}, @value{GDBN} displays this argument while your program
+continues to stop inside that function. When it stops elsewhere---where
+there is no variable @code{last_char}---the display is disabled
+automatically. The next time your program stops where @code{last_char}
+is meaningful, you can enable the display expression once again.
+
+@node Print Settings
+@section Print settings
+
+@cindex format options
+@cindex print settings
+@value{GDBN} provides the following ways to control how arrays, structures,
+and symbols are printed.
+
+@noindent
+These settings are useful for debugging programs in any language:
+
+@table @code
+@kindex set print address
+@item set print address
+@itemx set print address on
+@value{GDBN} prints memory addresses showing the location of stack
+traces, structure values, pointer values, breakpoints, and so forth,
+even when it also displays the contents of those addresses. The default
+is @code{on}. For example, this is what a stack frame display looks like with
+@code{set print address on}:
+
+@smallexample
+@group
+(@value{GDBP}) f
+#0 set_quotes (lq=0x34c78 "<<", rq=0x34c88 ">>")
+ at input.c:530
+530 if (lquote != def_lquote)
+@end group
+@end smallexample
+
+@item set print address off
+Do not print addresses when displaying their contents. For example,
+this is the same stack frame displayed with @code{set print address off}:
+
+@smallexample
+@group
+(@value{GDBP}) set print addr off
+(@value{GDBP}) f
+#0 set_quotes (lq="<<", rq=">>") at input.c:530
+530 if (lquote != def_lquote)
+@end group
+@end smallexample
+
+You can use @samp{set print address off} to eliminate all machine
+dependent displays from the @value{GDBN} interface. For example, with
+@code{print address off}, you should get the same text for backtraces on
+all machines---whether or not they involve pointer arguments.
+
+@kindex show print address
+@item show print address
+Show whether or not addresses are to be printed.
+@end table
+
+When @value{GDBN} prints a symbolic address, it normally prints the
+closest earlier symbol plus an offset. If that symbol does not uniquely
+identify the address (for example, it is a name whose scope is a single
+source file), you may need to clarify. One way to do this is with
+@code{info line}, for example @samp{info line *0x4537}. Alternately,
+you can set @value{GDBN} to print the source file and line number when
+it prints a symbolic address:
+
+@table @code
+@kindex set print symbol-filename
+@item set print symbol-filename on
+Tell @value{GDBN} to print the source file name and line number of a
+symbol in the symbolic form of an address.
+
+@item set print symbol-filename off
+Do not print source file name and line number of a symbol. This is the
+default.
+
+@kindex show print symbol-filename
+@item show print symbol-filename
+Show whether or not @value{GDBN} will print the source file name and
+line number of a symbol in the symbolic form of an address.
+@end table
+
+Another situation where it is helpful to show symbol filenames and line
+numbers is when disassembling code; @value{GDBN} shows you the line
+number and source file that corresponds to each instruction.
+
+Also, you may wish to see the symbolic form only if the address being
+printed is reasonably close to the closest earlier symbol:
+
+@table @code
+@kindex set print max-symbolic-offset
+@item set print max-symbolic-offset @var{max-offset}
+Tell @value{GDBN} to only display the symbolic form of an address if the
+offset between the closest earlier symbol and the address is less than
+@var{max-offset}. The default is 0, which tells @value{GDBN}
+to always print the symbolic form of an address if any symbol precedes it.
+
+@kindex show print max-symbolic-offset
+@item show print max-symbolic-offset
+Ask how large the maximum offset is that @value{GDBN} prints in a
+symbolic address.
+@end table
+
+@cindex wild pointer, interpreting
+@cindex pointer, finding referent
+If you have a pointer and you are not sure where it points, try
+@samp{set print symbol-filename on}. Then you can determine the name
+and source file location of the variable where it points, using
+@samp{p/a @var{pointer}}. This interprets the address in symbolic form.
+For example, here @value{GDBN} shows that a variable @code{ptt} points
+at another variable @code{t}, defined in @file{hi2.c}:
+
+@smallexample
+(@value{GDBP}) set print symbol-filename on
+(@value{GDBP}) p/a ptt
+$4 = 0xe008 <t in hi2.c>
+@end smallexample
+
+@quotation
+@emph{Warning:} For pointers that point to a local variable, @samp{p/a}
+does not show the symbol name and filename of the referent, even with
+the appropriate @code{set print} options turned on.
+@end quotation
+
+Other settings control how different kinds of objects are printed:
+
+@table @code
+@kindex set print array
+@item set print array
+@itemx set print array on
+Pretty print arrays. This format is more convenient to read,
+but uses more space. The default is off.
+
+@item set print array off
+Return to compressed format for arrays.
+
+@kindex show print array
+@item show print array
+Show whether compressed or pretty format is selected for displaying
+arrays.
+
+@kindex set print elements
+@item set print elements @var{number-of-elements}
+Set a limit on how many elements of an array @value{GDBN} will print.
+If @value{GDBN} is printing a large array, it stops printing after it has
+printed the number of elements set by the @code{set print elements} command.
+This limit also applies to the display of strings.
+When @value{GDBN} starts, this limit is set to 200.
+Setting @var{number-of-elements} to zero means that the printing is unlimited.
+
+@kindex show print elements
+@item show print elements
+Display the number of elements of a large array that @value{GDBN} will print.
+If the number is 0, then the printing is unlimited.
+
+@kindex set print null-stop
+@item set print null-stop
+Cause @value{GDBN} to stop printing the characters of an array when the first
+@sc{null} is encountered. This is useful when large arrays actually
+contain only short strings.
+The default is off.
+
+@kindex set print pretty
+@item set print pretty on
+Cause @value{GDBN} to print structures in an indented format with one member
+per line, like this:
+
+@smallexample
+@group
+$1 = @{
+ next = 0x0,
+ flags = @{
+ sweet = 1,
+ sour = 1
+ @},
+ meat = 0x54 "Pork"
+@}
+@end group
+@end smallexample
+
+@item set print pretty off
+Cause @value{GDBN} to print structures in a compact format, like this:
+
+@smallexample
+@group
+$1 = @{next = 0x0, flags = @{sweet = 1, sour = 1@}, \
+meat = 0x54 "Pork"@}
+@end group
+@end smallexample
+
+@noindent
+This is the default format.
+
+@kindex show print pretty
+@item show print pretty
+Show which format @value{GDBN} is using to print structures.
+
+@kindex set print sevenbit-strings
+@item set print sevenbit-strings on
+Print using only seven-bit characters; if this option is set,
+@value{GDBN} displays any eight-bit characters (in strings or
+character values) using the notation @code{\}@var{nnn}. This setting is
+best if you are working in English (@sc{ascii}) and you use the
+high-order bit of characters as a marker or ``meta'' bit.
+
+@item set print sevenbit-strings off
+Print full eight-bit characters. This allows the use of more
+international character sets, and is the default.
+
+@kindex show print sevenbit-strings
+@item show print sevenbit-strings
+Show whether or not @value{GDBN} is printing only seven-bit characters.
+
+@kindex set print union
+@item set print union on
+Tell @value{GDBN} to print unions which are contained in structures. This
+is the default setting.
+
+@item set print union off
+Tell @value{GDBN} not to print unions which are contained in structures.
+
+@kindex show print union
+@item show print union
+Ask @value{GDBN} whether or not it will print unions which are contained in
+structures.
+
+For example, given the declarations
+
+@smallexample
+typedef enum @{Tree, Bug@} Species;
+typedef enum @{Big_tree, Acorn, Seedling@} Tree_forms;
+typedef enum @{Caterpillar, Cocoon, Butterfly@}
+ Bug_forms;
+
+struct thing @{
+ Species it;
+ union @{
+ Tree_forms tree;
+ Bug_forms bug;
+ @} form;
+@};
+
+struct thing foo = @{Tree, @{Acorn@}@};
+@end smallexample
+
+@noindent
+with @code{set print union on} in effect @samp{p foo} would print
+
+@smallexample
+$1 = @{it = Tree, form = @{tree = Acorn, bug = Cocoon@}@}
+@end smallexample
+
+@noindent
+and with @code{set print union off} in effect it would print
+
+@smallexample
+$1 = @{it = Tree, form = @{...@}@}
+@end smallexample
+@end table
+
+@need 1000
+@noindent
+These settings are of interest when debugging C@t{++} programs:
+
+@table @code
+@cindex demangling
+@kindex set print demangle
+@item set print demangle
+@itemx set print demangle on
+Print C@t{++} names in their source form rather than in the encoded
+(``mangled'') form passed to the assembler and linker for type-safe
+linkage. The default is on.
+
+@kindex show print demangle
+@item show print demangle
+Show whether C@t{++} names are printed in mangled or demangled form.
+
+@kindex set print asm-demangle
+@item set print asm-demangle
+@itemx set print asm-demangle on
+Print C@t{++} names in their source form rather than their mangled form, even
+in assembler code printouts such as instruction disassemblies.
+The default is off.
+
+@kindex show print asm-demangle
+@item show print asm-demangle
+Show whether C@t{++} names in assembly listings are printed in mangled
+or demangled form.
+
+@kindex set demangle-style
+@cindex C@t{++} symbol decoding style
+@cindex symbol decoding style, C@t{++}
+@item set demangle-style @var{style}
+Choose among several encoding schemes used by different compilers to
+represent C@t{++} names. The choices for @var{style} are currently:
+
+@table @code
+@item auto
+Allow @value{GDBN} to choose a decoding style by inspecting your program.
+
+@item gnu
+Decode based on the @sc{gnu} C@t{++} compiler (@code{g++}) encoding algorithm.
+This is the default.
+
+@item hp
+Decode based on the HP ANSI C@t{++} (@code{aCC}) encoding algorithm.
+
+@item lucid
+Decode based on the Lucid C@t{++} compiler (@code{lcc}) encoding algorithm.
+
+@item arm
+Decode using the algorithm in the @cite{C@t{++} Annotated Reference Manual}.
+@strong{Warning:} this setting alone is not sufficient to allow
+debugging @code{cfront}-generated executables. @value{GDBN} would
+require further enhancement to permit that.
+
+@end table
+If you omit @var{style}, you will see a list of possible formats.
+
+@kindex show demangle-style
+@item show demangle-style
+Display the encoding style currently in use for decoding C@t{++} symbols.
+
+@kindex set print object
+@item set print object
+@itemx set print object on
+When displaying a pointer to an object, identify the @emph{actual}
+(derived) type of the object rather than the @emph{declared} type, using
+the virtual function table.
+
+@item set print object off
+Display only the declared type of objects, without reference to the
+virtual function table. This is the default setting.
+
+@kindex show print object
+@item show print object
+Show whether actual, or declared, object types are displayed.
+
+@kindex set print static-members
+@item set print static-members
+@itemx set print static-members on
+Print static members when displaying a C@t{++} object. The default is on.
+
+@item set print static-members off
+Do not print static members when displaying a C@t{++} object.
+
+@kindex show print static-members
+@item show print static-members
+Show whether C@t{++} static members are printed, or not.
+
+@c These don't work with HP ANSI C++ yet.
+@kindex set print vtbl
+@item set print vtbl
+@itemx set print vtbl on
+Pretty print C@t{++} virtual function tables. The default is off.
+(The @code{vtbl} commands do not work on programs compiled with the HP
+ANSI C@t{++} compiler (@code{aCC}).)
+
+@item set print vtbl off
+Do not pretty print C@t{++} virtual function tables.
+
+@kindex show print vtbl
+@item show print vtbl
+Show whether C@t{++} virtual function tables are pretty printed, or not.
+@end table
+
+@node Value History
+@section Value history
+
+@cindex value history
+Values printed by the @code{print} command are saved in the @value{GDBN}
+@dfn{value history}. This allows you to refer to them in other expressions.
+Values are kept until the symbol table is re-read or discarded
+(for example with the @code{file} or @code{symbol-file} commands).
+When the symbol table changes, the value history is discarded,
+since the values may contain pointers back to the types defined in the
+symbol table.
+
+@cindex @code{$}
+@cindex @code{$$}
+@cindex history number
+The values printed are given @dfn{history numbers} by which you can
+refer to them. These are successive integers starting with one.
+@code{print} shows you the history number assigned to a value by
+printing @samp{$@var{num} = } before the value; here @var{num} is the
+history number.
+
+To refer to any previous value, use @samp{$} followed by the value's
+history number. The way @code{print} labels its output is designed to
+remind you of this. Just @code{$} refers to the most recent value in
+the history, and @code{$$} refers to the value before that.
+@code{$$@var{n}} refers to the @var{n}th value from the end; @code{$$2}
+is the value just prior to @code{$$}, @code{$$1} is equivalent to
+@code{$$}, and @code{$$0} is equivalent to @code{$}.
+
+For example, suppose you have just printed a pointer to a structure and
+want to see the contents of the structure. It suffices to type
+
+@smallexample
+p *$
+@end smallexample
+
+If you have a chain of structures where the component @code{next} points
+to the next one, you can print the contents of the next one with this:
+
+@smallexample
+p *$.next
+@end smallexample
+
+@noindent
+You can print successive links in the chain by repeating this
+command---which you can do by just typing @key{RET}.
+
+Note that the history records values, not expressions. If the value of
+@code{x} is 4 and you type these commands:
+
+@smallexample
+print x
+set x=5
+@end smallexample
+
+@noindent
+then the value recorded in the value history by the @code{print} command
+remains 4 even though the value of @code{x} has changed.
+
+@table @code
+@kindex show values
+@item show values
+Print the last ten values in the value history, with their item numbers.
+This is like @samp{p@ $$9} repeated ten times, except that @code{show
+values} does not change the history.
+
+@item show values @var{n}
+Print ten history values centered on history item number @var{n}.
+
+@item show values +
+Print ten history values just after the values last printed. If no more
+values are available, @code{show values +} produces no display.
+@end table
+
+Pressing @key{RET} to repeat @code{show values @var{n}} has exactly the
+same effect as @samp{show values +}.
+
+@node Convenience Vars
+@section Convenience variables
+
+@cindex convenience variables
+@value{GDBN} provides @dfn{convenience variables} that you can use within
+@value{GDBN} to hold on to a value and refer to it later. These variables
+exist entirely within @value{GDBN}; they are not part of your program, and
+setting a convenience variable has no direct effect on further execution
+of your program. That is why you can use them freely.
+
+Convenience variables are prefixed with @samp{$}. Any name preceded by
+@samp{$} can be used for a convenience variable, unless it is one of
+the predefined machine-specific register names (@pxref{Registers, ,Registers}).
+(Value history references, in contrast, are @emph{numbers} preceded
+by @samp{$}. @xref{Value History, ,Value history}.)
+
+You can save a value in a convenience variable with an assignment
+expression, just as you would set a variable in your program.
+For example:
+
+@smallexample
+set $foo = *object_ptr
+@end smallexample
+
+@noindent
+would save in @code{$foo} the value contained in the object pointed to by
+@code{object_ptr}.
+
+Using a convenience variable for the first time creates it, but its
+value is @code{void} until you assign a new value. You can alter the
+value with another assignment at any time.
+
+Convenience variables have no fixed types. You can assign a convenience
+variable any type of value, including structures and arrays, even if
+that variable already has a value of a different type. The convenience
+variable, when used as an expression, has the type of its current value.
+
+@table @code
+@kindex show convenience
+@item show convenience
+Print a list of convenience variables used so far, and their values.
+Abbreviated @code{show conv}.
+@end table
+
+One of the ways to use a convenience variable is as a counter to be
+incremented or a pointer to be advanced. For example, to print
+a field from successive elements of an array of structures:
+
+@smallexample
+set $i = 0
+print bar[$i++]->contents
+@end smallexample
+
+@noindent
+Repeat that command by typing @key{RET}.
+
+Some convenience variables are created automatically by @value{GDBN} and given
+values likely to be useful.
+
+@table @code
+@vindex $_@r{, convenience variable}
+@item $_
+The variable @code{$_} is automatically set by the @code{x} command to
+the last address examined (@pxref{Memory, ,Examining memory}). Other
+commands which provide a default address for @code{x} to examine also
+set @code{$_} to that address; these commands include @code{info line}
+and @code{info breakpoint}. The type of @code{$_} is @code{void *}
+except when set by the @code{x} command, in which case it is a pointer
+to the type of @code{$__}.
+
+@vindex $__@r{, convenience variable}
+@item $__
+The variable @code{$__} is automatically set by the @code{x} command
+to the value found in the last address examined. Its type is chosen
+to match the format in which the data was printed.
+
+@item $_exitcode
+@vindex $_exitcode@r{, convenience variable}
+The variable @code{$_exitcode} is automatically set to the exit code when
+the program being debugged terminates.
+@end table
+
+On HP-UX systems, if you refer to a function or variable name that
+begins with a dollar sign, @value{GDBN} searches for a user or system
+name first, before it searches for a convenience variable.
+
+@node Registers
+@section Registers
+
+@cindex registers
+You can refer to machine register contents, in expressions, as variables
+with names starting with @samp{$}. The names of registers are different
+for each machine; use @code{info registers} to see the names used on
+your machine.
+
+@table @code
+@kindex info registers
+@item info registers
+Print the names and values of all registers except floating-point
+registers (in the selected stack frame).
+
+@kindex info all-registers
+@cindex floating point registers
+@item info all-registers
+Print the names and values of all registers, including floating-point
+registers.
+
+@item info registers @var{regname} @dots{}
+Print the @dfn{relativized} value of each specified register @var{regname}.
+As discussed in detail below, register values are normally relative to
+the selected stack frame. @var{regname} may be any register name valid on
+the machine you are using, with or without the initial @samp{$}.
+@end table
+
+@value{GDBN} has four ``standard'' register names that are available (in
+expressions) on most machines---whenever they do not conflict with an
+architecture's canonical mnemonics for registers. The register names
+@code{$pc} and @code{$sp} are used for the program counter register and
+the stack pointer. @code{$fp} is used for a register that contains a
+pointer to the current stack frame, and @code{$ps} is used for a
+register that contains the processor status. For example,
+you could print the program counter in hex with
+
+@smallexample
+p/x $pc
+@end smallexample
+
+@noindent
+or print the instruction to be executed next with
+
+@smallexample
+x/i $pc
+@end smallexample
+
+@noindent
+or add four to the stack pointer@footnote{This is a way of removing
+one word from the stack, on machines where stacks grow downward in
+memory (most machines, nowadays). This assumes that the innermost
+stack frame is selected; setting @code{$sp} is not allowed when other
+stack frames are selected. To pop entire frames off the stack,
+regardless of machine architecture, use @code{return};
+see @ref{Returning, ,Returning from a function}.} with
+
+@smallexample
+set $sp += 4
+@end smallexample
+
+Whenever possible, these four standard register names are available on
+your machine even though the machine has different canonical mnemonics,
+so long as there is no conflict. The @code{info registers} command
+shows the canonical names. For example, on the SPARC, @code{info
+registers} displays the processor status register as @code{$psr} but you
+can also refer to it as @code{$ps}; and on x86-based machines @code{$ps}
+is an alias for the @sc{eflags} register.
+
+@value{GDBN} always considers the contents of an ordinary register as an
+integer when the register is examined in this way. Some machines have
+special registers which can hold nothing but floating point; these
+registers are considered to have floating point values. There is no way
+to refer to the contents of an ordinary register as floating point value
+(although you can @emph{print} it as a floating point value with
+@samp{print/f $@var{regname}}).
+
+Some registers have distinct ``raw'' and ``virtual'' data formats. This
+means that the data format in which the register contents are saved by
+the operating system is not the same one that your program normally
+sees. For example, the registers of the 68881 floating point
+coprocessor are always saved in ``extended'' (raw) format, but all C
+programs expect to work with ``double'' (virtual) format. In such
+cases, @value{GDBN} normally works with the virtual format only (the format
+that makes sense for your program), but the @code{info registers} command
+prints the data in both formats.
+
+Normally, register values are relative to the selected stack frame
+(@pxref{Selection, ,Selecting a frame}). This means that you get the
+value that the register would contain if all stack frames farther in
+were exited and their saved registers restored. In order to see the
+true contents of hardware registers, you must select the innermost
+frame (with @samp{frame 0}).
+
+However, @value{GDBN} must deduce where registers are saved, from the machine
+code generated by your compiler. If some registers are not saved, or if
+@value{GDBN} is unable to locate the saved registers, the selected stack
+frame makes no difference.
+
+@node Floating Point Hardware
+@section Floating point hardware
+@cindex floating point
+
+Depending on the configuration, @value{GDBN} may be able to give
+you more information about the status of the floating point hardware.
+
+@table @code
+@kindex info float
+@item info float
+Display hardware-dependent information about the floating
+point unit. The exact contents and layout vary depending on the
+floating point chip. Currently, @samp{info float} is supported on
+the ARM and x86 machines.
+@end table
+
+@node Memory Region Attributes
+@section Memory region attributes
+@cindex memory region attributes
+
+@dfn{Memory region attributes} allow you to describe special handling
+required by regions of your target's memory. @value{GDBN} uses attributes
+to determine whether to allow certain types of memory accesses; whether to
+use specific width accesses; and whether to cache target memory.
+
+Defined memory regions can be individually enabled and disabled. When a
+memory region is disabled, @value{GDBN} uses the default attributes when
+accessing memory in that region. Similarly, if no memory regions have
+been defined, @value{GDBN} uses the default attributes when accessing
+all memory.
+
+When a memory region is defined, it is given a number to identify it;
+to enable, disable, or remove a memory region, you specify that number.
+
+@table @code
+@kindex mem
+@item mem @var{address1} @var{address2} @var{attributes}@dots{}
+Define memory region bounded by @var{address1} and @var{address2}
+with attributes @var{attributes}@dots{}.
+
+@kindex delete mem
+@item delete mem @var{nums}@dots{}
+Remove memory regions @var{nums}@dots{}.
+
+@kindex disable mem
+@item disable mem @var{nums}@dots{}
+Disable memory regions @var{nums}@dots{}.
+A disabled memory region is not forgotten.
+It may be enabled again later.
+
+@kindex enable mem
+@item enable mem @var{nums}@dots{}
+Enable memory regions @var{nums}@dots{}.
+
+@kindex info mem
+@item info mem
+Print a table of all defined memory regions, with the following columns
+for each region.
+
+@table @emph
+@item Memory Region Number
+@item Enabled or Disabled.
+Enabled memory regions are marked with @samp{y}.
+Disabled memory regions are marked with @samp{n}.
+
+@item Lo Address
+The address defining the inclusive lower bound of the memory region.
+
+@item Hi Address
+The address defining the exclusive upper bound of the memory region.
+
+@item Attributes
+The list of attributes set for this memory region.
+@end table
+@end table
+
+
+@subsection Attributes
+
+@subsubsection Memory Access Mode
+The access mode attributes set whether @value{GDBN} may make read or
+write accesses to a memory region.
+
+While these attributes prevent @value{GDBN} from performing invalid
+memory accesses, they do nothing to prevent the target system, I/O DMA,
+etc. from accessing memory.
+
+@table @code
+@item ro
+Memory is read only.
+@item wo
+Memory is write only.
+@item rw
+Memory is read/write. This is the default.
+@end table
+
+@subsubsection Memory Access Size
+The acccess size attributes tells @value{GDBN} to use specific sized
+accesses in the memory region. Often memory mapped device registers
+require specific sized accesses. If no access size attribute is
+specified, @value{GDBN} may use accesses of any size.
+
+@table @code
+@item 8
+Use 8 bit memory accesses.
+@item 16
+Use 16 bit memory accesses.
+@item 32
+Use 32 bit memory accesses.
+@item 64
+Use 64 bit memory accesses.
+@end table
+
+@c @subsubsection Hardware/Software Breakpoints
+@c The hardware/software breakpoint attributes set whether @value{GDBN}
+@c will use hardware or software breakpoints for the internal breakpoints
+@c used by the step, next, finish, until, etc. commands.
+@c
+@c @table @code
+@c @item hwbreak
+@c Always use hardware breakpoints
+@c @item swbreak (default)
+@c @end table
+
+@subsubsection Data Cache
+The data cache attributes set whether @value{GDBN} will cache target
+memory. While this generally improves performance by reducing debug
+protocol overhead, it can lead to incorrect results because @value{GDBN}
+does not know about volatile variables or memory mapped device
+registers.
+
+@table @code
+@item cache
+Enable @value{GDBN} to cache target memory.
+@item nocache
+Disable @value{GDBN} from caching target memory. This is the default.
+@end table
+
+@c @subsubsection Memory Write Verification
+@c The memory write verification attributes set whether @value{GDBN}
+@c will re-reads data after each write to verify the write was successful.
+@c
+@c @table @code
+@c @item verify
+@c @item noverify (default)
+@c @end table
+
+@node Dump/Restore Files
+@section Copy between memory and a file
+@cindex dump/restore files
+@cindex append data to a file
+@cindex dump data to a file
+@cindex restore data from a file
+@kindex dump
+@kindex append
+@kindex restore
+
+The commands @code{dump}, @code{append}, and @code{restore} are used
+for copying data between target memory and a file. Data is written
+into a file using @code{dump} or @code{append}, and restored from a
+file into memory by using @code{restore}. Files may be binary, srec,
+intel hex, or tekhex (but only binary files can be appended).
+
+@table @code
+@kindex dump binary
+@kindex append binary
+@item dump binary memory @var{filename} @var{start_addr} @var{end_addr}
+Dump contents of memory from @var{start_addr} to @var{end_addr} into
+raw binary format file @var{filename}.
+
+@item append binary memory @var{filename} @var{start_addr} @var{end_addr}
+Append contents of memory from @var{start_addr} to @var{end_addr} to
+raw binary format file @var{filename}.
+
+@item dump binary value @var{filename} @var{expression}
+Dump value of @var{expression} into raw binary format file @var{filename}.
+
+@item append binary memory @var{filename} @var{expression}
+Append value of @var{expression} to raw binary format file @var{filename}.
+
+@kindex dump ihex
+@item dump ihex memory @var{filename} @var{start_addr} @var{end_addr}
+Dump contents of memory from @var{start_addr} to @var{end_addr} into
+intel hex format file @var{filename}.
+
+@item dump ihex value @var{filename} @var{expression}
+Dump value of @var{expression} into intel hex format file @var{filename}.
+
+@kindex dump srec
+@item dump srec memory @var{filename} @var{start_addr} @var{end_addr}
+Dump contents of memory from @var{start_addr} to @var{end_addr} into
+srec format file @var{filename}.
+
+@item dump srec value @var{filename} @var{expression}
+Dump value of @var{expression} into srec format file @var{filename}.
+
+@kindex dump tekhex
+@item dump tekhex memory @var{filename} @var{start_addr} @var{end_addr}
+Dump contents of memory from @var{start_addr} to @var{end_addr} into
+tekhex format file @var{filename}.
+
+@item dump tekhex value @var{filename} @var{expression}
+Dump value of @var{expression} into tekhex format file @var{filename}.
+
+@item restore @var{filename} @var{[binary]} @var{bias} @var{start} @var{end}
+Restore the contents of file @var{filename} into memory. The @code{restore}
+command can automatically recognize any known bfd file format, except for
+raw binary. To restore a raw binary file you must use the optional argument
+@var{binary} after the filename.
+
+If @var{bias} is non-zero, its value will be added to the addresses
+contained in the file. Binary files always start at address zero, so
+they will be restored at address @var{bias}. Other bfd files have
+a built-in location; they will be restored at offset @var{bias}
+from that location.
+
+If @var{start} and/or @var{end} are non-zero, then only data between
+file offset @var{start} and file offset @var{end} will be restored.
+These offsets are relative to the addresses in the file, before
+the @var{bias} argument is applied.
+
+@end table
+
+@node Macros
+@chapter C Preprocessor Macros
+
+Some languages, such as C and C++, provide a way to define and invoke
+``preprocessor macros'' which expand into strings of tokens.
+@value{GDBN} can evaluate expressions containing macro invocations, show
+the result of macro expansion, and show a macro's definition, including
+where it was defined.
+
+You may need to compile your program specially to provide @value{GDBN}
+with information about preprocessor macros. Most compilers do not
+include macros in their debugging information, even when you compile
+with the @option{-g} flag. @xref{Compilation}.
+
+A program may define a macro at one point, remove that definition later,
+and then provide a different definition after that. Thus, at different
+points in the program, a macro may have different definitions, or have
+no definition at all. If there is a current stack frame, @value{GDBN}
+uses the macros in scope at that frame's source code line. Otherwise,
+@value{GDBN} uses the macros in scope at the current listing location;
+see @ref{List}.
+
+At the moment, @value{GDBN} does not support the @code{##}
+token-splicing operator, the @code{#} stringification operator, or
+variable-arity macros.
+
+Whenever @value{GDBN} evaluates an expression, it always expands any
+macro invocations present in the expression. @value{GDBN} also provides
+the following commands for working with macros explicitly.
+
+@table @code
+
+@kindex macro expand
+@cindex macro expansion, showing the results of preprocessor
+@cindex preprocessor macro expansion, showing the results of
+@cindex expanding preprocessor macros
+@item macro expand @var{expression}
+@itemx macro exp @var{expression}
+Show the results of expanding all preprocessor macro invocations in
+@var{expression}. Since @value{GDBN} simply expands macros, but does
+not parse the result, @var{expression} need not be a valid expression;
+it can be any string of tokens.
+
+@kindex macro expand-once
+@item macro expand-once @var{expression}
+@itemx macro exp1 @var{expression}
+@i{(This command is not yet implemented.)} Show the results of
+expanding those preprocessor macro invocations that appear explicitly in
+@var{expression}. Macro invocations appearing in that expansion are
+left unchanged. This command allows you to see the effect of a
+particular macro more clearly, without being confused by further
+expansions. Since @value{GDBN} simply expands macros, but does not
+parse the result, @var{expression} need not be a valid expression; it
+can be any string of tokens.
+
+@kindex show macro
+@cindex macro definition, showing
+@cindex definition, showing a macro's
+@item show macro @var{macro}
+Show the definition of the macro named @var{macro}, and describe the
+source location where that definition was established.
+
+@kindex macro define
+@cindex user-defined macros
+@cindex defining macros interactively
+@cindex macros, user-defined
+@item macro define @var{macro} @var{replacement-list}
+@itemx macro define @var{macro}(@var{arglist}) @var{replacement-list}
+@i{(This command is not yet implemented.)} Introduce a definition for a
+preprocessor macro named @var{macro}, invocations of which are replaced
+by the tokens given in @var{replacement-list}. The first form of this
+command defines an ``object-like'' macro, which takes no arguments; the
+second form defines a ``function-like'' macro, which takes the arguments
+given in @var{arglist}.
+
+A definition introduced by this command is in scope in every expression
+evaluated in @value{GDBN}, until it is removed with the @command{macro
+undef} command, described below. The definition overrides all
+definitions for @var{macro} present in the program being debugged, as
+well as any previous user-supplied definition.
+
+@kindex macro undef
+@item macro undef @var{macro}
+@i{(This command is not yet implemented.)} Remove any user-supplied
+definition for the macro named @var{macro}. This command only affects
+definitions provided with the @command{macro define} command, described
+above; it cannot remove definitions present in the program being
+debugged.
+
+@end table
+
+@cindex macros, example of debugging with
+Here is a transcript showing the above commands in action. First, we
+show our source files:
+
+@smallexample
+$ cat sample.c
+#include <stdio.h>
+#include "sample.h"
+
+#define M 42
+#define ADD(x) (M + x)
+
+main ()
+@{
+#define N 28
+ printf ("Hello, world!\n");
+#undef N
+ printf ("We're so creative.\n");
+#define N 1729
+ printf ("Goodbye, world!\n");
+@}
+$ cat sample.h
+#define Q <
+$
+@end smallexample
+
+Now, we compile the program using the @sc{gnu} C compiler, @value{NGCC}.
+We pass the @option{-gdwarf-2} and @option{-g3} flags to ensure the
+compiler includes information about preprocessor macros in the debugging
+information.
+
+@smallexample
+$ gcc -gdwarf-2 -g3 sample.c -o sample
+$
+@end smallexample
+
+Now, we start @value{GDBN} on our sample program:
+
+@smallexample
+$ gdb -nw sample
+GNU gdb 2002-05-06-cvs
+Copyright 2002 Free Software Foundation, Inc.
+GDB is free software, @dots{}
+(gdb)
+@end smallexample
+
+We can expand macros and examine their definitions, even when the
+program is not running. @value{GDBN} uses the current listing position
+to decide which macro definitions are in scope:
+
+@smallexample
+(gdb) list main
+3
+4 #define M 42
+5 #define ADD(x) (M + x)
+6
+7 main ()
+8 @{
+9 #define N 28
+10 printf ("Hello, world!\n");
+11 #undef N
+12 printf ("We're so creative.\n");
+(gdb) show macro ADD
+Defined at /home/jimb/gdb/macros/play/sample.c:5
+#define ADD(x) (M + x)
+(gdb) show macro Q
+Defined at /home/jimb/gdb/macros/play/sample.h:1
+ included at /home/jimb/gdb/macros/play/sample.c:2
+#define Q <
+(gdb) macro expand ADD(1)
+expands to: (42 + 1)
+(gdb) macro expand-once ADD(1)
+expands to: once (M + 1)
+(gdb)
+@end smallexample
+
+In the example above, note that @command{macro expand-once} expands only
+the macro invocation explicit in the original text --- the invocation of
+@code{ADD} --- but does not expand the invocation of the macro @code{M},
+which was introduced by @code{ADD}.
+
+Once the program is running, GDB uses the macro definitions in force at
+the source line of the current stack frame:
+
+@smallexample
+(gdb) break main
+Breakpoint 1 at 0x8048370: file sample.c, line 10.
+(gdb) run
+Starting program: /home/jimb/gdb/macros/play/sample
+
+Breakpoint 1, main () at sample.c:10
+10 printf ("Hello, world!\n");
+(gdb)
+@end smallexample
+
+At line 10, the definition of the macro @code{N} at line 9 is in force:
+
+@smallexample
+(gdb) show macro N
+Defined at /home/jimb/gdb/macros/play/sample.c:9
+#define N 28
+(gdb) macro expand N Q M
+expands to: 28 < 42
+(gdb) print N Q M
+$1 = 1
+(gdb)
+@end smallexample
+
+As we step over directives that remove @code{N}'s definition, and then
+give it a new definition, @value{GDBN} finds the definition (or lack
+thereof) in force at each point:
+
+@smallexample
+(gdb) next
+Hello, world!
+12 printf ("We're so creative.\n");
+(gdb) show macro N
+The symbol `N' has no definition as a C/C++ preprocessor macro
+at /home/jimb/gdb/macros/play/sample.c:12
+(gdb) next
+We're so creative.
+14 printf ("Goodbye, world!\n");
+(gdb) show macro N
+Defined at /home/jimb/gdb/macros/play/sample.c:13
+#define N 1729
+(gdb) macro expand N Q M
+expands to: 1729 < 42
+(gdb) print N Q M
+$2 = 0
+(gdb)
+@end smallexample
+
+
+@node Tracepoints
+@chapter Tracepoints
+@c This chapter is based on the documentation written by Michael
+@c Snyder, David Taylor, Jim Blandy, and Elena Zannoni.
+
+@cindex tracepoints
+In some applications, it is not feasible for the debugger to interrupt
+the program's execution long enough for the developer to learn
+anything helpful about its behavior. If the program's correctness
+depends on its real-time behavior, delays introduced by a debugger
+might cause the program to change its behavior drastically, or perhaps
+fail, even when the code itself is correct. It is useful to be able
+to observe the program's behavior without interrupting it.
+
+Using @value{GDBN}'s @code{trace} and @code{collect} commands, you can
+specify locations in the program, called @dfn{tracepoints}, and
+arbitrary expressions to evaluate when those tracepoints are reached.
+Later, using the @code{tfind} command, you can examine the values
+those expressions had when the program hit the tracepoints. The
+expressions may also denote objects in memory---structures or arrays,
+for example---whose values @value{GDBN} should record; while visiting
+a particular tracepoint, you may inspect those objects as if they were
+in memory at that moment. However, because @value{GDBN} records these
+values without interacting with you, it can do so quickly and
+unobtrusively, hopefully not disturbing the program's behavior.
+
+The tracepoint facility is currently available only for remote
+targets. @xref{Targets}. In addition, your remote target must know how
+to collect trace data. This functionality is implemented in the remote
+stub; however, none of the stubs distributed with @value{GDBN} support
+tracepoints as of this writing.
+
+This chapter describes the tracepoint commands and features.
+
+@menu
+* Set Tracepoints::
+* Analyze Collected Data::
+* Tracepoint Variables::
+@end menu
+
+@node Set Tracepoints
+@section Commands to Set Tracepoints
+
+Before running such a @dfn{trace experiment}, an arbitrary number of
+tracepoints can be set. Like a breakpoint (@pxref{Set Breaks}), a
+tracepoint has a number assigned to it by @value{GDBN}. Like with
+breakpoints, tracepoint numbers are successive integers starting from
+one. Many of the commands associated with tracepoints take the
+tracepoint number as their argument, to identify which tracepoint to
+work on.
+
+For each tracepoint, you can specify, in advance, some arbitrary set
+of data that you want the target to collect in the trace buffer when
+it hits that tracepoint. The collected data can include registers,
+local variables, or global data. Later, you can use @value{GDBN}
+commands to examine the values these data had at the time the
+tracepoint was hit.
+
+This section describes commands to set tracepoints and associated
+conditions and actions.
+
+@menu
+* Create and Delete Tracepoints::
+* Enable and Disable Tracepoints::
+* Tracepoint Passcounts::
+* Tracepoint Actions::
+* Listing Tracepoints::
+* Starting and Stopping Trace Experiment::
+@end menu
+
+@node Create and Delete Tracepoints
+@subsection Create and Delete Tracepoints
+
+@table @code
+@cindex set tracepoint
+@kindex trace
+@item trace
+The @code{trace} command is very similar to the @code{break} command.
+Its argument can be a source line, a function name, or an address in
+the target program. @xref{Set Breaks}. The @code{trace} command
+defines a tracepoint, which is a point in the target program where the
+debugger will briefly stop, collect some data, and then allow the
+program to continue. Setting a tracepoint or changing its commands
+doesn't take effect until the next @code{tstart} command; thus, you
+cannot change the tracepoint attributes once a trace experiment is
+running.
+
+Here are some examples of using the @code{trace} command:
+
+@smallexample
+(@value{GDBP}) @b{trace foo.c:121} // a source file and line number
+
+(@value{GDBP}) @b{trace +2} // 2 lines forward
+
+(@value{GDBP}) @b{trace my_function} // first source line of function
+
+(@value{GDBP}) @b{trace *my_function} // EXACT start address of function
+
+(@value{GDBP}) @b{trace *0x2117c4} // an address
+@end smallexample
+
+@noindent
+You can abbreviate @code{trace} as @code{tr}.
+
+@vindex $tpnum
+@cindex last tracepoint number
+@cindex recent tracepoint number
+@cindex tracepoint number
+The convenience variable @code{$tpnum} records the tracepoint number
+of the most recently set tracepoint.
+
+@kindex delete tracepoint
+@cindex tracepoint deletion
+@item delete tracepoint @r{[}@var{num}@r{]}
+Permanently delete one or more tracepoints. With no argument, the
+default is to delete all tracepoints.
+
+Examples:
+
+@smallexample
+(@value{GDBP}) @b{delete trace 1 2 3} // remove three tracepoints
+
+(@value{GDBP}) @b{delete trace} // remove all tracepoints
+@end smallexample
+
+@noindent
+You can abbreviate this command as @code{del tr}.
+@end table
+
+@node Enable and Disable Tracepoints
+@subsection Enable and Disable Tracepoints
+
+@table @code
+@kindex disable tracepoint
+@item disable tracepoint @r{[}@var{num}@r{]}
+Disable tracepoint @var{num}, or all tracepoints if no argument
+@var{num} is given. A disabled tracepoint will have no effect during
+the next trace experiment, but it is not forgotten. You can re-enable
+a disabled tracepoint using the @code{enable tracepoint} command.
+
+@kindex enable tracepoint
+@item enable tracepoint @r{[}@var{num}@r{]}
+Enable tracepoint @var{num}, or all tracepoints. The enabled
+tracepoints will become effective the next time a trace experiment is
+run.
+@end table
+
+@node Tracepoint Passcounts
+@subsection Tracepoint Passcounts
+
+@table @code
+@kindex passcount
+@cindex tracepoint pass count
+@item passcount @r{[}@var{n} @r{[}@var{num}@r{]]}
+Set the @dfn{passcount} of a tracepoint. The passcount is a way to
+automatically stop a trace experiment. If a tracepoint's passcount is
+@var{n}, then the trace experiment will be automatically stopped on
+the @var{n}'th time that tracepoint is hit. If the tracepoint number
+@var{num} is not specified, the @code{passcount} command sets the
+passcount of the most recently defined tracepoint. If no passcount is
+given, the trace experiment will run until stopped explicitly by the
+user.
+
+Examples:
+
+@smallexample
+(@value{GDBP}) @b{passcount 5 2} // Stop on the 5th execution of
+@exdent @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @code{// tracepoint 2}
+
+(@value{GDBP}) @b{passcount 12} // Stop on the 12th execution of the
+@exdent @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @code{// most recently defined tracepoint.}
+(@value{GDBP}) @b{trace foo}
+(@value{GDBP}) @b{pass 3}
+(@value{GDBP}) @b{trace bar}
+(@value{GDBP}) @b{pass 2}
+(@value{GDBP}) @b{trace baz}
+(@value{GDBP}) @b{pass 1} // Stop tracing when foo has been
+@exdent @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @code{// executed 3 times OR when bar has}
+@exdent @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @code{// been executed 2 times}
+@exdent @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @code{// OR when baz has been executed 1 time.}
+@end smallexample
+@end table
+
+@node Tracepoint Actions
+@subsection Tracepoint Action Lists
+
+@table @code
+@kindex actions
+@cindex tracepoint actions
+@item actions @r{[}@var{num}@r{]}
+This command will prompt for a list of actions to be taken when the
+tracepoint is hit. If the tracepoint number @var{num} is not
+specified, this command sets the actions for the one that was most
+recently defined (so that you can define a tracepoint and then say
+@code{actions} without bothering about its number). You specify the
+actions themselves on the following lines, one action at a time, and
+terminate the actions list with a line containing just @code{end}. So
+far, the only defined actions are @code{collect} and
+@code{while-stepping}.
+
+@cindex remove actions from a tracepoint
+To remove all actions from a tracepoint, type @samp{actions @var{num}}
+and follow it immediately with @samp{end}.
+
+@smallexample
+(@value{GDBP}) @b{collect @var{data}} // collect some data
+
+(@value{GDBP}) @b{while-stepping 5} // single-step 5 times, collect data
+
+(@value{GDBP}) @b{end} // signals the end of actions.
+@end smallexample
+
+In the following example, the action list begins with @code{collect}
+commands indicating the things to be collected when the tracepoint is
+hit. Then, in order to single-step and collect additional data
+following the tracepoint, a @code{while-stepping} command is used,
+followed by the list of things to be collected while stepping. The
+@code{while-stepping} command is terminated by its own separate
+@code{end} command. Lastly, the action list is terminated by an
+@code{end} command.
+
+@smallexample
+(@value{GDBP}) @b{trace foo}
+(@value{GDBP}) @b{actions}
+Enter actions for tracepoint 1, one per line:
+> collect bar,baz
+> collect $regs
+> while-stepping 12
+ > collect $fp, $sp
+ > end
+end
+@end smallexample
+
+@kindex collect @r{(tracepoints)}
+@item collect @var{expr1}, @var{expr2}, @dots{}
+Collect values of the given expressions when the tracepoint is hit.
+This command accepts a comma-separated list of any valid expressions.
+In addition to global, static, or local variables, the following
+special arguments are supported:
+
+@table @code
+@item $regs
+collect all registers
+
+@item $args
+collect all function arguments
+
+@item $locals
+collect all local variables.
+@end table
+
+You can give several consecutive @code{collect} commands, each one
+with a single argument, or one @code{collect} command with several
+arguments separated by commas: the effect is the same.
+
+The command @code{info scope} (@pxref{Symbols, info scope}) is
+particularly useful for figuring out what data to collect.
+
+@kindex while-stepping @r{(tracepoints)}
+@item while-stepping @var{n}
+Perform @var{n} single-step traces after the tracepoint, collecting
+new data at each step. The @code{while-stepping} command is
+followed by the list of what to collect while stepping (followed by
+its own @code{end} command):
+
+@smallexample
+> while-stepping 12
+ > collect $regs, myglobal
+ > end
+>
+@end smallexample
+
+@noindent
+You may abbreviate @code{while-stepping} as @code{ws} or
+@code{stepping}.
+@end table
+
+@node Listing Tracepoints
+@subsection Listing Tracepoints
+
+@table @code
+@kindex info tracepoints
+@cindex information about tracepoints
+@item info tracepoints @r{[}@var{num}@r{]}
+Display information about the tracepoint @var{num}. If you don't specify
+a tracepoint number, displays information about all the tracepoints
+defined so far. For each tracepoint, the following information is
+shown:
+
+@itemize @bullet
+@item
+its number
+@item
+whether it is enabled or disabled
+@item
+its address
+@item
+its passcount as given by the @code{passcount @var{n}} command
+@item
+its step count as given by the @code{while-stepping @var{n}} command
+@item
+where in the source files is the tracepoint set
+@item
+its action list as given by the @code{actions} command
+@end itemize
+
+@smallexample
+(@value{GDBP}) @b{info trace}
+Num Enb Address PassC StepC What
+1 y 0x002117c4 0 0 <gdb_asm>
+2 y 0x0020dc64 0 0 in g_test at g_test.c:1375
+3 y 0x0020b1f4 0 0 in get_data at ../foo.c:41
+(@value{GDBP})
+@end smallexample
+
+@noindent
+This command can be abbreviated @code{info tp}.
+@end table
+
+@node Starting and Stopping Trace Experiment
+@subsection Starting and Stopping Trace Experiment
+
+@table @code
+@kindex tstart
+@cindex start a new trace experiment
+@cindex collected data discarded
+@item tstart
+This command takes no arguments. It starts the trace experiment, and
+begins collecting data. This has the side effect of discarding all
+the data collected in the trace buffer during the previous trace
+experiment.
+
+@kindex tstop
+@cindex stop a running trace experiment
+@item tstop
+This command takes no arguments. It ends the trace experiment, and
+stops collecting data.
+
+@strong{Note:} a trace experiment and data collection may stop
+automatically if any tracepoint's passcount is reached
+(@pxref{Tracepoint Passcounts}), or if the trace buffer becomes full.
+
+@kindex tstatus
+@cindex status of trace data collection
+@cindex trace experiment, status of
+@item tstatus
+This command displays the status of the current trace data
+collection.
+@end table
+
+Here is an example of the commands we described so far:
+
+@smallexample
+(@value{GDBP}) @b{trace gdb_c_test}
+(@value{GDBP}) @b{actions}
+Enter actions for tracepoint #1, one per line.
+> collect $regs,$locals,$args
+> while-stepping 11
+ > collect $regs
+ > end
+> end
+(@value{GDBP}) @b{tstart}
+ [time passes @dots{}]
+(@value{GDBP}) @b{tstop}
+@end smallexample
+
+
+@node Analyze Collected Data
+@section Using the collected data
+
+After the tracepoint experiment ends, you use @value{GDBN} commands
+for examining the trace data. The basic idea is that each tracepoint
+collects a trace @dfn{snapshot} every time it is hit and another
+snapshot every time it single-steps. All these snapshots are
+consecutively numbered from zero and go into a buffer, and you can
+examine them later. The way you examine them is to @dfn{focus} on a
+specific trace snapshot. When the remote stub is focused on a trace
+snapshot, it will respond to all @value{GDBN} requests for memory and
+registers by reading from the buffer which belongs to that snapshot,
+rather than from @emph{real} memory or registers of the program being
+debugged. This means that @strong{all} @value{GDBN} commands
+(@code{print}, @code{info registers}, @code{backtrace}, etc.) will
+behave as if we were currently debugging the program state as it was
+when the tracepoint occurred. Any requests for data that are not in
+the buffer will fail.
+
+@menu
+* tfind:: How to select a trace snapshot
+* tdump:: How to display all data for a snapshot
+* save-tracepoints:: How to save tracepoints for a future run
+@end menu
+
+@node tfind
+@subsection @code{tfind @var{n}}
+
+@kindex tfind
+@cindex select trace snapshot
+@cindex find trace snapshot
+The basic command for selecting a trace snapshot from the buffer is
+@code{tfind @var{n}}, which finds trace snapshot number @var{n},
+counting from zero. If no argument @var{n} is given, the next
+snapshot is selected.
+
+Here are the various forms of using the @code{tfind} command.
+
+@table @code
+@item tfind start
+Find the first snapshot in the buffer. This is a synonym for
+@code{tfind 0} (since 0 is the number of the first snapshot).
+
+@item tfind none
+Stop debugging trace snapshots, resume @emph{live} debugging.
+
+@item tfind end
+Same as @samp{tfind none}.
+
+@item tfind
+No argument means find the next trace snapshot.
+
+@item tfind -
+Find the previous trace snapshot before the current one. This permits
+retracing earlier steps.
+
+@item tfind tracepoint @var{num}
+Find the next snapshot associated with tracepoint @var{num}. Search
+proceeds forward from the last examined trace snapshot. If no
+argument @var{num} is given, it means find the next snapshot collected
+for the same tracepoint as the current snapshot.
+
+@item tfind pc @var{addr}
+Find the next snapshot associated with the value @var{addr} of the
+program counter. Search proceeds forward from the last examined trace
+snapshot. If no argument @var{addr} is given, it means find the next
+snapshot with the same value of PC as the current snapshot.
+
+@item tfind outside @var{addr1}, @var{addr2}
+Find the next snapshot whose PC is outside the given range of
+addresses.
+
+@item tfind range @var{addr1}, @var{addr2}
+Find the next snapshot whose PC is between @var{addr1} and
+@var{addr2}. @c FIXME: Is the range inclusive or exclusive?
+
+@item tfind line @r{[}@var{file}:@r{]}@var{n}
+Find the next snapshot associated with the source line @var{n}. If
+the optional argument @var{file} is given, refer to line @var{n} in
+that source file. Search proceeds forward from the last examined
+trace snapshot. If no argument @var{n} is given, it means find the
+next line other than the one currently being examined; thus saying
+@code{tfind line} repeatedly can appear to have the same effect as
+stepping from line to line in a @emph{live} debugging session.
+@end table
+
+The default arguments for the @code{tfind} commands are specifically
+designed to make it easy to scan through the trace buffer. For
+instance, @code{tfind} with no argument selects the next trace
+snapshot, and @code{tfind -} with no argument selects the previous
+trace snapshot. So, by giving one @code{tfind} command, and then
+simply hitting @key{RET} repeatedly you can examine all the trace
+snapshots in order. Or, by saying @code{tfind -} and then hitting
+@key{RET} repeatedly you can examine the snapshots in reverse order.
+The @code{tfind line} command with no argument selects the snapshot
+for the next source line executed. The @code{tfind pc} command with
+no argument selects the next snapshot with the same program counter
+(PC) as the current frame. The @code{tfind tracepoint} command with
+no argument selects the next trace snapshot collected by the same
+tracepoint as the current one.
+
+In addition to letting you scan through the trace buffer manually,
+these commands make it easy to construct @value{GDBN} scripts that
+scan through the trace buffer and print out whatever collected data
+you are interested in. Thus, if we want to examine the PC, FP, and SP
+registers from each trace frame in the buffer, we can say this:
+
+@smallexample
+(@value{GDBP}) @b{tfind start}
+(@value{GDBP}) @b{while ($trace_frame != -1)}
+> printf "Frame %d, PC = %08X, SP = %08X, FP = %08X\n", \
+ $trace_frame, $pc, $sp, $fp
+> tfind
+> end
+
+Frame 0, PC = 0020DC64, SP = 0030BF3C, FP = 0030BF44
+Frame 1, PC = 0020DC6C, SP = 0030BF38, FP = 0030BF44
+Frame 2, PC = 0020DC70, SP = 0030BF34, FP = 0030BF44
+Frame 3, PC = 0020DC74, SP = 0030BF30, FP = 0030BF44
+Frame 4, PC = 0020DC78, SP = 0030BF2C, FP = 0030BF44
+Frame 5, PC = 0020DC7C, SP = 0030BF28, FP = 0030BF44
+Frame 6, PC = 0020DC80, SP = 0030BF24, FP = 0030BF44
+Frame 7, PC = 0020DC84, SP = 0030BF20, FP = 0030BF44
+Frame 8, PC = 0020DC88, SP = 0030BF1C, FP = 0030BF44
+Frame 9, PC = 0020DC8E, SP = 0030BF18, FP = 0030BF44
+Frame 10, PC = 00203F6C, SP = 0030BE3C, FP = 0030BF14
+@end smallexample
+
+Or, if we want to examine the variable @code{X} at each source line in
+the buffer:
+
+@smallexample
+(@value{GDBP}) @b{tfind start}
+(@value{GDBP}) @b{while ($trace_frame != -1)}
+> printf "Frame %d, X == %d\n", $trace_frame, X
+> tfind line
+> end
+
+Frame 0, X = 1
+Frame 7, X = 2
+Frame 13, X = 255
+@end smallexample
+
+@node tdump
+@subsection @code{tdump}
+@kindex tdump
+@cindex dump all data collected at tracepoint
+@cindex tracepoint data, display
+
+This command takes no arguments. It prints all the data collected at
+the current trace snapshot.
+
+@smallexample
+(@value{GDBP}) @b{trace 444}
+(@value{GDBP}) @b{actions}
+Enter actions for tracepoint #2, one per line:
+> collect $regs, $locals, $args, gdb_long_test
+> end
+
+(@value{GDBP}) @b{tstart}
+
+(@value{GDBP}) @b{tfind line 444}
+#0 gdb_test (p1=0x11, p2=0x22, p3=0x33, p4=0x44, p5=0x55, p6=0x66)
+at gdb_test.c:444
+444 printp( "%s: arguments = 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n", )
+
+(@value{GDBP}) @b{tdump}
+Data collected at tracepoint 2, trace frame 1:
+d0 0xc4aa0085 -995491707
+d1 0x18 24
+d2 0x80 128
+d3 0x33 51
+d4 0x71aea3d 119204413
+d5 0x22 34
+d6 0xe0 224
+d7 0x380035 3670069
+a0 0x19e24a 1696330
+a1 0x3000668 50333288
+a2 0x100 256
+a3 0x322000 3284992
+a4 0x3000698 50333336
+a5 0x1ad3cc 1758156
+fp 0x30bf3c 0x30bf3c
+sp 0x30bf34 0x30bf34
+ps 0x0 0
+pc 0x20b2c8 0x20b2c8
+fpcontrol 0x0 0
+fpstatus 0x0 0
+fpiaddr 0x0 0
+p = 0x20e5b4 "gdb-test"
+p1 = (void *) 0x11
+p2 = (void *) 0x22
+p3 = (void *) 0x33
+p4 = (void *) 0x44
+p5 = (void *) 0x55
+p6 = (void *) 0x66
+gdb_long_test = 17 '\021'
+
+(@value{GDBP})
+@end smallexample
+
+@node save-tracepoints
+@subsection @code{save-tracepoints @var{filename}}
+@kindex save-tracepoints
+@cindex save tracepoints for future sessions
+
+This command saves all current tracepoint definitions together with
+their actions and passcounts, into a file @file{@var{filename}}
+suitable for use in a later debugging session. To read the saved
+tracepoint definitions, use the @code{source} command (@pxref{Command
+Files}).
+
+@node Tracepoint Variables
+@section Convenience Variables for Tracepoints
+@cindex tracepoint variables
+@cindex convenience variables for tracepoints
+
+@table @code
+@vindex $trace_frame
+@item (int) $trace_frame
+The current trace snapshot (a.k.a.@: @dfn{frame}) number, or -1 if no
+snapshot is selected.
+
+@vindex $tracepoint
+@item (int) $tracepoint
+The tracepoint for the current trace snapshot.
+
+@vindex $trace_line
+@item (int) $trace_line
+The line number for the current trace snapshot.
+
+@vindex $trace_file
+@item (char []) $trace_file
+The source file for the current trace snapshot.
+
+@vindex $trace_func
+@item (char []) $trace_func
+The name of the function containing @code{$tracepoint}.
+@end table
+
+Note: @code{$trace_file} is not suitable for use in @code{printf},
+use @code{output} instead.
+
+Here's a simple example of using these convenience variables for
+stepping through all the trace snapshots and printing some of their
+data.
+
+@smallexample
+(@value{GDBP}) @b{tfind start}
+
+(@value{GDBP}) @b{while $trace_frame != -1}
+> output $trace_file
+> printf ", line %d (tracepoint #%d)\n", $trace_line, $tracepoint
+> tfind
+> end
+@end smallexample
+
+@node Overlays
+@chapter Debugging Programs That Use Overlays
+@cindex overlays
+
+If your program is too large to fit completely in your target system's
+memory, you can sometimes use @dfn{overlays} to work around this
+problem. @value{GDBN} provides some support for debugging programs that
+use overlays.
+
+@menu
+* How Overlays Work:: A general explanation of overlays.
+* Overlay Commands:: Managing overlays in @value{GDBN}.
+* Automatic Overlay Debugging:: @value{GDBN} can find out which overlays are
+ mapped by asking the inferior.
+* Overlay Sample Program:: A sample program using overlays.
+@end menu
+
+@node How Overlays Work
+@section How Overlays Work
+@cindex mapped overlays
+@cindex unmapped overlays
+@cindex load address, overlay's
+@cindex mapped address
+@cindex overlay area
+
+Suppose you have a computer whose instruction address space is only 64
+kilobytes long, but which has much more memory which can be accessed by
+other means: special instructions, segment registers, or memory
+management hardware, for example. Suppose further that you want to
+adapt a program which is larger than 64 kilobytes to run on this system.
+
+One solution is to identify modules of your program which are relatively
+independent, and need not call each other directly; call these modules
+@dfn{overlays}. Separate the overlays from the main program, and place
+their machine code in the larger memory. Place your main program in
+instruction memory, but leave at least enough space there to hold the
+largest overlay as well.
+
+Now, to call a function located in an overlay, you must first copy that
+overlay's machine code from the large memory into the space set aside
+for it in the instruction memory, and then jump to its entry point
+there.
+
+@c NB: In the below the mapped area's size is greater or equal to the
+@c size of all overlays. This is intentional to remind the developer
+@c that overlays don't necessarily need to be the same size.
+
+@smallexample
+@group
+ Data Instruction Larger
+Address Space Address Space Address Space
++-----------+ +-----------+ +-----------+
+| | | | | |
++-----------+ +-----------+ +-----------+<-- overlay 1
+| program | | main | .----| overlay 1 | load address
+| variables | | program | | +-----------+
+| and heap | | | | | |
++-----------+ | | | +-----------+<-- overlay 2
+| | +-----------+ | | | load address
++-----------+ | | | .-| overlay 2 |
+ | | | | | |
+ mapped --->+-----------+ | | +-----------+
+ address | | | | | |
+ | overlay | <-' | | |
+ | area | <---' +-----------+<-- overlay 3
+ | | <---. | | load address
+ +-----------+ `--| overlay 3 |
+ | | | |
+ +-----------+ | |
+ +-----------+
+ | |
+ +-----------+
+
+ @anchor{A code overlay}A code overlay
+@end group
+@end smallexample
+
+The diagram (@pxref{A code overlay}) shows a system with separate data
+and instruction address spaces. To map an overlay, the program copies
+its code from the larger address space to the instruction address space.
+Since the overlays shown here all use the same mapped address, only one
+may be mapped at a time. For a system with a single address space for
+data and instructions, the diagram would be similar, except that the
+program variables and heap would share an address space with the main
+program and the overlay area.
+
+An overlay loaded into instruction memory and ready for use is called a
+@dfn{mapped} overlay; its @dfn{mapped address} is its address in the
+instruction memory. An overlay not present (or only partially present)
+in instruction memory is called @dfn{unmapped}; its @dfn{load address}
+is its address in the larger memory. The mapped address is also called
+the @dfn{virtual memory address}, or @dfn{VMA}; the load address is also
+called the @dfn{load memory address}, or @dfn{LMA}.
+
+Unfortunately, overlays are not a completely transparent way to adapt a
+program to limited instruction memory. They introduce a new set of
+global constraints you must keep in mind as you design your program:
+
+@itemize @bullet
+
+@item
+Before calling or returning to a function in an overlay, your program
+must make sure that overlay is actually mapped. Otherwise, the call or
+return will transfer control to the right address, but in the wrong
+overlay, and your program will probably crash.
+
+@item
+If the process of mapping an overlay is expensive on your system, you
+will need to choose your overlays carefully to minimize their effect on
+your program's performance.
+
+@item
+The executable file you load onto your system must contain each
+overlay's instructions, appearing at the overlay's load address, not its
+mapped address. However, each overlay's instructions must be relocated
+and its symbols defined as if the overlay were at its mapped address.
+You can use GNU linker scripts to specify different load and relocation
+addresses for pieces of your program; see @ref{Overlay Description,,,
+ld.info, Using ld: the GNU linker}.
+
+@item
+The procedure for loading executable files onto your system must be able
+to load their contents into the larger address space as well as the
+instruction and data spaces.
+
+@end itemize
+
+The overlay system described above is rather simple, and could be
+improved in many ways:
+
+@itemize @bullet
+
+@item
+If your system has suitable bank switch registers or memory management
+hardware, you could use those facilities to make an overlay's load area
+contents simply appear at their mapped address in instruction space.
+This would probably be faster than copying the overlay to its mapped
+area in the usual way.
+
+@item
+If your overlays are small enough, you could set aside more than one
+overlay area, and have more than one overlay mapped at a time.
+
+@item
+You can use overlays to manage data, as well as instructions. In
+general, data overlays are even less transparent to your design than
+code overlays: whereas code overlays only require care when you call or
+return to functions, data overlays require care every time you access
+the data. Also, if you change the contents of a data overlay, you
+must copy its contents back out to its load address before you can copy a
+different data overlay into the same mapped area.
+
+@end itemize
+
+
+@node Overlay Commands
+@section Overlay Commands
+
+To use @value{GDBN}'s overlay support, each overlay in your program must
+correspond to a separate section of the executable file. The section's
+virtual memory address and load memory address must be the overlay's
+mapped and load addresses. Identifying overlays with sections allows
+@value{GDBN} to determine the appropriate address of a function or
+variable, depending on whether the overlay is mapped or not.
+
+@value{GDBN}'s overlay commands all start with the word @code{overlay};
+you can abbreviate this as @code{ov} or @code{ovly}. The commands are:
+
+@table @code
+@item overlay off
+@kindex overlay off
+Disable @value{GDBN}'s overlay support. When overlay support is
+disabled, @value{GDBN} assumes that all functions and variables are
+always present at their mapped addresses. By default, @value{GDBN}'s
+overlay support is disabled.
+
+@item overlay manual
+@kindex overlay manual
+@cindex manual overlay debugging
+Enable @dfn{manual} overlay debugging. In this mode, @value{GDBN}
+relies on you to tell it which overlays are mapped, and which are not,
+using the @code{overlay map-overlay} and @code{overlay unmap-overlay}
+commands described below.
+
+@item overlay map-overlay @var{overlay}
+@itemx overlay map @var{overlay}
+@kindex overlay map-overlay
+@cindex map an overlay
+Tell @value{GDBN} that @var{overlay} is now mapped; @var{overlay} must
+be the name of the object file section containing the overlay. When an
+overlay is mapped, @value{GDBN} assumes it can find the overlay's
+functions and variables at their mapped addresses. @value{GDBN} assumes
+that any other overlays whose mapped ranges overlap that of
+@var{overlay} are now unmapped.
+
+@item overlay unmap-overlay @var{overlay}
+@itemx overlay unmap @var{overlay}
+@kindex overlay unmap-overlay
+@cindex unmap an overlay
+Tell @value{GDBN} that @var{overlay} is no longer mapped; @var{overlay}
+must be the name of the object file section containing the overlay.
+When an overlay is unmapped, @value{GDBN} assumes it can find the
+overlay's functions and variables at their load addresses.
+
+@item overlay auto
+@kindex overlay auto
+Enable @dfn{automatic} overlay debugging. In this mode, @value{GDBN}
+consults a data structure the overlay manager maintains in the inferior
+to see which overlays are mapped. For details, see @ref{Automatic
+Overlay Debugging}.
+
+@item overlay load-target
+@itemx overlay load
+@kindex overlay load-target
+@cindex reloading the overlay table
+Re-read the overlay table from the inferior. Normally, @value{GDBN}
+re-reads the table @value{GDBN} automatically each time the inferior
+stops, so this command should only be necessary if you have changed the
+overlay mapping yourself using @value{GDBN}. This command is only
+useful when using automatic overlay debugging.
+
+@item overlay list-overlays
+@itemx overlay list
+@cindex listing mapped overlays
+Display a list of the overlays currently mapped, along with their mapped
+addresses, load addresses, and sizes.
+
+@end table
+
+Normally, when @value{GDBN} prints a code address, it includes the name
+of the function the address falls in:
+
+@smallexample
+(gdb) print main
+$3 = @{int ()@} 0x11a0 <main>
+@end smallexample
+@noindent
+When overlay debugging is enabled, @value{GDBN} recognizes code in
+unmapped overlays, and prints the names of unmapped functions with
+asterisks around them. For example, if @code{foo} is a function in an
+unmapped overlay, @value{GDBN} prints it this way:
+
+@smallexample
+(gdb) overlay list
+No sections are mapped.
+(gdb) print foo
+$5 = @{int (int)@} 0x100000 <*foo*>
+@end smallexample
+@noindent
+When @code{foo}'s overlay is mapped, @value{GDBN} prints the function's
+name normally:
+
+@smallexample
+(gdb) overlay list
+Section .ov.foo.text, loaded at 0x100000 - 0x100034,
+ mapped at 0x1016 - 0x104a
+(gdb) print foo
+$6 = @{int (int)@} 0x1016 <foo>
+@end smallexample
+
+When overlay debugging is enabled, @value{GDBN} can find the correct
+address for functions and variables in an overlay, whether or not the
+overlay is mapped. This allows most @value{GDBN} commands, like
+@code{break} and @code{disassemble}, to work normally, even on unmapped
+code. However, @value{GDBN}'s breakpoint support has some limitations:
+
+@itemize @bullet
+@item
+@cindex breakpoints in overlays
+@cindex overlays, setting breakpoints in
+You can set breakpoints in functions in unmapped overlays, as long as
+@value{GDBN} can write to the overlay at its load address.
+@item
+@value{GDBN} can not set hardware or simulator-based breakpoints in
+unmapped overlays. However, if you set a breakpoint at the end of your
+overlay manager (and tell @value{GDBN} which overlays are now mapped, if
+you are using manual overlay management), @value{GDBN} will re-set its
+breakpoints properly.
+@end itemize
+
+
+@node Automatic Overlay Debugging
+@section Automatic Overlay Debugging
+@cindex automatic overlay debugging
+
+@value{GDBN} can automatically track which overlays are mapped and which
+are not, given some simple co-operation from the overlay manager in the
+inferior. If you enable automatic overlay debugging with the
+@code{overlay auto} command (@pxref{Overlay Commands}), @value{GDBN}
+looks in the inferior's memory for certain variables describing the
+current state of the overlays.
+
+Here are the variables your overlay manager must define to support
+@value{GDBN}'s automatic overlay debugging:
+
+@table @asis
+
+@item @code{_ovly_table}:
+This variable must be an array of the following structures:
+
+@smallexample
+struct
+@{
+ /* The overlay's mapped address. */
+ unsigned long vma;
+
+ /* The size of the overlay, in bytes. */
+ unsigned long size;
+
+ /* The overlay's load address. */
+ unsigned long lma;
+
+ /* Non-zero if the overlay is currently mapped;
+ zero otherwise. */
+ unsigned long mapped;
+@}
+@end smallexample
+
+@item @code{_novlys}:
+This variable must be a four-byte signed integer, holding the total
+number of elements in @code{_ovly_table}.
+
+@end table
+
+To decide whether a particular overlay is mapped or not, @value{GDBN}
+looks for an entry in @w{@code{_ovly_table}} whose @code{vma} and
+@code{lma} members equal the VMA and LMA of the overlay's section in the
+executable file. When @value{GDBN} finds a matching entry, it consults
+the entry's @code{mapped} member to determine whether the overlay is
+currently mapped.
+
+In addition, your overlay manager may define a function called
+@code{_ovly_debug_event}. If this function is defined, @value{GDBN}
+will silently set a breakpoint there. If the overlay manager then
+calls this function whenever it has changed the overlay table, this
+will enable @value{GDBN} to accurately keep track of which overlays
+are in program memory, and update any breakpoints that may be set
+in overlays. This will allow breakpoints to work even if the
+overlays are kept in ROM or other non-writable memory while they
+are not being executed.
+
+@node Overlay Sample Program
+@section Overlay Sample Program
+@cindex overlay example program
+
+When linking a program which uses overlays, you must place the overlays
+at their load addresses, while relocating them to run at their mapped
+addresses. To do this, you must write a linker script (@pxref{Overlay
+Description,,, ld.info, Using ld: the GNU linker}). Unfortunately,
+since linker scripts are specific to a particular host system, target
+architecture, and target memory layout, this manual cannot provide
+portable sample code demonstrating @value{GDBN}'s overlay support.
+
+However, the @value{GDBN} source distribution does contain an overlaid
+program, with linker scripts for a few systems, as part of its test
+suite. The program consists of the following files from
+@file{gdb/testsuite/gdb.base}:
+
+@table @file
+@item overlays.c
+The main program file.
+@item ovlymgr.c
+A simple overlay manager, used by @file{overlays.c}.
+@item foo.c
+@itemx bar.c
+@itemx baz.c
+@itemx grbx.c
+Overlay modules, loaded and used by @file{overlays.c}.
+@item d10v.ld
+@itemx m32r.ld
+Linker scripts for linking the test program on the @code{d10v-elf}
+and @code{m32r-elf} targets.
+@end table
+
+You can build the test program using the @code{d10v-elf} GCC
+cross-compiler like this:
+
+@smallexample
+$ d10v-elf-gcc -g -c overlays.c
+$ d10v-elf-gcc -g -c ovlymgr.c
+$ d10v-elf-gcc -g -c foo.c
+$ d10v-elf-gcc -g -c bar.c
+$ d10v-elf-gcc -g -c baz.c
+$ d10v-elf-gcc -g -c grbx.c
+$ d10v-elf-gcc -g overlays.o ovlymgr.o foo.o bar.o \
+ baz.o grbx.o -Wl,-Td10v.ld -o overlays
+@end smallexample
+
+The build process is identical for any other architecture, except that
+you must substitute the appropriate compiler and linker script for the
+target system for @code{d10v-elf-gcc} and @code{d10v.ld}.
+
+
+@node Languages
+@chapter Using @value{GDBN} with Different Languages
+@cindex languages
+
+Although programming languages generally have common aspects, they are
+rarely expressed in the same manner. For instance, in ANSI C,
+dereferencing a pointer @code{p} is accomplished by @code{*p}, but in
+Modula-2, it is accomplished by @code{p^}. Values can also be
+represented (and displayed) differently. Hex numbers in C appear as
+@samp{0x1ae}, while in Modula-2 they appear as @samp{1AEH}.
+
+@cindex working language
+Language-specific information is built into @value{GDBN} for some languages,
+allowing you to express operations like the above in your program's
+native language, and allowing @value{GDBN} to output values in a manner
+consistent with the syntax of your program's native language. The
+language you use to build expressions is called the @dfn{working
+language}.
+
+@menu
+* Setting:: Switching between source languages
+* Show:: Displaying the language
+* Checks:: Type and range checks
+* Support:: Supported languages
+@end menu
+
+@node Setting
+@section Switching between source languages
+
+There are two ways to control the working language---either have @value{GDBN}
+set it automatically, or select it manually yourself. You can use the
+@code{set language} command for either purpose. On startup, @value{GDBN}
+defaults to setting the language automatically. The working language is
+used to determine how expressions you type are interpreted, how values
+are printed, etc.
+
+In addition to the working language, every source file that
+@value{GDBN} knows about has its own working language. For some object
+file formats, the compiler might indicate which language a particular
+source file is in. However, most of the time @value{GDBN} infers the
+language from the name of the file. The language of a source file
+controls whether C@t{++} names are demangled---this way @code{backtrace} can
+show each frame appropriately for its own language. There is no way to
+set the language of a source file from within @value{GDBN}, but you can
+set the language associated with a filename extension. @xref{Show, ,
+Displaying the language}.
+
+This is most commonly a problem when you use a program, such
+as @code{cfront} or @code{f2c}, that generates C but is written in
+another language. In that case, make the
+program use @code{#line} directives in its C output; that way
+@value{GDBN} will know the correct language of the source code of the original
+program, and will display that source code, not the generated C code.
+
+@menu
+* Filenames:: Filename extensions and languages.
+* Manually:: Setting the working language manually
+* Automatically:: Having @value{GDBN} infer the source language
+@end menu
+
+@node Filenames
+@subsection List of filename extensions and languages
+
+If a source file name ends in one of the following extensions, then
+@value{GDBN} infers that its language is the one indicated.
+
+@table @file
+
+@item .c
+C source file
+
+@item .C
+@itemx .cc
+@itemx .cp
+@itemx .cpp
+@itemx .cxx
+@itemx .c++
+C@t{++} source file
+
+@item .f
+@itemx .F
+Fortran source file
+
+@item .ch
+@itemx .c186
+@itemx .c286
+CHILL source file
+
+@item .mod
+Modula-2 source file
+
+@item .s
+@itemx .S
+Assembler source file. This actually behaves almost like C, but
+@value{GDBN} does not skip over function prologues when stepping.
+@end table
+
+In addition, you may set the language associated with a filename
+extension. @xref{Show, , Displaying the language}.
+
+@node Manually
+@subsection Setting the working language
+
+If you allow @value{GDBN} to set the language automatically,
+expressions are interpreted the same way in your debugging session and
+your program.
+
+@kindex set language
+If you wish, you may set the language manually. To do this, issue the
+command @samp{set language @var{lang}}, where @var{lang} is the name of
+a language, such as
+@code{c} or @code{modula-2}.
+For a list of the supported languages, type @samp{set language}.
+
+Setting the language manually prevents @value{GDBN} from updating the working
+language automatically. This can lead to confusion if you try
+to debug a program when the working language is not the same as the
+source language, when an expression is acceptable to both
+languages---but means different things. For instance, if the current
+source file were written in C, and @value{GDBN} was parsing Modula-2, a
+command such as:
+
+@smallexample
+print a = b + c
+@end smallexample
+
+@noindent
+might not have the effect you intended. In C, this means to add
+@code{b} and @code{c} and place the result in @code{a}. The result
+printed would be the value of @code{a}. In Modula-2, this means to compare
+@code{a} to the result of @code{b+c}, yielding a @code{BOOLEAN} value.
+
+@node Automatically
+@subsection Having @value{GDBN} infer the source language
+
+To have @value{GDBN} set the working language automatically, use
+@samp{set language local} or @samp{set language auto}. @value{GDBN}
+then infers the working language. That is, when your program stops in a
+frame (usually by encountering a breakpoint), @value{GDBN} sets the
+working language to the language recorded for the function in that
+frame. If the language for a frame is unknown (that is, if the function
+or block corresponding to the frame was defined in a source file that
+does not have a recognized extension), the current working language is
+not changed, and @value{GDBN} issues a warning.
+
+This may not seem necessary for most programs, which are written
+entirely in one source language. However, program modules and libraries
+written in one source language can be used by a main program written in
+a different source language. Using @samp{set language auto} in this
+case frees you from having to set the working language manually.
+
+@node Show
+@section Displaying the language
+
+The following commands help you find out which language is the
+working language, and also what language source files were written in.
+
+@kindex show language
+@kindex info frame@r{, show the source language}
+@kindex info source@r{, show the source language}
+@table @code
+@item show language
+Display the current working language. This is the
+language you can use with commands such as @code{print} to
+build and compute expressions that may involve variables in your program.
+
+@item info frame
+Display the source language for this frame. This language becomes the
+working language if you use an identifier from this frame.
+@xref{Frame Info, ,Information about a frame}, to identify the other
+information listed here.
+
+@item info source
+Display the source language of this source file.
+@xref{Symbols, ,Examining the Symbol Table}, to identify the other
+information listed here.
+@end table
+
+In unusual circumstances, you may have source files with extensions
+not in the standard list. You can then set the extension associated
+with a language explicitly:
+
+@kindex set extension-language
+@kindex info extensions
+@table @code
+@item set extension-language @var{.ext} @var{language}
+Set source files with extension @var{.ext} to be assumed to be in
+the source language @var{language}.
+
+@item info extensions
+List all the filename extensions and the associated languages.
+@end table
+
+@node Checks
+@section Type and range checking
+
+@quotation
+@emph{Warning:} In this release, the @value{GDBN} commands for type and range
+checking are included, but they do not yet have any effect. This
+section documents the intended facilities.
+@end quotation
+@c FIXME remove warning when type/range code added
+
+Some languages are designed to guard you against making seemingly common
+errors through a series of compile- and run-time checks. These include
+checking the type of arguments to functions and operators, and making
+sure mathematical overflows are caught at run time. Checks such as
+these help to ensure a program's correctness once it has been compiled
+by eliminating type mismatches, and providing active checks for range
+errors when your program is running.
+
+@value{GDBN} can check for conditions like the above if you wish.
+Although @value{GDBN} does not check the statements in your program, it
+can check expressions entered directly into @value{GDBN} for evaluation via
+the @code{print} command, for example. As with the working language,
+@value{GDBN} can also decide whether or not to check automatically based on
+your program's source language. @xref{Support, ,Supported languages},
+for the default settings of supported languages.
+
+@menu
+* Type Checking:: An overview of type checking
+* Range Checking:: An overview of range checking
+@end menu
+
+@cindex type checking
+@cindex checks, type
+@node Type Checking
+@subsection An overview of type checking
+
+Some languages, such as Modula-2, are strongly typed, meaning that the
+arguments to operators and functions have to be of the correct type,
+otherwise an error occurs. These checks prevent type mismatch
+errors from ever causing any run-time problems. For example,
+
+@smallexample
+1 + 2 @result{} 3
+@exdent but
+@error{} 1 + 2.3
+@end smallexample
+
+The second example fails because the @code{CARDINAL} 1 is not
+type-compatible with the @code{REAL} 2.3.
+
+For the expressions you use in @value{GDBN} commands, you can tell the
+@value{GDBN} type checker to skip checking;
+to treat any mismatches as errors and abandon the expression;
+or to only issue warnings when type mismatches occur,
+but evaluate the expression anyway. When you choose the last of
+these, @value{GDBN} evaluates expressions like the second example above, but
+also issues a warning.
+
+Even if you turn type checking off, there may be other reasons
+related to type that prevent @value{GDBN} from evaluating an expression.
+For instance, @value{GDBN} does not know how to add an @code{int} and
+a @code{struct foo}. These particular type errors have nothing to do
+with the language in use, and usually arise from expressions, such as
+the one described above, which make little sense to evaluate anyway.
+
+Each language defines to what degree it is strict about type. For
+instance, both Modula-2 and C require the arguments to arithmetical
+operators to be numbers. In C, enumerated types and pointers can be
+represented as numbers, so that they are valid arguments to mathematical
+operators. @xref{Support, ,Supported languages}, for further
+details on specific languages.
+
+@value{GDBN} provides some additional commands for controlling the type checker:
+
+@kindex set check@r{, type}
+@kindex set check type
+@kindex show check type
+@table @code
+@item set check type auto
+Set type checking on or off based on the current working language.
+@xref{Support, ,Supported languages}, for the default settings for
+each language.
+
+@item set check type on
+@itemx set check type off
+Set type checking on or off, overriding the default setting for the
+current working language. Issue a warning if the setting does not
+match the language default. If any type mismatches occur in
+evaluating an expression while type checking is on, @value{GDBN} prints a
+message and aborts evaluation of the expression.
+
+@item set check type warn
+Cause the type checker to issue warnings, but to always attempt to
+evaluate the expression. Evaluating the expression may still
+be impossible for other reasons. For example, @value{GDBN} cannot add
+numbers and structures.
+
+@item show type
+Show the current setting of the type checker, and whether or not @value{GDBN}
+is setting it automatically.
+@end table
+
+@cindex range checking
+@cindex checks, range
+@node Range Checking
+@subsection An overview of range checking
+
+In some languages (such as Modula-2), it is an error to exceed the
+bounds of a type; this is enforced with run-time checks. Such range
+checking is meant to ensure program correctness by making sure
+computations do not overflow, or indices on an array element access do
+not exceed the bounds of the array.
+
+For expressions you use in @value{GDBN} commands, you can tell
+@value{GDBN} to treat range errors in one of three ways: ignore them,
+always treat them as errors and abandon the expression, or issue
+warnings but evaluate the expression anyway.
+
+A range error can result from numerical overflow, from exceeding an
+array index bound, or when you type a constant that is not a member
+of any type. Some languages, however, do not treat overflows as an
+error. In many implementations of C, mathematical overflow causes the
+result to ``wrap around'' to lower values---for example, if @var{m} is
+the largest integer value, and @var{s} is the smallest, then
+
+@smallexample
+@var{m} + 1 @result{} @var{s}
+@end smallexample
+
+This, too, is specific to individual languages, and in some cases
+specific to individual compilers or machines. @xref{Support, ,
+Supported languages}, for further details on specific languages.
+
+@value{GDBN} provides some additional commands for controlling the range checker:
+
+@kindex set check@r{, range}
+@kindex set check range
+@kindex show check range
+@table @code
+@item set check range auto
+Set range checking on or off based on the current working language.
+@xref{Support, ,Supported languages}, for the default settings for
+each language.
+
+@item set check range on
+@itemx set check range off
+Set range checking on or off, overriding the default setting for the
+current working language. A warning is issued if the setting does not
+match the language default. If a range error occurs and range checking is on,
+then a message is printed and evaluation of the expression is aborted.
+
+@item set check range warn
+Output messages when the @value{GDBN} range checker detects a range error,
+but attempt to evaluate the expression anyway. Evaluating the
+expression may still be impossible for other reasons, such as accessing
+memory that the process does not own (a typical example from many Unix
+systems).
+
+@item show range
+Show the current setting of the range checker, and whether or not it is
+being set automatically by @value{GDBN}.
+@end table
+
+@node Support
+@section Supported languages
+
+@value{GDBN} supports C, C@t{++}, Fortran, Java, Chill, assembly, and Modula-2.
+@c This is false ...
+Some @value{GDBN} features may be used in expressions regardless of the
+language you use: the @value{GDBN} @code{@@} and @code{::} operators,
+and the @samp{@{type@}addr} construct (@pxref{Expressions,
+,Expressions}) can be used with the constructs of any supported
+language.
+
+The following sections detail to what degree each source language is
+supported by @value{GDBN}. These sections are not meant to be language
+tutorials or references, but serve only as a reference guide to what the
+@value{GDBN} expression parser accepts, and what input and output
+formats should look like for different languages. There are many good
+books written on each of these languages; please look to these for a
+language reference or tutorial.
+
+@menu
+* C:: C and C@t{++}
+* Modula-2:: Modula-2
+* Chill:: Chill
+@end menu
+
+@node C
+@subsection C and C@t{++}
+
+@cindex C and C@t{++}
+@cindex expressions in C or C@t{++}
+
+Since C and C@t{++} are so closely related, many features of @value{GDBN} apply
+to both languages. Whenever this is the case, we discuss those languages
+together.
+
+@cindex C@t{++}
+@cindex @code{g++}, @sc{gnu} C@t{++} compiler
+@cindex @sc{gnu} C@t{++}
+The C@t{++} debugging facilities are jointly implemented by the C@t{++}
+compiler and @value{GDBN}. Therefore, to debug your C@t{++} code
+effectively, you must compile your C@t{++} programs with a supported
+C@t{++} compiler, such as @sc{gnu} @code{g++}, or the HP ANSI C@t{++}
+compiler (@code{aCC}).
+
+For best results when using @sc{gnu} C@t{++}, use the stabs debugging
+format. You can select that format explicitly with the @code{g++}
+command-line options @samp{-gstabs} or @samp{-gstabs+}. See
+@ref{Debugging Options,,Options for Debugging Your Program or @sc{gnu}
+CC, gcc.info, Using @sc{gnu} CC}, for more information.
+
+@menu
+* C Operators:: C and C@t{++} operators
+* C Constants:: C and C@t{++} constants
+* C plus plus expressions:: C@t{++} expressions
+* C Defaults:: Default settings for C and C@t{++}
+* C Checks:: C and C@t{++} type and range checks
+* Debugging C:: @value{GDBN} and C
+* Debugging C plus plus:: @value{GDBN} features for C@t{++}
+@end menu
+
+@node C Operators
+@subsubsection C and C@t{++} operators
+
+@cindex C and C@t{++} operators
+
+Operators must be defined on values of specific types. For instance,
+@code{+} is defined on numbers, but not on structures. Operators are
+often defined on groups of types.
+
+For the purposes of C and C@t{++}, the following definitions hold:
+
+@itemize @bullet
+
+@item
+@emph{Integral types} include @code{int} with any of its storage-class
+specifiers; @code{char}; @code{enum}; and, for C@t{++}, @code{bool}.
+
+@item
+@emph{Floating-point types} include @code{float}, @code{double}, and
+@code{long double} (if supported by the target platform).
+
+@item
+@emph{Pointer types} include all types defined as @code{(@var{type} *)}.
+
+@item
+@emph{Scalar types} include all of the above.
+
+@end itemize
+
+@noindent
+The following operators are supported. They are listed here
+in order of increasing precedence:
+
+@table @code
+@item ,
+The comma or sequencing operator. Expressions in a comma-separated list
+are evaluated from left to right, with the result of the entire
+expression being the last expression evaluated.
+
+@item =
+Assignment. The value of an assignment expression is the value
+assigned. Defined on scalar types.
+
+@item @var{op}=
+Used in an expression of the form @w{@code{@var{a} @var{op}= @var{b}}},
+and translated to @w{@code{@var{a} = @var{a op b}}}.
+@w{@code{@var{op}=}} and @code{=} have the same precedence.
+@var{op} is any one of the operators @code{|}, @code{^}, @code{&},
+@code{<<}, @code{>>}, @code{+}, @code{-}, @code{*}, @code{/}, @code{%}.
+
+@item ?:
+The ternary operator. @code{@var{a} ? @var{b} : @var{c}} can be thought
+of as: if @var{a} then @var{b} else @var{c}. @var{a} should be of an
+integral type.
+
+@item ||
+Logical @sc{or}. Defined on integral types.
+
+@item &&
+Logical @sc{and}. Defined on integral types.
+
+@item |
+Bitwise @sc{or}. Defined on integral types.
+
+@item ^
+Bitwise exclusive-@sc{or}. Defined on integral types.
+
+@item &
+Bitwise @sc{and}. Defined on integral types.
+
+@item ==@r{, }!=
+Equality and inequality. Defined on scalar types. The value of these
+expressions is 0 for false and non-zero for true.
+
+@item <@r{, }>@r{, }<=@r{, }>=
+Less than, greater than, less than or equal, greater than or equal.
+Defined on scalar types. The value of these expressions is 0 for false
+and non-zero for true.
+
+@item <<@r{, }>>
+left shift, and right shift. Defined on integral types.
+
+@item @@
+The @value{GDBN} ``artificial array'' operator (@pxref{Expressions, ,Expressions}).
+
+@item +@r{, }-
+Addition and subtraction. Defined on integral types, floating-point types and
+pointer types.
+
+@item *@r{, }/@r{, }%
+Multiplication, division, and modulus. Multiplication and division are
+defined on integral and floating-point types. Modulus is defined on
+integral types.
+
+@item ++@r{, }--
+Increment and decrement. When appearing before a variable, the
+operation is performed before the variable is used in an expression;
+when appearing after it, the variable's value is used before the
+operation takes place.
+
+@item *
+Pointer dereferencing. Defined on pointer types. Same precedence as
+@code{++}.
+
+@item &
+Address operator. Defined on variables. Same precedence as @code{++}.
+
+For debugging C@t{++}, @value{GDBN} implements a use of @samp{&} beyond what is
+allowed in the C@t{++} language itself: you can use @samp{&(&@var{ref})}
+(or, if you prefer, simply @samp{&&@var{ref}}) to examine the address
+where a C@t{++} reference variable (declared with @samp{&@var{ref}}) is
+stored.
+
+@item -
+Negative. Defined on integral and floating-point types. Same
+precedence as @code{++}.
+
+@item !
+Logical negation. Defined on integral types. Same precedence as
+@code{++}.
+
+@item ~
+Bitwise complement operator. Defined on integral types. Same precedence as
+@code{++}.
+
+
+@item .@r{, }->
+Structure member, and pointer-to-structure member. For convenience,
+@value{GDBN} regards the two as equivalent, choosing whether to dereference a
+pointer based on the stored type information.
+Defined on @code{struct} and @code{union} data.
+
+@item .*@r{, }->*
+Dereferences of pointers to members.
+
+@item []
+Array indexing. @code{@var{a}[@var{i}]} is defined as
+@code{*(@var{a}+@var{i})}. Same precedence as @code{->}.
+
+@item ()
+Function parameter list. Same precedence as @code{->}.
+
+@item ::
+C@t{++} scope resolution operator. Defined on @code{struct}, @code{union},
+and @code{class} types.
+
+@item ::
+Doubled colons also represent the @value{GDBN} scope operator
+(@pxref{Expressions, ,Expressions}). Same precedence as @code{::},
+above.
+@end table
+
+If an operator is redefined in the user code, @value{GDBN} usually
+attempts to invoke the redefined version instead of using the operator's
+predefined meaning.
+
+@menu
+* C Constants::
+@end menu
+
+@node C Constants
+@subsubsection C and C@t{++} constants
+
+@cindex C and C@t{++} constants
+
+@value{GDBN} allows you to express the constants of C and C@t{++} in the
+following ways:
+
+@itemize @bullet
+@item
+Integer constants are a sequence of digits. Octal constants are
+specified by a leading @samp{0} (i.e.@: zero), and hexadecimal constants
+by a leading @samp{0x} or @samp{0X}. Constants may also end with a letter
+@samp{l}, specifying that the constant should be treated as a
+@code{long} value.
+
+@item
+Floating point constants are a sequence of digits, followed by a decimal
+point, followed by a sequence of digits, and optionally followed by an
+exponent. An exponent is of the form:
+@samp{@w{e@r{[[}+@r{]|}-@r{]}@var{nnn}}}, where @var{nnn} is another
+sequence of digits. The @samp{+} is optional for positive exponents.
+A floating-point constant may also end with a letter @samp{f} or
+@samp{F}, specifying that the constant should be treated as being of
+the @code{float} (as opposed to the default @code{double}) type; or with
+a letter @samp{l} or @samp{L}, which specifies a @code{long double}
+constant.
+
+@item
+Enumerated constants consist of enumerated identifiers, or their
+integral equivalents.
+
+@item
+Character constants are a single character surrounded by single quotes
+(@code{'}), or a number---the ordinal value of the corresponding character
+(usually its @sc{ascii} value). Within quotes, the single character may
+be represented by a letter or by @dfn{escape sequences}, which are of
+the form @samp{\@var{nnn}}, where @var{nnn} is the octal representation
+of the character's ordinal value; or of the form @samp{\@var{x}}, where
+@samp{@var{x}} is a predefined special character---for example,
+@samp{\n} for newline.
+
+@item
+String constants are a sequence of character constants surrounded by
+double quotes (@code{"}). Any valid character constant (as described
+above) may appear. Double quotes within the string must be preceded by
+a backslash, so for instance @samp{"a\"b'c"} is a string of five
+characters.
+
+@item
+Pointer constants are an integral value. You can also write pointers
+to constants using the C operator @samp{&}.
+
+@item
+Array constants are comma-separated lists surrounded by braces @samp{@{}
+and @samp{@}}; for example, @samp{@{1,2,3@}} is a three-element array of
+integers, @samp{@{@{1,2@}, @{3,4@}, @{5,6@}@}} is a three-by-two array,
+and @samp{@{&"hi", &"there", &"fred"@}} is a three-element array of pointers.
+@end itemize
+
+@menu
+* C plus plus expressions::
+* C Defaults::
+* C Checks::
+
+* Debugging C::
+@end menu
+
+@node C plus plus expressions
+@subsubsection C@t{++} expressions
+
+@cindex expressions in C@t{++}
+@value{GDBN} expression handling can interpret most C@t{++} expressions.
+
+@cindex C@t{++} support, not in @sc{coff}
+@cindex @sc{coff} versus C@t{++}
+@cindex C@t{++} and object formats
+@cindex object formats and C@t{++}
+@cindex a.out and C@t{++}
+@cindex @sc{ecoff} and C@t{++}
+@cindex @sc{xcoff} and C@t{++}
+@cindex @sc{elf}/stabs and C@t{++}
+@cindex @sc{elf}/@sc{dwarf} and C@t{++}
+@c FIXME!! GDB may eventually be able to debug C++ using DWARF; check
+@c periodically whether this has happened...
+@quotation
+@emph{Warning:} @value{GDBN} can only debug C@t{++} code if you use the
+proper compiler. Typically, C@t{++} debugging depends on the use of
+additional debugging information in the symbol table, and thus requires
+special support. In particular, if your compiler generates a.out, MIPS
+@sc{ecoff}, RS/6000 @sc{xcoff}, or @sc{elf} with stabs extensions to the
+symbol table, these facilities are all available. (With @sc{gnu} CC,
+you can use the @samp{-gstabs} option to request stabs debugging
+extensions explicitly.) Where the object code format is standard
+@sc{coff} or @sc{dwarf} in @sc{elf}, on the other hand, most of the C@t{++}
+support in @value{GDBN} does @emph{not} work.
+@end quotation
+
+@enumerate
+
+@cindex member functions
+@item
+Member function calls are allowed; you can use expressions like
+
+@smallexample
+count = aml->GetOriginal(x, y)
+@end smallexample
+
+@vindex this@r{, inside C@t{++} member functions}
+@cindex namespace in C@t{++}
+@item
+While a member function is active (in the selected stack frame), your
+expressions have the same namespace available as the member function;
+that is, @value{GDBN} allows implicit references to the class instance
+pointer @code{this} following the same rules as C@t{++}.
+
+@cindex call overloaded functions
+@cindex overloaded functions, calling
+@cindex type conversions in C@t{++}
+@item
+You can call overloaded functions; @value{GDBN} resolves the function
+call to the right definition, with some restrictions. @value{GDBN} does not
+perform overload resolution involving user-defined type conversions,
+calls to constructors, or instantiations of templates that do not exist
+in the program. It also cannot handle ellipsis argument lists or
+default arguments.
+
+It does perform integral conversions and promotions, floating-point
+promotions, arithmetic conversions, pointer conversions, conversions of
+class objects to base classes, and standard conversions such as those of
+functions or arrays to pointers; it requires an exact match on the
+number of function arguments.
+
+Overload resolution is always performed, unless you have specified
+@code{set overload-resolution off}. @xref{Debugging C plus plus,
+,@value{GDBN} features for C@t{++}}.
+
+You must specify @code{set overload-resolution off} in order to use an
+explicit function signature to call an overloaded function, as in
+@smallexample
+p 'foo(char,int)'('x', 13)
+@end smallexample
+
+The @value{GDBN} command-completion facility can simplify this;
+see @ref{Completion, ,Command completion}.
+
+@cindex reference declarations
+@item
+@value{GDBN} understands variables declared as C@t{++} references; you can use
+them in expressions just as you do in C@t{++} source---they are automatically
+dereferenced.
+
+In the parameter list shown when @value{GDBN} displays a frame, the values of
+reference variables are not displayed (unlike other variables); this
+avoids clutter, since references are often used for large structures.
+The @emph{address} of a reference variable is always shown, unless
+you have specified @samp{set print address off}.
+
+@item
+@value{GDBN} supports the C@t{++} name resolution operator @code{::}---your
+expressions can use it just as expressions in your program do. Since
+one scope may be defined in another, you can use @code{::} repeatedly if
+necessary, for example in an expression like
+@samp{@var{scope1}::@var{scope2}::@var{name}}. @value{GDBN} also allows
+resolving name scope by reference to source files, in both C and C@t{++}
+debugging (@pxref{Variables, ,Program variables}).
+@end enumerate
+
+In addition, when used with HP's C@t{++} compiler, @value{GDBN} supports
+calling virtual functions correctly, printing out virtual bases of
+objects, calling functions in a base subobject, casting objects, and
+invoking user-defined operators.
+
+@node C Defaults
+@subsubsection C and C@t{++} defaults
+
+@cindex C and C@t{++} defaults
+
+If you allow @value{GDBN} to set type and range checking automatically, they
+both default to @code{off} whenever the working language changes to
+C or C@t{++}. This happens regardless of whether you or @value{GDBN}
+selects the working language.
+
+If you allow @value{GDBN} to set the language automatically, it
+recognizes source files whose names end with @file{.c}, @file{.C}, or
+@file{.cc}, etc, and when @value{GDBN} enters code compiled from one of
+these files, it sets the working language to C or C@t{++}.
+@xref{Automatically, ,Having @value{GDBN} infer the source language},
+for further details.
+
+@c Type checking is (a) primarily motivated by Modula-2, and (b)
+@c unimplemented. If (b) changes, it might make sense to let this node
+@c appear even if Mod-2 does not, but meanwhile ignore it. roland 16jul93.
+
+@node C Checks
+@subsubsection C and C@t{++} type and range checks
+
+@cindex C and C@t{++} checks
+
+By default, when @value{GDBN} parses C or C@t{++} expressions, type checking
+is not used. However, if you turn type checking on, @value{GDBN}
+considers two variables type equivalent if:
+
+@itemize @bullet
+@item
+The two variables are structured and have the same structure, union, or
+enumerated tag.
+
+@item
+The two variables have the same type name, or types that have been
+declared equivalent through @code{typedef}.
+
+@ignore
+@c leaving this out because neither J Gilmore nor R Pesch understand it.
+@c FIXME--beers?
+@item
+The two @code{struct}, @code{union}, or @code{enum} variables are
+declared in the same declaration. (Note: this may not be true for all C
+compilers.)
+@end ignore
+@end itemize
+
+Range checking, if turned on, is done on mathematical operations. Array
+indices are not checked, since they are often used to index a pointer
+that is not itself an array.
+
+@node Debugging C
+@subsubsection @value{GDBN} and C
+
+The @code{set print union} and @code{show print union} commands apply to
+the @code{union} type. When set to @samp{on}, any @code{union} that is
+inside a @code{struct} or @code{class} is also printed. Otherwise, it
+appears as @samp{@{...@}}.
+
+The @code{@@} operator aids in the debugging of dynamic arrays, formed
+with pointers and a memory allocation function. @xref{Expressions,
+,Expressions}.
+
+@menu
+* Debugging C plus plus::
+@end menu
+
+@node Debugging C plus plus
+@subsubsection @value{GDBN} features for C@t{++}
+
+@cindex commands for C@t{++}
+
+Some @value{GDBN} commands are particularly useful with C@t{++}, and some are
+designed specifically for use with C@t{++}. Here is a summary:
+
+@table @code
+@cindex break in overloaded functions
+@item @r{breakpoint menus}
+When you want a breakpoint in a function whose name is overloaded,
+@value{GDBN} breakpoint menus help you specify which function definition
+you want. @xref{Breakpoint Menus,,Breakpoint menus}.
+
+@cindex overloading in C@t{++}
+@item rbreak @var{regex}
+Setting breakpoints using regular expressions is helpful for setting
+breakpoints on overloaded functions that are not members of any special
+classes.
+@xref{Set Breaks, ,Setting breakpoints}.
+
+@cindex C@t{++} exception handling
+@item catch throw
+@itemx catch catch
+Debug C@t{++} exception handling using these commands. @xref{Set
+Catchpoints, , Setting catchpoints}.
+
+@cindex inheritance
+@item ptype @var{typename}
+Print inheritance relationships as well as other information for type
+@var{typename}.
+@xref{Symbols, ,Examining the Symbol Table}.
+
+@cindex C@t{++} symbol display
+@item set print demangle
+@itemx show print demangle
+@itemx set print asm-demangle
+@itemx show print asm-demangle
+Control whether C@t{++} symbols display in their source form, both when
+displaying code as C@t{++} source and when displaying disassemblies.
+@xref{Print Settings, ,Print settings}.
+
+@item set print object
+@itemx show print object
+Choose whether to print derived (actual) or declared types of objects.
+@xref{Print Settings, ,Print settings}.
+
+@item set print vtbl
+@itemx show print vtbl
+Control the format for printing virtual function tables.
+@xref{Print Settings, ,Print settings}.
+(The @code{vtbl} commands do not work on programs compiled with the HP
+ANSI C@t{++} compiler (@code{aCC}).)
+
+@kindex set overload-resolution
+@cindex overloaded functions, overload resolution
+@item set overload-resolution on
+Enable overload resolution for C@t{++} expression evaluation. The default
+is on. For overloaded functions, @value{GDBN} evaluates the arguments
+and searches for a function whose signature matches the argument types,
+using the standard C@t{++} conversion rules (see @ref{C plus plus expressions, ,C@t{++}
+expressions}, for details). If it cannot find a match, it emits a
+message.
+
+@item set overload-resolution off
+Disable overload resolution for C@t{++} expression evaluation. For
+overloaded functions that are not class member functions, @value{GDBN}
+chooses the first function of the specified name that it finds in the
+symbol table, whether or not its arguments are of the correct type. For
+overloaded functions that are class member functions, @value{GDBN}
+searches for a function whose signature @emph{exactly} matches the
+argument types.
+
+@item @r{Overloaded symbol names}
+You can specify a particular definition of an overloaded symbol, using
+the same notation that is used to declare such symbols in C@t{++}: type
+@code{@var{symbol}(@var{types})} rather than just @var{symbol}. You can
+also use the @value{GDBN} command-line word completion facilities to list the
+available choices, or to finish the type list for you.
+@xref{Completion,, Command completion}, for details on how to do this.
+@end table
+
+@node Modula-2
+@subsection Modula-2
+
+@cindex Modula-2, @value{GDBN} support
+
+The extensions made to @value{GDBN} to support Modula-2 only support
+output from the @sc{gnu} Modula-2 compiler (which is currently being
+developed). Other Modula-2 compilers are not currently supported, and
+attempting to debug executables produced by them is most likely
+to give an error as @value{GDBN} reads in the executable's symbol
+table.
+
+@cindex expressions in Modula-2
+@menu
+* M2 Operators:: Built-in operators
+* Built-In Func/Proc:: Built-in functions and procedures
+* M2 Constants:: Modula-2 constants
+* M2 Defaults:: Default settings for Modula-2
+* Deviations:: Deviations from standard Modula-2
+* M2 Checks:: Modula-2 type and range checks
+* M2 Scope:: The scope operators @code{::} and @code{.}
+* GDB/M2:: @value{GDBN} and Modula-2
+@end menu
+
+@node M2 Operators
+@subsubsection Operators
+@cindex Modula-2 operators
+
+Operators must be defined on values of specific types. For instance,
+@code{+} is defined on numbers, but not on structures. Operators are
+often defined on groups of types. For the purposes of Modula-2, the
+following definitions hold:
+
+@itemize @bullet
+
+@item
+@emph{Integral types} consist of @code{INTEGER}, @code{CARDINAL}, and
+their subranges.
+
+@item
+@emph{Character types} consist of @code{CHAR} and its subranges.
+
+@item
+@emph{Floating-point types} consist of @code{REAL}.
+
+@item
+@emph{Pointer types} consist of anything declared as @code{POINTER TO
+@var{type}}.
+
+@item
+@emph{Scalar types} consist of all of the above.
+
+@item
+@emph{Set types} consist of @code{SET} and @code{BITSET} types.
+
+@item
+@emph{Boolean types} consist of @code{BOOLEAN}.
+@end itemize
+
+@noindent
+The following operators are supported, and appear in order of
+increasing precedence:
+
+@table @code
+@item ,
+Function argument or array index separator.
+
+@item :=
+Assignment. The value of @var{var} @code{:=} @var{value} is
+@var{value}.
+
+@item <@r{, }>
+Less than, greater than on integral, floating-point, or enumerated
+types.
+
+@item <=@r{, }>=
+Less than or equal to, greater than or equal to
+on integral, floating-point and enumerated types, or set inclusion on
+set types. Same precedence as @code{<}.
+
+@item =@r{, }<>@r{, }#
+Equality and two ways of expressing inequality, valid on scalar types.
+Same precedence as @code{<}. In @value{GDBN} scripts, only @code{<>} is
+available for inequality, since @code{#} conflicts with the script
+comment character.
+
+@item IN
+Set membership. Defined on set types and the types of their members.
+Same precedence as @code{<}.
+
+@item OR
+Boolean disjunction. Defined on boolean types.
+
+@item AND@r{, }&
+Boolean conjunction. Defined on boolean types.
+
+@item @@
+The @value{GDBN} ``artificial array'' operator (@pxref{Expressions, ,Expressions}).
+
+@item +@r{, }-
+Addition and subtraction on integral and floating-point types, or union
+and difference on set types.
+
+@item *
+Multiplication on integral and floating-point types, or set intersection
+on set types.
+
+@item /
+Division on floating-point types, or symmetric set difference on set
+types. Same precedence as @code{*}.
+
+@item DIV@r{, }MOD
+Integer division and remainder. Defined on integral types. Same
+precedence as @code{*}.
+
+@item -
+Negative. Defined on @code{INTEGER} and @code{REAL} data.
+
+@item ^
+Pointer dereferencing. Defined on pointer types.
+
+@item NOT
+Boolean negation. Defined on boolean types. Same precedence as
+@code{^}.
+
+@item .
+@code{RECORD} field selector. Defined on @code{RECORD} data. Same
+precedence as @code{^}.
+
+@item []
+Array indexing. Defined on @code{ARRAY} data. Same precedence as @code{^}.
+
+@item ()
+Procedure argument list. Defined on @code{PROCEDURE} objects. Same precedence
+as @code{^}.
+
+@item ::@r{, }.
+@value{GDBN} and Modula-2 scope operators.
+@end table
+
+@quotation
+@emph{Warning:} Sets and their operations are not yet supported, so @value{GDBN}
+treats the use of the operator @code{IN}, or the use of operators
+@code{+}, @code{-}, @code{*}, @code{/}, @code{=}, , @code{<>}, @code{#},
+@code{<=}, and @code{>=} on sets as an error.
+@end quotation
+
+
+@node Built-In Func/Proc
+@subsubsection Built-in functions and procedures
+@cindex Modula-2 built-ins
+
+Modula-2 also makes available several built-in procedures and functions.
+In describing these, the following metavariables are used:
+
+@table @var
+
+@item a
+represents an @code{ARRAY} variable.
+
+@item c
+represents a @code{CHAR} constant or variable.
+
+@item i
+represents a variable or constant of integral type.
+
+@item m
+represents an identifier that belongs to a set. Generally used in the
+same function with the metavariable @var{s}. The type of @var{s} should
+be @code{SET OF @var{mtype}} (where @var{mtype} is the type of @var{m}).
+
+@item n
+represents a variable or constant of integral or floating-point type.
+
+@item r
+represents a variable or constant of floating-point type.
+
+@item t
+represents a type.
+
+@item v
+represents a variable.
+
+@item x
+represents a variable or constant of one of many types. See the
+explanation of the function for details.
+@end table
+
+All Modula-2 built-in procedures also return a result, described below.
+
+@table @code
+@item ABS(@var{n})
+Returns the absolute value of @var{n}.
+
+@item CAP(@var{c})
+If @var{c} is a lower case letter, it returns its upper case
+equivalent, otherwise it returns its argument.
+
+@item CHR(@var{i})
+Returns the character whose ordinal value is @var{i}.
+
+@item DEC(@var{v})
+Decrements the value in the variable @var{v} by one. Returns the new value.
+
+@item DEC(@var{v},@var{i})
+Decrements the value in the variable @var{v} by @var{i}. Returns the
+new value.
+
+@item EXCL(@var{m},@var{s})
+Removes the element @var{m} from the set @var{s}. Returns the new
+set.
+
+@item FLOAT(@var{i})
+Returns the floating point equivalent of the integer @var{i}.
+
+@item HIGH(@var{a})
+Returns the index of the last member of @var{a}.
+
+@item INC(@var{v})
+Increments the value in the variable @var{v} by one. Returns the new value.
+
+@item INC(@var{v},@var{i})
+Increments the value in the variable @var{v} by @var{i}. Returns the
+new value.
+
+@item INCL(@var{m},@var{s})
+Adds the element @var{m} to the set @var{s} if it is not already
+there. Returns the new set.
+
+@item MAX(@var{t})
+Returns the maximum value of the type @var{t}.
+
+@item MIN(@var{t})
+Returns the minimum value of the type @var{t}.
+
+@item ODD(@var{i})
+Returns boolean TRUE if @var{i} is an odd number.
+
+@item ORD(@var{x})
+Returns the ordinal value of its argument. For example, the ordinal
+value of a character is its @sc{ascii} value (on machines supporting the
+@sc{ascii} character set). @var{x} must be of an ordered type, which include
+integral, character and enumerated types.
+
+@item SIZE(@var{x})
+Returns the size of its argument. @var{x} can be a variable or a type.
+
+@item TRUNC(@var{r})
+Returns the integral part of @var{r}.
+
+@item VAL(@var{t},@var{i})
+Returns the member of the type @var{t} whose ordinal value is @var{i}.
+@end table
+
+@quotation
+@emph{Warning:} Sets and their operations are not yet supported, so
+@value{GDBN} treats the use of procedures @code{INCL} and @code{EXCL} as
+an error.
+@end quotation
+
+@cindex Modula-2 constants
+@node M2 Constants
+@subsubsection Constants
+
+@value{GDBN} allows you to express the constants of Modula-2 in the following
+ways:
+
+@itemize @bullet
+
+@item
+Integer constants are simply a sequence of digits. When used in an
+expression, a constant is interpreted to be type-compatible with the
+rest of the expression. Hexadecimal integers are specified by a
+trailing @samp{H}, and octal integers by a trailing @samp{B}.
+
+@item
+Floating point constants appear as a sequence of digits, followed by a
+decimal point and another sequence of digits. An optional exponent can
+then be specified, in the form @samp{E@r{[}+@r{|}-@r{]}@var{nnn}}, where
+@samp{@r{[}+@r{|}-@r{]}@var{nnn}} is the desired exponent. All of the
+digits of the floating point constant must be valid decimal (base 10)
+digits.
+
+@item
+Character constants consist of a single character enclosed by a pair of
+like quotes, either single (@code{'}) or double (@code{"}). They may
+also be expressed by their ordinal value (their @sc{ascii} value, usually)
+followed by a @samp{C}.
+
+@item
+String constants consist of a sequence of characters enclosed by a
+pair of like quotes, either single (@code{'}) or double (@code{"}).
+Escape sequences in the style of C are also allowed. @xref{C
+Constants, ,C and C@t{++} constants}, for a brief explanation of escape
+sequences.
+
+@item
+Enumerated constants consist of an enumerated identifier.
+
+@item
+Boolean constants consist of the identifiers @code{TRUE} and
+@code{FALSE}.
+
+@item
+Pointer constants consist of integral values only.
+
+@item
+Set constants are not yet supported.
+@end itemize
+
+@node M2 Defaults
+@subsubsection Modula-2 defaults
+@cindex Modula-2 defaults
+
+If type and range checking are set automatically by @value{GDBN}, they
+both default to @code{on} whenever the working language changes to
+Modula-2. This happens regardless of whether you or @value{GDBN}
+selected the working language.
+
+If you allow @value{GDBN} to set the language automatically, then entering
+code compiled from a file whose name ends with @file{.mod} sets the
+working language to Modula-2. @xref{Automatically, ,Having @value{GDBN} set
+the language automatically}, for further details.
+
+@node Deviations
+@subsubsection Deviations from standard Modula-2
+@cindex Modula-2, deviations from
+
+A few changes have been made to make Modula-2 programs easier to debug.
+This is done primarily via loosening its type strictness:
+
+@itemize @bullet
+@item
+Unlike in standard Modula-2, pointer constants can be formed by
+integers. This allows you to modify pointer variables during
+debugging. (In standard Modula-2, the actual address contained in a
+pointer variable is hidden from you; it can only be modified
+through direct assignment to another pointer variable or expression that
+returned a pointer.)
+
+@item
+C escape sequences can be used in strings and characters to represent
+non-printable characters. @value{GDBN} prints out strings with these
+escape sequences embedded. Single non-printable characters are
+printed using the @samp{CHR(@var{nnn})} format.
+
+@item
+The assignment operator (@code{:=}) returns the value of its right-hand
+argument.
+
+@item
+All built-in procedures both modify @emph{and} return their argument.
+@end itemize
+
+@node M2 Checks
+@subsubsection Modula-2 type and range checks
+@cindex Modula-2 checks
+
+@quotation
+@emph{Warning:} in this release, @value{GDBN} does not yet perform type or
+range checking.
+@end quotation
+@c FIXME remove warning when type/range checks added
+
+@value{GDBN} considers two Modula-2 variables type equivalent if:
+
+@itemize @bullet
+@item
+They are of types that have been declared equivalent via a @code{TYPE
+@var{t1} = @var{t2}} statement
+
+@item
+They have been declared on the same line. (Note: This is true of the
+@sc{gnu} Modula-2 compiler, but it may not be true of other compilers.)
+@end itemize
+
+As long as type checking is enabled, any attempt to combine variables
+whose types are not equivalent is an error.
+
+Range checking is done on all mathematical operations, assignment, array
+index bounds, and all built-in functions and procedures.
+
+@node M2 Scope
+@subsubsection The scope operators @code{::} and @code{.}
+@cindex scope
+@cindex @code{.}, Modula-2 scope operator
+@cindex colon, doubled as scope operator
+@ifinfo
+@vindex colon-colon@r{, in Modula-2}
+@c Info cannot handle :: but TeX can.
+@end ifinfo
+@iftex
+@vindex ::@r{, in Modula-2}
+@end iftex
+
+There are a few subtle differences between the Modula-2 scope operator
+(@code{.}) and the @value{GDBN} scope operator (@code{::}). The two have
+similar syntax:
+
+@smallexample
+
+@var{module} . @var{id}
+@var{scope} :: @var{id}
+@end smallexample
+
+@noindent
+where @var{scope} is the name of a module or a procedure,
+@var{module} the name of a module, and @var{id} is any declared
+identifier within your program, except another module.
+
+Using the @code{::} operator makes @value{GDBN} search the scope
+specified by @var{scope} for the identifier @var{id}. If it is not
+found in the specified scope, then @value{GDBN} searches all scopes
+enclosing the one specified by @var{scope}.
+
+Using the @code{.} operator makes @value{GDBN} search the current scope for
+the identifier specified by @var{id} that was imported from the
+definition module specified by @var{module}. With this operator, it is
+an error if the identifier @var{id} was not imported from definition
+module @var{module}, or if @var{id} is not an identifier in
+@var{module}.
+
+@node GDB/M2
+@subsubsection @value{GDBN} and Modula-2
+
+Some @value{GDBN} commands have little use when debugging Modula-2 programs.
+Five subcommands of @code{set print} and @code{show print} apply
+specifically to C and C@t{++}: @samp{vtbl}, @samp{demangle},
+@samp{asm-demangle}, @samp{object}, and @samp{union}. The first four
+apply to C@t{++}, and the last to the C @code{union} type, which has no direct
+analogue in Modula-2.
+
+The @code{@@} operator (@pxref{Expressions, ,Expressions}), while available
+with any language, is not useful with Modula-2. Its
+intent is to aid the debugging of @dfn{dynamic arrays}, which cannot be
+created in Modula-2 as they can in C or C@t{++}. However, because an
+address can be specified by an integral constant, the construct
+@samp{@{@var{type}@}@var{adrexp}} is still useful.
+
+@cindex @code{#} in Modula-2
+In @value{GDBN} scripts, the Modula-2 inequality operator @code{#} is
+interpreted as the beginning of a comment. Use @code{<>} instead.
+
+@node Chill
+@subsection Chill
+
+The extensions made to @value{GDBN} to support Chill only support output
+from the @sc{gnu} Chill compiler. Other Chill compilers are not currently
+supported, and attempting to debug executables produced by them is most
+likely to give an error as @value{GDBN} reads in the executable's symbol
+table.
+
+@c This used to say "... following Chill related topics ...", but since
+@c menus are not shown in the printed manual, it would look awkward.
+This section covers the Chill related topics and the features
+of @value{GDBN} which support these topics.
+
+@menu
+* How modes are displayed:: How modes are displayed
+* Locations:: Locations and their accesses
+* Values and their Operations:: Values and their Operations
+* Chill type and range checks::
+* Chill defaults::
+@end menu
+
+@node How modes are displayed
+@subsubsection How modes are displayed
+
+The Chill Datatype- (Mode) support of @value{GDBN} is directly related
+with the functionality of the @sc{gnu} Chill compiler, and therefore deviates
+slightly from the standard specification of the Chill language. The
+provided modes are:
+
+@c FIXME: this @table's contents effectively disable @code by using @r
+@c on every @item. So why does it need @code?
+@table @code
+@item @r{@emph{Discrete modes:}}
+@itemize @bullet
+@item
+@emph{Integer Modes} which are predefined by @code{BYTE, UBYTE, INT,
+UINT, LONG, ULONG},
+@item
+@emph{Boolean Mode} which is predefined by @code{BOOL},
+@item
+@emph{Character Mode} which is predefined by @code{CHAR},
+@item
+@emph{Set Mode} which is displayed by the keyword @code{SET}.
+@smallexample
+(@value{GDBP}) ptype x
+type = SET (karli = 10, susi = 20, fritzi = 100)
+@end smallexample
+If the type is an unnumbered set the set element values are omitted.
+@item
+@emph{Range Mode} which is displayed by
+@smallexample
+@code{type = <basemode>(<lower bound> : <upper bound>)}
+@end smallexample
+where @code{<lower bound>, <upper bound>} can be of any discrete literal
+expression (e.g. set element names).
+@end itemize
+
+@item @r{@emph{Powerset Mode:}}
+A Powerset Mode is displayed by the keyword @code{POWERSET} followed by
+the member mode of the powerset. The member mode can be any discrete mode.
+@smallexample
+(@value{GDBP}) ptype x
+type = POWERSET SET (egon, hugo, otto)
+@end smallexample
+
+@item @r{@emph{Reference Modes:}}
+@itemize @bullet
+@item
+@emph{Bound Reference Mode} which is displayed by the keyword @code{REF}
+followed by the mode name to which the reference is bound.
+@item
+@emph{Free Reference Mode} which is displayed by the keyword @code{PTR}.
+@end itemize
+
+@item @r{@emph{Procedure mode}}
+The procedure mode is displayed by @code{type = PROC(<parameter list>)
+<return mode> EXCEPTIONS (<exception list>)}. The @code{<parameter
+list>} is a list of the parameter modes. @code{<return mode>} indicates
+the mode of the result of the procedure if any. The exceptionlist lists
+all possible exceptions which can be raised by the procedure.
+
+@ignore
+@item @r{@emph{Instance mode}}
+The instance mode is represented by a structure, which has a static
+type, and is therefore not really of interest.
+@end ignore
+
+@item @r{@emph{Synchronization Modes:}}
+@itemize @bullet
+@item
+@emph{Event Mode} which is displayed by
+@smallexample
+@code{EVENT (<event length>)}
+@end smallexample
+where @code{(<event length>)} is optional.
+@item
+@emph{Buffer Mode} which is displayed by
+@smallexample
+@code{BUFFER (<buffer length>)<buffer element mode>}
+@end smallexample
+where @code{(<buffer length>)} is optional.
+@end itemize
+
+@item @r{@emph{Timing Modes:}}
+@itemize @bullet
+@item
+@emph{Duration Mode} which is predefined by @code{DURATION}
+@item
+@emph{Absolute Time Mode} which is predefined by @code{TIME}
+@end itemize
+
+@item @r{@emph{Real Modes:}}
+Real Modes are predefined with @code{REAL} and @code{LONG_REAL}.
+
+@item @r{@emph{String Modes:}}
+@itemize @bullet
+@item
+@emph{Character String Mode} which is displayed by
+@smallexample
+@code{CHARS(<string length>)}
+@end smallexample
+followed by the keyword @code{VARYING} if the String Mode is a varying
+mode
+@item
+@emph{Bit String Mode} which is displayed by
+@smallexample
+@code{BOOLS(<string
+length>)}
+@end smallexample
+@end itemize
+
+@item @r{@emph{Array Mode:}}
+The Array Mode is displayed by the keyword @code{ARRAY(<range>)}
+followed by the element mode (which may in turn be an array mode).
+@smallexample
+(@value{GDBP}) ptype x
+type = ARRAY (1:42)
+ ARRAY (1:20)
+ SET (karli = 10, susi = 20, fritzi = 100)
+@end smallexample
+
+@item @r{@emph{Structure Mode}}
+The Structure mode is displayed by the keyword @code{STRUCT(<field
+list>)}. The @code{<field list>} consists of names and modes of fields
+of the structure. Variant structures have the keyword @code{CASE <field>
+OF <variant fields> ESAC} in their field list. Since the current version
+of the GNU Chill compiler doesn't implement tag processing (no runtime
+checks of variant fields, and therefore no debugging info), the output
+always displays all variant fields.
+@smallexample
+(@value{GDBP}) ptype str
+type = STRUCT (
+ as x,
+ bs x,
+ CASE bs OF
+ (karli):
+ cs a
+ (ott):
+ ds x
+ ESAC
+)
+@end smallexample
+@end table
+
+@node Locations
+@subsubsection Locations and their accesses
+
+A location in Chill is an object which can contain values.
+
+A value of a location is generally accessed by the (declared) name of
+the location. The output conforms to the specification of values in
+Chill programs. How values are specified
+is the topic of the next section, @ref{Values and their Operations}.
+
+The pseudo-location @code{RESULT} (or @code{result}) can be used to
+display or change the result of a currently-active procedure:
+
+@smallexample
+set result := EXPR
+@end smallexample
+
+@noindent
+This does the same as the Chill action @code{RESULT EXPR} (which
+is not available in @value{GDBN}).
+
+Values of reference mode locations are printed by @code{PTR(<hex
+value>)} in case of a free reference mode, and by @code{(REF <reference
+mode>) (<hex-value>)} in case of a bound reference. @code{<hex value>}
+represents the address where the reference points to. To access the
+value of the location referenced by the pointer, use the dereference
+operator @samp{->}.
+
+Values of procedure mode locations are displayed by
+@smallexample
+@code{@{ PROC
+(<argument modes> ) <return mode> @} <address> <name of procedure
+location>}
+@end smallexample
+@code{<argument modes>} is a list of modes according to the parameter
+specification of the procedure and @code{<address>} shows the address of
+the entry point.
+
+@ignore
+Locations of instance modes are displayed just like a structure with two
+fields specifying the @emph{process type} and the @emph{copy number} of
+the investigated instance location@footnote{This comes from the current
+implementation of instances. They are implemented as a structure (no
+na). The output should be something like @code{[<name of the process>;
+<instance number>]}.}. The field names are @code{__proc_type} and
+@code{__proc_copy}.
+
+Locations of synchronization modes are displayed like a structure with
+the field name @code{__event_data} in case of a event mode location, and
+like a structure with the field @code{__buffer_data} in case of a buffer
+mode location (refer to previous paragraph).
+
+Structure Mode locations are printed by @code{[.<field name>: <value>,
+...]}. The @code{<field name>} corresponds to the structure mode
+definition and the layout of @code{<value>} varies depending of the mode
+of the field. If the investigated structure mode location is of variant
+structure mode, the variant parts of the structure are enclosed in curled
+braces (@samp{@{@}}). Fields enclosed by @samp{@{,@}} are residing
+on the same memory location and represent the current values of the
+memory location in their specific modes. Since no tag processing is done
+all variants are displayed. A variant field is printed by
+@code{(<variant name>) = .<field name>: <value>}. (who implements the
+stuff ???)
+@smallexample
+(@value{GDBP}) print str1 $4 = [.as: 0, .bs: karli, .<TAG>: { (karli) =
+[.cs: []], (susi) = [.ds: susi]}]
+@end smallexample
+@end ignore
+
+Substructures of string mode-, array mode- or structure mode-values
+(e.g. array slices, fields of structure locations) are accessed using
+certain operations which are described in the next section, @ref{Values
+and their Operations}.
+
+A location value may be interpreted as having a different mode using the
+location conversion. This mode conversion is written as @code{<mode
+name>(<location>)}. The user has to consider that the sizes of the modes
+have to be equal otherwise an error occurs. Furthermore, no range
+checking of the location against the destination mode is performed, and
+therefore the result can be quite confusing.
+
+@smallexample
+(@value{GDBP}) print int (s(3 up 4)) XXX TO be filled in !! XXX
+@end smallexample
+
+@node Values and their Operations
+@subsubsection Values and their Operations
+
+Values are used to alter locations, to investigate complex structures in
+more detail or to filter relevant information out of a large amount of
+data. There are several (mode dependent) operations defined which enable
+such investigations. These operations are not only applicable to
+constant values but also to locations, which can become quite useful
+when debugging complex structures. During parsing the command line
+(e.g. evaluating an expression) @value{GDBN} treats location names as
+the values behind these locations.
+
+This section describes how values have to be specified and which
+operations are legal to be used with such values.
+
+@table @code
+@item Literal Values
+Literal values are specified in the same manner as in @sc{gnu} Chill programs.
+For detailed specification refer to the @sc{gnu} Chill implementation Manual
+chapter 1.5.
+@c FIXME: if the Chill Manual is a Texinfo documents, the above should
+@c be converted to a @ref.
+
+@ignore
+@itemize @bullet
+@item
+@emph{Integer Literals} are specified in the same manner as in Chill
+programs (refer to the Chill Standard z200/88 chpt 5.2.4.2)
+@item
+@emph{Boolean Literals} are defined by @code{TRUE} and @code{FALSE}.
+@item
+@emph{Character Literals} are defined by @code{'<character>'}. (e.g.
+@code{'M'})
+@item
+@emph{Set Literals} are defined by a name which was specified in a set
+mode. The value delivered by a Set Literal is the set value. This is
+comparable to an enumeration in C/C@t{++} language.
+@item
+@emph{Emptiness Literal} is predefined by @code{NULL}. The value of the
+emptiness literal delivers either the empty reference value, the empty
+procedure value or the empty instance value.
+
+@item
+@emph{Character String Literals} are defined by a sequence of characters
+enclosed in single- or double quotes. If a single- or double quote has
+to be part of the string literal it has to be stuffed (specified twice).
+@item
+@emph{Bitstring Literals} are specified in the same manner as in Chill
+programs (refer z200/88 chpt 5.2.4.8).
+@item
+@emph{Floating point literals} are specified in the same manner as in
+(gnu-)Chill programs (refer @sc{gnu} Chill implementation Manual chapter 1.5).
+@end itemize
+@end ignore
+
+@item Tuple Values
+A tuple is specified by @code{<mode name>[<tuple>]}, where @code{<mode
+name>} can be omitted if the mode of the tuple is unambiguous. This
+unambiguity is derived from the context of a evaluated expression.
+@code{<tuple>} can be one of the following:
+
+@itemize @bullet
+@item @emph{Powerset Tuple}
+@item @emph{Array Tuple}
+@item @emph{Structure Tuple}
+Powerset tuples, array tuples and structure tuples are specified in the
+same manner as in Chill programs refer to z200/88 chpt 5.2.5.
+@end itemize
+
+@item String Element Value
+A string element value is specified by
+@smallexample
+@code{<string value>(<index>)}
+@end smallexample
+where @code{<index>} is a integer expression. It delivers a character
+value which is equivalent to the character indexed by @code{<index>} in
+the string.
+
+@item String Slice Value
+A string slice value is specified by @code{<string value>(<slice
+spec>)}, where @code{<slice spec>} can be either a range of integer
+expressions or specified by @code{<start expr> up <size>}.
+@code{<size>} denotes the number of elements which the slice contains.
+The delivered value is a string value, which is part of the specified
+string.
+
+@item Array Element Values
+An array element value is specified by @code{<array value>(<expr>)} and
+delivers a array element value of the mode of the specified array.
+
+@item Array Slice Values
+An array slice is specified by @code{<array value>(<slice spec>)}, where
+@code{<slice spec>} can be either a range specified by expressions or by
+@code{<start expr> up <size>}. @code{<size>} denotes the number of
+arrayelements the slice contains. The delivered value is an array value
+which is part of the specified array.
+
+@item Structure Field Values
+A structure field value is derived by @code{<structure value>.<field
+name>}, where @code{<field name>} indicates the name of a field specified
+in the mode definition of the structure. The mode of the delivered value
+corresponds to this mode definition in the structure definition.
+
+@item Procedure Call Value
+The procedure call value is derived from the return value of the
+procedure@footnote{If a procedure call is used for instance in an
+expression, then this procedure is called with all its side
+effects. This can lead to confusing results if used carelessly.}.
+
+Values of duration mode locations are represented by @code{ULONG} literals.
+
+Values of time mode locations appear as
+@smallexample
+@code{TIME(<secs>:<nsecs>)}
+@end smallexample
+
+
+@ignore
+This is not implemented yet:
+@item Built-in Value
+@noindent
+The following built in functions are provided:
+
+@table @code
+@item @code{ADDR()}
+@item @code{NUM()}
+@item @code{PRED()}
+@item @code{SUCC()}
+@item @code{ABS()}
+@item @code{CARD()}
+@item @code{MAX()}
+@item @code{MIN()}
+@item @code{SIZE()}
+@item @code{UPPER()}
+@item @code{LOWER()}
+@item @code{LENGTH()}
+@item @code{SIN()}
+@item @code{COS()}
+@item @code{TAN()}
+@item @code{ARCSIN()}
+@item @code{ARCCOS()}
+@item @code{ARCTAN()}
+@item @code{EXP()}
+@item @code{LN()}
+@item @code{LOG()}
+@item @code{SQRT()}
+@end table
+
+For a detailed description refer to the GNU Chill implementation manual
+chapter 1.6.
+@end ignore
+
+@item Zero-adic Operator Value
+The zero-adic operator value is derived from the instance value for the
+current active process.
+
+@item Expression Values
+The value delivered by an expression is the result of the evaluation of
+the specified expression. If there are error conditions (mode
+incompatibility, etc.) the evaluation of expressions is aborted with a
+corresponding error message. Expressions may be parenthesised which
+causes the evaluation of this expression before any other expression
+which uses the result of the parenthesised expression. The following
+operators are supported by @value{GDBN}:
+
+@table @code
+@item @code{OR, ORIF, XOR}
+@itemx @code{AND, ANDIF}
+@itemx @code{NOT}
+Logical operators defined over operands of boolean mode.
+
+@item @code{=, /=}
+Equality and inequality operators defined over all modes.
+
+@item @code{>, >=}
+@itemx @code{<, <=}
+Relational operators defined over predefined modes.
+
+@item @code{+, -}
+@itemx @code{*, /, MOD, REM}
+Arithmetic operators defined over predefined modes.
+
+@item @code{-}
+Change sign operator.
+
+@item @code{//}
+String concatenation operator.
+
+@item @code{()}
+String repetition operator.
+
+@item @code{->}
+Referenced location operator which can be used either to take the
+address of a location (@code{->loc}), or to dereference a reference
+location (@code{loc->}).
+
+@item @code{OR, XOR}
+@itemx @code{AND}
+@itemx @code{NOT}
+Powerset and bitstring operators.
+
+@item @code{>, >=}
+@itemx @code{<, <=}
+Powerset inclusion operators.
+
+@item @code{IN}
+Membership operator.
+@end table
+@end table
+
+@node Chill type and range checks
+@subsubsection Chill type and range checks
+
+@value{GDBN} considers two Chill variables mode equivalent if the sizes
+of the two modes are equal. This rule applies recursively to more
+complex datatypes which means that complex modes are treated
+equivalent if all element modes (which also can be complex modes like
+structures, arrays, etc.) have the same size.
+
+Range checking is done on all mathematical operations, assignment, array
+index bounds and all built in procedures.
+
+Strong type checks are forced using the @value{GDBN} command @code{set
+check strong}. This enforces strong type and range checks on all
+operations where Chill constructs are used (expressions, built in
+functions, etc.) in respect to the semantics as defined in the z.200
+language specification.
+
+All checks can be disabled by the @value{GDBN} command @code{set check
+off}.
+
+@ignore
+@c Deviations from the Chill Standard Z200/88
+see last paragraph ?
+@end ignore
+
+@node Chill defaults
+@subsubsection Chill defaults
+
+If type and range checking are set automatically by @value{GDBN}, they
+both default to @code{on} whenever the working language changes to
+Chill. This happens regardless of whether you or @value{GDBN}
+selected the working language.
+
+If you allow @value{GDBN} to set the language automatically, then entering
+code compiled from a file whose name ends with @file{.ch} sets the
+working language to Chill. @xref{Automatically, ,Having @value{GDBN} set
+the language automatically}, for further details.
+
+@node Symbols
+@chapter Examining the Symbol Table
+
+The commands described in this chapter allow you to inquire about the
+symbols (names of variables, functions and types) defined in your
+program. This information is inherent in the text of your program and
+does not change as your program executes. @value{GDBN} finds it in your
+program's symbol table, in the file indicated when you started @value{GDBN}
+(@pxref{File Options, ,Choosing files}), or by one of the
+file-management commands (@pxref{Files, ,Commands to specify files}).
+
+@cindex symbol names
+@cindex names of symbols
+@cindex quoting names
+Occasionally, you may need to refer to symbols that contain unusual
+characters, which @value{GDBN} ordinarily treats as word delimiters. The
+most frequent case is in referring to static variables in other
+source files (@pxref{Variables,,Program variables}). File names
+are recorded in object files as debugging symbols, but @value{GDBN} would
+ordinarily parse a typical file name, like @file{foo.c}, as the three words
+@samp{foo} @samp{.} @samp{c}. To allow @value{GDBN} to recognize
+@samp{foo.c} as a single symbol, enclose it in single quotes; for example,
+
+@smallexample
+p 'foo.c'::x
+@end smallexample
+
+@noindent
+looks up the value of @code{x} in the scope of the file @file{foo.c}.
+
+@table @code
+@kindex info address
+@cindex address of a symbol
+@item info address @var{symbol}
+Describe where the data for @var{symbol} is stored. For a register
+variable, this says which register it is kept in. For a non-register
+local variable, this prints the stack-frame offset at which the variable
+is always stored.
+
+Note the contrast with @samp{print &@var{symbol}}, which does not work
+at all for a register variable, and for a stack local variable prints
+the exact address of the current instantiation of the variable.
+
+@kindex info symbol
+@cindex symbol from address
+@item info symbol @var{addr}
+Print the name of a symbol which is stored at the address @var{addr}.
+If no symbol is stored exactly at @var{addr}, @value{GDBN} prints the
+nearest symbol and an offset from it:
+
+@smallexample
+(@value{GDBP}) info symbol 0x54320
+_initialize_vx + 396 in section .text
+@end smallexample
+
+@noindent
+This is the opposite of the @code{info address} command. You can use
+it to find out the name of a variable or a function given its address.
+
+@kindex whatis
+@item whatis @var{expr}
+Print the data type of expression @var{expr}. @var{expr} is not
+actually evaluated, and any side-effecting operations (such as
+assignments or function calls) inside it do not take place.
+@xref{Expressions, ,Expressions}.
+
+@item whatis
+Print the data type of @code{$}, the last value in the value history.
+
+@kindex ptype
+@item ptype @var{typename}
+Print a description of data type @var{typename}. @var{typename} may be
+the name of a type, or for C code it may have the form @samp{class
+@var{class-name}}, @samp{struct @var{struct-tag}}, @samp{union
+@var{union-tag}} or @samp{enum @var{enum-tag}}.
+
+@item ptype @var{expr}
+@itemx ptype
+Print a description of the type of expression @var{expr}. @code{ptype}
+differs from @code{whatis} by printing a detailed description, instead
+of just the name of the type.
+
+For example, for this variable declaration:
+
+@smallexample
+struct complex @{double real; double imag;@} v;
+@end smallexample
+
+@noindent
+the two commands give this output:
+
+@smallexample
+@group
+(@value{GDBP}) whatis v
+type = struct complex
+(@value{GDBP}) ptype v
+type = struct complex @{
+ double real;
+ double imag;
+@}
+@end group
+@end smallexample
+
+@noindent
+As with @code{whatis}, using @code{ptype} without an argument refers to
+the type of @code{$}, the last value in the value history.
+
+@kindex info types
+@item info types @var{regexp}
+@itemx info types
+Print a brief description of all types whose names match @var{regexp}
+(or all types in your program, if you supply no argument). Each
+complete typename is matched as though it were a complete line; thus,
+@samp{i type value} gives information on all types in your program whose
+names include the string @code{value}, but @samp{i type ^value$} gives
+information only on types whose complete name is @code{value}.
+
+This command differs from @code{ptype} in two ways: first, like
+@code{whatis}, it does not print a detailed description; second, it
+lists all source files where a type is defined.
+
+@kindex info scope
+@cindex local variables
+@item info scope @var{addr}
+List all the variables local to a particular scope. This command
+accepts a location---a function name, a source line, or an address
+preceded by a @samp{*}, and prints all the variables local to the
+scope defined by that location. For example:
+
+@smallexample
+(@value{GDBP}) @b{info scope command_line_handler}
+Scope for command_line_handler:
+Symbol rl is an argument at stack/frame offset 8, length 4.
+Symbol linebuffer is in static storage at address 0x150a18, length 4.
+Symbol linelength is in static storage at address 0x150a1c, length 4.
+Symbol p is a local variable in register $esi, length 4.
+Symbol p1 is a local variable in register $ebx, length 4.
+Symbol nline is a local variable in register $edx, length 4.
+Symbol repeat is a local variable at frame offset -8, length 4.
+@end smallexample
+
+@noindent
+This command is especially useful for determining what data to collect
+during a @dfn{trace experiment}, see @ref{Tracepoint Actions,
+collect}.
+
+@kindex info source
+@item info source
+Show the name of the current source file---that is, the source file for
+the function containing the current point of execution---and the language
+it was written in.
+
+@kindex info sources
+@item info sources
+Print the names of all source files in your program for which there is
+debugging information, organized into two lists: files whose symbols
+have already been read, and files whose symbols will be read when needed.
+
+@kindex info functions
+@item info functions
+Print the names and data types of all defined functions.
+
+@item info functions @var{regexp}
+Print the names and data types of all defined functions
+whose names contain a match for regular expression @var{regexp}.
+Thus, @samp{info fun step} finds all functions whose names
+include @code{step}; @samp{info fun ^step} finds those whose names
+start with @code{step}. If a function name contains characters
+that conflict with the regular expression language (eg.
+@samp{operator*()}), they may be quoted with a backslash.
+
+@kindex info variables
+@item info variables
+Print the names and data types of all variables that are declared
+outside of functions (i.e.@: excluding local variables).
+
+@item info variables @var{regexp}
+Print the names and data types of all variables (except for local
+variables) whose names contain a match for regular expression
+@var{regexp}.
+
+@ignore
+This was never implemented.
+@kindex info methods
+@item info methods
+@itemx info methods @var{regexp}
+The @code{info methods} command permits the user to examine all defined
+methods within C@t{++} program, or (with the @var{regexp} argument) a
+specific set of methods found in the various C@t{++} classes. Many
+C@t{++} classes provide a large number of methods. Thus, the output
+from the @code{ptype} command can be overwhelming and hard to use. The
+@code{info-methods} command filters the methods, printing only those
+which match the regular-expression @var{regexp}.
+@end ignore
+
+@cindex reloading symbols
+Some systems allow individual object files that make up your program to
+be replaced without stopping and restarting your program. For example,
+in VxWorks you can simply recompile a defective object file and keep on
+running. If you are running on one of these systems, you can allow
+@value{GDBN} to reload the symbols for automatically relinked modules:
+
+@table @code
+@kindex set symbol-reloading
+@item set symbol-reloading on
+Replace symbol definitions for the corresponding source file when an
+object file with a particular name is seen again.
+
+@item set symbol-reloading off
+Do not replace symbol definitions when encountering object files of the
+same name more than once. This is the default state; if you are not
+running on a system that permits automatic relinking of modules, you
+should leave @code{symbol-reloading} off, since otherwise @value{GDBN}
+may discard symbols when linking large programs, that may contain
+several modules (from different directories or libraries) with the same
+name.
+
+@kindex show symbol-reloading
+@item show symbol-reloading
+Show the current @code{on} or @code{off} setting.
+@end table
+
+@kindex set opaque-type-resolution
+@item set opaque-type-resolution on
+Tell @value{GDBN} to resolve opaque types. An opaque type is a type
+declared as a pointer to a @code{struct}, @code{class}, or
+@code{union}---for example, @code{struct MyType *}---that is used in one
+source file although the full declaration of @code{struct MyType} is in
+another source file. The default is on.
+
+A change in the setting of this subcommand will not take effect until
+the next time symbols for a file are loaded.
+
+@item set opaque-type-resolution off
+Tell @value{GDBN} not to resolve opaque types. In this case, the type
+is printed as follows:
+@smallexample
+@{<no data fields>@}
+@end smallexample
+
+@kindex show opaque-type-resolution
+@item show opaque-type-resolution
+Show whether opaque types are resolved or not.
+
+@kindex maint print symbols
+@cindex symbol dump
+@kindex maint print psymbols
+@cindex partial symbol dump
+@item maint print symbols @var{filename}
+@itemx maint print psymbols @var{filename}
+@itemx maint print msymbols @var{filename}
+Write a dump of debugging symbol data into the file @var{filename}.
+These commands are used to debug the @value{GDBN} symbol-reading code. Only
+symbols with debugging data are included. If you use @samp{maint print
+symbols}, @value{GDBN} includes all the symbols for which it has already
+collected full details: that is, @var{filename} reflects symbols for
+only those files whose symbols @value{GDBN} has read. You can use the
+command @code{info sources} to find out which files these are. If you
+use @samp{maint print psymbols} instead, the dump shows information about
+symbols that @value{GDBN} only knows partially---that is, symbols defined in
+files that @value{GDBN} has skimmed, but not yet read completely. Finally,
+@samp{maint print msymbols} dumps just the minimal symbol information
+required for each object file from which @value{GDBN} has read some symbols.
+@xref{Files, ,Commands to specify files}, for a discussion of how
+@value{GDBN} reads symbols (in the description of @code{symbol-file}).
+@end table
+
+@node Altering
+@chapter Altering Execution
+
+Once you think you have found an error in your program, you might want to
+find out for certain whether correcting the apparent error would lead to
+correct results in the rest of the run. You can find the answer by
+experiment, using the @value{GDBN} features for altering execution of the
+program.
+
+For example, you can store new values into variables or memory
+locations, give your program a signal, restart it at a different
+address, or even return prematurely from a function.
+
+@menu
+* Assignment:: Assignment to variables
+* Jumping:: Continuing at a different address
+* Signaling:: Giving your program a signal
+* Returning:: Returning from a function
+* Calling:: Calling your program's functions
+* Patching:: Patching your program
+@end menu
+
+@node Assignment
+@section Assignment to variables
+
+@cindex assignment
+@cindex setting variables
+To alter the value of a variable, evaluate an assignment expression.
+@xref{Expressions, ,Expressions}. For example,
+
+@smallexample
+print x=4
+@end smallexample
+
+@noindent
+stores the value 4 into the variable @code{x}, and then prints the
+value of the assignment expression (which is 4).
+@xref{Languages, ,Using @value{GDBN} with Different Languages}, for more
+information on operators in supported languages.
+
+@kindex set variable
+@cindex variables, setting
+If you are not interested in seeing the value of the assignment, use the
+@code{set} command instead of the @code{print} command. @code{set} is
+really the same as @code{print} except that the expression's value is
+not printed and is not put in the value history (@pxref{Value History,
+,Value history}). The expression is evaluated only for its effects.
+
+If the beginning of the argument string of the @code{set} command
+appears identical to a @code{set} subcommand, use the @code{set
+variable} command instead of just @code{set}. This command is identical
+to @code{set} except for its lack of subcommands. For example, if your
+program has a variable @code{width}, you get an error if you try to set
+a new value with just @samp{set width=13}, because @value{GDBN} has the
+command @code{set width}:
+
+@smallexample
+(@value{GDBP}) whatis width
+type = double
+(@value{GDBP}) p width
+$4 = 13
+(@value{GDBP}) set width=47
+Invalid syntax in expression.
+@end smallexample
+
+@noindent
+The invalid expression, of course, is @samp{=47}. In
+order to actually set the program's variable @code{width}, use
+
+@smallexample
+(@value{GDBP}) set var width=47
+@end smallexample
+
+Because the @code{set} command has many subcommands that can conflict
+with the names of program variables, it is a good idea to use the
+@code{set variable} command instead of just @code{set}. For example, if
+your program has a variable @code{g}, you run into problems if you try
+to set a new value with just @samp{set g=4}, because @value{GDBN} has
+the command @code{set gnutarget}, abbreviated @code{set g}:
+
+@smallexample
+@group
+(@value{GDBP}) whatis g
+type = double
+(@value{GDBP}) p g
+$1 = 1
+(@value{GDBP}) set g=4
+(@value{GDBP}) p g
+$2 = 1
+(@value{GDBP}) r
+The program being debugged has been started already.
+Start it from the beginning? (y or n) y
+Starting program: /home/smith/cc_progs/a.out
+"/home/smith/cc_progs/a.out": can't open to read symbols:
+ Invalid bfd target.
+(@value{GDBP}) show g
+The current BFD target is "=4".
+@end group
+@end smallexample
+
+@noindent
+The program variable @code{g} did not change, and you silently set the
+@code{gnutarget} to an invalid value. In order to set the variable
+@code{g}, use
+
+@smallexample
+(@value{GDBP}) set var g=4
+@end smallexample
+
+@value{GDBN} allows more implicit conversions in assignments than C; you can
+freely store an integer value into a pointer variable or vice versa,
+and you can convert any structure to any other structure that is the
+same length or shorter.
+@comment FIXME: how do structs align/pad in these conversions?
+@comment /doc@cygnus.com 18dec1990
+
+To store values into arbitrary places in memory, use the @samp{@{@dots{}@}}
+construct to generate a value of specified type at a specified address
+(@pxref{Expressions, ,Expressions}). For example, @code{@{int@}0x83040} refers
+to memory location @code{0x83040} as an integer (which implies a certain size
+and representation in memory), and
+
+@smallexample
+set @{int@}0x83040 = 4
+@end smallexample
+
+@noindent
+stores the value 4 into that memory location.
+
+@node Jumping
+@section Continuing at a different address
+
+Ordinarily, when you continue your program, you do so at the place where
+it stopped, with the @code{continue} command. You can instead continue at
+an address of your own choosing, with the following commands:
+
+@table @code
+@kindex jump
+@item jump @var{linespec}
+Resume execution at line @var{linespec}. Execution stops again
+immediately if there is a breakpoint there. @xref{List, ,Printing
+source lines}, for a description of the different forms of
+@var{linespec}. It is common practice to use the @code{tbreak} command
+in conjunction with @code{jump}. @xref{Set Breaks, ,Setting
+breakpoints}.
+
+The @code{jump} command does not change the current stack frame, or
+the stack pointer, or the contents of any memory location or any
+register other than the program counter. If line @var{linespec} is in
+a different function from the one currently executing, the results may
+be bizarre if the two functions expect different patterns of arguments or
+of local variables. For this reason, the @code{jump} command requests
+confirmation if the specified line is not in the function currently
+executing. However, even bizarre results are predictable if you are
+well acquainted with the machine-language code of your program.
+
+@item jump *@var{address}
+Resume execution at the instruction at address @var{address}.
+@end table
+
+@c Doesn't work on HP-UX; have to set $pcoqh and $pcoqt.
+On many systems, you can get much the same effect as the @code{jump}
+command by storing a new value into the register @code{$pc}. The
+difference is that this does not start your program running; it only
+changes the address of where it @emph{will} run when you continue. For
+example,
+
+@smallexample
+set $pc = 0x485
+@end smallexample
+
+@noindent
+makes the next @code{continue} command or stepping command execute at
+address @code{0x485}, rather than at the address where your program stopped.
+@xref{Continuing and Stepping, ,Continuing and stepping}.
+
+The most common occasion to use the @code{jump} command is to back
+up---perhaps with more breakpoints set---over a portion of a program
+that has already executed, in order to examine its execution in more
+detail.
+
+@c @group
+@node Signaling
+@section Giving your program a signal
+
+@table @code
+@kindex signal
+@item signal @var{signal}
+Resume execution where your program stopped, but immediately give it the
+signal @var{signal}. @var{signal} can be the name or the number of a
+signal. For example, on many systems @code{signal 2} and @code{signal
+SIGINT} are both ways of sending an interrupt signal.
+
+Alternatively, if @var{signal} is zero, continue execution without
+giving a signal. This is useful when your program stopped on account of
+a signal and would ordinary see the signal when resumed with the
+@code{continue} command; @samp{signal 0} causes it to resume without a
+signal.
+
+@code{signal} does not repeat when you press @key{RET} a second time
+after executing the command.
+@end table
+@c @end group
+
+Invoking the @code{signal} command is not the same as invoking the
+@code{kill} utility from the shell. Sending a signal with @code{kill}
+causes @value{GDBN} to decide what to do with the signal depending on
+the signal handling tables (@pxref{Signals}). The @code{signal} command
+passes the signal directly to your program.
+
+
+@node Returning
+@section Returning from a function
+
+@table @code
+@cindex returning from a function
+@kindex return
+@item return
+@itemx return @var{expression}
+You can cancel execution of a function call with the @code{return}
+command. If you give an
+@var{expression} argument, its value is used as the function's return
+value.
+@end table
+
+When you use @code{return}, @value{GDBN} discards the selected stack frame
+(and all frames within it). You can think of this as making the
+discarded frame return prematurely. If you wish to specify a value to
+be returned, give that value as the argument to @code{return}.
+
+This pops the selected stack frame (@pxref{Selection, ,Selecting a
+frame}), and any other frames inside of it, leaving its caller as the
+innermost remaining frame. That frame becomes selected. The
+specified value is stored in the registers used for returning values
+of functions.
+
+The @code{return} command does not resume execution; it leaves the
+program stopped in the state that would exist if the function had just
+returned. In contrast, the @code{finish} command (@pxref{Continuing
+and Stepping, ,Continuing and stepping}) resumes execution until the
+selected stack frame returns naturally.
+
+@node Calling
+@section Calling program functions
+
+@cindex calling functions
+@kindex call
+@table @code
+@item call @var{expr}
+Evaluate the expression @var{expr} without displaying @code{void}
+returned values.
+@end table
+
+You can use this variant of the @code{print} command if you want to
+execute a function from your program, but without cluttering the output
+with @code{void} returned values. If the result is not void, it
+is printed and saved in the value history.
+
+@node Patching
+@section Patching programs
+
+@cindex patching binaries
+@cindex writing into executables
+@cindex writing into corefiles
+
+By default, @value{GDBN} opens the file containing your program's
+executable code (or the corefile) read-only. This prevents accidental
+alterations to machine code; but it also prevents you from intentionally
+patching your program's binary.
+
+If you'd like to be able to patch the binary, you can specify that
+explicitly with the @code{set write} command. For example, you might
+want to turn on internal debugging flags, or even to make emergency
+repairs.
+
+@table @code
+@kindex set write
+@item set write on
+@itemx set write off
+If you specify @samp{set write on}, @value{GDBN} opens executable and
+core files for both reading and writing; if you specify @samp{set write
+off} (the default), @value{GDBN} opens them read-only.
+
+If you have already loaded a file, you must load it again (using the
+@code{exec-file} or @code{core-file} command) after changing @code{set
+write}, for your new setting to take effect.
+
+@item show write
+@kindex show write
+Display whether executable files and core files are opened for writing
+as well as reading.
+@end table
+
+@node GDB Files
+@chapter @value{GDBN} Files
+
+@value{GDBN} needs to know the file name of the program to be debugged,
+both in order to read its symbol table and in order to start your
+program. To debug a core dump of a previous run, you must also tell
+@value{GDBN} the name of the core dump file.
+
+@menu
+* Files:: Commands to specify files
+* Symbol Errors:: Errors reading symbol files
+@end menu
+
+@node Files
+@section Commands to specify files
+
+@cindex symbol table
+@cindex core dump file
+
+You may want to specify executable and core dump file names. The usual
+way to do this is at start-up time, using the arguments to
+@value{GDBN}'s start-up commands (@pxref{Invocation, , Getting In and
+Out of @value{GDBN}}).
+
+Occasionally it is necessary to change to a different file during a
+@value{GDBN} session. Or you may run @value{GDBN} and forget to specify
+a file you want to use. In these situations the @value{GDBN} commands
+to specify new files are useful.
+
+@table @code
+@cindex executable file
+@kindex file
+@item file @var{filename}
+Use @var{filename} as the program to be debugged. It is read for its
+symbols and for the contents of pure memory. It is also the program
+executed when you use the @code{run} command. If you do not specify a
+directory and the file is not found in the @value{GDBN} working directory,
+@value{GDBN} uses the environment variable @code{PATH} as a list of
+directories to search, just as the shell does when looking for a program
+to run. You can change the value of this variable, for both @value{GDBN}
+and your program, using the @code{path} command.
+
+On systems with memory-mapped files, an auxiliary file named
+@file{@var{filename}.syms} may hold symbol table information for
+@var{filename}. If so, @value{GDBN} maps in the symbol table from
+@file{@var{filename}.syms}, starting up more quickly. See the
+descriptions of the file options @samp{-mapped} and @samp{-readnow}
+(available on the command line, and with the commands @code{file},
+@code{symbol-file}, or @code{add-symbol-file}, described below),
+for more information.
+
+@item file
+@code{file} with no argument makes @value{GDBN} discard any information it
+has on both executable file and the symbol table.
+
+@kindex exec-file
+@item exec-file @r{[} @var{filename} @r{]}
+Specify that the program to be run (but not the symbol table) is found
+in @var{filename}. @value{GDBN} searches the environment variable @code{PATH}
+if necessary to locate your program. Omitting @var{filename} means to
+discard information on the executable file.
+
+@kindex symbol-file
+@item symbol-file @r{[} @var{filename} @r{]}
+Read symbol table information from file @var{filename}. @code{PATH} is
+searched when necessary. Use the @code{file} command to get both symbol
+table and program to run from the same file.
+
+@code{symbol-file} with no argument clears out @value{GDBN} information on your
+program's symbol table.
+
+The @code{symbol-file} command causes @value{GDBN} to forget the contents
+of its convenience variables, the value history, and all breakpoints and
+auto-display expressions. This is because they may contain pointers to
+the internal data recording symbols and data types, which are part of
+the old symbol table data being discarded inside @value{GDBN}.
+
+@code{symbol-file} does not repeat if you press @key{RET} again after
+executing it once.
+
+When @value{GDBN} is configured for a particular environment, it
+understands debugging information in whatever format is the standard
+generated for that environment; you may use either a @sc{gnu} compiler, or
+other compilers that adhere to the local conventions.
+Best results are usually obtained from @sc{gnu} compilers; for example,
+using @code{@value{GCC}} you can generate debugging information for
+optimized code.
+
+For most kinds of object files, with the exception of old SVR3 systems
+using COFF, the @code{symbol-file} command does not normally read the
+symbol table in full right away. Instead, it scans the symbol table
+quickly to find which source files and which symbols are present. The
+details are read later, one source file at a time, as they are needed.
+
+The purpose of this two-stage reading strategy is to make @value{GDBN}
+start up faster. For the most part, it is invisible except for
+occasional pauses while the symbol table details for a particular source
+file are being read. (The @code{set verbose} command can turn these
+pauses into messages if desired. @xref{Messages/Warnings, ,Optional
+warnings and messages}.)
+
+We have not implemented the two-stage strategy for COFF yet. When the
+symbol table is stored in COFF format, @code{symbol-file} reads the
+symbol table data in full right away. Note that ``stabs-in-COFF''
+still does the two-stage strategy, since the debug info is actually
+in stabs format.
+
+@kindex readnow
+@cindex reading symbols immediately
+@cindex symbols, reading immediately
+@kindex mapped
+@cindex memory-mapped symbol file
+@cindex saving symbol table
+@item symbol-file @var{filename} @r{[} -readnow @r{]} @r{[} -mapped @r{]}
+@itemx file @var{filename} @r{[} -readnow @r{]} @r{[} -mapped @r{]}
+You can override the @value{GDBN} two-stage strategy for reading symbol
+tables by using the @samp{-readnow} option with any of the commands that
+load symbol table information, if you want to be sure @value{GDBN} has the
+entire symbol table available.
+
+If memory-mapped files are available on your system through the
+@code{mmap} system call, you can use another option, @samp{-mapped}, to
+cause @value{GDBN} to write the symbols for your program into a reusable
+file. Future @value{GDBN} debugging sessions map in symbol information
+from this auxiliary symbol file (if the program has not changed), rather
+than spending time reading the symbol table from the executable
+program. Using the @samp{-mapped} option has the same effect as
+starting @value{GDBN} with the @samp{-mapped} command-line option.
+
+You can use both options together, to make sure the auxiliary symbol
+file has all the symbol information for your program.
+
+The auxiliary symbol file for a program called @var{myprog} is called
+@samp{@var{myprog}.syms}. Once this file exists (so long as it is newer
+than the corresponding executable), @value{GDBN} always attempts to use
+it when you debug @var{myprog}; no special options or commands are
+needed.
+
+The @file{.syms} file is specific to the host machine where you run
+@value{GDBN}. It holds an exact image of the internal @value{GDBN}
+symbol table. It cannot be shared across multiple host platforms.
+
+@c FIXME: for now no mention of directories, since this seems to be in
+@c flux. 13mar1992 status is that in theory GDB would look either in
+@c current dir or in same dir as myprog; but issues like competing
+@c GDB's, or clutter in system dirs, mean that in practice right now
+@c only current dir is used. FFish says maybe a special GDB hierarchy
+@c (eg rooted in val of env var GDBSYMS) could exist for mappable symbol
+@c files.
+
+@kindex core
+@kindex core-file
+@item core-file @r{[} @var{filename} @r{]}
+Specify the whereabouts of a core dump file to be used as the ``contents
+of memory''. Traditionally, core files contain only some parts of the
+address space of the process that generated them; @value{GDBN} can access the
+executable file itself for other parts.
+
+@code{core-file} with no argument specifies that no core file is
+to be used.
+
+Note that the core file is ignored when your program is actually running
+under @value{GDBN}. So, if you have been running your program and you
+wish to debug a core file instead, you must kill the subprocess in which
+the program is running. To do this, use the @code{kill} command
+(@pxref{Kill Process, ,Killing the child process}).
+
+@kindex add-symbol-file
+@cindex dynamic linking
+@item add-symbol-file @var{filename} @var{address}
+@itemx add-symbol-file @var{filename} @var{address} @r{[} -readnow @r{]} @r{[} -mapped @r{]}
+@itemx add-symbol-file @var{filename} @r{-s}@var{section} @var{address} @dots{}
+The @code{add-symbol-file} command reads additional symbol table
+information from the file @var{filename}. You would use this command
+when @var{filename} has been dynamically loaded (by some other means)
+into the program that is running. @var{address} should be the memory
+address at which the file has been loaded; @value{GDBN} cannot figure
+this out for itself. You can additionally specify an arbitrary number
+of @samp{@r{-s}@var{section} @var{address}} pairs, to give an explicit
+section name and base address for that section. You can specify any
+@var{address} as an expression.
+
+The symbol table of the file @var{filename} is added to the symbol table
+originally read with the @code{symbol-file} command. You can use the
+@code{add-symbol-file} command any number of times; the new symbol data
+thus read keeps adding to the old. To discard all old symbol data
+instead, use the @code{symbol-file} command without any arguments.
+
+@cindex relocatable object files, reading symbols from
+@cindex object files, relocatable, reading symbols from
+@cindex reading symbols from relocatable object files
+@cindex symbols, reading from relocatable object files
+@cindex @file{.o} files, reading symbols from
+Although @var{filename} is typically a shared library file, an
+executable file, or some other object file which has been fully
+relocated for loading into a process, you can also load symbolic
+information from relocatable @file{.o} files, as long as:
+
+@itemize @bullet
+@item
+the file's symbolic information refers only to linker symbols defined in
+that file, not to symbols defined by other object files,
+@item
+every section the file's symbolic information refers to has actually
+been loaded into the inferior, as it appears in the file, and
+@item
+you can determine the address at which every section was loaded, and
+provide these to the @code{add-symbol-file} command.
+@end itemize
+
+@noindent
+Some embedded operating systems, like Sun Chorus and VxWorks, can load
+relocatable files into an already running program; such systems
+typically make the requirements above easy to meet. However, it's
+important to recognize that many native systems use complex link
+procedures (@code{.linkonce} section factoring and C++ constructor table
+assembly, for example) that make the requirements difficult to meet. In
+general, one cannot assume that using @code{add-symbol-file} to read a
+relocatable object file's symbolic information will have the same effect
+as linking the relocatable object file into the program in the normal
+way.
+
+@code{add-symbol-file} does not repeat if you press @key{RET} after using it.
+
+You can use the @samp{-mapped} and @samp{-readnow} options just as with
+the @code{symbol-file} command, to change how @value{GDBN} manages the symbol
+table information for @var{filename}.
+
+@kindex add-shared-symbol-file
+@item add-shared-symbol-file
+The @code{add-shared-symbol-file} command can be used only under Harris' CXUX
+operating system for the Motorola 88k. @value{GDBN} automatically looks for
+shared libraries, however if @value{GDBN} does not find yours, you can run
+@code{add-shared-symbol-file}. It takes no arguments.
+
+@kindex section
+@item section
+The @code{section} command changes the base address of section SECTION of
+the exec file to ADDR. This can be used if the exec file does not contain
+section addresses, (such as in the a.out format), or when the addresses
+specified in the file itself are wrong. Each section must be changed
+separately. The @code{info files} command, described below, lists all
+the sections and their addresses.
+
+@kindex info files
+@kindex info target
+@item info files
+@itemx info target
+@code{info files} and @code{info target} are synonymous; both print the
+current target (@pxref{Targets, ,Specifying a Debugging Target}),
+including the names of the executable and core dump files currently in
+use by @value{GDBN}, and the files from which symbols were loaded. The
+command @code{help target} lists all possible targets rather than
+current ones.
+
+@kindex maint info sections
+@item maint info sections
+Another command that can give you extra information about program sections
+is @code{maint info sections}. In addition to the section information
+displayed by @code{info files}, this command displays the flags and file
+offset of each section in the executable and core dump files. In addition,
+@code{maint info sections} provides the following command options (which
+may be arbitrarily combined):
+
+@table @code
+@item ALLOBJ
+Display sections for all loaded object files, including shared libraries.
+@item @var{sections}
+Display info only for named @var{sections}.
+@item @var{section-flags}
+Display info only for sections for which @var{section-flags} are true.
+The section flags that @value{GDBN} currently knows about are:
+@table @code
+@item ALLOC
+Section will have space allocated in the process when loaded.
+Set for all sections except those containing debug information.
+@item LOAD
+Section will be loaded from the file into the child process memory.
+Set for pre-initialized code and data, clear for @code{.bss} sections.
+@item RELOC
+Section needs to be relocated before loading.
+@item READONLY
+Section cannot be modified by the child process.
+@item CODE
+Section contains executable code only.
+@item DATA
+Section contains data only (no executable code).
+@item ROM
+Section will reside in ROM.
+@item CONSTRUCTOR
+Section contains data for constructor/destructor lists.
+@item HAS_CONTENTS
+Section is not empty.
+@item NEVER_LOAD
+An instruction to the linker to not output the section.
+@item COFF_SHARED_LIBRARY
+A notification to the linker that the section contains
+COFF shared library information.
+@item IS_COMMON
+Section contains common symbols.
+@end table
+@end table
+@kindex set trust-readonly-sections
+@item set trust-readonly-sections on
+Tell @value{GDBN} that readonly sections in your object file
+really are read-only (i.e.@: that their contents will not change).
+In that case, @value{GDBN} can fetch values from these sections
+out of the object file, rather than from the target program.
+For some targets (notably embedded ones), this can be a significant
+enhancement to debugging performance.
+
+The default is off.
+
+@item set trust-readonly-sections off
+Tell @value{GDBN} not to trust readonly sections. This means that
+the contents of the section might change while the program is running,
+and must therefore be fetched from the target when needed.
+@end table
+
+All file-specifying commands allow both absolute and relative file names
+as arguments. @value{GDBN} always converts the file name to an absolute file
+name and remembers it that way.
+
+@cindex shared libraries
+@value{GDBN} supports HP-UX, SunOS, SVr4, Irix 5, and IBM RS/6000 shared
+libraries.
+
+@value{GDBN} automatically loads symbol definitions from shared libraries
+when you use the @code{run} command, or when you examine a core file.
+(Before you issue the @code{run} command, @value{GDBN} does not understand
+references to a function in a shared library, however---unless you are
+debugging a core file).
+
+On HP-UX, if the program loads a library explicitly, @value{GDBN}
+automatically loads the symbols at the time of the @code{shl_load} call.
+
+@c FIXME: some @value{GDBN} release may permit some refs to undef
+@c FIXME...symbols---eg in a break cmd---assuming they are from a shared
+@c FIXME...lib; check this from time to time when updating manual
+
+There are times, however, when you may wish to not automatically load
+symbol definitions from shared libraries, such as when they are
+particularly large or there are many of them.
+
+To control the automatic loading of shared library symbols, use the
+commands:
+
+@table @code
+@kindex set auto-solib-add
+@item set auto-solib-add @var{mode}
+If @var{mode} is @code{on}, symbols from all shared object libraries
+will be loaded automatically when the inferior begins execution, you
+attach to an independently started inferior, or when the dynamic linker
+informs @value{GDBN} that a new library has been loaded. If @var{mode}
+is @code{off}, symbols must be loaded manually, using the
+@code{sharedlibrary} command. The default value is @code{on}.
+
+@kindex show auto-solib-add
+@item show auto-solib-add
+Display the current autoloading mode.
+@end table
+
+To explicitly load shared library symbols, use the @code{sharedlibrary}
+command:
+
+@table @code
+@kindex info sharedlibrary
+@kindex info share
+@item info share
+@itemx info sharedlibrary
+Print the names of the shared libraries which are currently loaded.
+
+@kindex sharedlibrary
+@kindex share
+@item sharedlibrary @var{regex}
+@itemx share @var{regex}
+Load shared object library symbols for files matching a
+Unix regular expression.
+As with files loaded automatically, it only loads shared libraries
+required by your program for a core file or after typing @code{run}. If
+@var{regex} is omitted all shared libraries required by your program are
+loaded.
+@end table
+
+On some systems, such as HP-UX systems, @value{GDBN} supports
+autoloading shared library symbols until a limiting threshold size is
+reached. This provides the benefit of allowing autoloading to remain on
+by default, but avoids autoloading excessively large shared libraries,
+up to a threshold that is initially set, but which you can modify if you
+wish.
+
+Beyond that threshold, symbols from shared libraries must be explicitly
+loaded. To load these symbols, use the command @code{sharedlibrary
+@var{filename}}. The base address of the shared library is determined
+automatically by @value{GDBN} and need not be specified.
+
+To display or set the threshold, use the commands:
+
+@table @code
+@kindex set auto-solib-limit
+@item set auto-solib-limit @var{threshold}
+Set the autoloading size threshold, in an integral number of megabytes.
+If @var{threshold} is nonzero and shared library autoloading is enabled,
+symbols from all shared object libraries will be loaded until the total
+size of the loaded shared library symbols exceeds this threshold.
+Otherwise, symbols must be loaded manually, using the
+@code{sharedlibrary} command. The default threshold is 100 (i.e.@: 100
+Mb).
+
+@kindex show auto-solib-limit
+@item show auto-solib-limit
+Display the current autoloading size threshold, in megabytes.
+@end table
+
+@node Symbol Errors
+@section Errors reading symbol files
+
+While reading a symbol file, @value{GDBN} occasionally encounters problems,
+such as symbol types it does not recognize, or known bugs in compiler
+output. By default, @value{GDBN} does not notify you of such problems, since
+they are relatively common and primarily of interest to people
+debugging compilers. If you are interested in seeing information
+about ill-constructed symbol tables, you can either ask @value{GDBN} to print
+only one message about each such type of problem, no matter how many
+times the problem occurs; or you can ask @value{GDBN} to print more messages,
+to see how many times the problems occur, with the @code{set
+complaints} command (@pxref{Messages/Warnings, ,Optional warnings and
+messages}).
+
+The messages currently printed, and their meanings, include:
+
+@table @code
+@item inner block not inside outer block in @var{symbol}
+
+The symbol information shows where symbol scopes begin and end
+(such as at the start of a function or a block of statements). This
+error indicates that an inner scope block is not fully contained
+in its outer scope blocks.
+
+@value{GDBN} circumvents the problem by treating the inner block as if it had
+the same scope as the outer block. In the error message, @var{symbol}
+may be shown as ``@code{(don't know)}'' if the outer block is not a
+function.
+
+@item block at @var{address} out of order
+
+The symbol information for symbol scope blocks should occur in
+order of increasing addresses. This error indicates that it does not
+do so.
+
+@value{GDBN} does not circumvent this problem, and has trouble
+locating symbols in the source file whose symbols it is reading. (You
+can often determine what source file is affected by specifying
+@code{set verbose on}. @xref{Messages/Warnings, ,Optional warnings and
+messages}.)
+
+@item bad block start address patched
+
+The symbol information for a symbol scope block has a start address
+smaller than the address of the preceding source line. This is known
+to occur in the SunOS 4.1.1 (and earlier) C compiler.
+
+@value{GDBN} circumvents the problem by treating the symbol scope block as
+starting on the previous source line.
+
+@item bad string table offset in symbol @var{n}
+
+@cindex foo
+Symbol number @var{n} contains a pointer into the string table which is
+larger than the size of the string table.
+
+@value{GDBN} circumvents the problem by considering the symbol to have the
+name @code{foo}, which may cause other problems if many symbols end up
+with this name.
+
+@item unknown symbol type @code{0x@var{nn}}
+
+The symbol information contains new data types that @value{GDBN} does
+not yet know how to read. @code{0x@var{nn}} is the symbol type of the
+uncomprehended information, in hexadecimal.
+
+@value{GDBN} circumvents the error by ignoring this symbol information.
+This usually allows you to debug your program, though certain symbols
+are not accessible. If you encounter such a problem and feel like
+debugging it, you can debug @code{@value{GDBP}} with itself, breakpoint
+on @code{complain}, then go up to the function @code{read_dbx_symtab}
+and examine @code{*bufp} to see the symbol.
+
+@item stub type has NULL name
+
+@value{GDBN} could not find the full definition for a struct or class.
+
+@item const/volatile indicator missing (ok if using g++ v1.x), got@dots{}
+The symbol information for a C@t{++} member function is missing some
+information that recent versions of the compiler should have output for
+it.
+
+@item info mismatch between compiler and debugger
+
+@value{GDBN} could not parse a type specification output by the compiler.
+
+@end table
+
+@node Targets
+@chapter Specifying a Debugging Target
+
+@cindex debugging target
+@kindex target
+
+A @dfn{target} is the execution environment occupied by your program.
+
+Often, @value{GDBN} runs in the same host environment as your program;
+in that case, the debugging target is specified as a side effect when
+you use the @code{file} or @code{core} commands. When you need more
+flexibility---for example, running @value{GDBN} on a physically separate
+host, or controlling a standalone system over a serial port or a
+realtime system over a TCP/IP connection---you can use the @code{target}
+command to specify one of the target types configured for @value{GDBN}
+(@pxref{Target Commands, ,Commands for managing targets}).
+
+@menu
+* Active Targets:: Active targets
+* Target Commands:: Commands for managing targets
+* Byte Order:: Choosing target byte order
+* Remote:: Remote debugging
+* KOD:: Kernel Object Display
+
+@end menu
+
+@node Active Targets
+@section Active targets
+
+@cindex stacking targets
+@cindex active targets
+@cindex multiple targets
+
+There are three classes of targets: processes, core files, and
+executable files. @value{GDBN} can work concurrently on up to three
+active targets, one in each class. This allows you to (for example)
+start a process and inspect its activity without abandoning your work on
+a core file.
+
+For example, if you execute @samp{gdb a.out}, then the executable file
+@code{a.out} is the only active target. If you designate a core file as
+well---presumably from a prior run that crashed and coredumped---then
+@value{GDBN} has two active targets and uses them in tandem, looking
+first in the corefile target, then in the executable file, to satisfy
+requests for memory addresses. (Typically, these two classes of target
+are complementary, since core files contain only a program's
+read-write memory---variables and so on---plus machine status, while
+executable files contain only the program text and initialized data.)
+
+When you type @code{run}, your executable file becomes an active process
+target as well. When a process target is active, all @value{GDBN}
+commands requesting memory addresses refer to that target; addresses in
+an active core file or executable file target are obscured while the
+process target is active.
+
+Use the @code{core-file} and @code{exec-file} commands to select a new
+core file or executable target (@pxref{Files, ,Commands to specify
+files}). To specify as a target a process that is already running, use
+the @code{attach} command (@pxref{Attach, ,Debugging an already-running
+process}).
+
+@node Target Commands
+@section Commands for managing targets
+
+@table @code
+@item target @var{type} @var{parameters}
+Connects the @value{GDBN} host environment to a target machine or
+process. A target is typically a protocol for talking to debugging
+facilities. You use the argument @var{type} to specify the type or
+protocol of the target machine.
+
+Further @var{parameters} are interpreted by the target protocol, but
+typically include things like device names or host names to connect
+with, process numbers, and baud rates.
+
+The @code{target} command does not repeat if you press @key{RET} again
+after executing the command.
+
+@kindex help target
+@item help target
+Displays the names of all targets available. To display targets
+currently selected, use either @code{info target} or @code{info files}
+(@pxref{Files, ,Commands to specify files}).
+
+@item help target @var{name}
+Describe a particular target, including any parameters necessary to
+select it.
+
+@kindex set gnutarget
+@item set gnutarget @var{args}
+@value{GDBN} uses its own library BFD to read your files. @value{GDBN}
+knows whether it is reading an @dfn{executable},
+a @dfn{core}, or a @dfn{.o} file; however, you can specify the file format
+with the @code{set gnutarget} command. Unlike most @code{target} commands,
+with @code{gnutarget} the @code{target} refers to a program, not a machine.
+
+@quotation
+@emph{Warning:} To specify a file format with @code{set gnutarget},
+you must know the actual BFD name.
+@end quotation
+
+@noindent
+@xref{Files, , Commands to specify files}.
+
+@kindex show gnutarget
+@item show gnutarget
+Use the @code{show gnutarget} command to display what file format
+@code{gnutarget} is set to read. If you have not set @code{gnutarget},
+@value{GDBN} will determine the file format for each file automatically,
+and @code{show gnutarget} displays @samp{The current BDF target is "auto"}.
+@end table
+
+Here are some common targets (available, or not, depending on the GDB
+configuration):
+
+@table @code
+@kindex target exec
+@item target exec @var{program}
+An executable file. @samp{target exec @var{program}} is the same as
+@samp{exec-file @var{program}}.
+
+@kindex target core
+@item target core @var{filename}
+A core dump file. @samp{target core @var{filename}} is the same as
+@samp{core-file @var{filename}}.
+
+@kindex target remote
+@item target remote @var{dev}
+Remote serial target in GDB-specific protocol. The argument @var{dev}
+specifies what serial device to use for the connection (e.g.
+@file{/dev/ttya}). @xref{Remote, ,Remote debugging}. @code{target remote}
+supports the @code{load} command. This is only useful if you have
+some other way of getting the stub to the target system, and you can put
+it somewhere in memory where it won't get clobbered by the download.
+
+@kindex target sim
+@item target sim
+Builtin CPU simulator. @value{GDBN} includes simulators for most architectures.
+In general,
+@smallexample
+ target sim
+ load
+ run
+@end smallexample
+@noindent
+works; however, you cannot assume that a specific memory map, device
+drivers, or even basic I/O is available, although some simulators do
+provide these. For info about any processor-specific simulator details,
+see the appropriate section in @ref{Embedded Processors, ,Embedded
+Processors}.
+
+@end table
+
+Some configurations may include these targets as well:
+
+@table @code
+
+@kindex target nrom
+@item target nrom @var{dev}
+NetROM ROM emulator. This target only supports downloading.
+
+@end table
+
+Different targets are available on different configurations of @value{GDBN};
+your configuration may have more or fewer targets.
+
+Many remote targets require you to download the executable's code
+once you've successfully established a connection.
+
+@table @code
+
+@kindex load @var{filename}
+@item load @var{filename}
+Depending on what remote debugging facilities are configured into
+@value{GDBN}, the @code{load} command may be available. Where it exists, it
+is meant to make @var{filename} (an executable) available for debugging
+on the remote system---by downloading, or dynamic linking, for example.
+@code{load} also records the @var{filename} symbol table in @value{GDBN}, like
+the @code{add-symbol-file} command.
+
+If your @value{GDBN} does not have a @code{load} command, attempting to
+execute it gets the error message ``@code{You can't do that when your
+target is @dots{}}''
+
+The file is loaded at whatever address is specified in the executable.
+For some object file formats, you can specify the load address when you
+link the program; for other formats, like a.out, the object file format
+specifies a fixed address.
+@c FIXME! This would be a good place for an xref to the GNU linker doc.
+
+@code{load} does not repeat if you press @key{RET} again after using it.
+@end table
+
+@node Byte Order
+@section Choosing target byte order
+
+@cindex choosing target byte order
+@cindex target byte order
+
+Some types of processors, such as the MIPS, PowerPC, and Hitachi SH,
+offer the ability to run either big-endian or little-endian byte
+orders. Usually the executable or symbol will include a bit to
+designate the endian-ness, and you will not need to worry about
+which to use. However, you may still find it useful to adjust
+@value{GDBN}'s idea of processor endian-ness manually.
+
+@table @code
+@kindex set endian big
+@item set endian big
+Instruct @value{GDBN} to assume the target is big-endian.
+
+@kindex set endian little
+@item set endian little
+Instruct @value{GDBN} to assume the target is little-endian.
+
+@kindex set endian auto
+@item set endian auto
+Instruct @value{GDBN} to use the byte order associated with the
+executable.
+
+@item show endian
+Display @value{GDBN}'s current idea of the target byte order.
+
+@end table
+
+Note that these commands merely adjust interpretation of symbolic
+data on the host, and that they have absolutely no effect on the
+target system.
+
+@node Remote
+@section Remote debugging
+@cindex remote debugging
+
+If you are trying to debug a program running on a machine that cannot run
+@value{GDBN} in the usual way, it is often useful to use remote debugging.
+For example, you might use remote debugging on an operating system kernel,
+or on a small system which does not have a general purpose operating system
+powerful enough to run a full-featured debugger.
+
+Some configurations of @value{GDBN} have special serial or TCP/IP interfaces
+to make this work with particular debugging targets. In addition,
+@value{GDBN} comes with a generic serial protocol (specific to @value{GDBN},
+but not specific to any particular target system) which you can use if you
+write the remote stubs---the code that runs on the remote system to
+communicate with @value{GDBN}.
+
+Other remote targets may be available in your
+configuration of @value{GDBN}; use @code{help target} to list them.
+
+@node KOD
+@section Kernel Object Display
+
+@cindex kernel object display
+@cindex kernel object
+@cindex KOD
+
+Some targets support kernel object display. Using this facility,
+@value{GDBN} communicates specially with the underlying operating system
+and can display information about operating system-level objects such as
+mutexes and other synchronization objects. Exactly which objects can be
+displayed is determined on a per-OS basis.
+
+Use the @code{set os} command to set the operating system. This tells
+@value{GDBN} which kernel object display module to initialize:
+
+@smallexample
+(@value{GDBP}) set os cisco
+@end smallexample
+
+If @code{set os} succeeds, @value{GDBN} will display some information
+about the operating system, and will create a new @code{info} command
+which can be used to query the target. The @code{info} command is named
+after the operating system:
+
+@smallexample
+(@value{GDBP}) info cisco
+List of Cisco Kernel Objects
+Object Description
+any Any and all objects
+@end smallexample
+
+Further subcommands can be used to query about particular objects known
+by the kernel.
+
+There is currently no way to determine whether a given operating system
+is supported other than to try it.
+
+
+@node Remote Debugging
+@chapter Debugging remote programs
+
+@menu
+* Server:: Using the gdbserver program
+* NetWare:: Using the gdbserve.nlm program
+* remote stub:: Implementing a remote stub
+@end menu
+
+@node Server
+@section Using the @code{gdbserver} program
+
+@kindex gdbserver
+@cindex remote connection without stubs
+@code{gdbserver} is a control program for Unix-like systems, which
+allows you to connect your program with a remote @value{GDBN} via
+@code{target remote}---but without linking in the usual debugging stub.
+
+@code{gdbserver} is not a complete replacement for the debugging stubs,
+because it requires essentially the same operating-system facilities
+that @value{GDBN} itself does. In fact, a system that can run
+@code{gdbserver} to connect to a remote @value{GDBN} could also run
+@value{GDBN} locally! @code{gdbserver} is sometimes useful nevertheless,
+because it is a much smaller program than @value{GDBN} itself. It is
+also easier to port than all of @value{GDBN}, so you may be able to get
+started more quickly on a new system by using @code{gdbserver}.
+Finally, if you develop code for real-time systems, you may find that
+the tradeoffs involved in real-time operation make it more convenient to
+do as much development work as possible on another system, for example
+by cross-compiling. You can use @code{gdbserver} to make a similar
+choice for debugging.
+
+@value{GDBN} and @code{gdbserver} communicate via either a serial line
+or a TCP connection, using the standard @value{GDBN} remote serial
+protocol.
+
+@table @emph
+@item On the target machine,
+you need to have a copy of the program you want to debug.
+@code{gdbserver} does not need your program's symbol table, so you can
+strip the program if necessary to save space. @value{GDBN} on the host
+system does all the symbol handling.
+
+To use the server, you must tell it how to communicate with @value{GDBN};
+the name of your program; and the arguments for your program. The usual
+syntax is:
+
+@smallexample
+target> gdbserver @var{comm} @var{program} [ @var{args} @dots{} ]
+@end smallexample
+
+@var{comm} is either a device name (to use a serial line) or a TCP
+hostname and portnumber. For example, to debug Emacs with the argument
+@samp{foo.txt} and communicate with @value{GDBN} over the serial port
+@file{/dev/com1}:
+
+@smallexample
+target> gdbserver /dev/com1 emacs foo.txt
+@end smallexample
+
+@code{gdbserver} waits passively for the host @value{GDBN} to communicate
+with it.
+
+To use a TCP connection instead of a serial line:
+
+@smallexample
+target> gdbserver host:2345 emacs foo.txt
+@end smallexample
+
+The only difference from the previous example is the first argument,
+specifying that you are communicating with the host @value{GDBN} via
+TCP. The @samp{host:2345} argument means that @code{gdbserver} is to
+expect a TCP connection from machine @samp{host} to local TCP port 2345.
+(Currently, the @samp{host} part is ignored.) You can choose any number
+you want for the port number as long as it does not conflict with any
+TCP ports already in use on the target system (for example, @code{23} is
+reserved for @code{telnet}).@footnote{If you choose a port number that
+conflicts with another service, @code{gdbserver} prints an error message
+and exits.} You must use the same port number with the host @value{GDBN}
+@code{target remote} command.
+
+On some targets, @code{gdbserver} can also attach to running programs.
+This is accomplished via the @code{--attach} argument. The syntax is:
+
+@smallexample
+target> gdbserver @var{comm} --attach @var{pid}
+@end smallexample
+
+@var{pid} is the process ID of a currently running process. It isn't necessary
+to point @code{gdbserver} at a binary for the running process.
+
+@item On the @value{GDBN} host machine,
+you need an unstripped copy of your program, since @value{GDBN} needs
+symbols and debugging information. Start up @value{GDBN} as usual,
+using the name of the local copy of your program as the first argument.
+(You may also need the @w{@samp{--baud}} option if the serial line is
+running at anything other than 9600@dmn{bps}.) After that, use @code{target
+remote} to establish communications with @code{gdbserver}. Its argument
+is either a device name (usually a serial device, like
+@file{/dev/ttyb}), or a TCP port descriptor in the form
+@code{@var{host}:@var{PORT}}. For example:
+
+@smallexample
+(@value{GDBP}) target remote /dev/ttyb
+@end smallexample
+
+@noindent
+communicates with the server via serial line @file{/dev/ttyb}, and
+
+@smallexample
+(@value{GDBP}) target remote the-target:2345
+@end smallexample
+
+@noindent
+communicates via a TCP connection to port 2345 on host @w{@file{the-target}}.
+For TCP connections, you must start up @code{gdbserver} prior to using
+the @code{target remote} command. Otherwise you may get an error whose
+text depends on the host system, but which usually looks something like
+@samp{Connection refused}.
+@end table
+
+@node NetWare
+@section Using the @code{gdbserve.nlm} program
+
+@kindex gdbserve.nlm
+@code{gdbserve.nlm} is a control program for NetWare systems, which
+allows you to connect your program with a remote @value{GDBN} via
+@code{target remote}.
+
+@value{GDBN} and @code{gdbserve.nlm} communicate via a serial line,
+using the standard @value{GDBN} remote serial protocol.
+
+@table @emph
+@item On the target machine,
+you need to have a copy of the program you want to debug.
+@code{gdbserve.nlm} does not need your program's symbol table, so you
+can strip the program if necessary to save space. @value{GDBN} on the
+host system does all the symbol handling.
+
+To use the server, you must tell it how to communicate with
+@value{GDBN}; the name of your program; and the arguments for your
+program. The syntax is:
+
+@smallexample
+load gdbserve [ BOARD=@var{board} ] [ PORT=@var{port} ]
+ [ BAUD=@var{baud} ] @var{program} [ @var{args} @dots{} ]
+@end smallexample
+
+@var{board} and @var{port} specify the serial line; @var{baud} specifies
+the baud rate used by the connection. @var{port} and @var{node} default
+to 0, @var{baud} defaults to 9600@dmn{bps}.
+
+For example, to debug Emacs with the argument @samp{foo.txt}and
+communicate with @value{GDBN} over serial port number 2 or board 1
+using a 19200@dmn{bps} connection:
+
+@smallexample
+load gdbserve BOARD=1 PORT=2 BAUD=19200 emacs foo.txt
+@end smallexample
+
+@item On the @value{GDBN} host machine,
+you need an unstripped copy of your program, since @value{GDBN} needs
+symbols and debugging information. Start up @value{GDBN} as usual,
+using the name of the local copy of your program as the first argument.
+(You may also need the @w{@samp{--baud}} option if the serial line is
+running at anything other than 9600@dmn{bps}. After that, use @code{target
+remote} to establish communications with @code{gdbserve.nlm}. Its
+argument is a device name (usually a serial device, like
+@file{/dev/ttyb}). For example:
+
+@smallexample
+(@value{GDBP}) target remote /dev/ttyb
+@end smallexample
+
+@noindent
+communications with the server via serial line @file{/dev/ttyb}.
+@end table
+
+@node remote stub
+@section Implementing a remote stub
+
+@cindex debugging stub, example
+@cindex remote stub, example
+@cindex stub example, remote debugging
+The stub files provided with @value{GDBN} implement the target side of the
+communication protocol, and the @value{GDBN} side is implemented in the
+@value{GDBN} source file @file{remote.c}. Normally, you can simply allow
+these subroutines to communicate, and ignore the details. (If you're
+implementing your own stub file, you can still ignore the details: start
+with one of the existing stub files. @file{sparc-stub.c} is the best
+organized, and therefore the easiest to read.)
+
+@cindex remote serial debugging, overview
+To debug a program running on another machine (the debugging
+@dfn{target} machine), you must first arrange for all the usual
+prerequisites for the program to run by itself. For example, for a C
+program, you need:
+
+@enumerate
+@item
+A startup routine to set up the C runtime environment; these usually
+have a name like @file{crt0}. The startup routine may be supplied by
+your hardware supplier, or you may have to write your own.
+
+@item
+A C subroutine library to support your program's
+subroutine calls, notably managing input and output.
+
+@item
+A way of getting your program to the other machine---for example, a
+download program. These are often supplied by the hardware
+manufacturer, but you may have to write your own from hardware
+documentation.
+@end enumerate
+
+The next step is to arrange for your program to use a serial port to
+communicate with the machine where @value{GDBN} is running (the @dfn{host}
+machine). In general terms, the scheme looks like this:
+
+@table @emph
+@item On the host,
+@value{GDBN} already understands how to use this protocol; when everything
+else is set up, you can simply use the @samp{target remote} command
+(@pxref{Targets,,Specifying a Debugging Target}).
+
+@item On the target,
+you must link with your program a few special-purpose subroutines that
+implement the @value{GDBN} remote serial protocol. The file containing these
+subroutines is called a @dfn{debugging stub}.
+
+On certain remote targets, you can use an auxiliary program
+@code{gdbserver} instead of linking a stub into your program.
+@xref{Server,,Using the @code{gdbserver} program}, for details.
+@end table
+
+The debugging stub is specific to the architecture of the remote
+machine; for example, use @file{sparc-stub.c} to debug programs on
+@sc{sparc} boards.
+
+@cindex remote serial stub list
+These working remote stubs are distributed with @value{GDBN}:
+
+@table @code
+
+@item i386-stub.c
+@cindex @file{i386-stub.c}
+@cindex Intel
+@cindex i386
+For Intel 386 and compatible architectures.
+
+@item m68k-stub.c
+@cindex @file{m68k-stub.c}
+@cindex Motorola 680x0
+@cindex m680x0
+For Motorola 680x0 architectures.
+
+@item sh-stub.c
+@cindex @file{sh-stub.c}
+@cindex Hitachi
+@cindex SH
+For Hitachi SH architectures.
+
+@item sparc-stub.c
+@cindex @file{sparc-stub.c}
+@cindex Sparc
+For @sc{sparc} architectures.
+
+@item sparcl-stub.c
+@cindex @file{sparcl-stub.c}
+@cindex Fujitsu
+@cindex SparcLite
+For Fujitsu @sc{sparclite} architectures.
+
+@end table
+
+The @file{README} file in the @value{GDBN} distribution may list other
+recently added stubs.
+
+@menu
+* Stub Contents:: What the stub can do for you
+* Bootstrapping:: What you must do for the stub
+* Debug Session:: Putting it all together
+@end menu
+
+@node Stub Contents
+@subsection What the stub can do for you
+
+@cindex remote serial stub
+The debugging stub for your architecture supplies these three
+subroutines:
+
+@table @code
+@item set_debug_traps
+@kindex set_debug_traps
+@cindex remote serial stub, initialization
+This routine arranges for @code{handle_exception} to run when your
+program stops. You must call this subroutine explicitly near the
+beginning of your program.
+
+@item handle_exception
+@kindex handle_exception
+@cindex remote serial stub, main routine
+This is the central workhorse, but your program never calls it
+explicitly---the setup code arranges for @code{handle_exception} to
+run when a trap is triggered.
+
+@code{handle_exception} takes control when your program stops during
+execution (for example, on a breakpoint), and mediates communications
+with @value{GDBN} on the host machine. This is where the communications
+protocol is implemented; @code{handle_exception} acts as the @value{GDBN}
+representative on the target machine. It begins by sending summary
+information on the state of your program, then continues to execute,
+retrieving and transmitting any information @value{GDBN} needs, until you
+execute a @value{GDBN} command that makes your program resume; at that point,
+@code{handle_exception} returns control to your own code on the target
+machine.
+
+@item breakpoint
+@cindex @code{breakpoint} subroutine, remote
+Use this auxiliary subroutine to make your program contain a
+breakpoint. Depending on the particular situation, this may be the only
+way for @value{GDBN} to get control. For instance, if your target
+machine has some sort of interrupt button, you won't need to call this;
+pressing the interrupt button transfers control to
+@code{handle_exception}---in effect, to @value{GDBN}. On some machines,
+simply receiving characters on the serial port may also trigger a trap;
+again, in that situation, you don't need to call @code{breakpoint} from
+your own program---simply running @samp{target remote} from the host
+@value{GDBN} session gets control.
+
+Call @code{breakpoint} if none of these is true, or if you simply want
+to make certain your program stops at a predetermined point for the
+start of your debugging session.
+@end table
+
+@node Bootstrapping
+@subsection What you must do for the stub
+
+@cindex remote stub, support routines
+The debugging stubs that come with @value{GDBN} are set up for a particular
+chip architecture, but they have no information about the rest of your
+debugging target machine.
+
+First of all you need to tell the stub how to communicate with the
+serial port.
+
+@table @code
+@item int getDebugChar()
+@kindex getDebugChar
+Write this subroutine to read a single character from the serial port.
+It may be identical to @code{getchar} for your target system; a
+different name is used to allow you to distinguish the two if you wish.
+
+@item void putDebugChar(int)
+@kindex putDebugChar
+Write this subroutine to write a single character to the serial port.
+It may be identical to @code{putchar} for your target system; a
+different name is used to allow you to distinguish the two if you wish.
+@end table
+
+@cindex control C, and remote debugging
+@cindex interrupting remote targets
+If you want @value{GDBN} to be able to stop your program while it is
+running, you need to use an interrupt-driven serial driver, and arrange
+for it to stop when it receives a @code{^C} (@samp{\003}, the control-C
+character). That is the character which @value{GDBN} uses to tell the
+remote system to stop.
+
+Getting the debugging target to return the proper status to @value{GDBN}
+probably requires changes to the standard stub; one quick and dirty way
+is to just execute a breakpoint instruction (the ``dirty'' part is that
+@value{GDBN} reports a @code{SIGTRAP} instead of a @code{SIGINT}).
+
+Other routines you need to supply are:
+
+@table @code
+@item void exceptionHandler (int @var{exception_number}, void *@var{exception_address})
+@kindex exceptionHandler
+Write this function to install @var{exception_address} in the exception
+handling tables. You need to do this because the stub does not have any
+way of knowing what the exception handling tables on your target system
+are like (for example, the processor's table might be in @sc{rom},
+containing entries which point to a table in @sc{ram}).
+@var{exception_number} is the exception number which should be changed;
+its meaning is architecture-dependent (for example, different numbers
+might represent divide by zero, misaligned access, etc). When this
+exception occurs, control should be transferred directly to
+@var{exception_address}, and the processor state (stack, registers,
+and so on) should be just as it is when a processor exception occurs. So if
+you want to use a jump instruction to reach @var{exception_address}, it
+should be a simple jump, not a jump to subroutine.
+
+For the 386, @var{exception_address} should be installed as an interrupt
+gate so that interrupts are masked while the handler runs. The gate
+should be at privilege level 0 (the most privileged level). The
+@sc{sparc} and 68k stubs are able to mask interrupts themselves without
+help from @code{exceptionHandler}.
+
+@item void flush_i_cache()
+@kindex flush_i_cache
+On @sc{sparc} and @sc{sparclite} only, write this subroutine to flush the
+instruction cache, if any, on your target machine. If there is no
+instruction cache, this subroutine may be a no-op.
+
+On target machines that have instruction caches, @value{GDBN} requires this
+function to make certain that the state of your program is stable.
+@end table
+
+@noindent
+You must also make sure this library routine is available:
+
+@table @code
+@item void *memset(void *, int, int)
+@kindex memset
+This is the standard library function @code{memset} that sets an area of
+memory to a known value. If you have one of the free versions of
+@code{libc.a}, @code{memset} can be found there; otherwise, you must
+either obtain it from your hardware manufacturer, or write your own.
+@end table
+
+If you do not use the GNU C compiler, you may need other standard
+library subroutines as well; this varies from one stub to another,
+but in general the stubs are likely to use any of the common library
+subroutines which @code{@value{GCC}} generates as inline code.
+
+
+@node Debug Session
+@subsection Putting it all together
+
+@cindex remote serial debugging summary
+In summary, when your program is ready to debug, you must follow these
+steps.
+
+@enumerate
+@item
+Make sure you have defined the supporting low-level routines
+(@pxref{Bootstrapping,,What you must do for the stub}):
+@display
+@code{getDebugChar}, @code{putDebugChar},
+@code{flush_i_cache}, @code{memset}, @code{exceptionHandler}.
+@end display
+
+@item
+Insert these lines near the top of your program:
+
+@smallexample
+set_debug_traps();
+breakpoint();
+@end smallexample
+
+@item
+For the 680x0 stub only, you need to provide a variable called
+@code{exceptionHook}. Normally you just use:
+
+@smallexample
+void (*exceptionHook)() = 0;
+@end smallexample
+
+@noindent
+but if before calling @code{set_debug_traps}, you set it to point to a
+function in your program, that function is called when
+@code{@value{GDBN}} continues after stopping on a trap (for example, bus
+error). The function indicated by @code{exceptionHook} is called with
+one parameter: an @code{int} which is the exception number.
+
+@item
+Compile and link together: your program, the @value{GDBN} debugging stub for
+your target architecture, and the supporting subroutines.
+
+@item
+Make sure you have a serial connection between your target machine and
+the @value{GDBN} host, and identify the serial port on the host.
+
+@item
+@c The "remote" target now provides a `load' command, so we should
+@c document that. FIXME.
+Download your program to your target machine (or get it there by
+whatever means the manufacturer provides), and start it.
+
+@item
+To start remote debugging, run @value{GDBN} on the host machine, and specify
+as an executable file the program that is running in the remote machine.
+This tells @value{GDBN} how to find your program's symbols and the contents
+of its pure text.
+
+@item
+@cindex serial line, @code{target remote}
+Establish communication using the @code{target remote} command.
+Its argument specifies how to communicate with the target
+machine---either via a devicename attached to a direct serial line, or a
+TCP or UDP port (usually to a terminal server which in turn has a serial line
+to the target). For example, to use a serial line connected to the
+device named @file{/dev/ttyb}:
+
+@smallexample
+target remote /dev/ttyb
+@end smallexample
+
+@cindex TCP port, @code{target remote}
+To use a TCP connection, use an argument of the form
+@code{@var{host}:@var{port}} or @code{tcp:@var{host}:@var{port}}.
+For example, to connect to port 2828 on a
+terminal server named @code{manyfarms}:
+
+@smallexample
+target remote manyfarms:2828
+@end smallexample
+
+If your remote target is actually running on the same machine as
+your debugger session (e.g.@: a simulator of your target running on
+the same host), you can omit the hostname. For example, to connect
+to port 1234 on your local machine:
+
+@smallexample
+target remote :1234
+@end smallexample
+@noindent
+
+Note that the colon is still required here.
+
+@cindex UDP port, @code{target remote}
+To use a UDP connection, use an argument of the form
+@code{udp:@var{host}:@var{port}}. For example, to connect to UDP port 2828
+on a terminal server named @code{manyfarms}:
+
+@smallexample
+target remote udp:manyfarms:2828
+@end smallexample
+
+When using a UDP connection for remote debugging, you should keep in mind
+that the `U' stands for ``Unreliable''. UDP can silently drop packets on
+busy or unreliable networks, which will cause havoc with your debugging
+session.
+
+@end enumerate
+
+Now you can use all the usual commands to examine and change data and to
+step and continue the remote program.
+
+To resume the remote program and stop debugging it, use the @code{detach}
+command.
+
+@cindex interrupting remote programs
+@cindex remote programs, interrupting
+Whenever @value{GDBN} is waiting for the remote program, if you type the
+interrupt character (often @key{C-C}), @value{GDBN} attempts to stop the
+program. This may or may not succeed, depending in part on the hardware
+and the serial drivers the remote system uses. If you type the
+interrupt character once again, @value{GDBN} displays this prompt:
+
+@smallexample
+Interrupted while waiting for the program.
+Give up (and stop debugging it)? (y or n)
+@end smallexample
+
+If you type @kbd{y}, @value{GDBN} abandons the remote debugging session.
+(If you decide you want to try again later, you can use @samp{target
+remote} again to connect once more.) If you type @kbd{n}, @value{GDBN}
+goes back to waiting.
+
+
+@node Configurations
+@chapter Configuration-Specific Information
+
+While nearly all @value{GDBN} commands are available for all native and
+cross versions of the debugger, there are some exceptions. This chapter
+describes things that are only available in certain configurations.
+
+There are three major categories of configurations: native
+configurations, where the host and target are the same, embedded
+operating system configurations, which are usually the same for several
+different processor architectures, and bare embedded processors, which
+are quite different from each other.
+
+@menu
+* Native::
+* Embedded OS::
+* Embedded Processors::
+* Architectures::
+@end menu
+
+@node Native
+@section Native
+
+This section describes details specific to particular native
+configurations.
+
+@menu
+* HP-UX:: HP-UX
+* SVR4 Process Information:: SVR4 process information
+* DJGPP Native:: Features specific to the DJGPP port
+* Cygwin Native:: Features specific to the Cygwin port
+@end menu
+
+@node HP-UX
+@subsection HP-UX
+
+On HP-UX systems, if you refer to a function or variable name that
+begins with a dollar sign, @value{GDBN} searches for a user or system
+name first, before it searches for a convenience variable.
+
+@node SVR4 Process Information
+@subsection SVR4 process information
+
+@kindex /proc
+@cindex process image
+
+Many versions of SVR4 provide a facility called @samp{/proc} that can be
+used to examine the image of a running process using file-system
+subroutines. If @value{GDBN} is configured for an operating system with
+this facility, the command @code{info proc} is available to report on
+several kinds of information about the process running your program.
+@code{info proc} works only on SVR4 systems that include the
+@code{procfs} code. This includes OSF/1 (Digital Unix), Solaris, Irix,
+and Unixware, but not HP-UX or Linux, for example.
+
+@table @code
+@kindex info proc
+@item info proc
+Summarize available information about the process.
+
+@kindex info proc mappings
+@item info proc mappings
+Report on the address ranges accessible in the program, with information
+on whether your program may read, write, or execute each range.
+@ignore
+@comment These sub-options of 'info proc' were not included when
+@comment procfs.c was re-written. Keep their descriptions around
+@comment against the day when someone finds the time to put them back in.
+@kindex info proc times
+@item info proc times
+Starting time, user CPU time, and system CPU time for your program and
+its children.
+
+@kindex info proc id
+@item info proc id
+Report on the process IDs related to your program: its own process ID,
+the ID of its parent, the process group ID, and the session ID.
+
+@kindex info proc status
+@item info proc status
+General information on the state of the process. If the process is
+stopped, this report includes the reason for stopping, and any signal
+received.
+
+@item info proc all
+Show all the above information about the process.
+@end ignore
+@end table
+
+@node DJGPP Native
+@subsection Features for Debugging @sc{djgpp} Programs
+@cindex @sc{djgpp} debugging
+@cindex native @sc{djgpp} debugging
+@cindex MS-DOS-specific commands
+
+@sc{djgpp} is the port of @sc{gnu} development tools to MS-DOS and
+MS-Windows. @sc{djgpp} programs are 32-bit protected-mode programs
+that use the @dfn{DPMI} (DOS Protected-Mode Interface) API to run on
+top of real-mode DOS systems and their emulations.
+
+@value{GDBN} supports native debugging of @sc{djgpp} programs, and
+defines a few commands specific to the @sc{djgpp} port. This
+subsection describes those commands.
+
+@table @code
+@kindex info dos
+@item info dos
+This is a prefix of @sc{djgpp}-specific commands which print
+information about the target system and important OS structures.
+
+@kindex sysinfo
+@cindex MS-DOS system info
+@cindex free memory information (MS-DOS)
+@item info dos sysinfo
+This command displays assorted information about the underlying
+platform: the CPU type and features, the OS version and flavor, the
+DPMI version, and the available conventional and DPMI memory.
+
+@cindex GDT
+@cindex LDT
+@cindex IDT
+@cindex segment descriptor tables
+@cindex descriptor tables display
+@item info dos gdt
+@itemx info dos ldt
+@itemx info dos idt
+These 3 commands display entries from, respectively, Global, Local,
+and Interrupt Descriptor Tables (GDT, LDT, and IDT). The descriptor
+tables are data structures which store a descriptor for each segment
+that is currently in use. The segment's selector is an index into a
+descriptor table; the table entry for that index holds the
+descriptor's base address and limit, and its attributes and access
+rights.
+
+A typical @sc{djgpp} program uses 3 segments: a code segment, a data
+segment (used for both data and the stack), and a DOS segment (which
+allows access to DOS/BIOS data structures and absolute addresses in
+conventional memory). However, the DPMI host will usually define
+additional segments in order to support the DPMI environment.
+
+@cindex garbled pointers
+These commands allow to display entries from the descriptor tables.
+Without an argument, all entries from the specified table are
+displayed. An argument, which should be an integer expression, means
+display a single entry whose index is given by the argument. For
+example, here's a convenient way to display information about the
+debugged program's data segment:
+
+@smallexample
+@exdent @code{(@value{GDBP}) info dos ldt $ds}
+@exdent @code{0x13f: base=0x11970000 limit=0x0009ffff 32-Bit Data (Read/Write, Exp-up)}
+@end smallexample
+
+@noindent
+This comes in handy when you want to see whether a pointer is outside
+the data segment's limit (i.e.@: @dfn{garbled}).
+
+@cindex page tables display (MS-DOS)
+@item info dos pde
+@itemx info dos pte
+These two commands display entries from, respectively, the Page
+Directory and the Page Tables. Page Directories and Page Tables are
+data structures which control how virtual memory addresses are mapped
+into physical addresses. A Page Table includes an entry for every
+page of memory that is mapped into the program's address space; there
+may be several Page Tables, each one holding up to 4096 entries. A
+Page Directory has up to 4096 entries, one each for every Page Table
+that is currently in use.
+
+Without an argument, @kbd{info dos pde} displays the entire Page
+Directory, and @kbd{info dos pte} displays all the entries in all of
+the Page Tables. An argument, an integer expression, given to the
+@kbd{info dos pde} command means display only that entry from the Page
+Directory table. An argument given to the @kbd{info dos pte} command
+means display entries from a single Page Table, the one pointed to by
+the specified entry in the Page Directory.
+
+@cindex direct memory access (DMA) on MS-DOS
+These commands are useful when your program uses @dfn{DMA} (Direct
+Memory Access), which needs physical addresses to program the DMA
+controller.
+
+These commands are supported only with some DPMI servers.
+
+@cindex physical address from linear address
+@item info dos address-pte @var{addr}
+This command displays the Page Table entry for a specified linear
+address. The argument linear address @var{addr} should already have the
+appropriate segment's base address added to it, because this command
+accepts addresses which may belong to @emph{any} segment. For
+example, here's how to display the Page Table entry for the page where
+the variable @code{i} is stored:
+
+@smallexample
+@exdent @code{(@value{GDBP}) info dos address-pte __djgpp_base_address + (char *)&i}
+@exdent @code{Page Table entry for address 0x11a00d30:}
+@exdent @code{Base=0x02698000 Dirty Acc. Not-Cached Write-Back Usr Read-Write +0xd30}
+@end smallexample
+
+@noindent
+This says that @code{i} is stored at offset @code{0xd30} from the page
+whose physical base address is @code{0x02698000}, and prints all the
+attributes of that page.
+
+Note that you must cast the addresses of variables to a @code{char *},
+since otherwise the value of @code{__djgpp_base_address}, the base
+address of all variables and functions in a @sc{djgpp} program, will
+be added using the rules of C pointer arithmetics: if @code{i} is
+declared an @code{int}, @value{GDBN} will add 4 times the value of
+@code{__djgpp_base_address} to the address of @code{i}.
+
+Here's another example, it displays the Page Table entry for the
+transfer buffer:
+
+@smallexample
+@exdent @code{(@value{GDBP}) info dos address-pte *((unsigned *)&_go32_info_block + 3)}
+@exdent @code{Page Table entry for address 0x29110:}
+@exdent @code{Base=0x00029000 Dirty Acc. Not-Cached Write-Back Usr Read-Write +0x110}
+@end smallexample
+
+@noindent
+(The @code{+ 3} offset is because the transfer buffer's address is the
+3rd member of the @code{_go32_info_block} structure.) The output of
+this command clearly shows that addresses in conventional memory are
+mapped 1:1, i.e.@: the physical and linear addresses are identical.
+
+This command is supported only with some DPMI servers.
+@end table
+
+@node Cygwin Native
+@subsection Features for Debugging MS Windows PE executables
+@cindex MS Windows debugging
+@cindex native Cygwin debugging
+@cindex Cygwin-specific commands
+
+@value{GDBN} supports native debugging of MS Windows programs, and
+defines a few commands specific to the Cygwin port. This
+subsection describes those commands.
+
+@table @code
+@kindex info w32
+@item info w32
+This is a prefix of MS Windows specific commands which print
+information about the target system and important OS structures.
+
+@item info w32 selector
+This command displays information returned by
+the Win32 API @code{GetThreadSelectorEntry} function.
+It takes an optional argument that is evaluated to
+a long value to give the information about this given selector.
+Without argument, this command displays information
+about the the six segment registers.
+
+@kindex info dll
+@item info dll
+This is a Cygwin specific alias of info shared.
+
+@kindex dll-symbols
+@item dll-symbols
+This command loads symbols from a dll similarly to
+add-sym command but without the need to specify a base address.
+
+@kindex set new-console
+@item set new-console @var{mode}
+If @var{mode} is @code{on} the debuggee will
+be started in a new console on next start.
+If @var{mode} is @code{off}i, the debuggee will
+be started in the same console as the debugger.
+
+@kindex show new-console
+@item show new-console
+Displays whether a new console is used
+when the debuggee is started.
+
+@kindex set new-group
+@item set new-group @var{mode}
+This boolean value controls whether the debuggee should
+start a new group or stay in the same group as the debugger.
+This affects the way the Windows OS handles
+Ctrl-C.
+
+@kindex show new-group
+@item show new-group
+Displays current value of new-group boolean.
+
+@kindex set debugevents
+@item set debugevents
+This boolean value adds debug output concerning events seen by the debugger.
+
+@kindex set debugexec
+@item set debugexec
+This boolean value adds debug output concerning execute events
+seen by the debugger.
+
+@kindex set debugexceptions
+@item set debugexceptions
+This boolean value adds debug ouptut concerning exception events
+seen by the debugger.
+
+@kindex set debugmemory
+@item set debugmemory
+This boolean value adds debug ouptut concerning memory events
+seen by the debugger.
+
+@kindex set shell
+@item set shell
+This boolean values specifies whether the debuggee is called
+via a shell or directly (default value is on).
+
+@kindex show shell
+@item show shell
+Displays if the debuggee will be started with a shell.
+
+@end table
+
+@node Embedded OS
+@section Embedded Operating Systems
+
+This section describes configurations involving the debugging of
+embedded operating systems that are available for several different
+architectures.
+
+@menu
+* VxWorks:: Using @value{GDBN} with VxWorks
+@end menu
+
+@value{GDBN} includes the ability to debug programs running on
+various real-time operating systems.
+
+@node VxWorks
+@subsection Using @value{GDBN} with VxWorks
+
+@cindex VxWorks
+
+@table @code
+
+@kindex target vxworks
+@item target vxworks @var{machinename}
+A VxWorks system, attached via TCP/IP. The argument @var{machinename}
+is the target system's machine name or IP address.
+
+@end table
+
+On VxWorks, @code{load} links @var{filename} dynamically on the
+current target system as well as adding its symbols in @value{GDBN}.
+
+@value{GDBN} enables developers to spawn and debug tasks running on networked
+VxWorks targets from a Unix host. Already-running tasks spawned from
+the VxWorks shell can also be debugged. @value{GDBN} uses code that runs on
+both the Unix host and on the VxWorks target. The program
+@code{@value{GDBP}} is installed and executed on the Unix host. (It may be
+installed with the name @code{vxgdb}, to distinguish it from a
+@value{GDBN} for debugging programs on the host itself.)
+
+@table @code
+@item VxWorks-timeout @var{args}
+@kindex vxworks-timeout
+All VxWorks-based targets now support the option @code{vxworks-timeout}.
+This option is set by the user, and @var{args} represents the number of
+seconds @value{GDBN} waits for responses to rpc's. You might use this if
+your VxWorks target is a slow software simulator or is on the far side
+of a thin network line.
+@end table
+
+The following information on connecting to VxWorks was current when
+this manual was produced; newer releases of VxWorks may use revised
+procedures.
+
+@kindex INCLUDE_RDB
+To use @value{GDBN} with VxWorks, you must rebuild your VxWorks kernel
+to include the remote debugging interface routines in the VxWorks
+library @file{rdb.a}. To do this, define @code{INCLUDE_RDB} in the
+VxWorks configuration file @file{configAll.h} and rebuild your VxWorks
+kernel. The resulting kernel contains @file{rdb.a}, and spawns the
+source debugging task @code{tRdbTask} when VxWorks is booted. For more
+information on configuring and remaking VxWorks, see the manufacturer's
+manual.
+@c VxWorks, see the @cite{VxWorks Programmer's Guide}.
+
+Once you have included @file{rdb.a} in your VxWorks system image and set
+your Unix execution search path to find @value{GDBN}, you are ready to
+run @value{GDBN}. From your Unix host, run @code{@value{GDBP}} (or
+@code{vxgdb}, depending on your installation).
+
+@value{GDBN} comes up showing the prompt:
+
+@smallexample
+(vxgdb)
+@end smallexample
+
+@menu
+* VxWorks Connection:: Connecting to VxWorks
+* VxWorks Download:: VxWorks download
+* VxWorks Attach:: Running tasks
+@end menu
+
+@node VxWorks Connection
+@subsubsection Connecting to VxWorks
+
+The @value{GDBN} command @code{target} lets you connect to a VxWorks target on the
+network. To connect to a target whose host name is ``@code{tt}'', type:
+
+@smallexample
+(vxgdb) target vxworks tt
+@end smallexample
+
+@need 750
+@value{GDBN} displays messages like these:
+
+@smallexample
+Attaching remote machine across net...
+Connected to tt.
+@end smallexample
+
+@need 1000
+@value{GDBN} then attempts to read the symbol tables of any object modules
+loaded into the VxWorks target since it was last booted. @value{GDBN} locates
+these files by searching the directories listed in the command search
+path (@pxref{Environment, ,Your program's environment}); if it fails
+to find an object file, it displays a message such as:
+
+@smallexample
+prog.o: No such file or directory.
+@end smallexample
+
+When this happens, add the appropriate directory to the search path with
+the @value{GDBN} command @code{path}, and execute the @code{target}
+command again.
+
+@node VxWorks Download
+@subsubsection VxWorks download
+
+@cindex download to VxWorks
+If you have connected to the VxWorks target and you want to debug an
+object that has not yet been loaded, you can use the @value{GDBN}
+@code{load} command to download a file from Unix to VxWorks
+incrementally. The object file given as an argument to the @code{load}
+command is actually opened twice: first by the VxWorks target in order
+to download the code, then by @value{GDBN} in order to read the symbol
+table. This can lead to problems if the current working directories on
+the two systems differ. If both systems have NFS mounted the same
+filesystems, you can avoid these problems by using absolute paths.
+Otherwise, it is simplest to set the working directory on both systems
+to the directory in which the object file resides, and then to reference
+the file by its name, without any path. For instance, a program
+@file{prog.o} may reside in @file{@var{vxpath}/vw/demo/rdb} in VxWorks
+and in @file{@var{hostpath}/vw/demo/rdb} on the host. To load this
+program, type this on VxWorks:
+
+@smallexample
+-> cd "@var{vxpath}/vw/demo/rdb"
+@end smallexample
+
+@noindent
+Then, in @value{GDBN}, type:
+
+@smallexample
+(vxgdb) cd @var{hostpath}/vw/demo/rdb
+(vxgdb) load prog.o
+@end smallexample
+
+@value{GDBN} displays a response similar to this:
+
+@smallexample
+Reading symbol data from wherever/vw/demo/rdb/prog.o... done.
+@end smallexample
+
+You can also use the @code{load} command to reload an object module
+after editing and recompiling the corresponding source file. Note that
+this makes @value{GDBN} delete all currently-defined breakpoints,
+auto-displays, and convenience variables, and to clear the value
+history. (This is necessary in order to preserve the integrity of
+debugger's data structures that reference the target system's symbol
+table.)
+
+@node VxWorks Attach
+@subsubsection Running tasks
+
+@cindex running VxWorks tasks
+You can also attach to an existing task using the @code{attach} command as
+follows:
+
+@smallexample
+(vxgdb) attach @var{task}
+@end smallexample
+
+@noindent
+where @var{task} is the VxWorks hexadecimal task ID. The task can be running
+or suspended when you attach to it. Running tasks are suspended at
+the time of attachment.
+
+@node Embedded Processors
+@section Embedded Processors
+
+This section goes into details specific to particular embedded
+configurations.
+
+
+@menu
+* ARM:: ARM
+* H8/300:: Hitachi H8/300
+* H8/500:: Hitachi H8/500
+* i960:: Intel i960
+* M32R/D:: Mitsubishi M32R/D
+* M68K:: Motorola M68K
+* M88K:: Motorola M88K
+* MIPS Embedded:: MIPS Embedded
+* PA:: HP PA Embedded
+* PowerPC: PowerPC
+* SH:: Hitachi SH
+* Sparclet:: Tsqware Sparclet
+* Sparclite:: Fujitsu Sparclite
+* ST2000:: Tandem ST2000
+* Z8000:: Zilog Z8000
+@end menu
+
+@node ARM
+@subsection ARM
+
+@table @code
+
+@kindex target rdi
+@item target rdi @var{dev}
+ARM Angel monitor, via RDI library interface to ADP protocol. You may
+use this target to communicate with both boards running the Angel
+monitor, or with the EmbeddedICE JTAG debug device.
+
+@kindex target rdp
+@item target rdp @var{dev}
+ARM Demon monitor.
+
+@end table
+
+@node H8/300
+@subsection Hitachi H8/300
+
+@table @code
+
+@kindex target hms@r{, with H8/300}
+@item target hms @var{dev}
+A Hitachi SH, H8/300, or H8/500 board, attached via serial line to your host.
+Use special commands @code{device} and @code{speed} to control the serial
+line and the communications speed used.
+
+@kindex target e7000@r{, with H8/300}
+@item target e7000 @var{dev}
+E7000 emulator for Hitachi H8 and SH.
+
+@kindex target sh3@r{, with H8/300}
+@kindex target sh3e@r{, with H8/300}
+@item target sh3 @var{dev}
+@itemx target sh3e @var{dev}
+Hitachi SH-3 and SH-3E target systems.
+
+@end table
+
+@cindex download to H8/300 or H8/500
+@cindex H8/300 or H8/500 download
+@cindex download to Hitachi SH
+@cindex Hitachi SH download
+When you select remote debugging to a Hitachi SH, H8/300, or H8/500
+board, the @code{load} command downloads your program to the Hitachi
+board and also opens it as the current executable target for
+@value{GDBN} on your host (like the @code{file} command).
+
+@value{GDBN} needs to know these things to talk to your
+Hitachi SH, H8/300, or H8/500:
+
+@enumerate
+@item
+that you want to use @samp{target hms}, the remote debugging interface
+for Hitachi microprocessors, or @samp{target e7000}, the in-circuit
+emulator for the Hitachi SH and the Hitachi 300H. (@samp{target hms} is
+the default when @value{GDBN} is configured specifically for the Hitachi SH,
+H8/300, or H8/500.)
+
+@item
+what serial device connects your host to your Hitachi board (the first
+serial device available on your host is the default).
+
+@item
+what speed to use over the serial device.
+@end enumerate
+
+@menu
+* Hitachi Boards:: Connecting to Hitachi boards.
+* Hitachi ICE:: Using the E7000 In-Circuit Emulator.
+* Hitachi Special:: Special @value{GDBN} commands for Hitachi micros.
+@end menu
+
+@node Hitachi Boards
+@subsubsection Connecting to Hitachi boards
+
+@c only for Unix hosts
+@kindex device
+@cindex serial device, Hitachi micros
+Use the special @code{@value{GDBN}} command @samp{device @var{port}} if you
+need to explicitly set the serial device. The default @var{port} is the
+first available port on your host. This is only necessary on Unix
+hosts, where it is typically something like @file{/dev/ttya}.
+
+@kindex speed
+@cindex serial line speed, Hitachi micros
+@code{@value{GDBN}} has another special command to set the communications
+speed: @samp{speed @var{bps}}. This command also is only used from Unix
+hosts; on DOS hosts, set the line speed as usual from outside @value{GDBN} with
+the DOS @code{mode} command (for instance,
+@w{@kbd{mode com2:9600,n,8,1,p}} for a 9600@dmn{bps} connection).
+
+The @samp{device} and @samp{speed} commands are available only when you
+use a Unix host to debug your Hitachi microprocessor programs. If you
+use a DOS host,
+@value{GDBN} depends on an auxiliary terminate-and-stay-resident program
+called @code{asynctsr} to communicate with the development board
+through a PC serial port. You must also use the DOS @code{mode} command
+to set up the serial port on the DOS side.
+
+The following sample session illustrates the steps needed to start a
+program under @value{GDBN} control on an H8/300. The example uses a
+sample H8/300 program called @file{t.x}. The procedure is the same for
+the Hitachi SH and the H8/500.
+
+First hook up your development board. In this example, we use a
+board attached to serial port @code{COM2}; if you use a different serial
+port, substitute its name in the argument of the @code{mode} command.
+When you call @code{asynctsr}, the auxiliary comms program used by the
+debugger, you give it just the numeric part of the serial port's name;
+for example, @samp{asyncstr 2} below runs @code{asyncstr} on
+@code{COM2}.
+
+@smallexample
+C:\H8300\TEST> asynctsr 2
+C:\H8300\TEST> mode com2:9600,n,8,1,p
+
+Resident portion of MODE loaded
+
+COM2: 9600, n, 8, 1, p
+
+@end smallexample
+
+@quotation
+@emph{Warning:} We have noticed a bug in PC-NFS that conflicts with
+@code{asynctsr}. If you also run PC-NFS on your DOS host, you may need to
+disable it, or even boot without it, to use @code{asynctsr} to control
+your development board.
+@end quotation
+
+@kindex target hms@r{, and serial protocol}
+Now that serial communications are set up, and the development board is
+connected, you can start up @value{GDBN}. Call @code{@value{GDBP}} with
+the name of your program as the argument. @code{@value{GDBN}} prompts
+you, as usual, with the prompt @samp{(@value{GDBP})}. Use two special
+commands to begin your debugging session: @samp{target hms} to specify
+cross-debugging to the Hitachi board, and the @code{load} command to
+download your program to the board. @code{load} displays the names of
+the program's sections, and a @samp{*} for each 2K of data downloaded.
+(If you want to refresh @value{GDBN} data on symbols or on the
+executable file without downloading, use the @value{GDBN} commands
+@code{file} or @code{symbol-file}. These commands, and @code{load}
+itself, are described in @ref{Files,,Commands to specify files}.)
+
+@smallexample
+(eg-C:\H8300\TEST) @value{GDBP} t.x
+@value{GDBN} is free software and you are welcome to distribute copies
+ of it under certain conditions; type "show copying" to see
+ the conditions.
+There is absolutely no warranty for @value{GDBN}; type "show warranty"
+for details.
+@value{GDBN} @value{GDBVN}, Copyright 1992 Free Software Foundation, Inc...
+(@value{GDBP}) target hms
+Connected to remote H8/300 HMS system.
+(@value{GDBP}) load t.x
+.text : 0x8000 .. 0xabde ***********
+.data : 0xabde .. 0xad30 *
+.stack : 0xf000 .. 0xf014 *
+@end smallexample
+
+At this point, you're ready to run or debug your program. From here on,
+you can use all the usual @value{GDBN} commands. The @code{break} command
+sets breakpoints; the @code{run} command starts your program;
+@code{print} or @code{x} display data; the @code{continue} command
+resumes execution after stopping at a breakpoint. You can use the
+@code{help} command at any time to find out more about @value{GDBN} commands.
+
+Remember, however, that @emph{operating system} facilities aren't
+available on your development board; for example, if your program hangs,
+you can't send an interrupt---but you can press the @sc{reset} switch!
+
+Use the @sc{reset} button on the development board
+@itemize @bullet
+@item
+to interrupt your program (don't use @kbd{ctl-C} on the DOS host---it has
+no way to pass an interrupt signal to the development board); and
+
+@item
+to return to the @value{GDBN} command prompt after your program finishes
+normally. The communications protocol provides no other way for @value{GDBN}
+to detect program completion.
+@end itemize
+
+In either case, @value{GDBN} sees the effect of a @sc{reset} on the
+development board as a ``normal exit'' of your program.
+
+@node Hitachi ICE
+@subsubsection Using the E7000 in-circuit emulator
+
+@kindex target e7000@r{, with Hitachi ICE}
+You can use the E7000 in-circuit emulator to develop code for either the
+Hitachi SH or the H8/300H. Use one of these forms of the @samp{target
+e7000} command to connect @value{GDBN} to your E7000:
+
+@table @code
+@item target e7000 @var{port} @var{speed}
+Use this form if your E7000 is connected to a serial port. The
+@var{port} argument identifies what serial port to use (for example,
+@samp{com2}). The third argument is the line speed in bits per second
+(for example, @samp{9600}).
+
+@item target e7000 @var{hostname}
+If your E7000 is installed as a host on a TCP/IP network, you can just
+specify its hostname; @value{GDBN} uses @code{telnet} to connect.
+@end table
+
+@node Hitachi Special
+@subsubsection Special @value{GDBN} commands for Hitachi micros
+
+Some @value{GDBN} commands are available only for the H8/300:
+
+@table @code
+
+@kindex set machine
+@kindex show machine
+@item set machine h8300
+@itemx set machine h8300h
+Condition @value{GDBN} for one of the two variants of the H8/300
+architecture with @samp{set machine}. You can use @samp{show machine}
+to check which variant is currently in effect.
+
+@end table
+
+@node H8/500
+@subsection H8/500
+
+@table @code
+
+@kindex set memory @var{mod}
+@cindex memory models, H8/500
+@item set memory @var{mod}
+@itemx show memory
+Specify which H8/500 memory model (@var{mod}) you are using with
+@samp{set memory}; check which memory model is in effect with @samp{show
+memory}. The accepted values for @var{mod} are @code{small},
+@code{big}, @code{medium}, and @code{compact}.
+
+@end table
+
+@node i960
+@subsection Intel i960
+
+@table @code
+
+@kindex target mon960
+@item target mon960 @var{dev}
+MON960 monitor for Intel i960.
+
+@kindex target nindy
+@item target nindy @var{devicename}
+An Intel 960 board controlled by a Nindy Monitor. @var{devicename} is
+the name of the serial device to use for the connection, e.g.
+@file{/dev/ttya}.
+
+@end table
+
+@cindex Nindy
+@cindex i960
+@dfn{Nindy} is a ROM Monitor program for Intel 960 target systems. When
+@value{GDBN} is configured to control a remote Intel 960 using Nindy, you can
+tell @value{GDBN} how to connect to the 960 in several ways:
+
+@itemize @bullet
+@item
+Through command line options specifying serial port, version of the
+Nindy protocol, and communications speed;
+
+@item
+By responding to a prompt on startup;
+
+@item
+By using the @code{target} command at any point during your @value{GDBN}
+session. @xref{Target Commands, ,Commands for managing targets}.
+
+@end itemize
+
+@cindex download to Nindy-960
+With the Nindy interface to an Intel 960 board, @code{load}
+downloads @var{filename} to the 960 as well as adding its symbols in
+@value{GDBN}.
+
+@menu
+* Nindy Startup:: Startup with Nindy
+* Nindy Options:: Options for Nindy
+* Nindy Reset:: Nindy reset command
+@end menu
+
+@node Nindy Startup
+@subsubsection Startup with Nindy
+
+If you simply start @code{@value{GDBP}} without using any command-line
+options, you are prompted for what serial port to use, @emph{before} you
+reach the ordinary @value{GDBN} prompt:
+
+@smallexample
+Attach /dev/ttyNN -- specify NN, or "quit" to quit:
+@end smallexample
+
+@noindent
+Respond to the prompt with whatever suffix (after @samp{/dev/tty})
+identifies the serial port you want to use. You can, if you choose,
+simply start up with no Nindy connection by responding to the prompt
+with an empty line. If you do this and later wish to attach to Nindy,
+use @code{target} (@pxref{Target Commands, ,Commands for managing targets}).
+
+@node Nindy Options
+@subsubsection Options for Nindy
+
+These are the startup options for beginning your @value{GDBN} session with a
+Nindy-960 board attached:
+
+@table @code
+@item -r @var{port}
+Specify the serial port name of a serial interface to be used to connect
+to the target system. This option is only available when @value{GDBN} is
+configured for the Intel 960 target architecture. You may specify
+@var{port} as any of: a full pathname (e.g. @samp{-r /dev/ttya}), a
+device name in @file{/dev} (e.g. @samp{-r ttya}), or simply the unique
+suffix for a specific @code{tty} (e.g. @samp{-r a}).
+
+@item -O
+(An uppercase letter ``O'', not a zero.) Specify that @value{GDBN} should use
+the ``old'' Nindy monitor protocol to connect to the target system.
+This option is only available when @value{GDBN} is configured for the Intel 960
+target architecture.
+
+@quotation
+@emph{Warning:} if you specify @samp{-O}, but are actually trying to
+connect to a target system that expects the newer protocol, the connection
+fails, appearing to be a speed mismatch. @value{GDBN} repeatedly
+attempts to reconnect at several different line speeds. You can abort
+this process with an interrupt.
+@end quotation
+
+@item -brk
+Specify that @value{GDBN} should first send a @code{BREAK} signal to the target
+system, in an attempt to reset it, before connecting to a Nindy target.
+
+@quotation
+@emph{Warning:} Many target systems do not have the hardware that this
+requires; it only works with a few boards.
+@end quotation
+@end table
+
+The standard @samp{-b} option controls the line speed used on the serial
+port.
+
+@c @group
+@node Nindy Reset
+@subsubsection Nindy reset command
+
+@table @code
+@item reset
+@kindex reset
+For a Nindy target, this command sends a ``break'' to the remote target
+system; this is only useful if the target has been equipped with a
+circuit to perform a hard reset (or some other interesting action) when
+a break is detected.
+@end table
+@c @end group
+
+@node M32R/D
+@subsection Mitsubishi M32R/D
+
+@table @code
+
+@kindex target m32r
+@item target m32r @var{dev}
+Mitsubishi M32R/D ROM monitor.
+
+@end table
+
+@node M68K
+@subsection M68k
+
+The Motorola m68k configuration includes ColdFire support, and
+target command for the following ROM monitors.
+
+@table @code
+
+@kindex target abug
+@item target abug @var{dev}
+ABug ROM monitor for M68K.
+
+@kindex target cpu32bug
+@item target cpu32bug @var{dev}
+CPU32BUG monitor, running on a CPU32 (M68K) board.
+
+@kindex target dbug
+@item target dbug @var{dev}
+dBUG ROM monitor for Motorola ColdFire.
+
+@kindex target est
+@item target est @var{dev}
+EST-300 ICE monitor, running on a CPU32 (M68K) board.
+
+@kindex target rom68k
+@item target rom68k @var{dev}
+ROM 68K monitor, running on an M68K IDP board.
+
+@end table
+
+If @value{GDBN} is configured with @code{m68*-ericsson-*}, it will
+instead have only a single special target command:
+
+@table @code
+
+@kindex target es1800
+@item target es1800 @var{dev}
+ES-1800 emulator for M68K.
+
+@end table
+
+[context?]
+
+@table @code
+
+@kindex target rombug
+@item target rombug @var{dev}
+ROMBUG ROM monitor for OS/9000.
+
+@end table
+
+@node M88K
+@subsection M88K
+
+@table @code
+
+@kindex target bug
+@item target bug @var{dev}
+BUG monitor, running on a MVME187 (m88k) board.
+
+@end table
+
+@node MIPS Embedded
+@subsection MIPS Embedded
+
+@cindex MIPS boards
+@value{GDBN} can use the MIPS remote debugging protocol to talk to a
+MIPS board attached to a serial line. This is available when
+you configure @value{GDBN} with @samp{--target=mips-idt-ecoff}.
+
+@need 1000
+Use these @value{GDBN} commands to specify the connection to your target board:
+
+@table @code
+@item target mips @var{port}
+@kindex target mips @var{port}
+To run a program on the board, start up @code{@value{GDBP}} with the
+name of your program as the argument. To connect to the board, use the
+command @samp{target mips @var{port}}, where @var{port} is the name of
+the serial port connected to the board. If the program has not already
+been downloaded to the board, you may use the @code{load} command to
+download it. You can then use all the usual @value{GDBN} commands.
+
+For example, this sequence connects to the target board through a serial
+port, and loads and runs a program called @var{prog} through the
+debugger:
+
+@smallexample
+host$ @value{GDBP} @var{prog}
+@value{GDBN} is free software and @dots{}
+(@value{GDBP}) target mips /dev/ttyb
+(@value{GDBP}) load @var{prog}
+(@value{GDBP}) run
+@end smallexample
+
+@item target mips @var{hostname}:@var{portnumber}
+On some @value{GDBN} host configurations, you can specify a TCP
+connection (for instance, to a serial line managed by a terminal
+concentrator) instead of a serial port, using the syntax
+@samp{@var{hostname}:@var{portnumber}}.
+
+@item target pmon @var{port}
+@kindex target pmon @var{port}
+PMON ROM monitor.
+
+@item target ddb @var{port}
+@kindex target ddb @var{port}
+NEC's DDB variant of PMON for Vr4300.
+
+@item target lsi @var{port}
+@kindex target lsi @var{port}
+LSI variant of PMON.
+
+@kindex target r3900
+@item target r3900 @var{dev}
+Densan DVE-R3900 ROM monitor for Toshiba R3900 Mips.
+
+@kindex target array
+@item target array @var{dev}
+Array Tech LSI33K RAID controller board.
+
+@end table
+
+
+@noindent
+@value{GDBN} also supports these special commands for MIPS targets:
+
+@table @code
+@item set processor @var{args}
+@itemx show processor
+@kindex set processor @var{args}
+@kindex show processor
+Use the @code{set processor} command to set the type of MIPS
+processor when you want to access processor-type-specific registers.
+For example, @code{set processor @var{r3041}} tells @value{GDBN}
+to use the CPU registers appropriate for the 3041 chip.
+Use the @code{show processor} command to see what MIPS processor @value{GDBN}
+is using. Use the @code{info reg} command to see what registers
+@value{GDBN} is using.
+
+@item set mipsfpu double
+@itemx set mipsfpu single
+@itemx set mipsfpu none
+@itemx show mipsfpu
+@kindex set mipsfpu
+@kindex show mipsfpu
+@cindex MIPS remote floating point
+@cindex floating point, MIPS remote
+If your target board does not support the MIPS floating point
+coprocessor, you should use the command @samp{set mipsfpu none} (if you
+need this, you may wish to put the command in your @value{GDBN} init
+file). This tells @value{GDBN} how to find the return value of
+functions which return floating point values. It also allows
+@value{GDBN} to avoid saving the floating point registers when calling
+functions on the board. If you are using a floating point coprocessor
+with only single precision floating point support, as on the @sc{r4650}
+processor, use the command @samp{set mipsfpu single}. The default
+double precision floating point coprocessor may be selected using
+@samp{set mipsfpu double}.
+
+In previous versions the only choices were double precision or no
+floating point, so @samp{set mipsfpu on} will select double precision
+and @samp{set mipsfpu off} will select no floating point.
+
+As usual, you can inquire about the @code{mipsfpu} variable with
+@samp{show mipsfpu}.
+
+@item set remotedebug @var{n}
+@itemx show remotedebug
+@kindex set remotedebug@r{, MIPS protocol}
+@kindex show remotedebug@r{, MIPS protocol}
+@cindex @code{remotedebug}, MIPS protocol
+@cindex MIPS @code{remotedebug} protocol
+@c FIXME! For this to be useful, you must know something about the MIPS
+@c FIXME...protocol. Where is it described?
+You can see some debugging information about communications with the board
+by setting the @code{remotedebug} variable. If you set it to @code{1} using
+@samp{set remotedebug 1}, every packet is displayed. If you set it
+to @code{2}, every character is displayed. You can check the current value
+at any time with the command @samp{show remotedebug}.
+
+@item set timeout @var{seconds}
+@itemx set retransmit-timeout @var{seconds}
+@itemx show timeout
+@itemx show retransmit-timeout
+@cindex @code{timeout}, MIPS protocol
+@cindex @code{retransmit-timeout}, MIPS protocol
+@kindex set timeout
+@kindex show timeout
+@kindex set retransmit-timeout
+@kindex show retransmit-timeout
+You can control the timeout used while waiting for a packet, in the MIPS
+remote protocol, with the @code{set timeout @var{seconds}} command. The
+default is 5 seconds. Similarly, you can control the timeout used while
+waiting for an acknowledgement of a packet with the @code{set
+retransmit-timeout @var{seconds}} command. The default is 3 seconds.
+You can inspect both values with @code{show timeout} and @code{show
+retransmit-timeout}. (These commands are @emph{only} available when
+@value{GDBN} is configured for @samp{--target=mips-idt-ecoff}.)
+
+The timeout set by @code{set timeout} does not apply when @value{GDBN}
+is waiting for your program to stop. In that case, @value{GDBN} waits
+forever because it has no way of knowing how long the program is going
+to run before stopping.
+@end table
+
+@node PowerPC
+@subsection PowerPC
+
+@table @code
+
+@kindex target dink32
+@item target dink32 @var{dev}
+DINK32 ROM monitor.
+
+@kindex target ppcbug
+@item target ppcbug @var{dev}
+@kindex target ppcbug1
+@item target ppcbug1 @var{dev}
+PPCBUG ROM monitor for PowerPC.
+
+@kindex target sds
+@item target sds @var{dev}
+SDS monitor, running on a PowerPC board (such as Motorola's ADS).
+
+@end table
+
+@node PA
+@subsection HP PA Embedded
+
+@table @code
+
+@kindex target op50n
+@item target op50n @var{dev}
+OP50N monitor, running on an OKI HPPA board.
+
+@kindex target w89k
+@item target w89k @var{dev}
+W89K monitor, running on a Winbond HPPA board.
+
+@end table
+
+@node SH
+@subsection Hitachi SH
+
+@table @code
+
+@kindex target hms@r{, with Hitachi SH}
+@item target hms @var{dev}
+A Hitachi SH board attached via serial line to your host. Use special
+commands @code{device} and @code{speed} to control the serial line and
+the communications speed used.
+
+@kindex target e7000@r{, with Hitachi SH}
+@item target e7000 @var{dev}
+E7000 emulator for Hitachi SH.
+
+@kindex target sh3@r{, with SH}
+@kindex target sh3e@r{, with SH}
+@item target sh3 @var{dev}
+@item target sh3e @var{dev}
+Hitachi SH-3 and SH-3E target systems.
+
+@end table
+
+@node Sparclet
+@subsection Tsqware Sparclet
+
+@cindex Sparclet
+
+@value{GDBN} enables developers to debug tasks running on
+Sparclet targets from a Unix host.
+@value{GDBN} uses code that runs on
+both the Unix host and on the Sparclet target. The program
+@code{@value{GDBP}} is installed and executed on the Unix host.
+
+@table @code
+@item remotetimeout @var{args}
+@kindex remotetimeout
+@value{GDBN} supports the option @code{remotetimeout}.
+This option is set by the user, and @var{args} represents the number of
+seconds @value{GDBN} waits for responses.
+@end table
+
+@cindex compiling, on Sparclet
+When compiling for debugging, include the options @samp{-g} to get debug
+information and @samp{-Ttext} to relocate the program to where you wish to
+load it on the target. You may also want to add the options @samp{-n} or
+@samp{-N} in order to reduce the size of the sections. Example:
+
+@smallexample
+sparclet-aout-gcc prog.c -Ttext 0x12010000 -g -o prog -N
+@end smallexample
+
+You can use @code{objdump} to verify that the addresses are what you intended:
+
+@smallexample
+sparclet-aout-objdump --headers --syms prog
+@end smallexample
+
+@cindex running, on Sparclet
+Once you have set
+your Unix execution search path to find @value{GDBN}, you are ready to
+run @value{GDBN}. From your Unix host, run @code{@value{GDBP}}
+(or @code{sparclet-aout-gdb}, depending on your installation).
+
+@value{GDBN} comes up showing the prompt:
+
+@smallexample
+(gdbslet)
+@end smallexample
+
+@menu
+* Sparclet File:: Setting the file to debug
+* Sparclet Connection:: Connecting to Sparclet
+* Sparclet Download:: Sparclet download
+* Sparclet Execution:: Running and debugging
+@end menu
+
+@node Sparclet File
+@subsubsection Setting file to debug
+
+The @value{GDBN} command @code{file} lets you choose with program to debug.
+
+@smallexample
+(gdbslet) file prog
+@end smallexample
+
+@need 1000
+@value{GDBN} then attempts to read the symbol table of @file{prog}.
+@value{GDBN} locates
+the file by searching the directories listed in the command search
+path.
+If the file was compiled with debug information (option "-g"), source
+files will be searched as well.
+@value{GDBN} locates
+the source files by searching the directories listed in the directory search
+path (@pxref{Environment, ,Your program's environment}).
+If it fails
+to find a file, it displays a message such as:
+
+@smallexample
+prog: No such file or directory.
+@end smallexample
+
+When this happens, add the appropriate directories to the search paths with
+the @value{GDBN} commands @code{path} and @code{dir}, and execute the
+@code{target} command again.
+
+@node Sparclet Connection
+@subsubsection Connecting to Sparclet
+
+The @value{GDBN} command @code{target} lets you connect to a Sparclet target.
+To connect to a target on serial port ``@code{ttya}'', type:
+
+@smallexample
+(gdbslet) target sparclet /dev/ttya
+Remote target sparclet connected to /dev/ttya
+main () at ../prog.c:3
+@end smallexample
+
+@need 750
+@value{GDBN} displays messages like these:
+
+@smallexample
+Connected to ttya.
+@end smallexample
+
+@node Sparclet Download
+@subsubsection Sparclet download
+
+@cindex download to Sparclet
+Once connected to the Sparclet target,
+you can use the @value{GDBN}
+@code{load} command to download the file from the host to the target.
+The file name and load offset should be given as arguments to the @code{load}
+command.
+Since the file format is aout, the program must be loaded to the starting
+address. You can use @code{objdump} to find out what this value is. The load
+offset is an offset which is added to the VMA (virtual memory address)
+of each of the file's sections.
+For instance, if the program
+@file{prog} was linked to text address 0x1201000, with data at 0x12010160
+and bss at 0x12010170, in @value{GDBN}, type:
+
+@smallexample
+(gdbslet) load prog 0x12010000
+Loading section .text, size 0xdb0 vma 0x12010000
+@end smallexample
+
+If the code is loaded at a different address then what the program was linked
+to, you may need to use the @code{section} and @code{add-symbol-file} commands
+to tell @value{GDBN} where to map the symbol table.
+
+@node Sparclet Execution
+@subsubsection Running and debugging
+
+@cindex running and debugging Sparclet programs
+You can now begin debugging the task using @value{GDBN}'s execution control
+commands, @code{b}, @code{step}, @code{run}, etc. See the @value{GDBN}
+manual for the list of commands.
+
+@smallexample
+(gdbslet) b main
+Breakpoint 1 at 0x12010000: file prog.c, line 3.
+(gdbslet) run
+Starting program: prog
+Breakpoint 1, main (argc=1, argv=0xeffff21c) at prog.c:3
+3 char *symarg = 0;
+(gdbslet) step
+4 char *execarg = "hello!";
+(gdbslet)
+@end smallexample
+
+@node Sparclite
+@subsection Fujitsu Sparclite
+
+@table @code
+
+@kindex target sparclite
+@item target sparclite @var{dev}
+Fujitsu sparclite boards, used only for the purpose of loading.
+You must use an additional command to debug the program.
+For example: target remote @var{dev} using @value{GDBN} standard
+remote protocol.
+
+@end table
+
+@node ST2000
+@subsection Tandem ST2000
+
+@value{GDBN} may be used with a Tandem ST2000 phone switch, running Tandem's
+STDBUG protocol.
+
+To connect your ST2000 to the host system, see the manufacturer's
+manual. Once the ST2000 is physically attached, you can run:
+
+@smallexample
+target st2000 @var{dev} @var{speed}
+@end smallexample
+
+@noindent
+to establish it as your debugging environment. @var{dev} is normally
+the name of a serial device, such as @file{/dev/ttya}, connected to the
+ST2000 via a serial line. You can instead specify @var{dev} as a TCP
+connection (for example, to a serial line attached via a terminal
+concentrator) using the syntax @code{@var{hostname}:@var{portnumber}}.
+
+The @code{load} and @code{attach} commands are @emph{not} defined for
+this target; you must load your program into the ST2000 as you normally
+would for standalone operation. @value{GDBN} reads debugging information
+(such as symbols) from a separate, debugging version of the program
+available on your host computer.
+@c FIXME!! This is terribly vague; what little content is here is
+@c basically hearsay.
+
+@cindex ST2000 auxiliary commands
+These auxiliary @value{GDBN} commands are available to help you with the ST2000
+environment:
+
+@table @code
+@item st2000 @var{command}
+@kindex st2000 @var{cmd}
+@cindex STDBUG commands (ST2000)
+@cindex commands to STDBUG (ST2000)
+Send a @var{command} to the STDBUG monitor. See the manufacturer's
+manual for available commands.
+
+@item connect
+@cindex connect (to STDBUG)
+Connect the controlling terminal to the STDBUG command monitor. When
+you are done interacting with STDBUG, typing either of two character
+sequences gets you back to the @value{GDBN} command prompt:
+@kbd{@key{RET}~.} (Return, followed by tilde and period) or
+@kbd{@key{RET}~@key{C-d}} (Return, followed by tilde and control-D).
+@end table
+
+@node Z8000
+@subsection Zilog Z8000
+
+@cindex Z8000
+@cindex simulator, Z8000
+@cindex Zilog Z8000 simulator
+
+When configured for debugging Zilog Z8000 targets, @value{GDBN} includes
+a Z8000 simulator.
+
+For the Z8000 family, @samp{target sim} simulates either the Z8002 (the
+unsegmented variant of the Z8000 architecture) or the Z8001 (the
+segmented variant). The simulator recognizes which architecture is
+appropriate by inspecting the object code.
+
+@table @code
+@item target sim @var{args}
+@kindex sim
+@kindex target sim@r{, with Z8000}
+Debug programs on a simulated CPU. If the simulator supports setup
+options, specify them via @var{args}.
+@end table
+
+@noindent
+After specifying this target, you can debug programs for the simulated
+CPU in the same style as programs for your host computer; use the
+@code{file} command to load a new program image, the @code{run} command
+to run your program, and so on.
+
+As well as making available all the usual machine registers
+(@pxref{Registers, ,Registers}), the Z8000 simulator provides three
+additional items of information as specially named registers:
+
+@table @code
+
+@item cycles
+Counts clock-ticks in the simulator.
+
+@item insts
+Counts instructions run in the simulator.
+
+@item time
+Execution time in 60ths of a second.
+
+@end table
+
+You can refer to these values in @value{GDBN} expressions with the usual
+conventions; for example, @w{@samp{b fputc if $cycles>5000}} sets a
+conditional breakpoint that suspends only after at least 5000
+simulated clock ticks.
+
+@node Architectures
+@section Architectures
+
+This section describes characteristics of architectures that affect
+all uses of @value{GDBN} with the architecture, both native and cross.
+
+@menu
+* A29K::
+* Alpha::
+* MIPS::
+@end menu
+
+@node A29K
+@subsection A29K
+
+@table @code
+
+@kindex set rstack_high_address
+@cindex AMD 29K register stack
+@cindex register stack, AMD29K
+@item set rstack_high_address @var{address}
+On AMD 29000 family processors, registers are saved in a separate
+@dfn{register stack}. There is no way for @value{GDBN} to determine the
+extent of this stack. Normally, @value{GDBN} just assumes that the
+stack is ``large enough''. This may result in @value{GDBN} referencing
+memory locations that do not exist. If necessary, you can get around
+this problem by specifying the ending address of the register stack with
+the @code{set rstack_high_address} command. The argument should be an
+address, which you probably want to precede with @samp{0x} to specify in
+hexadecimal.
+
+@kindex show rstack_high_address
+@item show rstack_high_address
+Display the current limit of the register stack, on AMD 29000 family
+processors.
+
+@end table
+
+@node Alpha
+@subsection Alpha
+
+See the following section.
+
+@node MIPS
+@subsection MIPS
+
+@cindex stack on Alpha
+@cindex stack on MIPS
+@cindex Alpha stack
+@cindex MIPS stack
+Alpha- and MIPS-based computers use an unusual stack frame, which
+sometimes requires @value{GDBN} to search backward in the object code to
+find the beginning of a function.
+
+@cindex response time, MIPS debugging
+To improve response time (especially for embedded applications, where
+@value{GDBN} may be restricted to a slow serial line for this search)
+you may want to limit the size of this search, using one of these
+commands:
+
+@table @code
+@cindex @code{heuristic-fence-post} (Alpha, MIPS)
+@item set heuristic-fence-post @var{limit}
+Restrict @value{GDBN} to examining at most @var{limit} bytes in its
+search for the beginning of a function. A value of @var{0} (the
+default) means there is no limit. However, except for @var{0}, the
+larger the limit the more bytes @code{heuristic-fence-post} must search
+and therefore the longer it takes to run.
+
+@item show heuristic-fence-post
+Display the current limit.
+@end table
+
+@noindent
+These commands are available @emph{only} when @value{GDBN} is configured
+for debugging programs on Alpha or MIPS processors.
+
+
+@node Controlling GDB
+@chapter Controlling @value{GDBN}
+
+You can alter the way @value{GDBN} interacts with you by using the
+@code{set} command. For commands controlling how @value{GDBN} displays
+data, see @ref{Print Settings, ,Print settings}. Other settings are
+described here.
+
+@menu
+* Prompt:: Prompt
+* Editing:: Command editing
+* History:: Command history
+* Screen Size:: Screen size
+* Numbers:: Numbers
+* Messages/Warnings:: Optional warnings and messages
+* Debugging Output:: Optional messages about internal happenings
+@end menu
+
+@node Prompt
+@section Prompt
+
+@cindex prompt
+
+@value{GDBN} indicates its readiness to read a command by printing a string
+called the @dfn{prompt}. This string is normally @samp{(@value{GDBP})}. You
+can change the prompt string with the @code{set prompt} command. For
+instance, when debugging @value{GDBN} with @value{GDBN}, it is useful to change
+the prompt in one of the @value{GDBN} sessions so that you can always tell
+which one you are talking to.
+
+@emph{Note:} @code{set prompt} does not add a space for you after the
+prompt you set. This allows you to set a prompt which ends in a space
+or a prompt that does not.
+
+@table @code
+@kindex set prompt
+@item set prompt @var{newprompt}
+Directs @value{GDBN} to use @var{newprompt} as its prompt string henceforth.
+
+@kindex show prompt
+@item show prompt
+Prints a line of the form: @samp{Gdb's prompt is: @var{your-prompt}}
+@end table
+
+@node Editing
+@section Command editing
+@cindex readline
+@cindex command line editing
+
+@value{GDBN} reads its input commands via the @dfn{readline} interface. This
+@sc{gnu} library provides consistent behavior for programs which provide a
+command line interface to the user. Advantages are @sc{gnu} Emacs-style
+or @dfn{vi}-style inline editing of commands, @code{csh}-like history
+substitution, and a storage and recall of command history across
+debugging sessions.
+
+You may control the behavior of command line editing in @value{GDBN} with the
+command @code{set}.
+
+@table @code
+@kindex set editing
+@cindex editing
+@item set editing
+@itemx set editing on
+Enable command line editing (enabled by default).
+
+@item set editing off
+Disable command line editing.
+
+@kindex show editing
+@item show editing
+Show whether command line editing is enabled.
+@end table
+
+@node History
+@section Command history
+
+@value{GDBN} can keep track of the commands you type during your
+debugging sessions, so that you can be certain of precisely what
+happened. Use these commands to manage the @value{GDBN} command
+history facility.
+
+@table @code
+@cindex history substitution
+@cindex history file
+@kindex set history filename
+@kindex GDBHISTFILE
+@item set history filename @var{fname}
+Set the name of the @value{GDBN} command history file to @var{fname}.
+This is the file where @value{GDBN} reads an initial command history
+list, and where it writes the command history from this session when it
+exits. You can access this list through history expansion or through
+the history command editing characters listed below. This file defaults
+to the value of the environment variable @code{GDBHISTFILE}, or to
+@file{./.gdb_history} (@file{./_gdb_history} on MS-DOS) if this variable
+is not set.
+
+@cindex history save
+@kindex set history save
+@item set history save
+@itemx set history save on
+Record command history in a file, whose name may be specified with the
+@code{set history filename} command. By default, this option is disabled.
+
+@item set history save off
+Stop recording command history in a file.
+
+@cindex history size
+@kindex set history size
+@item set history size @var{size}
+Set the number of commands which @value{GDBN} keeps in its history list.
+This defaults to the value of the environment variable
+@code{HISTSIZE}, or to 256 if this variable is not set.
+@end table
+
+@cindex history expansion
+History expansion assigns special meaning to the character @kbd{!}.
+@ifset have-readline-appendices
+@xref{Event Designators}.
+@end ifset
+
+Since @kbd{!} is also the logical not operator in C, history expansion
+is off by default. If you decide to enable history expansion with the
+@code{set history expansion on} command, you may sometimes need to
+follow @kbd{!} (when it is used as logical not, in an expression) with
+a space or a tab to prevent it from being expanded. The readline
+history facilities do not attempt substitution on the strings
+@kbd{!=} and @kbd{!(}, even when history expansion is enabled.
+
+The commands to control history expansion are:
+
+@table @code
+@kindex set history expansion
+@item set history expansion on
+@itemx set history expansion
+Enable history expansion. History expansion is off by default.
+
+@item set history expansion off
+Disable history expansion.
+
+The readline code comes with more complete documentation of
+editing and history expansion features. Users unfamiliar with @sc{gnu} Emacs
+or @code{vi} may wish to read it.
+@ifset have-readline-appendices
+@xref{Command Line Editing}.
+@end ifset
+
+@c @group
+@kindex show history
+@item show history
+@itemx show history filename
+@itemx show history save
+@itemx show history size
+@itemx show history expansion
+These commands display the state of the @value{GDBN} history parameters.
+@code{show history} by itself displays all four states.
+@c @end group
+@end table
+
+@table @code
+@kindex shows
+@item show commands
+Display the last ten commands in the command history.
+
+@item show commands @var{n}
+Print ten commands centered on command number @var{n}.
+
+@item show commands +
+Print ten commands just after the commands last printed.
+@end table
+
+@node Screen Size
+@section Screen size
+@cindex size of screen
+@cindex pauses in output
+
+Certain commands to @value{GDBN} may produce large amounts of
+information output to the screen. To help you read all of it,
+@value{GDBN} pauses and asks you for input at the end of each page of
+output. Type @key{RET} when you want to continue the output, or @kbd{q}
+to discard the remaining output. Also, the screen width setting
+determines when to wrap lines of output. Depending on what is being
+printed, @value{GDBN} tries to break the line at a readable place,
+rather than simply letting it overflow onto the following line.
+
+Normally @value{GDBN} knows the size of the screen from the terminal
+driver software. For example, on Unix @value{GDBN} uses the termcap data base
+together with the value of the @code{TERM} environment variable and the
+@code{stty rows} and @code{stty cols} settings. If this is not correct,
+you can override it with the @code{set height} and @code{set
+width} commands:
+
+@table @code
+@kindex set height
+@kindex set width
+@kindex show width
+@kindex show height
+@item set height @var{lpp}
+@itemx show height
+@itemx set width @var{cpl}
+@itemx show width
+These @code{set} commands specify a screen height of @var{lpp} lines and
+a screen width of @var{cpl} characters. The associated @code{show}
+commands display the current settings.
+
+If you specify a height of zero lines, @value{GDBN} does not pause during
+output no matter how long the output is. This is useful if output is to a
+file or to an editor buffer.
+
+Likewise, you can specify @samp{set width 0} to prevent @value{GDBN}
+from wrapping its output.
+@end table
+
+@node Numbers
+@section Numbers
+@cindex number representation
+@cindex entering numbers
+
+You can always enter numbers in octal, decimal, or hexadecimal in
+@value{GDBN} by the usual conventions: octal numbers begin with
+@samp{0}, decimal numbers end with @samp{.}, and hexadecimal numbers
+begin with @samp{0x}. Numbers that begin with none of these are, by
+default, entered in base 10; likewise, the default display for
+numbers---when no particular format is specified---is base 10. You can
+change the default base for both input and output with the @code{set
+radix} command.
+
+@table @code
+@kindex set input-radix
+@item set input-radix @var{base}
+Set the default base for numeric input. Supported choices
+for @var{base} are decimal 8, 10, or 16. @var{base} must itself be
+specified either unambiguously or using the current default radix; for
+example, any of
+
+@smallexample
+set radix 012
+set radix 10.
+set radix 0xa
+@end smallexample
+
+@noindent
+sets the base to decimal. On the other hand, @samp{set radix 10}
+leaves the radix unchanged no matter what it was.
+
+@kindex set output-radix
+@item set output-radix @var{base}
+Set the default base for numeric display. Supported choices
+for @var{base} are decimal 8, 10, or 16. @var{base} must itself be
+specified either unambiguously or using the current default radix.
+
+@kindex show input-radix
+@item show input-radix
+Display the current default base for numeric input.
+
+@kindex show output-radix
+@item show output-radix
+Display the current default base for numeric display.
+@end table
+
+@node Messages/Warnings
+@section Optional warnings and messages
+
+By default, @value{GDBN} is silent about its inner workings. If you are
+running on a slow machine, you may want to use the @code{set verbose}
+command. This makes @value{GDBN} tell you when it does a lengthy
+internal operation, so you will not think it has crashed.
+
+Currently, the messages controlled by @code{set verbose} are those
+which announce that the symbol table for a source file is being read;
+see @code{symbol-file} in @ref{Files, ,Commands to specify files}.
+
+@table @code
+@kindex set verbose
+@item set verbose on
+Enables @value{GDBN} output of certain informational messages.
+
+@item set verbose off
+Disables @value{GDBN} output of certain informational messages.
+
+@kindex show verbose
+@item show verbose
+Displays whether @code{set verbose} is on or off.
+@end table
+
+By default, if @value{GDBN} encounters bugs in the symbol table of an
+object file, it is silent; but if you are debugging a compiler, you may
+find this information useful (@pxref{Symbol Errors, ,Errors reading
+symbol files}).
+
+@table @code
+
+@kindex set complaints
+@item set complaints @var{limit}
+Permits @value{GDBN} to output @var{limit} complaints about each type of
+unusual symbols before becoming silent about the problem. Set
+@var{limit} to zero to suppress all complaints; set it to a large number
+to prevent complaints from being suppressed.
+
+@kindex show complaints
+@item show complaints
+Displays how many symbol complaints @value{GDBN} is permitted to produce.
+
+@end table
+
+By default, @value{GDBN} is cautious, and asks what sometimes seems to be a
+lot of stupid questions to confirm certain commands. For example, if
+you try to run a program which is already running:
+
+@smallexample
+(@value{GDBP}) run
+The program being debugged has been started already.
+Start it from the beginning? (y or n)
+@end smallexample
+
+If you are willing to unflinchingly face the consequences of your own
+commands, you can disable this ``feature'':
+
+@table @code
+
+@kindex set confirm
+@cindex flinching
+@cindex confirmation
+@cindex stupid questions
+@item set confirm off
+Disables confirmation requests.
+
+@item set confirm on
+Enables confirmation requests (the default).
+
+@kindex show confirm
+@item show confirm
+Displays state of confirmation requests.
+
+@end table
+
+@node Debugging Output
+@section Optional messages about internal happenings
+@table @code
+@kindex set debug arch
+@item set debug arch
+Turns on or off display of gdbarch debugging info. The default is off
+@kindex show debug arch
+@item show debug arch
+Displays the current state of displaying gdbarch debugging info.
+@kindex set debug event
+@item set debug event
+Turns on or off display of @value{GDBN} event debugging info. The
+default is off.
+@kindex show debug event
+@item show debug event
+Displays the current state of displaying @value{GDBN} event debugging
+info.
+@kindex set debug expression
+@item set debug expression
+Turns on or off display of @value{GDBN} expression debugging info. The
+default is off.
+@kindex show debug expression
+@item show debug expression
+Displays the current state of displaying @value{GDBN} expression
+debugging info.
+@kindex set debug overload
+@item set debug overload
+Turns on or off display of @value{GDBN} C@t{++} overload debugging
+info. This includes info such as ranking of functions, etc. The default
+is off.
+@kindex show debug overload
+@item show debug overload
+Displays the current state of displaying @value{GDBN} C@t{++} overload
+debugging info.
+@kindex set debug remote
+@cindex packets, reporting on stdout
+@cindex serial connections, debugging
+@item set debug remote
+Turns on or off display of reports on all packets sent back and forth across
+the serial line to the remote machine. The info is printed on the
+@value{GDBN} standard output stream. The default is off.
+@kindex show debug remote
+@item show debug remote
+Displays the state of display of remote packets.
+@kindex set debug serial
+@item set debug serial
+Turns on or off display of @value{GDBN} serial debugging info. The
+default is off.
+@kindex show debug serial
+@item show debug serial
+Displays the current state of displaying @value{GDBN} serial debugging
+info.
+@kindex set debug target
+@item set debug target
+Turns on or off display of @value{GDBN} target debugging info. This info
+includes what is going on at the target level of GDB, as it happens. The
+default is off.
+@kindex show debug target
+@item show debug target
+Displays the current state of displaying @value{GDBN} target debugging
+info.
+@kindex set debug varobj
+@item set debug varobj
+Turns on or off display of @value{GDBN} variable object debugging
+info. The default is off.
+@kindex show debug varobj
+@item show debug varobj
+Displays the current state of displaying @value{GDBN} variable object
+debugging info.
+@end table
+
+@node Sequences
+@chapter Canned Sequences of Commands
+
+Aside from breakpoint commands (@pxref{Break Commands, ,Breakpoint
+command lists}), @value{GDBN} provides two ways to store sequences of
+commands for execution as a unit: user-defined commands and command
+files.
+
+@menu
+* Define:: User-defined commands
+* Hooks:: User-defined command hooks
+* Command Files:: Command files
+* Output:: Commands for controlled output
+@end menu
+
+@node Define
+@section User-defined commands
+
+@cindex user-defined command
+A @dfn{user-defined command} is a sequence of @value{GDBN} commands to
+which you assign a new name as a command. This is done with the
+@code{define} command. User commands may accept up to 10 arguments
+separated by whitespace. Arguments are accessed within the user command
+via @var{$arg0@dots{}$arg9}. A trivial example:
+
+@smallexample
+define adder
+ print $arg0 + $arg1 + $arg2
+@end smallexample
+
+@noindent
+To execute the command use:
+
+@smallexample
+adder 1 2 3
+@end smallexample
+
+@noindent
+This defines the command @code{adder}, which prints the sum of
+its three arguments. Note the arguments are text substitutions, so they may
+reference variables, use complex expressions, or even perform inferior
+functions calls.
+
+@table @code
+
+@kindex define
+@item define @var{commandname}
+Define a command named @var{commandname}. If there is already a command
+by that name, you are asked to confirm that you want to redefine it.
+
+The definition of the command is made up of other @value{GDBN} command lines,
+which are given following the @code{define} command. The end of these
+commands is marked by a line containing @code{end}.
+
+@kindex if
+@kindex else
+@item if
+Takes a single argument, which is an expression to evaluate.
+It is followed by a series of commands that are executed
+only if the expression is true (nonzero).
+There can then optionally be a line @code{else}, followed
+by a series of commands that are only executed if the expression
+was false. The end of the list is marked by a line containing @code{end}.
+
+@kindex while
+@item while
+The syntax is similar to @code{if}: the command takes a single argument,
+which is an expression to evaluate, and must be followed by the commands to
+execute, one per line, terminated by an @code{end}.
+The commands are executed repeatedly as long as the expression
+evaluates to true.
+
+@kindex document
+@item document @var{commandname}
+Document the user-defined command @var{commandname}, so that it can be
+accessed by @code{help}. The command @var{commandname} must already be
+defined. This command reads lines of documentation just as @code{define}
+reads the lines of the command definition, ending with @code{end}.
+After the @code{document} command is finished, @code{help} on command
+@var{commandname} displays the documentation you have written.
+
+You may use the @code{document} command again to change the
+documentation of a command. Redefining the command with @code{define}
+does not change the documentation.
+
+@kindex help user-defined
+@item help user-defined
+List all user-defined commands, with the first line of the documentation
+(if any) for each.
+
+@kindex show user
+@item show user
+@itemx show user @var{commandname}
+Display the @value{GDBN} commands used to define @var{commandname} (but
+not its documentation). If no @var{commandname} is given, display the
+definitions for all user-defined commands.
+
+@kindex show max-user-call-depth
+@kindex set max-user-call-depth
+@item show max-user-call-depth
+@itemx set max-user-call-depth
+The value of @code{max-user-call-depth} controls how many recursion
+levels are allowed in user-defined commands before GDB suspects an
+infinite recursion and aborts the command.
+
+@end table
+
+When user-defined commands are executed, the
+commands of the definition are not printed. An error in any command
+stops execution of the user-defined command.
+
+If used interactively, commands that would ask for confirmation proceed
+without asking when used inside a user-defined command. Many @value{GDBN}
+commands that normally print messages to say what they are doing omit the
+messages when used in a user-defined command.
+
+@node Hooks
+@section User-defined command hooks
+@cindex command hooks
+@cindex hooks, for commands
+@cindex hooks, pre-command
+
+@kindex hook
+@kindex hook-
+You may define @dfn{hooks}, which are a special kind of user-defined
+command. Whenever you run the command @samp{foo}, if the user-defined
+command @samp{hook-foo} exists, it is executed (with no arguments)
+before that command.
+
+@cindex hooks, post-command
+@kindex hookpost
+@kindex hookpost-
+A hook may also be defined which is run after the command you executed.
+Whenever you run the command @samp{foo}, if the user-defined command
+@samp{hookpost-foo} exists, it is executed (with no arguments) after
+that command. Post-execution hooks may exist simultaneously with
+pre-execution hooks, for the same command.
+
+It is valid for a hook to call the command which it hooks. If this
+occurs, the hook is not re-executed, thereby avoiding infinte recursion.
+
+@c It would be nice if hookpost could be passed a parameter indicating
+@c if the command it hooks executed properly or not. FIXME!
+
+@kindex stop@r{, a pseudo-command}
+In addition, a pseudo-command, @samp{stop} exists. Defining
+(@samp{hook-stop}) makes the associated commands execute every time
+execution stops in your program: before breakpoint commands are run,
+displays are printed, or the stack frame is printed.
+
+For example, to ignore @code{SIGALRM} signals while
+single-stepping, but treat them normally during normal execution,
+you could define:
+
+@smallexample
+define hook-stop
+handle SIGALRM nopass
+end
+
+define hook-run
+handle SIGALRM pass
+end
+
+define hook-continue
+handle SIGLARM pass
+end
+@end smallexample
+
+As a further example, to hook at the begining and end of the @code{echo}
+command, and to add extra text to the beginning and end of the message,
+you could define:
+
+@smallexample
+define hook-echo
+echo <<<---
+end
+
+define hookpost-echo
+echo --->>>\n
+end
+
+(@value{GDBP}) echo Hello World
+<<<---Hello World--->>>
+(@value{GDBP})
+
+@end smallexample
+
+You can define a hook for any single-word command in @value{GDBN}, but
+not for command aliases; you should define a hook for the basic command
+name, e.g. @code{backtrace} rather than @code{bt}.
+@c FIXME! So how does Joe User discover whether a command is an alias
+@c or not?
+If an error occurs during the execution of your hook, execution of
+@value{GDBN} commands stops and @value{GDBN} issues a prompt
+(before the command that you actually typed had a chance to run).
+
+If you try to define a hook which does not match any known command, you
+get a warning from the @code{define} command.
+
+@node Command Files
+@section Command files
+
+@cindex command files
+A command file for @value{GDBN} is a file of lines that are @value{GDBN}
+commands. Comments (lines starting with @kbd{#}) may also be included.
+An empty line in a command file does nothing; it does not mean to repeat
+the last command, as it would from the terminal.
+
+@cindex init file
+@cindex @file{.gdbinit}
+@cindex @file{gdb.ini}
+When you start @value{GDBN}, it automatically executes commands from its
+@dfn{init files}, normally called @file{.gdbinit}@footnote{The DJGPP
+port of @value{GDBN} uses the name @file{gdb.ini} instead, due to the
+limitations of file names imposed by DOS filesystems.}.
+During startup, @value{GDBN} does the following:
+
+@enumerate
+@item
+Reads the init file (if any) in your home directory@footnote{On
+DOS/Windows systems, the home directory is the one pointed to by the
+@code{HOME} environment variable.}.
+
+@item
+Processes command line options and operands.
+
+@item
+Reads the init file (if any) in the current working directory.
+
+@item
+Reads command files specified by the @samp{-x} option.
+@end enumerate
+
+The init file in your home directory can set options (such as @samp{set
+complaints}) that affect subsequent processing of command line options
+and operands. Init files are not executed if you use the @samp{-nx}
+option (@pxref{Mode Options, ,Choosing modes}).
+
+@cindex init file name
+On some configurations of @value{GDBN}, the init file is known by a
+different name (these are typically environments where a specialized
+form of @value{GDBN} may need to coexist with other forms, hence a
+different name for the specialized version's init file). These are the
+environments with special init file names:
+
+@cindex @file{.vxgdbinit}
+@itemize @bullet
+@item
+VxWorks (Wind River Systems real-time OS): @file{.vxgdbinit}
+
+@cindex @file{.os68gdbinit}
+@item
+OS68K (Enea Data Systems real-time OS): @file{.os68gdbinit}
+
+@cindex @file{.esgdbinit}
+@item
+ES-1800 (Ericsson Telecom AB M68000 emulator): @file{.esgdbinit}
+@end itemize
+
+You can also request the execution of a command file with the
+@code{source} command:
+
+@table @code
+@kindex source
+@item source @var{filename}
+Execute the command file @var{filename}.
+@end table
+
+The lines in a command file are executed sequentially. They are not
+printed as they are executed. An error in any command terminates execution
+of the command file.
+
+Commands that would ask for confirmation if used interactively proceed
+without asking when used in a command file. Many @value{GDBN} commands that
+normally print messages to say what they are doing omit the messages
+when called from command files.
+
+@value{GDBN} also accepts command input from standard input. In this
+mode, normal output goes to standard output and error output goes to
+standard error. Errors in a command file supplied on standard input do
+not terminate execution of the command file --- execution continues with
+the next command.
+
+@smallexample
+gdb < cmds > log 2>&1
+@end smallexample
+
+(The syntax above will vary depending on the shell used.) This example
+will execute commands from the file @file{cmds}. All output and errors
+would be directed to @file{log}.
+
+@node Output
+@section Commands for controlled output
+
+During the execution of a command file or a user-defined command, normal
+@value{GDBN} output is suppressed; the only output that appears is what is
+explicitly printed by the commands in the definition. This section
+describes three commands useful for generating exactly the output you
+want.
+
+@table @code
+@kindex echo
+@item echo @var{text}
+@c I do not consider backslash-space a standard C escape sequence
+@c because it is not in ANSI.
+Print @var{text}. Nonprinting characters can be included in
+@var{text} using C escape sequences, such as @samp{\n} to print a
+newline. @strong{No newline is printed unless you specify one.}
+In addition to the standard C escape sequences, a backslash followed
+by a space stands for a space. This is useful for displaying a
+string with spaces at the beginning or the end, since leading and
+trailing spaces are otherwise trimmed from all arguments.
+To print @samp{@w{ }and foo =@w{ }}, use the command
+@samp{echo \@w{ }and foo = \@w{ }}.
+
+A backslash at the end of @var{text} can be used, as in C, to continue
+the command onto subsequent lines. For example,
+
+@smallexample
+echo This is some text\n\
+which is continued\n\
+onto several lines.\n
+@end smallexample
+
+produces the same output as
+
+@smallexample
+echo This is some text\n
+echo which is continued\n
+echo onto several lines.\n
+@end smallexample
+
+@kindex output
+@item output @var{expression}
+Print the value of @var{expression} and nothing but that value: no
+newlines, no @samp{$@var{nn} = }. The value is not entered in the
+value history either. @xref{Expressions, ,Expressions}, for more information
+on expressions.
+
+@item output/@var{fmt} @var{expression}
+Print the value of @var{expression} in format @var{fmt}. You can use
+the same formats as for @code{print}. @xref{Output Formats,,Output
+formats}, for more information.
+
+@kindex printf
+@item printf @var{string}, @var{expressions}@dots{}
+Print the values of the @var{expressions} under the control of
+@var{string}. The @var{expressions} are separated by commas and may be
+either numbers or pointers. Their values are printed as specified by
+@var{string}, exactly as if your program were to execute the C
+subroutine
+@c FIXME: the above implies that at least all ANSI C formats are
+@c supported, but it isn't true: %E and %G don't work (or so it seems).
+@c Either this is a bug, or the manual should document what formats are
+@c supported.
+
+@smallexample
+printf (@var{string}, @var{expressions}@dots{});
+@end smallexample
+
+For example, you can print two values in hex like this:
+
+@smallexample
+printf "foo, bar-foo = 0x%x, 0x%x\n", foo, bar-foo
+@end smallexample
+
+The only backslash-escape sequences that you can use in the format
+string are the simple ones that consist of backslash followed by a
+letter.
+@end table
+
+@node TUI
+@chapter @value{GDBN} Text User Interface
+@cindex TUI
+
+@menu
+* TUI Overview:: TUI overview
+* TUI Keys:: TUI key bindings
+* TUI Commands:: TUI specific commands
+* TUI Configuration:: TUI configuration variables
+@end menu
+
+The @value{GDBN} Text User Interface, TUI in short,
+is a terminal interface which uses the @code{curses} library
+to show the source file, the assembly output, the program registers
+and @value{GDBN} commands in separate text windows.
+The TUI is available only when @value{GDBN} is configured
+with the @code{--enable-tui} configure option (@pxref{Configure Options}).
+
+@node TUI Overview
+@section TUI overview
+
+The TUI has two display modes that can be switched while
+@value{GDBN} runs:
+
+@itemize @bullet
+@item
+A curses (or TUI) mode in which it displays several text
+windows on the terminal.
+
+@item
+A standard mode which corresponds to the @value{GDBN} configured without
+the TUI.
+@end itemize
+
+In the TUI mode, @value{GDBN} can display several text window
+on the terminal:
+
+@table @emph
+@item command
+This window is the @value{GDBN} command window with the @value{GDBN}
+prompt and the @value{GDBN} outputs. The @value{GDBN} input is still
+managed using readline but through the TUI. The @emph{command}
+window is always visible.
+
+@item source
+The source window shows the source file of the program. The current
+line as well as active breakpoints are displayed in this window.
+The current program position is shown with the @samp{>} marker and
+active breakpoints are shown with @samp{*} markers.
+
+@item assembly
+The assembly window shows the disassembly output of the program.
+
+@item register
+This window shows the processor registers. It detects when
+a register is changed and when this is the case, registers that have
+changed are highlighted.
+
+@end table
+
+The source, assembly and register windows are attached to the thread
+and the frame position. They are updated when the current thread
+changes, when the frame changes or when the program counter changes.
+These three windows are arranged by the TUI according to several
+layouts. The layout defines which of these three windows are visible.
+The following layouts are available:
+
+@itemize @bullet
+@item
+source
+
+@item
+assembly
+
+@item
+source and assembly
+
+@item
+source and registers
+
+@item
+assembly and registers
+
+@end itemize
+
+@node TUI Keys
+@section TUI Key Bindings
+@cindex TUI key bindings
+
+The TUI installs several key bindings in the readline keymaps
+(@pxref{Command Line Editing}).
+They allow to leave or enter in the TUI mode or they operate
+directly on the TUI layout and windows. The following key bindings
+are installed for both TUI mode and the @value{GDBN} standard mode.
+
+@table @kbd
+@kindex C-x C-a
+@item C-x C-a
+@kindex C-x a
+@itemx C-x a
+@kindex C-x A
+@itemx C-x A
+Enter or leave the TUI mode. When the TUI mode is left,
+the curses window management is left and @value{GDBN} operates using
+its standard mode writing on the terminal directly. When the TUI
+mode is entered, the control is given back to the curses windows.
+The screen is then refreshed.
+
+@kindex C-x 1
+@item C-x 1
+Use a TUI layout with only one window. The layout will
+either be @samp{source} or @samp{assembly}. When the TUI mode
+is not active, it will switch to the TUI mode.
+
+Think of this key binding as the Emacs @kbd{C-x 1} binding.
+
+@kindex C-x 2
+@item C-x 2
+Use a TUI layout with at least two windows. When the current
+layout shows already two windows, a next layout with two windows is used.
+When a new layout is chosen, one window will always be common to the
+previous layout and the new one.
+
+Think of it as the Emacs @kbd{C-x 2} binding.
+
+@end table
+
+The following key bindings are handled only by the TUI mode:
+
+@table @key
+@kindex PgUp
+@item PgUp
+Scroll the active window one page up.
+
+@kindex PgDn
+@item PgDn
+Scroll the active window one page down.
+
+@kindex Up
+@item Up
+Scroll the active window one line up.
+
+@kindex Down
+@item Down
+Scroll the active window one line down.
+
+@kindex Left
+@item Left
+Scroll the active window one column left.
+
+@kindex Right
+@item Right
+Scroll the active window one column right.
+
+@kindex C-L
+@item C-L
+Refresh the screen.
+
+@end table
+
+In the TUI mode, the arrow keys are used by the active window
+for scrolling. This means they are not available for readline. It is
+necessary to use other readline key bindings such as @key{C-p}, @key{C-n},
+@key{C-b} and @key{C-f}.
+
+@node TUI Commands
+@section TUI specific commands
+@cindex TUI commands
+
+The TUI has specific commands to control the text windows.
+These commands are always available, that is they do not depend on
+the current terminal mode in which @value{GDBN} runs. When @value{GDBN}
+is in the standard mode, using these commands will automatically switch
+in the TUI mode.
+
+@table @code
+@item layout next
+@kindex layout next
+Display the next layout.
+
+@item layout prev
+@kindex layout prev
+Display the previous layout.
+
+@item layout src
+@kindex layout src
+Display the source window only.
+
+@item layout asm
+@kindex layout asm
+Display the assembly window only.
+
+@item layout split
+@kindex layout split
+Display the source and assembly window.
+
+@item layout regs
+@kindex layout regs
+Display the register window together with the source or assembly window.
+
+@item focus next | prev | src | asm | regs | split
+@kindex focus
+Set the focus to the named window.
+This command allows to change the active window so that scrolling keys
+can be affected to another window.
+
+@item refresh
+@kindex refresh
+Refresh the screen. This is similar to using @key{C-L} key.
+
+@item update
+@kindex update
+Update the source window and the current execution point.
+
+@item winheight @var{name} +@var{count}
+@itemx winheight @var{name} -@var{count}
+@kindex winheight
+Change the height of the window @var{name} by @var{count}
+lines. Positive counts increase the height, while negative counts
+decrease it.
+
+@end table
+
+@node TUI Configuration
+@section TUI configuration variables
+@cindex TUI configuration variables
+
+The TUI has several configuration variables that control the
+appearance of windows on the terminal.
+
+@table @code
+@item set tui border-kind @var{kind}
+@kindex set tui border-kind
+Select the border appearance for the source, assembly and register windows.
+The possible values are the following:
+@table @code
+@item space
+Use a space character to draw the border.
+
+@item ascii
+Use ascii characters + - and | to draw the border.
+
+@item acs
+Use the Alternate Character Set to draw the border. The border is
+drawn using character line graphics if the terminal supports them.
+
+@end table
+
+@item set tui active-border-mode @var{mode}
+@kindex set tui active-border-mode
+Select the attributes to display the border of the active window.
+The possible values are @code{normal}, @code{standout}, @code{reverse},
+@code{half}, @code{half-standout}, @code{bold} and @code{bold-standout}.
+
+@item set tui border-mode @var{mode}
+@kindex set tui border-mode
+Select the attributes to display the border of other windows.
+The @var{mode} can be one of the following:
+@table @code
+@item normal
+Use normal attributes to display the border.
+
+@item standout
+Use standout mode.
+
+@item reverse
+Use reverse video mode.
+
+@item half
+Use half bright mode.
+
+@item half-standout
+Use half bright and standout mode.
+
+@item bold
+Use extra bright or bold mode.
+
+@item bold-standout
+Use extra bright or bold and standout mode.
+
+@end table
+
+@end table
+
+@node Emacs
+@chapter Using @value{GDBN} under @sc{gnu} Emacs
+
+@cindex Emacs
+@cindex @sc{gnu} Emacs
+A special interface allows you to use @sc{gnu} Emacs to view (and
+edit) the source files for the program you are debugging with
+@value{GDBN}.
+
+To use this interface, use the command @kbd{M-x gdb} in Emacs. Give the
+executable file you want to debug as an argument. This command starts
+@value{GDBN} as a subprocess of Emacs, with input and output through a newly
+created Emacs buffer.
+@c (Do not use the @code{-tui} option to run @value{GDBN} from Emacs.)
+
+Using @value{GDBN} under Emacs is just like using @value{GDBN} normally except for two
+things:
+
+@itemize @bullet
+@item
+All ``terminal'' input and output goes through the Emacs buffer.
+@end itemize
+
+This applies both to @value{GDBN} commands and their output, and to the input
+and output done by the program you are debugging.
+
+This is useful because it means that you can copy the text of previous
+commands and input them again; you can even use parts of the output
+in this way.
+
+All the facilities of Emacs' Shell mode are available for interacting
+with your program. In particular, you can send signals the usual
+way---for example, @kbd{C-c C-c} for an interrupt, @kbd{C-c C-z} for a
+stop.
+
+@itemize @bullet
+@item
+@value{GDBN} displays source code through Emacs.
+@end itemize
+
+Each time @value{GDBN} displays a stack frame, Emacs automatically finds the
+source file for that frame and puts an arrow (@samp{=>}) at the
+left margin of the current line. Emacs uses a separate buffer for
+source display, and splits the screen to show both your @value{GDBN} session
+and the source.
+
+Explicit @value{GDBN} @code{list} or search commands still produce output as
+usual, but you probably have no reason to use them from Emacs.
+
+@quotation
+@emph{Warning:} If the directory where your program resides is not your
+current directory, it can be easy to confuse Emacs about the location of
+the source files, in which case the auxiliary display buffer does not
+appear to show your source. @value{GDBN} can find programs by searching your
+environment's @code{PATH} variable, so the @value{GDBN} input and output
+session proceeds normally; but Emacs does not get enough information
+back from @value{GDBN} to locate the source files in this situation. To
+avoid this problem, either start @value{GDBN} mode from the directory where
+your program resides, or specify an absolute file name when prompted for the
+@kbd{M-x gdb} argument.
+
+A similar confusion can result if you use the @value{GDBN} @code{file} command to
+switch to debugging a program in some other location, from an existing
+@value{GDBN} buffer in Emacs.
+@end quotation
+
+By default, @kbd{M-x gdb} calls the program called @file{gdb}. If
+you need to call @value{GDBN} by a different name (for example, if you keep
+several configurations around, with different names) you can set the
+Emacs variable @code{gdb-command-name}; for example,
+
+@smallexample
+(setq gdb-command-name "mygdb")
+@end smallexample
+
+@noindent
+(preceded by @kbd{M-:} or @kbd{ESC :}, or typed in the @code{*scratch*} buffer, or
+in your @file{.emacs} file) makes Emacs call the program named
+``@code{mygdb}'' instead.
+
+In the @value{GDBN} I/O buffer, you can use these special Emacs commands in
+addition to the standard Shell mode commands:
+
+@table @kbd
+@item C-h m
+Describe the features of Emacs' @value{GDBN} Mode.
+
+@item M-s
+Execute to another source line, like the @value{GDBN} @code{step} command; also
+update the display window to show the current file and location.
+
+@item M-n
+Execute to next source line in this function, skipping all function
+calls, like the @value{GDBN} @code{next} command. Then update the display window
+to show the current file and location.
+
+@item M-i
+Execute one instruction, like the @value{GDBN} @code{stepi} command; update
+display window accordingly.
+
+@item M-x gdb-nexti
+Execute to next instruction, using the @value{GDBN} @code{nexti} command; update
+display window accordingly.
+
+@item C-c C-f
+Execute until exit from the selected stack frame, like the @value{GDBN}
+@code{finish} command.
+
+@item M-c
+Continue execution of your program, like the @value{GDBN} @code{continue}
+command.
+
+@emph{Warning:} In Emacs v19, this command is @kbd{C-c C-p}.
+
+@item M-u
+Go up the number of frames indicated by the numeric argument
+(@pxref{Arguments, , Numeric Arguments, Emacs, The @sc{gnu} Emacs Manual}),
+like the @value{GDBN} @code{up} command.
+
+@emph{Warning:} In Emacs v19, this command is @kbd{C-c C-u}.
+
+@item M-d
+Go down the number of frames indicated by the numeric argument, like the
+@value{GDBN} @code{down} command.
+
+@emph{Warning:} In Emacs v19, this command is @kbd{C-c C-d}.
+
+@item C-x &
+Read the number where the cursor is positioned, and insert it at the end
+of the @value{GDBN} I/O buffer. For example, if you wish to disassemble code
+around an address that was displayed earlier, type @kbd{disassemble};
+then move the cursor to the address display, and pick up the
+argument for @code{disassemble} by typing @kbd{C-x &}.
+
+You can customize this further by defining elements of the list
+@code{gdb-print-command}; once it is defined, you can format or
+otherwise process numbers picked up by @kbd{C-x &} before they are
+inserted. A numeric argument to @kbd{C-x &} indicates that you
+wish special formatting, and also acts as an index to pick an element of the
+list. If the list element is a string, the number to be inserted is
+formatted using the Emacs function @code{format}; otherwise the number
+is passed as an argument to the corresponding list element.
+@end table
+
+In any source file, the Emacs command @kbd{C-x SPC} (@code{gdb-break})
+tells @value{GDBN} to set a breakpoint on the source line point is on.
+
+If you accidentally delete the source-display buffer, an easy way to get
+it back is to type the command @code{f} in the @value{GDBN} buffer, to
+request a frame display; when you run under Emacs, this recreates
+the source buffer if necessary to show you the context of the current
+frame.
+
+The source files displayed in Emacs are in ordinary Emacs buffers
+which are visiting the source files in the usual way. You can edit
+the files with these buffers if you wish; but keep in mind that @value{GDBN}
+communicates with Emacs in terms of line numbers. If you add or
+delete lines from the text, the line numbers that @value{GDBN} knows cease
+to correspond properly with the code.
+
+@c The following dropped because Epoch is nonstandard. Reactivate
+@c if/when v19 does something similar. ---doc@cygnus.com 19dec1990
+@ignore
+@kindex Emacs Epoch environment
+@kindex Epoch
+@kindex inspect
+
+Version 18 of @sc{gnu} Emacs has a built-in window system
+called the @code{epoch}
+environment. Users of this environment can use a new command,
+@code{inspect} which performs identically to @code{print} except that
+each value is printed in its own window.
+@end ignore
+
+@include annotate.texi
+@include gdbmi.texinfo
+
+@node GDB Bugs
+@chapter Reporting Bugs in @value{GDBN}
+@cindex bugs in @value{GDBN}
+@cindex reporting bugs in @value{GDBN}
+
+Your bug reports play an essential role in making @value{GDBN} reliable.
+
+Reporting a bug may help you by bringing a solution to your problem, or it
+may not. But in any case the principal function of a bug report is to help
+the entire community by making the next version of @value{GDBN} work better. Bug
+reports are your contribution to the maintenance of @value{GDBN}.
+
+In order for a bug report to serve its purpose, you must include the
+information that enables us to fix the bug.
+
+@menu
+* Bug Criteria:: Have you found a bug?
+* Bug Reporting:: How to report bugs
+@end menu
+
+@node Bug Criteria
+@section Have you found a bug?
+@cindex bug criteria
+
+If you are not sure whether you have found a bug, here are some guidelines:
+
+@itemize @bullet
+@cindex fatal signal
+@cindex debugger crash
+@cindex crash of debugger
+@item
+If the debugger gets a fatal signal, for any input whatever, that is a
+@value{GDBN} bug. Reliable debuggers never crash.
+
+@cindex error on valid input
+@item
+If @value{GDBN} produces an error message for valid input, that is a
+bug. (Note that if you're cross debugging, the problem may also be
+somewhere in the connection to the target.)
+
+@cindex invalid input
+@item
+If @value{GDBN} does not produce an error message for invalid input,
+that is a bug. However, you should note that your idea of
+``invalid input'' might be our idea of ``an extension'' or ``support
+for traditional practice''.
+
+@item
+If you are an experienced user of debugging tools, your suggestions
+for improvement of @value{GDBN} are welcome in any case.
+@end itemize
+
+@node Bug Reporting
+@section How to report bugs
+@cindex bug reports
+@cindex @value{GDBN} bugs, reporting
+
+A number of companies and individuals offer support for @sc{gnu} products.
+If you obtained @value{GDBN} from a support organization, we recommend you
+contact that organization first.
+
+You can find contact information for many support companies and
+individuals in the file @file{etc/SERVICE} in the @sc{gnu} Emacs
+distribution.
+@c should add a web page ref...
+
+In any event, we also recommend that you submit bug reports for
+@value{GDBN}. The prefered method is to submit them directly using
+@uref{http://www.gnu.org/software/gdb/bugs/, @value{GDBN}'s Bugs web
+page}. Alternatively, the @email{bug-gdb@@gnu.org, e-mail gateway} can
+be used.
+
+@strong{Do not send bug reports to @samp{info-gdb}, or to
+@samp{help-gdb}, or to any newsgroups.} Most users of @value{GDBN} do
+not want to receive bug reports. Those that do have arranged to receive
+@samp{bug-gdb}.
+
+The mailing list @samp{bug-gdb} has a newsgroup @samp{gnu.gdb.bug} which
+serves as a repeater. The mailing list and the newsgroup carry exactly
+the same messages. Often people think of posting bug reports to the
+newsgroup instead of mailing them. This appears to work, but it has one
+problem which can be crucial: a newsgroup posting often lacks a mail
+path back to the sender. Thus, if we need to ask for more information,
+we may be unable to reach you. For this reason, it is better to send
+bug reports to the mailing list.
+
+The fundamental principle of reporting bugs usefully is this:
+@strong{report all the facts}. If you are not sure whether to state a
+fact or leave it out, state it!
+
+Often people omit facts because they think they know what causes the
+problem and assume that some details do not matter. Thus, you might
+assume that the name of the variable you use in an example does not matter.
+Well, probably it does not, but one cannot be sure. Perhaps the bug is a
+stray memory reference which happens to fetch from the location where that
+name is stored in memory; perhaps, if the name were different, the contents
+of that location would fool the debugger into doing the right thing despite
+the bug. Play it safe and give a specific, complete example. That is the
+easiest thing for you to do, and the most helpful.
+
+Keep in mind that the purpose of a bug report is to enable us to fix the
+bug. It may be that the bug has been reported previously, but neither
+you nor we can know that unless your bug report is complete and
+self-contained.
+
+Sometimes people give a few sketchy facts and ask, ``Does this ring a
+bell?'' Those bug reports are useless, and we urge everyone to
+@emph{refuse to respond to them} except to chide the sender to report
+bugs properly.
+
+To enable us to fix the bug, you should include all these things:
+
+@itemize @bullet
+@item
+The version of @value{GDBN}. @value{GDBN} announces it if you start
+with no arguments; you can also print it at any time using @code{show
+version}.
+
+Without this, we will not know whether there is any point in looking for
+the bug in the current version of @value{GDBN}.
+
+@item
+The type of machine you are using, and the operating system name and
+version number.
+
+@item
+What compiler (and its version) was used to compile @value{GDBN}---e.g.
+``@value{GCC}--2.8.1''.
+
+@item
+What compiler (and its version) was used to compile the program you are
+debugging---e.g. ``@value{GCC}--2.8.1'', or ``HP92453-01 A.10.32.03 HP
+C Compiler''. For GCC, you can say @code{gcc --version} to get this
+information; for other compilers, see the documentation for those
+compilers.
+
+@item
+The command arguments you gave the compiler to compile your example and
+observe the bug. For example, did you use @samp{-O}? To guarantee
+you will not omit something important, list them all. A copy of the
+Makefile (or the output from make) is sufficient.
+
+If we were to try to guess the arguments, we would probably guess wrong
+and then we might not encounter the bug.
+
+@item
+A complete input script, and all necessary source files, that will
+reproduce the bug.
+
+@item
+A description of what behavior you observe that you believe is
+incorrect. For example, ``It gets a fatal signal.''
+
+Of course, if the bug is that @value{GDBN} gets a fatal signal, then we
+will certainly notice it. But if the bug is incorrect output, we might
+not notice unless it is glaringly wrong. You might as well not give us
+a chance to make a mistake.
+
+Even if the problem you experience is a fatal signal, you should still
+say so explicitly. Suppose something strange is going on, such as, your
+copy of @value{GDBN} is out of synch, or you have encountered a bug in
+the C library on your system. (This has happened!) Your copy might
+crash and ours would not. If you told us to expect a crash, then when
+ours fails to crash, we would know that the bug was not happening for
+us. If you had not told us to expect a crash, then we would not be able
+to draw any conclusion from our observations.
+
+@item
+If you wish to suggest changes to the @value{GDBN} source, send us context
+diffs. If you even discuss something in the @value{GDBN} source, refer to
+it by context, not by line number.
+
+The line numbers in our development sources will not match those in your
+sources. Your line numbers would convey no useful information to us.
+
+@end itemize
+
+Here are some things that are not necessary:
+
+@itemize @bullet
+@item
+A description of the envelope of the bug.
+
+Often people who encounter a bug spend a lot of time investigating
+which changes to the input file will make the bug go away and which
+changes will not affect it.
+
+This is often time consuming and not very useful, because the way we
+will find the bug is by running a single example under the debugger
+with breakpoints, not by pure deduction from a series of examples.
+We recommend that you save your time for something else.
+
+Of course, if you can find a simpler example to report @emph{instead}
+of the original one, that is a convenience for us. Errors in the
+output will be easier to spot, running under the debugger will take
+less time, and so on.
+
+However, simplification is not vital; if you do not want to do this,
+report the bug anyway and send us the entire test case you used.
+
+@item
+A patch for the bug.
+
+A patch for the bug does help us if it is a good one. But do not omit
+the necessary information, such as the test case, on the assumption that
+a patch is all we need. We might see problems with your patch and decide
+to fix the problem another way, or we might not understand it at all.
+
+Sometimes with a program as complicated as @value{GDBN} it is very hard to
+construct an example that will make the program follow a certain path
+through the code. If you do not send us the example, we will not be able
+to construct one, so we will not be able to verify that the bug is fixed.
+
+And if we cannot understand what bug you are trying to fix, or why your
+patch should be an improvement, we will not install it. A test case will
+help us to understand.
+
+@item
+A guess about what the bug is or what it depends on.
+
+Such guesses are usually wrong. Even we cannot guess right about such
+things without first using the debugger to find the facts.
+@end itemize
+
+@c The readline documentation is distributed with the readline code
+@c and consists of the two following files:
+@c rluser.texinfo
+@c inc-hist.texinfo
+@c Use -I with makeinfo to point to the appropriate directory,
+@c environment var TEXINPUTS with TeX.
+@include rluser.texinfo
+@include inc-hist.texinfo
+
+
+@node Formatting Documentation
+@appendix Formatting Documentation
+
+@cindex @value{GDBN} reference card
+@cindex reference card
+The @value{GDBN} 4 release includes an already-formatted reference card, ready
+for printing with PostScript or Ghostscript, in the @file{gdb}
+subdirectory of the main source directory@footnote{In
+@file{gdb-@value{GDBVN}/gdb/refcard.ps} of the version @value{GDBVN}
+release.}. If you can use PostScript or Ghostscript with your printer,
+you can print the reference card immediately with @file{refcard.ps}.
+
+The release also includes the source for the reference card. You
+can format it, using @TeX{}, by typing:
+
+@smallexample
+make refcard.dvi
+@end smallexample
+
+The @value{GDBN} reference card is designed to print in @dfn{landscape}
+mode on US ``letter'' size paper;
+that is, on a sheet 11 inches wide by 8.5 inches
+high. You will need to specify this form of printing as an option to
+your @sc{dvi} output program.
+
+@cindex documentation
+
+All the documentation for @value{GDBN} comes as part of the machine-readable
+distribution. The documentation is written in Texinfo format, which is
+a documentation system that uses a single source file to produce both
+on-line information and a printed manual. You can use one of the Info
+formatting commands to create the on-line version of the documentation
+and @TeX{} (or @code{texi2roff}) to typeset the printed version.
+
+@value{GDBN} includes an already formatted copy of the on-line Info
+version of this manual in the @file{gdb} subdirectory. The main Info
+file is @file{gdb-@value{GDBVN}/gdb/gdb.info}, and it refers to
+subordinate files matching @samp{gdb.info*} in the same directory. If
+necessary, you can print out these files, or read them with any editor;
+but they are easier to read using the @code{info} subsystem in @sc{gnu}
+Emacs or the standalone @code{info} program, available as part of the
+@sc{gnu} Texinfo distribution.
+
+If you want to format these Info files yourself, you need one of the
+Info formatting programs, such as @code{texinfo-format-buffer} or
+@code{makeinfo}.
+
+If you have @code{makeinfo} installed, and are in the top level
+@value{GDBN} source directory (@file{gdb-@value{GDBVN}}, in the case of
+version @value{GDBVN}), you can make the Info file by typing:
+
+@smallexample
+cd gdb
+make gdb.info
+@end smallexample
+
+If you want to typeset and print copies of this manual, you need @TeX{},
+a program to print its @sc{dvi} output files, and @file{texinfo.tex}, the
+Texinfo definitions file.
+
+@TeX{} is a typesetting program; it does not print files directly, but
+produces output files called @sc{dvi} files. To print a typeset
+document, you need a program to print @sc{dvi} files. If your system
+has @TeX{} installed, chances are it has such a program. The precise
+command to use depends on your system; @kbd{lpr -d} is common; another
+(for PostScript devices) is @kbd{dvips}. The @sc{dvi} print command may
+require a file name without any extension or a @samp{.dvi} extension.
+
+@TeX{} also requires a macro definitions file called
+@file{texinfo.tex}. This file tells @TeX{} how to typeset a document
+written in Texinfo format. On its own, @TeX{} cannot either read or
+typeset a Texinfo file. @file{texinfo.tex} is distributed with GDB
+and is located in the @file{gdb-@var{version-number}/texinfo}
+directory.
+
+If you have @TeX{} and a @sc{dvi} printer program installed, you can
+typeset and print this manual. First switch to the the @file{gdb}
+subdirectory of the main source directory (for example, to
+@file{gdb-@value{GDBVN}/gdb}) and type:
+
+@smallexample
+make gdb.dvi
+@end smallexample
+
+Then give @file{gdb.dvi} to your @sc{dvi} printing program.
+
+@node Installing GDB
+@appendix Installing @value{GDBN}
+@cindex configuring @value{GDBN}
+@cindex installation
+
+@value{GDBN} comes with a @code{configure} script that automates the process
+of preparing @value{GDBN} for installation; you can then use @code{make} to
+build the @code{gdb} program.
+@iftex
+@c irrelevant in info file; it's as current as the code it lives with.
+@footnote{If you have a more recent version of @value{GDBN} than @value{GDBVN},
+look at the @file{README} file in the sources; we may have improved the
+installation procedures since publishing this manual.}
+@end iftex
+
+The @value{GDBN} distribution includes all the source code you need for
+@value{GDBN} in a single directory, whose name is usually composed by
+appending the version number to @samp{gdb}.
+
+For example, the @value{GDBN} version @value{GDBVN} distribution is in the
+@file{gdb-@value{GDBVN}} directory. That directory contains:
+
+@table @code
+@item gdb-@value{GDBVN}/configure @r{(and supporting files)}
+script for configuring @value{GDBN} and all its supporting libraries
+
+@item gdb-@value{GDBVN}/gdb
+the source specific to @value{GDBN} itself
+
+@item gdb-@value{GDBVN}/bfd
+source for the Binary File Descriptor library
+
+@item gdb-@value{GDBVN}/include
+@sc{gnu} include files
+
+@item gdb-@value{GDBVN}/libiberty
+source for the @samp{-liberty} free software library
+
+@item gdb-@value{GDBVN}/opcodes
+source for the library of opcode tables and disassemblers
+
+@item gdb-@value{GDBVN}/readline
+source for the @sc{gnu} command-line interface
+
+@item gdb-@value{GDBVN}/glob
+source for the @sc{gnu} filename pattern-matching subroutine
+
+@item gdb-@value{GDBVN}/mmalloc
+source for the @sc{gnu} memory-mapped malloc package
+@end table
+
+The simplest way to configure and build @value{GDBN} is to run @code{configure}
+from the @file{gdb-@var{version-number}} source directory, which in
+this example is the @file{gdb-@value{GDBVN}} directory.
+
+First switch to the @file{gdb-@var{version-number}} source directory
+if you are not already in it; then run @code{configure}. Pass the
+identifier for the platform on which @value{GDBN} will run as an
+argument.
+
+For example:
+
+@smallexample
+cd gdb-@value{GDBVN}
+./configure @var{host}
+make
+@end smallexample
+
+@noindent
+where @var{host} is an identifier such as @samp{sun4} or
+@samp{decstation}, that identifies the platform where @value{GDBN} will run.
+(You can often leave off @var{host}; @code{configure} tries to guess the
+correct value by examining your system.)
+
+Running @samp{configure @var{host}} and then running @code{make} builds the
+@file{bfd}, @file{readline}, @file{mmalloc}, and @file{libiberty}
+libraries, then @code{gdb} itself. The configured source files, and the
+binaries, are left in the corresponding source directories.
+
+@need 750
+@code{configure} is a Bourne-shell (@code{/bin/sh}) script; if your
+system does not recognize this automatically when you run a different
+shell, you may need to run @code{sh} on it explicitly:
+
+@smallexample
+sh configure @var{host}
+@end smallexample
+
+If you run @code{configure} from a directory that contains source
+directories for multiple libraries or programs, such as the
+@file{gdb-@value{GDBVN}} source directory for version @value{GDBVN}, @code{configure}
+creates configuration files for every directory level underneath (unless
+you tell it not to, with the @samp{--norecursion} option).
+
+You can run the @code{configure} script from any of the
+subordinate directories in the @value{GDBN} distribution if you only want to
+configure that subdirectory, but be sure to specify a path to it.
+
+For example, with version @value{GDBVN}, type the following to configure only
+the @code{bfd} subdirectory:
+
+@smallexample
+@group
+cd gdb-@value{GDBVN}/bfd
+../configure @var{host}
+@end group
+@end smallexample
+
+You can install @code{@value{GDBP}} anywhere; it has no hardwired paths.
+However, you should make sure that the shell on your path (named by
+the @samp{SHELL} environment variable) is publicly readable. Remember
+that @value{GDBN} uses the shell to start your program---some systems refuse to
+let @value{GDBN} debug child processes whose programs are not readable.
+
+@menu
+* Separate Objdir:: Compiling @value{GDBN} in another directory
+* Config Names:: Specifying names for hosts and targets
+* Configure Options:: Summary of options for configure
+@end menu
+
+@node Separate Objdir
+@section Compiling @value{GDBN} in another directory
+
+If you want to run @value{GDBN} versions for several host or target machines,
+you need a different @code{gdb} compiled for each combination of
+host and target. @code{configure} is designed to make this easy by
+allowing you to generate each configuration in a separate subdirectory,
+rather than in the source directory. If your @code{make} program
+handles the @samp{VPATH} feature (@sc{gnu} @code{make} does), running
+@code{make} in each of these directories builds the @code{gdb}
+program specified there.
+
+To build @code{gdb} in a separate directory, run @code{configure}
+with the @samp{--srcdir} option to specify where to find the source.
+(You also need to specify a path to find @code{configure}
+itself from your working directory. If the path to @code{configure}
+would be the same as the argument to @samp{--srcdir}, you can leave out
+the @samp{--srcdir} option; it is assumed.)
+
+For example, with version @value{GDBVN}, you can build @value{GDBN} in a
+separate directory for a Sun 4 like this:
+
+@smallexample
+@group
+cd gdb-@value{GDBVN}
+mkdir ../gdb-sun4
+cd ../gdb-sun4
+../gdb-@value{GDBVN}/configure sun4
+make
+@end group
+@end smallexample
+
+When @code{configure} builds a configuration using a remote source
+directory, it creates a tree for the binaries with the same structure
+(and using the same names) as the tree under the source directory. In
+the example, you'd find the Sun 4 library @file{libiberty.a} in the
+directory @file{gdb-sun4/libiberty}, and @value{GDBN} itself in
+@file{gdb-sun4/gdb}.
+
+One popular reason to build several @value{GDBN} configurations in separate
+directories is to configure @value{GDBN} for cross-compiling (where
+@value{GDBN} runs on one machine---the @dfn{host}---while debugging
+programs that run on another machine---the @dfn{target}).
+You specify a cross-debugging target by
+giving the @samp{--target=@var{target}} option to @code{configure}.
+
+When you run @code{make} to build a program or library, you must run
+it in a configured directory---whatever directory you were in when you
+called @code{configure} (or one of its subdirectories).
+
+The @code{Makefile} that @code{configure} generates in each source
+directory also runs recursively. If you type @code{make} in a source
+directory such as @file{gdb-@value{GDBVN}} (or in a separate configured
+directory configured with @samp{--srcdir=@var{dirname}/gdb-@value{GDBVN}}), you
+will build all the required libraries, and then build GDB.
+
+When you have multiple hosts or targets configured in separate
+directories, you can run @code{make} on them in parallel (for example,
+if they are NFS-mounted on each of the hosts); they will not interfere
+with each other.
+
+@node Config Names
+@section Specifying names for hosts and targets
+
+The specifications used for hosts and targets in the @code{configure}
+script are based on a three-part naming scheme, but some short predefined
+aliases are also supported. The full naming scheme encodes three pieces
+of information in the following pattern:
+
+@smallexample
+@var{architecture}-@var{vendor}-@var{os}
+@end smallexample
+
+For example, you can use the alias @code{sun4} as a @var{host} argument,
+or as the value for @var{target} in a @code{--target=@var{target}}
+option. The equivalent full name is @samp{sparc-sun-sunos4}.
+
+The @code{configure} script accompanying @value{GDBN} does not provide
+any query facility to list all supported host and target names or
+aliases. @code{configure} calls the Bourne shell script
+@code{config.sub} to map abbreviations to full names; you can read the
+script, if you wish, or you can use it to test your guesses on
+abbreviations---for example:
+
+@smallexample
+% sh config.sub i386-linux
+i386-pc-linux-gnu
+% sh config.sub alpha-linux
+alpha-unknown-linux-gnu
+% sh config.sub hp9k700
+hppa1.1-hp-hpux
+% sh config.sub sun4
+sparc-sun-sunos4.1.1
+% sh config.sub sun3
+m68k-sun-sunos4.1.1
+% sh config.sub i986v
+Invalid configuration `i986v': machine `i986v' not recognized
+@end smallexample
+
+@noindent
+@code{config.sub} is also distributed in the @value{GDBN} source
+directory (@file{gdb-@value{GDBVN}}, for version @value{GDBVN}).
+
+@node Configure Options
+@section @code{configure} options
+
+Here is a summary of the @code{configure} options and arguments that
+are most often useful for building @value{GDBN}. @code{configure} also has
+several other options not listed here. @inforef{What Configure
+Does,,configure.info}, for a full explanation of @code{configure}.
+
+@smallexample
+configure @r{[}--help@r{]}
+ @r{[}--prefix=@var{dir}@r{]}
+ @r{[}--exec-prefix=@var{dir}@r{]}
+ @r{[}--srcdir=@var{dirname}@r{]}
+ @r{[}--norecursion@r{]} @r{[}--rm@r{]}
+ @r{[}--target=@var{target}@r{]}
+ @var{host}
+@end smallexample
+
+@noindent
+You may introduce options with a single @samp{-} rather than
+@samp{--} if you prefer; but you may abbreviate option names if you use
+@samp{--}.
+
+@table @code
+@item --help
+Display a quick summary of how to invoke @code{configure}.
+
+@item --prefix=@var{dir}
+Configure the source to install programs and files under directory
+@file{@var{dir}}.
+
+@item --exec-prefix=@var{dir}
+Configure the source to install programs under directory
+@file{@var{dir}}.
+
+@c avoid splitting the warning from the explanation:
+@need 2000
+@item --srcdir=@var{dirname}
+@strong{Warning: using this option requires @sc{gnu} @code{make}, or another
+@code{make} that implements the @code{VPATH} feature.}@*
+Use this option to make configurations in directories separate from the
+@value{GDBN} source directories. Among other things, you can use this to
+build (or maintain) several configurations simultaneously, in separate
+directories. @code{configure} writes configuration specific files in
+the current directory, but arranges for them to use the source in the
+directory @var{dirname}. @code{configure} creates directories under
+the working directory in parallel to the source directories below
+@var{dirname}.
+
+@item --norecursion
+Configure only the directory level where @code{configure} is executed; do not
+propagate configuration to subdirectories.
+
+@item --target=@var{target}
+Configure @value{GDBN} for cross-debugging programs running on the specified
+@var{target}. Without this option, @value{GDBN} is configured to debug
+programs that run on the same machine (@var{host}) as @value{GDBN} itself.
+
+There is no convenient way to generate a list of all available targets.
+
+@item @var{host} @dots{}
+Configure @value{GDBN} to run on the specified @var{host}.
+
+There is no convenient way to generate a list of all available hosts.
+@end table
+
+There are many other options available as well, but they are generally
+needed for special purposes only.
+
+@node Maintenance Commands
+@appendix Maintenance Commands
+@cindex maintenance commands
+@cindex internal commands
+
+In addition to commands intended for @value{GDBN} users, @value{GDBN}
+includes a number of commands intended for @value{GDBN} developers.
+These commands are provided here for reference.
+
+@table @code
+@kindex maint info breakpoints
+@item @anchor{maint info breakpoints}maint info breakpoints
+Using the same format as @samp{info breakpoints}, display both the
+breakpoints you've set explicitly, and those @value{GDBN} is using for
+internal purposes. Internal breakpoints are shown with negative
+breakpoint numbers. The type column identifies what kind of breakpoint
+is shown:
+
+@table @code
+@item breakpoint
+Normal, explicitly set breakpoint.
+
+@item watchpoint
+Normal, explicitly set watchpoint.
+
+@item longjmp
+Internal breakpoint, used to handle correctly stepping through
+@code{longjmp} calls.
+
+@item longjmp resume
+Internal breakpoint at the target of a @code{longjmp}.
+
+@item until
+Temporary internal breakpoint used by the @value{GDBN} @code{until} command.
+
+@item finish
+Temporary internal breakpoint used by the @value{GDBN} @code{finish} command.
+
+@item shlib events
+Shared library events.
+
+@end table
+
+@end table
+
+
+@node Remote Protocol
+@appendix @value{GDBN} Remote Serial Protocol
+
+There may be occasions when you need to know something about the
+protocol---for example, if there is only one serial port to your target
+machine, you might want your program to do something special if it
+recognizes a packet meant for @value{GDBN}.
+
+In the examples below, @samp{<-} and @samp{->} are used to indicate
+transmitted and received data respectfully.
+
+@cindex protocol, @value{GDBN} remote serial
+@cindex serial protocol, @value{GDBN} remote
+@cindex remote serial protocol
+All @value{GDBN} commands and responses (other than acknowledgments) are
+sent as a @var{packet}. A @var{packet} is introduced with the character
+@samp{$}, the actual @var{packet-data}, and the terminating character
+@samp{#} followed by a two-digit @var{checksum}:
+
+@smallexample
+@code{$}@var{packet-data}@code{#}@var{checksum}
+@end smallexample
+@noindent
+
+@cindex checksum, for @value{GDBN} remote
+@noindent
+The two-digit @var{checksum} is computed as the modulo 256 sum of all
+characters between the leading @samp{$} and the trailing @samp{#} (an
+eight bit unsigned checksum).
+
+Implementors should note that prior to @value{GDBN} 5.0 the protocol
+specification also included an optional two-digit @var{sequence-id}:
+
+@smallexample
+@code{$}@var{sequence-id}@code{:}@var{packet-data}@code{#}@var{checksum}
+@end smallexample
+
+@cindex sequence-id, for @value{GDBN} remote
+@noindent
+That @var{sequence-id} was appended to the acknowledgment. @value{GDBN}
+has never output @var{sequence-id}s. Stubs that handle packets added
+since @value{GDBN} 5.0 must not accept @var{sequence-id}.
+
+@cindex acknowledgment, for @value{GDBN} remote
+When either the host or the target machine receives a packet, the first
+response expected is an acknowledgment: either @samp{+} (to indicate
+the package was received correctly) or @samp{-} (to request
+retransmission):
+
+@smallexample
+<- @code{$}@var{packet-data}@code{#}@var{checksum}
+-> @code{+}
+@end smallexample
+@noindent
+
+The host (@value{GDBN}) sends @var{command}s, and the target (the
+debugging stub incorporated in your program) sends a @var{response}. In
+the case of step and continue @var{command}s, the response is only sent
+when the operation has completed (the target has again stopped).
+
+@var{packet-data} consists of a sequence of characters with the
+exception of @samp{#} and @samp{$} (see @samp{X} packet for additional
+exceptions).
+
+Fields within the packet should be separated using @samp{,} @samp{;} or
+@samp{:}. Except where otherwise noted all numbers are represented in
+HEX with leading zeros suppressed.
+
+Implementors should note that prior to @value{GDBN} 5.0, the character
+@samp{:} could not appear as the third character in a packet (as it
+would potentially conflict with the @var{sequence-id}).
+
+Response @var{data} can be run-length encoded to save space. A @samp{*}
+means that the next character is an @sc{ascii} encoding giving a repeat count
+which stands for that many repetitions of the character preceding the
+@samp{*}. The encoding is @code{n+29}, yielding a printable character
+where @code{n >=3} (which is where rle starts to win). The printable
+characters @samp{$}, @samp{#}, @samp{+} and @samp{-} or with a numeric
+value greater than 126 should not be used.
+
+Some remote systems have used a different run-length encoding mechanism
+loosely refered to as the cisco encoding. Following the @samp{*}
+character are two hex digits that indicate the size of the packet.
+
+So:
+@smallexample
+"@code{0* }"
+@end smallexample
+@noindent
+means the same as "0000".
+
+The error response returned for some packets includes a two character
+error number. That number is not well defined.
+
+For any @var{command} not supported by the stub, an empty response
+(@samp{$#00}) should be returned. That way it is possible to extend the
+protocol. A newer @value{GDBN} can tell if a packet is supported based
+on that response.
+
+A stub is required to support the @samp{g}, @samp{G}, @samp{m}, @samp{M},
+@samp{c}, and @samp{s} @var{command}s. All other @var{command}s are
+optional.
+
+Below is a complete list of all currently defined @var{command}s and
+their corresponding response @var{data}:
+@page
+@multitable @columnfractions .30 .30 .40
+@item Packet
+@tab Request
+@tab Description
+
+@item extended mode
+@tab @code{!}
+@tab
+Enable extended mode. In extended mode, the remote server is made
+persistent. The @samp{R} packet is used to restart the program being
+debugged.
+@item
+@tab reply @samp{OK}
+@tab
+The remote target both supports and has enabled extended mode.
+
+@item last signal
+@tab @code{?}
+@tab
+Indicate the reason the target halted. The reply is the same as for step
+and continue.
+@item
+@tab reply
+@tab see below
+
+
+@item reserved
+@tab @code{a}
+@tab Reserved for future use
+
+@item set program arguments @strong{(reserved)}
+@tab @code{A}@var{arglen}@code{,}@var{argnum}@code{,}@var{arg}@code{,...}
+@tab
+@item
+@tab
+@tab
+Initialized @samp{argv[]} array passed into program. @var{arglen}
+specifies the number of bytes in the hex encoded byte stream @var{arg}.
+See @file{gdbserver} for more details.
+@item
+@tab reply @code{OK}
+@item
+@tab reply @code{E}@var{NN}
+
+@item set baud @strong{(deprecated)}
+@tab @code{b}@var{baud}
+@tab
+Change the serial line speed to @var{baud}. JTC: @emph{When does the
+transport layer state change? When it's received, or after the ACK is
+transmitted. In either case, there are problems if the command or the
+acknowledgment packet is dropped.} Stan: @emph{If people really wanted
+to add something like this, and get it working for the first time, they
+ought to modify ser-unix.c to send some kind of out-of-band message to a
+specially-setup stub and have the switch happen "in between" packets, so
+that from remote protocol's point of view, nothing actually
+happened.}
+
+@item set breakpoint @strong{(deprecated)}
+@tab @code{B}@var{addr},@var{mode}
+@tab
+Set (@var{mode} is @samp{S}) or clear (@var{mode} is @samp{C}) a
+breakpoint at @var{addr}. @emph{This has been replaced by the @samp{Z} and
+@samp{z} packets.}
+
+@item continue
+@tab @code{c}@var{addr}
+@tab
+@var{addr} is address to resume. If @var{addr} is omitted, resume at
+current address.
+@item
+@tab reply
+@tab see below
+
+@item continue with signal
+@tab @code{C}@var{sig}@code{;}@var{addr}
+@tab
+Continue with signal @var{sig} (hex signal number). If
+@code{;}@var{addr} is omitted, resume at same address.
+@item
+@tab reply
+@tab see below
+
+@item toggle debug @strong{(deprecated)}
+@tab @code{d}
+@tab
+toggle debug flag.
+
+@item detach
+@tab @code{D}
+@tab
+Detach @value{GDBN} from the remote system. Sent to the remote target before
+@value{GDBN} disconnects.
+@item
+@tab reply @emph{no response}
+@tab
+@value{GDBN} does not check for any response after sending this packet.
+
+@item reserved
+@tab @code{e}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{E}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{f}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{F}
+@tab Reserved for future use
+
+@item read registers
+@tab @code{g}
+@tab Read general registers.
+@item
+@tab reply @var{XX...}
+@tab
+Each byte of register data is described by two hex digits. The bytes
+with the register are transmitted in target byte order. The size of
+each register and their position within the @samp{g} @var{packet} are
+determined by the @value{GDBN} internal macros @var{REGISTER_RAW_SIZE} and
+@var{REGISTER_NAME} macros. The specification of several standard
+@code{g} packets is specified below.
+@item
+@tab @code{E}@var{NN}
+@tab for an error.
+
+@item write regs
+@tab @code{G}@var{XX...}
+@tab
+See @samp{g} for a description of the @var{XX...} data.
+@item
+@tab reply @code{OK}
+@tab for success
+@item
+@tab reply @code{E}@var{NN}
+@tab for an error
+
+@item reserved
+@tab @code{h}
+@tab Reserved for future use
+
+@item set thread
+@tab @code{H}@var{c}@var{t...}
+@tab
+Set thread for subsequent operations (@samp{m}, @samp{M}, @samp{g},
+@samp{G}, et.al.). @var{c} = @samp{c} for thread used in step and
+continue; @var{t...} can be -1 for all threads. @var{c} = @samp{g} for
+thread used in other operations. If zero, pick a thread, any thread.
+@item
+@tab reply @code{OK}
+@tab for success
+@item
+@tab reply @code{E}@var{NN}
+@tab for an error
+
+@c FIXME: JTC:
+@c 'H': How restrictive (or permissive) is the thread model. If a
+@c thread is selected and stopped, are other threads allowed
+@c to continue to execute? As I mentioned above, I think the
+@c semantics of each command when a thread is selected must be
+@c described. For example:
+@c
+@c 'g': If the stub supports threads and a specific thread is
+@c selected, returns the register block from that thread;
+@c otherwise returns current registers.
+@c
+@c 'G' If the stub supports threads and a specific thread is
+@c selected, sets the registers of the register block of
+@c that thread; otherwise sets current registers.
+
+@item cycle step @strong{(draft)}
+@tab @code{i}@var{addr}@code{,}@var{nnn}
+@tab
+Step the remote target by a single clock cycle. If @code{,}@var{nnn} is
+present, cycle step @var{nnn} cycles. If @var{addr} is present, cycle
+step starting at that address.
+
+@item signal then cycle step @strong{(reserved)}
+@tab @code{I}
+@tab
+See @samp{i} and @samp{S} for likely syntax and semantics.
+
+@item reserved
+@tab @code{j}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{J}
+@tab Reserved for future use
+
+@item kill request
+@tab @code{k}
+@tab
+FIXME: @emph{There is no description of how to operate when a specific
+thread context has been selected (i.e.@: does 'k' kill only that thread?)}.
+
+@item reserved
+@tab @code{l}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{L}
+@tab Reserved for future use
+
+@item read memory
+@tab @code{m}@var{addr}@code{,}@var{length}
+@tab
+Read @var{length} bytes of memory starting at address @var{addr}.
+Neither @value{GDBN} nor the stub assume that sized memory transfers are assumed
+using word alligned accesses. FIXME: @emph{A word aligned memory
+transfer mechanism is needed.}
+@item
+@tab reply @var{XX...}
+@tab
+@var{XX...} is mem contents. Can be fewer bytes than requested if able
+to read only part of the data. Neither @value{GDBN} nor the stub assume that
+sized memory transfers are assumed using word alligned accesses. FIXME:
+@emph{A word aligned memory transfer mechanism is needed.}
+@item
+@tab reply @code{E}@var{NN}
+@tab @var{NN} is errno
+
+@item write mem
+@tab @code{M}@var{addr},@var{length}@code{:}@var{XX...}
+@tab
+Write @var{length} bytes of memory starting at address @var{addr}.
+@var{XX...} is the data.
+@item
+@tab reply @code{OK}
+@tab for success
+@item
+@tab reply @code{E}@var{NN}
+@tab
+for an error (this includes the case where only part of the data was
+written).
+
+@item reserved
+@tab @code{n}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{N}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{o}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{O}
+@tab Reserved for future use
+
+@item read reg @strong{(reserved)}
+@tab @code{p}@var{n...}
+@tab
+See write register.
+@item
+@tab return @var{r....}
+@tab The hex encoded value of the register in target byte order.
+
+@item write reg
+@tab @code{P}@var{n...}@code{=}@var{r...}
+@tab
+Write register @var{n...} with value @var{r...}, which contains two hex
+digits for each byte in the register (target byte order).
+@item
+@tab reply @code{OK}
+@tab for success
+@item
+@tab reply @code{E}@var{NN}
+@tab for an error
+
+@item general query
+@tab @code{q}@var{query}
+@tab
+Request info about @var{query}. In general @value{GDBN} queries
+have a leading upper case letter. Custom vendor queries should use a
+company prefix (in lower case) ex: @samp{qfsf.var}. @var{query} may
+optionally be followed by a @samp{,} or @samp{;} separated list. Stubs
+must ensure that they match the full @var{query} name.
+@item
+@tab reply @code{XX...}
+@tab Hex encoded data from query. The reply can not be empty.
+@item
+@tab reply @code{E}@var{NN}
+@tab error reply
+@item
+@tab reply @samp{}
+@tab Indicating an unrecognized @var{query}.
+
+@item general set
+@tab @code{Q}@var{var}@code{=}@var{val}
+@tab
+Set value of @var{var} to @var{val}. See @samp{q} for a discussing of
+naming conventions.
+
+@item reset @strong{(deprecated)}
+@tab @code{r}
+@tab
+Reset the entire system.
+
+@item remote restart
+@tab @code{R}@var{XX}
+@tab
+Restart the program being debugged. @var{XX}, while needed, is ignored.
+This packet is only available in extended mode.
+@item
+@tab
+no reply
+@tab
+The @samp{R} packet has no reply.
+
+@item step
+@tab @code{s}@var{addr}
+@tab
+@var{addr} is address to resume. If @var{addr} is omitted, resume at
+same address.
+@item
+@tab reply
+@tab see below
+
+@item step with signal
+@tab @code{S}@var{sig}@code{;}@var{addr}
+@tab
+Like @samp{C} but step not continue.
+@item
+@tab reply
+@tab see below
+
+@item search
+@tab @code{t}@var{addr}@code{:}@var{PP}@code{,}@var{MM}
+@tab
+Search backwards starting at address @var{addr} for a match with pattern
+@var{PP} and mask @var{MM}. @var{PP} and @var{MM} are 4
+bytes. @var{addr} must be at least 3 digits.
+
+@item thread alive
+@tab @code{T}@var{XX}
+@tab Find out if the thread XX is alive.
+@item
+@tab reply @code{OK}
+@tab thread is still alive
+@item
+@tab reply @code{E}@var{NN}
+@tab thread is dead
+
+@item reserved
+@tab @code{u}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{U}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{v}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{V}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{w}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{W}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{x}
+@tab Reserved for future use
+
+@item write mem (binary)
+@tab @code{X}@var{addr}@code{,}@var{length}@var{:}@var{XX...}
+@tab
+@var{addr} is address, @var{length} is number of bytes, @var{XX...} is
+binary data. The characters @code{$}, @code{#}, and @code{0x7d} are
+escaped using @code{0x7d}.
+@item
+@tab reply @code{OK}
+@tab for success
+@item
+@tab reply @code{E}@var{NN}
+@tab for an error
+
+@item reserved
+@tab @code{y}
+@tab Reserved for future use
+
+@item reserved
+@tab @code{Y}
+@tab Reserved for future use
+
+@item remove break or watchpoint @strong{(draft)}
+@tab @code{z}@var{t}@code{,}@var{addr}@code{,}@var{length}
+@tab
+See @samp{Z}.
+
+@item insert break or watchpoint @strong{(draft)}
+@tab @code{Z}@var{t}@code{,}@var{addr}@code{,}@var{length}
+@tab
+@var{t} is type: @samp{0} - software breakpoint, @samp{1} - hardware
+breakpoint, @samp{2} - write watchpoint, @samp{3} - read watchpoint,
+@samp{4} - access watchpoint; @var{addr} is address; @var{length} is in
+bytes. For a software breakpoint, @var{length} specifies the size of
+the instruction to be patched. For hardware breakpoints and watchpoints
+@var{length} specifies the memory region to be monitored. To avoid
+potential problems with duplicate packets, the operations should be
+implemented in an idempotent way.
+@item
+@tab reply @code{E}@var{NN}
+@tab for an error
+@item
+@tab reply @code{OK}
+@tab for success
+@item
+@tab @samp{}
+@tab If not supported.
+
+@item reserved
+@tab <other>
+@tab Reserved for future use
+
+@end multitable
+
+The @samp{C}, @samp{c}, @samp{S}, @samp{s} and @samp{?} packets can
+receive any of the below as a reply. In the case of the @samp{C},
+@samp{c}, @samp{S} and @samp{s} packets, that reply is only returned
+when the target halts. In the below the exact meaning of @samp{signal
+number} is poorly defined. In general one of the UNIX signal numbering
+conventions is used.
+
+@multitable @columnfractions .4 .6
+
+@item @code{S}@var{AA}
+@tab @var{AA} is the signal number
+
+@item @code{T}@var{AA}@var{n...}@code{:}@var{r...}@code{;}@var{n...}@code{:}@var{r...}@code{;}@var{n...}@code{:}@var{r...}@code{;}
+@tab
+@var{AA} = two hex digit signal number; @var{n...} = register number
+(hex), @var{r...} = target byte ordered register contents, size defined
+by @code{REGISTER_RAW_SIZE}; @var{n...} = @samp{thread}, @var{r...} =
+thread process ID, this is a hex integer; @var{n...} = other string not
+starting with valid hex digit. @value{GDBN} should ignore this
+@var{n...}, @var{r...} pair and go on to the next. This way we can
+extend the protocol.
+
+@item @code{W}@var{AA}
+@tab
+The process exited, and @var{AA} is the exit status. This is only
+applicable for certains sorts of targets.
+
+@item @code{X}@var{AA}
+@tab
+The process terminated with signal @var{AA}.
+
+@item @code{N}@var{AA}@code{;}@var{t...}@code{;}@var{d...}@code{;}@var{b...} @strong{(obsolete)}
+@tab
+@var{AA} = signal number; @var{t...} = address of symbol "_start";
+@var{d...} = base of data section; @var{b...} = base of bss section.
+@emph{Note: only used by Cisco Systems targets. The difference between
+this reply and the "qOffsets" query is that the 'N' packet may arrive
+spontaneously whereas the 'qOffsets' is a query initiated by the host
+debugger.}
+
+@item @code{O}@var{XX...}
+@tab
+@var{XX...} is hex encoding of @sc{ascii} data. This can happen at any time
+while the program is running and the debugger should continue to wait
+for 'W', 'T', etc.
+
+@end multitable
+
+The following set and query packets have already been defined.
+
+@multitable @columnfractions .2 .2 .6
+
+@item current thread
+@tab @code{q}@code{C}
+@tab Return the current thread id.
+@item
+@tab reply @code{QC}@var{pid}
+@tab
+Where @var{pid} is a HEX encoded 16 bit process id.
+@item
+@tab reply *
+@tab Any other reply implies the old pid.
+
+@item all thread ids
+@tab @code{q}@code{fThreadInfo}
+@item
+@tab @code{q}@code{sThreadInfo}
+@tab
+Obtain a list of active thread ids from the target (OS). Since there
+may be too many active threads to fit into one reply packet, this query
+works iteratively: it may require more than one query/reply sequence to
+obtain the entire list of threads. The first query of the sequence will
+be the @code{qf}@code{ThreadInfo} query; subsequent queries in the
+sequence will be the @code{qs}@code{ThreadInfo} query.
+@item
+@tab
+@tab NOTE: replaces the @code{qL} query (see below).
+@item
+@tab reply @code{m}@var{<id>}
+@tab A single thread id
+@item
+@tab reply @code{m}@var{<id>},@var{<id>...}
+@tab a comma-separated list of thread ids
+@item
+@tab reply @code{l}
+@tab (lower case 'el') denotes end of list.
+@item
+@tab
+@tab
+In response to each query, the target will reply with a list of one
+or more thread ids, in big-endian hex, separated by commas. GDB will
+respond to each reply with a request for more thread ids (using the
+@code{qs} form of the query), until the target responds with @code{l}
+(lower-case el, for @code{'last'}).
+
+@item extra thread info
+@tab @code{q}@code{ThreadExtraInfo}@code{,}@var{id}
+@tab
+@item
+@tab
+@tab
+Where @var{<id>} is a thread-id in big-endian hex.
+Obtain a printable string description of a thread's attributes from
+the target OS. This string may contain anything that the target OS
+thinks is interesting for @value{GDBN} to tell the user about the thread.
+The string is displayed in @value{GDBN}'s @samp{info threads} display.
+Some examples of possible thread extra info strings are "Runnable", or
+"Blocked on Mutex".
+@item
+@tab reply @var{XX...}
+@tab
+Where @var{XX...} is a hex encoding of @sc{ascii} data, comprising the
+printable string containing the extra information about the thread's
+attributes.
+
+@item query @var{LIST} or @var{threadLIST} @strong{(deprecated)}
+@tab @code{q}@code{L}@var{startflag}@var{threadcount}@var{nextthread}
+@tab
+@item
+@tab
+@tab
+Obtain thread information from RTOS. Where: @var{startflag} (one hex
+digit) is one to indicate the first query and zero to indicate a
+subsequent query; @var{threadcount} (two hex digits) is the maximum
+number of threads the response packet can contain; and @var{nextthread}
+(eight hex digits), for subsequent queries (@var{startflag} is zero), is
+returned in the response as @var{argthread}.
+@item
+@tab
+@tab NOTE: this query is replaced by the @code{q}@code{fThreadInfo}
+query (see above).
+@item
+@tab reply @code{q}@code{M}@var{count}@var{done}@var{argthread}@var{thread...}
+@tab
+@item
+@tab
+@tab
+Where: @var{count} (two hex digits) is the number of threads being
+returned; @var{done} (one hex digit) is zero to indicate more threads
+and one indicates no further threads; @var{argthreadid} (eight hex
+digits) is @var{nextthread} from the request packet; @var{thread...} is
+a sequence of thread IDs from the target. @var{threadid} (eight hex
+digits). See @code{remote.c:parse_threadlist_response()}.
+
+@item compute CRC of memory block
+@tab @code{q}@code{CRC:}@var{addr}@code{,}@var{length}
+@tab
+@item
+@tab reply @code{E}@var{NN}
+@tab An error (such as memory fault)
+@item
+@tab reply @code{C}@var{CRC32}
+@tab A 32 bit cyclic redundancy check of the specified memory region.
+
+@item query sect offs
+@tab @code{q}@code{Offsets}
+@tab
+Get section offsets that the target used when re-locating the downloaded
+image. @emph{Note: while a @code{Bss} offset is included in the
+response, @value{GDBN} ignores this and instead applies the @code{Data}
+offset to the @code{Bss} section.}
+@item
+@tab reply @code{Text=}@var{xxx}@code{;Data=}@var{yyy}@code{;Bss=}@var{zzz}
+
+@item thread info request
+@tab @code{q}@code{P}@var{mode}@var{threadid}
+@tab
+@item
+@tab
+@tab
+Returns information on @var{threadid}. Where: @var{mode} is a hex
+encoded 32 bit mode; @var{threadid} is a hex encoded 64 bit thread ID.
+@item
+@tab reply *
+@tab
+See @code{remote.c:remote_unpack_thread_info_response()}.
+
+@item remote command
+@tab @code{q}@code{Rcmd,}@var{COMMAND}
+@tab
+@item
+@tab
+@tab
+@var{COMMAND} (hex encoded) is passed to the local interpreter for
+execution. Invalid commands should be reported using the output string.
+Before the final result packet, the target may also respond with a
+number of intermediate @code{O}@var{OUTPUT} console output
+packets. @emph{Implementors should note that providing access to a
+stubs's interpreter may have security implications}.
+@item
+@tab reply @code{OK}
+@tab
+A command response with no output.
+@item
+@tab reply @var{OUTPUT}
+@tab
+A command response with the hex encoded output string @var{OUTPUT}.
+@item
+@tab reply @code{E}@var{NN}
+@tab
+Indicate a badly formed request.
+
+@item
+@tab reply @samp{}
+@tab
+When @samp{q}@samp{Rcmd} is not recognized.
+
+@item symbol lookup
+@tab @code{qSymbol::}
+@tab
+Notify the target that @value{GDBN} is prepared to serve symbol lookup
+requests. Accept requests from the target for the values of symbols.
+@item
+@tab
+@tab
+@item
+@tab reply @code{OK}
+@tab
+The target does not need to look up any (more) symbols.
+@item
+@tab reply @code{qSymbol:}@var{sym_name}
+@tab
+@sp 2
+@noindent
+The target requests the value of symbol @var{sym_name} (hex encoded).
+@value{GDBN} may provide the value by using the
+@code{qSymbol:}@var{sym_value}:@var{sym_name}
+message, described below.
+
+@item symbol value
+@tab @code{qSymbol:}@var{sym_value}:@var{sym_name}
+@tab
+@sp 1
+@noindent
+Set the value of SYM_NAME to SYM_VALUE.
+@item
+@tab
+@tab
+@var{sym_name} (hex encoded) is the name of a symbol whose value
+the target has previously requested.
+@item
+@tab
+@tab
+@var{sym_value} (hex) is the value for symbol @var{sym_name}.
+If @value{GDBN} cannot supply a value for @var{sym_name}, then this
+field will be empty.
+@item
+@tab reply @code{OK}
+@tab
+The target does not need to look up any (more) symbols.
+@item
+@tab reply @code{qSymbol:}@var{sym_name}
+@tab
+@sp 2
+@noindent
+The target requests the value of a new symbol @var{sym_name} (hex encoded).
+@value{GDBN} will continue to supply the values of symbols (if available),
+until the target ceases to request them.
+
+@end multitable
+
+The following @samp{g}/@samp{G} packets have previously been defined.
+In the below, some thirty-two bit registers are transferred as sixty-four
+bits. Those registers should be zero/sign extended (which?) to fill the
+space allocated. Register bytes are transfered in target byte order.
+The two nibbles within a register byte are transfered most-significant -
+least-significant.
+
+@multitable @columnfractions .5 .5
+
+@item MIPS32
+@tab
+All registers are transfered as thirty-two bit quantities in the order:
+32 general-purpose; sr; lo; hi; bad; cause; pc; 32 floating-point
+registers; fsr; fir; fp.
+
+@item MIPS64
+@tab
+All registers are transfered as sixty-four bit quantities (including
+thirty-two bit registers such as @code{sr}). The ordering is the same
+as @code{MIPS32}.
+
+@end multitable
+
+Example sequence of a target being re-started. Notice how the restart
+does not get any direct output:
+
+@smallexample
+<- @code{R00}
+-> @code{+}
+@emph{target restarts}
+<- @code{?}
+-> @code{+}
+-> @code{T001:1234123412341234}
+<- @code{+}
+@end smallexample
+
+Example sequence of a target being stepped by a single instruction:
+
+@smallexample
+<- @code{G1445...}
+-> @code{+}
+<- @code{s}
+-> @code{+}
+@emph{time passes}
+-> @code{T001:1234123412341234}
+<- @code{+}
+<- @code{g}
+-> @code{+}
+-> @code{1455...}
+<- @code{+}
+@end smallexample
+
+@include gpl.texi
+
+@include fdl.texi
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@tex
+% I think something like @colophon should be in texinfo. In the
+% meantime:
+\long\def\colophon{\hbox to0pt{}\vfill
+\centerline{The body of this manual is set in}
+\centerline{\fontname\tenrm,}
+\centerline{with headings in {\bf\fontname\tenbf}}
+\centerline{and examples in {\tt\fontname\tentt}.}
+\centerline{{\it\fontname\tenit\/},}
+\centerline{{\bf\fontname\tenbf}, and}
+\centerline{{\sl\fontname\tensl\/}}
+\centerline{are used for emphasis.}\vfill}
+\page\colophon
+% Blame: doc@cygnus.com, 1991.
+@end tex
+
+@bye
diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo
new file mode 100644
index 00000000000..4f76f5fb524
--- /dev/null
+++ b/gdb/doc/gdbint.texinfo
@@ -0,0 +1,6095 @@
+\input texinfo @c -*- texinfo -*-
+@setfilename gdbint.info
+@include gdb-cfg.texi
+@dircategory Programming & development tools.
+@direntry
+* Gdb-Internals: (gdbint). The GNU debugger's internals.
+@end direntry
+
+@ifinfo
+This file documents the internals of the GNU debugger @value{GDBN}.
+Copyright 1990,1991,1992,1993,1994,1996,1998,1999,2000,2001,2002
+ Free Software Foundation, Inc.
+Contributed by Cygnus Solutions. Written by John Gilmore.
+Second Edition by Stan Shebs.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
+and with the Back-Cover Texts as in (a) below.
+
+(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
+this GNU Manual, like GNU software. Copies published by the Free
+Software Foundation raise funds for GNU development.''
+@end ifinfo
+
+@setchapternewpage off
+@settitle @value{GDBN} Internals
+
+@syncodeindex fn cp
+@syncodeindex vr cp
+
+@titlepage
+@title @value{GDBN} Internals
+@subtitle{A guide to the internals of the GNU debugger}
+@author John Gilmore
+@author Cygnus Solutions
+@author Second Edition:
+@author Stan Shebs
+@author Cygnus Solutions
+@page
+@tex
+\def\$#1${{#1}} % Kluge: collect RCS revision info without $...$
+\xdef\manvers{\$Revision$} % For use in headers, footers too
+{\parskip=0pt
+\hfill Cygnus Solutions\par
+\hfill \manvers\par
+\hfill \TeX{}info \texinfoversion\par
+}
+@end tex
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1990,1991,1992,1993,1994,1996,1998,1999,2000,2001
+ Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
+and with the Back-Cover Texts as in (a) below.
+
+(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
+this GNU Manual, like GNU software. Copies published by the Free
+Software Foundation raise funds for GNU development.''
+@end titlepage
+
+@contents
+
+@node Top
+@c Perhaps this should be the title of the document (but only for info,
+@c not for TeX). Existing GNU manuals seem inconsistent on this point.
+@top Scope of this Document
+
+This document documents the internals of the GNU debugger, @value{GDBN}. It
+includes description of @value{GDBN}'s key algorithms and operations, as well
+as the mechanisms that adapt @value{GDBN} to specific hosts and targets.
+
+@menu
+* Requirements::
+* Overall Structure::
+* Algorithms::
+* User Interface::
+* libgdb::
+* Symbol Handling::
+* Language Support::
+* Host Definition::
+* Target Architecture Definition::
+* Target Vector Definition::
+* Native Debugging::
+* Support Libraries::
+* Coding::
+* Porting GDB::
+* Releasing GDB::
+* Testsuite::
+* Hints::
+
+* GNU Free Documentation License:: The license for this documentation
+* Index::
+@end menu
+
+@node Requirements
+
+@chapter Requirements
+@cindex requirements for @value{GDBN}
+
+Before diving into the internals, you should understand the formal
+requirements and other expectations for @value{GDBN}. Although some
+of these may seem obvious, there have been proposals for @value{GDBN}
+that have run counter to these requirements.
+
+First of all, @value{GDBN} is a debugger. It's not designed to be a
+front panel for embedded systems. It's not a text editor. It's not a
+shell. It's not a programming environment.
+
+@value{GDBN} is an interactive tool. Although a batch mode is
+available, @value{GDBN}'s primary role is to interact with a human
+programmer.
+
+@value{GDBN} should be responsive to the user. A programmer hot on
+the trail of a nasty bug, and operating under a looming deadline, is
+going to be very impatient of everything, including the response time
+to debugger commands.
+
+@value{GDBN} should be relatively permissive, such as for expressions.
+While the compiler should be picky (or have the option to be made
+picky), since source code lives for a long time usually, the
+programmer doing debugging shouldn't be spending time figuring out to
+mollify the debugger.
+
+@value{GDBN} will be called upon to deal with really large programs.
+Executable sizes of 50 to 100 megabytes occur regularly, and we've
+heard reports of programs approaching 1 gigabyte in size.
+
+@value{GDBN} should be able to run everywhere. No other debugger is
+available for even half as many configurations as @value{GDBN}
+supports.
+
+
+@node Overall Structure
+
+@chapter Overall Structure
+
+@value{GDBN} consists of three major subsystems: user interface,
+symbol handling (the @dfn{symbol side}), and target system handling (the
+@dfn{target side}).
+
+The user interface consists of several actual interfaces, plus
+supporting code.
+
+The symbol side consists of object file readers, debugging info
+interpreters, symbol table management, source language expression
+parsing, type and value printing.
+
+The target side consists of execution control, stack frame analysis, and
+physical target manipulation.
+
+The target side/symbol side division is not formal, and there are a
+number of exceptions. For instance, core file support involves symbolic
+elements (the basic core file reader is in BFD) and target elements (it
+supplies the contents of memory and the values of registers). Instead,
+this division is useful for understanding how the minor subsystems
+should fit together.
+
+@section The Symbol Side
+
+The symbolic side of @value{GDBN} can be thought of as ``everything
+you can do in @value{GDBN} without having a live program running''.
+For instance, you can look at the types of variables, and evaluate
+many kinds of expressions.
+
+@section The Target Side
+
+The target side of @value{GDBN} is the ``bits and bytes manipulator''.
+Although it may make reference to symbolic info here and there, most
+of the target side will run with only a stripped executable
+available---or even no executable at all, in remote debugging cases.
+
+Operations such as disassembly, stack frame crawls, and register
+display, are able to work with no symbolic info at all. In some cases,
+such as disassembly, @value{GDBN} will use symbolic info to present addresses
+relative to symbols rather than as raw numbers, but it will work either
+way.
+
+@section Configurations
+
+@cindex host
+@cindex target
+@dfn{Host} refers to attributes of the system where @value{GDBN} runs.
+@dfn{Target} refers to the system where the program being debugged
+executes. In most cases they are the same machine, in which case a
+third type of @dfn{Native} attributes come into play.
+
+Defines and include files needed to build on the host are host support.
+Examples are tty support, system defined types, host byte order, host
+float format.
+
+Defines and information needed to handle the target format are target
+dependent. Examples are the stack frame format, instruction set,
+breakpoint instruction, registers, and how to set up and tear down the stack
+to call a function.
+
+Information that is only needed when the host and target are the same,
+is native dependent. One example is Unix child process support; if the
+host and target are not the same, doing a fork to start the target
+process is a bad idea. The various macros needed for finding the
+registers in the @code{upage}, running @code{ptrace}, and such are all
+in the native-dependent files.
+
+Another example of native-dependent code is support for features that
+are really part of the target environment, but which require
+@code{#include} files that are only available on the host system. Core
+file handling and @code{setjmp} handling are two common cases.
+
+When you want to make @value{GDBN} work ``native'' on a particular machine, you
+have to include all three kinds of information.
+
+
+@node Algorithms
+
+@chapter Algorithms
+@cindex algorithms
+
+@value{GDBN} uses a number of debugging-specific algorithms. They are
+often not very complicated, but get lost in the thicket of special
+cases and real-world issues. This chapter describes the basic
+algorithms and mentions some of the specific target definitions that
+they use.
+
+@section Frames
+
+@cindex frame
+@cindex call stack frame
+A frame is a construct that @value{GDBN} uses to keep track of calling
+and called functions.
+
+@findex create_new_frame
+@vindex FRAME_FP
+@code{FRAME_FP} in the machine description has no meaning to the
+machine-independent part of @value{GDBN}, except that it is used when
+setting up a new frame from scratch, as follows:
+
+@smallexample
+create_new_frame (read_register (FP_REGNUM), read_pc ()));
+@end smallexample
+
+@cindex frame pointer register
+Other than that, all the meaning imparted to @code{FP_REGNUM} is
+imparted by the machine-dependent code. So, @code{FP_REGNUM} can have
+any value that is convenient for the code that creates new frames.
+(@code{create_new_frame} calls @code{INIT_EXTRA_FRAME_INFO} if it is
+defined; that is where you should use the @code{FP_REGNUM} value, if
+your frames are nonstandard.)
+
+@cindex frame chain
+Given a @value{GDBN} frame, define @code{FRAME_CHAIN} to determine the
+address of the calling function's frame. This will be used to create
+a new @value{GDBN} frame struct, and then @code{INIT_EXTRA_FRAME_INFO}
+and @code{INIT_FRAME_PC} will be called for the new frame.
+
+@section Breakpoint Handling
+
+@cindex breakpoints
+In general, a breakpoint is a user-designated location in the program
+where the user wants to regain control if program execution ever reaches
+that location.
+
+There are two main ways to implement breakpoints; either as ``hardware''
+breakpoints or as ``software'' breakpoints.
+
+@cindex hardware breakpoints
+@cindex program counter
+Hardware breakpoints are sometimes available as a builtin debugging
+features with some chips. Typically these work by having dedicated
+register into which the breakpoint address may be stored. If the PC
+(shorthand for @dfn{program counter})
+ever matches a value in a breakpoint registers, the CPU raises an
+exception and reports it to @value{GDBN}.
+
+Another possibility is when an emulator is in use; many emulators
+include circuitry that watches the address lines coming out from the
+processor, and force it to stop if the address matches a breakpoint's
+address.
+
+A third possibility is that the target already has the ability to do
+breakpoints somehow; for instance, a ROM monitor may do its own
+software breakpoints. So although these are not literally ``hardware
+breakpoints'', from @value{GDBN}'s point of view they work the same;
+@value{GDBN} need not do nothing more than set the breakpoint and wait
+for something to happen.
+
+Since they depend on hardware resources, hardware breakpoints may be
+limited in number; when the user asks for more, @value{GDBN} will
+start trying to set software breakpoints. (On some architectures,
+notably the 32-bit x86 platforms, @value{GDBN} cannot always know
+whether there's enough hardware resources to insert all the hardware
+breakpoints and watchpoints. On those platforms, @value{GDBN} prints
+an error message only when the program being debugged is continued.)
+
+@cindex software breakpoints
+Software breakpoints require @value{GDBN} to do somewhat more work.
+The basic theory is that @value{GDBN} will replace a program
+instruction with a trap, illegal divide, or some other instruction
+that will cause an exception, and then when it's encountered,
+@value{GDBN} will take the exception and stop the program. When the
+user says to continue, @value{GDBN} will restore the original
+instruction, single-step, re-insert the trap, and continue on.
+
+Since it literally overwrites the program being tested, the program area
+must be writable, so this technique won't work on programs in ROM. It
+can also distort the behavior of programs that examine themselves,
+although such a situation would be highly unusual.
+
+Also, the software breakpoint instruction should be the smallest size of
+instruction, so it doesn't overwrite an instruction that might be a jump
+target, and cause disaster when the program jumps into the middle of the
+breakpoint instruction. (Strictly speaking, the breakpoint must be no
+larger than the smallest interval between instructions that may be jump
+targets; perhaps there is an architecture where only even-numbered
+instructions may jumped to.) Note that it's possible for an instruction
+set not to have any instructions usable for a software breakpoint,
+although in practice only the ARC has failed to define such an
+instruction.
+
+@findex BREAKPOINT
+The basic definition of the software breakpoint is the macro
+@code{BREAKPOINT}.
+
+Basic breakpoint object handling is in @file{breakpoint.c}. However,
+much of the interesting breakpoint action is in @file{infrun.c}.
+
+@section Single Stepping
+
+@section Signal Handling
+
+@section Thread Handling
+
+@section Inferior Function Calls
+
+@section Longjmp Support
+
+@cindex @code{longjmp} debugging
+@value{GDBN} has support for figuring out that the target is doing a
+@code{longjmp} and for stopping at the target of the jump, if we are
+stepping. This is done with a few specialized internal breakpoints,
+which are visible in the output of the @samp{maint info breakpoint}
+command.
+
+@findex GET_LONGJMP_TARGET
+To make this work, you need to define a macro called
+@code{GET_LONGJMP_TARGET}, which will examine the @code{jmp_buf}
+structure and extract the longjmp target address. Since @code{jmp_buf}
+is target specific, you will need to define it in the appropriate
+@file{tm-@var{target}.h} file. Look in @file{tm-sun4os4.h} and
+@file{sparc-tdep.c} for examples of how to do this.
+
+@section Watchpoints
+@cindex watchpoints
+
+Watchpoints are a special kind of breakpoints (@pxref{Algorithms,
+breakpoints}) which break when data is accessed rather than when some
+instruction is executed. When you have data which changes without
+your knowing what code does that, watchpoints are the silver bullet to
+hunt down and kill such bugs.
+
+@cindex hardware watchpoints
+@cindex software watchpoints
+Watchpoints can be either hardware-assisted or not; the latter type is
+known as ``software watchpoints.'' @value{GDBN} always uses
+hardware-assisted watchpoints if they are available, and falls back on
+software watchpoints otherwise. Typical situations where @value{GDBN}
+will use software watchpoints are:
+
+@itemize @bullet
+@item
+The watched memory region is too large for the underlying hardware
+watchpoint support. For example, each x86 debug register can watch up
+to 4 bytes of memory, so trying to watch data structures whose size is
+more than 16 bytes will cause @value{GDBN} to use software
+watchpoints.
+
+@item
+The value of the expression to be watched depends on data held in
+registers (as opposed to memory).
+
+@item
+Too many different watchpoints requested. (On some architectures,
+this situation is impossible to detect until the debugged program is
+resumed.) Note that x86 debug registers are used both for hardware
+breakpoints and for watchpoints, so setting too many hardware
+breakpoints might cause watchpoint insertion to fail.
+
+@item
+No hardware-assisted watchpoints provided by the target
+implementation.
+@end itemize
+
+Software watchpoints are very slow, since @value{GDBN} needs to
+single-step the program being debugged and test the value of the
+watched expression(s) after each instruction. The rest of this
+section is mostly irrelevant for software watchpoints.
+
+@value{GDBN} uses several macros and primitives to support hardware
+watchpoints:
+
+@table @code
+@findex TARGET_HAS_HARDWARE_WATCHPOINTS
+@item TARGET_HAS_HARDWARE_WATCHPOINTS
+If defined, the target supports hardware watchpoints.
+
+@findex TARGET_CAN_USE_HARDWARE_WATCHPOINT
+@item TARGET_CAN_USE_HARDWARE_WATCHPOINT (@var{type}, @var{count}, @var{other})
+Return the number of hardware watchpoints of type @var{type} that are
+possible to be set. The value is positive if @var{count} watchpoints
+of this type can be set, zero if setting watchpoints of this type is
+not supported, and negative if @var{count} is more than the maximum
+number of watchpoints of type @var{type} that can be set. @var{other}
+is non-zero if other types of watchpoints are currently enabled (there
+are architectures which cannot set watchpoints of different types at
+the same time).
+
+@findex TARGET_REGION_OK_FOR_HW_WATCHPOINT
+@item TARGET_REGION_OK_FOR_HW_WATCHPOINT (@var{addr}, @var{len})
+Return non-zero if hardware watchpoints can be used to watch a region
+whose address is @var{addr} and whose length in bytes is @var{len}.
+
+@findex TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT
+@item TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT (@var{size})
+Return non-zero if hardware watchpoints can be used to watch a region
+whose size is @var{size}. @value{GDBN} only uses this macro as a
+fall-back, in case @code{TARGET_REGION_OK_FOR_HW_WATCHPOINT} is not
+defined.
+
+@findex TARGET_DISABLE_HW_WATCHPOINTS
+@item TARGET_DISABLE_HW_WATCHPOINTS (@var{pid})
+Disables watchpoints in the process identified by @var{pid}. This is
+used, e.g., on HP-UX which provides operations to disable and enable
+the page-level memory protection that implements hardware watchpoints
+on that platform.
+
+@findex TARGET_ENABLE_HW_WATCHPOINTS
+@item TARGET_ENABLE_HW_WATCHPOINTS (@var{pid})
+Enables watchpoints in the process identified by @var{pid}. This is
+used, e.g., on HP-UX which provides operations to disable and enable
+the page-level memory protection that implements hardware watchpoints
+on that platform.
+
+@findex target_insert_watchpoint
+@findex target_remove_watchpoint
+@item target_insert_watchpoint (@var{addr}, @var{len}, @var{type})
+@itemx target_remove_watchpoint (@var{addr}, @var{len}, @var{type})
+Insert or remove a hardware watchpoint starting at @var{addr}, for
+@var{len} bytes. @var{type} is the watchpoint type, one of the
+possible values of the enumerated data type @code{target_hw_bp_type},
+defined by @file{breakpoint.h} as follows:
+
+@smallexample
+ enum target_hw_bp_type
+ @{
+ hw_write = 0, /* Common (write) HW watchpoint */
+ hw_read = 1, /* Read HW watchpoint */
+ hw_access = 2, /* Access (read or write) HW watchpoint */
+ hw_execute = 3 /* Execute HW breakpoint */
+ @};
+@end smallexample
+
+@noindent
+These two macros should return 0 for success, non-zero for failure.
+
+@cindex insert or remove hardware breakpoint
+@findex target_remove_hw_breakpoint
+@findex target_insert_hw_breakpoint
+@item target_remove_hw_breakpoint (@var{addr}, @var{shadow})
+@itemx target_insert_hw_breakpoint (@var{addr}, @var{shadow})
+Insert or remove a hardware-assisted breakpoint at address @var{addr}.
+Returns zero for success, non-zero for failure. @var{shadow} is the
+real contents of the byte where the breakpoint has been inserted; it
+is generally not valid when hardware breakpoints are used, but since
+no other code touches these values, the implementations of the above
+two macros can use them for their internal purposes.
+
+@findex target_stopped_data_address
+@item target_stopped_data_address ()
+If the inferior has some watchpoint that triggered, return the address
+associated with that watchpoint. Otherwise, return zero.
+
+@findex DECR_PC_AFTER_HW_BREAK
+@item DECR_PC_AFTER_HW_BREAK
+If defined, @value{GDBN} decrements the program counter by the value
+of @code{DECR_PC_AFTER_HW_BREAK} after a hardware break-point. This
+overrides the value of @code{DECR_PC_AFTER_BREAK} when a breakpoint
+that breaks is a hardware-assisted breakpoint.
+
+@findex HAVE_STEPPABLE_WATCHPOINT
+@item HAVE_STEPPABLE_WATCHPOINT
+If defined to a non-zero value, it is not necessary to disable a
+watchpoint to step over it.
+
+@findex HAVE_NONSTEPPABLE_WATCHPOINT
+@item HAVE_NONSTEPPABLE_WATCHPOINT
+If defined to a non-zero value, @value{GDBN} should disable a
+watchpoint to step the inferior over it.
+
+@findex HAVE_CONTINUABLE_WATCHPOINT
+@item HAVE_CONTINUABLE_WATCHPOINT
+If defined to a non-zero value, it is possible to continue the
+inferior after a watchpoint has been hit.
+
+@findex CANNOT_STEP_HW_WATCHPOINTS
+@item CANNOT_STEP_HW_WATCHPOINTS
+If this is defined to a non-zero value, @value{GDBN} will remove all
+watchpoints before stepping the inferior.
+
+@findex STOPPED_BY_WATCHPOINT
+@item STOPPED_BY_WATCHPOINT (@var{wait_status})
+Return non-zero if stopped by a watchpoint. @var{wait_status} is of
+the type @code{struct target_waitstatus}, defined by @file{target.h}.
+@end table
+
+@subsection x86 Watchpoints
+@cindex x86 debug registers
+@cindex watchpoints, on x86
+
+The 32-bit Intel x86 (a.k.a.@: ia32) processors feature special debug
+registers designed to facilitate debugging. @value{GDBN} provides a
+generic library of functions that x86-based ports can use to implement
+support for watchpoints and hardware-assisted breakpoints. This
+subsection documents the x86 watchpoint facilities in @value{GDBN}.
+
+To use the generic x86 watchpoint support, a port should do the
+following:
+
+@itemize @bullet
+@findex I386_USE_GENERIC_WATCHPOINTS
+@item
+Define the macro @code{I386_USE_GENERIC_WATCHPOINTS} somewhere in the
+target-dependent headers.
+
+@item
+Include the @file{config/i386/nm-i386.h} header file @emph{after}
+defining @code{I386_USE_GENERIC_WATCHPOINTS}.
+
+@item
+Add @file{i386-nat.o} to the value of the Make variable
+@code{NATDEPFILES} (@pxref{Native Debugging, NATDEPFILES}) or
+@code{TDEPFILES} (@pxref{Target Architecture Definition, TDEPFILES}).
+
+@item
+Provide implementations for the @code{I386_DR_LOW_*} macros described
+below. Typically, each macro should call a target-specific function
+which does the real work.
+@end itemize
+
+The x86 watchpoint support works by maintaining mirror images of the
+debug registers. Values are copied between the mirror images and the
+real debug registers via a set of macros which each target needs to
+provide:
+
+@table @code
+@findex I386_DR_LOW_SET_CONTROL
+@item I386_DR_LOW_SET_CONTROL (@var{val})
+Set the Debug Control (DR7) register to the value @var{val}.
+
+@findex I386_DR_LOW_SET_ADDR
+@item I386_DR_LOW_SET_ADDR (@var{idx}, @var{addr})
+Put the address @var{addr} into the debug register number @var{idx}.
+
+@findex I386_DR_LOW_RESET_ADDR
+@item I386_DR_LOW_RESET_ADDR (@var{idx})
+Reset (i.e.@: zero out) the address stored in the debug register
+number @var{idx}.
+
+@findex I386_DR_LOW_GET_STATUS
+@item I386_DR_LOW_GET_STATUS
+Return the value of the Debug Status (DR6) register. This value is
+used immediately after it is returned by
+@code{I386_DR_LOW_GET_STATUS}, so as to support per-thread status
+register values.
+@end table
+
+For each one of the 4 debug registers (whose indices are from 0 to 3)
+that store addresses, a reference count is maintained by @value{GDBN},
+to allow sharing of debug registers by several watchpoints. This
+allows users to define several watchpoints that watch the same
+expression, but with different conditions and/or commands, without
+wasting debug registers which are in short supply. @value{GDBN}
+maintains the reference counts internally, targets don't have to do
+anything to use this feature.
+
+The x86 debug registers can each watch a region that is 1, 2, or 4
+bytes long. The ia32 architecture requires that each watched region
+be appropriately aligned: 2-byte region on 2-byte boundary, 4-byte
+region on 4-byte boundary. However, the x86 watchpoint support in
+@value{GDBN} can watch unaligned regions and regions larger than 4
+bytes (up to 16 bytes) by allocating several debug registers to watch
+a single region. This allocation of several registers per a watched
+region is also done automatically without target code intervention.
+
+The generic x86 watchpoint support provides the following API for the
+@value{GDBN}'s application code:
+
+@table @code
+@findex i386_region_ok_for_watchpoint
+@item i386_region_ok_for_watchpoint (@var{addr}, @var{len})
+The macro @code{TARGET_REGION_OK_FOR_HW_WATCHPOINT} is set to call
+this function. It counts the number of debug registers required to
+watch a given region, and returns a non-zero value if that number is
+less than 4, the number of debug registers available to x86
+processors.
+
+@findex i386_stopped_data_address
+@item i386_stopped_data_address (void)
+The macros @code{STOPPED_BY_WATCHPOINT} and
+@code{target_stopped_data_address} are set to call this function. The
+argument passed to @code{STOPPED_BY_WATCHPOINT} is ignored. This
+function examines the breakpoint condition bits in the DR6 Debug
+Status register, as returned by the @code{I386_DR_LOW_GET_STATUS}
+macro, and returns the address associated with the first bit that is
+set in DR6.
+
+@findex i386_insert_watchpoint
+@findex i386_remove_watchpoint
+@item i386_insert_watchpoint (@var{addr}, @var{len}, @var{type})
+@itemx i386_remove_watchpoint (@var{addr}, @var{len}, @var{type})
+Insert or remove a watchpoint. The macros
+@code{target_insert_watchpoint} and @code{target_remove_watchpoint}
+are set to call these functions. @code{i386_insert_watchpoint} first
+looks for a debug register which is already set to watch the same
+region for the same access types; if found, it just increments the
+reference count of that debug register, thus implementing debug
+register sharing between watchpoints. If no such register is found,
+the function looks for a vacant debug register, sets its mirrored
+value to @var{addr}, sets the mirrored value of DR7 Debug Control
+register as appropriate for the @var{len} and @var{type} parameters,
+and then passes the new values of the debug register and DR7 to the
+inferior by calling @code{I386_DR_LOW_SET_ADDR} and
+@code{I386_DR_LOW_SET_CONTROL}. If more than one debug register is
+required to cover the given region, the above process is repeated for
+each debug register.
+
+@code{i386_remove_watchpoint} does the opposite: it resets the address
+in the mirrored value of the debug register and its read/write and
+length bits in the mirrored value of DR7, then passes these new
+values to the inferior via @code{I386_DR_LOW_RESET_ADDR} and
+@code{I386_DR_LOW_SET_CONTROL}. If a register is shared by several
+watchpoints, each time a @code{i386_remove_watchpoint} is called, it
+decrements the reference count, and only calls
+@code{I386_DR_LOW_RESET_ADDR} and @code{I386_DR_LOW_SET_CONTROL} when
+the count goes to zero.
+
+@findex i386_insert_hw_breakpoint
+@findex i386_remove_hw_breakpoint
+@item i386_insert_hw_breakpoint (@var{addr}, @var{shadow}
+@itemx i386_remove_hw_breakpoint (@var{addr}, @var{shadow})
+These functions insert and remove hardware-assisted breakpoints. The
+macros @code{target_insert_hw_breakpoint} and
+@code{target_remove_hw_breakpoint} are set to call these functions.
+These functions work like @code{i386_insert_watchpoint} and
+@code{i386_remove_watchpoint}, respectively, except that they set up
+the debug registers to watch instruction execution, and each
+hardware-assisted breakpoint always requires exactly one debug
+register.
+
+@findex i386_stopped_by_hwbp
+@item i386_stopped_by_hwbp (void)
+This function returns non-zero if the inferior has some watchpoint or
+hardware breakpoint that triggered. It works like
+@code{i386_stopped_data_address}, except that it doesn't return the
+address whose watchpoint triggered.
+
+@findex i386_cleanup_dregs
+@item i386_cleanup_dregs (void)
+This function clears all the reference counts, addresses, and control
+bits in the mirror images of the debug registers. It doesn't affect
+the actual debug registers in the inferior process.
+@end table
+
+@noindent
+@strong{Notes:}
+@enumerate 1
+@item
+x86 processors support setting watchpoints on I/O reads or writes.
+However, since no target supports this (as of March 2001), and since
+@code{enum target_hw_bp_type} doesn't even have an enumeration for I/O
+watchpoints, this feature is not yet available to @value{GDBN} running
+on x86.
+
+@item
+x86 processors can enable watchpoints locally, for the current task
+only, or globally, for all the tasks. For each debug register,
+there's a bit in the DR7 Debug Control register that determines
+whether the associated address is watched locally or globally. The
+current implementation of x86 watchpoint support in @value{GDBN}
+always sets watchpoints to be locally enabled, since global
+watchpoints might interfere with the underlying OS and are probably
+unavailable in many platforms.
+@end enumerate
+
+@node User Interface
+
+@chapter User Interface
+
+@value{GDBN} has several user interfaces. Although the command-line interface
+is the most common and most familiar, there are others.
+
+@section Command Interpreter
+
+@cindex command interpreter
+@cindex CLI
+The command interpreter in @value{GDBN} is fairly simple. It is designed to
+allow for the set of commands to be augmented dynamically, and also
+has a recursive subcommand capability, where the first argument to
+a command may itself direct a lookup on a different command list.
+
+For instance, the @samp{set} command just starts a lookup on the
+@code{setlist} command list, while @samp{set thread} recurses
+to the @code{set_thread_cmd_list}.
+
+@findex add_cmd
+@findex add_com
+To add commands in general, use @code{add_cmd}. @code{add_com} adds to
+the main command list, and should be used for those commands. The usual
+place to add commands is in the @code{_initialize_@var{xyz}} routines at
+the ends of most source files.
+
+@cindex deprecating commands
+@findex deprecate_cmd
+Before removing commands from the command set it is a good idea to
+deprecate them for some time. Use @code{deprecate_cmd} on commands or
+aliases to set the deprecated flag. @code{deprecate_cmd} takes a
+@code{struct cmd_list_element} as it's first argument. You can use the
+return value from @code{add_com} or @code{add_cmd} to deprecate the
+command immediately after it is created.
+
+The first time a command is used the user will be warned and offered a
+replacement (if one exists). Note that the replacement string passed to
+@code{deprecate_cmd} should be the full name of the command, i.e. the
+entire string the user should type at the command line.
+
+@section UI-Independent Output---the @code{ui_out} Functions
+@c This section is based on the documentation written by Fernando
+@c Nasser <fnasser@redhat.com>.
+
+@cindex @code{ui_out} functions
+The @code{ui_out} functions present an abstraction level for the
+@value{GDBN} output code. They hide the specifics of different user
+interfaces supported by @value{GDBN}, and thus free the programmer
+from the need to write several versions of the same code, one each for
+every UI, to produce output.
+
+@subsection Overview and Terminology
+
+In general, execution of each @value{GDBN} command produces some sort
+of output, and can even generate an input request.
+
+Output can be generated for the following purposes:
+
+@itemize @bullet
+@item
+to display a @emph{result} of an operation;
+
+@item
+to convey @emph{info} or produce side-effects of a requested
+operation;
+
+@item
+to provide a @emph{notification} of an asynchronous event (including
+progress indication of a prolonged asynchronous operation);
+
+@item
+to display @emph{error messages} (including warnings);
+
+@item
+to show @emph{debug data};
+
+@item
+to @emph{query} or prompt a user for input (a special case).
+@end itemize
+
+@noindent
+This section mainly concentrates on how to build result output,
+although some of it also applies to other kinds of output.
+
+Generation of output that displays the results of an operation
+involves one or more of the following:
+
+@itemize @bullet
+@item
+output of the actual data
+
+@item
+formatting the output as appropriate for console output, to make it
+easily readable by humans
+
+@item
+machine oriented formatting--a more terse formatting to allow for easy
+parsing by programs which read @value{GDBN}'s output
+
+@item
+annotation, whose purpose is to help legacy GUIs to identify interesting
+parts in the output
+@end itemize
+
+The @code{ui_out} routines take care of the first three aspects.
+Annotations are provided by separate annotation routines. Note that use
+of annotations for an interface between a GUI and @value{GDBN} is
+deprecated.
+
+Output can be in the form of a single item, which we call a @dfn{field};
+a @dfn{list} consisting of identical fields; a @dfn{tuple} consisting of
+non-identical fields; or a @dfn{table}, which is a tuple consisting of a
+header and a body. In a BNF-like form:
+
+@table @code
+@item <table> @expansion{}
+@code{<header> <body>}
+@item <header> @expansion{}
+@code{@{ <column> @}}
+@item <column> @expansion{}
+@code{<width> <alignment> <title>}
+@item <body> @expansion{}
+@code{@{<row>@}}
+@end table
+
+
+@subsection General Conventions
+
+Most @code{ui_out} routines are of type @code{void}, the exceptions are
+@code{ui_out_stream_new} (which returns a pointer to the newly created
+object) and the @code{make_cleanup} routines.
+
+The first parameter is always the @code{ui_out} vector object, a pointer
+to a @code{struct ui_out}.
+
+The @var{format} parameter is like in @code{printf} family of functions.
+When it is present, there must also be a variable list of arguments
+sufficient used to satisfy the @code{%} specifiers in the supplied
+format.
+
+When a character string argument is not used in a @code{ui_out} function
+call, a @code{NULL} pointer has to be supplied instead.
+
+
+@subsection Table, Tuple and List Functions
+
+@cindex list output functions
+@cindex table output functions
+@cindex tuple output functions
+This section introduces @code{ui_out} routines for building lists,
+tuples and tables. The routines to output the actual data items
+(fields) are presented in the next section.
+
+To recap: A @dfn{tuple} is a sequence of @dfn{fields}, each field
+containing information about an object; a @dfn{list} is a sequence of
+fields where each field describes an identical object.
+
+Use the @dfn{table} functions when your output consists of a list of
+rows (tuples) and the console output should include a heading. Use this
+even when you are listing just one object but you still want the header.
+
+@cindex nesting level in @code{ui_out} functions
+Tables can not be nested. Tuples and lists can be nested up to a
+maximum of five levels.
+
+The overall structure of the table output code is something like this:
+
+@smallexample
+ ui_out_table_begin
+ ui_out_table_header
+ @dots{}
+ ui_out_table_body
+ ui_out_tuple_begin
+ ui_out_field_*
+ @dots{}
+ ui_out_tuple_end
+ @dots{}
+ ui_out_table_end
+@end smallexample
+
+Here is the description of table-, tuple- and list-related @code{ui_out}
+functions:
+
+@deftypefun void ui_out_table_begin (struct ui_out *@var{uiout}, int @var{nbrofcols}, int @var{nr_rows}, const char *@var{tblid})
+The function @code{ui_out_table_begin} marks the beginning of the output
+of a table. It should always be called before any other @code{ui_out}
+function for a given table. @var{nbrofcols} is the number of columns in
+the table. @var{nr_rows} is the number of rows in the table.
+@var{tblid} is an optional string identifying the table. The string
+pointed to by @var{tblid} is copied by the implementation of
+@code{ui_out_table_begin}, so the application can free the string if it
+was @code{malloc}ed.
+
+The companion function @code{ui_out_table_end}, described below, marks
+the end of the table's output.
+@end deftypefun
+
+@deftypefun void ui_out_table_header (struct ui_out *@var{uiout}, int @var{width}, enum ui_align @var{alignment}, const char *@var{colhdr})
+@code{ui_out_table_header} provides the header information for a single
+table column. You call this function several times, one each for every
+column of the table, after @code{ui_out_table_begin}, but before
+@code{ui_out_table_body}.
+
+The value of @var{width} gives the column width in characters. The
+value of @var{alignment} is one of @code{left}, @code{center}, and
+@code{right}, and it specifies how to align the header: left-justify,
+center, or right-justify it. @var{colhdr} points to a string that
+specifies the column header; the implementation copies that string, so
+column header strings in @code{malloc}ed storage can be freed after the
+call.
+@end deftypefun
+
+@deftypefun void ui_out_table_body (struct ui_out *@var{uiout})
+This function delimits the table header from the table body.
+@end deftypefun
+
+@deftypefun void ui_out_table_end (struct ui_out *@var{uiout})
+This function signals the end of a table's output. It should be called
+after the table body has been produced by the list and field output
+functions.
+
+There should be exactly one call to @code{ui_out_table_end} for each
+call to @code{ui_out_table_begin}, otherwise the @code{ui_out} functions
+will signal an internal error.
+@end deftypefun
+
+The output of the tuples that represent the table rows must follow the
+call to @code{ui_out_table_body} and precede the call to
+@code{ui_out_table_end}. You build a tuple by calling
+@code{ui_out_tuple_begin} and @code{ui_out_tuple_end}, with suitable
+calls to functions which actually output fields between them.
+
+@deftypefun void ui_out_tuple_begin (struct ui_out *@var{uiout}, const char *@var{id})
+This function marks the beginning of a tuple output. @var{id} points
+to an optional string that identifies the tuple; it is copied by the
+implementation, and so strings in @code{malloc}ed storage can be freed
+after the call.
+@end deftypefun
+
+@deftypefun void ui_out_tuple_end (struct ui_out *@var{uiout})
+This function signals an end of a tuple output. There should be exactly
+one call to @code{ui_out_tuple_end} for each call to
+@code{ui_out_tuple_begin}, otherwise an internal @value{GDBN} error will
+be signaled.
+@end deftypefun
+
+@deftypefun struct cleanup *make_cleanup_ui_out_tuple_begin_end (struct ui_out *@var{uiout}, const char *@var{id})
+This function first opens the tuple and then establishes a cleanup
+(@pxref{Coding, Cleanups}) to close the tuple. It provides a convenient
+and correct implementation of the non-portable@footnote{The function
+cast is not portable ISO-C.} code sequence:
+@smallexample
+struct cleanup *old_cleanup;
+ui_out_tuple_begin (uiout, "...");
+old_cleanup = make_cleanup ((void(*)(void *)) ui_out_tuple_end,
+ uiout);
+@end smallexample
+@end deftypefun
+
+@deftypefun void ui_out_list_begin (struct ui_out *@var{uiout}, const char *@var{id})
+This function marks the beginning of a list output. @var{id} points to
+an optional string that identifies the list; it is copied by the
+implementation, and so strings in @code{malloc}ed storage can be freed
+after the call.
+@end deftypefun
+
+@deftypefun void ui_out_list_end (struct ui_out *@var{uiout})
+This function signals an end of a list output. There should be exactly
+one call to @code{ui_out_list_end} for each call to
+@code{ui_out_list_begin}, otherwise an internal @value{GDBN} error will
+be signaled.
+@end deftypefun
+
+@deftypefun struct cleanup *make_cleanup_ui_out_list_begin_end (struct ui_out *@var{uiout}, const char *@var{id})
+Similar to @code{make_cleanup_ui_out_tuple_begin_end}, this function
+opens a list and then establishes cleanup (@pxref{Coding, Cleanups})
+that will close the list.list.
+@end deftypefun
+
+@subsection Item Output Functions
+
+@cindex item output functions
+@cindex field output functions
+@cindex data output
+The functions described below produce output for the actual data
+items, or fields, which contain information about the object.
+
+Choose the appropriate function accordingly to your particular needs.
+
+@deftypefun void ui_out_field_fmt (struct ui_out *@var{uiout}, char *@var{fldname}, char *@var{format}, ...)
+This is the most general output function. It produces the
+representation of the data in the variable-length argument list
+according to formatting specifications in @var{format}, a
+@code{printf}-like format string. The optional argument @var{fldname}
+supplies the name of the field. The data items themselves are
+supplied as additional arguments after @var{format}.
+
+This generic function should be used only when it is not possible to
+use one of the specialized versions (see below).
+@end deftypefun
+
+@deftypefun void ui_out_field_int (struct ui_out *@var{uiout}, const char *@var{fldname}, int @var{value})
+This function outputs a value of an @code{int} variable. It uses the
+@code{"%d"} output conversion specification. @var{fldname} specifies
+the name of the field.
+@end deftypefun
+
+@deftypefun void ui_out_field_core_addr (struct ui_out *@var{uiout}, const char *@var{fldname}, CORE_ADDR @var{address})
+This function outputs an address.
+@end deftypefun
+
+@deftypefun void ui_out_field_string (struct ui_out *@var{uiout}, const char *@var{fldname}, const char *@var{string})
+This function outputs a string using the @code{"%s"} conversion
+specification.
+@end deftypefun
+
+Sometimes, there's a need to compose your output piece by piece using
+functions that operate on a stream, such as @code{value_print} or
+@code{fprintf_symbol_filtered}. These functions accept an argument of
+the type @code{struct ui_file *}, a pointer to a @code{ui_file} object
+used to store the data stream used for the output. When you use one
+of these functions, you need a way to pass their results stored in a
+@code{ui_file} object to the @code{ui_out} functions. To this end,
+you first create a @code{ui_stream} object by calling
+@code{ui_out_stream_new}, pass the @code{stream} member of that
+@code{ui_stream} object to @code{value_print} and similar functions,
+and finally call @code{ui_out_field_stream} to output the field you
+constructed. When the @code{ui_stream} object is no longer needed,
+you should destroy it and free its memory by calling
+@code{ui_out_stream_delete}.
+
+@deftypefun struct ui_stream *ui_out_stream_new (struct ui_out *@var{uiout})
+This function creates a new @code{ui_stream} object which uses the
+same output methods as the @code{ui_out} object whose pointer is
+passed in @var{uiout}. It returns a pointer to the newly created
+@code{ui_stream} object.
+@end deftypefun
+
+@deftypefun void ui_out_stream_delete (struct ui_stream *@var{streambuf})
+This functions destroys a @code{ui_stream} object specified by
+@var{streambuf}.
+@end deftypefun
+
+@deftypefun void ui_out_field_stream (struct ui_out *@var{uiout}, const char *@var{fieldname}, struct ui_stream *@var{streambuf})
+This function consumes all the data accumulated in
+@code{streambuf->stream} and outputs it like
+@code{ui_out_field_string} does. After a call to
+@code{ui_out_field_stream}, the accumulated data no longer exists, but
+the stream is still valid and may be used for producing more fields.
+@end deftypefun
+
+@strong{Important:} If there is any chance that your code could bail
+out before completing output generation and reaching the point where
+@code{ui_out_stream_delete} is called, it is necessary to set up a
+cleanup, to avoid leaking memory and other resources. Here's a
+skeleton code to do that:
+
+@smallexample
+ struct ui_stream *mybuf = ui_out_stream_new (uiout);
+ struct cleanup *old = make_cleanup (ui_out_stream_delete, mybuf);
+ ...
+ do_cleanups (old);
+@end smallexample
+
+If the function already has the old cleanup chain set (for other kinds
+of cleanups), you just have to add your cleanup to it:
+
+@smallexample
+ mybuf = ui_out_stream_new (uiout);
+ make_cleanup (ui_out_stream_delete, mybuf);
+@end smallexample
+
+Note that with cleanups in place, you should not call
+@code{ui_out_stream_delete} directly, or you would attempt to free the
+same buffer twice.
+
+@subsection Utility Output Functions
+
+@deftypefun void ui_out_field_skip (struct ui_out *@var{uiout}, const char *@var{fldname})
+This function skips a field in a table. Use it if you have to leave
+an empty field without disrupting the table alignment. The argument
+@var{fldname} specifies a name for the (missing) filed.
+@end deftypefun
+
+@deftypefun void ui_out_text (struct ui_out *@var{uiout}, const char *@var{string})
+This function outputs the text in @var{string} in a way that makes it
+easy to be read by humans. For example, the console implementation of
+this method filters the text through a built-in pager, to prevent it
+from scrolling off the visible portion of the screen.
+
+Use this function for printing relatively long chunks of text around
+the actual field data: the text it produces is not aligned according
+to the table's format. Use @code{ui_out_field_string} to output a
+string field, and use @code{ui_out_message}, described below, to
+output short messages.
+@end deftypefun
+
+@deftypefun void ui_out_spaces (struct ui_out *@var{uiout}, int @var{nspaces})
+This function outputs @var{nspaces} spaces. It is handy to align the
+text produced by @code{ui_out_text} with the rest of the table or
+list.
+@end deftypefun
+
+@deftypefun void ui_out_message (struct ui_out *@var{uiout}, int @var{verbosity}, const char *@var{format}, ...)
+This function produces a formatted message, provided that the current
+verbosity level is at least as large as given by @var{verbosity}. The
+current verbosity level is specified by the user with the @samp{set
+verbositylevel} command.@footnote{As of this writing (April 2001),
+setting verbosity level is not yet implemented, and is always returned
+as zero. So calling @code{ui_out_message} with a @var{verbosity}
+argument more than zero will cause the message to never be printed.}
+@end deftypefun
+
+@deftypefun void ui_out_wrap_hint (struct ui_out *@var{uiout}, char *@var{indent})
+This function gives the console output filter (a paging filter) a hint
+of where to break lines which are too long. Ignored for all other
+output consumers. @var{indent}, if non-@code{NULL}, is the string to
+be printed to indent the wrapped text on the next line; it must remain
+accessible until the next call to @code{ui_out_wrap_hint}, or until an
+explicit newline is produced by one of the other functions. If
+@var{indent} is @code{NULL}, the wrapped text will not be indented.
+@end deftypefun
+
+@deftypefun void ui_out_flush (struct ui_out *@var{uiout})
+This function flushes whatever output has been accumulated so far, if
+the UI buffers output.
+@end deftypefun
+
+
+@subsection Examples of Use of @code{ui_out} functions
+
+@cindex using @code{ui_out} functions
+@cindex @code{ui_out} functions, usage examples
+This section gives some practical examples of using the @code{ui_out}
+functions to generalize the old console-oriented code in
+@value{GDBN}. The examples all come from functions defined on the
+@file{breakpoints.c} file.
+
+This example, from the @code{breakpoint_1} function, shows how to
+produce a table.
+
+The original code was:
+
+@smallexample
+ if (!found_a_breakpoint++)
+ @{
+ annotate_breakpoints_headers ();
+
+ annotate_field (0);
+ printf_filtered ("Num ");
+ annotate_field (1);
+ printf_filtered ("Type ");
+ annotate_field (2);
+ printf_filtered ("Disp ");
+ annotate_field (3);
+ printf_filtered ("Enb ");
+ if (addressprint)
+ @{
+ annotate_field (4);
+ printf_filtered ("Address ");
+ @}
+ annotate_field (5);
+ printf_filtered ("What\n");
+
+ annotate_breakpoints_table ();
+ @}
+@end smallexample
+
+Here's the new version:
+
+@smallexample
+ nr_printable_breakpoints = @dots{};
+
+ if (addressprint)
+ ui_out_table_begin (ui, 6, nr_printable_breakpoints, "BreakpointTable");
+ else
+ ui_out_table_begin (ui, 5, nr_printable_breakpoints, "BreakpointTable");
+
+ if (nr_printable_breakpoints > 0)
+ annotate_breakpoints_headers ();
+ if (nr_printable_breakpoints > 0)
+ annotate_field (0);
+ ui_out_table_header (uiout, 3, ui_left, "number", "Num"); /* 1 */
+ if (nr_printable_breakpoints > 0)
+ annotate_field (1);
+ ui_out_table_header (uiout, 14, ui_left, "type", "Type"); /* 2 */
+ if (nr_printable_breakpoints > 0)
+ annotate_field (2);
+ ui_out_table_header (uiout, 4, ui_left, "disp", "Disp"); /* 3 */
+ if (nr_printable_breakpoints > 0)
+ annotate_field (3);
+ ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb"); /* 4 */
+ if (addressprint)
+ @{
+ if (nr_printable_breakpoints > 0)
+ annotate_field (4);
+ if (TARGET_ADDR_BIT <= 32)
+ ui_out_table_header (uiout, 10, ui_left, "addr", "Address");/* 5 */
+ else
+ ui_out_table_header (uiout, 18, ui_left, "addr", "Address");/* 5 */
+ @}
+ if (nr_printable_breakpoints > 0)
+ annotate_field (5);
+ ui_out_table_header (uiout, 40, ui_noalign, "what", "What"); /* 6 */
+ ui_out_table_body (uiout);
+ if (nr_printable_breakpoints > 0)
+ annotate_breakpoints_table ();
+@end smallexample
+
+This example, from the @code{print_one_breakpoint} function, shows how
+to produce the actual data for the table whose structure was defined
+in the above example. The original code was:
+
+@smallexample
+ annotate_record ();
+ annotate_field (0);
+ printf_filtered ("%-3d ", b->number);
+ annotate_field (1);
+ if ((int)b->type > (sizeof(bptypes)/sizeof(bptypes[0]))
+ || ((int) b->type != bptypes[(int) b->type].type))
+ internal_error ("bptypes table does not describe type #%d.",
+ (int)b->type);
+ printf_filtered ("%-14s ", bptypes[(int)b->type].description);
+ annotate_field (2);
+ printf_filtered ("%-4s ", bpdisps[(int)b->disposition]);
+ annotate_field (3);
+ printf_filtered ("%-3c ", bpenables[(int)b->enable]);
+ @dots{}
+@end smallexample
+
+This is the new version:
+
+@smallexample
+ annotate_record ();
+ ui_out_tuple_begin (uiout, "bkpt");
+ annotate_field (0);
+ ui_out_field_int (uiout, "number", b->number);
+ annotate_field (1);
+ if (((int) b->type > (sizeof (bptypes) / sizeof (bptypes[0])))
+ || ((int) b->type != bptypes[(int) b->type].type))
+ internal_error ("bptypes table does not describe type #%d.",
+ (int) b->type);
+ ui_out_field_string (uiout, "type", bptypes[(int)b->type].description);
+ annotate_field (2);
+ ui_out_field_string (uiout, "disp", bpdisps[(int)b->disposition]);
+ annotate_field (3);
+ ui_out_field_fmt (uiout, "enabled", "%c", bpenables[(int)b->enable]);
+ @dots{}
+@end smallexample
+
+This example, also from @code{print_one_breakpoint}, shows how to
+produce a complicated output field using the @code{print_expression}
+functions which requires a stream to be passed. It also shows how to
+automate stream destruction with cleanups. The original code was:
+
+@smallexample
+ annotate_field (5);
+ print_expression (b->exp, gdb_stdout);
+@end smallexample
+
+The new version is:
+
+@smallexample
+ struct ui_stream *stb = ui_out_stream_new (uiout);
+ struct cleanup *old_chain = make_cleanup_ui_out_stream_delete (stb);
+ ...
+ annotate_field (5);
+ print_expression (b->exp, stb->stream);
+ ui_out_field_stream (uiout, "what", local_stream);
+@end smallexample
+
+This example, also from @code{print_one_breakpoint}, shows how to use
+@code{ui_out_text} and @code{ui_out_field_string}. The original code
+was:
+
+@smallexample
+ annotate_field (5);
+ if (b->dll_pathname == NULL)
+ printf_filtered ("<any library> ");
+ else
+ printf_filtered ("library \"%s\" ", b->dll_pathname);
+@end smallexample
+
+It became:
+
+@smallexample
+ annotate_field (5);
+ if (b->dll_pathname == NULL)
+ @{
+ ui_out_field_string (uiout, "what", "<any library>");
+ ui_out_spaces (uiout, 1);
+ @}
+ else
+ @{
+ ui_out_text (uiout, "library \"");
+ ui_out_field_string (uiout, "what", b->dll_pathname);
+ ui_out_text (uiout, "\" ");
+ @}
+@end smallexample
+
+The following example from @code{print_one_breakpoint} shows how to
+use @code{ui_out_field_int} and @code{ui_out_spaces}. The original
+code was:
+
+@smallexample
+ annotate_field (5);
+ if (b->forked_inferior_pid != 0)
+ printf_filtered ("process %d ", b->forked_inferior_pid);
+@end smallexample
+
+It became:
+
+@smallexample
+ annotate_field (5);
+ if (b->forked_inferior_pid != 0)
+ @{
+ ui_out_text (uiout, "process ");
+ ui_out_field_int (uiout, "what", b->forked_inferior_pid);
+ ui_out_spaces (uiout, 1);
+ @}
+@end smallexample
+
+Here's an example of using @code{ui_out_field_string}. The original
+code was:
+
+@smallexample
+ annotate_field (5);
+ if (b->exec_pathname != NULL)
+ printf_filtered ("program \"%s\" ", b->exec_pathname);
+@end smallexample
+
+It became:
+
+@smallexample
+ annotate_field (5);
+ if (b->exec_pathname != NULL)
+ @{
+ ui_out_text (uiout, "program \"");
+ ui_out_field_string (uiout, "what", b->exec_pathname);
+ ui_out_text (uiout, "\" ");
+ @}
+@end smallexample
+
+Finally, here's an example of printing an address. The original code:
+
+@smallexample
+ annotate_field (4);
+ printf_filtered ("%s ",
+ local_hex_string_custom ((unsigned long) b->address, "08l"));
+@end smallexample
+
+It became:
+
+@smallexample
+ annotate_field (4);
+ ui_out_field_core_addr (uiout, "Address", b->address);
+@end smallexample
+
+
+@section Console Printing
+
+@section TUI
+
+@node libgdb
+
+@chapter libgdb
+
+@section libgdb 1.0
+@cindex @code{libgdb}
+@code{libgdb} 1.0 was an abortive project of years ago. The theory was
+to provide an API to @value{GDBN}'s functionality.
+
+@section libgdb 2.0
+@cindex @code{libgdb}
+@code{libgdb} 2.0 is an ongoing effort to update @value{GDBN} so that is
+better able to support graphical and other environments.
+
+Since @code{libgdb} development is on-going, its architecture is still
+evolving. The following components have so far been identified:
+
+@itemize @bullet
+@item
+Observer - @file{gdb-events.h}.
+@item
+Builder - @file{ui-out.h}
+@item
+Event Loop - @file{event-loop.h}
+@item
+Library - @file{gdb.h}
+@end itemize
+
+The model that ties these components together is described below.
+
+@section The @code{libgdb} Model
+
+A client of @code{libgdb} interacts with the library in two ways.
+
+@itemize @bullet
+@item
+As an observer (using @file{gdb-events}) receiving notifications from
+@code{libgdb} of any internal state changes (break point changes, run
+state, etc).
+@item
+As a client querying @code{libgdb} (using the @file{ui-out} builder) to
+obtain various status values from @value{GDBN}.
+@end itemize
+
+Since @code{libgdb} could have multiple clients (e.g. a GUI supporting
+the existing @value{GDBN} CLI), those clients must co-operate when
+controlling @code{libgdb}. In particular, a client must ensure that
+@code{libgdb} is idle (i.e. no other client is using @code{libgdb})
+before responding to a @file{gdb-event} by making a query.
+
+@section CLI support
+
+At present @value{GDBN}'s CLI is very much entangled in with the core of
+@code{libgdb}. Consequently, a client wishing to include the CLI in
+their interface needs to carefully co-ordinate its own and the CLI's
+requirements.
+
+It is suggested that the client set @code{libgdb} up to be bi-modal
+(alternate between CLI and client query modes). The notes below sketch
+out the theory:
+
+@itemize @bullet
+@item
+The client registers itself as an observer of @code{libgdb}.
+@item
+The client create and install @code{cli-out} builder using its own
+versions of the @code{ui-file} @code{gdb_stderr}, @code{gdb_stdtarg} and
+@code{gdb_stdout} streams.
+@item
+The client creates a separate custom @code{ui-out} builder that is only
+used while making direct queries to @code{libgdb}.
+@end itemize
+
+When the client receives input intended for the CLI, it simply passes it
+along. Since the @code{cli-out} builder is installed by default, all
+the CLI output in response to that command is routed (pronounced rooted)
+through to the client controlled @code{gdb_stdout} et.@: al.@: streams.
+At the same time, the client is kept abreast of internal changes by
+virtue of being a @code{libgdb} observer.
+
+The only restriction on the client is that it must wait until
+@code{libgdb} becomes idle before initiating any queries (using the
+client's custom builder).
+
+@section @code{libgdb} components
+
+@subheading Observer - @file{gdb-events.h}
+@file{gdb-events} provides the client with a very raw mechanism that can
+be used to implement an observer. At present it only allows for one
+observer and that observer must, internally, handle the need to delay
+the processing of any event notifications until after @code{libgdb} has
+finished the current command.
+
+@subheading Builder - @file{ui-out.h}
+@file{ui-out} provides the infrastructure necessary for a client to
+create a builder. That builder is then passed down to @code{libgdb}
+when doing any queries.
+
+@subheading Event Loop - @file{event-loop.h}
+@c There could be an entire section on the event-loop
+@file{event-loop}, currently non-re-entrant, provides a simple event
+loop. A client would need to either plug its self into this loop or,
+implement a new event-loop that GDB would use.
+
+The event-loop will eventually be made re-entrant. This is so that
+@value{GDB} can better handle the problem of some commands blocking
+instead of returning.
+
+@subheading Library - @file{gdb.h}
+@file{libgdb} is the most obvious component of this system. It provides
+the query interface. Each function is parameterized by a @code{ui-out}
+builder. The result of the query is constructed using that builder
+before the query function returns.
+
+@node Symbol Handling
+
+@chapter Symbol Handling
+
+Symbols are a key part of @value{GDBN}'s operation. Symbols include variables,
+functions, and types.
+
+@section Symbol Reading
+
+@cindex symbol reading
+@cindex reading of symbols
+@cindex symbol files
+@value{GDBN} reads symbols from @dfn{symbol files}. The usual symbol
+file is the file containing the program which @value{GDBN} is
+debugging. @value{GDBN} can be directed to use a different file for
+symbols (with the @samp{symbol-file} command), and it can also read
+more symbols via the @samp{add-file} and @samp{load} commands, or while
+reading symbols from shared libraries.
+
+@findex find_sym_fns
+Symbol files are initially opened by code in @file{symfile.c} using
+the BFD library (@pxref{Support Libraries}). BFD identifies the type
+of the file by examining its header. @code{find_sym_fns} then uses
+this identification to locate a set of symbol-reading functions.
+
+@findex add_symtab_fns
+@cindex @code{sym_fns} structure
+@cindex adding a symbol-reading module
+Symbol-reading modules identify themselves to @value{GDBN} by calling
+@code{add_symtab_fns} during their module initialization. The argument
+to @code{add_symtab_fns} is a @code{struct sym_fns} which contains the
+name (or name prefix) of the symbol format, the length of the prefix,
+and pointers to four functions. These functions are called at various
+times to process symbol files whose identification matches the specified
+prefix.
+
+The functions supplied by each module are:
+
+@table @code
+@item @var{xyz}_symfile_init(struct sym_fns *sf)
+
+@cindex secondary symbol file
+Called from @code{symbol_file_add} when we are about to read a new
+symbol file. This function should clean up any internal state (possibly
+resulting from half-read previous files, for example) and prepare to
+read a new symbol file. Note that the symbol file which we are reading
+might be a new ``main'' symbol file, or might be a secondary symbol file
+whose symbols are being added to the existing symbol table.
+
+The argument to @code{@var{xyz}_symfile_init} is a newly allocated
+@code{struct sym_fns} whose @code{bfd} field contains the BFD for the
+new symbol file being read. Its @code{private} field has been zeroed,
+and can be modified as desired. Typically, a struct of private
+information will be @code{malloc}'d, and a pointer to it will be placed
+in the @code{private} field.
+
+There is no result from @code{@var{xyz}_symfile_init}, but it can call
+@code{error} if it detects an unavoidable problem.
+
+@item @var{xyz}_new_init()
+
+Called from @code{symbol_file_add} when discarding existing symbols.
+This function needs only handle the symbol-reading module's internal
+state; the symbol table data structures visible to the rest of
+@value{GDBN} will be discarded by @code{symbol_file_add}. It has no
+arguments and no result. It may be called after
+@code{@var{xyz}_symfile_init}, if a new symbol table is being read, or
+may be called alone if all symbols are simply being discarded.
+
+@item @var{xyz}_symfile_read(struct sym_fns *sf, CORE_ADDR addr, int mainline)
+
+Called from @code{symbol_file_add} to actually read the symbols from a
+symbol-file into a set of psymtabs or symtabs.
+
+@code{sf} points to the @code{struct sym_fns} originally passed to
+@code{@var{xyz}_sym_init} for possible initialization. @code{addr} is
+the offset between the file's specified start address and its true
+address in memory. @code{mainline} is 1 if this is the main symbol
+table being read, and 0 if a secondary symbol file (e.g. shared library
+or dynamically loaded file) is being read.@refill
+@end table
+
+In addition, if a symbol-reading module creates psymtabs when
+@var{xyz}_symfile_read is called, these psymtabs will contain a pointer
+to a function @code{@var{xyz}_psymtab_to_symtab}, which can be called
+from any point in the @value{GDBN} symbol-handling code.
+
+@table @code
+@item @var{xyz}_psymtab_to_symtab (struct partial_symtab *pst)
+
+Called from @code{psymtab_to_symtab} (or the @code{PSYMTAB_TO_SYMTAB} macro) if
+the psymtab has not already been read in and had its @code{pst->symtab}
+pointer set. The argument is the psymtab to be fleshed-out into a
+symtab. Upon return, @code{pst->readin} should have been set to 1, and
+@code{pst->symtab} should contain a pointer to the new corresponding symtab, or
+zero if there were no symbols in that part of the symbol file.
+@end table
+
+@section Partial Symbol Tables
+
+@value{GDBN} has three types of symbol tables:
+
+@itemize @bullet
+@cindex full symbol table
+@cindex symtabs
+@item
+Full symbol tables (@dfn{symtabs}). These contain the main
+information about symbols and addresses.
+
+@cindex psymtabs
+@item
+Partial symbol tables (@dfn{psymtabs}). These contain enough
+information to know when to read the corresponding part of the full
+symbol table.
+
+@cindex minimal symbol table
+@cindex minsymtabs
+@item
+Minimal symbol tables (@dfn{msymtabs}). These contain information
+gleaned from non-debugging symbols.
+@end itemize
+
+@cindex partial symbol table
+This section describes partial symbol tables.
+
+A psymtab is constructed by doing a very quick pass over an executable
+file's debugging information. Small amounts of information are
+extracted---enough to identify which parts of the symbol table will
+need to be re-read and fully digested later, when the user needs the
+information. The speed of this pass causes @value{GDBN} to start up very
+quickly. Later, as the detailed rereading occurs, it occurs in small
+pieces, at various times, and the delay therefrom is mostly invisible to
+the user.
+@c (@xref{Symbol Reading}.)
+
+The symbols that show up in a file's psymtab should be, roughly, those
+visible to the debugger's user when the program is not running code from
+that file. These include external symbols and types, static symbols and
+types, and @code{enum} values declared at file scope.
+
+The psymtab also contains the range of instruction addresses that the
+full symbol table would represent.
+
+@cindex finding a symbol
+@cindex symbol lookup
+The idea is that there are only two ways for the user (or much of the
+code in the debugger) to reference a symbol:
+
+@itemize @bullet
+@findex find_pc_function
+@findex find_pc_line
+@item
+By its address (e.g. execution stops at some address which is inside a
+function in this file). The address will be noticed to be in the
+range of this psymtab, and the full symtab will be read in.
+@code{find_pc_function}, @code{find_pc_line}, and other
+@code{find_pc_@dots{}} functions handle this.
+
+@cindex lookup_symbol
+@item
+By its name
+(e.g. the user asks to print a variable, or set a breakpoint on a
+function). Global names and file-scope names will be found in the
+psymtab, which will cause the symtab to be pulled in. Local names will
+have to be qualified by a global name, or a file-scope name, in which
+case we will have already read in the symtab as we evaluated the
+qualifier. Or, a local symbol can be referenced when we are ``in'' a
+local scope, in which case the first case applies. @code{lookup_symbol}
+does most of the work here.
+@end itemize
+
+The only reason that psymtabs exist is to cause a symtab to be read in
+at the right moment. Any symbol that can be elided from a psymtab,
+while still causing that to happen, should not appear in it. Since
+psymtabs don't have the idea of scope, you can't put local symbols in
+them anyway. Psymtabs don't have the idea of the type of a symbol,
+either, so types need not appear, unless they will be referenced by
+name.
+
+It is a bug for @value{GDBN} to behave one way when only a psymtab has
+been read, and another way if the corresponding symtab has been read
+in. Such bugs are typically caused by a psymtab that does not contain
+all the visible symbols, or which has the wrong instruction address
+ranges.
+
+The psymtab for a particular section of a symbol file (objfile) could be
+thrown away after the symtab has been read in. The symtab should always
+be searched before the psymtab, so the psymtab will never be used (in a
+bug-free environment). Currently, psymtabs are allocated on an obstack,
+and all the psymbols themselves are allocated in a pair of large arrays
+on an obstack, so there is little to be gained by trying to free them
+unless you want to do a lot more work.
+
+@section Types
+
+@unnumberedsubsec Fundamental Types (e.g., @code{FT_VOID}, @code{FT_BOOLEAN}).
+
+@cindex fundamental types
+These are the fundamental types that @value{GDBN} uses internally. Fundamental
+types from the various debugging formats (stabs, ELF, etc) are mapped
+into one of these. They are basically a union of all fundamental types
+that @value{GDBN} knows about for all the languages that @value{GDBN}
+knows about.
+
+@unnumberedsubsec Type Codes (e.g., @code{TYPE_CODE_PTR}, @code{TYPE_CODE_ARRAY}).
+
+@cindex type codes
+Each time @value{GDBN} builds an internal type, it marks it with one
+of these types. The type may be a fundamental type, such as
+@code{TYPE_CODE_INT}, or a derived type, such as @code{TYPE_CODE_PTR}
+which is a pointer to another type. Typically, several @code{FT_*}
+types map to one @code{TYPE_CODE_*} type, and are distinguished by
+other members of the type struct, such as whether the type is signed
+or unsigned, and how many bits it uses.
+
+@unnumberedsubsec Builtin Types (e.g., @code{builtin_type_void}, @code{builtin_type_char}).
+
+These are instances of type structs that roughly correspond to
+fundamental types and are created as global types for @value{GDBN} to
+use for various ugly historical reasons. We eventually want to
+eliminate these. Note for example that @code{builtin_type_int}
+initialized in @file{gdbtypes.c} is basically the same as a
+@code{TYPE_CODE_INT} type that is initialized in @file{c-lang.c} for
+an @code{FT_INTEGER} fundamental type. The difference is that the
+@code{builtin_type} is not associated with any particular objfile, and
+only one instance exists, while @file{c-lang.c} builds as many
+@code{TYPE_CODE_INT} types as needed, with each one associated with
+some particular objfile.
+
+@section Object File Formats
+@cindex object file formats
+
+@subsection a.out
+
+@cindex @code{a.out} format
+The @code{a.out} format is the original file format for Unix. It
+consists of three sections: @code{text}, @code{data}, and @code{bss},
+which are for program code, initialized data, and uninitialized data,
+respectively.
+
+The @code{a.out} format is so simple that it doesn't have any reserved
+place for debugging information. (Hey, the original Unix hackers used
+@samp{adb}, which is a machine-language debugger!) The only debugging
+format for @code{a.out} is stabs, which is encoded as a set of normal
+symbols with distinctive attributes.
+
+The basic @code{a.out} reader is in @file{dbxread.c}.
+
+@subsection COFF
+
+@cindex COFF format
+The COFF format was introduced with System V Release 3 (SVR3) Unix.
+COFF files may have multiple sections, each prefixed by a header. The
+number of sections is limited.
+
+The COFF specification includes support for debugging. Although this
+was a step forward, the debugging information was woefully limited. For
+instance, it was not possible to represent code that came from an
+included file.
+
+The COFF reader is in @file{coffread.c}.
+
+@subsection ECOFF
+
+@cindex ECOFF format
+ECOFF is an extended COFF originally introduced for Mips and Alpha
+workstations.
+
+The basic ECOFF reader is in @file{mipsread.c}.
+
+@subsection XCOFF
+
+@cindex XCOFF format
+The IBM RS/6000 running AIX uses an object file format called XCOFF.
+The COFF sections, symbols, and line numbers are used, but debugging
+symbols are @code{dbx}-style stabs whose strings are located in the
+@code{.debug} section (rather than the string table). For more
+information, see @ref{Top,,,stabs,The Stabs Debugging Format}.
+
+The shared library scheme has a clean interface for figuring out what
+shared libraries are in use, but the catch is that everything which
+refers to addresses (symbol tables and breakpoints at least) needs to be
+relocated for both shared libraries and the main executable. At least
+using the standard mechanism this can only be done once the program has
+been run (or the core file has been read).
+
+@subsection PE
+
+@cindex PE-COFF format
+Windows 95 and NT use the PE (@dfn{Portable Executable}) format for their
+executables. PE is basically COFF with additional headers.
+
+While BFD includes special PE support, @value{GDBN} needs only the basic
+COFF reader.
+
+@subsection ELF
+
+@cindex ELF format
+The ELF format came with System V Release 4 (SVR4) Unix. ELF is similar
+to COFF in being organized into a number of sections, but it removes
+many of COFF's limitations.
+
+The basic ELF reader is in @file{elfread.c}.
+
+@subsection SOM
+
+@cindex SOM format
+SOM is HP's object file and debug format (not to be confused with IBM's
+SOM, which is a cross-language ABI).
+
+The SOM reader is in @file{hpread.c}.
+
+@subsection Other File Formats
+
+@cindex Netware Loadable Module format
+Other file formats that have been supported by @value{GDBN} include Netware
+Loadable Modules (@file{nlmread.c}).
+
+@section Debugging File Formats
+
+This section describes characteristics of debugging information that
+are independent of the object file format.
+
+@subsection stabs
+
+@cindex stabs debugging info
+@code{stabs} started out as special symbols within the @code{a.out}
+format. Since then, it has been encapsulated into other file
+formats, such as COFF and ELF.
+
+While @file{dbxread.c} does some of the basic stab processing,
+including for encapsulated versions, @file{stabsread.c} does
+the real work.
+
+@subsection COFF
+
+@cindex COFF debugging info
+The basic COFF definition includes debugging information. The level
+of support is minimal and non-extensible, and is not often used.
+
+@subsection Mips debug (Third Eye)
+
+@cindex ECOFF debugging info
+ECOFF includes a definition of a special debug format.
+
+The file @file{mdebugread.c} implements reading for this format.
+
+@subsection DWARF 1
+
+@cindex DWARF 1 debugging info
+DWARF 1 is a debugging format that was originally designed to be
+used with ELF in SVR4 systems.
+
+@c CHILL_PRODUCER
+@c GCC_PRODUCER
+@c GPLUS_PRODUCER
+@c LCC_PRODUCER
+@c If defined, these are the producer strings in a DWARF 1 file. All of
+@c these have reasonable defaults already.
+
+The DWARF 1 reader is in @file{dwarfread.c}.
+
+@subsection DWARF 2
+
+@cindex DWARF 2 debugging info
+DWARF 2 is an improved but incompatible version of DWARF 1.
+
+The DWARF 2 reader is in @file{dwarf2read.c}.
+
+@subsection SOM
+
+@cindex SOM debugging info
+Like COFF, the SOM definition includes debugging information.
+
+@section Adding a New Symbol Reader to @value{GDBN}
+
+@cindex adding debugging info reader
+If you are using an existing object file format (@code{a.out}, COFF, ELF, etc),
+there is probably little to be done.
+
+If you need to add a new object file format, you must first add it to
+BFD. This is beyond the scope of this document.
+
+You must then arrange for the BFD code to provide access to the
+debugging symbols. Generally @value{GDBN} will have to call swapping routines
+from BFD and a few other BFD internal routines to locate the debugging
+information. As much as possible, @value{GDBN} should not depend on the BFD
+internal data structures.
+
+For some targets (e.g., COFF), there is a special transfer vector used
+to call swapping routines, since the external data structures on various
+platforms have different sizes and layouts. Specialized routines that
+will only ever be implemented by one object file format may be called
+directly. This interface should be described in a file
+@file{bfd/lib@var{xyz}.h}, which is included by @value{GDBN}.
+
+
+@node Language Support
+
+@chapter Language Support
+
+@cindex language support
+@value{GDBN}'s language support is mainly driven by the symbol reader,
+although it is possible for the user to set the source language
+manually.
+
+@value{GDBN} chooses the source language by looking at the extension
+of the file recorded in the debug info; @file{.c} means C, @file{.f}
+means Fortran, etc. It may also use a special-purpose language
+identifier if the debug format supports it, like with DWARF.
+
+@section Adding a Source Language to @value{GDBN}
+
+@cindex adding source language
+To add other languages to @value{GDBN}'s expression parser, follow the
+following steps:
+
+@table @emph
+@item Create the expression parser.
+
+@cindex expression parser
+This should reside in a file @file{@var{lang}-exp.y}. Routines for
+building parsed expressions into a @code{union exp_element} list are in
+@file{parse.c}.
+
+@cindex language parser
+Since we can't depend upon everyone having Bison, and YACC produces
+parsers that define a bunch of global names, the following lines
+@strong{must} be included at the top of the YACC parser, to prevent the
+various parsers from defining the same global names:
+
+@smallexample
+#define yyparse @var{lang}_parse
+#define yylex @var{lang}_lex
+#define yyerror @var{lang}_error
+#define yylval @var{lang}_lval
+#define yychar @var{lang}_char
+#define yydebug @var{lang}_debug
+#define yypact @var{lang}_pact
+#define yyr1 @var{lang}_r1
+#define yyr2 @var{lang}_r2
+#define yydef @var{lang}_def
+#define yychk @var{lang}_chk
+#define yypgo @var{lang}_pgo
+#define yyact @var{lang}_act
+#define yyexca @var{lang}_exca
+#define yyerrflag @var{lang}_errflag
+#define yynerrs @var{lang}_nerrs
+@end smallexample
+
+At the bottom of your parser, define a @code{struct language_defn} and
+initialize it with the right values for your language. Define an
+@code{initialize_@var{lang}} routine and have it call
+@samp{add_language(@var{lang}_language_defn)} to tell the rest of @value{GDBN}
+that your language exists. You'll need some other supporting variables
+and functions, which will be used via pointers from your
+@code{@var{lang}_language_defn}. See the declaration of @code{struct
+language_defn} in @file{language.h}, and the other @file{*-exp.y} files,
+for more information.
+
+@item Add any evaluation routines, if necessary
+
+@cindex expression evaluation routines
+@findex evaluate_subexp
+@findex prefixify_subexp
+@findex length_of_subexp
+If you need new opcodes (that represent the operations of the language),
+add them to the enumerated type in @file{expression.h}. Add support
+code for these operations in the @code{evaluate_subexp} function
+defined in the file @file{eval.c}. Add cases
+for new opcodes in two functions from @file{parse.c}:
+@code{prefixify_subexp} and @code{length_of_subexp}. These compute
+the number of @code{exp_element}s that a given operation takes up.
+
+@item Update some existing code
+
+Add an enumerated identifier for your language to the enumerated type
+@code{enum language} in @file{defs.h}.
+
+Update the routines in @file{language.c} so your language is included.
+These routines include type predicates and such, which (in some cases)
+are language dependent. If your language does not appear in the switch
+statement, an error is reported.
+
+@vindex current_language
+Also included in @file{language.c} is the code that updates the variable
+@code{current_language}, and the routines that translate the
+@code{language_@var{lang}} enumerated identifier into a printable
+string.
+
+@findex _initialize_language
+Update the function @code{_initialize_language} to include your
+language. This function picks the default language upon startup, so is
+dependent upon which languages that @value{GDBN} is built for.
+
+@findex allocate_symtab
+Update @code{allocate_symtab} in @file{symfile.c} and/or symbol-reading
+code so that the language of each symtab (source file) is set properly.
+This is used to determine the language to use at each stack frame level.
+Currently, the language is set based upon the extension of the source
+file. If the language can be better inferred from the symbol
+information, please set the language of the symtab in the symbol-reading
+code.
+
+@findex print_subexp
+@findex op_print_tab
+Add helper code to @code{print_subexp} (in @file{expprint.c}) to handle any new
+expression opcodes you have added to @file{expression.h}. Also, add the
+printed representations of your operators to @code{op_print_tab}.
+
+@item Add a place of call
+
+@findex parse_exp_1
+Add a call to @code{@var{lang}_parse()} and @code{@var{lang}_error} in
+@code{parse_exp_1} (defined in @file{parse.c}).
+
+@item Use macros to trim code
+
+@cindex trimming language-dependent code
+The user has the option of building @value{GDBN} for some or all of the
+languages. If the user decides to build @value{GDBN} for the language
+@var{lang}, then every file dependent on @file{language.h} will have the
+macro @code{_LANG_@var{lang}} defined in it. Use @code{#ifdef}s to
+leave out large routines that the user won't need if he or she is not
+using your language.
+
+Note that you do not need to do this in your YACC parser, since if @value{GDBN}
+is not build for @var{lang}, then @file{@var{lang}-exp.tab.o} (the
+compiled form of your parser) is not linked into @value{GDBN} at all.
+
+See the file @file{configure.in} for how @value{GDBN} is configured
+for different languages.
+
+@item Edit @file{Makefile.in}
+
+Add dependencies in @file{Makefile.in}. Make sure you update the macro
+variables such as @code{HFILES} and @code{OBJS}, otherwise your code may
+not get linked in, or, worse yet, it may not get @code{tar}red into the
+distribution!
+@end table
+
+
+@node Host Definition
+
+@chapter Host Definition
+
+With the advent of Autoconf, it's rarely necessary to have host
+definition machinery anymore. The following information is provided,
+mainly, as an historical reference.
+
+@section Adding a New Host
+
+@cindex adding a new host
+@cindex host, adding
+@value{GDBN}'s host configuration support normally happens via Autoconf.
+New host-specific definitions should not be needed. Older hosts
+@value{GDBN} still use the host-specific definitions and files listed
+below, but these mostly exist for historical reasons, and will
+eventually disappear.
+
+@table @file
+@item gdb/config/@var{arch}/@var{xyz}.mh
+This file once contained both host and native configuration information
+(@pxref{Native Debugging}) for the machine @var{xyz}. The host
+configuration information is now handed by Autoconf.
+
+Host configuration information included a definition of
+@code{XM_FILE=xm-@var{xyz}.h} and possibly definitions for @code{CC},
+@code{SYSV_DEFINE}, @code{XM_CFLAGS}, @code{XM_ADD_FILES},
+@code{XM_CLIBS}, @code{XM_CDEPS}, etc.; see @file{Makefile.in}.
+
+New host only configurations do not need this file.
+
+@item gdb/config/@var{arch}/xm-@var{xyz}.h
+This file once contained definitions and includes required when hosting
+gdb on machine @var{xyz}. Those definitions and includes are now
+handled by Autoconf.
+
+New host and native configurations do not need this file.
+
+@emph{Maintainer's note: Some hosts continue to use the @file{xm-xyz.h}
+file to define the macros @var{HOST_FLOAT_FORMAT},
+@var{HOST_DOUBLE_FORMAT} and @var{HOST_LONG_DOUBLE_FORMAT}. That code
+also needs to be replaced with either an Autoconf or run-time test.}
+
+@end table
+
+@subheading Generic Host Support Files
+
+@cindex generic host support
+There are some ``generic'' versions of routines that can be used by
+various systems. These can be customized in various ways by macros
+defined in your @file{xm-@var{xyz}.h} file. If these routines work for
+the @var{xyz} host, you can just include the generic file's name (with
+@samp{.o}, not @samp{.c}) in @code{XDEPFILES}.
+
+Otherwise, if your machine needs custom support routines, you will need
+to write routines that perform the same functions as the generic file.
+Put them into @code{@var{xyz}-xdep.c}, and put @code{@var{xyz}-xdep.o}
+into @code{XDEPFILES}.
+
+@table @file
+@cindex remote debugging support
+@cindex serial line support
+@item ser-unix.c
+This contains serial line support for Unix systems. This is always
+included, via the makefile variable @code{SER_HARDWIRE}; override this
+variable in the @file{.mh} file to avoid it.
+
+@item ser-go32.c
+This contains serial line support for 32-bit programs running under DOS,
+using the DJGPP (a.k.a.@: GO32) execution environment.
+
+@cindex TCP remote support
+@item ser-tcp.c
+This contains generic TCP support using sockets.
+@end table
+
+@section Host Conditionals
+
+When @value{GDBN} is configured and compiled, various macros are
+defined or left undefined, to control compilation based on the
+attributes of the host system. These macros and their meanings (or if
+the meaning is not documented here, then one of the source files where
+they are used is indicated) are:
+
+@ftable @code
+@item @value{GDBN}INIT_FILENAME
+The default name of @value{GDBN}'s initialization file (normally
+@file{.gdbinit}).
+
+@item NO_STD_REGS
+This macro is deprecated.
+
+@item NO_SYS_FILE
+Define this if your system does not have a @code{<sys/file.h>}.
+
+@item SIGWINCH_HANDLER
+If your host defines @code{SIGWINCH}, you can define this to be the name
+of a function to be called if @code{SIGWINCH} is received.
+
+@item SIGWINCH_HANDLER_BODY
+Define this to expand into code that will define the function named by
+the expansion of @code{SIGWINCH_HANDLER}.
+
+@item ALIGN_STACK_ON_STARTUP
+@cindex stack alignment
+Define this if your system is of a sort that will crash in
+@code{tgetent} if the stack happens not to be longword-aligned when
+@code{main} is called. This is a rare situation, but is known to occur
+on several different types of systems.
+
+@item CRLF_SOURCE_FILES
+@cindex DOS text files
+Define this if host files use @code{\r\n} rather than @code{\n} as a
+line terminator. This will cause source file listings to omit @code{\r}
+characters when printing and it will allow @code{\r\n} line endings of files
+which are ``sourced'' by gdb. It must be possible to open files in binary
+mode using @code{O_BINARY} or, for fopen, @code{"rb"}.
+
+@item DEFAULT_PROMPT
+@cindex prompt
+The default value of the prompt string (normally @code{"(gdb) "}).
+
+@item DEV_TTY
+@cindex terminal device
+The name of the generic TTY device, defaults to @code{"/dev/tty"}.
+
+@item FCLOSE_PROVIDED
+Define this if the system declares @code{fclose} in the headers included
+in @code{defs.h}. This isn't needed unless your compiler is unusually
+anal.
+
+@item FOPEN_RB
+Define this if binary files are opened the same way as text files.
+
+@item GETENV_PROVIDED
+Define this if the system declares @code{getenv} in its headers included
+in @code{defs.h}. This isn't needed unless your compiler is unusually
+anal.
+
+@item HAVE_MMAP
+@findex mmap
+In some cases, use the system call @code{mmap} for reading symbol
+tables. For some machines this allows for sharing and quick updates.
+
+@item HAVE_TERMIO
+Define this if the host system has @code{termio.h}.
+
+@item INT_MAX
+@itemx INT_MIN
+@itemx LONG_MAX
+@itemx UINT_MAX
+@itemx ULONG_MAX
+Values for host-side constants.
+
+@item ISATTY
+Substitute for isatty, if not available.
+
+@item LONGEST
+This is the longest integer type available on the host. If not defined,
+it will default to @code{long long} or @code{long}, depending on
+@code{CC_HAS_LONG_LONG}.
+
+@item CC_HAS_LONG_LONG
+@cindex @code{long long} data type
+Define this if the host C compiler supports @code{long long}. This is set
+by the @code{configure} script.
+
+@item PRINTF_HAS_LONG_LONG
+Define this if the host can handle printing of long long integers via
+the printf format conversion specifier @code{ll}. This is set by the
+@code{configure} script.
+
+@item HAVE_LONG_DOUBLE
+Define this if the host C compiler supports @code{long double}. This is
+set by the @code{configure} script.
+
+@item PRINTF_HAS_LONG_DOUBLE
+Define this if the host can handle printing of long double float-point
+numbers via the printf format conversion specifier @code{Lg}. This is
+set by the @code{configure} script.
+
+@item SCANF_HAS_LONG_DOUBLE
+Define this if the host can handle the parsing of long double
+float-point numbers via the scanf format conversion specifier
+@code{Lg}. This is set by the @code{configure} script.
+
+@item LSEEK_NOT_LINEAR
+Define this if @code{lseek (n)} does not necessarily move to byte number
+@code{n} in the file. This is only used when reading source files. It
+is normally faster to define @code{CRLF_SOURCE_FILES} when possible.
+
+@item L_SET
+This macro is used as the argument to @code{lseek} (or, most commonly,
+@code{bfd_seek}). FIXME, should be replaced by SEEK_SET instead,
+which is the POSIX equivalent.
+
+@item MMAP_BASE_ADDRESS
+When using HAVE_MMAP, the first mapping should go at this address.
+
+@item MMAP_INCREMENT
+when using HAVE_MMAP, this is the increment between mappings.
+
+@item NORETURN
+If defined, this should be one or more tokens, such as @code{volatile},
+that can be used in both the declaration and definition of functions to
+indicate that they never return. The default is already set correctly
+if compiling with GCC. This will almost never need to be defined.
+
+@item ATTR_NORETURN
+If defined, this should be one or more tokens, such as
+@code{__attribute__ ((noreturn))}, that can be used in the declarations
+of functions to indicate that they never return. The default is already
+set correctly if compiling with GCC. This will almost never need to be
+defined.
+
+@item USE_GENERIC_DUMMY_FRAMES
+@cindex generic dummy frames
+Define this to 1 if the target is using the generic inferior function
+call code. See @code{blockframe.c} for more information.
+
+@item USE_MMALLOC
+@findex mmalloc
+@value{GDBN} will use the @code{mmalloc} library for memory allocation
+for symbol reading if this symbol is defined. Be careful defining it
+since there are systems on which @code{mmalloc} does not work for some
+reason. One example is the DECstation, where its RPC library can't
+cope with our redefinition of @code{malloc} to call @code{mmalloc}.
+When defining @code{USE_MMALLOC}, you will also have to set
+@code{MMALLOC} in the Makefile, to point to the @code{mmalloc} library. This
+define is set when you configure with @samp{--with-mmalloc}.
+
+@item NO_MMCHECK
+@findex mmcheck
+Define this if you are using @code{mmalloc}, but don't want the overhead
+of checking the heap with @code{mmcheck}. Note that on some systems,
+the C runtime makes calls to @code{malloc} prior to calling @code{main}, and if
+@code{free} is ever called with these pointers after calling
+@code{mmcheck} to enable checking, a memory corruption abort is certain
+to occur. These systems can still use @code{mmalloc}, but must define
+@code{NO_MMCHECK}.
+
+@item MMCHECK_FORCE
+Define this to 1 if the C runtime allocates memory prior to
+@code{mmcheck} being called, but that memory is never freed so we don't
+have to worry about it triggering a memory corruption abort. The
+default is 0, which means that @code{mmcheck} will only install the heap
+checking functions if there has not yet been any memory allocation
+calls, and if it fails to install the functions, @value{GDBN} will issue a
+warning. This is currently defined if you configure using
+@samp{--with-mmalloc}.
+
+@item NO_SIGINTERRUPT
+@findex siginterrupt
+Define this to indicate that @code{siginterrupt} is not available.
+
+@item SEEK_CUR
+@itemx SEEK_SET
+Define these to appropriate value for the system @code{lseek}, if not already
+defined.
+
+@item STOP_SIGNAL
+This is the signal for stopping @value{GDBN}. Defaults to
+@code{SIGTSTP}. (Only redefined for the Convex.)
+
+@item USE_O_NOCTTY
+Define this if the interior's tty should be opened with the @code{O_NOCTTY}
+flag. (FIXME: This should be a native-only flag, but @file{inflow.c} is
+always linked in.)
+
+@item USG
+Means that System V (prior to SVR4) include files are in use. (FIXME:
+This symbol is abused in @file{infrun.c}, @file{regex.c},
+@file{remote-nindy.c}, and @file{utils.c} for other things, at the
+moment.)
+
+@item lint
+Define this to help placate @code{lint} in some situations.
+
+@item volatile
+Define this to override the defaults of @code{__volatile__} or
+@code{/**/}.
+@end ftable
+
+
+@node Target Architecture Definition
+
+@chapter Target Architecture Definition
+
+@cindex target architecture definition
+@value{GDBN}'s target architecture defines what sort of
+machine-language programs @value{GDBN} can work with, and how it works
+with them.
+
+The target architecture object is implemented as the C structure
+@code{struct gdbarch *}. The structure, and its methods, are generated
+using the Bourne shell script @file{gdbarch.sh}.
+
+@section Operating System ABI Variant Handling
+@cindex OS ABI variants
+
+@value{GDBN} provides a mechanism for handling variations in OS
+ABIs. An OS ABI variant may have influence over any number of
+variables in the target architecture definition. There are two major
+components in the OS ABI mechanism: sniffers and handlers.
+
+A @dfn{sniffer} examines a file matching a BFD architecture/flavour pair
+(the architecture may be wildcarded) in an attempt to determine the
+OS ABI of that file. Sniffers with a wildcarded architecture are considered
+to be @dfn{generic}, while sniffers for a specific architecture are
+considered to be @dfn{specific}. A match from a specific sniffer
+overrides a match from a generic sniffer. Multiple sniffers for an
+architecture/flavour may exist, in order to differentiate between two
+different operating systems which use the same basic file format. The
+OS ABI framework provides a generic sniffer for ELF-format files which
+examines the @code{EI_OSABI} field of the ELF header, as well as note
+sections known to be used by several operating systems.
+
+@cindex fine-tuning @code{gdbarch} structure
+A @dfn{handler} is used to fine-tune the @code{gdbarch} structure for the
+selected OS ABI. There may be only one handler for a given OS ABI
+for each BFD architecture.
+
+The following OS ABI variants are defined in @file{osabi.h}:
+
+@table @code
+
+@findex GDB_OSABI_UNKNOWN
+@item GDB_OSABI_UNKNOWN
+The ABI of the inferior is unknown. The default @code{gdbarch}
+settings for the architecture will be used.
+
+@findex GDB_OSABI_SVR4
+@item GDB_OSABI_SVR4
+UNIX System V Release 4
+
+@findex GDB_OSABI_HURD
+@item GDB_OSABI_HURD
+GNU using the Hurd kernel
+
+@findex GDB_OSABI_SOLARIS
+@item GDB_OSABI_SOLARIS
+Sun Solaris
+
+@findex GDB_OSABI_OSF1
+@item GDB_OSABI_OSF1
+OSF/1, including Digital UNIX and Compaq Tru64 UNIX
+
+@findex GDB_OSABI_LINUX
+@item GDB_OSABI_LINUX
+GNU using the Linux kernel
+
+@findex GDB_OSABI_FREEBSD_AOUT
+@item GDB_OSABI_FREEBSD_AOUT
+FreeBSD using the a.out executable format
+
+@findex GDB_OSABI_FREEBSD_ELF
+@item GDB_OSABI_FREEBSD_ELF
+FreeBSD using the ELF executable format
+
+@findex GDB_OSABI_NETBSD_AOUT
+@item GDB_OSABI_NETBSD_AOUT
+NetBSD using the a.out executable format
+
+@findex GDB_OSABI_NETBSD_ELF
+@item GDB_OSABI_NETBSD_ELF
+NetBSD using the ELF executable format
+
+@findex GDB_OSABI_WINCE
+@item GDB_OSABI_WINCE
+Windows CE
+
+@findex GDB_OSABI_ARM_EABI_V1
+@item GDB_OSABI_ARM_EABI_V1
+ARM Embedded ABI version 1
+
+@findex GDB_OSABI_ARM_EABI_V2
+@item GDB_OSABI_ARM_EABI_V2
+ARM Embedded ABI version 2
+
+@findex GDB_OSABI_ARM_APCS
+@item GDB_OSABI_ARM_APCS
+Generic ARM Procedure Call Standard
+
+@end table
+
+Here are the functions that make up the OS ABI framework:
+
+@deftypefun const char *gdbarch_osabi_name (enum gdb_osabi @var{osabi})
+Return the name of the OS ABI corresponding to @var{osabi}.
+@end deftypefun
+
+@deftypefun void gdbarch_register_osabi (enum bfd_architecture @var{arch}, enum gdb_osabi @var{osabi}, void (*@var{init_osabi})(struct gdbarch_info @var{info}, struct gdbarch *@var{gdbarch}))
+Register the OS ABI handler specified by @var{init_osabi} for the
+architecture/OS ABI pair specified by @var{arch} and @var{osabi}.
+@end deftypefun
+
+@deftypefun void gdbarch_register_osabi_sniffer (enum bfd_architecture @var{arch}, enum bfd_flavour @var{flavour}, enum gdb_osabi (*@var{sniffer})(bfd *@var{abfd}))
+Register the OS ABI file sniffer specified by @var{sniffer} for the
+BFD architecture/flavour pair specified by @var{arch} and @var{flavour}.
+If @var{arch} is @code{bfd_arch_unknown}, the sniffer is considered to
+be generic, and is allowed to examine @var{flavour}-flavoured files for
+any architecture.
+@end deftypefun
+
+@deftypefun enum gdb_osabi gdbarch_lookup_osabi (bfd *@var{abfd})
+Examine the file described by @var{abfd} to determine its OS ABI.
+The value @code{GDB_OSABI_UNKNOWN} is returned if the OS ABI cannot
+be determined.
+@end deftypefun
+
+@deftypefun void gdbarch_init_osabi (struct gdbarch info @var{info}, struct gdbarch *@var{gdbarch}, enum gdb_osabi @var{osabi})
+Invoke the OS ABI handler corresponding to @var{osabi} to fine-tune the
+@code{gdbarch} structure specified by @var{gdbarch}. If a handler
+corresponding to @var{osabi} has not been registered for @var{gdbarch}'s
+architecture, a warning will be issued and the debugging session will continue
+with the defaults already established for @var{gdbarch}.
+@end deftypefun
+
+@section Registers and Memory
+
+@value{GDBN}'s model of the target machine is rather simple.
+@value{GDBN} assumes the machine includes a bank of registers and a
+block of memory. Each register may have a different size.
+
+@value{GDBN} does not have a magical way to match up with the
+compiler's idea of which registers are which; however, it is critical
+that they do match up accurately. The only way to make this work is
+to get accurate information about the order that the compiler uses,
+and to reflect that in the @code{REGISTER_NAME} and related macros.
+
+@value{GDBN} can handle big-endian, little-endian, and bi-endian architectures.
+
+@section Pointers Are Not Always Addresses
+@cindex pointer representation
+@cindex address representation
+@cindex word-addressed machines
+@cindex separate data and code address spaces
+@cindex spaces, separate data and code address
+@cindex address spaces, separate data and code
+@cindex code pointers, word-addressed
+@cindex converting between pointers and addresses
+@cindex D10V addresses
+
+On almost all 32-bit architectures, the representation of a pointer is
+indistinguishable from the representation of some fixed-length number
+whose value is the byte address of the object pointed to. On such
+machines, the words ``pointer'' and ``address'' can be used interchangeably.
+However, architectures with smaller word sizes are often cramped for
+address space, so they may choose a pointer representation that breaks this
+identity, and allows a larger code address space.
+
+For example, the Mitsubishi D10V is a 16-bit VLIW processor whose
+instructions are 32 bits long@footnote{Some D10V instructions are
+actually pairs of 16-bit sub-instructions. However, since you can't
+jump into the middle of such a pair, code addresses can only refer to
+full 32 bit instructions, which is what matters in this explanation.}.
+If the D10V used ordinary byte addresses to refer to code locations,
+then the processor would only be able to address 64kb of instructions.
+However, since instructions must be aligned on four-byte boundaries, the
+low two bits of any valid instruction's byte address are always
+zero---byte addresses waste two bits. So instead of byte addresses,
+the D10V uses word addresses---byte addresses shifted right two bits---to
+refer to code. Thus, the D10V can use 16-bit words to address 256kb of
+code space.
+
+However, this means that code pointers and data pointers have different
+forms on the D10V. The 16-bit word @code{0xC020} refers to byte address
+@code{0xC020} when used as a data address, but refers to byte address
+@code{0x30080} when used as a code address.
+
+(The D10V also uses separate code and data address spaces, which also
+affects the correspondence between pointers and addresses, but we're
+going to ignore that here; this example is already too long.)
+
+To cope with architectures like this---the D10V is not the only
+one!---@value{GDBN} tries to distinguish between @dfn{addresses}, which are
+byte numbers, and @dfn{pointers}, which are the target's representation
+of an address of a particular type of data. In the example above,
+@code{0xC020} is the pointer, which refers to one of the addresses
+@code{0xC020} or @code{0x30080}, depending on the type imposed upon it.
+@value{GDBN} provides functions for turning a pointer into an address
+and vice versa, in the appropriate way for the current architecture.
+
+Unfortunately, since addresses and pointers are identical on almost all
+processors, this distinction tends to bit-rot pretty quickly. Thus,
+each time you port @value{GDBN} to an architecture which does
+distinguish between pointers and addresses, you'll probably need to
+clean up some architecture-independent code.
+
+Here are functions which convert between pointers and addresses:
+
+@deftypefun CORE_ADDR extract_typed_address (void *@var{buf}, struct type *@var{type})
+Treat the bytes at @var{buf} as a pointer or reference of type
+@var{type}, and return the address it represents, in a manner
+appropriate for the current architecture. This yields an address
+@value{GDBN} can use to read target memory, disassemble, etc. Note that
+@var{buf} refers to a buffer in @value{GDBN}'s memory, not the
+inferior's.
+
+For example, if the current architecture is the Intel x86, this function
+extracts a little-endian integer of the appropriate length from
+@var{buf} and returns it. However, if the current architecture is the
+D10V, this function will return a 16-bit integer extracted from
+@var{buf}, multiplied by four if @var{type} is a pointer to a function.
+
+If @var{type} is not a pointer or reference type, then this function
+will signal an internal error.
+@end deftypefun
+
+@deftypefun CORE_ADDR store_typed_address (void *@var{buf}, struct type *@var{type}, CORE_ADDR @var{addr})
+Store the address @var{addr} in @var{buf}, in the proper format for a
+pointer of type @var{type} in the current architecture. Note that
+@var{buf} refers to a buffer in @value{GDBN}'s memory, not the
+inferior's.
+
+For example, if the current architecture is the Intel x86, this function
+stores @var{addr} unmodified as a little-endian integer of the
+appropriate length in @var{buf}. However, if the current architecture
+is the D10V, this function divides @var{addr} by four if @var{type} is
+a pointer to a function, and then stores it in @var{buf}.
+
+If @var{type} is not a pointer or reference type, then this function
+will signal an internal error.
+@end deftypefun
+
+@deftypefun CORE_ADDR value_as_address (struct value *@var{val})
+Assuming that @var{val} is a pointer, return the address it represents,
+as appropriate for the current architecture.
+
+This function actually works on integral values, as well as pointers.
+For pointers, it performs architecture-specific conversions as
+described above for @code{extract_typed_address}.
+@end deftypefun
+
+@deftypefun CORE_ADDR value_from_pointer (struct type *@var{type}, CORE_ADDR @var{addr})
+Create and return a value representing a pointer of type @var{type} to
+the address @var{addr}, as appropriate for the current architecture.
+This function performs architecture-specific conversions as described
+above for @code{store_typed_address}.
+@end deftypefun
+
+
+@value{GDBN} also provides functions that do the same tasks, but assume
+that pointers are simply byte addresses; they aren't sensitive to the
+current architecture, beyond knowing the appropriate endianness.
+
+@deftypefun CORE_ADDR extract_address (void *@var{addr}, int len)
+Extract a @var{len}-byte number from @var{addr} in the appropriate
+endianness for the current architecture, and return it. Note that
+@var{addr} refers to @value{GDBN}'s memory, not the inferior's.
+
+This function should only be used in architecture-specific code; it
+doesn't have enough information to turn bits into a true address in the
+appropriate way for the current architecture. If you can, use
+@code{extract_typed_address} instead.
+@end deftypefun
+
+@deftypefun void store_address (void *@var{addr}, int @var{len}, LONGEST @var{val})
+Store @var{val} at @var{addr} as a @var{len}-byte integer, in the
+appropriate endianness for the current architecture. Note that
+@var{addr} refers to a buffer in @value{GDBN}'s memory, not the
+inferior's.
+
+This function should only be used in architecture-specific code; it
+doesn't have enough information to turn a true address into bits in the
+appropriate way for the current architecture. If you can, use
+@code{store_typed_address} instead.
+@end deftypefun
+
+
+Here are some macros which architectures can define to indicate the
+relationship between pointers and addresses. These have default
+definitions, appropriate for architectures on which all pointers are
+simple unsigned byte addresses.
+
+@deftypefn {Target Macro} CORE_ADDR POINTER_TO_ADDRESS (struct type *@var{type}, char *@var{buf})
+Assume that @var{buf} holds a pointer of type @var{type}, in the
+appropriate format for the current architecture. Return the byte
+address the pointer refers to.
+
+This function may safely assume that @var{type} is either a pointer or a
+C@t{++} reference type.
+@end deftypefn
+
+@deftypefn {Target Macro} void ADDRESS_TO_POINTER (struct type *@var{type}, char *@var{buf}, CORE_ADDR @var{addr})
+Store in @var{buf} a pointer of type @var{type} representing the address
+@var{addr}, in the appropriate format for the current architecture.
+
+This function may safely assume that @var{type} is either a pointer or a
+C@t{++} reference type.
+@end deftypefn
+
+
+@section Raw and Virtual Register Representations
+@cindex raw register representation
+@cindex virtual register representation
+@cindex representations, raw and virtual registers
+
+@emph{Maintainer note: This section is pretty much obsolete. The
+functionality described here has largely been replaced by
+pseudo-registers and the mechanisms described in @ref{Target
+Architecture Definition, , Using Different Register and Memory Data
+Representations}. See also @uref{http://www.gnu.org/software/gdb/bugs/,
+Bug Tracking Database} and
+@uref{http://sources.redhat.com/gdb/current/ari/, ARI Index} for more
+up-to-date information.}
+
+Some architectures use one representation for a value when it lives in a
+register, but use a different representation when it lives in memory.
+In @value{GDBN}'s terminology, the @dfn{raw} representation is the one used in
+the target registers, and the @dfn{virtual} representation is the one
+used in memory, and within @value{GDBN} @code{struct value} objects.
+
+@emph{Maintainer note: Notice that the same mechanism is being used to
+both convert a register to a @code{struct value} and alternative
+register forms.}
+
+For almost all data types on almost all architectures, the virtual and
+raw representations are identical, and no special handling is needed.
+However, they do occasionally differ. For example:
+
+@itemize @bullet
+@item
+The x86 architecture supports an 80-bit @code{long double} type. However, when
+we store those values in memory, they occupy twelve bytes: the
+floating-point number occupies the first ten, and the final two bytes
+are unused. This keeps the values aligned on four-byte boundaries,
+allowing more efficient access. Thus, the x86 80-bit floating-point
+type is the raw representation, and the twelve-byte loosely-packed
+arrangement is the virtual representation.
+
+@item
+Some 64-bit MIPS targets present 32-bit registers to @value{GDBN} as 64-bit
+registers, with garbage in their upper bits. @value{GDBN} ignores the top 32
+bits. Thus, the 64-bit form, with garbage in the upper 32 bits, is the
+raw representation, and the trimmed 32-bit representation is the
+virtual representation.
+@end itemize
+
+In general, the raw representation is determined by the architecture, or
+@value{GDBN}'s interface to the architecture, while the virtual representation
+can be chosen for @value{GDBN}'s convenience. @value{GDBN}'s register file,
+@code{registers}, holds the register contents in raw format, and the
+@value{GDBN} remote protocol transmits register values in raw format.
+
+Your architecture may define the following macros to request
+conversions between the raw and virtual format:
+
+@deftypefn {Target Macro} int REGISTER_CONVERTIBLE (int @var{reg})
+Return non-zero if register number @var{reg}'s value needs different raw
+and virtual formats.
+
+You should not use @code{REGISTER_CONVERT_TO_VIRTUAL} for a register
+unless this macro returns a non-zero value for that register.
+@end deftypefn
+
+@deftypefn {Target Macro} int REGISTER_RAW_SIZE (int @var{reg})
+The size of register number @var{reg}'s raw value. This is the number
+of bytes the register will occupy in @code{registers}, or in a @value{GDBN}
+remote protocol packet.
+@end deftypefn
+
+@deftypefn {Target Macro} int REGISTER_VIRTUAL_SIZE (int @var{reg})
+The size of register number @var{reg}'s value, in its virtual format.
+This is the size a @code{struct value}'s buffer will have, holding that
+register's value.
+@end deftypefn
+
+@deftypefn {Target Macro} struct type *REGISTER_VIRTUAL_TYPE (int @var{reg})
+This is the type of the virtual representation of register number
+@var{reg}. Note that there is no need for a macro giving a type for the
+register's raw form; once the register's value has been obtained, @value{GDBN}
+always uses the virtual form.
+@end deftypefn
+
+@deftypefn {Target Macro} void REGISTER_CONVERT_TO_VIRTUAL (int @var{reg}, struct type *@var{type}, char *@var{from}, char *@var{to})
+Convert the value of register number @var{reg} to @var{type}, which
+should always be @code{REGISTER_VIRTUAL_TYPE (@var{reg})}. The buffer
+at @var{from} holds the register's value in raw format; the macro should
+convert the value to virtual format, and place it at @var{to}.
+
+Note that @code{REGISTER_CONVERT_TO_VIRTUAL} and
+@code{REGISTER_CONVERT_TO_RAW} take their @var{reg} and @var{type}
+arguments in different orders.
+
+You should only use @code{REGISTER_CONVERT_TO_VIRTUAL} with registers
+for which the @code{REGISTER_CONVERTIBLE} macro returns a non-zero
+value.
+@end deftypefn
+
+@deftypefn {Target Macro} void REGISTER_CONVERT_TO_RAW (struct type *@var{type}, int @var{reg}, char *@var{from}, char *@var{to})
+Convert the value of register number @var{reg} to @var{type}, which
+should always be @code{REGISTER_VIRTUAL_TYPE (@var{reg})}. The buffer
+at @var{from} holds the register's value in raw format; the macro should
+convert the value to virtual format, and place it at @var{to}.
+
+Note that REGISTER_CONVERT_TO_VIRTUAL and REGISTER_CONVERT_TO_RAW take
+their @var{reg} and @var{type} arguments in different orders.
+@end deftypefn
+
+
+@section Using Different Register and Memory Data Representations
+@cindex register representation
+@cindex memory representation
+@cindex representations, register and memory
+@cindex register data formats, converting
+@cindex @code{struct value}, converting register contents to
+
+@emph{Maintainer's note: The way GDB manipulates registers is undergoing
+significant change. Many of the macros and functions refered to in this
+section are likely to be subject to further revision. See
+@uref{http://sources.redhat.com/gdb/current/ari/, A.R. Index} and
+@uref{http://www.gnu.org/software/gdb/bugs, Bug Tracking Database} for
+further information. cagney/2002-05-06.}
+
+Some architectures can represent a data object in a register using a
+form that is different to the objects more normal memory representation.
+For example:
+
+@itemize @bullet
+
+@item
+The Alpha architecture can represent 32 bit integer values in
+floating-point registers.
+
+@item
+The x86 architecture supports 80-bit floating-point registers. The
+@code{long double} data type occupies 96 bits in memory but only 80 bits
+when stored in a register.
+
+@end itemize
+
+In general, the register representation of a data type is determined by
+the architecture, or @value{GDBN}'s interface to the architecture, while
+the memory representation is determined by the Application Binary
+Interface.
+
+For almost all data types on almost all architectures, the two
+representations are identical, and no special handling is needed.
+However, they do occasionally differ. Your architecture may define the
+following macros to request conversions between the register and memory
+representations of a data type:
+
+@deftypefn {Target Macro} int CONVERT_REGISTER_P (int @var{reg})
+Return non-zero if the representation of a data value stored in this
+register may be different to the representation of that same data value
+when stored in memory.
+
+When non-zero, the macros @code{REGISTER_TO_VALUE} and
+@code{VALUE_TO_REGISTER} are used to perform any necessary conversion.
+@end deftypefn
+
+@deftypefn {Target Macro} void REGISTER_TO_VALUE (int @var{reg}, struct type *@var{type}, char *@var{from}, char *@var{to})
+Convert the value of register number @var{reg} to a data object of type
+@var{type}. The buffer at @var{from} holds the register's value in raw
+format; the converted value should be placed in the buffer at @var{to}.
+
+Note that @code{REGISTER_TO_VALUE} and @code{VALUE_TO_REGISTER} take
+their @var{reg} and @var{type} arguments in different orders.
+
+You should only use @code{REGISTER_TO_VALUE} with registers for which
+the @code{CONVERT_REGISTER_P} macro returns a non-zero value.
+@end deftypefn
+
+@deftypefn {Target Macro} void VALUE_TO_REGISTER (struct type *@var{type}, int @var{reg}, char *@var{from}, char *@var{to})
+Convert a data value of type @var{type} to register number @var{reg}'
+raw format.
+
+Note that @code{REGISTER_TO_VALUE} and @code{VALUE_TO_REGISTER} take
+their @var{reg} and @var{type} arguments in different orders.
+
+You should only use @code{VALUE_TO_REGISTER} with registers for which
+the @code{CONVERT_REGISTER_P} macro returns a non-zero value.
+@end deftypefn
+
+@deftypefn {Target Macro} void REGISTER_CONVERT_TO_TYPE (int @var{regnum}, struct type *@var{type}, char *@var{buf})
+See @file{mips-tdep.c}. It does not do what you want.
+@end deftypefn
+
+
+@section Frame Interpretation
+
+@section Inferior Call Setup
+
+@section Compiler Characteristics
+
+@section Target Conditionals
+
+This section describes the macros that you can use to define the target
+machine.
+
+@table @code
+
+@item ADDITIONAL_OPTIONS
+@itemx ADDITIONAL_OPTION_CASES
+@itemx ADDITIONAL_OPTION_HANDLER
+@itemx ADDITIONAL_OPTION_HELP
+@findex ADDITIONAL_OPTION_HELP
+@findex ADDITIONAL_OPTION_HANDLER
+@findex ADDITIONAL_OPTION_CASES
+@findex ADDITIONAL_OPTIONS
+These are a set of macros that allow the addition of additional command
+line options to @value{GDBN}. They are currently used only for the unsupported
+i960 Nindy target, and should not be used in any other configuration.
+
+@item ADDR_BITS_REMOVE (addr)
+@findex ADDR_BITS_REMOVE
+If a raw machine instruction address includes any bits that are not
+really part of the address, then define this macro to expand into an
+expression that zeroes those bits in @var{addr}. This is only used for
+addresses of instructions, and even then not in all contexts.
+
+For example, the two low-order bits of the PC on the Hewlett-Packard PA
+2.0 architecture contain the privilege level of the corresponding
+instruction. Since instructions must always be aligned on four-byte
+boundaries, the processor masks out these bits to generate the actual
+address of the instruction. ADDR_BITS_REMOVE should filter out these
+bits with an expression such as @code{((addr) & ~3)}.
+
+@item ADDRESS_TO_POINTER (@var{type}, @var{buf}, @var{addr})
+@findex ADDRESS_TO_POINTER
+Store in @var{buf} a pointer of type @var{type} representing the address
+@var{addr}, in the appropriate format for the current architecture.
+This macro may safely assume that @var{type} is either a pointer or a
+C@t{++} reference type.
+@xref{Target Architecture Definition, , Pointers Are Not Always Addresses}.
+
+@item BEFORE_MAIN_LOOP_HOOK
+@findex BEFORE_MAIN_LOOP_HOOK
+Define this to expand into any code that you want to execute before the
+main loop starts. Although this is not, strictly speaking, a target
+conditional, that is how it is currently being used. Note that if a
+configuration were to define it one way for a host and a different way
+for the target, @value{GDBN} will probably not compile, let alone run
+correctly. This macro is currently used only for the unsupported i960 Nindy
+target, and should not be used in any other configuration.
+
+@item BELIEVE_PCC_PROMOTION
+@findex BELIEVE_PCC_PROMOTION
+Define if the compiler promotes a @code{short} or @code{char}
+parameter to an @code{int}, but still reports the parameter as its
+original type, rather than the promoted type.
+
+@item BELIEVE_PCC_PROMOTION_TYPE
+@findex BELIEVE_PCC_PROMOTION_TYPE
+Define this if @value{GDBN} should believe the type of a @code{short}
+argument when compiled by @code{pcc}, but look within a full int space to get
+its value. Only defined for Sun-3 at present.
+
+@item BITS_BIG_ENDIAN
+@findex BITS_BIG_ENDIAN
+Define this if the numbering of bits in the targets does @strong{not} match the
+endianness of the target byte order. A value of 1 means that the bits
+are numbered in a big-endian bit order, 0 means little-endian.
+
+@item BREAKPOINT
+@findex BREAKPOINT
+This is the character array initializer for the bit pattern to put into
+memory where a breakpoint is set. Although it's common to use a trap
+instruction for a breakpoint, it's not required; for instance, the bit
+pattern could be an invalid instruction. The breakpoint must be no
+longer than the shortest instruction of the architecture.
+
+@code{BREAKPOINT} has been deprecated in favor of
+@code{BREAKPOINT_FROM_PC}.
+
+@item BIG_BREAKPOINT
+@itemx LITTLE_BREAKPOINT
+@findex LITTLE_BREAKPOINT
+@findex BIG_BREAKPOINT
+Similar to BREAKPOINT, but used for bi-endian targets.
+
+@code{BIG_BREAKPOINT} and @code{LITTLE_BREAKPOINT} have been deprecated in
+favor of @code{BREAKPOINT_FROM_PC}.
+
+@item REMOTE_BREAKPOINT
+@itemx LITTLE_REMOTE_BREAKPOINT
+@itemx BIG_REMOTE_BREAKPOINT
+@findex BIG_REMOTE_BREAKPOINT
+@findex LITTLE_REMOTE_BREAKPOINT
+@findex REMOTE_BREAKPOINT
+Similar to BREAKPOINT, but used for remote targets.
+
+@code{BIG_REMOTE_BREAKPOINT} and @code{LITTLE_REMOTE_BREAKPOINT} have been
+deprecated in favor of @code{BREAKPOINT_FROM_PC}.
+
+@item BREAKPOINT_FROM_PC (@var{pcptr}, @var{lenptr})
+@findex BREAKPOINT_FROM_PC
+Use the program counter to determine the contents and size of a
+breakpoint instruction. It returns a pointer to a string of bytes
+that encode a breakpoint instruction, stores the length of the string
+to *@var{lenptr}, and adjusts pc (if necessary) to point to the actual
+memory location where the breakpoint should be inserted.
+
+Although it is common to use a trap instruction for a breakpoint, it's
+not required; for instance, the bit pattern could be an invalid
+instruction. The breakpoint must be no longer than the shortest
+instruction of the architecture.
+
+Replaces all the other @var{BREAKPOINT} macros.
+
+@item MEMORY_INSERT_BREAKPOINT (@var{addr}, @var{contents_cache})
+@itemx MEMORY_REMOVE_BREAKPOINT (@var{addr}, @var{contents_cache})
+@findex MEMORY_REMOVE_BREAKPOINT
+@findex MEMORY_INSERT_BREAKPOINT
+Insert or remove memory based breakpoints. Reasonable defaults
+(@code{default_memory_insert_breakpoint} and
+@code{default_memory_remove_breakpoint} respectively) have been
+provided so that it is not necessary to define these for most
+architectures. Architectures which may want to define
+@code{MEMORY_INSERT_BREAKPOINT} and @code{MEMORY_REMOVE_BREAKPOINT} will
+likely have instructions that are oddly sized or are not stored in a
+conventional manner.
+
+It may also be desirable (from an efficiency standpoint) to define
+custom breakpoint insertion and removal routines if
+@code{BREAKPOINT_FROM_PC} needs to read the target's memory for some
+reason.
+
+@item CALL_DUMMY_P
+@findex CALL_DUMMY_P
+A C expression that is non-zero when the target supports inferior function
+calls.
+
+@item CALL_DUMMY_WORDS
+@findex CALL_DUMMY_WORDS
+Pointer to an array of @code{LONGEST} words of data containing
+host-byte-ordered @code{REGISTER_BYTES} sized values that partially
+specify the sequence of instructions needed for an inferior function
+call.
+
+Should be deprecated in favor of a macro that uses target-byte-ordered
+data.
+
+@item SIZEOF_CALL_DUMMY_WORDS
+@findex SIZEOF_CALL_DUMMY_WORDS
+The size of @code{CALL_DUMMY_WORDS}. When @code{CALL_DUMMY_P} this must
+return a positive value. See also @code{CALL_DUMMY_LENGTH}.
+
+@item CALL_DUMMY
+@findex CALL_DUMMY
+A static initializer for @code{CALL_DUMMY_WORDS}. Deprecated.
+
+@item CALL_DUMMY_LOCATION
+@findex CALL_DUMMY_LOCATION
+See the file @file{inferior.h}.
+
+@item CALL_DUMMY_STACK_ADJUST
+@findex CALL_DUMMY_STACK_ADJUST
+Stack adjustment needed when performing an inferior function call.
+
+Should be deprecated in favor of something like @code{STACK_ALIGN}.
+
+@item CALL_DUMMY_STACK_ADJUST_P
+@findex CALL_DUMMY_STACK_ADJUST_P
+Predicate for use of @code{CALL_DUMMY_STACK_ADJUST}.
+
+Should be deprecated in favor of something like @code{STACK_ALIGN}.
+
+@item CANNOT_FETCH_REGISTER (@var{regno})
+@findex CANNOT_FETCH_REGISTER
+A C expression that should be nonzero if @var{regno} cannot be fetched
+from an inferior process. This is only relevant if
+@code{FETCH_INFERIOR_REGISTERS} is not defined.
+
+@item CANNOT_STORE_REGISTER (@var{regno})
+@findex CANNOT_STORE_REGISTER
+A C expression that should be nonzero if @var{regno} should not be
+written to the target. This is often the case for program counters,
+status words, and other special registers. If this is not defined,
+@value{GDBN} will assume that all registers may be written.
+
+@item DO_DEFERRED_STORES
+@itemx CLEAR_DEFERRED_STORES
+@findex CLEAR_DEFERRED_STORES
+@findex DO_DEFERRED_STORES
+Define this to execute any deferred stores of registers into the inferior,
+and to cancel any deferred stores.
+
+Currently only implemented correctly for native Sparc configurations?
+
+@item COERCE_FLOAT_TO_DOUBLE (@var{formal}, @var{actual})
+@findex COERCE_FLOAT_TO_DOUBLE
+@cindex promotion to @code{double}
+@cindex @code{float} arguments
+@cindex prototyped functions, passing arguments to
+@cindex passing arguments to prototyped functions
+Return non-zero if GDB should promote @code{float} values to
+@code{double} when calling a non-prototyped function. The argument
+@var{actual} is the type of the value we want to pass to the function.
+The argument @var{formal} is the type of this argument, as it appears in
+the function's definition. Note that @var{formal} may be zero if we
+have no debugging information for the function, or if we're passing more
+arguments than are officially declared (for example, varargs). This
+macro is never invoked if the function definitely has a prototype.
+
+How you should pass arguments to a function depends on whether it was
+defined in K&R style or prototype style. If you define a function using
+the K&R syntax that takes a @code{float} argument, then callers must
+pass that argument as a @code{double}. If you define the function using
+the prototype syntax, then you must pass the argument as a @code{float},
+with no promotion.
+
+Unfortunately, on certain older platforms, the debug info doesn't
+indicate reliably how each function was defined. A function type's
+@code{TYPE_FLAG_PROTOTYPED} flag may be unset, even if the function was
+defined in prototype style. When calling a function whose
+@code{TYPE_FLAG_PROTOTYPED} flag is unset, GDB consults the
+@code{COERCE_FLOAT_TO_DOUBLE} macro to decide what to do.
+
+@findex standard_coerce_float_to_double
+For modern targets, it is proper to assume that, if the prototype flag
+is unset, that can be trusted: @code{float} arguments should be promoted
+to @code{double}. You should use the function
+@code{standard_coerce_float_to_double} to get this behavior.
+
+@findex default_coerce_float_to_double
+For some older targets, if the prototype flag is unset, that doesn't
+tell us anything. So we guess that, if we don't have a type for the
+formal parameter (@i{i.e.}, the first argument to
+@code{COERCE_FLOAT_TO_DOUBLE} is null), then we should promote it;
+otherwise, we should leave it alone. The function
+@code{default_coerce_float_to_double} provides this behavior; it is the
+default value, for compatibility with older configurations.
+
+@item int CONVERT_REGISTER_P(@var{regnum})
+@findex CONVERT_REGISTER_P
+Return non-zero if register @var{regnum} can represent data values in a
+non-standard form.
+@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}.
+
+@item CPLUS_MARKER
+@findex CPLUS_MARKERz
+Define this to expand into the character that G@t{++} uses to distinguish
+compiler-generated identifiers from programmer-specified identifiers.
+By default, this expands into @code{'$'}. Most System V targets should
+define this to @code{'.'}.
+
+@item DBX_PARM_SYMBOL_CLASS
+@findex DBX_PARM_SYMBOL_CLASS
+Hook for the @code{SYMBOL_CLASS} of a parameter when decoding DBX symbol
+information. In the i960, parameters can be stored as locals or as
+args, depending on the type of the debug record.
+
+@item DECR_PC_AFTER_BREAK
+@findex DECR_PC_AFTER_BREAK
+Define this to be the amount by which to decrement the PC after the
+program encounters a breakpoint. This is often the number of bytes in
+@code{BREAKPOINT}, though not always. For most targets this value will be 0.
+
+@item DECR_PC_AFTER_HW_BREAK
+@findex DECR_PC_AFTER_HW_BREAK
+Similarly, for hardware breakpoints.
+
+@item DISABLE_UNSETTABLE_BREAK (@var{addr})
+@findex DISABLE_UNSETTABLE_BREAK
+If defined, this should evaluate to 1 if @var{addr} is in a shared
+library in which breakpoints cannot be set and so should be disabled.
+
+@item DO_REGISTERS_INFO
+@findex DO_REGISTERS_INFO
+If defined, use this to print the value of a register or all registers.
+
+@item PRINT_FLOAT_INFO()
+#findex PRINT_FLOAT_INFO
+If defined, then the @samp{info float} command will print information about
+the processor's floating point unit.
+
+@item DWARF_REG_TO_REGNUM
+@findex DWARF_REG_TO_REGNUM
+Convert DWARF register number into @value{GDBN} regnum. If not defined,
+no conversion will be performed.
+
+@item DWARF2_REG_TO_REGNUM
+@findex DWARF2_REG_TO_REGNUM
+Convert DWARF2 register number into @value{GDBN} regnum. If not
+defined, no conversion will be performed.
+
+@item ECOFF_REG_TO_REGNUM
+@findex ECOFF_REG_TO_REGNUM
+Convert ECOFF register number into @value{GDBN} regnum. If not defined,
+no conversion will be performed.
+
+@item END_OF_TEXT_DEFAULT
+@findex END_OF_TEXT_DEFAULT
+This is an expression that should designate the end of the text section.
+@c (? FIXME ?)
+
+@item EXTRACT_RETURN_VALUE(@var{type}, @var{regbuf}, @var{valbuf})
+@findex EXTRACT_RETURN_VALUE
+Define this to extract a function's return value of type @var{type} from
+the raw register state @var{regbuf} and copy that, in virtual format,
+into @var{valbuf}.
+
+@item EXTRACT_STRUCT_VALUE_ADDRESS(@var{regbuf})
+@findex EXTRACT_STRUCT_VALUE_ADDRESS
+When defined, extract from the array @var{regbuf} (containing the raw
+register state) the @code{CORE_ADDR} at which a function should return
+its structure value.
+
+If not defined, @code{EXTRACT_RETURN_VALUE} is used.
+
+@item EXTRACT_STRUCT_VALUE_ADDRESS_P()
+@findex EXTRACT_STRUCT_VALUE_ADDRESS_P
+Predicate for @code{EXTRACT_STRUCT_VALUE_ADDRESS}.
+
+@item FLOAT_INFO
+@findex FLOAT_INFO
+Deprecated in favor of @code{PRINT_FLOAT_INFO}.
+
+@item FP_REGNUM
+@findex FP_REGNUM
+If the virtual frame pointer is kept in a register, then define this
+macro to be the number (greater than or equal to zero) of that register.
+
+This should only need to be defined if @code{TARGET_READ_FP} is not
+defined.
+
+@item FRAMELESS_FUNCTION_INVOCATION(@var{fi})
+@findex FRAMELESS_FUNCTION_INVOCATION
+Define this to an expression that returns 1 if the function invocation
+represented by @var{fi} does not have a stack frame associated with it.
+Otherwise return 0.
+
+@item FRAME_ARGS_ADDRESS_CORRECT
+@findex FRAME_ARGS_ADDRESS_CORRECT
+See @file{stack.c}.
+
+@item FRAME_CHAIN(@var{frame})
+@findex FRAME_CHAIN
+Given @var{frame}, return a pointer to the calling frame.
+
+@item FRAME_CHAIN_VALID(@var{chain}, @var{thisframe})
+@findex FRAME_CHAIN_VALID
+Define this to be an expression that returns zero if the given frame is
+an outermost frame, with no caller, and nonzero otherwise. Several
+common definitions are available:
+
+@itemize @bullet
+@item
+@code{file_frame_chain_valid} is nonzero if the chain pointer is nonzero
+and given frame's PC is not inside the startup file (such as
+@file{crt0.o}).
+
+@item
+@code{func_frame_chain_valid} is nonzero if the chain
+pointer is nonzero and the given frame's PC is not in @code{main} or a
+known entry point function (such as @code{_start}).
+
+@item
+@code{generic_file_frame_chain_valid} and
+@code{generic_func_frame_chain_valid} are equivalent implementations for
+targets using generic dummy frames.
+@end itemize
+
+@item FRAME_INIT_SAVED_REGS(@var{frame})
+@findex FRAME_INIT_SAVED_REGS
+See @file{frame.h}. Determines the address of all registers in the
+current stack frame storing each in @code{frame->saved_regs}. Space for
+@code{frame->saved_regs} shall be allocated by
+@code{FRAME_INIT_SAVED_REGS} using either
+@code{frame_saved_regs_zalloc} or @code{frame_obstack_alloc}.
+
+@code{FRAME_FIND_SAVED_REGS} and @code{EXTRA_FRAME_INFO} are deprecated.
+
+@item FRAME_NUM_ARGS (@var{fi})
+@findex FRAME_NUM_ARGS
+For the frame described by @var{fi} return the number of arguments that
+are being passed. If the number of arguments is not known, return
+@code{-1}.
+
+@item FRAME_SAVED_PC(@var{frame})
+@findex FRAME_SAVED_PC
+Given @var{frame}, return the pc saved there. This is the return
+address.
+
+@item FUNCTION_EPILOGUE_SIZE
+@findex FUNCTION_EPILOGUE_SIZE
+For some COFF targets, the @code{x_sym.x_misc.x_fsize} field of the
+function end symbol is 0. For such targets, you must define
+@code{FUNCTION_EPILOGUE_SIZE} to expand into the standard size of a
+function's epilogue.
+
+@item FUNCTION_START_OFFSET
+@findex FUNCTION_START_OFFSET
+An integer, giving the offset in bytes from a function's address (as
+used in the values of symbols, function pointers, etc.), and the
+function's first genuine instruction.
+
+This is zero on almost all machines: the function's address is usually
+the address of its first instruction. However, on the VAX, for example,
+each function starts with two bytes containing a bitmask indicating
+which registers to save upon entry to the function. The VAX @code{call}
+instructions check this value, and save the appropriate registers
+automatically. Thus, since the offset from the function's address to
+its first instruction is two bytes, @code{FUNCTION_START_OFFSET} would
+be 2 on the VAX.
+
+@item GCC_COMPILED_FLAG_SYMBOL
+@itemx GCC2_COMPILED_FLAG_SYMBOL
+@findex GCC2_COMPILED_FLAG_SYMBOL
+@findex GCC_COMPILED_FLAG_SYMBOL
+If defined, these are the names of the symbols that @value{GDBN} will
+look for to detect that GCC compiled the file. The default symbols
+are @code{gcc_compiled.} and @code{gcc2_compiled.},
+respectively. (Currently only defined for the Delta 68.)
+
+@item @value{GDBN}_MULTI_ARCH
+@findex @value{GDBN}_MULTI_ARCH
+If defined and non-zero, enables support for multiple architectures
+within @value{GDBN}.
+
+This support can be enabled at two levels. At level one, only
+definitions for previously undefined macros are provided; at level two,
+a multi-arch definition of all architecture dependent macros will be
+defined.
+
+@item @value{GDBN}_TARGET_IS_HPPA
+@findex @value{GDBN}_TARGET_IS_HPPA
+This determines whether horrible kludge code in @file{dbxread.c} and
+@file{partial-stab.h} is used to mangle multiple-symbol-table files from
+HPPA's. This should all be ripped out, and a scheme like @file{elfread.c}
+used instead.
+
+@item GET_LONGJMP_TARGET
+@findex GET_LONGJMP_TARGET
+For most machines, this is a target-dependent parameter. On the
+DECstation and the Iris, this is a native-dependent parameter, since
+the header file @file{setjmp.h} is needed to define it.
+
+This macro determines the target PC address that @code{longjmp} will jump to,
+assuming that we have just stopped at a @code{longjmp} breakpoint. It takes a
+@code{CORE_ADDR *} as argument, and stores the target PC value through this
+pointer. It examines the current state of the machine as needed.
+
+@item GET_SAVED_REGISTER
+@findex GET_SAVED_REGISTER
+@findex get_saved_register
+Define this if you need to supply your own definition for the function
+@code{get_saved_register}.
+
+@item IBM6000_TARGET
+@findex IBM6000_TARGET
+Shows that we are configured for an IBM RS/6000 target. This
+conditional should be eliminated (FIXME) and replaced by
+feature-specific macros. It was introduced in a haste and we are
+repenting at leisure.
+
+@item I386_USE_GENERIC_WATCHPOINTS
+An x86-based target can define this to use the generic x86 watchpoint
+support; see @ref{Algorithms, I386_USE_GENERIC_WATCHPOINTS}.
+
+@item SYMBOLS_CAN_START_WITH_DOLLAR
+@findex SYMBOLS_CAN_START_WITH_DOLLAR
+Some systems have routines whose names start with @samp{$}. Giving this
+macro a non-zero value tells @value{GDBN}'s expression parser to check for such
+routines when parsing tokens that begin with @samp{$}.
+
+On HP-UX, certain system routines (millicode) have names beginning with
+@samp{$} or @samp{$$}. For example, @code{$$dyncall} is a millicode
+routine that handles inter-space procedure calls on PA-RISC.
+
+@item INIT_EXTRA_FRAME_INFO (@var{fromleaf}, @var{frame})
+@findex INIT_EXTRA_FRAME_INFO
+If additional information about the frame is required this should be
+stored in @code{frame->extra_info}. Space for @code{frame->extra_info}
+is allocated using @code{frame_obstack_alloc}.
+
+@item INIT_FRAME_PC (@var{fromleaf}, @var{prev})
+@findex INIT_FRAME_PC
+This is a C statement that sets the pc of the frame pointed to by
+@var{prev}. [By default...]
+
+@item INNER_THAN (@var{lhs}, @var{rhs})
+@findex INNER_THAN
+Returns non-zero if stack address @var{lhs} is inner than (nearer to the
+stack top) stack address @var{rhs}. Define this as @code{lhs < rhs} if
+the target's stack grows downward in memory, or @code{lhs > rsh} if the
+stack grows upward.
+
+@item gdbarch_in_function_epilogue_p (@var{gdbarch}, @var{pc})
+@findex gdbarch_in_function_epilogue_p
+Returns non-zero if the given @var{pc} is in the epilogue of a function.
+The epilogue of a function is defined as the part of a function where
+the stack frame of the function already has been destroyed up to the
+final `return from function call' instruction.
+
+@item SIGTRAMP_START (@var{pc})
+@findex SIGTRAMP_START
+@itemx SIGTRAMP_END (@var{pc})
+@findex SIGTRAMP_END
+Define these to be the start and end address of the @code{sigtramp} for the
+given @var{pc}. On machines where the address is just a compile time
+constant, the macro expansion will typically just ignore the supplied
+@var{pc}.
+
+@item IN_SOLIB_CALL_TRAMPOLINE (@var{pc}, @var{name})
+@findex IN_SOLIB_CALL_TRAMPOLINE
+Define this to evaluate to nonzero if the program is stopped in the
+trampoline that connects to a shared library.
+
+@item IN_SOLIB_RETURN_TRAMPOLINE (@var{pc}, @var{name})
+@findex IN_SOLIB_RETURN_TRAMPOLINE
+Define this to evaluate to nonzero if the program is stopped in the
+trampoline that returns from a shared library.
+
+@item IN_SOLIB_DYNSYM_RESOLVE_CODE (@var{pc})
+@findex IN_SOLIB_DYNSYM_RESOLVE_CODE
+Define this to evaluate to nonzero if the program is stopped in the
+dynamic linker.
+
+@item SKIP_SOLIB_RESOLVER (@var{pc})
+@findex SKIP_SOLIB_RESOLVER
+Define this to evaluate to the (nonzero) address at which execution
+should continue to get past the dynamic linker's symbol resolution
+function. A zero value indicates that it is not important or necessary
+to set a breakpoint to get through the dynamic linker and that single
+stepping will suffice.
+
+@item INTEGER_TO_ADDRESS (@var{type}, @var{buf})
+@findex INTEGER_TO_ADDRESS
+@cindex converting integers to addresses
+Define this when the architecture needs to handle non-pointer to address
+conversions specially. Converts that value to an address according to
+the current architectures conventions.
+
+@emph{Pragmatics: When the user copies a well defined expression from
+their source code and passes it, as a parameter, to @value{GDBN}'s
+@code{print} command, they should get the same value as would have been
+computed by the target program. Any deviation from this rule can cause
+major confusion and annoyance, and needs to be justified carefully. In
+other words, @value{GDBN} doesn't really have the freedom to do these
+conversions in clever and useful ways. It has, however, been pointed
+out that users aren't complaining about how @value{GDBN} casts integers
+to pointers; they are complaining that they can't take an address from a
+disassembly listing and give it to @code{x/i}. Adding an architecture
+method like @code{INTEGER_TO_ADDRESS} certainly makes it possible for
+@value{GDBN} to ``get it right'' in all circumstances.}
+
+@xref{Target Architecture Definition, , Pointers Are Not Always
+Addresses}.
+
+@item IS_TRAPPED_INTERNALVAR (@var{name})
+@findex IS_TRAPPED_INTERNALVAR
+This is an ugly hook to allow the specification of special actions that
+should occur as a side-effect of setting the value of a variable
+internal to @value{GDBN}. Currently only used by the h8500. Note that this
+could be either a host or target conditional.
+
+@item NEED_TEXT_START_END
+@findex NEED_TEXT_START_END
+Define this if @value{GDBN} should determine the start and end addresses of the
+text section. (Seems dubious.)
+
+@item NO_HIF_SUPPORT
+@findex NO_HIF_SUPPORT
+(Specific to the a29k.)
+
+@item POINTER_TO_ADDRESS (@var{type}, @var{buf})
+@findex POINTER_TO_ADDRESS
+Assume that @var{buf} holds a pointer of type @var{type}, in the
+appropriate format for the current architecture. Return the byte
+address the pointer refers to.
+@xref{Target Architecture Definition, , Pointers Are Not Always Addresses}.
+
+@item REGISTER_CONVERTIBLE (@var{reg})
+@findex REGISTER_CONVERTIBLE
+Return non-zero if @var{reg} uses different raw and virtual formats.
+@xref{Target Architecture Definition, , Raw and Virtual Register Representations}.
+
+@item REGISTER_TO_VALUE(@var{regnum}, @var{type}, @var{from}, @var{to})
+@findex REGISTER_TO_VALUE
+Convert the raw contents of register @var{regnum} into a value of type
+@var{type}.
+@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}.
+
+@item REGISTER_RAW_SIZE (@var{reg})
+@findex REGISTER_RAW_SIZE
+Return the raw size of @var{reg}; defaults to the size of the register's
+virtual type.
+@xref{Target Architecture Definition, , Raw and Virtual Register Representations}.
+
+@item REGISTER_VIRTUAL_SIZE (@var{reg})
+@findex REGISTER_VIRTUAL_SIZE
+Return the virtual size of @var{reg}; defaults to the size of the
+register's virtual type.
+Return the virtual size of @var{reg}.
+@xref{Target Architecture Definition, , Raw and Virtual Register Representations}.
+
+@item REGISTER_VIRTUAL_TYPE (@var{reg})
+@findex REGISTER_VIRTUAL_TYPE
+Return the virtual type of @var{reg}.
+@xref{Target Architecture Definition, , Raw and Virtual Register Representations}.
+
+@item REGISTER_CONVERT_TO_VIRTUAL(@var{reg}, @var{type}, @var{from}, @var{to})
+@findex REGISTER_CONVERT_TO_VIRTUAL
+Convert the value of register @var{reg} from its raw form to its virtual
+form.
+@xref{Target Architecture Definition, , Raw and Virtual Register Representations}.
+
+@item REGISTER_CONVERT_TO_RAW(@var{type}, @var{reg}, @var{from}, @var{to})
+@findex REGISTER_CONVERT_TO_RAW
+Convert the value of register @var{reg} from its virtual form to its raw
+form.
+@xref{Target Architecture Definition, , Raw and Virtual Register Representations}.
+
+@item RETURN_VALUE_ON_STACK(@var{type})
+@findex RETURN_VALUE_ON_STACK
+@cindex returning structures by value
+@cindex structures, returning by value
+
+Return non-zero if values of type TYPE are returned on the stack, using
+the ``struct convention'' (i.e., the caller provides a pointer to a
+buffer in which the callee should store the return value). This
+controls how the @samp{finish} command finds a function's return value,
+and whether an inferior function call reserves space on the stack for
+the return value.
+
+The full logic @value{GDBN} uses here is kind of odd.
+
+@itemize @bullet
+@item
+If the type being returned by value is not a structure, union, or array,
+and @code{RETURN_VALUE_ON_STACK} returns zero, then @value{GDBN}
+concludes the value is not returned using the struct convention.
+
+@item
+Otherwise, @value{GDBN} calls @code{USE_STRUCT_CONVENTION} (see below).
+If that returns non-zero, @value{GDBN} assumes the struct convention is
+in use.
+@end itemize
+
+In other words, to indicate that a given type is returned by value using
+the struct convention, that type must be either a struct, union, array,
+or something @code{RETURN_VALUE_ON_STACK} likes, @emph{and} something
+that @code{USE_STRUCT_CONVENTION} likes.
+
+Note that, in C and C@t{++}, arrays are never returned by value. In those
+languages, these predicates will always see a pointer type, never an
+array type. All the references above to arrays being returned by value
+apply only to other languages.
+
+@item SOFTWARE_SINGLE_STEP_P()
+@findex SOFTWARE_SINGLE_STEP_P
+Define this as 1 if the target does not have a hardware single-step
+mechanism. The macro @code{SOFTWARE_SINGLE_STEP} must also be defined.
+
+@item SOFTWARE_SINGLE_STEP(@var{signal}, @var{insert_breapoints_p})
+@findex SOFTWARE_SINGLE_STEP
+A function that inserts or removes (depending on
+@var{insert_breapoints_p}) breakpoints at each possible destinations of
+the next instruction. See @file{sparc-tdep.c} and @file{rs6000-tdep.c}
+for examples.
+
+@item SOFUN_ADDRESS_MAYBE_MISSING
+@findex SOFUN_ADDRESS_MAYBE_MISSING
+Somebody clever observed that, the more actual addresses you have in the
+debug information, the more time the linker has to spend relocating
+them. So whenever there's some other way the debugger could find the
+address it needs, you should omit it from the debug info, to make
+linking faster.
+
+@code{SOFUN_ADDRESS_MAYBE_MISSING} indicates that a particular set of
+hacks of this sort are in use, affecting @code{N_SO} and @code{N_FUN}
+entries in stabs-format debugging information. @code{N_SO} stabs mark
+the beginning and ending addresses of compilation units in the text
+segment. @code{N_FUN} stabs mark the starts and ends of functions.
+
+@code{SOFUN_ADDRESS_MAYBE_MISSING} means two things:
+
+@itemize @bullet
+@item
+@code{N_FUN} stabs have an address of zero. Instead, you should find the
+addresses where the function starts by taking the function name from
+the stab, and then looking that up in the minsyms (the
+linker/assembler symbol table). In other words, the stab has the
+name, and the linker/assembler symbol table is the only place that carries
+the address.
+
+@item
+@code{N_SO} stabs have an address of zero, too. You just look at the
+@code{N_FUN} stabs that appear before and after the @code{N_SO} stab,
+and guess the starting and ending addresses of the compilation unit from
+them.
+@end itemize
+
+@item PCC_SOL_BROKEN
+@findex PCC_SOL_BROKEN
+(Used only in the Convex target.)
+
+@item PC_IN_CALL_DUMMY
+@findex PC_IN_CALL_DUMMY
+See @file{inferior.h}.
+
+@item PC_IN_SIGTRAMP (@var{pc}, @var{name})
+@findex PC_IN_SIGTRAMP
+@cindex sigtramp
+The @dfn{sigtramp} is a routine that the kernel calls (which then calls
+the signal handler). On most machines it is a library routine that is
+linked into the executable.
+
+This function, given a program counter value in @var{pc} and the
+(possibly NULL) name of the function in which that @var{pc} resides,
+returns nonzero if the @var{pc} and/or @var{name} show that we are in
+sigtramp.
+
+@item PC_LOAD_SEGMENT
+@findex PC_LOAD_SEGMENT
+If defined, print information about the load segment for the program
+counter. (Defined only for the RS/6000.)
+
+@item PC_REGNUM
+@findex PC_REGNUM
+If the program counter is kept in a register, then define this macro to
+be the number (greater than or equal to zero) of that register.
+
+This should only need to be defined if @code{TARGET_READ_PC} and
+@code{TARGET_WRITE_PC} are not defined.
+
+@item NPC_REGNUM
+@findex NPC_REGNUM
+The number of the ``next program counter'' register, if defined.
+
+@item PARM_BOUNDARY
+@findex PARM_BOUNDARY
+If non-zero, round arguments to a boundary of this many bits before
+pushing them on the stack.
+
+@item PRINT_REGISTER_HOOK (@var{regno})
+@findex PRINT_REGISTER_HOOK
+If defined, this must be a function that prints the contents of the
+given register to standard output.
+
+@item PRINT_TYPELESS_INTEGER
+@findex PRINT_TYPELESS_INTEGER
+This is an obscure substitute for @code{print_longest} that seems to
+have been defined for the Convex target.
+
+@item PROCESS_LINENUMBER_HOOK
+@findex PROCESS_LINENUMBER_HOOK
+A hook defined for XCOFF reading.
+
+@item PROLOGUE_FIRSTLINE_OVERLAP
+@findex PROLOGUE_FIRSTLINE_OVERLAP
+(Only used in unsupported Convex configuration.)
+
+@item PS_REGNUM
+@findex PS_REGNUM
+If defined, this is the number of the processor status register. (This
+definition is only used in generic code when parsing "$ps".)
+
+@item POP_FRAME
+@findex POP_FRAME
+@findex call_function_by_hand
+@findex return_command
+Used in @samp{call_function_by_hand} to remove an artificial stack
+frame and in @samp{return_command} to remove a real stack frame.
+
+@item PUSH_ARGUMENTS (@var{nargs}, @var{args}, @var{sp}, @var{struct_return}, @var{struct_addr})
+@findex PUSH_ARGUMENTS
+Define this to push arguments onto the stack for inferior function
+call. Returns the updated stack pointer value.
+
+@item PUSH_DUMMY_FRAME
+@findex PUSH_DUMMY_FRAME
+Used in @samp{call_function_by_hand} to create an artificial stack frame.
+
+@item REGISTER_BYTES
+@findex REGISTER_BYTES
+The total amount of space needed to store @value{GDBN}'s copy of the machine's
+register state.
+
+@item REGISTER_NAME(@var{i})
+@findex REGISTER_NAME
+Return the name of register @var{i} as a string. May return @code{NULL}
+or @code{NUL} to indicate that register @var{i} is not valid.
+
+@item REGISTER_NAMES
+@findex REGISTER_NAMES
+Deprecated in favor of @code{REGISTER_NAME}.
+
+@item REG_STRUCT_HAS_ADDR (@var{gcc_p}, @var{type})
+@findex REG_STRUCT_HAS_ADDR
+Define this to return 1 if the given type will be passed by pointer
+rather than directly.
+
+@item SAVE_DUMMY_FRAME_TOS (@var{sp})
+@findex SAVE_DUMMY_FRAME_TOS
+Used in @samp{call_function_by_hand} to notify the target dependent code
+of the top-of-stack value that will be passed to the the inferior code.
+This is the value of the @code{SP} after both the dummy frame and space
+for parameters/results have been allocated on the stack.
+
+@item SDB_REG_TO_REGNUM
+@findex SDB_REG_TO_REGNUM
+Define this to convert sdb register numbers into @value{GDBN} regnums. If not
+defined, no conversion will be done.
+
+@item SHIFT_INST_REGS
+@findex SHIFT_INST_REGS
+(Only used for m88k targets.)
+
+@item SKIP_PERMANENT_BREAKPOINT
+@findex SKIP_PERMANENT_BREAKPOINT
+Advance the inferior's PC past a permanent breakpoint. @value{GDBN} normally
+steps over a breakpoint by removing it, stepping one instruction, and
+re-inserting the breakpoint. However, permanent breakpoints are
+hardwired into the inferior, and can't be removed, so this strategy
+doesn't work. Calling @code{SKIP_PERMANENT_BREAKPOINT} adjusts the processor's
+state so that execution will resume just after the breakpoint. This
+macro does the right thing even when the breakpoint is in the delay slot
+of a branch or jump.
+
+@item SKIP_PROLOGUE (@var{pc})
+@findex SKIP_PROLOGUE
+A C expression that returns the address of the ``real'' code beyond the
+function entry prologue found at @var{pc}.
+
+@item SKIP_TRAMPOLINE_CODE (@var{pc})
+@findex SKIP_TRAMPOLINE_CODE
+If the target machine has trampoline code that sits between callers and
+the functions being called, then define this macro to return a new PC
+that is at the start of the real function.
+
+@item SP_REGNUM
+@findex SP_REGNUM
+If the stack-pointer is kept in a register, then define this macro to be
+the number (greater than or equal to zero) of that register.
+
+This should only need to be defined if @code{TARGET_WRITE_SP} and
+@code{TARGET_WRITE_SP} are not defined.
+
+@item STAB_REG_TO_REGNUM
+@findex STAB_REG_TO_REGNUM
+Define this to convert stab register numbers (as gotten from `r'
+declarations) into @value{GDBN} regnums. If not defined, no conversion will be
+done.
+
+@item STACK_ALIGN (@var{addr})
+@findex STACK_ALIGN
+Define this to adjust the address to the alignment required for the
+processor's stack.
+
+@item STEP_SKIPS_DELAY (@var{addr})
+@findex STEP_SKIPS_DELAY
+Define this to return true if the address is of an instruction with a
+delay slot. If a breakpoint has been placed in the instruction's delay
+slot, @value{GDBN} will single-step over that instruction before resuming
+normally. Currently only defined for the Mips.
+
+@item STORE_RETURN_VALUE (@var{type}, @var{valbuf})
+@findex STORE_RETURN_VALUE
+A C expression that stores a function return value of type @var{type},
+where @var{valbuf} is the address of the value to be stored.
+
+@item SUN_FIXED_LBRAC_BUG
+@findex SUN_FIXED_LBRAC_BUG
+(Used only for Sun-3 and Sun-4 targets.)
+
+@item SYMBOL_RELOADING_DEFAULT
+@findex SYMBOL_RELOADING_DEFAULT
+The default value of the ``symbol-reloading'' variable. (Never defined in
+current sources.)
+
+@item TARGET_CHAR_BIT
+@findex TARGET_CHAR_BIT
+Number of bits in a char; defaults to 8.
+
+@item TARGET_CHAR_SIGNED
+@findex TARGET_CHAR_SIGNED
+Non-zero if @code{char} is normally signed on this architecture; zero if
+it should be unsigned.
+
+The ISO C standard requires the compiler to treat @code{char} as
+equivalent to either @code{signed char} or @code{unsigned char}; any
+character in the standard execution set is supposed to be positive.
+Most compilers treat @code{char} as signed, but @code{char} is unsigned
+on the IBM S/390, RS6000, and PowerPC targets.
+
+@item TARGET_COMPLEX_BIT
+@findex TARGET_COMPLEX_BIT
+Number of bits in a complex number; defaults to @code{2 * TARGET_FLOAT_BIT}.
+
+At present this macro is not used.
+
+@item TARGET_DOUBLE_BIT
+@findex TARGET_DOUBLE_BIT
+Number of bits in a double float; defaults to @code{8 * TARGET_CHAR_BIT}.
+
+@item TARGET_DOUBLE_COMPLEX_BIT
+@findex TARGET_DOUBLE_COMPLEX_BIT
+Number of bits in a double complex; defaults to @code{2 * TARGET_DOUBLE_BIT}.
+
+At present this macro is not used.
+
+@item TARGET_FLOAT_BIT
+@findex TARGET_FLOAT_BIT
+Number of bits in a float; defaults to @code{4 * TARGET_CHAR_BIT}.
+
+@item TARGET_INT_BIT
+@findex TARGET_INT_BIT
+Number of bits in an integer; defaults to @code{4 * TARGET_CHAR_BIT}.
+
+@item TARGET_LONG_BIT
+@findex TARGET_LONG_BIT
+Number of bits in a long integer; defaults to @code{4 * TARGET_CHAR_BIT}.
+
+@item TARGET_LONG_DOUBLE_BIT
+@findex TARGET_LONG_DOUBLE_BIT
+Number of bits in a long double float;
+defaults to @code{2 * TARGET_DOUBLE_BIT}.
+
+@item TARGET_LONG_LONG_BIT
+@findex TARGET_LONG_LONG_BIT
+Number of bits in a long long integer; defaults to @code{2 * TARGET_LONG_BIT}.
+
+@item TARGET_PTR_BIT
+@findex TARGET_PTR_BIT
+Number of bits in a pointer; defaults to @code{TARGET_INT_BIT}.
+
+@item TARGET_SHORT_BIT
+@findex TARGET_SHORT_BIT
+Number of bits in a short integer; defaults to @code{2 * TARGET_CHAR_BIT}.
+
+@item TARGET_READ_PC
+@findex TARGET_READ_PC
+@itemx TARGET_WRITE_PC (@var{val}, @var{pid})
+@findex TARGET_WRITE_PC
+@itemx TARGET_READ_SP
+@findex TARGET_READ_SP
+@itemx TARGET_WRITE_SP
+@findex TARGET_WRITE_SP
+@itemx TARGET_READ_FP
+@findex TARGET_READ_FP
+@findex read_pc
+@findex write_pc
+@findex read_sp
+@findex write_sp
+@findex read_fp
+These change the behavior of @code{read_pc}, @code{write_pc},
+@code{read_sp}, @code{write_sp} and @code{read_fp}. For most targets,
+these may be left undefined. @value{GDBN} will call the read and write
+register functions with the relevant @code{_REGNUM} argument.
+
+These macros are useful when a target keeps one of these registers in a
+hard to get at place; for example, part in a segment register and part
+in an ordinary register.
+
+@item TARGET_VIRTUAL_FRAME_POINTER(@var{pc}, @var{regp}, @var{offsetp})
+@findex TARGET_VIRTUAL_FRAME_POINTER
+Returns a @code{(register, offset)} pair representing the virtual
+frame pointer in use at the code address @var{pc}. If virtual
+frame pointers are not used, a default definition simply returns
+@code{FP_REGNUM}, with an offset of zero.
+
+@item TARGET_HAS_HARDWARE_WATCHPOINTS
+If non-zero, the target has support for hardware-assisted
+watchpoints. @xref{Algorithms, watchpoints}, for more details and
+other related macros.
+
+@item TARGET_PRINT_INSN (@var{addr}, @var{info})
+@findex TARGET_PRINT_INSN
+This is the function used by @value{GDBN} to print an assembly
+instruction. It prints the instruction at address @var{addr} in
+debugged memory and returns the length of the instruction, in bytes. If
+a target doesn't define its own printing routine, it defaults to an
+accessor function for the global pointer @code{tm_print_insn}. This
+usually points to a function in the @code{opcodes} library (@pxref{Support
+Libraries, ,Opcodes}). @var{info} is a structure (of type
+@code{disassemble_info}) defined in @file{include/dis-asm.h} used to
+pass information to the instruction decoding routine.
+
+@item USE_STRUCT_CONVENTION (@var{gcc_p}, @var{type})
+@findex USE_STRUCT_CONVENTION
+If defined, this must be an expression that is nonzero if a value of the
+given @var{type} being returned from a function must have space
+allocated for it on the stack. @var{gcc_p} is true if the function
+being considered is known to have been compiled by GCC; this is helpful
+for systems where GCC is known to use different calling convention than
+other compilers.
+
+@item VALUE_TO_REGISTER(@var{type}, @var{regnum}, @var{from}, @var{to})
+@findex VALUE_TO_REGISTER
+Convert a value of type @var{type} into the raw contents of register
+@var{regnum}'s.
+@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}.
+
+@item VARIABLES_INSIDE_BLOCK (@var{desc}, @var{gcc_p})
+@findex VARIABLES_INSIDE_BLOCK
+For dbx-style debugging information, if the compiler puts variable
+declarations inside LBRAC/RBRAC blocks, this should be defined to be
+nonzero. @var{desc} is the value of @code{n_desc} from the
+@code{N_RBRAC} symbol, and @var{gcc_p} is true if @value{GDBN} has noticed the
+presence of either the @code{GCC_COMPILED_SYMBOL} or the
+@code{GCC2_COMPILED_SYMBOL}. By default, this is 0.
+
+@item OS9K_VARIABLES_INSIDE_BLOCK (@var{desc}, @var{gcc_p})
+@findex OS9K_VARIABLES_INSIDE_BLOCK
+Similarly, for OS/9000. Defaults to 1.
+@end table
+
+Motorola M68K target conditionals.
+
+@ftable @code
+@item BPT_VECTOR
+Define this to be the 4-bit location of the breakpoint trap vector. If
+not defined, it will default to @code{0xf}.
+
+@item REMOTE_BPT_VECTOR
+Defaults to @code{1}.
+@end ftable
+
+@section Adding a New Target
+
+@cindex adding a target
+The following files add a target to @value{GDBN}:
+
+@table @file
+@vindex TDEPFILES
+@item gdb/config/@var{arch}/@var{ttt}.mt
+Contains a Makefile fragment specific to this target. Specifies what
+object files are needed for target @var{ttt}, by defining
+@samp{TDEPFILES=@dots{}} and @samp{TDEPLIBS=@dots{}}. Also specifies
+the header file which describes @var{ttt}, by defining @samp{TM_FILE=
+tm-@var{ttt}.h}.
+
+You can also define @samp{TM_CFLAGS}, @samp{TM_CLIBS}, @samp{TM_CDEPS},
+but these are now deprecated, replaced by autoconf, and may go away in
+future versions of @value{GDBN}.
+
+@item gdb/@var{ttt}-tdep.c
+Contains any miscellaneous code required for this target machine. On
+some machines it doesn't exist at all. Sometimes the macros in
+@file{tm-@var{ttt}.h} become very complicated, so they are implemented
+as functions here instead, and the macro is simply defined to call the
+function. This is vastly preferable, since it is easier to understand
+and debug.
+
+@item gdb/@var{arch}-tdep.c
+@itemx gdb/@var{arch}-tdep.h
+This often exists to describe the basic layout of the target machine's
+processor chip (registers, stack, etc.). If used, it is included by
+@file{@var{ttt}-tdep.h}. It can be shared among many targets that use
+the same processor.
+
+@item gdb/config/@var{arch}/tm-@var{ttt}.h
+(@file{tm.h} is a link to this file, created by @code{configure}). Contains
+macro definitions about the target machine's registers, stack frame
+format and instructions.
+
+New targets do not need this file and should not create it.
+
+@item gdb/config/@var{arch}/tm-@var{arch}.h
+This often exists to describe the basic layout of the target machine's
+processor chip (registers, stack, etc.). If used, it is included by
+@file{tm-@var{ttt}.h}. It can be shared among many targets that use the
+same processor.
+
+New targets do not need this file and should not create it.
+
+@end table
+
+If you are adding a new operating system for an existing CPU chip, add a
+@file{config/tm-@var{os}.h} file that describes the operating system
+facilities that are unusual (extra symbol table info; the breakpoint
+instruction needed; etc.). Then write a @file{@var{arch}/tm-@var{os}.h}
+that just @code{#include}s @file{tm-@var{arch}.h} and
+@file{config/tm-@var{os}.h}.
+
+
+@node Target Vector Definition
+
+@chapter Target Vector Definition
+@cindex target vector
+
+The target vector defines the interface between @value{GDBN}'s
+abstract handling of target systems, and the nitty-gritty code that
+actually exercises control over a process or a serial port.
+@value{GDBN} includes some 30-40 different target vectors; however,
+each configuration of @value{GDBN} includes only a few of them.
+
+@section File Targets
+
+Both executables and core files have target vectors.
+
+@section Standard Protocol and Remote Stubs
+
+@value{GDBN}'s file @file{remote.c} talks a serial protocol to code
+that runs in the target system. @value{GDBN} provides several sample
+@dfn{stubs} that can be integrated into target programs or operating
+systems for this purpose; they are named @file{*-stub.c}.
+
+The @value{GDBN} user's manual describes how to put such a stub into
+your target code. What follows is a discussion of integrating the
+SPARC stub into a complicated operating system (rather than a simple
+program), by Stu Grossman, the author of this stub.
+
+The trap handling code in the stub assumes the following upon entry to
+@code{trap_low}:
+
+@enumerate
+@item
+%l1 and %l2 contain pc and npc respectively at the time of the trap;
+
+@item
+traps are disabled;
+
+@item
+you are in the correct trap window.
+@end enumerate
+
+As long as your trap handler can guarantee those conditions, then there
+is no reason why you shouldn't be able to ``share'' traps with the stub.
+The stub has no requirement that it be jumped to directly from the
+hardware trap vector. That is why it calls @code{exceptionHandler()},
+which is provided by the external environment. For instance, this could
+set up the hardware traps to actually execute code which calls the stub
+first, and then transfers to its own trap handler.
+
+For the most point, there probably won't be much of an issue with
+``sharing'' traps, as the traps we use are usually not used by the kernel,
+and often indicate unrecoverable error conditions. Anyway, this is all
+controlled by a table, and is trivial to modify. The most important
+trap for us is for @code{ta 1}. Without that, we can't single step or
+do breakpoints. Everything else is unnecessary for the proper operation
+of the debugger/stub.
+
+From reading the stub, it's probably not obvious how breakpoints work.
+They are simply done by deposit/examine operations from @value{GDBN}.
+
+@section ROM Monitor Interface
+
+@section Custom Protocols
+
+@section Transport Layer
+
+@section Builtin Simulator
+
+
+@node Native Debugging
+
+@chapter Native Debugging
+@cindex native debugging
+
+Several files control @value{GDBN}'s configuration for native support:
+
+@table @file
+@vindex NATDEPFILES
+@item gdb/config/@var{arch}/@var{xyz}.mh
+Specifies Makefile fragments needed by a @emph{native} configuration on
+machine @var{xyz}. In particular, this lists the required
+native-dependent object files, by defining @samp{NATDEPFILES=@dots{}}.
+Also specifies the header file which describes native support on
+@var{xyz}, by defining @samp{NAT_FILE= nm-@var{xyz}.h}. You can also
+define @samp{NAT_CFLAGS}, @samp{NAT_ADD_FILES}, @samp{NAT_CLIBS},
+@samp{NAT_CDEPS}, etc.; see @file{Makefile.in}.
+
+@emph{Maintainer's note: The @file{.mh} suffix is because this file
+originally contained @file{Makefile} fragments for hosting @value{GDBN}
+on machine @var{xyz}. While the file is no longer used for this
+purpose, the @file{.mh} suffix remains. Perhaps someone will
+eventually rename these fragments so that they have a @file{.mn}
+suffix.}
+
+@item gdb/config/@var{arch}/nm-@var{xyz}.h
+(@file{nm.h} is a link to this file, created by @code{configure}). Contains C
+macro definitions describing the native system environment, such as
+child process control and core file support.
+
+@item gdb/@var{xyz}-nat.c
+Contains any miscellaneous C code required for this native support of
+this machine. On some machines it doesn't exist at all.
+@end table
+
+There are some ``generic'' versions of routines that can be used by
+various systems. These can be customized in various ways by macros
+defined in your @file{nm-@var{xyz}.h} file. If these routines work for
+the @var{xyz} host, you can just include the generic file's name (with
+@samp{.o}, not @samp{.c}) in @code{NATDEPFILES}.
+
+Otherwise, if your machine needs custom support routines, you will need
+to write routines that perform the same functions as the generic file.
+Put them into @file{@var{xyz}-nat.c}, and put @file{@var{xyz}-nat.o}
+into @code{NATDEPFILES}.
+
+@table @file
+@item inftarg.c
+This contains the @emph{target_ops vector} that supports Unix child
+processes on systems which use ptrace and wait to control the child.
+
+@item procfs.c
+This contains the @emph{target_ops vector} that supports Unix child
+processes on systems which use /proc to control the child.
+
+@item fork-child.c
+This does the low-level grunge that uses Unix system calls to do a ``fork
+and exec'' to start up a child process.
+
+@item infptrace.c
+This is the low level interface to inferior processes for systems using
+the Unix @code{ptrace} call in a vanilla way.
+@end table
+
+@section Native core file Support
+@cindex native core files
+
+@table @file
+@findex fetch_core_registers
+@item core-aout.c::fetch_core_registers()
+Support for reading registers out of a core file. This routine calls
+@code{register_addr()}, see below. Now that BFD is used to read core
+files, virtually all machines should use @code{core-aout.c}, and should
+just provide @code{fetch_core_registers} in @code{@var{xyz}-nat.c} (or
+@code{REGISTER_U_ADDR} in @code{nm-@var{xyz}.h}).
+
+@item core-aout.c::register_addr()
+If your @code{nm-@var{xyz}.h} file defines the macro
+@code{REGISTER_U_ADDR(addr, blockend, regno)}, it should be defined to
+set @code{addr} to the offset within the @samp{user} struct of @value{GDBN}
+register number @code{regno}. @code{blockend} is the offset within the
+``upage'' of @code{u.u_ar0}. If @code{REGISTER_U_ADDR} is defined,
+@file{core-aout.c} will define the @code{register_addr()} function and
+use the macro in it. If you do not define @code{REGISTER_U_ADDR}, but
+you are using the standard @code{fetch_core_registers()}, you will need
+to define your own version of @code{register_addr()}, put it into your
+@code{@var{xyz}-nat.c} file, and be sure @code{@var{xyz}-nat.o} is in
+the @code{NATDEPFILES} list. If you have your own
+@code{fetch_core_registers()}, you may not need a separate
+@code{register_addr()}. Many custom @code{fetch_core_registers()}
+implementations simply locate the registers themselves.@refill
+@end table
+
+When making @value{GDBN} run native on a new operating system, to make it
+possible to debug core files, you will need to either write specific
+code for parsing your OS's core files, or customize
+@file{bfd/trad-core.c}. First, use whatever @code{#include} files your
+machine uses to define the struct of registers that is accessible
+(possibly in the u-area) in a core file (rather than
+@file{machine/reg.h}), and an include file that defines whatever header
+exists on a core file (e.g. the u-area or a @code{struct core}). Then
+modify @code{trad_unix_core_file_p} to use these values to set up the
+section information for the data segment, stack segment, any other
+segments in the core file (perhaps shared library contents or control
+information), ``registers'' segment, and if there are two discontiguous
+sets of registers (e.g. integer and float), the ``reg2'' segment. This
+section information basically delimits areas in the core file in a
+standard way, which the section-reading routines in BFD know how to seek
+around in.
+
+Then back in @value{GDBN}, you need a matching routine called
+@code{fetch_core_registers}. If you can use the generic one, it's in
+@file{core-aout.c}; if not, it's in your @file{@var{xyz}-nat.c} file.
+It will be passed a char pointer to the entire ``registers'' segment,
+its length, and a zero; or a char pointer to the entire ``regs2''
+segment, its length, and a 2. The routine should suck out the supplied
+register values and install them into @value{GDBN}'s ``registers'' array.
+
+If your system uses @file{/proc} to control processes, and uses ELF
+format core files, then you may be able to use the same routines for
+reading the registers out of processes and out of core files.
+
+@section ptrace
+
+@section /proc
+
+@section win32
+
+@section shared libraries
+
+@section Native Conditionals
+@cindex native conditionals
+
+When @value{GDBN} is configured and compiled, various macros are
+defined or left undefined, to control compilation when the host and
+target systems are the same. These macros should be defined (or left
+undefined) in @file{nm-@var{system}.h}.
+
+@table @code
+@item ATTACH_DETACH
+@findex ATTACH_DETACH
+If defined, then @value{GDBN} will include support for the @code{attach} and
+@code{detach} commands.
+
+@item CHILD_PREPARE_TO_STORE
+@findex CHILD_PREPARE_TO_STORE
+If the machine stores all registers at once in the child process, then
+define this to ensure that all values are correct. This usually entails
+a read from the child.
+
+[Note that this is incorrectly defined in @file{xm-@var{system}.h} files
+currently.]
+
+@item FETCH_INFERIOR_REGISTERS
+@findex FETCH_INFERIOR_REGISTERS
+Define this if the native-dependent code will provide its own routines
+@code{fetch_inferior_registers} and @code{store_inferior_registers} in
+@file{@var{host}-nat.c}. If this symbol is @emph{not} defined, and
+@file{infptrace.c} is included in this configuration, the default
+routines in @file{infptrace.c} are used for these functions.
+
+@item FILES_INFO_HOOK
+@findex FILES_INFO_HOOK
+(Only defined for Convex.)
+
+@item FP0_REGNUM
+@findex FP0_REGNUM
+This macro is normally defined to be the number of the first floating
+point register, if the machine has such registers. As such, it would
+appear only in target-specific code. However, @file{/proc} support uses this
+to decide whether floats are in use on this target.
+
+@item GET_LONGJMP_TARGET
+@findex GET_LONGJMP_TARGET
+For most machines, this is a target-dependent parameter. On the
+DECstation and the Iris, this is a native-dependent parameter, since
+@file{setjmp.h} is needed to define it.
+
+This macro determines the target PC address that @code{longjmp} will jump to,
+assuming that we have just stopped at a longjmp breakpoint. It takes a
+@code{CORE_ADDR *} as argument, and stores the target PC value through this
+pointer. It examines the current state of the machine as needed.
+
+@item I386_USE_GENERIC_WATCHPOINTS
+An x86-based machine can define this to use the generic x86 watchpoint
+support; see @ref{Algorithms, I386_USE_GENERIC_WATCHPOINTS}.
+
+@item KERNEL_U_ADDR
+@findex KERNEL_U_ADDR
+Define this to the address of the @code{u} structure (the ``user
+struct'', also known as the ``u-page'') in kernel virtual memory. @value{GDBN}
+needs to know this so that it can subtract this address from absolute
+addresses in the upage, that are obtained via ptrace or from core files.
+On systems that don't need this value, set it to zero.
+
+@item KERNEL_U_ADDR_BSD
+@findex KERNEL_U_ADDR_BSD
+Define this to cause @value{GDBN} to determine the address of @code{u} at
+runtime, by using Berkeley-style @code{nlist} on the kernel's image in
+the root directory.
+
+@item KERNEL_U_ADDR_HPUX
+@findex KERNEL_U_ADDR_HPUX
+Define this to cause @value{GDBN} to determine the address of @code{u} at
+runtime, by using HP-style @code{nlist} on the kernel's image in the
+root directory.
+
+@item ONE_PROCESS_WRITETEXT
+@findex ONE_PROCESS_WRITETEXT
+Define this to be able to, when a breakpoint insertion fails, warn the
+user that another process may be running with the same executable.
+
+@item PREPARE_TO_PROCEED (@var{select_it})
+@findex PREPARE_TO_PROCEED
+This (ugly) macro allows a native configuration to customize the way the
+@code{proceed} function in @file{infrun.c} deals with switching between
+threads.
+
+In a multi-threaded task we may select another thread and then continue
+or step. But if the old thread was stopped at a breakpoint, it will
+immediately cause another breakpoint stop without any execution (i.e. it
+will report a breakpoint hit incorrectly). So @value{GDBN} must step over it
+first.
+
+If defined, @code{PREPARE_TO_PROCEED} should check the current thread
+against the thread that reported the most recent event. If a step-over
+is required, it returns TRUE. If @var{select_it} is non-zero, it should
+reselect the old thread.
+
+@item PROC_NAME_FMT
+@findex PROC_NAME_FMT
+Defines the format for the name of a @file{/proc} device. Should be
+defined in @file{nm.h} @emph{only} in order to override the default
+definition in @file{procfs.c}.
+
+@item PTRACE_FP_BUG
+@findex PTRACE_FP_BUG
+See @file{mach386-xdep.c}.
+
+@item PTRACE_ARG3_TYPE
+@findex PTRACE_ARG3_TYPE
+The type of the third argument to the @code{ptrace} system call, if it
+exists and is different from @code{int}.
+
+@item REGISTER_U_ADDR
+@findex REGISTER_U_ADDR
+Defines the offset of the registers in the ``u area''.
+
+@item SHELL_COMMAND_CONCAT
+@findex SHELL_COMMAND_CONCAT
+If defined, is a string to prefix on the shell command used to start the
+inferior.
+
+@item SHELL_FILE
+@findex SHELL_FILE
+If defined, this is the name of the shell to use to run the inferior.
+Defaults to @code{"/bin/sh"}.
+
+@item SOLIB_ADD (@var{filename}, @var{from_tty}, @var{targ}, @var{readsyms})
+@findex SOLIB_ADD
+Define this to expand into an expression that will cause the symbols in
+@var{filename} to be added to @value{GDBN}'s symbol table. If
+@var{readsyms} is zero symbols are not read but any necessary low level
+processing for @var{filename} is still done.
+
+@item SOLIB_CREATE_INFERIOR_HOOK
+@findex SOLIB_CREATE_INFERIOR_HOOK
+Define this to expand into any shared-library-relocation code that you
+want to be run just after the child process has been forked.
+
+@item START_INFERIOR_TRAPS_EXPECTED
+@findex START_INFERIOR_TRAPS_EXPECTED
+When starting an inferior, @value{GDBN} normally expects to trap
+twice; once when
+the shell execs, and once when the program itself execs. If the actual
+number of traps is something other than 2, then define this macro to
+expand into the number expected.
+
+@item SVR4_SHARED_LIBS
+@findex SVR4_SHARED_LIBS
+Define this to indicate that SVR4-style shared libraries are in use.
+
+@item USE_PROC_FS
+@findex USE_PROC_FS
+This determines whether small routines in @file{*-tdep.c}, which
+translate register values between @value{GDBN}'s internal
+representation and the @file{/proc} representation, are compiled.
+
+@item U_REGS_OFFSET
+@findex U_REGS_OFFSET
+This is the offset of the registers in the upage. It need only be
+defined if the generic ptrace register access routines in
+@file{infptrace.c} are being used (that is, @file{infptrace.c} is
+configured in, and @code{FETCH_INFERIOR_REGISTERS} is not defined). If
+the default value from @file{infptrace.c} is good enough, leave it
+undefined.
+
+The default value means that u.u_ar0 @emph{points to} the location of
+the registers. I'm guessing that @code{#define U_REGS_OFFSET 0} means
+that @code{u.u_ar0} @emph{is} the location of the registers.
+
+@item CLEAR_SOLIB
+@findex CLEAR_SOLIB
+See @file{objfiles.c}.
+
+@item DEBUG_PTRACE
+@findex DEBUG_PTRACE
+Define this to debug @code{ptrace} calls.
+@end table
+
+
+@node Support Libraries
+
+@chapter Support Libraries
+
+@section BFD
+@cindex BFD library
+
+BFD provides support for @value{GDBN} in several ways:
+
+@table @emph
+@item identifying executable and core files
+BFD will identify a variety of file types, including a.out, coff, and
+several variants thereof, as well as several kinds of core files.
+
+@item access to sections of files
+BFD parses the file headers to determine the names, virtual addresses,
+sizes, and file locations of all the various named sections in files
+(such as the text section or the data section). @value{GDBN} simply
+calls BFD to read or write section @var{x} at byte offset @var{y} for
+length @var{z}.
+
+@item specialized core file support
+BFD provides routines to determine the failing command name stored in a
+core file, the signal with which the program failed, and whether a core
+file matches (i.e.@: could be a core dump of) a particular executable
+file.
+
+@item locating the symbol information
+@value{GDBN} uses an internal interface of BFD to determine where to find the
+symbol information in an executable file or symbol-file. @value{GDBN} itself
+handles the reading of symbols, since BFD does not ``understand'' debug
+symbols, but @value{GDBN} uses BFD's cached information to find the symbols,
+string table, etc.
+@end table
+
+@section opcodes
+@cindex opcodes library
+
+The opcodes library provides @value{GDBN}'s disassembler. (It's a separate
+library because it's also used in binutils, for @file{objdump}).
+
+@section readline
+
+@section mmalloc
+
+@section libiberty
+
+@section gnu-regex
+@cindex regular expressions library
+
+Regex conditionals.
+
+@table @code
+@item C_ALLOCA
+
+@item NFAILURES
+
+@item RE_NREGS
+
+@item SIGN_EXTEND_CHAR
+
+@item SWITCH_ENUM_BUG
+
+@item SYNTAX_TABLE
+
+@item Sword
+
+@item sparc
+@end table
+
+@section include
+
+@node Coding
+
+@chapter Coding
+
+This chapter covers topics that are lower-level than the major
+algorithms of @value{GDBN}.
+
+@section Cleanups
+@cindex cleanups
+
+Cleanups are a structured way to deal with things that need to be done
+later.
+
+When your code does something (e.g., @code{xmalloc} some memory, or
+@code{open} a file) that needs to be undone later (e.g., @code{xfree}
+the memory or @code{close} the file), it can make a cleanup. The
+cleanup will be done at some future point: when the command is finished
+and control returns to the top level; when an error occurs and the stack
+is unwound; or when your code decides it's time to explicitly perform
+cleanups. Alternatively you can elect to discard the cleanups you
+created.
+
+Syntax:
+
+@table @code
+@item struct cleanup *@var{old_chain};
+Declare a variable which will hold a cleanup chain handle.
+
+@findex make_cleanup
+@item @var{old_chain} = make_cleanup (@var{function}, @var{arg});
+Make a cleanup which will cause @var{function} to be called with
+@var{arg} (a @code{char *}) later. The result, @var{old_chain}, is a
+handle that can later be passed to @code{do_cleanups} or
+@code{discard_cleanups}. Unless you are going to call
+@code{do_cleanups} or @code{discard_cleanups}, you can ignore the result
+from @code{make_cleanup}.
+
+@findex do_cleanups
+@item do_cleanups (@var{old_chain});
+Do all cleanups added to the chain since the corresponding
+@code{make_cleanup} call was made.
+
+@findex discard_cleanups
+@item discard_cleanups (@var{old_chain});
+Same as @code{do_cleanups} except that it just removes the cleanups from
+the chain and does not call the specified functions.
+@end table
+
+Cleanups are implemented as a chain. The handle returned by
+@code{make_cleanups} includes the cleanup passed to the call and any
+later cleanups appended to the chain (but not yet discarded or
+performed). E.g.:
+
+@smallexample
+make_cleanup (a, 0);
+@{
+ struct cleanup *old = make_cleanup (b, 0);
+ make_cleanup (c, 0)
+ ...
+ do_cleanups (old);
+@}
+@end smallexample
+
+@noindent
+will call @code{c()} and @code{b()} but will not call @code{a()}. The
+cleanup that calls @code{a()} will remain in the cleanup chain, and will
+be done later unless otherwise discarded.@refill
+
+Your function should explicitly do or discard the cleanups it creates.
+Failing to do this leads to non-deterministic behavior since the caller
+will arbitrarily do or discard your functions cleanups. This need leads
+to two common cleanup styles.
+
+The first style is try/finally. Before it exits, your code-block calls
+@code{do_cleanups} with the old cleanup chain and thus ensures that your
+code-block's cleanups are always performed. For instance, the following
+code-segment avoids a memory leak problem (even when @code{error} is
+called and a forced stack unwind occurs) by ensuring that the
+@code{xfree} will always be called:
+
+@smallexample
+struct cleanup *old = make_cleanup (null_cleanup, 0);
+data = xmalloc (sizeof blah);
+make_cleanup (xfree, data);
+... blah blah ...
+do_cleanups (old);
+@end smallexample
+
+The second style is try/except. Before it exits, your code-block calls
+@code{discard_cleanups} with the old cleanup chain and thus ensures that
+any created cleanups are not performed. For instance, the following
+code segment, ensures that the file will be closed but only if there is
+an error:
+
+@smallexample
+FILE *file = fopen ("afile", "r");
+struct cleanup *old = make_cleanup (close_file, file);
+... blah blah ...
+discard_cleanups (old);
+return file;
+@end smallexample
+
+Some functions, e.g. @code{fputs_filtered()} or @code{error()}, specify
+that they ``should not be called when cleanups are not in place''. This
+means that any actions you need to reverse in the case of an error or
+interruption must be on the cleanup chain before you call these
+functions, since they might never return to your code (they
+@samp{longjmp} instead).
+
+@section Wrapping Output Lines
+@cindex line wrap in output
+
+@findex wrap_here
+Output that goes through @code{printf_filtered} or @code{fputs_filtered}
+or @code{fputs_demangled} needs only to have calls to @code{wrap_here}
+added in places that would be good breaking points. The utility
+routines will take care of actually wrapping if the line width is
+exceeded.
+
+The argument to @code{wrap_here} is an indentation string which is
+printed @emph{only} if the line breaks there. This argument is saved
+away and used later. It must remain valid until the next call to
+@code{wrap_here} or until a newline has been printed through the
+@code{*_filtered} functions. Don't pass in a local variable and then
+return!
+
+It is usually best to call @code{wrap_here} after printing a comma or
+space. If you call it before printing a space, make sure that your
+indentation properly accounts for the leading space that will print if
+the line wraps there.
+
+Any function or set of functions that produce filtered output must
+finish by printing a newline, to flush the wrap buffer, before switching
+to unfiltered (@code{printf}) output. Symbol reading routines that
+print warnings are a good example.
+
+@section @value{GDBN} Coding Standards
+@cindex coding standards
+
+@value{GDBN} follows the GNU coding standards, as described in
+@file{etc/standards.texi}. This file is also available for anonymous
+FTP from GNU archive sites. @value{GDBN} takes a strict interpretation
+of the standard; in general, when the GNU standard recommends a practice
+but does not require it, @value{GDBN} requires it.
+
+@value{GDBN} follows an additional set of coding standards specific to
+@value{GDBN}, as described in the following sections.
+
+
+@subsection ISO-C
+
+@value{GDBN} assumes an ISO-C compliant compiler.
+
+@value{GDBN} does not assume an ISO-C or POSIX compliant C library.
+
+
+@subsection Memory Management
+
+@value{GDBN} does not use the functions @code{malloc}, @code{realloc},
+@code{calloc}, @code{free} and @code{asprintf}.
+
+@value{GDBN} uses the functions @code{xmalloc}, @code{xrealloc} and
+@code{xcalloc} when allocating memory. Unlike @code{malloc} et.al.@:
+these functions do not return when the memory pool is empty. Instead,
+they unwind the stack using cleanups. These functions return
+@code{NULL} when requested to allocate a chunk of memory of size zero.
+
+@emph{Pragmatics: By using these functions, the need to check every
+memory allocation is removed. These functions provide portable
+behavior.}
+
+@value{GDBN} does not use the function @code{free}.
+
+@value{GDBN} uses the function @code{xfree} to return memory to the
+memory pool. Consistent with ISO-C, this function ignores a request to
+free a @code{NULL} pointer.
+
+@emph{Pragmatics: On some systems @code{free} fails when passed a
+@code{NULL} pointer.}
+
+@value{GDBN} can use the non-portable function @code{alloca} for the
+allocation of small temporary values (such as strings).
+
+@emph{Pragmatics: This function is very non-portable. Some systems
+restrict the memory being allocated to no more than a few kilobytes.}
+
+@value{GDBN} uses the string function @code{xstrdup} and the print
+function @code{xasprintf}.
+
+@emph{Pragmatics: @code{asprintf} and @code{strdup} can fail. Print
+functions such as @code{sprintf} are very prone to buffer overflow
+errors.}
+
+
+@subsection Compiler Warnings
+@cindex compiler warnings
+
+With few exceptions, developers should include the configuration option
+@samp{--enable-gdb-build-warnings=,-Werror} when building @value{GDBN}.
+The exceptions are listed in the file @file{gdb/MAINTAINERS}.
+
+This option causes @value{GDBN} (when built using GCC) to be compiled
+with a carefully selected list of compiler warning flags. Any warnings
+from those flags being treated as errors.
+
+The current list of warning flags includes:
+
+@table @samp
+@item -Wimplicit
+Since @value{GDBN} coding standard requires all functions to be declared
+using a prototype, the flag has the side effect of ensuring that
+prototyped functions are always visible with out resorting to
+@samp{-Wstrict-prototypes}.
+
+@item -Wreturn-type
+Such code often appears to work except on instruction set architectures
+that use register windows.
+
+@item -Wcomment
+
+@item -Wtrigraphs
+
+@item -Wformat
+Since @value{GDBN} uses the @code{format printf} attribute on all
+@code{printf} like functions this checks not just @code{printf} calls
+but also calls to functions such as @code{fprintf_unfiltered}.
+
+@item -Wparentheses
+This warning includes uses of the assignment operator within an
+@code{if} statement.
+
+@item -Wpointer-arith
+
+@item -Wuninitialized
+@end table
+
+@emph{Pragmatics: Due to the way that @value{GDBN} is implemented most
+functions have unused parameters. Consequently the warning
+@samp{-Wunused-parameter} is precluded from the list. The macro
+@code{ATTRIBUTE_UNUSED} is not used as it leads to false negatives ---
+it is not an error to have @code{ATTRIBUTE_UNUSED} on a parameter that
+is being used. The options @samp{-Wall} and @samp{-Wunused} are also
+precluded because they both include @samp{-Wunused-parameter}.}
+
+@emph{Pragmatics: @value{GDBN} has not simply accepted the warnings
+enabled by @samp{-Wall -Werror -W...}. Instead it is selecting warnings
+when and where their benefits can be demonstrated.}
+
+@subsection Formatting
+
+@cindex source code formatting
+The standard GNU recommendations for formatting must be followed
+strictly.
+
+A function declaration should not have its name in column zero. A
+function definition should have its name in column zero.
+
+@smallexample
+/* Declaration */
+static void foo (void);
+/* Definition */
+void
+foo (void)
+@{
+@}
+@end smallexample
+
+@emph{Pragmatics: This simplifies scripting. Function definitions can
+be found using @samp{^function-name}.}
+
+There must be a space between a function or macro name and the opening
+parenthesis of its argument list (except for macro definitions, as
+required by C). There must not be a space after an open paren/bracket
+or before a close paren/bracket.
+
+While additional whitespace is generally helpful for reading, do not use
+more than one blank line to separate blocks, and avoid adding whitespace
+after the end of a program line (as of 1/99, some 600 lines had
+whitespace after the semicolon). Excess whitespace causes difficulties
+for @code{diff} and @code{patch} utilities.
+
+Pointers are declared using the traditional K&R C style:
+
+@smallexample
+void *foo;
+@end smallexample
+
+@noindent
+and not:
+
+@smallexample
+void * foo;
+void* foo;
+@end smallexample
+
+@subsection Comments
+
+@cindex comment formatting
+The standard GNU requirements on comments must be followed strictly.
+
+Block comments must appear in the following form, with no @code{/*}- or
+@code{*/}-only lines, and no leading @code{*}:
+
+@smallexample
+/* Wait for control to return from inferior to debugger. If inferior
+ gets a signal, we may decide to start it up again instead of
+ returning. That is why there is a loop in this function. When
+ this function actually returns it means the inferior should be left
+ stopped and @value{GDBN} should read more commands. */
+@end smallexample
+
+(Note that this format is encouraged by Emacs; tabbing for a multi-line
+comment works correctly, and @kbd{M-q} fills the block consistently.)
+
+Put a blank line between the block comments preceding function or
+variable definitions, and the definition itself.
+
+In general, put function-body comments on lines by themselves, rather
+than trying to fit them into the 20 characters left at the end of a
+line, since either the comment or the code will inevitably get longer
+than will fit, and then somebody will have to move it anyhow.
+
+@subsection C Usage
+
+@cindex C data types
+Code must not depend on the sizes of C data types, the format of the
+host's floating point numbers, the alignment of anything, or the order
+of evaluation of expressions.
+
+@cindex function usage
+Use functions freely. There are only a handful of compute-bound areas
+in @value{GDBN} that might be affected by the overhead of a function
+call, mainly in symbol reading. Most of @value{GDBN}'s performance is
+limited by the target interface (whether serial line or system call).
+
+However, use functions with moderation. A thousand one-line functions
+are just as hard to understand as a single thousand-line function.
+
+@emph{Macros are bad, M'kay.}
+(But if you have to use a macro, make sure that the macro arguments are
+protected with parentheses.)
+
+@cindex types
+
+Declarations like @samp{struct foo *} should be used in preference to
+declarations like @samp{typedef struct foo @{ @dots{} @} *foo_ptr}.
+
+
+@subsection Function Prototypes
+@cindex function prototypes
+
+Prototypes must be used when both @emph{declaring} and @emph{defining}
+a function. Prototypes for @value{GDBN} functions must include both the
+argument type and name, with the name matching that used in the actual
+function definition.
+
+All external functions should have a declaration in a header file that
+callers include, except for @code{_initialize_*} functions, which must
+be external so that @file{init.c} construction works, but shouldn't be
+visible to random source files.
+
+Where a source file needs a forward declaration of a static function,
+that declaration must appear in a block near the top of the source file.
+
+
+@subsection Internal Error Recovery
+
+During its execution, @value{GDBN} can encounter two types of errors.
+User errors and internal errors. User errors include not only a user
+entering an incorrect command but also problems arising from corrupt
+object files and system errors when interacting with the target.
+Internal errors include situations where @value{GDBN} has detected, at
+run time, a corrupt or erroneous situation.
+
+When reporting an internal error, @value{GDBN} uses
+@code{internal_error} and @code{gdb_assert}.
+
+@value{GDBN} must not call @code{abort} or @code{assert}.
+
+@emph{Pragmatics: There is no @code{internal_warning} function. Either
+the code detected a user error, recovered from it and issued a
+@code{warning} or the code failed to correctly recover from the user
+error and issued an @code{internal_error}.}
+
+@subsection File Names
+
+Any file used when building the core of @value{GDBN} must be in lower
+case. Any file used when building the core of @value{GDBN} must be 8.3
+unique. These requirements apply to both source and generated files.
+
+@emph{Pragmatics: The core of @value{GDBN} must be buildable on many
+platforms including DJGPP and MacOS/HFS. Every time an unfriendly file
+is introduced to the build process both @file{Makefile.in} and
+@file{configure.in} need to be modified accordingly. Compare the
+convoluted conversion process needed to transform @file{COPYING} into
+@file{copying.c} with the conversion needed to transform
+@file{version.in} into @file{version.c}.}
+
+Any file non 8.3 compliant file (that is not used when building the core
+of @value{GDBN}) must be added to @file{gdb/config/djgpp/fnchange.lst}.
+
+@emph{Pragmatics: This is clearly a compromise.}
+
+When @value{GDBN} has a local version of a system header file (ex
+@file{string.h}) the file name based on the POSIX header prefixed with
+@file{gdb_} (@file{gdb_string.h}).
+
+For other files @samp{-} is used as the separator.
+
+
+@subsection Include Files
+
+All @file{.c} files should include @file{defs.h} first.
+
+All @file{.c} files should explicitly include the headers for any
+declarations they refer to. They should not rely on files being
+included indirectly.
+
+With the exception of the global definitions supplied by @file{defs.h},
+a header file should explicitly include the header declaring any
+@code{typedefs} et.al.@: it refers to.
+
+@code{extern} declarations should never appear in @code{.c} files.
+
+All include files should be wrapped in:
+
+@smallexample
+#ifndef INCLUDE_FILE_NAME_H
+#define INCLUDE_FILE_NAME_H
+header body
+#endif
+@end smallexample
+
+
+@subsection Clean Design and Portable Implementation
+
+@cindex design
+In addition to getting the syntax right, there's the little question of
+semantics. Some things are done in certain ways in @value{GDBN} because long
+experience has shown that the more obvious ways caused various kinds of
+trouble.
+
+@cindex assumptions about targets
+You can't assume the byte order of anything that comes from a target
+(including @var{value}s, object files, and instructions). Such things
+must be byte-swapped using @code{SWAP_TARGET_AND_HOST} in
+@value{GDBN}, or one of the swap routines defined in @file{bfd.h},
+such as @code{bfd_get_32}.
+
+You can't assume that you know what interface is being used to talk to
+the target system. All references to the target must go through the
+current @code{target_ops} vector.
+
+You can't assume that the host and target machines are the same machine
+(except in the ``native'' support modules). In particular, you can't
+assume that the target machine's header files will be available on the
+host machine. Target code must bring along its own header files --
+written from scratch or explicitly donated by their owner, to avoid
+copyright problems.
+
+@cindex portability
+Insertion of new @code{#ifdef}'s will be frowned upon. It's much better
+to write the code portably than to conditionalize it for various
+systems.
+
+@cindex system dependencies
+New @code{#ifdef}'s which test for specific compilers or manufacturers
+or operating systems are unacceptable. All @code{#ifdef}'s should test
+for features. The information about which configurations contain which
+features should be segregated into the configuration files. Experience
+has proven far too often that a feature unique to one particular system
+often creeps into other systems; and that a conditional based on some
+predefined macro for your current system will become worthless over
+time, as new versions of your system come out that behave differently
+with regard to this feature.
+
+Adding code that handles specific architectures, operating systems,
+target interfaces, or hosts, is not acceptable in generic code.
+
+@cindex portable file name handling
+@cindex file names, portability
+One particularly notorious area where system dependencies tend to
+creep in is handling of file names. The mainline @value{GDBN} code
+assumes Posix semantics of file names: absolute file names begin with
+a forward slash @file{/}, slashes are used to separate leading
+directories, case-sensitive file names. These assumptions are not
+necessarily true on non-Posix systems such as MS-Windows. To avoid
+system-dependent code where you need to take apart or construct a file
+name, use the following portable macros:
+
+@table @code
+@findex HAVE_DOS_BASED_FILE_SYSTEM
+@item HAVE_DOS_BASED_FILE_SYSTEM
+This preprocessing symbol is defined to a non-zero value on hosts
+whose filesystems belong to the MS-DOS/MS-Windows family. Use this
+symbol to write conditional code which should only be compiled for
+such hosts.
+
+@findex IS_DIR_SEPARATOR
+@item IS_DIR_SEPARATOR (@var{c})
+Evaluates to a non-zero value if @var{c} is a directory separator
+character. On Unix and GNU/Linux systems, only a slash @file{/} is
+such a character, but on Windows, both @file{/} and @file{\} will
+pass.
+
+@findex IS_ABSOLUTE_PATH
+@item IS_ABSOLUTE_PATH (@var{file})
+Evaluates to a non-zero value if @var{file} is an absolute file name.
+For Unix and GNU/Linux hosts, a name which begins with a slash
+@file{/} is absolute. On DOS and Windows, @file{d:/foo} and
+@file{x:\bar} are also absolute file names.
+
+@findex FILENAME_CMP
+@item FILENAME_CMP (@var{f1}, @var{f2})
+Calls a function which compares file names @var{f1} and @var{f2} as
+appropriate for the underlying host filesystem. For Posix systems,
+this simply calls @code{strcmp}; on case-insensitive filesystems it
+will call @code{strcasecmp} instead.
+
+@findex DIRNAME_SEPARATOR
+@item DIRNAME_SEPARATOR
+Evaluates to a character which separates directories in
+@code{PATH}-style lists, typically held in environment variables.
+This character is @samp{:} on Unix, @samp{;} on DOS and Windows.
+
+@findex SLASH_STRING
+@item SLASH_STRING
+This evaluates to a constant string you should use to produce an
+absolute filename from leading directories and the file's basename.
+@code{SLASH_STRING} is @code{"/"} on most systems, but might be
+@code{"\\"} for some Windows-based ports.
+@end table
+
+In addition to using these macros, be sure to use portable library
+functions whenever possible. For example, to extract a directory or a
+basename part from a file name, use the @code{dirname} and
+@code{basename} library functions (available in @code{libiberty} for
+platforms which don't provide them), instead of searching for a slash
+with @code{strrchr}.
+
+Another way to generalize @value{GDBN} along a particular interface is with an
+attribute struct. For example, @value{GDBN} has been generalized to handle
+multiple kinds of remote interfaces---not by @code{#ifdef}s everywhere, but
+by defining the @code{target_ops} structure and having a current target (as
+well as a stack of targets below it, for memory references). Whenever
+something needs to be done that depends on which remote interface we are
+using, a flag in the current target_ops structure is tested (e.g.,
+@code{target_has_stack}), or a function is called through a pointer in the
+current target_ops structure. In this way, when a new remote interface
+is added, only one module needs to be touched---the one that actually
+implements the new remote interface. Other examples of
+attribute-structs are BFD access to multiple kinds of object file
+formats, or @value{GDBN}'s access to multiple source languages.
+
+Please avoid duplicating code. For example, in @value{GDBN} 3.x all
+the code interfacing between @code{ptrace} and the rest of
+@value{GDBN} was duplicated in @file{*-dep.c}, and so changing
+something was very painful. In @value{GDBN} 4.x, these have all been
+consolidated into @file{infptrace.c}. @file{infptrace.c} can deal
+with variations between systems the same way any system-independent
+file would (hooks, @code{#if defined}, etc.), and machines which are
+radically different don't need to use @file{infptrace.c} at all.
+
+All debugging code must be controllable using the @samp{set debug
+@var{module}} command. Do not use @code{printf} to print trace
+messages. Use @code{fprintf_unfiltered(gdb_stdlog, ...}. Do not use
+@code{#ifdef DEBUG}.
+
+
+@node Porting GDB
+
+@chapter Porting @value{GDBN}
+@cindex porting to new machines
+
+Most of the work in making @value{GDBN} compile on a new machine is in
+specifying the configuration of the machine. This is done in a
+dizzying variety of header files and configuration scripts, which we
+hope to make more sensible soon. Let's say your new host is called an
+@var{xyz} (e.g., @samp{sun4}), and its full three-part configuration
+name is @code{@var{arch}-@var{xvend}-@var{xos}} (e.g.,
+@samp{sparc-sun-sunos4}). In particular:
+
+@itemize @bullet
+@item
+In the top level directory, edit @file{config.sub} and add @var{arch},
+@var{xvend}, and @var{xos} to the lists of supported architectures,
+vendors, and operating systems near the bottom of the file. Also, add
+@var{xyz} as an alias that maps to
+@code{@var{arch}-@var{xvend}-@var{xos}}. You can test your changes by
+running
+
+@smallexample
+./config.sub @var{xyz}
+@end smallexample
+
+@noindent
+and
+
+@smallexample
+./config.sub @code{@var{arch}-@var{xvend}-@var{xos}}
+@end smallexample
+
+@noindent
+which should both respond with @code{@var{arch}-@var{xvend}-@var{xos}}
+and no error messages.
+
+@noindent
+You need to port BFD, if that hasn't been done already. Porting BFD is
+beyond the scope of this manual.
+
+@item
+To configure @value{GDBN} itself, edit @file{gdb/configure.host} to recognize
+your system and set @code{gdb_host} to @var{xyz}, and (unless your
+desired target is already available) also edit @file{gdb/configure.tgt},
+setting @code{gdb_target} to something appropriate (for instance,
+@var{xyz}).
+
+@emph{Maintainer's note: Work in progress. The file
+@file{gdb/configure.host} originally needed to be modified when either a
+new native target or a new host machine was being added to @value{GDBN}.
+Recent changes have removed this requirement. The file now only needs
+to be modified when adding a new native configuration. This will likely
+changed again in the future.}
+
+@item
+Finally, you'll need to specify and define @value{GDBN}'s host-, native-, and
+target-dependent @file{.h} and @file{.c} files used for your
+configuration.
+@end itemize
+
+@section Configuring @value{GDBN} for Release
+
+@cindex preparing a release
+@cindex making a distribution tarball
+From the top level directory (containing @file{gdb}, @file{bfd},
+@file{libiberty}, and so on):
+
+@smallexample
+make -f Makefile.in gdb.tar.gz
+@end smallexample
+
+@noindent
+This will properly configure, clean, rebuild any files that are
+distributed pre-built (e.g. @file{c-exp.tab.c} or @file{refcard.ps}),
+and will then make a tarfile. (If the top level directory has already
+been configured, you can just do @code{make gdb.tar.gz} instead.)
+
+This procedure requires:
+
+@itemize @bullet
+
+@item
+symbolic links;
+
+@item
+@code{makeinfo} (texinfo2 level);
+
+@item
+@TeX{};
+
+@item
+@code{dvips};
+
+@item
+@code{yacc} or @code{bison}.
+@end itemize
+
+@noindent
+@dots{} and the usual slew of utilities (@code{sed}, @code{tar}, etc.).
+
+@subheading TEMPORARY RELEASE PROCEDURE FOR DOCUMENTATION
+
+@file{gdb.texinfo} is currently marked up using the texinfo-2 macros,
+which are not yet a default for anything (but we have to start using
+them sometime).
+
+For making paper, the only thing this implies is the right generation of
+@file{texinfo.tex} needs to be included in the distribution.
+
+For making info files, however, rather than duplicating the texinfo2
+distribution, generate @file{gdb-all.texinfo} locally, and include the
+files @file{gdb.info*} in the distribution. Note the plural;
+@code{makeinfo} will split the document into one overall file and five
+or so included files.
+
+
+@node Releasing GDB
+
+@chapter Releasing @value{GDBN}
+@cindex making a new release of gdb
+
+@section Versions and Branches
+
+@subsection Version Identifiers
+
+@value{GDBN}'s version is determined by the file @file{gdb/version.in}.
+
+@value{GDBN}'s mainline uses ISO dates to differentiate between
+versions. The CVS repository uses @var{YYYY}-@var{MM}-@var{DD}-cvs
+while the corresponding snapshot uses @var{YYYYMMDD}.
+
+@value{GDBN}'s release branch uses a slightly more complicated scheme.
+When the branch is first cut, the mainline version identifier is
+prefixed with the @var{major}.@var{minor} from of the previous release
+series but with .90 appended. As draft releases are drawn from the
+branch, the minor minor number (.90) is incremented. Once the first
+release (@var{M}.@var{N}) has been made, the version prefix is updated
+to @var{M}.@var{N}.0.90 (dot zero, dot ninety). Follow on releases have
+an incremented minor minor version number (.0).
+
+Using 5.1 (previous) and 5.2 (current), the example below illustrates a
+typical sequence of version identifiers:
+
+@table @asis
+@item 5.1.1
+final release from previous branch
+@item 2002-03-03-cvs
+main-line the day the branch is cut
+@item 5.1.90-2002-03-03-cvs
+corresponding branch version
+@item 5.1.91
+first draft release candidate
+@item 5.1.91-2002-03-17-cvs
+updated branch version
+@item 5.1.92
+second draft release candidate
+@item 5.1.92-2002-03-31-cvs
+updated branch version
+@item 5.1.93
+final release candidate (see below)
+@item 5.2
+official release
+@item 5.2.0.90-2002-04-07-cvs
+updated CVS branch version
+@item 5.2.1
+second official release
+@end table
+
+Notes:
+
+@itemize @bullet
+@item
+Minor minor minor draft release candidates such as 5.2.0.91 have been
+omitted from the example. Such release candidates are, typically, never
+made.
+@item
+For 5.1.93 the bziped tar ball @file{gdb-5.1.93.tar.bz2} is just the
+official @file{gdb-5.2.tar} renamed and compressed.
+@end itemize
+
+To avoid version conflicts, vendors are expected to modify the file
+@file{gdb/version.in} to include a vendor unique alphabetic identifier
+(an official @value{GDBN} release never uses alphabetic characters in
+its version identifer).
+
+Since @value{GDBN} does not make minor minor minor releases (e.g.,
+5.1.0.1) the conflict between that and a minor minor draft release
+identifier (e.g., 5.1.0.90) is avoided.
+
+
+@subsection Branches
+
+@value{GDBN} draws a release series (5.2, 5.2.1, @dots{}) from a single
+release branch (gdb_5_2-branch). Since minor minor minor releases
+(5.1.0.1) are not made, the need to branch the release branch is avoided
+(it also turns out that the effort required for such a a branch and
+release is significantly greater than the effort needed to create a new
+release from the head of the release branch).
+
+Releases 5.0 and 5.1 used branch and release tags of the form:
+
+@smallexample
+gdb_N_M-YYYY-MM-DD-branchpoint
+gdb_N_M-YYYY-MM-DD-branch
+gdb_M_N-YYYY-MM-DD-release
+@end smallexample
+
+Release 5.2 is trialing the branch and release tags:
+
+@smallexample
+gdb_N_M-YYYY-MM-DD-branchpoint
+gdb_N_M-branch
+gdb_M_N-YYYY-MM-DD-release
+@end smallexample
+
+@emph{Pragmatics: The branchpoint and release tags need to identify when
+a branch and release are made. The branch tag, denoting the head of the
+branch, does not have this criteria.}
+
+
+@section Branch Commit Policy
+
+The branch commit policy is pretty slack. @value{GDBN} releases 5.0,
+5.1 and 5.2 all used the below:
+
+@itemize @bullet
+@item
+The @file{gdb/MAINTAINERS} file still holds.
+@item
+Don't fix something on the branch unless/until it is also fixed in the
+trunk. If this isn't possible, mentioning it in the @file{gdb/PROBLEMS}
+file is better than committing a hack.
+@item
+When considering a patch for the branch, suggested criteria include:
+Does it fix a build? Does it fix the sequence @kbd{break main; run}
+when debugging a static binary?
+@item
+The further a change is from the core of @value{GDBN}, the less likely
+the change will worry anyone (e.g., target specific code).
+@item
+Only post a proposal to change the core of @value{GDBN} after you've
+sent individual bribes to all the people listed in the
+@file{MAINTAINERS} file @t{;-)}
+@end itemize
+
+@emph{Pragmatics: Provided updates are restricted to non-core
+functionality there is little chance that a broken change will be fatal.
+This means that changes such as adding a new architectures or (within
+reason) support for a new host are considered acceptable.}
+
+
+@section Obsolete any code
+
+Before anything else, poke the other developers (and around the source
+code) to see if there is anything that can be removed from @value{GDBN}
+(an old target, an unused file).
+
+Obsolete code is identified by adding an @code{OBSOLETE} prefix to every
+line. Doing this means that it is easy to identify obsolete code when
+grepping through the sources.
+
+The process has a number of steps and is intentionally slow --- this is
+to mainly ensure that people have had a reasonable chance to respond.
+Remember, everything on the internet takes a week.
+
+@itemize @bullet
+@item
+announce the change on @email{gdb@@sources.redhat.com, GDB mailing list}
+@item
+wait a week or so
+@item
+announce the change on @email{gdb-announce@@sources.redhat.com, GDB
+Announcement mailing list}
+@item
+wait a week or so
+@item
+go through and edit all relevant files and lines (e.g., in
+@file{configure.tgt}) so that they are prefixed with the word
+@code{OBSOLETE}.
+@end itemize
+
+@emph{Maintainer note: Removing old code, while regrettable, is a good
+thing. Firstly it helps the developers by removing code that is either
+no longer relevant or simply wrong. Secondly since it removes any
+history associated with the file (effectively clearing the slate) the
+developer has a much freer hand when it comes to fixing broken files.}
+
+
+@section Before the Branch
+
+The most important objective at this stage is to find and fix simple
+changes that become a pain to track once the branch is created. For
+instance, configuration problems that stop @value{GDBN} from even
+building. If you can't get the problem fixed, document it in the
+@file{gdb/PROBLEMS} file.
+
+@subheading Prompt for @file{gdb/NEWS}
+
+People always forget. Send a post reminding them but also if you know
+something interesting happened add it yourself. The @code{schedule}
+script will mention this in its e-mail.
+
+@subheading Review @file{gdb/README}
+
+Grab one of the nightly snapshots and then walk through the
+@file{gdb/README} looking for anything that can be improved. The
+@code{schedule} script will mention this in its e-mail.
+
+@subheading Refresh any imported files.
+
+A number of files are taken from external repositories. They include:
+
+@itemize @bullet
+@item
+@file{texinfo/texinfo.tex}
+@item
+@file{config.guess} et.@: al.@: (see the top-level @file{MAINTAINERS}
+file)
+@item
+@file{etc/standards.texi}, @file{etc/make-stds.texi}
+@end itemize
+
+@subheading Check the ARI
+
+@uref{http://sources.redhat.com/gdb/ari,,A.R.I.} is an @code{awk} script
+(Awk Regression Index ;-) that checks for a number of errors and coding
+conventions. The checks include things like using @code{malloc} instead
+of @code{xmalloc} and file naming problems. There shouldn't be any
+regressions.
+
+@subsection Review the bug data base
+
+Close anything obviously fixed.
+
+@subsection Check all cross targets build
+
+The targets are listed in @file{gdb/MAINTAINERS}.
+
+
+@section Cut the branch
+
+@subheading The dirty work
+
+I think something like the below was used:
+
+@smallexample
+$ d=`date -u +%Y-%m-%d`
+$ echo $d
+2002-01-24
+$ cvs -f -d /cvs/src rtag -D $d-gmt \
+gdb_5_1-$d-branchpoint insight+dejagnu
+$ cvs -f -d /cvs/src rtag -b -r gdb_V_V-$d-branchpoint \
+gdb_5_1-$d-branch insight+dejagnu
+$
+@end smallexample
+
+@itemize @bullet
+@item
+the @kbd{-D YYYY-MM-DD-gmt} forces the branch to an exact date/time.
+@item
+the trunk is first tagged so that the branch point can easily be found
+@item
+Insight (which includes GDB) and dejagnu are tagged at the same time
+@end itemize
+
+@subheading Post the branch info
+
+@subheading Update the web and news pages
+
+@subheading Tweak cron to track the new branch
+
+@section Stabilize the branch
+
+Something goes here.
+
+@section Create a Release
+
+The process of creating and then making available a release is broken
+down into a number of stages. The first part addresses the technical
+process of creating a releasable tar ball. The later stages address the
+process of releasing that tar ball.
+
+When making a release candidate just the first section is needed.
+
+@subsection Create a release candidate
+
+The objective at this stage is to create a set of tar balls that can be
+made available as a formal release (or as a less formal release
+candidate).
+
+@subsubheading Freeze the branch
+
+Send out an e-mail notifying everyone that the branch is frozen to
+@email{gdb-patches@@sources.redhat.com}.
+
+@subsubheading Establish a few defaults.
+
+@smallexample
+$ b=gdb_5_2-branch
+$ v=5.2
+$ t=/sourceware/snapshot-tmp/gdbadmin-tmp
+$ echo $t/$b/$v
+/sourceware/snapshot-tmp/gdbadmin-tmp/gdb_5_2-branch/5.2
+$ mkdir -p $t/$b/$v
+$ cd $t/$b/$v
+$ pwd
+/sourceware/snapshot-tmp/gdbadmin-tmp/gdb_5_2-branch/5.2
+$ which autoconf
+/home/gdbadmin/bin/autoconf
+$
+@end smallexample
+
+@noindent
+Notes:
+
+@itemize @bullet
+@item
+Check the @code{autoconf} version carefully. You want to be using the
+version taken from the @file{binutils} snapshot directory. It is very
+unlikely that a system installed version of @code{autoconf} (e.g.,
+@file{/usr/bin/autoconf}) is correct.
+@end itemize
+
+@subsubheading Check out the relevant modules:
+
+@smallexample
+$ for m in gdb insight dejagnu
+do
+( mkdir -p $m && cd $m && cvs -q -f -d /cvs/src co -P -r $b $m )
+done
+$
+@end smallexample
+
+@noindent
+Note:
+
+@itemize @bullet
+@item
+The reading of @file{.cvsrc} is disabled (@file{-f}) so that there isn't
+any confusion between what is written here and what your local
+@code{cvs} really does.
+@end itemize
+
+@subsubheading Update relevant files.
+
+@table @file
+
+@item gdb/NEWS
+
+Major releases get their comments added as part of the mainline. Minor
+releases should probably mention any significant bugs that were fixed.
+
+Don't forget to include the @file{ChangeLog} entry.
+
+@smallexample
+$ emacs gdb/src/gdb/NEWS
+...
+c-x 4 a
+...
+c-x c-s c-x c-c
+$ cp gdb/src/gdb/NEWS insight/src/gdb/NEWS
+$ cp gdb/src/gdb/ChangeLog insight/src/gdb/ChangeLog
+@end smallexample
+
+@item gdb/README
+
+You'll need to update:
+
+@itemize @bullet
+@item
+the version
+@item
+the update date
+@item
+who did it
+@end itemize
+
+@smallexample
+$ emacs gdb/src/gdb/README
+...
+c-x 4 a
+...
+c-x c-s c-x c-c
+$ cp gdb/src/gdb/README insight/src/gdb/README
+$ cp gdb/src/gdb/ChangeLog insight/src/gdb/ChangeLog
+@end smallexample
+
+@emph{Maintainer note: Hopefully the @file{README} file was reviewed
+before the initial branch was cut so just a simple substitute is needed
+to get it updated.}
+
+@emph{Maintainer note: Other projects generate @file{README} and
+@file{INSTALL} from the core documentation. This might be worth
+pursuing.}
+
+@item gdb/version.in
+
+@smallexample
+$ echo $v > gdb/src/gdb/version.in
+$ cat gdb/src/gdb/version.in
+5.2
+$ emacs gdb/src/gdb/version.in
+...
+c-x 4 a
+... Bump to version ...
+c-x c-s c-x c-c
+$ cp gdb/src/gdb/version.in insight/src/gdb/version.in
+$ cp gdb/src/gdb/ChangeLog insight/src/gdb/ChangeLog
+@end smallexample
+
+@item dejagnu/src/dejagnu/configure.in
+
+Dejagnu is more complicated. The version number is a parameter to
+@code{AM_INIT_AUTOMAKE}. Tweak it to read something like gdb-5.1.91.
+
+Don't forget to re-generate @file{configure}.
+
+Don't forget to include a @file{ChangeLog} entry.
+
+@smallexample
+$ emacs dejagnu/src/dejagnu/configure.in
+...
+c-x 4 a
+...
+c-x c-s c-x c-c
+$ ( cd dejagnu/src/dejagnu && autoconf )
+@end smallexample
+
+@end table
+
+@subsubheading Do the dirty work
+
+This is identical to the process used to create the daily snapshot.
+
+@smallexample
+$ for m in gdb insight
+do
+( cd $m/src && gmake -f Makefile.in $m.tar )
+done
+$ ( m=dejagnu; cd $m/src && gmake -f Makefile.in $m.tar.bz2 )
+@end smallexample
+
+@subsubheading Check the source files
+
+You're looking for files that have mysteriously disappeared.
+@kbd{distclean} has the habit of deleting files it shouldn't. Watch out
+for the @file{version.in} update @kbd{cronjob}.
+
+@smallexample
+$ ( cd gdb/src && cvs -f -q -n update )
+M djunpack.bat
+? gdb-5.1.91.tar
+? proto-toplev
+@dots{} lots of generated files @dots{}
+M gdb/ChangeLog
+M gdb/NEWS
+M gdb/README
+M gdb/version.in
+@dots{} lots of generated files @dots{}
+$
+@end smallexample
+
+@noindent
+@emph{Don't worry about the @file{gdb.info-??} or
+@file{gdb/p-exp.tab.c}. They were generated (and yes @file{gdb.info-1}
+was also generated only something strange with CVS means that they
+didn't get supressed). Fixing it would be nice though.}
+
+@subsubheading Create compressed versions of the release
+
+@smallexample
+$ cp */src/*.tar .
+$ cp */src/*.bz2 .
+$ ls -F
+dejagnu/ dejagnu-gdb-5.2.tar.bz2 gdb/ gdb-5.2.tar insight/ insight-5.2.tar
+$ for m in gdb insight
+do
+bzip2 -v -9 -c $m-$v.tar > $m-$v.tar.bz2
+gzip -v -9 -c $m-$v.tar > $m-$v.tar.gz
+done
+$
+@end smallexample
+
+@noindent
+Note:
+
+@itemize @bullet
+@item
+A pipe such as @kbd{bunzip2 < xxx.bz2 | gzip -9 > xxx.gz} is not since,
+in that mode, @code{gzip} does not know the name of the file and, hence,
+can not include it in the compressed file. This is also why the release
+process runs @code{tar} and @code{bzip2} as separate passes.
+@end itemize
+
+@subsection Sanity check the tar ball
+
+Pick a popular machine (Solaris/PPC?) and try the build on that.
+
+@smallexample
+$ bunzip2 < gdb-5.2.tar.bz2 | tar xpf -
+$ cd gdb-5.2
+$ ./configure
+$ make
+@dots{}
+$ ./gdb/gdb ./gdb/gdb
+GNU gdb 5.2
+@dots{}
+(gdb) b main
+Breakpoint 1 at 0x80732bc: file main.c, line 734.
+(gdb) run
+Starting program: /tmp/gdb-5.2/gdb/gdb
+
+Breakpoint 1, main (argc=1, argv=0xbffff8b4) at main.c:734
+734 catch_errors (captured_main, &args, "", RETURN_MASK_ALL);
+(gdb) print args
+$1 = @{argc = 136426532, argv = 0x821b7f0@}
+(gdb)
+@end smallexample
+
+@subsection Make a release candidate available
+
+If this is a release candidate then the only remaining steps are:
+
+@enumerate
+@item
+Commit @file{version.in} and @file{ChangeLog}
+@item
+Tweak @file{version.in} (and @file{ChangeLog} to read
+@var{L}.@var{M}.@var{N}-0000-00-00-cvs so that the version update
+process can restart.
+@item
+Make the release candidate available in
+@uref{ftp://sources.redhat.com/pub/gdb/snapshots/branch}
+@item
+Notify the relevant mailing lists ( @email{gdb@@sources.redhat.com} and
+@email{gdb-testers@@sources.redhat.com} that the candidate is available.
+@end enumerate
+
+@subsection Make a formal release available
+
+(And you thought all that was required was to post an e-mail.)
+
+@subsubheading Install on sware
+
+Copy the new files to both the release and the old release directory:
+
+@smallexample
+$ cp *.bz2 *.gz ~ftp/pub/gdb/old-releases/
+$ cp *.bz2 *.gz ~ftp/pub/gdb/releases
+@end smallexample
+
+@noindent
+Clean up the releases directory so that only the most recent releases
+are available (e.g. keep 5.2 and 5.2.1 but remove 5.1):
+
+@smallexample
+$ cd ~ftp/pub/gdb/releases
+$ rm @dots{}
+@end smallexample
+
+@noindent
+Update the file @file{README} and @file{.message} in the releases
+directory:
+
+@smallexample
+$ vi README
+@dots{}
+$ rm -f .message
+$ ln README .message
+@end smallexample
+
+@subsubheading Update the web pages.
+
+@table @file
+
+@item htdocs/download/ANNOUNCEMENT
+This file, which is posted as the official announcement, includes:
+@itemize @bullet
+@item
+General announcement
+@item
+News. If making an @var{M}.@var{N}.1 release, retain the news from
+earlier @var{M}.@var{N} release.
+@item
+Errata
+@end itemize
+
+@item htdocs/index.html
+@itemx htdocs/news/index.html
+@itemx htdocs/download/index.html
+These files include:
+@itemize @bullet
+@item
+announcement of the most recent release
+@item
+news entry (remember to update both the top level and the news directory).
+@end itemize
+These pages also need to be regenerate using @code{index.sh}.
+
+@item download/onlinedocs/
+You need to find the magic command that is used to generate the online
+docs from the @file{.tar.bz2}. The best way is to look in the output
+from one of the nightly @code{cron} jobs and then just edit accordingly.
+Something like:
+
+@smallexample
+$ ~/ss/update-web-docs \
+ ~ftp/pub/gdb/releases/gdb-5.2.tar.bz2 \
+ $PWD/www \
+ /www/sourceware/htdocs/gdb/download/onlinedocs \
+ gdb
+@end smallexample
+
+@item download/ari/
+Just like the online documentation. Something like:
+
+@smallexample
+$ /bin/sh ~/ss/update-web-ari \
+ ~ftp/pub/gdb/releases/gdb-5.2.tar.bz2 \
+ $PWD/www \
+ /www/sourceware/htdocs/gdb/download/ari \
+ gdb
+@end smallexample
+
+@end table
+
+@subsubheading Shadow the pages onto gnu
+
+Something goes here.
+
+
+@subsubheading Install the @value{GDBN} tar ball on GNU
+
+At the time of writing, the GNU machine was @kbd{gnudist.gnu.org} in
+@file{~ftp/gnu/gdb}.
+
+@subsubheading Make the @file{ANNOUNCEMENT}
+
+Post the @file{ANNOUNCEMENT} file you created above to:
+
+@itemize @bullet
+@item
+@email{gdb-announce@@sources.redhat.com, GDB Announcement mailing list}
+@item
+@email{info-gnu@@gnu.org, General GNU Announcement list} (but delay it a
+day or so to let things get out)
+@item
+@email{bug-gdb@@gnu.org, GDB Bug Report mailing list}
+@end itemize
+
+@subsection Cleanup
+
+The release is out but you're still not finished.
+
+@subsubheading Commit outstanding changes
+
+In particular you'll need to commit any changes to:
+
+@itemize @bullet
+@item
+@file{gdb/ChangeLog}
+@item
+@file{gdb/version.in}
+@item
+@file{gdb/NEWS}
+@item
+@file{gdb/README}
+@end itemize
+
+@subsubheading Tag the release
+
+Something like:
+
+@smallexample
+$ d=`date -u +%Y-%m-%d`
+$ echo $d
+2002-01-24
+$ ( cd insight/src/gdb && cvs -f -q update )
+$ ( cd insight/src && cvs -f -q tag gdb_5_2-$d-release )
+@end smallexample
+
+Insight is used since that contains more of the release than
+@value{GDBN} (@code{dejagnu} doesn't get tagged but I think we can live
+with that).
+
+@subsubheading Mention the release on the trunk
+
+Just put something in the @file{ChangeLog} so that the trunk also
+indicates when the release was made.
+
+@subsubheading Restart @file{gdb/version.in}
+
+If @file{gdb/version.in} does not contain an ISO date such as
+@kbd{2002-01-24} then the daily @code{cronjob} won't update it. Having
+committed all the release changes it can be set to
+@file{5.2.0_0000-00-00-cvs} which will restart things (yes the @kbd{_}
+is important - it affects the snapshot process).
+
+Don't forget the @file{ChangeLog}.
+
+@subsubheading Merge into trunk
+
+The files committed to the branch may also need changes merged into the
+trunk.
+
+@subsubheading Revise the release schedule
+
+Post a revised release schedule to @email{gdb@@sources.redhat.com, GDB
+Discussion List} with an updated announcement. The schedule can be
+generated by running:
+
+@smallexample
+$ ~/ss/schedule `date +%s` schedule
+@end smallexample
+
+@noindent
+The first parameter is approximate date/time in seconds (from the epoch)
+of the most recent release.
+
+Also update the schedule @code{cronjob}.
+
+@section Post release
+
+Remove any @code{OBSOLETE} code.
+
+@node Testsuite
+
+@chapter Testsuite
+@cindex test suite
+
+The testsuite is an important component of the @value{GDBN} package.
+While it is always worthwhile to encourage user testing, in practice
+this is rarely sufficient; users typically use only a small subset of
+the available commands, and it has proven all too common for a change
+to cause a significant regression that went unnoticed for some time.
+
+The @value{GDBN} testsuite uses the DejaGNU testing framework.
+DejaGNU is built using @code{Tcl} and @code{expect}. The tests
+themselves are calls to various @code{Tcl} procs; the framework runs all the
+procs and summarizes the passes and fails.
+
+@section Using the Testsuite
+
+@cindex running the test suite
+To run the testsuite, simply go to the @value{GDBN} object directory (or to the
+testsuite's objdir) and type @code{make check}. This just sets up some
+environment variables and invokes DejaGNU's @code{runtest} script. While
+the testsuite is running, you'll get mentions of which test file is in use,
+and a mention of any unexpected passes or fails. When the testsuite is
+finished, you'll get a summary that looks like this:
+
+@smallexample
+ === gdb Summary ===
+
+# of expected passes 6016
+# of unexpected failures 58
+# of unexpected successes 5
+# of expected failures 183
+# of unresolved testcases 3
+# of untested testcases 5
+@end smallexample
+
+The ideal test run consists of expected passes only; however, reality
+conspires to keep us from this ideal. Unexpected failures indicate
+real problems, whether in @value{GDBN} or in the testsuite. Expected
+failures are still failures, but ones which have been decided are too
+hard to deal with at the time; for instance, a test case might work
+everywhere except on AIX, and there is no prospect of the AIX case
+being fixed in the near future. Expected failures should not be added
+lightly, since you may be masking serious bugs in @value{GDBN}.
+Unexpected successes are expected fails that are passing for some
+reason, while unresolved and untested cases often indicate some minor
+catastrophe, such as the compiler being unable to deal with a test
+program.
+
+When making any significant change to @value{GDBN}, you should run the
+testsuite before and after the change, to confirm that there are no
+regressions. Note that truly complete testing would require that you
+run the testsuite with all supported configurations and a variety of
+compilers; however this is more than really necessary. In many cases
+testing with a single configuration is sufficient. Other useful
+options are to test one big-endian (Sparc) and one little-endian (x86)
+host, a cross config with a builtin simulator (powerpc-eabi,
+mips-elf), or a 64-bit host (Alpha).
+
+If you add new functionality to @value{GDBN}, please consider adding
+tests for it as well; this way future @value{GDBN} hackers can detect
+and fix their changes that break the functionality you added.
+Similarly, if you fix a bug that was not previously reported as a test
+failure, please add a test case for it. Some cases are extremely
+difficult to test, such as code that handles host OS failures or bugs
+in particular versions of compilers, and it's OK not to try to write
+tests for all of those.
+
+@section Testsuite Organization
+
+@cindex test suite organization
+The testsuite is entirely contained in @file{gdb/testsuite}. While the
+testsuite includes some makefiles and configury, these are very minimal,
+and used for little besides cleaning up, since the tests themselves
+handle the compilation of the programs that @value{GDBN} will run. The file
+@file{testsuite/lib/gdb.exp} contains common utility procs useful for
+all @value{GDBN} tests, while the directory @file{testsuite/config} contains
+configuration-specific files, typically used for special-purpose
+definitions of procs like @code{gdb_load} and @code{gdb_start}.
+
+The tests themselves are to be found in @file{testsuite/gdb.*} and
+subdirectories of those. The names of the test files must always end
+with @file{.exp}. DejaGNU collects the test files by wildcarding
+in the test directories, so both subdirectories and individual files
+get chosen and run in alphabetical order.
+
+The following table lists the main types of subdirectories and what they
+are for. Since DejaGNU finds test files no matter where they are
+located, and since each test file sets up its own compilation and
+execution environment, this organization is simply for convenience and
+intelligibility.
+
+@table @file
+@item gdb.base
+This is the base testsuite. The tests in it should apply to all
+configurations of @value{GDBN} (but generic native-only tests may live here).
+The test programs should be in the subset of C that is valid K&R,
+ANSI/ISO, and C++ (@code{#ifdef}s are allowed if necessary, for instance
+for prototypes).
+
+@item gdb.@var{lang}
+Language-specific tests for any language @var{lang} besides C. Examples are
+@file{gdb.c++} and @file{gdb.java}.
+
+@item gdb.@var{platform}
+Non-portable tests. The tests are specific to a specific configuration
+(host or target), such as HP-UX or eCos. Example is @file{gdb.hp}, for
+HP-UX.
+
+@item gdb.@var{compiler}
+Tests specific to a particular compiler. As of this writing (June
+1999), there aren't currently any groups of tests in this category that
+couldn't just as sensibly be made platform-specific, but one could
+imagine a @file{gdb.gcc}, for tests of @value{GDBN}'s handling of GCC
+extensions.
+
+@item gdb.@var{subsystem}
+Tests that exercise a specific @value{GDBN} subsystem in more depth. For
+instance, @file{gdb.disasm} exercises various disassemblers, while
+@file{gdb.stabs} tests pathways through the stabs symbol reader.
+@end table
+
+@section Writing Tests
+@cindex writing tests
+
+In many areas, the @value{GDBN} tests are already quite comprehensive; you
+should be able to copy existing tests to handle new cases.
+
+You should try to use @code{gdb_test} whenever possible, since it
+includes cases to handle all the unexpected errors that might happen.
+However, it doesn't cost anything to add new test procedures; for
+instance, @file{gdb.base/exprs.exp} defines a @code{test_expr} that
+calls @code{gdb_test} multiple times.
+
+Only use @code{send_gdb} and @code{gdb_expect} when absolutely
+necessary, such as when @value{GDBN} has several valid responses to a command.
+
+The source language programs do @emph{not} need to be in a consistent
+style. Since @value{GDBN} is used to debug programs written in many different
+styles, it's worth having a mix of styles in the testsuite; for
+instance, some @value{GDBN} bugs involving the display of source lines would
+never manifest themselves if the programs used GNU coding style
+uniformly.
+
+@node Hints
+
+@chapter Hints
+
+Check the @file{README} file, it often has useful information that does not
+appear anywhere else in the directory.
+
+@menu
+* Getting Started:: Getting started working on @value{GDBN}
+* Debugging GDB:: Debugging @value{GDBN} with itself
+@end menu
+
+@node Getting Started,,, Hints
+
+@section Getting Started
+
+@value{GDBN} is a large and complicated program, and if you first starting to
+work on it, it can be hard to know where to start. Fortunately, if you
+know how to go about it, there are ways to figure out what is going on.
+
+This manual, the @value{GDBN} Internals manual, has information which applies
+generally to many parts of @value{GDBN}.
+
+Information about particular functions or data structures are located in
+comments with those functions or data structures. If you run across a
+function or a global variable which does not have a comment correctly
+explaining what is does, this can be thought of as a bug in @value{GDBN}; feel
+free to submit a bug report, with a suggested comment if you can figure
+out what the comment should say. If you find a comment which is
+actually wrong, be especially sure to report that.
+
+Comments explaining the function of macros defined in host, target, or
+native dependent files can be in several places. Sometimes they are
+repeated every place the macro is defined. Sometimes they are where the
+macro is used. Sometimes there is a header file which supplies a
+default definition of the macro, and the comment is there. This manual
+also documents all the available macros.
+@c (@pxref{Host Conditionals}, @pxref{Target
+@c Conditionals}, @pxref{Native Conditionals}, and @pxref{Obsolete
+@c Conditionals})
+
+Start with the header files. Once you have some idea of how
+@value{GDBN}'s internal symbol tables are stored (see @file{symtab.h},
+@file{gdbtypes.h}), you will find it much easier to understand the
+code which uses and creates those symbol tables.
+
+You may wish to process the information you are getting somehow, to
+enhance your understanding of it. Summarize it, translate it to another
+language, add some (perhaps trivial or non-useful) feature to @value{GDBN}, use
+the code to predict what a test case would do and write the test case
+and verify your prediction, etc. If you are reading code and your eyes
+are starting to glaze over, this is a sign you need to use a more active
+approach.
+
+Once you have a part of @value{GDBN} to start with, you can find more
+specifically the part you are looking for by stepping through each
+function with the @code{next} command. Do not use @code{step} or you
+will quickly get distracted; when the function you are stepping through
+calls another function try only to get a big-picture understanding
+(perhaps using the comment at the beginning of the function being
+called) of what it does. This way you can identify which of the
+functions being called by the function you are stepping through is the
+one which you are interested in. You may need to examine the data
+structures generated at each stage, with reference to the comments in
+the header files explaining what the data structures are supposed to
+look like.
+
+Of course, this same technique can be used if you are just reading the
+code, rather than actually stepping through it. The same general
+principle applies---when the code you are looking at calls something
+else, just try to understand generally what the code being called does,
+rather than worrying about all its details.
+
+@cindex command implementation
+A good place to start when tracking down some particular area is with
+a command which invokes that feature. Suppose you want to know how
+single-stepping works. As a @value{GDBN} user, you know that the
+@code{step} command invokes single-stepping. The command is invoked
+via command tables (see @file{command.h}); by convention the function
+which actually performs the command is formed by taking the name of
+the command and adding @samp{_command}, or in the case of an
+@code{info} subcommand, @samp{_info}. For example, the @code{step}
+command invokes the @code{step_command} function and the @code{info
+display} command invokes @code{display_info}. When this convention is
+not followed, you might have to use @code{grep} or @kbd{M-x
+tags-search} in emacs, or run @value{GDBN} on itself and set a
+breakpoint in @code{execute_command}.
+
+@cindex @code{bug-gdb} mailing list
+If all of the above fail, it may be appropriate to ask for information
+on @code{bug-gdb}. But @emph{never} post a generic question like ``I was
+wondering if anyone could give me some tips about understanding
+@value{GDBN}''---if we had some magic secret we would put it in this manual.
+Suggestions for improving the manual are always welcome, of course.
+
+@node Debugging GDB,,,Hints
+
+@section Debugging @value{GDBN} with itself
+@cindex debugging @value{GDBN}
+
+If @value{GDBN} is limping on your machine, this is the preferred way to get it
+fully functional. Be warned that in some ancient Unix systems, like
+Ultrix 4.2, a program can't be running in one process while it is being
+debugged in another. Rather than typing the command @kbd{@w{./gdb
+./gdb}}, which works on Suns and such, you can copy @file{gdb} to
+@file{gdb2} and then type @kbd{@w{./gdb ./gdb2}}.
+
+When you run @value{GDBN} in the @value{GDBN} source directory, it will read a
+@file{.gdbinit} file that sets up some simple things to make debugging
+gdb easier. The @code{info} command, when executed without a subcommand
+in a @value{GDBN} being debugged by gdb, will pop you back up to the top level
+gdb. See @file{.gdbinit} for details.
+
+If you use emacs, you will probably want to do a @code{make TAGS} after
+you configure your distribution; this will put the machine dependent
+routines for your local machine where they will be accessed first by
+@kbd{M-.}
+
+Also, make sure that you've either compiled @value{GDBN} with your local cc, or
+have run @code{fixincludes} if you are compiling with gcc.
+
+@section Submitting Patches
+
+@cindex submitting patches
+Thanks for thinking of offering your changes back to the community of
+@value{GDBN} users. In general we like to get well designed enhancements.
+Thanks also for checking in advance about the best way to transfer the
+changes.
+
+The @value{GDBN} maintainers will only install ``cleanly designed'' patches.
+This manual summarizes what we believe to be clean design for @value{GDBN}.
+
+If the maintainers don't have time to put the patch in when it arrives,
+or if there is any question about a patch, it goes into a large queue
+with everyone else's patches and bug reports.
+
+@cindex legal papers for code contributions
+The legal issue is that to incorporate substantial changes requires a
+copyright assignment from you and/or your employer, granting ownership
+of the changes to the Free Software Foundation. You can get the
+standard documents for doing this by sending mail to @code{gnu@@gnu.org}
+and asking for it. We recommend that people write in "All programs
+owned by the Free Software Foundation" as "NAME OF PROGRAM", so that
+changes in many programs (not just @value{GDBN}, but GAS, Emacs, GCC,
+etc) can be
+contributed with only one piece of legalese pushed through the
+bureaucracy and filed with the FSF. We can't start merging changes until
+this paperwork is received by the FSF (their rules, which we follow
+since we maintain it for them).
+
+Technically, the easiest way to receive changes is to receive each
+feature as a small context diff or unidiff, suitable for @code{patch}.
+Each message sent to me should include the changes to C code and
+header files for a single feature, plus @file{ChangeLog} entries for
+each directory where files were modified, and diffs for any changes
+needed to the manuals (@file{gdb/doc/gdb.texinfo} or
+@file{gdb/doc/gdbint.texinfo}). If there are a lot of changes for a
+single feature, they can be split down into multiple messages.
+
+In this way, if we read and like the feature, we can add it to the
+sources with a single patch command, do some testing, and check it in.
+If you leave out the @file{ChangeLog}, we have to write one. If you leave
+out the doc, we have to puzzle out what needs documenting. Etc., etc.
+
+The reason to send each change in a separate message is that we will not
+install some of the changes. They'll be returned to you with questions
+or comments. If we're doing our job correctly, the message back to you
+will say what you have to fix in order to make the change acceptable.
+The reason to have separate messages for separate features is so that
+the acceptable changes can be installed while one or more changes are
+being reworked. If multiple features are sent in a single message, we
+tend to not put in the effort to sort out the acceptable changes from
+the unacceptable, so none of the features get installed until all are
+acceptable.
+
+If this sounds painful or authoritarian, well, it is. But we get a lot
+of bug reports and a lot of patches, and many of them don't get
+installed because we don't have the time to finish the job that the bug
+reporter or the contributor could have done. Patches that arrive
+complete, working, and well designed, tend to get installed on the day
+they arrive. The others go into a queue and get installed as time
+permits, which, since the maintainers have many demands to meet, may not
+be for quite some time.
+
+Please send patches directly to
+@email{gdb-patches@@sources.redhat.com, the @value{GDBN} maintainers}.
+
+@section Obsolete Conditionals
+@cindex obsolete code
+
+Fragments of old code in @value{GDBN} sometimes reference or set the following
+configuration macros. They should not be used by new code, and old uses
+should be removed as those parts of the debugger are otherwise touched.
+
+@table @code
+@item STACK_END_ADDR
+This macro used to define where the end of the stack appeared, for use
+in interpreting core file formats that don't record this address in the
+core file itself. This information is now configured in BFD, and @value{GDBN}
+gets the info portably from there. The values in @value{GDBN}'s configuration
+files should be moved into BFD configuration files (if needed there),
+and deleted from all of @value{GDBN}'s config files.
+
+Any @file{@var{foo}-xdep.c} file that references STACK_END_ADDR
+is so old that it has never been converted to use BFD. Now that's old!
+
+@end table
+
+@include fdl.texi
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@bye
diff --git a/gdb/doc/gpl.texi b/gdb/doc/gpl.texi
new file mode 100644
index 00000000000..be7ddc2fc08
--- /dev/null
+++ b/gdb/doc/gpl.texi
@@ -0,0 +1,409 @@
+@ignore
+@c Set file name and title for man page.
+@setfilename gpl
+@settitle GNU General Public License
+@c man begin SEEALSO
+gfdl(7), fsf-funding(7).
+@c man end
+@c man begin COPYRIGHT
+Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@c man end
+@end ignore
+@node Copying
+@c man begin DESCRIPTION
+@appendix GNU GENERAL PUBLIC LICENSE
+@center Version 2, June 1991
+
+@display
+Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@unnumberedsec Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software---to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+@iftex
+@unnumberedsec TERMS AND CONDITIONS FOR COPYING,@*DISTRIBUTION AND MODIFICATION
+@end iftex
+@ifnottex
+@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end ifnottex
+
+@enumerate 0
+@item
+This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The ``Program'', below,
+refers to any such program or work, and a ``work based on the Program''
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term ``modification''.) Each licensee is addressed as ``you''.
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+@item
+You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+@item
+You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+@enumerate a
+@item
+You must cause the modified files to carry prominent notices
+stating that you changed the files and the date of any change.
+
+@item
+You must cause any work that you distribute or publish, that in
+whole or in part contains or is derived from the Program or any
+part thereof, to be licensed as a whole at no charge to all third
+parties under the terms of this License.
+
+@item
+If the modified program normally reads commands interactively
+when run, you must cause it, when started running for such
+interactive use in the most ordinary way, to print or display an
+announcement including an appropriate copyright notice and a
+notice that there is no warranty (or else, saying that you provide
+a warranty) and that users may redistribute the program under
+these conditions, and telling the user how to view a copy of this
+License. (Exception: if the Program itself is interactive but
+does not normally print such an announcement, your work based on
+the Program is not required to print an announcement.)
+@end enumerate
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+@item
+You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+@enumerate a
+@item
+Accompany it with the complete corresponding machine-readable
+source code, which must be distributed under the terms of Sections
+1 and 2 above on a medium customarily used for software interchange; or,
+
+@item
+Accompany it with a written offer, valid for at least three
+years, to give any third party, for a charge no more than your
+cost of physically performing source distribution, a complete
+machine-readable copy of the corresponding source code, to be
+distributed under the terms of Sections 1 and 2 above on a medium
+customarily used for software interchange; or,
+
+@item
+Accompany it with the information you received as to the offer
+to distribute corresponding source code. (This alternative is
+allowed only for noncommercial distribution and only if you
+received the program in object code or executable form with such
+an offer, in accord with Subsection b above.)
+@end enumerate
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+@item
+You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+@item
+You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+@item
+Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+@item
+If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+@item
+If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+@item
+The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and ``any
+later version'', you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+@item
+If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+@iftex
+@heading NO WARRANTY
+@end iftex
+@ifnottex
+@center NO WARRANTY
+@end ifnottex
+
+@item
+BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+@item
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+@end enumerate
+
+@iftex
+@heading END OF TERMS AND CONDITIONS
+@end iftex
+@ifnottex
+@center END OF TERMS AND CONDITIONS
+@end ifnottex
+
+@page
+@unnumberedsec How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the ``copyright'' line and a pointer to where the full notice is found.
+
+@smallexample
+@var{one line to give the program's name and a brief idea of what it does.}
+Copyright (C) @var{year} @var{name of author}
+
+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.
+@end smallexample
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+@smallexample
+Gnomovision version 69, Copyright (C) @var{year} @var{name of author}
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+type `show w'.
+This is free software, and you are welcome to redistribute it
+under certain conditions; type `show c' for details.
+@end smallexample
+
+The hypothetical commands @samp{show w} and @samp{show c} should show
+the appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than @samp{show w} and
+@samp{show c}; they could even be mouse-clicks or menu items---whatever
+suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a ``copyright disclaimer'' for the program, if
+necessary. Here is a sample; alter the names:
+
+@smallexample
+Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+`Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+@var{signature of Ty Coon}, 1 April 1989
+Ty Coon, President of Vice
+@end smallexample
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+@c man end
diff --git a/gdb/doc/lpsrc.sed b/gdb/doc/lpsrc.sed
new file mode 100644
index 00000000000..1c7af4aaf48
--- /dev/null
+++ b/gdb/doc/lpsrc.sed
@@ -0,0 +1,13 @@
+/font defs: ---/,/end font defs ---/c\
+%-------------------- PostScript (long names) font defs: -----------------\
+\\font\\bbf=Times-Bold at 10pt\
+\\font\\vbbf=Times-Bold at 12pt\
+\\font\\smrm=Times-Roman at 6pt\
+\\font\\brm=Times-Roman at 10pt\
+\\font\\rm=Times-Roman at 8pt\
+\\font\\it=Times-Italic at 8pt\
+\\font\\tt=Courier at 8pt\
+% Used only for \copyright, replacing plain TeX macro.\
+\\font\\sym=Symbol at 7pt\
+\\def\\copyright{{\\sym\\char'323}}\
+%-------------------- end font defs ---------------------------------
diff --git a/gdb/doc/psrc.sed b/gdb/doc/psrc.sed
new file mode 100644
index 00000000000..9bb557eae21
--- /dev/null
+++ b/gdb/doc/psrc.sed
@@ -0,0 +1,13 @@
+/font defs: ---/,/end font defs ---/c\
+%-------------------- PostScript (K Berry names) font defs: --------------\
+\\font\\bbf=ptmb at 10pt\
+\\font\\vbbf=ptmb at 12pt\
+\\font\\smrm=ptmr at 6pt\
+\\font\\brm=ptmr at 10pt\
+\\font\\rm=ptmr at 8pt\
+\\font\\it=ptmri at 8pt\
+\\font\\tt=pcrr at 8pt\
+% Used only for \copyright, replacing plain TeX macro.\
+\\font\\sym=psyr at 7pt\
+\\def\\copyright{{\\sym\\char'323}}\
+%-------------------- end font defs ---------------------------------
diff --git a/gdb/doc/refcard.tex b/gdb/doc/refcard.tex
new file mode 100644
index 00000000000..a8de9005d9d
--- /dev/null
+++ b/gdb/doc/refcard.tex
@@ -0,0 +1,647 @@
+%%%%%%%%%%%%%%%% gdb-refcard.tex %%%%%%%%%%%%%%%%
+
+%This file is TeX source for a reference card describing GDB, the GNU debugger.
+%Copyright 1991, 1992, 1993, 1996, 1998, 1999, 2000
+%Free Software Foundation, Inc.
+%Permission is granted to make and distribute verbatim copies of
+%this reference provided the copyright notices and permission notices
+%are preserved on all copies.
+%
+%TeX markup is a programming language; accordingly this file is source
+%for a program to generate a reference.
+%
+%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, 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 can find a copy of the GNU General Public License at the URL
+%http://www.gnu.org/copyleft/gpl.html; or write to the Free Software
+%Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+%
+%You can contact the maintainer at: doc@cygnus.com
+%
+% Documentation Department
+% Cygnus Solutions
+% 1325 Chesapeake Terrace
+% Sunnyvale, CA 94089 USA
+%
+% +1 800 CYGNUS-1
+%
+%
+%
+% 22-AUG-1993 Andreas Vogel
+%
+% Modifications made in order to handle different papersizes correctly.
+% You only have to set the total width and height of the paper, the
+% horizontal and vertical margin space measured from *paper edge*
+% and the interline and interspec spacing.
+% In order to support a new papersize, you have to fiddle with the
+% latter four dimensions. Just try out a few values.
+% All other values will be computed at process time so it should be
+% quite easy to support different paper sizes - only four values to
+% guess :-)
+%
+% To find the configuration places, just search for the string
+% "CONFIGURATION".
+%
+% Andreas Vogel (av@ssw.de)
+%
+%
+%
+% Uncomment the following `magnification' command if you want to print
+% out in a larger font. Caution! You may need larger paper. You had
+% best avoid using 3-column output if you try this. See the ``Three
+% column format'' section below if you want to print in three column
+% format.
+%
+%\magnification=\magstep 1
+%
+% NOTE ON INTENTIONAL OMISSIONS: This reference card includes most GDB
+% commands, but due to space constraints there are some things I chose
+% to omit. In general, not all synonyms for commands are covered, nor
+% all variations of a command.
+% The GDB-under-Emacs section omits gdb-mode functions without default
+% keybindings. GDB startup options are not described.
+% set print sevenbit-strings, set symbol-reloading omitted.
+% printsyms, printpsyms, omitted since they're for GDB maintenance primarily
+% share omitted due to obsolescence
+% set check range/type omitted at least til code is in GDB.
+%
+%-------------------- Three column format -----------------------
+
+%%%% --- To disable three column format, comment out this entire section
+
+% Three-column format for landscape printing
+
+%-------- Papersize defs:
+
+\newdimen\totalwidth \newdimen\totalheight
+\newdimen\hmargin \newdimen\vmargin
+\newdimen\secskip \newdimen\lskip
+\newdimen\barwidth \newdimen\barheight
+\newdimen\intersecwidth
+
+%%
+%% START CONFIGURATION - PAPERSIZE DEFINITIONS
+%------- Papersize params:
+%% US letter paper (8.5x11in)
+%%
+\totalwidth=11in % total width of paper
+\totalheight=8.5in % total height of paper
+\hmargin=.25in % horizontal margin width
+\vmargin=.25in % vertical margin width
+\secskip=1pc % space between refcard secs
+\lskip=2pt % extra skip between \sec entries
+%------- end papersize params
+%%
+%% change according to personal taste, not papersize dependent
+%%
+\barwidth=.1pt % width of the cropmark bar
+\barheight=2pt % height of the cropmark bar
+\intersecwidth=0.5em % width between \itmwid and \dfnwid
+%%
+%% END CONFIGURATION - PAPERSIZE DEFINITIONS
+%%
+
+%%
+%% values to be computed - nothing to configure
+%%
+\newdimen\fullhsize % width of area without margins
+\newdimen\itmwid % width of item column
+\newdimen\dfnwid % width of definition column
+\newdimen\temp % only for temporary use
+
+%%
+%% adjust the offsets so the margins are measured *from paper edge*
+%%
+\hoffset=-1in \advance \hoffset by \hmargin
+\voffset=-1in \advance \voffset by \vmargin
+
+%%
+%% fullhsize = totalwidth - (2 * hmargin)
+%%
+\fullhsize=\totalwidth
+\temp=\hmargin \multiply \temp by 2 \advance \fullhsize by -\temp
+
+%%
+%% hsize = (fullhsize - (4 * hmargin) - (2 * barwidth)) / 3
+%%
+\hsize=\fullhsize
+\temp=\hmargin \multiply \temp by 4 \advance \hsize by -\temp
+\temp=\barwidth \multiply \temp by 2 \advance \hsize by -\temp
+\divide \hsize by 3
+
+%%
+%% vsize = totalheight - (2 * vmargin)
+%%
+\vsize=\totalheight
+\temp=\vmargin \multiply \temp by 2 \advance \vsize by -\temp
+
+%%
+%% itmwid = (hsize - intersecwidth) * 1/3
+%% dfnwid = (hsize - intersecwidth) * 2/3
+%%
+\temp=\hsize \advance \temp by -\intersecwidth \divide \temp by 3
+\itmwid=\temp
+\dfnwid=\hsize \advance \dfnwid by -\itmwid
+
+%-------- end papersize defs
+
+
+\def\fulline{\hbox to \fullhsize}
+\let\lcr=L \newbox\leftcolumn\newbox\centercolumn
+\output={\if L\lcr
+ \global\setbox\leftcolumn=\columnbox \global\let\lcr=C
+ \else
+ \if C\lcr
+ \global\setbox\centercolumn=\columnbox \global\let\lcr=R
+ \else \tripleformat \global\let\lcr=L
+ \fi
+ \fi
+% \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+ }
+
+%%
+%% START CONFIGURATION - ALTERNATIVE FOLDING GUIDES
+%%
+%% For NO printed folding guide,
+%% comment out other \def\vdecor's and uncomment:
+
+%\def\vdecor{\hskip\hmargin plus1fil\hskip\barwidth plus1fil\hskip\hmargin plus1fil}
+
+%% For SOLID LINE folding guide,
+%% comment out other \def\vdecor's and uncomment:
+
+%\def\vdecor{\hskip\hmargin plus1fil \vrule width \barwidth \hskip\hmargin plus1fil}
+
+%% For SMALL MARKS NEAR TOP AND BOTTOM as folding guide,
+%% comment out other \def\vdecor's and uncomment:
+
+\def\vdecor{\hskip\hmargin plus1fil
+\vbox to \vsize{\hbox to \barwidth{\vrule height\barheight width\barwidth}\vfill
+\hbox to \barwidth{\vrule height\barheight width\barwidth}}%THIS PERCENT SIGN IS ESSENTIAL
+\hskip\hmargin plus1fil}
+
+%%
+%% END CONFIGURATION - ALTERNATIVES FOR FOLDING GUIDES
+%%
+
+\def\tripleformat{\shipout\vbox{\fulline{\box\leftcolumn\vdecor
+ \box\centercolumn\vdecor
+ \columnbox}
+ }
+ \advancepageno}
+\def\columnbox{\leftline{\pagebody}}
+\def\bye{\par\vfill
+ \supereject
+ \if R\lcr \null\vfill\eject\fi
+ \end}
+
+%-------------------- end three column format -----------------------
+
+%-------------------- Computer Modern font defs: --------------------
+\font\bbf=cmbx10
+\font\vbbf=cmbx12
+\font\smrm=cmr6
+\font\brm=cmr10
+\font\rm=cmr7
+\font\it=cmti7
+\font\tt=cmtt8
+%-------------------- end font defs ---------------------------------
+
+%
+\hyphenpenalty=5000\tolerance=2000\raggedright\raggedbottom
+\normalbaselineskip=9pt\baselineskip=9pt
+%
+\parindent=0pt
+\parskip=0pt
+\footline={\vbox to0pt{\hss}}
+%
+\def\ctl#1{{\tt C-#1}}
+\def\opt#1{{\brm[{\rm #1}]}}
+\def\xtra#1{\noalign{\smallskip{\tt#1}}}
+%
+\long\def\sec#1;#2\endsec{\vskip \secskip
+\halign{%
+%COL 1 (of halign):
+\vtop{\hsize=\itmwid\tt
+##\par\vskip \lskip }\hfil
+%COL 2 (of halign):
+&\vtop{\hsize=\dfnwid\hangafter=1\hangindent=\intersecwidth
+\rm ##\par\vskip \lskip}\cr
+%Tail of \long\def fills in halign body with \sec args:
+\noalign{{\bbf #1}\vskip \lskip}
+#2
+}
+}
+
+{\vbbf GDB QUICK REFERENCE}\hfil{\smrm GDB Version 5}\qquad
+
+\sec Essential Commands;
+gdb {\it program} \opt{{\it core}}&debug {\it program} \opt{using
+coredump {\it core}}\cr
+b \opt{\it file\tt:}{\it function}&set breakpoint at {\it function} \opt{in \it file}\cr
+run \opt{{\it arglist}}&start your program \opt{with {\it arglist}}\cr
+bt& backtrace: display program stack\cr
+p {\it expr}&display the value of an expression\cr
+c &continue running your program\cr
+n &next line, stepping over function calls\cr
+s &next line, stepping into function calls\cr
+\endsec
+
+\sec Starting GDB;
+gdb&start GDB, with no debugging files\cr
+gdb {\it program}&begin debugging {\it program}\cr
+gdb {\it program core}&debug coredump {\it core} produced by {\it
+program}\cr
+gdb --help&describe command line options\cr
+\endsec
+
+\sec Stopping GDB;
+quit&exit GDB; also {\tt q} or {\tt EOF} (eg \ctl{d})\cr
+INTERRUPT&(eg \ctl{c}) terminate current command, or send to running process\cr
+\endsec
+
+\sec Getting Help;
+help&list classes of commands\cr
+help {\it class}&one-line descriptions for commands in {\it class}\cr
+help {\it command}&describe {\it command}\cr
+\endsec
+
+\sec Executing your Program;
+run {\it arglist}&start your program with {\it arglist}\cr
+run&start your program with current argument list\cr
+run $\ldots$ <{\it inf} >{\it outf}&start your program with input, output
+redirected\cr
+\cr
+kill&kill running program\cr
+\cr
+tty {\it dev}&use {\it dev} as stdin and stdout for next {\tt run}\cr
+set args {\it arglist}&specify {\it arglist} for next
+{\tt run}\cr
+set args&specify empty argument list\cr
+show args&display argument list\cr
+\cr
+show env&show all environment variables\cr
+show env {\it var}&show value of environment variable {\it var}\cr
+set env {\it var} {\it string}&set environment variable {\it var}\cr
+unset env {\it var}&remove {\it var} from environment\cr
+\endsec
+
+\sec Shell Commands;
+cd {\it dir}&change working directory to {\it dir}\cr
+pwd&Print working directory\cr
+make $\ldots$&call ``{\tt make}''\cr
+shell {\it cmd}&execute arbitrary shell command string\cr
+\endsec
+
+\vfill
+\line{\smrm \opt{ } surround optional arguments \hfill $\ldots$ show
+one or more arguments}
+\vskip\baselineskip
+\centerline{\smrm \copyright 1998,2000 Free Software Foundation, Inc.\qquad Permissions on back}
+\eject
+\sec Breakpoints and Watchpoints;
+break \opt{\it file\tt:}{\it line}\par
+b \opt{\it file\tt:}{\it line}&set breakpoint at {\it line} number \opt{in \it file}\par
+eg:\quad{\tt break main.c:37}\quad\cr
+break \opt{\it file\tt:}{\it func}&set breakpoint at {\it
+func} \opt{in \it file}\cr
+break +{\it offset}\par
+break -{\it offset}&set break at {\it offset} lines from current stop\cr
+break *{\it addr}&set breakpoint at address {\it addr}\cr
+break&set breakpoint at next instruction\cr
+break $\ldots$ if {\it expr}&break conditionally on nonzero {\it expr}\cr
+cond {\it n} \opt{\it expr}&new conditional expression on breakpoint
+{\it n}; make unconditional if no {\it expr}\cr
+tbreak $\ldots$&temporary break; disable when reached\cr
+rbreak {\it regex}&break on all functions matching {\it regex}\cr
+watch {\it expr}&set a watchpoint for expression {\it expr}\cr
+catch {\it event}&break at {\it event}, which may be {\tt catch}, {\tt throw},
+{\tt exec}, {\tt fork}, {\tt vfork}, {\tt load}, or {\tt unload}.\cr
+\cr
+info break&show defined breakpoints\cr
+info watch&show defined watchpoints\cr
+\cr
+clear&delete breakpoints at next instruction\cr
+clear \opt{\it file\tt:}{\it fun}&delete breakpoints at entry to {\it fun}()\cr
+clear \opt{\it file\tt:}{\it line}&delete breakpoints on source line \cr
+delete \opt{{\it n}}&delete breakpoints
+\opt{or breakpoint {\it n}}\cr
+\cr
+disable \opt{{\it n}}&disable breakpoints
+\opt{or breakpoint {\it n}}
+\cr
+enable \opt{{\it n}}&enable breakpoints
+\opt{or breakpoint {\it n}}
+\cr
+enable once \opt{{\it n}}&enable breakpoints \opt{or breakpoint {\it n}};
+disable again when reached
+\cr
+enable del \opt{{\it n}}&enable breakpoints \opt{or breakpoint {\it n}};
+delete when reached
+\cr
+\cr
+ignore {\it n} {\it count}&ignore breakpoint {\it n}, {\it count}
+times\cr
+\cr
+commands {\it n}\par
+\qquad \opt{\tt silent}\par
+\qquad {\it command-list}&execute GDB {\it command-list} every time breakpoint {\it n} is reached. \opt{{\tt silent} suppresses default
+display}\cr
+end&end of {\it command-list}\cr
+\endsec
+
+\sec Program Stack;
+backtrace \opt{\it n}\par
+bt \opt{\it n}&print trace of all frames in stack; or of {\it n}
+frames---innermost if {\it n}{\tt >0}, outermost if {\it n}{\tt <0}\cr
+frame \opt{\it n}&select frame number {\it n} or frame at address {\it
+n}; if no {\it n}, display current frame\cr
+up {\it n}&select frame {\it n} frames up\cr
+down {\it n}&select frame {\it n} frames down\cr
+info frame \opt{\it addr}&describe selected frame, or frame at
+{\it addr}\cr
+info args&arguments of selected frame\cr
+info locals&local variables of selected frame\cr
+info reg \opt{\it rn}$\ldots$\par
+info all-reg \opt{\it rn}&register values \opt{for regs {\it rn\/}} in
+selected frame; {\tt all-reg} includes floating point\cr
+\endsec
+
+\vfill\eject
+\sec Execution Control;
+continue \opt{\it count}\par
+c \opt{\it count}&continue running; if {\it count} specified, ignore
+this breakpoint next {\it count} times\cr
+\cr
+step \opt{\it count}\par
+s \opt{\it count}&execute until another line reached; repeat {\it count} times if
+specified\cr
+stepi \opt{\it count}\par
+si \opt{\it count}&step by machine instructions rather than source
+lines\cr
+\cr
+next \opt{\it count}\par
+n \opt{\it count}&execute next line, including any function calls\cr
+nexti \opt{\it count}\par
+ni \opt{\it count}&next machine instruction rather than source
+line\cr
+\cr
+until \opt{\it location}&run until next instruction (or {\it
+location})\cr
+finish&run until selected stack frame returns\cr
+return \opt{\it expr}&pop selected stack frame without executing
+\opt{setting return value}\cr
+signal {\it num}&resume execution with signal {\it s} (none if {\tt 0})\cr
+jump {\it line}\par
+jump *{\it address}&resume execution at specified {\it line} number or
+{\it address}\cr
+set var={\it expr}&evaluate {\it expr} without displaying it; use for
+altering program variables\cr
+\endsec
+
+\sec Display;
+print \opt{\tt/{\it f}\/} \opt{\it expr}\par
+p \opt{\tt/{\it f}\/} \opt{\it expr}&show value of {\it expr} \opt{or
+last value \tt \$} according to format {\it f}:\cr
+\qquad x&hexadecimal\cr
+\qquad d&signed decimal\cr
+\qquad u&unsigned decimal\cr
+\qquad o&octal\cr
+\qquad t&binary\cr
+\qquad a&address, absolute and relative\cr
+\qquad c&character\cr
+\qquad f&floating point\cr
+call \opt{\tt /{\it f}\/} {\it expr}&like {\tt print} but does not display
+{\tt void}\cr
+x \opt{\tt/{\it Nuf}\/} {\it expr}&examine memory at address {\it expr};
+optional format spec follows slash\cr
+\quad {\it N}&count of how many units to display\cr
+\quad {\it u}&unit size; one of\cr
+&{\tt\qquad b}\ individual bytes\cr
+&{\tt\qquad h}\ halfwords (two bytes)\cr
+&{\tt\qquad w}\ words (four bytes)\cr
+&{\tt\qquad g}\ giant words (eight bytes)\cr
+\quad {\it f}&printing format. Any {\tt print} format, or\cr
+&{\tt\qquad s}\ null-terminated string\cr
+&{\tt\qquad i}\ machine instructions\cr
+disassem \opt{\it addr}&display memory as machine instructions\cr
+\endsec
+
+\sec Automatic Display;
+display \opt{\tt/\it f\/} {\it expr}&show value of {\it expr} each time
+program stops \opt{according to format {\it f}\/}\cr
+display&display all enabled expressions on list\cr
+undisplay {\it n}&remove number(s) {\it n} from list of
+automatically displayed expressions\cr
+disable disp {\it n}&disable display for expression(s) number {\it
+n}\cr
+enable disp {\it n}&enable display for expression(s) number {\it
+n}\cr
+info display&numbered list of display expressions\cr
+\endsec
+
+\vfill\eject
+
+\sec Expressions;
+{\it expr}&an expression in C, C++, or Modula-2 (including function calls), or:\cr
+{\it addr\/}@{\it len}&an array of {\it len} elements beginning at {\it
+addr}\cr
+{\it file}::{\it nm}&a variable or function {\it nm} defined in {\it
+file}\cr
+$\tt\{${\it type}$\tt\}${\it addr}&read memory at {\it addr} as specified
+{\it type}\cr
+\$&most recent displayed value\cr
+\${\it n}&{\it n}th displayed value\cr
+\$\$&displayed value previous to \$\cr
+\$\${\it n}&{\it n}th displayed value back from \$\cr
+\$\_&last address examined with {\tt x}\cr
+\$\_\_&value at address \$\_\cr
+\${\it var}&convenience variable; assign any value\cr
+\cr
+show values \opt{{\it n}}&show last 10 values \opt{or surrounding
+\${\it n}}\cr
+show conv&display all convenience variables\cr
+\endsec
+
+\sec Symbol Table;
+info address {\it s}&show where symbol {\it s} is stored\cr
+info func \opt{\it regex}&show names, types of defined functions
+(all, or matching {\it regex})\cr
+info var \opt{\it regex}&show names, types of global variables (all,
+or matching {\it regex})\cr
+whatis \opt{\it expr}\par
+ptype \opt{\it expr}&show data type of {\it expr} \opt{or \tt \$}
+without evaluating; {\tt ptype} gives more detail\cr
+ptype {\it type}&describe type, struct, union, or enum\cr
+\endsec
+
+\sec GDB Scripts;
+source {\it script}&read, execute GDB commands from file {\it
+script}\cr
+\cr
+define {\it cmd}\par
+\qquad {\it command-list}&create new GDB command {\it cmd};
+execute script defined by {\it command-list}\cr
+end&end of {\it command-list}\cr
+document {\it cmd}\par
+\qquad {\it help-text}&create online documentation
+for new GDB command {\it cmd}\cr
+end&end of {\it help-text}\cr
+\endsec
+
+\sec Signals;
+handle {\it signal} {\it act}&specify GDB actions for {\it signal}:\cr
+\quad print&announce signal\cr
+\quad noprint&be silent for signal\cr
+\quad stop&halt execution on signal\cr
+\quad nostop&do not halt execution\cr
+\quad pass&allow your program to handle signal\cr
+\quad nopass&do not allow your program to see signal\cr
+info signals&show table of signals, GDB action for each\cr
+\endsec
+
+\sec Debugging Targets;
+target {\it type} {\it param}&connect to target machine, process, or file\cr
+help target&display available targets\cr
+attach {\it param}&connect to another process\cr
+detach&release target from GDB control\cr
+\endsec
+
+\vfill\eject
+\sec Controlling GDB;
+set {\it param} {\it value}&set one of GDB's internal parameters\cr
+show {\it param}&display current setting of parameter\cr
+\xtra{\rm Parameters understood by {\tt set} and {\tt show}:}
+\quad complaint {\it limit}&number of messages on unusual symbols\cr
+\quad confirm {\it on/off}&enable or disable cautionary queries\cr
+\quad editing {\it on/off}&control {\tt readline} command-line editing\cr
+\quad height {\it lpp}&number of lines before pause in display\cr
+\quad language {\it lang}&Language for GDB expressions ({\tt auto}, {\tt c} or
+{\tt modula-2})\cr
+\quad listsize {\it n}&number of lines shown by {\tt list}\cr
+\quad prompt {\it str}&use {\it str} as GDB prompt\cr
+\quad radix {\it base}&octal, decimal, or hex number representation\cr
+\quad verbose {\it on/off}&control messages when loading
+symbols\cr
+\quad width {\it cpl}&number of characters before line folded\cr
+\quad write {\it on/off}&Allow or forbid patching binary, core files
+(when reopened with {\tt exec} or {\tt core})
+\cr
+\quad history $\ldots$\par
+\quad h $\ldots$&groups with the following options:\cr
+\quad h exp {\it off/on}&disable/enable {\tt readline} history expansion\cr
+\quad h file {\it filename}&file for recording GDB command history\cr
+\quad h size {\it size}&number of commands kept in history list\cr
+\quad h save {\it off/on}&control use of external file for
+command history\cr
+\cr
+\quad print $\ldots$\par
+\quad p $\ldots$&groups with the following options:\cr
+\quad p address {\it on/off}&print memory addresses in stacks,
+values\cr
+\quad p array {\it off/on}&compact or attractive format for
+arrays\cr
+\quad p demangl {\it on/off}&source (demangled) or internal form for C++
+symbols\cr
+\quad p asm-dem {\it on/off}&demangle C++ symbols in
+machine-instruction output\cr
+\quad p elements {\it limit}&number of array elements to display\cr
+\quad p object {\it on/off}&print C++ derived types for objects\cr
+\quad p pretty {\it off/on}&struct display: compact or indented\cr
+\quad p union {\it on/off}&display of union members\cr
+\quad p vtbl {\it off/on}&display of C++ virtual function
+tables\cr
+\cr
+show commands&show last 10 commands\cr
+show commands {\it n}&show 10 commands around number {\it n}\cr
+show commands +&show next 10 commands\cr
+\endsec
+
+\sec Working Files;
+file \opt{\it file}&use {\it file} for both symbols and executable;
+with no arg, discard both\cr
+core \opt{\it file}&read {\it file} as coredump; or discard\cr
+exec \opt{\it file}&use {\it file} as executable only; or discard\cr
+symbol \opt{\it file}&use symbol table from {\it file}; or discard\cr
+load {\it file}&dynamically link {\it file\/} and add its symbols\cr
+add-sym {\it file} {\it addr}&read additional symbols from {\it file},
+dynamically loaded at {\it addr}\cr
+info files&display working files and targets in use\cr
+path {\it dirs}&add {\it dirs} to front of path searched for
+executable and symbol files\cr
+show path&display executable and symbol file path\cr
+info share&list names of shared libraries currently loaded\cr
+\endsec
+
+\vfill\eject
+\sec Source Files;
+dir {\it names}&add directory {\it names} to front of source path\cr
+dir&clear source path\cr
+show dir&show current source path\cr
+\cr
+list&show next ten lines of source\cr
+list -&show previous ten lines\cr
+list {\it lines}&display source surrounding {\it lines},
+specified as:\cr
+\quad{\opt{\it file\tt:}\it num}&line number \opt{in named file}\cr
+\quad{\opt{\it file\tt:}\it function}&beginning of function \opt{in
+named file}\cr
+\quad{\tt +\it off}&{\it off} lines after last printed\cr
+\quad{\tt -\it off}&{\it off} lines previous to last printed\cr
+\quad{\tt*\it address}&line containing {\it address}\cr
+list {\it f},{\it l}&from line {\it f} to line {\it l}\cr
+info line {\it num}&show starting, ending addresses of compiled code for
+source line {\it num}\cr
+info source&show name of current source file\cr
+info sources&list all source files in use\cr
+forw {\it regex}&search following source lines for {\it regex}\cr
+rev {\it regex}&search preceding source lines for {\it regex}\cr
+\endsec
+
+\sec GDB under GNU Emacs;
+M-x gdb&run GDB under Emacs\cr
+\ctl{h} m&describe GDB mode\cr
+M-s&step one line ({\tt step})\cr
+M-n&next line ({\tt next})\cr
+M-i&step one instruction ({\tt stepi})\cr
+\ctl{c} \ctl{f}&finish current stack frame ({\tt finish})\cr
+M-c&continue ({\tt cont})\cr
+M-u&up {\it arg} frames ({\tt up})\cr
+M-d&down {\it arg} frames ({\tt down})\cr
+\ctl{x} \&&copy number from point, insert at end\cr
+\ctl{x} SPC&(in source file) set break at point\cr
+\endsec
+
+\sec GDB License;
+show copying&Display GNU General Public License\cr
+show warranty&There is NO WARRANTY for GDB. Display full no-warranty
+statement.\cr
+\endsec
+
+
+\vfill
+{\smrm\parskip=6pt
+Copyright \copyright 1991,'92,'93,'98,2000 Free Software Foundation, Inc.
+Author: Roland H. Pesch
+
+The author assumes no responsibility for any errors on this card.
+
+This card may be freely distributed under the terms of the GNU
+General Public License.
+
+Please contribute to development of this card by
+annotating it. Improvements can be sent to bug-gdb@gnu.org.
+
+GDB itself is free software; you are welcome to distribute copies of
+it under the terms of the GNU General Public License. There is
+absolutely no warranty for GDB.
+}
+\end
diff --git a/gdb/doc/stabs.texinfo b/gdb/doc/stabs.texinfo
new file mode 100644
index 00000000000..52b88b47ff7
--- /dev/null
+++ b/gdb/doc/stabs.texinfo
@@ -0,0 +1,4037 @@
+\input texinfo
+@setfilename stabs.info
+
+@c @finalout
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* Stabs: (stabs). The "stabs" debugging information format.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@ifinfo
+This document describes the stabs debugging symbol tables.
+
+Copyright 1992,1993,1994,1995,1997,1998,2000,2001
+ Free Software Foundation, Inc.
+Contributed by Cygnus Support. Written by Julia Menapace, Jim Kingdon,
+and David MacKenzie.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
+and with the Back-Cover Texts as in (a) below.
+
+(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
+this GNU Manual, like GNU software. Copies published by the Free
+Software Foundation raise funds for GNU development.''
+@end ifinfo
+
+@setchapternewpage odd
+@settitle STABS
+@titlepage
+@title The ``stabs'' debug format
+@author Julia Menapace, Jim Kingdon, David MacKenzie
+@author Cygnus Support
+@page
+@tex
+\def\$#1${{#1}} % Kluge: collect RCS revision info without $...$
+\xdef\manvers{\$Revision$} % For use in headers, footers too
+{\parskip=0pt
+\hfill Cygnus Support\par
+\hfill \manvers\par
+\hfill \TeX{}info \texinfoversion\par
+}
+@end tex
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1992,1993,1994,1995,1997,1998,2000,2001 Free Software Foundation, Inc.
+Contributed by Cygnus Support.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
+and with the Back-Cover Texts as in (a) below.
+
+(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
+this GNU Manual, like GNU software. Copies published by the Free
+Software Foundation raise funds for GNU development.''
+
+@end titlepage
+
+@ifinfo
+@node Top
+@top The "stabs" representation of debugging information
+
+This document describes the stabs debugging format.
+
+@menu
+* Overview:: Overview of stabs
+* Program Structure:: Encoding of the structure of the program
+* Constants:: Constants
+* Variables::
+* Types:: Type definitions
+* Symbol Tables:: Symbol information in symbol tables
+* Cplusplus:: Stabs specific to C++
+* Stab Types:: Symbol types in a.out files
+* Symbol Descriptors:: Table of symbol descriptors
+* Type Descriptors:: Table of type descriptors
+* Expanded Reference:: Reference information by stab type
+* Questions:: Questions and anomalies
+* Stab Sections:: In some object file formats, stabs are
+ in sections.
+* Symbol Types Index:: Index of symbolic stab symbol type names.
+@end menu
+@end ifinfo
+
+@c TeX can handle the contents at the start but makeinfo 3.12 can not
+@iftex
+@contents
+@end iftex
+
+@node Overview
+@chapter Overview of Stabs
+
+@dfn{Stabs} refers to a format for information that describes a program
+to a debugger. This format was apparently invented by
+Peter Kessler at
+the University of California at Berkeley, for the @code{pdx} Pascal
+debugger; the format has spread widely since then.
+
+This document is one of the few published sources of documentation on
+stabs. It is believed to be comprehensive for stabs used by C. The
+lists of symbol descriptors (@pxref{Symbol Descriptors}) and type
+descriptors (@pxref{Type Descriptors}) are believed to be completely
+comprehensive. Stabs for COBOL-specific features and for variant
+records (used by Pascal and Modula-2) are poorly documented here.
+
+@c FIXME: Need to document all OS9000 stuff in GDB; see all references
+@c to os9k_stabs in stabsread.c.
+
+Other sources of information on stabs are @cite{Dbx and Dbxtool
+Interfaces}, 2nd edition, by Sun, 1988, and @cite{AIX Version 3.2 Files
+Reference}, Fourth Edition, September 1992, "dbx Stabstring Grammar" in
+the a.out section, page 2-31. This document is believed to incorporate
+the information from those two sources except where it explicitly directs
+you to them for more information.
+
+@menu
+* Flow:: Overview of debugging information flow
+* Stabs Format:: Overview of stab format
+* String Field:: The string field
+* C Example:: A simple example in C source
+* Assembly Code:: The simple example at the assembly level
+@end menu
+
+@node Flow
+@section Overview of Debugging Information Flow
+
+The GNU C compiler compiles C source in a @file{.c} file into assembly
+language in a @file{.s} file, which the assembler translates into
+a @file{.o} file, which the linker combines with other @file{.o} files and
+libraries to produce an executable file.
+
+With the @samp{-g} option, GCC puts in the @file{.s} file additional
+debugging information, which is slightly transformed by the assembler
+and linker, and carried through into the final executable. This
+debugging information describes features of the source file like line
+numbers, the types and scopes of variables, and function names,
+parameters, and scopes.
+
+For some object file formats, the debugging information is encapsulated
+in assembler directives known collectively as @dfn{stab} (symbol table)
+directives, which are interspersed with the generated code. Stabs are
+the native format for debugging information in the a.out and XCOFF
+object file formats. The GNU tools can also emit stabs in the COFF and
+ECOFF object file formats.
+
+The assembler adds the information from stabs to the symbol information
+it places by default in the symbol table and the string table of the
+@file{.o} file it is building. The linker consolidates the @file{.o}
+files into one executable file, with one symbol table and one string
+table. Debuggers use the symbol and string tables in the executable as
+a source of debugging information about the program.
+
+@node Stabs Format
+@section Overview of Stab Format
+
+There are three overall formats for stab assembler directives,
+differentiated by the first word of the stab. The name of the directive
+describes which combination of four possible data fields follows. It is
+either @code{.stabs} (string), @code{.stabn} (number), or @code{.stabd}
+(dot). IBM's XCOFF assembler uses @code{.stabx} (and some other
+directives such as @code{.file} and @code{.bi}) instead of
+@code{.stabs}, @code{.stabn} or @code{.stabd}.
+
+The overall format of each class of stab is:
+
+@example
+.stabs "@var{string}",@var{type},@var{other},@var{desc},@var{value}
+.stabn @var{type},@var{other},@var{desc},@var{value}
+.stabd @var{type},@var{other},@var{desc}
+.stabx "@var{string}",@var{value},@var{type},@var{sdb-type}
+@end example
+
+@c what is the correct term for "current file location"? My AIX
+@c assembler manual calls it "the value of the current location counter".
+For @code{.stabn} and @code{.stabd}, there is no @var{string} (the
+@code{n_strx} field is zero; see @ref{Symbol Tables}). For
+@code{.stabd}, the @var{value} field is implicit and has the value of
+the current file location. For @code{.stabx}, the @var{sdb-type} field
+is unused for stabs and can always be set to zero. The @var{other}
+field is almost always unused and can be set to zero.
+
+The number in the @var{type} field gives some basic information about
+which type of stab this is (or whether it @emph{is} a stab, as opposed
+to an ordinary symbol). Each valid type number defines a different stab
+type; further, the stab type defines the exact interpretation of, and
+possible values for, any remaining @var{string}, @var{desc}, or
+@var{value} fields present in the stab. @xref{Stab Types}, for a list
+in numeric order of the valid @var{type} field values for stab directives.
+
+@node String Field
+@section The String Field
+
+For most stabs the string field holds the meat of the
+debugging information. The flexible nature of this field
+is what makes stabs extensible. For some stab types the string field
+contains only a name. For other stab types the contents can be a great
+deal more complex.
+
+The overall format of the string field for most stab types is:
+
+@example
+"@var{name}:@var{symbol-descriptor} @var{type-information}"
+@end example
+
+@var{name} is the name of the symbol represented by the stab; it can
+contain a pair of colons (@pxref{Nested Symbols}). @var{name} can be
+omitted, which means the stab represents an unnamed object. For
+example, @samp{:t10=*2} defines type 10 as a pointer to type 2, but does
+not give the type a name. Omitting the @var{name} field is supported by
+AIX dbx and GDB after about version 4.8, but not other debuggers. GCC
+sometimes uses a single space as the name instead of omitting the name
+altogether; apparently that is supported by most debuggers.
+
+The @var{symbol-descriptor} following the @samp{:} is an alphabetic
+character that tells more specifically what kind of symbol the stab
+represents. If the @var{symbol-descriptor} is omitted, but type
+information follows, then the stab represents a local variable. For a
+list of symbol descriptors, see @ref{Symbol Descriptors}. The @samp{c}
+symbol descriptor is an exception in that it is not followed by type
+information. @xref{Constants}.
+
+@var{type-information} is either a @var{type-number}, or
+@samp{@var{type-number}=}. A @var{type-number} alone is a type
+reference, referring directly to a type that has already been defined.
+
+The @samp{@var{type-number}=} form is a type definition, where the
+number represents a new type which is about to be defined. The type
+definition may refer to other types by number, and those type numbers
+may be followed by @samp{=} and nested definitions. Also, the Lucid
+compiler will repeat @samp{@var{type-number}=} more than once if it
+wants to define several type numbers at once.
+
+In a type definition, if the character that follows the equals sign is
+non-numeric then it is a @var{type-descriptor}, and tells what kind of
+type is about to be defined. Any other values following the
+@var{type-descriptor} vary, depending on the @var{type-descriptor}.
+@xref{Type Descriptors}, for a list of @var{type-descriptor} values. If
+a number follows the @samp{=} then the number is a @var{type-reference}.
+For a full description of types, @ref{Types}.
+
+A @var{type-number} is often a single number. The GNU and Sun tools
+additionally permit a @var{type-number} to be a pair
+(@var{file-number},@var{filetype-number}) (the parentheses appear in the
+string, and serve to distinguish the two cases). The @var{file-number}
+is 0 for the base source file, 1 for the first included file, 2 for the
+next, and so on. The @var{filetype-number} is a number starting with
+1 which is incremented for each new type defined in the file.
+(Separating the file number and the type number permits the
+@code{N_BINCL} optimization to succeed more often; see @ref{Include
+Files}).
+
+There is an AIX extension for type attributes. Following the @samp{=}
+are any number of type attributes. Each one starts with @samp{@@} and
+ends with @samp{;}. Debuggers, including AIX's dbx and GDB 4.10, skip
+any type attributes they do not recognize. GDB 4.9 and other versions
+of dbx may not do this. Because of a conflict with C++
+(@pxref{Cplusplus}), new attributes should not be defined which begin
+with a digit, @samp{(}, or @samp{-}; GDB may be unable to distinguish
+those from the C++ type descriptor @samp{@@}. The attributes are:
+
+@table @code
+@item a@var{boundary}
+@var{boundary} is an integer specifying the alignment. I assume it
+applies to all variables of this type.
+
+@item p@var{integer}
+Pointer class (for checking). Not sure what this means, or how
+@var{integer} is interpreted.
+
+@item P
+Indicate this is a packed type, meaning that structure fields or array
+elements are placed more closely in memory, to save memory at the
+expense of speed.
+
+@item s@var{size}
+Size in bits of a variable of this type. This is fully supported by GDB
+4.11 and later.
+
+@item S
+Indicate that this type is a string instead of an array of characters,
+or a bitstring instead of a set. It doesn't change the layout of the
+data being represented, but does enable the debugger to know which type
+it is.
+
+@item V
+Indicate that this type is a vector instead of an array. The only
+major difference between vectors and arrays is that vectors are
+passed by value instead of by reference (vector coprocessor extension).
+
+@end table
+
+All of this can make the string field quite long. All versions of GDB,
+and some versions of dbx, can handle arbitrarily long strings. But many
+versions of dbx (or assemblers or linkers, I'm not sure which)
+cretinously limit the strings to about 80 characters, so compilers which
+must work with such systems need to split the @code{.stabs} directive
+into several @code{.stabs} directives. Each stab duplicates every field
+except the string field. The string field of every stab except the last
+is marked as continued with a backslash at the end (in the assembly code
+this may be written as a double backslash, depending on the assembler).
+Removing the backslashes and concatenating the string fields of each
+stab produces the original, long string. Just to be incompatible (or so
+they don't have to worry about what the assembler does with
+backslashes), AIX can use @samp{?} instead of backslash.
+
+@node C Example
+@section A Simple Example in C Source
+
+To get the flavor of how stabs describe source information for a C
+program, let's look at the simple program:
+
+@example
+main()
+@{
+ printf("Hello world");
+@}
+@end example
+
+When compiled with @samp{-g}, the program above yields the following
+@file{.s} file. Line numbers have been added to make it easier to refer
+to parts of the @file{.s} file in the description of the stabs that
+follows.
+
+@node Assembly Code
+@section The Simple Example at the Assembly Level
+
+This simple ``hello world'' example demonstrates several of the stab
+types used to describe C language source files.
+
+@example
+1 gcc2_compiled.:
+2 .stabs "/cygint/s1/users/jcm/play/",100,0,0,Ltext0
+3 .stabs "hello.c",100,0,0,Ltext0
+4 .text
+5 Ltext0:
+6 .stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
+7 .stabs "char:t2=r2;0;127;",128,0,0,0
+8 .stabs "long int:t3=r1;-2147483648;2147483647;",128,0,0,0
+9 .stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
+10 .stabs "long unsigned int:t5=r1;0;-1;",128,0,0,0
+11 .stabs "short int:t6=r1;-32768;32767;",128,0,0,0
+12 .stabs "long long int:t7=r1;0;-1;",128,0,0,0
+13 .stabs "short unsigned int:t8=r1;0;65535;",128,0,0,0
+14 .stabs "long long unsigned int:t9=r1;0;-1;",128,0,0,0
+15 .stabs "signed char:t10=r1;-128;127;",128,0,0,0
+16 .stabs "unsigned char:t11=r1;0;255;",128,0,0,0
+17 .stabs "float:t12=r1;4;0;",128,0,0,0
+18 .stabs "double:t13=r1;8;0;",128,0,0,0
+19 .stabs "long double:t14=r1;8;0;",128,0,0,0
+20 .stabs "void:t15=15",128,0,0,0
+21 .align 4
+22 LC0:
+23 .ascii "Hello, world!\12\0"
+24 .align 4
+25 .global _main
+26 .proc 1
+27 _main:
+28 .stabn 68,0,4,LM1
+29 LM1:
+30 !#PROLOGUE# 0
+31 save %sp,-136,%sp
+32 !#PROLOGUE# 1
+33 call ___main,0
+34 nop
+35 .stabn 68,0,5,LM2
+36 LM2:
+37 LBB2:
+38 sethi %hi(LC0),%o1
+39 or %o1,%lo(LC0),%o0
+40 call _printf,0
+41 nop
+42 .stabn 68,0,6,LM3
+43 LM3:
+44 LBE2:
+45 .stabn 68,0,6,LM4
+46 LM4:
+47 L1:
+48 ret
+49 restore
+50 .stabs "main:F1",36,0,0,_main
+51 .stabn 192,0,0,LBB2
+52 .stabn 224,0,0,LBE2
+@end example
+
+@node Program Structure
+@chapter Encoding the Structure of the Program
+
+The elements of the program structure that stabs encode include the name
+of the main function, the names of the source and include files, the
+line numbers, procedure names and types, and the beginnings and ends of
+blocks of code.
+
+@menu
+* Main Program:: Indicate what the main program is
+* Source Files:: The path and name of the source file
+* Include Files:: Names of include files
+* Line Numbers::
+* Procedures::
+* Nested Procedures::
+* Block Structure::
+* Alternate Entry Points:: Entering procedures except at the beginning.
+@end menu
+
+@node Main Program
+@section Main Program
+
+@findex N_MAIN
+Most languages allow the main program to have any name. The
+@code{N_MAIN} stab type tells the debugger the name that is used in this
+program. Only the string field is significant; it is the name of
+a function which is the main program. Most C compilers do not use this
+stab (they expect the debugger to assume that the name is @code{main}),
+but some C compilers emit an @code{N_MAIN} stab for the @code{main}
+function. I'm not sure how XCOFF handles this.
+
+@node Source Files
+@section Paths and Names of the Source Files
+
+@findex N_SO
+Before any other stabs occur, there must be a stab specifying the source
+file. This information is contained in a symbol of stab type
+@code{N_SO}; the string field contains the name of the file. The
+value of the symbol is the start address of the portion of the
+text section corresponding to that file.
+
+With the Sun Solaris2 compiler, the desc field contains a
+source-language code.
+@c Do the debuggers use it? What are the codes? -djm
+
+Some compilers (for example, GCC2 and SunOS4 @file{/bin/cc}) also
+include the directory in which the source was compiled, in a second
+@code{N_SO} symbol preceding the one containing the file name. This
+symbol can be distinguished by the fact that it ends in a slash. Code
+from the @code{cfront} C++ compiler can have additional @code{N_SO} symbols for
+nonexistent source files after the @code{N_SO} for the real source file;
+these are believed to contain no useful information.
+
+For example:
+
+@example
+.stabs "/cygint/s1/users/jcm/play/",100,0,0,Ltext0 # @r{100 is N_SO}
+.stabs "hello.c",100,0,0,Ltext0
+ .text
+Ltext0:
+@end example
+
+@findex C_FILE
+Instead of @code{N_SO} symbols, XCOFF uses a @code{.file} assembler
+directive which assembles to a @code{C_FILE} symbol; explaining this in
+detail is outside the scope of this document.
+
+@c FIXME: Exactly when should the empty N_SO be used? Why?
+If it is useful to indicate the end of a source file, this is done with
+an @code{N_SO} symbol with an empty string for the name. The value is
+the address of the end of the text section for the file. For some
+systems, there is no indication of the end of a source file, and you
+just need to figure it ended when you see an @code{N_SO} for a different
+source file, or a symbol ending in @code{.o} (which at least some
+linkers insert to mark the start of a new @code{.o} file).
+
+@node Include Files
+@section Names of Include Files
+
+There are several schemes for dealing with include files: the
+traditional @code{N_SOL} approach, Sun's @code{N_BINCL} approach, and the
+XCOFF @code{C_BINCL} approach (which despite the similar name has little in
+common with @code{N_BINCL}).
+
+@findex N_SOL
+An @code{N_SOL} symbol specifies which include file subsequent symbols
+refer to. The string field is the name of the file and the value is the
+text address corresponding to the end of the previous include file and
+the start of this one. To specify the main source file again, use an
+@code{N_SOL} symbol with the name of the main source file.
+
+@findex N_BINCL
+@findex N_EINCL
+@findex N_EXCL
+The @code{N_BINCL} approach works as follows. An @code{N_BINCL} symbol
+specifies the start of an include file. In an object file, only the
+string is significant; the linker puts data into some of the other
+fields. The end of the include file is marked by an @code{N_EINCL}
+symbol (which has no string field). In an object file, there is no
+significant data in the @code{N_EINCL} symbol. @code{N_BINCL} and
+@code{N_EINCL} can be nested.
+
+If the linker detects that two source files have identical stabs between
+an @code{N_BINCL} and @code{N_EINCL} pair (as will generally be the case
+for a header file), then it only puts out the stabs once. Each
+additional occurrence is replaced by an @code{N_EXCL} symbol. I believe
+the GNU linker and the Sun (both SunOS4 and Solaris) linker are the only
+ones which supports this feature.
+
+A linker which supports this feature will set the value of a
+@code{N_BINCL} symbol to the total of all the characters in the stabs
+strings included in the header file, omitting any file numbers. The
+value of an @code{N_EXCL} symbol is the same as the value of the
+@code{N_BINCL} symbol it replaces. This information can be used to
+match up @code{N_EXCL} and @code{N_BINCL} symbols which have the same
+filename. The @code{N_EINCL} value, and the values of the other and
+description fields for all three, appear to always be zero.
+
+@findex C_BINCL
+@findex C_EINCL
+For the start of an include file in XCOFF, use the @file{.bi} assembler
+directive, which generates a @code{C_BINCL} symbol. A @file{.ei}
+directive, which generates a @code{C_EINCL} symbol, denotes the end of
+the include file. Both directives are followed by the name of the
+source file in quotes, which becomes the string for the symbol.
+The value of each symbol, produced automatically by the assembler
+and linker, is the offset into the executable of the beginning
+(inclusive, as you'd expect) or end (inclusive, as you would not expect)
+of the portion of the COFF line table that corresponds to this include
+file. @code{C_BINCL} and @code{C_EINCL} do not nest.
+
+@node Line Numbers
+@section Line Numbers
+
+@findex N_SLINE
+An @code{N_SLINE} symbol represents the start of a source line. The
+desc field contains the line number and the value contains the code
+address for the start of that source line. On most machines the address
+is absolute; for stabs in sections (@pxref{Stab Sections}), it is
+relative to the function in which the @code{N_SLINE} symbol occurs.
+
+@findex N_DSLINE
+@findex N_BSLINE
+GNU documents @code{N_DSLINE} and @code{N_BSLINE} symbols for line
+numbers in the data or bss segments, respectively. They are identical
+to @code{N_SLINE} but are relocated differently by the linker. They
+were intended to be used to describe the source location of a variable
+declaration, but I believe that GCC2 actually puts the line number in
+the desc field of the stab for the variable itself. GDB has been
+ignoring these symbols (unless they contain a string field) since
+at least GDB 3.5.
+
+For single source lines that generate discontiguous code, such as flow
+of control statements, there may be more than one line number entry for
+the same source line. In this case there is a line number entry at the
+start of each code range, each with the same line number.
+
+XCOFF does not use stabs for line numbers. Instead, it uses COFF line
+numbers (which are outside the scope of this document). Standard COFF
+line numbers cannot deal with include files, but in XCOFF this is fixed
+with the @code{C_BINCL} method of marking include files (@pxref{Include
+Files}).
+
+@node Procedures
+@section Procedures
+
+@findex N_FUN, for functions
+@findex N_FNAME
+@findex N_STSYM, for functions (Sun acc)
+@findex N_GSYM, for functions (Sun acc)
+All of the following stabs normally use the @code{N_FUN} symbol type.
+However, Sun's @code{acc} compiler on SunOS4 uses @code{N_GSYM} and
+@code{N_STSYM}, which means that the value of the stab for the function
+is useless and the debugger must get the address of the function from
+the non-stab symbols instead. On systems where non-stab symbols have
+leading underscores, the stabs will lack underscores and the debugger
+needs to know about the leading underscore to match up the stab and the
+non-stab symbol. BSD Fortran is said to use @code{N_FNAME} with the
+same restriction; the value of the symbol is not useful (I'm not sure it
+really does use this, because GDB doesn't handle this and no one has
+complained).
+
+@findex C_FUN
+A function is represented by an @samp{F} symbol descriptor for a global
+(extern) function, and @samp{f} for a static (local) function. For
+a.out, the value of the symbol is the address of the start of the
+function; it is already relocated. For stabs in ELF, the SunPRO
+compiler version 2.0.1 and GCC put out an address which gets relocated
+by the linker. In a future release SunPRO is planning to put out zero,
+in which case the address can be found from the ELF (non-stab) symbol.
+Because looking things up in the ELF symbols would probably be slow, I'm
+not sure how to find which symbol of that name is the right one, and
+this doesn't provide any way to deal with nested functions, it would
+probably be better to make the value of the stab an address relative to
+the start of the file, or just absolute. See @ref{ELF Linker
+Relocation} for more information on linker relocation of stabs in ELF
+files. For XCOFF, the stab uses the @code{C_FUN} storage class and the
+value of the stab is meaningless; the address of the function can be
+found from the csect symbol (XTY_LD/XMC_PR).
+
+The type information of the stab represents the return type of the
+function; thus @samp{foo:f5} means that foo is a function returning type
+5. There is no need to try to get the line number of the start of the
+function from the stab for the function; it is in the next
+@code{N_SLINE} symbol.
+
+@c FIXME: verify whether the "I suspect" below is true or not.
+Some compilers (such as Sun's Solaris compiler) support an extension for
+specifying the types of the arguments. I suspect this extension is not
+used for old (non-prototyped) function definitions in C. If the
+extension is in use, the type information of the stab for the function
+is followed by type information for each argument, with each argument
+preceded by @samp{;}. An argument type of 0 means that additional
+arguments are being passed, whose types and number may vary (@samp{...}
+in ANSI C). GDB has tolerated this extension (parsed the syntax, if not
+necessarily used the information) since at least version 4.8; I don't
+know whether all versions of dbx tolerate it. The argument types given
+here are not redundant with the symbols for the formal parameters
+(@pxref{Parameters}); they are the types of the arguments as they are
+passed, before any conversions might take place. For example, if a C
+function which is declared without a prototype takes a @code{float}
+argument, the value is passed as a @code{double} but then converted to a
+@code{float}. Debuggers need to use the types given in the arguments
+when printing values, but when calling the function they need to use the
+types given in the symbol defining the function.
+
+If the return type and types of arguments of a function which is defined
+in another source file are specified (i.e., a function prototype in ANSI
+C), traditionally compilers emit no stab; the only way for the debugger
+to find the information is if the source file where the function is
+defined was also compiled with debugging symbols. As an extension the
+Solaris compiler uses symbol descriptor @samp{P} followed by the return
+type of the function, followed by the arguments, each preceded by
+@samp{;}, as in a stab with symbol descriptor @samp{f} or @samp{F}.
+This use of symbol descriptor @samp{P} can be distinguished from its use
+for register parameters (@pxref{Register Parameters}) by the fact that it has
+symbol type @code{N_FUN}.
+
+The AIX documentation also defines symbol descriptor @samp{J} as an
+internal function. I assume this means a function nested within another
+function. It also says symbol descriptor @samp{m} is a module in
+Modula-2 or extended Pascal.
+
+Procedures (functions which do not return values) are represented as
+functions returning the @code{void} type in C. I don't see why this couldn't
+be used for all languages (inventing a @code{void} type for this purpose if
+necessary), but the AIX documentation defines @samp{I}, @samp{P}, and
+@samp{Q} for internal, global, and static procedures, respectively.
+These symbol descriptors are unusual in that they are not followed by
+type information.
+
+The following example shows a stab for a function @code{main} which
+returns type number @code{1}. The @code{_main} specified for the value
+is a reference to an assembler label which is used to fill in the start
+address of the function.
+
+@example
+.stabs "main:F1",36,0,0,_main # @r{36 is N_FUN}
+@end example
+
+The stab representing a procedure is located immediately following the
+code of the procedure. This stab is in turn directly followed by a
+group of other stabs describing elements of the procedure. These other
+stabs describe the procedure's parameters, its block local variables, and
+its block structure.
+
+If functions can appear in different sections, then the debugger may not
+be able to find the end of a function. Recent versions of GCC will mark
+the end of a function with an @code{N_FUN} symbol with an empty string
+for the name. The value is the address of the end of the current
+function. Without such a symbol, there is no indication of the address
+of the end of a function, and you must assume that it ended at the
+starting address of the next function or at the end of the text section
+for the program.
+
+@node Nested Procedures
+@section Nested Procedures
+
+For any of the symbol descriptors representing procedures, after the
+symbol descriptor and the type information is optionally a scope
+specifier. This consists of a comma, the name of the procedure, another
+comma, and the name of the enclosing procedure. The first name is local
+to the scope specified, and seems to be redundant with the name of the
+symbol (before the @samp{:}). This feature is used by GCC, and
+presumably Pascal, Modula-2, etc., compilers, for nested functions.
+
+If procedures are nested more than one level deep, only the immediately
+containing scope is specified. For example, this code:
+
+@example
+int
+foo (int x)
+@{
+ int bar (int y)
+ @{
+ int baz (int z)
+ @{
+ return x + y + z;
+ @}
+ return baz (x + 2 * y);
+ @}
+ return x + bar (3 * x);
+@}
+@end example
+
+@noindent
+produces the stabs:
+
+@example
+.stabs "baz:f1,baz,bar",36,0,0,_baz.15 # @r{36 is N_FUN}
+.stabs "bar:f1,bar,foo",36,0,0,_bar.12
+.stabs "foo:F1",36,0,0,_foo
+@end example
+
+@node Block Structure
+@section Block Structure
+
+@findex N_LBRAC
+@findex N_RBRAC
+@c For GCC 2.5.8 or so stabs-in-coff, these are absolute instead of
+@c function relative (as documented below). But GDB has never been able
+@c to deal with that (it had wanted them to be relative to the file, but
+@c I just fixed that (between GDB 4.12 and 4.13)), so it is function
+@c relative just like ELF and SOM and the below documentation.
+The program's block structure is represented by the @code{N_LBRAC} (left
+brace) and the @code{N_RBRAC} (right brace) stab types. The variables
+defined inside a block precede the @code{N_LBRAC} symbol for most
+compilers, including GCC. Other compilers, such as the Convex, Acorn
+RISC machine, and Sun @code{acc} compilers, put the variables after the
+@code{N_LBRAC} symbol. The values of the @code{N_LBRAC} and
+@code{N_RBRAC} symbols are the start and end addresses of the code of
+the block, respectively. For most machines, they are relative to the
+starting address of this source file. For the Gould NP1, they are
+absolute. For stabs in sections (@pxref{Stab Sections}), they are
+relative to the function in which they occur.
+
+The @code{N_LBRAC} and @code{N_RBRAC} stabs that describe the block
+scope of a procedure are located after the @code{N_FUN} stab that
+represents the procedure itself.
+
+Sun documents the desc field of @code{N_LBRAC} and
+@code{N_RBRAC} symbols as containing the nesting level of the block.
+However, dbx seems to not care, and GCC always sets desc to
+zero.
+
+@findex .bb
+@findex .be
+@findex C_BLOCK
+For XCOFF, block scope is indicated with @code{C_BLOCK} symbols. If the
+name of the symbol is @samp{.bb}, then it is the beginning of the block;
+if the name of the symbol is @samp{.be}; it is the end of the block.
+
+@node Alternate Entry Points
+@section Alternate Entry Points
+
+@findex N_ENTRY
+@findex C_ENTRY
+Some languages, like Fortran, have the ability to enter procedures at
+some place other than the beginning. One can declare an alternate entry
+point. The @code{N_ENTRY} stab is for this; however, the Sun FORTRAN
+compiler doesn't use it. According to AIX documentation, only the name
+of a @code{C_ENTRY} stab is significant; the address of the alternate
+entry point comes from the corresponding external symbol. A previous
+revision of this document said that the value of an @code{N_ENTRY} stab
+was the address of the alternate entry point, but I don't know the
+source for that information.
+
+@node Constants
+@chapter Constants
+
+The @samp{c} symbol descriptor indicates that this stab represents a
+constant. This symbol descriptor is an exception to the general rule
+that symbol descriptors are followed by type information. Instead, it
+is followed by @samp{=} and one of the following:
+
+@table @code
+@item b @var{value}
+Boolean constant. @var{value} is a numeric value; I assume it is 0 for
+false or 1 for true.
+
+@item c @var{value}
+Character constant. @var{value} is the numeric value of the constant.
+
+@item e @var{type-information} , @var{value}
+Constant whose value can be represented as integral.
+@var{type-information} is the type of the constant, as it would appear
+after a symbol descriptor (@pxref{String Field}). @var{value} is the
+numeric value of the constant. GDB 4.9 does not actually get the right
+value if @var{value} does not fit in a host @code{int}, but it does not
+do anything violent, and future debuggers could be extended to accept
+integers of any size (whether unsigned or not). This constant type is
+usually documented as being only for enumeration constants, but GDB has
+never imposed that restriction; I don't know about other debuggers.
+
+@item i @var{value}
+Integer constant. @var{value} is the numeric value. The type is some
+sort of generic integer type (for GDB, a host @code{int}); to specify
+the type explicitly, use @samp{e} instead.
+
+@item r @var{value}
+Real constant. @var{value} is the real value, which can be @samp{INF}
+(optionally preceded by a sign) for infinity, @samp{QNAN} for a quiet
+NaN (not-a-number), or @samp{SNAN} for a signalling NaN. If it is a
+normal number the format is that accepted by the C library function
+@code{atof}.
+
+@item s @var{string}
+String constant. @var{string} is a string enclosed in either @samp{'}
+(in which case @samp{'} characters within the string are represented as
+@samp{\'} or @samp{"} (in which case @samp{"} characters within the
+string are represented as @samp{\"}).
+
+@item S @var{type-information} , @var{elements} , @var{bits} , @var{pattern}
+Set constant. @var{type-information} is the type of the constant, as it
+would appear after a symbol descriptor (@pxref{String Field}).
+@var{elements} is the number of elements in the set (does this means
+how many bits of @var{pattern} are actually used, which would be
+redundant with the type, or perhaps the number of bits set in
+@var{pattern}? I don't get it), @var{bits} is the number of bits in the
+constant (meaning it specifies the length of @var{pattern}, I think),
+and @var{pattern} is a hexadecimal representation of the set. AIX
+documentation refers to a limit of 32 bytes, but I see no reason why
+this limit should exist. This form could probably be used for arbitrary
+constants, not just sets; the only catch is that @var{pattern} should be
+understood to be target, not host, byte order and format.
+@end table
+
+The boolean, character, string, and set constants are not supported by
+GDB 4.9, but it ignores them. GDB 4.8 and earlier gave an error
+message and refused to read symbols from the file containing the
+constants.
+
+The above information is followed by @samp{;}.
+
+@node Variables
+@chapter Variables
+
+Different types of stabs describe the various ways that variables can be
+allocated: on the stack, globally, in registers, in common blocks,
+statically, or as arguments to a function.
+
+@menu
+* Stack Variables:: Variables allocated on the stack.
+* Global Variables:: Variables used by more than one source file.
+* Register Variables:: Variables in registers.
+* Common Blocks:: Variables statically allocated together.
+* Statics:: Variables local to one source file.
+* Based Variables:: Fortran pointer based variables.
+* Parameters:: Variables for arguments to functions.
+@end menu
+
+@node Stack Variables
+@section Automatic Variables Allocated on the Stack
+
+If a variable's scope is local to a function and its lifetime is only as
+long as that function executes (C calls such variables
+@dfn{automatic}), it can be allocated in a register (@pxref{Register
+Variables}) or on the stack.
+
+@findex N_LSYM, for stack variables
+@findex C_LSYM
+Each variable allocated on the stack has a stab with the symbol
+descriptor omitted. Since type information should begin with a digit,
+@samp{-}, or @samp{(}, only those characters precluded from being used
+for symbol descriptors. However, the Acorn RISC machine (ARM) is said
+to get this wrong: it puts out a mere type definition here, without the
+preceding @samp{@var{type-number}=}. This is a bad idea; there is no
+guarantee that type descriptors are distinct from symbol descriptors.
+Stabs for stack variables use the @code{N_LSYM} stab type, or
+@code{C_LSYM} for XCOFF.
+
+The value of the stab is the offset of the variable within the
+local variables. On most machines this is an offset from the frame
+pointer and is negative. The location of the stab specifies which block
+it is defined in; see @ref{Block Structure}.
+
+For example, the following C code:
+
+@example
+int
+main ()
+@{
+ int x;
+@}
+@end example
+
+produces the following stabs:
+
+@example
+.stabs "main:F1",36,0,0,_main # @r{36 is N_FUN}
+.stabs "x:1",128,0,0,-12 # @r{128 is N_LSYM}
+.stabn 192,0,0,LBB2 # @r{192 is N_LBRAC}
+.stabn 224,0,0,LBE2 # @r{224 is N_RBRAC}
+@end example
+
+See @ref{Procedures} for more information on the @code{N_FUN} stab, and
+@ref{Block Structure} for more information on the @code{N_LBRAC} and
+@code{N_RBRAC} stabs.
+
+@node Global Variables
+@section Global Variables
+
+@findex N_GSYM
+@findex C_GSYM
+@c FIXME: verify for sure that it really is C_GSYM on XCOFF
+A variable whose scope is not specific to just one source file is
+represented by the @samp{G} symbol descriptor. These stabs use the
+@code{N_GSYM} stab type (C_GSYM for XCOFF). The type information for
+the stab (@pxref{String Field}) gives the type of the variable.
+
+For example, the following source code:
+
+@example
+char g_foo = 'c';
+@end example
+
+@noindent
+yields the following assembly code:
+
+@example
+.stabs "g_foo:G2",32,0,0,0 # @r{32 is N_GSYM}
+ .global _g_foo
+ .data
+_g_foo:
+ .byte 99
+@end example
+
+The address of the variable represented by the @code{N_GSYM} is not
+contained in the @code{N_GSYM} stab. The debugger gets this information
+from the external symbol for the global variable. In the example above,
+the @code{.global _g_foo} and @code{_g_foo:} lines tell the assembler to
+produce an external symbol.
+
+Some compilers, like GCC, output @code{N_GSYM} stabs only once, where
+the variable is defined. Other compilers, like SunOS4 /bin/cc, output a
+@code{N_GSYM} stab for each compilation unit which references the
+variable.
+
+@node Register Variables
+@section Register Variables
+
+@findex N_RSYM
+@findex C_RSYM
+@c According to an old version of this manual, AIX uses C_RPSYM instead
+@c of C_RSYM. I am skeptical; this should be verified.
+Register variables have their own stab type, @code{N_RSYM}
+(@code{C_RSYM} for XCOFF), and their own symbol descriptor, @samp{r}.
+The stab's value is the number of the register where the variable data
+will be stored.
+@c .stabs "name:type",N_RSYM,0,RegSize,RegNumber (Sun doc)
+
+AIX defines a separate symbol descriptor @samp{d} for floating point
+registers. This seems unnecessary; why not just just give floating
+point registers different register numbers? I have not verified whether
+the compiler actually uses @samp{d}.
+
+If the register is explicitly allocated to a global variable, but not
+initialized, as in:
+
+@example
+register int g_bar asm ("%g5");
+@end example
+
+@noindent
+then the stab may be emitted at the end of the object file, with
+the other bss symbols.
+
+@node Common Blocks
+@section Common Blocks
+
+A common block is a statically allocated section of memory which can be
+referred to by several source files. It may contain several variables.
+I believe Fortran is the only language with this feature.
+
+@findex N_BCOMM
+@findex N_ECOMM
+@findex C_BCOMM
+@findex C_ECOMM
+A @code{N_BCOMM} stab begins a common block and an @code{N_ECOMM} stab
+ends it. The only field that is significant in these two stabs is the
+string, which names a normal (non-debugging) symbol that gives the
+address of the common block. According to IBM documentation, only the
+@code{N_BCOMM} has the name of the common block (even though their
+compiler actually puts it both places).
+
+@findex N_ECOML
+@findex C_ECOML
+The stabs for the members of the common block are between the
+@code{N_BCOMM} and the @code{N_ECOMM}; the value of each stab is the
+offset within the common block of that variable. IBM uses the
+@code{C_ECOML} stab type, and there is a corresponding @code{N_ECOML}
+stab type, but Sun's Fortran compiler uses @code{N_GSYM} instead. The
+variables within a common block use the @samp{V} symbol descriptor (I
+believe this is true of all Fortran variables). Other stabs (at least
+type declarations using @code{C_DECL}) can also be between the
+@code{N_BCOMM} and the @code{N_ECOMM}.
+
+@node Statics
+@section Static Variables
+
+Initialized static variables are represented by the @samp{S} and
+@samp{V} symbol descriptors. @samp{S} means file scope static, and
+@samp{V} means procedure scope static. One exception: in XCOFF, IBM's
+xlc compiler always uses @samp{V}, and whether it is file scope or not
+is distinguished by whether the stab is located within a function.
+
+@c This is probably not worth mentioning; it is only true on the sparc
+@c for `double' variables which although declared const are actually in
+@c the data segment (the text segment can't guarantee 8 byte alignment).
+@c (although GCC
+@c 2.4.5 has a bug in that it uses @code{N_FUN}, so neither dbx nor GDB can
+@c find the variables)
+@findex N_STSYM
+@findex N_LCSYM
+@findex N_FUN, for variables
+@findex N_ROSYM
+In a.out files, @code{N_STSYM} means the data section, @code{N_FUN}
+means the text section, and @code{N_LCSYM} means the bss section. For
+those systems with a read-only data section separate from the text
+section (Solaris), @code{N_ROSYM} means the read-only data section.
+
+For example, the source lines:
+
+@example
+static const int var_const = 5;
+static int var_init = 2;
+static int var_noinit;
+@end example
+
+@noindent
+yield the following stabs:
+
+@example
+.stabs "var_const:S1",36,0,0,_var_const # @r{36 is N_FUN}
+@dots{}
+.stabs "var_init:S1",38,0,0,_var_init # @r{38 is N_STSYM}
+@dots{}
+.stabs "var_noinit:S1",40,0,0,_var_noinit # @r{40 is N_LCSYM}
+@end example
+
+@findex C_STSYM
+@findex C_BSTAT
+@findex C_ESTAT
+In XCOFF files, the stab type need not indicate the section;
+@code{C_STSYM} can be used for all statics. Also, each static variable
+is enclosed in a static block. A @code{C_BSTAT} (emitted with a
+@samp{.bs} assembler directive) symbol begins the static block; its
+value is the symbol number of the csect symbol whose value is the
+address of the static block, its section is the section of the variables
+in that static block, and its name is @samp{.bs}. A @code{C_ESTAT}
+(emitted with a @samp{.es} assembler directive) symbol ends the static
+block; its name is @samp{.es} and its value and section are ignored.
+
+In ECOFF files, the storage class is used to specify the section, so the
+stab type need not indicate the section.
+
+In ELF files, for the SunPRO compiler version 2.0.1, symbol descriptor
+@samp{S} means that the address is absolute (the linker relocates it)
+and symbol descriptor @samp{V} means that the address is relative to the
+start of the relevant section for that compilation unit. SunPRO has
+plans to have the linker stop relocating stabs; I suspect that their the
+debugger gets the address from the corresponding ELF (not stab) symbol.
+I'm not sure how to find which symbol of that name is the right one.
+The clean way to do all this would be to have a the value of a symbol
+descriptor @samp{S} symbol be an offset relative to the start of the
+file, just like everything else, but that introduces obvious
+compatibility problems. For more information on linker stab relocation,
+@xref{ELF Linker Relocation}.
+
+@node Based Variables
+@section Fortran Based Variables
+
+Fortran (at least, the Sun and SGI dialects of FORTRAN-77) has a feature
+which allows allocating arrays with @code{malloc}, but which avoids
+blurring the line between arrays and pointers the way that C does. In
+stabs such a variable uses the @samp{b} symbol descriptor.
+
+For example, the Fortran declarations
+
+@example
+real foo, foo10(10), foo10_5(10,5)
+pointer (foop, foo)
+pointer (foo10p, foo10)
+pointer (foo105p, foo10_5)
+@end example
+
+produce the stabs
+
+@example
+foo:b6
+foo10:bar3;1;10;6
+foo10_5:bar3;1;5;ar3;1;10;6
+@end example
+
+In this example, @code{real} is type 6 and type 3 is an integral type
+which is the type of the subscripts of the array (probably
+@code{integer}).
+
+The @samp{b} symbol descriptor is like @samp{V} in that it denotes a
+statically allocated symbol whose scope is local to a function; see
+@xref{Statics}. The value of the symbol, instead of being the address
+of the variable itself, is the address of a pointer to that variable.
+So in the above example, the value of the @code{foo} stab is the address
+of a pointer to a real, the value of the @code{foo10} stab is the
+address of a pointer to a 10-element array of reals, and the value of
+the @code{foo10_5} stab is the address of a pointer to a 5-element array
+of 10-element arrays of reals.
+
+@node Parameters
+@section Parameters
+
+Formal parameters to a function are represented by a stab (or sometimes
+two; see below) for each parameter. The stabs are in the order in which
+the debugger should print the parameters (i.e., the order in which the
+parameters are declared in the source file). The exact form of the stab
+depends on how the parameter is being passed.
+
+@findex N_PSYM
+@findex C_PSYM
+Parameters passed on the stack use the symbol descriptor @samp{p} and
+the @code{N_PSYM} symbol type (or @code{C_PSYM} for XCOFF). The value
+of the symbol is an offset used to locate the parameter on the stack;
+its exact meaning is machine-dependent, but on most machines it is an
+offset from the frame pointer.
+
+As a simple example, the code:
+
+@example
+main (argc, argv)
+ int argc;
+ char **argv;
+@end example
+
+produces the stabs:
+
+@example
+.stabs "main:F1",36,0,0,_main # @r{36 is N_FUN}
+.stabs "argc:p1",160,0,0,68 # @r{160 is N_PSYM}
+.stabs "argv:p20=*21=*2",160,0,0,72
+@end example
+
+The type definition of @code{argv} is interesting because it contains
+several type definitions. Type 21 is pointer to type 2 (char) and
+@code{argv} (type 20) is pointer to type 21.
+
+@c FIXME: figure out what these mean and describe them coherently.
+The following symbol descriptors are also said to go with @code{N_PSYM}.
+The value of the symbol is said to be an offset from the argument
+pointer (I'm not sure whether this is true or not).
+
+@example
+pP (<<??>>)
+pF Fortran function parameter
+X (function result variable)
+@end example
+
+@menu
+* Register Parameters::
+* Local Variable Parameters::
+* Reference Parameters::
+* Conformant Arrays::
+@end menu
+
+@node Register Parameters
+@subsection Passing Parameters in Registers
+
+If the parameter is passed in a register, then traditionally there are
+two symbols for each argument:
+
+@example
+.stabs "arg:p1" . . . ; N_PSYM
+.stabs "arg:r1" . . . ; N_RSYM
+@end example
+
+Debuggers use the second one to find the value, and the first one to
+know that it is an argument.
+
+@findex C_RPSYM
+@findex N_RSYM, for parameters
+Because that approach is kind of ugly, some compilers use symbol
+descriptor @samp{P} or @samp{R} to indicate an argument which is in a
+register. Symbol type @code{C_RPSYM} is used in XCOFF and @code{N_RSYM}
+is used otherwise. The symbol's value is the register number. @samp{P}
+and @samp{R} mean the same thing; the difference is that @samp{P} is a
+GNU invention and @samp{R} is an IBM (XCOFF) invention. As of version
+4.9, GDB should handle either one.
+
+There is at least one case where GCC uses a @samp{p} and @samp{r} pair
+rather than @samp{P}; this is where the argument is passed in the
+argument list and then loaded into a register.
+
+According to the AIX documentation, symbol descriptor @samp{D} is for a
+parameter passed in a floating point register. This seems
+unnecessary---why not just use @samp{R} with a register number which
+indicates that it's a floating point register? I haven't verified
+whether the system actually does what the documentation indicates.
+
+@c FIXME: On the hppa this is for any type > 8 bytes, I think, and not
+@c for small structures (investigate).
+On the sparc and hppa, for a @samp{P} symbol whose type is a structure
+or union, the register contains the address of the structure. On the
+sparc, this is also true of a @samp{p} and @samp{r} pair (using Sun
+@code{cc}) or a @samp{p} symbol. However, if a (small) structure is
+really in a register, @samp{r} is used. And, to top it all off, on the
+hppa it might be a structure which was passed on the stack and loaded
+into a register and for which there is a @samp{p} and @samp{r} pair! I
+believe that symbol descriptor @samp{i} is supposed to deal with this
+case (it is said to mean "value parameter by reference, indirect
+access"; I don't know the source for this information), but I don't know
+details or what compilers or debuggers use it, if any (not GDB or GCC).
+It is not clear to me whether this case needs to be dealt with
+differently than parameters passed by reference (@pxref{Reference Parameters}).
+
+@node Local Variable Parameters
+@subsection Storing Parameters as Local Variables
+
+There is a case similar to an argument in a register, which is an
+argument that is actually stored as a local variable. Sometimes this
+happens when the argument was passed in a register and then the compiler
+stores it as a local variable. If possible, the compiler should claim
+that it's in a register, but this isn't always done.
+
+If a parameter is passed as one type and converted to a smaller type by
+the prologue (for example, the parameter is declared as a @code{float},
+but the calling conventions specify that it is passed as a
+@code{double}), then GCC2 (sometimes) uses a pair of symbols. The first
+symbol uses symbol descriptor @samp{p} and the type which is passed.
+The second symbol has the type and location which the parameter actually
+has after the prologue. For example, suppose the following C code
+appears with no prototypes involved:
+
+@example
+void
+subr (f)
+ float f;
+@{
+@end example
+
+if @code{f} is passed as a double at stack offset 8, and the prologue
+converts it to a float in register number 0, then the stabs look like:
+
+@example
+.stabs "f:p13",160,0,3,8 # @r{160 is @code{N_PSYM}, here 13 is @code{double}}
+.stabs "f:r12",64,0,3,0 # @r{64 is @code{N_RSYM}, here 12 is @code{float}}
+@end example
+
+In both stabs 3 is the line number where @code{f} is declared
+(@pxref{Line Numbers}).
+
+@findex N_LSYM, for parameter
+GCC, at least on the 960, has another solution to the same problem. It
+uses a single @samp{p} symbol descriptor for an argument which is stored
+as a local variable but uses @code{N_LSYM} instead of @code{N_PSYM}. In
+this case, the value of the symbol is an offset relative to the local
+variables for that function, not relative to the arguments; on some
+machines those are the same thing, but not on all.
+
+@c This is mostly just background info; the part that logically belongs
+@c here is the last sentence.
+On the VAX or on other machines in which the calling convention includes
+the number of words of arguments actually passed, the debugger (GDB at
+least) uses the parameter symbols to keep track of whether it needs to
+print nameless arguments in addition to the formal parameters which it
+has printed because each one has a stab. For example, in
+
+@example
+extern int fprintf (FILE *stream, char *format, @dots{});
+@dots{}
+fprintf (stdout, "%d\n", x);
+@end example
+
+there are stabs for @code{stream} and @code{format}. On most machines,
+the debugger can only print those two arguments (because it has no way
+of knowing that additional arguments were passed), but on the VAX or
+other machines with a calling convention which indicates the number of
+words of arguments, the debugger can print all three arguments. To do
+so, the parameter symbol (symbol descriptor @samp{p}) (not necessarily
+@samp{r} or symbol descriptor omitted symbols) needs to contain the
+actual type as passed (for example, @code{double} not @code{float} if it
+is passed as a double and converted to a float).
+
+@node Reference Parameters
+@subsection Passing Parameters by Reference
+
+If the parameter is passed by reference (e.g., Pascal @code{VAR}
+parameters), then the symbol descriptor is @samp{v} if it is in the
+argument list, or @samp{a} if it in a register. Other than the fact
+that these contain the address of the parameter rather than the
+parameter itself, they are identical to @samp{p} and @samp{R},
+respectively. I believe @samp{a} is an AIX invention; @samp{v} is
+supported by all stabs-using systems as far as I know.
+
+@node Conformant Arrays
+@subsection Passing Conformant Array Parameters
+
+@c Is this paragraph correct? It is based on piecing together patchy
+@c information and some guesswork
+Conformant arrays are a feature of Modula-2, and perhaps other
+languages, in which the size of an array parameter is not known to the
+called function until run-time. Such parameters have two stabs: a
+@samp{x} for the array itself, and a @samp{C}, which represents the size
+of the array. The value of the @samp{x} stab is the offset in the
+argument list where the address of the array is stored (it this right?
+it is a guess); the value of the @samp{C} stab is the offset in the
+argument list where the size of the array (in elements? in bytes?) is
+stored.
+
+@node Types
+@chapter Defining Types
+
+The examples so far have described types as references to previously
+defined types, or defined in terms of subranges of or pointers to
+previously defined types. This chapter describes the other type
+descriptors that may follow the @samp{=} in a type definition.
+
+@menu
+* Builtin Types:: Integers, floating point, void, etc.
+* Miscellaneous Types:: Pointers, sets, files, etc.
+* Cross-References:: Referring to a type not yet defined.
+* Subranges:: A type with a specific range.
+* Arrays:: An aggregate type of same-typed elements.
+* Strings:: Like an array but also has a length.
+* Enumerations:: Like an integer but the values have names.
+* Structures:: An aggregate type of different-typed elements.
+* Typedefs:: Giving a type a name.
+* Unions:: Different types sharing storage.
+* Function Types::
+@end menu
+
+@node Builtin Types
+@section Builtin Types
+
+Certain types are built in (@code{int}, @code{short}, @code{void},
+@code{float}, etc.); the debugger recognizes these types and knows how
+to handle them. Thus, don't be surprised if some of the following ways
+of specifying builtin types do not specify everything that a debugger
+would need to know about the type---in some cases they merely specify
+enough information to distinguish the type from other types.
+
+The traditional way to define builtin types is convoluted, so new ways
+have been invented to describe them. Sun's @code{acc} uses special
+builtin type descriptors (@samp{b} and @samp{R}), and IBM uses negative
+type numbers. GDB accepts all three ways, as of version 4.8; dbx just
+accepts the traditional builtin types and perhaps one of the other two
+formats. The following sections describe each of these formats.
+
+@menu
+* Traditional Builtin Types:: Put on your seat belts and prepare for kludgery
+* Builtin Type Descriptors:: Builtin types with special type descriptors
+* Negative Type Numbers:: Builtin types using negative type numbers
+@end menu
+
+@node Traditional Builtin Types
+@subsection Traditional Builtin Types
+
+This is the traditional, convoluted method for defining builtin types.
+There are several classes of such type definitions: integer, floating
+point, and @code{void}.
+
+@menu
+* Traditional Integer Types::
+* Traditional Other Types::
+@end menu
+
+@node Traditional Integer Types
+@subsubsection Traditional Integer Types
+
+Often types are defined as subranges of themselves. If the bounding values
+fit within an @code{int}, then they are given normally. For example:
+
+@example
+.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0 # @r{128 is N_LSYM}
+.stabs "char:t2=r2;0;127;",128,0,0,0
+@end example
+
+Builtin types can also be described as subranges of @code{int}:
+
+@example
+.stabs "unsigned short:t6=r1;0;65535;",128,0,0,0
+@end example
+
+If the lower bound of a subrange is 0 and the upper bound is -1,
+the type is an unsigned integral type whose bounds are too
+big to describe in an @code{int}. Traditionally this is only used for
+@code{unsigned int} and @code{unsigned long}:
+
+@example
+.stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
+@end example
+
+For larger types, GCC 2.4.5 puts out bounds in octal, with one or more
+leading zeroes. In this case a negative bound consists of a number
+which is a 1 bit (for the sign bit) followed by a 0 bit for each bit in
+the number (except the sign bit), and a positive bound is one which is a
+1 bit for each bit in the number (except possibly the sign bit). All
+known versions of dbx and GDB version 4 accept this (at least in the
+sense of not refusing to process the file), but GDB 3.5 refuses to read
+the whole file containing such symbols. So GCC 2.3.3 did not output the
+proper size for these types. As an example of octal bounds, the string
+fields of the stabs for 64 bit integer types look like:
+
+@c .stabs directives, etc., omitted to make it fit on the page.
+@example
+long int:t3=r1;001000000000000000000000;000777777777777777777777;
+long unsigned int:t5=r1;000000000000000000000000;001777777777777777777777;
+@end example
+
+If the lower bound of a subrange is 0 and the upper bound is negative,
+the type is an unsigned integral type whose size in bytes is the
+absolute value of the upper bound. I believe this is a Convex
+convention for @code{unsigned long long}.
+
+If the lower bound of a subrange is negative and the upper bound is 0,
+the type is a signed integral type whose size in bytes is
+the absolute value of the lower bound. I believe this is a Convex
+convention for @code{long long}. To distinguish this from a legitimate
+subrange, the type should be a subrange of itself. I'm not sure whether
+this is the case for Convex.
+
+@node Traditional Other Types
+@subsubsection Traditional Other Types
+
+If the upper bound of a subrange is 0 and the lower bound is positive,
+the type is a floating point type, and the lower bound of the subrange
+indicates the number of bytes in the type:
+
+@example
+.stabs "float:t12=r1;4;0;",128,0,0,0
+.stabs "double:t13=r1;8;0;",128,0,0,0
+@end example
+
+However, GCC writes @code{long double} the same way it writes
+@code{double}, so there is no way to distinguish.
+
+@example
+.stabs "long double:t14=r1;8;0;",128,0,0,0
+@end example
+
+Complex types are defined the same way as floating-point types; there is
+no way to distinguish a single-precision complex from a double-precision
+floating-point type.
+
+The C @code{void} type is defined as itself:
+
+@example
+.stabs "void:t15=15",128,0,0,0
+@end example
+
+I'm not sure how a boolean type is represented.
+
+@node Builtin Type Descriptors
+@subsection Defining Builtin Types Using Builtin Type Descriptors
+
+This is the method used by Sun's @code{acc} for defining builtin types.
+These are the type descriptors to define builtin types:
+
+@table @code
+@c FIXME: clean up description of width and offset, once we figure out
+@c what they mean
+@item b @var{signed} @var{char-flag} @var{width} ; @var{offset} ; @var{nbits} ;
+Define an integral type. @var{signed} is @samp{u} for unsigned or
+@samp{s} for signed. @var{char-flag} is @samp{c} which indicates this
+is a character type, or is omitted. I assume this is to distinguish an
+integral type from a character type of the same size, for example it
+might make sense to set it for the C type @code{wchar_t} so the debugger
+can print such variables differently (Solaris does not do this). Sun
+sets it on the C types @code{signed char} and @code{unsigned char} which
+arguably is wrong. @var{width} and @var{offset} appear to be for small
+objects stored in larger ones, for example a @code{short} in an
+@code{int} register. @var{width} is normally the number of bytes in the
+type. @var{offset} seems to always be zero. @var{nbits} is the number
+of bits in the type.
+
+Note that type descriptor @samp{b} used for builtin types conflicts with
+its use for Pascal space types (@pxref{Miscellaneous Types}); they can
+be distinguished because the character following the type descriptor
+will be a digit, @samp{(}, or @samp{-} for a Pascal space type, or
+@samp{u} or @samp{s} for a builtin type.
+
+@item w
+Documented by AIX to define a wide character type, but their compiler
+actually uses negative type numbers (@pxref{Negative Type Numbers}).
+
+@item R @var{fp-type} ; @var{bytes} ;
+Define a floating point type. @var{fp-type} has one of the following values:
+
+@table @code
+@item 1 (NF_SINGLE)
+IEEE 32-bit (single precision) floating point format.
+
+@item 2 (NF_DOUBLE)
+IEEE 64-bit (double precision) floating point format.
+
+@item 3 (NF_COMPLEX)
+@item 4 (NF_COMPLEX16)
+@item 5 (NF_COMPLEX32)
+@c "GDB source" really means @file{include/aout/stab_gnu.h}, but trying
+@c to put that here got an overfull hbox.
+These are for complex numbers. A comment in the GDB source describes
+them as Fortran @code{complex}, @code{double complex}, and
+@code{complex*16}, respectively, but what does that mean? (i.e., Single
+precision? Double precision?).
+
+@item 6 (NF_LDOUBLE)
+Long double. This should probably only be used for Sun format
+@code{long double}, and new codes should be used for other floating
+point formats (@code{NF_DOUBLE} can be used if a @code{long double} is
+really just an IEEE double, of course).
+@end table
+
+@var{bytes} is the number of bytes occupied by the type. This allows a
+debugger to perform some operations with the type even if it doesn't
+understand @var{fp-type}.
+
+@item g @var{type-information} ; @var{nbits}
+Documented by AIX to define a floating type, but their compiler actually
+uses negative type numbers (@pxref{Negative Type Numbers}).
+
+@item c @var{type-information} ; @var{nbits}
+Documented by AIX to define a complex type, but their compiler actually
+uses negative type numbers (@pxref{Negative Type Numbers}).
+@end table
+
+The C @code{void} type is defined as a signed integral type 0 bits long:
+@example
+.stabs "void:t19=bs0;0;0",128,0,0,0
+@end example
+The Solaris compiler seems to omit the trailing semicolon in this case.
+Getting sloppy in this way is not a swift move because if a type is
+embedded in a more complex expression it is necessary to be able to tell
+where it ends.
+
+I'm not sure how a boolean type is represented.
+
+@node Negative Type Numbers
+@subsection Negative Type Numbers
+
+This is the method used in XCOFF for defining builtin types.
+Since the debugger knows about the builtin types anyway, the idea of
+negative type numbers is simply to give a special type number which
+indicates the builtin type. There is no stab defining these types.
+
+There are several subtle issues with negative type numbers.
+
+One is the size of the type. A builtin type (for example the C types
+@code{int} or @code{long}) might have different sizes depending on
+compiler options, the target architecture, the ABI, etc. This issue
+doesn't come up for IBM tools since (so far) they just target the
+RS/6000; the sizes indicated below for each size are what the IBM
+RS/6000 tools use. To deal with differing sizes, either define separate
+negative type numbers for each size (which works but requires changing
+the debugger, and, unless you get both AIX dbx and GDB to accept the
+change, introduces an incompatibility), or use a type attribute
+(@pxref{String Field}) to define a new type with the appropriate size
+(which merely requires a debugger which understands type attributes,
+like AIX dbx or GDB). For example,
+
+@example
+.stabs "boolean:t10=@@s8;-16",128,0,0,0
+@end example
+
+defines an 8-bit boolean type, and
+
+@example
+.stabs "boolean:t10=@@s64;-16",128,0,0,0
+@end example
+
+defines a 64-bit boolean type.
+
+A similar issue is the format of the type. This comes up most often for
+floating-point types, which could have various formats (particularly
+extended doubles, which vary quite a bit even among IEEE systems).
+Again, it is best to define a new negative type number for each
+different format; changing the format based on the target system has
+various problems. One such problem is that the Alpha has both VAX and
+IEEE floating types. One can easily imagine one library using the VAX
+types and another library in the same executable using the IEEE types.
+Another example is that the interpretation of whether a boolean is true
+or false can be based on the least significant bit, most significant
+bit, whether it is zero, etc., and different compilers (or different
+options to the same compiler) might provide different kinds of boolean.
+
+The last major issue is the names of the types. The name of a given
+type depends @emph{only} on the negative type number given; these do not
+vary depending on the language, the target system, or anything else.
+One can always define separate type numbers---in the following list you
+will see for example separate @code{int} and @code{integer*4} types
+which are identical except for the name. But compatibility can be
+maintained by not inventing new negative type numbers and instead just
+defining a new type with a new name. For example:
+
+@example
+.stabs "CARDINAL:t10=-8",128,0,0,0
+@end example
+
+Here is the list of negative type numbers. The phrase @dfn{integral
+type} is used to mean twos-complement (I strongly suspect that all
+machines which use stabs use twos-complement; most machines use
+twos-complement these days).
+
+@table @code
+@item -1
+@code{int}, 32 bit signed integral type.
+
+@item -2
+@code{char}, 8 bit type holding a character. Both GDB and dbx on AIX
+treat this as signed. GCC uses this type whether @code{char} is signed
+or not, which seems like a bad idea. The AIX compiler (@code{xlc}) seems to
+avoid this type; it uses -5 instead for @code{char}.
+
+@item -3
+@code{short}, 16 bit signed integral type.
+
+@item -4
+@code{long}, 32 bit signed integral type.
+
+@item -5
+@code{unsigned char}, 8 bit unsigned integral type.
+
+@item -6
+@code{signed char}, 8 bit signed integral type.
+
+@item -7
+@code{unsigned short}, 16 bit unsigned integral type.
+
+@item -8
+@code{unsigned int}, 32 bit unsigned integral type.
+
+@item -9
+@code{unsigned}, 32 bit unsigned integral type.
+
+@item -10
+@code{unsigned long}, 32 bit unsigned integral type.
+
+@item -11
+@code{void}, type indicating the lack of a value.
+
+@item -12
+@code{float}, IEEE single precision.
+
+@item -13
+@code{double}, IEEE double precision.
+
+@item -14
+@code{long double}, IEEE double precision. The compiler claims the size
+will increase in a future release, and for binary compatibility you have
+to avoid using @code{long double}. I hope when they increase it they
+use a new negative type number.
+
+@item -15
+@code{integer}. 32 bit signed integral type.
+
+@item -16
+@code{boolean}. 32 bit type. GDB and GCC assume that zero is false,
+one is true, and other values have unspecified meaning. I hope this
+agrees with how the IBM tools use the type.
+
+@item -17
+@code{short real}. IEEE single precision.
+
+@item -18
+@code{real}. IEEE double precision.
+
+@item -19
+@code{stringptr}. @xref{Strings}.
+
+@item -20
+@code{character}, 8 bit unsigned character type.
+
+@item -21
+@code{logical*1}, 8 bit type. This Fortran type has a split
+personality in that it is used for boolean variables, but can also be
+used for unsigned integers. 0 is false, 1 is true, and other values are
+non-boolean.
+
+@item -22
+@code{logical*2}, 16 bit type. This Fortran type has a split
+personality in that it is used for boolean variables, but can also be
+used for unsigned integers. 0 is false, 1 is true, and other values are
+non-boolean.
+
+@item -23
+@code{logical*4}, 32 bit type. This Fortran type has a split
+personality in that it is used for boolean variables, but can also be
+used for unsigned integers. 0 is false, 1 is true, and other values are
+non-boolean.
+
+@item -24
+@code{logical}, 32 bit type. This Fortran type has a split
+personality in that it is used for boolean variables, but can also be
+used for unsigned integers. 0 is false, 1 is true, and other values are
+non-boolean.
+
+@item -25
+@code{complex}. A complex type consisting of two IEEE single-precision
+floating point values.
+
+@item -26
+@code{complex}. A complex type consisting of two IEEE double-precision
+floating point values.
+
+@item -27
+@code{integer*1}, 8 bit signed integral type.
+
+@item -28
+@code{integer*2}, 16 bit signed integral type.
+
+@item -29
+@code{integer*4}, 32 bit signed integral type.
+
+@item -30
+@code{wchar}. Wide character, 16 bits wide, unsigned (what format?
+Unicode?).
+
+@item -31
+@code{long long}, 64 bit signed integral type.
+
+@item -32
+@code{unsigned long long}, 64 bit unsigned integral type.
+
+@item -33
+@code{logical*8}, 64 bit unsigned integral type.
+
+@item -34
+@code{integer*8}, 64 bit signed integral type.
+@end table
+
+@node Miscellaneous Types
+@section Miscellaneous Types
+
+@table @code
+@item b @var{type-information} ; @var{bytes}
+Pascal space type. This is documented by IBM; what does it mean?
+
+This use of the @samp{b} type descriptor can be distinguished
+from its use for builtin integral types (@pxref{Builtin Type
+Descriptors}) because the character following the type descriptor is
+always a digit, @samp{(}, or @samp{-}.
+
+@item B @var{type-information}
+A volatile-qualified version of @var{type-information}. This is
+a Sun extension. References and stores to a variable with a
+volatile-qualified type must not be optimized or cached; they
+must occur as the user specifies them.
+
+@item d @var{type-information}
+File of type @var{type-information}. As far as I know this is only used
+by Pascal.
+
+@item k @var{type-information}
+A const-qualified version of @var{type-information}. This is a Sun
+extension. A variable with a const-qualified type cannot be modified.
+
+@item M @var{type-information} ; @var{length}
+Multiple instance type. The type seems to composed of @var{length}
+repetitions of @var{type-information}, for example @code{character*3} is
+represented by @samp{M-2;3}, where @samp{-2} is a reference to a
+character type (@pxref{Negative Type Numbers}). I'm not sure how this
+differs from an array. This appears to be a Fortran feature.
+@var{length} is a bound, like those in range types; see @ref{Subranges}.
+
+@item S @var{type-information}
+Pascal set type. @var{type-information} must be a small type such as an
+enumeration or a subrange, and the type is a bitmask whose length is
+specified by the number of elements in @var{type-information}.
+
+In CHILL, if it is a bitstring instead of a set, also use the @samp{S}
+type attribute (@pxref{String Field}).
+
+@item * @var{type-information}
+Pointer to @var{type-information}.
+@end table
+
+@node Cross-References
+@section Cross-References to Other Types
+
+A type can be used before it is defined; one common way to deal with
+that situation is just to use a type reference to a type which has not
+yet been defined.
+
+Another way is with the @samp{x} type descriptor, which is followed by
+@samp{s} for a structure tag, @samp{u} for a union tag, or @samp{e} for
+a enumerator tag, followed by the name of the tag, followed by @samp{:}.
+If the name contains @samp{::} between a @samp{<} and @samp{>} pair (for
+C++ templates), such a @samp{::} does not end the name---only a single
+@samp{:} ends the name; see @ref{Nested Symbols}.
+
+For example, the following C declarations:
+
+@example
+struct foo;
+struct foo *bar;
+@end example
+
+@noindent
+produce:
+
+@example
+.stabs "bar:G16=*17=xsfoo:",32,0,0,0
+@end example
+
+Not all debuggers support the @samp{x} type descriptor, so on some
+machines GCC does not use it. I believe that for the above example it
+would just emit a reference to type 17 and never define it, but I
+haven't verified that.
+
+Modula-2 imported types, at least on AIX, use the @samp{i} type
+descriptor, which is followed by the name of the module from which the
+type is imported, followed by @samp{:}, followed by the name of the
+type. There is then optionally a comma followed by type information for
+the type. This differs from merely naming the type (@pxref{Typedefs}) in
+that it identifies the module; I don't understand whether the name of
+the type given here is always just the same as the name we are giving
+it, or whether this type descriptor is used with a nameless stab
+(@pxref{String Field}), or what. The symbol ends with @samp{;}.
+
+@node Subranges
+@section Subrange Types
+
+The @samp{r} type descriptor defines a type as a subrange of another
+type. It is followed by type information for the type of which it is a
+subrange, a semicolon, an integral lower bound, a semicolon, an
+integral upper bound, and a semicolon. The AIX documentation does not
+specify the trailing semicolon, in an effort to specify array indexes
+more cleanly, but a subrange which is not an array index has always
+included a trailing semicolon (@pxref{Arrays}).
+
+Instead of an integer, either bound can be one of the following:
+
+@table @code
+@item A @var{offset}
+The bound is passed by reference on the stack at offset @var{offset}
+from the argument list. @xref{Parameters}, for more information on such
+offsets.
+
+@item T @var{offset}
+The bound is passed by value on the stack at offset @var{offset} from
+the argument list.
+
+@item a @var{register-number}
+The bound is passed by reference in register number
+@var{register-number}.
+
+@item t @var{register-number}
+The bound is passed by value in register number @var{register-number}.
+
+@item J
+There is no bound.
+@end table
+
+Subranges are also used for builtin types; see @ref{Traditional Builtin Types}.
+
+@node Arrays
+@section Array Types
+
+Arrays use the @samp{a} type descriptor. Following the type descriptor
+is the type of the index and the type of the array elements. If the
+index type is a range type, it ends in a semicolon; otherwise
+(for example, if it is a type reference), there does not
+appear to be any way to tell where the types are separated. In an
+effort to clean up this mess, IBM documents the two types as being
+separated by a semicolon, and a range type as not ending in a semicolon
+(but this is not right for range types which are not array indexes,
+@pxref{Subranges}). I think probably the best solution is to specify
+that a semicolon ends a range type, and that the index type and element
+type of an array are separated by a semicolon, but that if the index
+type is a range type, the extra semicolon can be omitted. GDB (at least
+through version 4.9) doesn't support any kind of index type other than a
+range anyway; I'm not sure about dbx.
+
+It is well established, and widely used, that the type of the index,
+unlike most types found in the stabs, is merely a type definition, not
+type information (@pxref{String Field}) (that is, it need not start with
+@samp{@var{type-number}=} if it is defining a new type). According to a
+comment in GDB, this is also true of the type of the array elements; it
+gives @samp{ar1;1;10;ar1;1;10;4} as a legitimate way to express a two
+dimensional array. According to AIX documentation, the element type
+must be type information. GDB accepts either.
+
+The type of the index is often a range type, expressed as the type
+descriptor @samp{r} and some parameters. It defines the size of the
+array. In the example below, the range @samp{r1;0;2;} defines an index
+type which is a subrange of type 1 (integer), with a lower bound of 0
+and an upper bound of 2. This defines the valid range of subscripts of
+a three-element C array.
+
+For example, the definition:
+
+@example
+char char_vec[3] = @{'a','b','c'@};
+@end example
+
+@noindent
+produces the output:
+
+@example
+.stabs "char_vec:G19=ar1;0;2;2",32,0,0,0
+ .global _char_vec
+ .align 4
+_char_vec:
+ .byte 97
+ .byte 98
+ .byte 99
+@end example
+
+If an array is @dfn{packed}, the elements are spaced more
+closely than normal, saving memory at the expense of speed. For
+example, an array of 3-byte objects might, if unpacked, have each
+element aligned on a 4-byte boundary, but if packed, have no padding.
+One way to specify that something is packed is with type attributes
+(@pxref{String Field}). In the case of arrays, another is to use the
+@samp{P} type descriptor instead of @samp{a}. Other than specifying a
+packed array, @samp{P} is identical to @samp{a}.
+
+@c FIXME-what is it? A pointer?
+An open array is represented by the @samp{A} type descriptor followed by
+type information specifying the type of the array elements.
+
+@c FIXME: what is the format of this type? A pointer to a vector of pointers?
+An N-dimensional dynamic array is represented by
+
+@example
+D @var{dimensions} ; @var{type-information}
+@end example
+
+@c Does dimensions really have this meaning? The AIX documentation
+@c doesn't say.
+@var{dimensions} is the number of dimensions; @var{type-information}
+specifies the type of the array elements.
+
+@c FIXME: what is the format of this type? A pointer to some offsets in
+@c another array?
+A subarray of an N-dimensional array is represented by
+
+@example
+E @var{dimensions} ; @var{type-information}
+@end example
+
+@c Does dimensions really have this meaning? The AIX documentation
+@c doesn't say.
+@var{dimensions} is the number of dimensions; @var{type-information}
+specifies the type of the array elements.
+
+@node Strings
+@section Strings
+
+Some languages, like C or the original Pascal, do not have string types,
+they just have related things like arrays of characters. But most
+Pascals and various other languages have string types, which are
+indicated as follows:
+
+@table @code
+@item n @var{type-information} ; @var{bytes}
+@var{bytes} is the maximum length. I'm not sure what
+@var{type-information} is; I suspect that it means that this is a string
+of @var{type-information} (thus allowing a string of integers, a string
+of wide characters, etc., as well as a string of characters). Not sure
+what the format of this type is. This is an AIX feature.
+
+@item z @var{type-information} ; @var{bytes}
+Just like @samp{n} except that this is a gstring, not an ordinary
+string. I don't know the difference.
+
+@item N
+Pascal Stringptr. What is this? This is an AIX feature.
+@end table
+
+Languages, such as CHILL which have a string type which is basically
+just an array of characters use the @samp{S} type attribute
+(@pxref{String Field}).
+
+@node Enumerations
+@section Enumerations
+
+Enumerations are defined with the @samp{e} type descriptor.
+
+@c FIXME: Where does this information properly go? Perhaps it is
+@c redundant with something we already explain.
+The source line below declares an enumeration type at file scope.
+The type definition is located after the @code{N_RBRAC} that marks the end of
+the previous procedure's block scope, and before the @code{N_FUN} that marks
+the beginning of the next procedure's block scope. Therefore it does not
+describe a block local symbol, but a file local one.
+
+The source line:
+
+@example
+enum e_places @{first,second=3,last@};
+@end example
+
+@noindent
+generates the following stab:
+
+@example
+.stabs "e_places:T22=efirst:0,second:3,last:4,;",128,0,0,0
+@end example
+
+The symbol descriptor (@samp{T}) says that the stab describes a
+structure, enumeration, or union tag. The type descriptor @samp{e},
+following the @samp{22=} of the type definition narrows it down to an
+enumeration type. Following the @samp{e} is a list of the elements of
+the enumeration. The format is @samp{@var{name}:@var{value},}. The
+list of elements ends with @samp{;}. The fact that @var{value} is
+specified as an integer can cause problems if the value is large. GCC
+2.5.2 tries to output it in octal in that case with a leading zero,
+which is probably a good thing, although GDB 4.11 supports octal only in
+cases where decimal is perfectly good. Negative decimal values are
+supported by both GDB and dbx.
+
+There is no standard way to specify the size of an enumeration type; it
+is determined by the architecture (normally all enumerations types are
+32 bits). Type attributes can be used to specify an enumeration type of
+another size for debuggers which support them; see @ref{String Field}.
+
+Enumeration types are unusual in that they define symbols for the
+enumeration values (@code{first}, @code{second}, and @code{third} in the
+above example), and even though these symbols are visible in the file as
+a whole (rather than being in a more local namespace like structure
+member names), they are defined in the type definition for the
+enumeration type rather than each having their own symbol. In order to
+be fast, GDB will only get symbols from such types (in its initial scan
+of the stabs) if the type is the first thing defined after a @samp{T} or
+@samp{t} symbol descriptor (the above example fulfills this
+requirement). If the type does not have a name, the compiler should
+emit it in a nameless stab (@pxref{String Field}); GCC does this.
+
+@node Structures
+@section Structures
+
+The encoding of structures in stabs can be shown with an example.
+
+The following source code declares a structure tag and defines an
+instance of the structure in global scope. Then a @code{typedef} equates the
+structure tag with a new type. Separate stabs are generated for the
+structure tag, the structure @code{typedef}, and the structure instance. The
+stabs for the tag and the @code{typedef} are emitted when the definitions are
+encountered. Since the structure elements are not initialized, the
+stab and code for the structure variable itself is located at the end
+of the program in the bss section.
+
+@example
+struct s_tag @{
+ int s_int;
+ float s_float;
+ char s_char_vec[8];
+ struct s_tag* s_next;
+@} g_an_s;
+
+typedef struct s_tag s_typedef;
+@end example
+
+The structure tag has an @code{N_LSYM} stab type because, like the
+enumeration, the symbol has file scope. Like the enumeration, the
+symbol descriptor is @samp{T}, for enumeration, structure, or tag type.
+The type descriptor @samp{s} following the @samp{16=} of the type
+definition narrows the symbol type to structure.
+
+Following the @samp{s} type descriptor is the number of bytes the
+structure occupies, followed by a description of each structure element.
+The structure element descriptions are of the form @var{name:type, bit
+offset from the start of the struct, number of bits in the element}.
+
+@c FIXME: phony line break. Can probably be fixed by using an example
+@c with fewer fields.
+@example
+# @r{128 is N_LSYM}
+.stabs "s_tag:T16=s20s_int:1,0,32;s_float:12,32,32;
+ s_char_vec:17=ar1;0;7;2,64,64;s_next:18=*16,128,32;;",128,0,0,0
+@end example
+
+In this example, the first two structure elements are previously defined
+types. For these, the type following the @samp{@var{name}:} part of the
+element description is a simple type reference. The other two structure
+elements are new types. In this case there is a type definition
+embedded after the @samp{@var{name}:}. The type definition for the
+array element looks just like a type definition for a stand-alone array.
+The @code{s_next} field is a pointer to the same kind of structure that
+the field is an element of. So the definition of structure type 16
+contains a type definition for an element which is a pointer to type 16.
+
+If a field is a static member (this is a C++ feature in which a single
+variable appears to be a field of every structure of a given type) it
+still starts out with the field name, a colon, and the type, but then
+instead of a comma, bit position, comma, and bit size, there is a colon
+followed by the name of the variable which each such field refers to.
+
+If the structure has methods (a C++ feature), they follow the non-method
+fields; see @ref{Cplusplus}.
+
+@node Typedefs
+@section Giving a Type a Name
+
+@findex N_LSYM, for types
+@findex C_DECL, for types
+To give a type a name, use the @samp{t} symbol descriptor. The type
+is specified by the type information (@pxref{String Field}) for the stab.
+For example,
+
+@example
+.stabs "s_typedef:t16",128,0,0,0 # @r{128 is N_LSYM}
+@end example
+
+specifies that @code{s_typedef} refers to type number 16. Such stabs
+have symbol type @code{N_LSYM} (or @code{C_DECL} for XCOFF). (The Sun
+documentation mentions using @code{N_GSYM} in some cases).
+
+If you are specifying the tag name for a structure, union, or
+enumeration, use the @samp{T} symbol descriptor instead. I believe C is
+the only language with this feature.
+
+If the type is an opaque type (I believe this is a Modula-2 feature),
+AIX provides a type descriptor to specify it. The type descriptor is
+@samp{o} and is followed by a name. I don't know what the name
+means---is it always the same as the name of the type, or is this type
+descriptor used with a nameless stab (@pxref{String Field})? There
+optionally follows a comma followed by type information which defines
+the type of this type. If omitted, a semicolon is used in place of the
+comma and the type information, and the type is much like a generic
+pointer type---it has a known size but little else about it is
+specified.
+
+@node Unions
+@section Unions
+
+@example
+union u_tag @{
+ int u_int;
+ float u_float;
+ char* u_char;
+@} an_u;
+@end example
+
+This code generates a stab for a union tag and a stab for a union
+variable. Both use the @code{N_LSYM} stab type. If a union variable is
+scoped locally to the procedure in which it is defined, its stab is
+located immediately preceding the @code{N_LBRAC} for the procedure's block
+start.
+
+The stab for the union tag, however, is located preceding the code for
+the procedure in which it is defined. The stab type is @code{N_LSYM}. This
+would seem to imply that the union type is file scope, like the struct
+type @code{s_tag}. This is not true. The contents and position of the stab
+for @code{u_type} do not convey any information about its procedure local
+scope.
+
+@c FIXME: phony line break. Can probably be fixed by using an example
+@c with fewer fields.
+@smallexample
+# @r{128 is N_LSYM}
+.stabs "u_tag:T23=u4u_int:1,0,32;u_float:12,0,32;u_char:21,0,32;;",
+ 128,0,0,0
+@end smallexample
+
+The symbol descriptor @samp{T}, following the @samp{name:} means that
+the stab describes an enumeration, structure, or union tag. The type
+descriptor @samp{u}, following the @samp{23=} of the type definition,
+narrows it down to a union type definition. Following the @samp{u} is
+the number of bytes in the union. After that is a list of union element
+descriptions. Their format is @var{name:type, bit offset into the
+union, number of bytes for the element;}.
+
+The stab for the union variable is:
+
+@example
+.stabs "an_u:23",128,0,0,-20 # @r{128 is N_LSYM}
+@end example
+
+@samp{-20} specifies where the variable is stored (@pxref{Stack
+Variables}).
+
+@node Function Types
+@section Function Types
+
+Various types can be defined for function variables. These types are
+not used in defining functions (@pxref{Procedures}); they are used for
+things like pointers to functions.
+
+The simple, traditional, type is type descriptor @samp{f} is followed by
+type information for the return type of the function, followed by a
+semicolon.
+
+This does not deal with functions for which the number and types of the
+parameters are part of the type, as in Modula-2 or ANSI C. AIX provides
+extensions to specify these, using the @samp{f}, @samp{F}, @samp{p}, and
+@samp{R} type descriptors.
+
+First comes the type descriptor. If it is @samp{f} or @samp{F}, this
+type involves a function rather than a procedure, and the type
+information for the return type of the function follows, followed by a
+comma. Then comes the number of parameters to the function and a
+semicolon. Then, for each parameter, there is the name of the parameter
+followed by a colon (this is only present for type descriptors @samp{R}
+and @samp{F} which represent Pascal function or procedure parameters),
+type information for the parameter, a comma, 0 if passed by reference or
+1 if passed by value, and a semicolon. The type definition ends with a
+semicolon.
+
+For example, this variable definition:
+
+@example
+int (*g_pf)();
+@end example
+
+@noindent
+generates the following code:
+
+@example
+.stabs "g_pf:G24=*25=f1",32,0,0,0
+ .common _g_pf,4,"bss"
+@end example
+
+The variable defines a new type, 24, which is a pointer to another new
+type, 25, which is a function returning @code{int}.
+
+@node Symbol Tables
+@chapter Symbol Information in Symbol Tables
+
+This chapter describes the format of symbol table entries
+and how stab assembler directives map to them. It also describes the
+transformations that the assembler and linker make on data from stabs.
+
+@menu
+* Symbol Table Format::
+* Transformations On Symbol Tables::
+@end menu
+
+@node Symbol Table Format
+@section Symbol Table Format
+
+Each time the assembler encounters a stab directive, it puts
+each field of the stab into a corresponding field in a symbol table
+entry of its output file. If the stab contains a string field, the
+symbol table entry for that stab points to a string table entry
+containing the string data from the stab. Assembler labels become
+relocatable addresses. Symbol table entries in a.out have the format:
+
+@c FIXME: should refer to external, not internal.
+@example
+struct internal_nlist @{
+ unsigned long n_strx; /* index into string table of name */
+ unsigned char n_type; /* type of symbol */
+ unsigned char n_other; /* misc info (usually empty) */
+ unsigned short n_desc; /* description field */
+ bfd_vma n_value; /* value of symbol */
+@};
+@end example
+
+If the stab has a string, the @code{n_strx} field holds the offset in
+bytes of the string within the string table. The string is terminated
+by a NUL character. If the stab lacks a string (for example, it was
+produced by a @code{.stabn} or @code{.stabd} directive), the
+@code{n_strx} field is zero.
+
+Symbol table entries with @code{n_type} field values greater than 0x1f
+originated as stabs generated by the compiler (with one random
+exception). The other entries were placed in the symbol table of the
+executable by the assembler or the linker.
+
+@node Transformations On Symbol Tables
+@section Transformations on Symbol Tables
+
+The linker concatenates object files and does fixups of externally
+defined symbols.
+
+You can see the transformations made on stab data by the assembler and
+linker by examining the symbol table after each pass of the build. To
+do this, use @samp{nm -ap}, which dumps the symbol table, including
+debugging information, unsorted. For stab entries the columns are:
+@var{value}, @var{other}, @var{desc}, @var{type}, @var{string}. For
+assembler and linker symbols, the columns are: @var{value}, @var{type},
+@var{string}.
+
+The low 5 bits of the stab type tell the linker how to relocate the
+value of the stab. Thus for stab types like @code{N_RSYM} and
+@code{N_LSYM}, where the value is an offset or a register number, the
+low 5 bits are @code{N_ABS}, which tells the linker not to relocate the
+value.
+
+Where the value of a stab contains an assembly language label,
+it is transformed by each build step. The assembler turns it into a
+relocatable address and the linker turns it into an absolute address.
+
+@menu
+* Transformations On Static Variables::
+* Transformations On Global Variables::
+* Stab Section Transformations:: For some object file formats,
+ things are a bit different.
+@end menu
+
+@node Transformations On Static Variables
+@subsection Transformations on Static Variables
+
+This source line defines a static variable at file scope:
+
+@example
+static int s_g_repeat
+@end example
+
+@noindent
+The following stab describes the symbol:
+
+@example
+.stabs "s_g_repeat:S1",38,0,0,_s_g_repeat
+@end example
+
+@noindent
+The assembler transforms the stab into this symbol table entry in the
+@file{.o} file. The location is expressed as a data segment offset.
+
+@example
+00000084 - 00 0000 STSYM s_g_repeat:S1
+@end example
+
+@noindent
+In the symbol table entry from the executable, the linker has made the
+relocatable address absolute.
+
+@example
+0000e00c - 00 0000 STSYM s_g_repeat:S1
+@end example
+
+@node Transformations On Global Variables
+@subsection Transformations on Global Variables
+
+Stabs for global variables do not contain location information. In
+this case, the debugger finds location information in the assembler or
+linker symbol table entry describing the variable. The source line:
+
+@example
+char g_foo = 'c';
+@end example
+
+@noindent
+generates the stab:
+
+@example
+.stabs "g_foo:G2",32,0,0,0
+@end example
+
+The variable is represented by two symbol table entries in the object
+file (see below). The first one originated as a stab. The second one
+is an external symbol. The upper case @samp{D} signifies that the
+@code{n_type} field of the symbol table contains 7, @code{N_DATA} with
+local linkage. The stab's value is zero since the value is not used for
+@code{N_GSYM} stabs. The value of the linker symbol is the relocatable
+address corresponding to the variable.
+
+@example
+00000000 - 00 0000 GSYM g_foo:G2
+00000080 D _g_foo
+@end example
+
+@noindent
+These entries as transformed by the linker. The linker symbol table
+entry now holds an absolute address:
+
+@example
+00000000 - 00 0000 GSYM g_foo:G2
+@dots{}
+0000e008 D _g_foo
+@end example
+
+@node Stab Section Transformations
+@subsection Transformations of Stabs in separate sections
+
+For object file formats using stabs in separate sections (@pxref{Stab
+Sections}), use @code{objdump --stabs} instead of @code{nm} to show the
+stabs in an object or executable file. @code{objdump} is a GNU utility;
+Sun does not provide any equivalent.
+
+The following example is for a stab whose value is an address is
+relative to the compilation unit (@pxref{ELF Linker Relocation}). For
+example, if the source line
+
+@example
+static int ld = 5;
+@end example
+
+appears within a function, then the assembly language output from the
+compiler contains:
+
+@example
+.Ddata.data:
+@dots{}
+ .stabs "ld:V(0,3)",0x26,0,4,.L18-Ddata.data # @r{0x26 is N_STSYM}
+@dots{}
+.L18:
+ .align 4
+ .word 0x5
+@end example
+
+Because the value is formed by subtracting one symbol from another, the
+value is absolute, not relocatable, and so the object file contains
+
+@example
+Symnum n_type n_othr n_desc n_value n_strx String
+31 STSYM 0 4 00000004 680 ld:V(0,3)
+@end example
+
+without any relocations, and the executable file also contains
+
+@example
+Symnum n_type n_othr n_desc n_value n_strx String
+31 STSYM 0 4 00000004 680 ld:V(0,3)
+@end example
+
+@node Cplusplus
+@chapter GNU C++ Stabs
+
+@menu
+* Class Names:: C++ class names are both tags and typedefs.
+* Nested Symbols:: C++ symbol names can be within other types.
+* Basic Cplusplus Types::
+* Simple Classes::
+* Class Instance::
+* Methods:: Method definition
+* Method Type Descriptor:: The @samp{#} type descriptor
+* Member Type Descriptor:: The @samp{@@} type descriptor
+* Protections::
+* Method Modifiers::
+* Virtual Methods::
+* Inheritance::
+* Virtual Base Classes::
+* Static Members::
+@end menu
+
+@node Class Names
+@section C++ Class Names
+
+In C++, a class name which is declared with @code{class}, @code{struct},
+or @code{union}, is not only a tag, as in C, but also a type name. Thus
+there should be stabs with both @samp{t} and @samp{T} symbol descriptors
+(@pxref{Typedefs}).
+
+To save space, there is a special abbreviation for this case. If the
+@samp{T} symbol descriptor is followed by @samp{t}, then the stab
+defines both a type name and a tag.
+
+For example, the C++ code
+
+@example
+struct foo @{int x;@};
+@end example
+
+can be represented as either
+
+@example
+.stabs "foo:T19=s4x:1,0,32;;",128,0,0,0 # @r{128 is N_LSYM}
+.stabs "foo:t19",128,0,0,0
+@end example
+
+or
+
+@example
+.stabs "foo:Tt19=s4x:1,0,32;;",128,0,0,0
+@end example
+
+@node Nested Symbols
+@section Defining a Symbol Within Another Type
+
+In C++, a symbol (such as a type name) can be defined within another type.
+@c FIXME: Needs example.
+
+In stabs, this is sometimes represented by making the name of a symbol
+which contains @samp{::}. Such a pair of colons does not end the name
+of the symbol, the way a single colon would (@pxref{String Field}). I'm
+not sure how consistently used or well thought out this mechanism is.
+So that a pair of colons in this position always has this meaning,
+@samp{:} cannot be used as a symbol descriptor.
+
+For example, if the string for a stab is @samp{foo::bar::baz:t5=*6},
+then @code{foo::bar::baz} is the name of the symbol, @samp{t} is the
+symbol descriptor, and @samp{5=*6} is the type information.
+
+@node Basic Cplusplus Types
+@section Basic Types For C++
+
+<< the examples that follow are based on a01.C >>
+
+
+C++ adds two more builtin types to the set defined for C. These are
+the unknown type and the vtable record type. The unknown type, type
+16, is defined in terms of itself like the void type.
+
+The vtable record type, type 17, is defined as a structure type and
+then as a structure tag. The structure has four fields: delta, index,
+pfn, and delta2. pfn is the function pointer.
+
+<< In boilerplate $vtbl_ptr_type, what are the fields delta,
+index, and delta2 used for? >>
+
+This basic type is present in all C++ programs even if there are no
+virtual methods defined.
+
+@display
+.stabs "struct_name:sym_desc(type)type_def(17)=type_desc(struct)struct_bytes(8)
+ elem_name(delta):type_ref(short int),bit_offset(0),field_bits(16);
+ elem_name(index):type_ref(short int),bit_offset(16),field_bits(16);
+ elem_name(pfn):type_def(18)=type_desc(ptr to)type_ref(void),
+ bit_offset(32),field_bits(32);
+ elem_name(delta2):type_def(short int);bit_offset(32),field_bits(16);;"
+ N_LSYM, NIL, NIL
+@end display
+
+@smallexample
+.stabs "$vtbl_ptr_type:t17=s8
+ delta:6,0,16;index:6,16,16;pfn:18=*15,32,32;delta2:6,32,16;;"
+ ,128,0,0,0
+@end smallexample
+
+@display
+.stabs "name:sym_dec(struct tag)type_ref($vtbl_ptr_type)",N_LSYM,NIL,NIL,NIL
+@end display
+
+@example
+.stabs "$vtbl_ptr_type:T17",128,0,0,0
+@end example
+
+@node Simple Classes
+@section Simple Class Definition
+
+The stabs describing C++ language features are an extension of the
+stabs describing C. Stabs representing C++ class types elaborate
+extensively on the stab format used to describe structure types in C.
+Stabs representing class type variables look just like stabs
+representing C language variables.
+
+Consider the following very simple class definition.
+
+@example
+class baseA @{
+public:
+ int Adat;
+ int Ameth(int in, char other);
+@};
+@end example
+
+The class @code{baseA} is represented by two stabs. The first stab describes
+the class as a structure type. The second stab describes a structure
+tag of the class type. Both stabs are of stab type @code{N_LSYM}. Since the
+stab is not located between an @code{N_FUN} and an @code{N_LBRAC} stab this indicates
+that the class is defined at file scope. If it were, then the @code{N_LSYM}
+would signify a local variable.
+
+A stab describing a C++ class type is similar in format to a stab
+describing a C struct, with each class member shown as a field in the
+structure. The part of the struct format describing fields is
+expanded to include extra information relevant to C++ class members.
+In addition, if the class has multiple base classes or virtual
+functions the struct format outside of the field parts is also
+augmented.
+
+In this simple example the field part of the C++ class stab
+representing member data looks just like the field part of a C struct
+stab. The section on protections describes how its format is
+sometimes extended for member data.
+
+The field part of a C++ class stab representing a member function
+differs substantially from the field part of a C struct stab. It
+still begins with @samp{name:} but then goes on to define a new type number
+for the member function, describe its return type, its argument types,
+its protection level, any qualifiers applied to the method definition,
+and whether the method is virtual or not. If the method is virtual
+then the method description goes on to give the vtable index of the
+method, and the type number of the first base class defining the
+method.
+
+When the field name is a method name it is followed by two colons rather
+than one. This is followed by a new type definition for the method.
+This is a number followed by an equal sign and the type of the method.
+Normally this will be a type declared using the @samp{#} type
+descriptor; see @ref{Method Type Descriptor}; static member functions
+are declared using the @samp{f} type descriptor instead; see
+@ref{Function Types}.
+
+The format of an overloaded operator method name differs from that of
+other methods. It is @samp{op$::@var{operator-name}.} where
+@var{operator-name} is the operator name such as @samp{+} or @samp{+=}.
+The name ends with a period, and any characters except the period can
+occur in the @var{operator-name} string.
+
+The next part of the method description represents the arguments to the
+method, preceded by a colon and ending with a semi-colon. The types of
+the arguments are expressed in the same way argument types are expressed
+in C++ name mangling. In this example an @code{int} and a @code{char}
+map to @samp{ic}.
+
+This is followed by a number, a letter, and an asterisk or period,
+followed by another semicolon. The number indicates the protections
+that apply to the member function. Here the 2 means public. The
+letter encodes any qualifier applied to the method definition. In
+this case, @samp{A} means that it is a normal function definition. The dot
+shows that the method is not virtual. The sections that follow
+elaborate further on these fields and describe the additional
+information present for virtual methods.
+
+
+@display
+.stabs "class_name:sym_desc(type)type_def(20)=type_desc(struct)struct_bytes(4)
+ field_name(Adat):type(int),bit_offset(0),field_bits(32);
+
+ method_name(Ameth)::type_def(21)=type_desc(method)return_type(int);
+ :arg_types(int char);
+ protection(public)qualifier(normal)virtual(no);;"
+ N_LSYM,NIL,NIL,NIL
+@end display
+
+@smallexample
+.stabs "baseA:t20=s4Adat:1,0,32;Ameth::21=##1;:ic;2A.;;",128,0,0,0
+
+.stabs "class_name:sym_desc(struct tag)",N_LSYM,NIL,NIL,NIL
+
+.stabs "baseA:T20",128,0,0,0
+@end smallexample
+
+@node Class Instance
+@section Class Instance
+
+As shown above, describing even a simple C++ class definition is
+accomplished by massively extending the stab format used in C to
+describe structure types. However, once the class is defined, C stabs
+with no modifications can be used to describe class instances. The
+following source:
+
+@example
+main () @{
+ baseA AbaseA;
+@}
+@end example
+
+@noindent
+yields the following stab describing the class instance. It looks no
+different from a standard C stab describing a local variable.
+
+@display
+.stabs "name:type_ref(baseA)", N_LSYM, NIL, NIL, frame_ptr_offset
+@end display
+
+@example
+.stabs "AbaseA:20",128,0,0,-20
+@end example
+
+@node Methods
+@section Method Definition
+
+The class definition shown above declares Ameth. The C++ source below
+defines Ameth:
+
+@example
+int
+baseA::Ameth(int in, char other)
+@{
+ return in;
+@};
+@end example
+
+
+This method definition yields three stabs following the code of the
+method. One stab describes the method itself and following two describe
+its parameters. Although there is only one formal argument all methods
+have an implicit argument which is the @code{this} pointer. The @code{this}
+pointer is a pointer to the object on which the method was called. Note
+that the method name is mangled to encode the class name and argument
+types. Name mangling is described in the @sc{arm} (@cite{The Annotated
+C++ Reference Manual}, by Ellis and Stroustrup, @sc{isbn}
+0-201-51459-1); @file{gpcompare.texi} in Cygnus GCC distributions
+describes the differences between GNU mangling and @sc{arm}
+mangling.
+@c FIXME: Use @xref, especially if this is generally installed in the
+@c info tree.
+@c FIXME: This information should be in a net release, either of GCC or
+@c GDB. But gpcompare.texi doesn't seem to be in the FSF GCC.
+
+@example
+.stabs "name:symbol_descriptor(global function)return_type(int)",
+ N_FUN, NIL, NIL, code_addr_of_method_start
+
+.stabs "Ameth__5baseAic:F1",36,0,0,_Ameth__5baseAic
+@end example
+
+Here is the stab for the @code{this} pointer implicit argument. The
+name of the @code{this} pointer is always @code{this}. Type 19, the
+@code{this} pointer is defined as a pointer to type 20, @code{baseA},
+but a stab defining @code{baseA} has not yet been emitted. Since the
+compiler knows it will be emitted shortly, here it just outputs a cross
+reference to the undefined symbol, by prefixing the symbol name with
+@samp{xs}.
+
+@example
+.stabs "name:sym_desc(register param)type_def(19)=
+ type_desc(ptr to)type_ref(baseA)=
+ type_desc(cross-reference to)baseA:",N_RSYM,NIL,NIL,register_number
+
+.stabs "this:P19=*20=xsbaseA:",64,0,0,8
+@end example
+
+The stab for the explicit integer argument looks just like a parameter
+to a C function. The last field of the stab is the offset from the
+argument pointer, which in most systems is the same as the frame
+pointer.
+
+@example
+.stabs "name:sym_desc(value parameter)type_ref(int)",
+ N_PSYM,NIL,NIL,offset_from_arg_ptr
+
+.stabs "in:p1",160,0,0,72
+@end example
+
+<< The examples that follow are based on A1.C >>
+
+@node Method Type Descriptor
+@section The @samp{#} Type Descriptor
+
+This is used to describe a class method. This is a function which takes
+an extra argument as its first argument, for the @code{this} pointer.
+
+If the @samp{#} is immediately followed by another @samp{#}, the second
+one will be followed by the return type and a semicolon. The class and
+argument types are not specified, and must be determined by demangling
+the name of the method if it is available.
+
+Otherwise, the single @samp{#} is followed by the class type, a comma,
+the return type, a comma, and zero or more parameter types separated by
+commas. The list of arguments is terminated by a semicolon. In the
+debugging output generated by gcc, a final argument type of @code{void}
+indicates a method which does not take a variable number of arguments.
+If the final argument type of @code{void} does not appear, the method
+was declared with an ellipsis.
+
+Note that although such a type will normally be used to describe fields
+in structures, unions, or classes, for at least some versions of the
+compiler it can also be used in other contexts.
+
+@node Member Type Descriptor
+@section The @samp{@@} Type Descriptor
+
+The @samp{@@} type descriptor is for a member (class and variable) type.
+It is followed by type information for the offset basetype, a comma, and
+type information for the type of the field being pointed to. (FIXME:
+this is acknowledged to be gibberish. Can anyone say what really goes
+here?).
+
+Note that there is a conflict between this and type attributes
+(@pxref{String Field}); both use type descriptor @samp{@@}.
+Fortunately, the @samp{@@} type descriptor used in this C++ sense always
+will be followed by a digit, @samp{(}, or @samp{-}, and type attributes
+never start with those things.
+
+@node Protections
+@section Protections
+
+In the simple class definition shown above all member data and
+functions were publicly accessible. The example that follows
+contrasts public, protected and privately accessible fields and shows
+how these protections are encoded in C++ stabs.
+
+If the character following the @samp{@var{field-name}:} part of the
+string is @samp{/}, then the next character is the visibility. @samp{0}
+means private, @samp{1} means protected, and @samp{2} means public.
+Debuggers should ignore visibility characters they do not recognize, and
+assume a reasonable default (such as public) (GDB 4.11 does not, but
+this should be fixed in the next GDB release). If no visibility is
+specified the field is public. The visibility @samp{9} means that the
+field has been optimized out and is public (there is no way to specify
+an optimized out field with a private or protected visibility).
+Visibility @samp{9} is not supported by GDB 4.11; this should be fixed
+in the next GDB release.
+
+The following C++ source:
+
+@example
+class vis @{
+private:
+ int priv;
+protected:
+ char prot;
+public:
+ float pub;
+@};
+@end example
+
+@noindent
+generates the following stab:
+
+@example
+# @r{128 is N_LSYM}
+.stabs "vis:T19=s12priv:/01,0,32;prot:/12,32,8;pub:12,64,32;;",128,0,0,0
+@end example
+
+@samp{vis:T19=s12} indicates that type number 19 is a 12 byte structure
+named @code{vis} The @code{priv} field has public visibility
+(@samp{/0}), type int (@samp{1}), and offset and size @samp{,0,32;}.
+The @code{prot} field has protected visibility (@samp{/1}), type char
+(@samp{2}) and offset and size @samp{,32,8;}. The @code{pub} field has
+type float (@samp{12}), and offset and size @samp{,64,32;}.
+
+Protections for member functions are signified by one digit embedded in
+the field part of the stab describing the method. The digit is 0 if
+private, 1 if protected and 2 if public. Consider the C++ class
+definition below:
+
+@example
+class all_methods @{
+private:
+ int priv_meth(int in)@{return in;@};
+protected:
+ char protMeth(char in)@{return in;@};
+public:
+ float pubMeth(float in)@{return in;@};
+@};
+@end example
+
+It generates the following stab. The digit in question is to the left
+of an @samp{A} in each case. Notice also that in this case two symbol
+descriptors apply to the class name struct tag and struct type.
+
+@display
+.stabs "class_name:sym_desc(struct tag&type)type_def(21)=
+ sym_desc(struct)struct_bytes(1)
+ meth_name::type_def(22)=sym_desc(method)returning(int);
+ :args(int);protection(private)modifier(normal)virtual(no);
+ meth_name::type_def(23)=sym_desc(method)returning(char);
+ :args(char);protection(protected)modifier(normal)virtual(no);
+ meth_name::type_def(24)=sym_desc(method)returning(float);
+ :args(float);protection(public)modifier(normal)virtual(no);;",
+ N_LSYM,NIL,NIL,NIL
+@end display
+
+@smallexample
+.stabs "all_methods:Tt21=s1priv_meth::22=##1;:i;0A.;protMeth::23=##2;:c;1A.;
+ pubMeth::24=##12;:f;2A.;;",128,0,0,0
+@end smallexample
+
+@node Method Modifiers
+@section Method Modifiers (@code{const}, @code{volatile}, @code{const volatile})
+
+<< based on a6.C >>
+
+In the class example described above all the methods have the normal
+modifier. This method modifier information is located just after the
+protection information for the method. This field has four possible
+character values. Normal methods use @samp{A}, const methods use
+@samp{B}, volatile methods use @samp{C}, and const volatile methods use
+@samp{D}. Consider the class definition below:
+
+@example
+class A @{
+public:
+ int ConstMeth (int arg) const @{ return arg; @};
+ char VolatileMeth (char arg) volatile @{ return arg; @};
+ float ConstVolMeth (float arg) const volatile @{return arg; @};
+@};
+@end example
+
+This class is described by the following stab:
+
+@display
+.stabs "class(A):sym_desc(struct)type_def(20)=type_desc(struct)struct_bytes(1)
+ meth_name(ConstMeth)::type_def(21)sym_desc(method)
+ returning(int);:arg(int);protection(public)modifier(const)virtual(no);
+ meth_name(VolatileMeth)::type_def(22)=sym_desc(method)
+ returning(char);:arg(char);protection(public)modifier(volatile)virt(no)
+ meth_name(ConstVolMeth)::type_def(23)=sym_desc(method)
+ returning(float);:arg(float);protection(public)modifier(const volatile)
+ virtual(no);;", @dots{}
+@end display
+
+@example
+.stabs "A:T20=s1ConstMeth::21=##1;:i;2B.;VolatileMeth::22=##2;:c;2C.;
+ ConstVolMeth::23=##12;:f;2D.;;",128,0,0,0
+@end example
+
+@node Virtual Methods
+@section Virtual Methods
+
+<< The following examples are based on a4.C >>
+
+The presence of virtual methods in a class definition adds additional
+data to the class description. The extra data is appended to the
+description of the virtual method and to the end of the class
+description. Consider the class definition below:
+
+@example
+class A @{
+public:
+ int Adat;
+ virtual int A_virt (int arg) @{ return arg; @};
+@};
+@end example
+
+This results in the stab below describing class A. It defines a new
+type (20) which is an 8 byte structure. The first field of the class
+struct is @samp{Adat}, an integer, starting at structure offset 0 and
+occupying 32 bits.
+
+The second field in the class struct is not explicitly defined by the
+C++ class definition but is implied by the fact that the class
+contains a virtual method. This field is the vtable pointer. The
+name of the vtable pointer field starts with @samp{$vf} and continues with a
+type reference to the class it is part of. In this example the type
+reference for class A is 20 so the name of its vtable pointer field is
+@samp{$vf20}, followed by the usual colon.
+
+Next there is a type definition for the vtable pointer type (21).
+This is in turn defined as a pointer to another new type (22).
+
+Type 22 is the vtable itself, which is defined as an array, indexed by
+a range of integers between 0 and 1, and whose elements are of type
+17. Type 17 was the vtable record type defined by the boilerplate C++
+type definitions, as shown earlier.
+
+The bit offset of the vtable pointer field is 32. The number of bits
+in the field are not specified when the field is a vtable pointer.
+
+Next is the method definition for the virtual member function @code{A_virt}.
+Its description starts out using the same format as the non-virtual
+member functions described above, except instead of a dot after the
+@samp{A} there is an asterisk, indicating that the function is virtual.
+Since is is virtual some addition information is appended to the end
+of the method description.
+
+The first number represents the vtable index of the method. This is a
+32 bit unsigned number with the high bit set, followed by a
+semi-colon.
+
+The second number is a type reference to the first base class in the
+inheritance hierarchy defining the virtual member function. In this
+case the class stab describes a base class so the virtual function is
+not overriding any other definition of the method. Therefore the
+reference is to the type number of the class that the stab is
+describing (20).
+
+This is followed by three semi-colons. One marks the end of the
+current sub-section, one marks the end of the method field, and the
+third marks the end of the struct definition.
+
+For classes containing virtual functions the very last section of the
+string part of the stab holds a type reference to the first base
+class. This is preceded by @samp{~%} and followed by a final semi-colon.
+
+@display
+.stabs "class_name(A):type_def(20)=sym_desc(struct)struct_bytes(8)
+ field_name(Adat):type_ref(int),bit_offset(0),field_bits(32);
+ field_name(A virt func ptr):type_def(21)=type_desc(ptr to)type_def(22)=
+ sym_desc(array)index_type_ref(range of int from 0 to 1);
+ elem_type_ref(vtbl elem type),
+ bit_offset(32);
+ meth_name(A_virt)::typedef(23)=sym_desc(method)returning(int);
+ :arg_type(int),protection(public)normal(yes)virtual(yes)
+ vtable_index(1);class_first_defining(A);;;~%first_base(A);",
+ N_LSYM,NIL,NIL,NIL
+@end display
+
+@c FIXME: bogus line break.
+@example
+.stabs "A:t20=s8Adat:1,0,32;$vf20:21=*22=ar1;0;1;17,32;
+ A_virt::23=##1;:i;2A*-2147483647;20;;;~%20;",128,0,0,0
+@end example
+
+@node Inheritance
+@section Inheritance
+
+Stabs describing C++ derived classes include additional sections that
+describe the inheritance hierarchy of the class. A derived class stab
+also encodes the number of base classes. For each base class it tells
+if the base class is virtual or not, and if the inheritance is private
+or public. It also gives the offset into the object of the portion of
+the object corresponding to each base class.
+
+This additional information is embedded in the class stab following the
+number of bytes in the struct. First the number of base classes
+appears bracketed by an exclamation point and a comma.
+
+Then for each base type there repeats a series: a virtual character, a
+visibility character, a number, a comma, another number, and a
+semi-colon.
+
+The virtual character is @samp{1} if the base class is virtual and
+@samp{0} if not. The visibility character is @samp{2} if the derivation
+is public, @samp{1} if it is protected, and @samp{0} if it is private.
+Debuggers should ignore virtual or visibility characters they do not
+recognize, and assume a reasonable default (such as public and
+non-virtual) (GDB 4.11 does not, but this should be fixed in the next
+GDB release).
+
+The number following the virtual and visibility characters is the offset
+from the start of the object to the part of the object pertaining to the
+base class.
+
+After the comma, the second number is a type_descriptor for the base
+type. Finally a semi-colon ends the series, which repeats for each
+base class.
+
+The source below defines three base classes @code{A}, @code{B}, and
+@code{C} and the derived class @code{D}.
+
+
+@example
+class A @{
+public:
+ int Adat;
+ virtual int A_virt (int arg) @{ return arg; @};
+@};
+
+class B @{
+public:
+ int B_dat;
+ virtual int B_virt (int arg) @{return arg; @};
+@};
+
+class C @{
+public:
+ int Cdat;
+ virtual int C_virt (int arg) @{return arg; @};
+@};
+
+class D : A, virtual B, public C @{
+public:
+ int Ddat;
+ virtual int A_virt (int arg ) @{ return arg+1; @};
+ virtual int B_virt (int arg) @{ return arg+2; @};
+ virtual int C_virt (int arg) @{ return arg+3; @};
+ virtual int D_virt (int arg) @{ return arg; @};
+@};
+@end example
+
+Class stabs similar to the ones described earlier are generated for
+each base class.
+
+@c FIXME!!! the linebreaks in the following example probably make the
+@c examples literally unusable, but I don't know any other way to get
+@c them on the page.
+@c One solution would be to put some of the type definitions into
+@c separate stabs, even if that's not exactly what the compiler actually
+@c emits.
+@smallexample
+.stabs "A:T20=s8Adat:1,0,32;$vf20:21=*22=ar1;0;1;17,32;
+ A_virt::23=##1;:i;2A*-2147483647;20;;;~%20;",128,0,0,0
+
+.stabs "B:Tt25=s8Bdat:1,0,32;$vf25:21,32;B_virt::26=##1;
+ :i;2A*-2147483647;25;;;~%25;",128,0,0,0
+
+.stabs "C:Tt28=s8Cdat:1,0,32;$vf28:21,32;C_virt::29=##1;
+ :i;2A*-2147483647;28;;;~%28;",128,0,0,0
+@end smallexample
+
+In the stab describing derived class @code{D} below, the information about
+the derivation of this class is encoded as follows.
+
+@display
+.stabs "derived_class_name:symbol_descriptors(struct tag&type)=
+ type_descriptor(struct)struct_bytes(32)!num_bases(3),
+ base_virtual(no)inheritance_public(no)base_offset(0),
+ base_class_type_ref(A);
+ base_virtual(yes)inheritance_public(no)base_offset(NIL),
+ base_class_type_ref(B);
+ base_virtual(no)inheritance_public(yes)base_offset(64),
+ base_class_type_ref(C); @dots{}
+@end display
+
+@c FIXME! fake linebreaks.
+@smallexample
+.stabs "D:Tt31=s32!3,000,20;100,25;0264,28;$vb25:24,128;Ddat:
+ 1,160,32;A_virt::32=##1;:i;2A*-2147483647;20;;B_virt:
+ :32:i;2A*-2147483647;25;;C_virt::32:i;2A*-2147483647;
+ 28;;D_virt::32:i;2A*-2147483646;31;;;~%20;",128,0,0,0
+@end smallexample
+
+@node Virtual Base Classes
+@section Virtual Base Classes
+
+A derived class object consists of a concatenation in memory of the data
+areas defined by each base class, starting with the leftmost and ending
+with the rightmost in the list of base classes. The exception to this
+rule is for virtual inheritance. In the example above, class @code{D}
+inherits virtually from base class @code{B}. This means that an
+instance of a @code{D} object will not contain its own @code{B} part but
+merely a pointer to a @code{B} part, known as a virtual base pointer.
+
+In a derived class stab, the base offset part of the derivation
+information, described above, shows how the base class parts are
+ordered. The base offset for a virtual base class is always given as 0.
+Notice that the base offset for @code{B} is given as 0 even though
+@code{B} is not the first base class. The first base class @code{A}
+starts at offset 0.
+
+The field information part of the stab for class @code{D} describes the field
+which is the pointer to the virtual base class @code{B}. The vbase pointer
+name is @samp{$vb} followed by a type reference to the virtual base class.
+Since the type id for @code{B} in this example is 25, the vbase pointer name
+is @samp{$vb25}.
+
+@c FIXME!! fake linebreaks below
+@smallexample
+.stabs "D:Tt31=s32!3,000,20;100,25;0264,28;$vb25:24,128;Ddat:1,
+ 160,32;A_virt::32=##1;:i;2A*-2147483647;20;;B_virt::32:i;
+ 2A*-2147483647;25;;C_virt::32:i;2A*-2147483647;28;;D_virt:
+ :32:i;2A*-2147483646;31;;;~%20;",128,0,0,0
+@end smallexample
+
+Following the name and a semicolon is a type reference describing the
+type of the virtual base class pointer, in this case 24. Type 24 was
+defined earlier as the type of the @code{B} class @code{this} pointer. The
+@code{this} pointer for a class is a pointer to the class type.
+
+@example
+.stabs "this:P24=*25=xsB:",64,0,0,8
+@end example
+
+Finally the field offset part of the vbase pointer field description
+shows that the vbase pointer is the first field in the @code{D} object,
+before any data fields defined by the class. The layout of a @code{D}
+class object is a follows, @code{Adat} at 0, the vtable pointer for
+@code{A} at 32, @code{Cdat} at 64, the vtable pointer for C at 96, the
+virtual base pointer for @code{B} at 128, and @code{Ddat} at 160.
+
+
+@node Static Members
+@section Static Members
+
+The data area for a class is a concatenation of the space used by the
+data members of the class. If the class has virtual methods, a vtable
+pointer follows the class data. The field offset part of each field
+description in the class stab shows this ordering.
+
+<< How is this reflected in stabs? See Cygnus bug #677 for some info. >>
+
+@node Stab Types
+@appendix Table of Stab Types
+
+The following are all the possible values for the stab type field, for
+a.out files, in numeric order. This does not apply to XCOFF, but
+it does apply to stabs in sections (@pxref{Stab Sections}). Stabs in
+ECOFF use these values but add 0x8f300 to distinguish them from non-stab
+symbols.
+
+The symbolic names are defined in the file @file{include/aout/stabs.def}.
+
+@menu
+* Non-Stab Symbol Types:: Types from 0 to 0x1f
+* Stab Symbol Types:: Types from 0x20 to 0xff
+@end menu
+
+@node Non-Stab Symbol Types
+@appendixsec Non-Stab Symbol Types
+
+The following types are used by the linker and assembler, not by stab
+directives. Since this document does not attempt to describe aspects of
+object file format other than the debugging format, no details are
+given.
+
+@c Try to get most of these to fit on a single line.
+@iftex
+@tableindent=1.5in
+@end iftex
+
+@table @code
+@item 0x0 N_UNDF
+Undefined symbol
+
+@item 0x2 N_ABS
+File scope absolute symbol
+
+@item 0x3 N_ABS | N_EXT
+External absolute symbol
+
+@item 0x4 N_TEXT
+File scope text symbol
+
+@item 0x5 N_TEXT | N_EXT
+External text symbol
+
+@item 0x6 N_DATA
+File scope data symbol
+
+@item 0x7 N_DATA | N_EXT
+External data symbol
+
+@item 0x8 N_BSS
+File scope BSS symbol
+
+@item 0x9 N_BSS | N_EXT
+External BSS symbol
+
+@item 0x0c N_FN_SEQ
+Same as @code{N_FN}, for Sequent compilers
+
+@item 0x0a N_INDR
+Symbol is indirected to another symbol
+
+@item 0x12 N_COMM
+Common---visible after shared library dynamic link
+
+@item 0x14 N_SETA
+@itemx 0x15 N_SETA | N_EXT
+Absolute set element
+
+@item 0x16 N_SETT
+@itemx 0x17 N_SETT | N_EXT
+Text segment set element
+
+@item 0x18 N_SETD
+@itemx 0x19 N_SETD | N_EXT
+Data segment set element
+
+@item 0x1a N_SETB
+@itemx 0x1b N_SETB | N_EXT
+BSS segment set element
+
+@item 0x1c N_SETV
+@itemx 0x1d N_SETV | N_EXT
+Pointer to set vector
+
+@item 0x1e N_WARNING
+Print a warning message during linking
+
+@item 0x1f N_FN
+File name of a @file{.o} file
+@end table
+
+@node Stab Symbol Types
+@appendixsec Stab Symbol Types
+
+The following symbol types indicate that this is a stab. This is the
+full list of stab numbers, including stab types that are used in
+languages other than C.
+
+@table @code
+@item 0x20 N_GSYM
+Global symbol; see @ref{Global Variables}.
+
+@item 0x22 N_FNAME
+Function name (for BSD Fortran); see @ref{Procedures}.
+
+@item 0x24 N_FUN
+Function name (@pxref{Procedures}) or text segment variable
+(@pxref{Statics}).
+
+@item 0x26 N_STSYM
+Data segment file-scope variable; see @ref{Statics}.
+
+@item 0x28 N_LCSYM
+BSS segment file-scope variable; see @ref{Statics}.
+
+@item 0x2a N_MAIN
+Name of main routine; see @ref{Main Program}.
+
+@item 0x2c N_ROSYM
+Variable in @code{.rodata} section; see @ref{Statics}.
+
+@item 0x30 N_PC
+Global symbol (for Pascal); see @ref{N_PC}.
+
+@item 0x32 N_NSYMS
+Number of symbols (according to Ultrix V4.0); see @ref{N_NSYMS}.
+
+@item 0x34 N_NOMAP
+No DST map; see @ref{N_NOMAP}.
+
+@c FIXME: describe this solaris feature in the body of the text (see
+@c comments in include/aout/stab.def).
+@item 0x38 N_OBJ
+Object file (Solaris2).
+
+@c See include/aout/stab.def for (a little) more info.
+@item 0x3c N_OPT
+Debugger options (Solaris2).
+
+@item 0x40 N_RSYM
+Register variable; see @ref{Register Variables}.
+
+@item 0x42 N_M2C
+Modula-2 compilation unit; see @ref{N_M2C}.
+
+@item 0x44 N_SLINE
+Line number in text segment; see @ref{Line Numbers}.
+
+@item 0x46 N_DSLINE
+Line number in data segment; see @ref{Line Numbers}.
+
+@item 0x48 N_BSLINE
+Line number in bss segment; see @ref{Line Numbers}.
+
+@item 0x48 N_BROWS
+Sun source code browser, path to @file{.cb} file; see @ref{N_BROWS}.
+
+@item 0x4a N_DEFD
+GNU Modula2 definition module dependency; see @ref{N_DEFD}.
+
+@item 0x4c N_FLINE
+Function start/body/end line numbers (Solaris2).
+
+@item 0x50 N_EHDECL
+GNU C++ exception variable; see @ref{N_EHDECL}.
+
+@item 0x50 N_MOD2
+Modula2 info "for imc" (according to Ultrix V4.0); see @ref{N_MOD2}.
+
+@item 0x54 N_CATCH
+GNU C++ @code{catch} clause; see @ref{N_CATCH}.
+
+@item 0x60 N_SSYM
+Structure of union element; see @ref{N_SSYM}.
+
+@item 0x62 N_ENDM
+Last stab for module (Solaris2).
+
+@item 0x64 N_SO
+Path and name of source file; see @ref{Source Files}.
+
+@item 0x80 N_LSYM
+Stack variable (@pxref{Stack Variables}) or type (@pxref{Typedefs}).
+
+@item 0x82 N_BINCL
+Beginning of an include file (Sun only); see @ref{Include Files}.
+
+@item 0x84 N_SOL
+Name of include file; see @ref{Include Files}.
+
+@item 0xa0 N_PSYM
+Parameter variable; see @ref{Parameters}.
+
+@item 0xa2 N_EINCL
+End of an include file; see @ref{Include Files}.
+
+@item 0xa4 N_ENTRY
+Alternate entry point; see @ref{Alternate Entry Points}.
+
+@item 0xc0 N_LBRAC
+Beginning of a lexical block; see @ref{Block Structure}.
+
+@item 0xc2 N_EXCL
+Place holder for a deleted include file; see @ref{Include Files}.
+
+@item 0xc4 N_SCOPE
+Modula2 scope information (Sun linker); see @ref{N_SCOPE}.
+
+@item 0xe0 N_RBRAC
+End of a lexical block; see @ref{Block Structure}.
+
+@item 0xe2 N_BCOMM
+Begin named common block; see @ref{Common Blocks}.
+
+@item 0xe4 N_ECOMM
+End named common block; see @ref{Common Blocks}.
+
+@item 0xe8 N_ECOML
+Member of a common block; see @ref{Common Blocks}.
+
+@c FIXME: How does this really work? Move it to main body of document.
+@item 0xea N_WITH
+Pascal @code{with} statement: type,,0,0,offset (Solaris2).
+
+@item 0xf0 N_NBTEXT
+Gould non-base registers; see @ref{Gould}.
+
+@item 0xf2 N_NBDATA
+Gould non-base registers; see @ref{Gould}.
+
+@item 0xf4 N_NBBSS
+Gould non-base registers; see @ref{Gould}.
+
+@item 0xf6 N_NBSTS
+Gould non-base registers; see @ref{Gould}.
+
+@item 0xf8 N_NBLCS
+Gould non-base registers; see @ref{Gould}.
+@end table
+
+@c Restore the default table indent
+@iftex
+@tableindent=.8in
+@end iftex
+
+@node Symbol Descriptors
+@appendix Table of Symbol Descriptors
+
+The symbol descriptor is the character which follows the colon in many
+stabs, and which tells what kind of stab it is. @xref{String Field},
+for more information about their use.
+
+@c Please keep this alphabetical
+@table @code
+@c In TeX, this looks great, digit is in italics. But makeinfo insists
+@c on putting it in `', not realizing that @var should override @code.
+@c I don't know of any way to make makeinfo do the right thing. Seems
+@c like a makeinfo bug to me.
+@item @var{digit}
+@itemx (
+@itemx -
+Variable on the stack; see @ref{Stack Variables}.
+
+@item :
+C++ nested symbol; see @xref{Nested Symbols}.
+
+@item a
+Parameter passed by reference in register; see @ref{Reference Parameters}.
+
+@item b
+Based variable; see @ref{Based Variables}.
+
+@item c
+Constant; see @ref{Constants}.
+
+@item C
+Conformant array bound (Pascal, maybe other languages); @ref{Conformant
+Arrays}. Name of a caught exception (GNU C++). These can be
+distinguished because the latter uses @code{N_CATCH} and the former uses
+another symbol type.
+
+@item d
+Floating point register variable; see @ref{Register Variables}.
+
+@item D
+Parameter in floating point register; see @ref{Register Parameters}.
+
+@item f
+File scope function; see @ref{Procedures}.
+
+@item F
+Global function; see @ref{Procedures}.
+
+@item G
+Global variable; see @ref{Global Variables}.
+
+@item i
+@xref{Register Parameters}.
+
+@item I
+Internal (nested) procedure; see @ref{Nested Procedures}.
+
+@item J
+Internal (nested) function; see @ref{Nested Procedures}.
+
+@item L
+Label name (documented by AIX, no further information known).
+
+@item m
+Module; see @ref{Procedures}.
+
+@item p
+Argument list parameter; see @ref{Parameters}.
+
+@item pP
+@xref{Parameters}.
+
+@item pF
+Fortran Function parameter; see @ref{Parameters}.
+
+@item P
+Unfortunately, three separate meanings have been independently invented
+for this symbol descriptor. At least the GNU and Sun uses can be
+distinguished by the symbol type. Global Procedure (AIX) (symbol type
+used unknown); see @ref{Procedures}. Register parameter (GNU) (symbol
+type @code{N_PSYM}); see @ref{Parameters}. Prototype of function
+referenced by this file (Sun @code{acc}) (symbol type @code{N_FUN}).
+
+@item Q
+Static Procedure; see @ref{Procedures}.
+
+@item R
+Register parameter; see @ref{Register Parameters}.
+
+@item r
+Register variable; see @ref{Register Variables}.
+
+@item S
+File scope variable; see @ref{Statics}.
+
+@item s
+Local variable (OS9000).
+
+@item t
+Type name; see @ref{Typedefs}.
+
+@item T
+Enumeration, structure, or union tag; see @ref{Typedefs}.
+
+@item v
+Parameter passed by reference; see @ref{Reference Parameters}.
+
+@item V
+Procedure scope static variable; see @ref{Statics}.
+
+@item x
+Conformant array; see @ref{Conformant Arrays}.
+
+@item X
+Function return variable; see @ref{Parameters}.
+@end table
+
+@node Type Descriptors
+@appendix Table of Type Descriptors
+
+The type descriptor is the character which follows the type number and
+an equals sign. It specifies what kind of type is being defined.
+@xref{String Field}, for more information about their use.
+
+@table @code
+@item @var{digit}
+@itemx (
+Type reference; see @ref{String Field}.
+
+@item -
+Reference to builtin type; see @ref{Negative Type Numbers}.
+
+@item #
+Method (C++); see @ref{Method Type Descriptor}.
+
+@item *
+Pointer; see @ref{Miscellaneous Types}.
+
+@item &
+Reference (C++).
+
+@item @@
+Type Attributes (AIX); see @ref{String Field}. Member (class and variable)
+type (GNU C++); see @ref{Member Type Descriptor}.
+
+@item a
+Array; see @ref{Arrays}.
+
+@item A
+Open array; see @ref{Arrays}.
+
+@item b
+Pascal space type (AIX); see @ref{Miscellaneous Types}. Builtin integer
+type (Sun); see @ref{Builtin Type Descriptors}. Const and volatile
+qualified type (OS9000).
+
+@item B
+Volatile-qualified type; see @ref{Miscellaneous Types}.
+
+@item c
+Complex builtin type (AIX); see @ref{Builtin Type Descriptors}.
+Const-qualified type (OS9000).
+
+@item C
+COBOL Picture type. See AIX documentation for details.
+
+@item d
+File type; see @ref{Miscellaneous Types}.
+
+@item D
+N-dimensional dynamic array; see @ref{Arrays}.
+
+@item e
+Enumeration type; see @ref{Enumerations}.
+
+@item E
+N-dimensional subarray; see @ref{Arrays}.
+
+@item f
+Function type; see @ref{Function Types}.
+
+@item F
+Pascal function parameter; see @ref{Function Types}
+
+@item g
+Builtin floating point type; see @ref{Builtin Type Descriptors}.
+
+@item G
+COBOL Group. See AIX documentation for details.
+
+@item i
+Imported type (AIX); see @ref{Cross-References}. Volatile-qualified
+type (OS9000).
+
+@item k
+Const-qualified type; see @ref{Miscellaneous Types}.
+
+@item K
+COBOL File Descriptor. See AIX documentation for details.
+
+@item M
+Multiple instance type; see @ref{Miscellaneous Types}.
+
+@item n
+String type; see @ref{Strings}.
+
+@item N
+Stringptr; see @ref{Strings}.
+
+@item o
+Opaque type; see @ref{Typedefs}.
+
+@item p
+Procedure; see @ref{Function Types}.
+
+@item P
+Packed array; see @ref{Arrays}.
+
+@item r
+Range type; see @ref{Subranges}.
+
+@item R
+Builtin floating type; see @ref{Builtin Type Descriptors} (Sun). Pascal
+subroutine parameter; see @ref{Function Types} (AIX). Detecting this
+conflict is possible with careful parsing (hint: a Pascal subroutine
+parameter type will always contain a comma, and a builtin type
+descriptor never will).
+
+@item s
+Structure type; see @ref{Structures}.
+
+@item S
+Set type; see @ref{Miscellaneous Types}.
+
+@item u
+Union; see @ref{Unions}.
+
+@item v
+Variant record. This is a Pascal and Modula-2 feature which is like a
+union within a struct in C. See AIX documentation for details.
+
+@item w
+Wide character; see @ref{Builtin Type Descriptors}.
+
+@item x
+Cross-reference; see @ref{Cross-References}.
+
+@item Y
+Used by IBM's xlC C++ compiler (for structures, I think).
+
+@item z
+gstring; see @ref{Strings}.
+@end table
+
+@node Expanded Reference
+@appendix Expanded Reference by Stab Type
+
+@c FIXME: This appendix should go away; see N_PSYM or N_SO for an example.
+
+For a full list of stab types, and cross-references to where they are
+described, see @ref{Stab Types}. This appendix just covers certain
+stabs which are not yet described in the main body of this document;
+eventually the information will all be in one place.
+
+Format of an entry:
+
+The first line is the symbol type (see @file{include/aout/stab.def}).
+
+The second line describes the language constructs the symbol type
+represents.
+
+The third line is the stab format with the significant stab fields
+named and the rest NIL.
+
+Subsequent lines expand upon the meaning and possible values for each
+significant stab field.
+
+Finally, any further information.
+
+@menu
+* N_PC:: Pascal global symbol
+* N_NSYMS:: Number of symbols
+* N_NOMAP:: No DST map
+* N_M2C:: Modula-2 compilation unit
+* N_BROWS:: Path to .cb file for Sun source code browser
+* N_DEFD:: GNU Modula2 definition module dependency
+* N_EHDECL:: GNU C++ exception variable
+* N_MOD2:: Modula2 information "for imc"
+* N_CATCH:: GNU C++ "catch" clause
+* N_SSYM:: Structure or union element
+* N_SCOPE:: Modula2 scope information (Sun only)
+* Gould:: non-base register symbols used on Gould systems
+* N_LENG:: Length of preceding entry
+@end menu
+
+@node N_PC
+@section N_PC
+
+@deffn @code{.stabs} N_PC
+@findex N_PC
+Global symbol (for Pascal).
+
+@example
+"name" -> "symbol_name" <<?>>
+value -> supposedly the line number (stab.def is skeptical)
+@end example
+
+@display
+@file{stabdump.c} says:
+
+global pascal symbol: name,,0,subtype,line
+<< subtype? >>
+@end display
+@end deffn
+
+@node N_NSYMS
+@section N_NSYMS
+
+@deffn @code{.stabn} N_NSYMS
+@findex N_NSYMS
+Number of symbols (according to Ultrix V4.0).
+
+@display
+ 0, files,,funcs,lines (stab.def)
+@end display
+@end deffn
+
+@node N_NOMAP
+@section N_NOMAP
+
+@deffn @code{.stabs} N_NOMAP
+@findex N_NOMAP
+No DST map for symbol (according to Ultrix V4.0). I think this means a
+variable has been optimized out.
+
+@display
+ name, ,0,type,ignored (stab.def)
+@end display
+@end deffn
+
+@node N_M2C
+@section N_M2C
+
+@deffn @code{.stabs} N_M2C
+@findex N_M2C
+Modula-2 compilation unit.
+
+@example
+"string" -> "unit_name,unit_time_stamp[,code_time_stamp]"
+desc -> unit_number
+value -> 0 (main unit)
+ 1 (any other unit)
+@end example
+
+See @cite{Dbx and Dbxtool Interfaces}, 2nd edition, by Sun, 1988, for
+more information.
+
+@end deffn
+
+@node N_BROWS
+@section N_BROWS
+
+@deffn @code{.stabs} N_BROWS
+@findex N_BROWS
+Sun source code browser, path to @file{.cb} file
+
+<<?>>
+"path to associated @file{.cb} file"
+
+Note: N_BROWS has the same value as N_BSLINE.
+@end deffn
+
+@node N_DEFD
+@section N_DEFD
+
+@deffn @code{.stabn} N_DEFD
+@findex N_DEFD
+GNU Modula2 definition module dependency.
+
+GNU Modula-2 definition module dependency. The value is the
+modification time of the definition file. The other field is non-zero
+if it is imported with the GNU M2 keyword @code{%INITIALIZE}. Perhaps
+@code{N_M2C} can be used if there are enough empty fields?
+@end deffn
+
+@node N_EHDECL
+@section N_EHDECL
+
+@deffn @code{.stabs} N_EHDECL
+@findex N_EHDECL
+GNU C++ exception variable <<?>>.
+
+"@var{string} is variable name"
+
+Note: conflicts with @code{N_MOD2}.
+@end deffn
+
+@node N_MOD2
+@section N_MOD2
+
+@deffn @code{.stab?} N_MOD2
+@findex N_MOD2
+Modula2 info "for imc" (according to Ultrix V4.0)
+
+Note: conflicts with @code{N_EHDECL} <<?>>
+@end deffn
+
+@node N_CATCH
+@section N_CATCH
+
+@deffn @code{.stabn} N_CATCH
+@findex N_CATCH
+GNU C++ @code{catch} clause
+
+GNU C++ @code{catch} clause. The value is its address. The desc field
+is nonzero if this entry is immediately followed by a @code{CAUGHT} stab
+saying what exception was caught. Multiple @code{CAUGHT} stabs means
+that multiple exceptions can be caught here. If desc is 0, it means all
+exceptions are caught here.
+@end deffn
+
+@node N_SSYM
+@section N_SSYM
+
+@deffn @code{.stabn} N_SSYM
+@findex N_SSYM
+Structure or union element.
+
+The value is the offset in the structure.
+
+<<?looking at structs and unions in C I didn't see these>>
+@end deffn
+
+@node N_SCOPE
+@section N_SCOPE
+
+@deffn @code{.stab?} N_SCOPE
+@findex N_SCOPE
+Modula2 scope information (Sun linker)
+<<?>>
+@end deffn
+
+@node Gould
+@section Non-base registers on Gould systems
+
+@deffn @code{.stab?} N_NBTEXT
+@deffnx @code{.stab?} N_NBDATA
+@deffnx @code{.stab?} N_NBBSS
+@deffnx @code{.stab?} N_NBSTS
+@deffnx @code{.stab?} N_NBLCS
+@findex N_NBTEXT
+@findex N_NBDATA
+@findex N_NBBSS
+@findex N_NBSTS
+@findex N_NBLCS
+These are used on Gould systems for non-base registers syms.
+
+However, the following values are not the values used by Gould; they are
+the values which GNU has been documenting for these values for a long
+time, without actually checking what Gould uses. I include these values
+only because perhaps some someone actually did something with the GNU
+information (I hope not, why GNU knowingly assigned wrong values to
+these in the header file is a complete mystery to me).
+
+@example
+240 0xf0 N_NBTEXT ??
+242 0xf2 N_NBDATA ??
+244 0xf4 N_NBBSS ??
+246 0xf6 N_NBSTS ??
+248 0xf8 N_NBLCS ??
+@end example
+@end deffn
+
+@node N_LENG
+@section N_LENG
+
+@deffn @code{.stabn} N_LENG
+@findex N_LENG
+Second symbol entry containing a length-value for the preceding entry.
+The value is the length.
+@end deffn
+
+@node Questions
+@appendix Questions and Anomalies
+
+@itemize @bullet
+@item
+@c I think this is changed in GCC 2.4.5 to put the line number there.
+For GNU C stabs defining local and global variables (@code{N_LSYM} and
+@code{N_GSYM}), the desc field is supposed to contain the source
+line number on which the variable is defined. In reality the desc
+field is always 0. (This behavior is defined in @file{dbxout.c} and
+putting a line number in desc is controlled by @samp{#ifdef
+WINNING_GDB}, which defaults to false). GDB supposedly uses this
+information if you say @samp{list @var{var}}. In reality, @var{var} can
+be a variable defined in the program and GDB says @samp{function
+@var{var} not defined}.
+
+@item
+In GNU C stabs, there seems to be no way to differentiate tag types:
+structures, unions, and enums (symbol descriptor @samp{T}) and typedefs
+(symbol descriptor @samp{t}) defined at file scope from types defined locally
+to a procedure or other more local scope. They all use the @code{N_LSYM}
+stab type. Types defined at procedure scope are emitted after the
+@code{N_RBRAC} of the preceding function and before the code of the
+procedure in which they are defined. This is exactly the same as
+types defined in the source file between the two procedure bodies.
+GDB over-compensates by placing all types in block #1, the block for
+symbols of file scope. This is true for default, @samp{-ansi} and
+@samp{-traditional} compiler options. (Bugs gcc/1063, gdb/1066.)
+
+@item
+What ends the procedure scope? Is it the proc block's @code{N_RBRAC} or the
+next @code{N_FUN}? (I believe its the first.)
+@end itemize
+
+@node Stab Sections
+@appendix Using Stabs in Their Own Sections
+
+Many object file formats allow tools to create object files with custom
+sections containing any arbitrary data. For any such object file
+format, stabs can be embedded in special sections. This is how stabs
+are used with ELF and SOM, and aside from ECOFF and XCOFF, is how stabs
+are used with COFF.
+
+@menu
+* Stab Section Basics:: How to embed stabs in sections
+* ELF Linker Relocation:: Sun ELF hacks
+@end menu
+
+@node Stab Section Basics
+@appendixsec How to Embed Stabs in Sections
+
+The assembler creates two custom sections, a section named @code{.stab}
+which contains an array of fixed length structures, one struct per stab,
+and a section named @code{.stabstr} containing all the variable length
+strings that are referenced by stabs in the @code{.stab} section. The
+byte order of the stabs binary data depends on the object file format.
+For ELF, it matches the byte order of the ELF file itself, as determined
+from the @code{EI_DATA} field in the @code{e_ident} member of the ELF
+header. For SOM, it is always big-endian (is this true??? FIXME). For
+COFF, it matches the byte order of the COFF headers. The meaning of the
+fields is the same as for a.out (@pxref{Symbol Table Format}), except
+that the @code{n_strx} field is relative to the strings for the current
+compilation unit (which can be found using the synthetic N_UNDF stab
+described below), rather than the entire string table.
+
+The first stab in the @code{.stab} section for each compilation unit is
+synthetic, generated entirely by the assembler, with no corresponding
+@code{.stab} directive as input to the assembler. This stab contains
+the following fields:
+
+@table @code
+@item n_strx
+Offset in the @code{.stabstr} section to the source filename.
+
+@item n_type
+@code{N_UNDF}.
+
+@item n_other
+Unused field, always zero.
+This may eventually be used to hold overflows from the count in
+the @code{n_desc} field.
+
+@item n_desc
+Count of upcoming symbols, i.e., the number of remaining stabs for this
+source file.
+
+@item n_value
+Size of the string table fragment associated with this source file, in
+bytes.
+@end table
+
+The @code{.stabstr} section always starts with a null byte (so that string
+offsets of zero reference a null string), followed by random length strings,
+each of which is null byte terminated.
+
+The ELF section header for the @code{.stab} section has its
+@code{sh_link} member set to the section number of the @code{.stabstr}
+section, and the @code{.stabstr} section has its ELF section
+header @code{sh_type} member set to @code{SHT_STRTAB} to mark it as a
+string table. SOM and COFF have no way of linking the sections together
+or marking them as string tables.
+
+For COFF, the @code{.stab} and @code{.stabstr} sections may be simply
+concatenated by the linker. GDB then uses the @code{n_desc} fields to
+figure out the extent of the original sections. Similarly, the
+@code{n_value} fields of the header symbols are added together in order
+to get the actual position of the strings in a desired @code{.stabstr}
+section. Although this design obviates any need for the linker to
+relocate or otherwise manipulate @code{.stab} and @code{.stabstr}
+sections, it also requires some care to ensure that the offsets are
+calculated correctly. For instance, if the linker were to pad in
+between the @code{.stabstr} sections before concatenating, then the
+offsets to strings in the middle of the executable's @code{.stabstr}
+section would be wrong.
+
+The GNU linker is able to optimize stabs information by merging
+duplicate strings and removing duplicate header file information
+(@pxref{Include Files}). When some versions of the GNU linker optimize
+stabs in sections, they remove the leading @code{N_UNDF} symbol and
+arranges for all the @code{n_strx} fields to be relative to the start of
+the @code{.stabstr} section.
+
+@node ELF Linker Relocation
+@appendixsec Having the Linker Relocate Stabs in ELF
+
+This section describes some Sun hacks for Stabs in ELF; it does not
+apply to COFF or SOM.
+
+To keep linking fast, you don't want the linker to have to relocate very
+many stabs. Making sure this is done for @code{N_SLINE},
+@code{N_RBRAC}, and @code{N_LBRAC} stabs is the most important thing
+(see the descriptions of those stabs for more information). But Sun's
+stabs in ELF has taken this further, to make all addresses in the
+@code{n_value} field (functions and static variables) relative to the
+source file. For the @code{N_SO} symbol itself, Sun simply omits the
+address. To find the address of each section corresponding to a given
+source file, the compiler puts out symbols giving the address of each
+section for a given source file. Since these are ELF (not stab)
+symbols, the linker relocates them correctly without having to touch the
+stabs section. They are named @code{Bbss.bss} for the bss section,
+@code{Ddata.data} for the data section, and @code{Drodata.rodata} for
+the rodata section. For the text section, there is no such symbol (but
+there should be, see below). For an example of how these symbols work,
+@xref{Stab Section Transformations}. GCC does not provide these symbols;
+it instead relies on the stabs getting relocated. Thus addresses which
+would normally be relative to @code{Bbss.bss}, etc., are already
+relocated. The Sun linker provided with Solaris 2.2 and earlier
+relocates stabs using normal ELF relocation information, as it would do
+for any section. Sun has been threatening to kludge their linker to not
+do this (to speed up linking), even though the correct way to avoid
+having the linker do these relocations is to have the compiler no longer
+output relocatable values. Last I heard they had been talked out of the
+linker kludge. See Sun point patch 101052-01 and Sun bug 1142109. With
+the Sun compiler this affects @samp{S} symbol descriptor stabs
+(@pxref{Statics}) and functions (@pxref{Procedures}). In the latter
+case, to adopt the clean solution (making the value of the stab relative
+to the start of the compilation unit), it would be necessary to invent a
+@code{Ttext.text} symbol, analogous to the @code{Bbss.bss}, etc.,
+symbols. I recommend this rather than using a zero value and getting
+the address from the ELF symbols.
+
+Finding the correct @code{Bbss.bss}, etc., symbol is difficult, because
+the linker simply concatenates the @code{.stab} sections from each
+@file{.o} file without including any information about which part of a
+@code{.stab} section comes from which @file{.o} file. The way GDB does
+this is to look for an ELF @code{STT_FILE} symbol which has the same
+name as the last component of the file name from the @code{N_SO} symbol
+in the stabs (for example, if the file name is @file{../../gdb/main.c},
+it looks for an ELF @code{STT_FILE} symbol named @code{main.c}). This
+loses if different files have the same name (they could be in different
+directories, a library could have been copied from one system to
+another, etc.). It would be much cleaner to have the @code{Bbss.bss}
+symbols in the stabs themselves. Having the linker relocate them there
+is no more work than having the linker relocate ELF symbols, and it
+solves the problem of having to associate the ELF and stab symbols.
+However, no one has yet designed or implemented such a scheme.
+
+@node Symbol Types Index
+@unnumbered Symbol Types Index
+
+@printindex fn
+
+@c TeX can handle the contents at the start but makeinfo 3.12 can not
+@ifinfo
+@contents
+@end ifinfo
+@ifhtml
+@contents
+@end ifhtml
+
+@bye
diff --git a/gdb/doublest.c b/gdb/doublest.c
new file mode 100644
index 00000000000..a4b4b763f7f
--- /dev/null
+++ b/gdb/doublest.c
@@ -0,0 +1,788 @@
+/* Floating point routines for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001
+ 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. */
+
+/* Support for converting target fp numbers into host DOUBLEST format. */
+
+/* XXX - This code should really be in libiberty/floatformat.c,
+ however configuration issues with libiberty made this very
+ difficult to do in the available time. */
+
+#include "defs.h"
+#include "doublest.h"
+#include "floatformat.h"
+#include "gdb_assert.h"
+#include "gdb_string.h"
+#include "gdbtypes.h"
+#include <math.h> /* ldexp */
+
+/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
+ going to bother with trying to muck around with whether it is defined in
+ a system header, what we do if not, etc. */
+#define FLOATFORMAT_CHAR_BIT 8
+
+static unsigned long get_field (unsigned char *,
+ enum floatformat_byteorders,
+ unsigned int, unsigned int, unsigned int);
+
+/* Extract a field which starts at START and is LEN bytes long. DATA and
+ TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
+static unsigned long
+get_field (unsigned char *data, enum floatformat_byteorders order,
+ unsigned int total_len, unsigned int start, unsigned int len)
+{
+ unsigned long result;
+ unsigned int cur_byte;
+ int cur_bitshift;
+
+ /* Start at the least significant part of the field. */
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
+ {
+ /* We start counting from the other end (i.e, from the high bytes
+ rather than the low bytes). As such, we need to be concerned
+ with what happens if bit 0 doesn't start on a byte boundary.
+ I.e, we need to properly handle the case where total_len is
+ not evenly divisible by 8. So we compute ``excess'' which
+ represents the number of bits from the end of our starting
+ byte needed to get to bit 0. */
+ int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);
+ cur_byte = (total_len / FLOATFORMAT_CHAR_BIT)
+ - ((start + len + excess) / FLOATFORMAT_CHAR_BIT);
+ cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT)
+ - FLOATFORMAT_CHAR_BIT;
+ }
+ else
+ {
+ cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
+ cur_bitshift =
+ ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
+ }
+ if (cur_bitshift > -FLOATFORMAT_CHAR_BIT)
+ result = *(data + cur_byte) >> (-cur_bitshift);
+ else
+ result = 0;
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
+ ++cur_byte;
+ else
+ --cur_byte;
+
+ /* Move towards the most significant part of the field. */
+ while (cur_bitshift < len)
+ {
+ result |= (unsigned long)*(data + cur_byte) << cur_bitshift;
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
+ ++cur_byte;
+ else
+ --cur_byte;
+ }
+ if (len < sizeof(result) * FLOATFORMAT_CHAR_BIT)
+ /* Mask out bits which are not part of the field */
+ result &= ((1UL << len) - 1);
+ return result;
+}
+
+/* Convert from FMT to a DOUBLEST.
+ FROM is the address of the extended float.
+ Store the DOUBLEST in *TO. */
+
+static void
+convert_floatformat_to_doublest (const struct floatformat *fmt,
+ const void *from,
+ DOUBLEST *to)
+{
+ unsigned char *ufrom = (unsigned char *) from;
+ DOUBLEST dto;
+ long exponent;
+ unsigned long mant;
+ unsigned int mant_bits, mant_off;
+ int mant_bits_left;
+ int special_exponent; /* It's a NaN, denorm or zero */
+
+ /* If the mantissa bits are not contiguous from one end of the
+ mantissa to the other, we need to make a private copy of the
+ source bytes that is in the right order since the unpacking
+ algorithm assumes that the bits are contiguous.
+
+ Swap the bytes individually rather than accessing them through
+ "long *" since we have no guarantee that they start on a long
+ alignment, and also sizeof(long) for the host could be different
+ than sizeof(long) for the target. FIXME: Assumes sizeof(long)
+ for the target is 4. */
+
+ if (fmt->byteorder == floatformat_littlebyte_bigword)
+ {
+ static unsigned char *newfrom;
+ unsigned char *swapin, *swapout;
+ int longswaps;
+
+ longswaps = fmt->totalsize / FLOATFORMAT_CHAR_BIT;
+ longswaps >>= 3;
+
+ if (newfrom == NULL)
+ {
+ newfrom = (unsigned char *) xmalloc (fmt->totalsize);
+ }
+ swapout = newfrom;
+ swapin = ufrom;
+ ufrom = newfrom;
+ while (longswaps-- > 0)
+ {
+ /* This is ugly, but efficient */
+ *swapout++ = swapin[4];
+ *swapout++ = swapin[5];
+ *swapout++ = swapin[6];
+ *swapout++ = swapin[7];
+ *swapout++ = swapin[0];
+ *swapout++ = swapin[1];
+ *swapout++ = swapin[2];
+ *swapout++ = swapin[3];
+ swapin += 8;
+ }
+ }
+
+ exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
+ fmt->exp_start, fmt->exp_len);
+ /* Note that if exponent indicates a NaN, we can't really do anything useful
+ (not knowing if the host has NaN's, or how to build one). So it will
+ end up as an infinity or something close; that is OK. */
+
+ mant_bits_left = fmt->man_len;
+ mant_off = fmt->man_start;
+ dto = 0.0;
+
+ special_exponent = exponent == 0 || exponent == fmt->exp_nan;
+
+/* Don't bias NaNs. Use minimum exponent for denorms. For simplicity,
+ we don't check for zero as the exponent doesn't matter. */
+ if (!special_exponent)
+ exponent -= fmt->exp_bias;
+ else if (exponent == 0)
+ exponent = 1 - fmt->exp_bias;
+
+ /* Build the result algebraically. Might go infinite, underflow, etc;
+ who cares. */
+
+/* If this format uses a hidden bit, explicitly add it in now. Otherwise,
+ increment the exponent by one to account for the integer bit. */
+
+ if (!special_exponent)
+ {
+ if (fmt->intbit == floatformat_intbit_no)
+ dto = ldexp (1.0, exponent);
+ else
+ exponent++;
+ }
+
+ while (mant_bits_left > 0)
+ {
+ mant_bits = min (mant_bits_left, 32);
+
+ mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
+ mant_off, mant_bits);
+
+ dto += ldexp ((double) mant, exponent - mant_bits);
+ exponent -= mant_bits;
+ mant_off += mant_bits;
+ mant_bits_left -= mant_bits;
+ }
+
+ /* Negate it if negative. */
+ if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
+ dto = -dto;
+ *to = dto;
+}
+
+static void put_field (unsigned char *, enum floatformat_byteorders,
+ unsigned int,
+ unsigned int, unsigned int, unsigned long);
+
+/* Set a field which starts at START and is LEN bytes long. DATA and
+ TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
+static void
+put_field (unsigned char *data, enum floatformat_byteorders order,
+ unsigned int total_len, unsigned int start, unsigned int len,
+ unsigned long stuff_to_put)
+{
+ unsigned int cur_byte;
+ int cur_bitshift;
+
+ /* Start at the least significant part of the field. */
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
+ {
+ int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);
+ cur_byte = (total_len / FLOATFORMAT_CHAR_BIT)
+ - ((start + len + excess) / FLOATFORMAT_CHAR_BIT);
+ cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT)
+ - FLOATFORMAT_CHAR_BIT;
+ }
+ else
+ {
+ cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
+ cur_bitshift =
+ ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
+ }
+ if (cur_bitshift > -FLOATFORMAT_CHAR_BIT)
+ {
+ *(data + cur_byte) &=
+ ~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1)
+ << (-cur_bitshift));
+ *(data + cur_byte) |=
+ (stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
+ }
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
+ ++cur_byte;
+ else
+ --cur_byte;
+
+ /* Move towards the most significant part of the field. */
+ while (cur_bitshift < len)
+ {
+ if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
+ {
+ /* This is the last byte. */
+ *(data + cur_byte) &=
+ ~((1 << (len - cur_bitshift)) - 1);
+ *(data + cur_byte) |= (stuff_to_put >> cur_bitshift);
+ }
+ else
+ *(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
+ & ((1 << FLOATFORMAT_CHAR_BIT) - 1));
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
+ ++cur_byte;
+ else
+ --cur_byte;
+ }
+}
+
+#ifdef HAVE_LONG_DOUBLE
+/* Return the fractional part of VALUE, and put the exponent of VALUE in *EPTR.
+ The range of the returned value is >= 0.5 and < 1.0. This is equivalent to
+ frexp, but operates on the long double data type. */
+
+static long double ldfrexp (long double value, int *eptr);
+
+static long double
+ldfrexp (long double value, int *eptr)
+{
+ long double tmp;
+ int exp;
+
+ /* Unfortunately, there are no portable functions for extracting the exponent
+ of a long double, so we have to do it iteratively by multiplying or dividing
+ by two until the fraction is between 0.5 and 1.0. */
+
+ if (value < 0.0l)
+ value = -value;
+
+ tmp = 1.0l;
+ exp = 0;
+
+ if (value >= tmp) /* Value >= 1.0 */
+ while (value >= tmp)
+ {
+ tmp *= 2.0l;
+ exp++;
+ }
+ else if (value != 0.0l) /* Value < 1.0 and > 0.0 */
+ {
+ while (value < tmp)
+ {
+ tmp /= 2.0l;
+ exp--;
+ }
+ tmp *= 2.0l;
+ exp++;
+ }
+
+ *eptr = exp;
+ return value / tmp;
+}
+#endif /* HAVE_LONG_DOUBLE */
+
+
+/* The converse: convert the DOUBLEST *FROM to an extended float
+ and store where TO points. Neither FROM nor TO have any alignment
+ restrictions. */
+
+static void
+convert_doublest_to_floatformat (CONST struct floatformat *fmt,
+ const DOUBLEST *from,
+ void *to)
+{
+ DOUBLEST dfrom;
+ int exponent;
+ DOUBLEST mant;
+ unsigned int mant_bits, mant_off;
+ int mant_bits_left;
+ unsigned char *uto = (unsigned char *) to;
+
+ memcpy (&dfrom, from, sizeof (dfrom));
+ memset (uto, 0, (fmt->totalsize + FLOATFORMAT_CHAR_BIT - 1)
+ / FLOATFORMAT_CHAR_BIT);
+ if (dfrom == 0)
+ return; /* Result is zero */
+ if (dfrom != dfrom) /* Result is NaN */
+ {
+ /* From is NaN */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
+ fmt->exp_len, fmt->exp_nan);
+ /* Be sure it's not infinity, but NaN value is irrel */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
+ 32, 1);
+ return;
+ }
+
+ /* If negative, set the sign bit. */
+ if (dfrom < 0)
+ {
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
+ dfrom = -dfrom;
+ }
+
+ if (dfrom + dfrom == dfrom && dfrom != 0.0) /* Result is Infinity */
+ {
+ /* Infinity exponent is same as NaN's. */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
+ fmt->exp_len, fmt->exp_nan);
+ /* Infinity mantissa is all zeroes. */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
+ fmt->man_len, 0);
+ return;
+ }
+
+#ifdef HAVE_LONG_DOUBLE
+ mant = ldfrexp (dfrom, &exponent);
+#else
+ mant = frexp (dfrom, &exponent);
+#endif
+
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, fmt->exp_len,
+ exponent + fmt->exp_bias - 1);
+
+ mant_bits_left = fmt->man_len;
+ mant_off = fmt->man_start;
+ while (mant_bits_left > 0)
+ {
+ unsigned long mant_long;
+ mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
+
+ mant *= 4294967296.0;
+ mant_long = ((unsigned long) mant) & 0xffffffffL;
+ mant -= mant_long;
+
+ /* If the integer bit is implicit, then we need to discard it.
+ If we are discarding a zero, we should be (but are not) creating
+ a denormalized number which means adjusting the exponent
+ (I think). */
+ if (mant_bits_left == fmt->man_len
+ && fmt->intbit == floatformat_intbit_no)
+ {
+ mant_long <<= 1;
+ mant_long &= 0xffffffffL;
+ mant_bits -= 1;
+ }
+
+ if (mant_bits < 32)
+ {
+ /* The bits we want are in the most significant MANT_BITS bits of
+ mant_long. Move them to the least significant. */
+ mant_long >>= 32 - mant_bits;
+ }
+
+ put_field (uto, fmt->byteorder, fmt->totalsize,
+ mant_off, mant_bits, mant_long);
+ mant_off += mant_bits;
+ mant_bits_left -= mant_bits;
+ }
+ if (fmt->byteorder == floatformat_littlebyte_bigword)
+ {
+ int count;
+ unsigned char *swaplow = uto;
+ unsigned char *swaphigh = uto + 4;
+ unsigned char tmp;
+
+ for (count = 0; count < 4; count++)
+ {
+ tmp = *swaplow;
+ *swaplow++ = *swaphigh;
+ *swaphigh++ = tmp;
+ }
+ }
+}
+
+/* Check if VAL (which is assumed to be a floating point number whose
+ format is described by FMT) is negative. */
+
+int
+floatformat_is_negative (const struct floatformat *fmt, char *val)
+{
+ unsigned char *uval = (unsigned char *) val;
+ gdb_assert (fmt != NULL);
+ return get_field (uval, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1);
+}
+
+/* Check if VAL is "not a number" (NaN) for FMT. */
+
+int
+floatformat_is_nan (const struct floatformat *fmt, char *val)
+{
+ unsigned char *uval = (unsigned char *) val;
+ long exponent;
+ unsigned long mant;
+ unsigned int mant_bits, mant_off;
+ int mant_bits_left;
+
+ gdb_assert (fmt != NULL);
+
+ if (! fmt->exp_nan)
+ return 0;
+
+ exponent = get_field (uval, fmt->byteorder, fmt->totalsize,
+ fmt->exp_start, fmt->exp_len);
+
+ if (exponent != fmt->exp_nan)
+ return 0;
+
+ mant_bits_left = fmt->man_len;
+ mant_off = fmt->man_start;
+
+ while (mant_bits_left > 0)
+ {
+ mant_bits = min (mant_bits_left, 32);
+
+ mant = get_field (uval, fmt->byteorder, fmt->totalsize,
+ mant_off, mant_bits);
+
+ /* If there is an explicit integer bit, mask it off. */
+ if (mant_off == fmt->man_start
+ && fmt->intbit == floatformat_intbit_yes)
+ mant &= ~(1 << (mant_bits - 1));
+
+ if (mant)
+ return 1;
+
+ mant_off += mant_bits;
+ mant_bits_left -= mant_bits;
+ }
+
+ return 0;
+}
+
+/* Convert the mantissa of VAL (which is assumed to be a floating
+ point number whose format is described by FMT) into a hexadecimal
+ and store it in a static string. Return a pointer to that string. */
+
+char *
+floatformat_mantissa (const struct floatformat *fmt, char *val)
+{
+ unsigned char *uval = (unsigned char *) val;
+ unsigned long mant;
+ unsigned int mant_bits, mant_off;
+ int mant_bits_left;
+ static char res[50];
+ char buf[9];
+
+ /* Make sure we have enough room to store the mantissa. */
+ gdb_assert (fmt != NULL);
+ gdb_assert (sizeof res > ((fmt->man_len + 7) / 8) * 2);
+
+ mant_off = fmt->man_start;
+ mant_bits_left = fmt->man_len;
+ mant_bits = (mant_bits_left % 32) > 0 ? mant_bits_left % 32 : 32;
+
+ mant = get_field (uval, fmt->byteorder, fmt->totalsize,
+ mant_off, mant_bits);
+
+ sprintf (res, "%lx", mant);
+
+ mant_off += mant_bits;
+ mant_bits_left -= mant_bits;
+
+ while (mant_bits_left > 0)
+ {
+ mant = get_field (uval, fmt->byteorder, fmt->totalsize,
+ mant_off, 32);
+
+ sprintf (buf, "%08lx", mant);
+ strcat (res, buf);
+
+ mant_off += 32;
+ mant_bits_left -= 32;
+ }
+
+ return res;
+}
+
+
+/* Convert TO/FROM target to the hosts DOUBLEST floating-point format.
+
+ If the host and target formats agree, we just copy the raw data
+ into the appropriate type of variable and return, letting the host
+ increase precision as necessary. Otherwise, we call the conversion
+ routine and let it do the dirty work. */
+
+#ifndef HOST_FLOAT_FORMAT
+#define HOST_FLOAT_FORMAT 0
+#endif
+#ifndef HOST_DOUBLE_FORMAT
+#define HOST_DOUBLE_FORMAT 0
+#endif
+#ifndef HOST_LONG_DOUBLE_FORMAT
+#define HOST_LONG_DOUBLE_FORMAT 0
+#endif
+
+static const struct floatformat *host_float_format = HOST_FLOAT_FORMAT;
+static const struct floatformat *host_double_format = HOST_DOUBLE_FORMAT;
+static const struct floatformat *host_long_double_format = HOST_LONG_DOUBLE_FORMAT;
+
+void
+floatformat_to_doublest (const struct floatformat *fmt,
+ const void *in, DOUBLEST *out)
+{
+ gdb_assert (fmt != NULL);
+ if (fmt == host_float_format)
+ {
+ float val;
+ memcpy (&val, in, sizeof (val));
+ *out = val;
+ }
+ else if (fmt == host_double_format)
+ {
+ double val;
+ memcpy (&val, in, sizeof (val));
+ *out = val;
+ }
+ else if (fmt == host_long_double_format)
+ {
+ long double val;
+ memcpy (&val, in, sizeof (val));
+ *out = val;
+ }
+ else
+ convert_floatformat_to_doublest (fmt, in, out);
+}
+
+void
+floatformat_from_doublest (const struct floatformat *fmt,
+ const DOUBLEST *in, void *out)
+{
+ gdb_assert (fmt != NULL);
+ if (fmt == host_float_format)
+ {
+ float val = *in;
+ memcpy (out, &val, sizeof (val));
+ }
+ else if (fmt == host_double_format)
+ {
+ double val = *in;
+ memcpy (out, &val, sizeof (val));
+ }
+ else if (fmt == host_long_double_format)
+ {
+ long double val = *in;
+ memcpy (out, &val, sizeof (val));
+ }
+ else
+ convert_doublest_to_floatformat (fmt, in, out);
+}
+
+
+/* Return a floating-point format for a floating-point variable of
+ length LEN. Return NULL, if no suitable floating-point format
+ could be found.
+
+ We need this functionality since information about the
+ floating-point format of a type is not always available to GDB; the
+ debug information typically only tells us the size of a
+ floating-point type.
+
+ FIXME: kettenis/2001-10-28: In many places, particularly in
+ target-dependent code, the format of floating-point types is known,
+ but not passed on by GDB. This should be fixed. */
+
+const struct floatformat *
+floatformat_from_length (int len)
+{
+ if (len * TARGET_CHAR_BIT == TARGET_FLOAT_BIT)
+ return TARGET_FLOAT_FORMAT;
+ else if (len * TARGET_CHAR_BIT == TARGET_DOUBLE_BIT)
+ return TARGET_DOUBLE_FORMAT;
+ else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT)
+ return TARGET_LONG_DOUBLE_FORMAT;
+
+ return NULL;
+}
+
+const struct floatformat *
+floatformat_from_type (const struct type *type)
+{
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
+ if (TYPE_FLOATFORMAT (type) != NULL)
+ return TYPE_FLOATFORMAT (type);
+ else
+ return floatformat_from_length (TYPE_LENGTH (type));
+}
+
+/* If the host doesn't define NAN, use zero instead. */
+#ifndef NAN
+#define NAN 0.0
+#endif
+
+/* Extract a floating-point number of length LEN from a target-order
+ byte-stream at ADDR. Returns the value as type DOUBLEST. */
+
+DOUBLEST
+extract_floating (const void *addr, int len)
+{
+ const struct floatformat *fmt = floatformat_from_length (len);
+ DOUBLEST val;
+
+ if (fmt == NULL)
+ {
+ warning ("Can't store a floating-point number of %d bytes.", len);
+ return NAN;
+ }
+
+ floatformat_to_doublest (fmt, addr, &val);
+ return val;
+}
+
+/* Store VAL as a floating-point number of length LEN to a
+ target-order byte-stream at ADDR. */
+
+void
+store_floating (void *addr, int len, DOUBLEST val)
+{
+ const struct floatformat *fmt = floatformat_from_length (len);
+
+ if (fmt == NULL)
+ {
+ warning ("Can't store a floating-point number of %d bytes.", len);
+ memset (addr, 0, len);
+ }
+
+ floatformat_from_doublest (fmt, &val, addr);
+}
+
+/* Extract a floating-point number of type TYPE from a target-order
+ byte-stream at ADDR. Returns the value as type DOUBLEST. */
+
+DOUBLEST
+extract_typed_floating (const void *addr, const struct type *type)
+{
+ DOUBLEST retval;
+
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
+
+ if (TYPE_FLOATFORMAT (type) == NULL)
+ return extract_floating (addr, TYPE_LENGTH (type));
+
+ floatformat_to_doublest (TYPE_FLOATFORMAT (type), addr, &retval);
+ return retval;
+}
+
+/* Store VAL as a floating-point number of type TYPE to a target-order
+ byte-stream at ADDR. */
+
+void
+store_typed_floating (void *addr, const struct type *type, DOUBLEST val)
+{
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
+
+ /* FIXME: kettenis/2001-10-28: It is debatable whether we should
+ zero out any remaining bytes in the target buffer when TYPE is
+ longer than the actual underlying floating-point format. Perhaps
+ we should store a fixed bitpattern in those remaining bytes,
+ instead of zero, or perhaps we shouldn't touch those remaining
+ bytes at all.
+
+ NOTE: cagney/2001-10-28: With the way things currently work, it
+ isn't a good idea to leave the end bits undefined. This is
+ because GDB writes out the entire sizeof(<floating>) bits of the
+ floating-point type even though the value might only be stored
+ in, and the target processor may only refer to, the first N <
+ TYPE_LENGTH (type) bits. If the end of the buffer wasn't
+ initialized, GDB would write undefined data to the target. An
+ errant program, refering to that undefined data, would then
+ become non-deterministic.
+
+ See also the function convert_typed_floating below. */
+ memset (addr, 0, TYPE_LENGTH (type));
+
+ if (TYPE_FLOATFORMAT (type) == NULL)
+ store_floating (addr, TYPE_LENGTH (type), val);
+ else
+ floatformat_from_doublest (TYPE_FLOATFORMAT (type), &val, addr);
+}
+
+/* Convert a floating-point number of type FROM_TYPE from a
+ target-order byte-stream at FROM to a floating-point number of type
+ TO_TYPE, and store it to a target-order byte-stream at TO. */
+
+void
+convert_typed_floating (const void *from, const struct type *from_type,
+ void *to, const struct type *to_type)
+{
+ const struct floatformat *from_fmt = floatformat_from_type (from_type);
+ const struct floatformat *to_fmt = floatformat_from_type (to_type);
+
+ gdb_assert (TYPE_CODE (from_type) == TYPE_CODE_FLT);
+ gdb_assert (TYPE_CODE (to_type) == TYPE_CODE_FLT);
+
+ if (from_fmt == NULL || to_fmt == NULL)
+ {
+ /* If we don't know the floating-point format of FROM_TYPE or
+ TO_TYPE, there's not much we can do. We might make the
+ assumption that if the length of FROM_TYPE and TO_TYPE match,
+ their floating-point format would match too, but that
+ assumption might be wrong on targets that support
+ floating-point types that only differ in endianness for
+ example. So we warn instead, and zero out the target buffer. */
+ warning ("Can't convert floating-point number to desired type.");
+ memset (to, 0, TYPE_LENGTH (to_type));
+ }
+ else if (from_fmt == to_fmt)
+ {
+ /* We're in business. The floating-point format of FROM_TYPE
+ and TO_TYPE match. However, even though the floating-point
+ format matches, the length of the type might still be
+ different. Make sure we don't overrun any buffers. See
+ comment in store_typed_floating for a discussion about
+ zeroing out remaining bytes in the target buffer. */
+ memset (to, 0, TYPE_LENGTH (to_type));
+ memcpy (to, from, min (TYPE_LENGTH (from_type), TYPE_LENGTH (to_type)));
+ }
+ else
+ {
+ /* The floating-point types don't match. The best we can do
+ (aport from simulating the target FPU) is converting to the
+ widest floating-point type supported by the host, and then
+ again to the desired type. */
+ DOUBLEST d;
+
+ floatformat_to_doublest (from_fmt, from, &d);
+ floatformat_from_doublest (to_fmt, &d, to);
+ }
+}
diff --git a/gdb/doublest.h b/gdb/doublest.h
new file mode 100644
index 00000000000..920d7026db4
--- /dev/null
+++ b/gdb/doublest.h
@@ -0,0 +1,83 @@
+/* Floating point definitions for GDB.
+ Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001
+ 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. */
+
+#ifndef DOUBLEST_H
+#define DOUBLEST_H
+
+/* Setup definitions for host and target floating point formats. We need to
+ consider the format for `float', `double', and `long double' for both target
+ and host. We need to do this so that we know what kind of conversions need
+ to be done when converting target numbers to and from the hosts DOUBLEST
+ data type. */
+
+/* This is used to indicate that we don't know the format of the floating point
+ number. Typically, this is useful for native ports, where the actual format
+ is irrelevant, since no conversions will be taking place. */
+
+#include "floatformat.h" /* For struct floatformat */
+
+/* Use `long double' if the host compiler supports it. (Note that this is not
+ necessarily any longer than `double'. On SunOS/gcc, it's the same as
+ double.) This is necessary because GDB internally converts all floating
+ point values to the widest type supported by the host.
+
+ There are problems however, when the target `long double' is longer than the
+ host's `long double'. In general, we'll probably reduce the precision of
+ any such values and print a warning. */
+
+#ifdef HAVE_LONG_DOUBLE
+typedef long double DOUBLEST;
+#else
+typedef double DOUBLEST;
+#endif
+
+extern void floatformat_to_doublest (const struct floatformat *,
+ const void *in, DOUBLEST *out);
+extern void floatformat_from_doublest (const struct floatformat *,
+ const DOUBLEST *in, void *out);
+
+extern int floatformat_is_negative (const struct floatformat *, char *);
+extern int floatformat_is_nan (const struct floatformat *, char *);
+extern char *floatformat_mantissa (const struct floatformat *, char *);
+
+/* These two functions are deprecated in favour of
+ extract_typed_floating and store_typed_floating. See comments in
+ 'doublest.c' for details. */
+
+extern DOUBLEST extract_floating (const void *addr, int len);
+extern void store_floating (void *addr, int len, DOUBLEST val);
+
+/* Given TYPE, return its floatformat. TYPE_FLOATFORMAT() may return
+ NULL. type_floatformat() detects that and returns a floatformat
+ based on the type size when FLOATFORMAT is NULL. */
+
+const struct floatformat *floatformat_from_type (const struct type *type);
+
+extern DOUBLEST extract_typed_floating (const void *addr,
+ const struct type *type);
+extern void store_typed_floating (void *addr, const struct type *type,
+ DOUBLEST val);
+extern void convert_typed_floating (const void *from,
+ const struct type *from_type,
+ void *to, const struct type *to_type);
+
+#endif
diff --git a/gdb/dpx2-nat.c b/gdb/dpx2-nat.c
new file mode 100644
index 00000000000..04018db8552
--- /dev/null
+++ b/gdb/dpx2-nat.c
@@ -0,0 +1,83 @@
+/* DPX2 host interface.
+ Copyright 1988, 1989, 1991, 1993, 1995, 2000
+ 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 "defs.h"
+#include "gdbcore.h"
+
+#include "gdb_string.h"
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/user.h>
+#include <sys/reg.h>
+#include <sys/utsname.h>
+
+
+/* this table must line up with REGISTER_NAMES in tm-68k.h */
+/* symbols like 'A0' come from <sys/reg.h> */
+static int regmap[] =
+{
+ R0, R1, R2, R3, R4, R5, R6, R7,
+ A0, A1, A2, A3, A4, A5, A6, SP,
+ PS, PC,
+ FP0, FP1, FP2, FP3, FP4, FP5, FP6, FP7,
+ FP_CR, FP_SR, FP_IAR
+};
+
+/* blockend is the value of u.u_ar0, and points to the
+ * place where D0 is stored
+ */
+
+int
+dpx2_register_u_addr (int blockend, int regnum)
+{
+ if (regnum < FP0_REGNUM)
+ return (blockend + 4 * regmap[regnum]);
+ else
+ return (int) &(((struct user *) 0)->u_fpstate[regmap[regnum]]);
+}
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values.
+ Unfortunately this is not provided in the system header files.
+ To make matters worse, this value also differs between
+ the dpx/2200 and dpx/2300 models and nlist is not available on the dpx2.
+ We use utsname() to decide on which model we are running.
+ FIXME: This breaks cross examination of core files (it would not be hard
+ to check whether u.u_ar0 is between 0x7fff5000 and 0x7fffc000 and if so
+ use 0x7fff5000 and if not use 0x7fffc000. FIXME). */
+
+#define KERNEL_U_ADDR_200 0x7fff5000
+#define KERNEL_U_ADDR_300 0x7fffc000
+
+CORE_ADDR kernel_u_addr;
+
+void
+_initialize_dpx2_nat (void)
+{
+ struct utsname uts;
+
+ if (uname (&uts) == 0 && strcmp (uts.machine, "DPX/2200") == 0)
+ kernel_u_addr = KERNEL_U_ADDR_200;
+ else
+ kernel_u_addr = KERNEL_U_ADDR_300;
+}
diff --git a/gdb/dsrec.c b/gdb/dsrec.c
new file mode 100644
index 00000000000..5f2c2d703ce
--- /dev/null
+++ b/gdb/dsrec.c
@@ -0,0 +1,311 @@
+/* S-record download support for GDB, the GNU debugger.
+ Copyright 1995, 1996, 1997, 1999, 2000, 2001
+ 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 "defs.h"
+#include "serial.h"
+#include "srec.h"
+#include <time.h>
+
+extern void report_transfer_performance (unsigned long, time_t, time_t);
+
+extern int remote_debug;
+
+static int make_srec (char *srec, CORE_ADDR targ_addr, bfd * abfd,
+ asection * sect, int sectoff, int *maxrecsize,
+ int flags);
+
+/* Download an executable by converting it to S records. DESC is a
+ `struct serial *' to send the data to. FILE is the name of the
+ file to be loaded. LOAD_OFFSET is the offset into memory to load
+ data into. It is usually specified by the user and is useful with
+ the a.out file format. MAXRECSIZE is the length in chars of the
+ largest S-record the host can accomodate. This is measured from
+ the starting `S' to the last char of the checksum. FLAGS is
+ various random flags, and HASHMARK is non-zero to cause a `#' to be
+ printed out for each record loaded. WAITACK, if non-NULL, is a
+ function that waits for an acknowledgement after each S-record, and
+ returns non-zero if the ack is read correctly. */
+
+void
+load_srec (struct serial *desc, const char *file, bfd_vma load_offset,
+ int maxrecsize,
+ int flags, int hashmark, int (*waitack) (void))
+{
+ bfd *abfd;
+ asection *s;
+ char *srec;
+ int i;
+ int reclen;
+ time_t start_time, end_time;
+ unsigned long data_count = 0;
+
+ srec = (char *) alloca (maxrecsize + 1);
+
+ abfd = bfd_openr (file, 0);
+ if (!abfd)
+ {
+ printf_filtered ("Unable to open file %s\n", file);
+ return;
+ }
+
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ {
+ printf_filtered ("File is not an object file\n");
+ return;
+ }
+
+ start_time = time (NULL);
+
+ /* Write a type 0 header record. no data for a type 0, and there
+ is no data, so len is 0. */
+
+ reclen = maxrecsize;
+ make_srec (srec, 0, NULL, (asection *) 1, 0, &reclen, flags);
+ if (remote_debug)
+ {
+ srec[reclen] = '\0';
+ puts_debug ("sent -->", srec, "<--");
+ }
+ serial_write (desc, srec, reclen);
+
+ for (s = abfd->sections; s; s = s->next)
+ if (s->flags & SEC_LOAD)
+ {
+ int numbytes;
+ bfd_vma addr = bfd_get_section_vma (abfd, s) + load_offset;
+ bfd_size_type size = bfd_get_section_size_before_reloc (s);
+ char *section_name = (char *) bfd_get_section_name (abfd, s);
+ /* Both GDB and BFD have mechanisms for printing addresses.
+ In the below, GDB's is used so that the address is
+ consistent with the rest of GDB. BFD's printf_vma() could
+ have also been used. cagney 1999-09-01 */
+ printf_filtered ("%s\t: 0x%s .. 0x%s ",
+ section_name,
+ paddr (addr),
+ paddr (addr + size));
+ gdb_flush (gdb_stdout);
+
+ data_count += size;
+
+ for (i = 0; i < size; i += numbytes)
+ {
+ reclen = maxrecsize;
+ numbytes = make_srec (srec, (CORE_ADDR) (addr + i), abfd, s,
+ i, &reclen, flags);
+
+ if (remote_debug)
+ {
+ srec[reclen] = '\0';
+ puts_debug ("sent -->", srec, "<--");
+ }
+
+ /* Repeatedly send the S-record until a good
+ acknowledgement is sent back. */
+ do
+ {
+ serial_write (desc, srec, reclen);
+ if (ui_load_progress_hook)
+ if (ui_load_progress_hook (section_name, (unsigned long) i))
+ error ("Canceled the download");
+ }
+ while (waitack != NULL && !waitack ());
+
+ if (hashmark)
+ {
+ putchar_unfiltered ('#');
+ gdb_flush (gdb_stdout);
+ }
+ } /* Per-packet (or S-record) loop */
+
+ if (ui_load_progress_hook)
+ if (ui_load_progress_hook (section_name, (unsigned long) i))
+ error ("Canceled the download");
+ putchar_unfiltered ('\n');
+ }
+
+ if (hashmark)
+ putchar_unfiltered ('\n');
+
+ end_time = time (NULL);
+
+ /* Write a terminator record. */
+
+ reclen = maxrecsize;
+ make_srec (srec, abfd->start_address, NULL, NULL, 0, &reclen, flags);
+
+ if (remote_debug)
+ {
+ srec[reclen] = '\0';
+ puts_debug ("sent -->", srec, "<--");
+ }
+
+ serial_write (desc, srec, reclen);
+
+ /* Some monitors need these to wake up properly. (Which ones? -sts) */
+ serial_write (desc, "\r\r", 2);
+ if (remote_debug)
+ puts_debug ("sent -->", "\r\r", "<---");
+
+ serial_flush_input (desc);
+
+ report_transfer_performance (data_count, start_time, end_time);
+}
+
+/*
+ * make_srec -- make an srecord. This writes each line, one at a
+ * time, each with it's own header and trailer line.
+ * An srecord looks like this:
+ *
+ * byte count-+ address
+ * start ---+ | | data +- checksum
+ * | | | |
+ * S01000006F6B692D746573742E73726563E4
+ * S315000448600000000000000000FC00005900000000E9
+ * S31A0004000023C1400037DE00F023604000377B009020825000348D
+ * S30B0004485A0000000000004E
+ * S70500040000F6
+ *
+ * S<type><length><address><data><checksum>
+ *
+ * Where
+ * - length
+ * is the number of bytes following upto the checksum. Note that
+ * this is not the number of chars following, since it takes two
+ * chars to represent a byte.
+ * - type
+ * is one of:
+ * 0) header record
+ * 1) two byte address data record
+ * 2) three byte address data record
+ * 3) four byte address data record
+ * 7) four byte address termination record
+ * 8) three byte address termination record
+ * 9) two byte address termination record
+ *
+ * - address
+ * is the start address of the data following, or in the case of
+ * a termination record, the start address of the image
+ * - data
+ * is the data.
+ * - checksum
+ * is the sum of all the raw byte data in the record, from the length
+ * upwards, modulo 256 and subtracted from 255.
+ *
+ * This routine returns the length of the S-record.
+ *
+ */
+
+static int
+make_srec (char *srec, CORE_ADDR targ_addr, bfd *abfd, asection *sect,
+ int sectoff, int *maxrecsize, int flags)
+{
+ unsigned char checksum;
+ int tmp;
+ const static char hextab[] = "0123456789ABCDEF";
+ const static char data_code_table[] = "123";
+ const static char term_code_table[] = "987";
+ const static char header_code_table[] = "000";
+ const static char *formats[] =
+ {"S%c%02X%04X",
+ "S%c%02X%06X",
+ "S%c%02X%08X"};
+ char const *code_table;
+ int addr_size;
+ int payload_size;
+ char *binbuf;
+ char *p;
+
+ if (sect)
+ {
+ tmp = flags; /* Data or header record */
+ code_table = abfd ? data_code_table : header_code_table;
+ binbuf = alloca (*maxrecsize / 2);
+ }
+ else
+ {
+ tmp = flags >> SREC_TERM_SHIFT; /* Term record */
+ code_table = term_code_table;
+ binbuf = NULL;
+ }
+
+ if ((tmp & SREC_2_BYTE_ADDR) && (targ_addr <= 0xffff))
+ addr_size = 2;
+ else if ((tmp & SREC_3_BYTE_ADDR) && (targ_addr <= 0xffffff))
+ addr_size = 3;
+ else if (tmp & SREC_4_BYTE_ADDR)
+ addr_size = 4;
+ else
+ internal_error (__FILE__, __LINE__,
+ "make_srec: Bad address (0x%s), or bad flags (0x%x).",
+ paddr (targ_addr), flags);
+
+ /* Now that we know the address size, we can figure out how much
+ data this record can hold. */
+
+ if (sect && abfd)
+ {
+ payload_size = (*maxrecsize - (1 + 1 + 2 + addr_size * 2 + 2)) / 2;
+ payload_size = min (payload_size, sect->_raw_size - sectoff);
+
+ bfd_get_section_contents (abfd, sect, binbuf, sectoff, payload_size);
+ }
+ else
+ payload_size = 0; /* Term or header packets have no payload */
+
+ /* Output the header. */
+
+ sprintf (srec, formats[addr_size - 2], code_table[addr_size - 2],
+ addr_size + payload_size + 1, (int) targ_addr);
+
+ /* Note that the checksum is calculated on the raw data, not the
+ hexified data. It includes the length, address and the data
+ portions of the packet. */
+
+ checksum = 0;
+
+ checksum += (payload_size + addr_size + 1 /* Packet length */
+ + (targ_addr & 0xff) /* Address... */
+ + ((targ_addr >> 8) & 0xff)
+ + ((targ_addr >> 16) & 0xff)
+ + ((targ_addr >> 24) & 0xff));
+
+ p = srec + 1 + 1 + 2 + addr_size * 2;
+
+ /* Build the Srecord. */
+ for (tmp = 0; tmp < payload_size; tmp++)
+ {
+ unsigned char k;
+
+ k = binbuf[tmp];
+ *p++ = hextab[k >> 4];
+ *p++ = hextab[k & 0xf];
+ checksum += k;
+ }
+
+ checksum = ~checksum;
+
+ *p++ = hextab[checksum >> 4];
+ *p++ = hextab[checksum & 0xf];
+ *p++ = '\r';
+
+ *maxrecsize = p - srec;
+ return payload_size;
+}
diff --git a/gdb/dst.h b/gdb/dst.h
new file mode 100644
index 00000000000..b72c58c9653
--- /dev/null
+++ b/gdb/dst.h
@@ -0,0 +1,1671 @@
+/* <apollo/dst.h> */
+/* Apollo object module DST (debug symbol table) description */
+
+#ifndef apollo_dst_h
+#define apollo_dst_h
+
+#if defined(apollo) && !defined(__GNUC__)
+#define ALIGNED1 __attribute( (aligned(1)) )
+#else
+/* Remove attribute directives from non-Apollo code: */
+#define ALIGNED1 /* nil */
+#endif
+
+
+
+/* Identification of this version of the debug symbol table. Producers of the
+ debug symbol table must write these values into the version number field of
+ the compilation unit record in .blocks .
+ */
+#define dst_version_major 1
+#define dst_version_minor 3
+
+
+/*
+ ** Enumeration of debug record types appearing in .blocks and .symbols ...
+ */
+typedef enum
+ {
+ dst_typ_pad, /* 0 */
+ dst_typ_comp_unit, /* 1 */
+ dst_typ_section_tab, /* 2 */
+ dst_typ_file_tab, /* 3 */
+ dst_typ_block, /* 4 */
+ dst_typ_5,
+ dst_typ_var,
+ dst_typ_pointer, /* 7 */
+ dst_typ_array, /* 8 */
+ dst_typ_subrange, /* 9 */
+ dst_typ_set, /* 10 */
+ dst_typ_implicit_enum, /* 11 */
+ dst_typ_explicit_enum, /* 12 */
+ dst_typ_short_rec, /* 13 */
+ dst_typ_old_record,
+ dst_typ_short_union, /* 15 */
+ dst_typ_old_union,
+ dst_typ_file, /* 17 */
+ dst_typ_offset, /* 18 */
+ dst_typ_alias, /* 19 */
+ dst_typ_signature, /* 20 */
+ dst_typ_21,
+ dst_typ_old_label, /* 22 */
+ dst_typ_scope, /* 23 */
+ dst_typ_end_scope, /* 24 */
+ dst_typ_25,
+ dst_typ_26,
+ dst_typ_string_tab, /* 27 */
+ dst_typ_global_name_tab, /* 28 */
+ dst_typ_forward, /* 29 */
+ dst_typ_aux_size, /* 30 */
+ dst_typ_aux_align, /* 31 */
+ dst_typ_aux_field_size, /* 32 */
+ dst_typ_aux_field_off, /* 33 */
+ dst_typ_aux_field_align, /* 34 */
+ dst_typ_aux_qual, /* 35 */
+ dst_typ_aux_var_bound, /* 36 */
+ dst_typ_extension, /* 37 */
+ dst_typ_string, /* 38 */
+ dst_typ_old_entry,
+ dst_typ_const, /* 40 */
+ dst_typ_reference, /* 41 */
+ dst_typ_record, /* 42 */
+ dst_typ_union, /* 43 */
+ dst_typ_aux_type_deriv, /* 44 */
+ dst_typ_locpool, /* 45 */
+ dst_typ_variable, /* 46 */
+ dst_typ_label, /* 47 */
+ dst_typ_entry, /* 48 */
+ dst_typ_aux_lifetime, /* 49 */
+ dst_typ_aux_ptr_base, /* 50 */
+ dst_typ_aux_src_range, /* 51 */
+ dst_typ_aux_reg_val, /* 52 */
+ dst_typ_aux_unit_names, /* 53 */
+ dst_typ_aux_sect_info, /* 54 */
+ dst_typ_END_OF_ENUM
+ }
+dst_rec_type_t;
+
+
+/*
+ ** Dummy bounds for variably dimensioned arrays:
+ */
+#define dst_dummy_array_size 100
+
+
+/*
+ ** Reference to another item in the symbol table.
+ **
+ ** The value of a dst_rel_offset_t is the relative offset from the start of the
+ ** referencing record to the start of the referenced record, string, etc.
+ **
+ ** The value of a NIL dst_rel_offset_t is zero.
+ */
+
+typedef long dst_rel_offset_t ALIGNED1;
+
+
+/* FIXME: Here and many places we make assumptions about sizes of host
+ data types, structure layout, etc. Only needs to be fixed if we care
+ about cross-debugging, though. */
+
+/*
+ ** Section-relative reference.
+ **
+ ** The section index field is an index into the local compilation unit's
+ ** section table (see dst_rec_section_tab_t)--NOT into the object module
+ ** section table!
+ **
+ ** The sect_offset field is the offset in bytes into the section.
+ **
+ ** A NIL dst_sect_ref_t has a sect_index field of zero. Indexes originate
+ ** at one.
+ */
+
+typedef struct
+ {
+ unsigned short sect_index;
+ unsigned long sect_offset ALIGNED1;
+ }
+dst_sect_ref_t;
+
+#define dst_sect_index_nil 0
+#define dst_sect_index_origin 1
+
+
+/*
+ ** Source location descriptor.
+ **
+ ** The file_index field is an index into the local compilation unit's
+ ** file table (see dst_rec_file_tab_t).
+ **
+ ** A NIL dst_src_loc_t has a file_index field of zero. Indexes originate
+ ** at one.
+ */
+
+typedef struct
+ {
+ boolean reserved:1; /* reserved for future use */
+ int file_index:11; /* index into .blocks source file list */
+ int line_number:20; /* source line number */
+ }
+dst_src_loc_t;
+
+#define dst_file_index_nil 0
+#define dst_file_index_origin 1
+
+
+/*
+ ** Standard (primitive) type codes.
+ */
+
+typedef enum
+ {
+ dst_non_std_type,
+ dst_int8_type, /* 8 bit integer */
+ dst_int16_type, /* 16 bit integer */
+ dst_int32_type, /* 32 bit integer */
+ dst_uint8_type, /* 8 bit unsigned integer */
+ dst_uint16_type, /* 16 bit unsigned integer */
+ dst_uint32_type, /* 32 bit unsigned integer */
+ dst_real32_type, /* single precision ieee floatining point */
+ dst_real64_type, /* double precision ieee floatining point */
+ dst_complex_type, /* single precision complex */
+ dst_dcomplex_type, /* double precision complex */
+ dst_bool8_type, /* boolean =logical*1 */
+ dst_bool16_type, /* boolean =logical*2 */
+ dst_bool32_type, /* boolean =logical*4 */
+ dst_char_type, /* 8 bit ascii character */
+ dst_string_type, /* string of 8 bit ascii characters */
+ dst_ptr_type, /* univ_pointer */
+ dst_set_type, /* generic 256 bit set */
+ dst_proc_type, /* generic procedure (signature not specified) */
+ dst_func_type, /* generic function (signature not specified) */
+ dst_void_type, /* c void type */
+ dst_uchar_type, /* c unsigned char */
+ dst_std_type_END_OF_ENUM
+ }
+dst_std_type_t;
+
+
+/*
+ ** General data type descriptor
+ **
+ ** If the user_defined_type bit is clear, then the type is a standard type, and
+ ** the remaining bits contain the dst_std_type_t of the type. If the bit is
+ ** set, then the type is defined in a separate dst record, which is referenced
+ ** by the remaining bits as a dst_rel_offset_t.
+ */
+
+typedef union
+ {
+ struct
+ {
+ boolean user_defined_type:1; /* tag field */
+ int must_be_zero:23; /* 23 bits of pad */
+ dst_std_type_t dtc:8; /* 8 bit primitive data */
+ }
+ std_type;
+
+ struct
+ {
+ boolean user_defined_type:1; /* tag field */
+ int doffset:31; /* offset to type record */
+ }
+ user_type;
+ }
+dst_type_t ALIGNED1;
+
+/* The user_type.doffset field is a 31-bit signed value. Some versions of C
+ do not support signed bit fields. The following macro will extract that
+ field as a signed value:
+ */
+#define dst_user_type_offset(type_rec) \
+ ( ((int) ((type_rec).user_type.doffset << 1)) >> 1 )
+
+
+/*================================================*/
+/*========== RECORDS IN .blocks SECTION ==========*/
+/*================================================*/
+
+/*-----------------------
+ COMPILATION UNIT record
+ -----------------------
+ This must be the first record in each .blocks section.
+ Provides a set of information describing the output of a single compilation
+ and pointers to additional information for the compilation unit.
+*/
+
+typedef enum
+ {
+ dst_pc_code_locs, /* ranges in loc strings are pc ranges */
+ dst_comp_unit_END_OF_ENUM
+ }
+dst_comp_unit_flag_t;
+
+typedef enum
+ {
+ dst_lang_unk, /* unknown language */
+ dst_lang_pas, /* Pascal */
+ dst_lang_ftn, /* FORTRAN */
+ dst_lang_c, /* C */
+ dst_lang_mod2, /* Modula-2 */
+ dst_lang_asm_m68k, /* 68K assembly language */
+ dst_lang_asm_a88k, /* AT assembly language */
+ dst_lang_ada, /* Ada */
+ dst_lang_cxx, /* C++ */
+ dst_lang_END_OF_ENUM
+ }
+dst_lang_type_t;
+
+typedef struct
+ {
+ struct
+ {
+ unsigned char major_part; /* = dst_version_major */
+ unsigned char minor_part; /* = dst_version_minor */
+ }
+ version; /* version of dst */
+ unsigned short flags; /* mask of dst_comp_unit_flag_t */
+ unsigned short lang_type; /* source language */
+ unsigned short number_of_blocks; /* number of blocks records */
+ dst_rel_offset_t root_block_offset; /* offset to root block (module?) */
+ dst_rel_offset_t section_table /* offset to section table record */ ;
+ dst_rel_offset_t file_table; /* offset to file table record */
+ unsigned long data_size; /* total size of .blocks data */
+ }
+dst_rec_comp_unit_t ALIGNED1;
+
+
+/*--------------------
+ SECTION TABLE record
+ --------------------
+ There must be one section table associated with each compilation unit.
+ Other debug records refer to sections via their index in this table. The
+ section base addresses in the table are virtual addresses of the sections,
+ relocated by the linker.
+*/
+
+typedef struct
+ {
+ unsigned short number_of_sections; /* size of array: */
+ unsigned long section_base[dst_dummy_array_size] ALIGNED1;
+ }
+dst_rec_section_tab_t ALIGNED1;
+
+
+/*-----------------
+ FILE TABLE record
+ -----------------
+ There must be one file table associated with each compilation unit describing
+ the source (and include) files used by each compilation unit. Other debug
+ records refer to files via their index in this table. The first entry is the
+ primary source file.
+*/
+
+typedef struct
+ {
+ long dtm; /* time last modified (time_$clock_t) */
+ dst_rel_offset_t noffset; /* offset to name string for source file */
+ }
+dst_file_desc_t;
+
+typedef struct
+ {
+ unsigned short number_of_files; /* size of array: */
+ dst_file_desc_t files[dst_dummy_array_size] ALIGNED1;
+ }
+dst_rec_file_tab_t ALIGNED1;
+
+
+/*-----------------
+ NAME TABLE record
+ -----------------
+ A name table record may appear as an auxiliary record to the file table,
+ providing additional qualification of the file indexes for languages that
+ need it (i.e. Ada). Name table entries parallel file table entries of the
+ same file index.
+*/
+
+typedef struct
+ {
+ unsigned short number_of_names; /* size of array: */
+ dst_rel_offset_t names[dst_dummy_array_size] ALIGNED1;
+ }
+dst_rec_name_tab_t ALIGNED1;
+
+
+/*--------------
+ BLOCK record
+ --------------
+ Describes a lexical program block--a procedure, function, module, etc.
+*/
+
+/* Block types. These may be used in any way desired by the compiler writers.
+ The debugger uses them only to give a description to the user of the type of
+ a block. The debugger makes no other assumptions about the meaning of any
+ of these. For example, the fact that a block is executable (e.g., program)
+ or not (e.g., module) is expressed in block attributes (see below), not
+ guessed at from the block type.
+ */
+typedef enum
+ {
+ dst_block_module, /* some pascal = modula = ada types */
+ dst_block_program,
+ dst_block_procedure,
+ dst_block_function, /* C function */
+ dst_block_subroutine, /* some fortran block types */
+ dst_block_block_data,
+ dst_block_stmt_function,
+ dst_block_package, /* a few particular to Ada */
+ dst_block_package_body,
+ dst_block_subunit,
+ dst_block_task,
+ dst_block_file, /* a C outer scope? */
+ dst_block_class, /* C++ or Simula */
+ dst_block_END_OF_ENUM
+ }
+dst_block_type_t;
+
+/* Block attributes. This is the information used by the debugger to represent
+ the semantics of blocks.
+ */
+typedef enum
+ {
+ dst_block_main_entry, /* the block's entry point is a main entry into
+ the compilation unit */
+ dst_block_executable, /* the block has an entry point */
+ dst_block_attr_END_OF_ENUM
+ }
+dst_block_attr_t;
+
+/* Code range. Each block has associated with it one or more code ranges. An
+ individual code range is identified by a range of source (possibly nil) and
+ a range of executable code. For example, a block which has its executable
+ code spread over multiple sections will have one code range per section.
+ */
+typedef struct
+ {
+ unsigned long code_size; /* size of executable code (in bytes ) */
+ dst_sect_ref_t code_start; /* starting address of executable code */
+ dst_sect_ref_t lines_start; /* start of line number tables */
+ }
+dst_code_range_t;
+
+typedef struct
+ {
+ dst_block_type_t block_type:8;
+ unsigned short flags:8; /* mask of dst_block_attr_t flags */
+ dst_rel_offset_t sibling_block_off; /* offset to next sibling block */
+ dst_rel_offset_t child_block_off; /* offset to first contained block */
+ dst_rel_offset_t noffset; /* offset to block name string */
+ dst_sect_ref_t symbols_start; /* start of debug symbols */
+ unsigned short n_of_code_ranges; /* size of array... */
+ dst_code_range_t code_ranges[dst_dummy_array_size] ALIGNED1;
+ }
+dst_rec_block_t ALIGNED1;
+
+
+/*--------------------------
+ AUX SECT INFO TABLE record
+ --------------------------
+ Appears as an auxiliary to a block record. Expands code range information
+ by providing references into additional, language-dependent sections for
+ information related to specific code ranges of the block. Sect info table
+ entries parallel code range array entries of the same index.
+*/
+
+typedef struct
+ {
+ unsigned char tag; /* currently can only be zero */
+ unsigned char number_of_refs; /* size of array: */
+ dst_sect_ref_t refs[dst_dummy_array_size] ALIGNED1;
+ }
+dst_rec_sect_info_tab_t ALIGNED1;
+
+/*=================================================*/
+/*========== RECORDS IN .symbols SECTION ==========*/
+/*=================================================*/
+
+/*-----------------
+ CONSTANT record
+ -----------------
+ Describes a symbolic constant.
+*/
+
+typedef struct
+ {
+ float r; /* real part */
+ float i; /* imaginary part */
+ }
+dst_complex_t;
+
+typedef struct
+ {
+ double dr; /* real part */
+ double di; /* imaginary part */
+ }
+dst_double_complex_t;
+
+/* The following record provides a way of describing constant values with
+ non-standard type and no limit on size.
+ */
+typedef union
+ {
+ char char_data[dst_dummy_array_size];
+ short int_data[dst_dummy_array_size];
+ long long_data[dst_dummy_array_size];
+ }
+dst_big_kon_t;
+
+/* Representation of the value of a general constant.
+ */
+typedef struct
+ {
+ unsigned short length; /* size of constant value (bytes) */
+
+ union
+ {
+ unsigned short kon_int8;
+ short kon_int16;
+ long kon_int32 ALIGNED1;
+ float kon_real ALIGNED1;
+ double kon_dbl ALIGNED1;
+ dst_complex_t kon_cplx ALIGNED1;
+ dst_double_complex_t kon_dcplx ALIGNED1;
+ char kon_char;
+ dst_big_kon_t kon ALIGNED1;
+ }
+ val; /* value data of constant */
+ }
+dst_const_t ALIGNED1;
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name string */
+ dst_src_loc_t src_loc; /* file/line of const definition */
+ dst_type_t type_desc; /* type of this (manifest) constant */
+ dst_const_t value;
+ }
+dst_rec_const_t ALIGNED1;
+
+/*----------------
+ VARIABLE record
+ ----------------
+ Describes a program variable.
+*/
+
+/* Variable attributes. These define certain variable semantics to the
+ debugger.
+ */
+typedef enum
+ {
+ dst_var_attr_read_only, /* is read-only (a program literal) */
+ dst_var_attr_volatile, /* same as compiler's VOLATILE attribute */
+ dst_var_attr_global, /* is a global definition or reference */
+ dst_var_attr_compiler_gen, /* is compiler-generated */
+ dst_var_attr_static, /* has static location */
+ dst_var_attr_END_OF_ENUM
+ }
+dst_var_attr_t;
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name string */
+ dst_rel_offset_t loffset; /* offset to loc string */
+ dst_src_loc_t src_loc; /* file/line of variable definition */
+ dst_type_t type_desc; /* type descriptor */
+ unsigned short attributes; /* mask of dst_var_attr_t flags */
+ }
+dst_rec_variable_t ALIGNED1;
+
+
+/*----------------
+ old VAR record
+ -----------------
+ Used by older compilers to describe a variable
+*/
+
+typedef enum
+ {
+ dst_var_loc_unknown, /* Actually defined as "unknown" */
+ dst_var_loc_abs, /* Absolute address */
+ dst_var_loc_sect_off, /* Absolute address as a section offset */
+ dst_var_loc_ind_sect_off, /* An indexed section offset ???? */
+ dst_var_loc_reg, /* register */
+ dst_var_loc_reg_rel, /* register relative - usually fp */
+ dst_var_loc_ind_reg_rel, /* Indexed register relative */
+ dst_var_loc_ftn_ptr_based, /* Fortran pointer based */
+ dst_var_loc_pc_rel, /* PC relative. Really. */
+ dst_var_loc_external, /* External */
+ dst_var_loc_END_OF_ENUM
+ }
+dst_var_loc_t;
+
+/* Locations come in two versions. The short, and the long. The difference
+ * between the short and the long is the addition of a statement number
+ * field to the start andend of the range of the long, and and unkown
+ * purpose field in the middle. Also, loc_type and loc_index aren't
+ * bitfields in the long version.
+ */
+
+typedef struct
+ {
+ unsigned short loc_type:4;
+ unsigned short loc_index:12;
+ long location;
+ short start_line; /* start_line and end_line? */
+ short end_line; /* I'm guessing here. */
+ }
+dst_var_loc_short_t;
+
+typedef struct
+ {
+ unsigned short loc_type;
+ unsigned short loc_index;
+ long location;
+ short unknown; /* Always 0003 or 3b3c. Why? */
+ short start_statement;
+ short start_line;
+ short end_statement;
+ short end_line;
+ }
+dst_var_loc_long_t;
+
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name string */
+ dst_src_loc_t src_loc; /* file/line of description */
+ dst_type_t type_desc; /* Type description */
+ unsigned short attributes; /* mask of dst_var_attr_t flags */
+ unsigned short no_of_locs:15; /* Number of locations */
+ unsigned short short_locs:1; /* True if short locations. */
+ union
+ {
+ dst_var_loc_short_t shorts[dst_dummy_array_size];
+ dst_var_loc_long_t longs[dst_dummy_array_size];
+ }
+ locs;
+ }
+dst_rec_var_t;
+
+/*----------------
+ old LABEL record
+ -----------------
+ Used by older compilers to describe a label
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name string */
+ dst_src_loc_t src_loc; /* file/line of description */
+ char location[12]; /* location string */
+ }
+dst_rec_old_label_t ALIGNED1;
+
+/*----------------
+ POINTER record
+ ----------------
+ Describes a pointer type.
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to the name string for this type */
+ dst_src_loc_t src_loc; /* file/line of definition */
+ dst_type_t type_desc; /* base type of this pointer */
+ }
+dst_rec_pointer_t ALIGNED1;
+
+
+/*-------------
+ ARRAY record
+ -------------
+ Describes an array type.
+
+ Multidimensional arrays are described with a number of dst_rec_array_t
+ records, one per array dimension, each linked to the next through the
+ elem_type_desc.doffset field. Each record must have its multi_dim flag
+ set.
+
+ If column_major is true (as with FORTRAN arrays) then the last array bound in
+ the declaration is the first array index in memory, which is the opposite of
+ the usual case (as with Pascal and C arrays).
+
+ Variable array bounds are described by auxiliary records; if aux_var_bound
+ records are present, the lo_bound and hi_bound fields of this record are
+ ignored by the debugger.
+
+ span_comp identifies one of the language-dependent ways in which the distance
+ between successive array elements (span) is calculated.
+ dst_use_span_field -- the span is the value of span field.
+ dst_compute_from_prev -- the span is the size of the previous dimension.
+ dst_compute_from_next -- the span is the size of the next dimension.
+ In the latter two cases, the span field contains an amount of padding to add
+ to the size of the appropriate dimension to calculate the span.
+*/
+
+typedef enum
+ {
+ dst_use_span_field,
+ dst_compute_from_prev,
+ dst_compute_from_next,
+ dst_span_comp_END_OF_ENUM
+ }
+dst_span_comp_t;
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name string */
+ dst_src_loc_t src_loc; /* file/line of definition */
+ dst_type_t elem_type_desc; /* array element type */
+ dst_type_t indx_type_desc; /* array index type */
+ long lo_bound; /* lower bound of index */
+ long hi_bound; /* upper bound of index */
+ unsigned long span; /* see above */
+ unsigned long size; /* total array size (bytes) */
+ boolean multi_dim:1;
+ boolean is_packed:1; /* true if packed array */
+ boolean is_signed:1; /* true if packed elements are signed */
+ dst_span_comp_t span_comp:2; /* how to compute span */
+ boolean column_major:1;
+ unsigned short reserved:2; /* must be zero */
+ unsigned short elem_size:8; /* element size if packed (bits) */
+ }
+dst_rec_array_t ALIGNED1;
+
+
+/*-----------------
+ SUBRANGE record
+ -----------------
+ Describes a subrange type.
+*/
+
+/* Variable subrange bounds are described by auxiliary records; if aux_var_bound
+ records are present, the lo_bound and hi_bound fields of this record are
+ ignored by the debugger.
+ */
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name string */
+ dst_src_loc_t src_loc; /* file/line of subrange definition */
+ dst_type_t type_desc; /* parent type */
+ long lo_bound; /* lower bound of subrange */
+ long hi_bound; /* upper bound of subrange */
+ unsigned short size; /* storage size (bytes) */
+ }
+dst_rec_subrange_t ALIGNED1;
+
+
+/*---------------
+ STRING record
+ ---------------
+ Describes a string type.
+*/
+
+/* Variable subrange bounds are described by auxiliary records; if aux_var_bound
+ records are present, the lo_bound and hi_bound fields of this record are
+ ignored by the debugger.
+ */
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name string */
+ dst_src_loc_t src_loc; /* file/line of string definition */
+ dst_type_t elem_type_desc; /* element type */
+ dst_type_t indx_type_desc; /* index type */
+ long lo_bound; /* lower bound */
+ long hi_bound; /* upper bound */
+ unsigned long size; /* total string size (bytes) if fixed */
+ }
+dst_rec_string_t ALIGNED1;
+
+
+/*---------------
+ SET record
+ ---------------
+ Describes a set type.
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name string */
+ dst_src_loc_t src_loc; /* file/line of definition */
+ dst_type_t type_desc; /* element type */
+ unsigned short nbits; /* number of bits in set */
+ unsigned short size; /* storage size (bytes) */
+ }
+dst_rec_set_t ALIGNED1;
+
+
+/*-----------------------------
+ IMPLICIT ENUMERATION record
+ -----------------------------
+ Describes an enumeration type with implicit element values = 0, 1, 2, ...
+ (Pascal-style).
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name string */
+ dst_src_loc_t src_loc; /* file/line of definition */
+ unsigned short nelems; /* number of elements in enumeration */
+ unsigned short size; /* storage size (bytes) */
+ /* offsets to name strings of elements 0, 1, 2, ... */
+ dst_rel_offset_t elem_noffsets[dst_dummy_array_size];
+ }
+dst_rec_implicit_enum_t ALIGNED1;
+
+
+/*-----------------------------
+ EXPLICIT ENUMERATION record
+ -----------------------------
+ Describes an enumeration type with explicitly assigned element values
+ (C-style).
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to element name string */
+ long value; /* element value */
+ }
+dst_enum_elem_t;
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name string */
+ dst_src_loc_t src_loc; /* file/line of definition */
+ unsigned short nelems; /* number of elements in enumeration */
+ unsigned short size; /* storage size (bytes) */
+ /* name/value pairs, one describing each enumeration value: */
+ dst_enum_elem_t elems[dst_dummy_array_size];
+ }
+dst_rec_explicit_enum_t ALIGNED1;
+
+
+/*-----------------------
+ RECORD / UNION record
+ -----------------------
+ Describes a record (struct) or union.
+
+ If the record is larger than 2**16 bytes then an attached aux record
+ specifies its size. Also, if the record is stored in short form then
+ attached records specify field offsets larger than 2**16 bytes.
+
+ Whether the fields[] array or sfields[] array is used is selected by
+ the dst_rec_type_t of the overall dst record.
+*/
+
+/*
+ Record field descriptor, short form. This form handles only fields which
+ are an even number of bytes long, located some number of bytes from the
+ start of the record.
+ */
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to field name string */
+ dst_type_t type_desc; /* field type */
+ unsigned short foffset; /* field offset from start of record (bytes) */
+ }
+dst_short_field_t ALIGNED1;
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name string */
+ dst_type_t type_desc; /* field type */
+ unsigned short foffset; /* byte offset */
+ unsigned short is_packed:1; /* True if field is packed */
+ unsigned short bit_offset:6; /* Bit offset */
+ unsigned short size:6; /* Size in bits */
+ unsigned short sign:1; /* True if signed */
+ unsigned short pad:2; /* Padding. Must be 0 */
+ }
+dst_old_field_t ALIGNED1;
+
+/* Tag enumeration for long record field descriptor:
+ */
+typedef enum
+ {
+ dst_field_byte,
+ dst_field_bit,
+ dst_field_loc,
+ dst_field_END_OF_ENUM
+ }
+dst_field_format_t;
+
+/*
+ Record field descriptor, long form. The format of the field information
+ is identified by the format_tag, which contains one of the above values.
+ The field_byte variant is equivalent to the short form of field descriptor.
+ The field_bit variant handles fields which are any number of bits long,
+ located some number of bits from the start of the record. The field_loc
+ variant allows the location of the field to be described by a general loc
+ string.
+ */
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name of field */
+ dst_type_t type_desc; /* type of field */
+ union
+ {
+ struct
+ {
+ dst_field_format_t format_tag:2; /* dst_field_byte */
+ unsigned long offset:30; /* offset of field in bytes */
+ }
+ field_byte ALIGNED1;
+ struct
+ {
+ dst_field_format_t format_tag:2; /* dst_field_bit */
+ unsigned long nbits:6; /* bit size of field */
+ unsigned long is_signed:1; /* signed/unsigned attribute */
+ unsigned long bit_offset:3; /* bit offset from byte boundary */
+ int pad:4; /* must be zero */
+ unsigned short byte_offset; /* offset of byte boundary */
+ }
+ field_bit ALIGNED1;
+ struct
+ {
+ dst_field_format_t format_tag:2; /* dst_field_loc */
+ int loffset:30; /* dst_rel_offset_t to loc string */
+ }
+ field_loc ALIGNED1;
+ }
+ f ALIGNED1;
+ }
+dst_field_t;
+
+/* The field_loc.loffset field is a 30-bit signed value. Some versions of C do
+ not support signed bit fields. The following macro will extract that field
+ as a signed value:
+ */
+#define dst_field_loffset(field_rec) \
+ ( ((int) ((field_rec).f.field_loc.loffset << 2)) >> 2 )
+
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to record name string */
+ dst_src_loc_t src_loc; /* file/line where this record is defined */
+ unsigned short size; /* storage size (bytes) */
+ unsigned short nfields; /* number of fields in this record */
+ union
+ {
+ dst_field_t fields[dst_dummy_array_size];
+ dst_short_field_t sfields[dst_dummy_array_size];
+ dst_old_field_t ofields[dst_dummy_array_size];
+ }
+ f; /* array of fields */
+ }
+dst_rec_record_t ALIGNED1;
+
+
+/*-------------
+ FILE record
+ -------------
+ Describes a file type.
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name string */
+ dst_src_loc_t src_loc; /* file/line where type was defined */
+ dst_type_t type_desc; /* file element type */
+ }
+dst_rec_file_t ALIGNED1;
+
+
+/*---------------
+ OFFSET record
+ ---------------
+ Describes a Pascal offset type.
+ (This type, an undocumented Domain Pascal extension, is currently not
+ supported by the debugger)
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to the name string */
+ dst_src_loc_t src_loc; /* file/line of definition */
+ dst_type_t area_type_desc; /* area type */
+ dst_type_t base_type_desc; /* base type */
+ long lo_bound; /* low bound of the offset range */
+ long hi_bound; /* high bound of the offset range */
+ long bias; /* bias */
+ unsigned short scale; /* scale factor */
+ unsigned short size; /* storage size (bytes) */
+ }
+dst_rec_offset_t ALIGNED1;
+
+
+/*--------------
+ ALIAS record
+ --------------
+ Describes a type alias (e.g., typedef).
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name string */
+ dst_src_loc_t src_loc; /* file/line of definition */
+ dst_type_t type_desc; /* parent type */
+ }
+dst_rec_alias_t ALIGNED1;
+
+
+/*------------------
+ SIGNATURE record
+ ------------------
+ Describes a procedure/function type.
+*/
+
+/* Enumeration of argument semantics. Note that most are mutually
+ exclusive.
+ */
+typedef enum
+ {
+ dst_arg_attr_val, /* passed by value */
+ dst_arg_attr_ref, /* passed by reference */
+ dst_arg_attr_name, /* passed by name */
+ dst_arg_attr_in, /* readable in the callee */
+ dst_arg_attr_out, /* writable in the callee */
+ dst_arg_attr_hidden, /* not visible in the caller */
+ dst_arg_attr_END_OF_ENUM
+ }
+dst_arg_attr_t;
+
+/* Argument descriptor. Actually points to a variable record for most of the
+ information.
+ */
+typedef struct
+ {
+ dst_rel_offset_t var_offset; /* offset to variable record */
+ unsigned short attributes; /* a mask of dst_arg_attr_t flags */
+ }
+dst_arg_t ALIGNED1;
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to name string */
+ dst_src_loc_t src_loc; /* file/line of function definition */
+ dst_rel_offset_t result; /* offset to function result variable record */
+ unsigned short nargs; /* number of arguments */
+ dst_arg_t args[dst_dummy_array_size];
+ }
+dst_rec_signature_t ALIGNED1;
+
+/*--------------
+ SCOPE record
+ --------------
+ Obsolete. Use the new ENTRY type instead.
+ Old compilers may put this in as the first entry in a function,
+ terminated by an end of scope entry.
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* Name offset */
+ dst_src_loc_t start_line; /* Starting line */
+ dst_src_loc_t end_line; /* Ending line */
+ }
+dst_rec_scope_t ALIGNED1;
+
+/*--------------
+ ENTRY record
+ --------------
+ Describes a procedure/function entry point. An entry record is to a
+ signature record roughly as a variable record is to a type descriptor record.
+
+ The entry_number field is keyed to the entry numbers in .lines -- the
+ debugger locates the code location of an entry by searching the line
+ number table for an entry numbered with the value of entry_number. The
+ main entry is numbered zero.
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to entry name string */
+ dst_rel_offset_t loffset; /* where to jump to call this entry */
+ dst_src_loc_t src_loc; /* file/line of definition */
+ dst_rel_offset_t sig_desc; /* offset to signature descriptor */
+ unsigned int entry_number:8;
+ int pad:8; /* must be zero */
+ }
+dst_rec_entry_t ALIGNED1;
+
+/*-----------------------
+ Old format ENTRY record
+ -----------------------
+ Supposedly obsolete but still used by some compilers.
+ */
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* Offset to entry name string */
+ dst_src_loc_t src_loc; /* Location in source */
+ dst_rel_offset_t sig_desc; /* Signature description */
+ char unknown[36];
+ }
+dst_rec_old_entry_t ALIGNED1;
+
+/*--------------
+ LABEL record
+ --------------
+ Describes a program label.
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t noffset; /* offset to label string */
+ dst_rel_offset_t loffset; /* offset to loc string */
+ dst_src_loc_t src_loc; /* file/line of definition */
+ }
+dst_rec_label_t ALIGNED1;
+
+
+/*-----------------------
+ AUXILIARY SIZE record
+ -----------------------
+ May appear in the auxiliary record list of any type or variable record to
+ modify the default size of the type or variable.
+*/
+
+typedef struct
+ {
+ unsigned long size; /* size (bytes) */
+ }
+dst_rec_aux_size_t ALIGNED1;
+
+
+/*-----------------------
+ AUXILIARY ALIGN record
+ -----------------------
+ May appear in the auxiliary record list of any type or variable record to
+ modify the default alignment of the type or variable.
+*/
+
+typedef struct
+ {
+ unsigned short alignment; /* # of low order zero bits */
+ }
+dst_rec_aux_align_t ALIGNED1;
+
+
+/*-----------------------------
+ AUXILIARY FIELD SIZE record
+ -----------------------------
+ May appear in the auxiliary record list of any RECORD/UNION record to
+ modify the default size of a field.
+*/
+
+typedef struct
+ {
+ unsigned short field_no; /* field number */
+ unsigned long size; /* size (bits) */
+ }
+dst_rec_aux_field_size_t ALIGNED1;
+
+
+
+/*-----------------------------
+ AUXILIARY FIELD OFFSET record
+ -----------------------------
+ May appear in the auxiliary record list of any RECORD/UNION record to
+ specify a field offset larger than 2**16.
+*/
+
+typedef struct
+ {
+ unsigned short field_no; /* field number */
+ unsigned long foffset; /* offset */
+ }
+dst_rec_aux_field_off_t ALIGNED1;
+
+
+/*-----------------------------
+ AUXILIARY FIELD ALIGN record
+ -----------------------------
+ May appear in the auxiliary record list of any RECORD/UNION record to
+ modify the default alignment of a field.
+*/
+
+typedef struct
+ {
+ unsigned short field_no; /* field number */
+ unsigned short alignment; /* number of low order zero bits */
+ }
+dst_rec_aux_field_align_t ALIGNED1;
+
+
+/*----------------------------
+ AUXILIARY VAR BOUND record
+ ----------------------------
+ May appear in the auxiliary record list of any ARRAY, SUBRANGE or STRING
+ record to describe a variable bound for the range of the type.
+*/
+
+typedef enum
+ {
+ dst_low_bound, /* the low bound is variable */
+ dst_high_bound, /* the high bound is variable */
+ dst_var_bound_END_OF_ENUM
+ }
+dst_var_bound_t;
+
+typedef struct
+ {
+ unsigned short which; /* which bound */
+ dst_rel_offset_t voffset ALIGNED1; /* variable that defines bound */
+ }
+dst_rec_aux_var_bound_t ALIGNED1;
+
+
+/*----------------------------------
+ AUXILIARY TYPE DERIVATION record
+ ----------------------------------
+ May appear in the auxiliary record list of any RECORD/UNION record to denote
+ class inheritance of that type from a parent type.
+
+ Inheritance implies that it is possible to convert the inheritor type to the
+ inherited type, retaining those fields which were inherited. To allow this,
+ orig_field_no, a field number into the record type, is provided. If
+ orig_is_pointer is false, then the start of the inherited record is located
+ at the location of the field indexed by orig_field_no. If orig_is_pointer
+ is true, then it is located at the address contained in the field indexed
+ by orig_field_no (assumed to be a pointer).
+*/
+
+typedef struct
+ {
+ dst_type_t parent_type; /* reference to inherited type */
+ unsigned short orig_field_no;
+ boolean orig_is_pointer:1;
+ int unused:15; /* must be zero */
+ }
+dst_rec_aux_type_deriv_t ALIGNED1;
+
+
+/*------------------------------------
+ AUXILIARY VARIABLE LIFETIME record
+ ------------------------------------
+ May appear in the auxiliary record list of a VARIABLE record to add location
+ information for an additional variable lifetime.
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t loffset;
+ }
+dst_rec_aux_lifetime_t ALIGNED1;
+
+
+/*-------------------------------
+ AUXILIARY POINTER BASE record
+ -------------------------------
+ May appear in the auxiliary record list of a VARIABLE record to provide a
+ pointer base to substitute for references to any such bases in the location
+ string of the variable. A pointer base is another VARIABLE record. When
+ the variable is evaluated by the debugger, it uses the current value of the
+ pointer base variable in computing its location.
+
+ This is useful for representing FORTRAN pointer-based variables.
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t voffset;
+ }
+dst_rec_aux_ptr_base_t ALIGNED1;
+
+
+/*---------------------------------
+ AUXILIARY REGISTER VALUE record
+ ---------------------------------
+ May appear in the auxiliary record list of an ENTRY record to specify
+ a register that must be set to a specific value before jumping to the entry
+ point in a debugger "call". The debugger must set the debuggee register,
+ specified by the register code, to the value of the *address* to which the
+ location string resolves. If the address is register-relative, then the
+ call cannot be made unless the current stack frame is the lexical parent
+ of the entry. An example of this is when a (Pascal) nested procedure
+ contains references to its parent's variables, which it accesses through
+ a static link register. The static link register must be set to some
+ address relative to the parent's stack base register.
+*/
+
+typedef struct
+ {
+ unsigned short reg; /* identifies register to set (isp enum) */
+ dst_rel_offset_t loffset; /* references a location string */
+ }
+dst_rec_aux_reg_val_t ALIGNED1;
+
+
+/*==========================================================*/
+/*========== RECORDS USED IN .blocks AND .symbols ==========*/
+/*==========================================================*/
+
+/*---------------------
+ STRING TABLE record
+ ---------------------
+ A string table record contains any number of null-terminated, variable length
+ strings. The length field gives the size in bytes of the text field, which
+ can be any size.
+
+ The global name table shares this format. This record appears in the
+ .blocks section. Each string in the table identifies a global defined in
+ the current compilation unit.
+
+ The loc pool record shares this format as well. Loc strings are described
+ elsewhere.
+*/
+
+typedef struct
+ {
+ unsigned long length;
+ char text[dst_dummy_array_size];
+ }
+dst_rec_string_tab_t ALIGNED1;
+
+
+/*-----------------------
+ AUXILIARY QUAL record
+ -----------------------
+ May appear in the auxiliary record list of any BLOCK, VARIABLE, or type record
+ to provide it with a fully-qualified, language-dependent name.
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t lang_qual_name;
+ }
+dst_rec_aux_qual_t ALIGNED1;
+
+
+/*----------------
+ FORWARD record
+ ----------------
+ Reference to a record somewhere else. This allows identical definitions in
+ different scopes to share data.
+*/
+
+typedef struct
+ {
+ dst_rel_offset_t rec_off;
+ }
+dst_rec_forward_t ALIGNED1;
+
+
+/*-------------------------------
+ AUXILIARY SOURCE RANGE record
+ -------------------------------
+ May appear in the auxiliary record list of any BLOCK record to specify a
+ range of source lines over which the block is active.
+*/
+
+typedef struct
+ {
+ dst_src_loc_t first_line; /* first source line */
+ dst_src_loc_t last_line; /* last source line */
+ }
+dst_rec_aux_src_range_t ALIGNED1;
+
+
+/*------------------
+ EXTENSION record
+ ------------------
+ Provision for "foreign" records, such as might be generated by a non-Apollo
+ compiler. Apollo software will ignore these.
+*/
+
+typedef struct
+ {
+ unsigned short rec_size; /* record size (bytes) */
+ unsigned short ext_type; /* defined by whoever generates it */
+ unsigned short ext_data; /* place-holder for arbitrary amount of data */
+ }
+dst_rec_extension_t ALIGNED1;
+
+
+/*
+ ** DEBUG SYMBOL record -- The wrapper for all .blocks and .symbols records.
+ **
+ ** This record ties together all previous .blocks and .symbols records
+ ** together in a union with a common header. The rec_type field of the
+ ** header identifies the record type. The rec_flags field currently only
+ ** defines auxiliary record lists.
+ **
+ ** If a record carries with it a non-null auxiliary record list, its
+ ** dst_flag_has_aux_recs flag is set, and each of the records that follow
+ ** it are treated as its auxiliary records, until the end of the compilation
+ ** unit or scope is reached, or until an auxiliary record with its
+ ** dst_flag_last_aux_rec flag set is reached.
+ */
+
+typedef enum
+ {
+ dst_flag_has_aux_recs,
+ dst_flag_last_aux_rec,
+ dst_rec_flag_END_OF_ENUM
+ }
+dst_rec_flags_t;
+
+typedef struct
+ {
+ dst_rec_type_t rec_type:8; /* record type */
+ int rec_flags:8; /* mask of dst_rec_flags_t */
+ union /* switched on rec_type field above */
+ {
+ /* dst_typ_pad requires no additional fields */
+ dst_rec_comp_unit_t comp_unit_;
+ dst_rec_section_tab_t section_tab_;
+ dst_rec_file_tab_t file_tab_;
+ dst_rec_block_t block_;
+ dst_rec_var_t var_;
+ dst_rec_pointer_t pointer_;
+ dst_rec_array_t array_;
+ dst_rec_subrange_t subrange_;
+ dst_rec_set_t set_;
+ dst_rec_implicit_enum_t implicit_enum_;
+ dst_rec_explicit_enum_t explicit_enum_;
+ /* dst_typ_short_{rec,union} are represented by 'rec' (below) */
+ dst_rec_file_t file_;
+ dst_rec_offset_t offset_;
+ dst_rec_alias_t alias_;
+ dst_rec_signature_t signature_;
+ dst_rec_old_label_t old_label_;
+ dst_rec_scope_t scope_;
+ /* dst_typ_end_scope requires no additional fields */
+ dst_rec_string_tab_t string_tab_;
+ /* dst_typ_global_name_tab is represented by 'string_tab' (above) */
+ dst_rec_forward_t forward_;
+ dst_rec_aux_size_t aux_size_;
+ dst_rec_aux_align_t aux_align_;
+ dst_rec_aux_field_size_t aux_field_size_;
+ dst_rec_aux_field_off_t aux_field_off_;
+ dst_rec_aux_field_align_t aux_field_align_;
+ dst_rec_aux_qual_t aux_qual_;
+ dst_rec_aux_var_bound_t aux_var_bound_;
+ dst_rec_extension_t extension_;
+ dst_rec_string_t string_;
+ dst_rec_const_t const_;
+ /* dst_typ_reference is represented by 'pointer' (above) */
+ dst_rec_record_t record_;
+ /* dst_typ_union is represented by 'record' (above) */
+ dst_rec_aux_type_deriv_t aux_type_deriv_;
+ /* dst_typ_locpool is represented by 'string_tab' (above) */
+ dst_rec_variable_t variable_;
+ dst_rec_label_t label_;
+ dst_rec_entry_t entry_;
+ dst_rec_aux_lifetime_t aux_lifetime_;
+ dst_rec_aux_ptr_base_t aux_ptr_base_;
+ dst_rec_aux_src_range_t aux_src_range_;
+ dst_rec_aux_reg_val_t aux_reg_val_;
+ dst_rec_name_tab_t aux_unit_names_;
+ dst_rec_sect_info_tab_t aux_sect_info_;
+ }
+ rec_data ALIGNED1;
+ }
+dst_rec_t, *dst_rec_ptr_t;
+
+
+/*===============================================*/
+/*========== .lines SECTION DEFINITIONS =========*/
+/*===============================================*/
+/*
+ The .lines section contains a sequence of line number tables. There is no
+ record structure within the section. The start of the table for a routine
+ is pointed to by the block record, and the end of the table is signaled by
+ an escape code.
+
+ A line number table is a sequence of bytes. The default entry contains a line
+ number delta (-7..+7) in the high 4 bits and a pc delta (0..15) in the low 4
+ bits. Special cases, including when one or both of the values is too large
+ to fit in 4 bits and other special cases are handled through escape entries.
+ Escape entries are identified by the value 0x8 in the high 4 bits. The low 4
+ bits are occupied by a function code. Some escape entries are followed by
+ additional arguments, which may be bytes, words, or longwords. This data is
+ not aligned.
+
+ The initial PC offset, file number and line number are zero. Normally, the
+ table begins with a dst_ln_file escape which establishes the initial file
+ and line number. All PC deltas are unsigned (thus the table is ordered by
+ increasing PC); line number deltas are signed. The table ends with a
+ dst_ln_end escape, which is followed by a final table entry whose PC delta
+ gives the code size of the last statement.
+
+ Escape Semantic
+ --------- ------------------------------------------------------------
+ file Changes file state. The current source file remains constant
+ until another file escape. Though the line number state is
+ also updated by a file escape, a file escape does NOT
+ constitute a line table entry.
+
+ statement Alters the statement number of the next table entry. By
+ default, all table entries refer to the first statement on a
+ line. Statement number one is the second statement, and so on.
+
+ entry Identifies the next table entry as the position of an entry
+ point for the current block. The PC position should follow
+ any procedure prologue code. An argument specifies the entry
+ number, which is keyed to the entry number of the corresponding
+ .symbols ENTRY record.
+
+ exit Identifies the next table entry as the last position within
+ the current block before a procedure epiloge and subsequent
+ procedure exit.
+
+ gap By default, the executable code corresponding to a table entry
+ is assumed to extend to the beginning of the next table entry.
+ If this is not the case--there is a "hole" in the table--then
+ a gap escape should follow the first table entry to specify
+ where the code for that entry ends.
+ */
+
+#define dst_ln_escape_flag -8
+
+/*
+ Escape function codes:
+ */
+typedef enum
+ {
+ dst_ln_pad, /* pad byte */
+ dst_ln_file, /* file escape. Next 4 bytes are a dst_src_loc_t */
+ dst_ln_dln1_dpc1, /* 1 byte line delta, 1 byte pc delta */
+ dst_ln_dln2_dpc2, /* 2 bytes line delta, 2 bytes pc delta */
+ dst_ln_ln4_pc4, /* 4 bytes ABSOLUTE line number, 4 bytes ABSOLUTE pc */
+ dst_ln_dln1_dpc0, /* 1 byte line delta, pc delta = 0 */
+ dst_ln_ln_off_1, /* statement escape, stmt # = 1 (2nd stmt on line) */
+ dst_ln_ln_off, /* statement escape, stmt # = next byte */
+ dst_ln_entry, /* entry escape, next byte is entry number */
+ dst_ln_exit, /* exit escape */
+ dst_ln_stmt_end, /* gap escape, 4 bytes pc delta */
+ dst_ln_escape_11, /* reserved */
+ dst_ln_escape_12, /* reserved */
+ dst_ln_escape_13, /* reserved */
+ dst_ln_nxt_byte, /* next byte contains the real escape code */
+ dst_ln_end, /* end escape, final entry follows */
+ dst_ln_escape_END_OF_ENUM
+ }
+dst_ln_escape_t;
+
+/*
+ Line number table entry
+ */
+typedef union
+ {
+ struct
+ {
+ unsigned int ln_delta:4; /* 4 bit line number delta */
+ unsigned int pc_delta:4; /* 4 bit pc delta */
+ }
+ delta;
+
+ struct
+ {
+ unsigned int esc_flag:4; /* alias for ln_delta */
+ dst_ln_escape_t esc_code:4; /* escape function code */
+ }
+ esc;
+
+ char sdata; /* signed data byte */
+ unsigned char udata; /* unsigned data byte */
+ }
+dst_ln_entry_t,
+ *dst_ln_entry_ptr_t,
+ dst_ln_table_t[dst_dummy_array_size];
+
+/* The following macro will extract the ln_delta field as a signed value:
+ */
+#define dst_ln_ln_delta(ln_rec) \
+ ( ((short) ((ln_rec).delta.ln_delta << 12)) >> 12 )
+
+
+
+
+typedef struct dst_sec_struct
+ {
+ char *buffer;
+ long position;
+ long size;
+ long base;
+ }
+dst_sec;
+
+
+/* Macros for access to the data */
+
+#define DST_comp_unit(x) ((x)->rec_data.comp_unit_)
+#define DST_section_tab(x) ((x)->rec_data.section_tab_)
+#define DST_file_tab(x) ((x)->rec_data.file_tab_)
+#define DST_block(x) ((x)->rec_data.block_)
+#define DST_var(x) ((x)->rec_data.var_)
+#define DST_pointer(x) ((x)->rec_data.pointer_)
+#define DST_array(x) ((x)->rec_data.array_)
+#define DST_subrange(x) ((x)->rec_data.subrange_)
+#define DST_set(x) ((x)->rec_data.set_)
+#define DST_implicit_enum(x) ((x)->rec_data.implicit_enum_)
+#define DST_explicit_enum(x) ((x)->rec_data.explicit_enum_)
+#define DST_short_rec(x) ((x)->rec_data.record_)
+#define DST_short_union(x) ((x)->rec_data.record_)
+#define DST_file(x) ((x)->rec_data.file_)
+#define DST_offset(x) ((x)->rec_data.offset_)
+#define DST_alias(x) ((x)->rec_data.alias_)
+#define DST_signature(x) ((x)->rec_data.signature_)
+#define DST_old_label(x) ((x)->rec_data.old_label_)
+#define DST_scope(x) ((x)->rec_data.scope_)
+#define DST_string_tab(x) ((x)->rec_data.string_tab_)
+#define DST_global_name_tab(x) ((x)->rec_data.string_tab_)
+#define DST_forward(x) ((x)->rec_data.forward_)
+#define DST_aux_size(x) ((x)->rec_data.aux_size_)
+#define DST_aux_align(x) ((x)->rec_data.aux_align_)
+#define DST_aux_field_size(x) ((x)->rec_data.aux_field_size_)
+#define DST_aux_field_off(x) ((x)->rec_data.aux_field_off_)
+#define DST_aux_field_align(x) ((x)->rec_data.aux_field_align_)
+#define DST_aux_qual(x) ((x)->rec_data.aux_qual_)
+#define DST_aux_var_bound(x) ((x)->rec_data.aux_var_bound_)
+#define DST_extension(x) ((x)->rec_data.extension_)
+#define DST_string(x) ((x)->rec_data.string_)
+#define DST_const(x) ((x)->rec_data.const_)
+#define DST_reference(x) ((x)->rec_data.pointer_)
+#define DST_record(x) ((x)->rec_data.record_)
+#define DST_union(x) ((x)->rec_data.record_)
+#define DST_aux_type_deriv(x) ((x)->rec_data.aux_type_deriv_)
+#define DST_locpool(x) ((x)->rec_data.string_tab_)
+#define DST_variable(x) ((x)->rec_data.variable_)
+#define DST_label(x) ((x)->rec_data.label_)
+#define DST_entry(x) ((x)->rec_data.entry_)
+#define DST_aux_lifetime(x) ((x)->rec_data.aux_lifetime_)
+#define DST_aux_ptr_base(x) ((x)->rec_data.aux_ptr_base_)
+#define DST_aux_src_range(x) ((x)->rec_data.aux_src_range_)
+#define DST_aux_reg_val(x) ((x)->rec_data.aux_reg_val_)
+#define DST_aux_unit_names(x) ((x)->rec_data.aux_unit_names_)
+#define DST_aux_sect_info(x) ((x)->rec_data.aux_sect_info_)
+
+
+/*
+ * Type codes for loc strings. I'm not entirely certain about all of
+ * these, but they seem to work.
+ * troy@cbme.unsw.EDU.AU
+ * If you find a variable whose location can't be decoded, you should
+ * find out it's code using "dstdump -s filename". It will record an
+ * entry for the variable, and give a text representation of what
+ * the locstring means. Before that explaination there will be a
+ * number. In the LOCSTRING table, that number will appear before
+ * the start of the location string. Location string codes are
+ * five bit codes with a 3 bit argument. Check the high 5 bits of
+ * the one byte code, and figure out where it goes in here.
+ * Then figure out exactly what the meaning is and code it in
+ * dstread.c
+ *
+ * Note that ranged locs mean that the variable is in different locations
+ * depending on the current PC. We ignore these because (a) gcc can't handle
+ * them, and (b), If you don't use high levels of optimisation they won't
+ * occur.
+ */
+typedef enum
+ {
+ dst_lsc_end, /* End of string */
+ dst_lsc_indirect, /* Indirect through previous. Arg == 6 */
+ /* Or register ax (x=arg) */
+ dst_lsc_dreg, /* register dx (x=arg) */
+ dst_lsc_03,
+ dst_lsc_section, /* Section (arg+1) */
+ dst_lsc_05,
+ dst_lsc_06,
+ dst_lsc_add, /* Add (arg+1)*2 */
+ dst_lsc_sub, /* Subtract (arg+1)*2 */
+ dst_lsc_09,
+ dst_lsc_0a,
+ dst_lsc_sec_byte, /* Section of next byte+1 */
+ dst_lsc_add_byte, /* Add next byte (arg == 5) or next word
+ * (arg == 6)
+ */
+ dst_lsc_sub_byte, /* Subtract next byte. (arg == 1) or next
+ * word (arg == 6 ?)
+ */
+ dst_lsc_sbreg, /* Stack base register (frame pointer). Arg==0 */
+ dst_lsc_0f,
+ dst_lsc_ranged, /* location is pc dependent */
+ dst_lsc_11,
+ dst_lsc_12,
+ dst_lsc_13,
+ dst_lsc_14,
+ dst_lsc_15,
+ dst_lsc_16,
+ dst_lsc_17,
+ dst_lsc_18,
+ dst_lsc_19,
+ dst_lsc_1a,
+ dst_lsc_1b,
+ dst_lsc_1c,
+ dst_lsc_1d,
+ dst_lsc_1e,
+ dst_lsc_1f
+ }
+dst_loc_string_code_t;
+
+/* If the following occurs after an addition/subtraction, that addition
+ * or subtraction should be multiplied by 256. It's a complete byte, not
+ * a code.
+ */
+
+#define dst_multiply_256 ((char) 0x73)
+
+typedef struct
+ {
+ char code:5;
+ char arg:3;
+ }
+dst_loc_header_t ALIGNED1;
+
+typedef union
+ {
+ dst_loc_header_t header;
+ char data;
+ }
+dst_loc_entry_t ALIGNED1;
+
+#undef ALIGNED1
+#endif /* apollo_dst_h */
diff --git a/gdb/dstread.c b/gdb/dstread.c
new file mode 100644
index 00000000000..abcce097a27
--- /dev/null
+++ b/gdb/dstread.c
@@ -0,0 +1,1596 @@
+/* Read apollo DST symbol tables and convert to internal format, for GDB.
+ Contributed by Troy Rollo, University of NSW (troy@cbme.unsw.edu.au).
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+ 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "breakpoint.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "obstack.h"
+
+#include "gdb_string.h"
+
+#include "dst.h"
+
+CORE_ADDR cur_src_start_addr, cur_src_end_addr;
+dst_sec blocks_info, lines_info, symbols_info;
+
+/* Vector of line number information. */
+
+static struct linetable *line_vector;
+
+/* Index of next entry to go in line_vector_index. */
+
+static int line_vector_index;
+
+/* Last line number recorded in the line vector. */
+
+static int prev_line_number;
+
+/* Number of elements allocated for line_vector currently. */
+
+static int line_vector_length;
+
+static int init_dst_sections (int);
+
+static void read_dst_symtab (struct objfile *);
+
+static void find_dst_sections (bfd *, sec_ptr, PTR);
+
+static void dst_symfile_init (struct objfile *);
+
+static void dst_new_init (struct objfile *);
+
+static void dst_symfile_read (struct objfile *, int);
+
+static void dst_symfile_finish (struct objfile *);
+
+static void dst_end_symtab (struct objfile *);
+
+static void complete_symtab (char *, CORE_ADDR, unsigned int);
+
+static void dst_start_symtab (void);
+
+static void dst_record_line (int, CORE_ADDR);
+
+/* Manage the vector of line numbers. */
+/* FIXME: Use record_line instead. */
+
+static void
+dst_record_line (int line, CORE_ADDR pc)
+{
+ struct linetable_entry *e;
+ /* Make sure line vector is big enough. */
+
+ if (line_vector_index + 2 >= line_vector_length)
+ {
+ line_vector_length *= 2;
+ line_vector = (struct linetable *)
+ xrealloc ((char *) line_vector, sizeof (struct linetable)
+ + (line_vector_length
+ * sizeof (struct linetable_entry)));
+ }
+
+ e = line_vector->item + line_vector_index++;
+ e->line = line;
+ e->pc = pc;
+}
+
+/* Start a new symtab for a new source file.
+ It indicates the start of data for one original source file. */
+/* FIXME: use start_symtab, like coffread.c now does. */
+
+static void
+dst_start_symtab (void)
+{
+ /* Initialize the source file line number information for this file. */
+
+ if (line_vector) /* Unlikely, but maybe possible? */
+ xfree (line_vector);
+ line_vector_index = 0;
+ line_vector_length = 1000;
+ prev_line_number = -2; /* Force first line number to be explicit */
+ line_vector = (struct linetable *)
+ xmalloc (sizeof (struct linetable)
+ + line_vector_length * sizeof (struct linetable_entry));
+}
+
+/* Save the vital information from when starting to read a file,
+ for use when closing off the current file.
+ NAME is the file name the symbols came from, START_ADDR is the first
+ text address for the file, and SIZE is the number of bytes of text. */
+
+static void
+complete_symtab (char *name, CORE_ADDR start_addr, unsigned int size)
+{
+ last_source_file = savestring (name, strlen (name));
+ cur_src_start_addr = start_addr;
+ cur_src_end_addr = start_addr + size;
+
+ if (current_objfile->ei.entry_point >= cur_src_start_addr &&
+ current_objfile->ei.entry_point < cur_src_end_addr)
+ {
+ current_objfile->ei.entry_file_lowpc = cur_src_start_addr;
+ current_objfile->ei.entry_file_highpc = cur_src_end_addr;
+ }
+}
+
+/* Finish the symbol definitions for one main source file,
+ close off all the lexical contexts for that file
+ (creating struct block's for them), then make the
+ struct symtab for that file and put it in the list of all such. */
+/* FIXME: Use end_symtab, like coffread.c now does. */
+
+static void
+dst_end_symtab (struct objfile *objfile)
+{
+ register struct symtab *symtab;
+ register struct blockvector *blockvector;
+ register struct linetable *lv;
+
+ /* Create the blockvector that points to all the file's blocks. */
+
+ blockvector = make_blockvector (objfile);
+
+ /* Now create the symtab object for this source file. */
+ symtab = allocate_symtab (last_source_file, objfile);
+
+ /* Fill in its components. */
+ symtab->blockvector = blockvector;
+ symtab->free_code = free_linetable;
+ symtab->free_ptr = 0;
+ symtab->filename = last_source_file;
+ symtab->dirname = NULL;
+ symtab->debugformat = obsavestring ("Apollo DST", 10,
+ &objfile->symbol_obstack);
+ lv = line_vector;
+ lv->nitems = line_vector_index;
+ symtab->linetable = (struct linetable *)
+ xrealloc ((char *) lv, (sizeof (struct linetable)
+ + lv->nitems * sizeof (struct linetable_entry)));
+
+ free_named_symtabs (symtab->filename);
+
+ /* Reinitialize for beginning of new file. */
+ line_vector = 0;
+ line_vector_length = -1;
+ last_source_file = NULL;
+}
+
+/* dst_symfile_init ()
+ is the dst-specific initialization routine for reading symbols.
+
+ We will only be called if this is a DST or DST-like file.
+ BFD handles figuring out the format of the file, and code in symtab.c
+ uses BFD's determination to vector to us.
+
+ The ultimate result is a new symtab (or, FIXME, eventually a psymtab). */
+
+static void
+dst_symfile_init (struct objfile *objfile)
+{
+ asection *section;
+ bfd *abfd = objfile->obfd;
+
+ init_entry_point_info (objfile);
+
+}
+
+/* This function is called for every section; it finds the outer limits
+ of the line table (minimum and maximum file offset) so that the
+ mainline code can read the whole thing for efficiency. */
+
+/* ARGSUSED */
+static void
+find_dst_sections (bfd *abfd, sec_ptr asect, PTR vpinfo)
+{
+ int size, count;
+ long base;
+ file_ptr offset, maxoff;
+ dst_sec *section;
+
+/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
+ size = asect->_raw_size;
+ offset = asect->filepos;
+ base = asect->vma;
+/* End of warning */
+
+ section = NULL;
+ if (!strcmp (asect->name, ".blocks"))
+ section = &blocks_info;
+ else if (!strcmp (asect->name, ".lines"))
+ section = &lines_info;
+ else if (!strcmp (asect->name, ".symbols"))
+ section = &symbols_info;
+ if (!section)
+ return;
+ section->size = size;
+ section->position = offset;
+ section->base = base;
+}
+
+
+/* The BFD for this file -- only good while we're actively reading
+ symbols into a psymtab or a symtab. */
+
+static bfd *symfile_bfd;
+
+/* Read a symbol file, after initialization by dst_symfile_init. */
+/* FIXME! Addr and Mainline are not used yet -- this will not work for
+ shared libraries or add_file! */
+
+/* ARGSUSED */
+static void
+dst_symfile_read (struct objfile *objfile, int mainline)
+{
+ bfd *abfd = objfile->obfd;
+ char *name = bfd_get_filename (abfd);
+ int desc;
+ register int val;
+ int num_symbols;
+ int symtab_offset;
+ int stringtab_offset;
+
+ symfile_bfd = abfd; /* Kludge for swap routines */
+
+/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
+ desc = fileno ((FILE *) (abfd->iostream)); /* File descriptor */
+
+ /* Read the line number table, all at once. */
+ bfd_map_over_sections (abfd, find_dst_sections, (PTR) NULL);
+
+ val = init_dst_sections (desc);
+ if (val < 0)
+ error ("\"%s\": error reading debugging symbol tables\n", name);
+
+ init_minimal_symbol_collection ();
+ make_cleanup_discard_minimal_symbols ();
+
+ /* Now that the executable file is positioned at symbol table,
+ process it and define symbols accordingly. */
+
+ read_dst_symtab (objfile);
+
+ /* Sort symbols alphabetically within each block. */
+
+ {
+ struct symtab *s;
+ for (s = objfile->symtabs; s != NULL; s = s->next)
+ {
+ sort_symtab_syms (s);
+ }
+ }
+
+ /* Install any minimal symbols that have been collected as the current
+ minimal symbols for this objfile. */
+
+ install_minimal_symbols (objfile);
+}
+
+static void
+dst_new_init (struct objfile *ignore)
+{
+ /* Nothin' to do */
+}
+
+/* Perform any local cleanups required when we are done with a particular
+ objfile. I.E, we are in the process of discarding all symbol information
+ for an objfile, freeing up all memory held for it, and unlinking the
+ objfile struct from the global list of known objfiles. */
+
+static void
+dst_symfile_finish (struct objfile *objfile)
+{
+ /* Nothing to do */
+}
+
+
+/* Get the next line number from the DST. Returns 0 when we hit an
+ * end directive or cannot continue for any other reason.
+ *
+ * Note that ordinary pc deltas are multiplied by two. Apparently
+ * this is what was really intended.
+ */
+static int
+get_dst_line (signed char **buffer, long *pc)
+{
+ static last_pc = 0;
+ static long last_line = 0;
+ static int last_file = 0;
+ dst_ln_entry_ptr_t entry;
+ int size;
+ dst_src_loc_t *src_loc;
+
+ if (*pc != -1)
+ {
+ last_pc = *pc;
+ *pc = -1;
+ }
+ entry = (dst_ln_entry_ptr_t) * buffer;
+
+ while (dst_ln_ln_delta (*entry) == dst_ln_escape_flag)
+ {
+ switch (entry->esc.esc_code)
+ {
+ case dst_ln_pad:
+ size = 1; /* pad byte */
+ break;
+ case dst_ln_file:
+ /* file escape. Next 4 bytes are a dst_src_loc_t */
+ size = 5;
+ src_loc = (dst_src_loc_t *) (*buffer + 1);
+ last_line = src_loc->line_number;
+ last_file = src_loc->file_index;
+ break;
+ case dst_ln_dln1_dpc1:
+ /* 1 byte line delta, 1 byte pc delta */
+ last_line += (*buffer)[1];
+ last_pc += 2 * (unsigned char) (*buffer)[2];
+ dst_record_line (last_line, last_pc);
+ size = 3;
+ break;
+ case dst_ln_dln2_dpc2:
+ /* 2 bytes line delta, 2 bytes pc delta */
+ last_line += *(short *) (*buffer + 1);
+ last_pc += 2 * (*(short *) (*buffer + 3));
+ size = 5;
+ dst_record_line (last_line, last_pc);
+ break;
+ case dst_ln_ln4_pc4:
+ /* 4 bytes ABSOLUTE line number, 4 bytes ABSOLUTE pc */
+ last_line = *(unsigned long *) (*buffer + 1);
+ last_pc = *(unsigned long *) (*buffer + 5);
+ size = 9;
+ dst_record_line (last_line, last_pc);
+ break;
+ case dst_ln_dln1_dpc0:
+ /* 1 byte line delta, pc delta = 0 */
+ size = 2;
+ last_line += (*buffer)[1];
+ break;
+ case dst_ln_ln_off_1:
+ /* statement escape, stmt # = 1 (2nd stmt on line) */
+ size = 1;
+ break;
+ case dst_ln_ln_off:
+ /* statement escape, stmt # = next byte */
+ size = 2;
+ break;
+ case dst_ln_entry:
+ /* entry escape, next byte is entry number */
+ size = 2;
+ break;
+ case dst_ln_exit:
+ /* exit escape */
+ size = 1;
+ break;
+ case dst_ln_stmt_end:
+ /* gap escape, 4 bytes pc delta */
+ size = 5;
+ /* last_pc += 2 * (*(long *) (*buffer + 1)); */
+ /* Apparently this isn't supposed to actually modify
+ * the pc value. Totally weird.
+ */
+ break;
+ case dst_ln_escape_11:
+ case dst_ln_escape_12:
+ case dst_ln_escape_13:
+ size = 1;
+ break;
+ case dst_ln_nxt_byte:
+ /* This shouldn't happen. If it does, we're SOL */
+ return 0;
+ break;
+ case dst_ln_end:
+ /* end escape, final entry follows */
+ return 0;
+ }
+ *buffer += (size < 0) ? -size : size;
+ entry = (dst_ln_entry_ptr_t) * buffer;
+ }
+ last_line += dst_ln_ln_delta (*entry);
+ last_pc += entry->delta.pc_delta * 2;
+ (*buffer)++;
+ dst_record_line (last_line, last_pc);
+ return 1;
+}
+
+static void
+enter_all_lines (char *buffer, long address)
+{
+ if (buffer)
+ while (get_dst_line (&buffer, &address));
+}
+
+static int
+get_dst_entry (char *buffer, dst_rec_ptr_t *ret_entry)
+{
+ int size;
+ dst_rec_ptr_t entry;
+ static int last_type;
+ int ar_size;
+ static unsigned lu3;
+
+ entry = (dst_rec_ptr_t) buffer;
+ switch (entry->rec_type)
+ {
+ case dst_typ_pad:
+ size = 0;
+ break;
+ case dst_typ_comp_unit:
+ size = sizeof (DST_comp_unit (entry));
+ break;
+ case dst_typ_section_tab:
+ size = sizeof (DST_section_tab (entry))
+ + ((int) DST_section_tab (entry).number_of_sections
+ - dst_dummy_array_size) * sizeof (long);
+ break;
+ case dst_typ_file_tab:
+ size = sizeof (DST_file_tab (entry))
+ + ((int) DST_file_tab (entry).number_of_files
+ - dst_dummy_array_size) * sizeof (dst_file_desc_t);
+ break;
+ case dst_typ_block:
+ size = sizeof (DST_block (entry))
+ + ((int) DST_block (entry).n_of_code_ranges
+ - dst_dummy_array_size) * sizeof (dst_code_range_t);
+ break;
+ case dst_typ_5:
+ size = -1;
+ break;
+ case dst_typ_var:
+ size = sizeof (DST_var (entry)) -
+ sizeof (dst_var_loc_long_t) * dst_dummy_array_size +
+ DST_var (entry).no_of_locs *
+ (DST_var (entry).short_locs ?
+ sizeof (dst_var_loc_short_t) :
+ sizeof (dst_var_loc_long_t));
+ break;
+ case dst_typ_pointer:
+ size = sizeof (DST_pointer (entry));
+ break;
+ case dst_typ_array:
+ size = sizeof (DST_array (entry));
+ break;
+ case dst_typ_subrange:
+ size = sizeof (DST_subrange (entry));
+ break;
+ case dst_typ_set:
+ size = sizeof (DST_set (entry));
+ break;
+ case dst_typ_implicit_enum:
+ size = sizeof (DST_implicit_enum (entry))
+ + ((int) DST_implicit_enum (entry).nelems
+ - dst_dummy_array_size) * sizeof (dst_rel_offset_t);
+ break;
+ case dst_typ_explicit_enum:
+ size = sizeof (DST_explicit_enum (entry))
+ + ((int) DST_explicit_enum (entry).nelems
+ - dst_dummy_array_size) * sizeof (dst_enum_elem_t);
+ break;
+ case dst_typ_short_rec:
+ size = sizeof (DST_short_rec (entry))
+ + DST_short_rec (entry).nfields * sizeof (dst_short_field_t)
+ - dst_dummy_array_size * sizeof (dst_field_t);
+ break;
+ case dst_typ_short_union:
+ size = sizeof (DST_short_union (entry))
+ + DST_short_union (entry).nfields * sizeof (dst_short_field_t)
+ - dst_dummy_array_size * sizeof (dst_field_t);
+ break;
+ case dst_typ_file:
+ size = sizeof (DST_file (entry));
+ break;
+ case dst_typ_offset:
+ size = sizeof (DST_offset (entry));
+ break;
+ case dst_typ_alias:
+ size = sizeof (DST_alias (entry));
+ break;
+ case dst_typ_signature:
+ size = sizeof (DST_signature (entry)) +
+ ((int) DST_signature (entry).nargs -
+ dst_dummy_array_size) * sizeof (dst_arg_t);
+ break;
+ case dst_typ_21:
+ size = -1;
+ break;
+ case dst_typ_old_label:
+ size = sizeof (DST_old_label (entry));
+ break;
+ case dst_typ_scope:
+ size = sizeof (DST_scope (entry));
+ break;
+ case dst_typ_end_scope:
+ size = 0;
+ break;
+ case dst_typ_25:
+ case dst_typ_26:
+ size = -1;
+ break;
+ case dst_typ_string_tab:
+ case dst_typ_global_name_tab:
+ size = sizeof (DST_string_tab (entry))
+ + DST_string_tab (entry).length
+ - dst_dummy_array_size;
+ break;
+ case dst_typ_forward:
+ size = sizeof (DST_forward (entry));
+ get_dst_entry ((char *) entry + DST_forward (entry).rec_off, &entry);
+ break;
+ case dst_typ_aux_size:
+ size = sizeof (DST_aux_size (entry));
+ break;
+ case dst_typ_aux_align:
+ size = sizeof (DST_aux_align (entry));
+ break;
+ case dst_typ_aux_field_size:
+ size = sizeof (DST_aux_field_size (entry));
+ break;
+ case dst_typ_aux_field_off:
+ size = sizeof (DST_aux_field_off (entry));
+ break;
+ case dst_typ_aux_field_align:
+ size = sizeof (DST_aux_field_align (entry));
+ break;
+ case dst_typ_aux_qual:
+ size = sizeof (DST_aux_qual (entry));
+ break;
+ case dst_typ_aux_var_bound:
+ size = sizeof (DST_aux_var_bound (entry));
+ break;
+ case dst_typ_extension:
+ size = DST_extension (entry).rec_size;
+ break;
+ case dst_typ_string:
+ size = sizeof (DST_string (entry));
+ break;
+ case dst_typ_old_entry:
+ size = 48; /* Obsolete entry type */
+ break;
+ case dst_typ_const:
+ size = sizeof (DST_const (entry))
+ + DST_const (entry).value.length
+ - sizeof (DST_const (entry).value.val);
+ break;
+ case dst_typ_reference:
+ size = sizeof (DST_reference (entry));
+ break;
+ case dst_typ_old_record:
+ case dst_typ_old_union:
+ case dst_typ_record:
+ case dst_typ_union:
+ size = sizeof (DST_record (entry))
+ + ((int) DST_record (entry).nfields
+ - dst_dummy_array_size) * sizeof (dst_field_t);
+ break;
+ case dst_typ_aux_type_deriv:
+ size = sizeof (DST_aux_type_deriv (entry));
+ break;
+ case dst_typ_locpool:
+ size = sizeof (DST_locpool (entry))
+ + ((int) DST_locpool (entry).length -
+ dst_dummy_array_size);
+ break;
+ case dst_typ_variable:
+ size = sizeof (DST_variable (entry));
+ break;
+ case dst_typ_label:
+ size = sizeof (DST_label (entry));
+ break;
+ case dst_typ_entry:
+ size = sizeof (DST_entry (entry));
+ break;
+ case dst_typ_aux_lifetime:
+ size = sizeof (DST_aux_lifetime (entry));
+ break;
+ case dst_typ_aux_ptr_base:
+ size = sizeof (DST_aux_ptr_base (entry));
+ break;
+ case dst_typ_aux_src_range:
+ size = sizeof (DST_aux_src_range (entry));
+ break;
+ case dst_typ_aux_reg_val:
+ size = sizeof (DST_aux_reg_val (entry));
+ break;
+ case dst_typ_aux_unit_names:
+ size = sizeof (DST_aux_unit_names (entry))
+ + ((int) DST_aux_unit_names (entry).number_of_names
+ - dst_dummy_array_size) * sizeof (dst_rel_offset_t);
+ break;
+ case dst_typ_aux_sect_info:
+ size = sizeof (DST_aux_sect_info (entry))
+ + ((int) DST_aux_sect_info (entry).number_of_refs
+ - dst_dummy_array_size) * sizeof (dst_sect_ref_t);
+ break;
+ default:
+ size = -1;
+ break;
+ }
+ if (size == -1)
+ {
+ fprintf_unfiltered (gdb_stderr, "Warning: unexpected DST entry type (%d) found\nLast valid entry was of type: %d\n",
+ (int) entry->rec_type,
+ last_type);
+ fprintf_unfiltered (gdb_stderr, "Last unknown_3 value: %d\n", lu3);
+ size = 0;
+ }
+ else
+ last_type = entry->rec_type;
+ if (size & 1) /* Align on a word boundary */
+ size++;
+ size += 2;
+ *ret_entry = entry;
+ return size;
+}
+
+static int
+next_dst_entry (char **buffer, dst_rec_ptr_t *entry, dst_sec *table)
+{
+ if (*buffer - table->buffer >= table->size)
+ {
+ *entry = NULL;
+ return 0;
+ }
+ *buffer += get_dst_entry (*buffer, entry);
+ return 1;
+}
+
+#define NEXT_BLK(a, b) next_dst_entry(a, b, &blocks_info)
+#define NEXT_SYM(a, b) next_dst_entry(a, b, &symbols_info)
+#define DST_OFFSET(a, b) ((char *) (a) + (b))
+
+static dst_rec_ptr_t section_table = NULL;
+
+char *
+get_sec_ref (dst_sect_ref_t *ref)
+{
+ dst_sec *section = NULL;
+ long offset;
+
+ if (!section_table || !ref->sect_index)
+ return NULL;
+ offset = DST_section_tab (section_table).section_base[ref->sect_index - 1]
+ + ref->sect_offset;
+ if (offset >= blocks_info.base &&
+ offset < blocks_info.base + blocks_info.size)
+ section = &blocks_info;
+ else if (offset >= symbols_info.base &&
+ offset < symbols_info.base + symbols_info.size)
+ section = &symbols_info;
+ else if (offset >= lines_info.base &&
+ offset < lines_info.base + lines_info.size)
+ section = &lines_info;
+ if (!section)
+ return NULL;
+ return section->buffer + (offset - section->base);
+}
+
+CORE_ADDR
+dst_get_addr (int section, long offset)
+{
+ if (!section_table || !section)
+ return 0;
+ return DST_section_tab (section_table).section_base[section - 1] + offset;
+}
+
+CORE_ADDR
+dst_sym_addr (dst_sect_ref_t *ref)
+{
+ if (!section_table || !ref->sect_index)
+ return 0;
+ return DST_section_tab (section_table).section_base[ref->sect_index - 1]
+ + ref->sect_offset;
+}
+
+static struct symbol *
+create_new_symbol (struct objfile *objfile, char *name)
+{
+ struct symbol *sym = (struct symbol *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+ &objfile->symbol_obstack);
+ SYMBOL_VALUE (sym) = 0;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+ return sym;
+};
+
+static struct type *decode_dst_type (struct objfile *, dst_rec_ptr_t);
+
+static struct type *
+decode_type_desc (struct objfile *objfile, dst_type_t *type_desc,
+ dst_rec_ptr_t base)
+{
+ struct type *type;
+ dst_rec_ptr_t entry;
+ if (type_desc->std_type.user_defined_type)
+ {
+ entry = (dst_rec_ptr_t) DST_OFFSET (base,
+ dst_user_type_offset (*type_desc));
+ type = decode_dst_type (objfile, entry);
+ }
+ else
+ {
+ switch (type_desc->std_type.dtc)
+ {
+ case dst_int8_type:
+ type = builtin_type_signed_char;
+ break;
+ case dst_int16_type:
+ type = builtin_type_short;
+ break;
+ case dst_int32_type:
+ type = builtin_type_long;
+ break;
+ case dst_uint8_type:
+ type = builtin_type_unsigned_char;
+ break;
+ case dst_uint16_type:
+ type = builtin_type_unsigned_short;
+ break;
+ case dst_uint32_type:
+ type = builtin_type_unsigned_long;
+ break;
+ case dst_real32_type:
+ type = builtin_type_float;
+ break;
+ case dst_real64_type:
+ type = builtin_type_double;
+ break;
+ case dst_complex_type:
+ type = builtin_type_complex;
+ break;
+ case dst_dcomplex_type:
+ type = builtin_type_double_complex;
+ break;
+ case dst_bool8_type:
+ type = builtin_type_char;
+ break;
+ case dst_bool16_type:
+ type = builtin_type_short;
+ break;
+ case dst_bool32_type:
+ type = builtin_type_long;
+ break;
+ case dst_char_type:
+ type = builtin_type_char;
+ break;
+ /* The next few are more complex. I will take care
+ * of them properly at a later point.
+ */
+ case dst_string_type:
+ type = builtin_type_void;
+ break;
+ case dst_ptr_type:
+ type = builtin_type_void;
+ break;
+ case dst_set_type:
+ type = builtin_type_void;
+ break;
+ case dst_proc_type:
+ type = builtin_type_void;
+ break;
+ case dst_func_type:
+ type = builtin_type_void;
+ break;
+ /* Back tto some ordinary ones */
+ case dst_void_type:
+ type = builtin_type_void;
+ break;
+ case dst_uchar_type:
+ type = builtin_type_unsigned_char;
+ break;
+ default:
+ type = builtin_type_void;
+ break;
+ }
+ }
+ return type;
+}
+
+struct structure_list
+{
+ struct structure_list *next;
+ struct type *type;
+};
+
+static struct structure_list *struct_list = NULL;
+
+static struct type *
+find_dst_structure (char *name)
+{
+ struct structure_list *element;
+
+ for (element = struct_list; element; element = element->next)
+ if (!strcmp (name, TYPE_NAME (element->type)))
+ return element->type;
+ return NULL;
+}
+
+
+static struct type *
+decode_dst_structure (struct objfile *objfile, dst_rec_ptr_t entry, int code,
+ int version)
+{
+ struct type *type, *child_type;
+ char *struct_name;
+ char *name, *field_name;
+ int i;
+ int fieldoffset, fieldsize;
+ dst_type_t type_desc;
+ struct structure_list *element;
+
+ struct_name = DST_OFFSET (entry, DST_record (entry).noffset);
+ name = concat ((code == TYPE_CODE_UNION) ? "union " : "struct ",
+ struct_name, NULL);
+ type = find_dst_structure (name);
+ if (type)
+ {
+ xfree (name);
+ return type;
+ }
+ type = alloc_type (objfile);
+ TYPE_NAME (type) = obstack_copy0 (&objfile->symbol_obstack,
+ name, strlen (name));
+ xfree (name);
+ TYPE_CODE (type) = code;
+ TYPE_LENGTH (type) = DST_record (entry).size;
+ TYPE_NFIELDS (type) = DST_record (entry).nfields;
+ TYPE_FIELDS (type) = (struct field *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct field) *
+ DST_record (entry).nfields);
+ fieldoffset = fieldsize = 0;
+ INIT_CPLUS_SPECIFIC (type);
+ element = (struct structure_list *)
+ xmalloc (sizeof (struct structure_list));
+ element->type = type;
+ element->next = struct_list;
+ struct_list = element;
+ for (i = 0; i < DST_record (entry).nfields; i++)
+ {
+ switch (version)
+ {
+ case 2:
+ field_name = DST_OFFSET (entry,
+ DST_record (entry).f.ofields[i].noffset);
+ fieldoffset = DST_record (entry).f.ofields[i].foffset * 8 +
+ DST_record (entry).f.ofields[i].bit_offset;
+ fieldsize = DST_record (entry).f.ofields[i].size;
+ type_desc = DST_record (entry).f.ofields[i].type_desc;
+ break;
+ case 1:
+ field_name = DST_OFFSET (entry,
+ DST_record (entry).f.fields[i].noffset);
+ type_desc = DST_record (entry).f.fields[i].type_desc;
+ switch (DST_record (entry).f.fields[i].f.field_loc.format_tag)
+ {
+ case dst_field_byte:
+ fieldoffset = DST_record (entry).f.
+ fields[i].f.field_byte.offset * 8;
+ fieldsize = -1;
+ break;
+ case dst_field_bit:
+ fieldoffset = DST_record (entry).f.
+ fields[i].f.field_bit.byte_offset * 8 +
+ DST_record (entry).f.
+ fields[i].f.field_bit.bit_offset;
+ fieldsize = DST_record (entry).f.
+ fields[i].f.field_bit.nbits;
+ break;
+ case dst_field_loc:
+ fieldoffset += fieldsize;
+ fieldsize = -1;
+ break;
+ }
+ break;
+ case 0:
+ field_name = DST_OFFSET (entry,
+ DST_record (entry).f.sfields[i].noffset);
+ fieldoffset = DST_record (entry).f.sfields[i].foffset;
+ type_desc = DST_record (entry).f.sfields[i].type_desc;
+ if (i < DST_record (entry).nfields - 1)
+ fieldsize = DST_record (entry).f.sfields[i + 1].foffset;
+ else
+ fieldsize = DST_record (entry).size;
+ fieldsize -= fieldoffset;
+ fieldoffset *= 8;
+ fieldsize *= 8;
+ }
+ TYPE_FIELDS (type)[i].name =
+ obstack_copy0 (&objfile->symbol_obstack,
+ field_name, strlen (field_name));
+ TYPE_FIELDS (type)[i].type = decode_type_desc (objfile,
+ &type_desc,
+ entry);
+ if (fieldsize == -1)
+ fieldsize = TYPE_LENGTH (TYPE_FIELDS (type)[i].type) *
+ 8;
+ TYPE_FIELDS (type)[i].bitsize = fieldsize;
+ TYPE_FIELDS (type)[i].bitpos = fieldoffset;
+ }
+ return type;
+}
+
+static struct type *
+decode_dst_type (struct objfile *objfile, dst_rec_ptr_t entry)
+{
+ struct type *child_type, *type, *range_type, *index_type;
+
+ switch (entry->rec_type)
+ {
+ case dst_typ_var:
+ return decode_type_desc (objfile,
+ &DST_var (entry).type_desc,
+ entry);
+ break;
+ case dst_typ_variable:
+ return decode_type_desc (objfile,
+ &DST_variable (entry).type_desc,
+ entry);
+ break;
+ case dst_typ_short_rec:
+ return decode_dst_structure (objfile, entry, TYPE_CODE_STRUCT, 0);
+ case dst_typ_short_union:
+ return decode_dst_structure (objfile, entry, TYPE_CODE_UNION, 0);
+ case dst_typ_union:
+ return decode_dst_structure (objfile, entry, TYPE_CODE_UNION, 1);
+ case dst_typ_record:
+ return decode_dst_structure (objfile, entry, TYPE_CODE_STRUCT, 1);
+ case dst_typ_old_union:
+ return decode_dst_structure (objfile, entry, TYPE_CODE_UNION, 2);
+ case dst_typ_old_record:
+ return decode_dst_structure (objfile, entry, TYPE_CODE_STRUCT, 2);
+ case dst_typ_pointer:
+ return make_pointer_type (
+ decode_type_desc (objfile,
+ &DST_pointer (entry).type_desc,
+ entry),
+ NULL);
+ case dst_typ_array:
+ child_type = decode_type_desc (objfile,
+ &DST_pointer (entry).type_desc,
+ entry);
+ index_type = lookup_fundamental_type (objfile,
+ FT_INTEGER);
+ range_type = create_range_type ((struct type *) NULL,
+ index_type, DST_array (entry).lo_bound,
+ DST_array (entry).hi_bound);
+ return create_array_type ((struct type *) NULL, child_type,
+ range_type);
+ case dst_typ_alias:
+ return decode_type_desc (objfile,
+ &DST_alias (entry).type_desc,
+ entry);
+ default:
+ return builtin_type_int;
+ }
+}
+
+struct symbol_list
+{
+ struct symbol_list *next;
+ struct symbol *symbol;
+};
+
+static struct symbol_list *dst_global_symbols = NULL;
+static int total_globals = 0;
+
+static void
+decode_dst_locstring (char *locstr, struct symbol *sym)
+{
+ dst_loc_entry_t *entry, *next_entry;
+ CORE_ADDR temp;
+ int count = 0;
+
+ while (1)
+ {
+ if (count++ == 100)
+ {
+ fprintf_unfiltered (gdb_stderr, "Error reading locstring\n");
+ break;
+ }
+ entry = (dst_loc_entry_t *) locstr;
+ next_entry = (dst_loc_entry_t *) (locstr + 1);
+ switch (entry->header.code)
+ {
+ case dst_lsc_end: /* End of string */
+ return;
+ case dst_lsc_indirect: /* Indirect through previous. Arg == 6 */
+ /* Or register ax x == arg */
+ if (entry->header.arg < 6)
+ {
+ SYMBOL_CLASS (sym) = LOC_REGISTER;
+ SYMBOL_VALUE (sym) = entry->header.arg + 8;
+ }
+ /* We predict indirects */
+ locstr++;
+ break;
+ case dst_lsc_dreg:
+ SYMBOL_CLASS (sym) = LOC_REGISTER;
+ SYMBOL_VALUE (sym) = entry->header.arg;
+ locstr++;
+ break;
+ case dst_lsc_section: /* Section (arg+1) */
+ SYMBOL_VALUE (sym) = dst_get_addr (entry->header.arg + 1, 0);
+ locstr++;
+ break;
+ case dst_lsc_sec_byte: /* Section (next_byte+1) */
+ SYMBOL_VALUE (sym) = dst_get_addr (locstr[1] + 1, 0);
+ locstr += 2;
+ break;
+ case dst_lsc_add: /* Add (arg+1)*2 */
+ case dst_lsc_sub: /* Subtract (arg+1)*2 */
+ temp = (entry->header.arg + 1) * 2;
+ locstr++;
+ if (*locstr == dst_multiply_256)
+ {
+ temp <<= 8;
+ locstr++;
+ }
+ switch (entry->header.code)
+ {
+ case dst_lsc_add:
+ if (SYMBOL_CLASS (sym) == LOC_LOCAL)
+ SYMBOL_CLASS (sym) = LOC_ARG;
+ SYMBOL_VALUE (sym) += temp;
+ break;
+ case dst_lsc_sub:
+ SYMBOL_VALUE (sym) -= temp;
+ break;
+ }
+ break;
+ case dst_lsc_add_byte:
+ case dst_lsc_sub_byte:
+ switch (entry->header.arg & 0x03)
+ {
+ case 1:
+ temp = (unsigned char) locstr[1];
+ locstr += 2;
+ break;
+ case 2:
+ temp = *(unsigned short *) (locstr + 1);
+ locstr += 3;
+ break;
+ case 3:
+ temp = *(unsigned long *) (locstr + 1);
+ locstr += 5;
+ break;
+ }
+ if (*locstr == dst_multiply_256)
+ {
+ temp <<= 8;
+ locstr++;
+ }
+ switch (entry->header.code)
+ {
+ case dst_lsc_add_byte:
+ if (SYMBOL_CLASS (sym) == LOC_LOCAL)
+ SYMBOL_CLASS (sym) = LOC_ARG;
+ SYMBOL_VALUE (sym) += temp;
+ break;
+ case dst_lsc_sub_byte:
+ SYMBOL_VALUE (sym) -= temp;
+ break;
+ }
+ break;
+ case dst_lsc_sbreg: /* Stack base register (frame pointer). Arg==0 */
+ if (next_entry->header.code != dst_lsc_indirect)
+ {
+ SYMBOL_VALUE (sym) = 0;
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ return;
+ }
+ SYMBOL_VALUE (sym) = 0;
+ SYMBOL_CLASS (sym) = LOC_LOCAL;
+ locstr++;
+ break;
+ default:
+ SYMBOL_VALUE (sym) = 0;
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ return;
+ }
+ }
+}
+
+static struct symbol_list *
+process_dst_symbols (struct objfile *objfile, dst_rec_ptr_t entry, char *name,
+ int *nsyms_ret)
+{
+ struct symbol_list *list = NULL, *element;
+ struct symbol *sym;
+ char *symname;
+ int nsyms = 0;
+ char *location;
+ long line;
+ dst_type_t symtype;
+ struct type *type;
+ dst_var_attr_t attr;
+ dst_var_loc_t loc_type;
+ unsigned loc_index;
+ long loc_value;
+
+ if (!entry)
+ {
+ *nsyms_ret = 0;
+ return NULL;
+ }
+ location = (char *) entry;
+ while (NEXT_SYM (&location, &entry) &&
+ entry->rec_type != dst_typ_end_scope)
+ {
+ if (entry->rec_type == dst_typ_var)
+ {
+ if (DST_var (entry).short_locs)
+ {
+ loc_type = DST_var (entry).locs.shorts[0].loc_type;
+ loc_index = DST_var (entry).locs.shorts[0].loc_index;
+ loc_value = DST_var (entry).locs.shorts[0].location;
+ }
+ else
+ {
+ loc_type = DST_var (entry).locs.longs[0].loc_type;
+ loc_index = DST_var (entry).locs.longs[0].loc_index;
+ loc_value = DST_var (entry).locs.longs[0].location;
+ }
+ if (loc_type == dst_var_loc_external)
+ continue;
+ symname = DST_OFFSET (entry, DST_var (entry).noffset);
+ line = DST_var (entry).src_loc.line_number;
+ symtype = DST_var (entry).type_desc;
+ attr = DST_var (entry).attributes;
+ }
+ else if (entry->rec_type == dst_typ_variable)
+ {
+ symname = DST_OFFSET (entry,
+ DST_variable (entry).noffset);
+ line = DST_variable (entry).src_loc.line_number;
+ symtype = DST_variable (entry).type_desc;
+ attr = DST_variable (entry).attributes;
+ }
+ else
+ {
+ continue;
+ }
+ if (symname && name && !strcmp (symname, name))
+ /* It's the function return value */
+ continue;
+ sym = create_new_symbol (objfile, symname);
+
+ if ((attr & (1 << dst_var_attr_global)) ||
+ (attr & (1 << dst_var_attr_static)))
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ else
+ SYMBOL_CLASS (sym) = LOC_LOCAL;
+ SYMBOL_LINE (sym) = line;
+ SYMBOL_TYPE (sym) = decode_type_desc (objfile, &symtype,
+ entry);
+ SYMBOL_VALUE (sym) = 0;
+ switch (entry->rec_type)
+ {
+ case dst_typ_var:
+ switch (loc_type)
+ {
+ case dst_var_loc_abs:
+ SYMBOL_VALUE_ADDRESS (sym) = loc_value;
+ break;
+ case dst_var_loc_sect_off:
+ case dst_var_loc_ind_sect_off: /* What is this? */
+ SYMBOL_VALUE_ADDRESS (sym) = dst_get_addr (
+ loc_index,
+ loc_value);
+ break;
+ case dst_var_loc_ind_reg_rel: /* What is this? */
+ case dst_var_loc_reg_rel:
+ /* If it isn't fp relative, specify the
+ * register it's relative to.
+ */
+ if (loc_index)
+ {
+ sym->aux_value.basereg = loc_index;
+ }
+ SYMBOL_VALUE (sym) = loc_value;
+ if (loc_value > 0 &&
+ SYMBOL_CLASS (sym) == LOC_BASEREG)
+ SYMBOL_CLASS (sym) = LOC_BASEREG_ARG;
+ break;
+ case dst_var_loc_reg:
+ SYMBOL_VALUE (sym) = loc_index;
+ SYMBOL_CLASS (sym) = LOC_REGISTER;
+ break;
+ }
+ break;
+ case dst_typ_variable:
+ /* External variable..... don't try to interpret
+ * its nonexistant locstring.
+ */
+ if (DST_variable (entry).loffset == -1)
+ continue;
+ decode_dst_locstring (DST_OFFSET (entry,
+ DST_variable (entry).loffset),
+ sym);
+ }
+ element = (struct symbol_list *)
+ xmalloc (sizeof (struct symbol_list));
+
+ if (attr & (1 << dst_var_attr_global))
+ {
+ element->next = dst_global_symbols;
+ dst_global_symbols = element;
+ total_globals++;
+ }
+ else
+ {
+ element->next = list;
+ list = element;
+ nsyms++;
+ }
+ element->symbol = sym;
+ }
+ *nsyms_ret = nsyms;
+ return list;
+}
+
+
+static struct symbol *
+process_dst_function (struct objfile *objfile, dst_rec_ptr_t entry, char *name,
+ CORE_ADDR address)
+{
+ struct symbol *sym;
+ struct type *type, *ftype;
+ dst_rec_ptr_t sym_entry, typ_entry;
+ char *location;
+ struct symbol_list *element;
+
+ type = builtin_type_int;
+ sym = create_new_symbol (objfile, name);
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+
+ if (entry)
+ {
+ location = (char *) entry;
+ do
+ {
+ NEXT_SYM (&location, &sym_entry);
+ }
+ while (sym_entry && sym_entry->rec_type != dst_typ_signature);
+
+ if (sym_entry)
+ {
+ SYMBOL_LINE (sym) =
+ DST_signature (sym_entry).src_loc.line_number;
+ if (DST_signature (sym_entry).result)
+ {
+ typ_entry = (dst_rec_ptr_t)
+ DST_OFFSET (sym_entry,
+ DST_signature (sym_entry).result);
+ type = decode_dst_type (objfile, typ_entry);
+ }
+ }
+ }
+
+ if (!type->function_type)
+ {
+ ftype = alloc_type (objfile);
+ type->function_type = ftype;
+ TYPE_TARGET_TYPE (ftype) = type;
+ TYPE_CODE (ftype) = TYPE_CODE_FUNC;
+ }
+ SYMBOL_TYPE (sym) = type->function_type;
+
+ /* Now add ourselves to the global symbols list */
+ element = (struct symbol_list *)
+ xmalloc (sizeof (struct symbol_list));
+
+ element->next = dst_global_symbols;
+ dst_global_symbols = element;
+ total_globals++;
+ element->symbol = sym;
+
+ return sym;
+}
+
+static struct block *
+process_dst_block (struct objfile *objfile, dst_rec_ptr_t entry)
+{
+ struct block *block;
+ struct symbol *function = NULL;
+ CORE_ADDR address;
+ long size;
+ char *name;
+ dst_rec_ptr_t child_entry, symbol_entry;
+ struct block *child_block;
+ int total_symbols = 0;
+ char fake_name[20];
+ static long fake_seq = 0;
+ struct symbol_list *symlist, *nextsym;
+ int symnum;
+
+ if (DST_block (entry).noffset)
+ name = DST_OFFSET (entry, DST_block (entry).noffset);
+ else
+ name = NULL;
+ if (DST_block (entry).n_of_code_ranges)
+ {
+ address = dst_sym_addr (
+ &DST_block (entry).code_ranges[0].code_start);
+ size = DST_block (entry).code_ranges[0].code_size;
+ }
+ else
+ {
+ address = -1;
+ size = 0;
+ }
+ symbol_entry = (dst_rec_ptr_t) get_sec_ref (&DST_block (entry).symbols_start);
+ switch (DST_block (entry).block_type)
+ {
+ /* These are all really functions. Even the "program" type.
+ * This is because the Apollo OS was written in Pascal, and
+ * in Pascal, the main procedure is described as the Program.
+ * Cute, huh?
+ */
+ case dst_block_procedure:
+ case dst_block_function:
+ case dst_block_subroutine:
+ case dst_block_program:
+ prim_record_minimal_symbol (name, address, mst_text, objfile);
+ function = process_dst_function (
+ objfile,
+ symbol_entry,
+ name,
+ address);
+ enter_all_lines (get_sec_ref (&DST_block (entry).code_ranges[0].lines_start), address);
+ break;
+ case dst_block_block_data:
+ break;
+
+ default:
+ /* GDB has to call it something, and the module name
+ * won't cut it
+ */
+ sprintf (fake_name, "block_%08lx", fake_seq++);
+ function = process_dst_function (
+ objfile, NULL, fake_name, address);
+ break;
+ }
+ symlist = process_dst_symbols (objfile, symbol_entry,
+ name, &total_symbols);
+ block = (struct block *)
+ obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct block) +
+ (total_symbols - 1) * sizeof (struct symbol *));
+
+ symnum = 0;
+ while (symlist)
+ {
+ nextsym = symlist->next;
+
+ block->sym[symnum] = symlist->symbol;
+
+ xfree (symlist);
+ symlist = nextsym;
+ symnum++;
+ }
+ BLOCK_NSYMS (block) = total_symbols;
+ BLOCK_START (block) = address;
+ BLOCK_END (block) = address + size;
+ BLOCK_SUPERBLOCK (block) = 0;
+ if (function)
+ {
+ SYMBOL_BLOCK_VALUE (function) = block;
+ BLOCK_FUNCTION (block) = function;
+ }
+ else
+ BLOCK_FUNCTION (block) = 0;
+
+ if (DST_block (entry).child_block_off)
+ {
+ child_entry = (dst_rec_ptr_t) DST_OFFSET (entry,
+ DST_block (entry).child_block_off);
+ while (child_entry)
+ {
+ child_block = process_dst_block (objfile, child_entry);
+ if (child_block)
+ {
+ if (BLOCK_START (child_block) <
+ BLOCK_START (block) ||
+ BLOCK_START (block) == -1)
+ BLOCK_START (block) =
+ BLOCK_START (child_block);
+ if (BLOCK_END (child_block) >
+ BLOCK_END (block) ||
+ BLOCK_END (block) == -1)
+ BLOCK_END (block) =
+ BLOCK_END (child_block);
+ BLOCK_SUPERBLOCK (child_block) = block;
+ }
+ if (DST_block (child_entry).sibling_block_off)
+ child_entry = (dst_rec_ptr_t) DST_OFFSET (
+ child_entry,
+ DST_block (child_entry).sibling_block_off);
+ else
+ child_entry = NULL;
+ }
+ }
+ record_pending_block (objfile, block, NULL);
+ return block;
+}
+
+
+static void
+read_dst_symtab (struct objfile *objfile)
+{
+ char *buffer;
+ dst_rec_ptr_t entry, file_table, root_block;
+ char *source_file;
+ struct block *block, *global_block;
+ int symnum;
+ struct symbol_list *nextsym;
+ int module_num = 0;
+ struct structure_list *element;
+
+ current_objfile = objfile;
+ buffer = blocks_info.buffer;
+ while (NEXT_BLK (&buffer, &entry))
+ {
+ if (entry->rec_type == dst_typ_comp_unit)
+ {
+ file_table = (dst_rec_ptr_t) DST_OFFSET (entry,
+ DST_comp_unit (entry).file_table);
+ section_table = (dst_rec_ptr_t) DST_OFFSET (entry,
+ DST_comp_unit (entry).section_table);
+ root_block = (dst_rec_ptr_t) DST_OFFSET (entry,
+ DST_comp_unit (entry).root_block_offset);
+ source_file = DST_OFFSET (file_table,
+ DST_file_tab (file_table).files[0].noffset);
+ /* Point buffer to the start of the next comp_unit */
+ buffer = DST_OFFSET (entry,
+ DST_comp_unit (entry).data_size);
+ dst_start_symtab ();
+
+ block = process_dst_block (objfile, root_block);
+
+ global_block = (struct block *)
+ obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct block) +
+ (total_globals - 1) *
+ sizeof (struct symbol *));
+ BLOCK_NSYMS (global_block) = total_globals;
+ for (symnum = 0; symnum < total_globals; symnum++)
+ {
+ nextsym = dst_global_symbols->next;
+
+ global_block->sym[symnum] =
+ dst_global_symbols->symbol;
+
+ xfree (dst_global_symbols);
+ dst_global_symbols = nextsym;
+ }
+ dst_global_symbols = NULL;
+ total_globals = 0;
+ BLOCK_FUNCTION (global_block) = 0;
+ BLOCK_START (global_block) = BLOCK_START (block);
+ BLOCK_END (global_block) = BLOCK_END (block);
+ BLOCK_SUPERBLOCK (global_block) = 0;
+ BLOCK_SUPERBLOCK (block) = global_block;
+ record_pending_block (objfile, global_block, NULL);
+
+ complete_symtab (source_file,
+ BLOCK_START (block),
+ BLOCK_END (block) - BLOCK_START (block));
+ module_num++;
+ dst_end_symtab (objfile);
+ }
+ }
+ if (module_num)
+ prim_record_minimal_symbol ("<end_of_program>",
+ BLOCK_END (block), mst_text, objfile);
+ /* One more faked symbol to make sure nothing can ever run off the
+ * end of the symbol table. This one represents the end of the
+ * text space. It used to be (CORE_ADDR) -1 (effectively the highest
+ * int possible), but some parts of gdb treated it as a signed
+ * number and failed comparisons. We could equally use 7fffffff,
+ * but no functions are ever mapped to an address higher than
+ * 40000000
+ */
+ prim_record_minimal_symbol ("<end_of_text>",
+ (CORE_ADDR) 0x40000000,
+ mst_text, objfile);
+ while (struct_list)
+ {
+ element = struct_list;
+ struct_list = element->next;
+ xfree (element);
+ }
+}
+
+
+/* Support for line number handling */
+static char *linetab = NULL;
+static long linetab_offset;
+static unsigned long linetab_size;
+
+/* Read in all the line numbers for fast lookups later. Leave them in
+ external (unswapped) format in memory; we'll swap them as we enter
+ them into GDB's data structures. */
+static int
+init_one_section (int chan, dst_sec *secinfo)
+{
+ if (secinfo->size == 0
+ || lseek (chan, secinfo->position, 0) == -1
+ || (secinfo->buffer = xmalloc (secinfo->size)) == NULL
+ || myread (chan, secinfo->buffer, secinfo->size) == -1)
+ return 0;
+ else
+ return 1;
+}
+
+static int
+init_dst_sections (int chan)
+{
+
+ if (!init_one_section (chan, &blocks_info) ||
+ !init_one_section (chan, &lines_info) ||
+ !init_one_section (chan, &symbols_info))
+ return -1;
+ else
+ return 0;
+}
+
+/* Fake up support for relocating symbol addresses. FIXME. */
+
+struct section_offsets dst_symfile_faker =
+{0};
+
+void
+dst_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs)
+{
+ objfile->num_sections = 1;
+ objfile->section_offsets = &dst_symfile_faker;
+}
+
+/* Register our ability to parse symbols for DST BFD files */
+
+static struct sym_fns dst_sym_fns =
+{
+ /* FIXME: Can this be integrated with coffread.c? If not, should it be
+ a separate flavour like ecoff? */
+ (enum bfd_flavour) -2,
+
+ dst_new_init, /* sym_new_init: init anything gbl to entire symtab */
+ dst_symfile_init, /* sym_init: read initial info, setup for sym_read() */
+ dst_symfile_read, /* sym_read: read a symbol file into symtab */
+ dst_symfile_finish, /* sym_finish: finished with file, cleanup */
+ dst_symfile_offsets, /* sym_offsets: xlate external to internal form */
+ NULL /* next: pointer to next struct sym_fns */
+};
+
+void
+_initialize_dstread (void)
+{
+ add_symtab_fns (&dst_sym_fns);
+}
diff --git a/gdb/dve3900-rom.c b/gdb/dve3900-rom.c
new file mode 100644
index 00000000000..feb8e12001a
--- /dev/null
+++ b/gdb/dve3900-rom.c
@@ -0,0 +1,1063 @@
+/* Remote debugging interface for Densan DVE-R3900 ROM monitor for
+ GDB, the GNU debugger.
+ Copyright 1997, 1998, 2000, 2001 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "inferior.h"
+#include "command.h"
+#include "gdb_string.h"
+#include <time.h>
+#include "regcache.h"
+
+/* Type of function passed to bfd_map_over_sections. */
+
+typedef void (*section_map_func) (bfd * abfd, asection * sect, PTR obj);
+
+/* Packet escape character used by Densan monitor. */
+
+#define PESC 0xdc
+
+/* Maximum packet size. This is actually smaller than necessary
+ just to be safe. */
+
+#define MAXPSIZE 1024
+
+/* External functions. */
+
+extern void report_transfer_performance (unsigned long, time_t, time_t);
+
+/* Certain registers are "bitmapped", in that the monitor can only display
+ them or let the user modify them as a series of named bitfields.
+ This structure describes a field in a bitmapped register. */
+
+struct bit_field
+ {
+ char *prefix; /* string appearing before the value */
+ char *suffix; /* string appearing after the value */
+ char *user_name; /* name used by human when entering field value */
+ int length; /* number of bits in the field */
+ int start; /* starting (least significant) bit number of field */
+ };
+
+/* Local functions for register manipulation. */
+
+static void r3900_supply_register (char *regname, int regnamelen,
+ char *val, int vallen);
+static void fetch_bad_vaddr (void);
+static unsigned long fetch_fields (struct bit_field *bf);
+static void fetch_bitmapped_register (int regno, struct bit_field *bf);
+static void r3900_fetch_registers (int regno);
+static void store_bitmapped_register (int regno, struct bit_field *bf);
+static void r3900_store_registers (int regno);
+
+/* Local functions for fast binary loading. */
+
+static void write_long (char *buf, long n);
+static void write_long_le (char *buf, long n);
+static int debug_readchar (int hex);
+static void debug_write (unsigned char *buf, int buflen);
+static void ignore_packet (void);
+static void send_packet (char type, unsigned char *buf, int buflen, int seq);
+static void process_read_request (unsigned char *buf, int buflen);
+static void count_section (bfd * abfd, asection * s,
+ unsigned int *section_count);
+static void load_section (bfd * abfd, asection * s, unsigned int *data_count);
+static void r3900_load (char *filename, int from_tty);
+
+/* Miscellaneous local functions. */
+
+static void r3900_open (char *args, int from_tty);
+
+
+/* Pointers to static functions in monitor.c for fetching and storing
+ registers. We can't use these function in certain cases where the Densan
+ monitor acts perversely: for registers that it displays in bit-map
+ format, and those that can't be modified at all. In those cases
+ we have to use our own functions to fetch and store their values. */
+
+static void (*orig_monitor_fetch_registers) (int regno);
+static void (*orig_monitor_store_registers) (int regno);
+
+/* Pointer to static function in monitor. for loading programs.
+ We use this function for loading S-records via the serial link. */
+
+static void (*orig_monitor_load) (char *file, int from_tty);
+
+/* This flag is set if a fast ethernet download should be used. */
+
+static int ethernet = 0;
+
+/* This array of registers needs to match the indexes used by GDB. The
+ whole reason this exists is because the various ROM monitors use
+ different names than GDB does, and don't support all the registers
+ either. */
+
+static char *r3900_regnames[NUM_REGS] =
+{
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+
+ "S", /* PS_REGNUM */
+ "l", /* LO_REGNUM */
+ "h", /* HI_REGNUM */
+ "B", /* BADVADDR_REGNUM */
+ "Pcause", /* CAUSE_REGNUM */
+ "p" /* PC_REGNUM */
+};
+
+
+/* Table of register names produced by monitor's register dump command. */
+
+static struct reg_entry
+ {
+ char *name;
+ int regno;
+ }
+reg_table[] =
+{
+ {
+ "r0_zero", 0
+ }
+ ,
+ {
+ "r1_at", 1
+ }
+ ,
+ {
+ "r2_v0", 2
+ }
+ ,
+ {
+ "r3_v1", 3
+ }
+ ,
+ {
+ "r4_a0", 4
+ }
+ ,
+ {
+ "r5_a1", 5
+ }
+ ,
+ {
+ "r6_a2", 6
+ }
+ ,
+ {
+ "r7_a3", 7
+ }
+ ,
+ {
+ "r8_t0", 8
+ }
+ ,
+ {
+ "r9_t1", 9
+ }
+ ,
+ {
+ "r10_t2", 10
+ }
+ ,
+ {
+ "r11_t3", 11
+ }
+ ,
+ {
+ "r12_t4", 12
+ }
+ ,
+ {
+ "r13_t5", 13
+ }
+ ,
+ {
+ "r14_t6", 14
+ }
+ ,
+ {
+ "r15_t7", 15
+ }
+ ,
+ {
+ "r16_s0", 16
+ }
+ ,
+ {
+ "r17_s1", 17
+ }
+ ,
+ {
+ "r18_s2", 18
+ }
+ ,
+ {
+ "r19_s3", 19
+ }
+ ,
+ {
+ "r20_s4", 20
+ }
+ ,
+ {
+ "r21_s5", 21
+ }
+ ,
+ {
+ "r22_s6", 22
+ }
+ ,
+ {
+ "r23_s7", 23
+ }
+ ,
+ {
+ "r24_t8", 24
+ }
+ ,
+ {
+ "r25_t9", 25
+ }
+ ,
+ {
+ "r26_k0", 26
+ }
+ ,
+ {
+ "r27_k1", 27
+ }
+ ,
+ {
+ "r28_gp", 28
+ }
+ ,
+ {
+ "r29_sp", 29
+ }
+ ,
+ {
+ "r30_fp", 30
+ }
+ ,
+ {
+ "r31_ra", 31
+ }
+ ,
+ {
+ "HI", HI_REGNUM
+ }
+ ,
+ {
+ "LO", LO_REGNUM
+ }
+ ,
+ {
+ "PC", PC_REGNUM
+ }
+ ,
+ {
+ "BadV", BADVADDR_REGNUM
+ }
+ ,
+ {
+ NULL, 0
+ }
+};
+
+
+/* The monitor displays the cache register along with the status register,
+ as if they were a single register. So when we want to fetch the
+ status register, parse but otherwise ignore the fields of the
+ cache register that the monitor displays. Register fields that should
+ be ignored have a length of zero in the tables below. */
+
+static struct bit_field status_fields[] =
+{
+ /* Status register portion */
+ {"SR[<CU=", " ", "cu", 4, 28},
+ {"RE=", " ", "re", 1, 25},
+ {"BEV=", " ", "bev", 1, 22},
+ {"TS=", " ", "ts", 1, 21},
+ {"Nmi=", " ", "nmi", 1, 20},
+ {"INT=", " ", "int", 6, 10},
+ {"SW=", ">]", "sw", 2, 8},
+ {"[<KUO=", " ", "kuo", 1, 5},
+ {"IEO=", " ", "ieo", 1, 4},
+ {"KUP=", " ", "kup", 1, 3},
+ {"IEP=", " ", "iep", 1, 2},
+ {"KUC=", " ", "kuc", 1, 1},
+ {"IEC=", ">]", "iec", 1, 0},
+
+ /* Cache register portion (dummy for parsing only) */
+ {"CR[<IalO=", " ", "ialo", 0, 13},
+ {"DalO=", " ", "dalo", 0, 12},
+ {"IalP=", " ", "ialp", 0, 11},
+ {"DalP=", " ", "dalp", 0, 10},
+ {"IalC=", " ", "ialc", 0, 9},
+ {"DalC=", ">] ", "dalc", 0, 8},
+
+ {NULL, NULL, 0, 0} /* end of table marker */
+};
+
+
+#if 0 /* FIXME: Enable when we add support for modifying cache register. */
+static struct bit_field cache_fields[] =
+{
+ /* Status register portion (dummy for parsing only) */
+ {"SR[<CU=", " ", "cu", 0, 28},
+ {"RE=", " ", "re", 0, 25},
+ {"BEV=", " ", "bev", 0, 22},
+ {"TS=", " ", "ts", 0, 21},
+ {"Nmi=", " ", "nmi", 0, 20},
+ {"INT=", " ", "int", 0, 10},
+ {"SW=", ">]", "sw", 0, 8},
+ {"[<KUO=", " ", "kuo", 0, 5},
+ {"IEO=", " ", "ieo", 0, 4},
+ {"KUP=", " ", "kup", 0, 3},
+ {"IEP=", " ", "iep", 0, 2},
+ {"KUC=", " ", "kuc", 0, 1},
+ {"IEC=", ">]", "iec", 0, 0},
+
+ /* Cache register portion */
+ {"CR[<IalO=", " ", "ialo", 1, 13},
+ {"DalO=", " ", "dalo", 1, 12},
+ {"IalP=", " ", "ialp", 1, 11},
+ {"DalP=", " ", "dalp", 1, 10},
+ {"IalC=", " ", "ialc", 1, 9},
+ {"DalC=", ">] ", "dalc", 1, 8},
+
+ {NULL, NULL, NULL, 0, 0} /* end of table marker */
+};
+#endif
+
+
+static struct bit_field cause_fields[] =
+{
+ {"<BD=", " ", "bd", 1, 31},
+ {"CE=", " ", "ce", 2, 28},
+ {"IP=", " ", "ip", 6, 10},
+ {"SW=", " ", "sw", 2, 8},
+ {"EC=", ">]", "ec", 5, 2},
+
+ {NULL, NULL, NULL, 0, 0} /* end of table marker */
+};
+
+
+/* The monitor prints register values in the form
+
+ regname = xxxx xxxx
+
+ We look up the register name in a table, and remove the embedded space in
+ the hex value before passing it to monitor_supply_register. */
+
+static void
+r3900_supply_register (char *regname, int regnamelen, char *val, int vallen)
+{
+ int regno = -1;
+ int i;
+ char valbuf[10];
+ char *p;
+
+ /* Perform some sanity checks on the register name and value. */
+ if (regnamelen < 2 || regnamelen > 7 || vallen != 9)
+ return;
+
+ /* Look up the register name. */
+ for (i = 0; reg_table[i].name != NULL; i++)
+ {
+ int rlen = strlen (reg_table[i].name);
+ if (rlen == regnamelen && strncmp (regname, reg_table[i].name, rlen) == 0)
+ {
+ regno = reg_table[i].regno;
+ break;
+ }
+ }
+ if (regno == -1)
+ return;
+
+ /* Copy the hex value to a buffer and eliminate the embedded space. */
+ for (i = 0, p = valbuf; i < vallen; i++)
+ if (val[i] != ' ')
+ *p++ = val[i];
+ *p = '\0';
+
+ monitor_supply_register (regno, valbuf);
+}
+
+
+/* Fetch the BadVaddr register. Unlike the other registers, this
+ one can't be modified, and the monitor won't even prompt to let
+ you modify it. */
+
+static void
+fetch_bad_vaddr (void)
+{
+ char buf[20];
+
+ monitor_printf ("xB\r");
+ monitor_expect ("BadV=", NULL, 0);
+ monitor_expect_prompt (buf, sizeof (buf));
+ monitor_supply_register (BADVADDR_REGNUM, buf);
+}
+
+
+/* Read a series of bit fields from the monitor, and return their
+ combined binary value. */
+
+static unsigned long
+fetch_fields (struct bit_field *bf)
+{
+ char buf[20];
+ unsigned long val = 0;
+ unsigned long bits;
+
+ for (; bf->prefix != NULL; bf++)
+ {
+ monitor_expect (bf->prefix, NULL, 0); /* get prefix */
+ monitor_expect (bf->suffix, buf, sizeof (buf)); /* hex value, suffix */
+ if (bf->length != 0)
+ {
+ bits = strtoul (buf, NULL, 16); /* get field value */
+ bits &= ((1 << bf->length) - 1); /* mask out useless bits */
+ val |= bits << bf->start; /* insert into register */
+ }
+
+ }
+
+ return val;
+}
+
+
+static void
+fetch_bitmapped_register (int regno, struct bit_field *bf)
+{
+ unsigned long val;
+ unsigned char regbuf[MAX_REGISTER_RAW_SIZE];
+
+ monitor_printf ("x%s\r", r3900_regnames[regno]);
+ val = fetch_fields (bf);
+ monitor_printf (".\r");
+ monitor_expect_prompt (NULL, 0);
+
+ /* supply register stores in target byte order, so swap here */
+
+ store_unsigned_integer (regbuf, REGISTER_RAW_SIZE (regno), val);
+ supply_register (regno, regbuf);
+
+}
+
+
+/* Fetch all registers (if regno is -1), or one register from the
+ monitor. For most registers, we can use the generic monitor_
+ monitor_fetch_registers function. But others are displayed in
+ a very unusual fashion by the monitor, and must be handled specially. */
+
+static void
+r3900_fetch_registers (int regno)
+{
+ switch (regno)
+ {
+ case BADVADDR_REGNUM:
+ fetch_bad_vaddr ();
+ return;
+ case PS_REGNUM:
+ fetch_bitmapped_register (PS_REGNUM, status_fields);
+ return;
+ case CAUSE_REGNUM:
+ fetch_bitmapped_register (CAUSE_REGNUM, cause_fields);
+ return;
+ default:
+ orig_monitor_fetch_registers (regno);
+ }
+}
+
+
+/* Write the new value of the bitmapped register to the monitor. */
+
+static void
+store_bitmapped_register (int regno, struct bit_field *bf)
+{
+ unsigned long oldval, newval;
+
+ /* Fetch the current value of the register. */
+ monitor_printf ("x%s\r", r3900_regnames[regno]);
+ oldval = fetch_fields (bf);
+ newval = read_register (regno);
+
+ /* To save time, write just the fields that have changed. */
+ for (; bf->prefix != NULL; bf++)
+ {
+ if (bf->length != 0)
+ {
+ unsigned long oldbits, newbits, mask;
+
+ mask = (1 << bf->length) - 1;
+ oldbits = (oldval >> bf->start) & mask;
+ newbits = (newval >> bf->start) & mask;
+ if (oldbits != newbits)
+ monitor_printf ("%s %lx ", bf->user_name, newbits);
+ }
+ }
+
+ monitor_printf (".\r");
+ monitor_expect_prompt (NULL, 0);
+}
+
+
+static void
+r3900_store_registers (int regno)
+{
+ switch (regno)
+ {
+ case PS_REGNUM:
+ store_bitmapped_register (PS_REGNUM, status_fields);
+ return;
+ case CAUSE_REGNUM:
+ store_bitmapped_register (CAUSE_REGNUM, cause_fields);
+ return;
+ default:
+ orig_monitor_store_registers (regno);
+ }
+}
+
+
+/* Write a 4-byte integer to the buffer in big-endian order. */
+
+static void
+write_long (char *buf, long n)
+{
+ buf[0] = (n >> 24) & 0xff;
+ buf[1] = (n >> 16) & 0xff;
+ buf[2] = (n >> 8) & 0xff;
+ buf[3] = n & 0xff;
+}
+
+
+/* Write a 4-byte integer to the buffer in little-endian order. */
+
+static void
+write_long_le (char *buf, long n)
+{
+ buf[0] = n & 0xff;
+ buf[1] = (n >> 8) & 0xff;
+ buf[2] = (n >> 16) & 0xff;
+ buf[3] = (n >> 24) & 0xff;
+}
+
+
+/* Read a character from the monitor. If remote debugging is on,
+ print the received character. If HEX is non-zero, print the
+ character in hexadecimal; otherwise, print it in ASCII. */
+
+static int
+debug_readchar (int hex)
+{
+ char buf[10];
+ int c = monitor_readchar ();
+
+ if (remote_debug > 0)
+ {
+ if (hex)
+ sprintf (buf, "[%02x]", c & 0xff);
+ else if (c == '\0')
+ strcpy (buf, "\\0");
+ else
+ {
+ buf[0] = c;
+ buf[1] = '\0';
+ }
+ puts_debug ("Read -->", buf, "<--");
+ }
+ return c;
+}
+
+
+/* Send a buffer of characters to the monitor. If remote debugging is on,
+ print the sent buffer in hex. */
+
+static void
+debug_write (unsigned char *buf, int buflen)
+{
+ char s[10];
+
+ monitor_write (buf, buflen);
+
+ if (remote_debug > 0)
+ {
+ while (buflen-- > 0)
+ {
+ sprintf (s, "[%02x]", *buf & 0xff);
+ puts_debug ("Sent -->", s, "<--");
+ buf++;
+ }
+ }
+}
+
+
+/* Ignore a packet sent to us by the monitor. It send packets
+ when its console is in "communications interface" mode. A packet
+ is of this form:
+
+ start of packet flag (one byte: 0xdc)
+ packet type (one byte)
+ length (low byte)
+ length (high byte)
+ data (length bytes)
+
+ The last two bytes of the data field are a checksum, but we don't
+ bother to verify it.
+ */
+
+static void
+ignore_packet (void)
+{
+ int c;
+ int len;
+
+ /* Ignore lots of trash (messages about section addresses, for example)
+ until we see the start of a packet. */
+ for (len = 0; len < 256; len++)
+ {
+ c = debug_readchar (0);
+ if (c == PESC)
+ break;
+ }
+ if (len == 8)
+ error ("Packet header byte not found; %02x seen instead.", c);
+
+ /* Read the packet type and length. */
+ c = debug_readchar (1); /* type */
+
+ c = debug_readchar (1); /* low byte of length */
+ len = c & 0xff;
+
+ c = debug_readchar (1); /* high byte of length */
+ len += (c & 0xff) << 8;
+
+ /* Ignore the rest of the packet. */
+ while (len-- > 0)
+ c = debug_readchar (1);
+}
+
+
+/* Encapsulate some data into a packet and send it to the monitor.
+
+ The 'p' packet is a special case. This is a packet we send
+ in response to a read ('r') packet from the monitor. This function
+ appends a one-byte sequence number to the data field of such a packet.
+ */
+
+static void
+send_packet (char type, unsigned char *buf, int buflen, int seq)
+{
+ unsigned char hdr[4];
+ int len = buflen;
+ int sum, i;
+
+ /* If this is a 'p' packet, add one byte for a sequence number. */
+ if (type == 'p')
+ len++;
+
+ /* If the buffer has a non-zero length, add two bytes for a checksum. */
+ if (len > 0)
+ len += 2;
+
+ /* Write the packet header. */
+ hdr[0] = PESC;
+ hdr[1] = type;
+ hdr[2] = len & 0xff;
+ hdr[3] = (len >> 8) & 0xff;
+ debug_write (hdr, sizeof (hdr));
+
+ if (len)
+ {
+ /* Write the packet data. */
+ debug_write (buf, buflen);
+
+ /* Write the sequence number if this is a 'p' packet. */
+ if (type == 'p')
+ {
+ hdr[0] = seq;
+ debug_write (hdr, 1);
+ }
+
+ /* Write the checksum. */
+ sum = 0;
+ for (i = 0; i < buflen; i++)
+ {
+ int tmp = (buf[i] & 0xff);
+ if (i & 1)
+ sum += tmp;
+ else
+ sum += tmp << 8;
+ }
+ if (type == 'p')
+ {
+ if (buflen & 1)
+ sum += (seq & 0xff);
+ else
+ sum += (seq & 0xff) << 8;
+ }
+ sum = (sum & 0xffff) + ((sum >> 16) & 0xffff);
+ sum += (sum >> 16) & 1;
+ sum = ~sum;
+
+ hdr[0] = (sum >> 8) & 0xff;
+ hdr[1] = sum & 0xff;
+ debug_write (hdr, 2);
+ }
+}
+
+
+/* Respond to an expected read request from the monitor by sending
+ data in chunks. Handle all acknowledgements and handshaking packets.
+
+ The monitor expects a response consisting of a one or more 'p' packets,
+ each followed by a portion of the data requested. The 'p' packet
+ contains only a four-byte integer, the value of which is the number
+ of bytes of data we are about to send. Following the 'p' packet,
+ the monitor expects the data bytes themselves in raw, unpacketized,
+ form, without even a checksum.
+ */
+
+static void
+process_read_request (unsigned char *buf, int buflen)
+{
+ unsigned char len[4];
+ int i, chunk;
+ unsigned char seq;
+
+ /* Discard the read request. FIXME: we have to hope it's for
+ the exact number of bytes we want to send; should check for this. */
+ ignore_packet ();
+
+ for (i = chunk = 0, seq = 0; i < buflen; i += chunk, seq++)
+ {
+ /* Don't send more than MAXPSIZE bytes at a time. */
+ chunk = buflen - i;
+ if (chunk > MAXPSIZE)
+ chunk = MAXPSIZE;
+
+ /* Write a packet containing the number of bytes we are sending. */
+ write_long_le (len, chunk);
+ send_packet ('p', len, sizeof (len), seq);
+
+ /* Write the data in raw form following the packet. */
+ debug_write (&buf[i], chunk);
+
+ /* Discard the ACK packet. */
+ ignore_packet ();
+ }
+
+ /* Send an "end of data" packet. */
+ send_packet ('e', "", 0, 0);
+}
+
+
+/* Count loadable sections (helper function for r3900_load). */
+
+static void
+count_section (bfd *abfd, asection *s, unsigned int *section_count)
+{
+ if (s->flags & SEC_LOAD && bfd_section_size (abfd, s) != 0)
+ (*section_count)++;
+}
+
+
+/* Load a single BFD section (helper function for r3900_load).
+
+ WARNING: this code is filled with assumptions about how
+ the Densan monitor loads programs. The monitor issues
+ packets containing read requests, but rather than respond
+ to them in an general way, we expect them to following
+ a certain pattern.
+
+ For example, we know that the monitor will start loading by
+ issuing an 8-byte read request for the binary file header.
+ We know this is coming and ignore the actual contents
+ of the read request packet.
+ */
+
+static void
+load_section (bfd *abfd, asection *s, unsigned int *data_count)
+{
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_size_type section_size = bfd_section_size (abfd, s);
+ bfd_vma section_base = bfd_section_lma (abfd, s);
+ unsigned char *buffer;
+ unsigned char header[8];
+
+ /* Don't output zero-length sections. */
+ if (section_size == 0)
+ return;
+ if (data_count)
+ *data_count += section_size;
+
+ /* Print some fluff about the section being loaded. */
+ printf_filtered ("Loading section %s, size 0x%lx lma ",
+ bfd_section_name (abfd, s), (long) section_size);
+ print_address_numeric (section_base, 1, gdb_stdout);
+ printf_filtered ("\n");
+ gdb_flush (gdb_stdout);
+
+ /* Write the section header (location and size). */
+ write_long (&header[0], (long) section_base);
+ write_long (&header[4], (long) section_size);
+ process_read_request (header, sizeof (header));
+
+ /* Read the section contents into a buffer, write it out,
+ then free the buffer. */
+ buffer = (unsigned char *) xmalloc (section_size);
+ bfd_get_section_contents (abfd, s, buffer, 0, section_size);
+ process_read_request (buffer, section_size);
+ xfree (buffer);
+ }
+}
+
+
+/* When the ethernet is used as the console port on the Densan board,
+ we can use the "Rm" command to do a fast binary load. The format
+ of the download data is:
+
+ number of sections (4 bytes)
+ starting address (4 bytes)
+ repeat for each section:
+ location address (4 bytes)
+ section size (4 bytes)
+ binary data
+
+ The 4-byte fields are all in big-endian order.
+
+ Using this command is tricky because we have to put the monitor
+ into a special funky "communications interface" mode, in which
+ it sends and receives packets of data along with the normal prompt.
+ */
+
+static void
+r3900_load (char *filename, int from_tty)
+{
+ bfd *abfd;
+ unsigned int data_count = 0;
+ time_t start_time, end_time; /* for timing of download */
+ int section_count = 0;
+ unsigned char buffer[8];
+
+ /* If we are not using the ethernet, use the normal monitor load,
+ which sends S-records over the serial link. */
+ if (!ethernet)
+ {
+ orig_monitor_load (filename, from_tty);
+ return;
+ }
+
+ /* Open the file. */
+ if (filename == NULL || filename[0] == 0)
+ filename = get_exec_file (1);
+ abfd = bfd_openr (filename, 0);
+ if (!abfd)
+ error ("Unable to open file %s\n", filename);
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ error ("File is not an object file\n");
+
+ /* Output the "vconsi" command to get the monitor in the communication
+ state where it will accept a load command. This will cause
+ the monitor to emit a packet before each prompt, so ignore the packet. */
+ monitor_printf ("vconsi\r");
+ ignore_packet ();
+ monitor_expect_prompt (NULL, 0);
+
+ /* Output the "Rm" (load) command and respond to the subsequent "open"
+ packet by sending an ACK packet. */
+ monitor_printf ("Rm\r");
+ ignore_packet ();
+ send_packet ('a', "", 0, 0);
+
+ /* Output the fast load header (number of sections and starting address). */
+ bfd_map_over_sections ((bfd *) abfd, (section_map_func) count_section,
+ &section_count);
+ write_long (&buffer[0], (long) section_count);
+ if (exec_bfd)
+ write_long (&buffer[4], (long) bfd_get_start_address (exec_bfd));
+ else
+ write_long (&buffer[4], 0);
+ process_read_request (buffer, sizeof (buffer));
+
+ /* Output the section data. */
+ start_time = time (NULL);
+ bfd_map_over_sections (abfd, (section_map_func) load_section, &data_count);
+ end_time = time (NULL);
+
+ /* Acknowledge the close packet and put the monitor back into
+ "normal" mode so it won't send packets any more. */
+ ignore_packet ();
+ send_packet ('a', "", 0, 0);
+ monitor_expect_prompt (NULL, 0);
+ monitor_printf ("vconsx\r");
+ monitor_expect_prompt (NULL, 0);
+
+ /* Print start address and download performance information. */
+ printf_filtered ("Start address 0x%lx\n", (long) bfd_get_start_address (abfd));
+ report_transfer_performance (data_count, start_time, end_time);
+
+ /* Finally, make the PC point at the start address */
+ if (exec_bfd)
+ write_pc (bfd_get_start_address (exec_bfd));
+
+ inferior_ptid = null_ptid; /* No process now */
+
+ /* This is necessary because many things were based on the PC at the
+ time that we attached to the monitor, which is no longer valid
+ now that we have loaded new code (and just changed the PC).
+ Another way to do this might be to call normal_stop, except that
+ the stack may not be valid, and things would get horribly
+ confused... */
+ clear_symtab_users ();
+}
+
+
+/* Commands to send to the monitor when first connecting:
+ * The bare carriage return forces a prompt from the monitor
+ (monitor doesn't prompt immediately after a reset).
+ * The "vconsx" switches the monitor back to interactive mode
+ in case an aborted download had left it in packet mode.
+ * The "Xtr" command causes subsequent "t" (trace) commands to display
+ the general registers only.
+ * The "Xxr" command does the same thing for the "x" (examine
+ registers) command.
+ * The "bx" command clears all breakpoints.
+ */
+
+static char *r3900_inits[] =
+{"\r", "vconsx\r", "Xtr\r", "Xxr\r", "bx\r", NULL};
+static char *dummy_inits[] =
+{NULL};
+
+static struct target_ops r3900_ops;
+static struct monitor_ops r3900_cmds;
+
+static void
+r3900_open (char *args, int from_tty)
+{
+ char buf[64];
+ int i;
+
+ monitor_open (args, &r3900_cmds, from_tty);
+
+ /* We have to handle sending the init strings ourselves, because
+ the first two strings we send (carriage returns) may not be echoed
+ by the monitor, but the rest will be. */
+ monitor_printf_noecho ("\r\r");
+ for (i = 0; r3900_inits[i] != NULL; i++)
+ {
+ monitor_printf (r3900_inits[i]);
+ monitor_expect_prompt (NULL, 0);
+ }
+
+ /* Attempt to determine whether the console device is ethernet or serial.
+ This will tell us which kind of load to use (S-records over a serial
+ link, or the Densan fast binary multi-section format over the net). */
+
+ ethernet = 0;
+ monitor_printf ("v\r");
+ if (monitor_expect ("console device :", NULL, 0) != -1)
+ if (monitor_expect ("\n", buf, sizeof (buf)) != -1)
+ if (strstr (buf, "ethernet") != NULL)
+ ethernet = 1;
+ monitor_expect_prompt (NULL, 0);
+}
+
+void
+_initialize_r3900_rom (void)
+{
+ r3900_cmds.flags = MO_NO_ECHO_ON_OPEN |
+ MO_ADDR_BITS_REMOVE |
+ MO_CLR_BREAK_USES_ADDR |
+ MO_GETMEM_READ_SINGLE |
+ MO_PRINT_PROGRAM_OUTPUT;
+
+ r3900_cmds.init = dummy_inits;
+ r3900_cmds.cont = "g\r";
+ r3900_cmds.step = "t\r";
+ r3900_cmds.set_break = "b %A\r"; /* COREADDR */
+ r3900_cmds.clr_break = "b %A,0\r"; /* COREADDR */
+ r3900_cmds.fill = "fx %A s %x %x\r"; /* COREADDR, len, val */
+
+ r3900_cmds.setmem.cmdb = "sx %A %x\r"; /* COREADDR, val */
+ r3900_cmds.setmem.cmdw = "sh %A %x\r"; /* COREADDR, val */
+ r3900_cmds.setmem.cmdl = "sw %A %x\r"; /* COREADDR, val */
+
+ r3900_cmds.getmem.cmdb = "sx %A\r"; /* COREADDR */
+ r3900_cmds.getmem.cmdw = "sh %A\r"; /* COREADDR */
+ r3900_cmds.getmem.cmdl = "sw %A\r"; /* COREADDR */
+ r3900_cmds.getmem.resp_delim = " : ";
+ r3900_cmds.getmem.term = " ";
+ r3900_cmds.getmem.term_cmd = ".\r";
+
+ r3900_cmds.setreg.cmd = "x%s %x\r"; /* regname, val */
+
+ r3900_cmds.getreg.cmd = "x%s\r"; /* regname */
+ r3900_cmds.getreg.resp_delim = "=";
+ r3900_cmds.getreg.term = " ";
+ r3900_cmds.getreg.term_cmd = ".\r";
+
+ r3900_cmds.dump_registers = "x\r";
+ r3900_cmds.register_pattern =
+ "\\([a-zA-Z0-9_]+\\) *=\\([0-9a-f]+ [0-9a-f]+\\b\\)";
+ r3900_cmds.supply_register = r3900_supply_register;
+ /* S-record download, via "keyboard port". */
+ r3900_cmds.load = "r0\r";
+ r3900_cmds.prompt = "#";
+ r3900_cmds.line_term = "\r";
+ r3900_cmds.target = &r3900_ops;
+ r3900_cmds.stopbits = SERIAL_1_STOPBITS;
+ r3900_cmds.regnames = r3900_regnames;
+ r3900_cmds.magic = MONITOR_OPS_MAGIC;
+
+ init_monitor_ops (&r3900_ops);
+
+ r3900_ops.to_shortname = "r3900";
+ r3900_ops.to_longname = "R3900 monitor";
+ r3900_ops.to_doc = "Debug using the DVE R3900 monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ r3900_ops.to_open = r3900_open;
+
+ /* Override the functions to fetch and store registers. But save the
+ addresses of the default functions, because we will use those functions
+ for "normal" registers. */
+
+ orig_monitor_fetch_registers = r3900_ops.to_fetch_registers;
+ orig_monitor_store_registers = r3900_ops.to_store_registers;
+ r3900_ops.to_fetch_registers = r3900_fetch_registers;
+ r3900_ops.to_store_registers = r3900_store_registers;
+
+ /* Override the load function, but save the address of the default
+ function to use when loading S-records over a serial link. */
+ orig_monitor_load = r3900_ops.to_load;
+ r3900_ops.to_load = r3900_load;
+
+ add_target (&r3900_ops);
+}
diff --git a/gdb/dwarf2cfi.c b/gdb/dwarf2cfi.c
new file mode 100644
index 00000000000..783d1c014e0
--- /dev/null
+++ b/gdb/dwarf2cfi.c
@@ -0,0 +1,1784 @@
+/* Stack unwinding code based on dwarf2 frame info for GDB, the GNU debugger.
+ Copyright 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Jiri Smid, SuSE Labs.
+ Based on code written by Daniel Berlin (dan@dberlin.org).
+
+ 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 "defs.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "target.h"
+#include "elf/dwarf2.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "dwarf2cfi.h"
+
+/* Common Information Entry - holds information that is shared among many
+ Frame Descriptors. */
+struct cie_unit
+{
+ /* Offset of this unit in dwarf_frame_buffer. */
+ ULONGEST offset;
+
+ /* A null-terminated string that identifies the augmentation to this CIE or
+ to the FDEs that use it. */
+ char *augmentation;
+
+ /* A constant that is factored out of all advance location instructions. */
+ unsigned int code_align;
+
+ /* A constant that is factored out of all offset instructions. */
+ int data_align;
+
+ /* A constant that indicates which regiter represents the return address
+ of a function. */
+ unsigned char ra;
+
+ /* Indicates how addresses are encoded. */
+ unsigned char addr_encoding;
+
+ /* Pointer and length of the cie program. */
+ char *data;
+ unsigned int data_length;
+
+ struct objfile *objfile;
+
+ /* Next in chain. */
+ struct cie_unit *next;
+};
+
+/* Frame Description Entry. */
+struct fde_unit
+{
+ /* Address of the first location associated with this entry. */
+ CORE_ADDR initial_location;
+
+ /* Length of program section described by this entry. */
+ CORE_ADDR address_range;
+
+ /* Pointer to asociated CIE. */
+ struct cie_unit *cie_ptr;
+
+ /* Pointer and length of the cie program. */
+ char *data;
+ unsigned int data_length;
+};
+
+struct fde_array
+{
+ struct fde_unit **array;
+ int elems;
+ int array_size;
+};
+
+struct context_reg
+{
+ union
+ {
+ unsigned int reg;
+ long offset;
+ CORE_ADDR addr;
+ }
+ loc;
+ enum
+ {
+ REG_CTX_UNSAVED,
+ REG_CTX_SAVED_OFFSET,
+ REG_CTX_SAVED_REG,
+ REG_CTX_SAVED_ADDR,
+ REG_CTX_VALUE,
+ }
+ how;
+};
+
+/* This is the register and unwind state for a particular frame. */
+struct context
+{
+ struct context_reg *reg;
+
+ CORE_ADDR cfa;
+ CORE_ADDR ra;
+ void *lsda;
+ int args_size;
+};
+
+struct frame_state_reg
+{
+ union
+ {
+ unsigned int reg;
+ long offset;
+ unsigned char *exp;
+ }
+ loc;
+ enum
+ {
+ REG_UNSAVED,
+ REG_SAVED_OFFSET,
+ REG_SAVED_REG,
+ REG_SAVED_EXP,
+ }
+ how;
+};
+
+struct frame_state
+{
+ /* Each register save state can be described in terms of a CFA slot,
+ another register, or a location expression. */
+ struct frame_state_regs
+ {
+ struct frame_state_reg *reg;
+
+ /* Used to implement DW_CFA_remember_state. */
+ struct frame_state_regs *prev;
+ }
+ regs;
+
+ /* The CFA can be described in terms of a reg+offset or a
+ location expression. */
+ long cfa_offset;
+ int cfa_reg;
+ unsigned char *cfa_exp;
+ enum
+ {
+ CFA_UNSET,
+ CFA_REG_OFFSET,
+ CFA_EXP,
+ }
+ cfa_how;
+
+ /* The PC described by the current frame state. */
+ CORE_ADDR pc;
+
+ /* The information we care about from the CIE/FDE. */
+ int data_align;
+ unsigned int code_align;
+ unsigned char retaddr_column;
+ unsigned char addr_encoding;
+
+ struct objfile *objfile;
+};
+
+#define UNWIND_CONTEXT(fi) ((struct context *) (fi->context))
+
+
+static struct cie_unit *cie_chunks;
+static struct fde_array fde_chunks;
+/* Obstack for allocating temporary storage used during unwind operations. */
+static struct obstack unwind_tmp_obstack;
+
+extern file_ptr dwarf_frame_offset;
+extern unsigned int dwarf_frame_size;
+extern file_ptr dwarf_eh_frame_offset;
+extern unsigned int dwarf_eh_frame_size;
+
+static char *dwarf_frame_buffer;
+
+
+extern char *dwarf2_read_section (struct objfile *objfile, file_ptr offset,
+ unsigned int size);
+
+static struct fde_unit *fde_unit_alloc (void);
+static struct cie_unit *cie_unit_alloc (void);
+static void fde_chunks_need_space ();
+
+static struct context *context_alloc ();
+static struct frame_state *frame_state_alloc ();
+static void unwind_tmp_obstack_free ();
+static void context_cpy (struct context *dst, struct context *src);
+
+static unsigned int read_1u (bfd *abfd, char **p);
+static int read_1s (bfd *abfd, char **p);
+static unsigned int read_2u (bfd *abfd, char **p);
+static int read_2s (bfd *abfd, char **p);
+static unsigned int read_4u (bfd *abfd, char **p);
+static int read_4s (bfd *abfd, char **p);
+static ULONGEST read_8u (bfd *abfd, char **p);
+static LONGEST read_8s (bfd *abfd, char **p);
+
+static ULONGEST read_uleb128 (bfd *abfd, char **p);
+static LONGEST read_sleb128 (bfd *abfd, char **p);
+static CORE_ADDR read_pointer (bfd *abfd, char **p);
+static CORE_ADDR read_encoded_pointer (bfd *abfd, char **p,
+ unsigned char encoding);
+
+static LONGEST read_initial_length (bfd *abfd, char *buf, int *bytes_read);
+static ULONGEST read_length (bfd *abfd, char *buf, int *bytes_read,
+ int dwarf64);
+
+static int is_cie (ULONGEST cie_id, int dwarf64);
+static int compare_fde_unit (const void *a, const void *b);
+void dwarf2_build_frame_info (struct objfile *objfile);
+
+static void execute_cfa_program (struct objfile *objfile, char *insn_ptr,
+ char *insn_end, struct context *context,
+ struct frame_state *fs);
+static struct fde_unit *get_fde_for_addr (CORE_ADDR pc);
+static void frame_state_for (struct context *context, struct frame_state *fs);
+static void get_reg (char *reg, struct context *context, int regnum);
+static CORE_ADDR execute_stack_op (struct objfile *objfile,
+ char *op_ptr, char *op_end,
+ struct context *context, CORE_ADDR initial);
+static void update_context (struct context *context, struct frame_state *fs,
+ int chain);
+
+
+/* Memory allocation functions. */
+static struct fde_unit *
+fde_unit_alloc (void)
+{
+ struct fde_unit *fde;
+
+ fde = (struct fde_unit *) xmalloc (sizeof (struct fde_unit));
+ memset (fde, 0, sizeof (struct fde_unit));
+ return fde;
+}
+
+static struct cie_unit *
+cie_unit_alloc (void)
+{
+ struct cie_unit *cie;
+
+ cie = (struct cie_unit *) xmalloc (sizeof (struct cie_unit));
+ memset (cie, 0, sizeof (struct cie_unit));
+ return cie;
+}
+
+static void
+fde_chunks_need_space ()
+{
+ if (fde_chunks.elems < fde_chunks.array_size)
+ return;
+ fde_chunks.array_size =
+ fde_chunks.array_size ? 2 * fde_chunks.array_size : 1024;
+ fde_chunks.array =
+ xrealloc (fde_chunks.array,
+ sizeof (struct fde_unit) * fde_chunks.array_size);
+}
+
+/* Alocate a new `struct context' on temporary obstack. */
+static struct context *
+context_alloc ()
+{
+ struct context *context;
+
+ int regs_size = sizeof (struct context_reg) * NUM_REGS;
+
+ context = (struct context *) obstack_alloc (&unwind_tmp_obstack,
+ sizeof (struct context));
+ memset (context, 0, sizeof (struct context));
+ context->reg = (struct context_reg *) obstack_alloc (&unwind_tmp_obstack,
+ regs_size);
+ memset (context->reg, 0, regs_size);
+ return context;
+}
+
+/* Alocate a new `struct frame_state' on temporary obstack. */
+static struct frame_state *
+frame_state_alloc ()
+{
+ struct frame_state *fs;
+
+ int regs_size = sizeof (struct frame_state_reg) * NUM_REGS;
+
+ fs = (struct frame_state *) obstack_alloc (&unwind_tmp_obstack,
+ sizeof (struct frame_state));
+ memset (fs, 0, sizeof (struct frame_state));
+ fs->regs.reg = (struct frame_state_reg *) obstack_alloc (&unwind_tmp_obstack,
+ regs_size);
+ memset (fs->regs.reg, 0, regs_size);
+ return fs;
+}
+
+static void
+unwind_tmp_obstack_free ()
+{
+ obstack_free (&unwind_tmp_obstack, NULL);
+ obstack_init (&unwind_tmp_obstack);
+}
+
+static void
+context_cpy (struct context *dst, struct context *src)
+{
+ int regs_size = sizeof (struct context_reg) * NUM_REGS;
+ struct context_reg *dreg;
+
+ /* Structure dst contains a pointer to an array of
+ * registers of a given frame as well as src does. This
+ * array was already allocated before dst was passed to
+ * context_cpy but the pointer to it was overriden by
+ * '*dst = *src' and the array was lost. This led to the
+ * situation, that we've had a copy of src placed in dst,
+ * but both of them pointed to the same regs array and
+ * thus we've sometimes blindly rewritten it. Now we save
+ * the pointer before copying src to dst, return it back
+ * after that and copy the registers into their new place
+ * finally. --- mludvig@suse.cz */
+ dreg = dst->reg;
+ *dst = *src;
+ dst->reg = dreg;
+
+ memcpy (dst->reg, src->reg, regs_size);
+}
+
+static unsigned int
+read_1u (bfd *abfd, char **p)
+{
+ unsigned ret;
+
+ ret= bfd_get_8 (abfd, (bfd_byte *) *p);
+ (*p) ++;
+ return ret;
+}
+
+static int
+read_1s (bfd *abfd, char **p)
+{
+ int ret;
+
+ ret= bfd_get_signed_8 (abfd, (bfd_byte *) *p);
+ (*p) ++;
+ return ret;
+}
+
+static unsigned int
+read_2u (bfd *abfd, char **p)
+{
+ unsigned ret;
+
+ ret= bfd_get_16 (abfd, (bfd_byte *) *p);
+ (*p) ++;
+ return ret;
+}
+
+static int
+read_2s (bfd *abfd, char **p)
+{
+ int ret;
+
+ ret= bfd_get_signed_16 (abfd, (bfd_byte *) *p);
+ (*p) += 2;
+ return ret;
+}
+
+static unsigned int
+read_4u (bfd *abfd, char **p)
+{
+ unsigned int ret;
+
+ ret= bfd_get_32 (abfd, (bfd_byte *) *p);
+ (*p) += 4;
+ return ret;
+}
+
+static int
+read_4s (bfd *abfd, char **p)
+{
+ int ret;
+
+ ret= bfd_get_signed_32 (abfd, (bfd_byte *) *p);
+ (*p) += 4;
+ return ret;
+}
+
+static ULONGEST
+read_8u (bfd *abfd, char **p)
+{
+ ULONGEST ret;
+
+ ret = bfd_get_64 (abfd, (bfd_byte *) *p);
+ (*p) += 8;
+ return ret;
+}
+
+static LONGEST
+read_8s (bfd *abfd, char **p)
+{
+ LONGEST ret;
+
+ ret = bfd_get_signed_64 (abfd, (bfd_byte *) *p);
+ (*p) += 8;
+ return ret;
+}
+
+static ULONGEST
+read_uleb128 (bfd *abfd, char **p)
+{
+ ULONGEST ret;
+ int i, shift;
+ unsigned char byte;
+
+ ret = 0;
+ shift = 0;
+ i = 0;
+ while (1)
+ {
+ byte = bfd_get_8 (abfd, (bfd_byte *) *p);
+ (*p) ++;
+ ret |= ((unsigned long) (byte & 127) << shift);
+ if ((byte & 128) == 0)
+ {
+ break;
+ }
+ shift += 7;
+ }
+ return ret;
+}
+
+static LONGEST
+read_sleb128 (bfd *abfd, char **p)
+{
+ LONGEST ret;
+ int i, shift, size, num_read;
+ unsigned char byte;
+
+ ret = 0;
+ shift = 0;
+ size = 32;
+ num_read = 0;
+ i = 0;
+ while (1)
+ {
+ byte = bfd_get_8 (abfd, (bfd_byte *) *p);
+ (*p) ++;
+ ret |= ((long) (byte & 127) << shift);
+ shift += 7;
+ if ((byte & 128) == 0)
+ {
+ break;
+ }
+ }
+ if ((shift < size) && (byte & 0x40))
+ {
+ ret |= -(1 << shift);
+ }
+ return ret;
+}
+
+static CORE_ADDR
+read_pointer (bfd *abfd, char **p)
+{
+ switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
+ {
+ case 4:
+ return read_4u (abfd, p);
+ case 8:
+ return read_8u (abfd, p);
+ default:
+ error ("dwarf cfi error: unsupported target address length.");
+ }
+}
+
+static CORE_ADDR
+read_encoded_pointer (bfd *abfd, char **p, unsigned char encoding)
+{
+ CORE_ADDR ret;
+
+ switch (encoding & 0x0f)
+ {
+ case DW_EH_PE_absptr:
+ ret = read_pointer (abfd, p);
+ break;
+
+ case DW_EH_PE_uleb128:
+ ret = read_uleb128 (abfd, p);
+ break;
+ case DW_EH_PE_sleb128:
+ ret = read_sleb128 (abfd, p);
+ break;
+
+ case DW_EH_PE_udata2:
+ ret = read_2u (abfd, p);
+ break;
+ case DW_EH_PE_udata4:
+ ret = read_4u (abfd, p);
+ break;
+ case DW_EH_PE_udata8:
+ ret = read_8u (abfd, p);
+ break;
+
+ case DW_EH_PE_sdata2:
+ ret = read_2s (abfd, p);
+ break;
+ case DW_EH_PE_sdata4:
+ ret = read_4s (abfd, p);
+ break;
+ case DW_EH_PE_sdata8:
+ ret = read_8s (abfd, p);
+ break;
+
+ default:
+ internal_error (__FILE__, __LINE__,
+ "read_encoded_pointer: unknown pointer encoding");
+ }
+
+ if (ret != 0)
+ switch (encoding & 0xf0)
+ {
+ case DW_EH_PE_absptr:
+ break;
+ case DW_EH_PE_pcrel:
+ ret += (CORE_ADDR) *p;
+ break;
+ case DW_EH_PE_textrel:
+ case DW_EH_PE_datarel:
+ case DW_EH_PE_funcrel:
+ default:
+ internal_error (__FILE__, __LINE__,
+ "read_encoded_pointer: unknown pointer encoding");
+ }
+
+ return ret;
+}
+
+static LONGEST
+read_initial_length (bfd * abfd, char *buf, int *bytes_read)
+{
+ LONGEST ret = 0;
+
+ ret = bfd_get_32 (abfd, (bfd_byte *) buf);
+
+ if (ret == 0xffffffff)
+ {
+ ret = bfd_get_64 (abfd, (bfd_byte *) buf + 4);
+ *bytes_read = 12;
+ }
+ else
+ {
+ *bytes_read = 4;
+ }
+
+ return ret;
+}
+
+static ULONGEST
+read_length (bfd * abfd, char *buf, int *bytes_read, int dwarf64)
+{
+ if (dwarf64)
+ {
+ *bytes_read = 8;
+ return read_8u (abfd, &buf);
+ }
+ else
+ {
+ *bytes_read = 4;
+ return read_4u (abfd, &buf);
+ }
+}
+
+static void
+execute_cfa_program ( struct objfile *objfile, char *insn_ptr, char *insn_end,
+ struct context *context, struct frame_state *fs)
+{
+ struct frame_state_regs *unused_rs = NULL;
+
+ /* Don't allow remember/restore between CIE and FDE programs. */
+ fs->regs.prev = NULL;
+
+ while (insn_ptr < insn_end && fs->pc < context->ra)
+ {
+ unsigned char insn = *insn_ptr++;
+ ULONGEST reg, uoffset;
+ LONGEST offset;
+
+ if (insn & DW_CFA_advance_loc)
+ fs->pc += (insn & 0x3f) * fs->code_align;
+ else if (insn & DW_CFA_offset)
+ {
+ reg = insn & 0x3f;
+ uoffset = read_uleb128 (objfile->obfd, &insn_ptr);
+ offset = (long) uoffset * fs->data_align;
+ fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+ fs->regs.reg[reg].loc.offset = offset;
+ }
+ else if (insn & DW_CFA_restore)
+ {
+ reg = insn & 0x3f;
+ fs->regs.reg[reg].how = REG_UNSAVED;
+ }
+ else
+ switch (insn)
+ {
+ case DW_CFA_set_loc:
+ fs->pc = read_encoded_pointer (objfile->obfd, &insn_ptr,
+ fs->addr_encoding);
+ break;
+
+ case DW_CFA_advance_loc1:
+ fs->pc += read_1u (objfile->obfd, &insn_ptr);
+ break;
+ case DW_CFA_advance_loc2:
+ fs->pc += read_2u (objfile->obfd, &insn_ptr);
+ break;
+ case DW_CFA_advance_loc4:
+ fs->pc += read_4u (objfile->obfd, &insn_ptr);
+ break;
+
+ case DW_CFA_offset_extended:
+ reg = read_uleb128 (objfile->obfd, &insn_ptr);
+ uoffset = read_uleb128 (objfile->obfd, &insn_ptr);
+ offset = (long) uoffset *fs->data_align;
+ fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+ fs->regs.reg[reg].loc.offset = offset;
+ break;
+
+ case DW_CFA_restore_extended:
+ reg = read_uleb128 (objfile->obfd, &insn_ptr);
+ fs->regs.reg[reg].how = REG_UNSAVED;
+ break;
+
+ case DW_CFA_undefined:
+ case DW_CFA_same_value:
+ case DW_CFA_nop:
+ break;
+
+ case DW_CFA_register:
+ {
+ ULONGEST reg2;
+ reg = read_uleb128 (objfile->obfd, &insn_ptr);
+ reg2 = read_uleb128 (objfile->obfd, &insn_ptr);
+ fs->regs.reg[reg].how = REG_SAVED_REG;
+ fs->regs.reg[reg].loc.reg = reg2;
+ }
+ break;
+
+ case DW_CFA_remember_state:
+ {
+ struct frame_state_regs *new_rs;
+ if (unused_rs)
+ {
+ new_rs = unused_rs;
+ unused_rs = unused_rs->prev;
+ }
+ else
+ new_rs = xmalloc (sizeof (struct frame_state_regs));
+
+ *new_rs = fs->regs;
+ fs->regs.prev = new_rs;
+ }
+ break;
+
+ case DW_CFA_restore_state:
+ {
+ struct frame_state_regs *old_rs = fs->regs.prev;
+ fs->regs = *old_rs;
+ old_rs->prev = unused_rs;
+ unused_rs = old_rs;
+ }
+ break;
+
+ case DW_CFA_def_cfa:
+ reg = read_uleb128 (objfile->obfd, &insn_ptr);
+ uoffset = read_uleb128 (objfile->obfd, &insn_ptr);
+ fs->cfa_reg = reg;
+ fs->cfa_offset = uoffset;
+ fs->cfa_how = CFA_REG_OFFSET;
+ break;
+
+ case DW_CFA_def_cfa_register:
+ reg = read_uleb128 (objfile->obfd, &insn_ptr);
+ fs->cfa_reg = reg;
+ fs->cfa_how = CFA_REG_OFFSET;
+ break;
+
+ case DW_CFA_def_cfa_offset:
+ uoffset = read_uleb128 (objfile->obfd, &insn_ptr);
+ fs->cfa_offset = uoffset;
+ break;
+
+ case DW_CFA_def_cfa_expression:
+ uoffset = read_uleb128 (objfile->obfd, &insn_ptr);
+ fs->cfa_exp = insn_ptr;
+ fs->cfa_how = CFA_EXP;
+ insn_ptr += uoffset;
+ break;
+
+ case DW_CFA_expression:
+ reg = read_uleb128 (objfile->obfd, &insn_ptr);
+ uoffset = read_uleb128 (objfile->obfd, &insn_ptr);
+ fs->regs.reg[reg].how = REG_SAVED_EXP;
+ fs->regs.reg[reg].loc.exp = insn_ptr;
+ insn_ptr += uoffset;
+ break;
+
+ /* From the 2.1 draft. */
+ case DW_CFA_offset_extended_sf:
+ reg = read_uleb128 (objfile->obfd, &insn_ptr);
+ offset = read_sleb128 (objfile->obfd, &insn_ptr);
+ offset *= fs->data_align;
+ fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+ fs->regs.reg[reg].loc.offset = offset;
+ break;
+
+ case DW_CFA_def_cfa_sf:
+ reg = read_uleb128 (objfile->obfd, &insn_ptr);
+ offset = read_sleb128 (objfile->obfd, &insn_ptr);
+ fs->cfa_offset = offset;
+ fs->cfa_reg = reg;
+ fs->cfa_how = CFA_REG_OFFSET;
+ break;
+
+ case DW_CFA_def_cfa_offset_sf:
+ uoffset = read_uleb128 (objfile->obfd, &insn_ptr);
+ fs->cfa_offset = uoffset;
+ /* cfa_how deliberately not set. */
+ break;
+
+ case DW_CFA_GNU_window_save:
+ /* ??? Hardcoded for SPARC register window configuration. */
+ for (reg = 16; reg < 32; ++reg)
+ {
+ fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+ fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
+ }
+ break;
+
+ case DW_CFA_GNU_args_size:
+ uoffset = read_uleb128 (objfile->obfd, &insn_ptr);
+ context->args_size = uoffset;
+ break;
+
+ case DW_CFA_GNU_negative_offset_extended:
+ /* Obsoleted by DW_CFA_offset_extended_sf, but used by
+ older PowerPC code. */
+ reg = read_uleb128 (objfile->obfd, &insn_ptr);
+ uoffset = read_uleb128 (objfile->obfd, &insn_ptr);
+ offset = (long) uoffset *fs->data_align;
+ fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+ fs->regs.reg[reg].loc.offset = -offset;
+ break;
+
+ default:
+ error ("dwarf cfi error: unknown cfa instruction %d.", insn);
+ }
+ }
+}
+
+static struct fde_unit *
+get_fde_for_addr (CORE_ADDR pc)
+{
+ size_t lo, hi;
+ struct fde_unit *fde = NULL;
+ lo = 0;
+ hi = fde_chunks.elems;
+
+ while (lo < hi)
+ {
+ size_t i = (lo + hi) / 2;
+ fde = fde_chunks.array[i];
+ if (pc < fde->initial_location)
+ hi = i;
+ else if (pc >= fde->initial_location + fde->address_range)
+ lo = i + 1;
+ else
+ return fde;
+ }
+ return 0;
+}
+
+static void
+frame_state_for (struct context *context, struct frame_state *fs)
+{
+ struct fde_unit *fde;
+ struct cie_unit *cie;
+
+ context->args_size = 0;
+ context->lsda = 0;
+
+ fde = get_fde_for_addr (context->ra - 1);
+
+ if (fde == NULL)
+ return;
+
+ fs->pc = fde->initial_location;
+
+ if (fde->cie_ptr)
+ {
+ cie = fde->cie_ptr;
+
+ fs->code_align = cie->code_align;
+ fs->data_align = cie->data_align;
+ fs->retaddr_column = cie->ra;
+ fs->addr_encoding = cie->addr_encoding;
+ fs->objfile = cie->objfile;
+
+ execute_cfa_program (cie->objfile, cie->data,
+ cie->data + cie->data_length, context, fs);
+ execute_cfa_program (cie->objfile, fde->data,
+ fde->data + fde->data_length, context, fs);
+ }
+ else
+ internal_error (__FILE__, __LINE__,
+ "%s(): Internal error: fde->cie_ptr==NULL !",
+ __func__);
+}
+
+static void
+get_reg (char *reg, struct context *context, int regnum)
+{
+ switch (context->reg[regnum].how)
+ {
+ case REG_CTX_UNSAVED:
+ read_register_gen (regnum, reg);
+ break;
+ case REG_CTX_SAVED_OFFSET:
+ target_read_memory (context->cfa + context->reg[regnum].loc.offset,
+ reg, REGISTER_RAW_SIZE (regnum));
+ break;
+ case REG_CTX_SAVED_REG:
+ read_register_gen (context->reg[regnum].loc.reg, reg);
+ break;
+ case REG_CTX_SAVED_ADDR:
+ target_read_memory (context->reg[regnum].loc.addr,
+ reg, REGISTER_RAW_SIZE (regnum));
+ break;
+ case REG_CTX_VALUE:
+ memcpy (reg, &context->reg[regnum].loc.addr,
+ REGISTER_RAW_SIZE (regnum));
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "get_reg: unknown register rule");
+ }
+}
+
+/* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
+ onto the stack to start. */
+static CORE_ADDR
+execute_stack_op (struct objfile *objfile,
+ char *op_ptr, char *op_end, struct context *context,
+ CORE_ADDR initial)
+{
+ CORE_ADDR stack[64]; /* ??? Assume this is enough. */
+ int stack_elt;
+
+ stack[0] = initial;
+ stack_elt = 1;
+
+ while (op_ptr < op_end)
+ {
+ enum dwarf_location_atom op = *op_ptr++;
+ CORE_ADDR result;
+ ULONGEST reg;
+ LONGEST offset;
+
+ switch (op)
+ {
+ case DW_OP_lit0:
+ case DW_OP_lit1:
+ case DW_OP_lit2:
+ case DW_OP_lit3:
+ case DW_OP_lit4:
+ case DW_OP_lit5:
+ case DW_OP_lit6:
+ case DW_OP_lit7:
+ case DW_OP_lit8:
+ case DW_OP_lit9:
+ case DW_OP_lit10:
+ case DW_OP_lit11:
+ case DW_OP_lit12:
+ case DW_OP_lit13:
+ case DW_OP_lit14:
+ case DW_OP_lit15:
+ case DW_OP_lit16:
+ case DW_OP_lit17:
+ case DW_OP_lit18:
+ case DW_OP_lit19:
+ case DW_OP_lit20:
+ case DW_OP_lit21:
+ case DW_OP_lit22:
+ case DW_OP_lit23:
+ case DW_OP_lit24:
+ case DW_OP_lit25:
+ case DW_OP_lit26:
+ case DW_OP_lit27:
+ case DW_OP_lit28:
+ case DW_OP_lit29:
+ case DW_OP_lit30:
+ case DW_OP_lit31:
+ result = op - DW_OP_lit0;
+ break;
+
+ case DW_OP_addr:
+ result = read_pointer (objfile->obfd, &op_ptr);
+ break;
+
+ case DW_OP_const1u:
+ result = read_1u (objfile->obfd, &op_ptr);
+ break;
+ case DW_OP_const1s:
+ result = read_1s (objfile->obfd, &op_ptr);
+ break;
+ case DW_OP_const2u:
+ result = read_2u (objfile->obfd, &op_ptr);
+ break;
+ case DW_OP_const2s:
+ result = read_2s (objfile->obfd, &op_ptr);
+ break;
+ case DW_OP_const4u:
+ result = read_4u (objfile->obfd, &op_ptr);
+ break;
+ case DW_OP_const4s:
+ result = read_4s (objfile->obfd, &op_ptr);
+ break;
+ case DW_OP_const8u:
+ result = read_8u (objfile->obfd, &op_ptr);
+ break;
+ case DW_OP_const8s:
+ result = read_8s (objfile->obfd, &op_ptr);
+ break;
+ case DW_OP_constu:
+ result = read_uleb128 (objfile->obfd, &op_ptr);
+ break;
+ case DW_OP_consts:
+ result = read_sleb128 (objfile->obfd, &op_ptr);
+ break;
+
+ case DW_OP_reg0:
+ case DW_OP_reg1:
+ case DW_OP_reg2:
+ case DW_OP_reg3:
+ case DW_OP_reg4:
+ case DW_OP_reg5:
+ case DW_OP_reg6:
+ case DW_OP_reg7:
+ case DW_OP_reg8:
+ case DW_OP_reg9:
+ case DW_OP_reg10:
+ case DW_OP_reg11:
+ case DW_OP_reg12:
+ case DW_OP_reg13:
+ case DW_OP_reg14:
+ case DW_OP_reg15:
+ case DW_OP_reg16:
+ case DW_OP_reg17:
+ case DW_OP_reg18:
+ case DW_OP_reg19:
+ case DW_OP_reg20:
+ case DW_OP_reg21:
+ case DW_OP_reg22:
+ case DW_OP_reg23:
+ case DW_OP_reg24:
+ case DW_OP_reg25:
+ case DW_OP_reg26:
+ case DW_OP_reg27:
+ case DW_OP_reg28:
+ case DW_OP_reg29:
+ case DW_OP_reg30:
+ case DW_OP_reg31:
+ get_reg ((char *) &result, context, op - DW_OP_reg0);
+ break;
+ case DW_OP_regx:
+ reg = read_uleb128 (objfile->obfd, &op_ptr);
+ get_reg ((char *) &result, context, reg);
+ break;
+
+ case DW_OP_breg0:
+ case DW_OP_breg1:
+ case DW_OP_breg2:
+ case DW_OP_breg3:
+ case DW_OP_breg4:
+ case DW_OP_breg5:
+ case DW_OP_breg6:
+ case DW_OP_breg7:
+ case DW_OP_breg8:
+ case DW_OP_breg9:
+ case DW_OP_breg10:
+ case DW_OP_breg11:
+ case DW_OP_breg12:
+ case DW_OP_breg13:
+ case DW_OP_breg14:
+ case DW_OP_breg15:
+ case DW_OP_breg16:
+ case DW_OP_breg17:
+ case DW_OP_breg18:
+ case DW_OP_breg19:
+ case DW_OP_breg20:
+ case DW_OP_breg21:
+ case DW_OP_breg22:
+ case DW_OP_breg23:
+ case DW_OP_breg24:
+ case DW_OP_breg25:
+ case DW_OP_breg26:
+ case DW_OP_breg27:
+ case DW_OP_breg28:
+ case DW_OP_breg29:
+ case DW_OP_breg30:
+ case DW_OP_breg31:
+ offset = read_sleb128 (objfile->obfd, &op_ptr);
+ get_reg ((char *) &result, context, op - DW_OP_breg0);
+ result += offset;
+ break;
+ case DW_OP_bregx:
+ reg = read_uleb128 (objfile->obfd, &op_ptr);
+ offset = read_sleb128 (objfile->obfd, &op_ptr);
+ get_reg ((char *) &result, context, reg);
+ result += offset;
+ break;
+
+ case DW_OP_dup:
+ if (stack_elt < 1)
+ internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ result = stack[stack_elt - 1];
+ break;
+
+ case DW_OP_drop:
+ if (--stack_elt < 0)
+ internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ goto no_push;
+
+ case DW_OP_pick:
+ offset = *op_ptr++;
+ if (offset >= stack_elt - 1)
+ internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ result = stack[stack_elt - 1 - offset];
+ break;
+
+ case DW_OP_over:
+ if (stack_elt < 2)
+ internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ result = stack[stack_elt - 2];
+ break;
+
+ case DW_OP_rot:
+ {
+ CORE_ADDR t1, t2, t3;
+
+ if (stack_elt < 3)
+ internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ t1 = stack[stack_elt - 1];
+ t2 = stack[stack_elt - 2];
+ t3 = stack[stack_elt - 3];
+ stack[stack_elt - 1] = t2;
+ stack[stack_elt - 2] = t3;
+ stack[stack_elt - 3] = t1;
+ goto no_push;
+ }
+
+ case DW_OP_deref:
+ case DW_OP_deref_size:
+ case DW_OP_abs:
+ case DW_OP_neg:
+ case DW_OP_not:
+ case DW_OP_plus_uconst:
+ /* Unary operations. */
+ if (--stack_elt < 0)
+ internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ result = stack[stack_elt];
+
+ switch (op)
+ {
+ case DW_OP_deref:
+ {
+ char *ptr = (char *) result;
+ result = read_pointer (objfile->obfd, &ptr);
+ }
+ break;
+
+ case DW_OP_deref_size:
+ {
+ char *ptr = (char *) result;
+ switch (*op_ptr++)
+ {
+ case 1:
+ result = read_1u (objfile->obfd, &ptr);
+ break;
+ case 2:
+ result = read_2u (objfile->obfd, &ptr);
+ break;
+ case 4:
+ result = read_4u (objfile->obfd, &ptr);
+ break;
+ case 8:
+ result = read_8u (objfile->obfd, &ptr);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "execute_stack_op error");
+ }
+ }
+ break;
+
+ case DW_OP_abs:
+ if (result < 0)
+ result = -result;
+ break;
+ case DW_OP_neg:
+ result = -result;
+ break;
+ case DW_OP_not:
+ result = ~result;
+ break;
+ case DW_OP_plus_uconst:
+ result += read_uleb128 (objfile->obfd, &op_ptr);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case DW_OP_and:
+ case DW_OP_div:
+ case DW_OP_minus:
+ case DW_OP_mod:
+ case DW_OP_mul:
+ case DW_OP_or:
+ case DW_OP_plus:
+ case DW_OP_le:
+ case DW_OP_ge:
+ case DW_OP_eq:
+ case DW_OP_lt:
+ case DW_OP_gt:
+ case DW_OP_ne:
+ {
+ /* Binary operations. */
+ CORE_ADDR first, second;
+ if ((stack_elt -= 2) < 0)
+ internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ second = stack[stack_elt];
+ first = stack[stack_elt + 1];
+
+ switch (op)
+ {
+ case DW_OP_and:
+ result = second & first;
+ break;
+ case DW_OP_div:
+ result = (LONGEST) second / (LONGEST) first;
+ break;
+ case DW_OP_minus:
+ result = second - first;
+ break;
+ case DW_OP_mod:
+ result = (LONGEST) second % (LONGEST) first;
+ break;
+ case DW_OP_mul:
+ result = second * first;
+ break;
+ case DW_OP_or:
+ result = second | first;
+ break;
+ case DW_OP_plus:
+ result = second + first;
+ break;
+ case DW_OP_shl:
+ result = second << first;
+ break;
+ case DW_OP_shr:
+ result = second >> first;
+ break;
+ case DW_OP_shra:
+ result = (LONGEST) second >> first;
+ break;
+ case DW_OP_xor:
+ result = second ^ first;
+ break;
+ case DW_OP_le:
+ result = (LONGEST) first <= (LONGEST) second;
+ break;
+ case DW_OP_ge:
+ result = (LONGEST) first >= (LONGEST) second;
+ break;
+ case DW_OP_eq:
+ result = (LONGEST) first == (LONGEST) second;
+ break;
+ case DW_OP_lt:
+ result = (LONGEST) first < (LONGEST) second;
+ break;
+ case DW_OP_gt:
+ result = (LONGEST) first > (LONGEST) second;
+ break;
+ case DW_OP_ne:
+ result = (LONGEST) first != (LONGEST) second;
+ break;
+ default: /* This label is here just to avoid warning. */
+ break;
+ }
+ }
+ break;
+
+ case DW_OP_skip:
+ offset = read_2s (objfile->obfd, &op_ptr);
+ op_ptr += offset;
+ goto no_push;
+
+ case DW_OP_bra:
+ if (--stack_elt < 0)
+ internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ offset = read_2s (objfile->obfd, &op_ptr);
+ if (stack[stack_elt] != 0)
+ op_ptr += offset;
+ goto no_push;
+
+ case DW_OP_nop:
+ goto no_push;
+
+ default:
+ internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ }
+
+ /* Most things push a result value. */
+ if ((size_t) stack_elt >= sizeof (stack) / sizeof (*stack))
+ internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ stack[++stack_elt] = result;
+ no_push:;
+ }
+
+ /* We were executing this program to get a value. It should be
+ at top of stack. */
+ if (--stack_elt < 0)
+ internal_error (__FILE__, __LINE__, "execute_stack_op error");
+ return stack[stack_elt];
+}
+
+static void
+update_context (struct context *context, struct frame_state *fs, int chain)
+{
+ struct context *orig_context;
+ CORE_ADDR cfa;
+ long i;
+
+ orig_context = context_alloc ();
+ context_cpy (orig_context, context);
+ /* Compute this frame's CFA. */
+ switch (fs->cfa_how)
+ {
+ case CFA_REG_OFFSET:
+ get_reg ((char *) &cfa, context, fs->cfa_reg);
+ cfa += fs->cfa_offset;
+ break;
+
+ case CFA_EXP:
+ /* ??? No way of knowing what register number is the stack pointer
+ to do the same sort of handling as above. Assume that if the
+ CFA calculation is so complicated as to require a stack program
+ that this will not be a problem. */
+ {
+ char *exp = fs->cfa_exp;
+ ULONGEST len;
+
+ len = read_uleb128 (fs->objfile->obfd, &exp);
+ cfa = (CORE_ADDR) execute_stack_op (fs->objfile, exp,
+ exp + len, context, 0);
+ break;
+ }
+ default:
+ break;
+ }
+ context->cfa = cfa;
+
+ if (!chain)
+ orig_context->cfa = cfa;
+
+ /* Compute the addresses of all registers saved in this frame. */
+ for (i = 0; i < NUM_REGS; ++i)
+ switch (fs->regs.reg[i].how)
+ {
+ case REG_UNSAVED:
+ if (i == SP_REGNUM)
+ {
+ context->reg[i].how = REG_CTX_VALUE;
+ context->reg[i].loc.addr = cfa;
+ }
+ else
+ context->reg[i].how = REG_CTX_UNSAVED;
+ break;
+ case REG_SAVED_OFFSET:
+ context->reg[i].how = REG_CTX_SAVED_OFFSET;
+ context->reg[i].loc.offset = fs->regs.reg[i].loc.offset;
+ break;
+ case REG_SAVED_REG:
+ switch (orig_context->reg[fs->regs.reg[i].loc.reg].how)
+ {
+ case REG_CTX_UNSAVED:
+ context->reg[i].how = REG_CTX_UNSAVED;
+ break;
+ case REG_CTX_SAVED_OFFSET:
+ context->reg[i].how = REG_CTX_SAVED_OFFSET;
+ context->reg[i].loc.offset = orig_context->cfa - context->cfa +
+ orig_context->reg[fs->regs.reg[i].loc.reg].loc.offset;
+ break;
+ case REG_CTX_SAVED_REG:
+ context->reg[i].how = REG_CTX_SAVED_REG;
+ context->reg[i].loc.reg =
+ orig_context->reg[fs->regs.reg[i].loc.reg].loc.reg;
+ break;
+ case REG_CTX_SAVED_ADDR:
+ context->reg[i].how = REG_CTX_SAVED_ADDR;
+ context->reg[i].loc.addr =
+ orig_context->reg[fs->regs.reg[i].loc.reg].loc.addr;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "%s: unknown register rule", __func__);
+ }
+ break;
+ case REG_SAVED_EXP:
+ {
+ char *exp = fs->regs.reg[i].loc.exp;
+ ULONGEST len;
+ CORE_ADDR val;
+
+ len = read_uleb128 (fs->objfile->obfd, &exp);
+ val = execute_stack_op (fs->objfile, exp, exp + len,
+ orig_context, cfa);
+ context->reg[i].how = REG_CTX_SAVED_ADDR;
+ context->reg[i].loc.addr = val;
+ }
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "%s: unknown register rule", __func__);
+ }
+ get_reg ((char *) &context->ra, context, fs->retaddr_column);
+ unwind_tmp_obstack_free ();
+}
+
+static int
+is_cie (ULONGEST cie_id, int dwarf64)
+{
+ return dwarf64 ? (cie_id == 0xffffffffffffffff) : (cie_id == 0xffffffff);
+}
+
+static int
+compare_fde_unit (const void *a, const void *b)
+{
+ struct fde_unit **first, **second;
+ first = (struct fde_unit **) a;
+ second = (struct fde_unit **) b;
+ if ((*first)->initial_location > (*second)->initial_location)
+ return 1;
+ else if ((*first)->initial_location < (*second)->initial_location)
+ return -1;
+ else
+ return 0;
+}
+
+/* Build the cie_chunks and fde_chunks tables from informations
+ in .debug_frame section. */
+void
+dwarf2_build_frame_info (struct objfile *objfile)
+{
+ bfd *abfd = objfile->obfd;
+ char *start = NULL;
+ char *end = NULL;
+ int from_eh = 0;
+
+ obstack_init (&unwind_tmp_obstack);
+
+ dwarf_frame_buffer = 0;
+
+ if (dwarf_frame_offset)
+ {
+ dwarf_frame_buffer = dwarf2_read_section (objfile,
+ dwarf_frame_offset,
+ dwarf_frame_size);
+
+ start = dwarf_frame_buffer;
+ end = dwarf_frame_buffer + dwarf_frame_size;
+ }
+ else if (dwarf_eh_frame_offset)
+ {
+ dwarf_frame_buffer = dwarf2_read_section (objfile,
+ dwarf_eh_frame_offset,
+ dwarf_eh_frame_size);
+
+ start = dwarf_frame_buffer;
+ end = dwarf_frame_buffer + dwarf_eh_frame_size;
+
+ from_eh = 1;
+ }
+
+ if (start)
+ {
+ while (start < end)
+ {
+ unsigned long length;
+ ULONGEST cie_id;
+ ULONGEST unit_offset = start - dwarf_frame_buffer;
+ int bytes_read;
+ int dwarf64;
+ char *block_end;
+
+ length = read_initial_length (abfd, start, &bytes_read);
+ start += bytes_read;
+ dwarf64 = (bytes_read == 12);
+ block_end = start + length;
+
+ cie_id = read_length (abfd, start, &bytes_read, dwarf64);
+ start += bytes_read;
+
+ if ((from_eh && cie_id == 0) || is_cie (cie_id, dwarf64))
+ {
+ struct cie_unit *cie = cie_unit_alloc ();
+ char *aug;
+
+ cie->objfile = objfile;
+ cie->next = cie_chunks;
+ cie_chunks = cie;
+
+ cie->objfile = objfile;
+
+ cie->offset = unit_offset;
+
+ start++; /* version */
+
+ cie->augmentation = aug = start;
+ while (*start)
+ start++;
+ start++; /* skip past NUL */
+
+ cie->code_align = read_uleb128 (abfd, &start);
+ cie->data_align = read_sleb128 (abfd, &start);
+ cie->ra = read_1u (abfd, &start);
+
+ if (*aug == 'z')
+ {
+ int xtra = read_uleb128 (abfd, &start);
+ start += xtra;
+ ++aug;
+ }
+
+ while (*aug != '\0')
+ {
+ if (aug[0] == 'e' && aug[1] == 'h')
+ {
+ start += sizeof (void *);
+ aug += 2;
+ }
+ else if (aug[0] == 'R')
+ {
+ cie->addr_encoding = *start++;
+ aug += 1;
+ }
+ else if (aug[0] == 'P')
+ {
+ CORE_ADDR ptr;
+ ptr = read_encoded_pointer (abfd, &start,
+ cie->addr_encoding);
+ aug += 1;
+ }
+ else
+ warning ("%s(): unknown augmentation", __func__);
+ }
+
+ cie->data = start;
+ cie->data_length = block_end - start;
+ }
+ else
+ {
+ struct fde_unit *fde;
+ struct cie_unit *cie;
+
+ fde_chunks_need_space ();
+ fde = fde_unit_alloc ();
+
+ fde_chunks.array[fde_chunks.elems++] = fde;
+
+ fde->initial_location = read_pointer (abfd, &start)
+ + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ fde->address_range = read_pointer (abfd, &start);
+
+ cie = cie_chunks;
+ while(cie)
+ {
+ if (cie->objfile == objfile)
+ {
+ if (from_eh && (cie->offset == (unit_offset + bytes_read - cie_id)))
+ break;
+ if (!from_eh && (cie->offset == cie_id))
+ break;
+ }
+
+ cie = cie->next;
+ }
+
+ if (!cie)
+ error ("%s(): can't find CIE pointer", __func__);
+ fde->cie_ptr = cie;
+
+ if (cie->augmentation[0] == 'z')
+ read_uleb128 (abfd, &start);
+
+ fde->data = start;
+ fde->data_length = block_end - start;
+ }
+ start = block_end;
+ }
+ qsort (fde_chunks.array, fde_chunks.elems,
+ sizeof (struct fde_unit *), compare_fde_unit);
+ }
+}
+
+
+/* Return the frame address. */
+CORE_ADDR
+cfi_read_fp ()
+{
+ struct context *context;
+ struct frame_state *fs;
+ CORE_ADDR cfa;
+
+ context = context_alloc ();
+ fs = frame_state_alloc ();
+
+ context->ra = read_pc () + 1;
+
+ frame_state_for (context, fs);
+ update_context (context, fs, 0);
+
+ cfa = context->cfa;
+ unwind_tmp_obstack_free ();
+ return cfa;
+}
+
+/* Store the frame address. This function is not used. */
+
+void
+cfi_write_fp (CORE_ADDR val)
+{
+ struct context *context;
+ struct frame_state *fs;
+
+ context = context_alloc ();
+ fs = frame_state_alloc ();
+
+ context->ra = read_pc () + 1;
+
+ frame_state_for (context, fs);
+
+ if (fs->cfa_how == CFA_REG_OFFSET)
+ {
+ val -= fs->cfa_offset;
+ write_register_gen (fs->cfa_reg, (char *) &val);
+ }
+ else
+ warning ("Can't write fp.");
+
+ unwind_tmp_obstack_free ();
+}
+
+/* Restore the machine to the state it had before the current frame
+ was created. */
+void
+cfi_pop_frame (struct frame_info *fi)
+{
+ char regbuf[MAX_REGISTER_RAW_SIZE];
+ int regnum;
+
+ fi = get_current_frame ();
+
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ {
+ get_reg (regbuf, UNWIND_CONTEXT (fi), regnum);
+ write_register_bytes (REGISTER_BYTE (regnum), regbuf,
+ REGISTER_RAW_SIZE (regnum));
+ }
+ write_register (PC_REGNUM, UNWIND_CONTEXT (fi)->ra);
+
+ flush_cached_frames ();
+}
+
+/* Determine the address of the calling function's frame. */
+CORE_ADDR
+cfi_frame_chain (struct frame_info *fi)
+{
+ struct context *context;
+ struct frame_state *fs;
+ CORE_ADDR cfa;
+
+ context = context_alloc ();
+ fs = frame_state_alloc ();
+ context_cpy (context, UNWIND_CONTEXT (fi));
+
+ /* outermost frame */
+ if (context->ra == 0)
+ {
+ unwind_tmp_obstack_free ();
+ return 0;
+ }
+
+ frame_state_for (context, fs);
+ update_context (context, fs, 1);
+
+ cfa = context->cfa;
+ unwind_tmp_obstack_free ();
+
+ return cfa;
+}
+
+/* Sets the pc of the frame. */
+void
+cfi_init_frame_pc (int fromleaf, struct frame_info *fi)
+{
+ if (fi->next)
+ get_reg ((char *) &(fi->pc), UNWIND_CONTEXT (fi->next), PC_REGNUM);
+ else
+ fi->pc = read_pc ();
+}
+
+/* Initialize unwind context informations of the frame. */
+void
+cfi_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ struct frame_state *fs;
+
+ fs = frame_state_alloc ();
+ fi->context = frame_obstack_alloc (sizeof (struct context));
+ UNWIND_CONTEXT (fi)->reg =
+ frame_obstack_alloc (sizeof (struct context_reg) * NUM_REGS);
+ memset (UNWIND_CONTEXT (fi)->reg, 0,
+ sizeof (struct context_reg) * NUM_REGS);
+
+ if (fi->next)
+ {
+ context_cpy (UNWIND_CONTEXT (fi), UNWIND_CONTEXT (fi->next));
+ frame_state_for (UNWIND_CONTEXT (fi), fs);
+ update_context (UNWIND_CONTEXT (fi), fs, 1);
+ }
+ else
+ {
+ UNWIND_CONTEXT (fi)->ra = fi->pc + 1;
+ frame_state_for (UNWIND_CONTEXT (fi), fs);
+ update_context (UNWIND_CONTEXT (fi), fs, 0);
+ }
+ unwind_tmp_obstack_free ();
+}
+
+/* Obtain return address of the frame. */
+CORE_ADDR
+cfi_get_ra (struct frame_info *fi)
+{
+ return UNWIND_CONTEXT (fi)->ra;
+}
+
+/* Find register number REGNUM relative to FRAME and put its
+ (raw) contents in *RAW_BUFFER. Set *OPTIMIZED if the variable
+ was optimized out (and thus can't be fetched). If the variable
+ was fetched from memory, set *ADDRP to where it was fetched from,
+ otherwise it was fetched from a register.
+
+ The argument RAW_BUFFER must point to aligned memory. */
+void
+cfi_get_saved_register (char *raw_buffer,
+ int *optimized,
+ CORE_ADDR * addrp,
+ struct frame_info *frame,
+ int regnum, enum lval_type *lval)
+{
+ if (!target_has_registers)
+ error ("No registers.");
+
+ /* Normal systems don't optimize out things with register numbers. */
+ if (optimized != NULL)
+ *optimized = 0;
+
+ if (addrp) /* default assumption: not found in memory */
+ *addrp = 0;
+
+ if (!frame->next)
+ {
+ read_register_gen (regnum, raw_buffer);
+ if (lval != NULL)
+ *lval = lval_register;
+ if (addrp != NULL)
+ *addrp = REGISTER_BYTE (regnum);
+ }
+ else
+ {
+ frame = frame->next;
+ switch (UNWIND_CONTEXT (frame)->reg[regnum].how)
+ {
+ case REG_CTX_UNSAVED:
+ read_register_gen (regnum, raw_buffer);
+ if (lval != NULL)
+ *lval = not_lval;
+ if (optimized != NULL)
+ *optimized = 1;
+ break;
+ case REG_CTX_SAVED_OFFSET:
+ target_read_memory (UNWIND_CONTEXT (frame)->cfa +
+ UNWIND_CONTEXT (frame)->reg[regnum].loc.offset,
+ raw_buffer, REGISTER_RAW_SIZE (regnum));
+ if (lval != NULL)
+ *lval = lval_memory;
+ if (addrp != NULL)
+ *addrp =
+ UNWIND_CONTEXT (frame)->cfa +
+ UNWIND_CONTEXT (frame)->reg[regnum].loc.offset;
+ break;
+ case REG_CTX_SAVED_REG:
+ read_register_gen (UNWIND_CONTEXT (frame)->reg[regnum].loc.reg,
+ raw_buffer);
+ if (lval != NULL)
+ *lval = lval_register;
+ if (addrp != NULL)
+ *addrp =
+ REGISTER_BYTE (UNWIND_CONTEXT (frame)->reg[regnum].loc.reg);
+ break;
+ case REG_CTX_SAVED_ADDR:
+ target_read_memory (UNWIND_CONTEXT (frame)->reg[regnum].loc.addr,
+ raw_buffer, REGISTER_RAW_SIZE (regnum));
+ if (lval != NULL)
+ *lval = lval_memory;
+ if (addrp != NULL)
+ *addrp = UNWIND_CONTEXT (frame)->reg[regnum].loc.addr;
+ break;
+ case REG_CTX_VALUE:
+ memcpy (raw_buffer, &UNWIND_CONTEXT (frame)->reg[regnum].loc.addr,
+ REGISTER_RAW_SIZE (regnum));
+ if (lval != NULL)
+ *lval = not_lval;
+ if (optimized != NULL)
+ *optimized = 0;
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "cfi_get_saved_register: unknown register rule");
+ }
+ }
+}
+
+/* Return the register that the function uses for a frame pointer,
+ plus any necessary offset to be applied to the register before
+ any frame pointer offsets. */
+void
+cfi_virtual_frame_pointer (CORE_ADDR pc, int *frame_reg,
+ LONGEST * frame_offset)
+{
+ struct context *context;
+ struct frame_state *fs;
+
+ context = context_alloc ();
+ fs = frame_state_alloc ();
+
+ context->ra = read_pc () + 1;
+
+ frame_state_for (context, fs);
+
+ if (fs->cfa_how == CFA_REG_OFFSET)
+ {
+ *frame_reg = fs->cfa_reg;
+ *frame_offset = fs->cfa_offset;
+ }
+ else
+ error ("dwarf cfi error: CFA is not defined as CFA_REG_OFFSET");
+
+ unwind_tmp_obstack_free ();
+}
diff --git a/gdb/dwarf2cfi.h b/gdb/dwarf2cfi.h
new file mode 100644
index 00000000000..f4c675aca7b
--- /dev/null
+++ b/gdb/dwarf2cfi.h
@@ -0,0 +1,66 @@
+/* Stack unwinding code based on dwarf2 frame info for GDB, the GNU debugger.
+ Copyright 2001
+ 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. */
+
+#ifndef DWARF2CFI_H
+#define DWARF2CFI_H
+
+/* Return the frame address. */
+CORE_ADDR cfi_read_fp ();
+
+/* Store the frame address. */
+void cfi_write_fp (CORE_ADDR val);
+
+/* Restore the machine to the state it had before the current frame
+ was created. */
+void cfi_pop_frame (struct frame_info *);
+
+/* Determine the address of the calling function's frame. */
+CORE_ADDR cfi_frame_chain (struct frame_info *fi);
+
+/* Sets the pc of the frame. */
+void cfi_init_frame_pc (int fromleaf, struct frame_info *fi);
+
+/* Initialize unwind context informations of the frame. */
+void cfi_init_extra_frame_info (int fromleaf, struct frame_info *fi);
+
+/* Obtain return address of the frame. */
+CORE_ADDR cfi_get_ra (struct frame_info *fi);
+
+/* Find register number REGNUM relative to FRAME and put its
+ (raw) contents in *RAW_BUFFER. Set *OPTIMIZED if the variable
+ was optimized out (and thus can't be fetched). If the variable
+ was fetched from memory, set *ADDRP to where it was fetched from,
+ otherwise it was fetched from a register.
+
+ The argument RAW_BUFFER must point to aligned memory. */
+void cfi_get_saved_register (char *raw_buffer,
+ int *optimized,
+ CORE_ADDR * addrp,
+ struct frame_info *frame,
+ int regnum, enum lval_type *lval);
+
+/* Return the register that the function uses for a frame pointer,
+ plus any necessary offset to be applied to the register before
+ any frame pointer offsets. */
+void cfi_virtual_frame_pointer (CORE_ADDR pc, int *frame_regnum,
+ LONGEST * frame_offset);
+
+#endif
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
new file mode 100644
index 00000000000..6c2b542f634
--- /dev/null
+++ b/gdb/dwarf2read.c
@@ -0,0 +1,6813 @@
+/* DWARF 2 debugging format support for GDB.
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
+ Inc. with support from Florida State University (under contract
+ with the Ada Joint Program Office), and Silicon Graphics, Inc.
+ Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
+ based on Fred Fish's (Cygnus Support) implementation of DWARF 1
+ support in dwarfread.c
+
+ 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 "defs.h"
+#include "bfd.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "elf/dwarf2.h"
+#include "buildsym.h"
+#include "demangle.h"
+#include "expression.h"
+#include "filenames.h" /* for DOSish file names */
+#include "macrotab.h"
+
+#include "language.h"
+#include "complaints.h"
+#include "bcache.h"
+#include <fcntl.h>
+#include "gdb_string.h"
+#include "gdb_assert.h"
+#include <sys/types.h>
+
+#ifndef DWARF2_REG_TO_REGNUM
+#define DWARF2_REG_TO_REGNUM(REG) (REG)
+#endif
+
+#if 0
+/* .debug_info header for a compilation unit
+ Because of alignment constraints, this structure has padding and cannot
+ be mapped directly onto the beginning of the .debug_info section. */
+typedef struct comp_unit_header
+ {
+ unsigned int length; /* length of the .debug_info
+ contribution */
+ unsigned short version; /* version number -- 2 for DWARF
+ version 2 */
+ unsigned int abbrev_offset; /* offset into .debug_abbrev section */
+ unsigned char addr_size; /* byte size of an address -- 4 */
+ }
+_COMP_UNIT_HEADER;
+#define _ACTUAL_COMP_UNIT_HEADER_SIZE 11
+#endif
+
+/* .debug_pubnames header
+ Because of alignment constraints, this structure has padding and cannot
+ be mapped directly onto the beginning of the .debug_info section. */
+typedef struct pubnames_header
+ {
+ unsigned int length; /* length of the .debug_pubnames
+ contribution */
+ unsigned char version; /* version number -- 2 for DWARF
+ version 2 */
+ unsigned int info_offset; /* offset into .debug_info section */
+ unsigned int info_size; /* byte size of .debug_info section
+ portion */
+ }
+_PUBNAMES_HEADER;
+#define _ACTUAL_PUBNAMES_HEADER_SIZE 13
+
+/* .debug_pubnames header
+ Because of alignment constraints, this structure has padding and cannot
+ be mapped directly onto the beginning of the .debug_info section. */
+typedef struct aranges_header
+ {
+ unsigned int length; /* byte len of the .debug_aranges
+ contribution */
+ unsigned short version; /* version number -- 2 for DWARF
+ version 2 */
+ unsigned int info_offset; /* offset into .debug_info section */
+ unsigned char addr_size; /* byte size of an address */
+ unsigned char seg_size; /* byte size of segment descriptor */
+ }
+_ARANGES_HEADER;
+#define _ACTUAL_ARANGES_HEADER_SIZE 12
+
+/* .debug_line statement program prologue
+ Because of alignment constraints, this structure has padding and cannot
+ be mapped directly onto the beginning of the .debug_info section. */
+typedef struct statement_prologue
+ {
+ unsigned int total_length; /* byte length of the statement
+ information */
+ unsigned short version; /* version number -- 2 for DWARF
+ version 2 */
+ unsigned int prologue_length; /* # bytes between prologue &
+ stmt program */
+ unsigned char minimum_instruction_length; /* byte size of
+ smallest instr */
+ unsigned char default_is_stmt; /* initial value of is_stmt
+ register */
+ char line_base;
+ unsigned char line_range;
+ unsigned char opcode_base; /* number assigned to first special
+ opcode */
+ unsigned char *standard_opcode_lengths;
+ }
+_STATEMENT_PROLOGUE;
+
+/* offsets and sizes of debugging sections */
+
+static file_ptr dwarf_info_offset;
+static file_ptr dwarf_abbrev_offset;
+static file_ptr dwarf_line_offset;
+static file_ptr dwarf_pubnames_offset;
+static file_ptr dwarf_aranges_offset;
+static file_ptr dwarf_loc_offset;
+static file_ptr dwarf_macinfo_offset;
+static file_ptr dwarf_str_offset;
+file_ptr dwarf_frame_offset;
+file_ptr dwarf_eh_frame_offset;
+
+static unsigned int dwarf_info_size;
+static unsigned int dwarf_abbrev_size;
+static unsigned int dwarf_line_size;
+static unsigned int dwarf_pubnames_size;
+static unsigned int dwarf_aranges_size;
+static unsigned int dwarf_loc_size;
+static unsigned int dwarf_macinfo_size;
+static unsigned int dwarf_str_size;
+unsigned int dwarf_frame_size;
+unsigned int dwarf_eh_frame_size;
+
+/* names of the debugging sections */
+
+#define INFO_SECTION ".debug_info"
+#define ABBREV_SECTION ".debug_abbrev"
+#define LINE_SECTION ".debug_line"
+#define PUBNAMES_SECTION ".debug_pubnames"
+#define ARANGES_SECTION ".debug_aranges"
+#define LOC_SECTION ".debug_loc"
+#define MACINFO_SECTION ".debug_macinfo"
+#define STR_SECTION ".debug_str"
+#define FRAME_SECTION ".debug_frame"
+#define EH_FRAME_SECTION ".eh_frame"
+
+/* local data types */
+
+/* The data in a compilation unit header, after target2host
+ translation, looks like this. */
+struct comp_unit_head
+ {
+ unsigned long length;
+ short version;
+ unsigned int abbrev_offset;
+ unsigned char addr_size;
+ unsigned char signed_addr_p;
+ unsigned int offset_size; /* size of file offsets; either 4 or 8 */
+ unsigned int initial_length_size; /* size of the length field; either
+ 4 or 12 */
+ };
+
+/* The line number information for a compilation unit (found in the
+ .debug_line section) begins with a "statement program header",
+ which contains the following information. */
+struct line_header
+{
+ unsigned int total_length;
+ unsigned short version;
+ unsigned int header_length;
+ unsigned char minimum_instruction_length;
+ unsigned char default_is_stmt;
+ int line_base;
+ unsigned char line_range;
+ unsigned char opcode_base;
+
+ /* standard_opcode_lengths[i] is the number of operands for the
+ standard opcode whose value is i. This means that
+ standard_opcode_lengths[0] is unused, and the last meaningful
+ element is standard_opcode_lengths[opcode_base - 1]. */
+ unsigned char *standard_opcode_lengths;
+
+ /* The include_directories table. NOTE! These strings are not
+ allocated with xmalloc; instead, they are pointers into
+ debug_line_buffer. If you try to free them, `free' will get
+ indigestion. */
+ unsigned int num_include_dirs, include_dirs_size;
+ char **include_dirs;
+
+ /* The file_names table. NOTE! These strings are not allocated
+ with xmalloc; instead, they are pointers into debug_line_buffer.
+ Don't try to free them directly. */
+ unsigned int num_file_names, file_names_size;
+ struct file_entry
+ {
+ char *name;
+ unsigned int dir_index;
+ unsigned int mod_time;
+ unsigned int length;
+ } *file_names;
+
+ /* The start and end of the statement program following this
+ header. These point into dwarf_line_buffer. */
+ char *statement_program_start, *statement_program_end;
+};
+
+/* When we construct a partial symbol table entry we only
+ need this much information. */
+struct partial_die_info
+ {
+ enum dwarf_tag tag;
+ unsigned char has_children;
+ unsigned char is_external;
+ unsigned char is_declaration;
+ unsigned char has_type;
+ unsigned int offset;
+ unsigned int abbrev;
+ char *name;
+ int has_pc_info;
+ CORE_ADDR lowpc;
+ CORE_ADDR highpc;
+ struct dwarf_block *locdesc;
+ unsigned int language;
+ char *sibling;
+ };
+
+/* This data structure holds the information of an abbrev. */
+struct abbrev_info
+ {
+ unsigned int number; /* number identifying abbrev */
+ enum dwarf_tag tag; /* dwarf tag */
+ int has_children; /* boolean */
+ unsigned int num_attrs; /* number of attributes */
+ struct attr_abbrev *attrs; /* an array of attribute descriptions */
+ struct abbrev_info *next; /* next in chain */
+ };
+
+struct attr_abbrev
+ {
+ enum dwarf_attribute name;
+ enum dwarf_form form;
+ };
+
+/* This data structure holds a complete die structure. */
+struct die_info
+ {
+ enum dwarf_tag tag; /* Tag indicating type of die */
+ unsigned short has_children; /* Does the die have children */
+ unsigned int abbrev; /* Abbrev number */
+ unsigned int offset; /* Offset in .debug_info section */
+ unsigned int num_attrs; /* Number of attributes */
+ struct attribute *attrs; /* An array of attributes */
+ struct die_info *next_ref; /* Next die in ref hash table */
+ struct die_info *next; /* Next die in linked list */
+ struct type *type; /* Cached type information */
+ };
+
+/* Attributes have a name and a value */
+struct attribute
+ {
+ enum dwarf_attribute name;
+ enum dwarf_form form;
+ union
+ {
+ char *str;
+ struct dwarf_block *blk;
+ unsigned long unsnd;
+ long int snd;
+ CORE_ADDR addr;
+ }
+ u;
+ };
+
+struct function_range
+{
+ const char *name;
+ CORE_ADDR lowpc, highpc;
+ int seen_line;
+ struct function_range *next;
+};
+
+static struct function_range *cu_first_fn, *cu_last_fn, *cu_cached_fn;
+
+/* Get at parts of an attribute structure */
+
+#define DW_STRING(attr) ((attr)->u.str)
+#define DW_UNSND(attr) ((attr)->u.unsnd)
+#define DW_BLOCK(attr) ((attr)->u.blk)
+#define DW_SND(attr) ((attr)->u.snd)
+#define DW_ADDR(attr) ((attr)->u.addr)
+
+/* Blocks are a bunch of untyped bytes. */
+struct dwarf_block
+ {
+ unsigned int size;
+ char *data;
+ };
+
+/* We only hold one compilation unit's abbrevs in
+ memory at any one time. */
+#ifndef ABBREV_HASH_SIZE
+#define ABBREV_HASH_SIZE 121
+#endif
+#ifndef ATTR_ALLOC_CHUNK
+#define ATTR_ALLOC_CHUNK 4
+#endif
+
+static struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE];
+
+/* A hash table of die offsets for following references. */
+#ifndef REF_HASH_SIZE
+#define REF_HASH_SIZE 1021
+#endif
+
+static struct die_info *die_ref_table[REF_HASH_SIZE];
+
+/* Obstack for allocating temporary storage used during symbol reading. */
+static struct obstack dwarf2_tmp_obstack;
+
+/* Offset to the first byte of the current compilation unit header,
+ for resolving relative reference dies. */
+static unsigned int cu_header_offset;
+
+/* Allocate fields for structs, unions and enums in this size. */
+#ifndef DW_FIELD_ALLOC_CHUNK
+#define DW_FIELD_ALLOC_CHUNK 4
+#endif
+
+/* The language we are debugging. */
+static enum language cu_language;
+static const struct language_defn *cu_language_defn;
+
+/* Actually data from the sections. */
+static char *dwarf_info_buffer;
+static char *dwarf_abbrev_buffer;
+static char *dwarf_line_buffer;
+static char *dwarf_str_buffer;
+static char *dwarf_macinfo_buffer;
+
+/* A zeroed version of a partial die for initialization purposes. */
+static struct partial_die_info zeroed_partial_die;
+
+/* The generic symbol table building routines have separate lists for
+ file scope symbols and all all other scopes (local scopes). So
+ we need to select the right one to pass to add_symbol_to_list().
+ We do it by keeping a pointer to the correct list in list_in_scope.
+
+ FIXME: The original dwarf code just treated the file scope as the first
+ local scope, and all other local scopes as nested local scopes, and worked
+ fine. Check to see if we really need to distinguish these
+ in buildsym.c. */
+static struct pending **list_in_scope = &file_symbols;
+
+/* FIXME: decode_locdesc sets these variables to describe the location
+ to the caller. These ought to be a structure or something. If
+ none of the flags are set, the object lives at the address returned
+ by decode_locdesc. */
+
+static int optimized_out; /* No ops in location in expression,
+ so object was optimized out. */
+static int isreg; /* Object lives in register.
+ decode_locdesc's return value is
+ the register number. */
+static int offreg; /* Object's address is the sum of the
+ register specified by basereg, plus
+ the offset returned. */
+static int basereg; /* See `offreg'. */
+static int isderef; /* Value described by flags above is
+ the address of a pointer to the object. */
+static int islocal; /* Variable is at the returned offset
+ from the frame start, but there's
+ no identified frame pointer for
+ this function, so we can't say
+ which register it's relative to;
+ use LOC_LOCAL. */
+
+/* DW_AT_frame_base values for the current function.
+ frame_base_reg is -1 if DW_AT_frame_base is missing, otherwise it
+ contains the register number for the frame register.
+ frame_base_offset is the offset from the frame register to the
+ virtual stack frame. */
+static int frame_base_reg;
+static CORE_ADDR frame_base_offset;
+
+/* This value is added to each symbol value. FIXME: Generalize to
+ the section_offsets structure used by dbxread (once this is done,
+ pass the appropriate section number to end_symtab). */
+static CORE_ADDR baseaddr; /* Add to each symbol value */
+
+/* We put a pointer to this structure in the read_symtab_private field
+ of the psymtab.
+ The complete dwarf information for an objfile is kept in the
+ psymbol_obstack, so that absolute die references can be handled.
+ Most of the information in this structure is related to an entire
+ object file and could be passed via the sym_private field of the objfile.
+ It is however conceivable that dwarf2 might not be the only type
+ of symbols read from an object file. */
+
+struct dwarf2_pinfo
+ {
+ /* Pointer to start of dwarf info buffer for the objfile. */
+
+ char *dwarf_info_buffer;
+
+ /* Offset in dwarf_info_buffer for this compilation unit. */
+
+ unsigned long dwarf_info_offset;
+
+ /* Pointer to start of dwarf abbreviation buffer for the objfile. */
+
+ char *dwarf_abbrev_buffer;
+
+ /* Size of dwarf abbreviation section for the objfile. */
+
+ unsigned int dwarf_abbrev_size;
+
+ /* Pointer to start of dwarf line buffer for the objfile. */
+
+ char *dwarf_line_buffer;
+
+ /* Size of dwarf_line_buffer, in bytes. */
+
+ unsigned int dwarf_line_size;
+
+ /* Pointer to start of dwarf string buffer for the objfile. */
+
+ char *dwarf_str_buffer;
+
+ /* Size of dwarf string section for the objfile. */
+
+ unsigned int dwarf_str_size;
+
+ /* Pointer to start of dwarf macro buffer for the objfile. */
+
+ char *dwarf_macinfo_buffer;
+
+ /* Size of dwarf macinfo section for the objfile. */
+
+ unsigned int dwarf_macinfo_size;
+
+ };
+
+#define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private)
+#define DWARF_INFO_BUFFER(p) (PST_PRIVATE(p)->dwarf_info_buffer)
+#define DWARF_INFO_OFFSET(p) (PST_PRIVATE(p)->dwarf_info_offset)
+#define DWARF_ABBREV_BUFFER(p) (PST_PRIVATE(p)->dwarf_abbrev_buffer)
+#define DWARF_ABBREV_SIZE(p) (PST_PRIVATE(p)->dwarf_abbrev_size)
+#define DWARF_LINE_BUFFER(p) (PST_PRIVATE(p)->dwarf_line_buffer)
+#define DWARF_LINE_SIZE(p) (PST_PRIVATE(p)->dwarf_line_size)
+#define DWARF_STR_BUFFER(p) (PST_PRIVATE(p)->dwarf_str_buffer)
+#define DWARF_STR_SIZE(p) (PST_PRIVATE(p)->dwarf_str_size)
+#define DWARF_MACINFO_BUFFER(p) (PST_PRIVATE(p)->dwarf_macinfo_buffer)
+#define DWARF_MACINFO_SIZE(p) (PST_PRIVATE(p)->dwarf_macinfo_size)
+
+/* Maintain an array of referenced fundamental types for the current
+ compilation unit being read. For DWARF version 1, we have to construct
+ the fundamental types on the fly, since no information about the
+ fundamental types is supplied. Each such fundamental type is created by
+ calling a language dependent routine to create the type, and then a
+ pointer to that type is then placed in the array at the index specified
+ by it's FT_<TYPENAME> value. The array has a fixed size set by the
+ FT_NUM_MEMBERS compile time constant, which is the number of predefined
+ fundamental types gdb knows how to construct. */
+static struct type *ftypes[FT_NUM_MEMBERS]; /* Fundamental types */
+
+/* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
+ but this would require a corresponding change in unpack_field_as_long
+ and friends. */
+static int bits_per_byte = 8;
+
+/* The routines that read and process dies for a C struct or C++ class
+ pass lists of data member fields and lists of member function fields
+ in an instance of a field_info structure, as defined below. */
+struct field_info
+ {
+ /* List of data member and baseclasses fields. */
+ struct nextfield
+ {
+ struct nextfield *next;
+ int accessibility;
+ int virtuality;
+ struct field field;
+ }
+ *fields;
+
+ /* Number of fields. */
+ int nfields;
+
+ /* Number of baseclasses. */
+ int nbaseclasses;
+
+ /* Set if the accesibility of one of the fields is not public. */
+ int non_public_fields;
+
+ /* Member function fields array, entries are allocated in the order they
+ are encountered in the object file. */
+ struct nextfnfield
+ {
+ struct nextfnfield *next;
+ struct fn_field fnfield;
+ }
+ *fnfields;
+
+ /* Member function fieldlist array, contains name of possibly overloaded
+ member function, number of overloaded member functions and a pointer
+ to the head of the member function field chain. */
+ struct fnfieldlist
+ {
+ char *name;
+ int length;
+ struct nextfnfield *head;
+ }
+ *fnfieldlists;
+
+ /* Number of entries in the fnfieldlists array. */
+ int nfnfields;
+ };
+
+/* Various complaints about symbol reading that don't abort the process */
+
+static struct complaint dwarf2_const_ignored =
+{
+ "type qualifier 'const' ignored", 0, 0
+};
+static struct complaint dwarf2_volatile_ignored =
+{
+ "type qualifier 'volatile' ignored", 0, 0
+};
+static struct complaint dwarf2_non_const_array_bound_ignored =
+{
+ "non-constant array bounds form '%s' ignored", 0, 0
+};
+static struct complaint dwarf2_missing_line_number_section =
+{
+ "missing .debug_line section", 0, 0
+};
+static struct complaint dwarf2_statement_list_fits_in_line_number_section =
+{
+ "statement list doesn't fit in .debug_line section", 0, 0
+};
+static struct complaint dwarf2_mangled_line_number_section =
+{
+ "mangled .debug_line section", 0, 0
+};
+static struct complaint dwarf2_unsupported_die_ref_attr =
+{
+ "unsupported die ref attribute form: '%s'", 0, 0
+};
+static struct complaint dwarf2_unsupported_stack_op =
+{
+ "unsupported stack op: '%s'", 0, 0
+};
+static struct complaint dwarf2_complex_location_expr =
+{
+ "location expression too complex", 0, 0
+};
+static struct complaint dwarf2_unsupported_tag =
+{
+ "unsupported tag: '%s'", 0, 0
+};
+static struct complaint dwarf2_unsupported_at_encoding =
+{
+ "unsupported DW_AT_encoding: '%s'", 0, 0
+};
+static struct complaint dwarf2_unsupported_at_frame_base =
+{
+ "unsupported DW_AT_frame_base for function '%s'", 0, 0
+};
+static struct complaint dwarf2_unexpected_tag =
+{
+ "unexepected tag in read_type_die: '%s'", 0, 0
+};
+static struct complaint dwarf2_missing_at_frame_base =
+{
+ "DW_AT_frame_base missing for DW_OP_fbreg", 0, 0
+};
+static struct complaint dwarf2_bad_static_member_name =
+{
+ "unrecognized static data member name '%s'", 0, 0
+};
+static struct complaint dwarf2_unsupported_accessibility =
+{
+ "unsupported accessibility %d", 0, 0
+};
+static struct complaint dwarf2_bad_member_name_complaint =
+{
+ "cannot extract member name from '%s'", 0, 0
+};
+static struct complaint dwarf2_missing_member_fn_type_complaint =
+{
+ "member function type missing for '%s'", 0, 0
+};
+static struct complaint dwarf2_vtbl_not_found_complaint =
+{
+ "virtual function table pointer not found when defining class '%s'", 0, 0
+};
+static struct complaint dwarf2_absolute_sibling_complaint =
+{
+ "ignoring absolute DW_AT_sibling", 0, 0
+};
+static struct complaint dwarf2_const_value_length_mismatch =
+{
+ "const value length mismatch for '%s', got %d, expected %d", 0, 0
+};
+static struct complaint dwarf2_unsupported_const_value_attr =
+{
+ "unsupported const value attribute form: '%s'", 0, 0
+};
+static struct complaint dwarf2_misplaced_line_number =
+{
+ "misplaced first line number at 0x%lx for '%s'", 0, 0
+};
+static struct complaint dwarf2_line_header_too_long =
+{
+ "line number info header doesn't fit in `.debug_line' section", 0, 0
+};
+static struct complaint dwarf2_missing_macinfo_section =
+{
+ "missing .debug_macinfo section", 0, 0
+};
+static struct complaint dwarf2_macros_too_long =
+{
+ "macro info runs off end of `.debug_macinfo' section", 0, 0
+};
+static struct complaint dwarf2_macros_not_terminated =
+{
+ "no terminating 0-type entry for macros in `.debug_macinfo' section", 0, 0
+};
+static struct complaint dwarf2_macro_outside_file =
+{
+ "debug info gives macro %s outside of any file: %s", 0, 0
+};
+static struct complaint dwarf2_macro_unmatched_end_file =
+{
+ "macro debug info has an unmatched `close_file' directive", 0, 0
+};
+static struct complaint dwarf2_macro_malformed_definition =
+{
+ "macro debug info contains a malformed macro definition:\n`%s'", 0, 0
+};
+static struct complaint dwarf2_macro_spaces_in_definition =
+{
+ "macro definition contains spaces in formal argument list:\n`%s'", 0, 0
+};
+
+/* local function prototypes */
+
+static void dwarf2_locate_sections (bfd *, asection *, PTR);
+
+#if 0
+static void dwarf2_build_psymtabs_easy (struct objfile *, int);
+#endif
+
+static void dwarf2_build_psymtabs_hard (struct objfile *, int);
+
+static char *scan_partial_symbols (char *, struct objfile *,
+ CORE_ADDR *, CORE_ADDR *,
+ const struct comp_unit_head *);
+
+static void add_partial_symbol (struct partial_die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
+
+static void psymtab_to_symtab_1 (struct partial_symtab *);
+
+char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int);
+
+static void dwarf2_read_abbrevs (bfd *, unsigned int);
+
+static void dwarf2_empty_abbrev_table (PTR);
+
+static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int);
+
+static char *read_partial_die (struct partial_die_info *,
+ bfd *, char *,
+ const struct comp_unit_head *);
+
+static char *read_full_die (struct die_info **, bfd *, char *,
+ const struct comp_unit_head *);
+
+static char *read_attribute (struct attribute *, struct attr_abbrev *,
+ bfd *, char *, const struct comp_unit_head *);
+
+static char *read_attribute_value (struct attribute *, unsigned,
+ bfd *, char *, const struct comp_unit_head *);
+
+static unsigned int read_1_byte (bfd *, char *);
+
+static int read_1_signed_byte (bfd *, char *);
+
+static unsigned int read_2_bytes (bfd *, char *);
+
+static unsigned int read_4_bytes (bfd *, char *);
+
+static unsigned long read_8_bytes (bfd *, char *);
+
+static CORE_ADDR read_address (bfd *, char *ptr, const struct comp_unit_head *,
+ int *bytes_read);
+
+static LONGEST read_initial_length (bfd *, char *,
+ struct comp_unit_head *, int *bytes_read);
+
+static LONGEST read_offset (bfd *, char *, const struct comp_unit_head *,
+ int *bytes_read);
+
+static char *read_n_bytes (bfd *, char *, unsigned int);
+
+static char *read_string (bfd *, char *, unsigned int *);
+
+static char *read_indirect_string (bfd *, char *, const struct comp_unit_head *,
+ unsigned int *);
+
+static unsigned long read_unsigned_leb128 (bfd *, char *, unsigned int *);
+
+static long read_signed_leb128 (bfd *, char *, unsigned int *);
+
+static void set_cu_language (unsigned int);
+
+static struct attribute *dwarf_attr (struct die_info *, unsigned int);
+
+static int die_is_declaration (struct die_info *);
+
+static void free_line_header (struct line_header *lh);
+
+static struct line_header *(dwarf_decode_line_header
+ (unsigned int offset,
+ bfd *abfd,
+ const struct comp_unit_head *cu_header));
+
+static void dwarf_decode_lines (struct line_header *, char *, bfd *,
+ const struct comp_unit_head *);
+
+static void dwarf2_start_subfile (char *, char *);
+
+static struct symbol *new_symbol (struct die_info *, struct type *,
+ struct objfile *, const struct comp_unit_head *);
+
+static void dwarf2_const_value (struct attribute *, struct symbol *,
+ struct objfile *, const struct comp_unit_head *);
+
+static void dwarf2_const_value_data (struct attribute *attr,
+ struct symbol *sym,
+ int bits);
+
+static struct type *die_type (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static struct type *die_containing_type (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+#if 0
+static struct type *type_at_offset (unsigned int, struct objfile *);
+#endif
+
+static struct type *tag_type_to_type (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void read_type_die (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void read_typedef (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void read_base_type (struct die_info *, struct objfile *);
+
+static void read_file_scope (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void read_func_scope (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void read_lexical_block_scope (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static int dwarf2_get_pc_bounds (struct die_info *,
+ CORE_ADDR *, CORE_ADDR *, struct objfile *);
+
+static void dwarf2_add_field (struct field_info *, struct die_info *,
+ struct objfile *, const struct comp_unit_head *);
+
+static void dwarf2_attach_fields_to_type (struct field_info *,
+ struct type *, struct objfile *);
+
+static void dwarf2_add_member_fn (struct field_info *,
+ struct die_info *, struct type *,
+ struct objfile *objfile,
+ const struct comp_unit_head *);
+
+static void dwarf2_attach_fn_fields_to_type (struct field_info *,
+ struct type *, struct objfile *);
+
+static void read_structure_scope (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void read_common_block (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void read_enumeration (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static struct type *dwarf_base_type (int, int, struct objfile *);
+
+static CORE_ADDR decode_locdesc (struct dwarf_block *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void read_array_type (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void read_tag_pointer_type (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void read_tag_ptr_to_member_type (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void read_tag_reference_type (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void read_tag_const_type (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void read_tag_volatile_type (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static void read_tag_string_type (struct die_info *, struct objfile *);
+
+static void read_subroutine_type (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static struct die_info *read_comp_unit (char *, bfd *,
+ const struct comp_unit_head *);
+
+static void free_die_list (struct die_info *);
+
+static struct cleanup *make_cleanup_free_die_list (struct die_info *);
+
+static void process_die (struct die_info *, struct objfile *,
+ const struct comp_unit_head *);
+
+static char *dwarf2_linkage_name (struct die_info *);
+
+static char *dwarf_tag_name (unsigned int);
+
+static char *dwarf_attr_name (unsigned int);
+
+static char *dwarf_form_name (unsigned int);
+
+static char *dwarf_stack_op_name (unsigned int);
+
+static char *dwarf_bool_name (unsigned int);
+
+static char *dwarf_type_encoding_name (unsigned int);
+
+#if 0
+static char *dwarf_cfi_name (unsigned int);
+
+struct die_info *copy_die (struct die_info *);
+#endif
+
+static struct die_info *sibling_die (struct die_info *);
+
+static void dump_die (struct die_info *);
+
+static void dump_die_list (struct die_info *);
+
+static void store_in_ref_table (unsigned int, struct die_info *);
+
+static void dwarf2_empty_hash_tables (void);
+
+static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
+
+static struct die_info *follow_die_ref (unsigned int);
+
+static struct type *dwarf2_fundamental_type (struct objfile *, int);
+
+/* memory allocation interface */
+
+static void dwarf2_free_tmp_obstack (PTR);
+
+static struct dwarf_block *dwarf_alloc_block (void);
+
+static struct abbrev_info *dwarf_alloc_abbrev (void);
+
+static struct die_info *dwarf_alloc_die (void);
+
+static void initialize_cu_func_list (void);
+
+static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR);
+
+static void dwarf_decode_macros (struct line_header *, unsigned int,
+ char *, bfd *, const struct comp_unit_head *,
+ struct objfile *);
+
+/* Try to locate the sections we need for DWARF 2 debugging
+ information and return true if we have enough to do something. */
+
+int
+dwarf2_has_info (bfd *abfd)
+{
+ dwarf_info_offset = 0;
+ dwarf_abbrev_offset = 0;
+ dwarf_line_offset = 0;
+ dwarf_str_offset = 0;
+ dwarf_macinfo_offset = 0;
+ dwarf_frame_offset = 0;
+ dwarf_eh_frame_offset = 0;
+ bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL);
+ if (dwarf_info_offset && dwarf_abbrev_offset)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/* This function is mapped across the sections and remembers the
+ offset and size of each of the debugging sections we are interested
+ in. */
+
+static void
+dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, PTR ignore_ptr)
+{
+ if (STREQ (sectp->name, INFO_SECTION))
+ {
+ dwarf_info_offset = sectp->filepos;
+ dwarf_info_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, ABBREV_SECTION))
+ {
+ dwarf_abbrev_offset = sectp->filepos;
+ dwarf_abbrev_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, LINE_SECTION))
+ {
+ dwarf_line_offset = sectp->filepos;
+ dwarf_line_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, PUBNAMES_SECTION))
+ {
+ dwarf_pubnames_offset = sectp->filepos;
+ dwarf_pubnames_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, ARANGES_SECTION))
+ {
+ dwarf_aranges_offset = sectp->filepos;
+ dwarf_aranges_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, LOC_SECTION))
+ {
+ dwarf_loc_offset = sectp->filepos;
+ dwarf_loc_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, MACINFO_SECTION))
+ {
+ dwarf_macinfo_offset = sectp->filepos;
+ dwarf_macinfo_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, STR_SECTION))
+ {
+ dwarf_str_offset = sectp->filepos;
+ dwarf_str_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, FRAME_SECTION))
+ {
+ dwarf_frame_offset = sectp->filepos;
+ dwarf_frame_size = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, EH_FRAME_SECTION))
+ {
+ dwarf_eh_frame_offset = sectp->filepos;
+ dwarf_eh_frame_size = bfd_get_section_size_before_reloc (sectp);
+ }
+}
+
+/* Build a partial symbol table. */
+
+void
+dwarf2_build_psymtabs (struct objfile *objfile, int mainline)
+{
+
+ /* We definitely need the .debug_info and .debug_abbrev sections */
+
+ dwarf_info_buffer = dwarf2_read_section (objfile,
+ dwarf_info_offset,
+ dwarf_info_size);
+ dwarf_abbrev_buffer = dwarf2_read_section (objfile,
+ dwarf_abbrev_offset,
+ dwarf_abbrev_size);
+ dwarf_line_buffer = dwarf2_read_section (objfile,
+ dwarf_line_offset,
+ dwarf_line_size);
+
+ if (dwarf_str_offset)
+ dwarf_str_buffer = dwarf2_read_section (objfile,
+ dwarf_str_offset,
+ dwarf_str_size);
+ else
+ dwarf_str_buffer = NULL;
+
+ if (dwarf_macinfo_offset)
+ dwarf_macinfo_buffer = dwarf2_read_section (objfile,
+ dwarf_macinfo_offset,
+ dwarf_macinfo_size);
+ else
+ dwarf_macinfo_buffer = NULL;
+
+ if (mainline
+ || (objfile->global_psymbols.size == 0
+ && objfile->static_psymbols.size == 0))
+ {
+ init_psymbol_list (objfile, 1024);
+ }
+
+#if 0
+ if (dwarf_aranges_offset && dwarf_pubnames_offset)
+ {
+ /* Things are significantly easier if we have .debug_aranges and
+ .debug_pubnames sections */
+
+ dwarf2_build_psymtabs_easy (objfile, mainline);
+ }
+ else
+#endif
+ /* only test this case for now */
+ {
+ /* In this case we have to work a bit harder */
+ dwarf2_build_psymtabs_hard (objfile, mainline);
+ }
+}
+
+#if 0
+/* Build the partial symbol table from the information in the
+ .debug_pubnames and .debug_aranges sections. */
+
+static void
+dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline)
+{
+ bfd *abfd = objfile->obfd;
+ char *aranges_buffer, *pubnames_buffer;
+ char *aranges_ptr, *pubnames_ptr;
+ unsigned int entry_length, version, info_offset, info_size;
+
+ pubnames_buffer = dwarf2_read_section (objfile,
+ dwarf_pubnames_offset,
+ dwarf_pubnames_size);
+ pubnames_ptr = pubnames_buffer;
+ while ((pubnames_ptr - pubnames_buffer) < dwarf_pubnames_size)
+ {
+ struct comp_unit_head cu_header;
+ int bytes_read;
+
+ entry_length = read_initial_length (abfd, pubnames_ptr, &cu_header,
+ &bytes_read);
+ pubnames_ptr += bytes_read;
+ version = read_1_byte (abfd, pubnames_ptr);
+ pubnames_ptr += 1;
+ info_offset = read_4_bytes (abfd, pubnames_ptr);
+ pubnames_ptr += 4;
+ info_size = read_4_bytes (abfd, pubnames_ptr);
+ pubnames_ptr += 4;
+ }
+
+ aranges_buffer = dwarf2_read_section (objfile,
+ dwarf_aranges_offset,
+ dwarf_aranges_size);
+
+}
+#endif
+
+/* Read in the comp unit header information from the debug_info at
+ info_ptr. */
+
+static char *
+read_comp_unit_head (struct comp_unit_head *cu_header,
+ char *info_ptr, bfd *abfd)
+{
+ int signed_addr;
+ int bytes_read;
+ cu_header->length = read_initial_length (abfd, info_ptr, cu_header,
+ &bytes_read);
+ info_ptr += bytes_read;
+ cu_header->version = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ cu_header->abbrev_offset = read_offset (abfd, info_ptr, cu_header,
+ &bytes_read);
+ info_ptr += bytes_read;
+ cu_header->addr_size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ signed_addr = bfd_get_sign_extend_vma (abfd);
+ if (signed_addr < 0)
+ internal_error (__FILE__, __LINE__,
+ "read_comp_unit_head: dwarf from non elf file");
+ cu_header->signed_addr_p = signed_addr;
+ return info_ptr;
+}
+
+/* Build the partial symbol table by doing a quick pass through the
+ .debug_info and .debug_abbrev sections. */
+
+static void
+dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
+{
+ /* Instead of reading this into a big buffer, we should probably use
+ mmap() on architectures that support it. (FIXME) */
+ bfd *abfd = objfile->obfd;
+ char *info_ptr, *abbrev_ptr;
+ char *beg_of_comp_unit;
+ struct partial_die_info comp_unit_die;
+ struct partial_symtab *pst;
+ struct cleanup *back_to;
+ CORE_ADDR lowpc, highpc;
+
+ info_ptr = dwarf_info_buffer;
+ abbrev_ptr = dwarf_abbrev_buffer;
+
+ /* We use dwarf2_tmp_obstack for objects that don't need to survive
+ the partial symbol scan, like attribute values.
+
+ We could reduce our peak memory consumption during partial symbol
+ table construction by freeing stuff from this obstack more often
+ --- say, after processing each compilation unit, or each die ---
+ but it turns out that this saves almost nothing. For an
+ executable with 11Mb of Dwarf 2 data, I found about 64k allocated
+ on dwarf2_tmp_obstack. Some investigation showed:
+
+ 1) 69% of the attributes used forms DW_FORM_addr, DW_FORM_data*,
+ DW_FORM_flag, DW_FORM_[su]data, and DW_FORM_ref*. These are
+ all fixed-length values not requiring dynamic allocation.
+
+ 2) 30% of the attributes used the form DW_FORM_string. For
+ DW_FORM_string, read_attribute simply hands back a pointer to
+ the null-terminated string in dwarf_info_buffer, so no dynamic
+ allocation is needed there either.
+
+ 3) The remaining 1% of the attributes all used DW_FORM_block1.
+ 75% of those were DW_AT_frame_base location lists for
+ functions; the rest were DW_AT_location attributes, probably
+ for the global variables.
+
+ Anyway, what this all means is that the memory the dwarf2
+ reader uses as temporary space reading partial symbols is about
+ 0.5% as much as we use for dwarf_*_buffer. That's noise. */
+
+ obstack_init (&dwarf2_tmp_obstack);
+ back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
+
+ /* Since the objects we're extracting from dwarf_info_buffer vary in
+ length, only the individual functions to extract them (like
+ read_comp_unit_head and read_partial_die) can really know whether
+ the buffer is large enough to hold another complete object.
+
+ At the moment, they don't actually check that. If
+ dwarf_info_buffer holds just one extra byte after the last
+ compilation unit's dies, then read_comp_unit_head will happily
+ read off the end of the buffer. read_partial_die is similarly
+ casual. Those functions should be fixed.
+
+ For this loop condition, simply checking whether there's any data
+ left at all should be sufficient. */
+ while (info_ptr < dwarf_info_buffer + dwarf_info_size)
+ {
+ struct comp_unit_head cu_header;
+ beg_of_comp_unit = info_ptr;
+ info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd);
+
+ if (cu_header.version != 2)
+ {
+ error ("Dwarf Error: wrong version in compilation unit header.");
+ return;
+ }
+ if (cu_header.abbrev_offset >= dwarf_abbrev_size)
+ {
+ error ("Dwarf Error: bad offset (0x%lx) in compilation unit header (offset 0x%lx + 6).",
+ (long) cu_header.abbrev_offset,
+ (long) (beg_of_comp_unit - dwarf_info_buffer));
+ return;
+ }
+ if (beg_of_comp_unit + cu_header.length + cu_header.initial_length_size
+ > dwarf_info_buffer + dwarf_info_size)
+ {
+ error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0).",
+ (long) cu_header.length,
+ (long) (beg_of_comp_unit - dwarf_info_buffer));
+ return;
+ }
+ /* Read the abbrevs for this compilation unit into a table */
+ dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset);
+ make_cleanup (dwarf2_empty_abbrev_table, NULL);
+
+ /* Read the compilation unit die */
+ info_ptr = read_partial_die (&comp_unit_die, abfd, info_ptr,
+ &cu_header);
+
+ /* Set the language we're debugging */
+ set_cu_language (comp_unit_die.language);
+
+ /* Allocate a new partial symbol table structure */
+ pst = start_psymtab_common (objfile, objfile->section_offsets,
+ comp_unit_die.name ? comp_unit_die.name : "",
+ comp_unit_die.lowpc,
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+
+ pst->read_symtab_private = (char *)
+ obstack_alloc (&objfile->psymbol_obstack, sizeof (struct dwarf2_pinfo));
+ cu_header_offset = beg_of_comp_unit - dwarf_info_buffer;
+ DWARF_INFO_BUFFER (pst) = dwarf_info_buffer;
+ DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf_info_buffer;
+ DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
+ DWARF_ABBREV_SIZE (pst) = dwarf_abbrev_size;
+ DWARF_LINE_BUFFER (pst) = dwarf_line_buffer;
+ DWARF_LINE_SIZE (pst) = dwarf_line_size;
+ DWARF_STR_BUFFER (pst) = dwarf_str_buffer;
+ DWARF_STR_SIZE (pst) = dwarf_str_size;
+ DWARF_MACINFO_BUFFER (pst) = dwarf_macinfo_buffer;
+ DWARF_MACINFO_SIZE (pst) = dwarf_macinfo_size;
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+ /* Store the function that reads in the rest of the symbol table */
+ pst->read_symtab = dwarf2_psymtab_to_symtab;
+
+ /* Check if comp unit has_children.
+ If so, read the rest of the partial symbols from this comp unit.
+ If not, there's no more debug_info for this comp unit. */
+ if (comp_unit_die.has_children)
+ {
+ info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc,
+ &cu_header);
+
+ /* If the compilation unit didn't have an explicit address range,
+ then use the information extracted from its child dies. */
+ if (! comp_unit_die.has_pc_info)
+ {
+ comp_unit_die.lowpc = lowpc;
+ comp_unit_die.highpc = highpc;
+ }
+ }
+ pst->textlow = comp_unit_die.lowpc + baseaddr;
+ pst->texthigh = comp_unit_die.highpc + baseaddr;
+
+ pst->n_global_syms = objfile->global_psymbols.next -
+ (objfile->global_psymbols.list + pst->globals_offset);
+ pst->n_static_syms = objfile->static_psymbols.next -
+ (objfile->static_psymbols.list + pst->statics_offset);
+ sort_pst_symbols (pst);
+
+ /* If there is already a psymtab or symtab for a file of this
+ name, remove it. (If there is a symtab, more drastic things
+ also happen.) This happens in VxWorks. */
+ free_named_symtabs (pst->filename);
+
+ info_ptr = beg_of_comp_unit + cu_header.length
+ + cu_header.initial_length_size;
+ }
+ do_cleanups (back_to);
+}
+
+/* Read in all interesting dies to the end of the compilation unit. */
+
+static char *
+scan_partial_symbols (char *info_ptr, struct objfile *objfile,
+ CORE_ADDR *lowpc, CORE_ADDR *highpc,
+ const struct comp_unit_head *cu_header)
+{
+ bfd *abfd = objfile->obfd;
+ struct partial_die_info pdi;
+
+ /* This function is called after we've read in the comp_unit_die in
+ order to read its children. We start the nesting level at 1 since
+ we have pushed 1 level down in order to read the comp unit's children.
+ The comp unit itself is at level 0, so we stop reading when we pop
+ back to that level. */
+
+ int nesting_level = 1;
+
+ *lowpc = ((CORE_ADDR) -1);
+ *highpc = ((CORE_ADDR) 0);
+
+ while (nesting_level)
+ {
+ info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header);
+
+ if (pdi.name)
+ {
+ switch (pdi.tag)
+ {
+ case DW_TAG_subprogram:
+ if (pdi.has_pc_info)
+ {
+ if (pdi.lowpc < *lowpc)
+ {
+ *lowpc = pdi.lowpc;
+ }
+ if (pdi.highpc > *highpc)
+ {
+ *highpc = pdi.highpc;
+ }
+ if ((pdi.is_external || nesting_level == 1)
+ && !pdi.is_declaration)
+ {
+ add_partial_symbol (&pdi, objfile, cu_header);
+ }
+ }
+ break;
+ case DW_TAG_variable:
+ case DW_TAG_typedef:
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_enumeration_type:
+ if ((pdi.is_external || nesting_level == 1)
+ && !pdi.is_declaration)
+ {
+ add_partial_symbol (&pdi, objfile, cu_header);
+ }
+ break;
+ case DW_TAG_enumerator:
+ /* File scope enumerators are added to the partial symbol
+ table. */
+ if (nesting_level == 2)
+ add_partial_symbol (&pdi, objfile, cu_header);
+ break;
+ case DW_TAG_base_type:
+ /* File scope base type definitions are added to the partial
+ symbol table. */
+ if (nesting_level == 1)
+ add_partial_symbol (&pdi, objfile, cu_header);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* If the die has a sibling, skip to the sibling.
+ Do not skip enumeration types, we want to record their
+ enumerators. */
+ if (pdi.sibling && pdi.tag != DW_TAG_enumeration_type)
+ {
+ info_ptr = pdi.sibling;
+ }
+ else if (pdi.has_children)
+ {
+ /* Die has children, but the optional DW_AT_sibling attribute
+ is missing. */
+ nesting_level++;
+ }
+
+ if (pdi.tag == 0)
+ {
+ nesting_level--;
+ }
+ }
+
+ /* If we didn't find a lowpc, set it to highpc to avoid complaints
+ from `maint check'. */
+ if (*lowpc == ((CORE_ADDR) -1))
+ *lowpc = *highpc;
+ return info_ptr;
+}
+
+static void
+add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ CORE_ADDR addr = 0;
+
+ switch (pdi->tag)
+ {
+ case DW_TAG_subprogram:
+ if (pdi->is_external)
+ {
+ /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+ mst_text, objfile); */
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->global_psymbols,
+ 0, pdi->lowpc + baseaddr, cu_language, objfile);
+ }
+ else
+ {
+ /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+ mst_file_text, objfile); */
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->static_psymbols,
+ 0, pdi->lowpc + baseaddr, cu_language, objfile);
+ }
+ break;
+ case DW_TAG_variable:
+ if (pdi->is_external)
+ {
+ /* Global Variable.
+ Don't enter into the minimal symbol tables as there is
+ a minimal symbol table entry from the ELF symbols already.
+ Enter into partial symbol table if it has a location
+ descriptor or a type.
+ If the location descriptor is missing, new_symbol will create
+ a LOC_UNRESOLVED symbol, the address of the variable will then
+ be determined from the minimal symbol table whenever the variable
+ is referenced.
+ The address for the partial symbol table entry is not
+ used by GDB, but it comes in handy for debugging partial symbol
+ table building. */
+
+ if (pdi->locdesc)
+ addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
+ if (pdi->locdesc || pdi->has_type)
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->global_psymbols,
+ 0, addr + baseaddr, cu_language, objfile);
+ }
+ else
+ {
+ /* Static Variable. Skip symbols without location descriptors. */
+ if (pdi->locdesc == NULL)
+ return;
+ addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
+ /*prim_record_minimal_symbol (pdi->name, addr + baseaddr,
+ mst_file_data, objfile); */
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->static_psymbols,
+ 0, addr + baseaddr, cu_language, objfile);
+ }
+ break;
+ case DW_TAG_typedef:
+ case DW_TAG_base_type:
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0, cu_language, objfile);
+ break;
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_enumeration_type:
+ /* Skip aggregate types without children, these are external
+ references. */
+ if (pdi->has_children == 0)
+ return;
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ STRUCT_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0, cu_language, objfile);
+
+ if (cu_language == language_cplus)
+ {
+ /* For C++, these implicitly act as typedefs as well. */
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0, cu_language, objfile);
+ }
+ break;
+ case DW_TAG_enumerator:
+ add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0, cu_language, objfile);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Expand this partial symbol table into a full symbol table. */
+
+static void
+dwarf2_psymtab_to_symtab (struct partial_symtab *pst)
+{
+ /* FIXME: This is barely more than a stub. */
+ if (pst != NULL)
+ {
+ if (pst->readin)
+ {
+ warning ("bug: psymtab for %s is already read in.", pst->filename);
+ }
+ else
+ {
+ if (info_verbose)
+ {
+ printf_filtered ("Reading in symbols for %s...", pst->filename);
+ gdb_flush (gdb_stdout);
+ }
+
+ psymtab_to_symtab_1 (pst);
+
+ /* Finish up the debug error message. */
+ if (info_verbose)
+ printf_filtered ("done.\n");
+ }
+ }
+}
+
+static void
+psymtab_to_symtab_1 (struct partial_symtab *pst)
+{
+ struct objfile *objfile = pst->objfile;
+ bfd *abfd = objfile->obfd;
+ struct comp_unit_head cu_header;
+ struct die_info *dies;
+ unsigned long offset;
+ CORE_ADDR lowpc, highpc;
+ struct die_info *child_die;
+ char *info_ptr;
+ struct symtab *symtab;
+ struct cleanup *back_to;
+
+ /* Set local variables from the partial symbol table info. */
+ offset = DWARF_INFO_OFFSET (pst);
+ dwarf_info_buffer = DWARF_INFO_BUFFER (pst);
+ dwarf_abbrev_buffer = DWARF_ABBREV_BUFFER (pst);
+ dwarf_abbrev_size = DWARF_ABBREV_SIZE (pst);
+ dwarf_line_buffer = DWARF_LINE_BUFFER (pst);
+ dwarf_line_size = DWARF_LINE_SIZE (pst);
+ dwarf_str_buffer = DWARF_STR_BUFFER (pst);
+ dwarf_str_size = DWARF_STR_SIZE (pst);
+ dwarf_macinfo_buffer = DWARF_MACINFO_BUFFER (pst);
+ dwarf_macinfo_size = DWARF_MACINFO_SIZE (pst);
+ baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
+ cu_header_offset = offset;
+ info_ptr = dwarf_info_buffer + offset;
+
+ obstack_init (&dwarf2_tmp_obstack);
+ back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
+
+ buildsym_init ();
+ make_cleanup (really_free_pendings, NULL);
+
+ /* read in the comp_unit header */
+ info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd);
+
+ /* Read the abbrevs for this compilation unit */
+ dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset);
+ make_cleanup (dwarf2_empty_abbrev_table, NULL);
+
+ dies = read_comp_unit (info_ptr, abfd, &cu_header);
+
+ make_cleanup_free_die_list (dies);
+
+ /* Do line number decoding in read_file_scope () */
+ process_die (dies, objfile, &cu_header);
+
+ if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile))
+ {
+ /* Some compilers don't define a DW_AT_high_pc attribute for
+ the compilation unit. If the DW_AT_high_pc is missing,
+ synthesize it, by scanning the DIE's below the compilation unit. */
+ highpc = 0;
+ if (dies->has_children)
+ {
+ child_die = dies->next;
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag == DW_TAG_subprogram)
+ {
+ CORE_ADDR low, high;
+
+ if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile))
+ {
+ highpc = max (highpc, high);
+ }
+ }
+ child_die = sibling_die (child_die);
+ }
+ }
+ }
+ symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
+
+ /* Set symtab language to language from DW_AT_language.
+ If the compilation is from a C file generated by language preprocessors,
+ do not set the language if it was already deduced by start_subfile. */
+ if (symtab != NULL
+ && !(cu_language == language_c && symtab->language != language_c))
+ {
+ symtab->language = cu_language;
+ }
+ pst->symtab = symtab;
+ pst->readin = 1;
+ sort_symtab_syms (pst->symtab);
+
+ do_cleanups (back_to);
+}
+
+/* Process a die and its children. */
+
+static void
+process_die (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ switch (die->tag)
+ {
+ case DW_TAG_padding:
+ break;
+ case DW_TAG_compile_unit:
+ read_file_scope (die, objfile, cu_header);
+ break;
+ case DW_TAG_subprogram:
+ read_subroutine_type (die, objfile, cu_header);
+ read_func_scope (die, objfile, cu_header);
+ break;
+ case DW_TAG_inlined_subroutine:
+ /* FIXME: These are ignored for now.
+ They could be used to set breakpoints on all inlined instances
+ of a function and make GDB `next' properly over inlined functions. */
+ break;
+ case DW_TAG_lexical_block:
+ read_lexical_block_scope (die, objfile, cu_header);
+ break;
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ read_structure_scope (die, objfile, cu_header);
+ break;
+ case DW_TAG_enumeration_type:
+ read_enumeration (die, objfile, cu_header);
+ break;
+ case DW_TAG_subroutine_type:
+ read_subroutine_type (die, objfile, cu_header);
+ break;
+ case DW_TAG_array_type:
+ read_array_type (die, objfile, cu_header);
+ break;
+ case DW_TAG_pointer_type:
+ read_tag_pointer_type (die, objfile, cu_header);
+ break;
+ case DW_TAG_ptr_to_member_type:
+ read_tag_ptr_to_member_type (die, objfile, cu_header);
+ break;
+ case DW_TAG_reference_type:
+ read_tag_reference_type (die, objfile, cu_header);
+ break;
+ case DW_TAG_string_type:
+ read_tag_string_type (die, objfile);
+ break;
+ case DW_TAG_base_type:
+ read_base_type (die, objfile);
+ if (dwarf_attr (die, DW_AT_name))
+ {
+ /* Add a typedef symbol for the base type definition. */
+ new_symbol (die, die->type, objfile, cu_header);
+ }
+ break;
+ case DW_TAG_common_block:
+ read_common_block (die, objfile, cu_header);
+ break;
+ case DW_TAG_common_inclusion:
+ break;
+ default:
+ new_symbol (die, NULL, objfile, cu_header);
+ break;
+ }
+}
+
+static void
+initialize_cu_func_list (void)
+{
+ cu_first_fn = cu_last_fn = cu_cached_fn = NULL;
+}
+
+static void
+read_file_scope (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct cleanup *back_to = make_cleanup (null_cleanup, 0);
+ CORE_ADDR lowpc = ((CORE_ADDR) -1);
+ CORE_ADDR highpc = ((CORE_ADDR) 0);
+ struct attribute *attr;
+ char *name = "<unknown>";
+ char *comp_dir = NULL;
+ struct die_info *child_die;
+ bfd *abfd = objfile->obfd;
+ struct line_header *line_header = 0;
+
+ if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
+ {
+ if (die->has_children)
+ {
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag == DW_TAG_subprogram)
+ {
+ CORE_ADDR low, high;
+
+ if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile))
+ {
+ lowpc = min (lowpc, low);
+ highpc = max (highpc, high);
+ }
+ }
+ child_die = sibling_die (child_die);
+ }
+ }
+ }
+
+ /* If we didn't find a lowpc, set it to highpc to avoid complaints
+ from finish_block. */
+ if (lowpc == ((CORE_ADDR) -1))
+ lowpc = highpc;
+ lowpc += baseaddr;
+ highpc += baseaddr;
+
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr)
+ {
+ name = DW_STRING (attr);
+ }
+ attr = dwarf_attr (die, DW_AT_comp_dir);
+ if (attr)
+ {
+ comp_dir = DW_STRING (attr);
+ if (comp_dir)
+ {
+ /* Irix 6.2 native cc prepends <machine>.: to the compilation
+ directory, get rid of it. */
+ char *cp = strchr (comp_dir, ':');
+
+ if (cp && cp != comp_dir && cp[-1] == '.' && cp[1] == '/')
+ comp_dir = cp + 1;
+ }
+ }
+
+ if (objfile->ei.entry_point >= lowpc &&
+ objfile->ei.entry_point < highpc)
+ {
+ objfile->ei.entry_file_lowpc = lowpc;
+ objfile->ei.entry_file_highpc = highpc;
+ }
+
+ attr = dwarf_attr (die, DW_AT_language);
+ if (attr)
+ {
+ set_cu_language (DW_UNSND (attr));
+ }
+
+ /* We assume that we're processing GCC output. */
+ processing_gcc_compilation = 2;
+#if 0
+ /* FIXME:Do something here. */
+ if (dip->at_producer != NULL)
+ {
+ handle_producer (dip->at_producer);
+ }
+#endif
+
+ /* The compilation unit may be in a different language or objfile,
+ zero out all remembered fundamental types. */
+ memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
+
+ start_symtab (name, comp_dir, lowpc);
+ record_debugformat ("DWARF 2");
+
+ initialize_cu_func_list ();
+
+ /* Process all dies in compilation unit. */
+ if (die->has_children)
+ {
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ process_die (child_die, objfile, cu_header);
+ child_die = sibling_die (child_die);
+ }
+ }
+
+ /* Decode line number information if present. */
+ attr = dwarf_attr (die, DW_AT_stmt_list);
+ if (attr)
+ {
+ unsigned int line_offset = DW_UNSND (attr);
+ line_header = dwarf_decode_line_header (line_offset,
+ abfd, cu_header);
+ if (line_header)
+ {
+ make_cleanup ((make_cleanup_ftype *) free_line_header,
+ (void *) line_header);
+ dwarf_decode_lines (line_header, comp_dir, abfd, cu_header);
+ }
+ }
+
+ /* Decode macro information, if present. Dwarf 2 macro information
+ refers to information in the line number info statement program
+ header, so we can only read it if we've read the header
+ successfully. */
+ attr = dwarf_attr (die, DW_AT_macro_info);
+ if (attr)
+ {
+ unsigned int macro_offset = DW_UNSND (attr);
+ dwarf_decode_macros (line_header, macro_offset,
+ comp_dir, abfd, cu_header, objfile);
+ }
+ do_cleanups (back_to);
+}
+
+static void
+add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc)
+{
+ struct function_range *thisfn;
+
+ thisfn = (struct function_range *)
+ obstack_alloc (&dwarf2_tmp_obstack, sizeof (struct function_range));
+ thisfn->name = name;
+ thisfn->lowpc = lowpc;
+ thisfn->highpc = highpc;
+ thisfn->seen_line = 0;
+ thisfn->next = NULL;
+
+ if (cu_last_fn == NULL)
+ cu_first_fn = thisfn;
+ else
+ cu_last_fn->next = thisfn;
+
+ cu_last_fn = thisfn;
+}
+
+static void
+read_func_scope (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ register struct context_stack *new;
+ CORE_ADDR lowpc;
+ CORE_ADDR highpc;
+ struct die_info *child_die;
+ struct attribute *attr;
+ char *name;
+
+ name = dwarf2_linkage_name (die);
+
+ /* Ignore functions with missing or empty names and functions with
+ missing or invalid low and high pc attributes. */
+ if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
+ return;
+
+ lowpc += baseaddr;
+ highpc += baseaddr;
+
+ /* Record the function range for dwarf_decode_lines. */
+ add_to_cu_func_list (name, lowpc, highpc);
+
+ if (objfile->ei.entry_point >= lowpc &&
+ objfile->ei.entry_point < highpc)
+ {
+ objfile->ei.entry_func_lowpc = lowpc;
+ objfile->ei.entry_func_highpc = highpc;
+ }
+
+ /* Decode DW_AT_frame_base location descriptor if present, keep result
+ for DW_OP_fbreg operands in decode_locdesc. */
+ frame_base_reg = -1;
+ frame_base_offset = 0;
+ attr = dwarf_attr (die, DW_AT_frame_base);
+ if (attr)
+ {
+ CORE_ADDR addr = decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
+ if (isderef)
+ complain (&dwarf2_unsupported_at_frame_base, name);
+ else if (isreg)
+ frame_base_reg = addr;
+ else if (offreg)
+ {
+ frame_base_reg = basereg;
+ frame_base_offset = addr;
+ }
+ else
+ complain (&dwarf2_unsupported_at_frame_base, name);
+ }
+
+ new = push_context (0, lowpc);
+ new->name = new_symbol (die, die->type, objfile, cu_header);
+ list_in_scope = &local_symbols;
+
+ if (die->has_children)
+ {
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ process_die (child_die, objfile, cu_header);
+ child_die = sibling_die (child_die);
+ }
+ }
+
+ new = pop_context ();
+ /* Make a block for the local symbols within. */
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ lowpc, highpc, objfile);
+ list_in_scope = &file_symbols;
+}
+
+/* Process all the DIES contained within a lexical block scope. Start
+ a new scope, process the dies, and then close the scope. */
+
+static void
+read_lexical_block_scope (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ register struct context_stack *new;
+ CORE_ADDR lowpc, highpc;
+ struct die_info *child_die;
+
+ /* Ignore blocks with missing or invalid low and high pc attributes. */
+ if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
+ return;
+ lowpc += baseaddr;
+ highpc += baseaddr;
+
+ push_context (0, lowpc);
+ if (die->has_children)
+ {
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ process_die (child_die, objfile, cu_header);
+ child_die = sibling_die (child_die);
+ }
+ }
+ new = pop_context ();
+
+ if (local_symbols != NULL)
+ {
+ finish_block (0, &local_symbols, new->old_blocks, new->start_addr,
+ highpc, objfile);
+ }
+ local_symbols = new->locals;
+}
+
+/* Get low and high pc attributes from a die.
+ Return 1 if the attributes are present and valid, otherwise, return 0. */
+
+static int
+dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, CORE_ADDR *highpc,
+ struct objfile *objfile)
+{
+ struct attribute *attr;
+ CORE_ADDR low;
+ CORE_ADDR high;
+
+ attr = dwarf_attr (die, DW_AT_low_pc);
+ if (attr)
+ low = DW_ADDR (attr);
+ else
+ return 0;
+ attr = dwarf_attr (die, DW_AT_high_pc);
+ if (attr)
+ high = DW_ADDR (attr);
+ else
+ return 0;
+
+ if (high < low)
+ return 0;
+
+ /* When using the GNU linker, .gnu.linkonce. sections are used to
+ eliminate duplicate copies of functions and vtables and such.
+ The linker will arbitrarily choose one and discard the others.
+ The AT_*_pc values for such functions refer to local labels in
+ these sections. If the section from that file was discarded, the
+ labels are not in the output, so the relocs get a value of 0.
+ If this is a discarded function, mark the pc bounds as invalid,
+ so that GDB will ignore it. */
+ if (low == 0 && (bfd_get_file_flags (objfile->obfd) & HAS_RELOC) == 0)
+ return 0;
+
+ *lowpc = low;
+ *highpc = high;
+ return 1;
+}
+
+/* Add an aggregate field to the field list. */
+
+static void
+dwarf2_add_field (struct field_info *fip, struct die_info *die,
+ struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct nextfield *new_field;
+ struct attribute *attr;
+ struct field *fp;
+ char *fieldname = "";
+
+ /* Allocate a new field list entry and link it in. */
+ new_field = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+ make_cleanup (xfree, new_field);
+ memset (new_field, 0, sizeof (struct nextfield));
+ new_field->next = fip->fields;
+ fip->fields = new_field;
+ fip->nfields++;
+
+ /* Handle accessibility and virtuality of field.
+ The default accessibility for members is public, the default
+ accessibility for inheritance is private. */
+ if (die->tag != DW_TAG_inheritance)
+ new_field->accessibility = DW_ACCESS_public;
+ else
+ new_field->accessibility = DW_ACCESS_private;
+ new_field->virtuality = DW_VIRTUALITY_none;
+
+ attr = dwarf_attr (die, DW_AT_accessibility);
+ if (attr)
+ new_field->accessibility = DW_UNSND (attr);
+ if (new_field->accessibility != DW_ACCESS_public)
+ fip->non_public_fields = 1;
+ attr = dwarf_attr (die, DW_AT_virtuality);
+ if (attr)
+ new_field->virtuality = DW_UNSND (attr);
+
+ fp = &new_field->field;
+ if (die->tag == DW_TAG_member)
+ {
+ /* Get type of field. */
+ fp->type = die_type (die, objfile, cu_header);
+
+ /* Get bit size of field (zero if none). */
+ attr = dwarf_attr (die, DW_AT_bit_size);
+ if (attr)
+ {
+ FIELD_BITSIZE (*fp) = DW_UNSND (attr);
+ }
+ else
+ {
+ FIELD_BITSIZE (*fp) = 0;
+ }
+
+ /* Get bit offset of field. */
+ attr = dwarf_attr (die, DW_AT_data_member_location);
+ if (attr)
+ {
+ FIELD_BITPOS (*fp) =
+ decode_locdesc (DW_BLOCK (attr), objfile, cu_header) * bits_per_byte;
+ }
+ else
+ FIELD_BITPOS (*fp) = 0;
+ attr = dwarf_attr (die, DW_AT_bit_offset);
+ if (attr)
+ {
+ if (BITS_BIG_ENDIAN)
+ {
+ /* For big endian bits, the DW_AT_bit_offset gives the
+ additional bit offset from the MSB of the containing
+ anonymous object to the MSB of the field. We don't
+ have to do anything special since we don't need to
+ know the size of the anonymous object. */
+ FIELD_BITPOS (*fp) += DW_UNSND (attr);
+ }
+ else
+ {
+ /* For little endian bits, compute the bit offset to the
+ MSB of the anonymous object, subtract off the number of
+ bits from the MSB of the field to the MSB of the
+ object, and then subtract off the number of bits of
+ the field itself. The result is the bit offset of
+ the LSB of the field. */
+ int anonymous_size;
+ int bit_offset = DW_UNSND (attr);
+
+ attr = dwarf_attr (die, DW_AT_byte_size);
+ if (attr)
+ {
+ /* The size of the anonymous object containing
+ the bit field is explicit, so use the
+ indicated size (in bytes). */
+ anonymous_size = DW_UNSND (attr);
+ }
+ else
+ {
+ /* The size of the anonymous object containing
+ the bit field must be inferred from the type
+ attribute of the data member containing the
+ bit field. */
+ anonymous_size = TYPE_LENGTH (fp->type);
+ }
+ FIELD_BITPOS (*fp) += anonymous_size * bits_per_byte
+ - bit_offset - FIELD_BITSIZE (*fp);
+ }
+ }
+
+ /* Get name of field. */
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ fieldname = DW_STRING (attr);
+ fp->name = obsavestring (fieldname, strlen (fieldname),
+ &objfile->type_obstack);
+
+ /* Change accessibility for artificial fields (e.g. virtual table
+ pointer or virtual base class pointer) to private. */
+ if (dwarf_attr (die, DW_AT_artificial))
+ {
+ new_field->accessibility = DW_ACCESS_private;
+ fip->non_public_fields = 1;
+ }
+ }
+ else if (die->tag == DW_TAG_variable)
+ {
+ char *physname;
+
+ /* C++ static member.
+ Get name of field. */
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ fieldname = DW_STRING (attr);
+ else
+ return;
+
+ /* Get physical name. */
+ physname = dwarf2_linkage_name (die);
+
+ SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname),
+ &objfile->type_obstack));
+ FIELD_TYPE (*fp) = die_type (die, objfile, cu_header);
+ FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname),
+ &objfile->type_obstack);
+ }
+ else if (die->tag == DW_TAG_inheritance)
+ {
+ /* C++ base class field. */
+ attr = dwarf_attr (die, DW_AT_data_member_location);
+ if (attr)
+ FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), objfile, cu_header)
+ * bits_per_byte);
+ FIELD_BITSIZE (*fp) = 0;
+ FIELD_TYPE (*fp) = die_type (die, objfile, cu_header);
+ FIELD_NAME (*fp) = type_name_no_tag (fp->type);
+ fip->nbaseclasses++;
+ }
+}
+
+/* Create the vector of fields, and attach it to the type. */
+
+static void
+dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
+ struct objfile *objfile)
+{
+ int nfields = fip->nfields;
+
+ /* Record the field count, allocate space for the array of fields,
+ and create blank accessibility bitfields if necessary. */
+ TYPE_NFIELDS (type) = nfields;
+ TYPE_FIELDS (type) = (struct field *)
+ TYPE_ALLOC (type, sizeof (struct field) * nfields);
+ memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
+
+ if (fip->non_public_fields)
+ {
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+
+ TYPE_FIELD_PRIVATE_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
+
+ TYPE_FIELD_PROTECTED_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
+
+ TYPE_FIELD_IGNORE_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
+ }
+
+ /* If the type has baseclasses, allocate and clear a bit vector for
+ TYPE_FIELD_VIRTUAL_BITS. */
+ if (fip->nbaseclasses)
+ {
+ int num_bytes = B_BYTES (fip->nbaseclasses);
+ char *pointer;
+
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ pointer = (char *) TYPE_ALLOC (type, num_bytes);
+ TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer;
+ B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), fip->nbaseclasses);
+ TYPE_N_BASECLASSES (type) = fip->nbaseclasses;
+ }
+
+ /* Copy the saved-up fields into the field vector. Start from the head
+ of the list, adding to the tail of the field array, so that they end
+ up in the same order in the array in which they were added to the list. */
+ while (nfields-- > 0)
+ {
+ TYPE_FIELD (type, nfields) = fip->fields->field;
+ switch (fip->fields->accessibility)
+ {
+ case DW_ACCESS_private:
+ SET_TYPE_FIELD_PRIVATE (type, nfields);
+ break;
+
+ case DW_ACCESS_protected:
+ SET_TYPE_FIELD_PROTECTED (type, nfields);
+ break;
+
+ case DW_ACCESS_public:
+ break;
+
+ default:
+ /* Unknown accessibility. Complain and treat it as public. */
+ {
+ complain (&dwarf2_unsupported_accessibility,
+ fip->fields->accessibility);
+ }
+ break;
+ }
+ if (nfields < fip->nbaseclasses)
+ {
+ switch (fip->fields->virtuality)
+ {
+ case DW_VIRTUALITY_virtual:
+ case DW_VIRTUALITY_pure_virtual:
+ SET_TYPE_FIELD_VIRTUAL (type, nfields);
+ break;
+ }
+ }
+ fip->fields = fip->fields->next;
+ }
+}
+
+/* Add a member function to the proper fieldlist. */
+
+static void
+dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
+ struct type *type, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct attribute *attr;
+ struct fnfieldlist *flp;
+ int i;
+ struct fn_field *fnp;
+ char *fieldname;
+ char *physname;
+ struct nextfnfield *new_fnfield;
+
+ /* Get name of member function. */
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ fieldname = DW_STRING (attr);
+ else
+ return;
+
+ /* Get the mangled name. */
+ physname = dwarf2_linkage_name (die);
+
+ /* Look up member function name in fieldlist. */
+ for (i = 0; i < fip->nfnfields; i++)
+ {
+ if (STREQ (fip->fnfieldlists[i].name, fieldname))
+ break;
+ }
+
+ /* Create new list element if necessary. */
+ if (i < fip->nfnfields)
+ flp = &fip->fnfieldlists[i];
+ else
+ {
+ if ((fip->nfnfields % DW_FIELD_ALLOC_CHUNK) == 0)
+ {
+ fip->fnfieldlists = (struct fnfieldlist *)
+ xrealloc (fip->fnfieldlists,
+ (fip->nfnfields + DW_FIELD_ALLOC_CHUNK)
+ * sizeof (struct fnfieldlist));
+ if (fip->nfnfields == 0)
+ make_cleanup (free_current_contents, &fip->fnfieldlists);
+ }
+ flp = &fip->fnfieldlists[fip->nfnfields];
+ flp->name = fieldname;
+ flp->length = 0;
+ flp->head = NULL;
+ fip->nfnfields++;
+ }
+
+ /* Create a new member function field and chain it to the field list
+ entry. */
+ new_fnfield = (struct nextfnfield *) xmalloc (sizeof (struct nextfnfield));
+ make_cleanup (xfree, new_fnfield);
+ memset (new_fnfield, 0, sizeof (struct nextfnfield));
+ new_fnfield->next = flp->head;
+ flp->head = new_fnfield;
+ flp->length++;
+
+ /* Fill in the member function field info. */
+ fnp = &new_fnfield->fnfield;
+ fnp->physname = obsavestring (physname, strlen (physname),
+ &objfile->type_obstack);
+ fnp->type = alloc_type (objfile);
+ if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC)
+ {
+ struct type *return_type = TYPE_TARGET_TYPE (die->type);
+ struct type **arg_types;
+ int nparams = TYPE_NFIELDS (die->type);
+ int iparams;
+
+ /* Copy argument types from the subroutine type. */
+ arg_types = (struct type **)
+ TYPE_ALLOC (fnp->type, (nparams + 1) * sizeof (struct type *));
+ for (iparams = 0; iparams < nparams; iparams++)
+ arg_types[iparams] = TYPE_FIELD_TYPE (die->type, iparams);
+
+ /* Set last entry in argument type vector. */
+ if (TYPE_VARARGS (die->type))
+ arg_types[nparams] = NULL;
+ else
+ arg_types[nparams] = dwarf2_fundamental_type (objfile, FT_VOID);
+
+ smash_to_method_type (fnp->type, type, return_type, arg_types);
+
+ /* Handle static member functions.
+ Dwarf2 has no clean way to discern C++ static and non-static
+ member functions. G++ helps GDB by marking the first
+ parameter for non-static member functions (which is the
+ this pointer) as artificial. We obtain this information
+ from read_subroutine_type via TYPE_FIELD_ARTIFICIAL. */
+ if (nparams == 0 || TYPE_FIELD_ARTIFICIAL (die->type, 0) == 0)
+ fnp->voffset = VOFFSET_STATIC;
+ }
+ else
+ complain (&dwarf2_missing_member_fn_type_complaint, physname);
+
+ /* Get fcontext from DW_AT_containing_type if present. */
+ if (dwarf_attr (die, DW_AT_containing_type) != NULL)
+ fnp->fcontext = die_containing_type (die, objfile, cu_header);
+
+ /* dwarf2 doesn't have stubbed physical names, so the setting of is_const
+ and is_volatile is irrelevant, as it is needed by gdb_mangle_name only. */
+
+ /* Get accessibility. */
+ attr = dwarf_attr (die, DW_AT_accessibility);
+ if (attr)
+ {
+ switch (DW_UNSND (attr))
+ {
+ case DW_ACCESS_private:
+ fnp->is_private = 1;
+ break;
+ case DW_ACCESS_protected:
+ fnp->is_protected = 1;
+ break;
+ }
+ }
+
+ /* Check for artificial methods. */
+ attr = dwarf_attr (die, DW_AT_artificial);
+ if (attr && DW_UNSND (attr) != 0)
+ fnp->is_artificial = 1;
+
+ /* Get index in virtual function table if it is a virtual member function. */
+ attr = dwarf_attr (die, DW_AT_vtable_elem_location);
+ if (attr)
+ fnp->voffset = decode_locdesc (DW_BLOCK (attr), objfile, cu_header) + 2;
+}
+
+/* Create the vector of member function fields, and attach it to the type. */
+
+static void
+dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type,
+ struct objfile *objfile)
+{
+ struct fnfieldlist *flp;
+ int total_length = 0;
+ int i;
+
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
+ TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * fip->nfnfields);
+
+ for (i = 0, flp = fip->fnfieldlists; i < fip->nfnfields; i++, flp++)
+ {
+ struct nextfnfield *nfp = flp->head;
+ struct fn_fieldlist *fn_flp = &TYPE_FN_FIELDLIST (type, i);
+ int k;
+
+ TYPE_FN_FIELDLIST_NAME (type, i) = flp->name;
+ TYPE_FN_FIELDLIST_LENGTH (type, i) = flp->length;
+ fn_flp->fn_fields = (struct fn_field *)
+ TYPE_ALLOC (type, sizeof (struct fn_field) * flp->length);
+ for (k = flp->length; (k--, nfp); nfp = nfp->next)
+ fn_flp->fn_fields[k] = nfp->fnfield;
+
+ total_length += flp->length;
+ }
+
+ TYPE_NFN_FIELDS (type) = fip->nfnfields;
+ TYPE_NFN_FIELDS_TOTAL (type) = total_length;
+}
+
+/* Called when we find the DIE that starts a structure or union scope
+ (definition) to process all dies that define the members of the
+ structure or union.
+
+ NOTE: we need to call struct_type regardless of whether or not the
+ DIE has an at_name attribute, since it might be an anonymous
+ structure or union. This gets the type entered into our set of
+ user defined types.
+
+ However, if the structure is incomplete (an opaque struct/union)
+ then suppress creating a symbol table entry for it since gdb only
+ wants to find the one with the complete definition. Note that if
+ it is complete, we just call new_symbol, which does it's own
+ checking about whether the struct/union is anonymous or not (and
+ suppresses creating a symbol table entry itself). */
+
+static void
+read_structure_scope (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct type *type;
+ struct attribute *attr;
+
+ type = alloc_type (objfile);
+
+ INIT_CPLUS_SPECIFIC (type);
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ {
+ TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
+ strlen (DW_STRING (attr)),
+ &objfile->type_obstack);
+ }
+
+ if (die->tag == DW_TAG_structure_type)
+ {
+ TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ }
+ else if (die->tag == DW_TAG_union_type)
+ {
+ TYPE_CODE (type) = TYPE_CODE_UNION;
+ }
+ else
+ {
+ /* FIXME: TYPE_CODE_CLASS is currently defined to TYPE_CODE_STRUCT
+ in gdbtypes.h. */
+ TYPE_CODE (type) = TYPE_CODE_CLASS;
+ }
+
+ attr = dwarf_attr (die, DW_AT_byte_size);
+ if (attr)
+ {
+ TYPE_LENGTH (type) = DW_UNSND (attr);
+ }
+ else
+ {
+ TYPE_LENGTH (type) = 0;
+ }
+
+ /* We need to add the type field to the die immediately so we don't
+ infinitely recurse when dealing with pointers to the structure
+ type within the structure itself. */
+ die->type = type;
+
+ if (die->has_children && ! die_is_declaration (die))
+ {
+ struct field_info fi;
+ struct die_info *child_die;
+ struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
+
+ memset (&fi, 0, sizeof (struct field_info));
+
+ child_die = die->next;
+
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag == DW_TAG_member)
+ {
+ dwarf2_add_field (&fi, child_die, objfile, cu_header);
+ }
+ else if (child_die->tag == DW_TAG_variable)
+ {
+ /* C++ static member. */
+ dwarf2_add_field (&fi, child_die, objfile, cu_header);
+ }
+ else if (child_die->tag == DW_TAG_subprogram)
+ {
+ /* C++ member function. */
+ process_die (child_die, objfile, cu_header);
+ dwarf2_add_member_fn (&fi, child_die, type, objfile, cu_header);
+ }
+ else if (child_die->tag == DW_TAG_inheritance)
+ {
+ /* C++ base class field. */
+ dwarf2_add_field (&fi, child_die, objfile, cu_header);
+ }
+ else
+ {
+ process_die (child_die, objfile, cu_header);
+ }
+ child_die = sibling_die (child_die);
+ }
+
+ /* Attach fields and member functions to the type. */
+ if (fi.nfields)
+ dwarf2_attach_fields_to_type (&fi, type, objfile);
+ if (fi.nfnfields)
+ {
+ dwarf2_attach_fn_fields_to_type (&fi, type, objfile);
+
+ /* Get the type which refers to the base class (possibly this
+ class itself) which contains the vtable pointer for the current
+ class from the DW_AT_containing_type attribute. */
+
+ if (dwarf_attr (die, DW_AT_containing_type) != NULL)
+ {
+ struct type *t = die_containing_type (die, objfile, cu_header);
+
+ TYPE_VPTR_BASETYPE (type) = t;
+ if (type == t)
+ {
+ static const char vptr_name[] =
+ {'_', 'v', 'p', 't', 'r', '\0'};
+ int i;
+
+ /* Our own class provides vtbl ptr. */
+ for (i = TYPE_NFIELDS (t) - 1;
+ i >= TYPE_N_BASECLASSES (t);
+ --i)
+ {
+ char *fieldname = TYPE_FIELD_NAME (t, i);
+
+ if (STREQN (fieldname, vptr_name, strlen (vptr_name) - 1)
+ && is_cplus_marker (fieldname[strlen (vptr_name)]))
+ {
+ TYPE_VPTR_FIELDNO (type) = i;
+ break;
+ }
+ }
+
+ /* Complain if virtual function table field not found. */
+ if (i < TYPE_N_BASECLASSES (t))
+ complain (&dwarf2_vtbl_not_found_complaint,
+ TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : "");
+ }
+ else
+ {
+ TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t);
+ }
+ }
+ }
+
+ new_symbol (die, type, objfile, cu_header);
+
+ do_cleanups (back_to);
+ }
+ else
+ {
+ /* No children, must be stub. */
+ TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
+ }
+}
+
+/* Given a pointer to a die which begins an enumeration, process all
+ the dies that define the members of the enumeration.
+
+ This will be much nicer in draft 6 of the DWARF spec when our
+ members will be dies instead squished into the DW_AT_element_list
+ attribute.
+
+ NOTE: We reverse the order of the element list. */
+
+static void
+read_enumeration (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct die_info *child_die;
+ struct type *type;
+ struct field *fields;
+ struct attribute *attr;
+ struct symbol *sym;
+ int num_fields;
+ int unsigned_enum = 1;
+
+ type = alloc_type (objfile);
+
+ TYPE_CODE (type) = TYPE_CODE_ENUM;
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ {
+ TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
+ strlen (DW_STRING (attr)),
+ &objfile->type_obstack);
+ }
+
+ attr = dwarf_attr (die, DW_AT_byte_size);
+ if (attr)
+ {
+ TYPE_LENGTH (type) = DW_UNSND (attr);
+ }
+ else
+ {
+ TYPE_LENGTH (type) = 0;
+ }
+
+ num_fields = 0;
+ fields = NULL;
+ if (die->has_children)
+ {
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag != DW_TAG_enumerator)
+ {
+ process_die (child_die, objfile, cu_header);
+ }
+ else
+ {
+ attr = dwarf_attr (child_die, DW_AT_name);
+ if (attr)
+ {
+ sym = new_symbol (child_die, type, objfile, cu_header);
+ if (SYMBOL_VALUE (sym) < 0)
+ unsigned_enum = 0;
+
+ if ((num_fields % DW_FIELD_ALLOC_CHUNK) == 0)
+ {
+ fields = (struct field *)
+ xrealloc (fields,
+ (num_fields + DW_FIELD_ALLOC_CHUNK)
+ * sizeof (struct field));
+ }
+
+ FIELD_NAME (fields[num_fields]) = SYMBOL_NAME (sym);
+ FIELD_TYPE (fields[num_fields]) = NULL;
+ FIELD_BITPOS (fields[num_fields]) = SYMBOL_VALUE (sym);
+ FIELD_BITSIZE (fields[num_fields]) = 0;
+
+ num_fields++;
+ }
+ }
+
+ child_die = sibling_die (child_die);
+ }
+
+ if (num_fields)
+ {
+ TYPE_NFIELDS (type) = num_fields;
+ TYPE_FIELDS (type) = (struct field *)
+ TYPE_ALLOC (type, sizeof (struct field) * num_fields);
+ memcpy (TYPE_FIELDS (type), fields,
+ sizeof (struct field) * num_fields);
+ xfree (fields);
+ }
+ if (unsigned_enum)
+ TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+ }
+ die->type = type;
+ new_symbol (die, type, objfile, cu_header);
+}
+
+/* Extract all information from a DW_TAG_array_type DIE and put it in
+ the DIE's type field. For now, this only handles one dimensional
+ arrays. */
+
+static void
+read_array_type (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct die_info *child_die;
+ struct type *type = NULL;
+ struct type *element_type, *range_type, *index_type;
+ struct type **range_types = NULL;
+ struct attribute *attr;
+ int ndim = 0;
+ struct cleanup *back_to;
+
+ /* Return if we've already decoded this type. */
+ if (die->type)
+ {
+ return;
+ }
+
+ element_type = die_type (die, objfile, cu_header);
+
+ /* Irix 6.2 native cc creates array types without children for
+ arrays with unspecified length. */
+ if (die->has_children == 0)
+ {
+ index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
+ range_type = create_range_type (NULL, index_type, 0, -1);
+ die->type = create_array_type (NULL, element_type, range_type);
+ return;
+ }
+
+ back_to = make_cleanup (null_cleanup, NULL);
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag == DW_TAG_subrange_type)
+ {
+ unsigned int low, high;
+
+ /* Default bounds to an array with unspecified length. */
+ low = 0;
+ high = -1;
+ if (cu_language == language_fortran)
+ {
+ /* FORTRAN implies a lower bound of 1, if not given. */
+ low = 1;
+ }
+
+ index_type = die_type (child_die, objfile, cu_header);
+ attr = dwarf_attr (child_die, DW_AT_lower_bound);
+ if (attr)
+ {
+ if (attr->form == DW_FORM_sdata)
+ {
+ low = DW_SND (attr);
+ }
+ else if (attr->form == DW_FORM_udata
+ || attr->form == DW_FORM_data1
+ || attr->form == DW_FORM_data2
+ || attr->form == DW_FORM_data4
+ || attr->form == DW_FORM_data8)
+ {
+ low = DW_UNSND (attr);
+ }
+ else
+ {
+ complain (&dwarf2_non_const_array_bound_ignored,
+ dwarf_form_name (attr->form));
+#ifdef FORTRAN_HACK
+ die->type = lookup_pointer_type (element_type);
+ return;
+#else
+ low = 0;
+#endif
+ }
+ }
+ attr = dwarf_attr (child_die, DW_AT_upper_bound);
+ if (attr)
+ {
+ if (attr->form == DW_FORM_sdata)
+ {
+ high = DW_SND (attr);
+ }
+ else if (attr->form == DW_FORM_udata
+ || attr->form == DW_FORM_data1
+ || attr->form == DW_FORM_data2
+ || attr->form == DW_FORM_data4
+ || attr->form == DW_FORM_data8)
+ {
+ high = DW_UNSND (attr);
+ }
+ else if (attr->form == DW_FORM_block1)
+ {
+ /* GCC encodes arrays with unspecified or dynamic length
+ with a DW_FORM_block1 attribute.
+ FIXME: GDB does not yet know how to handle dynamic
+ arrays properly, treat them as arrays with unspecified
+ length for now. */
+ high = -1;
+ }
+ else
+ {
+ complain (&dwarf2_non_const_array_bound_ignored,
+ dwarf_form_name (attr->form));
+#ifdef FORTRAN_HACK
+ die->type = lookup_pointer_type (element_type);
+ return;
+#else
+ high = 1;
+#endif
+ }
+ }
+
+ /* Create a range type and save it for array type creation. */
+ if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
+ {
+ range_types = (struct type **)
+ xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
+ * sizeof (struct type *));
+ if (ndim == 0)
+ make_cleanup (free_current_contents, &range_types);
+ }
+ range_types[ndim++] = create_range_type (NULL, index_type, low, high);
+ }
+ child_die = sibling_die (child_die);
+ }
+
+ /* Dwarf2 dimensions are output from left to right, create the
+ necessary array types in backwards order. */
+ type = element_type;
+ while (ndim-- > 0)
+ type = create_array_type (NULL, type, range_types[ndim]);
+
+ /* Understand Dwarf2 support for vector types (like they occur on
+ the PowerPC w/ AltiVec). Gcc just adds another attribute to the
+ array type. This is not part of the Dwarf2/3 standard yet, but a
+ custom vendor extension. The main difference between a regular
+ array and the vector variant is that vectors are passed by value
+ to functions. */
+ attr = dwarf_attr (die, DW_AT_GNU_vector);
+ if (attr)
+ TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
+
+ do_cleanups (back_to);
+
+ /* Install the type in the die. */
+ die->type = type;
+}
+
+/* First cut: install each common block member as a global variable. */
+
+static void
+read_common_block (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct die_info *child_die;
+ struct attribute *attr;
+ struct symbol *sym;
+ CORE_ADDR base = (CORE_ADDR) 0;
+
+ attr = dwarf_attr (die, DW_AT_location);
+ if (attr)
+ {
+ base = decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
+ }
+ if (die->has_children)
+ {
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ sym = new_symbol (child_die, NULL, objfile, cu_header);
+ attr = dwarf_attr (child_die, DW_AT_data_member_location);
+ if (attr)
+ {
+ SYMBOL_VALUE_ADDRESS (sym) =
+ base + decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
+ add_symbol_to_list (sym, &global_symbols);
+ }
+ child_die = sibling_die (child_die);
+ }
+ }
+}
+
+/* Extract all information from a DW_TAG_pointer_type DIE and add to
+ the user defined type vector. */
+
+static void
+read_tag_pointer_type (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct type *type;
+ struct attribute *attr;
+
+ if (die->type)
+ {
+ return;
+ }
+
+ type = lookup_pointer_type (die_type (die, objfile, cu_header));
+ attr = dwarf_attr (die, DW_AT_byte_size);
+ if (attr)
+ {
+ TYPE_LENGTH (type) = DW_UNSND (attr);
+ }
+ else
+ {
+ TYPE_LENGTH (type) = cu_header->addr_size;
+ }
+ die->type = type;
+}
+
+/* Extract all information from a DW_TAG_ptr_to_member_type DIE and add to
+ the user defined type vector. */
+
+static void
+read_tag_ptr_to_member_type (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct type *type;
+ struct type *to_type;
+ struct type *domain;
+
+ if (die->type)
+ {
+ return;
+ }
+
+ type = alloc_type (objfile);
+ to_type = die_type (die, objfile, cu_header);
+ domain = die_containing_type (die, objfile, cu_header);
+ smash_to_member_type (type, domain, to_type);
+
+ die->type = type;
+}
+
+/* Extract all information from a DW_TAG_reference_type DIE and add to
+ the user defined type vector. */
+
+static void
+read_tag_reference_type (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct type *type;
+ struct attribute *attr;
+
+ if (die->type)
+ {
+ return;
+ }
+
+ type = lookup_reference_type (die_type (die, objfile, cu_header));
+ attr = dwarf_attr (die, DW_AT_byte_size);
+ if (attr)
+ {
+ TYPE_LENGTH (type) = DW_UNSND (attr);
+ }
+ else
+ {
+ TYPE_LENGTH (type) = cu_header->addr_size;
+ }
+ die->type = type;
+}
+
+static void
+read_tag_const_type (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct type *base_type;
+
+ if (die->type)
+ {
+ return;
+ }
+
+ base_type = die_type (die, objfile, cu_header);
+ die->type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
+}
+
+static void
+read_tag_volatile_type (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct type *base_type;
+
+ if (die->type)
+ {
+ return;
+ }
+
+ base_type = die_type (die, objfile, cu_header);
+ die->type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);
+}
+
+/* Extract all information from a DW_TAG_string_type DIE and add to
+ the user defined type vector. It isn't really a user defined type,
+ but it behaves like one, with other DIE's using an AT_user_def_type
+ attribute to reference it. */
+
+static void
+read_tag_string_type (struct die_info *die, struct objfile *objfile)
+{
+ struct type *type, *range_type, *index_type, *char_type;
+ struct attribute *attr;
+ unsigned int length;
+
+ if (die->type)
+ {
+ return;
+ }
+
+ attr = dwarf_attr (die, DW_AT_string_length);
+ if (attr)
+ {
+ length = DW_UNSND (attr);
+ }
+ else
+ {
+ /* check for the DW_AT_byte_size attribute */
+ attr = dwarf_attr (die, DW_AT_byte_size);
+ if (attr)
+ {
+ length = DW_UNSND (attr);
+ }
+ else
+ {
+ length = 1;
+ }
+ }
+ index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
+ range_type = create_range_type (NULL, index_type, 1, length);
+ if (cu_language == language_fortran)
+ {
+ /* Need to create a unique string type for bounds
+ information */
+ type = create_string_type (0, range_type);
+ }
+ else
+ {
+ char_type = dwarf2_fundamental_type (objfile, FT_CHAR);
+ type = create_string_type (char_type, range_type);
+ }
+ die->type = type;
+}
+
+/* Handle DIES due to C code like:
+
+ struct foo
+ {
+ int (*funcp)(int a, long l);
+ int b;
+ };
+
+ ('funcp' generates a DW_TAG_subroutine_type DIE)
+ */
+
+static void
+read_subroutine_type (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct type *type; /* Type that this function returns */
+ struct type *ftype; /* Function that returns above type */
+ struct attribute *attr;
+
+ /* Decode the type that this subroutine returns */
+ if (die->type)
+ {
+ return;
+ }
+ type = die_type (die, objfile, cu_header);
+ ftype = lookup_function_type (type);
+
+ /* All functions in C++ have prototypes. */
+ attr = dwarf_attr (die, DW_AT_prototyped);
+ if ((attr && (DW_UNSND (attr) != 0))
+ || cu_language == language_cplus)
+ TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
+
+ if (die->has_children)
+ {
+ struct die_info *child_die;
+ int nparams = 0;
+ int iparams = 0;
+
+ /* Count the number of parameters.
+ FIXME: GDB currently ignores vararg functions, but knows about
+ vararg member functions. */
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag == DW_TAG_formal_parameter)
+ nparams++;
+ else if (child_die->tag == DW_TAG_unspecified_parameters)
+ TYPE_FLAGS (ftype) |= TYPE_FLAG_VARARGS;
+ child_die = sibling_die (child_die);
+ }
+
+ /* Allocate storage for parameters and fill them in. */
+ TYPE_NFIELDS (ftype) = nparams;
+ TYPE_FIELDS (ftype) = (struct field *)
+ TYPE_ALLOC (ftype, nparams * sizeof (struct field));
+
+ child_die = die->next;
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag == DW_TAG_formal_parameter)
+ {
+ /* Dwarf2 has no clean way to discern C++ static and non-static
+ member functions. G++ helps GDB by marking the first
+ parameter for non-static member functions (which is the
+ this pointer) as artificial. We pass this information
+ to dwarf2_add_member_fn via TYPE_FIELD_ARTIFICIAL. */
+ attr = dwarf_attr (child_die, DW_AT_artificial);
+ if (attr)
+ TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr);
+ else
+ TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
+ TYPE_FIELD_TYPE (ftype, iparams) = die_type (child_die, objfile,
+ cu_header);
+ iparams++;
+ }
+ child_die = sibling_die (child_die);
+ }
+ }
+
+ die->type = ftype;
+}
+
+static void
+read_typedef (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct attribute *attr;
+ char *name = NULL;
+
+ if (!die->type)
+ {
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ {
+ name = DW_STRING (attr);
+ }
+ die->type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name, objfile);
+ TYPE_TARGET_TYPE (die->type) = die_type (die, objfile, cu_header);
+ }
+}
+
+/* Find a representation of a given base type and install
+ it in the TYPE field of the die. */
+
+static void
+read_base_type (struct die_info *die, struct objfile *objfile)
+{
+ struct type *type;
+ struct attribute *attr;
+ int encoding = 0, size = 0;
+
+ /* If we've already decoded this die, this is a no-op. */
+ if (die->type)
+ {
+ return;
+ }
+
+ attr = dwarf_attr (die, DW_AT_encoding);
+ if (attr)
+ {
+ encoding = DW_UNSND (attr);
+ }
+ attr = dwarf_attr (die, DW_AT_byte_size);
+ if (attr)
+ {
+ size = DW_UNSND (attr);
+ }
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ {
+ enum type_code code = TYPE_CODE_INT;
+ int type_flags = 0;
+
+ switch (encoding)
+ {
+ case DW_ATE_address:
+ /* Turn DW_ATE_address into a void * pointer. */
+ code = TYPE_CODE_PTR;
+ type_flags |= TYPE_FLAG_UNSIGNED;
+ break;
+ case DW_ATE_boolean:
+ code = TYPE_CODE_BOOL;
+ type_flags |= TYPE_FLAG_UNSIGNED;
+ break;
+ case DW_ATE_complex_float:
+ code = TYPE_CODE_COMPLEX;
+ break;
+ case DW_ATE_float:
+ code = TYPE_CODE_FLT;
+ break;
+ case DW_ATE_signed:
+ case DW_ATE_signed_char:
+ break;
+ case DW_ATE_unsigned:
+ case DW_ATE_unsigned_char:
+ type_flags |= TYPE_FLAG_UNSIGNED;
+ break;
+ default:
+ complain (&dwarf2_unsupported_at_encoding,
+ dwarf_type_encoding_name (encoding));
+ break;
+ }
+ type = init_type (code, size, type_flags, DW_STRING (attr), objfile);
+ if (encoding == DW_ATE_address)
+ TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID);
+ else if (encoding == DW_ATE_complex_float)
+ {
+ if (size == 32)
+ TYPE_TARGET_TYPE (type)
+ = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT);
+ else if (size == 16)
+ TYPE_TARGET_TYPE (type)
+ = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+ else if (size == 8)
+ TYPE_TARGET_TYPE (type)
+ = dwarf2_fundamental_type (objfile, FT_FLOAT);
+ }
+ }
+ else
+ {
+ type = dwarf_base_type (encoding, size, objfile);
+ }
+ die->type = type;
+}
+
+/* Read a whole compilation unit into a linked list of dies. */
+
+static struct die_info *
+read_comp_unit (char *info_ptr, bfd *abfd,
+ const struct comp_unit_head *cu_header)
+{
+ struct die_info *first_die, *last_die, *die;
+ char *cur_ptr;
+ int nesting_level;
+
+ /* Reset die reference table; we are
+ building new ones now. */
+ dwarf2_empty_hash_tables ();
+
+ cur_ptr = info_ptr;
+ nesting_level = 0;
+ first_die = last_die = NULL;
+ do
+ {
+ cur_ptr = read_full_die (&die, abfd, cur_ptr, cu_header);
+ if (die->has_children)
+ {
+ nesting_level++;
+ }
+ if (die->tag == 0)
+ {
+ nesting_level--;
+ }
+
+ die->next = NULL;
+
+ /* Enter die in reference hash table */
+ store_in_ref_table (die->offset, die);
+
+ if (!first_die)
+ {
+ first_die = last_die = die;
+ }
+ else
+ {
+ last_die->next = die;
+ last_die = die;
+ }
+ }
+ while (nesting_level > 0);
+ return first_die;
+}
+
+/* Free a linked list of dies. */
+
+static void
+free_die_list (struct die_info *dies)
+{
+ struct die_info *die, *next;
+
+ die = dies;
+ while (die)
+ {
+ next = die->next;
+ xfree (die->attrs);
+ xfree (die);
+ die = next;
+ }
+}
+
+static void
+do_free_die_list_cleanup (void *dies)
+{
+ free_die_list (dies);
+}
+
+static struct cleanup *
+make_cleanup_free_die_list (struct die_info *dies)
+{
+ return make_cleanup (do_free_die_list_cleanup, dies);
+}
+
+
+/* Read the contents of the section at OFFSET and of size SIZE from the
+ object file specified by OBJFILE into the psymbol_obstack and return it. */
+
+char *
+dwarf2_read_section (struct objfile *objfile, file_ptr offset,
+ unsigned int size)
+{
+ bfd *abfd = objfile->obfd;
+ char *buf;
+
+ if (size == 0)
+ return NULL;
+
+ buf = (char *) obstack_alloc (&objfile->psymbol_obstack, size);
+ if ((bfd_seek (abfd, offset, SEEK_SET) != 0) ||
+ (bfd_bread (buf, size, abfd) != size))
+ {
+ buf = NULL;
+ error ("Dwarf Error: Can't read DWARF data from '%s'",
+ bfd_get_filename (abfd));
+ }
+ return buf;
+}
+
+/* In DWARF version 2, the description of the debugging information is
+ stored in a separate .debug_abbrev section. Before we read any
+ dies from a section we read in all abbreviations and install them
+ in a hash table. */
+
+static void
+dwarf2_read_abbrevs (bfd *abfd, unsigned int offset)
+{
+ char *abbrev_ptr;
+ struct abbrev_info *cur_abbrev;
+ unsigned int abbrev_number, bytes_read, abbrev_name;
+ unsigned int abbrev_form, hash_number;
+
+ /* empty the table */
+ dwarf2_empty_abbrev_table (NULL);
+
+ abbrev_ptr = dwarf_abbrev_buffer + offset;
+ abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+
+ /* loop until we reach an abbrev number of 0 */
+ while (abbrev_number)
+ {
+ cur_abbrev = dwarf_alloc_abbrev ();
+
+ /* read in abbrev header */
+ cur_abbrev->number = abbrev_number;
+ cur_abbrev->tag = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ cur_abbrev->has_children = read_1_byte (abfd, abbrev_ptr);
+ abbrev_ptr += 1;
+
+ /* now read in declarations */
+ abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ while (abbrev_name)
+ {
+ if ((cur_abbrev->num_attrs % ATTR_ALLOC_CHUNK) == 0)
+ {
+ cur_abbrev->attrs = (struct attr_abbrev *)
+ xrealloc (cur_abbrev->attrs,
+ (cur_abbrev->num_attrs + ATTR_ALLOC_CHUNK)
+ * sizeof (struct attr_abbrev));
+ }
+ cur_abbrev->attrs[cur_abbrev->num_attrs].name = abbrev_name;
+ cur_abbrev->attrs[cur_abbrev->num_attrs++].form = abbrev_form;
+ abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ }
+
+ hash_number = abbrev_number % ABBREV_HASH_SIZE;
+ cur_abbrev->next = dwarf2_abbrevs[hash_number];
+ dwarf2_abbrevs[hash_number] = cur_abbrev;
+
+ /* Get next abbreviation.
+ Under Irix6 the abbreviations for a compilation unit are not
+ always properly terminated with an abbrev number of 0.
+ Exit loop if we encounter an abbreviation which we have
+ already read (which means we are about to read the abbreviations
+ for the next compile unit) or if the end of the abbreviation
+ table is reached. */
+ if ((unsigned int) (abbrev_ptr - dwarf_abbrev_buffer)
+ >= dwarf_abbrev_size)
+ break;
+ abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ if (dwarf2_lookup_abbrev (abbrev_number) != NULL)
+ break;
+ }
+}
+
+/* Empty the abbrev table for a new compilation unit. */
+
+/* ARGSUSED */
+static void
+dwarf2_empty_abbrev_table (PTR ignore)
+{
+ int i;
+ struct abbrev_info *abbrev, *next;
+
+ for (i = 0; i < ABBREV_HASH_SIZE; ++i)
+ {
+ next = NULL;
+ abbrev = dwarf2_abbrevs[i];
+ while (abbrev)
+ {
+ next = abbrev->next;
+ xfree (abbrev->attrs);
+ xfree (abbrev);
+ abbrev = next;
+ }
+ dwarf2_abbrevs[i] = NULL;
+ }
+}
+
+/* Lookup an abbrev_info structure in the abbrev hash table. */
+
+static struct abbrev_info *
+dwarf2_lookup_abbrev (unsigned int number)
+{
+ unsigned int hash_number;
+ struct abbrev_info *abbrev;
+
+ hash_number = number % ABBREV_HASH_SIZE;
+ abbrev = dwarf2_abbrevs[hash_number];
+
+ while (abbrev)
+ {
+ if (abbrev->number == number)
+ return abbrev;
+ else
+ abbrev = abbrev->next;
+ }
+ return NULL;
+}
+
+/* Read a minimal amount of information into the minimal die structure. */
+
+static char *
+read_partial_die (struct partial_die_info *part_die, bfd *abfd,
+ char *info_ptr, const struct comp_unit_head *cu_header)
+{
+ unsigned int abbrev_number, bytes_read, i;
+ struct abbrev_info *abbrev;
+ struct attribute attr;
+ struct attribute spec_attr;
+ int found_spec_attr = 0;
+ int has_low_pc_attr = 0;
+ int has_high_pc_attr = 0;
+
+ *part_die = zeroed_partial_die;
+ abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ if (!abbrev_number)
+ return info_ptr;
+
+ abbrev = dwarf2_lookup_abbrev (abbrev_number);
+ if (!abbrev)
+ {
+ error ("Dwarf Error: Could not find abbrev number %d.", abbrev_number);
+ }
+ part_die->offset = info_ptr - dwarf_info_buffer;
+ part_die->tag = abbrev->tag;
+ part_die->has_children = abbrev->has_children;
+ part_die->abbrev = abbrev_number;
+
+ for (i = 0; i < abbrev->num_attrs; ++i)
+ {
+ info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd,
+ info_ptr, cu_header);
+
+ /* Store the data if it is of an attribute we want to keep in a
+ partial symbol table. */
+ switch (attr.name)
+ {
+ case DW_AT_name:
+
+ /* Prefer DW_AT_MIPS_linkage_name over DW_AT_name. */
+ if (part_die->name == NULL)
+ part_die->name = DW_STRING (&attr);
+ break;
+ case DW_AT_MIPS_linkage_name:
+ part_die->name = DW_STRING (&attr);
+ break;
+ case DW_AT_low_pc:
+ has_low_pc_attr = 1;
+ part_die->lowpc = DW_ADDR (&attr);
+ break;
+ case DW_AT_high_pc:
+ has_high_pc_attr = 1;
+ part_die->highpc = DW_ADDR (&attr);
+ break;
+ case DW_AT_location:
+ part_die->locdesc = DW_BLOCK (&attr);
+ break;
+ case DW_AT_language:
+ part_die->language = DW_UNSND (&attr);
+ break;
+ case DW_AT_external:
+ part_die->is_external = DW_UNSND (&attr);
+ break;
+ case DW_AT_declaration:
+ part_die->is_declaration = DW_UNSND (&attr);
+ break;
+ case DW_AT_type:
+ part_die->has_type = 1;
+ break;
+ case DW_AT_abstract_origin:
+ case DW_AT_specification:
+ found_spec_attr = 1;
+ spec_attr = attr;
+ break;
+ case DW_AT_sibling:
+ /* Ignore absolute siblings, they might point outside of
+ the current compile unit. */
+ if (attr.form == DW_FORM_ref_addr)
+ complain (&dwarf2_absolute_sibling_complaint);
+ else
+ part_die->sibling =
+ dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* If we found a reference attribute and the die has no name, try
+ to find a name in the referred to die. */
+
+ if (found_spec_attr && part_die->name == NULL)
+ {
+ struct partial_die_info spec_die;
+ char *spec_ptr;
+ int dummy;
+
+ spec_ptr = dwarf_info_buffer + dwarf2_get_ref_die_offset (&spec_attr);
+ read_partial_die (&spec_die, abfd, spec_ptr, cu_header);
+ if (spec_die.name)
+ {
+ part_die->name = spec_die.name;
+
+ /* Copy DW_AT_external attribute if it is set. */
+ if (spec_die.is_external)
+ part_die->is_external = spec_die.is_external;
+ }
+ }
+
+ /* When using the GNU linker, .gnu.linkonce. sections are used to
+ eliminate duplicate copies of functions and vtables and such.
+ The linker will arbitrarily choose one and discard the others.
+ The AT_*_pc values for such functions refer to local labels in
+ these sections. If the section from that file was discarded, the
+ labels are not in the output, so the relocs get a value of 0.
+ If this is a discarded function, mark the pc bounds as invalid,
+ so that GDB will ignore it. */
+ if (has_low_pc_attr && has_high_pc_attr
+ && part_die->lowpc < part_die->highpc
+ && (part_die->lowpc != 0
+ || (bfd_get_file_flags (abfd) & HAS_RELOC)))
+ part_die->has_pc_info = 1;
+ return info_ptr;
+}
+
+/* Read the die from the .debug_info section buffer. And set diep to
+ point to a newly allocated die with its information. */
+
+static char *
+read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
+ const struct comp_unit_head *cu_header)
+{
+ unsigned int abbrev_number, bytes_read, i, offset;
+ struct abbrev_info *abbrev;
+ struct die_info *die;
+
+ offset = info_ptr - dwarf_info_buffer;
+ abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ if (!abbrev_number)
+ {
+ die = dwarf_alloc_die ();
+ die->tag = 0;
+ die->abbrev = abbrev_number;
+ die->type = NULL;
+ *diep = die;
+ return info_ptr;
+ }
+
+ abbrev = dwarf2_lookup_abbrev (abbrev_number);
+ if (!abbrev)
+ {
+ error ("Dwarf Error: could not find abbrev number %d.", abbrev_number);
+ }
+ die = dwarf_alloc_die ();
+ die->offset = offset;
+ die->tag = abbrev->tag;
+ die->has_children = abbrev->has_children;
+ die->abbrev = abbrev_number;
+ die->type = NULL;
+
+ die->num_attrs = abbrev->num_attrs;
+ die->attrs = (struct attribute *)
+ xmalloc (die->num_attrs * sizeof (struct attribute));
+
+ for (i = 0; i < abbrev->num_attrs; ++i)
+ {
+ info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i],
+ abfd, info_ptr, cu_header);
+ }
+
+ *diep = die;
+ return info_ptr;
+}
+
+/* Read an attribute value described by an attribute form. */
+
+static char *
+read_attribute_value (struct attribute *attr, unsigned form,
+ bfd *abfd, char *info_ptr,
+ const struct comp_unit_head *cu_header)
+{
+ unsigned int bytes_read;
+ struct dwarf_block *blk;
+
+ attr->form = form;
+ switch (form)
+ {
+ case DW_FORM_addr:
+ case DW_FORM_ref_addr:
+ DW_ADDR (attr) = read_address (abfd, info_ptr, cu_header, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_block2:
+ blk = dwarf_alloc_block ();
+ blk->size = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ info_ptr += blk->size;
+ DW_BLOCK (attr) = blk;
+ break;
+ case DW_FORM_block4:
+ blk = dwarf_alloc_block ();
+ blk->size = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ info_ptr += blk->size;
+ DW_BLOCK (attr) = blk;
+ break;
+ case DW_FORM_data2:
+ DW_UNSND (attr) = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ break;
+ case DW_FORM_data4:
+ DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ break;
+ case DW_FORM_data8:
+ DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
+ info_ptr += 8;
+ break;
+ case DW_FORM_string:
+ DW_STRING (attr) = read_string (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_strp:
+ DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header,
+ &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_block:
+ blk = dwarf_alloc_block ();
+ blk->size = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ info_ptr += blk->size;
+ DW_BLOCK (attr) = blk;
+ break;
+ case DW_FORM_block1:
+ blk = dwarf_alloc_block ();
+ blk->size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ info_ptr += blk->size;
+ DW_BLOCK (attr) = blk;
+ break;
+ case DW_FORM_data1:
+ DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ break;
+ case DW_FORM_flag:
+ DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ break;
+ case DW_FORM_sdata:
+ DW_SND (attr) = read_signed_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_udata:
+ DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_ref1:
+ DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ break;
+ case DW_FORM_ref2:
+ DW_UNSND (attr) = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ break;
+ case DW_FORM_ref4:
+ DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ break;
+ case DW_FORM_ref8:
+ DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
+ info_ptr += 8;
+ break;
+ case DW_FORM_ref_udata:
+ DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_indirect:
+ form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ info_ptr = read_attribute_value (attr, form, abfd, info_ptr, cu_header);
+ break;
+ default:
+ error ("Dwarf Error: Cannot handle %s in DWARF reader.",
+ dwarf_form_name (form));
+ }
+ return info_ptr;
+}
+
+/* Read an attribute described by an abbreviated attribute. */
+
+static char *
+read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
+ bfd *abfd, char *info_ptr,
+ const struct comp_unit_head *cu_header)
+{
+ attr->name = abbrev->name;
+ return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu_header);
+}
+
+/* read dwarf information from a buffer */
+
+static unsigned int
+read_1_byte (bfd *abfd, char *buf)
+{
+ return bfd_get_8 (abfd, (bfd_byte *) buf);
+}
+
+static int
+read_1_signed_byte (bfd *abfd, char *buf)
+{
+ return bfd_get_signed_8 (abfd, (bfd_byte *) buf);
+}
+
+static unsigned int
+read_2_bytes (bfd *abfd, char *buf)
+{
+ return bfd_get_16 (abfd, (bfd_byte *) buf);
+}
+
+static int
+read_2_signed_bytes (bfd *abfd, char *buf)
+{
+ return bfd_get_signed_16 (abfd, (bfd_byte *) buf);
+}
+
+static unsigned int
+read_4_bytes (bfd *abfd, char *buf)
+{
+ return bfd_get_32 (abfd, (bfd_byte *) buf);
+}
+
+static int
+read_4_signed_bytes (bfd *abfd, char *buf)
+{
+ return bfd_get_signed_32 (abfd, (bfd_byte *) buf);
+}
+
+static unsigned long
+read_8_bytes (bfd *abfd, char *buf)
+{
+ return bfd_get_64 (abfd, (bfd_byte *) buf);
+}
+
+static CORE_ADDR
+read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header,
+ int *bytes_read)
+{
+ CORE_ADDR retval = 0;
+
+ if (cu_header->signed_addr_p)
+ {
+ switch (cu_header->addr_size)
+ {
+ case 2:
+ retval = bfd_get_signed_16 (abfd, (bfd_byte *) buf);
+ break;
+ case 4:
+ retval = bfd_get_signed_32 (abfd, (bfd_byte *) buf);
+ break;
+ case 8:
+ retval = bfd_get_signed_64 (abfd, (bfd_byte *) buf);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "read_address: bad switch, signed");
+ }
+ }
+ else
+ {
+ switch (cu_header->addr_size)
+ {
+ case 2:
+ retval = bfd_get_16 (abfd, (bfd_byte *) buf);
+ break;
+ case 4:
+ retval = bfd_get_32 (abfd, (bfd_byte *) buf);
+ break;
+ case 8:
+ retval = bfd_get_64 (abfd, (bfd_byte *) buf);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "read_address: bad switch, unsigned");
+ }
+ }
+
+ *bytes_read = cu_header->addr_size;
+ return retval;
+}
+
+/* Reads the initial length from a section. The (draft) DWARF 2.1
+ specification allows the initial length to take up either 4 bytes
+ or 12 bytes. If the first 4 bytes are 0xffffffff, then the next 8
+ bytes describe the length and all offsets will be 8 bytes in length
+ instead of 4.
+
+ The value returned via bytes_read should be used to increment
+ the relevant pointer after calling read_initial_length().
+
+ As a side effect, this function sets the fields initial_length_size
+ and offset_size in cu_header to the values appropriate for the
+ length field. (The format of the initial length field determines
+ the width of file offsets to be fetched later with fetch_offset().)
+
+ [ Note: read_initial_length() and read_offset() are based on the
+ document entitled "DWARF Debugging Information Format", revision
+ 2.1, draft 4, dated July 20, 2000. This document was obtained
+ from:
+
+ http://reality.sgi.com/dehnert_engr/dwarf/dwarf2p1-draft4-000720.pdf
+
+ This document is only a draft and is subject to change. (So beware.)
+
+ - Kevin, Aug 4, 2000
+ ] */
+
+static LONGEST
+read_initial_length (bfd *abfd, char *buf, struct comp_unit_head *cu_header,
+ int *bytes_read)
+{
+ LONGEST retval = 0;
+
+ retval = bfd_get_32 (abfd, (bfd_byte *) buf);
+
+ if (retval == 0xffffffff)
+ {
+ retval = bfd_get_64 (abfd, (bfd_byte *) buf + 4);
+ *bytes_read = 12;
+ if (cu_header != NULL)
+ {
+ cu_header->initial_length_size = 12;
+ cu_header->offset_size = 8;
+ }
+ }
+ else
+ {
+ *bytes_read = 4;
+ if (cu_header != NULL)
+ {
+ cu_header->initial_length_size = 4;
+ cu_header->offset_size = 4;
+ }
+ }
+
+ return retval;
+}
+
+/* Read an offset from the data stream. The size of the offset is
+ given by cu_header->offset_size. */
+
+static LONGEST
+read_offset (bfd *abfd, char *buf, const struct comp_unit_head *cu_header,
+ int *bytes_read)
+{
+ LONGEST retval = 0;
+
+ switch (cu_header->offset_size)
+ {
+ case 4:
+ retval = bfd_get_32 (abfd, (bfd_byte *) buf);
+ *bytes_read = 4;
+ break;
+ case 8:
+ retval = bfd_get_64 (abfd, (bfd_byte *) buf);
+ *bytes_read = 8;
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "read_offset: bad switch");
+ }
+
+ return retval;
+}
+
+static char *
+read_n_bytes (bfd *abfd, char *buf, unsigned int size)
+{
+ /* If the size of a host char is 8 bits, we can return a pointer
+ to the buffer, otherwise we have to copy the data to a buffer
+ allocated on the temporary obstack. */
+ gdb_assert (HOST_CHAR_BIT == 8);
+ return buf;
+}
+
+static char *
+read_string (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
+{
+ /* If the size of a host char is 8 bits, we can return a pointer
+ to the string, otherwise we have to copy the string to a buffer
+ allocated on the temporary obstack. */
+ gdb_assert (HOST_CHAR_BIT == 8);
+ if (*buf == '\0')
+ {
+ *bytes_read_ptr = 1;
+ return NULL;
+ }
+ *bytes_read_ptr = strlen (buf) + 1;
+ return buf;
+}
+
+static char *
+read_indirect_string (bfd *abfd, char *buf,
+ const struct comp_unit_head *cu_header,
+ unsigned int *bytes_read_ptr)
+{
+ LONGEST str_offset = read_offset (abfd, buf, cu_header,
+ (int *) bytes_read_ptr);
+
+ if (dwarf_str_buffer == NULL)
+ {
+ error ("DW_FORM_strp used without .debug_str section");
+ return NULL;
+ }
+ if (str_offset >= dwarf_str_size)
+ {
+ error ("DW_FORM_strp pointing outside of .debug_str section");
+ return NULL;
+ }
+ gdb_assert (HOST_CHAR_BIT == 8);
+ if (dwarf_str_buffer[str_offset] == '\0')
+ return NULL;
+ return dwarf_str_buffer + str_offset;
+}
+
+static unsigned long
+read_unsigned_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
+{
+ unsigned long result;
+ unsigned int num_read;
+ int i, shift;
+ unsigned char byte;
+
+ result = 0;
+ shift = 0;
+ num_read = 0;
+ i = 0;
+ while (1)
+ {
+ byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+ buf++;
+ num_read++;
+ result |= ((unsigned long)(byte & 127) << shift);
+ if ((byte & 128) == 0)
+ {
+ break;
+ }
+ shift += 7;
+ }
+ *bytes_read_ptr = num_read;
+ return result;
+}
+
+static long
+read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
+{
+ long result;
+ int i, shift, size, num_read;
+ unsigned char byte;
+
+ result = 0;
+ shift = 0;
+ size = 32;
+ num_read = 0;
+ i = 0;
+ while (1)
+ {
+ byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+ buf++;
+ num_read++;
+ result |= ((long)(byte & 127) << shift);
+ shift += 7;
+ if ((byte & 128) == 0)
+ {
+ break;
+ }
+ }
+ if ((shift < size) && (byte & 0x40))
+ {
+ result |= -(1 << shift);
+ }
+ *bytes_read_ptr = num_read;
+ return result;
+}
+
+static void
+set_cu_language (unsigned int lang)
+{
+ switch (lang)
+ {
+ case DW_LANG_C89:
+ case DW_LANG_C:
+ cu_language = language_c;
+ break;
+ case DW_LANG_C_plus_plus:
+ cu_language = language_cplus;
+ break;
+ case DW_LANG_Fortran77:
+ case DW_LANG_Fortran90:
+ case DW_LANG_Fortran95:
+ cu_language = language_fortran;
+ break;
+ case DW_LANG_Mips_Assembler:
+ cu_language = language_asm;
+ break;
+ case DW_LANG_Java:
+ cu_language = language_java;
+ break;
+ case DW_LANG_Ada83:
+ case DW_LANG_Cobol74:
+ case DW_LANG_Cobol85:
+ case DW_LANG_Pascal83:
+ case DW_LANG_Modula2:
+ default:
+ cu_language = language_unknown;
+ break;
+ }
+ cu_language_defn = language_def (cu_language);
+}
+
+/* Return the named attribute or NULL if not there. */
+
+static struct attribute *
+dwarf_attr (struct die_info *die, unsigned int name)
+{
+ unsigned int i;
+ struct attribute *spec = NULL;
+
+ for (i = 0; i < die->num_attrs; ++i)
+ {
+ if (die->attrs[i].name == name)
+ {
+ return &die->attrs[i];
+ }
+ if (die->attrs[i].name == DW_AT_specification
+ || die->attrs[i].name == DW_AT_abstract_origin)
+ spec = &die->attrs[i];
+ }
+ if (spec)
+ {
+ struct die_info *ref_die =
+ follow_die_ref (dwarf2_get_ref_die_offset (spec));
+
+ if (ref_die)
+ return dwarf_attr (ref_die, name);
+ }
+
+ return NULL;
+}
+
+static int
+die_is_declaration (struct die_info *die)
+{
+ return (dwarf_attr (die, DW_AT_declaration)
+ && ! dwarf_attr (die, DW_AT_specification));
+}
+
+
+/* Free the line_header structure *LH, and any arrays and strings it
+ refers to. */
+static void
+free_line_header (struct line_header *lh)
+{
+ if (lh->standard_opcode_lengths)
+ xfree (lh->standard_opcode_lengths);
+
+ /* Remember that all the lh->file_names[i].name pointers are
+ pointers into debug_line_buffer, and don't need to be freed. */
+ if (lh->file_names)
+ xfree (lh->file_names);
+
+ /* Similarly for the include directory names. */
+ if (lh->include_dirs)
+ xfree (lh->include_dirs);
+
+ xfree (lh);
+}
+
+
+/* Add an entry to LH's include directory table. */
+static void
+add_include_dir (struct line_header *lh, char *include_dir)
+{
+ /* Grow the array if necessary. */
+ if (lh->include_dirs_size == 0)
+ {
+ lh->include_dirs_size = 1; /* for testing */
+ lh->include_dirs = xmalloc (lh->include_dirs_size
+ * sizeof (*lh->include_dirs));
+ }
+ else if (lh->num_include_dirs >= lh->include_dirs_size)
+ {
+ lh->include_dirs_size *= 2;
+ lh->include_dirs = xrealloc (lh->include_dirs,
+ (lh->include_dirs_size
+ * sizeof (*lh->include_dirs)));
+ }
+
+ lh->include_dirs[lh->num_include_dirs++] = include_dir;
+}
+
+
+/* Add an entry to LH's file name table. */
+static void
+add_file_name (struct line_header *lh,
+ char *name,
+ unsigned int dir_index,
+ unsigned int mod_time,
+ unsigned int length)
+{
+ struct file_entry *fe;
+
+ /* Grow the array if necessary. */
+ if (lh->file_names_size == 0)
+ {
+ lh->file_names_size = 1; /* for testing */
+ lh->file_names = xmalloc (lh->file_names_size
+ * sizeof (*lh->file_names));
+ }
+ else if (lh->num_file_names >= lh->file_names_size)
+ {
+ lh->file_names_size *= 2;
+ lh->file_names = xrealloc (lh->file_names,
+ (lh->file_names_size
+ * sizeof (*lh->file_names)));
+ }
+
+ fe = &lh->file_names[lh->num_file_names++];
+ fe->name = name;
+ fe->dir_index = dir_index;
+ fe->mod_time = mod_time;
+ fe->length = length;
+}
+
+
+/* Read the statement program header starting at OFFSET in
+ dwarf_line_buffer, according to the endianness of ABFD. Return a
+ pointer to a struct line_header, allocated using xmalloc.
+
+ NOTE: the strings in the include directory and file name tables of
+ the returned object point into debug_line_buffer, and must not be
+ freed. */
+static struct line_header *
+dwarf_decode_line_header (unsigned int offset, bfd *abfd,
+ const struct comp_unit_head *cu_header)
+{
+ struct cleanup *back_to;
+ struct line_header *lh;
+ char *line_ptr;
+ int bytes_read;
+ int i;
+ char *cur_dir, *cur_file;
+
+ if (dwarf_line_buffer == NULL)
+ {
+ complain (&dwarf2_missing_line_number_section);
+ return 0;
+ }
+
+ /* Make sure that at least there's room for the total_length field. That
+ could be 12 bytes long, but we're just going to fudge that. */
+ if (offset + 4 >= dwarf_line_size)
+ {
+ complain (&dwarf2_statement_list_fits_in_line_number_section);
+ return 0;
+ }
+
+ lh = xmalloc (sizeof (*lh));
+ memset (lh, 0, sizeof (*lh));
+ back_to = make_cleanup ((make_cleanup_ftype *) free_line_header,
+ (void *) lh);
+
+ line_ptr = dwarf_line_buffer + offset;
+
+ /* read in the header */
+ lh->total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read);
+ line_ptr += bytes_read;
+ if (line_ptr + lh->total_length > dwarf_line_buffer + dwarf_line_size)
+ {
+ complain (&dwarf2_statement_list_fits_in_line_number_section);
+ return 0;
+ }
+ lh->statement_program_end = line_ptr + lh->total_length;
+ lh->version = read_2_bytes (abfd, line_ptr);
+ line_ptr += 2;
+ lh->header_length = read_offset (abfd, line_ptr, cu_header, &bytes_read);
+ line_ptr += bytes_read;
+ lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh->default_is_stmt = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh->line_base = read_1_signed_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh->line_range = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh->opcode_base = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh->standard_opcode_lengths
+ = (unsigned char *) xmalloc (lh->opcode_base * sizeof (unsigned char));
+
+ lh->standard_opcode_lengths[0] = 1; /* This should never be used anyway. */
+ for (i = 1; i < lh->opcode_base; ++i)
+ {
+ lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ }
+
+ /* Read directory table */
+ while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL)
+ {
+ line_ptr += bytes_read;
+ add_include_dir (lh, cur_dir);
+ }
+ line_ptr += bytes_read;
+
+ /* Read file name table */
+ while ((cur_file = read_string (abfd, line_ptr, &bytes_read)) != NULL)
+ {
+ unsigned int dir_index, mod_time, length;
+
+ line_ptr += bytes_read;
+ dir_index = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ mod_time = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ length = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+
+ add_file_name (lh, cur_file, dir_index, mod_time, length);
+ }
+ line_ptr += bytes_read;
+ lh->statement_program_start = line_ptr;
+
+ if (line_ptr > dwarf_line_buffer + dwarf_line_size)
+ complain (&dwarf2_line_header_too_long);
+
+ discard_cleanups (back_to);
+ return lh;
+}
+
+/* This function exists to work around a bug in certain compilers
+ (particularly GCC 2.95), in which the first line number marker of a
+ function does not show up until after the prologue, right before
+ the second line number marker. This function shifts ADDRESS down
+ to the beginning of the function if necessary, and is called on
+ addresses passed to record_line. */
+
+static CORE_ADDR
+check_cu_functions (CORE_ADDR address)
+{
+ struct function_range *fn;
+
+ /* Find the function_range containing address. */
+ if (!cu_first_fn)
+ return address;
+
+ if (!cu_cached_fn)
+ cu_cached_fn = cu_first_fn;
+
+ fn = cu_cached_fn;
+ while (fn)
+ if (fn->lowpc <= address && fn->highpc > address)
+ goto found;
+ else
+ fn = fn->next;
+
+ fn = cu_first_fn;
+ while (fn && fn != cu_cached_fn)
+ if (fn->lowpc <= address && fn->highpc > address)
+ goto found;
+ else
+ fn = fn->next;
+
+ return address;
+
+ found:
+ if (fn->seen_line)
+ return address;
+ if (address != fn->lowpc)
+ complain (&dwarf2_misplaced_line_number,
+ (unsigned long) address, fn->name);
+ fn->seen_line = 1;
+ return fn->lowpc;
+}
+
+/* Decode the line number information for the compilation unit whose
+ line number info is at OFFSET in the .debug_line section.
+ The compilation directory of the file is passed in COMP_DIR. */
+
+static void
+dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
+ const struct comp_unit_head *cu_header)
+{
+ char *line_ptr;
+ char *line_end;
+ unsigned int i, bytes_read;
+ char *cur_dir;
+ unsigned char op_code, extended_op, adj_opcode;
+
+ line_ptr = lh->statement_program_start;
+ line_end = lh->statement_program_end;
+
+ /* Read the statement sequences until there's nothing left. */
+ while (line_ptr < line_end)
+ {
+ /* state machine registers */
+ CORE_ADDR address = 0;
+ unsigned int file = 1;
+ unsigned int line = 1;
+ unsigned int column = 0;
+ int is_stmt = lh->default_is_stmt;
+ int basic_block = 0;
+ int end_sequence = 0;
+
+ /* Start a subfile for the current file of the state machine. */
+ if (lh->num_file_names >= file)
+ {
+ /* lh->include_dirs and lh->file_names are 0-based, but the
+ directory and file name numbers in the statement program
+ are 1-based. */
+ struct file_entry *fe = &lh->file_names[file - 1];
+ char *dir;
+ if (fe->dir_index)
+ dir = lh->include_dirs[fe->dir_index - 1];
+ else
+ dir = comp_dir;
+ dwarf2_start_subfile (fe->name, dir);
+ }
+
+ /* Decode the table. */
+ while (!end_sequence)
+ {
+ op_code = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+
+ if (op_code >= lh->opcode_base)
+ { /* Special operand. */
+ adj_opcode = op_code - lh->opcode_base;
+ address += (adj_opcode / lh->line_range)
+ * lh->minimum_instruction_length;
+ line += lh->line_base + (adj_opcode % lh->line_range);
+ /* append row to matrix using current values */
+ address = check_cu_functions (address);
+ record_line (current_subfile, line, address);
+ basic_block = 1;
+ }
+ else switch (op_code)
+ {
+ case DW_LNS_extended_op:
+ line_ptr += 1; /* ignore length */
+ extended_op = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ switch (extended_op)
+ {
+ case DW_LNE_end_sequence:
+ end_sequence = 1;
+ record_line (current_subfile, 0, address);
+ break;
+ case DW_LNE_set_address:
+ address = read_address (abfd, line_ptr, cu_header, &bytes_read);
+ line_ptr += bytes_read;
+ address += baseaddr;
+ break;
+ case DW_LNE_define_file:
+ {
+ char *cur_file;
+ unsigned int dir_index, mod_time, length;
+
+ cur_file = read_string (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ dir_index =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ mod_time =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ length =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ add_file_name (lh, cur_file, dir_index, mod_time, length);
+ }
+ break;
+ default:
+ complain (&dwarf2_mangled_line_number_section);
+ return;
+ }
+ break;
+ case DW_LNS_copy:
+ address = check_cu_functions (address);
+ record_line (current_subfile, line, address);
+ basic_block = 0;
+ break;
+ case DW_LNS_advance_pc:
+ address += lh->minimum_instruction_length
+ * read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ break;
+ case DW_LNS_advance_line:
+ line += read_signed_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ break;
+ case DW_LNS_set_file:
+ {
+ /* lh->include_dirs and lh->file_names are 0-based,
+ but the directory and file name numbers in the
+ statement program are 1-based. */
+ struct file_entry *fe;
+ char *dir;
+ file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ fe = &lh->file_names[file - 1];
+ if (fe->dir_index)
+ dir = lh->include_dirs[fe->dir_index - 1];
+ else
+ dir = comp_dir;
+ dwarf2_start_subfile (fe->name, dir);
+ }
+ break;
+ case DW_LNS_set_column:
+ column = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ break;
+ case DW_LNS_negate_stmt:
+ is_stmt = (!is_stmt);
+ break;
+ case DW_LNS_set_basic_block:
+ basic_block = 1;
+ break;
+ /* Add to the address register of the state machine the
+ address increment value corresponding to special opcode
+ 255. Ie, this value is scaled by the minimum instruction
+ length since special opcode 255 would have scaled the
+ the increment. */
+ case DW_LNS_const_add_pc:
+ address += (lh->minimum_instruction_length
+ * ((255 - lh->opcode_base) / lh->line_range));
+ break;
+ case DW_LNS_fixed_advance_pc:
+ address += read_2_bytes (abfd, line_ptr);
+ line_ptr += 2;
+ break;
+ default:
+ { /* Unknown standard opcode, ignore it. */
+ int i;
+ for (i = 0; i < lh->standard_opcode_lengths[op_code]; i++)
+ {
+ (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ }
+ }
+ }
+ }
+ }
+}
+
+/* Start a subfile for DWARF. FILENAME is the name of the file and
+ DIRNAME the name of the source directory which contains FILENAME
+ or NULL if not known.
+ This routine tries to keep line numbers from identical absolute and
+ relative file names in a common subfile.
+
+ Using the `list' example from the GDB testsuite, which resides in
+ /srcdir and compiling it with Irix6.2 cc in /compdir using a filename
+ of /srcdir/list0.c yields the following debugging information for list0.c:
+
+ DW_AT_name: /srcdir/list0.c
+ DW_AT_comp_dir: /compdir
+ files.files[0].name: list0.h
+ files.files[0].dir: /srcdir
+ files.files[1].name: list0.c
+ files.files[1].dir: /srcdir
+
+ The line number information for list0.c has to end up in a single
+ subfile, so that `break /srcdir/list0.c:1' works as expected. */
+
+static void
+dwarf2_start_subfile (char *filename, char *dirname)
+{
+ /* If the filename isn't absolute, try to match an existing subfile
+ with the full pathname. */
+
+ if (!IS_ABSOLUTE_PATH (filename) && dirname != NULL)
+ {
+ struct subfile *subfile;
+ char *fullname = concat (dirname, "/", filename, NULL);
+
+ for (subfile = subfiles; subfile; subfile = subfile->next)
+ {
+ if (FILENAME_CMP (subfile->name, fullname) == 0)
+ {
+ current_subfile = subfile;
+ xfree (fullname);
+ return;
+ }
+ }
+ xfree (fullname);
+ }
+ start_subfile (filename, dirname);
+}
+
+/* Given a pointer to a DWARF information entry, figure out if we need
+ to make a symbol table entry for it, and if so, create a new entry
+ and return a pointer to it.
+ If TYPE is NULL, determine symbol type from the die, otherwise
+ used the passed type. */
+
+static struct symbol *
+new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct symbol *sym = NULL;
+ char *name;
+ struct attribute *attr = NULL;
+ struct attribute *attr2 = NULL;
+ CORE_ADDR addr;
+
+ name = dwarf2_linkage_name (die);
+ if (name)
+ {
+ sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ OBJSTAT (objfile, n_syms++);
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+ &objfile->symbol_obstack);
+
+ /* Default assumptions.
+ Use the passed type or decode it from the die. */
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ if (type != NULL)
+ SYMBOL_TYPE (sym) = type;
+ else
+ SYMBOL_TYPE (sym) = die_type (die, objfile, cu_header);
+ attr = dwarf_attr (die, DW_AT_decl_line);
+ if (attr)
+ {
+ SYMBOL_LINE (sym) = DW_UNSND (attr);
+ }
+
+ /* If this symbol is from a C++ compilation, then attempt to
+ cache the demangled form for future reference. This is a
+ typical time versus space tradeoff, that was decided in favor
+ of time because it sped up C++ symbol lookups by a factor of
+ about 20. */
+
+ SYMBOL_LANGUAGE (sym) = cu_language;
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+ switch (die->tag)
+ {
+ case DW_TAG_label:
+ attr = dwarf_attr (die, DW_AT_low_pc);
+ if (attr)
+ {
+ SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr;
+ }
+ SYMBOL_CLASS (sym) = LOC_LABEL;
+ break;
+ case DW_TAG_subprogram:
+ /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
+ finish_block. */
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+ attr2 = dwarf_attr (die, DW_AT_external);
+ if (attr2 && (DW_UNSND (attr2) != 0))
+ {
+ add_symbol_to_list (sym, &global_symbols);
+ }
+ else
+ {
+ add_symbol_to_list (sym, list_in_scope);
+ }
+ break;
+ case DW_TAG_variable:
+ /* Compilation with minimal debug info may result in variables
+ with missing type entries. Change the misleading `void' type
+ to something sensible. */
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID)
+ SYMBOL_TYPE (sym) = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / HOST_CHAR_BIT, 0,
+ "<variable, no debug info>",
+ objfile);
+ attr = dwarf_attr (die, DW_AT_const_value);
+ if (attr)
+ {
+ dwarf2_const_value (attr, sym, objfile, cu_header);
+ attr2 = dwarf_attr (die, DW_AT_external);
+ if (attr2 && (DW_UNSND (attr2) != 0))
+ add_symbol_to_list (sym, &global_symbols);
+ else
+ add_symbol_to_list (sym, list_in_scope);
+ break;
+ }
+ attr = dwarf_attr (die, DW_AT_location);
+ if (attr)
+ {
+ attr2 = dwarf_attr (die, DW_AT_external);
+ if (attr2 && (DW_UNSND (attr2) != 0))
+ {
+ SYMBOL_VALUE_ADDRESS (sym) =
+ decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
+ add_symbol_to_list (sym, &global_symbols);
+
+ /* In shared libraries the address of the variable
+ in the location descriptor might still be relocatable,
+ so its value could be zero.
+ Enter the symbol as a LOC_UNRESOLVED symbol, if its
+ value is zero, the address of the variable will then
+ be determined from the minimal symbol table whenever
+ the variable is referenced. */
+ if (SYMBOL_VALUE_ADDRESS (sym))
+ {
+ fixup_symbol_section (sym, objfile);
+ SYMBOL_VALUE_ADDRESS (sym) +=
+ ANOFFSET (objfile->section_offsets,
+ SYMBOL_SECTION (sym));
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ }
+ else
+ SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
+ }
+ else
+ {
+ SYMBOL_VALUE (sym) = addr =
+ decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
+ add_symbol_to_list (sym, list_in_scope);
+ if (optimized_out)
+ {
+ SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+ }
+ else if (isreg)
+ {
+ SYMBOL_CLASS (sym) = LOC_REGISTER;
+ SYMBOL_VALUE (sym) =
+ DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym));
+ }
+ else if (offreg)
+ {
+ SYMBOL_CLASS (sym) = LOC_BASEREG;
+ SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg);
+ }
+ else if (islocal)
+ {
+ SYMBOL_CLASS (sym) = LOC_LOCAL;
+ }
+ else
+ {
+ fixup_symbol_section (sym, objfile);
+ SYMBOL_VALUE_ADDRESS (sym) =
+ addr + ANOFFSET (objfile->section_offsets,
+ SYMBOL_SECTION (sym));
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ }
+ }
+ }
+ else
+ {
+ /* We do not know the address of this symbol.
+ If it is an external symbol and we have type information
+ for it, enter the symbol as a LOC_UNRESOLVED symbol.
+ The address of the variable will then be determined from
+ the minimal symbol table whenever the variable is
+ referenced. */
+ attr2 = dwarf_attr (die, DW_AT_external);
+ if (attr2 && (DW_UNSND (attr2) != 0)
+ && dwarf_attr (die, DW_AT_type) != NULL)
+ {
+ SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
+ add_symbol_to_list (sym, &global_symbols);
+ }
+ }
+ break;
+ case DW_TAG_formal_parameter:
+ attr = dwarf_attr (die, DW_AT_location);
+ if (attr)
+ {
+ SYMBOL_VALUE (sym) =
+ decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
+ if (isreg)
+ {
+ SYMBOL_CLASS (sym) = LOC_REGPARM;
+ SYMBOL_VALUE (sym) =
+ DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym));
+ }
+ else if (offreg)
+ {
+ if (isderef)
+ {
+ if (basereg != frame_base_reg)
+ complain (&dwarf2_complex_location_expr);
+ SYMBOL_CLASS (sym) = LOC_REF_ARG;
+ }
+ else
+ {
+ SYMBOL_CLASS (sym) = LOC_BASEREG_ARG;
+ SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg);
+ }
+ }
+ else
+ {
+ SYMBOL_CLASS (sym) = LOC_ARG;
+ }
+ }
+ attr = dwarf_attr (die, DW_AT_const_value);
+ if (attr)
+ {
+ dwarf2_const_value (attr, sym, objfile, cu_header);
+ }
+ add_symbol_to_list (sym, list_in_scope);
+ break;
+ case DW_TAG_unspecified_parameters:
+ /* From varargs functions; gdb doesn't seem to have any
+ interest in this information, so just ignore it for now.
+ (FIXME?) */
+ break;
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_enumeration_type:
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+ add_symbol_to_list (sym, list_in_scope);
+
+ /* The semantics of C++ state that "struct foo { ... }" also
+ defines a typedef for "foo". Synthesize a typedef symbol so
+ that "ptype foo" works as expected. */
+ if (cu_language == language_cplus)
+ {
+ struct symbol *typedef_sym = (struct symbol *)
+ obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ *typedef_sym = *sym;
+ SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE;
+ if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
+ TYPE_NAME (SYMBOL_TYPE (sym)) =
+ obsavestring (SYMBOL_NAME (sym),
+ strlen (SYMBOL_NAME (sym)),
+ &objfile->type_obstack);
+ add_symbol_to_list (typedef_sym, list_in_scope);
+ }
+ break;
+ case DW_TAG_typedef:
+ case DW_TAG_base_type:
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, list_in_scope);
+ break;
+ case DW_TAG_enumerator:
+ attr = dwarf_attr (die, DW_AT_const_value);
+ if (attr)
+ {
+ dwarf2_const_value (attr, sym, objfile, cu_header);
+ }
+ add_symbol_to_list (sym, list_in_scope);
+ break;
+ default:
+ /* Not a tag we recognize. Hopefully we aren't processing
+ trash data, but since we must specifically ignore things
+ we don't recognize, there is nothing else we should do at
+ this point. */
+ complain (&dwarf2_unsupported_tag, dwarf_tag_name (die->tag));
+ break;
+ }
+ }
+ return (sym);
+}
+
+/* Copy constant value from an attribute to a symbol. */
+
+static void
+dwarf2_const_value (struct attribute *attr, struct symbol *sym,
+ struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct dwarf_block *blk;
+
+ switch (attr->form)
+ {
+ case DW_FORM_addr:
+ if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != cu_header->addr_size)
+ complain (&dwarf2_const_value_length_mismatch, SYMBOL_NAME (sym),
+ cu_header->addr_size, TYPE_LENGTH (SYMBOL_TYPE (sym)));
+ SYMBOL_VALUE_BYTES (sym) = (char *)
+ obstack_alloc (&objfile->symbol_obstack, cu_header->addr_size);
+ store_address (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size,
+ DW_ADDR (attr));
+ SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+ break;
+ case DW_FORM_block1:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ case DW_FORM_block:
+ blk = DW_BLOCK (attr);
+ if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != blk->size)
+ complain (&dwarf2_const_value_length_mismatch, SYMBOL_NAME (sym),
+ blk->size, TYPE_LENGTH (SYMBOL_TYPE (sym)));
+ SYMBOL_VALUE_BYTES (sym) = (char *)
+ obstack_alloc (&objfile->symbol_obstack, blk->size);
+ memcpy (SYMBOL_VALUE_BYTES (sym), blk->data, blk->size);
+ SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+ break;
+
+ /* The DW_AT_const_value attributes are supposed to carry the
+ symbol's value "represented as it would be on the target
+ architecture." By the time we get here, it's already been
+ converted to host endianness, so we just need to sign- or
+ zero-extend it as appropriate. */
+ case DW_FORM_data1:
+ dwarf2_const_value_data (attr, sym, 8);
+ break;
+ case DW_FORM_data2:
+ dwarf2_const_value_data (attr, sym, 16);
+ break;
+ case DW_FORM_data4:
+ dwarf2_const_value_data (attr, sym, 32);
+ break;
+ case DW_FORM_data8:
+ dwarf2_const_value_data (attr, sym, 64);
+ break;
+
+ case DW_FORM_sdata:
+ SYMBOL_VALUE (sym) = DW_SND (attr);
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ break;
+
+ case DW_FORM_udata:
+ SYMBOL_VALUE (sym) = DW_UNSND (attr);
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ break;
+
+ default:
+ complain (&dwarf2_unsupported_const_value_attr,
+ dwarf_form_name (attr->form));
+ SYMBOL_VALUE (sym) = 0;
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ break;
+ }
+}
+
+
+/* Given an attr with a DW_FORM_dataN value in host byte order, sign-
+ or zero-extend it as appropriate for the symbol's type. */
+static void
+dwarf2_const_value_data (struct attribute *attr,
+ struct symbol *sym,
+ int bits)
+{
+ LONGEST l = DW_UNSND (attr);
+
+ if (bits < sizeof (l) * 8)
+ {
+ if (TYPE_UNSIGNED (SYMBOL_TYPE (sym)))
+ l &= ((LONGEST) 1 << bits) - 1;
+ else
+ l = (l << (sizeof (l) * 8 - bits)) >> (sizeof (l) * 8 - bits);
+ }
+
+ SYMBOL_VALUE (sym) = l;
+ SYMBOL_CLASS (sym) = LOC_CONST;
+}
+
+
+/* Return the type of the die in question using its DW_AT_type attribute. */
+
+static struct type *
+die_type (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct type *type;
+ struct attribute *type_attr;
+ struct die_info *type_die;
+ unsigned int ref;
+
+ type_attr = dwarf_attr (die, DW_AT_type);
+ if (!type_attr)
+ {
+ /* A missing DW_AT_type represents a void type. */
+ return dwarf2_fundamental_type (objfile, FT_VOID);
+ }
+ else
+ {
+ ref = dwarf2_get_ref_die_offset (type_attr);
+ type_die = follow_die_ref (ref);
+ if (!type_die)
+ {
+ error ("Dwarf Error: Cannot find referent at offset %d.", ref);
+ return NULL;
+ }
+ }
+ type = tag_type_to_type (type_die, objfile, cu_header);
+ if (!type)
+ {
+ dump_die (type_die);
+ error ("Dwarf Error: Problem turning type die at offset into gdb type.");
+ }
+ return type;
+}
+
+/* Return the containing type of the die in question using its
+ DW_AT_containing_type attribute. */
+
+static struct type *
+die_containing_type (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ struct type *type = NULL;
+ struct attribute *type_attr;
+ struct die_info *type_die = NULL;
+ unsigned int ref;
+
+ type_attr = dwarf_attr (die, DW_AT_containing_type);
+ if (type_attr)
+ {
+ ref = dwarf2_get_ref_die_offset (type_attr);
+ type_die = follow_die_ref (ref);
+ if (!type_die)
+ {
+ error ("Dwarf Error: Cannot find referent at offset %d.", ref);
+ return NULL;
+ }
+ type = tag_type_to_type (type_die, objfile, cu_header);
+ }
+ if (!type)
+ {
+ if (type_die)
+ dump_die (type_die);
+ error ("Dwarf Error: Problem turning containing type into gdb type.");
+ }
+ return type;
+}
+
+#if 0
+static struct type *
+type_at_offset (unsigned int offset, struct objfile *objfile)
+{
+ struct die_info *die;
+ struct type *type;
+
+ die = follow_die_ref (offset);
+ if (!die)
+ {
+ error ("Dwarf Error: Cannot find type referent at offset %d.", offset);
+ return NULL;
+ }
+ type = tag_type_to_type (die, objfile);
+ return type;
+}
+#endif
+
+static struct type *
+tag_type_to_type (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ if (die->type)
+ {
+ return die->type;
+ }
+ else
+ {
+ read_type_die (die, objfile, cu_header);
+ if (!die->type)
+ {
+ dump_die (die);
+ error ("Dwarf Error: Cannot find type of die.");
+ }
+ return die->type;
+ }
+}
+
+static void
+read_type_die (struct die_info *die, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ switch (die->tag)
+ {
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ read_structure_scope (die, objfile, cu_header);
+ break;
+ case DW_TAG_enumeration_type:
+ read_enumeration (die, objfile, cu_header);
+ break;
+ case DW_TAG_subprogram:
+ case DW_TAG_subroutine_type:
+ read_subroutine_type (die, objfile, cu_header);
+ break;
+ case DW_TAG_array_type:
+ read_array_type (die, objfile, cu_header);
+ break;
+ case DW_TAG_pointer_type:
+ read_tag_pointer_type (die, objfile, cu_header);
+ break;
+ case DW_TAG_ptr_to_member_type:
+ read_tag_ptr_to_member_type (die, objfile, cu_header);
+ break;
+ case DW_TAG_reference_type:
+ read_tag_reference_type (die, objfile, cu_header);
+ break;
+ case DW_TAG_const_type:
+ read_tag_const_type (die, objfile, cu_header);
+ break;
+ case DW_TAG_volatile_type:
+ read_tag_volatile_type (die, objfile, cu_header);
+ break;
+ case DW_TAG_string_type:
+ read_tag_string_type (die, objfile);
+ break;
+ case DW_TAG_typedef:
+ read_typedef (die, objfile, cu_header);
+ break;
+ case DW_TAG_base_type:
+ read_base_type (die, objfile);
+ break;
+ default:
+ complain (&dwarf2_unexpected_tag, dwarf_tag_name (die->tag));
+ break;
+ }
+}
+
+static struct type *
+dwarf_base_type (int encoding, int size, struct objfile *objfile)
+{
+ /* FIXME - this should not produce a new (struct type *)
+ every time. It should cache base types. */
+ struct type *type;
+ switch (encoding)
+ {
+ case DW_ATE_address:
+ type = dwarf2_fundamental_type (objfile, FT_VOID);
+ return type;
+ case DW_ATE_boolean:
+ type = dwarf2_fundamental_type (objfile, FT_BOOLEAN);
+ return type;
+ case DW_ATE_complex_float:
+ if (size == 16)
+ {
+ type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX);
+ }
+ else
+ {
+ type = dwarf2_fundamental_type (objfile, FT_COMPLEX);
+ }
+ return type;
+ case DW_ATE_float:
+ if (size == 8)
+ {
+ type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+ }
+ else
+ {
+ type = dwarf2_fundamental_type (objfile, FT_FLOAT);
+ }
+ return type;
+ case DW_ATE_signed:
+ switch (size)
+ {
+ case 1:
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
+ break;
+ case 2:
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT);
+ break;
+ default:
+ case 4:
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
+ break;
+ }
+ return type;
+ case DW_ATE_signed_char:
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
+ return type;
+ case DW_ATE_unsigned:
+ switch (size)
+ {
+ case 1:
+ type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
+ break;
+ case 2:
+ type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT);
+ break;
+ default:
+ case 4:
+ type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER);
+ break;
+ }
+ return type;
+ case DW_ATE_unsigned_char:
+ type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
+ return type;
+ default:
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
+ return type;
+ }
+}
+
+#if 0
+struct die_info *
+copy_die (struct die_info *old_die)
+{
+ struct die_info *new_die;
+ int i, num_attrs;
+
+ new_die = (struct die_info *) xmalloc (sizeof (struct die_info));
+ memset (new_die, 0, sizeof (struct die_info));
+
+ new_die->tag = old_die->tag;
+ new_die->has_children = old_die->has_children;
+ new_die->abbrev = old_die->abbrev;
+ new_die->offset = old_die->offset;
+ new_die->type = NULL;
+
+ num_attrs = old_die->num_attrs;
+ new_die->num_attrs = num_attrs;
+ new_die->attrs = (struct attribute *)
+ xmalloc (num_attrs * sizeof (struct attribute));
+
+ for (i = 0; i < old_die->num_attrs; ++i)
+ {
+ new_die->attrs[i].name = old_die->attrs[i].name;
+ new_die->attrs[i].form = old_die->attrs[i].form;
+ new_die->attrs[i].u.addr = old_die->attrs[i].u.addr;
+ }
+
+ new_die->next = NULL;
+ return new_die;
+}
+#endif
+
+/* Return sibling of die, NULL if no sibling. */
+
+static struct die_info *
+sibling_die (struct die_info *die)
+{
+ int nesting_level = 0;
+
+ if (!die->has_children)
+ {
+ if (die->next && (die->next->tag == 0))
+ {
+ return NULL;
+ }
+ else
+ {
+ return die->next;
+ }
+ }
+ else
+ {
+ do
+ {
+ if (die->has_children)
+ {
+ nesting_level++;
+ }
+ if (die->tag == 0)
+ {
+ nesting_level--;
+ }
+ die = die->next;
+ }
+ while (nesting_level);
+ if (die && (die->tag == 0))
+ {
+ return NULL;
+ }
+ else
+ {
+ return die;
+ }
+ }
+}
+
+/* Get linkage name of a die, return NULL if not found. */
+
+static char *
+dwarf2_linkage_name (struct die_info *die)
+{
+ struct attribute *attr;
+
+ attr = dwarf_attr (die, DW_AT_MIPS_linkage_name);
+ if (attr && DW_STRING (attr))
+ return DW_STRING (attr);
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ return DW_STRING (attr);
+ return NULL;
+}
+
+/* Convert a DIE tag into its string name. */
+
+static char *
+dwarf_tag_name (register unsigned tag)
+{
+ switch (tag)
+ {
+ case DW_TAG_padding:
+ return "DW_TAG_padding";
+ case DW_TAG_array_type:
+ return "DW_TAG_array_type";
+ case DW_TAG_class_type:
+ return "DW_TAG_class_type";
+ case DW_TAG_entry_point:
+ return "DW_TAG_entry_point";
+ case DW_TAG_enumeration_type:
+ return "DW_TAG_enumeration_type";
+ case DW_TAG_formal_parameter:
+ return "DW_TAG_formal_parameter";
+ case DW_TAG_imported_declaration:
+ return "DW_TAG_imported_declaration";
+ case DW_TAG_label:
+ return "DW_TAG_label";
+ case DW_TAG_lexical_block:
+ return "DW_TAG_lexical_block";
+ case DW_TAG_member:
+ return "DW_TAG_member";
+ case DW_TAG_pointer_type:
+ return "DW_TAG_pointer_type";
+ case DW_TAG_reference_type:
+ return "DW_TAG_reference_type";
+ case DW_TAG_compile_unit:
+ return "DW_TAG_compile_unit";
+ case DW_TAG_string_type:
+ return "DW_TAG_string_type";
+ case DW_TAG_structure_type:
+ return "DW_TAG_structure_type";
+ case DW_TAG_subroutine_type:
+ return "DW_TAG_subroutine_type";
+ case DW_TAG_typedef:
+ return "DW_TAG_typedef";
+ case DW_TAG_union_type:
+ return "DW_TAG_union_type";
+ case DW_TAG_unspecified_parameters:
+ return "DW_TAG_unspecified_parameters";
+ case DW_TAG_variant:
+ return "DW_TAG_variant";
+ case DW_TAG_common_block:
+ return "DW_TAG_common_block";
+ case DW_TAG_common_inclusion:
+ return "DW_TAG_common_inclusion";
+ case DW_TAG_inheritance:
+ return "DW_TAG_inheritance";
+ case DW_TAG_inlined_subroutine:
+ return "DW_TAG_inlined_subroutine";
+ case DW_TAG_module:
+ return "DW_TAG_module";
+ case DW_TAG_ptr_to_member_type:
+ return "DW_TAG_ptr_to_member_type";
+ case DW_TAG_set_type:
+ return "DW_TAG_set_type";
+ case DW_TAG_subrange_type:
+ return "DW_TAG_subrange_type";
+ case DW_TAG_with_stmt:
+ return "DW_TAG_with_stmt";
+ case DW_TAG_access_declaration:
+ return "DW_TAG_access_declaration";
+ case DW_TAG_base_type:
+ return "DW_TAG_base_type";
+ case DW_TAG_catch_block:
+ return "DW_TAG_catch_block";
+ case DW_TAG_const_type:
+ return "DW_TAG_const_type";
+ case DW_TAG_constant:
+ return "DW_TAG_constant";
+ case DW_TAG_enumerator:
+ return "DW_TAG_enumerator";
+ case DW_TAG_file_type:
+ return "DW_TAG_file_type";
+ case DW_TAG_friend:
+ return "DW_TAG_friend";
+ case DW_TAG_namelist:
+ return "DW_TAG_namelist";
+ case DW_TAG_namelist_item:
+ return "DW_TAG_namelist_item";
+ case DW_TAG_packed_type:
+ return "DW_TAG_packed_type";
+ case DW_TAG_subprogram:
+ return "DW_TAG_subprogram";
+ case DW_TAG_template_type_param:
+ return "DW_TAG_template_type_param";
+ case DW_TAG_template_value_param:
+ return "DW_TAG_template_value_param";
+ case DW_TAG_thrown_type:
+ return "DW_TAG_thrown_type";
+ case DW_TAG_try_block:
+ return "DW_TAG_try_block";
+ case DW_TAG_variant_part:
+ return "DW_TAG_variant_part";
+ case DW_TAG_variable:
+ return "DW_TAG_variable";
+ case DW_TAG_volatile_type:
+ return "DW_TAG_volatile_type";
+ case DW_TAG_MIPS_loop:
+ return "DW_TAG_MIPS_loop";
+ case DW_TAG_format_label:
+ return "DW_TAG_format_label";
+ case DW_TAG_function_template:
+ return "DW_TAG_function_template";
+ case DW_TAG_class_template:
+ return "DW_TAG_class_template";
+ default:
+ return "DW_TAG_<unknown>";
+ }
+}
+
+/* Convert a DWARF attribute code into its string name. */
+
+static char *
+dwarf_attr_name (register unsigned attr)
+{
+ switch (attr)
+ {
+ case DW_AT_sibling:
+ return "DW_AT_sibling";
+ case DW_AT_location:
+ return "DW_AT_location";
+ case DW_AT_name:
+ return "DW_AT_name";
+ case DW_AT_ordering:
+ return "DW_AT_ordering";
+ case DW_AT_subscr_data:
+ return "DW_AT_subscr_data";
+ case DW_AT_byte_size:
+ return "DW_AT_byte_size";
+ case DW_AT_bit_offset:
+ return "DW_AT_bit_offset";
+ case DW_AT_bit_size:
+ return "DW_AT_bit_size";
+ case DW_AT_element_list:
+ return "DW_AT_element_list";
+ case DW_AT_stmt_list:
+ return "DW_AT_stmt_list";
+ case DW_AT_low_pc:
+ return "DW_AT_low_pc";
+ case DW_AT_high_pc:
+ return "DW_AT_high_pc";
+ case DW_AT_language:
+ return "DW_AT_language";
+ case DW_AT_member:
+ return "DW_AT_member";
+ case DW_AT_discr:
+ return "DW_AT_discr";
+ case DW_AT_discr_value:
+ return "DW_AT_discr_value";
+ case DW_AT_visibility:
+ return "DW_AT_visibility";
+ case DW_AT_import:
+ return "DW_AT_import";
+ case DW_AT_string_length:
+ return "DW_AT_string_length";
+ case DW_AT_common_reference:
+ return "DW_AT_common_reference";
+ case DW_AT_comp_dir:
+ return "DW_AT_comp_dir";
+ case DW_AT_const_value:
+ return "DW_AT_const_value";
+ case DW_AT_containing_type:
+ return "DW_AT_containing_type";
+ case DW_AT_default_value:
+ return "DW_AT_default_value";
+ case DW_AT_inline:
+ return "DW_AT_inline";
+ case DW_AT_is_optional:
+ return "DW_AT_is_optional";
+ case DW_AT_lower_bound:
+ return "DW_AT_lower_bound";
+ case DW_AT_producer:
+ return "DW_AT_producer";
+ case DW_AT_prototyped:
+ return "DW_AT_prototyped";
+ case DW_AT_return_addr:
+ return "DW_AT_return_addr";
+ case DW_AT_start_scope:
+ return "DW_AT_start_scope";
+ case DW_AT_stride_size:
+ return "DW_AT_stride_size";
+ case DW_AT_upper_bound:
+ return "DW_AT_upper_bound";
+ case DW_AT_abstract_origin:
+ return "DW_AT_abstract_origin";
+ case DW_AT_accessibility:
+ return "DW_AT_accessibility";
+ case DW_AT_address_class:
+ return "DW_AT_address_class";
+ case DW_AT_artificial:
+ return "DW_AT_artificial";
+ case DW_AT_base_types:
+ return "DW_AT_base_types";
+ case DW_AT_calling_convention:
+ return "DW_AT_calling_convention";
+ case DW_AT_count:
+ return "DW_AT_count";
+ case DW_AT_data_member_location:
+ return "DW_AT_data_member_location";
+ case DW_AT_decl_column:
+ return "DW_AT_decl_column";
+ case DW_AT_decl_file:
+ return "DW_AT_decl_file";
+ case DW_AT_decl_line:
+ return "DW_AT_decl_line";
+ case DW_AT_declaration:
+ return "DW_AT_declaration";
+ case DW_AT_discr_list:
+ return "DW_AT_discr_list";
+ case DW_AT_encoding:
+ return "DW_AT_encoding";
+ case DW_AT_external:
+ return "DW_AT_external";
+ case DW_AT_frame_base:
+ return "DW_AT_frame_base";
+ case DW_AT_friend:
+ return "DW_AT_friend";
+ case DW_AT_identifier_case:
+ return "DW_AT_identifier_case";
+ case DW_AT_macro_info:
+ return "DW_AT_macro_info";
+ case DW_AT_namelist_items:
+ return "DW_AT_namelist_items";
+ case DW_AT_priority:
+ return "DW_AT_priority";
+ case DW_AT_segment:
+ return "DW_AT_segment";
+ case DW_AT_specification:
+ return "DW_AT_specification";
+ case DW_AT_static_link:
+ return "DW_AT_static_link";
+ case DW_AT_type:
+ return "DW_AT_type";
+ case DW_AT_use_location:
+ return "DW_AT_use_location";
+ case DW_AT_variable_parameter:
+ return "DW_AT_variable_parameter";
+ case DW_AT_virtuality:
+ return "DW_AT_virtuality";
+ case DW_AT_vtable_elem_location:
+ return "DW_AT_vtable_elem_location";
+
+#ifdef MIPS
+ case DW_AT_MIPS_fde:
+ return "DW_AT_MIPS_fde";
+ case DW_AT_MIPS_loop_begin:
+ return "DW_AT_MIPS_loop_begin";
+ case DW_AT_MIPS_tail_loop_begin:
+ return "DW_AT_MIPS_tail_loop_begin";
+ case DW_AT_MIPS_epilog_begin:
+ return "DW_AT_MIPS_epilog_begin";
+ case DW_AT_MIPS_loop_unroll_factor:
+ return "DW_AT_MIPS_loop_unroll_factor";
+ case DW_AT_MIPS_software_pipeline_depth:
+ return "DW_AT_MIPS_software_pipeline_depth";
+ case DW_AT_MIPS_linkage_name:
+ return "DW_AT_MIPS_linkage_name";
+#endif
+
+ case DW_AT_sf_names:
+ return "DW_AT_sf_names";
+ case DW_AT_src_info:
+ return "DW_AT_src_info";
+ case DW_AT_mac_info:
+ return "DW_AT_mac_info";
+ case DW_AT_src_coords:
+ return "DW_AT_src_coords";
+ case DW_AT_body_begin:
+ return "DW_AT_body_begin";
+ case DW_AT_body_end:
+ return "DW_AT_body_end";
+ case DW_AT_GNU_vector:
+ return "DW_AT_GNU_vector";
+ default:
+ return "DW_AT_<unknown>";
+ }
+}
+
+/* Convert a DWARF value form code into its string name. */
+
+static char *
+dwarf_form_name (register unsigned form)
+{
+ switch (form)
+ {
+ case DW_FORM_addr:
+ return "DW_FORM_addr";
+ case DW_FORM_block2:
+ return "DW_FORM_block2";
+ case DW_FORM_block4:
+ return "DW_FORM_block4";
+ case DW_FORM_data2:
+ return "DW_FORM_data2";
+ case DW_FORM_data4:
+ return "DW_FORM_data4";
+ case DW_FORM_data8:
+ return "DW_FORM_data8";
+ case DW_FORM_string:
+ return "DW_FORM_string";
+ case DW_FORM_block:
+ return "DW_FORM_block";
+ case DW_FORM_block1:
+ return "DW_FORM_block1";
+ case DW_FORM_data1:
+ return "DW_FORM_data1";
+ case DW_FORM_flag:
+ return "DW_FORM_flag";
+ case DW_FORM_sdata:
+ return "DW_FORM_sdata";
+ case DW_FORM_strp:
+ return "DW_FORM_strp";
+ case DW_FORM_udata:
+ return "DW_FORM_udata";
+ case DW_FORM_ref_addr:
+ return "DW_FORM_ref_addr";
+ case DW_FORM_ref1:
+ return "DW_FORM_ref1";
+ case DW_FORM_ref2:
+ return "DW_FORM_ref2";
+ case DW_FORM_ref4:
+ return "DW_FORM_ref4";
+ case DW_FORM_ref8:
+ return "DW_FORM_ref8";
+ case DW_FORM_ref_udata:
+ return "DW_FORM_ref_udata";
+ case DW_FORM_indirect:
+ return "DW_FORM_indirect";
+ default:
+ return "DW_FORM_<unknown>";
+ }
+}
+
+/* Convert a DWARF stack opcode into its string name. */
+
+static char *
+dwarf_stack_op_name (register unsigned op)
+{
+ switch (op)
+ {
+ case DW_OP_addr:
+ return "DW_OP_addr";
+ case DW_OP_deref:
+ return "DW_OP_deref";
+ case DW_OP_const1u:
+ return "DW_OP_const1u";
+ case DW_OP_const1s:
+ return "DW_OP_const1s";
+ case DW_OP_const2u:
+ return "DW_OP_const2u";
+ case DW_OP_const2s:
+ return "DW_OP_const2s";
+ case DW_OP_const4u:
+ return "DW_OP_const4u";
+ case DW_OP_const4s:
+ return "DW_OP_const4s";
+ case DW_OP_const8u:
+ return "DW_OP_const8u";
+ case DW_OP_const8s:
+ return "DW_OP_const8s";
+ case DW_OP_constu:
+ return "DW_OP_constu";
+ case DW_OP_consts:
+ return "DW_OP_consts";
+ case DW_OP_dup:
+ return "DW_OP_dup";
+ case DW_OP_drop:
+ return "DW_OP_drop";
+ case DW_OP_over:
+ return "DW_OP_over";
+ case DW_OP_pick:
+ return "DW_OP_pick";
+ case DW_OP_swap:
+ return "DW_OP_swap";
+ case DW_OP_rot:
+ return "DW_OP_rot";
+ case DW_OP_xderef:
+ return "DW_OP_xderef";
+ case DW_OP_abs:
+ return "DW_OP_abs";
+ case DW_OP_and:
+ return "DW_OP_and";
+ case DW_OP_div:
+ return "DW_OP_div";
+ case DW_OP_minus:
+ return "DW_OP_minus";
+ case DW_OP_mod:
+ return "DW_OP_mod";
+ case DW_OP_mul:
+ return "DW_OP_mul";
+ case DW_OP_neg:
+ return "DW_OP_neg";
+ case DW_OP_not:
+ return "DW_OP_not";
+ case DW_OP_or:
+ return "DW_OP_or";
+ case DW_OP_plus:
+ return "DW_OP_plus";
+ case DW_OP_plus_uconst:
+ return "DW_OP_plus_uconst";
+ case DW_OP_shl:
+ return "DW_OP_shl";
+ case DW_OP_shr:
+ return "DW_OP_shr";
+ case DW_OP_shra:
+ return "DW_OP_shra";
+ case DW_OP_xor:
+ return "DW_OP_xor";
+ case DW_OP_bra:
+ return "DW_OP_bra";
+ case DW_OP_eq:
+ return "DW_OP_eq";
+ case DW_OP_ge:
+ return "DW_OP_ge";
+ case DW_OP_gt:
+ return "DW_OP_gt";
+ case DW_OP_le:
+ return "DW_OP_le";
+ case DW_OP_lt:
+ return "DW_OP_lt";
+ case DW_OP_ne:
+ return "DW_OP_ne";
+ case DW_OP_skip:
+ return "DW_OP_skip";
+ case DW_OP_lit0:
+ return "DW_OP_lit0";
+ case DW_OP_lit1:
+ return "DW_OP_lit1";
+ case DW_OP_lit2:
+ return "DW_OP_lit2";
+ case DW_OP_lit3:
+ return "DW_OP_lit3";
+ case DW_OP_lit4:
+ return "DW_OP_lit4";
+ case DW_OP_lit5:
+ return "DW_OP_lit5";
+ case DW_OP_lit6:
+ return "DW_OP_lit6";
+ case DW_OP_lit7:
+ return "DW_OP_lit7";
+ case DW_OP_lit8:
+ return "DW_OP_lit8";
+ case DW_OP_lit9:
+ return "DW_OP_lit9";
+ case DW_OP_lit10:
+ return "DW_OP_lit10";
+ case DW_OP_lit11:
+ return "DW_OP_lit11";
+ case DW_OP_lit12:
+ return "DW_OP_lit12";
+ case DW_OP_lit13:
+ return "DW_OP_lit13";
+ case DW_OP_lit14:
+ return "DW_OP_lit14";
+ case DW_OP_lit15:
+ return "DW_OP_lit15";
+ case DW_OP_lit16:
+ return "DW_OP_lit16";
+ case DW_OP_lit17:
+ return "DW_OP_lit17";
+ case DW_OP_lit18:
+ return "DW_OP_lit18";
+ case DW_OP_lit19:
+ return "DW_OP_lit19";
+ case DW_OP_lit20:
+ return "DW_OP_lit20";
+ case DW_OP_lit21:
+ return "DW_OP_lit21";
+ case DW_OP_lit22:
+ return "DW_OP_lit22";
+ case DW_OP_lit23:
+ return "DW_OP_lit23";
+ case DW_OP_lit24:
+ return "DW_OP_lit24";
+ case DW_OP_lit25:
+ return "DW_OP_lit25";
+ case DW_OP_lit26:
+ return "DW_OP_lit26";
+ case DW_OP_lit27:
+ return "DW_OP_lit27";
+ case DW_OP_lit28:
+ return "DW_OP_lit28";
+ case DW_OP_lit29:
+ return "DW_OP_lit29";
+ case DW_OP_lit30:
+ return "DW_OP_lit30";
+ case DW_OP_lit31:
+ return "DW_OP_lit31";
+ case DW_OP_reg0:
+ return "DW_OP_reg0";
+ case DW_OP_reg1:
+ return "DW_OP_reg1";
+ case DW_OP_reg2:
+ return "DW_OP_reg2";
+ case DW_OP_reg3:
+ return "DW_OP_reg3";
+ case DW_OP_reg4:
+ return "DW_OP_reg4";
+ case DW_OP_reg5:
+ return "DW_OP_reg5";
+ case DW_OP_reg6:
+ return "DW_OP_reg6";
+ case DW_OP_reg7:
+ return "DW_OP_reg7";
+ case DW_OP_reg8:
+ return "DW_OP_reg8";
+ case DW_OP_reg9:
+ return "DW_OP_reg9";
+ case DW_OP_reg10:
+ return "DW_OP_reg10";
+ case DW_OP_reg11:
+ return "DW_OP_reg11";
+ case DW_OP_reg12:
+ return "DW_OP_reg12";
+ case DW_OP_reg13:
+ return "DW_OP_reg13";
+ case DW_OP_reg14:
+ return "DW_OP_reg14";
+ case DW_OP_reg15:
+ return "DW_OP_reg15";
+ case DW_OP_reg16:
+ return "DW_OP_reg16";
+ case DW_OP_reg17:
+ return "DW_OP_reg17";
+ case DW_OP_reg18:
+ return "DW_OP_reg18";
+ case DW_OP_reg19:
+ return "DW_OP_reg19";
+ case DW_OP_reg20:
+ return "DW_OP_reg20";
+ case DW_OP_reg21:
+ return "DW_OP_reg21";
+ case DW_OP_reg22:
+ return "DW_OP_reg22";
+ case DW_OP_reg23:
+ return "DW_OP_reg23";
+ case DW_OP_reg24:
+ return "DW_OP_reg24";
+ case DW_OP_reg25:
+ return "DW_OP_reg25";
+ case DW_OP_reg26:
+ return "DW_OP_reg26";
+ case DW_OP_reg27:
+ return "DW_OP_reg27";
+ case DW_OP_reg28:
+ return "DW_OP_reg28";
+ case DW_OP_reg29:
+ return "DW_OP_reg29";
+ case DW_OP_reg30:
+ return "DW_OP_reg30";
+ case DW_OP_reg31:
+ return "DW_OP_reg31";
+ case DW_OP_breg0:
+ return "DW_OP_breg0";
+ case DW_OP_breg1:
+ return "DW_OP_breg1";
+ case DW_OP_breg2:
+ return "DW_OP_breg2";
+ case DW_OP_breg3:
+ return "DW_OP_breg3";
+ case DW_OP_breg4:
+ return "DW_OP_breg4";
+ case DW_OP_breg5:
+ return "DW_OP_breg5";
+ case DW_OP_breg6:
+ return "DW_OP_breg6";
+ case DW_OP_breg7:
+ return "DW_OP_breg7";
+ case DW_OP_breg8:
+ return "DW_OP_breg8";
+ case DW_OP_breg9:
+ return "DW_OP_breg9";
+ case DW_OP_breg10:
+ return "DW_OP_breg10";
+ case DW_OP_breg11:
+ return "DW_OP_breg11";
+ case DW_OP_breg12:
+ return "DW_OP_breg12";
+ case DW_OP_breg13:
+ return "DW_OP_breg13";
+ case DW_OP_breg14:
+ return "DW_OP_breg14";
+ case DW_OP_breg15:
+ return "DW_OP_breg15";
+ case DW_OP_breg16:
+ return "DW_OP_breg16";
+ case DW_OP_breg17:
+ return "DW_OP_breg17";
+ case DW_OP_breg18:
+ return "DW_OP_breg18";
+ case DW_OP_breg19:
+ return "DW_OP_breg19";
+ case DW_OP_breg20:
+ return "DW_OP_breg20";
+ case DW_OP_breg21:
+ return "DW_OP_breg21";
+ case DW_OP_breg22:
+ return "DW_OP_breg22";
+ case DW_OP_breg23:
+ return "DW_OP_breg23";
+ case DW_OP_breg24:
+ return "DW_OP_breg24";
+ case DW_OP_breg25:
+ return "DW_OP_breg25";
+ case DW_OP_breg26:
+ return "DW_OP_breg26";
+ case DW_OP_breg27:
+ return "DW_OP_breg27";
+ case DW_OP_breg28:
+ return "DW_OP_breg28";
+ case DW_OP_breg29:
+ return "DW_OP_breg29";
+ case DW_OP_breg30:
+ return "DW_OP_breg30";
+ case DW_OP_breg31:
+ return "DW_OP_breg31";
+ case DW_OP_regx:
+ return "DW_OP_regx";
+ case DW_OP_fbreg:
+ return "DW_OP_fbreg";
+ case DW_OP_bregx:
+ return "DW_OP_bregx";
+ case DW_OP_piece:
+ return "DW_OP_piece";
+ case DW_OP_deref_size:
+ return "DW_OP_deref_size";
+ case DW_OP_xderef_size:
+ return "DW_OP_xderef_size";
+ case DW_OP_nop:
+ return "DW_OP_nop";
+ default:
+ return "OP_<unknown>";
+ }
+}
+
+static char *
+dwarf_bool_name (unsigned mybool)
+{
+ if (mybool)
+ return "TRUE";
+ else
+ return "FALSE";
+}
+
+/* Convert a DWARF type code into its string name. */
+
+static char *
+dwarf_type_encoding_name (register unsigned enc)
+{
+ switch (enc)
+ {
+ case DW_ATE_address:
+ return "DW_ATE_address";
+ case DW_ATE_boolean:
+ return "DW_ATE_boolean";
+ case DW_ATE_complex_float:
+ return "DW_ATE_complex_float";
+ case DW_ATE_float:
+ return "DW_ATE_float";
+ case DW_ATE_signed:
+ return "DW_ATE_signed";
+ case DW_ATE_signed_char:
+ return "DW_ATE_signed_char";
+ case DW_ATE_unsigned:
+ return "DW_ATE_unsigned";
+ case DW_ATE_unsigned_char:
+ return "DW_ATE_unsigned_char";
+ default:
+ return "DW_ATE_<unknown>";
+ }
+}
+
+/* Convert a DWARF call frame info operation to its string name. */
+
+#if 0
+static char *
+dwarf_cfi_name (register unsigned cfi_opc)
+{
+ switch (cfi_opc)
+ {
+ case DW_CFA_advance_loc:
+ return "DW_CFA_advance_loc";
+ case DW_CFA_offset:
+ return "DW_CFA_offset";
+ case DW_CFA_restore:
+ return "DW_CFA_restore";
+ case DW_CFA_nop:
+ return "DW_CFA_nop";
+ case DW_CFA_set_loc:
+ return "DW_CFA_set_loc";
+ case DW_CFA_advance_loc1:
+ return "DW_CFA_advance_loc1";
+ case DW_CFA_advance_loc2:
+ return "DW_CFA_advance_loc2";
+ case DW_CFA_advance_loc4:
+ return "DW_CFA_advance_loc4";
+ case DW_CFA_offset_extended:
+ return "DW_CFA_offset_extended";
+ case DW_CFA_restore_extended:
+ return "DW_CFA_restore_extended";
+ case DW_CFA_undefined:
+ return "DW_CFA_undefined";
+ case DW_CFA_same_value:
+ return "DW_CFA_same_value";
+ case DW_CFA_register:
+ return "DW_CFA_register";
+ case DW_CFA_remember_state:
+ return "DW_CFA_remember_state";
+ case DW_CFA_restore_state:
+ return "DW_CFA_restore_state";
+ case DW_CFA_def_cfa:
+ return "DW_CFA_def_cfa";
+ case DW_CFA_def_cfa_register:
+ return "DW_CFA_def_cfa_register";
+ case DW_CFA_def_cfa_offset:
+ return "DW_CFA_def_cfa_offset";
+
+ /* DWARF 3 */
+ case DW_CFA_def_cfa_expression:
+ return "DW_CFA_def_cfa_expression";
+ case DW_CFA_expression:
+ return "DW_CFA_expression";
+ case DW_CFA_offset_extended_sf:
+ return "DW_CFA_offset_extended_sf";
+ case DW_CFA_def_cfa_sf:
+ return "DW_CFA_def_cfa_sf";
+ case DW_CFA_def_cfa_offset_sf:
+ return "DW_CFA_def_cfa_offset_sf";
+
+ /* SGI/MIPS specific */
+ case DW_CFA_MIPS_advance_loc8:
+ return "DW_CFA_MIPS_advance_loc8";
+
+ /* GNU extensions */
+ case DW_CFA_GNU_window_save:
+ return "DW_CFA_GNU_window_save";
+ case DW_CFA_GNU_args_size:
+ return "DW_CFA_GNU_args_size";
+ case DW_CFA_GNU_negative_offset_extended:
+ return "DW_CFA_GNU_negative_offset_extended";
+
+ default:
+ return "DW_CFA_<unknown>";
+ }
+}
+#endif
+
+static void
+dump_die (struct die_info *die)
+{
+ unsigned int i;
+
+ fprintf_unfiltered (gdb_stderr, "Die: %s (abbrev = %d, offset = %d)\n",
+ dwarf_tag_name (die->tag), die->abbrev, die->offset);
+ fprintf_unfiltered (gdb_stderr, "\thas children: %s\n",
+ dwarf_bool_name (die->has_children));
+
+ fprintf_unfiltered (gdb_stderr, "\tattributes:\n");
+ for (i = 0; i < die->num_attrs; ++i)
+ {
+ fprintf_unfiltered (gdb_stderr, "\t\t%s (%s) ",
+ dwarf_attr_name (die->attrs[i].name),
+ dwarf_form_name (die->attrs[i].form));
+ switch (die->attrs[i].form)
+ {
+ case DW_FORM_ref_addr:
+ case DW_FORM_addr:
+ fprintf_unfiltered (gdb_stderr, "address: ");
+ print_address_numeric (DW_ADDR (&die->attrs[i]), 1, gdb_stderr);
+ break;
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ fprintf_unfiltered (gdb_stderr, "block: size %d", DW_BLOCK (&die->attrs[i])->size);
+ break;
+ case DW_FORM_data1:
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_udata:
+ case DW_FORM_sdata:
+ fprintf_unfiltered (gdb_stderr, "constant: %ld", DW_UNSND (&die->attrs[i]));
+ break;
+ case DW_FORM_string:
+ case DW_FORM_strp:
+ fprintf_unfiltered (gdb_stderr, "string: \"%s\"",
+ DW_STRING (&die->attrs[i])
+ ? DW_STRING (&die->attrs[i]) : "");
+ break;
+ case DW_FORM_flag:
+ if (DW_UNSND (&die->attrs[i]))
+ fprintf_unfiltered (gdb_stderr, "flag: TRUE");
+ else
+ fprintf_unfiltered (gdb_stderr, "flag: FALSE");
+ break;
+ case DW_FORM_indirect:
+ /* the reader will have reduced the indirect form to
+ the "base form" so this form should not occur */
+ fprintf_unfiltered (gdb_stderr, "unexpected attribute form: DW_FORM_indirect");
+ break;
+ default:
+ fprintf_unfiltered (gdb_stderr, "unsupported attribute form: %d.",
+ die->attrs[i].form);
+ }
+ fprintf_unfiltered (gdb_stderr, "\n");
+ }
+}
+
+static void
+dump_die_list (struct die_info *die)
+{
+ while (die)
+ {
+ dump_die (die);
+ die = die->next;
+ }
+}
+
+static void
+store_in_ref_table (unsigned int offset, struct die_info *die)
+{
+ int h;
+ struct die_info *old;
+
+ h = (offset % REF_HASH_SIZE);
+ old = die_ref_table[h];
+ die->next_ref = old;
+ die_ref_table[h] = die;
+}
+
+
+static void
+dwarf2_empty_hash_tables (void)
+{
+ memset (die_ref_table, 0, sizeof (die_ref_table));
+}
+
+static unsigned int
+dwarf2_get_ref_die_offset (struct attribute *attr)
+{
+ unsigned int result = 0;
+
+ switch (attr->form)
+ {
+ case DW_FORM_ref_addr:
+ result = DW_ADDR (attr);
+ break;
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
+ result = cu_header_offset + DW_UNSND (attr);
+ break;
+ default:
+ complain (&dwarf2_unsupported_die_ref_attr, dwarf_form_name (attr->form));
+ }
+ return result;
+}
+
+static struct die_info *
+follow_die_ref (unsigned int offset)
+{
+ struct die_info *die;
+ int h;
+
+ h = (offset % REF_HASH_SIZE);
+ die = die_ref_table[h];
+ while (die)
+ {
+ if (die->offset == offset)
+ {
+ return die;
+ }
+ die = die->next_ref;
+ }
+ return NULL;
+}
+
+static struct type *
+dwarf2_fundamental_type (struct objfile *objfile, int typeid)
+{
+ if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
+ {
+ error ("Dwarf Error: internal error - invalid fundamental type id %d.",
+ typeid);
+ }
+
+ /* Look for this particular type in the fundamental type vector. If
+ one is not found, create and install one appropriate for the
+ current language and the current target machine. */
+
+ if (ftypes[typeid] == NULL)
+ {
+ ftypes[typeid] = cu_language_defn->la_fund_type (objfile, typeid);
+ }
+
+ return (ftypes[typeid]);
+}
+
+/* Decode simple location descriptions.
+ Given a pointer to a dwarf block that defines a location, compute
+ the location and return the value.
+
+ FIXME: This is a kludge until we figure out a better
+ way to handle the location descriptions.
+ Gdb's design does not mesh well with the DWARF2 notion of a location
+ computing interpreter, which is a shame because the flexibility goes unused.
+ FIXME: Implement more operations as necessary.
+
+ A location description containing no operations indicates that the
+ object is optimized out. The global optimized_out flag is set for
+ those, the return value is meaningless.
+
+ When the result is a register number, the global isreg flag is set,
+ otherwise it is cleared.
+
+ When the result is a base register offset, the global offreg flag is set
+ and the register number is returned in basereg, otherwise it is cleared.
+
+ When the DW_OP_fbreg operation is encountered without a corresponding
+ DW_AT_frame_base attribute, the global islocal flag is set.
+ Hopefully the machine dependent code knows how to set up a virtual
+ frame pointer for the local references.
+
+ Note that stack[0] is unused except as a default error return.
+ Note that stack overflow is not yet handled. */
+
+static CORE_ADDR
+decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
+ const struct comp_unit_head *cu_header)
+{
+ int i;
+ int size = blk->size;
+ char *data = blk->data;
+ CORE_ADDR stack[64];
+ int stacki;
+ unsigned int bytes_read, unsnd;
+ unsigned char op;
+
+ i = 0;
+ stacki = 0;
+ stack[stacki] = 0;
+ isreg = 0;
+ offreg = 0;
+ isderef = 0;
+ islocal = 0;
+ optimized_out = 1;
+
+ while (i < size)
+ {
+ optimized_out = 0;
+ op = data[i++];
+ switch (op)
+ {
+ case DW_OP_lit0:
+ case DW_OP_lit1:
+ case DW_OP_lit2:
+ case DW_OP_lit3:
+ case DW_OP_lit4:
+ case DW_OP_lit5:
+ case DW_OP_lit6:
+ case DW_OP_lit7:
+ case DW_OP_lit8:
+ case DW_OP_lit9:
+ case DW_OP_lit10:
+ case DW_OP_lit11:
+ case DW_OP_lit12:
+ case DW_OP_lit13:
+ case DW_OP_lit14:
+ case DW_OP_lit15:
+ case DW_OP_lit16:
+ case DW_OP_lit17:
+ case DW_OP_lit18:
+ case DW_OP_lit19:
+ case DW_OP_lit20:
+ case DW_OP_lit21:
+ case DW_OP_lit22:
+ case DW_OP_lit23:
+ case DW_OP_lit24:
+ case DW_OP_lit25:
+ case DW_OP_lit26:
+ case DW_OP_lit27:
+ case DW_OP_lit28:
+ case DW_OP_lit29:
+ case DW_OP_lit30:
+ case DW_OP_lit31:
+ stack[++stacki] = op - DW_OP_lit0;
+ break;
+
+ case DW_OP_reg0:
+ case DW_OP_reg1:
+ case DW_OP_reg2:
+ case DW_OP_reg3:
+ case DW_OP_reg4:
+ case DW_OP_reg5:
+ case DW_OP_reg6:
+ case DW_OP_reg7:
+ case DW_OP_reg8:
+ case DW_OP_reg9:
+ case DW_OP_reg10:
+ case DW_OP_reg11:
+ case DW_OP_reg12:
+ case DW_OP_reg13:
+ case DW_OP_reg14:
+ case DW_OP_reg15:
+ case DW_OP_reg16:
+ case DW_OP_reg17:
+ case DW_OP_reg18:
+ case DW_OP_reg19:
+ case DW_OP_reg20:
+ case DW_OP_reg21:
+ case DW_OP_reg22:
+ case DW_OP_reg23:
+ case DW_OP_reg24:
+ case DW_OP_reg25:
+ case DW_OP_reg26:
+ case DW_OP_reg27:
+ case DW_OP_reg28:
+ case DW_OP_reg29:
+ case DW_OP_reg30:
+ case DW_OP_reg31:
+ isreg = 1;
+ stack[++stacki] = op - DW_OP_reg0;
+ break;
+
+ case DW_OP_regx:
+ isreg = 1;
+ unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+#if defined(HARRIS_TARGET) && defined(_M88K)
+ /* The Harris 88110 gdb ports have long kept their special reg
+ numbers between their gp-regs and their x-regs. This is
+ not how our dwarf is generated. Punt. */
+ unsnd += 6;
+#endif
+ stack[++stacki] = unsnd;
+ break;
+
+ case DW_OP_breg0:
+ case DW_OP_breg1:
+ case DW_OP_breg2:
+ case DW_OP_breg3:
+ case DW_OP_breg4:
+ case DW_OP_breg5:
+ case DW_OP_breg6:
+ case DW_OP_breg7:
+ case DW_OP_breg8:
+ case DW_OP_breg9:
+ case DW_OP_breg10:
+ case DW_OP_breg11:
+ case DW_OP_breg12:
+ case DW_OP_breg13:
+ case DW_OP_breg14:
+ case DW_OP_breg15:
+ case DW_OP_breg16:
+ case DW_OP_breg17:
+ case DW_OP_breg18:
+ case DW_OP_breg19:
+ case DW_OP_breg20:
+ case DW_OP_breg21:
+ case DW_OP_breg22:
+ case DW_OP_breg23:
+ case DW_OP_breg24:
+ case DW_OP_breg25:
+ case DW_OP_breg26:
+ case DW_OP_breg27:
+ case DW_OP_breg28:
+ case DW_OP_breg29:
+ case DW_OP_breg30:
+ case DW_OP_breg31:
+ offreg = 1;
+ basereg = op - DW_OP_breg0;
+ stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_bregx:
+ offreg = 1;
+ basereg = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+ stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_fbreg:
+ stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+ if (frame_base_reg >= 0)
+ {
+ offreg = 1;
+ basereg = frame_base_reg;
+ stack[stacki] += frame_base_offset;
+ }
+ else
+ {
+ complain (&dwarf2_missing_at_frame_base);
+ islocal = 1;
+ }
+ break;
+
+ case DW_OP_addr:
+ stack[++stacki] = read_address (objfile->obfd, &data[i],
+ cu_header, &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_const1u:
+ stack[++stacki] = read_1_byte (objfile->obfd, &data[i]);
+ i += 1;
+ break;
+
+ case DW_OP_const1s:
+ stack[++stacki] = read_1_signed_byte (objfile->obfd, &data[i]);
+ i += 1;
+ break;
+
+ case DW_OP_const2u:
+ stack[++stacki] = read_2_bytes (objfile->obfd, &data[i]);
+ i += 2;
+ break;
+
+ case DW_OP_const2s:
+ stack[++stacki] = read_2_signed_bytes (objfile->obfd, &data[i]);
+ i += 2;
+ break;
+
+ case DW_OP_const4u:
+ stack[++stacki] = read_4_bytes (objfile->obfd, &data[i]);
+ i += 4;
+ break;
+
+ case DW_OP_const4s:
+ stack[++stacki] = read_4_signed_bytes (objfile->obfd, &data[i]);
+ i += 4;
+ break;
+
+ case DW_OP_constu:
+ stack[++stacki] = read_unsigned_leb128 (NULL, (data + i),
+ &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_consts:
+ stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_dup:
+ stack[stacki + 1] = stack[stacki];
+ stacki++;
+ break;
+
+ case DW_OP_plus:
+ stack[stacki - 1] += stack[stacki];
+ stacki--;
+ break;
+
+ case DW_OP_plus_uconst:
+ stack[stacki] += read_unsigned_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_minus:
+ stack[stacki - 1] -= stack[stacki];
+ stacki--;
+ break;
+
+ case DW_OP_deref:
+ isderef = 1;
+ /* If we're not the last op, then we definitely can't encode
+ this using GDB's address_class enum. */
+ if (i < size)
+ complain (&dwarf2_complex_location_expr);
+ break;
+
+ default:
+ complain (&dwarf2_unsupported_stack_op, dwarf_stack_op_name (op));
+ return (stack[stacki]);
+ }
+ }
+ return (stack[stacki]);
+}
+
+/* memory allocation interface */
+
+/* ARGSUSED */
+static void
+dwarf2_free_tmp_obstack (PTR ignore)
+{
+ obstack_free (&dwarf2_tmp_obstack, NULL);
+}
+
+static struct dwarf_block *
+dwarf_alloc_block (void)
+{
+ struct dwarf_block *blk;
+
+ blk = (struct dwarf_block *)
+ obstack_alloc (&dwarf2_tmp_obstack, sizeof (struct dwarf_block));
+ return (blk);
+}
+
+static struct abbrev_info *
+dwarf_alloc_abbrev (void)
+{
+ struct abbrev_info *abbrev;
+
+ abbrev = (struct abbrev_info *) xmalloc (sizeof (struct abbrev_info));
+ memset (abbrev, 0, sizeof (struct abbrev_info));
+ return (abbrev);
+}
+
+static struct die_info *
+dwarf_alloc_die (void)
+{
+ struct die_info *die;
+
+ die = (struct die_info *) xmalloc (sizeof (struct die_info));
+ memset (die, 0, sizeof (struct die_info));
+ return (die);
+}
+
+
+/* Macro support. */
+
+
+/* Return the full name of file number I in *LH's file name table.
+ Use COMP_DIR as the name of the current directory of the
+ compilation. The result is allocated using xmalloc; the caller is
+ responsible for freeing it. */
+static char *
+file_full_name (int file, struct line_header *lh, const char *comp_dir)
+{
+ struct file_entry *fe = &lh->file_names[file - 1];
+
+ if (IS_ABSOLUTE_PATH (fe->name))
+ return xstrdup (fe->name);
+ else
+ {
+ const char *dir;
+ int dir_len;
+ char *full_name;
+
+ if (fe->dir_index)
+ dir = lh->include_dirs[fe->dir_index - 1];
+ else
+ dir = comp_dir;
+
+ if (dir)
+ {
+ dir_len = strlen (dir);
+ full_name = xmalloc (dir_len + 1 + strlen (fe->name) + 1);
+ strcpy (full_name, dir);
+ full_name[dir_len] = '/';
+ strcpy (full_name + dir_len + 1, fe->name);
+ return full_name;
+ }
+ else
+ return xstrdup (fe->name);
+ }
+}
+
+
+static struct macro_source_file *
+macro_start_file (int file, int line,
+ struct macro_source_file *current_file,
+ const char *comp_dir,
+ struct line_header *lh, struct objfile *objfile)
+{
+ /* The full name of this source file. */
+ char *full_name = file_full_name (file, lh, comp_dir);
+
+ /* We don't create a macro table for this compilation unit
+ at all until we actually get a filename. */
+ if (! pending_macros)
+ pending_macros = new_macro_table (&objfile->symbol_obstack,
+ &objfile->macro_cache);
+
+ if (! current_file)
+ /* If we have no current file, then this must be the start_file
+ directive for the compilation unit's main source file. */
+ current_file = macro_set_main (pending_macros, full_name);
+ else
+ current_file = macro_include (current_file, line, full_name);
+
+ xfree (full_name);
+
+ return current_file;
+}
+
+
+/* Copy the LEN characters at BUF to a xmalloc'ed block of memory,
+ followed by a null byte. */
+static char *
+copy_string (const char *buf, int len)
+{
+ char *s = xmalloc (len + 1);
+ memcpy (s, buf, len);
+ s[len] = '\0';
+
+ return s;
+}
+
+
+static const char *
+consume_improper_spaces (const char *p, const char *body)
+{
+ if (*p == ' ')
+ {
+ complain (&dwarf2_macro_spaces_in_definition, body);
+
+ while (*p == ' ')
+ p++;
+ }
+
+ return p;
+}
+
+
+static void
+parse_macro_definition (struct macro_source_file *file, int line,
+ const char *body)
+{
+ const char *p;
+
+ /* The body string takes one of two forms. For object-like macro
+ definitions, it should be:
+
+ <macro name> " " <definition>
+
+ For function-like macro definitions, it should be:
+
+ <macro name> "() " <definition>
+ or
+ <macro name> "(" <arg name> ( "," <arg name> ) * ") " <definition>
+
+ Spaces may appear only where explicitly indicated, and in the
+ <definition>.
+
+ The Dwarf 2 spec says that an object-like macro's name is always
+ followed by a space, but versions of GCC around March 2002 omit
+ the space when the macro's definition is the empty string.
+
+ The Dwarf 2 spec says that there should be no spaces between the
+ formal arguments in a function-like macro's formal argument list,
+ but versions of GCC around March 2002 include spaces after the
+ commas. */
+
+
+ /* Find the extent of the macro name. The macro name is terminated
+ by either a space or null character (for an object-like macro) or
+ an opening paren (for a function-like macro). */
+ for (p = body; *p; p++)
+ if (*p == ' ' || *p == '(')
+ break;
+
+ if (*p == ' ' || *p == '\0')
+ {
+ /* It's an object-like macro. */
+ int name_len = p - body;
+ char *name = copy_string (body, name_len);
+ const char *replacement;
+
+ if (*p == ' ')
+ replacement = body + name_len + 1;
+ else
+ {
+ complain (&dwarf2_macro_malformed_definition, body);
+ replacement = body + name_len;
+ }
+
+ macro_define_object (file, line, name, replacement);
+
+ xfree (name);
+ }
+ else if (*p == '(')
+ {
+ /* It's a function-like macro. */
+ char *name = copy_string (body, p - body);
+ int argc = 0;
+ int argv_size = 1;
+ char **argv = xmalloc (argv_size * sizeof (*argv));
+
+ p++;
+
+ p = consume_improper_spaces (p, body);
+
+ /* Parse the formal argument list. */
+ while (*p && *p != ')')
+ {
+ /* Find the extent of the current argument name. */
+ const char *arg_start = p;
+
+ while (*p && *p != ',' && *p != ')' && *p != ' ')
+ p++;
+
+ if (! *p || p == arg_start)
+ complain (&dwarf2_macro_malformed_definition,
+ body);
+ else
+ {
+ /* Make sure argv has room for the new argument. */
+ if (argc >= argv_size)
+ {
+ argv_size *= 2;
+ argv = xrealloc (argv, argv_size * sizeof (*argv));
+ }
+
+ argv[argc++] = copy_string (arg_start, p - arg_start);
+ }
+
+ p = consume_improper_spaces (p, body);
+
+ /* Consume the comma, if present. */
+ if (*p == ',')
+ {
+ p++;
+
+ p = consume_improper_spaces (p, body);
+ }
+ }
+
+ if (*p == ')')
+ {
+ p++;
+
+ if (*p == ' ')
+ /* Perfectly formed definition, no complaints. */
+ macro_define_function (file, line, name,
+ argc, (const char **) argv,
+ p + 1);
+ else if (*p == '\0')
+ {
+ /* Complain, but do define it. */
+ complain (&dwarf2_macro_malformed_definition, body);
+ macro_define_function (file, line, name,
+ argc, (const char **) argv,
+ p);
+ }
+ else
+ /* Just complain. */
+ complain (&dwarf2_macro_malformed_definition, body);
+ }
+ else
+ /* Just complain. */
+ complain (&dwarf2_macro_malformed_definition, body);
+
+ xfree (name);
+ {
+ int i;
+
+ for (i = 0; i < argc; i++)
+ xfree (argv[i]);
+ }
+ xfree (argv);
+ }
+ else
+ complain (&dwarf2_macro_malformed_definition, body);
+}
+
+
+static void
+dwarf_decode_macros (struct line_header *lh, unsigned int offset,
+ char *comp_dir, bfd *abfd,
+ const struct comp_unit_head *cu_header,
+ struct objfile *objfile)
+{
+ char *mac_ptr, *mac_end;
+ struct macro_source_file *current_file = 0;
+
+ if (dwarf_macinfo_buffer == NULL)
+ {
+ complain (&dwarf2_missing_macinfo_section);
+ return;
+ }
+
+ mac_ptr = dwarf_macinfo_buffer + offset;
+ mac_end = dwarf_macinfo_buffer + dwarf_macinfo_size;
+
+ for (;;)
+ {
+ enum dwarf_macinfo_record_type macinfo_type;
+
+ /* Do we at least have room for a macinfo type byte? */
+ if (mac_ptr >= mac_end)
+ {
+ complain (&dwarf2_macros_too_long);
+ return;
+ }
+
+ macinfo_type = read_1_byte (abfd, mac_ptr);
+ mac_ptr++;
+
+ switch (macinfo_type)
+ {
+ /* A zero macinfo type indicates the end of the macro
+ information. */
+ case 0:
+ return;
+
+ case DW_MACINFO_define:
+ case DW_MACINFO_undef:
+ {
+ int bytes_read;
+ int line;
+ char *body;
+
+ line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ body = read_string (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+
+ if (! current_file)
+ complain (&dwarf2_macro_outside_file,
+ macinfo_type == DW_MACINFO_define ? "definition" :
+ macinfo_type == DW_MACINFO_undef ? "undefinition" :
+ "something-or-other",
+ body);
+ else
+ {
+ if (macinfo_type == DW_MACINFO_define)
+ parse_macro_definition (current_file, line, body);
+ else if (macinfo_type == DW_MACINFO_undef)
+ macro_undef (current_file, line, body);
+ }
+ }
+ break;
+
+ case DW_MACINFO_start_file:
+ {
+ int bytes_read;
+ int line, file;
+
+ line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+
+ current_file = macro_start_file (file, line,
+ current_file, comp_dir,
+ lh, objfile);
+ }
+ break;
+
+ case DW_MACINFO_end_file:
+ if (! current_file)
+ complain (&dwarf2_macro_unmatched_end_file);
+ else
+ {
+ current_file = current_file->included_by;
+ if (! current_file)
+ {
+ enum dwarf_macinfo_record_type next_type;
+
+ /* GCC circa March 2002 doesn't produce the zero
+ type byte marking the end of the compilation
+ unit. Complain if it's not there, but exit no
+ matter what. */
+
+ /* Do we at least have room for a macinfo type byte? */
+ if (mac_ptr >= mac_end)
+ {
+ complain (&dwarf2_macros_too_long);
+ return;
+ }
+
+ /* We don't increment mac_ptr here, so this is just
+ a look-ahead. */
+ next_type = read_1_byte (abfd, mac_ptr);
+ if (next_type != 0)
+ complain (&dwarf2_macros_not_terminated);
+
+ return;
+ }
+ }
+ break;
+
+ case DW_MACINFO_vendor_ext:
+ {
+ int bytes_read;
+ int constant;
+ char *string;
+
+ constant = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ string = read_string (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+
+ /* We don't recognize any vendor extensions. */
+ }
+ break;
+ }
+ }
+}
diff --git a/gdb/dwarfread.c b/gdb/dwarfread.c
new file mode 100644
index 00000000000..dc72f87661d
--- /dev/null
+++ b/gdb/dwarfread.c
@@ -0,0 +1,3788 @@
+/* DWARF debugging format support for GDB.
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002
+ Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus Support. Portions based on dbxread.c,
+ mipsread.c, coffread.c, and dwarfread.c from a Data General SVR4 gdb port.
+
+ 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. */
+
+/*
+
+ FIXME: Do we need to generate dependencies in partial symtabs?
+ (Perhaps we don't need to).
+
+ FIXME: Resolve minor differences between what information we put in the
+ partial symbol table and what dbxread puts in. For example, we don't yet
+ put enum constants there. And dbxread seems to invent a lot of typedefs
+ we never see. Use the new printpsym command to see the partial symbol table
+ contents.
+
+ FIXME: Figure out a better way to tell gdb about the name of the function
+ contain the user's entry point (I.E. main())
+
+ FIXME: See other FIXME's and "ifdef 0" scattered throughout the code for
+ other things to work on, if you get bored. :-)
+
+ */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "elf/dwarf.h"
+#include "buildsym.h"
+#include "demangle.h"
+#include "expression.h" /* Needed for enum exp_opcode in language.h, sigh... */
+#include "language.h"
+#include "complaints.h"
+
+#include <fcntl.h>
+#include "gdb_string.h"
+
+/* Some macros to provide DIE info for complaints. */
+
+#define DIE_ID (curdie!=NULL ? curdie->die_ref : 0)
+#define DIE_NAME (curdie!=NULL && curdie->at_name!=NULL) ? curdie->at_name : ""
+
+/* Complaints that can be issued during DWARF debug info reading. */
+
+struct complaint no_bfd_get_N =
+{
+ "DIE @ 0x%x \"%s\", no bfd support for %d byte data object", 0, 0
+};
+
+struct complaint malformed_die =
+{
+ "DIE @ 0x%x \"%s\", malformed DIE, bad length (%d bytes)", 0, 0
+};
+
+struct complaint bad_die_ref =
+{
+ "DIE @ 0x%x \"%s\", reference to DIE (0x%x) outside compilation unit", 0, 0
+};
+
+struct complaint unknown_attribute_form =
+{
+ "DIE @ 0x%x \"%s\", unknown attribute form (0x%x)", 0, 0
+};
+
+struct complaint unknown_attribute_length =
+{
+ "DIE @ 0x%x \"%s\", unknown attribute length, skipped remaining attributes", 0, 0
+};
+
+struct complaint unexpected_fund_type =
+{
+ "DIE @ 0x%x \"%s\", unexpected fundamental type 0x%x", 0, 0
+};
+
+struct complaint unknown_type_modifier =
+{
+ "DIE @ 0x%x \"%s\", unknown type modifier %u", 0, 0
+};
+
+struct complaint volatile_ignored =
+{
+ "DIE @ 0x%x \"%s\", type modifier 'volatile' ignored", 0, 0
+};
+
+struct complaint const_ignored =
+{
+ "DIE @ 0x%x \"%s\", type modifier 'const' ignored", 0, 0
+};
+
+struct complaint botched_modified_type =
+{
+ "DIE @ 0x%x \"%s\", botched modified type decoding (mtype 0x%x)", 0, 0
+};
+
+struct complaint op_deref2 =
+{
+ "DIE @ 0x%x \"%s\", OP_DEREF2 address 0x%x not handled", 0, 0
+};
+
+struct complaint op_deref4 =
+{
+ "DIE @ 0x%x \"%s\", OP_DEREF4 address 0x%x not handled", 0, 0
+};
+
+struct complaint basereg_not_handled =
+{
+ "DIE @ 0x%x \"%s\", BASEREG %d not handled", 0, 0
+};
+
+struct complaint dup_user_type_allocation =
+{
+ "DIE @ 0x%x \"%s\", internal error: duplicate user type allocation", 0, 0
+};
+
+struct complaint dup_user_type_definition =
+{
+ "DIE @ 0x%x \"%s\", internal error: duplicate user type definition", 0, 0
+};
+
+struct complaint missing_tag =
+{
+ "DIE @ 0x%x \"%s\", missing class, structure, or union tag", 0, 0
+};
+
+struct complaint bad_array_element_type =
+{
+ "DIE @ 0x%x \"%s\", bad array element type attribute 0x%x", 0, 0
+};
+
+struct complaint subscript_data_items =
+{
+ "DIE @ 0x%x \"%s\", can't decode subscript data items", 0, 0
+};
+
+struct complaint unhandled_array_subscript_format =
+{
+ "DIE @ 0x%x \"%s\", array subscript format 0x%x not handled yet", 0, 0
+};
+
+struct complaint unknown_array_subscript_format =
+{
+ "DIE @ 0x%x \"%s\", unknown array subscript format %x", 0, 0
+};
+
+struct complaint not_row_major =
+{
+ "DIE @ 0x%x \"%s\", array not row major; not handled correctly", 0, 0
+};
+
+struct complaint missing_at_name =
+{
+ "DIE @ 0x%x, AT_name tag missing", 0, 0
+};
+
+typedef unsigned int DIE_REF; /* Reference to a DIE */
+
+#ifndef GCC_PRODUCER
+#define GCC_PRODUCER "GNU C "
+#endif
+
+#ifndef GPLUS_PRODUCER
+#define GPLUS_PRODUCER "GNU C++ "
+#endif
+
+#ifndef LCC_PRODUCER
+#define LCC_PRODUCER "NCR C/C++"
+#endif
+
+#ifndef CHILL_PRODUCER
+#define CHILL_PRODUCER "GNU Chill "
+#endif
+
+/* Flags to target_to_host() that tell whether or not the data object is
+ expected to be signed. Used, for example, when fetching a signed
+ integer in the target environment which is used as a signed integer
+ in the host environment, and the two environments have different sized
+ ints. In this case, *somebody* has to sign extend the smaller sized
+ int. */
+
+#define GET_UNSIGNED 0 /* No sign extension required */
+#define GET_SIGNED 1 /* Sign extension required */
+
+/* Defines for things which are specified in the document "DWARF Debugging
+ Information Format" published by UNIX International, Programming Languages
+ SIG. These defines are based on revision 1.0.0, Jan 20, 1992. */
+
+#define SIZEOF_DIE_LENGTH 4
+#define SIZEOF_DIE_TAG 2
+#define SIZEOF_ATTRIBUTE 2
+#define SIZEOF_FORMAT_SPECIFIER 1
+#define SIZEOF_FMT_FT 2
+#define SIZEOF_LINETBL_LENGTH 4
+#define SIZEOF_LINETBL_LINENO 4
+#define SIZEOF_LINETBL_STMT 2
+#define SIZEOF_LINETBL_DELTA 4
+#define SIZEOF_LOC_ATOM_CODE 1
+
+#define FORM_FROM_ATTR(attr) ((attr) & 0xF) /* Implicitly specified */
+
+/* Macros that return the sizes of various types of data in the target
+ environment.
+
+ FIXME: Currently these are just compile time constants (as they are in
+ other parts of gdb as well). They need to be able to get the right size
+ either from the bfd or possibly from the DWARF info. It would be nice if
+ the DWARF producer inserted DIES that describe the fundamental types in
+ the target environment into the DWARF info, similar to the way dbx stabs
+ producers produce information about their fundamental types. */
+
+#define TARGET_FT_POINTER_SIZE(objfile) (TARGET_PTR_BIT / TARGET_CHAR_BIT)
+#define TARGET_FT_LONG_SIZE(objfile) (TARGET_LONG_BIT / TARGET_CHAR_BIT)
+
+/* The Amiga SVR4 header file <dwarf.h> defines AT_element_list as a
+ FORM_BLOCK2, and this is the value emitted by the AT&T compiler.
+ However, the Issue 2 DWARF specification from AT&T defines it as
+ a FORM_BLOCK4, as does the latest specification from UI/PLSIG.
+ For backwards compatibility with the AT&T compiler produced executables
+ we define AT_short_element_list for this variant. */
+
+#define AT_short_element_list (0x00f0|FORM_BLOCK2)
+
+/* The DWARF debugging information consists of two major pieces,
+ one is a block of DWARF Information Entries (DIE's) and the other
+ is a line number table. The "struct dieinfo" structure contains
+ the information for a single DIE, the one currently being processed.
+
+ In order to make it easier to randomly access the attribute fields
+ of the current DIE, which are specifically unordered within the DIE,
+ each DIE is scanned and an instance of the "struct dieinfo"
+ structure is initialized.
+
+ Initialization is done in two levels. The first, done by basicdieinfo(),
+ just initializes those fields that are vital to deciding whether or not
+ to use this DIE, how to skip past it, etc. The second, done by the
+ function completedieinfo(), fills in the rest of the information.
+
+ Attributes which have block forms are not interpreted at the time
+ the DIE is scanned, instead we just save pointers to the start
+ of their value fields.
+
+ Some fields have a flag <name>_p that is set when the value of the
+ field is valid (I.E. we found a matching attribute in the DIE). Since
+ we may want to test for the presence of some attributes in the DIE,
+ such as AT_low_pc, without restricting the values of the field,
+ we need someway to note that we found such an attribute.
+
+ */
+
+typedef char BLOCK;
+
+struct dieinfo
+ {
+ char *die; /* Pointer to the raw DIE data */
+ unsigned long die_length; /* Length of the raw DIE data */
+ DIE_REF die_ref; /* Offset of this DIE */
+ unsigned short die_tag; /* Tag for this DIE */
+ unsigned long at_padding;
+ unsigned long at_sibling;
+ BLOCK *at_location;
+ char *at_name;
+ unsigned short at_fund_type;
+ BLOCK *at_mod_fund_type;
+ unsigned long at_user_def_type;
+ BLOCK *at_mod_u_d_type;
+ unsigned short at_ordering;
+ BLOCK *at_subscr_data;
+ unsigned long at_byte_size;
+ unsigned short at_bit_offset;
+ unsigned long at_bit_size;
+ BLOCK *at_element_list;
+ unsigned long at_stmt_list;
+ CORE_ADDR at_low_pc;
+ CORE_ADDR at_high_pc;
+ unsigned long at_language;
+ unsigned long at_member;
+ unsigned long at_discr;
+ BLOCK *at_discr_value;
+ BLOCK *at_string_length;
+ char *at_comp_dir;
+ char *at_producer;
+ unsigned long at_start_scope;
+ unsigned long at_stride_size;
+ unsigned long at_src_info;
+ char *at_prototyped;
+ unsigned int has_at_low_pc:1;
+ unsigned int has_at_stmt_list:1;
+ unsigned int has_at_byte_size:1;
+ unsigned int short_element_list:1;
+
+ /* Kludge to identify register variables */
+
+ unsigned int isreg;
+
+ /* Kludge to identify optimized out variables */
+
+ unsigned int optimized_out;
+
+ /* Kludge to identify basereg references.
+ Nonzero if we have an offset relative to a basereg. */
+
+ unsigned int offreg;
+
+ /* Kludge to identify which base register is it relative to. */
+
+ unsigned int basereg;
+ };
+
+static int diecount; /* Approximate count of dies for compilation unit */
+static struct dieinfo *curdie; /* For warnings and such */
+
+static char *dbbase; /* Base pointer to dwarf info */
+static int dbsize; /* Size of dwarf info in bytes */
+static int dbroff; /* Relative offset from start of .debug section */
+static char *lnbase; /* Base pointer to line section */
+
+/* This value is added to each symbol value. FIXME: Generalize to
+ the section_offsets structure used by dbxread (once this is done,
+ pass the appropriate section number to end_symtab). */
+static CORE_ADDR baseaddr; /* Add to each symbol value */
+
+/* The section offsets used in the current psymtab or symtab. FIXME,
+ only used to pass one value (baseaddr) at the moment. */
+static struct section_offsets *base_section_offsets;
+
+/* We put a pointer to this structure in the read_symtab_private field
+ of the psymtab. */
+
+struct dwfinfo
+ {
+ /* Always the absolute file offset to the start of the ".debug"
+ section for the file containing the DIE's being accessed. */
+ file_ptr dbfoff;
+ /* Relative offset from the start of the ".debug" section to the
+ first DIE to be accessed. When building the partial symbol
+ table, this value will be zero since we are accessing the
+ entire ".debug" section. When expanding a partial symbol
+ table entry, this value will be the offset to the first
+ DIE for the compilation unit containing the symbol that
+ triggers the expansion. */
+ int dbroff;
+ /* The size of the chunk of DIE's being examined, in bytes. */
+ int dblength;
+ /* The absolute file offset to the line table fragment. Ignored
+ when building partial symbol tables, but used when expanding
+ them, and contains the absolute file offset to the fragment
+ of the ".line" section containing the line numbers for the
+ current compilation unit. */
+ file_ptr lnfoff;
+ };
+
+#define DBFOFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->dbfoff)
+#define DBROFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->dbroff)
+#define DBLENGTH(p) (((struct dwfinfo *)((p)->read_symtab_private))->dblength)
+#define LNFOFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->lnfoff)
+
+/* The generic symbol table building routines have separate lists for
+ file scope symbols and all all other scopes (local scopes). So
+ we need to select the right one to pass to add_symbol_to_list().
+ We do it by keeping a pointer to the correct list in list_in_scope.
+
+ FIXME: The original dwarf code just treated the file scope as the first
+ local scope, and all other local scopes as nested local scopes, and worked
+ fine. Check to see if we really need to distinguish these in buildsym.c */
+
+struct pending **list_in_scope = &file_symbols;
+
+/* DIES which have user defined types or modified user defined types refer to
+ other DIES for the type information. Thus we need to associate the offset
+ of a DIE for a user defined type with a pointer to the type information.
+
+ Originally this was done using a simple but expensive algorithm, with an
+ array of unsorted structures, each containing an offset/type-pointer pair.
+ This array was scanned linearly each time a lookup was done. The result
+ was that gdb was spending over half it's startup time munging through this
+ array of pointers looking for a structure that had the right offset member.
+
+ The second attempt used the same array of structures, but the array was
+ sorted using qsort each time a new offset/type was recorded, and a binary
+ search was used to find the type pointer for a given DIE offset. This was
+ even slower, due to the overhead of sorting the array each time a new
+ offset/type pair was entered.
+
+ The third attempt uses a fixed size array of type pointers, indexed by a
+ value derived from the DIE offset. Since the minimum DIE size is 4 bytes,
+ we can divide any DIE offset by 4 to obtain a unique index into this fixed
+ size array. Since each element is a 4 byte pointer, it takes exactly as
+ much memory to hold this array as to hold the DWARF info for a given
+ compilation unit. But it gets freed as soon as we are done with it.
+ This has worked well in practice, as a reasonable tradeoff between memory
+ consumption and speed, without having to resort to much more complicated
+ algorithms. */
+
+static struct type **utypes; /* Pointer to array of user type pointers */
+static int numutypes; /* Max number of user type pointers */
+
+/* Maintain an array of referenced fundamental types for the current
+ compilation unit being read. For DWARF version 1, we have to construct
+ the fundamental types on the fly, since no information about the
+ fundamental types is supplied. Each such fundamental type is created by
+ calling a language dependent routine to create the type, and then a
+ pointer to that type is then placed in the array at the index specified
+ by it's FT_<TYPENAME> value. The array has a fixed size set by the
+ FT_NUM_MEMBERS compile time constant, which is the number of predefined
+ fundamental types gdb knows how to construct. */
+
+static struct type *ftypes[FT_NUM_MEMBERS]; /* Fundamental types */
+
+/* Record the language for the compilation unit which is currently being
+ processed. We know it once we have seen the TAG_compile_unit DIE,
+ and we need it while processing the DIE's for that compilation unit.
+ It is eventually saved in the symtab structure, but we don't finalize
+ the symtab struct until we have processed all the DIE's for the
+ compilation unit. We also need to get and save a pointer to the
+ language struct for this language, so we can call the language
+ dependent routines for doing things such as creating fundamental
+ types. */
+
+static enum language cu_language;
+static const struct language_defn *cu_language_defn;
+
+/* Forward declarations of static functions so we don't have to worry
+ about ordering within this file. */
+
+static void free_utypes (PTR);
+
+static int attribute_size (unsigned int);
+
+static CORE_ADDR target_to_host (char *, int, int, struct objfile *);
+
+static void add_enum_psymbol (struct dieinfo *, struct objfile *);
+
+static void handle_producer (char *);
+
+static void
+read_file_scope (struct dieinfo *, char *, char *, struct objfile *);
+
+static void
+read_func_scope (struct dieinfo *, char *, char *, struct objfile *);
+
+static void
+read_lexical_block_scope (struct dieinfo *, char *, char *, struct objfile *);
+
+static void scan_partial_symbols (char *, char *, struct objfile *);
+
+static void
+scan_compilation_units (char *, char *, file_ptr, file_ptr, struct objfile *);
+
+static void add_partial_symbol (struct dieinfo *, struct objfile *);
+
+static void basicdieinfo (struct dieinfo *, char *, struct objfile *);
+
+static void completedieinfo (struct dieinfo *, struct objfile *);
+
+static void dwarf_psymtab_to_symtab (struct partial_symtab *);
+
+static void psymtab_to_symtab_1 (struct partial_symtab *);
+
+static void read_ofile_symtab (struct partial_symtab *);
+
+static void process_dies (char *, char *, struct objfile *);
+
+static void
+read_structure_scope (struct dieinfo *, char *, char *, struct objfile *);
+
+static struct type *decode_array_element_type (char *);
+
+static struct type *decode_subscript_data_item (char *, char *);
+
+static void dwarf_read_array_type (struct dieinfo *);
+
+static void read_tag_pointer_type (struct dieinfo *dip);
+
+static void read_tag_string_type (struct dieinfo *dip);
+
+static void read_subroutine_type (struct dieinfo *, char *, char *);
+
+static void
+read_enumeration (struct dieinfo *, char *, char *, struct objfile *);
+
+static struct type *struct_type (struct dieinfo *, char *, char *,
+ struct objfile *);
+
+static struct type *enum_type (struct dieinfo *, struct objfile *);
+
+static void decode_line_numbers (char *);
+
+static struct type *decode_die_type (struct dieinfo *);
+
+static struct type *decode_mod_fund_type (char *);
+
+static struct type *decode_mod_u_d_type (char *);
+
+static struct type *decode_modified_type (char *, unsigned int, int);
+
+static struct type *decode_fund_type (unsigned int);
+
+static char *create_name (char *, struct obstack *);
+
+static struct type *lookup_utype (DIE_REF);
+
+static struct type *alloc_utype (DIE_REF, struct type *);
+
+static struct symbol *new_symbol (struct dieinfo *, struct objfile *);
+
+static void
+synthesize_typedef (struct dieinfo *, struct objfile *, struct type *);
+
+static int locval (struct dieinfo *);
+
+static void set_cu_language (struct dieinfo *);
+
+static struct type *dwarf_fundamental_type (struct objfile *, int);
+
+
+/*
+
+ LOCAL FUNCTION
+
+ dwarf_fundamental_type -- lookup or create a fundamental type
+
+ SYNOPSIS
+
+ struct type *
+ dwarf_fundamental_type (struct objfile *objfile, int typeid)
+
+ DESCRIPTION
+
+ DWARF version 1 doesn't supply any fundamental type information,
+ so gdb has to construct such types. It has a fixed number of
+ fundamental types that it knows how to construct, which is the
+ union of all types that it knows how to construct for all languages
+ that it knows about. These are enumerated in gdbtypes.h.
+
+ As an example, assume we find a DIE that references a DWARF
+ fundamental type of FT_integer. We first look in the ftypes
+ array to see if we already have such a type, indexed by the
+ gdb internal value of FT_INTEGER. If so, we simply return a
+ pointer to that type. If not, then we ask an appropriate
+ language dependent routine to create a type FT_INTEGER, using
+ defaults reasonable for the current target machine, and install
+ that type in ftypes for future reference.
+
+ RETURNS
+
+ Pointer to a fundamental type.
+
+ */
+
+static struct type *
+dwarf_fundamental_type (struct objfile *objfile, int typeid)
+{
+ if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
+ {
+ error ("internal error - invalid fundamental type id %d", typeid);
+ }
+
+ /* Look for this particular type in the fundamental type vector. If one is
+ not found, create and install one appropriate for the current language
+ and the current target machine. */
+
+ if (ftypes[typeid] == NULL)
+ {
+ ftypes[typeid] = cu_language_defn->la_fund_type (objfile, typeid);
+ }
+
+ return (ftypes[typeid]);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ set_cu_language -- set local copy of language for compilation unit
+
+ SYNOPSIS
+
+ void
+ set_cu_language (struct dieinfo *dip)
+
+ DESCRIPTION
+
+ Decode the language attribute for a compilation unit DIE and
+ remember what the language was. We use this at various times
+ when processing DIE's for a given compilation unit.
+
+ RETURNS
+
+ No return value.
+
+ */
+
+static void
+set_cu_language (struct dieinfo *dip)
+{
+ switch (dip->at_language)
+ {
+ case LANG_C89:
+ case LANG_C:
+ cu_language = language_c;
+ break;
+ case LANG_C_PLUS_PLUS:
+ cu_language = language_cplus;
+ break;
+ case LANG_CHILL:
+ cu_language = language_chill;
+ break;
+ case LANG_MODULA2:
+ cu_language = language_m2;
+ break;
+ case LANG_FORTRAN77:
+ case LANG_FORTRAN90:
+ cu_language = language_fortran;
+ break;
+ case LANG_ADA83:
+ case LANG_COBOL74:
+ case LANG_COBOL85:
+ case LANG_PASCAL83:
+ /* We don't know anything special about these yet. */
+ cu_language = language_unknown;
+ break;
+ default:
+ /* If no at_language, try to deduce one from the filename */
+ cu_language = deduce_language_from_filename (dip->at_name);
+ break;
+ }
+ cu_language_defn = language_def (cu_language);
+}
+
+/*
+
+ GLOBAL FUNCTION
+
+ dwarf_build_psymtabs -- build partial symtabs from DWARF debug info
+
+ SYNOPSIS
+
+ void dwarf_build_psymtabs (struct objfile *objfile,
+ int mainline, file_ptr dbfoff, unsigned int dbfsize,
+ file_ptr lnoffset, unsigned int lnsize)
+
+ DESCRIPTION
+
+ This function is called upon to build partial symtabs from files
+ containing DIE's (Dwarf Information Entries) and DWARF line numbers.
+
+ It is passed a bfd* containing the DIES
+ and line number information, the corresponding filename for that
+ file, a base address for relocating the symbols, a flag indicating
+ whether or not this debugging information is from a "main symbol
+ table" rather than a shared library or dynamically linked file,
+ and file offset/size pairs for the DIE information and line number
+ information.
+
+ RETURNS
+
+ No return value.
+
+ */
+
+void
+dwarf_build_psymtabs (struct objfile *objfile, int mainline, file_ptr dbfoff,
+ unsigned int dbfsize, file_ptr lnoffset,
+ unsigned int lnsize)
+{
+ bfd *abfd = objfile->obfd;
+ struct cleanup *back_to;
+
+ current_objfile = objfile;
+ dbsize = dbfsize;
+ dbbase = xmalloc (dbsize);
+ dbroff = 0;
+ if ((bfd_seek (abfd, dbfoff, SEEK_SET) != 0) ||
+ (bfd_bread (dbbase, dbsize, abfd) != dbsize))
+ {
+ xfree (dbbase);
+ error ("can't read DWARF data from '%s'", bfd_get_filename (abfd));
+ }
+ back_to = make_cleanup (xfree, dbbase);
+
+ /* If we are reinitializing, or if we have never loaded syms yet, init.
+ Since we have no idea how many DIES we are looking at, we just guess
+ some arbitrary value. */
+
+ if (mainline
+ || (objfile->global_psymbols.size == 0
+ && objfile->static_psymbols.size == 0))
+ {
+ init_psymbol_list (objfile, 1024);
+ }
+
+ /* Save the relocation factor where everybody can see it. */
+
+ base_section_offsets = objfile->section_offsets;
+ baseaddr = ANOFFSET (objfile->section_offsets, 0);
+
+ /* Follow the compilation unit sibling chain, building a partial symbol
+ table entry for each one. Save enough information about each compilation
+ unit to locate the full DWARF information later. */
+
+ scan_compilation_units (dbbase, dbbase + dbsize, dbfoff, lnoffset, objfile);
+
+ do_cleanups (back_to);
+ current_objfile = NULL;
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ read_lexical_block_scope -- process all dies in a lexical block
+
+ SYNOPSIS
+
+ static void read_lexical_block_scope (struct dieinfo *dip,
+ char *thisdie, char *enddie)
+
+ DESCRIPTION
+
+ Process all the DIES contained within a lexical block scope.
+ Start a new scope, process the dies, and then close the scope.
+
+ */
+
+static void
+read_lexical_block_scope (struct dieinfo *dip, char *thisdie, char *enddie,
+ struct objfile *objfile)
+{
+ register struct context_stack *new;
+
+ push_context (0, dip->at_low_pc);
+ process_dies (thisdie + dip->die_length, enddie, objfile);
+ new = pop_context ();
+ if (local_symbols != NULL)
+ {
+ finish_block (0, &local_symbols, new->old_blocks, new->start_addr,
+ dip->at_high_pc, objfile);
+ }
+ local_symbols = new->locals;
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ lookup_utype -- look up a user defined type from die reference
+
+ SYNOPSIS
+
+ static type *lookup_utype (DIE_REF die_ref)
+
+ DESCRIPTION
+
+ Given a DIE reference, lookup the user defined type associated with
+ that DIE, if it has been registered already. If not registered, then
+ return NULL. Alloc_utype() can be called to register an empty
+ type for this reference, which will be filled in later when the
+ actual referenced DIE is processed.
+ */
+
+static struct type *
+lookup_utype (DIE_REF die_ref)
+{
+ struct type *type = NULL;
+ int utypeidx;
+
+ utypeidx = (die_ref - dbroff) / 4;
+ if ((utypeidx < 0) || (utypeidx >= numutypes))
+ {
+ complain (&bad_die_ref, DIE_ID, DIE_NAME);
+ }
+ else
+ {
+ type = *(utypes + utypeidx);
+ }
+ return (type);
+}
+
+
+/*
+
+ LOCAL FUNCTION
+
+ alloc_utype -- add a user defined type for die reference
+
+ SYNOPSIS
+
+ static type *alloc_utype (DIE_REF die_ref, struct type *utypep)
+
+ DESCRIPTION
+
+ Given a die reference DIE_REF, and a possible pointer to a user
+ defined type UTYPEP, register that this reference has a user
+ defined type and either use the specified type in UTYPEP or
+ make a new empty type that will be filled in later.
+
+ We should only be called after calling lookup_utype() to verify that
+ there is not currently a type registered for DIE_REF.
+ */
+
+static struct type *
+alloc_utype (DIE_REF die_ref, struct type *utypep)
+{
+ struct type **typep;
+ int utypeidx;
+
+ utypeidx = (die_ref - dbroff) / 4;
+ typep = utypes + utypeidx;
+ if ((utypeidx < 0) || (utypeidx >= numutypes))
+ {
+ utypep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+ complain (&bad_die_ref, DIE_ID, DIE_NAME);
+ }
+ else if (*typep != NULL)
+ {
+ utypep = *typep;
+ complain (&dup_user_type_allocation, DIE_ID, DIE_NAME);
+ }
+ else
+ {
+ if (utypep == NULL)
+ {
+ utypep = alloc_type (current_objfile);
+ }
+ *typep = utypep;
+ }
+ return (utypep);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ free_utypes -- free the utypes array and reset pointer & count
+
+ SYNOPSIS
+
+ static void free_utypes (PTR dummy)
+
+ DESCRIPTION
+
+ Called via do_cleanups to free the utypes array, reset the pointer to NULL,
+ and set numutypes back to zero. This ensures that the utypes does not get
+ referenced after being freed.
+ */
+
+static void
+free_utypes (PTR dummy)
+{
+ xfree (utypes);
+ utypes = NULL;
+ numutypes = 0;
+}
+
+
+/*
+
+ LOCAL FUNCTION
+
+ decode_die_type -- return a type for a specified die
+
+ SYNOPSIS
+
+ static struct type *decode_die_type (struct dieinfo *dip)
+
+ DESCRIPTION
+
+ Given a pointer to a die information structure DIP, decode the
+ type of the die and return a pointer to the decoded type. All
+ dies without specific types default to type int.
+ */
+
+static struct type *
+decode_die_type (struct dieinfo *dip)
+{
+ struct type *type = NULL;
+
+ if (dip->at_fund_type != 0)
+ {
+ type = decode_fund_type (dip->at_fund_type);
+ }
+ else if (dip->at_mod_fund_type != NULL)
+ {
+ type = decode_mod_fund_type (dip->at_mod_fund_type);
+ }
+ else if (dip->at_user_def_type)
+ {
+ if ((type = lookup_utype (dip->at_user_def_type)) == NULL)
+ {
+ type = alloc_utype (dip->at_user_def_type, NULL);
+ }
+ }
+ else if (dip->at_mod_u_d_type)
+ {
+ type = decode_mod_u_d_type (dip->at_mod_u_d_type);
+ }
+ else
+ {
+ type = dwarf_fundamental_type (current_objfile, FT_VOID);
+ }
+ return (type);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ struct_type -- compute and return the type for a struct or union
+
+ SYNOPSIS
+
+ static struct type *struct_type (struct dieinfo *dip, char *thisdie,
+ char *enddie, struct objfile *objfile)
+
+ DESCRIPTION
+
+ Given pointer to a die information structure for a die which
+ defines a union or structure (and MUST define one or the other),
+ and pointers to the raw die data that define the range of dies which
+ define the members, compute and return the user defined type for the
+ structure or union.
+ */
+
+static struct type *
+struct_type (struct dieinfo *dip, char *thisdie, char *enddie,
+ struct objfile *objfile)
+{
+ struct type *type;
+ struct nextfield
+ {
+ struct nextfield *next;
+ struct field field;
+ };
+ struct nextfield *list = NULL;
+ struct nextfield *new;
+ int nfields = 0;
+ int n;
+ struct dieinfo mbr;
+ char *nextdie;
+ int anonymous_size;
+
+ if ((type = lookup_utype (dip->die_ref)) == NULL)
+ {
+ /* No forward references created an empty type, so install one now */
+ type = alloc_utype (dip->die_ref, NULL);
+ }
+ INIT_CPLUS_SPECIFIC (type);
+ switch (dip->die_tag)
+ {
+ case TAG_class_type:
+ TYPE_CODE (type) = TYPE_CODE_CLASS;
+ break;
+ case TAG_structure_type:
+ TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ break;
+ case TAG_union_type:
+ TYPE_CODE (type) = TYPE_CODE_UNION;
+ break;
+ default:
+ /* Should never happen */
+ TYPE_CODE (type) = TYPE_CODE_UNDEF;
+ complain (&missing_tag, DIE_ID, DIE_NAME);
+ break;
+ }
+ /* Some compilers try to be helpful by inventing "fake" names for
+ anonymous enums, structures, and unions, like "~0fake" or ".0fake".
+ Thanks, but no thanks... */
+ if (dip->at_name != NULL
+ && *dip->at_name != '~'
+ && *dip->at_name != '.')
+ {
+ TYPE_TAG_NAME (type) = obconcat (&objfile->type_obstack,
+ "", "", dip->at_name);
+ }
+ /* Use whatever size is known. Zero is a valid size. We might however
+ wish to check has_at_byte_size to make sure that some byte size was
+ given explicitly, but DWARF doesn't specify that explicit sizes of
+ zero have to present, so complaining about missing sizes should
+ probably not be the default. */
+ TYPE_LENGTH (type) = dip->at_byte_size;
+ thisdie += dip->die_length;
+ while (thisdie < enddie)
+ {
+ basicdieinfo (&mbr, thisdie, objfile);
+ completedieinfo (&mbr, objfile);
+ if (mbr.die_length <= SIZEOF_DIE_LENGTH)
+ {
+ break;
+ }
+ else if (mbr.at_sibling != 0)
+ {
+ nextdie = dbbase + mbr.at_sibling - dbroff;
+ }
+ else
+ {
+ nextdie = thisdie + mbr.die_length;
+ }
+ switch (mbr.die_tag)
+ {
+ case TAG_member:
+ /* Get space to record the next field's data. */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+ /* Save the data. */
+ list->field.name =
+ obsavestring (mbr.at_name, strlen (mbr.at_name),
+ &objfile->type_obstack);
+ FIELD_TYPE (list->field) = decode_die_type (&mbr);
+ FIELD_BITPOS (list->field) = 8 * locval (&mbr);
+ /* Handle bit fields. */
+ FIELD_BITSIZE (list->field) = mbr.at_bit_size;
+ if (BITS_BIG_ENDIAN)
+ {
+ /* For big endian bits, the at_bit_offset gives the
+ additional bit offset from the MSB of the containing
+ anonymous object to the MSB of the field. We don't
+ have to do anything special since we don't need to
+ know the size of the anonymous object. */
+ FIELD_BITPOS (list->field) += mbr.at_bit_offset;
+ }
+ else
+ {
+ /* For little endian bits, we need to have a non-zero
+ at_bit_size, so that we know we are in fact dealing
+ with a bitfield. Compute the bit offset to the MSB
+ of the anonymous object, subtract off the number of
+ bits from the MSB of the field to the MSB of the
+ object, and then subtract off the number of bits of
+ the field itself. The result is the bit offset of
+ the LSB of the field. */
+ if (mbr.at_bit_size > 0)
+ {
+ if (mbr.has_at_byte_size)
+ {
+ /* The size of the anonymous object containing
+ the bit field is explicit, so use the
+ indicated size (in bytes). */
+ anonymous_size = mbr.at_byte_size;
+ }
+ else
+ {
+ /* The size of the anonymous object containing
+ the bit field matches the size of an object
+ of the bit field's type. DWARF allows
+ at_byte_size to be left out in such cases, as
+ a debug information size optimization. */
+ anonymous_size = TYPE_LENGTH (list->field.type);
+ }
+ FIELD_BITPOS (list->field) +=
+ anonymous_size * 8 - mbr.at_bit_offset - mbr.at_bit_size;
+ }
+ }
+ nfields++;
+ break;
+ default:
+ process_dies (thisdie, nextdie, objfile);
+ break;
+ }
+ thisdie = nextdie;
+ }
+ /* Now create the vector of fields, and record how big it is. We may
+ not even have any fields, if this DIE was generated due to a reference
+ to an anonymous structure or union. In this case, TYPE_FLAG_STUB is
+ set, which clues gdb in to the fact that it needs to search elsewhere
+ for the full structure definition. */
+ if (nfields == 0)
+ {
+ TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
+ }
+ else
+ {
+ TYPE_NFIELDS (type) = nfields;
+ TYPE_FIELDS (type) = (struct field *)
+ TYPE_ALLOC (type, sizeof (struct field) * nfields);
+ /* Copy the saved-up fields into the field vector. */
+ for (n = nfields; list; list = list->next)
+ {
+ TYPE_FIELD (type, --n) = list->field;
+ }
+ }
+ return (type);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ read_structure_scope -- process all dies within struct or union
+
+ SYNOPSIS
+
+ static void read_structure_scope (struct dieinfo *dip,
+ char *thisdie, char *enddie, struct objfile *objfile)
+
+ DESCRIPTION
+
+ Called when we find the DIE that starts a structure or union
+ scope (definition) to process all dies that define the members
+ of the structure or union. DIP is a pointer to the die info
+ struct for the DIE that names the structure or union.
+
+ NOTES
+
+ Note that we need to call struct_type regardless of whether or not
+ the DIE has an at_name attribute, since it might be an anonymous
+ structure or union. This gets the type entered into our set of
+ user defined types.
+
+ However, if the structure is incomplete (an opaque struct/union)
+ then suppress creating a symbol table entry for it since gdb only
+ wants to find the one with the complete definition. Note that if
+ it is complete, we just call new_symbol, which does it's own
+ checking about whether the struct/union is anonymous or not (and
+ suppresses creating a symbol table entry itself).
+
+ */
+
+static void
+read_structure_scope (struct dieinfo *dip, char *thisdie, char *enddie,
+ struct objfile *objfile)
+{
+ struct type *type;
+ struct symbol *sym;
+
+ type = struct_type (dip, thisdie, enddie, objfile);
+ if (!TYPE_STUB (type))
+ {
+ sym = new_symbol (dip, objfile);
+ if (sym != NULL)
+ {
+ SYMBOL_TYPE (sym) = type;
+ if (cu_language == language_cplus)
+ {
+ synthesize_typedef (dip, objfile, type);
+ }
+ }
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ decode_array_element_type -- decode type of the array elements
+
+ SYNOPSIS
+
+ static struct type *decode_array_element_type (char *scan, char *end)
+
+ DESCRIPTION
+
+ As the last step in decoding the array subscript information for an
+ array DIE, we need to decode the type of the array elements. We are
+ passed a pointer to this last part of the subscript information and
+ must return the appropriate type. If the type attribute is not
+ recognized, just warn about the problem and return type int.
+ */
+
+static struct type *
+decode_array_element_type (char *scan)
+{
+ struct type *typep;
+ DIE_REF die_ref;
+ unsigned short attribute;
+ unsigned short fundtype;
+ int nbytes;
+
+ attribute = target_to_host (scan, SIZEOF_ATTRIBUTE, GET_UNSIGNED,
+ current_objfile);
+ scan += SIZEOF_ATTRIBUTE;
+ if ((nbytes = attribute_size (attribute)) == -1)
+ {
+ complain (&bad_array_element_type, DIE_ID, DIE_NAME, attribute);
+ typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+ }
+ else
+ {
+ switch (attribute)
+ {
+ case AT_fund_type:
+ fundtype = target_to_host (scan, nbytes, GET_UNSIGNED,
+ current_objfile);
+ typep = decode_fund_type (fundtype);
+ break;
+ case AT_mod_fund_type:
+ typep = decode_mod_fund_type (scan);
+ break;
+ case AT_user_def_type:
+ die_ref = target_to_host (scan, nbytes, GET_UNSIGNED,
+ current_objfile);
+ if ((typep = lookup_utype (die_ref)) == NULL)
+ {
+ typep = alloc_utype (die_ref, NULL);
+ }
+ break;
+ case AT_mod_u_d_type:
+ typep = decode_mod_u_d_type (scan);
+ break;
+ default:
+ complain (&bad_array_element_type, DIE_ID, DIE_NAME, attribute);
+ typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+ break;
+ }
+ }
+ return (typep);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ decode_subscript_data_item -- decode array subscript item
+
+ SYNOPSIS
+
+ static struct type *
+ decode_subscript_data_item (char *scan, char *end)
+
+ DESCRIPTION
+
+ The array subscripts and the data type of the elements of an
+ array are described by a list of data items, stored as a block
+ of contiguous bytes. There is a data item describing each array
+ dimension, and a final data item describing the element type.
+ The data items are ordered the same as their appearance in the
+ source (I.E. leftmost dimension first, next to leftmost second,
+ etc).
+
+ The data items describing each array dimension consist of four
+ parts: (1) a format specifier, (2) type type of the subscript
+ index, (3) a description of the low bound of the array dimension,
+ and (4) a description of the high bound of the array dimension.
+
+ The last data item is the description of the type of each of
+ the array elements.
+
+ We are passed a pointer to the start of the block of bytes
+ containing the remaining data items, and a pointer to the first
+ byte past the data. This function recursively decodes the
+ remaining data items and returns a type.
+
+ If we somehow fail to decode some data, we complain about it
+ and return a type "array of int".
+
+ BUGS
+ FIXME: This code only implements the forms currently used
+ by the AT&T and GNU C compilers.
+
+ The end pointer is supplied for error checking, maybe we should
+ use it for that...
+ */
+
+static struct type *
+decode_subscript_data_item (char *scan, char *end)
+{
+ struct type *typep = NULL; /* Array type we are building */
+ struct type *nexttype; /* Type of each element (may be array) */
+ struct type *indextype; /* Type of this index */
+ struct type *rangetype;
+ unsigned int format;
+ unsigned short fundtype;
+ unsigned long lowbound;
+ unsigned long highbound;
+ int nbytes;
+
+ format = target_to_host (scan, SIZEOF_FORMAT_SPECIFIER, GET_UNSIGNED,
+ current_objfile);
+ scan += SIZEOF_FORMAT_SPECIFIER;
+ switch (format)
+ {
+ case FMT_ET:
+ typep = decode_array_element_type (scan);
+ break;
+ case FMT_FT_C_C:
+ fundtype = target_to_host (scan, SIZEOF_FMT_FT, GET_UNSIGNED,
+ current_objfile);
+ indextype = decode_fund_type (fundtype);
+ scan += SIZEOF_FMT_FT;
+ nbytes = TARGET_FT_LONG_SIZE (current_objfile);
+ lowbound = target_to_host (scan, nbytes, GET_UNSIGNED, current_objfile);
+ scan += nbytes;
+ highbound = target_to_host (scan, nbytes, GET_UNSIGNED, current_objfile);
+ scan += nbytes;
+ nexttype = decode_subscript_data_item (scan, end);
+ if (nexttype == NULL)
+ {
+ /* Munged subscript data or other problem, fake it. */
+ complain (&subscript_data_items, DIE_ID, DIE_NAME);
+ nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+ }
+ rangetype = create_range_type ((struct type *) NULL, indextype,
+ lowbound, highbound);
+ typep = create_array_type ((struct type *) NULL, nexttype, rangetype);
+ break;
+ case FMT_FT_C_X:
+ case FMT_FT_X_C:
+ case FMT_FT_X_X:
+ case FMT_UT_C_C:
+ case FMT_UT_C_X:
+ case FMT_UT_X_C:
+ case FMT_UT_X_X:
+ complain (&unhandled_array_subscript_format, DIE_ID, DIE_NAME, format);
+ nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+ rangetype = create_range_type ((struct type *) NULL, nexttype, 0, 0);
+ typep = create_array_type ((struct type *) NULL, nexttype, rangetype);
+ break;
+ default:
+ complain (&unknown_array_subscript_format, DIE_ID, DIE_NAME, format);
+ nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+ rangetype = create_range_type ((struct type *) NULL, nexttype, 0, 0);
+ typep = create_array_type ((struct type *) NULL, nexttype, rangetype);
+ break;
+ }
+ return (typep);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ dwarf_read_array_type -- read TAG_array_type DIE
+
+ SYNOPSIS
+
+ static void dwarf_read_array_type (struct dieinfo *dip)
+
+ DESCRIPTION
+
+ Extract all information from a TAG_array_type DIE and add to
+ the user defined type vector.
+ */
+
+static void
+dwarf_read_array_type (struct dieinfo *dip)
+{
+ struct type *type;
+ struct type *utype;
+ char *sub;
+ char *subend;
+ unsigned short blocksz;
+ int nbytes;
+
+ if (dip->at_ordering != ORD_row_major)
+ {
+ /* FIXME: Can gdb even handle column major arrays? */
+ complain (&not_row_major, DIE_ID, DIE_NAME);
+ }
+ if ((sub = dip->at_subscr_data) != NULL)
+ {
+ nbytes = attribute_size (AT_subscr_data);
+ blocksz = target_to_host (sub, nbytes, GET_UNSIGNED, current_objfile);
+ subend = sub + nbytes + blocksz;
+ sub += nbytes;
+ type = decode_subscript_data_item (sub, subend);
+ if ((utype = lookup_utype (dip->die_ref)) == NULL)
+ {
+ /* Install user defined type that has not been referenced yet. */
+ alloc_utype (dip->die_ref, type);
+ }
+ else if (TYPE_CODE (utype) == TYPE_CODE_UNDEF)
+ {
+ /* Ick! A forward ref has already generated a blank type in our
+ slot, and this type probably already has things pointing to it
+ (which is what caused it to be created in the first place).
+ If it's just a place holder we can plop our fully defined type
+ on top of it. We can't recover the space allocated for our
+ new type since it might be on an obstack, but we could reuse
+ it if we kept a list of them, but it might not be worth it
+ (FIXME). */
+ *utype = *type;
+ }
+ else
+ {
+ /* Double ick! Not only is a type already in our slot, but
+ someone has decorated it. Complain and leave it alone. */
+ complain (&dup_user_type_definition, DIE_ID, DIE_NAME);
+ }
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ read_tag_pointer_type -- read TAG_pointer_type DIE
+
+ SYNOPSIS
+
+ static void read_tag_pointer_type (struct dieinfo *dip)
+
+ DESCRIPTION
+
+ Extract all information from a TAG_pointer_type DIE and add to
+ the user defined type vector.
+ */
+
+static void
+read_tag_pointer_type (struct dieinfo *dip)
+{
+ struct type *type;
+ struct type *utype;
+
+ type = decode_die_type (dip);
+ if ((utype = lookup_utype (dip->die_ref)) == NULL)
+ {
+ utype = lookup_pointer_type (type);
+ alloc_utype (dip->die_ref, utype);
+ }
+ else
+ {
+ TYPE_TARGET_TYPE (utype) = type;
+ TYPE_POINTER_TYPE (type) = utype;
+
+ /* We assume the machine has only one representation for pointers! */
+ /* FIXME: Possably a poor assumption */
+ TYPE_LENGTH (utype) = TARGET_PTR_BIT / TARGET_CHAR_BIT;
+ TYPE_CODE (utype) = TYPE_CODE_PTR;
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ read_tag_string_type -- read TAG_string_type DIE
+
+ SYNOPSIS
+
+ static void read_tag_string_type (struct dieinfo *dip)
+
+ DESCRIPTION
+
+ Extract all information from a TAG_string_type DIE and add to
+ the user defined type vector. It isn't really a user defined
+ type, but it behaves like one, with other DIE's using an
+ AT_user_def_type attribute to reference it.
+ */
+
+static void
+read_tag_string_type (struct dieinfo *dip)
+{
+ struct type *utype;
+ struct type *indextype;
+ struct type *rangetype;
+ unsigned long lowbound = 0;
+ unsigned long highbound;
+
+ if (dip->has_at_byte_size)
+ {
+ /* A fixed bounds string */
+ highbound = dip->at_byte_size - 1;
+ }
+ else
+ {
+ /* A varying length string. Stub for now. (FIXME) */
+ highbound = 1;
+ }
+ indextype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+ rangetype = create_range_type ((struct type *) NULL, indextype, lowbound,
+ highbound);
+
+ utype = lookup_utype (dip->die_ref);
+ if (utype == NULL)
+ {
+ /* No type defined, go ahead and create a blank one to use. */
+ utype = alloc_utype (dip->die_ref, (struct type *) NULL);
+ }
+ else
+ {
+ /* Already a type in our slot due to a forward reference. Make sure it
+ is a blank one. If not, complain and leave it alone. */
+ if (TYPE_CODE (utype) != TYPE_CODE_UNDEF)
+ {
+ complain (&dup_user_type_definition, DIE_ID, DIE_NAME);
+ return;
+ }
+ }
+
+ /* Create the string type using the blank type we either found or created. */
+ utype = create_string_type (utype, rangetype);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ read_subroutine_type -- process TAG_subroutine_type dies
+
+ SYNOPSIS
+
+ static void read_subroutine_type (struct dieinfo *dip, char thisdie,
+ char *enddie)
+
+ DESCRIPTION
+
+ Handle DIES due to C code like:
+
+ struct foo {
+ int (*funcp)(int a, long l); (Generates TAG_subroutine_type DIE)
+ int b;
+ };
+
+ NOTES
+
+ The parameter DIES are currently ignored. See if gdb has a way to
+ include this info in it's type system, and decode them if so. Is
+ this what the type structure's "arg_types" field is for? (FIXME)
+ */
+
+static void
+read_subroutine_type (struct dieinfo *dip, char *thisdie, char *enddie)
+{
+ struct type *type; /* Type that this function returns */
+ struct type *ftype; /* Function that returns above type */
+
+ /* Decode the type that this subroutine returns */
+
+ type = decode_die_type (dip);
+
+ /* Check to see if we already have a partially constructed user
+ defined type for this DIE, from a forward reference. */
+
+ if ((ftype = lookup_utype (dip->die_ref)) == NULL)
+ {
+ /* This is the first reference to one of these types. Make
+ a new one and place it in the user defined types. */
+ ftype = lookup_function_type (type);
+ alloc_utype (dip->die_ref, ftype);
+ }
+ else if (TYPE_CODE (ftype) == TYPE_CODE_UNDEF)
+ {
+ /* We have an existing partially constructed type, so bash it
+ into the correct type. */
+ TYPE_TARGET_TYPE (ftype) = type;
+ TYPE_LENGTH (ftype) = 1;
+ TYPE_CODE (ftype) = TYPE_CODE_FUNC;
+ }
+ else
+ {
+ complain (&dup_user_type_definition, DIE_ID, DIE_NAME);
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ read_enumeration -- process dies which define an enumeration
+
+ SYNOPSIS
+
+ static void read_enumeration (struct dieinfo *dip, char *thisdie,
+ char *enddie, struct objfile *objfile)
+
+ DESCRIPTION
+
+ Given a pointer to a die which begins an enumeration, process all
+ the dies that define the members of the enumeration.
+
+ NOTES
+
+ Note that we need to call enum_type regardless of whether or not we
+ have a symbol, since we might have an enum without a tag name (thus
+ no symbol for the tagname).
+ */
+
+static void
+read_enumeration (struct dieinfo *dip, char *thisdie, char *enddie,
+ struct objfile *objfile)
+{
+ struct type *type;
+ struct symbol *sym;
+
+ type = enum_type (dip, objfile);
+ sym = new_symbol (dip, objfile);
+ if (sym != NULL)
+ {
+ SYMBOL_TYPE (sym) = type;
+ if (cu_language == language_cplus)
+ {
+ synthesize_typedef (dip, objfile, type);
+ }
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ enum_type -- decode and return a type for an enumeration
+
+ SYNOPSIS
+
+ static type *enum_type (struct dieinfo *dip, struct objfile *objfile)
+
+ DESCRIPTION
+
+ Given a pointer to a die information structure for the die which
+ starts an enumeration, process all the dies that define the members
+ of the enumeration and return a type pointer for the enumeration.
+
+ At the same time, for each member of the enumeration, create a
+ symbol for it with namespace VAR_NAMESPACE and class LOC_CONST,
+ and give it the type of the enumeration itself.
+
+ NOTES
+
+ Note that the DWARF specification explicitly mandates that enum
+ constants occur in reverse order from the source program order,
+ for "consistency" and because this ordering is easier for many
+ compilers to generate. (Draft 6, sec 3.8.5, Enumeration type
+ Entries). Because gdb wants to see the enum members in program
+ source order, we have to ensure that the order gets reversed while
+ we are processing them.
+ */
+
+static struct type *
+enum_type (struct dieinfo *dip, struct objfile *objfile)
+{
+ struct type *type;
+ struct nextfield
+ {
+ struct nextfield *next;
+ struct field field;
+ };
+ struct nextfield *list = NULL;
+ struct nextfield *new;
+ int nfields = 0;
+ int n;
+ char *scan;
+ char *listend;
+ unsigned short blocksz;
+ struct symbol *sym;
+ int nbytes;
+ int unsigned_enum = 1;
+
+ if ((type = lookup_utype (dip->die_ref)) == NULL)
+ {
+ /* No forward references created an empty type, so install one now */
+ type = alloc_utype (dip->die_ref, NULL);
+ }
+ TYPE_CODE (type) = TYPE_CODE_ENUM;
+ /* Some compilers try to be helpful by inventing "fake" names for
+ anonymous enums, structures, and unions, like "~0fake" or ".0fake".
+ Thanks, but no thanks... */
+ if (dip->at_name != NULL
+ && *dip->at_name != '~'
+ && *dip->at_name != '.')
+ {
+ TYPE_TAG_NAME (type) = obconcat (&objfile->type_obstack,
+ "", "", dip->at_name);
+ }
+ if (dip->at_byte_size != 0)
+ {
+ TYPE_LENGTH (type) = dip->at_byte_size;
+ }
+ if ((scan = dip->at_element_list) != NULL)
+ {
+ if (dip->short_element_list)
+ {
+ nbytes = attribute_size (AT_short_element_list);
+ }
+ else
+ {
+ nbytes = attribute_size (AT_element_list);
+ }
+ blocksz = target_to_host (scan, nbytes, GET_UNSIGNED, objfile);
+ listend = scan + nbytes + blocksz;
+ scan += nbytes;
+ while (scan < listend)
+ {
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+ FIELD_TYPE (list->field) = NULL;
+ FIELD_BITSIZE (list->field) = 0;
+ FIELD_BITPOS (list->field) =
+ target_to_host (scan, TARGET_FT_LONG_SIZE (objfile), GET_SIGNED,
+ objfile);
+ scan += TARGET_FT_LONG_SIZE (objfile);
+ list->field.name = obsavestring (scan, strlen (scan),
+ &objfile->type_obstack);
+ scan += strlen (scan) + 1;
+ nfields++;
+ /* Handcraft a new symbol for this enum member. */
+ sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = create_name (list->field.name,
+ &objfile->symbol_obstack);
+ SYMBOL_INIT_LANGUAGE_SPECIFIC (sym, cu_language);
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ SYMBOL_TYPE (sym) = type;
+ SYMBOL_VALUE (sym) = FIELD_BITPOS (list->field);
+ if (SYMBOL_VALUE (sym) < 0)
+ unsigned_enum = 0;
+ add_symbol_to_list (sym, list_in_scope);
+ }
+ /* Now create the vector of fields, and record how big it is. This is
+ where we reverse the order, by pulling the members off the list in
+ reverse order from how they were inserted. If we have no fields
+ (this is apparently possible in C++) then skip building a field
+ vector. */
+ if (nfields > 0)
+ {
+ if (unsigned_enum)
+ TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+ TYPE_NFIELDS (type) = nfields;
+ TYPE_FIELDS (type) = (struct field *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct field) * nfields);
+ /* Copy the saved-up fields into the field vector. */
+ for (n = 0; (n < nfields) && (list != NULL); list = list->next)
+ {
+ TYPE_FIELD (type, n++) = list->field;
+ }
+ }
+ }
+ return (type);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ read_func_scope -- process all dies within a function scope
+
+ DESCRIPTION
+
+ Process all dies within a given function scope. We are passed
+ a die information structure pointer DIP for the die which
+ starts the function scope, and pointers into the raw die data
+ that define the dies within the function scope.
+
+ For now, we ignore lexical block scopes within the function.
+ The problem is that AT&T cc does not define a DWARF lexical
+ block scope for the function itself, while gcc defines a
+ lexical block scope for the function. We need to think about
+ how to handle this difference, or if it is even a problem.
+ (FIXME)
+ */
+
+static void
+read_func_scope (struct dieinfo *dip, char *thisdie, char *enddie,
+ struct objfile *objfile)
+{
+ register struct context_stack *new;
+
+ /* AT_name is absent if the function is described with an
+ AT_abstract_origin tag.
+ Ignore the function description for now to avoid GDB core dumps.
+ FIXME: Add code to handle AT_abstract_origin tags properly. */
+ if (dip->at_name == NULL)
+ {
+ complain (&missing_at_name, DIE_ID);
+ return;
+ }
+
+ if (objfile->ei.entry_point >= dip->at_low_pc &&
+ objfile->ei.entry_point < dip->at_high_pc)
+ {
+ objfile->ei.entry_func_lowpc = dip->at_low_pc;
+ objfile->ei.entry_func_highpc = dip->at_high_pc;
+ }
+ new = push_context (0, dip->at_low_pc);
+ new->name = new_symbol (dip, objfile);
+ list_in_scope = &local_symbols;
+ process_dies (thisdie + dip->die_length, enddie, objfile);
+ new = pop_context ();
+ /* Make a block for the local symbols within. */
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ new->start_addr, dip->at_high_pc, objfile);
+ list_in_scope = &file_symbols;
+}
+
+
+/*
+
+ LOCAL FUNCTION
+
+ handle_producer -- process the AT_producer attribute
+
+ DESCRIPTION
+
+ Perform any operations that depend on finding a particular
+ AT_producer attribute.
+
+ */
+
+static void
+handle_producer (char *producer)
+{
+
+ /* If this compilation unit was compiled with g++ or gcc, then set the
+ processing_gcc_compilation flag. */
+
+ if (STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER)))
+ {
+ char version = producer[strlen (GCC_PRODUCER)];
+ processing_gcc_compilation = (version == '2' ? 2 : 1);
+ }
+ else
+ {
+ processing_gcc_compilation =
+ STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))
+ || STREQN (producer, CHILL_PRODUCER, strlen (CHILL_PRODUCER));
+ }
+
+ /* Select a demangling style if we can identify the producer and if
+ the current style is auto. We leave the current style alone if it
+ is not auto. We also leave the demangling style alone if we find a
+ gcc (cc1) producer, as opposed to a g++ (cc1plus) producer. */
+
+ if (AUTO_DEMANGLING)
+ {
+ if (STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER)))
+ {
+#if 0
+ /* For now, stay with AUTO_DEMANGLING for g++ output, as we don't
+ know whether it will use the old style or v3 mangling. */
+ set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+#endif
+ }
+ else if (STREQN (producer, LCC_PRODUCER, strlen (LCC_PRODUCER)))
+ {
+ set_demangling_style (LUCID_DEMANGLING_STYLE_STRING);
+ }
+ }
+}
+
+
+/*
+
+ LOCAL FUNCTION
+
+ read_file_scope -- process all dies within a file scope
+
+ DESCRIPTION
+
+ Process all dies within a given file scope. We are passed a
+ pointer to the die information structure for the die which
+ starts the file scope, and pointers into the raw die data which
+ mark the range of dies within the file scope.
+
+ When the partial symbol table is built, the file offset for the line
+ number table for each compilation unit is saved in the partial symbol
+ table entry for that compilation unit. As the symbols for each
+ compilation unit are read, the line number table is read into memory
+ and the variable lnbase is set to point to it. Thus all we have to
+ do is use lnbase to access the line number table for the current
+ compilation unit.
+ */
+
+static void
+read_file_scope (struct dieinfo *dip, char *thisdie, char *enddie,
+ struct objfile *objfile)
+{
+ struct cleanup *back_to;
+ struct symtab *symtab;
+
+ if (objfile->ei.entry_point >= dip->at_low_pc &&
+ objfile->ei.entry_point < dip->at_high_pc)
+ {
+ objfile->ei.entry_file_lowpc = dip->at_low_pc;
+ objfile->ei.entry_file_highpc = dip->at_high_pc;
+ }
+ set_cu_language (dip);
+ if (dip->at_producer != NULL)
+ {
+ handle_producer (dip->at_producer);
+ }
+ numutypes = (enddie - thisdie) / 4;
+ utypes = (struct type **) xmalloc (numutypes * sizeof (struct type *));
+ back_to = make_cleanup (free_utypes, NULL);
+ memset (utypes, 0, numutypes * sizeof (struct type *));
+ memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
+ start_symtab (dip->at_name, dip->at_comp_dir, dip->at_low_pc);
+ record_debugformat ("DWARF 1");
+ decode_line_numbers (lnbase);
+ process_dies (thisdie + dip->die_length, enddie, objfile);
+
+ symtab = end_symtab (dip->at_high_pc, objfile, 0);
+ if (symtab != NULL)
+ {
+ symtab->language = cu_language;
+ }
+ do_cleanups (back_to);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ process_dies -- process a range of DWARF Information Entries
+
+ SYNOPSIS
+
+ static void process_dies (char *thisdie, char *enddie,
+ struct objfile *objfile)
+
+ DESCRIPTION
+
+ Process all DIE's in a specified range. May be (and almost
+ certainly will be) called recursively.
+ */
+
+static void
+process_dies (char *thisdie, char *enddie, struct objfile *objfile)
+{
+ char *nextdie;
+ struct dieinfo di;
+
+ while (thisdie < enddie)
+ {
+ basicdieinfo (&di, thisdie, objfile);
+ if (di.die_length < SIZEOF_DIE_LENGTH)
+ {
+ break;
+ }
+ else if (di.die_tag == TAG_padding)
+ {
+ nextdie = thisdie + di.die_length;
+ }
+ else
+ {
+ completedieinfo (&di, objfile);
+ if (di.at_sibling != 0)
+ {
+ nextdie = dbbase + di.at_sibling - dbroff;
+ }
+ else
+ {
+ nextdie = thisdie + di.die_length;
+ }
+ /* I think that these are always text, not data, addresses. */
+ di.at_low_pc = SMASH_TEXT_ADDRESS (di.at_low_pc);
+ di.at_high_pc = SMASH_TEXT_ADDRESS (di.at_high_pc);
+ switch (di.die_tag)
+ {
+ case TAG_compile_unit:
+ /* Skip Tag_compile_unit if we are already inside a compilation
+ unit, we are unable to handle nested compilation units
+ properly (FIXME). */
+ if (current_subfile == NULL)
+ read_file_scope (&di, thisdie, nextdie, objfile);
+ else
+ nextdie = thisdie + di.die_length;
+ break;
+ case TAG_global_subroutine:
+ case TAG_subroutine:
+ if (di.has_at_low_pc)
+ {
+ read_func_scope (&di, thisdie, nextdie, objfile);
+ }
+ break;
+ case TAG_lexical_block:
+ read_lexical_block_scope (&di, thisdie, nextdie, objfile);
+ break;
+ case TAG_class_type:
+ case TAG_structure_type:
+ case TAG_union_type:
+ read_structure_scope (&di, thisdie, nextdie, objfile);
+ break;
+ case TAG_enumeration_type:
+ read_enumeration (&di, thisdie, nextdie, objfile);
+ break;
+ case TAG_subroutine_type:
+ read_subroutine_type (&di, thisdie, nextdie);
+ break;
+ case TAG_array_type:
+ dwarf_read_array_type (&di);
+ break;
+ case TAG_pointer_type:
+ read_tag_pointer_type (&di);
+ break;
+ case TAG_string_type:
+ read_tag_string_type (&di);
+ break;
+ default:
+ new_symbol (&di, objfile);
+ break;
+ }
+ }
+ thisdie = nextdie;
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ decode_line_numbers -- decode a line number table fragment
+
+ SYNOPSIS
+
+ static void decode_line_numbers (char *tblscan, char *tblend,
+ long length, long base, long line, long pc)
+
+ DESCRIPTION
+
+ Translate the DWARF line number information to gdb form.
+
+ The ".line" section contains one or more line number tables, one for
+ each ".line" section from the objects that were linked.
+
+ The AT_stmt_list attribute for each TAG_source_file entry in the
+ ".debug" section contains the offset into the ".line" section for the
+ start of the table for that file.
+
+ The table itself has the following structure:
+
+ <table length><base address><source statement entry>
+ 4 bytes 4 bytes 10 bytes
+
+ The table length is the total size of the table, including the 4 bytes
+ for the length information.
+
+ The base address is the address of the first instruction generated
+ for the source file.
+
+ Each source statement entry has the following structure:
+
+ <line number><statement position><address delta>
+ 4 bytes 2 bytes 4 bytes
+
+ The line number is relative to the start of the file, starting with
+ line 1.
+
+ The statement position either -1 (0xFFFF) or the number of characters
+ from the beginning of the line to the beginning of the statement.
+
+ The address delta is the difference between the base address and
+ the address of the first instruction for the statement.
+
+ Note that we must copy the bytes from the packed table to our local
+ variables before attempting to use them, to avoid alignment problems
+ on some machines, particularly RISC processors.
+
+ BUGS
+
+ Does gdb expect the line numbers to be sorted? They are now by
+ chance/luck, but are not required to be. (FIXME)
+
+ The line with number 0 is unused, gdb apparently can discover the
+ span of the last line some other way. How? (FIXME)
+ */
+
+static void
+decode_line_numbers (char *linetable)
+{
+ char *tblscan;
+ char *tblend;
+ unsigned long length;
+ unsigned long base;
+ unsigned long line;
+ unsigned long pc;
+
+ if (linetable != NULL)
+ {
+ tblscan = tblend = linetable;
+ length = target_to_host (tblscan, SIZEOF_LINETBL_LENGTH, GET_UNSIGNED,
+ current_objfile);
+ tblscan += SIZEOF_LINETBL_LENGTH;
+ tblend += length;
+ base = target_to_host (tblscan, TARGET_FT_POINTER_SIZE (objfile),
+ GET_UNSIGNED, current_objfile);
+ tblscan += TARGET_FT_POINTER_SIZE (objfile);
+ base += baseaddr;
+ while (tblscan < tblend)
+ {
+ line = target_to_host (tblscan, SIZEOF_LINETBL_LINENO, GET_UNSIGNED,
+ current_objfile);
+ tblscan += SIZEOF_LINETBL_LINENO + SIZEOF_LINETBL_STMT;
+ pc = target_to_host (tblscan, SIZEOF_LINETBL_DELTA, GET_UNSIGNED,
+ current_objfile);
+ tblscan += SIZEOF_LINETBL_DELTA;
+ pc += base;
+ if (line != 0)
+ {
+ record_line (current_subfile, line, pc);
+ }
+ }
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ locval -- compute the value of a location attribute
+
+ SYNOPSIS
+
+ static int locval (struct dieinfo *dip)
+
+ DESCRIPTION
+
+ Given pointer to a string of bytes that define a location, compute
+ the location and return the value.
+ A location description containing no atoms indicates that the
+ object is optimized out. The optimized_out flag is set for those,
+ the return value is meaningless.
+
+ When computing values involving the current value of the frame pointer,
+ the value zero is used, which results in a value relative to the frame
+ pointer, rather than the absolute value. This is what GDB wants
+ anyway.
+
+ When the result is a register number, the isreg flag is set, otherwise
+ it is cleared. This is a kludge until we figure out a better
+ way to handle the problem. Gdb's design does not mesh well with the
+ DWARF notion of a location computing interpreter, which is a shame
+ because the flexibility goes unused.
+
+ NOTES
+
+ Note that stack[0] is unused except as a default error return.
+ Note that stack overflow is not yet handled.
+ */
+
+static int
+locval (struct dieinfo *dip)
+{
+ unsigned short nbytes;
+ unsigned short locsize;
+ auto long stack[64];
+ int stacki;
+ char *loc;
+ char *end;
+ int loc_atom_code;
+ int loc_value_size;
+
+ loc = dip->at_location;
+ nbytes = attribute_size (AT_location);
+ locsize = target_to_host (loc, nbytes, GET_UNSIGNED, current_objfile);
+ loc += nbytes;
+ end = loc + locsize;
+ stacki = 0;
+ stack[stacki] = 0;
+ dip->isreg = 0;
+ dip->offreg = 0;
+ dip->optimized_out = 1;
+ loc_value_size = TARGET_FT_LONG_SIZE (current_objfile);
+ while (loc < end)
+ {
+ dip->optimized_out = 0;
+ loc_atom_code = target_to_host (loc, SIZEOF_LOC_ATOM_CODE, GET_UNSIGNED,
+ current_objfile);
+ loc += SIZEOF_LOC_ATOM_CODE;
+ switch (loc_atom_code)
+ {
+ case 0:
+ /* error */
+ loc = end;
+ break;
+ case OP_REG:
+ /* push register (number) */
+ stack[++stacki]
+ = DWARF_REG_TO_REGNUM (target_to_host (loc, loc_value_size,
+ GET_UNSIGNED,
+ current_objfile));
+ loc += loc_value_size;
+ dip->isreg = 1;
+ break;
+ case OP_BASEREG:
+ /* push value of register (number) */
+ /* Actually, we compute the value as if register has 0, so the
+ value ends up being the offset from that register. */
+ dip->offreg = 1;
+ dip->basereg = target_to_host (loc, loc_value_size, GET_UNSIGNED,
+ current_objfile);
+ loc += loc_value_size;
+ stack[++stacki] = 0;
+ break;
+ case OP_ADDR:
+ /* push address (relocated address) */
+ stack[++stacki] = target_to_host (loc, loc_value_size,
+ GET_UNSIGNED, current_objfile);
+ loc += loc_value_size;
+ break;
+ case OP_CONST:
+ /* push constant (number) FIXME: signed or unsigned! */
+ stack[++stacki] = target_to_host (loc, loc_value_size,
+ GET_SIGNED, current_objfile);
+ loc += loc_value_size;
+ break;
+ case OP_DEREF2:
+ /* pop, deref and push 2 bytes (as a long) */
+ complain (&op_deref2, DIE_ID, DIE_NAME, stack[stacki]);
+ break;
+ case OP_DEREF4: /* pop, deref and push 4 bytes (as a long) */
+ complain (&op_deref4, DIE_ID, DIE_NAME, stack[stacki]);
+ break;
+ case OP_ADD: /* pop top 2 items, add, push result */
+ stack[stacki - 1] += stack[stacki];
+ stacki--;
+ break;
+ }
+ }
+ return (stack[stacki]);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ read_ofile_symtab -- build a full symtab entry from chunk of DIE's
+
+ SYNOPSIS
+
+ static void read_ofile_symtab (struct partial_symtab *pst)
+
+ DESCRIPTION
+
+ When expanding a partial symbol table entry to a full symbol table
+ entry, this is the function that gets called to read in the symbols
+ for the compilation unit. A pointer to the newly constructed symtab,
+ which is now the new first one on the objfile's symtab list, is
+ stashed in the partial symbol table entry.
+ */
+
+static void
+read_ofile_symtab (struct partial_symtab *pst)
+{
+ struct cleanup *back_to;
+ unsigned long lnsize;
+ file_ptr foffset;
+ bfd *abfd;
+ char lnsizedata[SIZEOF_LINETBL_LENGTH];
+
+ abfd = pst->objfile->obfd;
+ current_objfile = pst->objfile;
+
+ /* Allocate a buffer for the entire chunk of DIE's for this compilation
+ unit, seek to the location in the file, and read in all the DIE's. */
+
+ diecount = 0;
+ dbsize = DBLENGTH (pst);
+ dbbase = xmalloc (dbsize);
+ dbroff = DBROFF (pst);
+ foffset = DBFOFF (pst) + dbroff;
+ base_section_offsets = pst->section_offsets;
+ baseaddr = ANOFFSET (pst->section_offsets, 0);
+ if (bfd_seek (abfd, foffset, SEEK_SET) ||
+ (bfd_bread (dbbase, dbsize, abfd) != dbsize))
+ {
+ xfree (dbbase);
+ error ("can't read DWARF data");
+ }
+ back_to = make_cleanup (xfree, dbbase);
+
+ /* If there is a line number table associated with this compilation unit
+ then read the size of this fragment in bytes, from the fragment itself.
+ Allocate a buffer for the fragment and read it in for future
+ processing. */
+
+ lnbase = NULL;
+ if (LNFOFF (pst))
+ {
+ if (bfd_seek (abfd, LNFOFF (pst), SEEK_SET) ||
+ (bfd_bread ((PTR) lnsizedata, sizeof (lnsizedata), abfd)
+ != sizeof (lnsizedata)))
+ {
+ error ("can't read DWARF line number table size");
+ }
+ lnsize = target_to_host (lnsizedata, SIZEOF_LINETBL_LENGTH,
+ GET_UNSIGNED, pst->objfile);
+ lnbase = xmalloc (lnsize);
+ if (bfd_seek (abfd, LNFOFF (pst), SEEK_SET) ||
+ (bfd_bread (lnbase, lnsize, abfd) != lnsize))
+ {
+ xfree (lnbase);
+ error ("can't read DWARF line numbers");
+ }
+ make_cleanup (xfree, lnbase);
+ }
+
+ process_dies (dbbase, dbbase + dbsize, pst->objfile);
+ do_cleanups (back_to);
+ current_objfile = NULL;
+ pst->symtab = pst->objfile->symtabs;
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ psymtab_to_symtab_1 -- do grunt work for building a full symtab entry
+
+ SYNOPSIS
+
+ static void psymtab_to_symtab_1 (struct partial_symtab *pst)
+
+ DESCRIPTION
+
+ Called once for each partial symbol table entry that needs to be
+ expanded into a full symbol table entry.
+
+ */
+
+static void
+psymtab_to_symtab_1 (struct partial_symtab *pst)
+{
+ int i;
+ struct cleanup *old_chain;
+
+ if (pst != NULL)
+ {
+ if (pst->readin)
+ {
+ warning ("psymtab for %s already read in. Shouldn't happen.",
+ pst->filename);
+ }
+ else
+ {
+ /* Read in all partial symtabs on which this one is dependent */
+ for (i = 0; i < pst->number_of_dependencies; i++)
+ {
+ if (!pst->dependencies[i]->readin)
+ {
+ /* Inform about additional files that need to be read in. */
+ if (info_verbose)
+ {
+ fputs_filtered (" ", gdb_stdout);
+ wrap_here ("");
+ fputs_filtered ("and ", gdb_stdout);
+ wrap_here ("");
+ printf_filtered ("%s...",
+ pst->dependencies[i]->filename);
+ wrap_here ("");
+ gdb_flush (gdb_stdout); /* Flush output */
+ }
+ psymtab_to_symtab_1 (pst->dependencies[i]);
+ }
+ }
+ if (DBLENGTH (pst)) /* Otherwise it's a dummy */
+ {
+ buildsym_init ();
+ old_chain = make_cleanup (really_free_pendings, 0);
+ read_ofile_symtab (pst);
+ if (info_verbose)
+ {
+ printf_filtered ("%d DIE's, sorting...", diecount);
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+ }
+ sort_symtab_syms (pst->symtab);
+ do_cleanups (old_chain);
+ }
+ pst->readin = 1;
+ }
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ dwarf_psymtab_to_symtab -- build a full symtab entry from partial one
+
+ SYNOPSIS
+
+ static void dwarf_psymtab_to_symtab (struct partial_symtab *pst)
+
+ DESCRIPTION
+
+ This is the DWARF support entry point for building a full symbol
+ table entry from a partial symbol table entry. We are passed a
+ pointer to the partial symbol table entry that needs to be expanded.
+
+ */
+
+static void
+dwarf_psymtab_to_symtab (struct partial_symtab *pst)
+{
+
+ if (pst != NULL)
+ {
+ if (pst->readin)
+ {
+ warning ("psymtab for %s already read in. Shouldn't happen.",
+ pst->filename);
+ }
+ else
+ {
+ if (DBLENGTH (pst) || pst->number_of_dependencies)
+ {
+ /* Print the message now, before starting serious work, to avoid
+ disconcerting pauses. */
+ if (info_verbose)
+ {
+ printf_filtered ("Reading in symbols for %s...",
+ pst->filename);
+ gdb_flush (gdb_stdout);
+ }
+
+ psymtab_to_symtab_1 (pst);
+
+#if 0 /* FIXME: Check to see what dbxread is doing here and see if
+ we need to do an equivalent or is this something peculiar to
+ stabs/a.out format.
+ Match with global symbols. This only needs to be done once,
+ after all of the symtabs and dependencies have been read in.
+ */
+ scan_file_globals (pst->objfile);
+#endif
+
+ /* Finish up the verbose info message. */
+ if (info_verbose)
+ {
+ printf_filtered ("done.\n");
+ gdb_flush (gdb_stdout);
+ }
+ }
+ }
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ add_enum_psymbol -- add enumeration members to partial symbol table
+
+ DESCRIPTION
+
+ Given pointer to a DIE that is known to be for an enumeration,
+ extract the symbolic names of the enumeration members and add
+ partial symbols for them.
+ */
+
+static void
+add_enum_psymbol (struct dieinfo *dip, struct objfile *objfile)
+{
+ char *scan;
+ char *listend;
+ unsigned short blocksz;
+ int nbytes;
+
+ if ((scan = dip->at_element_list) != NULL)
+ {
+ if (dip->short_element_list)
+ {
+ nbytes = attribute_size (AT_short_element_list);
+ }
+ else
+ {
+ nbytes = attribute_size (AT_element_list);
+ }
+ blocksz = target_to_host (scan, nbytes, GET_UNSIGNED, objfile);
+ scan += nbytes;
+ listend = scan + blocksz;
+ while (scan < listend)
+ {
+ scan += TARGET_FT_LONG_SIZE (objfile);
+ add_psymbol_to_list (scan, strlen (scan), VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols, 0, 0, cu_language,
+ objfile);
+ scan += strlen (scan) + 1;
+ }
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ add_partial_symbol -- add symbol to partial symbol table
+
+ DESCRIPTION
+
+ Given a DIE, if it is one of the types that we want to
+ add to a partial symbol table, finish filling in the die info
+ and then add a partial symbol table entry for it.
+
+ NOTES
+
+ The caller must ensure that the DIE has a valid name attribute.
+ */
+
+static void
+add_partial_symbol (struct dieinfo *dip, struct objfile *objfile)
+{
+ switch (dip->die_tag)
+ {
+ case TAG_global_subroutine:
+ add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->global_psymbols,
+ 0, dip->at_low_pc, cu_language, objfile);
+ break;
+ case TAG_global_variable:
+ add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->global_psymbols,
+ 0, 0, cu_language, objfile);
+ break;
+ case TAG_subroutine:
+ add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->static_psymbols,
+ 0, dip->at_low_pc, cu_language, objfile);
+ break;
+ case TAG_local_variable:
+ add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->static_psymbols,
+ 0, 0, cu_language, objfile);
+ break;
+ case TAG_typedef:
+ add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ 0, 0, cu_language, objfile);
+ break;
+ case TAG_class_type:
+ case TAG_structure_type:
+ case TAG_union_type:
+ case TAG_enumeration_type:
+ /* Do not add opaque aggregate definitions to the psymtab. */
+ if (!dip->has_at_byte_size)
+ break;
+ add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
+ STRUCT_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ 0, 0, cu_language, objfile);
+ if (cu_language == language_cplus)
+ {
+ /* For C++, these implicitly act as typedefs as well. */
+ add_psymbol_to_list (dip->at_name, strlen (dip->at_name),
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ 0, 0, cu_language, objfile);
+ }
+ break;
+ }
+}
+/* *INDENT-OFF* */
+/*
+
+LOCAL FUNCTION
+
+ scan_partial_symbols -- scan DIE's within a single compilation unit
+
+DESCRIPTION
+
+ Process the DIE's within a single compilation unit, looking for
+ interesting DIE's that contribute to the partial symbol table entry
+ for this compilation unit.
+
+NOTES
+
+ There are some DIE's that may appear both at file scope and within
+ the scope of a function. We are only interested in the ones at file
+ scope, and the only way to tell them apart is to keep track of the
+ scope. For example, consider the test case:
+
+ static int i;
+ main () { int j; }
+
+ for which the relevant DWARF segment has the structure:
+
+ 0x51:
+ 0x23 global subrtn sibling 0x9b
+ name main
+ fund_type FT_integer
+ low_pc 0x800004cc
+ high_pc 0x800004d4
+
+ 0x74:
+ 0x23 local var sibling 0x97
+ name j
+ fund_type FT_integer
+ location OP_BASEREG 0xe
+ OP_CONST 0xfffffffc
+ OP_ADD
+ 0x97:
+ 0x4
+
+ 0x9b:
+ 0x1d local var sibling 0xb8
+ name i
+ fund_type FT_integer
+ location OP_ADDR 0x800025dc
+
+ 0xb8:
+ 0x4
+
+ We want to include the symbol 'i' in the partial symbol table, but
+ not the symbol 'j'. In essence, we want to skip all the dies within
+ the scope of a TAG_global_subroutine DIE.
+
+ Don't attempt to add anonymous structures or unions since they have
+ no name. Anonymous enumerations however are processed, because we
+ want to extract their member names (the check for a tag name is
+ done later).
+
+ Also, for variables and subroutines, check that this is the place
+ where the actual definition occurs, rather than just a reference
+ to an external.
+ */
+/* *INDENT-ON* */
+
+
+
+static void
+scan_partial_symbols (char *thisdie, char *enddie, struct objfile *objfile)
+{
+ char *nextdie;
+ char *temp;
+ struct dieinfo di;
+
+ while (thisdie < enddie)
+ {
+ basicdieinfo (&di, thisdie, objfile);
+ if (di.die_length < SIZEOF_DIE_LENGTH)
+ {
+ break;
+ }
+ else
+ {
+ nextdie = thisdie + di.die_length;
+ /* To avoid getting complete die information for every die, we
+ only do it (below) for the cases we are interested in. */
+ switch (di.die_tag)
+ {
+ case TAG_global_subroutine:
+ case TAG_subroutine:
+ completedieinfo (&di, objfile);
+ if (di.at_name && (di.has_at_low_pc || di.at_location))
+ {
+ add_partial_symbol (&di, objfile);
+ /* If there is a sibling attribute, adjust the nextdie
+ pointer to skip the entire scope of the subroutine.
+ Apply some sanity checking to make sure we don't
+ overrun or underrun the range of remaining DIE's */
+ if (di.at_sibling != 0)
+ {
+ temp = dbbase + di.at_sibling - dbroff;
+ if ((temp < thisdie) || (temp >= enddie))
+ {
+ complain (&bad_die_ref, DIE_ID, DIE_NAME,
+ di.at_sibling);
+ }
+ else
+ {
+ nextdie = temp;
+ }
+ }
+ }
+ break;
+ case TAG_global_variable:
+ case TAG_local_variable:
+ completedieinfo (&di, objfile);
+ if (di.at_name && (di.has_at_low_pc || di.at_location))
+ {
+ add_partial_symbol (&di, objfile);
+ }
+ break;
+ case TAG_typedef:
+ case TAG_class_type:
+ case TAG_structure_type:
+ case TAG_union_type:
+ completedieinfo (&di, objfile);
+ if (di.at_name)
+ {
+ add_partial_symbol (&di, objfile);
+ }
+ break;
+ case TAG_enumeration_type:
+ completedieinfo (&di, objfile);
+ if (di.at_name)
+ {
+ add_partial_symbol (&di, objfile);
+ }
+ add_enum_psymbol (&di, objfile);
+ break;
+ }
+ }
+ thisdie = nextdie;
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ scan_compilation_units -- build a psymtab entry for each compilation
+
+ DESCRIPTION
+
+ This is the top level dwarf parsing routine for building partial
+ symbol tables.
+
+ It scans from the beginning of the DWARF table looking for the first
+ TAG_compile_unit DIE, and then follows the sibling chain to locate
+ each additional TAG_compile_unit DIE.
+
+ For each TAG_compile_unit DIE it creates a partial symtab structure,
+ calls a subordinate routine to collect all the compilation unit's
+ global DIE's, file scope DIEs, typedef DIEs, etc, and then links the
+ new partial symtab structure into the partial symbol table. It also
+ records the appropriate information in the partial symbol table entry
+ to allow the chunk of DIE's and line number table for this compilation
+ unit to be located and re-read later, to generate a complete symbol
+ table entry for the compilation unit.
+
+ Thus it effectively partitions up a chunk of DIE's for multiple
+ compilation units into smaller DIE chunks and line number tables,
+ and associates them with a partial symbol table entry.
+
+ NOTES
+
+ If any compilation unit has no line number table associated with
+ it for some reason (a missing at_stmt_list attribute, rather than
+ just one with a value of zero, which is valid) then we ensure that
+ the recorded file offset is zero so that the routine which later
+ reads line number table fragments knows that there is no fragment
+ to read.
+
+ RETURNS
+
+ Returns no value.
+
+ */
+
+static void
+scan_compilation_units (char *thisdie, char *enddie, file_ptr dbfoff,
+ file_ptr lnoffset, struct objfile *objfile)
+{
+ char *nextdie;
+ struct dieinfo di;
+ struct partial_symtab *pst;
+ int culength;
+ int curoff;
+ file_ptr curlnoffset;
+
+ while (thisdie < enddie)
+ {
+ basicdieinfo (&di, thisdie, objfile);
+ if (di.die_length < SIZEOF_DIE_LENGTH)
+ {
+ break;
+ }
+ else if (di.die_tag != TAG_compile_unit)
+ {
+ nextdie = thisdie + di.die_length;
+ }
+ else
+ {
+ completedieinfo (&di, objfile);
+ set_cu_language (&di);
+ if (di.at_sibling != 0)
+ {
+ nextdie = dbbase + di.at_sibling - dbroff;
+ }
+ else
+ {
+ nextdie = thisdie + di.die_length;
+ }
+ curoff = thisdie - dbbase;
+ culength = nextdie - thisdie;
+ curlnoffset = di.has_at_stmt_list ? lnoffset + di.at_stmt_list : 0;
+
+ /* First allocate a new partial symbol table structure */
+
+ pst = start_psymtab_common (objfile, base_section_offsets,
+ di.at_name, di.at_low_pc,
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+
+ pst->texthigh = di.at_high_pc;
+ pst->read_symtab_private = (char *)
+ obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct dwfinfo));
+ DBFOFF (pst) = dbfoff;
+ DBROFF (pst) = curoff;
+ DBLENGTH (pst) = culength;
+ LNFOFF (pst) = curlnoffset;
+ pst->read_symtab = dwarf_psymtab_to_symtab;
+
+ /* Now look for partial symbols */
+
+ scan_partial_symbols (thisdie + di.die_length, nextdie, objfile);
+
+ pst->n_global_syms = objfile->global_psymbols.next -
+ (objfile->global_psymbols.list + pst->globals_offset);
+ pst->n_static_syms = objfile->static_psymbols.next -
+ (objfile->static_psymbols.list + pst->statics_offset);
+ sort_pst_symbols (pst);
+ /* If there is already a psymtab or symtab for a file of this name,
+ remove it. (If there is a symtab, more drastic things also
+ happen.) This happens in VxWorks. */
+ free_named_symtabs (pst->filename);
+ }
+ thisdie = nextdie;
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ new_symbol -- make a symbol table entry for a new symbol
+
+ SYNOPSIS
+
+ static struct symbol *new_symbol (struct dieinfo *dip,
+ struct objfile *objfile)
+
+ DESCRIPTION
+
+ Given a pointer to a DWARF information entry, figure out if we need
+ to make a symbol table entry for it, and if so, create a new entry
+ and return a pointer to it.
+ */
+
+static struct symbol *
+new_symbol (struct dieinfo *dip, struct objfile *objfile)
+{
+ struct symbol *sym = NULL;
+
+ if (dip->at_name != NULL)
+ {
+ sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ OBJSTAT (objfile, n_syms++);
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = create_name (dip->at_name,
+ &objfile->symbol_obstack);
+ /* default assumptions */
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ SYMBOL_TYPE (sym) = decode_die_type (dip);
+
+ /* If this symbol is from a C++ compilation, then attempt to cache the
+ demangled form for future reference. This is a typical time versus
+ space tradeoff, that was decided in favor of time because it sped up
+ C++ symbol lookups by a factor of about 20. */
+
+ SYMBOL_LANGUAGE (sym) = cu_language;
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+ switch (dip->die_tag)
+ {
+ case TAG_label:
+ SYMBOL_VALUE_ADDRESS (sym) = dip->at_low_pc;
+ SYMBOL_CLASS (sym) = LOC_LABEL;
+ break;
+ case TAG_global_subroutine:
+ case TAG_subroutine:
+ SYMBOL_VALUE_ADDRESS (sym) = dip->at_low_pc;
+ SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));
+ if (dip->at_prototyped)
+ TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED;
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+ if (dip->die_tag == TAG_global_subroutine)
+ {
+ add_symbol_to_list (sym, &global_symbols);
+ }
+ else
+ {
+ add_symbol_to_list (sym, list_in_scope);
+ }
+ break;
+ case TAG_global_variable:
+ if (dip->at_location != NULL)
+ {
+ SYMBOL_VALUE_ADDRESS (sym) = locval (dip);
+ add_symbol_to_list (sym, &global_symbols);
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ SYMBOL_VALUE (sym) += baseaddr;
+ }
+ break;
+ case TAG_local_variable:
+ if (dip->at_location != NULL)
+ {
+ int loc = locval (dip);
+ if (dip->optimized_out)
+ {
+ SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+ }
+ else if (dip->isreg)
+ {
+ SYMBOL_CLASS (sym) = LOC_REGISTER;
+ }
+ else if (dip->offreg)
+ {
+ SYMBOL_CLASS (sym) = LOC_BASEREG;
+ SYMBOL_BASEREG (sym) = dip->basereg;
+ }
+ else
+ {
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ SYMBOL_VALUE (sym) += baseaddr;
+ }
+ if (SYMBOL_CLASS (sym) == LOC_STATIC)
+ {
+ /* LOC_STATIC address class MUST use SYMBOL_VALUE_ADDRESS,
+ which may store to a bigger location than SYMBOL_VALUE. */
+ SYMBOL_VALUE_ADDRESS (sym) = loc;
+ }
+ else
+ {
+ SYMBOL_VALUE (sym) = loc;
+ }
+ add_symbol_to_list (sym, list_in_scope);
+ }
+ break;
+ case TAG_formal_parameter:
+ if (dip->at_location != NULL)
+ {
+ SYMBOL_VALUE (sym) = locval (dip);
+ }
+ add_symbol_to_list (sym, list_in_scope);
+ if (dip->isreg)
+ {
+ SYMBOL_CLASS (sym) = LOC_REGPARM;
+ }
+ else if (dip->offreg)
+ {
+ SYMBOL_CLASS (sym) = LOC_BASEREG_ARG;
+ SYMBOL_BASEREG (sym) = dip->basereg;
+ }
+ else
+ {
+ SYMBOL_CLASS (sym) = LOC_ARG;
+ }
+ break;
+ case TAG_unspecified_parameters:
+ /* From varargs functions; gdb doesn't seem to have any interest in
+ this information, so just ignore it for now. (FIXME?) */
+ break;
+ case TAG_class_type:
+ case TAG_structure_type:
+ case TAG_union_type:
+ case TAG_enumeration_type:
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+ add_symbol_to_list (sym, list_in_scope);
+ break;
+ case TAG_typedef:
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, list_in_scope);
+ break;
+ default:
+ /* Not a tag we recognize. Hopefully we aren't processing trash
+ data, but since we must specifically ignore things we don't
+ recognize, there is nothing else we should do at this point. */
+ break;
+ }
+ }
+ return (sym);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ synthesize_typedef -- make a symbol table entry for a "fake" typedef
+
+ SYNOPSIS
+
+ static void synthesize_typedef (struct dieinfo *dip,
+ struct objfile *objfile,
+ struct type *type);
+
+ DESCRIPTION
+
+ Given a pointer to a DWARF information entry, synthesize a typedef
+ for the name in the DIE, using the specified type.
+
+ This is used for C++ class, structs, unions, and enumerations to
+ set up the tag name as a type.
+
+ */
+
+static void
+synthesize_typedef (struct dieinfo *dip, struct objfile *objfile,
+ struct type *type)
+{
+ struct symbol *sym = NULL;
+
+ if (dip->at_name != NULL)
+ {
+ sym = (struct symbol *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
+ OBJSTAT (objfile, n_syms++);
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = create_name (dip->at_name,
+ &objfile->symbol_obstack);
+ SYMBOL_INIT_LANGUAGE_SPECIFIC (sym, cu_language);
+ SYMBOL_TYPE (sym) = type;
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, list_in_scope);
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ decode_mod_fund_type -- decode a modified fundamental type
+
+ SYNOPSIS
+
+ static struct type *decode_mod_fund_type (char *typedata)
+
+ DESCRIPTION
+
+ Decode a block of data containing a modified fundamental
+ type specification. TYPEDATA is a pointer to the block,
+ which starts with a length containing the size of the rest
+ of the block. At the end of the block is a fundmental type
+ code value that gives the fundamental type. Everything
+ in between are type modifiers.
+
+ We simply compute the number of modifiers and call the general
+ function decode_modified_type to do the actual work.
+ */
+
+static struct type *
+decode_mod_fund_type (char *typedata)
+{
+ struct type *typep = NULL;
+ unsigned short modcount;
+ int nbytes;
+
+ /* Get the total size of the block, exclusive of the size itself */
+
+ nbytes = attribute_size (AT_mod_fund_type);
+ modcount = target_to_host (typedata, nbytes, GET_UNSIGNED, current_objfile);
+ typedata += nbytes;
+
+ /* Deduct the size of the fundamental type bytes at the end of the block. */
+
+ modcount -= attribute_size (AT_fund_type);
+
+ /* Now do the actual decoding */
+
+ typep = decode_modified_type (typedata, modcount, AT_mod_fund_type);
+ return (typep);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ decode_mod_u_d_type -- decode a modified user defined type
+
+ SYNOPSIS
+
+ static struct type *decode_mod_u_d_type (char *typedata)
+
+ DESCRIPTION
+
+ Decode a block of data containing a modified user defined
+ type specification. TYPEDATA is a pointer to the block,
+ which consists of a two byte length, containing the size
+ of the rest of the block. At the end of the block is a
+ four byte value that gives a reference to a user defined type.
+ Everything in between are type modifiers.
+
+ We simply compute the number of modifiers and call the general
+ function decode_modified_type to do the actual work.
+ */
+
+static struct type *
+decode_mod_u_d_type (char *typedata)
+{
+ struct type *typep = NULL;
+ unsigned short modcount;
+ int nbytes;
+
+ /* Get the total size of the block, exclusive of the size itself */
+
+ nbytes = attribute_size (AT_mod_u_d_type);
+ modcount = target_to_host (typedata, nbytes, GET_UNSIGNED, current_objfile);
+ typedata += nbytes;
+
+ /* Deduct the size of the reference type bytes at the end of the block. */
+
+ modcount -= attribute_size (AT_user_def_type);
+
+ /* Now do the actual decoding */
+
+ typep = decode_modified_type (typedata, modcount, AT_mod_u_d_type);
+ return (typep);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ decode_modified_type -- decode modified user or fundamental type
+
+ SYNOPSIS
+
+ static struct type *decode_modified_type (char *modifiers,
+ unsigned short modcount, int mtype)
+
+ DESCRIPTION
+
+ Decode a modified type, either a modified fundamental type or
+ a modified user defined type. MODIFIERS is a pointer to the
+ block of bytes that define MODCOUNT modifiers. Immediately
+ following the last modifier is a short containing the fundamental
+ type or a long containing the reference to the user defined
+ type. Which one is determined by MTYPE, which is either
+ AT_mod_fund_type or AT_mod_u_d_type to indicate what modified
+ type we are generating.
+
+ We call ourself recursively to generate each modified type,`
+ until MODCOUNT reaches zero, at which point we have consumed
+ all the modifiers and generate either the fundamental type or
+ user defined type. When the recursion unwinds, each modifier
+ is applied in turn to generate the full modified type.
+
+ NOTES
+
+ If we find a modifier that we don't recognize, and it is not one
+ of those reserved for application specific use, then we issue a
+ warning and simply ignore the modifier.
+
+ BUGS
+
+ We currently ignore MOD_const and MOD_volatile. (FIXME)
+
+ */
+
+static struct type *
+decode_modified_type (char *modifiers, unsigned int modcount, int mtype)
+{
+ struct type *typep = NULL;
+ unsigned short fundtype;
+ DIE_REF die_ref;
+ char modifier;
+ int nbytes;
+
+ if (modcount == 0)
+ {
+ switch (mtype)
+ {
+ case AT_mod_fund_type:
+ nbytes = attribute_size (AT_fund_type);
+ fundtype = target_to_host (modifiers, nbytes, GET_UNSIGNED,
+ current_objfile);
+ typep = decode_fund_type (fundtype);
+ break;
+ case AT_mod_u_d_type:
+ nbytes = attribute_size (AT_user_def_type);
+ die_ref = target_to_host (modifiers, nbytes, GET_UNSIGNED,
+ current_objfile);
+ if ((typep = lookup_utype (die_ref)) == NULL)
+ {
+ typep = alloc_utype (die_ref, NULL);
+ }
+ break;
+ default:
+ complain (&botched_modified_type, DIE_ID, DIE_NAME, mtype);
+ typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+ break;
+ }
+ }
+ else
+ {
+ modifier = *modifiers++;
+ typep = decode_modified_type (modifiers, --modcount, mtype);
+ switch (modifier)
+ {
+ case MOD_pointer_to:
+ typep = lookup_pointer_type (typep);
+ break;
+ case MOD_reference_to:
+ typep = lookup_reference_type (typep);
+ break;
+ case MOD_const:
+ complain (&const_ignored, DIE_ID, DIE_NAME); /* FIXME */
+ break;
+ case MOD_volatile:
+ complain (&volatile_ignored, DIE_ID, DIE_NAME); /* FIXME */
+ break;
+ default:
+ if (!(MOD_lo_user <= (unsigned char) modifier
+ && (unsigned char) modifier <= MOD_hi_user))
+ {
+ complain (&unknown_type_modifier, DIE_ID, DIE_NAME, modifier);
+ }
+ break;
+ }
+ }
+ return (typep);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ decode_fund_type -- translate basic DWARF type to gdb base type
+
+ DESCRIPTION
+
+ Given an integer that is one of the fundamental DWARF types,
+ translate it to one of the basic internal gdb types and return
+ a pointer to the appropriate gdb type (a "struct type *").
+
+ NOTES
+
+ For robustness, if we are asked to translate a fundamental
+ type that we are unprepared to deal with, we return int so
+ callers can always depend upon a valid type being returned,
+ and so gdb may at least do something reasonable by default.
+ If the type is not in the range of those types defined as
+ application specific types, we also issue a warning.
+ */
+
+static struct type *
+decode_fund_type (unsigned int fundtype)
+{
+ struct type *typep = NULL;
+
+ switch (fundtype)
+ {
+
+ case FT_void:
+ typep = dwarf_fundamental_type (current_objfile, FT_VOID);
+ break;
+
+ case FT_boolean: /* Was FT_set in AT&T version */
+ typep = dwarf_fundamental_type (current_objfile, FT_BOOLEAN);
+ break;
+
+ case FT_pointer: /* (void *) */
+ typep = dwarf_fundamental_type (current_objfile, FT_VOID);
+ typep = lookup_pointer_type (typep);
+ break;
+
+ case FT_char:
+ typep = dwarf_fundamental_type (current_objfile, FT_CHAR);
+ break;
+
+ case FT_signed_char:
+ typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_CHAR);
+ break;
+
+ case FT_unsigned_char:
+ typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
+ break;
+
+ case FT_short:
+ typep = dwarf_fundamental_type (current_objfile, FT_SHORT);
+ break;
+
+ case FT_signed_short:
+ typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_SHORT);
+ break;
+
+ case FT_unsigned_short:
+ typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
+ break;
+
+ case FT_integer:
+ typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+ break;
+
+ case FT_signed_integer:
+ typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_INTEGER);
+ break;
+
+ case FT_unsigned_integer:
+ typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
+ break;
+
+ case FT_long:
+ typep = dwarf_fundamental_type (current_objfile, FT_LONG);
+ break;
+
+ case FT_signed_long:
+ typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_LONG);
+ break;
+
+ case FT_unsigned_long:
+ typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
+ break;
+
+ case FT_long_long:
+ typep = dwarf_fundamental_type (current_objfile, FT_LONG_LONG);
+ break;
+
+ case FT_signed_long_long:
+ typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_LONG_LONG);
+ break;
+
+ case FT_unsigned_long_long:
+ typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG);
+ break;
+
+ case FT_float:
+ typep = dwarf_fundamental_type (current_objfile, FT_FLOAT);
+ break;
+
+ case FT_dbl_prec_float:
+ typep = dwarf_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
+ break;
+
+ case FT_ext_prec_float:
+ typep = dwarf_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
+ break;
+
+ case FT_complex:
+ typep = dwarf_fundamental_type (current_objfile, FT_COMPLEX);
+ break;
+
+ case FT_dbl_prec_complex:
+ typep = dwarf_fundamental_type (current_objfile, FT_DBL_PREC_COMPLEX);
+ break;
+
+ case FT_ext_prec_complex:
+ typep = dwarf_fundamental_type (current_objfile, FT_EXT_PREC_COMPLEX);
+ break;
+
+ }
+
+ if (typep == NULL)
+ {
+ typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+ if (!(FT_lo_user <= fundtype && fundtype <= FT_hi_user))
+ {
+ complain (&unexpected_fund_type, DIE_ID, DIE_NAME, fundtype);
+ }
+ }
+
+ return (typep);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ create_name -- allocate a fresh copy of a string on an obstack
+
+ DESCRIPTION
+
+ Given a pointer to a string and a pointer to an obstack, allocates
+ a fresh copy of the string on the specified obstack.
+
+ */
+
+static char *
+create_name (char *name, struct obstack *obstackp)
+{
+ int length;
+ char *newname;
+
+ length = strlen (name) + 1;
+ newname = (char *) obstack_alloc (obstackp, length);
+ strcpy (newname, name);
+ return (newname);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ basicdieinfo -- extract the minimal die info from raw die data
+
+ SYNOPSIS
+
+ void basicdieinfo (char *diep, struct dieinfo *dip,
+ struct objfile *objfile)
+
+ DESCRIPTION
+
+ Given a pointer to raw DIE data, and a pointer to an instance of a
+ die info structure, this function extracts the basic information
+ from the DIE data required to continue processing this DIE, along
+ with some bookkeeping information about the DIE.
+
+ The information we absolutely must have includes the DIE tag,
+ and the DIE length. If we need the sibling reference, then we
+ will have to call completedieinfo() to process all the remaining
+ DIE information.
+
+ Note that since there is no guarantee that the data is properly
+ aligned in memory for the type of access required (indirection
+ through anything other than a char pointer), and there is no
+ guarantee that it is in the same byte order as the gdb host,
+ we call a function which deals with both alignment and byte
+ swapping issues. Possibly inefficient, but quite portable.
+
+ We also take care of some other basic things at this point, such
+ as ensuring that the instance of the die info structure starts
+ out completely zero'd and that curdie is initialized for use
+ in error reporting if we have a problem with the current die.
+
+ NOTES
+
+ All DIE's must have at least a valid length, thus the minimum
+ DIE size is SIZEOF_DIE_LENGTH. In order to have a valid tag, the
+ DIE size must be at least SIZEOF_DIE_TAG larger, otherwise they
+ are forced to be TAG_padding DIES.
+
+ Padding DIES must be at least SIZEOF_DIE_LENGTH in length, implying
+ that if a padding DIE is used for alignment and the amount needed is
+ less than SIZEOF_DIE_LENGTH, then the padding DIE has to be big
+ enough to align to the next alignment boundry.
+
+ We do some basic sanity checking here, such as verifying that the
+ length of the die would not cause it to overrun the recorded end of
+ the buffer holding the DIE info. If we find a DIE that is either
+ too small or too large, we force it's length to zero which should
+ cause the caller to take appropriate action.
+ */
+
+static void
+basicdieinfo (struct dieinfo *dip, char *diep, struct objfile *objfile)
+{
+ curdie = dip;
+ memset (dip, 0, sizeof (struct dieinfo));
+ dip->die = diep;
+ dip->die_ref = dbroff + (diep - dbbase);
+ dip->die_length = target_to_host (diep, SIZEOF_DIE_LENGTH, GET_UNSIGNED,
+ objfile);
+ if ((dip->die_length < SIZEOF_DIE_LENGTH) ||
+ ((diep + dip->die_length) > (dbbase + dbsize)))
+ {
+ complain (&malformed_die, DIE_ID, DIE_NAME, dip->die_length);
+ dip->die_length = 0;
+ }
+ else if (dip->die_length < (SIZEOF_DIE_LENGTH + SIZEOF_DIE_TAG))
+ {
+ dip->die_tag = TAG_padding;
+ }
+ else
+ {
+ diep += SIZEOF_DIE_LENGTH;
+ dip->die_tag = target_to_host (diep, SIZEOF_DIE_TAG, GET_UNSIGNED,
+ objfile);
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ completedieinfo -- finish reading the information for a given DIE
+
+ SYNOPSIS
+
+ void completedieinfo (struct dieinfo *dip, struct objfile *objfile)
+
+ DESCRIPTION
+
+ Given a pointer to an already partially initialized die info structure,
+ scan the raw DIE data and finish filling in the die info structure
+ from the various attributes found.
+
+ Note that since there is no guarantee that the data is properly
+ aligned in memory for the type of access required (indirection
+ through anything other than a char pointer), and there is no
+ guarantee that it is in the same byte order as the gdb host,
+ we call a function which deals with both alignment and byte
+ swapping issues. Possibly inefficient, but quite portable.
+
+ NOTES
+
+ Each time we are called, we increment the diecount variable, which
+ keeps an approximate count of the number of dies processed for
+ each compilation unit. This information is presented to the user
+ if the info_verbose flag is set.
+
+ */
+
+static void
+completedieinfo (struct dieinfo *dip, struct objfile *objfile)
+{
+ char *diep; /* Current pointer into raw DIE data */
+ char *end; /* Terminate DIE scan here */
+ unsigned short attr; /* Current attribute being scanned */
+ unsigned short form; /* Form of the attribute */
+ int nbytes; /* Size of next field to read */
+
+ diecount++;
+ diep = dip->die;
+ end = diep + dip->die_length;
+ diep += SIZEOF_DIE_LENGTH + SIZEOF_DIE_TAG;
+ while (diep < end)
+ {
+ attr = target_to_host (diep, SIZEOF_ATTRIBUTE, GET_UNSIGNED, objfile);
+ diep += SIZEOF_ATTRIBUTE;
+ if ((nbytes = attribute_size (attr)) == -1)
+ {
+ complain (&unknown_attribute_length, DIE_ID, DIE_NAME);
+ diep = end;
+ continue;
+ }
+ switch (attr)
+ {
+ case AT_fund_type:
+ dip->at_fund_type = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ break;
+ case AT_ordering:
+ dip->at_ordering = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ break;
+ case AT_bit_offset:
+ dip->at_bit_offset = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ break;
+ case AT_sibling:
+ dip->at_sibling = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ break;
+ case AT_stmt_list:
+ dip->at_stmt_list = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ dip->has_at_stmt_list = 1;
+ break;
+ case AT_low_pc:
+ dip->at_low_pc = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ dip->at_low_pc += baseaddr;
+ dip->has_at_low_pc = 1;
+ break;
+ case AT_high_pc:
+ dip->at_high_pc = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ dip->at_high_pc += baseaddr;
+ break;
+ case AT_language:
+ dip->at_language = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ break;
+ case AT_user_def_type:
+ dip->at_user_def_type = target_to_host (diep, nbytes,
+ GET_UNSIGNED, objfile);
+ break;
+ case AT_byte_size:
+ dip->at_byte_size = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ dip->has_at_byte_size = 1;
+ break;
+ case AT_bit_size:
+ dip->at_bit_size = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ break;
+ case AT_member:
+ dip->at_member = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ break;
+ case AT_discr:
+ dip->at_discr = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ break;
+ case AT_location:
+ dip->at_location = diep;
+ break;
+ case AT_mod_fund_type:
+ dip->at_mod_fund_type = diep;
+ break;
+ case AT_subscr_data:
+ dip->at_subscr_data = diep;
+ break;
+ case AT_mod_u_d_type:
+ dip->at_mod_u_d_type = diep;
+ break;
+ case AT_element_list:
+ dip->at_element_list = diep;
+ dip->short_element_list = 0;
+ break;
+ case AT_short_element_list:
+ dip->at_element_list = diep;
+ dip->short_element_list = 1;
+ break;
+ case AT_discr_value:
+ dip->at_discr_value = diep;
+ break;
+ case AT_string_length:
+ dip->at_string_length = diep;
+ break;
+ case AT_name:
+ dip->at_name = diep;
+ break;
+ case AT_comp_dir:
+ /* For now, ignore any "hostname:" portion, since gdb doesn't
+ know how to deal with it. (FIXME). */
+ dip->at_comp_dir = strrchr (diep, ':');
+ if (dip->at_comp_dir != NULL)
+ {
+ dip->at_comp_dir++;
+ }
+ else
+ {
+ dip->at_comp_dir = diep;
+ }
+ break;
+ case AT_producer:
+ dip->at_producer = diep;
+ break;
+ case AT_start_scope:
+ dip->at_start_scope = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ break;
+ case AT_stride_size:
+ dip->at_stride_size = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ break;
+ case AT_src_info:
+ dip->at_src_info = target_to_host (diep, nbytes, GET_UNSIGNED,
+ objfile);
+ break;
+ case AT_prototyped:
+ dip->at_prototyped = diep;
+ break;
+ default:
+ /* Found an attribute that we are unprepared to handle. However
+ it is specifically one of the design goals of DWARF that
+ consumers should ignore unknown attributes. As long as the
+ form is one that we recognize (so we know how to skip it),
+ we can just ignore the unknown attribute. */
+ break;
+ }
+ form = FORM_FROM_ATTR (attr);
+ switch (form)
+ {
+ case FORM_DATA2:
+ diep += 2;
+ break;
+ case FORM_DATA4:
+ case FORM_REF:
+ diep += 4;
+ break;
+ case FORM_DATA8:
+ diep += 8;
+ break;
+ case FORM_ADDR:
+ diep += TARGET_FT_POINTER_SIZE (objfile);
+ break;
+ case FORM_BLOCK2:
+ diep += 2 + target_to_host (diep, nbytes, GET_UNSIGNED, objfile);
+ break;
+ case FORM_BLOCK4:
+ diep += 4 + target_to_host (diep, nbytes, GET_UNSIGNED, objfile);
+ break;
+ case FORM_STRING:
+ diep += strlen (diep) + 1;
+ break;
+ default:
+ complain (&unknown_attribute_form, DIE_ID, DIE_NAME, form);
+ diep = end;
+ break;
+ }
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ target_to_host -- swap in target data to host
+
+ SYNOPSIS
+
+ target_to_host (char *from, int nbytes, int signextend,
+ struct objfile *objfile)
+
+ DESCRIPTION
+
+ Given pointer to data in target format in FROM, a byte count for
+ the size of the data in NBYTES, a flag indicating whether or not
+ the data is signed in SIGNEXTEND, and a pointer to the current
+ objfile in OBJFILE, convert the data to host format and return
+ the converted value.
+
+ NOTES
+
+ FIXME: If we read data that is known to be signed, and expect to
+ use it as signed data, then we need to explicitly sign extend the
+ result until the bfd library is able to do this for us.
+
+ FIXME: Would a 32 bit target ever need an 8 byte result?
+
+ */
+
+static CORE_ADDR
+target_to_host (char *from, int nbytes, int signextend, /* FIXME: Unused */
+ struct objfile *objfile)
+{
+ CORE_ADDR rtnval;
+
+ switch (nbytes)
+ {
+ case 8:
+ rtnval = bfd_get_64 (objfile->obfd, (bfd_byte *) from);
+ break;
+ case 4:
+ rtnval = bfd_get_32 (objfile->obfd, (bfd_byte *) from);
+ break;
+ case 2:
+ rtnval = bfd_get_16 (objfile->obfd, (bfd_byte *) from);
+ break;
+ case 1:
+ rtnval = bfd_get_8 (objfile->obfd, (bfd_byte *) from);
+ break;
+ default:
+ complain (&no_bfd_get_N, DIE_ID, DIE_NAME, nbytes);
+ rtnval = 0;
+ break;
+ }
+ return (rtnval);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ attribute_size -- compute size of data for a DWARF attribute
+
+ SYNOPSIS
+
+ static int attribute_size (unsigned int attr)
+
+ DESCRIPTION
+
+ Given a DWARF attribute in ATTR, compute the size of the first
+ piece of data associated with this attribute and return that
+ size.
+
+ Returns -1 for unrecognized attributes.
+
+ */
+
+static int
+attribute_size (unsigned int attr)
+{
+ int nbytes; /* Size of next data for this attribute */
+ unsigned short form; /* Form of the attribute */
+
+ form = FORM_FROM_ATTR (attr);
+ switch (form)
+ {
+ case FORM_STRING: /* A variable length field is next */
+ nbytes = 0;
+ break;
+ case FORM_DATA2: /* Next 2 byte field is the data itself */
+ case FORM_BLOCK2: /* Next 2 byte field is a block length */
+ nbytes = 2;
+ break;
+ case FORM_DATA4: /* Next 4 byte field is the data itself */
+ case FORM_BLOCK4: /* Next 4 byte field is a block length */
+ case FORM_REF: /* Next 4 byte field is a DIE offset */
+ nbytes = 4;
+ break;
+ case FORM_DATA8: /* Next 8 byte field is the data itself */
+ nbytes = 8;
+ break;
+ case FORM_ADDR: /* Next field size is target sizeof(void *) */
+ nbytes = TARGET_FT_POINTER_SIZE (objfile);
+ break;
+ default:
+ complain (&unknown_attribute_form, DIE_ID, DIE_NAME, form);
+ nbytes = -1;
+ break;
+ }
+ return (nbytes);
+}
diff --git a/gdb/elfread.c b/gdb/elfread.c
new file mode 100644
index 00000000000..e76cd0d4a35
--- /dev/null
+++ b/gdb/elfread.c
@@ -0,0 +1,790 @@
+/* Read ELF (Executable and Linking Format) object files for GDB.
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002
+ Free Software Foundation, Inc.
+ Written by Fred Fish at 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 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 "defs.h"
+#include "bfd.h"
+#include "gdb_string.h"
+#include "elf-bfd.h"
+#include "elf/mips.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "stabsread.h"
+#include "gdb-stabs.h"
+#include "complaints.h"
+#include "demangle.h"
+
+extern void _initialize_elfread (void);
+
+/* The struct elfinfo is available only during ELF symbol table and
+ psymtab reading. It is destroyed at the completion of psymtab-reading.
+ It's local to elf_symfile_read. */
+
+struct elfinfo
+ {
+ file_ptr dboffset; /* Offset to dwarf debug section */
+ unsigned int dbsize; /* Size of dwarf debug section */
+ file_ptr lnoffset; /* Offset to dwarf line number section */
+ unsigned int lnsize; /* Size of dwarf line number section */
+ asection *stabsect; /* Section pointer for .stab section */
+ asection *stabindexsect; /* Section pointer for .stab.index section */
+ asection *mdebugsect; /* Section pointer for .mdebug section */
+ };
+
+/* Various things we might complain about... */
+
+struct complaint section_info_complaint =
+{"elf/stab section information %s without a preceding file symbol", 0, 0};
+
+struct complaint section_info_dup_complaint =
+{"duplicated elf/stab section information for %s", 0, 0};
+
+struct complaint stab_info_mismatch_complaint =
+{"elf/stab section information missing for %s", 0, 0};
+
+struct complaint stab_info_questionable_complaint =
+{"elf/stab section information questionable for %s", 0, 0};
+
+static void free_elfinfo (void *);
+
+/* We are called once per section from elf_symfile_read. We
+ need to examine each section we are passed, check to see
+ if it is something we are interested in processing, and
+ if so, stash away some access information for the section.
+
+ For now we recognize the dwarf debug information sections and
+ line number sections from matching their section names. The
+ ELF definition is no real help here since it has no direct
+ knowledge of DWARF (by design, so any debugging format can be
+ used).
+
+ We also recognize the ".stab" sections used by the Sun compilers
+ released with Solaris 2.
+
+ FIXME: The section names should not be hardwired strings (what
+ should they be? I don't think most object file formats have enough
+ section flags to specify what kind of debug section it is
+ -kingdon). */
+
+static void
+elf_locate_sections (bfd *ignore_abfd, asection *sectp, void *eip)
+{
+ register struct elfinfo *ei;
+
+ ei = (struct elfinfo *) eip;
+ if (STREQ (sectp->name, ".debug"))
+ {
+ ei->dboffset = sectp->filepos;
+ ei->dbsize = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, ".line"))
+ {
+ ei->lnoffset = sectp->filepos;
+ ei->lnsize = bfd_get_section_size_before_reloc (sectp);
+ }
+ else if (STREQ (sectp->name, ".stab"))
+ {
+ ei->stabsect = sectp;
+ }
+ else if (STREQ (sectp->name, ".stab.index"))
+ {
+ ei->stabindexsect = sectp;
+ }
+ else if (STREQ (sectp->name, ".mdebug"))
+ {
+ ei->mdebugsect = sectp;
+ }
+}
+
+#if 0 /* Currently unused */
+
+char *
+elf_interpreter (bfd *abfd)
+{
+ sec_ptr interp_sec;
+ unsigned size;
+ char *interp = NULL;
+
+ interp_sec = bfd_get_section_by_name (abfd, ".interp");
+ if (interp_sec)
+ {
+ size = bfd_section_size (abfd, interp_sec);
+ interp = alloca (size);
+ if (bfd_get_section_contents (abfd, interp_sec, interp, (file_ptr) 0,
+ size))
+ {
+ interp = savestring (interp, size - 1);
+ }
+ else
+ {
+ interp = NULL;
+ }
+ }
+ return (interp);
+}
+
+#endif
+
+static struct minimal_symbol *
+record_minimal_symbol_and_info (char *name, CORE_ADDR address,
+ enum minimal_symbol_type ms_type, char *info, /* FIXME, is this really char *? */
+ asection *bfd_section, struct objfile *objfile)
+{
+ if (ms_type == mst_text || ms_type == mst_file_text)
+ address = SMASH_TEXT_ADDRESS (address);
+
+ return prim_record_minimal_symbol_and_info
+ (name, address, ms_type, info, bfd_section->index, bfd_section, objfile);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ elf_symtab_read -- read the symbol table of an ELF file
+
+ SYNOPSIS
+
+ void elf_symtab_read (struct objfile *objfile, int dynamic)
+
+ DESCRIPTION
+
+ Given an objfile and a flag that specifies whether or not the objfile
+ is for an executable or not (may be shared library for example), add
+ all the global function and data symbols to the minimal symbol table.
+
+ In stabs-in-ELF, as implemented by Sun, there are some local symbols
+ defined in the ELF symbol table, which can be used to locate
+ the beginnings of sections from each ".o" file that was linked to
+ form the executable objfile. We gather any such info and record it
+ in data structures hung off the objfile's private data.
+
+ */
+
+static void
+elf_symtab_read (struct objfile *objfile, int dynamic)
+{
+ long storage_needed;
+ asymbol *sym;
+ asymbol **symbol_table;
+ long number_of_symbols;
+ long i;
+ int index;
+ struct cleanup *back_to;
+ CORE_ADDR symaddr;
+ CORE_ADDR offset;
+ enum minimal_symbol_type ms_type;
+ /* If sectinfo is nonNULL, it contains section info that should end up
+ filed in the objfile. */
+ struct stab_section_info *sectinfo = NULL;
+ /* If filesym is nonzero, it points to a file symbol, but we haven't
+ seen any section info for it yet. */
+ asymbol *filesym = 0;
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ /* Name of filesym, as saved on the symbol_obstack. */
+ char *filesymname = obsavestring ("", 0, &objfile->symbol_obstack);
+#endif
+ struct dbx_symfile_info *dbx = objfile->sym_stab_info;
+ unsigned long size;
+ int stripped = (bfd_get_symcount (objfile->obfd) == 0);
+
+ if (dynamic)
+ {
+ storage_needed = bfd_get_dynamic_symtab_upper_bound (objfile->obfd);
+
+ /* Nothing to be done if there is no dynamic symtab. */
+ if (storage_needed < 0)
+ return;
+ }
+ else
+ {
+ storage_needed = bfd_get_symtab_upper_bound (objfile->obfd);
+ if (storage_needed < 0)
+ error ("Can't read symbols from %s: %s", bfd_get_filename (objfile->obfd),
+ bfd_errmsg (bfd_get_error ()));
+ }
+ if (storage_needed > 0)
+ {
+ symbol_table = (asymbol **) xmalloc (storage_needed);
+ back_to = make_cleanup (xfree, symbol_table);
+ if (dynamic)
+ number_of_symbols = bfd_canonicalize_dynamic_symtab (objfile->obfd,
+ symbol_table);
+ else
+ number_of_symbols = bfd_canonicalize_symtab (objfile->obfd, symbol_table);
+ if (number_of_symbols < 0)
+ error ("Can't read symbols from %s: %s", bfd_get_filename (objfile->obfd),
+ bfd_errmsg (bfd_get_error ()));
+
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ sym = symbol_table[i];
+ if (sym->name == NULL || *sym->name == '\0')
+ {
+ /* Skip names that don't exist (shouldn't happen), or names
+ that are null strings (may happen). */
+ continue;
+ }
+
+ offset = ANOFFSET (objfile->section_offsets, sym->section->index);
+ if (dynamic
+ && sym->section == &bfd_und_section
+ && (sym->flags & BSF_FUNCTION))
+ {
+ struct minimal_symbol *msym;
+
+ /* Symbol is a reference to a function defined in
+ a shared library.
+ If its value is non zero then it is usually the address
+ of the corresponding entry in the procedure linkage table,
+ plus the desired section offset.
+ If its value is zero then the dynamic linker has to resolve
+ the symbol. We are unable to find any meaningful address
+ for this symbol in the executable file, so we skip it. */
+ symaddr = sym->value;
+ if (symaddr == 0)
+ continue;
+ symaddr += offset;
+ msym = record_minimal_symbol_and_info
+ ((char *) sym->name, symaddr,
+ mst_solib_trampoline, NULL, sym->section, objfile);
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ if (msym != NULL)
+ msym->filename = filesymname;
+#endif
+ continue;
+ }
+
+ /* If it is a nonstripped executable, do not enter dynamic
+ symbols, as the dynamic symbol table is usually a subset
+ of the main symbol table. */
+ if (dynamic && !stripped)
+ continue;
+ if (sym->flags & BSF_FILE)
+ {
+ /* STT_FILE debugging symbol that helps stabs-in-elf debugging.
+ Chain any old one onto the objfile; remember new sym. */
+ if (sectinfo != NULL)
+ {
+ sectinfo->next = dbx->stab_section_info;
+ dbx->stab_section_info = sectinfo;
+ sectinfo = NULL;
+ }
+ filesym = sym;
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ filesymname =
+ obsavestring ((char *) filesym->name, strlen (filesym->name),
+ &objfile->symbol_obstack);
+#endif
+ }
+ else if (sym->flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK))
+ {
+ struct minimal_symbol *msym;
+
+ /* Select global/local/weak symbols. Note that bfd puts abs
+ symbols in their own section, so all symbols we are
+ interested in will have a section. */
+ /* Bfd symbols are section relative. */
+ symaddr = sym->value + sym->section->vma;
+ /* Relocate all non-absolute symbols by the section offset. */
+ if (sym->section != &bfd_abs_section)
+ {
+ symaddr += offset;
+ }
+ /* For non-absolute symbols, use the type of the section
+ they are relative to, to intuit text/data. Bfd provides
+ no way of figuring this out for absolute symbols. */
+ if (sym->section == &bfd_abs_section)
+ {
+ /* This is a hack to get the minimal symbol type
+ right for Irix 5, which has absolute addresses
+ with special section indices for dynamic symbols. */
+ unsigned short shndx =
+ ((elf_symbol_type *) sym)->internal_elf_sym.st_shndx;
+
+ switch (shndx)
+ {
+ case SHN_MIPS_TEXT:
+ ms_type = mst_text;
+ break;
+ case SHN_MIPS_DATA:
+ ms_type = mst_data;
+ break;
+ case SHN_MIPS_ACOMMON:
+ ms_type = mst_bss;
+ break;
+ default:
+ ms_type = mst_abs;
+ }
+
+ /* If it is an Irix dynamic symbol, skip section name
+ symbols, relocate all others by section offset. */
+ if (ms_type != mst_abs)
+ {
+ if (sym->name[0] == '.')
+ continue;
+ symaddr += offset;
+ }
+ }
+ else if (sym->section->flags & SEC_CODE)
+ {
+ if (sym->flags & BSF_GLOBAL)
+ {
+ ms_type = mst_text;
+ }
+ else if ((sym->name[0] == '.' && sym->name[1] == 'L')
+ || ((sym->flags & BSF_LOCAL)
+ && sym->name[0] == '$'
+ && sym->name[1] == 'L'))
+ /* Looks like a compiler-generated label. Skip it.
+ The assembler should be skipping these (to keep
+ executables small), but apparently with gcc on the
+ delta m88k SVR4, it loses. So to have us check too
+ should be harmless (but I encourage people to fix this
+ in the assembler instead of adding checks here). */
+ continue;
+#ifdef HARRIS_TARGET
+ else if (sym->name[0] == '.' && sym->name[1] == '.')
+ {
+ /* Looks like a Harris compiler generated label for the
+ purpose of marking instructions that are relevant to
+ DWARF dies. The assembler can't get rid of these
+ because they are relocatable addresses that the
+ linker needs to resolve. */
+ continue;
+ }
+#endif
+ else
+ {
+ ms_type = mst_file_text;
+ }
+ }
+ else if (sym->section->flags & SEC_ALLOC)
+ {
+ if (sym->flags & (BSF_GLOBAL | BSF_WEAK))
+ {
+ if (sym->section->flags & SEC_LOAD)
+ {
+ ms_type = mst_data;
+ }
+ else
+ {
+ ms_type = mst_bss;
+ }
+ }
+ else if (sym->flags & BSF_LOCAL)
+ {
+ /* Named Local variable in a Data section. Check its
+ name for stabs-in-elf. The STREQ macro checks the
+ first character inline, so we only actually do a
+ strcmp function call on names that start with 'B'
+ or 'D' */
+ index = SECT_OFF_MAX;
+ if (STREQ ("Bbss.bss", sym->name))
+ {
+ index = SECT_OFF_BSS (objfile);
+ }
+ else if (STREQ ("Ddata.data", sym->name))
+ {
+ index = SECT_OFF_DATA (objfile);
+ }
+ else if (STREQ ("Drodata.rodata", sym->name))
+ {
+ index = SECT_OFF_RODATA (objfile);
+ }
+ if (index != SECT_OFF_MAX)
+ {
+ /* Found a special local symbol. Allocate a
+ sectinfo, if needed, and fill it in. */
+ if (sectinfo == NULL)
+ {
+ sectinfo = (struct stab_section_info *)
+ xmmalloc (objfile->md, sizeof (*sectinfo));
+ memset (sectinfo, 0,
+ sizeof (*sectinfo));
+ if (filesym == NULL)
+ {
+ complain (&section_info_complaint,
+ sym->name);
+ }
+ else
+ {
+ sectinfo->filename =
+ (char *) filesym->name;
+ }
+ }
+ if (index != -1)
+ {
+ if (sectinfo->sections[index] != 0)
+ {
+ complain (&section_info_dup_complaint,
+ sectinfo->filename);
+ }
+ }
+ else
+ internal_error (__FILE__, __LINE__,
+ "Section index uninitialized.");
+ /* Bfd symbols are section relative. */
+ symaddr = sym->value + sym->section->vma;
+ /* Relocate non-absolute symbols by the section offset. */
+ if (sym->section != &bfd_abs_section)
+ {
+ symaddr += offset;
+ }
+ if (index != -1)
+ sectinfo->sections[index] = symaddr;
+ else
+ internal_error (__FILE__, __LINE__,
+ "Section index uninitialized.");
+ /* The special local symbols don't go in the
+ minimal symbol table, so ignore this one. */
+ continue;
+ }
+ /* Not a special stabs-in-elf symbol, do regular
+ symbol processing. */
+ if (sym->section->flags & SEC_LOAD)
+ {
+ ms_type = mst_file_data;
+ }
+ else
+ {
+ ms_type = mst_file_bss;
+ }
+ }
+ else
+ {
+ ms_type = mst_unknown;
+ }
+ }
+ else
+ {
+ /* FIXME: Solaris2 shared libraries include lots of
+ odd "absolute" and "undefined" symbols, that play
+ hob with actions like finding what function the PC
+ is in. Ignore them if they aren't text, data, or bss. */
+ /* ms_type = mst_unknown; */
+ continue; /* Skip this symbol. */
+ }
+ /* Pass symbol size field in via BFD. FIXME!!! */
+ size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
+ msym = record_minimal_symbol_and_info
+ ((char *) sym->name, symaddr,
+ ms_type, (void *) size, sym->section, objfile);
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ if (msym != NULL)
+ msym->filename = filesymname;
+#endif
+ ELF_MAKE_MSYMBOL_SPECIAL (sym, msym);
+ }
+ }
+ do_cleanups (back_to);
+ }
+}
+
+/* Scan and build partial symbols for a symbol file.
+ We have been initialized by a call to elf_symfile_init, which
+ currently does nothing.
+
+ SECTION_OFFSETS is a set of offsets to apply to relocate the symbols
+ in each section. We simplify it down to a single offset for all
+ symbols. FIXME.
+
+ MAINLINE is true if we are reading the main symbol
+ table (as opposed to a shared lib or dynamically loaded file).
+
+ This function only does the minimum work necessary for letting the
+ user "name" things symbolically; it does not read the entire symtab.
+ Instead, it reads the external and static symbols and puts them in partial
+ symbol tables. When more extensive information is requested of a
+ file, the corresponding partial symbol table is mutated into a full
+ fledged symbol table by going back and reading the symbols
+ for real.
+
+ We look for sections with specific names, to tell us what debug
+ format to look for: FIXME!!!
+
+ dwarf_build_psymtabs() builds psymtabs for DWARF symbols;
+ elfstab_build_psymtabs() handles STABS symbols;
+ mdebug_build_psymtabs() handles ECOFF debugging information.
+
+ Note that ELF files have a "minimal" symbol table, which looks a lot
+ like a COFF symbol table, but has only the minimal information necessary
+ for linking. We process this also, and use the information to
+ build gdb's minimal symbol table. This gives us some minimal debugging
+ capability even for files compiled without -g. */
+
+static void
+elf_symfile_read (struct objfile *objfile, int mainline)
+{
+ bfd *abfd = objfile->obfd;
+ struct elfinfo ei;
+ struct cleanup *back_to;
+ CORE_ADDR offset;
+
+ init_minimal_symbol_collection ();
+ back_to = make_cleanup_discard_minimal_symbols ();
+
+ memset ((char *) &ei, 0, sizeof (ei));
+
+ /* Allocate struct to keep track of the symfile */
+ objfile->sym_stab_info = (struct dbx_symfile_info *)
+ xmmalloc (objfile->md, sizeof (struct dbx_symfile_info));
+ memset ((char *) objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
+ make_cleanup (free_elfinfo, (void *) objfile);
+
+ /* Process the normal ELF symbol table first. This may write some
+ chain of info into the dbx_symfile_info in objfile->sym_stab_info,
+ which can later be used by elfstab_offset_sections. */
+
+ elf_symtab_read (objfile, 0);
+
+ /* Add the dynamic symbols. */
+
+ elf_symtab_read (objfile, 1);
+
+ /* Now process debugging information, which is contained in
+ special ELF sections. */
+
+ /* If we are reinitializing, or if we have never loaded syms yet,
+ set table to empty. MAINLINE is cleared so that *_read_psymtab
+ functions do not all also re-initialize the psymbol table. */
+ if (mainline)
+ {
+ init_psymbol_list (objfile, 0);
+ mainline = 0;
+ }
+
+ /* We first have to find them... */
+ bfd_map_over_sections (abfd, elf_locate_sections, (void *) & ei);
+
+ /* ELF debugging information is inserted into the psymtab in the
+ order of least informative first - most informative last. Since
+ the psymtab table is searched `most recent insertion first' this
+ increases the probability that more detailed debug information
+ for a section is found.
+
+ For instance, an object file might contain both .mdebug (XCOFF)
+ and .debug_info (DWARF2) sections then .mdebug is inserted first
+ (searched last) and DWARF2 is inserted last (searched first). If
+ we don't do this then the XCOFF info is found first - for code in
+ an included file XCOFF info is useless. */
+
+ if (ei.mdebugsect)
+ {
+ const struct ecoff_debug_swap *swap;
+
+ /* .mdebug section, presumably holding ECOFF debugging
+ information. */
+ swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
+ if (swap)
+ elfmdebug_build_psymtabs (objfile, swap, ei.mdebugsect);
+ }
+ if (ei.stabsect)
+ {
+ asection *str_sect;
+
+ /* Stab sections have an associated string table that looks like
+ a separate section. */
+ str_sect = bfd_get_section_by_name (abfd, ".stabstr");
+
+ /* FIXME should probably warn about a stab section without a stabstr. */
+ if (str_sect)
+ elfstab_build_psymtabs (objfile,
+ mainline,
+ ei.stabsect->filepos,
+ bfd_section_size (abfd, ei.stabsect),
+ str_sect->filepos,
+ bfd_section_size (abfd, str_sect));
+ }
+ if (dwarf2_has_info (abfd))
+ {
+ /* DWARF 2 sections */
+ dwarf2_build_psymtabs (objfile, mainline);
+ }
+ else if (ei.dboffset && ei.lnoffset)
+ {
+ /* DWARF sections */
+ dwarf_build_psymtabs (objfile,
+ mainline,
+ ei.dboffset, ei.dbsize,
+ ei.lnoffset, ei.lnsize);
+ }
+
+ if (DWARF2_BUILD_FRAME_INFO_P ())
+ DWARF2_BUILD_FRAME_INFO(objfile);
+
+ /* Install any minimal symbols that have been collected as the current
+ minimal symbols for this objfile. */
+
+ install_minimal_symbols (objfile);
+
+ do_cleanups (back_to);
+}
+
+/* This cleans up the objfile's sym_stab_info pointer, and the chain of
+ stab_section_info's, that might be dangling from it. */
+
+static void
+free_elfinfo (void *objp)
+{
+ struct objfile *objfile = (struct objfile *) objp;
+ struct dbx_symfile_info *dbxinfo = objfile->sym_stab_info;
+ struct stab_section_info *ssi, *nssi;
+
+ ssi = dbxinfo->stab_section_info;
+ while (ssi)
+ {
+ nssi = ssi->next;
+ xmfree (objfile->md, ssi);
+ ssi = nssi;
+ }
+
+ dbxinfo->stab_section_info = 0; /* Just say No mo info about this. */
+}
+
+
+/* Initialize anything that needs initializing when a completely new symbol
+ file is specified (not just adding some symbols from another file, e.g. a
+ shared library).
+
+ We reinitialize buildsym, since we may be reading stabs from an ELF file. */
+
+static void
+elf_new_init (struct objfile *ignore)
+{
+ stabsread_new_init ();
+ buildsym_new_init ();
+}
+
+/* Perform any local cleanups required when we are done with a particular
+ objfile. I.E, we are in the process of discarding all symbol information
+ for an objfile, freeing up all memory held for it, and unlinking the
+ objfile struct from the global list of known objfiles. */
+
+static void
+elf_symfile_finish (struct objfile *objfile)
+{
+ if (objfile->sym_stab_info != NULL)
+ {
+ xmfree (objfile->md, objfile->sym_stab_info);
+ }
+}
+
+/* ELF specific initialization routine for reading symbols.
+
+ It is passed a pointer to a struct sym_fns which contains, among other
+ things, the BFD for the file whose symbols are being read, and a slot for
+ a pointer to "private data" which we can fill with goodies.
+
+ For now at least, we have nothing in particular to do, so this function is
+ just a stub. */
+
+static void
+elf_symfile_init (struct objfile *objfile)
+{
+ /* ELF objects may be reordered, so set OBJF_REORDERED. If we
+ find this causes a significant slowdown in gdb then we could
+ set it in the debug symbol readers only when necessary. */
+ objfile->flags |= OBJF_REORDERED;
+}
+
+/* When handling an ELF file that contains Sun STABS debug info,
+ some of the debug info is relative to the particular chunk of the
+ section that was generated in its individual .o file. E.g.
+ offsets to static variables are relative to the start of the data
+ segment *for that module before linking*. This information is
+ painfully squirreled away in the ELF symbol table as local symbols
+ with wierd names. Go get 'em when needed. */
+
+void
+elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst)
+{
+ char *filename = pst->filename;
+ struct dbx_symfile_info *dbx = objfile->sym_stab_info;
+ struct stab_section_info *maybe = dbx->stab_section_info;
+ struct stab_section_info *questionable = 0;
+ int i;
+ char *p;
+
+ /* The ELF symbol info doesn't include path names, so strip the path
+ (if any) from the psymtab filename. */
+ while (0 != (p = strchr (filename, '/')))
+ filename = p + 1;
+
+ /* FIXME: This linear search could speed up significantly
+ if it was chained in the right order to match how we search it,
+ and if we unchained when we found a match. */
+ for (; maybe; maybe = maybe->next)
+ {
+ if (filename[0] == maybe->filename[0]
+ && STREQ (filename, maybe->filename))
+ {
+ /* We found a match. But there might be several source files
+ (from different directories) with the same name. */
+ if (0 == maybe->found)
+ break;
+ questionable = maybe; /* Might use it later. */
+ }
+ }
+
+ if (maybe == 0 && questionable != 0)
+ {
+ complain (&stab_info_questionable_complaint, filename);
+ maybe = questionable;
+ }
+
+ if (maybe)
+ {
+ /* Found it! Allocate a new psymtab struct, and fill it in. */
+ maybe->found++;
+ pst->section_offsets = (struct section_offsets *)
+ obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
+ for (i = 0; i < SECT_OFF_MAX; i++)
+ (pst->section_offsets)->offsets[i] = maybe->sections[i];
+ return;
+ }
+
+ /* We were unable to find any offsets for this file. Complain. */
+ if (dbx->stab_section_info) /* If there *is* any info, */
+ complain (&stab_info_mismatch_complaint, filename);
+}
+
+/* Register that we are able to handle ELF object file formats. */
+
+static struct sym_fns elf_sym_fns =
+{
+ bfd_target_elf_flavour,
+ elf_new_init, /* sym_new_init: init anything gbl to entire symtab */
+ elf_symfile_init, /* sym_init: read initial info, setup for sym_read() */
+ elf_symfile_read, /* sym_read: read a symbol file into symtab */
+ elf_symfile_finish, /* sym_finish: finished with file, cleanup */
+ default_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */
+ NULL /* next: pointer to next struct sym_fns */
+};
+
+void
+_initialize_elfread (void)
+{
+ add_symtab_fns (&elf_sym_fns);
+}
diff --git a/gdb/environ.c b/gdb/environ.c
new file mode 100644
index 00000000000..1f9a9d67e9f
--- /dev/null
+++ b/gdb/environ.c
@@ -0,0 +1,185 @@
+/* environ.c -- library for manipulating environments for GNU.
+ Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 2000
+ Free Software Foundation, Inc.
+
+ 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. */
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#define max(a, b) ((a) > (b) ? (a) : (b))
+
+#include "defs.h"
+#include "environ.h"
+#include "gdb_string.h"
+
+
+/* Return a new environment object. */
+
+struct environ *
+make_environ (void)
+{
+ register struct environ *e;
+
+ e = (struct environ *) xmalloc (sizeof (struct environ));
+
+ e->allocated = 10;
+ e->vector = (char **) xmalloc ((e->allocated + 1) * sizeof (char *));
+ e->vector[0] = 0;
+ return e;
+}
+
+/* Free an environment and all the strings in it. */
+
+void
+free_environ (register struct environ *e)
+{
+ register char **vector = e->vector;
+
+ while (*vector)
+ xfree (*vector++);
+
+ xfree (e);
+}
+
+/* Copy the environment given to this process into E.
+ Also copies all the strings in it, so we can be sure
+ that all strings in these environments are safe to free. */
+
+void
+init_environ (register struct environ *e)
+{
+ extern char **environ;
+ register int i;
+
+ if (environ == NULL)
+ return;
+
+ for (i = 0; environ[i]; i++) /*EMPTY */ ;
+
+ if (e->allocated < i)
+ {
+ e->allocated = max (i, e->allocated + 10);
+ e->vector = (char **) xrealloc ((char *) e->vector,
+ (e->allocated + 1) * sizeof (char *));
+ }
+
+ memcpy (e->vector, environ, (i + 1) * sizeof (char *));
+
+ while (--i >= 0)
+ {
+ register int len = strlen (e->vector[i]);
+ register char *new = (char *) xmalloc (len + 1);
+ memcpy (new, e->vector[i], len + 1);
+ e->vector[i] = new;
+ }
+}
+
+/* Return the vector of environment E.
+ This is used to get something to pass to execve. */
+
+char **
+environ_vector (struct environ *e)
+{
+ return e->vector;
+}
+
+/* Return the value in environment E of variable VAR. */
+
+char *
+get_in_environ (const struct environ *e, const char *var)
+{
+ register int len = strlen (var);
+ register char **vector = e->vector;
+ register char *s;
+
+ for (; (s = *vector) != NULL; vector++)
+ if (STREQN (s, var, len) && s[len] == '=')
+ return &s[len + 1];
+
+ return 0;
+}
+
+/* Store the value in E of VAR as VALUE. */
+
+void
+set_in_environ (struct environ *e, const char *var, const char *value)
+{
+ register int i;
+ register int len = strlen (var);
+ register char **vector = e->vector;
+ register char *s;
+
+ for (i = 0; (s = vector[i]) != NULL; i++)
+ if (STREQN (s, var, len) && s[len] == '=')
+ break;
+
+ if (s == 0)
+ {
+ if (i == e->allocated)
+ {
+ e->allocated += 10;
+ vector = (char **) xrealloc ((char *) vector,
+ (e->allocated + 1) * sizeof (char *));
+ e->vector = vector;
+ }
+ vector[i + 1] = 0;
+ }
+ else
+ xfree (s);
+
+ s = (char *) xmalloc (len + strlen (value) + 2);
+ strcpy (s, var);
+ strcat (s, "=");
+ strcat (s, value);
+ vector[i] = s;
+
+ /* This used to handle setting the PATH and GNUTARGET variables
+ specially. The latter has been replaced by "set gnutarget"
+ (which has worked since GDB 4.11). The former affects searching
+ the PATH to find SHELL, and searching the PATH to find the
+ argument of "symbol-file" or "exec-file". Maybe we should have
+ some kind of "set exec-path" for that. But in any event, having
+ "set env" affect anything besides the inferior is a bad idea.
+ What if we want to change the environment we pass to the program
+ without afecting GDB's behavior? */
+
+ return;
+}
+
+/* Remove the setting for variable VAR from environment E. */
+
+void
+unset_in_environ (struct environ *e, char *var)
+{
+ register int len = strlen (var);
+ register char **vector = e->vector;
+ register char *s;
+
+ for (; (s = *vector) != NULL; vector++)
+ {
+ if (STREQN (s, var, len) && s[len] == '=')
+ {
+ xfree (s);
+ /* Walk through the vector, shuffling args down by one, including
+ the NULL terminator. Can't use memcpy() here since the regions
+ overlap, and memmove() might not be available. */
+ while ((vector[0] = vector[1]) != NULL)
+ {
+ vector++;
+ }
+ break;
+ }
+ }
+}
diff --git a/gdb/environ.h b/gdb/environ.h
new file mode 100644
index 00000000000..1aa13944518
--- /dev/null
+++ b/gdb/environ.h
@@ -0,0 +1,51 @@
+/* Header for environment manipulation library.
+ Copyright 1989, 1992, 2000 Free Software Foundation, Inc.
+
+ 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. */
+
+#if !defined (ENVIRON_H)
+#define ENVIRON_H 1
+
+/* We manipulate environments represented as these structures. */
+
+struct environ
+ {
+ /* Number of usable slots allocated in VECTOR.
+ VECTOR always has one slot not counted here,
+ to hold the terminating zero. */
+ int allocated;
+ /* A vector of slots, ALLOCATED + 1 of them.
+ The first few slots contain strings "VAR=VALUE"
+ and the next one contains zero.
+ Then come some unused slots. */
+ char **vector;
+ };
+
+extern struct environ *make_environ (void);
+
+extern void free_environ (struct environ *);
+
+extern void init_environ (struct environ *);
+
+extern char *get_in_environ (const struct environ *, const char *);
+
+extern void set_in_environ (struct environ *, const char *, const char *);
+
+extern void unset_in_environ (struct environ *, char *);
+
+extern char **environ_vector (struct environ *);
+
+#endif /* defined (ENVIRON_H) */
diff --git a/gdb/eval.c b/gdb/eval.c
new file mode 100644
index 00000000000..4ff210b08cf
--- /dev/null
+++ b/gdb/eval.c
@@ -0,0 +1,1979 @@
+/* Evaluate expressions for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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 "defs.h"
+#include "gdb_string.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "value.h"
+#include "expression.h"
+#include "target.h"
+#include "frame.h"
+#include "language.h" /* For CAST_IS_CONVERSION */
+#include "f-lang.h" /* for array bound stuff */
+#include "cp-abi.h"
+
+/* Defined in symtab.c */
+extern int hp_som_som_object_present;
+
+/* This is defined in valops.c */
+extern int overload_resolution;
+
+/* JYG: lookup rtti type of STRUCTOP_PTR when this is set to continue
+ on with successful lookup for member/method of the rtti type. */
+extern int objectprint;
+
+/* Prototypes for local functions. */
+
+static struct value *evaluate_subexp_for_sizeof (struct expression *, int *);
+
+static struct value *evaluate_subexp_for_address (struct expression *,
+ int *, enum noside);
+
+static struct value *evaluate_subexp (struct type *, struct expression *,
+ int *, enum noside);
+
+static char *get_label (struct expression *, int *);
+
+static struct value *evaluate_struct_tuple (struct value *,
+ struct expression *, int *,
+ enum noside, int);
+
+static LONGEST init_array_element (struct value *, struct value *,
+ struct expression *, int *, enum noside,
+ LONGEST, LONGEST);
+
+static struct value *
+evaluate_subexp (struct type *expect_type, register struct expression *exp,
+ register int *pos, enum noside noside)
+{
+ return (*exp->language_defn->evaluate_exp) (expect_type, exp, pos, noside);
+}
+
+/* Parse the string EXP as a C expression, evaluate it,
+ and return the result as a number. */
+
+CORE_ADDR
+parse_and_eval_address (char *exp)
+{
+ struct expression *expr = parse_expression (exp);
+ register CORE_ADDR addr;
+ register struct cleanup *old_chain =
+ make_cleanup (free_current_contents, &expr);
+
+ addr = value_as_address (evaluate_expression (expr));
+ do_cleanups (old_chain);
+ return addr;
+}
+
+/* Like parse_and_eval_address but takes a pointer to a char * variable
+ and advanced that variable across the characters parsed. */
+
+CORE_ADDR
+parse_and_eval_address_1 (char **expptr)
+{
+ struct expression *expr = parse_exp_1 (expptr, (struct block *) 0, 0);
+ register CORE_ADDR addr;
+ register struct cleanup *old_chain =
+ make_cleanup (free_current_contents, &expr);
+
+ addr = value_as_address (evaluate_expression (expr));
+ do_cleanups (old_chain);
+ return addr;
+}
+
+/* Like parse_and_eval_address, but treats the value of the expression
+ as an integer, not an address, returns a LONGEST, not a CORE_ADDR */
+LONGEST
+parse_and_eval_long (char *exp)
+{
+ struct expression *expr = parse_expression (exp);
+ register LONGEST retval;
+ register struct cleanup *old_chain =
+ make_cleanup (free_current_contents, &expr);
+
+ retval = value_as_long (evaluate_expression (expr));
+ do_cleanups (old_chain);
+ return (retval);
+}
+
+struct value *
+parse_and_eval (char *exp)
+{
+ struct expression *expr = parse_expression (exp);
+ struct value *val;
+ register struct cleanup *old_chain =
+ make_cleanup (free_current_contents, &expr);
+
+ val = evaluate_expression (expr);
+ do_cleanups (old_chain);
+ return val;
+}
+
+/* Parse up to a comma (or to a closeparen)
+ in the string EXPP as an expression, evaluate it, and return the value.
+ EXPP is advanced to point to the comma. */
+
+struct value *
+parse_to_comma_and_eval (char **expp)
+{
+ struct expression *expr = parse_exp_1 (expp, (struct block *) 0, 1);
+ struct value *val;
+ register struct cleanup *old_chain =
+ make_cleanup (free_current_contents, &expr);
+
+ val = evaluate_expression (expr);
+ do_cleanups (old_chain);
+ return val;
+}
+
+/* Evaluate an expression in internal prefix form
+ such as is constructed by parse.y.
+
+ See expression.h for info on the format of an expression. */
+
+struct value *
+evaluate_expression (struct expression *exp)
+{
+ int pc = 0;
+ return evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_NORMAL);
+}
+
+/* Evaluate an expression, avoiding all memory references
+ and getting a value whose type alone is correct. */
+
+struct value *
+evaluate_type (struct expression *exp)
+{
+ int pc = 0;
+ return evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_AVOID_SIDE_EFFECTS);
+}
+
+/* If the next expression is an OP_LABELED, skips past it,
+ returning the label. Otherwise, does nothing and returns NULL. */
+
+static char *
+get_label (register struct expression *exp, int *pos)
+{
+ 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);
+ return name;
+ }
+ else
+ return NULL;
+}
+
+/* This function evaluates tuples (in Chill) or brace-initializers
+ (in C/C++) for structure types. */
+
+static struct value *
+evaluate_struct_tuple (struct value *struct_val,
+ register struct expression *exp,
+ register int *pos, enum noside noside, int nargs)
+{
+ struct type *struct_type = check_typedef (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)
+ {
+ int pc = *pos;
+ struct value *val = NULL;
+ int nlabels = 0;
+ int bitpos, bitsize;
+ char *addr;
+
+ /* Skip past the labels, and count them. */
+ while (get_label (exp, pos) != NULL)
+ nlabels++;
+
+ 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 (field_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;
+}
+
+/* Recursive helper function for setting elements of array tuples for Chill.
+ The target is ARRAY (which has bounds LOW_BOUND to HIGH_BOUND);
+ the element value is ELEMENT;
+ EXP, POS and NOSIDE are as usual.
+ Evaluates index expresions and sets the specified element(s) of
+ ARRAY to ELEMENT.
+ Returns last index value. */
+
+static LONGEST
+init_array_element (struct value *array, struct value *element,
+ register struct expression *exp, register int *pos,
+ enum noside noside, LONGEST low_bound, LONGEST high_bound)
+{
+ LONGEST index;
+ int element_size = TYPE_LENGTH (VALUE_TYPE (element));
+ if (exp->elts[*pos].opcode == BINOP_COMMA)
+ {
+ (*pos)++;
+ init_array_element (array, element, exp, pos, noside,
+ low_bound, high_bound);
+ return init_array_element (array, element,
+ exp, pos, noside, low_bound, high_bound);
+ }
+ else if (exp->elts[*pos].opcode == BINOP_RANGE)
+ {
+ LONGEST low, high;
+ (*pos)++;
+ low = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+ high = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+ if (low < low_bound || high > high_bound)
+ error ("tuple range index out of range");
+ for (index = low; index <= high; index++)
+ {
+ memcpy (VALUE_CONTENTS_RAW (array)
+ + (index - low_bound) * element_size,
+ VALUE_CONTENTS (element), element_size);
+ }
+ }
+ else
+ {
+ index = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+ if (index < low_bound || index > high_bound)
+ error ("tuple index out of range");
+ memcpy (VALUE_CONTENTS_RAW (array) + (index - low_bound) * element_size,
+ VALUE_CONTENTS (element), element_size);
+ }
+ return index;
+}
+
+struct value *
+evaluate_subexp_standard (struct type *expect_type,
+ register struct expression *exp, register int *pos,
+ enum noside noside)
+{
+ enum exp_opcode op;
+ int tem, tem2, tem3;
+ register int pc, pc2 = 0, oldpos;
+ struct value *arg1 = NULL;
+ struct value *arg2 = NULL;
+ struct value *arg3;
+ struct type *type;
+ int nargs;
+ struct value **argvec;
+ int upper, lower, retcode;
+ int code;
+ int ix;
+ long mem_offset;
+ struct type **arg_types;
+ int save_pos1;
+
+ pc = (*pos)++;
+ op = exp->elts[pc].opcode;
+
+ switch (op)
+ {
+ case OP_SCOPE:
+ tem = longest_to_int (exp->elts[pc + 2].longconst);
+ (*pos) += 4 + BYTES_TO_EXP_ELEM (tem + 1);
+ arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type,
+ 0,
+ exp->elts[pc + 1].type,
+ &exp->elts[pc + 3].string,
+ NULL_TYPE);
+ if (arg1 == NULL)
+ error ("There is no field named %s", &exp->elts[pc + 3].string);
+ return arg1;
+
+ case OP_LONG:
+ (*pos) += 3;
+ return value_from_longest (exp->elts[pc + 1].type,
+ exp->elts[pc + 2].longconst);
+
+ case OP_DOUBLE:
+ (*pos) += 3;
+ return value_from_double (exp->elts[pc + 1].type,
+ exp->elts[pc + 2].doubleconst);
+
+ case OP_VAR_VALUE:
+ (*pos) += 3;
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+
+ /* JYG: We used to just return value_zero of the symbol type
+ if we're asked to avoid side effects. Otherwise we return
+ value_of_variable (...). However I'm not sure if
+ value_of_variable () has any side effect.
+ We need a full value object returned here for whatis_exp ()
+ to call evaluate_type () and then pass the full value to
+ value_rtti_target_type () if we are dealing with a pointer
+ or reference to a base class and print object is on. */
+
+ return value_of_variable (exp->elts[pc + 2].symbol,
+ exp->elts[pc + 1].block);
+
+ case OP_LAST:
+ (*pos) += 2;
+ return
+ access_value_history (longest_to_int (exp->elts[pc + 1].longconst));
+
+ case OP_REGISTER:
+ {
+ int regno = longest_to_int (exp->elts[pc + 1].longconst);
+ struct value *val = value_of_register (regno, selected_frame);
+ (*pos) += 2;
+ if (val == NULL)
+ error ("Value of register %s not available.", REGISTER_NAME (regno));
+ else
+ return val;
+ }
+ case OP_BOOL:
+ (*pos) += 2;
+ return value_from_longest (LA_BOOL_TYPE,
+ exp->elts[pc + 1].longconst);
+
+ case OP_INTERNALVAR:
+ (*pos) += 2;
+ return value_of_internalvar (exp->elts[pc + 1].internalvar);
+
+ case OP_STRING:
+ tem = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ return value_string (&exp->elts[pc + 2].string, tem);
+
+ case OP_BITSTRING:
+ tem = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos)
+ += 3 + BYTES_TO_EXP_ELEM ((tem + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ return value_bitstring (&exp->elts[pc + 2].string, tem);
+ break;
+
+ case OP_ARRAY:
+ (*pos) += 3;
+ tem2 = longest_to_int (exp->elts[pc + 1].longconst);
+ tem3 = longest_to_int (exp->elts[pc + 2].longconst);
+ nargs = tem3 - tem2 + 1;
+ type = expect_type ? check_typedef (expect_type) : NULL_TYPE;
+
+ if (expect_type != NULL_TYPE && noside != EVAL_SKIP
+ && TYPE_CODE (type) == TYPE_CODE_STRUCT)
+ {
+ struct value *rec = allocate_value (expect_type);
+ memset (VALUE_CONTENTS_RAW (rec), '\0', TYPE_LENGTH (type));
+ return evaluate_struct_tuple (rec, exp, pos, noside, nargs);
+ }
+
+ if (expect_type != NULL_TYPE && noside != EVAL_SKIP
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ struct type *range_type = TYPE_FIELD_TYPE (type, 0);
+ struct type *element_type = TYPE_TARGET_TYPE (type);
+ struct value *array = allocate_value (expect_type);
+ int element_size = TYPE_LENGTH (check_typedef (element_type));
+ LONGEST low_bound, high_bound, index;
+ if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+ {
+ low_bound = 0;
+ high_bound = (TYPE_LENGTH (type) / element_size) - 1;
+ }
+ index = low_bound;
+ memset (VALUE_CONTENTS_RAW (array), 0, TYPE_LENGTH (expect_type));
+ for (tem = nargs; --nargs >= 0;)
+ {
+ struct value *element;
+ int index_pc = 0;
+ if (exp->elts[*pos].opcode == BINOP_RANGE)
+ {
+ index_pc = ++(*pos);
+ evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
+ }
+ element = evaluate_subexp (element_type, exp, pos, noside);
+ if (VALUE_TYPE (element) != element_type)
+ element = value_cast (element_type, element);
+ if (index_pc)
+ {
+ int continue_pc = *pos;
+ *pos = index_pc;
+ index = init_array_element (array, element, exp, pos, noside,
+ low_bound, high_bound);
+ *pos = continue_pc;
+ }
+ else
+ {
+ if (index > high_bound)
+ /* to avoid memory corruption */
+ error ("Too many array elements");
+ memcpy (VALUE_CONTENTS_RAW (array)
+ + (index - low_bound) * element_size,
+ VALUE_CONTENTS (element),
+ element_size);
+ }
+ index++;
+ }
+ return array;
+ }
+
+ if (expect_type != NULL_TYPE && noside != EVAL_SKIP
+ && TYPE_CODE (type) == TYPE_CODE_SET)
+ {
+ struct value *set = allocate_value (expect_type);
+ char *valaddr = VALUE_CONTENTS_RAW (set);
+ struct type *element_type = TYPE_INDEX_TYPE (type);
+ struct type *check_type = element_type;
+ LONGEST low_bound, high_bound;
+
+ /* get targettype of elementtype */
+ while (TYPE_CODE (check_type) == TYPE_CODE_RANGE ||
+ TYPE_CODE (check_type) == TYPE_CODE_TYPEDEF)
+ check_type = TYPE_TARGET_TYPE (check_type);
+
+ if (get_discrete_bounds (element_type, &low_bound, &high_bound) < 0)
+ error ("(power)set type with unknown size");
+ memset (valaddr, '\0', TYPE_LENGTH (type));
+ for (tem = 0; tem < nargs; tem++)
+ {
+ LONGEST range_low, range_high;
+ struct type *range_low_type, *range_high_type;
+ struct value *elem_val;
+ if (exp->elts[*pos].opcode == BINOP_RANGE)
+ {
+ (*pos)++;
+ elem_val = evaluate_subexp (element_type, exp, pos, noside);
+ range_low_type = VALUE_TYPE (elem_val);
+ range_low = value_as_long (elem_val);
+ elem_val = evaluate_subexp (element_type, exp, pos, noside);
+ range_high_type = VALUE_TYPE (elem_val);
+ range_high = value_as_long (elem_val);
+ }
+ else
+ {
+ elem_val = evaluate_subexp (element_type, exp, pos, noside);
+ range_low_type = range_high_type = VALUE_TYPE (elem_val);
+ range_low = range_high = value_as_long (elem_val);
+ }
+ /* check types of elements to avoid mixture of elements from
+ different types. Also check if type of element is "compatible"
+ with element type of powerset */
+ if (TYPE_CODE (range_low_type) == TYPE_CODE_RANGE)
+ range_low_type = TYPE_TARGET_TYPE (range_low_type);
+ if (TYPE_CODE (range_high_type) == TYPE_CODE_RANGE)
+ range_high_type = TYPE_TARGET_TYPE (range_high_type);
+ if ((TYPE_CODE (range_low_type) != TYPE_CODE (range_high_type)) ||
+ (TYPE_CODE (range_low_type) == TYPE_CODE_ENUM &&
+ (range_low_type != range_high_type)))
+ /* different element modes */
+ error ("POWERSET tuple elements of different mode");
+ if ((TYPE_CODE (check_type) != TYPE_CODE (range_low_type)) ||
+ (TYPE_CODE (check_type) == TYPE_CODE_ENUM &&
+ range_low_type != check_type))
+ error ("incompatible POWERSET tuple elements");
+ if (range_low > range_high)
+ {
+ warning ("empty POWERSET tuple range");
+ continue;
+ }
+ if (range_low < low_bound || range_high > high_bound)
+ error ("POWERSET tuple element out of range");
+ range_low -= low_bound;
+ range_high -= low_bound;
+ for (; range_low <= range_high; range_low++)
+ {
+ int bit_index = (unsigned) range_low % TARGET_CHAR_BIT;
+ if (BITS_BIG_ENDIAN)
+ bit_index = TARGET_CHAR_BIT - 1 - bit_index;
+ valaddr[(unsigned) range_low / TARGET_CHAR_BIT]
+ |= 1 << bit_index;
+ }
+ }
+ return set;
+ }
+
+ argvec = (struct value **) alloca (sizeof (struct value *) * nargs);
+ for (tem = 0; tem < nargs; tem++)
+ {
+ /* Ensure that array expressions are coerced into pointer objects. */
+ argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
+ }
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ return value_array (tem2, tem3, argvec);
+
+ case TERNOP_SLICE:
+ {
+ struct value *array = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ int lowbound
+ = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+ int upper
+ = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ return value_slice (array, lowbound, upper - lowbound + 1);
+ }
+
+ case TERNOP_SLICE_COUNT:
+ {
+ struct value *array = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ int lowbound
+ = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+ int length
+ = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+ return value_slice (array, lowbound, length);
+ }
+
+ case TERNOP_COND:
+ /* Skip third and second args to evaluate the first one. */
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (value_logical_not (arg1))
+ {
+ evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
+ return evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ }
+ else
+ {
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
+ return arg2;
+ }
+
+ case OP_FUNCALL:
+ (*pos) += 2;
+ op = exp->elts[*pos].opcode;
+ nargs = longest_to_int (exp->elts[pc + 1].longconst);
+ /* Allocate arg vector, including space for the function to be
+ called in argvec[0] and a terminating NULL */
+ argvec = (struct value **) alloca (sizeof (struct value *) * (nargs + 3));
+ if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
+ {
+ LONGEST fnptr;
+
+ /* 1997-08-01 Currently we do not support function invocation
+ via pointers-to-methods with HP aCC. Pointer does not point
+ to the function, but possibly to some thunk. */
+ if (hp_som_som_object_present)
+ {
+ error ("Not implemented: function invocation through pointer to method with HP aCC");
+ }
+
+ nargs++;
+ /* First, evaluate the structure into arg2 */
+ pc2 = (*pos)++;
+
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+
+ if (op == STRUCTOP_MEMBER)
+ {
+ arg2 = evaluate_subexp_for_address (exp, pos, noside);
+ }
+ else
+ {
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ }
+
+ /* If the function is a virtual function, then the
+ aggregate value (providing the structure) plays
+ its part by providing the vtable. Otherwise,
+ it is just along for the ride: call the function
+ directly. */
+
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+ fnptr = value_as_long (arg1);
+
+ if (METHOD_PTR_IS_VIRTUAL (fnptr))
+ {
+ int fnoffset = METHOD_PTR_TO_VOFFSET (fnptr);
+ struct type *basetype;
+ struct type *domain_type =
+ TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)));
+ int i, j;
+ basetype = TYPE_TARGET_TYPE (VALUE_TYPE (arg2));
+ if (domain_type != basetype)
+ arg2 = value_cast (lookup_pointer_type (domain_type), arg2);
+ basetype = TYPE_VPTR_BASETYPE (domain_type);
+ for (i = TYPE_NFN_FIELDS (basetype) - 1; i >= 0; i--)
+ {
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (basetype, i);
+ /* If one is virtual, then all are virtual. */
+ if (TYPE_FN_FIELD_VIRTUAL_P (f, 0))
+ for (j = TYPE_FN_FIELDLIST_LENGTH (basetype, i) - 1; j >= 0; --j)
+ if ((int) TYPE_FN_FIELD_VOFFSET (f, j) == fnoffset)
+ {
+ struct value *temp = value_ind (arg2);
+ arg1 = value_virtual_fn_field (&temp, f, j, domain_type, 0);
+ arg2 = value_addr (temp);
+ goto got_it;
+ }
+ }
+ if (i < 0)
+ error ("virtual function at index %d not found", fnoffset);
+ }
+ else
+ {
+ VALUE_TYPE (arg1) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)));
+ }
+ got_it:
+
+ /* Now, say which argument to start evaluating from */
+ tem = 2;
+ }
+ else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
+ {
+ /* Hair for method invocations */
+ int tem2;
+
+ nargs++;
+ /* First, evaluate the structure into arg2 */
+ pc2 = (*pos)++;
+ tem2 = longest_to_int (exp->elts[pc2 + 1].longconst);
+ *pos += 3 + BYTES_TO_EXP_ELEM (tem2 + 1);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+
+ if (op == STRUCTOP_STRUCT)
+ {
+ /* If v is a variable in a register, and the user types
+ v.method (), this will produce an error, because v has
+ no address.
+
+ A possible way around this would be to allocate a
+ copy of the variable on the stack, copy in the
+ contents, call the function, and copy out the
+ contents. I.e. convert this from call by reference
+ to call by copy-return (or whatever it's called).
+ However, this does not work because it is not the
+ same: the method being called could stash a copy of
+ the address, and then future uses through that address
+ (after the method returns) would be expected to
+ use the variable itself, not some copy of it. */
+ arg2 = evaluate_subexp_for_address (exp, pos, noside);
+ }
+ else
+ {
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ }
+ /* Now, say which argument to start evaluating from */
+ tem = 2;
+ }
+ else
+ {
+ /* Non-method function call */
+ save_pos1 = *pos;
+ argvec[0] = evaluate_subexp_with_coercion (exp, pos, noside);
+ tem = 1;
+ type = VALUE_TYPE (argvec[0]);
+ if (type && TYPE_CODE (type) == TYPE_CODE_PTR)
+ type = TYPE_TARGET_TYPE (type);
+ if (type && TYPE_CODE (type) == TYPE_CODE_FUNC)
+ {
+ for (; tem <= nargs && tem <= TYPE_NFIELDS (type); tem++)
+ {
+ /* pai: FIXME This seems to be coercing arguments before
+ * overload resolution has been done! */
+ argvec[tem] = evaluate_subexp (TYPE_FIELD_TYPE (type, tem - 1),
+ exp, pos, noside);
+ }
+ }
+ }
+
+ /* Evaluate arguments */
+ for (; tem <= nargs; tem++)
+ {
+ /* Ensure that array expressions are coerced into pointer objects. */
+ argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
+ }
+
+ /* signal end of arglist */
+ argvec[tem] = 0;
+
+ if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
+ {
+ int static_memfuncp;
+ char tstr[256];
+
+ /* Method invocation : stuff "this" as first parameter */
+ argvec[1] = arg2;
+ /* Name of method from expression */
+ strcpy (tstr, &exp->elts[pc2 + 2].string);
+
+ if (overload_resolution && (exp->language_defn->la_language == language_cplus))
+ {
+ /* Language is C++, do some overload resolution before evaluation */
+ struct value *valp = NULL;
+
+ /* Prepare list of argument types for overload resolution */
+ arg_types = (struct type **) alloca (nargs * (sizeof (struct type *)));
+ for (ix = 1; ix <= nargs; ix++)
+ arg_types[ix - 1] = VALUE_TYPE (argvec[ix]);
+
+ (void) find_overload_match (arg_types, nargs, tstr,
+ 1 /* method */ , 0 /* strict match */ ,
+ &arg2 /* the object */ , NULL,
+ &valp, NULL, &static_memfuncp);
+
+
+ argvec[1] = arg2; /* the ``this'' pointer */
+ argvec[0] = valp; /* use the method found after overload resolution */
+ }
+ else
+ /* Non-C++ case -- or no overload resolution */
+ {
+ struct value *temp = arg2;
+ argvec[0] = value_struct_elt (&temp, argvec + 1, tstr,
+ &static_memfuncp,
+ op == STRUCTOP_STRUCT
+ ? "structure" : "structure pointer");
+ /* value_struct_elt updates temp with the correct value
+ of the ``this'' pointer if necessary, so modify argvec[1] to
+ reflect any ``this'' changes. */
+ arg2 = value_from_longest (lookup_pointer_type(VALUE_TYPE (temp)),
+ VALUE_ADDRESS (temp) + VALUE_OFFSET (temp)
+ + VALUE_EMBEDDED_OFFSET (temp));
+ argvec[1] = arg2; /* the ``this'' pointer */
+ }
+
+ if (static_memfuncp)
+ {
+ argvec[1] = argvec[0];
+ nargs--;
+ argvec++;
+ }
+ }
+ else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
+ {
+ argvec[1] = arg2;
+ argvec[0] = arg1;
+ }
+ else if (op == OP_VAR_VALUE)
+ {
+ /* Non-member function being called */
+ /* fn: This can only be done for C++ functions. A C-style function
+ in a C++ program, for instance, does not have the fields that
+ are expected here */
+
+ if (overload_resolution && (exp->language_defn->la_language == language_cplus))
+ {
+ /* Language is C++, do some overload resolution before evaluation */
+ struct symbol *symp;
+
+ /* Prepare list of argument types for overload resolution */
+ arg_types = (struct type **) alloca (nargs * (sizeof (struct type *)));
+ for (ix = 1; ix <= nargs; ix++)
+ arg_types[ix - 1] = VALUE_TYPE (argvec[ix]);
+
+ (void) find_overload_match (arg_types, nargs, NULL /* no need for name */ ,
+ 0 /* not method */ , 0 /* strict match */ ,
+ NULL, exp->elts[save_pos1+2].symbol /* the function */ ,
+ NULL, &symp, NULL);
+
+ /* Now fix the expression being evaluated */
+ exp->elts[save_pos1+2].symbol = symp;
+ argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, noside);
+ }
+ else
+ {
+ /* Not C++, or no overload resolution allowed */
+ /* nothing to be done; argvec already correctly set up */
+ }
+ }
+ else
+ {
+ /* It is probably a C-style function */
+ /* nothing to be done; argvec already correctly set up */
+ }
+
+ do_call_it:
+
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (argvec[0] == NULL)
+ error ("Cannot evaluate function -- may be inlined");
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ /* If the return type doesn't look like a function type, call an
+ error. This can happen if somebody tries to turn a variable into
+ a function call. This is here because people often want to
+ call, eg, strcmp, which gdb doesn't know is a function. If
+ gdb isn't asked for it's opinion (ie. through "whatis"),
+ it won't offer it. */
+
+ struct type *ftype =
+ TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0]));
+
+ if (ftype)
+ return allocate_value (TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0])));
+ else
+ error ("Expression of type other than \"Function returning ...\" used as function");
+ }
+ return call_function_by_hand (argvec[0], nargs, argvec + 1);
+ /* pai: FIXME save value from call_function_by_hand, then adjust pc by adjust_fn_pc if +ve */
+
+ case OP_F77_UNDETERMINED_ARGLIST:
+
+ /* Remember that in F77, functions, substring ops and
+ array subscript operations cannot be disambiguated
+ at parse time. We have made all array subscript operations,
+ substring operations as well as function calls come here
+ and we now have to discover what the heck this thing actually was.
+ If it is a function, we process just as if we got an OP_FUNCALL. */
+
+ nargs = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 2;
+
+ /* First determine the type code we are dealing with. */
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ type = check_typedef (VALUE_TYPE (arg1));
+ code = TYPE_CODE (type);
+
+ switch (code)
+ {
+ case TYPE_CODE_ARRAY:
+ goto multi_f77_subscript;
+
+ case TYPE_CODE_STRING:
+ goto op_f77_substr;
+
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_FUNC:
+ /* It's a function call. */
+ /* Allocate arg vector, including space for the function to be
+ called in argvec[0] and a terminating NULL */
+ argvec = (struct value **) alloca (sizeof (struct value *) * (nargs + 2));
+ argvec[0] = arg1;
+ tem = 1;
+ for (; tem <= nargs; tem++)
+ argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
+ argvec[tem] = 0; /* signal end of arglist */
+ goto do_call_it;
+
+ default:
+ error ("Cannot perform substring on this type");
+ }
+
+ op_f77_substr:
+ /* We have a substring operation on our hands here,
+ let us get the string we will be dealing with */
+
+ /* Now evaluate the 'from' and 'to' */
+
+ arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+
+ if (nargs < 2)
+ return value_subscript (arg1, arg2);
+
+ arg3 = evaluate_subexp_with_coercion (exp, pos, noside);
+
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+
+ tem2 = value_as_long (arg2);
+ tem3 = value_as_long (arg3);
+
+ return value_slice (arg1, tem2, tem3 - tem2 + 1);
+
+ case OP_COMPLEX:
+ /* We have a complex number, There should be 2 floating
+ point numbers that compose it */
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+ return value_literal_complex (arg1, arg2, builtin_type_f_complex_s16);
+
+ case STRUCTOP_STRUCT:
+ tem = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (lookup_struct_elt_type (VALUE_TYPE (arg1),
+ &exp->elts[pc + 2].string,
+ 0),
+ lval_memory);
+ else
+ {
+ struct value *temp = arg1;
+ return value_struct_elt (&temp, NULL, &exp->elts[pc + 2].string,
+ NULL, "structure");
+ }
+
+ case STRUCTOP_PTR:
+ tem = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+
+ /* JYG: if print object is on we need to replace the base type
+ with rtti type in order to continue on with successful
+ lookup of member / method only available in the rtti type. */
+ {
+ struct type *type = VALUE_TYPE (arg1);
+ struct type *real_type;
+ int full, top, using_enc;
+
+ if (objectprint && TYPE_TARGET_TYPE(type) &&
+ (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
+ {
+ real_type = value_rtti_target_type (arg1, &full, &top, &using_enc);
+ if (real_type)
+ {
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ real_type = lookup_pointer_type (real_type);
+ else
+ real_type = lookup_reference_type (real_type);
+
+ arg1 = value_cast (real_type, arg1);
+ }
+ }
+ }
+
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (lookup_struct_elt_type (VALUE_TYPE (arg1),
+ &exp->elts[pc + 2].string,
+ 0),
+ lval_memory);
+ else
+ {
+ struct value *temp = arg1;
+ return value_struct_elt (&temp, NULL, &exp->elts[pc + 2].string,
+ NULL, "structure pointer");
+ }
+
+ case STRUCTOP_MEMBER:
+ arg1 = evaluate_subexp_for_address (exp, pos, noside);
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+ /* With HP aCC, pointers to methods do not point to the function code */
+ if (hp_som_som_object_present &&
+ (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_PTR) &&
+ (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) == TYPE_CODE_METHOD))
+ error ("Pointers to methods not supported with HP aCC"); /* 1997-08-19 */
+
+ mem_offset = value_as_long (arg2);
+ goto handle_pointer_to_member;
+
+ case STRUCTOP_MPTR:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+ /* With HP aCC, pointers to methods do not point to the function code */
+ if (hp_som_som_object_present &&
+ (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_PTR) &&
+ (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) == TYPE_CODE_METHOD))
+ error ("Pointers to methods not supported with HP aCC"); /* 1997-08-19 */
+
+ mem_offset = value_as_long (arg2);
+
+ handle_pointer_to_member:
+ /* HP aCC generates offsets that have bit #29 set; turn it off to get
+ a real offset to the member. */
+ if (hp_som_som_object_present)
+ {
+ if (!mem_offset) /* no bias -> really null */
+ error ("Attempted dereference of null pointer-to-member");
+ mem_offset &= ~0x20000000;
+ }
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ type = check_typedef (VALUE_TYPE (arg2));
+ if (TYPE_CODE (type) != TYPE_CODE_PTR)
+ goto bad_pointer_to_member;
+ type = check_typedef (TYPE_TARGET_TYPE (type));
+ if (TYPE_CODE (type) == TYPE_CODE_METHOD)
+ error ("not implemented: pointer-to-method in pointer-to-member construct");
+ if (TYPE_CODE (type) != TYPE_CODE_MEMBER)
+ goto bad_pointer_to_member;
+ /* Now, convert these values to an address. */
+ arg1 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)),
+ arg1);
+ arg3 = value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
+ value_as_long (arg1) + mem_offset);
+ return value_ind (arg3);
+ bad_pointer_to_member:
+ error ("non-pointer-to-member value used in pointer-to-member construct");
+
+ case BINOP_CONCAT:
+ arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+ arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (binop_user_defined_p (op, arg1, arg2))
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ else
+ return value_concat (arg1, arg2);
+
+ case BINOP_ASSIGN:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
+
+ /* Do special stuff for HP aCC pointers to members */
+ if (hp_som_som_object_present)
+ {
+ /* 1997-08-19 Can't assign HP aCC pointers to methods. No details of
+ the implementation yet; but the pointer appears to point to a code
+ sequence (thunk) in memory -- in any case it is *not* the address
+ of the function as it would be in a naive implementation. */
+ if ((TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR) &&
+ (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_METHOD))
+ error ("Assignment to pointers to methods not implemented with HP aCC");
+
+ /* HP aCC pointers to data members require a constant bias */
+ if ((TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR) &&
+ (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_MEMBER))
+ {
+ unsigned int *ptr = (unsigned int *) VALUE_CONTENTS (arg2); /* forces evaluation */
+ *ptr |= 0x20000000; /* set 29th bit */
+ }
+ }
+
+ if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+ return arg1;
+ if (binop_user_defined_p (op, arg1, arg2))
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ else
+ return value_assign (arg1, arg2);
+
+ case BINOP_ASSIGN_MODIFY:
+ (*pos) += 2;
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
+ if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+ return arg1;
+ op = exp->elts[pc + 1].opcode;
+ if (binop_user_defined_p (op, arg1, arg2))
+ return value_x_binop (arg1, arg2, BINOP_ASSIGN_MODIFY, op, noside);
+ else if (op == BINOP_ADD)
+ arg2 = value_add (arg1, arg2);
+ else if (op == BINOP_SUB)
+ arg2 = value_sub (arg1, arg2);
+ else
+ arg2 = value_binop (arg1, arg2, op);
+ return value_assign (arg1, arg2);
+
+ case BINOP_ADD:
+ arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+ arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (binop_user_defined_p (op, arg1, arg2))
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ else
+ return value_add (arg1, arg2);
+
+ case BINOP_SUB:
+ arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+ arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (binop_user_defined_p (op, arg1, arg2))
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ else
+ return value_sub (arg1, arg2);
+
+ case BINOP_MUL:
+ case BINOP_DIV:
+ case BINOP_REM:
+ case BINOP_MOD:
+ case BINOP_LSH:
+ case BINOP_RSH:
+ case BINOP_BITWISE_AND:
+ case BINOP_BITWISE_IOR:
+ case BINOP_BITWISE_XOR:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (binop_user_defined_p (op, arg1, arg2))
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ else if (noside == EVAL_AVOID_SIDE_EFFECTS
+ && (op == BINOP_DIV || op == BINOP_REM || op == BINOP_MOD))
+ return value_zero (VALUE_TYPE (arg1), not_lval);
+ else
+ return value_binop (arg1, arg2, op);
+
+ case BINOP_RANGE:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ error ("':' operator used in invalid context");
+
+ case BINOP_SUBSCRIPT:
+ arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+ arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (binop_user_defined_p (op, arg1, arg2))
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ else
+ {
+ /* If the user attempts to subscript something that is not an
+ array or pointer type (like a plain int variable for example),
+ then report this as an error. */
+
+ COERCE_REF (arg1);
+ type = check_typedef (VALUE_TYPE (arg1));
+ if (TYPE_CODE (type) != TYPE_CODE_ARRAY
+ && TYPE_CODE (type) != TYPE_CODE_PTR)
+ {
+ if (TYPE_NAME (type))
+ error ("cannot subscript something of type `%s'",
+ TYPE_NAME (type));
+ else
+ error ("cannot subscript requested type");
+ }
+
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1));
+ else
+ return value_subscript (arg1, arg2);
+ }
+
+ case BINOP_IN:
+ arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+ arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ return value_in (arg1, arg2);
+
+ case MULTI_SUBSCRIPT:
+ (*pos) += 2;
+ nargs = longest_to_int (exp->elts[pc + 1].longconst);
+ arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+ while (nargs-- > 0)
+ {
+ arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+ /* FIXME: EVAL_SKIP handling may not be correct. */
+ if (noside == EVAL_SKIP)
+ {
+ if (nargs > 0)
+ {
+ continue;
+ }
+ else
+ {
+ goto nosideret;
+ }
+ }
+ /* FIXME: EVAL_AVOID_SIDE_EFFECTS handling may not be correct. */
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ /* If the user attempts to subscript something that has no target
+ type (like a plain int variable for example), then report this
+ as an error. */
+
+ type = TYPE_TARGET_TYPE (check_typedef (VALUE_TYPE (arg1)));
+ if (type != NULL)
+ {
+ arg1 = value_zero (type, VALUE_LVAL (arg1));
+ noside = EVAL_SKIP;
+ continue;
+ }
+ else
+ {
+ error ("cannot subscript something of type `%s'",
+ TYPE_NAME (VALUE_TYPE (arg1)));
+ }
+ }
+
+ if (binop_user_defined_p (op, arg1, arg2))
+ {
+ arg1 = value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ }
+ else
+ {
+ arg1 = value_subscript (arg1, arg2);
+ }
+ }
+ return (arg1);
+
+ multi_f77_subscript:
+ {
+ int subscript_array[MAX_FORTRAN_DIMS + 1]; /* 1-based array of
+ subscripts, max == 7 */
+ int array_size_array[MAX_FORTRAN_DIMS + 1];
+ int ndimensions = 1, i;
+ struct type *tmp_type;
+ int offset_item; /* The array offset where the item lives */
+
+ if (nargs > MAX_FORTRAN_DIMS)
+ error ("Too many subscripts for F77 (%d Max)", MAX_FORTRAN_DIMS);
+
+ tmp_type = check_typedef (VALUE_TYPE (arg1));
+ ndimensions = calc_f77_array_dims (type);
+
+ if (nargs != ndimensions)
+ error ("Wrong number of subscripts");
+
+ /* Now that we know we have a legal array subscript expression
+ let us actually find out where this element exists in the array. */
+
+ offset_item = 0;
+ for (i = 1; i <= nargs; i++)
+ {
+ /* Evaluate each subscript, It must be a legal integer in F77 */
+ arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+
+ /* Fill in the subscript and array size arrays */
+
+ subscript_array[i] = value_as_long (arg2);
+
+ retcode = f77_get_dynamic_upperbound (tmp_type, &upper);
+ if (retcode == BOUND_FETCH_ERROR)
+ error ("Cannot obtain dynamic upper bound");
+
+ retcode = f77_get_dynamic_lowerbound (tmp_type, &lower);
+ if (retcode == BOUND_FETCH_ERROR)
+ error ("Cannot obtain dynamic lower bound");
+
+ array_size_array[i] = upper - lower + 1;
+
+ /* Zero-normalize subscripts so that offsetting will work. */
+
+ subscript_array[i] -= lower;
+
+ /* If we are at the bottom of a multidimensional
+ array type then keep a ptr to the last ARRAY
+ type around for use when calling value_subscript()
+ below. This is done because we pretend to value_subscript
+ that we actually have a one-dimensional array
+ of base element type that we apply a simple
+ offset to. */
+
+ if (i < nargs)
+ tmp_type = check_typedef (TYPE_TARGET_TYPE (tmp_type));
+ }
+
+ /* Now let us calculate the offset for this item */
+
+ offset_item = subscript_array[ndimensions];
+
+ for (i = ndimensions - 1; i >= 1; i--)
+ offset_item =
+ array_size_array[i] * offset_item + subscript_array[i];
+
+ /* Construct a value node with the value of the offset */
+
+ arg2 = value_from_longest (builtin_type_f_integer, offset_item);
+
+ /* Let us now play a dirty trick: we will take arg1
+ which is a value node pointing to the topmost level
+ of the multidimensional array-set and pretend
+ that it is actually a array of the final element
+ type, this will ensure that value_subscript()
+ returns the correct type value */
+
+ VALUE_TYPE (arg1) = tmp_type;
+ return value_ind (value_add (value_coerce_array (arg1), arg2));
+ }
+
+ case BINOP_LOGICAL_AND:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ {
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ goto nosideret;
+ }
+
+ oldpos = *pos;
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+ *pos = oldpos;
+
+ if (binop_user_defined_p (op, arg1, arg2))
+ {
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ }
+ else
+ {
+ tem = value_logical_not (arg1);
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos,
+ (tem ? EVAL_SKIP : noside));
+ return value_from_longest (LA_BOOL_TYPE,
+ (LONGEST) (!tem && !value_logical_not (arg2)));
+ }
+
+ case BINOP_LOGICAL_OR:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ {
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ goto nosideret;
+ }
+
+ oldpos = *pos;
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+ *pos = oldpos;
+
+ if (binop_user_defined_p (op, arg1, arg2))
+ {
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ }
+ else
+ {
+ tem = value_logical_not (arg1);
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos,
+ (!tem ? EVAL_SKIP : noside));
+ return value_from_longest (LA_BOOL_TYPE,
+ (LONGEST) (!tem || !value_logical_not (arg2)));
+ }
+
+ case BINOP_EQUAL:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (binop_user_defined_p (op, arg1, arg2))
+ {
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ }
+ else
+ {
+ tem = value_equal (arg1, arg2);
+ return value_from_longest (LA_BOOL_TYPE, (LONGEST) tem);
+ }
+
+ case BINOP_NOTEQUAL:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (binop_user_defined_p (op, arg1, arg2))
+ {
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ }
+ else
+ {
+ tem = value_equal (arg1, arg2);
+ return value_from_longest (LA_BOOL_TYPE, (LONGEST) ! tem);
+ }
+
+ case BINOP_LESS:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (binop_user_defined_p (op, arg1, arg2))
+ {
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ }
+ else
+ {
+ tem = value_less (arg1, arg2);
+ return value_from_longest (LA_BOOL_TYPE, (LONGEST) tem);
+ }
+
+ case BINOP_GTR:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (binop_user_defined_p (op, arg1, arg2))
+ {
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ }
+ else
+ {
+ tem = value_less (arg2, arg1);
+ return value_from_longest (LA_BOOL_TYPE, (LONGEST) tem);
+ }
+
+ case BINOP_GEQ:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (binop_user_defined_p (op, arg1, arg2))
+ {
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ }
+ else
+ {
+ tem = value_less (arg2, arg1) || value_equal (arg1, arg2);
+ return value_from_longest (LA_BOOL_TYPE, (LONGEST) tem);
+ }
+
+ case BINOP_LEQ:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (binop_user_defined_p (op, arg1, arg2))
+ {
+ return value_x_binop (arg1, arg2, op, OP_NULL, noside);
+ }
+ else
+ {
+ tem = value_less (arg1, arg2) || value_equal (arg1, arg2);
+ return value_from_longest (LA_BOOL_TYPE, (LONGEST) tem);
+ }
+
+ case BINOP_REPEAT:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ type = check_typedef (VALUE_TYPE (arg2));
+ if (TYPE_CODE (type) != TYPE_CODE_INT)
+ error ("Non-integral right operand for \"@\" operator.");
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ return allocate_repeat_value (VALUE_TYPE (arg1),
+ longest_to_int (value_as_long (arg2)));
+ }
+ else
+ return value_repeat (arg1, longest_to_int (value_as_long (arg2)));
+
+ case BINOP_COMMA:
+ evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ return evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+ case UNOP_NEG:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (unop_user_defined_p (op, arg1))
+ return value_x_unop (arg1, op, noside);
+ else
+ return value_neg (arg1);
+
+ case UNOP_COMPLEMENT:
+ /* C++: check for and handle destructor names. */
+ op = exp->elts[*pos].opcode;
+
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (unop_user_defined_p (UNOP_COMPLEMENT, arg1))
+ return value_x_unop (arg1, UNOP_COMPLEMENT, noside);
+ else
+ return value_complement (arg1);
+
+ case UNOP_LOGICAL_NOT:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (unop_user_defined_p (op, arg1))
+ return value_x_unop (arg1, op, noside);
+ else
+ return value_from_longest (LA_BOOL_TYPE,
+ (LONGEST) value_logical_not (arg1));
+
+ case UNOP_IND:
+ if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_PTR)
+ expect_type = TYPE_TARGET_TYPE (check_typedef (expect_type));
+ arg1 = evaluate_subexp (expect_type, exp, pos, noside);
+ if ((TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) &&
+ ((TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_METHOD) ||
+ (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_MEMBER)))
+ error ("Attempt to dereference pointer to member without an object");
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (unop_user_defined_p (op, arg1))
+ return value_x_unop (arg1, op, noside);
+ else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ type = check_typedef (VALUE_TYPE (arg1));
+ if (TYPE_CODE (type) == TYPE_CODE_PTR
+ || TYPE_CODE (type) == TYPE_CODE_REF
+ /* In C you can dereference an array to get the 1st elt. */
+ || TYPE_CODE (type) == TYPE_CODE_ARRAY
+ )
+ return value_zero (TYPE_TARGET_TYPE (type),
+ lval_memory);
+ else if (TYPE_CODE (type) == TYPE_CODE_INT)
+ /* GDB allows dereferencing an int. */
+ return value_zero (builtin_type_int, lval_memory);
+ else
+ error ("Attempt to take contents of a non-pointer value.");
+ }
+ return value_ind (arg1);
+
+ case UNOP_ADDR:
+ /* C++: check for and handle pointer to members. */
+
+ op = exp->elts[*pos].opcode;
+
+ if (noside == EVAL_SKIP)
+ {
+ if (op == OP_SCOPE)
+ {
+ int temm = longest_to_int (exp->elts[pc + 3].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (temm + 1);
+ }
+ else
+ evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
+ goto nosideret;
+ }
+ else
+ {
+ struct value *retvalp = evaluate_subexp_for_address (exp, pos, noside);
+ /* If HP aCC object, use bias for pointers to members */
+ if (hp_som_som_object_present &&
+ (TYPE_CODE (VALUE_TYPE (retvalp)) == TYPE_CODE_PTR) &&
+ (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (retvalp))) == TYPE_CODE_MEMBER))
+ {
+ unsigned int *ptr = (unsigned int *) VALUE_CONTENTS (retvalp); /* forces evaluation */
+ *ptr |= 0x20000000; /* set 29th bit */
+ }
+ return retvalp;
+ }
+
+ case UNOP_SIZEOF:
+ if (noside == EVAL_SKIP)
+ {
+ evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
+ goto nosideret;
+ }
+ return evaluate_subexp_for_sizeof (exp, pos);
+
+ case UNOP_CAST:
+ (*pos) += 2;
+ type = exp->elts[pc + 1].type;
+ arg1 = evaluate_subexp (type, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (type != VALUE_TYPE (arg1))
+ arg1 = value_cast (type, arg1);
+ return arg1;
+
+ case UNOP_MEMVAL:
+ (*pos) += 2;
+ arg1 = evaluate_subexp (expect_type, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (exp->elts[pc + 1].type, lval_memory);
+ else
+ return value_at_lazy (exp->elts[pc + 1].type,
+ value_as_address (arg1),
+ NULL);
+
+ case UNOP_PREINCREMENT:
+ arg1 = evaluate_subexp (expect_type, exp, pos, noside);
+ if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+ return arg1;
+ else if (unop_user_defined_p (op, arg1))
+ {
+ return value_x_unop (arg1, op, noside);
+ }
+ else
+ {
+ arg2 = value_add (arg1, value_from_longest (builtin_type_char,
+ (LONGEST) 1));
+ return value_assign (arg1, arg2);
+ }
+
+ case UNOP_PREDECREMENT:
+ arg1 = evaluate_subexp (expect_type, exp, pos, noside);
+ if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+ return arg1;
+ else if (unop_user_defined_p (op, arg1))
+ {
+ return value_x_unop (arg1, op, noside);
+ }
+ else
+ {
+ arg2 = value_sub (arg1, value_from_longest (builtin_type_char,
+ (LONGEST) 1));
+ return value_assign (arg1, arg2);
+ }
+
+ case UNOP_POSTINCREMENT:
+ arg1 = evaluate_subexp (expect_type, exp, pos, noside);
+ if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+ return arg1;
+ else if (unop_user_defined_p (op, arg1))
+ {
+ return value_x_unop (arg1, op, noside);
+ }
+ else
+ {
+ arg2 = value_add (arg1, value_from_longest (builtin_type_char,
+ (LONGEST) 1));
+ value_assign (arg1, arg2);
+ return arg1;
+ }
+
+ case UNOP_POSTDECREMENT:
+ arg1 = evaluate_subexp (expect_type, exp, pos, noside);
+ if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+ return arg1;
+ else if (unop_user_defined_p (op, arg1))
+ {
+ return value_x_unop (arg1, op, noside);
+ }
+ else
+ {
+ arg2 = value_sub (arg1, value_from_longest (builtin_type_char,
+ (LONGEST) 1));
+ value_assign (arg1, arg2);
+ return arg1;
+ }
+
+ case OP_THIS:
+ (*pos) += 1;
+ return value_of_this (1);
+
+ case OP_TYPE:
+ error ("Attempt to use a type name as an expression");
+
+ default:
+ /* Removing this case and compiling with gcc -Wall reveals that
+ a lot of cases are hitting this case. Some of these should
+ probably be removed from expression.h; others are legitimate
+ expressions which are (apparently) not fully implemented.
+
+ If there are any cases landing here which mean a user error,
+ then they should be separate cases, with more descriptive
+ error messages. */
+
+ error ("\
+GDB does not (yet) know how to evaluate that kind of expression");
+ }
+
+nosideret:
+ return value_from_longest (builtin_type_long, (LONGEST) 1);
+}
+
+/* Evaluate a subexpression of EXP, at index *POS,
+ and return the address of that subexpression.
+ Advance *POS over the subexpression.
+ If the subexpression isn't an lvalue, get an error.
+ NOSIDE may be EVAL_AVOID_SIDE_EFFECTS;
+ then only the type of the result need be correct. */
+
+static struct value *
+evaluate_subexp_for_address (register struct expression *exp, register int *pos,
+ enum noside noside)
+{
+ enum exp_opcode op;
+ register int pc;
+ struct symbol *var;
+
+ pc = (*pos);
+ op = exp->elts[pc].opcode;
+
+ switch (op)
+ {
+ case UNOP_IND:
+ (*pos)++;
+ return evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+ case UNOP_MEMVAL:
+ (*pos) += 3;
+ return value_cast (lookup_pointer_type (exp->elts[pc + 1].type),
+ evaluate_subexp (NULL_TYPE, exp, pos, noside));
+
+ case OP_VAR_VALUE:
+ var = exp->elts[pc + 2].symbol;
+
+ /* C++: The "address" of a reference should yield the address
+ * of the object pointed to. Let value_addr() deal with it. */
+ if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_REF)
+ goto default_case;
+
+ (*pos) += 4;
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ struct type *type =
+ lookup_pointer_type (SYMBOL_TYPE (var));
+ enum address_class sym_class = SYMBOL_CLASS (var);
+
+ if (sym_class == LOC_CONST
+ || sym_class == LOC_CONST_BYTES
+ || sym_class == LOC_REGISTER
+ || sym_class == LOC_REGPARM)
+ error ("Attempt to take address of register or constant.");
+
+ return
+ value_zero (type, not_lval);
+ }
+ else
+ return
+ locate_var_value
+ (var,
+ block_innermost_frame (exp->elts[pc + 1].block));
+
+ default:
+ default_case:
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ struct value *x = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (VALUE_LVAL (x) == lval_memory)
+ return value_zero (lookup_pointer_type (VALUE_TYPE (x)),
+ not_lval);
+ else
+ error ("Attempt to take address of non-lval");
+ }
+ return value_addr (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+ }
+}
+
+/* Evaluate like `evaluate_subexp' except coercing arrays to pointers.
+ When used in contexts where arrays will be coerced anyway, this is
+ equivalent to `evaluate_subexp' but much faster because it avoids
+ actually fetching array contents (perhaps obsolete now that we have
+ VALUE_LAZY).
+
+ Note that we currently only do the coercion for C expressions, where
+ arrays are zero based and the coercion is correct. For other languages,
+ with nonzero based arrays, coercion loses. Use CAST_IS_CONVERSION
+ to decide if coercion is appropriate.
+
+ */
+
+struct value *
+evaluate_subexp_with_coercion (register struct expression *exp,
+ register int *pos, enum noside noside)
+{
+ register enum exp_opcode op;
+ register int pc;
+ struct value *val;
+ struct symbol *var;
+
+ pc = (*pos);
+ op = exp->elts[pc].opcode;
+
+ switch (op)
+ {
+ case OP_VAR_VALUE:
+ var = exp->elts[pc + 2].symbol;
+ if (TYPE_CODE (check_typedef (SYMBOL_TYPE (var))) == TYPE_CODE_ARRAY
+ && CAST_IS_CONVERSION)
+ {
+ (*pos) += 4;
+ val =
+ locate_var_value
+ (var, block_innermost_frame (exp->elts[pc + 1].block));
+ return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (check_typedef (SYMBOL_TYPE (var)))),
+ val);
+ }
+ /* FALLTHROUGH */
+
+ default:
+ return evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ }
+}
+
+/* Evaluate a subexpression of EXP, at index *POS,
+ and return a value for the size of that subexpression.
+ Advance *POS over the subexpression. */
+
+static struct value *
+evaluate_subexp_for_sizeof (register struct expression *exp, register int *pos)
+{
+ enum exp_opcode op;
+ register int pc;
+ struct type *type;
+ struct value *val;
+
+ pc = (*pos);
+ op = exp->elts[pc].opcode;
+
+ switch (op)
+ {
+ /* This case is handled specially
+ so that we avoid creating a value for the result type.
+ If the result type is very big, it's desirable not to
+ create a value unnecessarily. */
+ case UNOP_IND:
+ (*pos)++;
+ val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+ type = check_typedef (VALUE_TYPE (val));
+ if (TYPE_CODE (type) != TYPE_CODE_PTR
+ && TYPE_CODE (type) != TYPE_CODE_REF
+ && TYPE_CODE (type) != TYPE_CODE_ARRAY)
+ error ("Attempt to take contents of a non-pointer value.");
+ type = check_typedef (TYPE_TARGET_TYPE (type));
+ return value_from_longest (builtin_type_int, (LONGEST)
+ TYPE_LENGTH (type));
+
+ case UNOP_MEMVAL:
+ (*pos) += 3;
+ type = check_typedef (exp->elts[pc + 1].type);
+ return value_from_longest (builtin_type_int,
+ (LONGEST) TYPE_LENGTH (type));
+
+ case OP_VAR_VALUE:
+ (*pos) += 4;
+ type = check_typedef (SYMBOL_TYPE (exp->elts[pc + 2].symbol));
+ return
+ value_from_longest (builtin_type_int, (LONGEST) TYPE_LENGTH (type));
+
+ default:
+ val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+ return value_from_longest (builtin_type_int,
+ (LONGEST) TYPE_LENGTH (VALUE_TYPE (val)));
+ }
+}
+
+/* Parse a type expression in the string [P..P+LENGTH). */
+
+struct type *
+parse_and_eval_type (char *p, int length)
+{
+ char *tmp = (char *) alloca (length + 4);
+ struct expression *expr;
+ tmp[0] = '(';
+ memcpy (tmp + 1, p, length);
+ tmp[length + 1] = ')';
+ tmp[length + 2] = '0';
+ tmp[length + 3] = '\0';
+ expr = parse_expression (tmp);
+ if (expr->elts[0].opcode != UNOP_CAST)
+ error ("Internal error in eval_type.");
+ return expr->elts[1].type;
+}
+
+int
+calc_f77_array_dims (struct type *array_type)
+{
+ int ndimen = 1;
+ struct type *tmp_type;
+
+ if ((TYPE_CODE (array_type) != TYPE_CODE_ARRAY))
+ error ("Can't get dimensions for a non-array type");
+
+ tmp_type = array_type;
+
+ while ((tmp_type = TYPE_TARGET_TYPE (tmp_type)))
+ {
+ if (TYPE_CODE (tmp_type) == TYPE_CODE_ARRAY)
+ ++ndimen;
+ }
+ return ndimen;
+}
diff --git a/gdb/event-loop.h b/gdb/event-loop.h
new file mode 100644
index 00000000000..2f2ff003f6a
--- /dev/null
+++ b/gdb/event-loop.h
@@ -0,0 +1,95 @@
+/* Definitions used by the GDB event loop.
+ Copyright 1999, 2000 Free Software Foundation, Inc.
+ Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
+
+ 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. */
+
+/* An event loop listens for events from multiple event sources. When
+ an event arrives, it is queued and processed by calling the
+ appropriate event handler. The event loop then continues to listen
+ for more events. An event loop completes when there are no event
+ sources to listen on. External event sources can be plugged into
+ the loop.
+
+ There are 3 main components:
+ - a list of file descriptors to be monitored, GDB_NOTIFIER.
+ - a list of events that have occurred, EVENT_QUEUE.
+ - a list of signal handling functions, SIGHANDLER_LIST.
+
+ GDB_NOTIFIER keeps track of the event sources. Event sources for
+ gdb are currently the UI and the target. Gdb communicates with the
+ command line user interface via the readline library and usually
+ communicates with remote targets via a serial port. Serial ports
+ are represented in GDB as file descriptors and select/poll calls.
+ For native targets instead, the communication consists of calls to
+ ptrace and waits (via signals) or calls to poll/select (via file
+ descriptors). In the current gdb, the code handling events related
+ to the target resides in the wait_for_inferior function and in
+ various target specific files (*-tdep.c).
+
+ EVENT_QUEUE keeps track of the events that have happened during the
+ last iteration of the event loop, and need to be processed. An
+ event is represented by a procedure to be invoked in order to
+ process the event. The queue is scanned head to tail. If the
+ event of interest is a change of state in a file descriptor, then a
+ call to poll or select will be made to detect it.
+
+ If the events generate signals, they are also queued by special
+ functions that are invoked through traditional signal handlers.
+ The actions to be taken is response to such events will be executed
+ when the SIGHANDLER_LIST is scanned, the next time through the
+ infinite loop.
+
+ Corollary tasks are the creation and deletion of event sources. */
+
+typedef void *gdb_client_data;
+struct async_signal_handler;
+typedef void (handler_func) (int, gdb_client_data);
+typedef void (sig_handler_func) (gdb_client_data);
+typedef void (timer_handler_func) (gdb_client_data);
+
+/* Where to add an event onto the event queue, by queue_event. */
+typedef enum
+ {
+ /* Add at tail of queue. It will be processed in first in first
+ out order. */
+ TAIL,
+ /* Add at head of queue. It will be processed in last in first out
+ order. */
+ HEAD
+ }
+queue_position;
+
+/* Tell create_file_handler what events we are interested in.
+ This is used by the select version of the event loop. */
+
+#define GDB_READABLE (1<<1)
+#define GDB_WRITABLE (1<<2)
+#define GDB_EXCEPTION (1<<3)
+
+/* Exported functions from event-loop.c */
+
+extern void start_event_loop (void);
+extern void delete_file_handler (int fd);
+extern void add_file_handler (int fd, handler_func * proc, gdb_client_data client_data);
+extern void mark_async_signal_handler (struct async_signal_handler *async_handler_ptr);
+extern struct async_signal_handler *
+ create_async_signal_handler (sig_handler_func * proc, gdb_client_data client_data);
+extern void delete_async_signal_handler (struct async_signal_handler **async_handler_ptr);
+extern int create_timer (int milliseconds, timer_handler_func * proc, gdb_client_data client_data);
+extern void delete_timer (int id);
diff --git a/gdb/exc_request.defs b/gdb/exc_request.defs
new file mode 100644
index 00000000000..9b5ed2ee421
--- /dev/null
+++ b/gdb/exc_request.defs
@@ -0,0 +1,51 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1993,1991,1990,1989,1988,1987 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+/*
+ * Abstract:
+ * MiG definitions file for Mach exception interface (request half).
+ */
+
+subsystem exc 2400;
+
+#include <mach/std_types.defs>
+
+#ifdef USERPREFIX
+userprefix USERPREFIX;
+#endif
+
+#ifdef SERVERPREFIX
+serverprefix SERVERPREFIX;
+#endif
+
+simpleroutine exception_raise_request (
+ exception_port : mach_port_t;
+ replyport reply : mach_port_send_once_t;
+ thread : mach_port_t;
+ task : mach_port_t;
+ exception : integer_t;
+ code : integer_t;
+ subcode : integer_t);
diff --git a/gdb/exec.c b/gdb/exec.c
new file mode 100644
index 00000000000..0228f419465
--- /dev/null
+++ b/gdb/exec.c
@@ -0,0 +1,775 @@
+/* Work with executable files, for GDB.
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001, 2002
+ 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcmd.h"
+#include "language.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "completer.h"
+#include "value.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <fcntl.h>
+#include "gdb_string.h"
+
+#include "gdbcore.h"
+
+#include <ctype.h>
+#include "gdb_stat.h"
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#include "xcoffsolib.h"
+
+struct vmap *map_vmap (bfd *, bfd *);
+
+void (*file_changed_hook) (char *);
+
+/* Prototypes for local functions */
+
+static void add_to_section_table (bfd *, sec_ptr, PTR);
+
+static void exec_close (int);
+
+static void file_command (char *, int);
+
+static void set_section_command (char *, int);
+
+static void exec_files_info (struct target_ops *);
+
+static void bfdsec_to_vmap (bfd *, sec_ptr, PTR);
+
+static int ignore (CORE_ADDR, char *);
+
+static void init_exec_ops (void);
+
+void _initialize_exec (void);
+
+/* The target vector for executable files. */
+
+struct target_ops exec_ops;
+
+/* The Binary File Descriptor handle for the executable file. */
+
+bfd *exec_bfd = NULL;
+
+/* Whether to open exec and core files read-only or read-write. */
+
+int write_files = 0;
+
+/* Text start and end addresses (KLUDGE) if needed */
+
+#ifndef NEED_TEXT_START_END
+#define NEED_TEXT_START_END (0)
+#endif
+CORE_ADDR text_start = 0;
+CORE_ADDR text_end = 0;
+
+struct vmap *vmap;
+
+void
+exec_open (char *args, int from_tty)
+{
+ target_preopen (from_tty);
+ exec_file_attach (args, from_tty);
+}
+
+/* ARGSUSED */
+static void
+exec_close (int quitting)
+{
+ int need_symtab_cleanup = 0;
+ struct vmap *vp, *nxt;
+
+ for (nxt = vmap; nxt != NULL;)
+ {
+ vp = nxt;
+ nxt = vp->nxt;
+
+ /* if there is an objfile associated with this bfd,
+ free_objfile() will do proper cleanup of objfile *and* bfd. */
+
+ if (vp->objfile)
+ {
+ free_objfile (vp->objfile);
+ need_symtab_cleanup = 1;
+ }
+ else if (vp->bfd != exec_bfd)
+ /* FIXME-leak: We should be freeing vp->name too, I think. */
+ if (!bfd_close (vp->bfd))
+ warning ("cannot close \"%s\": %s",
+ vp->name, bfd_errmsg (bfd_get_error ()));
+
+ /* FIXME: This routine is #if 0'd in symfile.c. What should we
+ be doing here? Should we just free everything in
+ vp->objfile->symtabs? Should free_objfile do that?
+ FIXME-as-well: free_objfile already free'd vp->name, so it isn't
+ valid here. */
+ free_named_symtabs (vp->name);
+ xfree (vp);
+ }
+
+ vmap = NULL;
+
+ if (exec_bfd)
+ {
+ char *name = bfd_get_filename (exec_bfd);
+
+ if (!bfd_close (exec_bfd))
+ warning ("cannot close \"%s\": %s",
+ name, bfd_errmsg (bfd_get_error ()));
+ xfree (name);
+ exec_bfd = NULL;
+ }
+
+ if (exec_ops.to_sections)
+ {
+ xfree (exec_ops.to_sections);
+ exec_ops.to_sections = NULL;
+ exec_ops.to_sections_end = NULL;
+ }
+}
+
+void
+exec_file_clear (int from_tty)
+{
+ /* Remove exec file. */
+ unpush_target (&exec_ops);
+
+ if (from_tty)
+ printf_unfiltered ("No executable file now.\n");
+}
+
+/* Process the first arg in ARGS as the new exec file.
+
+ This function is intended to be behave essentially the same
+ as exec_file_command, except that the latter will detect when
+ a target is being debugged, and will ask the user whether it
+ should be shut down first. (If the answer is "no", then the
+ new file is ignored.)
+
+ This file is used by exec_file_command, to do the work of opening
+ and processing the exec file after any prompting has happened.
+
+ And, it is used by child_attach, when the attach command was
+ given a pid but not a exec pathname, and the attach command could
+ figure out the pathname from the pid. (In this case, we shouldn't
+ ask the user whether the current target should be shut down --
+ we're supplying the exec pathname late for good reason.)
+
+ ARGS is assumed to be the filename. */
+
+void
+exec_file_attach (char *filename, int from_tty)
+{
+ /* Remove any previous exec file. */
+ unpush_target (&exec_ops);
+
+ /* Now open and digest the file the user requested, if any. */
+
+ if (!filename)
+ {
+ if (from_tty)
+ printf_unfiltered ("No executable file now.\n");
+ }
+ else
+ {
+ char *scratch_pathname;
+ int scratch_chan;
+
+ scratch_chan = openp (getenv ("PATH"), 1, filename,
+ write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, 0,
+ &scratch_pathname);
+#if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__)
+ if (scratch_chan < 0)
+ {
+ char *exename = alloca (strlen (filename) + 5);
+ strcat (strcpy (exename, filename), ".exe");
+ scratch_chan = openp (getenv ("PATH"), 1, exename, write_files ?
+ O_RDWR | O_BINARY : O_RDONLY | O_BINARY, 0, &scratch_pathname);
+ }
+#endif
+ if (scratch_chan < 0)
+ perror_with_name (filename);
+ exec_bfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan);
+
+ if (!exec_bfd)
+ error ("\"%s\": could not open as an executable file: %s",
+ scratch_pathname, bfd_errmsg (bfd_get_error ()));
+
+ /* At this point, scratch_pathname and exec_bfd->name both point to the
+ same malloc'd string. However exec_close() will attempt to free it
+ via the exec_bfd->name pointer, so we need to make another copy and
+ leave exec_bfd as the new owner of the original copy. */
+ scratch_pathname = xstrdup (scratch_pathname);
+ make_cleanup (xfree, scratch_pathname);
+
+ if (!bfd_check_format (exec_bfd, bfd_object))
+ {
+ /* Make sure to close exec_bfd, or else "run" might try to use
+ it. */
+ exec_close (0);
+ error ("\"%s\": not in executable format: %s",
+ scratch_pathname, bfd_errmsg (bfd_get_error ()));
+ }
+
+ /* FIXME - This should only be run for RS6000, but the ifdef is a poor
+ way to accomplish. */
+#ifdef IBM6000_TARGET
+ /* Setup initial vmap. */
+
+ map_vmap (exec_bfd, 0);
+ if (vmap == NULL)
+ {
+ /* Make sure to close exec_bfd, or else "run" might try to use
+ it. */
+ exec_close (0);
+ error ("\"%s\": can't find the file sections: %s",
+ scratch_pathname, bfd_errmsg (bfd_get_error ()));
+ }
+#endif /* IBM6000_TARGET */
+
+ if (build_section_table (exec_bfd, &exec_ops.to_sections,
+ &exec_ops.to_sections_end))
+ {
+ /* Make sure to close exec_bfd, or else "run" might try to use
+ it. */
+ exec_close (0);
+ error ("\"%s\": can't find the file sections: %s",
+ scratch_pathname, bfd_errmsg (bfd_get_error ()));
+ }
+
+ /* text_end is sometimes used for where to put call dummies. A
+ few ports use these for other purposes too. */
+ if (NEED_TEXT_START_END)
+ {
+ struct section_table *p;
+
+ /* Set text_start to the lowest address of the start of any
+ readonly code section and set text_end to the highest
+ address of the end of any readonly code section. */
+ /* FIXME: The comment above does not match the code. The
+ code checks for sections with are either code *or*
+ readonly. */
+ text_start = ~(CORE_ADDR) 0;
+ text_end = (CORE_ADDR) 0;
+ for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
+ if (bfd_get_section_flags (p->bfd, p->the_bfd_section)
+ & (SEC_CODE | SEC_READONLY))
+ {
+ if (text_start > p->addr)
+ text_start = p->addr;
+ if (text_end < p->endaddr)
+ text_end = p->endaddr;
+ }
+ }
+
+ validate_files ();
+
+ set_gdbarch_from_file (exec_bfd);
+
+ push_target (&exec_ops);
+
+ /* Tell display code (if any) about the changed file name. */
+ if (exec_file_display_hook)
+ (*exec_file_display_hook) (filename);
+ }
+}
+
+/* Process the first arg in ARGS as the new exec file.
+
+ Note that we have to explicitly ignore additional args, since we can
+ be called from file_command(), which also calls symbol_file_command()
+ which can take multiple args.
+
+ If ARGS is NULL, we just want to close the exec file. */
+
+static void
+exec_file_command (char *args, int from_tty)
+{
+ char **argv;
+ char *filename;
+
+ target_preopen (from_tty);
+
+ if (args)
+ {
+ /* Scan through the args and pick up the first non option arg
+ as the filename. */
+
+ argv = buildargv (args);
+ if (argv == NULL)
+ nomem (0);
+
+ make_cleanup_freeargv (argv);
+
+ for (; (*argv != NULL) && (**argv == '-'); argv++)
+ {;
+ }
+ if (*argv == NULL)
+ error ("No executable file name was specified");
+
+ filename = tilde_expand (*argv);
+ make_cleanup (xfree, filename);
+ exec_file_attach (filename, from_tty);
+ }
+ else
+ exec_file_attach (NULL, from_tty);
+}
+
+/* Set both the exec file and the symbol file, in one command.
+ What a novelty. Why did GDB go through four major releases before this
+ command was added? */
+
+static void
+file_command (char *arg, int from_tty)
+{
+ /* FIXME, if we lose on reading the symbol file, we should revert
+ the exec file, but that's rough. */
+ exec_file_command (arg, from_tty);
+ symbol_file_command (arg, from_tty);
+ if (file_changed_hook)
+ file_changed_hook (arg);
+}
+
+
+/* Locate all mappable sections of a BFD file.
+ table_pp_char is a char * to get it through bfd_map_over_sections;
+ we cast it back to its proper type. */
+
+static void
+add_to_section_table (bfd *abfd, sec_ptr asect, PTR table_pp_char)
+{
+ struct section_table **table_pp = (struct section_table **) table_pp_char;
+ flagword aflag;
+
+ aflag = bfd_get_section_flags (abfd, asect);
+ if (!(aflag & SEC_ALLOC))
+ return;
+ if (0 == bfd_section_size (abfd, asect))
+ return;
+ (*table_pp)->bfd = abfd;
+ (*table_pp)->the_bfd_section = asect;
+ (*table_pp)->addr = bfd_section_vma (abfd, asect);
+ (*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect);
+ (*table_pp)++;
+}
+
+/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR.
+ Returns 0 if OK, 1 on error. */
+
+int
+build_section_table (bfd *some_bfd, struct section_table **start,
+ struct section_table **end)
+{
+ unsigned count;
+
+ count = bfd_count_sections (some_bfd);
+ if (*start)
+ xfree (* start);
+ *start = (struct section_table *) xmalloc (count * sizeof (**start));
+ *end = *start;
+ bfd_map_over_sections (some_bfd, add_to_section_table, (char *) end);
+ if (*end > *start + count)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ /* We could realloc the table, but it probably loses for most files. */
+ return 0;
+}
+
+static void
+bfdsec_to_vmap (bfd *abfd, sec_ptr sect, PTR arg3)
+{
+ struct vmap_and_bfd *vmap_bfd = (struct vmap_and_bfd *) arg3;
+ struct vmap *vp;
+
+ vp = vmap_bfd->pvmap;
+
+ if ((bfd_get_section_flags (abfd, sect) & SEC_LOAD) == 0)
+ return;
+
+ if (STREQ (bfd_section_name (abfd, sect), ".text"))
+ {
+ vp->tstart = bfd_section_vma (abfd, sect);
+ vp->tend = vp->tstart + bfd_section_size (abfd, sect);
+ vp->tvma = bfd_section_vma (abfd, sect);
+ vp->toffs = sect->filepos;
+ }
+ else if (STREQ (bfd_section_name (abfd, sect), ".data"))
+ {
+ vp->dstart = bfd_section_vma (abfd, sect);
+ vp->dend = vp->dstart + bfd_section_size (abfd, sect);
+ vp->dvma = bfd_section_vma (abfd, sect);
+ }
+ /* Silently ignore other types of sections. (FIXME?) */
+}
+
+/* Make a vmap for ABFD which might be a member of the archive ARCH.
+ Return the new vmap. */
+
+struct vmap *
+map_vmap (bfd *abfd, bfd *arch)
+{
+ struct vmap_and_bfd vmap_bfd;
+ struct vmap *vp, **vpp;
+
+ vp = (struct vmap *) xmalloc (sizeof (*vp));
+ memset ((char *) vp, '\0', sizeof (*vp));
+ vp->nxt = 0;
+ vp->bfd = abfd;
+ vp->name = bfd_get_filename (arch ? arch : abfd);
+ vp->member = arch ? bfd_get_filename (abfd) : "";
+
+ vmap_bfd.pbfd = arch;
+ vmap_bfd.pvmap = vp;
+ bfd_map_over_sections (abfd, bfdsec_to_vmap, &vmap_bfd);
+
+ /* Find the end of the list and append. */
+ for (vpp = &vmap; *vpp; vpp = &(*vpp)->nxt)
+ ;
+ *vpp = vp;
+
+ return vp;
+}
+
+/* Read or write the exec file.
+
+ Args are address within a BFD file, address within gdb address-space,
+ length, and a flag indicating whether to read or write.
+
+ Result is a length:
+
+ 0: We cannot handle this address and length.
+ > 0: We have handled N bytes starting at this address.
+ (If N == length, we did it all.) We might be able
+ to handle more bytes beyond this length, but no
+ promises.
+ < 0: We cannot handle this address, but if somebody
+ else handles (-N) bytes, we can start from there.
+
+ The same routine is used to handle both core and exec files;
+ we just tail-call it with more arguments to select between them. */
+
+int
+xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ boolean res;
+ struct section_table *p;
+ CORE_ADDR nextsectaddr, memend;
+ boolean (*xfer_fn) (bfd *, sec_ptr, PTR, file_ptr, bfd_size_type);
+ asection *section = NULL;
+
+ if (len <= 0)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+ if (overlay_debugging)
+ {
+ section = find_pc_overlay (memaddr);
+ if (pc_in_unmapped_range (memaddr, section))
+ memaddr = overlay_mapped_address (memaddr, section);
+ }
+
+ memend = memaddr + len;
+ xfer_fn = write ? bfd_set_section_contents : bfd_get_section_contents;
+ nextsectaddr = memend;
+
+ for (p = target->to_sections; p < target->to_sections_end; p++)
+ {
+ if (overlay_debugging && section && p->the_bfd_section &&
+ strcmp (section->name, p->the_bfd_section->name) != 0)
+ continue; /* not the section we need */
+ if (memaddr >= p->addr)
+ if (memend <= p->endaddr)
+ {
+ /* Entire transfer is within this section. */
+ res = xfer_fn (p->bfd, p->the_bfd_section, myaddr,
+ memaddr - p->addr, len);
+ return (res != 0) ? len : 0;
+ }
+ else if (memaddr >= p->endaddr)
+ {
+ /* This section ends before the transfer starts. */
+ continue;
+ }
+ else
+ {
+ /* This section overlaps the transfer. Just do half. */
+ len = p->endaddr - memaddr;
+ res = xfer_fn (p->bfd, p->the_bfd_section, myaddr,
+ memaddr - p->addr, len);
+ return (res != 0) ? len : 0;
+ }
+ else
+ nextsectaddr = min (nextsectaddr, p->addr);
+ }
+
+ if (nextsectaddr >= memend)
+ return 0; /* We can't help */
+ else
+ return -(nextsectaddr - memaddr); /* Next boundary where we can help */
+}
+
+
+void
+print_section_info (struct target_ops *t, bfd *abfd)
+{
+ struct section_table *p;
+
+ printf_filtered ("\t`%s', ", bfd_get_filename (abfd));
+ wrap_here (" ");
+ printf_filtered ("file type %s.\n", bfd_get_target (abfd));
+ if (abfd == exec_bfd)
+ {
+ printf_filtered ("\tEntry point: ");
+ print_address_numeric (bfd_get_start_address (abfd), 1, gdb_stdout);
+ printf_filtered ("\n");
+ }
+ for (p = t->to_sections; p < t->to_sections_end; p++)
+ {
+ /* FIXME-32x64 need a print_address_numeric with field width */
+ printf_filtered ("\t%s", local_hex_string_custom ((unsigned long) p->addr, "08l"));
+ printf_filtered (" - %s", local_hex_string_custom ((unsigned long) p->endaddr, "08l"));
+ if (info_verbose)
+ printf_filtered (" @ %s",
+ local_hex_string_custom ((unsigned long) p->the_bfd_section->filepos, "08l"));
+ printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section));
+ if (p->bfd != abfd)
+ {
+ printf_filtered (" in %s", bfd_get_filename (p->bfd));
+ }
+ printf_filtered ("\n");
+ }
+}
+
+static void
+exec_files_info (struct target_ops *t)
+{
+ print_section_info (t, exec_bfd);
+
+ if (vmap)
+ {
+ struct vmap *vp;
+
+ printf_unfiltered ("\tMapping info for file `%s'.\n", vmap->name);
+ printf_unfiltered ("\t %*s %*s %*s %*s %8.8s %s\n",
+ strlen_paddr (), "tstart",
+ strlen_paddr (), "tend",
+ strlen_paddr (), "dstart",
+ strlen_paddr (), "dend",
+ "section",
+ "file(member)");
+
+ for (vp = vmap; vp; vp = vp->nxt)
+ printf_unfiltered ("\t0x%s 0x%s 0x%s 0x%s %s%s%s%s\n",
+ paddr (vp->tstart),
+ paddr (vp->tend),
+ paddr (vp->dstart),
+ paddr (vp->dend),
+ vp->name,
+ *vp->member ? "(" : "", vp->member,
+ *vp->member ? ")" : "");
+ }
+}
+
+/* msnyder 5/21/99:
+ exec_set_section_offsets sets the offsets of all the sections
+ in the exec objfile. */
+
+void
+exec_set_section_offsets (bfd_signed_vma text_off, bfd_signed_vma data_off,
+ bfd_signed_vma bss_off)
+{
+ struct section_table *sect;
+
+ for (sect = exec_ops.to_sections;
+ sect < exec_ops.to_sections_end;
+ sect++)
+ {
+ flagword flags;
+
+ flags = bfd_get_section_flags (exec_bfd, sect->the_bfd_section);
+
+ if (flags & SEC_CODE)
+ {
+ sect->addr += text_off;
+ sect->endaddr += text_off;
+ }
+ else if (flags & (SEC_DATA | SEC_LOAD))
+ {
+ sect->addr += data_off;
+ sect->endaddr += data_off;
+ }
+ else if (flags & SEC_ALLOC)
+ {
+ sect->addr += bss_off;
+ sect->endaddr += bss_off;
+ }
+ }
+}
+
+static void
+set_section_command (char *args, int from_tty)
+{
+ struct section_table *p;
+ char *secname;
+ unsigned seclen;
+ unsigned long secaddr;
+ char secprint[100];
+ long offset;
+
+ if (args == 0)
+ error ("Must specify section name and its virtual address");
+
+ /* Parse out section name */
+ for (secname = args; !isspace (*args); args++);
+ seclen = args - secname;
+
+ /* Parse out new virtual address */
+ secaddr = parse_and_eval_address (args);
+
+ for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
+ {
+ if (!strncmp (secname, bfd_section_name (exec_bfd, p->the_bfd_section), seclen)
+ && bfd_section_name (exec_bfd, p->the_bfd_section)[seclen] == '\0')
+ {
+ offset = secaddr - p->addr;
+ p->addr += offset;
+ p->endaddr += offset;
+ if (from_tty)
+ exec_files_info (&exec_ops);
+ return;
+ }
+ }
+ if (seclen >= sizeof (secprint))
+ seclen = sizeof (secprint) - 1;
+ strncpy (secprint, secname, seclen);
+ secprint[seclen] = '\0';
+ error ("Section %s not found", secprint);
+}
+
+/* If mourn is being called in all the right places, this could be say
+ `gdb internal error' (since generic_mourn calls
+ breakpoint_init_inferior). */
+
+static int
+ignore (CORE_ADDR addr, char *contents)
+{
+ return 0;
+}
+
+/* Find mapped memory. */
+
+extern void
+exec_set_find_memory_regions (int (*func) (int (*) (CORE_ADDR,
+ unsigned long,
+ int, int, int,
+ void *),
+ void *))
+{
+ exec_ops.to_find_memory_regions = func;
+}
+
+static char *exec_make_note_section (bfd *, int *);
+
+/* Fill in the exec file target vector. Very few entries need to be
+ defined. */
+
+static void
+init_exec_ops (void)
+{
+ exec_ops.to_shortname = "exec";
+ exec_ops.to_longname = "Local exec file";
+ exec_ops.to_doc = "Use an executable file as a target.\n\
+Specify the filename of the executable file.";
+ exec_ops.to_open = exec_open;
+ exec_ops.to_close = exec_close;
+ exec_ops.to_attach = find_default_attach;
+ exec_ops.to_require_attach = find_default_require_attach;
+ exec_ops.to_require_detach = find_default_require_detach;
+ exec_ops.to_xfer_memory = xfer_memory;
+ exec_ops.to_files_info = exec_files_info;
+ exec_ops.to_insert_breakpoint = ignore;
+ exec_ops.to_remove_breakpoint = ignore;
+ exec_ops.to_create_inferior = find_default_create_inferior;
+ exec_ops.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior;
+ exec_ops.to_stratum = file_stratum;
+ exec_ops.to_has_memory = 1;
+ exec_ops.to_make_corefile_notes = exec_make_note_section;
+ exec_ops.to_magic = OPS_MAGIC;
+}
+
+void
+_initialize_exec (void)
+{
+ struct cmd_list_element *c;
+
+ init_exec_ops ();
+
+ if (!dbx_commands)
+ {
+ c = add_cmd ("file", class_files, file_command,
+ "Use FILE as program to be debugged.\n\
+It is read for its symbols, for getting the contents of pure memory,\n\
+and it is the program executed when you use the `run' command.\n\
+If FILE cannot be found as specified, your execution directory path\n\
+($PATH) is searched for a command of that name.\n\
+No arg means to have no executable file and no symbols.", &cmdlist);
+ set_cmd_completer (c, filename_completer);
+ }
+
+ c = add_cmd ("exec-file", class_files, exec_file_command,
+ "Use FILE as program for getting contents of pure memory.\n\
+If FILE cannot be found as specified, your execution directory path\n\
+is searched for a command of that name.\n\
+No arg means have no executable file.", &cmdlist);
+ set_cmd_completer (c, filename_completer);
+
+ add_com ("section", class_files, set_section_command,
+ "Change the base address of section SECTION of the exec file to ADDR.\n\
+This can be used if the exec file does not contain section addresses,\n\
+(such as in the a.out format), or when the addresses specified in the\n\
+file itself are wrong. Each section must be changed separately. The\n\
+``info files'' command lists all the sections and their addresses.");
+
+ add_show_from_set
+ (add_set_cmd ("write", class_support, var_boolean, (char *) &write_files,
+ "Set writing into executable and core files.",
+ &setlist),
+ &showlist);
+
+ add_target (&exec_ops);
+}
+
+static char *
+exec_make_note_section (bfd *obfd, int *note_size)
+{
+ error ("Can't create a corefile");
+}
diff --git a/gdb/expprint.c b/gdb/expprint.c
new file mode 100644
index 00000000000..09e7db69b3a
--- /dev/null
+++ b/gdb/expprint.c
@@ -0,0 +1,985 @@
+/* Print in infix form a struct expression.
+ Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "language.h"
+#include "parser-defs.h"
+
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+
+/* Prototypes for local functions */
+
+static void print_subexp (struct expression *, int *, struct ui_file *,
+ enum precedence);
+
+void
+print_expression (struct expression *exp, struct ui_file *stream)
+{
+ int pc = 0;
+ print_subexp (exp, &pc, stream, PREC_NULL);
+}
+
+/* Print the subexpression of EXP that starts in position POS, on STREAM.
+ PREC is the precedence of the surrounding operator;
+ if the precedence of the main operator of this subexpression is less,
+ parentheses are needed here. */
+
+static void
+print_subexp (register struct expression *exp, register int *pos,
+ struct ui_file *stream, enum precedence prec)
+{
+ register unsigned tem;
+ register const struct op_print *op_print_tab;
+ register int pc;
+ unsigned nargs;
+ register char *op_str;
+ int assign_modify = 0;
+ enum exp_opcode opcode;
+ enum precedence myprec = PREC_NULL;
+ /* Set to 1 for a right-associative operator. */
+ int assoc = 0;
+ struct value *val;
+ char *tempstr = NULL;
+
+ op_print_tab = exp->language_defn->la_op_print_tab;
+ pc = (*pos)++;
+ opcode = exp->elts[pc].opcode;
+ switch (opcode)
+ {
+ /* Common ops */
+
+ case OP_SCOPE:
+ myprec = PREC_PREFIX;
+ assoc = 0;
+ fputs_filtered (type_name_no_tag (exp->elts[pc + 1].type), stream);
+ fputs_filtered ("::", stream);
+ nargs = longest_to_int (exp->elts[pc + 2].longconst);
+ (*pos) += 4 + BYTES_TO_EXP_ELEM (nargs + 1);
+ fputs_filtered (&exp->elts[pc + 3].string, stream);
+ return;
+
+ case OP_LONG:
+ (*pos) += 3;
+ value_print (value_from_longest (exp->elts[pc + 1].type,
+ exp->elts[pc + 2].longconst),
+ stream, 0, Val_no_prettyprint);
+ return;
+
+ case OP_DOUBLE:
+ (*pos) += 3;
+ value_print (value_from_double (exp->elts[pc + 1].type,
+ exp->elts[pc + 2].doubleconst),
+ stream, 0, Val_no_prettyprint);
+ return;
+
+ case OP_VAR_VALUE:
+ {
+ struct block *b;
+ (*pos) += 3;
+ b = exp->elts[pc + 1].block;
+ if (b != NULL
+ && BLOCK_FUNCTION (b) != NULL
+ && SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)) != NULL)
+ {
+ fputs_filtered (SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)), stream);
+ fputs_filtered ("::", stream);
+ }
+ fputs_filtered (SYMBOL_SOURCE_NAME (exp->elts[pc + 2].symbol), stream);
+ }
+ return;
+
+ case OP_LAST:
+ (*pos) += 2;
+ fprintf_filtered (stream, "$%d",
+ longest_to_int (exp->elts[pc + 1].longconst));
+ return;
+
+ case OP_REGISTER:
+ (*pos) += 2;
+ fprintf_filtered (stream, "$%s",
+ REGISTER_NAME (longest_to_int (exp->elts[pc + 1].longconst)));
+ return;
+
+ case OP_BOOL:
+ (*pos) += 2;
+ fprintf_filtered (stream, "%s",
+ longest_to_int (exp->elts[pc + 1].longconst)
+ ? "TRUE" : "FALSE");
+ return;
+
+ case OP_INTERNALVAR:
+ (*pos) += 2;
+ fprintf_filtered (stream, "$%s",
+ internalvar_name (exp->elts[pc + 1].internalvar));
+ return;
+
+ case OP_FUNCALL:
+ (*pos) += 2;
+ nargs = longest_to_int (exp->elts[pc + 1].longconst);
+ print_subexp (exp, pos, stream, PREC_SUFFIX);
+ fputs_filtered (" (", stream);
+ for (tem = 0; tem < nargs; tem++)
+ {
+ if (tem != 0)
+ fputs_filtered (", ", stream);
+ print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
+ }
+ fputs_filtered (")", stream);
+ return;
+
+ case OP_NAME:
+ case OP_EXPRSTRING:
+ nargs = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
+ fputs_filtered (&exp->elts[pc + 2].string, stream);
+ return;
+
+ case OP_STRING:
+ nargs = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
+ /* LA_PRINT_STRING will print using the current repeat count threshold.
+ If necessary, we can temporarily set it to zero, or pass it as an
+ additional parameter to LA_PRINT_STRING. -fnf */
+ LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 1, 0);
+ return;
+
+ case OP_BITSTRING:
+ nargs = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos)
+ += 3 + BYTES_TO_EXP_ELEM ((nargs + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT);
+ fprintf_unfiltered (stream, "B'<unimplemented>'");
+ return;
+
+ case OP_ARRAY:
+ (*pos) += 3;
+ nargs = longest_to_int (exp->elts[pc + 2].longconst);
+ nargs -= longest_to_int (exp->elts[pc + 1].longconst);
+ nargs++;
+ tem = 0;
+ if (exp->elts[pc + 4].opcode == OP_LONG
+ && exp->elts[pc + 5].type == builtin_type_char
+ && exp->language_defn->la_language == language_c)
+ {
+ /* Attempt to print C character arrays using string syntax.
+ Walk through the args, picking up one character from each
+ of the OP_LONG expression elements. If any array element
+ does not match our expection of what we should find for
+ a simple string, revert back to array printing. Note that
+ the last expression element is an explicit null terminator
+ byte, which doesn't get printed. */
+ tempstr = alloca (nargs);
+ pc += 4;
+ while (tem < nargs)
+ {
+ if (exp->elts[pc].opcode != OP_LONG
+ || exp->elts[pc + 1].type != builtin_type_char)
+ {
+ /* Not a simple array of char, use regular array printing. */
+ tem = 0;
+ break;
+ }
+ else
+ {
+ tempstr[tem++] =
+ longest_to_int (exp->elts[pc + 2].longconst);
+ pc += 4;
+ }
+ }
+ }
+ if (tem > 0)
+ {
+ LA_PRINT_STRING (stream, tempstr, nargs - 1, 1, 0);
+ (*pos) = pc;
+ }
+ else
+ {
+ int is_chill = exp->language_defn->la_language == language_chill;
+ fputs_filtered (is_chill ? " [" : " {", stream);
+ for (tem = 0; tem < nargs; tem++)
+ {
+ if (tem != 0)
+ {
+ fputs_filtered (", ", stream);
+ }
+ print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
+ }
+ fputs_filtered (is_chill ? "]" : "}", stream);
+ }
+ return;
+
+ case OP_LABELED:
+ tem = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
+
+ if (exp->language_defn->la_language == language_chill)
+ {
+ fputs_filtered (".", stream);
+ fputs_filtered (&exp->elts[pc + 2].string, stream);
+ fputs_filtered (exp->elts[*pos].opcode == OP_LABELED ? ", "
+ : ": ",
+ stream);
+ }
+ else
+ {
+ /* Gcc support both these syntaxes. Unsure which is preferred. */
+#if 1
+ fputs_filtered (&exp->elts[pc + 2].string, stream);
+ fputs_filtered (": ", stream);
+#else
+ fputs_filtered (".", stream);
+ fputs_filtered (&exp->elts[pc + 2].string, stream);
+ fputs_filtered ("=", stream);
+#endif
+ }
+ print_subexp (exp, pos, stream, PREC_SUFFIX);
+ return;
+
+ case TERNOP_COND:
+ if ((int) prec > (int) PREC_COMMA)
+ fputs_filtered ("(", stream);
+ /* Print the subexpressions, forcing parentheses
+ around any binary operations within them.
+ This is more parentheses than are strictly necessary,
+ but it looks clearer. */
+ print_subexp (exp, pos, stream, PREC_HYPER);
+ fputs_filtered (" ? ", stream);
+ print_subexp (exp, pos, stream, PREC_HYPER);
+ fputs_filtered (" : ", stream);
+ print_subexp (exp, pos, stream, PREC_HYPER);
+ if ((int) prec > (int) PREC_COMMA)
+ fputs_filtered (")", stream);
+ return;
+
+ case TERNOP_SLICE:
+ case TERNOP_SLICE_COUNT:
+ print_subexp (exp, pos, stream, PREC_SUFFIX);
+ fputs_filtered ("(", stream);
+ print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
+ fputs_filtered (opcode == TERNOP_SLICE ? " : " : " UP ", stream);
+ print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
+ fputs_filtered (")", stream);
+ return;
+
+ case STRUCTOP_STRUCT:
+ tem = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
+ print_subexp (exp, pos, stream, PREC_SUFFIX);
+ fputs_filtered (".", stream);
+ fputs_filtered (&exp->elts[pc + 2].string, stream);
+ return;
+
+ /* Will not occur for Modula-2 */
+ case STRUCTOP_PTR:
+ tem = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
+ print_subexp (exp, pos, stream, PREC_SUFFIX);
+ fputs_filtered ("->", stream);
+ fputs_filtered (&exp->elts[pc + 2].string, stream);
+ return;
+
+ case BINOP_SUBSCRIPT:
+ print_subexp (exp, pos, stream, PREC_SUFFIX);
+ fputs_filtered ("[", stream);
+ print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
+ fputs_filtered ("]", stream);
+ return;
+
+ case UNOP_POSTINCREMENT:
+ print_subexp (exp, pos, stream, PREC_SUFFIX);
+ fputs_filtered ("++", stream);
+ return;
+
+ case UNOP_POSTDECREMENT:
+ print_subexp (exp, pos, stream, PREC_SUFFIX);
+ fputs_filtered ("--", stream);
+ return;
+
+ case UNOP_CAST:
+ (*pos) += 2;
+ if ((int) prec > (int) PREC_PREFIX)
+ fputs_filtered ("(", stream);
+ fputs_filtered ("(", stream);
+ type_print (exp->elts[pc + 1].type, "", stream, 0);
+ fputs_filtered (") ", stream);
+ print_subexp (exp, pos, stream, PREC_PREFIX);
+ if ((int) prec > (int) PREC_PREFIX)
+ fputs_filtered (")", stream);
+ return;
+
+ case UNOP_MEMVAL:
+ (*pos) += 2;
+ if ((int) prec > (int) PREC_PREFIX)
+ fputs_filtered ("(", stream);
+ if (TYPE_CODE (exp->elts[pc + 1].type) == TYPE_CODE_FUNC &&
+ exp->elts[pc + 3].opcode == OP_LONG)
+ {
+ /* We have a minimal symbol fn, probably. It's encoded
+ as a UNOP_MEMVAL (function-type) of an OP_LONG (int, address).
+ Swallow the OP_LONG (including both its opcodes); ignore
+ its type; print the value in the type of the MEMVAL. */
+ (*pos) += 4;
+ val = value_at_lazy (exp->elts[pc + 1].type,
+ (CORE_ADDR) exp->elts[pc + 5].longconst,
+ NULL);
+ value_print (val, stream, 0, Val_no_prettyprint);
+ }
+ else
+ {
+ fputs_filtered ("{", stream);
+ type_print (exp->elts[pc + 1].type, "", stream, 0);
+ fputs_filtered ("} ", stream);
+ print_subexp (exp, pos, stream, PREC_PREFIX);
+ }
+ if ((int) prec > (int) PREC_PREFIX)
+ fputs_filtered (")", stream);
+ return;
+
+ case BINOP_ASSIGN_MODIFY:
+ opcode = exp->elts[pc + 1].opcode;
+ (*pos) += 2;
+ myprec = PREC_ASSIGN;
+ assoc = 1;
+ assign_modify = 1;
+ op_str = "???";
+ for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
+ if (op_print_tab[tem].opcode == opcode)
+ {
+ op_str = op_print_tab[tem].string;
+ break;
+ }
+ if (op_print_tab[tem].opcode != opcode)
+ /* Not found; don't try to keep going because we don't know how
+ to interpret further elements. */
+ error ("Invalid expression");
+ break;
+
+ /* C++ ops */
+
+ case OP_THIS:
+ ++(*pos);
+ fputs_filtered ("this", stream);
+ return;
+
+ /* Modula-2 ops */
+
+ case MULTI_SUBSCRIPT:
+ (*pos) += 2;
+ nargs = longest_to_int (exp->elts[pc + 1].longconst);
+ print_subexp (exp, pos, stream, PREC_SUFFIX);
+ fprintf_unfiltered (stream, " [");
+ for (tem = 0; tem < nargs; tem++)
+ {
+ if (tem != 0)
+ fprintf_unfiltered (stream, ", ");
+ print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
+ }
+ fprintf_unfiltered (stream, "]");
+ return;
+
+ case BINOP_VAL:
+ (*pos) += 2;
+ fprintf_unfiltered (stream, "VAL(");
+ type_print (exp->elts[pc + 1].type, "", stream, 0);
+ fprintf_unfiltered (stream, ",");
+ print_subexp (exp, pos, stream, PREC_PREFIX);
+ fprintf_unfiltered (stream, ")");
+ return;
+
+ case BINOP_INCL:
+ case BINOP_EXCL:
+ error ("print_subexp: Not implemented.");
+
+ /* Default ops */
+
+ default:
+ op_str = "???";
+ for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
+ if (op_print_tab[tem].opcode == opcode)
+ {
+ op_str = op_print_tab[tem].string;
+ myprec = op_print_tab[tem].precedence;
+ assoc = op_print_tab[tem].right_assoc;
+ break;
+ }
+ if (op_print_tab[tem].opcode != opcode)
+ /* Not found; don't try to keep going because we don't know how
+ to interpret further elements. For example, this happens
+ if opcode is OP_TYPE. */
+ error ("Invalid expression");
+ }
+
+ /* Note that PREC_BUILTIN will always emit parentheses. */
+ if ((int) myprec < (int) prec)
+ fputs_filtered ("(", stream);
+ if ((int) opcode > (int) BINOP_END)
+ {
+ if (assoc)
+ {
+ /* Unary postfix operator. */
+ print_subexp (exp, pos, stream, PREC_SUFFIX);
+ fputs_filtered (op_str, stream);
+ }
+ else
+ {
+ /* Unary prefix operator. */
+ fputs_filtered (op_str, stream);
+ if (myprec == PREC_BUILTIN_FUNCTION)
+ fputs_filtered ("(", stream);
+ print_subexp (exp, pos, stream, PREC_PREFIX);
+ if (myprec == PREC_BUILTIN_FUNCTION)
+ fputs_filtered (")", stream);
+ }
+ }
+ else
+ {
+ /* Binary operator. */
+ /* Print left operand.
+ If operator is right-associative,
+ increment precedence for this operand. */
+ print_subexp (exp, pos, stream,
+ (enum precedence) ((int) myprec + assoc));
+ /* Print the operator itself. */
+ if (assign_modify)
+ fprintf_filtered (stream, " %s= ", op_str);
+ else if (op_str[0] == ',')
+ fprintf_filtered (stream, "%s ", op_str);
+ else
+ fprintf_filtered (stream, " %s ", op_str);
+ /* Print right operand.
+ If operator is left-associative,
+ increment precedence for this operand. */
+ print_subexp (exp, pos, stream,
+ (enum precedence) ((int) myprec + !assoc));
+ }
+
+ if ((int) myprec < (int) prec)
+ fputs_filtered (")", stream);
+}
+
+/* Return the operator corresponding to opcode OP as
+ a string. NULL indicates that the opcode was not found in the
+ current language table. */
+char *
+op_string (enum exp_opcode op)
+{
+ int tem;
+ register const struct op_print *op_print_tab;
+
+ op_print_tab = current_language->la_op_print_tab;
+ for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
+ if (op_print_tab[tem].opcode == op)
+ return op_print_tab[tem].string;
+ return NULL;
+}
+
+/* Support for dumping the raw data from expressions in a human readable
+ form. */
+
+static char *op_name (int opcode);
+
+static char *
+op_name (int opcode)
+{
+ switch (opcode)
+ {
+ default:
+ {
+ static char buf[30];
+
+ sprintf (buf, "<unknown %d>", opcode);
+ return buf;
+ }
+ case OP_NULL:
+ return "OP_NULL";
+ case BINOP_ADD:
+ return "BINOP_ADD";
+ case BINOP_SUB:
+ return "BINOP_SUB";
+ case BINOP_MUL:
+ return "BINOP_MUL";
+ case BINOP_DIV:
+ return "BINOP_DIV";
+ case BINOP_REM:
+ return "BINOP_REM";
+ case BINOP_MOD:
+ return "BINOP_MOD";
+ case BINOP_LSH:
+ return "BINOP_LSH";
+ case BINOP_RSH:
+ return "BINOP_RSH";
+ case BINOP_LOGICAL_AND:
+ return "BINOP_LOGICAL_AND";
+ case BINOP_LOGICAL_OR:
+ return "BINOP_LOGICAL_OR";
+ case BINOP_BITWISE_AND:
+ return "BINOP_BITWISE_AND";
+ case BINOP_BITWISE_IOR:
+ return "BINOP_BITWISE_IOR";
+ case BINOP_BITWISE_XOR:
+ return "BINOP_BITWISE_XOR";
+ case BINOP_EQUAL:
+ return "BINOP_EQUAL";
+ case BINOP_NOTEQUAL:
+ return "BINOP_NOTEQUAL";
+ case BINOP_LESS:
+ return "BINOP_LESS";
+ case BINOP_GTR:
+ return "BINOP_GTR";
+ case BINOP_LEQ:
+ return "BINOP_LEQ";
+ case BINOP_GEQ:
+ return "BINOP_GEQ";
+ case BINOP_REPEAT:
+ return "BINOP_REPEAT";
+ case BINOP_ASSIGN:
+ return "BINOP_ASSIGN";
+ case BINOP_COMMA:
+ return "BINOP_COMMA";
+ case BINOP_SUBSCRIPT:
+ return "BINOP_SUBSCRIPT";
+ case MULTI_SUBSCRIPT:
+ return "MULTI_SUBSCRIPT";
+ case BINOP_EXP:
+ return "BINOP_EXP";
+ case BINOP_MIN:
+ return "BINOP_MIN";
+ case BINOP_MAX:
+ return "BINOP_MAX";
+ case STRUCTOP_MEMBER:
+ return "STRUCTOP_MEMBER";
+ case STRUCTOP_MPTR:
+ return "STRUCTOP_MPTR";
+ case BINOP_INTDIV:
+ return "BINOP_INTDIV";
+ case BINOP_ASSIGN_MODIFY:
+ return "BINOP_ASSIGN_MODIFY";
+ case BINOP_VAL:
+ return "BINOP_VAL";
+ case BINOP_INCL:
+ return "BINOP_INCL";
+ case BINOP_EXCL:
+ return "BINOP_EXCL";
+ case BINOP_CONCAT:
+ return "BINOP_CONCAT";
+ case BINOP_RANGE:
+ return "BINOP_RANGE";
+ case BINOP_END:
+ return "BINOP_END";
+ case TERNOP_COND:
+ return "TERNOP_COND";
+ case TERNOP_SLICE:
+ return "TERNOP_SLICE";
+ case TERNOP_SLICE_COUNT:
+ return "TERNOP_SLICE_COUNT";
+ case OP_LONG:
+ return "OP_LONG";
+ case OP_DOUBLE:
+ return "OP_DOUBLE";
+ case OP_VAR_VALUE:
+ return "OP_VAR_VALUE";
+ case OP_LAST:
+ return "OP_LAST";
+ case OP_REGISTER:
+ return "OP_REGISTER";
+ case OP_INTERNALVAR:
+ return "OP_INTERNALVAR";
+ case OP_FUNCALL:
+ return "OP_FUNCALL";
+ case OP_STRING:
+ return "OP_STRING";
+ case OP_BITSTRING:
+ return "OP_BITSTRING";
+ case OP_ARRAY:
+ return "OP_ARRAY";
+ case UNOP_CAST:
+ return "UNOP_CAST";
+ case UNOP_MEMVAL:
+ return "UNOP_MEMVAL";
+ case UNOP_NEG:
+ return "UNOP_NEG";
+ case UNOP_LOGICAL_NOT:
+ return "UNOP_LOGICAL_NOT";
+ case UNOP_COMPLEMENT:
+ return "UNOP_COMPLEMENT";
+ case UNOP_IND:
+ return "UNOP_IND";
+ case UNOP_ADDR:
+ return "UNOP_ADDR";
+ case UNOP_PREINCREMENT:
+ return "UNOP_PREINCREMENT";
+ case UNOP_POSTINCREMENT:
+ return "UNOP_POSTINCREMENT";
+ case UNOP_PREDECREMENT:
+ return "UNOP_PREDECREMENT";
+ case UNOP_POSTDECREMENT:
+ return "UNOP_POSTDECREMENT";
+ case UNOP_SIZEOF:
+ return "UNOP_SIZEOF";
+ case UNOP_LOWER:
+ return "UNOP_LOWER";
+ case UNOP_UPPER:
+ return "UNOP_UPPER";
+ case UNOP_LENGTH:
+ return "UNOP_LENGTH";
+ case UNOP_PLUS:
+ return "UNOP_PLUS";
+ case UNOP_CAP:
+ return "UNOP_CAP";
+ case UNOP_CHR:
+ return "UNOP_CHR";
+ case UNOP_ORD:
+ return "UNOP_ORD";
+ case UNOP_ABS:
+ return "UNOP_ABS";
+ case UNOP_FLOAT:
+ return "UNOP_FLOAT";
+ case UNOP_HIGH:
+ return "UNOP_HIGH";
+ case UNOP_MAX:
+ return "UNOP_MAX";
+ case UNOP_MIN:
+ return "UNOP_MIN";
+ case UNOP_ODD:
+ return "UNOP_ODD";
+ case UNOP_TRUNC:
+ return "UNOP_TRUNC";
+ case OP_BOOL:
+ return "OP_BOOL";
+ case OP_M2_STRING:
+ return "OP_M2_STRING";
+ case STRUCTOP_STRUCT:
+ return "STRUCTOP_STRUCT";
+ case STRUCTOP_PTR:
+ return "STRUCTOP_PTR";
+ case OP_THIS:
+ return "OP_THIS";
+ case OP_SCOPE:
+ return "OP_SCOPE";
+ case OP_TYPE:
+ return "OP_TYPE";
+ case OP_LABELED:
+ return "OP_LABELED";
+ }
+}
+
+void
+dump_prefix_expression (struct expression *exp, struct ui_file *stream,
+ char *note)
+{
+ int elt;
+ char *opcode_name;
+ char *eltscan;
+ int eltsize;
+
+ fprintf_filtered (stream, "Dump of expression @ ");
+ gdb_print_host_address (exp, stream);
+ fprintf_filtered (stream, ", %s:\nExpression: `", note);
+ if (exp->elts[0].opcode != OP_TYPE)
+ print_expression (exp, stream);
+ else
+ fprintf_filtered (stream, "Type printing not yet supported....");
+ fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n",
+ exp->language_defn->la_name, exp->nelts,
+ (long) sizeof (union exp_element));
+ fprintf_filtered (stream, "\t%5s %20s %16s %s\n", "Index", "Opcode",
+ "Hex Value", "String Value");
+ for (elt = 0; elt < exp->nelts; elt++)
+ {
+ fprintf_filtered (stream, "\t%5d ", elt);
+ opcode_name = op_name (exp->elts[elt].opcode);
+
+ fprintf_filtered (stream, "%20s ", opcode_name);
+ print_longest (stream, 'd', 0, exp->elts[elt].longconst);
+ fprintf_filtered (stream, " ");
+
+ for (eltscan = (char *) &exp->elts[elt],
+ eltsize = sizeof (union exp_element);
+ eltsize-- > 0;
+ eltscan++)
+ {
+ fprintf_filtered (stream, "%c",
+ isprint (*eltscan) ? (*eltscan & 0xFF) : '.');
+ }
+ fprintf_filtered (stream, "\n");
+ }
+}
+
+static int dump_subexp (struct expression *exp, struct ui_file *stream,
+ int elt);
+
+static int
+dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
+{
+ static int indent = 0;
+ int i;
+
+ fprintf_filtered (stream, "\n");
+ fprintf_filtered (stream, "\t%5d ", elt);
+
+ for (i = 1; i <= indent; i++)
+ fprintf_filtered (stream, " ");
+ indent += 2;
+
+ fprintf_filtered (stream, "%-20s ", op_name (exp->elts[elt].opcode));
+
+ switch (exp->elts[elt++].opcode)
+ {
+ case TERNOP_COND:
+ case TERNOP_SLICE:
+ case TERNOP_SLICE_COUNT:
+ elt = dump_subexp (exp, stream, elt);
+ case BINOP_ADD:
+ case BINOP_SUB:
+ case BINOP_MUL:
+ case BINOP_DIV:
+ case BINOP_REM:
+ case BINOP_MOD:
+ case BINOP_LSH:
+ case BINOP_RSH:
+ case BINOP_LOGICAL_AND:
+ case BINOP_LOGICAL_OR:
+ case BINOP_BITWISE_AND:
+ case BINOP_BITWISE_IOR:
+ case BINOP_BITWISE_XOR:
+ case BINOP_EQUAL:
+ case BINOP_NOTEQUAL:
+ case BINOP_LESS:
+ case BINOP_GTR:
+ case BINOP_LEQ:
+ case BINOP_GEQ:
+ case BINOP_REPEAT:
+ case BINOP_ASSIGN:
+ case BINOP_COMMA:
+ case BINOP_SUBSCRIPT:
+ case BINOP_EXP:
+ case BINOP_MIN:
+ case BINOP_MAX:
+ case BINOP_INTDIV:
+ case BINOP_ASSIGN_MODIFY:
+ case BINOP_VAL:
+ case BINOP_INCL:
+ case BINOP_EXCL:
+ case BINOP_CONCAT:
+ case BINOP_IN:
+ case BINOP_RANGE:
+ case BINOP_END:
+ elt = dump_subexp (exp, stream, elt);
+ case UNOP_NEG:
+ case UNOP_LOGICAL_NOT:
+ case UNOP_COMPLEMENT:
+ case UNOP_IND:
+ case UNOP_ADDR:
+ case UNOP_PREINCREMENT:
+ case UNOP_POSTINCREMENT:
+ case UNOP_PREDECREMENT:
+ case UNOP_POSTDECREMENT:
+ case UNOP_SIZEOF:
+ case UNOP_PLUS:
+ case UNOP_CAP:
+ case UNOP_CHR:
+ case UNOP_ORD:
+ case UNOP_ABS:
+ case UNOP_FLOAT:
+ case UNOP_HIGH:
+ case UNOP_MAX:
+ case UNOP_MIN:
+ case UNOP_ODD:
+ case UNOP_TRUNC:
+ case UNOP_LOWER:
+ case UNOP_UPPER:
+ case UNOP_LENGTH:
+ case UNOP_CARD:
+ case UNOP_CHMAX:
+ case UNOP_CHMIN:
+ elt = dump_subexp (exp, stream, elt);
+ break;
+ case OP_LONG:
+ fprintf_filtered (stream, "Type @");
+ gdb_print_host_address (exp->elts[elt].type, stream);
+ fprintf_filtered (stream, " (");
+ type_print (exp->elts[elt].type, NULL, stream, 0);
+ fprintf_filtered (stream, "), value %ld (0x%lx)",
+ (long) exp->elts[elt + 1].longconst,
+ (long) exp->elts[elt + 1].longconst);
+ elt += 3;
+ break;
+ case OP_DOUBLE:
+ fprintf_filtered (stream, "Type @");
+ gdb_print_host_address (exp->elts[elt].type, stream);
+ fprintf_filtered (stream, " (");
+ type_print (exp->elts[elt].type, NULL, stream, 0);
+ fprintf_filtered (stream, "), value %g",
+ (double) exp->elts[elt + 1].doubleconst);
+ elt += 3;
+ break;
+ case OP_VAR_VALUE:
+ fprintf_filtered (stream, "Block @");
+ gdb_print_host_address (exp->elts[elt].block, stream);
+ fprintf_filtered (stream, ", symbol @");
+ gdb_print_host_address (exp->elts[elt + 1].symbol, stream);
+ fprintf_filtered (stream, " (%s)",
+ SYMBOL_NAME (exp->elts[elt + 1].symbol));
+ elt += 3;
+ break;
+ case OP_LAST:
+ fprintf_filtered (stream, "History element %ld",
+ (long) exp->elts[elt].longconst);
+ elt += 2;
+ break;
+ case OP_REGISTER:
+ fprintf_filtered (stream, "Register %ld",
+ (long) exp->elts[elt].longconst);
+ elt += 2;
+ break;
+ case OP_INTERNALVAR:
+ fprintf_filtered (stream, "Internal var @");
+ gdb_print_host_address (exp->elts[elt].internalvar, stream);
+ fprintf_filtered (stream, " (%s)",
+ exp->elts[elt].internalvar->name);
+ elt += 2;
+ break;
+ case OP_FUNCALL:
+ {
+ int nargs;
+
+ nargs = longest_to_int (exp->elts[elt].longconst);
+
+ fprintf_filtered (stream, "Number of args: %d", nargs);
+ elt += 2;
+
+ for (i = 1; i <= nargs + 1; i++)
+ elt = dump_subexp (exp, stream, elt);
+ }
+ break;
+ case OP_ARRAY:
+ {
+ int lower, upper;
+ int i;
+
+ lower = longest_to_int (exp->elts[elt].longconst);
+ upper = longest_to_int (exp->elts[elt + 1].longconst);
+
+ fprintf_filtered (stream, "Bounds [%d:%d]", lower, upper);
+ elt += 3;
+
+ for (i = 1; i <= upper - lower + 1; i++)
+ elt = dump_subexp (exp, stream, elt);
+ }
+ break;
+ case UNOP_MEMVAL:
+ case UNOP_CAST:
+ fprintf_filtered (stream, "Type @");
+ gdb_print_host_address (exp->elts[elt].type, stream);
+ fprintf_filtered (stream, " (");
+ type_print (exp->elts[elt].type, NULL, stream, 0);
+ fprintf_filtered (stream, ")");
+ elt = dump_subexp (exp, stream, elt + 2);
+ break;
+ case OP_TYPE:
+ fprintf_filtered (stream, "Type @");
+ gdb_print_host_address (exp->elts[elt].type, stream);
+ fprintf_filtered (stream, " (");
+ type_print (exp->elts[elt].type, NULL, stream, 0);
+ fprintf_filtered (stream, ")");
+ elt += 2;
+ break;
+ case STRUCTOP_STRUCT:
+ case STRUCTOP_PTR:
+ {
+ char *elem_name;
+ int len;
+
+ len = longest_to_int (exp->elts[elt].longconst);
+ elem_name = &exp->elts[elt + 1].string;
+
+ fprintf_filtered (stream, "Element name: `%.*s'", len, elem_name);
+ elt = dump_subexp (exp, stream, elt + 3 + BYTES_TO_EXP_ELEM (len + 1));
+ }
+ break;
+ case OP_SCOPE:
+ {
+ char *elem_name;
+ int len;
+
+ fprintf_filtered (stream, "Type @");
+ gdb_print_host_address (exp->elts[elt].type, stream);
+ fprintf_filtered (stream, " (");
+ type_print (exp->elts[elt].type, NULL, stream, 0);
+ fprintf_filtered (stream, ") ");
+
+ len = longest_to_int (exp->elts[elt + 1].longconst);
+ elem_name = &exp->elts[elt + 2].string;
+
+ fprintf_filtered (stream, "Field name: `%.*s'", len, elem_name);
+ elt += 4 + BYTES_TO_EXP_ELEM (len + 1);
+ }
+ break;
+ default:
+ case OP_NULL:
+ case STRUCTOP_MEMBER:
+ case STRUCTOP_MPTR:
+ case MULTI_SUBSCRIPT:
+ case OP_F77_UNDETERMINED_ARGLIST:
+ case OP_COMPLEX:
+ case OP_STRING:
+ case OP_BITSTRING:
+ case OP_BOOL:
+ case OP_M2_STRING:
+ case OP_THIS:
+ case OP_LABELED:
+ case OP_NAME:
+ case OP_EXPRSTRING:
+ fprintf_filtered (stream, "Unknown format");
+ }
+
+ indent -= 2;
+
+ return elt;
+}
+
+void
+dump_postfix_expression (struct expression *exp, struct ui_file *stream,
+ char *note)
+{
+ int elt;
+
+ fprintf_filtered (stream, "Dump of expression @ ");
+ gdb_print_host_address (exp, stream);
+ fprintf_filtered (stream, ", %s:\nExpression: `", note);
+ if (exp->elts[0].opcode != OP_TYPE)
+ print_expression (exp, stream);
+ else
+ fputs_filtered ("Type printing not yet supported....", stream);
+ fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n",
+ exp->language_defn->la_name, exp->nelts,
+ (long) sizeof (union exp_element));
+ fputs_filtered ("\n", stream);
+
+ for (elt = 0; elt < exp->nelts;)
+ elt = dump_subexp (exp, stream, elt);
+ fputs_filtered ("\n", stream);
+}
diff --git a/gdb/expression.h b/gdb/expression.h
new file mode 100644
index 00000000000..0fbab0357c5
--- /dev/null
+++ b/gdb/expression.h
@@ -0,0 +1,381 @@
+/* Definitions for expressions stored in reversed prefix form, for GDB.
+ Copyright 1986, 1989, 1992, 1994, 2000 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. */
+
+#if !defined (EXPRESSION_H)
+#define EXPRESSION_H 1
+
+
+#include "symtab.h" /* Needed for "struct block" type. */
+#include "doublest.h" /* Needed for DOUBLEST. */
+
+
+/* Definitions for saved C expressions. */
+
+/* An expression is represented as a vector of union exp_element's.
+ Each exp_element is an opcode, except that some opcodes cause
+ the following exp_element to be treated as a long or double constant
+ or as a variable. The opcodes are obeyed, using a stack for temporaries.
+ The value is left on the temporary stack at the end. */
+
+/* When it is necessary to include a string,
+ it can occupy as many exp_elements as it needs.
+ We find the length of the string using strlen,
+ divide to find out how many exp_elements are used up,
+ and skip that many. Strings, like numbers, are indicated
+ by the preceding opcode. */
+
+enum exp_opcode
+ {
+ /* Used when it's necessary to pass an opcode which will be ignored,
+ or to catch uninitialized values. */
+ OP_NULL,
+
+/* BINOP_... operate on two values computed by following subexpressions,
+ replacing them by one result value. They take no immediate arguments. */
+
+ BINOP_ADD, /* + */
+ BINOP_SUB, /* - */
+ BINOP_MUL, /* * */
+ BINOP_DIV, /* / */
+ BINOP_REM, /* % */
+ BINOP_MOD, /* mod (Knuth 1.2.4) */
+ BINOP_LSH, /* << */
+ BINOP_RSH, /* >> */
+ BINOP_LOGICAL_AND, /* && */
+ BINOP_LOGICAL_OR, /* || */
+ BINOP_BITWISE_AND, /* & */
+ BINOP_BITWISE_IOR, /* | */
+ BINOP_BITWISE_XOR, /* ^ */
+ BINOP_EQUAL, /* == */
+ BINOP_NOTEQUAL, /* != */
+ BINOP_LESS, /* < */
+ BINOP_GTR, /* > */
+ BINOP_LEQ, /* <= */
+ BINOP_GEQ, /* >= */
+ BINOP_REPEAT, /* @ */
+ BINOP_ASSIGN, /* = */
+ BINOP_COMMA, /* , */
+ BINOP_SUBSCRIPT, /* x[y] */
+ BINOP_EXP, /* Exponentiation */
+
+ /* C++. */
+
+ BINOP_MIN, /* <? */
+ BINOP_MAX, /* >? */
+
+ /* STRUCTOP_MEMBER is used for pointer-to-member constructs.
+ X . * Y translates into X STRUCTOP_MEMBER Y. */
+ STRUCTOP_MEMBER,
+
+ /* STRUCTOP_MPTR is used for pointer-to-member constructs
+ when X is a pointer instead of an aggregate. */
+ STRUCTOP_MPTR,
+
+ /* end of C++. */
+
+ /* For Modula-2 integer division DIV */
+ BINOP_INTDIV,
+
+ BINOP_ASSIGN_MODIFY, /* +=, -=, *=, and so on.
+ The following exp_element is another opcode,
+ a BINOP_, saying how to modify.
+ Then comes another BINOP_ASSIGN_MODIFY,
+ making three exp_elements in total. */
+
+ /* Modula-2 standard (binary) procedures */
+ BINOP_VAL,
+ BINOP_INCL,
+ BINOP_EXCL,
+
+ /* Concatenate two operands, such as character strings or bitstrings.
+ If the first operand is a integer expression, then it means concatenate
+ the second operand with itself that many times. */
+ BINOP_CONCAT,
+
+ /* For Chill and Pascal. */
+ BINOP_IN, /* Returns 1 iff ARG1 IN ARG2. */
+
+ /* This is the "colon operator" used various places in Chill. */
+ BINOP_RANGE,
+
+ /* This must be the highest BINOP_ value, for expprint.c. */
+ BINOP_END,
+
+ /* Operates on three values computed by following subexpressions. */
+ TERNOP_COND, /* ?: */
+
+ /* A sub-string/sub-array. Chill syntax: OP1(OP2:OP3).
+ Return elements OP2 through OP3 of OP1. */
+ TERNOP_SLICE,
+
+ /* A sub-string/sub-array. Chill syntax: OP1(OP2 UP OP3).
+ Return OP3 elements of OP1, starting with element OP2. */
+ TERNOP_SLICE_COUNT,
+
+ /* Multidimensional subscript operator, such as Modula-2 x[a,b,...].
+ The dimensionality is encoded in the operator, like the number of
+ function arguments in OP_FUNCALL, I.E. <OP><dimension><OP>.
+ The value of the first following subexpression is subscripted
+ by each of the next following subexpressions, one per dimension. */
+ MULTI_SUBSCRIPT,
+
+ /* The OP_... series take immediate following arguments.
+ After the arguments come another OP_... (the same one)
+ so that the grouping can be recognized from the end. */
+
+ /* OP_LONG is followed by a type pointer in the next exp_element
+ and the long constant value in the following exp_element.
+ Then comes another OP_LONG.
+ Thus, the operation occupies four exp_elements. */
+ OP_LONG,
+
+ /* OP_DOUBLE is similar but takes a DOUBLEST constant instead of a long. */
+ OP_DOUBLE,
+
+ /* OP_VAR_VALUE takes one struct block * in the following element,
+ and one struct symbol * in the following exp_element, followed by
+ another OP_VAR_VALUE, making four exp_elements. If the block is
+ non-NULL, evaluate the symbol relative to the innermost frame
+ executing in that block; if the block is NULL use the selected frame. */
+ OP_VAR_VALUE,
+
+ /* OP_LAST is followed by an integer in the next exp_element.
+ The integer is zero for the last value printed,
+ or it is the absolute number of a history element.
+ With another OP_LAST at the end, this makes three exp_elements. */
+ OP_LAST,
+
+ /* OP_REGISTER is followed by an integer in the next exp_element.
+ This is the number of a register to fetch (as an int).
+ With another OP_REGISTER at the end, this makes three exp_elements. */
+ OP_REGISTER,
+
+ /* OP_INTERNALVAR is followed by an internalvar ptr in the next exp_element.
+ With another OP_INTERNALVAR at the end, this makes three exp_elements. */
+ OP_INTERNALVAR,
+
+ /* OP_FUNCALL is followed by an integer in the next exp_element.
+ The integer is the number of args to the function call.
+ That many plus one values from following subexpressions
+ are used, the first one being the function.
+ The integer is followed by a repeat of OP_FUNCALL,
+ making three exp_elements. */
+ OP_FUNCALL,
+
+ /* This is EXACTLY like OP_FUNCALL but is semantically different.
+ In F77, array subscript expressions, substring expressions
+ and function calls are all exactly the same syntactically. They may
+ only be dismabiguated at runtime. Thus this operator, which
+ indicates that we have found something of the form <name> ( <stuff> ) */
+ OP_F77_UNDETERMINED_ARGLIST,
+
+ /* The following OP is a special one, it introduces a F77 complex
+ literal. It is followed by exactly two args that are doubles. */
+ OP_COMPLEX,
+
+ /* OP_STRING represents a string constant.
+ Its format is the same as that of a STRUCTOP, but the string
+ data is just made into a string constant when the operation
+ is executed. */
+ OP_STRING,
+
+ /* OP_BITSTRING represents a packed bitstring constant.
+ Its format is the same as that of a STRUCTOP, but the bitstring
+ data is just made into a bitstring constant when the operation
+ is executed. */
+ OP_BITSTRING,
+
+ /* OP_ARRAY creates an array constant out of the following subexpressions.
+ It is followed by two exp_elements, the first containing an integer
+ that is the lower bound of the array and the second containing another
+ integer that is the upper bound of the array. The second integer is
+ followed by a repeat of OP_ARRAY, making four exp_elements total.
+ The bounds are used to compute the number of following subexpressions
+ to consume, as well as setting the bounds in the created array constant.
+ The type of the elements is taken from the type of the first subexp,
+ and they must all match. */
+ OP_ARRAY,
+
+ /* UNOP_CAST is followed by a type pointer in the next exp_element.
+ With another UNOP_CAST at the end, this makes three exp_elements.
+ It casts the value of the following subexpression. */
+ UNOP_CAST,
+
+ /* UNOP_MEMVAL is followed by a type pointer in the next exp_element
+ With another UNOP_MEMVAL at the end, this makes three exp_elements.
+ It casts the contents of the word addressed by the value of the
+ following subexpression. */
+ UNOP_MEMVAL,
+
+ /* UNOP_... operate on one value from a following subexpression
+ and replace it with a result. They take no immediate arguments. */
+
+ UNOP_NEG, /* Unary - */
+ UNOP_LOGICAL_NOT, /* Unary ! */
+ UNOP_COMPLEMENT, /* Unary ~ */
+ UNOP_IND, /* Unary * */
+ UNOP_ADDR, /* Unary & */
+ UNOP_PREINCREMENT, /* ++ before an expression */
+ UNOP_POSTINCREMENT, /* ++ after an expression */
+ UNOP_PREDECREMENT, /* -- before an expression */
+ UNOP_POSTDECREMENT, /* -- after an expression */
+ UNOP_SIZEOF, /* Unary sizeof (followed by expression) */
+
+ UNOP_PLUS, /* Unary plus */
+
+ UNOP_CAP, /* Modula-2 standard (unary) procedures */
+ UNOP_CHR,
+ UNOP_ORD,
+ UNOP_ABS,
+ UNOP_FLOAT,
+ UNOP_HIGH,
+ UNOP_MAX,
+ UNOP_MIN,
+ UNOP_ODD,
+ UNOP_TRUNC,
+
+ /* Chill builtin functions. */
+ UNOP_LOWER, UNOP_UPPER, UNOP_LENGTH, UNOP_CARD, UNOP_CHMAX, UNOP_CHMIN,
+
+ OP_BOOL, /* Modula-2 builtin BOOLEAN type */
+ OP_M2_STRING, /* Modula-2 string constants */
+
+ /* STRUCTOP_... operate on a value from a following subexpression
+ by extracting a structure component specified by a string
+ that appears in the following exp_elements (as many as needed).
+ STRUCTOP_STRUCT is used for "." and STRUCTOP_PTR for "->".
+ They differ only in the error message given in case the value is
+ not suitable or the structure component specified is not found.
+
+ The length of the string follows the opcode, followed by
+ BYTES_TO_EXP_ELEM(length) elements containing the data of the
+ string, followed by the length again and the opcode again. */
+
+ STRUCTOP_STRUCT,
+ STRUCTOP_PTR,
+
+ /* C++ */
+ /* OP_THIS is just a placeholder for the class instance variable.
+ It just comes in a tight (OP_THIS, OP_THIS) pair. */
+ OP_THIS,
+
+ /* OP_SCOPE surrounds a type name and a field name. The type
+ name is encoded as one element, but the field name stays as
+ a string, which, of course, is variable length. */
+ OP_SCOPE,
+
+ /* Used to represent named structure field values in brace initializers
+ (or tuples as they are called in Chill).
+ The gcc C syntax is NAME:VALUE or .NAME=VALUE, the Chill syntax is
+ .NAME:VALUE. Multiple labels (as in the Chill syntax
+ .NAME1,.NAME2:VALUE) is represented as if it were
+ .NAME1:(.NAME2:VALUE) (though that is not valid Chill syntax).
+
+ The NAME is represented as for STRUCTOP_STRUCT; VALUE follows. */
+ OP_LABELED,
+
+ /* OP_TYPE is for parsing types, and used with the "ptype" command
+ so we can look up types that are qualified by scope, either with
+ the GDB "::" operator, or the Modula-2 '.' operator. */
+ OP_TYPE,
+
+ /* An un-looked-up identifier. */
+ OP_NAME,
+
+ /* An unparsed expression. Used for Scheme (for now at least) */
+ OP_EXPRSTRING
+ };
+
+union exp_element
+ {
+ enum exp_opcode opcode;
+ struct symbol *symbol;
+ LONGEST longconst;
+ DOUBLEST doubleconst;
+ /* Really sizeof (union exp_element) characters (or less for the last
+ element of a string). */
+ char string;
+ struct type *type;
+ struct internalvar *internalvar;
+ struct block *block;
+ };
+
+struct expression
+ {
+ const struct language_defn *language_defn; /* language it was entered in */
+ int nelts;
+ union exp_element elts[1];
+ };
+
+/* Macros for converting between number of expression elements and bytes
+ to store that many expression elements. */
+
+#define EXP_ELEM_TO_BYTES(elements) \
+ ((elements) * sizeof (union exp_element))
+#define BYTES_TO_EXP_ELEM(bytes) \
+ (((bytes) + sizeof (union exp_element) - 1) / sizeof (union exp_element))
+
+/* From parse.c */
+
+extern struct expression *parse_expression (char *);
+
+extern struct expression *parse_exp_1 (char **, struct block *, int);
+
+/* The innermost context required by the stack and register variables
+ we've encountered so far. To use this, set it to NULL, then call
+ parse_<whatever>, then look at it. */
+extern struct block *innermost_block;
+
+/* From eval.c */
+
+/* Values of NOSIDE argument to eval_subexp. */
+
+enum noside
+ {
+ EVAL_NORMAL,
+ EVAL_SKIP, /* Only effect is to increment pos. */
+ EVAL_AVOID_SIDE_EFFECTS /* Don't modify any variables or
+ call any functions. The value
+ returned will have the correct
+ type, and will have an
+ approximately correct lvalue
+ type (inaccuracy: anything that is
+ listed as being in a register in
+ the function in which it was
+ declared will be lval_register). */
+ };
+
+extern struct value *evaluate_subexp_standard
+ (struct type *, struct expression *, int *, enum noside);
+
+/* From expprint.c */
+
+extern void print_expression (struct expression *, struct ui_file *);
+
+extern char *op_string (enum exp_opcode);
+
+extern void dump_prefix_expression (struct expression *,
+ struct ui_file *,
+ char *);
+extern void dump_postfix_expression (struct expression *,
+ struct ui_file *,
+ char *);
+
+#endif /* !defined (EXPRESSION_H) */
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
new file mode 100644
index 00000000000..e11687726ef
--- /dev/null
+++ b/gdb/f-exp.y
@@ -0,0 +1,1180 @@
+/* YACC parser for Fortran expressions, for GDB.
+ Copyright 1986, 1989, 1990, 1991, 1993, 1994, 1995, 1996, 2000, 2001
+ Free Software Foundation, Inc.
+
+ Contributed by Motorola. Adapted from the C parser by Farooq Butt
+ (fmbutt@engage.sps.mot.com).
+
+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. */
+
+/* This was blantantly ripped off the C expression parser, please
+ be aware of that as you look at its basic structure -FMB */
+
+/* Parse a F77 expression from text in a string,
+ and return the result as a struct expression pointer.
+ That structure contains arithmetic operations in reverse polish,
+ with constants represented by operations that are followed by special data.
+ See expression.h for the details of the format.
+ What is important here is that it can be built up sequentially
+ during the process of parsing; the lower levels of the tree always
+ come first in the result.
+
+ Note that malloc's and realloc's in this file are transformed to
+ xmalloc and xrealloc respectively by the same sed command in the
+ makefile that remaps any other malloc/realloc inserted by the parser
+ generator. Doing this with #defines and trying to control the interaction
+ with include files (<malloc.h> and <stdlib.h> for example) just became
+ too messy, particularly when such includes can be inserted at random
+ times by the parser generator. */
+
+%{
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "expression.h"
+#include "value.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "f-lang.h"
+#include "bfd.h" /* Required by objfiles.h. */
+#include "symfile.h" /* Required by objfiles.h. */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+#include <ctype.h>
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
+ as well as gratuitiously global symbol names, so we can have multiple
+ yacc generated parsers in gdb. Note that these are only the variables
+ produced by yacc. If other parser generators (bison, byacc, etc) produce
+ additional global names that conflict at link time, then those parser
+ generators need to be fixed instead of adding those names to this list. */
+
+#define yymaxdepth f_maxdepth
+#define yyparse f_parse
+#define yylex f_lex
+#define yyerror f_error
+#define yylval f_lval
+#define yychar f_char
+#define yydebug f_debug
+#define yypact f_pact
+#define yyr1 f_r1
+#define yyr2 f_r2
+#define yydef f_def
+#define yychk f_chk
+#define yypgo f_pgo
+#define yyact f_act
+#define yyexca f_exca
+#define yyerrflag f_errflag
+#define yynerrs f_nerrs
+#define yyps f_ps
+#define yypv f_pv
+#define yys f_s
+#define yy_yys f_yys
+#define yystate f_state
+#define yytmp f_tmp
+#define yyv f_v
+#define yy_yyv f_yyv
+#define yyval f_val
+#define yylloc f_lloc
+#define yyreds f_reds /* With YYDEBUG defined */
+#define yytoks f_toks /* With YYDEBUG defined */
+#define yylhs f_yylhs
+#define yylen f_yylen
+#define yydefred f_yydefred
+#define yydgoto f_yydgoto
+#define yysindex f_yysindex
+#define yyrindex f_yyrindex
+#define yygindex f_yygindex
+#define yytable f_yytable
+#define yycheck f_yycheck
+
+#ifndef YYDEBUG
+#define YYDEBUG 1 /* Default to no yydebug support */
+#endif
+
+int yyparse (void);
+
+static int yylex (void);
+
+void yyerror (char *);
+
+static void growbuf_by_size (int);
+
+static int match_string_literal (void);
+
+%}
+
+/* Although the yacc "value" of an expression is not used,
+ since the result is stored in the structure being created,
+ other node types do have values. */
+
+%union
+ {
+ LONGEST lval;
+ struct {
+ LONGEST val;
+ struct type *type;
+ } typed_val;
+ DOUBLEST dval;
+ struct symbol *sym;
+ struct type *tval;
+ struct stoken sval;
+ struct ttype tsym;
+ struct symtoken ssym;
+ int voidval;
+ struct block *bval;
+ enum exp_opcode opcode;
+ struct internalvar *ivar;
+
+ struct type **tvec;
+ int *ivec;
+ }
+
+%{
+/* YYSTYPE gets defined by %union */
+static int parse_number (char *, int, int, YYSTYPE *);
+%}
+
+%type <voidval> exp type_exp start variable
+%type <tval> type typebase
+%type <tvec> nonempty_typelist
+/* %type <bval> block */
+
+/* Fancy type parsing. */
+%type <voidval> func_mod direct_abs_decl abs_decl
+%type <tval> ptype
+
+%token <typed_val> INT
+%token <dval> FLOAT
+
+/* Both NAME and TYPENAME tokens represent symbols in the input,
+ and both convey their data as strings.
+ But a TYPENAME is a string that happens to be defined as a typedef
+ or builtin type name (such as int or char)
+ and a NAME is any other symbol.
+ Contexts where this distinction is not important can use the
+ nonterminal "name", which matches either NAME or TYPENAME. */
+
+%token <sval> STRING_LITERAL
+%token <lval> BOOLEAN_LITERAL
+%token <ssym> NAME
+%token <tsym> TYPENAME
+%type <sval> name
+%type <ssym> name_not_typename
+%type <tsym> typename
+
+/* A NAME_OR_INT is a symbol which is not known in the symbol table,
+ but which would parse as a valid number in the current input radix.
+ E.g. "c" when input_radix==16. Depending on the parse, it will be
+ turned into a name or into a number. */
+
+%token <ssym> NAME_OR_INT
+
+%token SIZEOF
+%token ERROR
+
+/* Special type cases, put in to allow the parser to distinguish different
+ legal basetypes. */
+%token INT_KEYWORD INT_S2_KEYWORD LOGICAL_S1_KEYWORD LOGICAL_S2_KEYWORD
+%token LOGICAL_KEYWORD REAL_KEYWORD REAL_S8_KEYWORD REAL_S16_KEYWORD
+%token COMPLEX_S8_KEYWORD COMPLEX_S16_KEYWORD COMPLEX_S32_KEYWORD
+%token BOOL_AND BOOL_OR BOOL_NOT
+%token <lval> CHARACTER
+
+%token <voidval> VARIABLE
+
+%token <opcode> ASSIGN_MODIFY
+
+%left ','
+%left ABOVE_COMMA
+%right '=' ASSIGN_MODIFY
+%right '?'
+%left BOOL_OR
+%right BOOL_NOT
+%left BOOL_AND
+%left '|'
+%left '^'
+%left '&'
+%left EQUAL NOTEQUAL
+%left LESSTHAN GREATERTHAN LEQ GEQ
+%left LSH RSH
+%left '@'
+%left '+' '-'
+%left '*' '/' '%'
+%right UNARY
+%right '('
+
+
+%%
+
+start : exp
+ | type_exp
+ ;
+
+type_exp: type
+ { write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type($1);
+ write_exp_elt_opcode(OP_TYPE); }
+ ;
+
+exp : '(' exp ')'
+ { }
+ ;
+
+/* Expressions, not including the comma operator. */
+exp : '*' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_IND); }
+
+exp : '&' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_ADDR); }
+
+exp : '-' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_NEG); }
+ ;
+
+exp : BOOL_NOT exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
+ ;
+
+exp : '~' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_COMPLEMENT); }
+ ;
+
+exp : SIZEOF exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_SIZEOF); }
+ ;
+
+/* No more explicit array operators, we treat everything in F77 as
+ a function call. The disambiguation as to whether we are
+ doing a subscript operation or a function call is done
+ later in eval.c. */
+
+exp : exp '('
+ { start_arglist (); }
+ arglist ')'
+ { write_exp_elt_opcode (OP_F77_UNDETERMINED_ARGLIST);
+ write_exp_elt_longcst ((LONGEST) end_arglist ());
+ write_exp_elt_opcode (OP_F77_UNDETERMINED_ARGLIST); }
+ ;
+
+arglist :
+ ;
+
+arglist : exp
+ { arglist_len = 1; }
+ ;
+
+arglist : substring
+ { arglist_len = 2;}
+
+arglist : arglist ',' exp %prec ABOVE_COMMA
+ { arglist_len++; }
+ ;
+
+substring: exp ':' exp %prec ABOVE_COMMA
+ { }
+ ;
+
+
+complexnum: exp ',' exp
+ { }
+ ;
+
+exp : '(' complexnum ')'
+ { write_exp_elt_opcode(OP_COMPLEX); }
+ ;
+
+exp : '(' type ')' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type ($2);
+ write_exp_elt_opcode (UNOP_CAST); }
+ ;
+
+/* Binary operators in order of decreasing precedence. */
+
+exp : exp '@' exp
+ { write_exp_elt_opcode (BINOP_REPEAT); }
+ ;
+
+exp : exp '*' exp
+ { write_exp_elt_opcode (BINOP_MUL); }
+ ;
+
+exp : exp '/' exp
+ { write_exp_elt_opcode (BINOP_DIV); }
+ ;
+
+exp : exp '%' exp
+ { write_exp_elt_opcode (BINOP_REM); }
+ ;
+
+exp : exp '+' exp
+ { write_exp_elt_opcode (BINOP_ADD); }
+ ;
+
+exp : exp '-' exp
+ { write_exp_elt_opcode (BINOP_SUB); }
+ ;
+
+exp : exp LSH exp
+ { write_exp_elt_opcode (BINOP_LSH); }
+ ;
+
+exp : exp RSH exp
+ { write_exp_elt_opcode (BINOP_RSH); }
+ ;
+
+exp : exp EQUAL exp
+ { write_exp_elt_opcode (BINOP_EQUAL); }
+ ;
+
+exp : exp NOTEQUAL exp
+ { write_exp_elt_opcode (BINOP_NOTEQUAL); }
+ ;
+
+exp : exp LEQ exp
+ { write_exp_elt_opcode (BINOP_LEQ); }
+ ;
+
+exp : exp GEQ exp
+ { write_exp_elt_opcode (BINOP_GEQ); }
+ ;
+
+exp : exp LESSTHAN exp
+ { write_exp_elt_opcode (BINOP_LESS); }
+ ;
+
+exp : exp GREATERTHAN exp
+ { write_exp_elt_opcode (BINOP_GTR); }
+ ;
+
+exp : exp '&' exp
+ { write_exp_elt_opcode (BINOP_BITWISE_AND); }
+ ;
+
+exp : exp '^' exp
+ { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
+ ;
+
+exp : exp '|' exp
+ { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
+ ;
+
+exp : exp BOOL_AND exp
+ { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
+ ;
+
+
+exp : exp BOOL_OR exp
+ { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
+ ;
+
+exp : exp '=' exp
+ { write_exp_elt_opcode (BINOP_ASSIGN); }
+ ;
+
+exp : exp ASSIGN_MODIFY exp
+ { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
+ write_exp_elt_opcode ($2);
+ write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
+ ;
+
+exp : INT
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type ($1.type);
+ write_exp_elt_longcst ((LONGEST)($1.val));
+ write_exp_elt_opcode (OP_LONG); }
+ ;
+
+exp : NAME_OR_INT
+ { YYSTYPE val;
+ parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val);
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (val.typed_val.type);
+ write_exp_elt_longcst ((LONGEST)val.typed_val.val);
+ write_exp_elt_opcode (OP_LONG); }
+ ;
+
+exp : FLOAT
+ { write_exp_elt_opcode (OP_DOUBLE);
+ write_exp_elt_type (builtin_type_f_real_s8);
+ write_exp_elt_dblcst ($1);
+ write_exp_elt_opcode (OP_DOUBLE); }
+ ;
+
+exp : variable
+ ;
+
+exp : VARIABLE
+ ;
+
+exp : SIZEOF '(' type ')' %prec UNARY
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_f_integer);
+ CHECK_TYPEDEF ($3);
+ write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
+ write_exp_elt_opcode (OP_LONG); }
+ ;
+
+exp : BOOLEAN_LITERAL
+ { write_exp_elt_opcode (OP_BOOL);
+ write_exp_elt_longcst ((LONGEST) $1);
+ write_exp_elt_opcode (OP_BOOL);
+ }
+ ;
+
+exp : STRING_LITERAL
+ {
+ write_exp_elt_opcode (OP_STRING);
+ write_exp_string ($1);
+ write_exp_elt_opcode (OP_STRING);
+ }
+ ;
+
+variable: name_not_typename
+ { struct symbol *sym = $1.sym;
+
+ if (sym)
+ {
+ if (symbol_read_needs_frame (sym))
+ {
+ if (innermost_block == 0 ||
+ contained_in (block_found,
+ innermost_block))
+ innermost_block = block_found;
+ }
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ /* We want to use the selected frame, not
+ another more inner frame which happens to
+ be in the same block. */
+ write_exp_elt_block (NULL);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ break;
+ }
+ else
+ {
+ struct minimal_symbol *msymbol;
+ register char *arg = copy_name ($1.stoken);
+
+ msymbol =
+ lookup_minimal_symbol (arg, NULL, NULL);
+ if (msymbol != NULL)
+ {
+ write_exp_msymbol (msymbol,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
+ }
+ else if (!have_full_symbols () && !have_partial_symbols ())
+ error ("No symbol table is loaded. Use the \"file\" command.");
+ else
+ error ("No symbol \"%s\" in current context.",
+ copy_name ($1.stoken));
+ }
+ }
+ ;
+
+
+type : ptype
+ ;
+
+ptype : typebase
+ | typebase abs_decl
+ {
+ /* This is where the interesting stuff happens. */
+ int done = 0;
+ int array_size;
+ struct type *follow_type = $1;
+ struct type *range_type;
+
+ while (!done)
+ switch (pop_type ())
+ {
+ case tp_end:
+ done = 1;
+ break;
+ case tp_pointer:
+ follow_type = lookup_pointer_type (follow_type);
+ break;
+ case tp_reference:
+ follow_type = lookup_reference_type (follow_type);
+ break;
+ case tp_array:
+ array_size = pop_type_int ();
+ if (array_size != -1)
+ {
+ range_type =
+ create_range_type ((struct type *) NULL,
+ builtin_type_f_integer, 0,
+ array_size - 1);
+ follow_type =
+ create_array_type ((struct type *) NULL,
+ follow_type, range_type);
+ }
+ else
+ follow_type = lookup_pointer_type (follow_type);
+ break;
+ case tp_function:
+ follow_type = lookup_function_type (follow_type);
+ break;
+ }
+ $$ = follow_type;
+ }
+ ;
+
+abs_decl: '*'
+ { push_type (tp_pointer); $$ = 0; }
+ | '*' abs_decl
+ { push_type (tp_pointer); $$ = $2; }
+ | '&'
+ { push_type (tp_reference); $$ = 0; }
+ | '&' abs_decl
+ { push_type (tp_reference); $$ = $2; }
+ | direct_abs_decl
+ ;
+
+direct_abs_decl: '(' abs_decl ')'
+ { $$ = $2; }
+ | direct_abs_decl func_mod
+ { push_type (tp_function); }
+ | func_mod
+ { push_type (tp_function); }
+ ;
+
+func_mod: '(' ')'
+ { $$ = 0; }
+ | '(' nonempty_typelist ')'
+ { free ((PTR)$2); $$ = 0; }
+ ;
+
+typebase /* Implements (approximately): (type-qualifier)* type-specifier */
+ : TYPENAME
+ { $$ = $1.type; }
+ | INT_KEYWORD
+ { $$ = builtin_type_f_integer; }
+ | INT_S2_KEYWORD
+ { $$ = builtin_type_f_integer_s2; }
+ | CHARACTER
+ { $$ = builtin_type_f_character; }
+ | LOGICAL_KEYWORD
+ { $$ = builtin_type_f_logical;}
+ | LOGICAL_S2_KEYWORD
+ { $$ = builtin_type_f_logical_s2;}
+ | LOGICAL_S1_KEYWORD
+ { $$ = builtin_type_f_logical_s1;}
+ | REAL_KEYWORD
+ { $$ = builtin_type_f_real;}
+ | REAL_S8_KEYWORD
+ { $$ = builtin_type_f_real_s8;}
+ | REAL_S16_KEYWORD
+ { $$ = builtin_type_f_real_s16;}
+ | COMPLEX_S8_KEYWORD
+ { $$ = builtin_type_f_complex_s8;}
+ | COMPLEX_S16_KEYWORD
+ { $$ = builtin_type_f_complex_s16;}
+ | COMPLEX_S32_KEYWORD
+ { $$ = builtin_type_f_complex_s32;}
+ ;
+
+typename: TYPENAME
+ ;
+
+nonempty_typelist
+ : type
+ { $$ = (struct type **) malloc (sizeof (struct type *) * 2);
+ $<ivec>$[0] = 1; /* Number of types in vector */
+ $$[1] = $1;
+ }
+ | nonempty_typelist ',' type
+ { int len = sizeof (struct type *) * (++($<ivec>1[0]) + 1);
+ $$ = (struct type **) realloc ((char *) $1, len);
+ $$[$<ivec>$[0]] = $3;
+ }
+ ;
+
+name : NAME
+ { $$ = $1.stoken; }
+ | TYPENAME
+ { $$ = $1.stoken; }
+ | NAME_OR_INT
+ { $$ = $1.stoken; }
+ ;
+
+name_not_typename : NAME
+/* These would be useful if name_not_typename was useful, but it is just
+ a fake for "variable", so these cause reduce/reduce conflicts because
+ the parser can't tell whether NAME_OR_INT is a name_not_typename (=variable,
+ =exp) or just an exp. If name_not_typename was ever used in an lvalue
+ context where only a name could occur, this might be useful.
+ | NAME_OR_INT
+ */
+ ;
+
+%%
+
+/* Take care of parsing a number (anything that starts with a digit).
+ Set yylval and return the token type; update lexptr.
+ LEN is the number of characters in it. */
+
+/*** Needs some error checking for the float case ***/
+
+static int
+parse_number (p, len, parsed_float, putithere)
+ register char *p;
+ register int len;
+ int parsed_float;
+ YYSTYPE *putithere;
+{
+ register LONGEST n = 0;
+ register LONGEST prevn = 0;
+ register int c;
+ register int base = input_radix;
+ int unsigned_p = 0;
+ int long_p = 0;
+ ULONGEST high_bit;
+ struct type *signed_type;
+ struct type *unsigned_type;
+
+ if (parsed_float)
+ {
+ /* It's a float since it contains a point or an exponent. */
+ /* [dD] is not understood as an exponent by atof, change it to 'e'. */
+ char *tmp, *tmp2;
+
+ tmp = xstrdup (p);
+ for (tmp2 = tmp; *tmp2; ++tmp2)
+ if (*tmp2 == 'd' || *tmp2 == 'D')
+ *tmp2 = 'e';
+ putithere->dval = atof (tmp);
+ free (tmp);
+ return FLOAT;
+ }
+
+ /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
+ if (p[0] == '0')
+ switch (p[1])
+ {
+ case 'x':
+ case 'X':
+ if (len >= 3)
+ {
+ p += 2;
+ base = 16;
+ len -= 2;
+ }
+ break;
+
+ case 't':
+ case 'T':
+ case 'd':
+ case 'D':
+ if (len >= 3)
+ {
+ p += 2;
+ base = 10;
+ len -= 2;
+ }
+ break;
+
+ default:
+ base = 8;
+ break;
+ }
+
+ while (len-- > 0)
+ {
+ c = *p++;
+ if (isupper (c))
+ c = tolower (c);
+ if (len == 0 && c == 'l')
+ long_p = 1;
+ else if (len == 0 && c == 'u')
+ unsigned_p = 1;
+ else
+ {
+ int i;
+ if (c >= '0' && c <= '9')
+ i = c - '0';
+ else if (c >= 'a' && c <= 'f')
+ i = c - 'a' + 10;
+ else
+ return ERROR; /* Char not a digit */
+ if (i >= base)
+ return ERROR; /* Invalid digit in this base */
+ n *= base;
+ n += i;
+ }
+ /* Portably test for overflow (only works for nonzero values, so make
+ a second check for zero). */
+ if ((prevn >= n) && n != 0)
+ unsigned_p=1; /* Try something unsigned */
+ /* If range checking enabled, portably test for unsigned overflow. */
+ if (RANGE_CHECK && n != 0)
+ {
+ if ((unsigned_p && (unsigned)prevn >= (unsigned)n))
+ range_error("Overflow on numeric constant.");
+ }
+ prevn = n;
+ }
+
+ /* If the number is too big to be an int, or it's got an l suffix
+ then it's a long. Work out if this has to be a long by
+ shifting right and and seeing if anything remains, and the
+ target int size is different to the target long size.
+
+ In the expression below, we could have tested
+ (n >> TARGET_INT_BIT)
+ to see if it was zero,
+ but too many compilers warn about that, when ints and longs
+ are the same size. So we shift it twice, with fewer bits
+ each time, for the same result. */
+
+ if ((TARGET_INT_BIT != TARGET_LONG_BIT
+ && ((n >> 2) >> (TARGET_INT_BIT-2))) /* Avoid shift warning */
+ || long_p)
+ {
+ high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1);
+ unsigned_type = builtin_type_unsigned_long;
+ signed_type = builtin_type_long;
+ }
+ else
+ {
+ high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1);
+ unsigned_type = builtin_type_unsigned_int;
+ signed_type = builtin_type_int;
+ }
+
+ putithere->typed_val.val = n;
+
+ /* If the high bit of the worked out type is set then this number
+ has to be unsigned. */
+
+ if (unsigned_p || (n & high_bit))
+ putithere->typed_val.type = unsigned_type;
+ else
+ putithere->typed_val.type = signed_type;
+
+ return INT;
+}
+
+struct token
+{
+ char *operator;
+ int token;
+ enum exp_opcode opcode;
+};
+
+static const struct token dot_ops[] =
+{
+ { ".and.", BOOL_AND, BINOP_END },
+ { ".AND.", BOOL_AND, BINOP_END },
+ { ".or.", BOOL_OR, BINOP_END },
+ { ".OR.", BOOL_OR, BINOP_END },
+ { ".not.", BOOL_NOT, BINOP_END },
+ { ".NOT.", BOOL_NOT, BINOP_END },
+ { ".eq.", EQUAL, BINOP_END },
+ { ".EQ.", EQUAL, BINOP_END },
+ { ".eqv.", EQUAL, BINOP_END },
+ { ".NEQV.", NOTEQUAL, BINOP_END },
+ { ".neqv.", NOTEQUAL, BINOP_END },
+ { ".EQV.", EQUAL, BINOP_END },
+ { ".ne.", NOTEQUAL, BINOP_END },
+ { ".NE.", NOTEQUAL, BINOP_END },
+ { ".le.", LEQ, BINOP_END },
+ { ".LE.", LEQ, BINOP_END },
+ { ".ge.", GEQ, BINOP_END },
+ { ".GE.", GEQ, BINOP_END },
+ { ".gt.", GREATERTHAN, BINOP_END },
+ { ".GT.", GREATERTHAN, BINOP_END },
+ { ".lt.", LESSTHAN, BINOP_END },
+ { ".LT.", LESSTHAN, BINOP_END },
+ { NULL, 0, 0 }
+};
+
+struct f77_boolean_val
+{
+ char *name;
+ int value;
+};
+
+static const struct f77_boolean_val boolean_values[] =
+{
+ { ".true.", 1 },
+ { ".TRUE.", 1 },
+ { ".false.", 0 },
+ { ".FALSE.", 0 },
+ { NULL, 0 }
+};
+
+static const struct token f77_keywords[] =
+{
+ { "complex_16", COMPLEX_S16_KEYWORD, BINOP_END },
+ { "complex_32", COMPLEX_S32_KEYWORD, BINOP_END },
+ { "character", CHARACTER, BINOP_END },
+ { "integer_2", INT_S2_KEYWORD, BINOP_END },
+ { "logical_1", LOGICAL_S1_KEYWORD, BINOP_END },
+ { "logical_2", LOGICAL_S2_KEYWORD, BINOP_END },
+ { "complex_8", COMPLEX_S8_KEYWORD, BINOP_END },
+ { "integer", INT_KEYWORD, BINOP_END },
+ { "logical", LOGICAL_KEYWORD, BINOP_END },
+ { "real_16", REAL_S16_KEYWORD, BINOP_END },
+ { "complex", COMPLEX_S8_KEYWORD, BINOP_END },
+ { "sizeof", SIZEOF, BINOP_END },
+ { "real_8", REAL_S8_KEYWORD, BINOP_END },
+ { "real", REAL_KEYWORD, BINOP_END },
+ { NULL, 0, 0 }
+};
+
+/* Implementation of a dynamically expandable buffer for processing input
+ characters acquired through lexptr and building a value to return in
+ yylval. Ripped off from ch-exp.y */
+
+static char *tempbuf; /* Current buffer contents */
+static int tempbufsize; /* Size of allocated buffer */
+static int tempbufindex; /* Current index into buffer */
+
+#define GROWBY_MIN_SIZE 64 /* Minimum amount to grow buffer by */
+
+#define CHECKBUF(size) \
+ do { \
+ if (tempbufindex + (size) >= tempbufsize) \
+ { \
+ growbuf_by_size (size); \
+ } \
+ } while (0);
+
+
+/* Grow the static temp buffer if necessary, including allocating the first one
+ on demand. */
+
+static void
+growbuf_by_size (count)
+ int count;
+{
+ int growby;
+
+ growby = max (count, GROWBY_MIN_SIZE);
+ tempbufsize += growby;
+ if (tempbuf == NULL)
+ tempbuf = (char *) malloc (tempbufsize);
+ else
+ tempbuf = (char *) realloc (tempbuf, tempbufsize);
+}
+
+/* Blatantly ripped off from ch-exp.y. This routine recognizes F77
+ string-literals.
+
+ Recognize a string literal. A string literal is a nonzero sequence
+ of characters enclosed in matching single quotes, except that
+ a single character inside single quotes is a character literal, which
+ we reject as a string literal. To embed the terminator character inside
+ a string, it is simply doubled (I.E. 'this''is''one''string') */
+
+static int
+match_string_literal ()
+{
+ char *tokptr = lexptr;
+
+ for (tempbufindex = 0, tokptr++; *tokptr != '\0'; tokptr++)
+ {
+ CHECKBUF (1);
+ if (*tokptr == *lexptr)
+ {
+ if (*(tokptr + 1) == *lexptr)
+ tokptr++;
+ else
+ break;
+ }
+ tempbuf[tempbufindex++] = *tokptr;
+ }
+ if (*tokptr == '\0' /* no terminator */
+ || tempbufindex == 0) /* no string */
+ return 0;
+ else
+ {
+ tempbuf[tempbufindex] = '\0';
+ yylval.sval.ptr = tempbuf;
+ yylval.sval.length = tempbufindex;
+ lexptr = ++tokptr;
+ return STRING_LITERAL;
+ }
+}
+
+/* Read one token, getting characters through lexptr. */
+
+static int
+yylex ()
+{
+ int c;
+ int namelen;
+ unsigned int i,token;
+ char *tokstart;
+
+ retry:
+
+ prev_lexptr = lexptr;
+
+ tokstart = lexptr;
+
+ /* First of all, let us make sure we are not dealing with the
+ special tokens .true. and .false. which evaluate to 1 and 0. */
+
+ if (*lexptr == '.')
+ {
+ for (i = 0; boolean_values[i].name != NULL; i++)
+ {
+ if STREQN (tokstart, boolean_values[i].name,
+ strlen (boolean_values[i].name))
+ {
+ lexptr += strlen (boolean_values[i].name);
+ yylval.lval = boolean_values[i].value;
+ return BOOLEAN_LITERAL;
+ }
+ }
+ }
+
+ /* See if it is a special .foo. operator */
+
+ for (i = 0; dot_ops[i].operator != NULL; i++)
+ if (STREQN (tokstart, dot_ops[i].operator, strlen (dot_ops[i].operator)))
+ {
+ lexptr += strlen (dot_ops[i].operator);
+ yylval.opcode = dot_ops[i].opcode;
+ return dot_ops[i].token;
+ }
+
+ switch (c = *tokstart)
+ {
+ case 0:
+ return 0;
+
+ case ' ':
+ case '\t':
+ case '\n':
+ lexptr++;
+ goto retry;
+
+ case '\'':
+ token = match_string_literal ();
+ if (token != 0)
+ return (token);
+ break;
+
+ case '(':
+ paren_depth++;
+ lexptr++;
+ return c;
+
+ case ')':
+ if (paren_depth == 0)
+ return 0;
+ paren_depth--;
+ lexptr++;
+ return c;
+
+ case ',':
+ if (comma_terminates && paren_depth == 0)
+ return 0;
+ lexptr++;
+ return c;
+
+ case '.':
+ /* Might be a floating point number. */
+ if (lexptr[1] < '0' || lexptr[1] > '9')
+ goto symbol; /* Nope, must be a symbol. */
+ /* FALL THRU into number case. */
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ /* It's a number. */
+ int got_dot = 0, got_e = 0, got_d = 0, toktype;
+ register char *p = tokstart;
+ int hex = input_radix > 10;
+
+ if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
+ {
+ p += 2;
+ hex = 1;
+ }
+ else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
+ {
+ p += 2;
+ hex = 0;
+ }
+
+ for (;; ++p)
+ {
+ if (!hex && !got_e && (*p == 'e' || *p == 'E'))
+ got_dot = got_e = 1;
+ else if (!hex && !got_d && (*p == 'd' || *p == 'D'))
+ got_dot = got_d = 1;
+ else if (!hex && !got_dot && *p == '.')
+ got_dot = 1;
+ else if (((got_e && (p[-1] == 'e' || p[-1] == 'E'))
+ || (got_d && (p[-1] == 'd' || p[-1] == 'D')))
+ && (*p == '-' || *p == '+'))
+ /* This is the sign of the exponent, not the end of the
+ number. */
+ continue;
+ /* We will take any letters or digits. parse_number will
+ complain if past the radix, or if L or U are not final. */
+ else if ((*p < '0' || *p > '9')
+ && ((*p < 'a' || *p > 'z')
+ && (*p < 'A' || *p > 'Z')))
+ break;
+ }
+ toktype = parse_number (tokstart, p - tokstart, got_dot|got_e|got_d,
+ &yylval);
+ if (toktype == ERROR)
+ {
+ char *err_copy = (char *) alloca (p - tokstart + 1);
+
+ memcpy (err_copy, tokstart, p - tokstart);
+ err_copy[p - tokstart] = 0;
+ error ("Invalid number \"%s\".", err_copy);
+ }
+ lexptr = p;
+ return toktype;
+ }
+
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '%':
+ case '|':
+ case '&':
+ case '^':
+ case '~':
+ case '!':
+ case '@':
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case '?':
+ case ':':
+ case '=':
+ case '{':
+ case '}':
+ symbol:
+ lexptr++;
+ return c;
+ }
+
+ if (!(c == '_' || c == '$'
+ || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
+ /* We must have come across a bad character (e.g. ';'). */
+ error ("Invalid character '%c' in expression.", c);
+
+ namelen = 0;
+ for (c = tokstart[namelen];
+ (c == '_' || c == '$' || (c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
+ c = tokstart[++namelen]);
+
+ /* The token "if" terminates the expression and is NOT
+ removed from the input stream. */
+
+ if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
+ return 0;
+
+ lexptr += namelen;
+
+ /* Catch specific keywords. */
+
+ for (i = 0; f77_keywords[i].operator != NULL; i++)
+ if (STREQN(tokstart, f77_keywords[i].operator,
+ strlen(f77_keywords[i].operator)))
+ {
+ /* lexptr += strlen(f77_keywords[i].operator); */
+ yylval.opcode = f77_keywords[i].opcode;
+ return f77_keywords[i].token;
+ }
+
+ yylval.sval.ptr = tokstart;
+ yylval.sval.length = namelen;
+
+ if (*tokstart == '$')
+ {
+ write_dollar_variable (yylval.sval);
+ return VARIABLE;
+ }
+
+ /* Use token-type TYPENAME for symbols that happen to be defined
+ currently as names of types; NAME for other symbols.
+ The caller is not constrained to care about the distinction. */
+ {
+ char *tmp = copy_name (yylval.sval);
+ struct symbol *sym;
+ int is_a_field_of_this = 0;
+ int hextype;
+
+ sym = lookup_symbol (tmp, expression_context_block,
+ VAR_NAMESPACE,
+ current_language->la_language == language_cplus
+ ? &is_a_field_of_this : NULL,
+ NULL);
+ if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+ {
+ yylval.tsym.type = SYMBOL_TYPE (sym);
+ return TYPENAME;
+ }
+ if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
+ return TYPENAME;
+
+ /* Input names that aren't symbols but ARE valid hex numbers,
+ when the input radix permits them, can be names or numbers
+ depending on the parse. Note we support radixes > 16 here. */
+ if (!sym
+ && ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10)
+ || (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
+ {
+ YYSTYPE newlval; /* Its value is ignored. */
+ hextype = parse_number (tokstart, namelen, 0, &newlval);
+ if (hextype == INT)
+ {
+ yylval.ssym.sym = sym;
+ yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+ return NAME_OR_INT;
+ }
+ }
+
+ /* Any other kind of symbol */
+ yylval.ssym.sym = sym;
+ yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+ return NAME;
+ }
+}
+
+void
+yyerror (msg)
+ char *msg;
+{
+ if (prev_lexptr)
+ lexptr = prev_lexptr;
+
+ error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
+}
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
new file mode 100644
index 00000000000..85866b360c8
--- /dev/null
+++ b/gdb/f-lang.c
@@ -0,0 +1,957 @@
+/* Fortran language support routines for GDB, the GNU debugger.
+ Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ Contributed by Motorola. Adapted from the C parser by Farooq Butt
+ (fmbutt@engage.sps.mot.com).
+
+ 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 "defs.h"
+#include "gdb_string.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "f-lang.h"
+#include "valprint.h"
+
+/* The built-in types of F77. FIXME: integer*4 is missing, plain
+ logical is missing (builtin_type_logical is logical*4). */
+
+struct type *builtin_type_f_character;
+struct type *builtin_type_f_logical;
+struct type *builtin_type_f_logical_s1;
+struct type *builtin_type_f_logical_s2;
+struct type *builtin_type_f_integer;
+struct type *builtin_type_f_integer_s2;
+struct type *builtin_type_f_real;
+struct type *builtin_type_f_real_s8;
+struct type *builtin_type_f_real_s16;
+struct type *builtin_type_f_complex_s8;
+struct type *builtin_type_f_complex_s16;
+struct type *builtin_type_f_complex_s32;
+struct type *builtin_type_f_void;
+
+/* Following is dubious stuff that had been in the xcoff reader. */
+
+struct saved_fcn
+ {
+ long line_offset; /* Line offset for function */
+ struct saved_fcn *next;
+ };
+
+
+struct saved_bf_symnum
+ {
+ long symnum_fcn; /* Symnum of function (i.e. .function directive) */
+ long symnum_bf; /* Symnum of .bf for this function */
+ struct saved_bf_symnum *next;
+ };
+
+typedef struct saved_fcn SAVED_FUNCTION, *SAVED_FUNCTION_PTR;
+typedef struct saved_bf_symnum SAVED_BF, *SAVED_BF_PTR;
+
+/* Local functions */
+
+extern void _initialize_f_language (void);
+#if 0
+static void clear_function_list (void);
+static long get_bf_for_fcn (long);
+static void clear_bf_list (void);
+static void patch_all_commons_by_name (char *, CORE_ADDR, int);
+static SAVED_F77_COMMON_PTR find_first_common_named (char *);
+static void add_common_entry (struct symbol *);
+static void add_common_block (char *, CORE_ADDR, int, char *);
+static SAVED_FUNCTION *allocate_saved_function_node (void);
+static SAVED_BF_PTR allocate_saved_bf_node (void);
+static COMMON_ENTRY_PTR allocate_common_entry_node (void);
+static SAVED_F77_COMMON_PTR allocate_saved_f77_common_node (void);
+static void patch_common_entries (SAVED_F77_COMMON_PTR, CORE_ADDR, int);
+#endif
+
+static struct type *f_create_fundamental_type (struct objfile *, int);
+static void f_printstr (struct ui_file * stream, char *string,
+ unsigned int length, int width,
+ int force_ellipses);
+static void f_printchar (int c, struct ui_file * stream);
+static void f_emit_char (int c, struct ui_file * stream, int quoter);
+
+/* Print the character C on STREAM as part of the contents of a literal
+ string whose delimiter is QUOTER. Note that that format for printing
+ characters and strings is language specific.
+ FIXME: This is a copy of the same function from c-exp.y. It should
+ be replaced with a true F77 version. */
+
+static void
+f_emit_char (register int c, struct ui_file *stream, int quoter)
+{
+ c &= 0xFF; /* Avoid sign bit follies */
+
+ if (PRINT_LITERAL_FORM (c))
+ {
+ if (c == '\\' || c == quoter)
+ fputs_filtered ("\\", stream);
+ fprintf_filtered (stream, "%c", c);
+ }
+ else
+ {
+ switch (c)
+ {
+ case '\n':
+ fputs_filtered ("\\n", stream);
+ break;
+ case '\b':
+ fputs_filtered ("\\b", stream);
+ break;
+ case '\t':
+ fputs_filtered ("\\t", stream);
+ break;
+ case '\f':
+ fputs_filtered ("\\f", stream);
+ break;
+ case '\r':
+ fputs_filtered ("\\r", stream);
+ break;
+ case '\033':
+ fputs_filtered ("\\e", stream);
+ break;
+ case '\007':
+ fputs_filtered ("\\a", stream);
+ break;
+ default:
+ fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
+ break;
+ }
+ }
+}
+
+/* FIXME: This is a copy of the same function from c-exp.y. It should
+ be replaced with a true F77version. */
+
+static void
+f_printchar (int c, struct ui_file *stream)
+{
+ fputs_filtered ("'", stream);
+ LA_EMIT_CHAR (c, stream, '\'');
+ fputs_filtered ("'", stream);
+}
+
+/* Print the character string STRING, printing at most LENGTH characters.
+ Printing stops early if the number hits print_max; repeat counts
+ are printed as appropriate. Print ellipses at the end if we
+ had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.
+ FIXME: This is a copy of the same function from c-exp.y. It should
+ be replaced with a true F77 version. */
+
+static void
+f_printstr (struct ui_file *stream, char *string, unsigned int length,
+ int width, int force_ellipses)
+{
+ register unsigned int i;
+ unsigned int things_printed = 0;
+ int in_quotes = 0;
+ int need_comma = 0;
+ extern int inspect_it;
+
+ if (length == 0)
+ {
+ fputs_filtered ("''", gdb_stdout);
+ return;
+ }
+
+ for (i = 0; i < length && things_printed < print_max; ++i)
+ {
+ /* Position of the character we are examining
+ to see whether it is repeated. */
+ unsigned int rep1;
+ /* Number of repetitions we have detected so far. */
+ unsigned int reps;
+
+ QUIT;
+
+ if (need_comma)
+ {
+ fputs_filtered (", ", stream);
+ need_comma = 0;
+ }
+
+ rep1 = i + 1;
+ reps = 1;
+ while (rep1 < length && string[rep1] == string[i])
+ {
+ ++rep1;
+ ++reps;
+ }
+
+ if (reps > repeat_count_threshold)
+ {
+ if (in_quotes)
+ {
+ if (inspect_it)
+ fputs_filtered ("\\', ", stream);
+ else
+ fputs_filtered ("', ", stream);
+ in_quotes = 0;
+ }
+ f_printchar (string[i], stream);
+ fprintf_filtered (stream, " <repeats %u times>", reps);
+ i = rep1 - 1;
+ things_printed += repeat_count_threshold;
+ need_comma = 1;
+ }
+ else
+ {
+ if (!in_quotes)
+ {
+ if (inspect_it)
+ fputs_filtered ("\\'", stream);
+ else
+ fputs_filtered ("'", stream);
+ in_quotes = 1;
+ }
+ LA_EMIT_CHAR (string[i], stream, '"');
+ ++things_printed;
+ }
+ }
+
+ /* Terminate the quotes if necessary. */
+ if (in_quotes)
+ {
+ if (inspect_it)
+ fputs_filtered ("\\'", stream);
+ else
+ fputs_filtered ("'", stream);
+ }
+
+ if (force_ellipses || i < length)
+ fputs_filtered ("...", stream);
+}
+
+/* FIXME: This is a copy of c_create_fundamental_type(), before
+ all the non-C types were stripped from it. Needs to be fixed
+ by an experienced F77 programmer. */
+
+static struct type *
+f_create_fundamental_type (struct objfile *objfile, int typeid)
+{
+ register struct type *type = NULL;
+
+ switch (typeid)
+ {
+ case FT_VOID:
+ type = init_type (TYPE_CODE_VOID,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "VOID", objfile);
+ break;
+ case FT_BOOLEAN:
+ type = init_type (TYPE_CODE_BOOL,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "boolean", objfile);
+ break;
+ case FT_STRING:
+ type = init_type (TYPE_CODE_STRING,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "string", objfile);
+ break;
+ case FT_CHAR:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "character", objfile);
+ break;
+ case FT_SIGNED_CHAR:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "integer*1", objfile);
+ break;
+ case FT_UNSIGNED_CHAR:
+ type = init_type (TYPE_CODE_BOOL,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "logical*1", objfile);
+ break;
+ case FT_SHORT:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ 0, "integer*2", objfile);
+ break;
+ case FT_SIGNED_SHORT:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ 0, "short", objfile); /* FIXME-fnf */
+ break;
+ case FT_UNSIGNED_SHORT:
+ type = init_type (TYPE_CODE_BOOL,
+ TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "logical*2", objfile);
+ break;
+ case FT_INTEGER:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "integer*4", objfile);
+ break;
+ case FT_SIGNED_INTEGER:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "integer", objfile); /* FIXME -fnf */
+ break;
+ case FT_UNSIGNED_INTEGER:
+ type = init_type (TYPE_CODE_BOOL,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "logical*4", objfile);
+ break;
+ case FT_FIXED_DECIMAL:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "fixed decimal", objfile);
+ break;
+ case FT_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "long", objfile);
+ break;
+ case FT_SIGNED_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "long", objfile); /* FIXME -fnf */
+ break;
+ case FT_UNSIGNED_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned long", objfile);
+ break;
+ case FT_LONG_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "long long", objfile);
+ break;
+ case FT_SIGNED_LONG_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "signed long long", objfile);
+ break;
+ case FT_UNSIGNED_LONG_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned long long", objfile);
+ break;
+ case FT_FLOAT:
+ type = init_type (TYPE_CODE_FLT,
+ TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0, "real", objfile);
+ break;
+ case FT_DBL_PREC_FLOAT:
+ type = init_type (TYPE_CODE_FLT,
+ TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "real*8", objfile);
+ break;
+ case FT_FLOAT_DECIMAL:
+ type = init_type (TYPE_CODE_FLT,
+ TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "floating decimal", objfile);
+ break;
+ case FT_EXT_PREC_FLOAT:
+ type = init_type (TYPE_CODE_FLT,
+ TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "real*16", objfile);
+ break;
+ case FT_COMPLEX:
+ type = init_type (TYPE_CODE_COMPLEX,
+ 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0, "complex*8", objfile);
+ TYPE_TARGET_TYPE (type) = builtin_type_f_real;
+ break;
+ case FT_DBL_PREC_COMPLEX:
+ type = init_type (TYPE_CODE_COMPLEX,
+ 2 * TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "complex*16", objfile);
+ TYPE_TARGET_TYPE (type) = builtin_type_f_real_s8;
+ break;
+ case FT_EXT_PREC_COMPLEX:
+ type = init_type (TYPE_CODE_COMPLEX,
+ 2 * TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "complex*32", objfile);
+ TYPE_TARGET_TYPE (type) = builtin_type_f_real_s16;
+ break;
+ default:
+ /* FIXME: For now, if we are asked to produce a type not in this
+ language, create the equivalent of a C integer type with the
+ name "<?type?>". When all the dust settles from the type
+ reconstruction work, this should probably become an error. */
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "<?type?>", objfile);
+ warning ("internal error: no F77 fundamental type %d", typeid);
+ break;
+ }
+ return (type);
+}
+
+
+/* Table of operators and their precedences for printing expressions. */
+
+static const struct op_print f_op_print_tab[] =
+{
+ {"+", BINOP_ADD, PREC_ADD, 0},
+ {"+", UNOP_PLUS, PREC_PREFIX, 0},
+ {"-", BINOP_SUB, PREC_ADD, 0},
+ {"-", UNOP_NEG, PREC_PREFIX, 0},
+ {"*", BINOP_MUL, PREC_MUL, 0},
+ {"/", BINOP_DIV, PREC_MUL, 0},
+ {"DIV", BINOP_INTDIV, PREC_MUL, 0},
+ {"MOD", BINOP_REM, PREC_MUL, 0},
+ {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
+ {".OR.", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
+ {".AND.", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
+ {".NOT.", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
+ {".EQ.", BINOP_EQUAL, PREC_EQUAL, 0},
+ {".NE.", BINOP_NOTEQUAL, PREC_EQUAL, 0},
+ {".LE.", BINOP_LEQ, PREC_ORDER, 0},
+ {".GE.", BINOP_GEQ, PREC_ORDER, 0},
+ {".GT.", BINOP_GTR, PREC_ORDER, 0},
+ {".LT.", BINOP_LESS, PREC_ORDER, 0},
+ {"**", UNOP_IND, PREC_PREFIX, 0},
+ {"@", BINOP_REPEAT, PREC_REPEAT, 0},
+ {NULL, 0, 0, 0}
+};
+
+struct type **const (f_builtin_types[]) =
+{
+ &builtin_type_f_character,
+ &builtin_type_f_logical,
+ &builtin_type_f_logical_s1,
+ &builtin_type_f_logical_s2,
+ &builtin_type_f_integer,
+ &builtin_type_f_integer_s2,
+ &builtin_type_f_real,
+ &builtin_type_f_real_s8,
+ &builtin_type_f_real_s16,
+ &builtin_type_f_complex_s8,
+ &builtin_type_f_complex_s16,
+#if 0
+ &builtin_type_f_complex_s32,
+#endif
+ &builtin_type_f_void,
+ 0
+};
+
+/* This is declared in c-lang.h but it is silly to import that file for what
+ is already just a hack. */
+extern int c_value_print (struct value *, struct ui_file *, int,
+ enum val_prettyprint);
+
+const struct language_defn f_language_defn =
+{
+ "fortran",
+ language_fortran,
+ f_builtin_types,
+ range_check_on,
+ type_check_on,
+ case_sensitive_off,
+ f_parse, /* parser */
+ f_error, /* parser error function */
+ evaluate_subexp_standard,
+ f_printchar, /* Print character constant */
+ f_printstr, /* function to print string constant */
+ f_emit_char, /* Function to print a single character */
+ f_create_fundamental_type, /* Create fundamental type in this language */
+ f_print_type, /* Print a type using appropriate syntax */
+ f_val_print, /* Print a value using appropriate syntax */
+ c_value_print, /* FIXME */
+ {"", "", "", ""}, /* Binary format info */
+ {"0%o", "0", "o", ""}, /* Octal format info */
+ {"%d", "", "d", ""}, /* Decimal format info */
+ {"0x%x", "0x", "x", ""}, /* Hex format info */
+ f_op_print_tab, /* expression operators for printing */
+ 0, /* arrays are first-class (not c-style) */
+ 1, /* String lower bound */
+ &builtin_type_f_character, /* Type of string elements */
+ LANG_MAGIC
+};
+
+void
+_initialize_f_language (void)
+{
+ builtin_type_f_void =
+ init_type (TYPE_CODE_VOID, 1,
+ 0,
+ "VOID", (struct objfile *) NULL);
+
+ builtin_type_f_character =
+ init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0,
+ "character", (struct objfile *) NULL);
+
+ builtin_type_f_logical_s1 =
+ init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "logical*1", (struct objfile *) NULL);
+
+ builtin_type_f_integer_s2 =
+ init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ 0,
+ "integer*2", (struct objfile *) NULL);
+
+ builtin_type_f_logical_s2 =
+ init_type (TYPE_CODE_BOOL, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "logical*2", (struct objfile *) NULL);
+
+ builtin_type_f_integer =
+ init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0,
+ "integer", (struct objfile *) NULL);
+
+ builtin_type_f_logical =
+ init_type (TYPE_CODE_BOOL, TARGET_INT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "logical*4", (struct objfile *) NULL);
+
+ builtin_type_f_real =
+ init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0,
+ "real", (struct objfile *) NULL);
+
+ builtin_type_f_real_s8 =
+ init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0,
+ "real*8", (struct objfile *) NULL);
+
+ builtin_type_f_real_s16 =
+ init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0,
+ "real*16", (struct objfile *) NULL);
+
+ builtin_type_f_complex_s8 =
+ init_type (TYPE_CODE_COMPLEX, 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0,
+ "complex*8", (struct objfile *) NULL);
+ TYPE_TARGET_TYPE (builtin_type_f_complex_s8) = builtin_type_f_real;
+
+ builtin_type_f_complex_s16 =
+ init_type (TYPE_CODE_COMPLEX, 2 * TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0,
+ "complex*16", (struct objfile *) NULL);
+ TYPE_TARGET_TYPE (builtin_type_f_complex_s16) = builtin_type_f_real_s8;
+
+ /* We have a new size == 4 double floats for the
+ complex*32 data type */
+
+ builtin_type_f_complex_s32 =
+ init_type (TYPE_CODE_COMPLEX, 2 * TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0,
+ "complex*32", (struct objfile *) NULL);
+ TYPE_TARGET_TYPE (builtin_type_f_complex_s32) = builtin_type_f_real_s16;
+
+ builtin_type_string =
+ init_type (TYPE_CODE_STRING, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0,
+ "character string", (struct objfile *) NULL);
+
+ add_language (&f_language_defn);
+}
+
+#if 0
+static SAVED_BF_PTR
+allocate_saved_bf_node (void)
+{
+ SAVED_BF_PTR new;
+
+ new = (SAVED_BF_PTR) xmalloc (sizeof (SAVED_BF));
+ return (new);
+}
+
+static SAVED_FUNCTION *
+allocate_saved_function_node (void)
+{
+ SAVED_FUNCTION *new;
+
+ new = (SAVED_FUNCTION *) xmalloc (sizeof (SAVED_FUNCTION));
+ return (new);
+}
+
+static SAVED_F77_COMMON_PTR
+allocate_saved_f77_common_node (void)
+{
+ SAVED_F77_COMMON_PTR new;
+
+ new = (SAVED_F77_COMMON_PTR) xmalloc (sizeof (SAVED_F77_COMMON));
+ return (new);
+}
+
+static COMMON_ENTRY_PTR
+allocate_common_entry_node (void)
+{
+ COMMON_ENTRY_PTR new;
+
+ new = (COMMON_ENTRY_PTR) xmalloc (sizeof (COMMON_ENTRY));
+ return (new);
+}
+#endif
+
+SAVED_F77_COMMON_PTR head_common_list = NULL; /* Ptr to 1st saved COMMON */
+SAVED_F77_COMMON_PTR tail_common_list = NULL; /* Ptr to last saved COMMON */
+SAVED_F77_COMMON_PTR current_common = NULL; /* Ptr to current COMMON */
+
+#if 0
+static SAVED_BF_PTR saved_bf_list = NULL; /* Ptr to (.bf,function)
+ list */
+static SAVED_BF_PTR saved_bf_list_end = NULL; /* Ptr to above list's end */
+static SAVED_BF_PTR current_head_bf_list = NULL; /* Current head of above list
+ */
+
+static SAVED_BF_PTR tmp_bf_ptr; /* Generic temporary for use
+ in macros */
+
+/* The following function simply enters a given common block onto
+ the global common block chain */
+
+static void
+add_common_block (char *name, CORE_ADDR offset, int secnum, char *func_stab)
+{
+ SAVED_F77_COMMON_PTR tmp;
+ char *c, *local_copy_func_stab;
+
+ /* If the COMMON block we are trying to add has a blank
+ name (i.e. "#BLNK_COM") then we set it to __BLANK
+ because the darn "#" character makes GDB's input
+ parser have fits. */
+
+
+ if (STREQ (name, BLANK_COMMON_NAME_ORIGINAL) ||
+ STREQ (name, BLANK_COMMON_NAME_MF77))
+ {
+
+ xfree (name);
+ name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1);
+ strcpy (name, BLANK_COMMON_NAME_LOCAL);
+ }
+
+ tmp = allocate_saved_f77_common_node ();
+
+ local_copy_func_stab = xmalloc (strlen (func_stab) + 1);
+ strcpy (local_copy_func_stab, func_stab);
+
+ tmp->name = xmalloc (strlen (name) + 1);
+
+ /* local_copy_func_stab is a stabstring, let us first extract the
+ function name from the stab by NULLing out the ':' character. */
+
+
+ c = NULL;
+ c = strchr (local_copy_func_stab, ':');
+
+ if (c)
+ *c = '\0';
+ else
+ error ("Malformed function STAB found in add_common_block()");
+
+
+ tmp->owning_function = xmalloc (strlen (local_copy_func_stab) + 1);
+
+ strcpy (tmp->owning_function, local_copy_func_stab);
+
+ strcpy (tmp->name, name);
+ tmp->offset = offset;
+ tmp->next = NULL;
+ tmp->entries = NULL;
+ tmp->secnum = secnum;
+
+ current_common = tmp;
+
+ if (head_common_list == NULL)
+ {
+ head_common_list = tail_common_list = tmp;
+ }
+ else
+ {
+ tail_common_list->next = tmp;
+ tail_common_list = tmp;
+ }
+}
+#endif
+
+/* The following function simply enters a given common entry onto
+ the "current_common" block that has been saved away. */
+
+#if 0
+static void
+add_common_entry (struct symbol *entry_sym_ptr)
+{
+ COMMON_ENTRY_PTR tmp;
+
+
+
+ /* The order of this list is important, since
+ we expect the entries to appear in decl.
+ order when we later issue "info common" calls */
+
+ tmp = allocate_common_entry_node ();
+
+ tmp->next = NULL;
+ tmp->symbol = entry_sym_ptr;
+
+ if (current_common == NULL)
+ error ("Attempt to add COMMON entry with no block open!");
+ else
+ {
+ if (current_common->entries == NULL)
+ {
+ current_common->entries = tmp;
+ current_common->end_of_entries = tmp;
+ }
+ else
+ {
+ current_common->end_of_entries->next = tmp;
+ current_common->end_of_entries = tmp;
+ }
+ }
+}
+#endif
+
+/* This routine finds the first encountred COMMON block named "name" */
+
+#if 0
+static SAVED_F77_COMMON_PTR
+find_first_common_named (char *name)
+{
+
+ SAVED_F77_COMMON_PTR tmp;
+
+ tmp = head_common_list;
+
+ while (tmp != NULL)
+ {
+ if (STREQ (tmp->name, name))
+ return (tmp);
+ else
+ tmp = tmp->next;
+ }
+ return (NULL);
+}
+#endif
+
+/* This routine finds the first encountred COMMON block named "name"
+ that belongs to function funcname */
+
+SAVED_F77_COMMON_PTR
+find_common_for_function (char *name, char *funcname)
+{
+
+ SAVED_F77_COMMON_PTR tmp;
+
+ tmp = head_common_list;
+
+ while (tmp != NULL)
+ {
+ if (STREQ (tmp->name, name) && STREQ (tmp->owning_function, funcname))
+ return (tmp);
+ else
+ tmp = tmp->next;
+ }
+ return (NULL);
+}
+
+
+#if 0
+
+/* The following function is called to patch up the offsets
+ for the statics contained in the COMMON block named
+ "name." */
+
+static void
+patch_common_entries (SAVED_F77_COMMON_PTR blk, CORE_ADDR offset, int secnum)
+{
+ COMMON_ENTRY_PTR entry;
+
+ blk->offset = offset; /* Keep this around for future use. */
+
+ entry = blk->entries;
+
+ while (entry != NULL)
+ {
+ SYMBOL_VALUE (entry->symbol) += offset;
+ SYMBOL_SECTION (entry->symbol) = secnum;
+
+ entry = entry->next;
+ }
+ blk->secnum = secnum;
+}
+
+/* Patch all commons named "name" that need patching.Since COMMON
+ blocks occur with relative infrequency, we simply do a linear scan on
+ the name. Eventually, the best way to do this will be a
+ hashed-lookup. Secnum is the section number for the .bss section
+ (which is where common data lives). */
+
+static void
+patch_all_commons_by_name (char *name, CORE_ADDR offset, int secnum)
+{
+
+ SAVED_F77_COMMON_PTR tmp;
+
+ /* For blank common blocks, change the canonical reprsentation
+ of a blank name */
+
+ if ((STREQ (name, BLANK_COMMON_NAME_ORIGINAL)) ||
+ (STREQ (name, BLANK_COMMON_NAME_MF77)))
+ {
+ xfree (name);
+ name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1);
+ strcpy (name, BLANK_COMMON_NAME_LOCAL);
+ }
+
+ tmp = head_common_list;
+
+ while (tmp != NULL)
+ {
+ if (COMMON_NEEDS_PATCHING (tmp))
+ if (STREQ (tmp->name, name))
+ patch_common_entries (tmp, offset, secnum);
+
+ tmp = tmp->next;
+ }
+}
+#endif
+
+/* This macro adds the symbol-number for the start of the function
+ (the symbol number of the .bf) referenced by symnum_fcn to a
+ list. This list, in reality should be a FIFO queue but since
+ #line pragmas sometimes cause line ranges to get messed up
+ we simply create a linear list. This list can then be searched
+ first by a queueing algorithm and upon failure fall back to
+ a linear scan. */
+
+#if 0
+#define ADD_BF_SYMNUM(bf_sym,fcn_sym) \
+ \
+ if (saved_bf_list == NULL) \
+{ \
+ tmp_bf_ptr = allocate_saved_bf_node(); \
+ \
+ tmp_bf_ptr->symnum_bf = (bf_sym); \
+ tmp_bf_ptr->symnum_fcn = (fcn_sym); \
+ tmp_bf_ptr->next = NULL; \
+ \
+ current_head_bf_list = saved_bf_list = tmp_bf_ptr; \
+ saved_bf_list_end = tmp_bf_ptr; \
+ } \
+else \
+{ \
+ tmp_bf_ptr = allocate_saved_bf_node(); \
+ \
+ tmp_bf_ptr->symnum_bf = (bf_sym); \
+ tmp_bf_ptr->symnum_fcn = (fcn_sym); \
+ tmp_bf_ptr->next = NULL; \
+ \
+ saved_bf_list_end->next = tmp_bf_ptr; \
+ saved_bf_list_end = tmp_bf_ptr; \
+ }
+#endif
+
+/* This function frees the entire (.bf,function) list */
+
+#if 0
+static void
+clear_bf_list (void)
+{
+
+ SAVED_BF_PTR tmp = saved_bf_list;
+ SAVED_BF_PTR next = NULL;
+
+ while (tmp != NULL)
+ {
+ next = tmp->next;
+ xfree (tmp);
+ tmp = next;
+ }
+ saved_bf_list = NULL;
+}
+#endif
+
+int global_remote_debug;
+
+#if 0
+
+static long
+get_bf_for_fcn (long the_function)
+{
+ SAVED_BF_PTR tmp;
+ int nprobes = 0;
+
+ /* First use a simple queuing algorithm (i.e. look and see if the
+ item at the head of the queue is the one you want) */
+
+ if (saved_bf_list == NULL)
+ internal_error (__FILE__, __LINE__,
+ "cannot get .bf node off empty list");
+
+ if (current_head_bf_list != NULL)
+ if (current_head_bf_list->symnum_fcn == the_function)
+ {
+ if (global_remote_debug)
+ fprintf_unfiltered (gdb_stderr, "*");
+
+ tmp = current_head_bf_list;
+ current_head_bf_list = current_head_bf_list->next;
+ return (tmp->symnum_bf);
+ }
+
+ /* If the above did not work (probably because #line directives were
+ used in the sourcefile and they messed up our internal tables) we now do
+ the ugly linear scan */
+
+ if (global_remote_debug)
+ fprintf_unfiltered (gdb_stderr, "\ndefaulting to linear scan\n");
+
+ nprobes = 0;
+ tmp = saved_bf_list;
+ while (tmp != NULL)
+ {
+ nprobes++;
+ if (tmp->symnum_fcn == the_function)
+ {
+ if (global_remote_debug)
+ fprintf_unfiltered (gdb_stderr, "Found in %d probes\n", nprobes);
+ current_head_bf_list = tmp->next;
+ return (tmp->symnum_bf);
+ }
+ tmp = tmp->next;
+ }
+
+ return (-1);
+}
+
+static SAVED_FUNCTION_PTR saved_function_list = NULL;
+static SAVED_FUNCTION_PTR saved_function_list_end = NULL;
+
+static void
+clear_function_list (void)
+{
+ SAVED_FUNCTION_PTR tmp = saved_function_list;
+ SAVED_FUNCTION_PTR next = NULL;
+
+ while (tmp != NULL)
+ {
+ next = tmp->next;
+ xfree (tmp);
+ tmp = next;
+ }
+
+ saved_function_list = NULL;
+}
+#endif
diff --git a/gdb/f-lang.h b/gdb/f-lang.h
new file mode 100644
index 00000000000..d929b919fc0
--- /dev/null
+++ b/gdb/f-lang.h
@@ -0,0 +1,98 @@
+/* Fortran language support definitions for GDB, the GNU debugger.
+ Copyright 1992, 1993, 1994, 1995, 1998, 2000
+ Free Software Foundation, Inc.
+ Contributed by Motorola. Adapted from the C definitions by Farooq Butt
+ (fmbutt@engage.sps.mot.com).
+
+ 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. */
+
+extern int f_parse (void);
+
+extern void f_error (char *); /* Defined in f-exp.y */
+
+extern void f_print_type (struct type *, char *, struct ui_file *, int,
+ int);
+
+extern int f_val_print (struct type *, char *, int, CORE_ADDR,
+ struct ui_file *, int, int, int,
+ enum val_prettyprint);
+
+/* Language-specific data structures */
+
+struct common_entry
+ {
+ struct symbol *symbol; /* The symbol node corresponding
+ to this component */
+ struct common_entry *next; /* The next component */
+ };
+
+struct saved_f77_common
+ {
+ char *name; /* Name of COMMON */
+ char *owning_function; /* Name of parent function */
+ int secnum; /* Section # of .bss */
+ CORE_ADDR offset; /* Offset from .bss for
+ this block */
+ struct common_entry *entries; /* List of block's components */
+ struct common_entry *end_of_entries; /* ptr. to end of components */
+ struct saved_f77_common *next; /* Next saved COMMON block */
+ };
+
+typedef struct saved_f77_common SAVED_F77_COMMON, *SAVED_F77_COMMON_PTR;
+
+typedef struct common_entry COMMON_ENTRY, *COMMON_ENTRY_PTR;
+
+extern SAVED_F77_COMMON_PTR head_common_list; /* Ptr to 1st saved COMMON */
+extern SAVED_F77_COMMON_PTR tail_common_list; /* Ptr to last saved COMMON */
+extern SAVED_F77_COMMON_PTR current_common; /* Ptr to current COMMON */
+
+extern SAVED_F77_COMMON_PTR find_common_for_function (char *, char *);
+
+#define UNINITIALIZED_SECNUM -1
+#define COMMON_NEEDS_PATCHING(blk) ((blk)->secnum == UNINITIALIZED_SECNUM)
+
+#define BLANK_COMMON_NAME_ORIGINAL "#BLNK_COM" /* XLF assigned */
+#define BLANK_COMMON_NAME_MF77 "__BLNK__" /* MF77 assigned */
+#define BLANK_COMMON_NAME_LOCAL "__BLANK" /* Local GDB */
+
+#define BOUND_FETCH_OK 1
+#define BOUND_FETCH_ERROR -999
+
+/* When reasonable array bounds cannot be fetched, such as when
+ you ask to 'mt print symbols' and there is no stack frame and
+ therefore no way of knowing the bounds of stack-based arrays,
+ we have to assign default bounds, these are as good as any... */
+
+#define DEFAULT_UPPER_BOUND 999999
+#define DEFAULT_LOWER_BOUND -999999
+
+extern char *real_main_name; /* Name of main function */
+extern int real_main_c_value; /* C_value field of main function */
+
+extern int f77_get_dynamic_upperbound (struct type *, int *);
+
+extern int f77_get_dynamic_lowerbound (struct type *, int *);
+
+extern void f77_get_dynamic_array_length (struct type *);
+
+extern int calc_f77_array_dims (struct type *);
+
+#define DEFAULT_DOTMAIN_NAME_IN_MF77 ".MAIN_"
+#define DEFAULT_MAIN_NAME_IN_MF77 "MAIN_"
+#define DEFAULT_DOTMAIN_NAME_IN_XLF_BUGGY ".main "
+#define DEFAULT_DOTMAIN_NAME_IN_XLF ".main"
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
new file mode 100644
index 00000000000..2beae0fed7f
--- /dev/null
+++ b/gdb/f-typeprint.c
@@ -0,0 +1,400 @@
+/* Support for printing Fortran types for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1998, 2000,
+ 2001, 2002
+ Free Software Foundation, Inc.
+ Contributed by Motorola. Adapted from the C version by Farooq Butt
+ (fmbutt@engage.sps.mot.com).
+
+ 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 "defs.h"
+#include "obstack.h"
+#include "bfd.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "f-lang.h"
+
+#include "gdb_string.h"
+#include <errno.h>
+
+#if 0 /* Currently unused */
+static void f_type_print_args (struct type *, struct ui_file *);
+#endif
+
+static void print_equivalent_f77_float_type (struct type *,
+ struct ui_file *);
+
+static void f_type_print_varspec_suffix (struct type *, struct ui_file *,
+ int, int, int);
+
+void f_type_print_varspec_prefix (struct type *, struct ui_file *,
+ int, int);
+
+void f_type_print_base (struct type *, struct ui_file *, int, int);
+
+
+/* LEVEL is the depth to indent lines by. */
+
+void
+f_print_type (struct type *type, char *varstring, struct ui_file *stream,
+ int show, int level)
+{
+ register enum type_code code;
+ int demangled_args;
+
+ f_type_print_base (type, stream, show, level);
+ code = TYPE_CODE (type);
+ if ((varstring != NULL && *varstring != '\0')
+ ||
+ /* Need a space if going to print stars or brackets;
+ but not if we will print just a type name. */
+ ((show > 0 || TYPE_NAME (type) == 0)
+ &&
+ (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC
+ || code == TYPE_CODE_METHOD
+ || code == TYPE_CODE_ARRAY
+ || code == TYPE_CODE_MEMBER
+ || code == TYPE_CODE_REF)))
+ fputs_filtered (" ", stream);
+ f_type_print_varspec_prefix (type, stream, show, 0);
+
+ fputs_filtered (varstring, stream);
+
+ /* For demangled function names, we have the arglist as part of the name,
+ so don't print an additional pair of ()'s */
+
+ demangled_args = varstring[strlen (varstring) - 1] == ')';
+ f_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
+}
+
+/* Print any asterisks or open-parentheses needed before the
+ variable name (to describe its type).
+
+ On outermost call, pass 0 for PASSED_A_PTR.
+ On outermost call, SHOW > 0 means should ignore
+ any typename for TYPE and show its details.
+ SHOW is always zero on recursive calls. */
+
+void
+f_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
+ int show, int passed_a_ptr)
+{
+ if (type == 0)
+ return;
+
+ if (TYPE_NAME (type) && show <= 0)
+ return;
+
+ QUIT;
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_PTR:
+ f_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
+ break;
+
+ case TYPE_CODE_FUNC:
+ f_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+ if (passed_a_ptr)
+ fprintf_filtered (stream, "(");
+ break;
+
+ case TYPE_CODE_ARRAY:
+ f_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+ break;
+
+ case TYPE_CODE_UNDEF:
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_ERROR:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_SET:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_STRING:
+ case TYPE_CODE_BITSTRING:
+ case TYPE_CODE_METHOD:
+ case TYPE_CODE_MEMBER:
+ case TYPE_CODE_REF:
+ case TYPE_CODE_COMPLEX:
+ case TYPE_CODE_TYPEDEF:
+ /* These types need no prefix. They are listed here so that
+ gcc -Wall will reveal any types that haven't been handled. */
+ break;
+ }
+}
+
+/* Print any array sizes, function arguments or close parentheses
+ needed after the variable name (to describe its type).
+ Args work like c_type_print_varspec_prefix. */
+
+static void
+f_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
+ int show, int passed_a_ptr, int demangled_args)
+{
+ int upper_bound, lower_bound;
+ int lower_bound_was_default = 0;
+ static int arrayprint_recurse_level = 0;
+ int retcode;
+
+ if (type == 0)
+ return;
+
+ if (TYPE_NAME (type) && show <= 0)
+ return;
+
+ QUIT;
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ arrayprint_recurse_level++;
+
+ if (arrayprint_recurse_level == 1)
+ fprintf_filtered (stream, "(");
+
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY)
+ f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0);
+
+ retcode = f77_get_dynamic_lowerbound (type, &lower_bound);
+
+ lower_bound_was_default = 0;
+
+ if (retcode == BOUND_FETCH_ERROR)
+ fprintf_filtered (stream, "???");
+ else if (lower_bound == 1) /* The default */
+ lower_bound_was_default = 1;
+ else
+ fprintf_filtered (stream, "%d", lower_bound);
+
+ if (lower_bound_was_default)
+ lower_bound_was_default = 0;
+ else
+ fprintf_filtered (stream, ":");
+
+ /* Make sure that, if we have an assumed size array, we
+ print out a warning and print the upperbound as '*' */
+
+ if (TYPE_ARRAY_UPPER_BOUND_TYPE (type) == BOUND_CANNOT_BE_DETERMINED)
+ fprintf_filtered (stream, "*");
+ else
+ {
+ retcode = f77_get_dynamic_upperbound (type, &upper_bound);
+
+ if (retcode == BOUND_FETCH_ERROR)
+ fprintf_filtered (stream, "???");
+ else
+ fprintf_filtered (stream, "%d", upper_bound);
+ }
+
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_ARRAY)
+ f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0);
+ if (arrayprint_recurse_level == 1)
+ fprintf_filtered (stream, ")");
+ else
+ fprintf_filtered (stream, ",");
+ arrayprint_recurse_level--;
+ break;
+
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_REF:
+ f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1, 0);
+ fprintf_filtered (stream, ")");
+ break;
+
+ case TYPE_CODE_FUNC:
+ f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
+ passed_a_ptr, 0);
+ if (passed_a_ptr)
+ fprintf_filtered (stream, ")");
+
+ fprintf_filtered (stream, "()");
+ break;
+
+ case TYPE_CODE_UNDEF:
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_ERROR:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_SET:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_STRING:
+ case TYPE_CODE_BITSTRING:
+ case TYPE_CODE_METHOD:
+ case TYPE_CODE_MEMBER:
+ case TYPE_CODE_COMPLEX:
+ case TYPE_CODE_TYPEDEF:
+ /* These types do not need a suffix. They are listed so that
+ gcc -Wall will report types that may not have been considered. */
+ break;
+ }
+}
+
+static void
+print_equivalent_f77_float_type (struct type *type, struct ui_file *stream)
+{
+ /* Override type name "float" and make it the
+ appropriate real. XLC stupidly outputs -12 as a type
+ for real when it really should be outputting -18 */
+
+ fprintf_filtered (stream, "real*%d", TYPE_LENGTH (type));
+}
+
+/* Print the name of the type (or the ultimate pointer target,
+ function value or array element), or the description of a
+ structure or union.
+
+ SHOW nonzero means don't print this type as just its name;
+ show its real definition even if it has a name.
+ SHOW zero means print just typename or struct tag if there is one
+ SHOW negative means abbreviate structure elements.
+ SHOW is decremented for printing of structure elements.
+
+ LEVEL is the depth to indent by.
+ We increase it for some recursive calls. */
+
+void
+f_type_print_base (struct type *type, struct ui_file *stream, int show,
+ int level)
+{
+ int retcode;
+ int upper_bound;
+
+ QUIT;
+
+ wrap_here (" ");
+ if (type == NULL)
+ {
+ fputs_filtered ("<type unknown>", stream);
+ return;
+ }
+
+ /* When SHOW is zero or less, and there is a valid type name, then always
+ just print the type name directly from the type. */
+
+ if ((show <= 0) && (TYPE_NAME (type) != NULL))
+ {
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ print_equivalent_f77_float_type (type, stream);
+ else
+ fputs_filtered (TYPE_NAME (type), stream);
+ return;
+ }
+
+ if (TYPE_CODE (type) != TYPE_CODE_TYPEDEF)
+ CHECK_TYPEDEF (type);
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_TYPEDEF:
+ f_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level);
+ break;
+
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_FUNC:
+ f_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
+ break;
+
+ case TYPE_CODE_PTR:
+ fprintf_filtered (stream, "PTR TO -> ( ");
+ f_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level);
+ break;
+
+ case TYPE_CODE_VOID:
+ fprintf_filtered (stream, "VOID");
+ break;
+
+ case TYPE_CODE_UNDEF:
+ fprintf_filtered (stream, "struct <unknown>");
+ break;
+
+ case TYPE_CODE_ERROR:
+ fprintf_filtered (stream, "<unknown type>");
+ break;
+
+ case TYPE_CODE_RANGE:
+ /* This should not occur */
+ fprintf_filtered (stream, "<range type>");
+ break;
+
+ case TYPE_CODE_CHAR:
+ /* Override name "char" and make it "character" */
+ fprintf_filtered (stream, "character");
+ break;
+
+ case TYPE_CODE_INT:
+ /* There may be some character types that attempt to come
+ through as TYPE_CODE_INT since dbxstclass.h is so
+ C-oriented, we must change these to "character" from "char". */
+
+ if (STREQ (TYPE_NAME (type), "char"))
+ fprintf_filtered (stream, "character");
+ else
+ goto default_case;
+ break;
+
+ case TYPE_CODE_COMPLEX:
+ fprintf_filtered (stream, "complex*%d", TYPE_LENGTH (type));
+ break;
+
+ case TYPE_CODE_FLT:
+ print_equivalent_f77_float_type (type, stream);
+ break;
+
+ case TYPE_CODE_STRING:
+ /* Strings may have dynamic upperbounds (lengths) like arrays. */
+
+ if (TYPE_ARRAY_UPPER_BOUND_TYPE (type) == BOUND_CANNOT_BE_DETERMINED)
+ fprintf_filtered (stream, "character*(*)");
+ else
+ {
+ retcode = f77_get_dynamic_upperbound (type, &upper_bound);
+
+ if (retcode == BOUND_FETCH_ERROR)
+ fprintf_filtered (stream, "character*???");
+ else
+ fprintf_filtered (stream, "character*%d", upper_bound);
+ }
+ break;
+
+ default_case:
+ default:
+ /* Handle types not explicitly handled by the other cases,
+ such as fundamental types. For these, just print whatever
+ the type name is, as recorded in the type itself. If there
+ is no type name, then complain. */
+ if (TYPE_NAME (type) != NULL)
+ fputs_filtered (TYPE_NAME (type), stream);
+ else
+ error ("Invalid type code (%d) in symbol table.", TYPE_CODE (type));
+ break;
+ }
+}
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
new file mode 100644
index 00000000000..48c511377e8
--- /dev/null
+++ b/gdb/f-valprint.c
@@ -0,0 +1,739 @@
+/* Support for printing Fortran values for GDB, the GNU debugger.
+ Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000
+ Free Software Foundation, Inc.
+ Contributed by Motorola. Adapted from the C definitions by Farooq Butt
+ (fmbutt@engage.sps.mot.com), additionally worked over by Stan Shebs.
+
+ 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 "defs.h"
+#include "gdb_string.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "valprint.h"
+#include "language.h"
+#include "f-lang.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "command.h"
+
+#if 0
+static int there_is_a_visible_common_named (char *);
+#endif
+
+extern void _initialize_f_valprint (void);
+static void info_common_command (char *, int);
+static void list_all_visible_commons (char *);
+static void f77_print_array (struct type *, char *, CORE_ADDR,
+ struct ui_file *, int, int, int,
+ enum val_prettyprint);
+static void f77_print_array_1 (int, int, struct type *, char *,
+ CORE_ADDR, struct ui_file *, int, int, int,
+ enum val_prettyprint);
+static void f77_create_arrayprint_offset_tbl (struct type *,
+ struct ui_file *);
+static void f77_get_dynamic_length_of_aggregate (struct type *);
+
+int f77_array_offset_tbl[MAX_FORTRAN_DIMS + 1][2];
+
+/* Array which holds offsets to be applied to get a row's elements
+ for a given array. Array also holds the size of each subarray. */
+
+/* The following macro gives us the size of the nth dimension, Where
+ n is 1 based. */
+
+#define F77_DIM_SIZE(n) (f77_array_offset_tbl[n][1])
+
+/* The following gives us the offset for row n where n is 1-based. */
+
+#define F77_DIM_OFFSET(n) (f77_array_offset_tbl[n][0])
+
+int
+f77_get_dynamic_lowerbound (struct type *type, int *lower_bound)
+{
+ CORE_ADDR current_frame_addr;
+ CORE_ADDR ptr_to_lower_bound;
+
+ switch (TYPE_ARRAY_LOWER_BOUND_TYPE (type))
+ {
+ case BOUND_BY_VALUE_ON_STACK:
+ current_frame_addr = selected_frame->frame;
+ if (current_frame_addr > 0)
+ {
+ *lower_bound =
+ read_memory_integer (current_frame_addr +
+ TYPE_ARRAY_LOWER_BOUND_VALUE (type),
+ 4);
+ }
+ else
+ {
+ *lower_bound = DEFAULT_LOWER_BOUND;
+ return BOUND_FETCH_ERROR;
+ }
+ break;
+
+ case BOUND_SIMPLE:
+ *lower_bound = TYPE_ARRAY_LOWER_BOUND_VALUE (type);
+ break;
+
+ case BOUND_CANNOT_BE_DETERMINED:
+ error ("Lower bound may not be '*' in F77");
+ break;
+
+ case BOUND_BY_REF_ON_STACK:
+ current_frame_addr = selected_frame->frame;
+ if (current_frame_addr > 0)
+ {
+ ptr_to_lower_bound =
+ read_memory_integer (current_frame_addr +
+ TYPE_ARRAY_LOWER_BOUND_VALUE (type),
+ 4);
+ *lower_bound = read_memory_integer (ptr_to_lower_bound, 4);
+ }
+ else
+ {
+ *lower_bound = DEFAULT_LOWER_BOUND;
+ return BOUND_FETCH_ERROR;
+ }
+ break;
+
+ case BOUND_BY_REF_IN_REG:
+ case BOUND_BY_VALUE_IN_REG:
+ default:
+ error ("??? unhandled dynamic array bound type ???");
+ break;
+ }
+ return BOUND_FETCH_OK;
+}
+
+int
+f77_get_dynamic_upperbound (struct type *type, int *upper_bound)
+{
+ CORE_ADDR current_frame_addr = 0;
+ CORE_ADDR ptr_to_upper_bound;
+
+ switch (TYPE_ARRAY_UPPER_BOUND_TYPE (type))
+ {
+ case BOUND_BY_VALUE_ON_STACK:
+ current_frame_addr = selected_frame->frame;
+ if (current_frame_addr > 0)
+ {
+ *upper_bound =
+ read_memory_integer (current_frame_addr +
+ TYPE_ARRAY_UPPER_BOUND_VALUE (type),
+ 4);
+ }
+ else
+ {
+ *upper_bound = DEFAULT_UPPER_BOUND;
+ return BOUND_FETCH_ERROR;
+ }
+ break;
+
+ case BOUND_SIMPLE:
+ *upper_bound = TYPE_ARRAY_UPPER_BOUND_VALUE (type);
+ break;
+
+ case BOUND_CANNOT_BE_DETERMINED:
+ /* we have an assumed size array on our hands. Assume that
+ upper_bound == lower_bound so that we show at least
+ 1 element.If the user wants to see more elements, let
+ him manually ask for 'em and we'll subscript the
+ array and show him */
+ f77_get_dynamic_lowerbound (type, upper_bound);
+ break;
+
+ case BOUND_BY_REF_ON_STACK:
+ current_frame_addr = selected_frame->frame;
+ if (current_frame_addr > 0)
+ {
+ ptr_to_upper_bound =
+ read_memory_integer (current_frame_addr +
+ TYPE_ARRAY_UPPER_BOUND_VALUE (type),
+ 4);
+ *upper_bound = read_memory_integer (ptr_to_upper_bound, 4);
+ }
+ else
+ {
+ *upper_bound = DEFAULT_UPPER_BOUND;
+ return BOUND_FETCH_ERROR;
+ }
+ break;
+
+ case BOUND_BY_REF_IN_REG:
+ case BOUND_BY_VALUE_IN_REG:
+ default:
+ error ("??? unhandled dynamic array bound type ???");
+ break;
+ }
+ return BOUND_FETCH_OK;
+}
+
+/* Obtain F77 adjustable array dimensions */
+
+static void
+f77_get_dynamic_length_of_aggregate (struct type *type)
+{
+ int upper_bound = -1;
+ int lower_bound = 1;
+ int retcode;
+
+ /* Recursively go all the way down into a possibly multi-dimensional
+ F77 array and get the bounds. For simple arrays, this is pretty
+ easy but when the bounds are dynamic, we must be very careful
+ to add up all the lengths correctly. Not doing this right
+ will lead to horrendous-looking arrays in parameter lists.
+
+ This function also works for strings which behave very
+ similarly to arrays. */
+
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY
+ || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRING)
+ f77_get_dynamic_length_of_aggregate (TYPE_TARGET_TYPE (type));
+
+ /* Recursion ends here, start setting up lengths. */
+ retcode = f77_get_dynamic_lowerbound (type, &lower_bound);
+ if (retcode == BOUND_FETCH_ERROR)
+ error ("Cannot obtain valid array lower bound");
+
+ retcode = f77_get_dynamic_upperbound (type, &upper_bound);
+ if (retcode == BOUND_FETCH_ERROR)
+ error ("Cannot obtain valid array upper bound");
+
+ /* Patch in a valid length value. */
+
+ TYPE_LENGTH (type) =
+ (upper_bound - lower_bound + 1) * TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type)));
+}
+
+/* Function that sets up the array offset,size table for the array
+ type "type". */
+
+static void
+f77_create_arrayprint_offset_tbl (struct type *type, struct ui_file *stream)
+{
+ struct type *tmp_type;
+ int eltlen;
+ int ndimen = 1;
+ int upper, lower, retcode;
+
+ tmp_type = type;
+
+ while ((TYPE_CODE (tmp_type) == TYPE_CODE_ARRAY))
+ {
+ if (TYPE_ARRAY_UPPER_BOUND_TYPE (tmp_type) == BOUND_CANNOT_BE_DETERMINED)
+ fprintf_filtered (stream, "<assumed size array> ");
+
+ retcode = f77_get_dynamic_upperbound (tmp_type, &upper);
+ if (retcode == BOUND_FETCH_ERROR)
+ error ("Cannot obtain dynamic upper bound");
+
+ retcode = f77_get_dynamic_lowerbound (tmp_type, &lower);
+ if (retcode == BOUND_FETCH_ERROR)
+ error ("Cannot obtain dynamic lower bound");
+
+ F77_DIM_SIZE (ndimen) = upper - lower + 1;
+
+ tmp_type = TYPE_TARGET_TYPE (tmp_type);
+ ndimen++;
+ }
+
+ /* Now we multiply eltlen by all the offsets, so that later we
+ can print out array elements correctly. Up till now we
+ know an offset to apply to get the item but we also
+ have to know how much to add to get to the next item */
+
+ ndimen--;
+ eltlen = TYPE_LENGTH (tmp_type);
+ F77_DIM_OFFSET (ndimen) = eltlen;
+ while (--ndimen > 0)
+ {
+ eltlen *= F77_DIM_SIZE (ndimen + 1);
+ F77_DIM_OFFSET (ndimen) = eltlen;
+ }
+}
+
+/* Actual function which prints out F77 arrays, Valaddr == address in
+ the superior. Address == the address in the inferior. */
+
+static void
+f77_print_array_1 (int nss, int ndimensions, struct type *type, char *valaddr,
+ CORE_ADDR address, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
+{
+ int i;
+
+ if (nss != ndimensions)
+ {
+ for (i = 0; i < F77_DIM_SIZE (nss); i++)
+ {
+ fprintf_filtered (stream, "( ");
+ f77_print_array_1 (nss + 1, ndimensions, TYPE_TARGET_TYPE (type),
+ valaddr + i * F77_DIM_OFFSET (nss),
+ address + i * F77_DIM_OFFSET (nss),
+ stream, format, deref_ref, recurse, pretty);
+ fprintf_filtered (stream, ") ");
+ }
+ }
+ else
+ {
+ for (i = 0; (i < F77_DIM_SIZE (nss) && i < print_max); i++)
+ {
+ val_print (TYPE_TARGET_TYPE (type),
+ valaddr + i * F77_DIM_OFFSET (ndimensions),
+ 0,
+ address + i * F77_DIM_OFFSET (ndimensions),
+ stream, format, deref_ref, recurse, pretty);
+
+ if (i != (F77_DIM_SIZE (nss) - 1))
+ fprintf_filtered (stream, ", ");
+
+ if (i == print_max - 1)
+ fprintf_filtered (stream, "...");
+ }
+ }
+}
+
+/* This function gets called to print an F77 array, we set up some
+ stuff and then immediately call f77_print_array_1() */
+
+static void
+f77_print_array (struct type *type, char *valaddr, CORE_ADDR address,
+ struct ui_file *stream, int format, int deref_ref, int recurse,
+ enum val_prettyprint pretty)
+{
+ int ndimensions;
+
+ ndimensions = calc_f77_array_dims (type);
+
+ if (ndimensions > MAX_FORTRAN_DIMS || ndimensions < 0)
+ error ("Type node corrupt! F77 arrays cannot have %d subscripts (%d Max)",
+ ndimensions, MAX_FORTRAN_DIMS);
+
+ /* Since F77 arrays are stored column-major, we set up an
+ offset table to get at the various row's elements. The
+ offset table contains entries for both offset and subarray size. */
+
+ f77_create_arrayprint_offset_tbl (type, stream);
+
+ f77_print_array_1 (1, ndimensions, type, valaddr, address, stream, format,
+ deref_ref, recurse, pretty);
+}
+
+
+/* Print data of type TYPE located at VALADDR (within GDB), which came from
+ the inferior at address ADDRESS, onto stdio stream STREAM according to
+ FORMAT (a letter or 0 for natural format). The data at VALADDR is in
+ target byte order.
+
+ If the data are a string pointer, returns the number of string characters
+ printed.
+
+ If DEREF_REF is nonzero, then dereference references, otherwise just print
+ them like pointers.
+
+ The PRETTY parameter controls prettyprinting. */
+
+int
+f_val_print (struct type *type, char *valaddr, int embedded_offset,
+ CORE_ADDR address, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
+{
+ register unsigned int i = 0; /* Number of characters printed */
+ struct type *elttype;
+ LONGEST val;
+ CORE_ADDR addr;
+
+ CHECK_TYPEDEF (type);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_STRING:
+ f77_get_dynamic_length_of_aggregate (type);
+ LA_PRINT_STRING (stream, valaddr, TYPE_LENGTH (type), 1, 0);
+ break;
+
+ case TYPE_CODE_ARRAY:
+ fprintf_filtered (stream, "(");
+ f77_print_array (type, valaddr, address, stream, format,
+ deref_ref, recurse, pretty);
+ fprintf_filtered (stream, ")");
+ break;
+#if 0
+ /* Array of unspecified length: treat like pointer to first elt. */
+ valaddr = (char *) &address;
+ /* FALL THROUGH */
+#endif
+ case TYPE_CODE_PTR:
+ if (format && format != 's')
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ break;
+ }
+ else
+ {
+ addr = unpack_pointer (type, valaddr);
+ elttype = check_typedef (TYPE_TARGET_TYPE (type));
+
+ if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
+ {
+ /* Try to print what function it points to. */
+ print_address_demangle (addr, stream, demangle);
+ /* Return value is irrelevant except for string pointers. */
+ return 0;
+ }
+
+ if (addressprint && format != 's')
+ fprintf_filtered (stream, "0x%s", paddr_nz (addr));
+
+ /* For a pointer to char or unsigned char, also print the string
+ pointed to, unless pointer is null. */
+ if (TYPE_LENGTH (elttype) == 1
+ && TYPE_CODE (elttype) == TYPE_CODE_INT
+ && (format == 0 || format == 's')
+ && addr != 0)
+ i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream);
+
+ /* Return number of characters printed, plus one for the
+ terminating null if we have "reached the end". */
+ return (i + (print_max && i != print_max));
+ }
+ break;
+
+ case TYPE_CODE_FUNC:
+ if (format)
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ break;
+ }
+ /* FIXME, we should consider, at least for ANSI C language, eliminating
+ the distinction made between FUNCs and POINTERs to FUNCs. */
+ fprintf_filtered (stream, "{");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, "} ");
+ /* Try to print what function it points to, and its address. */
+ print_address_demangle (address, stream, demangle);
+ break;
+
+ case TYPE_CODE_INT:
+ format = format ? format : output_format;
+ if (format)
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ else
+ {
+ val_print_type_code_int (type, valaddr, stream);
+ /* C and C++ has no single byte int type, char is used instead.
+ Since we don't know whether the value is really intended to
+ be used as an integer or a character, print the character
+ equivalent as well. */
+ if (TYPE_LENGTH (type) == 1)
+ {
+ fputs_filtered (" ", stream);
+ LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr),
+ stream);
+ }
+ }
+ break;
+
+ case TYPE_CODE_FLT:
+ if (format)
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ else
+ print_floating (valaddr, type, stream);
+ break;
+
+ case TYPE_CODE_VOID:
+ fprintf_filtered (stream, "VOID");
+ break;
+
+ case TYPE_CODE_ERROR:
+ fprintf_filtered (stream, "<error type>");
+ break;
+
+ case TYPE_CODE_RANGE:
+ /* FIXME, we should not ever have to print one of these yet. */
+ fprintf_filtered (stream, "<range type>");
+ break;
+
+ case TYPE_CODE_BOOL:
+ format = format ? format : output_format;
+ if (format)
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ else
+ {
+ val = 0;
+ switch (TYPE_LENGTH (type))
+ {
+ case 1:
+ val = unpack_long (builtin_type_f_logical_s1, valaddr);
+ break;
+
+ case 2:
+ val = unpack_long (builtin_type_f_logical_s2, valaddr);
+ break;
+
+ case 4:
+ val = unpack_long (builtin_type_f_logical, valaddr);
+ break;
+
+ default:
+ error ("Logicals of length %d bytes not supported",
+ TYPE_LENGTH (type));
+
+ }
+
+ if (val == 0)
+ fprintf_filtered (stream, ".FALSE.");
+ else if (val == 1)
+ fprintf_filtered (stream, ".TRUE.");
+ else
+ /* Not a legitimate logical type, print as an integer. */
+ {
+ /* Bash the type code temporarily. */
+ TYPE_CODE (type) = TYPE_CODE_INT;
+ f_val_print (type, valaddr, 0, address, stream, format,
+ deref_ref, recurse, pretty);
+ /* Restore the type code so later uses work as intended. */
+ TYPE_CODE (type) = TYPE_CODE_BOOL;
+ }
+ }
+ break;
+
+ case TYPE_CODE_COMPLEX:
+ switch (TYPE_LENGTH (type))
+ {
+ case 8:
+ type = builtin_type_f_real;
+ break;
+ case 16:
+ type = builtin_type_f_real_s8;
+ break;
+ case 32:
+ type = builtin_type_f_real_s16;
+ break;
+ default:
+ error ("Cannot print out complex*%d variables", TYPE_LENGTH (type));
+ }
+ fputs_filtered ("(", stream);
+ print_floating (valaddr, type, stream);
+ fputs_filtered (",", stream);
+ print_floating (valaddr + TYPE_LENGTH (type), type, stream);
+ fputs_filtered (")", stream);
+ break;
+
+ case TYPE_CODE_UNDEF:
+ /* This happens (without TYPE_FLAG_STUB set) on systems which don't use
+ dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
+ and no complete type for struct foo in that file. */
+ fprintf_filtered (stream, "<incomplete type>");
+ break;
+
+ default:
+ error ("Invalid F77 type code %d in symbol table.", TYPE_CODE (type));
+ }
+ gdb_flush (stream);
+ return 0;
+}
+
+static void
+list_all_visible_commons (char *funname)
+{
+ SAVED_F77_COMMON_PTR tmp;
+
+ tmp = head_common_list;
+
+ printf_filtered ("All COMMON blocks visible at this level:\n\n");
+
+ while (tmp != NULL)
+ {
+ if (STREQ (tmp->owning_function, funname))
+ printf_filtered ("%s\n", tmp->name);
+
+ tmp = tmp->next;
+ }
+}
+
+/* This function is used to print out the values in a given COMMON
+ block. It will always use the most local common block of the
+ given name */
+
+static void
+info_common_command (char *comname, int from_tty)
+{
+ SAVED_F77_COMMON_PTR the_common;
+ COMMON_ENTRY_PTR entry;
+ struct frame_info *fi;
+ register char *funname = 0;
+ struct symbol *func;
+
+ /* We have been told to display the contents of F77 COMMON
+ block supposedly visible in this function. Let us
+ first make sure that it is visible and if so, let
+ us display its contents */
+
+ fi = selected_frame;
+
+ if (fi == NULL)
+ error ("No frame selected");
+
+ /* The following is generally ripped off from stack.c's routine
+ print_frame_info() */
+
+ func = find_pc_function (fi->pc);
+ if (func)
+ {
+ /* In certain pathological cases, the symtabs give the wrong
+ function (when we are in the first function in a file which
+ is compiled without debugging symbols, the previous function
+ is compiled with debugging symbols, and the "foo.o" symbol
+ that is supposed to tell us where the file with debugging symbols
+ ends has been truncated by ar because it is longer than 15
+ characters).
+
+ So look in the minimal symbol tables as well, and if it comes
+ up with a larger address for the function use that instead.
+ I don't think this can ever cause any problems; there shouldn't
+ be any minimal symbols in the middle of a function.
+ FIXME: (Not necessarily true. What about text labels) */
+
+ struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
+
+ if (msymbol != NULL
+ && (SYMBOL_VALUE_ADDRESS (msymbol)
+ > BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
+ funname = SYMBOL_NAME (msymbol);
+ else
+ funname = SYMBOL_NAME (func);
+ }
+ else
+ {
+ register struct minimal_symbol *msymbol =
+ lookup_minimal_symbol_by_pc (fi->pc);
+
+ if (msymbol != NULL)
+ funname = SYMBOL_NAME (msymbol);
+ }
+
+ /* If comname is NULL, we assume the user wishes to see the
+ which COMMON blocks are visible here and then return */
+
+ if (comname == 0)
+ {
+ list_all_visible_commons (funname);
+ return;
+ }
+
+ the_common = find_common_for_function (comname, funname);
+
+ if (the_common)
+ {
+ if (STREQ (comname, BLANK_COMMON_NAME_LOCAL))
+ printf_filtered ("Contents of blank COMMON block:\n");
+ else
+ printf_filtered ("Contents of F77 COMMON block '%s':\n", comname);
+
+ printf_filtered ("\n");
+ entry = the_common->entries;
+
+ while (entry != NULL)
+ {
+ printf_filtered ("%s = ", SYMBOL_NAME (entry->symbol));
+ print_variable_value (entry->symbol, fi, gdb_stdout);
+ printf_filtered ("\n");
+ entry = entry->next;
+ }
+ }
+ else
+ printf_filtered ("Cannot locate the common block %s in function '%s'\n",
+ comname, funname);
+}
+
+/* This function is used to determine whether there is a
+ F77 common block visible at the current scope called 'comname'. */
+
+#if 0
+static int
+there_is_a_visible_common_named (char *comname)
+{
+ SAVED_F77_COMMON_PTR the_common;
+ struct frame_info *fi;
+ register char *funname = 0;
+ struct symbol *func;
+
+ if (comname == NULL)
+ error ("Cannot deal with NULL common name!");
+
+ fi = selected_frame;
+
+ if (fi == NULL)
+ error ("No frame selected");
+
+ /* The following is generally ripped off from stack.c's routine
+ print_frame_info() */
+
+ func = find_pc_function (fi->pc);
+ if (func)
+ {
+ /* In certain pathological cases, the symtabs give the wrong
+ function (when we are in the first function in a file which
+ is compiled without debugging symbols, the previous function
+ is compiled with debugging symbols, and the "foo.o" symbol
+ that is supposed to tell us where the file with debugging symbols
+ ends has been truncated by ar because it is longer than 15
+ characters).
+
+ So look in the minimal symbol tables as well, and if it comes
+ up with a larger address for the function use that instead.
+ I don't think this can ever cause any problems; there shouldn't
+ be any minimal symbols in the middle of a function.
+ FIXME: (Not necessarily true. What about text labels) */
+
+ struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
+
+ if (msymbol != NULL
+ && (SYMBOL_VALUE_ADDRESS (msymbol)
+ > BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
+ funname = SYMBOL_NAME (msymbol);
+ else
+ funname = SYMBOL_NAME (func);
+ }
+ else
+ {
+ register struct minimal_symbol *msymbol =
+ lookup_minimal_symbol_by_pc (fi->pc);
+
+ if (msymbol != NULL)
+ funname = SYMBOL_NAME (msymbol);
+ }
+
+ the_common = find_common_for_function (comname, funname);
+
+ return (the_common ? 1 : 0);
+}
+#endif
+
+void
+_initialize_f_valprint (void)
+{
+ add_info ("common", info_common_command,
+ "Print out the values contained in a Fortran COMMON block.");
+ if (xdb_commands)
+ add_com ("lc", class_info, info_common_command,
+ "Print out the values contained in a Fortran COMMON block.");
+}
diff --git a/gdb/fbsd-proc.c b/gdb/fbsd-proc.c
new file mode 100644
index 00000000000..c68238dbece
--- /dev/null
+++ b/gdb/fbsd-proc.c
@@ -0,0 +1,173 @@
+/* FreeBSD-specific methods for using the /proc file system.
+ Copyright 2002 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 "defs.h"
+#include "gdbcore.h"
+#include "inferior.h"
+
+#include <sys/procfs.h>
+#include <sys/types.h>
+
+#include "elf-bfd.h"
+
+#include "gregset.h"
+
+char *
+child_pid_to_exec_file (int pid)
+{
+ char *path;
+ char *buf;
+
+ xasprintf (&path, "/proc/%d/file", pid);
+ buf = xcalloc (MAXPATHLEN, sizeof (char));
+ make_cleanup (xfree, path);
+ make_cleanup (xfree, buf);
+
+ if (readlink (path, buf, MAXPATHLEN) > 0)
+ return buf;
+
+ return NULL;
+}
+
+static int
+read_mapping (FILE *mapfile,
+ unsigned long *start,
+ unsigned long *end,
+ char *protection)
+{
+ int resident, privateresident;
+ unsigned long obj;
+ int ref_count, shadow_count;
+ unsigned flags;
+ char cow[5], access[4];
+ char type[8];
+ int ret;
+
+ /* The layout is described in /usr/src/miscfs/procfs/procfs_map.c. */
+ ret = fscanf (mapfile, "%lx %lx %d %d %lx %s %d %d %x %s %s %s\n",
+ start, end,
+ &resident, &privateresident, &obj,
+ protection,
+ &ref_count, &shadow_count, &flags, cow, access, type);
+
+ return (ret != 0 && ret != EOF);
+}
+
+static int
+fbsd_find_memory_regions (int (*func) (CORE_ADDR,
+ unsigned long,
+ int, int, int,
+ void *),
+ void *obfd)
+{
+ pid_t pid = ptid_get_pid (inferior_ptid);
+ char *mapfilename;
+ FILE *mapfile;
+ unsigned long start, end, size;
+ char protection[4];
+ int read, write, exec;
+
+ xasprintf (&mapfilename, "/proc/%ld/map", (long) pid);
+ mapfile = fopen (mapfilename, "r");
+ if (mapfile == NULL)
+ error ("Couldn't open %s\n", mapfilename);
+
+ if (info_verbose)
+ fprintf_filtered (gdb_stdout,
+ "Reading memory regions from %s\n", mapfilename);
+
+ /* Now iterate until end-of-file. */
+ while (read_mapping (mapfile, &start, &end, &protection[0]))
+ {
+ size = end - start;
+
+ read = (strchr (protection, 'r') != 0);
+ write = (strchr (protection, 'w') != 0);
+ exec = (strchr (protection, 'x') != 0);
+
+ if (info_verbose)
+ {
+ fprintf_filtered (gdb_stdout,
+ "Save segment, %ld bytes at 0x%s (%c%c%c)\n",
+ size, paddr_nz (start),
+ read ? 'r' : '-',
+ write ? 'w' : '-',
+ exec ? 'x' : '-');
+ }
+
+ /* Invoke the callback function to create the corefile segment. */
+ func (start, size, read, write, exec, obfd);
+ }
+
+ fclose (mapfile);
+ return 0;
+}
+
+static char *
+fbsd_make_corefile_notes (bfd *obfd, int *note_size)
+{
+ gregset_t gregs;
+ fpregset_t fpregs;
+ char *note_data = NULL;
+
+ fill_gregset (&gregs, -1);
+ note_data = (char *) elfcore_write_prstatus (obfd,
+ note_data,
+ note_size,
+ ptid_get_pid (inferior_ptid),
+ stop_signal,
+ &gregs);
+
+ fill_fpregset (&fpregs, -1);
+ note_data = (char *) elfcore_write_prfpreg (obfd,
+ note_data,
+ note_size,
+ &fpregs,
+ sizeof (fpregs));
+
+ if (get_exec_file (0))
+ {
+ char *fname = strrchr (get_exec_file (0), '/') + 1;
+ char *psargs = xstrdup (fname);
+
+ if (get_inferior_args ())
+ psargs = reconcat (psargs, psargs, " ", get_inferior_args (), NULL);
+
+ note_data = (char *) elfcore_write_prpsinfo (obfd,
+ note_data,
+ note_size,
+ fname,
+ psargs);
+ }
+
+ make_cleanup (xfree, note_data);
+ return note_data;
+}
+
+
+void
+_initialize_fbsd_proc (void)
+{
+ extern void inftarg_set_find_memory_regions ();
+ extern void inftarg_set_make_corefile_notes ();
+
+ inftarg_set_find_memory_regions (fbsd_find_memory_regions);
+ inftarg_set_make_corefile_notes (fbsd_make_corefile_notes);
+}
diff --git a/gdb/findvar.c b/gdb/findvar.c
new file mode 100644
index 00000000000..831ae4bc1b0
--- /dev/null
+++ b/gdb/findvar.c
@@ -0,0 +1,903 @@
+/* Find a variable's value in memory, for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "frame.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdb_string.h"
+#include "gdb_assert.h"
+#include "floatformat.h"
+#include "symfile.h" /* for overlay functions */
+#include "regcache.h"
+#include "builtin-regs.h"
+
+/* Basic byte-swapping routines. GDB has needed these for a long time...
+ All extract a target-format integer at ADDR which is LEN bytes long. */
+
+#if TARGET_CHAR_BIT != 8 || HOST_CHAR_BIT != 8
+ /* 8 bit characters are a pretty safe assumption these days, so we
+ assume it throughout all these swapping routines. If we had to deal with
+ 9 bit characters, we would need to make len be in bits and would have
+ to re-write these routines... */
+you lose
+#endif
+
+LONGEST
+extract_signed_integer (void *addr, int len)
+{
+ LONGEST retval;
+ unsigned char *p;
+ unsigned char *startaddr = (unsigned char *) addr;
+ unsigned char *endaddr = startaddr + len;
+
+ if (len > (int) sizeof (LONGEST))
+ error ("\
+That operation is not available on integers of more than %d bytes.",
+ (int) sizeof (LONGEST));
+
+ /* Start at the most significant end of the integer, and work towards
+ the least significant. */
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ p = startaddr;
+ /* Do the sign extension once at the start. */
+ retval = ((LONGEST) * p ^ 0x80) - 0x80;
+ for (++p; p < endaddr; ++p)
+ retval = (retval << 8) | *p;
+ }
+ else
+ {
+ p = endaddr - 1;
+ /* Do the sign extension once at the start. */
+ retval = ((LONGEST) * p ^ 0x80) - 0x80;
+ for (--p; p >= startaddr; --p)
+ retval = (retval << 8) | *p;
+ }
+ return retval;
+}
+
+ULONGEST
+extract_unsigned_integer (void *addr, int len)
+{
+ ULONGEST retval;
+ unsigned char *p;
+ unsigned char *startaddr = (unsigned char *) addr;
+ unsigned char *endaddr = startaddr + len;
+
+ if (len > (int) sizeof (ULONGEST))
+ error ("\
+That operation is not available on integers of more than %d bytes.",
+ (int) sizeof (ULONGEST));
+
+ /* Start at the most significant end of the integer, and work towards
+ the least significant. */
+ retval = 0;
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ for (p = startaddr; p < endaddr; ++p)
+ retval = (retval << 8) | *p;
+ }
+ else
+ {
+ for (p = endaddr - 1; p >= startaddr; --p)
+ retval = (retval << 8) | *p;
+ }
+ return retval;
+}
+
+/* Sometimes a long long unsigned integer can be extracted as a
+ LONGEST value. This is done so that we can print these values
+ better. If this integer can be converted to a LONGEST, this
+ function returns 1 and sets *PVAL. Otherwise it returns 0. */
+
+int
+extract_long_unsigned_integer (void *addr, int orig_len, LONGEST *pval)
+{
+ char *p, *first_addr;
+ int len;
+
+ len = orig_len;
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ for (p = (char *) addr;
+ len > (int) sizeof (LONGEST) && p < (char *) addr + orig_len;
+ p++)
+ {
+ if (*p == 0)
+ len--;
+ else
+ break;
+ }
+ first_addr = p;
+ }
+ else
+ {
+ first_addr = (char *) addr;
+ for (p = (char *) addr + orig_len - 1;
+ len > (int) sizeof (LONGEST) && p >= (char *) addr;
+ p--)
+ {
+ if (*p == 0)
+ len--;
+ else
+ break;
+ }
+ }
+
+ if (len <= (int) sizeof (LONGEST))
+ {
+ *pval = (LONGEST) extract_unsigned_integer (first_addr,
+ sizeof (LONGEST));
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* Treat the LEN bytes at ADDR as a target-format address, and return
+ that address. ADDR is a buffer in the GDB process, not in the
+ inferior.
+
+ This function should only be used by target-specific code. It
+ assumes that a pointer has the same representation as that thing's
+ address represented as an integer. Some machines use word
+ addresses, or similarly munged things, for certain types of
+ pointers, so that assumption doesn't hold everywhere.
+
+ Common code should use extract_typed_address instead, or something
+ else based on POINTER_TO_ADDRESS. */
+
+CORE_ADDR
+extract_address (void *addr, int len)
+{
+ /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure
+ whether we want this to be true eventually. */
+ return (CORE_ADDR) extract_unsigned_integer (addr, len);
+}
+
+
+/* Treat the bytes at BUF as a pointer of type TYPE, and return the
+ address it represents. */
+CORE_ADDR
+extract_typed_address (void *buf, struct type *type)
+{
+ if (TYPE_CODE (type) != TYPE_CODE_PTR
+ && TYPE_CODE (type) != TYPE_CODE_REF)
+ internal_error (__FILE__, __LINE__,
+ "extract_typed_address: "
+ "type is not a pointer or reference");
+
+ return POINTER_TO_ADDRESS (type, buf);
+}
+
+
+void
+store_signed_integer (void *addr, int len, LONGEST val)
+{
+ unsigned char *p;
+ unsigned char *startaddr = (unsigned char *) addr;
+ unsigned char *endaddr = startaddr + len;
+
+ /* Start at the least significant end of the integer, and work towards
+ the most significant. */
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ for (p = endaddr - 1; p >= startaddr; --p)
+ {
+ *p = val & 0xff;
+ val >>= 8;
+ }
+ }
+ else
+ {
+ for (p = startaddr; p < endaddr; ++p)
+ {
+ *p = val & 0xff;
+ val >>= 8;
+ }
+ }
+}
+
+void
+store_unsigned_integer (void *addr, int len, ULONGEST val)
+{
+ unsigned char *p;
+ unsigned char *startaddr = (unsigned char *) addr;
+ unsigned char *endaddr = startaddr + len;
+
+ /* Start at the least significant end of the integer, and work towards
+ the most significant. */
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ for (p = endaddr - 1; p >= startaddr; --p)
+ {
+ *p = val & 0xff;
+ val >>= 8;
+ }
+ }
+ else
+ {
+ for (p = startaddr; p < endaddr; ++p)
+ {
+ *p = val & 0xff;
+ val >>= 8;
+ }
+ }
+}
+
+/* Store the address VAL as a LEN-byte value in target byte order at
+ ADDR. ADDR is a buffer in the GDB process, not in the inferior.
+
+ This function should only be used by target-specific code. It
+ assumes that a pointer has the same representation as that thing's
+ address represented as an integer. Some machines use word
+ addresses, or similarly munged things, for certain types of
+ pointers, so that assumption doesn't hold everywhere.
+
+ Common code should use store_typed_address instead, or something else
+ based on ADDRESS_TO_POINTER. */
+void
+store_address (void *addr, int len, LONGEST val)
+{
+ store_unsigned_integer (addr, len, val);
+}
+
+
+/* Store the address ADDR as a pointer of type TYPE at BUF, in target
+ form. */
+void
+store_typed_address (void *buf, struct type *type, CORE_ADDR addr)
+{
+ if (TYPE_CODE (type) != TYPE_CODE_PTR
+ && TYPE_CODE (type) != TYPE_CODE_REF)
+ internal_error (__FILE__, __LINE__,
+ "store_typed_address: "
+ "type is not a pointer or reference");
+
+ ADDRESS_TO_POINTER (type, buf, addr);
+}
+
+
+
+/* Return a `value' with the contents of (virtual or cooked) register
+ REGNUM as found in the specified FRAME. The register's type is
+ determined by REGISTER_VIRTUAL_TYPE.
+
+ NOTE: returns NULL if register value is not available. Caller will
+ check return value or die! */
+
+struct value *
+value_of_register (int regnum, struct frame_info *frame)
+{
+ CORE_ADDR addr;
+ int optim;
+ struct value *reg_val;
+ char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ enum lval_type lval;
+
+ /* Builtin registers lie completly outside of the range of normal
+ registers. Catch them early so that the target never sees them. */
+ if (regnum >= NUM_REGS + NUM_PSEUDO_REGS)
+ return value_of_builtin_reg (regnum, selected_frame);
+
+ get_saved_register (raw_buffer, &optim, &addr,
+ frame, regnum, &lval);
+
+ /* FIXME: cagney/2002-05-15: This test is just bogus.
+
+ It indicates that the target failed to supply a value for a
+ register because it was "not available" at this time. Problem
+ is, the target still has the register and so get saved_register()
+ may be returning a value saved on the stack. */
+
+ if (register_cached (regnum) < 0)
+ return NULL; /* register value not available */
+
+ reg_val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum));
+
+ /* Convert raw data to virtual format if necessary. */
+
+ if (REGISTER_CONVERTIBLE (regnum))
+ {
+ REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum),
+ raw_buffer, VALUE_CONTENTS_RAW (reg_val));
+ }
+ else if (REGISTER_RAW_SIZE (regnum) == REGISTER_VIRTUAL_SIZE (regnum))
+ memcpy (VALUE_CONTENTS_RAW (reg_val), raw_buffer,
+ REGISTER_RAW_SIZE (regnum));
+ else
+ internal_error (__FILE__, __LINE__,
+ "Register \"%s\" (%d) has conflicting raw (%d) and virtual (%d) size",
+ REGISTER_NAME (regnum),
+ regnum,
+ REGISTER_RAW_SIZE (regnum),
+ REGISTER_VIRTUAL_SIZE (regnum));
+ VALUE_LVAL (reg_val) = lval;
+ VALUE_ADDRESS (reg_val) = addr;
+ VALUE_REGNO (reg_val) = regnum;
+ VALUE_OPTIMIZED_OUT (reg_val) = optim;
+ return reg_val;
+}
+
+/* Given a pointer of type TYPE in target form in BUF, return the
+ address it represents. */
+CORE_ADDR
+unsigned_pointer_to_address (struct type *type, void *buf)
+{
+ return extract_address (buf, TYPE_LENGTH (type));
+}
+
+CORE_ADDR
+signed_pointer_to_address (struct type *type, void *buf)
+{
+ return extract_signed_integer (buf, TYPE_LENGTH (type));
+}
+
+/* Given an address, store it as a pointer of type TYPE in target
+ format in BUF. */
+void
+unsigned_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr)
+{
+ store_address (buf, TYPE_LENGTH (type), addr);
+}
+
+void
+address_to_signed_pointer (struct type *type, void *buf, CORE_ADDR addr)
+{
+ store_signed_integer (buf, TYPE_LENGTH (type), addr);
+}
+
+/* Will calling read_var_value or locate_var_value on SYM end
+ up caring what frame it is being evaluated relative to? SYM must
+ be non-NULL. */
+int
+symbol_read_needs_frame (struct symbol *sym)
+{
+ switch (SYMBOL_CLASS (sym))
+ {
+ /* All cases listed explicitly so that gcc -Wall will detect it if
+ we failed to consider one. */
+ case LOC_REGISTER:
+ case LOC_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_LOCAL:
+ case LOC_LOCAL_ARG:
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
+ case LOC_THREAD_LOCAL_STATIC:
+ return 1;
+
+ case LOC_UNDEF:
+ case LOC_CONST:
+ case LOC_STATIC:
+ case LOC_INDIRECT:
+ case LOC_TYPEDEF:
+
+ case LOC_LABEL:
+ /* Getting the address of a label can be done independently of the block,
+ even if some *uses* of that address wouldn't work so well without
+ the right frame. */
+
+ case LOC_BLOCK:
+ case LOC_CONST_BYTES:
+ case LOC_UNRESOLVED:
+ case LOC_OPTIMIZED_OUT:
+ return 0;
+ }
+ return 1;
+}
+
+/* Given a struct symbol for a variable,
+ and a stack frame id, read the value of the variable
+ and return a (pointer to a) struct value containing the value.
+ If the variable cannot be found, return a zero pointer.
+ If FRAME is NULL, use the selected_frame. */
+
+struct value *
+read_var_value (register struct symbol *var, struct frame_info *frame)
+{
+ register struct value *v;
+ struct type *type = SYMBOL_TYPE (var);
+ CORE_ADDR addr;
+ register int len;
+
+ v = allocate_value (type);
+ VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */
+ VALUE_BFD_SECTION (v) = SYMBOL_BFD_SECTION (var);
+
+ len = TYPE_LENGTH (type);
+
+ if (frame == NULL)
+ frame = selected_frame;
+
+ switch (SYMBOL_CLASS (var))
+ {
+ case LOC_CONST:
+ /* Put the constant back in target format. */
+ store_signed_integer (VALUE_CONTENTS_RAW (v), len,
+ (LONGEST) SYMBOL_VALUE (var));
+ VALUE_LVAL (v) = not_lval;
+ return v;
+
+ case LOC_LABEL:
+ /* Put the constant back in target format. */
+ if (overlay_debugging)
+ {
+ CORE_ADDR addr
+ = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
+ SYMBOL_BFD_SECTION (var));
+ store_typed_address (VALUE_CONTENTS_RAW (v), type, addr);
+ }
+ else
+ store_typed_address (VALUE_CONTENTS_RAW (v), type,
+ SYMBOL_VALUE_ADDRESS (var));
+ VALUE_LVAL (v) = not_lval;
+ return v;
+
+ case LOC_CONST_BYTES:
+ {
+ char *bytes_addr;
+ bytes_addr = SYMBOL_VALUE_BYTES (var);
+ memcpy (VALUE_CONTENTS_RAW (v), bytes_addr, len);
+ VALUE_LVAL (v) = not_lval;
+ return v;
+ }
+
+ case LOC_STATIC:
+ if (overlay_debugging)
+ addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
+ SYMBOL_BFD_SECTION (var));
+ else
+ addr = SYMBOL_VALUE_ADDRESS (var);
+ break;
+
+ case LOC_INDIRECT:
+ {
+ /* The import slot does not have a real address in it from the
+ dynamic loader (dld.sl on HP-UX), if the target hasn't
+ begun execution yet, so check for that. */
+ CORE_ADDR locaddr;
+ struct value *loc;
+ if (!target_has_execution)
+ error ("\
+Attempt to access variable defined in different shared object or load module when\n\
+addresses have not been bound by the dynamic loader. Try again when executable is running.");
+
+ locaddr = SYMBOL_VALUE_ADDRESS (var);
+ loc = value_at (lookup_pointer_type (type), locaddr, NULL);
+ addr = value_as_address (loc);
+ }
+
+ case LOC_ARG:
+ if (frame == NULL)
+ return 0;
+ addr = FRAME_ARGS_ADDRESS (frame);
+ if (!addr)
+ return 0;
+ addr += SYMBOL_VALUE (var);
+ break;
+
+ case LOC_REF_ARG:
+ {
+ struct value *ref;
+ CORE_ADDR argref;
+ if (frame == NULL)
+ return 0;
+ argref = FRAME_ARGS_ADDRESS (frame);
+ if (!argref)
+ return 0;
+ argref += SYMBOL_VALUE (var);
+ ref = value_at (lookup_pointer_type (type), argref, NULL);
+ addr = value_as_address (ref);
+ break;
+ }
+
+ case LOC_LOCAL:
+ case LOC_LOCAL_ARG:
+ if (frame == NULL)
+ return 0;
+ addr = FRAME_LOCALS_ADDRESS (frame);
+ addr += SYMBOL_VALUE (var);
+ break;
+
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
+ case LOC_THREAD_LOCAL_STATIC:
+ {
+ struct value *regval;
+
+ regval = value_from_register (lookup_pointer_type (type),
+ SYMBOL_BASEREG (var), frame);
+ if (regval == NULL)
+ error ("Value of base register not available.");
+ addr = value_as_address (regval);
+ addr += SYMBOL_VALUE (var);
+ break;
+ }
+
+ case LOC_TYPEDEF:
+ error ("Cannot look up value of a typedef");
+ break;
+
+ case LOC_BLOCK:
+ if (overlay_debugging)
+ VALUE_ADDRESS (v) = symbol_overlayed_address
+ (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_BFD_SECTION (var));
+ else
+ VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (var));
+ return v;
+
+ case LOC_REGISTER:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ {
+ struct block *b;
+ int regno = SYMBOL_VALUE (var);
+ struct value *regval;
+
+ if (frame == NULL)
+ return 0;
+ b = get_frame_block (frame, 0);
+
+ if (SYMBOL_CLASS (var) == LOC_REGPARM_ADDR)
+ {
+ regval = value_from_register (lookup_pointer_type (type),
+ regno,
+ frame);
+
+ if (regval == NULL)
+ error ("Value of register variable not available.");
+
+ addr = value_as_address (regval);
+ VALUE_LVAL (v) = lval_memory;
+ }
+ else
+ {
+ regval = value_from_register (type, regno, frame);
+
+ if (regval == NULL)
+ error ("Value of register variable not available.");
+ return regval;
+ }
+ }
+ break;
+
+ case LOC_UNRESOLVED:
+ {
+ struct minimal_symbol *msym;
+
+ msym = lookup_minimal_symbol (SYMBOL_NAME (var), NULL, NULL);
+ if (msym == NULL)
+ return 0;
+ if (overlay_debugging)
+ addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (msym),
+ SYMBOL_BFD_SECTION (msym));
+ else
+ addr = SYMBOL_VALUE_ADDRESS (msym);
+ }
+ break;
+
+ case LOC_OPTIMIZED_OUT:
+ VALUE_LVAL (v) = not_lval;
+ VALUE_OPTIMIZED_OUT (v) = 1;
+ return v;
+
+ default:
+ error ("Cannot look up value of a botched symbol.");
+ break;
+ }
+
+ VALUE_ADDRESS (v) = addr;
+ VALUE_LAZY (v) = 1;
+ return v;
+}
+
+/* Return a value of type TYPE, stored in register REGNUM, in frame
+ FRAME.
+
+ NOTE: returns NULL if register value is not available.
+ Caller will check return value or die! */
+
+struct value *
+value_from_register (struct type *type, int regnum, struct frame_info *frame)
+{
+ char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ CORE_ADDR addr;
+ int optim;
+ struct value *v = allocate_value (type);
+ char *value_bytes = 0;
+ int value_bytes_copied = 0;
+ int num_storage_locs;
+ enum lval_type lval;
+ int len;
+
+ CHECK_TYPEDEF (type);
+ len = TYPE_LENGTH (type);
+
+ VALUE_REGNO (v) = regnum;
+
+ num_storage_locs = (len > REGISTER_VIRTUAL_SIZE (regnum) ?
+ ((len - 1) / REGISTER_RAW_SIZE (regnum)) + 1 :
+ 1);
+
+ if (num_storage_locs > 1
+#ifdef GDB_TARGET_IS_H8500
+ || TYPE_CODE (type) == TYPE_CODE_PTR
+#endif
+ )
+ {
+ /* Value spread across multiple storage locations. */
+
+ int local_regnum;
+ int mem_stor = 0, reg_stor = 0;
+ int mem_tracking = 1;
+ CORE_ADDR last_addr = 0;
+ CORE_ADDR first_addr = 0;
+
+ value_bytes = (char *) alloca (len + MAX_REGISTER_RAW_SIZE);
+
+ /* Copy all of the data out, whereever it may be. */
+
+#ifdef GDB_TARGET_IS_H8500
+/* This piece of hideosity is required because the H8500 treats registers
+ differently depending upon whether they are used as pointers or not. As a
+ pointer, a register needs to have a page register tacked onto the front.
+ An alternate way to do this would be to have gcc output different register
+ numbers for the pointer & non-pointer form of the register. But, it
+ doesn't, so we're stuck with this. */
+
+ if (TYPE_CODE (type) == TYPE_CODE_PTR
+ && len > 2)
+ {
+ int page_regnum;
+
+ switch (regnum)
+ {
+ case R0_REGNUM:
+ case R1_REGNUM:
+ case R2_REGNUM:
+ case R3_REGNUM:
+ page_regnum = SEG_D_REGNUM;
+ break;
+ case R4_REGNUM:
+ case R5_REGNUM:
+ page_regnum = SEG_E_REGNUM;
+ break;
+ case R6_REGNUM:
+ case R7_REGNUM:
+ page_regnum = SEG_T_REGNUM;
+ break;
+ }
+
+ value_bytes[0] = 0;
+ get_saved_register (value_bytes + 1,
+ &optim,
+ &addr,
+ frame,
+ page_regnum,
+ &lval);
+
+ if (register_cached (page_regnum) == -1)
+ return NULL; /* register value not available */
+
+ if (lval == lval_register)
+ reg_stor++;
+ else
+ mem_stor++;
+ first_addr = addr;
+ last_addr = addr;
+
+ get_saved_register (value_bytes + 2,
+ &optim,
+ &addr,
+ frame,
+ regnum,
+ &lval);
+
+ if (register_cached (regnum) == -1)
+ return NULL; /* register value not available */
+
+ if (lval == lval_register)
+ reg_stor++;
+ else
+ {
+ mem_stor++;
+ mem_tracking = mem_tracking && (addr == last_addr);
+ }
+ last_addr = addr;
+ }
+ else
+#endif /* GDB_TARGET_IS_H8500 */
+ for (local_regnum = regnum;
+ value_bytes_copied < len;
+ (value_bytes_copied += REGISTER_RAW_SIZE (local_regnum),
+ ++local_regnum))
+ {
+ get_saved_register (value_bytes + value_bytes_copied,
+ &optim,
+ &addr,
+ frame,
+ local_regnum,
+ &lval);
+
+ if (register_cached (local_regnum) == -1)
+ return NULL; /* register value not available */
+
+ if (regnum == local_regnum)
+ first_addr = addr;
+ if (lval == lval_register)
+ reg_stor++;
+ else
+ {
+ mem_stor++;
+
+ mem_tracking =
+ (mem_tracking
+ && (regnum == local_regnum
+ || addr == last_addr));
+ }
+ last_addr = addr;
+ }
+
+ if ((reg_stor && mem_stor)
+ || (mem_stor && !mem_tracking))
+ /* Mixed storage; all of the hassle we just went through was
+ for some good purpose. */
+ {
+ VALUE_LVAL (v) = lval_reg_frame_relative;
+ VALUE_FRAME (v) = FRAME_FP (frame);
+ VALUE_FRAME_REGNUM (v) = regnum;
+ }
+ else if (mem_stor)
+ {
+ VALUE_LVAL (v) = lval_memory;
+ VALUE_ADDRESS (v) = first_addr;
+ }
+ else if (reg_stor)
+ {
+ VALUE_LVAL (v) = lval_register;
+ VALUE_ADDRESS (v) = first_addr;
+ }
+ else
+ internal_error (__FILE__, __LINE__,
+ "value_from_register: Value not stored anywhere!");
+
+ VALUE_OPTIMIZED_OUT (v) = optim;
+
+ /* Any structure stored in more than one register will always be
+ an integral number of registers. Otherwise, you'd need to do
+ some fiddling with the last register copied here for little
+ endian machines. */
+
+ /* Copy into the contents section of the value. */
+ memcpy (VALUE_CONTENTS_RAW (v), value_bytes, len);
+
+ /* Finally do any conversion necessary when extracting this
+ type from more than one register. */
+#ifdef REGISTER_CONVERT_TO_TYPE
+ REGISTER_CONVERT_TO_TYPE (regnum, type, VALUE_CONTENTS_RAW (v));
+#endif
+ return v;
+ }
+
+ /* Data is completely contained within a single register. Locate the
+ register's contents in a real register or in core;
+ read the data in raw format. */
+
+ get_saved_register (raw_buffer, &optim, &addr, frame, regnum, &lval);
+
+ if (register_cached (regnum) == -1)
+ return NULL; /* register value not available */
+
+ VALUE_OPTIMIZED_OUT (v) = optim;
+ VALUE_LVAL (v) = lval;
+ VALUE_ADDRESS (v) = addr;
+
+ /* Convert the raw register to the corresponding data value's memory
+ format, if necessary. */
+
+ if (CONVERT_REGISTER_P (regnum))
+ {
+ REGISTER_TO_VALUE (regnum, type, raw_buffer, VALUE_CONTENTS_RAW (v));
+ }
+ else
+ {
+ /* Raw and virtual formats are the same for this register. */
+
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG && len < REGISTER_RAW_SIZE (regnum))
+ {
+ /* Big-endian, and we want less than full size. */
+ VALUE_OFFSET (v) = REGISTER_RAW_SIZE (regnum) - len;
+ }
+
+ memcpy (VALUE_CONTENTS_RAW (v), raw_buffer + VALUE_OFFSET (v), len);
+ }
+
+ return v;
+}
+
+/* Given a struct symbol for a variable or function,
+ and a stack frame id,
+ return a (pointer to a) struct value containing the properly typed
+ address. */
+
+struct value *
+locate_var_value (register struct symbol *var, struct frame_info *frame)
+{
+ CORE_ADDR addr = 0;
+ struct type *type = SYMBOL_TYPE (var);
+ struct value *lazy_value;
+
+ /* Evaluate it first; if the result is a memory address, we're fine.
+ Lazy evaluation pays off here. */
+
+ lazy_value = read_var_value (var, frame);
+ if (lazy_value == 0)
+ error ("Address of \"%s\" is unknown.", SYMBOL_SOURCE_NAME (var));
+
+ if (VALUE_LAZY (lazy_value)
+ || TYPE_CODE (type) == TYPE_CODE_FUNC)
+ {
+ struct value *val;
+
+ addr = VALUE_ADDRESS (lazy_value);
+ val = value_from_pointer (lookup_pointer_type (type), addr);
+ VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (lazy_value);
+ return val;
+ }
+
+ /* Not a memory address; check what the problem was. */
+ switch (VALUE_LVAL (lazy_value))
+ {
+ case lval_register:
+ gdb_assert (REGISTER_NAME (VALUE_REGNO (lazy_value)) != NULL
+ && *REGISTER_NAME (VALUE_REGNO (lazy_value)) != '\0');
+ error("Address requested for identifier "
+ "\"%s\" which is in register $%s",
+ SYMBOL_SOURCE_NAME (var),
+ REGISTER_NAME (VALUE_REGNO (lazy_value)));
+ break;
+
+ case lval_reg_frame_relative:
+ gdb_assert (REGISTER_NAME (VALUE_FRAME_REGNUM (lazy_value)) != NULL
+ && *REGISTER_NAME (VALUE_FRAME_REGNUM (lazy_value)) != '\0');
+ error("Address requested for identifier "
+ "\"%s\" which is in frame register $%s",
+ SYMBOL_SOURCE_NAME (var),
+ REGISTER_NAME (VALUE_FRAME_REGNUM (lazy_value)));
+ break;
+
+ default:
+ error ("Can't take address of \"%s\" which isn't an lvalue.",
+ SYMBOL_SOURCE_NAME (var));
+ break;
+ }
+ return 0; /* For lint -- never reached */
+}
diff --git a/gdb/fork-child.c b/gdb/fork-child.c
new file mode 100644
index 00000000000..aacd53cac71
--- /dev/null
+++ b/gdb/fork-child.c
@@ -0,0 +1,573 @@
+/* Fork a Unix child process, and set up to debug it, for GDB.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
+ 2001 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 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 "defs.h"
+#include "gdb_string.h"
+#include "frame.h" /* required by inferior.h */
+#include "inferior.h"
+#include "target.h"
+#include "gdb_wait.h"
+#include "gdb_vfork.h"
+#include "gdbcore.h"
+#include "terminal.h"
+#include "gdbthread.h"
+#include "command.h" /* for dont_repeat () */
+
+#include <signal.h>
+
+/* This just gets used as a default if we can't find SHELL */
+#ifndef SHELL_FILE
+#define SHELL_FILE "/bin/sh"
+#endif
+
+extern char **environ;
+
+/* This function breaks up an argument string into an argument
+ * vector suitable for passing to execvp().
+ * E.g., on "run a b c d" this routine would get as input
+ * the string "a b c d", and as output it would fill in argv with
+ * the four arguments "a", "b", "c", "d".
+ */
+static void
+breakup_args (char *scratch, char **argv)
+{
+ char *cp = scratch;
+
+ for (;;)
+ {
+
+ /* Scan past leading separators */
+ while (*cp == ' ' || *cp == '\t' || *cp == '\n')
+ {
+ cp++;
+ }
+
+ /* Break if at end of string */
+ if (*cp == '\0')
+ break;
+
+ /* Take an arg */
+ *argv++ = cp;
+
+ /* Scan for next arg separator */
+ cp = strchr (cp, ' ');
+ if (cp == NULL)
+ cp = strchr (cp, '\t');
+ if (cp == NULL)
+ cp = strchr (cp, '\n');
+
+ /* No separators => end of string => break */
+ if (cp == NULL)
+ break;
+
+ /* Replace the separator with a terminator */
+ *cp++ = '\0';
+ }
+
+ /* execv requires a null-terminated arg vector */
+ *argv = NULL;
+
+}
+
+
+/* Start an inferior Unix child process and sets inferior_ptid 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. SHELL_FILE is the shell file,
+ or NULL if we should pick one. Errors reported with error(). */
+
+/* This function is NOT-REENTRANT. Some of the variables have been
+ made static to ensure that they survive the vfork() call. */
+
+void
+fork_inferior (char *exec_file_arg, char *allargs, char **env,
+ void (*traceme_fun) (void), void (*init_trace_fun) (int),
+ void (*pre_trace_fun) (void), char *shell_file_arg)
+{
+ int pid;
+ char *shell_command;
+ static char default_shell_file[] = SHELL_FILE;
+ int len;
+ /* Set debug_fork then attach to the child while it sleeps, to debug. */
+ static int debug_fork = 0;
+ /* This is set to the result of setpgrp, which if vforked, will be visible
+ to you in the parent process. It's only used by humans for debugging. */
+ static int debug_setpgrp = 657473;
+ static char *shell_file;
+ static char *exec_file;
+ char **save_our_env;
+ int shell = 0;
+ static char **argv;
+
+ /* If no exec file handed to us, get it from the exec-file command -- with
+ a good, common error message if none is specified. */
+ exec_file = exec_file_arg;
+ if (exec_file == 0)
+ exec_file = get_exec_file (1);
+
+ /* STARTUP_WITH_SHELL is defined in inferior.h.
+ * If 0, we'll just do a fork/exec, no shell, so don't
+ * bother figuring out what shell.
+ */
+ shell_file = shell_file_arg;
+ if (STARTUP_WITH_SHELL)
+ {
+ /* Figure out what shell to start up the user program under. */
+ if (shell_file == NULL)
+ shell_file = getenv ("SHELL");
+ if (shell_file == NULL)
+ shell_file = default_shell_file;
+ shell = 1;
+ }
+
+ /* Multiplying the length of exec_file by 4 is to account for the fact
+ that it may expand when quoted; it is a worst-case number based on
+ every character being '. */
+ len = 5 + 4 * strlen (exec_file) + 1 + strlen (allargs) + 1 + /*slop */ 12;
+ /* If desired, concat something onto the front of ALLARGS.
+ SHELL_COMMAND is the result. */
+#ifdef SHELL_COMMAND_CONCAT
+ shell_command = (char *) alloca (strlen (SHELL_COMMAND_CONCAT) + len);
+ strcpy (shell_command, SHELL_COMMAND_CONCAT);
+#else
+ shell_command = (char *) alloca (len);
+ shell_command[0] = '\0';
+#endif
+
+ if (!shell)
+ {
+ /* We're going to call execvp. Create argv */
+ /* Largest case: every other character is a separate arg */
+ argv = (char **) xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) * sizeof (*argv));
+ argv[0] = exec_file;
+ breakup_args (allargs, &argv[1]);
+
+ }
+ else
+ {
+
+ /* We're going to call a shell */
+
+ /* Now add exec_file, quoting as necessary. */
+
+ char *p;
+ int need_to_quote;
+
+ strcat (shell_command, "exec ");
+
+ /* Quoting in this style is said to work with all shells. But csh
+ on IRIX 4.0.1 can't deal with it. So we only quote it if we need
+ to. */
+ p = exec_file;
+ while (1)
+ {
+ switch (*p)
+ {
+ case '\'':
+ case '!':
+ case '"':
+ case '(':
+ case ')':
+ case '$':
+ case '&':
+ case ';':
+ case '<':
+ case '>':
+ case ' ':
+ case '\n':
+ case '\t':
+ need_to_quote = 1;
+ goto end_scan;
+
+ case '\0':
+ need_to_quote = 0;
+ goto end_scan;
+
+ default:
+ break;
+ }
+ ++p;
+ }
+ end_scan:
+ if (need_to_quote)
+ {
+ strcat (shell_command, "'");
+ for (p = exec_file; *p != '\0'; ++p)
+ {
+ if (*p == '\'')
+ strcat (shell_command, "'\\''");
+ else if (*p == '!')
+ strcat (shell_command, "\\!");
+ else
+ strncat (shell_command, p, 1);
+ }
+ strcat (shell_command, "'");
+ }
+ else
+ strcat (shell_command, exec_file);
+
+ strcat (shell_command, " ");
+ strcat (shell_command, allargs);
+
+ }
+
+ /* exec is said to fail if the executable is open. */
+ close_exec_file ();
+
+ /* Retain a copy of our environment variables, since the child will
+ replace the value of environ and if we're vforked, we have to
+ restore it. */
+ save_our_env = environ;
+
+ /* Tell the terminal handling subsystem what tty we plan to run on;
+ it will just record the information for later. */
+
+ new_tty_prefork (inferior_io_terminal);
+
+ /* It is generally good practice to flush any possible pending stdio
+ output prior to doing a fork, to avoid the possibility of both the
+ parent and child flushing the same data after the fork. */
+
+ gdb_flush (gdb_stdout);
+ gdb_flush (gdb_stderr);
+
+ /* If there's any initialization of the target layers that must happen
+ to prepare to handle the child we're about fork, do it now...
+ */
+ if (pre_trace_fun != NULL)
+ (*pre_trace_fun) ();
+
+ /* Create the child process. Note that the apparent call to vfork()
+ below *might* actually be a call to fork() due to the fact that
+ autoconf will ``#define vfork fork'' on certain platforms. */
+ if (debug_fork)
+ pid = fork ();
+ else
+ pid = vfork ();
+
+ if (pid < 0)
+ perror_with_name ("vfork");
+
+ if (pid == 0)
+ {
+ if (debug_fork)
+ sleep (debug_fork);
+
+ /* Run inferior in a separate process group. */
+ debug_setpgrp = gdb_setpgid ();
+ if (debug_setpgrp == -1)
+ perror ("setpgrp failed in child");
+
+ /* Ask the tty subsystem to switch to the one we specified earlier
+ (or to share the current terminal, if none was specified). */
+
+ new_tty ();
+
+ /* Changing the signal handlers for the inferior after
+ a vfork can also change them for the superior, so we don't mess
+ with signals here. See comments in
+ initialize_signals for how we get the right signal handlers
+ for the inferior. */
+
+ /* "Trace me, Dr. Memory!" */
+ (*traceme_fun) ();
+ /* The call above set this process (the "child") as debuggable
+ * by the original gdb process (the "parent"). Since processes
+ * (unlike people) can have only one parent, if you are
+ * debugging gdb itself (and your debugger is thus _already_ the
+ * controller/parent for this child), code from here on out
+ * is undebuggable. Indeed, you probably got an error message
+ * saying "not parent". Sorry--you'll have to use print statements!
+ */
+
+ /* There is no execlpe call, so we have to set the environment
+ for our child in the global variable. If we've vforked, this
+ clobbers the parent, but environ is restored a few lines down
+ in the parent. By the way, yes we do need to look down the
+ path to find $SHELL. Rich Pixley says so, and I agree. */
+ environ = env;
+
+ /* If we decided above to start up with a shell,
+ * we exec the shell,
+ * "-c" says to interpret the next arg as a shell command
+ * to execute, and this command is "exec <target-program> <args>".
+ * "-f" means "fast startup" to the c-shell, which means
+ * don't do .cshrc file. Doing .cshrc may cause fork/exec
+ * events which will confuse debugger start-up code.
+ */
+ if (shell)
+ {
+ execlp (shell_file, shell_file, "-c", shell_command, (char *) 0);
+
+ /* If we get here, it's an error */
+ fprintf_unfiltered (gdb_stderr, "Cannot exec %s: %s.\n", shell_file,
+ safe_strerror (errno));
+ gdb_flush (gdb_stderr);
+ _exit (0177);
+ }
+ else
+ {
+ /* Otherwise, we directly exec the target program with execvp. */
+ int i;
+ char *errstring;
+
+ execvp (exec_file, argv);
+
+ /* If we get here, it's an error */
+ errstring = safe_strerror (errno);
+ fprintf_unfiltered (gdb_stderr, "Cannot exec %s ", exec_file);
+
+ i = 1;
+ while (argv[i] != NULL)
+ {
+ if (i != 1)
+ fprintf_unfiltered (gdb_stderr, " ");
+ fprintf_unfiltered (gdb_stderr, "%s", argv[i]);
+ i++;
+ }
+ fprintf_unfiltered (gdb_stderr, ".\n");
+ /* This extra info seems to be useless
+ fprintf_unfiltered (gdb_stderr, "Got error %s.\n", errstring);
+ */
+ gdb_flush (gdb_stderr);
+ _exit (0177);
+ }
+ }
+
+ /* Restore our environment in case a vforked child clob'd it. */
+ environ = save_our_env;
+
+ init_thread_list ();
+
+ inferior_ptid = pid_to_ptid (pid); /* Needed for wait_for_inferior stuff below */
+
+ /* Now that we have a child process, make it our target, and
+ initialize anything target-vector-specific that needs initializing. */
+
+ (*init_trace_fun) (pid);
+
+ /* We are now in the child process of interest, having exec'd the
+ correct program, and are poised at the first instruction of the
+ new program. */
+
+ /* Allow target dependent code to play with the new process. This might be
+ used to have target-specific code initialize a variable in the new process
+ prior to executing the first instruction. */
+ TARGET_CREATE_INFERIOR_HOOK (pid);
+
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+ SOLIB_CREATE_INFERIOR_HOOK (pid);
+#endif
+}
+
+/* An inferior Unix process CHILD_PID has been created by a call to
+ fork() (or variants like vfork). It is presently stopped, and waiting
+ to be resumed. clone_and_follow_inferior will fork the debugger,
+ and that clone will "follow" (attach to) CHILD_PID. The original copy
+ of the debugger will not touch CHILD_PID again.
+
+ Also, the original debugger will set FOLLOWED_CHILD FALSE, while the
+ clone will set it TRUE.
+ */
+void
+clone_and_follow_inferior (int child_pid, int *followed_child)
+{
+ int debugger_pid;
+ int status;
+ char pid_spelling[100]; /* Arbitrary but sufficient length. */
+
+ /* This semaphore is used to coordinate the two debuggers' handoff
+ of CHILD_PID. The original debugger will detach from CHILD_PID,
+ and then the clone debugger will attach to it. (It must be done
+ this way because on some targets, only one process at a time can
+ trace another. Thus, the original debugger must relinquish its
+ tracing rights before the clone can pick them up.)
+ */
+#define SEM_TALK (1)
+#define SEM_LISTEN (0)
+ int handoff_semaphore[2]; /* Original "talks" to [1], clone "listens" to [0] */
+ int talk_value = 99;
+ int listen_value;
+
+ /* Set debug_fork then attach to the child while it sleeps, to debug. */
+ static int debug_fork = 0;
+
+ /* It is generally good practice to flush any possible pending stdio
+ output prior to doing a fork, to avoid the possibility of both the
+ parent and child flushing the same data after the fork. */
+
+ gdb_flush (gdb_stdout);
+ gdb_flush (gdb_stderr);
+
+ /* Open the semaphore pipes.
+ */
+ status = pipe (handoff_semaphore);
+ if (status < 0)
+ error ("error getting pipe for handoff semaphore");
+
+ /* Clone the debugger. Note that the apparent call to vfork()
+ below *might* actually be a call to fork() due to the fact that
+ autoconf will ``#define vfork fork'' on certain platforms. */
+ if (debug_fork)
+ debugger_pid = fork ();
+ else
+ debugger_pid = vfork ();
+
+ if (debugger_pid < 0)
+ perror_with_name ("fork");
+
+ /* Are we the original debugger? If so, we must relinquish all claims
+ to CHILD_PID. */
+ if (debugger_pid != 0)
+ {
+ char signal_spelling[100]; /* Arbitrary but sufficient length */
+
+ /* Detach from CHILD_PID. Deliver a "stop" signal when we do, though,
+ so that it remains stopped until the clone debugger can attach
+ to it.
+ */
+ detach_breakpoints (child_pid);
+
+ sprintf (signal_spelling, "%d", target_signal_to_host (TARGET_SIGNAL_STOP));
+ target_require_detach (child_pid, signal_spelling, 1);
+
+ /* Notify the clone debugger that it should attach to CHILD_PID. */
+ write (handoff_semaphore[SEM_TALK], &talk_value, sizeof (talk_value));
+
+ *followed_child = 0;
+ }
+
+ /* We're the child. */
+ else
+ {
+ if (debug_fork)
+ sleep (debug_fork);
+
+ /* The child (i.e., the cloned debugger) must now attach to
+ CHILD_PID. inferior_ptid is presently set to the parent process
+ of the fork, while CHILD_PID should be the child process of the
+ fork.
+
+ Wait until the original debugger relinquishes control of CHILD_PID,
+ though.
+ */
+ read (handoff_semaphore[SEM_LISTEN], &listen_value, sizeof (listen_value));
+
+ /* Note that we DON'T want to actually detach from inferior_ptid,
+ because that would allow it to run free. The original
+ debugger wants to retain control of the process. So, we
+ just reset inferior_ptid to CHILD_PID, and then ensure that all
+ breakpoints are really set in CHILD_PID.
+ */
+ target_mourn_inferior ();
+
+ /* Ask the tty subsystem to switch to the one we specified earlier
+ (or to share the current terminal, if none was specified). */
+
+ new_tty ();
+
+ dont_repeat ();
+ sprintf (pid_spelling, "%d", child_pid);
+ target_require_attach (pid_spelling, 1);
+
+ /* Perform any necessary cleanup, after attachment. (This form
+ of attaching can behave differently on some targets than the
+ standard method, where a process formerly not under debugger
+ control was suddenly attached to..)
+ */
+ target_post_follow_inferior_by_clone ();
+
+ *followed_child = 1;
+ }
+
+ /* Discard the handoff sempahore. */
+ (void) close (handoff_semaphore[SEM_LISTEN]);
+ (void) close (handoff_semaphore[SEM_TALK]);
+}
+
+/* Accept NTRAPS traps from the inferior. */
+
+void
+startup_inferior (int ntraps)
+{
+ int pending_execs = ntraps;
+ int terminal_initted;
+
+ /* The process was started by the fork that created it,
+ but it will have stopped one instruction after execing the shell.
+ Here we must get it up to actual execution of the real program. */
+
+ clear_proceed_status ();
+
+ init_wait_for_inferior ();
+
+ terminal_initted = 0;
+
+ if (STARTUP_WITH_SHELL)
+ inferior_ignoring_startup_exec_events = ntraps;
+ else
+ inferior_ignoring_startup_exec_events = 0;
+ inferior_ignoring_leading_exec_events =
+ target_reported_exec_events_per_exec_call () - 1;
+
+#ifdef STARTUP_INFERIOR
+ STARTUP_INFERIOR (pending_execs);
+#else
+ while (1)
+ {
+ stop_soon_quietly = 1; /* Make wait_for_inferior be quiet */
+ wait_for_inferior ();
+ if (stop_signal != TARGET_SIGNAL_TRAP)
+ {
+ /* Let shell child handle its own signals in its own way */
+ /* FIXME, what if child has exit()ed? Must exit loop somehow */
+ resume (0, stop_signal);
+ }
+ else
+ {
+ /* We handle SIGTRAP, however; it means child did an exec. */
+ if (!terminal_initted)
+ {
+ /* Now that the child has exec'd we know it has already set its
+ process group. On POSIX systems, tcsetpgrp will fail with
+ EPERM if we try it before the child's setpgid. */
+
+ /* Set up the "saved terminal modes" of the inferior
+ based on what modes we are starting it with. */
+ target_terminal_init ();
+
+ /* Install inferior's terminal modes. */
+ target_terminal_inferior ();
+
+ terminal_initted = 1;
+ }
+
+ pending_execs = pending_execs - 1;
+ if (0 == pending_execs)
+ break;
+
+ resume (0, TARGET_SIGNAL_0); /* Just make it go on */
+ }
+ }
+#endif /* STARTUP_INFERIOR */
+ stop_soon_quietly = 0;
+}
diff --git a/gdb/fr30-tdep.c b/gdb/fr30-tdep.c
new file mode 100644
index 00000000000..09f886fed87
--- /dev/null
+++ b/gdb/fr30-tdep.c
@@ -0,0 +1,601 @@
+/* Target-dependent code for the Fujitsu FR30.
+ Copyright 1999, 2000, 2001 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "obstack.h"
+#include "target.h"
+#include "value.h"
+#include "bfd.h"
+#include "gdb_string.h"
+#include "gdbcore.h"
+#include "symfile.h"
+#include "regcache.h"
+
+/* An expression that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. */
+int
+fr30_frameless_function_invocation (struct frame_info *fi)
+{
+ int frameless;
+ CORE_ADDR func_start, after_prologue;
+ func_start = (get_pc_function_start ((fi)->pc) +
+ FUNCTION_START_OFFSET);
+ after_prologue = func_start;
+ after_prologue = SKIP_PROLOGUE (after_prologue);
+ frameless = (after_prologue == func_start);
+ return frameless;
+}
+
+/* Function: pop_frame
+ This routine gets called when either the user uses the `return'
+ command, or the call dummy breakpoint gets hit. */
+
+void
+fr30_pop_frame (void)
+{
+ struct frame_info *frame = get_current_frame ();
+ int regnum;
+ CORE_ADDR sp = read_register (SP_REGNUM);
+
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ generic_pop_dummy_frame ();
+ else
+ {
+ write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
+
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ if (frame->fsr.regs[regnum] != 0)
+ {
+ write_register (regnum,
+ read_memory_unsigned_integer (frame->fsr.regs[regnum],
+ REGISTER_RAW_SIZE (regnum)));
+ }
+ write_register (SP_REGNUM, sp + frame->framesize);
+ }
+ flush_cached_frames ();
+}
+
+
+/* Function: fr30_store_return_value
+ Put a value where a caller expects to see it. Used by the 'return'
+ command. */
+void
+fr30_store_return_value (struct type *type,
+ char *valbuf)
+{
+ /* Here's how the FR30 returns values (gleaned from gcc/config/
+ fr30/fr30.h):
+
+ If the return value is 32 bits long or less, it goes in r4.
+
+ If the return value is 64 bits long or less, it goes in r4 (most
+ significant word) and r5 (least significant word.
+
+ If the function returns a structure, of any size, the caller
+ passes the function an invisible first argument where the callee
+ should store the value. But GDB doesn't let you do that anyway.
+
+ If you're returning a value smaller than a word, it's not really
+ necessary to zero the upper bytes of the register; the caller is
+ supposed to ignore them. However, the FR30 typically keeps its
+ values extended to the full register width, so we should emulate
+ that. */
+
+ /* The FR30 is big-endian, so if we return a small value (like a
+ short or a char), we need to position it correctly within the
+ register. We round the size up to a register boundary, and then
+ adjust the offset so as to place the value at the right end. */
+ int value_size = TYPE_LENGTH (type);
+ int returned_size = (value_size + FR30_REGSIZE - 1) & ~(FR30_REGSIZE - 1);
+ int offset = (REGISTER_BYTE (RETVAL_REG)
+ + (returned_size - value_size));
+ char *zeros = alloca (returned_size);
+ memset (zeros, 0, returned_size);
+
+ write_register_bytes (REGISTER_BYTE (RETVAL_REG), zeros, returned_size);
+ write_register_bytes (offset, valbuf, value_size);
+}
+
+
+/* Function: skip_prologue
+ Return the address of the first code past the prologue of the function. */
+
+CORE_ADDR
+fr30_skip_prologue (CORE_ADDR pc)
+{
+ CORE_ADDR func_addr, func_end;
+
+ /* See what the symbol table says */
+
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (func_addr, 0);
+
+ if (sal.line != 0 && sal.end < func_end)
+ {
+ return sal.end;
+ }
+ }
+
+/* Either we didn't find the start of this function (nothing we can do),
+ or there's no line info, or the line after the prologue is after
+ the end of the function (there probably isn't a prologue). */
+
+ return pc;
+}
+
+
+/* Function: push_arguments
+ Setup arguments and RP for a call to the target. First four args
+ go in FIRST_ARGREG -> LAST_ARGREG, subsequent args go on stack...
+ Structs are passed by reference. XXX not right now Z.R.
+ 64 bit quantities (doubles and long longs) may be split between
+ the regs and the stack.
+ When calling a function that returns a struct, a pointer to the struct
+ is passed in as a secret first argument (always in FIRST_ARGREG).
+
+ Stack space for the args has NOT been allocated: that job is up to us.
+ */
+
+CORE_ADDR
+fr30_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int argreg;
+ int argnum;
+ int stack_offset;
+ struct stack_arg
+ {
+ char *val;
+ int len;
+ int offset;
+ };
+ struct stack_arg *stack_args =
+ (struct stack_arg *) alloca (nargs * sizeof (struct stack_arg));
+ int nstack_args = 0;
+
+ argreg = FIRST_ARGREG;
+
+ /* the struct_return pointer occupies the first parameter-passing reg */
+ if (struct_return)
+ write_register (argreg++, struct_addr);
+
+ stack_offset = 0;
+
+ /* Process args from left to right. Store as many as allowed in
+ registers, save the rest to be pushed on the stack */
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ char *val;
+ struct value *arg = args[argnum];
+ struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+ struct type *target_type = TYPE_TARGET_TYPE (arg_type);
+ int len = TYPE_LENGTH (arg_type);
+ enum type_code typecode = TYPE_CODE (arg_type);
+ CORE_ADDR regval;
+ int newarg;
+
+ val = (char *) VALUE_CONTENTS (arg);
+
+ {
+ /* Copy the argument to general registers or the stack in
+ register-sized pieces. Large arguments are split between
+ registers and stack. */
+ while (len > 0)
+ {
+ if (argreg <= LAST_ARGREG)
+ {
+ int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE;
+ regval = extract_address (val, partial_len);
+
+ /* It's a simple argument being passed in a general
+ register. */
+ write_register (argreg, regval);
+ argreg++;
+ len -= partial_len;
+ val += partial_len;
+ }
+ else
+ {
+ /* keep for later pushing */
+ stack_args[nstack_args].val = val;
+ stack_args[nstack_args++].len = len;
+ break;
+ }
+ }
+ }
+ }
+ /* now do the real stack pushing, process args right to left */
+ while (nstack_args--)
+ {
+ sp -= stack_args[nstack_args].len;
+ write_memory (sp, stack_args[nstack_args].val,
+ stack_args[nstack_args].len);
+ }
+
+ /* Return adjusted stack pointer. */
+ return sp;
+}
+
+void _initialize_fr30_tdep (void);
+
+void
+_initialize_fr30_tdep (void)
+{
+ extern int print_insn_fr30 (bfd_vma, disassemble_info *);
+ tm_print_insn = print_insn_fr30;
+}
+
+/* Function: check_prologue_cache
+ Check if prologue for this frame's PC has already been scanned.
+ If it has, copy the relevant information about that prologue and
+ return non-zero. Otherwise do not copy anything and return zero.
+
+ The information saved in the cache includes:
+ * the frame register number;
+ * the size of the stack frame;
+ * the offsets of saved regs (relative to the old SP); and
+ * the offset from the stack pointer to the frame pointer
+
+ The cache contains only one entry, since this is adequate
+ for the typical sequence of prologue scan requests we get.
+ When performing a backtrace, GDB will usually ask to scan
+ the same function twice in a row (once to get the frame chain,
+ and once to fill in the extra frame information).
+ */
+
+static struct frame_info prologue_cache;
+
+static int
+check_prologue_cache (struct frame_info *fi)
+{
+ int i;
+
+ if (fi->pc == prologue_cache.pc)
+ {
+ fi->framereg = prologue_cache.framereg;
+ fi->framesize = prologue_cache.framesize;
+ fi->frameoffset = prologue_cache.frameoffset;
+ for (i = 0; i <= NUM_REGS; i++)
+ fi->fsr.regs[i] = prologue_cache.fsr.regs[i];
+ return 1;
+ }
+ else
+ return 0;
+}
+
+
+/* Function: save_prologue_cache
+ Copy the prologue information from fi to the prologue cache.
+ */
+
+static void
+save_prologue_cache (struct frame_info *fi)
+{
+ int i;
+
+ prologue_cache.pc = fi->pc;
+ prologue_cache.framereg = fi->framereg;
+ prologue_cache.framesize = fi->framesize;
+ prologue_cache.frameoffset = fi->frameoffset;
+
+ for (i = 0; i <= NUM_REGS; i++)
+ {
+ prologue_cache.fsr.regs[i] = fi->fsr.regs[i];
+ }
+}
+
+
+/* Function: scan_prologue
+ Scan the prologue of the function that contains PC, and record what
+ we find in PI. PI->fsr must be zeroed by the called. Returns the
+ pc after the prologue. Note that the addresses saved in pi->fsr
+ are actually just frame relative (negative offsets from the frame
+ pointer). This is because we don't know the actual value of the
+ frame pointer yet. In some circumstances, the frame pointer can't
+ be determined till after we have scanned the prologue. */
+
+static void
+fr30_scan_prologue (struct frame_info *fi)
+{
+ int sp_offset, fp_offset;
+ CORE_ADDR prologue_start, prologue_end, current_pc;
+
+ /* Check if this function is already in the cache of frame information. */
+ if (check_prologue_cache (fi))
+ return;
+
+ /* Assume there is no frame until proven otherwise. */
+ fi->framereg = SP_REGNUM;
+ fi->framesize = 0;
+ fi->frameoffset = 0;
+
+ /* Find the function prologue. If we can't find the function in
+ the symbol table, peek in the stack frame to find the PC. */
+ if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end))
+ {
+ /* Assume the prologue is everything between the first instruction
+ in the function and the first source line. */
+ struct symtab_and_line sal = find_pc_line (prologue_start, 0);
+
+ if (sal.line == 0) /* no line info, use current PC */
+ prologue_end = fi->pc;
+ else if (sal.end < prologue_end) /* next line begins after fn end */
+ prologue_end = sal.end; /* (probably means no prologue) */
+ }
+ else
+ {
+ /* XXX Z.R. What now??? The following is entirely bogus */
+ prologue_start = (read_memory_integer (fi->frame, 4) & 0x03fffffc) - 12;
+ prologue_end = prologue_start + 40;
+ }
+
+ /* Now search the prologue looking for instructions that set up the
+ frame pointer, adjust the stack pointer, and save registers. */
+
+ sp_offset = fp_offset = 0;
+ for (current_pc = prologue_start; current_pc < prologue_end; current_pc += 2)
+ {
+ unsigned int insn;
+
+ insn = read_memory_unsigned_integer (current_pc, 2);
+
+ if ((insn & 0xfe00) == 0x8e00) /* stm0 or stm1 */
+ {
+ int reg, mask = insn & 0xff;
+
+ /* scan in one sweep - create virtual 16-bit mask from either insn's mask */
+ if ((insn & 0x0100) == 0)
+ {
+ mask <<= 8; /* stm0 - move to upper byte in virtual mask */
+ }
+
+ /* Calculate offsets of saved registers (to be turned later into addresses). */
+ for (reg = R4_REGNUM; reg <= R11_REGNUM; reg++)
+ if (mask & (1 << (15 - reg)))
+ {
+ sp_offset -= 4;
+ fi->fsr.regs[reg] = sp_offset;
+ }
+ }
+ else if ((insn & 0xfff0) == 0x1700) /* st rx,@-r15 */
+ {
+ int reg = insn & 0xf;
+
+ sp_offset -= 4;
+ fi->fsr.regs[reg] = sp_offset;
+ }
+ else if ((insn & 0xff00) == 0x0f00) /* enter */
+ {
+ fp_offset = fi->fsr.regs[FP_REGNUM] = sp_offset - 4;
+ sp_offset -= 4 * (insn & 0xff);
+ fi->framereg = FP_REGNUM;
+ }
+ else if (insn == 0x1781) /* st rp,@-sp */
+ {
+ sp_offset -= 4;
+ fi->fsr.regs[RP_REGNUM] = sp_offset;
+ }
+ else if (insn == 0x170e) /* st fp,@-sp */
+ {
+ sp_offset -= 4;
+ fi->fsr.regs[FP_REGNUM] = sp_offset;
+ }
+ else if (insn == 0x8bfe) /* mov sp,fp */
+ {
+ fi->framereg = FP_REGNUM;
+ }
+ else if ((insn & 0xff00) == 0xa300) /* addsp xx */
+ {
+ sp_offset += 4 * (signed char) (insn & 0xff);
+ }
+ else if ((insn & 0xff0f) == 0x9b00 && /* ldi:20 xx,r0 */
+ read_memory_unsigned_integer (current_pc + 4, 2)
+ == 0xac0f) /* sub r0,sp */
+ {
+ /* large stack adjustment */
+ sp_offset -= (((insn & 0xf0) << 12) | read_memory_unsigned_integer (current_pc + 2, 2));
+ current_pc += 4;
+ }
+ else if (insn == 0x9f80 && /* ldi:32 xx,r0 */
+ read_memory_unsigned_integer (current_pc + 6, 2)
+ == 0xac0f) /* sub r0,sp */
+ {
+ /* large stack adjustment */
+ sp_offset -=
+ (read_memory_unsigned_integer (current_pc + 2, 2) << 16 |
+ read_memory_unsigned_integer (current_pc + 4, 2));
+ current_pc += 6;
+ }
+ }
+
+ /* The frame size is just the negative of the offset (from the original SP)
+ of the last thing thing we pushed on the stack. The frame offset is
+ [new FP] - [new SP]. */
+ fi->framesize = -sp_offset;
+ fi->frameoffset = fp_offset - sp_offset;
+
+ save_prologue_cache (fi);
+}
+
+/* Function: init_extra_frame_info
+ Setup the frame's frame pointer, pc, and frame addresses for saved
+ registers. Most of the work is done in scan_prologue().
+
+ Note that when we are called for the last frame (currently active frame),
+ that fi->pc and fi->frame will already be setup. However, fi->frame will
+ be valid only if this routine uses FP. For previous frames, fi-frame will
+ always be correct (since that is derived from fr30_frame_chain ()).
+
+ We can be called with the PC in the call dummy under two circumstances.
+ First, during normal backtracing, second, while figuring out the frame
+ pointer just prior to calling the target function (see run_stack_dummy). */
+
+void
+fr30_init_extra_frame_info (struct frame_info *fi)
+{
+ int reg;
+
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs);
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ /* We need to setup fi->frame here because run_stack_dummy gets it wrong
+ by assuming it's always FP. */
+ fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
+ fi->framesize = 0;
+ fi->frameoffset = 0;
+ return;
+ }
+ fr30_scan_prologue (fi);
+
+ if (!fi->next) /* this is the innermost frame? */
+ fi->frame = read_register (fi->framereg);
+ else
+ /* not the innermost frame */
+ /* If we have an FP, the callee saved it. */
+ if (fi->framereg == FP_REGNUM)
+ if (fi->next->fsr.regs[fi->framereg] != 0)
+ fi->frame = read_memory_integer (fi->next->fsr.regs[fi->framereg], 4);
+
+ /* Calculate actual addresses of saved registers using offsets determined
+ by fr30_scan_prologue. */
+ for (reg = 0; reg < NUM_REGS; reg++)
+ if (fi->fsr.regs[reg] != 0)
+ {
+ fi->fsr.regs[reg] += fi->frame + fi->framesize - fi->frameoffset;
+ }
+}
+
+/* Function: find_callers_reg
+ Find REGNUM on the stack. Otherwise, it's in an active register.
+ One thing we might want to do here is to check REGNUM against the
+ clobber mask, and somehow flag it as invalid if it isn't saved on
+ the stack somewhere. This would provide a graceful failure mode
+ when trying to get the value of caller-saves registers for an inner
+ frame. */
+
+CORE_ADDR
+fr30_find_callers_reg (struct frame_info *fi, int regnum)
+{
+ for (; fi; fi = fi->next)
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, regnum);
+ else if (fi->fsr.regs[regnum] != 0)
+ return read_memory_unsigned_integer (fi->fsr.regs[regnum],
+ REGISTER_RAW_SIZE (regnum));
+
+ return read_register (regnum);
+}
+
+
+/* Function: frame_chain
+ Figure out the frame prior to FI. Unfortunately, this involves
+ scanning the prologue of the caller, which will also be done
+ shortly by fr30_init_extra_frame_info. For the dummy frame, we
+ just return the stack pointer that was in use at the time the
+ function call was made. */
+
+
+CORE_ADDR
+fr30_frame_chain (struct frame_info *fi)
+{
+ CORE_ADDR fn_start, callers_pc, fp;
+ struct frame_info caller_fi;
+ int framereg;
+
+ /* is this a dummy frame? */
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return fi->frame; /* dummy frame same as caller's frame */
+
+ /* is caller-of-this a dummy frame? */
+ callers_pc = FRAME_SAVED_PC (fi); /* find out who called us: */
+ fp = fr30_find_callers_reg (fi, FP_REGNUM);
+ if (PC_IN_CALL_DUMMY (callers_pc, fp, fp))
+ return fp; /* dummy frame's frame may bear no relation to ours */
+
+ if (find_pc_partial_function (fi->pc, 0, &fn_start, 0))
+ if (fn_start == entry_point_address ())
+ return 0; /* in _start fn, don't chain further */
+
+ framereg = fi->framereg;
+
+ /* If the caller is the startup code, we're at the end of the chain. */
+ if (find_pc_partial_function (callers_pc, 0, &fn_start, 0))
+ if (fn_start == entry_point_address ())
+ return 0;
+
+ memset (&caller_fi, 0, sizeof (caller_fi));
+ caller_fi.pc = callers_pc;
+ fr30_scan_prologue (&caller_fi);
+ framereg = caller_fi.framereg;
+
+ /* If the caller used a frame register, return its value.
+ Otherwise, return the caller's stack pointer. */
+ if (framereg == FP_REGNUM)
+ return fr30_find_callers_reg (fi, framereg);
+ else
+ return fi->frame + fi->framesize;
+}
+
+/* Function: frame_saved_pc
+ Find the caller of this frame. We do this by seeing if RP_REGNUM
+ is saved in the stack anywhere, otherwise we get it from the
+ registers. If the inner frame is a dummy frame, return its PC
+ instead of RP, because that's where "caller" of the dummy-frame
+ will be found. */
+
+CORE_ADDR
+fr30_frame_saved_pc (struct frame_info *fi)
+{
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
+ else
+ return fr30_find_callers_reg (fi, RP_REGNUM);
+}
+
+/* Function: fix_call_dummy
+ Pokes the callee function's address into the CALL_DUMMY assembly stub.
+ Assumes that the CALL_DUMMY looks like this:
+ jarl <offset24>, r31
+ trap
+ */
+
+int
+fr30_fix_call_dummy (char *dummy, CORE_ADDR sp, CORE_ADDR fun, int nargs,
+ struct value **args, struct type *type, int gcc_p)
+{
+ long offset24;
+
+ offset24 = (long) fun - (long) entry_point_address ();
+ offset24 &= 0x3fffff;
+ offset24 |= 0xff800000; /* jarl <offset24>, r31 */
+
+ store_unsigned_integer ((unsigned int *) &dummy[2], 2, offset24 & 0xffff);
+ store_unsigned_integer ((unsigned int *) &dummy[0], 2, offset24 >> 16);
+ return 0;
+}
diff --git a/gdb/frame.c b/gdb/frame.c
new file mode 100644
index 00000000000..24cd9071437
--- /dev/null
+++ b/gdb/frame.c
@@ -0,0 +1,171 @@
+/* Cache and manage the values of registers for GDB, the GNU debugger.
+
+ Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000,
+ 2001, 2002 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 "defs.h"
+#include "frame.h"
+#include "target.h"
+#include "value.h"
+#include "inferior.h" /* for inferior_ptid */
+#include "regcache.h"
+
+/* FIND_SAVED_REGISTER ()
+
+ Return the address in which frame FRAME's value of register REGNUM
+ has been saved in memory. Or return zero if it has not been saved.
+ If REGNUM specifies the SP, the value we return is actually
+ the SP value, not an address where it was saved. */
+
+CORE_ADDR
+find_saved_register (struct frame_info *frame, int regnum)
+{
+ register struct frame_info *frame1 = NULL;
+ register CORE_ADDR addr = 0;
+
+ if (frame == NULL) /* No regs saved if want current frame */
+ return 0;
+
+ /* Note that this next routine assumes that registers used in
+ frame x will be saved only in the frame that x calls and
+ frames interior to it. This is not true on the sparc, but the
+ above macro takes care of it, so we should be all right. */
+ while (1)
+ {
+ QUIT;
+ frame1 = get_next_frame (frame);
+ if (frame1 == 0)
+ break;
+ frame = frame1;
+ FRAME_INIT_SAVED_REGS (frame1);
+ if (frame1->saved_regs[regnum])
+ addr = frame1->saved_regs[regnum];
+ }
+
+ return addr;
+}
+
+/* DEFAULT_GET_SAVED_REGISTER ()
+
+ Find register number REGNUM relative to FRAME and put its (raw,
+ target format) contents in *RAW_BUFFER. Set *OPTIMIZED if the
+ variable was optimized out (and thus can't be fetched). Set *LVAL
+ to lval_memory, lval_register, or not_lval, depending on whether
+ the value was fetched from memory, from a register, or in a strange
+ and non-modifiable way (e.g. a frame pointer which was calculated
+ rather than fetched). Set *ADDRP to the address, either in memory
+ on as a REGISTER_BYTE offset into the registers array.
+
+ Note that this implementation never sets *LVAL to not_lval. But
+ it can be replaced by defining GET_SAVED_REGISTER and supplying
+ your own.
+
+ The argument RAW_BUFFER must point to aligned memory. */
+
+static void
+default_get_saved_register (char *raw_buffer,
+ int *optimized,
+ CORE_ADDR *addrp,
+ struct frame_info *frame,
+ int regnum,
+ enum lval_type *lval)
+{
+ CORE_ADDR addr;
+
+ if (!target_has_registers)
+ error ("No registers.");
+
+ /* Normal systems don't optimize out things with register numbers. */
+ if (optimized != NULL)
+ *optimized = 0;
+ addr = find_saved_register (frame, regnum);
+ if (addr != 0)
+ {
+ if (lval != NULL)
+ *lval = lval_memory;
+ if (regnum == SP_REGNUM)
+ {
+ if (raw_buffer != NULL)
+ {
+ /* Put it back in target format. */
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
+ (LONGEST) addr);
+ }
+ if (addrp != NULL)
+ *addrp = 0;
+ return;
+ }
+ if (raw_buffer != NULL)
+ target_read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum));
+ }
+ else
+ {
+ if (lval != NULL)
+ *lval = lval_register;
+ addr = REGISTER_BYTE (regnum);
+ if (raw_buffer != NULL)
+ read_register_gen (regnum, raw_buffer);
+ }
+ if (addrp != NULL)
+ *addrp = addr;
+}
+
+#if !defined (GET_SAVED_REGISTER)
+#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \
+ default_get_saved_register(raw_buffer, optimized, addrp, frame, regnum, lval)
+#endif
+
+void
+get_saved_register (char *raw_buffer,
+ int *optimized,
+ CORE_ADDR *addrp,
+ struct frame_info *frame,
+ int regnum,
+ enum lval_type *lval)
+{
+ GET_SAVED_REGISTER (raw_buffer, optimized, addrp, frame, regnum, lval);
+}
+
+/* frame_register_read ()
+
+ Find and return the value of REGNUM for the specified stack frame.
+ The number of bytes copied is REGISTER_RAW_SIZE (REGNUM).
+
+ Returns 0 if the register value could not be found. */
+
+int
+frame_register_read (struct frame_info *frame, int regnum, void *myaddr)
+{
+ int optim;
+ get_saved_register (myaddr, &optim, (CORE_ADDR *) NULL, frame,
+ regnum, (enum lval_type *) NULL);
+
+ /* FIXME: cagney/2002-05-15: This test, is just bogus.
+
+ It indicates that the target failed to supply a value for a
+ register because it was "not available" at this time. Problem
+ is, the target still has the register and so get saved_register()
+ may be returning a value saved on the stack. */
+
+ if (register_cached (regnum) < 0)
+ return 0; /* register value not available */
+
+ return !optim;
+}
diff --git a/gdb/frame.h b/gdb/frame.h
new file mode 100644
index 00000000000..f0631b01555
--- /dev/null
+++ b/gdb/frame.h
@@ -0,0 +1,293 @@
+/* Definitions for dealing with stack frames, for GDB, the GNU debugger.
+
+ Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996,
+ 1997, 1998, 1999, 2000, 2001, 2002 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. */
+
+#if !defined (FRAME_H)
+#define FRAME_H 1
+
+/* Describe the saved registers of a frame. */
+
+#if defined (EXTRA_FRAME_INFO) || defined (FRAME_FIND_SAVED_REGS)
+/* XXXX - deprecated */
+struct frame_saved_regs
+ {
+ /* For each register R (except the SP), regs[R] is the address at
+ which it was saved on entry to the frame, or zero if it was not
+ saved on entry to this frame. This includes special registers
+ such as pc and fp saved in special ways in the stack frame.
+
+ regs[SP_REGNUM] is different. It holds the actual SP, not the
+ address at which it was saved. */
+
+ CORE_ADDR regs[NUM_REGS];
+ };
+#endif
+
+/* We keep a cache of stack frames, each of which is a "struct
+ frame_info". The innermost one gets allocated (in
+ wait_for_inferior) each time the inferior stops; current_frame
+ points to it. Additional frames get allocated (in
+ get_prev_frame) as needed, and are chained through the next
+ and prev fields. Any time that the frame cache becomes invalid
+ (most notably when we execute something, but also if we change how
+ we interpret the frames (e.g. "set heuristic-fence-post" in
+ mips-tdep.c, or anything which reads new symbols)), we should call
+ reinit_frame_cache. */
+
+struct frame_info
+ {
+ /* Nominal address of the frame described. See comments at FRAME_FP
+ about what this means outside the *FRAME* macros; in the *FRAME*
+ macros, it can mean whatever makes most sense for this machine. */
+ CORE_ADDR frame;
+
+ /* Address at which execution is occurring in this frame.
+ For the innermost frame, it's the current pc.
+ For other frames, it is a pc saved in the next frame. */
+ CORE_ADDR pc;
+
+ /* Level of this frame. The inner-most (youngest) frame is at
+ level 0. As you move towards the outer-most (oldest) frame,
+ the level increases. This is a cached value. It could just as
+ easily be computed by counting back from the selected frame to
+ the inner most frame. */
+ /* NOTE: cagney/2002-04-05: Perhaphs a level of ``-1'' should be
+ reserved to indicate a bogus frame - one that has been created
+ just to keep GDB happy (GDB always needs a frame). For the
+ moment leave this as speculation. */
+ int level;
+
+ /* Nonzero if this is a frame associated with calling a signal handler.
+
+ Set by machine-dependent code. On some machines, if
+ the machine-dependent code fails to check for this, the backtrace
+ will look relatively normal. For example, on the i386
+ #3 0x158728 in sighold ()
+ On other machines (e.g. rs6000), the machine-dependent code better
+ set this to prevent us from trying to print it like a normal frame. */
+ int signal_handler_caller;
+
+ /* For each register, address of where it was saved on entry to
+ the frame, or zero if it was not saved on entry to this frame.
+ This includes special registers such as pc and fp saved in
+ special ways in the stack frame. The SP_REGNUM is even more
+ special, the address here is the sp for the previous frame, not
+ the address where the sp was saved. */
+ /* Allocated by frame_saved_regs_zalloc () which is called /
+ initialized by FRAME_INIT_SAVED_REGS(). */
+ CORE_ADDR *saved_regs; /*NUM_REGS + NUM_PSEUDO_REGS*/
+
+#ifdef EXTRA_FRAME_INFO
+ /* XXXX - deprecated */
+ /* Anything extra for this structure that may have been defined
+ in the machine dependent files. */
+ EXTRA_FRAME_INFO
+#endif
+
+ /* Anything extra for this structure that may have been defined
+ in the machine dependent files. */
+ /* Allocated by frame_obstack_alloc () which is called /
+ initialized by INIT_EXTRA_FRAME_INFO */
+ struct frame_extra_info *extra_info;
+
+ /* If dwarf2 unwind frame informations is used, this structure holds all
+ related unwind data. */
+ struct unwind_contect *context;
+
+ /* Pointers to the next (down, inner) and previous (up, outer)
+ frame_info's in the frame cache. */
+ struct frame_info *next; /* down, inner */
+ struct frame_info *prev; /* up, outer */
+ };
+
+/* Values for the source flag to be used in print_frame_info_base(). */
+enum print_what
+ {
+ /* Print only the source line, like in stepi. */
+ SRC_LINE = -1,
+ /* Print only the location, i.e. level, address (sometimes)
+ function, args, file, line, line num. */
+ LOCATION,
+ /* Print both of the above. */
+ SRC_AND_LOC,
+ /* Print location only, but always include the address. */
+ LOC_AND_ADDRESS
+ };
+
+/* Allocate additional space for appendices to a struct frame_info.
+ NOTE: Much of GDB's code works on the assumption that the allocated
+ saved_regs[] array is the size specified below. If you try to make
+ that array smaller, GDB will happily walk off its end. */
+
+#ifdef SIZEOF_FRAME_SAVED_REGS
+#error "SIZEOF_FRAME_SAVED_REGS can not be re-defined"
+#endif
+#define SIZEOF_FRAME_SAVED_REGS \
+ (sizeof (CORE_ADDR) * (NUM_REGS+NUM_PSEUDO_REGS))
+
+extern void *frame_obstack_alloc (unsigned long size);
+extern void frame_saved_regs_zalloc (struct frame_info *);
+
+/* Return the frame address from FI. Except in the machine-dependent
+ *FRAME* macros, a frame address has no defined meaning other than
+ as a magic cookie which identifies a frame over calls to the
+ inferior. The only known exception is inferior.h
+ (PC_IN_CALL_DUMMY) [ON_STACK]; see comments there. You cannot
+ assume that a frame address contains enough information to
+ reconstruct the frame; if you want more than just to identify the
+ frame (e.g. be able to fetch variables relative to that frame),
+ then save the whole struct frame_info (and the next struct
+ frame_info, since the latter is used for fetching variables on some
+ machines). */
+
+#define FRAME_FP(fi) ((fi)->frame)
+
+/* Level of the frame: 0 for innermost, 1 for its caller, ...; or -1
+ for an invalid frame. */
+
+extern int frame_relative_level (struct frame_info *fi);
+
+/* Define a default FRAME_CHAIN_VALID, in the form that is suitable for most
+ targets. If FRAME_CHAIN_VALID returns zero it means that the given frame
+ is the outermost one and has no caller.
+
+ XXXX - both default and alternate frame_chain_valid functions are
+ deprecated. New code should use dummy frames and one of the
+ generic functions. */
+
+extern int file_frame_chain_valid (CORE_ADDR, struct frame_info *);
+extern int func_frame_chain_valid (CORE_ADDR, struct frame_info *);
+extern int nonnull_frame_chain_valid (CORE_ADDR, struct frame_info *);
+extern int generic_file_frame_chain_valid (CORE_ADDR, struct frame_info *);
+extern int generic_func_frame_chain_valid (CORE_ADDR, struct frame_info *);
+extern void generic_save_dummy_frame_tos (CORE_ADDR sp);
+
+/* The stack frame that the user has specified for commands to act on.
+ Note that one cannot assume this is the address of valid data. */
+
+extern struct frame_info *selected_frame;
+
+/* Level of the selected frame:
+ 0 for innermost, 1 for its caller, ...
+ or -1 for frame specified by address with no defined level. */
+
+extern struct frame_info *create_new_frame (CORE_ADDR, CORE_ADDR);
+
+extern void flush_cached_frames (void);
+
+extern void reinit_frame_cache (void);
+
+
+#ifdef FRAME_FIND_SAVED_REGS
+/* XXX - deprecated */
+#define FRAME_INIT_SAVED_REGS(FI) get_frame_saved_regs (FI, NULL)
+extern void get_frame_saved_regs (struct frame_info *,
+ struct frame_saved_regs *);
+#endif
+
+extern void set_current_frame (struct frame_info *);
+
+extern struct frame_info *get_prev_frame (struct frame_info *);
+
+extern struct frame_info *get_current_frame (void);
+
+extern struct frame_info *get_next_frame (struct frame_info *);
+
+extern struct block *get_frame_block (struct frame_info *,
+ CORE_ADDR *addr_in_block);
+
+extern struct block *get_current_block (CORE_ADDR *addr_in_block);
+
+extern struct block *get_selected_block (CORE_ADDR *addr_in_block);
+
+extern struct symbol *get_frame_function (struct frame_info *);
+
+extern CORE_ADDR get_frame_pc (struct frame_info *);
+
+extern CORE_ADDR get_pc_function_start (CORE_ADDR);
+
+extern struct block *block_for_pc (CORE_ADDR);
+
+extern struct block *block_for_pc_sect (CORE_ADDR, asection *);
+
+extern int frameless_look_for_prologue (struct frame_info *);
+
+extern void print_frame_args (struct symbol *, struct frame_info *,
+ int, struct ui_file *);
+
+extern struct frame_info *find_relative_frame (struct frame_info *, int *);
+
+extern void show_and_print_stack_frame (struct frame_info *fi, int level,
+ int source);
+
+extern void print_stack_frame (struct frame_info *, int, int);
+
+extern void print_only_stack_frame (struct frame_info *, int, int);
+
+extern void show_stack_frame (struct frame_info *);
+
+extern void select_frame (struct frame_info *);
+
+extern void record_selected_frame (CORE_ADDR *, int *);
+
+extern void print_frame_info (struct frame_info *, int, int, int);
+
+extern void show_frame_info (struct frame_info *, int, int, int);
+
+extern CORE_ADDR find_saved_register (struct frame_info *, int);
+
+extern struct frame_info *block_innermost_frame (struct block *);
+
+extern struct frame_info *find_frame_addr_in_frame_chain (CORE_ADDR);
+
+extern CORE_ADDR sigtramp_saved_pc (struct frame_info *);
+
+extern CORE_ADDR generic_read_register_dummy (CORE_ADDR pc,
+ CORE_ADDR fp, int);
+extern void generic_push_dummy_frame (void);
+extern void generic_pop_current_frame (void (*)(struct frame_info *));
+extern void generic_pop_dummy_frame (void);
+
+extern int generic_pc_in_call_dummy (CORE_ADDR pc,
+ CORE_ADDR sp, CORE_ADDR fp);
+extern char *generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp);
+
+extern void generic_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun,
+ int nargs, struct value **args,
+ struct type *type, int gcc_p);
+
+extern void generic_get_saved_register (char *, int *, CORE_ADDR *,
+ struct frame_info *, int,
+ enum lval_type *);
+
+extern void generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi);
+
+extern void get_saved_register (char *raw_buffer, int *optimized,
+ CORE_ADDR * addrp,
+ struct frame_info *frame,
+ int regnum, enum lval_type *lval);
+
+/* Return the register as found on the FRAME. Return zero if the
+ register could not be found. */
+extern int frame_register_read (struct frame_info *frame, int regnum,
+ void *buf);
+
+#endif /* !defined (FRAME_H) */
diff --git a/gdb/gcore.c b/gdb/gcore.c
new file mode 100644
index 00000000000..25d1ed70e24
--- /dev/null
+++ b/gdb/gcore.c
@@ -0,0 +1,508 @@
+/* Generate a core file for the inferior process.
+ Copyright 2001, 2002 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 "defs.h"
+#include "cli/cli-decode.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "elf-bfd.h"
+#include <sys/procfs.h>
+#include "symfile.h"
+#include "objfiles.h"
+
+static char *default_gcore_target (void);
+static enum bfd_architecture default_gcore_arch (void);
+static unsigned long default_gcore_mach (void);
+static int gcore_memory_sections (bfd *);
+
+/* Function: gcore_command
+ Generate a core file from the inferior process. */
+
+static void
+gcore_command (char *args, int from_tty)
+{
+ struct cleanup *old_chain;
+ char *corefilename, corefilename_buffer[40];
+ asection *note_sec = NULL;
+ bfd *obfd;
+ void *note_data = NULL;
+ int note_size = 0;
+
+ /* No use generating a corefile without a target process. */
+ if (!(target_has_execution))
+ noprocess ();
+
+ if (args && *args)
+ corefilename = args;
+ else
+ {
+ /* Default corefile name is "core.PID". */
+ sprintf (corefilename_buffer, "core.%d", PIDGET (inferior_ptid));
+ corefilename = corefilename_buffer;
+ }
+
+ if (info_verbose)
+ fprintf_filtered (gdb_stdout,
+ "Opening corefile '%s' for output.\n", corefilename);
+
+ /* Open the output file. */
+ if (!(obfd = bfd_openw (corefilename, default_gcore_target ())))
+ {
+ error ("Failed to open '%s' for output.", corefilename);
+ }
+
+ /* Need a cleanup that will close the file (FIXME: delete it?). */
+ old_chain = make_cleanup_bfd_close (obfd);
+
+ bfd_set_format (obfd, bfd_core);
+ bfd_set_arch_mach (obfd, default_gcore_arch (), default_gcore_mach ());
+
+ /* An external target method must build the notes section. */
+ note_data = (char *) target_make_corefile_notes (obfd, &note_size);
+
+ /* Create the note section. */
+ if (note_data != NULL && note_size != 0)
+ {
+ if ((note_sec = bfd_make_section_anyway (obfd, "note0")) == NULL)
+ error ("Failed to create 'note' section for corefile: %s",
+ bfd_errmsg (bfd_get_error ()));
+
+ bfd_set_section_vma (obfd, note_sec, 0);
+ bfd_set_section_flags (obfd, note_sec,
+ SEC_HAS_CONTENTS | SEC_READONLY | SEC_ALLOC);
+ bfd_set_section_alignment (obfd, note_sec, 0);
+ bfd_set_section_size (obfd, note_sec, note_size);
+ }
+
+ /* Now create the memory/load sections. */
+ if (gcore_memory_sections (obfd) == 0)
+ error ("gcore: failed to get corefile memory sections from target.");
+
+ /* Write out the contents of the note section. */
+ if (note_data != NULL && note_size != 0)
+ {
+ if (!bfd_set_section_contents (obfd, note_sec, note_data, 0, note_size))
+ {
+ warning ("writing note section (%s)",
+ bfd_errmsg (bfd_get_error ()));
+ }
+ }
+
+ /* Succeeded. */
+ fprintf_filtered (gdb_stdout,
+ "Saved corefile %s\n", corefilename);
+
+ /* Clean-ups will close the output file and free malloc memory. */
+ do_cleanups (old_chain);
+ return;
+}
+
+static unsigned long
+default_gcore_mach (void)
+{
+#if 1 /* See if this even matters... */
+ return 0;
+#else
+#ifdef TARGET_ARCHITECTURE
+ const struct bfd_arch_info * bfdarch = TARGET_ARCHITECTURE;
+
+ if (bfdarch != NULL)
+ return bfdarch->mach;
+#endif /* TARGET_ARCHITECTURE */
+ if (exec_bfd == NULL)
+ error ("Can't find default bfd machine type (need execfile).");
+
+ return bfd_get_mach (exec_bfd);
+#endif /* 1 */
+}
+
+static enum bfd_architecture
+default_gcore_arch (void)
+{
+#ifdef TARGET_ARCHITECTURE
+ const struct bfd_arch_info * bfdarch = TARGET_ARCHITECTURE;
+
+ if (bfdarch != NULL)
+ return bfdarch->arch;
+#endif
+ if (exec_bfd == NULL)
+ error ("Can't find bfd architecture for corefile (need execfile).");
+
+ return bfd_get_arch (exec_bfd);
+}
+
+static char *
+default_gcore_target (void)
+{
+ /* FIXME -- this may only work for ELF targets. */
+ if (exec_bfd == NULL)
+ return NULL;
+ else
+ return bfd_get_target (exec_bfd);
+}
+
+/*
+ * Default method for stack segment (preemptable by target).
+ */
+
+static int (*override_derive_stack_segment) (bfd_vma *, bfd_vma *);
+
+extern void
+preempt_derive_stack_segment (int (*override_func) (bfd_vma *, bfd_vma *))
+{
+ override_derive_stack_segment = override_func;
+}
+
+/* Function: default_derive_stack_segment
+ Derive a reasonable stack segment by unwinding the target stack.
+
+ Returns 0 for failure, 1 for success. */
+
+static int
+default_derive_stack_segment (bfd_vma *bottom, bfd_vma *top)
+{
+ bfd_vma tmp_vma;
+ struct frame_info *fi, *tmp_fi;
+
+ if (bottom == NULL || top == NULL)
+ return 0; /* Paranoia. */
+
+ if (!target_has_stack || !target_has_registers)
+ return 0; /* Can't succeed without stack and registers. */
+
+ if ((fi = get_current_frame ()) == NULL)
+ return 0; /* Can't succeed without current frame. */
+
+ /* Save frame pointer of TOS frame. */
+ *top = fi->frame;
+ /* If current stack pointer is more "inner", use that instead. */
+ if (INNER_THAN (read_sp (), *top))
+ *top = read_sp ();
+
+ /* Find prev-most frame. */
+ while ((tmp_fi = get_prev_frame (fi)) != NULL)
+ fi = tmp_fi;
+
+ /* Save frame pointer of prev-most frame. */
+ *bottom = fi->frame;
+
+ /* Now canonicalize their order, so that 'bottom' is a lower address
+ (as opposed to a lower stack frame). */
+ if (*bottom > *top)
+ {
+ tmp_vma = *top;
+ *top = *bottom;
+ *bottom = tmp_vma;
+ }
+
+ return 1; /* success */
+}
+
+static int
+derive_stack_segment (bfd_vma *bottom, bfd_vma *top)
+{
+ if (override_derive_stack_segment)
+ return override_derive_stack_segment (bottom, top);
+ else
+ return default_derive_stack_segment (bottom, top);
+}
+
+/*
+ * Default method for heap segment (preemptable by target).
+ */
+
+static int (*override_derive_heap_segment) (bfd *, bfd_vma *, bfd_vma *);
+
+extern void
+preempt_derive_heap_segment (int (*override_func) (bfd *,
+ bfd_vma *, bfd_vma *))
+{
+ override_derive_heap_segment = override_func;
+}
+
+/* Function: default_derive_heap_segment
+ Derive a reasonable heap segment by looking at sbrk and
+ the static data sections.
+
+ Returns 0 for failure, 1 for success. */
+
+static int
+default_derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
+{
+ bfd_vma top_of_data_memory = 0;
+ bfd_vma top_of_heap = 0;
+ bfd_size_type sec_size;
+ struct value *zero, *sbrk;
+ bfd_vma sec_vaddr;
+ asection *sec;
+
+ if (bottom == NULL || top == NULL)
+ return 0; /* Paranoia. */
+
+ if (!target_has_execution)
+ return 0; /* This function depends on being able
+ to call a function in the inferior. */
+
+ /* Assumption: link map is arranged as follows (low to high addresses):
+ text sections
+ data sections (including bss)
+ heap
+ */
+
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ if (bfd_get_section_flags (abfd, sec) & SEC_DATA ||
+ strcmp (".bss", bfd_section_name (abfd, sec)) == 0)
+ {
+ sec_vaddr = bfd_get_section_vma (abfd, sec);
+ sec_size = bfd_get_section_size_before_reloc (sec);
+ if (sec_vaddr + sec_size > top_of_data_memory)
+ top_of_data_memory = sec_vaddr + sec_size;
+ }
+ }
+ /* Now get the top-of-heap by calling sbrk in the inferior. */
+ if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL)
+ {
+ if ((sbrk = find_function_in_inferior ("sbrk")) == NULL)
+ return 0;
+ }
+ else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL)
+ {
+ if ((sbrk = find_function_in_inferior ("_sbrk")) == NULL)
+ return 0;
+ }
+ else
+ return 0;
+
+ if ((zero = value_from_longest (builtin_type_int, (LONGEST) 0)) == NULL)
+ return 0;
+ if ((sbrk = call_function_by_hand (sbrk, 1, &zero)) == NULL)
+ return 0;
+ top_of_heap = value_as_long (sbrk);
+
+ /* Return results. */
+ if (top_of_heap > top_of_data_memory)
+ {
+ *bottom = top_of_data_memory;
+ *top = top_of_heap;
+ return 1; /* success */
+ }
+ else
+ return 0; /* No additional heap space needs to be saved. */
+}
+
+static int
+derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
+{
+ if (override_derive_heap_segment)
+ return override_derive_heap_segment (abfd, bottom, top);
+ else
+ return default_derive_heap_segment (abfd, bottom, top);
+}
+
+/* ARGSUSED */
+static void
+make_output_phdrs (bfd *obfd, asection *osec, void *ignored)
+{
+ int p_flags = 0;
+ int p_type;
+
+ /* FIXME: these constants may only be applicable for ELF. */
+ if (strncmp (bfd_section_name (obfd, osec), "load", 4) == 0)
+ p_type = PT_LOAD;
+ else
+ p_type = PT_NOTE;
+
+ p_flags |= PF_R; /* Segment is readable. */
+ if (!(bfd_get_section_flags (obfd, osec) & SEC_READONLY))
+ p_flags |= PF_W; /* Segment is writable. */
+ if (bfd_get_section_flags (obfd, osec) & SEC_CODE)
+ p_flags |= PF_X; /* Segment is executable. */
+
+ bfd_record_phdr (obfd, p_type, 1, p_flags, 0, 0,
+ 0, 0, 1, &osec);
+}
+
+static asection *
+make_mem_sec (bfd *obfd,
+ bfd_vma addr,
+ bfd_size_type size,
+ unsigned int flags,
+ unsigned int alignment)
+{
+ asection *osec;
+
+ if ((osec = bfd_make_section_anyway (obfd, "load")) == NULL)
+ {
+ warning ("Couldn't make gcore segment: %s",
+ bfd_errmsg (bfd_get_error ()));
+ return NULL;
+ }
+
+ if (info_verbose)
+ {
+ fprintf_filtered (gdb_stdout,
+ "Save segment, %lld bytes at 0x%s\n",
+ (long long) size, paddr_nz (addr));
+ }
+
+ bfd_set_section_size (obfd, osec, size);
+ bfd_set_section_vma (obfd, osec, addr);
+ osec->lma = 0; /* FIXME: there should be a macro for this! */
+ bfd_set_section_alignment (obfd, osec, alignment);
+ bfd_set_section_flags (obfd, osec,
+ flags | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS);
+ return osec;
+}
+
+static int
+gcore_create_callback (CORE_ADDR vaddr,
+ unsigned long size,
+ int read, int write, int exec,
+ void *data)
+{
+ flagword flags = 0;
+
+ if (write == 0)
+ {
+ flags |= SEC_READONLY;
+ /* Set size == zero for readonly sections. */
+ size = 0;
+ }
+ if (exec)
+ {
+ flags |= SEC_CODE;
+ }
+ else
+ {
+ flags |= SEC_DATA;
+ }
+
+ return ((make_mem_sec ((bfd *) data, vaddr, size, flags, 0)) == NULL);
+}
+
+static int
+objfile_find_memory_regions (int (*func) (CORE_ADDR,
+ unsigned long,
+ int, int, int,
+ void *),
+ void *obfd)
+{
+ /* Use objfile data to create memory sections. */
+ struct objfile *objfile;
+ struct obj_section *objsec;
+ bfd_vma temp_bottom, temp_top;
+
+ /* Call callback function for each objfile section. */
+ ALL_OBJSECTIONS (objfile, objsec)
+ {
+ bfd *ibfd = objfile->obfd;
+ asection *isec = objsec->the_bfd_section;
+ flagword flags = bfd_get_section_flags (ibfd, isec);
+ int ret;
+
+ if ((flags & SEC_ALLOC) || (flags & SEC_LOAD))
+ {
+ int size = bfd_section_size (ibfd, isec);
+ int ret;
+
+ if ((ret = (*func) (objsec->addr,
+ bfd_section_size (ibfd, isec),
+ 1, /* All sections will be readable. */
+ (flags & SEC_READONLY) == 0, /* writable */
+ (flags & SEC_CODE) != 0, /* executable */
+ obfd)) != 0)
+ return ret;
+ }
+ }
+
+ /* Make a stack segment. */
+ if (derive_stack_segment (&temp_bottom, &temp_top))
+ (*func) (temp_bottom,
+ temp_top - temp_bottom,
+ 1, /* Stack section will be readable */
+ 1, /* Stack section will be writable */
+ 0, /* Stack section will not be executable */
+ obfd);
+
+ /* Make a heap segment. */
+ if (derive_heap_segment (exec_bfd, &temp_bottom, &temp_top))
+ (*func) (temp_bottom,
+ temp_top - temp_bottom,
+ 1, /* Heap section will be readable */
+ 1, /* Heap section will be writable */
+ 0, /* Heap section will not be executable */
+ obfd);
+ return 0;
+}
+
+static void
+gcore_copy_callback (bfd *obfd, asection *osec, void *ignored)
+{
+ bfd_size_type size = bfd_section_size (obfd, osec);
+ struct cleanup *old_chain = NULL;
+ void *memhunk;
+
+ if (size == 0)
+ return; /* Read-only sections are marked as zero-size.
+ We don't have to copy their contents. */
+ if (strncmp ("load", bfd_section_name (obfd, osec), 4) != 0)
+ return; /* Only interested in "load" sections. */
+
+ if ((memhunk = xmalloc (size)) == NULL)
+ error ("Not enough memory to create corefile.");
+ old_chain = make_cleanup (xfree, memhunk);
+
+ if (target_read_memory (bfd_section_vma (obfd, osec),
+ memhunk, size) != 0)
+ warning ("Memory read failed for corefile section, %ld bytes at 0x%s\n",
+ (long) size, paddr (bfd_section_vma (obfd, osec)));
+ if (!bfd_set_section_contents (obfd, osec, memhunk, 0, size))
+ warning ("Failed to write corefile contents (%s).",
+ bfd_errmsg (bfd_get_error ()));
+
+ do_cleanups (old_chain); /* frees the xmalloc buffer */
+}
+
+static int
+gcore_memory_sections (bfd *obfd)
+{
+ if (target_find_memory_regions (gcore_create_callback, obfd) != 0)
+ return 0; /* FIXME error return/msg? */
+
+ /* Record phdrs for section-to-segment mapping. */
+ bfd_map_over_sections (obfd, make_output_phdrs, NULL);
+
+ /* Copy memory region contents. */
+ bfd_map_over_sections (obfd, gcore_copy_callback, NULL);
+
+ return 1; /* success */
+}
+
+void
+_initialize_gcore (void)
+{
+ add_com ("generate-core-file", class_files, gcore_command,
+ "Save a core file with the current state of the debugged process.\n\
+Argument is optional filename. Default filename is 'core.<process_id>'.");
+
+ add_com_alias ("gcore", "generate-core-file", class_files, 1);
+ exec_set_find_memory_regions (objfile_find_memory_regions);
+}
diff --git a/gdb/gdb-events.c b/gdb/gdb-events.c
new file mode 100644
index 00000000000..ada30a3ef5a
--- /dev/null
+++ b/gdb/gdb-events.c
@@ -0,0 +1,351 @@
+/* User Interface Events.
+
+ Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Solutions.
+
+ 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. */
+
+/* Work in progress */
+
+/* This file was created with the aid of ``gdb-events.sh''.
+
+ The bourn shell script ``gdb-events.sh'' creates the files
+ ``new-gdb-events.c'' and ``new-gdb-events.h and then compares
+ them against the existing ``gdb-events.[hc]''. Any differences
+ found being reported.
+
+ If editing this file, please also run gdb-events.sh and merge any
+ changes into that script. Conversely, when making sweeping changes
+ to this file, modifying gdb-events.sh and using its output may
+ prove easier. */
+
+
+#include "defs.h"
+#include "gdb-events.h"
+#include "gdbcmd.h"
+
+#if WITH_GDB_EVENTS
+static struct gdb_events null_event_hooks;
+static struct gdb_events queue_event_hooks;
+static struct gdb_events *current_event_hooks = &null_event_hooks;
+#endif
+
+int gdb_events_debug;
+
+#if WITH_GDB_EVENTS
+
+void
+breakpoint_create_event (int b)
+{
+ if (gdb_events_debug)
+ fprintf_unfiltered (gdb_stdlog, "breakpoint_create_event\n");
+ if (!current_event_hooks->breakpoint_create)
+ return;
+ current_event_hooks->breakpoint_create (b);
+}
+
+void
+breakpoint_delete_event (int b)
+{
+ if (gdb_events_debug)
+ fprintf_unfiltered (gdb_stdlog, "breakpoint_delete_event\n");
+ if (!current_event_hooks->breakpoint_delete)
+ return;
+ current_event_hooks->breakpoint_delete (b);
+}
+
+void
+breakpoint_modify_event (int b)
+{
+ if (gdb_events_debug)
+ fprintf_unfiltered (gdb_stdlog, "breakpoint_modify_event\n");
+ if (!current_event_hooks->breakpoint_modify)
+ return;
+ current_event_hooks->breakpoint_modify (b);
+}
+
+void
+tracepoint_create_event (int number)
+{
+ if (gdb_events_debug)
+ fprintf_unfiltered (gdb_stdlog, "tracepoint_create_event\n");
+ if (!current_event_hooks->tracepoint_create)
+ return;
+ current_event_hooks->tracepoint_create (number);
+}
+
+void
+tracepoint_delete_event (int number)
+{
+ if (gdb_events_debug)
+ fprintf_unfiltered (gdb_stdlog, "tracepoint_delete_event\n");
+ if (!current_event_hooks->tracepoint_delete)
+ return;
+ current_event_hooks->tracepoint_delete (number);
+}
+
+void
+tracepoint_modify_event (int number)
+{
+ if (gdb_events_debug)
+ fprintf_unfiltered (gdb_stdlog, "tracepoint_modify_event\n");
+ if (!current_event_hooks->tracepoint_modify)
+ return;
+ current_event_hooks->tracepoint_modify (number);
+}
+
+void
+architecture_changed_event (void)
+{
+ if (gdb_events_debug)
+ fprintf_unfiltered (gdb_stdlog, "architecture_changed_event\n");
+ if (!current_event_hooks->architecture_changed)
+ return;
+ current_event_hooks->architecture_changed ();
+}
+
+#endif
+
+#if WITH_GDB_EVENTS
+struct gdb_events *
+set_gdb_event_hooks (struct gdb_events *vector)
+{
+ struct gdb_events *old_events = current_event_hooks;
+ if (vector == NULL)
+ current_event_hooks = &queue_event_hooks;
+ else
+ current_event_hooks = vector;
+ return old_events;
+}
+#endif
+
+enum gdb_event
+{
+ breakpoint_create,
+ breakpoint_delete,
+ breakpoint_modify,
+ tracepoint_create,
+ tracepoint_delete,
+ tracepoint_modify,
+ architecture_changed,
+ nr_gdb_events
+};
+
+struct breakpoint_create
+ {
+ int b;
+ };
+
+struct breakpoint_delete
+ {
+ int b;
+ };
+
+struct breakpoint_modify
+ {
+ int b;
+ };
+
+struct tracepoint_create
+ {
+ int number;
+ };
+
+struct tracepoint_delete
+ {
+ int number;
+ };
+
+struct tracepoint_modify
+ {
+ int number;
+ };
+
+struct event
+ {
+ enum gdb_event type;
+ struct event *next;
+ union
+ {
+ struct breakpoint_create breakpoint_create;
+ struct breakpoint_delete breakpoint_delete;
+ struct breakpoint_modify breakpoint_modify;
+ struct tracepoint_create tracepoint_create;
+ struct tracepoint_delete tracepoint_delete;
+ struct tracepoint_modify tracepoint_modify;
+ }
+ data;
+ };
+struct event *pending_events;
+struct event *delivering_events;
+
+static void
+append (struct event *new_event)
+{
+ struct event **event = &pending_events;
+ while ((*event) != NULL)
+ event = &((*event)->next);
+ (*event) = new_event;
+ (*event)->next = NULL;
+}
+
+static void
+queue_breakpoint_create (int b)
+{
+ struct event *event = XMALLOC (struct event);
+ event->type = breakpoint_create;
+ event->data.breakpoint_create.b = b;
+ append (event);
+}
+
+static void
+queue_breakpoint_delete (int b)
+{
+ struct event *event = XMALLOC (struct event);
+ event->type = breakpoint_delete;
+ event->data.breakpoint_delete.b = b;
+ append (event);
+}
+
+static void
+queue_breakpoint_modify (int b)
+{
+ struct event *event = XMALLOC (struct event);
+ event->type = breakpoint_modify;
+ event->data.breakpoint_modify.b = b;
+ append (event);
+}
+
+static void
+queue_tracepoint_create (int number)
+{
+ struct event *event = XMALLOC (struct event);
+ event->type = tracepoint_create;
+ event->data.tracepoint_create.number = number;
+ append (event);
+}
+
+static void
+queue_tracepoint_delete (int number)
+{
+ struct event *event = XMALLOC (struct event);
+ event->type = tracepoint_delete;
+ event->data.tracepoint_delete.number = number;
+ append (event);
+}
+
+static void
+queue_tracepoint_modify (int number)
+{
+ struct event *event = XMALLOC (struct event);
+ event->type = tracepoint_modify;
+ event->data.tracepoint_modify.number = number;
+ append (event);
+}
+
+static void
+queue_architecture_changed (void)
+{
+ struct event *event = XMALLOC (struct event);
+ event->type = architecture_changed;
+ append (event);
+}
+
+void
+gdb_events_deliver (struct gdb_events *vector)
+{
+ /* Just zap any events left around from last time. */
+ while (delivering_events != NULL)
+ {
+ struct event *event = delivering_events;
+ delivering_events = event->next;
+ xfree (event);
+ }
+ /* Process any pending events. Because one of the deliveries could
+ bail out we move everything off of the pending queue onto an
+ in-progress queue where it can, later, be cleaned up if
+ necessary. */
+ delivering_events = pending_events;
+ pending_events = NULL;
+ while (delivering_events != NULL)
+ {
+ struct event *event = delivering_events;
+ switch (event->type)
+ {
+ case breakpoint_create:
+ vector->breakpoint_create
+ (event->data.breakpoint_create.b);
+ break;
+ case breakpoint_delete:
+ vector->breakpoint_delete
+ (event->data.breakpoint_delete.b);
+ break;
+ case breakpoint_modify:
+ vector->breakpoint_modify
+ (event->data.breakpoint_modify.b);
+ break;
+ case tracepoint_create:
+ vector->tracepoint_create
+ (event->data.tracepoint_create.number);
+ break;
+ case tracepoint_delete:
+ vector->tracepoint_delete
+ (event->data.tracepoint_delete.number);
+ break;
+ case tracepoint_modify:
+ vector->tracepoint_modify
+ (event->data.tracepoint_modify.number);
+ break;
+ case architecture_changed:
+ vector->architecture_changed ();
+ break;
+ }
+ delivering_events = event->next;
+ xfree (event);
+ }
+}
+
+void _initialize_gdb_events (void);
+void
+_initialize_gdb_events (void)
+{
+ struct cmd_list_element *c;
+#if WITH_GDB_EVENTS
+ queue_event_hooks.breakpoint_create = queue_breakpoint_create;
+ queue_event_hooks.breakpoint_delete = queue_breakpoint_delete;
+ queue_event_hooks.breakpoint_modify = queue_breakpoint_modify;
+ queue_event_hooks.tracepoint_create = queue_tracepoint_create;
+ queue_event_hooks.tracepoint_delete = queue_tracepoint_delete;
+ queue_event_hooks.tracepoint_modify = queue_tracepoint_modify;
+ queue_event_hooks.architecture_changed = queue_architecture_changed;
+#endif
+
+ c = add_set_cmd ("eventdebug", class_maintenance, var_zinteger,
+ (char *) (&gdb_events_debug), "Set event debugging.\n\
+When non-zero, event/notify debugging is enabled.", &setlist);
+ deprecate_cmd (c, "set debug event");
+ deprecate_cmd (add_show_from_set (c, &showlist), "show debug event");
+
+ add_show_from_set (add_set_cmd ("event",
+ class_maintenance,
+ var_zinteger,
+ (char *) (&gdb_events_debug),
+ "Set event debugging.\n\
+When non-zero, event/notify debugging is enabled.", &setdebuglist),
+ &showdebuglist);
+}
diff --git a/gdb/gdb-events.h b/gdb/gdb-events.h
new file mode 100644
index 00000000000..5f7fc6b5a55
--- /dev/null
+++ b/gdb/gdb-events.h
@@ -0,0 +1,114 @@
+/* User Interface Events.
+
+ Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Solutions.
+
+ 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. */
+
+/* Work in progress */
+
+/* This file was created with the aid of ``gdb-events.sh''.
+
+ The bourn shell script ``gdb-events.sh'' creates the files
+ ``new-gdb-events.c'' and ``new-gdb-events.h and then compares
+ them against the existing ``gdb-events.[hc]''. Any differences
+ found being reported.
+
+ If editing this file, please also run gdb-events.sh and merge any
+ changes into that script. Conversely, when making sweeping changes
+ to this file, modifying gdb-events.sh and using its output may
+ prove easier. */
+
+
+#ifndef GDB_EVENTS_H
+#define GDB_EVENTS_H
+
+#ifndef WITH_GDB_EVENTS
+#define WITH_GDB_EVENTS 1
+#endif
+
+
+/* COMPAT: pointer variables for old, unconverted events.
+ A call to set_gdb_events() will automatically update these. */
+
+
+
+/* Type definition of all hook functions.
+ Recommended pratice is to first declare each hook function using
+ the below ftype and then define it. */
+
+typedef void (gdb_events_breakpoint_create_ftype) (int b);
+typedef void (gdb_events_breakpoint_delete_ftype) (int b);
+typedef void (gdb_events_breakpoint_modify_ftype) (int b);
+typedef void (gdb_events_tracepoint_create_ftype) (int number);
+typedef void (gdb_events_tracepoint_delete_ftype) (int number);
+typedef void (gdb_events_tracepoint_modify_ftype) (int number);
+typedef void (gdb_events_architecture_changed_ftype) (void);
+
+
+/* gdb-events: object. */
+
+struct gdb_events
+ {
+ gdb_events_breakpoint_create_ftype *breakpoint_create;
+ gdb_events_breakpoint_delete_ftype *breakpoint_delete;
+ gdb_events_breakpoint_modify_ftype *breakpoint_modify;
+ gdb_events_tracepoint_create_ftype *tracepoint_create;
+ gdb_events_tracepoint_delete_ftype *tracepoint_delete;
+ gdb_events_tracepoint_modify_ftype *tracepoint_modify;
+ gdb_events_architecture_changed_ftype *architecture_changed;
+ };
+
+
+/* Interface into events functions.
+ Where a *_p() predicate is present, it must be called before
+ calling the hook proper. */
+extern void breakpoint_create_event (int b);
+extern void breakpoint_delete_event (int b);
+extern void breakpoint_modify_event (int b);
+extern void tracepoint_create_event (int number);
+extern void tracepoint_delete_event (int number);
+extern void tracepoint_modify_event (int number);
+extern void architecture_changed_event (void);
+
+
+/* When GDB_EVENTS are not being used, completly disable them. */
+
+#if !WITH_GDB_EVENTS
+#define breakpoint_create_event(b) 0
+#define breakpoint_delete_event(b) 0
+#define breakpoint_modify_event(b) 0
+#define tracepoint_create_event(number) 0
+#define tracepoint_delete_event(number) 0
+#define tracepoint_modify_event(number) 0
+#define architecture_changed_event() 0
+#endif
+
+/* Install custom gdb-events hooks. */
+extern struct gdb_events *set_gdb_event_hooks (struct gdb_events *vector);
+
+/* Deliver any pending events. */
+extern void gdb_events_deliver (struct gdb_events *vector);
+
+#if !WITH_GDB_EVENTS
+#define set_gdb_events(x) 0
+#define set_gdb_event_hooks(x) 0
+#define gdb_events_deliver(x) 0
+#endif
+
+#endif
diff --git a/gdb/gdb-events.sh b/gdb/gdb-events.sh
new file mode 100755
index 00000000000..9965f05577f
--- /dev/null
+++ b/gdb/gdb-events.sh
@@ -0,0 +1,605 @@
+#!/bin/sh
+
+# User Interface Events.
+# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+#
+# Contributed by Cygnus Solutions.
+#
+# 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.
+
+#
+# What happens next:
+#
+
+# The gdb-events.h/gdb-events.c files this script generates are commited
+# and published.
+
+# Any UI module that is installing events is changed so that the
+# events are installed using the ``set_gdb_events()'' and
+# ``gdb_event_hooks()'' interfaces. There could prove to be an issue
+# here with respect to annotate. We might need to accomodate a hook
+# stack that allows several ui blocks to install their own events.
+
+# Each of the variable events (as currently generated) is converted
+# to either a straight function call or a function call with a
+# predicate.
+
+
+IFS=:
+
+read="class returntype function formal actual attrib"
+
+function_list ()
+{
+ # category:
+ # # -> disable
+ # * -> compatibility - pointer variable that is initialized
+ # by set_gdb_events().
+ # ? -> Predicate and function proper.
+ # f -> always call (must have a void returntype)
+ # return-type
+ # name
+ # formal argument list
+ # actual argument list
+ # attributes
+ # description
+ cat <<EOF |
+f:void:breakpoint_create:int b:b
+f:void:breakpoint_delete:int b:b
+f:void:breakpoint_modify:int b:b
+f:void:tracepoint_create:int number:number
+f:void:tracepoint_delete:int number:number
+f:void:tracepoint_modify:int number:number
+f:void:architecture_changed:void
+#*:void:annotate_starting_hook:void
+#*:void:annotate_stopped_hook:void
+#*:void:annotate_signalled_hook:void
+#*:void:annotate_signal_hook:void
+#*:void:annotate_exited_hook:void
+##*:void:print_register_hook:int
+##*:CORE_ADDR:find_toc_address_hook:CORE_ADDR
+##*:void:sparc_print_register_hook:int regno:regno
+#*:void:target_resume_hook:void
+#*:void:target_wait_loop_hook:void
+#*:void:init_gdb_hook:char *argv0:argv0
+#*:void:command_loop_hook:void
+#*:void:fputs_unfiltered_hook:const char *linebuff,struct ui_file *stream:linebuff, stream
+#*:void:print_frame_info_listing_hook:struct symtab *s, int line, int stopline, int noerror:s, line, stopline, noerror
+#*:int:query_hook:const char *query, va_list args:query, args
+#*:void:warning_hook:const char *string, va_list args:string, args
+#*:void:target_output_hook:char *b:b
+#*:void:interactive_hook:void
+#*:void:registers_changed_hook:void
+#*:void:readline_begin_hook:char *format, ...:format
+#*:char *:readline_hook:char *prompt:prompt
+#*:void:readline_end_hook:void
+#*:void:register_changed_hook:int regno:regno
+#*:void:memory_changed_hook:CORE_ADDR addr, int len:addr, len
+#*:void:context_hook:int num:num
+#*:int:target_wait_hook:int pid, struct target_waitstatus *status:pid, status
+#*:void:call_command_hook:struct cmd_list_element *c, char *cmd, int from_tty:c, cmd, from_tty
+#*:NORETURN void:error_hook:void:: ATTR_NORETURN
+#*:void:error_begin_hook:void
+##*:int:target_architecture_hook:const struct bfd_arch_info *
+#*:void:exec_file_display_hook:char *filename:filename
+#*:void:file_changed_hook:char *filename:filename
+##*:void:specify_exec_file_hook:
+#*:int:gdb_load_progress_hook:char *section, unsigned long num:section, num
+#*:void:pre_add_symbol_hook:char *name:name
+#*:void:post_add_symbol_hook:void
+#*:void:selected_frame_level_changed_hook:int level:level
+#*:int:gdb_loop_hook:int signo:signo
+##*:void:solib_create_inferior_hook:void
+##*:void:xcoff_relocate_symtab_hook:unsigned int
+EOF
+ grep -v '^#'
+}
+
+copyright ()
+{
+ cat <<EOF
+/* User Interface Events.
+
+ Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Solutions.
+
+ 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. */
+
+/* Work in progress */
+
+/* This file was created with the aid of \`\`gdb-events.sh''.
+
+ The bourn shell script \`\`gdb-events.sh'' creates the files
+ \`\`new-gdb-events.c'' and \`\`new-gdb-events.h and then compares
+ them against the existing \`\`gdb-events.[hc]''. Any differences
+ found being reported.
+
+ If editing this file, please also run gdb-events.sh and merge any
+ changes into that script. Conversely, when making sweeping changes
+ to this file, modifying gdb-events.sh and using its output may
+ prove easier. */
+
+EOF
+}
+
+#
+# The .h file
+#
+
+exec > new-gdb-events.h
+copyright
+cat <<EOF
+
+#ifndef GDB_EVENTS_H
+#define GDB_EVENTS_H
+
+#ifndef WITH_GDB_EVENTS
+#define WITH_GDB_EVENTS 1
+#endif
+EOF
+
+# pointer declarations
+echo ""
+echo ""
+cat <<EOF
+/* COMPAT: pointer variables for old, unconverted events.
+ A call to set_gdb_events() will automatically update these. */
+EOF
+echo ""
+function_list | while eval read $read
+do
+ case "${class}" in
+ "*" )
+ echo "extern ${returntype} (*${function}_event) (${formal})${attrib};"
+ ;;
+ esac
+done
+
+# function typedef's
+echo ""
+echo ""
+cat <<EOF
+/* Type definition of all hook functions.
+ Recommended pratice is to first declare each hook function using
+ the below ftype and then define it. */
+EOF
+echo ""
+function_list | while eval read $read
+do
+ echo "typedef ${returntype} (gdb_events_${function}_ftype) (${formal});"
+done
+
+# gdb_events object
+echo ""
+echo ""
+cat <<EOF
+/* gdb-events: object. */
+EOF
+echo ""
+echo "struct gdb_events"
+echo " {"
+function_list | while eval read $read
+do
+ echo " gdb_events_${function}_ftype *${function}${attrib};"
+done
+echo " };"
+
+# function declarations
+echo ""
+echo ""
+cat <<EOF
+/* Interface into events functions.
+ Where a *_p() predicate is present, it must be called before
+ calling the hook proper. */
+EOF
+function_list | while eval read $read
+do
+ case "${class}" in
+ "*" ) continue ;;
+ "?" )
+ echo "extern int ${function}_p (void);"
+ echo "extern ${returntype} ${function}_event (${formal})${attrib};"
+ ;;
+ "f" )
+ echo "extern ${returntype} ${function}_event (${formal})${attrib};"
+ ;;
+ esac
+done
+
+# function macros
+echo ""
+echo ""
+cat <<EOF
+/* When GDB_EVENTS are not being used, completly disable them. */
+EOF
+echo ""
+echo "#if !WITH_GDB_EVENTS"
+function_list | while eval read $read
+do
+ case "${class}" in
+ "*" ) continue ;;
+ "?" )
+ echo "#define ${function}_event_p() 0"
+ echo "#define ${function}_event(${actual}) 0"
+ ;;
+ "f" )
+ echo "#define ${function}_event(${actual}) 0"
+ ;;
+ esac
+done
+echo "#endif"
+
+# our set function
+cat <<EOF
+
+/* Install custom gdb-events hooks. */
+extern struct gdb_events *set_gdb_event_hooks (struct gdb_events *vector);
+
+/* Deliver any pending events. */
+extern void gdb_events_deliver (struct gdb_events *vector);
+
+#if !WITH_GDB_EVENTS
+#define set_gdb_events(x) 0
+#define set_gdb_event_hooks(x) 0
+#define gdb_events_deliver(x) 0
+#endif
+EOF
+
+# close it off
+echo ""
+echo "#endif"
+exec 1>&2
+#../move-if-change new-gdb-events.h gdb-events.h
+if test -r gdb-events.h
+then
+ diff -c gdb-events.h new-gdb-events.h
+ if [ $? = 1 ]
+ then
+ echo "gdb-events.h changed? cp new-gdb-events.h gdb-events.h" 1>&2
+ fi
+else
+ echo "File missing? mv new-gdb-events.h gdb-events.h" 1>&2
+fi
+
+
+
+#
+# C file
+#
+
+exec > new-gdb-events.c
+copyright
+cat <<EOF
+
+#include "defs.h"
+#include "gdb-events.h"
+#include "gdbcmd.h"
+
+#if WITH_GDB_EVENTS
+static struct gdb_events null_event_hooks;
+static struct gdb_events queue_event_hooks;
+static struct gdb_events *current_event_hooks = &null_event_hooks;
+#endif
+
+int gdb_events_debug;
+EOF
+
+# global pointer variables - always have this
+#echo ""
+#function_list | while eval read $read
+#do
+# case "${class}" in
+# "*" )
+# echo "${returntype} (*${function}_event) (${formal})${attrib} = 0;"
+# ;;
+# esac
+#done
+
+# function bodies
+echo ""
+echo "#if WITH_GDB_EVENTS"
+function_list | while eval read $read
+do
+ case "${class}" in
+ "*" ) continue ;;
+ "?" )
+cat <<EOF
+
+int
+${function}_event_p (${formal})
+{
+ return current_event_hooks->${function};
+}
+
+${returntype}
+${function}_event (${formal})
+{
+ return current_events->${function} (${actual});
+}
+EOF
+ ;;
+ "f" )
+cat <<EOF
+
+void
+${function}_event (${formal})
+{
+ if (gdb_events_debug)
+ fprintf_unfiltered (gdb_stdlog, "${function}_event\n");
+ if (!current_event_hooks->${function})
+ return;
+ current_event_hooks->${function} (${actual});
+}
+EOF
+ ;;
+ esac
+done
+echo ""
+echo "#endif"
+
+# Set hooks function
+echo ""
+cat <<EOF
+#if WITH_GDB_EVENTS
+struct gdb_events *
+set_gdb_event_hooks (struct gdb_events *vector)
+{
+ struct gdb_events *old_events = current_event_hooks;
+ if (vector == NULL)
+ current_event_hooks = &queue_event_hooks;
+ else
+ current_event_hooks = vector;
+ return old_events;
+EOF
+function_list | while eval read $read
+do
+ case "${class}" in
+ "*" )
+ echo " ${function}_event = hooks->${function};"
+ ;;
+ esac
+done
+cat <<EOF
+}
+#endif
+EOF
+
+# event type
+echo ""
+cat <<EOF
+enum gdb_event
+{
+EOF
+function_list | while eval read $read
+do
+ case "${class}" in
+ "f" )
+ echo " ${function},"
+ ;;
+ esac
+done
+cat <<EOF
+ nr_gdb_events
+};
+EOF
+
+# event data
+echo ""
+function_list | while eval read $read
+do
+ case "${class}" in
+ "f" )
+ if test ${actual}
+ then
+ echo "struct ${function}"
+ echo " {"
+ echo " `echo ${formal} | tr '[,]' '[;]'`;"
+ echo " };"
+ echo ""
+ fi
+ ;;
+ esac
+done
+
+# event queue
+cat <<EOF
+struct event
+ {
+ enum gdb_event type;
+ struct event *next;
+ union
+ {
+EOF
+function_list | while eval read $read
+do
+ case "${class}" in
+ "f" )
+ if test ${actual}
+ then
+ echo " struct ${function} ${function};"
+ fi
+ ;;
+ esac
+done
+cat <<EOF
+ }
+ data;
+ };
+struct event *pending_events;
+struct event *delivering_events;
+EOF
+
+# append
+echo ""
+cat <<EOF
+static void
+append (struct event *new_event)
+{
+ struct event **event = &pending_events;
+ while ((*event) != NULL)
+ event = &((*event)->next);
+ (*event) = new_event;
+ (*event)->next = NULL;
+}
+EOF
+
+# schedule a given event
+function_list | while eval read $read
+do
+ case "${class}" in
+ "f" )
+ echo ""
+ echo "static void"
+ echo "queue_${function} (${formal})"
+ echo "{"
+ echo " struct event *event = XMALLOC (struct event);"
+ echo " event->type = ${function};"
+ for arg in `echo ${actual} | tr '[,]' '[:]' | tr -d '[ ]'`; do
+ echo " event->data.${function}.${arg} = ${arg};"
+ done
+ echo " append (event);"
+ echo "}"
+ ;;
+ esac
+done
+
+# deliver
+echo ""
+cat <<EOF
+void
+gdb_events_deliver (struct gdb_events *vector)
+{
+ /* Just zap any events left around from last time. */
+ while (delivering_events != NULL)
+ {
+ struct event *event = delivering_events;
+ delivering_events = event->next;
+ xfree (event);
+ }
+ /* Process any pending events. Because one of the deliveries could
+ bail out we move everything off of the pending queue onto an
+ in-progress queue where it can, later, be cleaned up if
+ necessary. */
+ delivering_events = pending_events;
+ pending_events = NULL;
+ while (delivering_events != NULL)
+ {
+ struct event *event = delivering_events;
+ switch (event->type)
+ {
+EOF
+function_list | while eval read $read
+do
+ case "${class}" in
+ "f" )
+ echo " case ${function}:"
+ if test ${actual}
+ then
+ echo " vector->${function}"
+ sep=" ("
+ ass=""
+ for arg in `echo ${actual} | tr '[,]' '[:]' | tr -d '[ ]'`; do
+ ass="${ass}${sep}event->data.${function}.${arg}"
+ sep=",
+ "
+ done
+ echo "${ass});"
+ else
+ echo " vector->${function} ();"
+ fi
+ echo " break;"
+ ;;
+ esac
+done
+cat <<EOF
+ }
+ delivering_events = event->next;
+ xfree (event);
+ }
+}
+EOF
+
+# Finally the initialization
+echo ""
+cat <<EOF
+void _initialize_gdb_events (void);
+void
+_initialize_gdb_events (void)
+{
+ struct cmd_list_element *c;
+#if WITH_GDB_EVENTS
+EOF
+function_list | while eval read $read
+do
+ case "${class}" in
+ "f" )
+ echo " queue_event_hooks.${function} = queue_${function};"
+ ;;
+ esac
+done
+cat <<EOF
+#endif
+
+ c = add_set_cmd ("eventdebug", class_maintenance, var_zinteger,
+ (char *) (&gdb_events_debug), "Set event debugging.\n\\
+When non-zero, event/notify debugging is enabled.", &setlist);
+ deprecate_cmd (c, "set debug event");
+ deprecate_cmd (add_show_from_set (c, &showlist), "show debug event");
+
+ add_show_from_set (add_set_cmd ("event",
+ class_maintenance,
+ var_zinteger,
+ (char *) (&gdb_events_debug),
+ "Set event debugging.\n\\
+When non-zero, event/notify debugging is enabled.", &setdebuglist),
+ &showdebuglist);
+}
+EOF
+
+# close things off
+exec 1>&2
+#../move-if-change new-gdb-events.c gdb-events.c
+# Replace any leading spaces with tabs
+sed < new-gdb-events.c > tmp-gdb-events.c \
+ -e 's/\( \)* /\1 /g'
+mv tmp-gdb-events.c new-gdb-events.c
+# Move if changed?
+if test -r gdb-events.c
+then
+ diff -c gdb-events.c new-gdb-events.c
+ if [ $? = 1 ]
+ then
+ echo "gdb-events.c changed? cp new-gdb-events.c gdb-events.c" 1>&2
+ fi
+else
+ echo "File missing? mv new-gdb-events.c gdb-events.c" 1>&2
+fi
diff --git a/gdb/gdb-stabs.h b/gdb/gdb-stabs.h
new file mode 100644
index 00000000000..d2da2d11d99
--- /dev/null
+++ b/gdb/gdb-stabs.h
@@ -0,0 +1,87 @@
+/* Definitions for symbol-reading containing "stabs", for GDB.
+ Copyright 1992, 1993, 1995, 1996, 1997, 1999, 2000
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support. Written by John Gilmore.
+
+ 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. */
+
+/* This file exists to hold the common definitions required of most of
+ the symbol-readers that end up using stabs. The common use of
+ these `symbol-type-specific' customizations of the generic data
+ structures makes the stabs-oriented symbol readers able to call
+ each others' functions as required. */
+
+#if !defined (GDBSTABS_H)
+#define GDBSTABS_H
+
+#define SECT_OFF_MAX 64 /* Count of possible values */
+
+/* The stab_section_info chain remembers info from the ELF symbol table,
+ while psymtabs are being built for the other symbol tables in the
+ objfile. It is destroyed at the complation of psymtab-reading.
+ Any info that was used from it has been copied into psymtabs. */
+
+struct stab_section_info
+ {
+ char *filename;
+ CORE_ADDR sections[SECT_OFF_MAX];
+ struct stab_section_info *next;
+ int found; /* Count of times it's found in searching */
+ };
+
+/* Information is passed among various dbxread routines for accessing
+ symbol files. A pointer to this structure is kept in the sym_stab_info
+ field of the objfile struct. */
+
+struct dbx_symfile_info
+ {
+ CORE_ADDR text_addr; /* Start of text section */
+ int text_size; /* Size of text section */
+ int symcount; /* How many symbols are there in the file */
+ char *stringtab; /* The actual string table */
+ int stringtab_size; /* Its size */
+ file_ptr symtab_offset; /* Offset in file to symbol table */
+ int symbol_size; /* Bytes in a single symbol */
+ struct stab_section_info *stab_section_info; /* section starting points
+ of the original .o files before linking. */
+
+ /* See stabsread.h for the use of the following. */
+ struct header_file *header_files;
+ int n_header_files;
+ int n_allocated_header_files;
+
+ /* Pointers to BFD sections. These are used to speed up the building of
+ minimal symbols. */
+ asection *text_section;
+ asection *data_section;
+ asection *bss_section;
+ };
+
+#define DBX_SYMFILE_INFO(o) ((o)->sym_stab_info)
+#define DBX_TEXT_ADDR(o) (DBX_SYMFILE_INFO(o)->text_addr)
+#define DBX_TEXT_SIZE(o) (DBX_SYMFILE_INFO(o)->text_size)
+#define DBX_SYMCOUNT(o) (DBX_SYMFILE_INFO(o)->symcount)
+#define DBX_STRINGTAB(o) (DBX_SYMFILE_INFO(o)->stringtab)
+#define DBX_STRINGTAB_SIZE(o) (DBX_SYMFILE_INFO(o)->stringtab_size)
+#define DBX_SYMTAB_OFFSET(o) (DBX_SYMFILE_INFO(o)->symtab_offset)
+#define DBX_SYMBOL_SIZE(o) (DBX_SYMFILE_INFO(o)->symbol_size)
+#define DBX_TEXT_SECTION(o) (DBX_SYMFILE_INFO(o)->text_section)
+#define DBX_DATA_SECTION(o) (DBX_SYMFILE_INFO(o)->data_section)
+#define DBX_BSS_SECTION(o) (DBX_SYMFILE_INFO(o)->bss_section)
+
+#endif /* GDBSTABS_H */
diff --git a/gdb/gdb.1 b/gdb/gdb.1
new file mode 100644
index 00000000000..5872f989c64
--- /dev/null
+++ b/gdb/gdb.1
@@ -0,0 +1,375 @@
+.\" Copyright 1991, 1999 Free Software Foundation, Inc.
+.\" See section COPYING for conditions for redistribution
+.\" $Id$
+.TH gdb 1 "4nov1991" "GNU Tools" "GNU Tools"
+.SH NAME
+gdb \- The GNU Debugger
+.SH SYNOPSIS
+.na
+.TP
+.B gdb
+.RB "[\|" \-help "\|]"
+.RB "[\|" \-nx "\|]"
+.RB "[\|" \-q "\|]"
+.RB "[\|" \-batch "\|]"
+.RB "[\|" \-cd=\c
+.I dir\c
+\|]
+.RB "[\|" \-f "\|]"
+.RB "[\|" "\-b\ "\c
+.IR bps "\|]"
+.RB "[\|" "\-tty="\c
+.IR dev "\|]"
+.RB "[\|" "\-s "\c
+.I symfile\c
+\&\|]
+.RB "[\|" "\-e "\c
+.I prog\c
+\&\|]
+.RB "[\|" "\-se "\c
+.I prog\c
+\&\|]
+.RB "[\|" "\-c "\c
+.I core\c
+\&\|]
+.RB "[\|" "\-x "\c
+.I cmds\c
+\&\|]
+.RB "[\|" "\-d "\c
+.I dir\c
+\&\|]
+.RB "[\|" \c
+.I prog\c
+.RB "[\|" \c
+.IR core \||\| procID\c
+\&\|]\&\|]
+.ad b
+.SH DESCRIPTION
+The purpose of a debugger such as GDB is to allow you to see what is
+going on ``inside'' another program while it executes\(em\&or what another
+program was doing at the moment it crashed.
+
+GDB can do four main kinds of things (plus other things in support of
+these) to help you catch bugs in the act:
+
+.TP
+\ \ \ \(bu
+Start your program, specifying anything that might affect its behavior.
+
+.TP
+\ \ \ \(bu
+Make your program stop on specified conditions.
+
+.TP
+\ \ \ \(bu
+Examine what has happened, when your program has stopped.
+
+.TP
+\ \ \ \(bu
+Change things in your program, so you can experiment with correcting the
+effects of one bug and go on to learn about another.
+.PP
+
+You can use GDB to debug programs written in C, C++, and Modula-2.
+Fortran support will be added when a GNU Fortran compiler is ready.
+
+GDB is invoked with the shell command \c
+.B gdb\c
+\&. Once started, it reads
+commands from the terminal until you tell it to exit with the GDB
+command \c
+.B quit\c
+\&. You can get online help from \c
+.B gdb\c
+\& itself
+by using the command \c
+.B help\c
+\&.
+
+You can run \c
+.B gdb\c
+\& with no arguments or options; but the most
+usual way to start GDB is with one argument or two, specifying an
+executable program as the argument:
+.sp
+.br
+gdb\ program
+.br
+.sp
+
+You can also start with both an executable program and a core file specified:
+.sp
+.br
+gdb\ program\ core
+.br
+.sp
+
+You can, instead, specify a process ID as a second argument, if you want
+to debug a running process:
+.sp
+.br
+gdb\ program\ 1234
+.br
+.sp
+
+would attach GDB to process \c
+.B 1234\c
+\& (unless you also have a file
+named `\|\c
+.B 1234\c
+\&\|'; GDB does check for a core file first).
+
+Here are some of the most frequently needed GDB commands:
+.TP
+.B break \fR[\|\fIfile\fB:\fR\|]\fIfunction
+\&
+Set a breakpoint at \c
+.I function\c
+\& (in \c
+.I file\c
+\&).
+.TP
+.B run \fR[\|\fIarglist\fR\|]
+Start your program (with \c
+.I arglist\c
+\&, if specified).
+.TP
+.B bt
+Backtrace: display the program stack.
+.TP
+.BI print " expr"\c
+\&
+Display the value of an expression.
+.TP
+.B c
+Continue running your program (after stopping, e.g. at a breakpoint).
+.TP
+.B next
+Execute next program line (after stopping); step \c
+.I over\c
+\& any
+function calls in the line.
+.TP
+.B step
+Execute next program line (after stopping); step \c
+.I into\c
+\& any
+function calls in the line.
+.TP
+.B help \fR[\|\fIname\fR\|]
+Show information about GDB command \c
+.I name\c
+\&, or general information
+about using GDB.
+.TP
+.B quit
+Exit from GDB.
+.PP
+For full details on GDB, see \c
+.I
+Using GDB: A Guide to the GNU Source-Level Debugger\c
+\&, by Richard M. Stallman and Roland H. Pesch. The same text is available online
+as the \c
+.B gdb\c
+\& entry in the \c
+.B info\c
+\& program.
+.SH OPTIONS
+Any arguments other than options specify an executable
+file and core file (or process ID); that is, the first argument
+encountered with no
+associated option flag is equivalent to a `\|\c
+.B \-se\c
+\&\|' option, and the
+second, if any, is equivalent to a `\|\c
+.B \-c\c
+\&\|' option if it's the name of a file. Many options have
+both long and short forms; both are shown here. The long forms are also
+recognized if you truncate them, so long as enough of the option is
+present to be unambiguous. (If you prefer, you can flag option
+arguments with `\|\c
+.B +\c
+\&\|' rather than `\|\c
+.B \-\c
+\&\|', though we illustrate the
+more usual convention.)
+
+All the options and command line arguments you give are processed
+in sequential order. The order makes a difference when the
+`\|\c
+.B \-x\c
+\&\|' option is used.
+
+.TP
+.B \-help
+.TP
+.B \-h
+List all options, with brief explanations.
+
+.TP
+.BI "\-symbols=" "file"\c
+.TP
+.BI "\-s " "file"\c
+\&
+Read symbol table from file \c
+.I file\c
+\&.
+
+.TP
+.B \-write
+Enable writing into executable and core files.
+
+.TP
+.BI "\-exec=" "file"\c
+.TP
+.BI "\-e " "file"\c
+\&
+Use file \c
+.I file\c
+\& as the executable file to execute when
+appropriate, and for examining pure data in conjunction with a core
+dump.
+
+.TP
+.BI "\-se=" "file"\c
+\&
+Read symbol table from file \c
+.I file\c
+\& and use it as the executable
+file.
+
+.TP
+.BI "\-core=" "file"\c
+.TP
+.BI "\-c " "file"\c
+\&
+Use file \c
+.I file\c
+\& as a core dump to examine.
+
+.TP
+.BI "\-command=" "file"\c
+.TP
+.BI "\-x " "file"\c
+\&
+Execute GDB commands from file \c
+.I file\c
+\&.
+
+.TP
+.BI "\-directory=" "directory"\c
+.TP
+.BI "\-d " "directory"\c
+\&
+Add \c
+.I directory\c
+\& to the path to search for source files.
+.PP
+
+.TP
+.B \-nx
+.TP
+.B \-n
+Do not execute commands from any `\|\c
+.B .gdbinit\c
+\&\|' initialization files.
+Normally, the commands in these files are executed after all the
+command options and arguments have been processed.
+
+
+.TP
+.B \-quiet
+.TP
+.B \-q
+``Quiet''. Do not print the introductory and copyright messages. These
+messages are also suppressed in batch mode.
+
+.TP
+.B \-batch
+Run in batch mode. Exit with status \c
+.B 0\c
+\& after processing all the command
+files specified with `\|\c
+.B \-x\c
+\&\|' (and `\|\c
+.B .gdbinit\c
+\&\|', if not inhibited).
+Exit with nonzero status if an error occurs in executing the GDB
+commands in the command files.
+
+Batch mode may be useful for running GDB as a filter, for example to
+download and run a program on another computer; in order to make this
+more useful, the message
+.sp
+.br
+Program\ exited\ normally.
+.br
+.sp
+
+(which is ordinarily issued whenever a program running under GDB control
+terminates) is not issued when running in batch mode.
+
+.TP
+.BI "\-cd=" "directory"\c
+\&
+Run GDB using \c
+.I directory\c
+\& as its working directory,
+instead of the current directory.
+
+.TP
+.B \-fullname
+.TP
+.B \-f
+Emacs sets this option when it runs GDB as a subprocess. It tells GDB
+to output the full file name and line number in a standard,
+recognizable fashion each time a stack frame is displayed (which
+includes each time the program stops). This recognizable format looks
+like two `\|\c
+.B \032\c
+\&\|' characters, followed by the file name, line number
+and character position separated by colons, and a newline. The
+Emacs-to-GDB interface program uses the two `\|\c
+.B \032\c
+\&\|' characters as
+a signal to display the source code for the frame.
+
+.TP
+.BI "\-b " "bps"\c
+\&
+Set the line speed (baud rate or bits per second) of any serial
+interface used by GDB for remote debugging.
+
+.TP
+.BI "\-tty=" "device"\c
+\&
+Run using \c
+.I device\c
+\& for your program's standard input and output.
+.PP
+
+.SH "SEE ALSO"
+.RB "`\|" gdb "\|'"
+entry in
+.B info\c
+\&;
+.I
+Using GDB: A Guide to the GNU Source-Level Debugger\c
+, Richard M. Stallman and Roland H. Pesch, July 1991.
+.SH COPYING
+Copyright (c) 1991 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be included in
+translations approved by the Free Software Foundation instead of in
+the original English.
diff --git a/gdb/gdb.gdb b/gdb/gdb.gdb
new file mode 100644
index 00000000000..437784102c1
--- /dev/null
+++ b/gdb/gdb.gdb
@@ -0,0 +1,35 @@
+# Examples of using gdb's command language to print out various gdb data
+# structures.
+
+define list-objfiles
+ set $obj = object_files
+ printf "objfile bfd msyms name\n"
+ while $obj != 0
+ printf "0x%-8x 0x%-8x %6d %s\n", $obj, $obj->obfd, \
+ $obj->minimal_symbol_count, $obj->name
+ set var $obj = $obj->next
+ end
+end
+document list-objfiles
+Print a table of the current objfiles.
+end
+
+define print-values
+ printf "Location Offset Size Lazy Contents0-3 Lval\n"
+ set $val = $arg0
+ while $val != 0
+ printf "%8x %6d %10d %4d %12x ", $val->location.address, \
+ $val->offset, \
+ $val->type->length, $val->lazy, $val->aligner.contents[0]
+ output $val->lval
+ printf "\n"
+ set $val = $val->next
+ end
+end
+document print-values
+Print a list of values.
+Takes one argument, the value to print, and prints all the values which
+are chained through the next field. Thus the most recently created values
+will be listed first. The "Contents0-3" field gives the first "int"
+of the VALUE_CONTENTS; not the entire contents.
+end
diff --git a/gdb/gdb.h b/gdb/gdb.h
new file mode 100644
index 00000000000..737ac82edfe
--- /dev/null
+++ b/gdb/gdb.h
@@ -0,0 +1,60 @@
+/* Library interface into GDB.
+ Copyright 1999, 2001
+ 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. */
+
+#ifndef GDB_H
+#define GDB_H
+
+/* Return-code (RC) from a gdb library call. (The abreviation RC is
+ taken from the sim/common directory.) */
+
+enum gdb_rc {
+ /* The operation failed. The failure message can be fetched by
+ calling ``char *error_last_message(void)''. The value is
+ determined by the catch_errors() interface. */
+ /* NOTE: Since ``defs.h:catch_errors()'' does not return an error /
+ internal / quit indication it is not possible to return that
+ here. */
+ GDB_RC_FAIL = 0,
+ /* No error occured but nothing happened. Due to the catch_errors()
+ interface, this must be non-zero. */
+ GDB_RC_NONE = 1,
+ /* The operation was successful. Due to the catch_errors()
+ interface, this must be non-zero. */
+ GDB_RC_OK = 2
+};
+
+
+/* Print the specified breakpoint on GDB_STDOUT. (Eventually this
+ function will ``print'' the object on ``output''). */
+enum gdb_rc gdb_breakpoint_query (struct ui_out *uiout, int bnum);
+
+/* Create a breakpoint at ADDRESS (a GDB source and line). */
+enum gdb_rc gdb_breakpoint (char *address, char *condition,
+ int hardwareflag, int tempflag,
+ int thread, int ignore_count);
+
+/* Switch thread and print notification. */
+enum gdb_rc gdb_thread_select (struct ui_out *uiout, char *tidstr);
+
+/* Print a list of known thread ids. */
+enum gdb_rc gdb_list_thread_ids (struct ui_out *uiout);
+
+#endif
diff --git a/gdb/gdb_assert.h b/gdb/gdb_assert.h
new file mode 100644
index 00000000000..4f0bcdc9497
--- /dev/null
+++ b/gdb/gdb_assert.h
@@ -0,0 +1,55 @@
+/* GDB-friendly replacement for <assert.h>.
+ Copyright 2000, 2001 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. */
+
+#ifndef GDB_ASSERT_H
+#define GDB_ASSERT_H
+
+/* PRAGMATICS: "gdb_assert.h":gdb_assert() is a lower case (rather
+ than upper case) macro since that provides the closest fit to the
+ existing lower case macro <assert.h>:assert() that it is
+ replacing. */
+
+#define gdb_assert(expr) \
+ ((void) ((expr) ? 0 : \
+ (gdb_assert_fail (#expr, __FILE__, __LINE__, ASSERT_FUNCTION), 0)))
+
+/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
+ which contains the name of the function currently being defined.
+ This is broken in G++ before version 2.6.
+ C9x has a similar variable called __func__, but prefer the GCC one since
+ it demangles C++ function names. */
+#if (GCC_VERSION >= 2004)
+#define ASSERT_FUNCTION __PRETTY_FUNCTION__
+#else
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#define ASSERT_FUNCTION __func__
+#else
+#define ASSERT_FUNCTION ((const char *) 0)
+#endif
+#endif
+
+/* This prints an "Assertion failed" message, aksing the user if they
+ want to continue, dump core, or just exit. */
+#define gdb_assert_fail(assertion, file, line, function) \
+ internal_error (file, line, "%s%sAssertion `%s' failed.", \
+ function ? function : "", function ? ": " : "", \
+ assertion)
+
+#endif /* gdb_assert.h */
diff --git a/gdb/gdb_dirent.h b/gdb/gdb_dirent.h
new file mode 100644
index 00000000000..9cb40061420
--- /dev/null
+++ b/gdb/gdb_dirent.h
@@ -0,0 +1,40 @@
+/* Portable <dirent.h>
+ Copyright 2000 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. */
+
+#if !defined(GDB_DIRENT_H)
+#define GDB_DIRENT_H
+
+/* From bfd/hpux-core.c. */
+
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+#else
+# ifdef HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+
+#endif /* !defined(GDB_DIRENT_H) */
diff --git a/gdb/gdb_indent.sh b/gdb/gdb_indent.sh
new file mode 100755
index 00000000000..1e727fe2309
--- /dev/null
+++ b/gdb/gdb_indent.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+# Try to find a GNU indent. There could be a BSD indent in front of a
+# GNU gindent so when indent is found, keep looking.
+
+gindent=
+indent=
+paths=`echo $PATH | sed \
+ -e 's/::/:.:/g' \
+ -e 's/^:/.:/' \
+ -e 's/:$/:./' \
+ -e 's/:/ /g'`
+for path in $paths
+do
+ if test ! -n "${gindent}" -a -x ${path}/gindent
+ then
+ gindent=${path}/gindent
+ break
+ elif test ! -n "${indent}" -a -x ${path}/indent
+ then
+ indent=${path}/indent
+ fi
+done
+
+if test -n "${gindent}"
+then
+ indent=${gindent}
+elif test -n "${indent}"
+then
+ :
+else
+ echo "Indent not found" 1>&2
+fi
+
+
+# Check that the indent found is both GNU and a reasonable version.
+# Different indent versions give different indentation.
+
+case `${indent} --version 2>/dev/null < /dev/null` in
+ GNU*2.2.6 ) ;;
+ *GNU* ) echo "Incorrect version of GNU indent" 1>&2 ;;
+ * ) echo "Indent is not GNU" 1>&2 ;;
+esac
+
+
+# Check that we're in the GDB source directory
+
+case `pwd` in
+ */gdb ) ;;
+ */sim/* ) ;;
+ * ) echo "Not in GDB directory" 1>&2 ; exit 1 ;;
+esac
+
+
+# Run indent per GDB specs
+
+types="-T FILE `cat *.h | sed -n \
+ -e 's/^.*[^a-z0-9_]\([a-z0-9_]*_ftype\).*$/-T \1/p' \
+ -e 's/^.*[^a-z0-9_]\([a-z0-9_]*_func\).*$/-T \1/p' \
+ -e 's/^typedef.*[^a-zA-Z0-9_]\([a-zA-Z0-9_]*[a-zA-Z0-9_]\);$/-T \1/p' \
+ | sort -u`"
+
+${indent} ${types} "$@"
diff --git a/gdb/gdb_proc_service.h b/gdb/gdb_proc_service.h
new file mode 100644
index 00000000000..e77cdf6cd80
--- /dev/null
+++ b/gdb/gdb_proc_service.h
@@ -0,0 +1,86 @@
+/* <proc_service.h> replacement for systems that don't have it.
+ Copyright 2000 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. */
+
+#ifndef GDB_PROC_SERVICE_H
+#define GDB_PROC_SERVICE_H
+
+#include <sys/types.h>
+
+#ifdef HAVE_PROC_SERVICE_H
+#include <proc_service.h>
+#else
+
+#ifdef HAVE_SYS_PROCFS_H
+#include <sys/procfs.h>
+#endif
+
+#include "gregset.h"
+
+typedef enum
+{
+ PS_OK, /* Success. */
+ PS_ERR, /* Generic error. */
+ PS_BADPID, /* Bad process handle. */
+ PS_BADLID, /* Bad LWP id. */
+ PS_BADADDR, /* Bad address. */
+ PS_NOSYM, /* Symbol not found. */
+ PS_NOFREGS /* FPU register set not available. */
+} ps_err_e;
+
+#ifndef HAVE_LWPID_T
+typedef unsigned int lwpid_t;
+#endif
+
+typedef unsigned long paddr_t;
+
+#ifndef HAVE_PSADDR_T
+typedef unsigned long psaddr_t;
+#endif
+
+#ifndef HAVE_PRGREGSET_T
+typedef gdb_gregset_t prgregset_t;
+#endif
+
+#ifndef HAVE_PRFPREGSET_T
+typedef gdb_fpregset_t prfpregset_t;
+#endif
+
+#endif /* HAVE_PROC_SERVICE_H */
+
+/* Fix-up some broken systems. */
+
+/* Unfortunately glibc 2.1.3 was released with a broken prfpregset_t
+ type. We let configure check for this lossage, and make
+ appropriate typedefs here. */
+
+#ifdef PRFPREGSET_T_BROKEN
+typedef gdb_fpregset_t gdb_prfpregset_t;
+#else
+typedef prfpregset_t gdb_prfpregset_t;
+#endif
+
+/* Structure that identifies the target process. */
+struct ps_prochandle
+{
+ /* The process id is all we need. */
+ pid_t pid;
+};
+
+#endif /* gdb_proc_service.h */
diff --git a/gdb/gdb_regex.h b/gdb/gdb_regex.h
new file mode 100644
index 00000000000..27a570a1f40
--- /dev/null
+++ b/gdb/gdb_regex.h
@@ -0,0 +1,30 @@
+/* Portable <regex.h>
+ Copyright 2000, 2001 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. */
+
+#ifndef GDB_REGEX_H
+#define GDB_REGEX_H
+
+#ifdef USE_INCLUDED_REGEX
+#include "xregex.h"
+#else
+#include <regex.h>
+#endif
+
+#endif /* gdb_regex.h */
diff --git a/gdb/gdb_stat.h b/gdb/gdb_stat.h
new file mode 100644
index 00000000000..f3577f2f994
--- /dev/null
+++ b/gdb/gdb_stat.h
@@ -0,0 +1,74 @@
+/* Portable <sys/stat.h>
+ 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. */
+
+#if !defined(GDB_STAT_H)
+#define GDB_STAT_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef STAT_MACROS_BROKEN
+#undef S_ISBLK
+#undef S_ISCHR
+#undef S_ISDIR
+#undef S_ISREG
+#undef S_ISFIFO
+#undef S_ISLNK
+#undef S_ISSOCK
+#undef S_ISMPB
+#undef S_ISMPC
+#undef S_ISNWK
+#endif
+
+#if !defined(S_ISBLK) && defined(S_IFBLK)
+#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#endif
+#if !defined(S_ISCHR) && defined(S_IFCHR)
+#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#endif
+#if !defined(S_ISDIR) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+#if !defined(S_ISREG) && defined(S_IFREG)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+#if !defined(S_ISFIFO) && defined(S_IFIFO)
+#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#endif
+#if !defined(S_ISLNK) && defined(S_IFLNK)
+#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#endif
+#if !defined(S_ISSOCK) && defined(S_IFSOCK)
+#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+#endif
+#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
+#define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
+#define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
+#endif
+#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
+#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
+#endif
+
+/* Microsoft C's stat.h doesn't define all the POSIX file modes. */
+#ifndef S_IROTH
+#define S_IROTH S_IREAD
+#endif
+
+#endif /* !defined(GDB_STAT_H) */
diff --git a/gdb/gdb_string.h b/gdb/gdb_string.h
new file mode 100644
index 00000000000..f54af80845c
--- /dev/null
+++ b/gdb/gdb_string.h
@@ -0,0 +1,67 @@
+/* Portable <string.h>
+ Copyright 1995, 1998, 1999, 2000, 2001 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. */
+
+#if !defined(GDB_STRING_H)
+#define GDB_STRING_H
+
+#ifdef STDC_HEADERS
+#include <string.h>
+#else
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#ifndef strchr
+extern char *strchr (const char *, int); /* X3.159-1989 4.11.5.2 */
+#endif
+
+#ifndef strrchr
+extern char *strrchr (const char *, int); /* X3.159-1989 4.11.5.5 */
+#endif
+
+#ifndef strtok
+extern char *strtok (char *, const char *); /* X3.159-1989 4.11.5.8 */
+#endif
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#else
+extern void *memset ();
+extern void *memcpy ();
+extern void *memmove ();
+extern int memcmp ();
+#endif
+#endif /* STDC_HEADERS */
+
+#ifdef NEED_DECLARATION_STRERROR
+#ifndef strerror
+extern char *strerror (int); /* X3.159-1989 4.11.6.2 */
+#endif
+#endif
+
+#ifdef NEED_DECLARATION_STRSTR
+#ifndef strstr
+extern char *strstr (const char *, const char *); /* X3.159-1989 4.11.5.7 */
+#endif
+#endif
+
+#endif /* !defined(GDB_STRING_H) */
diff --git a/gdb/gdb_thread_db.h b/gdb/gdb_thread_db.h
new file mode 100644
index 00000000000..8088da0da69
--- /dev/null
+++ b/gdb/gdb_thread_db.h
@@ -0,0 +1,450 @@
+#ifdef HAVE_THREAD_DB_H
+#include <thread_db.h>
+#else
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+typedef uint32_t gdb_uint32_t;
+#define GDB_UINT32_C(c) UINT32_C(c)
+#else
+typedef unsigned int gdb_uint32_t;
+#define GDB_UINT32_C(c) c ## U
+#endif
+
+/* Copyright 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef _THREAD_DB_H
+#define _THREAD_DB_H 1
+
+/* This is the debugger interface for the LinuxThreads library. It is
+ modelled closely after the interface with same names in Solaris with
+ the goal to share the same code in the debugger. */
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/procfs.h>
+
+
+/* Error codes of the library. */
+typedef enum
+{
+ TD_OK, /* No error. */
+ TD_ERR, /* No further specified error. */
+ TD_NOTHR, /* No matching thread found. */
+ TD_NOSV, /* No matching synchronization handle found. */
+ TD_NOLWP, /* No matching light-weighted process found. */
+ TD_BADPH, /* Invalid process handle. */
+ TD_BADTH, /* Invalid thread handle. */
+ TD_BADSH, /* Invalid synchronization handle. */
+ TD_BADTA, /* Invalid thread agent. */
+ TD_BADKEY, /* Invalid key. */
+ TD_NOMSG, /* No event available. */
+ TD_NOFPREGS, /* No floating-point register content available. */
+ TD_NOLIBTHREAD, /* Application not linked with thread library. */
+ TD_NOEVENT, /* Requested event is not supported. */
+ TD_NOCAPAB, /* Capability not available. */
+ TD_DBERR, /* Internal debug library error. */
+ TD_NOAPLIC, /* Operation is not applicable. */
+ TD_NOTSD, /* No thread-specific data available. */
+ TD_MALLOC, /* Out of memory. */
+ TD_PARTIALREG, /* Not entire register set was read or written. */
+ TD_NOXREGS /* X register set not available for given thread. */
+} td_err_e;
+
+
+/* Possible thread states. TD_THR_ANY_STATE is a pseudo-state used to
+ select threads regardless of state in td_ta_thr_iter(). */
+typedef enum
+{
+ TD_THR_ANY_STATE,
+ TD_THR_UNKNOWN,
+ TD_THR_STOPPED,
+ TD_THR_RUN,
+ TD_THR_ACTIVE,
+ TD_THR_ZOMBIE,
+ TD_THR_SLEEP,
+ TD_THR_STOPPED_ASLEEP
+} td_thr_state_e;
+
+/* Thread type: user or system. TD_THR_ANY_TYPE is a pseudo-type used
+ to select threads regardless of type in td_ta_thr_iter(). */
+typedef enum
+{
+ TD_THR_ANY_TYPE,
+ TD_THR_USER,
+ TD_THR_SYSTEM
+} td_thr_type_e;
+
+
+/* Types of the debugging library. */
+
+/* Handle for a process. This type is opaque. */
+typedef struct td_thragent td_thragent_t;
+
+/* The actual thread handle type. This is also opaque. */
+typedef struct td_thrhandle
+{
+ td_thragent_t *th_ta_p;
+ psaddr_t th_unique;
+} td_thrhandle_t;
+
+
+/* Flags for `td_ta_thr_iter'. */
+#define TD_THR_ANY_USER_FLAGS 0xffffffff
+#define TD_THR_LOWEST_PRIORITY -20
+#define TD_SIGNO_MASK NULL
+
+
+#define TD_EVENTSIZE 2
+#define BT_UISHIFT 5 /* log base 2 of BT_NBIPUI, to extract word index */
+#define BT_NBIPUI (1 << BT_UISHIFT) /* n bits per uint */
+#define BT_UIMASK (BT_NBIPUI - 1) /* to extract bit index */
+
+/* Bitmask of enabled events. */
+typedef struct td_thr_events
+{
+ gdb_uint32_t event_bits[TD_EVENTSIZE];
+} td_thr_events_t;
+
+/* Event set manipulation macros. */
+#define __td_eventmask(n) \
+ (GDB_UINT32_C (1) << (((n) - 1) & BT_UIMASK))
+#define __td_eventword(n) \
+ ((GDB_UINT32_C ((n) - 1)) >> BT_UISHIFT)
+
+#define td_event_emptyset(setp) \
+ do { \
+ int __i; \
+ for (__i = TD_EVENTSIZE; __i > 0; --__i) \
+ (setp)->event_bits[__i - 1] = 0; \
+ } while (0)
+
+#define td_event_fillset(setp) \
+ do { \
+ int __i; \
+ for (__i = TD_EVENTSIZE; __i > 0; --__i) \
+ (setp)->event_bits[__i - 1] = GDB_UINT32_C (0xffffffff); \
+ } while (0)
+
+#define td_event_addset(setp, n) \
+ (((setp)->event_bits[__td_eventword (n)]) |= __td_eventmask (n))
+#define td_event_delset(setp, n) \
+ (((setp)->event_bits[__td_eventword (n)]) &= ~__td_eventmask (n))
+#define td_eventismember(setp, n) \
+ (__td_eventmask (n) & ((setp)->event_bits[__td_eventword (n)]))
+#if TD_EVENTSIZE == 2
+# define td_eventisempty(setp) \
+ (!((setp)->event_bits[0]) && !((setp)->event_bits[1]))
+#else
+# error "td_eventisempty must be changed to match TD_EVENTSIZE"
+#endif
+
+/* Events reportable by the thread implementation. */
+typedef enum
+{
+ TD_ALL_EVENTS, /* Pseudo-event number. */
+ TD_EVENT_NONE = TD_ALL_EVENTS, /* Depends on context. */
+ TD_READY, /* Is executable now. */
+ TD_SLEEP, /* Blocked in a synchronization obj. */
+ TD_SWITCHTO, /* Now assigned to a process. */
+ TD_SWITCHFROM, /* Not anymore assigned to a process. */
+ TD_LOCK_TRY, /* Trying to get an unavailable lock. */
+ TD_CATCHSIG, /* Signal posted to the thread. */
+ TD_IDLE, /* Process getting idle. */
+ TD_CREATE, /* New thread created. */
+ TD_DEATH, /* Thread terminated. */
+ TD_PREEMPT, /* Preempted. */
+ TD_PRI_INHERIT, /* Inherited elevated priority. */
+ TD_REAP, /* Reaped. */
+ TD_CONCURRENCY, /* Number of processes changing. */
+ TD_TIMEOUT, /* Conditional variable wait timed out. */
+ TD_MIN_EVENT_NUM = TD_READY,
+ TD_MAX_EVENT_NUM = TD_TIMEOUT,
+ TD_EVENTS_ENABLE = 31 /* Event reporting enabled. */
+} td_event_e;
+
+/* Values representing the different ways events are reported. */
+typedef enum
+{
+ NOTIFY_BPT, /* User must insert breakpoint at u.bptaddr. */
+ NOTIFY_AUTOBPT, /* Breakpoint at u.bptaddr is automatically
+ inserted. */
+ NOTIFY_SYSCALL /* System call u.syscallno will be invoked. */
+} td_notify_e;
+
+/* Description how event type is reported. */
+typedef struct td_notify
+{
+ td_notify_e type; /* Way the event is reported. */
+ union
+ {
+ psaddr_t bptaddr; /* Address of breakpoint. */
+ int syscallno; /* Number of system call used. */
+ } u;
+} td_notify_t;
+
+/* Structure used to report event. */
+typedef struct td_event_msg
+{
+ td_event_e event; /* Event type being reported. */
+ const td_thrhandle_t *th_p; /* Thread reporting the event. */
+ union
+ {
+#if 0
+ td_synchandle_t *sh; /* Handle of synchronization object. */
+#endif
+ uintptr_t data; /* Event specific data. */
+ } msg;
+} td_event_msg_t;
+
+/* Structure containing event data available in each thread structure. */
+typedef struct
+{
+ td_thr_events_t eventmask; /* Mask of enabled events. */
+ td_event_e eventnum; /* Number of last event. */
+ void *eventdata; /* Data associated with event. */
+} td_eventbuf_t;
+
+
+/* Gathered statistics about the process. */
+typedef struct td_ta_stats
+{
+ int nthreads; /* Total number of threads in use. */
+ int r_concurrency; /* Concurrency level requested by user. */
+ int nrunnable_num; /* Average runnable threads, numerator. */
+ int nrunnable_den; /* Average runnable threads, denominator. */
+ int a_concurrency_num; /* Achieved concurrency level, numerator. */
+ int a_concurrency_den; /* Achieved concurrency level, denominator. */
+ int nlwps_num; /* Average number of processes in use,
+ numerator. */
+ int nlwps_den; /* Average number of processes in use,
+ denominator. */
+ int nidle_num; /* Average number of idling processes,
+ numerator. */
+ int nidle_den; /* Average number of idling processes,
+ denominator. */
+} td_ta_stats_t;
+
+
+/* Since Sun's library is based on Solaris threads we have to define a few
+ types to map them to POSIX threads. */
+typedef pthread_t thread_t;
+typedef pthread_key_t thread_key_t;
+
+
+/* Callback for iteration over threads. */
+typedef int td_thr_iter_f (const td_thrhandle_t *, void *);
+
+/* Callback for iteration over thread local data. */
+typedef int td_key_iter_f (thread_key_t, void (*) (void *), void *);
+
+
+
+/* Forward declaration. This has to be defined by the user. */
+struct ps_prochandle;
+
+
+/* Information about the thread. */
+typedef struct td_thrinfo
+{
+ td_thragent_t *ti_ta_p; /* Process handle. */
+ unsigned int ti_user_flags; /* Unused. */
+ thread_t ti_tid; /* Thread ID returned by
+ pthread_create(). */
+ char *ti_tls; /* Pointer to thread-local data. */
+ psaddr_t ti_startfunc; /* Start function passed to
+ pthread_create(). */
+ psaddr_t ti_stkbase; /* Base of thread's stack. */
+ long int ti_stksize; /* Size of thread's stack. */
+ psaddr_t ti_ro_area; /* Unused. */
+ int ti_ro_size; /* Unused. */
+ td_thr_state_e ti_state; /* Thread state. */
+ unsigned char ti_db_suspended; /* Nonzero if suspended by debugger. */
+ td_thr_type_e ti_type; /* Type of the thread (system vs
+ user thread). */
+ intptr_t ti_pc; /* Unused. */
+ intptr_t ti_sp; /* Unused. */
+ short int ti_flags; /* Unused. */
+ int ti_pri; /* Thread priority. */
+ lwpid_t ti_lid; /* Unused. */
+ sigset_t ti_sigmask; /* Signal mask. */
+ unsigned char ti_traceme; /* Nonzero if event reporting
+ enabled. */
+ unsigned char ti_preemptflag; /* Unused. */
+ unsigned char ti_pirecflag; /* Unused. */
+ sigset_t ti_pending; /* Set of pending signals. */
+ td_thr_events_t ti_events; /* Set of enabled events. */
+} td_thrinfo_t;
+
+
+
+/* Prototypes for exported library functions. */
+
+/* Initialize the thread debug support library. */
+extern td_err_e td_init (void);
+
+/* Historical relict. Should not be used anymore. */
+extern td_err_e td_log (void);
+
+/* Generate new thread debug library handle for process PS. */
+extern td_err_e td_ta_new (struct ps_prochandle *__ps, td_thragent_t **__ta);
+
+/* Free resources allocated for TA. */
+extern td_err_e td_ta_delete (td_thragent_t *__ta);
+
+/* Get number of currently running threads in process associated with TA. */
+extern td_err_e td_ta_get_nthreads (const td_thragent_t *__ta, int *__np);
+
+/* Return process handle passed in `td_ta_new' for process associated with
+ TA. */
+extern td_err_e td_ta_get_ph (const td_thragent_t *__ta,
+ struct ps_prochandle **__ph);
+
+/* Map thread library handle PT to thread debug library handle for process
+ associated with TA and store result in *TH. */
+extern td_err_e td_ta_map_id2thr (const td_thragent_t *__ta, pthread_t __pt,
+ td_thrhandle_t *__th);
+
+/* Map process ID LWPID to thread debug library handle for process
+ associated with TA and store result in *TH. */
+extern td_err_e td_ta_map_lwp2thr (const td_thragent_t *__ta, lwpid_t __lwpid,
+ td_thrhandle_t *__th);
+
+
+/* Call for each thread in a process associated with TA the callback function
+ CALLBACK. */
+extern td_err_e td_ta_thr_iter (const td_thragent_t *__ta,
+ td_thr_iter_f *__callback, void *__cbdata_p,
+ td_thr_state_e __state, int __ti_pri,
+ sigset_t *__ti_sigmask_p,
+ unsigned int __ti_user_flags);
+
+/* Call for each defined thread local data entry the callback function KI. */
+extern td_err_e td_ta_tsd_iter (const td_thragent_t *__ta, td_key_iter_f *__ki,
+ void *__p);
+
+
+/* Get event address for EVENT. */
+extern td_err_e td_ta_event_addr (const td_thragent_t *__ta,
+ td_event_e __event, td_notify_t *__ptr);
+
+/* Enable EVENT in global mask. */
+extern td_err_e td_ta_set_event (const td_thragent_t *__ta,
+ td_thr_events_t *__event);
+
+/* Disable EVENT in global mask. */
+extern td_err_e td_ta_clear_event (const td_thragent_t *__ta,
+ td_thr_events_t *__event);
+
+/* Return information about last event. */
+extern td_err_e td_ta_event_getmsg (const td_thragent_t *__ta,
+ td_event_msg_t *msg);
+
+
+/* Set suggested concurrency level for process associated with TA. */
+extern td_err_e td_ta_setconcurrency (const td_thragent_t *__ta, int __level);
+
+
+/* Enable collecting statistics for process associated with TA. */
+extern td_err_e td_ta_enable_stats (const td_thragent_t *__ta, int __enable);
+
+/* Reset statistics. */
+extern td_err_e td_ta_reset_stats (const td_thragent_t *__ta);
+
+/* Retrieve statistics from process associated with TA. */
+extern td_err_e td_ta_get_stats (const td_thragent_t *__ta,
+ td_ta_stats_t *__statsp);
+
+
+/* Validate that TH is a thread handle. */
+extern td_err_e td_thr_validate (const td_thrhandle_t *__th);
+
+/* Return information about thread TH. */
+extern td_err_e td_thr_get_info (const td_thrhandle_t *__th,
+ td_thrinfo_t *__infop);
+
+/* Retrieve floating-point register contents of process running thread TH. */
+extern td_err_e td_thr_getfpregs (const td_thrhandle_t *__th,
+ prfpregset_t *__regset);
+
+/* Retrieve general register contents of process running thread TH. */
+extern td_err_e td_thr_getgregs (const td_thrhandle_t *__th,
+ prgregset_t __gregs);
+
+/* Retrieve extended register contents of process running thread TH. */
+extern td_err_e td_thr_getxregs (const td_thrhandle_t *__th, void *__xregs);
+
+/* Get size of extended register set of process running thread TH. */
+extern td_err_e td_thr_getxregsize (const td_thrhandle_t *__th, int *__sizep);
+
+/* Set floating-point register contents of process running thread TH. */
+extern td_err_e td_thr_setfpregs (const td_thrhandle_t *__th,
+ const prfpregset_t *__fpregs);
+
+/* Set general register contents of process running thread TH. */
+extern td_err_e td_thr_setgregs (const td_thrhandle_t *__th,
+ prgregset_t __gregs);
+
+/* Set extended register contents of process running thread TH. */
+extern td_err_e td_thr_setxregs (const td_thrhandle_t *__th,
+ const void *__addr);
+
+
+/* Enable reporting for EVENT for thread TH. */
+extern td_err_e td_thr_event_enable (const td_thrhandle_t *__th, int __event);
+
+/* Enable EVENT for thread TH. */
+extern td_err_e td_thr_set_event (const td_thrhandle_t *__th,
+ td_thr_events_t *__event);
+
+/* Disable EVENT for thread TH. */
+extern td_err_e td_thr_clear_event (const td_thrhandle_t *__th,
+ td_thr_events_t *__event);
+
+/* Get event message for thread TH. */
+extern td_err_e td_thr_event_getmsg (const td_thrhandle_t *__th,
+ td_event_msg_t *__msg);
+
+
+/* Set priority of thread TH. */
+extern td_err_e td_thr_setprio (const td_thrhandle_t *__th, int __prio);
+
+
+/* Set pending signals for thread TH. */
+extern td_err_e td_thr_setsigpending (const td_thrhandle_t *__th,
+ unsigned char __n, const sigset_t *__ss);
+
+/* Set signal mask for thread TH. */
+extern td_err_e td_thr_sigsetmask (const td_thrhandle_t *__th,
+ const sigset_t *__ss);
+
+
+/* Return thread local data associated with key TK in thread TH. */
+extern td_err_e td_thr_tsd (const td_thrhandle_t *__th,
+ const thread_key_t __tk, void **__data);
+
+
+/* Suspend execution of thread TH. */
+extern td_err_e td_thr_dbsuspend (const td_thrhandle_t *__th);
+
+/* Resume execution of thread TH. */
+extern td_err_e td_thr_dbresume (const td_thrhandle_t *__th);
+
+#endif /* thread_db.h */
+
+#endif /* HAVE_THREAD_DB_H */
diff --git a/gdb/gdb_vfork.h b/gdb/gdb_vfork.h
new file mode 100644
index 00000000000..b9cef96a69f
--- /dev/null
+++ b/gdb/gdb_vfork.h
@@ -0,0 +1,28 @@
+/* GDB-friendly replacement for <vfork.h>.
+ Copyright 2001 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. */
+
+#ifndef GDB_VFORK_H
+#define GDB_VFORK_H
+
+#if HAVE_VFORK_H
+#include <vfork.h>
+#endif
+
+#endif /* GDB_VFORK_H */
diff --git a/gdb/gdb_wait.h b/gdb/gdb_wait.h
new file mode 100644
index 00000000000..fec6f602a83
--- /dev/null
+++ b/gdb/gdb_wait.h
@@ -0,0 +1,121 @@
+/* Standard wait macros.
+ Copyright 2000 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. */
+
+#ifndef GDB_WAIT_H
+#define GDB_WAIT_H
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h> /* POSIX */
+#else
+#ifdef HAVE_WAIT_H
+#include <wait.h> /* legacy */
+#endif
+#endif
+
+/* Define how to access the int that the wait system call stores.
+ This has been compatible in all Unix systems since time immemorial,
+ but various well-meaning people have defined various different
+ words for the same old bits in the same old int (sometimes claimed
+ to be a struct). We just know it's an int and we use these macros
+ to access the bits. */
+
+/* The following macros are defined equivalently to their definitions
+ in POSIX.1. We fail to define WNOHANG and WUNTRACED, which POSIX.1
+ <sys/wait.h> defines, since our code does not use waitpid() (but
+ NOTE exception for GNU/Linux below). We also fail to declare
+ wait() and waitpid(). */
+
+#ifndef WIFEXITED
+#define WIFEXITED(w) (((w)&0377) == 0)
+#endif
+
+#ifndef WIFSIGNALED
+#define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
+#endif
+
+#ifndef WIFSTOPPED
+#ifdef IBM6000
+
+/* Unfortunately, the above comment (about being compatible in all Unix
+ systems) is not quite correct for AIX, sigh. And AIX 3.2 can generate
+ status words like 0x57c (sigtrap received after load), and gdb would
+ choke on it. */
+
+#define WIFSTOPPED(w) ((w)&0x40)
+
+#else
+#define WIFSTOPPED(w) (((w)&0377) == 0177)
+#endif
+#endif
+
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(w) (((w) >> 8) & 0377) /* same as WRETCODE */
+#endif
+
+#ifndef WTERMSIG
+#define WTERMSIG(w) ((w) & 0177)
+#endif
+
+#ifndef WSTOPSIG
+#define WSTOPSIG WEXITSTATUS
+#endif
+
+/* These are not defined in POSIX, but are used by our programs. */
+
+#define WAITTYPE int
+
+#ifndef WCOREDUMP
+#define WCOREDUMP(w) (((w)&0200) != 0)
+#endif
+
+#ifndef WSETEXIT
+# ifdef W_EXITCODE
+#define WSETEXIT(w,status) ((w) = W_EXITCODE(status,0))
+# else
+#define WSETEXIT(w,status) ((w) = (0 | ((status) << 8)))
+# endif
+#endif
+
+#ifndef WSETSTOP
+# ifdef W_STOPCODE
+#define WSETSTOP(w,sig) ((w) = W_STOPCODE(sig))
+# else
+#define WSETSTOP(w,sig) ((w) = (0177 | ((sig) << 8)))
+# endif
+#endif
+
+/* For native GNU/Linux we may use waitpid and the __WCLONE option.
+ <GRIPE> It is of course dangerous not to use the REAL header file...
+ </GRIPE>. */
+
+/* Bits in the third argument to `waitpid'. */
+#ifndef WNOHANG
+#define WNOHANG 1 /* Don't block waiting. */
+#endif
+
+#ifndef WUNTRACED
+#define WUNTRACED 2 /* Report status of stopped children. */
+#endif
+
+#ifndef __WCLONE
+#define __WCLONE 0x80000000 /* Wait for cloned process. */
+#endif
+
+#endif
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
new file mode 100644
index 00000000000..6990953c0c8
--- /dev/null
+++ b/gdb/gdbarch.c
@@ -0,0 +1,5348 @@
+/* *INDENT-OFF* */ /* THIS FILE IS GENERATED */
+
+/* Dynamic architecture support for GDB, the GNU debugger.
+ Copyright 1998, 1999, 2000, 2001, 2002 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. */
+
+/* This file was created with the aid of ``gdbarch.sh''.
+
+ The Bourne shell script ``gdbarch.sh'' creates the files
+ ``new-gdbarch.c'' and ``new-gdbarch.h and then compares them
+ against the existing ``gdbarch.[hc]''. Any differences found
+ being reported.
+
+ If editing this file, please also run gdbarch.sh and merge any
+ changes into that script. Conversely, when making sweeping changes
+ to this file, modifying gdbarch.sh and using its output may prove
+ easier. */
+
+
+#include "defs.h"
+#include "arch-utils.h"
+
+#if GDB_MULTI_ARCH
+#include "gdbcmd.h"
+#include "inferior.h" /* enum CALL_DUMMY_LOCATION et.al. */
+#else
+/* Just include everything in sight so that the every old definition
+ of macro is visible. */
+#include "gdb_string.h"
+#include <ctype.h>
+#include "symtab.h"
+#include "frame.h"
+#include "inferior.h"
+#include "breakpoint.h"
+#include "gdb_wait.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "gdbthread.h"
+#include "annotate.h"
+#include "symfile.h" /* for overlay functions */
+#include "value.h" /* For old tm.h/nm.h macros. */
+#endif
+#include "symcat.h"
+
+#include "floatformat.h"
+
+#include "gdb_assert.h"
+#include "gdb-events.h"
+
+/* Static function declarations */
+
+static void verify_gdbarch (struct gdbarch *gdbarch);
+static void alloc_gdbarch_data (struct gdbarch *);
+static void init_gdbarch_data (struct gdbarch *);
+static void free_gdbarch_data (struct gdbarch *);
+static void init_gdbarch_swap (struct gdbarch *);
+static void clear_gdbarch_swap (struct gdbarch *);
+static void swapout_gdbarch_swap (struct gdbarch *);
+static void swapin_gdbarch_swap (struct gdbarch *);
+
+/* Non-zero if we want to trace architecture code. */
+
+#ifndef GDBARCH_DEBUG
+#define GDBARCH_DEBUG 0
+#endif
+int gdbarch_debug = GDBARCH_DEBUG;
+
+
+/* Maintain the struct gdbarch object */
+
+struct gdbarch
+{
+ /* basic architectural information */
+ const struct bfd_arch_info * bfd_arch_info;
+ int byte_order;
+
+ /* target specific vector. */
+ struct gdbarch_tdep *tdep;
+ gdbarch_dump_tdep_ftype *dump_tdep;
+
+ /* per-architecture data-pointers */
+ unsigned nr_data;
+ void **data;
+
+ /* per-architecture swap-regions */
+ struct gdbarch_swap *swap;
+
+ /* Multi-arch values.
+
+ When extending this structure you must:
+
+ Add the field below.
+
+ Declare set/get functions and define the corresponding
+ macro in gdbarch.h.
+
+ gdbarch_alloc(): If zero/NULL is not a suitable default,
+ initialize the new field.
+
+ verify_gdbarch(): Confirm that the target updated the field
+ correctly.
+
+ gdbarch_dump(): Add a fprintf_unfiltered call so that the new
+ field is dumped out
+
+ ``startup_gdbarch()'': Append an initial value to the static
+ variable (base values on the host's c-type system).
+
+ get_gdbarch(): Implement the set/get functions (probably using
+ the macro's as shortcuts).
+
+ */
+
+ int short_bit;
+ int int_bit;
+ int long_bit;
+ int long_long_bit;
+ int float_bit;
+ int double_bit;
+ int long_double_bit;
+ int ptr_bit;
+ int addr_bit;
+ int bfd_vma_bit;
+ int char_signed;
+ gdbarch_read_pc_ftype *read_pc;
+ gdbarch_write_pc_ftype *write_pc;
+ gdbarch_read_fp_ftype *read_fp;
+ gdbarch_read_sp_ftype *read_sp;
+ gdbarch_write_sp_ftype *write_sp;
+ gdbarch_virtual_frame_pointer_ftype *virtual_frame_pointer;
+ gdbarch_register_read_ftype *register_read;
+ gdbarch_register_write_ftype *register_write;
+ int num_regs;
+ int num_pseudo_regs;
+ int sp_regnum;
+ int fp_regnum;
+ int pc_regnum;
+ int ps_regnum;
+ int fp0_regnum;
+ int npc_regnum;
+ gdbarch_stab_reg_to_regnum_ftype *stab_reg_to_regnum;
+ gdbarch_ecoff_reg_to_regnum_ftype *ecoff_reg_to_regnum;
+ gdbarch_dwarf_reg_to_regnum_ftype *dwarf_reg_to_regnum;
+ gdbarch_sdb_reg_to_regnum_ftype *sdb_reg_to_regnum;
+ gdbarch_dwarf2_reg_to_regnum_ftype *dwarf2_reg_to_regnum;
+ gdbarch_register_name_ftype *register_name;
+ int register_size;
+ int register_bytes;
+ gdbarch_register_byte_ftype *register_byte;
+ gdbarch_register_raw_size_ftype *register_raw_size;
+ int max_register_raw_size;
+ gdbarch_register_virtual_size_ftype *register_virtual_size;
+ int max_register_virtual_size;
+ gdbarch_register_virtual_type_ftype *register_virtual_type;
+ gdbarch_do_registers_info_ftype *do_registers_info;
+ gdbarch_print_float_info_ftype *print_float_info;
+ gdbarch_register_sim_regno_ftype *register_sim_regno;
+ gdbarch_register_bytes_ok_ftype *register_bytes_ok;
+ gdbarch_cannot_fetch_register_ftype *cannot_fetch_register;
+ gdbarch_cannot_store_register_ftype *cannot_store_register;
+ gdbarch_get_longjmp_target_ftype *get_longjmp_target;
+ int use_generic_dummy_frames;
+ int call_dummy_location;
+ gdbarch_call_dummy_address_ftype *call_dummy_address;
+ CORE_ADDR call_dummy_start_offset;
+ CORE_ADDR call_dummy_breakpoint_offset;
+ int call_dummy_breakpoint_offset_p;
+ int call_dummy_length;
+ gdbarch_pc_in_call_dummy_ftype *pc_in_call_dummy;
+ int call_dummy_p;
+ LONGEST * call_dummy_words;
+ int sizeof_call_dummy_words;
+ int call_dummy_stack_adjust_p;
+ int call_dummy_stack_adjust;
+ gdbarch_fix_call_dummy_ftype *fix_call_dummy;
+ gdbarch_init_frame_pc_first_ftype *init_frame_pc_first;
+ gdbarch_init_frame_pc_ftype *init_frame_pc;
+ int believe_pcc_promotion;
+ int believe_pcc_promotion_type;
+ gdbarch_coerce_float_to_double_ftype *coerce_float_to_double;
+ gdbarch_get_saved_register_ftype *get_saved_register;
+ gdbarch_register_convertible_ftype *register_convertible;
+ gdbarch_register_convert_to_virtual_ftype *register_convert_to_virtual;
+ gdbarch_register_convert_to_raw_ftype *register_convert_to_raw;
+ gdbarch_convert_register_p_ftype *convert_register_p;
+ gdbarch_register_to_value_ftype *register_to_value;
+ gdbarch_value_to_register_ftype *value_to_register;
+ gdbarch_fetch_pseudo_register_ftype *fetch_pseudo_register;
+ gdbarch_store_pseudo_register_ftype *store_pseudo_register;
+ gdbarch_pointer_to_address_ftype *pointer_to_address;
+ gdbarch_address_to_pointer_ftype *address_to_pointer;
+ gdbarch_integer_to_address_ftype *integer_to_address;
+ gdbarch_return_value_on_stack_ftype *return_value_on_stack;
+ gdbarch_extract_return_value_ftype *extract_return_value;
+ gdbarch_push_arguments_ftype *push_arguments;
+ gdbarch_push_dummy_frame_ftype *push_dummy_frame;
+ gdbarch_push_return_address_ftype *push_return_address;
+ gdbarch_pop_frame_ftype *pop_frame;
+ gdbarch_store_struct_return_ftype *store_struct_return;
+ gdbarch_store_return_value_ftype *store_return_value;
+ gdbarch_extract_struct_value_address_ftype *extract_struct_value_address;
+ gdbarch_use_struct_convention_ftype *use_struct_convention;
+ gdbarch_frame_init_saved_regs_ftype *frame_init_saved_regs;
+ gdbarch_init_extra_frame_info_ftype *init_extra_frame_info;
+ gdbarch_skip_prologue_ftype *skip_prologue;
+ gdbarch_prologue_frameless_p_ftype *prologue_frameless_p;
+ gdbarch_inner_than_ftype *inner_than;
+ gdbarch_breakpoint_from_pc_ftype *breakpoint_from_pc;
+ gdbarch_memory_insert_breakpoint_ftype *memory_insert_breakpoint;
+ gdbarch_memory_remove_breakpoint_ftype *memory_remove_breakpoint;
+ CORE_ADDR decr_pc_after_break;
+ gdbarch_prepare_to_proceed_ftype *prepare_to_proceed;
+ CORE_ADDR function_start_offset;
+ gdbarch_remote_translate_xfer_address_ftype *remote_translate_xfer_address;
+ CORE_ADDR frame_args_skip;
+ gdbarch_frameless_function_invocation_ftype *frameless_function_invocation;
+ gdbarch_frame_chain_ftype *frame_chain;
+ gdbarch_frame_chain_valid_ftype *frame_chain_valid;
+ gdbarch_frame_saved_pc_ftype *frame_saved_pc;
+ gdbarch_frame_args_address_ftype *frame_args_address;
+ gdbarch_frame_locals_address_ftype *frame_locals_address;
+ gdbarch_saved_pc_after_call_ftype *saved_pc_after_call;
+ gdbarch_frame_num_args_ftype *frame_num_args;
+ gdbarch_stack_align_ftype *stack_align;
+ int extra_stack_alignment_needed;
+ gdbarch_reg_struct_has_addr_ftype *reg_struct_has_addr;
+ gdbarch_save_dummy_frame_tos_ftype *save_dummy_frame_tos;
+ int parm_boundary;
+ const struct floatformat * float_format;
+ const struct floatformat * double_format;
+ const struct floatformat * long_double_format;
+ gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr;
+ gdbarch_addr_bits_remove_ftype *addr_bits_remove;
+ gdbarch_smash_text_address_ftype *smash_text_address;
+ gdbarch_software_single_step_ftype *software_single_step;
+ gdbarch_print_insn_ftype *print_insn;
+ gdbarch_skip_trampoline_code_ftype *skip_trampoline_code;
+ gdbarch_in_solib_call_trampoline_ftype *in_solib_call_trampoline;
+ gdbarch_pc_in_sigtramp_ftype *pc_in_sigtramp;
+ gdbarch_in_function_epilogue_p_ftype *in_function_epilogue_p;
+ gdbarch_construct_inferior_arguments_ftype *construct_inferior_arguments;
+ gdbarch_dwarf2_build_frame_info_ftype *dwarf2_build_frame_info;
+ gdbarch_elf_make_msymbol_special_ftype *elf_make_msymbol_special;
+ gdbarch_coff_make_msymbol_special_ftype *coff_make_msymbol_special;
+};
+
+
+/* The default architecture uses host values (for want of a better
+ choice). */
+
+extern const struct bfd_arch_info bfd_default_arch_struct;
+
+struct gdbarch startup_gdbarch =
+{
+ /* basic architecture information */
+ &bfd_default_arch_struct,
+ BFD_ENDIAN_BIG,
+ /* target specific vector and its dump routine */
+ NULL, NULL,
+ /*per-architecture data-pointers and swap regions */
+ 0, NULL, NULL,
+ /* Multi-arch values */
+ 8 * sizeof (short),
+ 8 * sizeof (int),
+ 8 * sizeof (long),
+ 8 * sizeof (LONGEST),
+ 8 * sizeof (float),
+ 8 * sizeof (double),
+ 8 * sizeof (long double),
+ 8 * sizeof (void*),
+ 8 * sizeof (void*),
+ 8 * sizeof (void*),
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ -1,
+ -1,
+ -1,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ generic_register_size,
+ 0,
+ generic_register_size,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ generic_get_saved_register,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ generic_in_function_epilogue_p,
+ construct_inferior_arguments,
+ 0,
+ 0,
+ 0,
+ /* startup_gdbarch() */
+};
+
+struct gdbarch *current_gdbarch = &startup_gdbarch;
+
+/* Do any initialization needed for a non-multiarch configuration
+ after the _initialize_MODULE functions have been run. */
+void
+initialize_non_multiarch ()
+{
+ alloc_gdbarch_data (&startup_gdbarch);
+ /* Ensure that all swap areas are zeroed so that they again think
+ they are starting from scratch. */
+ clear_gdbarch_swap (&startup_gdbarch);
+ init_gdbarch_swap (&startup_gdbarch);
+ init_gdbarch_data (&startup_gdbarch);
+}
+
+
+/* Create a new ``struct gdbarch'' based on information provided by
+ ``struct gdbarch_info''. */
+
+struct gdbarch *
+gdbarch_alloc (const struct gdbarch_info *info,
+ struct gdbarch_tdep *tdep)
+{
+ /* NOTE: The new architecture variable is named ``current_gdbarch''
+ so that macros such as TARGET_DOUBLE_BIT, when expanded, refer to
+ the current local architecture and not the previous global
+ architecture. This ensures that the new architectures initial
+ values are not influenced by the previous architecture. Once
+ everything is parameterised with gdbarch, this will go away. */
+ struct gdbarch *current_gdbarch = XMALLOC (struct gdbarch);
+ memset (current_gdbarch, 0, sizeof (*current_gdbarch));
+
+ alloc_gdbarch_data (current_gdbarch);
+
+ current_gdbarch->tdep = tdep;
+
+ current_gdbarch->bfd_arch_info = info->bfd_arch_info;
+ current_gdbarch->byte_order = info->byte_order;
+
+ /* Force the explicit initialization of these. */
+ current_gdbarch->short_bit = 2*TARGET_CHAR_BIT;
+ current_gdbarch->int_bit = 4*TARGET_CHAR_BIT;
+ current_gdbarch->long_bit = 4*TARGET_CHAR_BIT;
+ current_gdbarch->long_long_bit = 2*TARGET_LONG_BIT;
+ current_gdbarch->float_bit = 4*TARGET_CHAR_BIT;
+ current_gdbarch->double_bit = 8*TARGET_CHAR_BIT;
+ current_gdbarch->long_double_bit = 8*TARGET_CHAR_BIT;
+ current_gdbarch->ptr_bit = TARGET_INT_BIT;
+ current_gdbarch->bfd_vma_bit = TARGET_ARCHITECTURE->bits_per_address;
+ current_gdbarch->char_signed = -1;
+ current_gdbarch->read_pc = generic_target_read_pc;
+ current_gdbarch->write_pc = generic_target_write_pc;
+ current_gdbarch->read_fp = generic_target_read_fp;
+ current_gdbarch->read_sp = generic_target_read_sp;
+ current_gdbarch->write_sp = generic_target_write_sp;
+ current_gdbarch->virtual_frame_pointer = legacy_virtual_frame_pointer;
+ current_gdbarch->num_regs = -1;
+ current_gdbarch->sp_regnum = -1;
+ current_gdbarch->fp_regnum = -1;
+ current_gdbarch->pc_regnum = -1;
+ current_gdbarch->ps_regnum = -1;
+ current_gdbarch->fp0_regnum = -1;
+ current_gdbarch->npc_regnum = -1;
+ current_gdbarch->stab_reg_to_regnum = no_op_reg_to_regnum;
+ current_gdbarch->ecoff_reg_to_regnum = no_op_reg_to_regnum;
+ current_gdbarch->dwarf_reg_to_regnum = no_op_reg_to_regnum;
+ current_gdbarch->sdb_reg_to_regnum = no_op_reg_to_regnum;
+ current_gdbarch->dwarf2_reg_to_regnum = no_op_reg_to_regnum;
+ current_gdbarch->register_name = legacy_register_name;
+ current_gdbarch->register_size = -1;
+ current_gdbarch->register_bytes = -1;
+ current_gdbarch->register_raw_size = generic_register_size;
+ current_gdbarch->max_register_raw_size = -1;
+ current_gdbarch->register_virtual_size = generic_register_size;
+ current_gdbarch->max_register_virtual_size = -1;
+ current_gdbarch->do_registers_info = do_registers_info;
+ current_gdbarch->print_float_info = default_print_float_info;
+ current_gdbarch->register_sim_regno = default_register_sim_regno;
+ current_gdbarch->cannot_fetch_register = cannot_register_not;
+ current_gdbarch->cannot_store_register = cannot_register_not;
+ current_gdbarch->use_generic_dummy_frames = -1;
+ current_gdbarch->call_dummy_start_offset = -1;
+ current_gdbarch->call_dummy_breakpoint_offset = -1;
+ current_gdbarch->call_dummy_breakpoint_offset_p = -1;
+ current_gdbarch->call_dummy_length = -1;
+ current_gdbarch->call_dummy_p = -1;
+ current_gdbarch->call_dummy_words = legacy_call_dummy_words;
+ current_gdbarch->sizeof_call_dummy_words = legacy_sizeof_call_dummy_words;
+ current_gdbarch->call_dummy_stack_adjust_p = -1;
+ current_gdbarch->init_frame_pc_first = init_frame_pc_noop;
+ current_gdbarch->init_frame_pc = init_frame_pc_default;
+ current_gdbarch->coerce_float_to_double = default_coerce_float_to_double;
+ current_gdbarch->register_convertible = generic_register_convertible_not;
+ current_gdbarch->convert_register_p = legacy_convert_register_p;
+ current_gdbarch->register_to_value = legacy_register_to_value;
+ current_gdbarch->value_to_register = legacy_value_to_register;
+ current_gdbarch->pointer_to_address = unsigned_pointer_to_address;
+ current_gdbarch->address_to_pointer = unsigned_address_to_pointer;
+ current_gdbarch->return_value_on_stack = generic_return_value_on_stack_not;
+ current_gdbarch->push_arguments = default_push_arguments;
+ current_gdbarch->use_struct_convention = generic_use_struct_convention;
+ current_gdbarch->prologue_frameless_p = generic_prologue_frameless_p;
+ current_gdbarch->breakpoint_from_pc = legacy_breakpoint_from_pc;
+ current_gdbarch->memory_insert_breakpoint = default_memory_insert_breakpoint;
+ current_gdbarch->memory_remove_breakpoint = default_memory_remove_breakpoint;
+ current_gdbarch->decr_pc_after_break = -1;
+ current_gdbarch->prepare_to_proceed = default_prepare_to_proceed;
+ current_gdbarch->function_start_offset = -1;
+ current_gdbarch->remote_translate_xfer_address = generic_remote_translate_xfer_address;
+ current_gdbarch->frame_args_skip = -1;
+ current_gdbarch->frameless_function_invocation = generic_frameless_function_invocation_not;
+ current_gdbarch->frame_chain_valid = func_frame_chain_valid;
+ current_gdbarch->extra_stack_alignment_needed = 1;
+ current_gdbarch->convert_from_func_ptr_addr = core_addr_identity;
+ current_gdbarch->addr_bits_remove = core_addr_identity;
+ current_gdbarch->smash_text_address = core_addr_identity;
+ current_gdbarch->print_insn = legacy_print_insn;
+ current_gdbarch->skip_trampoline_code = generic_skip_trampoline_code;
+ current_gdbarch->in_solib_call_trampoline = generic_in_solib_call_trampoline;
+ current_gdbarch->pc_in_sigtramp = legacy_pc_in_sigtramp;
+ current_gdbarch->in_function_epilogue_p = generic_in_function_epilogue_p;
+ current_gdbarch->construct_inferior_arguments = construct_inferior_arguments;
+ current_gdbarch->elf_make_msymbol_special = default_elf_make_msymbol_special;
+ current_gdbarch->coff_make_msymbol_special = default_coff_make_msymbol_special;
+ /* gdbarch_alloc() */
+
+ return current_gdbarch;
+}
+
+
+/* Free a gdbarch struct. This should never happen in normal
+ operation --- once you've created a gdbarch, you keep it around.
+ However, if an architecture's init function encounters an error
+ building the structure, it may need to clean up a partially
+ constructed gdbarch. */
+
+void
+gdbarch_free (struct gdbarch *arch)
+{
+ gdb_assert (arch != NULL);
+ free_gdbarch_data (arch);
+ xfree (arch);
+}
+
+
+/* Ensure that all values in a GDBARCH are reasonable. */
+
+static void
+verify_gdbarch (struct gdbarch *gdbarch)
+{
+ struct ui_file *log;
+ struct cleanup *cleanups;
+ long dummy;
+ char *buf;
+ /* Only perform sanity checks on a multi-arch target. */
+ if (!GDB_MULTI_ARCH)
+ return;
+ log = mem_fileopen ();
+ cleanups = make_cleanup_ui_file_delete (log);
+ /* fundamental */
+ if (gdbarch->byte_order == BFD_ENDIAN_UNKNOWN)
+ fprintf_unfiltered (log, "\n\tbyte-order");
+ if (gdbarch->bfd_arch_info == NULL)
+ fprintf_unfiltered (log, "\n\tbfd_arch_info");
+ /* Check those that need to be defined for the given multi-arch level. */
+ /* Skip verify of short_bit, invalid_p == 0 */
+ /* Skip verify of int_bit, invalid_p == 0 */
+ /* Skip verify of long_bit, invalid_p == 0 */
+ /* Skip verify of long_long_bit, invalid_p == 0 */
+ /* Skip verify of float_bit, invalid_p == 0 */
+ /* Skip verify of double_bit, invalid_p == 0 */
+ /* Skip verify of long_double_bit, invalid_p == 0 */
+ /* Skip verify of ptr_bit, invalid_p == 0 */
+ if (gdbarch->addr_bit == 0)
+ gdbarch->addr_bit = TARGET_PTR_BIT;
+ /* Skip verify of bfd_vma_bit, invalid_p == 0 */
+ if (gdbarch->char_signed == -1)
+ gdbarch->char_signed = 1;
+ /* Skip verify of read_pc, invalid_p == 0 */
+ /* Skip verify of write_pc, invalid_p == 0 */
+ /* Skip verify of read_fp, invalid_p == 0 */
+ /* Skip verify of read_sp, invalid_p == 0 */
+ /* Skip verify of write_sp, invalid_p == 0 */
+ /* Skip verify of virtual_frame_pointer, invalid_p == 0 */
+ /* Skip verify of register_read, has predicate */
+ /* Skip verify of register_write, has predicate */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->num_regs == -1))
+ fprintf_unfiltered (log, "\n\tnum_regs");
+ /* Skip verify of num_pseudo_regs, invalid_p == 0 */
+ /* Skip verify of sp_regnum, invalid_p == 0 */
+ /* Skip verify of fp_regnum, invalid_p == 0 */
+ /* Skip verify of pc_regnum, invalid_p == 0 */
+ /* Skip verify of ps_regnum, invalid_p == 0 */
+ /* Skip verify of fp0_regnum, invalid_p == 0 */
+ /* Skip verify of npc_regnum, invalid_p == 0 */
+ /* Skip verify of stab_reg_to_regnum, invalid_p == 0 */
+ /* Skip verify of ecoff_reg_to_regnum, invalid_p == 0 */
+ /* Skip verify of dwarf_reg_to_regnum, invalid_p == 0 */
+ /* Skip verify of sdb_reg_to_regnum, invalid_p == 0 */
+ /* Skip verify of dwarf2_reg_to_regnum, invalid_p == 0 */
+ /* Skip verify of register_name, invalid_p == 0 */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->register_size == -1))
+ fprintf_unfiltered (log, "\n\tregister_size");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->register_bytes == -1))
+ fprintf_unfiltered (log, "\n\tregister_bytes");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->register_byte == 0))
+ fprintf_unfiltered (log, "\n\tregister_byte");
+ /* Skip verify of register_raw_size, invalid_p == 0 */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->max_register_raw_size == -1))
+ fprintf_unfiltered (log, "\n\tmax_register_raw_size");
+ /* Skip verify of register_virtual_size, invalid_p == 0 */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->max_register_virtual_size == -1))
+ fprintf_unfiltered (log, "\n\tmax_register_virtual_size");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->register_virtual_type == 0))
+ fprintf_unfiltered (log, "\n\tregister_virtual_type");
+ /* Skip verify of do_registers_info, invalid_p == 0 */
+ /* Skip verify of print_float_info, invalid_p == 0 */
+ /* Skip verify of register_sim_regno, invalid_p == 0 */
+ /* Skip verify of register_bytes_ok, has predicate */
+ /* Skip verify of cannot_fetch_register, invalid_p == 0 */
+ /* Skip verify of cannot_store_register, invalid_p == 0 */
+ /* Skip verify of get_longjmp_target, has predicate */
+ if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->use_generic_dummy_frames == -1))
+ fprintf_unfiltered (log, "\n\tuse_generic_dummy_frames");
+ if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->call_dummy_location == 0))
+ fprintf_unfiltered (log, "\n\tcall_dummy_location");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->call_dummy_location == AT_ENTRY_POINT && gdbarch->call_dummy_address == 0))
+ fprintf_unfiltered (log, "\n\tcall_dummy_address");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->call_dummy_start_offset == -1))
+ fprintf_unfiltered (log, "\n\tcall_dummy_start_offset");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->call_dummy_breakpoint_offset_p && gdbarch->call_dummy_breakpoint_offset == -1))
+ fprintf_unfiltered (log, "\n\tcall_dummy_breakpoint_offset");
+ if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->call_dummy_breakpoint_offset_p == -1))
+ fprintf_unfiltered (log, "\n\tcall_dummy_breakpoint_offset_p");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->call_dummy_length == -1))
+ fprintf_unfiltered (log, "\n\tcall_dummy_length");
+ if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->pc_in_call_dummy == 0))
+ fprintf_unfiltered (log, "\n\tpc_in_call_dummy");
+ if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->call_dummy_p == -1))
+ fprintf_unfiltered (log, "\n\tcall_dummy_p");
+ /* Skip verify of call_dummy_words, invalid_p == 0 */
+ /* Skip verify of sizeof_call_dummy_words, invalid_p == 0 */
+ if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->call_dummy_stack_adjust_p == -1))
+ fprintf_unfiltered (log, "\n\tcall_dummy_stack_adjust_p");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->call_dummy_stack_adjust_p && gdbarch->call_dummy_stack_adjust == 0))
+ fprintf_unfiltered (log, "\n\tcall_dummy_stack_adjust");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->fix_call_dummy == 0))
+ fprintf_unfiltered (log, "\n\tfix_call_dummy");
+ /* Skip verify of init_frame_pc_first, invalid_p == 0 */
+ /* Skip verify of init_frame_pc, invalid_p == 0 */
+ /* Skip verify of coerce_float_to_double, invalid_p == 0 */
+ if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->get_saved_register == 0))
+ fprintf_unfiltered (log, "\n\tget_saved_register");
+ /* Skip verify of register_convertible, invalid_p == 0 */
+ /* Skip verify of register_convert_to_virtual, invalid_p == 0 */
+ /* Skip verify of register_convert_to_raw, invalid_p == 0 */
+ /* Skip verify of convert_register_p, invalid_p == 0 */
+ /* Skip verify of register_to_value, invalid_p == 0 */
+ /* Skip verify of value_to_register, invalid_p == 0 */
+ /* Skip verify of fetch_pseudo_register, has predicate */
+ /* Skip verify of store_pseudo_register, has predicate */
+ /* Skip verify of pointer_to_address, invalid_p == 0 */
+ /* Skip verify of address_to_pointer, invalid_p == 0 */
+ /* Skip verify of integer_to_address, has predicate */
+ /* Skip verify of return_value_on_stack, invalid_p == 0 */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->extract_return_value == 0))
+ fprintf_unfiltered (log, "\n\textract_return_value");
+ /* Skip verify of push_arguments, invalid_p == 0 */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->push_dummy_frame == 0))
+ fprintf_unfiltered (log, "\n\tpush_dummy_frame");
+ /* Skip verify of push_return_address, has predicate */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->pop_frame == 0))
+ fprintf_unfiltered (log, "\n\tpop_frame");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->store_struct_return == 0))
+ fprintf_unfiltered (log, "\n\tstore_struct_return");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->store_return_value == 0))
+ fprintf_unfiltered (log, "\n\tstore_return_value");
+ /* Skip verify of extract_struct_value_address, has predicate */
+ /* Skip verify of use_struct_convention, invalid_p == 0 */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->frame_init_saved_regs == 0))
+ fprintf_unfiltered (log, "\n\tframe_init_saved_regs");
+ /* Skip verify of init_extra_frame_info, has predicate */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->skip_prologue == 0))
+ fprintf_unfiltered (log, "\n\tskip_prologue");
+ /* Skip verify of prologue_frameless_p, invalid_p == 0 */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->inner_than == 0))
+ fprintf_unfiltered (log, "\n\tinner_than");
+ /* Skip verify of breakpoint_from_pc, invalid_p == 0 */
+ /* Skip verify of memory_insert_breakpoint, invalid_p == 0 */
+ /* Skip verify of memory_remove_breakpoint, invalid_p == 0 */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->decr_pc_after_break == -1))
+ fprintf_unfiltered (log, "\n\tdecr_pc_after_break");
+ /* Skip verify of prepare_to_proceed, invalid_p == 0 */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->function_start_offset == -1))
+ fprintf_unfiltered (log, "\n\tfunction_start_offset");
+ /* Skip verify of remote_translate_xfer_address, invalid_p == 0 */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->frame_args_skip == -1))
+ fprintf_unfiltered (log, "\n\tframe_args_skip");
+ /* Skip verify of frameless_function_invocation, invalid_p == 0 */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->frame_chain == 0))
+ fprintf_unfiltered (log, "\n\tframe_chain");
+ /* Skip verify of frame_chain_valid, invalid_p == 0 */
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->frame_saved_pc == 0))
+ fprintf_unfiltered (log, "\n\tframe_saved_pc");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->frame_args_address == 0))
+ fprintf_unfiltered (log, "\n\tframe_args_address");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->frame_locals_address == 0))
+ fprintf_unfiltered (log, "\n\tframe_locals_address");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->saved_pc_after_call == 0))
+ fprintf_unfiltered (log, "\n\tsaved_pc_after_call");
+ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ && (gdbarch->frame_num_args == 0))
+ fprintf_unfiltered (log, "\n\tframe_num_args");
+ /* Skip verify of stack_align, has predicate */
+ /* Skip verify of extra_stack_alignment_needed, invalid_p == 0 */
+ /* Skip verify of reg_struct_has_addr, has predicate */
+ /* Skip verify of save_dummy_frame_tos, has predicate */
+ if (gdbarch->float_format == 0)
+ gdbarch->float_format = default_float_format (gdbarch);
+ if (gdbarch->double_format == 0)
+ gdbarch->double_format = default_double_format (gdbarch);
+ if (gdbarch->long_double_format == 0)
+ gdbarch->long_double_format = default_double_format (gdbarch);
+ /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */
+ /* Skip verify of addr_bits_remove, invalid_p == 0 */
+ /* Skip verify of smash_text_address, invalid_p == 0 */
+ /* Skip verify of software_single_step, has predicate */
+ /* Skip verify of print_insn, invalid_p == 0 */
+ /* Skip verify of skip_trampoline_code, invalid_p == 0 */
+ /* Skip verify of in_solib_call_trampoline, invalid_p == 0 */
+ /* Skip verify of pc_in_sigtramp, invalid_p == 0 */
+ /* Skip verify of in_function_epilogue_p, invalid_p == 0 */
+ /* Skip verify of construct_inferior_arguments, invalid_p == 0 */
+ /* Skip verify of dwarf2_build_frame_info, has predicate */
+ /* Skip verify of elf_make_msymbol_special, invalid_p == 0 */
+ /* Skip verify of coff_make_msymbol_special, invalid_p == 0 */
+ buf = ui_file_xstrdup (log, &dummy);
+ make_cleanup (xfree, buf);
+ if (strlen (buf) > 0)
+ internal_error (__FILE__, __LINE__,
+ "verify_gdbarch: the following are invalid ...%s",
+ buf);
+ do_cleanups (cleanups);
+}
+
+
+/* Print out the details of the current architecture. */
+
+/* NOTE/WARNING: The parameter is called ``current_gdbarch'' so that it
+ just happens to match the global variable ``current_gdbarch''. That
+ way macros refering to that variable get the local and not the global
+ version - ulgh. Once everything is parameterised with gdbarch, this
+ will go away. */
+
+void
+gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
+{
+ fprintf_unfiltered (file,
+ "gdbarch_dump: GDB_MULTI_ARCH = %d\n",
+ GDB_MULTI_ARCH);
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: in_function_epilogue_p = 0x%08lx\n",
+ (long) current_gdbarch->in_function_epilogue_p);
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: register_read = 0x%08lx\n",
+ (long) current_gdbarch->register_read);
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: register_write = 0x%08lx\n",
+ (long) current_gdbarch->register_write);
+#ifdef ADDRESS_TO_POINTER
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "ADDRESS_TO_POINTER(type, buf, addr)",
+ XSTRING (ADDRESS_TO_POINTER (type, buf, addr)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: ADDRESS_TO_POINTER = 0x%08lx\n",
+ (long) current_gdbarch->address_to_pointer
+ /*ADDRESS_TO_POINTER ()*/);
+#endif
+#ifdef ADDR_BITS_REMOVE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "ADDR_BITS_REMOVE(addr)",
+ XSTRING (ADDR_BITS_REMOVE (addr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: ADDR_BITS_REMOVE = 0x%08lx\n",
+ (long) current_gdbarch->addr_bits_remove
+ /*ADDR_BITS_REMOVE ()*/);
+#endif
+#ifdef BELIEVE_PCC_PROMOTION
+ fprintf_unfiltered (file,
+ "gdbarch_dump: BELIEVE_PCC_PROMOTION # %s\n",
+ XSTRING (BELIEVE_PCC_PROMOTION));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: BELIEVE_PCC_PROMOTION = %d\n",
+ BELIEVE_PCC_PROMOTION);
+#endif
+#ifdef BELIEVE_PCC_PROMOTION_TYPE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: BELIEVE_PCC_PROMOTION_TYPE # %s\n",
+ XSTRING (BELIEVE_PCC_PROMOTION_TYPE));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: BELIEVE_PCC_PROMOTION_TYPE = %d\n",
+ BELIEVE_PCC_PROMOTION_TYPE);
+#endif
+#ifdef BREAKPOINT_FROM_PC
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "BREAKPOINT_FROM_PC(pcptr, lenptr)",
+ XSTRING (BREAKPOINT_FROM_PC (pcptr, lenptr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: BREAKPOINT_FROM_PC = 0x%08lx\n",
+ (long) current_gdbarch->breakpoint_from_pc
+ /*BREAKPOINT_FROM_PC ()*/);
+#endif
+#ifdef CALL_DUMMY_ADDRESS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "CALL_DUMMY_ADDRESS()",
+ XSTRING (CALL_DUMMY_ADDRESS ()));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_ADDRESS = 0x%08lx\n",
+ (long) current_gdbarch->call_dummy_address
+ /*CALL_DUMMY_ADDRESS ()*/);
+#endif
+#ifdef CALL_DUMMY_BREAKPOINT_OFFSET
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_BREAKPOINT_OFFSET # %s\n",
+ XSTRING (CALL_DUMMY_BREAKPOINT_OFFSET));
+ if (CALL_DUMMY_BREAKPOINT_OFFSET_P)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_BREAKPOINT_OFFSET = 0x%08lx\n",
+ (long) CALL_DUMMY_BREAKPOINT_OFFSET);
+#endif
+#ifdef CALL_DUMMY_BREAKPOINT_OFFSET_P
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_BREAKPOINT_OFFSET_P # %s\n",
+ XSTRING (CALL_DUMMY_BREAKPOINT_OFFSET_P));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_BREAKPOINT_OFFSET_P = %d\n",
+ CALL_DUMMY_BREAKPOINT_OFFSET_P);
+#endif
+#ifdef CALL_DUMMY_LENGTH
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_LENGTH # %s\n",
+ XSTRING (CALL_DUMMY_LENGTH));
+ if (CALL_DUMMY_LOCATION == BEFORE_TEXT_END || CALL_DUMMY_LOCATION == AFTER_TEXT_END)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_LENGTH = %d\n",
+ CALL_DUMMY_LENGTH);
+#endif
+#ifdef CALL_DUMMY_LOCATION
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_LOCATION # %s\n",
+ XSTRING (CALL_DUMMY_LOCATION));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_LOCATION = %d\n",
+ CALL_DUMMY_LOCATION);
+#endif
+#ifdef CALL_DUMMY_P
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_P # %s\n",
+ XSTRING (CALL_DUMMY_P));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_P = %d\n",
+ CALL_DUMMY_P);
+#endif
+#ifdef CALL_DUMMY_STACK_ADJUST
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_STACK_ADJUST # %s\n",
+ XSTRING (CALL_DUMMY_STACK_ADJUST));
+ if (CALL_DUMMY_STACK_ADJUST_P)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_STACK_ADJUST = 0x%08lx\n",
+ (long) CALL_DUMMY_STACK_ADJUST);
+#endif
+#ifdef CALL_DUMMY_STACK_ADJUST_P
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_STACK_ADJUST_P # %s\n",
+ XSTRING (CALL_DUMMY_STACK_ADJUST_P));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_STACK_ADJUST_P = 0x%08lx\n",
+ (long) CALL_DUMMY_STACK_ADJUST_P);
+#endif
+#ifdef CALL_DUMMY_START_OFFSET
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_START_OFFSET # %s\n",
+ XSTRING (CALL_DUMMY_START_OFFSET));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_START_OFFSET = 0x%08lx\n",
+ (long) CALL_DUMMY_START_OFFSET);
+#endif
+#ifdef CALL_DUMMY_WORDS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_WORDS # %s\n",
+ XSTRING (CALL_DUMMY_WORDS));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CALL_DUMMY_WORDS = 0x%08lx\n",
+ (long) CALL_DUMMY_WORDS);
+#endif
+#ifdef CANNOT_FETCH_REGISTER
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "CANNOT_FETCH_REGISTER(regnum)",
+ XSTRING (CANNOT_FETCH_REGISTER (regnum)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CANNOT_FETCH_REGISTER = 0x%08lx\n",
+ (long) current_gdbarch->cannot_fetch_register
+ /*CANNOT_FETCH_REGISTER ()*/);
+#endif
+#ifdef CANNOT_STORE_REGISTER
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "CANNOT_STORE_REGISTER(regnum)",
+ XSTRING (CANNOT_STORE_REGISTER (regnum)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CANNOT_STORE_REGISTER = 0x%08lx\n",
+ (long) current_gdbarch->cannot_store_register
+ /*CANNOT_STORE_REGISTER ()*/);
+#endif
+#ifdef COERCE_FLOAT_TO_DOUBLE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "COERCE_FLOAT_TO_DOUBLE(formal, actual)",
+ XSTRING (COERCE_FLOAT_TO_DOUBLE (formal, actual)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: COERCE_FLOAT_TO_DOUBLE = 0x%08lx\n",
+ (long) current_gdbarch->coerce_float_to_double
+ /*COERCE_FLOAT_TO_DOUBLE ()*/);
+#endif
+#ifdef COFF_MAKE_MSYMBOL_SPECIAL
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "COFF_MAKE_MSYMBOL_SPECIAL(val, msym)",
+ XSTRING (COFF_MAKE_MSYMBOL_SPECIAL (val, msym)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: COFF_MAKE_MSYMBOL_SPECIAL = 0x%08lx\n",
+ (long) current_gdbarch->coff_make_msymbol_special
+ /*COFF_MAKE_MSYMBOL_SPECIAL ()*/);
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: construct_inferior_arguments = 0x%08lx\n",
+ (long) current_gdbarch->construct_inferior_arguments);
+#ifdef CONVERT_FROM_FUNC_PTR_ADDR
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "CONVERT_FROM_FUNC_PTR_ADDR(addr)",
+ XSTRING (CONVERT_FROM_FUNC_PTR_ADDR (addr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CONVERT_FROM_FUNC_PTR_ADDR = 0x%08lx\n",
+ (long) current_gdbarch->convert_from_func_ptr_addr
+ /*CONVERT_FROM_FUNC_PTR_ADDR ()*/);
+#endif
+#ifdef CONVERT_REGISTER_P
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "CONVERT_REGISTER_P(regnum)",
+ XSTRING (CONVERT_REGISTER_P (regnum)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CONVERT_REGISTER_P = 0x%08lx\n",
+ (long) current_gdbarch->convert_register_p
+ /*CONVERT_REGISTER_P ()*/);
+#endif
+#ifdef DECR_PC_AFTER_BREAK
+ fprintf_unfiltered (file,
+ "gdbarch_dump: DECR_PC_AFTER_BREAK # %s\n",
+ XSTRING (DECR_PC_AFTER_BREAK));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: DECR_PC_AFTER_BREAK = %ld\n",
+ (long) DECR_PC_AFTER_BREAK);
+#endif
+#ifdef DO_REGISTERS_INFO
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "DO_REGISTERS_INFO(reg_nr, fpregs)",
+ XSTRING (DO_REGISTERS_INFO (reg_nr, fpregs)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: DO_REGISTERS_INFO = 0x%08lx\n",
+ (long) current_gdbarch->do_registers_info
+ /*DO_REGISTERS_INFO ()*/);
+#endif
+#ifdef DWARF2_BUILD_FRAME_INFO
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "DWARF2_BUILD_FRAME_INFO(objfile)",
+ XSTRING (DWARF2_BUILD_FRAME_INFO (objfile)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: DWARF2_BUILD_FRAME_INFO = 0x%08lx\n",
+ (long) current_gdbarch->dwarf2_build_frame_info
+ /*DWARF2_BUILD_FRAME_INFO ()*/);
+#endif
+#ifdef DWARF2_REG_TO_REGNUM
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "DWARF2_REG_TO_REGNUM(dwarf2_regnr)",
+ XSTRING (DWARF2_REG_TO_REGNUM (dwarf2_regnr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: DWARF2_REG_TO_REGNUM = 0x%08lx\n",
+ (long) current_gdbarch->dwarf2_reg_to_regnum
+ /*DWARF2_REG_TO_REGNUM ()*/);
+#endif
+#ifdef DWARF_REG_TO_REGNUM
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "DWARF_REG_TO_REGNUM(dwarf_regnr)",
+ XSTRING (DWARF_REG_TO_REGNUM (dwarf_regnr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: DWARF_REG_TO_REGNUM = 0x%08lx\n",
+ (long) current_gdbarch->dwarf_reg_to_regnum
+ /*DWARF_REG_TO_REGNUM ()*/);
+#endif
+#ifdef ECOFF_REG_TO_REGNUM
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "ECOFF_REG_TO_REGNUM(ecoff_regnr)",
+ XSTRING (ECOFF_REG_TO_REGNUM (ecoff_regnr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: ECOFF_REG_TO_REGNUM = 0x%08lx\n",
+ (long) current_gdbarch->ecoff_reg_to_regnum
+ /*ECOFF_REG_TO_REGNUM ()*/);
+#endif
+#ifdef ELF_MAKE_MSYMBOL_SPECIAL
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "ELF_MAKE_MSYMBOL_SPECIAL(sym, msym)",
+ XSTRING (ELF_MAKE_MSYMBOL_SPECIAL (sym, msym)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: ELF_MAKE_MSYMBOL_SPECIAL = 0x%08lx\n",
+ (long) current_gdbarch->elf_make_msymbol_special
+ /*ELF_MAKE_MSYMBOL_SPECIAL ()*/);
+#endif
+#ifdef EXTRACT_RETURN_VALUE
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "EXTRACT_RETURN_VALUE(type, regbuf, valbuf)",
+ XSTRING (EXTRACT_RETURN_VALUE (type, regbuf, valbuf)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: EXTRACT_RETURN_VALUE = 0x%08lx\n",
+ (long) current_gdbarch->extract_return_value
+ /*EXTRACT_RETURN_VALUE ()*/);
+#endif
+#ifdef EXTRACT_STRUCT_VALUE_ADDRESS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "EXTRACT_STRUCT_VALUE_ADDRESS(regbuf)",
+ XSTRING (EXTRACT_STRUCT_VALUE_ADDRESS (regbuf)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: EXTRACT_STRUCT_VALUE_ADDRESS = 0x%08lx\n",
+ (long) current_gdbarch->extract_struct_value_address
+ /*EXTRACT_STRUCT_VALUE_ADDRESS ()*/);
+#endif
+#ifdef EXTRA_STACK_ALIGNMENT_NEEDED
+ fprintf_unfiltered (file,
+ "gdbarch_dump: EXTRA_STACK_ALIGNMENT_NEEDED # %s\n",
+ XSTRING (EXTRA_STACK_ALIGNMENT_NEEDED));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: EXTRA_STACK_ALIGNMENT_NEEDED = %d\n",
+ EXTRA_STACK_ALIGNMENT_NEEDED);
+#endif
+#ifdef FETCH_PSEUDO_REGISTER
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "FETCH_PSEUDO_REGISTER(regnum)",
+ XSTRING (FETCH_PSEUDO_REGISTER (regnum)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FETCH_PSEUDO_REGISTER = 0x%08lx\n",
+ (long) current_gdbarch->fetch_pseudo_register
+ /*FETCH_PSEUDO_REGISTER ()*/);
+#endif
+#ifdef FIX_CALL_DUMMY
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "FIX_CALL_DUMMY(dummy, pc, fun, nargs, args, type, gcc_p)",
+ XSTRING (FIX_CALL_DUMMY (dummy, pc, fun, nargs, args, type, gcc_p)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FIX_CALL_DUMMY = 0x%08lx\n",
+ (long) current_gdbarch->fix_call_dummy
+ /*FIX_CALL_DUMMY ()*/);
+#endif
+#ifdef FP0_REGNUM
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FP0_REGNUM # %s\n",
+ XSTRING (FP0_REGNUM));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FP0_REGNUM = %d\n",
+ FP0_REGNUM);
+#endif
+#ifdef FP_REGNUM
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FP_REGNUM # %s\n",
+ XSTRING (FP_REGNUM));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FP_REGNUM = %d\n",
+ FP_REGNUM);
+#endif
+#ifdef FRAMELESS_FUNCTION_INVOCATION
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "FRAMELESS_FUNCTION_INVOCATION(fi)",
+ XSTRING (FRAMELESS_FUNCTION_INVOCATION (fi)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FRAMELESS_FUNCTION_INVOCATION = 0x%08lx\n",
+ (long) current_gdbarch->frameless_function_invocation
+ /*FRAMELESS_FUNCTION_INVOCATION ()*/);
+#endif
+#ifdef FRAME_ARGS_ADDRESS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "FRAME_ARGS_ADDRESS(fi)",
+ XSTRING (FRAME_ARGS_ADDRESS (fi)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FRAME_ARGS_ADDRESS = 0x%08lx\n",
+ (long) current_gdbarch->frame_args_address
+ /*FRAME_ARGS_ADDRESS ()*/);
+#endif
+#ifdef FRAME_ARGS_SKIP
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FRAME_ARGS_SKIP # %s\n",
+ XSTRING (FRAME_ARGS_SKIP));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FRAME_ARGS_SKIP = %ld\n",
+ (long) FRAME_ARGS_SKIP);
+#endif
+#ifdef FRAME_CHAIN
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "FRAME_CHAIN(frame)",
+ XSTRING (FRAME_CHAIN (frame)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FRAME_CHAIN = 0x%08lx\n",
+ (long) current_gdbarch->frame_chain
+ /*FRAME_CHAIN ()*/);
+#endif
+#ifdef FRAME_CHAIN_VALID
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "FRAME_CHAIN_VALID(chain, thisframe)",
+ XSTRING (FRAME_CHAIN_VALID (chain, thisframe)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FRAME_CHAIN_VALID = 0x%08lx\n",
+ (long) current_gdbarch->frame_chain_valid
+ /*FRAME_CHAIN_VALID ()*/);
+#endif
+#ifdef FRAME_INIT_SAVED_REGS
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "FRAME_INIT_SAVED_REGS(frame)",
+ XSTRING (FRAME_INIT_SAVED_REGS (frame)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FRAME_INIT_SAVED_REGS = 0x%08lx\n",
+ (long) current_gdbarch->frame_init_saved_regs
+ /*FRAME_INIT_SAVED_REGS ()*/);
+#endif
+#ifdef FRAME_LOCALS_ADDRESS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "FRAME_LOCALS_ADDRESS(fi)",
+ XSTRING (FRAME_LOCALS_ADDRESS (fi)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FRAME_LOCALS_ADDRESS = 0x%08lx\n",
+ (long) current_gdbarch->frame_locals_address
+ /*FRAME_LOCALS_ADDRESS ()*/);
+#endif
+#ifdef FRAME_NUM_ARGS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "FRAME_NUM_ARGS(frame)",
+ XSTRING (FRAME_NUM_ARGS (frame)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FRAME_NUM_ARGS = 0x%08lx\n",
+ (long) current_gdbarch->frame_num_args
+ /*FRAME_NUM_ARGS ()*/);
+#endif
+#ifdef FRAME_SAVED_PC
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "FRAME_SAVED_PC(fi)",
+ XSTRING (FRAME_SAVED_PC (fi)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FRAME_SAVED_PC = 0x%08lx\n",
+ (long) current_gdbarch->frame_saved_pc
+ /*FRAME_SAVED_PC ()*/);
+#endif
+#ifdef FUNCTION_START_OFFSET
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FUNCTION_START_OFFSET # %s\n",
+ XSTRING (FUNCTION_START_OFFSET));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: FUNCTION_START_OFFSET = %ld\n",
+ (long) FUNCTION_START_OFFSET);
+#endif
+#ifdef GET_LONGJMP_TARGET
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "GET_LONGJMP_TARGET(pc)",
+ XSTRING (GET_LONGJMP_TARGET (pc)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: GET_LONGJMP_TARGET = 0x%08lx\n",
+ (long) current_gdbarch->get_longjmp_target
+ /*GET_LONGJMP_TARGET ()*/);
+#endif
+#ifdef GET_SAVED_REGISTER
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval)",
+ XSTRING (GET_SAVED_REGISTER (raw_buffer, optimized, addrp, frame, regnum, lval)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: GET_SAVED_REGISTER = 0x%08lx\n",
+ (long) current_gdbarch->get_saved_register
+ /*GET_SAVED_REGISTER ()*/);
+#endif
+#ifdef INIT_EXTRA_FRAME_INFO
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "INIT_EXTRA_FRAME_INFO(fromleaf, frame)",
+ XSTRING (INIT_EXTRA_FRAME_INFO (fromleaf, frame)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: INIT_EXTRA_FRAME_INFO = 0x%08lx\n",
+ (long) current_gdbarch->init_extra_frame_info
+ /*INIT_EXTRA_FRAME_INFO ()*/);
+#endif
+#ifdef INIT_FRAME_PC
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "INIT_FRAME_PC(fromleaf, prev)",
+ XSTRING (INIT_FRAME_PC (fromleaf, prev)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: INIT_FRAME_PC = 0x%08lx\n",
+ (long) current_gdbarch->init_frame_pc
+ /*INIT_FRAME_PC ()*/);
+#endif
+#ifdef INIT_FRAME_PC_FIRST
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "INIT_FRAME_PC_FIRST(fromleaf, prev)",
+ XSTRING (INIT_FRAME_PC_FIRST (fromleaf, prev)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: INIT_FRAME_PC_FIRST = 0x%08lx\n",
+ (long) current_gdbarch->init_frame_pc_first
+ /*INIT_FRAME_PC_FIRST ()*/);
+#endif
+#ifdef INNER_THAN
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "INNER_THAN(lhs, rhs)",
+ XSTRING (INNER_THAN (lhs, rhs)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: INNER_THAN = 0x%08lx\n",
+ (long) current_gdbarch->inner_than
+ /*INNER_THAN ()*/);
+#endif
+#ifdef INTEGER_TO_ADDRESS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "INTEGER_TO_ADDRESS(type, buf)",
+ XSTRING (INTEGER_TO_ADDRESS (type, buf)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: INTEGER_TO_ADDRESS = 0x%08lx\n",
+ (long) current_gdbarch->integer_to_address
+ /*INTEGER_TO_ADDRESS ()*/);
+#endif
+#ifdef IN_SOLIB_CALL_TRAMPOLINE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "IN_SOLIB_CALL_TRAMPOLINE(pc, name)",
+ XSTRING (IN_SOLIB_CALL_TRAMPOLINE (pc, name)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: IN_SOLIB_CALL_TRAMPOLINE = 0x%08lx\n",
+ (long) current_gdbarch->in_solib_call_trampoline
+ /*IN_SOLIB_CALL_TRAMPOLINE ()*/);
+#endif
+#ifdef MAX_REGISTER_RAW_SIZE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: MAX_REGISTER_RAW_SIZE # %s\n",
+ XSTRING (MAX_REGISTER_RAW_SIZE));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: MAX_REGISTER_RAW_SIZE = %d\n",
+ MAX_REGISTER_RAW_SIZE);
+#endif
+#ifdef MAX_REGISTER_VIRTUAL_SIZE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: MAX_REGISTER_VIRTUAL_SIZE # %s\n",
+ XSTRING (MAX_REGISTER_VIRTUAL_SIZE));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: MAX_REGISTER_VIRTUAL_SIZE = %d\n",
+ MAX_REGISTER_VIRTUAL_SIZE);
+#endif
+#ifdef MEMORY_INSERT_BREAKPOINT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "MEMORY_INSERT_BREAKPOINT(addr, contents_cache)",
+ XSTRING (MEMORY_INSERT_BREAKPOINT (addr, contents_cache)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: MEMORY_INSERT_BREAKPOINT = 0x%08lx\n",
+ (long) current_gdbarch->memory_insert_breakpoint
+ /*MEMORY_INSERT_BREAKPOINT ()*/);
+#endif
+#ifdef MEMORY_REMOVE_BREAKPOINT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "MEMORY_REMOVE_BREAKPOINT(addr, contents_cache)",
+ XSTRING (MEMORY_REMOVE_BREAKPOINT (addr, contents_cache)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: MEMORY_REMOVE_BREAKPOINT = 0x%08lx\n",
+ (long) current_gdbarch->memory_remove_breakpoint
+ /*MEMORY_REMOVE_BREAKPOINT ()*/);
+#endif
+#ifdef NPC_REGNUM
+ fprintf_unfiltered (file,
+ "gdbarch_dump: NPC_REGNUM # %s\n",
+ XSTRING (NPC_REGNUM));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: NPC_REGNUM = %d\n",
+ NPC_REGNUM);
+#endif
+#ifdef NUM_PSEUDO_REGS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: NUM_PSEUDO_REGS # %s\n",
+ XSTRING (NUM_PSEUDO_REGS));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: NUM_PSEUDO_REGS = %d\n",
+ NUM_PSEUDO_REGS);
+#endif
+#ifdef NUM_REGS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: NUM_REGS # %s\n",
+ XSTRING (NUM_REGS));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: NUM_REGS = %d\n",
+ NUM_REGS);
+#endif
+#ifdef PARM_BOUNDARY
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PARM_BOUNDARY # %s\n",
+ XSTRING (PARM_BOUNDARY));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PARM_BOUNDARY = %d\n",
+ PARM_BOUNDARY);
+#endif
+#ifdef PC_IN_CALL_DUMMY
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "PC_IN_CALL_DUMMY(pc, sp, frame_address)",
+ XSTRING (PC_IN_CALL_DUMMY (pc, sp, frame_address)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PC_IN_CALL_DUMMY = 0x%08lx\n",
+ (long) current_gdbarch->pc_in_call_dummy
+ /*PC_IN_CALL_DUMMY ()*/);
+#endif
+#ifdef PC_IN_SIGTRAMP
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "PC_IN_SIGTRAMP(pc, name)",
+ XSTRING (PC_IN_SIGTRAMP (pc, name)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PC_IN_SIGTRAMP = 0x%08lx\n",
+ (long) current_gdbarch->pc_in_sigtramp
+ /*PC_IN_SIGTRAMP ()*/);
+#endif
+#ifdef PC_REGNUM
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PC_REGNUM # %s\n",
+ XSTRING (PC_REGNUM));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PC_REGNUM = %d\n",
+ PC_REGNUM);
+#endif
+#ifdef POINTER_TO_ADDRESS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "POINTER_TO_ADDRESS(type, buf)",
+ XSTRING (POINTER_TO_ADDRESS (type, buf)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: POINTER_TO_ADDRESS = 0x%08lx\n",
+ (long) current_gdbarch->pointer_to_address
+ /*POINTER_TO_ADDRESS ()*/);
+#endif
+#ifdef POP_FRAME
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "POP_FRAME(-)",
+ XSTRING (POP_FRAME (-)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: POP_FRAME = 0x%08lx\n",
+ (long) current_gdbarch->pop_frame
+ /*POP_FRAME ()*/);
+#endif
+#ifdef PREPARE_TO_PROCEED
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "PREPARE_TO_PROCEED(select_it)",
+ XSTRING (PREPARE_TO_PROCEED (select_it)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PREPARE_TO_PROCEED = 0x%08lx\n",
+ (long) current_gdbarch->prepare_to_proceed
+ /*PREPARE_TO_PROCEED ()*/);
+#endif
+#ifdef PRINT_FLOAT_INFO
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "PRINT_FLOAT_INFO()",
+ XSTRING (PRINT_FLOAT_INFO ()));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PRINT_FLOAT_INFO = 0x%08lx\n",
+ (long) current_gdbarch->print_float_info
+ /*PRINT_FLOAT_INFO ()*/);
+#endif
+#ifdef PROLOGUE_FRAMELESS_P
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "PROLOGUE_FRAMELESS_P(ip)",
+ XSTRING (PROLOGUE_FRAMELESS_P (ip)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PROLOGUE_FRAMELESS_P = 0x%08lx\n",
+ (long) current_gdbarch->prologue_frameless_p
+ /*PROLOGUE_FRAMELESS_P ()*/);
+#endif
+#ifdef PS_REGNUM
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PS_REGNUM # %s\n",
+ XSTRING (PS_REGNUM));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PS_REGNUM = %d\n",
+ PS_REGNUM);
+#endif
+#ifdef PUSH_ARGUMENTS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr)",
+ XSTRING (PUSH_ARGUMENTS (nargs, args, sp, struct_return, struct_addr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PUSH_ARGUMENTS = 0x%08lx\n",
+ (long) current_gdbarch->push_arguments
+ /*PUSH_ARGUMENTS ()*/);
+#endif
+#ifdef PUSH_DUMMY_FRAME
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "PUSH_DUMMY_FRAME(-)",
+ XSTRING (PUSH_DUMMY_FRAME (-)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PUSH_DUMMY_FRAME = 0x%08lx\n",
+ (long) current_gdbarch->push_dummy_frame
+ /*PUSH_DUMMY_FRAME ()*/);
+#endif
+#ifdef PUSH_RETURN_ADDRESS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "PUSH_RETURN_ADDRESS(pc, sp)",
+ XSTRING (PUSH_RETURN_ADDRESS (pc, sp)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PUSH_RETURN_ADDRESS = 0x%08lx\n",
+ (long) current_gdbarch->push_return_address
+ /*PUSH_RETURN_ADDRESS ()*/);
+#endif
+#ifdef REGISTER_BYTE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "REGISTER_BYTE(reg_nr)",
+ XSTRING (REGISTER_BYTE (reg_nr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_BYTE = 0x%08lx\n",
+ (long) current_gdbarch->register_byte
+ /*REGISTER_BYTE ()*/);
+#endif
+#ifdef REGISTER_BYTES
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_BYTES # %s\n",
+ XSTRING (REGISTER_BYTES));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_BYTES = %d\n",
+ REGISTER_BYTES);
+#endif
+#ifdef REGISTER_BYTES_OK
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "REGISTER_BYTES_OK(nr_bytes)",
+ XSTRING (REGISTER_BYTES_OK (nr_bytes)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_BYTES_OK = 0x%08lx\n",
+ (long) current_gdbarch->register_bytes_ok
+ /*REGISTER_BYTES_OK ()*/);
+#endif
+#ifdef REGISTER_CONVERTIBLE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "REGISTER_CONVERTIBLE(nr)",
+ XSTRING (REGISTER_CONVERTIBLE (nr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_CONVERTIBLE = 0x%08lx\n",
+ (long) current_gdbarch->register_convertible
+ /*REGISTER_CONVERTIBLE ()*/);
+#endif
+#ifdef REGISTER_CONVERT_TO_RAW
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "REGISTER_CONVERT_TO_RAW(type, regnum, from, to)",
+ XSTRING (REGISTER_CONVERT_TO_RAW (type, regnum, from, to)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_CONVERT_TO_RAW = 0x%08lx\n",
+ (long) current_gdbarch->register_convert_to_raw
+ /*REGISTER_CONVERT_TO_RAW ()*/);
+#endif
+#ifdef REGISTER_CONVERT_TO_VIRTUAL
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "REGISTER_CONVERT_TO_VIRTUAL(regnum, type, from, to)",
+ XSTRING (REGISTER_CONVERT_TO_VIRTUAL (regnum, type, from, to)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_CONVERT_TO_VIRTUAL = 0x%08lx\n",
+ (long) current_gdbarch->register_convert_to_virtual
+ /*REGISTER_CONVERT_TO_VIRTUAL ()*/);
+#endif
+#ifdef REGISTER_NAME
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "REGISTER_NAME(regnr)",
+ XSTRING (REGISTER_NAME (regnr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_NAME = 0x%08lx\n",
+ (long) current_gdbarch->register_name
+ /*REGISTER_NAME ()*/);
+#endif
+#ifdef REGISTER_RAW_SIZE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "REGISTER_RAW_SIZE(reg_nr)",
+ XSTRING (REGISTER_RAW_SIZE (reg_nr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_RAW_SIZE = 0x%08lx\n",
+ (long) current_gdbarch->register_raw_size
+ /*REGISTER_RAW_SIZE ()*/);
+#endif
+#ifdef REGISTER_SIM_REGNO
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "REGISTER_SIM_REGNO(reg_nr)",
+ XSTRING (REGISTER_SIM_REGNO (reg_nr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_SIM_REGNO = 0x%08lx\n",
+ (long) current_gdbarch->register_sim_regno
+ /*REGISTER_SIM_REGNO ()*/);
+#endif
+#ifdef REGISTER_SIZE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_SIZE # %s\n",
+ XSTRING (REGISTER_SIZE));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_SIZE = %d\n",
+ REGISTER_SIZE);
+#endif
+#ifdef REGISTER_TO_VALUE
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "REGISTER_TO_VALUE(regnum, type, from, to)",
+ XSTRING (REGISTER_TO_VALUE (regnum, type, from, to)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_TO_VALUE = 0x%08lx\n",
+ (long) current_gdbarch->register_to_value
+ /*REGISTER_TO_VALUE ()*/);
+#endif
+#ifdef REGISTER_VIRTUAL_SIZE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "REGISTER_VIRTUAL_SIZE(reg_nr)",
+ XSTRING (REGISTER_VIRTUAL_SIZE (reg_nr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_VIRTUAL_SIZE = 0x%08lx\n",
+ (long) current_gdbarch->register_virtual_size
+ /*REGISTER_VIRTUAL_SIZE ()*/);
+#endif
+#ifdef REGISTER_VIRTUAL_TYPE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "REGISTER_VIRTUAL_TYPE(reg_nr)",
+ XSTRING (REGISTER_VIRTUAL_TYPE (reg_nr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REGISTER_VIRTUAL_TYPE = 0x%08lx\n",
+ (long) current_gdbarch->register_virtual_type
+ /*REGISTER_VIRTUAL_TYPE ()*/);
+#endif
+#ifdef REG_STRUCT_HAS_ADDR
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "REG_STRUCT_HAS_ADDR(gcc_p, type)",
+ XSTRING (REG_STRUCT_HAS_ADDR (gcc_p, type)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REG_STRUCT_HAS_ADDR = 0x%08lx\n",
+ (long) current_gdbarch->reg_struct_has_addr
+ /*REG_STRUCT_HAS_ADDR ()*/);
+#endif
+#ifdef REMOTE_TRANSLATE_XFER_ADDRESS
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "REMOTE_TRANSLATE_XFER_ADDRESS(gdb_addr, gdb_len, rem_addr, rem_len)",
+ XSTRING (REMOTE_TRANSLATE_XFER_ADDRESS (gdb_addr, gdb_len, rem_addr, rem_len)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: REMOTE_TRANSLATE_XFER_ADDRESS = 0x%08lx\n",
+ (long) current_gdbarch->remote_translate_xfer_address
+ /*REMOTE_TRANSLATE_XFER_ADDRESS ()*/);
+#endif
+#ifdef RETURN_VALUE_ON_STACK
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "RETURN_VALUE_ON_STACK(type)",
+ XSTRING (RETURN_VALUE_ON_STACK (type)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: RETURN_VALUE_ON_STACK = 0x%08lx\n",
+ (long) current_gdbarch->return_value_on_stack
+ /*RETURN_VALUE_ON_STACK ()*/);
+#endif
+#ifdef SAVED_PC_AFTER_CALL
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "SAVED_PC_AFTER_CALL(frame)",
+ XSTRING (SAVED_PC_AFTER_CALL (frame)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: SAVED_PC_AFTER_CALL = 0x%08lx\n",
+ (long) current_gdbarch->saved_pc_after_call
+ /*SAVED_PC_AFTER_CALL ()*/);
+#endif
+#ifdef SAVE_DUMMY_FRAME_TOS
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "SAVE_DUMMY_FRAME_TOS(sp)",
+ XSTRING (SAVE_DUMMY_FRAME_TOS (sp)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: SAVE_DUMMY_FRAME_TOS = 0x%08lx\n",
+ (long) current_gdbarch->save_dummy_frame_tos
+ /*SAVE_DUMMY_FRAME_TOS ()*/);
+#endif
+#ifdef SDB_REG_TO_REGNUM
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "SDB_REG_TO_REGNUM(sdb_regnr)",
+ XSTRING (SDB_REG_TO_REGNUM (sdb_regnr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: SDB_REG_TO_REGNUM = 0x%08lx\n",
+ (long) current_gdbarch->sdb_reg_to_regnum
+ /*SDB_REG_TO_REGNUM ()*/);
+#endif
+#ifdef SIZEOF_CALL_DUMMY_WORDS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: SIZEOF_CALL_DUMMY_WORDS # %s\n",
+ XSTRING (SIZEOF_CALL_DUMMY_WORDS));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: SIZEOF_CALL_DUMMY_WORDS = 0x%08lx\n",
+ (long) SIZEOF_CALL_DUMMY_WORDS);
+#endif
+#ifdef SKIP_PROLOGUE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "SKIP_PROLOGUE(ip)",
+ XSTRING (SKIP_PROLOGUE (ip)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: SKIP_PROLOGUE = 0x%08lx\n",
+ (long) current_gdbarch->skip_prologue
+ /*SKIP_PROLOGUE ()*/);
+#endif
+#ifdef SKIP_TRAMPOLINE_CODE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "SKIP_TRAMPOLINE_CODE(pc)",
+ XSTRING (SKIP_TRAMPOLINE_CODE (pc)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: SKIP_TRAMPOLINE_CODE = 0x%08lx\n",
+ (long) current_gdbarch->skip_trampoline_code
+ /*SKIP_TRAMPOLINE_CODE ()*/);
+#endif
+#ifdef SMASH_TEXT_ADDRESS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "SMASH_TEXT_ADDRESS(addr)",
+ XSTRING (SMASH_TEXT_ADDRESS (addr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: SMASH_TEXT_ADDRESS = 0x%08lx\n",
+ (long) current_gdbarch->smash_text_address
+ /*SMASH_TEXT_ADDRESS ()*/);
+#endif
+#ifdef SOFTWARE_SINGLE_STEP
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p)",
+ XSTRING (SOFTWARE_SINGLE_STEP (sig, insert_breakpoints_p)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: SOFTWARE_SINGLE_STEP = 0x%08lx\n",
+ (long) current_gdbarch->software_single_step
+ /*SOFTWARE_SINGLE_STEP ()*/);
+#endif
+#ifdef SP_REGNUM
+ fprintf_unfiltered (file,
+ "gdbarch_dump: SP_REGNUM # %s\n",
+ XSTRING (SP_REGNUM));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: SP_REGNUM = %d\n",
+ SP_REGNUM);
+#endif
+#ifdef STAB_REG_TO_REGNUM
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "STAB_REG_TO_REGNUM(stab_regnr)",
+ XSTRING (STAB_REG_TO_REGNUM (stab_regnr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: STAB_REG_TO_REGNUM = 0x%08lx\n",
+ (long) current_gdbarch->stab_reg_to_regnum
+ /*STAB_REG_TO_REGNUM ()*/);
+#endif
+#ifdef STACK_ALIGN
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "STACK_ALIGN(sp)",
+ XSTRING (STACK_ALIGN (sp)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: STACK_ALIGN = 0x%08lx\n",
+ (long) current_gdbarch->stack_align
+ /*STACK_ALIGN ()*/);
+#endif
+#ifdef STORE_PSEUDO_REGISTER
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "STORE_PSEUDO_REGISTER(regnum)",
+ XSTRING (STORE_PSEUDO_REGISTER (regnum)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: STORE_PSEUDO_REGISTER = 0x%08lx\n",
+ (long) current_gdbarch->store_pseudo_register
+ /*STORE_PSEUDO_REGISTER ()*/);
+#endif
+#ifdef STORE_RETURN_VALUE
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "STORE_RETURN_VALUE(type, valbuf)",
+ XSTRING (STORE_RETURN_VALUE (type, valbuf)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: STORE_RETURN_VALUE = 0x%08lx\n",
+ (long) current_gdbarch->store_return_value
+ /*STORE_RETURN_VALUE ()*/);
+#endif
+#ifdef STORE_STRUCT_RETURN
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "STORE_STRUCT_RETURN(addr, sp)",
+ XSTRING (STORE_STRUCT_RETURN (addr, sp)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: STORE_STRUCT_RETURN = 0x%08lx\n",
+ (long) current_gdbarch->store_struct_return
+ /*STORE_STRUCT_RETURN ()*/);
+#endif
+#ifdef TARGET_ADDR_BIT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_ADDR_BIT # %s\n",
+ XSTRING (TARGET_ADDR_BIT));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_ADDR_BIT = %d\n",
+ TARGET_ADDR_BIT);
+#endif
+#ifdef TARGET_ARCHITECTURE
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_ARCHITECTURE # %s\n",
+ XSTRING (TARGET_ARCHITECTURE));
+ if (TARGET_ARCHITECTURE != NULL)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_ARCHITECTURE = %s\n",
+ TARGET_ARCHITECTURE->printable_name);
+#endif
+#ifdef TARGET_BFD_VMA_BIT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_BFD_VMA_BIT # %s\n",
+ XSTRING (TARGET_BFD_VMA_BIT));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_BFD_VMA_BIT = %d\n",
+ TARGET_BFD_VMA_BIT);
+#endif
+#ifdef TARGET_BYTE_ORDER
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_BYTE_ORDER # %s\n",
+ XSTRING (TARGET_BYTE_ORDER));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_BYTE_ORDER = %ld\n",
+ (long) TARGET_BYTE_ORDER);
+#endif
+#ifdef TARGET_CHAR_SIGNED
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_CHAR_SIGNED # %s\n",
+ XSTRING (TARGET_CHAR_SIGNED));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_CHAR_SIGNED = %d\n",
+ TARGET_CHAR_SIGNED);
+#endif
+#ifdef TARGET_DOUBLE_BIT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_DOUBLE_BIT # %s\n",
+ XSTRING (TARGET_DOUBLE_BIT));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_DOUBLE_BIT = %d\n",
+ TARGET_DOUBLE_BIT);
+#endif
+#ifdef TARGET_DOUBLE_FORMAT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_DOUBLE_FORMAT # %s\n",
+ XSTRING (TARGET_DOUBLE_FORMAT));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_DOUBLE_FORMAT = %ld\n",
+ (long) TARGET_DOUBLE_FORMAT);
+#endif
+#ifdef TARGET_FLOAT_BIT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_FLOAT_BIT # %s\n",
+ XSTRING (TARGET_FLOAT_BIT));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_FLOAT_BIT = %d\n",
+ TARGET_FLOAT_BIT);
+#endif
+#ifdef TARGET_FLOAT_FORMAT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_FLOAT_FORMAT # %s\n",
+ XSTRING (TARGET_FLOAT_FORMAT));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_FLOAT_FORMAT = %ld\n",
+ (long) TARGET_FLOAT_FORMAT);
+#endif
+#ifdef TARGET_INT_BIT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_INT_BIT # %s\n",
+ XSTRING (TARGET_INT_BIT));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_INT_BIT = %d\n",
+ TARGET_INT_BIT);
+#endif
+#ifdef TARGET_LONG_BIT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_LONG_BIT # %s\n",
+ XSTRING (TARGET_LONG_BIT));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_LONG_BIT = %d\n",
+ TARGET_LONG_BIT);
+#endif
+#ifdef TARGET_LONG_DOUBLE_BIT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_LONG_DOUBLE_BIT # %s\n",
+ XSTRING (TARGET_LONG_DOUBLE_BIT));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_LONG_DOUBLE_BIT = %d\n",
+ TARGET_LONG_DOUBLE_BIT);
+#endif
+#ifdef TARGET_LONG_DOUBLE_FORMAT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_LONG_DOUBLE_FORMAT # %s\n",
+ XSTRING (TARGET_LONG_DOUBLE_FORMAT));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_LONG_DOUBLE_FORMAT = %ld\n",
+ (long) TARGET_LONG_DOUBLE_FORMAT);
+#endif
+#ifdef TARGET_LONG_LONG_BIT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_LONG_LONG_BIT # %s\n",
+ XSTRING (TARGET_LONG_LONG_BIT));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_LONG_LONG_BIT = %d\n",
+ TARGET_LONG_LONG_BIT);
+#endif
+#ifdef TARGET_PRINT_INSN
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "TARGET_PRINT_INSN(vma, info)",
+ XSTRING (TARGET_PRINT_INSN (vma, info)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_PRINT_INSN = 0x%08lx\n",
+ (long) current_gdbarch->print_insn
+ /*TARGET_PRINT_INSN ()*/);
+#endif
+#ifdef TARGET_PTR_BIT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_PTR_BIT # %s\n",
+ XSTRING (TARGET_PTR_BIT));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_PTR_BIT = %d\n",
+ TARGET_PTR_BIT);
+#endif
+#ifdef TARGET_READ_FP
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "TARGET_READ_FP()",
+ XSTRING (TARGET_READ_FP ()));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_READ_FP = 0x%08lx\n",
+ (long) current_gdbarch->read_fp
+ /*TARGET_READ_FP ()*/);
+#endif
+#ifdef TARGET_READ_PC
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "TARGET_READ_PC(ptid)",
+ XSTRING (TARGET_READ_PC (ptid)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_READ_PC = 0x%08lx\n",
+ (long) current_gdbarch->read_pc
+ /*TARGET_READ_PC ()*/);
+#endif
+#ifdef TARGET_READ_SP
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "TARGET_READ_SP()",
+ XSTRING (TARGET_READ_SP ()));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_READ_SP = 0x%08lx\n",
+ (long) current_gdbarch->read_sp
+ /*TARGET_READ_SP ()*/);
+#endif
+#ifdef TARGET_SHORT_BIT
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_SHORT_BIT # %s\n",
+ XSTRING (TARGET_SHORT_BIT));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_SHORT_BIT = %d\n",
+ TARGET_SHORT_BIT);
+#endif
+#ifdef TARGET_VIRTUAL_FRAME_POINTER
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "TARGET_VIRTUAL_FRAME_POINTER(pc, frame_regnum, frame_offset)",
+ XSTRING (TARGET_VIRTUAL_FRAME_POINTER (pc, frame_regnum, frame_offset)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_VIRTUAL_FRAME_POINTER = 0x%08lx\n",
+ (long) current_gdbarch->virtual_frame_pointer
+ /*TARGET_VIRTUAL_FRAME_POINTER ()*/);
+#endif
+#ifdef TARGET_WRITE_PC
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "TARGET_WRITE_PC(val, ptid)",
+ XSTRING (TARGET_WRITE_PC (val, ptid)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_WRITE_PC = 0x%08lx\n",
+ (long) current_gdbarch->write_pc
+ /*TARGET_WRITE_PC ()*/);
+#endif
+#ifdef TARGET_WRITE_SP
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "TARGET_WRITE_SP(val)",
+ XSTRING (TARGET_WRITE_SP (val)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: TARGET_WRITE_SP = 0x%08lx\n",
+ (long) current_gdbarch->write_sp
+ /*TARGET_WRITE_SP ()*/);
+#endif
+#ifdef USE_GENERIC_DUMMY_FRAMES
+ fprintf_unfiltered (file,
+ "gdbarch_dump: USE_GENERIC_DUMMY_FRAMES # %s\n",
+ XSTRING (USE_GENERIC_DUMMY_FRAMES));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: USE_GENERIC_DUMMY_FRAMES = %d\n",
+ USE_GENERIC_DUMMY_FRAMES);
+#endif
+#ifdef USE_STRUCT_CONVENTION
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "USE_STRUCT_CONVENTION(gcc_p, value_type)",
+ XSTRING (USE_STRUCT_CONVENTION (gcc_p, value_type)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: USE_STRUCT_CONVENTION = 0x%08lx\n",
+ (long) current_gdbarch->use_struct_convention
+ /*USE_STRUCT_CONVENTION ()*/);
+#endif
+#ifdef VALUE_TO_REGISTER
+#if GDB_MULTI_ARCH
+ /* Macro might contain `[{}]' when not multi-arch */
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "VALUE_TO_REGISTER(type, regnum, from, to)",
+ XSTRING (VALUE_TO_REGISTER (type, regnum, from, to)));
+#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: VALUE_TO_REGISTER = 0x%08lx\n",
+ (long) current_gdbarch->value_to_register
+ /*VALUE_TO_REGISTER ()*/);
+#endif
+ if (current_gdbarch->dump_tdep != NULL)
+ current_gdbarch->dump_tdep (current_gdbarch, file);
+}
+
+struct gdbarch_tdep *
+gdbarch_tdep (struct gdbarch *gdbarch)
+{
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_tdep called\n");
+ return gdbarch->tdep;
+}
+
+
+const struct bfd_arch_info *
+gdbarch_bfd_arch_info (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_bfd_arch_info called\n");
+ return gdbarch->bfd_arch_info;
+}
+
+int
+gdbarch_byte_order (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_byte_order called\n");
+ return gdbarch->byte_order;
+}
+
+int
+gdbarch_short_bit (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of short_bit, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_short_bit called\n");
+ return gdbarch->short_bit;
+}
+
+void
+set_gdbarch_short_bit (struct gdbarch *gdbarch,
+ int short_bit)
+{
+ gdbarch->short_bit = short_bit;
+}
+
+int
+gdbarch_int_bit (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of int_bit, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_int_bit called\n");
+ return gdbarch->int_bit;
+}
+
+void
+set_gdbarch_int_bit (struct gdbarch *gdbarch,
+ int int_bit)
+{
+ gdbarch->int_bit = int_bit;
+}
+
+int
+gdbarch_long_bit (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of long_bit, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_long_bit called\n");
+ return gdbarch->long_bit;
+}
+
+void
+set_gdbarch_long_bit (struct gdbarch *gdbarch,
+ int long_bit)
+{
+ gdbarch->long_bit = long_bit;
+}
+
+int
+gdbarch_long_long_bit (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of long_long_bit, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_long_long_bit called\n");
+ return gdbarch->long_long_bit;
+}
+
+void
+set_gdbarch_long_long_bit (struct gdbarch *gdbarch,
+ int long_long_bit)
+{
+ gdbarch->long_long_bit = long_long_bit;
+}
+
+int
+gdbarch_float_bit (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of float_bit, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_float_bit called\n");
+ return gdbarch->float_bit;
+}
+
+void
+set_gdbarch_float_bit (struct gdbarch *gdbarch,
+ int float_bit)
+{
+ gdbarch->float_bit = float_bit;
+}
+
+int
+gdbarch_double_bit (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of double_bit, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_double_bit called\n");
+ return gdbarch->double_bit;
+}
+
+void
+set_gdbarch_double_bit (struct gdbarch *gdbarch,
+ int double_bit)
+{
+ gdbarch->double_bit = double_bit;
+}
+
+int
+gdbarch_long_double_bit (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of long_double_bit, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_long_double_bit called\n");
+ return gdbarch->long_double_bit;
+}
+
+void
+set_gdbarch_long_double_bit (struct gdbarch *gdbarch,
+ int long_double_bit)
+{
+ gdbarch->long_double_bit = long_double_bit;
+}
+
+int
+gdbarch_ptr_bit (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of ptr_bit, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_ptr_bit called\n");
+ return gdbarch->ptr_bit;
+}
+
+void
+set_gdbarch_ptr_bit (struct gdbarch *gdbarch,
+ int ptr_bit)
+{
+ gdbarch->ptr_bit = ptr_bit;
+}
+
+int
+gdbarch_addr_bit (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->addr_bit == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_addr_bit invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_addr_bit called\n");
+ return gdbarch->addr_bit;
+}
+
+void
+set_gdbarch_addr_bit (struct gdbarch *gdbarch,
+ int addr_bit)
+{
+ gdbarch->addr_bit = addr_bit;
+}
+
+int
+gdbarch_bfd_vma_bit (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of bfd_vma_bit, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_bfd_vma_bit called\n");
+ return gdbarch->bfd_vma_bit;
+}
+
+void
+set_gdbarch_bfd_vma_bit (struct gdbarch *gdbarch,
+ int bfd_vma_bit)
+{
+ gdbarch->bfd_vma_bit = bfd_vma_bit;
+}
+
+int
+gdbarch_char_signed (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->char_signed == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_char_signed invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_char_signed called\n");
+ return gdbarch->char_signed;
+}
+
+void
+set_gdbarch_char_signed (struct gdbarch *gdbarch,
+ int char_signed)
+{
+ gdbarch->char_signed = char_signed;
+}
+
+CORE_ADDR
+gdbarch_read_pc (struct gdbarch *gdbarch, ptid_t ptid)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->read_pc == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_read_pc invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_read_pc called\n");
+ return gdbarch->read_pc (ptid);
+}
+
+void
+set_gdbarch_read_pc (struct gdbarch *gdbarch,
+ gdbarch_read_pc_ftype read_pc)
+{
+ gdbarch->read_pc = read_pc;
+}
+
+void
+gdbarch_write_pc (struct gdbarch *gdbarch, CORE_ADDR val, ptid_t ptid)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->write_pc == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_write_pc invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_write_pc called\n");
+ gdbarch->write_pc (val, ptid);
+}
+
+void
+set_gdbarch_write_pc (struct gdbarch *gdbarch,
+ gdbarch_write_pc_ftype write_pc)
+{
+ gdbarch->write_pc = write_pc;
+}
+
+CORE_ADDR
+gdbarch_read_fp (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->read_fp == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_read_fp invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_read_fp called\n");
+ return gdbarch->read_fp ();
+}
+
+void
+set_gdbarch_read_fp (struct gdbarch *gdbarch,
+ gdbarch_read_fp_ftype read_fp)
+{
+ gdbarch->read_fp = read_fp;
+}
+
+CORE_ADDR
+gdbarch_read_sp (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->read_sp == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_read_sp invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_read_sp called\n");
+ return gdbarch->read_sp ();
+}
+
+void
+set_gdbarch_read_sp (struct gdbarch *gdbarch,
+ gdbarch_read_sp_ftype read_sp)
+{
+ gdbarch->read_sp = read_sp;
+}
+
+void
+gdbarch_write_sp (struct gdbarch *gdbarch, CORE_ADDR val)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->write_sp == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_write_sp invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_write_sp called\n");
+ gdbarch->write_sp (val);
+}
+
+void
+set_gdbarch_write_sp (struct gdbarch *gdbarch,
+ gdbarch_write_sp_ftype write_sp)
+{
+ gdbarch->write_sp = write_sp;
+}
+
+void
+gdbarch_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->virtual_frame_pointer == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_virtual_frame_pointer invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_virtual_frame_pointer called\n");
+ gdbarch->virtual_frame_pointer (pc, frame_regnum, frame_offset);
+}
+
+void
+set_gdbarch_virtual_frame_pointer (struct gdbarch *gdbarch,
+ gdbarch_virtual_frame_pointer_ftype virtual_frame_pointer)
+{
+ gdbarch->virtual_frame_pointer = virtual_frame_pointer;
+}
+
+int
+gdbarch_register_read_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->register_read != 0;
+}
+
+void
+gdbarch_register_read (struct gdbarch *gdbarch, int regnum, char *buf)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_read == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_read invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_read called\n");
+ gdbarch->register_read (gdbarch, regnum, buf);
+}
+
+void
+set_gdbarch_register_read (struct gdbarch *gdbarch,
+ gdbarch_register_read_ftype register_read)
+{
+ gdbarch->register_read = register_read;
+}
+
+int
+gdbarch_register_write_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->register_write != 0;
+}
+
+void
+gdbarch_register_write (struct gdbarch *gdbarch, int regnum, char *buf)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_write == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_write invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_write called\n");
+ gdbarch->register_write (gdbarch, regnum, buf);
+}
+
+void
+set_gdbarch_register_write (struct gdbarch *gdbarch,
+ gdbarch_register_write_ftype register_write)
+{
+ gdbarch->register_write = register_write;
+}
+
+int
+gdbarch_num_regs (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->num_regs == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_num_regs invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_num_regs called\n");
+ return gdbarch->num_regs;
+}
+
+void
+set_gdbarch_num_regs (struct gdbarch *gdbarch,
+ int num_regs)
+{
+ gdbarch->num_regs = num_regs;
+}
+
+int
+gdbarch_num_pseudo_regs (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of num_pseudo_regs, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_num_pseudo_regs called\n");
+ return gdbarch->num_pseudo_regs;
+}
+
+void
+set_gdbarch_num_pseudo_regs (struct gdbarch *gdbarch,
+ int num_pseudo_regs)
+{
+ gdbarch->num_pseudo_regs = num_pseudo_regs;
+}
+
+int
+gdbarch_sp_regnum (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of sp_regnum, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_sp_regnum called\n");
+ return gdbarch->sp_regnum;
+}
+
+void
+set_gdbarch_sp_regnum (struct gdbarch *gdbarch,
+ int sp_regnum)
+{
+ gdbarch->sp_regnum = sp_regnum;
+}
+
+int
+gdbarch_fp_regnum (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of fp_regnum, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_fp_regnum called\n");
+ return gdbarch->fp_regnum;
+}
+
+void
+set_gdbarch_fp_regnum (struct gdbarch *gdbarch,
+ int fp_regnum)
+{
+ gdbarch->fp_regnum = fp_regnum;
+}
+
+int
+gdbarch_pc_regnum (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of pc_regnum, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_pc_regnum called\n");
+ return gdbarch->pc_regnum;
+}
+
+void
+set_gdbarch_pc_regnum (struct gdbarch *gdbarch,
+ int pc_regnum)
+{
+ gdbarch->pc_regnum = pc_regnum;
+}
+
+int
+gdbarch_ps_regnum (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of ps_regnum, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_ps_regnum called\n");
+ return gdbarch->ps_regnum;
+}
+
+void
+set_gdbarch_ps_regnum (struct gdbarch *gdbarch,
+ int ps_regnum)
+{
+ gdbarch->ps_regnum = ps_regnum;
+}
+
+int
+gdbarch_fp0_regnum (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of fp0_regnum, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_fp0_regnum called\n");
+ return gdbarch->fp0_regnum;
+}
+
+void
+set_gdbarch_fp0_regnum (struct gdbarch *gdbarch,
+ int fp0_regnum)
+{
+ gdbarch->fp0_regnum = fp0_regnum;
+}
+
+int
+gdbarch_npc_regnum (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of npc_regnum, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_npc_regnum called\n");
+ return gdbarch->npc_regnum;
+}
+
+void
+set_gdbarch_npc_regnum (struct gdbarch *gdbarch,
+ int npc_regnum)
+{
+ gdbarch->npc_regnum = npc_regnum;
+}
+
+int
+gdbarch_stab_reg_to_regnum (struct gdbarch *gdbarch, int stab_regnr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->stab_reg_to_regnum == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_stab_reg_to_regnum invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_stab_reg_to_regnum called\n");
+ return gdbarch->stab_reg_to_regnum (stab_regnr);
+}
+
+void
+set_gdbarch_stab_reg_to_regnum (struct gdbarch *gdbarch,
+ gdbarch_stab_reg_to_regnum_ftype stab_reg_to_regnum)
+{
+ gdbarch->stab_reg_to_regnum = stab_reg_to_regnum;
+}
+
+int
+gdbarch_ecoff_reg_to_regnum (struct gdbarch *gdbarch, int ecoff_regnr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->ecoff_reg_to_regnum == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_ecoff_reg_to_regnum invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_ecoff_reg_to_regnum called\n");
+ return gdbarch->ecoff_reg_to_regnum (ecoff_regnr);
+}
+
+void
+set_gdbarch_ecoff_reg_to_regnum (struct gdbarch *gdbarch,
+ gdbarch_ecoff_reg_to_regnum_ftype ecoff_reg_to_regnum)
+{
+ gdbarch->ecoff_reg_to_regnum = ecoff_reg_to_regnum;
+}
+
+int
+gdbarch_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int dwarf_regnr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->dwarf_reg_to_regnum == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_dwarf_reg_to_regnum invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_dwarf_reg_to_regnum called\n");
+ return gdbarch->dwarf_reg_to_regnum (dwarf_regnr);
+}
+
+void
+set_gdbarch_dwarf_reg_to_regnum (struct gdbarch *gdbarch,
+ gdbarch_dwarf_reg_to_regnum_ftype dwarf_reg_to_regnum)
+{
+ gdbarch->dwarf_reg_to_regnum = dwarf_reg_to_regnum;
+}
+
+int
+gdbarch_sdb_reg_to_regnum (struct gdbarch *gdbarch, int sdb_regnr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->sdb_reg_to_regnum == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_sdb_reg_to_regnum invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_sdb_reg_to_regnum called\n");
+ return gdbarch->sdb_reg_to_regnum (sdb_regnr);
+}
+
+void
+set_gdbarch_sdb_reg_to_regnum (struct gdbarch *gdbarch,
+ gdbarch_sdb_reg_to_regnum_ftype sdb_reg_to_regnum)
+{
+ gdbarch->sdb_reg_to_regnum = sdb_reg_to_regnum;
+}
+
+int
+gdbarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int dwarf2_regnr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->dwarf2_reg_to_regnum == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_dwarf2_reg_to_regnum invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_dwarf2_reg_to_regnum called\n");
+ return gdbarch->dwarf2_reg_to_regnum (dwarf2_regnr);
+}
+
+void
+set_gdbarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch,
+ gdbarch_dwarf2_reg_to_regnum_ftype dwarf2_reg_to_regnum)
+{
+ gdbarch->dwarf2_reg_to_regnum = dwarf2_reg_to_regnum;
+}
+
+char *
+gdbarch_register_name (struct gdbarch *gdbarch, int regnr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_name == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_name invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_name called\n");
+ return gdbarch->register_name (regnr);
+}
+
+void
+set_gdbarch_register_name (struct gdbarch *gdbarch,
+ gdbarch_register_name_ftype register_name)
+{
+ gdbarch->register_name = register_name;
+}
+
+int
+gdbarch_register_size (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_size == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_size invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_size called\n");
+ return gdbarch->register_size;
+}
+
+void
+set_gdbarch_register_size (struct gdbarch *gdbarch,
+ int register_size)
+{
+ gdbarch->register_size = register_size;
+}
+
+int
+gdbarch_register_bytes (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_bytes == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_bytes invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_bytes called\n");
+ return gdbarch->register_bytes;
+}
+
+void
+set_gdbarch_register_bytes (struct gdbarch *gdbarch,
+ int register_bytes)
+{
+ gdbarch->register_bytes = register_bytes;
+}
+
+int
+gdbarch_register_byte (struct gdbarch *gdbarch, int reg_nr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_byte == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_byte invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_byte called\n");
+ return gdbarch->register_byte (reg_nr);
+}
+
+void
+set_gdbarch_register_byte (struct gdbarch *gdbarch,
+ gdbarch_register_byte_ftype register_byte)
+{
+ gdbarch->register_byte = register_byte;
+}
+
+int
+gdbarch_register_raw_size (struct gdbarch *gdbarch, int reg_nr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_raw_size == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_raw_size invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_raw_size called\n");
+ return gdbarch->register_raw_size (reg_nr);
+}
+
+void
+set_gdbarch_register_raw_size (struct gdbarch *gdbarch,
+ gdbarch_register_raw_size_ftype register_raw_size)
+{
+ gdbarch->register_raw_size = register_raw_size;
+}
+
+int
+gdbarch_max_register_raw_size (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->max_register_raw_size == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_max_register_raw_size invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_max_register_raw_size called\n");
+ return gdbarch->max_register_raw_size;
+}
+
+void
+set_gdbarch_max_register_raw_size (struct gdbarch *gdbarch,
+ int max_register_raw_size)
+{
+ gdbarch->max_register_raw_size = max_register_raw_size;
+}
+
+int
+gdbarch_register_virtual_size (struct gdbarch *gdbarch, int reg_nr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_virtual_size == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_virtual_size invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_virtual_size called\n");
+ return gdbarch->register_virtual_size (reg_nr);
+}
+
+void
+set_gdbarch_register_virtual_size (struct gdbarch *gdbarch,
+ gdbarch_register_virtual_size_ftype register_virtual_size)
+{
+ gdbarch->register_virtual_size = register_virtual_size;
+}
+
+int
+gdbarch_max_register_virtual_size (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->max_register_virtual_size == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_max_register_virtual_size invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_max_register_virtual_size called\n");
+ return gdbarch->max_register_virtual_size;
+}
+
+void
+set_gdbarch_max_register_virtual_size (struct gdbarch *gdbarch,
+ int max_register_virtual_size)
+{
+ gdbarch->max_register_virtual_size = max_register_virtual_size;
+}
+
+struct type *
+gdbarch_register_virtual_type (struct gdbarch *gdbarch, int reg_nr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_virtual_type == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_virtual_type invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_virtual_type called\n");
+ return gdbarch->register_virtual_type (reg_nr);
+}
+
+void
+set_gdbarch_register_virtual_type (struct gdbarch *gdbarch,
+ gdbarch_register_virtual_type_ftype register_virtual_type)
+{
+ gdbarch->register_virtual_type = register_virtual_type;
+}
+
+void
+gdbarch_do_registers_info (struct gdbarch *gdbarch, int reg_nr, int fpregs)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->do_registers_info == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_do_registers_info invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_do_registers_info called\n");
+ gdbarch->do_registers_info (reg_nr, fpregs);
+}
+
+void
+set_gdbarch_do_registers_info (struct gdbarch *gdbarch,
+ gdbarch_do_registers_info_ftype do_registers_info)
+{
+ gdbarch->do_registers_info = do_registers_info;
+}
+
+void
+gdbarch_print_float_info (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->print_float_info == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_print_float_info invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_print_float_info called\n");
+ gdbarch->print_float_info ();
+}
+
+void
+set_gdbarch_print_float_info (struct gdbarch *gdbarch,
+ gdbarch_print_float_info_ftype print_float_info)
+{
+ gdbarch->print_float_info = print_float_info;
+}
+
+int
+gdbarch_register_sim_regno (struct gdbarch *gdbarch, int reg_nr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_sim_regno == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_sim_regno invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_sim_regno called\n");
+ return gdbarch->register_sim_regno (reg_nr);
+}
+
+void
+set_gdbarch_register_sim_regno (struct gdbarch *gdbarch,
+ gdbarch_register_sim_regno_ftype register_sim_regno)
+{
+ gdbarch->register_sim_regno = register_sim_regno;
+}
+
+int
+gdbarch_register_bytes_ok_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->register_bytes_ok != 0;
+}
+
+int
+gdbarch_register_bytes_ok (struct gdbarch *gdbarch, long nr_bytes)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_bytes_ok == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_bytes_ok invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_bytes_ok called\n");
+ return gdbarch->register_bytes_ok (nr_bytes);
+}
+
+void
+set_gdbarch_register_bytes_ok (struct gdbarch *gdbarch,
+ gdbarch_register_bytes_ok_ftype register_bytes_ok)
+{
+ gdbarch->register_bytes_ok = register_bytes_ok;
+}
+
+int
+gdbarch_cannot_fetch_register (struct gdbarch *gdbarch, int regnum)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->cannot_fetch_register == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_cannot_fetch_register invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_cannot_fetch_register called\n");
+ return gdbarch->cannot_fetch_register (regnum);
+}
+
+void
+set_gdbarch_cannot_fetch_register (struct gdbarch *gdbarch,
+ gdbarch_cannot_fetch_register_ftype cannot_fetch_register)
+{
+ gdbarch->cannot_fetch_register = cannot_fetch_register;
+}
+
+int
+gdbarch_cannot_store_register (struct gdbarch *gdbarch, int regnum)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->cannot_store_register == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_cannot_store_register invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_cannot_store_register called\n");
+ return gdbarch->cannot_store_register (regnum);
+}
+
+void
+set_gdbarch_cannot_store_register (struct gdbarch *gdbarch,
+ gdbarch_cannot_store_register_ftype cannot_store_register)
+{
+ gdbarch->cannot_store_register = cannot_store_register;
+}
+
+int
+gdbarch_get_longjmp_target_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->get_longjmp_target != 0;
+}
+
+int
+gdbarch_get_longjmp_target (struct gdbarch *gdbarch, CORE_ADDR *pc)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->get_longjmp_target == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_get_longjmp_target invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_get_longjmp_target called\n");
+ return gdbarch->get_longjmp_target (pc);
+}
+
+void
+set_gdbarch_get_longjmp_target (struct gdbarch *gdbarch,
+ gdbarch_get_longjmp_target_ftype get_longjmp_target)
+{
+ gdbarch->get_longjmp_target = get_longjmp_target;
+}
+
+int
+gdbarch_use_generic_dummy_frames (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->use_generic_dummy_frames == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_use_generic_dummy_frames invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_use_generic_dummy_frames called\n");
+ return gdbarch->use_generic_dummy_frames;
+}
+
+void
+set_gdbarch_use_generic_dummy_frames (struct gdbarch *gdbarch,
+ int use_generic_dummy_frames)
+{
+ gdbarch->use_generic_dummy_frames = use_generic_dummy_frames;
+}
+
+int
+gdbarch_call_dummy_location (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->call_dummy_location == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_call_dummy_location invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_location called\n");
+ return gdbarch->call_dummy_location;
+}
+
+void
+set_gdbarch_call_dummy_location (struct gdbarch *gdbarch,
+ int call_dummy_location)
+{
+ gdbarch->call_dummy_location = call_dummy_location;
+}
+
+CORE_ADDR
+gdbarch_call_dummy_address (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->call_dummy_address == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_call_dummy_address invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_address called\n");
+ return gdbarch->call_dummy_address ();
+}
+
+void
+set_gdbarch_call_dummy_address (struct gdbarch *gdbarch,
+ gdbarch_call_dummy_address_ftype call_dummy_address)
+{
+ gdbarch->call_dummy_address = call_dummy_address;
+}
+
+CORE_ADDR
+gdbarch_call_dummy_start_offset (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->call_dummy_start_offset == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_call_dummy_start_offset invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_start_offset called\n");
+ return gdbarch->call_dummy_start_offset;
+}
+
+void
+set_gdbarch_call_dummy_start_offset (struct gdbarch *gdbarch,
+ CORE_ADDR call_dummy_start_offset)
+{
+ gdbarch->call_dummy_start_offset = call_dummy_start_offset;
+}
+
+CORE_ADDR
+gdbarch_call_dummy_breakpoint_offset (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->call_dummy_breakpoint_offset_p && gdbarch->call_dummy_breakpoint_offset == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_call_dummy_breakpoint_offset invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_breakpoint_offset called\n");
+ return gdbarch->call_dummy_breakpoint_offset;
+}
+
+void
+set_gdbarch_call_dummy_breakpoint_offset (struct gdbarch *gdbarch,
+ CORE_ADDR call_dummy_breakpoint_offset)
+{
+ gdbarch->call_dummy_breakpoint_offset = call_dummy_breakpoint_offset;
+}
+
+int
+gdbarch_call_dummy_breakpoint_offset_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->call_dummy_breakpoint_offset_p == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_call_dummy_breakpoint_offset_p invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_breakpoint_offset_p called\n");
+ return gdbarch->call_dummy_breakpoint_offset_p;
+}
+
+void
+set_gdbarch_call_dummy_breakpoint_offset_p (struct gdbarch *gdbarch,
+ int call_dummy_breakpoint_offset_p)
+{
+ gdbarch->call_dummy_breakpoint_offset_p = call_dummy_breakpoint_offset_p;
+}
+
+int
+gdbarch_call_dummy_length (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->call_dummy_length == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_call_dummy_length invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_length called\n");
+ return gdbarch->call_dummy_length;
+}
+
+void
+set_gdbarch_call_dummy_length (struct gdbarch *gdbarch,
+ int call_dummy_length)
+{
+ gdbarch->call_dummy_length = call_dummy_length;
+}
+
+int
+gdbarch_pc_in_call_dummy (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->pc_in_call_dummy == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_pc_in_call_dummy invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_pc_in_call_dummy called\n");
+ return gdbarch->pc_in_call_dummy (pc, sp, frame_address);
+}
+
+void
+set_gdbarch_pc_in_call_dummy (struct gdbarch *gdbarch,
+ gdbarch_pc_in_call_dummy_ftype pc_in_call_dummy)
+{
+ gdbarch->pc_in_call_dummy = pc_in_call_dummy;
+}
+
+int
+gdbarch_call_dummy_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->call_dummy_p == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_call_dummy_p invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_p called\n");
+ return gdbarch->call_dummy_p;
+}
+
+void
+set_gdbarch_call_dummy_p (struct gdbarch *gdbarch,
+ int call_dummy_p)
+{
+ gdbarch->call_dummy_p = call_dummy_p;
+}
+
+LONGEST *
+gdbarch_call_dummy_words (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of call_dummy_words, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_words called\n");
+ return gdbarch->call_dummy_words;
+}
+
+void
+set_gdbarch_call_dummy_words (struct gdbarch *gdbarch,
+ LONGEST * call_dummy_words)
+{
+ gdbarch->call_dummy_words = call_dummy_words;
+}
+
+int
+gdbarch_sizeof_call_dummy_words (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of sizeof_call_dummy_words, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_sizeof_call_dummy_words called\n");
+ return gdbarch->sizeof_call_dummy_words;
+}
+
+void
+set_gdbarch_sizeof_call_dummy_words (struct gdbarch *gdbarch,
+ int sizeof_call_dummy_words)
+{
+ gdbarch->sizeof_call_dummy_words = sizeof_call_dummy_words;
+}
+
+int
+gdbarch_call_dummy_stack_adjust_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->call_dummy_stack_adjust_p == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_call_dummy_stack_adjust_p invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_stack_adjust_p called\n");
+ return gdbarch->call_dummy_stack_adjust_p;
+}
+
+void
+set_gdbarch_call_dummy_stack_adjust_p (struct gdbarch *gdbarch,
+ int call_dummy_stack_adjust_p)
+{
+ gdbarch->call_dummy_stack_adjust_p = call_dummy_stack_adjust_p;
+}
+
+int
+gdbarch_call_dummy_stack_adjust (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->call_dummy_stack_adjust_p && gdbarch->call_dummy_stack_adjust == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_call_dummy_stack_adjust invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_call_dummy_stack_adjust called\n");
+ return gdbarch->call_dummy_stack_adjust;
+}
+
+void
+set_gdbarch_call_dummy_stack_adjust (struct gdbarch *gdbarch,
+ int call_dummy_stack_adjust)
+{
+ gdbarch->call_dummy_stack_adjust = call_dummy_stack_adjust;
+}
+
+void
+gdbarch_fix_call_dummy (struct gdbarch *gdbarch, char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, struct value **args, struct type *type, int gcc_p)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->fix_call_dummy == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_fix_call_dummy invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_fix_call_dummy called\n");
+ gdbarch->fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p);
+}
+
+void
+set_gdbarch_fix_call_dummy (struct gdbarch *gdbarch,
+ gdbarch_fix_call_dummy_ftype fix_call_dummy)
+{
+ gdbarch->fix_call_dummy = fix_call_dummy;
+}
+
+void
+gdbarch_init_frame_pc_first (struct gdbarch *gdbarch, int fromleaf, struct frame_info *prev)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->init_frame_pc_first == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_init_frame_pc_first invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_init_frame_pc_first called\n");
+ gdbarch->init_frame_pc_first (fromleaf, prev);
+}
+
+void
+set_gdbarch_init_frame_pc_first (struct gdbarch *gdbarch,
+ gdbarch_init_frame_pc_first_ftype init_frame_pc_first)
+{
+ gdbarch->init_frame_pc_first = init_frame_pc_first;
+}
+
+void
+gdbarch_init_frame_pc (struct gdbarch *gdbarch, int fromleaf, struct frame_info *prev)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->init_frame_pc == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_init_frame_pc invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_init_frame_pc called\n");
+ gdbarch->init_frame_pc (fromleaf, prev);
+}
+
+void
+set_gdbarch_init_frame_pc (struct gdbarch *gdbarch,
+ gdbarch_init_frame_pc_ftype init_frame_pc)
+{
+ gdbarch->init_frame_pc = init_frame_pc;
+}
+
+int
+gdbarch_believe_pcc_promotion (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_believe_pcc_promotion called\n");
+ return gdbarch->believe_pcc_promotion;
+}
+
+void
+set_gdbarch_believe_pcc_promotion (struct gdbarch *gdbarch,
+ int believe_pcc_promotion)
+{
+ gdbarch->believe_pcc_promotion = believe_pcc_promotion;
+}
+
+int
+gdbarch_believe_pcc_promotion_type (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_believe_pcc_promotion_type called\n");
+ return gdbarch->believe_pcc_promotion_type;
+}
+
+void
+set_gdbarch_believe_pcc_promotion_type (struct gdbarch *gdbarch,
+ int believe_pcc_promotion_type)
+{
+ gdbarch->believe_pcc_promotion_type = believe_pcc_promotion_type;
+}
+
+int
+gdbarch_coerce_float_to_double (struct gdbarch *gdbarch, struct type *formal, struct type *actual)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->coerce_float_to_double == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_coerce_float_to_double invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_coerce_float_to_double called\n");
+ return gdbarch->coerce_float_to_double (formal, actual);
+}
+
+void
+set_gdbarch_coerce_float_to_double (struct gdbarch *gdbarch,
+ gdbarch_coerce_float_to_double_ftype coerce_float_to_double)
+{
+ gdbarch->coerce_float_to_double = coerce_float_to_double;
+}
+
+void
+gdbarch_get_saved_register (struct gdbarch *gdbarch, char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->get_saved_register == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_get_saved_register invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_get_saved_register called\n");
+ gdbarch->get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval);
+}
+
+void
+set_gdbarch_get_saved_register (struct gdbarch *gdbarch,
+ gdbarch_get_saved_register_ftype get_saved_register)
+{
+ gdbarch->get_saved_register = get_saved_register;
+}
+
+int
+gdbarch_register_convertible (struct gdbarch *gdbarch, int nr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_convertible == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_convertible invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_convertible called\n");
+ return gdbarch->register_convertible (nr);
+}
+
+void
+set_gdbarch_register_convertible (struct gdbarch *gdbarch,
+ gdbarch_register_convertible_ftype register_convertible)
+{
+ gdbarch->register_convertible = register_convertible;
+}
+
+void
+gdbarch_register_convert_to_virtual (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_convert_to_virtual == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_convert_to_virtual invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_convert_to_virtual called\n");
+ gdbarch->register_convert_to_virtual (regnum, type, from, to);
+}
+
+void
+set_gdbarch_register_convert_to_virtual (struct gdbarch *gdbarch,
+ gdbarch_register_convert_to_virtual_ftype register_convert_to_virtual)
+{
+ gdbarch->register_convert_to_virtual = register_convert_to_virtual;
+}
+
+void
+gdbarch_register_convert_to_raw (struct gdbarch *gdbarch, struct type *type, int regnum, char *from, char *to)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_convert_to_raw == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_convert_to_raw invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_convert_to_raw called\n");
+ gdbarch->register_convert_to_raw (type, regnum, from, to);
+}
+
+void
+set_gdbarch_register_convert_to_raw (struct gdbarch *gdbarch,
+ gdbarch_register_convert_to_raw_ftype register_convert_to_raw)
+{
+ gdbarch->register_convert_to_raw = register_convert_to_raw;
+}
+
+int
+gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->convert_register_p == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_convert_register_p invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_convert_register_p called\n");
+ return gdbarch->convert_register_p (regnum);
+}
+
+void
+set_gdbarch_convert_register_p (struct gdbarch *gdbarch,
+ gdbarch_convert_register_p_ftype convert_register_p)
+{
+ gdbarch->convert_register_p = convert_register_p;
+}
+
+void
+gdbarch_register_to_value (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->register_to_value == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_register_to_value invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_to_value called\n");
+ gdbarch->register_to_value (regnum, type, from, to);
+}
+
+void
+set_gdbarch_register_to_value (struct gdbarch *gdbarch,
+ gdbarch_register_to_value_ftype register_to_value)
+{
+ gdbarch->register_to_value = register_to_value;
+}
+
+void
+gdbarch_value_to_register (struct gdbarch *gdbarch, struct type *type, int regnum, char *from, char *to)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->value_to_register == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_value_to_register invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_value_to_register called\n");
+ gdbarch->value_to_register (type, regnum, from, to);
+}
+
+void
+set_gdbarch_value_to_register (struct gdbarch *gdbarch,
+ gdbarch_value_to_register_ftype value_to_register)
+{
+ gdbarch->value_to_register = value_to_register;
+}
+
+int
+gdbarch_fetch_pseudo_register_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->fetch_pseudo_register != 0;
+}
+
+void
+gdbarch_fetch_pseudo_register (struct gdbarch *gdbarch, int regnum)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->fetch_pseudo_register == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_fetch_pseudo_register invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_fetch_pseudo_register called\n");
+ gdbarch->fetch_pseudo_register (regnum);
+}
+
+void
+set_gdbarch_fetch_pseudo_register (struct gdbarch *gdbarch,
+ gdbarch_fetch_pseudo_register_ftype fetch_pseudo_register)
+{
+ gdbarch->fetch_pseudo_register = fetch_pseudo_register;
+}
+
+int
+gdbarch_store_pseudo_register_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->store_pseudo_register != 0;
+}
+
+void
+gdbarch_store_pseudo_register (struct gdbarch *gdbarch, int regnum)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->store_pseudo_register == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_store_pseudo_register invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_store_pseudo_register called\n");
+ gdbarch->store_pseudo_register (regnum);
+}
+
+void
+set_gdbarch_store_pseudo_register (struct gdbarch *gdbarch,
+ gdbarch_store_pseudo_register_ftype store_pseudo_register)
+{
+ gdbarch->store_pseudo_register = store_pseudo_register;
+}
+
+CORE_ADDR
+gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, void *buf)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->pointer_to_address == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_pointer_to_address invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_pointer_to_address called\n");
+ return gdbarch->pointer_to_address (type, buf);
+}
+
+void
+set_gdbarch_pointer_to_address (struct gdbarch *gdbarch,
+ gdbarch_pointer_to_address_ftype pointer_to_address)
+{
+ gdbarch->pointer_to_address = pointer_to_address;
+}
+
+void
+gdbarch_address_to_pointer (struct gdbarch *gdbarch, struct type *type, void *buf, CORE_ADDR addr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->address_to_pointer == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_address_to_pointer invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_address_to_pointer called\n");
+ gdbarch->address_to_pointer (type, buf, addr);
+}
+
+void
+set_gdbarch_address_to_pointer (struct gdbarch *gdbarch,
+ gdbarch_address_to_pointer_ftype address_to_pointer)
+{
+ gdbarch->address_to_pointer = address_to_pointer;
+}
+
+int
+gdbarch_integer_to_address_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->integer_to_address != 0;
+}
+
+CORE_ADDR
+gdbarch_integer_to_address (struct gdbarch *gdbarch, struct type *type, void *buf)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->integer_to_address == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_integer_to_address invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_integer_to_address called\n");
+ return gdbarch->integer_to_address (type, buf);
+}
+
+void
+set_gdbarch_integer_to_address (struct gdbarch *gdbarch,
+ gdbarch_integer_to_address_ftype integer_to_address)
+{
+ gdbarch->integer_to_address = integer_to_address;
+}
+
+int
+gdbarch_return_value_on_stack (struct gdbarch *gdbarch, struct type *type)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->return_value_on_stack == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_return_value_on_stack invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_return_value_on_stack called\n");
+ return gdbarch->return_value_on_stack (type);
+}
+
+void
+set_gdbarch_return_value_on_stack (struct gdbarch *gdbarch,
+ gdbarch_return_value_on_stack_ftype return_value_on_stack)
+{
+ gdbarch->return_value_on_stack = return_value_on_stack;
+}
+
+void
+gdbarch_extract_return_value (struct gdbarch *gdbarch, struct type *type, char *regbuf, char *valbuf)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->extract_return_value == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_extract_return_value invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_extract_return_value called\n");
+ gdbarch->extract_return_value (type, regbuf, valbuf);
+}
+
+void
+set_gdbarch_extract_return_value (struct gdbarch *gdbarch,
+ gdbarch_extract_return_value_ftype extract_return_value)
+{
+ gdbarch->extract_return_value = extract_return_value;
+}
+
+CORE_ADDR
+gdbarch_push_arguments (struct gdbarch *gdbarch, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->push_arguments == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_push_arguments invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_push_arguments called\n");
+ return gdbarch->push_arguments (nargs, args, sp, struct_return, struct_addr);
+}
+
+void
+set_gdbarch_push_arguments (struct gdbarch *gdbarch,
+ gdbarch_push_arguments_ftype push_arguments)
+{
+ gdbarch->push_arguments = push_arguments;
+}
+
+void
+gdbarch_push_dummy_frame (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->push_dummy_frame == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_push_dummy_frame invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_push_dummy_frame called\n");
+ gdbarch->push_dummy_frame ();
+}
+
+void
+set_gdbarch_push_dummy_frame (struct gdbarch *gdbarch,
+ gdbarch_push_dummy_frame_ftype push_dummy_frame)
+{
+ gdbarch->push_dummy_frame = push_dummy_frame;
+}
+
+int
+gdbarch_push_return_address_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->push_return_address != 0;
+}
+
+CORE_ADDR
+gdbarch_push_return_address (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR sp)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->push_return_address == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_push_return_address invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_push_return_address called\n");
+ return gdbarch->push_return_address (pc, sp);
+}
+
+void
+set_gdbarch_push_return_address (struct gdbarch *gdbarch,
+ gdbarch_push_return_address_ftype push_return_address)
+{
+ gdbarch->push_return_address = push_return_address;
+}
+
+void
+gdbarch_pop_frame (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->pop_frame == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_pop_frame invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_pop_frame called\n");
+ gdbarch->pop_frame ();
+}
+
+void
+set_gdbarch_pop_frame (struct gdbarch *gdbarch,
+ gdbarch_pop_frame_ftype pop_frame)
+{
+ gdbarch->pop_frame = pop_frame;
+}
+
+void
+gdbarch_store_struct_return (struct gdbarch *gdbarch, CORE_ADDR addr, CORE_ADDR sp)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->store_struct_return == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_store_struct_return invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_store_struct_return called\n");
+ gdbarch->store_struct_return (addr, sp);
+}
+
+void
+set_gdbarch_store_struct_return (struct gdbarch *gdbarch,
+ gdbarch_store_struct_return_ftype store_struct_return)
+{
+ gdbarch->store_struct_return = store_struct_return;
+}
+
+void
+gdbarch_store_return_value (struct gdbarch *gdbarch, struct type *type, char *valbuf)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->store_return_value == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_store_return_value invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_store_return_value called\n");
+ gdbarch->store_return_value (type, valbuf);
+}
+
+void
+set_gdbarch_store_return_value (struct gdbarch *gdbarch,
+ gdbarch_store_return_value_ftype store_return_value)
+{
+ gdbarch->store_return_value = store_return_value;
+}
+
+int
+gdbarch_extract_struct_value_address_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->extract_struct_value_address != 0;
+}
+
+CORE_ADDR
+gdbarch_extract_struct_value_address (struct gdbarch *gdbarch, char *regbuf)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->extract_struct_value_address == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_extract_struct_value_address invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_extract_struct_value_address called\n");
+ return gdbarch->extract_struct_value_address (regbuf);
+}
+
+void
+set_gdbarch_extract_struct_value_address (struct gdbarch *gdbarch,
+ gdbarch_extract_struct_value_address_ftype extract_struct_value_address)
+{
+ gdbarch->extract_struct_value_address = extract_struct_value_address;
+}
+
+int
+gdbarch_use_struct_convention (struct gdbarch *gdbarch, int gcc_p, struct type *value_type)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->use_struct_convention == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_use_struct_convention invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_use_struct_convention called\n");
+ return gdbarch->use_struct_convention (gcc_p, value_type);
+}
+
+void
+set_gdbarch_use_struct_convention (struct gdbarch *gdbarch,
+ gdbarch_use_struct_convention_ftype use_struct_convention)
+{
+ gdbarch->use_struct_convention = use_struct_convention;
+}
+
+void
+gdbarch_frame_init_saved_regs (struct gdbarch *gdbarch, struct frame_info *frame)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->frame_init_saved_regs == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_frame_init_saved_regs invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_init_saved_regs called\n");
+ gdbarch->frame_init_saved_regs (frame);
+}
+
+void
+set_gdbarch_frame_init_saved_regs (struct gdbarch *gdbarch,
+ gdbarch_frame_init_saved_regs_ftype frame_init_saved_regs)
+{
+ gdbarch->frame_init_saved_regs = frame_init_saved_regs;
+}
+
+int
+gdbarch_init_extra_frame_info_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->init_extra_frame_info != 0;
+}
+
+void
+gdbarch_init_extra_frame_info (struct gdbarch *gdbarch, int fromleaf, struct frame_info *frame)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->init_extra_frame_info == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_init_extra_frame_info invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_init_extra_frame_info called\n");
+ gdbarch->init_extra_frame_info (fromleaf, frame);
+}
+
+void
+set_gdbarch_init_extra_frame_info (struct gdbarch *gdbarch,
+ gdbarch_init_extra_frame_info_ftype init_extra_frame_info)
+{
+ gdbarch->init_extra_frame_info = init_extra_frame_info;
+}
+
+CORE_ADDR
+gdbarch_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR ip)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->skip_prologue == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_skip_prologue invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_skip_prologue called\n");
+ return gdbarch->skip_prologue (ip);
+}
+
+void
+set_gdbarch_skip_prologue (struct gdbarch *gdbarch,
+ gdbarch_skip_prologue_ftype skip_prologue)
+{
+ gdbarch->skip_prologue = skip_prologue;
+}
+
+int
+gdbarch_prologue_frameless_p (struct gdbarch *gdbarch, CORE_ADDR ip)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->prologue_frameless_p == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_prologue_frameless_p invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_prologue_frameless_p called\n");
+ return gdbarch->prologue_frameless_p (ip);
+}
+
+void
+set_gdbarch_prologue_frameless_p (struct gdbarch *gdbarch,
+ gdbarch_prologue_frameless_p_ftype prologue_frameless_p)
+{
+ gdbarch->prologue_frameless_p = prologue_frameless_p;
+}
+
+int
+gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->inner_than == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_inner_than invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_inner_than called\n");
+ return gdbarch->inner_than (lhs, rhs);
+}
+
+void
+set_gdbarch_inner_than (struct gdbarch *gdbarch,
+ gdbarch_inner_than_ftype inner_than)
+{
+ gdbarch->inner_than = inner_than;
+}
+
+const unsigned char *
+gdbarch_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->breakpoint_from_pc == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_breakpoint_from_pc invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_breakpoint_from_pc called\n");
+ return gdbarch->breakpoint_from_pc (pcptr, lenptr);
+}
+
+void
+set_gdbarch_breakpoint_from_pc (struct gdbarch *gdbarch,
+ gdbarch_breakpoint_from_pc_ftype breakpoint_from_pc)
+{
+ gdbarch->breakpoint_from_pc = breakpoint_from_pc;
+}
+
+int
+gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, CORE_ADDR addr, char *contents_cache)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->memory_insert_breakpoint == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_memory_insert_breakpoint invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_memory_insert_breakpoint called\n");
+ return gdbarch->memory_insert_breakpoint (addr, contents_cache);
+}
+
+void
+set_gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch,
+ gdbarch_memory_insert_breakpoint_ftype memory_insert_breakpoint)
+{
+ gdbarch->memory_insert_breakpoint = memory_insert_breakpoint;
+}
+
+int
+gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch, CORE_ADDR addr, char *contents_cache)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->memory_remove_breakpoint == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_memory_remove_breakpoint invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_memory_remove_breakpoint called\n");
+ return gdbarch->memory_remove_breakpoint (addr, contents_cache);
+}
+
+void
+set_gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch,
+ gdbarch_memory_remove_breakpoint_ftype memory_remove_breakpoint)
+{
+ gdbarch->memory_remove_breakpoint = memory_remove_breakpoint;
+}
+
+CORE_ADDR
+gdbarch_decr_pc_after_break (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->decr_pc_after_break == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_decr_pc_after_break invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_decr_pc_after_break called\n");
+ return gdbarch->decr_pc_after_break;
+}
+
+void
+set_gdbarch_decr_pc_after_break (struct gdbarch *gdbarch,
+ CORE_ADDR decr_pc_after_break)
+{
+ gdbarch->decr_pc_after_break = decr_pc_after_break;
+}
+
+int
+gdbarch_prepare_to_proceed (struct gdbarch *gdbarch, int select_it)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->prepare_to_proceed == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_prepare_to_proceed invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_prepare_to_proceed called\n");
+ return gdbarch->prepare_to_proceed (select_it);
+}
+
+void
+set_gdbarch_prepare_to_proceed (struct gdbarch *gdbarch,
+ gdbarch_prepare_to_proceed_ftype prepare_to_proceed)
+{
+ gdbarch->prepare_to_proceed = prepare_to_proceed;
+}
+
+CORE_ADDR
+gdbarch_function_start_offset (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->function_start_offset == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_function_start_offset invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_function_start_offset called\n");
+ return gdbarch->function_start_offset;
+}
+
+void
+set_gdbarch_function_start_offset (struct gdbarch *gdbarch,
+ CORE_ADDR function_start_offset)
+{
+ gdbarch->function_start_offset = function_start_offset;
+}
+
+void
+gdbarch_remote_translate_xfer_address (struct gdbarch *gdbarch, CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR *rem_addr, int *rem_len)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->remote_translate_xfer_address == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_remote_translate_xfer_address invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_remote_translate_xfer_address called\n");
+ gdbarch->remote_translate_xfer_address (gdb_addr, gdb_len, rem_addr, rem_len);
+}
+
+void
+set_gdbarch_remote_translate_xfer_address (struct gdbarch *gdbarch,
+ gdbarch_remote_translate_xfer_address_ftype remote_translate_xfer_address)
+{
+ gdbarch->remote_translate_xfer_address = remote_translate_xfer_address;
+}
+
+CORE_ADDR
+gdbarch_frame_args_skip (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->frame_args_skip == -1)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_frame_args_skip invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_args_skip called\n");
+ return gdbarch->frame_args_skip;
+}
+
+void
+set_gdbarch_frame_args_skip (struct gdbarch *gdbarch,
+ CORE_ADDR frame_args_skip)
+{
+ gdbarch->frame_args_skip = frame_args_skip;
+}
+
+int
+gdbarch_frameless_function_invocation (struct gdbarch *gdbarch, struct frame_info *fi)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->frameless_function_invocation == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_frameless_function_invocation invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_frameless_function_invocation called\n");
+ return gdbarch->frameless_function_invocation (fi);
+}
+
+void
+set_gdbarch_frameless_function_invocation (struct gdbarch *gdbarch,
+ gdbarch_frameless_function_invocation_ftype frameless_function_invocation)
+{
+ gdbarch->frameless_function_invocation = frameless_function_invocation;
+}
+
+CORE_ADDR
+gdbarch_frame_chain (struct gdbarch *gdbarch, struct frame_info *frame)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->frame_chain == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_frame_chain invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_chain called\n");
+ return gdbarch->frame_chain (frame);
+}
+
+void
+set_gdbarch_frame_chain (struct gdbarch *gdbarch,
+ gdbarch_frame_chain_ftype frame_chain)
+{
+ gdbarch->frame_chain = frame_chain;
+}
+
+int
+gdbarch_frame_chain_valid (struct gdbarch *gdbarch, CORE_ADDR chain, struct frame_info *thisframe)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->frame_chain_valid == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_frame_chain_valid invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_chain_valid called\n");
+ return gdbarch->frame_chain_valid (chain, thisframe);
+}
+
+void
+set_gdbarch_frame_chain_valid (struct gdbarch *gdbarch,
+ gdbarch_frame_chain_valid_ftype frame_chain_valid)
+{
+ gdbarch->frame_chain_valid = frame_chain_valid;
+}
+
+CORE_ADDR
+gdbarch_frame_saved_pc (struct gdbarch *gdbarch, struct frame_info *fi)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->frame_saved_pc == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_frame_saved_pc invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_saved_pc called\n");
+ return gdbarch->frame_saved_pc (fi);
+}
+
+void
+set_gdbarch_frame_saved_pc (struct gdbarch *gdbarch,
+ gdbarch_frame_saved_pc_ftype frame_saved_pc)
+{
+ gdbarch->frame_saved_pc = frame_saved_pc;
+}
+
+CORE_ADDR
+gdbarch_frame_args_address (struct gdbarch *gdbarch, struct frame_info *fi)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->frame_args_address == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_frame_args_address invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_args_address called\n");
+ return gdbarch->frame_args_address (fi);
+}
+
+void
+set_gdbarch_frame_args_address (struct gdbarch *gdbarch,
+ gdbarch_frame_args_address_ftype frame_args_address)
+{
+ gdbarch->frame_args_address = frame_args_address;
+}
+
+CORE_ADDR
+gdbarch_frame_locals_address (struct gdbarch *gdbarch, struct frame_info *fi)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->frame_locals_address == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_frame_locals_address invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_locals_address called\n");
+ return gdbarch->frame_locals_address (fi);
+}
+
+void
+set_gdbarch_frame_locals_address (struct gdbarch *gdbarch,
+ gdbarch_frame_locals_address_ftype frame_locals_address)
+{
+ gdbarch->frame_locals_address = frame_locals_address;
+}
+
+CORE_ADDR
+gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, struct frame_info *frame)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->saved_pc_after_call == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_saved_pc_after_call invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_saved_pc_after_call called\n");
+ return gdbarch->saved_pc_after_call (frame);
+}
+
+void
+set_gdbarch_saved_pc_after_call (struct gdbarch *gdbarch,
+ gdbarch_saved_pc_after_call_ftype saved_pc_after_call)
+{
+ gdbarch->saved_pc_after_call = saved_pc_after_call;
+}
+
+int
+gdbarch_frame_num_args (struct gdbarch *gdbarch, struct frame_info *frame)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->frame_num_args == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_frame_num_args invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_frame_num_args called\n");
+ return gdbarch->frame_num_args (frame);
+}
+
+void
+set_gdbarch_frame_num_args (struct gdbarch *gdbarch,
+ gdbarch_frame_num_args_ftype frame_num_args)
+{
+ gdbarch->frame_num_args = frame_num_args;
+}
+
+int
+gdbarch_stack_align_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->stack_align != 0;
+}
+
+CORE_ADDR
+gdbarch_stack_align (struct gdbarch *gdbarch, CORE_ADDR sp)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->stack_align == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_stack_align invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_stack_align called\n");
+ return gdbarch->stack_align (sp);
+}
+
+void
+set_gdbarch_stack_align (struct gdbarch *gdbarch,
+ gdbarch_stack_align_ftype stack_align)
+{
+ gdbarch->stack_align = stack_align;
+}
+
+int
+gdbarch_extra_stack_alignment_needed (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of extra_stack_alignment_needed, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_extra_stack_alignment_needed called\n");
+ return gdbarch->extra_stack_alignment_needed;
+}
+
+void
+set_gdbarch_extra_stack_alignment_needed (struct gdbarch *gdbarch,
+ int extra_stack_alignment_needed)
+{
+ gdbarch->extra_stack_alignment_needed = extra_stack_alignment_needed;
+}
+
+int
+gdbarch_reg_struct_has_addr_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->reg_struct_has_addr != 0;
+}
+
+int
+gdbarch_reg_struct_has_addr (struct gdbarch *gdbarch, int gcc_p, struct type *type)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->reg_struct_has_addr == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_reg_struct_has_addr invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_reg_struct_has_addr called\n");
+ return gdbarch->reg_struct_has_addr (gcc_p, type);
+}
+
+void
+set_gdbarch_reg_struct_has_addr (struct gdbarch *gdbarch,
+ gdbarch_reg_struct_has_addr_ftype reg_struct_has_addr)
+{
+ gdbarch->reg_struct_has_addr = reg_struct_has_addr;
+}
+
+int
+gdbarch_save_dummy_frame_tos_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->save_dummy_frame_tos != 0;
+}
+
+void
+gdbarch_save_dummy_frame_tos (struct gdbarch *gdbarch, CORE_ADDR sp)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->save_dummy_frame_tos == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_save_dummy_frame_tos invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_save_dummy_frame_tos called\n");
+ gdbarch->save_dummy_frame_tos (sp);
+}
+
+void
+set_gdbarch_save_dummy_frame_tos (struct gdbarch *gdbarch,
+ gdbarch_save_dummy_frame_tos_ftype save_dummy_frame_tos)
+{
+ gdbarch->save_dummy_frame_tos = save_dummy_frame_tos;
+}
+
+int
+gdbarch_parm_boundary (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_parm_boundary called\n");
+ return gdbarch->parm_boundary;
+}
+
+void
+set_gdbarch_parm_boundary (struct gdbarch *gdbarch,
+ int parm_boundary)
+{
+ gdbarch->parm_boundary = parm_boundary;
+}
+
+const struct floatformat *
+gdbarch_float_format (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_float_format called\n");
+ return gdbarch->float_format;
+}
+
+void
+set_gdbarch_float_format (struct gdbarch *gdbarch,
+ const struct floatformat * float_format)
+{
+ gdbarch->float_format = float_format;
+}
+
+const struct floatformat *
+gdbarch_double_format (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_double_format called\n");
+ return gdbarch->double_format;
+}
+
+void
+set_gdbarch_double_format (struct gdbarch *gdbarch,
+ const struct floatformat * double_format)
+{
+ gdbarch->double_format = double_format;
+}
+
+const struct floatformat *
+gdbarch_long_double_format (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_long_double_format called\n");
+ return gdbarch->long_double_format;
+}
+
+void
+set_gdbarch_long_double_format (struct gdbarch *gdbarch,
+ const struct floatformat * long_double_format)
+{
+ gdbarch->long_double_format = long_double_format;
+}
+
+CORE_ADDR
+gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->convert_from_func_ptr_addr == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_convert_from_func_ptr_addr invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_convert_from_func_ptr_addr called\n");
+ return gdbarch->convert_from_func_ptr_addr (addr);
+}
+
+void
+set_gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
+ gdbarch_convert_from_func_ptr_addr_ftype convert_from_func_ptr_addr)
+{
+ gdbarch->convert_from_func_ptr_addr = convert_from_func_ptr_addr;
+}
+
+CORE_ADDR
+gdbarch_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->addr_bits_remove == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_addr_bits_remove invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_addr_bits_remove called\n");
+ return gdbarch->addr_bits_remove (addr);
+}
+
+void
+set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch,
+ gdbarch_addr_bits_remove_ftype addr_bits_remove)
+{
+ gdbarch->addr_bits_remove = addr_bits_remove;
+}
+
+CORE_ADDR
+gdbarch_smash_text_address (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->smash_text_address == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_smash_text_address invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_smash_text_address called\n");
+ return gdbarch->smash_text_address (addr);
+}
+
+void
+set_gdbarch_smash_text_address (struct gdbarch *gdbarch,
+ gdbarch_smash_text_address_ftype smash_text_address)
+{
+ gdbarch->smash_text_address = smash_text_address;
+}
+
+int
+gdbarch_software_single_step_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->software_single_step != 0;
+}
+
+void
+gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->software_single_step == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_software_single_step invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_software_single_step called\n");
+ gdbarch->software_single_step (sig, insert_breakpoints_p);
+}
+
+void
+set_gdbarch_software_single_step (struct gdbarch *gdbarch,
+ gdbarch_software_single_step_ftype software_single_step)
+{
+ gdbarch->software_single_step = software_single_step;
+}
+
+int
+gdbarch_print_insn (struct gdbarch *gdbarch, bfd_vma vma, disassemble_info *info)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->print_insn == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_print_insn invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_print_insn called\n");
+ return gdbarch->print_insn (vma, info);
+}
+
+void
+set_gdbarch_print_insn (struct gdbarch *gdbarch,
+ gdbarch_print_insn_ftype print_insn)
+{
+ gdbarch->print_insn = print_insn;
+}
+
+CORE_ADDR
+gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->skip_trampoline_code == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_skip_trampoline_code invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_skip_trampoline_code called\n");
+ return gdbarch->skip_trampoline_code (pc);
+}
+
+void
+set_gdbarch_skip_trampoline_code (struct gdbarch *gdbarch,
+ gdbarch_skip_trampoline_code_ftype skip_trampoline_code)
+{
+ gdbarch->skip_trampoline_code = skip_trampoline_code;
+}
+
+int
+gdbarch_in_solib_call_trampoline (struct gdbarch *gdbarch, CORE_ADDR pc, char *name)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->in_solib_call_trampoline == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_in_solib_call_trampoline invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_in_solib_call_trampoline called\n");
+ return gdbarch->in_solib_call_trampoline (pc, name);
+}
+
+void
+set_gdbarch_in_solib_call_trampoline (struct gdbarch *gdbarch,
+ gdbarch_in_solib_call_trampoline_ftype in_solib_call_trampoline)
+{
+ gdbarch->in_solib_call_trampoline = in_solib_call_trampoline;
+}
+
+int
+gdbarch_pc_in_sigtramp (struct gdbarch *gdbarch, CORE_ADDR pc, char *name)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->pc_in_sigtramp == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_pc_in_sigtramp invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_pc_in_sigtramp called\n");
+ return gdbarch->pc_in_sigtramp (pc, name);
+}
+
+void
+set_gdbarch_pc_in_sigtramp (struct gdbarch *gdbarch,
+ gdbarch_pc_in_sigtramp_ftype pc_in_sigtramp)
+{
+ gdbarch->pc_in_sigtramp = pc_in_sigtramp;
+}
+
+int
+gdbarch_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->in_function_epilogue_p == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_in_function_epilogue_p invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_in_function_epilogue_p called\n");
+ return gdbarch->in_function_epilogue_p (gdbarch, addr);
+}
+
+void
+set_gdbarch_in_function_epilogue_p (struct gdbarch *gdbarch,
+ gdbarch_in_function_epilogue_p_ftype in_function_epilogue_p)
+{
+ gdbarch->in_function_epilogue_p = in_function_epilogue_p;
+}
+
+char *
+gdbarch_construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->construct_inferior_arguments == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_construct_inferior_arguments invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_construct_inferior_arguments called\n");
+ return gdbarch->construct_inferior_arguments (gdbarch, argc, argv);
+}
+
+void
+set_gdbarch_construct_inferior_arguments (struct gdbarch *gdbarch,
+ gdbarch_construct_inferior_arguments_ftype construct_inferior_arguments)
+{
+ gdbarch->construct_inferior_arguments = construct_inferior_arguments;
+}
+
+int
+gdbarch_dwarf2_build_frame_info_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->dwarf2_build_frame_info != 0;
+}
+
+void
+gdbarch_dwarf2_build_frame_info (struct gdbarch *gdbarch, struct objfile *objfile)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->dwarf2_build_frame_info == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_dwarf2_build_frame_info invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_dwarf2_build_frame_info called\n");
+ gdbarch->dwarf2_build_frame_info (objfile);
+}
+
+void
+set_gdbarch_dwarf2_build_frame_info (struct gdbarch *gdbarch,
+ gdbarch_dwarf2_build_frame_info_ftype dwarf2_build_frame_info)
+{
+ gdbarch->dwarf2_build_frame_info = dwarf2_build_frame_info;
+}
+
+void
+gdbarch_elf_make_msymbol_special (struct gdbarch *gdbarch, asymbol *sym, struct minimal_symbol *msym)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->elf_make_msymbol_special == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_elf_make_msymbol_special invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_elf_make_msymbol_special called\n");
+ gdbarch->elf_make_msymbol_special (sym, msym);
+}
+
+void
+set_gdbarch_elf_make_msymbol_special (struct gdbarch *gdbarch,
+ gdbarch_elf_make_msymbol_special_ftype elf_make_msymbol_special)
+{
+ gdbarch->elf_make_msymbol_special = elf_make_msymbol_special;
+}
+
+void
+gdbarch_coff_make_msymbol_special (struct gdbarch *gdbarch, int val, struct minimal_symbol *msym)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->coff_make_msymbol_special == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_coff_make_msymbol_special invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_coff_make_msymbol_special called\n");
+ gdbarch->coff_make_msymbol_special (val, msym);
+}
+
+void
+set_gdbarch_coff_make_msymbol_special (struct gdbarch *gdbarch,
+ gdbarch_coff_make_msymbol_special_ftype coff_make_msymbol_special)
+{
+ gdbarch->coff_make_msymbol_special = coff_make_msymbol_special;
+}
+
+
+/* Keep a registry of per-architecture data-pointers required by GDB
+ modules. */
+
+struct gdbarch_data
+{
+ unsigned index;
+ gdbarch_data_init_ftype *init;
+ gdbarch_data_free_ftype *free;
+};
+
+struct gdbarch_data_registration
+{
+ struct gdbarch_data *data;
+ struct gdbarch_data_registration *next;
+};
+
+struct gdbarch_data_registry
+{
+ unsigned nr;
+ struct gdbarch_data_registration *registrations;
+};
+
+struct gdbarch_data_registry gdbarch_data_registry =
+{
+ 0, NULL,
+};
+
+struct gdbarch_data *
+register_gdbarch_data (gdbarch_data_init_ftype *init,
+ gdbarch_data_free_ftype *free)
+{
+ struct gdbarch_data_registration **curr;
+ for (curr = &gdbarch_data_registry.registrations;
+ (*curr) != NULL;
+ curr = &(*curr)->next);
+ (*curr) = XMALLOC (struct gdbarch_data_registration);
+ (*curr)->next = NULL;
+ (*curr)->data = XMALLOC (struct gdbarch_data);
+ (*curr)->data->index = gdbarch_data_registry.nr++;
+ (*curr)->data->init = init;
+ (*curr)->data->free = free;
+ return (*curr)->data;
+}
+
+
+/* Walk through all the registered users initializing each in turn. */
+
+static void
+init_gdbarch_data (struct gdbarch *gdbarch)
+{
+ struct gdbarch_data_registration *rego;
+ for (rego = gdbarch_data_registry.registrations;
+ rego != NULL;
+ rego = rego->next)
+ {
+ struct gdbarch_data *data = rego->data;
+ gdb_assert (data->index < gdbarch->nr_data);
+ if (data->init != NULL)
+ {
+ void *pointer = data->init (gdbarch);
+ set_gdbarch_data (gdbarch, data, pointer);
+ }
+ }
+}
+
+/* Create/delete the gdbarch data vector. */
+
+static void
+alloc_gdbarch_data (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch->data == NULL);
+ gdbarch->nr_data = gdbarch_data_registry.nr;
+ gdbarch->data = xcalloc (gdbarch->nr_data, sizeof (void*));
+}
+
+static void
+free_gdbarch_data (struct gdbarch *gdbarch)
+{
+ struct gdbarch_data_registration *rego;
+ gdb_assert (gdbarch->data != NULL);
+ for (rego = gdbarch_data_registry.registrations;
+ rego != NULL;
+ rego = rego->next)
+ {
+ struct gdbarch_data *data = rego->data;
+ gdb_assert (data->index < gdbarch->nr_data);
+ if (data->free != NULL && gdbarch->data[data->index] != NULL)
+ {
+ data->free (gdbarch, gdbarch->data[data->index]);
+ gdbarch->data[data->index] = NULL;
+ }
+ }
+ xfree (gdbarch->data);
+ gdbarch->data = NULL;
+}
+
+
+/* Initialize the current value of thee specified per-architecture
+ data-pointer. */
+
+void
+set_gdbarch_data (struct gdbarch *gdbarch,
+ struct gdbarch_data *data,
+ void *pointer)
+{
+ gdb_assert (data->index < gdbarch->nr_data);
+ if (data->free != NULL && gdbarch->data[data->index] != NULL)
+ data->free (gdbarch, gdbarch->data[data->index]);
+ gdbarch->data[data->index] = pointer;
+}
+
+/* Return the current value of the specified per-architecture
+ data-pointer. */
+
+void *
+gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data)
+{
+ gdb_assert (data->index < gdbarch->nr_data);
+ return gdbarch->data[data->index];
+}
+
+
+
+/* Keep a registry of swapped data required by GDB modules. */
+
+struct gdbarch_swap
+{
+ void *swap;
+ struct gdbarch_swap_registration *source;
+ struct gdbarch_swap *next;
+};
+
+struct gdbarch_swap_registration
+{
+ void *data;
+ unsigned long sizeof_data;
+ gdbarch_swap_ftype *init;
+ struct gdbarch_swap_registration *next;
+};
+
+struct gdbarch_swap_registry
+{
+ int nr;
+ struct gdbarch_swap_registration *registrations;
+};
+
+struct gdbarch_swap_registry gdbarch_swap_registry =
+{
+ 0, NULL,
+};
+
+void
+register_gdbarch_swap (void *data,
+ unsigned long sizeof_data,
+ gdbarch_swap_ftype *init)
+{
+ struct gdbarch_swap_registration **rego;
+ for (rego = &gdbarch_swap_registry.registrations;
+ (*rego) != NULL;
+ rego = &(*rego)->next);
+ (*rego) = XMALLOC (struct gdbarch_swap_registration);
+ (*rego)->next = NULL;
+ (*rego)->init = init;
+ (*rego)->data = data;
+ (*rego)->sizeof_data = sizeof_data;
+}
+
+static void
+clear_gdbarch_swap (struct gdbarch *gdbarch)
+{
+ struct gdbarch_swap *curr;
+ for (curr = gdbarch->swap;
+ curr != NULL;
+ curr = curr->next)
+ {
+ memset (curr->source->data, 0, curr->source->sizeof_data);
+ }
+}
+
+static void
+init_gdbarch_swap (struct gdbarch *gdbarch)
+{
+ struct gdbarch_swap_registration *rego;
+ struct gdbarch_swap **curr = &gdbarch->swap;
+ for (rego = gdbarch_swap_registry.registrations;
+ rego != NULL;
+ rego = rego->next)
+ {
+ if (rego->data != NULL)
+ {
+ (*curr) = XMALLOC (struct gdbarch_swap);
+ (*curr)->source = rego;
+ (*curr)->swap = xmalloc (rego->sizeof_data);
+ (*curr)->next = NULL;
+ curr = &(*curr)->next;
+ }
+ if (rego->init != NULL)
+ rego->init ();
+ }
+}
+
+static void
+swapout_gdbarch_swap (struct gdbarch *gdbarch)
+{
+ struct gdbarch_swap *curr;
+ for (curr = gdbarch->swap;
+ curr != NULL;
+ curr = curr->next)
+ memcpy (curr->swap, curr->source->data, curr->source->sizeof_data);
+}
+
+static void
+swapin_gdbarch_swap (struct gdbarch *gdbarch)
+{
+ struct gdbarch_swap *curr;
+ for (curr = gdbarch->swap;
+ curr != NULL;
+ curr = curr->next)
+ memcpy (curr->source->data, curr->swap, curr->source->sizeof_data);
+}
+
+
+/* Keep a registry of the architectures known by GDB. */
+
+struct gdbarch_registration
+{
+ enum bfd_architecture bfd_architecture;
+ gdbarch_init_ftype *init;
+ gdbarch_dump_tdep_ftype *dump_tdep;
+ struct gdbarch_list *arches;
+ struct gdbarch_registration *next;
+};
+
+static struct gdbarch_registration *gdbarch_registry = NULL;
+
+static void
+append_name (const char ***buf, int *nr, const char *name)
+{
+ *buf = xrealloc (*buf, sizeof (char**) * (*nr + 1));
+ (*buf)[*nr] = name;
+ *nr += 1;
+}
+
+const char **
+gdbarch_printable_names (void)
+{
+ if (GDB_MULTI_ARCH)
+ {
+ /* Accumulate a list of names based on the registed list of
+ architectures. */
+ enum bfd_architecture a;
+ int nr_arches = 0;
+ const char **arches = NULL;
+ struct gdbarch_registration *rego;
+ for (rego = gdbarch_registry;
+ rego != NULL;
+ rego = rego->next)
+ {
+ const struct bfd_arch_info *ap;
+ ap = bfd_lookup_arch (rego->bfd_architecture, 0);
+ if (ap == NULL)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch_architecture_names: multi-arch unknown");
+ do
+ {
+ append_name (&arches, &nr_arches, ap->printable_name);
+ ap = ap->next;
+ }
+ while (ap != NULL);
+ }
+ append_name (&arches, &nr_arches, NULL);
+ return arches;
+ }
+ else
+ /* Just return all the architectures that BFD knows. Assume that
+ the legacy architecture framework supports them. */
+ return bfd_arch_list ();
+}
+
+
+void
+gdbarch_register (enum bfd_architecture bfd_architecture,
+ gdbarch_init_ftype *init,
+ gdbarch_dump_tdep_ftype *dump_tdep)
+{
+ struct gdbarch_registration **curr;
+ const struct bfd_arch_info *bfd_arch_info;
+ /* Check that BFD recognizes this architecture */
+ bfd_arch_info = bfd_lookup_arch (bfd_architecture, 0);
+ if (bfd_arch_info == NULL)
+ {
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: Attempt to register unknown architecture (%d)",
+ bfd_architecture);
+ }
+ /* Check that we haven't seen this architecture before */
+ for (curr = &gdbarch_registry;
+ (*curr) != NULL;
+ curr = &(*curr)->next)
+ {
+ if (bfd_architecture == (*curr)->bfd_architecture)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: Duplicate registraration of architecture (%s)",
+ bfd_arch_info->printable_name);
+ }
+ /* log it */
+ if (gdbarch_debug)
+ fprintf_unfiltered (gdb_stdlog, "register_gdbarch_init (%s, 0x%08lx)\n",
+ bfd_arch_info->printable_name,
+ (long) init);
+ /* Append it */
+ (*curr) = XMALLOC (struct gdbarch_registration);
+ (*curr)->bfd_architecture = bfd_architecture;
+ (*curr)->init = init;
+ (*curr)->dump_tdep = dump_tdep;
+ (*curr)->arches = NULL;
+ (*curr)->next = NULL;
+ /* When non- multi-arch, install whatever target dump routine we've
+ been provided - hopefully that routine has been written correctly
+ and works regardless of multi-arch. */
+ if (!GDB_MULTI_ARCH && dump_tdep != NULL
+ && startup_gdbarch.dump_tdep == NULL)
+ startup_gdbarch.dump_tdep = dump_tdep;
+}
+
+void
+register_gdbarch_init (enum bfd_architecture bfd_architecture,
+ gdbarch_init_ftype *init)
+{
+ gdbarch_register (bfd_architecture, init, NULL);
+}
+
+
+/* Look for an architecture using gdbarch_info. Base search on only
+ BFD_ARCH_INFO and BYTE_ORDER. */
+
+struct gdbarch_list *
+gdbarch_list_lookup_by_info (struct gdbarch_list *arches,
+ const struct gdbarch_info *info)
+{
+ for (; arches != NULL; arches = arches->next)
+ {
+ if (info->bfd_arch_info != arches->gdbarch->bfd_arch_info)
+ continue;
+ if (info->byte_order != arches->gdbarch->byte_order)
+ continue;
+ return arches;
+ }
+ return NULL;
+}
+
+
+/* Update the current architecture. Return ZERO if the update request
+ failed. */
+
+int
+gdbarch_update_p (struct gdbarch_info info)
+{
+ struct gdbarch *new_gdbarch;
+ struct gdbarch *old_gdbarch;
+ struct gdbarch_registration *rego;
+
+ /* Fill in missing parts of the INFO struct using a number of
+ sources: ``set ...''; INFOabfd supplied; existing target. */
+
+ /* ``(gdb) set architecture ...'' */
+ if (info.bfd_arch_info == NULL
+ && !TARGET_ARCHITECTURE_AUTO)
+ info.bfd_arch_info = TARGET_ARCHITECTURE;
+ if (info.bfd_arch_info == NULL
+ && info.abfd != NULL
+ && bfd_get_arch (info.abfd) != bfd_arch_unknown
+ && bfd_get_arch (info.abfd) != bfd_arch_obscure)
+ info.bfd_arch_info = bfd_get_arch_info (info.abfd);
+ if (info.bfd_arch_info == NULL)
+ info.bfd_arch_info = TARGET_ARCHITECTURE;
+
+ /* ``(gdb) set byte-order ...'' */
+ if (info.byte_order == BFD_ENDIAN_UNKNOWN
+ && !TARGET_BYTE_ORDER_AUTO)
+ info.byte_order = TARGET_BYTE_ORDER;
+ /* From the INFO struct. */
+ if (info.byte_order == BFD_ENDIAN_UNKNOWN
+ && info.abfd != NULL)
+ info.byte_order = (bfd_big_endian (info.abfd) ? BFD_ENDIAN_BIG
+ : bfd_little_endian (info.abfd) ? BFD_ENDIAN_LITTLE
+ : BFD_ENDIAN_UNKNOWN);
+ /* From the current target. */
+ if (info.byte_order == BFD_ENDIAN_UNKNOWN)
+ info.byte_order = TARGET_BYTE_ORDER;
+
+ /* Must have found some sort of architecture. */
+ gdb_assert (info.bfd_arch_info != NULL);
+
+ if (gdbarch_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "gdbarch_update: info.bfd_arch_info %s\n",
+ (info.bfd_arch_info != NULL
+ ? info.bfd_arch_info->printable_name
+ : "(null)"));
+ fprintf_unfiltered (gdb_stdlog,
+ "gdbarch_update: info.byte_order %d (%s)\n",
+ info.byte_order,
+ (info.byte_order == BFD_ENDIAN_BIG ? "big"
+ : info.byte_order == BFD_ENDIAN_LITTLE ? "little"
+ : "default"));
+ fprintf_unfiltered (gdb_stdlog,
+ "gdbarch_update: info.abfd 0x%lx\n",
+ (long) info.abfd);
+ fprintf_unfiltered (gdb_stdlog,
+ "gdbarch_update: info.tdep_info 0x%lx\n",
+ (long) info.tdep_info);
+ }
+
+ /* Find the target that knows about this architecture. */
+ for (rego = gdbarch_registry;
+ rego != NULL;
+ rego = rego->next)
+ if (rego->bfd_architecture == info.bfd_arch_info->arch)
+ break;
+ if (rego == NULL)
+ {
+ if (gdbarch_debug)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_update: No matching architecture\n");
+ return 0;
+ }
+
+ /* Swap the data belonging to the old target out setting the
+ installed data to zero. This stops the ->init() function trying
+ to refer to the previous architecture's global data structures. */
+ swapout_gdbarch_swap (current_gdbarch);
+ clear_gdbarch_swap (current_gdbarch);
+
+ /* Save the previously selected architecture, setting the global to
+ NULL. This stops ->init() trying to use the previous
+ architecture's configuration. The previous architecture may not
+ even be of the same architecture family. The most recent
+ architecture of the same family is found at the head of the
+ rego->arches list. */
+ old_gdbarch = current_gdbarch;
+ current_gdbarch = NULL;
+
+ /* Ask the target for a replacement architecture. */
+ new_gdbarch = rego->init (info, rego->arches);
+
+ /* Did the target like it? No. Reject the change and revert to the
+ old architecture. */
+ if (new_gdbarch == NULL)
+ {
+ if (gdbarch_debug)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Target rejected architecture\n");
+ swapin_gdbarch_swap (old_gdbarch);
+ current_gdbarch = old_gdbarch;
+ return 0;
+ }
+
+ /* Did the architecture change? No. Oops, put the old architecture
+ back. */
+ if (old_gdbarch == new_gdbarch)
+ {
+ if (gdbarch_debug)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Architecture 0x%08lx (%s) unchanged\n",
+ (long) new_gdbarch,
+ new_gdbarch->bfd_arch_info->printable_name);
+ swapin_gdbarch_swap (old_gdbarch);
+ current_gdbarch = old_gdbarch;
+ return 1;
+ }
+
+ /* Is this a pre-existing architecture? Yes. Move it to the front
+ of the list of architectures (keeping the list sorted Most
+ Recently Used) and then copy it in. */
+ {
+ struct gdbarch_list **list;
+ for (list = &rego->arches;
+ (*list) != NULL;
+ list = &(*list)->next)
+ {
+ if ((*list)->gdbarch == new_gdbarch)
+ {
+ struct gdbarch_list *this;
+ if (gdbarch_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "gdbarch_update: Previous architecture 0x%08lx (%s) selected\n",
+ (long) new_gdbarch,
+ new_gdbarch->bfd_arch_info->printable_name);
+ /* Unlink this. */
+ this = (*list);
+ (*list) = this->next;
+ /* Insert in the front. */
+ this->next = rego->arches;
+ rego->arches = this;
+ /* Copy the new architecture in. */
+ current_gdbarch = new_gdbarch;
+ swapin_gdbarch_swap (new_gdbarch);
+ architecture_changed_event ();
+ return 1;
+ }
+ }
+ }
+
+ /* Prepend this new architecture to the architecture list (keep the
+ list sorted Most Recently Used). */
+ {
+ struct gdbarch_list *this = XMALLOC (struct gdbarch_list);
+ this->next = rego->arches;
+ this->gdbarch = new_gdbarch;
+ rego->arches = this;
+ }
+
+ /* Switch to this new architecture. Dump it out. */
+ current_gdbarch = new_gdbarch;
+ if (gdbarch_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "gdbarch_update: New architecture 0x%08lx (%s) selected\n",
+ (long) new_gdbarch,
+ new_gdbarch->bfd_arch_info->printable_name);
+ }
+
+ /* Check that the newly installed architecture is valid. Plug in
+ any post init values. */
+ new_gdbarch->dump_tdep = rego->dump_tdep;
+ verify_gdbarch (new_gdbarch);
+
+ /* Initialize the per-architecture memory (swap) areas.
+ CURRENT_GDBARCH must be update before these modules are
+ called. */
+ init_gdbarch_swap (new_gdbarch);
+
+ /* Initialize the per-architecture data-pointer of all parties that
+ registered an interest in this architecture. CURRENT_GDBARCH
+ must be updated before these modules are called. */
+ init_gdbarch_data (new_gdbarch);
+ architecture_changed_event ();
+
+ if (gdbarch_debug)
+ gdbarch_dump (current_gdbarch, gdb_stdlog);
+
+ return 1;
+}
+
+
+/* Disassembler */
+
+/* Pointer to the target-dependent disassembly function. */
+int (*tm_print_insn) (bfd_vma, disassemble_info *);
+disassemble_info tm_print_insn_info;
+
+
+extern void _initialize_gdbarch (void);
+
+void
+_initialize_gdbarch (void)
+{
+ struct cmd_list_element *c;
+
+ INIT_DISASSEMBLE_INFO_NO_ARCH (tm_print_insn_info, gdb_stdout, (fprintf_ftype)fprintf_filtered);
+ tm_print_insn_info.flavour = bfd_target_unknown_flavour;
+ tm_print_insn_info.read_memory_func = dis_asm_read_memory;
+ tm_print_insn_info.memory_error_func = dis_asm_memory_error;
+ tm_print_insn_info.print_address_func = dis_asm_print_address;
+
+ add_show_from_set (add_set_cmd ("arch",
+ class_maintenance,
+ var_zinteger,
+ (char *)&gdbarch_debug,
+ "Set architecture debugging.\n\
+When non-zero, architecture debugging is enabled.", &setdebuglist),
+ &showdebuglist);
+ c = add_set_cmd ("archdebug",
+ class_maintenance,
+ var_zinteger,
+ (char *)&gdbarch_debug,
+ "Set architecture debugging.\n\
+When non-zero, architecture debugging is enabled.", &setlist);
+
+ deprecate_cmd (c, "set debug arch");
+ deprecate_cmd (add_show_from_set (c, &showlist), "show debug arch");
+}
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
new file mode 100644
index 00000000000..9f45459c95f
--- /dev/null
+++ b/gdb/gdbarch.h
@@ -0,0 +1,2711 @@
+/* *INDENT-OFF* */ /* THIS FILE IS GENERATED */
+
+/* Dynamic architecture support for GDB, the GNU debugger.
+ Copyright 1998, 1999, 2000, 2001, 2002 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. */
+
+/* This file was created with the aid of ``gdbarch.sh''.
+
+ The Bourne shell script ``gdbarch.sh'' creates the files
+ ``new-gdbarch.c'' and ``new-gdbarch.h and then compares them
+ against the existing ``gdbarch.[hc]''. Any differences found
+ being reported.
+
+ If editing this file, please also run gdbarch.sh and merge any
+ changes into that script. Conversely, when making sweeping changes
+ to this file, modifying gdbarch.sh and using its output may prove
+ easier. */
+
+#ifndef GDBARCH_H
+#define GDBARCH_H
+
+#include "dis-asm.h" /* Get defs for disassemble_info, which unfortunately is a typedef. */
+#if !GDB_MULTI_ARCH
+/* Pull in function declarations refered to, indirectly, via macros. */
+#include "value.h" /* For default_coerce_float_to_double which is referenced by a macro. */
+#include "inferior.h" /* For unsigned_address_to_pointer(). */
+#endif
+
+struct frame_info;
+struct value;
+struct objfile;
+struct minimal_symbol;
+
+extern struct gdbarch *current_gdbarch;
+
+
+/* If any of the following are defined, the target wasn't correctly
+ converted. */
+
+#if GDB_MULTI_ARCH
+#if defined (EXTRA_FRAME_INFO)
+#error "EXTRA_FRAME_INFO: replaced by struct frame_extra_info"
+#endif
+#endif
+
+#if GDB_MULTI_ARCH
+#if defined (FRAME_FIND_SAVED_REGS)
+#error "FRAME_FIND_SAVED_REGS: replaced by FRAME_INIT_SAVED_REGS"
+#endif
+#endif
+
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PURE) && defined (GDB_TM_FILE)
+#error "GDB_TM_FILE: Pure multi-arch targets do not have a tm.h file."
+#endif
+
+
+/* The following are pre-initialized by GDBARCH. */
+
+extern const struct bfd_arch_info * gdbarch_bfd_arch_info (struct gdbarch *gdbarch);
+/* set_gdbarch_bfd_arch_info() - not applicable - pre-initialized. */
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_ARCHITECTURE)
+#error "Non multi-arch definition of TARGET_ARCHITECTURE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_ARCHITECTURE)
+#define TARGET_ARCHITECTURE (gdbarch_bfd_arch_info (current_gdbarch))
+#endif
+#endif
+
+extern int gdbarch_byte_order (struct gdbarch *gdbarch);
+/* set_gdbarch_byte_order() - not applicable - pre-initialized. */
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_BYTE_ORDER)
+#error "Non multi-arch definition of TARGET_BYTE_ORDER"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_BYTE_ORDER)
+#define TARGET_BYTE_ORDER (gdbarch_byte_order (current_gdbarch))
+#endif
+#endif
+
+
+/* The following are initialized by the target dependent code. */
+
+/* Number of bits in a char or unsigned char for the target machine.
+ Just like CHAR_BIT in <limits.h> but describes the target machine.
+ v::TARGET_CHAR_BIT:int:char_bit::::8 * sizeof (char):8::0:
+
+ Number of bits in a short or unsigned short for the target machine. */
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_SHORT_BIT)
+#define TARGET_SHORT_BIT (2*TARGET_CHAR_BIT)
+#endif
+
+extern int gdbarch_short_bit (struct gdbarch *gdbarch);
+extern void set_gdbarch_short_bit (struct gdbarch *gdbarch, int short_bit);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_SHORT_BIT)
+#error "Non multi-arch definition of TARGET_SHORT_BIT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_SHORT_BIT)
+#define TARGET_SHORT_BIT (gdbarch_short_bit (current_gdbarch))
+#endif
+#endif
+
+/* Number of bits in an int or unsigned int for the target machine. */
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_INT_BIT)
+#define TARGET_INT_BIT (4*TARGET_CHAR_BIT)
+#endif
+
+extern int gdbarch_int_bit (struct gdbarch *gdbarch);
+extern void set_gdbarch_int_bit (struct gdbarch *gdbarch, int int_bit);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_INT_BIT)
+#error "Non multi-arch definition of TARGET_INT_BIT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_INT_BIT)
+#define TARGET_INT_BIT (gdbarch_int_bit (current_gdbarch))
+#endif
+#endif
+
+/* Number of bits in a long or unsigned long for the target machine. */
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_LONG_BIT)
+#define TARGET_LONG_BIT (4*TARGET_CHAR_BIT)
+#endif
+
+extern int gdbarch_long_bit (struct gdbarch *gdbarch);
+extern void set_gdbarch_long_bit (struct gdbarch *gdbarch, int long_bit);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_LONG_BIT)
+#error "Non multi-arch definition of TARGET_LONG_BIT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_LONG_BIT)
+#define TARGET_LONG_BIT (gdbarch_long_bit (current_gdbarch))
+#endif
+#endif
+
+/* Number of bits in a long long or unsigned long long for the target
+ machine. */
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_LONG_LONG_BIT)
+#define TARGET_LONG_LONG_BIT (2*TARGET_LONG_BIT)
+#endif
+
+extern int gdbarch_long_long_bit (struct gdbarch *gdbarch);
+extern void set_gdbarch_long_long_bit (struct gdbarch *gdbarch, int long_long_bit);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_LONG_LONG_BIT)
+#error "Non multi-arch definition of TARGET_LONG_LONG_BIT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_LONG_LONG_BIT)
+#define TARGET_LONG_LONG_BIT (gdbarch_long_long_bit (current_gdbarch))
+#endif
+#endif
+
+/* Number of bits in a float for the target machine. */
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_FLOAT_BIT)
+#define TARGET_FLOAT_BIT (4*TARGET_CHAR_BIT)
+#endif
+
+extern int gdbarch_float_bit (struct gdbarch *gdbarch);
+extern void set_gdbarch_float_bit (struct gdbarch *gdbarch, int float_bit);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_FLOAT_BIT)
+#error "Non multi-arch definition of TARGET_FLOAT_BIT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_FLOAT_BIT)
+#define TARGET_FLOAT_BIT (gdbarch_float_bit (current_gdbarch))
+#endif
+#endif
+
+/* Number of bits in a double for the target machine. */
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_DOUBLE_BIT)
+#define TARGET_DOUBLE_BIT (8*TARGET_CHAR_BIT)
+#endif
+
+extern int gdbarch_double_bit (struct gdbarch *gdbarch);
+extern void set_gdbarch_double_bit (struct gdbarch *gdbarch, int double_bit);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_DOUBLE_BIT)
+#error "Non multi-arch definition of TARGET_DOUBLE_BIT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_DOUBLE_BIT)
+#define TARGET_DOUBLE_BIT (gdbarch_double_bit (current_gdbarch))
+#endif
+#endif
+
+/* Number of bits in a long double for the target machine. */
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_LONG_DOUBLE_BIT)
+#define TARGET_LONG_DOUBLE_BIT (8*TARGET_CHAR_BIT)
+#endif
+
+extern int gdbarch_long_double_bit (struct gdbarch *gdbarch);
+extern void set_gdbarch_long_double_bit (struct gdbarch *gdbarch, int long_double_bit);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_LONG_DOUBLE_BIT)
+#error "Non multi-arch definition of TARGET_LONG_DOUBLE_BIT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_LONG_DOUBLE_BIT)
+#define TARGET_LONG_DOUBLE_BIT (gdbarch_long_double_bit (current_gdbarch))
+#endif
+#endif
+
+/* For most targets, a pointer on the target and its representation as an
+ address in GDB have the same size and "look the same". For such a
+ target, you need only set TARGET_PTR_BIT / ptr_bit and TARGET_ADDR_BIT
+ / addr_bit will be set from it.
+
+ If TARGET_PTR_BIT and TARGET_ADDR_BIT are different, you'll probably
+ also need to set POINTER_TO_ADDRESS and ADDRESS_TO_POINTER as well.
+
+ ptr_bit is the size of a pointer on the target */
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_PTR_BIT)
+#define TARGET_PTR_BIT (TARGET_INT_BIT)
+#endif
+
+extern int gdbarch_ptr_bit (struct gdbarch *gdbarch);
+extern void set_gdbarch_ptr_bit (struct gdbarch *gdbarch, int ptr_bit);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_PTR_BIT)
+#error "Non multi-arch definition of TARGET_PTR_BIT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_PTR_BIT)
+#define TARGET_PTR_BIT (gdbarch_ptr_bit (current_gdbarch))
+#endif
+#endif
+
+/* addr_bit is the size of a target address as represented in gdb */
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_ADDR_BIT)
+#define TARGET_ADDR_BIT (TARGET_PTR_BIT)
+#endif
+
+extern int gdbarch_addr_bit (struct gdbarch *gdbarch);
+extern void set_gdbarch_addr_bit (struct gdbarch *gdbarch, int addr_bit);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_ADDR_BIT)
+#error "Non multi-arch definition of TARGET_ADDR_BIT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_ADDR_BIT)
+#define TARGET_ADDR_BIT (gdbarch_addr_bit (current_gdbarch))
+#endif
+#endif
+
+/* Number of bits in a BFD_VMA for the target object file format. */
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_BFD_VMA_BIT)
+#define TARGET_BFD_VMA_BIT (TARGET_ARCHITECTURE->bits_per_address)
+#endif
+
+extern int gdbarch_bfd_vma_bit (struct gdbarch *gdbarch);
+extern void set_gdbarch_bfd_vma_bit (struct gdbarch *gdbarch, int bfd_vma_bit);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_BFD_VMA_BIT)
+#error "Non multi-arch definition of TARGET_BFD_VMA_BIT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_BFD_VMA_BIT)
+#define TARGET_BFD_VMA_BIT (gdbarch_bfd_vma_bit (current_gdbarch))
+#endif
+#endif
+
+/* One if `char' acts like `signed char', zero if `unsigned char'. */
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_CHAR_SIGNED)
+#define TARGET_CHAR_SIGNED (1)
+#endif
+
+extern int gdbarch_char_signed (struct gdbarch *gdbarch);
+extern void set_gdbarch_char_signed (struct gdbarch *gdbarch, int char_signed);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_CHAR_SIGNED)
+#error "Non multi-arch definition of TARGET_CHAR_SIGNED"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_CHAR_SIGNED)
+#define TARGET_CHAR_SIGNED (gdbarch_char_signed (current_gdbarch))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_READ_PC)
+#define TARGET_READ_PC(ptid) (generic_target_read_pc (ptid))
+#endif
+
+typedef CORE_ADDR (gdbarch_read_pc_ftype) (ptid_t ptid);
+extern CORE_ADDR gdbarch_read_pc (struct gdbarch *gdbarch, ptid_t ptid);
+extern void set_gdbarch_read_pc (struct gdbarch *gdbarch, gdbarch_read_pc_ftype *read_pc);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_READ_PC)
+#error "Non multi-arch definition of TARGET_READ_PC"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_READ_PC)
+#define TARGET_READ_PC(ptid) (gdbarch_read_pc (current_gdbarch, ptid))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_WRITE_PC)
+#define TARGET_WRITE_PC(val, ptid) (generic_target_write_pc (val, ptid))
+#endif
+
+typedef void (gdbarch_write_pc_ftype) (CORE_ADDR val, ptid_t ptid);
+extern void gdbarch_write_pc (struct gdbarch *gdbarch, CORE_ADDR val, ptid_t ptid);
+extern void set_gdbarch_write_pc (struct gdbarch *gdbarch, gdbarch_write_pc_ftype *write_pc);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_WRITE_PC)
+#error "Non multi-arch definition of TARGET_WRITE_PC"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_WRITE_PC)
+#define TARGET_WRITE_PC(val, ptid) (gdbarch_write_pc (current_gdbarch, val, ptid))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_READ_FP)
+#define TARGET_READ_FP() (generic_target_read_fp ())
+#endif
+
+typedef CORE_ADDR (gdbarch_read_fp_ftype) (void);
+extern CORE_ADDR gdbarch_read_fp (struct gdbarch *gdbarch);
+extern void set_gdbarch_read_fp (struct gdbarch *gdbarch, gdbarch_read_fp_ftype *read_fp);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_READ_FP)
+#error "Non multi-arch definition of TARGET_READ_FP"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_READ_FP)
+#define TARGET_READ_FP() (gdbarch_read_fp (current_gdbarch))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_READ_SP)
+#define TARGET_READ_SP() (generic_target_read_sp ())
+#endif
+
+typedef CORE_ADDR (gdbarch_read_sp_ftype) (void);
+extern CORE_ADDR gdbarch_read_sp (struct gdbarch *gdbarch);
+extern void set_gdbarch_read_sp (struct gdbarch *gdbarch, gdbarch_read_sp_ftype *read_sp);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_READ_SP)
+#error "Non multi-arch definition of TARGET_READ_SP"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_READ_SP)
+#define TARGET_READ_SP() (gdbarch_read_sp (current_gdbarch))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_WRITE_SP)
+#define TARGET_WRITE_SP(val) (generic_target_write_sp (val))
+#endif
+
+typedef void (gdbarch_write_sp_ftype) (CORE_ADDR val);
+extern void gdbarch_write_sp (struct gdbarch *gdbarch, CORE_ADDR val);
+extern void set_gdbarch_write_sp (struct gdbarch *gdbarch, gdbarch_write_sp_ftype *write_sp);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_WRITE_SP)
+#error "Non multi-arch definition of TARGET_WRITE_SP"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_WRITE_SP)
+#define TARGET_WRITE_SP(val) (gdbarch_write_sp (current_gdbarch, val))
+#endif
+#endif
+
+/* Function for getting target's idea of a frame pointer. FIXME: GDB's
+ whole scheme for dealing with "frames" and "frame pointers" needs a
+ serious shakedown. */
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_VIRTUAL_FRAME_POINTER)
+#define TARGET_VIRTUAL_FRAME_POINTER(pc, frame_regnum, frame_offset) (legacy_virtual_frame_pointer (pc, frame_regnum, frame_offset))
+#endif
+
+typedef void (gdbarch_virtual_frame_pointer_ftype) (CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset);
+extern void gdbarch_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset);
+extern void set_gdbarch_virtual_frame_pointer (struct gdbarch *gdbarch, gdbarch_virtual_frame_pointer_ftype *virtual_frame_pointer);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_VIRTUAL_FRAME_POINTER)
+#error "Non multi-arch definition of TARGET_VIRTUAL_FRAME_POINTER"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_VIRTUAL_FRAME_POINTER)
+#define TARGET_VIRTUAL_FRAME_POINTER(pc, frame_regnum, frame_offset) (gdbarch_virtual_frame_pointer (current_gdbarch, pc, frame_regnum, frame_offset))
+#endif
+#endif
+
+extern int gdbarch_register_read_p (struct gdbarch *gdbarch);
+
+typedef void (gdbarch_register_read_ftype) (struct gdbarch *gdbarch, int regnum, char *buf);
+extern void gdbarch_register_read (struct gdbarch *gdbarch, int regnum, char *buf);
+extern void set_gdbarch_register_read (struct gdbarch *gdbarch, gdbarch_register_read_ftype *register_read);
+
+extern int gdbarch_register_write_p (struct gdbarch *gdbarch);
+
+typedef void (gdbarch_register_write_ftype) (struct gdbarch *gdbarch, int regnum, char *buf);
+extern void gdbarch_register_write (struct gdbarch *gdbarch, int regnum, char *buf);
+extern void set_gdbarch_register_write (struct gdbarch *gdbarch, gdbarch_register_write_ftype *register_write);
+
+extern int gdbarch_num_regs (struct gdbarch *gdbarch);
+extern void set_gdbarch_num_regs (struct gdbarch *gdbarch, int num_regs);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (NUM_REGS)
+#error "Non multi-arch definition of NUM_REGS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (NUM_REGS)
+#define NUM_REGS (gdbarch_num_regs (current_gdbarch))
+#endif
+#endif
+
+/* This macro gives the number of pseudo-registers that live in the
+ register namespace but do not get fetched or stored on the target.
+ These pseudo-registers may be aliases for other registers,
+ combinations of other registers, or they may be computed by GDB. */
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (NUM_PSEUDO_REGS)
+#define NUM_PSEUDO_REGS (0)
+#endif
+
+extern int gdbarch_num_pseudo_regs (struct gdbarch *gdbarch);
+extern void set_gdbarch_num_pseudo_regs (struct gdbarch *gdbarch, int num_pseudo_regs);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (NUM_PSEUDO_REGS)
+#error "Non multi-arch definition of NUM_PSEUDO_REGS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (NUM_PSEUDO_REGS)
+#define NUM_PSEUDO_REGS (gdbarch_num_pseudo_regs (current_gdbarch))
+#endif
+#endif
+
+/* GDB's standard (or well known) register numbers. These can map onto
+ a real register or a pseudo (computed) register or not be defined at
+ all (-1). */
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (SP_REGNUM)
+#define SP_REGNUM (-1)
+#endif
+
+extern int gdbarch_sp_regnum (struct gdbarch *gdbarch);
+extern void set_gdbarch_sp_regnum (struct gdbarch *gdbarch, int sp_regnum);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SP_REGNUM)
+#error "Non multi-arch definition of SP_REGNUM"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SP_REGNUM)
+#define SP_REGNUM (gdbarch_sp_regnum (current_gdbarch))
+#endif
+#endif
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (FP_REGNUM)
+#define FP_REGNUM (-1)
+#endif
+
+extern int gdbarch_fp_regnum (struct gdbarch *gdbarch);
+extern void set_gdbarch_fp_regnum (struct gdbarch *gdbarch, int fp_regnum);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FP_REGNUM)
+#error "Non multi-arch definition of FP_REGNUM"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FP_REGNUM)
+#define FP_REGNUM (gdbarch_fp_regnum (current_gdbarch))
+#endif
+#endif
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (PC_REGNUM)
+#define PC_REGNUM (-1)
+#endif
+
+extern int gdbarch_pc_regnum (struct gdbarch *gdbarch);
+extern void set_gdbarch_pc_regnum (struct gdbarch *gdbarch, int pc_regnum);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PC_REGNUM)
+#error "Non multi-arch definition of PC_REGNUM"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PC_REGNUM)
+#define PC_REGNUM (gdbarch_pc_regnum (current_gdbarch))
+#endif
+#endif
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (PS_REGNUM)
+#define PS_REGNUM (-1)
+#endif
+
+extern int gdbarch_ps_regnum (struct gdbarch *gdbarch);
+extern void set_gdbarch_ps_regnum (struct gdbarch *gdbarch, int ps_regnum);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PS_REGNUM)
+#error "Non multi-arch definition of PS_REGNUM"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PS_REGNUM)
+#define PS_REGNUM (gdbarch_ps_regnum (current_gdbarch))
+#endif
+#endif
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (FP0_REGNUM)
+#define FP0_REGNUM (-1)
+#endif
+
+extern int gdbarch_fp0_regnum (struct gdbarch *gdbarch);
+extern void set_gdbarch_fp0_regnum (struct gdbarch *gdbarch, int fp0_regnum);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FP0_REGNUM)
+#error "Non multi-arch definition of FP0_REGNUM"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FP0_REGNUM)
+#define FP0_REGNUM (gdbarch_fp0_regnum (current_gdbarch))
+#endif
+#endif
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (NPC_REGNUM)
+#define NPC_REGNUM (-1)
+#endif
+
+extern int gdbarch_npc_regnum (struct gdbarch *gdbarch);
+extern void set_gdbarch_npc_regnum (struct gdbarch *gdbarch, int npc_regnum);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (NPC_REGNUM)
+#error "Non multi-arch definition of NPC_REGNUM"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (NPC_REGNUM)
+#define NPC_REGNUM (gdbarch_npc_regnum (current_gdbarch))
+#endif
+#endif
+
+/* Convert stab register number (from `r' declaration) to a gdb REGNUM. */
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (STAB_REG_TO_REGNUM)
+#define STAB_REG_TO_REGNUM(stab_regnr) (no_op_reg_to_regnum (stab_regnr))
+#endif
+
+typedef int (gdbarch_stab_reg_to_regnum_ftype) (int stab_regnr);
+extern int gdbarch_stab_reg_to_regnum (struct gdbarch *gdbarch, int stab_regnr);
+extern void set_gdbarch_stab_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_stab_reg_to_regnum_ftype *stab_reg_to_regnum);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (STAB_REG_TO_REGNUM)
+#error "Non multi-arch definition of STAB_REG_TO_REGNUM"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (STAB_REG_TO_REGNUM)
+#define STAB_REG_TO_REGNUM(stab_regnr) (gdbarch_stab_reg_to_regnum (current_gdbarch, stab_regnr))
+#endif
+#endif
+
+/* Provide a default mapping from a ecoff register number to a gdb REGNUM. */
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (ECOFF_REG_TO_REGNUM)
+#define ECOFF_REG_TO_REGNUM(ecoff_regnr) (no_op_reg_to_regnum (ecoff_regnr))
+#endif
+
+typedef int (gdbarch_ecoff_reg_to_regnum_ftype) (int ecoff_regnr);
+extern int gdbarch_ecoff_reg_to_regnum (struct gdbarch *gdbarch, int ecoff_regnr);
+extern void set_gdbarch_ecoff_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_ecoff_reg_to_regnum_ftype *ecoff_reg_to_regnum);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ECOFF_REG_TO_REGNUM)
+#error "Non multi-arch definition of ECOFF_REG_TO_REGNUM"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ECOFF_REG_TO_REGNUM)
+#define ECOFF_REG_TO_REGNUM(ecoff_regnr) (gdbarch_ecoff_reg_to_regnum (current_gdbarch, ecoff_regnr))
+#endif
+#endif
+
+/* Provide a default mapping from a DWARF register number to a gdb REGNUM. */
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (DWARF_REG_TO_REGNUM)
+#define DWARF_REG_TO_REGNUM(dwarf_regnr) (no_op_reg_to_regnum (dwarf_regnr))
+#endif
+
+typedef int (gdbarch_dwarf_reg_to_regnum_ftype) (int dwarf_regnr);
+extern int gdbarch_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int dwarf_regnr);
+extern void set_gdbarch_dwarf_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_dwarf_reg_to_regnum_ftype *dwarf_reg_to_regnum);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DWARF_REG_TO_REGNUM)
+#error "Non multi-arch definition of DWARF_REG_TO_REGNUM"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DWARF_REG_TO_REGNUM)
+#define DWARF_REG_TO_REGNUM(dwarf_regnr) (gdbarch_dwarf_reg_to_regnum (current_gdbarch, dwarf_regnr))
+#endif
+#endif
+
+/* Convert from an sdb register number to an internal gdb register number.
+ This should be defined in tm.h, if REGISTER_NAMES is not set up
+ to map one to one onto the sdb register numbers. */
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (SDB_REG_TO_REGNUM)
+#define SDB_REG_TO_REGNUM(sdb_regnr) (no_op_reg_to_regnum (sdb_regnr))
+#endif
+
+typedef int (gdbarch_sdb_reg_to_regnum_ftype) (int sdb_regnr);
+extern int gdbarch_sdb_reg_to_regnum (struct gdbarch *gdbarch, int sdb_regnr);
+extern void set_gdbarch_sdb_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_sdb_reg_to_regnum_ftype *sdb_reg_to_regnum);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SDB_REG_TO_REGNUM)
+#error "Non multi-arch definition of SDB_REG_TO_REGNUM"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SDB_REG_TO_REGNUM)
+#define SDB_REG_TO_REGNUM(sdb_regnr) (gdbarch_sdb_reg_to_regnum (current_gdbarch, sdb_regnr))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (DWARF2_REG_TO_REGNUM)
+#define DWARF2_REG_TO_REGNUM(dwarf2_regnr) (no_op_reg_to_regnum (dwarf2_regnr))
+#endif
+
+typedef int (gdbarch_dwarf2_reg_to_regnum_ftype) (int dwarf2_regnr);
+extern int gdbarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int dwarf2_regnr);
+extern void set_gdbarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_dwarf2_reg_to_regnum_ftype *dwarf2_reg_to_regnum);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DWARF2_REG_TO_REGNUM)
+#error "Non multi-arch definition of DWARF2_REG_TO_REGNUM"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DWARF2_REG_TO_REGNUM)
+#define DWARF2_REG_TO_REGNUM(dwarf2_regnr) (gdbarch_dwarf2_reg_to_regnum (current_gdbarch, dwarf2_regnr))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (REGISTER_NAME)
+#define REGISTER_NAME(regnr) (legacy_register_name (regnr))
+#endif
+
+typedef char * (gdbarch_register_name_ftype) (int regnr);
+extern char * gdbarch_register_name (struct gdbarch *gdbarch, int regnr);
+extern void set_gdbarch_register_name (struct gdbarch *gdbarch, gdbarch_register_name_ftype *register_name);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_NAME)
+#error "Non multi-arch definition of REGISTER_NAME"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_NAME)
+#define REGISTER_NAME(regnr) (gdbarch_register_name (current_gdbarch, regnr))
+#endif
+#endif
+
+extern int gdbarch_register_size (struct gdbarch *gdbarch);
+extern void set_gdbarch_register_size (struct gdbarch *gdbarch, int register_size);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_SIZE)
+#error "Non multi-arch definition of REGISTER_SIZE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_SIZE)
+#define REGISTER_SIZE (gdbarch_register_size (current_gdbarch))
+#endif
+#endif
+
+extern int gdbarch_register_bytes (struct gdbarch *gdbarch);
+extern void set_gdbarch_register_bytes (struct gdbarch *gdbarch, int register_bytes);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_BYTES)
+#error "Non multi-arch definition of REGISTER_BYTES"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_BYTES)
+#define REGISTER_BYTES (gdbarch_register_bytes (current_gdbarch))
+#endif
+#endif
+
+typedef int (gdbarch_register_byte_ftype) (int reg_nr);
+extern int gdbarch_register_byte (struct gdbarch *gdbarch, int reg_nr);
+extern void set_gdbarch_register_byte (struct gdbarch *gdbarch, gdbarch_register_byte_ftype *register_byte);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_BYTE)
+#error "Non multi-arch definition of REGISTER_BYTE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_BYTE)
+#define REGISTER_BYTE(reg_nr) (gdbarch_register_byte (current_gdbarch, reg_nr))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (REGISTER_RAW_SIZE)
+#define REGISTER_RAW_SIZE(reg_nr) (generic_register_size (reg_nr))
+#endif
+
+typedef int (gdbarch_register_raw_size_ftype) (int reg_nr);
+extern int gdbarch_register_raw_size (struct gdbarch *gdbarch, int reg_nr);
+extern void set_gdbarch_register_raw_size (struct gdbarch *gdbarch, gdbarch_register_raw_size_ftype *register_raw_size);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_RAW_SIZE)
+#error "Non multi-arch definition of REGISTER_RAW_SIZE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_RAW_SIZE)
+#define REGISTER_RAW_SIZE(reg_nr) (gdbarch_register_raw_size (current_gdbarch, reg_nr))
+#endif
+#endif
+
+extern int gdbarch_max_register_raw_size (struct gdbarch *gdbarch);
+extern void set_gdbarch_max_register_raw_size (struct gdbarch *gdbarch, int max_register_raw_size);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (MAX_REGISTER_RAW_SIZE)
+#error "Non multi-arch definition of MAX_REGISTER_RAW_SIZE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (MAX_REGISTER_RAW_SIZE)
+#define MAX_REGISTER_RAW_SIZE (gdbarch_max_register_raw_size (current_gdbarch))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (REGISTER_VIRTUAL_SIZE)
+#define REGISTER_VIRTUAL_SIZE(reg_nr) (generic_register_size (reg_nr))
+#endif
+
+typedef int (gdbarch_register_virtual_size_ftype) (int reg_nr);
+extern int gdbarch_register_virtual_size (struct gdbarch *gdbarch, int reg_nr);
+extern void set_gdbarch_register_virtual_size (struct gdbarch *gdbarch, gdbarch_register_virtual_size_ftype *register_virtual_size);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_VIRTUAL_SIZE)
+#error "Non multi-arch definition of REGISTER_VIRTUAL_SIZE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_VIRTUAL_SIZE)
+#define REGISTER_VIRTUAL_SIZE(reg_nr) (gdbarch_register_virtual_size (current_gdbarch, reg_nr))
+#endif
+#endif
+
+extern int gdbarch_max_register_virtual_size (struct gdbarch *gdbarch);
+extern void set_gdbarch_max_register_virtual_size (struct gdbarch *gdbarch, int max_register_virtual_size);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (MAX_REGISTER_VIRTUAL_SIZE)
+#error "Non multi-arch definition of MAX_REGISTER_VIRTUAL_SIZE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (MAX_REGISTER_VIRTUAL_SIZE)
+#define MAX_REGISTER_VIRTUAL_SIZE (gdbarch_max_register_virtual_size (current_gdbarch))
+#endif
+#endif
+
+typedef struct type * (gdbarch_register_virtual_type_ftype) (int reg_nr);
+extern struct type * gdbarch_register_virtual_type (struct gdbarch *gdbarch, int reg_nr);
+extern void set_gdbarch_register_virtual_type (struct gdbarch *gdbarch, gdbarch_register_virtual_type_ftype *register_virtual_type);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_VIRTUAL_TYPE)
+#error "Non multi-arch definition of REGISTER_VIRTUAL_TYPE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_VIRTUAL_TYPE)
+#define REGISTER_VIRTUAL_TYPE(reg_nr) (gdbarch_register_virtual_type (current_gdbarch, reg_nr))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (DO_REGISTERS_INFO)
+#define DO_REGISTERS_INFO(reg_nr, fpregs) (do_registers_info (reg_nr, fpregs))
+#endif
+
+typedef void (gdbarch_do_registers_info_ftype) (int reg_nr, int fpregs);
+extern void gdbarch_do_registers_info (struct gdbarch *gdbarch, int reg_nr, int fpregs);
+extern void set_gdbarch_do_registers_info (struct gdbarch *gdbarch, gdbarch_do_registers_info_ftype *do_registers_info);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DO_REGISTERS_INFO)
+#error "Non multi-arch definition of DO_REGISTERS_INFO"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DO_REGISTERS_INFO)
+#define DO_REGISTERS_INFO(reg_nr, fpregs) (gdbarch_do_registers_info (current_gdbarch, reg_nr, fpregs))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (PRINT_FLOAT_INFO)
+#define PRINT_FLOAT_INFO() (default_print_float_info ())
+#endif
+
+typedef void (gdbarch_print_float_info_ftype) (void);
+extern void gdbarch_print_float_info (struct gdbarch *gdbarch);
+extern void set_gdbarch_print_float_info (struct gdbarch *gdbarch, gdbarch_print_float_info_ftype *print_float_info);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PRINT_FLOAT_INFO)
+#error "Non multi-arch definition of PRINT_FLOAT_INFO"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PRINT_FLOAT_INFO)
+#define PRINT_FLOAT_INFO() (gdbarch_print_float_info (current_gdbarch))
+#endif
+#endif
+
+/* MAP a GDB RAW register number onto a simulator register number. See
+ also include/...-sim.h. */
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (REGISTER_SIM_REGNO)
+#define REGISTER_SIM_REGNO(reg_nr) (default_register_sim_regno (reg_nr))
+#endif
+
+typedef int (gdbarch_register_sim_regno_ftype) (int reg_nr);
+extern int gdbarch_register_sim_regno (struct gdbarch *gdbarch, int reg_nr);
+extern void set_gdbarch_register_sim_regno (struct gdbarch *gdbarch, gdbarch_register_sim_regno_ftype *register_sim_regno);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_SIM_REGNO)
+#error "Non multi-arch definition of REGISTER_SIM_REGNO"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_SIM_REGNO)
+#define REGISTER_SIM_REGNO(reg_nr) (gdbarch_register_sim_regno (current_gdbarch, reg_nr))
+#endif
+#endif
+
+#if defined (REGISTER_BYTES_OK)
+/* Legacy for systems yet to multi-arch REGISTER_BYTES_OK */
+#if !defined (REGISTER_BYTES_OK_P)
+#define REGISTER_BYTES_OK_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (REGISTER_BYTES_OK_P)
+#define REGISTER_BYTES_OK_P() (0)
+#endif
+
+extern int gdbarch_register_bytes_ok_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_BYTES_OK_P)
+#error "Non multi-arch definition of REGISTER_BYTES_OK"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_BYTES_OK_P)
+#define REGISTER_BYTES_OK_P() (gdbarch_register_bytes_ok_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (REGISTER_BYTES_OK)
+#define REGISTER_BYTES_OK(nr_bytes) (internal_error (__FILE__, __LINE__, "REGISTER_BYTES_OK"), 0)
+#endif
+
+typedef int (gdbarch_register_bytes_ok_ftype) (long nr_bytes);
+extern int gdbarch_register_bytes_ok (struct gdbarch *gdbarch, long nr_bytes);
+extern void set_gdbarch_register_bytes_ok (struct gdbarch *gdbarch, gdbarch_register_bytes_ok_ftype *register_bytes_ok);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_BYTES_OK)
+#error "Non multi-arch definition of REGISTER_BYTES_OK"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_BYTES_OK)
+#define REGISTER_BYTES_OK(nr_bytes) (gdbarch_register_bytes_ok (current_gdbarch, nr_bytes))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (CANNOT_FETCH_REGISTER)
+#define CANNOT_FETCH_REGISTER(regnum) (cannot_register_not (regnum))
+#endif
+
+typedef int (gdbarch_cannot_fetch_register_ftype) (int regnum);
+extern int gdbarch_cannot_fetch_register (struct gdbarch *gdbarch, int regnum);
+extern void set_gdbarch_cannot_fetch_register (struct gdbarch *gdbarch, gdbarch_cannot_fetch_register_ftype *cannot_fetch_register);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CANNOT_FETCH_REGISTER)
+#error "Non multi-arch definition of CANNOT_FETCH_REGISTER"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CANNOT_FETCH_REGISTER)
+#define CANNOT_FETCH_REGISTER(regnum) (gdbarch_cannot_fetch_register (current_gdbarch, regnum))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (CANNOT_STORE_REGISTER)
+#define CANNOT_STORE_REGISTER(regnum) (cannot_register_not (regnum))
+#endif
+
+typedef int (gdbarch_cannot_store_register_ftype) (int regnum);
+extern int gdbarch_cannot_store_register (struct gdbarch *gdbarch, int regnum);
+extern void set_gdbarch_cannot_store_register (struct gdbarch *gdbarch, gdbarch_cannot_store_register_ftype *cannot_store_register);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CANNOT_STORE_REGISTER)
+#error "Non multi-arch definition of CANNOT_STORE_REGISTER"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CANNOT_STORE_REGISTER)
+#define CANNOT_STORE_REGISTER(regnum) (gdbarch_cannot_store_register (current_gdbarch, regnum))
+#endif
+#endif
+
+/* setjmp/longjmp support. */
+
+#if defined (GET_LONGJMP_TARGET)
+/* Legacy for systems yet to multi-arch GET_LONGJMP_TARGET */
+#if !defined (GET_LONGJMP_TARGET_P)
+#define GET_LONGJMP_TARGET_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (GET_LONGJMP_TARGET_P)
+#define GET_LONGJMP_TARGET_P() (0)
+#endif
+
+extern int gdbarch_get_longjmp_target_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (GET_LONGJMP_TARGET_P)
+#error "Non multi-arch definition of GET_LONGJMP_TARGET"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (GET_LONGJMP_TARGET_P)
+#define GET_LONGJMP_TARGET_P() (gdbarch_get_longjmp_target_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (GET_LONGJMP_TARGET)
+#define GET_LONGJMP_TARGET(pc) (internal_error (__FILE__, __LINE__, "GET_LONGJMP_TARGET"), 0)
+#endif
+
+typedef int (gdbarch_get_longjmp_target_ftype) (CORE_ADDR *pc);
+extern int gdbarch_get_longjmp_target (struct gdbarch *gdbarch, CORE_ADDR *pc);
+extern void set_gdbarch_get_longjmp_target (struct gdbarch *gdbarch, gdbarch_get_longjmp_target_ftype *get_longjmp_target);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (GET_LONGJMP_TARGET)
+#error "Non multi-arch definition of GET_LONGJMP_TARGET"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (GET_LONGJMP_TARGET)
+#define GET_LONGJMP_TARGET(pc) (gdbarch_get_longjmp_target (current_gdbarch, pc))
+#endif
+#endif
+
+/* Non multi-arch DUMMY_FRAMES are a mess (multi-arch ones are not that
+ much better but at least they are vaguely consistent). The headers
+ and body contain convoluted #if/#else sequences for determine how
+ things should be compiled. Instead of trying to mimic that
+ behaviour here (and hence entrench it further) gdbarch simply
+ reqires that these methods be set up from the word go. This also
+ avoids any potential problems with moving beyond multi-arch partial. */
+
+extern int gdbarch_use_generic_dummy_frames (struct gdbarch *gdbarch);
+extern void set_gdbarch_use_generic_dummy_frames (struct gdbarch *gdbarch, int use_generic_dummy_frames);
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (USE_GENERIC_DUMMY_FRAMES)
+#error "Non multi-arch definition of USE_GENERIC_DUMMY_FRAMES"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (USE_GENERIC_DUMMY_FRAMES)
+#define USE_GENERIC_DUMMY_FRAMES (gdbarch_use_generic_dummy_frames (current_gdbarch))
+#endif
+#endif
+
+extern int gdbarch_call_dummy_location (struct gdbarch *gdbarch);
+extern void set_gdbarch_call_dummy_location (struct gdbarch *gdbarch, int call_dummy_location);
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_LOCATION)
+#error "Non multi-arch definition of CALL_DUMMY_LOCATION"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_LOCATION)
+#define CALL_DUMMY_LOCATION (gdbarch_call_dummy_location (current_gdbarch))
+#endif
+#endif
+
+typedef CORE_ADDR (gdbarch_call_dummy_address_ftype) (void);
+extern CORE_ADDR gdbarch_call_dummy_address (struct gdbarch *gdbarch);
+extern void set_gdbarch_call_dummy_address (struct gdbarch *gdbarch, gdbarch_call_dummy_address_ftype *call_dummy_address);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_ADDRESS)
+#error "Non multi-arch definition of CALL_DUMMY_ADDRESS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_ADDRESS)
+#define CALL_DUMMY_ADDRESS() (gdbarch_call_dummy_address (current_gdbarch))
+#endif
+#endif
+
+extern CORE_ADDR gdbarch_call_dummy_start_offset (struct gdbarch *gdbarch);
+extern void set_gdbarch_call_dummy_start_offset (struct gdbarch *gdbarch, CORE_ADDR call_dummy_start_offset);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_START_OFFSET)
+#error "Non multi-arch definition of CALL_DUMMY_START_OFFSET"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_START_OFFSET)
+#define CALL_DUMMY_START_OFFSET (gdbarch_call_dummy_start_offset (current_gdbarch))
+#endif
+#endif
+
+extern CORE_ADDR gdbarch_call_dummy_breakpoint_offset (struct gdbarch *gdbarch);
+extern void set_gdbarch_call_dummy_breakpoint_offset (struct gdbarch *gdbarch, CORE_ADDR call_dummy_breakpoint_offset);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_BREAKPOINT_OFFSET)
+#error "Non multi-arch definition of CALL_DUMMY_BREAKPOINT_OFFSET"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_BREAKPOINT_OFFSET)
+#define CALL_DUMMY_BREAKPOINT_OFFSET (gdbarch_call_dummy_breakpoint_offset (current_gdbarch))
+#endif
+#endif
+
+extern int gdbarch_call_dummy_breakpoint_offset_p (struct gdbarch *gdbarch);
+extern void set_gdbarch_call_dummy_breakpoint_offset_p (struct gdbarch *gdbarch, int call_dummy_breakpoint_offset_p);
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_BREAKPOINT_OFFSET_P)
+#error "Non multi-arch definition of CALL_DUMMY_BREAKPOINT_OFFSET_P"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_BREAKPOINT_OFFSET_P)
+#define CALL_DUMMY_BREAKPOINT_OFFSET_P (gdbarch_call_dummy_breakpoint_offset_p (current_gdbarch))
+#endif
+#endif
+
+extern int gdbarch_call_dummy_length (struct gdbarch *gdbarch);
+extern void set_gdbarch_call_dummy_length (struct gdbarch *gdbarch, int call_dummy_length);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_LENGTH)
+#error "Non multi-arch definition of CALL_DUMMY_LENGTH"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_LENGTH)
+#define CALL_DUMMY_LENGTH (gdbarch_call_dummy_length (current_gdbarch))
+#endif
+#endif
+
+typedef int (gdbarch_pc_in_call_dummy_ftype) (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address);
+extern int gdbarch_pc_in_call_dummy (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address);
+extern void set_gdbarch_pc_in_call_dummy (struct gdbarch *gdbarch, gdbarch_pc_in_call_dummy_ftype *pc_in_call_dummy);
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (PC_IN_CALL_DUMMY)
+#error "Non multi-arch definition of PC_IN_CALL_DUMMY"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (PC_IN_CALL_DUMMY)
+#define PC_IN_CALL_DUMMY(pc, sp, frame_address) (gdbarch_pc_in_call_dummy (current_gdbarch, pc, sp, frame_address))
+#endif
+#endif
+
+extern int gdbarch_call_dummy_p (struct gdbarch *gdbarch);
+extern void set_gdbarch_call_dummy_p (struct gdbarch *gdbarch, int call_dummy_p);
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_P)
+#error "Non multi-arch definition of CALL_DUMMY_P"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_P)
+#define CALL_DUMMY_P (gdbarch_call_dummy_p (current_gdbarch))
+#endif
+#endif
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (CALL_DUMMY_WORDS)
+#define CALL_DUMMY_WORDS (legacy_call_dummy_words)
+#endif
+
+extern LONGEST * gdbarch_call_dummy_words (struct gdbarch *gdbarch);
+extern void set_gdbarch_call_dummy_words (struct gdbarch *gdbarch, LONGEST * call_dummy_words);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_WORDS)
+#error "Non multi-arch definition of CALL_DUMMY_WORDS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_WORDS)
+#define CALL_DUMMY_WORDS (gdbarch_call_dummy_words (current_gdbarch))
+#endif
+#endif
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (SIZEOF_CALL_DUMMY_WORDS)
+#define SIZEOF_CALL_DUMMY_WORDS (legacy_sizeof_call_dummy_words)
+#endif
+
+extern int gdbarch_sizeof_call_dummy_words (struct gdbarch *gdbarch);
+extern void set_gdbarch_sizeof_call_dummy_words (struct gdbarch *gdbarch, int sizeof_call_dummy_words);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SIZEOF_CALL_DUMMY_WORDS)
+#error "Non multi-arch definition of SIZEOF_CALL_DUMMY_WORDS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SIZEOF_CALL_DUMMY_WORDS)
+#define SIZEOF_CALL_DUMMY_WORDS (gdbarch_sizeof_call_dummy_words (current_gdbarch))
+#endif
+#endif
+
+extern int gdbarch_call_dummy_stack_adjust_p (struct gdbarch *gdbarch);
+extern void set_gdbarch_call_dummy_stack_adjust_p (struct gdbarch *gdbarch, int call_dummy_stack_adjust_p);
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_STACK_ADJUST_P)
+#error "Non multi-arch definition of CALL_DUMMY_STACK_ADJUST_P"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_STACK_ADJUST_P)
+#define CALL_DUMMY_STACK_ADJUST_P (gdbarch_call_dummy_stack_adjust_p (current_gdbarch))
+#endif
+#endif
+
+extern int gdbarch_call_dummy_stack_adjust (struct gdbarch *gdbarch);
+extern void set_gdbarch_call_dummy_stack_adjust (struct gdbarch *gdbarch, int call_dummy_stack_adjust);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CALL_DUMMY_STACK_ADJUST)
+#error "Non multi-arch definition of CALL_DUMMY_STACK_ADJUST"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CALL_DUMMY_STACK_ADJUST)
+#define CALL_DUMMY_STACK_ADJUST (gdbarch_call_dummy_stack_adjust (current_gdbarch))
+#endif
+#endif
+
+typedef void (gdbarch_fix_call_dummy_ftype) (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, struct value **args, struct type *type, int gcc_p);
+extern void gdbarch_fix_call_dummy (struct gdbarch *gdbarch, char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, struct value **args, struct type *type, int gcc_p);
+extern void set_gdbarch_fix_call_dummy (struct gdbarch *gdbarch, gdbarch_fix_call_dummy_ftype *fix_call_dummy);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FIX_CALL_DUMMY)
+#error "Non multi-arch definition of FIX_CALL_DUMMY"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FIX_CALL_DUMMY)
+#define FIX_CALL_DUMMY(dummy, pc, fun, nargs, args, type, gcc_p) (gdbarch_fix_call_dummy (current_gdbarch, dummy, pc, fun, nargs, args, type, gcc_p))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (INIT_FRAME_PC_FIRST)
+#define INIT_FRAME_PC_FIRST(fromleaf, prev) (init_frame_pc_noop (fromleaf, prev))
+#endif
+
+typedef void (gdbarch_init_frame_pc_first_ftype) (int fromleaf, struct frame_info *prev);
+extern void gdbarch_init_frame_pc_first (struct gdbarch *gdbarch, int fromleaf, struct frame_info *prev);
+extern void set_gdbarch_init_frame_pc_first (struct gdbarch *gdbarch, gdbarch_init_frame_pc_first_ftype *init_frame_pc_first);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (INIT_FRAME_PC_FIRST)
+#error "Non multi-arch definition of INIT_FRAME_PC_FIRST"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (INIT_FRAME_PC_FIRST)
+#define INIT_FRAME_PC_FIRST(fromleaf, prev) (gdbarch_init_frame_pc_first (current_gdbarch, fromleaf, prev))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (INIT_FRAME_PC)
+#define INIT_FRAME_PC(fromleaf, prev) (init_frame_pc_default (fromleaf, prev))
+#endif
+
+typedef void (gdbarch_init_frame_pc_ftype) (int fromleaf, struct frame_info *prev);
+extern void gdbarch_init_frame_pc (struct gdbarch *gdbarch, int fromleaf, struct frame_info *prev);
+extern void set_gdbarch_init_frame_pc (struct gdbarch *gdbarch, gdbarch_init_frame_pc_ftype *init_frame_pc);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (INIT_FRAME_PC)
+#error "Non multi-arch definition of INIT_FRAME_PC"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (INIT_FRAME_PC)
+#define INIT_FRAME_PC(fromleaf, prev) (gdbarch_init_frame_pc (current_gdbarch, fromleaf, prev))
+#endif
+#endif
+
+extern int gdbarch_believe_pcc_promotion (struct gdbarch *gdbarch);
+extern void set_gdbarch_believe_pcc_promotion (struct gdbarch *gdbarch, int believe_pcc_promotion);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (BELIEVE_PCC_PROMOTION)
+#error "Non multi-arch definition of BELIEVE_PCC_PROMOTION"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (BELIEVE_PCC_PROMOTION)
+#define BELIEVE_PCC_PROMOTION (gdbarch_believe_pcc_promotion (current_gdbarch))
+#endif
+#endif
+
+extern int gdbarch_believe_pcc_promotion_type (struct gdbarch *gdbarch);
+extern void set_gdbarch_believe_pcc_promotion_type (struct gdbarch *gdbarch, int believe_pcc_promotion_type);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (BELIEVE_PCC_PROMOTION_TYPE)
+#error "Non multi-arch definition of BELIEVE_PCC_PROMOTION_TYPE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (BELIEVE_PCC_PROMOTION_TYPE)
+#define BELIEVE_PCC_PROMOTION_TYPE (gdbarch_believe_pcc_promotion_type (current_gdbarch))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (COERCE_FLOAT_TO_DOUBLE)
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (default_coerce_float_to_double (formal, actual))
+#endif
+
+typedef int (gdbarch_coerce_float_to_double_ftype) (struct type *formal, struct type *actual);
+extern int gdbarch_coerce_float_to_double (struct gdbarch *gdbarch, struct type *formal, struct type *actual);
+extern void set_gdbarch_coerce_float_to_double (struct gdbarch *gdbarch, gdbarch_coerce_float_to_double_ftype *coerce_float_to_double);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (COERCE_FLOAT_TO_DOUBLE)
+#error "Non multi-arch definition of COERCE_FLOAT_TO_DOUBLE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (COERCE_FLOAT_TO_DOUBLE)
+#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (gdbarch_coerce_float_to_double (current_gdbarch, formal, actual))
+#endif
+#endif
+
+/* GET_SAVED_REGISTER is like DUMMY_FRAMES. It is at level one as the
+ old code has strange #ifdef interaction. So far no one has found
+ that default_get_saved_register() is the default they are after. */
+
+typedef void (gdbarch_get_saved_register_ftype) (char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval);
+extern void gdbarch_get_saved_register (struct gdbarch *gdbarch, char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval);
+extern void set_gdbarch_get_saved_register (struct gdbarch *gdbarch, gdbarch_get_saved_register_ftype *get_saved_register);
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (GET_SAVED_REGISTER)
+#error "Non multi-arch definition of GET_SAVED_REGISTER"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (GET_SAVED_REGISTER)
+#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) (gdbarch_get_saved_register (current_gdbarch, raw_buffer, optimized, addrp, frame, regnum, lval))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (REGISTER_CONVERTIBLE)
+#define REGISTER_CONVERTIBLE(nr) (generic_register_convertible_not (nr))
+#endif
+
+typedef int (gdbarch_register_convertible_ftype) (int nr);
+extern int gdbarch_register_convertible (struct gdbarch *gdbarch, int nr);
+extern void set_gdbarch_register_convertible (struct gdbarch *gdbarch, gdbarch_register_convertible_ftype *register_convertible);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_CONVERTIBLE)
+#error "Non multi-arch definition of REGISTER_CONVERTIBLE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_CONVERTIBLE)
+#define REGISTER_CONVERTIBLE(nr) (gdbarch_register_convertible (current_gdbarch, nr))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (REGISTER_CONVERT_TO_VIRTUAL)
+#define REGISTER_CONVERT_TO_VIRTUAL(regnum, type, from, to) (internal_error (__FILE__, __LINE__, "REGISTER_CONVERT_TO_VIRTUAL"), 0)
+#endif
+
+typedef void (gdbarch_register_convert_to_virtual_ftype) (int regnum, struct type *type, char *from, char *to);
+extern void gdbarch_register_convert_to_virtual (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to);
+extern void set_gdbarch_register_convert_to_virtual (struct gdbarch *gdbarch, gdbarch_register_convert_to_virtual_ftype *register_convert_to_virtual);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_CONVERT_TO_VIRTUAL)
+#error "Non multi-arch definition of REGISTER_CONVERT_TO_VIRTUAL"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_CONVERT_TO_VIRTUAL)
+#define REGISTER_CONVERT_TO_VIRTUAL(regnum, type, from, to) (gdbarch_register_convert_to_virtual (current_gdbarch, regnum, type, from, to))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (REGISTER_CONVERT_TO_RAW)
+#define REGISTER_CONVERT_TO_RAW(type, regnum, from, to) (internal_error (__FILE__, __LINE__, "REGISTER_CONVERT_TO_RAW"), 0)
+#endif
+
+typedef void (gdbarch_register_convert_to_raw_ftype) (struct type *type, int regnum, char *from, char *to);
+extern void gdbarch_register_convert_to_raw (struct gdbarch *gdbarch, struct type *type, int regnum, char *from, char *to);
+extern void set_gdbarch_register_convert_to_raw (struct gdbarch *gdbarch, gdbarch_register_convert_to_raw_ftype *register_convert_to_raw);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_CONVERT_TO_RAW)
+#error "Non multi-arch definition of REGISTER_CONVERT_TO_RAW"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_CONVERT_TO_RAW)
+#define REGISTER_CONVERT_TO_RAW(type, regnum, from, to) (gdbarch_register_convert_to_raw (current_gdbarch, type, regnum, from, to))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (CONVERT_REGISTER_P)
+#define CONVERT_REGISTER_P(regnum) (legacy_convert_register_p (regnum))
+#endif
+
+typedef int (gdbarch_convert_register_p_ftype) (int regnum);
+extern int gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum);
+extern void set_gdbarch_convert_register_p (struct gdbarch *gdbarch, gdbarch_convert_register_p_ftype *convert_register_p);
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (CONVERT_REGISTER_P)
+#error "Non multi-arch definition of CONVERT_REGISTER_P"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (CONVERT_REGISTER_P)
+#define CONVERT_REGISTER_P(regnum) (gdbarch_convert_register_p (current_gdbarch, regnum))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (REGISTER_TO_VALUE)
+#define REGISTER_TO_VALUE(regnum, type, from, to) (legacy_register_to_value (regnum, type, from, to))
+#endif
+
+typedef void (gdbarch_register_to_value_ftype) (int regnum, struct type *type, char *from, char *to);
+extern void gdbarch_register_to_value (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to);
+extern void set_gdbarch_register_to_value (struct gdbarch *gdbarch, gdbarch_register_to_value_ftype *register_to_value);
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_TO_VALUE)
+#error "Non multi-arch definition of REGISTER_TO_VALUE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_TO_VALUE)
+#define REGISTER_TO_VALUE(regnum, type, from, to) (gdbarch_register_to_value (current_gdbarch, regnum, type, from, to))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (VALUE_TO_REGISTER)
+#define VALUE_TO_REGISTER(type, regnum, from, to) (legacy_value_to_register (type, regnum, from, to))
+#endif
+
+typedef void (gdbarch_value_to_register_ftype) (struct type *type, int regnum, char *from, char *to);
+extern void gdbarch_value_to_register (struct gdbarch *gdbarch, struct type *type, int regnum, char *from, char *to);
+extern void set_gdbarch_value_to_register (struct gdbarch *gdbarch, gdbarch_value_to_register_ftype *value_to_register);
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (VALUE_TO_REGISTER)
+#error "Non multi-arch definition of VALUE_TO_REGISTER"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (VALUE_TO_REGISTER)
+#define VALUE_TO_REGISTER(type, regnum, from, to) (gdbarch_value_to_register (current_gdbarch, type, regnum, from, to))
+#endif
+#endif
+
+/* This function is called when the value of a pseudo-register needs to
+ be updated. Typically it will be defined on a per-architecture
+ basis. */
+
+#if defined (FETCH_PSEUDO_REGISTER)
+/* Legacy for systems yet to multi-arch FETCH_PSEUDO_REGISTER */
+#if !defined (FETCH_PSEUDO_REGISTER_P)
+#define FETCH_PSEUDO_REGISTER_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (FETCH_PSEUDO_REGISTER_P)
+#define FETCH_PSEUDO_REGISTER_P() (0)
+#endif
+
+extern int gdbarch_fetch_pseudo_register_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FETCH_PSEUDO_REGISTER_P)
+#error "Non multi-arch definition of FETCH_PSEUDO_REGISTER"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FETCH_PSEUDO_REGISTER_P)
+#define FETCH_PSEUDO_REGISTER_P() (gdbarch_fetch_pseudo_register_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (FETCH_PSEUDO_REGISTER)
+#define FETCH_PSEUDO_REGISTER(regnum) (internal_error (__FILE__, __LINE__, "FETCH_PSEUDO_REGISTER"), 0)
+#endif
+
+typedef void (gdbarch_fetch_pseudo_register_ftype) (int regnum);
+extern void gdbarch_fetch_pseudo_register (struct gdbarch *gdbarch, int regnum);
+extern void set_gdbarch_fetch_pseudo_register (struct gdbarch *gdbarch, gdbarch_fetch_pseudo_register_ftype *fetch_pseudo_register);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FETCH_PSEUDO_REGISTER)
+#error "Non multi-arch definition of FETCH_PSEUDO_REGISTER"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FETCH_PSEUDO_REGISTER)
+#define FETCH_PSEUDO_REGISTER(regnum) (gdbarch_fetch_pseudo_register (current_gdbarch, regnum))
+#endif
+#endif
+
+/* This function is called when the value of a pseudo-register needs to
+ be set or stored. Typically it will be defined on a
+ per-architecture basis. */
+
+#if defined (STORE_PSEUDO_REGISTER)
+/* Legacy for systems yet to multi-arch STORE_PSEUDO_REGISTER */
+#if !defined (STORE_PSEUDO_REGISTER_P)
+#define STORE_PSEUDO_REGISTER_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (STORE_PSEUDO_REGISTER_P)
+#define STORE_PSEUDO_REGISTER_P() (0)
+#endif
+
+extern int gdbarch_store_pseudo_register_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (STORE_PSEUDO_REGISTER_P)
+#error "Non multi-arch definition of STORE_PSEUDO_REGISTER"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (STORE_PSEUDO_REGISTER_P)
+#define STORE_PSEUDO_REGISTER_P() (gdbarch_store_pseudo_register_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (STORE_PSEUDO_REGISTER)
+#define STORE_PSEUDO_REGISTER(regnum) (internal_error (__FILE__, __LINE__, "STORE_PSEUDO_REGISTER"), 0)
+#endif
+
+typedef void (gdbarch_store_pseudo_register_ftype) (int regnum);
+extern void gdbarch_store_pseudo_register (struct gdbarch *gdbarch, int regnum);
+extern void set_gdbarch_store_pseudo_register (struct gdbarch *gdbarch, gdbarch_store_pseudo_register_ftype *store_pseudo_register);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (STORE_PSEUDO_REGISTER)
+#error "Non multi-arch definition of STORE_PSEUDO_REGISTER"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (STORE_PSEUDO_REGISTER)
+#define STORE_PSEUDO_REGISTER(regnum) (gdbarch_store_pseudo_register (current_gdbarch, regnum))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (POINTER_TO_ADDRESS)
+#define POINTER_TO_ADDRESS(type, buf) (unsigned_pointer_to_address (type, buf))
+#endif
+
+typedef CORE_ADDR (gdbarch_pointer_to_address_ftype) (struct type *type, void *buf);
+extern CORE_ADDR gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, void *buf);
+extern void set_gdbarch_pointer_to_address (struct gdbarch *gdbarch, gdbarch_pointer_to_address_ftype *pointer_to_address);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (POINTER_TO_ADDRESS)
+#error "Non multi-arch definition of POINTER_TO_ADDRESS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (POINTER_TO_ADDRESS)
+#define POINTER_TO_ADDRESS(type, buf) (gdbarch_pointer_to_address (current_gdbarch, type, buf))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (ADDRESS_TO_POINTER)
+#define ADDRESS_TO_POINTER(type, buf, addr) (unsigned_address_to_pointer (type, buf, addr))
+#endif
+
+typedef void (gdbarch_address_to_pointer_ftype) (struct type *type, void *buf, CORE_ADDR addr);
+extern void gdbarch_address_to_pointer (struct gdbarch *gdbarch, struct type *type, void *buf, CORE_ADDR addr);
+extern void set_gdbarch_address_to_pointer (struct gdbarch *gdbarch, gdbarch_address_to_pointer_ftype *address_to_pointer);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ADDRESS_TO_POINTER)
+#error "Non multi-arch definition of ADDRESS_TO_POINTER"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ADDRESS_TO_POINTER)
+#define ADDRESS_TO_POINTER(type, buf, addr) (gdbarch_address_to_pointer (current_gdbarch, type, buf, addr))
+#endif
+#endif
+
+#if defined (INTEGER_TO_ADDRESS)
+/* Legacy for systems yet to multi-arch INTEGER_TO_ADDRESS */
+#if !defined (INTEGER_TO_ADDRESS_P)
+#define INTEGER_TO_ADDRESS_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (INTEGER_TO_ADDRESS_P)
+#define INTEGER_TO_ADDRESS_P() (0)
+#endif
+
+extern int gdbarch_integer_to_address_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (INTEGER_TO_ADDRESS_P)
+#error "Non multi-arch definition of INTEGER_TO_ADDRESS"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (INTEGER_TO_ADDRESS_P)
+#define INTEGER_TO_ADDRESS_P() (gdbarch_integer_to_address_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (INTEGER_TO_ADDRESS)
+#define INTEGER_TO_ADDRESS(type, buf) (internal_error (__FILE__, __LINE__, "INTEGER_TO_ADDRESS"), 0)
+#endif
+
+typedef CORE_ADDR (gdbarch_integer_to_address_ftype) (struct type *type, void *buf);
+extern CORE_ADDR gdbarch_integer_to_address (struct gdbarch *gdbarch, struct type *type, void *buf);
+extern void set_gdbarch_integer_to_address (struct gdbarch *gdbarch, gdbarch_integer_to_address_ftype *integer_to_address);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (INTEGER_TO_ADDRESS)
+#error "Non multi-arch definition of INTEGER_TO_ADDRESS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (INTEGER_TO_ADDRESS)
+#define INTEGER_TO_ADDRESS(type, buf) (gdbarch_integer_to_address (current_gdbarch, type, buf))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (RETURN_VALUE_ON_STACK)
+#define RETURN_VALUE_ON_STACK(type) (generic_return_value_on_stack_not (type))
+#endif
+
+typedef int (gdbarch_return_value_on_stack_ftype) (struct type *type);
+extern int gdbarch_return_value_on_stack (struct gdbarch *gdbarch, struct type *type);
+extern void set_gdbarch_return_value_on_stack (struct gdbarch *gdbarch, gdbarch_return_value_on_stack_ftype *return_value_on_stack);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (RETURN_VALUE_ON_STACK)
+#error "Non multi-arch definition of RETURN_VALUE_ON_STACK"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (RETURN_VALUE_ON_STACK)
+#define RETURN_VALUE_ON_STACK(type) (gdbarch_return_value_on_stack (current_gdbarch, type))
+#endif
+#endif
+
+typedef void (gdbarch_extract_return_value_ftype) (struct type *type, char *regbuf, char *valbuf);
+extern void gdbarch_extract_return_value (struct gdbarch *gdbarch, struct type *type, char *regbuf, char *valbuf);
+extern void set_gdbarch_extract_return_value (struct gdbarch *gdbarch, gdbarch_extract_return_value_ftype *extract_return_value);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (EXTRACT_RETURN_VALUE)
+#error "Non multi-arch definition of EXTRACT_RETURN_VALUE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (EXTRACT_RETURN_VALUE)
+#define EXTRACT_RETURN_VALUE(type, regbuf, valbuf) (gdbarch_extract_return_value (current_gdbarch, type, regbuf, valbuf))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (PUSH_ARGUMENTS)
+#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) (default_push_arguments (nargs, args, sp, struct_return, struct_addr))
+#endif
+
+typedef CORE_ADDR (gdbarch_push_arguments_ftype) (int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr);
+extern CORE_ADDR gdbarch_push_arguments (struct gdbarch *gdbarch, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr);
+extern void set_gdbarch_push_arguments (struct gdbarch *gdbarch, gdbarch_push_arguments_ftype *push_arguments);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PUSH_ARGUMENTS)
+#error "Non multi-arch definition of PUSH_ARGUMENTS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PUSH_ARGUMENTS)
+#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) (gdbarch_push_arguments (current_gdbarch, nargs, args, sp, struct_return, struct_addr))
+#endif
+#endif
+
+typedef void (gdbarch_push_dummy_frame_ftype) (void);
+extern void gdbarch_push_dummy_frame (struct gdbarch *gdbarch);
+extern void set_gdbarch_push_dummy_frame (struct gdbarch *gdbarch, gdbarch_push_dummy_frame_ftype *push_dummy_frame);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PUSH_DUMMY_FRAME)
+#error "Non multi-arch definition of PUSH_DUMMY_FRAME"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PUSH_DUMMY_FRAME)
+#define PUSH_DUMMY_FRAME (gdbarch_push_dummy_frame (current_gdbarch))
+#endif
+#endif
+
+#if defined (PUSH_RETURN_ADDRESS)
+/* Legacy for systems yet to multi-arch PUSH_RETURN_ADDRESS */
+#if !defined (PUSH_RETURN_ADDRESS_P)
+#define PUSH_RETURN_ADDRESS_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (PUSH_RETURN_ADDRESS_P)
+#define PUSH_RETURN_ADDRESS_P() (0)
+#endif
+
+extern int gdbarch_push_return_address_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PUSH_RETURN_ADDRESS_P)
+#error "Non multi-arch definition of PUSH_RETURN_ADDRESS"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PUSH_RETURN_ADDRESS_P)
+#define PUSH_RETURN_ADDRESS_P() (gdbarch_push_return_address_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (PUSH_RETURN_ADDRESS)
+#define PUSH_RETURN_ADDRESS(pc, sp) (internal_error (__FILE__, __LINE__, "PUSH_RETURN_ADDRESS"), 0)
+#endif
+
+typedef CORE_ADDR (gdbarch_push_return_address_ftype) (CORE_ADDR pc, CORE_ADDR sp);
+extern CORE_ADDR gdbarch_push_return_address (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR sp);
+extern void set_gdbarch_push_return_address (struct gdbarch *gdbarch, gdbarch_push_return_address_ftype *push_return_address);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PUSH_RETURN_ADDRESS)
+#error "Non multi-arch definition of PUSH_RETURN_ADDRESS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PUSH_RETURN_ADDRESS)
+#define PUSH_RETURN_ADDRESS(pc, sp) (gdbarch_push_return_address (current_gdbarch, pc, sp))
+#endif
+#endif
+
+typedef void (gdbarch_pop_frame_ftype) (void);
+extern void gdbarch_pop_frame (struct gdbarch *gdbarch);
+extern void set_gdbarch_pop_frame (struct gdbarch *gdbarch, gdbarch_pop_frame_ftype *pop_frame);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (POP_FRAME)
+#error "Non multi-arch definition of POP_FRAME"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (POP_FRAME)
+#define POP_FRAME (gdbarch_pop_frame (current_gdbarch))
+#endif
+#endif
+
+typedef void (gdbarch_store_struct_return_ftype) (CORE_ADDR addr, CORE_ADDR sp);
+extern void gdbarch_store_struct_return (struct gdbarch *gdbarch, CORE_ADDR addr, CORE_ADDR sp);
+extern void set_gdbarch_store_struct_return (struct gdbarch *gdbarch, gdbarch_store_struct_return_ftype *store_struct_return);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (STORE_STRUCT_RETURN)
+#error "Non multi-arch definition of STORE_STRUCT_RETURN"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (STORE_STRUCT_RETURN)
+#define STORE_STRUCT_RETURN(addr, sp) (gdbarch_store_struct_return (current_gdbarch, addr, sp))
+#endif
+#endif
+
+typedef void (gdbarch_store_return_value_ftype) (struct type *type, char *valbuf);
+extern void gdbarch_store_return_value (struct gdbarch *gdbarch, struct type *type, char *valbuf);
+extern void set_gdbarch_store_return_value (struct gdbarch *gdbarch, gdbarch_store_return_value_ftype *store_return_value);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (STORE_RETURN_VALUE)
+#error "Non multi-arch definition of STORE_RETURN_VALUE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (STORE_RETURN_VALUE)
+#define STORE_RETURN_VALUE(type, valbuf) (gdbarch_store_return_value (current_gdbarch, type, valbuf))
+#endif
+#endif
+
+#if defined (EXTRACT_STRUCT_VALUE_ADDRESS)
+/* Legacy for systems yet to multi-arch EXTRACT_STRUCT_VALUE_ADDRESS */
+#if !defined (EXTRACT_STRUCT_VALUE_ADDRESS_P)
+#define EXTRACT_STRUCT_VALUE_ADDRESS_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (EXTRACT_STRUCT_VALUE_ADDRESS_P)
+#define EXTRACT_STRUCT_VALUE_ADDRESS_P() (0)
+#endif
+
+extern int gdbarch_extract_struct_value_address_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (EXTRACT_STRUCT_VALUE_ADDRESS_P)
+#error "Non multi-arch definition of EXTRACT_STRUCT_VALUE_ADDRESS"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (EXTRACT_STRUCT_VALUE_ADDRESS_P)
+#define EXTRACT_STRUCT_VALUE_ADDRESS_P() (gdbarch_extract_struct_value_address_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (EXTRACT_STRUCT_VALUE_ADDRESS)
+#define EXTRACT_STRUCT_VALUE_ADDRESS(regbuf) (internal_error (__FILE__, __LINE__, "EXTRACT_STRUCT_VALUE_ADDRESS"), 0)
+#endif
+
+typedef CORE_ADDR (gdbarch_extract_struct_value_address_ftype) (char *regbuf);
+extern CORE_ADDR gdbarch_extract_struct_value_address (struct gdbarch *gdbarch, char *regbuf);
+extern void set_gdbarch_extract_struct_value_address (struct gdbarch *gdbarch, gdbarch_extract_struct_value_address_ftype *extract_struct_value_address);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (EXTRACT_STRUCT_VALUE_ADDRESS)
+#error "Non multi-arch definition of EXTRACT_STRUCT_VALUE_ADDRESS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (EXTRACT_STRUCT_VALUE_ADDRESS)
+#define EXTRACT_STRUCT_VALUE_ADDRESS(regbuf) (gdbarch_extract_struct_value_address (current_gdbarch, regbuf))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (USE_STRUCT_CONVENTION)
+#define USE_STRUCT_CONVENTION(gcc_p, value_type) (generic_use_struct_convention (gcc_p, value_type))
+#endif
+
+typedef int (gdbarch_use_struct_convention_ftype) (int gcc_p, struct type *value_type);
+extern int gdbarch_use_struct_convention (struct gdbarch *gdbarch, int gcc_p, struct type *value_type);
+extern void set_gdbarch_use_struct_convention (struct gdbarch *gdbarch, gdbarch_use_struct_convention_ftype *use_struct_convention);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (USE_STRUCT_CONVENTION)
+#error "Non multi-arch definition of USE_STRUCT_CONVENTION"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (USE_STRUCT_CONVENTION)
+#define USE_STRUCT_CONVENTION(gcc_p, value_type) (gdbarch_use_struct_convention (current_gdbarch, gcc_p, value_type))
+#endif
+#endif
+
+typedef void (gdbarch_frame_init_saved_regs_ftype) (struct frame_info *frame);
+extern void gdbarch_frame_init_saved_regs (struct gdbarch *gdbarch, struct frame_info *frame);
+extern void set_gdbarch_frame_init_saved_regs (struct gdbarch *gdbarch, gdbarch_frame_init_saved_regs_ftype *frame_init_saved_regs);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_INIT_SAVED_REGS)
+#error "Non multi-arch definition of FRAME_INIT_SAVED_REGS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_INIT_SAVED_REGS)
+#define FRAME_INIT_SAVED_REGS(frame) (gdbarch_frame_init_saved_regs (current_gdbarch, frame))
+#endif
+#endif
+
+#if defined (INIT_EXTRA_FRAME_INFO)
+/* Legacy for systems yet to multi-arch INIT_EXTRA_FRAME_INFO */
+#if !defined (INIT_EXTRA_FRAME_INFO_P)
+#define INIT_EXTRA_FRAME_INFO_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (INIT_EXTRA_FRAME_INFO_P)
+#define INIT_EXTRA_FRAME_INFO_P() (0)
+#endif
+
+extern int gdbarch_init_extra_frame_info_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (INIT_EXTRA_FRAME_INFO_P)
+#error "Non multi-arch definition of INIT_EXTRA_FRAME_INFO"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (INIT_EXTRA_FRAME_INFO_P)
+#define INIT_EXTRA_FRAME_INFO_P() (gdbarch_init_extra_frame_info_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (INIT_EXTRA_FRAME_INFO)
+#define INIT_EXTRA_FRAME_INFO(fromleaf, frame) (internal_error (__FILE__, __LINE__, "INIT_EXTRA_FRAME_INFO"), 0)
+#endif
+
+typedef void (gdbarch_init_extra_frame_info_ftype) (int fromleaf, struct frame_info *frame);
+extern void gdbarch_init_extra_frame_info (struct gdbarch *gdbarch, int fromleaf, struct frame_info *frame);
+extern void set_gdbarch_init_extra_frame_info (struct gdbarch *gdbarch, gdbarch_init_extra_frame_info_ftype *init_extra_frame_info);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (INIT_EXTRA_FRAME_INFO)
+#error "Non multi-arch definition of INIT_EXTRA_FRAME_INFO"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (INIT_EXTRA_FRAME_INFO)
+#define INIT_EXTRA_FRAME_INFO(fromleaf, frame) (gdbarch_init_extra_frame_info (current_gdbarch, fromleaf, frame))
+#endif
+#endif
+
+typedef CORE_ADDR (gdbarch_skip_prologue_ftype) (CORE_ADDR ip);
+extern CORE_ADDR gdbarch_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR ip);
+extern void set_gdbarch_skip_prologue (struct gdbarch *gdbarch, gdbarch_skip_prologue_ftype *skip_prologue);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SKIP_PROLOGUE)
+#error "Non multi-arch definition of SKIP_PROLOGUE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SKIP_PROLOGUE)
+#define SKIP_PROLOGUE(ip) (gdbarch_skip_prologue (current_gdbarch, ip))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (PROLOGUE_FRAMELESS_P)
+#define PROLOGUE_FRAMELESS_P(ip) (generic_prologue_frameless_p (ip))
+#endif
+
+typedef int (gdbarch_prologue_frameless_p_ftype) (CORE_ADDR ip);
+extern int gdbarch_prologue_frameless_p (struct gdbarch *gdbarch, CORE_ADDR ip);
+extern void set_gdbarch_prologue_frameless_p (struct gdbarch *gdbarch, gdbarch_prologue_frameless_p_ftype *prologue_frameless_p);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PROLOGUE_FRAMELESS_P)
+#error "Non multi-arch definition of PROLOGUE_FRAMELESS_P"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PROLOGUE_FRAMELESS_P)
+#define PROLOGUE_FRAMELESS_P(ip) (gdbarch_prologue_frameless_p (current_gdbarch, ip))
+#endif
+#endif
+
+typedef int (gdbarch_inner_than_ftype) (CORE_ADDR lhs, CORE_ADDR rhs);
+extern int gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs);
+extern void set_gdbarch_inner_than (struct gdbarch *gdbarch, gdbarch_inner_than_ftype *inner_than);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (INNER_THAN)
+#error "Non multi-arch definition of INNER_THAN"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (INNER_THAN)
+#define INNER_THAN(lhs, rhs) (gdbarch_inner_than (current_gdbarch, lhs, rhs))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (BREAKPOINT_FROM_PC)
+#define BREAKPOINT_FROM_PC(pcptr, lenptr) (legacy_breakpoint_from_pc (pcptr, lenptr))
+#endif
+
+typedef const unsigned char * (gdbarch_breakpoint_from_pc_ftype) (CORE_ADDR *pcptr, int *lenptr);
+extern const unsigned char * gdbarch_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr);
+extern void set_gdbarch_breakpoint_from_pc (struct gdbarch *gdbarch, gdbarch_breakpoint_from_pc_ftype *breakpoint_from_pc);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (BREAKPOINT_FROM_PC)
+#error "Non multi-arch definition of BREAKPOINT_FROM_PC"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (BREAKPOINT_FROM_PC)
+#define BREAKPOINT_FROM_PC(pcptr, lenptr) (gdbarch_breakpoint_from_pc (current_gdbarch, pcptr, lenptr))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (MEMORY_INSERT_BREAKPOINT)
+#define MEMORY_INSERT_BREAKPOINT(addr, contents_cache) (default_memory_insert_breakpoint (addr, contents_cache))
+#endif
+
+typedef int (gdbarch_memory_insert_breakpoint_ftype) (CORE_ADDR addr, char *contents_cache);
+extern int gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, CORE_ADDR addr, char *contents_cache);
+extern void set_gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, gdbarch_memory_insert_breakpoint_ftype *memory_insert_breakpoint);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (MEMORY_INSERT_BREAKPOINT)
+#error "Non multi-arch definition of MEMORY_INSERT_BREAKPOINT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (MEMORY_INSERT_BREAKPOINT)
+#define MEMORY_INSERT_BREAKPOINT(addr, contents_cache) (gdbarch_memory_insert_breakpoint (current_gdbarch, addr, contents_cache))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (MEMORY_REMOVE_BREAKPOINT)
+#define MEMORY_REMOVE_BREAKPOINT(addr, contents_cache) (default_memory_remove_breakpoint (addr, contents_cache))
+#endif
+
+typedef int (gdbarch_memory_remove_breakpoint_ftype) (CORE_ADDR addr, char *contents_cache);
+extern int gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch, CORE_ADDR addr, char *contents_cache);
+extern void set_gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch, gdbarch_memory_remove_breakpoint_ftype *memory_remove_breakpoint);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (MEMORY_REMOVE_BREAKPOINT)
+#error "Non multi-arch definition of MEMORY_REMOVE_BREAKPOINT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (MEMORY_REMOVE_BREAKPOINT)
+#define MEMORY_REMOVE_BREAKPOINT(addr, contents_cache) (gdbarch_memory_remove_breakpoint (current_gdbarch, addr, contents_cache))
+#endif
+#endif
+
+extern CORE_ADDR gdbarch_decr_pc_after_break (struct gdbarch *gdbarch);
+extern void set_gdbarch_decr_pc_after_break (struct gdbarch *gdbarch, CORE_ADDR decr_pc_after_break);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DECR_PC_AFTER_BREAK)
+#error "Non multi-arch definition of DECR_PC_AFTER_BREAK"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DECR_PC_AFTER_BREAK)
+#define DECR_PC_AFTER_BREAK (gdbarch_decr_pc_after_break (current_gdbarch))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (PREPARE_TO_PROCEED)
+#define PREPARE_TO_PROCEED(select_it) (default_prepare_to_proceed (select_it))
+#endif
+
+typedef int (gdbarch_prepare_to_proceed_ftype) (int select_it);
+extern int gdbarch_prepare_to_proceed (struct gdbarch *gdbarch, int select_it);
+extern void set_gdbarch_prepare_to_proceed (struct gdbarch *gdbarch, gdbarch_prepare_to_proceed_ftype *prepare_to_proceed);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PREPARE_TO_PROCEED)
+#error "Non multi-arch definition of PREPARE_TO_PROCEED"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PREPARE_TO_PROCEED)
+#define PREPARE_TO_PROCEED(select_it) (gdbarch_prepare_to_proceed (current_gdbarch, select_it))
+#endif
+#endif
+
+extern CORE_ADDR gdbarch_function_start_offset (struct gdbarch *gdbarch);
+extern void set_gdbarch_function_start_offset (struct gdbarch *gdbarch, CORE_ADDR function_start_offset);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FUNCTION_START_OFFSET)
+#error "Non multi-arch definition of FUNCTION_START_OFFSET"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FUNCTION_START_OFFSET)
+#define FUNCTION_START_OFFSET (gdbarch_function_start_offset (current_gdbarch))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (REMOTE_TRANSLATE_XFER_ADDRESS)
+#define REMOTE_TRANSLATE_XFER_ADDRESS(gdb_addr, gdb_len, rem_addr, rem_len) (generic_remote_translate_xfer_address (gdb_addr, gdb_len, rem_addr, rem_len))
+#endif
+
+typedef void (gdbarch_remote_translate_xfer_address_ftype) (CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR *rem_addr, int *rem_len);
+extern void gdbarch_remote_translate_xfer_address (struct gdbarch *gdbarch, CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR *rem_addr, int *rem_len);
+extern void set_gdbarch_remote_translate_xfer_address (struct gdbarch *gdbarch, gdbarch_remote_translate_xfer_address_ftype *remote_translate_xfer_address);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REMOTE_TRANSLATE_XFER_ADDRESS)
+#error "Non multi-arch definition of REMOTE_TRANSLATE_XFER_ADDRESS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REMOTE_TRANSLATE_XFER_ADDRESS)
+#define REMOTE_TRANSLATE_XFER_ADDRESS(gdb_addr, gdb_len, rem_addr, rem_len) (gdbarch_remote_translate_xfer_address (current_gdbarch, gdb_addr, gdb_len, rem_addr, rem_len))
+#endif
+#endif
+
+extern CORE_ADDR gdbarch_frame_args_skip (struct gdbarch *gdbarch);
+extern void set_gdbarch_frame_args_skip (struct gdbarch *gdbarch, CORE_ADDR frame_args_skip);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_ARGS_SKIP)
+#error "Non multi-arch definition of FRAME_ARGS_SKIP"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_ARGS_SKIP)
+#define FRAME_ARGS_SKIP (gdbarch_frame_args_skip (current_gdbarch))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (FRAMELESS_FUNCTION_INVOCATION)
+#define FRAMELESS_FUNCTION_INVOCATION(fi) (generic_frameless_function_invocation_not (fi))
+#endif
+
+typedef int (gdbarch_frameless_function_invocation_ftype) (struct frame_info *fi);
+extern int gdbarch_frameless_function_invocation (struct gdbarch *gdbarch, struct frame_info *fi);
+extern void set_gdbarch_frameless_function_invocation (struct gdbarch *gdbarch, gdbarch_frameless_function_invocation_ftype *frameless_function_invocation);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAMELESS_FUNCTION_INVOCATION)
+#error "Non multi-arch definition of FRAMELESS_FUNCTION_INVOCATION"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAMELESS_FUNCTION_INVOCATION)
+#define FRAMELESS_FUNCTION_INVOCATION(fi) (gdbarch_frameless_function_invocation (current_gdbarch, fi))
+#endif
+#endif
+
+typedef CORE_ADDR (gdbarch_frame_chain_ftype) (struct frame_info *frame);
+extern CORE_ADDR gdbarch_frame_chain (struct gdbarch *gdbarch, struct frame_info *frame);
+extern void set_gdbarch_frame_chain (struct gdbarch *gdbarch, gdbarch_frame_chain_ftype *frame_chain);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_CHAIN)
+#error "Non multi-arch definition of FRAME_CHAIN"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_CHAIN)
+#define FRAME_CHAIN(frame) (gdbarch_frame_chain (current_gdbarch, frame))
+#endif
+#endif
+
+/* Define a default FRAME_CHAIN_VALID, in the form that is suitable for
+ most targets. If FRAME_CHAIN_VALID returns zero it means that the
+ given frame is the outermost one and has no caller.
+
+ XXXX - both default and alternate frame_chain_valid functions are
+ deprecated. New code should use dummy frames and one of the generic
+ functions. */
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (FRAME_CHAIN_VALID)
+#define FRAME_CHAIN_VALID(chain, thisframe) (func_frame_chain_valid (chain, thisframe))
+#endif
+
+typedef int (gdbarch_frame_chain_valid_ftype) (CORE_ADDR chain, struct frame_info *thisframe);
+extern int gdbarch_frame_chain_valid (struct gdbarch *gdbarch, CORE_ADDR chain, struct frame_info *thisframe);
+extern void set_gdbarch_frame_chain_valid (struct gdbarch *gdbarch, gdbarch_frame_chain_valid_ftype *frame_chain_valid);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_CHAIN_VALID)
+#error "Non multi-arch definition of FRAME_CHAIN_VALID"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_CHAIN_VALID)
+#define FRAME_CHAIN_VALID(chain, thisframe) (gdbarch_frame_chain_valid (current_gdbarch, chain, thisframe))
+#endif
+#endif
+
+typedef CORE_ADDR (gdbarch_frame_saved_pc_ftype) (struct frame_info *fi);
+extern CORE_ADDR gdbarch_frame_saved_pc (struct gdbarch *gdbarch, struct frame_info *fi);
+extern void set_gdbarch_frame_saved_pc (struct gdbarch *gdbarch, gdbarch_frame_saved_pc_ftype *frame_saved_pc);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_SAVED_PC)
+#error "Non multi-arch definition of FRAME_SAVED_PC"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_SAVED_PC)
+#define FRAME_SAVED_PC(fi) (gdbarch_frame_saved_pc (current_gdbarch, fi))
+#endif
+#endif
+
+typedef CORE_ADDR (gdbarch_frame_args_address_ftype) (struct frame_info *fi);
+extern CORE_ADDR gdbarch_frame_args_address (struct gdbarch *gdbarch, struct frame_info *fi);
+extern void set_gdbarch_frame_args_address (struct gdbarch *gdbarch, gdbarch_frame_args_address_ftype *frame_args_address);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_ARGS_ADDRESS)
+#error "Non multi-arch definition of FRAME_ARGS_ADDRESS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_ARGS_ADDRESS)
+#define FRAME_ARGS_ADDRESS(fi) (gdbarch_frame_args_address (current_gdbarch, fi))
+#endif
+#endif
+
+typedef CORE_ADDR (gdbarch_frame_locals_address_ftype) (struct frame_info *fi);
+extern CORE_ADDR gdbarch_frame_locals_address (struct gdbarch *gdbarch, struct frame_info *fi);
+extern void set_gdbarch_frame_locals_address (struct gdbarch *gdbarch, gdbarch_frame_locals_address_ftype *frame_locals_address);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_LOCALS_ADDRESS)
+#error "Non multi-arch definition of FRAME_LOCALS_ADDRESS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_LOCALS_ADDRESS)
+#define FRAME_LOCALS_ADDRESS(fi) (gdbarch_frame_locals_address (current_gdbarch, fi))
+#endif
+#endif
+
+typedef CORE_ADDR (gdbarch_saved_pc_after_call_ftype) (struct frame_info *frame);
+extern CORE_ADDR gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, struct frame_info *frame);
+extern void set_gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, gdbarch_saved_pc_after_call_ftype *saved_pc_after_call);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SAVED_PC_AFTER_CALL)
+#error "Non multi-arch definition of SAVED_PC_AFTER_CALL"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SAVED_PC_AFTER_CALL)
+#define SAVED_PC_AFTER_CALL(frame) (gdbarch_saved_pc_after_call (current_gdbarch, frame))
+#endif
+#endif
+
+typedef int (gdbarch_frame_num_args_ftype) (struct frame_info *frame);
+extern int gdbarch_frame_num_args (struct gdbarch *gdbarch, struct frame_info *frame);
+extern void set_gdbarch_frame_num_args (struct gdbarch *gdbarch, gdbarch_frame_num_args_ftype *frame_num_args);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (FRAME_NUM_ARGS)
+#error "Non multi-arch definition of FRAME_NUM_ARGS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (FRAME_NUM_ARGS)
+#define FRAME_NUM_ARGS(frame) (gdbarch_frame_num_args (current_gdbarch, frame))
+#endif
+#endif
+
+#if defined (STACK_ALIGN)
+/* Legacy for systems yet to multi-arch STACK_ALIGN */
+#if !defined (STACK_ALIGN_P)
+#define STACK_ALIGN_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (STACK_ALIGN_P)
+#define STACK_ALIGN_P() (0)
+#endif
+
+extern int gdbarch_stack_align_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (STACK_ALIGN_P)
+#error "Non multi-arch definition of STACK_ALIGN"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (STACK_ALIGN_P)
+#define STACK_ALIGN_P() (gdbarch_stack_align_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (STACK_ALIGN)
+#define STACK_ALIGN(sp) (internal_error (__FILE__, __LINE__, "STACK_ALIGN"), 0)
+#endif
+
+typedef CORE_ADDR (gdbarch_stack_align_ftype) (CORE_ADDR sp);
+extern CORE_ADDR gdbarch_stack_align (struct gdbarch *gdbarch, CORE_ADDR sp);
+extern void set_gdbarch_stack_align (struct gdbarch *gdbarch, gdbarch_stack_align_ftype *stack_align);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (STACK_ALIGN)
+#error "Non multi-arch definition of STACK_ALIGN"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (STACK_ALIGN)
+#define STACK_ALIGN(sp) (gdbarch_stack_align (current_gdbarch, sp))
+#endif
+#endif
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (EXTRA_STACK_ALIGNMENT_NEEDED)
+#define EXTRA_STACK_ALIGNMENT_NEEDED (1)
+#endif
+
+extern int gdbarch_extra_stack_alignment_needed (struct gdbarch *gdbarch);
+extern void set_gdbarch_extra_stack_alignment_needed (struct gdbarch *gdbarch, int extra_stack_alignment_needed);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (EXTRA_STACK_ALIGNMENT_NEEDED)
+#error "Non multi-arch definition of EXTRA_STACK_ALIGNMENT_NEEDED"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (EXTRA_STACK_ALIGNMENT_NEEDED)
+#define EXTRA_STACK_ALIGNMENT_NEEDED (gdbarch_extra_stack_alignment_needed (current_gdbarch))
+#endif
+#endif
+
+#if defined (REG_STRUCT_HAS_ADDR)
+/* Legacy for systems yet to multi-arch REG_STRUCT_HAS_ADDR */
+#if !defined (REG_STRUCT_HAS_ADDR_P)
+#define REG_STRUCT_HAS_ADDR_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (REG_STRUCT_HAS_ADDR_P)
+#define REG_STRUCT_HAS_ADDR_P() (0)
+#endif
+
+extern int gdbarch_reg_struct_has_addr_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REG_STRUCT_HAS_ADDR_P)
+#error "Non multi-arch definition of REG_STRUCT_HAS_ADDR"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REG_STRUCT_HAS_ADDR_P)
+#define REG_STRUCT_HAS_ADDR_P() (gdbarch_reg_struct_has_addr_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (REG_STRUCT_HAS_ADDR)
+#define REG_STRUCT_HAS_ADDR(gcc_p, type) (internal_error (__FILE__, __LINE__, "REG_STRUCT_HAS_ADDR"), 0)
+#endif
+
+typedef int (gdbarch_reg_struct_has_addr_ftype) (int gcc_p, struct type *type);
+extern int gdbarch_reg_struct_has_addr (struct gdbarch *gdbarch, int gcc_p, struct type *type);
+extern void set_gdbarch_reg_struct_has_addr (struct gdbarch *gdbarch, gdbarch_reg_struct_has_addr_ftype *reg_struct_has_addr);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (REG_STRUCT_HAS_ADDR)
+#error "Non multi-arch definition of REG_STRUCT_HAS_ADDR"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (REG_STRUCT_HAS_ADDR)
+#define REG_STRUCT_HAS_ADDR(gcc_p, type) (gdbarch_reg_struct_has_addr (current_gdbarch, gcc_p, type))
+#endif
+#endif
+
+#if defined (SAVE_DUMMY_FRAME_TOS)
+/* Legacy for systems yet to multi-arch SAVE_DUMMY_FRAME_TOS */
+#if !defined (SAVE_DUMMY_FRAME_TOS_P)
+#define SAVE_DUMMY_FRAME_TOS_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (SAVE_DUMMY_FRAME_TOS_P)
+#define SAVE_DUMMY_FRAME_TOS_P() (0)
+#endif
+
+extern int gdbarch_save_dummy_frame_tos_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SAVE_DUMMY_FRAME_TOS_P)
+#error "Non multi-arch definition of SAVE_DUMMY_FRAME_TOS"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SAVE_DUMMY_FRAME_TOS_P)
+#define SAVE_DUMMY_FRAME_TOS_P() (gdbarch_save_dummy_frame_tos_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (SAVE_DUMMY_FRAME_TOS)
+#define SAVE_DUMMY_FRAME_TOS(sp) (internal_error (__FILE__, __LINE__, "SAVE_DUMMY_FRAME_TOS"), 0)
+#endif
+
+typedef void (gdbarch_save_dummy_frame_tos_ftype) (CORE_ADDR sp);
+extern void gdbarch_save_dummy_frame_tos (struct gdbarch *gdbarch, CORE_ADDR sp);
+extern void set_gdbarch_save_dummy_frame_tos (struct gdbarch *gdbarch, gdbarch_save_dummy_frame_tos_ftype *save_dummy_frame_tos);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SAVE_DUMMY_FRAME_TOS)
+#error "Non multi-arch definition of SAVE_DUMMY_FRAME_TOS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SAVE_DUMMY_FRAME_TOS)
+#define SAVE_DUMMY_FRAME_TOS(sp) (gdbarch_save_dummy_frame_tos (current_gdbarch, sp))
+#endif
+#endif
+
+extern int gdbarch_parm_boundary (struct gdbarch *gdbarch);
+extern void set_gdbarch_parm_boundary (struct gdbarch *gdbarch, int parm_boundary);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PARM_BOUNDARY)
+#error "Non multi-arch definition of PARM_BOUNDARY"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PARM_BOUNDARY)
+#define PARM_BOUNDARY (gdbarch_parm_boundary (current_gdbarch))
+#endif
+#endif
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_FLOAT_FORMAT)
+#define TARGET_FLOAT_FORMAT (default_float_format (current_gdbarch))
+#endif
+
+extern const struct floatformat * gdbarch_float_format (struct gdbarch *gdbarch);
+extern void set_gdbarch_float_format (struct gdbarch *gdbarch, const struct floatformat * float_format);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_FLOAT_FORMAT)
+#error "Non multi-arch definition of TARGET_FLOAT_FORMAT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_FLOAT_FORMAT)
+#define TARGET_FLOAT_FORMAT (gdbarch_float_format (current_gdbarch))
+#endif
+#endif
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_DOUBLE_FORMAT)
+#define TARGET_DOUBLE_FORMAT (default_double_format (current_gdbarch))
+#endif
+
+extern const struct floatformat * gdbarch_double_format (struct gdbarch *gdbarch);
+extern void set_gdbarch_double_format (struct gdbarch *gdbarch, const struct floatformat * double_format);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_DOUBLE_FORMAT)
+#error "Non multi-arch definition of TARGET_DOUBLE_FORMAT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_DOUBLE_FORMAT)
+#define TARGET_DOUBLE_FORMAT (gdbarch_double_format (current_gdbarch))
+#endif
+#endif
+
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_LONG_DOUBLE_FORMAT)
+#define TARGET_LONG_DOUBLE_FORMAT (default_double_format (current_gdbarch))
+#endif
+
+extern const struct floatformat * gdbarch_long_double_format (struct gdbarch *gdbarch);
+extern void set_gdbarch_long_double_format (struct gdbarch *gdbarch, const struct floatformat * long_double_format);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_LONG_DOUBLE_FORMAT)
+#error "Non multi-arch definition of TARGET_LONG_DOUBLE_FORMAT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_LONG_DOUBLE_FORMAT)
+#define TARGET_LONG_DOUBLE_FORMAT (gdbarch_long_double_format (current_gdbarch))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (CONVERT_FROM_FUNC_PTR_ADDR)
+#define CONVERT_FROM_FUNC_PTR_ADDR(addr) (core_addr_identity (addr))
+#endif
+
+typedef CORE_ADDR (gdbarch_convert_from_func_ptr_addr_ftype) (CORE_ADDR addr);
+extern CORE_ADDR gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr);
+extern void set_gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (CONVERT_FROM_FUNC_PTR_ADDR)
+#error "Non multi-arch definition of CONVERT_FROM_FUNC_PTR_ADDR"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CONVERT_FROM_FUNC_PTR_ADDR)
+#define CONVERT_FROM_FUNC_PTR_ADDR(addr) (gdbarch_convert_from_func_ptr_addr (current_gdbarch, addr))
+#endif
+#endif
+
+/* On some machines there are bits in addresses which are not really
+ part of the address, but are used by the kernel, the hardware, etc.
+ for special purposes. ADDR_BITS_REMOVE takes out any such bits so
+ we get a "real" address such as one would find in a symbol table.
+ This is used only for addresses of instructions, and even then I'm
+ not sure it's used in all contexts. It exists to deal with there
+ being a few stray bits in the PC which would mislead us, not as some
+ sort of generic thing to handle alignment or segmentation (it's
+ possible it should be in TARGET_READ_PC instead). */
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (ADDR_BITS_REMOVE)
+#define ADDR_BITS_REMOVE(addr) (core_addr_identity (addr))
+#endif
+
+typedef CORE_ADDR (gdbarch_addr_bits_remove_ftype) (CORE_ADDR addr);
+extern CORE_ADDR gdbarch_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr);
+extern void set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch, gdbarch_addr_bits_remove_ftype *addr_bits_remove);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ADDR_BITS_REMOVE)
+#error "Non multi-arch definition of ADDR_BITS_REMOVE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ADDR_BITS_REMOVE)
+#define ADDR_BITS_REMOVE(addr) (gdbarch_addr_bits_remove (current_gdbarch, addr))
+#endif
+#endif
+
+/* It is not at all clear why SMASH_TEXT_ADDRESS is not folded into
+ ADDR_BITS_REMOVE. */
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (SMASH_TEXT_ADDRESS)
+#define SMASH_TEXT_ADDRESS(addr) (core_addr_identity (addr))
+#endif
+
+typedef CORE_ADDR (gdbarch_smash_text_address_ftype) (CORE_ADDR addr);
+extern CORE_ADDR gdbarch_smash_text_address (struct gdbarch *gdbarch, CORE_ADDR addr);
+extern void set_gdbarch_smash_text_address (struct gdbarch *gdbarch, gdbarch_smash_text_address_ftype *smash_text_address);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SMASH_TEXT_ADDRESS)
+#error "Non multi-arch definition of SMASH_TEXT_ADDRESS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SMASH_TEXT_ADDRESS)
+#define SMASH_TEXT_ADDRESS(addr) (gdbarch_smash_text_address (current_gdbarch, addr))
+#endif
+#endif
+
+/* FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if
+ the target needs software single step. An ISA method to implement it.
+
+ FIXME/cagney/2001-01-18: This should be replaced with something that inserts breakpoints
+ using the breakpoint system instead of blatting memory directly (as with rs6000).
+
+ FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the target can
+ single step. If not, then implement single step using breakpoints. */
+
+#if defined (SOFTWARE_SINGLE_STEP)
+/* Legacy for systems yet to multi-arch SOFTWARE_SINGLE_STEP */
+#if !defined (SOFTWARE_SINGLE_STEP_P)
+#define SOFTWARE_SINGLE_STEP_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (SOFTWARE_SINGLE_STEP_P)
+#define SOFTWARE_SINGLE_STEP_P() (0)
+#endif
+
+extern int gdbarch_software_single_step_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SOFTWARE_SINGLE_STEP_P)
+#error "Non multi-arch definition of SOFTWARE_SINGLE_STEP"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SOFTWARE_SINGLE_STEP_P)
+#define SOFTWARE_SINGLE_STEP_P() (gdbarch_software_single_step_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (SOFTWARE_SINGLE_STEP)
+#define SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p) (internal_error (__FILE__, __LINE__, "SOFTWARE_SINGLE_STEP"), 0)
+#endif
+
+typedef void (gdbarch_software_single_step_ftype) (enum target_signal sig, int insert_breakpoints_p);
+extern void gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p);
+extern void set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch_software_single_step_ftype *software_single_step);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SOFTWARE_SINGLE_STEP)
+#error "Non multi-arch definition of SOFTWARE_SINGLE_STEP"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SOFTWARE_SINGLE_STEP)
+#define SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p) (gdbarch_software_single_step (current_gdbarch, sig, insert_breakpoints_p))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (TARGET_PRINT_INSN)
+#define TARGET_PRINT_INSN(vma, info) (legacy_print_insn (vma, info))
+#endif
+
+typedef int (gdbarch_print_insn_ftype) (bfd_vma vma, disassemble_info *info);
+extern int gdbarch_print_insn (struct gdbarch *gdbarch, bfd_vma vma, disassemble_info *info);
+extern void set_gdbarch_print_insn (struct gdbarch *gdbarch, gdbarch_print_insn_ftype *print_insn);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_PRINT_INSN)
+#error "Non multi-arch definition of TARGET_PRINT_INSN"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_PRINT_INSN)
+#define TARGET_PRINT_INSN(vma, info) (gdbarch_print_insn (current_gdbarch, vma, info))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (SKIP_TRAMPOLINE_CODE)
+#define SKIP_TRAMPOLINE_CODE(pc) (generic_skip_trampoline_code (pc))
+#endif
+
+typedef CORE_ADDR (gdbarch_skip_trampoline_code_ftype) (CORE_ADDR pc);
+extern CORE_ADDR gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, CORE_ADDR pc);
+extern void set_gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, gdbarch_skip_trampoline_code_ftype *skip_trampoline_code);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SKIP_TRAMPOLINE_CODE)
+#error "Non multi-arch definition of SKIP_TRAMPOLINE_CODE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SKIP_TRAMPOLINE_CODE)
+#define SKIP_TRAMPOLINE_CODE(pc) (gdbarch_skip_trampoline_code (current_gdbarch, pc))
+#endif
+#endif
+
+/* For SVR4 shared libraries, each call goes through a small piece of
+ trampoline code in the ".plt" section. IN_SOLIB_CALL_TRAMPOLINE evaluates
+ to nonzero if we are current stopped in one of these. */
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (IN_SOLIB_CALL_TRAMPOLINE)
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) (generic_in_solib_call_trampoline (pc, name))
+#endif
+
+typedef int (gdbarch_in_solib_call_trampoline_ftype) (CORE_ADDR pc, char *name);
+extern int gdbarch_in_solib_call_trampoline (struct gdbarch *gdbarch, CORE_ADDR pc, char *name);
+extern void set_gdbarch_in_solib_call_trampoline (struct gdbarch *gdbarch, gdbarch_in_solib_call_trampoline_ftype *in_solib_call_trampoline);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (IN_SOLIB_CALL_TRAMPOLINE)
+#error "Non multi-arch definition of IN_SOLIB_CALL_TRAMPOLINE"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (IN_SOLIB_CALL_TRAMPOLINE)
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) (gdbarch_in_solib_call_trampoline (current_gdbarch, pc, name))
+#endif
+#endif
+
+/* Sigtramp is a routine that the kernel calls (which then calls the
+ signal handler). On most machines it is a library routine that is
+ linked into the executable.
+
+ This macro, given a program counter value and the name of the
+ function in which that PC resides (which can be null if the name is
+ not known), returns nonzero if the PC and name show that we are in
+ sigtramp.
+
+ On most machines just see if the name is sigtramp (and if we have
+ no name, assume we are not in sigtramp).
+
+ FIXME: cagney/2002-04-21: The function find_pc_partial_function
+ calls find_pc_sect_partial_function() which calls PC_IN_SIGTRAMP.
+ This means PC_IN_SIGTRAMP function can't be implemented by doing its
+ own local NAME lookup.
+
+ FIXME: cagney/2002-04-21: PC_IN_SIGTRAMP is something of a mess.
+ Some code also depends on SIGTRAMP_START and SIGTRAMP_END but other
+ does not. */
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (PC_IN_SIGTRAMP)
+#define PC_IN_SIGTRAMP(pc, name) (legacy_pc_in_sigtramp (pc, name))
+#endif
+
+typedef int (gdbarch_pc_in_sigtramp_ftype) (CORE_ADDR pc, char *name);
+extern int gdbarch_pc_in_sigtramp (struct gdbarch *gdbarch, CORE_ADDR pc, char *name);
+extern void set_gdbarch_pc_in_sigtramp (struct gdbarch *gdbarch, gdbarch_pc_in_sigtramp_ftype *pc_in_sigtramp);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PC_IN_SIGTRAMP)
+#error "Non multi-arch definition of PC_IN_SIGTRAMP"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PC_IN_SIGTRAMP)
+#define PC_IN_SIGTRAMP(pc, name) (gdbarch_pc_in_sigtramp (current_gdbarch, pc, name))
+#endif
+#endif
+
+/* A target might have problems with watchpoints as soon as the stack
+ frame of the current function has been destroyed. This mostly happens
+ as the first action in a funtion's epilogue. in_function_epilogue_p()
+ is defined to return a non-zero value if either the given addr is one
+ instruction after the stack destroying instruction up to the trailing
+ return instruction or if we can figure out that the stack frame has
+ already been invalidated regardless of the value of addr. Targets
+ which don't suffer from that problem could just let this functionality
+ untouched. */
+
+typedef int (gdbarch_in_function_epilogue_p_ftype) (struct gdbarch *gdbarch, CORE_ADDR addr);
+extern int gdbarch_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR addr);
+extern void set_gdbarch_in_function_epilogue_p (struct gdbarch *gdbarch, gdbarch_in_function_epilogue_p_ftype *in_function_epilogue_p);
+
+/* Given a vector of command-line arguments, return a newly allocated
+ string which, when passed to the create_inferior function, will be
+ parsed (on Unix systems, by the shell) to yield the same vector.
+ This function should call error() if the argument vector is not
+ representable for this target or if this target does not support
+ command-line arguments.
+ ARGC is the number of elements in the vector.
+ ARGV is an array of strings, one per argument. */
+
+typedef char * (gdbarch_construct_inferior_arguments_ftype) (struct gdbarch *gdbarch, int argc, char **argv);
+extern char * gdbarch_construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv);
+extern void set_gdbarch_construct_inferior_arguments (struct gdbarch *gdbarch, gdbarch_construct_inferior_arguments_ftype *construct_inferior_arguments);
+
+#if defined (DWARF2_BUILD_FRAME_INFO)
+/* Legacy for systems yet to multi-arch DWARF2_BUILD_FRAME_INFO */
+#if !defined (DWARF2_BUILD_FRAME_INFO_P)
+#define DWARF2_BUILD_FRAME_INFO_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (DWARF2_BUILD_FRAME_INFO_P)
+#define DWARF2_BUILD_FRAME_INFO_P() (0)
+#endif
+
+extern int gdbarch_dwarf2_build_frame_info_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DWARF2_BUILD_FRAME_INFO_P)
+#error "Non multi-arch definition of DWARF2_BUILD_FRAME_INFO"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DWARF2_BUILD_FRAME_INFO_P)
+#define DWARF2_BUILD_FRAME_INFO_P() (gdbarch_dwarf2_build_frame_info_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (DWARF2_BUILD_FRAME_INFO)
+#define DWARF2_BUILD_FRAME_INFO(objfile) (internal_error (__FILE__, __LINE__, "DWARF2_BUILD_FRAME_INFO"), 0)
+#endif
+
+typedef void (gdbarch_dwarf2_build_frame_info_ftype) (struct objfile *objfile);
+extern void gdbarch_dwarf2_build_frame_info (struct gdbarch *gdbarch, struct objfile *objfile);
+extern void set_gdbarch_dwarf2_build_frame_info (struct gdbarch *gdbarch, gdbarch_dwarf2_build_frame_info_ftype *dwarf2_build_frame_info);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DWARF2_BUILD_FRAME_INFO)
+#error "Non multi-arch definition of DWARF2_BUILD_FRAME_INFO"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DWARF2_BUILD_FRAME_INFO)
+#define DWARF2_BUILD_FRAME_INFO(objfile) (gdbarch_dwarf2_build_frame_info (current_gdbarch, objfile))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (ELF_MAKE_MSYMBOL_SPECIAL)
+#define ELF_MAKE_MSYMBOL_SPECIAL(sym, msym) (default_elf_make_msymbol_special (sym, msym))
+#endif
+
+typedef void (gdbarch_elf_make_msymbol_special_ftype) (asymbol *sym, struct minimal_symbol *msym);
+extern void gdbarch_elf_make_msymbol_special (struct gdbarch *gdbarch, asymbol *sym, struct minimal_symbol *msym);
+extern void set_gdbarch_elf_make_msymbol_special (struct gdbarch *gdbarch, gdbarch_elf_make_msymbol_special_ftype *elf_make_msymbol_special);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ELF_MAKE_MSYMBOL_SPECIAL)
+#error "Non multi-arch definition of ELF_MAKE_MSYMBOL_SPECIAL"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ELF_MAKE_MSYMBOL_SPECIAL)
+#define ELF_MAKE_MSYMBOL_SPECIAL(sym, msym) (gdbarch_elf_make_msymbol_special (current_gdbarch, sym, msym))
+#endif
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (COFF_MAKE_MSYMBOL_SPECIAL)
+#define COFF_MAKE_MSYMBOL_SPECIAL(val, msym) (default_coff_make_msymbol_special (val, msym))
+#endif
+
+typedef void (gdbarch_coff_make_msymbol_special_ftype) (int val, struct minimal_symbol *msym);
+extern void gdbarch_coff_make_msymbol_special (struct gdbarch *gdbarch, int val, struct minimal_symbol *msym);
+extern void set_gdbarch_coff_make_msymbol_special (struct gdbarch *gdbarch, gdbarch_coff_make_msymbol_special_ftype *coff_make_msymbol_special);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (COFF_MAKE_MSYMBOL_SPECIAL)
+#error "Non multi-arch definition of COFF_MAKE_MSYMBOL_SPECIAL"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (COFF_MAKE_MSYMBOL_SPECIAL)
+#define COFF_MAKE_MSYMBOL_SPECIAL(val, msym) (gdbarch_coff_make_msymbol_special (current_gdbarch, val, msym))
+#endif
+#endif
+
+extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
+
+
+/* Mechanism for co-ordinating the selection of a specific
+ architecture.
+
+ GDB targets (*-tdep.c) can register an interest in a specific
+ architecture. Other GDB components can register a need to maintain
+ per-architecture data.
+
+ The mechanisms below ensures that there is only a loose connection
+ between the set-architecture command and the various GDB
+ components. Each component can independently register their need
+ to maintain architecture specific data with gdbarch.
+
+ Pragmatics:
+
+ Previously, a single TARGET_ARCHITECTURE_HOOK was provided. It
+ didn't scale.
+
+ The more traditional mega-struct containing architecture specific
+ data for all the various GDB components was also considered. Since
+ GDB is built from a variable number of (fairly independent)
+ components it was determined that the global aproach was not
+ applicable. */
+
+
+/* Register a new architectural family with GDB.
+
+ Register support for the specified ARCHITECTURE with GDB. When
+ gdbarch determines that the specified architecture has been
+ selected, the corresponding INIT function is called.
+
+ --
+
+ The INIT function takes two parameters: INFO which contains the
+ information available to gdbarch about the (possibly new)
+ architecture; ARCHES which is a list of the previously created
+ ``struct gdbarch'' for this architecture.
+
+ The INFO parameter is, as far as possible, be pre-initialized with
+ information obtained from INFO.ABFD or the previously selected
+ architecture.
+
+ The ARCHES parameter is a linked list (sorted most recently used)
+ of all the previously created architures for this architecture
+ family. The (possibly NULL) ARCHES->gdbarch can used to access
+ values from the previously selected architecture for this
+ architecture family. The global ``current_gdbarch'' shall not be
+ used.
+
+ The INIT function shall return any of: NULL - indicating that it
+ doesn't recognize the selected architecture; an existing ``struct
+ gdbarch'' from the ARCHES list - indicating that the new
+ architecture is just a synonym for an earlier architecture (see
+ gdbarch_list_lookup_by_info()); a newly created ``struct gdbarch''
+ - that describes the selected architecture (see gdbarch_alloc()).
+
+ The DUMP_TDEP function shall print out all target specific values.
+ Care should be taken to ensure that the function works in both the
+ multi-arch and non- multi-arch cases. */
+
+struct gdbarch_list
+{
+ struct gdbarch *gdbarch;
+ struct gdbarch_list *next;
+};
+
+struct gdbarch_info
+{
+ /* Use default: NULL (ZERO). */
+ const struct bfd_arch_info *bfd_arch_info;
+
+ /* Use default: BFD_ENDIAN_UNKNOWN (NB: is not ZERO). */
+ int byte_order;
+
+ /* Use default: NULL (ZERO). */
+ bfd *abfd;
+
+ /* Use default: NULL (ZERO). */
+ struct gdbarch_tdep_info *tdep_info;
+};
+
+typedef struct gdbarch *(gdbarch_init_ftype) (struct gdbarch_info info, struct gdbarch_list *arches);
+typedef void (gdbarch_dump_tdep_ftype) (struct gdbarch *gdbarch, struct ui_file *file);
+
+/* DEPRECATED - use gdbarch_register() */
+extern void register_gdbarch_init (enum bfd_architecture architecture, gdbarch_init_ftype *);
+
+extern void gdbarch_register (enum bfd_architecture architecture,
+ gdbarch_init_ftype *,
+ gdbarch_dump_tdep_ftype *);
+
+
+/* Return a freshly allocated, NULL terminated, array of the valid
+ architecture names. Since architectures are registered during the
+ _initialize phase this function only returns useful information
+ once initialization has been completed. */
+
+extern const char **gdbarch_printable_names (void);
+
+
+/* Helper function. Search the list of ARCHES for a GDBARCH that
+ matches the information provided by INFO. */
+
+extern struct gdbarch_list *gdbarch_list_lookup_by_info (struct gdbarch_list *arches, const struct gdbarch_info *info);
+
+
+/* Helper function. Create a preliminary ``struct gdbarch''. Perform
+ basic initialization using values obtained from the INFO andTDEP
+ parameters. set_gdbarch_*() functions are called to complete the
+ initialization of the object. */
+
+extern struct gdbarch *gdbarch_alloc (const struct gdbarch_info *info, struct gdbarch_tdep *tdep);
+
+
+/* Helper function. Free a partially-constructed ``struct gdbarch''.
+ It is assumed that the caller freeds the ``struct
+ gdbarch_tdep''. */
+
+extern void gdbarch_free (struct gdbarch *);
+
+
+/* Helper function. Force an update of the current architecture.
+
+ The actual architecture selected is determined by INFO, ``(gdb) set
+ architecture'' et.al., the existing architecture and BFD's default
+ architecture. INFO should be initialized to zero and then selected
+ fields should be updated.
+
+ Returns non-zero if the update succeeds */
+
+extern int gdbarch_update_p (struct gdbarch_info info);
+
+
+
+/* Register per-architecture data-pointer.
+
+ Reserve space for a per-architecture data-pointer. An identifier
+ for the reserved data-pointer is returned. That identifer should
+ be saved in a local static variable.
+
+ The per-architecture data-pointer can be initialized in one of two
+ ways: The value can be set explicitly using a call to
+ set_gdbarch_data(); the value can be set implicitly using the value
+ returned by a non-NULL INIT() callback. INIT(), when non-NULL is
+ called after the basic architecture vector has been created.
+
+ When a previously created architecture is re-selected, the
+ per-architecture data-pointer for that previous architecture is
+ restored. INIT() is not called.
+
+ During initialization, multiple assignments of the data-pointer are
+ allowed, non-NULL values are deleted by calling FREE(). If the
+ architecture is deleted using gdbarch_free() all non-NULL data
+ pointers are also deleted using FREE().
+
+ Multiple registrarants for any architecture are allowed (and
+ strongly encouraged). */
+
+struct gdbarch_data;
+
+typedef void *(gdbarch_data_init_ftype) (struct gdbarch *gdbarch);
+typedef void (gdbarch_data_free_ftype) (struct gdbarch *gdbarch,
+ void *pointer);
+extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype *init,
+ gdbarch_data_free_ftype *free);
+extern void set_gdbarch_data (struct gdbarch *gdbarch,
+ struct gdbarch_data *data,
+ void *pointer);
+
+extern void *gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *);
+
+
+/* Register per-architecture memory region.
+
+ Provide a memory-region swap mechanism. Per-architecture memory
+ region are created. These memory regions are swapped whenever the
+ architecture is changed. For a new architecture, the memory region
+ is initialized with zero (0) and the INIT function is called.
+
+ Memory regions are swapped / initialized in the order that they are
+ registered. NULL DATA and/or INIT values can be specified.
+
+ New code should use register_gdbarch_data(). */
+
+typedef void (gdbarch_swap_ftype) (void);
+extern void register_gdbarch_swap (void *data, unsigned long size, gdbarch_swap_ftype *init);
+#define REGISTER_GDBARCH_SWAP(VAR) register_gdbarch_swap (&(VAR), sizeof ((VAR)), NULL)
+
+
+
+/* The target-system-dependent byte order is dynamic */
+
+extern int target_byte_order;
+#ifndef TARGET_BYTE_ORDER
+#define TARGET_BYTE_ORDER (target_byte_order + 0)
+#endif
+
+extern int target_byte_order_auto;
+#ifndef TARGET_BYTE_ORDER_AUTO
+#define TARGET_BYTE_ORDER_AUTO (target_byte_order_auto + 0)
+#endif
+
+
+
+/* The target-system-dependent BFD architecture is dynamic */
+
+extern int target_architecture_auto;
+#ifndef TARGET_ARCHITECTURE_AUTO
+#define TARGET_ARCHITECTURE_AUTO (target_architecture_auto + 0)
+#endif
+
+extern const struct bfd_arch_info *target_architecture;
+#ifndef TARGET_ARCHITECTURE
+#define TARGET_ARCHITECTURE (target_architecture + 0)
+#endif
+
+
+/* The target-system-dependent disassembler is semi-dynamic */
+
+extern int dis_asm_read_memory (bfd_vma memaddr, bfd_byte *myaddr,
+ unsigned int len, disassemble_info *info);
+
+extern void dis_asm_memory_error (int status, bfd_vma memaddr,
+ disassemble_info *info);
+
+extern void dis_asm_print_address (bfd_vma addr,
+ disassemble_info *info);
+
+extern int (*tm_print_insn) (bfd_vma, disassemble_info*);
+extern disassemble_info tm_print_insn_info;
+#ifndef TARGET_PRINT_INSN_INFO
+#define TARGET_PRINT_INSN_INFO (&tm_print_insn_info)
+#endif
+
+
+
+/* Set the dynamic target-system-dependent parameters (architecture,
+ byte-order, ...) using information found in the BFD */
+
+extern void set_gdbarch_from_file (bfd *);
+
+
+/* Initialize the current architecture to the "first" one we find on
+ our list. */
+
+extern void initialize_current_architecture (void);
+
+/* For non-multiarched targets, do any initialization of the default
+ gdbarch object necessary after the _initialize_MODULE functions
+ have run. */
+extern void initialize_non_multiarch ();
+
+/* gdbarch trace variable */
+extern int gdbarch_debug;
+
+extern void gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file);
+
+#endif
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
new file mode 100755
index 00000000000..ebcb4238550
--- /dev/null
+++ b/gdb/gdbarch.sh
@@ -0,0 +1,2330 @@
+#!/bin/sh -u
+
+# Architecture commands for GDB, the GNU debugger.
+# Copyright 1998, 1999, 2000, 2001, 2002 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.
+
+# Make certain that the script is running in an internationalized
+# environment.
+LANG=c ; export LANG
+LC_ALL=c ; export LC_ALL
+
+
+compare_new ()
+{
+ file=$1
+ if test ! -r ${file}
+ then
+ echo "${file} missing? cp new-${file} ${file}" 1>&2
+ elif diff -u ${file} new-${file}
+ then
+ echo "${file} unchanged" 1>&2
+ else
+ echo "${file} has changed? cp new-${file} ${file}" 1>&2
+ fi
+}
+
+
+# Format of the input table
+read="class level macro returntype function formal actual attrib staticdefault predefault postdefault invalid_p fmt print print_p description"
+
+do_read ()
+{
+ comment=""
+ class=""
+ while read line
+ do
+ if test "${line}" = ""
+ then
+ continue
+ elif test "${line}" = "#" -a "${comment}" = ""
+ then
+ continue
+ elif expr "${line}" : "#" > /dev/null
+ then
+ comment="${comment}
+${line}"
+ else
+
+ # The semantics of IFS varies between different SH's. Some
+ # treat ``::' as three fields while some treat it as just too.
+ # Work around this by eliminating ``::'' ....
+ line="`echo "${line}" | sed -e 's/::/: :/g' -e 's/::/: :/g'`"
+
+ OFS="${IFS}" ; IFS="[:]"
+ eval read ${read} <<EOF
+${line}
+EOF
+ IFS="${OFS}"
+
+ # .... and then going back through each field and strip out those
+ # that ended up with just that space character.
+ for r in ${read}
+ do
+ if eval test \"\${${r}}\" = \"\ \"
+ then
+ eval ${r}=""
+ fi
+ done
+
+ case "${level}" in
+ 1 ) gt_level=">= GDB_MULTI_ARCH_PARTIAL" ;;
+ 2 ) gt_level="> GDB_MULTI_ARCH_PARTIAL" ;;
+ "" ) ;;
+ * ) error "Error: bad level for ${function}" 1>&2 ; kill $$ ; exit 1 ;;
+ esac
+
+ case "${class}" in
+ m ) staticdefault="${predefault}" ;;
+ M ) staticdefault="0" ;;
+ * ) test "${staticdefault}" || staticdefault=0 ;;
+ esac
+ # NOT YET: Breaks BELIEVE_PCC_PROMOTION and confuses non-
+ # multi-arch defaults.
+ # test "${predefault}" || predefault=0
+
+ # come up with a format, use a few guesses for variables
+ case ":${class}:${fmt}:${print}:" in
+ :[vV]::: )
+ if [ "${returntype}" = int ]
+ then
+ fmt="%d"
+ print="${macro}"
+ elif [ "${returntype}" = long ]
+ then
+ fmt="%ld"
+ print="${macro}"
+ fi
+ ;;
+ esac
+ test "${fmt}" || fmt="%ld"
+ test "${print}" || print="(long) ${macro}"
+
+ case "${invalid_p}" in
+ 0 ) valid_p=1 ;;
+ "" )
+ if [ -n "${predefault}" ]
+ then
+ #invalid_p="gdbarch->${function} == ${predefault}"
+ valid_p="gdbarch->${function} != ${predefault}"
+ else
+ #invalid_p="gdbarch->${function} == 0"
+ valid_p="gdbarch->${function} != 0"
+ fi
+ ;;
+ * ) valid_p="!(${invalid_p})"
+ esac
+
+ # PREDEFAULT is a valid fallback definition of MEMBER when
+ # multi-arch is not enabled. This ensures that the
+ # default value, when multi-arch is the same as the
+ # default value when not multi-arch. POSTDEFAULT is
+ # always a valid definition of MEMBER as this again
+ # ensures consistency.
+
+ if [ -n "${postdefault}" ]
+ then
+ fallbackdefault="${postdefault}"
+ elif [ -n "${predefault}" ]
+ then
+ fallbackdefault="${predefault}"
+ else
+ fallbackdefault="0"
+ fi
+
+ #NOT YET: See gdbarch.log for basic verification of
+ # database
+
+ break
+ fi
+ done
+ if [ -n "${class}" ]
+ then
+ true
+ else
+ false
+ fi
+}
+
+
+fallback_default_p ()
+{
+ [ -n "${postdefault}" -a "x${invalid_p}" != "x0" ] \
+ || [ -n "${predefault}" -a "x${invalid_p}" = "x0" ]
+}
+
+class_is_variable_p ()
+{
+ case "${class}" in
+ *v* | *V* ) true ;;
+ * ) false ;;
+ esac
+}
+
+class_is_function_p ()
+{
+ case "${class}" in
+ *f* | *F* | *m* | *M* ) true ;;
+ * ) false ;;
+ esac
+}
+
+class_is_multiarch_p ()
+{
+ case "${class}" in
+ *m* | *M* ) true ;;
+ * ) false ;;
+ esac
+}
+
+class_is_predicate_p ()
+{
+ case "${class}" in
+ *F* | *V* | *M* ) true ;;
+ * ) false ;;
+ esac
+}
+
+class_is_info_p ()
+{
+ case "${class}" in
+ *i* ) true ;;
+ * ) false ;;
+ esac
+}
+
+
+# dump out/verify the doco
+for field in ${read}
+do
+ case ${field} in
+
+ class ) : ;;
+
+ # # -> line disable
+ # f -> function
+ # hiding a function
+ # F -> function + predicate
+ # hiding a function + predicate to test function validity
+ # v -> variable
+ # hiding a variable
+ # V -> variable + predicate
+ # hiding a variable + predicate to test variables validity
+ # i -> set from info
+ # hiding something from the ``struct info'' object
+ # m -> multi-arch function
+ # hiding a multi-arch function (parameterised with the architecture)
+ # M -> multi-arch function + predicate
+ # hiding a multi-arch function + predicate to test function validity
+
+ level ) : ;;
+
+ # See GDB_MULTI_ARCH description. Having GDB_MULTI_ARCH >=
+ # LEVEL is a predicate on checking that a given method is
+ # initialized (using INVALID_P).
+
+ macro ) : ;;
+
+ # The name of the MACRO that this method is to be accessed by.
+
+ returntype ) : ;;
+
+ # For functions, the return type; for variables, the data type
+
+ function ) : ;;
+
+ # For functions, the member function name; for variables, the
+ # variable name. Member function names are always prefixed with
+ # ``gdbarch_'' for name-space purity.
+
+ formal ) : ;;
+
+ # The formal argument list. It is assumed that the formal
+ # argument list includes the actual name of each list element.
+ # A function with no arguments shall have ``void'' as the
+ # formal argument list.
+
+ actual ) : ;;
+
+ # The list of actual arguments. The arguments specified shall
+ # match the FORMAL list given above. Functions with out
+ # arguments leave this blank.
+
+ attrib ) : ;;
+
+ # Any GCC attributes that should be attached to the function
+ # declaration. At present this field is unused.
+
+ staticdefault ) : ;;
+
+ # To help with the GDB startup a static gdbarch object is
+ # created. STATICDEFAULT is the value to insert into that
+ # static gdbarch object. Since this a static object only
+ # simple expressions can be used.
+
+ # If STATICDEFAULT is empty, zero is used.
+
+ predefault ) : ;;
+
+ # An initial value to assign to MEMBER of the freshly
+ # malloc()ed gdbarch object. After initialization, the
+ # freshly malloc()ed object is passed to the target
+ # architecture code for further updates.
+
+ # If PREDEFAULT is empty, zero is used.
+
+ # A non-empty PREDEFAULT, an empty POSTDEFAULT and a zero
+ # INVALID_P are specified, PREDEFAULT will be used as the
+ # default for the non- multi-arch target.
+
+ # A zero PREDEFAULT function will force the fallback to call
+ # internal_error().
+
+ # Variable declarations can refer to ``gdbarch'' which will
+ # contain the current architecture. Care should be taken.
+
+ postdefault ) : ;;
+
+ # A value to assign to MEMBER of the new gdbarch object should
+ # the target architecture code fail to change the PREDEFAULT
+ # value.
+
+ # If POSTDEFAULT is empty, no post update is performed.
+
+ # If both INVALID_P and POSTDEFAULT are non-empty then
+ # INVALID_P will be used to determine if MEMBER should be
+ # changed to POSTDEFAULT.
+
+ # If a non-empty POSTDEFAULT and a zero INVALID_P are
+ # specified, POSTDEFAULT will be used as the default for the
+ # non- multi-arch target (regardless of the value of
+ # PREDEFAULT).
+
+ # You cannot specify both a zero INVALID_P and a POSTDEFAULT.
+
+ # Variable declarations can refer to ``gdbarch'' which will
+ # contain the current architecture. Care should be taken.
+
+ invalid_p ) : ;;
+
+ # A predicate equation that validates MEMBER. Non-zero is
+ # returned if the code creating the new architecture failed to
+ # initialize MEMBER or the initialized the member is invalid.
+ # If POSTDEFAULT is non-empty then MEMBER will be updated to
+ # that value. If POSTDEFAULT is empty then internal_error()
+ # is called.
+
+ # If INVALID_P is empty, a check that MEMBER is no longer
+ # equal to PREDEFAULT is used.
+
+ # The expression ``0'' disables the INVALID_P check making
+ # PREDEFAULT a legitimate value.
+
+ # See also PREDEFAULT and POSTDEFAULT.
+
+ fmt ) : ;;
+
+ # printf style format string that can be used to print out the
+ # MEMBER. Sometimes "%s" is useful. For functions, this is
+ # ignored and the function address is printed.
+
+ # If FMT is empty, ``%ld'' is used.
+
+ print ) : ;;
+
+ # An optional equation that casts MEMBER to a value suitable
+ # for formatting by FMT.
+
+ # If PRINT is empty, ``(long)'' is used.
+
+ print_p ) : ;;
+
+ # An optional indicator for any predicte to wrap around the
+ # print member code.
+
+ # () -> Call a custom function to do the dump.
+ # exp -> Wrap print up in ``if (${print_p}) ...
+ # ``'' -> No predicate
+
+ # If PRINT_P is empty, ``1'' is always used.
+
+ description ) : ;;
+
+ # Currently unused.
+
+ *)
+ echo "Bad field ${field}"
+ exit 1;;
+ esac
+done
+
+
+function_list ()
+{
+ # See below (DOCO) for description of each field
+ cat <<EOF
+i:2:TARGET_ARCHITECTURE:const struct bfd_arch_info *:bfd_arch_info::::&bfd_default_arch_struct::::%s:TARGET_ARCHITECTURE->printable_name:TARGET_ARCHITECTURE != NULL
+#
+i:2:TARGET_BYTE_ORDER:int:byte_order::::BFD_ENDIAN_BIG
+# Number of bits in a char or unsigned char for the target machine.
+# Just like CHAR_BIT in <limits.h> but describes the target machine.
+# v::TARGET_CHAR_BIT:int:char_bit::::8 * sizeof (char):8::0:
+#
+# Number of bits in a short or unsigned short for the target machine.
+v::TARGET_SHORT_BIT:int:short_bit::::8 * sizeof (short):2*TARGET_CHAR_BIT::0
+# Number of bits in an int or unsigned int for the target machine.
+v::TARGET_INT_BIT:int:int_bit::::8 * sizeof (int):4*TARGET_CHAR_BIT::0
+# Number of bits in a long or unsigned long for the target machine.
+v::TARGET_LONG_BIT:int:long_bit::::8 * sizeof (long):4*TARGET_CHAR_BIT::0
+# Number of bits in a long long or unsigned long long for the target
+# machine.
+v::TARGET_LONG_LONG_BIT:int:long_long_bit::::8 * sizeof (LONGEST):2*TARGET_LONG_BIT::0
+# Number of bits in a float for the target machine.
+v::TARGET_FLOAT_BIT:int:float_bit::::8 * sizeof (float):4*TARGET_CHAR_BIT::0
+# Number of bits in a double for the target machine.
+v::TARGET_DOUBLE_BIT:int:double_bit::::8 * sizeof (double):8*TARGET_CHAR_BIT::0
+# Number of bits in a long double for the target machine.
+v::TARGET_LONG_DOUBLE_BIT:int:long_double_bit::::8 * sizeof (long double):8*TARGET_CHAR_BIT::0
+# For most targets, a pointer on the target and its representation as an
+# address in GDB have the same size and "look the same". For such a
+# target, you need only set TARGET_PTR_BIT / ptr_bit and TARGET_ADDR_BIT
+# / addr_bit will be set from it.
+#
+# If TARGET_PTR_BIT and TARGET_ADDR_BIT are different, you'll probably
+# also need to set POINTER_TO_ADDRESS and ADDRESS_TO_POINTER as well.
+#
+# ptr_bit is the size of a pointer on the target
+v::TARGET_PTR_BIT:int:ptr_bit::::8 * sizeof (void*):TARGET_INT_BIT::0
+# addr_bit is the size of a target address as represented in gdb
+v::TARGET_ADDR_BIT:int:addr_bit::::8 * sizeof (void*):0:TARGET_PTR_BIT:
+# Number of bits in a BFD_VMA for the target object file format.
+v::TARGET_BFD_VMA_BIT:int:bfd_vma_bit::::8 * sizeof (void*):TARGET_ARCHITECTURE->bits_per_address::0
+#
+# One if \`char' acts like \`signed char', zero if \`unsigned char'.
+v::TARGET_CHAR_SIGNED:int:char_signed::::1:-1:1::::
+#
+f::TARGET_READ_PC:CORE_ADDR:read_pc:ptid_t ptid:ptid::0:generic_target_read_pc::0
+f::TARGET_WRITE_PC:void:write_pc:CORE_ADDR val, ptid_t ptid:val, ptid::0:generic_target_write_pc::0
+f::TARGET_READ_FP:CORE_ADDR:read_fp:void:::0:generic_target_read_fp::0
+f::TARGET_READ_SP:CORE_ADDR:read_sp:void:::0:generic_target_read_sp::0
+f::TARGET_WRITE_SP:void:write_sp:CORE_ADDR val:val::0:generic_target_write_sp::0
+# Function for getting target's idea of a frame pointer. FIXME: GDB's
+# whole scheme for dealing with "frames" and "frame pointers" needs a
+# serious shakedown.
+f::TARGET_VIRTUAL_FRAME_POINTER:void:virtual_frame_pointer:CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset:pc, frame_regnum, frame_offset::0:legacy_virtual_frame_pointer::0
+#
+M:::void:register_read:int regnum, char *buf:regnum, buf:
+M:::void:register_write:int regnum, char *buf:regnum, buf:
+#
+v:2:NUM_REGS:int:num_regs::::0:-1
+# This macro gives the number of pseudo-registers that live in the
+# register namespace but do not get fetched or stored on the target.
+# These pseudo-registers may be aliases for other registers,
+# combinations of other registers, or they may be computed by GDB.
+v:2:NUM_PSEUDO_REGS:int:num_pseudo_regs::::0:0::0:::
+
+# GDB's standard (or well known) register numbers. These can map onto
+# a real register or a pseudo (computed) register or not be defined at
+# all (-1).
+v:2:SP_REGNUM:int:sp_regnum::::-1:-1::0
+v:2:FP_REGNUM:int:fp_regnum::::-1:-1::0
+v:2:PC_REGNUM:int:pc_regnum::::-1:-1::0
+v:2:PS_REGNUM:int:ps_regnum::::-1:-1::0
+v:2:FP0_REGNUM:int:fp0_regnum::::0:-1::0
+v:2:NPC_REGNUM:int:npc_regnum::::0:-1::0
+# Convert stab register number (from \`r\' declaration) to a gdb REGNUM.
+f:2:STAB_REG_TO_REGNUM:int:stab_reg_to_regnum:int stab_regnr:stab_regnr:::no_op_reg_to_regnum::0
+# Provide a default mapping from a ecoff register number to a gdb REGNUM.
+f:2:ECOFF_REG_TO_REGNUM:int:ecoff_reg_to_regnum:int ecoff_regnr:ecoff_regnr:::no_op_reg_to_regnum::0
+# Provide a default mapping from a DWARF register number to a gdb REGNUM.
+f:2:DWARF_REG_TO_REGNUM:int:dwarf_reg_to_regnum:int dwarf_regnr:dwarf_regnr:::no_op_reg_to_regnum::0
+# Convert from an sdb register number to an internal gdb register number.
+# This should be defined in tm.h, if REGISTER_NAMES is not set up
+# to map one to one onto the sdb register numbers.
+f:2:SDB_REG_TO_REGNUM:int:sdb_reg_to_regnum:int sdb_regnr:sdb_regnr:::no_op_reg_to_regnum::0
+f:2:DWARF2_REG_TO_REGNUM:int:dwarf2_reg_to_regnum:int dwarf2_regnr:dwarf2_regnr:::no_op_reg_to_regnum::0
+f:2:REGISTER_NAME:char *:register_name:int regnr:regnr:::legacy_register_name::0
+v:2:REGISTER_SIZE:int:register_size::::0:-1
+v:2:REGISTER_BYTES:int:register_bytes::::0:-1
+f:2:REGISTER_BYTE:int:register_byte:int reg_nr:reg_nr::0:0
+f:2:REGISTER_RAW_SIZE:int:register_raw_size:int reg_nr:reg_nr::generic_register_size:generic_register_size::0
+v:2:MAX_REGISTER_RAW_SIZE:int:max_register_raw_size::::0:-1
+f:2:REGISTER_VIRTUAL_SIZE:int:register_virtual_size:int reg_nr:reg_nr::generic_register_size:generic_register_size::0
+v:2:MAX_REGISTER_VIRTUAL_SIZE:int:max_register_virtual_size::::0:-1
+f:2:REGISTER_VIRTUAL_TYPE:struct type *:register_virtual_type:int reg_nr:reg_nr::0:0
+f:2:DO_REGISTERS_INFO:void:do_registers_info:int reg_nr, int fpregs:reg_nr, fpregs:::do_registers_info::0
+f:2:PRINT_FLOAT_INFO:void:print_float_info:void::::default_print_float_info::0
+# MAP a GDB RAW register number onto a simulator register number. See
+# also include/...-sim.h.
+f:2:REGISTER_SIM_REGNO:int:register_sim_regno:int reg_nr:reg_nr:::default_register_sim_regno::0
+F:2:REGISTER_BYTES_OK:int:register_bytes_ok:long nr_bytes:nr_bytes::0:0
+f:2:CANNOT_FETCH_REGISTER:int:cannot_fetch_register:int regnum:regnum:::cannot_register_not::0
+f:2:CANNOT_STORE_REGISTER:int:cannot_store_register:int regnum:regnum:::cannot_register_not::0
+# setjmp/longjmp support.
+F:2:GET_LONGJMP_TARGET:int:get_longjmp_target:CORE_ADDR *pc:pc::0:0
+#
+# Non multi-arch DUMMY_FRAMES are a mess (multi-arch ones are not that
+# much better but at least they are vaguely consistent). The headers
+# and body contain convoluted #if/#else sequences for determine how
+# things should be compiled. Instead of trying to mimic that
+# behaviour here (and hence entrench it further) gdbarch simply
+# reqires that these methods be set up from the word go. This also
+# avoids any potential problems with moving beyond multi-arch partial.
+v:1:USE_GENERIC_DUMMY_FRAMES:int:use_generic_dummy_frames::::0:-1
+v:1:CALL_DUMMY_LOCATION:int:call_dummy_location::::0:0
+f:2:CALL_DUMMY_ADDRESS:CORE_ADDR:call_dummy_address:void:::0:0::gdbarch->call_dummy_location == AT_ENTRY_POINT && gdbarch->call_dummy_address == 0
+v:2:CALL_DUMMY_START_OFFSET:CORE_ADDR:call_dummy_start_offset::::0:-1:::0x%08lx
+v:2:CALL_DUMMY_BREAKPOINT_OFFSET:CORE_ADDR:call_dummy_breakpoint_offset::::0:-1::gdbarch->call_dummy_breakpoint_offset_p && gdbarch->call_dummy_breakpoint_offset == -1:0x%08lx::CALL_DUMMY_BREAKPOINT_OFFSET_P
+v:1:CALL_DUMMY_BREAKPOINT_OFFSET_P:int:call_dummy_breakpoint_offset_p::::0:-1
+v:2:CALL_DUMMY_LENGTH:int:call_dummy_length::::0:-1:::::CALL_DUMMY_LOCATION == BEFORE_TEXT_END || CALL_DUMMY_LOCATION == AFTER_TEXT_END
+f:1:PC_IN_CALL_DUMMY:int:pc_in_call_dummy:CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address:pc, sp, frame_address::0:0
+v:1:CALL_DUMMY_P:int:call_dummy_p::::0:-1
+v:2:CALL_DUMMY_WORDS:LONGEST *:call_dummy_words::::0:legacy_call_dummy_words::0:0x%08lx
+v:2:SIZEOF_CALL_DUMMY_WORDS:int:sizeof_call_dummy_words::::0:legacy_sizeof_call_dummy_words::0:0x%08lx
+v:1:CALL_DUMMY_STACK_ADJUST_P:int:call_dummy_stack_adjust_p::::0:-1:::0x%08lx
+v:2:CALL_DUMMY_STACK_ADJUST:int:call_dummy_stack_adjust::::0:::gdbarch->call_dummy_stack_adjust_p && gdbarch->call_dummy_stack_adjust == 0:0x%08lx::CALL_DUMMY_STACK_ADJUST_P
+f:2:FIX_CALL_DUMMY:void:fix_call_dummy:char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, struct value **args, struct type *type, int gcc_p:dummy, pc, fun, nargs, args, type, gcc_p:::0
+f:2:INIT_FRAME_PC_FIRST:void:init_frame_pc_first:int fromleaf, struct frame_info *prev:fromleaf, prev:::init_frame_pc_noop::0
+f:2:INIT_FRAME_PC:void:init_frame_pc:int fromleaf, struct frame_info *prev:fromleaf, prev:::init_frame_pc_default::0
+#
+v:2:BELIEVE_PCC_PROMOTION:int:believe_pcc_promotion:::::::
+v:2:BELIEVE_PCC_PROMOTION_TYPE:int:believe_pcc_promotion_type:::::::
+f:2:COERCE_FLOAT_TO_DOUBLE:int:coerce_float_to_double:struct type *formal, struct type *actual:formal, actual:::default_coerce_float_to_double::0
+# GET_SAVED_REGISTER is like DUMMY_FRAMES. It is at level one as the
+# old code has strange #ifdef interaction. So far no one has found
+# that default_get_saved_register() is the default they are after.
+f:1:GET_SAVED_REGISTER:void:get_saved_register:char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval:raw_buffer, optimized, addrp, frame, regnum, lval::generic_get_saved_register:0
+#
+f:2:REGISTER_CONVERTIBLE:int:register_convertible:int nr:nr:::generic_register_convertible_not::0
+f:2:REGISTER_CONVERT_TO_VIRTUAL:void:register_convert_to_virtual:int regnum, struct type *type, char *from, char *to:regnum, type, from, to:::0::0
+f:2:REGISTER_CONVERT_TO_RAW:void:register_convert_to_raw:struct type *type, int regnum, char *from, char *to:type, regnum, from, to:::0::0
+#
+f:1:CONVERT_REGISTER_P:int:convert_register_p:int regnum:regnum::0:legacy_convert_register_p::0
+f:1:REGISTER_TO_VALUE:void:register_to_value:int regnum, struct type *type, char *from, char *to:regnum, type, from, to::0:legacy_register_to_value::0
+f:1:VALUE_TO_REGISTER:void:value_to_register:struct type *type, int regnum, char *from, char *to:type, regnum, from, to::0:legacy_value_to_register::0
+# This function is called when the value of a pseudo-register needs to
+# be updated. Typically it will be defined on a per-architecture
+# basis.
+F:2:FETCH_PSEUDO_REGISTER:void:fetch_pseudo_register:int regnum:regnum:
+# This function is called when the value of a pseudo-register needs to
+# be set or stored. Typically it will be defined on a
+# per-architecture basis.
+F:2:STORE_PSEUDO_REGISTER:void:store_pseudo_register:int regnum:regnum:
+#
+f:2:POINTER_TO_ADDRESS:CORE_ADDR:pointer_to_address:struct type *type, void *buf:type, buf:::unsigned_pointer_to_address::0
+f:2:ADDRESS_TO_POINTER:void:address_to_pointer:struct type *type, void *buf, CORE_ADDR addr:type, buf, addr:::unsigned_address_to_pointer::0
+F:2:INTEGER_TO_ADDRESS:CORE_ADDR:integer_to_address:struct type *type, void *buf:type, buf
+#
+f:2:RETURN_VALUE_ON_STACK:int:return_value_on_stack:struct type *type:type:::generic_return_value_on_stack_not::0
+f:2:EXTRACT_RETURN_VALUE:void:extract_return_value:struct type *type, char *regbuf, char *valbuf:type, regbuf, valbuf::0:0
+f:2:PUSH_ARGUMENTS:CORE_ADDR:push_arguments:int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr:nargs, args, sp, struct_return, struct_addr:::default_push_arguments::0
+f:2:PUSH_DUMMY_FRAME:void:push_dummy_frame:void:-:::0
+F:2:PUSH_RETURN_ADDRESS:CORE_ADDR:push_return_address:CORE_ADDR pc, CORE_ADDR sp:pc, sp:::0
+f:2:POP_FRAME:void:pop_frame:void:-:::0
+#
+f:2:STORE_STRUCT_RETURN:void:store_struct_return:CORE_ADDR addr, CORE_ADDR sp:addr, sp:::0
+f:2:STORE_RETURN_VALUE:void:store_return_value:struct type *type, char *valbuf:type, valbuf:::0
+F:2:EXTRACT_STRUCT_VALUE_ADDRESS:CORE_ADDR:extract_struct_value_address:char *regbuf:regbuf:::0
+f:2:USE_STRUCT_CONVENTION:int:use_struct_convention:int gcc_p, struct type *value_type:gcc_p, value_type:::generic_use_struct_convention::0
+#
+f:2:FRAME_INIT_SAVED_REGS:void:frame_init_saved_regs:struct frame_info *frame:frame::0:0
+F:2:INIT_EXTRA_FRAME_INFO:void:init_extra_frame_info:int fromleaf, struct frame_info *frame:fromleaf, frame:::0
+#
+f:2:SKIP_PROLOGUE:CORE_ADDR:skip_prologue:CORE_ADDR ip:ip::0:0
+f:2:PROLOGUE_FRAMELESS_P:int:prologue_frameless_p:CORE_ADDR ip:ip::0:generic_prologue_frameless_p::0
+f:2:INNER_THAN:int:inner_than:CORE_ADDR lhs, CORE_ADDR rhs:lhs, rhs::0:0
+f:2:BREAKPOINT_FROM_PC:const unsigned char *:breakpoint_from_pc:CORE_ADDR *pcptr, int *lenptr:pcptr, lenptr:::legacy_breakpoint_from_pc::0
+f:2:MEMORY_INSERT_BREAKPOINT:int:memory_insert_breakpoint:CORE_ADDR addr, char *contents_cache:addr, contents_cache::0:default_memory_insert_breakpoint::0
+f:2:MEMORY_REMOVE_BREAKPOINT:int:memory_remove_breakpoint:CORE_ADDR addr, char *contents_cache:addr, contents_cache::0:default_memory_remove_breakpoint::0
+v:2:DECR_PC_AFTER_BREAK:CORE_ADDR:decr_pc_after_break::::0:-1
+f::PREPARE_TO_PROCEED:int:prepare_to_proceed:int select_it:select_it::0:default_prepare_to_proceed::0
+v:2:FUNCTION_START_OFFSET:CORE_ADDR:function_start_offset::::0:-1
+#
+f:2:REMOTE_TRANSLATE_XFER_ADDRESS:void:remote_translate_xfer_address:CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR *rem_addr, int *rem_len:gdb_addr, gdb_len, rem_addr, rem_len:::generic_remote_translate_xfer_address::0
+#
+v:2:FRAME_ARGS_SKIP:CORE_ADDR:frame_args_skip::::0:-1
+f:2:FRAMELESS_FUNCTION_INVOCATION:int:frameless_function_invocation:struct frame_info *fi:fi:::generic_frameless_function_invocation_not::0
+f:2:FRAME_CHAIN:CORE_ADDR:frame_chain:struct frame_info *frame:frame::0:0
+# Define a default FRAME_CHAIN_VALID, in the form that is suitable for
+# most targets. If FRAME_CHAIN_VALID returns zero it means that the
+# given frame is the outermost one and has no caller.
+#
+# XXXX - both default and alternate frame_chain_valid functions are
+# deprecated. New code should use dummy frames and one of the generic
+# functions.
+f:2:FRAME_CHAIN_VALID:int:frame_chain_valid:CORE_ADDR chain, struct frame_info *thisframe:chain, thisframe:::func_frame_chain_valid::0
+f:2:FRAME_SAVED_PC:CORE_ADDR:frame_saved_pc:struct frame_info *fi:fi::0:0
+f:2:FRAME_ARGS_ADDRESS:CORE_ADDR:frame_args_address:struct frame_info *fi:fi::0:0
+f:2:FRAME_LOCALS_ADDRESS:CORE_ADDR:frame_locals_address:struct frame_info *fi:fi::0:0
+f:2:SAVED_PC_AFTER_CALL:CORE_ADDR:saved_pc_after_call:struct frame_info *frame:frame::0:0
+f:2:FRAME_NUM_ARGS:int:frame_num_args:struct frame_info *frame:frame::0:0
+#
+F:2:STACK_ALIGN:CORE_ADDR:stack_align:CORE_ADDR sp:sp::0:0
+v:2:EXTRA_STACK_ALIGNMENT_NEEDED:int:extra_stack_alignment_needed::::0:1::0:::
+F:2:REG_STRUCT_HAS_ADDR:int:reg_struct_has_addr:int gcc_p, struct type *type:gcc_p, type::0:0
+F:2:SAVE_DUMMY_FRAME_TOS:void:save_dummy_frame_tos:CORE_ADDR sp:sp::0:0
+v:2:PARM_BOUNDARY:int:parm_boundary
+#
+v:2:TARGET_FLOAT_FORMAT:const struct floatformat *:float_format::::::default_float_format (gdbarch)
+v:2:TARGET_DOUBLE_FORMAT:const struct floatformat *:double_format::::::default_double_format (gdbarch)
+v:2:TARGET_LONG_DOUBLE_FORMAT:const struct floatformat *:long_double_format::::::default_double_format (gdbarch)
+f:2:CONVERT_FROM_FUNC_PTR_ADDR:CORE_ADDR:convert_from_func_ptr_addr:CORE_ADDR addr:addr:::core_addr_identity::0
+# On some machines there are bits in addresses which are not really
+# part of the address, but are used by the kernel, the hardware, etc.
+# for special purposes. ADDR_BITS_REMOVE takes out any such bits so
+# we get a "real" address such as one would find in a symbol table.
+# This is used only for addresses of instructions, and even then I'm
+# not sure it's used in all contexts. It exists to deal with there
+# being a few stray bits in the PC which would mislead us, not as some
+# sort of generic thing to handle alignment or segmentation (it's
+# possible it should be in TARGET_READ_PC instead).
+f:2:ADDR_BITS_REMOVE:CORE_ADDR:addr_bits_remove:CORE_ADDR addr:addr:::core_addr_identity::0
+# It is not at all clear why SMASH_TEXT_ADDRESS is not folded into
+# ADDR_BITS_REMOVE.
+f:2:SMASH_TEXT_ADDRESS:CORE_ADDR:smash_text_address:CORE_ADDR addr:addr:::core_addr_identity::0
+# FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if
+# the target needs software single step. An ISA method to implement it.
+#
+# FIXME/cagney/2001-01-18: This should be replaced with something that inserts breakpoints
+# using the breakpoint system instead of blatting memory directly (as with rs6000).
+#
+# FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the target can
+# single step. If not, then implement single step using breakpoints.
+F:2:SOFTWARE_SINGLE_STEP:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p::0:0
+f:2:TARGET_PRINT_INSN:int:print_insn:bfd_vma vma, disassemble_info *info:vma, info:::legacy_print_insn::0
+f:2:SKIP_TRAMPOLINE_CODE:CORE_ADDR:skip_trampoline_code:CORE_ADDR pc:pc:::generic_skip_trampoline_code::0
+# For SVR4 shared libraries, each call goes through a small piece of
+# trampoline code in the ".plt" section. IN_SOLIB_CALL_TRAMPOLINE evaluates
+# to nonzero if we are current stopped in one of these.
+f:2:IN_SOLIB_CALL_TRAMPOLINE:int:in_solib_call_trampoline:CORE_ADDR pc, char *name:pc, name:::generic_in_solib_call_trampoline::0
+# Sigtramp is a routine that the kernel calls (which then calls the
+# signal handler). On most machines it is a library routine that is
+# linked into the executable.
+#
+# This macro, given a program counter value and the name of the
+# function in which that PC resides (which can be null if the name is
+# not known), returns nonzero if the PC and name show that we are in
+# sigtramp.
+#
+# On most machines just see if the name is sigtramp (and if we have
+# no name, assume we are not in sigtramp).
+#
+# FIXME: cagney/2002-04-21: The function find_pc_partial_function
+# calls find_pc_sect_partial_function() which calls PC_IN_SIGTRAMP.
+# This means PC_IN_SIGTRAMP function can't be implemented by doing its
+# own local NAME lookup.
+#
+# FIXME: cagney/2002-04-21: PC_IN_SIGTRAMP is something of a mess.
+# Some code also depends on SIGTRAMP_START and SIGTRAMP_END but other
+# does not.
+f:2:PC_IN_SIGTRAMP:int:pc_in_sigtramp:CORE_ADDR pc, char *name:pc, name:::legacy_pc_in_sigtramp::0
+# A target might have problems with watchpoints as soon as the stack
+# frame of the current function has been destroyed. This mostly happens
+# as the first action in a funtion's epilogue. in_function_epilogue_p()
+# is defined to return a non-zero value if either the given addr is one
+# instruction after the stack destroying instruction up to the trailing
+# return instruction or if we can figure out that the stack frame has
+# already been invalidated regardless of the value of addr. Targets
+# which don't suffer from that problem could just let this functionality
+# untouched.
+m:::int:in_function_epilogue_p:CORE_ADDR addr:addr::0:generic_in_function_epilogue_p::0
+# Given a vector of command-line arguments, return a newly allocated
+# string which, when passed to the create_inferior function, will be
+# parsed (on Unix systems, by the shell) to yield the same vector.
+# This function should call error() if the argument vector is not
+# representable for this target or if this target does not support
+# command-line arguments.
+# ARGC is the number of elements in the vector.
+# ARGV is an array of strings, one per argument.
+m::CONSTRUCT_INFERIOR_ARGUMENTS:char *:construct_inferior_arguments:int argc, char **argv:argc, argv:::construct_inferior_arguments::0
+F:2:DWARF2_BUILD_FRAME_INFO:void:dwarf2_build_frame_info:struct objfile *objfile:objfile:::0
+f:2:ELF_MAKE_MSYMBOL_SPECIAL:void:elf_make_msymbol_special:asymbol *sym, struct minimal_symbol *msym:sym, msym:::default_elf_make_msymbol_special::0
+f:2:COFF_MAKE_MSYMBOL_SPECIAL:void:coff_make_msymbol_special:int val, struct minimal_symbol *msym:val, msym:::default_coff_make_msymbol_special::0
+EOF
+}
+
+#
+# The .log file
+#
+exec > new-gdbarch.log
+function_list | while do_read
+do
+ cat <<EOF
+${class} ${macro}(${actual})
+ ${returntype} ${function} ($formal)${attrib}
+EOF
+ for r in ${read}
+ do
+ eval echo \"\ \ \ \ ${r}=\${${r}}\"
+ done
+# #fallbackdefault=${fallbackdefault}
+# #valid_p=${valid_p}
+#EOF
+ if class_is_predicate_p && fallback_default_p
+ then
+ echo "Error: predicate function ${macro} can not have a non- multi-arch default" 1>&2
+ kill $$
+ exit 1
+ fi
+ if [ "x${invalid_p}" = "x0" -a -n "${postdefault}" ]
+ then
+ echo "Error: postdefault is useless when invalid_p=0" 1>&2
+ kill $$
+ exit 1
+ fi
+ if class_is_multiarch_p
+ then
+ if class_is_predicate_p ; then :
+ elif test "x${predefault}" = "x"
+ then
+ echo "Error: pure multi-arch function must have a predefault" 1>&2
+ kill $$
+ exit 1
+ fi
+ fi
+ echo ""
+done
+
+exec 1>&2
+compare_new gdbarch.log
+
+
+copyright ()
+{
+cat <<EOF
+/* *INDENT-OFF* */ /* THIS FILE IS GENERATED */
+
+/* Dynamic architecture support for GDB, the GNU debugger.
+ Copyright 1998, 1999, 2000, 2001, 2002 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. */
+
+/* This file was created with the aid of \`\`gdbarch.sh''.
+
+ The Bourne shell script \`\`gdbarch.sh'' creates the files
+ \`\`new-gdbarch.c'' and \`\`new-gdbarch.h and then compares them
+ against the existing \`\`gdbarch.[hc]''. Any differences found
+ being reported.
+
+ If editing this file, please also run gdbarch.sh and merge any
+ changes into that script. Conversely, when making sweeping changes
+ to this file, modifying gdbarch.sh and using its output may prove
+ easier. */
+
+EOF
+}
+
+#
+# The .h file
+#
+
+exec > new-gdbarch.h
+copyright
+cat <<EOF
+#ifndef GDBARCH_H
+#define GDBARCH_H
+
+#include "dis-asm.h" /* Get defs for disassemble_info, which unfortunately is a typedef. */
+#if !GDB_MULTI_ARCH
+/* Pull in function declarations refered to, indirectly, via macros. */
+#include "value.h" /* For default_coerce_float_to_double which is referenced by a macro. */
+#include "inferior.h" /* For unsigned_address_to_pointer(). */
+#endif
+
+struct frame_info;
+struct value;
+struct objfile;
+struct minimal_symbol;
+
+extern struct gdbarch *current_gdbarch;
+
+
+/* If any of the following are defined, the target wasn't correctly
+ converted. */
+
+#if GDB_MULTI_ARCH
+#if defined (EXTRA_FRAME_INFO)
+#error "EXTRA_FRAME_INFO: replaced by struct frame_extra_info"
+#endif
+#endif
+
+#if GDB_MULTI_ARCH
+#if defined (FRAME_FIND_SAVED_REGS)
+#error "FRAME_FIND_SAVED_REGS: replaced by FRAME_INIT_SAVED_REGS"
+#endif
+#endif
+
+#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PURE) && defined (GDB_TM_FILE)
+#error "GDB_TM_FILE: Pure multi-arch targets do not have a tm.h file."
+#endif
+EOF
+
+# function typedef's
+printf "\n"
+printf "\n"
+printf "/* The following are pre-initialized by GDBARCH. */\n"
+function_list | while do_read
+do
+ if class_is_info_p
+ then
+ printf "\n"
+ printf "extern ${returntype} gdbarch_${function} (struct gdbarch *gdbarch);\n"
+ printf "/* set_gdbarch_${function}() - not applicable - pre-initialized. */\n"
+ printf "#if (GDB_MULTI_ARCH ${gt_level}) && defined (${macro})\n"
+ printf "#error \"Non multi-arch definition of ${macro}\"\n"
+ printf "#endif\n"
+ printf "#if GDB_MULTI_ARCH\n"
+ printf "#if (GDB_MULTI_ARCH ${gt_level}) || !defined (${macro})\n"
+ printf "#define ${macro} (gdbarch_${function} (current_gdbarch))\n"
+ printf "#endif\n"
+ printf "#endif\n"
+ fi
+done
+
+# function typedef's
+printf "\n"
+printf "\n"
+printf "/* The following are initialized by the target dependent code. */\n"
+function_list | while do_read
+do
+ if [ -n "${comment}" ]
+ then
+ echo "${comment}" | sed \
+ -e '2 s,#,/*,' \
+ -e '3,$ s,#, ,' \
+ -e '$ s,$, */,'
+ fi
+ if class_is_multiarch_p
+ then
+ if class_is_predicate_p
+ then
+ printf "\n"
+ printf "extern int gdbarch_${function}_p (struct gdbarch *gdbarch);\n"
+ fi
+ else
+ if class_is_predicate_p
+ then
+ printf "\n"
+ printf "#if defined (${macro})\n"
+ printf "/* Legacy for systems yet to multi-arch ${macro} */\n"
+ #printf "#if (GDB_MULTI_ARCH <= GDB_MULTI_ARCH_PARTIAL) && defined (${macro})\n"
+ printf "#if !defined (${macro}_P)\n"
+ printf "#define ${macro}_P() (1)\n"
+ printf "#endif\n"
+ printf "#endif\n"
+ printf "\n"
+ printf "/* Default predicate for non- multi-arch targets. */\n"
+ printf "#if (!GDB_MULTI_ARCH) && !defined (${macro}_P)\n"
+ printf "#define ${macro}_P() (0)\n"
+ printf "#endif\n"
+ printf "\n"
+ printf "extern int gdbarch_${function}_p (struct gdbarch *gdbarch);\n"
+ printf "#if (GDB_MULTI_ARCH ${gt_level}) && defined (${macro}_P)\n"
+ printf "#error \"Non multi-arch definition of ${macro}\"\n"
+ printf "#endif\n"
+ printf "#if (GDB_MULTI_ARCH ${gt_level}) || !defined (${macro}_P)\n"
+ printf "#define ${macro}_P() (gdbarch_${function}_p (current_gdbarch))\n"
+ printf "#endif\n"
+ fi
+ fi
+ if class_is_variable_p
+ then
+ if fallback_default_p || class_is_predicate_p
+ then
+ printf "\n"
+ printf "/* Default (value) for non- multi-arch platforms. */\n"
+ printf "#if (!GDB_MULTI_ARCH) && !defined (${macro})\n"
+ echo "#define ${macro} (${fallbackdefault})" \
+ | sed -e 's/\([^a-z_]\)\(gdbarch[^a-z_]\)/\1current_\2/g'
+ printf "#endif\n"
+ fi
+ printf "\n"
+ printf "extern ${returntype} gdbarch_${function} (struct gdbarch *gdbarch);\n"
+ printf "extern void set_gdbarch_${function} (struct gdbarch *gdbarch, ${returntype} ${function});\n"
+ printf "#if (GDB_MULTI_ARCH ${gt_level}) && defined (${macro})\n"
+ printf "#error \"Non multi-arch definition of ${macro}\"\n"
+ printf "#endif\n"
+ printf "#if GDB_MULTI_ARCH\n"
+ printf "#if (GDB_MULTI_ARCH ${gt_level}) || !defined (${macro})\n"
+ printf "#define ${macro} (gdbarch_${function} (current_gdbarch))\n"
+ printf "#endif\n"
+ printf "#endif\n"
+ fi
+ if class_is_function_p
+ then
+ if class_is_multiarch_p ; then :
+ elif fallback_default_p || class_is_predicate_p
+ then
+ printf "\n"
+ printf "/* Default (function) for non- multi-arch platforms. */\n"
+ printf "#if (!GDB_MULTI_ARCH) && !defined (${macro})\n"
+ if [ "x${fallbackdefault}" = "x0" ]
+ then
+ printf "#define ${macro}(${actual}) (internal_error (__FILE__, __LINE__, \"${macro}\"), 0)\n"
+ else
+ # FIXME: Should be passing current_gdbarch through!
+ echo "#define ${macro}(${actual}) (${fallbackdefault} (${actual}))" \
+ | sed -e 's/\([^a-z_]\)\(gdbarch[^a-z_]\)/\1current_\2/g'
+ fi
+ printf "#endif\n"
+ fi
+ printf "\n"
+ if [ "x${formal}" = "xvoid" ] && class_is_multiarch_p
+ then
+ printf "typedef ${returntype} (gdbarch_${function}_ftype) (struct gdbarch *gdbarch);\n"
+ elif class_is_multiarch_p
+ then
+ printf "typedef ${returntype} (gdbarch_${function}_ftype) (struct gdbarch *gdbarch, ${formal});\n"
+ else
+ printf "typedef ${returntype} (gdbarch_${function}_ftype) (${formal});\n"
+ fi
+ if [ "x${formal}" = "xvoid" ]
+ then
+ printf "extern ${returntype} gdbarch_${function} (struct gdbarch *gdbarch);\n"
+ else
+ printf "extern ${returntype} gdbarch_${function} (struct gdbarch *gdbarch, ${formal});\n"
+ fi
+ printf "extern void set_gdbarch_${function} (struct gdbarch *gdbarch, gdbarch_${function}_ftype *${function});\n"
+ if class_is_multiarch_p ; then :
+ else
+ printf "#if (GDB_MULTI_ARCH ${gt_level}) && defined (${macro})\n"
+ printf "#error \"Non multi-arch definition of ${macro}\"\n"
+ printf "#endif\n"
+ printf "#if GDB_MULTI_ARCH\n"
+ printf "#if (GDB_MULTI_ARCH ${gt_level}) || !defined (${macro})\n"
+ if [ "x${actual}" = "x" ]
+ then
+ printf "#define ${macro}() (gdbarch_${function} (current_gdbarch))\n"
+ elif [ "x${actual}" = "x-" ]
+ then
+ printf "#define ${macro} (gdbarch_${function} (current_gdbarch))\n"
+ else
+ printf "#define ${macro}(${actual}) (gdbarch_${function} (current_gdbarch, ${actual}))\n"
+ fi
+ printf "#endif\n"
+ printf "#endif\n"
+ fi
+ fi
+done
+
+# close it off
+cat <<EOF
+
+extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
+
+
+/* Mechanism for co-ordinating the selection of a specific
+ architecture.
+
+ GDB targets (*-tdep.c) can register an interest in a specific
+ architecture. Other GDB components can register a need to maintain
+ per-architecture data.
+
+ The mechanisms below ensures that there is only a loose connection
+ between the set-architecture command and the various GDB
+ components. Each component can independently register their need
+ to maintain architecture specific data with gdbarch.
+
+ Pragmatics:
+
+ Previously, a single TARGET_ARCHITECTURE_HOOK was provided. It
+ didn't scale.
+
+ The more traditional mega-struct containing architecture specific
+ data for all the various GDB components was also considered. Since
+ GDB is built from a variable number of (fairly independent)
+ components it was determined that the global aproach was not
+ applicable. */
+
+
+/* Register a new architectural family with GDB.
+
+ Register support for the specified ARCHITECTURE with GDB. When
+ gdbarch determines that the specified architecture has been
+ selected, the corresponding INIT function is called.
+
+ --
+
+ The INIT function takes two parameters: INFO which contains the
+ information available to gdbarch about the (possibly new)
+ architecture; ARCHES which is a list of the previously created
+ \`\`struct gdbarch'' for this architecture.
+
+ The INFO parameter is, as far as possible, be pre-initialized with
+ information obtained from INFO.ABFD or the previously selected
+ architecture.
+
+ The ARCHES parameter is a linked list (sorted most recently used)
+ of all the previously created architures for this architecture
+ family. The (possibly NULL) ARCHES->gdbarch can used to access
+ values from the previously selected architecture for this
+ architecture family. The global \`\`current_gdbarch'' shall not be
+ used.
+
+ The INIT function shall return any of: NULL - indicating that it
+ doesn't recognize the selected architecture; an existing \`\`struct
+ gdbarch'' from the ARCHES list - indicating that the new
+ architecture is just a synonym for an earlier architecture (see
+ gdbarch_list_lookup_by_info()); a newly created \`\`struct gdbarch''
+ - that describes the selected architecture (see gdbarch_alloc()).
+
+ The DUMP_TDEP function shall print out all target specific values.
+ Care should be taken to ensure that the function works in both the
+ multi-arch and non- multi-arch cases. */
+
+struct gdbarch_list
+{
+ struct gdbarch *gdbarch;
+ struct gdbarch_list *next;
+};
+
+struct gdbarch_info
+{
+ /* Use default: NULL (ZERO). */
+ const struct bfd_arch_info *bfd_arch_info;
+
+ /* Use default: BFD_ENDIAN_UNKNOWN (NB: is not ZERO). */
+ int byte_order;
+
+ /* Use default: NULL (ZERO). */
+ bfd *abfd;
+
+ /* Use default: NULL (ZERO). */
+ struct gdbarch_tdep_info *tdep_info;
+};
+
+typedef struct gdbarch *(gdbarch_init_ftype) (struct gdbarch_info info, struct gdbarch_list *arches);
+typedef void (gdbarch_dump_tdep_ftype) (struct gdbarch *gdbarch, struct ui_file *file);
+
+/* DEPRECATED - use gdbarch_register() */
+extern void register_gdbarch_init (enum bfd_architecture architecture, gdbarch_init_ftype *);
+
+extern void gdbarch_register (enum bfd_architecture architecture,
+ gdbarch_init_ftype *,
+ gdbarch_dump_tdep_ftype *);
+
+
+/* Return a freshly allocated, NULL terminated, array of the valid
+ architecture names. Since architectures are registered during the
+ _initialize phase this function only returns useful information
+ once initialization has been completed. */
+
+extern const char **gdbarch_printable_names (void);
+
+
+/* Helper function. Search the list of ARCHES for a GDBARCH that
+ matches the information provided by INFO. */
+
+extern struct gdbarch_list *gdbarch_list_lookup_by_info (struct gdbarch_list *arches, const struct gdbarch_info *info);
+
+
+/* Helper function. Create a preliminary \`\`struct gdbarch''. Perform
+ basic initialization using values obtained from the INFO andTDEP
+ parameters. set_gdbarch_*() functions are called to complete the
+ initialization of the object. */
+
+extern struct gdbarch *gdbarch_alloc (const struct gdbarch_info *info, struct gdbarch_tdep *tdep);
+
+
+/* Helper function. Free a partially-constructed \`\`struct gdbarch''.
+ It is assumed that the caller freeds the \`\`struct
+ gdbarch_tdep''. */
+
+extern void gdbarch_free (struct gdbarch *);
+
+
+/* Helper function. Force an update of the current architecture.
+
+ The actual architecture selected is determined by INFO, \`\`(gdb) set
+ architecture'' et.al., the existing architecture and BFD's default
+ architecture. INFO should be initialized to zero and then selected
+ fields should be updated.
+
+ Returns non-zero if the update succeeds */
+
+extern int gdbarch_update_p (struct gdbarch_info info);
+
+
+
+/* Register per-architecture data-pointer.
+
+ Reserve space for a per-architecture data-pointer. An identifier
+ for the reserved data-pointer is returned. That identifer should
+ be saved in a local static variable.
+
+ The per-architecture data-pointer can be initialized in one of two
+ ways: The value can be set explicitly using a call to
+ set_gdbarch_data(); the value can be set implicitly using the value
+ returned by a non-NULL INIT() callback. INIT(), when non-NULL is
+ called after the basic architecture vector has been created.
+
+ When a previously created architecture is re-selected, the
+ per-architecture data-pointer for that previous architecture is
+ restored. INIT() is not called.
+
+ During initialization, multiple assignments of the data-pointer are
+ allowed, non-NULL values are deleted by calling FREE(). If the
+ architecture is deleted using gdbarch_free() all non-NULL data
+ pointers are also deleted using FREE().
+
+ Multiple registrarants for any architecture are allowed (and
+ strongly encouraged). */
+
+struct gdbarch_data;
+
+typedef void *(gdbarch_data_init_ftype) (struct gdbarch *gdbarch);
+typedef void (gdbarch_data_free_ftype) (struct gdbarch *gdbarch,
+ void *pointer);
+extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype *init,
+ gdbarch_data_free_ftype *free);
+extern void set_gdbarch_data (struct gdbarch *gdbarch,
+ struct gdbarch_data *data,
+ void *pointer);
+
+extern void *gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *);
+
+
+/* Register per-architecture memory region.
+
+ Provide a memory-region swap mechanism. Per-architecture memory
+ region are created. These memory regions are swapped whenever the
+ architecture is changed. For a new architecture, the memory region
+ is initialized with zero (0) and the INIT function is called.
+
+ Memory regions are swapped / initialized in the order that they are
+ registered. NULL DATA and/or INIT values can be specified.
+
+ New code should use register_gdbarch_data(). */
+
+typedef void (gdbarch_swap_ftype) (void);
+extern void register_gdbarch_swap (void *data, unsigned long size, gdbarch_swap_ftype *init);
+#define REGISTER_GDBARCH_SWAP(VAR) register_gdbarch_swap (&(VAR), sizeof ((VAR)), NULL)
+
+
+
+/* The target-system-dependent byte order is dynamic */
+
+extern int target_byte_order;
+#ifndef TARGET_BYTE_ORDER
+#define TARGET_BYTE_ORDER (target_byte_order + 0)
+#endif
+
+extern int target_byte_order_auto;
+#ifndef TARGET_BYTE_ORDER_AUTO
+#define TARGET_BYTE_ORDER_AUTO (target_byte_order_auto + 0)
+#endif
+
+
+
+/* The target-system-dependent BFD architecture is dynamic */
+
+extern int target_architecture_auto;
+#ifndef TARGET_ARCHITECTURE_AUTO
+#define TARGET_ARCHITECTURE_AUTO (target_architecture_auto + 0)
+#endif
+
+extern const struct bfd_arch_info *target_architecture;
+#ifndef TARGET_ARCHITECTURE
+#define TARGET_ARCHITECTURE (target_architecture + 0)
+#endif
+
+
+/* The target-system-dependent disassembler is semi-dynamic */
+
+extern int dis_asm_read_memory (bfd_vma memaddr, bfd_byte *myaddr,
+ unsigned int len, disassemble_info *info);
+
+extern void dis_asm_memory_error (int status, bfd_vma memaddr,
+ disassemble_info *info);
+
+extern void dis_asm_print_address (bfd_vma addr,
+ disassemble_info *info);
+
+extern int (*tm_print_insn) (bfd_vma, disassemble_info*);
+extern disassemble_info tm_print_insn_info;
+#ifndef TARGET_PRINT_INSN_INFO
+#define TARGET_PRINT_INSN_INFO (&tm_print_insn_info)
+#endif
+
+
+
+/* Set the dynamic target-system-dependent parameters (architecture,
+ byte-order, ...) using information found in the BFD */
+
+extern void set_gdbarch_from_file (bfd *);
+
+
+/* Initialize the current architecture to the "first" one we find on
+ our list. */
+
+extern void initialize_current_architecture (void);
+
+/* For non-multiarched targets, do any initialization of the default
+ gdbarch object necessary after the _initialize_MODULE functions
+ have run. */
+extern void initialize_non_multiarch ();
+
+/* gdbarch trace variable */
+extern int gdbarch_debug;
+
+extern void gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file);
+
+#endif
+EOF
+exec 1>&2
+#../move-if-change new-gdbarch.h gdbarch.h
+compare_new gdbarch.h
+
+
+#
+# C file
+#
+
+exec > new-gdbarch.c
+copyright
+cat <<EOF
+
+#include "defs.h"
+#include "arch-utils.h"
+
+#if GDB_MULTI_ARCH
+#include "gdbcmd.h"
+#include "inferior.h" /* enum CALL_DUMMY_LOCATION et.al. */
+#else
+/* Just include everything in sight so that the every old definition
+ of macro is visible. */
+#include "gdb_string.h"
+#include <ctype.h>
+#include "symtab.h"
+#include "frame.h"
+#include "inferior.h"
+#include "breakpoint.h"
+#include "gdb_wait.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "gdbthread.h"
+#include "annotate.h"
+#include "symfile.h" /* for overlay functions */
+#include "value.h" /* For old tm.h/nm.h macros. */
+#endif
+#include "symcat.h"
+
+#include "floatformat.h"
+
+#include "gdb_assert.h"
+#include "gdb-events.h"
+
+/* Static function declarations */
+
+static void verify_gdbarch (struct gdbarch *gdbarch);
+static void alloc_gdbarch_data (struct gdbarch *);
+static void init_gdbarch_data (struct gdbarch *);
+static void free_gdbarch_data (struct gdbarch *);
+static void init_gdbarch_swap (struct gdbarch *);
+static void clear_gdbarch_swap (struct gdbarch *);
+static void swapout_gdbarch_swap (struct gdbarch *);
+static void swapin_gdbarch_swap (struct gdbarch *);
+
+/* Non-zero if we want to trace architecture code. */
+
+#ifndef GDBARCH_DEBUG
+#define GDBARCH_DEBUG 0
+#endif
+int gdbarch_debug = GDBARCH_DEBUG;
+
+EOF
+
+# gdbarch open the gdbarch object
+printf "\n"
+printf "/* Maintain the struct gdbarch object */\n"
+printf "\n"
+printf "struct gdbarch\n"
+printf "{\n"
+printf " /* basic architectural information */\n"
+function_list | while do_read
+do
+ if class_is_info_p
+ then
+ printf " ${returntype} ${function};\n"
+ fi
+done
+printf "\n"
+printf " /* target specific vector. */\n"
+printf " struct gdbarch_tdep *tdep;\n"
+printf " gdbarch_dump_tdep_ftype *dump_tdep;\n"
+printf "\n"
+printf " /* per-architecture data-pointers */\n"
+printf " unsigned nr_data;\n"
+printf " void **data;\n"
+printf "\n"
+printf " /* per-architecture swap-regions */\n"
+printf " struct gdbarch_swap *swap;\n"
+printf "\n"
+cat <<EOF
+ /* Multi-arch values.
+
+ When extending this structure you must:
+
+ Add the field below.
+
+ Declare set/get functions and define the corresponding
+ macro in gdbarch.h.
+
+ gdbarch_alloc(): If zero/NULL is not a suitable default,
+ initialize the new field.
+
+ verify_gdbarch(): Confirm that the target updated the field
+ correctly.
+
+ gdbarch_dump(): Add a fprintf_unfiltered call so that the new
+ field is dumped out
+
+ \`\`startup_gdbarch()'': Append an initial value to the static
+ variable (base values on the host's c-type system).
+
+ get_gdbarch(): Implement the set/get functions (probably using
+ the macro's as shortcuts).
+
+ */
+
+EOF
+function_list | while do_read
+do
+ if class_is_variable_p
+ then
+ printf " ${returntype} ${function};\n"
+ elif class_is_function_p
+ then
+ printf " gdbarch_${function}_ftype *${function}${attrib};\n"
+ fi
+done
+printf "};\n"
+
+# A pre-initialized vector
+printf "\n"
+printf "\n"
+cat <<EOF
+/* The default architecture uses host values (for want of a better
+ choice). */
+EOF
+printf "\n"
+printf "extern const struct bfd_arch_info bfd_default_arch_struct;\n"
+printf "\n"
+printf "struct gdbarch startup_gdbarch =\n"
+printf "{\n"
+printf " /* basic architecture information */\n"
+function_list | while do_read
+do
+ if class_is_info_p
+ then
+ printf " ${staticdefault},\n"
+ fi
+done
+cat <<EOF
+ /* target specific vector and its dump routine */
+ NULL, NULL,
+ /*per-architecture data-pointers and swap regions */
+ 0, NULL, NULL,
+ /* Multi-arch values */
+EOF
+function_list | while do_read
+do
+ if class_is_function_p || class_is_variable_p
+ then
+ printf " ${staticdefault},\n"
+ fi
+done
+cat <<EOF
+ /* startup_gdbarch() */
+};
+
+struct gdbarch *current_gdbarch = &startup_gdbarch;
+
+/* Do any initialization needed for a non-multiarch configuration
+ after the _initialize_MODULE functions have been run. */
+void
+initialize_non_multiarch ()
+{
+ alloc_gdbarch_data (&startup_gdbarch);
+ /* Ensure that all swap areas are zeroed so that they again think
+ they are starting from scratch. */
+ clear_gdbarch_swap (&startup_gdbarch);
+ init_gdbarch_swap (&startup_gdbarch);
+ init_gdbarch_data (&startup_gdbarch);
+}
+EOF
+
+# Create a new gdbarch struct
+printf "\n"
+printf "\n"
+cat <<EOF
+/* Create a new \`\`struct gdbarch'' based on information provided by
+ \`\`struct gdbarch_info''. */
+EOF
+printf "\n"
+cat <<EOF
+struct gdbarch *
+gdbarch_alloc (const struct gdbarch_info *info,
+ struct gdbarch_tdep *tdep)
+{
+ /* NOTE: The new architecture variable is named \`\`current_gdbarch''
+ so that macros such as TARGET_DOUBLE_BIT, when expanded, refer to
+ the current local architecture and not the previous global
+ architecture. This ensures that the new architectures initial
+ values are not influenced by the previous architecture. Once
+ everything is parameterised with gdbarch, this will go away. */
+ struct gdbarch *current_gdbarch = XMALLOC (struct gdbarch);
+ memset (current_gdbarch, 0, sizeof (*current_gdbarch));
+
+ alloc_gdbarch_data (current_gdbarch);
+
+ current_gdbarch->tdep = tdep;
+EOF
+printf "\n"
+function_list | while do_read
+do
+ if class_is_info_p
+ then
+ printf " current_gdbarch->${function} = info->${function};\n"
+ fi
+done
+printf "\n"
+printf " /* Force the explicit initialization of these. */\n"
+function_list | while do_read
+do
+ if class_is_function_p || class_is_variable_p
+ then
+ if [ -n "${predefault}" -a "x${predefault}" != "x0" ]
+ then
+ printf " current_gdbarch->${function} = ${predefault};\n"
+ fi
+ fi
+done
+cat <<EOF
+ /* gdbarch_alloc() */
+
+ return current_gdbarch;
+}
+EOF
+
+# Free a gdbarch struct.
+printf "\n"
+printf "\n"
+cat <<EOF
+/* Free a gdbarch struct. This should never happen in normal
+ operation --- once you've created a gdbarch, you keep it around.
+ However, if an architecture's init function encounters an error
+ building the structure, it may need to clean up a partially
+ constructed gdbarch. */
+
+void
+gdbarch_free (struct gdbarch *arch)
+{
+ gdb_assert (arch != NULL);
+ free_gdbarch_data (arch);
+ xfree (arch);
+}
+EOF
+
+# verify a new architecture
+printf "\n"
+printf "\n"
+printf "/* Ensure that all values in a GDBARCH are reasonable. */\n"
+printf "\n"
+cat <<EOF
+static void
+verify_gdbarch (struct gdbarch *gdbarch)
+{
+ struct ui_file *log;
+ struct cleanup *cleanups;
+ long dummy;
+ char *buf;
+ /* Only perform sanity checks on a multi-arch target. */
+ if (!GDB_MULTI_ARCH)
+ return;
+ log = mem_fileopen ();
+ cleanups = make_cleanup_ui_file_delete (log);
+ /* fundamental */
+ if (gdbarch->byte_order == BFD_ENDIAN_UNKNOWN)
+ fprintf_unfiltered (log, "\n\tbyte-order");
+ if (gdbarch->bfd_arch_info == NULL)
+ fprintf_unfiltered (log, "\n\tbfd_arch_info");
+ /* Check those that need to be defined for the given multi-arch level. */
+EOF
+function_list | while do_read
+do
+ if class_is_function_p || class_is_variable_p
+ then
+ if [ "x${invalid_p}" = "x0" ]
+ then
+ printf " /* Skip verify of ${function}, invalid_p == 0 */\n"
+ elif class_is_predicate_p
+ then
+ printf " /* Skip verify of ${function}, has predicate */\n"
+ # FIXME: See do_read for potential simplification
+ elif [ -n "${invalid_p}" -a -n "${postdefault}" ]
+ then
+ printf " if (${invalid_p})\n"
+ printf " gdbarch->${function} = ${postdefault};\n"
+ elif [ -n "${predefault}" -a -n "${postdefault}" ]
+ then
+ printf " if (gdbarch->${function} == ${predefault})\n"
+ printf " gdbarch->${function} = ${postdefault};\n"
+ elif [ -n "${postdefault}" ]
+ then
+ printf " if (gdbarch->${function} == 0)\n"
+ printf " gdbarch->${function} = ${postdefault};\n"
+ elif [ -n "${invalid_p}" ]
+ then
+ printf " if ((GDB_MULTI_ARCH ${gt_level})\n"
+ printf " && (${invalid_p}))\n"
+ printf " fprintf_unfiltered (log, \"\\\\n\\\\t${function}\");\n"
+ elif [ -n "${predefault}" ]
+ then
+ printf " if ((GDB_MULTI_ARCH ${gt_level})\n"
+ printf " && (gdbarch->${function} == ${predefault}))\n"
+ printf " fprintf_unfiltered (log, \"\\\\n\\\\t${function}\");\n"
+ fi
+ fi
+done
+cat <<EOF
+ buf = ui_file_xstrdup (log, &dummy);
+ make_cleanup (xfree, buf);
+ if (strlen (buf) > 0)
+ internal_error (__FILE__, __LINE__,
+ "verify_gdbarch: the following are invalid ...%s",
+ buf);
+ do_cleanups (cleanups);
+}
+EOF
+
+# dump the structure
+printf "\n"
+printf "\n"
+cat <<EOF
+/* Print out the details of the current architecture. */
+
+/* NOTE/WARNING: The parameter is called \`\`current_gdbarch'' so that it
+ just happens to match the global variable \`\`current_gdbarch''. That
+ way macros refering to that variable get the local and not the global
+ version - ulgh. Once everything is parameterised with gdbarch, this
+ will go away. */
+
+void
+gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
+{
+ fprintf_unfiltered (file,
+ "gdbarch_dump: GDB_MULTI_ARCH = %d\\n",
+ GDB_MULTI_ARCH);
+EOF
+function_list | sort -t: +2 | while do_read
+do
+ # multiarch functions don't have macros.
+ if class_is_multiarch_p
+ then
+ printf " if (GDB_MULTI_ARCH)\n"
+ printf " fprintf_unfiltered (file,\n"
+ printf " \"gdbarch_dump: ${function} = 0x%%08lx\\\\n\",\n"
+ printf " (long) current_gdbarch->${function});\n"
+ continue
+ fi
+ # Print the macro definition.
+ printf "#ifdef ${macro}\n"
+ if [ "x${returntype}" = "xvoid" ]
+ then
+ printf "#if GDB_MULTI_ARCH\n"
+ printf " /* Macro might contain \`[{}]' when not multi-arch */\n"
+ fi
+ if class_is_function_p
+ then
+ printf " fprintf_unfiltered (file,\n"
+ printf " \"gdbarch_dump: %%s # %%s\\\\n\",\n"
+ printf " \"${macro}(${actual})\",\n"
+ printf " XSTRING (${macro} (${actual})));\n"
+ else
+ printf " fprintf_unfiltered (file,\n"
+ printf " \"gdbarch_dump: ${macro} # %%s\\\\n\",\n"
+ printf " XSTRING (${macro}));\n"
+ fi
+ # Print the architecture vector value
+ if [ "x${returntype}" = "xvoid" ]
+ then
+ printf "#endif\n"
+ fi
+ if [ "x${print_p}" = "x()" ]
+ then
+ printf " gdbarch_dump_${function} (current_gdbarch);\n"
+ elif [ "x${print_p}" = "x0" ]
+ then
+ printf " /* skip print of ${macro}, print_p == 0. */\n"
+ elif [ -n "${print_p}" ]
+ then
+ printf " if (${print_p})\n"
+ printf " fprintf_unfiltered (file,\n"
+ printf " \"gdbarch_dump: ${macro} = %s\\\\n\",\n" "${fmt}"
+ printf " ${print});\n"
+ elif class_is_function_p
+ then
+ printf " if (GDB_MULTI_ARCH)\n"
+ printf " fprintf_unfiltered (file,\n"
+ printf " \"gdbarch_dump: ${macro} = 0x%%08lx\\\\n\",\n"
+ printf " (long) current_gdbarch->${function}\n"
+ printf " /*${macro} ()*/);\n"
+ else
+ printf " fprintf_unfiltered (file,\n"
+ printf " \"gdbarch_dump: ${macro} = %s\\\\n\",\n" "${fmt}"
+ printf " ${print});\n"
+ fi
+ printf "#endif\n"
+done
+cat <<EOF
+ if (current_gdbarch->dump_tdep != NULL)
+ current_gdbarch->dump_tdep (current_gdbarch, file);
+}
+EOF
+
+
+# GET/SET
+printf "\n"
+cat <<EOF
+struct gdbarch_tdep *
+gdbarch_tdep (struct gdbarch *gdbarch)
+{
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_tdep called\\n");
+ return gdbarch->tdep;
+}
+EOF
+printf "\n"
+function_list | while do_read
+do
+ if class_is_predicate_p
+ then
+ printf "\n"
+ printf "int\n"
+ printf "gdbarch_${function}_p (struct gdbarch *gdbarch)\n"
+ printf "{\n"
+ printf " gdb_assert (gdbarch != NULL);\n"
+ if [ -n "${valid_p}" ]
+ then
+ printf " return ${valid_p};\n"
+ else
+ printf "#error \"gdbarch_${function}_p: not defined\"\n"
+ fi
+ printf "}\n"
+ fi
+ if class_is_function_p
+ then
+ printf "\n"
+ printf "${returntype}\n"
+ if [ "x${formal}" = "xvoid" ]
+ then
+ printf "gdbarch_${function} (struct gdbarch *gdbarch)\n"
+ else
+ printf "gdbarch_${function} (struct gdbarch *gdbarch, ${formal})\n"
+ fi
+ printf "{\n"
+ printf " gdb_assert (gdbarch != NULL);\n"
+ printf " if (gdbarch->${function} == 0)\n"
+ printf " internal_error (__FILE__, __LINE__,\n"
+ printf " \"gdbarch: gdbarch_${function} invalid\");\n"
+ printf " if (gdbarch_debug >= 2)\n"
+ printf " fprintf_unfiltered (gdb_stdlog, \"gdbarch_${function} called\\\\n\");\n"
+ if [ "x${actual}" = "x-" -o "x${actual}" = "x" ]
+ then
+ if class_is_multiarch_p
+ then
+ params="gdbarch"
+ else
+ params=""
+ fi
+ else
+ if class_is_multiarch_p
+ then
+ params="gdbarch, ${actual}"
+ else
+ params="${actual}"
+ fi
+ fi
+ if [ "x${returntype}" = "xvoid" ]
+ then
+ printf " gdbarch->${function} (${params});\n"
+ else
+ printf " return gdbarch->${function} (${params});\n"
+ fi
+ printf "}\n"
+ printf "\n"
+ printf "void\n"
+ printf "set_gdbarch_${function} (struct gdbarch *gdbarch,\n"
+ printf " `echo ${function} | sed -e 's/./ /g'` gdbarch_${function}_ftype ${function})\n"
+ printf "{\n"
+ printf " gdbarch->${function} = ${function};\n"
+ printf "}\n"
+ elif class_is_variable_p
+ then
+ printf "\n"
+ printf "${returntype}\n"
+ printf "gdbarch_${function} (struct gdbarch *gdbarch)\n"
+ printf "{\n"
+ printf " gdb_assert (gdbarch != NULL);\n"
+ if [ "x${invalid_p}" = "x0" ]
+ then
+ printf " /* Skip verify of ${function}, invalid_p == 0 */\n"
+ elif [ -n "${invalid_p}" ]
+ then
+ printf " if (${invalid_p})\n"
+ printf " internal_error (__FILE__, __LINE__,\n"
+ printf " \"gdbarch: gdbarch_${function} invalid\");\n"
+ elif [ -n "${predefault}" ]
+ then
+ printf " if (gdbarch->${function} == ${predefault})\n"
+ printf " internal_error (__FILE__, __LINE__,\n"
+ printf " \"gdbarch: gdbarch_${function} invalid\");\n"
+ fi
+ printf " if (gdbarch_debug >= 2)\n"
+ printf " fprintf_unfiltered (gdb_stdlog, \"gdbarch_${function} called\\\\n\");\n"
+ printf " return gdbarch->${function};\n"
+ printf "}\n"
+ printf "\n"
+ printf "void\n"
+ printf "set_gdbarch_${function} (struct gdbarch *gdbarch,\n"
+ printf " `echo ${function} | sed -e 's/./ /g'` ${returntype} ${function})\n"
+ printf "{\n"
+ printf " gdbarch->${function} = ${function};\n"
+ printf "}\n"
+ elif class_is_info_p
+ then
+ printf "\n"
+ printf "${returntype}\n"
+ printf "gdbarch_${function} (struct gdbarch *gdbarch)\n"
+ printf "{\n"
+ printf " gdb_assert (gdbarch != NULL);\n"
+ printf " if (gdbarch_debug >= 2)\n"
+ printf " fprintf_unfiltered (gdb_stdlog, \"gdbarch_${function} called\\\\n\");\n"
+ printf " return gdbarch->${function};\n"
+ printf "}\n"
+ fi
+done
+
+# All the trailing guff
+cat <<EOF
+
+
+/* Keep a registry of per-architecture data-pointers required by GDB
+ modules. */
+
+struct gdbarch_data
+{
+ unsigned index;
+ gdbarch_data_init_ftype *init;
+ gdbarch_data_free_ftype *free;
+};
+
+struct gdbarch_data_registration
+{
+ struct gdbarch_data *data;
+ struct gdbarch_data_registration *next;
+};
+
+struct gdbarch_data_registry
+{
+ unsigned nr;
+ struct gdbarch_data_registration *registrations;
+};
+
+struct gdbarch_data_registry gdbarch_data_registry =
+{
+ 0, NULL,
+};
+
+struct gdbarch_data *
+register_gdbarch_data (gdbarch_data_init_ftype *init,
+ gdbarch_data_free_ftype *free)
+{
+ struct gdbarch_data_registration **curr;
+ for (curr = &gdbarch_data_registry.registrations;
+ (*curr) != NULL;
+ curr = &(*curr)->next);
+ (*curr) = XMALLOC (struct gdbarch_data_registration);
+ (*curr)->next = NULL;
+ (*curr)->data = XMALLOC (struct gdbarch_data);
+ (*curr)->data->index = gdbarch_data_registry.nr++;
+ (*curr)->data->init = init;
+ (*curr)->data->free = free;
+ return (*curr)->data;
+}
+
+
+/* Walk through all the registered users initializing each in turn. */
+
+static void
+init_gdbarch_data (struct gdbarch *gdbarch)
+{
+ struct gdbarch_data_registration *rego;
+ for (rego = gdbarch_data_registry.registrations;
+ rego != NULL;
+ rego = rego->next)
+ {
+ struct gdbarch_data *data = rego->data;
+ gdb_assert (data->index < gdbarch->nr_data);
+ if (data->init != NULL)
+ {
+ void *pointer = data->init (gdbarch);
+ set_gdbarch_data (gdbarch, data, pointer);
+ }
+ }
+}
+
+/* Create/delete the gdbarch data vector. */
+
+static void
+alloc_gdbarch_data (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch->data == NULL);
+ gdbarch->nr_data = gdbarch_data_registry.nr;
+ gdbarch->data = xcalloc (gdbarch->nr_data, sizeof (void*));
+}
+
+static void
+free_gdbarch_data (struct gdbarch *gdbarch)
+{
+ struct gdbarch_data_registration *rego;
+ gdb_assert (gdbarch->data != NULL);
+ for (rego = gdbarch_data_registry.registrations;
+ rego != NULL;
+ rego = rego->next)
+ {
+ struct gdbarch_data *data = rego->data;
+ gdb_assert (data->index < gdbarch->nr_data);
+ if (data->free != NULL && gdbarch->data[data->index] != NULL)
+ {
+ data->free (gdbarch, gdbarch->data[data->index]);
+ gdbarch->data[data->index] = NULL;
+ }
+ }
+ xfree (gdbarch->data);
+ gdbarch->data = NULL;
+}
+
+
+/* Initialize the current value of thee specified per-architecture
+ data-pointer. */
+
+void
+set_gdbarch_data (struct gdbarch *gdbarch,
+ struct gdbarch_data *data,
+ void *pointer)
+{
+ gdb_assert (data->index < gdbarch->nr_data);
+ if (data->free != NULL && gdbarch->data[data->index] != NULL)
+ data->free (gdbarch, gdbarch->data[data->index]);
+ gdbarch->data[data->index] = pointer;
+}
+
+/* Return the current value of the specified per-architecture
+ data-pointer. */
+
+void *
+gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data)
+{
+ gdb_assert (data->index < gdbarch->nr_data);
+ return gdbarch->data[data->index];
+}
+
+
+
+/* Keep a registry of swapped data required by GDB modules. */
+
+struct gdbarch_swap
+{
+ void *swap;
+ struct gdbarch_swap_registration *source;
+ struct gdbarch_swap *next;
+};
+
+struct gdbarch_swap_registration
+{
+ void *data;
+ unsigned long sizeof_data;
+ gdbarch_swap_ftype *init;
+ struct gdbarch_swap_registration *next;
+};
+
+struct gdbarch_swap_registry
+{
+ int nr;
+ struct gdbarch_swap_registration *registrations;
+};
+
+struct gdbarch_swap_registry gdbarch_swap_registry =
+{
+ 0, NULL,
+};
+
+void
+register_gdbarch_swap (void *data,
+ unsigned long sizeof_data,
+ gdbarch_swap_ftype *init)
+{
+ struct gdbarch_swap_registration **rego;
+ for (rego = &gdbarch_swap_registry.registrations;
+ (*rego) != NULL;
+ rego = &(*rego)->next);
+ (*rego) = XMALLOC (struct gdbarch_swap_registration);
+ (*rego)->next = NULL;
+ (*rego)->init = init;
+ (*rego)->data = data;
+ (*rego)->sizeof_data = sizeof_data;
+}
+
+static void
+clear_gdbarch_swap (struct gdbarch *gdbarch)
+{
+ struct gdbarch_swap *curr;
+ for (curr = gdbarch->swap;
+ curr != NULL;
+ curr = curr->next)
+ {
+ memset (curr->source->data, 0, curr->source->sizeof_data);
+ }
+}
+
+static void
+init_gdbarch_swap (struct gdbarch *gdbarch)
+{
+ struct gdbarch_swap_registration *rego;
+ struct gdbarch_swap **curr = &gdbarch->swap;
+ for (rego = gdbarch_swap_registry.registrations;
+ rego != NULL;
+ rego = rego->next)
+ {
+ if (rego->data != NULL)
+ {
+ (*curr) = XMALLOC (struct gdbarch_swap);
+ (*curr)->source = rego;
+ (*curr)->swap = xmalloc (rego->sizeof_data);
+ (*curr)->next = NULL;
+ curr = &(*curr)->next;
+ }
+ if (rego->init != NULL)
+ rego->init ();
+ }
+}
+
+static void
+swapout_gdbarch_swap (struct gdbarch *gdbarch)
+{
+ struct gdbarch_swap *curr;
+ for (curr = gdbarch->swap;
+ curr != NULL;
+ curr = curr->next)
+ memcpy (curr->swap, curr->source->data, curr->source->sizeof_data);
+}
+
+static void
+swapin_gdbarch_swap (struct gdbarch *gdbarch)
+{
+ struct gdbarch_swap *curr;
+ for (curr = gdbarch->swap;
+ curr != NULL;
+ curr = curr->next)
+ memcpy (curr->source->data, curr->swap, curr->source->sizeof_data);
+}
+
+
+/* Keep a registry of the architectures known by GDB. */
+
+struct gdbarch_registration
+{
+ enum bfd_architecture bfd_architecture;
+ gdbarch_init_ftype *init;
+ gdbarch_dump_tdep_ftype *dump_tdep;
+ struct gdbarch_list *arches;
+ struct gdbarch_registration *next;
+};
+
+static struct gdbarch_registration *gdbarch_registry = NULL;
+
+static void
+append_name (const char ***buf, int *nr, const char *name)
+{
+ *buf = xrealloc (*buf, sizeof (char**) * (*nr + 1));
+ (*buf)[*nr] = name;
+ *nr += 1;
+}
+
+const char **
+gdbarch_printable_names (void)
+{
+ if (GDB_MULTI_ARCH)
+ {
+ /* Accumulate a list of names based on the registed list of
+ architectures. */
+ enum bfd_architecture a;
+ int nr_arches = 0;
+ const char **arches = NULL;
+ struct gdbarch_registration *rego;
+ for (rego = gdbarch_registry;
+ rego != NULL;
+ rego = rego->next)
+ {
+ const struct bfd_arch_info *ap;
+ ap = bfd_lookup_arch (rego->bfd_architecture, 0);
+ if (ap == NULL)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch_architecture_names: multi-arch unknown");
+ do
+ {
+ append_name (&arches, &nr_arches, ap->printable_name);
+ ap = ap->next;
+ }
+ while (ap != NULL);
+ }
+ append_name (&arches, &nr_arches, NULL);
+ return arches;
+ }
+ else
+ /* Just return all the architectures that BFD knows. Assume that
+ the legacy architecture framework supports them. */
+ return bfd_arch_list ();
+}
+
+
+void
+gdbarch_register (enum bfd_architecture bfd_architecture,
+ gdbarch_init_ftype *init,
+ gdbarch_dump_tdep_ftype *dump_tdep)
+{
+ struct gdbarch_registration **curr;
+ const struct bfd_arch_info *bfd_arch_info;
+ /* Check that BFD recognizes this architecture */
+ bfd_arch_info = bfd_lookup_arch (bfd_architecture, 0);
+ if (bfd_arch_info == NULL)
+ {
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: Attempt to register unknown architecture (%d)",
+ bfd_architecture);
+ }
+ /* Check that we haven't seen this architecture before */
+ for (curr = &gdbarch_registry;
+ (*curr) != NULL;
+ curr = &(*curr)->next)
+ {
+ if (bfd_architecture == (*curr)->bfd_architecture)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: Duplicate registraration of architecture (%s)",
+ bfd_arch_info->printable_name);
+ }
+ /* log it */
+ if (gdbarch_debug)
+ fprintf_unfiltered (gdb_stdlog, "register_gdbarch_init (%s, 0x%08lx)\n",
+ bfd_arch_info->printable_name,
+ (long) init);
+ /* Append it */
+ (*curr) = XMALLOC (struct gdbarch_registration);
+ (*curr)->bfd_architecture = bfd_architecture;
+ (*curr)->init = init;
+ (*curr)->dump_tdep = dump_tdep;
+ (*curr)->arches = NULL;
+ (*curr)->next = NULL;
+ /* When non- multi-arch, install whatever target dump routine we've
+ been provided - hopefully that routine has been written correctly
+ and works regardless of multi-arch. */
+ if (!GDB_MULTI_ARCH && dump_tdep != NULL
+ && startup_gdbarch.dump_tdep == NULL)
+ startup_gdbarch.dump_tdep = dump_tdep;
+}
+
+void
+register_gdbarch_init (enum bfd_architecture bfd_architecture,
+ gdbarch_init_ftype *init)
+{
+ gdbarch_register (bfd_architecture, init, NULL);
+}
+
+
+/* Look for an architecture using gdbarch_info. Base search on only
+ BFD_ARCH_INFO and BYTE_ORDER. */
+
+struct gdbarch_list *
+gdbarch_list_lookup_by_info (struct gdbarch_list *arches,
+ const struct gdbarch_info *info)
+{
+ for (; arches != NULL; arches = arches->next)
+ {
+ if (info->bfd_arch_info != arches->gdbarch->bfd_arch_info)
+ continue;
+ if (info->byte_order != arches->gdbarch->byte_order)
+ continue;
+ return arches;
+ }
+ return NULL;
+}
+
+
+/* Update the current architecture. Return ZERO if the update request
+ failed. */
+
+int
+gdbarch_update_p (struct gdbarch_info info)
+{
+ struct gdbarch *new_gdbarch;
+ struct gdbarch *old_gdbarch;
+ struct gdbarch_registration *rego;
+
+ /* Fill in missing parts of the INFO struct using a number of
+ sources: \`\`set ...''; INFOabfd supplied; existing target. */
+
+ /* \`\`(gdb) set architecture ...'' */
+ if (info.bfd_arch_info == NULL
+ && !TARGET_ARCHITECTURE_AUTO)
+ info.bfd_arch_info = TARGET_ARCHITECTURE;
+ if (info.bfd_arch_info == NULL
+ && info.abfd != NULL
+ && bfd_get_arch (info.abfd) != bfd_arch_unknown
+ && bfd_get_arch (info.abfd) != bfd_arch_obscure)
+ info.bfd_arch_info = bfd_get_arch_info (info.abfd);
+ if (info.bfd_arch_info == NULL)
+ info.bfd_arch_info = TARGET_ARCHITECTURE;
+
+ /* \`\`(gdb) set byte-order ...'' */
+ if (info.byte_order == BFD_ENDIAN_UNKNOWN
+ && !TARGET_BYTE_ORDER_AUTO)
+ info.byte_order = TARGET_BYTE_ORDER;
+ /* From the INFO struct. */
+ if (info.byte_order == BFD_ENDIAN_UNKNOWN
+ && info.abfd != NULL)
+ info.byte_order = (bfd_big_endian (info.abfd) ? BFD_ENDIAN_BIG
+ : bfd_little_endian (info.abfd) ? BFD_ENDIAN_LITTLE
+ : BFD_ENDIAN_UNKNOWN);
+ /* From the current target. */
+ if (info.byte_order == BFD_ENDIAN_UNKNOWN)
+ info.byte_order = TARGET_BYTE_ORDER;
+
+ /* Must have found some sort of architecture. */
+ gdb_assert (info.bfd_arch_info != NULL);
+
+ if (gdbarch_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "gdbarch_update: info.bfd_arch_info %s\n",
+ (info.bfd_arch_info != NULL
+ ? info.bfd_arch_info->printable_name
+ : "(null)"));
+ fprintf_unfiltered (gdb_stdlog,
+ "gdbarch_update: info.byte_order %d (%s)\n",
+ info.byte_order,
+ (info.byte_order == BFD_ENDIAN_BIG ? "big"
+ : info.byte_order == BFD_ENDIAN_LITTLE ? "little"
+ : "default"));
+ fprintf_unfiltered (gdb_stdlog,
+ "gdbarch_update: info.abfd 0x%lx\n",
+ (long) info.abfd);
+ fprintf_unfiltered (gdb_stdlog,
+ "gdbarch_update: info.tdep_info 0x%lx\n",
+ (long) info.tdep_info);
+ }
+
+ /* Find the target that knows about this architecture. */
+ for (rego = gdbarch_registry;
+ rego != NULL;
+ rego = rego->next)
+ if (rego->bfd_architecture == info.bfd_arch_info->arch)
+ break;
+ if (rego == NULL)
+ {
+ if (gdbarch_debug)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_update: No matching architecture\\n");
+ return 0;
+ }
+
+ /* Swap the data belonging to the old target out setting the
+ installed data to zero. This stops the ->init() function trying
+ to refer to the previous architecture's global data structures. */
+ swapout_gdbarch_swap (current_gdbarch);
+ clear_gdbarch_swap (current_gdbarch);
+
+ /* Save the previously selected architecture, setting the global to
+ NULL. This stops ->init() trying to use the previous
+ architecture's configuration. The previous architecture may not
+ even be of the same architecture family. The most recent
+ architecture of the same family is found at the head of the
+ rego->arches list. */
+ old_gdbarch = current_gdbarch;
+ current_gdbarch = NULL;
+
+ /* Ask the target for a replacement architecture. */
+ new_gdbarch = rego->init (info, rego->arches);
+
+ /* Did the target like it? No. Reject the change and revert to the
+ old architecture. */
+ if (new_gdbarch == NULL)
+ {
+ if (gdbarch_debug)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Target rejected architecture\\n");
+ swapin_gdbarch_swap (old_gdbarch);
+ current_gdbarch = old_gdbarch;
+ return 0;
+ }
+
+ /* Did the architecture change? No. Oops, put the old architecture
+ back. */
+ if (old_gdbarch == new_gdbarch)
+ {
+ if (gdbarch_debug)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Architecture 0x%08lx (%s) unchanged\\n",
+ (long) new_gdbarch,
+ new_gdbarch->bfd_arch_info->printable_name);
+ swapin_gdbarch_swap (old_gdbarch);
+ current_gdbarch = old_gdbarch;
+ return 1;
+ }
+
+ /* Is this a pre-existing architecture? Yes. Move it to the front
+ of the list of architectures (keeping the list sorted Most
+ Recently Used) and then copy it in. */
+ {
+ struct gdbarch_list **list;
+ for (list = &rego->arches;
+ (*list) != NULL;
+ list = &(*list)->next)
+ {
+ if ((*list)->gdbarch == new_gdbarch)
+ {
+ struct gdbarch_list *this;
+ if (gdbarch_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "gdbarch_update: Previous architecture 0x%08lx (%s) selected\n",
+ (long) new_gdbarch,
+ new_gdbarch->bfd_arch_info->printable_name);
+ /* Unlink this. */
+ this = (*list);
+ (*list) = this->next;
+ /* Insert in the front. */
+ this->next = rego->arches;
+ rego->arches = this;
+ /* Copy the new architecture in. */
+ current_gdbarch = new_gdbarch;
+ swapin_gdbarch_swap (new_gdbarch);
+ architecture_changed_event ();
+ return 1;
+ }
+ }
+ }
+
+ /* Prepend this new architecture to the architecture list (keep the
+ list sorted Most Recently Used). */
+ {
+ struct gdbarch_list *this = XMALLOC (struct gdbarch_list);
+ this->next = rego->arches;
+ this->gdbarch = new_gdbarch;
+ rego->arches = this;
+ }
+
+ /* Switch to this new architecture. Dump it out. */
+ current_gdbarch = new_gdbarch;
+ if (gdbarch_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "gdbarch_update: New architecture 0x%08lx (%s) selected\\n",
+ (long) new_gdbarch,
+ new_gdbarch->bfd_arch_info->printable_name);
+ }
+
+ /* Check that the newly installed architecture is valid. Plug in
+ any post init values. */
+ new_gdbarch->dump_tdep = rego->dump_tdep;
+ verify_gdbarch (new_gdbarch);
+
+ /* Initialize the per-architecture memory (swap) areas.
+ CURRENT_GDBARCH must be update before these modules are
+ called. */
+ init_gdbarch_swap (new_gdbarch);
+
+ /* Initialize the per-architecture data-pointer of all parties that
+ registered an interest in this architecture. CURRENT_GDBARCH
+ must be updated before these modules are called. */
+ init_gdbarch_data (new_gdbarch);
+ architecture_changed_event ();
+
+ if (gdbarch_debug)
+ gdbarch_dump (current_gdbarch, gdb_stdlog);
+
+ return 1;
+}
+
+
+/* Disassembler */
+
+/* Pointer to the target-dependent disassembly function. */
+int (*tm_print_insn) (bfd_vma, disassemble_info *);
+disassemble_info tm_print_insn_info;
+
+
+extern void _initialize_gdbarch (void);
+
+void
+_initialize_gdbarch (void)
+{
+ struct cmd_list_element *c;
+
+ INIT_DISASSEMBLE_INFO_NO_ARCH (tm_print_insn_info, gdb_stdout, (fprintf_ftype)fprintf_filtered);
+ tm_print_insn_info.flavour = bfd_target_unknown_flavour;
+ tm_print_insn_info.read_memory_func = dis_asm_read_memory;
+ tm_print_insn_info.memory_error_func = dis_asm_memory_error;
+ tm_print_insn_info.print_address_func = dis_asm_print_address;
+
+ add_show_from_set (add_set_cmd ("arch",
+ class_maintenance,
+ var_zinteger,
+ (char *)&gdbarch_debug,
+ "Set architecture debugging.\\n\\
+When non-zero, architecture debugging is enabled.", &setdebuglist),
+ &showdebuglist);
+ c = add_set_cmd ("archdebug",
+ class_maintenance,
+ var_zinteger,
+ (char *)&gdbarch_debug,
+ "Set architecture debugging.\\n\\
+When non-zero, architecture debugging is enabled.", &setlist);
+
+ deprecate_cmd (c, "set debug arch");
+ deprecate_cmd (add_show_from_set (c, &showlist), "show debug arch");
+}
+EOF
+
+# close things off
+exec 1>&2
+#../move-if-change new-gdbarch.c gdbarch.c
+compare_new gdbarch.c
diff --git a/gdb/gdbcmd.h b/gdb/gdbcmd.h
new file mode 100644
index 00000000000..8c4490ec940
--- /dev/null
+++ b/gdb/gdbcmd.h
@@ -0,0 +1,122 @@
+/* ***DEPRECATED*** The gdblib files must not be calling/using things in any
+ of the possible command languages. If necessary, a hook (that may be
+ present or not) must be used and set to the appropriate routine by any
+ command language that cares about it. If you are having to include this
+ file you are possibly doing things the old way. This file will disapear.
+ fnasser@redhat.com */
+
+/* Header file for GDB-specific command-line stuff.
+ Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1998, 1999,
+ 2000, 2002 Free Software Foundation, Inc.
+
+ 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. */
+
+#if !defined (GDBCMD_H)
+#define GDBCMD_H 1
+
+#include "command.h"
+#include "ui-out.h"
+
+/* Chain containing all defined commands. */
+
+extern struct cmd_list_element *cmdlist;
+
+/* Chain containing all defined info subcommands. */
+
+extern struct cmd_list_element *infolist;
+
+/* Chain containing all defined enable subcommands. */
+
+extern struct cmd_list_element *enablelist;
+
+/* Chain containing all defined disable subcommands. */
+
+extern struct cmd_list_element *disablelist;
+
+/* Chain containing all defined delete subcommands. */
+
+extern struct cmd_list_element *deletelist;
+
+/* Chain containing all defined toggle subcommands. */
+
+extern struct cmd_list_element *togglelist;
+
+/* Chain containing all defined stop subcommands. */
+
+extern struct cmd_list_element *stoplist;
+
+/* Chain containing all defined "enable breakpoint" subcommands. */
+
+extern struct cmd_list_element *enablebreaklist;
+
+/* Chain containing all defined set subcommands */
+
+extern struct cmd_list_element *setlist;
+
+/* Chain containing all defined unset subcommands */
+
+extern struct cmd_list_element *unsetlist;
+
+/* Chain containing all defined show subcommands. */
+
+extern struct cmd_list_element *showlist;
+
+/* Chain containing all defined \"set history\". */
+
+extern struct cmd_list_element *sethistlist;
+
+/* Chain containing all defined \"show history\". */
+
+extern struct cmd_list_element *showhistlist;
+
+/* Chain containing all defined \"unset history\". */
+
+extern struct cmd_list_element *unsethistlist;
+
+/* Chain containing all defined maintenance subcommands. */
+
+extern struct cmd_list_element *maintenancelist;
+
+/* Chain containing all defined "maintenance info" subcommands. */
+
+extern struct cmd_list_element *maintenanceinfolist;
+
+/* Chain containing all defined "maintenance print" subcommands. */
+
+extern struct cmd_list_element *maintenanceprintlist;
+
+extern struct cmd_list_element *setprintlist;
+
+extern struct cmd_list_element *showprintlist;
+
+extern struct cmd_list_element *setdebuglist;
+
+extern struct cmd_list_element *showdebuglist;
+
+extern struct cmd_list_element *setchecklist;
+
+extern struct cmd_list_element *showchecklist;
+
+extern void execute_command (char *, int);
+
+enum command_control_type execute_control_command (struct command_line *);
+
+extern void print_command_line (struct command_line *, unsigned int,
+ struct ui_file *);
+extern void print_command_lines (struct ui_out *,
+ struct command_line *, unsigned int);
+
+#endif /* !defined (GDBCMD_H) */
diff --git a/gdb/gdbcore.h b/gdb/gdbcore.h
new file mode 100644
index 00000000000..88594554080
--- /dev/null
+++ b/gdb/gdbcore.h
@@ -0,0 +1,201 @@
+/* Machine independent variables that describe the core file under GDB.
+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001 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. */
+
+/* Interface routines for core, executable, etc. */
+
+#if !defined (GDBCORE_H)
+#define GDBCORE_H 1
+
+#include "bfd.h"
+
+/* Return the name of the executable file as a string.
+ ERR nonzero means get error if there is none specified;
+ otherwise return 0 in that case. */
+
+extern char *get_exec_file (int err);
+
+/* Nonzero if there is a core file. */
+
+extern int have_core_file_p (void);
+
+/* Read "memory data" from whatever target or inferior we have.
+ Returns zero if successful, errno value if not. EIO is used for
+ address out of bounds. If breakpoints are inserted, returns shadow
+ contents, not the breakpoints themselves. From breakpoint.c. */
+
+extern int read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len);
+
+/* Report a memory error with error(). */
+
+extern void memory_error (int status, CORE_ADDR memaddr);
+
+/* Like target_read_memory, but report an error if can't read. */
+
+extern void read_memory (CORE_ADDR memaddr, char *myaddr, int len);
+
+/* Read an integer from debugged memory, given address and number of
+ bytes. */
+
+extern LONGEST read_memory_integer (CORE_ADDR memaddr, int len);
+extern int safe_read_memory_integer (CORE_ADDR memaddr, int len, LONGEST *return_value);
+
+/* Read an unsigned integer from debugged memory, given address and
+ number of bytes. */
+
+extern ULONGEST read_memory_unsigned_integer (CORE_ADDR memaddr, int len);
+
+/* Read a null-terminated string from the debuggee's memory, given address,
+ * a buffer into which to place the string, and the maximum available space */
+extern void read_memory_string (CORE_ADDR, char *, int);
+
+/* This takes a char *, not void *. This is probably right, because
+ passing in an int * or whatever is wrong with respect to
+ byteswapping, alignment, different sizes for host vs. target types,
+ etc. */
+
+extern void write_memory (CORE_ADDR memaddr, char *myaddr, int len);
+
+/* Store VALUE at ADDR in the inferior as a LEN-byte unsigned integer. */
+extern void write_memory_unsigned_integer (CORE_ADDR addr, int len,
+ ULONGEST value);
+
+/* Store VALUE at ADDR in the inferior as a LEN-byte unsigned integer. */
+extern void write_memory_signed_integer (CORE_ADDR addr, int len,
+ LONGEST value);
+
+extern void generic_search (int len, char *data, char *mask,
+ CORE_ADDR startaddr, int increment,
+ CORE_ADDR lorange, CORE_ADDR hirange,
+ CORE_ADDR * addr_found, char *data_found);
+
+/* Hook for `exec_file_command' command to call. */
+
+extern void (*exec_file_display_hook) (char *filename);
+
+/* Hook for "file_command", which is more useful than above
+ (because it is invoked AFTER symbols are read, not before) */
+
+extern void (*file_changed_hook) (char *filename);
+
+extern void specify_exec_file_hook (void (*hook) (char *filename));
+
+/* Binary File Diddlers for the exec and core files */
+
+extern bfd *core_bfd;
+extern bfd *exec_bfd;
+
+/* Whether to open exec and core files read-only or read-write. */
+
+extern int write_files;
+
+extern void core_file_command (char *filename, int from_tty);
+
+extern void exec_open (char *filename, int from_tty);
+
+extern void exec_file_attach (char *filename, int from_tty);
+
+extern void exec_file_clear (int from_tty);
+
+extern void validate_files (void);
+
+extern CORE_ADDR register_addr (int regno, CORE_ADDR blockend);
+
+#if !defined (KERNEL_U_ADDR)
+extern CORE_ADDR kernel_u_addr;
+#define KERNEL_U_ADDR kernel_u_addr
+#endif
+
+/* The target vector for core files. */
+
+extern struct target_ops core_ops;
+
+/* The current default bfd target. */
+
+extern char *gnutarget;
+
+extern void set_gnutarget (char *);
+
+/* Structure to keep track of core register reading functions for
+ various core file types. */
+
+struct core_fns
+ {
+
+ /* BFD flavour that a core file handler is prepared to read. This
+ can be used by the handler's core tasting function as a first
+ level filter to reject BFD's that don't have the right
+ flavour. */
+
+ enum bfd_flavour core_flavour;
+
+ /* Core file handler function to call to recognize corefile
+ formats that BFD rejects. Some core file format just don't fit
+ into the BFD model, or may require other resources to identify
+ them, that simply aren't available to BFD (such as symbols from
+ another file). Returns nonzero if the handler recognizes the
+ format, zero otherwise. */
+
+ int (*check_format) (bfd *);
+
+ /* Core file handler function to call to ask if it can handle a
+ given core file format or not. Returns zero if it can't,
+ nonzero otherwise. */
+
+ int (*core_sniffer) (struct core_fns *, bfd *);
+
+ /* Extract the register values out of the core file and store them where
+ `read_register' will find them.
+
+ CORE_REG_SECT points to the register values themselves, read into
+ memory.
+
+ CORE_REG_SIZE is the size of that area.
+
+ WHICH says which set of registers we are handling:
+ 0 --- integer registers
+ 2 --- floating-point registers, on machines where they are
+ discontiguous
+ 3 --- extended floating-point registers, on machines where
+ these are present in yet a third area. (GNU/Linux uses
+ this to get at the SSE registers.)
+
+ REG_ADDR is the offset from u.u_ar0 to the register values relative to
+ core_reg_sect. This is used with old-fashioned core files to locate the
+ registers in a large upage-plus-stack ".reg" section. Original upage
+ address X is at location core_reg_sect+x+reg_addr. */
+
+ void (*core_read_registers) (char *core_reg_sect,
+ unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr);
+
+ /* Finds the next struct core_fns. They are allocated and initialized
+ in whatever module implements the functions pointed to; an
+ initializer calls add_core_fns to add them to the global chain. */
+
+ struct core_fns *next;
+
+ };
+
+extern void add_core_fns (struct core_fns *cf);
+extern int default_core_sniffer (struct core_fns *cf, bfd * abfd);
+extern int default_check_format (bfd * abfd);
+
+#endif /* !defined (GDBCORE_H) */
diff --git a/gdb/gdbinit.in b/gdb/gdbinit.in
new file mode 100644
index 00000000000..b6a32dba09f
--- /dev/null
+++ b/gdb/gdbinit.in
@@ -0,0 +1,18 @@
+echo Setting up the environment for debugging gdb.\n
+
+set complaints 1
+
+b internal_error
+
+b info_command
+commands
+ silent
+ return
+end
+
+dir @srcdir@
+dir .
+dir @srcdir@/../mmalloc
+dir @srcdir@/../libiberty
+dir @srcdir@/../bfd
+set prompt (top-gdb)
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
new file mode 100644
index 00000000000..2c8cd3366b4
--- /dev/null
+++ b/gdb/gdbserver/Makefile.in
@@ -0,0 +1,299 @@
+# Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+# 1999, 2000, 2001, 2002 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.
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+host_alias = @host_alias@
+target_alias = @target_alias@
+program_transform_name = @program_transform_name@
+bindir = @bindir@
+libdir = @libdir@
+tooldir = $(libdir)/$(target_alias)
+
+datadir = @datadir@
+mandir = @mandir@
+man1dir = $(mandir)/man1
+man2dir = $(mandir)/man2
+man3dir = $(mandir)/man3
+man4dir = $(mandir)/man4
+man5dir = $(mandir)/man5
+man6dir = $(mandir)/man6
+man7dir = $(mandir)/man7
+man8dir = $(mandir)/man8
+man9dir = $(mandir)/man9
+infodir = @infodir@
+htmldir = $(prefix)/html
+includedir = @includedir@
+
+SHELL = /bin/sh
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+CC = @CC@
+
+# Directory containing source files. Don't clean up the spacing,
+# this exact string is matched for by the "configure" script.
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+# It is also possible that you will need to add -I/usr/include/sys to the
+# CFLAGS section if your system doesn't have fcntl.h in /usr/include (which
+# is where it should be according to Posix).
+
+# Set this up with gcc if you have gnu ld and the loader will print out
+# line numbers for undefinded refs.
+#CC-LD=gcc -static
+CC-LD=${CC}
+
+# Where is the "include" directory? Traditionally ../include or ./include
+INCLUDE_DIR = ${srcdir}/../../include
+INCLUDE_DEP = $$(INCLUDE_DIR)
+
+# Where are the BFD library?
+BFD_DIR = ../../bfd
+BFD = $(BFD_DIR)/libbfd.a
+BFD_SRC = $(srcdir)/$(BFD_DIR)
+BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC)
+
+# Where is the source dir for the READLINE library? Traditionally in .. or .
+# (For the binary library built from it, we use ${READLINE_DIR}${subdir}.)
+READLINE_DIR = ${srcdir}/../readline
+READLINE_DEP = $$(READLINE_DIR)
+
+# All the includes used for CFLAGS and for lint.
+# -I. for config files.
+# -I${srcdir} for our headers.
+# -I$(srcdir)/../regformats for regdef.h.
+INCLUDE_CFLAGS = -I. -I${srcdir} -I$(srcdir)/../regformats -I$(INCLUDE_DIR)
+
+# M{H,T}_CFLAGS, if defined, has host- and target-dependent CFLAGS
+# from the config/ directory.
+GLOBAL_CFLAGS = ${MT_CFLAGS} ${MH_CFLAGS}
+#PROFILE_CFLAGS = -pg
+
+WARN_CFLAGS = -Wall
+
+# CFLAGS is specifically reserved for setting from the command line
+# when running make. I.E. "make CFLAGS=-Wmissing-prototypes".
+CFLAGS = @CFLAGS@
+
+# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
+INTERNAL_CFLAGS = $(WARN_CFLAGS) ${CFLAGS} ${GLOBAL_CFLAGS} \
+ ${PROFILE_CFLAGS} ${INCLUDE_CFLAGS} ${BFD_CFLAGS}
+
+# LDFLAGS is specifically reserved for setting from the command line
+# when running make.
+
+# Perhaps should come from parent Makefile
+VERSION = gdbserver-4.12.3
+DIST=gdb
+
+LINT=/usr/5bin/lint
+LINTFLAGS= $(BFD_CFLAGS)
+
+# All source files that go into linking GDB remote server.
+
+SFILES = $(srcdir)/low-hppabsd.c $(srcdir)/low-linux.c $(srcdir)/low-lynx.c \
+ $(srcdir)/low-nbsd.c $(srcdir)/low-sim.c $(srcdir)/low-sparc.c \
+ $(srcdir)/low-sun3.c $(srcdir)/utils.c $(srcdir)/server.c \
+ $(srcdir)/remote-utils.c
+
+DEPFILES = @GDBSERVER_DEPFILES@
+
+SOURCES = $(SFILES)
+TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
+
+OBS = inferiors.o regcache.o remote-utils.o server.o signals.o target.o \
+ utils.o \
+ mem-break.o \
+ $(DEPFILES)
+
+# Prevent Sun make from putting in the machine type. Setting
+# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1.
+.c.o:
+ ${CC} -c ${INTERNAL_CFLAGS} $<
+
+all: gdbserver gdbreplay
+
+# Traditionally "install" depends on "all". But it may be useful
+# not to; for example, if the user has made some trivial change to a
+# source file and doesn't care about rebuilding or just wants to save the
+# time it takes for make to check that all is up to date.
+# install-only is intended to address that need.
+install: all install-only
+install-only:
+ n=`echo gdbserver | sed '$(program_transform_name)'`; \
+ if [ x$$n = x ]; then n=gdbserver; else true; fi; \
+ $(INSTALL_PROGRAM) gdbserver $(bindir)/$$n; \
+ $(INSTALL_DATA) $(srcdir)/gdbserver.1 $(man1dir)/$$n.1
+
+uninstall: force
+ n=`echo gdbserver | sed '$(program_transform_name)'`; \
+ if [ x$$n = x ]; then n=gdbserver; else true; fi; \
+ rm -f $(bindir)/$$n $(man1dir)/$$n.1
+
+installcheck:
+check:
+info dvi:
+install-info:
+html:
+install-html:
+clean-info:
+
+gdbserver: $(OBS) ${ADD_DEPS} ${CDEPS}
+ rm -f gdbserver
+ ${CC-LD} $(GLOBAL_CFLAGS) $(LDFLAGS) -o gdbserver $(OBS) \
+ $(GDBSERVER_LIBS) $(XM_CLIBS)
+
+gdbreplay: gdbreplay.o
+ rm -f gdbreplay
+ ${CC-LD} $(GLOBAL_CFLAGS) $(LDFLAGS) -o gdbreplay gdbreplay.o \
+ $(XM_CLIBS)
+
+# Put the proper machine-specific files first, so M-. on a machine
+# specific routine gets the one for the correct machine.
+# The xyzzy stuff below deals with empty DEPFILES
+TAGS: ${TAGFILES}
+ etags `find ${srcdir}/../config -name $(TM_FILE) -print` \
+ `find ${srcdir}/../config -name ${XM_FILE} -print` \
+ `find ${srcdir}/../config -name ${NAT_FILE} -print` \
+ `for i in yzzy ${DEPFILES}; do \
+ if [ x$$i != xyzzy ]; then \
+ echo ${srcdir}/$$i | sed -e 's/\.o$$/\.c/' ; \
+ fi; \
+ done` \
+ ${TAGFILES}
+tags: TAGS
+
+clean:
+ rm -f *.o ${ADD_FILES} *~
+ rm -f gdbserver gdbreplay core make.log
+ rm -f reg-arm.c reg-i386.c reg-ia64.c reg-m68k.c reg-mips.c
+ rm -f reg-ppc.c reg-sh.c reg-x86-64.c reg-i386-linux.c
+
+distclean: clean
+ rm -f nm.h tm.h xm.h config.status
+ rm -f Makefile
+
+maintainer-clean realclean: clean
+ rm -f nm.h tm.h xm.h config.status
+ rm -f Makefile
+
+STAGESTUFF=${OBS} ${TSOBS} ${NTSOBS} ${ADD_FILES} init.c init.o version.c gdb
+
+config.h: stamp-h ; @true
+stamp-h: config.in config.status
+ CONFIG_FILES="" $(SHELL) ./config.status
+
+Makefile: Makefile.in config.status
+ CONFIG_HEADERS="" $(SHELL) ./config.status
+
+config.status: configure configure.srv
+ $(SHELL) ./config.status --recheck
+
+force:
+
+version.c: Makefile
+ echo 'char *version = "$(VERSION)";' >version.c
+
+# GNU Make has an annoying habit of putting *all* the Makefile variables
+# into the environment, unless you include this target as a circumvention.
+# Rumor is that this will be fixed (and this target can be removed)
+# in GNU Make 4.0.
+.NOEXPORT:
+
+# GNU Make 3.63 has a different problem: it keeps tacking command line
+# overrides onto the definition of $(MAKE). This variable setting
+# will remove them.
+MAKEOVERRIDES=
+
+## This is ugly, but I don't want GNU make to put these variables in
+## the environment. Older makes will see this as a set of targets
+## with no dependencies and no actions.
+unexport CHILLFLAGS CHILL_LIB CHILL_FOR_TARGET :
+
+regdat_sh = $(srcdir)/../regformats/regdat.sh
+regdef_h = $(srcdir)/../regformats/regdef.h
+regcache_h = $(srcdir)/regcache.h
+server_h = $(srcdir)/server.h $(regcache_h) config.h $(srcdir)/target.h \
+ $(srcdir)/mem-break.h
+
+inferiors.o: inferiors.c $(server_h)
+mem-break.o: mem-break.c $(server_h)
+regcache.o: regcache.c $(server_h) $(regdef_h)
+remote-utils.o: remote-utils.c terminal.h $(server_h)
+server.o: server.c $(server_h)
+target.o: target.c $(server_h)
+utils.o: utils.c $(server_h)
+
+signals.o: ../signals/signals.c $(server_h)
+ $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+
+i387-fp.o: i387-fp.c $(server_h)
+
+linux_low_h = $(srcdir)/linux-low.h
+
+linux-low.o: linux-low.c $(linux_low_h) $(server_h)
+linux-arm-low.o: linux-arm-low.c $(linux_low_h) $(server_h)
+linux-i386-low.o: linux-i386-low.c $(linux_low_h) $(server_h)
+linux-ia64-low.o: linux-ia64-low.c $(linux_low_h) $(server_h)
+linux-mips-low.o: linux-mips-low.c $(linux_low_h) $(server_h)
+linux-ppc-low.o: linux-ppc-low.c $(linux_low_h) $(server_h)
+linux-s390-low.o: linux-s390-low.c $(linux_low_h) $(server_h)
+linux-sh-low.o: linux-sh-low.c $(linux_low_h) $(server_h)
+linux-x86-64-low.o: linux-x86-64-low.c $(linux_low_h) $(server_h)
+
+reg-arm.o : reg-arm.c $(regdef_h)
+reg-arm.c : $(srcdir)/../regformats/reg-arm.dat $(regdat_sh)
+ sh $(regdat_sh) $(srcdir)/../regformats/reg-arm.dat reg-arm.c
+reg-i386.o : reg-i386.c $(regdef_h)
+reg-i386.c : $(srcdir)/../regformats/reg-i386.dat $(regdat_sh)
+ sh $(regdat_sh) $(srcdir)/../regformats/reg-i386.dat reg-i386.c
+reg-i386-linux.o : reg-i386-linux.c $(regdef_h)
+reg-i386-linux.c : $(srcdir)/../regformats/reg-i386-linux.dat $(regdat_sh)
+ sh $(regdat_sh) $(srcdir)/../regformats/reg-i386-linux.dat reg-i386-linux.c
+reg-ia64.o : reg-ia64.c $(regdef_h)
+reg-ia64.c : $(srcdir)/../regformats/reg-ia64.dat $(regdat_sh)
+ sh $(regdat_sh) $(srcdir)/../regformats/reg-ia64.dat reg-ia64.c
+reg-m68k.o : reg-m68k.c $(regdef_h)
+reg-m68k.c : $(srcdir)/../regformats/reg-m68k.dat $(regdat_sh)
+ sh $(regdat_sh) $(srcdir)/../regformats/reg-m68k.dat reg-m68k.c
+reg-mips.o : reg-mips.c $(regdef_h)
+reg-mips.c : $(srcdir)/../regformats/reg-mips.dat $(regdat_sh)
+ sh $(regdat_sh) $(srcdir)/../regformats/reg-mips.dat reg-mips.c
+reg-ppc.o : reg-ppc.c $(regdef_h)
+reg-ppc.c : $(srcdir)/../regformats/reg-ppc.dat $(regdat_sh)
+ sh $(regdat_sh) $(srcdir)/../regformats/reg-ppc.dat reg-ppc.c
+reg-s390.o : reg-s390.c $(regdef_h)
+reg-s390.c : $(srcdir)/../regformats/reg-s390.dat $(regdat_sh)
+ sh $(regdat_sh) $(srcdir)/../regformats/reg-s390.dat reg-s390.c
+reg-s390x.o : reg-s390x.c $(regdef_h)
+reg-s390x.c : $(srcdir)/../regformats/reg-s390x.dat $(regdat_sh)
+ sh $(regdat_sh) $(srcdir)/../regformats/reg-s390x.dat reg-s390x.c
+reg-sh.o : reg-sh.c $(regdef_h)
+reg-sh.c : $(srcdir)/../regformats/reg-sh.dat $(regdat_sh)
+ sh $(regdat_sh) $(srcdir)/../regformats/reg-sh.dat reg-sh.c
+reg-x86-64.o : reg-x86-64.c $(regdef_h)
+reg-x86-64.c : $(srcdir)/../regformats/reg-x86-64.dat $(regdat_sh)
+ sh $(regdat_sh) $(srcdir)/../regformats/reg-x86-64.dat reg-x86-64.c
+
+# This is the end of "Makefile.in".
diff --git a/gdb/gdbserver/README b/gdb/gdbserver/README
new file mode 100644
index 00000000000..71887cae290
--- /dev/null
+++ b/gdb/gdbserver/README
@@ -0,0 +1,138 @@
+ README for GDBserver & GDBreplay
+ by Stu Grossman and Fred Fish
+
+Introduction:
+
+This is GDBserver, a remote server for Un*x-like systems. It can be used to
+control the execution of a program on a target system from a GDB on a different
+host. GDB and GDBserver communicate using the standard remote serial protocol
+implemented in remote.c, and various *-stub.c files. They communicate via
+either a serial line or a TCP connection.
+
+Usage (server (target) side):
+
+First, you need to have a copy of the program you want to debug put onto
+the target system. The program can be stripped to save space if needed, as
+GDBserver doesn't care about symbols. All symbol handling is taken care of by
+the GDB running on the host system.
+
+To use the server, you log on to the target system, and run the `gdbserver'
+program. You must tell it (a) how to communicate with GDB, (b) the name of
+your program, and (c) its arguments. The general syntax is:
+
+ target> gdbserver COMM PROGRAM [ARGS ...]
+
+For example, using a serial port, you might say:
+
+ target> gdbserver /dev/com1 emacs foo.txt
+
+This tells gdbserver to debug emacs with an argument of foo.txt, and to
+communicate with GDB via /dev/com1. Gdbserver now waits patiently for the
+host GDB to communicate with it.
+
+To use a TCP connection, you could say:
+
+ target> gdbserver host:2345 emacs foo.txt
+
+This says pretty much the same thing as the last example, except that we are
+going to communicate with the host GDB via TCP. The `host:2345' argument means
+that we are expecting to see a TCP connection from `host' to local TCP port
+2345. (Currently, the `host' part is ignored.) You can choose any number you
+want for the port number as long as it does not conflict with any existing TCP
+ports on the target system. This same port number must be used in the host
+GDBs `target remote' command, which will be described shortly. Note that if
+you chose a port number that conflicts with another service, gdbserver will
+print an error message and exit.
+
+On some targets, gdbserver can also attach to running programs. This is
+accomplished via the --attach argument. The syntax is:
+
+ target> gdbserver COMM --attach PID
+
+PID is the process ID of a currently running process. It isn't necessary
+to point gdbserver at a binary for the running process.
+
+Usage (host side):
+
+You need an unstripped copy of the target program on your host system, since
+GDB needs to examine it's symbol tables and such. Start up GDB as you normally
+would, with the target program as the first argument. (You may need to use the
+--baud option if the serial line is running at anything except 9600 baud.)
+Ie: `gdb TARGET-PROG', or `gdb --baud BAUD TARGET-PROG'. After that, the only
+new command you need to know about is `target remote'. It's argument is either
+a device name (usually a serial device, like `/dev/ttyb'), or a HOST:PORT
+descriptor. For example:
+
+ (gdb) target remote /dev/ttyb
+
+communicates with the server via serial line /dev/ttyb, and:
+
+ (gdb) target remote the-target:2345
+
+communicates via a TCP connection to port 2345 on host `the-target', where
+you previously started up gdbserver with the same port number. Note that for
+TCP connections, you must start up gdbserver prior to using the `target remote'
+command, otherwise you may get an error that looks something like
+`Connection refused'.
+
+Building gdbserver:
+
+The supported targets as of February 2002 are:
+ arm-*-linux-gnu
+ i386-*-linux-gnu
+ ia64-*-linux-gnu
+ m68k-*-linux-gnu
+ mips-*-linux-gnu
+ powerpc-*-linux-gnu
+ sh-*-linux-gnu
+
+Configuring gdbserver you should specify the same machine for host and
+target (which are the machine that gdbserver is going to run on. This
+is not the same as the machine that gdb is going to run on; building
+gdbserver automatically as part of building a whole tree of tools does
+not currently work if cross-compilation is involved (we don't get the
+right CC in the Makefile, to start with)).
+
+Building gdbserver for your target is very straightforward. If you build
+GDB natively on a target which gdbserver supports, it will be built
+automatically when you build GDB. You can also build just gdbserver:
+
+ % mkdir obj
+ % cd obj
+ % path-to-gdbserver-sources/configure
+ % make
+
+If you prefer to cross-compile to your target, then you can also build
+gdbserver that way. In a Bourne shell, for example:
+
+ % export CC=your-cross-compiler
+ % path-to-gdbserver-sources/configure your-target-name
+ % make
+
+Using GDBreplay:
+
+A special hacked down version of gdbserver can be used to replay remote
+debug log files created by gdb. Before using the gdb "target" command to
+initiate a remote debug session, use "set remotelogfile <filename>" to tell
+gdb that you want to make a recording of the serial or tcp session. Note
+that when replaying the session, gdb communicates with gdbreplay via tcp,
+regardless of whether the original session was via a serial link or tcp.
+
+Once you are done with the remote debug session, start gdbreplay and
+tell it the name of the log file and the host and port number that gdb
+should connect to (typically the same as the host running gdb):
+
+ $ gdbreplay logfile host:port
+
+Then start gdb (preferably in a different screen or window) and use the
+"target" command to connect to gdbreplay:
+
+ (gdb) target remote host:port
+
+Repeat the same sequence of user commands to gdb that you gave in the
+original debug session. Gdb should not be able to tell that it is talking
+to gdbreplay rather than a real target, all other things being equal. Note
+that gdbreplay echos the command lines to stderr, as well as the contents of
+the packets it sends and receives. The last command echoed by gdbreplay is
+the next command that needs to be typed to gdb to continue the session in
+sync with the original session.
diff --git a/gdb/gdbserver/acconfig.h b/gdb/gdbserver/acconfig.h
new file mode 100644
index 00000000000..968feb8b436
--- /dev/null
+++ b/gdb/gdbserver/acconfig.h
@@ -0,0 +1,9 @@
+/* Define if the target supports PTRACE_PEEKUSR for register access. */
+#undef HAVE_LINUX_USRREGS
+
+/* Define if the target supports PTRACE_GETREGS for register access. */
+#undef HAVE_LINUX_REGSETS
+
+/* Define if the target supports PTRACE_GETFPXREGS for extended
+ register access. */
+#undef HAVE_PTRACE_GETFPXREGS
diff --git a/gdb/gdbserver/acinclude.m4 b/gdb/gdbserver/acinclude.m4
new file mode 100644
index 00000000000..bbfa86f16c5
--- /dev/null
+++ b/gdb/gdbserver/acinclude.m4
@@ -0,0 +1,41 @@
+dnl gdb/gdbserver/configure.in uses BFD_HAVE_SYS_PROCFS_TYPE.
+sinclude(../../bfd/acinclude.m4)
+
+AC_DEFUN([SRV_CHECK_THREAD_DB],
+[AC_CACHE_CHECK([for libthread_db],[srv_cv_thread_db],
+ [old_LIBS="$LIBS"
+ LIBS="$LIBS -lthread_db"
+ AC_TRY_LINK(
+ [void ps_pglobal_lookup() {}
+ void ps_pdread() {}
+ void ps_pdwrite() {}
+ void ps_lgetregs() {}
+ void ps_lsetregs() {}
+ void ps_lgetfpregs() {}
+ void ps_lsetfpregs() {}
+ void ps_getpid() {}],
+ [td_ta_new();],
+ [srv_cv_thread_db="-lthread_db"],
+ [srv_cv_thread_db=no
+
+ if test "$prefix" = "/usr" || test "$prefix" = "NONE"; then
+ thread_db="/lib/libthread_db.so.1"
+ else
+ thread_db='$prefix/lib/libthread_db.so.1'
+ fi
+ LIBS="$old_LIBS `eval echo "$thread_db"`"
+ AC_TRY_LINK(
+ [void ps_pglobal_lookup() {}
+ void ps_pdread() {}
+ void ps_pdwrite() {}
+ void ps_lgetregs() {}
+ void ps_lsetregs() {}
+ void ps_lgetfpregs() {}
+ void ps_lsetfpregs() {}
+ void ps_getpid() {}],
+ [td_ta_new();],
+ [srv_cv_thread_db="$thread_db"],
+ [srv_cv_thread_db=no])
+ LIBS="$old_LIBS"
+ ]])
+)])
diff --git a/gdb/gdbserver/aclocal.m4 b/gdb/gdbserver/aclocal.m4
new file mode 100644
index 00000000000..24b9ced2835
--- /dev/null
+++ b/gdb/gdbserver/aclocal.m4
@@ -0,0 +1,100 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4-p4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+
+# serial 1
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so. This macro tries various
+# options that select ANSI C on some system or another. It considers the
+# compiler to be in ANSI C mode if it handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+AC_DEFUN(AM_PROG_CC_STDC,
+[AC_REQUIRE([AC_PROG_CC])
+AC_BEFORE([$0], [AC_C_INLINE])
+AC_BEFORE([$0], [AC_C_CONST])
+dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require
+dnl a magic option to avoid problems with ANSI preprocessor commands
+dnl like #elif.
+dnl FIXME: can't do this because then AC_AIX won't work due to a
+dnl circular dependency.
+dnl AC_BEFORE([$0], [AC_PROG_CPP])
+AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C)
+AC_CACHE_VAL(am_cv_prog_cc_stdc,
+[am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ AC_TRY_COMPILE(
+[#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+], [
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+],
+[am_cv_prog_cc_stdc="$ac_arg"; break])
+done
+CC="$ac_save_CC"
+])
+if test -z "$am_cv_prog_cc_stdc"; then
+ AC_MSG_RESULT([none needed])
+else
+ AC_MSG_RESULT($am_cv_prog_cc_stdc)
+fi
+case "x$am_cv_prog_cc_stdc" in
+ x|xno) ;;
+ *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+])
+
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
new file mode 100644
index 00000000000..9d553f220be
--- /dev/null
+++ b/gdb/gdbserver/config.in
@@ -0,0 +1,29 @@
+/* config.in. Generated automatically from configure.in by autoheader 2.13. */
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if the target supports PTRACE_PEEKUSR for register access. */
+#undef HAVE_LINUX_USRREGS
+
+/* Define if the target supports PTRACE_GETREGS for register access. */
+#undef HAVE_LINUX_REGSETS
+
+/* Define if the target supports PTRACE_GETFPXREGS for extended
+ register access. */
+#undef HAVE_PTRACE_GETFPXREGS
+
+/* Define if you have the <sgtty.h> header file. */
+#undef HAVE_SGTTY_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/reg.h> header file. */
+#undef HAVE_SYS_REG_H
+
+/* Define if you have the <termio.h> header file. */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
new file mode 100755
index 00000000000..758d48383f1
--- /dev/null
+++ b/gdb/gdbserver/configure
@@ -0,0 +1,1606 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=server.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:530: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:560: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:611: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:643: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 654 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:659: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:685: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:690: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:699: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+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
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:718: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:797: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:818: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:836: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:871: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ 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
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:925: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 940 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:946: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 957 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:963: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 974 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:980: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1005: checking for ANSI C header files" >&5
+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 1010 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1018: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+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 1035 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+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 1053 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1074 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1085: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+
+for ac_hdr in sgtty.h termio.h termios.h sys/reg.h string.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1113: checking for $ac_hdr" >&5
+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 1118 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1123: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+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 | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+. ${srcdir}/configure.srv
+
+if test "${srv_linux_usrregs}" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LINUX_USRREGS 1
+EOF
+
+fi
+
+if test "${srv_linux_regsets}" = "yes"; then
+ echo $ac_n "checking for PTRACE_GETREGS""... $ac_c" 1>&6
+echo "configure:1161: checking for PTRACE_GETREGS" >&5
+ if eval "test \"`echo '$''{'gdbsrv_cv_have_ptrace_getregs'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1166 "configure"
+#include "confdefs.h"
+#include <sys/ptrace.h>
+int main() {
+PTRACE_GETREGS;
+; return 0; }
+EOF
+if { (eval echo configure:1173: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdbsrv_cv_have_ptrace_getregs=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdbsrv_cv_have_ptrace_getregs=no
+fi
+rm -f conftest*
+fi
+
+ echo "$ac_t""$gdbsrv_cv_have_ptrace_getregs" 1>&6
+ if test "${gdbsrv_cv_have_ptrace_getregs}" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LINUX_REGSETS 1
+EOF
+
+ fi
+
+ echo $ac_n "checking for PTRACE_GETFPXREGS""... $ac_c" 1>&6
+echo "configure:1194: checking for PTRACE_GETFPXREGS" >&5
+ if eval "test \"`echo '$''{'gdbsrv_cv_have_ptrace_getfpxregs'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1199 "configure"
+#include "confdefs.h"
+#include <sys/ptrace.h>
+int main() {
+PTRACE_GETFPXREGS;
+; return 0; }
+EOF
+if { (eval echo configure:1206: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gdbsrv_cv_have_ptrace_getfpxregs=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gdbsrv_cv_have_ptrace_getfpxregs=no
+fi
+rm -f conftest*
+fi
+
+ echo "$ac_t""$gdbsrv_cv_have_ptrace_getfpxregs" 1>&6
+ if test "${gdbsrv_cv_have_ptrace_getfpxregs}" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PTRACE_GETFPXREGS 1
+EOF
+
+ fi
+fi
+
+GDBSERVER_DEPFILES="$srv_regobj $srv_tgtobj"
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@CPP@%$CPP%g
+s%@GDBSERVER_DEPFILES@%$GDBSERVER_DEPFILES%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+case x$CONFIG_HEADERS in
+xconfig.h:config.in)
+echo > stamp-h ;;
+esac
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/gdbserver/configure.in b/gdb/gdbserver/configure.in
new file mode 100644
index 00000000000..db7e301934b
--- /dev/null
+++ b/gdb/gdbserver/configure.in
@@ -0,0 +1,74 @@
+dnl Autoconf configure script for GDB server.
+dnl Copyright 2000, 2002 Free Software Foundation, Inc.
+dnl
+dnl This file is part of GDB.
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT(server.c)
+AC_CONFIG_HEADER(config.h:config.in)
+
+AC_PROG_CC
+
+AC_CANONICAL_SYSTEM
+
+AC_PROG_INSTALL
+
+AC_HEADER_STDC
+
+AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h)
+
+. ${srcdir}/configure.srv
+
+if test "${srv_linux_usrregs}" = "yes"; then
+ AC_DEFINE(HAVE_LINUX_USRREGS)
+fi
+
+if test "${srv_linux_regsets}" = "yes"; then
+ AC_MSG_CHECKING(for PTRACE_GETREGS)
+ AC_CACHE_VAL(gdbsrv_cv_have_ptrace_getregs,
+ [AC_TRY_COMPILE([#include <sys/ptrace.h>],
+ [PTRACE_GETREGS;],
+ [gdbsrv_cv_have_ptrace_getregs=yes],
+ [gdbsrv_cv_have_ptrace_getregs=no])])
+ AC_MSG_RESULT($gdbsrv_cv_have_ptrace_getregs)
+ if test "${gdbsrv_cv_have_ptrace_getregs}" = "yes"; then
+ AC_DEFINE(HAVE_LINUX_REGSETS)
+ fi
+
+ AC_MSG_CHECKING(for PTRACE_GETFPXREGS)
+ AC_CACHE_VAL(gdbsrv_cv_have_ptrace_getfpxregs,
+ [AC_TRY_COMPILE([#include <sys/ptrace.h>],
+ [PTRACE_GETFPXREGS;],
+ [gdbsrv_cv_have_ptrace_getfpxregs=yes],
+ [gdbsrv_cv_have_ptrace_getfpxregs=no])])
+ AC_MSG_RESULT($gdbsrv_cv_have_ptrace_getfpxregs)
+ if test "${gdbsrv_cv_have_ptrace_getfpxregs}" = "yes"; then
+ AC_DEFINE(HAVE_PTRACE_GETFPXREGS)
+ fi
+fi
+
+GDBSERVER_DEPFILES="$srv_regobj $srv_tgtobj"
+
+AC_SUBST(GDBSERVER_DEPFILES)
+
+AC_OUTPUT(Makefile,
+[case x$CONFIG_HEADERS in
+xconfig.h:config.in)
+echo > stamp-h ;;
+esac
+])
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
new file mode 100644
index 00000000000..3268cd77207
--- /dev/null
+++ b/gdb/gdbserver/configure.srv
@@ -0,0 +1,65 @@
+# Mappings from configuration triplets to gdbserver build options.
+# This is invoked from the autoconf-generated configure script, to
+# produce the appropriate Makefile substitutions.
+
+# This file sets the following shell variables:
+# srv_regobj The register protocol appropriate for this target.
+# srv_tgtobj Any other target-specific modules appropriate
+# for this target.
+#
+# In addition, on GNU/Linux the following shell variables will be set:
+# srv_linux_regsets Set to "yes" if ptrace(PTRACE_GETREGS) and friends
+# may be available on this platform; unset otherwise.
+# They will only be used if <sys/ptrace.h> defines
+# PTRACE_GETREGS.
+# srv_linux_usrregs Set to "yes" if we can get at registers via
+# PTRACE_PEEKUSR / PTRACE_POKEUSR.
+
+# Input is taken from the "${target}" variable.
+
+case "${target}" in
+ arm*-*-linux*) srv_regobj=reg-arm.o
+ srv_tgtobj="linux-low.o linux-arm-low.o"
+ srv_linux_usrregs=yes
+ ;;
+ i[3456]86-*-linux*) srv_regobj=reg-i386-linux.o
+ srv_tgtobj="linux-low.o linux-i386-low.o i387-fp.o"
+ srv_linux_usrregs=yes
+ srv_linux_regsets=yes
+ ;;
+ ia64-*-linux*) srv_regobj=reg-ia64.o
+ srv_tgtobj="linux-low.o linux-ia64-low.o"
+ srv_linux_usrregs=yes
+ ;;
+ m68*-*-linux*) srv_regobj=reg-m68k.o
+ srv_tgtobj="linux-low.o linux-m68k-low.o"
+ srv_linux_usrregs=yes
+ ;;
+ mips*-*-linux*) srv_regobj=reg-mips.o
+ srv_tgtobj="linux-low.o linux-mips-low.o"
+ srv_linux_usrregs=yes
+ ;;
+ powerpc*-*-linux*) srv_regobj=reg-ppc.o
+ srv_tgtobj="linux-low.o linux-ppc-low.o"
+ srv_linux_usrregs=yes
+ ;;
+ s390-*-linux*) srv_regobj=reg-s390.o
+ srv_tgtobj="linux-low.o linux-s390-low.o"
+ srv_linux_usrregs=yes
+ ;;
+ s390x-*-linux*) srv_regobj=reg-s390x.o
+ srv_tgtobj="linux-low.o linux-s390-low.o"
+ srv_linux_usrregs=yes
+ ;;
+ sh*-*-linux*) srv_regobj=reg-sh.o
+ srv_tgtobj="linux-low.o linux-sh-low.o"
+ srv_linux_usrregs=yes
+ ;;
+ x86_64-*-linux*) srv_regobj=reg-x86-64.o
+ srv_tgtobj="linux-low.o linux-x86-64-low.o i387-fp.o"
+ srv_linux_regsets=yes
+ ;;
+ *) echo "Error: target not supported by gdbserver."
+ exit 1
+ ;;
+esac
diff --git a/gdb/gdbserver/gdbreplay.c b/gdb/gdbserver/gdbreplay.c
new file mode 100644
index 00000000000..65831b1d762
--- /dev/null
+++ b/gdb/gdbserver/gdbreplay.c
@@ -0,0 +1,324 @@
+/* Replay a remote debug session logfile for GDB.
+ Copyright 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
+ Written by Fred Fish (fnf@cygnus.com) from pieces of gdbserver.
+
+ 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 "config.h"
+#include <stdio.h>
+#include <sys/file.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/tcp.h>
+#include <signal.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+/* Sort of a hack... */
+#define EOL (EOF - 1)
+
+static int remote_desc;
+
+/* Print the system error message for errno, and also mention STRING
+ as the file name for which the error was encountered.
+ Then return to command level. */
+
+void
+perror_with_name (char *string)
+{
+#ifndef STDC_HEADERS
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+ extern int errno;
+#endif
+ const char *err;
+ char *combined;
+
+ err = (errno < sys_nerr) ? sys_errlist[errno] : "unknown error";
+ combined = (char *) alloca (strlen (err) + strlen (string) + 3);
+ strcpy (combined, string);
+ strcat (combined, ": ");
+ strcat (combined, err);
+ fprintf (stderr, "\n%s.\n", combined);
+ fflush (stderr);
+ exit (1);
+}
+
+static void
+sync_error (FILE *fp, char *desc, int expect, int got)
+{
+ fprintf (stderr, "\n%s\n", desc);
+ fprintf (stderr, "At logfile offset %ld, expected '0x%x' got '0x%x'\n",
+ ftell (fp), expect, got);
+ fflush (stderr);
+ exit (1);
+}
+
+void
+remote_close (void)
+{
+ close (remote_desc);
+}
+
+/* Open a connection to a remote debugger.
+ NAME is the filename used for communication. */
+
+void
+remote_open (char *name)
+{
+ if (!strchr (name, ':'))
+ {
+ fprintf (stderr, "%s: Must specify tcp connection as host:addr\n", name);
+ fflush (stderr);
+ exit (1);
+ }
+ else
+ {
+ char *port_str;
+ int port;
+ struct sockaddr_in sockaddr;
+ int tmp;
+ int tmp_desc;
+
+ port_str = strchr (name, ':');
+
+ port = atoi (port_str + 1);
+
+ tmp_desc = socket (PF_INET, SOCK_STREAM, 0);
+ if (tmp_desc < 0)
+ perror_with_name ("Can't open socket");
+
+ /* Allow rapid reuse of this port. */
+ tmp = 1;
+ setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
+ sizeof (tmp));
+
+ sockaddr.sin_family = PF_INET;
+ sockaddr.sin_port = htons (port);
+ sockaddr.sin_addr.s_addr = INADDR_ANY;
+
+ if (bind (tmp_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
+ || listen (tmp_desc, 1))
+ perror_with_name ("Can't bind address");
+
+ tmp = sizeof (sockaddr);
+ remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp);
+ if (remote_desc == -1)
+ perror_with_name ("Accept failed");
+
+ /* Enable TCP keep alive process. */
+ tmp = 1;
+ setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *) &tmp, sizeof (tmp));
+
+ /* Tell TCP not to delay small packets. This greatly speeds up
+ interactive response. */
+ tmp = 1;
+ setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
+ (char *) &tmp, sizeof (tmp));
+
+ close (tmp_desc); /* No longer need this */
+
+ signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbreplay simply
+ exits when the remote side dies. */
+ }
+
+ fcntl (remote_desc, F_SETFL, FASYNC);
+
+ fprintf (stderr, "Replay logfile using %s\n", name);
+ fflush (stderr);
+}
+
+static int
+tohex (int ch)
+{
+ if (ch >= '0' && ch <= '9')
+ {
+ return (ch - '0');
+ }
+ if (ch >= 'A' && ch <= 'F')
+ {
+ return (ch - 'A' + 10);
+ }
+ if (ch >= 'a' && ch <= 'f')
+ {
+ return (ch - 'a' + 10);
+ }
+ fprintf (stderr, "\nInvalid hex digit '%c'\n", ch);
+ fflush (stderr);
+ exit (1);
+}
+
+static int
+logchar (FILE *fp)
+{
+ int ch;
+ int ch2;
+
+ ch = fgetc (fp);
+ fputc (ch, stdout);
+ fflush (stdout);
+ switch (ch)
+ {
+ case '\n':
+ ch = EOL;
+ break;
+ case '\\':
+ ch = fgetc (fp);
+ fputc (ch, stdout);
+ fflush (stdout);
+ switch (ch)
+ {
+ case '\\':
+ break;
+ case 'b':
+ ch = '\b';
+ break;
+ case 'f':
+ ch = '\f';
+ break;
+ case 'n':
+ ch = '\n';
+ break;
+ case 'r':
+ ch = '\r';
+ break;
+ case 't':
+ ch = '\t';
+ break;
+ case 'v':
+ ch = '\v';
+ break;
+ case 'x':
+ ch2 = fgetc (fp);
+ fputc (ch2, stdout);
+ fflush (stdout);
+ ch = tohex (ch2) << 4;
+ ch2 = fgetc (fp);
+ fputc (ch2, stdout);
+ fflush (stdout);
+ ch |= tohex (ch2);
+ break;
+ default:
+ /* Treat any other char as just itself */
+ break;
+ }
+ default:
+ break;
+ }
+ return (ch);
+}
+
+/* Accept input from gdb and match with chars from fp (after skipping one
+ blank) up until a \n is read from fp (which is not matched) */
+
+void
+expect (FILE *fp)
+{
+ int fromlog;
+ unsigned char fromgdb;
+
+ if ((fromlog = logchar (fp)) != ' ')
+ {
+ sync_error (fp, "Sync error during gdb read of leading blank", ' ',
+ fromlog);
+ }
+ do
+ {
+ fromlog = logchar (fp);
+ if (fromlog == EOL)
+ {
+ break;
+ }
+ read (remote_desc, &fromgdb, 1);
+ }
+ while (fromlog == fromgdb);
+ if (fromlog != EOL)
+ {
+ sync_error (fp, "Sync error during read of gdb packet", fromlog,
+ fromgdb);
+ }
+}
+
+/* Play data back to gdb from fp (after skipping leading blank) up until a
+ \n is read from fp (which is discarded and not sent to gdb). */
+
+void
+play (FILE *fp)
+{
+ int fromlog;
+ char ch;
+
+ if ((fromlog = logchar (fp)) != ' ')
+ {
+ sync_error (fp, "Sync error skipping blank during write to gdb", ' ',
+ fromlog);
+ }
+ while ((fromlog = logchar (fp)) != EOL)
+ {
+ ch = fromlog;
+ write (remote_desc, &ch, 1);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ FILE *fp;
+ int ch;
+
+ if (argc < 3)
+ {
+ fprintf (stderr, "Usage: gdbreplay <logfile> <host:port>\n");
+ fflush (stderr);
+ exit (1);
+ }
+ fp = fopen (argv[1], "r");
+ if (fp == NULL)
+ {
+ perror_with_name (argv[1]);
+ }
+ remote_open (argv[2]);
+ while ((ch = logchar (fp)) != EOF)
+ {
+ switch (ch)
+ {
+ case 'w':
+ /* data sent from gdb to gdbreplay, accept and match it */
+ expect (fp);
+ break;
+ case 'r':
+ /* data sent from gdbreplay to gdb, play it */
+ play (fp);
+ break;
+ case 'c':
+ /* Command executed by gdb */
+ while ((ch = logchar (fp)) != EOL);
+ break;
+ }
+ }
+ remote_close ();
+ exit (0);
+}
diff --git a/gdb/gdbserver/gdbserver.1 b/gdb/gdbserver/gdbserver.1
new file mode 100644
index 00000000000..846634b7ca5
--- /dev/null
+++ b/gdb/gdbserver/gdbserver.1
@@ -0,0 +1,116 @@
+.\" Copyright 1993 Free Software Foundation, Inc.
+.\" See section COPYING for conditions for redistribution
+.TH gdbserver 1 "2 November 1993" "Cygnus Support" "GNU Development Tools"
+.SH NAME
+gdbserver \- Remote Server for the GNU Debugger
+.SH SYNOPSIS
+.na
+.TP
+.B gdbserver
+.RB tty
+.RB prog
+.RB "[\|" args... "\|]"
+.PP
+.B gdbserver
+.RB tty
+.B --attach
+.RB PID
+.ad b
+.SH DESCRIPTION
+GDBSERVER is a program that allows you to run GDB on a different machine
+than the one which is running the program being debugged.
+
+Usage (server (target) side):
+
+First, you need to have a copy of the program you want to debug put onto
+the target system. The program can be stripped to save space if needed, as
+GDBserver doesn't care about symbols. All symbol handling is taken care of by
+the GDB running on the host system.
+
+To use the server, you log on to the target system, and run the `gdbserver'
+program. You must tell it (a) how to communicate with GDB, (b) the name of
+your program, and (c) its arguments. The general syntax is:
+
+ target> gdbserver COMM PROGRAM [ARGS ...]
+
+For example, using a serial port, you might say:
+
+ target> gdbserver /dev/com1 emacs foo.txt
+
+This tells gdbserver to debug emacs with an argument of foo.txt, and to
+communicate with GDB via /dev/com1. Gdbserver now waits patiently for the
+host GDB to communicate with it.
+
+To use a TCP connection, you could say:
+
+ target> gdbserver host:2345 emacs foo.txt
+
+This says pretty much the same thing as the last example, except that we are
+going to communicate with the host GDB via TCP. The `host:2345' argument means
+that we are expecting to see a TCP connection from `host' to local TCP port
+2345. (Currently, the `host' part is ignored.) You can choose any number you
+want for the port number as long as it does not conflict with any existing TCP
+ports on the target system. This same port number must be used in the host
+GDBs `target remote' command, which will be described shortly. Note that if
+you chose a port number that conflicts with another service, gdbserver will
+print an error message and exit.
+
+On some targets, gdbserver can also attach to running programs.
+This is accomplished via the --attach argument. The syntax is:
+
+ target> gdbserver COMM --attach PID
+
+PID is the process ID of a currently running process. It isn't
+necessary to point gdbserver at a binary for the running process.
+
+Usage (host side):
+
+You need an unstripped copy of the target program on your host system, since
+GDB needs to examine it's symbol tables and such. Start up GDB as you normally
+would, with the target program as the first argument. (You may need to use the
+--baud option if the serial line is running at anything except 9600 baud.)
+Ie: `gdb TARGET-PROG', or `gdb --baud BAUD TARGET-PROG'. After that, the only
+new command you need to know about is `target remote'. It's argument is either
+a device name (usually a serial device, like `/dev/ttyb'), or a HOST:PORT
+descriptor. For example:
+
+ (gdb) target remote /dev/ttyb
+
+communicates with the server via serial line /dev/ttyb, and:
+
+ (gdb) target remote the-target:2345
+
+communicates via a TCP connection to port 2345 on host `the-target', where
+you previously started up gdbserver with the same port number. Note that for
+TCP connections, you must start up gdbserver prior to using the `target remote'
+command, otherwise you may get an error that looks something like
+`Connection refused'.
+.SH OPTIONS
+You have to supply the name of the program to debug
+and the tty to communicate on; the remote GDB will do everything else.
+Any remaining arguments will be passed to the program verbatim.
+.SH "SEE ALSO"
+.RB "`\|" gdb "\|'"
+entry in
+.B info\c
+\&;
+.I
+Using GDB: A Guide to the GNU Source-Level Debugger\c
+, Richard M. Stallman and Roland H. Pesch, July 1991.
+.SH COPYING
+Copyright (c) 1993 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be included in
+translations approved by the Free Software Foundation instead of in
+the original English.
diff --git a/gdb/gdbserver/i387-fp.c b/gdb/gdbserver/i387-fp.c
new file mode 100644
index 00000000000..3d1d6a6fd5c
--- /dev/null
+++ b/gdb/gdbserver/i387-fp.c
@@ -0,0 +1,290 @@
+/* i387-specific utility functions, for the remote server for GDB.
+ Copyright 2000, 2001, 2002
+ 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 "server.h"
+
+int num_xmm_registers = 8;
+
+/* Note: These functions preserve the reserved bits in control registers.
+ However, gdbserver promptly throws away that information. */
+
+/* These structs should have the proper sizes and alignment on both
+ i386 and x86-64 machines. */
+
+struct i387_fsave {
+ /* All these are only sixteen bits, plus padding, except for fop (which
+ is only eleven bits), and fooff / fioff (which are 32 bits each). */
+ unsigned int fctrl;
+ unsigned int fstat;
+ unsigned int ftag;
+ unsigned int fioff;
+ unsigned short fiseg;
+ unsigned short fop;
+ unsigned int fooff;
+ unsigned int foseg;
+
+ /* Space for eight 80-bit FP values. */
+ char st_space[80];
+};
+
+struct i387_fxsave {
+ /* All these are only sixteen bits, plus padding, except for fop (which
+ is only eleven bits), and fooff / fioff (which are 32 bits each). */
+ unsigned short fctrl;
+ unsigned short fstat;
+ unsigned short ftag;
+ unsigned short fop;
+ unsigned int fioff;
+ unsigned int fiseg;
+ unsigned int fooff;
+ unsigned int foseg;
+
+ unsigned int mxcsr;
+
+ unsigned int _pad1;
+
+ /* Space for eight 80-bit FP values in 128-bit spaces. */
+ char st_space[128];
+
+ /* Space for eight 128-bit XMM values, or 16 on x86-64. */
+ char xmm_space[256];
+};
+
+void
+i387_cache_to_fsave (void *buf)
+{
+ struct i387_fsave *fp = (struct i387_fsave *) buf;
+ int i;
+ int st0_regnum = find_regno ("st0");
+ unsigned long val, val2;
+
+ for (i = 0; i < 8; i++)
+ collect_register (i + st0_regnum, ((char *) &fp->st_space[0]) + i * 10);
+
+ collect_register_by_name ("fioff", &fp->fioff);
+ collect_register_by_name ("fooff", &fp->fooff);
+
+ /* This one's 11 bits... */
+ collect_register_by_name ("fop", &val2);
+ fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
+
+ /* Some registers are 16-bit. */
+ collect_register_by_name ("fctrl", &val);
+ *(unsigned short *) &fp->fctrl = val;
+
+ collect_register_by_name ("fstat", &val);
+ val &= 0xFFFF;
+ *(unsigned short *) &fp->fstat = val;
+
+ collect_register_by_name ("ftag", &val);
+ val &= 0xFFFF;
+ *(unsigned short *) &fp->ftag = val;
+
+ collect_register_by_name ("fiseg", &val);
+ val &= 0xFFFF;
+ *(unsigned short *) &fp->fiseg = val;
+
+ collect_register_by_name ("foseg", &val);
+ val &= 0xFFFF;
+ *(unsigned short *) &fp->foseg = val;
+}
+
+void
+i387_fsave_to_cache (void *buf)
+{
+ struct i387_fsave *fp = (struct i387_fsave *) buf;
+ int i;
+ int st0_regnum = find_regno ("st0");
+ unsigned long val;
+
+ for (i = 0; i < 8; i++)
+ supply_register (i + st0_regnum, ((char *) &fp->st_space[0]) + i * 10);
+
+ supply_register_by_name ("fioff", &fp->fioff);
+ supply_register_by_name ("fooff", &fp->fooff);
+
+ /* Some registers are 16-bit. */
+ val = fp->fctrl & 0xFFFF;
+ supply_register_by_name ("fctrl", &val);
+
+ val = fp->fstat & 0xFFFF;
+ supply_register_by_name ("fstat", &val);
+
+ val = fp->ftag & 0xFFFF;
+ supply_register_by_name ("ftag", &val);
+
+ val = fp->fiseg & 0xFFFF;
+ supply_register_by_name ("fiseg", &val);
+
+ val = fp->foseg & 0xFFFF;
+ supply_register_by_name ("foseg", &val);
+
+ val = (fp->fop) & 0x7FF;
+ supply_register_by_name ("fop", &val);
+}
+
+void
+i387_cache_to_fxsave (void *buf)
+{
+ struct i387_fxsave *fp = (struct i387_fxsave *) buf;
+ int i;
+ int st0_regnum = find_regno ("st0");
+ int xmm0_regnum = find_regno ("xmm0");
+ unsigned long val, val2;
+
+ for (i = 0; i < 8; i++)
+ collect_register (i + st0_regnum, ((char *) &fp->st_space[0]) + i * 16);
+ for (i = 0; i < num_xmm_registers; i++)
+ collect_register (i + xmm0_regnum, ((char *) &fp->xmm_space[0]) + i * 16);
+
+ collect_register_by_name ("fioff", &fp->fioff);
+ collect_register_by_name ("fooff", &fp->fooff);
+ collect_register_by_name ("mxcsr", &fp->mxcsr);
+
+ /* This one's 11 bits... */
+ collect_register_by_name ("fop", &val2);
+ fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
+
+ /* Some registers are 16-bit. */
+ collect_register_by_name ("fctrl", &val);
+ *(unsigned short *) &fp->fctrl = val;
+
+ collect_register_by_name ("fstat", &val);
+ val &= 0xFFFF;
+ *(unsigned short *) &fp->fstat = val;
+
+ /* Convert to the simplifed tag form stored in fxsave data. */
+ collect_register_by_name ("ftag", &val);
+ val &= 0xFFFF;
+ for (i = 7; i >= 0; i--)
+ {
+ int tag = (val >> (i * 2)) & 3;
+
+ if (tag != 3)
+ val2 |= (1 << i);
+ }
+ *(unsigned short *) &fp->ftag = val2;
+
+ collect_register_by_name ("fiseg", &val);
+ val &= 0xFFFF;
+ *(unsigned short *) &fp->fiseg = val;
+
+ collect_register_by_name ("foseg", &val);
+ val &= 0xFFFF;
+ *(unsigned short *) &fp->foseg = val;
+}
+
+static int
+i387_ftag (struct i387_fxsave *fp, int regno)
+{
+ unsigned char *raw = &fp->st_space[regno * 16];
+ unsigned int exponent;
+ unsigned long fraction[2];
+ int integer;
+
+ integer = raw[7] & 0x80;
+ exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
+ fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
+ fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
+ | (raw[5] << 8) | raw[4]);
+
+ if (exponent == 0x7fff)
+ {
+ /* Special. */
+ return (2);
+ }
+ else if (exponent == 0x0000)
+ {
+ if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
+ {
+ /* Zero. */
+ return (1);
+ }
+ else
+ {
+ /* Special. */
+ return (2);
+ }
+ }
+ else
+ {
+ if (integer)
+ {
+ /* Valid. */
+ return (0);
+ }
+ else
+ {
+ /* Special. */
+ return (2);
+ }
+ }
+}
+
+void
+i387_fxsave_to_cache (void *buf)
+{
+ struct i387_fxsave *fp = (struct i387_fxsave *) buf;
+ int i, top;
+ int st0_regnum = find_regno ("st0");
+ int xmm0_regnum = find_regno ("xmm0");
+ unsigned long val;
+
+ for (i = 0; i < 8; i++)
+ supply_register (i + st0_regnum, ((char *) &fp->st_space[0]) + i * 16);
+ for (i = 0; i < num_xmm_registers; i++)
+ supply_register (i + xmm0_regnum, ((char *) &fp->xmm_space[0]) + i * 16);
+
+ supply_register_by_name ("fioff", &fp->fioff);
+ supply_register_by_name ("fooff", &fp->fooff);
+ supply_register_by_name ("mxcsr", &fp->mxcsr);
+
+ /* Some registers are 16-bit. */
+ val = fp->fctrl & 0xFFFF;
+ supply_register_by_name ("fctrl", &val);
+
+ val = fp->fstat & 0xFFFF;
+ supply_register_by_name ("fstat", &val);
+
+ /* Generate the form of ftag data that GDB expects. */
+ top = (fp->fstat >> 11) & 0x7;
+ val = 0;
+ for (i = 7; i >= 0; i--)
+ {
+ int tag;
+ if (val & (1 << i))
+ tag = i387_ftag (fp, (i + 8 - top) % 8);
+ else
+ tag = 3;
+ val |= tag << (2 * i);
+ }
+ supply_register_by_name ("ftag", &val);
+
+ val = fp->fiseg & 0xFFFF;
+ supply_register_by_name ("fiseg", &val);
+
+ val = fp->foseg & 0xFFFF;
+ supply_register_by_name ("foseg", &val);
+
+ val = (fp->fop) & 0x7FF;
+ supply_register_by_name ("fop", &val);
+}
+
diff --git a/gdb/gdbserver/i387-fp.h b/gdb/gdbserver/i387-fp.h
new file mode 100644
index 00000000000..90fe4ca6eb7
--- /dev/null
+++ b/gdb/gdbserver/i387-fp.h
@@ -0,0 +1,33 @@
+/* i387-specific utility functions, for the remote server for GDB.
+ Copyright 2000, 2001, 2002
+ 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. */
+
+#ifndef I387_FP_H
+#define I387_FP_H
+
+void i387_cache_to_fsave (void *buf);
+void i387_fsave_to_cache (void *buf);
+
+void i387_cache_to_fxsave (void *buf);
+void i387_fxsave_to_cache (void *buf);
+
+extern int num_xmm_registers;
+
+#endif /* I387_FP_H */
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
new file mode 100644
index 00000000000..774798deae3
--- /dev/null
+++ b/gdb/gdbserver/inferiors.c
@@ -0,0 +1,105 @@
+/* Inferior process information for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ 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 <stdlib.h>
+
+#include "server.h"
+
+struct inferior_info
+{
+ int pid;
+ void *target_data;
+ void *regcache_data;
+ struct inferior_info *next;
+};
+
+static struct inferior_info *inferiors;
+struct inferior_info *current_inferior;
+int signal_pid;
+
+void
+add_inferior (int pid)
+{
+ struct inferior_info *new_inferior
+ = (struct inferior_info *) malloc (sizeof (*new_inferior));
+
+ memset (new_inferior, 0, sizeof (*new_inferior));
+
+ new_inferior->pid = pid;
+
+ new_inferior->next = inferiors;
+ inferiors = new_inferior;
+
+ if (current_inferior == NULL)
+ current_inferior = inferiors;
+
+ create_register_cache (new_inferior);
+
+ if (signal_pid == 0)
+ signal_pid = pid;
+}
+
+void
+clear_inferiors (void)
+{
+ struct inferior_info *inf = inferiors, *next_inf;
+
+ while (inf)
+ {
+ next_inf = inf->next;
+
+ if (inf->target_data)
+ free (inf->target_data);
+ if (inf->regcache_data)
+ free_register_cache (inf);
+
+ free (inf);
+ inf = next_inf;
+ }
+
+ inferiors = NULL;
+}
+
+void *
+inferior_target_data (struct inferior_info *inferior)
+{
+ return inferior->target_data;
+}
+
+void
+set_inferior_target_data (struct inferior_info *inferior, void *data)
+{
+ inferior->target_data = data;
+}
+
+void *
+inferior_regcache_data (struct inferior_info *inferior)
+{
+ return inferior->regcache_data;
+}
+
+void
+set_inferior_regcache_data (struct inferior_info *inferior, void *data)
+{
+ inferior->regcache_data = data;
+}
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
new file mode 100644
index 00000000000..2958fdf3129
--- /dev/null
+++ b/gdb/gdbserver/linux-arm-low.c
@@ -0,0 +1,53 @@
+/* GNU/Linux/ARM specific low level interface, for the remote server for GDB.
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ 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 "server.h"
+#include "linux-low.h"
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+#define arm_num_regs 16
+
+static int arm_regmap[] = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ 32, 36, 40, 44, 48, 52, 56, 60,
+};
+
+static int
+arm_cannot_store_register (int regno)
+{
+ return (regno >= arm_num_regs);
+}
+
+static int
+arm_cannot_fetch_register (int regno)
+{
+ return (regno >= arm_num_regs);
+}
+
+struct linux_target_ops the_low_target = {
+ arm_num_regs,
+ arm_regmap,
+ arm_cannot_fetch_register,
+ arm_cannot_store_register,
+};
diff --git a/gdb/gdbserver/linux-i386-low.c b/gdb/gdbserver/linux-i386-low.c
new file mode 100644
index 00000000000..71264321341
--- /dev/null
+++ b/gdb/gdbserver/linux-i386-low.c
@@ -0,0 +1,157 @@
+/* GNU/Linux/i386 specific low level interface, for the remote server for GDB.
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ 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 "server.h"
+#include "linux-low.h"
+#include "i387-fp.h"
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+/* This module only supports access to the general purpose registers. */
+
+#define i386_num_regs 16
+
+/* This stuff comes from i386-linux-nat.c. */
+
+/* Mapping between the general-purpose registers in `struct user'
+ format and GDB's register array layout. */
+static int i386_regmap[] =
+{
+ EAX * 4, ECX * 4, EDX * 4, EBX * 4,
+ UESP * 4, EBP * 4, ESI * 4, EDI * 4,
+ EIP * 4, EFL * 4, CS * 4, SS * 4,
+ DS * 4, ES * 4, FS * 4, GS * 4
+};
+
+static int
+i386_cannot_store_register (int regno)
+{
+ return (regno >= i386_num_regs);
+}
+
+static int
+i386_cannot_fetch_register (int regno)
+{
+ return (regno >= i386_num_regs);
+}
+
+
+#ifdef HAVE_LINUX_REGSETS
+#include <sys/procfs.h>
+#include <sys/ptrace.h>
+
+static void
+i386_fill_gregset (void *buf)
+{
+ int i;
+
+ for (i = 0; i < i386_num_regs; i++)
+ collect_register (i, ((char *) buf) + i386_regmap[i]);
+
+ collect_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4);
+}
+
+static void
+i386_store_gregset (void *buf)
+{
+ int i;
+
+ for (i = 0; i < i386_num_regs; i++)
+ supply_register (i, ((char *) buf) + i386_regmap[i]);
+
+ supply_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4);
+}
+
+static void
+i386_fill_fpregset (void *buf)
+{
+ i387_cache_to_fsave (buf);
+}
+
+static void
+i386_store_fpregset (void *buf)
+{
+ i387_fsave_to_cache (buf);
+}
+
+static void
+i386_fill_fpxregset (void *buf)
+{
+ i387_cache_to_fxsave (buf);
+}
+
+static void
+i386_store_fpxregset (void *buf)
+{
+ i387_fxsave_to_cache (buf);
+}
+
+
+struct regset_info target_regsets[] = {
+ { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
+ i386_fill_gregset, i386_store_gregset },
+#ifdef HAVE_PTRACE_GETFPXREGS
+ { PTRACE_GETFPXREGS, PTRACE_SETFPXREGS, sizeof (elf_fpxregset_t),
+ i386_fill_fpxregset, i386_store_fpxregset },
+#endif
+ { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
+ i386_fill_fpregset, i386_store_fpregset },
+ { 0, 0, -1, NULL, NULL }
+};
+
+#endif /* HAVE_LINUX_REGSETS */
+
+static const char i386_breakpoint[] = { 0xCC };
+#define i386_breakpoint_len 1
+
+static CORE_ADDR
+i386_stop_pc ()
+{
+ unsigned long pc;
+
+ /* Overkill */
+ fetch_inferior_registers (0);
+
+ collect_register_by_name ("eip", &pc);
+ return pc - 1;
+}
+
+static void
+i386_set_pc (CORE_ADDR newpc)
+{
+ supply_register_by_name ("eip", &newpc);
+
+ /* Overkill */
+ store_inferior_registers (0);
+}
+
+struct linux_target_ops the_low_target = {
+ i386_num_regs,
+ i386_regmap,
+ i386_cannot_fetch_register,
+ i386_cannot_store_register,
+ i386_stop_pc,
+ i386_set_pc,
+ i386_breakpoint,
+ i386_breakpoint_len,
+};
diff --git a/gdb/gdbserver/linux-ia64-low.c b/gdb/gdbserver/linux-ia64-low.c
new file mode 100644
index 00000000000..9407e6cbcf7
--- /dev/null
+++ b/gdb/gdbserver/linux-ia64-low.c
@@ -0,0 +1,303 @@
+/* GNU/Linux/IA64 specific low level interface, for the remote server for GDB.
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ 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 "server.h"
+#include "linux-low.h"
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+#define ia64_num_regs 590
+
+#include <asm/ptrace_offsets.h>
+
+static int ia64_regmap[] =
+ {
+ /* general registers */
+ -1, /* gr0 not available; i.e, it's always zero */
+ PT_R1,
+ PT_R2,
+ PT_R3,
+ PT_R4,
+ PT_R5,
+ PT_R6,
+ PT_R7,
+ PT_R8,
+ PT_R9,
+ PT_R10,
+ PT_R11,
+ PT_R12,
+ PT_R13,
+ PT_R14,
+ PT_R15,
+ PT_R16,
+ PT_R17,
+ PT_R18,
+ PT_R19,
+ PT_R20,
+ PT_R21,
+ PT_R22,
+ PT_R23,
+ PT_R24,
+ PT_R25,
+ PT_R26,
+ PT_R27,
+ PT_R28,
+ PT_R29,
+ PT_R30,
+ PT_R31,
+ /* gr32 through gr127 not directly available via the ptrace interface */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ /* Floating point registers */
+ -1, -1, /* f0 and f1 not available (f0 is +0.0 and f1 is +1.0) */
+ PT_F2,
+ PT_F3,
+ PT_F4,
+ PT_F5,
+ PT_F6,
+ PT_F7,
+ PT_F8,
+ PT_F9,
+ PT_F10,
+ PT_F11,
+ PT_F12,
+ PT_F13,
+ PT_F14,
+ PT_F15,
+ PT_F16,
+ PT_F17,
+ PT_F18,
+ PT_F19,
+ PT_F20,
+ PT_F21,
+ PT_F22,
+ PT_F23,
+ PT_F24,
+ PT_F25,
+ PT_F26,
+ PT_F27,
+ PT_F28,
+ PT_F29,
+ PT_F30,
+ PT_F31,
+ PT_F32,
+ PT_F33,
+ PT_F34,
+ PT_F35,
+ PT_F36,
+ PT_F37,
+ PT_F38,
+ PT_F39,
+ PT_F40,
+ PT_F41,
+ PT_F42,
+ PT_F43,
+ PT_F44,
+ PT_F45,
+ PT_F46,
+ PT_F47,
+ PT_F48,
+ PT_F49,
+ PT_F50,
+ PT_F51,
+ PT_F52,
+ PT_F53,
+ PT_F54,
+ PT_F55,
+ PT_F56,
+ PT_F57,
+ PT_F58,
+ PT_F59,
+ PT_F60,
+ PT_F61,
+ PT_F62,
+ PT_F63,
+ PT_F64,
+ PT_F65,
+ PT_F66,
+ PT_F67,
+ PT_F68,
+ PT_F69,
+ PT_F70,
+ PT_F71,
+ PT_F72,
+ PT_F73,
+ PT_F74,
+ PT_F75,
+ PT_F76,
+ PT_F77,
+ PT_F78,
+ PT_F79,
+ PT_F80,
+ PT_F81,
+ PT_F82,
+ PT_F83,
+ PT_F84,
+ PT_F85,
+ PT_F86,
+ PT_F87,
+ PT_F88,
+ PT_F89,
+ PT_F90,
+ PT_F91,
+ PT_F92,
+ PT_F93,
+ PT_F94,
+ PT_F95,
+ PT_F96,
+ PT_F97,
+ PT_F98,
+ PT_F99,
+ PT_F100,
+ PT_F101,
+ PT_F102,
+ PT_F103,
+ PT_F104,
+ PT_F105,
+ PT_F106,
+ PT_F107,
+ PT_F108,
+ PT_F109,
+ PT_F110,
+ PT_F111,
+ PT_F112,
+ PT_F113,
+ PT_F114,
+ PT_F115,
+ PT_F116,
+ PT_F117,
+ PT_F118,
+ PT_F119,
+ PT_F120,
+ PT_F121,
+ PT_F122,
+ PT_F123,
+ PT_F124,
+ PT_F125,
+ PT_F126,
+ PT_F127,
+ /* predicate registers - we don't fetch these individually */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ /* branch registers */
+ PT_B0,
+ PT_B1,
+ PT_B2,
+ PT_B3,
+ PT_B4,
+ PT_B5,
+ PT_B6,
+ PT_B7,
+ /* virtual frame pointer and virtual return address pointer */
+ -1, -1,
+ /* other registers */
+ PT_PR,
+ PT_CR_IIP, /* ip */
+ PT_CR_IPSR, /* psr */
+ PT_CFM, /* cfm */
+ /* kernel registers not visible via ptrace interface (?) */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ /* hole */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ PT_AR_RSC,
+ PT_AR_BSP,
+ PT_AR_BSPSTORE,
+ PT_AR_RNAT,
+ -1,
+ -1, /* Not available: FCR, IA32 floating control register */
+ -1, -1,
+ -1, /* Not available: EFLAG */
+ -1, /* Not available: CSD */
+ -1, /* Not available: SSD */
+ -1, /* Not available: CFLG */
+ -1, /* Not available: FSR */
+ -1, /* Not available: FIR */
+ -1, /* Not available: FDR */
+ -1,
+ PT_AR_CCV,
+ -1, -1, -1,
+ PT_AR_UNAT,
+ -1, -1, -1,
+ PT_AR_FPSR,
+ -1, -1, -1,
+ -1, /* Not available: ITC */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ PT_AR_PFS,
+ PT_AR_LC,
+ -1, /* Not available: EC, the Epilog Count register */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1,
+ /* nat bits - not fetched directly; instead we obtain these bits from
+ either rnat or unat or from memory. */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ };
+
+static int
+ia64_cannot_store_register (int regno)
+{
+ return 0;
+}
+
+static int
+ia64_cannot_fetch_register (int regno)
+{
+ return 0;
+}
+
+struct linux_target_ops the_low_target = {
+ ia64_num_regs,
+ ia64_regmap,
+ ia64_cannot_fetch_register,
+ ia64_cannot_store_register,
+};
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
new file mode 100644
index 00000000000..6cfe0d5aea5
--- /dev/null
+++ b/gdb/gdbserver/linux-low.c
@@ -0,0 +1,590 @@
+/* Low level interface to ptrace, for the remote server for GDB.
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ 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 "server.h"
+#include "linux-low.h"
+
+#include <sys/wait.h>
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/ptrace.h>
+#include <sys/user.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static CORE_ADDR linux_bp_reinsert;
+
+static void linux_resume (int step, int signal);
+
+#define PTRACE_ARG3_TYPE long
+#define PTRACE_XFER_TYPE long
+
+#ifdef HAVE_LINUX_REGSETS
+static int use_regsets_p = 1;
+#endif
+
+extern int errno;
+
+static int inferior_pid;
+
+struct inferior_linux_data
+{
+ int pid;
+};
+
+/* Start an inferior process and returns its pid.
+ ALLARGS is a vector of program-name and args. */
+
+static int
+linux_create_inferior (char *program, char **allargs)
+{
+ struct inferior_linux_data *tdata;
+ int pid;
+
+ pid = fork ();
+ if (pid < 0)
+ perror_with_name ("fork");
+
+ if (pid == 0)
+ {
+ ptrace (PTRACE_TRACEME, 0, 0, 0);
+
+ execv (program, allargs);
+
+ fprintf (stderr, "Cannot exec %s: %s.\n", program,
+ strerror (errno));
+ fflush (stderr);
+ _exit (0177);
+ }
+
+ add_inferior (pid);
+ tdata = (struct inferior_linux_data *) malloc (sizeof (*tdata));
+ tdata->pid = pid;
+ set_inferior_target_data (current_inferior, tdata);
+
+ /* FIXME remove */
+ inferior_pid = pid;
+ return 0;
+}
+
+/* Attach to an inferior process. */
+
+static int
+linux_attach (int pid)
+{
+ struct inferior_linux_data *tdata;
+
+ if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0)
+ {
+ fprintf (stderr, "Cannot attach to process %d: %s (%d)\n", pid,
+ errno < sys_nerr ? sys_errlist[errno] : "unknown error",
+ errno);
+ fflush (stderr);
+ _exit (0177);
+ }
+
+ add_inferior (pid);
+ tdata = (struct inferior_linux_data *) malloc (sizeof (*tdata));
+ tdata->pid = pid;
+ set_inferior_target_data (current_inferior, tdata);
+ return 0;
+}
+
+/* Kill the inferior process. Make us have no inferior. */
+
+static void
+linux_kill (void)
+{
+ if (inferior_pid == 0)
+ return;
+ ptrace (PTRACE_KILL, inferior_pid, 0, 0);
+ wait (0);
+ clear_inferiors ();
+}
+
+/* Return nonzero if the given thread is still alive. */
+static int
+linux_thread_alive (int pid)
+{
+ return 1;
+}
+
+static int
+linux_wait_for_one_inferior (struct inferior_info *child)
+{
+ struct inferior_linux_data *child_data = inferior_target_data (child);
+ int pid, wstat;
+
+ while (1)
+ {
+ pid = waitpid (child_data->pid, &wstat, 0);
+
+ if (pid != child_data->pid)
+ perror_with_name ("wait");
+
+ /* If this target supports breakpoints, see if we hit one. */
+ if (the_low_target.stop_pc != NULL
+ && WIFSTOPPED (wstat)
+ && WSTOPSIG (wstat) == SIGTRAP)
+ {
+ CORE_ADDR stop_pc;
+
+ if (linux_bp_reinsert != 0)
+ {
+ reinsert_breakpoint (linux_bp_reinsert);
+ linux_bp_reinsert = 0;
+ linux_resume (0, 0);
+ continue;
+ }
+
+ fetch_inferior_registers (0);
+ stop_pc = (*the_low_target.stop_pc) ();
+
+ if (check_breakpoints (stop_pc) != 0)
+ {
+ if (the_low_target.set_pc != NULL)
+ (*the_low_target.set_pc) (stop_pc);
+
+ if (the_low_target.breakpoint_reinsert_addr == NULL)
+ {
+ linux_bp_reinsert = stop_pc;
+ uninsert_breakpoint (stop_pc);
+ linux_resume (1, 0);
+ }
+ else
+ {
+ reinsert_breakpoint_by_bp
+ (stop_pc, (*the_low_target.breakpoint_reinsert_addr) ());
+ linux_resume (0, 0);
+ }
+
+ continue;
+ }
+ }
+
+ return wstat;
+ }
+ /* NOTREACHED */
+ return 0;
+}
+
+/* Wait for process, returns status */
+
+static unsigned char
+linux_wait (char *status)
+{
+ int w;
+
+ enable_async_io ();
+ w = linux_wait_for_one_inferior (current_inferior);
+ disable_async_io ();
+
+ if (WIFEXITED (w))
+ {
+ fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
+ *status = 'W';
+ clear_inferiors ();
+ return ((unsigned char) WEXITSTATUS (w));
+ }
+ else if (!WIFSTOPPED (w))
+ {
+ fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
+ clear_inferiors ();
+ *status = 'X';
+ return ((unsigned char) WTERMSIG (w));
+ }
+
+ fetch_inferior_registers (0);
+
+ *status = 'T';
+ return ((unsigned char) WSTOPSIG (w));
+}
+
+/* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+static void
+linux_resume (int step, int signal)
+{
+ errno = 0;
+ ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
+ if (errno)
+ perror_with_name ("ptrace");
+}
+
+
+#ifdef HAVE_LINUX_USRREGS
+
+#define REGISTER_RAW_SIZE(regno) register_size((regno))
+
+int
+register_addr (int regnum)
+{
+ int addr;
+
+ if (regnum < 0 || regnum >= the_low_target.num_regs)
+ error ("Invalid register number %d.", regnum);
+
+ addr = the_low_target.regmap[regnum];
+ if (addr == -1)
+ addr = 0;
+
+ return addr;
+}
+
+/* Fetch one register. */
+static void
+fetch_register (int regno)
+{
+ CORE_ADDR regaddr;
+ register int i;
+
+ if (regno >= the_low_target.num_regs)
+ return;
+ if ((*the_low_target.cannot_fetch_register) (regno))
+ return;
+
+ regaddr = register_addr (regno);
+ if (regaddr == -1)
+ return;
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ *(PTRACE_XFER_TYPE *) (register_data (regno) + i) =
+ ptrace (PTRACE_PEEKUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, 0);
+ regaddr += sizeof (PTRACE_XFER_TYPE);
+ if (errno != 0)
+ {
+ /* Warning, not error, in case we are attached; sometimes the
+ kernel doesn't let us at the registers. */
+ char *err = strerror (errno);
+ char *msg = alloca (strlen (err) + 128);
+ sprintf (msg, "reading register %d: %s", regno, err);
+ error (msg);
+ goto error_exit;
+ }
+ }
+error_exit:;
+}
+
+/* Fetch all registers, or just one, from the child process. */
+static void
+usr_fetch_inferior_registers (int regno)
+{
+ if (regno == -1 || regno == 0)
+ for (regno = 0; regno < the_low_target.num_regs; regno++)
+ fetch_register (regno);
+ else
+ fetch_register (regno);
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+static void
+usr_store_inferior_registers (int regno)
+{
+ CORE_ADDR regaddr;
+ int i;
+
+ if (regno >= 0)
+ {
+ if (regno >= the_low_target.num_regs)
+ return;
+
+ if ((*the_low_target.cannot_store_register) (regno) == 1)
+ return;
+
+ regaddr = register_addr (regno);
+ if (regaddr == -1)
+ return;
+ errno = 0;
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
+ *(int *) (register_data (regno) + i));
+ if (errno != 0)
+ {
+ if ((*the_low_target.cannot_store_register) (regno) == 0)
+ {
+ char *err = strerror (errno);
+ char *msg = alloca (strlen (err) + 128);
+ sprintf (msg, "writing register %d: %s",
+ regno, err);
+ error (msg);
+ return;
+ }
+ }
+ regaddr += sizeof (int);
+ }
+ }
+ else
+ for (regno = 0; regno < the_low_target.num_regs; regno++)
+ store_inferior_registers (regno);
+}
+#endif /* HAVE_LINUX_USRREGS */
+
+
+
+#ifdef HAVE_LINUX_REGSETS
+
+static int
+regsets_fetch_inferior_registers (void)
+{
+ struct regset_info *regset;
+
+ regset = target_regsets;
+
+ while (regset->size >= 0)
+ {
+ void *buf;
+ int res;
+
+ if (regset->size == 0)
+ {
+ regset ++;
+ continue;
+ }
+
+ buf = malloc (regset->size);
+ res = ptrace (regset->get_request, inferior_pid, 0, buf);
+ if (res < 0)
+ {
+ if (errno == EIO)
+ {
+ /* If we get EIO on the first regset, do not try regsets again.
+ If we get EIO on a later regset, disable that regset. */
+ if (regset == target_regsets)
+ {
+ use_regsets_p = 0;
+ return -1;
+ }
+ else
+ {
+ regset->size = 0;
+ continue;
+ }
+ }
+ else
+ {
+ perror ("Warning: ptrace(regsets_fetch_inferior_registers)");
+ }
+ }
+ regset->store_function (buf);
+ regset ++;
+ }
+ return 0;
+}
+
+static int
+regsets_store_inferior_registers (void)
+{
+ struct regset_info *regset;
+
+ regset = target_regsets;
+
+ while (regset->size >= 0)
+ {
+ void *buf;
+ int res;
+
+ if (regset->size == 0)
+ {
+ regset ++;
+ continue;
+ }
+
+ buf = malloc (regset->size);
+ regset->fill_function (buf);
+ res = ptrace (regset->set_request, inferior_pid, 0, buf);
+ if (res < 0)
+ {
+ if (errno == EIO)
+ {
+ /* If we get EIO on the first regset, do not try regsets again.
+ If we get EIO on a later regset, disable that regset. */
+ if (regset == target_regsets)
+ {
+ use_regsets_p = 0;
+ return -1;
+ }
+ else
+ {
+ regset->size = 0;
+ continue;
+ }
+ }
+ else
+ {
+ perror ("Warning: ptrace(regsets_store_inferior_registers)");
+ }
+ }
+ regset ++;
+ }
+ return 0;
+}
+
+#endif /* HAVE_LINUX_REGSETS */
+
+
+void
+linux_fetch_registers (int regno)
+{
+#ifdef HAVE_LINUX_REGSETS
+ if (use_regsets_p)
+ {
+ if (regsets_fetch_inferior_registers () == 0)
+ return;
+ }
+#endif
+#ifdef HAVE_LINUX_USRREGS
+ usr_fetch_inferior_registers (regno);
+#endif
+}
+
+void
+linux_store_registers (int regno)
+{
+#ifdef HAVE_LINUX_REGSETS
+ if (use_regsets_p)
+ {
+ if (regsets_store_inferior_registers () == 0)
+ return;
+ }
+#endif
+#ifdef HAVE_LINUX_USRREGS
+ usr_store_inferior_registers (regno);
+#endif
+}
+
+
+/* Copy LEN bytes from inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. */
+
+static void
+linux_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
+ / sizeof (PTRACE_XFER_TYPE);
+ /* Allocate buffer of that many longwords. */
+ register PTRACE_XFER_TYPE *buffer
+ = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
+
+ /* Read all the longwords */
+ for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
+ {
+ buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0);
+ }
+
+ /* Copy appropriate bytes out of the buffer. */
+ memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len);
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+ to inferior's memory at MEMADDR.
+ On failure (cannot write the inferior)
+ returns the value of errno. */
+
+static int
+linux_write_memory (CORE_ADDR memaddr, const char *myaddr, int len)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) / sizeof (PTRACE_XFER_TYPE);
+ /* Allocate buffer of that many longwords. */
+ register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
+ extern int errno;
+
+ /* Fill start and end extra bytes of buffer with existing memory data. */
+
+ buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid,
+ (PTRACE_ARG3_TYPE) addr, 0);
+
+ if (count > 1)
+ {
+ buffer[count - 1]
+ = ptrace (PTRACE_PEEKTEXT, inferior_pid,
+ (PTRACE_ARG3_TYPE) (addr + (count - 1)
+ * sizeof (PTRACE_XFER_TYPE)),
+ 0);
+ }
+
+ /* Copy data to be written over corresponding part of buffer */
+
+ memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), myaddr, len);
+
+ /* Write the entire buffer. */
+
+ for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ ptrace (PTRACE_POKETEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]);
+ if (errno)
+ return errno;
+ }
+
+ return 0;
+}
+
+static void
+linux_look_up_symbols (void)
+{
+ /* Don't need to look up any symbols yet. */
+}
+
+
+static struct target_ops linux_target_ops = {
+ linux_create_inferior,
+ linux_attach,
+ linux_kill,
+ linux_thread_alive,
+ linux_resume,
+ linux_wait,
+ linux_fetch_registers,
+ linux_store_registers,
+ linux_read_memory,
+ linux_write_memory,
+ linux_look_up_symbols,
+};
+
+void
+initialize_low (void)
+{
+ set_target_ops (&linux_target_ops);
+ set_breakpoint_data (the_low_target.breakpoint,
+ the_low_target.breakpoint_len);
+ init_registers ();
+}
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
new file mode 100644
index 00000000000..b484982e15e
--- /dev/null
+++ b/gdb/gdbserver/linux-low.h
@@ -0,0 +1,49 @@
+/* Internal interfaces for the GNU/Linux specific target code for gdbserver.
+ Copyright 2002, 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. */
+
+#ifdef HAVE_LINUX_REGSETS
+typedef void (*regset_func) (void *);
+struct regset_info
+{
+ int get_request, set_request;
+ int size;
+ regset_func fill_function, store_function;
+};
+extern struct regset_info target_regsets[];
+#endif
+
+struct linux_target_ops
+{
+ int num_regs;
+ int *regmap;
+ int (*cannot_fetch_register) (int);
+
+ /* Returns 0 if we can store the register, 1 if we can not
+ store the register, and 2 if failure to store the register
+ is acceptable. */
+ int (*cannot_store_register) (int);
+ CORE_ADDR (*stop_pc) (void);
+ void (*set_pc) (CORE_ADDR newpc);
+ const char *breakpoint;
+ int breakpoint_len;
+ CORE_ADDR (*breakpoint_reinsert_addr) (void);
+};
+
+extern struct linux_target_ops the_low_target;
diff --git a/gdb/gdbserver/linux-m68k-low.c b/gdb/gdbserver/linux-m68k-low.c
new file mode 100644
index 00000000000..760de6e0535
--- /dev/null
+++ b/gdb/gdbserver/linux-m68k-low.c
@@ -0,0 +1,72 @@
+/* GNU/Linux/m68k specific low level interface, for the remote server for GDB.
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ 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 "server.h"
+#include "linux-low.h"
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+#define m68k_num_regs 31
+
+/* This table must line up with REGISTER_NAMES in tm-m68k.h */
+static int m68k_regmap[] =
+{
+#ifdef PT_D0
+ PT_D0 * 4, PT_D1 * 4, PT_D2 * 4, PT_D3 * 4,
+ PT_D4 * 4, PT_D5 * 4, PT_D6 * 4, PT_D7 * 4,
+ PT_A0 * 4, PT_A1 * 4, PT_A2 * 4, PT_A3 * 4,
+ PT_A4 * 4, PT_A5 * 4, PT_A6 * 4, PT_USP * 4,
+ PT_SR * 4, PT_PC * 4,
+#else
+ 14 * 4, 0 * 4, 1 * 4, 2 * 4, 3 * 4, 4 * 4, 5 * 4, 6 * 4,
+ 7 * 4, 8 * 4, 9 * 4, 10 * 4, 11 * 4, 12 * 4, 13 * 4, 15 * 4,
+ 17 * 4, 18 * 4,
+#endif
+#ifdef PT_FP0
+ PT_FP0 * 4, PT_FP1 * 4, PT_FP2 * 4, PT_FP3 * 4,
+ PT_FP4 * 4, PT_FP5 * 4, PT_FP6 * 4, PT_FP7 * 4,
+ PT_FPCR * 4, PT_FPSR * 4, PT_FPIAR * 4
+#else
+ 21 * 4, 24 * 4, 27 * 4, 30 * 4, 33 * 4, 36 * 4,
+ 39 * 4, 42 * 4, 45 * 4, 46 * 4, 47 * 4
+#endif
+};
+
+static int
+m68k_cannot_store_register (int regno)
+{
+ return (regno >= m68k_num_regs);
+}
+
+static int
+m68k_cannot_fetch_register (int regno)
+{
+ return (regno >= m68k_num_regs);
+}
+
+struct linux_target_ops the_low_target = {
+ m68k_num_regs,
+ m68k_regmap,
+ m68k_cannot_fetch_register,
+ m68k_cannot_store_register,
+};
diff --git a/gdb/gdbserver/linux-mips-low.c b/gdb/gdbserver/linux-mips-low.c
new file mode 100644
index 00000000000..f721ec94eeb
--- /dev/null
+++ b/gdb/gdbserver/linux-mips-low.c
@@ -0,0 +1,104 @@
+/* GNU/Linux/MIPS specific low level interface, for the remote server for GDB.
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ 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 "server.h"
+#include "linux-low.h"
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+#define mips_num_regs 90
+
+#include <asm/ptrace.h>
+
+/* Return the ptrace ``address'' of register REGNO. */
+
+/* Matches mips_generic32_regs */
+static int mips_regmap[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+
+ -1, MMLO, MMHI, BADVADDR, CAUSE, PC,
+
+ FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3,
+ FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7,
+ FPR_BASE + 8, FPR_BASE + 8, FPR_BASE + 10, FPR_BASE + 11,
+ FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15,
+ FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19,
+ FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23,
+ FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27,
+ FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31,
+ FPC_CSR, FPC_EIR,
+
+ -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+/* From mips-linux-nat.c. */
+
+/* Pseudo registers can not be read. ptrace does not provide a way to
+ read (or set) PS_REGNUM, and there's no point in reading or setting
+ ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via
+ ptrace(). */
+
+static int
+mips_cannot_fetch_register (int regno)
+{
+ if (mips_regmap[regno] == -1)
+ return 1;
+
+ if (find_regno ("zero") == regno)
+ return 1;
+
+ return 0;
+}
+
+static int
+mips_cannot_store_register (int regno)
+{
+ if (mips_regmap[regno] == -1)
+ return 1;
+
+ if (find_regno ("zero") == regno)
+ return 1;
+
+ if (find_regno ("cause") == regno)
+ return 1;
+
+ if (find_regno ("bad") == regno)
+ return 1;
+
+ if (find_regno ("fir") == regno)
+ return 1;
+
+ return 0;
+}
+
+struct linux_target_ops the_low_target = {
+ mips_num_regs,
+ mips_regmap,
+ mips_cannot_fetch_register,
+ mips_cannot_store_register,
+};
diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c
new file mode 100644
index 00000000000..7cb315a304a
--- /dev/null
+++ b/gdb/gdbserver/linux-ppc-low.c
@@ -0,0 +1,72 @@
+/* GNU/Linux/PowerPC specific low level interface, for the remote server for
+ GDB.
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ 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 "server.h"
+#include "linux-low.h"
+
+#include <asm/ptrace.h>
+
+#define ppc_num_regs 71
+
+/* Currently, don't check/send MQ. */
+static int ppc_regmap[] =
+ {PT_R0 * 4, PT_R1 * 4, PT_R2 * 4, PT_R3 * 4,
+ PT_R4 * 4, PT_R5 * 4, PT_R6 * 4, PT_R7 * 4,
+ PT_R8 * 4, PT_R9 * 4, PT_R10 * 4, PT_R11 * 4,
+ PT_R12 * 4, PT_R13 * 4, PT_R14 * 4, PT_R15 * 4,
+ PT_R16 * 4, PT_R17 * 4, PT_R18 * 4, PT_R19 * 4,
+ PT_R20 * 4, PT_R21 * 4, PT_R22 * 4, PT_R23 * 4,
+ PT_R24 * 4, PT_R25 * 4, PT_R26 * 4, PT_R27 * 4,
+ PT_R28 * 4, PT_R29 * 4, PT_R30 * 4, PT_R31 * 4,
+ PT_FPR0*4, PT_FPR0*4 + 8, PT_FPR0*4+16, PT_FPR0*4+24,
+ PT_FPR0*4+32, PT_FPR0*4+40, PT_FPR0*4+48, PT_FPR0*4+56,
+ PT_FPR0*4+64, PT_FPR0*4+72, PT_FPR0*4+80, PT_FPR0*4+88,
+ PT_FPR0*4+96, PT_FPR0*4+104, PT_FPR0*4+112, PT_FPR0*4+120,
+ PT_FPR0*4+128, PT_FPR0*4+136, PT_FPR0*4+144, PT_FPR0*4+152,
+ PT_FPR0*4+160, PT_FPR0*4+168, PT_FPR0*4+176, PT_FPR0*4+184,
+ PT_FPR0*4+192, PT_FPR0*4+200, PT_FPR0*4+208, PT_FPR0*4+216,
+ PT_FPR0*4+224, PT_FPR0*4+232, PT_FPR0*4+240, PT_FPR0*4+248,
+ PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4,
+ PT_CTR * 4, PT_XER * 4, PT_FPSCR * 4, };
+
+static int
+ppc_cannot_store_register (int regno)
+{
+ /* Some kernels do not allow us to store fpscr. */
+ if (regno == find_regno ("fpscr"))
+ return 2;
+
+ return 0;
+}
+
+static int
+ppc_cannot_fetch_register (int regno)
+{
+ return 0;
+}
+
+struct linux_target_ops the_low_target = {
+ ppc_num_regs,
+ ppc_regmap,
+ ppc_cannot_fetch_register,
+ ppc_cannot_store_register,
+};
diff --git a/gdb/gdbserver/linux-s390-low.c b/gdb/gdbserver/linux-s390-low.c
new file mode 100644
index 00000000000..8d800ae8b5f
--- /dev/null
+++ b/gdb/gdbserver/linux-s390-low.c
@@ -0,0 +1,88 @@
+/* GNU/Linux S/390 specific low level interface, for the remote server
+ for GDB.
+ Copyright 2001, 2002
+ 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. */
+
+/* This file is used for both 31-bit and 64-bit S/390 systems. */
+
+#include "server.h"
+#include "linux-low.h"
+
+#include <asm/ptrace.h>
+
+#define s390_num_regs 67
+
+static int s390_regmap[] = {
+ PT_PSWMASK, PT_PSWADDR,
+
+ PT_GPR0, PT_GPR1, PT_GPR2, PT_GPR3,
+ PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
+ PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
+ PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15,
+
+ PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
+ PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
+ PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
+ PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
+
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, PT_CR_9, PT_CR_10, PT_CR_11,
+ -1, -1, -1, -1,
+
+ PT_FPC,
+
+#ifdef PT_FPR0_HI
+ PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
+ PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
+ PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
+ PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI,
+#else
+ PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3,
+ PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7,
+ PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11,
+ PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15,
+#endif
+};
+
+static int
+s390_cannot_fetch_register (int regno)
+{
+ if (s390_regmap[regno] == -1)
+ return 1;
+
+ return 0;
+}
+
+static int
+s390_cannot_store_register (int regno)
+{
+ if (s390_regmap[regno] == -1)
+ return 1;
+
+ return 0;
+}
+
+struct linux_target_ops the_low_target = {
+ s390_num_regs,
+ s390_regmap,
+ s390_cannot_fetch_register,
+ s390_cannot_store_register,
+};
diff --git a/gdb/gdbserver/linux-sh-low.c b/gdb/gdbserver/linux-sh-low.c
new file mode 100644
index 00000000000..cdc390d2332
--- /dev/null
+++ b/gdb/gdbserver/linux-sh-low.c
@@ -0,0 +1,65 @@
+/* GNU/Linux/SH specific low level interface, for the remote server for GDB.
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ 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 "server.h"
+#include "linux-low.h"
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+#include <asm/ptrace.h>
+
+#define sh_num_regs 41
+
+/* Currently, don't check/send MQ. */
+static int sh_regmap[] = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ 32, 36, 40, 44, 48, 52, 56, 60,
+
+ REG_PC*4, REG_PR*4, REG_GBR*4, -1,
+ REG_MACH*4, REG_MACL*4, REG_SR*4,
+ REG_FPUL*4, REG_FPSCR*4,
+
+ REG_FPREG0+0, REG_FPREG0+4, REG_FPREG0+8, REG_FPREG0+12,
+ REG_FPREG0+16, REG_FPREG0+20, REG_FPREG0+24, REG_FPREG0+28,
+ REG_FPREG0+32, REG_FPREG0+36, REG_FPREG0+40, REG_FPREG0+44,
+ REG_FPREG0+48, REG_FPREG0+52, REG_FPREG0+56, REG_FPREG0+60,
+};
+
+static int
+sh_cannot_store_register (int regno)
+{
+ return 0;
+}
+
+static int
+sh_cannot_fetch_register (int regno)
+{
+ return 0;
+}
+
+struct linux_target_ops the_low_target = {
+ sh_num_regs,
+ sh_regmap,
+ sh_cannot_fetch_register,
+ sh_cannot_store_register,
+};
diff --git a/gdb/gdbserver/linux-x86-64-low.c b/gdb/gdbserver/linux-x86-64-low.c
new file mode 100644
index 00000000000..e1248904aba
--- /dev/null
+++ b/gdb/gdbserver/linux-x86-64-low.c
@@ -0,0 +1,85 @@
+/* GNU/Linux/x86-64 specific low level interface, for the remote server
+ for GDB.
+ Copyright 2002
+ 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 "server.h"
+#include "linux-low.h"
+#include "i387-fp.h"
+
+#include <sys/reg.h>
+#include <sys/procfs.h>
+#include <sys/ptrace.h>
+
+#define X86_64_NUM_GREGS 22
+
+static int x86_64_regmap[X86_64_NUM_GREGS] = {
+ RAX, RBX, RCX, RDX,
+ RSI, RDI, RBP, RSP,
+ R8, R9, R10, R11,
+ R12, R13, R14, R15,
+ RIP, EFLAGS,
+ DS, ES, FS, GS
+};
+
+static void
+x86_64_fill_gregset (void *buf)
+{
+ int i;
+
+ for (i = 0; i < X86_64_NUM_GREGS; i++)
+ collect_register (i, ((char *) buf) + x86_64_regmap[i]);
+}
+
+static void
+x86_64_store_gregset (void *buf)
+{
+ int i;
+
+ for (i = 0; i < X86_64_NUM_GREGS; i++)
+ supply_register (i, ((char *) buf) + x86_64_regmap[i]);
+}
+
+static void
+x86_64_fill_fpregset (void *buf)
+{
+ i387_cache_to_fxsave (buf);
+}
+
+static void
+x86_64_store_fpregset (void *buf)
+{
+ i387_fxsave_to_cache (buf);
+}
+
+struct regset_info target_regsets[] = {
+ { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
+ x86_64_fill_gregset, x86_64_store_gregset },
+ { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
+ x86_64_fill_fpregset, x86_64_store_fpregset },
+ { 0, 0, -1, NULL, NULL }
+};
+
+struct linux_target_ops the_low_target = {
+ -1,
+ NULL,
+ NULL,
+ NULL,
+};
diff --git a/gdb/gdbserver/low-hppabsd.c b/gdb/gdbserver/low-hppabsd.c
new file mode 100644
index 00000000000..3287923d113
--- /dev/null
+++ b/gdb/gdbserver/low-hppabsd.c
@@ -0,0 +1,355 @@
+/* Low level interface to ptrace, for the remote server for GDB.
+ Copyright 1995, 1996, 1999, 2000, 2001, 2002 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 "server.h"
+#include <sys/wait.h>
+#include "frame.h"
+#include "inferior.h"
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sgtty.h>
+#include <fcntl.h>
+
+/***************Begin MY defs*********************/
+static char my_registers[REGISTER_BYTES];
+char *registers = my_registers;
+/***************End MY defs*********************/
+
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+extern int errno;
+
+/* Start an inferior process and returns its pid.
+ ALLARGS is a vector of program-name and args. */
+
+int
+create_inferior (char *program, char **allargs)
+{
+ int pid;
+
+ pid = fork ();
+ if (pid < 0)
+ perror_with_name ("fork");
+
+ if (pid == 0)
+ {
+ ptrace (PT_TRACE_ME, 0, 0, 0, 0);
+
+ execv (program, allargs);
+
+ fprintf (stderr, "Cannot exec %s: %s.\n", program,
+ errno < sys_nerr ? sys_errlist[errno] : "unknown error");
+ fflush (stderr);
+ _exit (0177);
+ }
+
+ return pid;
+}
+
+/* Kill the inferior process. Make us have no inferior. */
+
+void
+kill_inferior (void)
+{
+ if (inferior_pid == 0)
+ return;
+ ptrace (8, inferior_pid, 0, 0, 0);
+ wait (0);
+/*************inferior_died ();****VK**************/
+}
+
+/* Attaching is not supported. */
+int
+myattach (int pid)
+{
+ return -1;
+}
+
+/* Return nonzero if the given thread is still alive. */
+int
+mythread_alive (int pid)
+{
+ return 1;
+}
+
+/* Wait for process, returns status */
+
+unsigned char
+mywait (char *status)
+{
+ int pid;
+ union wait w;
+
+ enable_async_io ();
+ pid = waitpid (inferior_pid, &w, 0);
+ disable_async_io ();
+ if (pid != inferior_pid)
+ perror_with_name ("wait");
+
+ if (WIFEXITED (w))
+ {
+ fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
+ *status = 'W';
+ return ((unsigned char) WEXITSTATUS (w));
+ }
+ else if (!WIFSTOPPED (w))
+ {
+ fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
+ *status = 'X';
+ return ((unsigned char) WTERMSIG (w));
+ }
+
+ fetch_inferior_registers (0);
+
+ *status = 'T';
+ return ((unsigned char) WSTOPSIG (w));
+}
+
+/* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+void
+myresume (int step, int signal)
+{
+ errno = 0;
+ ptrace (step ? PT_STEP : PT_CONTINUE, inferior_pid, 1, signal, 0);
+ if (errno)
+ perror_with_name ("ptrace");
+}
+
+
+#if !defined (offsetof)
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+#endif
+
+/* U_REGS_OFFSET is the offset of the registers within the u area. */
+#if !defined (U_REGS_OFFSET)
+#define U_REGS_OFFSET \
+ ptrace (PT_READ_U, inferior_pid, \
+ (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
+ - KERNEL_U_ADDR
+#endif
+
+CORE_ADDR
+register_addr (int regno, CORE_ADDR blockend)
+{
+ CORE_ADDR addr;
+
+ if (regno < 0 || regno >= NUM_REGS)
+ error ("Invalid register number %d.", regno);
+
+ REGISTER_U_ADDR (addr, blockend, regno);
+
+ return addr;
+}
+
+/* Fetch one register. */
+
+static void
+fetch_register (int regno)
+{
+ register unsigned int regaddr;
+ char buf[MAX_REGISTER_RAW_SIZE];
+ register int i;
+
+ /* Offset of registers within the u area. */
+ unsigned int offset;
+
+ offset = U_REGS_OFFSET;
+
+ regaddr = register_addr (regno, offset);
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+ {
+ errno = 0;
+ *(int *) &registers[regno * 4 + i] = ptrace (PT_RUREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) regaddr, 0, 0);
+ regaddr += sizeof (int);
+ if (errno != 0)
+ {
+ /* Warning, not error, in case we are attached; sometimes the
+ kernel doesn't let us at the registers. */
+ char *err = strerror (errno);
+ char *msg = alloca (strlen (err) + 128);
+ sprintf (msg, "reading register %d: %s", regno, err);
+ error (msg);
+ goto error_exit;
+ }
+ }
+error_exit:;
+}
+
+/* Fetch all registers, or just one, from the child process. */
+
+void
+fetch_inferior_registers (int regno)
+{
+ if (regno == -1 || regno == 0)
+ for (regno = 0; regno < NUM_REGS; regno++)
+ fetch_register (regno);
+ else
+ fetch_register (regno);
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ register unsigned int regaddr;
+ char buf[80];
+ extern char registers[];
+ register int i;
+ unsigned int offset = U_REGS_OFFSET;
+ int scratch;
+
+ if (regno >= 0)
+ {
+ if (CANNOT_STORE_REGISTER (regno))
+ return;
+ regaddr = register_addr (regno, offset);
+ errno = 0;
+ if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
+ {
+ scratch = *(int *) &registers[REGISTER_BYTE (regno)] | 0x3;
+ ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
+ scratch, 0);
+ if (errno != 0)
+ {
+ /* Error, even if attached. Failing to write these two
+ registers is pretty serious. */
+ sprintf (buf, "writing register number %d", regno);
+ perror_with_name (buf);
+ }
+ }
+ else
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+ {
+ errno = 0;
+ ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
+ *(int *) &registers[REGISTER_BYTE (regno) + i], 0);
+ if (errno != 0)
+ {
+ /* Warning, not error, in case we are attached; sometimes the
+ kernel doesn't let us at the registers. */
+ char *err = strerror (errno);
+ char *msg = alloca (strlen (err) + 128);
+ sprintf (msg, "writing register %d: %s",
+ regno, err);
+ error (msg);
+ return;
+ }
+ regaddr += sizeof (int);
+ }
+ }
+ else
+ for (regno = 0; regno < NUM_REGS; regno++)
+ store_inferior_registers (regno);
+}
+
+/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
+ in the NEW_SUN_PTRACE case.
+ It ought to be straightforward. But it appears that writing did
+ not write the data that I specified. I cannot understand where
+ it got the data that it actually did write. */
+
+/* Copy LEN bytes from inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. */
+
+void
+read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+ /* Allocate buffer of that many longwords. */
+ register int *buffer = (int *) alloca (count * sizeof (int));
+
+ /* Read all the longwords */
+ for (i = 0; i < count; i++, addr += sizeof (int))
+ {
+ buffer[i] = ptrace (1, inferior_pid, addr, 0, 0);
+ }
+
+ /* Copy appropriate bytes out of the buffer. */
+ memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+ to inferior's memory at MEMADDR.
+ On failure (cannot write the inferior)
+ returns the value of errno. */
+
+int
+write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+ /* Allocate buffer of that many longwords. */
+ register int *buffer = (int *) alloca (count * sizeof (int));
+ extern int errno;
+
+ /* Fill start and end extra bytes of buffer with existing memory data. */
+
+ buffer[0] = ptrace (1, inferior_pid, addr, 0, 0);
+
+ if (count > 1)
+ {
+ buffer[count - 1]
+ = ptrace (1, inferior_pid,
+ addr + (count - 1) * sizeof (int), 0, 0);
+ }
+
+ /* Copy data to be written over corresponding part of buffer */
+
+ memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
+
+ /* Write the entire buffer. */
+
+ for (i = 0; i < count; i++, addr += sizeof (int))
+ {
+ errno = 0;
+ ptrace (4, inferior_pid, addr, buffer[i], 0);
+ if (errno)
+ return errno;
+ }
+
+ return 0;
+}
+
+void
+initialize_low (void)
+{
+}
diff --git a/gdb/gdbserver/low-lynx.c b/gdb/gdbserver/low-lynx.c
new file mode 100644
index 00000000000..90e18db5e39
--- /dev/null
+++ b/gdb/gdbserver/low-lynx.c
@@ -0,0 +1,745 @@
+/* Low level interface to ptrace, for the remote server for GDB.
+ Copyright 1986, 1987, 1993, 1994, 1995, 1999, 2000, 2001, 2002
+ 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 "server.h"
+#include "frame.h"
+#include "inferior.h"
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#define LYNXOS
+#include <sys/mem.h>
+#include <sys/signal.h>
+#include <sys/file.h>
+#include <sys/kernel.h>
+#ifndef __LYNXOS
+#define __LYNXOS
+#endif
+#include <sys/itimer.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/proc.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sgtty.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include <sys/fpp.h>
+
+static char my_registers[REGISTER_BYTES];
+char *registers = my_registers;
+
+#include <sys/ptrace.h>
+
+/* Start an inferior process and returns its pid.
+ ALLARGS is a vector of program-name and args. */
+
+int
+create_inferior (char *program, char **allargs)
+{
+ int pid;
+
+ pid = fork ();
+ if (pid < 0)
+ perror_with_name ("fork");
+
+ if (pid == 0)
+ {
+ int pgrp;
+
+ /* Switch child to it's own process group so that signals won't
+ directly affect gdbserver. */
+
+ pgrp = getpid ();
+ setpgrp (0, pgrp);
+ ioctl (0, TIOCSPGRP, &pgrp);
+
+ ptrace (PTRACE_TRACEME, 0, (PTRACE_ARG3_TYPE) 0, 0);
+
+ execv (program, allargs);
+
+ fprintf (stderr, "GDBserver (process %d): Cannot exec %s: %s.\n",
+ getpid (), program,
+ errno < sys_nerr ? sys_errlist[errno] : "unknown error");
+ fflush (stderr);
+ _exit (0177);
+ }
+
+ return pid;
+}
+
+/* Attaching is not supported. */
+int
+myattach (int pid)
+{
+ return -1;
+}
+
+/* Kill the inferior process. Make us have no inferior. */
+
+void
+kill_inferior (void)
+{
+ if (inferior_pid == 0)
+ return;
+ ptrace (PTRACE_KILL, inferior_pid, 0, 0);
+ wait (0);
+
+ inferior_pid = 0;
+}
+
+/* Return nonzero if the given thread is still alive. */
+int
+mythread_alive (int pid)
+{
+ /* Arggh. Apparently pthread_kill only works for threads within
+ the process that calls pthread_kill.
+
+ We want to avoid the lynx signal extensions as they simply don't
+ map well to the generic gdb interface we want to keep.
+
+ All we want to do is determine if a particular thread is alive;
+ it appears as if we can just make a harmless thread specific
+ ptrace call to do that. */
+ return (ptrace (PTRACE_THREADUSER,
+ BUILDPID (PIDGET (inferior_pid), pid), 0, 0) != -1);
+}
+
+/* Wait for process, returns status */
+
+unsigned char
+mywait (char *status)
+{
+ int pid;
+ union wait w;
+
+ while (1)
+ {
+ enable_async_io ();
+
+ pid = wait (&w);
+
+ disable_async_io ();
+
+ if (pid != PIDGET (inferior_pid))
+ perror_with_name ("wait");
+
+ thread_from_wait = w.w_tid;
+ inferior_pid = BUILDPID (inferior_pid, w.w_tid);
+
+ if (WIFSTOPPED (w)
+ && WSTOPSIG (w) == SIGTRAP)
+ {
+ int realsig;
+
+ realsig = ptrace (PTRACE_GETTRACESIG, inferior_pid,
+ (PTRACE_ARG3_TYPE) 0, 0);
+
+ if (realsig == SIGNEWTHREAD)
+ {
+ /* It's a new thread notification. Nothing to do here since
+ the machine independent code in wait_for_inferior will
+ add the thread to the thread list and restart the thread
+ when pid != inferior_pid and pid is not in the thread list.
+ We don't even want to muck with realsig -- the code in
+ wait_for_inferior expects SIGTRAP. */
+ ;
+ }
+ }
+ break;
+ }
+
+ if (WIFEXITED (w))
+ {
+ *status = 'W';
+ return ((unsigned char) WEXITSTATUS (w));
+ }
+ else if (!WIFSTOPPED (w))
+ {
+ *status = 'X';
+ return ((unsigned char) WTERMSIG (w));
+ }
+
+ fetch_inferior_registers (0);
+
+ *status = 'T';
+ return ((unsigned char) WSTOPSIG (w));
+}
+
+/* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+void
+myresume (int step, int signal)
+{
+ errno = 0;
+ ptrace (step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT,
+ BUILDPID (inferior_pid, cont_thread == -1 ? 0 : cont_thread),
+ 1, signal);
+ if (errno)
+ perror_with_name ("ptrace");
+}
+
+#undef offsetof
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+
+/* Mapping between GDB register #s and offsets into econtext. Must be
+ consistent with REGISTER_NAMES macro in various tmXXX.h files. */
+
+#define X(ENTRY)(offsetof(struct econtext, ENTRY))
+
+#ifdef I386
+/* Mappings from tm-i386v.h */
+
+static int regmap[] =
+{
+ X (eax),
+ X (ecx),
+ X (edx),
+ X (ebx),
+ X (esp), /* sp */
+ X (ebp), /* fp */
+ X (esi),
+ X (edi),
+ X (eip), /* pc */
+ X (flags), /* ps */
+ X (cs),
+ X (ss),
+ X (ds),
+ X (es),
+ X (ecode), /* Lynx doesn't give us either fs or gs, so */
+ X (fault), /* we just substitute these two in the hopes
+ that they are useful. */
+};
+#endif
+
+#ifdef M68K
+/* Mappings from tm-m68k.h */
+
+static int regmap[] =
+{
+ X (regs[0]), /* d0 */
+ X (regs[1]), /* d1 */
+ X (regs[2]), /* d2 */
+ X (regs[3]), /* d3 */
+ X (regs[4]), /* d4 */
+ X (regs[5]), /* d5 */
+ X (regs[6]), /* d6 */
+ X (regs[7]), /* d7 */
+ X (regs[8]), /* a0 */
+ X (regs[9]), /* a1 */
+ X (regs[10]), /* a2 */
+ X (regs[11]), /* a3 */
+ X (regs[12]), /* a4 */
+ X (regs[13]), /* a5 */
+ X (regs[14]), /* fp */
+ 0, /* sp */
+ X (status), /* ps */
+ X (pc),
+
+ X (fregs[0 * 3]), /* fp0 */
+ X (fregs[1 * 3]), /* fp1 */
+ X (fregs[2 * 3]), /* fp2 */
+ X (fregs[3 * 3]), /* fp3 */
+ X (fregs[4 * 3]), /* fp4 */
+ X (fregs[5 * 3]), /* fp5 */
+ X (fregs[6 * 3]), /* fp6 */
+ X (fregs[7 * 3]), /* fp7 */
+
+ X (fcregs[0]), /* fpcontrol */
+ X (fcregs[1]), /* fpstatus */
+ X (fcregs[2]), /* fpiaddr */
+ X (ssw), /* fpcode */
+ X (fault), /* fpflags */
+};
+#endif
+
+#ifdef SPARC
+/* Mappings from tm-sparc.h */
+
+#define FX(ENTRY)(offsetof(struct fcontext, ENTRY))
+
+static int regmap[] =
+{
+ -1, /* g0 */
+ X (g1),
+ X (g2),
+ X (g3),
+ X (g4),
+ -1, /* g5->g7 aren't saved by Lynx */
+ -1,
+ -1,
+
+ X (o[0]),
+ X (o[1]),
+ X (o[2]),
+ X (o[3]),
+ X (o[4]),
+ X (o[5]),
+ X (o[6]), /* sp */
+ X (o[7]), /* ra */
+
+ -1, -1, -1, -1, -1, -1, -1, -1, /* l0 -> l7 */
+
+ -1, -1, -1, -1, -1, -1, -1, -1, /* i0 -> i7 */
+
+ FX (f.fregs[0]), /* f0 */
+ FX (f.fregs[1]),
+ FX (f.fregs[2]),
+ FX (f.fregs[3]),
+ FX (f.fregs[4]),
+ FX (f.fregs[5]),
+ FX (f.fregs[6]),
+ FX (f.fregs[7]),
+ FX (f.fregs[8]),
+ FX (f.fregs[9]),
+ FX (f.fregs[10]),
+ FX (f.fregs[11]),
+ FX (f.fregs[12]),
+ FX (f.fregs[13]),
+ FX (f.fregs[14]),
+ FX (f.fregs[15]),
+ FX (f.fregs[16]),
+ FX (f.fregs[17]),
+ FX (f.fregs[18]),
+ FX (f.fregs[19]),
+ FX (f.fregs[20]),
+ FX (f.fregs[21]),
+ FX (f.fregs[22]),
+ FX (f.fregs[23]),
+ FX (f.fregs[24]),
+ FX (f.fregs[25]),
+ FX (f.fregs[26]),
+ FX (f.fregs[27]),
+ FX (f.fregs[28]),
+ FX (f.fregs[29]),
+ FX (f.fregs[30]),
+ FX (f.fregs[31]),
+
+ X (y),
+ X (psr),
+ X (wim),
+ X (tbr),
+ X (pc),
+ X (npc),
+ FX (fsr), /* fpsr */
+ -1, /* cpsr */
+};
+#endif
+
+#ifdef SPARC
+
+/* This routine handles some oddball cases for Sparc registers and LynxOS.
+ In partucular, it causes refs to G0, g5->7, and all fp regs to return zero.
+ It also handles knows where to find the I & L regs on the stack. */
+
+void
+fetch_inferior_registers (int regno)
+{
+#if 0
+ int whatregs = 0;
+
+#define WHATREGS_FLOAT 1
+#define WHATREGS_GEN 2
+#define WHATREGS_STACK 4
+
+ if (regno == -1)
+ whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
+ else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
+ whatregs = WHATREGS_STACK;
+ else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
+ whatregs = WHATREGS_FLOAT;
+ else
+ whatregs = WHATREGS_GEN;
+
+ if (whatregs & WHATREGS_GEN)
+ {
+ struct econtext ec; /* general regs */
+ char buf[MAX_REGISTER_RAW_SIZE];
+ int retval;
+ int i;
+
+ errno = 0;
+ retval = ptrace (PTRACE_GETREGS,
+ BUILDPID (inferior_pid, general_thread),
+ (PTRACE_ARG3_TYPE) & ec,
+ 0);
+ if (errno)
+ perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
+
+ memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM));
+ supply_register (G0_REGNUM, buf);
+ supply_register (TBR_REGNUM, (char *) &ec.tbr);
+
+ memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &ec.g1,
+ 4 * REGISTER_RAW_SIZE (G1_REGNUM));
+ for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++)
+ register_valid[i] = 1;
+
+ supply_register (PS_REGNUM, (char *) &ec.psr);
+ supply_register (Y_REGNUM, (char *) &ec.y);
+ supply_register (PC_REGNUM, (char *) &ec.pc);
+ supply_register (NPC_REGNUM, (char *) &ec.npc);
+ supply_register (WIM_REGNUM, (char *) &ec.wim);
+
+ memcpy (&registers[REGISTER_BYTE (O0_REGNUM)], ec.o,
+ 8 * REGISTER_RAW_SIZE (O0_REGNUM));
+ for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++)
+ register_valid[i] = 1;
+ }
+
+ if (whatregs & WHATREGS_STACK)
+ {
+ CORE_ADDR sp;
+ int i;
+
+ sp = read_register (SP_REGNUM);
+
+ target_xfer_memory (sp + FRAME_SAVED_I0,
+ &registers[REGISTER_BYTE (I0_REGNUM)],
+ 8 * REGISTER_RAW_SIZE (I0_REGNUM), 0);
+ for (i = I0_REGNUM; i <= I7_REGNUM; i++)
+ register_valid[i] = 1;
+
+ target_xfer_memory (sp + FRAME_SAVED_L0,
+ &registers[REGISTER_BYTE (L0_REGNUM)],
+ 8 * REGISTER_RAW_SIZE (L0_REGNUM), 0);
+ for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++)
+ register_valid[i] = 1;
+ }
+
+ if (whatregs & WHATREGS_FLOAT)
+ {
+ struct fcontext fc; /* fp regs */
+ int retval;
+ int i;
+
+ errno = 0;
+ retval = ptrace (PTRACE_GETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
+ 0);
+ if (errno)
+ perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
+
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs,
+ 32 * REGISTER_RAW_SIZE (FP0_REGNUM));
+ for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
+ register_valid[i] = 1;
+
+ supply_register (FPS_REGNUM, (char *) &fc.fsr);
+ }
+#endif
+}
+
+/* This routine handles storing of the I & L regs for the Sparc. The trick
+ here is that they actually live on the stack. The really tricky part is
+ that when changing the stack pointer, the I & L regs must be written to
+ where the new SP points, otherwise the regs will be incorrect when the
+ process is started up again. We assume that the I & L regs are valid at
+ this point. */
+
+void
+store_inferior_registers (int regno)
+{
+#if 0
+ int whatregs = 0;
+
+ if (regno == -1)
+ whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
+ else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
+ whatregs = WHATREGS_STACK;
+ else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
+ whatregs = WHATREGS_FLOAT;
+ else if (regno == SP_REGNUM)
+ whatregs = WHATREGS_STACK | WHATREGS_GEN;
+ else
+ whatregs = WHATREGS_GEN;
+
+ if (whatregs & WHATREGS_GEN)
+ {
+ struct econtext ec; /* general regs */
+ int retval;
+
+ ec.tbr = read_register (TBR_REGNUM);
+ memcpy (&ec.g1, &registers[REGISTER_BYTE (G1_REGNUM)],
+ 4 * REGISTER_RAW_SIZE (G1_REGNUM));
+
+ ec.psr = read_register (PS_REGNUM);
+ ec.y = read_register (Y_REGNUM);
+ ec.pc = read_register (PC_REGNUM);
+ ec.npc = read_register (NPC_REGNUM);
+ ec.wim = read_register (WIM_REGNUM);
+
+ memcpy (ec.o, &registers[REGISTER_BYTE (O0_REGNUM)],
+ 8 * REGISTER_RAW_SIZE (O0_REGNUM));
+
+ errno = 0;
+ retval = ptrace (PTRACE_SETREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & ec,
+ 0);
+ if (errno)
+ perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
+ }
+
+ if (whatregs & WHATREGS_STACK)
+ {
+ int regoffset;
+ CORE_ADDR sp;
+
+ sp = read_register (SP_REGNUM);
+
+ if (regno == -1 || regno == SP_REGNUM)
+ {
+ if (!register_valid[L0_REGNUM + 5])
+ abort ();
+ target_xfer_memory (sp + FRAME_SAVED_I0,
+ &registers[REGISTER_BYTE (I0_REGNUM)],
+ 8 * REGISTER_RAW_SIZE (I0_REGNUM), 1);
+
+ target_xfer_memory (sp + FRAME_SAVED_L0,
+ &registers[REGISTER_BYTE (L0_REGNUM)],
+ 8 * REGISTER_RAW_SIZE (L0_REGNUM), 1);
+ }
+ else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
+ {
+ if (!register_valid[regno])
+ abort ();
+ if (regno >= L0_REGNUM && regno <= L0_REGNUM + 7)
+ regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM)
+ + FRAME_SAVED_L0;
+ else
+ regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (I0_REGNUM)
+ + FRAME_SAVED_I0;
+ target_xfer_memory (sp + regoffset, &registers[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE (regno), 1);
+ }
+ }
+
+ if (whatregs & WHATREGS_FLOAT)
+ {
+ struct fcontext fc; /* fp regs */
+ int retval;
+
+/* We read fcontext first so that we can get good values for fq_t... */
+ errno = 0;
+ retval = ptrace (PTRACE_GETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
+ 0);
+ if (errno)
+ perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
+
+ memcpy (fc.f.fregs, &registers[REGISTER_BYTE (FP0_REGNUM)],
+ 32 * REGISTER_RAW_SIZE (FP0_REGNUM));
+
+ fc.fsr = read_register (FPS_REGNUM);
+
+ errno = 0;
+ retval = ptrace (PTRACE_SETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
+ 0);
+ if (errno)
+ perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
+ }
+#endif
+}
+#endif /* SPARC */
+
+#ifndef SPARC
+
+/* Return the offset relative to the start of the per-thread data to the
+ saved context block. */
+
+static unsigned long
+lynx_registers_addr (void)
+{
+ CORE_ADDR stblock;
+ int ecpoff = offsetof (st_t, ecp);
+ CORE_ADDR ecp;
+
+ errno = 0;
+ stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, BUILDPID (inferior_pid, general_thread),
+ (PTRACE_ARG3_TYPE) 0, 0);
+ if (errno)
+ perror_with_name ("PTRACE_THREADUSER");
+
+ ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, BUILDPID (inferior_pid, general_thread),
+ (PTRACE_ARG3_TYPE) ecpoff, 0);
+ if (errno)
+ perror_with_name ("lynx_registers_addr(PTRACE_PEEKTHREAD)");
+
+ return ecp - stblock;
+}
+
+/* Fetch one or more registers from the inferior. REGNO == -1 to get
+ them all. We actually fetch more than requested, when convenient,
+ marking them as valid so we won't fetch them again. */
+
+void
+fetch_inferior_registers (int ignored)
+{
+ int regno;
+ unsigned long reg;
+ unsigned long ecp;
+
+ ecp = lynx_registers_addr ();
+
+ for (regno = 0; regno < NUM_REGS; regno++)
+ {
+ int ptrace_fun = PTRACE_PEEKTHREAD;
+
+#ifdef PTRACE_PEEKUSP
+ ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
+#endif
+
+ errno = 0;
+ reg = ptrace (ptrace_fun, BUILDPID (inferior_pid, general_thread),
+ (PTRACE_ARG3_TYPE) (ecp + regmap[regno]), 0);
+ if (errno)
+ perror_with_name ("fetch_inferior_registers(PTRACE_PEEKTHREAD)");
+
+ *(unsigned long *) &registers[REGISTER_BYTE (regno)] = reg;
+ }
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int ignored)
+{
+ int regno;
+ unsigned long reg;
+ unsigned long ecp;
+
+ ecp = lynx_registers_addr ();
+
+ for (regno = 0; regno < NUM_REGS; regno++)
+ {
+ int ptrace_fun = PTRACE_POKEUSER;
+
+#ifdef PTRACE_POKEUSP
+ ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
+#endif
+
+ reg = *(unsigned long *) &registers[REGISTER_BYTE (regno)];
+
+ errno = 0;
+ ptrace (ptrace_fun, BUILDPID (inferior_pid, general_thread),
+ (PTRACE_ARG3_TYPE) (ecp + regmap[regno]), reg);
+ if (errno)
+ perror_with_name ("PTRACE_POKEUSER");
+ }
+}
+
+#endif /* ! SPARC */
+
+/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
+ in the NEW_SUN_PTRACE case.
+ It ought to be straightforward. But it appears that writing did
+ not write the data that I specified. I cannot understand where
+ it got the data that it actually did write. */
+
+/* Copy LEN bytes from inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. */
+
+void
+read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+ /* Allocate buffer of that many longwords. */
+ register int *buffer = (int *) alloca (count * sizeof (int));
+
+ /* Read all the longwords */
+ for (i = 0; i < count; i++, addr += sizeof (int))
+ {
+ buffer[i] = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread), addr, 0);
+ }
+
+ /* Copy appropriate bytes out of the buffer. */
+ memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+ to inferior's memory at MEMADDR.
+ On failure (cannot write the inferior)
+ returns the value of errno. */
+
+int
+write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+ /* Allocate buffer of that many longwords. */
+ register int *buffer = (int *) alloca (count * sizeof (int));
+ extern int errno;
+
+ /* Fill start and end extra bytes of buffer with existing memory data. */
+
+ buffer[0] = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread), addr, 0);
+
+ if (count > 1)
+ {
+ buffer[count - 1]
+ = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread),
+ addr + (count - 1) * sizeof (int), 0);
+ }
+
+ /* Copy data to be written over corresponding part of buffer */
+
+ memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
+
+ /* Write the entire buffer. */
+
+ for (i = 0; i < count; i++, addr += sizeof (int))
+ {
+ while (1)
+ {
+ errno = 0;
+ ptrace (PTRACE_POKETEXT, BUILDPID (inferior_pid, general_thread), addr, buffer[i]);
+ if (errno)
+ {
+ fprintf (stderr, "\
+ptrace (PTRACE_POKETEXT): errno=%d, pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n",
+ errno, BUILDPID (inferior_pid, general_thread),
+ addr, buffer[i]);
+ fprintf (stderr, "Sleeping for 1 second\n");
+ sleep (1);
+ }
+ else
+ break;
+ }
+ }
+
+ return 0;
+}
+
+void
+initialize_low (void)
+{
+}
diff --git a/gdb/gdbserver/low-nbsd.c b/gdb/gdbserver/low-nbsd.c
new file mode 100644
index 00000000000..9046d635604
--- /dev/null
+++ b/gdb/gdbserver/low-nbsd.c
@@ -0,0 +1,599 @@
+/* Low level interface to ptrace, for the remote server for GDB.
+ Copyright 1986, 1987, 1993, 2000, 2001, 2002 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 "server.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#include "frame.h"
+#include "inferior.h"
+
+#include <stdio.h>
+#include <errno.h>
+
+/***************Begin MY defs*********************/
+static char my_registers[REGISTER_BYTES];
+char *registers = my_registers;
+/***************End MY defs*********************/
+
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#define RF(dst, src) \
+ memcpy(&registers[REGISTER_BYTE(dst)], &src, sizeof(src))
+
+#define RS(src, dst) \
+ memcpy(&dst, &registers[REGISTER_BYTE(src)], sizeof(dst))
+
+#ifdef __i386__
+struct env387
+ {
+ unsigned short control;
+ unsigned short r0;
+ unsigned short status;
+ unsigned short r1;
+ unsigned short tag;
+ unsigned short r2;
+ unsigned long eip;
+ unsigned short code_seg;
+ unsigned short opcode;
+ unsigned long operand;
+ unsigned short operand_seg;
+ unsigned short r3;
+ unsigned char regs[8][10];
+ };
+
+/* i386_register_raw_size[i] is the number of bytes of storage in the
+ actual machine representation for register i. */
+int i386_register_raw_size[MAX_NUM_REGS] = {
+ 4, 4, 4, 4,
+ 4, 4, 4, 4,
+ 4, 4, 4, 4,
+ 4, 4, 4, 4,
+ 10, 10, 10, 10,
+ 10, 10, 10, 10,
+ 4, 4, 4, 4,
+ 4, 4, 4, 4,
+ 16, 16, 16, 16,
+ 16, 16, 16, 16,
+ 4
+};
+
+int i386_register_byte[MAX_NUM_REGS];
+
+static void
+initialize_arch (void)
+{
+ /* Initialize the table saying where each register starts in the
+ register file. */
+ {
+ int i, offset;
+
+ offset = 0;
+ for (i = 0; i < MAX_NUM_REGS; i++)
+ {
+ i386_register_byte[i] = offset;
+ offset += i386_register_raw_size[i];
+ }
+ }
+}
+#endif /* !__i386__ */
+
+#ifdef __m68k__
+static void
+initialize_arch (void)
+{
+}
+#endif /* !__m68k__ */
+
+#ifdef __ns32k__
+static void
+initialize_arch (void)
+{
+}
+#endif /* !__ns32k__ */
+
+#ifdef __powerpc__
+#include "ppc-tdep.h"
+
+static void
+initialize_arch (void)
+{
+}
+#endif /* !__powerpc__ */
+
+
+/* Start an inferior process and returns its pid.
+ ALLARGS is a vector of program-name and args. */
+
+int
+create_inferior (char *program, char **allargs)
+{
+ int pid;
+
+ pid = fork ();
+ if (pid < 0)
+ perror_with_name ("fork");
+
+ if (pid == 0)
+ {
+ ptrace (PT_TRACE_ME, 0, 0, 0);
+
+ execv (program, allargs);
+
+ fprintf (stderr, "Cannot exec %s: %s.\n", program,
+ errno < sys_nerr ? sys_errlist[errno] : "unknown error");
+ fflush (stderr);
+ _exit (0177);
+ }
+
+ return pid;
+}
+
+/* Attaching is not supported. */
+int
+myattach (int pid)
+{
+ return -1;
+}
+
+/* Kill the inferior process. Make us have no inferior. */
+
+void
+kill_inferior (void)
+{
+ if (inferior_pid == 0)
+ return;
+ ptrace (PT_KILL, inferior_pid, 0, 0);
+ wait (0);
+ /*************inferior_died ();****VK**************/
+}
+
+/* Return nonzero if the given thread is still alive. */
+int
+mythread_alive (int pid)
+{
+ return 1;
+}
+
+/* Wait for process, returns status */
+
+unsigned char
+mywait (char *status)
+{
+ int pid;
+ int w;
+
+ enable_async_io ();
+ pid = waitpid (inferior_pid, &w, 0);
+ disable_async_io ();
+ if (pid != inferior_pid)
+ perror_with_name ("wait");
+
+ if (WIFEXITED (w))
+ {
+ fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
+ *status = 'W';
+ return ((unsigned char) WEXITSTATUS (w));
+ }
+ else if (!WIFSTOPPED (w))
+ {
+ fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
+ *status = 'X';
+ return ((unsigned char) WTERMSIG (w));
+ }
+
+ fetch_inferior_registers (0);
+
+ *status = 'T';
+ return ((unsigned char) WSTOPSIG (w));
+}
+
+/* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+void
+myresume (int step, int signal)
+{
+ errno = 0;
+ ptrace (step ? PT_STEP : PT_CONTINUE, inferior_pid,
+ (PTRACE_ARG3_TYPE) 1, signal);
+ if (errno)
+ perror_with_name ("ptrace");
+}
+
+
+#ifdef __i386__
+/* Fetch one or more registers from the inferior. REGNO == -1 to get
+ them all. We actually fetch more than requested, when convenient,
+ marking them as valid so we won't fetch them again. */
+
+void
+fetch_inferior_registers (int ignored)
+{
+ struct reg inferior_registers;
+ struct env387 inferior_fp_registers;
+
+ ptrace (PT_GETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) &inferior_registers, 0);
+ ptrace (PT_GETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
+
+ RF ( 0, inferior_registers.r_eax);
+ RF ( 1, inferior_registers.r_ecx);
+ RF ( 2, inferior_registers.r_edx);
+ RF ( 3, inferior_registers.r_ebx);
+ RF ( 4, inferior_registers.r_esp);
+ RF ( 5, inferior_registers.r_ebp);
+ RF ( 6, inferior_registers.r_esi);
+ RF ( 7, inferior_registers.r_edi);
+ RF ( 8, inferior_registers.r_eip);
+ RF ( 9, inferior_registers.r_eflags);
+ RF (10, inferior_registers.r_cs);
+ RF (11, inferior_registers.r_ss);
+ RF (12, inferior_registers.r_ds);
+ RF (13, inferior_registers.r_es);
+ RF (14, inferior_registers.r_fs);
+ RF (15, inferior_registers.r_gs);
+
+ RF (FP0_REGNUM, inferior_fp_registers.regs[0]);
+ RF (FP0_REGNUM + 1, inferior_fp_registers.regs[1]);
+ RF (FP0_REGNUM + 2, inferior_fp_registers.regs[2]);
+ RF (FP0_REGNUM + 3, inferior_fp_registers.regs[3]);
+ RF (FP0_REGNUM + 4, inferior_fp_registers.regs[4]);
+ RF (FP0_REGNUM + 5, inferior_fp_registers.regs[5]);
+ RF (FP0_REGNUM + 6, inferior_fp_registers.regs[6]);
+ RF (FP0_REGNUM + 7, inferior_fp_registers.regs[7]);
+
+ RF (FCTRL_REGNUM, inferior_fp_registers.control);
+ RF (FSTAT_REGNUM, inferior_fp_registers.status);
+ RF (FTAG_REGNUM, inferior_fp_registers.tag);
+ RF (FCS_REGNUM, inferior_fp_registers.code_seg);
+ RF (FCOFF_REGNUM, inferior_fp_registers.eip);
+ RF (FDS_REGNUM, inferior_fp_registers.operand_seg);
+ RF (FDOFF_REGNUM, inferior_fp_registers.operand);
+ RF (FOP_REGNUM, inferior_fp_registers.opcode);
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int ignored)
+{
+ struct reg inferior_registers;
+ struct env387 inferior_fp_registers;
+
+ RS ( 0, inferior_registers.r_eax);
+ RS ( 1, inferior_registers.r_ecx);
+ RS ( 2, inferior_registers.r_edx);
+ RS ( 3, inferior_registers.r_ebx);
+ RS ( 4, inferior_registers.r_esp);
+ RS ( 5, inferior_registers.r_ebp);
+ RS ( 6, inferior_registers.r_esi);
+ RS ( 7, inferior_registers.r_edi);
+ RS ( 8, inferior_registers.r_eip);
+ RS ( 9, inferior_registers.r_eflags);
+ RS (10, inferior_registers.r_cs);
+ RS (11, inferior_registers.r_ss);
+ RS (12, inferior_registers.r_ds);
+ RS (13, inferior_registers.r_es);
+ RS (14, inferior_registers.r_fs);
+ RS (15, inferior_registers.r_gs);
+
+ RS (FP0_REGNUM, inferior_fp_registers.regs[0]);
+ RS (FP0_REGNUM + 1, inferior_fp_registers.regs[1]);
+ RS (FP0_REGNUM + 2, inferior_fp_registers.regs[2]);
+ RS (FP0_REGNUM + 3, inferior_fp_registers.regs[3]);
+ RS (FP0_REGNUM + 4, inferior_fp_registers.regs[4]);
+ RS (FP0_REGNUM + 5, inferior_fp_registers.regs[5]);
+ RS (FP0_REGNUM + 6, inferior_fp_registers.regs[6]);
+ RS (FP0_REGNUM + 7, inferior_fp_registers.regs[7]);
+
+ RS (FCTRL_REGNUM, inferior_fp_registers.control);
+ RS (FSTAT_REGNUM, inferior_fp_registers.status);
+ RS (FTAG_REGNUM, inferior_fp_registers.tag);
+ RS (FCS_REGNUM, inferior_fp_registers.code_seg);
+ RS (FCOFF_REGNUM, inferior_fp_registers.eip);
+ RS (FDS_REGNUM, inferior_fp_registers.operand_seg);
+ RS (FDOFF_REGNUM, inferior_fp_registers.operand);
+ RS (FOP_REGNUM, inferior_fp_registers.opcode);
+
+ ptrace (PT_SETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) &inferior_registers, 0);
+ ptrace (PT_SETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
+}
+#endif /* !__i386__ */
+
+#ifdef __m68k__
+/* Fetch one or more registers from the inferior. REGNO == -1 to get
+ them all. We actually fetch more than requested, when convenient,
+ marking them as valid so we won't fetch them again. */
+
+void
+fetch_inferior_registers (int regno)
+{
+ struct reg inferior_registers;
+ struct fpreg inferior_fp_registers;
+
+ ptrace (PT_GETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0);
+ memcpy (&registers[REGISTER_BYTE (0)], &inferior_registers,
+ sizeof (inferior_registers));
+
+ ptrace (PT_GETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0);
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
+ sizeof (inferior_fp_registers));
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ struct reg inferior_registers;
+ struct fpreg inferior_fp_registers;
+
+ memcpy (&inferior_registers, &registers[REGISTER_BYTE (0)],
+ sizeof (inferior_registers));
+ ptrace (PT_SETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0);
+
+ memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
+ sizeof (inferior_fp_registers));
+ ptrace (PT_SETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0);
+}
+#endif /* !__m68k__ */
+
+
+#ifdef __ns32k__
+/* Fetch one or more registers from the inferior. REGNO == -1 to get
+ them all. We actually fetch more than requested, when convenient,
+ marking them as valid so we won't fetch them again. */
+
+void
+fetch_inferior_registers (int regno)
+{
+ struct reg inferior_registers;
+ struct fpreg inferior_fpregisters;
+
+ ptrace (PT_GETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0);
+ ptrace (PT_GETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_fpregisters, 0);
+
+ RF (R0_REGNUM + 0, inferior_registers.r_r0);
+ RF (R0_REGNUM + 1, inferior_registers.r_r1);
+ RF (R0_REGNUM + 2, inferior_registers.r_r2);
+ RF (R0_REGNUM + 3, inferior_registers.r_r3);
+ RF (R0_REGNUM + 4, inferior_registers.r_r4);
+ RF (R0_REGNUM + 5, inferior_registers.r_r5);
+ RF (R0_REGNUM + 6, inferior_registers.r_r6);
+ RF (R0_REGNUM + 7, inferior_registers.r_r7);
+
+ RF (SP_REGNUM, inferior_registers.r_sp);
+ RF (FP_REGNUM, inferior_registers.r_fp);
+ RF (PC_REGNUM, inferior_registers.r_pc);
+ RF (PS_REGNUM, inferior_registers.r_psr);
+
+ RF (FPS_REGNUM, inferior_fpregisters.r_fsr);
+ RF (FP0_REGNUM + 0, inferior_fpregisters.r_freg[0]);
+ RF (FP0_REGNUM + 2, inferior_fpregisters.r_freg[2]);
+ RF (FP0_REGNUM + 4, inferior_fpregisters.r_freg[4]);
+ RF (FP0_REGNUM + 6, inferior_fpregisters.r_freg[6]);
+ RF (LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]);
+ RF (LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]);
+ RF (LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]);
+ RF (LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]);
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ struct reg inferior_registers;
+ struct fpreg inferior_fpregisters;
+
+ RS (R0_REGNUM + 0, inferior_registers.r_r0);
+ RS (R0_REGNUM + 1, inferior_registers.r_r1);
+ RS (R0_REGNUM + 2, inferior_registers.r_r2);
+ RS (R0_REGNUM + 3, inferior_registers.r_r3);
+ RS (R0_REGNUM + 4, inferior_registers.r_r4);
+ RS (R0_REGNUM + 5, inferior_registers.r_r5);
+ RS (R0_REGNUM + 6, inferior_registers.r_r6);
+ RS (R0_REGNUM + 7, inferior_registers.r_r7);
+
+ RS (SP_REGNUM, inferior_registers.r_sp);
+ RS (FP_REGNUM, inferior_registers.r_fp);
+ RS (PC_REGNUM, inferior_registers.r_pc);
+ RS (PS_REGNUM, inferior_registers.r_psr);
+
+ RS (FPS_REGNUM, inferior_fpregisters.r_fsr);
+ RS (FP0_REGNUM + 0, inferior_fpregisters.r_freg[0]);
+ RS (FP0_REGNUM + 2, inferior_fpregisters.r_freg[2]);
+ RS (FP0_REGNUM + 4, inferior_fpregisters.r_freg[4]);
+ RS (FP0_REGNUM + 6, inferior_fpregisters.r_freg[6]);
+ RS (LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]);
+ RS (LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]);
+ RS (LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]);
+ RS (LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]);
+
+ ptrace (PT_SETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0);
+ ptrace (PT_SETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_fpregisters, 0);
+
+}
+#endif /* !__ns32k__ */
+
+#ifdef __powerpc__
+/* Fetch one or more registers from the inferior. REGNO == -1 to get
+ them all. We actually fetch more than requested, when convenient,
+ marking them as valid so we won't fetch them again. */
+
+void
+fetch_inferior_registers (int regno)
+{
+ struct reg inferior_registers;
+#ifdef PT_GETFPREGS
+ struct fpreg inferior_fp_registers;
+#endif
+ int i;
+
+ ptrace (PT_GETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0);
+ for (i = 0; i < 32; i++)
+ RF (i, inferior_registers.fixreg[i]);
+ RF (PPC_LR_REGNUM, inferior_registers.lr);
+ RF (PPC_CR_REGNUM, inferior_registers.cr);
+ RF (PPC_XER_REGNUM, inferior_registers.xer);
+ RF (PPC_CTR_REGNUM, inferior_registers.ctr);
+ RF (PC_REGNUM, inferior_registers.pc);
+
+#ifdef PT_GETFPREGS
+ ptrace (PT_GETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0);
+ for (i = 0; i < 32; i++)
+ RF (FP0_REGNUM + i, inferior_fp_registers.r_regs[i]);
+#endif
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ struct reg inferior_registers;
+#ifdef PT_SETFPREGS
+ struct fpreg inferior_fp_registers;
+#endif
+ int i;
+
+ for (i = 0; i < 32; i++)
+ RS (i, inferior_registers.fixreg[i]);
+ RS (PPC_LR_REGNUM, inferior_registers.lr);
+ RS (PPC_CR_REGNUM, inferior_registers.cr);
+ RS (PPC_XER_REGNUM, inferior_registers.xer);
+ RS (PPC_CTR_REGNUM, inferior_registers.ctr);
+ RS (PC_REGNUM, inferior_registers.pc);
+ ptrace (PT_SETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0);
+
+#ifdef PT_SETFPREGS
+ for (i = 0; i < 32; i++)
+ RS (FP0_REGNUM + i, inferior_fp_registers.r_regs[i]);
+ ptrace (PT_SETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0);
+#endif
+}
+#endif /* !__powerpc__ */
+
+/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
+ in the NEW_SUN_PTRACE case.
+ It ought to be straightforward. But it appears that writing did
+ not write the data that I specified. I cannot understand where
+ it got the data that it actually did write. */
+
+/* Copy LEN bytes from inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. */
+
+void
+read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+ /* Allocate buffer of that many longwords. */
+ register int *buffer = (int *) alloca (count * sizeof (int));
+
+ /* Read all the longwords */
+ for (i = 0; i < count; i++, addr += sizeof (int))
+ {
+ buffer[i] = ptrace (PT_READ_D, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0);
+ }
+
+ /* Copy appropriate bytes out of the buffer. */
+ memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+ to inferior's memory at MEMADDR.
+ On failure (cannot write the inferior)
+ returns the value of errno. */
+
+int
+write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+ /* Allocate buffer of that many longwords. */
+ register int *buffer = (int *) alloca (count * sizeof (int));
+ extern int errno;
+
+ /* Fill start and end extra bytes of buffer with existing memory data. */
+
+ buffer[0] = ptrace (PT_READ_D, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0);
+
+ if (count > 1)
+ {
+ buffer[count - 1]
+ = ptrace (PT_READ_D, inferior_pid,
+ (PTRACE_ARG3_TYPE) addr + (count - 1) * sizeof (int), 0);
+ }
+
+ /* Copy data to be written over corresponding part of buffer */
+
+ memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
+
+ /* Write the entire buffer. */
+
+ for (i = 0; i < count; i++, addr += sizeof (int))
+ {
+ errno = 0;
+ ptrace (PT_WRITE_D, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]);
+ if (errno)
+ return errno;
+ }
+
+ return 0;
+}
+
+void
+initialize_low (void)
+{
+ initialize_arch ();
+}
diff --git a/gdb/gdbserver/low-sim.c b/gdb/gdbserver/low-sim.c
new file mode 100644
index 00000000000..86a040621d9
--- /dev/null
+++ b/gdb/gdbserver/low-sim.c
@@ -0,0 +1,269 @@
+/* Low level interface to simulators, for the remote server for GDB.
+ Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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 "server.h"
+#include "bfd.h"
+#include "callback.h" /* GDB simulator callback interface */
+#include "remote-sim.h" /* GDB simulator interface */
+
+extern int remote_debug;
+
+extern host_callback default_callback; /* in sim/common/callback.c */
+
+static char my_registers[REGISTER_BYTES] __attribute__ ((aligned));
+char * registers = my_registers;
+
+int target_byte_order; /* used by simulator */
+
+/* We record the result of sim_open so we can pass it
+ back to the other sim_foo routines. */
+static SIM_DESC gdbsim_desc = 0;
+
+/* This version of "load" should be usable for any simulator that
+ does not support loading itself. */
+
+static void
+mygeneric_load (bfd *loadfile_bfd)
+{
+ asection *s;
+
+ for (s = loadfile_bfd->sections; s; s = s->next)
+ {
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_size_type size;
+
+ size = bfd_get_section_size_before_reloc (s);
+ if (size > 0)
+ {
+ char *buffer;
+ bfd_vma lma; /* use load address, not virtual address */
+
+ buffer = xmalloc (size);
+ lma = s->lma;
+
+ /* Is this really necessary? I guess it gives the user something
+ to look at during a long download. */
+ printf ("Loading section %s, size 0x%lx lma 0x%lx\n",
+ bfd_get_section_name (loadfile_bfd, s),
+ (unsigned long) size,
+ (unsigned long) lma); /* chops high 32 bits. FIXME!! */
+
+ bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
+
+ write_inferior_memory (lma, buffer, size);
+ free (buffer);
+ }
+ }
+ }
+
+ printf ("Start address 0x%lx\n",
+ (unsigned long) loadfile_bfd->start_address);
+
+ /* We were doing this in remote-mips.c, I suspect it is right
+ for other targets too. */
+ /* write_pc (loadfile_bfd->start_address); *//* FIXME!! */
+}
+
+int
+create_inferior (char *program, char **argv)
+{
+ bfd *abfd;
+ int pid = 0;
+ char **new_argv;
+ int nargs;
+
+ abfd = bfd_openr (program, 0);
+ if (!abfd)
+ {
+ fprintf (stderr, "gdbserver: can't open %s: %s\n",
+ program, bfd_errmsg (bfd_get_error ()));
+ exit (1);
+ }
+
+ if (!bfd_check_format (abfd, bfd_object))
+ {
+ fprintf (stderr, "gdbserver: unknown load format for %s: %s\n",
+ program, bfd_errmsg (bfd_get_error ()));
+ exit (1);
+ }
+
+ /* Add "-E big" or "-E little" to the argument list depending on the
+ endianness of the program to be loaded. */
+ for (nargs = 0; argv[nargs] != NULL; nargs++) /* count the args */
+ ;
+ new_argv = alloca (sizeof (char *) * (nargs + 3)); /* allocate new args */
+ for (nargs = 0; argv[nargs] != NULL; nargs++) /* copy old to new */
+ new_argv[nargs] = argv[nargs];
+ new_argv[nargs] = "-E";
+ new_argv[nargs + 1] = bfd_big_endian (abfd) ? "big" : "little";
+ new_argv[nargs + 2] = NULL;
+ argv = new_argv;
+
+ /* Create an instance of the simulator. */
+ default_callback.init (&default_callback);
+ gdbsim_desc = sim_open (SIM_OPEN_STANDALONE, &default_callback, abfd, argv);
+ if (gdbsim_desc == 0)
+ exit (1);
+
+ /* Load the program into the simulator. */
+ if (abfd)
+ if (sim_load (gdbsim_desc, program, NULL, 0) == SIM_RC_FAIL)
+ mygeneric_load (abfd);
+
+ /* Create an inferior process in the simulator. This initializes SP. */
+ sim_create_inferior (gdbsim_desc, abfd, argv, /* env */ NULL);
+ sim_resume (gdbsim_desc, 1, 0); /* execute one instr */
+ return pid;
+}
+
+/* Attaching is not supported. */
+int
+myattach (int pid)
+{
+ return -1;
+}
+
+/* Kill the inferior process. Make us have no inferior. */
+
+void
+kill_inferior (void)
+{
+ sim_close (gdbsim_desc, 0);
+ default_callback.shutdown (&default_callback);
+}
+
+/* Fetch one register. */
+
+static void
+fetch_register (int regno)
+{
+ sim_fetch_register (gdbsim_desc, regno, &registers[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE (regno));
+}
+
+/* Fetch all registers, or just one, from the child process. */
+
+void
+fetch_inferior_registers (int regno)
+{
+ if (regno == -1 || regno == 0)
+ for (regno = 0; regno < NUM_REGS /*-NUM_FREGS*/ ; regno++)
+ fetch_register (regno);
+ else
+ fetch_register (regno);
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ if (regno == -1)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ store_inferior_registers (regno);
+ }
+ else
+ sim_store_register (gdbsim_desc, regno, &registers[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE (regno));
+}
+
+/* Return nonzero if the given thread is still alive. */
+int
+mythread_alive (int pid)
+{
+ return 1;
+}
+
+/* Wait for process, returns status */
+
+unsigned char
+mywait (char *status)
+{
+ int sigrc;
+ enum sim_stop reason;
+
+ sim_stop_reason (gdbsim_desc, &reason, &sigrc);
+ switch (reason)
+ {
+ case sim_exited:
+ if (remote_debug)
+ printf ("\nChild exited with retcode = %x \n", sigrc);
+ *status = 'W';
+ return sigrc;
+
+#if 0
+ case sim_stopped:
+ if (remote_debug)
+ printf ("\nChild terminated with signal = %x \n", sigrc);
+ *status = 'X';
+ return sigrc;
+#endif
+
+ default: /* should this be sim_signalled or sim_stopped? FIXME!! */
+ if (remote_debug)
+ printf ("\nChild received signal = %x \n", sigrc);
+ fetch_inferior_registers (0);
+ *status = 'T';
+ return (unsigned char) sigrc;
+ }
+}
+
+/* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+void
+myresume (int step, int signo)
+{
+ /* Should be using target_signal_to_host() or signal numbers in target.h
+ to convert GDB signal number to target signal number. */
+ sim_resume (gdbsim_desc, step, signo);
+}
+
+/* Copy LEN bytes from inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. */
+
+void
+read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ sim_read (gdbsim_desc, memaddr, myaddr, len);
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+ to inferior's memory at MEMADDR.
+ On failure (cannot write the inferior)
+ returns the value of errno. */
+
+int
+write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ sim_write (gdbsim_desc, memaddr, myaddr, len); /* should check for error. FIXME!! */
+ return 0;
+}
+
+void
+initialize_low (void)
+{
+}
diff --git a/gdb/gdbserver/low-sparc.c b/gdb/gdbserver/low-sparc.c
new file mode 100644
index 00000000000..4b03140e128
--- /dev/null
+++ b/gdb/gdbserver/low-sparc.c
@@ -0,0 +1,314 @@
+/* Low level interface to ptrace, for the remote server for GDB.
+ Copyright 1986, 1987, 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002
+ 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 "server.h"
+#include <sys/wait.h>
+#include "frame.h"
+#include "inferior.h"
+/***************************
+#include "initialize.h"
+****************************/
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sgtty.h>
+#include <fcntl.h>
+
+/***************Begin MY defs*********************/
+static char my_registers[REGISTER_BYTES];
+char *registers = my_registers;
+/***************End MY defs*********************/
+
+#include <sys/ptrace.h>
+#include <sys/reg.h>
+
+extern int sys_nerr;
+extern char **sys_errlist;
+extern int errno;
+
+/* Start an inferior process and returns its pid.
+ ALLARGS is a vector of program-name and args. */
+
+int
+create_inferior (char *program, char **allargs)
+{
+ int pid;
+
+ pid = fork ();
+ if (pid < 0)
+ perror_with_name ("fork");
+
+ if (pid == 0)
+ {
+ ptrace (PTRACE_TRACEME);
+
+ execv (program, allargs);
+
+ fprintf (stderr, "Cannot exec %s: %s.\n", program,
+ errno < sys_nerr ? sys_errlist[errno] : "unknown error");
+ fflush (stderr);
+ _exit (0177);
+ }
+
+ return pid;
+}
+
+/* Attaching is not supported. */
+int
+myattach (int pid)
+{
+ return -1;
+}
+
+/* Kill the inferior process. Make us have no inferior. */
+
+void
+kill_inferior (void)
+{
+ if (inferior_pid == 0)
+ return;
+ ptrace (8, inferior_pid, 0, 0);
+ wait (0);
+/*************inferior_died ();****VK**************/
+}
+
+/* Return nonzero if the given thread is still alive. */
+int
+mythread_alive (int pid)
+{
+ return 1;
+}
+
+/* Wait for process, returns status */
+
+unsigned char
+mywait (char *status)
+{
+ int pid;
+ union wait w;
+
+ enable_async_io ();
+ pid = waitpid (inferior_pid, &w, 0);
+ disable_async_io ();
+ if (pid != inferior_pid)
+ perror_with_name ("wait");
+
+ if (WIFEXITED (w))
+ {
+ fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
+ *status = 'W';
+ return ((unsigned char) WEXITSTATUS (w));
+ }
+ else if (!WIFSTOPPED (w))
+ {
+ fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
+ *status = 'X';
+ return ((unsigned char) WTERMSIG (w));
+ }
+
+ fetch_inferior_registers (0);
+
+ *status = 'T';
+ return ((unsigned char) WSTOPSIG (w));
+}
+
+/* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+void
+myresume (int step, int signal)
+{
+ errno = 0;
+ ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
+ if (errno)
+ perror_with_name ("ptrace");
+}
+
+/* Fetch one or more registers from the inferior. REGNO == -1 to get
+ them all. We actually fetch more than requested, when convenient,
+ marking them as valid so we won't fetch them again. */
+
+void
+fetch_inferior_registers (int ignored)
+{
+ struct regs inferior_registers;
+ struct fp_status inferior_fp_registers;
+ int i;
+
+ /* Global and Out regs are fetched directly, as well as the control
+ registers. If we're getting one of the in or local regs,
+ and the stack pointer has not yet been fetched,
+ we have to do that first, since they're found in memory relative
+ to the stack pointer. */
+
+ if (ptrace (PTRACE_GETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0))
+ perror ("ptrace_getregs");
+
+ registers[REGISTER_BYTE (0)] = 0;
+ memcpy (&registers[REGISTER_BYTE (1)], &inferior_registers.r_g1,
+ 15 * REGISTER_RAW_SIZE (G0_REGNUM));
+ *(int *) &registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
+ *(int *) &registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
+ *(int *) &registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
+ *(int *) &registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
+
+ /* Floating point registers */
+
+ if (ptrace (PTRACE_GETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers,
+ 0))
+ perror ("ptrace_getfpregs");
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
+ sizeof inferior_fp_registers.fpu_fr);
+
+ /* These regs are saved on the stack by the kernel. Only read them
+ all (16 ptrace calls!) if we really need them. */
+
+ read_inferior_memory (*(CORE_ADDR *) & registers[REGISTER_BYTE (SP_REGNUM)],
+ &registers[REGISTER_BYTE (L0_REGNUM)],
+ 16 * REGISTER_RAW_SIZE (L0_REGNUM));
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int ignored)
+{
+ struct regs inferior_registers;
+ struct fp_status inferior_fp_registers;
+ CORE_ADDR sp = *(CORE_ADDR *) & registers[REGISTER_BYTE (SP_REGNUM)];
+
+ write_inferior_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
+ 16 * REGISTER_RAW_SIZE (L0_REGNUM));
+
+ memcpy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (G1_REGNUM)],
+ 15 * REGISTER_RAW_SIZE (G1_REGNUM));
+
+ inferior_registers.r_ps =
+ *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
+ inferior_registers.r_pc =
+ *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
+ inferior_registers.r_npc =
+ *(int *) &registers[REGISTER_BYTE (NPC_REGNUM)];
+ inferior_registers.r_y =
+ *(int *) &registers[REGISTER_BYTE (Y_REGNUM)];
+
+ if (ptrace (PTRACE_SETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0))
+ perror ("ptrace_setregs");
+
+ memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
+ sizeof inferior_fp_registers.fpu_fr);
+
+ if (ptrace (PTRACE_SETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0))
+ perror ("ptrace_setfpregs");
+}
+
+/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
+ in the NEW_SUN_PTRACE case.
+ It ought to be straightforward. But it appears that writing did
+ not write the data that I specified. I cannot understand where
+ it got the data that it actually did write. */
+
+/* Copy LEN bytes from inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. */
+
+void
+read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+ /* Allocate buffer of that many longwords. */
+ register int *buffer = (int *) alloca (count * sizeof (int));
+
+ /* Read all the longwords */
+ for (i = 0; i < count; i++, addr += sizeof (int))
+ {
+ buffer[i] = ptrace (1, inferior_pid, addr, 0);
+ }
+
+ /* Copy appropriate bytes out of the buffer. */
+ memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+ to inferior's memory at MEMADDR.
+ On failure (cannot write the inferior)
+ returns the value of errno. */
+
+int
+write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+ /* Allocate buffer of that many longwords. */
+ register int *buffer = (int *) alloca (count * sizeof (int));
+ extern int errno;
+
+ /* Fill start and end extra bytes of buffer with existing memory data. */
+
+ buffer[0] = ptrace (1, inferior_pid, addr, 0);
+
+ if (count > 1)
+ {
+ buffer[count - 1]
+ = ptrace (1, inferior_pid,
+ addr + (count - 1) * sizeof (int), 0);
+ }
+
+ /* Copy data to be written over corresponding part of buffer */
+
+ bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
+
+ /* Write the entire buffer. */
+
+ for (i = 0; i < count; i++, addr += sizeof (int))
+ {
+ errno = 0;
+ ptrace (4, inferior_pid, addr, buffer[i]);
+ if (errno)
+ return errno;
+ }
+
+ return 0;
+}
+
+void
+initialize_low (void)
+{
+}
diff --git a/gdb/gdbserver/low-sun3.c b/gdb/gdbserver/low-sun3.c
new file mode 100644
index 00000000000..ccaded826cc
--- /dev/null
+++ b/gdb/gdbserver/low-sun3.c
@@ -0,0 +1,291 @@
+/* Low level interface to ptrace, for the remote server for GDB.
+ Copyright 1986, 1987, 1993, 1994, 1995, 1999, 2000, 2001, 2002
+ 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 "server.h"
+#include "<sys/wait.h>"
+#include "frame.h"
+#include "inferior.h"
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sgtty.h>
+#include <fcntl.h>
+
+/***************Begin MY defs*********************/
+static char my_registers[REGISTER_BYTES];
+char *registers = my_registers;
+/***************End MY defs*********************/
+
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+extern int sys_nerr;
+extern char **sys_errlist;
+extern int errno;
+
+/* Start an inferior process and returns its pid.
+ ALLARGS is a vector of program-name and args. */
+
+int
+create_inferior (char *program, char **allargs)
+{
+ int pid;
+
+ pid = fork ();
+ if (pid < 0)
+ perror_with_name ("fork");
+
+ if (pid == 0)
+ {
+ ptrace (PTRACE_TRACEME);
+
+ execv (program, allargs);
+
+ fprintf (stderr, "Cannot exec %s: %s.\n", program,
+ errno < sys_nerr ? sys_errlist[errno] : "unknown error");
+ fflush (stderr);
+ _exit (0177);
+ }
+
+ return pid;
+}
+
+/* Attaching is not supported. */
+int
+myattach (int pid)
+{
+ return -1;
+}
+
+/* Kill the inferior process. Make us have no inferior. */
+
+void
+kill_inferior (void)
+{
+ if (inferior_pid == 0)
+ return;
+ ptrace (8, inferior_pid, 0, 0);
+ wait (0);
+/*************inferior_died ();****VK**************/
+}
+
+/* Return nonzero if the given thread is still alive. */
+int
+mythread_alive (int pid)
+{
+ return 1;
+}
+
+/* Wait for process, returns status */
+
+unsigned char
+mywait (char *status)
+{
+ int pid;
+ union wait w;
+
+ pid = wait (&w);
+ if (pid != inferior_pid)
+ perror_with_name ("wait");
+
+ if (WIFEXITED (w))
+ {
+ fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
+ *status = 'W';
+ return ((unsigned char) WEXITSTATUS (w));
+ }
+ else if (!WIFSTOPPED (w))
+ {
+ fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
+ *status = 'X';
+ return ((unsigned char) WTERMSIG (w));
+ }
+
+ fetch_inferior_registers (0);
+
+ *status = 'T';
+ return ((unsigned char) WSTOPSIG (w));
+}
+
+/* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+void
+myresume (int step, int signal)
+{
+ errno = 0;
+ ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
+ if (errno)
+ perror_with_name ("ptrace");
+}
+
+/* Fetch one or more registers from the inferior. REGNO == -1 to get
+ them all. We actually fetch more than requested, when convenient,
+ marking them as valid so we won't fetch them again. */
+
+void
+fetch_inferior_registers (int ignored)
+{
+ struct regs inferior_registers;
+ struct fp_status inferior_fp_registers;
+
+ ptrace (PTRACE_GETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_registers);
+#ifdef FP0_REGNUM
+ ptrace (PTRACE_GETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers);
+#endif
+
+ memcpy (registers, &inferior_registers, 16 * 4);
+#ifdef FP0_REGNUM
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
+ sizeof inferior_fp_registers.fps_regs);
+#endif
+ *(int *) &registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
+ *(int *) &registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
+#ifdef FP0_REGNUM
+ memcpy
+ (&registers[REGISTER_BYTE (FPC_REGNUM)],
+ &inferior_fp_registers.fps_control,
+ sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
+#endif
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int ignored)
+{
+ struct regs inferior_registers;
+ struct fp_status inferior_fp_registers;
+
+ memcpy (&inferior_registers, registers, 16 * 4);
+#ifdef FP0_REGNUM
+ memcpy (&inferior_fp_registers,
+ &registers[REGISTER_BYTE (FP0_REGNUM)],
+ sizeof inferior_fp_registers.fps_regs);
+#endif
+ inferior_registers.r_ps = *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
+ inferior_registers.r_pc = *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
+
+#ifdef FP0_REGNUM
+ memcpy (&inferior_fp_registers.fps_control,
+ &registers[REGISTER_BYTE (FPC_REGNUM)],
+ (sizeof inferior_fp_registers
+ - sizeof inferior_fp_registers.fps_regs));
+#endif
+
+ ptrace (PTRACE_SETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_registers);
+#if FP0_REGNUM
+ ptrace (PTRACE_SETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers);
+#endif
+}
+
+/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
+ in the NEW_SUN_PTRACE case.
+ It ought to be straightforward. But it appears that writing did
+ not write the data that I specified. I cannot understand where
+ it got the data that it actually did write. */
+
+/* Copy LEN bytes from inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. */
+
+void
+read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+ /* Allocate buffer of that many longwords. */
+ register int *buffer = (int *) alloca (count * sizeof (int));
+
+ /* Read all the longwords */
+ for (i = 0; i < count; i++, addr += sizeof (int))
+ {
+ buffer[i] = ptrace (1, inferior_pid, addr, 0);
+ }
+
+ /* Copy appropriate bytes out of the buffer. */
+ memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+ to inferior's memory at MEMADDR.
+ On failure (cannot write the inferior)
+ returns the value of errno. */
+
+int
+write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+ /* Allocate buffer of that many longwords. */
+ register int *buffer = (int *) alloca (count * sizeof (int));
+ extern int errno;
+
+ /* Fill start and end extra bytes of buffer with existing memory data. */
+
+ buffer[0] = ptrace (1, inferior_pid, addr, 0);
+
+ if (count > 1)
+ {
+ buffer[count - 1]
+ = ptrace (1, inferior_pid,
+ addr + (count - 1) * sizeof (int), 0);
+ }
+
+ /* Copy data to be written over corresponding part of buffer */
+
+ memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
+
+ /* Write the entire buffer. */
+
+ for (i = 0; i < count; i++, addr += sizeof (int))
+ {
+ errno = 0;
+ ptrace (4, inferior_pid, addr, buffer[i]);
+ if (errno)
+ return errno;
+ }
+
+ return 0;
+}
+
+void
+initialize_low (void)
+{
+}
diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
new file mode 100644
index 00000000000..6edc88327e9
--- /dev/null
+++ b/gdb/gdbserver/mem-break.c
@@ -0,0 +1,280 @@
+/* Memory breakpoint operations for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ 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 "server.h"
+
+const char *breakpoint_data;
+int breakpoint_len;
+
+#define MAX_BREAKPOINT_LEN 8
+
+struct breakpoint
+{
+ struct breakpoint *next;
+ CORE_ADDR pc;
+ unsigned char old_data[MAX_BREAKPOINT_LEN];
+
+ /* Non-zero iff we are stepping over this breakpoint. */
+ int reinserting;
+
+ /* Non-NULL iff this breakpoint was inserted to step over
+ another one. Points to the other breakpoint (which is also
+ in the *next chain somewhere). */
+ struct breakpoint *breakpoint_to_reinsert;
+
+ /* Function to call when we hit this breakpoint. */
+ void (*handler) (CORE_ADDR);
+};
+
+struct breakpoint *breakpoints;
+
+void
+set_breakpoint_at (CORE_ADDR where, void (*handler) (CORE_ADDR))
+{
+ struct breakpoint *bp;
+
+ if (breakpoint_data == NULL)
+ error ("Target does not support breakpoints.");
+
+ bp = malloc (sizeof (struct breakpoint));
+ memset (bp, 0, sizeof (struct breakpoint));
+
+ (*the_target->read_memory) (where, bp->old_data,
+ breakpoint_len);
+ (*the_target->write_memory) (where, breakpoint_data,
+ breakpoint_len);
+
+ bp->pc = where;
+ bp->handler = handler;
+
+ bp->next = breakpoints;
+ breakpoints = bp;
+}
+
+static void
+delete_breakpoint (struct breakpoint *bp)
+{
+ struct breakpoint *cur;
+
+ if (breakpoints == bp)
+ {
+ breakpoints = bp->next;
+ (*the_target->write_memory) (bp->pc, bp->old_data,
+ breakpoint_len);
+ free (bp);
+ return;
+ }
+ cur = breakpoints;
+ while (cur->next)
+ {
+ if (cur->next == bp)
+ {
+ cur->next = bp->next;
+ (*the_target->write_memory) (bp->pc, bp->old_data,
+ breakpoint_len);
+ free (bp);
+ return;
+ }
+ }
+ warning ("Could not find breakpoint in list.");
+}
+
+static struct breakpoint *
+find_breakpoint_at (CORE_ADDR where)
+{
+ struct breakpoint *bp = breakpoints;
+
+ while (bp != NULL)
+ {
+ if (bp->pc == where)
+ return bp;
+ bp = bp->next;
+ }
+
+ return NULL;
+}
+
+static void
+reinsert_breakpoint_handler (CORE_ADDR stop_pc)
+{
+ struct breakpoint *stop_bp, *orig_bp;
+
+ stop_bp = find_breakpoint_at (stop_pc);
+ if (stop_bp == NULL)
+ error ("lost the stopping breakpoint.");
+
+ orig_bp = stop_bp->breakpoint_to_reinsert;
+ if (orig_bp == NULL)
+ error ("no breakpoint to reinsert");
+
+ (*the_target->write_memory) (orig_bp->pc, breakpoint_data,
+ breakpoint_len);
+ orig_bp->reinserting = 0;
+ delete_breakpoint (stop_bp);
+}
+
+void
+reinsert_breakpoint_by_bp (CORE_ADDR stop_pc, CORE_ADDR stop_at)
+{
+ struct breakpoint *bp, *orig_bp;
+
+ set_breakpoint_at (stop_at, reinsert_breakpoint_handler);
+
+ orig_bp = find_breakpoint_at (stop_pc);
+ if (orig_bp == NULL)
+ error ("Could not find original breakpoint in list.");
+
+ bp = find_breakpoint_at (stop_at);
+ if (bp == NULL)
+ error ("Could not find breakpoint in list (reinserting by breakpoint).");
+ bp->breakpoint_to_reinsert = orig_bp;
+
+ (*the_target->write_memory) (orig_bp->pc, orig_bp->old_data,
+ breakpoint_len);
+ orig_bp->reinserting = 1;
+}
+
+void
+uninsert_breakpoint (CORE_ADDR stopped_at)
+{
+ struct breakpoint *bp;
+
+ bp = find_breakpoint_at (stopped_at);
+ if (bp == NULL)
+ error ("Could not find breakpoint in list (uninserting).");
+
+ (*the_target->write_memory) (bp->pc, bp->old_data,
+ breakpoint_len);
+ bp->reinserting = 1;
+}
+
+void
+reinsert_breakpoint (CORE_ADDR stopped_at)
+{
+ struct breakpoint *bp;
+
+ bp = find_breakpoint_at (stopped_at);
+ if (bp == NULL)
+ error ("Could not find breakpoint in list (uninserting).");
+ if (! bp->reinserting)
+ error ("Breakpoint already inserted at reinsert time.");
+
+ (*the_target->write_memory) (bp->pc, breakpoint_data,
+ breakpoint_len);
+ bp->reinserting = 0;
+}
+
+int
+check_breakpoints (CORE_ADDR stop_pc)
+{
+ struct breakpoint *bp;
+
+ bp = find_breakpoint_at (stop_pc);
+ if (bp == NULL)
+ return 0;
+ if (bp->reinserting)
+ {
+ warning ("Hit a removed breakpoint?");
+ return 0;
+ }
+
+ (*bp->handler) (bp->pc);
+ return 1;
+}
+
+void
+set_breakpoint_data (const char *bp_data, int bp_len)
+{
+ breakpoint_data = bp_data;
+ breakpoint_len = bp_len;
+}
+
+void
+check_mem_read (CORE_ADDR mem_addr, char *buf, int mem_len)
+{
+ struct breakpoint *bp = breakpoints;
+ CORE_ADDR mem_end = mem_addr + mem_len;
+
+ for (; bp != NULL; bp = bp->next)
+ {
+ CORE_ADDR bp_end = bp->pc + breakpoint_len;
+ CORE_ADDR start, end;
+ int copy_offset, copy_len, buf_offset;
+
+ if (mem_addr >= bp_end)
+ continue;
+ if (bp->pc >= mem_end)
+ continue;
+
+ start = bp->pc;
+ if (mem_addr > start)
+ start = mem_addr;
+
+ end = bp_end;
+ if (end > mem_end)
+ end = mem_end;
+
+ copy_len = end - start;
+ copy_offset = start - bp->pc;
+ buf_offset = start - mem_addr;
+
+ memcpy (buf + buf_offset, bp->old_data + copy_offset, copy_len);
+ }
+}
+
+void
+check_mem_write (CORE_ADDR mem_addr, char *buf, int mem_len)
+{
+ struct breakpoint *bp = breakpoints;
+ CORE_ADDR mem_end = mem_addr + mem_len;
+
+ for (; bp != NULL; bp = bp->next)
+ {
+ CORE_ADDR bp_end = bp->pc + breakpoint_len;
+ CORE_ADDR start, end;
+ int copy_offset, copy_len, buf_offset;
+
+ if (mem_addr >= bp_end)
+ continue;
+ if (bp->pc >= mem_end)
+ continue;
+
+ start = bp->pc;
+ if (mem_addr > start)
+ start = mem_addr;
+
+ end = bp_end;
+ if (end > mem_end)
+ end = mem_end;
+
+ copy_len = end - start;
+ copy_offset = start - bp->pc;
+ buf_offset = start - mem_addr;
+
+ memcpy (bp->old_data + copy_offset, buf + buf_offset, copy_len);
+ if (bp->reinserting == 0)
+ memcpy (buf + buf_offset, breakpoint_data + copy_offset, copy_len);
+ }
+}
+
+
diff --git a/gdb/gdbserver/mem-break.h b/gdb/gdbserver/mem-break.h
new file mode 100644
index 00000000000..356e7630cab
--- /dev/null
+++ b/gdb/gdbserver/mem-break.h
@@ -0,0 +1,71 @@
+/* Memory breakpoint interfaces for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ 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. */
+
+#ifndef MEM_BREAK_H
+#define MEM_BREAK_H
+
+/* Breakpoints are opaque. */
+
+/* Create a new breakpoint at WHERE, and call HANDLER when
+ it is hit. */
+
+void set_breakpoint_at (CORE_ADDR where,
+ void (*handler) (CORE_ADDR));
+
+/* Create a reinsertion breakpoint at STOP_AT for the breakpoint
+ currently at STOP_PC (and temporarily remove the breakpoint at
+ STOP_PC). */
+
+void reinsert_breakpoint_by_bp (CORE_ADDR stop_pc, CORE_ADDR stop_at);
+
+/* Change the status of the breakpoint at WHERE to inserted. */
+
+void reinsert_breakpoint (CORE_ADDR where);
+
+/* Change the status of the breakpoint at WHERE to uninserted. */
+
+void uninsert_breakpoint (CORE_ADDR where);
+
+/* See if any breakpoint claims ownership of STOP_PC. Call the handler for
+ the breakpoint, if found. */
+
+int check_breakpoints (CORE_ADDR stop_pc);
+
+/* See if any breakpoints shadow the target memory area from MEM_ADDR
+ to MEM_ADDR + MEM_LEN. Update the data already read from the target
+ (in BUF) if necessary. */
+
+void check_mem_read (CORE_ADDR mem_addr, char *buf, int mem_len);
+
+/* See if any breakpoints shadow the target memory area from MEM_ADDR
+ to MEM_ADDR + MEM_LEN. Update the data to be written to the target
+ (in BUF) if necessary, as well as the original data for any breakpoints. */
+
+void check_mem_write (CORE_ADDR mem_addr, char *buf, int mem_len);
+
+/* Set the byte pattern to insert for memory breakpoints. This function
+ must be called before any breakpoints are set. */
+
+void set_breakpoint_data (const char *bp_data, int bp_len);
+
+#endif /* MEM_BREAK_H */
diff --git a/gdb/gdbserver/proc-service.c b/gdb/gdbserver/proc-service.c
new file mode 100644
index 00000000000..becf565529b
--- /dev/null
+++ b/gdb/gdbserver/proc-service.c
@@ -0,0 +1,256 @@
+/* libthread_db helper functions for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ 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 "server.h"
+
+/* This file is currently tied to GNU/Linux. It should scale well to
+ another libthread_db implementation, with the approriate gdbserver
+ hooks, but for now this means we can use GNU/Linux's target data. */
+
+#include "linux-low.h"
+
+/* Correct for all GNU/Linux targets (for quite some time). */
+#define GDB_GREGSET_T elf_gregset_t
+#define GDB_FPREGSET_T elf_fpregset_t
+
+#ifndef HAVE_ELF_FPREGSET_T
+/* Make sure we have said types. Not all platforms bring in <linux/elf.h>
+ via <sys/procfs.h>. */
+#ifdef HAVE_LINUX_ELF_H
+#include <linux/elf.h>
+#endif
+#endif
+
+#include "../gdb_proc_service.h"
+
+typedef struct ps_prochandle *gdb_ps_prochandle_t;
+typedef void *gdb_ps_read_buf_t;
+typedef const void *gdb_ps_write_buf_t;
+typedef size_t gdb_ps_size_t;
+
+/* FIXME redo this right */
+#if 0
+#ifndef HAVE_LINUX_REGSETS
+#error HAVE_LINUX_REGSETS required!
+#else
+static struct regset_info *
+gregset_info(void)
+{
+ int i = 0;
+
+ while (target_regsets[i].size != -1)
+ {
+ if (target_regsets[i].type == GENERAL_REGS)
+ break;
+ i++;
+ }
+
+ return &target_regsets[i];
+}
+
+static struct regset_info *
+fpregset_info(void)
+{
+ int i = 0;
+
+ while (target_regsets[i].size != -1)
+ {
+ if (target_regsets[i].type == FP_REGS)
+ break;
+ i++;
+ }
+
+ return &target_regsets[i];
+}
+#endif
+#endif
+
+/* Search for the symbol named NAME within the object named OBJ within
+ the target process PH. If the symbol is found the address of the
+ symbol is stored in SYM_ADDR. */
+
+ps_err_e
+ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *obj,
+ const char *name, paddr_t *sym_addr)
+{
+ CORE_ADDR addr;
+
+ if (look_up_one_symbol (name, &addr) == 0)
+ return PS_NOSYM;
+
+ *sym_addr = (paddr_t) (unsigned long) addr;
+ return PS_OK;
+}
+
+/* Read SIZE bytes from the target process PH at address ADDR and copy
+ them into BUF. */
+
+ps_err_e
+ps_pdread (gdb_ps_prochandle_t ph, paddr_t addr,
+ gdb_ps_read_buf_t buf, gdb_ps_size_t size)
+{
+ read_inferior_memory (addr, buf, size);
+ return PS_OK;
+}
+
+/* Write SIZE bytes from BUF into the target process PH at address ADDR. */
+
+ps_err_e
+ps_pdwrite (gdb_ps_prochandle_t ph, paddr_t addr,
+ gdb_ps_write_buf_t buf, gdb_ps_size_t size)
+{
+ return write_inferior_memory (addr, buf, size);
+}
+
+/* Get the general registers of LWP LWPID within the target process PH
+ and store them in GREGSET. */
+
+ps_err_e
+ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
+{
+#if 0
+ struct thread_info *reg_inferior, *save_inferior;
+ void *regcache;
+
+ reg_inferior = (struct thread_info *) find_inferior_id (&all_threads,
+ lwpid);
+ if (reg_inferior == NULL)
+ return PS_ERR;
+
+ save_inferior = current_inferior;
+ current_inferior = reg_inferior;
+
+ regcache = new_register_cache ();
+ the_target->fetch_registers (0, regcache);
+ gregset_info()->fill_function (gregset, regcache);
+ free_register_cache (regcache);
+
+ current_inferior = save_inferior;
+ return PS_OK;
+#endif
+ /* FIXME */
+ return PS_ERR;
+}
+
+/* Set the general registers of LWP LWPID within the target process PH
+ from GREGSET. */
+
+ps_err_e
+ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, const prgregset_t gregset)
+{
+#if 0
+ struct thread_info *reg_inferior, *save_inferior;
+ void *regcache;
+
+ reg_inferior = (struct thread_info *) find_inferior_id (&all_threads, lwpid);
+ if (reg_inferior == NULL)
+ return PS_ERR;
+
+ save_inferior = current_inferior;
+ current_inferior = reg_inferior;
+
+ regcache = new_register_cache ();
+ gregset_info()->store_function (gregset, regcache);
+ the_target->store_registers (0, regcache);
+ free_register_cache (regcache);
+
+ current_inferior = save_inferior;
+
+ return PS_OK;
+#endif
+ /* FIXME */
+ return PS_ERR;
+}
+
+/* Get the floating-point registers of LWP LWPID within the target
+ process PH and store them in FPREGSET. */
+
+ps_err_e
+ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+ gdb_prfpregset_t *fpregset)
+{
+#if 0
+ struct thread_info *reg_inferior, *save_inferior;
+ void *regcache;
+
+ reg_inferior = (struct thread_info *) find_inferior_id (&all_threads, lwpid);
+ if (reg_inferior == NULL)
+ return PS_ERR;
+
+ save_inferior = current_inferior;
+ current_inferior = reg_inferior;
+
+ regcache = new_register_cache ();
+ the_target->fetch_registers (0, regcache);
+ fpregset_info()->fill_function (fpregset, regcache);
+ free_register_cache (regcache);
+
+ current_inferior = save_inferior;
+
+ return PS_OK;
+#endif
+ /* FIXME */
+ return PS_ERR;
+}
+
+/* Set the floating-point registers of LWP LWPID within the target
+ process PH from FPREGSET. */
+
+ps_err_e
+ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+ const gdb_prfpregset_t *fpregset)
+{
+#if 0
+ struct thread_info *reg_inferior, *save_inferior;
+ void *regcache;
+
+ reg_inferior = (struct thread_info *) find_inferior_id (&all_threads, lwpid);
+ if (reg_inferior == NULL)
+ return PS_ERR;
+
+ save_inferior = current_inferior;
+ current_inferior = reg_inferior;
+
+ regcache = new_register_cache ();
+ fpregset_info()->store_function (fpregset, regcache);
+ the_target->store_registers (0, regcache);
+ free_register_cache (regcache);
+
+ current_inferior = save_inferior;
+
+ return PS_OK;
+#endif
+ /* FIXME */
+ return PS_ERR;
+}
+
+/* Return overall process id of the target PH. Special for GNU/Linux
+ -- not used on Solaris. */
+
+pid_t
+ps_getpid (gdb_ps_prochandle_t ph)
+{
+ return ph->pid;
+}
+
+
diff --git a/gdb/gdbserver/regcache.c b/gdb/gdbserver/regcache.c
new file mode 100644
index 00000000000..701d09232f8
--- /dev/null
+++ b/gdb/gdbserver/regcache.c
@@ -0,0 +1,188 @@
+/* Register support routines for the remote server for GDB.
+ Copyright 2001, 2002
+ 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 "server.h"
+#include "regdef.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+struct inferior_regcache_data
+{
+ char *registers;
+};
+
+static int register_bytes;
+
+static struct reg *reg_defs;
+static int num_registers;
+
+const char **gdbserver_expedite_regs;
+
+static struct inferior_regcache_data *
+get_regcache (struct inferior_info *inf)
+{
+ struct inferior_regcache_data *regcache;
+
+ regcache = (struct inferior_regcache_data *) inferior_regcache_data (inf);
+
+ if (regcache == NULL)
+ fatal ("no register cache");
+
+ return regcache;
+}
+
+int
+registers_length (void)
+{
+ return 2 * register_bytes;
+}
+
+void
+create_register_cache (struct inferior_info *inferior)
+{
+ struct inferior_regcache_data *regcache;
+
+ regcache = malloc (sizeof (*regcache));
+
+ regcache->registers = malloc (register_bytes);
+ if (regcache->registers == NULL)
+ fatal ("Could not allocate register cache.");
+
+ set_inferior_regcache_data (inferior, regcache);
+}
+
+void
+free_register_cache (struct inferior_info *inferior)
+{
+ free (get_regcache (current_inferior)->registers);
+ free (get_regcache (current_inferior));
+ set_inferior_regcache_data (inferior, NULL);
+}
+
+void
+set_register_cache (struct reg *regs, int n)
+{
+ int offset, i;
+
+ reg_defs = regs;
+ num_registers = n;
+
+ offset = 0;
+ for (i = 0; i < n; i++)
+ {
+ regs[i].offset = offset;
+ offset += regs[i].size;
+ }
+
+ register_bytes = offset / 8;
+}
+
+void
+registers_to_string (char *buf)
+{
+ char *registers = get_regcache (current_inferior)->registers;
+
+ convert_int_to_ascii (registers, buf, register_bytes);
+}
+
+void
+registers_from_string (char *buf)
+{
+ int len = strlen (buf);
+ char *registers = get_regcache (current_inferior)->registers;
+
+ if (len != register_bytes * 2)
+ {
+ warning ("Wrong sized register packet (expected %d bytes, got %d)", 2*register_bytes, len);
+ if (len > register_bytes * 2)
+ len = register_bytes * 2;
+ }
+ convert_ascii_to_int (buf, registers, len / 2);
+}
+
+struct reg *
+find_register_by_name (const char *name)
+{
+ int i;
+
+ for (i = 0; i < num_registers; i++)
+ if (!strcmp (name, reg_defs[i].name))
+ return &reg_defs[i];
+ fatal ("Unknown register %s requested", name);
+ return 0;
+}
+
+int
+find_regno (const char *name)
+{
+ int i;
+
+ for (i = 0; i < num_registers; i++)
+ if (!strcmp (name, reg_defs[i].name))
+ return i;
+ fatal ("Unknown register %s requested", name);
+ return -1;
+}
+
+struct reg *
+find_register_by_number (int n)
+{
+ return &reg_defs[n];
+}
+
+int
+register_size (int n)
+{
+ return reg_defs[n].size / 8;
+}
+
+char *
+register_data (int n)
+{
+ char *registers = get_regcache (current_inferior)->registers;
+
+ return registers + (reg_defs[n].offset / 8);
+}
+
+void
+supply_register (int n, const void *buf)
+{
+ memcpy (register_data (n), buf, register_size (n));
+}
+
+void
+supply_register_by_name (const char *name, const void *buf)
+{
+ supply_register (find_regno (name), buf);
+}
+
+void
+collect_register (int n, void *buf)
+{
+ memcpy (buf, register_data (n), register_size (n));
+}
+
+void
+collect_register_by_name (const char *name, void *buf)
+{
+ collect_register (find_regno (name), buf);
+}
diff --git a/gdb/gdbserver/regcache.h b/gdb/gdbserver/regcache.h
new file mode 100644
index 00000000000..362288ee049
--- /dev/null
+++ b/gdb/gdbserver/regcache.h
@@ -0,0 +1,67 @@
+/* Register support routines for the remote server for GDB.
+ Copyright 2001, 2002 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. */
+
+#ifndef REGCACHE_H
+#define REGCACHE_H
+
+struct inferior_info;
+
+/* Create a new register cache for INFERIOR. */
+
+void create_register_cache (struct inferior_info *inferior);
+
+/* Release all memory associated with the register cache for INFERIOR. */
+
+void free_register_cache (struct inferior_info *inferior);
+
+/* Convert all registers to a string in the currently specified remote
+ format. */
+
+void registers_to_string (char *buf);
+
+/* Convert a string to register values and fill our register cache. */
+
+void registers_from_string (char *buf);
+
+/* Return the size in bytes of a string-encoded register packet. */
+
+int registers_length (void);
+
+/* Return a pointer to the description of register ``n''. */
+
+struct reg *find_register_by_number (int n);
+
+char *register_data (int n);
+
+int register_size (int n);
+
+int find_regno (const char *name);
+
+extern const char **gdbserver_expedite_regs;
+
+void supply_register (int n, const void *buf);
+
+void supply_register_by_name (const char *name, const void *buf);
+
+void collect_register (int n, void *buf);
+
+void collect_register_by_name (const char *name, void *buf);
+
+#endif /* REGCACHE_H */
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
new file mode 100644
index 00000000000..14734f161bd
--- /dev/null
+++ b/gdb/gdbserver/remote-utils.c
@@ -0,0 +1,639 @@
+/* Remote utility routines for the remote server for GDB.
+ Copyright 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ 2002
+ 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 "server.h"
+#include "terminal.h"
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/tcp.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+
+int remote_debug = 0;
+struct ui_file *gdb_stdlog;
+
+static int remote_desc;
+
+/* Open a connection to a remote debugger.
+ NAME is the filename used for communication. */
+
+void
+remote_open (char *name)
+{
+ int save_fcntl_flags;
+
+ if (!strchr (name, ':'))
+ {
+ remote_desc = open (name, O_RDWR);
+ if (remote_desc < 0)
+ perror_with_name ("Could not open remote device");
+
+#ifdef HAVE_TERMIOS
+ {
+ struct termios termios;
+ tcgetattr (remote_desc, &termios);
+
+ termios.c_iflag = 0;
+ termios.c_oflag = 0;
+ termios.c_lflag = 0;
+ termios.c_cflag &= ~(CSIZE | PARENB);
+ termios.c_cflag |= CLOCAL | CS8;
+ termios.c_cc[VMIN] = 1;
+ termios.c_cc[VTIME] = 0;
+
+ tcsetattr (remote_desc, TCSANOW, &termios);
+ }
+#endif
+
+#ifdef HAVE_TERMIO
+ {
+ struct termio termio;
+ ioctl (remote_desc, TCGETA, &termio);
+
+ termio.c_iflag = 0;
+ termio.c_oflag = 0;
+ termio.c_lflag = 0;
+ termio.c_cflag &= ~(CSIZE | PARENB);
+ termio.c_cflag |= CLOCAL | CS8;
+ termio.c_cc[VMIN] = 1;
+ termio.c_cc[VTIME] = 0;
+
+ ioctl (remote_desc, TCSETA, &termio);
+ }
+#endif
+
+#ifdef HAVE_SGTTY
+ {
+ struct sgttyb sg;
+
+ ioctl (remote_desc, TIOCGETP, &sg);
+ sg.sg_flags = RAW;
+ ioctl (remote_desc, TIOCSETP, &sg);
+ }
+#endif
+
+ fprintf (stderr, "Remote debugging using %s\n", name);
+ }
+ else
+ {
+ char *port_str;
+ int port;
+ struct sockaddr_in sockaddr;
+ int tmp;
+ int tmp_desc;
+
+ port_str = strchr (name, ':');
+
+ port = atoi (port_str + 1);
+
+ tmp_desc = socket (PF_INET, SOCK_STREAM, 0);
+ if (tmp_desc < 0)
+ perror_with_name ("Can't open socket");
+
+ /* Allow rapid reuse of this port. */
+ tmp = 1;
+ setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
+ sizeof (tmp));
+
+ sockaddr.sin_family = PF_INET;
+ sockaddr.sin_port = htons (port);
+ sockaddr.sin_addr.s_addr = INADDR_ANY;
+
+ if (bind (tmp_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
+ || listen (tmp_desc, 1))
+ perror_with_name ("Can't bind address");
+
+ tmp = sizeof (sockaddr);
+ remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp);
+ if (remote_desc == -1)
+ perror_with_name ("Accept failed");
+
+ /* Enable TCP keep alive process. */
+ tmp = 1;
+ setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *) &tmp, sizeof (tmp));
+
+ /* Tell TCP not to delay small packets. This greatly speeds up
+ interactive response. */
+ tmp = 1;
+ setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
+ (char *) &tmp, sizeof (tmp));
+
+ close (tmp_desc); /* No longer need this */
+
+ signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply
+ exits when the remote side dies. */
+
+ /* Convert IP address to string. */
+ fprintf (stderr, "Remote debugging from host %s\n",
+ inet_ntoa (sockaddr.sin_addr));
+ }
+
+#if defined(F_SETFL) && defined (FASYNC)
+ save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0);
+ fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC);
+#if defined (F_SETOWN)
+ fcntl (remote_desc, F_SETOWN, getpid ());
+#endif
+#endif
+ disable_async_io ();
+}
+
+void
+remote_close (void)
+{
+ close (remote_desc);
+}
+
+/* Convert hex digit A to a number. */
+
+static int
+fromhex (int a)
+{
+ if (a >= '0' && a <= '9')
+ return a - '0';
+ else if (a >= 'a' && a <= 'f')
+ return a - 'a' + 10;
+ else
+ error ("Reply contains invalid hex digit");
+ return 0;
+}
+
+int
+unhexify (char *bin, const char *hex, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ if (hex[0] == 0 || hex[1] == 0)
+ {
+ /* Hex string is short, or of uneven length.
+ Return the count that has been converted so far. */
+ return i;
+ }
+ *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
+ hex += 2;
+ }
+ return i;
+}
+
+static void
+decode_address (CORE_ADDR *addrp, const char *start, int len)
+{
+ CORE_ADDR addr;
+ char ch;
+ int i;
+
+ addr = 0;
+ for (i = 0; i < len; i++)
+ {
+ ch = start[i];
+ addr = addr << 4;
+ addr = addr | (fromhex (ch) & 0x0f);
+ }
+ *addrp = addr;
+}
+
+/* Convert number NIB to a hex digit. */
+
+static int
+tohex (int nib)
+{
+ if (nib < 10)
+ return '0' + nib;
+ else
+ return 'a' + nib - 10;
+}
+
+int
+hexify (char *hex, const char *bin, int count)
+{
+ int i;
+
+ /* May use a length, or a nul-terminated string as input. */
+ if (count == 0)
+ count = strlen (bin);
+
+ for (i = 0; i < count; i++)
+ {
+ *hex++ = tohex ((*bin >> 4) & 0xf);
+ *hex++ = tohex (*bin++ & 0xf);
+ }
+ *hex = 0;
+ return i;
+}
+
+/* Send a packet to the remote machine, with error checking.
+ The data of the packet is in BUF. Returns >= 0 on success, -1 otherwise. */
+
+int
+putpkt (char *buf)
+{
+ int i;
+ unsigned char csum = 0;
+ char *buf2;
+ char buf3[1];
+ int cnt = strlen (buf);
+ char *p;
+
+ buf2 = malloc (PBUFSIZ);
+
+ /* Copy the packet into buffer BUF2, encapsulating it
+ and giving it a checksum. */
+
+ p = buf2;
+ *p++ = '$';
+
+ for (i = 0; i < cnt; i++)
+ {
+ csum += buf[i];
+ *p++ = buf[i];
+ }
+ *p++ = '#';
+ *p++ = tohex ((csum >> 4) & 0xf);
+ *p++ = tohex (csum & 0xf);
+
+ *p = '\0';
+
+ /* Send it over and over until we get a positive ack. */
+
+ do
+ {
+ int cc;
+
+ if (write (remote_desc, buf2, p - buf2) != p - buf2)
+ {
+ perror ("putpkt(write)");
+ return -1;
+ }
+
+ if (remote_debug)
+ printf ("putpkt (\"%s\"); [looking for ack]\n", buf2);
+ cc = read (remote_desc, buf3, 1);
+ if (remote_debug)
+ printf ("[received '%c' (0x%x)]\n", buf3[0], buf3[0]);
+ if (cc <= 0)
+ {
+ if (cc == 0)
+ fprintf (stderr, "putpkt(read): Got EOF\n");
+ else
+ perror ("putpkt(read)");
+
+ free (buf2);
+ return -1;
+ }
+ }
+ while (buf3[0] != '+');
+
+ free (buf2);
+ return 1; /* Success! */
+}
+
+/* Come here when we get an input interrupt from the remote side. This
+ interrupt should only be active while we are waiting for the child to do
+ something. About the only thing that should come through is a ^C, which
+ will cause us to send a SIGINT to the child. */
+
+static void
+input_interrupt (int unused)
+{
+ fd_set readset;
+ struct timeval immediate = { 0, 0 };
+
+ /* Protect against spurious interrupts. This has been observed to
+ be a problem under NetBSD 1.4 and 1.5. */
+
+ FD_ZERO (&readset);
+ FD_SET (remote_desc, &readset);
+ if (select (remote_desc + 1, &readset, 0, 0, &immediate) > 0)
+ {
+ int cc;
+ char c;
+
+ cc = read (remote_desc, &c, 1);
+
+ if (cc != 1 || c != '\003')
+ {
+ fprintf (stderr, "input_interrupt, cc = %d c = %d\n", cc, c);
+ return;
+ }
+
+ kill (signal_pid, SIGINT);
+ }
+}
+
+void
+enable_async_io (void)
+{
+ signal (SIGIO, input_interrupt);
+}
+
+void
+disable_async_io (void)
+{
+ signal (SIGIO, SIG_IGN);
+}
+
+/* Returns next char from remote GDB. -1 if error. */
+
+static int
+readchar (void)
+{
+ static char buf[BUFSIZ];
+ static int bufcnt = 0;
+ static char *bufp;
+
+ if (bufcnt-- > 0)
+ return *bufp++ & 0x7f;
+
+ bufcnt = read (remote_desc, buf, sizeof (buf));
+
+ if (bufcnt <= 0)
+ {
+ if (bufcnt == 0)
+ fprintf (stderr, "readchar: Got EOF\n");
+ else
+ perror ("readchar");
+
+ return -1;
+ }
+
+ bufp = buf;
+ bufcnt--;
+ return *bufp++ & 0x7f;
+}
+
+/* Read a packet from the remote machine, with error checking,
+ and store it in BUF. Returns length of packet, or negative if error. */
+
+int
+getpkt (char *buf)
+{
+ char *bp;
+ unsigned char csum, c1, c2;
+ int c;
+
+ while (1)
+ {
+ csum = 0;
+
+ while (1)
+ {
+ c = readchar ();
+ if (c == '$')
+ break;
+ if (remote_debug)
+ printf ("[getpkt: discarding char '%c']\n", c);
+ if (c < 0)
+ return -1;
+ }
+
+ bp = buf;
+ while (1)
+ {
+ c = readchar ();
+ if (c < 0)
+ return -1;
+ if (c == '#')
+ break;
+ *bp++ = c;
+ csum += c;
+ }
+ *bp = 0;
+
+ c1 = fromhex (readchar ());
+ c2 = fromhex (readchar ());
+
+ if (csum == (c1 << 4) + c2)
+ break;
+
+ fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
+ (c1 << 4) + c2, csum, buf);
+ write (remote_desc, "-", 1);
+ }
+
+ if (remote_debug)
+ printf ("getpkt (\"%s\"); [sending ack] \n", buf);
+
+ write (remote_desc, "+", 1);
+
+ if (remote_debug)
+ printf ("[sent ack]\n");
+ return bp - buf;
+}
+
+void
+write_ok (char *buf)
+{
+ buf[0] = 'O';
+ buf[1] = 'K';
+ buf[2] = '\0';
+}
+
+void
+write_enn (char *buf)
+{
+ buf[0] = 'E';
+ buf[1] = 'N';
+ buf[2] = 'N';
+ buf[3] = '\0';
+}
+
+void
+convert_int_to_ascii (char *from, char *to, int n)
+{
+ int nib;
+ char ch;
+ while (n--)
+ {
+ ch = *from++;
+ nib = ((ch & 0xf0) >> 4) & 0x0f;
+ *to++ = tohex (nib);
+ nib = ch & 0x0f;
+ *to++ = tohex (nib);
+ }
+ *to++ = 0;
+}
+
+
+void
+convert_ascii_to_int (char *from, char *to, int n)
+{
+ int nib1, nib2;
+ while (n--)
+ {
+ nib1 = fromhex (*from++);
+ nib2 = fromhex (*from++);
+ *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
+ }
+}
+
+static char *
+outreg (int regno, char *buf)
+{
+ int regsize = register_size (regno);
+
+ if ((regno >> 12) != 0)
+ *buf++ = tohex ((regno >> 12) & 0xf);
+ if ((regno >> 8) != 0)
+ *buf++ = tohex ((regno >> 8) & 0xf);
+ *buf++ = tohex ((regno >> 4) & 0xf);
+ *buf++ = tohex (regno & 0xf);
+ *buf++ = ':';
+ convert_int_to_ascii (register_data (regno), buf, regsize);
+ buf += 2 * regsize;
+ *buf++ = ';';
+
+ return buf;
+}
+
+void
+prepare_resume_reply (char *buf, char status, unsigned char signo)
+{
+ int nib, sig;
+
+ *buf++ = status;
+
+ sig = (int)target_signal_from_host (signo);
+
+ nib = ((sig & 0xf0) >> 4);
+ *buf++ = tohex (nib);
+ nib = sig & 0x0f;
+ *buf++ = tohex (nib);
+
+ if (status == 'T')
+ {
+ const char **regp = gdbserver_expedite_regs;
+ while (*regp)
+ {
+ buf = outreg (find_regno (*regp), buf);
+ regp ++;
+ }
+
+ /* If the debugger hasn't used any thread features, don't burden it with
+ threads. If we didn't check this, GDB 4.13 and older would choke. */
+ if (cont_thread != 0)
+ {
+ if (old_thread_from_wait != thread_from_wait)
+ {
+ sprintf (buf, "thread:%x;", thread_from_wait);
+ buf += strlen (buf);
+ old_thread_from_wait = thread_from_wait;
+ }
+ }
+ }
+ /* For W and X, we're done. */
+ *buf++ = 0;
+}
+
+void
+decode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr)
+{
+ int i = 0, j = 0;
+ char ch;
+ *mem_addr_ptr = *len_ptr = 0;
+
+ while ((ch = from[i++]) != ',')
+ {
+ *mem_addr_ptr = *mem_addr_ptr << 4;
+ *mem_addr_ptr |= fromhex (ch) & 0x0f;
+ }
+
+ for (j = 0; j < 4; j++)
+ {
+ if ((ch = from[i++]) == 0)
+ break;
+ *len_ptr = *len_ptr << 4;
+ *len_ptr |= fromhex (ch) & 0x0f;
+ }
+}
+
+void
+decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr,
+ char *to)
+{
+ int i = 0;
+ char ch;
+ *mem_addr_ptr = *len_ptr = 0;
+
+ while ((ch = from[i++]) != ',')
+ {
+ *mem_addr_ptr = *mem_addr_ptr << 4;
+ *mem_addr_ptr |= fromhex (ch) & 0x0f;
+ }
+
+ while ((ch = from[i++]) != ':')
+ {
+ *len_ptr = *len_ptr << 4;
+ *len_ptr |= fromhex (ch) & 0x0f;
+ }
+
+ convert_ascii_to_int (&from[i++], to, *len_ptr);
+}
+
+int
+look_up_one_symbol (const char *name, CORE_ADDR *addrp)
+{
+ char own_buf[266], *p, *q;
+ int len;
+
+ /* Send the request. */
+ strcpy (own_buf, "qSymbol:");
+ hexify (own_buf + strlen ("qSymbol:"), name, strlen (name));
+ if (putpkt (own_buf) < 0)
+ return -1;
+
+ /* FIXME: Eventually add buffer overflow checking (to getpkt?) */
+ len = getpkt (own_buf);
+ if (len < 0)
+ return -1;
+
+ if (strncmp (own_buf, "qSymbol:", strlen ("qSymbol:")) != 0)
+ {
+ /* Malformed response. */
+ if (remote_debug)
+ fprintf (stderr, "Malformed response to qSymbol, ignoring.\n");
+ return -1;
+ }
+
+ p = own_buf + strlen ("qSymbol:");
+ q = p;
+ while (*q && *q != ':')
+ q++;
+
+ /* Make sure we found a value for the symbol. */
+ if (p == q || *q == '\0')
+ return 0;
+
+ decode_address (addrp, p, q - p);
+ return 1;
+}
+
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
new file mode 100644
index 00000000000..a31547c9b39
--- /dev/null
+++ b/gdb/gdbserver/server.c
@@ -0,0 +1,359 @@
+/* Main code for remote server for GDB.
+ Copyright 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002
+ 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 "server.h"
+
+int cont_thread;
+int general_thread;
+int thread_from_wait;
+int old_thread_from_wait;
+int extended_protocol;
+jmp_buf toplevel;
+
+static unsigned char
+start_inferior (char *argv[], char *statusptr)
+{
+ /* FIXME Check error? Or turn to void. */
+ create_inferior (argv[0], argv);
+ /* FIXME Print pid properly. */
+ fprintf (stderr, "Process %s created; pid = %d\n", argv[0], signal_pid);
+
+ /* Wait till we are at 1st instruction in program, return signal number. */
+ return mywait (statusptr);
+}
+
+static int
+attach_inferior (int pid, char *statusptr, unsigned char *sigptr)
+{
+ /* myattach should return -1 if attaching is unsupported,
+ 0 if it succeeded, and call error() otherwise. */
+ if (myattach (pid) != 0)
+ return -1;
+
+ *sigptr = mywait (statusptr);
+
+ return 0;
+}
+
+extern int remote_debug;
+
+/* Handle all of the extended 'q' packets. */
+void
+handle_query (char *own_buf)
+{
+ if (strcmp ("qSymbol::", own_buf) == 0)
+ {
+ if (the_target->look_up_symbols != NULL)
+ (*the_target->look_up_symbols) ();
+
+ strcpy (own_buf, "OK");
+ return;
+ }
+
+ /* Otherwise we didn't know what packet it was. Say we didn't
+ understand it. */
+ own_buf[0] = 0;
+}
+
+static int attached;
+
+static void
+gdbserver_usage (void)
+{
+ error ("Usage:\tgdbserver COMM PROG [ARGS ...]\n"
+ "\tgdbserver COMM --attach PID\n"
+ "\n"
+ "COMM may either be a tty device (for serial debugging), or \n"
+ "HOST:PORT to listen for a TCP connection.\n");
+}
+
+int
+main (int argc, char *argv[])
+{
+ char ch, status, *own_buf, mem_buf[2000];
+ int i = 0;
+ unsigned char signal;
+ unsigned int len;
+ CORE_ADDR mem_addr;
+ int bad_attach;
+ int pid;
+ char *arg_end;
+
+ if (setjmp (toplevel))
+ {
+ fprintf (stderr, "Exiting\n");
+ exit (1);
+ }
+
+ bad_attach = 0;
+ pid = 0;
+ attached = 0;
+ if (argc >= 3 && strcmp (argv[2], "--attach") == 0)
+ {
+ if (argc == 4
+ && argv[3] != '\0'
+ && (pid = strtoul (argv[3], &arg_end, 10)) != 0
+ && *arg_end == '\0')
+ {
+ ;
+ }
+ else
+ bad_attach = 1;
+ }
+
+ if (argc < 3 || bad_attach)
+ gdbserver_usage();
+
+ initialize_low ();
+
+ own_buf = malloc (PBUFSIZ);
+
+ if (pid == 0)
+ {
+ /* Wait till we are at first instruction in program. */
+ signal = start_inferior (&argv[2], &status);
+
+ /* We are now stopped at the first instruction of the target process */
+ }
+ else
+ {
+ switch (attach_inferior (pid, &status, &signal))
+ {
+ case -1:
+ error ("Attaching not supported on this target");
+ break;
+ default:
+ attached = 1;
+ break;
+ }
+ }
+
+ while (1)
+ {
+ remote_open (argv[1]);
+
+ restart:
+ setjmp (toplevel);
+ while (getpkt (own_buf) > 0)
+ {
+ unsigned char sig;
+ i = 0;
+ ch = own_buf[i++];
+ switch (ch)
+ {
+ case 'q':
+ handle_query (own_buf);
+ break;
+ case 'd':
+ remote_debug = !remote_debug;
+ break;
+ case '!':
+ if (attached == 0)
+ {
+ extended_protocol = 1;
+ prepare_resume_reply (own_buf, status, signal);
+ }
+ else
+ {
+ /* We can not use the extended protocol if we are
+ attached, because we can not restart the running
+ program. So return unrecognized. */
+ own_buf[0] = '\0';
+ }
+ break;
+ case '?':
+ prepare_resume_reply (own_buf, status, signal);
+ break;
+ case 'H':
+ switch (own_buf[1])
+ {
+ case 'g':
+ general_thread = strtol (&own_buf[2], NULL, 16);
+ write_ok (own_buf);
+ fetch_inferior_registers (0);
+ break;
+ case 'c':
+ cont_thread = strtol (&own_buf[2], NULL, 16);
+ write_ok (own_buf);
+ break;
+ default:
+ /* Silently ignore it so that gdb can extend the protocol
+ without compatibility headaches. */
+ own_buf[0] = '\0';
+ break;
+ }
+ break;
+ case 'g':
+ registers_to_string (own_buf);
+ break;
+ case 'G':
+ registers_from_string (&own_buf[1]);
+ store_inferior_registers (-1);
+ write_ok (own_buf);
+ break;
+ case 'm':
+ decode_m_packet (&own_buf[1], &mem_addr, &len);
+ read_inferior_memory (mem_addr, mem_buf, len);
+ convert_int_to_ascii (mem_buf, own_buf, len);
+ break;
+ case 'M':
+ decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
+ if (write_inferior_memory (mem_addr, mem_buf, len) == 0)
+ write_ok (own_buf);
+ else
+ write_enn (own_buf);
+ break;
+ case 'C':
+ convert_ascii_to_int (own_buf + 1, &sig, 1);
+ if (target_signal_to_host_p (sig))
+ signal = target_signal_to_host (sig);
+ else
+ signal = 0;
+ myresume (0, signal);
+ signal = mywait (&status);
+ prepare_resume_reply (own_buf, status, signal);
+ break;
+ case 'S':
+ convert_ascii_to_int (own_buf + 1, &sig, 1);
+ if (target_signal_to_host_p (sig))
+ signal = target_signal_to_host (sig);
+ else
+ signal = 0;
+ myresume (1, signal);
+ signal = mywait (&status);
+ prepare_resume_reply (own_buf, status, signal);
+ break;
+ case 'c':
+ myresume (0, 0);
+ signal = mywait (&status);
+ prepare_resume_reply (own_buf, status, signal);
+ break;
+ case 's':
+ myresume (1, 0);
+ signal = mywait (&status);
+ prepare_resume_reply (own_buf, status, signal);
+ break;
+ case 'k':
+ fprintf (stderr, "Killing inferior\n");
+ kill_inferior ();
+ /* When using the extended protocol, we start up a new
+ debugging session. The traditional protocol will
+ exit instead. */
+ if (extended_protocol)
+ {
+ write_ok (own_buf);
+ fprintf (stderr, "GDBserver restarting\n");
+
+ /* Wait till we are at 1st instruction in prog. */
+ signal = start_inferior (&argv[2], &status);
+ goto restart;
+ break;
+ }
+ else
+ {
+ exit (0);
+ break;
+ }
+ case 'T':
+ if (mythread_alive (strtol (&own_buf[1], NULL, 16)))
+ write_ok (own_buf);
+ else
+ write_enn (own_buf);
+ break;
+ case 'R':
+ /* Restarting the inferior is only supported in the
+ extended protocol. */
+ if (extended_protocol)
+ {
+ kill_inferior ();
+ write_ok (own_buf);
+ fprintf (stderr, "GDBserver restarting\n");
+
+ /* Wait till we are at 1st instruction in prog. */
+ signal = start_inferior (&argv[2], &status);
+ goto restart;
+ break;
+ }
+ else
+ {
+ /* It is a request we don't understand. Respond with an
+ empty packet so that gdb knows that we don't support this
+ request. */
+ own_buf[0] = '\0';
+ break;
+ }
+ default:
+ /* It is a request we don't understand. Respond with an
+ empty packet so that gdb knows that we don't support this
+ request. */
+ own_buf[0] = '\0';
+ break;
+ }
+
+ putpkt (own_buf);
+
+ if (status == 'W')
+ fprintf (stderr,
+ "\nChild exited with status %d\n", sig);
+ if (status == 'X')
+ fprintf (stderr, "\nChild terminated with signal = 0x%x\n", sig);
+ if (status == 'W' || status == 'X')
+ {
+ if (extended_protocol)
+ {
+ fprintf (stderr, "Killing inferior\n");
+ kill_inferior ();
+ write_ok (own_buf);
+ fprintf (stderr, "GDBserver restarting\n");
+
+ /* Wait till we are at 1st instruction in prog. */
+ signal = start_inferior (&argv[2], &status);
+ goto restart;
+ break;
+ }
+ else
+ {
+ fprintf (stderr, "GDBserver exiting\n");
+ exit (0);
+ }
+ }
+ }
+
+ /* We come here when getpkt fails.
+
+ For the extended remote protocol we exit (and this is the only
+ way we gracefully exit!).
+
+ For the traditional remote protocol close the connection,
+ and re-open it at the top of the loop. */
+ if (extended_protocol)
+ {
+ remote_close ();
+ exit (0);
+ }
+ else
+ {
+ fprintf (stderr, "Remote side has terminated connection. "
+ "GDBserver will reopen the connection.\n");
+ remote_close ();
+ }
+ }
+}
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
new file mode 100644
index 00000000000..32b90b5bcc7
--- /dev/null
+++ b/gdb/gdbserver/server.h
@@ -0,0 +1,144 @@
+/* Common definitions for remote server for GDB.
+ Copyright 1993, 1995, 1997, 1998, 1999, 2000, 2002
+ 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. */
+
+#ifndef SERVER_H
+#define SERVER_H
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <setjmp.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifndef ATTR_NORETURN
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))
+#define ATTR_NORETURN __attribute__ ((noreturn))
+#else
+#define ATTR_NORETURN /* nothing */
+#endif
+#endif
+
+#ifndef ATTR_FORMAT
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 4))
+#define ATTR_FORMAT(type, x, y) __attribute__ ((format(type, x, y)))
+#else
+#define ATTR_FORMAT(type, x, y) /* nothing */
+#endif
+#endif
+
+/* FIXME: This should probably be autoconf'd for. It's an integer type at
+ least the size of a (void *). */
+typedef long long CORE_ADDR;
+
+/* Opaque inferior process information. */
+struct inferior_info;
+
+#include "regcache.h"
+#include "gdb/signals.h"
+
+#include "target.h"
+#include "mem-break.h"
+
+/* Target-specific functions */
+
+void initialize_low ();
+
+/* Target-specific variables */
+
+extern char *registers;
+
+/* From inferiors.c. */
+
+extern struct inferior_info *current_inferior;
+extern int signal_pid;
+void add_inferior (int pid);
+void clear_inferiors (void);
+void *inferior_target_data (struct inferior_info *);
+void set_inferior_target_data (struct inferior_info *, void *);
+void *inferior_regcache_data (struct inferior_info *);
+void set_inferior_regcache_data (struct inferior_info *, void *);
+
+/* Public variables in server.c */
+
+extern int cont_thread;
+extern int general_thread;
+extern int thread_from_wait;
+extern int old_thread_from_wait;
+
+extern jmp_buf toplevel;
+
+/* Functions from remote-utils.c */
+
+int putpkt (char *buf);
+int getpkt (char *buf);
+void remote_open (char *name);
+void remote_close (void);
+void write_ok (char *buf);
+void write_enn (char *buf);
+void enable_async_io (void);
+void disable_async_io (void);
+void convert_ascii_to_int (char *from, char *to, int n);
+void convert_int_to_ascii (char *from, char *to, int n);
+void prepare_resume_reply (char *buf, char status, unsigned char sig);
+
+void decode_m_packet (char *from, CORE_ADDR * mem_addr_ptr,
+ unsigned int *len_ptr);
+void decode_M_packet (char *from, CORE_ADDR * mem_addr_ptr,
+ unsigned int *len_ptr, char *to);
+
+int unhexify (char *bin, const char *hex, int count);
+int hexify (char *hex, const char *bin, int count);
+
+int look_up_one_symbol (const char *name, CORE_ADDR *addrp);
+
+/* Functions from ``signals.c''. */
+enum target_signal target_signal_from_host (int hostsig);
+int target_signal_to_host_p (enum target_signal oursig);
+int target_signal_to_host (enum target_signal oursig);
+
+/* Functions from utils.c */
+
+void perror_with_name (char *string);
+void error (const char *string,...) ATTR_NORETURN;
+void fatal (const char *string,...) ATTR_NORETURN;
+void warning (const char *string,...);
+
+/* Functions from the register cache definition. */
+
+void init_registers (void);
+
+/* Maximum number of bytes to read/write at once. The value here
+ is chosen to fill up a packet (the headers account for the 32). */
+#define MAXBUFBYTES(N) (((N)-32)/2)
+
+/* Buffer sizes for transferring memory, registers, etc. Round up PBUFSIZ to
+ hold all the registers, at least. */
+#define PBUFSIZ ((registers_length () + 32 > 2000) \
+ ? (registers_length () + 32) \
+ : 2000)
+
+#endif /* SERVER_H */
diff --git a/gdb/gdbserver/target.c b/gdb/gdbserver/target.c
new file mode 100644
index 00000000000..53a4c1ef55a
--- /dev/null
+++ b/gdb/gdbserver/target.c
@@ -0,0 +1,47 @@
+/* Target operations for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ 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 "server.h"
+
+struct target_ops *the_target;
+
+void
+read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ (*the_target->read_memory) (memaddr, myaddr, len);
+ check_mem_read (memaddr, myaddr, len);
+}
+
+int
+write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ check_mem_write (memaddr, myaddr, len);
+ return (*the_target->write_memory) (memaddr, myaddr, len);
+}
+
+void
+set_target_ops (struct target_ops *target)
+{
+ the_target = (struct target_ops *) malloc (sizeof (*the_target));
+ memcpy (the_target, target, sizeof (*the_target));
+}
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
new file mode 100644
index 00000000000..6d06b9fd4ab
--- /dev/null
+++ b/gdb/gdbserver/target.h
@@ -0,0 +1,141 @@
+/* Target operations for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ 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. */
+
+#ifndef TARGET_H
+#define TARGET_H
+
+struct target_ops
+{
+ /* Start a new process.
+
+ PROGRAM is a path to the program to execute.
+ ARGS is a standard NULL-terminated array of arguments,
+ to be passed to the inferior as ``argv''.
+
+ Returns 0 on success, -1 on failure. Registers the new
+ process with the process list. */
+
+ int (*create_inferior) (char *program, char **args);
+
+ /* Attach to a running process.
+
+ PID is the process ID to attach to, specified by the user
+ or a higher layer. */
+
+ int (*attach) (int pid);
+
+ /* Kill all inferiors. */
+
+ void (*kill) (void);
+
+ /* Return 1 iff the thread with process ID PID is alive. */
+
+ int (*thread_alive) (int pid);
+
+ /* Resume the inferior process.
+
+ If STEP is non-zero, we want to single-step.
+
+ If SIGNAL is nonzero, send the process that signal as we resume it.
+ */
+
+ void (*resume) (int step, int signo);
+
+ /* Wait for the inferior process to change state.
+
+ STATUSP will be filled in with a response code to send to GDB.
+
+ Returns the signal which caused the process to stop. */
+
+ unsigned char (*wait) (char *status);
+
+ /* Fetch registers from the inferior process.
+
+ If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
+
+ void (*fetch_registers) (int regno);
+
+ /* Store registers to the inferior process.
+
+ If REGNO is -1, store all registers; otherwise, store at least REGNO. */
+
+ void (*store_registers) (int regno);
+
+ /* Read memory from the inferior process. This should generally be
+ called through read_inferior_memory, which handles breakpoint shadowing.
+
+ Read LEN bytes at MEMADDR into a buffer at MYADDR. */
+
+ void (*read_memory) (CORE_ADDR memaddr, char *myaddr, int len);
+
+ /* Write memory to the inferior process. This should generally be
+ called through write_inferior_memory, which handles breakpoint shadowing.
+
+ Write LEN bytes from the buffer at MYADDR to MEMADDR.
+
+ Returns 0 on success and errno on failure. */
+
+ int (*write_memory) (CORE_ADDR memaddr, const char *myaddr, int len);
+
+ /* Query GDB for the values of any symbols we're interested in.
+ This function is called whenever we receive a "qSymbols::"
+ query, which corresponds to every time more symbols (might)
+ become available. NULL if we aren't interested in any
+ symbols. */
+
+ void (*look_up_symbols) (void);
+};
+
+extern struct target_ops *the_target;
+
+void set_target_ops (struct target_ops *);
+
+#define create_inferior(program, args) \
+ (*the_target->create_inferior) (program, args)
+
+#define myattach(pid) \
+ (*the_target->attach) (pid)
+
+#define kill_inferior() \
+ (*the_target->kill) ()
+
+#define mythread_alive(pid) \
+ (*the_target->thread_alive) (pid)
+
+#define myresume(step,signo) \
+ (*the_target->resume) (step, signo)
+
+#define mywait(statusp) \
+ (*the_target->wait) (statusp)
+
+#define fetch_inferior_registers(regno) \
+ (*the_target->fetch_registers) (regno)
+
+#define store_inferior_registers(regno) \
+ (*the_target->store_registers) (regno)
+
+void read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len);
+
+int write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len);
+
+#endif /* TARGET_H */
diff --git a/gdb/gdbserver/terminal.h b/gdb/gdbserver/terminal.h
new file mode 100644
index 00000000000..69b6692ceff
--- /dev/null
+++ b/gdb/gdbserver/terminal.h
@@ -0,0 +1,51 @@
+/* Terminal interface definitions for the GDB remote server.
+ Copyright 2002, 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. */
+
+#if !defined (TERMINAL_H)
+#define TERMINAL_H 1
+
+/* Autoconf will have defined HAVE_TERMIOS_H, HAVE_TERMIO_H,
+ and HAVE_SGTTY_H for us as appropriate. */
+
+#if defined(HAVE_TERMIOS_H)
+#define HAVE_TERMIOS
+#include <termios.h>
+#else /* ! HAVE_TERMIOS_H */
+#if defined(HAVE_TERMIO_H)
+#define HAVE_TERMIO
+#include <termio.h>
+
+#undef TIOCGETP
+#define TIOCGETP TCGETA
+#undef TIOCSETN
+#define TIOCSETN TCSETA
+#undef TIOCSETP
+#define TIOCSETP TCSETAF
+#define TERMINAL struct termio
+#else /* ! HAVE_TERMIO_H; default to SGTTY. */
+#define HAVE_SGTTY
+#include <fcntl.h>
+#include <sgtty.h>
+#include <sys/ioctl.h>
+#define TERMINAL struct sgttyb
+#endif
+#endif
+
+#endif /* !defined (TERMINAL_H) */
diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c
new file mode 100644
index 00000000000..f3d57a54d62
--- /dev/null
+++ b/gdb/gdbserver/thread-db.c
@@ -0,0 +1,342 @@
+/* Thread management interface, for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ 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 "server.h"
+
+#include "linux-low.h"
+
+extern int debug_threads;
+
+#ifdef HAVE_THREAD_DB_H
+#include <thread_db.h>
+#endif
+
+/* Correct for all GNU/Linux targets (for quite some time). */
+#define GDB_GREGSET_T elf_gregset_t
+#define GDB_FPREGSET_T elf_fpregset_t
+
+#ifndef HAVE_ELF_FPREGSET_T
+/* Make sure we have said types. Not all platforms bring in <linux/elf.h>
+ via <sys/procfs.h>. */
+#ifdef HAVE_LINUX_ELF_H
+#include <linux/elf.h>
+#endif
+#endif
+
+#include "../gdb_proc_service.h"
+
+/* Structure that identifies the child process for the
+ <proc_service.h> interface. */
+static struct ps_prochandle proc_handle;
+
+/* Connection to the libthread_db library. */
+static td_thragent_t *thread_agent;
+
+static int find_new_threads_callback (const td_thrhandle_t *th_p, void *data);
+
+static char *
+thread_db_err_str (td_err_e err)
+{
+ static char buf[64];
+
+ switch (err)
+ {
+ case TD_OK:
+ return "generic 'call succeeded'";
+ case TD_ERR:
+ return "generic error";
+ case TD_NOTHR:
+ return "no thread to satisfy query";
+ case TD_NOSV:
+ return "no sync handle to satisfy query";
+ case TD_NOLWP:
+ return "no LWP to satisfy query";
+ case TD_BADPH:
+ return "invalid process handle";
+ case TD_BADTH:
+ return "invalid thread handle";
+ case TD_BADSH:
+ return "invalid synchronization handle";
+ case TD_BADTA:
+ return "invalid thread agent";
+ case TD_BADKEY:
+ return "invalid key";
+ case TD_NOMSG:
+ return "no event message for getmsg";
+ case TD_NOFPREGS:
+ return "FPU register set not available";
+ case TD_NOLIBTHREAD:
+ return "application not linked with libthread";
+ case TD_NOEVENT:
+ return "requested event is not supported";
+ case TD_NOCAPAB:
+ return "capability not available";
+ case TD_DBERR:
+ return "debugger service failed";
+ case TD_NOAPLIC:
+ return "operation not applicable to";
+ case TD_NOTSD:
+ return "no thread-specific data for this thread";
+ case TD_MALLOC:
+ return "malloc failed";
+ case TD_PARTIALREG:
+ return "only part of register set was written/read";
+ case TD_NOXREGS:
+ return "X register set not available for this thread";
+ default:
+ snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
+ return buf;
+ }
+}
+
+#if 0
+static char *
+thread_db_state_str (td_thr_state_e state)
+{
+ static char buf[64];
+
+ switch (state)
+ {
+ case TD_THR_STOPPED:
+ return "stopped by debugger";
+ case TD_THR_RUN:
+ return "runnable";
+ case TD_THR_ACTIVE:
+ return "active";
+ case TD_THR_ZOMBIE:
+ return "zombie";
+ case TD_THR_SLEEP:
+ return "sleeping";
+ case TD_THR_STOPPED_ASLEEP:
+ return "stopped by debugger AND blocked";
+ default:
+ snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
+ return buf;
+ }
+}
+#endif
+
+static void
+thread_db_create_event (CORE_ADDR where)
+{
+ td_event_msg_t msg;
+ td_err_e err;
+ struct inferior_linux_data *tdata;
+
+ if (debug_threads)
+ fprintf (stderr, "Thread creation event.\n");
+
+ tdata = inferior_target_data (current_inferior);
+
+ /* FIXME: This assumes we don't get another event.
+ In the LinuxThreads implementation, this is safe,
+ because all events come from the manager thread
+ (except for its own creation, of course). */
+ err = td_ta_event_getmsg (thread_agent, &msg);
+ if (err != TD_OK)
+ fprintf (stderr, "thread getmsg err: %s\n",
+ thread_db_err_str (err));
+
+ /* msg.event == TD_EVENT_CREATE */
+
+ find_new_threads_callback (msg.th_p, NULL);
+}
+
+#if 0
+static void
+thread_db_death_event (CORE_ADDR where)
+{
+ if (debug_threads)
+ fprintf (stderr, "Thread death event.\n");
+}
+#endif
+
+static int
+thread_db_enable_reporting ()
+{
+ td_thr_events_t events;
+ td_notify_t notify;
+ td_err_e err;
+
+ /* Set the process wide mask saying which events we're interested in. */
+ td_event_emptyset (&events);
+ td_event_addset (&events, TD_CREATE);
+
+#if 0
+ /* This is reported to be broken in glibc 2.1.3. A different approach
+ will be necessary to support that. */
+ td_event_addset (&events, TD_DEATH);
+#endif
+
+ err = td_ta_set_event (thread_agent, &events);
+ if (err != TD_OK)
+ {
+ warning ("Unable to set global thread event mask: %s",
+ thread_db_err_str (err));
+ return 0;
+ }
+
+ /* Get address for thread creation breakpoint. */
+ err = td_ta_event_addr (thread_agent, TD_CREATE, &notify);
+ if (err != TD_OK)
+ {
+ warning ("Unable to get location for thread creation breakpoint: %s",
+ thread_db_err_str (err));
+ return 0;
+ }
+ set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr,
+ thread_db_create_event);
+
+#if 0
+ /* Don't concern ourselves with reported thread deaths, only
+ with actual thread deaths (via wait). */
+
+ /* Get address for thread death breakpoint. */
+ err = td_ta_event_addr (thread_agent, TD_DEATH, &notify);
+ if (err != TD_OK)
+ {
+ warning ("Unable to get location for thread death breakpoint: %s",
+ thread_db_err_str (err));
+ return;
+ }
+ set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr,
+ thread_db_death_event);
+#endif
+
+ return 1;
+}
+
+static void
+maybe_attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
+{
+ td_err_e err;
+ struct thread_info *inferior;
+ struct process_info *process;
+
+ /* If we are attaching to our first thread, things are a little
+ different. */
+ if (all_threads.head == all_threads.tail)
+ {
+ inferior = (struct thread_info *) all_threads.head;
+ process = get_thread_process (inferior);
+ if (process->thread_known == 0)
+ {
+ /* Switch to indexing the threads list by TID. */
+ change_inferior_id (&all_threads, ti_p->ti_tid);
+ goto found;
+ }
+ }
+
+ inferior = (struct thread_info *) find_inferior_id (&all_threads,
+ ti_p->ti_tid);
+ if (inferior != NULL)
+ return;
+
+ if (debug_threads)
+ fprintf (stderr, "Attaching to thread %ld (LWP %d)\n",
+ ti_p->ti_tid, ti_p->ti_lid);
+ linux_attach_lwp (ti_p->ti_lid, ti_p->ti_tid);
+ inferior = (struct thread_info *) find_inferior_id (&all_threads,
+ ti_p->ti_tid);
+ if (inferior == NULL)
+ {
+ warning ("Could not attach to thread %ld (LWP %d)\n",
+ ti_p->ti_tid, ti_p->ti_lid);
+ return;
+ }
+
+ process = inferior_target_data (inferior);
+
+found:
+ new_thread_notify (ti_p->ti_tid);
+
+ process->tid = ti_p->ti_tid;
+ process->lwpid = ti_p->ti_lid;
+
+ process->thread_known = 1;
+ err = td_thr_event_enable (th_p, 1);
+ if (err != TD_OK)
+ error ("Cannot enable thread event reporting for %d: %s",
+ ti_p->ti_lid, thread_db_err_str (err));
+}
+
+static int
+find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
+{
+ td_thrinfo_t ti;
+ td_err_e err;
+
+ err = td_thr_get_info (th_p, &ti);
+ if (err != TD_OK)
+ error ("Cannot get thread info: %s", thread_db_err_str (err));
+
+ /* Check for zombies. */
+ if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
+ return 0;
+
+ maybe_attach_thread (th_p, &ti);
+
+ return 0;
+}
+
+static void
+thread_db_find_new_threads (void)
+{
+ td_err_e err;
+
+ /* Iterate over all user-space threads to discover new threads. */
+ err = td_ta_thr_iter (thread_agent, find_new_threads_callback, NULL,
+ TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
+ TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
+ if (err != TD_OK)
+ error ("Cannot find new threads: %s", thread_db_err_str (err));
+}
+
+int
+thread_db_init ()
+{
+ int err;
+
+ proc_handle.pid = ((struct inferior_list_entry *)current_inferior)->id;
+
+ err = td_ta_new (&proc_handle, &thread_agent);
+ switch (err)
+ {
+ case TD_NOLIBTHREAD:
+ /* No thread library was detected. */
+ return 0;
+
+ case TD_OK:
+ /* The thread library was detected. */
+
+ if (thread_db_enable_reporting () == 0)
+ return 0;
+ thread_db_find_new_threads ();
+ return 1;
+
+ default:
+ warning ("error initializing thread_db library.");
+ }
+
+ return 0;
+}
diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
new file mode 100644
index 00000000000..e13eda80d46
--- /dev/null
+++ b/gdb/gdbserver/utils.c
@@ -0,0 +1,99 @@
+/* General utility routines for the remote server for GDB.
+ Copyright 1986, 1989, 1993, 1995, 1996, 1997, 1999, 2000, 2002
+ 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 "server.h"
+#include <stdio.h>
+#include <string.h>
+
+/* Generally useful subroutines used throughout the program. */
+
+/* Print the system error message for errno, and also mention STRING
+ as the file name for which the error was encountered.
+ Then return to command level. */
+
+void
+perror_with_name (char *string)
+{
+#ifndef STDC_HEADERS
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+ extern int errno;
+#endif
+ const char *err;
+ char *combined;
+
+ if (errno < sys_nerr)
+ err = sys_errlist[errno];
+ else
+ err = "unknown error";
+
+ combined = (char *) alloca (strlen (err) + strlen (string) + 3);
+ strcpy (combined, string);
+ strcat (combined, ": ");
+ strcat (combined, err);
+
+ error ("%s.", combined);
+}
+
+/* Print an error message and return to command level.
+ STRING is the error message, used as a fprintf string,
+ and ARG is passed as an argument to it. */
+
+void
+error (const char *string,...)
+{
+ extern jmp_buf toplevel;
+ va_list args;
+ va_start (args, string);
+ fflush (stdout);
+ vfprintf (stderr, string, args);
+ fprintf (stderr, "\n");
+ longjmp (toplevel, 1);
+}
+
+/* Print an error message and exit reporting failure.
+ This is for a error that we cannot continue from.
+ STRING and ARG are passed to fprintf. */
+
+/* VARARGS */
+void
+fatal (const char *string,...)
+{
+ va_list args;
+ va_start (args, string);
+ fprintf (stderr, "gdb: ");
+ vfprintf (stderr, string, args);
+ fprintf (stderr, "\n");
+ va_end (args);
+ exit (1);
+}
+
+/* VARARGS */
+void
+warning (const char *string,...)
+{
+ va_list args;
+ va_start (args, string);
+ fprintf (stderr, "gdb: ");
+ vfprintf (stderr, string, args);
+ fprintf (stderr, "\n");
+ va_end (args);
+}
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
new file mode 100644
index 00000000000..da89b36eee1
--- /dev/null
+++ b/gdb/gdbthread.h
@@ -0,0 +1,155 @@
+/* Multi-process/thread control defs for GDB, the GNU debugger.
+ Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1997, 1998, 1999,
+ 2000
+ Free Software Foundation, Inc.
+ Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
+
+
+ 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. */
+
+#ifndef GDBTHREAD_H
+#define GDBTHREAD_H
+
+/* For bpstat */
+#include "breakpoint.h"
+
+struct thread_info
+{
+ struct thread_info *next;
+ ptid_t ptid; /* "Actual process id";
+ In fact, this may be overloaded with
+ kernel thread id, etc. */
+ int num; /* Convenient handle (GDB thread id) */
+ /* State from wait_for_inferior */
+ CORE_ADDR prev_pc;
+ CORE_ADDR prev_func_start;
+ char *prev_func_name;
+ struct breakpoint *step_resume_breakpoint;
+ struct breakpoint *through_sigtramp_breakpoint;
+ CORE_ADDR step_range_start;
+ CORE_ADDR step_range_end;
+ CORE_ADDR step_frame_address;
+ CORE_ADDR step_sp;
+ int current_line;
+ struct symtab *current_symtab;
+ int trap_expected;
+ int handling_longjmp;
+ int another_trap;
+
+ /* This is set TRUE when a catchpoint of a shared library event
+ triggers. Since we don't wish to leave the inferior in the
+ solib hook when we report the event, we step the inferior
+ back to user code before stopping and reporting the event. */
+ int stepping_through_solib_after_catch;
+
+ /* When stepping_through_solib_after_catch is TRUE, this is a
+ list of the catchpoints that should be reported as triggering
+ when we finally do stop stepping. */
+ bpstat stepping_through_solib_catchpoints;
+
+ /* This is set to TRUE when this thread is in a signal handler
+ trampoline and we're single-stepping through it. */
+ int stepping_through_sigtramp;
+
+ /* Private data used by the target vector implementation. */
+ struct private_thread_info *private;
+};
+
+/* Create an empty thread list, or empty the existing one. */
+extern void init_thread_list (void);
+
+/* Add a thread to the thread list.
+ Note that add_thread now returns the handle of the new thread,
+ so that the caller may initialize the private thread data. */
+extern struct thread_info *add_thread (ptid_t ptid);
+
+/* Delete an existing thread list entry. */
+extern void delete_thread (ptid_t);
+
+/* Delete a step_resume_breakpoint from the thread database. */
+extern void delete_step_resume_breakpoint (void *);
+
+/* Translate the integer thread id (GDB's homegrown id, not the system's)
+ into a "pid" (which may be overloaded with extra thread information). */
+extern ptid_t thread_id_to_pid (int);
+
+/* Translate a 'pid' (which may be overloaded with extra thread information)
+ into the integer thread id (GDB's homegrown id, not the system's). */
+extern int pid_to_thread_id (ptid_t ptid);
+
+/* Boolean test for an already-known pid (which may be overloaded with
+ extra thread information). */
+extern int in_thread_list (ptid_t ptid);
+
+/* Boolean test for an already-known thread id (GDB's homegrown id,
+ not the system's). */
+extern int valid_thread_id (int thread);
+
+/* Search function to lookup a thread by 'pid'. */
+extern struct thread_info *find_thread_pid (ptid_t ptid);
+
+/* Iterator function to call a user-provided callback function
+ once for each known thread. */
+typedef int (*thread_callback_func) (struct thread_info *, void *);
+extern struct thread_info *iterate_over_threads (thread_callback_func, void *);
+
+/* infrun context switch: save the debugger state for the given thread. */
+extern void save_infrun_state (ptid_t ptid,
+ CORE_ADDR prev_pc,
+ CORE_ADDR prev_func_start,
+ char *prev_func_name,
+ int trap_expected,
+ struct breakpoint *step_resume_breakpoint,
+ struct breakpoint *through_sigtramp_breakpoint,
+ CORE_ADDR step_range_start,
+ CORE_ADDR step_range_end,
+ CORE_ADDR step_frame_address,
+ int handling_longjmp,
+ int another_trap,
+ int stepping_through_solib_after_catch,
+ bpstat stepping_through_solib_catchpoints,
+ int stepping_through_sigtramp,
+ int current_line,
+ struct symtab *current_symtab,
+ CORE_ADDR step_sp);
+
+/* infrun context switch: load the debugger state previously saved
+ for the given thread. */
+extern void load_infrun_state (ptid_t ptid,
+ CORE_ADDR *prev_pc,
+ CORE_ADDR *prev_func_start,
+ char **prev_func_name,
+ int *trap_expected,
+ struct breakpoint **step_resume_breakpoint,
+ struct breakpoint **through_sigtramp_breakpoint,
+ CORE_ADDR *step_range_start,
+ CORE_ADDR *step_range_end,
+ CORE_ADDR *step_frame_address,
+ int *handling_longjmp,
+ int *another_trap,
+ int *stepping_through_solib_affter_catch,
+ bpstat *stepping_through_solib_catchpoints,
+ int *stepping_through_sigtramp,
+ int *current_line,
+ struct symtab **current_symtab,
+ CORE_ADDR *step_sp);
+
+/* Commands with a prefix of `thread'. */
+extern struct cmd_list_element *thread_cmd_list;
+
+#endif /* GDBTHREAD_H */
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
new file mode 100644
index 00000000000..0f757f5a122
--- /dev/null
+++ b/gdb/gdbtypes.c
@@ -0,0 +1,3518 @@
+/* Support routines for manipulating internal types for GDB.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support, using pieces from other GDB modules.
+
+ 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 "defs.h"
+#include "gdb_string.h"
+#include "bfd.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "language.h"
+#include "target.h"
+#include "value.h"
+#include "demangle.h"
+#include "complaints.h"
+#include "gdbcmd.h"
+#include "wrapper.h"
+#include "cp-abi.h"
+#include "gdb_assert.h"
+
+/* These variables point to the objects
+ representing the predefined C data types. */
+
+struct type *builtin_type_void;
+struct type *builtin_type_char;
+struct type *builtin_type_true_char;
+struct type *builtin_type_short;
+struct type *builtin_type_int;
+struct type *builtin_type_long;
+struct type *builtin_type_long_long;
+struct type *builtin_type_signed_char;
+struct type *builtin_type_unsigned_char;
+struct type *builtin_type_unsigned_short;
+struct type *builtin_type_unsigned_int;
+struct type *builtin_type_unsigned_long;
+struct type *builtin_type_unsigned_long_long;
+struct type *builtin_type_float;
+struct type *builtin_type_double;
+struct type *builtin_type_long_double;
+struct type *builtin_type_complex;
+struct type *builtin_type_double_complex;
+struct type *builtin_type_string;
+struct type *builtin_type_int8;
+struct type *builtin_type_uint8;
+struct type *builtin_type_int16;
+struct type *builtin_type_uint16;
+struct type *builtin_type_int32;
+struct type *builtin_type_uint32;
+struct type *builtin_type_int64;
+struct type *builtin_type_uint64;
+struct type *builtin_type_int128;
+struct type *builtin_type_uint128;
+struct type *builtin_type_bool;
+
+/* 128 bit long vector types */
+struct type *builtin_type_v2_double;
+struct type *builtin_type_v4_float;
+struct type *builtin_type_v2_int64;
+struct type *builtin_type_v4_int32;
+struct type *builtin_type_v8_int16;
+struct type *builtin_type_v16_int8;
+/* 64 bit long vector types */
+struct type *builtin_type_v2_float;
+struct type *builtin_type_v2_int32;
+struct type *builtin_type_v4_int16;
+struct type *builtin_type_v8_int8;
+
+struct type *builtin_type_v4sf;
+struct type *builtin_type_v4si;
+struct type *builtin_type_v16qi;
+struct type *builtin_type_v8qi;
+struct type *builtin_type_v8hi;
+struct type *builtin_type_v4hi;
+struct type *builtin_type_v2si;
+struct type *builtin_type_vec128;
+struct type *builtin_type_vec128i;
+struct type *builtin_type_ieee_single_big;
+struct type *builtin_type_ieee_single_little;
+struct type *builtin_type_ieee_double_big;
+struct type *builtin_type_ieee_double_little;
+struct type *builtin_type_ieee_double_littlebyte_bigword;
+struct type *builtin_type_i387_ext;
+struct type *builtin_type_m68881_ext;
+struct type *builtin_type_i960_ext;
+struct type *builtin_type_m88110_ext;
+struct type *builtin_type_m88110_harris_ext;
+struct type *builtin_type_arm_ext_big;
+struct type *builtin_type_arm_ext_littlebyte_bigword;
+struct type *builtin_type_ia64_spill_big;
+struct type *builtin_type_ia64_spill_little;
+struct type *builtin_type_ia64_quad_big;
+struct type *builtin_type_ia64_quad_little;
+struct type *builtin_type_void_data_ptr;
+struct type *builtin_type_void_func_ptr;
+struct type *builtin_type_CORE_ADDR;
+struct type *builtin_type_bfd_vma;
+
+int opaque_type_resolution = 1;
+int overload_debug = 0;
+
+struct extra
+ {
+ char str[128];
+ int len;
+ }; /* maximum extension is 128! FIXME */
+
+static void add_name (struct extra *, char *);
+static void add_mangled_type (struct extra *, struct type *);
+#if 0
+static void cfront_mangle_name (struct type *, int, int);
+#endif
+static void print_bit_vector (B_TYPE *, int);
+static void print_arg_types (struct type **, int);
+static void dump_fn_fieldlists (struct type *, int);
+static void print_cplus_stuff (struct type *, int);
+static void virtual_base_list_aux (struct type *dclass);
+
+
+/* Alloc a new type structure and fill it with some defaults. If
+ OBJFILE is non-NULL, then allocate the space for the type structure
+ in that objfile's type_obstack. Otherwise allocate the new type structure
+ by xmalloc () (for permanent types). */
+
+struct type *
+alloc_type (struct objfile *objfile)
+{
+ register struct type *type;
+
+ /* Alloc the structure and start off with all fields zeroed. */
+
+ if (objfile == NULL)
+ {
+ type = xmalloc (sizeof (struct type));
+ memset (type, 0, sizeof (struct type));
+ TYPE_MAIN_TYPE (type) = xmalloc (sizeof (struct main_type));
+ }
+ else
+ {
+ type = obstack_alloc (&objfile->type_obstack,
+ sizeof (struct type));
+ memset (type, 0, sizeof (struct type));
+ TYPE_MAIN_TYPE (type) = obstack_alloc (&objfile->type_obstack,
+ sizeof (struct main_type));
+ OBJSTAT (objfile, n_types++);
+ }
+ memset (TYPE_MAIN_TYPE (type), 0, sizeof (struct main_type));
+
+ /* Initialize the fields that might not be zero. */
+
+ TYPE_CODE (type) = TYPE_CODE_UNDEF;
+ TYPE_OBJFILE (type) = objfile;
+ TYPE_VPTR_FIELDNO (type) = -1;
+ TYPE_CHAIN (type) = type; /* Chain back to itself. */
+
+ return (type);
+}
+
+/* Alloc a new type instance structure, fill it with some defaults,
+ and point it at OLDTYPE. Allocate the new type instance from the
+ same place as OLDTYPE. */
+
+static struct type *
+alloc_type_instance (struct type *oldtype)
+{
+ struct type *type;
+
+ /* Allocate the structure. */
+
+ if (TYPE_OBJFILE (oldtype) == NULL)
+ {
+ type = xmalloc (sizeof (struct type));
+ memset (type, 0, sizeof (struct type));
+ }
+ else
+ {
+ type = obstack_alloc (&TYPE_OBJFILE (oldtype)->type_obstack,
+ sizeof (struct type));
+ memset (type, 0, sizeof (struct type));
+ }
+ TYPE_MAIN_TYPE (type) = TYPE_MAIN_TYPE (oldtype);
+
+ TYPE_CHAIN (type) = type; /* Chain back to itself for now. */
+
+ return (type);
+}
+
+/* Clear all remnants of the previous type at TYPE, in preparation for
+ replacing it with something else. */
+static void
+smash_type (struct type *type)
+{
+ memset (TYPE_MAIN_TYPE (type), 0, sizeof (struct main_type));
+
+ /* For now, delete the rings. */
+ TYPE_CHAIN (type) = type;
+
+ /* For now, leave the pointer/reference types alone. */
+}
+
+/* Lookup a pointer to a type TYPE. TYPEPTR, if nonzero, points
+ to a pointer to memory where the pointer type should be stored.
+ If *TYPEPTR is zero, update it to point to the pointer type we return.
+ We allocate new memory if needed. */
+
+struct type *
+make_pointer_type (struct type *type, struct type **typeptr)
+{
+ register struct type *ntype; /* New type */
+ struct objfile *objfile;
+
+ ntype = TYPE_POINTER_TYPE (type);
+
+ if (ntype)
+ {
+ if (typeptr == 0)
+ return ntype; /* Don't care about alloc, and have new type. */
+ else if (*typeptr == 0)
+ {
+ *typeptr = ntype; /* Tracking alloc, and we have new type. */
+ return ntype;
+ }
+ }
+
+ if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */
+ {
+ ntype = alloc_type (TYPE_OBJFILE (type));
+ if (typeptr)
+ *typeptr = ntype;
+ }
+ else
+ /* We have storage, but need to reset it. */
+ {
+ ntype = *typeptr;
+ objfile = TYPE_OBJFILE (ntype);
+ smash_type (ntype);
+ TYPE_OBJFILE (ntype) = objfile;
+ }
+
+ TYPE_TARGET_TYPE (ntype) = type;
+ TYPE_POINTER_TYPE (type) = ntype;
+
+ /* FIXME! Assume the machine has only one representation for pointers! */
+
+ TYPE_LENGTH (ntype) = TARGET_PTR_BIT / TARGET_CHAR_BIT;
+ TYPE_CODE (ntype) = TYPE_CODE_PTR;
+
+ /* Mark pointers as unsigned. The target converts between pointers
+ and addresses (CORE_ADDRs) using POINTER_TO_ADDRESS() and
+ ADDRESS_TO_POINTER(). */
+ TYPE_FLAGS (ntype) |= TYPE_FLAG_UNSIGNED;
+
+ if (!TYPE_POINTER_TYPE (type)) /* Remember it, if don't have one. */
+ TYPE_POINTER_TYPE (type) = ntype;
+
+ return ntype;
+}
+
+/* Given a type TYPE, return a type of pointers to that type.
+ May need to construct such a type if this is the first use. */
+
+struct type *
+lookup_pointer_type (struct type *type)
+{
+ return make_pointer_type (type, (struct type **) 0);
+}
+
+/* Lookup a C++ `reference' to a type TYPE. TYPEPTR, if nonzero, points
+ to a pointer to memory where the reference type should be stored.
+ If *TYPEPTR is zero, update it to point to the reference type we return.
+ We allocate new memory if needed. */
+
+struct type *
+make_reference_type (struct type *type, struct type **typeptr)
+{
+ register struct type *ntype; /* New type */
+ struct objfile *objfile;
+
+ ntype = TYPE_REFERENCE_TYPE (type);
+
+ if (ntype)
+ {
+ if (typeptr == 0)
+ return ntype; /* Don't care about alloc, and have new type. */
+ else if (*typeptr == 0)
+ {
+ *typeptr = ntype; /* Tracking alloc, and we have new type. */
+ return ntype;
+ }
+ }
+
+ if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */
+ {
+ ntype = alloc_type (TYPE_OBJFILE (type));
+ if (typeptr)
+ *typeptr = ntype;
+ }
+ else
+ /* We have storage, but need to reset it. */
+ {
+ ntype = *typeptr;
+ objfile = TYPE_OBJFILE (ntype);
+ smash_type (ntype);
+ TYPE_OBJFILE (ntype) = objfile;
+ }
+
+ TYPE_TARGET_TYPE (ntype) = type;
+ TYPE_REFERENCE_TYPE (type) = ntype;
+
+ /* FIXME! Assume the machine has only one representation for references,
+ and that it matches the (only) representation for pointers! */
+
+ TYPE_LENGTH (ntype) = TARGET_PTR_BIT / TARGET_CHAR_BIT;
+ TYPE_CODE (ntype) = TYPE_CODE_REF;
+
+ if (!TYPE_REFERENCE_TYPE (type)) /* Remember it, if don't have one. */
+ TYPE_REFERENCE_TYPE (type) = ntype;
+
+ return ntype;
+}
+
+/* Same as above, but caller doesn't care about memory allocation details. */
+
+struct type *
+lookup_reference_type (struct type *type)
+{
+ return make_reference_type (type, (struct type **) 0);
+}
+
+/* Lookup a function type that returns type TYPE. TYPEPTR, if nonzero, points
+ to a pointer to memory where the function type should be stored.
+ If *TYPEPTR is zero, update it to point to the function type we return.
+ We allocate new memory if needed. */
+
+struct type *
+make_function_type (struct type *type, struct type **typeptr)
+{
+ register struct type *ntype; /* New type */
+ struct objfile *objfile;
+
+ if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */
+ {
+ ntype = alloc_type (TYPE_OBJFILE (type));
+ if (typeptr)
+ *typeptr = ntype;
+ }
+ else
+ /* We have storage, but need to reset it. */
+ {
+ ntype = *typeptr;
+ objfile = TYPE_OBJFILE (ntype);
+ smash_type (ntype);
+ TYPE_OBJFILE (ntype) = objfile;
+ }
+
+ TYPE_TARGET_TYPE (ntype) = type;
+
+ TYPE_LENGTH (ntype) = 1;
+ TYPE_CODE (ntype) = TYPE_CODE_FUNC;
+
+ return ntype;
+}
+
+
+/* Given a type TYPE, return a type of functions that return that type.
+ May need to construct such a type if this is the first use. */
+
+struct type *
+lookup_function_type (struct type *type)
+{
+ return make_function_type (type, (struct type **) 0);
+}
+
+/* Identify address space identifier by name --
+ return the integer flag defined in gdbtypes.h. */
+extern int
+address_space_name_to_int (char *space_identifier)
+{
+ /* Check for known address space delimiters. */
+ if (!strcmp (space_identifier, "code"))
+ return TYPE_FLAG_CODE_SPACE;
+ else if (!strcmp (space_identifier, "data"))
+ return TYPE_FLAG_DATA_SPACE;
+ else
+ error ("Unknown address space specifier: \"%s\"", space_identifier);
+}
+
+/* Identify address space identifier by integer flag as defined in
+ gdbtypes.h -- return the string version of the adress space name. */
+
+extern char *
+address_space_int_to_name (int space_flag)
+{
+ if (space_flag & TYPE_FLAG_CODE_SPACE)
+ return "code";
+ else if (space_flag & TYPE_FLAG_DATA_SPACE)
+ return "data";
+ else
+ return NULL;
+}
+
+/* Create a new type with instance flags NEW_FLAGS, based on TYPE.
+ If STORAGE is non-NULL, create the new type instance there. */
+
+struct type *
+make_qualified_type (struct type *type, int new_flags,
+ struct type *storage)
+{
+ struct type *ntype;
+
+ ntype = type;
+ do {
+ if (TYPE_INSTANCE_FLAGS (ntype) == new_flags)
+ return ntype;
+ ntype = TYPE_CHAIN (ntype);
+ } while (ntype != type);
+
+ /* Create a new type instance. */
+ if (storage == NULL)
+ ntype = alloc_type_instance (type);
+ else
+ {
+ ntype = storage;
+ TYPE_MAIN_TYPE (ntype) = TYPE_MAIN_TYPE (type);
+ TYPE_CHAIN (ntype) = ntype;
+ }
+
+ /* Pointers or references to the original type are not relevant to
+ the new type. */
+ TYPE_POINTER_TYPE (ntype) = (struct type *) 0;
+ TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0;
+
+ /* Chain the new qualified type to the old type. */
+ TYPE_CHAIN (ntype) = TYPE_CHAIN (type);
+ TYPE_CHAIN (type) = ntype;
+
+ /* Now set the instance flags and return the new type. */
+ TYPE_INSTANCE_FLAGS (ntype) = new_flags;
+
+ return ntype;
+}
+
+/* Make an address-space-delimited variant of a type -- a type that
+ is identical to the one supplied except that it has an address
+ space attribute attached to it (such as "code" or "data").
+
+ This is for Harvard architectures. */
+
+struct type *
+make_type_with_address_space (struct type *type, int space_flag)
+{
+ struct type *ntype;
+ int new_flags = ((TYPE_INSTANCE_FLAGS (type)
+ & ~(TYPE_FLAG_CODE_SPACE | TYPE_FLAG_DATA_SPACE))
+ | space_flag);
+
+ return make_qualified_type (type, new_flags, NULL);
+}
+
+/* Make a "c-v" variant of a type -- a type that is identical to the
+ one supplied except that it may have const or volatile attributes
+ CNST is a flag for setting the const attribute
+ VOLTL is a flag for setting the volatile attribute
+ TYPE is the base type whose variant we are creating.
+ TYPEPTR, if nonzero, points
+ to a pointer to memory where the reference type should be stored.
+ If *TYPEPTR is zero, update it to point to the reference type we return.
+ We allocate new memory if needed. */
+
+struct type *
+make_cv_type (int cnst, int voltl, struct type *type, struct type **typeptr)
+{
+ register struct type *ntype; /* New type */
+ register struct type *tmp_type = type; /* tmp type */
+ struct objfile *objfile;
+
+ int new_flags = (TYPE_INSTANCE_FLAGS (type)
+ & ~(TYPE_FLAG_CONST | TYPE_FLAG_VOLATILE));
+
+ if (cnst)
+ new_flags |= TYPE_FLAG_CONST;
+
+ if (voltl)
+ new_flags |= TYPE_FLAG_VOLATILE;
+
+ if (typeptr && *typeptr != NULL)
+ {
+ /* Objfile is per-core-type. This const-qualified type had best
+ belong to the same objfile as the type it is qualifying, unless
+ we are overwriting a stub type, in which case the safest thing
+ to do is to copy the core type into the new objfile. */
+
+ gdb_assert (TYPE_OBJFILE (*typeptr) == TYPE_OBJFILE (type)
+ || TYPE_STUB (*typeptr));
+ if (TYPE_OBJFILE (*typeptr) != TYPE_OBJFILE (type))
+ {
+ TYPE_MAIN_TYPE (*typeptr)
+ = TYPE_ALLOC (*typeptr, sizeof (struct main_type));
+ *TYPE_MAIN_TYPE (*typeptr)
+ = *TYPE_MAIN_TYPE (type);
+ }
+ }
+
+ ntype = make_qualified_type (type, new_flags, typeptr ? *typeptr : NULL);
+
+ if (typeptr != NULL)
+ *typeptr = ntype;
+
+ return ntype;
+}
+
+/* Replace the contents of ntype with the type *type. This changes the
+ contents, rather than the pointer for TYPE_MAIN_TYPE (ntype); thus
+ the changes are propogated to all types in the TYPE_CHAIN.
+
+ In order to build recursive types, it's inevitable that we'll need
+ to update types in place --- but this sort of indiscriminate
+ smashing is ugly, and needs to be replaced with something more
+ controlled. TYPE_MAIN_TYPE is a step in this direction; it's not
+ clear if more steps are needed. */
+void
+replace_type (struct type *ntype, struct type *type)
+{
+ struct type *cv_chain, *as_chain, *ptr, *ref;
+
+ *TYPE_MAIN_TYPE (ntype) = *TYPE_MAIN_TYPE (type);
+
+ /* Assert that the two types have equivalent instance qualifiers.
+ This should be true for at least all of our debug readers. */
+ gdb_assert (TYPE_INSTANCE_FLAGS (ntype) == TYPE_INSTANCE_FLAGS (type));
+}
+
+/* Implement direct support for MEMBER_TYPE in GNU C++.
+ May need to construct such a type if this is the first use.
+ The TYPE is the type of the member. The DOMAIN is the type
+ of the aggregate that the member belongs to. */
+
+struct type *
+lookup_member_type (struct type *type, struct type *domain)
+{
+ register struct type *mtype;
+
+ mtype = alloc_type (TYPE_OBJFILE (type));
+ smash_to_member_type (mtype, domain, type);
+ return (mtype);
+}
+
+/* Allocate a stub method whose return type is TYPE.
+ This apparently happens for speed of symbol reading, since parsing
+ out the arguments to the method is cpu-intensive, the way we are doing
+ it. So, we will fill in arguments later.
+ This always returns a fresh type. */
+
+struct type *
+allocate_stub_method (struct type *type)
+{
+ struct type *mtype;
+
+ mtype = init_type (TYPE_CODE_METHOD, 1, TYPE_FLAG_STUB, NULL,
+ TYPE_OBJFILE (type));
+ TYPE_TARGET_TYPE (mtype) = type;
+ /* _DOMAIN_TYPE (mtype) = unknown yet */
+ /* _ARG_TYPES (mtype) = unknown yet */
+ return (mtype);
+}
+
+/* Create a range type using either a blank type supplied in RESULT_TYPE,
+ or creating a new type, inheriting the objfile from INDEX_TYPE.
+
+ Indices will be of type INDEX_TYPE, and will range from LOW_BOUND to
+ HIGH_BOUND, inclusive.
+
+ FIXME: Maybe we should check the TYPE_CODE of RESULT_TYPE to make
+ sure it is TYPE_CODE_UNDEF before we bash it into a range type? */
+
+struct type *
+create_range_type (struct type *result_type, struct type *index_type,
+ int low_bound, int high_bound)
+{
+ if (result_type == NULL)
+ {
+ result_type = alloc_type (TYPE_OBJFILE (index_type));
+ }
+ TYPE_CODE (result_type) = TYPE_CODE_RANGE;
+ TYPE_TARGET_TYPE (result_type) = index_type;
+ if (TYPE_STUB (index_type))
+ TYPE_FLAGS (result_type) |= TYPE_FLAG_TARGET_STUB;
+ else
+ TYPE_LENGTH (result_type) = TYPE_LENGTH (check_typedef (index_type));
+ TYPE_NFIELDS (result_type) = 2;
+ TYPE_FIELDS (result_type) = (struct field *)
+ TYPE_ALLOC (result_type, 2 * sizeof (struct field));
+ memset (TYPE_FIELDS (result_type), 0, 2 * sizeof (struct field));
+ TYPE_FIELD_BITPOS (result_type, 0) = low_bound;
+ TYPE_FIELD_BITPOS (result_type, 1) = high_bound;
+ TYPE_FIELD_TYPE (result_type, 0) = builtin_type_int; /* FIXME */
+ TYPE_FIELD_TYPE (result_type, 1) = builtin_type_int; /* FIXME */
+
+ if (low_bound >= 0)
+ TYPE_FLAGS (result_type) |= TYPE_FLAG_UNSIGNED;
+
+ return (result_type);
+}
+
+/* Set *LOWP and *HIGHP to the lower and upper bounds of discrete type TYPE.
+ Return 1 of type is a range type, 0 if it is discrete (and bounds
+ will fit in LONGEST), or -1 otherwise. */
+
+int
+get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
+{
+ CHECK_TYPEDEF (type);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_RANGE:
+ *lowp = TYPE_LOW_BOUND (type);
+ *highp = TYPE_HIGH_BOUND (type);
+ return 1;
+ case TYPE_CODE_ENUM:
+ if (TYPE_NFIELDS (type) > 0)
+ {
+ /* The enums may not be sorted by value, so search all
+ entries */
+ int i;
+
+ *lowp = *highp = TYPE_FIELD_BITPOS (type, 0);
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
+ {
+ if (TYPE_FIELD_BITPOS (type, i) < *lowp)
+ *lowp = TYPE_FIELD_BITPOS (type, i);
+ if (TYPE_FIELD_BITPOS (type, i) > *highp)
+ *highp = TYPE_FIELD_BITPOS (type, i);
+ }
+
+ /* Set unsigned indicator if warranted. */
+ if (*lowp >= 0)
+ {
+ TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+ }
+ }
+ else
+ {
+ *lowp = 0;
+ *highp = -1;
+ }
+ return 0;
+ case TYPE_CODE_BOOL:
+ *lowp = 0;
+ *highp = 1;
+ return 0;
+ case TYPE_CODE_INT:
+ if (TYPE_LENGTH (type) > sizeof (LONGEST)) /* Too big */
+ return -1;
+ if (!TYPE_UNSIGNED (type))
+ {
+ *lowp = -(1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1));
+ *highp = -*lowp - 1;
+ return 0;
+ }
+ /* ... fall through for unsigned ints ... */
+ case TYPE_CODE_CHAR:
+ *lowp = 0;
+ /* This round-about calculation is to avoid shifting by
+ TYPE_LENGTH (type) * TARGET_CHAR_BIT, which will not work
+ if TYPE_LENGTH (type) == sizeof (LONGEST). */
+ *highp = 1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1);
+ *highp = (*highp - 1) | *highp;
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+/* Create an array type using either a blank type supplied in RESULT_TYPE,
+ or creating a new type, inheriting the objfile from RANGE_TYPE.
+
+ Elements will be of type ELEMENT_TYPE, the indices will be of type
+ RANGE_TYPE.
+
+ FIXME: Maybe we should check the TYPE_CODE of RESULT_TYPE to make
+ sure it is TYPE_CODE_UNDEF before we bash it into an array type? */
+
+struct type *
+create_array_type (struct type *result_type, struct type *element_type,
+ struct type *range_type)
+{
+ LONGEST low_bound, high_bound;
+
+ if (result_type == NULL)
+ {
+ result_type = alloc_type (TYPE_OBJFILE (range_type));
+ }
+ TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
+ TYPE_TARGET_TYPE (result_type) = element_type;
+ if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+ low_bound = high_bound = 0;
+ CHECK_TYPEDEF (element_type);
+ TYPE_LENGTH (result_type) =
+ TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
+ TYPE_NFIELDS (result_type) = 1;
+ TYPE_FIELDS (result_type) =
+ (struct field *) TYPE_ALLOC (result_type, sizeof (struct field));
+ memset (TYPE_FIELDS (result_type), 0, sizeof (struct field));
+ TYPE_FIELD_TYPE (result_type, 0) = range_type;
+ TYPE_VPTR_FIELDNO (result_type) = -1;
+
+ /* TYPE_FLAG_TARGET_STUB will take care of zero length arrays */
+ if (TYPE_LENGTH (result_type) == 0)
+ TYPE_FLAGS (result_type) |= TYPE_FLAG_TARGET_STUB;
+
+ return (result_type);
+}
+
+/* Create a string type using either a blank type supplied in RESULT_TYPE,
+ or creating a new type. String types are similar enough to array of
+ char types that we can use create_array_type to build the basic type
+ and then bash it into a string type.
+
+ For fixed length strings, the range type contains 0 as the lower
+ bound and the length of the string minus one as the upper bound.
+
+ FIXME: Maybe we should check the TYPE_CODE of RESULT_TYPE to make
+ sure it is TYPE_CODE_UNDEF before we bash it into a string type? */
+
+struct type *
+create_string_type (struct type *result_type, struct type *range_type)
+{
+ result_type = create_array_type (result_type,
+ *current_language->string_char_type,
+ range_type);
+ TYPE_CODE (result_type) = TYPE_CODE_STRING;
+ return (result_type);
+}
+
+struct type *
+create_set_type (struct type *result_type, struct type *domain_type)
+{
+ LONGEST low_bound, high_bound, bit_length;
+ if (result_type == NULL)
+ {
+ result_type = alloc_type (TYPE_OBJFILE (domain_type));
+ }
+ TYPE_CODE (result_type) = TYPE_CODE_SET;
+ TYPE_NFIELDS (result_type) = 1;
+ TYPE_FIELDS (result_type) = (struct field *)
+ TYPE_ALLOC (result_type, 1 * sizeof (struct field));
+ memset (TYPE_FIELDS (result_type), 0, sizeof (struct field));
+
+ if (!TYPE_STUB (domain_type))
+ {
+ if (get_discrete_bounds (domain_type, &low_bound, &high_bound) < 0)
+ low_bound = high_bound = 0;
+ bit_length = high_bound - low_bound + 1;
+ TYPE_LENGTH (result_type)
+ = (bit_length + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT;
+ }
+ TYPE_FIELD_TYPE (result_type, 0) = domain_type;
+
+ if (low_bound >= 0)
+ TYPE_FLAGS (result_type) |= TYPE_FLAG_UNSIGNED;
+
+ return (result_type);
+}
+
+/* Construct and return a type of the form:
+ struct NAME { ELT_TYPE ELT_NAME[N]; }
+ We use these types for SIMD registers. For example, the type of
+ the SSE registers on the late x86-family processors is:
+ struct __builtin_v4sf { float f[4]; }
+ built by the function call:
+ init_simd_type ("__builtin_v4sf", builtin_type_float, "f", 4)
+ The type returned is a permanent type, allocated using malloc; it
+ doesn't live in any objfile's obstack. */
+static struct type *
+init_simd_type (char *name,
+ struct type *elt_type,
+ char *elt_name,
+ int n)
+{
+ struct type *simd_type;
+ struct type *array_type;
+
+ simd_type = init_composite_type (name, TYPE_CODE_STRUCT);
+ array_type = create_array_type (0, elt_type,
+ create_range_type (0, builtin_type_int,
+ 0, n-1));
+ append_composite_type_field (simd_type, elt_name, array_type);
+ return simd_type;
+}
+
+static struct type *
+init_vector_type (struct type *elt_type, int n)
+{
+ struct type *array_type;
+
+ array_type = create_array_type (0, elt_type,
+ create_range_type (0, builtin_type_int,
+ 0, n-1));
+ TYPE_FLAGS (array_type) |= TYPE_FLAG_VECTOR;
+ return array_type;
+}
+
+static struct type *
+build_builtin_type_vec128 (void)
+{
+ /* Construct a type for the 128 bit registers. The type we're
+ building is this: */
+#if 0
+ union __gdb_builtin_type_vec128
+ {
+ int128_t uint128;
+ float v4_float[4];
+ int32_t v4_int32[4];
+ int16_t v8_int16[8];
+ int8_t v16_int8[16];
+ };
+#endif
+
+ struct type *t;
+
+ t = init_composite_type ("__gdb_builtin_type_vec128", TYPE_CODE_UNION);
+ append_composite_type_field (t, "uint128", builtin_type_int128);
+ append_composite_type_field (t, "v4_float", builtin_type_v4_float);
+ append_composite_type_field (t, "v4_int32", builtin_type_v4_int32);
+ append_composite_type_field (t, "v8_int16", builtin_type_v8_int16);
+ append_composite_type_field (t, "v16_int8", builtin_type_v16_int8);
+
+ return t;
+}
+
+static struct type *
+build_builtin_type_vec128i (void)
+{
+ /* 128-bit Intel SIMD registers */
+ struct type *t;
+
+ t = init_composite_type ("__gdb_builtin_type_vec128i", TYPE_CODE_UNION);
+ append_composite_type_field (t, "v4_float", builtin_type_v4_float);
+ append_composite_type_field (t, "v2_double", builtin_type_v2_double);
+ append_composite_type_field (t, "v16_int8", builtin_type_v16_int8);
+ append_composite_type_field (t, "v8_int16", builtin_type_v8_int16);
+ append_composite_type_field (t, "v4_int32", builtin_type_v4_int32);
+ append_composite_type_field (t, "v2_int64", builtin_type_v2_int64);
+ append_composite_type_field (t, "uint128", builtin_type_int128);
+
+ return t;
+}
+
+/* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE.
+ A MEMBER is a wierd thing -- it amounts to a typed offset into
+ a struct, e.g. "an int at offset 8". A MEMBER TYPE doesn't
+ include the offset (that's the value of the MEMBER itself), but does
+ include the structure type into which it points (for some reason).
+
+ When "smashing" the type, we preserve the objfile that the
+ old type pointed to, since we aren't changing where the type is actually
+ allocated. */
+
+void
+smash_to_member_type (struct type *type, struct type *domain,
+ struct type *to_type)
+{
+ struct objfile *objfile;
+
+ objfile = TYPE_OBJFILE (type);
+
+ smash_type (type);
+ TYPE_OBJFILE (type) = objfile;
+ TYPE_TARGET_TYPE (type) = to_type;
+ TYPE_DOMAIN_TYPE (type) = domain;
+ TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */
+ TYPE_CODE (type) = TYPE_CODE_MEMBER;
+}
+
+/* Smash TYPE to be a type of method of DOMAIN with type TO_TYPE.
+ METHOD just means `function that gets an extra "this" argument'.
+
+ When "smashing" the type, we preserve the objfile that the
+ old type pointed to, since we aren't changing where the type is actually
+ allocated. */
+
+void
+smash_to_method_type (struct type *type, struct type *domain,
+ struct type *to_type, struct type **args)
+{
+ struct objfile *objfile;
+
+ objfile = TYPE_OBJFILE (type);
+
+ smash_type (type);
+ TYPE_OBJFILE (type) = objfile;
+ TYPE_TARGET_TYPE (type) = to_type;
+ TYPE_DOMAIN_TYPE (type) = domain;
+ TYPE_ARG_TYPES (type) = args;
+ TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */
+ TYPE_CODE (type) = TYPE_CODE_METHOD;
+}
+
+/* Return a typename for a struct/union/enum type without "struct ",
+ "union ", or "enum ". If the type has a NULL name, return NULL. */
+
+char *
+type_name_no_tag (register const struct type *type)
+{
+ if (TYPE_TAG_NAME (type) != NULL)
+ return TYPE_TAG_NAME (type);
+
+ /* Is there code which expects this to return the name if there is no
+ tag name? My guess is that this is mainly used for C++ in cases where
+ the two will always be the same. */
+ return TYPE_NAME (type);
+}
+
+/* Lookup a primitive type named NAME.
+ Return zero if NAME is not a primitive type. */
+
+struct type *
+lookup_primitive_typename (char *name)
+{
+ struct type **const *p;
+
+ for (p = current_language->la_builtin_type_vector; *p != NULL; p++)
+ {
+ if (STREQ (TYPE_NAME (**p), name))
+ {
+ return (**p);
+ }
+ }
+ return (NULL);
+}
+
+/* Lookup a typedef or primitive type named NAME,
+ visible in lexical block BLOCK.
+ If NOERR is nonzero, return zero if NAME is not suitably defined. */
+
+struct type *
+lookup_typename (char *name, struct block *block, int noerr)
+{
+ register struct symbol *sym;
+ register struct type *tmp;
+
+ sym = lookup_symbol (name, block, VAR_NAMESPACE, 0, (struct symtab **) NULL);
+ if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF)
+ {
+ tmp = lookup_primitive_typename (name);
+ if (tmp)
+ {
+ return (tmp);
+ }
+ else if (!tmp && noerr)
+ {
+ return (NULL);
+ }
+ else
+ {
+ error ("No type named %s.", name);
+ }
+ }
+ return (SYMBOL_TYPE (sym));
+}
+
+struct type *
+lookup_unsigned_typename (char *name)
+{
+ char *uns = alloca (strlen (name) + 10);
+
+ strcpy (uns, "unsigned ");
+ strcpy (uns + 9, name);
+ return (lookup_typename (uns, (struct block *) NULL, 0));
+}
+
+struct type *
+lookup_signed_typename (char *name)
+{
+ struct type *t;
+ char *uns = alloca (strlen (name) + 8);
+
+ strcpy (uns, "signed ");
+ strcpy (uns + 7, name);
+ t = lookup_typename (uns, (struct block *) NULL, 1);
+ /* If we don't find "signed FOO" just try again with plain "FOO". */
+ if (t != NULL)
+ return t;
+ return lookup_typename (name, (struct block *) NULL, 0);
+}
+
+/* Lookup a structure type named "struct NAME",
+ visible in lexical block BLOCK. */
+
+struct type *
+lookup_struct (char *name, struct block *block)
+{
+ register struct symbol *sym;
+
+ sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0,
+ (struct symtab **) NULL);
+
+ if (sym == NULL)
+ {
+ error ("No struct type named %s.", name);
+ }
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT)
+ {
+ error ("This context has class, union or enum %s, not a struct.", name);
+ }
+ return (SYMBOL_TYPE (sym));
+}
+
+/* Lookup a union type named "union NAME",
+ visible in lexical block BLOCK. */
+
+struct type *
+lookup_union (char *name, struct block *block)
+{
+ register struct symbol *sym;
+ struct type *t;
+
+ sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0,
+ (struct symtab **) NULL);
+
+ if (sym == NULL)
+ error ("No union type named %s.", name);
+
+ t = SYMBOL_TYPE (sym);
+
+ if (TYPE_CODE (t) == TYPE_CODE_UNION)
+ return (t);
+
+ /* C++ unions may come out with TYPE_CODE_CLASS, but we look at
+ * a further "declared_type" field to discover it is really a union.
+ */
+ if (HAVE_CPLUS_STRUCT (t))
+ if (TYPE_DECLARED_TYPE (t) == DECLARED_TYPE_UNION)
+ return (t);
+
+ /* If we get here, it's not a union */
+ error ("This context has class, struct or enum %s, not a union.", name);
+}
+
+
+/* Lookup an enum type named "enum NAME",
+ visible in lexical block BLOCK. */
+
+struct type *
+lookup_enum (char *name, struct block *block)
+{
+ register struct symbol *sym;
+
+ sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0,
+ (struct symtab **) NULL);
+ if (sym == NULL)
+ {
+ error ("No enum type named %s.", name);
+ }
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_ENUM)
+ {
+ error ("This context has class, struct or union %s, not an enum.", name);
+ }
+ return (SYMBOL_TYPE (sym));
+}
+
+/* Lookup a template type named "template NAME<TYPE>",
+ visible in lexical block BLOCK. */
+
+struct type *
+lookup_template_type (char *name, struct type *type, struct block *block)
+{
+ struct symbol *sym;
+ char *nam = (char *) alloca (strlen (name) + strlen (TYPE_NAME (type)) + 4);
+ strcpy (nam, name);
+ strcat (nam, "<");
+ strcat (nam, TYPE_NAME (type));
+ strcat (nam, " >"); /* FIXME, extra space still introduced in gcc? */
+
+ sym = lookup_symbol (nam, block, VAR_NAMESPACE, 0, (struct symtab **) NULL);
+
+ if (sym == NULL)
+ {
+ error ("No template type named %s.", name);
+ }
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT)
+ {
+ error ("This context has class, union or enum %s, not a struct.", name);
+ }
+ return (SYMBOL_TYPE (sym));
+}
+
+/* Given a type TYPE, lookup the type of the component of type named NAME.
+
+ TYPE can be either a struct or union, or a pointer or reference to a struct or
+ union. If it is a pointer or reference, its target type is automatically used.
+ Thus '.' and '->' are interchangable, as specified for the definitions of the
+ expression element types STRUCTOP_STRUCT and STRUCTOP_PTR.
+
+ If NOERR is nonzero, return zero if NAME is not suitably defined.
+ If NAME is the name of a baseclass type, return that type. */
+
+struct type *
+lookup_struct_elt_type (struct type *type, char *name, int noerr)
+{
+ int i;
+
+ for (;;)
+ {
+ CHECK_TYPEDEF (type);
+ if (TYPE_CODE (type) != TYPE_CODE_PTR
+ && TYPE_CODE (type) != TYPE_CODE_REF)
+ break;
+ type = TYPE_TARGET_TYPE (type);
+ }
+
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT &&
+ TYPE_CODE (type) != TYPE_CODE_UNION)
+ {
+ target_terminal_ours ();
+ gdb_flush (gdb_stdout);
+ fprintf_unfiltered (gdb_stderr, "Type ");
+ type_print (type, "", gdb_stderr, -1);
+ error (" is not a structure or union type.");
+ }
+
+#if 0
+ /* FIXME: This change put in by Michael seems incorrect for the case where
+ the structure tag name is the same as the member name. I.E. when doing
+ "ptype bell->bar" for "struct foo { int bar; int foo; } bell;"
+ Disabled by fnf. */
+ {
+ char *typename;
+
+ typename = type_name_no_tag (type);
+ if (typename != NULL && STREQ (typename, name))
+ return type;
+ }
+#endif
+
+ for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
+ {
+ char *t_field_name = TYPE_FIELD_NAME (type, i);
+
+ if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
+ {
+ return TYPE_FIELD_TYPE (type, i);
+ }
+ }
+
+ /* OK, it's not in this class. Recursively check the baseclasses. */
+ for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
+ {
+ struct type *t;
+
+ t = lookup_struct_elt_type (TYPE_BASECLASS (type, i), name, noerr);
+ if (t != NULL)
+ {
+ return t;
+ }
+ }
+
+ if (noerr)
+ {
+ return NULL;
+ }
+
+ target_terminal_ours ();
+ gdb_flush (gdb_stdout);
+ fprintf_unfiltered (gdb_stderr, "Type ");
+ type_print (type, "", gdb_stderr, -1);
+ fprintf_unfiltered (gdb_stderr, " has no component named ");
+ fputs_filtered (name, gdb_stderr);
+ error (".");
+ return (struct type *) -1; /* For lint */
+}
+
+/* If possible, make the vptr_fieldno and vptr_basetype fields of TYPE
+ valid. Callers should be aware that in some cases (for example,
+ the type or one of its baseclasses is a stub type and we are
+ debugging a .o file), this function will not be able to find the virtual
+ function table pointer, and vptr_fieldno will remain -1 and vptr_basetype
+ will remain NULL. */
+
+void
+fill_in_vptr_fieldno (struct type *type)
+{
+ CHECK_TYPEDEF (type);
+
+ if (TYPE_VPTR_FIELDNO (type) < 0)
+ {
+ int i;
+
+ /* We must start at zero in case the first (and only) baseclass is
+ virtual (and hence we cannot share the table pointer). */
+ for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
+ {
+ fill_in_vptr_fieldno (TYPE_BASECLASS (type, i));
+ if (TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, i)) >= 0)
+ {
+ TYPE_VPTR_FIELDNO (type)
+ = TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, i));
+ TYPE_VPTR_BASETYPE (type)
+ = TYPE_VPTR_BASETYPE (TYPE_BASECLASS (type, i));
+ break;
+ }
+ }
+ }
+}
+
+/* Find the method and field indices for the destructor in class type T.
+ Return 1 if the destructor was found, otherwise, return 0. */
+
+int
+get_destructor_fn_field (struct type *t, int *method_indexp, int *field_indexp)
+{
+ int i;
+
+ for (i = 0; i < TYPE_NFN_FIELDS (t); i++)
+ {
+ int j;
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
+
+ for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (t, i); j++)
+ {
+ if (is_destructor_name (TYPE_FN_FIELD_PHYSNAME (f, j)) != 0)
+ {
+ *method_indexp = i;
+ *field_indexp = j;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Added by Bryan Boreham, Kewill, Sun Sep 17 18:07:17 1989.
+
+ If this is a stubbed struct (i.e. declared as struct foo *), see if
+ we can find a full definition in some other file. If so, copy this
+ definition, so we can use it in future. There used to be a comment (but
+ not any code) that if we don't find a full definition, we'd set a flag
+ so we don't spend time in the future checking the same type. That would
+ be a mistake, though--we might load in more symbols which contain a
+ full definition for the type.
+
+ This used to be coded as a macro, but I don't think it is called
+ often enough to merit such treatment. */
+
+struct complaint stub_noname_complaint =
+{"stub type has NULL name", 0, 0};
+
+struct type *
+check_typedef (struct type *type)
+{
+ struct type *orig_type = type;
+ int is_const, is_volatile;
+
+ while (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
+ {
+ if (!TYPE_TARGET_TYPE (type))
+ {
+ char *name;
+ struct symbol *sym;
+
+ /* It is dangerous to call lookup_symbol if we are currently
+ reading a symtab. Infinite recursion is one danger. */
+ if (currently_reading_symtab)
+ return type;
+
+ name = type_name_no_tag (type);
+ /* FIXME: shouldn't we separately check the TYPE_NAME and the
+ TYPE_TAG_NAME, and look in STRUCT_NAMESPACE and/or VAR_NAMESPACE
+ as appropriate? (this code was written before TYPE_NAME and
+ TYPE_TAG_NAME were separate). */
+ if (name == NULL)
+ {
+ complain (&stub_noname_complaint);
+ return type;
+ }
+ sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0,
+ (struct symtab **) NULL);
+ if (sym)
+ TYPE_TARGET_TYPE (type) = SYMBOL_TYPE (sym);
+ else
+ TYPE_TARGET_TYPE (type) = alloc_type (NULL); /* TYPE_CODE_UNDEF */
+ }
+ type = TYPE_TARGET_TYPE (type);
+ }
+
+ is_const = TYPE_CONST (type);
+ is_volatile = TYPE_VOLATILE (type);
+
+ /* If this is a struct/class/union with no fields, then check whether a
+ full definition exists somewhere else. This is for systems where a
+ type definition with no fields is issued for such types, instead of
+ identifying them as stub types in the first place */
+
+ if (TYPE_IS_OPAQUE (type) && opaque_type_resolution && !currently_reading_symtab)
+ {
+ char *name = type_name_no_tag (type);
+ struct type *newtype;
+ if (name == NULL)
+ {
+ complain (&stub_noname_complaint);
+ return type;
+ }
+ newtype = lookup_transparent_type (name);
+ if (newtype)
+ make_cv_type (is_const, is_volatile, newtype, &type);
+ }
+ /* Otherwise, rely on the stub flag being set for opaque/stubbed types */
+ else if (TYPE_STUB (type) && !currently_reading_symtab)
+ {
+ char *name = type_name_no_tag (type);
+ /* FIXME: shouldn't we separately check the TYPE_NAME and the
+ TYPE_TAG_NAME, and look in STRUCT_NAMESPACE and/or VAR_NAMESPACE
+ as appropriate? (this code was written before TYPE_NAME and
+ TYPE_TAG_NAME were separate). */
+ struct symbol *sym;
+ if (name == NULL)
+ {
+ complain (&stub_noname_complaint);
+ return type;
+ }
+ sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0, (struct symtab **) NULL);
+ if (sym)
+ make_cv_type (is_const, is_volatile, SYMBOL_TYPE (sym), &type);
+ }
+
+ if (TYPE_TARGET_STUB (type))
+ {
+ struct type *range_type;
+ struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
+
+ if (TYPE_STUB (target_type) || TYPE_TARGET_STUB (target_type))
+ {
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_NFIELDS (type) == 1
+ && (TYPE_CODE (range_type = TYPE_FIELD_TYPE (type, 0))
+ == TYPE_CODE_RANGE))
+ {
+ /* Now recompute the length of the array type, based on its
+ number of elements and the target type's length. */
+ TYPE_LENGTH (type) =
+ ((TYPE_FIELD_BITPOS (range_type, 1)
+ - TYPE_FIELD_BITPOS (range_type, 0)
+ + 1)
+ * TYPE_LENGTH (target_type));
+ TYPE_FLAGS (type) &= ~TYPE_FLAG_TARGET_STUB;
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
+ {
+ TYPE_LENGTH (type) = TYPE_LENGTH (target_type);
+ TYPE_FLAGS (type) &= ~TYPE_FLAG_TARGET_STUB;
+ }
+ }
+ /* Cache TYPE_LENGTH for future use. */
+ TYPE_LENGTH (orig_type) = TYPE_LENGTH (type);
+ return type;
+}
+
+/* New code added to support parsing of Cfront stabs strings */
+#define INIT_EXTRA { pextras->len=0; pextras->str[0]='\0'; }
+#define ADD_EXTRA(c) { pextras->str[pextras->len++]=c; }
+
+static void
+add_name (struct extra *pextras, char *n)
+{
+ int nlen;
+
+ if ((nlen = (n ? strlen (n) : 0)) == 0)
+ return;
+ sprintf (pextras->str + pextras->len, "%d%s", nlen, n);
+ pextras->len = strlen (pextras->str);
+}
+
+static void
+add_mangled_type (struct extra *pextras, struct type *t)
+{
+ enum type_code tcode;
+ int tlen, tflags;
+ char *tname;
+
+ tcode = TYPE_CODE (t);
+ tlen = TYPE_LENGTH (t);
+ tflags = TYPE_FLAGS (t);
+ tname = TYPE_NAME (t);
+ /* args of "..." seem to get mangled as "e" */
+
+ switch (tcode)
+ {
+ case TYPE_CODE_INT:
+ if (tflags == 1)
+ ADD_EXTRA ('U');
+ switch (tlen)
+ {
+ case 1:
+ ADD_EXTRA ('c');
+ break;
+ case 2:
+ ADD_EXTRA ('s');
+ break;
+ case 4:
+ {
+ char *pname;
+ if ((pname = strrchr (tname, 'l'), pname) && !strcmp (pname, "long"))
+ {
+ ADD_EXTRA ('l');
+ }
+ else
+ {
+ ADD_EXTRA ('i');
+ }
+ }
+ break;
+ default:
+ {
+
+ static struct complaint msg =
+ {"Bad int type code length x%x\n", 0, 0};
+
+ complain (&msg, tlen);
+
+ }
+ }
+ break;
+ case TYPE_CODE_FLT:
+ switch (tlen)
+ {
+ case 4:
+ ADD_EXTRA ('f');
+ break;
+ case 8:
+ ADD_EXTRA ('d');
+ break;
+ case 16:
+ ADD_EXTRA ('r');
+ break;
+ default:
+ {
+ static struct complaint msg =
+ {"Bad float type code length x%x\n", 0, 0};
+ complain (&msg, tlen);
+ }
+ }
+ break;
+ case TYPE_CODE_REF:
+ ADD_EXTRA ('R');
+ /* followed by what it's a ref to */
+ break;
+ case TYPE_CODE_PTR:
+ ADD_EXTRA ('P');
+ /* followed by what it's a ptr to */
+ break;
+ case TYPE_CODE_TYPEDEF:
+ {
+ static struct complaint msg =
+ {"Typedefs in overloaded functions not yet supported\n", 0, 0};
+ complain (&msg);
+ }
+ /* followed by type bytes & name */
+ break;
+ case TYPE_CODE_FUNC:
+ ADD_EXTRA ('F');
+ /* followed by func's arg '_' & ret types */
+ break;
+ case TYPE_CODE_VOID:
+ ADD_EXTRA ('v');
+ break;
+ case TYPE_CODE_METHOD:
+ ADD_EXTRA ('M');
+ /* followed by name of class and func's arg '_' & ret types */
+ add_name (pextras, tname);
+ ADD_EXTRA ('F'); /* then mangle function */
+ break;
+ case TYPE_CODE_STRUCT: /* C struct */
+ case TYPE_CODE_UNION: /* C union */
+ case TYPE_CODE_ENUM: /* Enumeration type */
+ /* followed by name of type */
+ add_name (pextras, tname);
+ break;
+
+ /* errors possible types/not supported */
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_ARRAY: /* Array type */
+ case TYPE_CODE_MEMBER: /* Member type */
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_COMPLEX: /* Complex float */
+ case TYPE_CODE_UNDEF:
+ case TYPE_CODE_SET: /* Pascal sets */
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_STRING:
+ case TYPE_CODE_BITSTRING:
+ case TYPE_CODE_ERROR:
+ default:
+ {
+ static struct complaint msg =
+ {"Unknown type code x%x\n", 0, 0};
+ complain (&msg, tcode);
+ }
+ }
+ if (TYPE_TARGET_TYPE (t))
+ add_mangled_type (pextras, TYPE_TARGET_TYPE (t));
+}
+
+#if 0
+void
+cfront_mangle_name (struct type *type, int i, int j)
+{
+ struct fn_field *f;
+ char *mangled_name = gdb_mangle_name (type, i, j);
+
+ f = TYPE_FN_FIELDLIST1 (type, i); /* moved from below */
+
+ /* kludge to support cfront methods - gdb expects to find "F" for
+ ARM_mangled names, so when we mangle, we have to add it here */
+ if (ARM_DEMANGLING)
+ {
+ int k;
+ char *arm_mangled_name;
+ struct fn_field *method = &f[j];
+ char *field_name = TYPE_FN_FIELDLIST_NAME (type, i);
+ char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
+ char *newname = type_name_no_tag (type);
+
+ struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);
+ int nargs = TYPE_NFIELDS (ftype); /* number of args */
+ struct extra extras, *pextras = &extras;
+ INIT_EXTRA
+
+ if (TYPE_FN_FIELD_STATIC_P (f, j)) /* j for sublist within this list */
+ ADD_EXTRA ('S')
+ ADD_EXTRA ('F')
+ /* add args here! */
+ if (nargs <= 1) /* no args besides this */
+ ADD_EXTRA ('v')
+ else
+ {
+ for (k = 1; k < nargs; k++)
+ {
+ struct type *t;
+ t = TYPE_FIELD_TYPE (ftype, k);
+ add_mangled_type (pextras, t);
+ }
+ }
+ ADD_EXTRA ('\0')
+ printf ("add_mangled_type: %s\n", extras.str); /* FIXME */
+ xasprintf (&arm_mangled_name, "%s%s", mangled_name, extras.str);
+ xfree (mangled_name);
+ mangled_name = arm_mangled_name;
+ }
+}
+#endif /* 0 */
+
+#undef ADD_EXTRA
+/* End of new code added to support parsing of Cfront stabs strings */
+
+/* Parse a type expression in the string [P..P+LENGTH). If an error occurs,
+ silently return builtin_type_void. */
+
+struct type *
+safe_parse_type (char *p, int length)
+{
+ struct ui_file *saved_gdb_stderr;
+ struct type *type;
+
+ /* Suppress error messages. */
+ saved_gdb_stderr = gdb_stderr;
+ gdb_stderr = ui_file_new ();
+
+ /* Call parse_and_eval_type() without fear of longjmp()s. */
+ if (!gdb_parse_and_eval_type (p, length, &type))
+ type = builtin_type_void;
+
+ /* Stop suppressing error messages. */
+ ui_file_delete (gdb_stderr);
+ gdb_stderr = saved_gdb_stderr;
+
+ return type;
+}
+
+/* Ugly hack to convert method stubs into method types.
+
+ He ain't kiddin'. This demangles the name of the method into a string
+ including argument types, parses out each argument type, generates
+ a string casting a zero to that type, evaluates the string, and stuffs
+ the resulting type into an argtype vector!!! Then it knows the type
+ of the whole function (including argument types for overloading),
+ which info used to be in the stab's but was removed to hack back
+ the space required for them. */
+
+void
+check_stub_method (struct type *type, int method_id, int signature_id)
+{
+ struct fn_field *f;
+ char *mangled_name = gdb_mangle_name (type, method_id, signature_id);
+ char *demangled_name = cplus_demangle (mangled_name,
+ DMGL_PARAMS | DMGL_ANSI);
+ char *argtypetext, *p;
+ int depth = 0, argcount = 1;
+ struct type **argtypes;
+ struct type *mtype;
+
+ /* Make sure we got back a function string that we can use. */
+ if (demangled_name)
+ p = strchr (demangled_name, '(');
+ else
+ p = NULL;
+
+ if (demangled_name == NULL || p == NULL)
+ error ("Internal: Cannot demangle mangled name `%s'.", mangled_name);
+
+ /* Now, read in the parameters that define this type. */
+ p += 1;
+ argtypetext = p;
+ while (*p)
+ {
+ if (*p == '(' || *p == '<')
+ {
+ depth += 1;
+ }
+ else if (*p == ')' || *p == '>')
+ {
+ depth -= 1;
+ }
+ else if (*p == ',' && depth == 0)
+ {
+ argcount += 1;
+ }
+
+ p += 1;
+ }
+
+ /* We need two more slots: one for the THIS pointer, and one for the
+ NULL [...] or void [end of arglist]. */
+
+ argtypes = (struct type **)
+ TYPE_ALLOC (type, (argcount + 2) * sizeof (struct type *));
+ p = argtypetext;
+
+ /* Add THIS pointer for non-static methods. */
+ f = TYPE_FN_FIELDLIST1 (type, method_id);
+ if (TYPE_FN_FIELD_STATIC_P (f, signature_id))
+ argcount = 0;
+ else
+ {
+ argtypes[0] = lookup_pointer_type (type);
+ argcount = 1;
+ }
+
+ if (*p != ')') /* () means no args, skip while */
+ {
+ depth = 0;
+ while (*p)
+ {
+ if (depth <= 0 && (*p == ',' || *p == ')'))
+ {
+ /* Avoid parsing of ellipsis, they will be handled below. */
+ if (strncmp (argtypetext, "...", p - argtypetext) != 0)
+ {
+ argtypes[argcount] =
+ safe_parse_type (argtypetext, p - argtypetext);
+ argcount += 1;
+ }
+ argtypetext = p + 1;
+ }
+
+ if (*p == '(' || *p == '<')
+ {
+ depth += 1;
+ }
+ else if (*p == ')' || *p == '>')
+ {
+ depth -= 1;
+ }
+
+ p += 1;
+ }
+ }
+
+ if (p[-2] != '.') /* Not '...' */
+ {
+ argtypes[argcount] = builtin_type_void; /* List terminator */
+ }
+ else
+ {
+ argtypes[argcount] = NULL; /* Ellist terminator */
+ }
+
+ xfree (demangled_name);
+
+ TYPE_FN_FIELD_PHYSNAME (f, signature_id) = mangled_name;
+
+ /* Now update the old "stub" type into a real type. */
+ mtype = TYPE_FN_FIELD_TYPE (f, signature_id);
+ TYPE_DOMAIN_TYPE (mtype) = type;
+ TYPE_ARG_TYPES (mtype) = argtypes;
+ TYPE_FLAGS (mtype) &= ~TYPE_FLAG_STUB;
+ TYPE_FN_FIELD_STUB (f, signature_id) = 0;
+}
+
+const struct cplus_struct_type cplus_struct_default;
+
+void
+allocate_cplus_struct_type (struct type *type)
+{
+ if (!HAVE_CPLUS_STRUCT (type))
+ {
+ TYPE_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *)
+ TYPE_ALLOC (type, sizeof (struct cplus_struct_type));
+ *(TYPE_CPLUS_SPECIFIC (type)) = cplus_struct_default;
+ }
+}
+
+/* Helper function to initialize the standard scalar types.
+
+ If NAME is non-NULL and OBJFILE is non-NULL, then we make a copy
+ of the string pointed to by name in the type_obstack for that objfile,
+ and initialize the type name to that copy. There are places (mipsread.c
+ in particular, where init_type is called with a NULL value for NAME). */
+
+struct type *
+init_type (enum type_code code, int length, int flags, char *name,
+ struct objfile *objfile)
+{
+ register struct type *type;
+
+ type = alloc_type (objfile);
+ TYPE_CODE (type) = code;
+ TYPE_LENGTH (type) = length;
+ TYPE_FLAGS (type) |= flags;
+ if ((name != NULL) && (objfile != NULL))
+ {
+ TYPE_NAME (type) =
+ obsavestring (name, strlen (name), &objfile->type_obstack);
+ }
+ else
+ {
+ TYPE_NAME (type) = name;
+ }
+
+ /* C++ fancies. */
+
+ if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
+ {
+ INIT_CPLUS_SPECIFIC (type);
+ }
+ return (type);
+}
+
+/* Helper function. Create an empty composite type. */
+
+struct type *
+init_composite_type (char *name, enum type_code code)
+{
+ struct type *t;
+ gdb_assert (code == TYPE_CODE_STRUCT
+ || code == TYPE_CODE_UNION);
+ t = init_type (code, 0, 0, NULL, NULL);
+ TYPE_TAG_NAME (t) = name;
+ return t;
+}
+
+/* Helper function. Append a field to a composite type. */
+
+void
+append_composite_type_field (struct type *t, char *name, struct type *field)
+{
+ struct field *f;
+ TYPE_NFIELDS (t) = TYPE_NFIELDS (t) + 1;
+ TYPE_FIELDS (t) = xrealloc (TYPE_FIELDS (t),
+ sizeof (struct field) * TYPE_NFIELDS (t));
+ f = &(TYPE_FIELDS (t)[TYPE_NFIELDS (t) - 1]);
+ memset (f, 0, sizeof f[0]);
+ FIELD_TYPE (f[0]) = field;
+ FIELD_NAME (f[0]) = name;
+ if (TYPE_CODE (t) == TYPE_CODE_UNION)
+ {
+ if (TYPE_LENGTH (t) < TYPE_LENGTH (field))
+ TYPE_LENGTH (t) = TYPE_LENGTH (field);
+ }
+ else if (TYPE_CODE (t) == TYPE_CODE_STRUCT)
+ {
+ TYPE_LENGTH (t) = TYPE_LENGTH (t) + TYPE_LENGTH (field);
+ if (TYPE_NFIELDS (t) > 1)
+ {
+ FIELD_BITPOS (f[0]) = (FIELD_BITPOS (f[-1])
+ + TYPE_LENGTH (field) * TARGET_CHAR_BIT);
+ }
+ }
+}
+
+/* Look up a fundamental type for the specified objfile.
+ May need to construct such a type if this is the first use.
+
+ Some object file formats (ELF, COFF, etc) do not define fundamental
+ types such as "int" or "double". Others (stabs for example), do
+ define fundamental types.
+
+ For the formats which don't provide fundamental types, gdb can create
+ such types, using defaults reasonable for the current language and
+ the current target machine.
+
+ NOTE: This routine is obsolescent. Each debugging format reader
+ should manage it's own fundamental types, either creating them from
+ suitable defaults or reading them from the debugging information,
+ whichever is appropriate. The DWARF reader has already been
+ fixed to do this. Once the other readers are fixed, this routine
+ will go away. Also note that fundamental types should be managed
+ on a compilation unit basis in a multi-language environment, not
+ on a linkage unit basis as is done here. */
+
+
+struct type *
+lookup_fundamental_type (struct objfile *objfile, int typeid)
+{
+ register struct type **typep;
+ register int nbytes;
+
+ if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
+ {
+ error ("internal error - invalid fundamental type id %d", typeid);
+ }
+
+ /* If this is the first time we need a fundamental type for this objfile
+ then we need to initialize the vector of type pointers. */
+
+ if (objfile->fundamental_types == NULL)
+ {
+ nbytes = FT_NUM_MEMBERS * sizeof (struct type *);
+ objfile->fundamental_types = (struct type **)
+ obstack_alloc (&objfile->type_obstack, nbytes);
+ memset ((char *) objfile->fundamental_types, 0, nbytes);
+ OBJSTAT (objfile, n_types += FT_NUM_MEMBERS);
+ }
+
+ /* Look for this particular type in the fundamental type vector. If one is
+ not found, create and install one appropriate for the current language. */
+
+ typep = objfile->fundamental_types + typeid;
+ if (*typep == NULL)
+ {
+ *typep = create_fundamental_type (objfile, typeid);
+ }
+
+ return (*typep);
+}
+
+int
+can_dereference (struct type *t)
+{
+ /* FIXME: Should we return true for references as well as pointers? */
+ CHECK_TYPEDEF (t);
+ return
+ (t != NULL
+ && TYPE_CODE (t) == TYPE_CODE_PTR
+ && TYPE_CODE (TYPE_TARGET_TYPE (t)) != TYPE_CODE_VOID);
+}
+
+int
+is_integral_type (struct type *t)
+{
+ CHECK_TYPEDEF (t);
+ return
+ ((t != NULL)
+ && ((TYPE_CODE (t) == TYPE_CODE_INT)
+ || (TYPE_CODE (t) == TYPE_CODE_ENUM)
+ || (TYPE_CODE (t) == TYPE_CODE_CHAR)
+ || (TYPE_CODE (t) == TYPE_CODE_RANGE)
+ || (TYPE_CODE (t) == TYPE_CODE_BOOL)));
+}
+
+/* Chill varying string and arrays are represented as follows:
+
+ struct { int __var_length; ELEMENT_TYPE[MAX_SIZE] __var_data};
+
+ Return true if TYPE is such a Chill varying type. */
+
+int
+chill_varying_type (struct type *type)
+{
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+ || TYPE_NFIELDS (type) != 2
+ || strcmp (TYPE_FIELD_NAME (type, 0), "__var_length") != 0)
+ return 0;
+ return 1;
+}
+
+/* Check whether BASE is an ancestor or base class or DCLASS
+ Return 1 if so, and 0 if not.
+ Note: callers may want to check for identity of the types before
+ calling this function -- identical types are considered to satisfy
+ the ancestor relationship even if they're identical */
+
+int
+is_ancestor (struct type *base, struct type *dclass)
+{
+ int i;
+
+ CHECK_TYPEDEF (base);
+ CHECK_TYPEDEF (dclass);
+
+ if (base == dclass)
+ return 1;
+ if (TYPE_NAME (base) && TYPE_NAME (dclass) &&
+ !strcmp (TYPE_NAME (base), TYPE_NAME (dclass)))
+ return 1;
+
+ for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
+ if (is_ancestor (base, TYPE_BASECLASS (dclass, i)))
+ return 1;
+
+ return 0;
+}
+
+
+
+/* See whether DCLASS has a virtual table. This routine is aimed at
+ the HP/Taligent ANSI C++ runtime model, and may not work with other
+ runtime models. Return 1 => Yes, 0 => No. */
+
+int
+has_vtable (struct type *dclass)
+{
+ /* In the HP ANSI C++ runtime model, a class has a vtable only if it
+ has virtual functions or virtual bases. */
+
+ register int i;
+
+ if (TYPE_CODE (dclass) != TYPE_CODE_CLASS)
+ return 0;
+
+ /* First check for the presence of virtual bases */
+ if (TYPE_FIELD_VIRTUAL_BITS (dclass))
+ for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
+ if (B_TST (TYPE_FIELD_VIRTUAL_BITS (dclass), i))
+ return 1;
+
+ /* Next check for virtual functions */
+ if (TYPE_FN_FIELDLISTS (dclass))
+ for (i = 0; i < TYPE_NFN_FIELDS (dclass); i++)
+ if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (dclass, i), 0))
+ return 1;
+
+ /* Recurse on non-virtual bases to see if any of them needs a vtable */
+ if (TYPE_FIELD_VIRTUAL_BITS (dclass))
+ for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
+ if ((!B_TST (TYPE_FIELD_VIRTUAL_BITS (dclass), i)) &&
+ (has_vtable (TYPE_FIELD_TYPE (dclass, i))))
+ return 1;
+
+ /* Well, maybe we don't need a virtual table */
+ return 0;
+}
+
+/* Return a pointer to the "primary base class" of DCLASS.
+
+ A NULL return indicates that DCLASS has no primary base, or that it
+ couldn't be found (insufficient information).
+
+ This routine is aimed at the HP/Taligent ANSI C++ runtime model,
+ and may not work with other runtime models. */
+
+struct type *
+primary_base_class (struct type *dclass)
+{
+ /* In HP ANSI C++'s runtime model, a "primary base class" of a class
+ is the first directly inherited, non-virtual base class that
+ requires a virtual table */
+
+ register int i;
+
+ if (TYPE_CODE (dclass) != TYPE_CODE_CLASS)
+ return NULL;
+
+ for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
+ if (!TYPE_FIELD_VIRTUAL (dclass, i) &&
+ has_vtable (TYPE_FIELD_TYPE (dclass, i)))
+ return TYPE_FIELD_TYPE (dclass, i);
+
+ return NULL;
+}
+
+/* Global manipulated by virtual_base_list[_aux]() */
+
+static struct vbase *current_vbase_list = NULL;
+
+/* Return a pointer to a null-terminated list of struct vbase
+ items. The vbasetype pointer of each item in the list points to the
+ type information for a virtual base of the argument DCLASS.
+
+ Helper function for virtual_base_list().
+ Note: the list goes backward, right-to-left. virtual_base_list()
+ copies the items out in reverse order. */
+
+static void
+virtual_base_list_aux (struct type *dclass)
+{
+ struct vbase *tmp_vbase;
+ register int i;
+
+ if (TYPE_CODE (dclass) != TYPE_CODE_CLASS)
+ return;
+
+ for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
+ {
+ /* Recurse on this ancestor, first */
+ virtual_base_list_aux (TYPE_FIELD_TYPE (dclass, i));
+
+ /* If this current base is itself virtual, add it to the list */
+ if (BASETYPE_VIA_VIRTUAL (dclass, i))
+ {
+ struct type *basetype = TYPE_FIELD_TYPE (dclass, i);
+
+ /* Check if base already recorded */
+ tmp_vbase = current_vbase_list;
+ while (tmp_vbase)
+ {
+ if (tmp_vbase->vbasetype == basetype)
+ break; /* found it */
+ tmp_vbase = tmp_vbase->next;
+ }
+
+ if (!tmp_vbase) /* normal exit from loop */
+ {
+ /* Allocate new item for this virtual base */
+ tmp_vbase = (struct vbase *) xmalloc (sizeof (struct vbase));
+
+ /* Stick it on at the end of the list */
+ tmp_vbase->vbasetype = basetype;
+ tmp_vbase->next = current_vbase_list;
+ current_vbase_list = tmp_vbase;
+ }
+ } /* if virtual */
+ } /* for loop over bases */
+}
+
+
+/* Compute the list of virtual bases in the right order. Virtual
+ bases are laid out in the object's memory area in order of their
+ occurrence in a depth-first, left-to-right search through the
+ ancestors.
+
+ Argument DCLASS is the type whose virtual bases are required.
+ Return value is the address of a null-terminated array of pointers
+ to struct type items.
+
+ This routine is aimed at the HP/Taligent ANSI C++ runtime model,
+ and may not work with other runtime models.
+
+ This routine merely hands off the argument to virtual_base_list_aux()
+ and then copies the result into an array to save space. */
+
+struct type **
+virtual_base_list (struct type *dclass)
+{
+ register struct vbase *tmp_vbase;
+ register struct vbase *tmp_vbase_2;
+ register int i;
+ int count;
+ struct type **vbase_array;
+
+ current_vbase_list = NULL;
+ virtual_base_list_aux (dclass);
+
+ for (i = 0, tmp_vbase = current_vbase_list; tmp_vbase != NULL; i++, tmp_vbase = tmp_vbase->next)
+ /* no body */ ;
+
+ count = i;
+
+ vbase_array = (struct type **) xmalloc ((count + 1) * sizeof (struct type *));
+
+ for (i = count - 1, tmp_vbase = current_vbase_list; i >= 0; i--, tmp_vbase = tmp_vbase->next)
+ vbase_array[i] = tmp_vbase->vbasetype;
+
+ /* Get rid of constructed chain */
+ tmp_vbase_2 = tmp_vbase = current_vbase_list;
+ while (tmp_vbase)
+ {
+ tmp_vbase = tmp_vbase->next;
+ xfree (tmp_vbase_2);
+ tmp_vbase_2 = tmp_vbase;
+ }
+
+ vbase_array[count] = NULL;
+ return vbase_array;
+}
+
+/* Return the length of the virtual base list of the type DCLASS. */
+
+int
+virtual_base_list_length (struct type *dclass)
+{
+ register int i;
+ register struct vbase *tmp_vbase;
+
+ current_vbase_list = NULL;
+ virtual_base_list_aux (dclass);
+
+ for (i = 0, tmp_vbase = current_vbase_list; tmp_vbase != NULL; i++, tmp_vbase = tmp_vbase->next)
+ /* no body */ ;
+ return i;
+}
+
+/* Return the number of elements of the virtual base list of the type
+ DCLASS, ignoring those appearing in the primary base (and its
+ primary base, recursively). */
+
+int
+virtual_base_list_length_skip_primaries (struct type *dclass)
+{
+ register int i;
+ register struct vbase *tmp_vbase;
+ struct type *primary;
+
+ primary = TYPE_RUNTIME_PTR (dclass) ? TYPE_PRIMARY_BASE (dclass) : NULL;
+
+ if (!primary)
+ return virtual_base_list_length (dclass);
+
+ current_vbase_list = NULL;
+ virtual_base_list_aux (dclass);
+
+ for (i = 0, tmp_vbase = current_vbase_list; tmp_vbase != NULL; tmp_vbase = tmp_vbase->next)
+ {
+ if (virtual_base_index (tmp_vbase->vbasetype, primary) >= 0)
+ continue;
+ i++;
+ }
+ return i;
+}
+
+
+/* Return the index (position) of type BASE, which is a virtual base
+ class of DCLASS, in the latter's virtual base list. A return of -1
+ indicates "not found" or a problem. */
+
+int
+virtual_base_index (struct type *base, struct type *dclass)
+{
+ register struct type *vbase;
+ register int i;
+
+ if ((TYPE_CODE (dclass) != TYPE_CODE_CLASS) ||
+ (TYPE_CODE (base) != TYPE_CODE_CLASS))
+ return -1;
+
+ i = 0;
+ vbase = virtual_base_list (dclass)[0];
+ while (vbase)
+ {
+ if (vbase == base)
+ break;
+ vbase = virtual_base_list (dclass)[++i];
+ }
+
+ return vbase ? i : -1;
+}
+
+
+
+/* Return the index (position) of type BASE, which is a virtual base
+ class of DCLASS, in the latter's virtual base list. Skip over all
+ bases that may appear in the virtual base list of the primary base
+ class of DCLASS (recursively). A return of -1 indicates "not
+ found" or a problem. */
+
+int
+virtual_base_index_skip_primaries (struct type *base, struct type *dclass)
+{
+ register struct type *vbase;
+ register int i, j;
+ struct type *primary;
+
+ if ((TYPE_CODE (dclass) != TYPE_CODE_CLASS) ||
+ (TYPE_CODE (base) != TYPE_CODE_CLASS))
+ return -1;
+
+ primary = TYPE_RUNTIME_PTR (dclass) ? TYPE_PRIMARY_BASE (dclass) : NULL;
+
+ j = -1;
+ i = 0;
+ vbase = virtual_base_list (dclass)[0];
+ while (vbase)
+ {
+ if (!primary || (virtual_base_index_skip_primaries (vbase, primary) < 0))
+ j++;
+ if (vbase == base)
+ break;
+ vbase = virtual_base_list (dclass)[++i];
+ }
+
+ return vbase ? j : -1;
+}
+
+/* Return position of a derived class DCLASS in the list of
+ * primary bases starting with the remotest ancestor.
+ * Position returned is 0-based. */
+
+int
+class_index_in_primary_list (struct type *dclass)
+{
+ struct type *pbc; /* primary base class */
+
+ /* Simply recurse on primary base */
+ pbc = TYPE_PRIMARY_BASE (dclass);
+ if (pbc)
+ return 1 + class_index_in_primary_list (pbc);
+ else
+ return 0;
+}
+
+/* Return a count of the number of virtual functions a type has.
+ * This includes all the virtual functions it inherits from its
+ * base classes too.
+ */
+
+/* pai: FIXME This doesn't do the right thing: count redefined virtual
+ * functions only once (latest redefinition)
+ */
+
+int
+count_virtual_fns (struct type *dclass)
+{
+ int fn, oi; /* function and overloaded instance indices */
+ int vfuncs; /* count to return */
+
+ /* recurse on bases that can share virtual table */
+ struct type *pbc = primary_base_class (dclass);
+ if (pbc)
+ vfuncs = count_virtual_fns (pbc);
+ else
+ vfuncs = 0;
+
+ for (fn = 0; fn < TYPE_NFN_FIELDS (dclass); fn++)
+ for (oi = 0; oi < TYPE_FN_FIELDLIST_LENGTH (dclass, fn); oi++)
+ if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (dclass, fn), oi))
+ vfuncs++;
+
+ return vfuncs;
+}
+
+
+
+/* Functions for overload resolution begin here */
+
+/* Compare two badness vectors A and B and return the result.
+ * 0 => A and B are identical
+ * 1 => A and B are incomparable
+ * 2 => A is better than B
+ * 3 => A is worse than B */
+
+int
+compare_badness (struct badness_vector *a, struct badness_vector *b)
+{
+ int i;
+ int tmp;
+ short found_pos = 0; /* any positives in c? */
+ short found_neg = 0; /* any negatives in c? */
+
+ /* differing lengths => incomparable */
+ if (a->length != b->length)
+ return 1;
+
+ /* Subtract b from a */
+ for (i = 0; i < a->length; i++)
+ {
+ tmp = a->rank[i] - b->rank[i];
+ if (tmp > 0)
+ found_pos = 1;
+ else if (tmp < 0)
+ found_neg = 1;
+ }
+
+ if (found_pos)
+ {
+ if (found_neg)
+ return 1; /* incomparable */
+ else
+ return 3; /* A > B */
+ }
+ else
+ /* no positives */
+ {
+ if (found_neg)
+ return 2; /* A < B */
+ else
+ return 0; /* A == B */
+ }
+}
+
+/* Rank a function by comparing its parameter types (PARMS, length NPARMS),
+ * to the types of an argument list (ARGS, length NARGS).
+ * Return a pointer to a badness vector. This has NARGS + 1 entries. */
+
+struct badness_vector *
+rank_function (struct type **parms, int nparms, struct type **args, int nargs)
+{
+ int i;
+ struct badness_vector *bv;
+ int min_len = nparms < nargs ? nparms : nargs;
+
+ bv = xmalloc (sizeof (struct badness_vector));
+ bv->length = nargs + 1; /* add 1 for the length-match rank */
+ bv->rank = xmalloc ((nargs + 1) * sizeof (int));
+
+ /* First compare the lengths of the supplied lists.
+ * If there is a mismatch, set it to a high value. */
+
+ /* pai/1997-06-03 FIXME: when we have debug info about default
+ * arguments and ellipsis parameter lists, we should consider those
+ * and rank the length-match more finely. */
+
+ LENGTH_MATCH (bv) = (nargs != nparms) ? LENGTH_MISMATCH_BADNESS : 0;
+
+ /* Now rank all the parameters of the candidate function */
+ for (i = 1; i <= min_len; i++)
+ bv->rank[i] = rank_one_type (parms[i-1], args[i-1]);
+
+ /* If more arguments than parameters, add dummy entries */
+ for (i = min_len + 1; i <= nargs; i++)
+ bv->rank[i] = TOO_FEW_PARAMS_BADNESS;
+
+ return bv;
+}
+
+/* Compare one type (PARM) for compatibility with another (ARG).
+ * PARM is intended to be the parameter type of a function; and
+ * ARG is the supplied argument's type. This function tests if
+ * the latter can be converted to the former.
+ *
+ * Return 0 if they are identical types;
+ * Otherwise, return an integer which corresponds to how compatible
+ * PARM is to ARG. The higher the return value, the worse the match.
+ * Generally the "bad" conversions are all uniformly assigned a 100 */
+
+int
+rank_one_type (struct type *parm, struct type *arg)
+{
+ /* Identical type pointers */
+ /* However, this still doesn't catch all cases of same type for arg
+ * and param. The reason is that builtin types are different from
+ * the same ones constructed from the object. */
+ if (parm == arg)
+ return 0;
+
+ /* Resolve typedefs */
+ if (TYPE_CODE (parm) == TYPE_CODE_TYPEDEF)
+ parm = check_typedef (parm);
+ if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
+ arg = check_typedef (arg);
+
+ /*
+ Well, damnit, if the names are exactly the same,
+ i'll say they are exactly the same. This happens when we generate
+ method stubs. The types won't point to the same address, but they
+ really are the same.
+ */
+
+ if (TYPE_NAME (parm) && TYPE_NAME (arg) &&
+ !strcmp (TYPE_NAME (parm), TYPE_NAME (arg)))
+ return 0;
+
+ /* Check if identical after resolving typedefs */
+ if (parm == arg)
+ return 0;
+
+ /* See through references, since we can almost make non-references
+ references. */
+ if (TYPE_CODE (arg) == TYPE_CODE_REF)
+ return (rank_one_type (parm, TYPE_TARGET_TYPE (arg))
+ + REFERENCE_CONVERSION_BADNESS);
+ if (TYPE_CODE (parm) == TYPE_CODE_REF)
+ return (rank_one_type (TYPE_TARGET_TYPE (parm), arg)
+ + REFERENCE_CONVERSION_BADNESS);
+ if (overload_debug)
+ /* Debugging only. */
+ fprintf_filtered (gdb_stderr,"------ Arg is %s [%d], parm is %s [%d]\n",
+ TYPE_NAME (arg), TYPE_CODE (arg), TYPE_NAME (parm), TYPE_CODE (parm));
+
+ /* x -> y means arg of type x being supplied for parameter of type y */
+
+ switch (TYPE_CODE (parm))
+ {
+ case TYPE_CODE_PTR:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_PTR:
+ if (TYPE_CODE (TYPE_TARGET_TYPE (parm)) == TYPE_CODE_VOID)
+ return VOID_PTR_CONVERSION_BADNESS;
+ else
+ return rank_one_type (TYPE_TARGET_TYPE (parm), TYPE_TARGET_TYPE (arg));
+ case TYPE_CODE_ARRAY:
+ return rank_one_type (TYPE_TARGET_TYPE (parm), TYPE_TARGET_TYPE (arg));
+ case TYPE_CODE_FUNC:
+ return rank_one_type (TYPE_TARGET_TYPE (parm), arg);
+ case TYPE_CODE_INT:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_BOOL:
+ return POINTER_CONVERSION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ case TYPE_CODE_ARRAY:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_ARRAY:
+ return rank_one_type (TYPE_TARGET_TYPE (parm), TYPE_TARGET_TYPE (arg));
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ case TYPE_CODE_FUNC:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_PTR: /* funcptr -> func */
+ return rank_one_type (parm, TYPE_TARGET_TYPE (arg));
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ case TYPE_CODE_INT:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_INT:
+ if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm))
+ {
+ /* Deal with signed, unsigned, and plain chars and
+ signed and unsigned ints */
+ if (TYPE_NOSIGN (parm))
+ {
+ /* This case only for character types */
+ if (TYPE_NOSIGN (arg)) /* plain char -> plain char */
+ return 0;
+ else
+ return INTEGER_COERCION_BADNESS; /* signed/unsigned char -> plain char */
+ }
+ else if (TYPE_UNSIGNED (parm))
+ {
+ if (TYPE_UNSIGNED (arg))
+ {
+ if (!strcmp_iw (TYPE_NAME (parm), TYPE_NAME (arg)))
+ return 0; /* unsigned int -> unsigned int, or unsigned long -> unsigned long */
+ else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long"))
+ return INTEGER_PROMOTION_BADNESS; /* unsigned int -> unsigned long */
+ else
+ return INTEGER_COERCION_BADNESS; /* unsigned long -> unsigned int */
+ }
+ else
+ {
+ if (!strcmp_iw (TYPE_NAME (arg), "long") && !strcmp_iw (TYPE_NAME (parm), "int"))
+ return INTEGER_COERCION_BADNESS; /* signed long -> unsigned int */
+ else
+ return INTEGER_CONVERSION_BADNESS; /* signed int/long -> unsigned int/long */
+ }
+ }
+ else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg))
+ {
+ if (!strcmp_iw (TYPE_NAME (parm), TYPE_NAME (arg)))
+ return 0;
+ else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long"))
+ return INTEGER_PROMOTION_BADNESS;
+ else
+ return INTEGER_COERCION_BADNESS;
+ }
+ else
+ return INTEGER_COERCION_BADNESS;
+ }
+ else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
+ return INTEGER_PROMOTION_BADNESS;
+ else
+ return INTEGER_COERCION_BADNESS;
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_BOOL:
+ return INTEGER_PROMOTION_BADNESS;
+ case TYPE_CODE_FLT:
+ return INT_FLOAT_CONVERSION_BADNESS;
+ case TYPE_CODE_PTR:
+ return NS_POINTER_CONVERSION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_ENUM:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_ENUM:
+ return INTEGER_COERCION_BADNESS;
+ case TYPE_CODE_FLT:
+ return INT_FLOAT_CONVERSION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_CHAR:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_ENUM:
+ return INTEGER_COERCION_BADNESS;
+ case TYPE_CODE_FLT:
+ return INT_FLOAT_CONVERSION_BADNESS;
+ case TYPE_CODE_INT:
+ if (TYPE_LENGTH (arg) > TYPE_LENGTH (parm))
+ return INTEGER_COERCION_BADNESS;
+ else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
+ return INTEGER_PROMOTION_BADNESS;
+ /* >>> !! else fall through !! <<< */
+ case TYPE_CODE_CHAR:
+ /* Deal with signed, unsigned, and plain chars for C++
+ and with int cases falling through from previous case */
+ if (TYPE_NOSIGN (parm))
+ {
+ if (TYPE_NOSIGN (arg))
+ return 0;
+ else
+ return INTEGER_COERCION_BADNESS;
+ }
+ else if (TYPE_UNSIGNED (parm))
+ {
+ if (TYPE_UNSIGNED (arg))
+ return 0;
+ else
+ return INTEGER_PROMOTION_BADNESS;
+ }
+ else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg))
+ return 0;
+ else
+ return INTEGER_COERCION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_RANGE:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_ENUM:
+ return INTEGER_COERCION_BADNESS;
+ case TYPE_CODE_FLT:
+ return INT_FLOAT_CONVERSION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_BOOL:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_PTR:
+ return BOOLEAN_CONVERSION_BADNESS;
+ case TYPE_CODE_BOOL:
+ return 0;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_FLT:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_FLT:
+ if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
+ return FLOAT_PROMOTION_BADNESS;
+ else if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm))
+ return 0;
+ else
+ return FLOAT_CONVERSION_BADNESS;
+ case TYPE_CODE_INT:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_CHAR:
+ return INT_FLOAT_CONVERSION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_COMPLEX:
+ switch (TYPE_CODE (arg))
+ { /* Strictly not needed for C++, but... */
+ case TYPE_CODE_FLT:
+ return FLOAT_PROMOTION_BADNESS;
+ case TYPE_CODE_COMPLEX:
+ return 0;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_STRUCT:
+ /* currently same as TYPE_CODE_CLASS */
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_STRUCT:
+ /* Check for derivation */
+ if (is_ancestor (parm, arg))
+ return BASE_CONVERSION_BADNESS;
+ /* else fall through */
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_UNION:
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_UNION:
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_MEMBER:
+ switch (TYPE_CODE (arg))
+ {
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_METHOD:
+ switch (TYPE_CODE (arg))
+ {
+
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_REF:
+ switch (TYPE_CODE (arg))
+ {
+
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+
+ break;
+ case TYPE_CODE_SET:
+ switch (TYPE_CODE (arg))
+ {
+ /* Not in C++ */
+ case TYPE_CODE_SET:
+ return rank_one_type (TYPE_FIELD_TYPE (parm, 0), TYPE_FIELD_TYPE (arg, 0));
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+ break;
+ case TYPE_CODE_VOID:
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ } /* switch (TYPE_CODE (arg)) */
+}
+
+
+/* End of functions for overload resolution */
+
+static void
+print_bit_vector (B_TYPE *bits, int nbits)
+{
+ int bitno;
+
+ for (bitno = 0; bitno < nbits; bitno++)
+ {
+ if ((bitno % 8) == 0)
+ {
+ puts_filtered (" ");
+ }
+ if (B_TST (bits, bitno))
+ {
+ printf_filtered ("1");
+ }
+ else
+ {
+ printf_filtered ("0");
+ }
+ }
+}
+
+/* The args list is a strange beast. It is either terminated by a NULL
+ pointer for varargs functions, or by a pointer to a TYPE_CODE_VOID
+ type for normal fixed argcount functions. (FIXME someday)
+ Also note the first arg should be the "this" pointer, we may not want to
+ include it since we may get into a infinitely recursive situation. */
+
+static void
+print_arg_types (struct type **args, int spaces)
+{
+ if (args != NULL)
+ {
+ while (*args != NULL)
+ {
+ recursive_dump_type (*args, spaces + 2);
+ if (TYPE_CODE (*args++) == TYPE_CODE_VOID)
+ {
+ break;
+ }
+ }
+ }
+}
+
+static void
+dump_fn_fieldlists (struct type *type, int spaces)
+{
+ int method_idx;
+ int overload_idx;
+ struct fn_field *f;
+
+ printfi_filtered (spaces, "fn_fieldlists ");
+ gdb_print_host_address (TYPE_FN_FIELDLISTS (type), gdb_stdout);
+ printf_filtered ("\n");
+ for (method_idx = 0; method_idx < TYPE_NFN_FIELDS (type); method_idx++)
+ {
+ f = TYPE_FN_FIELDLIST1 (type, method_idx);
+ printfi_filtered (spaces + 2, "[%d] name '%s' (",
+ method_idx,
+ TYPE_FN_FIELDLIST_NAME (type, method_idx));
+ gdb_print_host_address (TYPE_FN_FIELDLIST_NAME (type, method_idx),
+ gdb_stdout);
+ printf_filtered (") length %d\n",
+ TYPE_FN_FIELDLIST_LENGTH (type, method_idx));
+ for (overload_idx = 0;
+ overload_idx < TYPE_FN_FIELDLIST_LENGTH (type, method_idx);
+ overload_idx++)
+ {
+ printfi_filtered (spaces + 4, "[%d] physname '%s' (",
+ overload_idx,
+ TYPE_FN_FIELD_PHYSNAME (f, overload_idx));
+ gdb_print_host_address (TYPE_FN_FIELD_PHYSNAME (f, overload_idx),
+ gdb_stdout);
+ printf_filtered (")\n");
+ printfi_filtered (spaces + 8, "type ");
+ gdb_print_host_address (TYPE_FN_FIELD_TYPE (f, overload_idx), gdb_stdout);
+ printf_filtered ("\n");
+
+ recursive_dump_type (TYPE_FN_FIELD_TYPE (f, overload_idx),
+ spaces + 8 + 2);
+
+ printfi_filtered (spaces + 8, "args ");
+ gdb_print_host_address (TYPE_FN_FIELD_ARGS (f, overload_idx), gdb_stdout);
+ printf_filtered ("\n");
+
+ print_arg_types (TYPE_FN_FIELD_ARGS (f, overload_idx), spaces);
+ printfi_filtered (spaces + 8, "fcontext ");
+ gdb_print_host_address (TYPE_FN_FIELD_FCONTEXT (f, overload_idx),
+ gdb_stdout);
+ printf_filtered ("\n");
+
+ printfi_filtered (spaces + 8, "is_const %d\n",
+ TYPE_FN_FIELD_CONST (f, overload_idx));
+ printfi_filtered (spaces + 8, "is_volatile %d\n",
+ TYPE_FN_FIELD_VOLATILE (f, overload_idx));
+ printfi_filtered (spaces + 8, "is_private %d\n",
+ TYPE_FN_FIELD_PRIVATE (f, overload_idx));
+ printfi_filtered (spaces + 8, "is_protected %d\n",
+ TYPE_FN_FIELD_PROTECTED (f, overload_idx));
+ printfi_filtered (spaces + 8, "is_stub %d\n",
+ TYPE_FN_FIELD_STUB (f, overload_idx));
+ printfi_filtered (spaces + 8, "voffset %u\n",
+ TYPE_FN_FIELD_VOFFSET (f, overload_idx));
+ }
+ }
+}
+
+static void
+print_cplus_stuff (struct type *type, int spaces)
+{
+ printfi_filtered (spaces, "n_baseclasses %d\n",
+ TYPE_N_BASECLASSES (type));
+ printfi_filtered (spaces, "nfn_fields %d\n",
+ TYPE_NFN_FIELDS (type));
+ printfi_filtered (spaces, "nfn_fields_total %d\n",
+ TYPE_NFN_FIELDS_TOTAL (type));
+ if (TYPE_N_BASECLASSES (type) > 0)
+ {
+ printfi_filtered (spaces, "virtual_field_bits (%d bits at *",
+ TYPE_N_BASECLASSES (type));
+ gdb_print_host_address (TYPE_FIELD_VIRTUAL_BITS (type), gdb_stdout);
+ printf_filtered (")");
+
+ print_bit_vector (TYPE_FIELD_VIRTUAL_BITS (type),
+ TYPE_N_BASECLASSES (type));
+ puts_filtered ("\n");
+ }
+ if (TYPE_NFIELDS (type) > 0)
+ {
+ if (TYPE_FIELD_PRIVATE_BITS (type) != NULL)
+ {
+ printfi_filtered (spaces, "private_field_bits (%d bits at *",
+ TYPE_NFIELDS (type));
+ gdb_print_host_address (TYPE_FIELD_PRIVATE_BITS (type), gdb_stdout);
+ printf_filtered (")");
+ print_bit_vector (TYPE_FIELD_PRIVATE_BITS (type),
+ TYPE_NFIELDS (type));
+ puts_filtered ("\n");
+ }
+ if (TYPE_FIELD_PROTECTED_BITS (type) != NULL)
+ {
+ printfi_filtered (spaces, "protected_field_bits (%d bits at *",
+ TYPE_NFIELDS (type));
+ gdb_print_host_address (TYPE_FIELD_PROTECTED_BITS (type), gdb_stdout);
+ printf_filtered (")");
+ print_bit_vector (TYPE_FIELD_PROTECTED_BITS (type),
+ TYPE_NFIELDS (type));
+ puts_filtered ("\n");
+ }
+ }
+ if (TYPE_NFN_FIELDS (type) > 0)
+ {
+ dump_fn_fieldlists (type, spaces);
+ }
+}
+
+static void
+print_bound_type (int bt)
+{
+ switch (bt)
+ {
+ case BOUND_CANNOT_BE_DETERMINED:
+ printf_filtered ("(BOUND_CANNOT_BE_DETERMINED)");
+ break;
+ case BOUND_BY_REF_ON_STACK:
+ printf_filtered ("(BOUND_BY_REF_ON_STACK)");
+ break;
+ case BOUND_BY_VALUE_ON_STACK:
+ printf_filtered ("(BOUND_BY_VALUE_ON_STACK)");
+ break;
+ case BOUND_BY_REF_IN_REG:
+ printf_filtered ("(BOUND_BY_REF_IN_REG)");
+ break;
+ case BOUND_BY_VALUE_IN_REG:
+ printf_filtered ("(BOUND_BY_VALUE_IN_REG)");
+ break;
+ case BOUND_SIMPLE:
+ printf_filtered ("(BOUND_SIMPLE)");
+ break;
+ default:
+ printf_filtered ("(unknown bound type)");
+ break;
+ }
+}
+
+static struct obstack dont_print_type_obstack;
+
+void
+recursive_dump_type (struct type *type, int spaces)
+{
+ int idx;
+
+ if (spaces == 0)
+ obstack_begin (&dont_print_type_obstack, 0);
+
+ if (TYPE_NFIELDS (type) > 0
+ || (TYPE_CPLUS_SPECIFIC (type) && TYPE_NFN_FIELDS (type) > 0))
+ {
+ struct type **first_dont_print
+ = (struct type **) obstack_base (&dont_print_type_obstack);
+
+ int i = (struct type **) obstack_next_free (&dont_print_type_obstack)
+ - first_dont_print;
+
+ while (--i >= 0)
+ {
+ if (type == first_dont_print[i])
+ {
+ printfi_filtered (spaces, "type node ");
+ gdb_print_host_address (type, gdb_stdout);
+ printf_filtered (" <same as already seen type>\n");
+ return;
+ }
+ }
+
+ obstack_ptr_grow (&dont_print_type_obstack, type);
+ }
+
+ printfi_filtered (spaces, "type node ");
+ gdb_print_host_address (type, gdb_stdout);
+ printf_filtered ("\n");
+ printfi_filtered (spaces, "name '%s' (",
+ TYPE_NAME (type) ? TYPE_NAME (type) : "<NULL>");
+ gdb_print_host_address (TYPE_NAME (type), gdb_stdout);
+ printf_filtered (")\n");
+ printfi_filtered (spaces, "tagname '%s' (",
+ TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : "<NULL>");
+ gdb_print_host_address (TYPE_TAG_NAME (type), gdb_stdout);
+ printf_filtered (")\n");
+ printfi_filtered (spaces, "code 0x%x ", TYPE_CODE (type));
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_UNDEF:
+ printf_filtered ("(TYPE_CODE_UNDEF)");
+ break;
+ case TYPE_CODE_PTR:
+ printf_filtered ("(TYPE_CODE_PTR)");
+ break;
+ case TYPE_CODE_ARRAY:
+ printf_filtered ("(TYPE_CODE_ARRAY)");
+ break;
+ case TYPE_CODE_STRUCT:
+ printf_filtered ("(TYPE_CODE_STRUCT)");
+ break;
+ case TYPE_CODE_UNION:
+ printf_filtered ("(TYPE_CODE_UNION)");
+ break;
+ case TYPE_CODE_ENUM:
+ printf_filtered ("(TYPE_CODE_ENUM)");
+ break;
+ case TYPE_CODE_FUNC:
+ printf_filtered ("(TYPE_CODE_FUNC)");
+ break;
+ case TYPE_CODE_INT:
+ printf_filtered ("(TYPE_CODE_INT)");
+ break;
+ case TYPE_CODE_FLT:
+ printf_filtered ("(TYPE_CODE_FLT)");
+ break;
+ case TYPE_CODE_VOID:
+ printf_filtered ("(TYPE_CODE_VOID)");
+ break;
+ case TYPE_CODE_SET:
+ printf_filtered ("(TYPE_CODE_SET)");
+ break;
+ case TYPE_CODE_RANGE:
+ printf_filtered ("(TYPE_CODE_RANGE)");
+ break;
+ case TYPE_CODE_STRING:
+ printf_filtered ("(TYPE_CODE_STRING)");
+ break;
+ case TYPE_CODE_BITSTRING:
+ printf_filtered ("(TYPE_CODE_BITSTRING)");
+ break;
+ case TYPE_CODE_ERROR:
+ printf_filtered ("(TYPE_CODE_ERROR)");
+ break;
+ case TYPE_CODE_MEMBER:
+ printf_filtered ("(TYPE_CODE_MEMBER)");
+ break;
+ case TYPE_CODE_METHOD:
+ printf_filtered ("(TYPE_CODE_METHOD)");
+ break;
+ case TYPE_CODE_REF:
+ printf_filtered ("(TYPE_CODE_REF)");
+ break;
+ case TYPE_CODE_CHAR:
+ printf_filtered ("(TYPE_CODE_CHAR)");
+ break;
+ case TYPE_CODE_BOOL:
+ printf_filtered ("(TYPE_CODE_BOOL)");
+ break;
+ case TYPE_CODE_COMPLEX:
+ printf_filtered ("(TYPE_CODE_COMPLEX)");
+ break;
+ case TYPE_CODE_TYPEDEF:
+ printf_filtered ("(TYPE_CODE_TYPEDEF)");
+ break;
+ case TYPE_CODE_TEMPLATE:
+ printf_filtered ("(TYPE_CODE_TEMPLATE)");
+ break;
+ case TYPE_CODE_TEMPLATE_ARG:
+ printf_filtered ("(TYPE_CODE_TEMPLATE_ARG)");
+ break;
+ default:
+ printf_filtered ("(UNKNOWN TYPE CODE)");
+ break;
+ }
+ puts_filtered ("\n");
+ printfi_filtered (spaces, "length %d\n", TYPE_LENGTH (type));
+ printfi_filtered (spaces, "upper_bound_type 0x%x ",
+ TYPE_ARRAY_UPPER_BOUND_TYPE (type));
+ print_bound_type (TYPE_ARRAY_UPPER_BOUND_TYPE (type));
+ puts_filtered ("\n");
+ printfi_filtered (spaces, "lower_bound_type 0x%x ",
+ TYPE_ARRAY_LOWER_BOUND_TYPE (type));
+ print_bound_type (TYPE_ARRAY_LOWER_BOUND_TYPE (type));
+ puts_filtered ("\n");
+ printfi_filtered (spaces, "objfile ");
+ gdb_print_host_address (TYPE_OBJFILE (type), gdb_stdout);
+ printf_filtered ("\n");
+ printfi_filtered (spaces, "target_type ");
+ gdb_print_host_address (TYPE_TARGET_TYPE (type), gdb_stdout);
+ printf_filtered ("\n");
+ if (TYPE_TARGET_TYPE (type) != NULL)
+ {
+ recursive_dump_type (TYPE_TARGET_TYPE (type), spaces + 2);
+ }
+ printfi_filtered (spaces, "pointer_type ");
+ gdb_print_host_address (TYPE_POINTER_TYPE (type), gdb_stdout);
+ printf_filtered ("\n");
+ printfi_filtered (spaces, "reference_type ");
+ gdb_print_host_address (TYPE_REFERENCE_TYPE (type), gdb_stdout);
+ printf_filtered ("\n");
+ printfi_filtered (spaces, "type_chain ");
+ gdb_print_host_address (TYPE_CHAIN (type), gdb_stdout);
+ printf_filtered ("\n");
+ printfi_filtered (spaces, "instance_flags 0x%x", TYPE_INSTANCE_FLAGS (type));
+ if (TYPE_CONST (type))
+ {
+ puts_filtered (" TYPE_FLAG_CONST");
+ }
+ if (TYPE_VOLATILE (type))
+ {
+ puts_filtered (" TYPE_FLAG_VOLATILE");
+ }
+ if (TYPE_CODE_SPACE (type))
+ {
+ puts_filtered (" TYPE_FLAG_CODE_SPACE");
+ }
+ if (TYPE_DATA_SPACE (type))
+ {
+ puts_filtered (" TYPE_FLAG_DATA_SPACE");
+ }
+ puts_filtered ("\n");
+ printfi_filtered (spaces, "flags 0x%x", TYPE_FLAGS (type));
+ if (TYPE_UNSIGNED (type))
+ {
+ puts_filtered (" TYPE_FLAG_UNSIGNED");
+ }
+ if (TYPE_NOSIGN (type))
+ {
+ puts_filtered (" TYPE_FLAG_NOSIGN");
+ }
+ if (TYPE_STUB (type))
+ {
+ puts_filtered (" TYPE_FLAG_STUB");
+ }
+ if (TYPE_TARGET_STUB (type))
+ {
+ puts_filtered (" TYPE_FLAG_TARGET_STUB");
+ }
+ if (TYPE_STATIC (type))
+ {
+ puts_filtered (" TYPE_FLAG_STATIC");
+ }
+ if (TYPE_PROTOTYPED (type))
+ {
+ puts_filtered (" TYPE_FLAG_PROTOTYPED");
+ }
+ if (TYPE_INCOMPLETE (type))
+ {
+ puts_filtered (" TYPE_FLAG_INCOMPLETE");
+ }
+ if (TYPE_VARARGS (type))
+ {
+ puts_filtered (" TYPE_FLAG_VARARGS");
+ }
+ /* This is used for things like AltiVec registers on ppc. Gcc emits
+ an attribute for the array type, which tells whether or not we
+ have a vector, instead of a regular array. */
+ if (TYPE_VECTOR (type))
+ {
+ puts_filtered (" TYPE_FLAG_VECTOR");
+ }
+ puts_filtered ("\n");
+ printfi_filtered (spaces, "nfields %d ", TYPE_NFIELDS (type));
+ gdb_print_host_address (TYPE_FIELDS (type), gdb_stdout);
+ puts_filtered ("\n");
+ for (idx = 0; idx < TYPE_NFIELDS (type); idx++)
+ {
+ printfi_filtered (spaces + 2,
+ "[%d] bitpos %d bitsize %d type ",
+ idx, TYPE_FIELD_BITPOS (type, idx),
+ TYPE_FIELD_BITSIZE (type, idx));
+ gdb_print_host_address (TYPE_FIELD_TYPE (type, idx), gdb_stdout);
+ printf_filtered (" name '%s' (",
+ TYPE_FIELD_NAME (type, idx) != NULL
+ ? TYPE_FIELD_NAME (type, idx)
+ : "<NULL>");
+ gdb_print_host_address (TYPE_FIELD_NAME (type, idx), gdb_stdout);
+ printf_filtered (")\n");
+ if (TYPE_FIELD_TYPE (type, idx) != NULL)
+ {
+ recursive_dump_type (TYPE_FIELD_TYPE (type, idx), spaces + 4);
+ }
+ }
+ printfi_filtered (spaces, "vptr_basetype ");
+ gdb_print_host_address (TYPE_VPTR_BASETYPE (type), gdb_stdout);
+ puts_filtered ("\n");
+ if (TYPE_VPTR_BASETYPE (type) != NULL)
+ {
+ recursive_dump_type (TYPE_VPTR_BASETYPE (type), spaces + 2);
+ }
+ printfi_filtered (spaces, "vptr_fieldno %d\n", TYPE_VPTR_FIELDNO (type));
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_METHOD:
+ case TYPE_CODE_FUNC:
+ printfi_filtered (spaces, "arg_types ");
+ gdb_print_host_address (TYPE_ARG_TYPES (type), gdb_stdout);
+ puts_filtered ("\n");
+ print_arg_types (TYPE_ARG_TYPES (type), spaces);
+ break;
+
+ case TYPE_CODE_STRUCT:
+ printfi_filtered (spaces, "cplus_stuff ");
+ gdb_print_host_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout);
+ puts_filtered ("\n");
+ print_cplus_stuff (type, spaces);
+ break;
+
+ case TYPE_CODE_FLT:
+ printfi_filtered (spaces, "floatformat ");
+ if (TYPE_FLOATFORMAT (type) == NULL
+ || TYPE_FLOATFORMAT (type)->name == NULL)
+ puts_filtered ("(null)");
+ else
+ puts_filtered (TYPE_FLOATFORMAT (type)->name);
+ puts_filtered ("\n");
+ break;
+
+ default:
+ /* We have to pick one of the union types to be able print and test
+ the value. Pick cplus_struct_type, even though we know it isn't
+ any particular one. */
+ printfi_filtered (spaces, "type_specific ");
+ gdb_print_host_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout);
+ if (TYPE_CPLUS_SPECIFIC (type) != NULL)
+ {
+ printf_filtered (" (unknown data form)");
+ }
+ printf_filtered ("\n");
+ break;
+
+ }
+ if (spaces == 0)
+ obstack_free (&dont_print_type_obstack, NULL);
+}
+
+static void build_gdbtypes (void);
+static void
+build_gdbtypes (void)
+{
+ builtin_type_void =
+ init_type (TYPE_CODE_VOID, 1,
+ 0,
+ "void", (struct objfile *) NULL);
+ builtin_type_char =
+ init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ (TYPE_FLAG_NOSIGN
+ | (TARGET_CHAR_SIGNED ? 0 : TYPE_FLAG_UNSIGNED)),
+ "char", (struct objfile *) NULL);
+ builtin_type_true_char =
+ init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0,
+ "true character", (struct objfile *) NULL);
+ builtin_type_signed_char =
+ init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0,
+ "signed char", (struct objfile *) NULL);
+ builtin_type_unsigned_char =
+ init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "unsigned char", (struct objfile *) NULL);
+ builtin_type_short =
+ init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ 0,
+ "short", (struct objfile *) NULL);
+ builtin_type_unsigned_short =
+ init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "unsigned short", (struct objfile *) NULL);
+ builtin_type_int =
+ init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0,
+ "int", (struct objfile *) NULL);
+ builtin_type_unsigned_int =
+ init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "unsigned int", (struct objfile *) NULL);
+ builtin_type_long =
+ init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ 0,
+ "long", (struct objfile *) NULL);
+ builtin_type_unsigned_long =
+ init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "unsigned long", (struct objfile *) NULL);
+ builtin_type_long_long =
+ init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+ 0,
+ "long long", (struct objfile *) NULL);
+ builtin_type_unsigned_long_long =
+ init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "unsigned long long", (struct objfile *) NULL);
+ builtin_type_float =
+ init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0,
+ "float", (struct objfile *) NULL);
+/* vinschen@redhat.com 2002-02-08:
+ The below lines are disabled since they are doing the wrong
+ thing for non-multiarch targets. They are setting the correct
+ type of floats for the target but while on multiarch targets
+ this is done everytime the architecture changes, it's done on
+ non-multiarch targets only on startup, leaving the wrong values
+ in even if the architecture changes (eg. from big-endian to
+ little-endian). */
+#if 0
+ TYPE_FLOATFORMAT (builtin_type_float) = TARGET_FLOAT_FORMAT;
+#endif
+ builtin_type_double =
+ init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0,
+ "double", (struct objfile *) NULL);
+#if 0
+ TYPE_FLOATFORMAT (builtin_type_double) = TARGET_DOUBLE_FORMAT;
+#endif
+ builtin_type_long_double =
+ init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0,
+ "long double", (struct objfile *) NULL);
+#if 0
+ TYPE_FLOATFORMAT (builtin_type_long_double) = TARGET_LONG_DOUBLE_FORMAT;
+#endif
+ builtin_type_complex =
+ init_type (TYPE_CODE_COMPLEX, 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0,
+ "complex", (struct objfile *) NULL);
+ TYPE_TARGET_TYPE (builtin_type_complex) = builtin_type_float;
+ builtin_type_double_complex =
+ init_type (TYPE_CODE_COMPLEX, 2 * TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0,
+ "double complex", (struct objfile *) NULL);
+ TYPE_TARGET_TYPE (builtin_type_double_complex) = builtin_type_double;
+ builtin_type_string =
+ init_type (TYPE_CODE_STRING, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0,
+ "string", (struct objfile *) NULL);
+ builtin_type_int8 =
+ init_type (TYPE_CODE_INT, 8 / 8,
+ 0,
+ "int8_t", (struct objfile *) NULL);
+ builtin_type_uint8 =
+ init_type (TYPE_CODE_INT, 8 / 8,
+ TYPE_FLAG_UNSIGNED,
+ "uint8_t", (struct objfile *) NULL);
+ builtin_type_int16 =
+ init_type (TYPE_CODE_INT, 16 / 8,
+ 0,
+ "int16_t", (struct objfile *) NULL);
+ builtin_type_uint16 =
+ init_type (TYPE_CODE_INT, 16 / 8,
+ TYPE_FLAG_UNSIGNED,
+ "uint16_t", (struct objfile *) NULL);
+ builtin_type_int32 =
+ init_type (TYPE_CODE_INT, 32 / 8,
+ 0,
+ "int32_t", (struct objfile *) NULL);
+ builtin_type_uint32 =
+ init_type (TYPE_CODE_INT, 32 / 8,
+ TYPE_FLAG_UNSIGNED,
+ "uint32_t", (struct objfile *) NULL);
+ builtin_type_int64 =
+ init_type (TYPE_CODE_INT, 64 / 8,
+ 0,
+ "int64_t", (struct objfile *) NULL);
+ builtin_type_uint64 =
+ init_type (TYPE_CODE_INT, 64 / 8,
+ TYPE_FLAG_UNSIGNED,
+ "uint64_t", (struct objfile *) NULL);
+ builtin_type_int128 =
+ init_type (TYPE_CODE_INT, 128 / 8,
+ 0,
+ "int128_t", (struct objfile *) NULL);
+ builtin_type_uint128 =
+ init_type (TYPE_CODE_INT, 128 / 8,
+ TYPE_FLAG_UNSIGNED,
+ "uint128_t", (struct objfile *) NULL);
+ builtin_type_bool =
+ init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0,
+ "bool", (struct objfile *) NULL);
+
+ /* Add user knob for controlling resolution of opaque types */
+ add_show_from_set
+ (add_set_cmd ("opaque-type-resolution", class_support, var_boolean, (char *) &opaque_type_resolution,
+ "Set resolution of opaque struct/class/union types (if set before loading symbols).",
+ &setlist),
+ &showlist);
+ opaque_type_resolution = 1;
+
+ /* Build SIMD types. */
+ builtin_type_v4sf
+ = init_simd_type ("__builtin_v4sf", builtin_type_float, "f", 4);
+ builtin_type_v4si
+ = init_simd_type ("__builtin_v4si", builtin_type_int32, "f", 4);
+ builtin_type_v16qi
+ = init_simd_type ("__builtin_v16qi", builtin_type_int8, "f", 16);
+ builtin_type_v8qi
+ = init_simd_type ("__builtin_v8qi", builtin_type_int8, "f", 8);
+ builtin_type_v8hi
+ = init_simd_type ("__builtin_v8hi", builtin_type_int16, "f", 8);
+ builtin_type_v4hi
+ = init_simd_type ("__builtin_v4hi", builtin_type_int16, "f", 4);
+ builtin_type_v2si
+ = init_simd_type ("__builtin_v2si", builtin_type_int32, "f", 2);
+
+ /* 128 bit vectors. */
+ builtin_type_v2_double = init_vector_type (builtin_type_double, 2);
+ builtin_type_v4_float = init_vector_type (builtin_type_float, 4);
+ builtin_type_v2_int64 = init_vector_type (builtin_type_int64, 2);
+ builtin_type_v4_int32 = init_vector_type (builtin_type_int32, 4);
+ builtin_type_v8_int16 = init_vector_type (builtin_type_int16, 8);
+ builtin_type_v16_int8 = init_vector_type (builtin_type_int8, 16);
+ /* 64 bit vectors. */
+ builtin_type_v2_float = init_vector_type (builtin_type_float, 2);
+ builtin_type_v2_int32 = init_vector_type (builtin_type_int32, 2);
+ builtin_type_v4_int16 = init_vector_type (builtin_type_int16, 4);
+ builtin_type_v8_int8 = init_vector_type (builtin_type_int8, 8);
+
+ /* Vector types. */
+ builtin_type_vec128 = build_builtin_type_vec128 ();
+ builtin_type_vec128i = build_builtin_type_vec128i ();
+
+ /* Pointer/Address types. */
+
+ /* NOTE: on some targets, addresses and pointers are not necessarily
+ the same --- for example, on the D10V, pointers are 16 bits long,
+ but addresses are 32 bits long. See doc/gdbint.texinfo,
+ ``Pointers Are Not Always Addresses''.
+
+ The upshot is:
+ - gdb's `struct type' always describes the target's
+ representation.
+ - gdb's `struct value' objects should always hold values in
+ target form.
+ - gdb's CORE_ADDR values are addresses in the unified virtual
+ address space that the assembler and linker work with. Thus,
+ since target_read_memory takes a CORE_ADDR as an argument, it
+ can access any memory on the target, even if the processor has
+ separate code and data address spaces.
+
+ So, for example:
+ - If v is a value holding a D10V code pointer, its contents are
+ in target form: a big-endian address left-shifted two bits.
+ - If p is a D10V pointer type, TYPE_LENGTH (p) == 2, just as
+ sizeof (void *) == 2 on the target.
+
+ In this context, builtin_type_CORE_ADDR is a bit odd: it's a
+ target type for a value the target will never see. It's only
+ used to hold the values of (typeless) linker symbols, which are
+ indeed in the unified virtual address space. */
+ builtin_type_void_data_ptr = make_pointer_type (builtin_type_void, NULL);
+ builtin_type_void_func_ptr
+ = lookup_pointer_type (lookup_function_type (builtin_type_void));
+ builtin_type_CORE_ADDR =
+ init_type (TYPE_CODE_INT, TARGET_ADDR_BIT / 8,
+ TYPE_FLAG_UNSIGNED,
+ "__CORE_ADDR", (struct objfile *) NULL);
+ builtin_type_bfd_vma =
+ init_type (TYPE_CODE_INT, TARGET_BFD_VMA_BIT / 8,
+ TYPE_FLAG_UNSIGNED,
+ "__bfd_vma", (struct objfile *) NULL);
+}
+
+
+extern void _initialize_gdbtypes (void);
+void
+_initialize_gdbtypes (void)
+{
+ struct cmd_list_element *c;
+ build_gdbtypes ();
+
+ /* FIXME - For the moment, handle types by swapping them in and out.
+ Should be using the per-architecture data-pointer and a large
+ struct. */
+ register_gdbarch_swap (&builtin_type_void, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_char, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_short, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_int, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_long, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_long_long, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_signed_char, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_unsigned_char, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_unsigned_short, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_unsigned_int, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_unsigned_long, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_unsigned_long_long, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_float, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_double, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_long_double, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_complex, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_double_complex, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_string, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_int8, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_uint8, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_int16, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_uint16, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_int32, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_uint32, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_int64, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_uint64, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_int128, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_uint128, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v4sf, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v4si, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v16qi, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v8qi, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v8hi, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v4hi, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v2si, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v2_double, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v4_float, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v2_int64, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v4_int32, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v8_int16, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v16_int8, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v2_float, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v2_int32, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v8_int8, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v4_int16, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_vec128, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_vec128i, sizeof (struct type *), NULL);
+ REGISTER_GDBARCH_SWAP (builtin_type_void_data_ptr);
+ REGISTER_GDBARCH_SWAP (builtin_type_void_func_ptr);
+ REGISTER_GDBARCH_SWAP (builtin_type_CORE_ADDR);
+ REGISTER_GDBARCH_SWAP (builtin_type_bfd_vma);
+ register_gdbarch_swap (NULL, 0, build_gdbtypes);
+
+ /* Note: These types do not need to be swapped - they are target
+ neutral. */
+ builtin_type_ieee_single_big =
+ init_type (TYPE_CODE_FLT, floatformat_ieee_single_big.totalsize / 8,
+ 0, "builtin_type_ieee_single_big", NULL);
+ TYPE_FLOATFORMAT (builtin_type_ieee_single_big) = &floatformat_ieee_single_big;
+ builtin_type_ieee_single_little =
+ init_type (TYPE_CODE_FLT, floatformat_ieee_single_little.totalsize / 8,
+ 0, "builtin_type_ieee_single_little", NULL);
+ TYPE_FLOATFORMAT (builtin_type_ieee_single_little) = &floatformat_ieee_single_little;
+ builtin_type_ieee_double_big =
+ init_type (TYPE_CODE_FLT, floatformat_ieee_double_big.totalsize / 8,
+ 0, "builtin_type_ieee_double_big", NULL);
+ TYPE_FLOATFORMAT (builtin_type_ieee_double_big) = &floatformat_ieee_double_big;
+ builtin_type_ieee_double_little =
+ init_type (TYPE_CODE_FLT, floatformat_ieee_double_little.totalsize / 8,
+ 0, "builtin_type_ieee_double_little", NULL);
+ TYPE_FLOATFORMAT (builtin_type_ieee_double_little) = &floatformat_ieee_double_little;
+ builtin_type_ieee_double_littlebyte_bigword =
+ init_type (TYPE_CODE_FLT, floatformat_ieee_double_littlebyte_bigword.totalsize / 8,
+ 0, "builtin_type_ieee_double_littlebyte_bigword", NULL);
+ TYPE_FLOATFORMAT (builtin_type_ieee_double_littlebyte_bigword) = &floatformat_ieee_double_littlebyte_bigword;
+ builtin_type_i387_ext =
+ init_type (TYPE_CODE_FLT, floatformat_i387_ext.totalsize / 8,
+ 0, "builtin_type_i387_ext", NULL);
+ TYPE_FLOATFORMAT (builtin_type_i387_ext) = &floatformat_i387_ext;
+ builtin_type_m68881_ext =
+ init_type (TYPE_CODE_FLT, floatformat_m68881_ext.totalsize / 8,
+ 0, "builtin_type_m68881_ext", NULL);
+ TYPE_FLOATFORMAT (builtin_type_m68881_ext) = &floatformat_m68881_ext;
+ builtin_type_i960_ext =
+ init_type (TYPE_CODE_FLT, floatformat_i960_ext.totalsize / 8,
+ 0, "builtin_type_i960_ext", NULL);
+ TYPE_FLOATFORMAT (builtin_type_i960_ext) = &floatformat_i960_ext;
+ builtin_type_m88110_ext =
+ init_type (TYPE_CODE_FLT, floatformat_m88110_ext.totalsize / 8,
+ 0, "builtin_type_m88110_ext", NULL);
+ TYPE_FLOATFORMAT (builtin_type_m88110_ext) = &floatformat_m88110_ext;
+ builtin_type_m88110_harris_ext =
+ init_type (TYPE_CODE_FLT, floatformat_m88110_harris_ext.totalsize / 8,
+ 0, "builtin_type_m88110_harris_ext", NULL);
+ TYPE_FLOATFORMAT (builtin_type_m88110_harris_ext) = &floatformat_m88110_harris_ext;
+ builtin_type_arm_ext_big =
+ init_type (TYPE_CODE_FLT, floatformat_arm_ext_big.totalsize / 8,
+ 0, "builtin_type_arm_ext_big", NULL);
+ TYPE_FLOATFORMAT (builtin_type_arm_ext_big) = &floatformat_arm_ext_big;
+ builtin_type_arm_ext_littlebyte_bigword =
+ init_type (TYPE_CODE_FLT, floatformat_arm_ext_littlebyte_bigword.totalsize / 8,
+ 0, "builtin_type_arm_ext_littlebyte_bigword", NULL);
+ TYPE_FLOATFORMAT (builtin_type_arm_ext_littlebyte_bigword) = &floatformat_arm_ext_littlebyte_bigword;
+ builtin_type_ia64_spill_big =
+ init_type (TYPE_CODE_FLT, floatformat_ia64_spill_big.totalsize / 8,
+ 0, "builtin_type_ia64_spill_big", NULL);
+ TYPE_FLOATFORMAT (builtin_type_ia64_spill_big) = &floatformat_ia64_spill_big;
+ builtin_type_ia64_spill_little =
+ init_type (TYPE_CODE_FLT, floatformat_ia64_spill_little.totalsize / 8,
+ 0, "builtin_type_ia64_spill_little", NULL);
+ TYPE_FLOATFORMAT (builtin_type_ia64_spill_little) = &floatformat_ia64_spill_little;
+ builtin_type_ia64_quad_big =
+ init_type (TYPE_CODE_FLT, floatformat_ia64_quad_big.totalsize / 8,
+ 0, "builtin_type_ia64_quad_big", NULL);
+ TYPE_FLOATFORMAT (builtin_type_ia64_quad_big) = &floatformat_ia64_quad_big;
+ builtin_type_ia64_quad_little =
+ init_type (TYPE_CODE_FLT, floatformat_ia64_quad_little.totalsize / 8,
+ 0, "builtin_type_ia64_quad_little", NULL);
+ TYPE_FLOATFORMAT (builtin_type_ia64_quad_little) = &floatformat_ia64_quad_little;
+
+ add_show_from_set (
+ add_set_cmd ("overload", no_class, var_zinteger, (char *) &overload_debug,
+ "Set debugging of C++ overloading.\n\
+ When enabled, ranking of the functions\n\
+ is displayed.", &setdebuglist),
+ &showdebuglist);
+}
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
new file mode 100644
index 00000000000..9233bac2bb7
--- /dev/null
+++ b/gdb/gdbtypes.h
@@ -0,0 +1,1257 @@
+/* Internal type definitions for GDB.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support, using pieces from other GDB modules.
+
+ 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. */
+
+#if !defined (GDBTYPES_H)
+#define GDBTYPES_H 1
+
+/* Forward declarations for prototypes. */
+struct block;
+
+/* Codes for `fundamental types'. This is a monstrosity based on the
+ bogus notion that there are certain compiler-independent
+ `fundamental types'. None of these is well-defined (how big is
+ FT_SHORT? Does it depend on the language? How does the
+ language-specific code know which type to correlate to FT_SHORT?) */
+
+#define FT_VOID 0
+#define FT_BOOLEAN 1
+#define FT_CHAR 2 /* we use this for not-unsigned C/C++ chars */
+#define FT_SIGNED_CHAR 3 /* we use this for C++ signed chars */
+#define FT_UNSIGNED_CHAR 4 /* we use this for C/C++ unsigned chars */
+#define FT_SHORT 5
+#define FT_SIGNED_SHORT 6
+#define FT_UNSIGNED_SHORT 7
+#define FT_INTEGER 8
+#define FT_SIGNED_INTEGER 9
+#define FT_UNSIGNED_INTEGER 10
+#define FT_LONG 11
+#define FT_SIGNED_LONG 12
+#define FT_UNSIGNED_LONG 13
+#define FT_LONG_LONG 14
+#define FT_SIGNED_LONG_LONG 15
+#define FT_UNSIGNED_LONG_LONG 16
+#define FT_FLOAT 17
+#define FT_DBL_PREC_FLOAT 18
+#define FT_EXT_PREC_FLOAT 19
+#define FT_COMPLEX 20
+#define FT_DBL_PREC_COMPLEX 21
+#define FT_EXT_PREC_COMPLEX 22
+#define FT_STRING 23
+#define FT_FIXED_DECIMAL 24
+#define FT_FLOAT_DECIMAL 25
+#define FT_BYTE 26
+#define FT_UNSIGNED_BYTE 27
+#define FT_TEMPLATE_ARG 28
+
+#define FT_NUM_MEMBERS 29 /* Highest FT_* above, plus one. */
+
+/* Some macros for char-based bitfields. */
+
+#define B_SET(a,x) ((a)[(x)>>3] |= (1 << ((x)&7)))
+#define B_CLR(a,x) ((a)[(x)>>3] &= ~(1 << ((x)&7)))
+#define B_TST(a,x) ((a)[(x)>>3] & (1 << ((x)&7)))
+#define B_TYPE unsigned char
+#define B_BYTES(x) ( 1 + ((x)>>3) )
+#define B_CLRALL(a,x) memset ((a), 0, B_BYTES(x))
+
+/* Different kinds of data types are distinguished by the `code' field. */
+
+enum type_code
+ {
+ TYPE_CODE_UNDEF, /* Not used; catches errors */
+ TYPE_CODE_PTR, /* Pointer type */
+ TYPE_CODE_ARRAY, /* Array type with lower & upper bounds. */
+ TYPE_CODE_STRUCT, /* C struct or Pascal record */
+ TYPE_CODE_UNION, /* C union or Pascal variant part */
+ TYPE_CODE_ENUM, /* Enumeration type */
+ TYPE_CODE_FUNC, /* Function type */
+ TYPE_CODE_INT, /* Integer type */
+
+ /* Floating type. This is *NOT* a complex type. Beware, there are parts
+ of GDB which bogusly assume that TYPE_CODE_FLT can mean complex. */
+ TYPE_CODE_FLT,
+
+ /* Void type. The length field specifies the length (probably always
+ one) which is used in pointer arithmetic involving pointers to
+ this type, but actually dereferencing such a pointer is invalid;
+ a void type has no length and no actual representation in memory
+ or registers. A pointer to a void type is a generic pointer. */
+ TYPE_CODE_VOID,
+
+ TYPE_CODE_SET, /* Pascal sets */
+ TYPE_CODE_RANGE, /* Range (integers within spec'd bounds) */
+
+ /* A string type which is like an array of character but prints
+ differently (at least for CHILL). It does not contain a length
+ field as Pascal strings (for many Pascals, anyway) do; if we want
+ to deal with such strings, we should use a new type code. */
+ TYPE_CODE_STRING,
+
+ /* String of bits; like TYPE_CODE_SET but prints differently (at least
+ for CHILL). */
+ TYPE_CODE_BITSTRING,
+
+ /* Unknown type. The length field is valid if we were able to
+ deduce that much about the type, or 0 if we don't even know that. */
+ TYPE_CODE_ERROR,
+
+ /* C++ */
+ TYPE_CODE_MEMBER, /* Member type */
+ TYPE_CODE_METHOD, /* Method type */
+ TYPE_CODE_REF, /* C++ Reference types */
+
+ TYPE_CODE_CHAR, /* *real* character type */
+
+ /* Boolean type. 0 is false, 1 is true, and other values are non-boolean
+ (e.g. FORTRAN "logical" used as unsigned int). */
+ TYPE_CODE_BOOL,
+
+ /* Fortran */
+ TYPE_CODE_COMPLEX, /* Complex float */
+
+ TYPE_CODE_TYPEDEF,
+ TYPE_CODE_TEMPLATE, /* C++ template */
+ TYPE_CODE_TEMPLATE_ARG /* C++ template arg */
+
+ };
+
+/* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an
+ alias for TYPE_CODE_STRUCT. This is for DWARF, which has a distinct
+ "class" attribute. Perhaps we should actually have a separate TYPE_CODE
+ so that we can print "class" or "struct" depending on what the debug
+ info said. It's not clear we should bother. */
+
+#define TYPE_CODE_CLASS TYPE_CODE_STRUCT
+
+/* Some bits for the type's flags word, and macros to test them. */
+
+/* Unsigned integer type. If this is not set for a TYPE_CODE_INT, the
+ type is signed (unless TYPE_FLAG_NOSIGN (below) is set). */
+
+#define TYPE_FLAG_UNSIGNED (1 << 0)
+#define TYPE_UNSIGNED(t) (TYPE_FLAGS (t) & TYPE_FLAG_UNSIGNED)
+
+/* No sign for this type. In C++, "char", "signed char", and "unsigned
+ char" are distinct types; so we need an extra flag to indicate the
+ absence of a sign! */
+
+#define TYPE_FLAG_NOSIGN (1 << 1)
+#define TYPE_NOSIGN(t) (TYPE_FLAGS (t) & TYPE_FLAG_NOSIGN)
+
+/* This appears in a type's flags word if it is a stub type (e.g., if
+ someone referenced a type that wasn't defined in a source file
+ via (struct sir_not_appearing_in_this_film *)). */
+
+#define TYPE_FLAG_STUB (1 << 2)
+#define TYPE_STUB(t) (TYPE_FLAGS (t) & TYPE_FLAG_STUB)
+
+/* The target type of this type is a stub type, and this type needs to
+ be updated if it gets un-stubbed in check_typedef.
+ Used for arrays and ranges, in which TYPE_LENGTH of the array/range
+ gets set based on the TYPE_LENGTH of the target type.
+ Also, set for TYPE_CODE_TYPEDEF. */
+
+#define TYPE_FLAG_TARGET_STUB (1 << 3)
+#define TYPE_TARGET_STUB(t) (TYPE_FLAGS (t) & TYPE_FLAG_TARGET_STUB)
+
+/* Static type. If this is set, the corresponding type had
+ * a static modifier.
+ * Note: This may be unnecessary, since static data members
+ * are indicated by other means (bitpos == -1)
+ */
+
+#define TYPE_FLAG_STATIC (1 << 4)
+#define TYPE_STATIC(t) (TYPE_FLAGS (t) & TYPE_FLAG_STATIC)
+
+/* Constant type. If this is set, the corresponding type has a
+ * const modifier.
+ */
+
+#define TYPE_FLAG_CONST (1 << 5)
+#define TYPE_CONST(t) (TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_CONST)
+
+/* Volatile type. If this is set, the corresponding type has a
+ * volatile modifier.
+ */
+
+#define TYPE_FLAG_VOLATILE (1 << 6)
+#define TYPE_VOLATILE(t) (TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_VOLATILE)
+
+
+/* This is a function type which appears to have a prototype. We need this
+ for function calls in order to tell us if it's necessary to coerce the args,
+ or to just do the standard conversions. This is used with a short field. */
+
+#define TYPE_FLAG_PROTOTYPED (1 << 7)
+#define TYPE_PROTOTYPED(t) (TYPE_FLAGS (t) & TYPE_FLAG_PROTOTYPED)
+
+/* This flag is used to indicate that processing for this type
+ is incomplete.
+
+ (Mostly intended for HP platforms, where class methods, for
+ instance, can be encountered before their classes in the debug
+ info; the incomplete type has to be marked so that the class and
+ the method can be assigned correct types.) */
+
+#define TYPE_FLAG_INCOMPLETE (1 << 8)
+#define TYPE_INCOMPLETE(t) (TYPE_FLAGS (t) & TYPE_FLAG_INCOMPLETE)
+
+/* Instruction-space delimited type. This is for Harvard architectures
+ which have separate instruction and data address spaces (and perhaps
+ others).
+
+ GDB usually defines a flat address space that is a superset of the
+ architecture's two (or more) address spaces, but this is an extension
+ of the architecture's model.
+
+ If TYPE_FLAG_INST is set, an object of the corresponding type
+ resides in instruction memory, even if its address (in the extended
+ flat address space) does not reflect this.
+
+ Similarly, if TYPE_FLAG_DATA is set, then an object of the
+ corresponding type resides in the data memory space, even if
+ this is not indicated by its (flat address space) address.
+
+ If neither flag is set, the default space for functions / methods
+ is instruction space, and for data objects is data memory. */
+
+#define TYPE_FLAG_CODE_SPACE (1 << 9)
+#define TYPE_CODE_SPACE(t) (TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_CODE_SPACE)
+
+#define TYPE_FLAG_DATA_SPACE (1 << 10)
+#define TYPE_DATA_SPACE(t) (TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_DATA_SPACE)
+
+/* FIXME: Kludge to mark a varargs function type for C++ member
+ function argument processing. Currently only used in dwarf2read.c,
+ but put it here so we won't accidentally overload the bit with
+ another flag. */
+
+#define TYPE_FLAG_VARARGS (1 << 11)
+#define TYPE_VARARGS(t) (TYPE_FLAGS (t) & TYPE_FLAG_VARARGS)
+
+/* Identify a vector type. Gcc is handling this by adding an extra
+ attribute to the array type. We slurp that in as a new flag of a
+ type. This is used only in dwarf2read.c. */
+#define TYPE_FLAG_VECTOR (1 << 12)
+#define TYPE_VECTOR(t) (TYPE_FLAGS (t) & TYPE_FLAG_VECTOR)
+
+struct main_type
+{
+ /* Code for kind of type */
+
+ enum type_code code;
+
+ /* Name of this type, or NULL if none.
+
+ This is used for printing only, except by poorly designed C++ code.
+ For looking up a name, look for a symbol in the VAR_NAMESPACE. */
+
+ char *name;
+
+ /* Tag name for this type, or NULL if none. This means that the
+ name of the type consists of a keyword followed by the tag name.
+ Which keyword is determined by the type code ("struct" for
+ TYPE_CODE_STRUCT, etc.). As far as I know C/C++ are the only languages
+ with this feature.
+
+ This is used for printing only, except by poorly designed C++ code.
+ For looking up a name, look for a symbol in the STRUCT_NAMESPACE.
+ One more legitimate use is that if TYPE_FLAG_STUB is set, this is
+ the name to use to look for definitions in other files. */
+
+ char *tag_name;
+
+ /* Length of storage for a value of this type. This is what
+ sizeof(type) would return; use it for address arithmetic,
+ memory reads and writes, etc. This size includes padding. For
+ example, an i386 extended-precision floating point value really
+ only occupies ten bytes, but most ABI's declare its size to be
+ 12 bytes, to preserve alignment. A `struct type' representing
+ such a floating-point type would have a `length' value of 12,
+ even though the last two bytes are unused.
+
+ There's a bit of a host/target mess here, if you're concerned
+ about machines whose bytes aren't eight bits long, or who don't
+ have byte-addressed memory. Various places pass this to memcpy
+ and such, meaning it must be in units of host bytes. Various
+ other places expect they can calculate addresses by adding it
+ and such, meaning it must be in units of target bytes. For
+ some DSP targets, in which HOST_CHAR_BIT will (presumably) be 8
+ and TARGET_CHAR_BIT will be (say) 32, this is a problem.
+
+ One fix would be to make this field in bits (requiring that it
+ always be a multiple of HOST_CHAR_BIT and TARGET_CHAR_BIT) ---
+ the other choice would be to make it consistently in units of
+ HOST_CHAR_BIT. However, this would still fail to address
+ machines based on a ternary or decimal representation. */
+
+ unsigned length;
+
+ /* FIXME, these should probably be restricted to a Fortran-specific
+ field in some fashion. */
+#define BOUND_CANNOT_BE_DETERMINED 5
+#define BOUND_BY_REF_ON_STACK 4
+#define BOUND_BY_VALUE_ON_STACK 3
+#define BOUND_BY_REF_IN_REG 2
+#define BOUND_BY_VALUE_IN_REG 1
+#define BOUND_SIMPLE 0
+ int upper_bound_type;
+ int lower_bound_type;
+
+ /* Every type is now associated with a particular objfile, and the
+ type is allocated on the type_obstack for that objfile. One problem
+ however, is that there are times when gdb allocates new types while
+ it is not in the process of reading symbols from a particular objfile.
+ Fortunately, these happen when the type being created is a derived
+ type of an existing type, such as in lookup_pointer_type(). So
+ we can just allocate the new type using the same objfile as the
+ existing type, but to do this we need a backpointer to the objfile
+ from the existing type. Yes this is somewhat ugly, but without
+ major overhaul of the internal type system, it can't be avoided
+ for now. */
+
+ struct objfile *objfile;
+
+ /* For a pointer type, describes the type of object pointed to.
+ For an array type, describes the type of the elements.
+ For a function or method type, describes the type of the return value.
+ For a range type, describes the type of the full range.
+ For a complex type, describes the type of each coordinate.
+ Unused otherwise. */
+
+ struct type *target_type;
+
+ /* Flags about this type. */
+
+ int flags;
+
+ /* Number of fields described for this type */
+
+ short nfields;
+
+ /* For structure and union types, a description of each field.
+ For set and pascal array types, there is one "field",
+ whose type is the domain type of the set or array.
+ For range types, there are two "fields",
+ the minimum and maximum values (both inclusive).
+ For enum types, each possible value is described by one "field".
+ For a function type, a "field" for each parameter type.
+ For C++ classes, there is one field for each base class (if it is
+ a derived class) plus one field for each class data member. Member
+ functions are recorded elsewhere.
+
+ Using a pointer to a separate array of fields
+ allows all types to have the same size, which is useful
+ because we can allocate the space for a type before
+ we know what to put in it. */
+
+ struct field
+ {
+ union field_location
+ {
+ /* Position of this field, counting in bits from start of
+ containing structure.
+ For BITS_BIG_ENDIAN=1 targets, it is the bit offset to the MSB.
+ For BITS_BIG_ENDIAN=0 targets, it is the bit offset to the LSB.
+ For a range bound or enum value, this is the value itself. */
+
+ int bitpos;
+
+ /* For a static field, if TYPE_FIELD_STATIC_HAS_ADDR then physaddr
+ is the location (in the target) of the static field.
+ Otherwise, physname is the mangled label of the static field. */
+
+ CORE_ADDR physaddr;
+ char *physname;
+
+ /* For a function type, this is 1 if the argument is marked
+ artificial. Artificial arguments should not be shown to the
+ user. */
+ int artificial;
+ }
+ loc;
+
+ /* Size of this field, in bits, or zero if not packed.
+ For an unpacked field, the field's type's length
+ says how many bytes the field occupies.
+ A value of -1 or -2 indicates a static field; -1 means the location
+ is specified by the label loc.physname; -2 means that loc.physaddr
+ specifies the actual address. */
+
+ int bitsize;
+
+ /* In a struct or union type, type of this field.
+ In a function type, type of this argument.
+ In an array type, the domain-type of the array. */
+
+ struct type *type;
+
+ /* Name of field, value or argument.
+ NULL for range bounds and array domains. */
+
+ char *name;
+
+ } *fields;
+
+ /* For types with virtual functions (TYPE_CODE_STRUCT), VPTR_BASETYPE
+ is the base class which defined the virtual function table pointer.
+
+ For types that are pointer to member types (TYPE_CODE_MEMBER),
+ VPTR_BASETYPE is the type that this pointer is a member of.
+
+ For method types (TYPE_CODE_METHOD), VPTR_BASETYPE is the aggregate
+ type that contains the method.
+
+ Unused otherwise. */
+
+ struct type *vptr_basetype;
+
+ /* Field number of the virtual function table pointer in
+ VPTR_BASETYPE. If -1, we were unable to find the virtual
+ function table pointer in initial symbol reading, and
+ fill_in_vptr_fieldno should be called to find it if possible.
+
+ Unused if this type does not have virtual functions. */
+
+ int vptr_fieldno;
+
+ /* Slot to point to additional language-specific fields of this type. */
+
+ union type_specific
+ {
+ /* ARG_TYPES is for TYPE_CODE_METHOD.
+ Contains the type of each argument, ending with a void type
+ after the last argument for normal member functions or a NULL
+ pointer after the last argument for functions with variable
+ arguments. */
+
+ struct type **arg_types;
+
+ /* CPLUS_STUFF is for TYPE_CODE_STRUCT. It is initialized to point to
+ cplus_struct_default, a default static instance of a struct
+ cplus_struct_type. */
+
+ struct cplus_struct_type *cplus_stuff;
+
+ /* FLOATFORMAT is for TYPE_CODE_FLT. It is a pointer to the
+ floatformat object that describes the floating-point value
+ that resides within the type. */
+
+ const struct floatformat *floatformat;
+ } type_specific;
+};
+
+/* A ``struct type'' describes a particular instance of a type, with
+ some particular qualification. */
+struct type
+{
+ /* Type that is a pointer to this type.
+ NULL if no such pointer-to type is known yet.
+ The debugger may add the address of such a type
+ if it has to construct one later. */
+
+ struct type *pointer_type;
+
+ /* C++: also need a reference type. */
+
+ struct type *reference_type;
+
+ /* Variant chain. This points to a type that differs from this one only
+ in qualifiers. Currently, the possible qualifiers are const, volatile,
+ code-space, and data-space. The variants are linked in a circular
+ ring and share MAIN_TYPE. */
+ struct type *chain;
+
+ /* Flags specific to this instance of the type, indicating where
+ on the ring we are. */
+ int instance_flags;
+
+ /* Core type, shared by a group of qualified types. */
+ struct main_type *main_type;
+};
+
+#define NULL_TYPE ((struct type *) 0)
+
+/* C++ language-specific information for TYPE_CODE_STRUCT and TYPE_CODE_UNION
+ nodes. */
+
+struct cplus_struct_type
+ {
+ /* Number of base classes this type derives from. The baseclasses are
+ stored in the first N_BASECLASSES fields (i.e. the `fields' field of
+ the struct type). I think only the `type' field of such a field has
+ any meaning. */
+
+ short n_baseclasses;
+
+ /* Number of methods with unique names. All overloaded methods with
+ the same name count only once. */
+
+ short nfn_fields;
+
+ /* Number of methods described for this type, not including the
+ methods that it derives from. */
+
+ short nfn_fields_total;
+
+ /* The "declared_type" field contains a code saying how the
+ user really declared this type, e.g., "class s", "union s",
+ "struct s".
+ The 3 above things come out from the C++ compiler looking like classes,
+ but we keep track of the real declaration so we can give
+ the correct information on "ptype". (Note: TEMPLATE may not
+ belong in this list...) */
+
+#define DECLARED_TYPE_CLASS 0
+#define DECLARED_TYPE_UNION 1
+#define DECLARED_TYPE_STRUCT 2
+#define DECLARED_TYPE_TEMPLATE 3
+ short declared_type; /* One of the above codes */
+
+ /* For derived classes, the number of base classes is given by n_baseclasses
+ and virtual_field_bits is a bit vector containing one bit per base class.
+ If the base class is virtual, the corresponding bit will be set.
+ I.E, given:
+
+ class A{};
+ class B{};
+ class C : public B, public virtual A {};
+
+ B is a baseclass of C; A is a virtual baseclass for C.
+ This is a C++ 2.0 language feature. */
+
+ B_TYPE *virtual_field_bits;
+
+ /* For classes with private fields, the number of fields is given by
+ nfields and private_field_bits is a bit vector containing one bit
+ per field.
+ If the field is private, the corresponding bit will be set. */
+
+ B_TYPE *private_field_bits;
+
+ /* For classes with protected fields, the number of fields is given by
+ nfields and protected_field_bits is a bit vector containing one bit
+ per field.
+ If the field is private, the corresponding bit will be set. */
+
+ B_TYPE *protected_field_bits;
+
+ /* for classes with fields to be ignored, either this is optimized out
+ or this field has length 0 */
+
+ B_TYPE *ignore_field_bits;
+
+ /* For classes, structures, and unions, a description of each field,
+ which consists of an overloaded name, followed by the types of
+ arguments that the method expects, and then the name after it
+ has been renamed to make it distinct.
+
+ fn_fieldlists points to an array of nfn_fields of these. */
+
+ struct fn_fieldlist
+ {
+
+ /* The overloaded name. */
+
+ char *name;
+
+ /* The number of methods with this name. */
+
+ int length;
+
+ /* The list of methods. */
+
+ struct fn_field
+ {
+
+ /* If is_stub is clear, this is the mangled name which we can
+ look up to find the address of the method (FIXME: it would
+ be cleaner to have a pointer to the struct symbol here
+ instead). */
+
+ /* If is_stub is set, this is the portion of the mangled
+ name which specifies the arguments. For example, "ii",
+ if there are two int arguments, or "" if there are no
+ arguments. See gdb_mangle_name for the conversion from this
+ format to the one used if is_stub is clear. */
+
+ char *physname;
+
+ /* The function type for the method.
+ (This comment used to say "The return value of the method",
+ but that's wrong. The function type
+ is expected here, i.e. something with TYPE_CODE_FUNC,
+ and *not* the return-value type). */
+
+ struct type *type;
+
+ /* For virtual functions.
+ First baseclass that defines this virtual function. */
+
+ struct type *fcontext;
+
+ /* Attributes. */
+
+ unsigned int is_const:1;
+ unsigned int is_volatile:1;
+ unsigned int is_private:1;
+ unsigned int is_protected:1;
+ unsigned int is_public:1;
+ unsigned int is_abstract:1;
+ unsigned int is_static:1;
+ unsigned int is_final:1;
+ unsigned int is_synchronized:1;
+ unsigned int is_native:1;
+ unsigned int is_artificial:1;
+
+ /* A stub method only has some fields valid (but they are enough
+ to reconstruct the rest of the fields). */
+ unsigned int is_stub:1;
+
+ /* C++ method that is inlined */
+ unsigned int is_inlined:1;
+
+ /* Unused. */
+ unsigned int dummy:3;
+
+ /* Index into that baseclass's virtual function table,
+ minus 2; else if static: VOFFSET_STATIC; else: 0. */
+
+ unsigned int voffset:16;
+
+#define VOFFSET_STATIC 1
+
+ }
+ *fn_fields;
+
+ }
+ *fn_fieldlists;
+
+ /* If this "struct type" describes a template, then it
+ * has arguments. "template_args" points to an array of
+ * template arg descriptors, of length "ntemplate_args".
+ * The only real information in each of these template arg descriptors
+ * is a name. "type" will typically just point to a "struct type" with
+ * the placeholder TYPE_CODE_TEMPLATE_ARG type.
+ */
+ short ntemplate_args;
+ struct template_arg
+ {
+ char *name;
+ struct type *type;
+ }
+ *template_args;
+
+ /* If this "struct type" describes a template, it has a list
+ * of instantiations. "instantiations" is a pointer to an array
+ * of type's, one representing each instantiation. There
+ * are "ninstantiations" elements in this array.
+ */
+ short ninstantiations;
+ struct type **instantiations;
+
+ /* The following points to information relevant to the runtime model
+ * of the compiler.
+ * Currently being used only for HP's ANSI C++ compiler.
+ * (This type may have to be changed/enhanced for other compilers.)
+ *
+ * RUNTIME_PTR is NULL if there is no runtime information (currently
+ * this means the type was not compiled by HP aCC).
+ *
+ * Fields in structure pointed to:
+ * ->HAS_VTABLE : 0 => no virtual table, 1 => vtable present
+ *
+ * ->PRIMARY_BASE points to the first non-virtual base class that has
+ * a virtual table.
+ *
+ * ->VIRTUAL_BASE_LIST points to a list of struct type * pointers that
+ * point to the type information for all virtual bases among this type's
+ * ancestors.
+ */
+ struct runtime_info
+ {
+ short has_vtable;
+ struct type *primary_base;
+ struct type **virtual_base_list;
+ }
+ *runtime_ptr;
+
+ /* Pointer to information about enclosing scope, if this is a
+ * local type. If it is not a local type, this is NULL
+ */
+ struct local_type_info
+ {
+ char *file;
+ int line;
+ }
+ *localtype_ptr;
+ };
+
+/* Struct used in computing virtual base list */
+struct vbase
+ {
+ struct type *vbasetype; /* pointer to virtual base */
+ struct vbase *next; /* next in chain */
+ };
+
+/* Struct used for ranking a function for overload resolution */
+struct badness_vector
+ {
+ int length;
+ int *rank;
+ };
+
+/* The default value of TYPE_CPLUS_SPECIFIC(T) points to the
+ this shared static structure. */
+
+extern const struct cplus_struct_type cplus_struct_default;
+
+extern void allocate_cplus_struct_type (struct type *);
+
+#define INIT_CPLUS_SPECIFIC(type) \
+ (TYPE_CPLUS_SPECIFIC(type)=(struct cplus_struct_type*)&cplus_struct_default)
+#define ALLOCATE_CPLUS_STRUCT_TYPE(type) allocate_cplus_struct_type (type)
+#define HAVE_CPLUS_STRUCT(type) \
+ (TYPE_CPLUS_SPECIFIC(type) != &cplus_struct_default)
+
+#define TYPE_INSTANCE_FLAGS(thistype) (thistype)->instance_flags
+#define TYPE_MAIN_TYPE(thistype) (thistype)->main_type
+#define TYPE_NAME(thistype) TYPE_MAIN_TYPE(thistype)->name
+#define TYPE_TAG_NAME(type) TYPE_MAIN_TYPE(type)->tag_name
+#define TYPE_TARGET_TYPE(thistype) TYPE_MAIN_TYPE(thistype)->target_type
+#define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type
+#define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type
+#define TYPE_CHAIN(thistype) (thistype)->chain
+/* Note that if thistype is a TYPEDEF type, you have to call check_typedef.
+ But check_typedef does set the TYPE_LENGTH of the TYPEDEF type,
+ so you only have to call check_typedef once. Since allocate_value
+ calls check_typedef, TYPE_LENGTH (VALUE_TYPE (X)) is safe. */
+#define TYPE_LENGTH(thistype) TYPE_MAIN_TYPE(thistype)->length
+#define TYPE_OBJFILE(thistype) TYPE_MAIN_TYPE(thistype)->objfile
+#define TYPE_FLAGS(thistype) TYPE_MAIN_TYPE(thistype)->flags
+/* Note that TYPE_CODE can be TYPE_CODE_TYPEDEF, so if you want the real
+ type, you need to do TYPE_CODE (check_type (this_type)). */
+#define TYPE_CODE(thistype) TYPE_MAIN_TYPE(thistype)->code
+#define TYPE_NFIELDS(thistype) TYPE_MAIN_TYPE(thistype)->nfields
+#define TYPE_FIELDS(thistype) TYPE_MAIN_TYPE(thistype)->fields
+#define TYPE_TEMPLATE_ARGS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->template_args
+#define TYPE_INSTANTIATIONS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->instantiations
+
+#define TYPE_INDEX_TYPE(type) TYPE_FIELD_TYPE (type, 0)
+#define TYPE_LOW_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 0)
+#define TYPE_HIGH_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 1)
+
+/* Moto-specific stuff for FORTRAN arrays */
+
+#define TYPE_ARRAY_UPPER_BOUND_TYPE(thistype) \
+ TYPE_MAIN_TYPE(thistype)->upper_bound_type
+#define TYPE_ARRAY_LOWER_BOUND_TYPE(thistype) \
+ TYPE_MAIN_TYPE(thistype)->lower_bound_type
+
+#define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \
+ (TYPE_FIELD_BITPOS((TYPE_FIELD_TYPE((arraytype),0)),1))
+
+#define TYPE_ARRAY_LOWER_BOUND_VALUE(arraytype) \
+ (TYPE_FIELD_BITPOS((TYPE_FIELD_TYPE((arraytype),0)),0))
+
+/* C++ */
+
+#define TYPE_VPTR_BASETYPE(thistype) TYPE_MAIN_TYPE(thistype)->vptr_basetype
+#define TYPE_DOMAIN_TYPE(thistype) TYPE_MAIN_TYPE(thistype)->vptr_basetype
+#define TYPE_VPTR_FIELDNO(thistype) TYPE_MAIN_TYPE(thistype)->vptr_fieldno
+#define TYPE_FN_FIELDS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fields
+#define TYPE_NFN_FIELDS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->nfn_fields
+#define TYPE_NFN_FIELDS_TOTAL(thistype) TYPE_CPLUS_SPECIFIC(thistype)->nfn_fields_total
+#define TYPE_NTEMPLATE_ARGS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->ntemplate_args
+#define TYPE_NINSTANTIATIONS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->ninstantiations
+#define TYPE_DECLARED_TYPE(thistype) TYPE_CPLUS_SPECIFIC(thistype)->declared_type
+#define TYPE_TYPE_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific
+#define TYPE_ARG_TYPES(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.arg_types
+#define TYPE_CPLUS_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff
+#define TYPE_FLOATFORMAT(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.floatformat
+#define TYPE_BASECLASS(thistype,index) TYPE_MAIN_TYPE(thistype)->fields[index].type
+#define TYPE_N_BASECLASSES(thistype) TYPE_CPLUS_SPECIFIC(thistype)->n_baseclasses
+#define TYPE_BASECLASS_NAME(thistype,index) TYPE_MAIN_TYPE(thistype)->fields[index].name
+#define TYPE_BASECLASS_BITPOS(thistype,index) TYPE_FIELD_BITPOS(thistype,index)
+#define BASETYPE_VIA_PUBLIC(thistype, index) \
+ ((!TYPE_FIELD_PRIVATE(thistype, index)) && (!TYPE_FIELD_PROTECTED(thistype, index)))
+
+#define BASETYPE_VIA_VIRTUAL(thistype, index) \
+ (TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits == NULL ? 0 \
+ : B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (index)))
+
+#define FIELD_TYPE(thisfld) ((thisfld).type)
+#define FIELD_NAME(thisfld) ((thisfld).name)
+#define FIELD_BITPOS(thisfld) ((thisfld).loc.bitpos)
+#define FIELD_ARTIFICIAL(thisfld) ((thisfld).loc.artificial)
+#define FIELD_BITSIZE(thisfld) ((thisfld).bitsize)
+#define FIELD_PHYSNAME(thisfld) ((thisfld).loc.physname)
+#define FIELD_PHYSADDR(thisfld) ((thisfld).loc.physaddr)
+#define SET_FIELD_PHYSNAME(thisfld, name) \
+ ((thisfld).bitsize = -1, FIELD_PHYSNAME(thisfld) = (name))
+#define SET_FIELD_PHYSADDR(thisfld, name) \
+ ((thisfld).bitsize = -2, FIELD_PHYSADDR(thisfld) = (name))
+#define TYPE_FIELD(thistype, n) TYPE_MAIN_TYPE(thistype)->fields[n]
+#define TYPE_FIELD_TYPE(thistype, n) FIELD_TYPE(TYPE_FIELD(thistype, n))
+#define TYPE_FIELD_NAME(thistype, n) FIELD_NAME(TYPE_FIELD(thistype, n))
+#define TYPE_FIELD_BITPOS(thistype, n) FIELD_BITPOS(TYPE_FIELD(thistype,n))
+#define TYPE_FIELD_ARTIFICIAL(thistype, n) FIELD_ARTIFICIAL(TYPE_FIELD(thistype,n))
+#define TYPE_FIELD_BITSIZE(thistype, n) FIELD_BITSIZE(TYPE_FIELD(thistype,n))
+#define TYPE_FIELD_PACKED(thistype, n) (FIELD_BITSIZE(TYPE_FIELD(thistype,n))!=0)
+#define TYPE_TEMPLATE_ARG(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->template_args[n]
+#define TYPE_INSTANTIATION(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->instantiations[n]
+
+#define TYPE_FIELD_PRIVATE_BITS(thistype) \
+ TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits
+#define TYPE_FIELD_PROTECTED_BITS(thistype) \
+ TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits
+#define TYPE_FIELD_IGNORE_BITS(thistype) \
+ TYPE_CPLUS_SPECIFIC(thistype)->ignore_field_bits
+#define TYPE_FIELD_VIRTUAL_BITS(thistype) \
+ TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits
+#define SET_TYPE_FIELD_PRIVATE(thistype, n) \
+ B_SET (TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits, (n))
+#define SET_TYPE_FIELD_PROTECTED(thistype, n) \
+ B_SET (TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits, (n))
+#define SET_TYPE_FIELD_IGNORE(thistype, n) \
+ B_SET (TYPE_CPLUS_SPECIFIC(thistype)->ignore_field_bits, (n))
+#define SET_TYPE_FIELD_VIRTUAL(thistype, n) \
+ B_SET (TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n))
+#define TYPE_FIELD_PRIVATE(thistype, n) \
+ (TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits == NULL ? 0 \
+ : B_TST(TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits, (n)))
+#define TYPE_FIELD_PROTECTED(thistype, n) \
+ (TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits == NULL ? 0 \
+ : B_TST(TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits, (n)))
+#define TYPE_FIELD_IGNORE(thistype, n) \
+ (TYPE_CPLUS_SPECIFIC(thistype)->ignore_field_bits == NULL ? 0 \
+ : B_TST(TYPE_CPLUS_SPECIFIC(thistype)->ignore_field_bits, (n)))
+#define TYPE_FIELD_VIRTUAL(thistype, n) \
+ (TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits == NULL ? 0 \
+ : B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n)))
+
+#define TYPE_FIELD_STATIC(thistype, n) (TYPE_MAIN_TYPE (thistype)->fields[n].bitsize < 0)
+#define TYPE_FIELD_STATIC_HAS_ADDR(thistype, n) (TYPE_MAIN_TYPE (thistype)->fields[n].bitsize == -2)
+#define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) FIELD_PHYSNAME(TYPE_FIELD(thistype, n))
+#define TYPE_FIELD_STATIC_PHYSADDR(thistype, n) FIELD_PHYSADDR(TYPE_FIELD(thistype, n))
+
+#define TYPE_FN_FIELDLISTS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists
+#define TYPE_FN_FIELDLIST(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n]
+#define TYPE_FN_FIELDLIST1(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n].fn_fields
+#define TYPE_FN_FIELDLIST_NAME(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n].name
+#define TYPE_FN_FIELDLIST_LENGTH(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n].length
+
+#define TYPE_FN_FIELD(thisfn, n) (thisfn)[n]
+#define TYPE_FN_FIELD_PHYSNAME(thisfn, n) (thisfn)[n].physname
+#define TYPE_FN_FIELD_TYPE(thisfn, n) (thisfn)[n].type
+#define TYPE_FN_FIELD_ARGS(thisfn, n) TYPE_ARG_TYPES ((thisfn)[n].type)
+#define TYPE_FN_FIELD_CONST(thisfn, n) ((thisfn)[n].is_const)
+#define TYPE_FN_FIELD_VOLATILE(thisfn, n) ((thisfn)[n].is_volatile)
+#define TYPE_FN_FIELD_PRIVATE(thisfn, n) ((thisfn)[n].is_private)
+#define TYPE_FN_FIELD_PROTECTED(thisfn, n) ((thisfn)[n].is_protected)
+#define TYPE_FN_FIELD_PUBLIC(thisfn, n) ((thisfn)[n].is_public)
+#define TYPE_FN_FIELD_STATIC(thisfn, n) ((thisfn)[n].is_static)
+#define TYPE_FN_FIELD_FINAL(thisfn, n) ((thisfn)[n].is_final)
+#define TYPE_FN_FIELD_SYNCHRONIZED(thisfn, n) ((thisfn)[n].is_synchronized)
+#define TYPE_FN_FIELD_NATIVE(thisfn, n) ((thisfn)[n].is_native)
+#define TYPE_FN_FIELD_ARTIFICIAL(thisfn, n) ((thisfn)[n].is_artificial)
+#define TYPE_FN_FIELD_ABSTRACT(thisfn, n) ((thisfn)[n].is_abstract)
+#define TYPE_FN_FIELD_STUB(thisfn, n) ((thisfn)[n].is_stub)
+#define TYPE_FN_FIELD_INLINED(thisfn, n) ((thisfn)[n].is_inlined)
+#define TYPE_FN_FIELD_FCONTEXT(thisfn, n) ((thisfn)[n].fcontext)
+#define TYPE_FN_FIELD_VOFFSET(thisfn, n) ((thisfn)[n].voffset-2)
+#define TYPE_FN_FIELD_VIRTUAL_P(thisfn, n) ((thisfn)[n].voffset > 1)
+#define TYPE_FN_FIELD_STATIC_P(thisfn, n) ((thisfn)[n].voffset == VOFFSET_STATIC)
+
+#define TYPE_RUNTIME_PTR(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->runtime_ptr)
+#define TYPE_VTABLE(thistype) (TYPE_RUNTIME_PTR(thistype)->has_vtable)
+#define TYPE_HAS_VTABLE(thistype) (TYPE_RUNTIME_PTR(thistype) && TYPE_VTABLE(thistype))
+#define TYPE_PRIMARY_BASE(thistype) (TYPE_RUNTIME_PTR(thistype)->primary_base)
+#define TYPE_VIRTUAL_BASE_LIST(thistype) (TYPE_RUNTIME_PTR(thistype)->virtual_base_list)
+
+#define TYPE_LOCALTYPE_PTR(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->localtype_ptr)
+#define TYPE_LOCALTYPE_FILE(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->localtype_ptr->file)
+#define TYPE_LOCALTYPE_LINE(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->localtype_ptr->line)
+
+#define TYPE_IS_OPAQUE(thistype) (((TYPE_CODE (thistype) == TYPE_CODE_STRUCT) || \
+ (TYPE_CODE (thistype) == TYPE_CODE_UNION)) && \
+ (TYPE_NFIELDS (thistype) == 0) && \
+ (TYPE_CPLUS_SPECIFIC (thistype) && (TYPE_NFN_FIELDS (thistype) == 0)))
+
+
+
+/* Implicit sizes */
+extern struct type *builtin_type_void;
+extern struct type *builtin_type_char;
+extern struct type *builtin_type_short;
+extern struct type *builtin_type_int;
+extern struct type *builtin_type_long;
+extern struct type *builtin_type_signed_char;
+extern struct type *builtin_type_unsigned_char;
+extern struct type *builtin_type_unsigned_short;
+extern struct type *builtin_type_unsigned_int;
+extern struct type *builtin_type_unsigned_long;
+extern struct type *builtin_type_float;
+extern struct type *builtin_type_double;
+extern struct type *builtin_type_long_double;
+extern struct type *builtin_type_complex;
+extern struct type *builtin_type_double_complex;
+extern struct type *builtin_type_string;
+extern struct type *builtin_type_bool;
+
+/* Address/pointer types: */
+/* (C) Language `pointer to data' type. Some target platforms use an
+ implicitly {sign,zero} -extended 32 bit C language pointer on a 64
+ bit ISA. */
+extern struct type *builtin_type_void_data_ptr;
+
+/* (C) Language `pointer to function returning void' type. Since
+ ANSI, C standards have explicitly said that pointers to functions
+ and pointers to data are not interconvertible --- that is, you
+ can't cast a function pointer to void * and back, and expect to get
+ the same value. However, all function pointer types are
+ interconvertible, so void (*) () can server as a generic function
+ pointer. */
+extern struct type *builtin_type_void_func_ptr;
+
+/* The target CPU's address type. This is the ISA address size. */
+extern struct type *builtin_type_CORE_ADDR;
+/* The symbol table address type. Some object file formats have a 32
+ bit address type even though the TARGET has a 64 bit pointer type
+ (cf MIPS). */
+extern struct type *builtin_type_bfd_vma;
+
+/* Explicit sizes - see C9X <intypes.h> for naming scheme */
+extern struct type *builtin_type_int8;
+extern struct type *builtin_type_uint8;
+extern struct type *builtin_type_int16;
+extern struct type *builtin_type_uint16;
+extern struct type *builtin_type_int32;
+extern struct type *builtin_type_uint32;
+extern struct type *builtin_type_int64;
+extern struct type *builtin_type_uint64;
+extern struct type *builtin_type_int128;
+extern struct type *builtin_type_uint128;
+
+/* SIMD types. We inherit these names from GCC. */
+extern struct type *builtin_type_v4sf;
+extern struct type *builtin_type_v4si;
+extern struct type *builtin_type_v16qi;
+extern struct type *builtin_type_v8qi;
+extern struct type *builtin_type_v8hi;
+extern struct type *builtin_type_v4hi;
+extern struct type *builtin_type_v2si;
+
+/* Type for 128 bit vectors. */
+extern struct type *builtin_type_vec128;
+extern struct type *builtin_type_vec128i;
+
+/* Explicit floating-point formats. See "floatformat.h". */
+extern struct type *builtin_type_ieee_single_big;
+extern struct type *builtin_type_ieee_single_little;
+extern struct type *builtin_type_ieee_double_big;
+extern struct type *builtin_type_ieee_double_little;
+extern struct type *builtin_type_ieee_double_littlebyte_bigword;
+extern struct type *builtin_type_i387_ext;
+extern struct type *builtin_type_m68881_ext;
+extern struct type *builtin_type_i960_ext;
+extern struct type *builtin_type_m88110_ext;
+extern struct type *builtin_type_m88110_harris_ext;
+extern struct type *builtin_type_arm_ext_big;
+extern struct type *builtin_type_arm_ext_littlebyte_bigword;
+extern struct type *builtin_type_ia64_spill_big;
+extern struct type *builtin_type_ia64_spill_little;
+extern struct type *builtin_type_ia64_quad_big;
+extern struct type *builtin_type_ia64_quad_little;
+
+/* We use this for the '/c' print format, because builtin_type_char is
+ just a one-byte integral type, which languages less laid back than
+ C will print as ... well, a one-byte integral type. */
+extern struct type *builtin_type_true_char;
+
+/* This type represents a type that was unrecognized in symbol
+ read-in. */
+
+extern struct type *builtin_type_error;
+
+extern struct type *builtin_type_long_long;
+extern struct type *builtin_type_unsigned_long_long;
+
+/* Modula-2 types */
+
+extern struct type *builtin_type_m2_char;
+extern struct type *builtin_type_m2_int;
+extern struct type *builtin_type_m2_card;
+extern struct type *builtin_type_m2_real;
+extern struct type *builtin_type_m2_bool;
+
+/* Chill types */
+
+extern struct type *builtin_type_chill_bool;
+extern struct type *builtin_type_chill_char;
+extern struct type *builtin_type_chill_long;
+extern struct type *builtin_type_chill_ulong;
+extern struct type *builtin_type_chill_real;
+
+/* Fortran (F77) types */
+
+extern struct type *builtin_type_f_character;
+extern struct type *builtin_type_f_integer;
+extern struct type *builtin_type_f_integer_s2;
+extern struct type *builtin_type_f_logical;
+extern struct type *builtin_type_f_logical_s1;
+extern struct type *builtin_type_f_logical_s2;
+extern struct type *builtin_type_f_real;
+extern struct type *builtin_type_f_real_s8;
+extern struct type *builtin_type_f_real_s16;
+extern struct type *builtin_type_f_complex_s8;
+extern struct type *builtin_type_f_complex_s16;
+extern struct type *builtin_type_f_complex_s32;
+extern struct type *builtin_type_f_void;
+
+/* RTTI for C++ */
+/* extern struct type *builtin_type_cxx_typeinfo; */
+
+/* Maximum and minimum values of built-in types */
+
+#define MAX_OF_TYPE(t) \
+ (TYPE_UNSIGNED(t) ? UMAX_OF_SIZE(TYPE_LENGTH(t)) \
+ : MAX_OF_SIZE(TYPE_LENGTH(t)))
+
+#define MIN_OF_TYPE(t) \
+ (TYPE_UNSIGNED(t) ? UMIN_OF_SIZE(TYPE_LENGTH(t)) \
+ : MIN_OF_SIZE(TYPE_LENGTH(t)))
+
+/* Allocate space for storing data associated with a particular type.
+ We ensure that the space is allocated using the same mechanism that
+ was used to allocate the space for the type structure itself. I.E.
+ if the type is on an objfile's type_obstack, then the space for data
+ associated with that type will also be allocated on the type_obstack.
+ If the type is not associated with any particular objfile (such as
+ builtin types), then the data space will be allocated with xmalloc,
+ the same as for the type structure. */
+
+#define TYPE_ALLOC(t,size) \
+ (TYPE_OBJFILE (t) != NULL \
+ ? obstack_alloc (&TYPE_OBJFILE (t) -> type_obstack, size) \
+ : xmalloc (size))
+
+extern struct type *alloc_type (struct objfile *);
+
+extern struct type *init_type (enum type_code, int, int, char *,
+ struct objfile *);
+
+/* Helper functions to construct a struct or record type. An
+ initially empty type is created using init_composite_type().
+ Fields are then added using append_struct_type_field(). A union
+ type has its size set to the largest field. A struct type has each
+ field packed against the previous. */
+
+extern struct type *init_composite_type (char *name, enum type_code code);
+extern void append_composite_type_field (struct type *t, char *name,
+ struct type *field);
+
+extern struct type *lookup_reference_type (struct type *);
+
+extern struct type *make_reference_type (struct type *, struct type **);
+
+extern struct type *make_cv_type (int, int, struct type *, struct type **);
+
+extern void replace_type (struct type *, struct type *);
+
+extern int address_space_name_to_int (char *);
+
+extern char *address_space_int_to_name (int);
+
+extern struct type *make_type_with_address_space (struct type *type,
+ int space_identifier);
+
+extern struct type *lookup_member_type (struct type *, struct type *);
+
+extern void
+smash_to_method_type (struct type *, struct type *, struct type *,
+ struct type **);
+
+extern void
+smash_to_member_type (struct type *, struct type *, struct type *);
+
+extern struct type *allocate_stub_method (struct type *);
+
+extern char *type_name_no_tag (const struct type *);
+
+extern struct type *lookup_struct_elt_type (struct type *, char *, int);
+
+extern struct type *make_pointer_type (struct type *, struct type **);
+
+extern struct type *lookup_pointer_type (struct type *);
+
+extern struct type *make_function_type (struct type *, struct type **);
+
+extern struct type *lookup_function_type (struct type *);
+
+extern struct type *create_range_type (struct type *, struct type *, int,
+ int);
+
+extern struct type *create_array_type (struct type *, struct type *,
+ struct type *);
+
+extern struct type *create_string_type (struct type *, struct type *);
+
+extern struct type *create_set_type (struct type *, struct type *);
+
+extern int chill_varying_type (struct type *);
+
+extern struct type *lookup_unsigned_typename (char *);
+
+extern struct type *lookup_signed_typename (char *);
+
+extern struct type *check_typedef (struct type *);
+
+#define CHECK_TYPEDEF(TYPE) (TYPE) = check_typedef (TYPE)
+
+extern void check_stub_method (struct type *, int, int);
+
+extern struct type *lookup_primitive_typename (char *);
+
+extern char *gdb_mangle_name (struct type *, int, int);
+
+extern struct type *builtin_type (char **);
+
+extern struct type *lookup_typename (char *, struct block *, int);
+
+extern struct type *lookup_template_type (char *, struct type *,
+ struct block *);
+
+extern struct type *lookup_fundamental_type (struct objfile *, int);
+
+extern void fill_in_vptr_fieldno (struct type *);
+
+extern int get_destructor_fn_field (struct type *, int *, int *);
+
+extern int get_discrete_bounds (struct type *, LONGEST *, LONGEST *);
+
+extern int is_ancestor (struct type *, struct type *);
+
+extern int has_vtable (struct type *);
+
+extern struct type *primary_base_class (struct type *);
+
+extern struct type **virtual_base_list (struct type *);
+
+extern int virtual_base_list_length (struct type *);
+extern int virtual_base_list_length_skip_primaries (struct type *);
+
+extern int virtual_base_index (struct type *, struct type *);
+extern int virtual_base_index_skip_primaries (struct type *, struct type *);
+
+
+extern int class_index_in_primary_list (struct type *);
+
+extern int count_virtual_fns (struct type *);
+
+/* Constants for HP/Taligent ANSI C++ runtime model */
+
+/* Where virtual function entries begin in the
+ * virtual table, in the non-RRBC vtable format.
+ * First 4 are the metavtable pointer, top offset,
+ * typeinfo pointer, and dup base info pointer */
+#define HP_ACC_VFUNC_START 4
+
+/* (Negative) Offset where virtual base offset entries begin
+ * in the virtual table. Skips over metavtable pointer and
+ * the self-offset entry.
+ * NOTE: NEGATE THIS BEFORE USING! The virtual base offsets
+ * appear before the address point of the vtable (the slot
+ * pointed to by the object's vtable pointer), i.e. at lower
+ * addresses than the vtable pointer. */
+#define HP_ACC_VBASE_START 2
+
+/* (Positive) Offset where the pointer to the typeinfo
+ * object is present in the virtual table */
+#define HP_ACC_TYPEINFO_OFFSET 2
+
+/* (Positive) Offset where the ``top offset'' entry of
+ * the virtual table is */
+#define HP_ACC_TOP_OFFSET_OFFSET 1
+
+/* Overload resolution */
+
+#define LENGTH_MATCH(bv) ((bv)->rank[0])
+
+/* Badness if parameter list length doesn't match arg list length */
+#define LENGTH_MISMATCH_BADNESS 100
+/* Dummy badness value for nonexistent parameter positions */
+#define TOO_FEW_PARAMS_BADNESS 100
+/* Badness if no conversion among types */
+#define INCOMPATIBLE_TYPE_BADNESS 100
+/* Badness of coercing large integer to smaller size */
+#define INTEGER_COERCION_BADNESS 100
+/* Badness of coercing large floating type to smaller size */
+#define FLOAT_COERCION_BADNESS 100
+
+/* Badness of integral promotion */
+#define INTEGER_PROMOTION_BADNESS 1
+/* Badness of floating promotion */
+#define FLOAT_PROMOTION_BADNESS 1
+/* Badness of integral conversion */
+#define INTEGER_CONVERSION_BADNESS 2
+/* Badness of floating conversion */
+#define FLOAT_CONVERSION_BADNESS 2
+/* Badness of integer<->floating conversions */
+#define INT_FLOAT_CONVERSION_BADNESS 2
+/* Badness of converting to a boolean */
+#define BOOLEAN_CONVERSION_BADNESS 2
+/* Badness of pointer conversion */
+#define POINTER_CONVERSION_BADNESS 2
+/* Badness of conversion of pointer to void pointer */
+#define VOID_PTR_CONVERSION_BADNESS 2
+/* Badness of converting derived to base class */
+#define BASE_CONVERSION_BADNESS 2
+/* Badness of converting from non-reference to reference */
+#define REFERENCE_CONVERSION_BADNESS 2
+
+/* Non-standard conversions allowed by the debugger */
+/* Converting a pointer to an int is usually OK */
+#define NS_POINTER_CONVERSION_BADNESS 10
+
+
+extern int compare_badness (struct badness_vector *, struct badness_vector *);
+
+extern struct badness_vector *rank_function (struct type **, int,
+ struct type **, int);
+
+extern int rank_one_type (struct type *, struct type *);
+
+extern void recursive_dump_type (struct type *, int);
+
+/* printcmd.c */
+
+extern void print_scalar_formatted (char *, struct type *, int, int,
+ struct ui_file *);
+
+extern int can_dereference (struct type *);
+
+extern int is_integral_type (struct type *);
+
+extern void maintenance_print_type (char *, int);
+
+#endif /* GDBTYPES_H */
diff --git a/gdb/gnu-nat.c b/gdb/gnu-nat.c
new file mode 100644
index 00000000000..a4b8020a04c
--- /dev/null
+++ b/gdb/gnu-nat.c
@@ -0,0 +1,3439 @@
+/* Interface GDB to the GNU Hurd.
+ Copyright 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ Some code and ideas from m3-nat.c by Jukka Virtanen <jtv@hut.fi>
+
+ 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 <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include "gdb_string.h"
+#include <sys/ptrace.h>
+
+#include <mach.h>
+#include <mach_error.h>
+#include <mach/exception.h>
+#include <mach/message.h>
+#include <mach/notify.h>
+#include <mach/vm_attributes.h>
+
+#include <hurd.h>
+#include <hurd/interrupt.h>
+#include <hurd/msg.h>
+#include <hurd/msg_request.h>
+#include <hurd/process.h>
+#include <hurd/process_request.h>
+#include <hurd/signal.h>
+#include <hurd/sigpreempt.h>
+
+#include <portinfo.h>
+
+#include "defs.h"
+#include "inferior.h"
+#include "symtab.h"
+#include "value.h"
+#include "language.h"
+#include "target.h"
+#include "gdb_wait.h"
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "gdbthread.h"
+#include "gdb_assert.h"
+
+#include "gnu-nat.h"
+
+#include "exc_request_S.h"
+#include "notify_S.h"
+#include "process_reply_S.h"
+#include "msg_reply_S.h"
+#include "exc_request_U.h"
+#include "msg_U.h"
+
+static process_t proc_server = MACH_PORT_NULL;
+
+/* If we've sent a proc_wait_request to the proc server, the pid of the
+ process we asked about. We can only ever have one outstanding. */
+int proc_wait_pid = 0;
+
+/* The number of wait requests we've sent, and expect replies from. */
+int proc_waits_pending = 0;
+
+int gnu_debug_flag = 0;
+
+/* Forward decls */
+
+extern struct target_ops gnu_ops;
+
+struct inf *make_inf ();
+void inf_clear_wait (struct inf *inf);
+void inf_cleanup (struct inf *inf);
+void inf_startup (struct inf *inf, int pid);
+int inf_update_suspends (struct inf *inf);
+void inf_set_pid (struct inf *inf, pid_t pid);
+void inf_validate_procs (struct inf *inf);
+void inf_steal_exc_ports (struct inf *inf);
+void inf_restore_exc_ports (struct inf *inf);
+struct proc *inf_tid_to_proc (struct inf *inf, int tid);
+inline void inf_set_threads_resume_sc (struct inf *inf,
+ struct proc *run_thread,
+ int run_others);
+inline int inf_set_threads_resume_sc_for_signal_thread (struct inf *inf);
+inline void inf_suspend (struct inf *inf);
+inline void inf_resume (struct inf *inf);
+void inf_set_step_thread (struct inf *inf, struct proc *proc);
+void inf_detach (struct inf *inf);
+void inf_attach (struct inf *inf, int pid);
+void inf_signal (struct inf *inf, enum target_signal sig);
+void inf_continue (struct inf *inf);
+
+#define inf_debug(_inf, msg, args...) \
+ do { struct inf *__inf = (_inf); \
+ debug ("{inf %d %p}: " msg, __inf->pid, __inf , ##args); } while (0)
+
+void proc_abort (struct proc *proc, int force);
+struct proc *make_proc (struct inf *inf, mach_port_t port, int tid);
+struct proc *_proc_free (struct proc *proc);
+int proc_update_sc (struct proc *proc);
+error_t proc_get_exception_port (struct proc *proc, mach_port_t * port);
+error_t proc_set_exception_port (struct proc *proc, mach_port_t port);
+static mach_port_t _proc_get_exc_port (struct proc *proc);
+void proc_steal_exc_port (struct proc *proc, mach_port_t exc_port);
+void proc_restore_exc_port (struct proc *proc);
+int proc_trace (struct proc *proc, int set);
+
+/* Evaluate RPC_EXPR in a scope with the variables MSGPORT and REFPORT bound
+ to INF's msg port and task port respectively. If it has no msg port,
+ EIEIO is returned. INF must refer to a running process! */
+#define INF_MSGPORT_RPC(inf, rpc_expr) \
+ HURD_MSGPORT_RPC (proc_getmsgport (proc_server, inf->pid, &msgport), \
+ (refport = inf->task->port, 0), 0, \
+ msgport ? (rpc_expr) : EIEIO)
+
+/* Like INF_MSGPORT_RPC, but will also resume the signal thread to ensure
+ there's someone around to deal with the RPC (and resuspend things
+ afterwards). This effects INF's threads' resume_sc count. */
+#define INF_RESUME_MSGPORT_RPC(inf, rpc_expr) \
+ (inf_set_threads_resume_sc_for_signal_thread (inf) \
+ ? ({ error_t __e; \
+ inf_resume (inf); \
+ __e = INF_MSGPORT_RPC (inf, rpc_expr); \
+ inf_suspend (inf); \
+ __e; }) \
+ : EIEIO)
+
+
+/* The state passed by an exception message. */
+struct exc_state
+ {
+ int exception; /* The exception code */
+ int code, subcode;
+ mach_port_t handler; /* The real exception port to handle this. */
+ mach_port_t reply; /* The reply port from the exception call. */
+ };
+
+/* The results of the last wait an inf did. */
+struct inf_wait
+ {
+ struct target_waitstatus status; /* The status returned to gdb. */
+ struct exc_state exc; /* The exception that caused us to return. */
+ struct proc *thread; /* The thread in question. */
+ int suppress; /* Something trivial happened. */
+ };
+
+/* The state of an inferior. */
+struct inf
+ {
+ /* Fields describing the current inferior. */
+
+ struct proc *task; /* The mach task. */
+ struct proc *threads; /* A linked list of all threads in TASK. */
+
+ /* True if THREADS needn't be validated by querying the task. We assume that
+ we and the task in question are the only ones frobbing the thread list,
+ so as long as we don't let any code run, we don't have to worry about
+ THREADS changing. */
+ int threads_up_to_date;
+
+ pid_t pid; /* The real system PID. */
+
+ struct inf_wait wait; /* What to return from target_wait. */
+
+ /* One thread proc in INF may be in `single-stepping mode'. This is it. */
+ struct proc *step_thread;
+
+ /* The thread we think is the signal thread. */
+ struct proc *signal_thread;
+
+ mach_port_t event_port; /* Where we receive various msgs. */
+
+ /* True if we think at least one thread in the inferior could currently be
+ running. */
+ unsigned int running:1;
+
+ /* True if the process has stopped (in the proc server sense). Note that
+ since a proc server `stop' leaves the signal thread running, the inf can
+ be RUNNING && STOPPED... */
+ unsigned int stopped:1;
+
+ /* True if the inferior has no message port. */
+ unsigned int nomsg:1;
+
+ /* True if the inferior is traced. */
+ unsigned int traced:1;
+
+ /* True if we shouldn't try waiting for the inferior, usually because we
+ can't for some reason. */
+ unsigned int no_wait:1;
+
+ /* When starting a new inferior, we don't try to validate threads until all
+ the proper execs have been done. This is a count of how many execs we
+ expect to happen. */
+ unsigned pending_execs;
+
+ /* Fields describing global state */
+
+ /* The task suspend count used when gdb has control. This is normally 1 to
+ make things easier for us, but sometimes (like when attaching to vital
+ system servers) it may be desirable to let the task continue to run
+ (pausing individual threads as necessary). */
+ int pause_sc;
+
+ /* The task suspend count left when detaching from a task. */
+ int detach_sc;
+
+ /* The initial values used for the run_sc and pause_sc of newly discovered
+ threads -- see the definition of those fields in struct proc. */
+ int default_thread_run_sc;
+ int default_thread_pause_sc;
+ int default_thread_detach_sc;
+
+ /* True if the process should be traced when started/attached. Newly
+ started processes *must* be traced at first to exec them properly, but
+ if this is false, tracing is turned off as soon it has done so. */
+ int want_signals;
+
+ /* True if exceptions from the inferior process should be trapped. This
+ must be on to use breakpoints. */
+ int want_exceptions;
+ };
+
+
+int
+__proc_pid (struct proc *proc)
+{
+ return proc->inf->pid;
+}
+
+
+/* Update PROC's real suspend count to match it's desired one. Returns true
+ if we think PROC is now in a runnable state. */
+int
+proc_update_sc (struct proc *proc)
+{
+ int running;
+ int err = 0;
+ int delta = proc->sc - proc->cur_sc;
+
+ if (delta)
+ proc_debug (proc, "sc: %d --> %d", proc->cur_sc, proc->sc);
+
+ if (proc->sc == 0 && proc->state_changed)
+ /* Since PROC may start running, we must write back any state changes. */
+ {
+ gdb_assert (proc_is_thread (proc));
+ proc_debug (proc, "storing back changed thread state");
+ err = thread_set_state (proc->port, THREAD_STATE_FLAVOR,
+ (thread_state_t) &proc->state, THREAD_STATE_SIZE);
+ if (!err)
+ proc->state_changed = 0;
+ }
+
+ if (delta > 0)
+ {
+ while (delta-- > 0 && !err)
+ {
+ if (proc_is_task (proc))
+ err = task_suspend (proc->port);
+ else
+ err = thread_suspend (proc->port);
+ }
+ }
+ else
+ {
+ while (delta++ < 0 && !err)
+ {
+ if (proc_is_task (proc))
+ err = task_resume (proc->port);
+ else
+ err = thread_resume (proc->port);
+ }
+ }
+ if (!err)
+ proc->cur_sc = proc->sc;
+
+ /* If we got an error, then the task/thread has disappeared. */
+ running = !err && proc->sc == 0;
+
+ proc_debug (proc, "is %s", err ? "dead" : running ? "running" : "suspended");
+ if (err)
+ proc_debug (proc, "err = %s", safe_strerror (err));
+
+ if (running)
+ {
+ proc->aborted = 0;
+ proc->state_valid = proc->state_changed = 0;
+ proc->fetched_regs = 0;
+ }
+
+ return running;
+}
+
+
+/* Thread_abort is called on PROC if needed. PROC must be a thread proc.
+ If PROC is deemed `precious', then nothing is done unless FORCE is true.
+ In particular, a thread is precious if it's running (in which case forcing
+ it includes suspending it first), or if it has an exception pending. */
+void
+proc_abort (struct proc *proc, int force)
+{
+ gdb_assert (proc_is_thread (proc));
+
+ if (!proc->aborted)
+ {
+ struct inf *inf = proc->inf;
+ int running = (proc->cur_sc == 0 && inf->task->cur_sc == 0);
+
+ if (running && force)
+ {
+ proc->sc = 1;
+ inf_update_suspends (proc->inf);
+ running = 0;
+ warning ("Stopped %s.", proc_string (proc));
+ }
+ else if (proc == inf->wait.thread && inf->wait.exc.reply && !force)
+ /* An exception is pending on PROC, which don't mess with. */
+ running = 1;
+
+ if (!running)
+ /* We only abort the thread if it's not actually running. */
+ {
+ thread_abort (proc->port);
+ proc_debug (proc, "aborted");
+ proc->aborted = 1;
+ }
+ else
+ proc_debug (proc, "not aborting");
+ }
+}
+
+/* Make sure that the state field in PROC is up to date, and return a pointer
+ to it, or 0 if something is wrong. If WILL_MODIFY is true, makes sure
+ that the thread is stopped and aborted first, and sets the state_changed
+ field in PROC to true. */
+thread_state_t
+proc_get_state (struct proc *proc, int will_modify)
+{
+ int was_aborted = proc->aborted;
+
+ proc_debug (proc, "updating state info%s",
+ will_modify ? " (with intention to modify)" : "");
+
+ proc_abort (proc, will_modify);
+
+ if (!was_aborted && proc->aborted)
+ /* PROC's state may have changed since we last fetched it. */
+ proc->state_valid = 0;
+
+ if (!proc->state_valid)
+ {
+ mach_msg_type_number_t state_size = THREAD_STATE_SIZE;
+ error_t err =
+ thread_get_state (proc->port, THREAD_STATE_FLAVOR,
+ (thread_state_t) &proc->state, &state_size);
+ proc_debug (proc, "getting thread state");
+ proc->state_valid = !err;
+ }
+
+ if (proc->state_valid)
+ {
+ if (will_modify)
+ proc->state_changed = 1;
+ return (thread_state_t) &proc->state;
+ }
+ else
+ return 0;
+}
+
+
+/* Set PORT to PROC's exception port. */
+error_t
+proc_get_exception_port (struct proc * proc, mach_port_t * port)
+{
+ if (proc_is_task (proc))
+ return task_get_exception_port (proc->port, port);
+ else
+ return thread_get_exception_port (proc->port, port);
+}
+
+/* Set PROC's exception port to PORT. */
+error_t
+proc_set_exception_port (struct proc * proc, mach_port_t port)
+{
+ proc_debug (proc, "setting exception port: %d", port);
+ if (proc_is_task (proc))
+ return task_set_exception_port (proc->port, port);
+ else
+ return thread_set_exception_port (proc->port, port);
+}
+
+/* Get PROC's exception port, cleaning up a bit if proc has died. */
+static mach_port_t
+_proc_get_exc_port (struct proc *proc)
+{
+ mach_port_t exc_port;
+ error_t err = proc_get_exception_port (proc, &exc_port);
+
+ if (err)
+ /* PROC must be dead. */
+ {
+ if (proc->exc_port)
+ mach_port_deallocate (mach_task_self (), proc->exc_port);
+ proc->exc_port = MACH_PORT_NULL;
+ if (proc->saved_exc_port)
+ mach_port_deallocate (mach_task_self (), proc->saved_exc_port);
+ proc->saved_exc_port = MACH_PORT_NULL;
+ }
+
+ return exc_port;
+}
+
+/* Replace PROC's exception port with EXC_PORT, unless it's already been
+ done. Stash away any existing exception port so we can restore it later. */
+void
+proc_steal_exc_port (struct proc *proc, mach_port_t exc_port)
+{
+ mach_port_t cur_exc_port = _proc_get_exc_port (proc);
+
+ if (cur_exc_port)
+ {
+ error_t err = 0;
+
+ proc_debug (proc, "inserting exception port: %d", exc_port);
+
+ if (cur_exc_port != exc_port)
+ /* Put in our exception port. */
+ err = proc_set_exception_port (proc, exc_port);
+
+ if (err || cur_exc_port == proc->exc_port)
+ /* We previously set the exception port, and it's still set. So we
+ just keep the old saved port which is what the proc set. */
+ {
+ if (cur_exc_port)
+ mach_port_deallocate (mach_task_self (), cur_exc_port);
+ }
+ else
+ /* Keep a copy of PROC's old exception port so it can be restored. */
+ {
+ if (proc->saved_exc_port)
+ mach_port_deallocate (mach_task_self (), proc->saved_exc_port);
+ proc->saved_exc_port = cur_exc_port;
+ }
+
+ proc_debug (proc, "saved exception port: %d", proc->saved_exc_port);
+
+ if (!err)
+ proc->exc_port = exc_port;
+ else
+ warning ("Error setting exception port for %s: %s",
+ proc_string (proc), safe_strerror (err));
+ }
+}
+
+/* If we previously replaced PROC's exception port, put back what we
+ found there at the time, unless *our* exception port has since been
+ overwritten, in which case who knows what's going on. */
+void
+proc_restore_exc_port (struct proc *proc)
+{
+ mach_port_t cur_exc_port = _proc_get_exc_port (proc);
+
+ if (cur_exc_port)
+ {
+ error_t err = 0;
+
+ proc_debug (proc, "restoring real exception port");
+
+ if (proc->exc_port == cur_exc_port)
+ /* Our's is still there. */
+ err = proc_set_exception_port (proc, proc->saved_exc_port);
+
+ if (proc->saved_exc_port)
+ mach_port_deallocate (mach_task_self (), proc->saved_exc_port);
+ proc->saved_exc_port = MACH_PORT_NULL;
+
+ if (!err)
+ proc->exc_port = MACH_PORT_NULL;
+ else
+ warning ("Error setting exception port for %s: %s",
+ proc_string (proc), safe_strerror (err));
+ }
+}
+
+
+/* Turns hardware tracing in PROC on or off when SET is true or false,
+ respectively. Returns true on success. */
+int
+proc_trace (struct proc *proc, int set)
+{
+ thread_state_t state = proc_get_state (proc, 1);
+
+ if (!state)
+ return 0; /* the thread must be dead. */
+
+ proc_debug (proc, "tracing %s", set ? "on" : "off");
+
+ if (set)
+ {
+ /* XXX We don't get the exception unless the thread has its own
+ exception port???? */
+ if (proc->exc_port == MACH_PORT_NULL)
+ proc_steal_exc_port (proc, proc->inf->event_port);
+ THREAD_STATE_SET_TRACED (state);
+ }
+ else
+ THREAD_STATE_CLEAR_TRACED (state);
+
+ return 1;
+}
+
+
+/* A variable from which to assign new TIDs. */
+static int next_thread_id = 1;
+
+/* Returns a new proc structure with the given fields. Also adds a
+ notification for PORT becoming dead to be sent to INF's notify port. */
+struct proc *
+make_proc (struct inf *inf, mach_port_t port, int tid)
+{
+ error_t err;
+ mach_port_t prev_port = MACH_PORT_NULL;
+ struct proc *proc = xmalloc (sizeof (struct proc));
+
+ proc->port = port;
+ proc->tid = tid;
+ proc->inf = inf;
+ proc->next = 0;
+ proc->saved_exc_port = MACH_PORT_NULL;
+ proc->exc_port = MACH_PORT_NULL;
+
+ proc->sc = 0;
+ proc->cur_sc = 0;
+
+ /* Note that these are all the values for threads; the task simply uses the
+ corresponding field in INF directly. */
+ proc->run_sc = inf->default_thread_run_sc;
+ proc->pause_sc = inf->default_thread_pause_sc;
+ proc->detach_sc = inf->default_thread_detach_sc;
+ proc->resume_sc = proc->run_sc;
+
+ proc->aborted = 0;
+ proc->dead = 0;
+ proc->state_valid = 0;
+ proc->state_changed = 0;
+
+ proc_debug (proc, "is new");
+
+ /* Get notified when things die. */
+ err =
+ mach_port_request_notification (mach_task_self (), port,
+ MACH_NOTIFY_DEAD_NAME, 1,
+ inf->event_port,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE,
+ &prev_port);
+ if (err)
+ warning ("Couldn't request notification for port %d: %s",
+ port, safe_strerror (err));
+ else
+ {
+ proc_debug (proc, "notifications to: %d", inf->event_port);
+ if (prev_port != MACH_PORT_NULL)
+ mach_port_deallocate (mach_task_self (), prev_port);
+ }
+
+ if (inf->want_exceptions)
+ {
+ if (proc_is_task (proc))
+ /* Make the task exception port point to us. */
+ proc_steal_exc_port (proc, inf->event_port);
+ else
+ /* Just clear thread exception ports -- they default to the
+ task one. */
+ proc_steal_exc_port (proc, MACH_PORT_NULL);
+ }
+
+ return proc;
+}
+
+/* Frees PROC and any resources it uses, and returns the value of PROC's
+ next field. */
+struct proc *
+_proc_free (struct proc *proc)
+{
+ struct inf *inf = proc->inf;
+ struct proc *next = proc->next;
+
+ proc_debug (proc, "freeing...");
+
+ if (proc == inf->step_thread)
+ /* Turn off single stepping. */
+ inf_set_step_thread (inf, 0);
+ if (proc == inf->wait.thread)
+ inf_clear_wait (inf);
+ if (proc == inf->signal_thread)
+ inf->signal_thread = 0;
+
+ if (proc->port != MACH_PORT_NULL)
+ {
+ if (proc->exc_port != MACH_PORT_NULL)
+ /* Restore the original exception port. */
+ proc_restore_exc_port (proc);
+ if (proc->cur_sc != 0)
+ /* Resume the thread/task. */
+ {
+ proc->sc = 0;
+ proc_update_sc (proc);
+ }
+ mach_port_deallocate (mach_task_self (), proc->port);
+ }
+
+ xfree (proc);
+ return next;
+}
+
+
+struct inf *
+make_inf (void)
+{
+ struct inf *inf = xmalloc (sizeof (struct inf));
+
+ inf->task = 0;
+ inf->threads = 0;
+ inf->threads_up_to_date = 0;
+ inf->pid = 0;
+ inf->wait.status.kind = TARGET_WAITKIND_SPURIOUS;
+ inf->wait.thread = 0;
+ inf->wait.exc.handler = MACH_PORT_NULL;
+ inf->wait.exc.reply = MACH_PORT_NULL;
+ inf->step_thread = 0;
+ inf->signal_thread = 0;
+ inf->event_port = MACH_PORT_NULL;
+ inf->running = 0;
+ inf->stopped = 0;
+ inf->nomsg = 1;
+ inf->traced = 0;
+ inf->no_wait = 0;
+ inf->pending_execs = 0;
+ inf->pause_sc = 1;
+ inf->detach_sc = 0;
+ inf->default_thread_run_sc = 0;
+ inf->default_thread_pause_sc = 0;
+ inf->default_thread_detach_sc = 0;
+ inf->want_signals = 1; /* By default */
+ inf->want_exceptions = 1; /* By default */
+
+ return inf;
+}
+
+/* Clear INF's target wait status. */
+void
+inf_clear_wait (struct inf *inf)
+{
+ inf_debug (inf, "clearing wait");
+ inf->wait.status.kind = TARGET_WAITKIND_SPURIOUS;
+ inf->wait.thread = 0;
+ inf->wait.suppress = 0;
+ if (inf->wait.exc.handler != MACH_PORT_NULL)
+ {
+ mach_port_deallocate (mach_task_self (), inf->wait.exc.handler);
+ inf->wait.exc.handler = MACH_PORT_NULL;
+ }
+ if (inf->wait.exc.reply != MACH_PORT_NULL)
+ {
+ mach_port_deallocate (mach_task_self (), inf->wait.exc.reply);
+ inf->wait.exc.reply = MACH_PORT_NULL;
+ }
+}
+
+
+void
+inf_cleanup (struct inf *inf)
+{
+ inf_debug (inf, "cleanup");
+
+ inf_clear_wait (inf);
+
+ inf_set_pid (inf, -1);
+ inf->pid = 0;
+ inf->running = 0;
+ inf->stopped = 0;
+ inf->nomsg = 1;
+ inf->traced = 0;
+ inf->no_wait = 0;
+ inf->pending_execs = 0;
+
+ if (inf->event_port)
+ {
+ mach_port_destroy (mach_task_self (), inf->event_port);
+ inf->event_port = MACH_PORT_NULL;
+ }
+}
+
+void
+inf_startup (struct inf *inf, int pid)
+{
+ error_t err;
+
+ inf_debug (inf, "startup: pid = %d", pid);
+
+ inf_cleanup (inf);
+
+ /* Make the port on which we receive all events. */
+ err = mach_port_allocate (mach_task_self (),
+ MACH_PORT_RIGHT_RECEIVE, &inf->event_port);
+ if (err)
+ error ("Error allocating event port: %s", safe_strerror (err));
+
+ /* Make a send right for it, so we can easily copy it for other people. */
+ mach_port_insert_right (mach_task_self (), inf->event_port,
+ inf->event_port, MACH_MSG_TYPE_MAKE_SEND);
+ inf_set_pid (inf, pid);
+}
+
+
+/* Close current process, if any, and attach INF to process PORT. */
+void
+inf_set_pid (struct inf *inf, pid_t pid)
+{
+ task_t task_port;
+ struct proc *task = inf->task;
+
+ inf_debug (inf, "setting pid: %d", pid);
+
+ if (pid < 0)
+ task_port = MACH_PORT_NULL;
+ else
+ {
+ error_t err = proc_pid2task (proc_server, pid, &task_port);
+ if (err)
+ error ("Error getting task for pid %d: %s", pid, safe_strerror (err));
+ }
+
+ inf_debug (inf, "setting task: %d", task_port);
+
+ if (inf->pause_sc)
+ task_suspend (task_port);
+
+ if (task && task->port != task_port)
+ {
+ inf->task = 0;
+ inf_validate_procs (inf); /* Trash all the threads. */
+ _proc_free (task); /* And the task. */
+ }
+
+ if (task_port != MACH_PORT_NULL)
+ {
+ inf->task = make_proc (inf, task_port, PROC_TID_TASK);
+ inf->threads_up_to_date = 0;
+ }
+
+ if (inf->task)
+ {
+ inf->pid = pid;
+ if (inf->pause_sc)
+ /* Reflect task_suspend above. */
+ inf->task->sc = inf->task->cur_sc = 1;
+ }
+ else
+ inf->pid = -1;
+}
+
+
+/* Validates INF's stopped, nomsg and traced field from the actual
+ proc server state. Note that the traced field is only updated from
+ the proc server state if we do not have a message port. If we do
+ have a message port we'd better look at the tracemask itself. */
+static void
+inf_validate_procinfo (struct inf *inf)
+{
+ char *noise;
+ mach_msg_type_number_t noise_len = 0;
+ struct procinfo *pi;
+ mach_msg_type_number_t pi_len = 0;
+ int info_flags = 0;
+ error_t err =
+ proc_getprocinfo (proc_server, inf->pid, &info_flags,
+ (procinfo_t *) &pi, &pi_len, &noise, &noise_len);
+
+ if (!err)
+ {
+ inf->stopped = !!(pi->state & PI_STOPPED);
+ inf->nomsg = !!(pi->state & PI_NOMSG);
+ if (inf->nomsg)
+ inf->traced = !!(pi->state & PI_TRACED);
+ vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len);
+ if (noise_len > 0)
+ vm_deallocate (mach_task_self (), (vm_address_t) noise, noise_len);
+ }
+}
+
+/* Validates INF's task suspend count. If it's higher than we expect,
+ verify with the user before `stealing' the extra count. */
+static void
+inf_validate_task_sc (struct inf *inf)
+{
+ char *noise;
+ mach_msg_type_number_t noise_len = 0;
+ struct procinfo *pi;
+ mach_msg_type_number_t pi_len = 0;
+ int info_flags = PI_FETCH_TASKINFO;
+ int suspend_count = -1;
+ error_t err;
+
+ retry:
+ err = proc_getprocinfo (proc_server, inf->pid, &info_flags,
+ (procinfo_t *) &pi, &pi_len, &noise, &noise_len);
+ if (err)
+ {
+ inf->task->dead = 1; /* oh well */
+ return;
+ }
+
+ if (inf->task->cur_sc < pi->taskinfo.suspend_count && suspend_count == -1)
+ {
+ /* The proc server might have suspended the task while stopping
+ it. This happens when the task is handling a traced signal.
+ Refetch the suspend count. The proc server should be
+ finished stopping the task by now. */
+ suspend_count = pi->taskinfo.suspend_count;
+ goto retry;
+ }
+
+ suspend_count = pi->taskinfo.suspend_count;
+
+ vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len);
+ if (noise_len > 0)
+ vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len);
+
+ if (inf->task->cur_sc < suspend_count)
+ {
+ int abort;
+
+ target_terminal_ours (); /* Allow I/O. */
+ abort = !query ("Pid %d has an additional task suspend count of %d;"
+ " clear it? ", inf->pid,
+ suspend_count - inf->task->cur_sc);
+ target_terminal_inferior (); /* Give it back to the child. */
+
+ if (abort)
+ error ("Additional task suspend count left untouched.");
+
+ inf->task->cur_sc = suspend_count;
+ }
+}
+
+/* Turns tracing for INF on or off, depending on ON, unless it already
+ is. If INF is running, the resume_sc count of INF's threads will
+ be modified, and the signal thread will briefly be run to change
+ the trace state. */
+void
+inf_set_traced (struct inf *inf, int on)
+{
+ if (on == inf->traced)
+ return;
+
+ if (inf->task && !inf->task->dead)
+ /* Make it take effect immediately. */
+ {
+ sigset_t mask = on ? ~(sigset_t) 0 : 0;
+ error_t err =
+ INF_RESUME_MSGPORT_RPC (inf, msg_set_init_int (msgport, refport,
+ INIT_TRACEMASK, mask));
+ if (err == EIEIO)
+ {
+ if (on)
+ warning ("Can't modify tracing state for pid %d: %s",
+ inf->pid, "No signal thread");
+ inf->traced = on;
+ }
+ else if (err)
+ warning ("Can't modify tracing state for pid %d: %s",
+ inf->pid, safe_strerror (err));
+ else
+ inf->traced = on;
+ }
+ else
+ inf->traced = on;
+}
+
+
+/* Makes all the real suspend count deltas of all the procs in INF
+ match the desired values. Careful to always do thread/task suspend
+ counts in the safe order. Returns true if at least one thread is
+ thought to be running. */
+int
+inf_update_suspends (struct inf *inf)
+{
+ struct proc *task = inf->task;
+ /* We don't have to update INF->threads even though we're iterating over it
+ because we'll change a thread only if it already has an existing proc
+ entry. */
+
+ inf_debug (inf, "updating suspend counts");
+
+ if (task)
+ {
+ struct proc *thread;
+ int task_running = (task->sc == 0), thread_running = 0;
+
+ if (task->sc > task->cur_sc)
+ /* The task is becoming _more_ suspended; do before any threads. */
+ task_running = proc_update_sc (task);
+
+ if (inf->pending_execs)
+ /* When we're waiting for an exec, things may be happening behind our
+ back, so be conservative. */
+ thread_running = 1;
+
+ /* Do all the thread suspend counts. */
+ for (thread = inf->threads; thread; thread = thread->next)
+ thread_running |= proc_update_sc (thread);
+
+ if (task->sc != task->cur_sc)
+ /* We didn't do the task first, because we wanted to wait for the
+ threads; do it now. */
+ task_running = proc_update_sc (task);
+
+ inf_debug (inf, "%srunning...",
+ (thread_running && task_running) ? "" : "not ");
+
+ inf->running = thread_running && task_running;
+
+ /* Once any thread has executed some code, we can't depend on the
+ threads list any more. */
+ if (inf->running)
+ inf->threads_up_to_date = 0;
+
+ return inf->running;
+ }
+
+ return 0;
+}
+
+
+/* Converts a GDB pid to a struct proc. */
+struct proc *
+inf_tid_to_thread (struct inf *inf, int tid)
+{
+ struct proc *thread = inf->threads;
+
+ while (thread)
+ if (thread->tid == tid)
+ return thread;
+ else
+ thread = thread->next;
+ return 0;
+}
+
+/* Converts a thread port to a struct proc. */
+struct proc *
+inf_port_to_thread (struct inf *inf, mach_port_t port)
+{
+ struct proc *thread = inf->threads;
+ while (thread)
+ if (thread->port == port)
+ return thread;
+ else
+ thread = thread->next;
+ return 0;
+}
+
+
+/* Make INF's list of threads be consistent with reality of TASK. */
+void
+inf_validate_procs (struct inf *inf)
+{
+ thread_array_t threads;
+ mach_msg_type_number_t num_threads, i;
+ struct proc *task = inf->task;
+
+ /* If no threads are currently running, this function will guarantee that
+ things are up to date. The exception is if there are zero threads --
+ then it is almost certainly in an odd state, and probably some outside
+ agent will create threads. */
+ inf->threads_up_to_date = inf->threads ? !inf->running : 0;
+
+ if (task)
+ {
+ error_t err = task_threads (task->port, &threads, &num_threads);
+ inf_debug (inf, "fetching threads");
+ if (err)
+ /* TASK must be dead. */
+ {
+ task->dead = 1;
+ task = 0;
+ }
+ }
+
+ if (!task)
+ {
+ num_threads = 0;
+ inf_debug (inf, "no task");
+ }
+
+ {
+ /* Make things normally linear. */
+ mach_msg_type_number_t search_start = 0;
+ /* Which thread in PROCS corresponds to each task thread, & the task. */
+ struct proc *matched[num_threads + 1];
+ /* The last thread in INF->threads, so we can add to the end. */
+ struct proc *last = 0;
+ /* The current thread we're considering. */
+ struct proc *thread = inf->threads;
+
+ bzero (matched, sizeof (matched));
+
+ while (thread)
+ {
+ mach_msg_type_number_t left;
+
+ for (i = search_start, left = num_threads; left; i++, left--)
+ {
+ if (i >= num_threads)
+ i -= num_threads; /* I wrapped around. */
+ if (thread->port == threads[i])
+ /* We already know about this thread. */
+ {
+ matched[i] = thread;
+ last = thread;
+ thread = thread->next;
+ search_start++;
+ break;
+ }
+ }
+
+ if (!left)
+ {
+ proc_debug (thread, "died!");
+ thread->port = MACH_PORT_NULL;
+ thread = _proc_free (thread); /* THREAD is dead. */
+ (last ? last->next : inf->threads) = thread;
+ }
+ }
+
+ for (i = 0; i < num_threads; i++)
+ {
+ if (matched[i])
+ /* Throw away the duplicate send right. */
+ mach_port_deallocate (mach_task_self (), threads[i]);
+ else
+ /* THREADS[I] is a thread we don't know about yet! */
+ {
+ thread = make_proc (inf, threads[i], next_thread_id++);
+ (last ? last->next : inf->threads) = thread;
+ last = thread;
+ proc_debug (thread, "new thread: %d", threads[i]);
+ add_thread (pid_to_ptid (thread->tid)); /* Tell GDB's generic thread code. */
+ }
+ }
+
+ vm_deallocate (mach_task_self (),
+ (vm_address_t) threads, (num_threads * sizeof (thread_t)));
+ }
+}
+
+
+/* Makes sure that INF's thread list is synced with the actual process. */
+inline int
+inf_update_procs (struct inf *inf)
+{
+ if (!inf->task)
+ return 0;
+ if (!inf->threads_up_to_date)
+ inf_validate_procs (inf);
+ return !!inf->task;
+}
+
+/* Sets the resume_sc of each thread in inf. That of RUN_THREAD is set to 0,
+ and others are set to their run_sc if RUN_OTHERS is true, and otherwise
+ their pause_sc. */
+inline void
+inf_set_threads_resume_sc (struct inf *inf,
+ struct proc *run_thread, int run_others)
+{
+ struct proc *thread;
+ inf_update_procs (inf);
+ for (thread = inf->threads; thread; thread = thread->next)
+ if (thread == run_thread)
+ thread->resume_sc = 0;
+ else if (run_others)
+ thread->resume_sc = thread->run_sc;
+ else
+ thread->resume_sc = thread->pause_sc;
+}
+
+
+/* Cause INF to continue execution immediately; individual threads may still
+ be suspended (but their suspend counts will be updated). */
+inline void
+inf_resume (struct inf *inf)
+{
+ struct proc *thread;
+
+ inf_update_procs (inf);
+
+ for (thread = inf->threads; thread; thread = thread->next)
+ thread->sc = thread->resume_sc;
+
+ if (inf->task)
+ {
+ if (!inf->pending_execs)
+ /* Try to make sure our task count is correct -- in the case where
+ we're waiting for an exec though, things are too volatile, so just
+ assume things will be reasonable (which they usually will be). */
+ inf_validate_task_sc (inf);
+ inf->task->sc = 0;
+ }
+
+ inf_update_suspends (inf);
+}
+
+/* Cause INF to stop execution immediately; individual threads may still
+ be running. */
+inline void
+inf_suspend (struct inf *inf)
+{
+ struct proc *thread;
+
+ inf_update_procs (inf);
+
+ for (thread = inf->threads; thread; thread = thread->next)
+ thread->sc = thread->pause_sc;
+
+ if (inf->task)
+ inf->task->sc = inf->pause_sc;
+
+ inf_update_suspends (inf);
+}
+
+
+/* INF has one thread PROC that is in single-stepping mode. This
+ function changes it to be PROC, changing any old step_thread to be
+ a normal one. A PROC of 0 clears any existing value. */
+void
+inf_set_step_thread (struct inf *inf, struct proc *thread)
+{
+ gdb_assert (!thread || proc_is_thread (thread));
+
+ if (thread)
+ inf_debug (inf, "setting step thread: %d/%d", inf->pid, thread->tid);
+ else
+ inf_debug (inf, "clearing step thread");
+
+ if (inf->step_thread != thread)
+ {
+ if (inf->step_thread && inf->step_thread->port != MACH_PORT_NULL)
+ if (!proc_trace (inf->step_thread, 0))
+ return;
+ if (thread && proc_trace (thread, 1))
+ inf->step_thread = thread;
+ else
+ inf->step_thread = 0;
+ }
+}
+
+
+/* Set up the thread resume_sc's so that only the signal thread is running
+ (plus whatever other thread are set to always run). Returns true if we
+ did so, or false if we can't find a signal thread. */
+inline int
+inf_set_threads_resume_sc_for_signal_thread (struct inf *inf)
+{
+ if (inf->signal_thread)
+ {
+ inf_set_threads_resume_sc (inf, inf->signal_thread, 0);
+ return 1;
+ }
+ else
+ return 0;
+}
+
+static void
+inf_update_signal_thread (struct inf *inf)
+{
+ /* XXX for now we assume that if there's a msgport, the 2nd thread is
+ the signal thread. */
+ inf->signal_thread = inf->threads ? inf->threads->next : 0;
+}
+
+
+/* Detachs from INF's inferior task, letting it run once again... */
+void
+inf_detach (struct inf *inf)
+{
+ struct proc *task = inf->task;
+
+ inf_debug (inf, "detaching...");
+
+ inf_clear_wait (inf);
+ inf_set_step_thread (inf, 0);
+
+ if (task)
+ {
+ struct proc *thread;
+
+ inf_validate_procinfo (inf);
+
+ inf_set_traced (inf, 0);
+ if (inf->stopped)
+ {
+ if (inf->nomsg)
+ inf_continue (inf);
+ else
+ inf_signal (inf, TARGET_SIGNAL_0);
+ }
+
+ proc_restore_exc_port (task);
+ task->sc = inf->detach_sc;
+
+ for (thread = inf->threads; thread; thread = thread->next)
+ {
+ proc_restore_exc_port (thread);
+ thread->sc = thread->detach_sc;
+ }
+
+ inf_update_suspends (inf);
+ }
+
+ inf_cleanup (inf);
+}
+
+/* Attaches INF to the process with process id PID, returning it in a
+ suspended state suitable for debugging. */
+void
+inf_attach (struct inf *inf, int pid)
+{
+ inf_debug (inf, "attaching: %d", pid);
+
+ if (inf->pid)
+ inf_detach (inf);
+
+ inf_startup (inf, pid);
+}
+
+
+/* Makes sure that we've got our exception ports entrenched in the process. */
+void
+inf_steal_exc_ports (struct inf *inf)
+{
+ struct proc *thread;
+
+ inf_debug (inf, "stealing exception ports");
+
+ inf_set_step_thread (inf, 0); /* The step thread is special. */
+
+ proc_steal_exc_port (inf->task, inf->event_port);
+ for (thread = inf->threads; thread; thread = thread->next)
+ proc_steal_exc_port (thread, MACH_PORT_NULL);
+}
+
+/* Makes sure the process has its own exception ports. */
+void
+inf_restore_exc_ports (struct inf *inf)
+{
+ struct proc *thread;
+
+ inf_debug (inf, "restoring exception ports");
+
+ inf_set_step_thread (inf, 0); /* The step thread is special. */
+
+ proc_restore_exc_port (inf->task);
+ for (thread = inf->threads; thread; thread = thread->next)
+ proc_restore_exc_port (thread);
+}
+
+
+/* Deliver signal SIG to INF. If INF is stopped, delivering a signal, even
+ signal 0, will continue it. INF is assumed to be in a paused state, and
+ the resume_sc's of INF's threads may be affected. */
+void
+inf_signal (struct inf *inf, enum target_signal sig)
+{
+ error_t err = 0;
+ int host_sig = target_signal_to_host (sig);
+
+#define NAME target_signal_to_name (sig)
+
+ if (host_sig >= _NSIG)
+ /* A mach exception. Exceptions are encoded in the signal space by
+ putting them after _NSIG; this assumes they're positive (and not
+ extremely large)! */
+ {
+ struct inf_wait *w = &inf->wait;
+ if (w->status.kind == TARGET_WAITKIND_STOPPED
+ && w->status.value.sig == sig
+ && w->thread && !w->thread->aborted)
+ /* We're passing through the last exception we received. This is
+ kind of bogus, because exceptions are per-thread whereas gdb
+ treats signals as per-process. We just forward the exception to
+ the correct handler, even it's not for the same thread as TID --
+ i.e., we pretend it's global. */
+ {
+ struct exc_state *e = &w->exc;
+ inf_debug (inf, "passing through exception:"
+ " task = %d, thread = %d, exc = %d"
+ ", code = %d, subcode = %d",
+ w->thread->port, inf->task->port,
+ e->exception, e->code, e->subcode);
+ err =
+ exception_raise_request (e->handler,
+ e->reply, MACH_MSG_TYPE_MOVE_SEND_ONCE,
+ w->thread->port, inf->task->port,
+ e->exception, e->code, e->subcode);
+ }
+ else
+ error ("Can't forward spontaneous exception (%s).", NAME);
+ }
+ else
+ /* A Unix signal. */
+ if (inf->stopped)
+ /* The process is stopped and expecting a signal. Just send off a
+ request and let it get handled when we resume everything. */
+ {
+ inf_debug (inf, "sending %s to stopped process", NAME);
+ err =
+ INF_MSGPORT_RPC (inf,
+ msg_sig_post_untraced_request (msgport,
+ inf->event_port,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE,
+ host_sig, 0,
+ refport));
+ if (!err)
+ /* Posting an untraced signal automatically continues it.
+ We clear this here rather than when we get the reply
+ because we'd rather assume it's not stopped when it
+ actually is, than the reverse. */
+ inf->stopped = 0;
+ }
+ else
+ /* It's not expecting it. We have to let just the signal thread
+ run, and wait for it to get into a reasonable state before we
+ can continue the rest of the process. When we finally resume the
+ process the signal we request will be the very first thing that
+ happens. */
+ {
+ inf_debug (inf, "sending %s to unstopped process"
+ " (so resuming signal thread)", NAME);
+ err =
+ INF_RESUME_MSGPORT_RPC (inf,
+ msg_sig_post_untraced (msgport, host_sig,
+ 0, refport));
+ }
+
+ if (err == EIEIO)
+ /* Can't do too much... */
+ warning ("Can't deliver signal %s: No signal thread.", NAME);
+ else if (err)
+ warning ("Delivering signal %s: %s", NAME, safe_strerror (err));
+
+#undef NAME
+}
+
+
+/* Continue INF without delivering a signal. This is meant to be used
+ when INF does not have a message port. */
+void
+inf_continue (struct inf *inf)
+{
+ process_t proc;
+ error_t err = proc_pid2proc (proc_server, inf->pid, &proc);
+
+ if (!err)
+ {
+ inf_debug (inf, "continuing process");
+
+ err = proc_mark_cont (proc);
+ if (!err)
+ {
+ struct proc *thread;
+
+ for (thread = inf->threads; thread; thread = thread->next)
+ thread_resume (thread->port);
+
+ inf->stopped = 0;
+ }
+ }
+
+ if (err)
+ warning ("Can't continue process: %s", safe_strerror (err));
+}
+
+
+/* The inferior used for all gdb target ops. */
+struct inf *current_inferior = 0;
+
+/* The inferior being waited for by gnu_wait. Since GDB is decidely not
+ multi-threaded, we don't bother to lock this. */
+struct inf *waiting_inf;
+
+/* Wait for something to happen in the inferior, returning what in STATUS. */
+static ptid_t
+gnu_wait (ptid_t tid, struct target_waitstatus *status)
+{
+ struct msg
+ {
+ mach_msg_header_t hdr;
+ mach_msg_type_t type;
+ int data[8000];
+ } msg;
+ error_t err;
+ struct proc *thread;
+ struct inf *inf = current_inferior;
+
+ extern int exc_server (mach_msg_header_t *, mach_msg_header_t *);
+ extern int msg_reply_server (mach_msg_header_t *, mach_msg_header_t *);
+ extern int notify_server (mach_msg_header_t *, mach_msg_header_t *);
+ extern int process_reply_server (mach_msg_header_t *, mach_msg_header_t *);
+
+ gdb_assert (inf->task);
+
+ if (!inf->threads && !inf->pending_execs)
+ /* No threads! Assume that maybe some outside agency is frobbing our
+ task, and really look for new threads. If we can't find any, just tell
+ the user to try again later. */
+ {
+ inf_validate_procs (inf);
+ if (!inf->threads && !inf->task->dead)
+ error ("There are no threads; try again later.");
+ }
+
+ waiting_inf = inf;
+
+ inf_debug (inf, "waiting for: %d", PIDGET (tid));
+
+rewait:
+ if (proc_wait_pid != inf->pid && !inf->no_wait)
+ /* Always get information on events from the proc server. */
+ {
+ inf_debug (inf, "requesting wait on pid %d", inf->pid);
+
+ if (proc_wait_pid)
+ /* The proc server is single-threaded, and only allows a single
+ outstanding wait request, so we have to cancel the previous one. */
+ {
+ inf_debug (inf, "cancelling previous wait on pid %d", proc_wait_pid);
+ interrupt_operation (proc_server, 0);
+ }
+
+ err =
+ proc_wait_request (proc_server, inf->event_port, inf->pid, WUNTRACED);
+ if (err)
+ warning ("wait request failed: %s", safe_strerror (err));
+ else
+ {
+ inf_debug (inf, "waits pending: %d", proc_waits_pending);
+ proc_wait_pid = inf->pid;
+ /* Even if proc_waits_pending was > 0 before, we still won't
+ get any other replies, because it was either from a
+ different INF, or a different process attached to INF --
+ and the event port, which is the wait reply port, changes
+ when you switch processes. */
+ proc_waits_pending = 1;
+ }
+ }
+
+ inf_clear_wait (inf);
+
+ /* What can happen? (1) Dead name notification; (2) Exceptions arrive;
+ (3) wait reply from the proc server. */
+
+ inf_debug (inf, "waiting for an event...");
+ err = mach_msg (&msg.hdr, MACH_RCV_MSG | MACH_RCV_INTERRUPT,
+ 0, sizeof (struct msg), inf->event_port,
+ MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+
+ /* Re-suspend the task. */
+ inf_suspend (inf);
+
+ if (!inf->task && inf->pending_execs)
+ /* When doing an exec, it's possible that the old task wasn't reused
+ (e.g., setuid execs). So if the task seems to have disappeared,
+ attempt to refetch it, as the pid should still be the same. */
+ inf_set_pid (inf, inf->pid);
+
+ if (err == EMACH_RCV_INTERRUPTED)
+ inf_debug (inf, "interrupted");
+ else if (err)
+ error ("Couldn't wait for an event: %s", safe_strerror (err));
+ else
+ {
+ struct
+ {
+ mach_msg_header_t hdr;
+ mach_msg_type_t err_type;
+ kern_return_t err;
+ char noise[200];
+ }
+ reply;
+
+ inf_debug (inf, "event: msgid = %d", msg.hdr.msgh_id);
+
+ /* Handle what we got. */
+ if (!notify_server (&msg.hdr, &reply.hdr)
+ && !exc_server (&msg.hdr, &reply.hdr)
+ && !process_reply_server (&msg.hdr, &reply.hdr)
+ && !msg_reply_server (&msg.hdr, &reply.hdr))
+ /* Whatever it is, it's something strange. */
+ error ("Got a strange event, msg id = %d.", msg.hdr.msgh_id);
+
+ if (reply.err)
+ error ("Handling event, msgid = %d: %s",
+ msg.hdr.msgh_id, safe_strerror (reply.err));
+ }
+
+ if (inf->pending_execs)
+ /* We're waiting for the inferior to finish execing. */
+ {
+ struct inf_wait *w = &inf->wait;
+ enum target_waitkind kind = w->status.kind;
+
+ if (kind == TARGET_WAITKIND_SPURIOUS)
+ /* Since gdb is actually counting the number of times the inferior
+ stops, expecting one stop per exec, we only return major events
+ while execing. */
+ {
+ w->suppress = 1;
+ inf_debug (inf, "pending_execs = %d, ignoring minor event",
+ inf->pending_execs);
+ }
+ else if (kind == TARGET_WAITKIND_STOPPED
+ && w->status.value.sig == TARGET_SIGNAL_TRAP)
+ /* Ah hah! A SIGTRAP from the inferior while starting up probably
+ means we've succesfully completed an exec! */
+ {
+ if (--inf->pending_execs == 0)
+ /* We're done! */
+ {
+#if 0 /* do we need this? */
+ prune_threads (1); /* Get rid of the old shell threads */
+ renumber_threads (0); /* Give our threads reasonable names. */
+#endif
+ }
+ inf_debug (inf, "pending exec completed, pending_execs => %d",
+ inf->pending_execs);
+ }
+ else if (kind == TARGET_WAITKIND_STOPPED)
+ /* It's possible that this signal is because of a crashed process
+ being handled by the hurd crash server; in this case, the process
+ will have an extra task suspend, which we need to know about.
+ Since the code in inf_resume that normally checks for this is
+ disabled while INF->pending_execs, we do the check here instead. */
+ inf_validate_task_sc (inf);
+ }
+
+ if (inf->wait.suppress)
+ /* Some totally spurious event happened that we don't consider
+ worth returning to gdb. Just keep waiting. */
+ {
+ inf_debug (inf, "suppressing return, rewaiting...");
+ inf_resume (inf);
+ goto rewait;
+ }
+
+ /* Pass back out our results. */
+ bcopy (&inf->wait.status, status, sizeof (*status));
+
+ thread = inf->wait.thread;
+ if (thread)
+ tid = pid_to_ptid (thread->tid);
+ else
+ thread = inf_tid_to_thread (inf, PIDGET (tid));
+
+ if (!thread || thread->port == MACH_PORT_NULL)
+ {
+ /* TID is dead; try and find a new thread. */
+ if (inf_update_procs (inf) && inf->threads)
+ tid = pid_to_ptid (inf->threads->tid); /* The first available thread. */
+ else
+ tid = inferior_ptid; /* let wait_for_inferior handle exit case */
+ }
+
+ if (thread && PIDGET (tid) >= 0 && status->kind != TARGET_WAITKIND_SPURIOUS
+ && inf->pause_sc == 0 && thread->pause_sc == 0)
+ /* If something actually happened to THREAD, make sure we
+ suspend it. */
+ {
+ thread->sc = 1;
+ inf_update_suspends (inf);
+ }
+
+ inf_debug (inf, "returning tid = %d, status = %s (%d)", PIDGET (tid),
+ status->kind == TARGET_WAITKIND_EXITED ? "EXITED"
+ : status->kind == TARGET_WAITKIND_STOPPED ? "STOPPED"
+ : status->kind == TARGET_WAITKIND_SIGNALLED ? "SIGNALLED"
+ : status->kind == TARGET_WAITKIND_LOADED ? "LOADED"
+ : status->kind == TARGET_WAITKIND_SPURIOUS ? "SPURIOUS"
+ : "?",
+ status->value.integer);
+
+ return tid;
+}
+
+
+/* The rpc handler called by exc_server. */
+error_t
+S_exception_raise_request (mach_port_t port, mach_port_t reply_port,
+ thread_t thread_port, task_t task_port,
+ int exception, int code, int subcode)
+{
+ struct inf *inf = waiting_inf;
+ struct proc *thread = inf_port_to_thread (inf, thread_port);
+
+ inf_debug (waiting_inf,
+ "thread = %d, task = %d, exc = %d, code = %d, subcode = %d",
+ thread_port, task_port, exception, code, subcode);
+
+ if (!thread)
+ /* We don't know about thread? */
+ {
+ inf_update_procs (inf);
+ thread = inf_port_to_thread (inf, thread_port);
+ if (!thread)
+ /* Give up, the generating thread is gone. */
+ return 0;
+ }
+
+ mach_port_deallocate (mach_task_self (), thread_port);
+ mach_port_deallocate (mach_task_self (), task_port);
+
+ if (!thread->aborted)
+ /* THREAD hasn't been aborted since this exception happened (abortion
+ clears any exception state), so it must be real. */
+ {
+ /* Store away the details; this will destroy any previous info. */
+ inf->wait.thread = thread;
+
+ inf->wait.status.kind = TARGET_WAITKIND_STOPPED;
+
+ if (exception == EXC_BREAKPOINT)
+ /* GDB likes to get SIGTRAP for breakpoints. */
+ {
+ inf->wait.status.value.sig = TARGET_SIGNAL_TRAP;
+ mach_port_deallocate (mach_task_self (), reply_port);
+ }
+ else
+ /* Record the exception so that we can forward it later. */
+ {
+ if (thread->exc_port == port)
+ {
+ inf_debug (waiting_inf, "Handler is thread exception port <%d>",
+ thread->saved_exc_port);
+ inf->wait.exc.handler = thread->saved_exc_port;
+ }
+ else
+ {
+ inf_debug (waiting_inf, "Handler is task exception port <%d>",
+ inf->task->saved_exc_port);
+ inf->wait.exc.handler = inf->task->saved_exc_port;
+ gdb_assert (inf->task->exc_port == port);
+ }
+ if (inf->wait.exc.handler != MACH_PORT_NULL)
+ /* Add a reference to the exception handler. */
+ mach_port_mod_refs (mach_task_self (),
+ inf->wait.exc.handler, MACH_PORT_RIGHT_SEND,
+ 1);
+
+ inf->wait.exc.exception = exception;
+ inf->wait.exc.code = code;
+ inf->wait.exc.subcode = subcode;
+ inf->wait.exc.reply = reply_port;
+
+ /* Exceptions are encoded in the signal space by putting them after
+ _NSIG; this assumes they're positive (and not extremely large)! */
+ inf->wait.status.value.sig =
+ target_signal_from_host (_NSIG + exception);
+ }
+ }
+ else
+ /* A supppressed exception, which ignore. */
+ {
+ inf->wait.suppress = 1;
+ mach_port_deallocate (mach_task_self (), reply_port);
+ }
+
+ return 0;
+}
+
+
+/* Fill in INF's wait field after a task has died without giving us more
+ detailed information. */
+void
+inf_task_died_status (struct inf *inf)
+{
+ warning ("Pid %d died with unknown exit status, using SIGKILL.", inf->pid);
+ inf->wait.status.kind = TARGET_WAITKIND_SIGNALLED;
+ inf->wait.status.value.sig = TARGET_SIGNAL_KILL;
+}
+
+/* Notify server routines. The only real one is dead name notification. */
+error_t
+do_mach_notify_dead_name (mach_port_t notify, mach_port_t dead_port)
+{
+ struct inf *inf = waiting_inf;
+
+ inf_debug (waiting_inf, "port = %d", dead_port);
+
+ if (inf->task && inf->task->port == dead_port)
+ {
+ proc_debug (inf->task, "is dead");
+ inf->task->port = MACH_PORT_NULL;
+ if (proc_wait_pid == inf->pid)
+ /* We have a wait outstanding on the process, which will return more
+ detailed information, so delay until we get that. */
+ inf->wait.suppress = 1;
+ else
+ /* We never waited for the process (maybe it wasn't a child), so just
+ pretend it got a SIGKILL. */
+ inf_task_died_status (inf);
+ }
+ else
+ {
+ struct proc *thread = inf_port_to_thread (inf, dead_port);
+ if (thread)
+ {
+ proc_debug (thread, "is dead");
+ thread->port = MACH_PORT_NULL;
+ }
+
+ if (inf->task->dead)
+ /* Since the task is dead, its threads are dying with it. */
+ inf->wait.suppress = 1;
+ }
+
+ mach_port_deallocate (mach_task_self (), dead_port);
+ inf->threads_up_to_date = 0; /* Just in case */
+
+ return 0;
+}
+
+
+static error_t
+ill_rpc (char *fun)
+{
+ warning ("illegal rpc: %s", fun);
+ return 0;
+}
+
+error_t
+do_mach_notify_no_senders (mach_port_t notify, mach_port_mscount_t count)
+{
+ return ill_rpc (__FUNCTION__);
+}
+
+error_t
+do_mach_notify_port_deleted (mach_port_t notify, mach_port_t name)
+{
+ return ill_rpc (__FUNCTION__);
+}
+
+error_t
+do_mach_notify_msg_accepted (mach_port_t notify, mach_port_t name)
+{
+ return ill_rpc (__FUNCTION__);
+}
+
+error_t
+do_mach_notify_port_destroyed (mach_port_t notify, mach_port_t name)
+{
+ return ill_rpc (__FUNCTION__);
+}
+
+error_t
+do_mach_notify_send_once (mach_port_t notify)
+{
+ return ill_rpc (__FUNCTION__);
+}
+
+
+/* Process_reply server routines. We only use process_wait_reply. */
+
+error_t
+S_proc_wait_reply (mach_port_t reply, error_t err,
+ int status, int sigcode, rusage_t rusage, pid_t pid)
+{
+ struct inf *inf = waiting_inf;
+
+ inf_debug (inf, "err = %s, pid = %d, status = 0x%x, sigcode = %d",
+ err ? safe_strerror (err) : "0", pid, status, sigcode);
+
+ if (err && proc_wait_pid && (!inf->task || !inf->task->port))
+ /* Ack. The task has died, but the task-died notification code didn't
+ tell anyone because it thought a more detailed reply from the
+ procserver was forthcoming. However, we now learn that won't
+ happen... So we have to act like the task just died, and this time,
+ tell the world. */
+ inf_task_died_status (inf);
+
+ if (--proc_waits_pending == 0)
+ /* PROC_WAIT_PID represents the most recent wait. We will always get
+ replies in order because the proc server is single threaded. */
+ proc_wait_pid = 0;
+
+ inf_debug (inf, "waits pending now: %d", proc_waits_pending);
+
+ if (err)
+ {
+ if (err != EINTR)
+ {
+ warning ("Can't wait for pid %d: %s", inf->pid, safe_strerror (err));
+ inf->no_wait = 1;
+
+ /* Since we can't see the inferior's signals, don't trap them. */
+ inf_set_traced (inf, 0);
+ }
+ }
+ else if (pid == inf->pid)
+ {
+ store_waitstatus (&inf->wait.status, status);
+ if (inf->wait.status.kind == TARGET_WAITKIND_STOPPED)
+ /* The process has sent us a signal, and stopped itself in a sane
+ state pending our actions. */
+ {
+ inf_debug (inf, "process has stopped itself");
+ inf->stopped = 1;
+ }
+ }
+ else
+ inf->wait.suppress = 1; /* Something odd happened. Ignore. */
+
+ return 0;
+}
+
+error_t
+S_proc_setmsgport_reply (mach_port_t reply, error_t err,
+ mach_port_t old_msg_port)
+{
+ return ill_rpc (__FUNCTION__);
+}
+
+error_t
+S_proc_getmsgport_reply (mach_port_t reply, error_t err, mach_port_t msg_port)
+{
+ return ill_rpc (__FUNCTION__);
+}
+
+
+/* Msg_reply server routines. We only use msg_sig_post_untraced_reply. */
+
+error_t
+S_msg_sig_post_untraced_reply (mach_port_t reply, error_t err)
+{
+ struct inf *inf = waiting_inf;
+
+ if (err == EBUSY)
+ /* EBUSY is what we get when the crash server has grabbed control of the
+ process and doesn't like what signal we tried to send it. Just act
+ like the process stopped (using a signal of 0 should mean that the
+ *next* time the user continues, it will pass signal 0, which the crash
+ server should like). */
+ {
+ inf->wait.status.kind = TARGET_WAITKIND_STOPPED;
+ inf->wait.status.value.sig = TARGET_SIGNAL_0;
+ }
+ else if (err)
+ warning ("Signal delivery failed: %s", safe_strerror (err));
+
+ if (err)
+ /* We only get this reply when we've posted a signal to a process which we
+ thought was stopped, and which we expected to continue after the signal.
+ Given that the signal has failed for some reason, it's reasonable to
+ assume it's still stopped. */
+ inf->stopped = 1;
+ else
+ inf->wait.suppress = 1;
+
+ return 0;
+}
+
+error_t
+S_msg_sig_post_reply (mach_port_t reply, error_t err)
+{
+ return ill_rpc (__FUNCTION__);
+}
+
+
+/* Returns the number of messages queued for the receive right PORT. */
+static mach_port_msgcount_t
+port_msgs_queued (mach_port_t port)
+{
+ struct mach_port_status status;
+ error_t err =
+ mach_port_get_receive_status (mach_task_self (), port, &status);
+
+ if (err)
+ return 0;
+ else
+ return status.mps_msgcount;
+}
+
+
+/* Resume execution of the inferior process.
+
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal.
+
+ TID STEP:
+ -1 true Single step the current thread allowing other threads to run.
+ -1 false Continue the current thread allowing other threads to run.
+ X true Single step the given thread, don't allow any others to run.
+ X false Continue the given thread, do not allow any others to run.
+ (Where X, of course, is anything except -1)
+
+ Note that a resume may not `take' if there are pending exceptions/&c
+ still unprocessed from the last resume we did (any given resume may result
+ in multiple events returned by wait).
+ */
+static void
+gnu_resume (ptid_t tid, int step, enum target_signal sig)
+{
+ struct proc *step_thread = 0;
+ struct inf *inf = current_inferior;
+
+ inf_debug (inf, "tid = %d, step = %d, sig = %d", PIDGET (tid), step, sig);
+
+ inf_validate_procinfo (inf);
+
+ if (sig != TARGET_SIGNAL_0 || inf->stopped)
+ {
+ if (sig == TARGET_SIGNAL_0 && inf->nomsg)
+ inf_continue (inf);
+ else
+ inf_signal (inf, sig);
+ }
+ else if (inf->wait.exc.reply != MACH_PORT_NULL)
+ /* We received an exception to which we have chosen not to forward, so
+ abort the faulting thread, which will perhaps retake it. */
+ {
+ proc_abort (inf->wait.thread, 1);
+ warning ("Aborting %s with unforwarded exception %s.",
+ proc_string (inf->wait.thread),
+ target_signal_to_name (inf->wait.status.value.sig));
+ }
+
+ if (port_msgs_queued (inf->event_port))
+ /* If there are still messages in our event queue, don't bother resuming
+ the process, as we're just going to stop it right away anyway. */
+ return;
+
+ inf_update_procs (inf);
+
+ if (PIDGET (tid) < 0)
+ /* Allow all threads to run, except perhaps single-stepping one. */
+ {
+ inf_debug (inf, "running all threads; tid = %d", PIDGET (inferior_ptid));
+ tid = inferior_ptid; /* What to step. */
+ inf_set_threads_resume_sc (inf, 0, 1);
+ }
+ else
+ /* Just allow a single thread to run. */
+ {
+ struct proc *thread = inf_tid_to_thread (inf, PIDGET (tid));
+ if (!thread)
+ error ("Can't run single thread id %d: no such thread!");
+ inf_debug (inf, "running one thread: %d/%d", inf->pid, thread->tid);
+ inf_set_threads_resume_sc (inf, thread, 0);
+ }
+
+ if (step)
+ {
+ step_thread = inf_tid_to_thread (inf, PIDGET (tid));
+ if (!step_thread)
+ warning ("Can't step thread id %d: no such thread.", PIDGET (tid));
+ else
+ inf_debug (inf, "stepping thread: %d/%d", inf->pid, step_thread->tid);
+ }
+ if (step_thread != inf->step_thread)
+ inf_set_step_thread (inf, step_thread);
+
+ inf_debug (inf, "here we go...");
+ inf_resume (inf);
+}
+
+
+static void
+gnu_kill_inferior (void)
+{
+ struct proc *task = current_inferior->task;
+ if (task)
+ {
+ proc_debug (task, "terminating...");
+ task_terminate (task->port);
+ inf_set_pid (current_inferior, -1);
+ }
+ target_mourn_inferior ();
+}
+
+/* Clean up after the inferior dies. */
+static void
+gnu_mourn_inferior (void)
+{
+ inf_debug (current_inferior, "rip");
+ inf_detach (current_inferior);
+ unpush_target (&gnu_ops);
+ generic_mourn_inferior ();
+}
+
+
+/* Fork an inferior process, and start debugging it. */
+
+/* Set INFERIOR_PID to the first thread available in the child, if any. */
+static int
+inf_pick_first_thread (void)
+{
+ if (current_inferior->task && current_inferior->threads)
+ /* The first thread. */
+ return current_inferior->threads->tid;
+ else
+ /* What may be the next thread. */
+ return next_thread_id;
+}
+
+static struct inf *
+cur_inf (void)
+{
+ if (!current_inferior)
+ current_inferior = make_inf ();
+ return current_inferior;
+}
+
+static void
+gnu_create_inferior (char *exec_file, char *allargs, char **env)
+{
+ struct inf *inf = cur_inf ();
+
+ void trace_me ()
+ {
+ /* We're in the child; make this process stop as soon as it execs. */
+ inf_debug (inf, "tracing self");
+ if (ptrace (PTRACE_TRACEME) != 0)
+ error ("ptrace (PTRACE_TRACEME) failed!");
+ }
+ void attach_to_child (int pid)
+ {
+ /* Attach to the now stopped child, which is actually a shell... */
+ inf_debug (inf, "attaching to child: %d", pid);
+
+ inf_attach (inf, pid);
+
+ attach_flag = 0;
+ push_target (&gnu_ops);
+
+ inf->pending_execs = 2;
+ inf->nomsg = 1;
+ inf->traced = 1;
+
+ /* Now let the child run again, knowing that it will stop immediately
+ because of the ptrace. */
+ inf_resume (inf);
+ inferior_ptid = pid_to_ptid (inf_pick_first_thread ());
+
+ startup_inferior (inf->pending_execs);
+ }
+
+ inf_debug (inf, "creating inferior");
+
+ fork_inferior (exec_file, allargs, env, trace_me, attach_to_child,
+ NULL, NULL);
+
+ inf_validate_procinfo (inf);
+ inf_update_signal_thread (inf);
+ inf_set_traced (inf, inf->want_signals);
+
+ /* Execing the process will have trashed our exception ports; steal them
+ back (or make sure they're restored if the user wants that). */
+ if (inf->want_exceptions)
+ inf_steal_exc_ports (inf);
+ else
+ inf_restore_exc_ports (inf);
+
+ /* Here we go! */
+ proceed ((CORE_ADDR) -1, 0, 0);
+}
+
+/* Mark our target-struct as eligible for stray "run" and "attach"
+ commands. */
+static int
+gnu_can_run (void)
+{
+ return 1;
+}
+
+
+#ifdef ATTACH_DETACH
+
+/* Attach to process PID, then initialize for debugging it
+ and wait for the trace-trap that results from attaching. */
+static void
+gnu_attach (char *args, int from_tty)
+{
+ int pid;
+ char *exec_file;
+ struct inf *inf = cur_inf ();
+
+ if (!args)
+ error_no_arg ("process-id to attach");
+
+ pid = atoi (args);
+
+ if (pid == getpid ()) /* Trying to masturbate? */
+ error ("I refuse to debug myself!");
+
+ if (from_tty)
+ {
+ exec_file = (char *) get_exec_file (0);
+
+ if (exec_file)
+ printf_unfiltered ("Attaching to program `%s', pid %d\n",
+ exec_file, pid);
+ else
+ printf_unfiltered ("Attaching to pid %d\n", pid);
+
+ gdb_flush (gdb_stdout);
+ }
+
+ inf_debug (inf, "attaching to pid: %d", pid);
+
+ inf_attach (inf, pid);
+ inf_update_procs (inf);
+
+ inferior_ptid = pid_to_ptid (inf_pick_first_thread ());
+
+ attach_flag = 1;
+ push_target (&gnu_ops);
+
+ /* We have to initialize the terminal settings now, since the code
+ below might try to restore them. */
+ target_terminal_init ();
+
+ /* If the process was stopped before we attached, make it continue the next
+ time the user does a continue. */
+ inf_validate_procinfo (inf);
+
+ inf_update_signal_thread (inf);
+ inf_set_traced (inf, inf->want_signals);
+
+#if 0 /* Do we need this? */
+ renumber_threads (0); /* Give our threads reasonable names. */
+#endif
+}
+
+
+/* Take a program previously attached to and detaches it.
+ The program resumes execution and will no longer stop
+ on signals, etc. We'd better not have left any breakpoints
+ in the program or it'll die when it hits one. For this
+ to work, it may be necessary for the process to have been
+ previously attached. It *might* work if the program was
+ started via fork. */
+static void
+gnu_detach (char *args, int from_tty)
+{
+ if (from_tty)
+ {
+ char *exec_file = get_exec_file (0);
+ if (exec_file)
+ printf_unfiltered ("Detaching from program `%s' pid %d\n",
+ exec_file, current_inferior->pid);
+ else
+ printf_unfiltered ("Detaching from pid %d\n", current_inferior->pid);
+ gdb_flush (gdb_stdout);
+ }
+
+ inf_detach (current_inferior);
+
+ inferior_ptid = null_ptid;
+
+ unpush_target (&gnu_ops); /* Pop out of handling an inferior */
+}
+#endif /* ATTACH_DETACH */
+
+
+static void
+gnu_terminal_init_inferior (void)
+{
+ gdb_assert (current_inferior);
+ terminal_init_inferior_with_pgrp (current_inferior->pid);
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+static void
+gnu_prepare_to_store (void)
+{
+#ifdef CHILD_PREPARE_TO_STORE
+ CHILD_PREPARE_TO_STORE ();
+#endif
+}
+
+static void
+gnu_open (char *arg, int from_tty)
+{
+ error ("Use the \"run\" command to start a Unix child process.");
+}
+
+static void
+gnu_stop (void)
+{
+ error ("to_stop target function not implemented");
+}
+
+static char *
+gnu_pid_to_exec_file (int pid)
+{
+ error ("to_pid_to_exec_file target function not implemented");
+ return NULL;
+}
+
+
+static int
+gnu_thread_alive (ptid_t tid)
+{
+ inf_update_procs (current_inferior);
+ return !!inf_tid_to_thread (current_inferior, PIDGET (tid));
+}
+
+
+/* Read inferior task's LEN bytes from ADDR and copy it to MYADDR in
+ gdb's address space. Return 0 on failure; number of bytes read
+ otherwise. */
+int
+gnu_read_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length)
+{
+ error_t err;
+ vm_address_t low_address = (vm_address_t) trunc_page (addr);
+ vm_size_t aligned_length =
+ (vm_size_t) round_page (addr + length) - low_address;
+ pointer_t copied;
+ int copy_count;
+
+ /* Get memory from inferior with page aligned addresses */
+ err = vm_read (task, low_address, aligned_length, &copied, &copy_count);
+ if (err)
+ return 0;
+
+ err = hurd_safe_copyin (myaddr, (void *) addr - low_address + copied, length);
+ if (err)
+ {
+ warning ("Read from inferior faulted: %s", safe_strerror (err));
+ length = 0;
+ }
+
+ err = vm_deallocate (mach_task_self (), copied, copy_count);
+ if (err)
+ warning ("gnu_read_inferior vm_deallocate failed: %s", safe_strerror (err));
+
+ return length;
+}
+
+#define CHK_GOTO_OUT(str,ret) \
+ do if (ret != KERN_SUCCESS) { errstr = #str; goto out; } while(0)
+
+struct vm_region_list
+{
+ struct vm_region_list *next;
+ vm_prot_t protection;
+ vm_address_t start;
+ vm_size_t length;
+};
+
+struct obstack region_obstack;
+
+/* Write gdb's LEN bytes from MYADDR and copy it to ADDR in inferior
+ task's address space. */
+int
+gnu_write_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length)
+{
+ error_t err = 0;
+ vm_address_t low_address = (vm_address_t) trunc_page (addr);
+ vm_size_t aligned_length =
+ (vm_size_t) round_page (addr + length) - low_address;
+ pointer_t copied;
+ int copy_count;
+ int deallocate = 0;
+
+ char *errstr = "Bug in gnu_write_inferior";
+
+ struct vm_region_list *region_element;
+ struct vm_region_list *region_head = (struct vm_region_list *) NULL;
+
+ /* Get memory from inferior with page aligned addresses */
+ err = vm_read (task,
+ low_address,
+ aligned_length,
+ &copied,
+ &copy_count);
+ CHK_GOTO_OUT ("gnu_write_inferior vm_read failed", err);
+
+ deallocate++;
+
+ err = hurd_safe_copyout ((void *) addr - low_address + copied,
+ myaddr, length);
+ CHK_GOTO_OUT ("Write to inferior faulted", err);
+
+ obstack_init (&region_obstack);
+
+ /* Do writes atomically.
+ First check for holes and unwritable memory. */
+ {
+ vm_size_t remaining_length = aligned_length;
+ vm_address_t region_address = low_address;
+
+ struct vm_region_list *scan;
+
+ while (region_address < low_address + aligned_length)
+ {
+ vm_prot_t protection;
+ vm_prot_t max_protection;
+ vm_inherit_t inheritance;
+ boolean_t shared;
+ mach_port_t object_name;
+ vm_offset_t offset;
+ vm_size_t region_length = remaining_length;
+ vm_address_t old_address = region_address;
+
+ err = vm_region (task,
+ &region_address,
+ &region_length,
+ &protection,
+ &max_protection,
+ &inheritance,
+ &shared,
+ &object_name,
+ &offset);
+ CHK_GOTO_OUT ("vm_region failed", err);
+
+ /* Check for holes in memory */
+ if (old_address != region_address)
+ {
+ warning ("No memory at 0x%x. Nothing written",
+ old_address);
+ err = KERN_SUCCESS;
+ length = 0;
+ goto out;
+ }
+
+ if (!(max_protection & VM_PROT_WRITE))
+ {
+ warning ("Memory at address 0x%x is unwritable. Nothing written",
+ old_address);
+ err = KERN_SUCCESS;
+ length = 0;
+ goto out;
+ }
+
+ /* Chain the regions for later use */
+ region_element =
+ (struct vm_region_list *)
+ obstack_alloc (&region_obstack, sizeof (struct vm_region_list));
+
+ region_element->protection = protection;
+ region_element->start = region_address;
+ region_element->length = region_length;
+
+ /* Chain the regions along with protections */
+ region_element->next = region_head;
+ region_head = region_element;
+
+ region_address += region_length;
+ remaining_length = remaining_length - region_length;
+ }
+
+ /* If things fail after this, we give up.
+ Somebody is messing up inferior_task's mappings. */
+
+ /* Enable writes to the chained vm regions */
+ for (scan = region_head; scan; scan = scan->next)
+ {
+ if (!(scan->protection & VM_PROT_WRITE))
+ {
+ err = vm_protect (task,
+ scan->start,
+ scan->length,
+ FALSE,
+ scan->protection | VM_PROT_WRITE);
+ CHK_GOTO_OUT ("vm_protect: enable write failed", err);
+ }
+ }
+
+ err = vm_write (task,
+ low_address,
+ copied,
+ aligned_length);
+ CHK_GOTO_OUT ("vm_write failed", err);
+
+ /* Set up the original region protections, if they were changed */
+ for (scan = region_head; scan; scan = scan->next)
+ {
+ if (!(scan->protection & VM_PROT_WRITE))
+ {
+ err = vm_protect (task,
+ scan->start,
+ scan->length,
+ FALSE,
+ scan->protection);
+ CHK_GOTO_OUT ("vm_protect: enable write failed", err);
+ }
+ }
+ }
+
+out:
+ if (deallocate)
+ {
+ obstack_free (&region_obstack, 0);
+
+ (void) vm_deallocate (mach_task_self (),
+ copied,
+ copy_count);
+ }
+
+ if (err != KERN_SUCCESS)
+ {
+ warning ("%s: %s", errstr, mach_error_string (err));
+ return 0;
+ }
+
+ return length;
+}
+
+
+/* Return 0 on failure, number of bytes handled otherwise. TARGET
+ is ignored. */
+static int
+gnu_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ task_t task = (current_inferior
+ ? (current_inferior->task
+ ? current_inferior->task->port : 0)
+ : 0);
+
+ if (task == MACH_PORT_NULL)
+ return 0;
+ else
+ {
+ inf_debug (current_inferior, "%s %p[%d] %s %p",
+ write ? "writing" : "reading", (void *) memaddr, len,
+ write ? "<--" : "-->", myaddr);
+ if (write)
+ return gnu_write_inferior (task, memaddr, myaddr, len);
+ else
+ return gnu_read_inferior (task, memaddr, myaddr, len);
+ }
+}
+
+/* Call FUNC on each memory region in the task. */
+static int
+gnu_find_memory_regions (int (*func) (CORE_ADDR,
+ unsigned long,
+ int, int, int,
+ void *),
+ void *data)
+{
+ error_t err;
+ task_t task;
+ vm_address_t region_address, last_region_address, last_region_end;
+ vm_prot_t last_protection;
+
+ if (current_inferior == 0 || current_inferior->task == 0)
+ return 0;
+ task = current_inferior->task->port;
+ if (task == MACH_PORT_NULL)
+ return 0;
+
+ region_address = last_region_address = last_region_end = VM_MIN_ADDRESS;
+ last_protection = VM_PROT_NONE;
+ while (region_address < VM_MAX_ADDRESS)
+ {
+ vm_prot_t protection;
+ vm_prot_t max_protection;
+ vm_inherit_t inheritance;
+ boolean_t shared;
+ mach_port_t object_name;
+ vm_offset_t offset;
+ vm_size_t region_length = VM_MAX_ADDRESS - region_address;
+ vm_address_t old_address = region_address;
+
+ err = vm_region (task,
+ &region_address,
+ &region_length,
+ &protection,
+ &max_protection,
+ &inheritance,
+ &shared,
+ &object_name,
+ &offset);
+ if (err == KERN_NO_SPACE)
+ break;
+ if (err != KERN_SUCCESS)
+ {
+ warning ("vm_region failed: %s", mach_error_string (err));
+ return -1;
+ }
+
+ if (protection == last_protection && region_address == last_region_end)
+ /* This region is contiguous with and indistinguishable from
+ the previous one, so we just extend that one. */
+ last_region_end = region_address += region_length;
+ else
+ {
+ /* This region is distinct from the last one we saw, so report
+ that previous one. */
+ if (last_protection != VM_PROT_NONE)
+ (*func) (last_region_address,
+ last_region_end - last_region_address,
+ last_protection & VM_PROT_READ,
+ last_protection & VM_PROT_WRITE,
+ last_protection & VM_PROT_EXECUTE,
+ data);
+ last_region_address = region_address;
+ last_region_end = region_address += region_length;
+ last_protection = protection;
+ }
+ }
+
+ /* Report the final region. */
+ if (last_region_end > last_region_address && last_protection != VM_PROT_NONE)
+ (*func) (last_region_address, last_region_end - last_region_address,
+ last_protection & VM_PROT_READ,
+ last_protection & VM_PROT_WRITE,
+ last_protection & VM_PROT_EXECUTE,
+ data);
+
+ return 0;
+}
+
+
+/* Return printable description of proc. */
+char *
+proc_string (struct proc *proc)
+{
+ static char tid_str[80];
+ if (proc_is_task (proc))
+ sprintf (tid_str, "process %d", proc->inf->pid);
+ else
+ sprintf (tid_str, "thread %d.%d",
+ proc->inf->pid, pid_to_thread_id (MERGEPID (proc->tid, 0)));
+ return tid_str;
+}
+
+static char *
+gnu_pid_to_str (ptid_t ptid)
+{
+ struct inf *inf = current_inferior;
+ int tid = PIDGET (ptid);
+ struct proc *thread = inf_tid_to_thread (inf, tid);
+
+ if (thread)
+ return proc_string (thread);
+ else
+ {
+ static char tid_str[80];
+ sprintf (tid_str, "bogus thread id %d", tid);
+ return tid_str;
+ }
+}
+
+
+extern void gnu_store_registers (int regno);
+extern void gnu_fetch_registers (int regno);
+
+struct target_ops gnu_ops;
+
+static void
+init_gnu_ops (void)
+{
+ gnu_ops.to_shortname = "GNU"; /* to_shortname */
+ gnu_ops.to_longname = "GNU Hurd process"; /* to_longname */
+ gnu_ops.to_doc = "GNU Hurd process"; /* to_doc */
+ gnu_ops.to_open = gnu_open; /* to_open */
+ gnu_ops.to_close = 0; /* to_close */
+ gnu_ops.to_attach = gnu_attach; /* to_attach */
+ gnu_ops.to_post_attach = NULL;
+ gnu_ops.to_require_attach = NULL; /* to_require_attach */
+ gnu_ops.to_detach = gnu_detach; /* to_detach */
+ gnu_ops.to_require_detach = NULL; /* to_require_detach */
+ gnu_ops.to_resume = gnu_resume; /* to_resume */
+ gnu_ops.to_wait = gnu_wait; /* to_wait */
+ gnu_ops.to_post_wait = NULL; /* to_post_wait */
+ gnu_ops.to_fetch_registers = gnu_fetch_registers; /* to_fetch_registers */
+ gnu_ops.to_store_registers = gnu_store_registers; /* to_store_registers */
+ gnu_ops.to_prepare_to_store = gnu_prepare_to_store; /* to_prepare_to_store */
+ gnu_ops.to_xfer_memory = gnu_xfer_memory; /* to_xfer_memory */
+ gnu_ops.to_find_memory_regions = gnu_find_memory_regions;
+ gnu_ops.to_files_info = 0; /* to_files_info */
+ gnu_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ gnu_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ gnu_ops.to_terminal_init = gnu_terminal_init_inferior;
+ gnu_ops.to_terminal_inferior = terminal_inferior;
+ gnu_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ gnu_ops.to_terminal_ours = terminal_ours;
+ gnu_ops.to_terminal_info = child_terminal_info;
+ gnu_ops.to_kill = gnu_kill_inferior; /* to_kill */
+ gnu_ops.to_load = 0; /* to_load */
+ gnu_ops.to_lookup_symbol = 0; /* to_lookup_symbol */
+ gnu_ops.to_create_inferior = gnu_create_inferior; /* to_create_inferior */
+ gnu_ops.to_post_startup_inferior = NULL; /* to_post_startup_inferior */
+ /* to_acknowledge_created_inferior */
+ gnu_ops.to_acknowledge_created_inferior = NULL;
+ /* to_clone_and_follow_inferior */
+ gnu_ops.to_clone_and_follow_inferior = NULL;
+ /* to_post_follow_inferior_by_clone */
+ gnu_ops.to_post_follow_inferior_by_clone = NULL;
+ gnu_ops.to_insert_fork_catchpoint = NULL;
+ gnu_ops.to_remove_fork_catchpoint = NULL;
+ gnu_ops.to_insert_vfork_catchpoint = NULL;
+ gnu_ops.to_remove_vfork_catchpoint = NULL;
+ gnu_ops.to_has_forked = NULL; /* to_has_forked */
+ gnu_ops.to_has_vforked = NULL; /* to_has_vforked */
+ gnu_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ gnu_ops.to_post_follow_vfork = NULL; /* to_post_follow_vfork */
+ gnu_ops.to_insert_exec_catchpoint = NULL;
+ gnu_ops.to_remove_exec_catchpoint = NULL;
+ gnu_ops.to_has_execd = NULL;
+ gnu_ops.to_reported_exec_events_per_exec_call = NULL;
+ gnu_ops.to_has_exited = NULL;
+ gnu_ops.to_mourn_inferior = gnu_mourn_inferior; /* to_mourn_inferior */
+ gnu_ops.to_can_run = gnu_can_run; /* to_can_run */
+ gnu_ops.to_notice_signals = 0; /* to_notice_signals */
+ gnu_ops.to_thread_alive = gnu_thread_alive; /* to_thread_alive */
+ gnu_ops.to_pid_to_str = gnu_pid_to_str; /* to_pid_to_str */
+ gnu_ops.to_stop = gnu_stop; /* to_stop */
+ gnu_ops.to_pid_to_exec_file = gnu_pid_to_exec_file; /* to_pid_to_exec_file */
+ gnu_ops.to_stratum = process_stratum; /* to_stratum */
+ gnu_ops.DONT_USE = 0; /* to_next */
+ gnu_ops.to_has_all_memory = 1; /* to_has_all_memory */
+ gnu_ops.to_has_memory = 1; /* to_has_memory */
+ gnu_ops.to_has_stack = 1; /* to_has_stack */
+ gnu_ops.to_has_registers = 1; /* to_has_registers */
+ gnu_ops.to_has_execution = 1; /* to_has_execution */
+ gnu_ops.to_sections = 0; /* sections */
+ gnu_ops.to_sections_end = 0; /* sections_end */
+ gnu_ops.to_magic = OPS_MAGIC; /* to_magic */
+} /* init_gnu_ops */
+
+
+/* User task commands. */
+
+struct cmd_list_element *set_task_cmd_list = 0;
+struct cmd_list_element *show_task_cmd_list = 0;
+/* User thread commands. */
+
+/* Commands with a prefix of `set/show thread'. */
+extern struct cmd_list_element *thread_cmd_list;
+struct cmd_list_element *set_thread_cmd_list = NULL;
+struct cmd_list_element *show_thread_cmd_list = NULL;
+
+/* Commands with a prefix of `set/show thread default'. */
+struct cmd_list_element *set_thread_default_cmd_list = NULL;
+struct cmd_list_element *show_thread_default_cmd_list = NULL;
+
+static void
+set_thread_cmd (char *args, int from_tty)
+{
+ printf_unfiltered ("\"set thread\" must be followed by the name of a thread property, or \"default\".\n");
+}
+
+static void
+show_thread_cmd (char *args, int from_tty)
+{
+ printf_unfiltered ("\"show thread\" must be followed by the name of a thread property, or \"default\".\n");
+}
+
+static void
+set_thread_default_cmd (char *args, int from_tty)
+{
+ printf_unfiltered ("\"set thread default\" must be followed by the name of a thread property.\n");
+}
+
+static void
+show_thread_default_cmd (char *args, int from_tty)
+{
+ printf_unfiltered ("\"show thread default\" must be followed by the name of a thread property.\n");
+}
+
+static int
+parse_int_arg (char *args, char *cmd_prefix)
+{
+ if (args)
+ {
+ char *arg_end;
+ int val = strtoul (args, &arg_end, 10);
+ if (*args && *arg_end == '\0')
+ return val;
+ }
+ error ("Illegal argument for \"%s\" command, should be an integer.", cmd_prefix);
+}
+
+static int
+_parse_bool_arg (char *args, char *t_val, char *f_val, char *cmd_prefix)
+{
+ if (!args || strcmp (args, t_val) == 0)
+ return 1;
+ else if (strcmp (args, f_val) == 0)
+ return 0;
+ else
+ error ("Illegal argument for \"%s\" command, should be \"%s\" or \"%s\".",
+ cmd_prefix, t_val, f_val);
+}
+
+#define parse_bool_arg(args, cmd_prefix) \
+ _parse_bool_arg (args, "on", "off", cmd_prefix)
+
+static void
+check_empty (char *args, char *cmd_prefix)
+{
+ if (args)
+ error ("Garbage after \"%s\" command: `%s'", cmd_prefix, args);
+}
+
+/* Returns the alive thread named by INFERIOR_PID, or signals an error. */
+static struct proc *
+cur_thread (void)
+{
+ struct inf *inf = cur_inf ();
+ struct proc *thread = inf_tid_to_thread (inf, PIDGET (inferior_ptid));
+ if (!thread)
+ error ("No current thread.");
+ return thread;
+}
+
+/* Returns the current inferior, but signals an error if it has no task. */
+static struct inf *
+active_inf (void)
+{
+ struct inf *inf = cur_inf ();
+ if (!inf->task)
+ error ("No current process.");
+ return inf;
+}
+
+
+static void
+set_task_pause_cmd (char *args, int from_tty)
+{
+ struct inf *inf = cur_inf ();
+ int old_sc = inf->pause_sc;
+
+ inf->pause_sc = parse_bool_arg (args, "set task pause");
+
+ if (old_sc == 0 && inf->pause_sc != 0)
+ /* If the task is currently unsuspended, immediately suspend it,
+ otherwise wait until the next time it gets control. */
+ inf_suspend (inf);
+}
+
+static void
+show_task_pause_cmd (char *args, int from_tty)
+{
+ struct inf *inf = cur_inf ();
+ check_empty (args, "show task pause");
+ printf_unfiltered ("The inferior task %s suspended while gdb has control.\n",
+ inf->task
+ ? (inf->pause_sc == 0 ? "isn't" : "is")
+ : (inf->pause_sc == 0 ? "won't be" : "will be"));
+}
+
+static void
+set_task_detach_sc_cmd (char *args, int from_tty)
+{
+ cur_inf ()->detach_sc = parse_int_arg (args, "set task detach-suspend-count");
+}
+
+static void
+show_task_detach_sc_cmd (char *args, int from_tty)
+{
+ check_empty (args, "show task detach-suspend-count");
+ printf_unfiltered ("The inferior task will be left with a suspend count of %d when detaching.\n",
+ cur_inf ()->detach_sc);
+}
+
+
+static void
+set_thread_default_pause_cmd (char *args, int from_tty)
+{
+ struct inf *inf = cur_inf ();
+ inf->default_thread_pause_sc =
+ parse_bool_arg (args, "set thread default pause") ? 0 : 1;
+}
+
+static void
+show_thread_default_pause_cmd (char *args, int from_tty)
+{
+ struct inf *inf = cur_inf ();
+ int sc = inf->default_thread_pause_sc;
+ check_empty (args, "show thread default pause");
+ printf_unfiltered ("New threads %s suspended while gdb has control%s.\n",
+ sc ? "are" : "aren't",
+ !sc && inf->pause_sc ? " (but the task is)" : "");
+}
+
+static void
+set_thread_default_run_cmd (char *args, int from_tty)
+{
+ struct inf *inf = cur_inf ();
+ inf->default_thread_run_sc =
+ parse_bool_arg (args, "set thread default run") ? 0 : 1;
+}
+
+static void
+show_thread_default_run_cmd (char *args, int from_tty)
+{
+ struct inf *inf = cur_inf ();
+ check_empty (args, "show thread default run");
+ printf_unfiltered ("New threads %s allowed to run.\n",
+ inf->default_thread_run_sc == 0 ? "are" : "aren't");
+}
+
+static void
+set_thread_default_detach_sc_cmd (char *args, int from_tty)
+{
+ cur_inf ()->default_thread_detach_sc =
+ parse_int_arg (args, "set thread default detach-suspend-count");
+}
+
+static void
+show_thread_default_detach_sc_cmd (char *args, int from_tty)
+{
+ check_empty (args, "show thread default detach-suspend-count");
+ printf_unfiltered ("New threads will get a detach-suspend-count of %d.\n",
+ cur_inf ()->default_thread_detach_sc);
+}
+
+
+/* Steal a send right called NAME in the inferior task, and make it PROC's
+ saved exception port. */
+static void
+steal_exc_port (struct proc *proc, mach_port_t name)
+{
+ error_t err;
+ mach_port_t port;
+ mach_msg_type_name_t port_type;
+
+ if (!proc || !proc->inf->task)
+ error ("No inferior task.");
+
+ err = mach_port_extract_right (proc->inf->task->port,
+ name, MACH_MSG_TYPE_COPY_SEND,
+ &port, &port_type);
+ if (err)
+ error ("Couldn't extract send right %d from inferior: %s",
+ name, safe_strerror (err));
+
+ if (proc->saved_exc_port)
+ /* Get rid of our reference to the old one. */
+ mach_port_deallocate (mach_task_self (), proc->saved_exc_port);
+
+ proc->saved_exc_port = port;
+
+ if (!proc->exc_port)
+ /* If PROC is a thread, we may not have set its exception port before.
+ We can't use proc_steal_exc_port because it also sets saved_exc_port. */
+ {
+ proc->exc_port = proc->inf->event_port;
+ err = proc_set_exception_port (proc, proc->exc_port);
+ error ("Can't set exception port for %s: %s",
+ proc_string (proc), safe_strerror (err));
+ }
+}
+
+static void
+set_task_exc_port_cmd (char *args, int from_tty)
+{
+ struct inf *inf = cur_inf ();
+ if (!args)
+ error ("No argument to \"set task exception-port\" command.");
+ steal_exc_port (inf->task, parse_and_eval_address (args));
+}
+
+static void
+set_stopped_cmd (char *args, int from_tty)
+{
+ cur_inf ()->stopped = _parse_bool_arg (args, "yes", "no", "set stopped");
+}
+
+static void
+show_stopped_cmd (char *args, int from_tty)
+{
+ struct inf *inf = active_inf ();
+ check_empty (args, "show stopped");
+ printf_unfiltered ("The inferior process %s stopped.\n",
+ inf->stopped ? "is" : "isn't");
+}
+
+static void
+set_sig_thread_cmd (char *args, int from_tty)
+{
+ struct inf *inf = cur_inf ();
+
+ if (!args || (!isdigit (*args) && strcmp (args, "none") != 0))
+ error ("Illegal argument to \"set signal-thread\" command.\n"
+ "Should be an integer thread ID, or `none'.");
+
+ if (strcmp (args, "none") == 0)
+ inf->signal_thread = 0;
+ else
+ {
+ int tid = PIDGET (thread_id_to_pid (atoi (args)));
+ if (tid < 0)
+ error ("Thread ID %s not known. Use the \"info threads\" command to\n"
+ "see the IDs of currently known threads.", args);
+ inf->signal_thread = inf_tid_to_thread (inf, tid);
+ }
+}
+
+static void
+show_sig_thread_cmd (char *args, int from_tty)
+{
+ struct inf *inf = active_inf ();
+ check_empty (args, "show signal-thread");
+ if (inf->signal_thread)
+ printf_unfiltered ("The signal thread is %s.\n",
+ proc_string (inf->signal_thread));
+ else
+ printf_unfiltered ("There is no signal thread.\n");
+}
+
+
+static void
+set_signals_cmd (char *args, int from_tty)
+{
+ struct inf *inf = cur_inf ();
+
+ inf->want_signals = parse_bool_arg (args, "set signals");
+
+ if (inf->task && inf->want_signals != inf->traced)
+ /* Make this take effect immediately in a running process. */
+ inf_set_traced (inf, inf->want_signals);
+}
+
+static void
+show_signals_cmd (char *args, int from_tty)
+{
+ struct inf *inf = cur_inf ();
+ check_empty (args, "show signals");
+ printf_unfiltered ("The inferior process's signals %s intercepted.\n",
+ inf->task
+ ? (inf->traced ? "are" : "aren't")
+ : (inf->want_signals ? "will be" : "won't be"));
+}
+
+static void
+set_exceptions_cmd (char *args, int from_tty)
+{
+ struct inf *inf = cur_inf ();
+ int val = parse_bool_arg (args, "set exceptions");
+
+ if (inf->task && inf->want_exceptions != val)
+ /* Make this take effect immediately in a running process. */
+ /* XXX */ ;
+
+ inf->want_exceptions = val;
+}
+
+static void
+show_exceptions_cmd (char *args, int from_tty)
+{
+ struct inf *inf = cur_inf ();
+ check_empty (args, "show exceptions");
+ printf_unfiltered ("Exceptions in the inferior %s trapped.\n",
+ inf->task
+ ? (inf->want_exceptions ? "are" : "aren't")
+ : (inf->want_exceptions ? "will be" : "won't be"));
+}
+
+
+static void
+set_task_cmd (char *args, int from_tty)
+{
+ printf_unfiltered ("\"set task\" must be followed by the name"
+ " of a task property.\n");
+}
+
+static void
+show_task_cmd (char *args, int from_tty)
+{
+ struct inf *inf = cur_inf ();
+
+ check_empty (args, "show task");
+
+ show_signals_cmd (0, from_tty);
+ show_exceptions_cmd (0, from_tty);
+ show_task_pause_cmd (0, from_tty);
+
+ if (inf->pause_sc == 0)
+ show_thread_default_pause_cmd (0, from_tty);
+ show_thread_default_run_cmd (0, from_tty);
+
+ if (inf->task)
+ {
+ show_stopped_cmd (0, from_tty);
+ show_sig_thread_cmd (0, from_tty);
+ }
+
+ if (inf->detach_sc != 0)
+ show_task_detach_sc_cmd (0, from_tty);
+ if (inf->default_thread_detach_sc != 0)
+ show_thread_default_detach_sc_cmd (0, from_tty);
+}
+
+
+static void
+set_noninvasive_cmd (char *args, int from_tty)
+{
+ /* Invert the sense of the arg for each component. */
+ char *inv_args = parse_bool_arg (args, "set noninvasive") ? "off" : "on";
+
+ set_task_pause_cmd (inv_args, from_tty);
+ set_signals_cmd (inv_args, from_tty);
+ set_exceptions_cmd (inv_args, from_tty);
+}
+
+
+static void
+info_port_rights (char *args, mach_port_type_t only)
+{
+ struct inf *inf = active_inf ();
+ struct value *vmark = value_mark ();
+
+ if (args)
+ /* Explicit list of port rights. */
+ {
+ while (*args)
+ {
+ struct value *val = parse_to_comma_and_eval (&args);
+ long right = value_as_long (val);
+ error_t err =
+ print_port_info (right, 0, inf->task->port, PORTINFO_DETAILS,
+ stdout);
+ if (err)
+ error ("%ld: %s.", right, safe_strerror (err));
+ }
+ }
+ else
+ /* Print all of them. */
+ {
+ error_t err =
+ print_task_ports_info (inf->task->port, only, PORTINFO_DETAILS,
+ stdout);
+ if (err)
+ error ("%s.", safe_strerror (err));
+ }
+
+ value_free_to_mark (vmark);
+}
+
+static void
+info_send_rights_cmd (char *args, int from_tty)
+{
+ info_port_rights (args, MACH_PORT_TYPE_SEND);
+}
+
+static void
+info_recv_rights_cmd (char *args, int from_tty)
+{
+ info_port_rights (args, MACH_PORT_TYPE_RECEIVE);
+}
+
+static void
+info_port_sets_cmd (char *args, int from_tty)
+{
+ info_port_rights (args, MACH_PORT_TYPE_PORT_SET);
+}
+
+static void
+info_dead_names_cmd (char *args, int from_tty)
+{
+ info_port_rights (args, MACH_PORT_TYPE_DEAD_NAME);
+}
+
+static void
+info_port_rights_cmd (char *args, int from_tty)
+{
+ info_port_rights (args, ~0);
+}
+
+
+static void
+add_task_commands (void)
+{
+ add_cmd ("pause", class_run, set_thread_default_pause_cmd,
+ "Set whether the new threads are suspended while gdb has control.\n\
+This property normally has no effect because the whole task is\n\
+suspended, however, that may be disabled with \"set task pause off\".\n\
+The default value is \"off\".",
+ &set_thread_default_cmd_list);
+ add_cmd ("pause", no_class, show_thread_default_pause_cmd,
+ "Show whether new threads are suspended while gdb has control.",
+ &show_thread_default_cmd_list);
+
+ add_cmd ("run", class_run, set_thread_default_run_cmd,
+ "Set whether new threads are allowed to run \
+(once gdb has noticed them).",
+ &set_thread_default_cmd_list);
+ add_cmd ("run", no_class, show_thread_default_run_cmd,
+ "Show whether new threads are allowed to run \
+(once gdb has noticed them).",
+ &show_thread_default_cmd_list);
+
+ add_cmd ("detach-suspend-count", class_run, set_thread_default_detach_sc_cmd,
+ "Set the default detach-suspend-count value for new threads.",
+ &set_thread_default_cmd_list);
+ add_cmd ("detach-suspend-count", no_class, show_thread_default_detach_sc_cmd,
+ "Show the default detach-suspend-count value for new threads.",
+ &show_thread_default_cmd_list);
+
+ add_cmd ("signals", class_run, set_signals_cmd,
+ "Set whether the inferior process's signals will be intercepted.\n\
+Mach exceptions (such as breakpoint traps) are not affected.",
+ &setlist);
+ add_alias_cmd ("sigs", "signals", class_run, 1, &setlist);
+ add_cmd ("signals", no_class, show_signals_cmd,
+ "Show whether the inferior process's signals will be intercepted.",
+ &showlist);
+ add_alias_cmd ("sigs", "signals", no_class, 1, &showlist);
+
+ add_cmd ("signal-thread", class_run, set_sig_thread_cmd,
+ "Set the thread that gdb thinks is the libc signal thread.\n\
+This thread is run when delivering a signal to a non-stopped process.",
+ &setlist);
+ add_alias_cmd ("sigthread", "signal-thread", class_run, 1, &setlist);
+ add_cmd ("signal-thread", no_class, show_sig_thread_cmd,
+ "Set the thread that gdb thinks is the libc signal thread.",
+ &showlist);
+ add_alias_cmd ("sigthread", "signal-thread", no_class, 1, &showlist);
+
+ add_cmd ("stopped", class_run, set_stopped_cmd,
+ "Set whether gdb thinks the inferior process is stopped \
+as with SIGSTOP.\n\
+Stopped process will be continued by sending them a signal.",
+ &setlist);
+ add_cmd ("stopped", no_class, show_signals_cmd,
+ "Show whether gdb thinks the inferior process is stopped \
+as with SIGSTOP.",
+ &showlist);
+
+ add_cmd ("exceptions", class_run, set_exceptions_cmd,
+ "Set whether exceptions in the inferior process will be trapped.\n\
+When exceptions are turned off, neither breakpoints nor single-stepping\n\
+will work.",
+ &setlist);
+ /* Allow `set exc' despite conflict with `set exception-port'. */
+ add_alias_cmd ("exc", "exceptions", class_run, 1, &setlist);
+ add_cmd ("exceptions", no_class, show_exceptions_cmd,
+ "Show whether exceptions in the inferior process will be trapped.",
+ &showlist);
+
+ add_prefix_cmd ("task", no_class, set_task_cmd,
+ "Command prefix for setting task attributes.",
+ &set_task_cmd_list, "set task ", 0, &setlist);
+ add_prefix_cmd ("task", no_class, show_task_cmd,
+ "Command prefix for showing task attributes.",
+ &show_task_cmd_list, "show task ", 0, &showlist);
+
+ add_cmd ("pause", class_run, set_task_pause_cmd,
+ "Set whether the task is suspended while gdb has control.\n\
+A value of \"on\" takes effect immediately, otherwise nothing happens\n\
+until the next time the program is continued.\n\
+When setting this to \"off\", \"set thread default pause on\" can be\n\
+used to pause individual threads by default instead.",
+ &set_task_cmd_list);
+ add_cmd ("pause", no_class, show_task_pause_cmd,
+ "Show whether the task is suspended while gdb has control.",
+ &show_task_cmd_list);
+
+ add_cmd ("detach-suspend-count", class_run, set_task_detach_sc_cmd,
+ "Set the suspend count will leave on the thread when detaching.",
+ &set_task_cmd_list);
+ add_cmd ("detach-suspend-count", no_class, show_task_detach_sc_cmd,
+ "Show the suspend count will leave on the thread when detaching.",
+ &show_task_cmd_list);
+
+ add_cmd ("exception-port", no_class, set_task_exc_port_cmd,
+ "Set the task exception port to which we forward exceptions.\n\
+The argument should be the value of the send right in the task.",
+ &set_task_cmd_list);
+ add_alias_cmd ("excp", "exception-port", no_class, 1, &set_task_cmd_list);
+ add_alias_cmd ("exc-port", "exception-port", no_class, 1,
+ &set_task_cmd_list);
+
+ /* A convenient way of turning on all options require to noninvasively
+ debug running tasks. */
+ add_cmd ("noninvasive", no_class, set_noninvasive_cmd,
+ "Set task options so that we interfere as little as possible.\n\
+This is the same as setting `task pause', `exceptions', and\n\
+`signals' to the opposite value.",
+ &setlist);
+
+ /* Commands to show information about the task's ports. */
+ add_cmd ("send-rights", class_info, info_send_rights_cmd,
+ "Show information about the task's send rights",
+ &infolist);
+ add_cmd ("receive-rights", class_info, info_recv_rights_cmd,
+ "Show information about the task's receive rights",
+ &infolist);
+ add_cmd ("port-rights", class_info, info_port_rights_cmd,
+ "Show information about the task's port rights",
+ &infolist);
+ add_cmd ("port-sets", class_info, info_port_sets_cmd,
+ "Show information about the task's port sets",
+ &infolist);
+ add_cmd ("dead-names", class_info, info_dead_names_cmd,
+ "Show information about the task's dead names",
+ &infolist);
+ add_info_alias ("ports", "port-rights", 1);
+ add_info_alias ("port", "port-rights", 1);
+ add_info_alias ("psets", "port-sets", 1);
+}
+
+
+static void
+set_thread_pause_cmd (char *args, int from_tty)
+{
+ struct proc *thread = cur_thread ();
+ int old_sc = thread->pause_sc;
+ thread->pause_sc = parse_bool_arg (args, "set thread pause");
+ if (old_sc == 0 && thread->pause_sc != 0 && thread->inf->pause_sc == 0)
+ /* If the task is currently unsuspended, immediately suspend it,
+ otherwise wait until the next time it gets control. */
+ inf_suspend (thread->inf);
+}
+
+static void
+show_thread_pause_cmd (char *args, int from_tty)
+{
+ struct proc *thread = cur_thread ();
+ int sc = thread->pause_sc;
+ check_empty (args, "show task pause");
+ printf_unfiltered ("Thread %s %s suspended while gdb has control%s.\n",
+ proc_string (thread),
+ sc ? "is" : "isn't",
+ !sc && thread->inf->pause_sc ? " (but the task is)" : "");
+}
+
+static void
+set_thread_run_cmd (char *args, int from_tty)
+{
+ struct proc *thread = cur_thread ();
+ thread->run_sc = parse_bool_arg (args, "set thread run") ? 0 : 1;
+}
+
+static void
+show_thread_run_cmd (char *args, int from_tty)
+{
+ struct proc *thread = cur_thread ();
+ check_empty (args, "show thread run");
+ printf_unfiltered ("Thread %s %s allowed to run.",
+ proc_string (thread),
+ thread->run_sc == 0 ? "is" : "isn't");
+}
+
+static void
+set_thread_detach_sc_cmd (char *args, int from_tty)
+{
+ cur_thread ()->detach_sc = parse_int_arg (args,
+ "set thread detach-suspend-count");
+}
+
+static void
+show_thread_detach_sc_cmd (char *args, int from_tty)
+{
+ struct proc *thread = cur_thread ();
+ check_empty (args, "show thread detach-suspend-count");
+ printf_unfiltered ("Thread %s will be left with a suspend count"
+ " of %d when detaching.\n",
+ proc_string (thread),
+ thread->detach_sc);
+}
+
+static void
+set_thread_exc_port_cmd (char *args, int from_tty)
+{
+ struct proc *thread = cur_thread ();
+ if (!args)
+ error ("No argument to \"set thread exception-port\" command.");
+ steal_exc_port (thread, parse_and_eval_address (args));
+}
+
+#if 0
+static void
+show_thread_cmd (char *args, int from_tty)
+{
+ struct proc *thread = cur_thread ();
+ check_empty (args, "show thread");
+ show_thread_run_cmd (0, from_tty);
+ show_thread_pause_cmd (0, from_tty);
+ if (thread->detach_sc != 0)
+ show_thread_detach_sc_cmd (0, from_tty);
+}
+#endif
+
+static void
+thread_takeover_sc_cmd (char *args, int from_tty)
+{
+ struct proc *thread = cur_thread ();
+ thread_basic_info_data_t _info;
+ thread_basic_info_t info = &_info;
+ mach_msg_type_number_t info_len = THREAD_BASIC_INFO_COUNT;
+ error_t err =
+ thread_info (thread->port, THREAD_BASIC_INFO, (int *) &info, &info_len);
+ if (err)
+ error ("%s.", safe_strerror (err));
+ thread->sc = info->suspend_count;
+ if (from_tty)
+ printf_unfiltered ("Suspend count was %d.\n", thread->sc);
+ if (info != &_info)
+ vm_deallocate (mach_task_self (), (vm_address_t) info,
+ info_len * sizeof (int));
+}
+
+
+static void
+add_thread_commands (void)
+{
+ add_prefix_cmd ("thread", no_class, set_thread_cmd,
+ "Command prefix for setting thread properties.",
+ &set_thread_cmd_list, "set thread ", 0, &setlist);
+ add_prefix_cmd ("default", no_class, show_thread_cmd,
+ "Command prefix for setting default thread properties.",
+ &set_thread_default_cmd_list, "set thread default ", 0,
+ &set_thread_cmd_list);
+ add_prefix_cmd ("thread", no_class, set_thread_default_cmd,
+ "Command prefix for showing thread properties.",
+ &show_thread_cmd_list, "show thread ", 0, &showlist);
+ add_prefix_cmd ("default", no_class, show_thread_default_cmd,
+ "Command prefix for showing default thread properties.",
+ &show_thread_default_cmd_list, "show thread default ", 0,
+ &show_thread_cmd_list);
+
+ add_cmd ("pause", class_run, set_thread_pause_cmd,
+ "Set whether the current thread is suspended \
+while gdb has control.\n\
+A value of \"on\" takes effect immediately, otherwise nothing happens\n\
+until the next time the program is continued. This property normally\n\
+has no effect because the whole task is suspended, however, that may\n\
+be disabled with \"set task pause off\".\n\
+The default value is \"off\".",
+ &set_thread_cmd_list);
+ add_cmd ("pause", no_class, show_thread_pause_cmd,
+ "Show whether the current thread is suspended \
+while gdb has control.",
+ &show_thread_cmd_list);
+
+ add_cmd ("run", class_run, set_thread_run_cmd,
+ "Set whether the current thread is allowed to run.",
+ &set_thread_cmd_list);
+ add_cmd ("run", no_class, show_thread_run_cmd,
+ "Show whether the current thread is allowed to run.",
+ &show_thread_cmd_list);
+
+ add_cmd ("detach-suspend-count", class_run, set_thread_detach_sc_cmd,
+ "Set the suspend count will leave on the thread when detaching.\n\
+Note that this is relative to suspend count when gdb noticed the thread;\n\
+use the `thread takeover-suspend-count' to force it to an absolute value.",
+ &set_thread_cmd_list);
+ add_cmd ("detach-suspend-count", no_class, show_thread_detach_sc_cmd,
+ "Show the suspend count will leave on the thread when detaching.\n\
+Note that this is relative to suspend count when gdb noticed the thread;\n\
+use the `thread takeover-suspend-count' to force it to an absolute value.",
+ &show_thread_cmd_list);
+
+ add_cmd ("exception-port", no_class, set_thread_exc_port_cmd,
+ "Set the thread exception port to which we forward exceptions.\n\
+This overrides the task exception port.\n\
+The argument should be the value of the send right in the task.",
+ &set_thread_cmd_list);
+ add_alias_cmd ("excp", "exception-port", no_class, 1, &set_thread_cmd_list);
+ add_alias_cmd ("exc-port", "exception-port", no_class, 1,
+ &set_thread_cmd_list);
+
+ add_cmd ("takeover-suspend-count", no_class, thread_takeover_sc_cmd,
+ "Force the threads absolute suspend-count to be gdb's.\n\
+Prior to giving this command, gdb's thread suspend-counts are relative\n\
+to the thread's initial suspend-count when gdb notices the threads.",
+ &thread_cmd_list);
+}
+
+
+void
+_initialize_gnu_nat (void)
+{
+ proc_server = getproc ();
+
+ init_gnu_ops ();
+ add_target (&gnu_ops);
+
+ add_task_commands ();
+ add_thread_commands ();
+ add_set_cmd ("gnu-debug", class_maintenance,
+ var_boolean, (char *) &gnu_debug_flag,
+ "Set debugging output for the gnu backend.", &maintenancelist);
+}
+
+#ifdef FLUSH_INFERIOR_CACHE
+
+/* When over-writing code on some machines the I-Cache must be flushed
+ explicitly, because it is not kept coherent by the lazy hardware.
+ This definitely includes breakpoints, for instance, or else we
+ end up looping in mysterious Bpt traps */
+
+void
+flush_inferior_icache (CORE_ADDR pc, int amount)
+{
+ vm_machine_attribute_val_t flush = MATTR_VAL_ICACHE_FLUSH;
+ error_t ret;
+
+ ret = vm_machine_attribute (current_inferior->task->port,
+ pc,
+ amount,
+ MATTR_CACHE,
+ &flush);
+ if (ret != KERN_SUCCESS)
+ warning ("Error flushing inferior's cache : %s", safe_strerror (ret));
+}
+#endif /* FLUSH_INFERIOR_CACHE */
diff --git a/gdb/gnu-nat.h b/gdb/gnu-nat.h
new file mode 100644
index 00000000000..cc430835f2c
--- /dev/null
+++ b/gdb/gnu-nat.h
@@ -0,0 +1,101 @@
+/* Common things used by the various *gnu-nat.c files
+ Copyright 1995, 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ The GNU Hurd 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, or (at
+ your option) any later version.
+
+ The GNU Hurd 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. */
+
+#ifndef __GNU_NAT_H__
+#define __GNU_NAT_H__
+
+#include <unistd.h>
+#include <mach.h>
+
+struct inf;
+
+extern struct inf *current_inferior;
+
+/* Converts a GDB pid to a struct proc. */
+struct proc *inf_tid_to_thread (struct inf *inf, int tid);
+
+/* Makes sure that INF's thread list is synced with the actual process. */
+int inf_update_procs (struct inf *inf);
+
+/* A proc is either a thread, or the task (there can only be one task proc
+ because it always has the same TID, PROC_TID_TASK). */
+struct proc
+ {
+ thread_t port; /* The task or thread port. */
+ int tid; /* The GDB pid (actually a thread id). */
+ int num; /* An id number for threads, to print. */
+
+ mach_port_t saved_exc_port; /* The task/thread's real exception port. */
+ mach_port_t exc_port; /* Our replacement, which for. */
+
+ int sc; /* Desired suspend count. */
+ int cur_sc; /* Implemented suspend count. */
+ int run_sc; /* Default sc when the program is running. */
+ int pause_sc; /* Default sc when gdb has control. */
+ int resume_sc; /* Sc resulting from the last resume. */
+ int detach_sc; /* SC to leave around when detaching
+ from program. */
+
+ thread_state_data_t state; /* Registers, &c. */
+ int state_valid:1; /* True if STATE is up to date. */
+ int state_changed:1;
+
+ int aborted:1; /* True if thread_abort has been called. */
+ int dead:1; /* We happen to know it's actually dead. */
+
+ /* Bit mask of registers fetched by gdb. This is used when we re-fetch
+ STATE after aborting the thread, to detect that gdb may have out-of-date
+ information. */
+ unsigned long fetched_regs;
+
+ struct inf *inf; /* Where we come from. */
+
+ struct proc *next;
+ };
+
+/* The task has a thread entry with this TID. */
+#define PROC_TID_TASK (-1)
+
+#define proc_is_task(proc) ((proc)->tid == PROC_TID_TASK)
+#define proc_is_thread(proc) ((proc)->tid != PROC_TID_TASK)
+
+extern int __proc_pid (struct proc *proc);
+
+/* Make sure that the state field in PROC is up to date, and return a
+ pointer to it, or 0 if something is wrong. If WILL_MODIFY is true,
+ makes sure that the thread is stopped and aborted first, and sets
+ the state_changed field in PROC to true. */
+extern thread_state_t proc_get_state (struct proc *proc, int will_modify);
+
+/* Return printable description of proc. */
+extern char *proc_string (struct proc *proc);
+
+#define proc_debug(_proc, msg, args...) \
+ do { struct proc *__proc = (_proc); \
+ debug ("{proc %d/%d %p}: " msg, \
+ __proc_pid (__proc), __proc->tid, __proc , ##args); } while (0)
+
+extern int gnu_debug_flag;
+
+#define debug(msg, args...) \
+ do { if (gnu_debug_flag) \
+ fprintf_unfiltered (gdb_stdlog, "%s: " msg "\r\n", __FUNCTION__ , ##args); } while (0)
+
+#endif /* __GNU_NAT_H__ */
diff --git a/gdb/gnu-v2-abi.c b/gdb/gnu-v2-abi.c
new file mode 100644
index 00000000000..2b086c57f5e
--- /dev/null
+++ b/gdb/gnu-v2-abi.c
@@ -0,0 +1,429 @@
+/* Abstraction of GNU v2 abi.
+ Contributed by Daniel Berlin <dberlin@redhat.com>
+ Copyright 2001 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 "defs.h"
+#include "gdb_string.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "value.h"
+#include "demangle.h"
+#include "cp-abi.h"
+
+#include <ctype.h>
+
+struct cp_abi_ops gnu_v2_abi_ops;
+
+static int vb_match (struct type *, int, struct type *);
+int gnuv2_baseclass_offset (struct type *type, int index, char *valaddr,
+ CORE_ADDR address);
+
+static enum dtor_kinds
+gnuv2_is_destructor_name (const char *name)
+{
+ if ((name[0] == '_' && is_cplus_marker (name[1]) && name[2] == '_')
+ || strncmp (name, "__dt__", 6) == 0)
+ return complete_object_dtor;
+ else
+ return 0;
+}
+
+static enum ctor_kinds
+gnuv2_is_constructor_name (const char *name)
+{
+ if ((name[0] == '_' && name[1] == '_'
+ && (isdigit (name[2]) || strchr ("Qt", name[2])))
+ || strncmp (name, "__ct__", 6) == 0)
+ return complete_object_ctor;
+ else
+ return 0;
+}
+
+static int
+gnuv2_is_vtable_name (const char *name)
+{
+ return (((name)[0] == '_'
+ && (((name)[1] == 'V' && (name)[2] == 'T')
+ || ((name)[1] == 'v' && (name)[2] == 't'))
+ && is_cplus_marker ((name)[3])) ||
+ ((name)[0] == '_' && (name)[1] == '_'
+ && (name)[2] == 'v' && (name)[3] == 't' && (name)[4] == '_'));
+}
+
+static int
+gnuv2_is_operator_name (const char *name)
+{
+ return strncmp (name, "operator", 8) == 0;
+}
+
+
+/* Return a virtual function as a value.
+ ARG1 is the object which provides the virtual function
+ table pointer. *ARG1P is side-effected in calling this function.
+ F is the list of member functions which contains the desired virtual
+ function.
+ J is an index into F which provides the desired virtual function.
+
+ TYPE is the type in which F is located. */
+static struct value *
+gnuv2_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j,
+ struct type * type, int offset)
+{
+ struct value *arg1 = *arg1p;
+ struct type *type1 = check_typedef (VALUE_TYPE (arg1));
+
+
+ struct type *entry_type;
+ /* First, get the virtual function table pointer. That comes
+ with a strange type, so cast it to type `pointer to long' (which
+ should serve just fine as a function type). Then, index into
+ the table, and convert final value to appropriate function type. */
+ struct value *entry;
+ struct value *vfn;
+ struct value *vtbl;
+ struct value *vi = value_from_longest (builtin_type_int,
+ (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
+ struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j);
+ struct type *context;
+ if (fcontext == NULL)
+ /* We don't have an fcontext (e.g. the program was compiled with
+ g++ version 1). Try to get the vtbl from the TYPE_VPTR_BASETYPE.
+ This won't work right for multiple inheritance, but at least we
+ should do as well as GDB 3.x did. */
+ fcontext = TYPE_VPTR_BASETYPE (type);
+ context = lookup_pointer_type (fcontext);
+ /* Now context is a pointer to the basetype containing the vtbl. */
+ if (TYPE_TARGET_TYPE (context) != type1)
+ {
+ struct value *tmp = value_cast (context, value_addr (arg1));
+ arg1 = value_ind (tmp);
+ type1 = check_typedef (VALUE_TYPE (arg1));
+ }
+
+ context = type1;
+ /* Now context is the basetype containing the vtbl. */
+
+ /* This type may have been defined before its virtual function table
+ was. If so, fill in the virtual function table entry for the
+ type now. */
+ if (TYPE_VPTR_FIELDNO (context) < 0)
+ fill_in_vptr_fieldno (context);
+
+ /* The virtual function table is now an array of structures
+ which have the form { int16 offset, delta; void *pfn; }. */
+ vtbl = value_primitive_field (arg1, 0, TYPE_VPTR_FIELDNO (context),
+ TYPE_VPTR_BASETYPE (context));
+
+ /* With older versions of g++, the vtbl field pointed to an array
+ of structures. Nowadays it points directly to the structure. */
+ if (TYPE_CODE (VALUE_TYPE (vtbl)) == TYPE_CODE_PTR
+ && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (vtbl))) == TYPE_CODE_ARRAY)
+ {
+ /* Handle the case where the vtbl field points to an
+ array of structures. */
+ vtbl = value_ind (vtbl);
+
+ /* Index into the virtual function table. This is hard-coded because
+ looking up a field is not cheap, and it may be important to save
+ time, e.g. if the user has set a conditional breakpoint calling
+ a virtual function. */
+ entry = value_subscript (vtbl, vi);
+ }
+ else
+ {
+ /* Handle the case where the vtbl field points directly to a structure. */
+ vtbl = value_add (vtbl, vi);
+ entry = value_ind (vtbl);
+ }
+
+ entry_type = check_typedef (VALUE_TYPE (entry));
+
+ if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT)
+ {
+ /* Move the `this' pointer according to the virtual function table. */
+ VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0));
+
+ if (!VALUE_LAZY (arg1))
+ {
+ VALUE_LAZY (arg1) = 1;
+ value_fetch_lazy (arg1);
+ }
+
+ vfn = value_field (entry, 2);
+ }
+ else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR)
+ vfn = entry;
+ else
+ error ("I'm confused: virtual function table has bad type");
+ /* Reinstantiate the function pointer with the correct type. */
+ VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
+
+ *arg1p = arg1;
+ return vfn;
+}
+
+
+struct type *
+gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
+{
+ struct type *known_type;
+ struct type *rtti_type;
+ CORE_ADDR coreptr;
+ struct value *vp;
+ int using_enclosing = 0;
+ long top_offset = 0;
+ char rtti_type_name[256];
+ CORE_ADDR vtbl;
+ struct minimal_symbol *minsym;
+ struct symbol *sym;
+ char *demangled_name;
+ struct type *btype;
+
+ if (full)
+ *full = 0;
+ if (top)
+ *top = -1;
+ if (using_enc)
+ *using_enc = 0;
+
+ /* Get declared type */
+ known_type = VALUE_TYPE (v);
+ CHECK_TYPEDEF (known_type);
+ /* RTTI works only or class objects */
+ if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
+ return NULL;
+
+ /* Plan on this changing in the future as i get around to setting
+ the vtables properly for G++ compiled stuff. Also, I'll be using
+ the type info functions, which are always right. Deal with it
+ until then. */
+
+ /* If the type has no vptr fieldno, try to get it filled in */
+ if (TYPE_VPTR_FIELDNO(known_type) < 0)
+ fill_in_vptr_fieldno(known_type);
+
+ /* If we still can't find one, give up */
+ if (TYPE_VPTR_FIELDNO(known_type) < 0)
+ return NULL;
+
+ /* Make sure our basetype and known type match, otherwise, cast
+ so we can get at the vtable properly.
+ */
+ btype = TYPE_VPTR_BASETYPE (known_type);
+ CHECK_TYPEDEF (btype);
+ if (btype != known_type )
+ {
+ v = value_cast (btype, v);
+ if (using_enc)
+ *using_enc=1;
+ }
+ /*
+ We can't use value_ind here, because it would want to use RTTI, and
+ we'd waste a bunch of time figuring out we already know the type.
+ Besides, we don't care about the type, just the actual pointer
+ */
+ if (VALUE_ADDRESS (value_field (v, TYPE_VPTR_FIELDNO (known_type))) == 0)
+ return NULL;
+
+ /*
+ If we are enclosed by something that isn't us, adjust the
+ address properly and set using_enclosing.
+ */
+ if (VALUE_ENCLOSING_TYPE(v) != VALUE_TYPE(v))
+ {
+ struct value *tempval;
+ int bitpos = TYPE_BASECLASS_BITPOS (known_type,
+ TYPE_VPTR_FIELDNO (known_type));
+ tempval=value_field (v, TYPE_VPTR_FIELDNO(known_type));
+ VALUE_ADDRESS(tempval) += bitpos / 8;
+ vtbl=value_as_address (tempval);
+ using_enclosing=1;
+ }
+ else
+ {
+ vtbl=value_as_address(value_field(v,TYPE_VPTR_FIELDNO(known_type)));
+ using_enclosing=0;
+ }
+
+ /* Try to find a symbol that is the vtable */
+ minsym=lookup_minimal_symbol_by_pc(vtbl);
+ if (minsym==NULL
+ || (demangled_name=SYMBOL_NAME(minsym))==NULL
+ || !is_vtable_name (demangled_name))
+ return NULL;
+
+ /* If we just skip the prefix, we get screwed by namespaces */
+ demangled_name=cplus_demangle(demangled_name,DMGL_PARAMS|DMGL_ANSI);
+ *(strchr(demangled_name,' '))=0;
+
+ /* Lookup the type for the name */
+ rtti_type=lookup_typename(demangled_name, (struct block *)0,1);
+
+ if (rtti_type==NULL)
+ return NULL;
+
+ if (TYPE_N_BASECLASSES(rtti_type) > 1 && full && (*full) != 1)
+ {
+ if (top)
+ *top=TYPE_BASECLASS_BITPOS(rtti_type,TYPE_VPTR_FIELDNO(rtti_type))/8;
+ if (top && ((*top) >0))
+ {
+ if (TYPE_LENGTH(rtti_type) > TYPE_LENGTH(known_type))
+ {
+ if (full)
+ *full=0;
+ }
+ else
+ {
+ if (full)
+ *full=1;
+ }
+ }
+ }
+ else
+ {
+ if (full)
+ *full=1;
+ }
+ if (using_enc)
+ *using_enc=using_enclosing;
+
+ return rtti_type;
+}
+
+/* Return true if the INDEXth field of TYPE is a virtual baseclass
+ pointer which is for the base class whose type is BASECLASS. */
+
+static int
+vb_match (struct type *type, int index, struct type *basetype)
+{
+ struct type *fieldtype;
+ char *name = TYPE_FIELD_NAME (type, index);
+ char *field_class_name = NULL;
+
+ if (*name != '_')
+ return 0;
+ /* gcc 2.4 uses _vb$. */
+ if (name[1] == 'v' && name[2] == 'b' && is_cplus_marker (name[3]))
+ field_class_name = name + 4;
+ /* gcc 2.5 will use __vb_. */
+ if (name[1] == '_' && name[2] == 'v' && name[3] == 'b' && name[4] == '_')
+ field_class_name = name + 5;
+
+ if (field_class_name == NULL)
+ /* This field is not a virtual base class pointer. */
+ return 0;
+
+ /* It's a virtual baseclass pointer, now we just need to find out whether
+ it is for this baseclass. */
+ fieldtype = TYPE_FIELD_TYPE (type, index);
+ if (fieldtype == NULL
+ || TYPE_CODE (fieldtype) != TYPE_CODE_PTR)
+ /* "Can't happen". */
+ return 0;
+
+ /* What we check for is that either the types are equal (needed for
+ nameless types) or have the same name. This is ugly, and a more
+ elegant solution should be devised (which would probably just push
+ the ugliness into symbol reading unless we change the stabs format). */
+ if (TYPE_TARGET_TYPE (fieldtype) == basetype)
+ return 1;
+
+ if (TYPE_NAME (basetype) != NULL
+ && TYPE_NAME (TYPE_TARGET_TYPE (fieldtype)) != NULL
+ && STREQ (TYPE_NAME (basetype),
+ TYPE_NAME (TYPE_TARGET_TYPE (fieldtype))))
+ return 1;
+ return 0;
+}
+
+/* Compute the offset of the baseclass which is
+ the INDEXth baseclass of class TYPE,
+ for value at VALADDR (in host) at ADDRESS (in target).
+ The result is the offset of the baseclass value relative
+ to (the address of)(ARG) + OFFSET.
+
+ -1 is returned on error. */
+
+int
+gnuv2_baseclass_offset (struct type *type, int index, char *valaddr,
+ CORE_ADDR address)
+{
+ struct type *basetype = TYPE_BASECLASS (type, index);
+
+ if (BASETYPE_VIA_VIRTUAL (type, index))
+ {
+ /* Must hunt for the pointer to this virtual baseclass. */
+ register int i, len = TYPE_NFIELDS (type);
+ register int n_baseclasses = TYPE_N_BASECLASSES (type);
+
+ /* First look for the virtual baseclass pointer
+ in the fields. */
+ for (i = n_baseclasses; i < len; i++)
+ {
+ if (vb_match (type, i, basetype))
+ {
+ CORE_ADDR addr
+ = unpack_pointer (TYPE_FIELD_TYPE (type, i),
+ valaddr + (TYPE_FIELD_BITPOS (type, i) / 8));
+
+ return addr - (LONGEST) address;
+ }
+ }
+ /* Not in the fields, so try looking through the baseclasses. */
+ for (i = index + 1; i < n_baseclasses; i++)
+ {
+ int boffset =
+ baseclass_offset (type, i, valaddr, address);
+ if (boffset)
+ return boffset;
+ }
+ /* Not found. */
+ return -1;
+ }
+
+ /* Baseclass is easily computed. */
+ return TYPE_BASECLASS_BITPOS (type, index) / 8;
+}
+
+static void
+init_gnuv2_ops (void)
+{
+ gnu_v2_abi_ops.shortname = "gnu-v2";
+ gnu_v2_abi_ops.longname = "GNU G++ Version 2 ABI";
+ gnu_v2_abi_ops.doc = "G++ Version 2 ABI";
+ gnu_v2_abi_ops.is_destructor_name = gnuv2_is_destructor_name;
+ gnu_v2_abi_ops.is_constructor_name = gnuv2_is_constructor_name;
+ gnu_v2_abi_ops.is_vtable_name = gnuv2_is_vtable_name;
+ gnu_v2_abi_ops.is_operator_name = gnuv2_is_operator_name;
+ gnu_v2_abi_ops.virtual_fn_field = gnuv2_virtual_fn_field;
+ gnu_v2_abi_ops.rtti_type = gnuv2_value_rtti_type;
+ gnu_v2_abi_ops.baseclass_offset = gnuv2_baseclass_offset;
+}
+
+void
+_initialize_gnu_v2_abi (void)
+{
+ init_gnuv2_ops ();
+ register_cp_abi (gnu_v2_abi_ops);
+ switch_to_cp_abi ("gnu-v2");
+}
diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c
new file mode 100644
index 00000000000..e86af89d557
--- /dev/null
+++ b/gdb/gnu-v3-abi.c
@@ -0,0 +1,450 @@
+/* Abstraction of GNU v3 abi.
+ Contributed by Jim Blandy <jimb@redhat.com>
+
+ Copyright 2001, 2002 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 "defs.h"
+#include "value.h"
+#include "cp-abi.h"
+#include "demangle.h"
+#include "gdb_assert.h"
+
+static struct cp_abi_ops gnu_v3_abi_ops;
+
+static int
+gnuv3_is_vtable_name (const char *name)
+{
+ return strncmp (name, "_ZTV", 4) == 0;
+}
+
+static int
+gnuv3_is_operator_name (const char *name)
+{
+ return strncmp (name, "operator", 8) == 0;
+}
+
+
+/* To help us find the components of a vtable, we build ourselves a
+ GDB type object representing the vtable structure. Following the
+ V3 ABI, it goes something like this:
+
+ struct gdb_gnu_v3_abi_vtable {
+
+ / * An array of virtual call and virtual base offsets. The real
+ length of this array depends on the class hierarchy; we use
+ negative subscripts to access the elements. Yucky, but
+ better than the alternatives. * /
+ ptrdiff_t vcall_and_vbase_offsets[0];
+
+ / * The offset from a virtual pointer referring to this table
+ to the top of the complete object. * /
+ ptrdiff_t offset_to_top;
+
+ / * The type_info pointer for this class. This is really a
+ std::type_info *, but GDB doesn't really look at the
+ type_info object itself, so we don't bother to get the type
+ exactly right. * /
+ void *type_info;
+
+ / * Virtual table pointers in objects point here. * /
+
+ / * Virtual function pointers. Like the vcall/vbase array, the
+ real length of this table depends on the class hierarchy. * /
+ void (*virtual_functions[0]) ();
+
+ };
+
+ The catch, of course, is that the exact layout of this table
+ depends on the ABI --- word size, endianness, alignment, etc. So
+ the GDB type object is actually a per-architecture kind of thing.
+
+ vtable_type_gdbarch_data is a gdbarch per-architecture data pointer
+ which refers to the struct type * for this structure, laid out
+ appropriately for the architecture. */
+static struct gdbarch_data *vtable_type_gdbarch_data;
+
+
+/* Human-readable names for the numbers of the fields above. */
+enum {
+ vtable_field_vcall_and_vbase_offsets,
+ vtable_field_offset_to_top,
+ vtable_field_type_info,
+ vtable_field_virtual_functions
+};
+
+
+/* Return a GDB type representing `struct gdb_gnu_v3_abi_vtable',
+ described above, laid out appropriately for ARCH.
+
+ We use this function as the gdbarch per-architecture data
+ initialization function. We assume that the gdbarch framework
+ calls the per-architecture data initialization functions after it
+ sets current_gdbarch to the new architecture. */
+static void *
+build_gdb_vtable_type (struct gdbarch *arch)
+{
+ struct type *t;
+ struct field *field_list, *field;
+ int offset;
+
+ struct type *void_ptr_type
+ = lookup_pointer_type (builtin_type_void);
+ struct type *ptr_to_void_fn_type
+ = lookup_pointer_type (lookup_function_type (builtin_type_void));
+
+ /* ARCH can't give us the true ptrdiff_t type, so we guess. */
+ struct type *ptrdiff_type
+ = init_type (TYPE_CODE_INT, TARGET_PTR_BIT / TARGET_CHAR_BIT, 0,
+ "ptrdiff_t", 0);
+
+ /* We assume no padding is necessary, since GDB doesn't know
+ anything about alignment at the moment. If this assumption bites
+ us, we should add a gdbarch method which, given a type, returns
+ the alignment that type requires, and then use that here. */
+
+ /* Build the field list. */
+ field_list = xmalloc (sizeof (struct field [4]));
+ memset (field_list, 0, sizeof (struct field [4]));
+ field = &field_list[0];
+ offset = 0;
+
+ /* ptrdiff_t vcall_and_vbase_offsets[0]; */
+ FIELD_NAME (*field) = "vcall_and_vbase_offsets";
+ FIELD_TYPE (*field)
+ = create_array_type (0, ptrdiff_type,
+ create_range_type (0, builtin_type_int, 0, -1));
+ FIELD_BITPOS (*field) = offset * TARGET_CHAR_BIT;
+ offset += TYPE_LENGTH (FIELD_TYPE (*field));
+ field++;
+
+ /* ptrdiff_t offset_to_top; */
+ FIELD_NAME (*field) = "offset_to_top";
+ FIELD_TYPE (*field) = ptrdiff_type;
+ FIELD_BITPOS (*field) = offset * TARGET_CHAR_BIT;
+ offset += TYPE_LENGTH (FIELD_TYPE (*field));
+ field++;
+
+ /* void *type_info; */
+ FIELD_NAME (*field) = "type_info";
+ FIELD_TYPE (*field) = void_ptr_type;
+ FIELD_BITPOS (*field) = offset * TARGET_CHAR_BIT;
+ offset += TYPE_LENGTH (FIELD_TYPE (*field));
+ field++;
+
+ /* void (*virtual_functions[0]) (); */
+ FIELD_NAME (*field) = "virtual_functions";
+ FIELD_TYPE (*field)
+ = create_array_type (0, ptr_to_void_fn_type,
+ create_range_type (0, builtin_type_int, 0, -1));
+ FIELD_BITPOS (*field) = offset * TARGET_CHAR_BIT;
+ offset += TYPE_LENGTH (FIELD_TYPE (*field));
+ field++;
+
+ /* We assumed in the allocation above that there were four fields. */
+ gdb_assert (field == (field_list + 4));
+
+ t = init_type (TYPE_CODE_STRUCT, offset, 0, 0, 0);
+ TYPE_NFIELDS (t) = field - field_list;
+ TYPE_FIELDS (t) = field_list;
+ TYPE_TAG_NAME (t) = "gdb_gnu_v3_abi_vtable";
+
+ return t;
+}
+
+
+/* Return the offset from the start of the imaginary `struct
+ gdb_gnu_v3_abi_vtable' object to the vtable's "address point"
+ (i.e., where objects' virtual table pointers point). */
+static int
+vtable_address_point_offset ()
+{
+ struct type *vtable_type = gdbarch_data (current_gdbarch,
+ vtable_type_gdbarch_data);
+
+ return (TYPE_FIELD_BITPOS (vtable_type, vtable_field_virtual_functions)
+ / TARGET_CHAR_BIT);
+}
+
+
+static struct type *
+gnuv3_rtti_type (struct value *value,
+ int *full_p, int *top_p, int *using_enc_p)
+{
+ struct type *vtable_type = gdbarch_data (current_gdbarch,
+ vtable_type_gdbarch_data);
+ struct type *value_type = check_typedef (VALUE_TYPE (value));
+ CORE_ADDR vtable_address;
+ struct value *vtable;
+ struct minimal_symbol *vtable_symbol;
+ const char *vtable_symbol_name;
+ const char *class_name;
+ struct symbol *class_symbol;
+ struct type *run_time_type;
+ struct type *base_type;
+ LONGEST offset_to_top;
+
+ /* We only have RTTI for class objects. */
+ if (TYPE_CODE (value_type) != TYPE_CODE_CLASS)
+ return NULL;
+
+ /* If we can't find the virtual table pointer for value_type, we
+ can't find the RTTI. */
+ fill_in_vptr_fieldno (value_type);
+ if (TYPE_VPTR_FIELDNO (value_type) == -1)
+ return NULL;
+
+ if (using_enc_p)
+ *using_enc_p = 0;
+
+ /* Fetch VALUE's virtual table pointer, and tweak it to point at
+ an instance of our imaginary gdb_gnu_v3_abi_vtable structure. */
+ base_type = check_typedef (TYPE_VPTR_BASETYPE (value_type));
+ if (value_type != base_type)
+ {
+ value = value_cast (base_type, value);
+ if (using_enc_p)
+ *using_enc_p = 1;
+ }
+ vtable_address
+ = value_as_address (value_field (value, TYPE_VPTR_FIELDNO (value_type)));
+ vtable = value_at_lazy (vtable_type,
+ vtable_address - vtable_address_point_offset (),
+ VALUE_BFD_SECTION (value));
+
+ /* Find the linker symbol for this vtable. */
+ vtable_symbol
+ = lookup_minimal_symbol_by_pc (VALUE_ADDRESS (vtable)
+ + VALUE_OFFSET (vtable)
+ + VALUE_EMBEDDED_OFFSET (vtable));
+ if (! vtable_symbol)
+ return NULL;
+
+ /* The symbol's demangled name should be something like "vtable for
+ CLASS", where CLASS is the name of the run-time type of VALUE.
+ If we didn't like this approach, we could instead look in the
+ type_info object itself to get the class name. But this way
+ should work just as well, and doesn't read target memory. */
+ vtable_symbol_name = SYMBOL_DEMANGLED_NAME (vtable_symbol);
+ if (vtable_symbol_name == NULL
+ || strncmp (vtable_symbol_name, "vtable for ", 11))
+ {
+ warning ("can't find linker symbol for virtual table for `%s' value",
+ TYPE_NAME (value_type));
+ if (vtable_symbol_name)
+ warning (" found `%s' instead", vtable_symbol_name);
+ return NULL;
+ }
+ class_name = vtable_symbol_name + 11;
+
+ /* Try to look up the class name as a type name. */
+ class_symbol = lookup_symbol (class_name, 0, STRUCT_NAMESPACE, 0, 0);
+ if (! class_symbol)
+ {
+ warning ("can't find class named `%s', as given by C++ RTTI", class_name);
+ return NULL;
+ }
+
+ /* Make sure the type symbol is sane. (An earlier version of this
+ code would find constructor functions, who have the same name as
+ the class.) */
+ if (SYMBOL_CLASS (class_symbol) != LOC_TYPEDEF
+ || TYPE_CODE (SYMBOL_TYPE (class_symbol)) != TYPE_CODE_CLASS)
+ {
+ warning ("C++ RTTI gives a class name of `%s', but that isn't a type name",
+ class_name);
+ return NULL;
+ }
+
+ /* This is the object's run-time type! */
+ run_time_type = SYMBOL_TYPE (class_symbol);
+
+ /* Get the offset from VALUE to the top of the complete object.
+ NOTE: this is the reverse of the meaning of *TOP_P. */
+ offset_to_top
+ = value_as_long (value_field (vtable, vtable_field_offset_to_top));
+
+ if (full_p)
+ *full_p = (- offset_to_top == VALUE_EMBEDDED_OFFSET (value)
+ && (TYPE_LENGTH (VALUE_ENCLOSING_TYPE (value))
+ >= TYPE_LENGTH (run_time_type)));
+ if (top_p)
+ *top_p = - offset_to_top;
+
+ return run_time_type;
+}
+
+
+static struct value *
+gnuv3_virtual_fn_field (struct value **value_p,
+ struct fn_field *f, int j,
+ struct type *type, int offset)
+{
+ struct type *vtable_type = gdbarch_data (current_gdbarch,
+ vtable_type_gdbarch_data);
+ struct value *value = *value_p;
+ struct type *value_type = check_typedef (VALUE_TYPE (value));
+ struct type *vfn_base;
+ CORE_ADDR vtable_address;
+ struct value *vtable;
+ struct value *vfn;
+
+ /* Some simple sanity checks. */
+ if (TYPE_CODE (value_type) != TYPE_CODE_CLASS)
+ error ("Only classes can have virtual functions.");
+
+ /* Find the base class that defines this virtual function. */
+ vfn_base = TYPE_FN_FIELD_FCONTEXT (f, j);
+ if (! vfn_base)
+ /* In programs compiled with G++ version 1, the debug info doesn't
+ say which base class defined the virtual function. We'll guess
+ it's the same base class that has our vtable; this is wrong for
+ multiple inheritance, but it's better than nothing. */
+ vfn_base = TYPE_VPTR_BASETYPE (type);
+
+ /* This type may have been defined before its virtual function table
+ was. If so, fill in the virtual function table entry for the
+ type now. */
+ if (TYPE_VPTR_FIELDNO (vfn_base) < 0)
+ fill_in_vptr_fieldno (vfn_base);
+
+ /* Now that we know which base class is defining our virtual
+ function, cast our value to that baseclass. This takes care of
+ any necessary `this' adjustments. */
+ if (vfn_base != value_type)
+ value = value_cast (vfn_base, value);
+
+ /* Now value is an object of the appropriate base type. Fetch its
+ virtual table. */
+ /* It might be possible to do this cast at the same time as the above.
+ Does multiple inheritance affect this?
+ Can this even trigger, or is TYPE_VPTR_BASETYPE idempotent?
+ */
+ if (TYPE_VPTR_BASETYPE (vfn_base) != vfn_base)
+ value = value_cast (TYPE_VPTR_BASETYPE (vfn_base), value);
+ vtable_address
+ = value_as_address (value_field (value, TYPE_VPTR_FIELDNO (vfn_base)));
+
+ vtable = value_at_lazy (vtable_type,
+ vtable_address - vtable_address_point_offset (),
+ VALUE_BFD_SECTION (value));
+
+ /* Fetch the appropriate function pointer from the vtable. */
+ vfn = value_subscript (value_field (vtable, vtable_field_virtual_functions),
+ value_from_longest (builtin_type_int,
+ TYPE_FN_FIELD_VOFFSET (f, j)));
+
+ /* Cast the function pointer to the appropriate type. */
+ vfn = value_cast (lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j)),
+ vfn);
+
+ /* Is (type)value always numerically the same as (vfn_base)value?
+ If so we can spare this cast and use one of the ones above. */
+ *value_p = value_addr (value_cast (type, *value_p));
+
+ return vfn;
+}
+
+/* Compute the offset of the baseclass which is
+ the INDEXth baseclass of class TYPE,
+ for value at VALADDR (in host) at ADDRESS (in target).
+ The result is the offset of the baseclass value relative
+ to (the address of)(ARG) + OFFSET.
+
+ -1 is returned on error. */
+int
+gnuv3_baseclass_offset (struct type *type, int index, char *valaddr,
+ CORE_ADDR address)
+{
+ struct type *vtable_type = gdbarch_data (current_gdbarch,
+ vtable_type_gdbarch_data);
+ struct type *basetype = TYPE_BASECLASS (type, index);
+ struct value *full_object, *vbase_object, *orig_object;
+ struct value *vtable, *orig_typeinfo, *orig_base_info;
+ struct type *orig_type, *vbasetype;
+ struct value *offset_val, *vbase_array;
+ CORE_ADDR vtable_address;
+ long int cur_base_offset, base_offset;
+ int to_top;
+ int baseclasses, i;
+
+ /* If it isn't a virtual base, this is easy. The offset is in the
+ type definition. */
+ if (!BASETYPE_VIA_VIRTUAL (type, index))
+ return TYPE_BASECLASS_BITPOS (type, index) / 8;
+
+ /* To access a virtual base, we need to use the vbase offset stored in
+ our vtable. Recent GCC versions provide this information. If it isn't
+ available, we could get what we needed from RTTI, or from drawing the
+ complete inheritance graph based on the debug info. Neither is
+ worthwhile. */
+ cur_base_offset = TYPE_BASECLASS_BITPOS (type, index) / 8;
+ if (cur_base_offset >= - vtable_address_point_offset ())
+ error ("Expected a negative vbase offset (old compiler?)");
+
+ cur_base_offset = cur_base_offset + vtable_address_point_offset ();
+ if ((- cur_base_offset) % TYPE_LENGTH (builtin_type_void_data_ptr) != 0)
+ error ("Misaligned vbase offset.");
+ cur_base_offset = cur_base_offset
+ / ((int) TYPE_LENGTH (builtin_type_void_data_ptr));
+
+ /* We're now looking for the cur_base_offset'th entry (negative index)
+ in the vcall_and_vbase_offsets array. */
+
+ orig_object = value_at_lazy (type, address, NULL);
+ vbasetype = TYPE_VPTR_BASETYPE (VALUE_TYPE (orig_object));
+ vbase_object = value_cast (vbasetype, orig_object);
+
+ vtable_address
+ = value_as_address (value_field (vbase_object,
+ TYPE_VPTR_FIELDNO (vbasetype)));
+ vtable = value_at_lazy (vtable_type,
+ vtable_address - vtable_address_point_offset (),
+ NULL);
+ offset_val = value_from_longest(builtin_type_int, cur_base_offset);
+ vbase_array = value_field (vtable, vtable_field_vcall_and_vbase_offsets);
+ base_offset = value_as_long (value_subscript (vbase_array, offset_val));
+ return base_offset;
+}
+
+static void
+init_gnuv3_ops (void)
+{
+ vtable_type_gdbarch_data = register_gdbarch_data (build_gdb_vtable_type, 0);
+
+ gnu_v3_abi_ops.shortname = "gnu-v3";
+ gnu_v3_abi_ops.longname = "GNU G++ Version 3 ABI";
+ gnu_v3_abi_ops.doc = "G++ Version 3 ABI";
+ gnu_v3_abi_ops.is_destructor_name = is_gnu_v3_mangled_dtor;
+ gnu_v3_abi_ops.is_constructor_name = is_gnu_v3_mangled_ctor;
+ gnu_v3_abi_ops.is_vtable_name = gnuv3_is_vtable_name;
+ gnu_v3_abi_ops.is_operator_name = gnuv3_is_operator_name;
+ gnu_v3_abi_ops.rtti_type = gnuv3_rtti_type;
+ gnu_v3_abi_ops.virtual_fn_field = gnuv3_virtual_fn_field;
+ gnu_v3_abi_ops.baseclass_offset = gnuv3_baseclass_offset;
+}
+
+
+void
+_initialize_gnu_v3_abi (void)
+{
+ init_gnuv3_ops ();
+
+ register_cp_abi (gnu_v3_abi_ops);
+}
diff --git a/gdb/go32-nat.c b/gdb/go32-nat.c
new file mode 100644
index 00000000000..a16b1b37295
--- /dev/null
+++ b/gdb/go32-nat.c
@@ -0,0 +1,1963 @@
+/* Native debugging support for Intel x86 running DJGPP.
+ Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Written by Robert Hoehne.
+
+ 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 <fcntl.h>
+
+#include "defs.h"
+#include "inferior.h"
+#include "gdb_wait.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "floatformat.h"
+#include "buildsym.h"
+#include "i387-tdep.h"
+#include "i386-tdep.h"
+#include "value.h"
+#include "regcache.h"
+#include "gdb_string.h"
+
+#include <stdio.h> /* might be required for __DJGPP_MINOR__ */
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+#include <io.h>
+#include <dos.h>
+#include <dpmi.h>
+#include <go32.h>
+#include <sys/farptr.h>
+#include <debug/v2load.h>
+#include <debug/dbgcom.h>
+#if __DJGPP_MINOR__ > 2
+#include <debug/redir.h>
+#endif
+
+#if __DJGPP_MINOR__ < 3
+/* This code will be provided from DJGPP 2.03 on. Until then I code it
+ here */
+typedef struct
+ {
+ unsigned short sig0;
+ unsigned short sig1;
+ unsigned short sig2;
+ unsigned short sig3;
+ unsigned short exponent:15;
+ unsigned short sign:1;
+ }
+NPXREG;
+
+typedef struct
+ {
+ unsigned int control;
+ unsigned int status;
+ unsigned int tag;
+ unsigned int eip;
+ unsigned int cs;
+ unsigned int dataptr;
+ unsigned int datasel;
+ NPXREG reg[8];
+ }
+NPX;
+
+static NPX npx;
+
+static void save_npx (void); /* Save the FPU of the debugged program */
+static void load_npx (void); /* Restore the FPU of the debugged program */
+
+/* ------------------------------------------------------------------------- */
+/* Store the contents of the NPX in the global variable `npx'. */
+/* *INDENT-OFF* */
+
+static void
+save_npx (void)
+{
+ asm ("inb $0xa0, %%al \n\
+ testb $0x20, %%al \n\
+ jz 1f \n\
+ xorb %%al, %%al \n\
+ outb %%al, $0xf0 \n\
+ movb $0x20, %%al \n\
+ outb %%al, $0xa0 \n\
+ outb %%al, $0x20 \n\
+1: \n\
+ fnsave %0 \n\
+ fwait "
+: "=m" (npx)
+: /* No input */
+: "%eax");
+}
+
+/* *INDENT-ON* */
+
+
+/* ------------------------------------------------------------------------- */
+/* Reload the contents of the NPX from the global variable `npx'. */
+
+static void
+load_npx (void)
+{
+ asm ("frstor %0":"=m" (npx));
+}
+/* ------------------------------------------------------------------------- */
+/* Stubs for the missing redirection functions. */
+typedef struct {
+ char *command;
+ int redirected;
+} cmdline_t;
+
+void
+redir_cmdline_delete (cmdline_t *ptr)
+{
+ ptr->redirected = 0;
+}
+
+int
+redir_cmdline_parse (const char *args, cmdline_t *ptr)
+{
+ return -1;
+}
+
+int
+redir_to_child (cmdline_t *ptr)
+{
+ return 1;
+}
+
+int
+redir_to_debugger (cmdline_t *ptr)
+{
+ return 1;
+}
+
+int
+redir_debug_init (cmdline_t *ptr)
+{
+ return 0;
+}
+#endif /* __DJGPP_MINOR < 3 */
+
+typedef enum { wp_insert, wp_remove, wp_count } wp_op;
+
+/* This holds the current reference counts for each debug register. */
+static int dr_ref_count[4];
+
+#define SOME_PID 42
+
+static int prog_has_started = 0;
+static void go32_open (char *name, int from_tty);
+static void go32_close (int quitting);
+static void go32_attach (char *args, int from_tty);
+static void go32_detach (char *args, int from_tty);
+static void go32_resume (ptid_t ptid, int step,
+ enum target_signal siggnal);
+static ptid_t go32_wait (ptid_t ptid,
+ struct target_waitstatus *status);
+static void go32_fetch_registers (int regno);
+static void store_register (int regno);
+static void go32_store_registers (int regno);
+static void go32_prepare_to_store (void);
+static int go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int write,
+ struct mem_attrib *attrib,
+ struct target_ops *target);
+static void go32_files_info (struct target_ops *target);
+static void go32_stop (void);
+static void go32_kill_inferior (void);
+static void go32_create_inferior (char *exec_file, char *args, char **env);
+static void go32_mourn_inferior (void);
+static int go32_can_run (void);
+
+static struct target_ops go32_ops;
+static void go32_terminal_init (void);
+static void go32_terminal_inferior (void);
+static void go32_terminal_ours (void);
+
+#define r_ofs(x) (offsetof(TSS,x))
+
+static struct
+{
+ size_t tss_ofs;
+ size_t size;
+}
+regno_mapping[] =
+{
+ {r_ofs (tss_eax), 4}, /* normal registers, from a_tss */
+ {r_ofs (tss_ecx), 4},
+ {r_ofs (tss_edx), 4},
+ {r_ofs (tss_ebx), 4},
+ {r_ofs (tss_esp), 4},
+ {r_ofs (tss_ebp), 4},
+ {r_ofs (tss_esi), 4},
+ {r_ofs (tss_edi), 4},
+ {r_ofs (tss_eip), 4},
+ {r_ofs (tss_eflags), 4},
+ {r_ofs (tss_cs), 2},
+ {r_ofs (tss_ss), 2},
+ {r_ofs (tss_ds), 2},
+ {r_ofs (tss_es), 2},
+ {r_ofs (tss_fs), 2},
+ {r_ofs (tss_gs), 2},
+ {0, 10}, /* 8 FP registers, from npx.reg[] */
+ {1, 10},
+ {2, 10},
+ {3, 10},
+ {4, 10},
+ {5, 10},
+ {6, 10},
+ {7, 10},
+ /* The order of the next 7 registers must be consistent
+ with their numbering in config/i386/tm-i386.h, which see. */
+ {0, 2}, /* control word, from npx */
+ {4, 2}, /* status word, from npx */
+ {8, 2}, /* tag word, from npx */
+ {16, 2}, /* last FP exception CS from npx */
+ {12, 4}, /* last FP exception EIP from npx */
+ {24, 2}, /* last FP exception operand selector from npx */
+ {20, 4}, /* last FP exception operand offset from npx */
+ {18, 2} /* last FP opcode from npx */
+};
+
+static struct
+ {
+ int go32_sig;
+ enum target_signal gdb_sig;
+ }
+sig_map[] =
+{
+ {0, TARGET_SIGNAL_FPE},
+ {1, TARGET_SIGNAL_TRAP},
+ /* Exception 2 is triggered by the NMI. DJGPP handles it as SIGILL,
+ but I think SIGBUS is better, since the NMI is usually activated
+ as a result of a memory parity check failure. */
+ {2, TARGET_SIGNAL_BUS},
+ {3, TARGET_SIGNAL_TRAP},
+ {4, TARGET_SIGNAL_FPE},
+ {5, TARGET_SIGNAL_SEGV},
+ {6, TARGET_SIGNAL_ILL},
+ {7, TARGET_SIGNAL_EMT}, /* no-coprocessor exception */
+ {8, TARGET_SIGNAL_SEGV},
+ {9, TARGET_SIGNAL_SEGV},
+ {10, TARGET_SIGNAL_BUS},
+ {11, TARGET_SIGNAL_SEGV},
+ {12, TARGET_SIGNAL_SEGV},
+ {13, TARGET_SIGNAL_SEGV},
+ {14, TARGET_SIGNAL_SEGV},
+ {16, TARGET_SIGNAL_FPE},
+ {17, TARGET_SIGNAL_BUS},
+ {31, TARGET_SIGNAL_ILL},
+ {0x1b, TARGET_SIGNAL_INT},
+ {0x75, TARGET_SIGNAL_FPE},
+ {0x78, TARGET_SIGNAL_ALRM},
+ {0x79, TARGET_SIGNAL_INT},
+ {0x7a, TARGET_SIGNAL_QUIT},
+ {-1, TARGET_SIGNAL_LAST}
+};
+
+static struct {
+ enum target_signal gdb_sig;
+ int djgpp_excepno;
+} excepn_map[] = {
+ {TARGET_SIGNAL_0, -1},
+ {TARGET_SIGNAL_ILL, 6}, /* Invalid Opcode */
+ {TARGET_SIGNAL_EMT, 7}, /* triggers SIGNOFP */
+ {TARGET_SIGNAL_SEGV, 13}, /* GPF */
+ {TARGET_SIGNAL_BUS, 17}, /* Alignment Check */
+ /* The rest are fake exceptions, see dpmiexcp.c in djlsr*.zip for
+ details. */
+ {TARGET_SIGNAL_TERM, 0x1b}, /* triggers Ctrl-Break type of SIGINT */
+ {TARGET_SIGNAL_FPE, 0x75},
+ {TARGET_SIGNAL_INT, 0x79},
+ {TARGET_SIGNAL_QUIT, 0x7a},
+ {TARGET_SIGNAL_ALRM, 0x78}, /* triggers SIGTIMR */
+ {TARGET_SIGNAL_PROF, 0x78},
+ {TARGET_SIGNAL_LAST, -1}
+};
+
+static void
+go32_open (char *name, int from_tty)
+{
+ printf_unfiltered ("Done. Use the \"run\" command to run the program.\n");
+}
+
+static void
+go32_close (int quitting)
+{
+}
+
+static void
+go32_attach (char *args, int from_tty)
+{
+ error ("\
+You cannot attach to a running program on this platform.\n\
+Use the `run' command to run DJGPP programs.");
+}
+
+static void
+go32_detach (char *args, int from_tty)
+{
+}
+
+static int resume_is_step;
+static int resume_signal = -1;
+
+static void
+go32_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ int i;
+
+ resume_is_step = step;
+
+ if (siggnal != TARGET_SIGNAL_0 && siggnal != TARGET_SIGNAL_TRAP)
+ {
+ for (i = 0, resume_signal = -1;
+ excepn_map[i].gdb_sig != TARGET_SIGNAL_LAST; i++)
+ if (excepn_map[i].gdb_sig == siggnal)
+ {
+ resume_signal = excepn_map[i].djgpp_excepno;
+ break;
+ }
+ if (resume_signal == -1)
+ printf_unfiltered ("Cannot deliver signal %s on this platform.\n",
+ target_signal_to_name (siggnal));
+ }
+}
+
+static char child_cwd[FILENAME_MAX];
+
+static ptid_t
+go32_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ int i;
+ unsigned char saved_opcode;
+ unsigned long INT3_addr = 0;
+ int stepping_over_INT = 0;
+
+ a_tss.tss_eflags &= 0xfeff; /* reset the single-step flag (TF) */
+ if (resume_is_step)
+ {
+ /* If the next instruction is INT xx or INTO, we need to handle
+ them specially. Intel manuals say that these instructions
+ reset the single-step flag (a.k.a. TF). However, it seems
+ that, at least in the DPMI environment, and at least when
+ stepping over the DPMI interrupt 31h, the problem is having
+ TF set at all when INT 31h is executed: the debuggee either
+ crashes (and takes the system with it) or is killed by a
+ SIGTRAP.
+
+ So we need to emulate single-step mode: we put an INT3 opcode
+ right after the INT xx instruction, let the debuggee run
+ until it hits INT3 and stops, then restore the original
+ instruction which we overwrote with the INT3 opcode, and back
+ up the debuggee's EIP to that instruction. */
+ read_child (a_tss.tss_eip, &saved_opcode, 1);
+ if (saved_opcode == 0xCD || saved_opcode == 0xCE)
+ {
+ unsigned char INT3_opcode = 0xCC;
+
+ INT3_addr
+ = saved_opcode == 0xCD ? a_tss.tss_eip + 2 : a_tss.tss_eip + 1;
+ stepping_over_INT = 1;
+ read_child (INT3_addr, &saved_opcode, 1);
+ write_child (INT3_addr, &INT3_opcode, 1);
+ }
+ else
+ a_tss.tss_eflags |= 0x0100; /* normal instruction: set TF */
+ }
+
+ /* The special value FFFFh in tss_trap indicates to run_child that
+ tss_irqn holds a signal to be delivered to the debuggee. */
+ if (resume_signal <= -1)
+ {
+ a_tss.tss_trap = 0;
+ a_tss.tss_irqn = 0xff;
+ }
+ else
+ {
+ a_tss.tss_trap = 0xffff; /* run_child looks for this */
+ a_tss.tss_irqn = resume_signal;
+ }
+
+ /* The child might change working directory behind our back. The
+ GDB users won't like the side effects of that when they work with
+ relative file names, and GDB might be confused by its current
+ directory not being in sync with the truth. So we always make a
+ point of changing back to where GDB thinks is its cwd, when we
+ return control to the debugger, but restore child's cwd before we
+ run it. */
+ /* Initialize child_cwd, before the first call to run_child and not
+ in the initialization, so the child get also the changed directory
+ set with the gdb-command "cd ..." */
+ if (!*child_cwd)
+ /* Initialize child's cwd with the current one. */
+ getcwd (child_cwd, sizeof (child_cwd));
+
+ chdir (child_cwd);
+
+#if __DJGPP_MINOR__ < 3
+ load_npx ();
+#endif
+ run_child ();
+#if __DJGPP_MINOR__ < 3
+ save_npx ();
+#endif
+
+ /* Did we step over an INT xx instruction? */
+ if (stepping_over_INT && a_tss.tss_eip == INT3_addr + 1)
+ {
+ /* Restore the original opcode. */
+ a_tss.tss_eip--; /* EIP points *after* the INT3 instruction */
+ write_child (a_tss.tss_eip, &saved_opcode, 1);
+ /* Simulate a TRAP exception. */
+ a_tss.tss_irqn = 1;
+ a_tss.tss_eflags |= 0x0100;
+ }
+
+ getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */
+ chdir (current_directory);
+
+ if (a_tss.tss_irqn == 0x21)
+ {
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = a_tss.tss_eax & 0xff;
+ }
+ else
+ {
+ status->value.sig = TARGET_SIGNAL_UNKNOWN;
+ status->kind = TARGET_WAITKIND_STOPPED;
+ for (i = 0; sig_map[i].go32_sig != -1; i++)
+ {
+ if (a_tss.tss_irqn == sig_map[i].go32_sig)
+ {
+#if __DJGPP_MINOR__ < 3
+ if ((status->value.sig = sig_map[i].gdb_sig) !=
+ TARGET_SIGNAL_TRAP)
+ status->kind = TARGET_WAITKIND_SIGNALLED;
+#else
+ status->value.sig = sig_map[i].gdb_sig;
+#endif
+ break;
+ }
+ }
+ }
+ return pid_to_ptid (SOME_PID);
+}
+
+static void
+fetch_register (int regno)
+{
+ if (regno < FP0_REGNUM)
+ supply_register (regno, (char *) &a_tss + regno_mapping[regno].tss_ofs);
+ else if (FP_REGNUM_P (regno) || FPC_REGNUM_P (regno))
+ i387_supply_register (regno, (char *) &npx);
+ else
+ internal_error (__FILE__, __LINE__,
+ "Invalid register no. %d in fetch_register.", regno);
+}
+
+static void
+go32_fetch_registers (int regno)
+{
+ if (regno >= 0)
+ fetch_register (regno);
+ else
+ {
+ for (regno = 0; regno < FP0_REGNUM; regno++)
+ fetch_register (regno);
+ i387_supply_fsave ((char *) &npx);
+ }
+}
+
+static void
+store_register (int regno)
+{
+ if (regno < FP0_REGNUM)
+ regcache_collect (regno, (char *) &a_tss + regno_mapping[regno].tss_ofs);
+ else if (FP_REGNUM_P (regno) || FPC_REGNUM_P (regno))
+ i387_fill_fsave ((char *) &npx, regno);
+ else
+ internal_error (__FILE__, __LINE__,
+ "Invalid register no. %d in store_register.", regno);
+}
+
+static void
+go32_store_registers (int regno)
+{
+ unsigned r;
+
+ if (regno >= 0)
+ store_register (regno);
+ else
+ {
+ for (r = 0; r < FP0_REGNUM; r++)
+ store_register (r);
+ i387_fill_fsave ((char *) &npx, -1);
+ }
+}
+
+static void
+go32_prepare_to_store (void)
+{
+}
+
+static int
+go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib, struct target_ops *target)
+{
+ if (write)
+ {
+ if (write_child (memaddr, myaddr, len))
+ {
+ return 0;
+ }
+ else
+ {
+ return len;
+ }
+ }
+ else
+ {
+ if (read_child (memaddr, myaddr, len))
+ {
+ return 0;
+ }
+ else
+ {
+ return len;
+ }
+ }
+}
+
+static cmdline_t child_cmd; /* parsed child's command line kept here */
+
+static void
+go32_files_info (struct target_ops *target)
+{
+ printf_unfiltered ("You are running a DJGPP V2 program.\n");
+}
+
+static void
+go32_stop (void)
+{
+ normal_stop ();
+ cleanup_client ();
+ inferior_ptid = null_ptid;
+ prog_has_started = 0;
+}
+
+static void
+go32_kill_inferior (void)
+{
+ redir_cmdline_delete (&child_cmd);
+ resume_signal = -1;
+ resume_is_step = 0;
+ unpush_target (&go32_ops);
+}
+
+static void
+go32_create_inferior (char *exec_file, char *args, char **env)
+{
+ extern char **environ;
+ jmp_buf start_state;
+ char *cmdline;
+ char **env_save = environ;
+ size_t cmdlen;
+
+ /* If no exec file handed to us, get it from the exec-file command -- with
+ a good, common error message if none is specified. */
+ if (exec_file == 0)
+ exec_file = get_exec_file (1);
+
+ if (prog_has_started)
+ {
+ go32_stop ();
+ go32_kill_inferior ();
+ }
+ resume_signal = -1;
+ resume_is_step = 0;
+
+ /* Initialize child's cwd as empty to be initialized when starting
+ the child. */
+ *child_cwd = 0;
+
+ /* Init command line storage. */
+ if (redir_debug_init (&child_cmd) == -1)
+ internal_error (__FILE__, __LINE__,
+ "Cannot allocate redirection storage: not enough memory.\n");
+
+ /* Parse the command line and create redirections. */
+ if (strpbrk (args, "<>"))
+ {
+ if (redir_cmdline_parse (args, &child_cmd) == 0)
+ args = child_cmd.command;
+ else
+ error ("Syntax error in command line.");
+ }
+ else
+ child_cmd.command = xstrdup (args);
+
+ cmdlen = strlen (args);
+ /* v2loadimage passes command lines via DOS memory, so it cannot
+ possibly handle commands longer than 1MB. */
+ if (cmdlen > 1024*1024)
+ error ("Command line too long.");
+
+ cmdline = xmalloc (cmdlen + 4);
+ strcpy (cmdline + 1, args);
+ /* If the command-line length fits into DOS 126-char limits, use the
+ DOS command tail format; otherwise, tell v2loadimage to pass it
+ through a buffer in conventional memory. */
+ if (cmdlen < 127)
+ {
+ cmdline[0] = strlen (args);
+ cmdline[cmdlen + 1] = 13;
+ }
+ else
+ cmdline[0] = 0xff; /* signal v2loadimage it's a long command */
+
+ environ = env;
+
+ if (v2loadimage (exec_file, cmdline, start_state))
+ {
+ environ = env_save;
+ printf_unfiltered ("Load failed for image %s\n", exec_file);
+ exit (1);
+ }
+ environ = env_save;
+ xfree (cmdline);
+
+ edi_init (start_state);
+#if __DJGPP_MINOR__ < 3
+ save_npx ();
+#endif
+
+ inferior_ptid = pid_to_ptid (SOME_PID);
+ push_target (&go32_ops);
+ clear_proceed_status ();
+ insert_breakpoints ();
+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
+ prog_has_started = 1;
+}
+
+static void
+go32_mourn_inferior (void)
+{
+ /* We need to make sure all the breakpoint enable bits in the DR7
+ register are reset when the inferior exits. Otherwise, if they
+ rerun the inferior, the uncleared bits may cause random SIGTRAPs,
+ failure to set more watchpoints, and other calamities. It would
+ be nice if GDB itself would take care to remove all breakpoints
+ at all times, but it doesn't, probably under an assumption that
+ the OS cleans up when the debuggee exits. */
+ i386_cleanup_dregs ();
+ go32_kill_inferior ();
+ generic_mourn_inferior ();
+}
+
+static int
+go32_can_run (void)
+{
+ return 1;
+}
+
+/* Hardware watchpoint support. */
+
+#define D_REGS edi.dr
+#define CONTROL D_REGS[7]
+#define STATUS D_REGS[6]
+
+/* Pass the address ADDR to the inferior in the I'th debug register.
+ Here we just store the address in D_REGS, the watchpoint will be
+ actually set up when go32_wait runs the debuggee. */
+void
+go32_set_dr (int i, CORE_ADDR addr)
+{
+ if (i < 0 || i > 3)
+ internal_error (__FILE__, __LINE__,
+ "Invalid register %d in go32_set_dr.\n", i);
+ D_REGS[i] = addr;
+}
+
+/* Pass the value VAL to the inferior in the DR7 debug control
+ register. Here we just store the address in D_REGS, the watchpoint
+ will be actually set up when go32_wait runs the debuggee. */
+void
+go32_set_dr7 (unsigned val)
+{
+ CONTROL = val;
+}
+
+/* Get the value of the DR6 debug status register from the inferior.
+ Here we just return the value stored in D_REGS, as we've got it
+ from the last go32_wait call. */
+unsigned
+go32_get_dr6 (void)
+{
+ return STATUS;
+}
+
+/* Put the device open on handle FD into either raw or cooked
+ mode, return 1 if it was in raw mode, zero otherwise. */
+
+static int
+device_mode (int fd, int raw_p)
+{
+ int oldmode, newmode;
+ __dpmi_regs regs;
+
+ regs.x.ax = 0x4400;
+ regs.x.bx = fd;
+ __dpmi_int (0x21, &regs);
+ if (regs.x.flags & 1)
+ return -1;
+ newmode = oldmode = regs.x.dx;
+
+ if (raw_p)
+ newmode |= 0x20;
+ else
+ newmode &= ~0x20;
+
+ if (oldmode & 0x80) /* Only for character dev */
+ {
+ regs.x.ax = 0x4401;
+ regs.x.bx = fd;
+ regs.x.dx = newmode & 0xff; /* Force upper byte zero, else it fails */
+ __dpmi_int (0x21, &regs);
+ if (regs.x.flags & 1)
+ return -1;
+ }
+ return (oldmode & 0x20) == 0x20;
+}
+
+
+static int inf_mode_valid = 0;
+static int inf_terminal_mode;
+
+/* This semaphore is needed because, amazingly enough, GDB calls
+ target.to_terminal_ours more than once after the inferior stops.
+ But we need the information from the first call only, since the
+ second call will always see GDB's own cooked terminal. */
+static int terminal_is_ours = 1;
+
+static void
+go32_terminal_init (void)
+{
+ inf_mode_valid = 0; /* reinitialize, in case they are restarting child */
+ terminal_is_ours = 1;
+}
+
+static void
+go32_terminal_info (char *args, int from_tty)
+{
+ printf_unfiltered ("Inferior's terminal is in %s mode.\n",
+ !inf_mode_valid
+ ? "default" : inf_terminal_mode ? "raw" : "cooked");
+
+#if __DJGPP_MINOR__ > 2
+ if (child_cmd.redirection)
+ {
+ int i;
+
+ for (i = 0; i < DBG_HANDLES; i++)
+ {
+ if (child_cmd.redirection[i]->file_name)
+ printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
+ i, child_cmd.redirection[i]->file_name);
+ else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1)
+ printf_unfiltered
+ ("\tFile handle %d appears to be closed by inferior.\n", i);
+ /* Mask off the raw/cooked bit when comparing device info words. */
+ else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf)
+ != (_get_dev_info (i) & 0xdf))
+ printf_unfiltered
+ ("\tFile handle %d appears to be redirected by inferior.\n", i);
+ }
+ }
+#endif
+}
+
+static void
+go32_terminal_inferior (void)
+{
+ /* Redirect standard handles as child wants them. */
+ errno = 0;
+ if (redir_to_child (&child_cmd) == -1)
+ {
+ redir_to_debugger (&child_cmd);
+ error ("Cannot redirect standard handles for program: %s.",
+ safe_strerror (errno));
+ }
+ /* set the console device of the inferior to whatever mode
+ (raw or cooked) we found it last time */
+ if (terminal_is_ours)
+ {
+ if (inf_mode_valid)
+ device_mode (0, inf_terminal_mode);
+ terminal_is_ours = 0;
+ }
+}
+
+static void
+go32_terminal_ours (void)
+{
+ /* Switch to cooked mode on the gdb terminal and save the inferior
+ terminal mode to be restored when it is resumed */
+ if (!terminal_is_ours)
+ {
+ inf_terminal_mode = device_mode (0, 0);
+ if (inf_terminal_mode != -1)
+ inf_mode_valid = 1;
+ else
+ /* If device_mode returned -1, we don't know what happens with
+ handle 0 anymore, so make the info invalid. */
+ inf_mode_valid = 0;
+ terminal_is_ours = 1;
+
+ /* Restore debugger's standard handles. */
+ errno = 0;
+ if (redir_to_debugger (&child_cmd) == -1)
+ {
+ redir_to_child (&child_cmd);
+ error ("Cannot redirect standard handles for debugger: %s.",
+ safe_strerror (errno));
+ }
+ }
+}
+
+static void
+init_go32_ops (void)
+{
+ go32_ops.to_shortname = "djgpp";
+ go32_ops.to_longname = "djgpp target process";
+ go32_ops.to_doc =
+ "Program loaded by djgpp, when gdb is used as an external debugger";
+ go32_ops.to_open = go32_open;
+ go32_ops.to_close = go32_close;
+ go32_ops.to_attach = go32_attach;
+ go32_ops.to_detach = go32_detach;
+ go32_ops.to_resume = go32_resume;
+ go32_ops.to_wait = go32_wait;
+ go32_ops.to_fetch_registers = go32_fetch_registers;
+ go32_ops.to_store_registers = go32_store_registers;
+ go32_ops.to_prepare_to_store = go32_prepare_to_store;
+ go32_ops.to_xfer_memory = go32_xfer_memory;
+ go32_ops.to_files_info = go32_files_info;
+ go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ go32_ops.to_terminal_init = go32_terminal_init;
+ go32_ops.to_terminal_inferior = go32_terminal_inferior;
+ go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
+ go32_ops.to_terminal_ours = go32_terminal_ours;
+ go32_ops.to_terminal_info = go32_terminal_info;
+ go32_ops.to_kill = go32_kill_inferior;
+ go32_ops.to_create_inferior = go32_create_inferior;
+ go32_ops.to_mourn_inferior = go32_mourn_inferior;
+ go32_ops.to_can_run = go32_can_run;
+ go32_ops.to_stop = go32_stop;
+ go32_ops.to_stratum = process_stratum;
+ go32_ops.to_has_all_memory = 1;
+ go32_ops.to_has_memory = 1;
+ go32_ops.to_has_stack = 1;
+ go32_ops.to_has_registers = 1;
+ go32_ops.to_has_execution = 1;
+ go32_ops.to_magic = OPS_MAGIC;
+
+ /* Initialize child's cwd as empty to be initialized when starting
+ the child. */
+ *child_cwd = 0;
+
+ /* Initialize child's command line storage. */
+ if (redir_debug_init (&child_cmd) == -1)
+ internal_error (__FILE__, __LINE__,
+ "Cannot allocate redirection storage: not enough memory.\n");
+
+ /* We are always processing GCC-compiled programs. */
+ processing_gcc_compilation = 2;
+}
+
+unsigned short windows_major, windows_minor;
+
+/* Compute the version Windows reports via Int 2Fh/AX=1600h. */
+static void
+go32_get_windows_version(void)
+{
+ __dpmi_regs r;
+
+ r.x.ax = 0x1600;
+ __dpmi_int(0x2f, &r);
+ if (r.h.al > 2 && r.h.al != 0x80 && r.h.al != 0xff
+ && (r.h.al > 3 || r.h.ah > 0))
+ {
+ windows_major = r.h.al;
+ windows_minor = r.h.ah;
+ }
+ else
+ windows_major = 0xff; /* meaning no Windows */
+}
+
+/* A subroutine of go32_sysinfo to display memory info. */
+static void
+print_mem (unsigned long datum, const char *header, int in_pages_p)
+{
+ if (datum != 0xffffffffUL)
+ {
+ if (in_pages_p)
+ datum <<= 12;
+ puts_filtered (header);
+ if (datum > 1024)
+ {
+ printf_filtered ("%lu KB", datum >> 10);
+ if (datum > 1024 * 1024)
+ printf_filtered (" (%lu MB)", datum >> 20);
+ }
+ else
+ printf_filtered ("%lu Bytes", datum);
+ puts_filtered ("\n");
+ }
+}
+
+/* Display assorted information about the underlying OS. */
+static void
+go32_sysinfo (char *arg, int from_tty)
+{
+ struct utsname u;
+ char cpuid_vendor[13];
+ unsigned cpuid_max = 0, cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
+ unsigned true_dos_version = _get_dos_version (1);
+ unsigned advertized_dos_version = ((unsigned int)_osmajor << 8) | _osminor;
+ int dpmi_flags;
+ char dpmi_vendor_info[129];
+ int dpmi_vendor_available =
+ __dpmi_get_capabilities (&dpmi_flags, dpmi_vendor_info);
+ __dpmi_version_ret dpmi_version_data;
+ long eflags;
+ __dpmi_free_mem_info mem_info;
+ __dpmi_regs regs;
+
+ cpuid_vendor[0] = '\0';
+ if (uname (&u))
+ strcpy (u.machine, "Unknown x86");
+ else if (u.machine[0] == 'i' && u.machine[1] > 4)
+ {
+ /* CPUID with EAX = 0 returns the Vendor ID. */
+ __asm__ __volatile__ ("xorl %%ebx, %%ebx;"
+ "xorl %%ecx, %%ecx;"
+ "xorl %%edx, %%edx;"
+ "movl $0, %%eax;"
+ "cpuid;"
+ "movl %%ebx, %0;"
+ "movl %%edx, %1;"
+ "movl %%ecx, %2;"
+ "movl %%eax, %3;"
+ : "=m" (cpuid_vendor[0]),
+ "=m" (cpuid_vendor[4]),
+ "=m" (cpuid_vendor[8]),
+ "=m" (cpuid_max)
+ :
+ : "%eax", "%ebx", "%ecx", "%edx");
+ cpuid_vendor[12] = '\0';
+ }
+
+ printf_filtered ("CPU Type.......................%s", u.machine);
+ if (cpuid_vendor[0])
+ printf_filtered (" (%s)", cpuid_vendor);
+ puts_filtered ("\n");
+
+ /* CPUID with EAX = 1 returns processor signature and features. */
+ if (cpuid_max >= 1)
+ {
+ static char *brand_name[] = {
+ "",
+ " Celeron",
+ " III",
+ " III Xeon",
+ "", "", "", "",
+ " 4"
+ };
+ char cpu_string[80];
+ char cpu_brand[20];
+ unsigned brand_idx;
+ int intel_p = strcmp (cpuid_vendor, "GenuineIntel") == 0;
+ int amd_p = strcmp (cpuid_vendor, "AuthenticAMD") == 0;
+ unsigned cpu_family, cpu_model;
+
+ __asm__ __volatile__ ("movl $1, %%eax;"
+ "cpuid;"
+ : "=a" (cpuid_eax),
+ "=b" (cpuid_ebx),
+ "=d" (cpuid_edx)
+ :
+ : "%ecx");
+ brand_idx = cpuid_ebx & 0xff;
+ cpu_family = (cpuid_eax >> 8) & 0xf;
+ cpu_model = (cpuid_eax >> 4) & 0xf;
+ cpu_brand[0] = '\0';
+ if (intel_p)
+ {
+ if (brand_idx > 0
+ && brand_idx < sizeof(brand_name)/sizeof(brand_name[0])
+ && *brand_name[brand_idx])
+ strcpy (cpu_brand, brand_name[brand_idx]);
+ else if (cpu_family == 5)
+ {
+ if (((cpuid_eax >> 12) & 3) == 0 && cpu_model == 4)
+ strcpy (cpu_brand, " MMX");
+ else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 1)
+ strcpy (cpu_brand, " OverDrive");
+ else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 2)
+ strcpy (cpu_brand, " Dual");
+ }
+ else if (cpu_family == 6 && cpu_model < 8)
+ {
+ switch (cpu_model)
+ {
+ case 1:
+ strcpy (cpu_brand, " Pro");
+ break;
+ case 3:
+ strcpy (cpu_brand, " II");
+ break;
+ case 5:
+ strcpy (cpu_brand, " II Xeon");
+ break;
+ case 6:
+ strcpy (cpu_brand, " Celeron");
+ break;
+ case 7:
+ strcpy (cpu_brand, " III");
+ break;
+ }
+ }
+ }
+ else if (amd_p)
+ {
+ switch (cpu_family)
+ {
+ case 4:
+ strcpy (cpu_brand, "486/5x86");
+ break;
+ case 5:
+ switch (cpu_model)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ strcpy (cpu_brand, "-K5");
+ break;
+ case 6:
+ case 7:
+ strcpy (cpu_brand, "-K6");
+ break;
+ case 8:
+ strcpy (cpu_brand, "-K6-2");
+ break;
+ case 9:
+ strcpy (cpu_brand, "-K6-III");
+ break;
+ }
+ break;
+ case 6:
+ switch (cpu_model)
+ {
+ case 1:
+ case 2:
+ case 4:
+ strcpy (cpu_brand, " Athlon");
+ break;
+ case 3:
+ strcpy (cpu_brand, " Duron");
+ break;
+ }
+ break;
+ }
+ }
+ sprintf (cpu_string, "%s%s Model %d Stepping %d",
+ intel_p ? "Pentium" : (amd_p ? "AMD" : "ix86"),
+ cpu_brand, cpu_model, cpuid_eax & 0xf);
+ printfi_filtered (31, "%s\n", cpu_string);
+ if (((cpuid_edx & (6 | (0x0d << 23))) != 0)
+ || ((cpuid_edx & 1) == 0)
+ || (amd_p && (cpuid_edx & (3 << 30)) != 0))
+ {
+ puts_filtered ("CPU Features...................");
+ /* We only list features which might be useful in the DPMI
+ environment. */
+ if ((cpuid_edx & 1) == 0)
+ puts_filtered ("No FPU "); /* it's unusual to not have an FPU */
+ if ((cpuid_edx & (1 << 1)) != 0)
+ puts_filtered ("VME ");
+ if ((cpuid_edx & (1 << 2)) != 0)
+ puts_filtered ("DE ");
+ if ((cpuid_edx & (1 << 4)) != 0)
+ puts_filtered ("TSC ");
+ if ((cpuid_edx & (1 << 23)) != 0)
+ puts_filtered ("MMX ");
+ if ((cpuid_edx & (1 << 25)) != 0)
+ puts_filtered ("SSE ");
+ if ((cpuid_edx & (1 << 26)) != 0)
+ puts_filtered ("SSE2 ");
+ if (amd_p)
+ {
+ if ((cpuid_edx & (1 << 31)) != 0)
+ puts_filtered ("3DNow! ");
+ if ((cpuid_edx & (1 << 30)) != 0)
+ puts_filtered ("3DNow!Ext");
+ }
+ puts_filtered ("\n");
+ }
+ }
+ puts_filtered ("\n");
+ printf_filtered ("DOS Version....................%s %s.%s",
+ _os_flavor, u.release, u.version);
+ if (true_dos_version != advertized_dos_version)
+ printf_filtered (" (disguised as v%d.%d)", _osmajor, _osminor);
+ puts_filtered ("\n");
+ if (!windows_major)
+ go32_get_windows_version ();
+ if (windows_major != 0xff)
+ {
+ const char *windows_flavor;
+
+ printf_filtered ("Windows Version................%d.%02d (Windows ",
+ windows_major, windows_minor);
+ switch (windows_major)
+ {
+ case 3:
+ windows_flavor = "3.X";
+ break;
+ case 4:
+ switch (windows_minor)
+ {
+ case 0:
+ windows_flavor = "95, 95A, or 95B";
+ break;
+ case 3:
+ windows_flavor = "95B OSR2.1 or 95C OSR2.5";
+ break;
+ case 10:
+ windows_flavor = "98 or 98 SE";
+ break;
+ case 90:
+ windows_flavor = "ME";
+ break;
+ default:
+ windows_flavor = "9X";
+ break;
+ }
+ break;
+ default:
+ windows_flavor = "??";
+ break;
+ }
+ printf_filtered ("%s)\n", windows_flavor);
+ }
+ else if (true_dos_version == 0x532 && advertized_dos_version == 0x500)
+ printf_filtered ("Windows Version................Windows NT or Windows 2000\n");
+ puts_filtered ("\n");
+ if (dpmi_vendor_available == 0)
+ {
+ /* The DPMI spec says the vendor string should be ASCIIZ, but
+ I don't trust the vendors to follow that... */
+ if (!memchr (&dpmi_vendor_info[2], 0, 126))
+ dpmi_vendor_info[128] = '\0';
+ printf_filtered ("DPMI Host......................%s v%d.%d (capabilities: %#x)\n",
+ &dpmi_vendor_info[2],
+ (unsigned)dpmi_vendor_info[0],
+ (unsigned)dpmi_vendor_info[1],
+ ((unsigned)dpmi_flags & 0x7f));
+ }
+ __dpmi_get_version (&dpmi_version_data);
+ printf_filtered ("DPMI Version...................%d.%02d\n",
+ dpmi_version_data.major, dpmi_version_data.minor);
+ printf_filtered ("DPMI Info......................%s-bit DPMI, with%s Virtual Memory support\n",
+ (dpmi_version_data.flags & 1) ? "32" : "16",
+ (dpmi_version_data.flags & 4) ? "" : "out");
+ printfi_filtered (31, "Interrupts reflected to %s mode\n",
+ (dpmi_version_data.flags & 2) ? "V86" : "Real");
+ printfi_filtered (31, "Processor type: i%d86\n",
+ dpmi_version_data.cpu);
+ printfi_filtered (31, "PIC base interrupt: Master: %#x Slave: %#x\n",
+ dpmi_version_data.master_pic, dpmi_version_data.slave_pic);
+
+ /* a_tss is only initialized when the debuggee is first run. */
+ if (prog_has_started)
+ {
+ __asm__ __volatile__ ("pushfl ; popl %0" : "=g" (eflags));
+ printf_filtered ("Protection.....................Ring %d (in %s), with%s I/O protection\n",
+ a_tss.tss_cs & 3, (a_tss.tss_cs & 4) ? "LDT" : "GDT",
+ (a_tss.tss_cs & 3) > ((eflags >> 12) & 3) ? "" : "out");
+ }
+ puts_filtered ("\n");
+ __dpmi_get_free_memory_information (&mem_info);
+ print_mem (mem_info.total_number_of_physical_pages,
+ "DPMI Total Physical Memory.....", 1);
+ print_mem (mem_info.total_number_of_free_pages,
+ "DPMI Free Physical Memory......", 1);
+ print_mem (mem_info.size_of_paging_file_partition_in_pages,
+ "DPMI Swap Space................", 1);
+ print_mem (mem_info.linear_address_space_size_in_pages,
+ "DPMI Total Linear Address Size.", 1);
+ print_mem (mem_info.free_linear_address_space_in_pages,
+ "DPMI Free Linear Address Size..", 1);
+ print_mem (mem_info.largest_available_free_block_in_bytes,
+ "DPMI Largest Free Memory Block.", 0);
+
+ regs.h.ah = 0x48;
+ regs.x.bx = 0xffff;
+ __dpmi_int (0x21, &regs);
+ print_mem (regs.x.bx << 4, "Free DOS Memory................", 0);
+ regs.x.ax = 0x5800;
+ __dpmi_int (0x21, &regs);
+ if ((regs.x.flags & 1) == 0)
+ {
+ static const char *dos_hilo[] = {
+ "Low", "", "", "", "High", "", "", "", "High, then Low"
+ };
+ static const char *dos_fit[] = {
+ "First", "Best", "Last"
+ };
+ int hilo_idx = (regs.x.ax >> 4) & 0x0f;
+ int fit_idx = regs.x.ax & 0x0f;
+
+ if (hilo_idx > 8)
+ hilo_idx = 0;
+ if (fit_idx > 2)
+ fit_idx = 0;
+ printf_filtered ("DOS Memory Allocation..........%s memory, %s fit\n",
+ dos_hilo[hilo_idx], dos_fit[fit_idx]);
+ regs.x.ax = 0x5802;
+ __dpmi_int (0x21, &regs);
+ if ((regs.x.flags & 1) != 0)
+ regs.h.al = 0;
+ printfi_filtered (31, "UMBs %sin DOS memory chain\n",
+ regs.h.al == 0 ? "not " : "");
+ }
+}
+
+struct seg_descr {
+ unsigned short limit0 __attribute__((packed));
+ unsigned short base0 __attribute__((packed));
+ unsigned char base1 __attribute__((packed));
+ unsigned stype:5 __attribute__((packed));
+ unsigned dpl:2 __attribute__((packed));
+ unsigned present:1 __attribute__((packed));
+ unsigned limit1:4 __attribute__((packed));
+ unsigned available:1 __attribute__((packed));
+ unsigned dummy:1 __attribute__((packed));
+ unsigned bit32:1 __attribute__((packed));
+ unsigned page_granular:1 __attribute__((packed));
+ unsigned char base2 __attribute__((packed));
+};
+
+struct gate_descr {
+ unsigned short offset0 __attribute__((packed));
+ unsigned short selector __attribute__((packed));
+ unsigned param_count:5 __attribute__((packed));
+ unsigned dummy:3 __attribute__((packed));
+ unsigned stype:5 __attribute__((packed));
+ unsigned dpl:2 __attribute__((packed));
+ unsigned present:1 __attribute__((packed));
+ unsigned short offset1 __attribute__((packed));
+};
+
+/* Read LEN bytes starting at logical address ADDR, and put the result
+ into DEST. Return 1 if success, zero if not. */
+static int
+read_memory_region (unsigned long addr, void *dest, size_t len)
+{
+ unsigned long dos_ds_limit = __dpmi_get_segment_limit (_dos_ds);
+ int retval = 1;
+
+ /* For the low memory, we can simply use _dos_ds. */
+ if (addr <= dos_ds_limit - len)
+ dosmemget (addr, len, dest);
+ else
+ {
+ /* For memory above 1MB we need to set up a special segment to
+ be able to access that memory. */
+ int sel = __dpmi_allocate_ldt_descriptors (1);
+
+ if (sel <= 0)
+ retval = 0;
+ else
+ {
+ int access_rights = __dpmi_get_descriptor_access_rights (sel);
+ size_t segment_limit = len - 1;
+
+ /* Make sure the crucial bits in the descriptor access
+ rights are set correctly. Some DPMI providers might barf
+ if we set the segment limit to something that is not an
+ integral multiple of 4KB pages if the granularity bit is
+ not set to byte-granular, even though the DPMI spec says
+ it's the host's responsibility to set that bit correctly. */
+ if (len > 1024 * 1024)
+ {
+ access_rights |= 0x8000;
+ /* Page-granular segments should have the low 12 bits of
+ the limit set. */
+ segment_limit |= 0xfff;
+ }
+ else
+ access_rights &= ~0x8000;
+
+ if (__dpmi_set_segment_base_address (sel, addr) != -1
+ && __dpmi_set_descriptor_access_rights (sel, access_rights) != -1
+ && __dpmi_set_segment_limit (sel, segment_limit) != -1
+ /* W2K silently fails to set the segment limit, leaving
+ it at zero; this test avoids the resulting crash. */
+ && __dpmi_get_segment_limit (sel) >= segment_limit)
+ movedata (sel, 0, _my_ds (), (unsigned)dest, len);
+ else
+ retval = 0;
+
+ __dpmi_free_ldt_descriptor (sel);
+ }
+ }
+ return retval;
+}
+
+/* Get a segment descriptor stored at index IDX in the descriptor
+ table whose base address is TABLE_BASE. Return the descriptor
+ type, or -1 if failure. */
+static int
+get_descriptor (unsigned long table_base, int idx, void *descr)
+{
+ unsigned long addr = table_base + idx * 8; /* 8 bytes per entry */
+
+ if (read_memory_region (addr, descr, 8))
+ return (int)((struct seg_descr *)descr)->stype;
+ return -1;
+}
+
+struct dtr_reg {
+ unsigned short limit __attribute__((packed));
+ unsigned long base __attribute__((packed));
+};
+
+/* Display a segment descriptor stored at index IDX in a descriptor
+ table whose type is TYPE and whose base address is BASE_ADDR. If
+ FORCE is non-zero, display even invalid descriptors. */
+static void
+display_descriptor (unsigned type, unsigned long base_addr, int idx, int force)
+{
+ struct seg_descr descr;
+ struct gate_descr gate;
+
+ /* Get the descriptor from the table. */
+ if (idx == 0 && type == 0)
+ puts_filtered ("0x000: null descriptor\n");
+ else if (get_descriptor (base_addr, idx, &descr) != -1)
+ {
+ /* For each type of descriptor table, this has a bit set if the
+ corresponding type of selectors is valid in that table. */
+ static unsigned allowed_descriptors[] = {
+ 0xffffdafeL, /* GDT */
+ 0x0000c0e0L, /* IDT */
+ 0xffffdafaL /* LDT */
+ };
+
+ /* If the program hasn't started yet, assume the debuggee will
+ have the same CPL as the debugger. */
+ int cpl = prog_has_started ? (a_tss.tss_cs & 3) : _my_cs () & 3;
+ unsigned long limit = (descr.limit1 << 16) | descr.limit0;
+
+ if (descr.present
+ && (allowed_descriptors[type] & (1 << descr.stype)) != 0)
+ {
+ printf_filtered ("0x%03x: ",
+ type == 1
+ ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
+ if (descr.page_granular)
+ limit = (limit << 12) | 0xfff; /* big segment: low 12 bit set */
+ if (descr.stype == 1 || descr.stype == 2 || descr.stype == 3
+ || descr.stype == 9 || descr.stype == 11
+ || (descr.stype >= 16 && descr.stype < 32))
+ printf_filtered ("base=0x%02x%02x%04x limit=0x%08lx",
+ descr.base2, descr.base1, descr.base0, limit);
+
+ switch (descr.stype)
+ {
+ case 1:
+ case 3:
+ printf_filtered (" 16-bit TSS (task %sactive)",
+ descr.stype == 3 ? "" : "in");
+ break;
+ case 2:
+ puts_filtered (" LDT");
+ break;
+ case 4:
+ memcpy (&gate, &descr, sizeof gate);
+ printf_filtered ("selector=0x%04x offs=0x%04x%04x",
+ gate.selector, gate.offset1, gate.offset0);
+ printf_filtered (" 16-bit Call Gate (params=%d)",
+ gate.param_count);
+ break;
+ case 5:
+ printf_filtered ("TSS selector=0x%04x", descr.base0);
+ printfi_filtered (16, "Task Gate");
+ break;
+ case 6:
+ case 7:
+ memcpy (&gate, &descr, sizeof gate);
+ printf_filtered ("selector=0x%04x offs=0x%04x%04x",
+ gate.selector, gate.offset1, gate.offset0);
+ printf_filtered (" 16-bit %s Gate",
+ descr.stype == 6 ? "Interrupt" : "Trap");
+ break;
+ case 9:
+ case 11:
+ printf_filtered (" 32-bit TSS (task %sactive)",
+ descr.stype == 3 ? "" : "in");
+ break;
+ case 12:
+ memcpy (&gate, &descr, sizeof gate);
+ printf_filtered ("selector=0x%04x offs=0x%04x%04x",
+ gate.selector, gate.offset1, gate.offset0);
+ printf_filtered (" 32-bit Call Gate (params=%d)",
+ gate.param_count);
+ break;
+ case 14:
+ case 15:
+ memcpy (&gate, &descr, sizeof gate);
+ printf_filtered ("selector=0x%04x offs=0x%04x%04x",
+ gate.selector, gate.offset1, gate.offset0);
+ printf_filtered (" 32-bit %s Gate",
+ descr.stype == 14 ? "Interrupt" : "Trap");
+ break;
+ case 16: /* data segments */
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ case 22:
+ case 23:
+ printf_filtered (" %s-bit Data (%s Exp-%s%s)",
+ descr.bit32 ? "32" : "16",
+ descr.stype & 2 ? "Read/Write," : "Read-Only, ",
+ descr.stype & 4 ? "down" : "up",
+ descr.stype & 1 ? "" : ", N.Acc");
+ break;
+ case 24: /* code segments */
+ case 25:
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ case 30:
+ case 31:
+ printf_filtered (" %s-bit Code (%s, %sConf%s)",
+ descr.bit32 ? "32" : "16",
+ descr.stype & 2 ? "Exec/Read" : "Exec-Only",
+ descr.stype & 4 ? "" : "N.",
+ descr.stype & 1 ? "" : ", N.Acc");
+ break;
+ default:
+ printf_filtered ("Unknown type 0x%02x", descr.stype);
+ break;
+ }
+ puts_filtered ("\n");
+ }
+ else if (force)
+ {
+ printf_filtered ("0x%03x: ",
+ type == 1
+ ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
+ if (!descr.present)
+ puts_filtered ("Segment not present\n");
+ else
+ printf_filtered ("Segment type 0x%02x is invalid in this table\n",
+ descr.stype);
+ }
+ }
+ else if (force)
+ printf_filtered ("0x%03x: Cannot read this descriptor\n", idx);
+}
+
+static void
+go32_sldt (char *arg, int from_tty)
+{
+ struct dtr_reg gdtr;
+ unsigned short ldtr = 0;
+ int ldt_idx;
+ struct seg_descr ldt_descr;
+ long ldt_entry = -1L;
+ int cpl = (prog_has_started ? a_tss.tss_cs : _my_cs ()) & 3;
+
+ if (arg && *arg)
+ {
+ while (*arg && isspace(*arg))
+ arg++;
+
+ if (*arg)
+ {
+ ldt_entry = parse_and_eval_long (arg);
+ if (ldt_entry < 0
+ || (ldt_entry & 4) == 0
+ || (ldt_entry & 3) != (cpl & 3))
+ error ("Invalid LDT entry 0x%03x.", ldt_entry);
+ }
+ }
+
+ __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
+ __asm__ __volatile__ ("sldt %0" : "=m" (ldtr) : /* no inputs */ );
+ ldt_idx = ldtr / 8;
+ if (ldt_idx == 0)
+ puts_filtered ("There is no LDT.\n");
+ /* LDT's entry in the GDT must have the type LDT, which is 2. */
+ else if (get_descriptor (gdtr.base, ldt_idx, &ldt_descr) != 2)
+ printf_filtered ("LDT is present (at %#x), but unreadable by GDB.\n",
+ ldt_descr.base0
+ | (ldt_descr.base1 << 16)
+ | (ldt_descr.base2 << 24));
+ else
+ {
+ unsigned base =
+ ldt_descr.base0
+ | (ldt_descr.base1 << 16)
+ | (ldt_descr.base2 << 24);
+ unsigned limit = ldt_descr.limit0 | (ldt_descr.limit1 << 16);
+ int max_entry;
+
+ if (ldt_descr.page_granular)
+ /* Page-granular segments must have the low 12 bits of their
+ limit set. */
+ limit = (limit << 12) | 0xfff;
+ /* LDT cannot have more than 8K 8-byte entries, i.e. more than
+ 64KB. */
+ if (limit > 0xffff)
+ limit = 0xffff;
+
+ max_entry = (limit + 1) / 8;
+
+ if (ldt_entry >= 0)
+ {
+ if (ldt_entry > limit)
+ error ("Invalid LDT entry %#x: outside valid limits [0..%#x]",
+ ldt_entry, limit);
+
+ display_descriptor (ldt_descr.stype, base, ldt_entry / 8, 1);
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; i < max_entry; i++)
+ display_descriptor (ldt_descr.stype, base, i, 0);
+ }
+ }
+}
+
+static void
+go32_sgdt (char *arg, int from_tty)
+{
+ struct dtr_reg gdtr;
+ long gdt_entry = -1L;
+ int max_entry;
+
+ if (arg && *arg)
+ {
+ while (*arg && isspace(*arg))
+ arg++;
+
+ if (*arg)
+ {
+ gdt_entry = parse_and_eval_long (arg);
+ if (gdt_entry < 0 || (gdt_entry & 7) != 0)
+ error ("Invalid GDT entry 0x%03x: not an integral multiple of 8.",
+ gdt_entry);
+ }
+ }
+
+ __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
+ max_entry = (gdtr.limit + 1) / 8;
+
+ if (gdt_entry >= 0)
+ {
+ if (gdt_entry > gdtr.limit)
+ error ("Invalid GDT entry %#x: outside valid limits [0..%#x]",
+ gdt_entry, gdtr.limit);
+
+ display_descriptor (0, gdtr.base, gdt_entry / 8, 1);
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; i < max_entry; i++)
+ display_descriptor (0, gdtr.base, i, 0);
+ }
+}
+
+static void
+go32_sidt (char *arg, int from_tty)
+{
+ struct dtr_reg idtr;
+ long idt_entry = -1L;
+ int max_entry;
+
+ if (arg && *arg)
+ {
+ while (*arg && isspace(*arg))
+ arg++;
+
+ if (*arg)
+ {
+ idt_entry = parse_and_eval_long (arg);
+ if (idt_entry < 0)
+ error ("Invalid (negative) IDT entry %d.", idt_entry);
+ }
+ }
+
+ __asm__ __volatile__ ("sidt %0" : "=m" (idtr) : /* no inputs */ );
+ max_entry = (idtr.limit + 1) / 8;
+ if (max_entry > 0x100) /* no more than 256 entries */
+ max_entry = 0x100;
+
+ if (idt_entry >= 0)
+ {
+ if (idt_entry > idtr.limit)
+ error ("Invalid IDT entry %#x: outside valid limits [0..%#x]",
+ idt_entry, idtr.limit);
+
+ display_descriptor (1, idtr.base, idt_entry, 1);
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; i < max_entry; i++)
+ display_descriptor (1, idtr.base, i, 0);
+ }
+}
+
+/* Cached linear address of the base of the page directory. For
+ now, available only under CWSDPMI. Code based on ideas and
+ suggestions from Charles Sandmann <sandmann@clio.rice.edu>. */
+static unsigned long pdbr;
+
+static unsigned long
+get_cr3 (void)
+{
+ unsigned offset;
+ unsigned taskreg;
+ unsigned long taskbase, cr3;
+ struct dtr_reg gdtr;
+
+ if (pdbr > 0 && pdbr <= 0xfffff)
+ return pdbr;
+
+ /* Get the linear address of GDT and the Task Register. */
+ __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
+ __asm__ __volatile__ ("str %0" : "=m" (taskreg) : /* no inputs */ );
+
+ /* Task Register is a segment selector for the TSS of the current
+ task. Therefore, it can be used as an index into the GDT to get
+ at the segment descriptor for the TSS. To get the index, reset
+ the low 3 bits of the selector (which give the CPL). Add 2 to the
+ offset to point to the 3 low bytes of the base address. */
+ offset = gdtr.base + (taskreg & 0xfff8) + 2;
+
+
+ /* CWSDPMI's task base is always under the 1MB mark. */
+ if (offset > 0xfffff)
+ return 0;
+
+ _farsetsel (_dos_ds);
+ taskbase = _farnspeekl (offset) & 0xffffffU;
+ taskbase += _farnspeekl (offset + 2) & 0xff000000U;
+ if (taskbase > 0xfffff)
+ return 0;
+
+ /* CR3 (a.k.a. PDBR, the Page Directory Base Register) is stored at
+ offset 1Ch in the TSS. */
+ cr3 = _farnspeekl (taskbase + 0x1c) & ~0xfff;
+ if (cr3 > 0xfffff)
+ {
+#if 0 /* not fullly supported yet */
+ /* The Page Directory is in UMBs. In that case, CWSDPMI puts
+ the first Page Table right below the Page Directory. Thus,
+ the first Page Table's entry for its own address and the Page
+ Directory entry for that Page Table will hold the same
+ physical address. The loop below searches the entire UMB
+ range of addresses for such an occurence. */
+ unsigned long addr, pte_idx;
+
+ for (addr = 0xb0000, pte_idx = 0xb0;
+ pte_idx < 0xff;
+ addr += 0x1000, pte_idx++)
+ {
+ if (((_farnspeekl (addr + 4 * pte_idx) & 0xfffff027) ==
+ (_farnspeekl (addr + 0x1000) & 0xfffff027))
+ && ((_farnspeekl (addr + 4 * pte_idx + 4) & 0xfffff000) == cr3))
+ {
+ cr3 = addr + 0x1000;
+ break;
+ }
+ }
+#endif
+
+ if (cr3 > 0xfffff)
+ cr3 = 0;
+ }
+
+ return cr3;
+}
+
+/* Return the N'th Page Directory entry. */
+static unsigned long
+get_pde (int n)
+{
+ unsigned long pde = 0;
+
+ if (pdbr && n >= 0 && n < 1024)
+ {
+ pde = _farpeekl (_dos_ds, pdbr + 4*n);
+ }
+ return pde;
+}
+
+/* Return the N'th entry of the Page Table whose Page Directory entry
+ is PDE. */
+static unsigned long
+get_pte (unsigned long pde, int n)
+{
+ unsigned long pte = 0;
+
+ /* pde & 0x80 tests the 4MB page bit. We don't support 4MB
+ page tables, for now. */
+ if ((pde & 1) && !(pde & 0x80) && n >= 0 && n < 1024)
+ {
+ pde &= ~0xfff; /* clear non-address bits */
+ pte = _farpeekl (_dos_ds, pde + 4*n);
+ }
+ return pte;
+}
+
+/* Display a Page Directory or Page Table entry. IS_DIR, if non-zero,
+ says this is a Page Directory entry. If FORCE is non-zero, display
+ the entry even if its Present flag is off. OFF is the offset of the
+ address from the page's base address. */
+static void
+display_ptable_entry (unsigned long entry, int is_dir, int force, unsigned off)
+{
+ if ((entry & 1) != 0)
+ {
+ printf_filtered ("Base=0x%05lx000", entry >> 12);
+ if ((entry & 0x100) && !is_dir)
+ puts_filtered (" Global");
+ if ((entry & 0x40) && !is_dir)
+ puts_filtered (" Dirty");
+ printf_filtered (" %sAcc.", (entry & 0x20) ? "" : "Not-");
+ printf_filtered (" %sCached", (entry & 0x10) ? "" : "Not-");
+ printf_filtered (" Write-%s", (entry & 8) ? "Thru" : "Back");
+ printf_filtered (" %s", (entry & 4) ? "Usr" : "Sup");
+ printf_filtered (" Read-%s", (entry & 2) ? "Write" : "Only");
+ if (off)
+ printf_filtered (" +0x%x", off);
+ puts_filtered ("\n");
+ }
+ else if (force)
+ printf_filtered ("Page%s not present or not supported; value=0x%lx.\n",
+ is_dir ? " Table" : "", entry >> 1);
+}
+
+static void
+go32_pde (char *arg, int from_tty)
+{
+ long pde_idx = -1, i;
+
+ if (arg && *arg)
+ {
+ while (*arg && isspace(*arg))
+ arg++;
+
+ if (*arg)
+ {
+ pde_idx = parse_and_eval_long (arg);
+ if (pde_idx < 0 || pde_idx >= 1024)
+ error ("Entry %ld is outside valid limits [0..1023].", pde_idx);
+ }
+ }
+
+ pdbr = get_cr3 ();
+ if (!pdbr)
+ puts_filtered ("Access to Page Directories is not supported on this system.\n");
+ else if (pde_idx >= 0)
+ display_ptable_entry (get_pde (pde_idx), 1, 1, 0);
+ else
+ for (i = 0; i < 1024; i++)
+ display_ptable_entry (get_pde (i), 1, 0, 0);
+}
+
+/* A helper function to display entries in a Page Table pointed to by
+ the N'th entry in the Page Directory. If FORCE is non-zero, say
+ something even if the Page Table is not accessible. */
+static void
+display_page_table (long n, int force)
+{
+ unsigned long pde = get_pde (n);
+
+ if ((pde & 1) != 0)
+ {
+ int i;
+
+ printf_filtered ("Page Table pointed to by Page Directory entry 0x%lx:\n", n);
+ for (i = 0; i < 1024; i++)
+ display_ptable_entry (get_pte (pde, i), 0, 0, 0);
+ puts_filtered ("\n");
+ }
+ else if (force)
+ printf_filtered ("Page Table not present; value=0x%lx.\n", pde >> 1);
+}
+
+static void
+go32_pte (char *arg, int from_tty)
+{
+ long pde_idx = -1, i;
+
+ if (arg && *arg)
+ {
+ while (*arg && isspace(*arg))
+ arg++;
+
+ if (*arg)
+ {
+ pde_idx = parse_and_eval_long (arg);
+ if (pde_idx < 0 || pde_idx >= 1024)
+ error ("Entry %d is outside valid limits [0..1023].", pde_idx);
+ }
+ }
+
+ pdbr = get_cr3 ();
+ if (!pdbr)
+ puts_filtered ("Access to Page Tables is not supported on this system.\n");
+ else if (pde_idx >= 0)
+ display_page_table (pde_idx, 1);
+ else
+ for (i = 0; i < 1024; i++)
+ display_page_table (i, 0);
+}
+
+static void
+go32_pte_for_address (char *arg, int from_tty)
+{
+ CORE_ADDR addr = 0, i;
+
+ if (arg && *arg)
+ {
+ while (*arg && isspace(*arg))
+ arg++;
+
+ if (*arg)
+ addr = parse_and_eval_address (arg);
+ }
+ if (!addr)
+ error_no_arg ("linear address");
+
+ pdbr = get_cr3 ();
+ if (!pdbr)
+ puts_filtered ("Access to Page Tables is not supported on this system.\n");
+ else
+ {
+ int pde_idx = (addr >> 22) & 0x3ff;
+ int pte_idx = (addr >> 12) & 0x3ff;
+ unsigned offs = addr & 0xfff;
+
+ printf_filtered ("Page Table entry for address 0x%llx:\n",
+ (unsigned long long)addr);
+ display_ptable_entry (get_pte (get_pde (pde_idx), pte_idx), 0, 1, offs);
+ }
+}
+
+static struct cmd_list_element *info_dos_cmdlist = NULL;
+
+static void
+go32_info_dos_command (char *args, int from_tty)
+{
+ help_list (info_dos_cmdlist, "info dos ", class_info, gdb_stdout);
+}
+
+void
+_initialize_go32_nat (void)
+{
+ init_go32_ops ();
+ add_target (&go32_ops);
+
+ add_prefix_cmd ("dos", class_info, go32_info_dos_command,
+ "Print information specific to DJGPP (aka MS-DOS) debugging.",
+ &info_dos_cmdlist, "info dos ", 0, &infolist);
+
+ add_cmd ("sysinfo", class_info, go32_sysinfo,
+ "Display information about the target system, including CPU, OS, DPMI, etc.",
+ &info_dos_cmdlist);
+ add_cmd ("ldt", class_info, go32_sldt,
+ "Display entries in the LDT (Local Descriptor Table).\n"
+ "Entry number (an expression) as an argument means display only that entry.",
+ &info_dos_cmdlist);
+ add_cmd ("gdt", class_info, go32_sgdt,
+ "Display entries in the GDT (Global Descriptor Table).\n"
+ "Entry number (an expression) as an argument means display only that entry.",
+ &info_dos_cmdlist);
+ add_cmd ("idt", class_info, go32_sidt,
+ "Display entries in the IDT (Interrupt Descriptor Table).\n"
+ "Entry number (an expression) as an argument means display only that entry.",
+ &info_dos_cmdlist);
+ add_cmd ("pde", class_info, go32_pde,
+ "Display entries in the Page Directory.\n"
+ "Entry number (an expression) as an argument means display only that entry.",
+ &info_dos_cmdlist);
+ add_cmd ("pte", class_info, go32_pte,
+ "Display entries in Page Tables.\n"
+ "Entry number (an expression) as an argument means display only entries\n"
+ "from the Page Table pointed to by the specified Page Directory entry.",
+ &info_dos_cmdlist);
+ add_cmd ("address-pte", class_info, go32_pte_for_address,
+ "Display a Page Table entry for a linear address.\n"
+ "The address argument must be a linear address, after adding to\n"
+ "it the base address of the appropriate segment.\n"
+ "The base address of variables and functions in the debuggee's data\n"
+ "or code segment is stored in the variable __djgpp_base_address,\n"
+ "so use `__djgpp_base_address + (char *)&var' as the argument.\n"
+ "For other segments, look up their base address in the output of\n"
+ "the `info dos ldt' command.",
+ &info_dos_cmdlist);
+}
+
+pid_t
+tcgetpgrp (int fd)
+{
+ if (isatty (fd))
+ return SOME_PID;
+ errno = ENOTTY;
+ return -1;
+}
+
+int
+tcsetpgrp (int fd, pid_t pgid)
+{
+ if (isatty (fd) && pgid == SOME_PID)
+ return 0;
+ errno = pgid == SOME_PID ? ENOTTY : ENOSYS;
+ return -1;
+}
diff --git a/gdb/gregset.h b/gdb/gregset.h
new file mode 100644
index 00000000000..0ec80a118d0
--- /dev/null
+++ b/gdb/gregset.h
@@ -0,0 +1,69 @@
+/* Interface for functions using gregset and fpregset types.
+ Copyright 2000, 2002 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. */
+
+#ifndef GREGSET_H
+#define GREGSET_H
+
+#ifndef GDB_GREGSET_T
+#define GDB_GREGSET_T gregset_t
+#endif
+
+#ifndef GDB_FPREGSET_T
+#define GDB_FPREGSET_T fpregset_t
+#endif
+
+typedef GDB_GREGSET_T gdb_gregset_t;
+typedef GDB_FPREGSET_T gdb_fpregset_t;
+
+/* A gregset is a data structure supplied by the native OS containing
+ the general register values of the debugged process. Usually this
+ includes integer registers and control registers. An fpregset is a
+ data structure containing the floating point registers. These data
+ structures were originally a part of the /proc interface, but have
+ been borrowed or copied by other GDB targets, eg. GNU/Linux. */
+
+/* Copy register values from the native target gregset/fpregset
+ into GDB's internal register cache. */
+
+extern void supply_gregset (gdb_gregset_t *gregs);
+extern void supply_fpregset (gdb_fpregset_t *fpregs);
+
+/* Copy register values from GDB's register cache into
+ the native target gregset/fpregset. If regno is -1,
+ copy all the registers. */
+
+extern void fill_gregset (gdb_gregset_t *gregs, int regno);
+extern void fill_fpregset (gdb_fpregset_t *fpregs, int regno);
+
+#ifdef FILL_FPXREGSET
+/* GNU/Linux i386: Copy register values between GDB's internal register cache
+ and the i386 extended floating point registers. */
+
+#ifndef GDB_FPXREGSET_T
+#define GDB_FPXREGSET_T elf_fpxregset_t
+#endif
+
+typedef GDB_FPXREGSET_T gdb_fpxregset_t;
+
+extern void supply_fpxregset (gdb_fpxregset_t *fpxregs);
+extern void fill_fpxregset (gdb_fpxregset_t *fpxregs, int regno);
+#endif
+
+#endif
diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c
new file mode 100644
index 00000000000..b12897fda9d
--- /dev/null
+++ b/gdb/h8300-tdep.c
@@ -0,0 +1,890 @@
+/* Target-machine dependent code for Hitachi H8/300, for GDB.
+
+ Copyright 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
+ 1999, 2000, 2001, 2002 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. */
+
+/*
+ Contributed by Steve Chamberlain
+ sac@cygnus.com
+ */
+
+#include "defs.h"
+#include "frame.h"
+#include "obstack.h"
+#include "symtab.h"
+#include "dis-asm.h"
+#include "gdbcmd.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "gdb_string.h"
+#include "value.h"
+#include "regcache.h"
+
+extern int h8300hmode, h8300smode;
+
+#undef NUM_REGS
+#define NUM_REGS (h8300smode?12:11)
+
+#define UNSIGNED_SHORT(X) ((X) & 0xffff)
+
+#define IS_PUSH(x) ((x & 0xfff0)==0x6df0)
+#define IS_PUSH_FP(x) (x == 0x6df6)
+#define IS_MOVE_FP(x) (x == 0x0d76 || x == 0x0ff6)
+#define IS_MOV_SP_FP(x) (x == 0x0d76 || x == 0x0ff6)
+#define IS_SUB2_SP(x) (x==0x1b87)
+#define IS_SUB4_SP(x) (x==0x1b97)
+#define IS_SUBL_SP(x) (x==0x7a37)
+#define IS_MOVK_R5(x) (x==0x7905)
+#define IS_SUB_R5SP(x) (x==0x1957)
+
+/* The register names change depending on whether the h8300h processor
+ type is selected. */
+
+static char *original_register_names[] = REGISTER_NAMES;
+
+static char *h8300h_register_names[] = {
+ "er0", "er1", "er2", "er3", "er4", "er5", "er6",
+ "sp", "ccr", "pc", "cycles", "exr", "tick", "inst"
+};
+
+char **h8300_register_names = original_register_names;
+
+/* Local function declarations. */
+
+static CORE_ADDR examine_prologue ();
+static void set_machine_hook (char *filename);
+
+CORE_ADDR
+h8300_skip_prologue (CORE_ADDR start_pc)
+{
+ short int w;
+ int adjust = 0;
+
+ /* Skip past all push and stm insns. */
+ while (1)
+ {
+ w = read_memory_unsigned_integer (start_pc, 2);
+ /* First look for push insns. */
+ if (w == 0x0100 || w == 0x0110 || w == 0x0120 || w == 0x0130)
+ {
+ w = read_memory_unsigned_integer (start_pc + 2, 2);
+ adjust = 2;
+ }
+
+ if (IS_PUSH (w))
+ {
+ start_pc += 2 + adjust;
+ w = read_memory_unsigned_integer (start_pc, 2);
+ continue;
+ }
+ adjust = 0;
+ break;
+ }
+
+ /* Skip past a move to FP, either word or long sized */
+ w = read_memory_unsigned_integer (start_pc, 2);
+ if (w == 0x0100)
+ {
+ w = read_memory_unsigned_integer (start_pc + 2, 2);
+ adjust += 2;
+ }
+
+ if (IS_MOVE_FP (w))
+ {
+ start_pc += 2 + adjust;
+ w = read_memory_unsigned_integer (start_pc, 2);
+ }
+
+ /* Check for loading either a word constant into r5;
+ long versions are handled by the SUBL_SP below. */
+ if (IS_MOVK_R5 (w))
+ {
+ start_pc += 2;
+ w = read_memory_unsigned_integer (start_pc, 2);
+ }
+
+ /* Now check for subtracting r5 from sp, word sized only. */
+ if (IS_SUB_R5SP (w))
+ {
+ start_pc += 2 + adjust;
+ w = read_memory_unsigned_integer (start_pc, 2);
+ }
+
+ /* Check for subs #2 and subs #4. */
+ while (IS_SUB2_SP (w) || IS_SUB4_SP (w))
+ {
+ start_pc += 2 + adjust;
+ w = read_memory_unsigned_integer (start_pc, 2);
+ }
+
+ /* Check for a 32bit subtract. */
+ if (IS_SUBL_SP (w))
+ start_pc += 6 + adjust;
+
+ return start_pc;
+}
+
+int
+gdb_print_insn_h8300 (bfd_vma memaddr, disassemble_info *info)
+{
+ if (h8300smode)
+ return print_insn_h8300s (memaddr, info);
+ else if (h8300hmode)
+ return print_insn_h8300h (memaddr, info);
+ else
+ return print_insn_h8300 (memaddr, info);
+}
+
+/* Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+
+ For us, the frame address is its stack pointer value, so we look up
+ the function prologue to determine the caller's sp value, and return it. */
+
+CORE_ADDR
+h8300_frame_chain (struct frame_info *thisframe)
+{
+ if (PC_IN_CALL_DUMMY (thisframe->pc, thisframe->frame, thisframe->frame))
+ { /* initialize the from_pc now */
+ thisframe->from_pc = generic_read_register_dummy (thisframe->pc,
+ thisframe->frame,
+ PC_REGNUM);
+ return thisframe->frame;
+ }
+ h8300_frame_find_saved_regs (thisframe, (struct frame_saved_regs *) 0);
+ return thisframe->fsr->regs[SP_REGNUM];
+}
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame.
+
+ We cache the result of doing this in the frame_obstack, since it is
+ fairly expensive. */
+
+void
+h8300_frame_find_saved_regs (struct frame_info *fi,
+ struct frame_saved_regs *fsr)
+{
+ register struct frame_saved_regs *cache_fsr;
+ CORE_ADDR ip;
+ struct symtab_and_line sal;
+ CORE_ADDR limit;
+
+ if (!fi->fsr)
+ {
+ cache_fsr = (struct frame_saved_regs *)
+ frame_obstack_alloc (sizeof (struct frame_saved_regs));
+ memset (cache_fsr, '\0', sizeof (struct frame_saved_regs));
+
+ fi->fsr = cache_fsr;
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ { /* no more to do. */
+ if (fsr)
+ *fsr = *fi->fsr;
+ return;
+ }
+ /* Find the start and end of the function prologue. If the PC
+ is in the function prologue, we only consider the part that
+ has executed already. */
+
+ ip = get_pc_function_start (fi->pc);
+ sal = find_pc_line (ip, 0);
+ limit = (sal.end && sal.end < fi->pc) ? sal.end : fi->pc;
+
+ /* This will fill in fields in *fi as well as in cache_fsr. */
+ examine_prologue (ip, limit, fi->frame, cache_fsr, fi);
+ }
+
+ if (fsr)
+ *fsr = *fi->fsr;
+}
+
+/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
+ is not the address of a valid instruction, the address of the next
+ instruction beyond ADDR otherwise. *PWORD1 receives the first word
+ of the instruction. */
+
+CORE_ADDR
+NEXT_PROLOGUE_INSN (CORE_ADDR addr, CORE_ADDR lim, INSN_WORD *pword1)
+{
+ char buf[2];
+ if (addr < lim + 8)
+ {
+ read_memory (addr, buf, 2);
+ *pword1 = extract_signed_integer (buf, 2);
+
+ return addr + 2;
+ }
+ return 0;
+}
+
+/* Examine the prologue of a function. `ip' points to the first instruction.
+ `limit' is the limit of the prologue (e.g. the addr of the first
+ linenumber, or perhaps the program counter if we're stepping through).
+ `frame_sp' is the stack pointer value in use in this frame.
+ `fsr' is a pointer to a frame_saved_regs structure into which we put
+ info about the registers saved by this frame.
+ `fi' is a struct frame_info pointer; we fill in various fields in it
+ to reflect the offsets of the arg pointer and the locals pointer. */
+
+static CORE_ADDR
+examine_prologue (register CORE_ADDR ip, register CORE_ADDR limit,
+ CORE_ADDR after_prolog_fp, struct frame_saved_regs *fsr,
+ struct frame_info *fi)
+{
+ register CORE_ADDR next_ip;
+ int r;
+ int have_fp = 0;
+ INSN_WORD insn_word;
+ /* Number of things pushed onto stack, starts at 2/4, 'cause the
+ PC is already there */
+ unsigned int reg_save_depth = h8300hmode ? 4 : 2;
+
+ unsigned int auto_depth = 0; /* Number of bytes of autos */
+
+ char in_frame[11]; /* One for each reg */
+
+ int adjust = 0;
+
+ memset (in_frame, 1, 11);
+ for (r = 0; r < 8; r++)
+ {
+ fsr->regs[r] = 0;
+ }
+ if (after_prolog_fp == 0)
+ {
+ after_prolog_fp = read_register (SP_REGNUM);
+ }
+
+ /* If the PC isn't valid, quit now. */
+ if (ip == 0 || ip & (h8300hmode ? ~0xffffff : ~0xffff))
+ return 0;
+
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
+
+ if (insn_word == 0x0100)
+ {
+ insn_word = read_memory_unsigned_integer (ip + 2, 2);
+ adjust = 2;
+ }
+
+ /* Skip over any fp push instructions */
+ fsr->regs[6] = after_prolog_fp;
+ while (next_ip && IS_PUSH_FP (insn_word))
+ {
+ ip = next_ip + adjust;
+
+ in_frame[insn_word & 0x7] = reg_save_depth;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
+ reg_save_depth += 2 + adjust;
+ }
+
+ /* Is this a move into the fp */
+ if (next_ip && IS_MOV_SP_FP (insn_word))
+ {
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
+ have_fp = 1;
+ }
+
+ /* Skip over any stack adjustment, happens either with a number of
+ sub#2,sp or a mov #x,r5 sub r5,sp */
+
+ if (next_ip && (IS_SUB2_SP (insn_word) || IS_SUB4_SP (insn_word)))
+ {
+ while (next_ip && (IS_SUB2_SP (insn_word) || IS_SUB4_SP (insn_word)))
+ {
+ auto_depth += IS_SUB2_SP (insn_word) ? 2 : 4;
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
+ }
+ }
+ else
+ {
+ if (next_ip && IS_MOVK_R5 (insn_word))
+ {
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
+ auto_depth += insn_word;
+
+ next_ip = NEXT_PROLOGUE_INSN (next_ip, limit, &insn_word);
+ auto_depth += insn_word;
+ }
+ if (next_ip && IS_SUBL_SP (insn_word))
+ {
+ ip = next_ip;
+ auto_depth += read_memory_unsigned_integer (ip, 4);
+ ip += 4;
+
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
+ }
+ }
+
+ /* Now examine the push insns to determine where everything lives
+ on the stack. */
+ while (1)
+ {
+ adjust = 0;
+ if (!next_ip)
+ break;
+
+ if (insn_word == 0x0100)
+ {
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
+ adjust = 2;
+ }
+
+ if (IS_PUSH (insn_word))
+ {
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
+ fsr->regs[r] = after_prolog_fp + auto_depth;
+ auto_depth += 2 + adjust;
+ continue;
+ }
+
+ /* Now check for push multiple insns. */
+ if (insn_word == 0x0110 || insn_word == 0x0120 || insn_word == 0x0130)
+ {
+ int count = ((insn_word >> 4) & 0xf) + 1;
+ int start, i;
+
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
+ start = insn_word & 0x7;
+
+ for (i = start; i <= start + count; i++)
+ {
+ fsr->regs[i] = after_prolog_fp + auto_depth;
+ auto_depth += 4;
+ }
+ }
+ break;
+ }
+
+ /* The args are always reffed based from the stack pointer */
+ fi->args_pointer = after_prolog_fp;
+ /* Locals are always reffed based from the fp */
+ fi->locals_pointer = after_prolog_fp;
+ /* The PC is at a known place */
+ fi->from_pc = read_memory_unsigned_integer (after_prolog_fp + BINWORD, BINWORD);
+
+ /* Rememeber any others too */
+ in_frame[PC_REGNUM] = 0;
+
+ if (have_fp)
+ /* We keep the old FP in the SP spot */
+ fsr->regs[SP_REGNUM] = read_memory_unsigned_integer (fsr->regs[6], BINWORD);
+ else
+ fsr->regs[SP_REGNUM] = after_prolog_fp + auto_depth;
+
+ return (ip);
+}
+
+void
+h8300_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ fi->fsr = 0; /* Not yet allocated */
+ fi->args_pointer = 0; /* Unknown */
+ fi->locals_pointer = 0; /* Unknown */
+ fi->from_pc = 0;
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ { /* anything special to do? */
+ return;
+ }
+}
+
+/* Return the saved PC from this frame.
+
+ If the frame has a memory copy of SRP_REGNUM, use that. If not,
+ just use the register SRP_REGNUM itself. */
+
+CORE_ADDR
+h8300_frame_saved_pc (struct frame_info *frame)
+{
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ return generic_read_register_dummy (frame->pc, frame->frame, PC_REGNUM);
+ else
+ return frame->from_pc;
+}
+
+CORE_ADDR
+h8300_frame_locals_address (struct frame_info *fi)
+{
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return (CORE_ADDR) 0; /* Not sure what else to do... */
+ if (!fi->locals_pointer)
+ {
+ struct frame_saved_regs ignore;
+
+ get_frame_saved_regs (fi, &ignore);
+
+ }
+ return fi->locals_pointer;
+}
+
+/* Return the address of the argument block for the frame
+ described by FI. Returns 0 if the address is unknown. */
+
+CORE_ADDR
+h8300_frame_args_address (struct frame_info *fi)
+{
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return (CORE_ADDR) 0; /* Not sure what else to do... */
+ if (!fi->args_pointer)
+ {
+ struct frame_saved_regs ignore;
+
+ get_frame_saved_regs (fi, &ignore);
+
+ }
+
+ return fi->args_pointer;
+}
+
+/* Function: push_arguments
+ Setup the function arguments for calling a function in the inferior.
+
+ On the Hitachi H8/300 architecture, there are three registers (R0 to R2)
+ which are dedicated for passing function arguments. Up to the first
+ three arguments (depending on size) may go into these registers.
+ The rest go on the stack.
+
+ Arguments that are smaller than WORDSIZE bytes will still take up a
+ whole register or a whole WORDSIZE word on the stack, and will be
+ right-justified in the register or the stack word. This includes
+ chars and small aggregate types. Note that WORDSIZE depends on the
+ cpu type.
+
+ Arguments that are larger than WORDSIZE bytes will be split between
+ two or more registers as available, but will NOT be split between a
+ register and the stack.
+
+ An exceptional case exists for struct arguments (and possibly other
+ aggregates such as arrays) -- if the size is larger than WORDSIZE
+ bytes but not a multiple of WORDSIZE bytes. In this case the
+ argument is never split between the registers and the stack, but
+ instead is copied in its entirety onto the stack, AND also copied
+ into as many registers as there is room for. In other words, space
+ in registers permitting, two copies of the same argument are passed
+ in. As far as I can tell, only the one on the stack is used,
+ although that may be a function of the level of compiler
+ optimization. I suspect this is a compiler bug. Arguments of
+ these odd sizes are left-justified within the word (as opposed to
+ arguments smaller than WORDSIZE bytes, which are right-justified).
+
+ If the function is to return an aggregate type such as a struct,
+ the caller must allocate space into which the callee will copy the
+ return value. In this case, a pointer to the return value location
+ is passed into the callee in register R0, which displaces one of
+ the other arguments passed in via registers R0 to R2. */
+
+CORE_ADDR
+h8300_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ unsigned char struct_return, CORE_ADDR struct_addr)
+{
+ int stack_align, stack_alloc, stack_offset;
+ int wordsize;
+ int argreg;
+ int argnum;
+ struct type *type;
+ CORE_ADDR regval;
+ char *val;
+ char valbuf[4];
+ int len;
+
+ if (h8300hmode || h8300smode)
+ {
+ stack_align = 3;
+ wordsize = 4;
+ }
+ else
+ {
+ stack_align = 1;
+ wordsize = 2;
+ }
+
+ /* first force sp to a n-byte alignment */
+ sp = sp & ~stack_align;
+
+ /* Now make sure there's space on the stack */
+ for (argnum = 0, stack_alloc = 0;
+ argnum < nargs; argnum++)
+ stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + stack_align)
+ & ~stack_align);
+ sp -= stack_alloc; /* make room on stack for args */
+ /* we may over-allocate a little here, but that won't hurt anything */
+
+ argreg = ARG0_REGNUM;
+ if (struct_return) /* "struct return" pointer takes up one argreg */
+ {
+ write_register (argreg++, struct_addr);
+ }
+
+ /* Now load as many as possible of the first arguments into
+ registers, and push the rest onto the stack. There are 3N bytes
+ in three registers available. Loop thru args from first to last. */
+
+ for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
+ {
+ type = VALUE_TYPE (args[argnum]);
+ len = TYPE_LENGTH (type);
+ memset (valbuf, 0, sizeof (valbuf));
+ if (len < wordsize)
+ {
+ /* the purpose of this is to right-justify the value within the word */
+ memcpy (valbuf + (wordsize - len),
+ (char *) VALUE_CONTENTS (args[argnum]), len);
+ val = valbuf;
+ }
+ else
+ val = (char *) VALUE_CONTENTS (args[argnum]);
+
+ if (len > (ARGLAST_REGNUM + 1 - argreg) * REGISTER_RAW_SIZE (ARG0_REGNUM) ||
+ (len > wordsize && (len & stack_align) != 0))
+ { /* passed on the stack */
+ write_memory (sp + stack_offset, val,
+ len < wordsize ? wordsize : len);
+ stack_offset += (len + stack_align) & ~stack_align;
+ }
+ /* NOTE WELL!!!!! This is not an "else if" clause!!!
+ That's because some *&^%$ things get passed on the stack
+ AND in the registers! */
+ if (len <= (ARGLAST_REGNUM + 1 - argreg) * REGISTER_RAW_SIZE (ARG0_REGNUM))
+ while (len > 0)
+ { /* there's room in registers */
+ regval = extract_address (val, wordsize);
+ write_register (argreg, regval);
+ len -= wordsize;
+ val += wordsize;
+ argreg++;
+ }
+ }
+ return sp;
+}
+
+/* Function: push_return_address
+ Setup the return address for a dummy frame, as called by
+ call_function_by_hand. Only necessary when you are using an
+ empty CALL_DUMMY, ie. the target will not actually be executing
+ a JSR/BSR instruction. */
+
+CORE_ADDR
+h8300_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ unsigned char buf[4];
+ int wordsize;
+
+ if (h8300hmode || h8300smode)
+ wordsize = 4;
+ else
+ wordsize = 2;
+
+ sp -= wordsize;
+ store_unsigned_integer (buf, wordsize, CALL_DUMMY_ADDRESS ());
+ write_memory (sp, buf, wordsize);
+ return sp;
+}
+
+/* Function: h8300_pop_frame
+ Restore the machine to the state it had before the current frame
+ was created. Usually used either by the "RETURN" command, or by
+ call_function_by_hand after the dummy_frame is finished. */
+
+void
+h8300_pop_frame (void)
+{
+ unsigned regnum;
+ struct frame_saved_regs fsr;
+ struct frame_info *frame = get_current_frame ();
+
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ {
+ generic_pop_dummy_frame ();
+ }
+ else
+ {
+ get_frame_saved_regs (frame, &fsr);
+
+ for (regnum = 0; regnum < 8; regnum++)
+ {
+ /* Don't forget SP_REGNUM is a frame_saved_regs struct is the
+ actual value we want, not the address of the value we want. */
+ if (fsr.regs[regnum] && regnum != SP_REGNUM)
+ write_register (regnum,
+ read_memory_integer (fsr.regs[regnum], BINWORD));
+ else if (fsr.regs[regnum] && regnum == SP_REGNUM)
+ write_register (regnum, frame->frame + 2 * BINWORD);
+ }
+
+ /* Don't forget the update the PC too! */
+ write_pc (frame->from_pc);
+ }
+ flush_cached_frames ();
+}
+
+/* Function: extract_return_value
+ Figure out where in REGBUF the called function has left its return value.
+ Copy that into VALBUF. Be sure to account for CPU type. */
+
+void
+h8300_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ int wordsize, len;
+
+ if (h8300smode || h8300hmode)
+ wordsize = 4;
+ else
+ wordsize = 2;
+
+ len = TYPE_LENGTH (type);
+
+ switch (len)
+ {
+ case 1: /* (char) */
+ case 2: /* (short), (int) */
+ memcpy (valbuf, regbuf + REGISTER_BYTE (0) + (wordsize - len), len);
+ break;
+ case 4: /* (long), (float) */
+ if (h8300smode || h8300hmode)
+ {
+ memcpy (valbuf, regbuf + REGISTER_BYTE (0), 4);
+ }
+ else
+ {
+ memcpy (valbuf, regbuf + REGISTER_BYTE (0), 2);
+ memcpy (valbuf + 2, regbuf + REGISTER_BYTE (1), 2);
+ }
+ break;
+ case 8: /* (double) (doesn't seem to happen, which is good,
+ because this almost certainly isn't right. */
+ error ("I don't know how a double is returned.");
+ break;
+ }
+}
+
+/* Function: store_return_value
+ Place the appropriate value in the appropriate registers.
+ Primarily used by the RETURN command. */
+
+void
+h8300_store_return_value (struct type *type, char *valbuf)
+{
+ int wordsize, len, regval;
+
+ if (h8300hmode || h8300smode)
+ wordsize = 4;
+ else
+ wordsize = 2;
+
+ len = TYPE_LENGTH (type);
+ switch (len)
+ {
+ case 1: /* char */
+ case 2: /* short, int */
+ regval = extract_address (valbuf, len);
+ write_register (0, regval);
+ break;
+ case 4: /* long, float */
+ regval = extract_address (valbuf, len);
+ if (h8300smode || h8300hmode)
+ {
+ write_register (0, regval);
+ }
+ else
+ {
+ write_register (0, regval >> 16);
+ write_register (1, regval & 0xffff);
+ }
+ break;
+ case 8: /* presumeably double, but doesn't seem to happen */
+ error ("I don't know how to return a double.");
+ break;
+ }
+}
+
+struct cmd_list_element *setmemorylist;
+
+static void
+set_register_names (void)
+{
+ if (h8300hmode != 0)
+ h8300_register_names = h8300h_register_names;
+ else
+ h8300_register_names = original_register_names;
+}
+
+static void
+h8300_command (char *args, int from_tty)
+{
+ extern int h8300hmode;
+ h8300hmode = 0;
+ h8300smode = 0;
+ set_register_names ();
+}
+
+static void
+h8300h_command (char *args, int from_tty)
+{
+ extern int h8300hmode;
+ h8300hmode = 1;
+ h8300smode = 0;
+ set_register_names ();
+}
+
+static void
+h8300s_command (char *args, int from_tty)
+{
+ extern int h8300smode;
+ extern int h8300hmode;
+ h8300smode = 1;
+ h8300hmode = 1;
+ set_register_names ();
+}
+
+static void
+set_machine (char *args, int from_tty)
+{
+ printf_unfiltered ("\"set machine\" must be followed by h8300, h8300h");
+ printf_unfiltered ("or h8300s");
+ help_list (setmemorylist, "set memory ", -1, gdb_stdout);
+}
+
+/* set_machine_hook is called as the exec file is being opened, but
+ before the symbol file is opened. This allows us to set the
+ h8300hmode flag based on the machine type specified in the exec
+ file. This in turn will cause subsequently defined pointer types
+ to be 16 or 32 bits as appropriate for the machine. */
+
+static void
+set_machine_hook (char *filename)
+{
+ if (bfd_get_mach (exec_bfd) == bfd_mach_h8300s)
+ {
+ h8300smode = 1;
+ h8300hmode = 1;
+ }
+ else if (bfd_get_mach (exec_bfd) == bfd_mach_h8300h)
+ {
+ h8300smode = 0;
+ h8300hmode = 1;
+ }
+ else
+ {
+ h8300smode = 0;
+ h8300hmode = 0;
+ }
+ set_register_names ();
+}
+
+void
+_initialize_h8300m (void)
+{
+ add_prefix_cmd ("machine", no_class, set_machine,
+ "set the machine type",
+ &setmemorylist, "set machine ", 0,
+ &setlist);
+
+ add_cmd ("h8300", class_support, h8300_command,
+ "Set machine to be H8/300.", &setmemorylist);
+
+ add_cmd ("h8300h", class_support, h8300h_command,
+ "Set machine to be H8/300H.", &setmemorylist);
+
+ add_cmd ("h8300s", class_support, h8300s_command,
+ "Set machine to be H8/300S.", &setmemorylist);
+
+ /* Add a hook to set the machine type when we're loading a file. */
+
+ specify_exec_file_hook (set_machine_hook);
+}
+
+void
+h8300_print_register_hook (int regno)
+{
+ if (regno == CCR_REGNUM)
+ {
+ /* CCR register */
+ int C, Z, N, V;
+ unsigned char b[REGISTER_SIZE];
+ unsigned char l;
+ frame_register_read (selected_frame, regno, b);
+ l = b[REGISTER_VIRTUAL_SIZE (CCR_REGNUM) - 1];
+ printf_unfiltered ("\t");
+ printf_unfiltered ("I-%d ", (l & 0x80) != 0);
+ printf_unfiltered ("UI-%d ", (l & 0x40) != 0);
+ printf_unfiltered ("H-%d ", (l & 0x20) != 0);
+ printf_unfiltered ("U-%d ", (l & 0x10) != 0);
+ N = (l & 0x8) != 0;
+ Z = (l & 0x4) != 0;
+ V = (l & 0x2) != 0;
+ C = (l & 0x1) != 0;
+ printf_unfiltered ("N-%d ", N);
+ printf_unfiltered ("Z-%d ", Z);
+ printf_unfiltered ("V-%d ", V);
+ printf_unfiltered ("C-%d ", C);
+ if ((C | Z) == 0)
+ printf_unfiltered ("u> ");
+ if ((C | Z) == 1)
+ printf_unfiltered ("u<= ");
+ if ((C == 0))
+ printf_unfiltered ("u>= ");
+ if (C == 1)
+ printf_unfiltered ("u< ");
+ if (Z == 0)
+ printf_unfiltered ("!= ");
+ if (Z == 1)
+ printf_unfiltered ("== ");
+ if ((N ^ V) == 0)
+ printf_unfiltered (">= ");
+ if ((N ^ V) == 1)
+ printf_unfiltered ("< ");
+ if ((Z | (N ^ V)) == 0)
+ printf_unfiltered ("> ");
+ if ((Z | (N ^ V)) == 1)
+ printf_unfiltered ("<= ");
+ }
+
+ if (regno == EXR_REGNUM && h8300smode)
+ {
+ /* EXR register */
+ unsigned char b[REGISTER_SIZE];
+ unsigned char l;
+ frame_register_read (selected_frame, regno, b);
+ l = b[REGISTER_VIRTUAL_SIZE (EXR_REGNUM) - 1];
+ printf_unfiltered ("\t");
+ printf_unfiltered ("T-%d - - - ", (l & 0x80) != 0);
+ printf_unfiltered ("I2-%d ", (l & 4) != 0);
+ printf_unfiltered ("I1-%d ", (l & 2) != 0);
+ printf_unfiltered ("I0-%d", (l & 1) != 0);
+ }
+}
+
+void
+_initialize_h8300_tdep (void)
+{
+ tm_print_insn = gdb_print_insn_h8300;
+}
diff --git a/gdb/h8500-tdep.c b/gdb/h8500-tdep.c
new file mode 100644
index 00000000000..04ba7067630
--- /dev/null
+++ b/gdb/h8500-tdep.c
@@ -0,0 +1,628 @@
+/* Target-dependent code for Hitachi H8/500, for GDB.
+
+ Copyright 1993, 1994, 1995, 1998, 2000, 2001, 2002 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. */
+
+/*
+ Contributed by Steve Chamberlain
+ sac@cygnus.com
+ */
+
+#include "defs.h"
+#include "frame.h"
+#include "obstack.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcmd.h"
+#include "value.h"
+#include "dis-asm.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#define UNSIGNED_SHORT(X) ((X) & 0xffff)
+
+static int code_size = 2;
+
+static int data_size = 2;
+
+/* Shape of an H8/500 frame :
+
+ arg-n
+ ..
+ arg-2
+ arg-1
+ return address <2 or 4 bytes>
+ old fp <2 bytes>
+ auto-n
+ ..
+ auto-1
+ saved registers
+
+ */
+
+/* an easy to debug H8 stack frame looks like:
+ 0x6df6 push r6
+ 0x0d76 mov.w r7,r6
+ 0x6dfn push reg
+ 0x7905 nnnn mov.w #n,r5 or 0x1b87 subs #2,sp
+ 0x1957 sub.w r5,sp
+
+ */
+
+#define IS_PUSH(x) (((x) & 0xff00)==0x6d00)
+#define IS_LINK_8(x) ((x) == 0x17)
+#define IS_LINK_16(x) ((x) == 0x1f)
+#define IS_MOVE_FP(x) ((x) == 0x0d76)
+#define IS_MOV_SP_FP(x) ((x) == 0x0d76)
+#define IS_SUB2_SP(x) ((x) == 0x1b87)
+#define IS_MOVK_R5(x) ((x) == 0x7905)
+#define IS_SUB_R5SP(x) ((x) == 0x1957)
+
+#define LINK_8 0x17
+#define LINK_16 0x1f
+
+int minimum_mode = 1;
+
+CORE_ADDR
+h8500_skip_prologue (CORE_ADDR start_pc)
+{
+ short int w;
+
+ w = read_memory_integer (start_pc, 1);
+ if (w == LINK_8)
+ {
+ start_pc += 2;
+ w = read_memory_integer (start_pc, 1);
+ }
+
+ if (w == LINK_16)
+ {
+ start_pc += 3;
+ w = read_memory_integer (start_pc, 2);
+ }
+
+ return start_pc;
+}
+
+CORE_ADDR
+h8500_addr_bits_remove (CORE_ADDR addr)
+{
+ return ((addr) & 0xffffff);
+}
+
+/* Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+
+ For us, the frame address is its stack pointer value, so we look up
+ the function prologue to determine the caller's sp value, and return it. */
+
+CORE_ADDR
+h8500_frame_chain (struct frame_info *thisframe)
+{
+ if (!inside_entry_file (thisframe->pc))
+ return (read_memory_integer (FRAME_FP (thisframe), PTR_SIZE));
+ else
+ return 0;
+}
+
+/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
+ is not the address of a valid instruction, the address of the next
+ instruction beyond ADDR otherwise. *PWORD1 receives the first word
+ of the instruction. */
+
+CORE_ADDR
+NEXT_PROLOGUE_INSN (CORE_ADDR addr, CORE_ADDR lim, char *pword1)
+{
+ if (addr < lim + 8)
+ {
+ read_memory (addr, pword1, 1);
+ read_memory (addr, pword1 + 1, 1);
+ return 1;
+ }
+ return 0;
+}
+
+/* Examine the prologue of a function. `ip' points to the first
+ instruction. `limit' is the limit of the prologue (e.g. the addr
+ of the first linenumber, or perhaps the program counter if we're
+ stepping through). `frame_sp' is the stack pointer value in use in
+ this frame. `fsr' is a pointer to a frame_saved_regs structure
+ into which we put info about the registers saved by this frame.
+ `fi' is a struct frame_info pointer; we fill in various fields in
+ it to reflect the offsets of the arg pointer and the locals
+ pointer. */
+
+/* Return the saved PC from this frame. */
+
+CORE_ADDR
+frame_saved_pc (struct frame_info *frame)
+{
+ return read_memory_integer (FRAME_FP (frame) + 2, PTR_SIZE);
+}
+
+void
+h8500_pop_frame (void)
+{
+ unsigned regnum;
+ struct frame_saved_regs fsr;
+ struct frame_info *frame = get_current_frame ();
+
+ get_frame_saved_regs (frame, &fsr);
+
+ for (regnum = 0; regnum < 8; regnum++)
+ {
+ if (fsr.regs[regnum])
+ write_register (regnum, read_memory_short (fsr.regs[regnum]));
+
+ flush_cached_frames ();
+ }
+}
+
+void
+print_register_hook (int regno)
+{
+ if (regno == CCR_REGNUM)
+ {
+ /* CCR register */
+
+ int C, Z, N, V;
+ unsigned char b[2];
+ unsigned char l;
+
+ frame_register_read (selected_frame, regno, b);
+ l = b[1];
+ printf_unfiltered ("\t");
+ printf_unfiltered ("I-%d - ", (l & 0x80) != 0);
+ N = (l & 0x8) != 0;
+ Z = (l & 0x4) != 0;
+ V = (l & 0x2) != 0;
+ C = (l & 0x1) != 0;
+ printf_unfiltered ("N-%d ", N);
+ printf_unfiltered ("Z-%d ", Z);
+ printf_unfiltered ("V-%d ", V);
+ printf_unfiltered ("C-%d ", C);
+ if ((C | Z) == 0)
+ printf_unfiltered ("u> ");
+ if ((C | Z) == 1)
+ printf_unfiltered ("u<= ");
+ if ((C == 0))
+ printf_unfiltered ("u>= ");
+ if (C == 1)
+ printf_unfiltered ("u< ");
+ if (Z == 0)
+ printf_unfiltered ("!= ");
+ if (Z == 1)
+ printf_unfiltered ("== ");
+ if ((N ^ V) == 0)
+ printf_unfiltered (">= ");
+ if ((N ^ V) == 1)
+ printf_unfiltered ("< ");
+ if ((Z | (N ^ V)) == 0)
+ printf_unfiltered ("> ");
+ if ((Z | (N ^ V)) == 1)
+ printf_unfiltered ("<= ");
+ }
+}
+
+int
+h8500_register_size (int regno)
+{
+ switch (regno)
+ {
+ case SEG_C_REGNUM:
+ case SEG_D_REGNUM:
+ case SEG_E_REGNUM:
+ case SEG_T_REGNUM:
+ return 1;
+ case R0_REGNUM:
+ case R1_REGNUM:
+ case R2_REGNUM:
+ case R3_REGNUM:
+ case R4_REGNUM:
+ case R5_REGNUM:
+ case R6_REGNUM:
+ case R7_REGNUM:
+ case CCR_REGNUM:
+ return 2;
+
+ case PR0_REGNUM:
+ case PR1_REGNUM:
+ case PR2_REGNUM:
+ case PR3_REGNUM:
+ case PR4_REGNUM:
+ case PR5_REGNUM:
+ case PR6_REGNUM:
+ case PR7_REGNUM:
+ case PC_REGNUM:
+ return 4;
+ default:
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+}
+
+struct type *
+h8500_register_virtual_type (int regno)
+{
+ switch (regno)
+ {
+ case SEG_C_REGNUM:
+ case SEG_E_REGNUM:
+ case SEG_D_REGNUM:
+ case SEG_T_REGNUM:
+ return builtin_type_unsigned_char;
+ case R0_REGNUM:
+ case R1_REGNUM:
+ case R2_REGNUM:
+ case R3_REGNUM:
+ case R4_REGNUM:
+ case R5_REGNUM:
+ case R6_REGNUM:
+ case R7_REGNUM:
+ case CCR_REGNUM:
+ return builtin_type_unsigned_short;
+ case PR0_REGNUM:
+ case PR1_REGNUM:
+ case PR2_REGNUM:
+ case PR3_REGNUM:
+ case PR4_REGNUM:
+ case PR5_REGNUM:
+ case PR6_REGNUM:
+ case PR7_REGNUM:
+ case PC_REGNUM:
+ return builtin_type_unsigned_long;
+ default:
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+}
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame. */
+
+void
+frame_find_saved_regs (struct frame_info *frame_info,
+ struct frame_saved_regs *frame_saved_regs)
+{
+ register int regnum;
+ register int regmask;
+ register CORE_ADDR next_addr;
+ register CORE_ADDR pc;
+ unsigned char thebyte;
+
+ memset (frame_saved_regs, '\0', sizeof *frame_saved_regs);
+
+ if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4
+ && (frame_info)->pc <= (frame_info)->frame)
+ {
+ next_addr = (frame_info)->frame;
+ pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4;
+ }
+ else
+ {
+ pc = get_pc_function_start ((frame_info)->pc);
+ /* Verify we have a link a6 instruction next;
+ if not we lose. If we win, find the address above the saved
+ regs using the amount of storage from the link instruction.
+ */
+
+ thebyte = read_memory_integer (pc, 1);
+ if (0x1f == thebyte)
+ next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 2), pc += 2;
+ else if (0x17 == thebyte)
+ next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 1), pc += 1;
+ else
+ goto lose;
+#if 0
+ /* FIXME steve */
+ /* If have an add:g.waddal #-n, sp next, adjust next_addr. */
+ if ((0x0c0177777 & read_memory_integer (pc, 2)) == 0157774)
+ next_addr += read_memory_integer (pc += 2, 4), pc += 4;
+#endif
+ }
+
+ thebyte = read_memory_integer (pc, 1);
+ if (thebyte == 0x12)
+ {
+ /* Got stm */
+ pc++;
+ regmask = read_memory_integer (pc, 1);
+ pc++;
+ for (regnum = 0; regnum < 8; regnum++, regmask >>= 1)
+ {
+ if (regmask & 1)
+ {
+ (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2;
+ }
+ }
+ thebyte = read_memory_integer (pc, 1);
+ }
+ /* Maybe got a load of pushes */
+ while (thebyte == 0xbf)
+ {
+ pc++;
+ regnum = read_memory_integer (pc, 1) & 0x7;
+ pc++;
+ (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2;
+ thebyte = read_memory_integer (pc, 1);
+ }
+
+lose:;
+
+ /* Remember the address of the frame pointer */
+ (frame_saved_regs)->regs[FP_REGNUM] = (frame_info)->frame;
+
+ /* This is where the old sp is hidden */
+ (frame_saved_regs)->regs[SP_REGNUM] = (frame_info)->frame;
+
+ /* And the PC - remember the pushed FP is always two bytes long */
+ (frame_saved_regs)->regs[PC_REGNUM] = (frame_info)->frame + 2;
+}
+
+CORE_ADDR
+saved_pc_after_call (void)
+{
+ int x;
+ int a = read_register (SP_REGNUM);
+
+ x = read_memory_integer (a, code_size);
+ if (code_size == 2)
+ {
+ /* Stick current code segement onto top */
+ x &= 0xffff;
+ x |= read_register (SEG_C_REGNUM) << 16;
+ }
+ x &= 0xffffff;
+ return x;
+}
+
+void
+h8500_set_pointer_size (int newsize)
+{
+ static int oldsize = 0;
+
+ if (oldsize != newsize)
+ {
+ printf_unfiltered ("pointer size set to %d bits\n", newsize);
+ oldsize = newsize;
+ if (newsize == 32)
+ {
+ minimum_mode = 0;
+ }
+ else
+ {
+ minimum_mode = 1;
+ }
+ _initialize_gdbtypes ();
+ }
+}
+
+static void
+big_command (char *arg, int from_tty)
+{
+ h8500_set_pointer_size (32);
+ code_size = 4;
+ data_size = 4;
+}
+
+static void
+medium_command (char *arg, int from_tty)
+{
+ h8500_set_pointer_size (32);
+ code_size = 4;
+ data_size = 2;
+}
+
+static void
+compact_command (char *arg, int from_tty)
+{
+ h8500_set_pointer_size (32);
+ code_size = 2;
+ data_size = 4;
+}
+
+static void
+small_command (char *arg, int from_tty)
+{
+ h8500_set_pointer_size (16);
+ code_size = 2;
+ data_size = 2;
+}
+
+static struct cmd_list_element *setmemorylist;
+
+static void
+set_memory (char *args, int from_tty)
+{
+ printf_unfiltered ("\"set memory\" must be followed by the name of a memory subcommand.\n");
+ help_list (setmemorylist, "set memory ", -1, gdb_stdout);
+}
+
+/* See if variable name is ppc or pr[0-7] */
+
+int
+h8500_is_trapped_internalvar (char *name)
+{
+ if (name[0] != 'p')
+ return 0;
+
+ if (strcmp (name + 1, "pc") == 0)
+ return 1;
+
+ if (name[1] == 'r'
+ && name[2] >= '0'
+ && name[2] <= '7'
+ && name[3] == '\000')
+ return 1;
+ else
+ return 0;
+}
+
+struct value *
+h8500_value_of_trapped_internalvar (struct internalvar *var)
+{
+ LONGEST regval;
+ unsigned char regbuf[4];
+ int page_regnum, regnum;
+
+ regnum = var->name[2] == 'c' ? PC_REGNUM : var->name[2] - '0';
+
+ switch (var->name[2])
+ {
+ case 'c':
+ page_regnum = SEG_C_REGNUM;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ page_regnum = SEG_D_REGNUM;
+ break;
+ case '4':
+ case '5':
+ page_regnum = SEG_E_REGNUM;
+ break;
+ case '6':
+ case '7':
+ page_regnum = SEG_T_REGNUM;
+ break;
+ }
+
+ get_saved_register (regbuf, NULL, NULL, selected_frame, page_regnum, NULL);
+ regval = regbuf[0] << 16;
+
+ get_saved_register (regbuf, NULL, NULL, selected_frame, regnum, NULL);
+ regval |= regbuf[0] << 8 | regbuf[1]; /* XXX host/target byte order */
+
+ xfree (var->value); /* Free up old value */
+
+ var->value = value_from_longest (builtin_type_unsigned_long, regval);
+ release_value (var->value); /* Unchain new value */
+
+ VALUE_LVAL (var->value) = lval_internalvar;
+ VALUE_INTERNALVAR (var->value) = var;
+ return var->value;
+}
+
+void
+h8500_set_trapped_internalvar (struct internalvar *var, struct value *newval,
+ int bitpos, int bitsize, int offset)
+{
+ char *page_regnum, *regnum;
+ char expression[100];
+ unsigned new_regval;
+ struct type *type;
+ enum type_code newval_type_code;
+
+ type = check_typedef (VALUE_TYPE (newval));
+ newval_type_code = TYPE_CODE (type);
+
+ if ((newval_type_code != TYPE_CODE_INT
+ && newval_type_code != TYPE_CODE_PTR)
+ || TYPE_LENGTH (type) != sizeof (new_regval))
+ error ("Illegal type (%s) for assignment to $%s\n",
+ TYPE_NAME (VALUE_TYPE (newval)), var->name);
+
+ new_regval = *(long *) VALUE_CONTENTS_RAW (newval);
+
+ regnum = var->name + 1;
+
+ switch (var->name[2])
+ {
+ case 'c':
+ page_regnum = "cp";
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ page_regnum = "dp";
+ break;
+ case '4':
+ case '5':
+ page_regnum = "ep";
+ break;
+ case '6':
+ case '7':
+ page_regnum = "tp";
+ break;
+ }
+
+ sprintf (expression, "$%s=%d", page_regnum, new_regval >> 16);
+ parse_and_eval (expression);
+
+ sprintf (expression, "$%s=%d", regnum, new_regval & 0xffff);
+ parse_and_eval (expression);
+}
+
+CORE_ADDR
+h8500_read_sp (void)
+{
+ return read_register (PR7_REGNUM);
+}
+
+void
+h8500_write_sp (CORE_ADDR v)
+{
+ write_register (PR7_REGNUM, v);
+}
+
+CORE_ADDR
+h8500_read_pc (ptid_t ptid)
+{
+ return read_register (PC_REGNUM);
+}
+
+void
+h8500_write_pc (CORE_ADDR v, ptid_t ptid)
+{
+ write_register (PC_REGNUM, v);
+}
+
+CORE_ADDR
+h8500_read_fp (void)
+{
+ return read_register (PR6_REGNUM);
+}
+
+void
+_initialize_h8500_tdep (void)
+{
+ tm_print_insn = print_insn_h8500;
+
+ add_prefix_cmd ("memory", no_class, set_memory,
+ "set the memory model", &setmemorylist, "set memory ", 0,
+ &setlist);
+
+ add_cmd ("small", class_support, small_command,
+ "Set small memory model. (16 bit code, 16 bit data)", &setmemorylist);
+
+ add_cmd ("big", class_support, big_command,
+ "Set big memory model. (32 bit code, 32 bit data)", &setmemorylist);
+
+ add_cmd ("medium", class_support, medium_command,
+ "Set medium memory model. (32 bit code, 16 bit data)", &setmemorylist);
+
+ add_cmd ("compact", class_support, compact_command,
+ "Set compact memory model. (16 bit code, 32 bit data)", &setmemorylist);
+
+}
diff --git a/gdb/hp300ux-nat.c b/gdb/hp300ux-nat.c
new file mode 100644
index 00000000000..ecb8a35295b
--- /dev/null
+++ b/gdb/hp300ux-nat.c
@@ -0,0 +1,226 @@
+/* HP/UX native interface for HP 300's, for GDB when running under Unix.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1996, 1999, 2000,
+ 2001 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "regcache.h"
+
+/* Defining this means some system include files define some extra stuff. */
+#define WOPR
+#include <sys/param.h>
+#include <signal.h>
+#include <sys/user.h>
+#include <fcntl.h>
+
+#include <sys/ptrace.h>
+#include <sys/reg.h>
+#include <sys/trap.h>
+
+#include <sys/file.h>
+
+static void fetch_inferior_register (int, unsigned int);
+
+static void store_inferior_register_1 (int, unsigned int, int);
+
+static void store_inferior_register (int, unsigned int);
+
+/* Get kernel_u_addr using HPUX-style nlist(). */
+CORE_ADDR kernel_u_addr;
+
+struct hpnlist
+ {
+ char *n_name;
+ long n_value;
+ unsigned char n_type;
+ unsigned char n_length;
+ short n_almod;
+ short n_unused;
+ };
+static struct hpnlist nl[] =
+{
+ {"_u", -1,},
+ {(char *) 0,}};
+
+/* read the value of the u area from the hp-ux kernel */
+void
+_initialize_hp300ux_nat (void)
+{
+#ifndef HPUX_VERSION_5
+ nlist ("/hp-ux", nl);
+ kernel_u_addr = nl[0].n_value;
+#else /* HPUX version 5. */
+ kernel_u_addr = (CORE_ADDR) 0x0097900;
+#endif
+}
+
+#define INFERIOR_AR0(u) \
+ ((ptrace \
+ (PT_RUAREA, PIDGET (inferior_ptid), \
+ (PTRACE_ARG3_TYPE) ((char *) &u.u_ar0 - (char *) &u), 0, 0)) \
+ - kernel_u_addr)
+
+static void
+fetch_inferior_register (register int regno, register unsigned int regaddr)
+{
+#ifndef HPUX_VERSION_5
+ if (regno == PS_REGNUM)
+ {
+ union
+ {
+ int i;
+ short s[2];
+ }
+ ps_val;
+ int regval;
+
+ ps_val.i = (ptrace (PT_RUAREA, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) regaddr, 0, 0));
+ regval = ps_val.s[0];
+ supply_register (regno, (char *) &regval);
+ }
+ else
+#endif /* not HPUX_VERSION_5 */
+ {
+ char buf[MAX_REGISTER_RAW_SIZE];
+ register int i;
+
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+ {
+ *(int *) &buf[i] = ptrace (PT_RUAREA, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) regaddr, 0, 0);
+ regaddr += sizeof (int);
+ }
+ supply_register (regno, buf);
+ }
+ return;
+}
+
+static void
+store_inferior_register_1 (int regno, unsigned int regaddr, int val)
+{
+ errno = 0;
+ ptrace (PT_WUAREA, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr,
+ val, 0);
+#if 0
+ /* HP-UX randomly sets errno to non-zero for regno == 25.
+ However, the value is correctly written, so ignore errno. */
+ if (errno != 0)
+ {
+ char string_buf[64];
+
+ sprintf (string_buf, "writing register number %d", regno);
+ perror_with_name (string_buf);
+ }
+#endif
+ return;
+}
+
+static void
+store_inferior_register (register int regno, register unsigned int regaddr)
+{
+#ifndef HPUX_VERSION_5
+ if (regno == PS_REGNUM)
+ {
+ union
+ {
+ int i;
+ short s[2];
+ }
+ ps_val;
+
+ ps_val.i = (ptrace (PT_RUAREA, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) regaddr, 0, 0));
+ ps_val.s[0] = (read_register (regno));
+ store_inferior_register_1 (regno, regaddr, ps_val.i);
+ }
+ else
+#endif /* not HPUX_VERSION_5 */
+ {
+ register int i;
+
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+ {
+ store_inferior_register_1
+ (regno, regaddr,
+ (*(int *) &registers[(REGISTER_BYTE (regno)) + i]));
+ regaddr += sizeof (int);
+ }
+ }
+ return;
+}
+
+void
+fetch_inferior_registers (int regno)
+{
+ struct user u;
+ register unsigned int ar0_offset;
+
+ ar0_offset = (INFERIOR_AR0 (u));
+ if (regno == -1)
+ {
+ for (regno = 0; (regno < FP0_REGNUM); regno++)
+ fetch_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
+ for (; (regno < NUM_REGS); regno++)
+ fetch_inferior_register (regno, (FP_REGISTER_ADDR (u, regno)));
+ }
+ else
+ fetch_inferior_register (regno,
+ (regno < FP0_REGNUM
+ ? REGISTER_ADDR (ar0_offset, regno)
+ : FP_REGISTER_ADDR (u, regno)));
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (register int regno)
+{
+ struct user u;
+ register unsigned int ar0_offset;
+
+ if (regno >= FP0_REGNUM)
+ {
+ store_inferior_register (regno, (FP_REGISTER_ADDR (u, regno)));
+ return;
+ }
+
+ ar0_offset = (INFERIOR_AR0 (u));
+ if (regno >= 0)
+ {
+ store_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
+ return;
+ }
+
+ for (regno = 0; (regno < FP0_REGNUM); regno++)
+ store_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
+ for (; (regno < NUM_REGS); regno++)
+ store_inferior_register (regno, (FP_REGISTER_ADDR (u, regno)));
+ return;
+}
+
+int
+getpagesize (void)
+{
+ return 4096;
+}
diff --git a/gdb/hpacc-abi.c b/gdb/hpacc-abi.c
new file mode 100644
index 00000000000..6753cd7d865
--- /dev/null
+++ b/gdb/hpacc-abi.c
@@ -0,0 +1,328 @@
+/* Abstraction of HP aCC ABI.
+ Contributed by Daniel Berlin <dberlin@redhat.com>
+ Most of the real code is from HP, i've just fiddled it to fit in
+ the C++ ABI abstraction framework.
+
+ Copyright 2001 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 "defs.h"
+#include "value.h"
+#include "gdb_regex.h"
+#include "gdb_string.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "cp-abi.h"
+
+struct cp_abi_ops hpacc_abi_ops;
+
+/* It appears the is_*_name stuff is never used when we try the hpACC
+ * ABI. As such, I have no clue what the real answers are. Shouldn't
+ * have any more effect than it does now. */
+static regex_t constructor_pattern;
+static regex_t destructor_pattern;
+static regex_t operator_pattern;
+
+static enum dtor_kinds
+hpacc_is_destructor_name (const char *name)
+{
+ if (regexec (&destructor_pattern, name, 0, 0, 0) == 0)
+ return complete_object_dtor;
+ else
+ return 0;
+}
+
+static enum ctor_kinds
+hpacc_is_constructor_name (const char *name)
+{
+ if (regexec (&constructor_pattern, name, 0, 0, 0) == 0)
+ return complete_object_ctor;
+ else
+ return 0;
+}
+
+static int
+hpacc_is_operator_name (const char *name)
+{
+ return regexec (&operator_pattern, name, 0, 0, 0) == 0;
+}
+
+static int
+hpacc_is_vtable_name (const char *name)
+{
+ return strcmp (name,
+ "This will never match anything, please fill it in") == 0;
+}
+
+/* Return a virtual function as a value.
+ ARG1 is the object which provides the virtual function
+ table pointer. *ARG1P is side-effected in calling this function.
+ F is the list of member functions which contains the desired virtual
+ function.
+ J is an index into F which provides the desired virtual function.
+
+ TYPE is the type in which F is located. */
+static struct value *
+hpacc_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j,
+ struct type * type, int offset)
+{
+ struct value *arg1 = *arg1p;
+ struct type *type1 = check_typedef (VALUE_TYPE (arg1));
+
+ /* Deal with HP/Taligent runtime model for virtual functions */
+ struct value *vp;
+ struct value *argp; /* arg1 cast to base */
+ CORE_ADDR coreptr; /* pointer to target address */
+ int class_index; /* which class segment pointer to use */
+ struct type *ftype = TYPE_FN_FIELD_TYPE (f, j); /* method type */
+
+ argp = value_cast (type, *arg1p);
+
+ if (VALUE_ADDRESS (argp) == 0)
+ error ("Address of object is null; object may not have been created.");
+
+ /* pai: FIXME -- 32x64 possible problem? */
+ /* First word (4 bytes) in object layout is the vtable pointer */
+ coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (argp)); /* pai: (temp) */
+ /* + offset + VALUE_EMBEDDED_OFFSET (argp)); */
+
+ if (!coreptr)
+ error
+ ("Virtual table pointer is null for object; object may not have been created.");
+
+ /* pai/1997-05-09
+ * FIXME: The code here currently handles only
+ * the non-RRBC case of the Taligent/HP runtime spec; when RRBC
+ * is introduced, the condition for the "if" below will have to
+ * be changed to be a test for the RRBC case. */
+
+ if (1)
+ {
+ /* Non-RRBC case; the virtual function pointers are stored at fixed
+ * offsets in the virtual table. */
+
+ /* Retrieve the offset in the virtual table from the debug
+ * info. The offset of the vfunc's entry is in words from
+ * the beginning of the vtable; but first we have to adjust
+ * by HP_ACC_VFUNC_START to account for other entries */
+
+ /* pai: FIXME: 32x64 problem here, a word may be 8 bytes in
+ * which case the multiplier should be 8 and values should be long */
+ vp = value_at (builtin_type_int,
+ coreptr + 4 * (TYPE_FN_FIELD_VOFFSET (f, j) +
+ HP_ACC_VFUNC_START), NULL);
+
+ coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
+ /* coreptr now contains the address of the virtual function */
+ /* (Actually, it contains the pointer to the plabel for the function. */
+ }
+ else
+ {
+ /* RRBC case; the virtual function pointers are found by double
+ * indirection through the class segment tables. */
+
+ /* Choose class segment depending on type we were passed */
+ class_index = class_index_in_primary_list (type);
+
+ /* Find class segment pointer. These are in the vtable slots after
+ * some other entries, so adjust by HP_ACC_VFUNC_START for that. */
+ /* pai: FIXME 32x64 problem here, if words are 8 bytes long
+ * the multiplier below has to be 8 and value should be long. */
+ vp = value_at (builtin_type_int,
+ coreptr + 4 * (HP_ACC_VFUNC_START + class_index), NULL);
+ /* Indirect once more, offset by function index */
+ /* pai: FIXME 32x64 problem here, again multiplier could be 8 and value long */
+ coreptr =
+ *(CORE_ADDR *) (VALUE_CONTENTS (vp) +
+ 4 * TYPE_FN_FIELD_VOFFSET (f, j));
+ vp = value_at (builtin_type_int, coreptr, NULL);
+ coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
+
+ /* coreptr now contains the address of the virtual function */
+ /* (Actually, it contains the pointer to the plabel for the function.) */
+
+ }
+
+ if (!coreptr)
+ error ("Address of virtual function is null; error in virtual table?");
+
+ /* Wrap this addr in a value and return pointer */
+ vp = allocate_value (ftype);
+ VALUE_TYPE (vp) = ftype;
+ VALUE_ADDRESS (vp) = coreptr;
+
+ /* pai: (temp) do we need the value_ind stuff in value_fn_field? */
+ return vp;
+}
+
+
+static struct type *
+hpacc_value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
+{
+ struct type *known_type;
+ struct type *rtti_type;
+ CORE_ADDR coreptr;
+ struct value *vp;
+ int using_enclosing = 0;
+ long top_offset = 0;
+ char rtti_type_name[256];
+
+ if (full)
+ *full = 0;
+ if (top)
+ *top = -1;
+ if (using_enc)
+ *using_enc = 0;
+
+ /* Get declared type */
+ known_type = VALUE_TYPE (v);
+ CHECK_TYPEDEF (known_type);
+ /* RTTI works only or class objects */
+ if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
+ return NULL;
+
+ /* If neither the declared type nor the enclosing type of the
+ * value structure has a HP ANSI C++ style virtual table,
+ * we can't do anything. */
+ if (!TYPE_HAS_VTABLE (known_type))
+ {
+ known_type = VALUE_ENCLOSING_TYPE (v);
+ CHECK_TYPEDEF (known_type);
+ if ((TYPE_CODE (known_type) != TYPE_CODE_CLASS) ||
+ !TYPE_HAS_VTABLE (known_type))
+ return NULL; /* No RTTI, or not HP-compiled types */
+ CHECK_TYPEDEF (known_type);
+ using_enclosing = 1;
+ }
+
+ if (using_enclosing && using_enc)
+ *using_enc = 1;
+
+ /* First get the virtual table address */
+ coreptr = *(CORE_ADDR *) ((VALUE_CONTENTS_ALL (v))
+ + VALUE_OFFSET (v)
+ + (using_enclosing
+ ? 0
+ : VALUE_EMBEDDED_OFFSET (v)));
+ if (coreptr == 0)
+ /* return silently -- maybe called on gdb-generated value */
+ return NULL;
+
+ /* Fetch the top offset of the object */
+ /* FIXME possible 32x64 problem with pointer size & arithmetic */
+ vp = value_at (builtin_type_int,
+ coreptr + 4 * HP_ACC_TOP_OFFSET_OFFSET,
+ VALUE_BFD_SECTION (v));
+ top_offset = value_as_long (vp);
+ if (top)
+ *top = top_offset;
+
+ /* Fetch the typeinfo pointer */
+ /* FIXME possible 32x64 problem with pointer size & arithmetic */
+ vp = value_at (builtin_type_int, coreptr + 4 * HP_ACC_TYPEINFO_OFFSET,
+ VALUE_BFD_SECTION (v));
+ /* Indirect through the typeinfo pointer and retrieve the pointer
+ * to the string name */
+ coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
+ if (!coreptr)
+ error ("Retrieved null typeinfo pointer in trying to determine "
+ "run-time type");
+ /* 4 -> offset of name field */
+ vp = value_at (builtin_type_int, coreptr + 4, VALUE_BFD_SECTION (v));
+ /* FIXME possible 32x64 problem */
+
+ coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
+
+ read_memory_string (coreptr, rtti_type_name, 256);
+
+ if (strlen (rtti_type_name) == 0)
+ error ("Retrieved null type name from typeinfo");
+
+ /* search for type */
+ rtti_type = lookup_typename (rtti_type_name, (struct block *) 0, 1);
+
+ if (!rtti_type)
+ error ("Could not find run-time type: invalid type name %s in typeinfo??",
+ rtti_type_name);
+ CHECK_TYPEDEF (rtti_type);
+#if 0
+ printf ("RTTI type name %s, tag %s, full? %d\n", TYPE_NAME (rtti_type),
+ TYPE_TAG_NAME (rtti_type), full ? *full : -1);
+#endif
+ /* Check whether we have the entire object */
+ if (full /* Non-null pointer passed */
+ &&
+ /* Either we checked on the whole object in hand and found the
+ top offset to be zero */
+ (((top_offset == 0) &&
+ using_enclosing &&
+ TYPE_LENGTH (known_type) == TYPE_LENGTH (rtti_type))
+ ||
+ /* Or we checked on the embedded object and top offset was the
+ same as the embedded offset */
+ ((top_offset == VALUE_EMBEDDED_OFFSET (v)) &&
+ !using_enclosing &&
+ TYPE_LENGTH (VALUE_ENCLOSING_TYPE (v)) == TYPE_LENGTH (rtti_type))))
+
+ *full = 1;
+
+ return rtti_type;
+}
+
+extern int gnuv2_baseclass_offset (struct type *type, int index,
+ char *valaddr, CORE_ADDR address);
+
+static void
+init_hpacc_ops (void)
+{
+ hpacc_abi_ops.shortname = "hpaCC";
+ hpacc_abi_ops.longname = "HP aCC ABI";
+ hpacc_abi_ops.doc = "HP aCC ABI";
+ hpacc_abi_ops.is_destructor_name = hpacc_is_destructor_name;
+ hpacc_abi_ops.is_constructor_name = hpacc_is_constructor_name;
+ hpacc_abi_ops.is_vtable_name = hpacc_is_vtable_name;
+ hpacc_abi_ops.is_operator_name = hpacc_is_operator_name;
+ hpacc_abi_ops.virtual_fn_field = hpacc_virtual_fn_field;
+ hpacc_abi_ops.rtti_type = hpacc_value_rtti_type;
+ /* It seems that this function is specific to GNU G++ < 3.0.
+ However, it is called for data members even in the HP
+ case (although not for member functions).
+ FIXME: Is that correct? */
+ hpacc_abi_ops.baseclass_offset = gnuv2_baseclass_offset;
+}
+
+
+void
+_initialize_hpacc_abi (void)
+{
+ init_hpacc_ops ();
+
+ regcomp (&constructor_pattern,
+ "^This will never match anything, please fill it in$", REG_NOSUB);
+
+ regcomp (&destructor_pattern,
+ "^This will never match anything, please fill it in$", REG_NOSUB);
+
+ regcomp (&operator_pattern,
+ "^This will never match anything, please fill it in$", REG_NOSUB);
+
+ register_cp_abi (hpacc_abi_ops);
+}
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
new file mode 100644
index 00000000000..3890fc2f773
--- /dev/null
+++ b/gdb/hppa-tdep.c
@@ -0,0 +1,4773 @@
+/* Target-dependent code for the HP PA architecture, for GDB.
+
+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+ 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 "defs.h"
+#include "frame.h"
+#include "bfd.h"
+#include "inferior.h"
+#include "value.h"
+#include "regcache.h"
+#include "completer.h"
+
+/* For argument passing to the inferior */
+#include "symtab.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <dl.h>
+#include <sys/param.h>
+#include <signal.h>
+
+#include <sys/ptrace.h>
+#include <machine/save_state.h>
+
+#ifdef COFF_ENCAPSULATE
+#include "a.out.encap.h"
+#else
+#endif
+
+/*#include <sys/user.h> After a.out.h */
+#include <sys/file.h>
+#include "gdb_stat.h"
+#include "gdb_wait.h"
+
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "symfile.h"
+#include "objfiles.h"
+
+/* To support detection of the pseudo-initial frame
+ that threads have. */
+#define THREAD_INITIAL_FRAME_SYMBOL "__pthread_exit"
+#define THREAD_INITIAL_FRAME_SYM_LEN sizeof(THREAD_INITIAL_FRAME_SYMBOL)
+
+static int extract_5_load (unsigned int);
+
+static unsigned extract_5R_store (unsigned int);
+
+static unsigned extract_5r_store (unsigned int);
+
+static void find_dummy_frame_regs (struct frame_info *,
+ struct frame_saved_regs *);
+
+static int find_proc_framesize (CORE_ADDR);
+
+static int find_return_regnum (CORE_ADDR);
+
+struct unwind_table_entry *find_unwind_entry (CORE_ADDR);
+
+static int extract_17 (unsigned int);
+
+static unsigned deposit_21 (unsigned int, unsigned int);
+
+static int extract_21 (unsigned);
+
+static unsigned deposit_14 (int, unsigned int);
+
+static int extract_14 (unsigned);
+
+static void unwind_command (char *, int);
+
+static int low_sign_extend (unsigned int, unsigned int);
+
+static int sign_extend (unsigned int, unsigned int);
+
+static int restore_pc_queue (struct frame_saved_regs *);
+
+static int hppa_alignof (struct type *);
+
+/* To support multi-threading and stepping. */
+int hppa_prepare_to_proceed ();
+
+static int prologue_inst_adjust_sp (unsigned long);
+
+static int is_branch (unsigned long);
+
+static int inst_saves_gr (unsigned long);
+
+static int inst_saves_fr (unsigned long);
+
+static int pc_in_interrupt_handler (CORE_ADDR);
+
+static int pc_in_linker_stub (CORE_ADDR);
+
+static int compare_unwind_entries (const void *, const void *);
+
+static void read_unwind_info (struct objfile *);
+
+static void internalize_unwinds (struct objfile *,
+ struct unwind_table_entry *,
+ asection *, unsigned int,
+ unsigned int, CORE_ADDR);
+static void pa_print_registers (char *, int, int);
+static void pa_strcat_registers (char *, int, int, struct ui_file *);
+static void pa_register_look_aside (char *, int, long *);
+static void pa_print_fp_reg (int);
+static void pa_strcat_fp_reg (int, struct ui_file *, enum precision_type);
+static void record_text_segment_lowaddr (bfd *, asection *, void *);
+
+typedef struct
+ {
+ struct minimal_symbol *msym;
+ CORE_ADDR solib_handle;
+ CORE_ADDR return_val;
+ }
+args_for_find_stub;
+
+static int cover_find_stub_with_shl_get (PTR);
+
+static int is_pa_2 = 0; /* False */
+
+/* This is declared in symtab.c; set to 1 in hp-symtab-read.c */
+extern int hp_som_som_object_present;
+
+/* In breakpoint.c */
+extern int exception_catchpoints_are_fragile;
+
+/* This is defined in valops.c. */
+extern struct value *find_function_in_inferior (char *);
+
+/* Should call_function allocate stack space for a struct return? */
+int
+hppa_use_struct_convention (int gcc_p, struct type *type)
+{
+ return (TYPE_LENGTH (type) > 2 * REGISTER_SIZE);
+}
+
+
+/* Routines to extract various sized constants out of hppa
+ instructions. */
+
+/* This assumes that no garbage lies outside of the lower bits of
+ value. */
+
+static int
+sign_extend (unsigned val, unsigned bits)
+{
+ return (int) (val >> (bits - 1) ? (-1 << bits) | val : val);
+}
+
+/* For many immediate values the sign bit is the low bit! */
+
+static int
+low_sign_extend (unsigned val, unsigned bits)
+{
+ return (int) ((val & 0x1 ? (-1 << (bits - 1)) : 0) | val >> 1);
+}
+
+/* extract the immediate field from a ld{bhw}s instruction */
+
+static int
+extract_5_load (unsigned word)
+{
+ return low_sign_extend (word >> 16 & MASK_5, 5);
+}
+
+/* extract the immediate field from a break instruction */
+
+static unsigned
+extract_5r_store (unsigned word)
+{
+ return (word & MASK_5);
+}
+
+/* extract the immediate field from a {sr}sm instruction */
+
+static unsigned
+extract_5R_store (unsigned word)
+{
+ return (word >> 16 & MASK_5);
+}
+
+/* extract a 14 bit immediate field */
+
+static int
+extract_14 (unsigned word)
+{
+ return low_sign_extend (word & MASK_14, 14);
+}
+
+/* deposit a 14 bit constant in a word */
+
+static unsigned
+deposit_14 (int opnd, unsigned word)
+{
+ unsigned sign = (opnd < 0 ? 1 : 0);
+
+ return word | ((unsigned) opnd << 1 & MASK_14) | sign;
+}
+
+/* extract a 21 bit constant */
+
+static int
+extract_21 (unsigned word)
+{
+ int val;
+
+ word &= MASK_21;
+ word <<= 11;
+ val = GET_FIELD (word, 20, 20);
+ val <<= 11;
+ val |= GET_FIELD (word, 9, 19);
+ val <<= 2;
+ val |= GET_FIELD (word, 5, 6);
+ val <<= 5;
+ val |= GET_FIELD (word, 0, 4);
+ val <<= 2;
+ val |= GET_FIELD (word, 7, 8);
+ return sign_extend (val, 21) << 11;
+}
+
+/* deposit a 21 bit constant in a word. Although 21 bit constants are
+ usually the top 21 bits of a 32 bit constant, we assume that only
+ the low 21 bits of opnd are relevant */
+
+static unsigned
+deposit_21 (unsigned opnd, unsigned word)
+{
+ unsigned val = 0;
+
+ val |= GET_FIELD (opnd, 11 + 14, 11 + 18);
+ val <<= 2;
+ val |= GET_FIELD (opnd, 11 + 12, 11 + 13);
+ val <<= 2;
+ val |= GET_FIELD (opnd, 11 + 19, 11 + 20);
+ val <<= 11;
+ val |= GET_FIELD (opnd, 11 + 1, 11 + 11);
+ val <<= 1;
+ val |= GET_FIELD (opnd, 11 + 0, 11 + 0);
+ return word | val;
+}
+
+/* extract a 17 bit constant from branch instructions, returning the
+ 19 bit signed value. */
+
+static int
+extract_17 (unsigned word)
+{
+ return sign_extend (GET_FIELD (word, 19, 28) |
+ GET_FIELD (word, 29, 29) << 10 |
+ GET_FIELD (word, 11, 15) << 11 |
+ (word & 0x1) << 16, 17) << 2;
+}
+
+
+/* Compare the start address for two unwind entries returning 1 if
+ the first address is larger than the second, -1 if the second is
+ larger than the first, and zero if they are equal. */
+
+static int
+compare_unwind_entries (const void *arg1, const void *arg2)
+{
+ const struct unwind_table_entry *a = arg1;
+ const struct unwind_table_entry *b = arg2;
+
+ if (a->region_start > b->region_start)
+ return 1;
+ else if (a->region_start < b->region_start)
+ return -1;
+ else
+ return 0;
+}
+
+static CORE_ADDR low_text_segment_address;
+
+static void
+record_text_segment_lowaddr (bfd *abfd, asection *section, void *ignored)
+{
+ if ((section->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
+ == (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
+ && section->vma < low_text_segment_address)
+ low_text_segment_address = section->vma;
+}
+
+static void
+internalize_unwinds (struct objfile *objfile, struct unwind_table_entry *table,
+ asection *section, unsigned int entries, unsigned int size,
+ CORE_ADDR text_offset)
+{
+ /* We will read the unwind entries into temporary memory, then
+ fill in the actual unwind table. */
+ if (size > 0)
+ {
+ unsigned long tmp;
+ unsigned i;
+ char *buf = alloca (size);
+
+ low_text_segment_address = -1;
+
+ /* If addresses are 64 bits wide, then unwinds are supposed to
+ be segment relative offsets instead of absolute addresses.
+
+ Note that when loading a shared library (text_offset != 0) the
+ unwinds are already relative to the text_offset that will be
+ passed in. */
+ if (TARGET_PTR_BIT == 64 && text_offset == 0)
+ {
+ bfd_map_over_sections (objfile->obfd,
+ record_text_segment_lowaddr, (PTR) NULL);
+
+ /* ?!? Mask off some low bits. Should this instead subtract
+ out the lowest section's filepos or something like that?
+ This looks very hokey to me. */
+ low_text_segment_address &= ~0xfff;
+ text_offset += low_text_segment_address;
+ }
+
+ bfd_get_section_contents (objfile->obfd, section, buf, 0, size);
+
+ /* Now internalize the information being careful to handle host/target
+ endian issues. */
+ for (i = 0; i < entries; i++)
+ {
+ table[i].region_start = bfd_get_32 (objfile->obfd,
+ (bfd_byte *) buf);
+ table[i].region_start += text_offset;
+ buf += 4;
+ table[i].region_end = bfd_get_32 (objfile->obfd, (bfd_byte *) buf);
+ table[i].region_end += text_offset;
+ buf += 4;
+ tmp = bfd_get_32 (objfile->obfd, (bfd_byte *) buf);
+ buf += 4;
+ table[i].Cannot_unwind = (tmp >> 31) & 0x1;
+ table[i].Millicode = (tmp >> 30) & 0x1;
+ table[i].Millicode_save_sr0 = (tmp >> 29) & 0x1;
+ table[i].Region_description = (tmp >> 27) & 0x3;
+ table[i].reserved1 = (tmp >> 26) & 0x1;
+ table[i].Entry_SR = (tmp >> 25) & 0x1;
+ table[i].Entry_FR = (tmp >> 21) & 0xf;
+ table[i].Entry_GR = (tmp >> 16) & 0x1f;
+ table[i].Args_stored = (tmp >> 15) & 0x1;
+ table[i].Variable_Frame = (tmp >> 14) & 0x1;
+ table[i].Separate_Package_Body = (tmp >> 13) & 0x1;
+ table[i].Frame_Extension_Millicode = (tmp >> 12) & 0x1;
+ table[i].Stack_Overflow_Check = (tmp >> 11) & 0x1;
+ table[i].Two_Instruction_SP_Increment = (tmp >> 10) & 0x1;
+ table[i].Ada_Region = (tmp >> 9) & 0x1;
+ table[i].cxx_info = (tmp >> 8) & 0x1;
+ table[i].cxx_try_catch = (tmp >> 7) & 0x1;
+ table[i].sched_entry_seq = (tmp >> 6) & 0x1;
+ table[i].reserved2 = (tmp >> 5) & 0x1;
+ table[i].Save_SP = (tmp >> 4) & 0x1;
+ table[i].Save_RP = (tmp >> 3) & 0x1;
+ table[i].Save_MRP_in_frame = (tmp >> 2) & 0x1;
+ table[i].extn_ptr_defined = (tmp >> 1) & 0x1;
+ table[i].Cleanup_defined = tmp & 0x1;
+ tmp = bfd_get_32 (objfile->obfd, (bfd_byte *) buf);
+ buf += 4;
+ table[i].MPE_XL_interrupt_marker = (tmp >> 31) & 0x1;
+ table[i].HP_UX_interrupt_marker = (tmp >> 30) & 0x1;
+ table[i].Large_frame = (tmp >> 29) & 0x1;
+ table[i].Pseudo_SP_Set = (tmp >> 28) & 0x1;
+ table[i].reserved4 = (tmp >> 27) & 0x1;
+ table[i].Total_frame_size = tmp & 0x7ffffff;
+
+ /* Stub unwinds are handled elsewhere. */
+ table[i].stub_unwind.stub_type = 0;
+ table[i].stub_unwind.padding = 0;
+ }
+ }
+}
+
+/* Read in the backtrace information stored in the `$UNWIND_START$' section of
+ the object file. This info is used mainly by find_unwind_entry() to find
+ out the stack frame size and frame pointer used by procedures. We put
+ everything on the psymbol obstack in the objfile so that it automatically
+ gets freed when the objfile is destroyed. */
+
+static void
+read_unwind_info (struct objfile *objfile)
+{
+ asection *unwind_sec, *stub_unwind_sec;
+ unsigned unwind_size, stub_unwind_size, total_size;
+ unsigned index, unwind_entries;
+ unsigned stub_entries, total_entries;
+ CORE_ADDR text_offset;
+ struct obj_unwind_info *ui;
+ obj_private_data_t *obj_private;
+
+ text_offset = ANOFFSET (objfile->section_offsets, 0);
+ ui = (struct obj_unwind_info *) obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct obj_unwind_info));
+
+ ui->table = NULL;
+ ui->cache = NULL;
+ ui->last = -1;
+
+ /* For reasons unknown the HP PA64 tools generate multiple unwinder
+ sections in a single executable. So we just iterate over every
+ section in the BFD looking for unwinder sections intead of trying
+ to do a lookup with bfd_get_section_by_name.
+
+ First determine the total size of the unwind tables so that we
+ can allocate memory in a nice big hunk. */
+ total_entries = 0;
+ for (unwind_sec = objfile->obfd->sections;
+ unwind_sec;
+ unwind_sec = unwind_sec->next)
+ {
+ if (strcmp (unwind_sec->name, "$UNWIND_START$") == 0
+ || strcmp (unwind_sec->name, ".PARISC.unwind") == 0)
+ {
+ unwind_size = bfd_section_size (objfile->obfd, unwind_sec);
+ unwind_entries = unwind_size / UNWIND_ENTRY_SIZE;
+
+ total_entries += unwind_entries;
+ }
+ }
+
+ /* Now compute the size of the stub unwinds. Note the ELF tools do not
+ use stub unwinds at the curren time. */
+ stub_unwind_sec = bfd_get_section_by_name (objfile->obfd, "$UNWIND_END$");
+
+ if (stub_unwind_sec)
+ {
+ stub_unwind_size = bfd_section_size (objfile->obfd, stub_unwind_sec);
+ stub_entries = stub_unwind_size / STUB_UNWIND_ENTRY_SIZE;
+ }
+ else
+ {
+ stub_unwind_size = 0;
+ stub_entries = 0;
+ }
+
+ /* Compute total number of unwind entries and their total size. */
+ total_entries += stub_entries;
+ total_size = total_entries * sizeof (struct unwind_table_entry);
+
+ /* Allocate memory for the unwind table. */
+ ui->table = (struct unwind_table_entry *)
+ obstack_alloc (&objfile->psymbol_obstack, total_size);
+ ui->last = total_entries - 1;
+
+ /* Now read in each unwind section and internalize the standard unwind
+ entries. */
+ index = 0;
+ for (unwind_sec = objfile->obfd->sections;
+ unwind_sec;
+ unwind_sec = unwind_sec->next)
+ {
+ if (strcmp (unwind_sec->name, "$UNWIND_START$") == 0
+ || strcmp (unwind_sec->name, ".PARISC.unwind") == 0)
+ {
+ unwind_size = bfd_section_size (objfile->obfd, unwind_sec);
+ unwind_entries = unwind_size / UNWIND_ENTRY_SIZE;
+
+ internalize_unwinds (objfile, &ui->table[index], unwind_sec,
+ unwind_entries, unwind_size, text_offset);
+ index += unwind_entries;
+ }
+ }
+
+ /* Now read in and internalize the stub unwind entries. */
+ if (stub_unwind_size > 0)
+ {
+ unsigned int i;
+ char *buf = alloca (stub_unwind_size);
+
+ /* Read in the stub unwind entries. */
+ bfd_get_section_contents (objfile->obfd, stub_unwind_sec, buf,
+ 0, stub_unwind_size);
+
+ /* Now convert them into regular unwind entries. */
+ for (i = 0; i < stub_entries; i++, index++)
+ {
+ /* Clear out the next unwind entry. */
+ memset (&ui->table[index], 0, sizeof (struct unwind_table_entry));
+
+ /* Convert offset & size into region_start and region_end.
+ Stuff away the stub type into "reserved" fields. */
+ ui->table[index].region_start = bfd_get_32 (objfile->obfd,
+ (bfd_byte *) buf);
+ ui->table[index].region_start += text_offset;
+ buf += 4;
+ ui->table[index].stub_unwind.stub_type = bfd_get_8 (objfile->obfd,
+ (bfd_byte *) buf);
+ buf += 2;
+ ui->table[index].region_end
+ = ui->table[index].region_start + 4 *
+ (bfd_get_16 (objfile->obfd, (bfd_byte *) buf) - 1);
+ buf += 2;
+ }
+
+ }
+
+ /* Unwind table needs to be kept sorted. */
+ qsort (ui->table, total_entries, sizeof (struct unwind_table_entry),
+ compare_unwind_entries);
+
+ /* Keep a pointer to the unwind information. */
+ if (objfile->obj_private == NULL)
+ {
+ obj_private = (obj_private_data_t *)
+ obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (obj_private_data_t));
+ obj_private->unwind_info = NULL;
+ obj_private->so_info = NULL;
+ obj_private->dp = 0;
+
+ objfile->obj_private = (PTR) obj_private;
+ }
+ obj_private = (obj_private_data_t *) objfile->obj_private;
+ obj_private->unwind_info = ui;
+}
+
+/* Lookup the unwind (stack backtrace) info for the given PC. We search all
+ of the objfiles seeking the unwind table entry for this PC. Each objfile
+ contains a sorted list of struct unwind_table_entry. Since we do a binary
+ search of the unwind tables, we depend upon them to be sorted. */
+
+struct unwind_table_entry *
+find_unwind_entry (CORE_ADDR pc)
+{
+ int first, middle, last;
+ struct objfile *objfile;
+
+ /* A function at address 0? Not in HP-UX! */
+ if (pc == (CORE_ADDR) 0)
+ return NULL;
+
+ ALL_OBJFILES (objfile)
+ {
+ struct obj_unwind_info *ui;
+ ui = NULL;
+ if (objfile->obj_private)
+ ui = ((obj_private_data_t *) (objfile->obj_private))->unwind_info;
+
+ if (!ui)
+ {
+ read_unwind_info (objfile);
+ if (objfile->obj_private == NULL)
+ error ("Internal error reading unwind information.");
+ ui = ((obj_private_data_t *) (objfile->obj_private))->unwind_info;
+ }
+
+ /* First, check the cache */
+
+ if (ui->cache
+ && pc >= ui->cache->region_start
+ && pc <= ui->cache->region_end)
+ return ui->cache;
+
+ /* Not in the cache, do a binary search */
+
+ first = 0;
+ last = ui->last;
+
+ while (first <= last)
+ {
+ middle = (first + last) / 2;
+ if (pc >= ui->table[middle].region_start
+ && pc <= ui->table[middle].region_end)
+ {
+ ui->cache = &ui->table[middle];
+ return &ui->table[middle];
+ }
+
+ if (pc < ui->table[middle].region_start)
+ last = middle - 1;
+ else
+ first = middle + 1;
+ }
+ } /* ALL_OBJFILES() */
+ return NULL;
+}
+
+/* Return the adjustment necessary to make for addresses on the stack
+ as presented by hpread.c.
+
+ This is necessary because of the stack direction on the PA and the
+ bizarre way in which someone (?) decided they wanted to handle
+ frame pointerless code in GDB. */
+int
+hpread_adjust_stack_address (CORE_ADDR func_addr)
+{
+ struct unwind_table_entry *u;
+
+ u = find_unwind_entry (func_addr);
+ if (!u)
+ return 0;
+ else
+ return u->Total_frame_size << 3;
+}
+
+/* Called to determine if PC is in an interrupt handler of some
+ kind. */
+
+static int
+pc_in_interrupt_handler (CORE_ADDR pc)
+{
+ struct unwind_table_entry *u;
+ struct minimal_symbol *msym_us;
+
+ u = find_unwind_entry (pc);
+ if (!u)
+ return 0;
+
+ /* Oh joys. HPUX sets the interrupt bit for _sigreturn even though
+ its frame isn't a pure interrupt frame. Deal with this. */
+ msym_us = lookup_minimal_symbol_by_pc (pc);
+
+ return (u->HP_UX_interrupt_marker
+ && !PC_IN_SIGTRAMP (pc, SYMBOL_NAME (msym_us)));
+}
+
+/* Called when no unwind descriptor was found for PC. Returns 1 if it
+ appears that PC is in a linker stub.
+
+ ?!? Need to handle stubs which appear in PA64 code. */
+
+static int
+pc_in_linker_stub (CORE_ADDR pc)
+{
+ int found_magic_instruction = 0;
+ int i;
+ char buf[4];
+
+ /* If unable to read memory, assume pc is not in a linker stub. */
+ if (target_read_memory (pc, buf, 4) != 0)
+ return 0;
+
+ /* We are looking for something like
+
+ ; $$dyncall jams RP into this special spot in the frame (RP')
+ ; before calling the "call stub"
+ ldw -18(sp),rp
+
+ ldsid (rp),r1 ; Get space associated with RP into r1
+ mtsp r1,sp ; Move it into space register 0
+ be,n 0(sr0),rp) ; back to your regularly scheduled program */
+
+ /* Maximum known linker stub size is 4 instructions. Search forward
+ from the given PC, then backward. */
+ for (i = 0; i < 4; i++)
+ {
+ /* If we hit something with an unwind, stop searching this direction. */
+
+ if (find_unwind_entry (pc + i * 4) != 0)
+ break;
+
+ /* Check for ldsid (rp),r1 which is the magic instruction for a
+ return from a cross-space function call. */
+ if (read_memory_integer (pc + i * 4, 4) == 0x004010a1)
+ {
+ found_magic_instruction = 1;
+ break;
+ }
+ /* Add code to handle long call/branch and argument relocation stubs
+ here. */
+ }
+
+ if (found_magic_instruction != 0)
+ return 1;
+
+ /* Now look backward. */
+ for (i = 0; i < 4; i++)
+ {
+ /* If we hit something with an unwind, stop searching this direction. */
+
+ if (find_unwind_entry (pc - i * 4) != 0)
+ break;
+
+ /* Check for ldsid (rp),r1 which is the magic instruction for a
+ return from a cross-space function call. */
+ if (read_memory_integer (pc - i * 4, 4) == 0x004010a1)
+ {
+ found_magic_instruction = 1;
+ break;
+ }
+ /* Add code to handle long call/branch and argument relocation stubs
+ here. */
+ }
+ return found_magic_instruction;
+}
+
+static int
+find_return_regnum (CORE_ADDR pc)
+{
+ struct unwind_table_entry *u;
+
+ u = find_unwind_entry (pc);
+
+ if (!u)
+ return RP_REGNUM;
+
+ if (u->Millicode)
+ return 31;
+
+ return RP_REGNUM;
+}
+
+/* Return size of frame, or -1 if we should use a frame pointer. */
+static int
+find_proc_framesize (CORE_ADDR pc)
+{
+ struct unwind_table_entry *u;
+ struct minimal_symbol *msym_us;
+
+ /* This may indicate a bug in our callers... */
+ if (pc == (CORE_ADDR) 0)
+ return -1;
+
+ u = find_unwind_entry (pc);
+
+ if (!u)
+ {
+ if (pc_in_linker_stub (pc))
+ /* Linker stubs have a zero size frame. */
+ return 0;
+ else
+ return -1;
+ }
+
+ msym_us = lookup_minimal_symbol_by_pc (pc);
+
+ /* If Save_SP is set, and we're not in an interrupt or signal caller,
+ then we have a frame pointer. Use it. */
+ if (u->Save_SP
+ && !pc_in_interrupt_handler (pc)
+ && msym_us
+ && !PC_IN_SIGTRAMP (pc, SYMBOL_NAME (msym_us)))
+ return -1;
+
+ return u->Total_frame_size << 3;
+}
+
+/* Return offset from sp at which rp is saved, or 0 if not saved. */
+static int rp_saved (CORE_ADDR);
+
+static int
+rp_saved (CORE_ADDR pc)
+{
+ struct unwind_table_entry *u;
+
+ /* A function at, and thus a return PC from, address 0? Not in HP-UX! */
+ if (pc == (CORE_ADDR) 0)
+ return 0;
+
+ u = find_unwind_entry (pc);
+
+ if (!u)
+ {
+ if (pc_in_linker_stub (pc))
+ /* This is the so-called RP'. */
+ return -24;
+ else
+ return 0;
+ }
+
+ if (u->Save_RP)
+ return (TARGET_PTR_BIT == 64 ? -16 : -20);
+ else if (u->stub_unwind.stub_type != 0)
+ {
+ switch (u->stub_unwind.stub_type)
+ {
+ case EXPORT:
+ case IMPORT:
+ return -24;
+ case PARAMETER_RELOCATION:
+ return -8;
+ default:
+ return 0;
+ }
+ }
+ else
+ return 0;
+}
+
+int
+frameless_function_invocation (struct frame_info *frame)
+{
+ struct unwind_table_entry *u;
+
+ u = find_unwind_entry (frame->pc);
+
+ if (u == 0)
+ return 0;
+
+ return (u->Total_frame_size == 0 && u->stub_unwind.stub_type == 0);
+}
+
+CORE_ADDR
+saved_pc_after_call (struct frame_info *frame)
+{
+ int ret_regnum;
+ CORE_ADDR pc;
+ struct unwind_table_entry *u;
+
+ ret_regnum = find_return_regnum (get_frame_pc (frame));
+ pc = read_register (ret_regnum) & ~0x3;
+
+ /* If PC is in a linker stub, then we need to dig the address
+ the stub will return to out of the stack. */
+ u = find_unwind_entry (pc);
+ if (u && u->stub_unwind.stub_type != 0)
+ return FRAME_SAVED_PC (frame);
+ else
+ return pc;
+}
+
+CORE_ADDR
+hppa_frame_saved_pc (struct frame_info *frame)
+{
+ CORE_ADDR pc = get_frame_pc (frame);
+ struct unwind_table_entry *u;
+ CORE_ADDR old_pc;
+ int spun_around_loop = 0;
+ int rp_offset = 0;
+
+ /* BSD, HPUX & OSF1 all lay out the hardware state in the same manner
+ at the base of the frame in an interrupt handler. Registers within
+ are saved in the exact same order as GDB numbers registers. How
+ convienent. */
+ if (pc_in_interrupt_handler (pc))
+ return read_memory_integer (frame->frame + PC_REGNUM * 4,
+ TARGET_PTR_BIT / 8) & ~0x3;
+
+ if ((frame->pc >= frame->frame
+ && frame->pc <= (frame->frame
+ /* A call dummy is sized in words, but it is
+ actually a series of instructions. Account
+ for that scaling factor. */
+ + ((REGISTER_SIZE / INSTRUCTION_SIZE)
+ * CALL_DUMMY_LENGTH)
+ /* Similarly we have to account for 64bit
+ wide register saves. */
+ + (32 * REGISTER_SIZE)
+ /* We always consider FP regs 8 bytes long. */
+ + (NUM_REGS - FP0_REGNUM) * 8
+ /* Similarly we have to account for 64bit
+ wide register saves. */
+ + (6 * REGISTER_SIZE))))
+ {
+ return read_memory_integer ((frame->frame
+ + (TARGET_PTR_BIT == 64 ? -16 : -20)),
+ TARGET_PTR_BIT / 8) & ~0x3;
+ }
+
+#ifdef FRAME_SAVED_PC_IN_SIGTRAMP
+ /* Deal with signal handler caller frames too. */
+ if (frame->signal_handler_caller)
+ {
+ CORE_ADDR rp;
+ FRAME_SAVED_PC_IN_SIGTRAMP (frame, &rp);
+ return rp & ~0x3;
+ }
+#endif
+
+ if (frameless_function_invocation (frame))
+ {
+ int ret_regnum;
+
+ ret_regnum = find_return_regnum (pc);
+
+ /* If the next frame is an interrupt frame or a signal
+ handler caller, then we need to look in the saved
+ register area to get the return pointer (the values
+ in the registers may not correspond to anything useful). */
+ if (frame->next
+ && (frame->next->signal_handler_caller
+ || pc_in_interrupt_handler (frame->next->pc)))
+ {
+ struct frame_saved_regs saved_regs;
+
+ get_frame_saved_regs (frame->next, &saved_regs);
+ if (read_memory_integer (saved_regs.regs[FLAGS_REGNUM],
+ TARGET_PTR_BIT / 8) & 0x2)
+ {
+ pc = read_memory_integer (saved_regs.regs[31],
+ TARGET_PTR_BIT / 8) & ~0x3;
+
+ /* Syscalls are really two frames. The syscall stub itself
+ with a return pointer in %rp and the kernel call with
+ a return pointer in %r31. We return the %rp variant
+ if %r31 is the same as frame->pc. */
+ if (pc == frame->pc)
+ pc = read_memory_integer (saved_regs.regs[RP_REGNUM],
+ TARGET_PTR_BIT / 8) & ~0x3;
+ }
+ else
+ pc = read_memory_integer (saved_regs.regs[RP_REGNUM],
+ TARGET_PTR_BIT / 8) & ~0x3;
+ }
+ else
+ pc = read_register (ret_regnum) & ~0x3;
+ }
+ else
+ {
+ spun_around_loop = 0;
+ old_pc = pc;
+
+ restart:
+ rp_offset = rp_saved (pc);
+
+ /* Similar to code in frameless function case. If the next
+ frame is a signal or interrupt handler, then dig the right
+ information out of the saved register info. */
+ if (rp_offset == 0
+ && frame->next
+ && (frame->next->signal_handler_caller
+ || pc_in_interrupt_handler (frame->next->pc)))
+ {
+ struct frame_saved_regs saved_regs;
+
+ get_frame_saved_regs (frame->next, &saved_regs);
+ if (read_memory_integer (saved_regs.regs[FLAGS_REGNUM],
+ TARGET_PTR_BIT / 8) & 0x2)
+ {
+ pc = read_memory_integer (saved_regs.regs[31],
+ TARGET_PTR_BIT / 8) & ~0x3;
+
+ /* Syscalls are really two frames. The syscall stub itself
+ with a return pointer in %rp and the kernel call with
+ a return pointer in %r31. We return the %rp variant
+ if %r31 is the same as frame->pc. */
+ if (pc == frame->pc)
+ pc = read_memory_integer (saved_regs.regs[RP_REGNUM],
+ TARGET_PTR_BIT / 8) & ~0x3;
+ }
+ else
+ pc = read_memory_integer (saved_regs.regs[RP_REGNUM],
+ TARGET_PTR_BIT / 8) & ~0x3;
+ }
+ else if (rp_offset == 0)
+ {
+ old_pc = pc;
+ pc = read_register (RP_REGNUM) & ~0x3;
+ }
+ else
+ {
+ old_pc = pc;
+ pc = read_memory_integer (frame->frame + rp_offset,
+ TARGET_PTR_BIT / 8) & ~0x3;
+ }
+ }
+
+ /* If PC is inside a linker stub, then dig out the address the stub
+ will return to.
+
+ Don't do this for long branch stubs. Why? For some unknown reason
+ _start is marked as a long branch stub in hpux10. */
+ u = find_unwind_entry (pc);
+ if (u && u->stub_unwind.stub_type != 0
+ && u->stub_unwind.stub_type != LONG_BRANCH)
+ {
+ unsigned int insn;
+
+ /* If this is a dynamic executable, and we're in a signal handler,
+ then the call chain will eventually point us into the stub for
+ _sigreturn. Unlike most cases, we'll be pointed to the branch
+ to the real sigreturn rather than the code after the real branch!.
+
+ Else, try to dig the address the stub will return to in the normal
+ fashion. */
+ insn = read_memory_integer (pc, 4);
+ if ((insn & 0xfc00e000) == 0xe8000000)
+ return (pc + extract_17 (insn) + 8) & ~0x3;
+ else
+ {
+ if (old_pc == pc)
+ spun_around_loop++;
+
+ if (spun_around_loop > 1)
+ {
+ /* We're just about to go around the loop again with
+ no more hope of success. Die. */
+ error ("Unable to find return pc for this frame");
+ }
+ else
+ goto restart;
+ }
+ }
+
+ return pc;
+}
+
+/* We need to correct the PC and the FP for the outermost frame when we are
+ in a system call. */
+
+void
+init_extra_frame_info (int fromleaf, struct frame_info *frame)
+{
+ int flags;
+ int framesize;
+
+ if (frame->next && !fromleaf)
+ return;
+
+ /* If the next frame represents a frameless function invocation
+ then we have to do some adjustments that are normally done by
+ FRAME_CHAIN. (FRAME_CHAIN is not called in this case.) */
+ if (fromleaf)
+ {
+ /* Find the framesize of *this* frame without peeking at the PC
+ in the current frame structure (it isn't set yet). */
+ framesize = find_proc_framesize (FRAME_SAVED_PC (get_next_frame (frame)));
+
+ /* Now adjust our base frame accordingly. If we have a frame pointer
+ use it, else subtract the size of this frame from the current
+ frame. (we always want frame->frame to point at the lowest address
+ in the frame). */
+ if (framesize == -1)
+ frame->frame = TARGET_READ_FP ();
+ else
+ frame->frame -= framesize;
+ return;
+ }
+
+ flags = read_register (FLAGS_REGNUM);
+ if (flags & 2) /* In system call? */
+ frame->pc = read_register (31) & ~0x3;
+
+ /* The outermost frame is always derived from PC-framesize
+
+ One might think frameless innermost frames should have
+ a frame->frame that is the same as the parent's frame->frame.
+ That is wrong; frame->frame in that case should be the *high*
+ address of the parent's frame. It's complicated as hell to
+ explain, but the parent *always* creates some stack space for
+ the child. So the child actually does have a frame of some
+ sorts, and its base is the high address in its parent's frame. */
+ framesize = find_proc_framesize (frame->pc);
+ if (framesize == -1)
+ frame->frame = TARGET_READ_FP ();
+ else
+ frame->frame = read_register (SP_REGNUM) - framesize;
+}
+
+/* Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+
+ This may involve searching through prologues for several functions
+ at boundaries where GCC calls HP C code, or where code which has
+ a frame pointer calls code without a frame pointer. */
+
+CORE_ADDR
+frame_chain (struct frame_info *frame)
+{
+ int my_framesize, caller_framesize;
+ struct unwind_table_entry *u;
+ CORE_ADDR frame_base;
+ struct frame_info *tmp_frame;
+
+ /* A frame in the current frame list, or zero. */
+ struct frame_info *saved_regs_frame = 0;
+ /* Where the registers were saved in saved_regs_frame.
+ If saved_regs_frame is zero, this is garbage. */
+ struct frame_saved_regs saved_regs;
+
+ CORE_ADDR caller_pc;
+
+ struct minimal_symbol *min_frame_symbol;
+ struct symbol *frame_symbol;
+ char *frame_symbol_name;
+
+ /* If this is a threaded application, and we see the
+ routine "__pthread_exit", treat it as the stack root
+ for this thread. */
+ min_frame_symbol = lookup_minimal_symbol_by_pc (frame->pc);
+ frame_symbol = find_pc_function (frame->pc);
+
+ if ((min_frame_symbol != 0) /* && (frame_symbol == 0) */ )
+ {
+ /* The test above for "no user function name" would defend
+ against the slim likelihood that a user might define a
+ routine named "__pthread_exit" and then try to debug it.
+
+ If it weren't commented out, and you tried to debug the
+ pthread library itself, you'd get errors.
+
+ So for today, we don't make that check. */
+ frame_symbol_name = SYMBOL_NAME (min_frame_symbol);
+ if (frame_symbol_name != 0)
+ {
+ if (0 == strncmp (frame_symbol_name,
+ THREAD_INITIAL_FRAME_SYMBOL,
+ THREAD_INITIAL_FRAME_SYM_LEN))
+ {
+ /* Pretend we've reached the bottom of the stack. */
+ return (CORE_ADDR) 0;
+ }
+ }
+ } /* End of hacky code for threads. */
+
+ /* Handle HPUX, BSD, and OSF1 style interrupt frames first. These
+ are easy; at *sp we have a full save state strucutre which we can
+ pull the old stack pointer from. Also see frame_saved_pc for
+ code to dig a saved PC out of the save state structure. */
+ if (pc_in_interrupt_handler (frame->pc))
+ frame_base = read_memory_integer (frame->frame + SP_REGNUM * 4,
+ TARGET_PTR_BIT / 8);
+#ifdef FRAME_BASE_BEFORE_SIGTRAMP
+ else if (frame->signal_handler_caller)
+ {
+ FRAME_BASE_BEFORE_SIGTRAMP (frame, &frame_base);
+ }
+#endif
+ else
+ frame_base = frame->frame;
+
+ /* Get frame sizes for the current frame and the frame of the
+ caller. */
+ my_framesize = find_proc_framesize (frame->pc);
+ caller_pc = FRAME_SAVED_PC (frame);
+
+ /* If we can't determine the caller's PC, then it's not likely we can
+ really determine anything meaningful about its frame. We'll consider
+ this to be stack bottom. */
+ if (caller_pc == (CORE_ADDR) 0)
+ return (CORE_ADDR) 0;
+
+ caller_framesize = find_proc_framesize (FRAME_SAVED_PC (frame));
+
+ /* If caller does not have a frame pointer, then its frame
+ can be found at current_frame - caller_framesize. */
+ if (caller_framesize != -1)
+ {
+ return frame_base - caller_framesize;
+ }
+ /* Both caller and callee have frame pointers and are GCC compiled
+ (SAVE_SP bit in unwind descriptor is on for both functions.
+ The previous frame pointer is found at the top of the current frame. */
+ if (caller_framesize == -1 && my_framesize == -1)
+ {
+ return read_memory_integer (frame_base, TARGET_PTR_BIT / 8);
+ }
+ /* Caller has a frame pointer, but callee does not. This is a little
+ more difficult as GCC and HP C lay out locals and callee register save
+ areas very differently.
+
+ The previous frame pointer could be in a register, or in one of
+ several areas on the stack.
+
+ Walk from the current frame to the innermost frame examining
+ unwind descriptors to determine if %r3 ever gets saved into the
+ stack. If so return whatever value got saved into the stack.
+ If it was never saved in the stack, then the value in %r3 is still
+ valid, so use it.
+
+ We use information from unwind descriptors to determine if %r3
+ is saved into the stack (Entry_GR field has this information). */
+
+ for (tmp_frame = frame; tmp_frame; tmp_frame = tmp_frame->next)
+ {
+ u = find_unwind_entry (tmp_frame->pc);
+
+ if (!u)
+ {
+ /* We could find this information by examining prologues. I don't
+ think anyone has actually written any tools (not even "strip")
+ which leave them out of an executable, so maybe this is a moot
+ point. */
+ /* ??rehrauer: Actually, it's quite possible to stepi your way into
+ code that doesn't have unwind entries. For example, stepping into
+ the dynamic linker will give you a PC that has none. Thus, I've
+ disabled this warning. */
+#if 0
+ warning ("Unable to find unwind for PC 0x%x -- Help!", tmp_frame->pc);
+#endif
+ return (CORE_ADDR) 0;
+ }
+
+ if (u->Save_SP
+ || tmp_frame->signal_handler_caller
+ || pc_in_interrupt_handler (tmp_frame->pc))
+ break;
+
+ /* Entry_GR specifies the number of callee-saved general registers
+ saved in the stack. It starts at %r3, so %r3 would be 1. */
+ if (u->Entry_GR >= 1)
+ {
+ /* The unwind entry claims that r3 is saved here. However,
+ in optimized code, GCC often doesn't actually save r3.
+ We'll discover this if we look at the prologue. */
+ get_frame_saved_regs (tmp_frame, &saved_regs);
+ saved_regs_frame = tmp_frame;
+
+ /* If we have an address for r3, that's good. */
+ if (saved_regs.regs[FP_REGNUM])
+ break;
+ }
+ }
+
+ if (tmp_frame)
+ {
+ /* We may have walked down the chain into a function with a frame
+ pointer. */
+ if (u->Save_SP
+ && !tmp_frame->signal_handler_caller
+ && !pc_in_interrupt_handler (tmp_frame->pc))
+ {
+ return read_memory_integer (tmp_frame->frame, TARGET_PTR_BIT / 8);
+ }
+ /* %r3 was saved somewhere in the stack. Dig it out. */
+ else
+ {
+ /* Sick.
+
+ For optimization purposes many kernels don't have the
+ callee saved registers into the save_state structure upon
+ entry into the kernel for a syscall; the optimization
+ is usually turned off if the process is being traced so
+ that the debugger can get full register state for the
+ process.
+
+ This scheme works well except for two cases:
+
+ * Attaching to a process when the process is in the
+ kernel performing a system call (debugger can't get
+ full register state for the inferior process since
+ the process wasn't being traced when it entered the
+ system call).
+
+ * Register state is not complete if the system call
+ causes the process to core dump.
+
+
+ The following heinous code is an attempt to deal with
+ the lack of register state in a core dump. It will
+ fail miserably if the function which performs the
+ system call has a variable sized stack frame. */
+
+ if (tmp_frame != saved_regs_frame)
+ get_frame_saved_regs (tmp_frame, &saved_regs);
+
+ /* Abominable hack. */
+ if (current_target.to_has_execution == 0
+ && ((saved_regs.regs[FLAGS_REGNUM]
+ && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM],
+ TARGET_PTR_BIT / 8)
+ & 0x2))
+ || (saved_regs.regs[FLAGS_REGNUM] == 0
+ && read_register (FLAGS_REGNUM) & 0x2)))
+ {
+ u = find_unwind_entry (FRAME_SAVED_PC (frame));
+ if (!u)
+ {
+ return read_memory_integer (saved_regs.regs[FP_REGNUM],
+ TARGET_PTR_BIT / 8);
+ }
+ else
+ {
+ return frame_base - (u->Total_frame_size << 3);
+ }
+ }
+
+ return read_memory_integer (saved_regs.regs[FP_REGNUM],
+ TARGET_PTR_BIT / 8);
+ }
+ }
+ else
+ {
+ /* Get the innermost frame. */
+ tmp_frame = frame;
+ while (tmp_frame->next != NULL)
+ tmp_frame = tmp_frame->next;
+
+ if (tmp_frame != saved_regs_frame)
+ get_frame_saved_regs (tmp_frame, &saved_regs);
+
+ /* Abominable hack. See above. */
+ if (current_target.to_has_execution == 0
+ && ((saved_regs.regs[FLAGS_REGNUM]
+ && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM],
+ TARGET_PTR_BIT / 8)
+ & 0x2))
+ || (saved_regs.regs[FLAGS_REGNUM] == 0
+ && read_register (FLAGS_REGNUM) & 0x2)))
+ {
+ u = find_unwind_entry (FRAME_SAVED_PC (frame));
+ if (!u)
+ {
+ return read_memory_integer (saved_regs.regs[FP_REGNUM],
+ TARGET_PTR_BIT / 8);
+ }
+ else
+ {
+ return frame_base - (u->Total_frame_size << 3);
+ }
+ }
+
+ /* The value in %r3 was never saved into the stack (thus %r3 still
+ holds the value of the previous frame pointer). */
+ return TARGET_READ_FP ();
+ }
+}
+
+
+/* To see if a frame chain is valid, see if the caller looks like it
+ was compiled with gcc. */
+
+int
+hppa_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
+{
+ struct minimal_symbol *msym_us;
+ struct minimal_symbol *msym_start;
+ struct unwind_table_entry *u, *next_u = NULL;
+ struct frame_info *next;
+
+ if (!chain)
+ return 0;
+
+ u = find_unwind_entry (thisframe->pc);
+
+ if (u == NULL)
+ return 1;
+
+ /* We can't just check that the same of msym_us is "_start", because
+ someone idiotically decided that they were going to make a Ltext_end
+ symbol with the same address. This Ltext_end symbol is totally
+ indistinguishable (as nearly as I can tell) from the symbol for a function
+ which is (legitimately, since it is in the user's namespace)
+ named Ltext_end, so we can't just ignore it. */
+ msym_us = lookup_minimal_symbol_by_pc (FRAME_SAVED_PC (thisframe));
+ msym_start = lookup_minimal_symbol ("_start", NULL, NULL);
+ if (msym_us
+ && msym_start
+ && SYMBOL_VALUE_ADDRESS (msym_us) == SYMBOL_VALUE_ADDRESS (msym_start))
+ return 0;
+
+ /* Grrrr. Some new idiot decided that they don't want _start for the
+ PRO configurations; $START$ calls main directly.... Deal with it. */
+ msym_start = lookup_minimal_symbol ("$START$", NULL, NULL);
+ if (msym_us
+ && msym_start
+ && SYMBOL_VALUE_ADDRESS (msym_us) == SYMBOL_VALUE_ADDRESS (msym_start))
+ return 0;
+
+ next = get_next_frame (thisframe);
+ if (next)
+ next_u = find_unwind_entry (next->pc);
+
+ /* If this frame does not save SP, has no stack, isn't a stub,
+ and doesn't "call" an interrupt routine or signal handler caller,
+ then its not valid. */
+ if (u->Save_SP || u->Total_frame_size || u->stub_unwind.stub_type != 0
+ || (thisframe->next && thisframe->next->signal_handler_caller)
+ || (next_u && next_u->HP_UX_interrupt_marker))
+ return 1;
+
+ if (pc_in_linker_stub (thisframe->pc))
+ return 1;
+
+ return 0;
+}
+
+/*
+ These functions deal with saving and restoring register state
+ around a function call in the inferior. They keep the stack
+ double-word aligned; eventually, on an hp700, the stack will have
+ to be aligned to a 64-byte boundary. */
+
+void
+push_dummy_frame (struct inferior_status *inf_status)
+{
+ CORE_ADDR sp, pc, pcspace;
+ register int regnum;
+ CORE_ADDR int_buffer;
+ double freg_buffer;
+
+ /* Oh, what a hack. If we're trying to perform an inferior call
+ while the inferior is asleep, we have to make sure to clear
+ the "in system call" bit in the flag register (the call will
+ start after the syscall returns, so we're no longer in the system
+ call!) This state is kept in "inf_status", change it there.
+
+ We also need a number of horrid hacks to deal with lossage in the
+ PC queue registers (apparently they're not valid when the in syscall
+ bit is set). */
+ pc = target_read_pc (inferior_ptid);
+ int_buffer = read_register (FLAGS_REGNUM);
+ if (int_buffer & 0x2)
+ {
+ unsigned int sid;
+ int_buffer &= ~0x2;
+ write_inferior_status_register (inf_status, 0, int_buffer);
+ write_inferior_status_register (inf_status, PCOQ_HEAD_REGNUM, pc + 0);
+ write_inferior_status_register (inf_status, PCOQ_TAIL_REGNUM, pc + 4);
+ sid = (pc >> 30) & 0x3;
+ if (sid == 0)
+ pcspace = read_register (SR4_REGNUM);
+ else
+ pcspace = read_register (SR4_REGNUM + 4 + sid);
+ write_inferior_status_register (inf_status, PCSQ_HEAD_REGNUM, pcspace);
+ write_inferior_status_register (inf_status, PCSQ_TAIL_REGNUM, pcspace);
+ }
+ else
+ pcspace = read_register (PCSQ_HEAD_REGNUM);
+
+ /* Space for "arguments"; the RP goes in here. */
+ sp = read_register (SP_REGNUM) + 48;
+ int_buffer = read_register (RP_REGNUM) | 0x3;
+
+ /* The 32bit and 64bit ABIs save the return pointer into different
+ stack slots. */
+ if (REGISTER_SIZE == 8)
+ write_memory (sp - 16, (char *) &int_buffer, REGISTER_SIZE);
+ else
+ write_memory (sp - 20, (char *) &int_buffer, REGISTER_SIZE);
+
+ int_buffer = TARGET_READ_FP ();
+ write_memory (sp, (char *) &int_buffer, REGISTER_SIZE);
+
+ write_register (FP_REGNUM, sp);
+
+ sp += 2 * REGISTER_SIZE;
+
+ for (regnum = 1; regnum < 32; regnum++)
+ if (regnum != RP_REGNUM && regnum != FP_REGNUM)
+ sp = push_word (sp, read_register (regnum));
+
+ /* This is not necessary for the 64bit ABI. In fact it is dangerous. */
+ if (REGISTER_SIZE != 8)
+ sp += 4;
+
+ for (regnum = FP0_REGNUM; regnum < NUM_REGS; regnum++)
+ {
+ read_register_bytes (REGISTER_BYTE (regnum), (char *) &freg_buffer, 8);
+ sp = push_bytes (sp, (char *) &freg_buffer, 8);
+ }
+ sp = push_word (sp, read_register (IPSW_REGNUM));
+ sp = push_word (sp, read_register (SAR_REGNUM));
+ sp = push_word (sp, pc);
+ sp = push_word (sp, pcspace);
+ sp = push_word (sp, pc + 4);
+ sp = push_word (sp, pcspace);
+ write_register (SP_REGNUM, sp);
+}
+
+static void
+find_dummy_frame_regs (struct frame_info *frame,
+ struct frame_saved_regs *frame_saved_regs)
+{
+ CORE_ADDR fp = frame->frame;
+ int i;
+
+ /* The 32bit and 64bit ABIs save RP into different locations. */
+ if (REGISTER_SIZE == 8)
+ frame_saved_regs->regs[RP_REGNUM] = (fp - 16) & ~0x3;
+ else
+ frame_saved_regs->regs[RP_REGNUM] = (fp - 20) & ~0x3;
+
+ frame_saved_regs->regs[FP_REGNUM] = fp;
+
+ frame_saved_regs->regs[1] = fp + (2 * REGISTER_SIZE);
+
+ for (fp += 3 * REGISTER_SIZE, i = 3; i < 32; i++)
+ {
+ if (i != FP_REGNUM)
+ {
+ frame_saved_regs->regs[i] = fp;
+ fp += REGISTER_SIZE;
+ }
+ }
+
+ /* This is not necessary or desirable for the 64bit ABI. */
+ if (REGISTER_SIZE != 8)
+ fp += 4;
+
+ for (i = FP0_REGNUM; i < NUM_REGS; i++, fp += 8)
+ frame_saved_regs->regs[i] = fp;
+
+ frame_saved_regs->regs[IPSW_REGNUM] = fp;
+ frame_saved_regs->regs[SAR_REGNUM] = fp + REGISTER_SIZE;
+ frame_saved_regs->regs[PCOQ_HEAD_REGNUM] = fp + 2 * REGISTER_SIZE;
+ frame_saved_regs->regs[PCSQ_HEAD_REGNUM] = fp + 3 * REGISTER_SIZE;
+ frame_saved_regs->regs[PCOQ_TAIL_REGNUM] = fp + 4 * REGISTER_SIZE;
+ frame_saved_regs->regs[PCSQ_TAIL_REGNUM] = fp + 5 * REGISTER_SIZE;
+}
+
+void
+hppa_pop_frame (void)
+{
+ register struct frame_info *frame = get_current_frame ();
+ register CORE_ADDR fp, npc, target_pc;
+ register int regnum;
+ struct frame_saved_regs fsr;
+ double freg_buffer;
+
+ fp = FRAME_FP (frame);
+ get_frame_saved_regs (frame, &fsr);
+
+#ifndef NO_PC_SPACE_QUEUE_RESTORE
+ if (fsr.regs[IPSW_REGNUM]) /* Restoring a call dummy frame */
+ restore_pc_queue (&fsr);
+#endif
+
+ for (regnum = 31; regnum > 0; regnum--)
+ if (fsr.regs[regnum])
+ write_register (regnum, read_memory_integer (fsr.regs[regnum],
+ REGISTER_SIZE));
+
+ for (regnum = NUM_REGS - 1; regnum >= FP0_REGNUM; regnum--)
+ if (fsr.regs[regnum])
+ {
+ read_memory (fsr.regs[regnum], (char *) &freg_buffer, 8);
+ write_register_bytes (REGISTER_BYTE (regnum), (char *) &freg_buffer, 8);
+ }
+
+ if (fsr.regs[IPSW_REGNUM])
+ write_register (IPSW_REGNUM,
+ read_memory_integer (fsr.regs[IPSW_REGNUM],
+ REGISTER_SIZE));
+
+ if (fsr.regs[SAR_REGNUM])
+ write_register (SAR_REGNUM,
+ read_memory_integer (fsr.regs[SAR_REGNUM],
+ REGISTER_SIZE));
+
+ /* If the PC was explicitly saved, then just restore it. */
+ if (fsr.regs[PCOQ_TAIL_REGNUM])
+ {
+ npc = read_memory_integer (fsr.regs[PCOQ_TAIL_REGNUM],
+ REGISTER_SIZE);
+ write_register (PCOQ_TAIL_REGNUM, npc);
+ }
+ /* Else use the value in %rp to set the new PC. */
+ else
+ {
+ npc = read_register (RP_REGNUM);
+ write_pc (npc);
+ }
+
+ write_register (FP_REGNUM, read_memory_integer (fp, REGISTER_SIZE));
+
+ if (fsr.regs[IPSW_REGNUM]) /* call dummy */
+ write_register (SP_REGNUM, fp - 48);
+ else
+ write_register (SP_REGNUM, fp);
+
+ /* The PC we just restored may be inside a return trampoline. If so
+ we want to restart the inferior and run it through the trampoline.
+
+ Do this by setting a momentary breakpoint at the location the
+ trampoline returns to.
+
+ Don't skip through the trampoline if we're popping a dummy frame. */
+ target_pc = SKIP_TRAMPOLINE_CODE (npc & ~0x3) & ~0x3;
+ if (target_pc && !fsr.regs[IPSW_REGNUM])
+ {
+ struct symtab_and_line sal;
+ struct breakpoint *breakpoint;
+ struct cleanup *old_chain;
+
+ /* Set up our breakpoint. Set it to be silent as the MI code
+ for "return_command" will print the frame we returned to. */
+ sal = find_pc_line (target_pc, 0);
+ sal.pc = target_pc;
+ breakpoint = set_momentary_breakpoint (sal, NULL, bp_finish);
+ breakpoint->silent = 1;
+
+ /* So we can clean things up. */
+ old_chain = make_cleanup_delete_breakpoint (breakpoint);
+
+ /* Start up the inferior. */
+ clear_proceed_status ();
+ proceed_to_finish = 1;
+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+
+ /* Perform our cleanups. */
+ do_cleanups (old_chain);
+ }
+ flush_cached_frames ();
+}
+
+/* After returning to a dummy on the stack, restore the instruction
+ queue space registers. */
+
+static int
+restore_pc_queue (struct frame_saved_regs *fsr)
+{
+ CORE_ADDR pc = read_pc ();
+ CORE_ADDR new_pc = read_memory_integer (fsr->regs[PCOQ_HEAD_REGNUM],
+ TARGET_PTR_BIT / 8);
+ struct target_waitstatus w;
+ int insn_count;
+
+ /* Advance past break instruction in the call dummy. */
+ write_register (PCOQ_HEAD_REGNUM, pc + 4);
+ write_register (PCOQ_TAIL_REGNUM, pc + 8);
+
+ /* HPUX doesn't let us set the space registers or the space
+ registers of the PC queue through ptrace. Boo, hiss.
+ Conveniently, the call dummy has this sequence of instructions
+ after the break:
+ mtsp r21, sr0
+ ble,n 0(sr0, r22)
+
+ So, load up the registers and single step until we are in the
+ right place. */
+
+ write_register (21, read_memory_integer (fsr->regs[PCSQ_HEAD_REGNUM],
+ REGISTER_SIZE));
+ write_register (22, new_pc);
+
+ for (insn_count = 0; insn_count < 3; insn_count++)
+ {
+ /* FIXME: What if the inferior gets a signal right now? Want to
+ merge this into wait_for_inferior (as a special kind of
+ watchpoint? By setting a breakpoint at the end? Is there
+ any other choice? Is there *any* way to do this stuff with
+ ptrace() or some equivalent?). */
+ resume (1, 0);
+ target_wait (inferior_ptid, &w);
+
+ if (w.kind == TARGET_WAITKIND_SIGNALLED)
+ {
+ stop_signal = w.value.sig;
+ terminal_ours_for_output ();
+ printf_unfiltered ("\nProgram terminated with signal %s, %s.\n",
+ target_signal_to_name (stop_signal),
+ target_signal_to_string (stop_signal));
+ gdb_flush (gdb_stdout);
+ return 0;
+ }
+ }
+ target_terminal_ours ();
+ target_fetch_registers (-1);
+ return 1;
+}
+
+
+#ifdef PA20W_CALLING_CONVENTIONS
+
+/* This function pushes a stack frame with arguments as part of the
+ inferior function calling mechanism.
+
+ This is the version for the PA64, in which later arguments appear
+ at higher addresses. (The stack always grows towards higher
+ addresses.)
+
+ We simply allocate the appropriate amount of stack space and put
+ arguments into their proper slots. The call dummy code will copy
+ arguments into registers as needed by the ABI.
+
+ This ABI also requires that the caller provide an argument pointer
+ to the callee, so we do that too. */
+
+CORE_ADDR
+hppa_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ /* array of arguments' offsets */
+ int *offset = (int *) alloca (nargs * sizeof (int));
+
+ /* array of arguments' lengths: real lengths in bytes, not aligned to
+ word size */
+ int *lengths = (int *) alloca (nargs * sizeof (int));
+
+ /* The value of SP as it was passed into this function after
+ aligning. */
+ CORE_ADDR orig_sp = STACK_ALIGN (sp);
+
+ /* The number of stack bytes occupied by the current argument. */
+ int bytes_reserved;
+
+ /* The total number of bytes reserved for the arguments. */
+ int cum_bytes_reserved = 0;
+
+ /* Similarly, but aligned. */
+ int cum_bytes_aligned = 0;
+ int i;
+
+ /* Iterate over each argument provided by the user. */
+ for (i = 0; i < nargs; i++)
+ {
+ struct type *arg_type = VALUE_TYPE (args[i]);
+
+ /* Integral scalar values smaller than a register are padded on
+ the left. We do this by promoting them to full-width,
+ although the ABI says to pad them with garbage. */
+ if (is_integral_type (arg_type)
+ && TYPE_LENGTH (arg_type) < REGISTER_SIZE)
+ {
+ args[i] = value_cast ((TYPE_UNSIGNED (arg_type)
+ ? builtin_type_unsigned_long
+ : builtin_type_long),
+ args[i]);
+ arg_type = VALUE_TYPE (args[i]);
+ }
+
+ lengths[i] = TYPE_LENGTH (arg_type);
+
+ /* Align the size of the argument to the word size for this
+ target. */
+ bytes_reserved = (lengths[i] + REGISTER_SIZE - 1) & -REGISTER_SIZE;
+
+ offset[i] = cum_bytes_reserved;
+
+ /* Aggregates larger than eight bytes (the only types larger
+ than eight bytes we have) are aligned on a 16-byte boundary,
+ possibly padded on the right with garbage. This may leave an
+ empty word on the stack, and thus an unused register, as per
+ the ABI. */
+ if (bytes_reserved > 8)
+ {
+ /* Round up the offset to a multiple of two slots. */
+ int new_offset = ((offset[i] + 2*REGISTER_SIZE-1)
+ & -(2*REGISTER_SIZE));
+
+ /* Note the space we've wasted, if any. */
+ bytes_reserved += new_offset - offset[i];
+ offset[i] = new_offset;
+ }
+
+ cum_bytes_reserved += bytes_reserved;
+ }
+
+ /* CUM_BYTES_RESERVED already accounts for all the arguments
+ passed by the user. However, the ABIs mandate minimum stack space
+ allocations for outgoing arguments.
+
+ The ABIs also mandate minimum stack alignments which we must
+ preserve. */
+ cum_bytes_aligned = STACK_ALIGN (cum_bytes_reserved);
+ sp += max (cum_bytes_aligned, REG_PARM_STACK_SPACE);
+
+ /* Now write each of the args at the proper offset down the stack. */
+ for (i = 0; i < nargs; i++)
+ write_memory (orig_sp + offset[i], VALUE_CONTENTS (args[i]), lengths[i]);
+
+ /* If a structure has to be returned, set up register 28 to hold its
+ address */
+ if (struct_return)
+ write_register (28, struct_addr);
+
+ /* For the PA64 we must pass a pointer to the outgoing argument list.
+ The ABI mandates that the pointer should point to the first byte of
+ storage beyond the register flushback area.
+
+ However, the call dummy expects the outgoing argument pointer to
+ be passed in register %r4. */
+ write_register (4, orig_sp + REG_PARM_STACK_SPACE);
+
+ /* ?!? This needs further work. We need to set up the global data
+ pointer for this procedure. This assumes the same global pointer
+ for every procedure. The call dummy expects the dp value to
+ be passed in register %r6. */
+ write_register (6, read_register (27));
+
+ /* The stack will have 64 bytes of additional space for a frame marker. */
+ return sp + 64;
+}
+
+#else
+
+/* This function pushes a stack frame with arguments as part of the
+ inferior function calling mechanism.
+
+ This is the version of the function for the 32-bit PA machines, in
+ which later arguments appear at lower addresses. (The stack always
+ grows towards higher addresses.)
+
+ We simply allocate the appropriate amount of stack space and put
+ arguments into their proper slots. The call dummy code will copy
+ arguments into registers as needed by the ABI. */
+
+CORE_ADDR
+hppa_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ /* array of arguments' offsets */
+ int *offset = (int *) alloca (nargs * sizeof (int));
+
+ /* array of arguments' lengths: real lengths in bytes, not aligned to
+ word size */
+ int *lengths = (int *) alloca (nargs * sizeof (int));
+
+ /* The number of stack bytes occupied by the current argument. */
+ int bytes_reserved;
+
+ /* The total number of bytes reserved for the arguments. */
+ int cum_bytes_reserved = 0;
+
+ /* Similarly, but aligned. */
+ int cum_bytes_aligned = 0;
+ int i;
+
+ /* Iterate over each argument provided by the user. */
+ for (i = 0; i < nargs; i++)
+ {
+ lengths[i] = TYPE_LENGTH (VALUE_TYPE (args[i]));
+
+ /* Align the size of the argument to the word size for this
+ target. */
+ bytes_reserved = (lengths[i] + REGISTER_SIZE - 1) & -REGISTER_SIZE;
+
+ offset[i] = (cum_bytes_reserved
+ + (lengths[i] > 4 ? bytes_reserved : lengths[i]));
+
+ /* If the argument is a double word argument, then it needs to be
+ double word aligned. */
+ if ((bytes_reserved == 2 * REGISTER_SIZE)
+ && (offset[i] % 2 * REGISTER_SIZE))
+ {
+ int new_offset = 0;
+ /* BYTES_RESERVED is already aligned to the word, so we put
+ the argument at one word more down the stack.
+
+ This will leave one empty word on the stack, and one unused
+ register as mandated by the ABI. */
+ new_offset = ((offset[i] + 2 * REGISTER_SIZE - 1)
+ & -(2 * REGISTER_SIZE));
+
+ if ((new_offset - offset[i]) >= 2 * REGISTER_SIZE)
+ {
+ bytes_reserved += REGISTER_SIZE;
+ offset[i] += REGISTER_SIZE;
+ }
+ }
+
+ cum_bytes_reserved += bytes_reserved;
+
+ }
+
+ /* CUM_BYTES_RESERVED already accounts for all the arguments passed
+ by the user. However, the ABI mandates minimum stack space
+ allocations for outgoing arguments.
+
+ The ABI also mandates minimum stack alignments which we must
+ preserve. */
+ cum_bytes_aligned = STACK_ALIGN (cum_bytes_reserved);
+ sp += max (cum_bytes_aligned, REG_PARM_STACK_SPACE);
+
+ /* Now write each of the args at the proper offset down the stack.
+ ?!? We need to promote values to a full register instead of skipping
+ words in the stack. */
+ for (i = 0; i < nargs; i++)
+ write_memory (sp - offset[i], VALUE_CONTENTS (args[i]), lengths[i]);
+
+ /* If a structure has to be returned, set up register 28 to hold its
+ address */
+ if (struct_return)
+ write_register (28, struct_addr);
+
+ /* The stack will have 32 bytes of additional space for a frame marker. */
+ return sp + 32;
+}
+
+#endif
+
+/* elz: this function returns a value which is built looking at the given address.
+ It is called from call_function_by_hand, in case we need to return a
+ value which is larger than 64 bits, and it is stored in the stack rather than
+ in the registers r28 and r29 or fr4.
+ This function does the same stuff as value_being_returned in values.c, but
+ gets the value from the stack rather than from the buffer where all the
+ registers were saved when the function called completed. */
+struct value *
+hppa_value_returned_from_stack (register struct type *valtype, CORE_ADDR addr)
+{
+ register struct value *val;
+
+ val = allocate_value (valtype);
+ CHECK_TYPEDEF (valtype);
+ target_read_memory (addr, VALUE_CONTENTS_RAW (val), TYPE_LENGTH (valtype));
+
+ return val;
+}
+
+
+
+/* elz: Used to lookup a symbol in the shared libraries.
+ This function calls shl_findsym, indirectly through a
+ call to __d_shl_get. __d_shl_get is in end.c, which is always
+ linked in by the hp compilers/linkers.
+ The call to shl_findsym cannot be made directly because it needs
+ to be active in target address space.
+ inputs: - minimal symbol pointer for the function we want to look up
+ - address in target space of the descriptor for the library
+ where we want to look the symbol up.
+ This address is retrieved using the
+ som_solib_get_solib_by_pc function (somsolib.c).
+ output: - real address in the library of the function.
+ note: the handle can be null, in which case shl_findsym will look for
+ the symbol in all the loaded shared libraries.
+ files to look at if you need reference on this stuff:
+ dld.c, dld_shl_findsym.c
+ end.c
+ man entry for shl_findsym */
+
+CORE_ADDR
+find_stub_with_shl_get (struct minimal_symbol *function, CORE_ADDR handle)
+{
+ struct symbol *get_sym, *symbol2;
+ struct minimal_symbol *buff_minsym, *msymbol;
+ struct type *ftype;
+ struct value **args;
+ struct value *funcval;
+ struct value *val;
+
+ int x, namelen, err_value, tmp = -1;
+ CORE_ADDR endo_buff_addr, value_return_addr, errno_return_addr;
+ CORE_ADDR stub_addr;
+
+
+ args = alloca (sizeof (struct value *) * 8); /* 6 for the arguments and one null one??? */
+ funcval = find_function_in_inferior ("__d_shl_get");
+ get_sym = lookup_symbol ("__d_shl_get", NULL, VAR_NAMESPACE, NULL, NULL);
+ buff_minsym = lookup_minimal_symbol ("__buffer", NULL, NULL);
+ msymbol = lookup_minimal_symbol ("__shldp", NULL, NULL);
+ symbol2 = lookup_symbol ("__shldp", NULL, VAR_NAMESPACE, NULL, NULL);
+ endo_buff_addr = SYMBOL_VALUE_ADDRESS (buff_minsym);
+ namelen = strlen (SYMBOL_NAME (function));
+ value_return_addr = endo_buff_addr + namelen;
+ ftype = check_typedef (SYMBOL_TYPE (get_sym));
+
+ /* do alignment */
+ if ((x = value_return_addr % 64) != 0)
+ value_return_addr = value_return_addr + 64 - x;
+
+ errno_return_addr = value_return_addr + 64;
+
+
+ /* set up stuff needed by __d_shl_get in buffer in end.o */
+
+ target_write_memory (endo_buff_addr, SYMBOL_NAME (function), namelen);
+
+ target_write_memory (value_return_addr, (char *) &tmp, 4);
+
+ target_write_memory (errno_return_addr, (char *) &tmp, 4);
+
+ target_write_memory (SYMBOL_VALUE_ADDRESS (msymbol),
+ (char *) &handle, 4);
+
+ /* now prepare the arguments for the call */
+
+ args[0] = value_from_longest (TYPE_FIELD_TYPE (ftype, 0), 12);
+ args[1] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 1), SYMBOL_VALUE_ADDRESS (msymbol));
+ args[2] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 2), endo_buff_addr);
+ args[3] = value_from_longest (TYPE_FIELD_TYPE (ftype, 3), TYPE_PROCEDURE);
+ args[4] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 4), value_return_addr);
+ args[5] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 5), errno_return_addr);
+
+ /* now call the function */
+
+ val = call_function_by_hand (funcval, 6, args);
+
+ /* now get the results */
+
+ target_read_memory (errno_return_addr, (char *) &err_value, sizeof (err_value));
+
+ target_read_memory (value_return_addr, (char *) &stub_addr, sizeof (stub_addr));
+ if (stub_addr <= 0)
+ error ("call to __d_shl_get failed, error code is %d", err_value);
+
+ return (stub_addr);
+}
+
+/* Cover routine for find_stub_with_shl_get to pass to catch_errors */
+static int
+cover_find_stub_with_shl_get (PTR args_untyped)
+{
+ args_for_find_stub *args = args_untyped;
+ args->return_val = find_stub_with_shl_get (args->msym, args->solib_handle);
+ return 0;
+}
+
+/* Insert the specified number of args and function address
+ into a call sequence of the above form stored at DUMMYNAME.
+
+ On the hppa we need to call the stack dummy through $$dyncall.
+ Therefore our version of FIX_CALL_DUMMY takes an extra argument,
+ real_pc, which is the location where gdb should start up the
+ inferior to do the function call.
+
+ This has to work across several versions of hpux, bsd, osf1. It has to
+ work regardless of what compiler was used to build the inferior program.
+ It should work regardless of whether or not end.o is available. It has
+ to work even if gdb can not call into the dynamic loader in the inferior
+ to query it for symbol names and addresses.
+
+ Yes, all those cases should work. Luckily code exists to handle most
+ of them. The complexity is in selecting exactly what scheme should
+ be used to perform the inferior call.
+
+ At the current time this routine is known not to handle cases where
+ the program was linked with HP's compiler without including end.o.
+
+ Please contact Jeff Law (law@cygnus.com) before changing this code. */
+
+CORE_ADDR
+hppa_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+ struct value **args, struct type *type, int gcc_p)
+{
+ CORE_ADDR dyncall_addr;
+ struct minimal_symbol *msymbol;
+ struct minimal_symbol *trampoline;
+ int flags = read_register (FLAGS_REGNUM);
+ struct unwind_table_entry *u = NULL;
+ CORE_ADDR new_stub = 0;
+ CORE_ADDR solib_handle = 0;
+
+ /* Nonzero if we will use GCC's PLT call routine. This routine must be
+ passed an import stub, not a PLABEL. It is also necessary to set %r19
+ (the PIC register) before performing the call.
+
+ If zero, then we are using __d_plt_call (HP's PLT call routine) or we
+ are calling the target directly. When using __d_plt_call we want to
+ use a PLABEL instead of an import stub. */
+ int using_gcc_plt_call = 1;
+
+#ifdef GDB_TARGET_IS_HPPA_20W
+ /* We currently use completely different code for the PA2.0W inferior
+ function call sequences. This needs to be cleaned up. */
+ {
+ CORE_ADDR pcsqh, pcsqt, pcoqh, pcoqt, sr5;
+ struct target_waitstatus w;
+ int inst1, inst2;
+ char buf[4];
+ int status;
+ struct objfile *objfile;
+
+ /* We can not modify the PC space queues directly, so we start
+ up the inferior and execute a couple instructions to set the
+ space queues so that they point to the call dummy in the stack. */
+ pcsqh = read_register (PCSQ_HEAD_REGNUM);
+ sr5 = read_register (SR5_REGNUM);
+ if (1)
+ {
+ pcoqh = read_register (PCOQ_HEAD_REGNUM);
+ pcoqt = read_register (PCOQ_TAIL_REGNUM);
+ if (target_read_memory (pcoqh, buf, 4) != 0)
+ error ("Couldn't modify space queue\n");
+ inst1 = extract_unsigned_integer (buf, 4);
+
+ if (target_read_memory (pcoqt, buf, 4) != 0)
+ error ("Couldn't modify space queue\n");
+ inst2 = extract_unsigned_integer (buf, 4);
+
+ /* BVE (r1) */
+ *((int *) buf) = 0xe820d000;
+ if (target_write_memory (pcoqh, buf, 4) != 0)
+ error ("Couldn't modify space queue\n");
+
+ /* NOP */
+ *((int *) buf) = 0x08000240;
+ if (target_write_memory (pcoqt, buf, 4) != 0)
+ {
+ *((int *) buf) = inst1;
+ target_write_memory (pcoqh, buf, 4);
+ error ("Couldn't modify space queue\n");
+ }
+
+ write_register (1, pc);
+
+ /* Single step twice, the BVE instruction will set the space queue
+ such that it points to the PC value written immediately above
+ (ie the call dummy). */
+ resume (1, 0);
+ target_wait (inferior_ptid, &w);
+ resume (1, 0);
+ target_wait (inferior_ptid, &w);
+
+ /* Restore the two instructions at the old PC locations. */
+ *((int *) buf) = inst1;
+ target_write_memory (pcoqh, buf, 4);
+ *((int *) buf) = inst2;
+ target_write_memory (pcoqt, buf, 4);
+ }
+
+ /* The call dummy wants the ultimate destination address initially
+ in register %r5. */
+ write_register (5, fun);
+
+ /* We need to see if this objfile has a different DP value than our
+ own (it could be a shared library for example). */
+ ALL_OBJFILES (objfile)
+ {
+ struct obj_section *s;
+ obj_private_data_t *obj_private;
+
+ /* See if FUN is in any section within this shared library. */
+ for (s = objfile->sections; s < objfile->sections_end; s++)
+ if (s->addr <= fun && fun < s->endaddr)
+ break;
+
+ if (s >= objfile->sections_end)
+ continue;
+
+ obj_private = (obj_private_data_t *) objfile->obj_private;
+
+ /* The DP value may be different for each objfile. But within an
+ objfile each function uses the same dp value. Thus we do not need
+ to grope around the opd section looking for dp values.
+
+ ?!? This is not strictly correct since we may be in a shared library
+ and want to call back into the main program. To make that case
+ work correctly we need to set obj_private->dp for the main program's
+ objfile, then remove this conditional. */
+ if (obj_private->dp)
+ write_register (27, obj_private->dp);
+ break;
+ }
+ return pc;
+ }
+#endif
+
+#ifndef GDB_TARGET_IS_HPPA_20W
+ /* Prefer __gcc_plt_call over the HP supplied routine because
+ __gcc_plt_call works for any number of arguments. */
+ trampoline = NULL;
+ if (lookup_minimal_symbol ("__gcc_plt_call", NULL, NULL) == NULL)
+ using_gcc_plt_call = 0;
+
+ msymbol = lookup_minimal_symbol ("$$dyncall", NULL, NULL);
+ if (msymbol == NULL)
+ error ("Can't find an address for $$dyncall trampoline");
+
+ dyncall_addr = SYMBOL_VALUE_ADDRESS (msymbol);
+
+ /* FUN could be a procedure label, in which case we have to get
+ its real address and the value of its GOT/DP if we plan to
+ call the routine via gcc_plt_call. */
+ if ((fun & 0x2) && using_gcc_plt_call)
+ {
+ /* Get the GOT/DP value for the target function. It's
+ at *(fun+4). Note the call dummy is *NOT* allowed to
+ trash %r19 before calling the target function. */
+ write_register (19, read_memory_integer ((fun & ~0x3) + 4,
+ REGISTER_SIZE));
+
+ /* Now get the real address for the function we are calling, it's
+ at *fun. */
+ fun = (CORE_ADDR) read_memory_integer (fun & ~0x3,
+ TARGET_PTR_BIT / 8);
+ }
+ else
+ {
+
+#ifndef GDB_TARGET_IS_PA_ELF
+ /* FUN could be an export stub, the real address of a function, or
+ a PLABEL. When using gcc's PLT call routine we must call an import
+ stub rather than the export stub or real function for lazy binding
+ to work correctly
+
+ If we are using the gcc PLT call routine, then we need to
+ get the import stub for the target function. */
+ if (using_gcc_plt_call && som_solib_get_got_by_pc (fun))
+ {
+ struct objfile *objfile;
+ struct minimal_symbol *funsymbol, *stub_symbol;
+ CORE_ADDR newfun = 0;
+
+ funsymbol = lookup_minimal_symbol_by_pc (fun);
+ if (!funsymbol)
+ error ("Unable to find minimal symbol for target function.\n");
+
+ /* Search all the object files for an import symbol with the
+ right name. */
+ ALL_OBJFILES (objfile)
+ {
+ stub_symbol
+ = lookup_minimal_symbol_solib_trampoline
+ (SYMBOL_NAME (funsymbol), NULL, objfile);
+
+ if (!stub_symbol)
+ stub_symbol = lookup_minimal_symbol (SYMBOL_NAME (funsymbol),
+ NULL, objfile);
+
+ /* Found a symbol with the right name. */
+ if (stub_symbol)
+ {
+ struct unwind_table_entry *u;
+ /* It must be a shared library trampoline. */
+ if (MSYMBOL_TYPE (stub_symbol) != mst_solib_trampoline)
+ continue;
+
+ /* It must also be an import stub. */
+ u = find_unwind_entry (SYMBOL_VALUE (stub_symbol));
+ if (u == NULL
+ || (u->stub_unwind.stub_type != IMPORT
+#ifdef GDB_NATIVE_HPUX_11
+ /* Sigh. The hpux 10.20 dynamic linker will blow
+ chunks if we perform a call to an unbound function
+ via the IMPORT_SHLIB stub. The hpux 11.00 dynamic
+ linker will blow chunks if we do not call the
+ unbound function via the IMPORT_SHLIB stub.
+
+ We currently have no way to select bevahior on just
+ the target. However, we only support HPUX/SOM in
+ native mode. So we conditinalize on a native
+ #ifdef. Ugly. Ugly. Ugly */
+ && u->stub_unwind.stub_type != IMPORT_SHLIB
+#endif
+ ))
+ continue;
+
+ /* OK. Looks like the correct import stub. */
+ newfun = SYMBOL_VALUE (stub_symbol);
+ fun = newfun;
+
+ /* If we found an IMPORT stub, then we want to stop
+ searching now. If we found an IMPORT_SHLIB, we want
+ to continue the search in the hopes that we will find
+ an IMPORT stub. */
+ if (u->stub_unwind.stub_type == IMPORT)
+ break;
+ }
+ }
+
+ /* Ouch. We did not find an import stub. Make an attempt to
+ do the right thing instead of just croaking. Most of the
+ time this will actually work. */
+ if (newfun == 0)
+ write_register (19, som_solib_get_got_by_pc (fun));
+
+ u = find_unwind_entry (fun);
+ if (u
+ && (u->stub_unwind.stub_type == IMPORT
+ || u->stub_unwind.stub_type == IMPORT_SHLIB))
+ trampoline = lookup_minimal_symbol ("__gcc_plt_call", NULL, NULL);
+
+ /* If we found the import stub in the shared library, then we have
+ to set %r19 before we call the stub. */
+ if (u && u->stub_unwind.stub_type == IMPORT_SHLIB)
+ write_register (19, som_solib_get_got_by_pc (fun));
+ }
+#endif
+ }
+
+ /* If we are calling into another load module then have sr4export call the
+ magic __d_plt_call routine which is linked in from end.o.
+
+ You can't use _sr4export to make the call as the value in sp-24 will get
+ fried and you end up returning to the wrong location. You can't call the
+ target as the code to bind the PLT entry to a function can't return to a
+ stack address.
+
+ Also, query the dynamic linker in the inferior to provide a suitable
+ PLABEL for the target function. */
+ if (!using_gcc_plt_call)
+ {
+ CORE_ADDR new_fun;
+
+ /* Get a handle for the shared library containing FUN. Given the
+ handle we can query the shared library for a PLABEL. */
+ solib_handle = som_solib_get_solib_by_pc (fun);
+
+ if (solib_handle)
+ {
+ struct minimal_symbol *fmsymbol = lookup_minimal_symbol_by_pc (fun);
+
+ trampoline = lookup_minimal_symbol ("__d_plt_call", NULL, NULL);
+
+ if (trampoline == NULL)
+ {
+ error ("Can't find an address for __d_plt_call or __gcc_plt_call trampoline\nSuggest linking executable with -g or compiling with gcc.");
+ }
+
+ /* This is where sr4export will jump to. */
+ new_fun = SYMBOL_VALUE_ADDRESS (trampoline);
+
+ /* If the function is in a shared library, then call __d_shl_get to
+ get a PLABEL for the target function. */
+ new_stub = find_stub_with_shl_get (fmsymbol, solib_handle);
+
+ if (new_stub == 0)
+ error ("Can't find an import stub for %s", SYMBOL_NAME (fmsymbol));
+
+ /* We have to store the address of the stub in __shlib_funcptr. */
+ msymbol = lookup_minimal_symbol ("__shlib_funcptr", NULL,
+ (struct objfile *) NULL);
+
+ if (msymbol == NULL)
+ error ("Can't find an address for __shlib_funcptr");
+ target_write_memory (SYMBOL_VALUE_ADDRESS (msymbol),
+ (char *) &new_stub, 4);
+
+ /* We want sr4export to call __d_plt_call, so we claim it is
+ the final target. Clear trampoline. */
+ fun = new_fun;
+ trampoline = NULL;
+ }
+ }
+
+ /* Store upper 21 bits of function address into ldil. fun will either be
+ the final target (most cases) or __d_plt_call when calling into a shared
+ library and __gcc_plt_call is not available. */
+ store_unsigned_integer
+ (&dummy[FUNC_LDIL_OFFSET],
+ INSTRUCTION_SIZE,
+ deposit_21 (fun >> 11,
+ extract_unsigned_integer (&dummy[FUNC_LDIL_OFFSET],
+ INSTRUCTION_SIZE)));
+
+ /* Store lower 11 bits of function address into ldo */
+ store_unsigned_integer
+ (&dummy[FUNC_LDO_OFFSET],
+ INSTRUCTION_SIZE,
+ deposit_14 (fun & MASK_11,
+ extract_unsigned_integer (&dummy[FUNC_LDO_OFFSET],
+ INSTRUCTION_SIZE)));
+#ifdef SR4EXPORT_LDIL_OFFSET
+
+ {
+ CORE_ADDR trampoline_addr;
+
+ /* We may still need sr4export's address too. */
+
+ if (trampoline == NULL)
+ {
+ msymbol = lookup_minimal_symbol ("_sr4export", NULL, NULL);
+ if (msymbol == NULL)
+ error ("Can't find an address for _sr4export trampoline");
+
+ trampoline_addr = SYMBOL_VALUE_ADDRESS (msymbol);
+ }
+ else
+ trampoline_addr = SYMBOL_VALUE_ADDRESS (trampoline);
+
+
+ /* Store upper 21 bits of trampoline's address into ldil */
+ store_unsigned_integer
+ (&dummy[SR4EXPORT_LDIL_OFFSET],
+ INSTRUCTION_SIZE,
+ deposit_21 (trampoline_addr >> 11,
+ extract_unsigned_integer (&dummy[SR4EXPORT_LDIL_OFFSET],
+ INSTRUCTION_SIZE)));
+
+ /* Store lower 11 bits of trampoline's address into ldo */
+ store_unsigned_integer
+ (&dummy[SR4EXPORT_LDO_OFFSET],
+ INSTRUCTION_SIZE,
+ deposit_14 (trampoline_addr & MASK_11,
+ extract_unsigned_integer (&dummy[SR4EXPORT_LDO_OFFSET],
+ INSTRUCTION_SIZE)));
+ }
+#endif
+
+ write_register (22, pc);
+
+ /* If we are in a syscall, then we should call the stack dummy
+ directly. $$dyncall is not needed as the kernel sets up the
+ space id registers properly based on the value in %r31. In
+ fact calling $$dyncall will not work because the value in %r22
+ will be clobbered on the syscall exit path.
+
+ Similarly if the current PC is in a shared library. Note however,
+ this scheme won't work if the shared library isn't mapped into
+ the same space as the stack. */
+ if (flags & 2)
+ return pc;
+#ifndef GDB_TARGET_IS_PA_ELF
+ else if (som_solib_get_got_by_pc (target_read_pc (inferior_ptid)))
+ return pc;
+#endif
+ else
+ return dyncall_addr;
+#endif
+}
+
+
+
+
+/* If the pid is in a syscall, then the FP register is not readable.
+ We'll return zero in that case, rather than attempting to read it
+ and cause a warning. */
+CORE_ADDR
+target_read_fp (int pid)
+{
+ int flags = read_register (FLAGS_REGNUM);
+
+ if (flags & 2)
+ {
+ return (CORE_ADDR) 0;
+ }
+
+ /* This is the only site that may directly read_register () the FP
+ register. All others must use TARGET_READ_FP (). */
+ return read_register (FP_REGNUM);
+}
+
+
+/* Get the PC from %r31 if currently in a syscall. Also mask out privilege
+ bits. */
+
+CORE_ADDR
+target_read_pc (ptid_t ptid)
+{
+ int flags = read_register_pid (FLAGS_REGNUM, ptid);
+
+ /* The following test does not belong here. It is OS-specific, and belongs
+ in native code. */
+ /* Test SS_INSYSCALL */
+ if (flags & 2)
+ return read_register_pid (31, ptid) & ~0x3;
+
+ return read_register_pid (PC_REGNUM, ptid) & ~0x3;
+}
+
+/* Write out the PC. If currently in a syscall, then also write the new
+ PC value into %r31. */
+
+void
+target_write_pc (CORE_ADDR v, ptid_t ptid)
+{
+ int flags = read_register_pid (FLAGS_REGNUM, ptid);
+
+ /* The following test does not belong here. It is OS-specific, and belongs
+ in native code. */
+ /* If in a syscall, then set %r31. Also make sure to get the
+ privilege bits set correctly. */
+ /* Test SS_INSYSCALL */
+ if (flags & 2)
+ write_register_pid (31, v | 0x3, ptid);
+
+ write_register_pid (PC_REGNUM, v, ptid);
+ write_register_pid (NPC_REGNUM, v + 4, ptid);
+}
+
+/* return the alignment of a type in bytes. Structures have the maximum
+ alignment required by their fields. */
+
+static int
+hppa_alignof (struct type *type)
+{
+ int max_align, align, i;
+ CHECK_TYPEDEF (type);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_FLT:
+ return TYPE_LENGTH (type);
+ case TYPE_CODE_ARRAY:
+ return hppa_alignof (TYPE_FIELD_TYPE (type, 0));
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ max_align = 1;
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
+ {
+ /* Bit fields have no real alignment. */
+ /* if (!TYPE_FIELD_BITPOS (type, i)) */
+ if (!TYPE_FIELD_BITSIZE (type, i)) /* elz: this should be bitsize */
+ {
+ align = hppa_alignof (TYPE_FIELD_TYPE (type, i));
+ max_align = max (max_align, align);
+ }
+ }
+ return max_align;
+ default:
+ return 4;
+ }
+}
+
+/* Print the register regnum, or all registers if regnum is -1 */
+
+void
+pa_do_registers_info (int regnum, int fpregs)
+{
+ char raw_regs[REGISTER_BYTES];
+ int i;
+
+ /* Make a copy of gdb's save area (may cause actual
+ reads from the target). */
+ for (i = 0; i < NUM_REGS; i++)
+ frame_register_read (selected_frame, i, raw_regs + REGISTER_BYTE (i));
+
+ if (regnum == -1)
+ pa_print_registers (raw_regs, regnum, fpregs);
+ else if (regnum < FP4_REGNUM)
+ {
+ long reg_val[2];
+
+ /* Why is the value not passed through "extract_signed_integer"
+ as in "pa_print_registers" below? */
+ pa_register_look_aside (raw_regs, regnum, &reg_val[0]);
+
+ if (!is_pa_2)
+ {
+ printf_unfiltered ("%s %lx\n", REGISTER_NAME (regnum), reg_val[1]);
+ }
+ else
+ {
+ /* Fancy % formats to prevent leading zeros. */
+ if (reg_val[0] == 0)
+ printf_unfiltered ("%s %lx\n", REGISTER_NAME (regnum), reg_val[1]);
+ else
+ printf_unfiltered ("%s %lx%8.8lx\n", REGISTER_NAME (regnum),
+ reg_val[0], reg_val[1]);
+ }
+ }
+ else
+ /* Note that real floating point values only start at
+ FP4_REGNUM. FP0 and up are just status and error
+ registers, which have integral (bit) values. */
+ pa_print_fp_reg (regnum);
+}
+
+/********** new function ********************/
+void
+pa_do_strcat_registers_info (int regnum, int fpregs, struct ui_file *stream,
+ enum precision_type precision)
+{
+ char raw_regs[REGISTER_BYTES];
+ int i;
+
+ /* Make a copy of gdb's save area (may cause actual
+ reads from the target). */
+ for (i = 0; i < NUM_REGS; i++)
+ frame_register_read (selected_frame, i, raw_regs + REGISTER_BYTE (i));
+
+ if (regnum == -1)
+ pa_strcat_registers (raw_regs, regnum, fpregs, stream);
+
+ else if (regnum < FP4_REGNUM)
+ {
+ long reg_val[2];
+
+ /* Why is the value not passed through "extract_signed_integer"
+ as in "pa_print_registers" below? */
+ pa_register_look_aside (raw_regs, regnum, &reg_val[0]);
+
+ if (!is_pa_2)
+ {
+ fprintf_unfiltered (stream, "%s %lx", REGISTER_NAME (regnum), reg_val[1]);
+ }
+ else
+ {
+ /* Fancy % formats to prevent leading zeros. */
+ if (reg_val[0] == 0)
+ fprintf_unfiltered (stream, "%s %lx", REGISTER_NAME (regnum),
+ reg_val[1]);
+ else
+ fprintf_unfiltered (stream, "%s %lx%8.8lx", REGISTER_NAME (regnum),
+ reg_val[0], reg_val[1]);
+ }
+ }
+ else
+ /* Note that real floating point values only start at
+ FP4_REGNUM. FP0 and up are just status and error
+ registers, which have integral (bit) values. */
+ pa_strcat_fp_reg (regnum, stream, precision);
+}
+
+/* If this is a PA2.0 machine, fetch the real 64-bit register
+ value. Otherwise use the info from gdb's saved register area.
+
+ Note that reg_val is really expected to be an array of longs,
+ with two elements. */
+static void
+pa_register_look_aside (char *raw_regs, int regnum, long *raw_val)
+{
+ static int know_which = 0; /* False */
+
+ int regaddr;
+ unsigned int offset;
+ register int i;
+ int start;
+
+
+ char buf[MAX_REGISTER_RAW_SIZE];
+ long long reg_val;
+
+ if (!know_which)
+ {
+ if (CPU_PA_RISC2_0 == sysconf (_SC_CPU_VERSION))
+ {
+ is_pa_2 = (1 == 1);
+ }
+
+ know_which = 1; /* True */
+ }
+
+ raw_val[0] = 0;
+ raw_val[1] = 0;
+
+ if (!is_pa_2)
+ {
+ raw_val[1] = *(long *) (raw_regs + REGISTER_BYTE (regnum));
+ return;
+ }
+
+ /* Code below copied from hppah-nat.c, with fixes for wide
+ registers, using different area of save_state, etc. */
+ if (regnum == FLAGS_REGNUM || regnum >= FP0_REGNUM ||
+ !HAVE_STRUCT_SAVE_STATE_T || !HAVE_STRUCT_MEMBER_SS_WIDE)
+ {
+ /* Use narrow regs area of save_state and default macro. */
+ offset = U_REGS_OFFSET;
+ regaddr = register_addr (regnum, offset);
+ start = 1;
+ }
+ else
+ {
+ /* Use wide regs area, and calculate registers as 8 bytes wide.
+
+ We'd like to do this, but current version of "C" doesn't
+ permit "offsetof":
+
+ offset = offsetof(save_state_t, ss_wide);
+
+ Note that to avoid "C" doing typed pointer arithmetic, we
+ have to cast away the type in our offset calculation:
+ otherwise we get an offset of 1! */
+
+ /* NB: save_state_t is not available before HPUX 9.
+ The ss_wide field is not available previous to HPUX 10.20,
+ so to avoid compile-time warnings, we only compile this for
+ PA 2.0 processors. This control path should only be followed
+ if we're debugging a PA 2.0 processor, so this should not cause
+ problems. */
+
+ /* #if the following code out so that this file can still be
+ compiled on older HPUX boxes (< 10.20) which don't have
+ this structure/structure member. */
+#if HAVE_STRUCT_SAVE_STATE_T == 1 && HAVE_STRUCT_MEMBER_SS_WIDE == 1
+ save_state_t temp;
+
+ offset = ((int) &temp.ss_wide) - ((int) &temp);
+ regaddr = offset + regnum * 8;
+ start = 0;
+#endif
+ }
+
+ for (i = start; i < 2; i++)
+ {
+ errno = 0;
+ raw_val[i] = call_ptrace (PT_RUREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) regaddr, 0);
+ if (errno != 0)
+ {
+ /* Warning, not error, in case we are attached; sometimes the
+ kernel doesn't let us at the registers. */
+ char *err = safe_strerror (errno);
+ char *msg = alloca (strlen (err) + 128);
+ sprintf (msg, "reading register %s: %s", REGISTER_NAME (regnum), err);
+ warning (msg);
+ goto error_exit;
+ }
+
+ regaddr += sizeof (long);
+ }
+
+ if (regnum == PCOQ_HEAD_REGNUM || regnum == PCOQ_TAIL_REGNUM)
+ raw_val[1] &= ~0x3; /* I think we're masking out space bits */
+
+error_exit:
+ ;
+}
+
+/* "Info all-reg" command */
+
+static void
+pa_print_registers (char *raw_regs, int regnum, int fpregs)
+{
+ int i, j;
+ /* Alas, we are compiled so that "long long" is 32 bits */
+ long raw_val[2];
+ long long_val;
+ int rows = 48, columns = 2;
+
+ for (i = 0; i < rows; i++)
+ {
+ for (j = 0; j < columns; j++)
+ {
+ /* We display registers in column-major order. */
+ int regnum = i + j * rows;
+
+ /* Q: Why is the value passed through "extract_signed_integer",
+ while above, in "pa_do_registers_info" it isn't?
+ A: ? */
+ pa_register_look_aside (raw_regs, regnum, &raw_val[0]);
+
+ /* Even fancier % formats to prevent leading zeros
+ and still maintain the output in columns. */
+ if (!is_pa_2)
+ {
+ /* Being big-endian, on this machine the low bits
+ (the ones we want to look at) are in the second longword. */
+ long_val = extract_signed_integer (&raw_val[1], 4);
+ printf_filtered ("%10.10s: %8lx ",
+ REGISTER_NAME (regnum), long_val);
+ }
+ else
+ {
+ /* raw_val = extract_signed_integer(&raw_val, 8); */
+ if (raw_val[0] == 0)
+ printf_filtered ("%10.10s: %8lx ",
+ REGISTER_NAME (regnum), raw_val[1]);
+ else
+ printf_filtered ("%10.10s: %8lx%8.8lx ",
+ REGISTER_NAME (regnum),
+ raw_val[0], raw_val[1]);
+ }
+ }
+ printf_unfiltered ("\n");
+ }
+
+ if (fpregs)
+ for (i = FP4_REGNUM; i < NUM_REGS; i++) /* FP4_REGNUM == 72 */
+ pa_print_fp_reg (i);
+}
+
+/************* new function ******************/
+static void
+pa_strcat_registers (char *raw_regs, int regnum, int fpregs,
+ struct ui_file *stream)
+{
+ int i, j;
+ long raw_val[2]; /* Alas, we are compiled so that "long long" is 32 bits */
+ long long_val;
+ enum precision_type precision;
+
+ precision = unspecified_precision;
+
+ for (i = 0; i < 18; i++)
+ {
+ for (j = 0; j < 4; j++)
+ {
+ /* Q: Why is the value passed through "extract_signed_integer",
+ while above, in "pa_do_registers_info" it isn't?
+ A: ? */
+ pa_register_look_aside (raw_regs, i + (j * 18), &raw_val[0]);
+
+ /* Even fancier % formats to prevent leading zeros
+ and still maintain the output in columns. */
+ if (!is_pa_2)
+ {
+ /* Being big-endian, on this machine the low bits
+ (the ones we want to look at) are in the second longword. */
+ long_val = extract_signed_integer (&raw_val[1], 4);
+ fprintf_filtered (stream, "%8.8s: %8lx ",
+ REGISTER_NAME (i + (j * 18)), long_val);
+ }
+ else
+ {
+ /* raw_val = extract_signed_integer(&raw_val, 8); */
+ if (raw_val[0] == 0)
+ fprintf_filtered (stream, "%8.8s: %8lx ",
+ REGISTER_NAME (i + (j * 18)), raw_val[1]);
+ else
+ fprintf_filtered (stream, "%8.8s: %8lx%8.8lx ",
+ REGISTER_NAME (i + (j * 18)), raw_val[0],
+ raw_val[1]);
+ }
+ }
+ fprintf_unfiltered (stream, "\n");
+ }
+
+ if (fpregs)
+ for (i = FP4_REGNUM; i < NUM_REGS; i++) /* FP4_REGNUM == 72 */
+ pa_strcat_fp_reg (i, stream, precision);
+}
+
+static void
+pa_print_fp_reg (int i)
+{
+ char raw_buffer[MAX_REGISTER_RAW_SIZE];
+ char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
+
+ /* Get 32bits of data. */
+ frame_register_read (selected_frame, i, raw_buffer);
+
+ /* Put it in the buffer. No conversions are ever necessary. */
+ memcpy (virtual_buffer, raw_buffer, REGISTER_RAW_SIZE (i));
+
+ fputs_filtered (REGISTER_NAME (i), gdb_stdout);
+ print_spaces_filtered (8 - strlen (REGISTER_NAME (i)), gdb_stdout);
+ fputs_filtered ("(single precision) ", gdb_stdout);
+
+ val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0, gdb_stdout, 0,
+ 1, 0, Val_pretty_default);
+ printf_filtered ("\n");
+
+ /* If "i" is even, then this register can also be a double-precision
+ FP register. Dump it out as such. */
+ if ((i % 2) == 0)
+ {
+ /* Get the data in raw format for the 2nd half. */
+ frame_register_read (selected_frame, i + 1, raw_buffer);
+
+ /* Copy it into the appropriate part of the virtual buffer. */
+ memcpy (virtual_buffer + REGISTER_RAW_SIZE (i), raw_buffer,
+ REGISTER_RAW_SIZE (i));
+
+ /* Dump it as a double. */
+ fputs_filtered (REGISTER_NAME (i), gdb_stdout);
+ print_spaces_filtered (8 - strlen (REGISTER_NAME (i)), gdb_stdout);
+ fputs_filtered ("(double precision) ", gdb_stdout);
+
+ val_print (builtin_type_double, virtual_buffer, 0, 0, gdb_stdout, 0,
+ 1, 0, Val_pretty_default);
+ printf_filtered ("\n");
+ }
+}
+
+/*************** new function ***********************/
+static void
+pa_strcat_fp_reg (int i, struct ui_file *stream, enum precision_type precision)
+{
+ char raw_buffer[MAX_REGISTER_RAW_SIZE];
+ char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
+
+ fputs_filtered (REGISTER_NAME (i), stream);
+ print_spaces_filtered (8 - strlen (REGISTER_NAME (i)), stream);
+
+ /* Get 32bits of data. */
+ frame_register_read (selected_frame, i, raw_buffer);
+
+ /* Put it in the buffer. No conversions are ever necessary. */
+ memcpy (virtual_buffer, raw_buffer, REGISTER_RAW_SIZE (i));
+
+ if (precision == double_precision && (i % 2) == 0)
+ {
+
+ char raw_buf[MAX_REGISTER_RAW_SIZE];
+
+ /* Get the data in raw format for the 2nd half. */
+ frame_register_read (selected_frame, i + 1, raw_buf);
+
+ /* Copy it into the appropriate part of the virtual buffer. */
+ memcpy (virtual_buffer + REGISTER_RAW_SIZE (i), raw_buf, REGISTER_RAW_SIZE (i));
+
+ val_print (builtin_type_double, virtual_buffer, 0, 0, stream, 0,
+ 1, 0, Val_pretty_default);
+
+ }
+ else
+ {
+ val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0, stream, 0,
+ 1, 0, Val_pretty_default);
+ }
+
+}
+
+/* Return one if PC is in the call path of a trampoline, else return zero.
+
+ Note we return one for *any* call trampoline (long-call, arg-reloc), not
+ just shared library trampolines (import, export). */
+
+int
+in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+ struct minimal_symbol *minsym;
+ struct unwind_table_entry *u;
+ static CORE_ADDR dyncall = 0;
+ static CORE_ADDR sr4export = 0;
+
+#ifdef GDB_TARGET_IS_HPPA_20W
+ /* PA64 has a completely different stub/trampoline scheme. Is it
+ better? Maybe. It's certainly harder to determine with any
+ certainty that we are in a stub because we can not refer to the
+ unwinders to help.
+
+ The heuristic is simple. Try to lookup the current PC value in th
+ minimal symbol table. If that fails, then assume we are not in a
+ stub and return.
+
+ Then see if the PC value falls within the section bounds for the
+ section containing the minimal symbol we found in the first
+ step. If it does, then assume we are not in a stub and return.
+
+ Finally peek at the instructions to see if they look like a stub. */
+ {
+ struct minimal_symbol *minsym;
+ asection *sec;
+ CORE_ADDR addr;
+ int insn, i;
+
+ minsym = lookup_minimal_symbol_by_pc (pc);
+ if (! minsym)
+ return 0;
+
+ sec = SYMBOL_BFD_SECTION (minsym);
+
+ if (sec->vma <= pc
+ && sec->vma + sec->_cooked_size < pc)
+ return 0;
+
+ /* We might be in a stub. Peek at the instructions. Stubs are 3
+ instructions long. */
+ insn = read_memory_integer (pc, 4);
+
+ /* Find out where we think we are within the stub. */
+ if ((insn & 0xffffc00e) == 0x53610000)
+ addr = pc;
+ else if ((insn & 0xffffffff) == 0xe820d000)
+ addr = pc - 4;
+ else if ((insn & 0xffffc00e) == 0x537b0000)
+ addr = pc - 8;
+ else
+ return 0;
+
+ /* Now verify each insn in the range looks like a stub instruction. */
+ insn = read_memory_integer (addr, 4);
+ if ((insn & 0xffffc00e) != 0x53610000)
+ return 0;
+
+ /* Now verify each insn in the range looks like a stub instruction. */
+ insn = read_memory_integer (addr + 4, 4);
+ if ((insn & 0xffffffff) != 0xe820d000)
+ return 0;
+
+ /* Now verify each insn in the range looks like a stub instruction. */
+ insn = read_memory_integer (addr + 8, 4);
+ if ((insn & 0xffffc00e) != 0x537b0000)
+ return 0;
+
+ /* Looks like a stub. */
+ return 1;
+ }
+#endif
+
+ /* FIXME XXX - dyncall and sr4export must be initialized whenever we get a
+ new exec file */
+
+ /* First see if PC is in one of the two C-library trampolines. */
+ if (!dyncall)
+ {
+ minsym = lookup_minimal_symbol ("$$dyncall", NULL, NULL);
+ if (minsym)
+ dyncall = SYMBOL_VALUE_ADDRESS (minsym);
+ else
+ dyncall = -1;
+ }
+
+ if (!sr4export)
+ {
+ minsym = lookup_minimal_symbol ("_sr4export", NULL, NULL);
+ if (minsym)
+ sr4export = SYMBOL_VALUE_ADDRESS (minsym);
+ else
+ sr4export = -1;
+ }
+
+ if (pc == dyncall || pc == sr4export)
+ return 1;
+
+ minsym = lookup_minimal_symbol_by_pc (pc);
+ if (minsym && strcmp (SYMBOL_NAME (minsym), ".stub") == 0)
+ return 1;
+
+ /* Get the unwind descriptor corresponding to PC, return zero
+ if no unwind was found. */
+ u = find_unwind_entry (pc);
+ if (!u)
+ return 0;
+
+ /* If this isn't a linker stub, then return now. */
+ if (u->stub_unwind.stub_type == 0)
+ return 0;
+
+ /* By definition a long-branch stub is a call stub. */
+ if (u->stub_unwind.stub_type == LONG_BRANCH)
+ return 1;
+
+ /* The call and return path execute the same instructions within
+ an IMPORT stub! So an IMPORT stub is both a call and return
+ trampoline. */
+ if (u->stub_unwind.stub_type == IMPORT)
+ return 1;
+
+ /* Parameter relocation stubs always have a call path and may have a
+ return path. */
+ if (u->stub_unwind.stub_type == PARAMETER_RELOCATION
+ || u->stub_unwind.stub_type == EXPORT)
+ {
+ CORE_ADDR addr;
+
+ /* Search forward from the current PC until we hit a branch
+ or the end of the stub. */
+ for (addr = pc; addr <= u->region_end; addr += 4)
+ {
+ unsigned long insn;
+
+ insn = read_memory_integer (addr, 4);
+
+ /* Does it look like a bl? If so then it's the call path, if
+ we find a bv or be first, then we're on the return path. */
+ if ((insn & 0xfc00e000) == 0xe8000000)
+ return 1;
+ else if ((insn & 0xfc00e001) == 0xe800c000
+ || (insn & 0xfc000000) == 0xe0000000)
+ return 0;
+ }
+
+ /* Should never happen. */
+ warning ("Unable to find branch in parameter relocation stub.\n");
+ return 0;
+ }
+
+ /* Unknown stub type. For now, just return zero. */
+ return 0;
+}
+
+/* Return one if PC is in the return path of a trampoline, else return zero.
+
+ Note we return one for *any* call trampoline (long-call, arg-reloc), not
+ just shared library trampolines (import, export). */
+
+int
+in_solib_return_trampoline (CORE_ADDR pc, char *name)
+{
+ struct unwind_table_entry *u;
+
+ /* Get the unwind descriptor corresponding to PC, return zero
+ if no unwind was found. */
+ u = find_unwind_entry (pc);
+ if (!u)
+ return 0;
+
+ /* If this isn't a linker stub or it's just a long branch stub, then
+ return zero. */
+ if (u->stub_unwind.stub_type == 0 || u->stub_unwind.stub_type == LONG_BRANCH)
+ return 0;
+
+ /* The call and return path execute the same instructions within
+ an IMPORT stub! So an IMPORT stub is both a call and return
+ trampoline. */
+ if (u->stub_unwind.stub_type == IMPORT)
+ return 1;
+
+ /* Parameter relocation stubs always have a call path and may have a
+ return path. */
+ if (u->stub_unwind.stub_type == PARAMETER_RELOCATION
+ || u->stub_unwind.stub_type == EXPORT)
+ {
+ CORE_ADDR addr;
+
+ /* Search forward from the current PC until we hit a branch
+ or the end of the stub. */
+ for (addr = pc; addr <= u->region_end; addr += 4)
+ {
+ unsigned long insn;
+
+ insn = read_memory_integer (addr, 4);
+
+ /* Does it look like a bl? If so then it's the call path, if
+ we find a bv or be first, then we're on the return path. */
+ if ((insn & 0xfc00e000) == 0xe8000000)
+ return 0;
+ else if ((insn & 0xfc00e001) == 0xe800c000
+ || (insn & 0xfc000000) == 0xe0000000)
+ return 1;
+ }
+
+ /* Should never happen. */
+ warning ("Unable to find branch in parameter relocation stub.\n");
+ return 0;
+ }
+
+ /* Unknown stub type. For now, just return zero. */
+ return 0;
+
+}
+
+/* Figure out if PC is in a trampoline, and if so find out where
+ the trampoline will jump to. If not in a trampoline, return zero.
+
+ Simple code examination probably is not a good idea since the code
+ sequences in trampolines can also appear in user code.
+
+ We use unwinds and information from the minimal symbol table to
+ determine when we're in a trampoline. This won't work for ELF
+ (yet) since it doesn't create stub unwind entries. Whether or
+ not ELF will create stub unwinds or normal unwinds for linker
+ stubs is still being debated.
+
+ This should handle simple calls through dyncall or sr4export,
+ long calls, argument relocation stubs, and dyncall/sr4export
+ calling an argument relocation stub. It even handles some stubs
+ used in dynamic executables. */
+
+CORE_ADDR
+skip_trampoline_code (CORE_ADDR pc, char *name)
+{
+ long orig_pc = pc;
+ long prev_inst, curr_inst, loc;
+ static CORE_ADDR dyncall = 0;
+ static CORE_ADDR dyncall_external = 0;
+ static CORE_ADDR sr4export = 0;
+ struct minimal_symbol *msym;
+ struct unwind_table_entry *u;
+
+ /* FIXME XXX - dyncall and sr4export must be initialized whenever we get a
+ new exec file */
+
+ if (!dyncall)
+ {
+ msym = lookup_minimal_symbol ("$$dyncall", NULL, NULL);
+ if (msym)
+ dyncall = SYMBOL_VALUE_ADDRESS (msym);
+ else
+ dyncall = -1;
+ }
+
+ if (!dyncall_external)
+ {
+ msym = lookup_minimal_symbol ("$$dyncall_external", NULL, NULL);
+ if (msym)
+ dyncall_external = SYMBOL_VALUE_ADDRESS (msym);
+ else
+ dyncall_external = -1;
+ }
+
+ if (!sr4export)
+ {
+ msym = lookup_minimal_symbol ("_sr4export", NULL, NULL);
+ if (msym)
+ sr4export = SYMBOL_VALUE_ADDRESS (msym);
+ else
+ sr4export = -1;
+ }
+
+ /* Addresses passed to dyncall may *NOT* be the actual address
+ of the function. So we may have to do something special. */
+ if (pc == dyncall)
+ {
+ pc = (CORE_ADDR) read_register (22);
+
+ /* If bit 30 (counting from the left) is on, then pc is the address of
+ the PLT entry for this function, not the address of the function
+ itself. Bit 31 has meaning too, but only for MPE. */
+ if (pc & 0x2)
+ pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, TARGET_PTR_BIT / 8);
+ }
+ if (pc == dyncall_external)
+ {
+ pc = (CORE_ADDR) read_register (22);
+ pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, TARGET_PTR_BIT / 8);
+ }
+ else if (pc == sr4export)
+ pc = (CORE_ADDR) (read_register (22));
+
+ /* Get the unwind descriptor corresponding to PC, return zero
+ if no unwind was found. */
+ u = find_unwind_entry (pc);
+ if (!u)
+ return 0;
+
+ /* If this isn't a linker stub, then return now. */
+ /* elz: attention here! (FIXME) because of a compiler/linker
+ error, some stubs which should have a non zero stub_unwind.stub_type
+ have unfortunately a value of zero. So this function would return here
+ as if we were not in a trampoline. To fix this, we go look at the partial
+ symbol information, which reports this guy as a stub.
+ (FIXME): Unfortunately, we are not that lucky: it turns out that the
+ partial symbol information is also wrong sometimes. This is because
+ when it is entered (somread.c::som_symtab_read()) it can happen that
+ if the type of the symbol (from the som) is Entry, and the symbol is
+ in a shared library, then it can also be a trampoline. This would
+ be OK, except that I believe the way they decide if we are ina shared library
+ does not work. SOOOO..., even if we have a regular function w/o trampolines
+ its minimal symbol can be assigned type mst_solib_trampoline.
+ Also, if we find that the symbol is a real stub, then we fix the unwind
+ descriptor, and define the stub type to be EXPORT.
+ Hopefully this is correct most of the times. */
+ if (u->stub_unwind.stub_type == 0)
+ {
+
+/* elz: NOTE (FIXME!) once the problem with the unwind information is fixed
+ we can delete all the code which appears between the lines */
+/*--------------------------------------------------------------------------*/
+ msym = lookup_minimal_symbol_by_pc (pc);
+
+ if (msym == NULL || MSYMBOL_TYPE (msym) != mst_solib_trampoline)
+ return orig_pc == pc ? 0 : pc & ~0x3;
+
+ else if (msym != NULL && MSYMBOL_TYPE (msym) == mst_solib_trampoline)
+ {
+ struct objfile *objfile;
+ struct minimal_symbol *msymbol;
+ int function_found = 0;
+
+ /* go look if there is another minimal symbol with the same name as
+ this one, but with type mst_text. This would happen if the msym
+ is an actual trampoline, in which case there would be another
+ symbol with the same name corresponding to the real function */
+
+ ALL_MSYMBOLS (objfile, msymbol)
+ {
+ if (MSYMBOL_TYPE (msymbol) == mst_text
+ && STREQ (SYMBOL_NAME (msymbol), SYMBOL_NAME (msym)))
+ {
+ function_found = 1;
+ break;
+ }
+ }
+
+ if (function_found)
+ /* the type of msym is correct (mst_solib_trampoline), but
+ the unwind info is wrong, so set it to the correct value */
+ u->stub_unwind.stub_type = EXPORT;
+ else
+ /* the stub type info in the unwind is correct (this is not a
+ trampoline), but the msym type information is wrong, it
+ should be mst_text. So we need to fix the msym, and also
+ get out of this function */
+ {
+ MSYMBOL_TYPE (msym) = mst_text;
+ return orig_pc == pc ? 0 : pc & ~0x3;
+ }
+ }
+
+/*--------------------------------------------------------------------------*/
+ }
+
+ /* It's a stub. Search for a branch and figure out where it goes.
+ Note we have to handle multi insn branch sequences like ldil;ble.
+ Most (all?) other branches can be determined by examining the contents
+ of certain registers and the stack. */
+
+ loc = pc;
+ curr_inst = 0;
+ prev_inst = 0;
+ while (1)
+ {
+ /* Make sure we haven't walked outside the range of this stub. */
+ if (u != find_unwind_entry (loc))
+ {
+ warning ("Unable to find branch in linker stub");
+ return orig_pc == pc ? 0 : pc & ~0x3;
+ }
+
+ prev_inst = curr_inst;
+ curr_inst = read_memory_integer (loc, 4);
+
+ /* Does it look like a branch external using %r1? Then it's the
+ branch from the stub to the actual function. */
+ if ((curr_inst & 0xffe0e000) == 0xe0202000)
+ {
+ /* Yup. See if the previous instruction loaded
+ a value into %r1. If so compute and return the jump address. */
+ if ((prev_inst & 0xffe00000) == 0x20200000)
+ return (extract_21 (prev_inst) + extract_17 (curr_inst)) & ~0x3;
+ else
+ {
+ warning ("Unable to find ldil X,%%r1 before ble Y(%%sr4,%%r1).");
+ return orig_pc == pc ? 0 : pc & ~0x3;
+ }
+ }
+
+ /* Does it look like a be 0(sr0,%r21)? OR
+ Does it look like a be, n 0(sr0,%r21)? OR
+ Does it look like a bve (r21)? (this is on PA2.0)
+ Does it look like a bve, n(r21)? (this is also on PA2.0)
+ That's the branch from an
+ import stub to an export stub.
+
+ It is impossible to determine the target of the branch via
+ simple examination of instructions and/or data (consider
+ that the address in the plabel may be the address of the
+ bind-on-reference routine in the dynamic loader).
+
+ So we have try an alternative approach.
+
+ Get the name of the symbol at our current location; it should
+ be a stub symbol with the same name as the symbol in the
+ shared library.
+
+ Then lookup a minimal symbol with the same name; we should
+ get the minimal symbol for the target routine in the shared
+ library as those take precedence of import/export stubs. */
+ if ((curr_inst == 0xe2a00000) ||
+ (curr_inst == 0xe2a00002) ||
+ (curr_inst == 0xeaa0d000) ||
+ (curr_inst == 0xeaa0d002))
+ {
+ struct minimal_symbol *stubsym, *libsym;
+
+ stubsym = lookup_minimal_symbol_by_pc (loc);
+ if (stubsym == NULL)
+ {
+ warning ("Unable to find symbol for 0x%lx", loc);
+ return orig_pc == pc ? 0 : pc & ~0x3;
+ }
+
+ libsym = lookup_minimal_symbol (SYMBOL_NAME (stubsym), NULL, NULL);
+ if (libsym == NULL)
+ {
+ warning ("Unable to find library symbol for %s\n",
+ SYMBOL_NAME (stubsym));
+ return orig_pc == pc ? 0 : pc & ~0x3;
+ }
+
+ return SYMBOL_VALUE (libsym);
+ }
+
+ /* Does it look like bl X,%rp or bl X,%r0? Another way to do a
+ branch from the stub to the actual function. */
+ /*elz */
+ else if ((curr_inst & 0xffe0e000) == 0xe8400000
+ || (curr_inst & 0xffe0e000) == 0xe8000000
+ || (curr_inst & 0xffe0e000) == 0xe800A000)
+ return (loc + extract_17 (curr_inst) + 8) & ~0x3;
+
+ /* Does it look like bv (rp)? Note this depends on the
+ current stack pointer being the same as the stack
+ pointer in the stub itself! This is a branch on from the
+ stub back to the original caller. */
+ /*else if ((curr_inst & 0xffe0e000) == 0xe840c000) */
+ else if ((curr_inst & 0xffe0f000) == 0xe840c000)
+ {
+ /* Yup. See if the previous instruction loaded
+ rp from sp - 8. */
+ if (prev_inst == 0x4bc23ff1)
+ return (read_memory_integer
+ (read_register (SP_REGNUM) - 8, 4)) & ~0x3;
+ else
+ {
+ warning ("Unable to find restore of %%rp before bv (%%rp).");
+ return orig_pc == pc ? 0 : pc & ~0x3;
+ }
+ }
+
+ /* elz: added this case to capture the new instruction
+ at the end of the return part of an export stub used by
+ the PA2.0: BVE, n (rp) */
+ else if ((curr_inst & 0xffe0f000) == 0xe840d000)
+ {
+ return (read_memory_integer
+ (read_register (SP_REGNUM) - 24, TARGET_PTR_BIT / 8)) & ~0x3;
+ }
+
+ /* What about be,n 0(sr0,%rp)? It's just another way we return to
+ the original caller from the stub. Used in dynamic executables. */
+ else if (curr_inst == 0xe0400002)
+ {
+ /* The value we jump to is sitting in sp - 24. But that's
+ loaded several instructions before the be instruction.
+ I guess we could check for the previous instruction being
+ mtsp %r1,%sr0 if we want to do sanity checking. */
+ return (read_memory_integer
+ (read_register (SP_REGNUM) - 24, TARGET_PTR_BIT / 8)) & ~0x3;
+ }
+
+ /* Haven't found the branch yet, but we're still in the stub.
+ Keep looking. */
+ loc += 4;
+ }
+}
+
+
+/* For the given instruction (INST), return any adjustment it makes
+ to the stack pointer or zero for no adjustment.
+
+ This only handles instructions commonly found in prologues. */
+
+static int
+prologue_inst_adjust_sp (unsigned long inst)
+{
+ /* This must persist across calls. */
+ static int save_high21;
+
+ /* The most common way to perform a stack adjustment ldo X(sp),sp */
+ if ((inst & 0xffffc000) == 0x37de0000)
+ return extract_14 (inst);
+
+ /* stwm X,D(sp) */
+ if ((inst & 0xffe00000) == 0x6fc00000)
+ return extract_14 (inst);
+
+ /* std,ma X,D(sp) */
+ if ((inst & 0xffe00008) == 0x73c00008)
+ return (inst & 0x1 ? -1 << 13 : 0) | (((inst >> 4) & 0x3ff) << 3);
+
+ /* addil high21,%r1; ldo low11,(%r1),%r30)
+ save high bits in save_high21 for later use. */
+ if ((inst & 0xffe00000) == 0x28200000)
+ {
+ save_high21 = extract_21 (inst);
+ return 0;
+ }
+
+ if ((inst & 0xffff0000) == 0x343e0000)
+ return save_high21 + extract_14 (inst);
+
+ /* fstws as used by the HP compilers. */
+ if ((inst & 0xffffffe0) == 0x2fd01220)
+ return extract_5_load (inst);
+
+ /* No adjustment. */
+ return 0;
+}
+
+/* Return nonzero if INST is a branch of some kind, else return zero. */
+
+static int
+is_branch (unsigned long inst)
+{
+ switch (inst >> 26)
+ {
+ case 0x20:
+ case 0x21:
+ case 0x22:
+ case 0x23:
+ case 0x27:
+ case 0x28:
+ case 0x29:
+ case 0x2a:
+ case 0x2b:
+ case 0x2f:
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x38:
+ case 0x39:
+ case 0x3a:
+ case 0x3b:
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+/* Return the register number for a GR which is saved by INST or
+ zero it INST does not save a GR. */
+
+static int
+inst_saves_gr (unsigned long inst)
+{
+ /* Does it look like a stw? */
+ if ((inst >> 26) == 0x1a || (inst >> 26) == 0x1b
+ || (inst >> 26) == 0x1f
+ || ((inst >> 26) == 0x1f
+ && ((inst >> 6) == 0xa)))
+ return extract_5R_store (inst);
+
+ /* Does it look like a std? */
+ if ((inst >> 26) == 0x1c
+ || ((inst >> 26) == 0x03
+ && ((inst >> 6) & 0xf) == 0xb))
+ return extract_5R_store (inst);
+
+ /* Does it look like a stwm? GCC & HPC may use this in prologues. */
+ if ((inst >> 26) == 0x1b)
+ return extract_5R_store (inst);
+
+ /* Does it look like sth or stb? HPC versions 9.0 and later use these
+ too. */
+ if ((inst >> 26) == 0x19 || (inst >> 26) == 0x18
+ || ((inst >> 26) == 0x3
+ && (((inst >> 6) & 0xf) == 0x8
+ || (inst >> 6) & 0xf) == 0x9))
+ return extract_5R_store (inst);
+
+ return 0;
+}
+
+/* Return the register number for a FR which is saved by INST or
+ zero it INST does not save a FR.
+
+ Note we only care about full 64bit register stores (that's the only
+ kind of stores the prologue will use).
+
+ FIXME: What about argument stores with the HP compiler in ANSI mode? */
+
+static int
+inst_saves_fr (unsigned long inst)
+{
+ /* is this an FSTD ? */
+ if ((inst & 0xfc00dfc0) == 0x2c001200)
+ return extract_5r_store (inst);
+ if ((inst & 0xfc000002) == 0x70000002)
+ return extract_5R_store (inst);
+ /* is this an FSTW ? */
+ if ((inst & 0xfc00df80) == 0x24001200)
+ return extract_5r_store (inst);
+ if ((inst & 0xfc000002) == 0x7c000000)
+ return extract_5R_store (inst);
+ return 0;
+}
+
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code.
+
+ Use information in the unwind table to determine what exactly should
+ be in the prologue. */
+
+
+CORE_ADDR
+skip_prologue_hard_way (CORE_ADDR pc)
+{
+ char buf[4];
+ CORE_ADDR orig_pc = pc;
+ unsigned long inst, stack_remaining, save_gr, save_fr, save_rp, save_sp;
+ unsigned long args_stored, status, i, restart_gr, restart_fr;
+ struct unwind_table_entry *u;
+
+ restart_gr = 0;
+ restart_fr = 0;
+
+restart:
+ u = find_unwind_entry (pc);
+ if (!u)
+ return pc;
+
+ /* If we are not at the beginning of a function, then return now. */
+ if ((pc & ~0x3) != u->region_start)
+ return pc;
+
+ /* This is how much of a frame adjustment we need to account for. */
+ stack_remaining = u->Total_frame_size << 3;
+
+ /* Magic register saves we want to know about. */
+ save_rp = u->Save_RP;
+ save_sp = u->Save_SP;
+
+ /* An indication that args may be stored into the stack. Unfortunately
+ the HPUX compilers tend to set this in cases where no args were
+ stored too!. */
+ args_stored = 1;
+
+ /* Turn the Entry_GR field into a bitmask. */
+ save_gr = 0;
+ for (i = 3; i < u->Entry_GR + 3; i++)
+ {
+ /* Frame pointer gets saved into a special location. */
+ if (u->Save_SP && i == FP_REGNUM)
+ continue;
+
+ save_gr |= (1 << i);
+ }
+ save_gr &= ~restart_gr;
+
+ /* Turn the Entry_FR field into a bitmask too. */
+ save_fr = 0;
+ for (i = 12; i < u->Entry_FR + 12; i++)
+ save_fr |= (1 << i);
+ save_fr &= ~restart_fr;
+
+ /* Loop until we find everything of interest or hit a branch.
+
+ For unoptimized GCC code and for any HP CC code this will never ever
+ examine any user instructions.
+
+ For optimzied GCC code we're faced with problems. GCC will schedule
+ its prologue and make prologue instructions available for delay slot
+ filling. The end result is user code gets mixed in with the prologue
+ and a prologue instruction may be in the delay slot of the first branch
+ or call.
+
+ Some unexpected things are expected with debugging optimized code, so
+ we allow this routine to walk past user instructions in optimized
+ GCC code. */
+ while (save_gr || save_fr || save_rp || save_sp || stack_remaining > 0
+ || args_stored)
+ {
+ unsigned int reg_num;
+ unsigned long old_stack_remaining, old_save_gr, old_save_fr;
+ unsigned long old_save_rp, old_save_sp, next_inst;
+
+ /* Save copies of all the triggers so we can compare them later
+ (only for HPC). */
+ old_save_gr = save_gr;
+ old_save_fr = save_fr;
+ old_save_rp = save_rp;
+ old_save_sp = save_sp;
+ old_stack_remaining = stack_remaining;
+
+ status = target_read_memory (pc, buf, 4);
+ inst = extract_unsigned_integer (buf, 4);
+
+ /* Yow! */
+ if (status != 0)
+ return pc;
+
+ /* Note the interesting effects of this instruction. */
+ stack_remaining -= prologue_inst_adjust_sp (inst);
+
+ /* There are limited ways to store the return pointer into the
+ stack. */
+ if (inst == 0x6bc23fd9 || inst == 0x0fc212c1)
+ save_rp = 0;
+
+ /* These are the only ways we save SP into the stack. At this time
+ the HP compilers never bother to save SP into the stack. */
+ if ((inst & 0xffffc000) == 0x6fc10000
+ || (inst & 0xffffc00c) == 0x73c10008)
+ save_sp = 0;
+
+ /* Are we loading some register with an offset from the argument
+ pointer? */
+ if ((inst & 0xffe00000) == 0x37a00000
+ || (inst & 0xffffffe0) == 0x081d0240)
+ {
+ pc += 4;
+ continue;
+ }
+
+ /* Account for general and floating-point register saves. */
+ reg_num = inst_saves_gr (inst);
+ save_gr &= ~(1 << reg_num);
+
+ /* Ugh. Also account for argument stores into the stack.
+ Unfortunately args_stored only tells us that some arguments
+ where stored into the stack. Not how many or what kind!
+
+ This is a kludge as on the HP compiler sets this bit and it
+ never does prologue scheduling. So once we see one, skip past
+ all of them. We have similar code for the fp arg stores below.
+
+ FIXME. Can still die if we have a mix of GR and FR argument
+ stores! */
+ if (reg_num >= (TARGET_PTR_BIT == 64 ? 19 : 23) && reg_num <= 26)
+ {
+ while (reg_num >= (TARGET_PTR_BIT == 64 ? 19 : 23) && reg_num <= 26)
+ {
+ pc += 4;
+ status = target_read_memory (pc, buf, 4);
+ inst = extract_unsigned_integer (buf, 4);
+ if (status != 0)
+ return pc;
+ reg_num = inst_saves_gr (inst);
+ }
+ args_stored = 0;
+ continue;
+ }
+
+ reg_num = inst_saves_fr (inst);
+ save_fr &= ~(1 << reg_num);
+
+ status = target_read_memory (pc + 4, buf, 4);
+ next_inst = extract_unsigned_integer (buf, 4);
+
+ /* Yow! */
+ if (status != 0)
+ return pc;
+
+ /* We've got to be read to handle the ldo before the fp register
+ save. */
+ if ((inst & 0xfc000000) == 0x34000000
+ && inst_saves_fr (next_inst) >= 4
+ && inst_saves_fr (next_inst) <= (TARGET_PTR_BIT == 64 ? 11 : 7))
+ {
+ /* So we drop into the code below in a reasonable state. */
+ reg_num = inst_saves_fr (next_inst);
+ pc -= 4;
+ }
+
+ /* Ugh. Also account for argument stores into the stack.
+ This is a kludge as on the HP compiler sets this bit and it
+ never does prologue scheduling. So once we see one, skip past
+ all of them. */
+ if (reg_num >= 4 && reg_num <= (TARGET_PTR_BIT == 64 ? 11 : 7))
+ {
+ while (reg_num >= 4 && reg_num <= (TARGET_PTR_BIT == 64 ? 11 : 7))
+ {
+ pc += 8;
+ status = target_read_memory (pc, buf, 4);
+ inst = extract_unsigned_integer (buf, 4);
+ if (status != 0)
+ return pc;
+ if ((inst & 0xfc000000) != 0x34000000)
+ break;
+ status = target_read_memory (pc + 4, buf, 4);
+ next_inst = extract_unsigned_integer (buf, 4);
+ if (status != 0)
+ return pc;
+ reg_num = inst_saves_fr (next_inst);
+ }
+ args_stored = 0;
+ continue;
+ }
+
+ /* Quit if we hit any kind of branch. This can happen if a prologue
+ instruction is in the delay slot of the first call/branch. */
+ if (is_branch (inst))
+ break;
+
+ /* What a crock. The HP compilers set args_stored even if no
+ arguments were stored into the stack (boo hiss). This could
+ cause this code to then skip a bunch of user insns (up to the
+ first branch).
+
+ To combat this we try to identify when args_stored was bogusly
+ set and clear it. We only do this when args_stored is nonzero,
+ all other resources are accounted for, and nothing changed on
+ this pass. */
+ if (args_stored
+ && !(save_gr || save_fr || save_rp || save_sp || stack_remaining > 0)
+ && old_save_gr == save_gr && old_save_fr == save_fr
+ && old_save_rp == save_rp && old_save_sp == save_sp
+ && old_stack_remaining == stack_remaining)
+ break;
+
+ /* Bump the PC. */
+ pc += 4;
+ }
+
+ /* We've got a tenative location for the end of the prologue. However
+ because of limitations in the unwind descriptor mechanism we may
+ have went too far into user code looking for the save of a register
+ that does not exist. So, if there registers we expected to be saved
+ but never were, mask them out and restart.
+
+ This should only happen in optimized code, and should be very rare. */
+ if (save_gr || (save_fr && !(restart_fr || restart_gr)))
+ {
+ pc = orig_pc;
+ restart_gr = save_gr;
+ restart_fr = save_fr;
+ goto restart;
+ }
+
+ return pc;
+}
+
+
+/* Return the address of the PC after the last prologue instruction if
+ we can determine it from the debug symbols. Else return zero. */
+
+static CORE_ADDR
+after_prologue (CORE_ADDR pc)
+{
+ struct symtab_and_line sal;
+ CORE_ADDR func_addr, func_end;
+ struct symbol *f;
+
+ /* If we can not find the symbol in the partial symbol table, then
+ there is no hope we can determine the function's start address
+ with this code. */
+ if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ return 0;
+
+ /* Get the line associated with FUNC_ADDR. */
+ sal = find_pc_line (func_addr, 0);
+
+ /* There are only two cases to consider. First, the end of the source line
+ is within the function bounds. In that case we return the end of the
+ source line. Second is the end of the source line extends beyond the
+ bounds of the current function. We need to use the slow code to
+ examine instructions in that case.
+
+ Anything else is simply a bug elsewhere. Fixing it here is absolutely
+ the wrong thing to do. In fact, it should be entirely possible for this
+ function to always return zero since the slow instruction scanning code
+ is supposed to *always* work. If it does not, then it is a bug. */
+ if (sal.end < func_end)
+ return sal.end;
+ else
+ return 0;
+}
+
+/* To skip prologues, I use this predicate. Returns either PC itself
+ if the code at PC does not look like a function prologue; otherwise
+ returns an address that (if we're lucky) follows the prologue. If
+ LENIENT, then we must skip everything which is involved in setting
+ up the frame (it's OK to skip more, just so long as we don't skip
+ anything which might clobber the registers which are being saved.
+ Currently we must not skip more on the alpha, but we might the lenient
+ stuff some day. */
+
+CORE_ADDR
+hppa_skip_prologue (CORE_ADDR pc)
+{
+ unsigned long inst;
+ int offset;
+ CORE_ADDR post_prologue_pc;
+ char buf[4];
+
+ /* See if we can determine the end of the prologue via the symbol table.
+ If so, then return either PC, or the PC after the prologue, whichever
+ is greater. */
+
+ post_prologue_pc = after_prologue (pc);
+
+ /* If after_prologue returned a useful address, then use it. Else
+ fall back on the instruction skipping code.
+
+ Some folks have claimed this causes problems because the breakpoint
+ may be the first instruction of the prologue. If that happens, then
+ the instruction skipping code has a bug that needs to be fixed. */
+ if (post_prologue_pc != 0)
+ return max (pc, post_prologue_pc);
+ else
+ return (skip_prologue_hard_way (pc));
+}
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame. */
+
+void
+hppa_frame_find_saved_regs (struct frame_info *frame_info,
+ struct frame_saved_regs *frame_saved_regs)
+{
+ CORE_ADDR pc;
+ struct unwind_table_entry *u;
+ unsigned long inst, stack_remaining, save_gr, save_fr, save_rp, save_sp;
+ int status, i, reg;
+ char buf[4];
+ int fp_loc = -1;
+ int final_iteration;
+
+ /* Zero out everything. */
+ memset (frame_saved_regs, '\0', sizeof (struct frame_saved_regs));
+
+ /* Call dummy frames always look the same, so there's no need to
+ examine the dummy code to determine locations of saved registers;
+ instead, let find_dummy_frame_regs fill in the correct offsets
+ for the saved registers. */
+ if ((frame_info->pc >= frame_info->frame
+ && frame_info->pc <= (frame_info->frame
+ /* A call dummy is sized in words, but it is
+ actually a series of instructions. Account
+ for that scaling factor. */
+ + ((REGISTER_SIZE / INSTRUCTION_SIZE)
+ * CALL_DUMMY_LENGTH)
+ /* Similarly we have to account for 64bit
+ wide register saves. */
+ + (32 * REGISTER_SIZE)
+ /* We always consider FP regs 8 bytes long. */
+ + (NUM_REGS - FP0_REGNUM) * 8
+ /* Similarly we have to account for 64bit
+ wide register saves. */
+ + (6 * REGISTER_SIZE))))
+ find_dummy_frame_regs (frame_info, frame_saved_regs);
+
+ /* Interrupt handlers are special too. They lay out the register
+ state in the exact same order as the register numbers in GDB. */
+ if (pc_in_interrupt_handler (frame_info->pc))
+ {
+ for (i = 0; i < NUM_REGS; i++)
+ {
+ /* SP is a little special. */
+ if (i == SP_REGNUM)
+ frame_saved_regs->regs[SP_REGNUM]
+ = read_memory_integer (frame_info->frame + SP_REGNUM * 4,
+ TARGET_PTR_BIT / 8);
+ else
+ frame_saved_regs->regs[i] = frame_info->frame + i * 4;
+ }
+ return;
+ }
+
+#ifdef FRAME_FIND_SAVED_REGS_IN_SIGTRAMP
+ /* Handle signal handler callers. */
+ if (frame_info->signal_handler_caller)
+ {
+ FRAME_FIND_SAVED_REGS_IN_SIGTRAMP (frame_info, frame_saved_regs);
+ return;
+ }
+#endif
+
+ /* Get the starting address of the function referred to by the PC
+ saved in frame. */
+ pc = get_pc_function_start (frame_info->pc);
+
+ /* Yow! */
+ u = find_unwind_entry (pc);
+ if (!u)
+ return;
+
+ /* This is how much of a frame adjustment we need to account for. */
+ stack_remaining = u->Total_frame_size << 3;
+
+ /* Magic register saves we want to know about. */
+ save_rp = u->Save_RP;
+ save_sp = u->Save_SP;
+
+ /* Turn the Entry_GR field into a bitmask. */
+ save_gr = 0;
+ for (i = 3; i < u->Entry_GR + 3; i++)
+ {
+ /* Frame pointer gets saved into a special location. */
+ if (u->Save_SP && i == FP_REGNUM)
+ continue;
+
+ save_gr |= (1 << i);
+ }
+
+ /* Turn the Entry_FR field into a bitmask too. */
+ save_fr = 0;
+ for (i = 12; i < u->Entry_FR + 12; i++)
+ save_fr |= (1 << i);
+
+ /* The frame always represents the value of %sp at entry to the
+ current function (and is thus equivalent to the "saved" stack
+ pointer. */
+ frame_saved_regs->regs[SP_REGNUM] = frame_info->frame;
+
+ /* Loop until we find everything of interest or hit a branch.
+
+ For unoptimized GCC code and for any HP CC code this will never ever
+ examine any user instructions.
+
+ For optimized GCC code we're faced with problems. GCC will schedule
+ its prologue and make prologue instructions available for delay slot
+ filling. The end result is user code gets mixed in with the prologue
+ and a prologue instruction may be in the delay slot of the first branch
+ or call.
+
+ Some unexpected things are expected with debugging optimized code, so
+ we allow this routine to walk past user instructions in optimized
+ GCC code. */
+ final_iteration = 0;
+ while ((save_gr || save_fr || save_rp || save_sp || stack_remaining > 0)
+ && pc <= frame_info->pc)
+ {
+ status = target_read_memory (pc, buf, 4);
+ inst = extract_unsigned_integer (buf, 4);
+
+ /* Yow! */
+ if (status != 0)
+ return;
+
+ /* Note the interesting effects of this instruction. */
+ stack_remaining -= prologue_inst_adjust_sp (inst);
+
+ /* There are limited ways to store the return pointer into the
+ stack. */
+ if (inst == 0x6bc23fd9) /* stw rp,-0x14(sr0,sp) */
+ {
+ save_rp = 0;
+ frame_saved_regs->regs[RP_REGNUM] = frame_info->frame - 20;
+ }
+ else if (inst == 0x0fc212c1) /* std rp,-0x10(sr0,sp) */
+ {
+ save_rp = 0;
+ frame_saved_regs->regs[RP_REGNUM] = frame_info->frame - 16;
+ }
+
+ /* Note if we saved SP into the stack. This also happens to indicate
+ the location of the saved frame pointer. */
+ if ( (inst & 0xffffc000) == 0x6fc10000 /* stw,ma r1,N(sr0,sp) */
+ || (inst & 0xffffc00c) == 0x73c10008) /* std,ma r1,N(sr0,sp) */
+ {
+ frame_saved_regs->regs[FP_REGNUM] = frame_info->frame;
+ save_sp = 0;
+ }
+
+ /* Account for general and floating-point register saves. */
+ reg = inst_saves_gr (inst);
+ if (reg >= 3 && reg <= 18
+ && (!u->Save_SP || reg != FP_REGNUM))
+ {
+ save_gr &= ~(1 << reg);
+
+ /* stwm with a positive displacement is a *post modify*. */
+ if ((inst >> 26) == 0x1b
+ && extract_14 (inst) >= 0)
+ frame_saved_regs->regs[reg] = frame_info->frame;
+ /* A std has explicit post_modify forms. */
+ else if ((inst & 0xfc00000c0) == 0x70000008)
+ frame_saved_regs->regs[reg] = frame_info->frame;
+ else
+ {
+ CORE_ADDR offset;
+
+ if ((inst >> 26) == 0x1c)
+ offset = (inst & 0x1 ? -1 << 13 : 0) | (((inst >> 4) & 0x3ff) << 3);
+ else if ((inst >> 26) == 0x03)
+ offset = low_sign_extend (inst & 0x1f, 5);
+ else
+ offset = extract_14 (inst);
+
+ /* Handle code with and without frame pointers. */
+ if (u->Save_SP)
+ frame_saved_regs->regs[reg]
+ = frame_info->frame + offset;
+ else
+ frame_saved_regs->regs[reg]
+ = (frame_info->frame + (u->Total_frame_size << 3)
+ + offset);
+ }
+ }
+
+
+ /* GCC handles callee saved FP regs a little differently.
+
+ It emits an instruction to put the value of the start of
+ the FP store area into %r1. It then uses fstds,ma with
+ a basereg of %r1 for the stores.
+
+ HP CC emits them at the current stack pointer modifying
+ the stack pointer as it stores each register. */
+
+ /* ldo X(%r3),%r1 or ldo X(%r30),%r1. */
+ if ((inst & 0xffffc000) == 0x34610000
+ || (inst & 0xffffc000) == 0x37c10000)
+ fp_loc = extract_14 (inst);
+
+ reg = inst_saves_fr (inst);
+ if (reg >= 12 && reg <= 21)
+ {
+ /* Note +4 braindamage below is necessary because the FP status
+ registers are internally 8 registers rather than the expected
+ 4 registers. */
+ save_fr &= ~(1 << reg);
+ if (fp_loc == -1)
+ {
+ /* 1st HP CC FP register store. After this instruction
+ we've set enough state that the GCC and HPCC code are
+ both handled in the same manner. */
+ frame_saved_regs->regs[reg + FP4_REGNUM + 4] = frame_info->frame;
+ fp_loc = 8;
+ }
+ else
+ {
+ frame_saved_regs->regs[reg + FP0_REGNUM + 4]
+ = frame_info->frame + fp_loc;
+ fp_loc += 8;
+ }
+ }
+
+ /* Quit if we hit any kind of branch the previous iteration. */
+ if (final_iteration)
+ break;
+
+ /* We want to look precisely one instruction beyond the branch
+ if we have not found everything yet. */
+ if (is_branch (inst))
+ final_iteration = 1;
+
+ /* Bump the PC. */
+ pc += 4;
+ }
+}
+
+
+/* Exception handling support for the HP-UX ANSI C++ compiler.
+ The compiler (aCC) provides a callback for exception events;
+ GDB can set a breakpoint on this callback and find out what
+ exception event has occurred. */
+
+/* The name of the hook to be set to point to the callback function */
+static char HP_ACC_EH_notify_hook[] = "__eh_notify_hook";
+/* The name of the function to be used to set the hook value */
+static char HP_ACC_EH_set_hook_value[] = "__eh_set_hook_value";
+/* The name of the callback function in end.o */
+static char HP_ACC_EH_notify_callback[] = "__d_eh_notify_callback";
+/* Name of function in end.o on which a break is set (called by above) */
+static char HP_ACC_EH_break[] = "__d_eh_break";
+/* Name of flag (in end.o) that enables catching throws */
+static char HP_ACC_EH_catch_throw[] = "__d_eh_catch_throw";
+/* Name of flag (in end.o) that enables catching catching */
+static char HP_ACC_EH_catch_catch[] = "__d_eh_catch_catch";
+/* The enum used by aCC */
+typedef enum
+ {
+ __EH_NOTIFY_THROW,
+ __EH_NOTIFY_CATCH
+ }
+__eh_notification;
+
+/* Is exception-handling support available with this executable? */
+static int hp_cxx_exception_support = 0;
+/* Has the initialize function been run? */
+int hp_cxx_exception_support_initialized = 0;
+/* Similar to above, but imported from breakpoint.c -- non-target-specific */
+extern int exception_support_initialized;
+/* Address of __eh_notify_hook */
+static CORE_ADDR eh_notify_hook_addr = 0;
+/* Address of __d_eh_notify_callback */
+static CORE_ADDR eh_notify_callback_addr = 0;
+/* Address of __d_eh_break */
+static CORE_ADDR eh_break_addr = 0;
+/* Address of __d_eh_catch_catch */
+static CORE_ADDR eh_catch_catch_addr = 0;
+/* Address of __d_eh_catch_throw */
+static CORE_ADDR eh_catch_throw_addr = 0;
+/* Sal for __d_eh_break */
+static struct symtab_and_line *break_callback_sal = 0;
+
+/* Code in end.c expects __d_pid to be set in the inferior,
+ otherwise __d_eh_notify_callback doesn't bother to call
+ __d_eh_break! So we poke the pid into this symbol
+ ourselves.
+ 0 => success
+ 1 => failure */
+int
+setup_d_pid_in_inferior (void)
+{
+ CORE_ADDR anaddr;
+ struct minimal_symbol *msymbol;
+ char buf[4]; /* FIXME 32x64? */
+
+ /* Slam the pid of the process into __d_pid; failing is only a warning! */
+ msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile);
+ if (msymbol == NULL)
+ {
+ warning ("Unable to find __d_pid symbol in object file.");
+ warning ("Suggest linking executable with -g (links in /opt/langtools/lib/end.o).");
+ return 1;
+ }
+
+ anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+ store_unsigned_integer (buf, 4, PIDGET (inferior_ptid)); /* FIXME 32x64? */
+ if (target_write_memory (anaddr, buf, 4)) /* FIXME 32x64? */
+ {
+ warning ("Unable to write __d_pid");
+ warning ("Suggest linking executable with -g (links in /opt/langtools/lib/end.o).");
+ return 1;
+ }
+ return 0;
+}
+
+/* Initialize exception catchpoint support by looking for the
+ necessary hooks/callbacks in end.o, etc., and set the hook value to
+ point to the required debug function
+
+ Return 0 => failure
+ 1 => success */
+
+static int
+initialize_hp_cxx_exception_support (void)
+{
+ struct symtabs_and_lines sals;
+ struct cleanup *old_chain;
+ struct cleanup *canonical_strings_chain = NULL;
+ int i;
+ char *addr_start;
+ char *addr_end = NULL;
+ char **canonical = (char **) NULL;
+ int thread = -1;
+ struct symbol *sym = NULL;
+ struct minimal_symbol *msym = NULL;
+ struct objfile *objfile;
+ asection *shlib_info;
+
+ /* Detect and disallow recursion. On HP-UX with aCC, infinite
+ recursion is a possibility because finding the hook for exception
+ callbacks involves making a call in the inferior, which means
+ re-inserting breakpoints which can re-invoke this code */
+
+ static int recurse = 0;
+ if (recurse > 0)
+ {
+ hp_cxx_exception_support_initialized = 0;
+ exception_support_initialized = 0;
+ return 0;
+ }
+
+ hp_cxx_exception_support = 0;
+
+ /* First check if we have seen any HP compiled objects; if not,
+ it is very unlikely that HP's idiosyncratic callback mechanism
+ for exception handling debug support will be available!
+ This will percolate back up to breakpoint.c, where our callers
+ will decide to try the g++ exception-handling support instead. */
+ if (!hp_som_som_object_present)
+ return 0;
+
+ /* We have a SOM executable with SOM debug info; find the hooks */
+
+ /* First look for the notify hook provided by aCC runtime libs */
+ /* If we find this symbol, we conclude that the executable must
+ have HP aCC exception support built in. If this symbol is not
+ found, even though we're a HP SOM-SOM file, we may have been
+ built with some other compiler (not aCC). This results percolates
+ back up to our callers in breakpoint.c which can decide to
+ try the g++ style of exception support instead.
+ If this symbol is found but the other symbols we require are
+ not found, there is something weird going on, and g++ support
+ should *not* be tried as an alternative.
+
+ ASSUMPTION: Only HP aCC code will have __eh_notify_hook defined.
+ ASSUMPTION: HP aCC and g++ modules cannot be linked together. */
+
+ /* libCsup has this hook; it'll usually be non-debuggable */
+ msym = lookup_minimal_symbol (HP_ACC_EH_notify_hook, NULL, NULL);
+ if (msym)
+ {
+ eh_notify_hook_addr = SYMBOL_VALUE_ADDRESS (msym);
+ hp_cxx_exception_support = 1;
+ }
+ else
+ {
+ warning ("Unable to find exception callback hook (%s).", HP_ACC_EH_notify_hook);
+ warning ("Executable may not have been compiled debuggable with HP aCC.");
+ warning ("GDB will be unable to intercept exception events.");
+ eh_notify_hook_addr = 0;
+ hp_cxx_exception_support = 0;
+ return 0;
+ }
+
+ /* Next look for the notify callback routine in end.o */
+ /* This is always available in the SOM symbol dictionary if end.o is linked in */
+ msym = lookup_minimal_symbol (HP_ACC_EH_notify_callback, NULL, NULL);
+ if (msym)
+ {
+ eh_notify_callback_addr = SYMBOL_VALUE_ADDRESS (msym);
+ hp_cxx_exception_support = 1;
+ }
+ else
+ {
+ warning ("Unable to find exception callback routine (%s).", HP_ACC_EH_notify_callback);
+ warning ("Suggest linking executable with -g (links in /opt/langtools/lib/end.o).");
+ warning ("GDB will be unable to intercept exception events.");
+ eh_notify_callback_addr = 0;
+ return 0;
+ }
+
+#ifndef GDB_TARGET_IS_HPPA_20W
+ /* Check whether the executable is dynamically linked or archive bound */
+ /* With an archive-bound executable we can use the raw addresses we find
+ for the callback function, etc. without modification. For an executable
+ with shared libraries, we have to do more work to find the plabel, which
+ can be the target of a call through $$dyncall from the aCC runtime support
+ library (libCsup) which is linked shared by default by aCC. */
+ /* This test below was copied from somsolib.c/somread.c. It may not be a very
+ reliable one to test that an executable is linked shared. pai/1997-07-18 */
+ shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
+ if (shlib_info && (bfd_section_size (symfile_objfile->obfd, shlib_info) != 0))
+ {
+ /* The minsym we have has the local code address, but that's not the
+ plabel that can be used by an inter-load-module call. */
+ /* Find solib handle for main image (which has end.o), and use that
+ and the min sym as arguments to __d_shl_get() (which does the equivalent
+ of shl_findsym()) to find the plabel. */
+
+ args_for_find_stub args;
+ static char message[] = "Error while finding exception callback hook:\n";
+
+ args.solib_handle = som_solib_get_solib_by_pc (eh_notify_callback_addr);
+ args.msym = msym;
+ args.return_val = 0;
+
+ recurse++;
+ catch_errors (cover_find_stub_with_shl_get, (PTR) &args, message,
+ RETURN_MASK_ALL);
+ eh_notify_callback_addr = args.return_val;
+ recurse--;
+
+ exception_catchpoints_are_fragile = 1;
+
+ if (!eh_notify_callback_addr)
+ {
+ /* We can get here either if there is no plabel in the export list
+ for the main image, or if something strange happened (?) */
+ warning ("Couldn't find a plabel (indirect function label) for the exception callback.");
+ warning ("GDB will not be able to intercept exception events.");
+ return 0;
+ }
+ }
+ else
+ exception_catchpoints_are_fragile = 0;
+#endif
+
+ /* Now, look for the breakpointable routine in end.o */
+ /* This should also be available in the SOM symbol dict. if end.o linked in */
+ msym = lookup_minimal_symbol (HP_ACC_EH_break, NULL, NULL);
+ if (msym)
+ {
+ eh_break_addr = SYMBOL_VALUE_ADDRESS (msym);
+ hp_cxx_exception_support = 1;
+ }
+ else
+ {
+ warning ("Unable to find exception callback routine to set breakpoint (%s).", HP_ACC_EH_break);
+ warning ("Suggest linking executable with -g (link in /opt/langtools/lib/end.o).");
+ warning ("GDB will be unable to intercept exception events.");
+ eh_break_addr = 0;
+ return 0;
+ }
+
+ /* Next look for the catch enable flag provided in end.o */
+ sym = lookup_symbol (HP_ACC_EH_catch_catch, (struct block *) NULL,
+ VAR_NAMESPACE, 0, (struct symtab **) NULL);
+ if (sym) /* sometimes present in debug info */
+ {
+ eh_catch_catch_addr = SYMBOL_VALUE_ADDRESS (sym);
+ hp_cxx_exception_support = 1;
+ }
+ else
+ /* otherwise look in SOM symbol dict. */
+ {
+ msym = lookup_minimal_symbol (HP_ACC_EH_catch_catch, NULL, NULL);
+ if (msym)
+ {
+ eh_catch_catch_addr = SYMBOL_VALUE_ADDRESS (msym);
+ hp_cxx_exception_support = 1;
+ }
+ else
+ {
+ warning ("Unable to enable interception of exception catches.");
+ warning ("Executable may not have been compiled debuggable with HP aCC.");
+ warning ("Suggest linking executable with -g (link in /opt/langtools/lib/end.o).");
+ return 0;
+ }
+ }
+
+ /* Next look for the catch enable flag provided end.o */
+ sym = lookup_symbol (HP_ACC_EH_catch_catch, (struct block *) NULL,
+ VAR_NAMESPACE, 0, (struct symtab **) NULL);
+ if (sym) /* sometimes present in debug info */
+ {
+ eh_catch_throw_addr = SYMBOL_VALUE_ADDRESS (sym);
+ hp_cxx_exception_support = 1;
+ }
+ else
+ /* otherwise look in SOM symbol dict. */
+ {
+ msym = lookup_minimal_symbol (HP_ACC_EH_catch_throw, NULL, NULL);
+ if (msym)
+ {
+ eh_catch_throw_addr = SYMBOL_VALUE_ADDRESS (msym);
+ hp_cxx_exception_support = 1;
+ }
+ else
+ {
+ warning ("Unable to enable interception of exception throws.");
+ warning ("Executable may not have been compiled debuggable with HP aCC.");
+ warning ("Suggest linking executable with -g (link in /opt/langtools/lib/end.o).");
+ return 0;
+ }
+ }
+
+ /* Set the flags */
+ hp_cxx_exception_support = 2; /* everything worked so far */
+ hp_cxx_exception_support_initialized = 1;
+ exception_support_initialized = 1;
+
+ return 1;
+}
+
+/* Target operation for enabling or disabling interception of
+ exception events.
+ KIND is either EX_EVENT_THROW or EX_EVENT_CATCH
+ ENABLE is either 0 (disable) or 1 (enable).
+ Return value is NULL if no support found;
+ -1 if something went wrong,
+ or a pointer to a symtab/line struct if the breakpointable
+ address was found. */
+
+struct symtab_and_line *
+child_enable_exception_callback (enum exception_event_kind kind, int enable)
+{
+ char buf[4];
+
+ if (!exception_support_initialized || !hp_cxx_exception_support_initialized)
+ if (!initialize_hp_cxx_exception_support ())
+ return NULL;
+
+ switch (hp_cxx_exception_support)
+ {
+ case 0:
+ /* Assuming no HP support at all */
+ return NULL;
+ case 1:
+ /* HP support should be present, but something went wrong */
+ return (struct symtab_and_line *) -1; /* yuck! */
+ /* there may be other cases in the future */
+ }
+
+ /* Set the EH hook to point to the callback routine */
+ store_unsigned_integer (buf, 4, enable ? eh_notify_callback_addr : 0); /* FIXME 32x64 problem */
+ /* pai: (temp) FIXME should there be a pack operation first? */
+ if (target_write_memory (eh_notify_hook_addr, buf, 4)) /* FIXME 32x64 problem */
+ {
+ warning ("Could not write to target memory for exception event callback.");
+ warning ("Interception of exception events may not work.");
+ return (struct symtab_and_line *) -1;
+ }
+ if (enable)
+ {
+ /* Ensure that __d_pid is set up correctly -- end.c code checks this. :-( */
+ if (PIDGET (inferior_ptid) > 0)
+ {
+ if (setup_d_pid_in_inferior ())
+ return (struct symtab_and_line *) -1;
+ }
+ else
+ {
+ warning ("Internal error: Invalid inferior pid? Cannot intercept exception events.");
+ return (struct symtab_and_line *) -1;
+ }
+ }
+
+ switch (kind)
+ {
+ case EX_EVENT_THROW:
+ store_unsigned_integer (buf, 4, enable ? 1 : 0);
+ if (target_write_memory (eh_catch_throw_addr, buf, 4)) /* FIXME 32x64? */
+ {
+ warning ("Couldn't enable exception throw interception.");
+ return (struct symtab_and_line *) -1;
+ }
+ break;
+ case EX_EVENT_CATCH:
+ store_unsigned_integer (buf, 4, enable ? 1 : 0);
+ if (target_write_memory (eh_catch_catch_addr, buf, 4)) /* FIXME 32x64? */
+ {
+ warning ("Couldn't enable exception catch interception.");
+ return (struct symtab_and_line *) -1;
+ }
+ break;
+ default:
+ error ("Request to enable unknown or unsupported exception event.");
+ }
+
+ /* Copy break address into new sal struct, malloc'ing if needed. */
+ if (!break_callback_sal)
+ {
+ break_callback_sal = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line));
+ }
+ INIT_SAL (break_callback_sal);
+ break_callback_sal->symtab = NULL;
+ break_callback_sal->pc = eh_break_addr;
+ break_callback_sal->line = 0;
+ break_callback_sal->end = eh_break_addr;
+
+ return break_callback_sal;
+}
+
+/* Record some information about the current exception event */
+static struct exception_event_record current_ex_event;
+/* Convenience struct */
+static struct symtab_and_line null_symtab_and_line =
+{NULL, 0, 0, 0};
+
+/* Report current exception event. Returns a pointer to a record
+ that describes the kind of the event, where it was thrown from,
+ and where it will be caught. More information may be reported
+ in the future */
+struct exception_event_record *
+child_get_current_exception_event (void)
+{
+ CORE_ADDR event_kind;
+ CORE_ADDR throw_addr;
+ CORE_ADDR catch_addr;
+ struct frame_info *fi, *curr_frame;
+ int level = 1;
+
+ curr_frame = get_current_frame ();
+ if (!curr_frame)
+ return (struct exception_event_record *) NULL;
+
+ /* Go up one frame to __d_eh_notify_callback, because at the
+ point when this code is executed, there's garbage in the
+ arguments of __d_eh_break. */
+ fi = find_relative_frame (curr_frame, &level);
+ if (level != 0)
+ return (struct exception_event_record *) NULL;
+
+ select_frame (fi);
+
+ /* Read in the arguments */
+ /* __d_eh_notify_callback() is called with 3 arguments:
+ 1. event kind catch or throw
+ 2. the target address if known
+ 3. a flag -- not sure what this is. pai/1997-07-17 */
+ event_kind = read_register (ARG0_REGNUM);
+ catch_addr = read_register (ARG1_REGNUM);
+
+ /* Now go down to a user frame */
+ /* For a throw, __d_eh_break is called by
+ __d_eh_notify_callback which is called by
+ __notify_throw which is called
+ from user code.
+ For a catch, __d_eh_break is called by
+ __d_eh_notify_callback which is called by
+ <stackwalking stuff> which is called by
+ __throw__<stuff> or __rethrow_<stuff> which is called
+ from user code. */
+ /* FIXME: Don't use such magic numbers; search for the frames */
+ level = (event_kind == EX_EVENT_THROW) ? 3 : 4;
+ fi = find_relative_frame (curr_frame, &level);
+ if (level != 0)
+ return (struct exception_event_record *) NULL;
+
+ select_frame (fi);
+ throw_addr = fi->pc;
+
+ /* Go back to original (top) frame */
+ select_frame (curr_frame);
+
+ current_ex_event.kind = (enum exception_event_kind) event_kind;
+ current_ex_event.throw_sal = find_pc_line (throw_addr, 1);
+ current_ex_event.catch_sal = find_pc_line (catch_addr, 1);
+
+ return &current_ex_event;
+}
+
+static void
+unwind_command (char *exp, int from_tty)
+{
+ CORE_ADDR address;
+ struct unwind_table_entry *u;
+
+ /* If we have an expression, evaluate it and use it as the address. */
+
+ if (exp != 0 && *exp != 0)
+ address = parse_and_eval_address (exp);
+ else
+ return;
+
+ u = find_unwind_entry (address);
+
+ if (!u)
+ {
+ printf_unfiltered ("Can't find unwind table entry for %s\n", exp);
+ return;
+ }
+
+ printf_unfiltered ("unwind_table_entry (0x%s):\n",
+ paddr_nz (host_pointer_to_address (u)));
+
+ printf_unfiltered ("\tregion_start = ");
+ print_address (u->region_start, gdb_stdout);
+
+ printf_unfiltered ("\n\tregion_end = ");
+ print_address (u->region_end, gdb_stdout);
+
+#define pif(FLD) if (u->FLD) printf_unfiltered (" "#FLD);
+
+ printf_unfiltered ("\n\tflags =");
+ pif (Cannot_unwind);
+ pif (Millicode);
+ pif (Millicode_save_sr0);
+ pif (Entry_SR);
+ pif (Args_stored);
+ pif (Variable_Frame);
+ pif (Separate_Package_Body);
+ pif (Frame_Extension_Millicode);
+ pif (Stack_Overflow_Check);
+ pif (Two_Instruction_SP_Increment);
+ pif (Ada_Region);
+ pif (Save_SP);
+ pif (Save_RP);
+ pif (Save_MRP_in_frame);
+ pif (extn_ptr_defined);
+ pif (Cleanup_defined);
+ pif (MPE_XL_interrupt_marker);
+ pif (HP_UX_interrupt_marker);
+ pif (Large_frame);
+
+ putchar_unfiltered ('\n');
+
+#define pin(FLD) printf_unfiltered ("\t"#FLD" = 0x%x\n", u->FLD);
+
+ pin (Region_description);
+ pin (Entry_FR);
+ pin (Entry_GR);
+ pin (Total_frame_size);
+}
+
+#ifdef PREPARE_TO_PROCEED
+
+/* If the user has switched threads, and there is a breakpoint
+ at the old thread's pc location, then switch to that thread
+ and return TRUE, else return FALSE and don't do a thread
+ switch (or rather, don't seem to have done a thread switch).
+
+ Ptrace-based gdb will always return FALSE to the thread-switch
+ query, and thus also to PREPARE_TO_PROCEED.
+
+ The important thing is whether there is a BPT instruction,
+ not how many user breakpoints there are. So we have to worry
+ about things like these:
+
+ o Non-bp stop -- NO
+
+ o User hits bp, no switch -- NO
+
+ o User hits bp, switches threads -- YES
+
+ o User hits bp, deletes bp, switches threads -- NO
+
+ o User hits bp, deletes one of two or more bps
+ at that PC, user switches threads -- YES
+
+ o Plus, since we're buffering events, the user may have hit a
+ breakpoint, deleted the breakpoint and then gotten another
+ hit on that same breakpoint on another thread which
+ actually hit before the delete. (FIXME in breakpoint.c
+ so that "dead" breakpoints are ignored?) -- NO
+
+ For these reasons, we have to violate information hiding and
+ call "breakpoint_here_p". If core gdb thinks there is a bpt
+ here, that's what counts, as core gdb is the one which is
+ putting the BPT instruction in and taking it out.
+
+ Note that this implementation is potentially redundant now that
+ default_prepare_to_proceed() has been added.
+
+ FIXME This may not support switching threads after Ctrl-C
+ correctly. The default implementation does support this. */
+int
+hppa_prepare_to_proceed (void)
+{
+ pid_t old_thread;
+ pid_t current_thread;
+
+ old_thread = hppa_switched_threads (PIDGET (inferior_ptid));
+ if (old_thread != 0)
+ {
+ /* Switched over from "old_thread". Try to do
+ as little work as possible, 'cause mostly
+ we're going to switch back. */
+ CORE_ADDR new_pc;
+ CORE_ADDR old_pc = read_pc ();
+
+ /* Yuk, shouldn't use global to specify current
+ thread. But that's how gdb does it. */
+ current_thread = PIDGET (inferior_ptid);
+ inferior_ptid = pid_to_ptid (old_thread);
+
+ new_pc = read_pc ();
+ if (new_pc != old_pc /* If at same pc, no need */
+ && breakpoint_here_p (new_pc))
+ {
+ /* User hasn't deleted the BP.
+ Return TRUE, finishing switch to "old_thread". */
+ flush_cached_frames ();
+ registers_changed ();
+#if 0
+ printf ("---> PREPARE_TO_PROCEED (was %d, now %d)!\n",
+ current_thread, PIDGET (inferior_ptid));
+#endif
+
+ return 1;
+ }
+
+ /* Otherwise switch back to the user-chosen thread. */
+ inferior_ptid = pid_to_ptid (current_thread);
+ new_pc = read_pc (); /* Re-prime register cache */
+ }
+
+ return 0;
+}
+#endif /* PREPARE_TO_PROCEED */
+
+void
+hppa_skip_permanent_breakpoint (void)
+{
+ /* To step over a breakpoint instruction on the PA takes some
+ fiddling with the instruction address queue.
+
+ When we stop at a breakpoint, the IA queue front (the instruction
+ we're executing now) points at the breakpoint instruction, and
+ the IA queue back (the next instruction to execute) points to
+ whatever instruction we would execute after the breakpoint, if it
+ were an ordinary instruction. This is the case even if the
+ breakpoint is in the delay slot of a branch instruction.
+
+ Clearly, to step past the breakpoint, we need to set the queue
+ front to the back. But what do we put in the back? What
+ instruction comes after that one? Because of the branch delay
+ slot, the next insn is always at the back + 4. */
+ write_register (PCOQ_HEAD_REGNUM, read_register (PCOQ_TAIL_REGNUM));
+ write_register (PCSQ_HEAD_REGNUM, read_register (PCSQ_TAIL_REGNUM));
+
+ write_register (PCOQ_TAIL_REGNUM, read_register (PCOQ_TAIL_REGNUM) + 4);
+ /* We can leave the tail's space the same, since there's no jump. */
+}
+
+void
+_initialize_hppa_tdep (void)
+{
+ struct cmd_list_element *c;
+ void break_at_finish_command (char *arg, int from_tty);
+ void tbreak_at_finish_command (char *arg, int from_tty);
+ void break_at_finish_at_depth_command (char *arg, int from_tty);
+
+ tm_print_insn = print_insn_hppa;
+
+ add_cmd ("unwind", class_maintenance, unwind_command,
+ "Print unwind table entry at given address.",
+ &maintenanceprintlist);
+
+ deprecate_cmd (add_com ("xbreak", class_breakpoint,
+ break_at_finish_command,
+ concat ("Set breakpoint at procedure exit. \n\
+Argument may be function name, or \"*\" and an address.\n\
+If function is specified, break at end of code for that function.\n\
+If an address is specified, break at the end of the function that contains \n\
+that exact address.\n",
+ "With no arg, uses current execution address of selected stack frame.\n\
+This is useful for breaking on return to a stack frame.\n\
+\n\
+Multiple breakpoints at one place are permitted, and useful if conditional.\n\
+\n\
+Do \"help breakpoints\" for info on other commands dealing with breakpoints.", NULL)), NULL);
+ deprecate_cmd (add_com_alias ("xb", "xbreak", class_breakpoint, 1), NULL);
+ deprecate_cmd (add_com_alias ("xbr", "xbreak", class_breakpoint, 1), NULL);
+ deprecate_cmd (add_com_alias ("xbre", "xbreak", class_breakpoint, 1), NULL);
+ deprecate_cmd (add_com_alias ("xbrea", "xbreak", class_breakpoint, 1), NULL);
+
+ deprecate_cmd (c = add_com ("txbreak", class_breakpoint,
+ tbreak_at_finish_command,
+"Set temporary breakpoint at procedure exit. Either there should\n\
+be no argument or the argument must be a depth.\n"), NULL);
+ set_cmd_completer (c, location_completer);
+
+ if (xdb_commands)
+ deprecate_cmd (add_com ("bx", class_breakpoint,
+ break_at_finish_at_depth_command,
+"Set breakpoint at procedure exit. Either there should\n\
+be no argument or the argument must be a depth.\n"), NULL);
+}
+
+/* Copy the function value from VALBUF into the proper location
+ for a function return.
+
+ Called only in the context of the "return" command. */
+
+void
+hppa_store_return_value (struct type *type, char *valbuf)
+{
+ /* For software floating point, the return value goes into the
+ integer registers. But we do not have any flag to key this on,
+ so we always store the value into the integer registers.
+
+ If its a float value, then we also store it into the floating
+ point registers. */
+ write_register_bytes (REGISTER_BYTE (28)
+ + (TYPE_LENGTH (type) > 4
+ ? (8 - TYPE_LENGTH (type))
+ : (4 - TYPE_LENGTH (type))),
+ valbuf,
+ TYPE_LENGTH (type));
+ if (! SOFT_FLOAT && TYPE_CODE (type) == TYPE_CODE_FLT)
+ write_register_bytes (REGISTER_BYTE (FP4_REGNUM),
+ valbuf,
+ TYPE_LENGTH (type));
+}
+
+/* Copy the function's return value into VALBUF.
+
+ This function is called only in the context of "target function calls",
+ ie. when the debugger forces a function to be called in the child, and
+ when the debugger forces a fucntion to return prematurely via the
+ "return" command. */
+
+void
+hppa_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ if (! SOFT_FLOAT && TYPE_CODE (type) == TYPE_CODE_FLT)
+ memcpy (valbuf,
+ (char *)regbuf + REGISTER_BYTE (FP4_REGNUM),
+ TYPE_LENGTH (type));
+ else
+ memcpy (valbuf,
+ ((char *)regbuf
+ + REGISTER_BYTE (28)
+ + (TYPE_LENGTH (type) > 4
+ ? (8 - TYPE_LENGTH (type))
+ : (4 - TYPE_LENGTH (type)))),
+ TYPE_LENGTH (type));
+}
diff --git a/gdb/hppab-nat.c b/gdb/hppab-nat.c
new file mode 100644
index 00000000000..51dde60508e
--- /dev/null
+++ b/gdb/hppab-nat.c
@@ -0,0 +1,214 @@
+/* Machine-dependent hooks for the unix child process stratum. This
+ code is for the HP PA-RISC cpu.
+
+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1998,
+ 1999, 2000, 2001 Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+ 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 "defs.h"
+#include "inferior.h"
+#include "target.h"
+#include "regcache.h"
+#include <sys/ptrace.h>
+
+/* Use an extra level of indirection for ptrace calls.
+ This lets us breakpoint usefully on call_ptrace. It also
+ allows us to pass an extra argument to ptrace without
+ using an ANSI-C specific macro. */
+
+#define ptrace call_ptrace
+
+#if !defined (offsetof)
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+#endif
+
+/* U_REGS_OFFSET is the offset of the registers within the u area. */
+#if !defined (U_REGS_OFFSET)
+#define U_REGS_OFFSET \
+ ptrace (PT_READ_U, PIDGET (inferior_ptid), \
+ (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
+ - KERNEL_U_ADDR
+#endif
+
+/* Fetch one register. */
+
+static void
+fetch_register (int regno)
+{
+ register unsigned int regaddr;
+ char buf[MAX_REGISTER_RAW_SIZE];
+ register int i;
+
+ /* Offset of registers within the u area. */
+ unsigned int offset;
+
+ offset = U_REGS_OFFSET;
+
+ regaddr = register_addr (regno, offset);
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+ {
+ errno = 0;
+ *(int *) &buf[i] = ptrace (PT_RUREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) regaddr, 0);
+ regaddr += sizeof (int);
+ if (errno != 0)
+ {
+ /* Warning, not error, in case we are attached; sometimes the
+ kernel doesn't let us at the registers. */
+ char *err = safe_strerror (errno);
+ char *msg = alloca (strlen (err) + 128);
+ sprintf (msg, "reading register %s: %s", REGISTER_NAME (regno), err);
+ warning (msg);
+ goto error_exit;
+ }
+ }
+ supply_register (regno, buf);
+error_exit:;
+}
+
+/* Fetch all registers, or just one, from the child process. */
+
+void
+fetch_inferior_registers (int regno)
+{
+ if (regno == -1)
+ for (regno = 0; regno < NUM_REGS; regno++)
+ fetch_register (regno);
+ else
+ fetch_register (regno);
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ register unsigned int regaddr;
+ char buf[80];
+ register int i;
+ unsigned int offset = U_REGS_OFFSET;
+ int scratch;
+
+ if (regno >= 0)
+ {
+ if (CANNOT_STORE_REGISTER (regno))
+ return;
+ regaddr = register_addr (regno, offset);
+ errno = 0;
+ if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
+ {
+ scratch = *(int *) &registers[REGISTER_BYTE (regno)] | 0x3;
+ ptrace (PT_WUREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr,
+ scratch);
+ if (errno != 0)
+ {
+ /* Error, even if attached. Failing to write these two
+ registers is pretty serious. */
+ sprintf (buf, "writing register number %d", regno);
+ perror_with_name (buf);
+ }
+ }
+ else
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+ {
+ errno = 0;
+ ptrace (PT_WUREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) regaddr,
+ *(int *) &registers[REGISTER_BYTE (regno) + i]);
+ if (errno != 0)
+ {
+ /* Warning, not error, in case we are attached; sometimes the
+ kernel doesn't let us at the registers. */
+ char *err = safe_strerror (errno);
+ char *msg = alloca (strlen (err) + 128);
+ sprintf (msg, "writing register %s: %s",
+ REGISTER_NAME (regno), err);
+ warning (msg);
+ return;
+ }
+ regaddr += sizeof (int);
+ }
+ }
+ else
+ for (regno = 0; regno < NUM_REGS; regno++)
+ store_inferior_registers (regno);
+}
+
+/* PT_PROT is specific to the PA BSD kernel and isn't documented
+ anywhere (except here).
+
+ PT_PROT allows one to enable/disable the data memory break bit
+ for pages of memory in an inferior process. This bit is used
+ to cause "Data memory break traps" to occur when the appropriate
+ page is written to.
+
+ The arguments are as follows:
+
+ PT_PROT -- The ptrace action to perform.
+
+ INFERIOR_PID -- The pid of the process who's page table entries
+ will be modified.
+
+ PT_ARGS -- The *address* of a 3 word block of memory which has
+ additional information:
+
+ word 0 -- The start address to watch. This should be a page-aligned
+ address.
+
+ word 1 -- The ending address to watch. Again, this should be a
+ page aligned address.
+
+ word 2 -- Nonzero to enable the data memory break bit on the
+ given address range or zero to disable the data memory break
+ bit on the given address range.
+
+ This call may fail if the given addresses are not valid in the inferior
+ process. This most often happens when restarting a program which
+ has watchpoints inserted on heap or stack memory. */
+
+#define PT_PROT 21
+
+int
+hppa_set_watchpoint (int addr, int len, int flag)
+{
+ int pt_args[3];
+ pt_args[0] = addr;
+ pt_args[1] = addr + len;
+ pt_args[2] = flag;
+
+ /* Mask off the lower 12 bits since we want to work on a page basis. */
+ pt_args[0] >>= 12;
+ pt_args[1] >>= 12;
+
+ /* Rounding adjustments. */
+ pt_args[1] -= pt_args[0];
+ pt_args[1]++;
+
+ /* Put the lower 12 bits back as zero. */
+ pt_args[0] <<= 12;
+ pt_args[1] <<= 12;
+
+ /* Do it. */
+ return ptrace (PT_PROT, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) pt_args, 0);
+}
diff --git a/gdb/hppah-nat.c b/gdb/hppah-nat.c
new file mode 100644
index 00000000000..aab5e96ccf3
--- /dev/null
+++ b/gdb/hppah-nat.c
@@ -0,0 +1,1140 @@
+/* Native support code for HPUX PA-RISC.
+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+ 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 "defs.h"
+#include "inferior.h"
+#include "target.h"
+#include <sys/ptrace.h>
+#include "gdbcore.h"
+#include "gdb_wait.h"
+#include "regcache.h"
+#include <signal.h>
+
+extern CORE_ADDR text_end;
+
+static void fetch_register (int);
+
+void
+fetch_inferior_registers (int regno)
+{
+ if (regno == -1)
+ for (regno = 0; regno < NUM_REGS; regno++)
+ fetch_register (regno);
+ else
+ fetch_register (regno);
+}
+
+/* Our own version of the offsetof macro, since we can't assume ANSI C. */
+#define HPPAH_OFFSETOF(type, member) ((int) (&((type *) 0)->member))
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ register unsigned int regaddr;
+ char buf[80];
+ register int i;
+ unsigned int offset = U_REGS_OFFSET;
+ int scratch;
+
+ if (regno >= 0)
+ {
+ unsigned int addr, len, offset;
+
+ if (CANNOT_STORE_REGISTER (regno))
+ return;
+
+ offset = 0;
+ len = REGISTER_RAW_SIZE (regno);
+
+ /* Requests for register zero actually want the save_state's
+ ss_flags member. As RM says: "Oh, what a hack!" */
+ if (regno == 0)
+ {
+ save_state_t ss;
+ addr = HPPAH_OFFSETOF (save_state_t, ss_flags);
+ len = sizeof (ss.ss_flags);
+
+ /* Note that ss_flags is always an int, no matter what
+ REGISTER_RAW_SIZE(0) says. Assuming all HP-UX PA machines
+ are big-endian, put it at the least significant end of the
+ value, and zap the rest of the buffer. */
+ offset = REGISTER_RAW_SIZE (0) - len;
+ }
+
+ /* Floating-point registers come from the ss_fpblock area. */
+ else if (regno >= FP0_REGNUM)
+ addr = (HPPAH_OFFSETOF (save_state_t, ss_fpblock)
+ + (REGISTER_BYTE (regno) - REGISTER_BYTE (FP0_REGNUM)));
+
+ /* Wide registers come from the ss_wide area.
+ I think it's more PC to test (ss_flags & SS_WIDEREGS) to select
+ between ss_wide and ss_narrow than to use the raw register size.
+ But checking ss_flags would require an extra ptrace call for
+ every register reference. Bleah. */
+ else if (len == 8)
+ addr = (HPPAH_OFFSETOF (save_state_t, ss_wide)
+ + REGISTER_BYTE (regno));
+
+ /* Narrow registers come from the ss_narrow area. Note that
+ ss_narrow starts with gr1, not gr0. */
+ else if (len == 4)
+ addr = (HPPAH_OFFSETOF (save_state_t, ss_narrow)
+ + (REGISTER_BYTE (regno) - REGISTER_BYTE (1)));
+ else
+ internal_error (__FILE__, __LINE__,
+ "hppah-nat.c (write_register): unexpected register size");
+
+#ifdef GDB_TARGET_IS_HPPA_20W
+ /* Unbelieveable. The PC head and tail must be written in 64bit hunks
+ or we will get an error. Worse yet, the oddball ptrace/ttrace
+ layering will not allow us to perform a 64bit register store.
+
+ What a crock. */
+ if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM && len == 8)
+ {
+ CORE_ADDR temp;
+
+ temp = *(CORE_ADDR *)&registers[REGISTER_BYTE (regno)];
+
+ /* Set the priv level (stored in the low two bits of the PC. */
+ temp |= 0x3;
+
+ ttrace_write_reg_64 (PIDGET (inferior_ptid), (CORE_ADDR)addr,
+ (CORE_ADDR)&temp);
+
+ /* If we fail to write the PC, give a true error instead of
+ just a warning. */
+ if (errno != 0)
+ {
+ char *err = safe_strerror (errno);
+ char *msg = alloca (strlen (err) + 128);
+ sprintf (msg, "writing `%s' register: %s",
+ REGISTER_NAME (regno), err);
+ perror_with_name (msg);
+ }
+ return;
+ }
+
+ /* Another crock. HPUX complains if you write a nonzero value to
+ the high part of IPSW. What will it take for HP to catch a
+ clue about building sensible interfaces? */
+ if (regno == IPSW_REGNUM && len == 8)
+ *(int *)&registers[REGISTER_BYTE (regno)] = 0;
+#endif
+
+ for (i = 0; i < len; i += sizeof (int))
+ {
+ errno = 0;
+ call_ptrace (PT_WUREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) addr + i,
+ *(int *) &registers[REGISTER_BYTE (regno) + i]);
+ if (errno != 0)
+ {
+ /* Warning, not error, in case we are attached; sometimes
+ the kernel doesn't let us at the registers. */
+ char *err = safe_strerror (errno);
+ char *msg = alloca (strlen (err) + 128);
+ sprintf (msg, "writing `%s' register: %s",
+ REGISTER_NAME (regno), err);
+ /* If we fail to write the PC, give a true error instead of
+ just a warning. */
+ if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
+ perror_with_name (msg);
+ else
+ warning (msg);
+ return;
+ }
+ }
+ }
+ else
+ for (regno = 0; regno < NUM_REGS; regno++)
+ store_inferior_registers (regno);
+}
+
+
+/* Fetch a register's value from the process's U area. */
+static void
+fetch_register (int regno)
+{
+ char buf[MAX_REGISTER_RAW_SIZE];
+ unsigned int addr, len, offset;
+ int i;
+
+ offset = 0;
+ len = REGISTER_RAW_SIZE (regno);
+
+ /* Requests for register zero actually want the save_state's
+ ss_flags member. As RM says: "Oh, what a hack!" */
+ if (regno == 0)
+ {
+ save_state_t ss;
+ addr = HPPAH_OFFSETOF (save_state_t, ss_flags);
+ len = sizeof (ss.ss_flags);
+
+ /* Note that ss_flags is always an int, no matter what
+ REGISTER_RAW_SIZE(0) says. Assuming all HP-UX PA machines
+ are big-endian, put it at the least significant end of the
+ value, and zap the rest of the buffer. */
+ offset = REGISTER_RAW_SIZE (0) - len;
+ memset (buf, 0, sizeof (buf));
+ }
+
+ /* Floating-point registers come from the ss_fpblock area. */
+ else if (regno >= FP0_REGNUM)
+ addr = (HPPAH_OFFSETOF (save_state_t, ss_fpblock)
+ + (REGISTER_BYTE (regno) - REGISTER_BYTE (FP0_REGNUM)));
+
+ /* Wide registers come from the ss_wide area.
+ I think it's more PC to test (ss_flags & SS_WIDEREGS) to select
+ between ss_wide and ss_narrow than to use the raw register size.
+ But checking ss_flags would require an extra ptrace call for
+ every register reference. Bleah. */
+ else if (len == 8)
+ addr = (HPPAH_OFFSETOF (save_state_t, ss_wide)
+ + REGISTER_BYTE (regno));
+
+ /* Narrow registers come from the ss_narrow area. Note that
+ ss_narrow starts with gr1, not gr0. */
+ else if (len == 4)
+ addr = (HPPAH_OFFSETOF (save_state_t, ss_narrow)
+ + (REGISTER_BYTE (regno) - REGISTER_BYTE (1)));
+
+ else
+ internal_error (__FILE__, __LINE__,
+ "hppa-nat.c (fetch_register): unexpected register size");
+
+ for (i = 0; i < len; i += sizeof (int))
+ {
+ errno = 0;
+ /* Copy an int from the U area to buf. Fill the least
+ significant end if len != raw_size. */
+ * (int *) &buf[offset + i] =
+ call_ptrace (PT_RUREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) addr + i, 0);
+ if (errno != 0)
+ {
+ /* Warning, not error, in case we are attached; sometimes
+ the kernel doesn't let us at the registers. */
+ char *err = safe_strerror (errno);
+ char *msg = alloca (strlen (err) + 128);
+ sprintf (msg, "reading `%s' register: %s",
+ REGISTER_NAME (regno), err);
+ warning (msg);
+ return;
+ }
+ }
+
+ /* If we're reading an address from the instruction address queue,
+ mask out the bottom two bits --- they contain the privilege
+ level. */
+ if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
+ buf[len - 1] &= ~0x3;
+
+ supply_register (regno, buf);
+}
+
+
+/* Copy LEN bytes to or from inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. Copy to inferior if
+ WRITE is nonzero.
+
+ Returns the length copied, which is either the LEN argument or zero.
+ This xfer function does not do partial moves, since child_ops
+ doesn't allow memory operations to cross below us in the target stack
+ anyway. TARGET is ignored. */
+
+int
+child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *mem,
+ struct target_ops *target)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & - (CORE_ADDR)(sizeof (int));
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+
+ /* Allocate buffer of that many longwords.
+ Note -- do not use alloca to allocate this buffer since there is no
+ guarantee of when the buffer will actually be deallocated.
+
+ This routine can be called over and over with the same call chain;
+ this (in effect) would pile up all those alloca requests until a call
+ to alloca was made from a point higher than this routine in the
+ call chain. */
+ register int *buffer = (int *) xmalloc (count * sizeof (int));
+
+ if (write)
+ {
+ /* Fill start and end extra bytes of buffer with existing memory data. */
+ if (addr != memaddr || len < (int) sizeof (int))
+ {
+ /* Need part of initial word -- fetch it. */
+ buffer[0] = call_ptrace (addr < text_end ? PT_RIUSER : PT_RDUSER,
+ PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) addr, 0);
+ }
+
+ if (count > 1) /* FIXME, avoid if even boundary */
+ {
+ buffer[count - 1]
+ = call_ptrace (addr < text_end ? PT_RIUSER : PT_RDUSER,
+ PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) (addr
+ + (count - 1) * sizeof (int)),
+ 0);
+ }
+
+ /* Copy data to be written over corresponding part of buffer */
+ memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
+
+ /* Write the entire buffer. */
+ for (i = 0; i < count; i++, addr += sizeof (int))
+ {
+ int pt_status;
+ int pt_request;
+ /* The HP-UX kernel crashes if you use PT_WDUSER to write into the
+ text segment. FIXME -- does it work to write into the data
+ segment using WIUSER, or do these idiots really expect us to
+ figure out which segment the address is in, so we can use a
+ separate system call for it??! */
+ errno = 0;
+ pt_request = (addr < text_end) ? PT_WIUSER : PT_WDUSER;
+ pt_status = call_ptrace (pt_request,
+ PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) addr,
+ buffer[i]);
+
+ /* Did we fail? Might we've guessed wrong about which
+ segment this address resides in? Try the other request,
+ and see if that works... */
+ if ((pt_status == -1) && errno)
+ {
+ errno = 0;
+ pt_request = (pt_request == PT_WIUSER) ? PT_WDUSER : PT_WIUSER;
+ pt_status = call_ptrace (pt_request,
+ PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) addr,
+ buffer[i]);
+
+ /* No, we still fail. Okay, time to punt. */
+ if ((pt_status == -1) && errno)
+ {
+ xfree (buffer);
+ return 0;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Read all the longwords */
+ for (i = 0; i < count; i++, addr += sizeof (int))
+ {
+ errno = 0;
+ buffer[i] = call_ptrace (addr < text_end ? PT_RIUSER : PT_RDUSER,
+ PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) addr, 0);
+ if (errno)
+ {
+ xfree (buffer);
+ return 0;
+ }
+ QUIT;
+ }
+
+ /* Copy appropriate bytes out of the buffer. */
+ memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
+ }
+ xfree (buffer);
+ return len;
+}
+
+
+void
+child_post_follow_inferior_by_clone (void)
+{
+ int status;
+
+ /* This function is used when following both the parent and child
+ of a fork. In this case, the debugger clones itself. The original
+ debugger follows the parent, the clone follows the child. The
+ original detaches from the child, delivering a SIGSTOP to it to
+ keep it from running away until the clone can attach itself.
+
+ At this point, the clone has attached to the child. Because of
+ the SIGSTOP, we must now deliver a SIGCONT to the child, or it
+ won't behave properly. */
+ status = kill (PIDGET (inferior_ptid), SIGCONT);
+}
+
+
+void
+child_post_follow_vfork (int parent_pid, int followed_parent, int child_pid,
+ int followed_child)
+{
+ /* Are we a debugger that followed the parent of a vfork? If so,
+ then recall that the child's vfork event was delivered to us
+ first. And, that the parent was suspended by the OS until the
+ child's exec or exit events were received.
+
+ Upon receiving that child vfork, then, we were forced to remove
+ all breakpoints in the child and continue it so that it could
+ reach the exec or exit point.
+
+ But also recall that the parent and child of a vfork share the
+ same address space. Thus, removing bp's in the child also
+ removed them from the parent.
+
+ Now that the child has safely exec'd or exited, we must restore
+ the parent's breakpoints before we continue it. Else, we may
+ cause it run past expected stopping points. */
+ if (followed_parent)
+ {
+ reattach_breakpoints (parent_pid);
+ }
+
+ /* Are we a debugger that followed the child of a vfork? If so,
+ then recall that we don't actually acquire control of the child
+ until after it has exec'd or exited. */
+ if (followed_child)
+ {
+ /* If the child has exited, then there's nothing for us to do.
+ In the case of an exec event, we'll let that be handled by
+ the normal mechanism that notices and handles exec events, in
+ resume(). */
+ }
+}
+
+/* Format a process id, given PID. Be sure to terminate
+ this with a null--it's going to be printed via a "%s". */
+char *
+child_pid_to_str (ptid_t ptid)
+{
+ /* Static because address returned */
+ static char buf[30];
+ pid_t pid = PIDGET (ptid);
+
+ /* Extra NUL for paranoia's sake */
+ sprintf (buf, "process %d%c", pid, '\0');
+
+ return buf;
+}
+
+/* Format a thread id, given TID. Be sure to terminate
+ this with a null--it's going to be printed via a "%s".
+
+ Note: This is a core-gdb tid, not the actual system tid.
+ See infttrace.c for details. */
+char *
+hppa_tid_to_str (ptid_t ptid)
+{
+ /* Static because address returned */
+ static char buf[30];
+ /* This seems strange, but when I did the ptid conversion, it looked
+ as though a pid was always being passed. - Kevin Buettner */
+ pid_t tid = PIDGET (ptid);
+
+ /* Extra NULLs for paranoia's sake */
+ sprintf (buf, "system thread %d%c", tid, '\0');
+
+ return buf;
+}
+
+#if !defined (GDB_NATIVE_HPUX_11)
+
+/* The following code is a substitute for the infttrace.c versions used
+ with ttrace() in HPUX 11. */
+
+/* This value is an arbitrary integer. */
+#define PT_VERSION 123456
+
+/* This semaphore is used to coordinate the child and parent processes
+ after a fork(), and before an exec() by the child. See
+ parent_attach_all for details. */
+
+typedef struct
+{
+ int parent_channel[2]; /* Parent "talks" to [1], child "listens" to [0] */
+ int child_channel[2]; /* Child "talks" to [1], parent "listens" to [0] */
+}
+startup_semaphore_t;
+
+#define SEM_TALK (1)
+#define SEM_LISTEN (0)
+
+static startup_semaphore_t startup_semaphore;
+
+extern int parent_attach_all (int, PTRACE_ARG3_TYPE, int);
+
+#ifdef PT_SETTRC
+/* This function causes the caller's process to be traced by its
+ parent. This is intended to be called after GDB forks itself,
+ and before the child execs the target.
+
+ Note that HP-UX ptrace is rather funky in how this is done.
+ If the parent wants to get the initial exec event of a child,
+ it must set the ptrace event mask of the child to include execs.
+ (The child cannot do this itself.) This must be done after the
+ child is forked, but before it execs.
+
+ To coordinate the parent and child, we implement a semaphore using
+ pipes. After SETTRC'ing itself, the child tells the parent that
+ it is now traceable by the parent, and waits for the parent's
+ acknowledgement. The parent can then set the child's event mask,
+ and notify the child that it can now exec.
+
+ (The acknowledgement by parent happens as a result of a call to
+ child_acknowledge_created_inferior.) */
+
+int
+parent_attach_all (int pid, PTRACE_ARG3_TYPE addr, int data)
+{
+ int pt_status = 0;
+
+ /* We need a memory home for a constant. */
+ int tc_magic_child = PT_VERSION;
+ int tc_magic_parent = 0;
+
+ /* The remainder of this function is only useful for HPUX 10.0 and
+ later, as it depends upon the ability to request notification
+ of specific kinds of events by the kernel. */
+#if defined(PT_SET_EVENT_MASK)
+
+ /* Notify the parent that we're potentially ready to exec(). */
+ write (startup_semaphore.child_channel[SEM_TALK],
+ &tc_magic_child,
+ sizeof (tc_magic_child));
+
+ /* Wait for acknowledgement from the parent. */
+ read (startup_semaphore.parent_channel[SEM_LISTEN],
+ &tc_magic_parent,
+ sizeof (tc_magic_parent));
+ if (tc_magic_child != tc_magic_parent)
+ warning ("mismatched semaphore magic");
+
+ /* Discard our copy of the semaphore. */
+ (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
+ (void) close (startup_semaphore.parent_channel[SEM_TALK]);
+ (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
+ (void) close (startup_semaphore.child_channel[SEM_TALK]);
+#endif
+
+ return 0;
+}
+#endif
+
+int
+hppa_require_attach (int pid)
+{
+ int pt_status;
+ CORE_ADDR pc;
+ CORE_ADDR pc_addr;
+ unsigned int regs_offset;
+
+ /* Are we already attached? There appears to be no explicit way to
+ answer this via ptrace, so we try something which should be
+ innocuous if we are attached. If that fails, then we assume
+ we're not attached, and so attempt to make it so. */
+
+ errno = 0;
+ regs_offset = U_REGS_OFFSET;
+ pc_addr = register_addr (PC_REGNUM, regs_offset);
+ pc = call_ptrace (PT_READ_U, pid, (PTRACE_ARG3_TYPE) pc_addr, 0);
+
+ if (errno)
+ {
+ errno = 0;
+ pt_status = call_ptrace (PT_ATTACH, pid, (PTRACE_ARG3_TYPE) 0, 0);
+
+ if (errno)
+ return -1;
+
+ /* Now we really are attached. */
+ errno = 0;
+ }
+ attach_flag = 1;
+ return pid;
+}
+
+int
+hppa_require_detach (int pid, int signal)
+{
+ errno = 0;
+ call_ptrace (PT_DETACH, pid, (PTRACE_ARG3_TYPE) 1, signal);
+ errno = 0; /* Ignore any errors. */
+ return pid;
+}
+
+/* Since ptrace doesn't support memory page-protection events, which
+ are used to implement "hardware" watchpoints on HP-UX, these are
+ dummy versions, which perform no useful work. */
+
+void
+hppa_enable_page_protection_events (int pid)
+{
+}
+
+void
+hppa_disable_page_protection_events (int pid)
+{
+}
+
+int
+hppa_insert_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len, int type)
+{
+ error ("Hardware watchpoints not implemented on this platform.");
+}
+
+int
+hppa_remove_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len,
+ enum bptype type)
+{
+ error ("Hardware watchpoints not implemented on this platform.");
+}
+
+int
+hppa_can_use_hw_watchpoint (enum bptype type, int cnt, enum bptype ot)
+{
+ return 0;
+}
+
+int
+hppa_range_profitable_for_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len)
+{
+ error ("Hardware watchpoints not implemented on this platform.");
+}
+
+char *
+hppa_pid_or_tid_to_str (ptid_t id)
+{
+ /* In the ptrace world, there are only processes. */
+ return child_pid_to_str (id);
+}
+
+/* This function has no meaning in a non-threaded world. Thus, we
+ return 0 (FALSE). See the use of "hppa_prepare_to_proceed" in
+ hppa-tdep.c. */
+
+pid_t
+hppa_switched_threads (pid_t pid)
+{
+ return (pid_t) 0;
+}
+
+void
+hppa_ensure_vforking_parent_remains_stopped (int pid)
+{
+ /* This assumes that the vforked parent is presently stopped, and
+ that the vforked child has just delivered its first exec event.
+ Calling kill() this way will cause the SIGTRAP to be delivered as
+ soon as the parent is resumed, which happens as soon as the
+ vforked child is resumed. See wait_for_inferior for the use of
+ this function. */
+ kill (pid, SIGTRAP);
+}
+
+int
+hppa_resume_execd_vforking_child_to_get_parent_vfork (void)
+{
+ return 1; /* Yes, the child must be resumed. */
+}
+
+void
+require_notification_of_events (int pid)
+{
+#if defined(PT_SET_EVENT_MASK)
+ int pt_status;
+ ptrace_event_t ptrace_events;
+ int nsigs;
+ int signum;
+
+ /* Instruct the kernel as to the set of events we wish to be
+ informed of. (This support does not exist before HPUX 10.0.
+ We'll assume if PT_SET_EVENT_MASK has not been defined by
+ <sys/ptrace.h>, then we're being built on pre-10.0.) */
+ memset (&ptrace_events, 0, sizeof (ptrace_events));
+
+ /* Note: By default, all signals are visible to us. If we wish
+ the kernel to keep certain signals hidden from us, we do it
+ by calling sigdelset (ptrace_events.pe_signals, signal) for
+ each such signal here, before doing PT_SET_EVENT_MASK. */
+ /* RM: The above comment is no longer true. We start with ignoring
+ all signals, and then add the ones we are interested in. We could
+ do it the other way: start by looking at all signals and then
+ deleting the ones that we aren't interested in, except that
+ multiple gdb signals may be mapped to the same host signal
+ (eg. TARGET_SIGNAL_IO and TARGET_SIGNAL_POLL both get mapped to
+ signal 22 on HPUX 10.20) We want to be notified if we are
+ interested in either signal. */
+ sigfillset (&ptrace_events.pe_signals);
+
+ /* RM: Let's not bother with signals we don't care about */
+ nsigs = (int) TARGET_SIGNAL_LAST;
+ for (signum = nsigs; signum > 0; signum--)
+ {
+ if ((signal_stop_state (signum)) ||
+ (signal_print_state (signum)) ||
+ (!signal_pass_state (signum)))
+ {
+ if (target_signal_to_host_p (signum))
+ sigdelset (&ptrace_events.pe_signals,
+ target_signal_to_host (signum));
+ }
+ }
+
+ ptrace_events.pe_set_event = 0;
+
+ ptrace_events.pe_set_event |= PTRACE_SIGNAL;
+ ptrace_events.pe_set_event |= PTRACE_EXEC;
+ ptrace_events.pe_set_event |= PTRACE_FORK;
+ ptrace_events.pe_set_event |= PTRACE_VFORK;
+ /* ??rehrauer: Add this one when we're prepared to catch it...
+ ptrace_events.pe_set_event |= PTRACE_EXIT;
+ */
+
+ errno = 0;
+ pt_status = call_ptrace (PT_SET_EVENT_MASK,
+ pid,
+ (PTRACE_ARG3_TYPE) & ptrace_events,
+ sizeof (ptrace_events));
+ if (errno)
+ perror_with_name ("ptrace");
+ if (pt_status < 0)
+ return;
+#endif
+}
+
+void
+require_notification_of_exec_events (int pid)
+{
+#if defined(PT_SET_EVENT_MASK)
+ int pt_status;
+ ptrace_event_t ptrace_events;
+
+ /* Instruct the kernel as to the set of events we wish to be
+ informed of. (This support does not exist before HPUX 10.0.
+ We'll assume if PT_SET_EVENT_MASK has not been defined by
+ <sys/ptrace.h>, then we're being built on pre-10.0.) */
+ memset (&ptrace_events, 0, sizeof (ptrace_events));
+
+ /* Note: By default, all signals are visible to us. If we wish
+ the kernel to keep certain signals hidden from us, we do it
+ by calling sigdelset (ptrace_events.pe_signals, signal) for
+ each such signal here, before doing PT_SET_EVENT_MASK. */
+ sigemptyset (&ptrace_events.pe_signals);
+
+ ptrace_events.pe_set_event = 0;
+
+ ptrace_events.pe_set_event |= PTRACE_EXEC;
+ /* ??rehrauer: Add this one when we're prepared to catch it...
+ ptrace_events.pe_set_event |= PTRACE_EXIT;
+ */
+
+ errno = 0;
+ pt_status = call_ptrace (PT_SET_EVENT_MASK,
+ pid,
+ (PTRACE_ARG3_TYPE) & ptrace_events,
+ sizeof (ptrace_events));
+ if (errno)
+ perror_with_name ("ptrace");
+ if (pt_status < 0)
+ return;
+#endif
+}
+
+/* This function is called by the parent process, with pid being the
+ ID of the child process, after the debugger has forked. */
+
+void
+child_acknowledge_created_inferior (int pid)
+{
+ /* We need a memory home for a constant. */
+ int tc_magic_parent = PT_VERSION;
+ int tc_magic_child = 0;
+
+ /* The remainder of this function is only useful for HPUX 10.0 and
+ later, as it depends upon the ability to request notification
+ of specific kinds of events by the kernel. */
+#if defined(PT_SET_EVENT_MASK)
+ /* Wait for the child to tell us that it has forked. */
+ read (startup_semaphore.child_channel[SEM_LISTEN],
+ &tc_magic_child,
+ sizeof (tc_magic_child));
+
+ /* Notify the child that it can exec.
+
+ In the infttrace.c variant of this function, we set the child's
+ event mask after the fork but before the exec. In the ptrace
+ world, it seems we can't set the event mask until after the exec. */
+ write (startup_semaphore.parent_channel[SEM_TALK],
+ &tc_magic_parent,
+ sizeof (tc_magic_parent));
+
+ /* We'd better pause a bit before trying to set the event mask,
+ though, to ensure that the exec has happened. We don't want to
+ wait() on the child, because that'll screw up the upper layers
+ of gdb's execution control that expect to see the exec event.
+
+ After an exec, the child is no longer executing gdb code. Hence,
+ we can't have yet another synchronization via the pipes. We'll
+ just sleep for a second, and hope that's enough delay... */
+ sleep (1);
+
+ /* Instruct the kernel as to the set of events we wish to be
+ informed of. */
+ require_notification_of_exec_events (pid);
+
+ /* Discard our copy of the semaphore. */
+ (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
+ (void) close (startup_semaphore.parent_channel[SEM_TALK]);
+ (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
+ (void) close (startup_semaphore.child_channel[SEM_TALK]);
+#endif
+}
+
+void
+child_post_startup_inferior (ptid_t ptid)
+{
+ require_notification_of_events (PIDGET (ptid));
+}
+
+void
+child_post_attach (int pid)
+{
+ require_notification_of_events (pid);
+}
+
+int
+child_insert_fork_catchpoint (int pid)
+{
+ /* This request is only available on HPUX 10.0 and later. */
+#if !defined(PT_SET_EVENT_MASK)
+ error ("Unable to catch forks prior to HPUX 10.0");
+#else
+ /* Enable reporting of fork events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them. */
+ return 0;
+#endif
+}
+
+int
+child_remove_fork_catchpoint (int pid)
+{
+ /* This request is only available on HPUX 10.0 and later. */
+#if !defined(PT_SET_EVENT_MASK)
+ error ("Unable to catch forks prior to HPUX 10.0");
+#else
+ /* Disable reporting of fork events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them. */
+ return 0;
+#endif
+}
+
+int
+child_insert_vfork_catchpoint (int pid)
+{
+ /* This request is only available on HPUX 10.0 and later. */
+#if !defined(PT_SET_EVENT_MASK)
+ error ("Unable to catch vforks prior to HPUX 10.0");
+#else
+ /* Enable reporting of vfork events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them. */
+ return 0;
+#endif
+}
+
+int
+child_remove_vfork_catchpoint (int pid)
+{
+ /* This request is only available on HPUX 10.0 and later. */
+#if !defined(PT_SET_EVENT_MASK)
+ error ("Unable to catch vforks prior to HPUX 10.0");
+#else
+ /* Disable reporting of vfork events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them. */
+ return 0;
+#endif
+}
+
+int
+child_has_forked (int pid, int *childpid)
+{
+ /* This request is only available on HPUX 10.0 and later. */
+#if !defined(PT_GET_PROCESS_STATE)
+ *childpid = 0;
+ return 0;
+#else
+ int pt_status;
+ ptrace_state_t ptrace_state;
+
+ errno = 0;
+ pt_status = call_ptrace (PT_GET_PROCESS_STATE,
+ pid,
+ (PTRACE_ARG3_TYPE) & ptrace_state,
+ sizeof (ptrace_state));
+ if (errno)
+ perror_with_name ("ptrace");
+ if (pt_status < 0)
+ return 0;
+
+ if (ptrace_state.pe_report_event & PTRACE_FORK)
+ {
+ *childpid = ptrace_state.pe_other_pid;
+ return 1;
+ }
+
+ return 0;
+#endif
+}
+
+int
+child_has_vforked (int pid, int *childpid)
+{
+ /* This request is only available on HPUX 10.0 and later. */
+#if !defined(PT_GET_PROCESS_STATE)
+ *childpid = 0;
+ return 0;
+
+#else
+ int pt_status;
+ ptrace_state_t ptrace_state;
+
+ errno = 0;
+ pt_status = call_ptrace (PT_GET_PROCESS_STATE,
+ pid,
+ (PTRACE_ARG3_TYPE) & ptrace_state,
+ sizeof (ptrace_state));
+ if (errno)
+ perror_with_name ("ptrace");
+ if (pt_status < 0)
+ return 0;
+
+ if (ptrace_state.pe_report_event & PTRACE_VFORK)
+ {
+ *childpid = ptrace_state.pe_other_pid;
+ return 1;
+ }
+
+ return 0;
+#endif
+}
+
+int
+child_can_follow_vfork_prior_to_exec (void)
+{
+ /* ptrace doesn't allow this. */
+ return 0;
+}
+
+int
+child_insert_exec_catchpoint (int pid)
+{
+ /* This request is only available on HPUX 10.0 and later. */
+#if !defined(PT_SET_EVENT_MASK)
+ error ("Unable to catch execs prior to HPUX 10.0");
+
+#else
+ /* Enable reporting of exec events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them. */
+ return 0;
+#endif
+}
+
+int
+child_remove_exec_catchpoint (int pid)
+{
+ /* This request is only available on HPUX 10.0 and later. */
+#if !defined(PT_SET_EVENT_MASK)
+ error ("Unable to catch execs prior to HPUX 10.0");
+
+#else
+ /* Disable reporting of exec events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them. */
+ return 0;
+#endif
+}
+
+int
+child_has_execd (int pid, char **execd_pathname)
+{
+ /* This request is only available on HPUX 10.0 and later. */
+#if !defined(PT_GET_PROCESS_STATE)
+ *execd_pathname = NULL;
+ return 0;
+
+#else
+ int pt_status;
+ ptrace_state_t ptrace_state;
+
+ errno = 0;
+ pt_status = call_ptrace (PT_GET_PROCESS_STATE,
+ pid,
+ (PTRACE_ARG3_TYPE) & ptrace_state,
+ sizeof (ptrace_state));
+ if (errno)
+ perror_with_name ("ptrace");
+ if (pt_status < 0)
+ return 0;
+
+ if (ptrace_state.pe_report_event & PTRACE_EXEC)
+ {
+ char *exec_file = target_pid_to_exec_file (pid);
+ *execd_pathname = savestring (exec_file, strlen (exec_file));
+ return 1;
+ }
+
+ return 0;
+#endif
+}
+
+int
+child_reported_exec_events_per_exec_call (void)
+{
+ return 2; /* ptrace reports the event twice per call. */
+}
+
+int
+child_has_syscall_event (int pid, enum target_waitkind *kind, int *syscall_id)
+{
+ /* This request is only available on HPUX 10.30 and later, via
+ the ttrace interface. */
+
+ *kind = TARGET_WAITKIND_SPURIOUS;
+ *syscall_id = -1;
+ return 0;
+}
+
+char *
+child_pid_to_exec_file (int pid)
+{
+ static char exec_file_buffer[1024];
+ int pt_status;
+ CORE_ADDR top_of_stack;
+ char four_chars[4];
+ int name_index;
+ int i;
+ ptid_t saved_inferior_ptid;
+ boolean done;
+
+#ifdef PT_GET_PROCESS_PATHNAME
+ /* As of 10.x HP-UX, there's an explicit request to get the pathname. */
+ pt_status = call_ptrace (PT_GET_PROCESS_PATHNAME,
+ pid,
+ (PTRACE_ARG3_TYPE) exec_file_buffer,
+ sizeof (exec_file_buffer) - 1);
+ if (pt_status == 0)
+ return exec_file_buffer;
+#endif
+
+ /* It appears that this request is broken prior to 10.30.
+ If it fails, try a really, truly amazingly gross hack
+ that DDE uses, of pawing through the process' data
+ segment to find the pathname. */
+
+ top_of_stack = 0x7b03a000;
+ name_index = 0;
+ done = 0;
+
+ /* On the chance that pid != inferior_ptid, set inferior_ptid
+ to pid, so that (grrrr!) implicit uses of inferior_ptid get
+ the right id. */
+
+ saved_inferior_ptid = inferior_ptid;
+ inferior_ptid = pid_to_ptid (pid);
+
+ /* Try to grab a null-terminated string. */
+ while (!done)
+ {
+ if (target_read_memory (top_of_stack, four_chars, 4) != 0)
+ {
+ inferior_ptid = saved_inferior_ptid;
+ return NULL;
+ }
+ for (i = 0; i < 4; i++)
+ {
+ exec_file_buffer[name_index++] = four_chars[i];
+ done = (four_chars[i] == '\0');
+ if (done)
+ break;
+ }
+ top_of_stack += 4;
+ }
+
+ if (exec_file_buffer[0] == '\0')
+ {
+ inferior_ptid = saved_inferior_ptid;
+ return NULL;
+ }
+
+ inferior_ptid = saved_inferior_ptid;
+ return exec_file_buffer;
+}
+
+void
+pre_fork_inferior (void)
+{
+ int status;
+
+ status = pipe (startup_semaphore.parent_channel);
+ if (status < 0)
+ {
+ warning ("error getting parent pipe for startup semaphore");
+ return;
+ }
+
+ status = pipe (startup_semaphore.child_channel);
+ if (status < 0)
+ {
+ warning ("error getting child pipe for startup semaphore");
+ return;
+ }
+}
+
+
+/* Check to see if the given thread is alive.
+
+ This is a no-op, as ptrace doesn't support threads, so we just
+ return "TRUE". */
+
+int
+child_thread_alive (ptid_t ptid)
+{
+ return 1;
+}
+
+#endif /* ! GDB_NATIVE_HPUX_11 */
diff --git a/gdb/hppam3-nat.c b/gdb/hppam3-nat.c
new file mode 100644
index 00000000000..ee67f1b4dcf
--- /dev/null
+++ b/gdb/hppam3-nat.c
@@ -0,0 +1,141 @@
+/* Low level interface to HP800 running mach 4.0.
+ Copyright 1995, 2000, 2001 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 "defs.h"
+#include "inferior.h"
+#include "floatformat.h"
+#include "regcache.h"
+
+#include <stdio.h>
+
+#include <mach.h>
+#include <mach/message.h>
+#include <mach/exception.h>
+#include <mach_error.h>
+
+#include <target.h>
+
+/*
+ * Fetch inferiors registers for gdb.
+ * REGNO specifies which (as gdb views it) register, -1 for all.
+ */
+
+void
+fetch_inferior_registers (int regno)
+{
+ kern_return_t ret;
+ thread_state_data_t state;
+ unsigned int stateCnt = TRACE_FLAVOR_SIZE;
+ int index;
+
+ if (!MACH_PORT_VALID (current_thread))
+ error ("fetch inferior registers: Invalid thread");
+
+ if (must_suspend_thread)
+ setup_thread (current_thread, 1);
+
+ ret = thread_get_state (current_thread,
+ TRACE_FLAVOR,
+ state,
+ &stateCnt);
+
+ if (ret != KERN_SUCCESS)
+ warning ("fetch_inferior_registers: %s ",
+ mach_error_string (ret));
+ else
+ {
+ for (index = 0; index < NUM_REGS; index++)
+ supply_register (index, (void *) &state[index]);
+ }
+
+ if (must_suspend_thread)
+ setup_thread (current_thread, 0);
+}
+
+/* Store our register values back into the inferior.
+ * If REGNO is -1, do this for all registers.
+ * Otherwise, REGNO specifies which register
+ *
+ * On mach3 all registers are always saved in one call.
+ */
+void
+store_inferior_registers (int regno)
+{
+ kern_return_t ret;
+ thread_state_data_t state;
+ unsigned int stateCnt = TRACE_FLAVOR_SIZE;
+ register int index;
+
+ if (!MACH_PORT_VALID (current_thread))
+ error ("store inferior registers: Invalid thread");
+
+ if (must_suspend_thread)
+ setup_thread (current_thread, 1);
+
+ /* Fetch the state of the current thread */
+ ret = thread_get_state (current_thread,
+ TRACE_FLAVOR,
+ state,
+ &stateCnt);
+
+ if (ret != KERN_SUCCESS)
+ {
+ warning ("store_inferior_registers (get): %s",
+ mach_error_string (ret));
+ if (must_suspend_thread)
+ setup_thread (current_thread, 0);
+ return;
+ }
+
+
+ /* move gdb's registers to thread's state
+
+ * Since we save all registers anyway, save the ones
+ * that gdb thinks are valid (e.g. ignore the regno
+ * parameter)
+ */
+ if (regno > 0 && regno < NUM_REGS)
+ {
+ memcpy (&state[regno], &registers[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE (regno));
+ }
+ else
+ {
+ for (index = 0; index < NUM_REGS; index++)
+ memcpy (&state[index], &registers[REGISTER_BYTE (index)],
+ REGISTER_RAW_SIZE (index));
+/* state[index] = registers[REGISTER_BYTE (index)]; */
+
+ }
+
+ /* Write gdb's current view of register to the thread
+ */
+ ret = thread_set_state (current_thread,
+ TRACE_FLAVOR,
+ state,
+ TRACE_FLAVOR_SIZE);
+
+ if (ret != KERN_SUCCESS)
+ warning ("store_inferior_registers (set): %s",
+ mach_error_string (ret));
+
+ if (must_suspend_thread)
+ setup_thread (current_thread, 0);
+}
diff --git a/gdb/hpread.c b/gdb/hpread.c
new file mode 100644
index 00000000000..98869a8eb12
--- /dev/null
+++ b/gdb/hpread.c
@@ -0,0 +1,6339 @@
+/* Read hp debug symbols and convert to internal format, for GDB.
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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.
+
+ Written by the Center for Software Science at the University of Utah
+ and by Cygnus Support. */
+
+#include "defs.h"
+#include "bfd.h"
+#include "gdb_string.h"
+#include "hp-symtab.h"
+#include "syms.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "complaints.h"
+#include "gdb-stabs.h"
+#include "gdbtypes.h"
+#include "demangle.h"
+
+/* Private information attached to an objfile which we use to find
+ and internalize the HP C debug symbols within that objfile. */
+
+struct hpread_symfile_info
+ {
+ /* The contents of each of the debug sections (there are 4 of them). */
+ char *gntt;
+ char *lntt;
+ char *slt;
+ char *vt;
+
+ /* We keep the size of the $VT$ section for range checking. */
+ unsigned int vt_size;
+
+ /* Some routines still need to know the number of symbols in the
+ main debug sections ($LNTT$ and $GNTT$). */
+ unsigned int lntt_symcount;
+ unsigned int gntt_symcount;
+
+ /* To keep track of all the types we've processed. */
+ struct type **dntt_type_vector;
+ int dntt_type_vector_length;
+
+ /* Keeps track of the beginning of a range of source lines. */
+ sltpointer sl_index;
+
+ /* Some state variables we'll need. */
+ int within_function;
+
+ /* Keep track of the current function's address. We may need to look
+ up something based on this address. */
+ unsigned int current_function_value;
+ };
+
+/* Accessor macros to get at the fields. */
+#define HPUX_SYMFILE_INFO(o) \
+ ((struct hpread_symfile_info *)((o)->sym_private))
+#define GNTT(o) (HPUX_SYMFILE_INFO(o)->gntt)
+#define LNTT(o) (HPUX_SYMFILE_INFO(o)->lntt)
+#define SLT(o) (HPUX_SYMFILE_INFO(o)->slt)
+#define VT(o) (HPUX_SYMFILE_INFO(o)->vt)
+#define VT_SIZE(o) (HPUX_SYMFILE_INFO(o)->vt_size)
+#define LNTT_SYMCOUNT(o) (HPUX_SYMFILE_INFO(o)->lntt_symcount)
+#define GNTT_SYMCOUNT(o) (HPUX_SYMFILE_INFO(o)->gntt_symcount)
+#define DNTT_TYPE_VECTOR(o) (HPUX_SYMFILE_INFO(o)->dntt_type_vector)
+#define DNTT_TYPE_VECTOR_LENGTH(o) \
+ (HPUX_SYMFILE_INFO(o)->dntt_type_vector_length)
+#define SL_INDEX(o) (HPUX_SYMFILE_INFO(o)->sl_index)
+#define WITHIN_FUNCTION(o) (HPUX_SYMFILE_INFO(o)->within_function)
+#define CURRENT_FUNCTION_VALUE(o) (HPUX_SYMFILE_INFO(o)->current_function_value)
+
+/* Given the native debug symbol SYM, set NAMEP to the name associated
+ with the debug symbol. Note we may be called with a debug symbol which
+ has no associated name, in that case we return an empty string.
+
+ Also note we "know" that the name for any symbol is always in the
+ same place. Hence we don't have to conditionalize on the symbol type. */
+#define SET_NAMESTRING(SYM, NAMEP, OBJFILE) \
+ if (! hpread_has_name ((SYM)->dblock.kind)) \
+ *NAMEP = ""; \
+ else if (((unsigned)(SYM)->dsfile.name) >= VT_SIZE (OBJFILE)) \
+ { \
+ complain (&string_table_offset_complaint, (char *) symnum); \
+ *NAMEP = ""; \
+ } \
+ else \
+ *NAMEP = (SYM)->dsfile.name + VT (OBJFILE)
+
+/* We put a pointer to this structure in the read_symtab_private field
+ of the psymtab. */
+
+struct symloc
+ {
+ /* The offset within the file symbol table of first local symbol for
+ this file. */
+
+ int ldsymoff;
+
+ /* Length (in bytes) of the section of the symbol table devoted to
+ this file's symbols (actually, the section bracketed may contain
+ more than just this file's symbols). If ldsymlen is 0, the only
+ reason for this thing's existence is the dependency list.
+ Nothing else will happen when it is read in. */
+
+ int ldsymlen;
+ };
+
+#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
+#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen)
+#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private))
+
+/* FIXME: Shouldn't this stuff be in a .h file somewhere? */
+/* Complaints about the symbols we have encountered. */
+extern struct complaint string_table_offset_complaint;
+extern struct complaint lbrac_unmatched_complaint;
+extern struct complaint lbrac_mismatch_complaint;
+
+static struct complaint hpread_unhandled_end_common_complaint =
+{
+ "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON/DNTT_TYPE_END.\n", 0, 0
+};
+
+static struct complaint hpread_unhandled_type_complaint =
+{
+ "hpread_type_translate: unhandled type code.", 0, 0
+};
+
+static struct complaint hpread_struct_complaint =
+{
+ "hpread_read_struct_type: expected SVAR type...", 0, 0
+};
+
+static struct complaint hpread_array_complaint =
+{
+ "error in hpread_array_type.", 0, 0
+};
+
+static struct complaint hpread_type_lookup_complaint =
+{
+ "error in hpread_type_lookup().", 0, 0
+};
+
+
+static struct complaint hpread_unexpected_end_complaint =
+{
+ "internal error in hp-symtab-read.c: Unexpected DNTT_TYPE_END kind.", 0, 0
+};
+
+static struct complaint hpread_tagdef_complaint =
+{
+ "error processing class tagdef", 0, 0
+};
+
+static struct complaint hpread_unhandled_common_complaint =
+{
+ "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON.", 0, 0
+};
+
+static struct complaint hpread_unhandled_blockdata_complaint =
+{
+ "unhandled symbol in hp-symtab-read.c: DNTT_TYPE_BLOCKDATA.", 0, 0
+};
+
+/* To generate dumping code, uncomment this define. The dumping
+ itself is controlled by routine-local statics called "dumping". */
+/* #define DUMPING 1 */
+
+/* To use the quick look-up tables, uncomment this define. */
+#define QUICK_LOOK_UP 1
+
+/* To call PXDB to process un-processed files, uncomment this define. */
+#define USE_PXDB 1
+
+/* Forward procedure declarations */
+
+void hpread_symfile_init (struct objfile *);
+
+void do_pxdb (bfd *);
+
+void hpread_build_psymtabs (struct objfile *, int);
+
+void hpread_symfile_finish (struct objfile *);
+
+static union dnttentry *hpread_get_gntt (int, struct objfile *);
+
+static union dnttentry *hpread_get_lntt (int index, struct objfile *objfile);
+
+
+static unsigned long hpread_get_textlow (int, int, struct objfile *, int);
+
+static struct partial_symtab *hpread_start_psymtab
+ (struct objfile *, char *, CORE_ADDR, int,
+ struct partial_symbol **, struct partial_symbol **);
+
+static struct partial_symtab *hpread_end_psymtab
+ (struct partial_symtab *, char **, int, int, CORE_ADDR,
+ struct partial_symtab **, int);
+
+static unsigned long hpread_get_scope_start (sltpointer, struct objfile *);
+
+static unsigned long hpread_get_line (sltpointer, struct objfile *);
+
+static CORE_ADDR hpread_get_location (sltpointer, struct objfile *);
+
+static void hpread_psymtab_to_symtab_1 (struct partial_symtab *);
+
+void hpread_psymtab_to_symtab (struct partial_symtab *);
+
+static struct symtab *hpread_expand_symtab
+ (struct objfile *, int, int, CORE_ADDR, int,
+ struct section_offsets *, char *);
+
+static int hpread_type_translate (dnttpointer);
+
+static struct type **hpread_lookup_type (dnttpointer, struct objfile *);
+
+static struct type *hpread_alloc_type (dnttpointer, struct objfile *);
+
+static struct type *hpread_read_enum_type
+ (dnttpointer, union dnttentry *, struct objfile *);
+
+static struct type *hpread_read_function_type
+ (dnttpointer, union dnttentry *, struct objfile *, int);
+
+static struct type *hpread_read_doc_function_type
+ (dnttpointer, union dnttentry *, struct objfile *, int);
+
+static struct type *hpread_read_struct_type
+ (dnttpointer, union dnttentry *, struct objfile *);
+
+static struct type *hpread_get_nth_template_arg (struct objfile *, int);
+
+static struct type *hpread_read_templ_arg_type
+ (dnttpointer, union dnttentry *, struct objfile *, char *);
+
+static struct type *hpread_read_set_type
+ (dnttpointer, union dnttentry *, struct objfile *);
+
+static struct type *hpread_read_array_type
+ (dnttpointer, union dnttentry *dn_bufp, struct objfile *objfile);
+
+static struct type *hpread_read_subrange_type
+ (dnttpointer, union dnttentry *, struct objfile *);
+
+static struct type *hpread_type_lookup (dnttpointer, struct objfile *);
+
+static sltpointer hpread_record_lines
+ (struct subfile *, sltpointer, sltpointer, struct objfile *, CORE_ADDR);
+
+static void hpread_process_one_debug_symbol
+ (union dnttentry *, char *, struct section_offsets *,
+ struct objfile *, CORE_ADDR, int, char *, int, int *);
+
+static int hpread_get_scope_depth (union dnttentry *, struct objfile *, int);
+
+static void fix_static_member_physnames
+ (struct type *, char *, struct objfile *);
+
+static void fixup_class_method_type
+ (struct type *, struct type *, struct objfile *);
+
+static void hpread_adjust_bitoffsets (struct type *, int);
+
+static dnttpointer hpread_get_next_skip_over_anon_unions
+ (int, dnttpointer, union dnttentry **, struct objfile *);
+
+
+/* Global to indicate presence of HP-compiled objects,
+ in particular, SOM executable file with SOM debug info
+ Defined in symtab.c, used in hppa-tdep.c. */
+extern int hp_som_som_object_present;
+
+/* Static used to indicate a class type that requires a
+ fix-up of one of its method types */
+static struct type *fixup_class = NULL;
+
+/* Static used to indicate the method type that is to be
+ used to fix-up the type for fixup_class */
+static struct type *fixup_method = NULL;
+
+#ifdef USE_PXDB
+
+/* NOTE use of system files! May not be portable. */
+
+#define PXDB_SVR4 "/opt/langtools/bin/pxdb"
+#define PXDB_BSD "/usr/bin/pxdb"
+
+#include <stdlib.h>
+#include "gdb_string.h"
+
+/* check for the existence of a file, given its full pathname */
+int
+file_exists (char *filename)
+{
+ if (filename)
+ return (access (filename, F_OK) == 0);
+ return 0;
+}
+
+
+/* Translate from the "hp_language" enumeration in hp-symtab.h
+ used in the debug info to gdb's generic enumeration in defs.h. */
+static enum language
+trans_lang (enum hp_language in_lang)
+{
+ if (in_lang == HP_LANGUAGE_C)
+ return language_c;
+
+ else if (in_lang == HP_LANGUAGE_CPLUSPLUS)
+ return language_cplus;
+
+ else if (in_lang == HP_LANGUAGE_FORTRAN)
+ return language_fortran;
+
+ else
+ return language_unknown;
+}
+
+static char main_string[] = "main";
+
+/* Call PXDB to process our file.
+
+ Approach copied from DDE's "dbgk_run_pxdb". Note: we
+ don't check for BSD location of pxdb, nor for existence
+ of pxdb itself, etc.
+
+ NOTE: uses system function and string functions directly.
+
+ Return value: 1 if ok, 0 if not */
+int
+hpread_call_pxdb (const char *file_name)
+{
+ char *p;
+ int status;
+ int retval;
+
+ if (file_exists (PXDB_SVR4))
+ {
+ p = xmalloc (strlen (PXDB_SVR4) + strlen (file_name) + 2);
+ strcpy (p, PXDB_SVR4);
+ strcat (p, " ");
+ strcat (p, file_name);
+
+ warning ("File not processed by pxdb--about to process now.\n");
+ status = system (p);
+
+ retval = (status == 0);
+ }
+ else
+ {
+ warning ("pxdb not found at standard location: /opt/langtools/bin\ngdb will not be able to debug %s.\nPlease install pxdb at the above location and then restart gdb.\nYou can also run pxdb on %s with the command\n\"pxdb %s\" and then restart gdb.", file_name, file_name, file_name);
+
+ retval = 0;
+ }
+ return retval;
+} /* hpread_call_pxdb */
+
+
+/* Return 1 if the file turns out to need pre-processing
+ by PXDB, and we have thus called PXDB to do this processing
+ and the file therefore needs to be re-loaded. Otherwise
+ return 0. */
+int
+hpread_pxdb_needed (bfd *sym_bfd)
+{
+ asection *pinfo_section, *debug_section, *header_section;
+ unsigned int do_pxdb;
+ char *buf;
+ bfd_size_type header_section_size;
+
+ unsigned long tmp;
+ unsigned int pxdbed;
+
+ header_section = bfd_get_section_by_name (sym_bfd, "$HEADER$");
+ if (!header_section)
+ {
+ return 0; /* No header at all, can't recover... */
+ }
+
+ debug_section = bfd_get_section_by_name (sym_bfd, "$DEBUG$");
+ pinfo_section = bfd_get_section_by_name (sym_bfd, "$PINFO$");
+
+ if (pinfo_section && !debug_section)
+ {
+ /* Debug info with DOC, has different header format.
+ this only happens if the file was pxdbed and compiled optimized
+ otherwise the PINFO section is not there. */
+ header_section_size = bfd_section_size (objfile->obfd, header_section);
+
+ if (header_section_size == (bfd_size_type) sizeof (DOC_info_PXDB_header))
+ {
+ buf = alloca (sizeof (DOC_info_PXDB_header));
+
+ if (!bfd_get_section_contents (sym_bfd,
+ header_section,
+ buf, 0,
+ header_section_size))
+ error ("bfd_get_section_contents\n");
+
+ tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 4));
+ pxdbed = (tmp >> 31) & 0x1;
+
+ if (!pxdbed)
+ error ("file debug header info invalid\n");
+ do_pxdb = 0;
+ }
+
+ else
+ error ("invalid $HEADER$ size in executable \n");
+ }
+
+ else
+ {
+
+ /* this can be three different cases:
+ 1. pxdbed and not doc
+ - DEBUG and HEADER sections are there
+ - header is PXDB_header type
+ - pxdbed flag is set to 1
+
+ 2. not pxdbed and doc
+ - DEBUG and HEADER sections are there
+ - header is DOC_info_header type
+ - pxdbed flag is set to 0
+
+ 3. not pxdbed and not doc
+ - DEBUG and HEADER sections are there
+ - header is XDB_header type
+ - pxdbed flag is set to 0
+
+ NOTE: the pxdbed flag is meaningful also in the not
+ already pxdb processed version of the header,
+ because in case on non-already processed by pxdb files
+ that same bit in the header would be always zero.
+ Why? Because the bit is the leftmost bit of a word
+ which contains a 'length' which is always a positive value
+ so that bit is never set to 1 (otherwise it would be negative)
+
+ Given the above, we have two choices : either we ignore the
+ size of the header itself and just look at the pxdbed field,
+ or we check the size and then we (for safety and paranoia related
+ issues) check the bit.
+ The first solution is used by DDE, the second by PXDB itself.
+ I am using the second one here, because I already wrote it,
+ and it is the end of a long day.
+ Also, using the first approach would still involve size issues
+ because we need to read in the contents of the header section, and
+ give the correct amount of stuff we want to read to the
+ get_bfd_section_contents function. */
+
+ /* decide which case depending on the size of the header section.
+ The size is as defined in hp-symtab.h */
+
+ header_section_size = bfd_section_size (objfile->obfd, header_section);
+
+ if (header_section_size == (bfd_size_type) sizeof (PXDB_header)) /* pxdb and not doc */
+ {
+
+ buf = alloca (sizeof (PXDB_header));
+ if (!bfd_get_section_contents (sym_bfd,
+ header_section,
+ buf, 0,
+ header_section_size))
+ error ("bfd_get_section_contents\n");
+
+ tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 3));
+ pxdbed = (tmp >> 31) & 0x1;
+
+ if (pxdbed)
+ do_pxdb = 0;
+ else
+ error ("file debug header invalid\n");
+ }
+ else /*not pxdbed and doc OR not pxdbed and non doc */
+ do_pxdb = 1;
+ }
+
+ if (do_pxdb)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+} /* hpread_pxdb_needed */
+
+#endif
+
+/* Check whether the file needs to be preprocessed by pxdb.
+ If so, call pxdb. */
+
+void
+do_pxdb (bfd *sym_bfd)
+{
+ /* The following code is HP-specific. The "right" way of
+ doing this is unknown, but we bet would involve a target-
+ specific pre-file-load check using a generic mechanism. */
+
+ /* This code will not be executed if the file is not in SOM
+ format (i.e. if compiled with gcc) */
+ if (hpread_pxdb_needed (sym_bfd))
+ {
+ /*This file has not been pre-processed. Preprocess now */
+
+ if (hpread_call_pxdb (sym_bfd->filename))
+ {
+ /* The call above has changed the on-disk file,
+ we can close the file anyway, because the
+ symbols will be reread in when the target is run */
+ bfd_close (sym_bfd);
+ }
+ }
+}
+
+
+
+#ifdef QUICK_LOOK_UP
+
+/* Code to handle quick lookup-tables follows. */
+
+
+/* Some useful macros */
+#define VALID_FILE(i) ((i) < pxdb_header_p->fd_entries)
+#define VALID_MODULE(i) ((i) < pxdb_header_p->md_entries)
+#define VALID_PROC(i) ((i) < pxdb_header_p->pd_entries)
+#define VALID_CLASS(i) ((i) < pxdb_header_p->cd_entries)
+
+#define FILE_START(i) (qFD[i].adrStart)
+#define MODULE_START(i) (qMD[i].adrStart)
+#define PROC_START(i) (qPD[i].adrStart)
+
+#define FILE_END(i) (qFD[i].adrEnd)
+#define MODULE_END(i) (qMD[i].adrEnd)
+#define PROC_END(i) (qPD[i].adrEnd)
+
+#define FILE_ISYM(i) (qFD[i].isym)
+#define MODULE_ISYM(i) (qMD[i].isym)
+#define PROC_ISYM(i) (qPD[i].isym)
+
+#define VALID_CURR_FILE (curr_fd < pxdb_header_p->fd_entries)
+#define VALID_CURR_MODULE (curr_md < pxdb_header_p->md_entries)
+#define VALID_CURR_PROC (curr_pd < pxdb_header_p->pd_entries)
+#define VALID_CURR_CLASS (curr_cd < pxdb_header_p->cd_entries)
+
+#define CURR_FILE_START (qFD[curr_fd].adrStart)
+#define CURR_MODULE_START (qMD[curr_md].adrStart)
+#define CURR_PROC_START (qPD[curr_pd].adrStart)
+
+#define CURR_FILE_END (qFD[curr_fd].adrEnd)
+#define CURR_MODULE_END (qMD[curr_md].adrEnd)
+#define CURR_PROC_END (qPD[curr_pd].adrEnd)
+
+#define CURR_FILE_ISYM (qFD[curr_fd].isym)
+#define CURR_MODULE_ISYM (qMD[curr_md].isym)
+#define CURR_PROC_ISYM (qPD[curr_pd].isym)
+
+#define TELL_OBJFILE \
+ do { \
+ if( !told_objfile ) { \
+ told_objfile = 1; \
+ warning ("\nIn object file \"%s\":\n", \
+ objfile->name); \
+ } \
+ } while (0)
+
+
+
+/* Keeping track of the start/end symbol table (LNTT) indices of
+ psymtabs created so far */
+
+typedef struct
+{
+ int start;
+ int end;
+}
+pst_syms_struct;
+
+static pst_syms_struct *pst_syms_array = 0;
+
+static pst_syms_count = 0;
+static pst_syms_size = 0;
+
+/* used by the TELL_OBJFILE macro */
+static boolean told_objfile = 0;
+
+/* Set up psymtab symbol index stuff */
+static void
+init_pst_syms (void)
+{
+ pst_syms_count = 0;
+ pst_syms_size = 20;
+ pst_syms_array = (pst_syms_struct *) xmalloc (20 * sizeof (pst_syms_struct));
+}
+
+/* Clean up psymtab symbol index stuff */
+static void
+clear_pst_syms (void)
+{
+ pst_syms_count = 0;
+ pst_syms_size = 0;
+ xfree (pst_syms_array);
+ pst_syms_array = 0;
+}
+
+/* Add information about latest psymtab to symbol index table */
+static void
+record_pst_syms (int start_sym, int end_sym)
+{
+ if (++pst_syms_count > pst_syms_size)
+ {
+ pst_syms_array = (pst_syms_struct *) xrealloc (pst_syms_array,
+ 2 * pst_syms_size * sizeof (pst_syms_struct));
+ pst_syms_size *= 2;
+ }
+ pst_syms_array[pst_syms_count - 1].start = start_sym;
+ pst_syms_array[pst_syms_count - 1].end = end_sym;
+}
+
+/* Find a suitable symbol table index which can serve as the upper
+ bound of a psymtab that starts at INDEX
+
+ This scans backwards in the psymtab symbol index table to find a
+ "hole" in which the given index can fit. This is a heuristic!!
+ We don't search the entire table to check for multiple holes,
+ we don't care about overlaps, etc.
+
+ Return 0 => not found */
+static int
+find_next_pst_start (int index)
+{
+ int i;
+
+ for (i = pst_syms_count - 1; i >= 0; i--)
+ if (pst_syms_array[i].end <= index)
+ return (i == pst_syms_count - 1) ? 0 : pst_syms_array[i + 1].start - 1;
+
+ if (pst_syms_array[0].start > index)
+ return pst_syms_array[0].start - 1;
+
+ return 0;
+}
+
+
+
+/* Utility functions to find the ending symbol index for a psymtab */
+
+/* Find the next file entry that begins beyond INDEX, and return
+ its starting symbol index - 1.
+ QFD is the file table, CURR_FD is the file entry from where to start,
+ PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
+
+ Return 0 => not found */
+static int
+find_next_file_isym (int index, quick_file_entry *qFD, int curr_fd,
+ PXDB_header_ptr pxdb_header_p)
+{
+ while (VALID_CURR_FILE)
+ {
+ if (CURR_FILE_ISYM >= index)
+ return CURR_FILE_ISYM - 1;
+ curr_fd++;
+ }
+ return 0;
+}
+
+/* Find the next procedure entry that begins beyond INDEX, and return
+ its starting symbol index - 1.
+ QPD is the procedure table, CURR_PD is the proc entry from where to start,
+ PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
+
+ Return 0 => not found */
+static int
+find_next_proc_isym (int index, quick_procedure_entry *qPD, int curr_pd,
+ PXDB_header_ptr pxdb_header_p)
+{
+ while (VALID_CURR_PROC)
+ {
+ if (CURR_PROC_ISYM >= index)
+ return CURR_PROC_ISYM - 1;
+ curr_pd++;
+ }
+ return 0;
+}
+
+/* Find the next module entry that begins beyond INDEX, and return
+ its starting symbol index - 1.
+ QMD is the module table, CURR_MD is the modue entry from where to start,
+ PXDB_HEADER_P as in hpread_quick_traverse (to allow macros to work).
+
+ Return 0 => not found */
+static int
+find_next_module_isym (int index, quick_module_entry *qMD, int curr_md,
+ PXDB_header_ptr pxdb_header_p)
+{
+ while (VALID_CURR_MODULE)
+ {
+ if (CURR_MODULE_ISYM >= index)
+ return CURR_MODULE_ISYM - 1;
+ curr_md++;
+ }
+ return 0;
+}
+
+/* Scan and record partial symbols for all functions starting from index
+ pointed to by CURR_PD_P, and between code addresses START_ADR and END_ADR.
+ Other parameters are explained in comments below. */
+
+/* This used to be inline in hpread_quick_traverse, but now that we do
+ essentially the same thing for two different cases (modules and
+ module-less files), it's better organized in a separate routine,
+ although it does take lots of arguments. pai/1997-10-08
+
+ CURR_PD_P is the pointer to the current proc index. QPD is the
+ procedure quick lookup table. MAX_PROCS is the number of entries
+ in the proc. table. START_ADR is the beginning of the code range
+ for the current psymtab. end_adr is the end of the code range for
+ the current psymtab. PST is the current psymtab. VT_bits is
+ a pointer to the strings table of SOM debug space. OBJFILE is
+ the current object file. */
+
+static int
+scan_procs (int *curr_pd_p, quick_procedure_entry *qPD, int max_procs,
+ CORE_ADDR start_adr, CORE_ADDR end_adr, struct partial_symtab *pst,
+ char *vt_bits, struct objfile *objfile)
+{
+ union dnttentry *dn_bufp;
+ int symbol_count = 0; /* Total number of symbols in this psymtab */
+ int curr_pd = *curr_pd_p; /* Convenience variable -- avoid dereferencing pointer all the time */
+
+#ifdef DUMPING
+ /* Turn this on for lots of debugging information in this routine */
+ static int dumping = 0;
+#endif
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("Scan_procs called, addresses %x to %x, proc %x\n", start_adr, end_adr, curr_pd);
+ }
+#endif
+
+ while ((CURR_PROC_START <= end_adr) && (curr_pd < max_procs))
+ {
+
+ char *rtn_name; /* mangled name */
+ char *rtn_dem_name; /* qualified demangled name */
+ char *class_name;
+ int class;
+
+ if ((trans_lang ((enum hp_language) qPD[curr_pd].language) == language_cplus) &&
+ vt_bits[(long) qPD[curr_pd].sbAlias]) /* not a null string */
+ {
+ /* Get mangled name for the procedure, and demangle it */
+ rtn_name = &vt_bits[(long) qPD[curr_pd].sbAlias];
+ rtn_dem_name = cplus_demangle (rtn_name, DMGL_ANSI | DMGL_PARAMS);
+ }
+ else
+ {
+ rtn_name = &vt_bits[(long) qPD[curr_pd].sbProc];
+ rtn_dem_name = NULL;
+ }
+
+ /* Hack to get around HP C/C++ compilers' insistence on providing
+ "_MAIN_" as an alternate name for "main" */
+ if ((strcmp (rtn_name, "_MAIN_") == 0) &&
+ (strcmp (&vt_bits[(long) qPD[curr_pd].sbProc], "main") == 0))
+ rtn_dem_name = rtn_name = main_string;
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("..add %s (demangled %s), index %x to this psymtab\n", rtn_name, rtn_dem_name, curr_pd);
+ }
+#endif
+
+ /* Check for module-spanning routines. */
+ if (CURR_PROC_END > end_adr)
+ {
+ TELL_OBJFILE;
+ warning ("Procedure \"%s\" [0x%x] spans file or module boundaries.", rtn_name, curr_pd);
+ }
+
+ /* Add this routine symbol to the list in the objfile.
+ Unfortunately we have to go to the LNTT to determine the
+ correct list to put it on. An alternative (which the
+ code used to do) would be to not check and always throw
+ it on the "static" list. But if we go that route, then
+ symbol_lookup() needs to be tweaked a bit to account
+ for the fact that the function might not be found on
+ the correct list in the psymtab. - RT */
+ dn_bufp = hpread_get_lntt (qPD[curr_pd].isym, objfile);
+ if (dn_bufp->dfunc.global)
+ add_psymbol_with_dem_name_to_list (rtn_name,
+ strlen (rtn_name),
+ rtn_dem_name,
+ strlen (rtn_dem_name),
+ VAR_NAMESPACE,
+ LOC_BLOCK, /* "I am a routine" */
+ &objfile->global_psymbols,
+ (qPD[curr_pd].adrStart + /* Starting address of rtn */
+ ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile))),
+ 0, /* core addr?? */
+ trans_lang ((enum hp_language) qPD[curr_pd].language),
+ objfile);
+ else
+ add_psymbol_with_dem_name_to_list (rtn_name,
+ strlen (rtn_name),
+ rtn_dem_name,
+ strlen (rtn_dem_name),
+ VAR_NAMESPACE,
+ LOC_BLOCK, /* "I am a routine" */
+ &objfile->static_psymbols,
+ (qPD[curr_pd].adrStart + /* Starting address of rtn */
+ ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile))),
+ 0, /* core addr?? */
+ trans_lang ((enum hp_language) qPD[curr_pd].language),
+ objfile);
+
+ symbol_count++;
+ *curr_pd_p = ++curr_pd; /* bump up count & reflect in caller */
+ } /* loop over procedures */
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ if (symbol_count == 0)
+ printf ("Scan_procs: no symbols found!\n");
+ }
+#endif
+
+ return symbol_count;
+}
+
+
+/* Traverse the quick look-up tables, building a set of psymtabs.
+
+ This constructs a psymtab for modules and files in the quick lookup
+ tables.
+
+ Mostly, modules correspond to compilation units, so we try to
+ create psymtabs that correspond to modules; however, in some cases
+ a file can result in a compiled object which does not have a module
+ entry for it, so in such cases we create a psymtab for the file. */
+
+int
+hpread_quick_traverse (struct objfile *objfile, char *gntt_bits,
+ char *vt_bits, PXDB_header_ptr pxdb_header_p)
+{
+ struct partial_symtab *pst;
+
+ char *addr;
+
+ quick_procedure_entry *qPD;
+ quick_file_entry *qFD;
+ quick_module_entry *qMD;
+ quick_class_entry *qCD;
+
+ int idx;
+ int i;
+ CORE_ADDR start_adr; /* current psymtab's starting code addr */
+ CORE_ADDR end_adr; /* current psymtab's ending code addr */
+ CORE_ADDR next_mod_adr; /* next module's starting code addr */
+ int curr_pd; /* current procedure */
+ int curr_fd; /* current file */
+ int curr_md; /* current module */
+ int start_sym; /* current psymtab's starting symbol index */
+ int end_sym; /* current psymtab's ending symbol index */
+ int max_LNTT_sym_index;
+ int syms_in_pst;
+ B_TYPE *class_entered;
+
+ struct partial_symbol **global_syms; /* We'll be filling in the "global" */
+ struct partial_symbol **static_syms; /* and "static" tables in the objfile
+ as we go, so we need a pair of
+ current pointers. */
+
+#ifdef DUMPING
+ /* Turn this on for lots of debugging information in this routine.
+ You get a blow-by-blow account of quick lookup table reading */
+ static int dumping = 0;
+#endif
+
+ pst = (struct partial_symtab *) 0;
+
+ /* Clear out some globals */
+ init_pst_syms ();
+ told_objfile = 0;
+
+ /* Demangling style -- if EDG style already set, don't change it,
+ as HP style causes some problems with the KAI EDG compiler */
+ if (current_demangling_style != edg_demangling)
+ {
+ /* Otherwise, ensure that we are using HP style demangling */
+ set_demangling_style (HP_DEMANGLING_STYLE_STRING);
+ }
+
+ /* First we need to find the starting points of the quick
+ look-up tables in the GNTT. */
+
+ addr = gntt_bits;
+
+ qPD = (quick_procedure_entry_ptr) addr;
+ addr += pxdb_header_p->pd_entries * sizeof (quick_procedure_entry);
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("\n Printing routines as we see them\n");
+ for (i = 0; VALID_PROC (i); i++)
+ {
+ idx = (long) qPD[i].sbProc;
+ printf ("%s %x..%x\n", &vt_bits[idx],
+ (int) PROC_START (i),
+ (int) PROC_END (i));
+ }
+ }
+#endif
+
+ qFD = (quick_file_entry_ptr) addr;
+ addr += pxdb_header_p->fd_entries * sizeof (quick_file_entry);
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("\n Printing files as we see them\n");
+ for (i = 0; VALID_FILE (i); i++)
+ {
+ idx = (long) qFD[i].sbFile;
+ printf ("%s %x..%x\n", &vt_bits[idx],
+ (int) FILE_START (i),
+ (int) FILE_END (i));
+ }
+ }
+#endif
+
+ qMD = (quick_module_entry_ptr) addr;
+ addr += pxdb_header_p->md_entries * sizeof (quick_module_entry);
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("\n Printing modules as we see them\n");
+ for (i = 0; i < pxdb_header_p->md_entries; i++)
+ {
+ idx = (long) qMD[i].sbMod;
+ printf ("%s\n", &vt_bits[idx]);
+ }
+ }
+#endif
+
+ qCD = (quick_class_entry_ptr) addr;
+ addr += pxdb_header_p->cd_entries * sizeof (quick_class_entry);
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("\n Printing classes as we see them\n");
+ for (i = 0; VALID_CLASS (i); i++)
+ {
+ idx = (long) qCD[i].sbClass;
+ printf ("%s\n", &vt_bits[idx]);
+ }
+
+ printf ("\n Done with dump, on to build!\n");
+ }
+#endif
+
+ /* We need this index only while hp-symtab-read.c expects
+ a byte offset to the end of the LNTT entries for a given
+ psymtab. Thus the need for it should go away someday.
+
+ When it goes away, then we won't have any need to load the
+ LNTT from the objfile at psymtab-time, and start-up will be
+ faster. To make that work, we'll need some way to create
+ a null pst for the "globals" pseudo-module. */
+ max_LNTT_sym_index = LNTT_SYMCOUNT (objfile);
+
+ /* Scan the module descriptors and make a psymtab for each.
+
+ We know the MDs, FDs and the PDs are in order by starting
+ address. We use that fact to traverse all three arrays in
+ parallel, knowing when the next PD is in a new file
+ and we need to create a new psymtab. */
+ curr_pd = 0; /* Current procedure entry */
+ curr_fd = 0; /* Current file entry */
+ curr_md = 0; /* Current module entry */
+
+ start_adr = 0; /* Current psymtab code range */
+ end_adr = 0;
+
+ start_sym = 0; /* Current psymtab symbol range */
+ end_sym = 0;
+
+ syms_in_pst = 0; /* Symbol count for psymtab */
+
+ /* Psts actually just have pointers into the objfile's
+ symbol table, not their own symbol tables. */
+ global_syms = objfile->global_psymbols.list;
+ static_syms = objfile->static_psymbols.list;
+
+
+ /* First skip over pseudo-entries with address 0. These represent inlined
+ routines and abstract (uninstantiated) template routines.
+ FIXME: These should be read in and available -- even if we can't set
+ breakpoints, etc., there's some information that can be presented
+ to the user. pai/1997-10-08 */
+
+ while (VALID_CURR_PROC && (CURR_PROC_START == 0))
+ curr_pd++;
+
+ /* Loop over files, modules, and procedures in code address order. Each
+ time we enter an iteration of this loop, curr_pd points to the first
+ unprocessed procedure, curr_fd points to the first unprocessed file, and
+ curr_md to the first unprocessed module. Each iteration of this loop
+ updates these as required -- any or all of them may be bumpd up
+ each time around. When we exit this loop, we are done with all files
+ and modules in the tables -- there may still be some procedures, however.
+
+ Note: This code used to loop only over module entries, under the assumption
+ that files can occur via inclusions and are thus unreliable, while a
+ compiled object always corresponds to a module. With CTTI in the HP aCC
+ compiler, it turns out that compiled objects may have only files and no
+ modules; so we have to loop over files and modules, creating psymtabs for
+ either as appropriate. Unfortunately there are some problems (notably:
+ 1. the lack of "SRC_FILE_END" entries in the LNTT, 2. the lack of pointers
+ to the ending symbol indices of a module or a file) which make it quite hard
+ to do this correctly. Currently it uses a bunch of heuristics to start and
+ end psymtabs; they seem to work well with most objects generated by aCC, but
+ who knows when that will change... */
+
+ while (VALID_CURR_FILE || VALID_CURR_MODULE)
+ {
+
+ char *mod_name_string;
+ char *full_name_string;
+
+ /* First check for modules like "version.c", which have no code
+ in them but still have qMD entries. They also have no qFD or
+ qPD entries. Their start address is -1 and their end address
+ is 0. */
+ if (VALID_CURR_MODULE && (CURR_MODULE_START == -1) && (CURR_MODULE_END == 0))
+ {
+
+ mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod];
+
+#ifdef DUMPING
+ if (dumping)
+ printf ("Module with data only %s\n", mod_name_string);
+#endif
+
+ /* We'll skip the rest (it makes error-checking easier), and
+ just make an empty pst. Right now empty psts are not put
+ in the pst chain, so all this is for naught, but later it
+ might help. */
+
+ pst = hpread_start_psymtab (objfile,
+ mod_name_string,
+ CURR_MODULE_START, /* Low text address: bogus! */
+ (CURR_MODULE_ISYM * sizeof (struct dntt_type_block)),
+ /* ldsymoff */
+ global_syms,
+ static_syms);
+
+ pst = hpread_end_psymtab (pst,
+ NULL, /* psymtab_include_list */
+ 0, /* includes_used */
+ end_sym * sizeof (struct dntt_type_block),
+ /* byte index in LNTT of end
+ = capping symbol offset
+ = LDSYMOFF of nextfile */
+ 0, /* text high */
+ NULL, /* dependency_list */
+ 0); /* dependencies_used */
+
+ global_syms = objfile->global_psymbols.next;
+ static_syms = objfile->static_psymbols.next;
+
+ curr_md++;
+ }
+ else if (VALID_CURR_MODULE &&
+ ((CURR_MODULE_START == 0) || (CURR_MODULE_START == -1) ||
+ (CURR_MODULE_END == 0) || (CURR_MODULE_END == -1)))
+ {
+ TELL_OBJFILE;
+ warning ("Module \"%s\" [0x%s] has non-standard addresses. It starts at 0x%s, ends at 0x%s, and will be skipped.",
+ mod_name_string, paddr_nz (curr_md), paddr_nz (start_adr), paddr_nz (end_adr));
+ /* On to next module */
+ curr_md++;
+ }
+ else
+ {
+ /* First check if we are looking at a file with code in it
+ that does not overlap the current module's code range */
+
+ if (VALID_CURR_FILE ? (VALID_CURR_MODULE ? (CURR_FILE_END < CURR_MODULE_START) : 1) : 0)
+ {
+
+ /* Looking at file not corresponding to any module,
+ create a psymtab for it */
+ full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile];
+ start_adr = CURR_FILE_START;
+ end_adr = CURR_FILE_END;
+ start_sym = CURR_FILE_ISYM;
+
+ /* Check if there are any procedures not handled until now, that
+ begin before the start address of this file, and if so, adjust
+ this module's start address to include them. This handles routines that
+ are in between file or module ranges for some reason (probably
+ indicates a compiler bug */
+
+ if (CURR_PROC_START < start_adr)
+ {
+ TELL_OBJFILE;
+ warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
+ &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd);
+ start_adr = CURR_PROC_START;
+ if (CURR_PROC_ISYM < start_sym)
+ start_sym = CURR_PROC_ISYM;
+ }
+
+ /* Sometimes (compiler bug -- COBOL) the module end address is higher
+ than the start address of the next module, so check for that and
+ adjust accordingly */
+
+ if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr))
+ {
+ TELL_OBJFILE;
+ warning ("File \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.",
+ full_name_string, curr_fd);
+ end_adr = FILE_START (curr_fd + 1) - 1; /* Is -4 (or -8 for 64-bit) better? */
+ }
+ if (VALID_MODULE (curr_md) && (CURR_MODULE_START <= end_adr))
+ {
+ TELL_OBJFILE;
+ warning ("File \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.",
+ full_name_string, curr_fd);
+ end_adr = CURR_MODULE_START - 1; /* Is -4 (or -8 for 64-bit) better? */
+ }
+
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("Make new psymtab for file %s (%x to %x).\n",
+ full_name_string, start_adr, end_adr);
+ }
+#endif
+ /* Create the basic psymtab, connecting it in the list
+ for this objfile and pointing its symbol entries
+ to the current end of the symbol areas in the objfile.
+
+ The "ldsymoff" parameter is the byte offset in the LNTT
+ of the first symbol in this file. Some day we should
+ turn this into an index (fix in hp-symtab-read.c as well).
+ And it's not even the right byte offset, as we're using
+ the size of a union! FIXME! */
+ pst = hpread_start_psymtab (objfile,
+ full_name_string,
+ start_adr, /* Low text address */
+ (start_sym * sizeof (struct dntt_type_block)),
+ /* ldsymoff */
+ global_syms,
+ static_syms);
+
+ /* Set up to only enter each class referenced in this module once. */
+ class_entered = xmalloc (B_BYTES (pxdb_header_p->cd_entries));
+ B_CLRALL (class_entered, pxdb_header_p->cd_entries);
+
+ /* Scan the procedure descriptors for procedures in the current
+ file, based on the starting addresses. */
+
+ syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
+ start_adr, end_adr, pst, vt_bits, objfile);
+
+ /* Get ending symbol offset */
+
+ end_sym = 0;
+ /* First check for starting index before previous psymtab */
+ if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end)
+ {
+ end_sym = find_next_pst_start (start_sym);
+ }
+ /* Look for next start index of a file or module, or procedure */
+ if (!end_sym)
+ {
+ int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p);
+ int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md, pxdb_header_p);
+ int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p);
+
+ if (next_file_isym && next_module_isym)
+ {
+ /* pick lower of next file or module start index */
+ end_sym = min (next_file_isym, next_module_isym);
+ }
+ else
+ {
+ /* one of them is zero, pick the other */
+ end_sym = max (next_file_isym, next_module_isym);
+ }
+
+ /* As a precaution, check next procedure index too */
+ if (!end_sym)
+ end_sym = next_proc_isym;
+ else
+ end_sym = min (end_sym, next_proc_isym);
+ }
+
+ /* Couldn't find procedure, file, or module, use globals as default */
+ if (!end_sym)
+ end_sym = pxdb_header_p->globals;
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("File psymtab indices: %x to %x\n", start_sym, end_sym);
+ }
+#endif
+
+ pst = hpread_end_psymtab (pst,
+ NULL, /* psymtab_include_list */
+ 0, /* includes_used */
+ end_sym * sizeof (struct dntt_type_block),
+ /* byte index in LNTT of end
+ = capping symbol offset
+ = LDSYMOFF of nextfile */
+ end_adr, /* text high */
+ NULL, /* dependency_list */
+ 0); /* dependencies_used */
+
+ record_pst_syms (start_sym, end_sym);
+
+ if (NULL == pst)
+ warning ("No symbols in psymtab for file \"%s\" [0x%x].", full_name_string, curr_fd);
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("Made new psymtab for file %s (%x to %x), sym %x to %x.\n",
+ full_name_string, start_adr, end_adr, CURR_FILE_ISYM, end_sym);
+ }
+#endif
+ /* Prepare for the next psymtab. */
+ global_syms = objfile->global_psymbols.next;
+ static_syms = objfile->static_psymbols.next;
+ xfree (class_entered);
+
+ curr_fd++;
+ } /* Psymtab for file */
+ else
+ {
+ /* We have a module for which we create a psymtab */
+
+ mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod];
+
+ /* We will include the code ranges of any files that happen to
+ overlap with this module */
+
+ /* So, first pick the lower of the file's and module's start addresses */
+ start_adr = CURR_MODULE_START;
+ if (VALID_CURR_FILE)
+ {
+ if (CURR_FILE_START < CURR_MODULE_START)
+ {
+ TELL_OBJFILE;
+ warning ("File \"%s\" [0x%x] crosses beginning of module \"%s\".",
+ &vt_bits[(long) qFD[curr_fd].sbFile],
+ curr_fd, mod_name_string);
+
+ start_adr = CURR_FILE_START;
+ }
+ }
+
+ /* Also pick the lower of the file's and the module's start symbol indices */
+ start_sym = CURR_MODULE_ISYM;
+ if (VALID_CURR_FILE && (CURR_FILE_ISYM < CURR_MODULE_ISYM))
+ start_sym = CURR_FILE_ISYM;
+
+ /* For the end address, we scan through the files till we find one
+ that overlaps the current module but ends beyond it; if no such file exists we
+ simply use the module's start address.
+ (Note, if file entries themselves overlap
+ we take the longest overlapping extension beyond the end of the module...)
+ We assume that modules never overlap. */
+
+ end_adr = CURR_MODULE_END;
+
+ if (VALID_CURR_FILE)
+ {
+ while (VALID_CURR_FILE && (CURR_FILE_START < end_adr))
+ {
+
+#ifdef DUMPING
+ if (dumping)
+ printf ("Maybe skipping file %s which overlaps with module %s\n",
+ &vt_bits[(long) qFD[curr_fd].sbFile], mod_name_string);
+#endif
+ if (CURR_FILE_END > end_adr)
+ {
+ TELL_OBJFILE;
+ warning ("File \"%s\" [0x%x] crosses end of module \"%s\".",
+ &vt_bits[(long) qFD[curr_fd].sbFile],
+ curr_fd, mod_name_string);
+ end_adr = CURR_FILE_END;
+ }
+ curr_fd++;
+ }
+ curr_fd--; /* back up after going too far */
+ }
+
+ /* Sometimes (compiler bug -- COBOL) the module end address is higher
+ than the start address of the next module, so check for that and
+ adjust accordingly */
+
+ if (VALID_MODULE (curr_md + 1) && (MODULE_START (curr_md + 1) <= end_adr))
+ {
+ TELL_OBJFILE;
+ warning ("Module \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.",
+ mod_name_string, curr_md);
+ end_adr = MODULE_START (curr_md + 1) - 1; /* Is -4 (or -8 for 64-bit) better? */
+ }
+ if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr))
+ {
+ TELL_OBJFILE;
+ warning ("Module \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.",
+ mod_name_string, curr_md);
+ end_adr = FILE_START (curr_fd + 1) - 1; /* Is -4 (or -8 for 64-bit) better? */
+ }
+
+ /* Use one file to get the full name for the module. This
+ situation can arise if there is executable code in a #include
+ file. Each file with code in it gets a qFD. Files which don't
+ contribute code don't get a qFD, even if they include files
+ which do, e.g.:
+
+ body.c: rtn.h:
+ int x; int main() {
+ #include "rtn.h" return x;
+ }
+
+ There will a qFD for "rtn.h",and a qMD for "body.c",
+ but no qMD for "rtn.h" or qFD for "body.c"!
+
+ We pick the name of the last file to overlap with this
+ module. C convention is to put include files first. In a
+ perfect world, we could check names and use the file whose full
+ path name ends with the module name. */
+
+ if (VALID_CURR_FILE)
+ full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile];
+ else
+ full_name_string = mod_name_string;
+
+ /* Check if there are any procedures not handled until now, that
+ begin before the start address we have now, and if so, adjust
+ this psymtab's start address to include them. This handles routines that
+ are in between file or module ranges for some reason (probably
+ indicates a compiler bug */
+
+ if (CURR_PROC_START < start_adr)
+ {
+ TELL_OBJFILE;
+ warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
+ &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd);
+ start_adr = CURR_PROC_START;
+ if (CURR_PROC_ISYM < start_sym)
+ start_sym = CURR_PROC_ISYM;
+ }
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("Make new psymtab for module %s (%x to %x), using file %s\n",
+ mod_name_string, start_adr, end_adr, full_name_string);
+ }
+#endif
+ /* Create the basic psymtab, connecting it in the list
+ for this objfile and pointing its symbol entries
+ to the current end of the symbol areas in the objfile.
+
+ The "ldsymoff" parameter is the byte offset in the LNTT
+ of the first symbol in this file. Some day we should
+ turn this into an index (fix in hp-symtab-read.c as well).
+ And it's not even the right byte offset, as we're using
+ the size of a union! FIXME! */
+ pst = hpread_start_psymtab (objfile,
+ full_name_string,
+ start_adr, /* Low text address */
+ (start_sym * sizeof (struct dntt_type_block)),
+ /* ldsymoff */
+ global_syms,
+ static_syms);
+
+ /* Set up to only enter each class referenced in this module once. */
+ class_entered = xmalloc (B_BYTES (pxdb_header_p->cd_entries));
+ B_CLRALL (class_entered, pxdb_header_p->cd_entries);
+
+ /* Scan the procedure descriptors for procedures in the current
+ module, based on the starting addresses. */
+
+ syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
+ start_adr, end_adr, pst, vt_bits, objfile);
+
+ /* Get ending symbol offset */
+
+ end_sym = 0;
+ /* First check for starting index before previous psymtab */
+ if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end)
+ {
+ end_sym = find_next_pst_start (start_sym);
+ }
+ /* Look for next start index of a file or module, or procedure */
+ if (!end_sym)
+ {
+ int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p);
+ int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md + 1, pxdb_header_p);
+ int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p);
+
+ if (next_file_isym && next_module_isym)
+ {
+ /* pick lower of next file or module start index */
+ end_sym = min (next_file_isym, next_module_isym);
+ }
+ else
+ {
+ /* one of them is zero, pick the other */
+ end_sym = max (next_file_isym, next_module_isym);
+ }
+
+ /* As a precaution, check next procedure index too */
+ if (!end_sym)
+ end_sym = next_proc_isym;
+ else
+ end_sym = min (end_sym, next_proc_isym);
+ }
+
+ /* Couldn't find procedure, file, or module, use globals as default */
+ if (!end_sym)
+ end_sym = pxdb_header_p->globals;
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("Module psymtab indices: %x to %x\n", start_sym, end_sym);
+ }
+#endif
+
+ pst = hpread_end_psymtab (pst,
+ NULL, /* psymtab_include_list */
+ 0, /* includes_used */
+ end_sym * sizeof (struct dntt_type_block),
+ /* byte index in LNTT of end
+ = capping symbol offset
+ = LDSYMOFF of nextfile */
+ end_adr, /* text high */
+ NULL, /* dependency_list */
+ 0); /* dependencies_used */
+
+ record_pst_syms (start_sym, end_sym);
+
+ if (NULL == pst)
+ warning ("No symbols in psymtab for module \"%s\" [0x%x].", mod_name_string, curr_md);
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("Made new psymtab for module %s (%x to %x), sym %x to %x.\n",
+ mod_name_string, start_adr, end_adr, CURR_MODULE_ISYM, end_sym);
+ }
+#endif
+
+ /* Prepare for the next psymtab. */
+ global_syms = objfile->global_psymbols.next;
+ static_syms = objfile->static_psymbols.next;
+ xfree (class_entered);
+
+ curr_md++;
+ curr_fd++;
+ } /* psymtab for module */
+ } /* psymtab for non-bogus file or module */
+ } /* End of while loop over all files & modules */
+
+ /* There may be some routines after all files and modules -- these will get
+ inserted in a separate new module of their own */
+ if (VALID_CURR_PROC)
+ {
+ start_adr = CURR_PROC_START;
+ end_adr = qPD[pxdb_header_p->pd_entries - 1].adrEnd;
+ TELL_OBJFILE;
+ warning ("Found functions beyond end of all files and modules [0x%x].", curr_pd);
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("Orphan functions at end, PD %d and beyond (%x to %x)\n",
+ curr_pd, start_adr, end_adr);
+ }
+#endif
+ pst = hpread_start_psymtab (objfile,
+ "orphans",
+ start_adr, /* Low text address */
+ (CURR_PROC_ISYM * sizeof (struct dntt_type_block)),
+ /* ldsymoff */
+ global_syms,
+ static_syms);
+
+ scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
+ start_adr, end_adr, pst, vt_bits, objfile);
+
+ pst = hpread_end_psymtab (pst,
+ NULL, /* psymtab_include_list */
+ 0, /* includes_used */
+ pxdb_header_p->globals * sizeof (struct dntt_type_block),
+ /* byte index in LNTT of end
+ = capping symbol offset
+ = LDSYMOFF of nextfile */
+ end_adr, /* text high */
+ NULL, /* dependency_list */
+ 0); /* dependencies_used */
+ }
+
+
+#ifdef NEVER_NEVER
+ /* Now build psts for non-module things (in the tail of
+ the LNTT, after the last END MODULE entry).
+
+ If null psts were kept on the chain, this would be
+ a solution. FIXME */
+ pst = hpread_start_psymtab (objfile,
+ "globals",
+ 0,
+ (pxdb_header_p->globals
+ * sizeof (struct dntt_type_block)),
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ hpread_end_psymtab (pst,
+ NULL, 0,
+ (max_LNTT_sym_index * sizeof (struct dntt_type_block)),
+ 0,
+ NULL, 0);
+#endif
+
+ clear_pst_syms ();
+
+ return 1;
+
+} /* End of hpread_quick_traverse. */
+
+
+/* Get appropriate header, based on pxdb type.
+ Return value: 1 if ok, 0 if not */
+int
+hpread_get_header (struct objfile *objfile, PXDB_header_ptr pxdb_header_p)
+{
+ asection *pinfo_section, *debug_section, *header_section;
+
+#ifdef DUMPING
+ /* Turn on for debugging information */
+ static int dumping = 0;
+#endif
+
+ header_section = bfd_get_section_by_name (objfile->obfd, "$HEADER$");
+ if (!header_section)
+ {
+ /* We don't have either PINFO or DEBUG sections. But
+ stuff like "libc.sl" has no debug info. There's no
+ need to warn the user of this, as it may be ok. The
+ caller will figure it out and issue any needed
+ messages. */
+#ifdef DUMPING
+ if (dumping)
+ printf ("==No debug info at all for %s.\n", objfile->name);
+#endif
+
+ return 0;
+ }
+
+ /* We would like either a $DEBUG$ or $PINFO$ section.
+ Once we know which, we can understand the header
+ data (which we have defined to suit the more common
+ $DEBUG$ case). */
+ debug_section = bfd_get_section_by_name (objfile->obfd, "$DEBUG$");
+ pinfo_section = bfd_get_section_by_name (objfile->obfd, "$PINFO$");
+ if (debug_section)
+ {
+ /* The expected case: normal pxdb header. */
+ bfd_get_section_contents (objfile->obfd, header_section,
+ pxdb_header_p, 0, sizeof (PXDB_header));
+
+ if (!pxdb_header_p->pxdbed)
+ {
+ /* This shouldn't happen if we check in "symfile.c". */
+ return 0;
+ } /* DEBUG section */
+ }
+
+ else if (pinfo_section)
+ {
+ /* The DOC case; we need to translate this into a
+ regular header. */
+ DOC_info_PXDB_header doc_header;
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("==OOps, PINFO, let's try to handle this, %s.\n", objfile->name);
+ }
+#endif
+
+ bfd_get_section_contents (objfile->obfd,
+ header_section,
+ &doc_header, 0,
+ sizeof (DOC_info_PXDB_header));
+
+ if (!doc_header.pxdbed)
+ {
+ /* This shouldn't happen if we check in "symfile.c". */
+ warning ("File \"%s\" not processed by pxdb!", objfile->name);
+ return 0;
+ }
+
+ /* Copy relevent fields to standard header passed in. */
+ pxdb_header_p->pd_entries = doc_header.pd_entries;
+ pxdb_header_p->fd_entries = doc_header.fd_entries;
+ pxdb_header_p->md_entries = doc_header.md_entries;
+ pxdb_header_p->pxdbed = doc_header.pxdbed;
+ pxdb_header_p->bighdr = doc_header.bighdr;
+ pxdb_header_p->sa_header = doc_header.sa_header;
+ pxdb_header_p->inlined = doc_header.inlined;
+ pxdb_header_p->globals = doc_header.globals;
+ pxdb_header_p->time = doc_header.time;
+ pxdb_header_p->pg_entries = doc_header.pg_entries;
+ pxdb_header_p->functions = doc_header.functions;
+ pxdb_header_p->files = doc_header.files;
+ pxdb_header_p->cd_entries = doc_header.cd_entries;
+ pxdb_header_p->aa_entries = doc_header.aa_entries;
+ pxdb_header_p->oi_entries = doc_header.oi_entries;
+ pxdb_header_p->version = doc_header.version;
+ } /* PINFO section */
+
+ else
+ {
+#ifdef DUMPING
+ if (dumping)
+ printf ("==No debug info at all for %s.\n", objfile->name);
+#endif
+
+ return 0;
+
+ }
+
+ return 1;
+} /* End of hpread_get_header */
+#endif /* QUICK_LOOK_UP */
+
+
+/* Initialization for reading native HP C debug symbols from OBJFILE.
+
+ Its only purpose in life is to set up the symbol reader's private
+ per-objfile data structures, and read in the raw contents of the debug
+ sections (attaching pointers to the debug info into the private data
+ structures).
+
+ Since BFD doesn't know how to read debug symbols in a format-independent
+ way (and may never do so...), we have to do it ourselves. Note we may
+ be called on a file without native HP C debugging symbols.
+
+ FIXME, there should be a cleaner peephole into the BFD environment
+ here. */
+void
+hpread_symfile_init (struct objfile *objfile)
+{
+ asection *vt_section, *slt_section, *lntt_section, *gntt_section;
+
+ /* Allocate struct to keep track of the symfile */
+ objfile->sym_private = (PTR)
+ xmmalloc (objfile->md, sizeof (struct hpread_symfile_info));
+ memset (objfile->sym_private, 0, sizeof (struct hpread_symfile_info));
+
+ /* We haven't read in any types yet. */
+ DNTT_TYPE_VECTOR (objfile) = 0;
+
+ /* Read in data from the $GNTT$ subspace. */
+ gntt_section = bfd_get_section_by_name (objfile->obfd, "$GNTT$");
+ if (!gntt_section)
+ return;
+
+ GNTT (objfile)
+ = obstack_alloc (&objfile->symbol_obstack,
+ bfd_section_size (objfile->obfd, gntt_section));
+
+ bfd_get_section_contents (objfile->obfd, gntt_section, GNTT (objfile),
+ 0, bfd_section_size (objfile->obfd, gntt_section));
+
+ GNTT_SYMCOUNT (objfile)
+ = bfd_section_size (objfile->obfd, gntt_section)
+ / sizeof (struct dntt_type_block);
+
+ /* Read in data from the $LNTT$ subspace. Also keep track of the number
+ of LNTT symbols.
+
+ FIXME: this could be moved into the psymtab-to-symtab expansion
+ code, and save startup time. At the moment this data is
+ still used, though. We'd need a way to tell hp-symtab-read.c
+ whether or not to load the LNTT. */
+ lntt_section = bfd_get_section_by_name (objfile->obfd, "$LNTT$");
+ if (!lntt_section)
+ return;
+
+ LNTT (objfile)
+ = obstack_alloc (&objfile->symbol_obstack,
+ bfd_section_size (objfile->obfd, lntt_section));
+
+ bfd_get_section_contents (objfile->obfd, lntt_section, LNTT (objfile),
+ 0, bfd_section_size (objfile->obfd, lntt_section));
+
+ LNTT_SYMCOUNT (objfile)
+ = bfd_section_size (objfile->obfd, lntt_section)
+ / sizeof (struct dntt_type_block);
+
+ /* Read in data from the $SLT$ subspace. $SLT$ contains information
+ on source line numbers. */
+ slt_section = bfd_get_section_by_name (objfile->obfd, "$SLT$");
+ if (!slt_section)
+ return;
+
+ SLT (objfile) =
+ obstack_alloc (&objfile->symbol_obstack,
+ bfd_section_size (objfile->obfd, slt_section));
+
+ bfd_get_section_contents (objfile->obfd, slt_section, SLT (objfile),
+ 0, bfd_section_size (objfile->obfd, slt_section));
+
+ /* Read in data from the $VT$ subspace. $VT$ contains things like
+ names and constants. Keep track of the number of symbols in the VT. */
+ vt_section = bfd_get_section_by_name (objfile->obfd, "$VT$");
+ if (!vt_section)
+ return;
+
+ VT_SIZE (objfile) = bfd_section_size (objfile->obfd, vt_section);
+
+ VT (objfile) =
+ (char *) obstack_alloc (&objfile->symbol_obstack,
+ VT_SIZE (objfile));
+
+ bfd_get_section_contents (objfile->obfd, vt_section, VT (objfile),
+ 0, VT_SIZE (objfile));
+}
+
+/* Scan and build partial symbols for a symbol file.
+
+ The minimal symbol table (either SOM or HP a.out) has already been
+ read in; all we need to do is setup partial symbols based on the
+ native debugging information.
+
+ Note that the minimal table is produced by the linker, and has
+ only global routines in it; the psymtab is based on compiler-
+ generated debug information and has non-global
+ routines in it as well as files and class information.
+
+ We assume hpread_symfile_init has been called to initialize the
+ symbol reader's private data structures.
+
+ MAINLINE is true if we are reading the main symbol table (as
+ opposed to a shared lib or dynamically loaded file). */
+
+void
+hpread_build_psymtabs (struct objfile *objfile, int mainline)
+{
+
+#ifdef DUMPING
+ /* Turn this on to get debugging output. */
+ static int dumping = 0;
+#endif
+
+ char *namestring;
+ int past_first_source_file = 0;
+ struct cleanup *old_chain;
+
+ int hp_symnum, symcount, i;
+ int scan_start = 0;
+
+ union dnttentry *dn_bufp;
+ unsigned long valu;
+ char *p;
+ int texthigh = 0;
+ int have_name = 0;
+
+ /* Current partial symtab */
+ struct partial_symtab *pst;
+
+ /* List of current psymtab's include files */
+ char **psymtab_include_list;
+ int includes_allocated;
+ int includes_used;
+
+ /* Index within current psymtab dependency list */
+ struct partial_symtab **dependency_list;
+ int dependencies_used, dependencies_allocated;
+
+ /* Just in case the stabs reader left turds lying around. */
+ free_pending_blocks ();
+ make_cleanup (really_free_pendings, 0);
+
+ pst = (struct partial_symtab *) 0;
+
+ /* We shouldn't use alloca, instead use malloc/free. Doing so avoids
+ a number of problems with cross compilation and creating useless holes
+ in the stack when we have to allocate new entries. FIXME. */
+
+ includes_allocated = 30;
+ includes_used = 0;
+ psymtab_include_list = (char **) alloca (includes_allocated *
+ sizeof (char *));
+
+ dependencies_allocated = 30;
+ dependencies_used = 0;
+ dependency_list =
+ (struct partial_symtab **) alloca (dependencies_allocated *
+ sizeof (struct partial_symtab *));
+
+ old_chain = make_cleanup_free_objfile (objfile);
+
+ last_source_file = 0;
+
+#ifdef QUICK_LOOK_UP
+ {
+ /* Begin code for new-style loading of quick look-up tables. */
+
+ /* elz: this checks whether the file has beeen processed by pxdb.
+ If not we would like to try to read the psymbols in
+ anyway, but it turns out to be not so easy. So this could
+ actually be commented out, but I leave it in, just in case
+ we decide to add support for non-pxdb-ed stuff in the future. */
+ PXDB_header pxdb_header;
+ int found_modules_in_program;
+
+ if (hpread_get_header (objfile, &pxdb_header))
+ {
+ /* Build a minimal table. No types, no global variables,
+ no include files.... */
+#ifdef DUMPING
+ if (dumping)
+ printf ("\nNew method for %s\n", objfile->name);
+#endif
+
+ /* elz: quick_traverse returns true if it found
+ some modules in the main source file, other
+ than those in end.c
+ In C and C++, all the files have MODULES entries
+ in the LNTT, and the quick table traverse is all
+ based on finding these MODULES entries. Without
+ those it cannot work.
+ It happens that F77 programs don't have MODULES
+ so the quick traverse gets confused. F90 programs
+ have modules, and the quick method still works.
+ So, if modules (other than those in end.c) are
+ not found we give up on the quick table stuff,
+ and fall back on the slower method */
+ found_modules_in_program = hpread_quick_traverse (objfile,
+ GNTT (objfile),
+ VT (objfile),
+ &pxdb_header);
+
+ discard_cleanups (old_chain);
+
+ /* Set up to scan the global section of the LNTT.
+
+ This field is not always correct: if there are
+ no globals, it will point to the last record in
+ the regular LNTT, which is usually an END MODULE.
+
+ Since it might happen that there could be a file
+ with just one global record, there's no way to
+ tell other than by looking at the record, so that's
+ done below. */
+ if (found_modules_in_program)
+ scan_start = pxdb_header.globals;
+ }
+#ifdef DUMPING
+ else
+ {
+ if (dumping)
+ printf ("\nGoing on to old method for %s\n", objfile->name);
+ }
+#endif
+ }
+#endif /* QUICK_LOOK_UP */
+
+ /* Make two passes, one over the GNTT symbols, the other for the
+ LNTT symbols.
+
+ JB comment: above isn't true--they only make one pass, over
+ the LNTT. */
+ for (i = 0; i < 1; i++)
+ {
+ int within_function = 0;
+
+ if (i)
+ symcount = GNTT_SYMCOUNT (objfile);
+ else
+ symcount = LNTT_SYMCOUNT (objfile);
+
+
+ for (hp_symnum = scan_start; hp_symnum < symcount; hp_symnum++)
+ {
+ QUIT;
+ if (i)
+ dn_bufp = hpread_get_gntt (hp_symnum, objfile);
+ else
+ dn_bufp = hpread_get_lntt (hp_symnum, objfile);
+
+ if (dn_bufp->dblock.extension)
+ continue;
+
+ /* Only handle things which are necessary for minimal symbols.
+ everything else is ignored. */
+ switch (dn_bufp->dblock.kind)
+ {
+ case DNTT_TYPE_SRCFILE:
+ {
+#ifdef QUICK_LOOK_UP
+ if (scan_start == hp_symnum
+ && symcount == hp_symnum + 1)
+ {
+ /* If there are NO globals in an executable,
+ PXDB's index to the globals will point to
+ the last record in the file, which
+ could be this record. (this happened for F77 libraries)
+ ignore it and be done! */
+ continue;
+ }
+#endif /* QUICK_LOOK_UP */
+
+ /* A source file of some kind. Note this may simply
+ be an included file. */
+ SET_NAMESTRING (dn_bufp, &namestring, objfile);
+
+ /* Check if this is the source file we are already working
+ with. */
+ if (pst && !strcmp (namestring, pst->filename))
+ continue;
+
+ /* Check if this is an include file, if so check if we have
+ already seen it. Add it to the include list */
+ p = strrchr (namestring, '.');
+ if (!strcmp (p, ".h"))
+ {
+ int j, found;
+
+ found = 0;
+ for (j = 0; j < includes_used; j++)
+ if (!strcmp (namestring, psymtab_include_list[j]))
+ {
+ found = 1;
+ break;
+ }
+ if (found)
+ continue;
+
+ /* Add it to the list of includes seen so far and
+ allocate more include space if necessary. */
+ psymtab_include_list[includes_used++] = namestring;
+ if (includes_used >= includes_allocated)
+ {
+ char **orig = psymtab_include_list;
+
+ psymtab_include_list = (char **)
+ alloca ((includes_allocated *= 2) *
+ sizeof (char *));
+ memcpy ((PTR) psymtab_include_list, (PTR) orig,
+ includes_used * sizeof (char *));
+ }
+ continue;
+ }
+
+ if (pst)
+ {
+ if (!have_name)
+ {
+ pst->filename = (char *)
+ obstack_alloc (&pst->objfile->psymbol_obstack,
+ strlen (namestring) + 1);
+ strcpy (pst->filename, namestring);
+ have_name = 1;
+ continue;
+ }
+ continue;
+ }
+
+ /* This is a bonafide new source file.
+ End the current partial symtab and start a new one. */
+
+ if (pst && past_first_source_file)
+ {
+ hpread_end_psymtab (pst, psymtab_include_list,
+ includes_used,
+ (hp_symnum
+ * sizeof (struct dntt_type_block)),
+ texthigh,
+ dependency_list, dependencies_used);
+ pst = (struct partial_symtab *) 0;
+ includes_used = 0;
+ dependencies_used = 0;
+ }
+ else
+ past_first_source_file = 1;
+
+ valu = hpread_get_textlow (i, hp_symnum, objfile, symcount);
+ valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ pst = hpread_start_psymtab (objfile,
+ namestring, valu,
+ (hp_symnum
+ * sizeof (struct dntt_type_block)),
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ texthigh = valu;
+ have_name = 1;
+ continue;
+ }
+
+ case DNTT_TYPE_MODULE:
+ /* A source file. It's still unclear to me what the
+ real difference between a DNTT_TYPE_SRCFILE and DNTT_TYPE_MODULE
+ is supposed to be. */
+
+ /* First end the previous psymtab */
+ if (pst)
+ {
+ hpread_end_psymtab (pst, psymtab_include_list, includes_used,
+ ((hp_symnum - 1)
+ * sizeof (struct dntt_type_block)),
+ texthigh,
+ dependency_list, dependencies_used);
+ pst = (struct partial_symtab *) 0;
+ includes_used = 0;
+ dependencies_used = 0;
+ have_name = 0;
+ }
+
+ /* Now begin a new module and a new psymtab for it */
+ SET_NAMESTRING (dn_bufp, &namestring, objfile);
+ valu = hpread_get_textlow (i, hp_symnum, objfile, symcount);
+ valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ if (!pst)
+ {
+ pst = hpread_start_psymtab (objfile,
+ namestring, valu,
+ (hp_symnum
+ * sizeof (struct dntt_type_block)),
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ texthigh = valu;
+ have_name = 0;
+ }
+ continue;
+
+ case DNTT_TYPE_FUNCTION:
+ case DNTT_TYPE_ENTRY:
+ /* The beginning of a function. DNTT_TYPE_ENTRY may also denote
+ a secondary entry point. */
+ valu = dn_bufp->dfunc.hiaddr + ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
+ if (valu > texthigh)
+ texthigh = valu;
+ valu = dn_bufp->dfunc.lowaddr +
+ ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ SET_NAMESTRING (dn_bufp, &namestring, objfile);
+ if (dn_bufp->dfunc.global)
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->global_psymbols, valu,
+ 0, language_unknown, objfile);
+ else
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->static_psymbols, valu,
+ 0, language_unknown, objfile);
+ within_function = 1;
+ continue;
+
+ case DNTT_TYPE_DOC_FUNCTION:
+ valu = dn_bufp->ddocfunc.hiaddr + ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
+ if (valu > texthigh)
+ texthigh = valu;
+ valu = dn_bufp->ddocfunc.lowaddr +
+ ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ SET_NAMESTRING (dn_bufp, &namestring, objfile);
+ if (dn_bufp->ddocfunc.global)
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->global_psymbols, valu,
+ 0, language_unknown, objfile);
+ else
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->static_psymbols, valu,
+ 0, language_unknown, objfile);
+ within_function = 1;
+ continue;
+
+ case DNTT_TYPE_BEGIN:
+ case DNTT_TYPE_END:
+ /* We don't check MODULE end here, because there can be
+ symbols beyond the module end which properly belong to the
+ current psymtab -- so we wait till the next MODULE start */
+
+
+#ifdef QUICK_LOOK_UP
+ if (scan_start == hp_symnum
+ && symcount == hp_symnum + 1)
+ {
+ /* If there are NO globals in an executable,
+ PXDB's index to the globals will point to
+ the last record in the file, which is
+ probably an END MODULE, i.e. this record.
+ ignore it and be done! */
+ continue;
+ }
+#endif /* QUICK_LOOK_UP */
+
+ /* Scope block begin/end. We only care about function
+ and file blocks right now. */
+
+ if ((dn_bufp->dend.endkind == DNTT_TYPE_FUNCTION) ||
+ (dn_bufp->dend.endkind == DNTT_TYPE_DOC_FUNCTION))
+ within_function = 0;
+ continue;
+
+ case DNTT_TYPE_SVAR:
+ case DNTT_TYPE_DVAR:
+ case DNTT_TYPE_TYPEDEF:
+ case DNTT_TYPE_TAGDEF:
+ {
+ /* Variables, typedefs an the like. */
+ enum address_class storage;
+ namespace_enum namespace;
+
+ /* Don't add locals to the partial symbol table. */
+ if (within_function
+ && (dn_bufp->dblock.kind == DNTT_TYPE_SVAR
+ || dn_bufp->dblock.kind == DNTT_TYPE_DVAR))
+ continue;
+
+ /* TAGDEFs go into the structure namespace. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF)
+ namespace = STRUCT_NAMESPACE;
+ else
+ namespace = VAR_NAMESPACE;
+
+ /* What kind of "storage" does this use? */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_SVAR)
+ storage = LOC_STATIC;
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR
+ && dn_bufp->ddvar.regvar)
+ storage = LOC_REGISTER;
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR)
+ storage = LOC_LOCAL;
+ else
+ storage = LOC_UNDEF;
+
+ SET_NAMESTRING (dn_bufp, &namestring, objfile);
+ if (!pst)
+ {
+ pst = hpread_start_psymtab (objfile,
+ "globals", 0,
+ (hp_symnum
+ * sizeof (struct dntt_type_block)),
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ }
+
+ /* Compute address of the data symbol */
+ valu = dn_bufp->dsvar.location;
+ /* Relocate in case it's in a shared library */
+ if (storage == LOC_STATIC)
+ valu += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+
+ /* Luckily, dvar, svar, typedef, and tagdef all
+ have their "global" bit in the same place, so it works
+ (though it's bad programming practice) to reference
+ "dsvar.global" even though we may be looking at
+ any of the above four types. */
+ if (dn_bufp->dsvar.global)
+ {
+ add_psymbol_to_list (namestring, strlen (namestring),
+ namespace, storage,
+ &objfile->global_psymbols,
+ valu,
+ 0, language_unknown, objfile);
+ }
+ else
+ {
+ add_psymbol_to_list (namestring, strlen (namestring),
+ namespace, storage,
+ &objfile->static_psymbols,
+ valu,
+ 0, language_unknown, objfile);
+ }
+
+ /* For TAGDEF's, the above code added the tagname to the
+ struct namespace. This will cause tag "t" to be found
+ on a reference of the form "(struct t) x". But for
+ C++ classes, "t" will also be a typename, which we
+ want to find on a reference of the form "ptype t".
+ Therefore, we also add "t" to the var namespace.
+ Do the same for enum's due to the way aCC generates
+ debug info for these (see more extended comment
+ in hp-symtab-read.c).
+ We do the same for templates, so that "ptype t"
+ where "t" is a template also works. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF &&
+ dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
+ {
+ int global = dn_bufp->dtag.global;
+ /* Look ahead to see if it's a C++ class */
+ dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile);
+ if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS ||
+ dn_bufp->dblock.kind == DNTT_TYPE_ENUM ||
+ dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+ {
+ if (global)
+ {
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, storage,
+ &objfile->global_psymbols,
+ dn_bufp->dsvar.location,
+ 0, language_unknown, objfile);
+ }
+ else
+ {
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, storage,
+ &objfile->static_psymbols,
+ dn_bufp->dsvar.location,
+ 0, language_unknown, objfile);
+ }
+ }
+ }
+ }
+ continue;
+
+ case DNTT_TYPE_MEMENUM:
+ case DNTT_TYPE_CONST:
+ /* Constants and members of enumerated types. */
+ SET_NAMESTRING (dn_bufp, &namestring, objfile);
+ if (!pst)
+ {
+ pst = hpread_start_psymtab (objfile,
+ "globals", 0,
+ (hp_symnum
+ * sizeof (struct dntt_type_block)),
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ }
+ if (dn_bufp->dconst.global)
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->global_psymbols, 0,
+ 0, language_unknown, objfile);
+ else
+ add_psymbol_to_list (namestring, strlen (namestring),
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols, 0,
+ 0, language_unknown, objfile);
+ continue;
+ default:
+ continue;
+ }
+ }
+ }
+
+ /* End any pending partial symbol table. */
+ if (pst)
+ {
+ hpread_end_psymtab (pst, psymtab_include_list, includes_used,
+ hp_symnum * sizeof (struct dntt_type_block),
+ 0, dependency_list, dependencies_used);
+ }
+
+ discard_cleanups (old_chain);
+}
+
+/* Perform any local cleanups required when we are done with a particular
+ objfile. I.E, we are in the process of discarding all symbol information
+ for an objfile, freeing up all memory held for it, and unlinking the
+ objfile struct from the global list of known objfiles. */
+
+void
+hpread_symfile_finish (struct objfile *objfile)
+{
+ if (objfile->sym_private != NULL)
+ {
+ xmfree (objfile->md, objfile->sym_private);
+ }
+}
+
+
+/* The remaining functions are all for internal use only. */
+
+/* Various small functions to get entries in the debug symbol sections. */
+
+union dnttentry *
+hpread_get_lntt (int index, struct objfile *objfile)
+{
+ return (union dnttentry *)
+ &(LNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
+}
+
+static union dnttentry *
+hpread_get_gntt (int index, struct objfile *objfile)
+{
+ return (union dnttentry *)
+ &(GNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
+}
+
+union sltentry *
+hpread_get_slt (int index, struct objfile *objfile)
+{
+ return (union sltentry *) &(SLT (objfile)[index * sizeof (union sltentry)]);
+}
+
+/* Get the low address associated with some symbol (typically the start
+ of a particular source file or module). Since that information is not
+ stored as part of the DNTT_TYPE_MODULE or DNTT_TYPE_SRCFILE symbol we
+ must infer it from the existence of DNTT_TYPE_FUNCTION symbols. */
+
+static unsigned long
+hpread_get_textlow (int global, int index, struct objfile *objfile,
+ int symcount)
+{
+ union dnttentry *dn_bufp;
+ struct minimal_symbol *msymbol;
+
+ /* Look for a DNTT_TYPE_FUNCTION symbol. */
+ if (index < symcount) /* symcount is the number of symbols in */
+ { /* the dbinfo, LNTT table */
+ do
+ {
+ if (global)
+ dn_bufp = hpread_get_gntt (index++, objfile);
+ else
+ dn_bufp = hpread_get_lntt (index++, objfile);
+ }
+ while (dn_bufp->dblock.kind != DNTT_TYPE_FUNCTION
+ && dn_bufp->dblock.kind != DNTT_TYPE_DOC_FUNCTION
+ && dn_bufp->dblock.kind != DNTT_TYPE_END
+ && index < symcount);
+ }
+
+ /* Avoid going past a DNTT_TYPE_END when looking for a DNTT_TYPE_FUNCTION. This
+ might happen when a sourcefile has no functions. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_END)
+ return 0;
+
+ /* Avoid going past the end of the LNTT file */
+ if (index == symcount)
+ return 0;
+
+ /* The minimal symbols are typically more accurate for some reason. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION)
+ msymbol = lookup_minimal_symbol (dn_bufp->dfunc.name + VT (objfile), NULL,
+ objfile);
+ else /* must be a DNTT_TYPE_DOC_FUNCTION */
+ msymbol = lookup_minimal_symbol (dn_bufp->ddocfunc.name + VT (objfile), NULL,
+ objfile);
+
+ if (msymbol)
+ return SYMBOL_VALUE_ADDRESS (msymbol);
+ else
+ return dn_bufp->dfunc.lowaddr;
+}
+
+/* Allocate and partially fill a partial symtab. It will be
+ completely filled at the end of the symbol list.
+
+ SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
+ is the address relative to which its symbols are (incremental) or 0
+ (normal). */
+
+static struct partial_symtab *
+hpread_start_psymtab (struct objfile *objfile, char *filename,
+ CORE_ADDR textlow, int ldsymoff,
+ struct partial_symbol **global_syms,
+ struct partial_symbol **static_syms)
+{
+ int offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ extern void hpread_psymtab_to_symtab ();
+ struct partial_symtab *result =
+ start_psymtab_common (objfile, objfile->section_offsets,
+ filename, textlow, global_syms, static_syms);
+
+ result->textlow += offset;
+ result->read_symtab_private = (char *)
+ obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
+ LDSYMOFF (result) = ldsymoff;
+ result->read_symtab = hpread_psymtab_to_symtab;
+
+ return result;
+}
+
+
+/* Close off the current usage of PST.
+ Returns PST or NULL if the partial symtab was empty and thrown away.
+
+ capping_symbol_offset --Byte index in LNTT or GNTT of the
+ last symbol processed during the build
+ of the previous pst.
+
+ FIXME: List variables and peculiarities of same. */
+
+static struct partial_symtab *
+hpread_end_psymtab (struct partial_symtab *pst, char **include_list,
+ int num_includes, int capping_symbol_offset,
+ CORE_ADDR capping_text,
+ struct partial_symtab **dependency_list,
+ int number_dependencies)
+{
+ int i;
+ struct objfile *objfile = pst->objfile;
+ int offset = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
+
+#ifdef DUMPING
+ /* Turn on to see what kind of a psymtab we've built. */
+ static int dumping = 0;
+#endif
+
+ if (capping_symbol_offset != -1)
+ LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
+ else
+ LDSYMLEN (pst) = 0;
+ pst->texthigh = capping_text + offset;
+
+ pst->n_global_syms =
+ objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
+ pst->n_static_syms =
+ objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset);
+
+#ifdef DUMPING
+ if (dumping)
+ {
+ printf ("\nPst %s, LDSYMOFF %x (%x), LDSYMLEN %x (%x), globals %d, statics %d\n",
+ pst->filename,
+ LDSYMOFF (pst),
+ LDSYMOFF (pst) / sizeof (struct dntt_type_block),
+ LDSYMLEN (pst),
+ LDSYMLEN (pst) / sizeof (struct dntt_type_block),
+ pst->n_global_syms, pst->n_static_syms);
+ }
+#endif
+
+ pst->number_of_dependencies = number_dependencies;
+ if (number_dependencies)
+ {
+ pst->dependencies = (struct partial_symtab **)
+ obstack_alloc (&objfile->psymbol_obstack,
+ number_dependencies * sizeof (struct partial_symtab *));
+ memcpy (pst->dependencies, dependency_list,
+ number_dependencies * sizeof (struct partial_symtab *));
+ }
+ else
+ pst->dependencies = 0;
+
+ for (i = 0; i < num_includes; i++)
+ {
+ struct partial_symtab *subpst =
+ allocate_psymtab (include_list[i], objfile);
+
+ subpst->section_offsets = pst->section_offsets;
+ subpst->read_symtab_private =
+ (char *) obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct symloc));
+ LDSYMOFF (subpst) =
+ LDSYMLEN (subpst) =
+ subpst->textlow =
+ subpst->texthigh = 0;
+
+ /* We could save slight bits of space by only making one of these,
+ shared by the entire set of include files. FIXME-someday. */
+ subpst->dependencies = (struct partial_symtab **)
+ obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct partial_symtab *));
+ subpst->dependencies[0] = pst;
+ subpst->number_of_dependencies = 1;
+
+ subpst->globals_offset =
+ subpst->n_global_syms =
+ subpst->statics_offset =
+ subpst->n_static_syms = 0;
+
+ subpst->readin = 0;
+ subpst->symtab = 0;
+ subpst->read_symtab = pst->read_symtab;
+ }
+
+ sort_pst_symbols (pst);
+
+ /* If there is already a psymtab or symtab for a file of this name, remove it.
+ (If there is a symtab, more drastic things also happen.)
+ This happens in VxWorks. */
+ free_named_symtabs (pst->filename);
+
+ if (num_includes == 0
+ && number_dependencies == 0
+ && pst->n_global_syms == 0
+ && pst->n_static_syms == 0)
+ {
+ /* Throw away this psymtab, it's empty. We can't deallocate it, since
+ it is on the obstack, but we can forget to chain it on the list.
+ Empty psymtabs happen as a result of header files which don't have
+ any symbols in them. There can be a lot of them. But this check
+ is wrong, in that a psymtab with N_SLINE entries but nothing else
+ is not empty, but we don't realize that. Fixing that without slowing
+ things down might be tricky.
+ It's also wrong if we're using the quick look-up tables, as
+ we can get empty psymtabs from modules with no routines in
+ them. */
+
+ discard_psymtab (pst);
+
+ /* Indicate that psymtab was thrown away. */
+ pst = (struct partial_symtab *) NULL;
+
+ }
+ return pst;
+}
+
+
+/* Get the nesting depth for the source line identified by INDEX. */
+
+static unsigned long
+hpread_get_scope_start (sltpointer index, struct objfile *objfile)
+{
+ union sltentry *sl_bufp;
+
+ sl_bufp = hpread_get_slt (index, objfile);
+ return sl_bufp->sspec.backptr.dnttp.index;
+}
+
+/* Get the source line number the the line identified by INDEX. */
+
+static unsigned long
+hpread_get_line (sltpointer index, struct objfile *objfile)
+{
+ union sltentry *sl_bufp;
+
+ sl_bufp = hpread_get_slt (index, objfile);
+ return sl_bufp->snorm.line;
+}
+
+/* Find the code address associated with a given sltpointer */
+
+static CORE_ADDR
+hpread_get_location (sltpointer index, struct objfile *objfile)
+{
+ union sltentry *sl_bufp;
+ int i;
+
+ /* code location of special sltentrys is determined from context */
+ sl_bufp = hpread_get_slt (index, objfile);
+
+ if (sl_bufp->snorm.sltdesc == SLT_END)
+ {
+ /* find previous normal sltentry and get address */
+ for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
+ (sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) &&
+ (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
+ sl_bufp = hpread_get_slt (index - i, objfile);
+ if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
+ return sl_bufp->snormoff.address;
+ else
+ return sl_bufp->snorm.address;
+ }
+
+ /* find next normal sltentry and get address */
+ for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
+ (sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) &&
+ (sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
+ sl_bufp = hpread_get_slt (index + i, objfile);
+ if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
+ return sl_bufp->snormoff.address;
+ else
+ return sl_bufp->snorm.address;
+}
+
+
+/* Return 1 if an HP debug symbol of type KIND has a name associated with
+ * it, else return 0. (This function is not currently used, but I'll
+ * leave it here in case it proves useful later on. - RT).
+ */
+
+int
+hpread_has_name (enum dntt_entry_type kind)
+{
+ switch (kind)
+ {
+ case DNTT_TYPE_SRCFILE:
+ case DNTT_TYPE_MODULE:
+ case DNTT_TYPE_FUNCTION:
+ case DNTT_TYPE_DOC_FUNCTION:
+ case DNTT_TYPE_ENTRY:
+ case DNTT_TYPE_IMPORT:
+ case DNTT_TYPE_LABEL:
+ case DNTT_TYPE_FPARAM:
+ case DNTT_TYPE_SVAR:
+ case DNTT_TYPE_DVAR:
+ case DNTT_TYPE_CONST:
+ case DNTT_TYPE_TYPEDEF:
+ case DNTT_TYPE_TAGDEF:
+ case DNTT_TYPE_MEMENUM:
+ case DNTT_TYPE_FIELD:
+ case DNTT_TYPE_SA:
+ case DNTT_TYPE_BLOCKDATA:
+ case DNTT_TYPE_MEMFUNC:
+ case DNTT_TYPE_DOC_MEMFUNC:
+ return 1;
+
+ case DNTT_TYPE_BEGIN:
+ case DNTT_TYPE_END:
+ case DNTT_TYPE_POINTER:
+ case DNTT_TYPE_ENUM:
+ case DNTT_TYPE_SET:
+ case DNTT_TYPE_ARRAY:
+ case DNTT_TYPE_STRUCT:
+ case DNTT_TYPE_UNION:
+ case DNTT_TYPE_VARIANT:
+ case DNTT_TYPE_FILE:
+ case DNTT_TYPE_FUNCTYPE:
+ case DNTT_TYPE_SUBRANGE:
+ case DNTT_TYPE_WITH:
+ case DNTT_TYPE_COMMON:
+ case DNTT_TYPE_COBSTRUCT:
+ case DNTT_TYPE_XREF:
+ case DNTT_TYPE_MACRO:
+ case DNTT_TYPE_CLASS_SCOPE:
+ case DNTT_TYPE_REFERENCE:
+ case DNTT_TYPE_PTRMEM:
+ case DNTT_TYPE_PTRMEMFUNC:
+ case DNTT_TYPE_CLASS:
+ case DNTT_TYPE_GENFIELD:
+ case DNTT_TYPE_VFUNC:
+ case DNTT_TYPE_MEMACCESS:
+ case DNTT_TYPE_INHERITANCE:
+ case DNTT_TYPE_FRIEND_CLASS:
+ case DNTT_TYPE_FRIEND_FUNC:
+ case DNTT_TYPE_MODIFIER:
+ case DNTT_TYPE_OBJECT_ID:
+ case DNTT_TYPE_TEMPLATE:
+ case DNTT_TYPE_TEMPLATE_ARG:
+ case DNTT_TYPE_FUNC_TEMPLATE:
+ case DNTT_TYPE_LINK:
+ /* DNTT_TYPE_DYN_ARRAY_DESC ? */
+ /* DNTT_TYPE_DESC_SUBRANGE ? */
+ /* DNTT_TYPE_BEGIN_EXT ? */
+ /* DNTT_TYPE_INLN ? */
+ /* DNTT_TYPE_INLN_LIST ? */
+ /* DNTT_TYPE_ALIAS ? */
+ default:
+ return 0;
+ }
+}
+
+/* Do the dirty work of reading in the full symbol from a partial symbol
+ table. */
+
+static void
+hpread_psymtab_to_symtab_1 (struct partial_symtab *pst)
+{
+ struct cleanup *old_chain;
+ int i;
+
+ /* Get out quick if passed junk. */
+ if (!pst)
+ return;
+
+ /* Complain if we've already read in this symbol table. */
+ if (pst->readin)
+ {
+ fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in."
+ " Shouldn't happen.\n",
+ pst->filename);
+ return;
+ }
+
+ /* Read in all partial symtabs on which this one is dependent */
+ for (i = 0; i < pst->number_of_dependencies; i++)
+ if (!pst->dependencies[i]->readin)
+ {
+ /* Inform about additional files that need to be read in. */
+ if (info_verbose)
+ {
+ fputs_filtered (" ", gdb_stdout);
+ wrap_here ("");
+ fputs_filtered ("and ", gdb_stdout);
+ wrap_here ("");
+ printf_filtered ("%s...", pst->dependencies[i]->filename);
+ wrap_here (""); /* Flush output */
+ gdb_flush (gdb_stdout);
+ }
+ hpread_psymtab_to_symtab_1 (pst->dependencies[i]);
+ }
+
+ /* If it's real... */
+ if (LDSYMLEN (pst))
+ {
+ /* Init stuff necessary for reading in symbols */
+ buildsym_init ();
+ old_chain = make_cleanup (really_free_pendings, 0);
+
+ pst->symtab =
+ hpread_expand_symtab (pst->objfile, LDSYMOFF (pst), LDSYMLEN (pst),
+ pst->textlow, pst->texthigh - pst->textlow,
+ pst->section_offsets, pst->filename);
+ sort_symtab_syms (pst->symtab);
+
+ do_cleanups (old_chain);
+ }
+
+ pst->readin = 1;
+}
+
+/* Read in all of the symbols for a given psymtab for real.
+ Be verbose about it if the user wants that. */
+
+void
+hpread_psymtab_to_symtab (struct partial_symtab *pst)
+{
+ /* Get out quick if given junk. */
+ if (!pst)
+ return;
+
+ /* Sanity check. */
+ if (pst->readin)
+ {
+ fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in."
+ " Shouldn't happen.\n",
+ pst->filename);
+ return;
+ }
+
+ /* elz: setting the flag to indicate that the code of the target
+ was compiled using an HP compiler (aCC, cc)
+ the processing_acc_compilation variable is declared in the
+ file buildsym.h, the HP_COMPILED_TARGET is defined to be equal
+ to 3 in the file tm_hppa.h */
+
+ processing_gcc_compilation = 0;
+
+ if (LDSYMLEN (pst) || pst->number_of_dependencies)
+ {
+ /* Print the message now, before reading the string table,
+ to avoid disconcerting pauses. */
+ if (info_verbose)
+ {
+ printf_filtered ("Reading in symbols for %s...", pst->filename);
+ gdb_flush (gdb_stdout);
+ }
+
+ hpread_psymtab_to_symtab_1 (pst);
+
+ /* Match with global symbols. This only needs to be done once,
+ after all of the symtabs and dependencies have been read in. */
+ scan_file_globals (pst->objfile);
+
+ /* Finish up the debug error message. */
+ if (info_verbose)
+ printf_filtered ("done.\n");
+ }
+}
+
+/* Read in a defined section of a specific object file's symbols.
+
+ DESC is the file descriptor for the file, positioned at the
+ beginning of the symtab
+ SYM_OFFSET is the offset within the file of
+ the beginning of the symbols we want to read
+ SYM_SIZE is the size of the symbol info to read in.
+ TEXT_OFFSET is the beginning of the text segment we are reading symbols for
+ TEXT_SIZE is the size of the text segment read in.
+ SECTION_OFFSETS are the relocation offsets which get added to each symbol. */
+
+static struct symtab *
+hpread_expand_symtab (struct objfile *objfile, int sym_offset, int sym_size,
+ CORE_ADDR text_offset, int text_size,
+ struct section_offsets *section_offsets, char *filename)
+{
+ char *namestring;
+ union dnttentry *dn_bufp;
+ unsigned max_symnum;
+ int at_module_boundary = 0;
+ /* 1 => at end, -1 => at beginning */
+
+ int sym_index = sym_offset / sizeof (struct dntt_type_block);
+
+ current_objfile = objfile;
+ subfile_stack = 0;
+
+ last_source_file = 0;
+
+ /* Demangling style -- if EDG style already set, don't change it,
+ as HP style causes some problems with the KAI EDG compiler */
+ if (current_demangling_style != edg_demangling)
+ {
+ /* Otherwise, ensure that we are using HP style demangling */
+ set_demangling_style (HP_DEMANGLING_STYLE_STRING);
+ }
+
+ dn_bufp = hpread_get_lntt (sym_index, objfile);
+ if (!((dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_SRCFILE) ||
+ (dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_MODULE)))
+ {
+ start_symtab ("globals", NULL, 0);
+ record_debugformat ("HP");
+ }
+
+ /* The psymtab builder (hp-psymtab-read.c) is the one that
+ * determined the "sym_size" argument (i.e. how many DNTT symbols
+ * are in this symtab), which we use to compute "max_symnum"
+ * (point in DNTT to which we read).
+ *
+ * Perhaps this should be changed so that
+ * process_one_debug_symbol() "knows" when
+ * to stop reading (based on reading from the MODULE to the matching
+ * END), and take out this reliance on a #-syms being passed in...
+ * (I'm worried about the reliability of this number). But I'll
+ * leave it as-is, for now. - RT
+ *
+ * The change above has been made. I've left the "for" loop control
+ * in to prepare for backing this out again. -JB
+ */
+ max_symnum = sym_size / sizeof (struct dntt_type_block);
+ /* No reason to multiply on pst side and divide on sym side... FIXME */
+
+ /* Read in and process each debug symbol within the specified range.
+ */
+ for (symnum = 0;
+ symnum < max_symnum;
+ symnum++)
+ {
+ QUIT; /* Allow this to be interruptable */
+ dn_bufp = hpread_get_lntt (sym_index + symnum, objfile);
+
+ if (dn_bufp->dblock.extension)
+ continue;
+
+ /* Yow! We call SET_NAMESTRING on things without names! */
+ SET_NAMESTRING (dn_bufp, &namestring, objfile);
+
+ hpread_process_one_debug_symbol (dn_bufp, namestring, section_offsets,
+ objfile, text_offset, text_size,
+ filename, symnum + sym_index,
+ &at_module_boundary
+ );
+
+ /* OLD COMMENTS: This routine is only called for psts. All psts
+ * correspond to MODULES. If we ever do lazy-reading of globals
+ * from the LNTT, then there will be a pst which ends when the
+ * LNTT ends, and not at an END MODULE entry. Then we'll have
+ * to re-visit this break.
+
+ if( at_end_of_module )
+ break;
+
+ */
+
+ /* We no longer break out of the loop when we reach the end of a
+ module. The reason is that with CTTI, the compiler can generate
+ function symbols (for template function instantiations) which are not
+ in any module; typically they show up beyond a module's end, and
+ before the next module's start. We include them in the current
+ module. However, we still don't trust the MAX_SYMNUM value from
+ the psymtab, so we break out if we enter a new module. */
+
+ if (at_module_boundary == -1)
+ break;
+ }
+
+ current_objfile = NULL;
+ hp_som_som_object_present = 1; /* Indicate we've processed an HP SOM SOM file */
+
+ return end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT (objfile));
+}
+
+
+
+
+/* Convert basic types from HP debug format into GDB internal format. */
+
+static int
+hpread_type_translate (dnttpointer typep)
+{
+ if (!typep.dntti.immediate)
+ {
+ error ("error in hpread_type_translate\n.");
+ return FT_VOID;
+ }
+
+ switch (typep.dntti.type)
+ {
+ case HP_TYPE_BOOLEAN:
+ case HP_TYPE_BOOLEAN_S300_COMPAT:
+ case HP_TYPE_BOOLEAN_VAX_COMPAT:
+ return FT_BOOLEAN;
+ case HP_TYPE_CHAR: /* C signed char, C++ plain char */
+
+ case HP_TYPE_WIDE_CHAR:
+ return FT_CHAR;
+ case HP_TYPE_INT:
+ if (typep.dntti.bitlength <= 8)
+ return FT_SIGNED_CHAR; /* C++ signed char */
+ if (typep.dntti.bitlength <= 16)
+ return FT_SHORT;
+ if (typep.dntti.bitlength <= 32)
+ return FT_INTEGER;
+ return FT_LONG_LONG;
+ case HP_TYPE_LONG:
+ if (typep.dntti.bitlength <= 8)
+ return FT_SIGNED_CHAR; /* C++ signed char. */
+ return FT_LONG;
+ case HP_TYPE_UNSIGNED_LONG:
+ if (typep.dntti.bitlength <= 8)
+ return FT_UNSIGNED_CHAR; /* C/C++ unsigned char */
+ if (typep.dntti.bitlength <= 16)
+ return FT_UNSIGNED_SHORT;
+ if (typep.dntti.bitlength <= 32)
+ return FT_UNSIGNED_LONG;
+ return FT_UNSIGNED_LONG_LONG;
+ case HP_TYPE_UNSIGNED_INT:
+ if (typep.dntti.bitlength <= 8)
+ return FT_UNSIGNED_CHAR;
+ if (typep.dntti.bitlength <= 16)
+ return FT_UNSIGNED_SHORT;
+ if (typep.dntti.bitlength <= 32)
+ return FT_UNSIGNED_INTEGER;
+ return FT_UNSIGNED_LONG_LONG;
+ case HP_TYPE_REAL:
+ case HP_TYPE_REAL_3000:
+ case HP_TYPE_DOUBLE:
+ if (typep.dntti.bitlength == 64)
+ return FT_DBL_PREC_FLOAT;
+ if (typep.dntti.bitlength == 128)
+ return FT_EXT_PREC_FLOAT;
+ return FT_FLOAT;
+ case HP_TYPE_COMPLEX:
+ case HP_TYPE_COMPLEXS3000:
+ if (typep.dntti.bitlength == 128)
+ return FT_DBL_PREC_COMPLEX;
+ if (typep.dntti.bitlength == 192)
+ return FT_EXT_PREC_COMPLEX;
+ return FT_COMPLEX;
+ case HP_TYPE_VOID:
+ return FT_VOID;
+ case HP_TYPE_STRING200:
+ case HP_TYPE_LONGSTRING200:
+ case HP_TYPE_FTN_STRING_SPEC:
+ case HP_TYPE_MOD_STRING_SPEC:
+ case HP_TYPE_MOD_STRING_3000:
+ case HP_TYPE_FTN_STRING_S300_COMPAT:
+ case HP_TYPE_FTN_STRING_VAX_COMPAT:
+ return FT_STRING;
+ case HP_TYPE_TEMPLATE_ARG:
+ return FT_TEMPLATE_ARG;
+ case HP_TYPE_TEXT:
+ case HP_TYPE_FLABEL:
+ case HP_TYPE_PACKED_DECIMAL:
+ case HP_TYPE_ANYPOINTER:
+ case HP_TYPE_GLOBAL_ANYPOINTER:
+ case HP_TYPE_LOCAL_ANYPOINTER:
+ default:
+ warning ("hpread_type_translate: unhandled type code.\n");
+ return FT_VOID;
+ }
+}
+
+/* Given a position in the DNTT, return a pointer to the
+ * already-built "struct type" (if any), for the type defined
+ * at that position.
+ */
+
+static struct type **
+hpread_lookup_type (dnttpointer hp_type, struct objfile *objfile)
+{
+ unsigned old_len;
+ int index = hp_type.dnttp.index;
+ int size_changed = 0;
+
+ /* The immediate flag indicates this doesn't actually point to
+ * a type DNTT.
+ */
+ if (hp_type.dntti.immediate)
+ return NULL;
+
+ /* For each objfile, we maintain a "type vector".
+ * This an array of "struct type *"'s with one pointer per DNTT index.
+ * Given a DNTT index, we look in this array to see if we have
+ * already processed this DNTT and if it is a type definition.
+ * If so, then we can locate a pointer to the already-built
+ * "struct type", and not build it again.
+ *
+ * The need for this arises because our DNTT-walking code wanders
+ * around. In particular, it will encounter the same type multiple
+ * times (once for each object of that type). We don't want to
+ * built multiple "struct type"'s for the same thing.
+ *
+ * Having said this, I should point out that this type-vector is
+ * an expensive way to keep track of this. If most DNTT entries are
+ * 3 words, the type-vector will be 1/3 the size of the DNTT itself.
+ * Alternative solutions:
+ * - Keep a compressed or hashed table. Less memory, but more expensive
+ * to search and update.
+ * - (Suggested by JB): Overwrite the DNTT entry itself
+ * with the info. Create a new type code "ALREADY_BUILT", and modify
+ * the DNTT to have that type code and point to the already-built entry.
+ * -RT
+ */
+
+ if (index < LNTT_SYMCOUNT (objfile))
+ {
+ if (index >= DNTT_TYPE_VECTOR_LENGTH (objfile))
+ {
+ old_len = DNTT_TYPE_VECTOR_LENGTH (objfile);
+
+ /* See if we need to allocate a type-vector. */
+ if (old_len == 0)
+ {
+ DNTT_TYPE_VECTOR_LENGTH (objfile) = LNTT_SYMCOUNT (objfile) + GNTT_SYMCOUNT (objfile);
+ DNTT_TYPE_VECTOR (objfile) = (struct type **)
+ xmmalloc (objfile->md, DNTT_TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *));
+ memset (&DNTT_TYPE_VECTOR (objfile)[old_len], 0,
+ (DNTT_TYPE_VECTOR_LENGTH (objfile) - old_len) *
+ sizeof (struct type *));
+ }
+
+ /* See if we need to resize type-vector. With my change to
+ * initially allocate a correct-size type-vector, this code
+ * should no longer trigger.
+ */
+ while (index >= DNTT_TYPE_VECTOR_LENGTH (objfile))
+ {
+ DNTT_TYPE_VECTOR_LENGTH (objfile) *= 2;
+ size_changed = 1;
+ }
+ if (size_changed)
+ {
+ DNTT_TYPE_VECTOR (objfile) = (struct type **)
+ xmrealloc (objfile->md,
+ (char *) DNTT_TYPE_VECTOR (objfile),
+ (DNTT_TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *)));
+
+ memset (&DNTT_TYPE_VECTOR (objfile)[old_len], 0,
+ (DNTT_TYPE_VECTOR_LENGTH (objfile) - old_len) *
+ sizeof (struct type *));
+ }
+
+ }
+ return &DNTT_TYPE_VECTOR (objfile)[index];
+ }
+ else
+ return NULL;
+}
+
+/* Possibly allocate a GDB internal type so we can internalize HP_TYPE.
+ Note we'll just return the address of a GDB internal type if we already
+ have it lying around. */
+
+static struct type *
+hpread_alloc_type (dnttpointer hp_type, struct objfile *objfile)
+{
+ struct type **type_addr;
+
+ type_addr = hpread_lookup_type (hp_type, objfile);
+ if (*type_addr == 0)
+ {
+ *type_addr = alloc_type (objfile);
+
+ /* A hack - if we really are a C++ class symbol, then this default
+ * will get overriden later on.
+ */
+ TYPE_CPLUS_SPECIFIC (*type_addr)
+ = (struct cplus_struct_type *) &cplus_struct_default;
+ }
+
+ return *type_addr;
+}
+
+/* Read a native enumerated type and return it in GDB internal form. */
+
+static struct type *
+hpread_read_enum_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+ struct objfile *objfile)
+{
+ struct type *type;
+ struct pending **symlist, *osyms, *syms;
+ struct pending *local_list = NULL;
+ int o_nsyms, nsyms = 0;
+ dnttpointer mem;
+ union dnttentry *memp;
+ char *name;
+ long n;
+ struct symbol *sym;
+
+ /* Allocate a GDB type. If we've already read in this enum type,
+ * it'll return the already built GDB type, so stop here.
+ * (Note: I added this check, to conform with what's done for
+ * struct, union, class.
+ * I assume this is OK. - RT)
+ */
+ type = hpread_alloc_type (hp_type, objfile);
+ if (TYPE_CODE (type) == TYPE_CODE_ENUM)
+ return type;
+
+ /* HP C supports "sized enums", where a specifier such as "short" or
+ "char" can be used to get enums of different sizes. So don't assume
+ an enum is always 4 bytes long. pai/1997-08-21 */
+ TYPE_LENGTH (type) = dn_bufp->denum.bitlength / 8;
+
+ symlist = &file_symbols;
+ osyms = *symlist;
+ o_nsyms = osyms ? osyms->nsyms : 0;
+
+ /* Get a name for each member and add it to our list of members.
+ * The list of "mem" SOM records we are walking should all be
+ * SOM type DNTT_TYPE_MEMENUM (not checked).
+ */
+ mem = dn_bufp->denum.firstmem;
+ while (mem.word && mem.word != DNTTNIL)
+ {
+ memp = hpread_get_lntt (mem.dnttp.index, objfile);
+
+ name = VT (objfile) + memp->dmember.name;
+ sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+ &objfile->symbol_obstack);
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_VALUE (sym) = memp->dmember.value;
+ add_symbol_to_list (sym, symlist);
+ nsyms++;
+ mem = memp->dmember.nextmem;
+ }
+
+ /* Now that we know more about the enum, fill in more info. */
+ TYPE_CODE (type) = TYPE_CODE_ENUM;
+ TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
+ TYPE_NFIELDS (type) = nsyms;
+ TYPE_FIELDS (type) = (struct field *)
+ obstack_alloc (&objfile->type_obstack, sizeof (struct field) * nsyms);
+
+ /* Find the symbols for the members and put them into the type.
+ The symbols can be found in the symlist that we put them on
+ to cause them to be defined. osyms contains the old value
+ of that symlist; everything up to there was defined by us.
+
+ Note that we preserve the order of the enum constants, so
+ that in something like "enum {FOO, LAST_THING=FOO}" we print
+ FOO, not LAST_THING. */
+ for (syms = *symlist, n = 0; syms; syms = syms->next)
+ {
+ int j = 0;
+ if (syms == osyms)
+ j = o_nsyms;
+ for (; j < syms->nsyms; j++, n++)
+ {
+ struct symbol *xsym = syms->symbol[j];
+ SYMBOL_TYPE (xsym) = type;
+ TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+ TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
+ TYPE_FIELD_BITSIZE (type, n) = 0;
+ }
+ if (syms == osyms)
+ break;
+ }
+
+ return type;
+}
+
+/* Read and internalize a native function debug symbol. */
+
+static struct type *
+hpread_read_function_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+ struct objfile *objfile, int newblock)
+{
+ struct type *type, *type1;
+ struct pending *syms;
+ struct pending *local_list = NULL;
+ int nsyms = 0;
+ dnttpointer param;
+ union dnttentry *paramp;
+ char *name;
+ long n;
+ struct symbol *sym;
+ int record_args = 1;
+
+ /* See if we've already read in this type. */
+ type = hpread_alloc_type (hp_type, objfile);
+ if (TYPE_CODE (type) == TYPE_CODE_FUNC)
+ {
+ record_args = 0; /* already read in, don't modify type */
+ }
+ else
+ {
+ /* Nope, so read it in and store it away. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION ||
+ dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC)
+ type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc.retval,
+ objfile));
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE)
+ type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunctype.retval,
+ objfile));
+ else /* expect DNTT_TYPE_FUNC_TEMPLATE */
+ type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc_template.retval,
+ objfile));
+ replace_type (type, type1);
+
+ /* Mark it -- in the middle of processing */
+ TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
+ }
+
+ /* Now examine each parameter noting its type, location, and a
+ wealth of other information. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION ||
+ dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC)
+ param = dn_bufp->dfunc.firstparam;
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE)
+ param = dn_bufp->dfunctype.firstparam;
+ else /* expect DNTT_TYPE_FUNC_TEMPLATE */
+ param = dn_bufp->dfunc_template.firstparam;
+ while (param.word && param.word != DNTTNIL)
+ {
+ paramp = hpread_get_lntt (param.dnttp.index, objfile);
+ nsyms++;
+ param = paramp->dfparam.nextparam;
+
+ /* Get the name. */
+ name = VT (objfile) + paramp->dfparam.name;
+ sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ (void) memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+ &objfile->symbol_obstack);
+
+ /* Figure out where it lives. */
+ if (paramp->dfparam.regparam)
+ SYMBOL_CLASS (sym) = LOC_REGPARM;
+ else if (paramp->dfparam.indirect)
+ SYMBOL_CLASS (sym) = LOC_REF_ARG;
+ else
+ SYMBOL_CLASS (sym) = LOC_ARG;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ if (paramp->dfparam.copyparam)
+ {
+ SYMBOL_VALUE (sym) = paramp->dfparam.location;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+ SYMBOL_VALUE (sym)
+ += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+ /* This is likely a pass-by-invisible reference parameter,
+ Hack on the symbol class to make GDB happy. */
+ /* ??rehrauer: This appears to be broken w/r/t to passing
+ C values of type float and struct. Perhaps this ought
+ to be highighted as a special case, but for now, just
+ allowing these to be LOC_ARGs seems to work fine.
+ */
+#if 0
+ SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+#endif
+ }
+ else
+ SYMBOL_VALUE (sym) = paramp->dfparam.location;
+
+ /* Get its type. */
+ SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile);
+ /* Add it to the symbol list. */
+ /* Note 1 (RT) At the moment, add_symbol_to_list() is also being
+ * called on FPARAM symbols from the process_one_debug_symbol()
+ * level... so parameters are getting added twice! (this shows
+ * up in the symbol dump you get from "maint print symbols ...").
+ * Note 2 (RT) I took out the processing of FPARAM from the
+ * process_one_debug_symbol() level, so at the moment parameters are only
+ * being processed here. This seems to have no ill effect.
+ */
+ /* Note 3 (pai/1997-08-11) I removed the add_symbol_to_list() which put
+ each fparam on the local_symbols list from here. Now we use the
+ local_list to which fparams are added below, and set the param_symbols
+ global to point to that at the end of this routine. */
+ /* elz: I added this new list of symbols which is local to the function.
+ this list is the one which is actually used to build the type for the
+ function rather than the gloabal list pointed to by symlist.
+ Using a global list to keep track of the parameters is wrong, because
+ this function is called recursively if one parameter happend to be
+ a function itself with more parameters in it. Adding parameters to the
+ same global symbol list would not work!
+ Actually it did work in case of cc compiled programs where you do
+ not check the parameter lists of the arguments. */
+ add_symbol_to_list (sym, &local_list);
+
+ }
+
+ /* If type was read in earlier, don't bother with modifying
+ the type struct */
+ if (!record_args)
+ goto finish;
+
+ /* Note how many parameters we found. */
+ TYPE_NFIELDS (type) = nsyms;
+ TYPE_FIELDS (type) = (struct field *)
+ obstack_alloc (&objfile->type_obstack,
+ sizeof (struct field) * nsyms);
+
+ /* Find the symbols for the parameters and
+ use them to fill parameter-type information into the function-type.
+ The parameter symbols can be found in the local_list that we just put them on. */
+ /* Note that we preserve the order of the parameters, so
+ that in something like "enum {FOO, LAST_THING=FOO}" we print
+ FOO, not LAST_THING. */
+
+ /* get the parameters types from the local list not the global list
+ so that the type can be correctly constructed for functions which
+ have function as parameters */
+ for (syms = local_list, n = 0; syms; syms = syms->next)
+ {
+ int j = 0;
+ for (j = 0; j < syms->nsyms; j++, n++)
+ {
+ struct symbol *xsym = syms->symbol[j];
+ TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+ TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym);
+ TYPE_FIELD_ARTIFICIAL (type, n) = 0;
+ TYPE_FIELD_BITSIZE (type, n) = 0;
+ }
+ }
+ /* Mark it as having been processed */
+ TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE);
+
+ /* Check whether we need to fix-up a class type with this function's type */
+ if (fixup_class && (fixup_method == type))
+ {
+ fixup_class_method_type (fixup_class, fixup_method, objfile);
+ fixup_class = NULL;
+ fixup_method = NULL;
+ }
+
+ /* Set the param list of this level of the context stack
+ to our local list. Do this only if this function was
+ called for creating a new block, and not if it was called
+ simply to get the function type. This prevents recursive
+ invocations from trashing param_symbols. */
+finish:
+ if (newblock)
+ param_symbols = local_list;
+
+ return type;
+}
+
+
+/* Read and internalize a native DOC function debug symbol. */
+/* This is almost identical to hpread_read_function_type(), except
+ * for references to dn_bufp->ddocfunc instead of db_bufp->dfunc.
+ * Since debug information for DOC functions is more likely to be
+ * volatile, please leave it this way.
+ */
+static struct type *
+hpread_read_doc_function_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+ struct objfile *objfile, int newblock)
+{
+ struct type *type, *type1;
+ struct pending *syms;
+ struct pending *local_list = NULL;
+ int nsyms = 0;
+ dnttpointer param;
+ union dnttentry *paramp;
+ char *name;
+ long n;
+ struct symbol *sym;
+ int record_args = 1;
+
+ /* See if we've already read in this type. */
+ type = hpread_alloc_type (hp_type, objfile);
+ if (TYPE_CODE (type) == TYPE_CODE_FUNC)
+ {
+ record_args = 0; /* already read in, don't modify type */
+ }
+ else
+ {
+ /* Nope, so read it in and store it away. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION ||
+ dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC)
+ type1 = lookup_function_type (hpread_type_lookup (dn_bufp->ddocfunc.retval,
+ objfile));
+ replace_type (type, type1);
+
+ /* Mark it -- in the middle of processing */
+ TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
+ }
+
+ /* Now examine each parameter noting its type, location, and a
+ wealth of other information. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION ||
+ dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC)
+ param = dn_bufp->ddocfunc.firstparam;
+ while (param.word && param.word != DNTTNIL)
+ {
+ paramp = hpread_get_lntt (param.dnttp.index, objfile);
+ nsyms++;
+ param = paramp->dfparam.nextparam;
+
+ /* Get the name. */
+ name = VT (objfile) + paramp->dfparam.name;
+ sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ (void) memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = name;
+
+ /* Figure out where it lives. */
+ if (paramp->dfparam.regparam)
+ SYMBOL_CLASS (sym) = LOC_REGPARM;
+ else if (paramp->dfparam.indirect)
+ SYMBOL_CLASS (sym) = LOC_REF_ARG;
+ else
+ SYMBOL_CLASS (sym) = LOC_ARG;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ if (paramp->dfparam.copyparam)
+ {
+ SYMBOL_VALUE (sym) = paramp->dfparam.location;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+ SYMBOL_VALUE (sym)
+ += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+ /* This is likely a pass-by-invisible reference parameter,
+ Hack on the symbol class to make GDB happy. */
+ /* ??rehrauer: This appears to be broken w/r/t to passing
+ C values of type float and struct. Perhaps this ought
+ to be highighted as a special case, but for now, just
+ allowing these to be LOC_ARGs seems to work fine.
+ */
+#if 0
+ SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+#endif
+ }
+ else
+ SYMBOL_VALUE (sym) = paramp->dfparam.location;
+
+ /* Get its type. */
+ SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile);
+ /* Add it to the symbol list. */
+ /* Note 1 (RT) At the moment, add_symbol_to_list() is also being
+ * called on FPARAM symbols from the process_one_debug_symbol()
+ * level... so parameters are getting added twice! (this shows
+ * up in the symbol dump you get from "maint print symbols ...").
+ * Note 2 (RT) I took out the processing of FPARAM from the
+ * process_one_debug_symbol() level, so at the moment parameters are only
+ * being processed here. This seems to have no ill effect.
+ */
+ /* Note 3 (pai/1997-08-11) I removed the add_symbol_to_list() which put
+ each fparam on the local_symbols list from here. Now we use the
+ local_list to which fparams are added below, and set the param_symbols
+ global to point to that at the end of this routine. */
+
+ /* elz: I added this new list of symbols which is local to the function.
+ this list is the one which is actually used to build the type for the
+ function rather than the gloabal list pointed to by symlist.
+ Using a global list to keep track of the parameters is wrong, because
+ this function is called recursively if one parameter happend to be
+ a function itself with more parameters in it. Adding parameters to the
+ same global symbol list would not work!
+ Actually it did work in case of cc compiled programs where you do not check the
+ parameter lists of the arguments. */
+ add_symbol_to_list (sym, &local_list);
+ }
+
+ /* If type was read in earlier, don't bother with modifying
+ the type struct */
+ if (!record_args)
+ goto finish;
+
+ /* Note how many parameters we found. */
+ TYPE_NFIELDS (type) = nsyms;
+ TYPE_FIELDS (type) = (struct field *)
+ obstack_alloc (&objfile->type_obstack,
+ sizeof (struct field) * nsyms);
+
+ /* Find the symbols for the parameters and
+ use them to fill parameter-type information into the function-type.
+ The parameter symbols can be found in the local_list that we just put them on. */
+ /* Note that we preserve the order of the parameters, so
+ that in something like "enum {FOO, LAST_THING=FOO}" we print
+ FOO, not LAST_THING. */
+
+ /* get the parameters types from the local list not the global list
+ so that the type can be correctly constructed for functions which
+ have function as parameters
+ */
+ for (syms = local_list, n = 0; syms; syms = syms->next)
+ {
+ int j = 0;
+ for (j = 0; j < syms->nsyms; j++, n++)
+ {
+ struct symbol *xsym = syms->symbol[j];
+ TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+ TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym);
+ TYPE_FIELD_ARTIFICIAL (type, n) = 0;
+ TYPE_FIELD_BITSIZE (type, n) = 0;
+ }
+ }
+
+ /* Mark it as having been processed */
+ TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE);
+
+ /* Check whether we need to fix-up a class type with this function's type */
+ if (fixup_class && (fixup_method == type))
+ {
+ fixup_class_method_type (fixup_class, fixup_method, objfile);
+ fixup_class = NULL;
+ fixup_method = NULL;
+ }
+
+ /* Set the param list of this level of the context stack
+ to our local list. Do this only if this function was
+ called for creating a new block, and not if it was called
+ simply to get the function type. This prevents recursive
+ invocations from trashing param_symbols. */
+finish:
+ if (newblock)
+ param_symbols = local_list;
+
+ return type;
+}
+
+
+
+/* A file-level variable which keeps track of the current-template
+ * being processed. Set in hpread_read_struct_type() while processing
+ * a template type. Referred to in hpread_get_nth_templ_arg().
+ * Yes, this is a kludge, but it arises from the kludge that already
+ * exists in symtab.h, namely the fact that they encode
+ * "template argument n" with fundamental type FT_TEMPLATE_ARG and
+ * bitlength n. This means that deep in processing fundamental types
+ * I need to ask the question "what template am I in the middle of?".
+ * The alternative to stuffing a global would be to pass an argument
+ * down the chain of calls just for this purpose.
+ *
+ * There may be problems handling nested templates... tough.
+ */
+static struct type *current_template = NULL;
+
+/* Read in and internalize a structure definition.
+ * This same routine is called for struct, union, and class types.
+ * Also called for templates, since they build a very similar
+ * type entry as for class types.
+ */
+
+static struct type *
+hpread_read_struct_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+ struct objfile *objfile)
+{
+ /* The data members get linked together into a list of struct nextfield's */
+ struct nextfield
+ {
+ struct nextfield *next;
+ struct field field;
+ unsigned char attributes; /* store visibility and virtuality info */
+#define ATTR_VIRTUAL 1
+#define ATTR_PRIVATE 2
+#define ATTR_PROTECT 3
+ };
+
+
+ /* The methods get linked together into a list of struct next_fn_field's */
+ struct next_fn_field
+ {
+ struct next_fn_field *next;
+ struct fn_fieldlist field;
+ struct fn_field fn_field;
+ int num_fn_fields;
+ };
+
+ /* The template args get linked together into a list of struct next_template's */
+ struct next_template
+ {
+ struct next_template *next;
+ struct template_arg arg;
+ };
+
+ /* The template instantiations get linked together into a list of these... */
+ struct next_instantiation
+ {
+ struct next_instantiation *next;
+ struct type *t;
+ };
+
+ struct type *type;
+ struct type *baseclass;
+ struct type *memtype;
+ struct nextfield *list = 0, *tmp_list = 0;
+ struct next_fn_field *fn_list = 0;
+ struct next_fn_field *fn_p;
+ struct next_template *t_new, *t_list = 0;
+ struct nextfield *new;
+ struct next_fn_field *fn_new;
+ struct next_instantiation *i_new, *i_list = 0;
+ int n, nfields = 0, n_fn_fields = 0, n_fn_fields_total = 0;
+ int n_base_classes = 0, n_templ_args = 0;
+ int ninstantiations = 0;
+ dnttpointer field, fn_field, parent;
+ union dnttentry *fieldp, *fn_fieldp, *parentp;
+ int i;
+ int static_member = 0;
+ int const_member = 0;
+ int volatile_member = 0;
+ unsigned long vtbl_offset;
+ int need_bitvectors = 0;
+ char *method_name = NULL;
+ char *method_alias = NULL;
+
+
+ /* Is it something we've already dealt with? */
+ type = hpread_alloc_type (hp_type, objfile);
+ if ((TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
+ (TYPE_CODE (type) == TYPE_CODE_UNION) ||
+ (TYPE_CODE (type) == TYPE_CODE_CLASS) ||
+ (TYPE_CODE (type) == TYPE_CODE_TEMPLATE))
+ return type;
+
+ /* Get the basic type correct. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
+ {
+ TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ TYPE_LENGTH (type) = dn_bufp->dstruct.bitlength / 8;
+ }
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
+ {
+ TYPE_CODE (type) = TYPE_CODE_UNION;
+ TYPE_LENGTH (type) = dn_bufp->dunion.bitlength / 8;
+ }
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
+ {
+ TYPE_CODE (type) = TYPE_CODE_CLASS;
+ TYPE_LENGTH (type) = dn_bufp->dclass.bitlength / 8;
+
+ /* Overrides the TYPE_CPLUS_SPECIFIC(type) with allocated memory
+ * rather than &cplus_struct_default.
+ */
+ allocate_cplus_struct_type (type);
+
+ /* Fill in declared-type.
+ * (The C++ compiler will emit TYPE_CODE_CLASS
+ * for all 3 of "class", "struct"
+ * "union", and we have to look at the "class_decl" field if we
+ * want to know how it was really declared)
+ */
+ /* (0==class, 1==union, 2==struct) */
+ TYPE_DECLARED_TYPE (type) = dn_bufp->dclass.class_decl;
+ }
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+ {
+ /* Get the basic type correct. */
+ TYPE_CODE (type) = TYPE_CODE_TEMPLATE;
+ allocate_cplus_struct_type (type);
+ TYPE_DECLARED_TYPE (type) = DECLARED_TYPE_TEMPLATE;
+ }
+ else
+ return type;
+
+
+ TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
+
+ /* For classes, read the parent list.
+ * Question (RT): Do we need to do this for templates also?
+ */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
+ {
+
+ /* First read the parent-list (classes from which we derive fields) */
+ parent = dn_bufp->dclass.parentlist;
+ while (parent.word && parent.word != DNTTNIL)
+ {
+ parentp = hpread_get_lntt (parent.dnttp.index, objfile);
+
+ /* "parentp" should point to a DNTT_TYPE_INHERITANCE record */
+
+ /* Get space to record the next field/data-member. */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+
+ FIELD_BITSIZE (list->field) = 0;
+
+ /* The "classname" field is actually a DNTT pointer to the base class */
+ baseclass = hpread_type_lookup (parentp->dinheritance.classname,
+ objfile);
+ FIELD_TYPE (list->field) = baseclass;
+
+ list->field.name = type_name_no_tag (FIELD_TYPE (list->field));
+
+ list->attributes = 0;
+
+ /* Check for virtuality of base, and set the
+ * offset of the base subobject within the object.
+ * (Offset set to -1 for virtual bases (for now).)
+ */
+ if (parentp->dinheritance.Virtual)
+ {
+ B_SET (&(list->attributes), ATTR_VIRTUAL);
+ parentp->dinheritance.offset = -1;
+ }
+ else
+ FIELD_BITPOS (list->field) = parentp->dinheritance.offset;
+
+ /* Check visibility */
+ switch (parentp->dinheritance.visibility)
+ {
+ case 1:
+ B_SET (&(list->attributes), ATTR_PROTECT);
+ break;
+ case 2:
+ B_SET (&(list->attributes), ATTR_PRIVATE);
+ break;
+ }
+
+ n_base_classes++;
+ nfields++;
+
+ parent = parentp->dinheritance.next;
+ }
+ }
+
+ /* For templates, read the template argument list.
+ * This must be done before processing the member list, because
+ * the member list may refer back to this. E.g.:
+ * template <class T1, class T2> class q2 {
+ * public:
+ * T1 a;
+ * T2 b;
+ * };
+ * We need to read the argument list "T1", "T2" first.
+ */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+ {
+ /* Kludge alert: This stuffs a global "current_template" which
+ * is referred to by hpread_get_nth_templ_arg(). The global
+ * is cleared at the end of this routine.
+ */
+ current_template = type;
+
+ /* Read in the argument list */
+ field = dn_bufp->dtemplate.arglist;
+ while (field.word && field.word != DNTTNIL)
+ {
+ /* Get this template argument */
+ fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+ if (fieldp->dblock.kind != DNTT_TYPE_TEMPLATE_ARG)
+ {
+ warning ("Invalid debug info: Template argument entry is of wrong kind");
+ break;
+ }
+ /* Bump the count */
+ n_templ_args++;
+ /* Allocate and fill in a struct next_template */
+ t_new = (struct next_template *) alloca (sizeof (struct next_template));
+ t_new->next = t_list;
+ t_list = t_new;
+ t_list->arg.name = VT (objfile) + fieldp->dtempl_arg.name;
+ t_list->arg.type = hpread_read_templ_arg_type (field, fieldp,
+ objfile, t_list->arg.name);
+ /* Walk to the next template argument */
+ field = fieldp->dtempl_arg.nextarg;
+ }
+ }
+
+ TYPE_NTEMPLATE_ARGS (type) = n_templ_args;
+
+ if (n_templ_args > 0)
+ TYPE_TEMPLATE_ARGS (type) = (struct template_arg *)
+ obstack_alloc (&objfile->type_obstack, sizeof (struct template_arg) * n_templ_args);
+ for (n = n_templ_args; t_list; t_list = t_list->next)
+ {
+ n -= 1;
+ TYPE_TEMPLATE_ARG (type, n) = t_list->arg;
+ }
+
+ /* Next read in and internalize all the fields/members. */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
+ field = dn_bufp->dstruct.firstfield;
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
+ field = dn_bufp->dunion.firstfield;
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
+ field = dn_bufp->dclass.memberlist;
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+ field = dn_bufp->dtemplate.memberlist;
+ else
+ field.word = DNTTNIL;
+
+ while (field.word && field.word != DNTTNIL)
+ {
+ fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+
+ /* At this point "fieldp" may point to either a DNTT_TYPE_FIELD
+ * or a DNTT_TYPE_GENFIELD record.
+ */
+ vtbl_offset = 0;
+ static_member = 0;
+ const_member = 0;
+ volatile_member = 0;
+
+ if (fieldp->dblock.kind == DNTT_TYPE_GENFIELD)
+ {
+
+ /* The type will be GENFIELD if the field is a method or
+ * a static member (or some other cases -- see below)
+ */
+
+ /* Follow a link to get to the record for the field. */
+ fn_field = fieldp->dgenfield.field;
+ fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
+
+ /* Virtual funcs are indicated by a VFUNC which points to the
+ * real entry
+ */
+ if (fn_fieldp->dblock.kind == DNTT_TYPE_VFUNC)
+ {
+ vtbl_offset = fn_fieldp->dvfunc.vtbl_offset;
+ fn_field = fn_fieldp->dvfunc.funcptr;
+ fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
+ }
+
+ /* A function's entry may be preceded by a modifier which
+ * labels it static/constant/volatile.
+ */
+ if (fn_fieldp->dblock.kind == DNTT_TYPE_MODIFIER)
+ {
+ static_member = fn_fieldp->dmodifier.m_static;
+ const_member = fn_fieldp->dmodifier.m_const;
+ volatile_member = fn_fieldp->dmodifier.m_volatile;
+ fn_field = fn_fieldp->dmodifier.type;
+ fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
+ }
+
+ /* Check whether we have a method */
+ if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) ||
+ (fn_fieldp->dblock.kind == DNTT_TYPE_FUNCTION) ||
+ (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC) ||
+ (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_FUNCTION))
+ {
+ /* Method found */
+
+ short ix = 0;
+
+ /* Look up function type of method */
+ memtype = hpread_type_lookup (fn_field, objfile);
+
+ /* Methods can be seen before classes in the SOM records.
+ If we are processing this class because it's a parameter of a
+ method, at this point the method's type is actually incomplete;
+ we'll have to fix it up later; mark the class for this. */
+
+ if (TYPE_INCOMPLETE (memtype))
+ {
+ TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
+ if (fixup_class)
+ warning ("Two classes to fix up for method?? Type information may be incorrect for some classes.");
+ if (fixup_method)
+ warning ("Two methods to be fixed up at once?? Type information may be incorrect for some classes.");
+ fixup_class = type; /* remember this class has to be fixed up */
+ fixup_method = memtype; /* remember the method type to be used in fixup */
+ }
+
+ /* HP aCC generates operator names without the "operator" keyword, and
+ generates null strings as names for operators that are
+ user-defined type conversions to basic types (e.g. operator int ()).
+ So try to reconstruct name as best as possible. */
+
+ method_name = (char *) (VT (objfile) + fn_fieldp->dfunc.name);
+ method_alias = (char *) (VT (objfile) + fn_fieldp->dfunc.alias);
+
+ if (!method_name || /* no name */
+ !*method_name || /* or null name */
+ cplus_mangle_opname (method_name, DMGL_ANSI)) /* or name is an operator like "<" */
+ {
+ char *tmp_name = cplus_demangle (method_alias, DMGL_ANSI);
+ char *op_string = strstr (tmp_name, "operator");
+ method_name = xmalloc (strlen (op_string) + 1); /* don't overwrite VT! */
+ strcpy (method_name, op_string);
+ }
+
+ /* First check if a method of the same name has already been seen. */
+ fn_p = fn_list;
+ while (fn_p)
+ {
+ if (STREQ (fn_p->field.name, method_name))
+ break;
+ fn_p = fn_p->next;
+ }
+
+ /* If no such method was found, allocate a new entry in the list */
+ if (!fn_p)
+ {
+ /* Get space to record this member function */
+ /* Note: alloca used; this will disappear on routine exit */
+ fn_new = (struct next_fn_field *) alloca (sizeof (struct next_fn_field));
+ fn_new->next = fn_list;
+ fn_list = fn_new;
+
+ /* Fill in the fields of the struct nextfield */
+
+ /* Record the (unmangled) method name */
+ fn_list->field.name = method_name;
+ /* Initial space for overloaded methods */
+ /* Note: xmalloc is used; this will persist after this routine exits */
+ fn_list->field.fn_fields = (struct fn_field *) xmalloc (5 * (sizeof (struct fn_field)));
+ fn_list->field.length = 1; /* Init # of overloaded instances */
+ fn_list->num_fn_fields = 5; /* # of entries for which space allocated */
+ fn_p = fn_list;
+ ix = 0; /* array index for fn_field */
+ /* Bump the total count of the distinctly named methods */
+ n_fn_fields++;
+ }
+ else
+ /* Another overloaded instance of an already seen method name */
+ {
+ if (++(fn_p->field.length) > fn_p->num_fn_fields)
+ {
+ /* Increase space allocated for overloaded instances */
+ fn_p->field.fn_fields
+ = (struct fn_field *) xrealloc (fn_p->field.fn_fields,
+ (fn_p->num_fn_fields + 5) * sizeof (struct fn_field));
+ fn_p->num_fn_fields += 5;
+ }
+ ix = fn_p->field.length - 1; /* array index for fn_field */
+ }
+
+ /* "physname" is intended to be the name of this overloaded instance. */
+ if ((fn_fieldp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
+ method_alias &&
+ *method_alias) /* not a null string */
+ fn_p->field.fn_fields[ix].physname = method_alias;
+ else
+ fn_p->field.fn_fields[ix].physname = method_name;
+ /* What's expected here is the function type */
+ /* But mark it as NULL if the method was incompletely processed
+ We'll fix this up later when the method is fully processed */
+ if (TYPE_INCOMPLETE (memtype))
+ {
+ fn_p->field.fn_fields[ix].type = NULL;
+ }
+ else
+ {
+ fn_p->field.fn_fields[ix].type = memtype;
+
+ /* The argument list */
+ TYPE_TYPE_SPECIFIC (fn_p->field.fn_fields[ix].type).arg_types
+ = (struct type **) obstack_alloc (&objfile->type_obstack,
+ (sizeof (struct type *)
+ * (TYPE_NFIELDS (memtype)
+ + 1)));
+ for (i = 0; i < TYPE_NFIELDS (memtype); i++)
+ TYPE_TYPE_SPECIFIC (fn_p->field.fn_fields[ix].type)
+ .arg_types[i] = TYPE_FIELDS (memtype)[i].type;
+ /* void termination */
+ TYPE_TYPE_SPECIFIC (fn_p->field.fn_fields[ix].type)
+ .arg_types[TYPE_NFIELDS (memtype)] = builtin_type_void;
+ }
+
+ /* For virtual functions, fill in the voffset field with the
+ * virtual table offset. (This is just copied over from the
+ * SOM record; not sure if it is what GDB expects here...).
+ * But if the function is a static method, set it to 1.
+ *
+ * Note that we have to add 1 because 1 indicates a static
+ * method, and 0 indicates a non-static, non-virtual method */
+
+ if (static_member)
+ fn_p->field.fn_fields[ix].voffset = VOFFSET_STATIC;
+ else
+ fn_p->field.fn_fields[ix].voffset = vtbl_offset ? vtbl_offset + 1 : 0;
+
+ /* Also fill in the fcontext field with the current
+ * class. (The latter isn't quite right: should be the baseclass
+ * that defines the virtual function... Note we do have
+ * a variable "baseclass" that we could stuff into the fcontext
+ * field, but "baseclass" isn't necessarily right either,
+ * since the virtual function could have been defined more
+ * than one level up).
+ */
+
+ if (vtbl_offset != 0)
+ fn_p->field.fn_fields[ix].fcontext = type;
+ else
+ fn_p->field.fn_fields[ix].fcontext = NULL;
+
+ /* Other random fields pertaining to this method */
+ fn_p->field.fn_fields[ix].is_const = const_member;
+ fn_p->field.fn_fields[ix].is_volatile = volatile_member; /* ?? */
+ switch (fieldp->dgenfield.visibility)
+ {
+ case 1:
+ fn_p->field.fn_fields[ix].is_protected = 1;
+ fn_p->field.fn_fields[ix].is_private = 0;
+ break;
+ case 2:
+ fn_p->field.fn_fields[ix].is_protected = 0;
+ fn_p->field.fn_fields[ix].is_private = 1;
+ break;
+ default: /* public */
+ fn_p->field.fn_fields[ix].is_protected = 0;
+ fn_p->field.fn_fields[ix].is_private = 0;
+ }
+ fn_p->field.fn_fields[ix].is_stub = 0;
+
+ /* HP aCC emits both MEMFUNC and FUNCTION entries for a method;
+ if the class points to the FUNCTION, there is usually separate
+ code for the method; but if we have a MEMFUNC, the method has
+ been inlined (and there is usually no FUNCTION entry)
+ FIXME Not sure if this test is accurate. pai/1997-08-22 */
+ if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) ||
+ (fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC))
+ fn_p->field.fn_fields[ix].is_inlined = 1;
+ else
+ fn_p->field.fn_fields[ix].is_inlined = 0;
+
+ fn_p->field.fn_fields[ix].dummy = 0;
+
+ /* Bump the total count of the member functions */
+ n_fn_fields_total++;
+
+ }
+ else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR)
+ {
+ /* This case is for static data members of classes */
+
+ /* pai:: FIXME -- check that "staticmem" bit is set */
+
+ /* Get space to record this static member */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+
+ list->field.name = VT (objfile) + fn_fieldp->dsvar.name;
+ FIELD_BITSIZE (list->field) = -1; /* indicates static member */
+ SET_FIELD_PHYSNAME (list->field, 0); /* initialize to empty */
+ memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile);
+
+ FIELD_TYPE (list->field) = memtype;
+ list->attributes = 0;
+ switch (fieldp->dgenfield.visibility)
+ {
+ case 1:
+ B_SET (&(list->attributes), ATTR_PROTECT);
+ break;
+ case 2:
+ B_SET (&(list->attributes), ATTR_PRIVATE);
+ break;
+ }
+ nfields++;
+ }
+
+ else if (fn_fieldp->dblock.kind == DNTT_TYPE_FIELD)
+ {
+ /* FIELDs follow GENFIELDs for fields of anonymous unions.
+ Code below is replicated from the case for FIELDs further
+ below, except that fieldp is replaced by fn_fieldp */
+ if (!fn_fieldp->dfield.a_union)
+ warning ("Debug info inconsistent: FIELD of anonymous union doesn't have a_union bit set");
+ /* Get space to record the next field/data-member. */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+
+ list->field.name = VT (objfile) + fn_fieldp->dfield.name;
+ FIELD_BITPOS (list->field) = fn_fieldp->dfield.bitoffset;
+ if (fn_fieldp->dfield.bitlength % 8)
+ list->field.bitsize = fn_fieldp->dfield.bitlength;
+ else
+ list->field.bitsize = 0;
+
+ memtype = hpread_type_lookup (fn_fieldp->dfield.type, objfile);
+ list->field.type = memtype;
+ list->attributes = 0;
+ switch (fn_fieldp->dfield.visibility)
+ {
+ case 1:
+ B_SET (&(list->attributes), ATTR_PROTECT);
+ break;
+ case 2:
+ B_SET (&(list->attributes), ATTR_PRIVATE);
+ break;
+ }
+ nfields++;
+ }
+ else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR)
+ {
+ /* Field of anonymous union; union is not inside a class */
+ if (!fn_fieldp->dsvar.a_union)
+ warning ("Debug info inconsistent: SVAR field in anonymous union doesn't have a_union bit set");
+ /* Get space to record the next field/data-member. */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+
+ list->field.name = VT (objfile) + fn_fieldp->dsvar.name;
+ FIELD_BITPOS (list->field) = 0; /* FIXME is this always true? */
+ FIELD_BITSIZE (list->field) = 0; /* use length from type */
+ memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile);
+ list->field.type = memtype;
+ list->attributes = 0;
+ /* No info to set visibility -- always public */
+ nfields++;
+ }
+ else if (fn_fieldp->dblock.kind == DNTT_TYPE_DVAR)
+ {
+ /* Field of anonymous union; union is not inside a class */
+ if (!fn_fieldp->ddvar.a_union)
+ warning ("Debug info inconsistent: DVAR field in anonymous union doesn't have a_union bit set");
+ /* Get space to record the next field/data-member. */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+
+ list->field.name = VT (objfile) + fn_fieldp->ddvar.name;
+ FIELD_BITPOS (list->field) = 0; /* FIXME is this always true? */
+ FIELD_BITSIZE (list->field) = 0; /* use length from type */
+ memtype = hpread_type_lookup (fn_fieldp->ddvar.type, objfile);
+ list->field.type = memtype;
+ list->attributes = 0;
+ /* No info to set visibility -- always public */
+ nfields++;
+ }
+ else
+ { /* Not a method, nor a static data member, nor an anon union field */
+
+ /* This case is for miscellaneous type entries (local enums,
+ local function templates, etc.) that can be present
+ inside a class. */
+
+ /* Enums -- will be handled by other code that takes care
+ of DNTT_TYPE_ENUM; here we see only DNTT_TYPE_MEMENUM so
+ it's not clear we could have handled them here at all. */
+ /* FUNC_TEMPLATE: is handled by other code (?). */
+ /* MEMACCESS: modified access for inherited member. Not
+ sure what to do with this, ignoriing it at present. */
+
+ /* What other entries can appear following a GENFIELD which
+ we do not handle above? (MODIFIER, VFUNC handled above.) */
+
+ if ((fn_fieldp->dblock.kind != DNTT_TYPE_MEMACCESS) &&
+ (fn_fieldp->dblock.kind != DNTT_TYPE_MEMENUM) &&
+ (fn_fieldp->dblock.kind != DNTT_TYPE_FUNC_TEMPLATE))
+ warning ("Internal error: Unexpected debug record kind %d found following DNTT_GENFIELD",
+ fn_fieldp->dblock.kind);
+ }
+ /* walk to the next FIELD or GENFIELD */
+ field = fieldp->dgenfield.nextfield;
+
+ }
+ else if (fieldp->dblock.kind == DNTT_TYPE_FIELD)
+ {
+
+ /* Ordinary structure/union/class field */
+ struct type *anon_union_type;
+
+ /* Get space to record the next field/data-member. */
+ new = (struct nextfield *) alloca (sizeof (struct nextfield));
+ new->next = list;
+ list = new;
+
+ list->field.name = VT (objfile) + fieldp->dfield.name;
+
+
+ /* A FIELD by itself (without a GENFIELD) can also be a static member */
+ if (fieldp->dfield.staticmem)
+ {
+ FIELD_BITPOS (list->field) = -1;
+ FIELD_BITSIZE (list->field) = 0;
+ }
+ else
+ /* Non-static data member */
+ {
+ FIELD_BITPOS (list->field) = fieldp->dfield.bitoffset;
+ if (fieldp->dfield.bitlength % 8)
+ FIELD_BITSIZE (list->field) = fieldp->dfield.bitlength;
+ else
+ FIELD_BITSIZE (list->field) = 0;
+ }
+
+ memtype = hpread_type_lookup (fieldp->dfield.type, objfile);
+ FIELD_TYPE (list->field) = memtype;
+ list->attributes = 0;
+ switch (fieldp->dfield.visibility)
+ {
+ case 1:
+ B_SET (&(list->attributes), ATTR_PROTECT);
+ break;
+ case 2:
+ B_SET (&(list->attributes), ATTR_PRIVATE);
+ break;
+ }
+ nfields++;
+
+
+ /* Note 1: First, we have to check if the current field is an anonymous
+ union. If it is, then *its* fields are threaded along in the
+ nextfield chain. :-( This was supposed to help debuggers, but is
+ really just a nuisance since we deal with anonymous unions anyway by
+ checking that the name is null. So anyway, we skip over the fields
+ of the anonymous union. pai/1997-08-22 */
+ /* Note 2: In addition, the bitoffsets for the fields of the anon union
+ are relative to the enclosing struct, *NOT* relative to the anon
+ union! This is an even bigger nuisance -- we have to go in and munge
+ the anon union's type information appropriately. pai/1997-08-22 */
+
+ /* Both tasks noted above are done by a separate function. This takes us
+ to the next FIELD or GENFIELD, skipping anon unions, and recursively
+ processing intermediate types. */
+ field = hpread_get_next_skip_over_anon_unions (1, field, &fieldp, objfile);
+
+ }
+ else
+ {
+ /* neither field nor genfield ?? is this possible?? */
+ /* pai:: FIXME walk to the next -- how? */
+ warning ("Internal error: unexpected DNTT kind %d encountered as field of struct",
+ fieldp->dblock.kind);
+ warning ("Skipping remaining fields of struct");
+ break; /* get out of loop of fields */
+ }
+ }
+
+ /* If it's a template, read in the instantiation list */
+ if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+ {
+ ninstantiations = 0;
+ field = dn_bufp->dtemplate.expansions;
+ while (field.word && field.word != DNTTNIL)
+ {
+ fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+
+ /* The expansions or nextexp should point to a tagdef */
+ if (fieldp->dblock.kind != DNTT_TYPE_TAGDEF)
+ break;
+
+ i_new = (struct next_instantiation *) alloca (sizeof (struct next_instantiation));
+ i_new->next = i_list;
+ i_list = i_new;
+ i_list->t = hpread_type_lookup (field, objfile);
+ ninstantiations++;
+
+ /* And the "type" field of that should point to a class */
+ field = fieldp->dtag.type;
+ fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+ if (fieldp->dblock.kind != DNTT_TYPE_CLASS)
+ break;
+
+ /* Get the next expansion */
+ field = fieldp->dclass.nextexp;
+ }
+ }
+ TYPE_NINSTANTIATIONS (type) = ninstantiations;
+ if (ninstantiations > 0)
+ TYPE_INSTANTIATIONS (type) = (struct type **)
+ obstack_alloc (&objfile->type_obstack, sizeof (struct type *) * ninstantiations);
+ for (n = ninstantiations; i_list; i_list = i_list->next)
+ {
+ n -= 1;
+ TYPE_INSTANTIATION (type, n) = i_list->t;
+ }
+
+
+ /* Copy the field-list to GDB's symbol table */
+ TYPE_NFIELDS (type) = nfields;
+ TYPE_N_BASECLASSES (type) = n_base_classes;
+ TYPE_FIELDS (type) = (struct field *)
+ obstack_alloc (&objfile->type_obstack, sizeof (struct field) * nfields);
+ /* Copy the saved-up fields into the field vector. */
+ for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next)
+ {
+ n -= 1;
+ TYPE_FIELD (type, n) = tmp_list->field;
+ }
+
+ /* Copy the "function-field-list" (i.e., the list of member
+ * functions in the class) to GDB's symbol table
+ */
+ TYPE_NFN_FIELDS (type) = n_fn_fields;
+ TYPE_NFN_FIELDS_TOTAL (type) = n_fn_fields_total;
+ TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
+ obstack_alloc (&objfile->type_obstack, sizeof (struct fn_fieldlist) * n_fn_fields);
+ for (n = n_fn_fields; fn_list; fn_list = fn_list->next)
+ {
+ n -= 1;
+ TYPE_FN_FIELDLIST (type, n) = fn_list->field;
+ }
+
+ /* pai:: FIXME -- perhaps each bitvector should be created individually */
+ for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next)
+ {
+ n -= 1;
+ if (tmp_list->attributes)
+ {
+ need_bitvectors = 1;
+ break;
+ }
+ }
+
+ if (need_bitvectors)
+ {
+ /* pai:: this step probably redundant */
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+
+ TYPE_FIELD_VIRTUAL_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), nfields);
+
+ TYPE_FIELD_PRIVATE_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
+
+ TYPE_FIELD_PROTECTED_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
+
+ /* this field vector isn't actually used with HP aCC */
+ TYPE_FIELD_IGNORE_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
+
+ while (nfields-- > 0)
+ {
+ if (B_TST (&(list->attributes), ATTR_VIRTUAL))
+ SET_TYPE_FIELD_VIRTUAL (type, nfields);
+ if (B_TST (&(list->attributes), ATTR_PRIVATE))
+ SET_TYPE_FIELD_PRIVATE (type, nfields);
+ if (B_TST (&(list->attributes), ATTR_PROTECT))
+ SET_TYPE_FIELD_PROTECTED (type, nfields);
+
+ list = list->next;
+ }
+ }
+ else
+ {
+ TYPE_FIELD_VIRTUAL_BITS (type) = NULL;
+ TYPE_FIELD_PROTECTED_BITS (type) = NULL;
+ TYPE_FIELD_PRIVATE_BITS (type) = NULL;
+ }
+
+ if (has_vtable (type))
+ {
+ /* Allocate space for class runtime information */
+ TYPE_RUNTIME_PTR (type) = (struct runtime_info *) xmalloc (sizeof (struct runtime_info));
+ /* Set flag for vtable */
+ TYPE_VTABLE (type) = 1;
+ /* The first non-virtual base class with a vtable. */
+ TYPE_PRIMARY_BASE (type) = primary_base_class (type);
+ /* The virtual base list. */
+ TYPE_VIRTUAL_BASE_LIST (type) = virtual_base_list (type);
+ }
+ else
+ TYPE_RUNTIME_PTR (type) = NULL;
+
+ /* If this is a local type (C++ - declared inside a function), record file name & line # */
+ if (hpread_get_scope_depth (dn_bufp, objfile, 1 /* no need for real depth */ ))
+ {
+ TYPE_LOCALTYPE_PTR (type) = (struct local_type_info *) xmalloc (sizeof (struct local_type_info));
+ TYPE_LOCALTYPE_FILE (type) = (char *) xmalloc (strlen (current_subfile->name) + 1);
+ strcpy (TYPE_LOCALTYPE_FILE (type), current_subfile->name);
+ if (current_subfile->line_vector && (current_subfile->line_vector->nitems > 0))
+ TYPE_LOCALTYPE_LINE (type) = current_subfile->line_vector->item[current_subfile->line_vector->nitems - 1].line;
+ else
+ TYPE_LOCALTYPE_LINE (type) = 0;
+ }
+ else
+ TYPE_LOCALTYPE_PTR (type) = NULL;
+
+ /* Clear the global saying what template we are in the middle of processing */
+ current_template = NULL;
+
+ return type;
+}
+
+/* Adjust the physnames for each static member of a struct
+ or class type to be something like "A::x"; then various
+ other pieces of code that do a lookup_symbol on the phyname
+ work correctly.
+ TYPE is a pointer to the struct/class type
+ NAME is a char * (string) which is the class/struct name
+ Void return */
+
+static void
+fix_static_member_physnames (struct type *type, char *class_name,
+ struct objfile *objfile)
+{
+ int i;
+
+ /* We fix the member names only for classes or structs */
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
+ return;
+
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
+ if (TYPE_FIELD_STATIC (type, i))
+ {
+ if (TYPE_FIELD_STATIC_PHYSNAME (type, i))
+ return; /* physnames are already set */
+
+ SET_FIELD_PHYSNAME (TYPE_FIELDS (type)[i],
+ obstack_alloc (&objfile->type_obstack,
+ strlen (class_name) + strlen (TYPE_FIELD_NAME (type, i)) + 3));
+ strcpy (TYPE_FIELD_STATIC_PHYSNAME (type, i), class_name);
+ strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), "::");
+ strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), TYPE_FIELD_NAME (type, i));
+ }
+}
+
+/* Fix-up the type structure for a CLASS so that the type entry
+ * for a method (previously marked with a null type in hpread_read_struct_type()
+ * is set correctly to METHOD.
+ * OBJFILE is as for other such functions.
+ * Void return. */
+
+static void
+fixup_class_method_type (struct type *class, struct type *method,
+ struct objfile *objfile)
+{
+ int i, j, k;
+
+ if (!class || !method || !objfile)
+ return;
+
+ /* Only for types that have methods */
+ if ((TYPE_CODE (class) != TYPE_CODE_CLASS) &&
+ (TYPE_CODE (class) != TYPE_CODE_UNION))
+ return;
+
+ /* Loop over all methods and find the one marked with a NULL type */
+ for (i = 0; i < TYPE_NFN_FIELDS (class); i++)
+ for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (class, i); j++)
+ if (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) == NULL)
+ {
+ /* Set the method type */
+ TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) = method;
+ /* The argument list */
+ TYPE_TYPE_SPECIFIC (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j)).arg_types
+ = (struct type **) obstack_alloc (&objfile->type_obstack,
+ sizeof (struct type *) * (TYPE_NFIELDS (method) + 1));
+ for (k = 0; k < TYPE_NFIELDS (method); k++)
+ TYPE_TYPE_SPECIFIC (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j)).arg_types[k] = TYPE_FIELDS (method)[k].type;
+ /* void termination */
+ TYPE_TYPE_SPECIFIC (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j)).arg_types[TYPE_NFIELDS (method)] = builtin_type_void;
+
+ /* Break out of both loops -- only one method to fix up in a class */
+ goto finish;
+ }
+
+finish:
+ TYPE_FLAGS (class) &= ~TYPE_FLAG_INCOMPLETE;
+}
+
+
+/* If we're in the middle of processing a template, get a pointer
+ * to the Nth template argument.
+ * An example may make this clearer:
+ * template <class T1, class T2> class q2 {
+ * public:
+ * T1 a;
+ * T2 b;
+ * };
+ * The type for "a" will be "first template arg" and
+ * the type for "b" will be "second template arg".
+ * We need to look these up in order to fill in "a" and "b"'s type.
+ * This is called from hpread_type_lookup().
+ */
+static struct type *
+hpread_get_nth_template_arg (struct objfile *objfile, int n)
+{
+ if (current_template != NULL)
+ return TYPE_TEMPLATE_ARG (current_template, n).type;
+ else
+ return lookup_fundamental_type (objfile, FT_TEMPLATE_ARG);
+}
+
+/* Read in and internalize a TEMPL_ARG (template arg) symbol. */
+
+static struct type *
+hpread_read_templ_arg_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+ struct objfile *objfile, char *name)
+{
+ struct type *type;
+
+ /* See if it's something we've already deal with. */
+ type = hpread_alloc_type (hp_type, objfile);
+ if (TYPE_CODE (type) == TYPE_CODE_TEMPLATE_ARG)
+ return type;
+
+ /* Nope. Fill in the appropriate fields. */
+ TYPE_CODE (type) = TYPE_CODE_TEMPLATE_ARG;
+ TYPE_LENGTH (type) = 0;
+ TYPE_NFIELDS (type) = 0;
+ TYPE_NAME (type) = name;
+ return type;
+}
+
+/* Read in and internalize a set debug symbol. */
+
+static struct type *
+hpread_read_set_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+ struct objfile *objfile)
+{
+ struct type *type;
+
+ /* See if it's something we've already deal with. */
+ type = hpread_alloc_type (hp_type, objfile);
+ if (TYPE_CODE (type) == TYPE_CODE_SET)
+ return type;
+
+ /* Nope. Fill in the appropriate fields. */
+ TYPE_CODE (type) = TYPE_CODE_SET;
+ TYPE_LENGTH (type) = dn_bufp->dset.bitlength / 8;
+ TYPE_NFIELDS (type) = 0;
+ TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dset.subtype,
+ objfile);
+ return type;
+}
+
+/* Read in and internalize an array debug symbol. */
+
+static struct type *
+hpread_read_array_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+ struct objfile *objfile)
+{
+ struct type *type;
+
+ /* Allocate an array type symbol.
+ * Why no check for already-read here, like in the other
+ * hpread_read_xxx_type routines? Because it kept us
+ * from properly determining the size of the array!
+ */
+ type = hpread_alloc_type (hp_type, objfile);
+
+ TYPE_CODE (type) = TYPE_CODE_ARRAY;
+
+ /* Although the hp-symtab.h does not *require* this to be the case,
+ * GDB is assuming that "arrayisbytes" and "elemisbytes" be consistent.
+ * I.e., express both array-length and element-length in bits,
+ * or express both array-length and element-length in bytes.
+ */
+ if (!((dn_bufp->darray.arrayisbytes && dn_bufp->darray.elemisbytes) ||
+ (!dn_bufp->darray.arrayisbytes && !dn_bufp->darray.elemisbytes)))
+ {
+ warning ("error in hpread_array_type.\n");
+ return NULL;
+ }
+ else if (dn_bufp->darray.arraylength == 0x7fffffff)
+ {
+ /* The HP debug format represents char foo[]; as an array with
+ * length 0x7fffffff. Internally GDB wants to represent this
+ * as an array of length zero.
+ */
+ TYPE_LENGTH (type) = 0;
+ }
+ else if (dn_bufp->darray.arrayisbytes)
+ TYPE_LENGTH (type) = dn_bufp->darray.arraylength;
+ else /* arraylength is in bits */
+ TYPE_LENGTH (type) = dn_bufp->darray.arraylength / 8;
+
+ TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->darray.elemtype,
+ objfile);
+
+ /* The one "field" is used to store the subscript type */
+ /* Since C and C++ multi-dimensional arrays are simply represented
+ * as: array of array of ..., we only need one subscript-type
+ * per array. This subscript type is typically a subrange of integer.
+ * If this gets extended to support languages like Pascal, then
+ * we need to fix this to represent multi-dimensional arrays properly.
+ */
+ TYPE_NFIELDS (type) = 1;
+ TYPE_FIELDS (type) = (struct field *)
+ obstack_alloc (&objfile->type_obstack, sizeof (struct field));
+ TYPE_FIELD_TYPE (type, 0) = hpread_type_lookup (dn_bufp->darray.indextype,
+ objfile);
+ return type;
+}
+
+/* Read in and internalize a subrange debug symbol. */
+static struct type *
+hpread_read_subrange_type (dnttpointer hp_type, union dnttentry *dn_bufp,
+ struct objfile *objfile)
+{
+ struct type *type;
+
+ /* Is it something we've already dealt with. */
+ type = hpread_alloc_type (hp_type, objfile);
+ if (TYPE_CODE (type) == TYPE_CODE_RANGE)
+ return type;
+
+ /* Nope, internalize it. */
+ TYPE_CODE (type) = TYPE_CODE_RANGE;
+ TYPE_LENGTH (type) = dn_bufp->dsubr.bitlength / 8;
+ TYPE_NFIELDS (type) = 2;
+ TYPE_FIELDS (type)
+ = (struct field *) obstack_alloc (&objfile->type_obstack,
+ 2 * sizeof (struct field));
+
+ if (dn_bufp->dsubr.dyn_low)
+ TYPE_FIELD_BITPOS (type, 0) = 0;
+ else
+ TYPE_FIELD_BITPOS (type, 0) = dn_bufp->dsubr.lowbound;
+
+ if (dn_bufp->dsubr.dyn_high)
+ TYPE_FIELD_BITPOS (type, 1) = -1;
+ else
+ TYPE_FIELD_BITPOS (type, 1) = dn_bufp->dsubr.highbound;
+ TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dsubr.subtype,
+ objfile);
+ return type;
+}
+
+/* struct type * hpread_type_lookup(hp_type, objfile)
+ * Arguments:
+ * hp_type: A pointer into the DNTT specifying what type we
+ * are about to "look up"., or else [for fundamental types
+ * like int, float, ...] an "immediate" structure describing
+ * the type.
+ * objfile: ?
+ * Return value: A pointer to a "struct type" (representation of a
+ * type in GDB's internal symbol table - see gdbtypes.h)
+ * Routine description:
+ * There are a variety of places when scanning the DNTT when we
+ * need to interpret a "type" field. The simplest and most basic
+ * example is when we're processing the symbol table record
+ * for a data symbol (a SVAR or DVAR record). That has
+ * a "type" field specifying the type of the data symbol. That
+ * "type" field is either an "immediate" type specification (for the
+ * fundamental types) or a DNTT pointer (for more complicated types).
+ * For the more complicated types, we may or may not have already
+ * processed the pointed-to type. (Multiple data symbols can of course
+ * share the same type).
+ * The job of hpread_type_lookup() is to process this "type" field.
+ * Most of the real work is done in subroutines. Here we interpret
+ * the immediate flag. If not immediate, chase the DNTT pointer to
+ * find our way to the SOM record describing the type, switch on
+ * the SOM kind, and then call an appropriate subroutine depending
+ * on what kind of type we are constructing. (e.g., an array type,
+ * a struct/class type, etc).
+ */
+static struct type *
+hpread_type_lookup (dnttpointer hp_type, struct objfile *objfile)
+{
+ union dnttentry *dn_bufp;
+ struct type *tmp_type;
+
+ /* First see if it's a simple builtin type. */
+ if (hp_type.dntti.immediate)
+ {
+ /* If this is a template argument, the argument number is
+ * encoded in the bitlength. All other cases, just return
+ * GDB's representation of this fundamental type.
+ */
+ if (hp_type.dntti.type == HP_TYPE_TEMPLATE_ARG)
+ return hpread_get_nth_template_arg (objfile, hp_type.dntti.bitlength);
+ else
+ return lookup_fundamental_type (objfile,
+ hpread_type_translate (hp_type));
+ }
+
+ /* Not a builtin type. We'll have to read it in. */
+ if (hp_type.dnttp.index < LNTT_SYMCOUNT (objfile))
+ dn_bufp = hpread_get_lntt (hp_type.dnttp.index, objfile);
+ else
+ /* This is a fancy way of returning NULL */
+ return lookup_fundamental_type (objfile, FT_VOID);
+
+ switch (dn_bufp->dblock.kind)
+ {
+ case DNTT_TYPE_SRCFILE:
+ case DNTT_TYPE_MODULE:
+ case DNTT_TYPE_ENTRY:
+ case DNTT_TYPE_BEGIN:
+ case DNTT_TYPE_END:
+ case DNTT_TYPE_IMPORT:
+ case DNTT_TYPE_LABEL:
+ case DNTT_TYPE_FPARAM:
+ case DNTT_TYPE_SVAR:
+ case DNTT_TYPE_DVAR:
+ case DNTT_TYPE_CONST:
+ case DNTT_TYPE_MEMENUM:
+ case DNTT_TYPE_VARIANT:
+ case DNTT_TYPE_FILE:
+ case DNTT_TYPE_WITH:
+ case DNTT_TYPE_COMMON:
+ case DNTT_TYPE_COBSTRUCT:
+ case DNTT_TYPE_XREF:
+ case DNTT_TYPE_SA:
+ case DNTT_TYPE_MACRO:
+ case DNTT_TYPE_BLOCKDATA:
+ case DNTT_TYPE_CLASS_SCOPE:
+ case DNTT_TYPE_MEMACCESS:
+ case DNTT_TYPE_INHERITANCE:
+ case DNTT_TYPE_OBJECT_ID:
+ case DNTT_TYPE_FRIEND_CLASS:
+ case DNTT_TYPE_FRIEND_FUNC:
+ /* These are not types - something went wrong. */
+ /* This is a fancy way of returning NULL */
+ return lookup_fundamental_type (objfile, FT_VOID);
+
+ case DNTT_TYPE_FUNCTION:
+ /* We wind up here when dealing with class member functions
+ * (called from hpread_read_struct_type(), i.e. when processing
+ * the class definition itself).
+ */
+ return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+ case DNTT_TYPE_DOC_FUNCTION:
+ return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0);
+
+ case DNTT_TYPE_TYPEDEF:
+ {
+ /* A typedef - chase it down by making a recursive call */
+ struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type,
+ objfile);
+
+ /* The following came from the base hpread.c that we inherited.
+ * It is WRONG so I have commented it out. - RT
+ *...
+
+ char *suffix;
+ suffix = VT (objfile) + dn_bufp->dtype.name;
+ TYPE_NAME (structtype) = suffix;
+
+ * ... further explanation ....
+ *
+ * What we have here is a typedef pointing to a typedef.
+ * E.g.,
+ * typedef int foo;
+ * typedef foo fum;
+ *
+ * What we desire to build is (these are pictures
+ * of "struct type"'s):
+ *
+ * +---------+ +----------+ +------------+
+ * | typedef | | typedef | | fund. type |
+ * | type| -> | type| -> | |
+ * | "fum" | | "foo" | | "int" |
+ * +---------+ +----------+ +------------+
+ *
+ * What this commented-out code is doing is smashing the
+ * name of pointed-to-type to be the same as the pointed-from
+ * type. So we wind up with something like:
+ *
+ * +---------+ +----------+ +------------+
+ * | typedef | | typedef | | fund. type |
+ * | type| -> | type| -> | |
+ * | "fum" | | "fum" | | "fum" |
+ * +---------+ +----------+ +------------+
+ *
+ */
+
+ return structtype;
+ }
+
+ case DNTT_TYPE_TAGDEF:
+ {
+ /* Just a little different from above. We have to tack on
+ * an identifier of some kind (struct, union, enum, class, etc).
+ */
+ struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type,
+ objfile);
+ char *prefix, *suffix;
+ suffix = VT (objfile) + dn_bufp->dtype.name;
+
+ /* Lookup the next type in the list. It should be a structure,
+ * union, class, enum, or template type.
+ * We will need to attach that to our name.
+ */
+ if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
+ dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile);
+ else
+ {
+ complain (&hpread_type_lookup_complaint);
+ return NULL;
+ }
+
+ if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
+ {
+ prefix = "struct ";
+ }
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
+ {
+ prefix = "union ";
+ }
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
+ {
+ /* Further field for CLASS saying how it was really declared */
+ /* 0==class, 1==union, 2==struct */
+ if (dn_bufp->dclass.class_decl == 0)
+ prefix = "class ";
+ else if (dn_bufp->dclass.class_decl == 1)
+ prefix = "union ";
+ else if (dn_bufp->dclass.class_decl == 2)
+ prefix = "struct ";
+ else
+ prefix = "";
+ }
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_ENUM)
+ {
+ prefix = "enum ";
+ }
+ else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+ {
+ prefix = "template ";
+ }
+ else
+ {
+ prefix = "";
+ }
+
+ /* Build the correct name. */
+ TYPE_NAME (structtype)
+ = (char *) obstack_alloc (&objfile->type_obstack,
+ strlen (prefix) + strlen (suffix) + 1);
+ TYPE_NAME (structtype) = strcpy (TYPE_NAME (structtype), prefix);
+ TYPE_NAME (structtype) = strcat (TYPE_NAME (structtype), suffix);
+ TYPE_TAG_NAME (structtype) = suffix;
+
+ /* For classes/structs, we have to set the static member "physnames"
+ to point to strings like "Class::Member" */
+ if (TYPE_CODE (structtype) == TYPE_CODE_STRUCT)
+ fix_static_member_physnames (structtype, suffix, objfile);
+
+ return structtype;
+ }
+
+ case DNTT_TYPE_POINTER:
+ /* Pointer type - call a routine in gdbtypes.c that constructs
+ * the appropriate GDB type.
+ */
+ return make_pointer_type (
+ hpread_type_lookup (dn_bufp->dptr.pointsto,
+ objfile),
+ NULL);
+
+ case DNTT_TYPE_REFERENCE:
+ /* C++ reference type - call a routine in gdbtypes.c that constructs
+ * the appropriate GDB type.
+ */
+ return make_reference_type (
+ hpread_type_lookup (dn_bufp->dreference.pointsto,
+ objfile),
+ NULL);
+
+ case DNTT_TYPE_ENUM:
+ return hpread_read_enum_type (hp_type, dn_bufp, objfile);
+ case DNTT_TYPE_SET:
+ return hpread_read_set_type (hp_type, dn_bufp, objfile);
+ case DNTT_TYPE_SUBRANGE:
+ return hpread_read_subrange_type (hp_type, dn_bufp, objfile);
+ case DNTT_TYPE_ARRAY:
+ return hpread_read_array_type (hp_type, dn_bufp, objfile);
+ case DNTT_TYPE_STRUCT:
+ case DNTT_TYPE_UNION:
+ return hpread_read_struct_type (hp_type, dn_bufp, objfile);
+ case DNTT_TYPE_FIELD:
+ return hpread_type_lookup (dn_bufp->dfield.type, objfile);
+
+ case DNTT_TYPE_FUNCTYPE:
+ /* Here we want to read the function SOMs and return a
+ * type for it. We get here, for instance, when processing
+ * pointer-to-function type.
+ */
+ return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+ case DNTT_TYPE_PTRMEM:
+ /* Declares a C++ pointer-to-data-member type.
+ * The "pointsto" field defines the class,
+ * while the "memtype" field defines the pointed-to-type.
+ */
+ {
+ struct type *ptrmemtype;
+ struct type *class_type;
+ struct type *memtype;
+ memtype = hpread_type_lookup (dn_bufp->dptrmem.memtype,
+ objfile),
+ class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto,
+ objfile),
+ ptrmemtype = alloc_type (objfile);
+ smash_to_member_type (ptrmemtype, class_type, memtype);
+ return make_pointer_type (ptrmemtype, NULL);
+ }
+ break;
+
+ case DNTT_TYPE_PTRMEMFUNC:
+ /* Defines a C++ pointer-to-function-member type.
+ * The "pointsto" field defines the class,
+ * while the "memtype" field defines the pointed-to-type.
+ */
+ {
+ struct type *ptrmemtype;
+ struct type *class_type;
+ struct type *functype;
+ struct type *retvaltype;
+ int nargs;
+ int i;
+ struct type **args_type;
+ class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto,
+ objfile);
+ functype = hpread_type_lookup (dn_bufp->dptrmem.memtype,
+ objfile);
+ retvaltype = TYPE_TARGET_TYPE (functype);
+ nargs = TYPE_NFIELDS (functype);
+ args_type = (struct type **) xmalloc ((nargs + 1) * sizeof (struct type *));
+ for (i = 0; i < nargs; i++)
+ {
+ args_type[i] = TYPE_FIELD_TYPE (functype, i);
+ }
+ args_type[nargs] = NULL;
+ ptrmemtype = alloc_type (objfile);
+ smash_to_method_type (ptrmemtype, class_type, retvaltype, args_type);
+ return make_pointer_type (ptrmemtype, NULL);
+ }
+ break;
+
+ case DNTT_TYPE_CLASS:
+ return hpread_read_struct_type (hp_type, dn_bufp, objfile);
+
+ case DNTT_TYPE_GENFIELD:
+ /* Chase pointer from GENFIELD to FIELD, and make recursive
+ * call on that.
+ */
+ return hpread_type_lookup (dn_bufp->dgenfield.field, objfile);
+
+ case DNTT_TYPE_VFUNC:
+ /* C++ virtual function.
+ * We get here in the course of processing a class type which
+ * contains virtual functions. Just go through another level
+ * of indirection to get to the pointed-to function SOM.
+ */
+ return hpread_type_lookup (dn_bufp->dvfunc.funcptr, objfile);
+
+ case DNTT_TYPE_MODIFIER:
+ /* Check the modifiers and then just make a recursive call on
+ * the "type" pointed to by the modifier DNTT.
+ *
+ * pai:: FIXME -- do we ever want to handle "m_duplicate" and
+ * "m_void" modifiers? Is static_flag really needed here?
+ * (m_static used for methods of classes, elsewhere).
+ */
+ tmp_type = make_cv_type (dn_bufp->dmodifier.m_const,
+ dn_bufp->dmodifier.m_volatile,
+ hpread_type_lookup (dn_bufp->dmodifier.type, objfile),
+ 0);
+ return tmp_type;
+
+
+ case DNTT_TYPE_MEMFUNC:
+ /* Member function. Treat like a function.
+ * I think we get here in the course of processing a
+ * pointer-to-member-function type...
+ */
+ return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+ case DNTT_TYPE_DOC_MEMFUNC:
+ return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0);
+
+ case DNTT_TYPE_TEMPLATE:
+ /* Template - sort of the header for a template definition,
+ * which like a class, points to a member list and also points
+ * to a TEMPLATE_ARG list of type-arguments.
+ */
+ return hpread_read_struct_type (hp_type, dn_bufp, objfile);
+
+ case DNTT_TYPE_TEMPLATE_ARG:
+ {
+ char *name;
+ /* The TEMPLATE record points to an argument list of
+ * TEMPLATE_ARG records, each of which describes one
+ * of the type-arguments.
+ */
+ name = VT (objfile) + dn_bufp->dtempl_arg.name;
+ return hpread_read_templ_arg_type (hp_type, dn_bufp, objfile, name);
+ }
+
+ case DNTT_TYPE_FUNC_TEMPLATE:
+ /* We wind up here when processing a TEMPLATE type,
+ * if the template has member function(s).
+ * Treat it like a FUNCTION.
+ */
+ return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
+
+ case DNTT_TYPE_LINK:
+ /* The LINK record is used to link up templates with instantiations.
+ * There is no type associated with the LINK record per se.
+ */
+ return lookup_fundamental_type (objfile, FT_VOID);
+
+ /* Also not yet handled... */
+ /* case DNTT_TYPE_DYN_ARRAY_DESC: */
+ /* case DNTT_TYPE_DESC_SUBRANGE: */
+ /* case DNTT_TYPE_BEGIN_EXT: */
+ /* case DNTT_TYPE_INLN: */
+ /* case DNTT_TYPE_INLN_LIST: */
+ /* case DNTT_TYPE_ALIAS: */
+ default:
+ /* A fancy way of returning NULL */
+ return lookup_fundamental_type (objfile, FT_VOID);
+ }
+}
+
+static sltpointer
+hpread_record_lines (struct subfile *subfile, sltpointer s_idx,
+ sltpointer e_idx, struct objfile *objfile,
+ CORE_ADDR offset)
+{
+ union sltentry *sl_bufp;
+
+ while (s_idx <= e_idx)
+ {
+ sl_bufp = hpread_get_slt (s_idx, objfile);
+ /* Only record "normal" entries in the SLT. */
+ if (sl_bufp->snorm.sltdesc == SLT_NORMAL
+ || sl_bufp->snorm.sltdesc == SLT_EXIT)
+ record_line (subfile, sl_bufp->snorm.line,
+ sl_bufp->snorm.address + offset);
+ else if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
+ record_line (subfile, sl_bufp->snormoff.line,
+ sl_bufp->snormoff.address + offset);
+ s_idx++;
+ }
+ return e_idx;
+}
+
+/* Given a function "f" which is a member of a class, find
+ * the classname that it is a member of. Used to construct
+ * the name (e.g., "c::f") which GDB will put in the
+ * "demangled name" field of the function's symbol.
+ * Called from hpread_process_one_debug_symbol()
+ * If "f" is not a member function, return NULL.
+ */
+char *
+class_of (struct type *functype)
+{
+ struct type *first_param_type;
+ char *first_param_name;
+ struct type *pointed_to_type;
+ char *class_name;
+
+ /* Check that the function has a first argument "this",
+ * and that "this" is a pointer to a class. If not,
+ * functype is not a member function, so return NULL.
+ */
+ if (TYPE_NFIELDS (functype) == 0)
+ return NULL;
+ first_param_name = TYPE_FIELD_NAME (functype, 0);
+ if (first_param_name == NULL)
+ return NULL; /* paranoia */
+ if (strcmp (first_param_name, "this"))
+ return NULL;
+ first_param_type = TYPE_FIELD_TYPE (functype, 0);
+ if (first_param_type == NULL)
+ return NULL; /* paranoia */
+ if (TYPE_CODE (first_param_type) != TYPE_CODE_PTR)
+ return NULL;
+
+ /* Get the thing that "this" points to, check that
+ * it's a class, and get its class name.
+ */
+ pointed_to_type = TYPE_TARGET_TYPE (first_param_type);
+ if (pointed_to_type == NULL)
+ return NULL; /* paranoia */
+ if (TYPE_CODE (pointed_to_type) != TYPE_CODE_CLASS)
+ return NULL;
+ class_name = TYPE_NAME (pointed_to_type);
+ if (class_name == NULL)
+ return NULL; /* paranoia */
+
+ /* The class name may be of the form "class c", in which case
+ * we want to strip off the leading "class ".
+ */
+ if (strncmp (class_name, "class ", 6) == 0)
+ class_name += 6;
+
+ return class_name;
+}
+
+/* Internalize one native debug symbol.
+ * Called in a loop from hpread_expand_symtab().
+ * Arguments:
+ * dn_bufp:
+ * name:
+ * section_offsets:
+ * objfile:
+ * text_offset:
+ * text_size:
+ * filename:
+ * index: Index of this symbol
+ * at_module_boundary_p Pointer to boolean flag to control caller's loop.
+ */
+
+static void
+hpread_process_one_debug_symbol (union dnttentry *dn_bufp, char *name,
+ struct section_offsets *section_offsets,
+ struct objfile *objfile, CORE_ADDR text_offset,
+ int text_size, char *filename, int index,
+ int *at_module_boundary_p)
+{
+ unsigned long desc;
+ int type;
+ CORE_ADDR valu;
+ int offset = ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+ int data_offset = ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
+ union dnttentry *dn_temp;
+ dnttpointer hp_type;
+ struct symbol *sym;
+ struct context_stack *new;
+ char *class_scope_name;
+
+ /* Allocate one GDB debug symbol and fill in some default values. */
+ sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = obsavestring (name, strlen (name), &objfile->symbol_obstack);
+ SYMBOL_LANGUAGE (sym) = language_auto;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_LINE (sym) = 0;
+ SYMBOL_VALUE (sym) = 0;
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+
+ /* Just a trick in case the SOM debug symbol is a type definition.
+ * There are routines that are set up to build a GDB type symbol, given
+ * a SOM dnttpointer. So we set up a dummy SOM dnttpointer "hp_type".
+ * This allows us to call those same routines.
+ */
+ hp_type.dnttp.extension = 1;
+ hp_type.dnttp.immediate = 0;
+ hp_type.dnttp.global = 0;
+ hp_type.dnttp.index = index;
+
+ /* This "type" is the type of SOM record.
+ * Switch on SOM type.
+ */
+ type = dn_bufp->dblock.kind;
+ switch (type)
+ {
+ case DNTT_TYPE_SRCFILE:
+ /* This type of symbol indicates from which source file or
+ * include file any following data comes. It may indicate:
+ *
+ * o The start of an entirely new source file (and thus
+ * a new module)
+ *
+ * o The start of a different source file due to #include
+ *
+ * o The end of an include file and the return to the original
+ * file. Thus if "foo.c" includes "bar.h", we see first
+ * a SRCFILE for foo.c, then one for bar.h, and then one for
+ * foo.c again.
+ *
+ * If it indicates the start of a new module then we must
+ * finish the symbol table of the previous module
+ * (if any) and start accumulating a new symbol table.
+ */
+
+ valu = text_offset;
+ if (!last_source_file)
+ {
+ /*
+ * A note on "last_source_file": this is a char* pointing
+ * to the actual file name. "start_symtab" sets it,
+ * "end_symtab" clears it.
+ *
+ * So if "last_source_file" is NULL, then either this is
+ * the first record we are looking at, or a previous call
+ * to "end_symtab()" was made to close out the previous
+ * module. Since we're now quitting the scan loop when we
+ * see a MODULE END record, we should never get here, except
+ * in the case that we're not using the quick look-up tables
+ * and have to use the old system as a fall-back.
+ */
+ start_symtab (name, NULL, valu);
+ record_debugformat ("HP");
+ SL_INDEX (objfile) = dn_bufp->dsfile.address;
+ }
+
+ else
+ {
+ /* Either a new include file, or a SRCFILE record
+ * saying we are back in the main source (or out of
+ * a nested include file) again.
+ */
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->dsfile.address,
+ objfile, offset);
+ }
+
+ /* A note on "start_subfile". This routine will check
+ * the name we pass it and look for an existing subfile
+ * of that name. There's thus only one sub-file for the
+ * actual source (e.g. for "foo.c" in foo.c), despite the
+ * fact that we'll see lots of SRCFILE entries for foo.c
+ * inside foo.c.
+ */
+ start_subfile (name, NULL);
+ break;
+
+ case DNTT_TYPE_MODULE:
+ /*
+ * We no longer ignore DNTT_TYPE_MODULE symbols. The module
+ * represents the meaningful semantic structure of a compilation
+ * unit. We expect to start the psymtab-to-symtab expansion
+ * looking at a MODULE entry, and to end it at the corresponding
+ * END MODULE entry.
+ *
+ *--Begin outdated comments
+ *
+ * This record signifies the start of a new source module
+ * In C/C++ there is no explicit "module" construct in the language,
+ * but each compilation unit is implicitly a module and they
+ * do emit the DNTT_TYPE_MODULE records.
+ * The end of the module is marked by a matching DNTT_TYPE_END record.
+ *
+ * The reason GDB gets away with ignoring the DNTT_TYPE_MODULE record
+ * is it notices the DNTT_TYPE_END record for the previous
+ * module (see comments under DNTT_TYPE_END case), and then treats
+ * the next DNTT_TYPE_SRCFILE record as if it were the module-start record.
+ * (i.e., it makes a start_symtab() call).
+ * This scheme seems a little convoluted, but I'll leave it
+ * alone on the principle "if it ain't broke don't fix
+ * it". (RT).
+ *
+ *-- End outdated comments
+ */
+
+ valu = text_offset;
+ if (!last_source_file)
+ {
+ /* Start of a new module. We know this because "last_source_file"
+ * is NULL, which can only happen the first time or if we just
+ * made a call to end_symtab() to close out the previous module.
+ */
+ start_symtab (name, NULL, valu);
+ SL_INDEX (objfile) = dn_bufp->dmodule.address;
+ }
+ else
+ {
+ /* This really shouldn't happen if we're using the quick
+ * look-up tables, as it would mean we'd scanned past an
+ * END MODULE entry. But if we're not using the tables,
+ * we started the module on the SRCFILE entry, so it's ok.
+ * For now, accept this.
+ */
+ /* warning( "Error expanding psymtab, missed module end, found entry for %s",
+ * name );
+ */
+ *at_module_boundary_p = -1;
+ }
+
+ start_subfile (name, NULL);
+ break;
+
+ case DNTT_TYPE_FUNCTION:
+ case DNTT_TYPE_ENTRY:
+ /* A function or secondary entry point. */
+ valu = dn_bufp->dfunc.lowaddr + offset;
+
+ /* Record lines up to this point. */
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->dfunc.address,
+ objfile, offset);
+
+ WITHIN_FUNCTION (objfile) = 1;
+ CURRENT_FUNCTION_VALUE (objfile) = valu;
+
+ /* Stack must be empty now. */
+ if (context_stack_depth != 0)
+ complain (&lbrac_unmatched_complaint, (char *) symnum);
+ new = push_context (0, valu);
+
+ /* Built a type for the function. This includes processing
+ * the symbol records for the function parameters.
+ */
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+ SYMBOL_TYPE (sym) = hpread_read_function_type (hp_type, dn_bufp, objfile, 1);
+
+ /* The "SYMBOL_NAME" field is expected to be the mangled name
+ * (if any), which we get from the "alias" field of the SOM record
+ * if that exists.
+ */
+ if ((dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
+ dn_bufp->dfunc.alias && /* has an alias */
+ *(char *) (VT (objfile) + dn_bufp->dfunc.alias)) /* not a null string */
+ SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.alias;
+ else
+ SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name;
+
+ /* Special hack to get around HP compilers' insistence on
+ * reporting "main" as "_MAIN_" for C/C++ */
+ if ((strcmp (SYMBOL_NAME (sym), "_MAIN_") == 0) &&
+ (strcmp (VT (objfile) + dn_bufp->dfunc.name, "main") == 0))
+ SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name;
+
+ /* The SYMBOL_CPLUS_DEMANGLED_NAME field is expected to
+ * be the demangled name.
+ */
+ if (dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS)
+ {
+ /* SYMBOL_INIT_DEMANGLED_NAME is a macro which winds up
+ * calling the demangler in libiberty (cplus_demangle()) to
+ * do the job. This generally does the job, even though
+ * it's intended for the GNU compiler and not the aCC compiler
+ * Note that SYMBOL_INIT_DEMANGLED_NAME calls the
+ * demangler with arguments DMGL_PARAMS | DMGL_ANSI.
+ * Generally, we don't want params when we display
+ * a demangled name, but when I took out the DMGL_PARAMS,
+ * some things broke, so I'm leaving it in here, and
+ * working around the issue in stack.c. - RT
+ */
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+ if ((SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->dfunc.alias) &&
+ (!SYMBOL_CPLUS_DEMANGLED_NAME (sym)))
+ {
+
+ /* Well, the symbol name is mangled, but the
+ * demangler in libiberty failed so the demangled
+ * field is still NULL. Try to
+ * do the job ourselves based on the "name" field
+ * in the SOM record. A complication here is that
+ * the name field contains only the function name
+ * (like "f"), whereas we want the class qualification
+ * (as in "c::f"). Try to reconstruct that.
+ */
+ char *basename;
+ char *classname;
+ char *dem_name;
+ basename = VT (objfile) + dn_bufp->dfunc.name;
+ classname = class_of (SYMBOL_TYPE (sym));
+ if (classname)
+ {
+ dem_name = xmalloc (strlen (basename) + strlen (classname) + 3);
+ strcpy (dem_name, classname);
+ strcat (dem_name, "::");
+ strcat (dem_name, basename);
+ SYMBOL_CPLUS_DEMANGLED_NAME (sym) = dem_name;
+ SYMBOL_LANGUAGE (sym) = language_cplus;
+ }
+ }
+ }
+
+ /* Add the function symbol to the list of symbols in this blockvector */
+ if (dn_bufp->dfunc.global)
+ add_symbol_to_list (sym, &global_symbols);
+ else
+ add_symbol_to_list (sym, &file_symbols);
+ new->name = sym;
+
+ /* Search forward to the next BEGIN and also read
+ * in the line info up to that point.
+ * Not sure why this is needed.
+ * In HP FORTRAN this code is harmful since there
+ * may not be a BEGIN after the FUNCTION.
+ * So I made it C/C++ specific. - RT
+ */
+ if (dn_bufp->dfunc.language == HP_LANGUAGE_C ||
+ dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS)
+ {
+ while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN)
+ {
+ dn_bufp = hpread_get_lntt (++index, objfile);
+ if (dn_bufp->dblock.extension)
+ continue;
+ }
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->dbegin.address,
+ objfile, offset);
+ SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
+ }
+ record_line (current_subfile, SYMBOL_LINE (sym), valu);
+ break;
+
+ case DNTT_TYPE_DOC_FUNCTION:
+ valu = dn_bufp->ddocfunc.lowaddr + offset;
+
+ /* Record lines up to this point. */
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->ddocfunc.address,
+ objfile, offset);
+
+ WITHIN_FUNCTION (objfile) = 1;
+ CURRENT_FUNCTION_VALUE (objfile) = valu;
+ /* Stack must be empty now. */
+ if (context_stack_depth != 0)
+ complain (&lbrac_unmatched_complaint, (char *) symnum);
+ new = push_context (0, valu);
+
+ /* Built a type for the function. This includes processing
+ * the symbol records for the function parameters.
+ */
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+ SYMBOL_TYPE (sym) = hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 1);
+
+ /* The "SYMBOL_NAME" field is expected to be the mangled name
+ * (if any), which we get from the "alias" field of the SOM record
+ * if that exists.
+ */
+ if ((dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
+ dn_bufp->ddocfunc.alias && /* has an alias */
+ *(char *) (VT (objfile) + dn_bufp->ddocfunc.alias)) /* not a null string */
+ SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.alias;
+ else
+ SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name;
+
+ /* Special hack to get around HP compilers' insistence on
+ * reporting "main" as "_MAIN_" for C/C++ */
+ if ((strcmp (SYMBOL_NAME (sym), "_MAIN_") == 0) &&
+ (strcmp (VT (objfile) + dn_bufp->ddocfunc.name, "main") == 0))
+ SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name;
+
+ if (dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS)
+ {
+
+ /* SYMBOL_INIT_DEMANGLED_NAME is a macro which winds up
+ * calling the demangler in libiberty (cplus_demangle()) to
+ * do the job. This generally does the job, even though
+ * it's intended for the GNU compiler and not the aCC compiler
+ * Note that SYMBOL_INIT_DEMANGLED_NAME calls the
+ * demangler with arguments DMGL_PARAMS | DMGL_ANSI.
+ * Generally, we don't want params when we display
+ * a demangled name, but when I took out the DMGL_PARAMS,
+ * some things broke, so I'm leaving it in here, and
+ * working around the issue in stack.c. - RT
+ */
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+
+ if ((SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->ddocfunc.alias) &&
+ (!SYMBOL_CPLUS_DEMANGLED_NAME (sym)))
+ {
+
+ /* Well, the symbol name is mangled, but the
+ * demangler in libiberty failed so the demangled
+ * field is still NULL. Try to
+ * do the job ourselves based on the "name" field
+ * in the SOM record. A complication here is that
+ * the name field contains only the function name
+ * (like "f"), whereas we want the class qualification
+ * (as in "c::f"). Try to reconstruct that.
+ */
+ char *basename;
+ char *classname;
+ char *dem_name;
+ basename = VT (objfile) + dn_bufp->ddocfunc.name;
+ classname = class_of (SYMBOL_TYPE (sym));
+ if (classname)
+ {
+ dem_name = xmalloc (strlen (basename) + strlen (classname) + 3);
+ strcpy (dem_name, classname);
+ strcat (dem_name, "::");
+ strcat (dem_name, basename);
+ SYMBOL_CPLUS_DEMANGLED_NAME (sym) = dem_name;
+ SYMBOL_LANGUAGE (sym) = language_cplus;
+ }
+ }
+ }
+
+ /* Add the function symbol to the list of symbols in this blockvector */
+ if (dn_bufp->ddocfunc.global)
+ add_symbol_to_list (sym, &global_symbols);
+ else
+ add_symbol_to_list (sym, &file_symbols);
+ new->name = sym;
+
+ /* Search forward to the next BEGIN and also read
+ * in the line info up to that point.
+ * Not sure why this is needed.
+ * In HP FORTRAN this code is harmful since there
+ * may not be a BEGIN after the FUNCTION.
+ * So I made it C/C++ specific. - RT
+ */
+ if (dn_bufp->ddocfunc.language == HP_LANGUAGE_C ||
+ dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS)
+ {
+ while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN)
+ {
+ dn_bufp = hpread_get_lntt (++index, objfile);
+ if (dn_bufp->dblock.extension)
+ continue;
+ }
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->dbegin.address,
+ objfile, offset);
+ SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
+ }
+ record_line (current_subfile, SYMBOL_LINE (sym), valu);
+ break;
+
+ case DNTT_TYPE_BEGIN:
+ /* Begin a new scope. */
+ if (context_stack_depth == 1 /* this means we're at function level */ &&
+ context_stack[0].name != NULL /* this means it's a function */ &&
+ context_stack[0].depth == 0 /* this means it's the first BEGIN
+ we've seen after the FUNCTION */
+ )
+ {
+ /* This is the first BEGIN after a FUNCTION.
+ * We ignore this one, since HP compilers always insert
+ * at least one BEGIN, i.e. it's:
+ *
+ * FUNCTION
+ * argument symbols
+ * BEGIN
+ * local symbols
+ * (possibly nested BEGIN ... END's if there are inner { } blocks)
+ * END
+ * END
+ *
+ * By ignoring this first BEGIN, the local symbols get treated
+ * as belonging to the function scope, and "print func::local_sym"
+ * works (which is what we want).
+ */
+
+ /* All we do here is increase the depth count associated with
+ * the FUNCTION entry in the context stack. This ensures that
+ * the next BEGIN we see (if any), representing a real nested { }
+ * block, will get processed.
+ */
+
+ context_stack[0].depth++;
+
+ }
+ else
+ {
+
+ /* Record lines up to this SLT pointer. */
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->dbegin.address,
+ objfile, offset);
+ /* Calculate start address of new scope */
+ valu = hpread_get_location (dn_bufp->dbegin.address, objfile);
+ valu += offset; /* Relocate for dynamic loading */
+ /* We use the scope start DNTT index as nesting depth identifier! */
+ desc = hpread_get_scope_start (dn_bufp->dbegin.address, objfile);
+ new = push_context (desc, valu);
+ }
+ break;
+
+ case DNTT_TYPE_END:
+ /* End a scope. */
+
+ /* Valid end kinds are:
+ * MODULE
+ * FUNCTION
+ * WITH
+ * COMMON
+ * BEGIN
+ * CLASS_SCOPE
+ */
+
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->dend.address,
+ objfile, offset);
+ switch (dn_bufp->dend.endkind)
+ {
+ case DNTT_TYPE_MODULE:
+ /* Ending a module ends the symbol table for that module.
+ * Calling end_symtab() has the side effect of clearing the
+ * last_source_file pointer, which in turn signals
+ * process_one_debug_symbol() to treat the next DNTT_TYPE_SRCFILE
+ * record as a module-begin.
+ */
+ valu = text_offset + text_size + offset;
+
+ /* Tell our caller that we're done with expanding the
+ * debug information for a module.
+ */
+ *at_module_boundary_p = 1;
+
+ /* Don't do this, as our caller will do it!
+
+ * (void) end_symtab (valu, objfile, 0);
+ */
+ break;
+
+ case DNTT_TYPE_FUNCTION:
+ /* Ending a function, well, ends the function's scope. */
+ dn_temp = hpread_get_lntt (dn_bufp->dend.beginscope.dnttp.index,
+ objfile);
+ valu = dn_temp->dfunc.hiaddr + offset;
+ /* Insert func params into local list */
+ merge_symbol_lists (&param_symbols, &local_symbols);
+ new = pop_context ();
+ /* Make a block for the local symbols within. */
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ new->start_addr, valu, objfile);
+ WITHIN_FUNCTION (objfile) = 0; /* This may have to change for Pascal */
+ local_symbols = new->locals;
+ param_symbols = new->params;
+ break;
+
+ case DNTT_TYPE_BEGIN:
+ if (context_stack_depth == 1 &&
+ context_stack[0].name != NULL &&
+ context_stack[0].depth == 1)
+ {
+ /* This is the END corresponding to the
+ * BEGIN which we ignored - see DNTT_TYPE_BEGIN case above.
+ */
+ context_stack[0].depth--;
+ }
+ else
+ {
+ /* Ending a local scope. */
+ valu = hpread_get_location (dn_bufp->dend.address, objfile);
+ /* Why in the hell is this needed? */
+ valu += offset + 9; /* Relocate for dynamic loading */
+ new = pop_context ();
+ desc = dn_bufp->dend.beginscope.dnttp.index;
+ if (desc != new->depth)
+ complain (&lbrac_mismatch_complaint, (char *) symnum);
+
+ /* Make a block for the local symbols within. */
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ new->start_addr, valu, objfile);
+ local_symbols = new->locals;
+ param_symbols = new->params;
+ }
+ break;
+
+ case DNTT_TYPE_WITH:
+ /* Since we ignore the DNTT_TYPE_WITH that starts the scope,
+ * we can ignore the DNTT_TYPE_END that ends it.
+ */
+ break;
+
+ case DNTT_TYPE_COMMON:
+ /* End a FORTRAN common block. We don't currently handle these */
+ complain (&hpread_unhandled_end_common_complaint);
+ break;
+
+ case DNTT_TYPE_CLASS_SCOPE:
+
+ /* pai: FIXME Not handling nested classes for now -- must
+ * maintain a stack */
+ class_scope_name = NULL;
+
+#if 0
+ /* End a class scope */
+ valu = hpread_get_location (dn_bufp->dend.address, objfile);
+ /* Why in the hell is this needed? */
+ valu += offset + 9; /* Relocate for dynamic loading */
+ new = pop_context ();
+ desc = dn_bufp->dend.beginscope.dnttp.index;
+ if (desc != new->depth)
+ complain (&lbrac_mismatch_complaint, (char *) symnum);
+ /* Make a block for the local symbols within. */
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ new->start_addr, valu, objfile);
+ local_symbols = new->locals;
+ param_symbols = new->params;
+#endif
+ break;
+
+ default:
+ complain (&hpread_unexpected_end_complaint);
+ break;
+ }
+ break;
+
+ /* DNTT_TYPE_IMPORT is not handled */
+
+ case DNTT_TYPE_LABEL:
+ SYMBOL_NAMESPACE (sym) = LABEL_NAMESPACE;
+ break;
+
+ case DNTT_TYPE_FPARAM:
+ /* Function parameters. */
+ /* Note 1: This code was present in the 4.16 sources, and then
+ removed, because fparams are handled in
+ hpread_read_function_type(). However, while fparam symbols
+ are indeed handled twice, this code here cannot be removed
+ because then they don't get added to the local symbol list of
+ the function's code block, which leads to a failure to look
+ up locals, "this"-relative member names, etc. So I've put
+ this code back in. pai/1997-07-21 */
+ /* Note 2: To fix a defect, we stopped adding FPARAMS to local_symbols
+ in hpread_read_function_type(), so FPARAMS had to be handled
+ here. I changed the location to be the appropriate argument
+ kinds rather than LOC_LOCAL. pai/1997-08-08 */
+ /* Note 3: Well, the fix in Note 2 above broke argument printing
+ in traceback frames, and further it makes assumptions about the
+ order of the FPARAM entries from HP compilers (cc and aCC in particular
+ generate them in reverse orders -- fixing one breaks for the other).
+ So I've added code in hpread_read_function_type() to add fparams
+ to a param_symbols list for the current context level. These are
+ then merged into local_symbols when a function end is reached.
+ pai/1997-08-11 */
+
+ break; /* do nothing; handled in hpread_read_function_type() */
+
+#if 0 /* Old code */
+ if (dn_bufp->dfparam.regparam)
+ SYMBOL_CLASS (sym) = LOC_REGISTER;
+ else if (dn_bufp->dfparam.indirect)
+ SYMBOL_CLASS (sym) = LOC_REF_ARG;
+ else
+ SYMBOL_CLASS (sym) = LOC_ARG;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ if (dn_bufp->dfparam.copyparam)
+ {
+ SYMBOL_VALUE (sym) = dn_bufp->dfparam.location;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+ SYMBOL_VALUE (sym)
+ += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+ }
+ else
+ SYMBOL_VALUE (sym) = dn_bufp->dfparam.location;
+ SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dfparam.type, objfile);
+ add_symbol_to_list (sym, &fparam_symbols);
+ break;
+#endif
+
+ case DNTT_TYPE_SVAR:
+ /* Static variables. */
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+
+ /* Note: There is a case that arises with globals in shared
+ * libraries where we need to set the address to LOC_INDIRECT.
+ * This case is if you have a global "g" in one library, and
+ * it is referenced "extern <type> g;" in another library.
+ * If we're processing the symbols for the referencing library,
+ * we'll see a global "g", but in this case the address given
+ * in the symbol table contains a pointer to the real "g".
+ * We use the storage class LOC_INDIRECT to indicate this. RT
+ */
+ if (is_in_import_list (SYMBOL_NAME (sym), objfile))
+ SYMBOL_CLASS (sym) = LOC_INDIRECT;
+
+ SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location + data_offset;
+ SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dsvar.type, objfile);
+
+ if (dn_bufp->dsvar.global)
+ add_symbol_to_list (sym, &global_symbols);
+
+ else if (WITHIN_FUNCTION (objfile))
+ add_symbol_to_list (sym, &local_symbols);
+
+ else
+ add_symbol_to_list (sym, &file_symbols);
+
+ if (dn_bufp->dsvar.thread_specific)
+ {
+ /* Thread-local variable.
+ */
+ SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC;
+ SYMBOL_BASEREG (sym) = CR27_REGNUM;
+
+ if (objfile->flags & OBJF_SHARED)
+ {
+ /*
+ * This variable is not only thread local but
+ * in a shared library.
+ *
+ * Alas, the shared lib structures are private
+ * to "somsolib.c". But C lets us point to one.
+ */
+ struct so_list *so;
+
+ if (objfile->obj_private == NULL)
+ error ("Internal error in reading shared library information.");
+
+ so = ((obj_private_data_t *) (objfile->obj_private))->so_info;
+ if (so == NULL)
+ error ("Internal error in reading shared library information.");
+
+ /* Thread-locals in shared libraries do NOT have the
+ * standard offset ("data_offset"), so we re-calculate
+ * where to look for this variable, using a call-back
+ * to interpret the private shared-library data.
+ */
+ SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location +
+ so_lib_thread_start_addr (so);
+ }
+ }
+ break;
+
+ case DNTT_TYPE_DVAR:
+ /* Dynamic variables. */
+ if (dn_bufp->ddvar.regvar)
+ SYMBOL_CLASS (sym) = LOC_REGISTER;
+ else
+ SYMBOL_CLASS (sym) = LOC_LOCAL;
+
+ SYMBOL_VALUE (sym) = dn_bufp->ddvar.location;
+#ifdef HPREAD_ADJUST_STACK_ADDRESS
+ SYMBOL_VALUE (sym)
+ += HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
+#endif
+ SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->ddvar.type, objfile);
+ if (dn_bufp->ddvar.global)
+ add_symbol_to_list (sym, &global_symbols);
+ else if (WITHIN_FUNCTION (objfile))
+ add_symbol_to_list (sym, &local_symbols);
+ else
+ add_symbol_to_list (sym, &file_symbols);
+ break;
+
+ case DNTT_TYPE_CONST:
+ /* A constant (pascal?). */
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ SYMBOL_VALUE (sym) = dn_bufp->dconst.location;
+ SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dconst.type, objfile);
+ if (dn_bufp->dconst.global)
+ add_symbol_to_list (sym, &global_symbols);
+ else if (WITHIN_FUNCTION (objfile))
+ add_symbol_to_list (sym, &local_symbols);
+ else
+ add_symbol_to_list (sym, &file_symbols);
+ break;
+
+ case DNTT_TYPE_TYPEDEF:
+ /* A typedef. We do want to process these, since a name is
+ * added to the namespace for the typedef'ed name.
+ */
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
+ if (dn_bufp->dtype.global)
+ add_symbol_to_list (sym, &global_symbols);
+ else if (WITHIN_FUNCTION (objfile))
+ add_symbol_to_list (sym, &local_symbols);
+ else
+ add_symbol_to_list (sym, &file_symbols);
+ break;
+
+ case DNTT_TYPE_TAGDEF:
+ {
+ int global = dn_bufp->dtag.global;
+ /* Structure, union, enum, template, or class tag definition */
+ /* We do want to process these, since a name is
+ * added to the namespace for the tag name (and if C++ class,
+ * for the typename also).
+ */
+ SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+
+ /* The tag contains in its "type" field a pointer to the
+ * DNTT_TYPE_STRUCT, DNTT_TYPE_UNION, DNTT_TYPE_ENUM,
+ * DNTT_TYPE_CLASS or DNTT_TYPE_TEMPLATE
+ * record that actually defines the type.
+ */
+ SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
+ TYPE_NAME (sym->type) = SYMBOL_NAME (sym);
+ TYPE_TAG_NAME (sym->type) = SYMBOL_NAME (sym);
+ if (dn_bufp->dtag.global)
+ add_symbol_to_list (sym, &global_symbols);
+ else if (WITHIN_FUNCTION (objfile))
+ add_symbol_to_list (sym, &local_symbols);
+ else
+ add_symbol_to_list (sym, &file_symbols);
+
+ /* If this is a C++ class, then we additionally
+ * need to define a typedef for the
+ * class type. E.g., so that the name "c" becomes visible as
+ * a type name when the user says "class c { ... }".
+ * In order to figure this out, we need to chase down the "type"
+ * field to get to the DNTT_TYPE_CLASS record.
+ *
+ * We also add the typename for ENUM. Though this isn't
+ * strictly correct, it is necessary because of the debug info
+ * generated by the aCC compiler, in which we cannot
+ * distinguish between:
+ * enum e { ... };
+ * and
+ * typedef enum { ... } e;
+ * I.e., the compiler emits the same debug info for the above
+ * two cases, in both cases "e" appearing as a tagdef.
+ * Therefore go ahead and generate the typename so that
+ * "ptype e" will work in the above cases.
+ *
+ * We also add the typename for TEMPLATE, so as to allow "ptype t"
+ * when "t" is a template name.
+ */
+ if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
+ dn_bufp = hpread_get_lntt (dn_bufp->dtag.type.dnttp.index, objfile);
+ else
+ {
+ complain (&hpread_tagdef_complaint);
+ return;
+ }
+ if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS ||
+ dn_bufp->dblock.kind == DNTT_TYPE_ENUM ||
+ dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
+ {
+ struct symbol *newsym;
+
+ newsym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ memset (newsym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (newsym) = name;
+ SYMBOL_LANGUAGE (newsym) = language_auto;
+ SYMBOL_NAMESPACE (newsym) = VAR_NAMESPACE;
+ SYMBOL_LINE (newsym) = 0;
+ SYMBOL_VALUE (newsym) = 0;
+ SYMBOL_CLASS (newsym) = LOC_TYPEDEF;
+ SYMBOL_TYPE (newsym) = sym->type;
+ if (global)
+ add_symbol_to_list (newsym, &global_symbols);
+ else if (WITHIN_FUNCTION (objfile))
+ add_symbol_to_list (newsym, &local_symbols);
+ else
+ add_symbol_to_list (newsym, &file_symbols);
+ }
+ }
+ break;
+
+ case DNTT_TYPE_POINTER:
+ /* Declares a pointer type. Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_ENUM:
+ /* Declares an enum type. Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_MEMENUM:
+ /* Member of enum */
+ /* Ignored at this level, but hpread_read_enum_type() will take
+ * care of walking the list of enumeration members.
+ */
+ break;
+
+ case DNTT_TYPE_SET:
+ /* Declares a set type. Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_SUBRANGE:
+ /* Declares a subrange type. Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_ARRAY:
+ /* Declares an array type. Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_STRUCT:
+ case DNTT_TYPE_UNION:
+ /* Declares an struct/union type.
+ * Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_FIELD:
+ /* Structure/union/class field */
+ /* Ignored at this level, but hpread_read_struct_type() will take
+ * care of walking the list of structure/union/class members.
+ */
+ break;
+
+ /* DNTT_TYPE_VARIANT is not handled by GDB */
+
+ /* DNTT_TYPE_FILE is not handled by GDB */
+
+ case DNTT_TYPE_FUNCTYPE:
+ /* Function type */
+ /* Ignored at this level, handled within hpread_type_lookup() */
+ break;
+
+ case DNTT_TYPE_WITH:
+ /* This is emitted within methods to indicate "with <class>"
+ * scoping rules (i.e., indicate that the class data members
+ * are directly visible).
+ * However, since GDB already infers this by looking at the
+ * "this" argument, interpreting the DNTT_TYPE_WITH
+ * symbol record is unnecessary.
+ */
+ break;
+
+ case DNTT_TYPE_COMMON:
+ /* FORTRAN common. Not yet handled. */
+ complain (&hpread_unhandled_common_complaint);
+ break;
+
+ /* DNTT_TYPE_COBSTRUCT is not handled by GDB. */
+ /* DNTT_TYPE_XREF is not handled by GDB. */
+ /* DNTT_TYPE_SA is not handled by GDB. */
+ /* DNTT_TYPE_MACRO is not handled by GDB */
+
+ case DNTT_TYPE_BLOCKDATA:
+ /* Not sure what this is - part of FORTRAN support maybe?
+ * Anyway, not yet handled.
+ */
+ complain (&hpread_unhandled_blockdata_complaint);
+ break;
+
+ case DNTT_TYPE_CLASS_SCOPE:
+
+
+
+ /* The compiler brackets member functions with a CLASS_SCOPE/END
+ * pair of records, presumably to put them in a different scope
+ * from the module scope where they are normally defined.
+ * E.g., in the situation:
+ * void f() { ... }
+ * void c::f() { ...}
+ * The member function "c::f" will be bracketed by a CLASS_SCOPE/END.
+ * This causes "break f" at the module level to pick the
+ * the file-level function f(), not the member function
+ * (which needs to be referenced via "break c::f").
+ *
+ * Here we record the class name to generate the demangled names of
+ * member functions later.
+ *
+ * FIXME Not being used now for anything -- cplus_demangle seems
+ * enough for getting the class-qualified names of functions. We
+ * may need this for handling nested classes and types. */
+
+ /* pai: FIXME Not handling nested classes for now -- need to
+ * maintain a stack */
+
+ dn_temp = hpread_get_lntt (dn_bufp->dclass_scope.type.dnttp.index, objfile);
+ if (dn_temp->dblock.kind == DNTT_TYPE_TAGDEF)
+ class_scope_name = VT (objfile) + dn_temp->dtag.name;
+ else
+ class_scope_name = NULL;
+
+#if 0
+
+ /* Begin a new scope. */
+ SL_INDEX (objfile) = hpread_record_lines (current_subfile,
+ SL_INDEX (objfile),
+ dn_bufp->dclass_scope.address,
+ objfile, offset);
+ valu = hpread_get_location (dn_bufp->dclass_scope.address, objfile);
+ valu += offset; /* Relocate for dynamic loading */
+ desc = hpread_get_scope_start (dn_bufp->dclass_scope.address, objfile);
+ /* We use the scope start DNTT index as the nesting depth identifier! */
+ new = push_context (desc, valu);
+#endif
+ break;
+
+ case DNTT_TYPE_REFERENCE:
+ /* Declares a C++ reference type. Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_PTRMEM:
+ /* Declares a C++ pointer-to-data-member type. This does not
+ * need to be handled at this level; being a type description it
+ * is instead handled at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_PTRMEMFUNC:
+ /* Declares a C++ pointer-to-function-member type. This does not
+ * need to be handled at this level; being a type description it
+ * is instead handled at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_CLASS:
+ /* Declares a class type.
+ * Should not be necessary to do anything
+ * with the type at this level; these are processed
+ * at the hpread_type_lookup() level.
+ */
+ break;
+
+ case DNTT_TYPE_GENFIELD:
+ /* I believe this is used for class member functions */
+ /* Ignored at this level, but hpread_read_struct_type() will take
+ * care of walking the list of class members.
+ */
+ break;
+
+ case DNTT_TYPE_VFUNC:
+ /* Virtual function */
+ /* This does not have to be handled at this level; handled in
+ * the course of processing class symbols.
+ */
+ break;
+
+ case DNTT_TYPE_MEMACCESS:
+ /* DDE ignores this symbol table record.
+ * It has something to do with "modified access" to class members.
+ * I'll assume we can safely ignore it too.
+ */
+ break;
+
+ case DNTT_TYPE_INHERITANCE:
+ /* These don't have to be handled here, since they are handled
+ * within hpread_read_struct_type() in the process of constructing
+ * a class type.
+ */
+ break;
+
+ case DNTT_TYPE_FRIEND_CLASS:
+ case DNTT_TYPE_FRIEND_FUNC:
+ /* These can safely be ignored, as GDB doesn't need this
+ * info. DDE only uses it in "describe". We may later want
+ * to extend GDB's "ptype" to give this info, but for now
+ * it seems safe enough to ignore it.
+ */
+ break;
+
+ case DNTT_TYPE_MODIFIER:
+ /* Intended to supply "modified access" to a type */
+ /* From the way DDE handles this, it looks like it always
+ * modifies a type. Therefore it is safe to ignore it at this
+ * level, and handle it in hpread_type_lookup().
+ */
+ break;
+
+ case DNTT_TYPE_OBJECT_ID:
+ /* Just ignore this - that's all DDE does */
+ break;
+
+ case DNTT_TYPE_MEMFUNC:
+ /* Member function */
+ /* This does not have to be handled at this level; handled in
+ * the course of processing class symbols.
+ */
+ break;
+
+ case DNTT_TYPE_DOC_MEMFUNC:
+ /* Member function */
+ /* This does not have to be handled at this level; handled in
+ * the course of processing class symbols.
+ */
+ break;
+
+ case DNTT_TYPE_TEMPLATE:
+ /* Template - sort of the header for a template definition,
+ * which like a class, points to a member list and also points
+ * to a TEMPLATE_ARG list of type-arguments.
+ * We do not need to process TEMPLATE records at this level though.
+ */
+ break;
+
+ case DNTT_TYPE_TEMPLATE_ARG:
+ /* The TEMPLATE record points to an argument list of
+ * TEMPLATE_ARG records, each of which describes one
+ * of the type-arguments.
+ * We do not need to process TEMPLATE_ARG records at this level though.
+ */
+ break;
+
+ case DNTT_TYPE_FUNC_TEMPLATE:
+ /* This will get emitted for member functions of templates.
+ * But we don't need to process this record at this level though,
+ * we will process it in the course of processing a TEMPLATE
+ * record.
+ */
+ break;
+
+ case DNTT_TYPE_LINK:
+ /* The LINK record is used to link up templates with instantiations. */
+ /* It is not clear why this is needed, and furthermore aCC does
+ * not appear to generate this, so I think we can safely ignore it. - RT
+ */
+ break;
+
+ /* DNTT_TYPE_DYN_ARRAY_DESC is not handled by GDB */
+ /* DNTT_TYPE_DESC_SUBRANGE is not handled by GDB */
+ /* DNTT_TYPE_BEGIN_EXT is not handled by GDB */
+ /* DNTT_TYPE_INLN is not handled by GDB */
+ /* DNTT_TYPE_INLN_LIST is not handled by GDB */
+ /* DNTT_TYPE_ALIAS is not handled by GDB */
+
+ default:
+ break;
+ }
+}
+
+/* Get nesting depth for a DNTT entry.
+ * DN_BUFP points to a DNTT entry.
+ * OBJFILE is the object file.
+ * REPORT_NESTED is a flag; if 0, real nesting depth is
+ * reported, if it is 1, the function simply returns a
+ * non-zero value if the nesting depth is anything > 0.
+ *
+ * Return value is an integer. 0 => not a local type / name
+ * positive return => type or name is local to some
+ * block or function.
+ */
+
+
+/* elz: ATTENTION: FIXME: NOTE: WARNING!!!!
+ this function now returns 0 right away. It was taking too much time
+ at start up. Now, though, the local types are not handled correctly.
+ */
+
+
+static int
+hpread_get_scope_depth (union dnttentry *dn_bufp, struct objfile *objfile,
+ int report_nested)
+{
+ register int index;
+ register union dnttentry *dn_tmp;
+ register short depth = 0;
+/****************************/
+ return 0;
+/****************************/
+
+ index = (((char *) dn_bufp) - LNTT (objfile)) / (sizeof (struct dntt_type_block));
+
+ while (--index >= 0)
+ {
+ dn_tmp = hpread_get_lntt (index, objfile);
+ switch (dn_tmp->dblock.kind)
+ {
+ case DNTT_TYPE_MODULE:
+ return depth;
+ case DNTT_TYPE_END:
+ /* index is signed int; dnttp.index is 29-bit unsigned int! */
+ index = (int) dn_tmp->dend.beginscope.dnttp.index;
+ break;
+ case DNTT_TYPE_BEGIN:
+ case DNTT_TYPE_FUNCTION:
+ case DNTT_TYPE_DOC_FUNCTION:
+ case DNTT_TYPE_WITH:
+ case DNTT_TYPE_COMMON:
+ case DNTT_TYPE_CLASS_SCOPE:
+ depth++;
+ if (report_nested)
+ return 1;
+ break;
+ default:
+ break;
+ }
+ }
+ return depth;
+}
+
+/* Adjust the bitoffsets for all fields of an anonymous union of
+ type TYPE by negative BITS. This handles HP aCC's hideous habit
+ of giving members of anonymous unions bit offsets relative to the
+ enclosing structure instead of relative to the union itself. */
+
+static void
+hpread_adjust_bitoffsets (struct type *type, int bits)
+{
+ register int i;
+
+ /* This is done only for unions; caller had better check that
+ it is an anonymous one. */
+ if (TYPE_CODE (type) != TYPE_CODE_UNION)
+ return;
+
+ /* Adjust each field; since this is a union, there are no base
+ classes. Also no static membes. Also, no need for recursion as
+ the members of this union if themeselves structs or unions, have
+ the correct bitoffsets; if an anonymous union is a member of this
+ anonymous union, the code in hpread_read_struct_type() will
+ adjust for that. */
+
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
+ TYPE_FIELD_BITPOS (type, i) -= bits;
+}
+
+/* Because of quirks in HP compilers' treatment of anonymous unions inside
+ classes, we have to chase through a chain of threaded FIELD entries.
+ If we encounter an anonymous union in the chain, we must recursively skip over
+ that too.
+
+ This function does a "next" in the chain of FIELD entries, but transparently
+ skips over anonymous unions' fields (recursively).
+
+ Inputs are the number of times to do "next" at the top level, the dnttpointer
+ (FIELD) and entry pointer (FIELDP) for the dntt record corresponding to it,
+ and the ubiquitous objfile parameter. (Note: FIELDP is a **.) Return value
+ is a dnttpointer for the new field after all the skipped ones */
+
+static dnttpointer
+hpread_get_next_skip_over_anon_unions (int skip_fields, dnttpointer field,
+ union dnttentry **fieldp,
+ struct objfile *objfile)
+{
+ struct type *anon_type;
+ register int i;
+ int bitoffset;
+ char *name;
+
+ for (i = 0; i < skip_fields; i++)
+ {
+ /* Get type of item we're looking at now; recursively processes the types
+ of these intermediate items we skip over, so they aren't lost. */
+ anon_type = hpread_type_lookup ((*fieldp)->dfield.type, objfile);
+ anon_type = CHECK_TYPEDEF (anon_type);
+ bitoffset = (*fieldp)->dfield.bitoffset;
+ name = VT (objfile) + (*fieldp)->dfield.name;
+ /* First skip over one item to avoid stack death on recursion */
+ field = (*fieldp)->dfield.nextfield;
+ *fieldp = hpread_get_lntt (field.dnttp.index, objfile);
+ /* Do we have another anonymous union? If so, adjust the bitoffsets
+ of its members and skip over its members. */
+ if ((TYPE_CODE (anon_type) == TYPE_CODE_UNION) &&
+ (!name || STREQ (name, "")))
+ {
+ hpread_adjust_bitoffsets (anon_type, bitoffset);
+ field = hpread_get_next_skip_over_anon_unions (TYPE_NFIELDS (anon_type), field, fieldp, objfile);
+ }
+ }
+ return field;
+}
diff --git a/gdb/hpux-thread.c b/gdb/hpux-thread.c
new file mode 100644
index 00000000000..eec18ffffa5
--- /dev/null
+++ b/gdb/hpux-thread.c
@@ -0,0 +1,585 @@
+/* Low level interface for debugging HPUX/DCE threads for GDB, the GNU debugger.
+ Copyright 1996, 1998, 1999, 2000, 2001 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. */
+
+/* This module implements a sort of half target that sits between the
+ machine-independent parts of GDB and the ptrace interface (infptrace.c) to
+ provide access to the HPUX user-mode thread implementation.
+
+ HPUX threads are true user-mode threads, which are invoked via the cma_*
+ and pthread_* (DCE and Posix respectivly) interfaces. These are mostly
+ implemented in user-space, with all thread context kept in various
+ structures that live in the user's heap. For the most part, the kernel has
+ no knowlege of these threads.
+
+ */
+
+#include "defs.h"
+
+#define _CMA_NOWRAPPERS_
+
+#include <cma_tcb_defs.h>
+#include <cma_deb_core.h>
+#include "gdbthread.h"
+#include "target.h"
+#include "inferior.h"
+#include "regcache.h"
+#include <fcntl.h>
+#include <sys/stat.h>
+#include "gdbcore.h"
+
+extern int child_suppress_run;
+extern struct target_ops child_ops; /* target vector for inftarg.c */
+
+extern void _initialize_hpux_thread (void);
+
+struct string_map
+ {
+ int num;
+ char *str;
+ };
+
+static int hpux_thread_active = 0;
+
+static ptid_t main_ptid; /* Real process ID */
+
+static CORE_ADDR P_cma__g_known_threads;
+static CORE_ADDR P_cma__g_current_thread;
+
+static void hpux_thread_resume (ptid_t ptid, int step,
+ enum target_signal signo);
+
+static void init_hpux_thread_ops (void);
+
+static struct target_ops hpux_thread_ops;
+
+static ptid_t find_active_thread (void);
+
+static int cached_thread;
+static cma__t_int_tcb cached_tcb;
+
+static ptid_t
+find_active_thread (void)
+{
+ static cma__t_int_tcb tcb;
+ CORE_ADDR tcb_ptr;
+
+ read_memory ((CORE_ADDR) P_cma__g_current_thread,
+ (char *) &tcb_ptr,
+ sizeof tcb_ptr);
+
+ read_memory (tcb_ptr, (char *) &tcb, sizeof tcb);
+
+ return (ptid_build (PIDGET (main_ptid), 0,
+ cma_thread_get_unique (&tcb.prolog.client_thread)));
+}
+
+static cma__t_int_tcb *find_tcb (ptid_t ptid);
+
+static cma__t_int_tcb *
+find_tcb (ptid_t ptid)
+{
+ cma__t_known_object queue_header;
+ cma__t_queue *queue_ptr;
+ int thread = ptid_get_tid (ptid);
+
+ if (thread == cached_thread)
+ return &cached_tcb;
+
+ read_memory ((CORE_ADDR) P_cma__g_known_threads,
+ (char *) &queue_header,
+ sizeof queue_header);
+
+ for (queue_ptr = queue_header.queue.flink;
+ queue_ptr != (cma__t_queue *) P_cma__g_known_threads;
+ queue_ptr = cached_tcb.threads.flink)
+ {
+ cma__t_int_tcb *tcb_ptr;
+
+ tcb_ptr = cma__base (queue_ptr, threads, cma__t_int_tcb);
+
+ read_memory ((CORE_ADDR) tcb_ptr, (char *) &cached_tcb, sizeof cached_tcb);
+
+ if (cached_tcb.header.type == cma__c_obj_tcb)
+ if (cma_thread_get_unique (&cached_tcb.prolog.client_thread) == thread)
+ {
+ cached_thread = thread;
+ return &cached_tcb;
+ }
+ }
+
+ error ("Can't find TCB %d", thread);
+ return NULL;
+}
+
+/* Most target vector functions from here on actually just pass through to
+ inftarg.c, as they don't need to do anything specific for threads. */
+
+/* ARGSUSED */
+static void
+hpux_thread_open (char *arg, int from_tty)
+{
+ child_ops.to_open (arg, from_tty);
+}
+
+/* Attach to process PID, then initialize for debugging it
+ and wait for the trace-trap that results from attaching. */
+
+static void
+hpux_thread_attach (char *args, int from_tty)
+{
+ child_ops.to_attach (args, from_tty);
+
+ /* XXX - might want to iterate over all the threads and register them. */
+}
+
+/* Take a program previously attached to and detaches it.
+ The program resumes execution and will no longer stop
+ on signals, etc. We'd better not have left any breakpoints
+ in the program or it'll die when it hits one. For this
+ to work, it may be necessary for the process to have been
+ previously attached. It *might* work if the program was
+ started via the normal ptrace (PTRACE_TRACEME). */
+
+static void
+hpux_thread_detach (char *args, int from_tty)
+{
+ child_ops.to_detach (args, from_tty);
+}
+
+/* Resume execution of process PID. If STEP is nozero, then
+ just single step it. If SIGNAL is nonzero, restart it with that
+ signal activated. We may have to convert pid from a thread-id to an LWP id
+ for procfs. */
+
+static void
+hpux_thread_resume (ptid_t ptid, int step, enum target_signal signo)
+{
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_ptid ();
+
+ ptid = main_ptid;
+ inferior_ptid = main_ptid;
+
+#if 0
+ if (pid != -1)
+ {
+ pid = thread_to_lwp (pid, -2);
+ if (pid == -2) /* Inactive thread */
+ error ("This version of Solaris can't start inactive threads.");
+ }
+#endif
+
+ child_ops.to_resume (ptid, step, signo);
+
+ cached_thread = 0;
+
+ do_cleanups (old_chain);
+}
+
+/* Wait for any threads to stop. We may have to convert PID from a thread id
+ to a LWP id, and vice versa on the way out. */
+
+static ptid_t
+hpux_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+{
+ ptid_t rtnval;
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_ptid ();
+
+ inferior_ptid = main_ptid;
+
+ if (!ptid_equal (ptid, minus_one_ptid))
+ ptid = main_ptid;
+
+ rtnval = child_ops.to_wait (ptid, ourstatus);
+
+ rtnval = find_active_thread ();
+
+ do_cleanups (old_chain);
+
+ return rtnval;
+}
+
+static char regmap[NUM_REGS] =
+{
+ -2, -1, -1, 0, 4, 8, 12, 16, 20, 24, /* flags, r1 -> r9 */
+ 28, 32, 36, 40, 44, 48, 52, 56, 60, -1, /* r10 -> r19 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* r20 -> r29 */
+
+ /* r30, r31, sar, pcoqh, pcsqh, pcoqt, pcsqt, eiem, iir, isr */
+ -2, -1, -1, -2, -1, -1, -1, -1, -1, -1,
+
+ /* ior, ipsw, goto, sr4, sr0, sr1, sr2, sr3, sr5, sr6 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+ /* sr7, cr0, cr8, cr9, ccr, cr12, cr13, cr24, cr25, cr26 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+ -1, -1, -1, -1, /* mpsfu_high, mpsfu_low, mpsfu_ovflo, pad */
+ 144, -1, -1, -1, -1, -1, -1, -1, /* fpsr, fpe1 -> fpe7 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* fr4 -> fr7 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* fr8 -> fr11 */
+ 136, -1, 128, -1, 120, -1, 112, -1, /* fr12 -> fr15 */
+ 104, -1, 96, -1, 88, -1, 80, -1, /* fr16 -> fr19 */
+ 72, -1, 64, -1, -1, -1, -1, -1, /* fr20 -> fr23 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* fr24 -> fr27 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* fr28 -> fr31 */
+};
+
+static void
+hpux_thread_fetch_registers (int regno)
+{
+ cma__t_int_tcb tcb, *tcb_ptr;
+ struct cleanup *old_chain;
+ int i;
+ int first_regno, last_regno;
+
+ tcb_ptr = find_tcb (inferior_ptid);
+
+ old_chain = save_inferior_ptid ();
+
+ inferior_ptid = main_ptid;
+
+ if (tcb_ptr->state == cma__c_state_running)
+ {
+ child_ops.to_fetch_registers (regno);
+
+ do_cleanups (old_chain);
+
+ return;
+ }
+
+ if (regno == -1)
+ {
+ first_regno = 0;
+ last_regno = NUM_REGS - 1;
+ }
+ else
+ {
+ first_regno = regno;
+ last_regno = regno;
+ }
+
+ for (regno = first_regno; regno <= last_regno; regno++)
+ {
+ if (regmap[regno] == -1)
+ child_ops.to_fetch_registers (regno);
+ else
+ {
+ unsigned char buf[MAX_REGISTER_RAW_SIZE];
+ CORE_ADDR sp;
+
+ sp = (CORE_ADDR) tcb_ptr->static_ctx.sp - 160;
+
+ if (regno == FLAGS_REGNUM)
+ /* Flags must be 0 to avoid bogus value for SS_INSYSCALL */
+ memset (buf, '\000', REGISTER_RAW_SIZE (regno));
+ else if (regno == SP_REGNUM)
+ store_address (buf, sizeof sp, sp);
+ else if (regno == PC_REGNUM)
+ read_memory (sp - 20, buf, REGISTER_RAW_SIZE (regno));
+ else
+ read_memory (sp + regmap[regno], buf, REGISTER_RAW_SIZE (regno));
+
+ supply_register (regno, buf);
+ }
+ }
+
+ do_cleanups (old_chain);
+}
+
+static void
+hpux_thread_store_registers (int regno)
+{
+ cma__t_int_tcb tcb, *tcb_ptr;
+ struct cleanup *old_chain;
+ int i;
+ int first_regno, last_regno;
+
+ tcb_ptr = find_tcb (inferior_ptid);
+
+ old_chain = save_inferior_ptid ();
+
+ inferior_ptid = main_ptid;
+
+ if (tcb_ptr->state == cma__c_state_running)
+ {
+ child_ops.to_store_registers (regno);
+
+ do_cleanups (old_chain);
+
+ return;
+ }
+
+ if (regno == -1)
+ {
+ first_regno = 0;
+ last_regno = NUM_REGS - 1;
+ }
+ else
+ {
+ first_regno = regno;
+ last_regno = regno;
+ }
+
+ for (regno = first_regno; regno <= last_regno; regno++)
+ {
+ if (regmap[regno] == -1)
+ child_ops.to_store_registers (regno);
+ else
+ {
+ unsigned char buf[MAX_REGISTER_RAW_SIZE];
+ CORE_ADDR sp;
+
+ sp = (CORE_ADDR) tcb_ptr->static_ctx.sp - 160;
+
+ if (regno == FLAGS_REGNUM)
+ child_ops.to_store_registers (regno); /* Let lower layer handle this... */
+ else if (regno == SP_REGNUM)
+ {
+ write_memory ((CORE_ADDR) & tcb_ptr->static_ctx.sp,
+ registers + REGISTER_BYTE (regno),
+ REGISTER_RAW_SIZE (regno));
+ tcb_ptr->static_ctx.sp = (cma__t_hppa_regs *)
+ (extract_address (registers + REGISTER_BYTE (regno), REGISTER_RAW_SIZE (regno)) + 160);
+ }
+ else if (regno == PC_REGNUM)
+ write_memory (sp - 20,
+ registers + REGISTER_BYTE (regno),
+ REGISTER_RAW_SIZE (regno));
+ else
+ write_memory (sp + regmap[regno],
+ registers + REGISTER_BYTE (regno),
+ REGISTER_RAW_SIZE (regno));
+ }
+ }
+
+ do_cleanups (old_chain);
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+static void
+hpux_thread_prepare_to_store (void)
+{
+ child_ops.to_prepare_to_store ();
+}
+
+static int
+hpux_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int dowrite, struct mem_attrib *attribs,
+ struct target_ops *target)
+{
+ int retval;
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_ptid ();
+
+ inferior_ptid = main_ptid;
+
+ retval =
+ child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, attribs, target);
+
+ do_cleanups (old_chain);
+
+ return retval;
+}
+
+/* Print status information about what we're accessing. */
+
+static void
+hpux_thread_files_info (struct target_ops *ignore)
+{
+ child_ops.to_files_info (ignore);
+}
+
+static void
+hpux_thread_kill_inferior (void)
+{
+ child_ops.to_kill ();
+}
+
+static void
+hpux_thread_notice_signals (ptid_t ptid)
+{
+ child_ops.to_notice_signals (ptid);
+}
+
+/* Fork an inferior process, and start debugging it with /proc. */
+
+static void
+hpux_thread_create_inferior (char *exec_file, char *allargs, char **env)
+{
+ child_ops.to_create_inferior (exec_file, allargs, env);
+
+ if (hpux_thread_active)
+ {
+ main_ptid = inferior_ptid;
+
+ push_target (&hpux_thread_ops);
+
+ inferior_ptid = find_active_thread ();
+
+ add_thread (inferior_ptid);
+ }
+}
+
+/* This routine is called whenever a new symbol table is read in, or when all
+ symbol tables are removed. libthread_db can only be initialized when it
+ finds the right variables in libthread.so. Since it's a shared library,
+ those variables don't show up until the library gets mapped and the symbol
+ table is read in. */
+
+/* This new_objfile event is now managed by a chained function pointer.
+ * It is the callee's responsability to call the next client on the chain.
+ */
+
+/* Saved pointer to previous owner of the new_objfile event. */
+static void (*target_new_objfile_chain) (struct objfile *);
+
+void
+hpux_thread_new_objfile (struct objfile *objfile)
+{
+ struct minimal_symbol *ms;
+
+ if (!objfile)
+ {
+ hpux_thread_active = 0;
+ goto quit;
+ }
+
+ ms = lookup_minimal_symbol ("cma__g_known_threads", NULL, objfile);
+
+ if (!ms)
+ goto quit;
+
+ P_cma__g_known_threads = SYMBOL_VALUE_ADDRESS (ms);
+
+ ms = lookup_minimal_symbol ("cma__g_current_thread", NULL, objfile);
+
+ if (!ms)
+ goto quit;
+
+ P_cma__g_current_thread = SYMBOL_VALUE_ADDRESS (ms);
+
+ hpux_thread_active = 1;
+quit:
+ /* Call predecessor on chain, if any. */
+ if (target_new_objfile_chain)
+ target_new_objfile_chain (objfile);
+}
+
+/* Clean up after the inferior dies. */
+
+static void
+hpux_thread_mourn_inferior (void)
+{
+ child_ops.to_mourn_inferior ();
+}
+
+/* Mark our target-struct as eligible for stray "run" and "attach" commands. */
+
+static int
+hpux_thread_can_run (void)
+{
+ return child_suppress_run;
+}
+
+static int
+hpux_thread_alive (ptid_t ptid)
+{
+ return 1;
+}
+
+static void
+hpux_thread_stop (void)
+{
+ child_ops.to_stop ();
+}
+
+/* Convert a pid to printable form. */
+
+char *
+hpux_pid_to_str (ptid_t ptid)
+{
+ static char buf[100];
+ int pid = PIDGET (ptid);
+
+ sprintf (buf, "Thread %ld", ptid_get_tid (ptid));
+
+ return buf;
+}
+
+static void
+init_hpux_thread_ops (void)
+{
+ hpux_thread_ops.to_shortname = "hpux-threads";
+ hpux_thread_ops.to_longname = "HPUX threads and pthread.";
+ hpux_thread_ops.to_doc = "HPUX threads and pthread support.";
+ hpux_thread_ops.to_open = hpux_thread_open;
+ hpux_thread_ops.to_attach = hpux_thread_attach;
+ hpux_thread_ops.to_detach = hpux_thread_detach;
+ hpux_thread_ops.to_resume = hpux_thread_resume;
+ hpux_thread_ops.to_wait = hpux_thread_wait;
+ hpux_thread_ops.to_fetch_registers = hpux_thread_fetch_registers;
+ hpux_thread_ops.to_store_registers = hpux_thread_store_registers;
+ hpux_thread_ops.to_prepare_to_store = hpux_thread_prepare_to_store;
+ hpux_thread_ops.to_xfer_memory = hpux_thread_xfer_memory;
+ hpux_thread_ops.to_files_info = hpux_thread_files_info;
+ hpux_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ hpux_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ hpux_thread_ops.to_terminal_init = terminal_init_inferior;
+ hpux_thread_ops.to_terminal_inferior = terminal_inferior;
+ hpux_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ hpux_thread_ops.to_terminal_ours = terminal_ours;
+ hpux_thread_ops.to_terminal_info = child_terminal_info;
+ hpux_thread_ops.to_kill = hpux_thread_kill_inferior;
+ hpux_thread_ops.to_create_inferior = hpux_thread_create_inferior;
+ hpux_thread_ops.to_mourn_inferior = hpux_thread_mourn_inferior;
+ hpux_thread_ops.to_can_run = hpux_thread_can_run;
+ hpux_thread_ops.to_notice_signals = hpux_thread_notice_signals;
+ hpux_thread_ops.to_thread_alive = hpux_thread_alive;
+ hpux_thread_ops.to_stop = hpux_thread_stop;
+ hpux_thread_ops.to_stratum = process_stratum;
+ hpux_thread_ops.to_has_all_memory = 1;
+ hpux_thread_ops.to_has_memory = 1;
+ hpux_thread_ops.to_has_stack = 1;
+ hpux_thread_ops.to_has_registers = 1;
+ hpux_thread_ops.to_has_execution = 1;
+ hpux_thread_ops.to_magic = OPS_MAGIC;
+}
+
+void
+_initialize_hpux_thread (void)
+{
+ init_hpux_thread_ops ();
+ add_target (&hpux_thread_ops);
+
+ child_suppress_run = 1;
+ /* Hook into new_objfile notification. */
+ target_new_objfile_chain = target_new_objfile_hook;
+ target_new_objfile_hook = hpux_thread_new_objfile;
+}
diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
new file mode 100644
index 00000000000..e20e894113e
--- /dev/null
+++ b/gdb/i386-linux-nat.c
@@ -0,0 +1,955 @@
+/* Native-dependent code for GNU/Linux x86.
+
+ Copyright 1999, 2000, 2001, 2002 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 "defs.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#include "gdb_assert.h"
+#include <sys/ptrace.h>
+#include <sys/user.h>
+#include <sys/procfs.h>
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+#ifdef HAVE_SYS_DEBUGREG_H
+#include <sys/debugreg.h>
+#endif
+
+#ifndef DR_FIRSTADDR
+#define DR_FIRSTADDR 0
+#endif
+
+#ifndef DR_LASTADDR
+#define DR_LASTADDR 3
+#endif
+
+#ifndef DR_STATUS
+#define DR_STATUS 6
+#endif
+
+#ifndef DR_CONTROL
+#define DR_CONTROL 7
+#endif
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* Prototypes for i387_supply_fsave etc. */
+#include "i387-tdep.h"
+
+/* Defines for XMM0_REGNUM etc. */
+#include "i386-tdep.h"
+
+/* Prototypes for local functions. */
+static void dummy_sse_values (void);
+
+
+
+/* The register sets used in GNU/Linux ELF core-dumps are identical to
+ the register sets in `struct user' that is used for a.out
+ core-dumps, and is also used by `ptrace'. The corresponding types
+ are `elf_gregset_t' for the general-purpose registers (with
+ `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
+ for the floating-point registers.
+
+ Those types used to be available under the names `gregset_t' and
+ `fpregset_t' too, and this file used those names in the past. But
+ those names are now used for the register sets used in the
+ `mcontext_t' type, and have a different size and layout. */
+
+/* Mapping between the general-purpose registers in `struct user'
+ format and GDB's register array layout. */
+static int regmap[] =
+{
+ EAX, ECX, EDX, EBX,
+ UESP, EBP, ESI, EDI,
+ EIP, EFL, CS, SS,
+ DS, ES, FS, GS
+};
+
+/* Which ptrace request retrieves which registers?
+ These apply to the corresponding SET requests as well. */
+#define GETREGS_SUPPLIES(regno) \
+ ((0 <= (regno) && (regno) <= 15) || (regno) == I386_LINUX_ORIG_EAX_REGNUM)
+#define GETFPREGS_SUPPLIES(regno) \
+ (FP0_REGNUM <= (regno) && (regno) <= LAST_FPU_CTRL_REGNUM)
+#define GETFPXREGS_SUPPLIES(regno) \
+ (FP0_REGNUM <= (regno) && (regno) <= MXCSR_REGNUM)
+
+/* Does the current host support the GETREGS request? */
+int have_ptrace_getregs =
+#ifdef HAVE_PTRACE_GETREGS
+ 1
+#else
+ 0
+#endif
+;
+
+/* Does the current host support the GETFPXREGS request? The header
+ file may or may not define it, and even if it is defined, the
+ kernel will return EIO if it's running on a pre-SSE processor.
+
+ My instinct is to attach this to some architecture- or
+ target-specific data structure, but really, a particular GDB
+ process can only run on top of one kernel at a time. So it's okay
+ for this to be a simple variable. */
+int have_ptrace_getfpxregs =
+#ifdef HAVE_PTRACE_GETFPXREGS
+ 1
+#else
+ 0
+#endif
+;
+
+
+/* Support for the user struct. */
+
+/* Return the address of register REGNUM. BLOCKEND is the value of
+ u.u_ar0, which should point to the registers. */
+
+CORE_ADDR
+register_u_addr (CORE_ADDR blockend, int regnum)
+{
+ return (blockend + 4 * regmap[regnum]);
+}
+
+/* Return the size of the user struct. */
+
+int
+kernel_u_size (void)
+{
+ return (sizeof (struct user));
+}
+
+
+/* Fetching registers directly from the U area, one at a time. */
+
+/* FIXME: kettenis/2000-03-05: This duplicates code from `inptrace.c'.
+ The problem is that we define FETCH_INFERIOR_REGISTERS since we
+ want to use our own versions of {fetch,store}_inferior_registers
+ that use the GETREGS request. This means that the code in
+ `infptrace.c' is #ifdef'd out. But we need to fall back on that
+ code when GDB is running on top of a kernel that doesn't support
+ the GETREGS request. I want to avoid changing `infptrace.c' right
+ now. */
+
+#ifndef PT_READ_U
+#define PT_READ_U PTRACE_PEEKUSR
+#endif
+#ifndef PT_WRITE_U
+#define PT_WRITE_U PTRACE_POKEUSR
+#endif
+
+/* Default the type of the ptrace transfer to int. */
+#ifndef PTRACE_XFER_TYPE
+#define PTRACE_XFER_TYPE int
+#endif
+
+/* Registers we shouldn't try to fetch. */
+#define OLD_CANNOT_FETCH_REGISTER(regno) ((regno) >= NUM_GREGS)
+
+/* Fetch one register. */
+
+static void
+fetch_register (int regno)
+{
+ /* This isn't really an address. But ptrace thinks of it as one. */
+ CORE_ADDR regaddr;
+ char mess[128]; /* For messages */
+ register int i;
+ unsigned int offset; /* Offset of registers within the u area. */
+ char buf[MAX_REGISTER_RAW_SIZE];
+ int tid;
+
+ if (OLD_CANNOT_FETCH_REGISTER (regno))
+ {
+ memset (buf, '\0', REGISTER_RAW_SIZE (regno)); /* Supply zeroes */
+ supply_register (regno, buf);
+ return;
+ }
+
+ /* Overload thread id onto process id */
+ if ((tid = TIDGET (inferior_ptid)) == 0)
+ tid = PIDGET (inferior_ptid); /* no thread id, just use process id */
+
+ offset = U_REGS_OFFSET;
+
+ regaddr = register_addr (regno, offset);
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ *(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid,
+ (PTRACE_ARG3_TYPE) regaddr, 0);
+ regaddr += sizeof (PTRACE_XFER_TYPE);
+ if (errno != 0)
+ {
+ sprintf (mess, "reading register %s (#%d)",
+ REGISTER_NAME (regno), regno);
+ perror_with_name (mess);
+ }
+ }
+ supply_register (regno, buf);
+}
+
+/* Fetch register values from the inferior.
+ If REGNO is negative, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+old_fetch_inferior_registers (int regno)
+{
+ if (regno >= 0)
+ {
+ fetch_register (regno);
+ }
+ else
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ {
+ fetch_register (regno);
+ }
+ }
+}
+
+/* Registers we shouldn't try to store. */
+#define OLD_CANNOT_STORE_REGISTER(regno) ((regno) >= NUM_GREGS)
+
+/* Store one register. */
+
+static void
+store_register (int regno)
+{
+ /* This isn't really an address. But ptrace thinks of it as one. */
+ CORE_ADDR regaddr;
+ char mess[128]; /* For messages */
+ register int i;
+ unsigned int offset; /* Offset of registers within the u area. */
+ int tid;
+
+ if (OLD_CANNOT_STORE_REGISTER (regno))
+ {
+ return;
+ }
+
+ /* Overload thread id onto process id */
+ if ((tid = TIDGET (inferior_ptid)) == 0)
+ tid = PIDGET (inferior_ptid); /* no thread id, just use process id */
+
+ offset = U_REGS_OFFSET;
+
+ regaddr = register_addr (regno, offset);
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,
+ *(PTRACE_XFER_TYPE *) & registers[REGISTER_BYTE (regno) + i]);
+ regaddr += sizeof (PTRACE_XFER_TYPE);
+ if (errno != 0)
+ {
+ sprintf (mess, "writing register %s (#%d)",
+ REGISTER_NAME (regno), regno);
+ perror_with_name (mess);
+ }
+ }
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is negative, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+old_store_inferior_registers (int regno)
+{
+ if (regno >= 0)
+ {
+ store_register (regno);
+ }
+ else
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ {
+ store_register (regno);
+ }
+ }
+}
+
+
+/* Transfering the general-purpose registers between GDB, inferiors
+ and core files. */
+
+/* Fill GDB's register array with the general-purpose register values
+ in *GREGSETP. */
+
+void
+supply_gregset (elf_gregset_t *gregsetp)
+{
+ elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ int i;
+
+ for (i = 0; i < NUM_GREGS; i++)
+ supply_register (i, (char *) (regp + regmap[i]));
+
+ supply_register (I386_LINUX_ORIG_EAX_REGNUM, (char *) (regp + ORIG_EAX));
+}
+
+/* Fill register REGNO (if it is a general-purpose register) in
+ *GREGSETPS with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+
+void
+fill_gregset (elf_gregset_t *gregsetp, int regno)
+{
+ elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ int i;
+
+ for (i = 0; i < NUM_GREGS; i++)
+ if ((regno == -1 || regno == i))
+ regcache_collect (i, regp + regmap[i]);
+
+ if (regno == -1 || regno == I386_LINUX_ORIG_EAX_REGNUM)
+ regcache_collect (I386_LINUX_ORIG_EAX_REGNUM, regp + ORIG_EAX);
+}
+
+#ifdef HAVE_PTRACE_GETREGS
+
+/* Fetch all general-purpose registers from process/thread TID and
+ store their values in GDB's register array. */
+
+static void
+fetch_regs (int tid)
+{
+ elf_gregset_t regs;
+
+ if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
+ {
+ if (errno == EIO)
+ {
+ /* The kernel we're running on doesn't support the GETREGS
+ request. Reset `have_ptrace_getregs'. */
+ have_ptrace_getregs = 0;
+ return;
+ }
+
+ perror_with_name ("Couldn't get registers");
+ }
+
+ supply_gregset (&regs);
+}
+
+/* Store all valid general-purpose registers in GDB's register array
+ into the process/thread specified by TID. */
+
+static void
+store_regs (int tid, int regno)
+{
+ elf_gregset_t regs;
+
+ if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
+ perror_with_name ("Couldn't get registers");
+
+ fill_gregset (&regs, regno);
+
+ if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
+ perror_with_name ("Couldn't write registers");
+}
+
+#else
+
+static void fetch_regs (int tid) {}
+static void store_regs (int tid, int regno) {}
+
+#endif
+
+
+/* Transfering floating-point registers between GDB, inferiors and cores. */
+
+/* Fill GDB's register array with the floating-point register values in
+ *FPREGSETP. */
+
+void
+supply_fpregset (elf_fpregset_t *fpregsetp)
+{
+ i387_supply_fsave ((char *) fpregsetp);
+ dummy_sse_values ();
+}
+
+/* Fill register REGNO (if it is a floating-point register) in
+ *FPREGSETP with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+
+void
+fill_fpregset (elf_fpregset_t *fpregsetp, int regno)
+{
+ i387_fill_fsave ((char *) fpregsetp, regno);
+}
+
+#ifdef HAVE_PTRACE_GETREGS
+
+/* Fetch all floating-point registers from process/thread TID and store
+ thier values in GDB's register array. */
+
+static void
+fetch_fpregs (int tid)
+{
+ elf_fpregset_t fpregs;
+
+ if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
+ perror_with_name ("Couldn't get floating point status");
+
+ supply_fpregset (&fpregs);
+}
+
+/* Store all valid floating-point registers in GDB's register array
+ into the process/thread specified by TID. */
+
+static void
+store_fpregs (int tid, int regno)
+{
+ elf_fpregset_t fpregs;
+
+ if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
+ perror_with_name ("Couldn't get floating point status");
+
+ fill_fpregset (&fpregs, regno);
+
+ if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
+ perror_with_name ("Couldn't write floating point status");
+}
+
+#else
+
+static void fetch_fpregs (int tid) {}
+static void store_fpregs (int tid, int regno) {}
+
+#endif
+
+
+/* Transfering floating-point and SSE registers to and from GDB. */
+
+#ifdef HAVE_PTRACE_GETFPXREGS
+
+/* Fill GDB's register array with the floating-point and SSE register
+ values in *FPXREGSETP. */
+
+void
+supply_fpxregset (elf_fpxregset_t *fpxregsetp)
+{
+ i387_supply_fxsave ((char *) fpxregsetp);
+}
+
+/* Fill register REGNO (if it is a floating-point or SSE register) in
+ *FPXREGSETP with the value in GDB's register array. If REGNO is
+ -1, do this for all registers. */
+
+void
+fill_fpxregset (elf_fpxregset_t *fpxregsetp, int regno)
+{
+ i387_fill_fxsave ((char *) fpxregsetp, regno);
+}
+
+/* Fetch all registers covered by the PTRACE_GETFPXREGS request from
+ process/thread TID and store their values in GDB's register array.
+ Return non-zero if successful, zero otherwise. */
+
+static int
+fetch_fpxregs (int tid)
+{
+ elf_fpxregset_t fpxregs;
+
+ if (! have_ptrace_getfpxregs)
+ return 0;
+
+ if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0)
+ {
+ if (errno == EIO)
+ {
+ have_ptrace_getfpxregs = 0;
+ return 0;
+ }
+
+ perror_with_name ("Couldn't read floating-point and SSE registers");
+ }
+
+ supply_fpxregset (&fpxregs);
+ return 1;
+}
+
+/* Store all valid registers in GDB's register array covered by the
+ PTRACE_SETFPXREGS request into the process/thread specified by TID.
+ Return non-zero if successful, zero otherwise. */
+
+static int
+store_fpxregs (int tid, int regno)
+{
+ elf_fpxregset_t fpxregs;
+
+ if (! have_ptrace_getfpxregs)
+ return 0;
+
+ if (ptrace (PTRACE_GETFPXREGS, tid, 0, &fpxregs) == -1)
+ {
+ if (errno == EIO)
+ {
+ have_ptrace_getfpxregs = 0;
+ return 0;
+ }
+
+ perror_with_name ("Couldn't read floating-point and SSE registers");
+ }
+
+ fill_fpxregset (&fpxregs, regno);
+
+ if (ptrace (PTRACE_SETFPXREGS, tid, 0, &fpxregs) == -1)
+ perror_with_name ("Couldn't write floating-point and SSE registers");
+
+ return 1;
+}
+
+/* Fill the XMM registers in the register array with dummy values. For
+ cases where we don't have access to the XMM registers. I think
+ this is cleaner than printing a warning. For a cleaner solution,
+ we should gdbarchify the i386 family. */
+
+static void
+dummy_sse_values (void)
+{
+ /* C doesn't have a syntax for NaN's, so write it out as an array of
+ longs. */
+ static long dummy[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff };
+ static long mxcsr = 0x1f80;
+ int reg;
+
+ for (reg = 0; reg < 8; reg++)
+ supply_register (XMM0_REGNUM + reg, (char *) dummy);
+ supply_register (MXCSR_REGNUM, (char *) &mxcsr);
+}
+
+#else
+
+static int fetch_fpxregs (int tid) { return 0; }
+static int store_fpxregs (int tid, int regno) { return 0; }
+static void dummy_sse_values (void) {}
+
+#endif /* HAVE_PTRACE_GETFPXREGS */
+
+
+/* Transferring arbitrary registers between GDB and inferior. */
+
+/* Check if register REGNO in the child process is accessible.
+ If we are accessing registers directly via the U area, only the
+ general-purpose registers are available.
+ All registers should be accessible if we have GETREGS support. */
+
+int
+cannot_fetch_register (int regno)
+{
+ if (! have_ptrace_getregs)
+ return OLD_CANNOT_FETCH_REGISTER (regno);
+ return 0;
+}
+int
+cannot_store_register (int regno)
+{
+ if (! have_ptrace_getregs)
+ return OLD_CANNOT_STORE_REGISTER (regno);
+ return 0;
+}
+
+/* Fetch register REGNO from the child process. If REGNO is -1, do
+ this for all registers (including the floating point and SSE
+ registers). */
+
+void
+fetch_inferior_registers (int regno)
+{
+ int tid;
+
+ /* Use the old method of peeking around in `struct user' if the
+ GETREGS request isn't available. */
+ if (! have_ptrace_getregs)
+ {
+ old_fetch_inferior_registers (regno);
+ return;
+ }
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ if ((tid = TIDGET (inferior_ptid)) == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ /* Use the PTRACE_GETFPXREGS request whenever possible, since it
+ transfers more registers in one system call, and we'll cache the
+ results. But remember that fetch_fpxregs can fail, and return
+ zero. */
+ if (regno == -1)
+ {
+ fetch_regs (tid);
+
+ /* The call above might reset `have_ptrace_getregs'. */
+ if (! have_ptrace_getregs)
+ {
+ old_fetch_inferior_registers (-1);
+ return;
+ }
+
+ if (fetch_fpxregs (tid))
+ return;
+ fetch_fpregs (tid);
+ return;
+ }
+
+ if (GETREGS_SUPPLIES (regno))
+ {
+ fetch_regs (tid);
+ return;
+ }
+
+ if (GETFPXREGS_SUPPLIES (regno))
+ {
+ if (fetch_fpxregs (tid))
+ return;
+
+ /* Either our processor or our kernel doesn't support the SSE
+ registers, so read the FP registers in the traditional way,
+ and fill the SSE registers with dummy values. It would be
+ more graceful to handle differences in the register set using
+ gdbarch. Until then, this will at least make things work
+ plausibly. */
+ fetch_fpregs (tid);
+ return;
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "Got request for bad register number %d.", regno);
+}
+
+/* Store register REGNO back into the child process. If REGNO is -1,
+ do this for all registers (including the floating point and SSE
+ registers). */
+void
+store_inferior_registers (int regno)
+{
+ int tid;
+
+ /* Use the old method of poking around in `struct user' if the
+ SETREGS request isn't available. */
+ if (! have_ptrace_getregs)
+ {
+ old_store_inferior_registers (regno);
+ return;
+ }
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ if ((tid = TIDGET (inferior_ptid)) == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ /* Use the PTRACE_SETFPXREGS requests whenever possible, since it
+ transfers more registers in one system call. But remember that
+ store_fpxregs can fail, and return zero. */
+ if (regno == -1)
+ {
+ store_regs (tid, regno);
+ if (store_fpxregs (tid, regno))
+ return;
+ store_fpregs (tid, regno);
+ return;
+ }
+
+ if (GETREGS_SUPPLIES (regno))
+ {
+ store_regs (tid, regno);
+ return;
+ }
+
+ if (GETFPXREGS_SUPPLIES (regno))
+ {
+ if (store_fpxregs (tid, regno))
+ return;
+
+ /* Either our processor or our kernel doesn't support the SSE
+ registers, so just write the FP registers in the traditional
+ way. */
+ store_fpregs (tid, regno);
+ return;
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "Got request to store bad register number %d.", regno);
+}
+
+
+static unsigned long
+i386_linux_dr_get (int regnum)
+{
+ int tid;
+ unsigned long value;
+
+ /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
+ multi-threaded processes here. For now, pretend there is just
+ one thread. */
+ tid = PIDGET (inferior_ptid);
+
+ /* FIXME: kettenis/2001-03-27: Calling perror_with_name if the
+ ptrace call fails breaks debugging remote targets. The correct
+ way to fix this is to add the hardware breakpoint and watchpoint
+ stuff to the target vectore. For now, just return zero if the
+ ptrace call fails. */
+ errno = 0;
+ value = ptrace (PT_READ_U, tid,
+ offsetof (struct user, u_debugreg[regnum]), 0);
+ if (errno != 0)
+#if 0
+ perror_with_name ("Couldn't read debug register");
+#else
+ return 0;
+#endif
+
+ return value;
+}
+
+static void
+i386_linux_dr_set (int regnum, unsigned long value)
+{
+ int tid;
+
+ /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
+ multi-threaded processes here. For now, pretend there is just
+ one thread. */
+ tid = PIDGET (inferior_ptid);
+
+ errno = 0;
+ ptrace (PT_WRITE_U, tid,
+ offsetof (struct user, u_debugreg[regnum]), value);
+ if (errno != 0)
+ perror_with_name ("Couldn't write debug register");
+}
+
+void
+i386_linux_dr_set_control (unsigned long control)
+{
+ i386_linux_dr_set (DR_CONTROL, control);
+}
+
+void
+i386_linux_dr_set_addr (int regnum, CORE_ADDR addr)
+{
+ gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
+
+ i386_linux_dr_set (DR_FIRSTADDR + regnum, addr);
+}
+
+void
+i386_linux_dr_reset_addr (int regnum)
+{
+ gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
+
+ i386_linux_dr_set (DR_FIRSTADDR + regnum, 0L);
+}
+
+unsigned long
+i386_linux_dr_get_status (void)
+{
+ return i386_linux_dr_get (DR_STATUS);
+}
+
+
+/* Interpreting register set info found in core files. */
+
+/* Provide registers to GDB from a core file.
+
+ (We can't use the generic version of this function in
+ core-regset.c, because GNU/Linux has *three* different kinds of
+ register set notes. core-regset.c would have to call
+ supply_fpxregset, which most platforms don't have.)
+
+ CORE_REG_SECT points to an array of bytes, which are the contents
+ of a `note' from a core file which BFD thinks might contain
+ register contents. CORE_REG_SIZE is its size.
+
+ WHICH says which register set corelow suspects this is:
+ 0 --- the general-purpose register set, in elf_gregset_t format
+ 2 --- the floating-point register set, in elf_fpregset_t format
+ 3 --- the extended floating-point register set, in elf_fpxregset_t format
+
+ REG_ADDR isn't used on GNU/Linux. */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+ elf_gregset_t gregset;
+ elf_fpregset_t fpregset;
+
+ switch (which)
+ {
+ case 0:
+ if (core_reg_size != sizeof (gregset))
+ warning ("Wrong size gregset in core file.");
+ else
+ {
+ memcpy (&gregset, core_reg_sect, sizeof (gregset));
+ supply_gregset (&gregset);
+ }
+ break;
+
+ case 2:
+ if (core_reg_size != sizeof (fpregset))
+ warning ("Wrong size fpregset in core file.");
+ else
+ {
+ memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
+ supply_fpregset (&fpregset);
+ }
+ break;
+
+#ifdef HAVE_PTRACE_GETFPXREGS
+ {
+ elf_fpxregset_t fpxregset;
+
+ case 3:
+ if (core_reg_size != sizeof (fpxregset))
+ warning ("Wrong size fpxregset in core file.");
+ else
+ {
+ memcpy (&fpxregset, core_reg_sect, sizeof (fpxregset));
+ supply_fpxregset (&fpxregset);
+ }
+ break;
+ }
+#endif
+
+ default:
+ /* We've covered all the kinds of registers we know about here,
+ so this must be something we wouldn't know what to do with
+ anyway. Just ignore it. */
+ break;
+ }
+}
+
+
+/* The instruction for a GNU/Linux system call is:
+ int $0x80
+ or 0xcd 0x80. */
+
+static const unsigned char linux_syscall[] = { 0xcd, 0x80 };
+
+#define LINUX_SYSCALL_LEN (sizeof linux_syscall)
+
+/* The system call number is stored in the %eax register. */
+#define LINUX_SYSCALL_REGNUM 0 /* %eax */
+
+/* We are specifically interested in the sigreturn and rt_sigreturn
+ system calls. */
+
+#ifndef SYS_sigreturn
+#define SYS_sigreturn 0x77
+#endif
+#ifndef SYS_rt_sigreturn
+#define SYS_rt_sigreturn 0xad
+#endif
+
+/* Offset to saved processor flags, from <asm/sigcontext.h>. */
+#define LINUX_SIGCONTEXT_EFLAGS_OFFSET (64)
+
+/* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+void
+child_resume (ptid_t ptid, int step, enum target_signal signal)
+{
+ int pid = PIDGET (ptid);
+
+ int request = PTRACE_CONT;
+
+ if (pid == -1)
+ /* Resume all threads. */
+ /* I think this only gets used in the non-threaded case, where "resume
+ all threads" and "resume inferior_ptid" are the same. */
+ pid = PIDGET (inferior_ptid);
+
+ if (step)
+ {
+ CORE_ADDR pc = read_pc_pid (pid_to_ptid (pid));
+ unsigned char buf[LINUX_SYSCALL_LEN];
+
+ request = PTRACE_SINGLESTEP;
+
+ /* Returning from a signal trampoline is done by calling a
+ special system call (sigreturn or rt_sigreturn, see
+ i386-linux-tdep.c for more information). This system call
+ restores the registers that were saved when the signal was
+ raised, including %eflags. That means that single-stepping
+ won't work. Instead, we'll have to modify the signal context
+ that's about to be restored, and set the trace flag there. */
+
+ /* First check if PC is at a system call. */
+ if (read_memory_nobpt (pc, (char *) buf, LINUX_SYSCALL_LEN) == 0
+ && memcmp (buf, linux_syscall, LINUX_SYSCALL_LEN) == 0)
+ {
+ int syscall = read_register_pid (LINUX_SYSCALL_REGNUM,
+ pid_to_ptid (pid));
+
+ /* Then check the system call number. */
+ if (syscall == SYS_sigreturn || syscall == SYS_rt_sigreturn)
+ {
+ CORE_ADDR sp = read_register (SP_REGNUM);
+ CORE_ADDR addr = sp;
+ unsigned long int eflags;
+
+ if (syscall == SYS_rt_sigreturn)
+ addr = read_memory_integer (sp + 8, 4) + 20;
+
+ /* Set the trace flag in the context that's about to be
+ restored. */
+ addr += LINUX_SIGCONTEXT_EFLAGS_OFFSET;
+ read_memory (addr, (char *) &eflags, 4);
+ eflags |= 0x0100;
+ write_memory (addr, (char *) &eflags, 4);
+ }
+ }
+ }
+
+ if (ptrace (request, pid, 0, target_signal_to_host (signal)) == -1)
+ perror_with_name ("ptrace");
+}
+
+
+/* Register that we are able to handle GNU/Linux ELF core file
+ formats. */
+
+static struct core_fns linux_elf_core_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_i386_linux_nat (void)
+{
+ add_core_fns (&linux_elf_core_fns);
+}
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
new file mode 100644
index 00000000000..9592decee19
--- /dev/null
+++ b/gdb/i386-linux-tdep.c
@@ -0,0 +1,530 @@
+/* Target-dependent code for GNU/Linux running on i386's, for GDB.
+
+ Copyright 2000, 2001, 2002 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 "defs.h"
+#include "gdbcore.h"
+#include "frame.h"
+#include "value.h"
+#include "regcache.h"
+#include "inferior.h"
+
+/* For i386_linux_skip_solib_resolver. */
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+
+#include "solib-svr4.h" /* For struct link_map_offsets. */
+
+/* Return the name of register REG. */
+
+char *
+i386_linux_register_name (int reg)
+{
+ /* Deal with the extra "orig_eax" pseudo register. */
+ if (reg == I386_LINUX_ORIG_EAX_REGNUM)
+ return "orig_eax";
+
+ return i386_register_name (reg);
+}
+
+int
+i386_linux_register_byte (int reg)
+{
+ /* Deal with the extra "orig_eax" pseudo register. */
+ if (reg == I386_LINUX_ORIG_EAX_REGNUM)
+ return (i386_register_byte (I386_LINUX_ORIG_EAX_REGNUM - 1)
+ + i386_register_raw_size (I386_LINUX_ORIG_EAX_REGNUM - 1));
+
+ return i386_register_byte (reg);
+}
+
+int
+i386_linux_register_raw_size (int reg)
+{
+ /* Deal with the extra "orig_eax" pseudo register. */
+ if (reg == I386_LINUX_ORIG_EAX_REGNUM)
+ return 4;
+
+ return i386_register_raw_size (reg);
+}
+
+/* Recognizing signal handler frames. */
+
+/* GNU/Linux has two flavors of signals. Normal signal handlers, and
+ "realtime" (RT) signals. The RT signals can provide additional
+ information to the signal handler if the SA_SIGINFO flag is set
+ when establishing a signal handler using `sigaction'. It is not
+ unlikely that future versions of GNU/Linux will support SA_SIGINFO
+ for normal signals too. */
+
+/* When the i386 Linux kernel calls a signal handler and the
+ SA_RESTORER flag isn't set, the return address points to a bit of
+ code on the stack. This function returns whether the PC appears to
+ be within this bit of code.
+
+ The instruction sequence for normal signals is
+ pop %eax
+ mov $0x77,%eax
+ int $0x80
+ or 0x58 0xb8 0x77 0x00 0x00 0x00 0xcd 0x80.
+
+ Checking for the code sequence should be somewhat reliable, because
+ the effect is to call the system call sigreturn. This is unlikely
+ to occur anywhere other than a signal trampoline.
+
+ It kind of sucks that we have to read memory from the process in
+ order to identify a signal trampoline, but there doesn't seem to be
+ any other way. The PC_IN_SIGTRAMP macro in tm-linux.h arranges to
+ only call us if no function name could be identified, which should
+ be the case since the code is on the stack.
+
+ Detection of signal trampolines for handlers that set the
+ SA_RESTORER flag is in general not possible. Unfortunately this is
+ what the GNU C Library has been doing for quite some time now.
+ However, as of version 2.1.2, the GNU C Library uses signal
+ trampolines (named __restore and __restore_rt) that are identical
+ to the ones used by the kernel. Therefore, these trampolines are
+ supported too. */
+
+#define LINUX_SIGTRAMP_INSN0 (0x58) /* pop %eax */
+#define LINUX_SIGTRAMP_OFFSET0 (0)
+#define LINUX_SIGTRAMP_INSN1 (0xb8) /* mov $NNNN,%eax */
+#define LINUX_SIGTRAMP_OFFSET1 (1)
+#define LINUX_SIGTRAMP_INSN2 (0xcd) /* int */
+#define LINUX_SIGTRAMP_OFFSET2 (6)
+
+static const unsigned char linux_sigtramp_code[] =
+{
+ LINUX_SIGTRAMP_INSN0, /* pop %eax */
+ LINUX_SIGTRAMP_INSN1, 0x77, 0x00, 0x00, 0x00, /* mov $0x77,%eax */
+ LINUX_SIGTRAMP_INSN2, 0x80 /* int $0x80 */
+};
+
+#define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code)
+
+/* If PC is in a sigtramp routine, return the address of the start of
+ the routine. Otherwise, return 0. */
+
+static CORE_ADDR
+i386_linux_sigtramp_start (CORE_ADDR pc)
+{
+ unsigned char buf[LINUX_SIGTRAMP_LEN];
+
+ /* We only recognize a signal trampoline if PC is at the start of
+ one of the three instructions. We optimize for finding the PC at
+ the start, as will be the case when the trampoline is not the
+ first frame on the stack. We assume that in the case where the
+ PC is not at the start of the instruction sequence, there will be
+ a few trailing readable bytes on the stack. */
+
+ if (read_memory_nobpt (pc, (char *) buf, LINUX_SIGTRAMP_LEN) != 0)
+ return 0;
+
+ if (buf[0] != LINUX_SIGTRAMP_INSN0)
+ {
+ int adjust;
+
+ switch (buf[0])
+ {
+ case LINUX_SIGTRAMP_INSN1:
+ adjust = LINUX_SIGTRAMP_OFFSET1;
+ break;
+ case LINUX_SIGTRAMP_INSN2:
+ adjust = LINUX_SIGTRAMP_OFFSET2;
+ break;
+ default:
+ return 0;
+ }
+
+ pc -= adjust;
+
+ if (read_memory_nobpt (pc, (char *) buf, LINUX_SIGTRAMP_LEN) != 0)
+ return 0;
+ }
+
+ if (memcmp (buf, linux_sigtramp_code, LINUX_SIGTRAMP_LEN) != 0)
+ return 0;
+
+ return pc;
+}
+
+/* This function does the same for RT signals. Here the instruction
+ sequence is
+ mov $0xad,%eax
+ int $0x80
+ or 0xb8 0xad 0x00 0x00 0x00 0xcd 0x80.
+
+ The effect is to call the system call rt_sigreturn. */
+
+#define LINUX_RT_SIGTRAMP_INSN0 (0xb8) /* mov $NNNN,%eax */
+#define LINUX_RT_SIGTRAMP_OFFSET0 (0)
+#define LINUX_RT_SIGTRAMP_INSN1 (0xcd) /* int */
+#define LINUX_RT_SIGTRAMP_OFFSET1 (5)
+
+static const unsigned char linux_rt_sigtramp_code[] =
+{
+ LINUX_RT_SIGTRAMP_INSN0, 0xad, 0x00, 0x00, 0x00, /* mov $0xad,%eax */
+ LINUX_RT_SIGTRAMP_INSN1, 0x80 /* int $0x80 */
+};
+
+#define LINUX_RT_SIGTRAMP_LEN (sizeof linux_rt_sigtramp_code)
+
+/* If PC is in a RT sigtramp routine, return the address of the start
+ of the routine. Otherwise, return 0. */
+
+static CORE_ADDR
+i386_linux_rt_sigtramp_start (CORE_ADDR pc)
+{
+ unsigned char buf[LINUX_RT_SIGTRAMP_LEN];
+
+ /* We only recognize a signal trampoline if PC is at the start of
+ one of the two instructions. We optimize for finding the PC at
+ the start, as will be the case when the trampoline is not the
+ first frame on the stack. We assume that in the case where the
+ PC is not at the start of the instruction sequence, there will be
+ a few trailing readable bytes on the stack. */
+
+ if (read_memory_nobpt (pc, (char *) buf, LINUX_RT_SIGTRAMP_LEN) != 0)
+ return 0;
+
+ if (buf[0] != LINUX_RT_SIGTRAMP_INSN0)
+ {
+ if (buf[0] != LINUX_RT_SIGTRAMP_INSN1)
+ return 0;
+
+ pc -= LINUX_RT_SIGTRAMP_OFFSET1;
+
+ if (read_memory_nobpt (pc, (char *) buf, LINUX_RT_SIGTRAMP_LEN) != 0)
+ return 0;
+ }
+
+ if (memcmp (buf, linux_rt_sigtramp_code, LINUX_RT_SIGTRAMP_LEN) != 0)
+ return 0;
+
+ return pc;
+}
+
+/* Return whether PC is in a GNU/Linux sigtramp routine. */
+
+int
+i386_linux_in_sigtramp (CORE_ADDR pc, char *name)
+{
+ if (name)
+ return STREQ ("__restore", name) || STREQ ("__restore_rt", name);
+
+ return (i386_linux_sigtramp_start (pc) != 0
+ || i386_linux_rt_sigtramp_start (pc) != 0);
+}
+
+/* Assuming FRAME is for a GNU/Linux sigtramp routine, return the
+ address of the associated sigcontext structure. */
+
+CORE_ADDR
+i386_linux_sigcontext_addr (struct frame_info *frame)
+{
+ CORE_ADDR pc;
+
+ pc = i386_linux_sigtramp_start (frame->pc);
+ if (pc)
+ {
+ CORE_ADDR sp;
+
+ if (frame->next)
+ /* If this isn't the top frame, the next frame must be for the
+ signal handler itself. The sigcontext structure lives on
+ the stack, right after the signum argument. */
+ return frame->next->frame + 12;
+
+ /* This is the top frame. We'll have to find the address of the
+ sigcontext structure by looking at the stack pointer. Keep
+ in mind that the first instruction of the sigtramp code is
+ "pop %eax". If the PC is at this instruction, adjust the
+ returned value accordingly. */
+ sp = read_register (SP_REGNUM);
+ if (pc == frame->pc)
+ return sp + 4;
+ return sp;
+ }
+
+ pc = i386_linux_rt_sigtramp_start (frame->pc);
+ if (pc)
+ {
+ if (frame->next)
+ /* If this isn't the top frame, the next frame must be for the
+ signal handler itself. The sigcontext structure is part of
+ the user context. A pointer to the user context is passed
+ as the third argument to the signal handler. */
+ return read_memory_integer (frame->next->frame + 16, 4) + 20;
+
+ /* This is the top frame. Again, use the stack pointer to find
+ the address of the sigcontext structure. */
+ return read_memory_integer (read_register (SP_REGNUM) + 8, 4) + 20;
+ }
+
+ error ("Couldn't recognize signal trampoline.");
+ return 0;
+}
+
+/* Offset to saved PC in sigcontext, from <asm/sigcontext.h>. */
+#define LINUX_SIGCONTEXT_PC_OFFSET (56)
+
+/* Assuming FRAME is for a GNU/Linux sigtramp routine, return the
+ saved program counter. */
+
+static CORE_ADDR
+i386_linux_sigtramp_saved_pc (struct frame_info *frame)
+{
+ CORE_ADDR addr;
+ addr = i386_linux_sigcontext_addr (frame);
+ return read_memory_integer (addr + LINUX_SIGCONTEXT_PC_OFFSET, 4);
+}
+
+/* Offset to saved SP in sigcontext, from <asm/sigcontext.h>. */
+#define LINUX_SIGCONTEXT_SP_OFFSET (28)
+
+/* Assuming FRAME is for a GNU/Linux sigtramp routine, return the
+ saved stack pointer. */
+
+static CORE_ADDR
+i386_linux_sigtramp_saved_sp (struct frame_info *frame)
+{
+ CORE_ADDR addr;
+ addr = i386_linux_sigcontext_addr (frame);
+ return read_memory_integer (addr + LINUX_SIGCONTEXT_SP_OFFSET, 4);
+}
+
+/* Signal trampolines don't have a meaningful frame. As in
+ "i386/tm-i386.h", the frame pointer value we use is actually the
+ frame pointer of the calling frame -- that is, the frame which was
+ in progress when the signal trampoline was entered. GDB mostly
+ treats this frame pointer value as a magic cookie. We detect the
+ case of a signal trampoline by looking at the SIGNAL_HANDLER_CALLER
+ field, which is set based on PC_IN_SIGTRAMP.
+
+ When a signal trampoline is invoked from a frameless function, we
+ essentially have two frameless functions in a row. In this case,
+ we use the same magic cookie for three frames in a row. We detect
+ this case by seeing whether the next frame has
+ SIGNAL_HANDLER_CALLER set, and, if it does, checking whether the
+ current frame is actually frameless. In this case, we need to get
+ the PC by looking at the SP register value stored in the signal
+ context.
+
+ This should work in most cases except in horrible situations where
+ a signal occurs just as we enter a function but before the frame
+ has been set up. */
+
+#define FRAMELESS_SIGNAL(frame) \
+ ((frame)->next != NULL \
+ && (frame)->next->signal_handler_caller \
+ && frameless_look_for_prologue (frame))
+
+CORE_ADDR
+i386_linux_frame_chain (struct frame_info *frame)
+{
+ if (frame->signal_handler_caller || FRAMELESS_SIGNAL (frame))
+ return frame->frame;
+
+ if (! inside_entry_file (frame->pc))
+ return read_memory_unsigned_integer (frame->frame, 4);
+
+ return 0;
+}
+
+/* Return the saved program counter for FRAME. */
+
+CORE_ADDR
+i386_linux_frame_saved_pc (struct frame_info *frame)
+{
+ if (frame->signal_handler_caller)
+ return i386_linux_sigtramp_saved_pc (frame);
+
+ if (FRAMELESS_SIGNAL (frame))
+ {
+ CORE_ADDR sp = i386_linux_sigtramp_saved_sp (frame->next);
+ return read_memory_unsigned_integer (sp, 4);
+ }
+
+ return read_memory_unsigned_integer (frame->frame + 4, 4);
+}
+
+/* Immediately after a function call, return the saved pc. */
+
+CORE_ADDR
+i386_linux_saved_pc_after_call (struct frame_info *frame)
+{
+ if (frame->signal_handler_caller)
+ return i386_linux_sigtramp_saved_pc (frame);
+
+ return read_memory_unsigned_integer (read_register (SP_REGNUM), 4);
+}
+
+/* Set the program counter for process PTID to PC. */
+
+void
+i386_linux_write_pc (CORE_ADDR pc, ptid_t ptid)
+{
+ write_register_pid (PC_REGNUM, pc, ptid);
+
+ /* We must be careful with modifying the program counter. If we
+ just interrupted a system call, the kernel might try to restart
+ it when we resume the inferior. On restarting the system call,
+ the kernel will try backing up the program counter even though it
+ no longer points at the system call. This typically results in a
+ SIGSEGV or SIGILL. We can prevent this by writing `-1' in the
+ "orig_eax" pseudo-register.
+
+ Note that "orig_eax" is saved when setting up a dummy call frame.
+ This means that it is properly restored when that frame is
+ popped, and that the interrupted system call will be restarted
+ when we resume the inferior on return from a function call from
+ within GDB. In all other cases the system call will not be
+ restarted. */
+ write_register_pid (I386_LINUX_ORIG_EAX_REGNUM, -1, ptid);
+}
+
+/* Calling functions in shared libraries. */
+
+/* Find the minimal symbol named NAME, and return both the minsym
+ struct and its objfile. This probably ought to be in minsym.c, but
+ everything there is trying to deal with things like C++ and
+ SOFUN_ADDRESS_MAYBE_TURQUOISE, ... Since this is so simple, it may
+ be considered too special-purpose for general consumption. */
+
+static struct minimal_symbol *
+find_minsym_and_objfile (char *name, struct objfile **objfile_p)
+{
+ struct objfile *objfile;
+
+ ALL_OBJFILES (objfile)
+ {
+ struct minimal_symbol *msym;
+
+ ALL_OBJFILE_MSYMBOLS (objfile, msym)
+ {
+ if (SYMBOL_NAME (msym)
+ && STREQ (SYMBOL_NAME (msym), name))
+ {
+ *objfile_p = objfile;
+ return msym;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static CORE_ADDR
+skip_hurd_resolver (CORE_ADDR pc)
+{
+ /* The HURD dynamic linker is part of the GNU C library, so many
+ GNU/Linux distributions use it. (All ELF versions, as far as I
+ know.) An unresolved PLT entry points to "_dl_runtime_resolve",
+ which calls "fixup" to patch the PLT, and then passes control to
+ the function.
+
+ We look for the symbol `_dl_runtime_resolve', and find `fixup' in
+ the same objfile. If we are at the entry point of `fixup', then
+ we set a breakpoint at the return address (at the top of the
+ stack), and continue.
+
+ It's kind of gross to do all these checks every time we're
+ called, since they don't change once the executable has gotten
+ started. But this is only a temporary hack --- upcoming versions
+ of GNU/Linux will provide a portable, efficient interface for
+ debugging programs that use shared libraries. */
+
+ struct objfile *objfile;
+ struct minimal_symbol *resolver
+ = find_minsym_and_objfile ("_dl_runtime_resolve", &objfile);
+
+ if (resolver)
+ {
+ struct minimal_symbol *fixup
+ = lookup_minimal_symbol ("fixup", NULL, objfile);
+
+ if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc)
+ return (SAVED_PC_AFTER_CALL (get_current_frame ()));
+ }
+
+ return 0;
+}
+
+/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c.
+ This function:
+ 1) decides whether a PLT has sent us into the linker to resolve
+ a function reference, and
+ 2) if so, tells us where to set a temporary breakpoint that will
+ trigger when the dynamic linker is done. */
+
+CORE_ADDR
+i386_linux_skip_solib_resolver (CORE_ADDR pc)
+{
+ CORE_ADDR result;
+
+ /* Plug in functions for other kinds of resolvers here. */
+ result = skip_hurd_resolver (pc);
+ if (result)
+ return result;
+
+ return 0;
+}
+
+/* Fetch (and possibly build) an appropriate link_map_offsets
+ structure for native GNU/Linux x86 targets using the struct offsets
+ defined in link.h (but without actual reference to that file).
+
+ This makes it possible to access GNU/Linux x86 shared libraries
+ from a GDB that was not built on an GNU/Linux x86 host (for cross
+ debugging). */
+
+struct link_map_offsets *
+i386_linux_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_debug_size = 8; /* The actual size is 20 bytes, but
+ this is all we need. */
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 4;
+
+ lmo.link_map_size = 20; /* The actual size is 552 bytes, but
+ this is all we need. */
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 4;
+
+ lmo.l_name_offset = 4;
+ lmo.l_name_size = 4;
+
+ lmo.l_next_offset = 12;
+ lmo.l_next_size = 4;
+
+ lmo.l_prev_offset = 16;
+ lmo.l_prev_size = 4;
+ }
+
+ return lmp;
+}
diff --git a/gdb/i386-linux-tdep.h b/gdb/i386-linux-tdep.h
new file mode 100644
index 00000000000..3c30130ede9
--- /dev/null
+++ b/gdb/i386-linux-tdep.h
@@ -0,0 +1,36 @@
+/* Target-dependent code for Linux/x86.
+ Copyright 2002
+ 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. */
+
+#ifndef I386_LINUX_TDEP_H
+#define I386_LINUX_TDEP_H
+
+/* The Linux kernel pretends there is an additional "orig_eax"
+ register. Since GDB needs access to that register to be able to
+ properly restart system calls when necessary (see
+ i386-linux-tdep.c) we need our own versions of a number of
+ functions that deal with GDB's register cache. */
+
+/* Register number for the "orig_eax" pseudo-register. If this
+ pseudo-register contains a value >= 0 it is interpreted as the
+ system call number that the kernel is supposed to restart. */
+#define I386_LINUX_ORIG_EAX_REGNUM I386_SSE_NUM_REGS
+
+#endif /* i386-linux-tdep.h */
diff --git a/gdb/i386-nat.c b/gdb/i386-nat.c
new file mode 100644
index 00000000000..adf220bba73
--- /dev/null
+++ b/gdb/i386-nat.c
@@ -0,0 +1,635 @@
+/* Intel x86 (a.k.a. ia32) native-dependent code.
+ Copyright (C) 2001 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 "defs.h"
+#include "breakpoint.h"
+#include "command.h"
+#include "gdbcmd.h"
+
+/* Support for hardware watchpoints and breakpoints using the x86
+ debug registers.
+
+ This provides several functions for inserting and removing
+ hardware-assisted breakpoints and watchpoints, testing if
+ one or more of the watchpoints triggered and at what address,
+ checking whether a given region can be watched, etc.
+
+ A target which wants to use these functions should define
+ several macros, such as `target_insert_watchpoint' and
+ `target_stopped_data_address', listed in target.h, to call
+ the appropriate functions below. It should also define
+ I386_USE_GENERIC_WATCHPOINTS in its tm.h file.
+
+ In addition, each target should provide several low-level
+ macros that will be called to insert watchpoints and hardware
+ breakpoints into the inferior, remove them, and check their
+ status. These macros are:
+
+ I386_DR_LOW_SET_CONTROL -- set the debug control (DR7)
+ register to a given value
+
+ I386_DR_LOW_SET_ADDR -- put an address into one debug
+ register
+
+ I386_DR_LOW_RESET_ADDR -- reset the address stored in
+ one debug register
+
+ I386_DR_LOW_GET_STATUS -- return the value of the debug
+ status (DR6) register.
+
+ The functions below implement debug registers sharing by
+ reference counts, and allow to watch regions up to 16 bytes
+ long. */
+
+#ifdef I386_USE_GENERIC_WATCHPOINTS
+
+/* Support for 8-byte wide hw watchpoints. */
+#ifndef TARGET_HAS_DR_LEN_8
+#define TARGET_HAS_DR_LEN_8 0
+#endif
+
+/* Debug registers' indices. */
+#define DR_NADDR 4 /* the number of debug address registers */
+#define DR_STATUS 6 /* index of debug status register (DR6) */
+#define DR_CONTROL 7 /* index of debug control register (DR7) */
+
+/* DR7 Debug Control register fields. */
+
+/* How many bits to skip in DR7 to get to R/W and LEN fields. */
+#define DR_CONTROL_SHIFT 16
+/* How many bits in DR7 per R/W and LEN field for each watchpoint. */
+#define DR_CONTROL_SIZE 4
+
+/* Watchpoint/breakpoint read/write fields in DR7. */
+#define DR_RW_EXECUTE (0x0) /* break on instruction execution */
+#define DR_RW_WRITE (0x1) /* break on data writes */
+#define DR_RW_READ (0x3) /* break on data reads or writes */
+
+/* This is here for completeness. No platform supports this
+ functionality yet (as of Mar-2001). Note that the DE flag in the
+ CR4 register needs to be set to support this. */
+#ifndef DR_RW_IORW
+#define DR_RW_IORW (0x2) /* break on I/O reads or writes */
+#endif
+
+/* Watchpoint/breakpoint length fields in DR7. The 2-bit left shift
+ is so we could OR this with the read/write field defined above. */
+#define DR_LEN_1 (0x0 << 2) /* 1-byte region watch or breakpt */
+#define DR_LEN_2 (0x1 << 2) /* 2-byte region watch */
+#define DR_LEN_4 (0x3 << 2) /* 4-byte region watch */
+#define DR_LEN_8 (0x2 << 2) /* 8-byte region watch (x86-64) */
+
+/* Local and Global Enable flags in DR7.
+
+ When the Local Enable flag is set, the breakpoint/watchpoint is
+ enabled only for the current task; the processor automatically
+ clears this flag on every task switch. When the Global Enable
+ flag is set, the breakpoint/watchpoint is enabled for all tasks;
+ the processor never clears this flag.
+
+ Currently, all watchpoint are locally enabled. If you need to
+ enable them globally, read the comment which pertains to this in
+ i386_insert_aligned_watchpoint below. */
+#define DR_LOCAL_ENABLE_SHIFT 0 /* extra shift to the local enable bit */
+#define DR_GLOBAL_ENABLE_SHIFT 1 /* extra shift to the global enable bit */
+#define DR_ENABLE_SIZE 2 /* 2 enable bits per debug register */
+
+/* Local and global exact breakpoint enable flags (a.k.a. slowdown
+ flags). These are only required on i386, to allow detection of the
+ exact instruction which caused a watchpoint to break; i486 and
+ later processors do that automatically. We set these flags for
+ back compatibility. */
+#define DR_LOCAL_SLOWDOWN (0x100)
+#define DR_GLOBAL_SLOWDOWN (0x200)
+
+/* Fields reserved by Intel. This includes the GD (General Detect
+ Enable) flag, which causes a debug exception to be generated when a
+ MOV instruction accesses one of the debug registers.
+
+ FIXME: My Intel manual says we should use 0xF800, not 0xFC00. */
+#define DR_CONTROL_RESERVED (0xFC00)
+
+/* Auxiliary helper macros. */
+
+/* A value that masks all fields in DR7 that are reserved by Intel. */
+#define I386_DR_CONTROL_MASK (~DR_CONTROL_RESERVED)
+
+/* The I'th debug register is vacant if its Local and Global Enable
+ bits are reset in the Debug Control register. */
+#define I386_DR_VACANT(i) \
+ ((dr_control_mirror & (3 << (DR_ENABLE_SIZE * (i)))) == 0)
+
+/* Locally enable the break/watchpoint in the I'th debug register. */
+#define I386_DR_LOCAL_ENABLE(i) \
+ dr_control_mirror |= (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (i)))
+
+/* Globally enable the break/watchpoint in the I'th debug register. */
+#define I386_DR_GLOBAL_ENABLE(i) \
+ dr_control_mirror |= (1 << (DR_GLOBAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (i)))
+
+/* Disable the break/watchpoint in the I'th debug register. */
+#define I386_DR_DISABLE(i) \
+ dr_control_mirror &= ~(3 << (DR_ENABLE_SIZE * (i)))
+
+/* Set in DR7 the RW and LEN fields for the I'th debug register. */
+#define I386_DR_SET_RW_LEN(i,rwlen) \
+ do { \
+ dr_control_mirror &= ~(0x0f << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE*(i))); \
+ dr_control_mirror |= ((rwlen) << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE*(i))); \
+ } while (0)
+
+/* Get from DR7 the RW and LEN fields for the I'th debug register. */
+#define I386_DR_GET_RW_LEN(i) \
+ ((dr_control_mirror >> (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (i))) & 0x0f)
+
+/* Did the watchpoint whose address is in the I'th register break? */
+#define I386_DR_WATCH_HIT(i) (dr_status_mirror & (1 << (i)))
+
+/* A macro to loop over all debug registers. */
+#define ALL_DEBUG_REGISTERS(i) for (i = 0; i < DR_NADDR; i++)
+
+/* Mirror the inferior's DRi registers. We keep the status and
+ control registers separated because they don't hold addresses. */
+static CORE_ADDR dr_mirror[DR_NADDR];
+static unsigned dr_status_mirror, dr_control_mirror;
+
+/* Reference counts for each debug register. */
+static int dr_ref_count[DR_NADDR];
+
+/* Whether or not to print the mirrored debug registers. */
+static int maint_show_dr;
+
+/* Types of operations supported by i386_handle_nonaligned_watchpoint. */
+typedef enum { WP_INSERT, WP_REMOVE, WP_COUNT } i386_wp_op_t;
+
+/* Internal functions. */
+
+/* Return the value of a 4-bit field for DR7 suitable for watching a
+ region of LEN bytes for accesses of type TYPE. LEN is assumed
+ to have the value of 1, 2, or 4. */
+static unsigned i386_length_and_rw_bits (int len, enum target_hw_bp_type type);
+
+/* Insert a watchpoint at address ADDR, which is assumed to be aligned
+ according to the length of the region to watch. LEN_RW_BITS is the
+ value of the bit-field from DR7 which describes the length and
+ access type of the region to be watched by this watchpoint. Return
+ 0 on success, -1 on failure. */
+static int i386_insert_aligned_watchpoint (CORE_ADDR addr,
+ unsigned len_rw_bits);
+
+/* Remove a watchpoint at address ADDR, which is assumed to be aligned
+ according to the length of the region to watch. LEN_RW_BITS is the
+ value of the bits from DR7 which describes the length and access
+ type of the region watched by this watchpoint. Return 0 on
+ success, -1 on failure. */
+static int i386_remove_aligned_watchpoint (CORE_ADDR addr,
+ unsigned len_rw_bits);
+
+/* Insert or remove a (possibly non-aligned) watchpoint, or count the
+ number of debug registers required to watch a region at address
+ ADDR whose length is LEN for accesses of type TYPE. Return 0 on
+ successful insertion or removal, a positive number when queried
+ about the number of registers, or -1 on failure. If WHAT is not
+ a valid value, bombs through internal_error. */
+static int i386_handle_nonaligned_watchpoint (i386_wp_op_t what,
+ CORE_ADDR addr, int len,
+ enum target_hw_bp_type type);
+
+/* Implementation. */
+
+/* Clear the reference counts and forget everything we knew about
+ the debug registers. */
+void
+i386_cleanup_dregs (void)
+{
+ int i;
+
+ ALL_DEBUG_REGISTERS(i)
+ {
+ dr_mirror[i] = 0;
+ dr_ref_count[i] = 0;
+ }
+ dr_control_mirror = 0;
+ dr_status_mirror = 0;
+}
+
+/* Print the values of the mirrored debug registers.
+ This is called when maint_show_dr is non-zero. To set that
+ up, type "maint show-debug-regs" at GDB's prompt. */
+static void
+i386_show_dr (const char *func, CORE_ADDR addr,
+ int len, enum target_hw_bp_type type)
+{
+ int i;
+
+ puts_unfiltered (func);
+ if (addr || len)
+ printf_unfiltered (" (addr=%lx, len=%d, type=%s)",
+ /* This code is for ia32, so casting CORE_ADDR
+ to unsigned long should be okay. */
+ (unsigned long)addr, len,
+ type == hw_write ? "data-write"
+ : (type == hw_read ? "data-read"
+ : (type == hw_access ? "data-read/write"
+ : (type == hw_execute ? "instruction-execute"
+ /* FIXME: if/when I/O read/write
+ watchpoints are supported, add them
+ here. */
+ : "??unknown??"))));
+ puts_unfiltered (":\n");
+ printf_unfiltered ("\tCONTROL (DR7): %08x STATUS (DR6): %08x\n",
+ dr_control_mirror, dr_status_mirror);
+ ALL_DEBUG_REGISTERS(i)
+ {
+ printf_unfiltered ("\tDR%d: addr=0x%s, ref.count=%d DR%d: addr=0x%s, ref.count=%d\n",
+ i, paddr(dr_mirror[i]), dr_ref_count[i],
+ i+1, paddr(dr_mirror[i+1]), dr_ref_count[i+1]);
+ i++;
+ }
+}
+
+/* Return the value of a 4-bit field for DR7 suitable for watching a
+ region of LEN bytes for accesses of type TYPE. LEN is assumed
+ to have the value of 1, 2, or 4. */
+static unsigned
+i386_length_and_rw_bits (int len, enum target_hw_bp_type type)
+{
+ unsigned rw;
+
+ switch (type)
+ {
+ case hw_execute:
+ rw = DR_RW_EXECUTE;
+ break;
+ case hw_write:
+ rw = DR_RW_WRITE;
+ break;
+ case hw_read: /* x86 doesn't support data-read watchpoints */
+ case hw_access:
+ rw = DR_RW_READ;
+ break;
+#if 0
+ case hw_io_access: /* not yet supported */
+ rw = DR_RW_IORW;
+ break;
+#endif
+ default:
+ internal_error (__FILE__, __LINE__, "\
+Invalid hw breakpoint type %d in i386_length_and_rw_bits.\n", (int)type);
+ }
+
+ switch (len)
+ {
+ case 1:
+ return (DR_LEN_1 | rw);
+ case 2:
+ return (DR_LEN_2 | rw);
+ case 4:
+ return (DR_LEN_4 | rw);
+ case 8:
+ if (TARGET_HAS_DR_LEN_8)
+ return (DR_LEN_8 | rw);
+ default:
+ internal_error (__FILE__, __LINE__, "\
+Invalid hw breakpoint length %d in i386_length_and_rw_bits.\n", len);
+ }
+}
+
+/* Insert a watchpoint at address ADDR, which is assumed to be aligned
+ according to the length of the region to watch. LEN_RW_BITS is the
+ value of the bits from DR7 which describes the length and access
+ type of the region to be watched by this watchpoint. Return 0 on
+ success, -1 on failure. */
+static int
+i386_insert_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits)
+{
+ int i;
+
+ /* First, look for an occupied debug register with the same address
+ and the same RW and LEN definitions. If we find one, we can
+ reuse it for this watchpoint as well (and save a register). */
+ ALL_DEBUG_REGISTERS(i)
+ {
+ if (!I386_DR_VACANT (i)
+ && dr_mirror[i] == addr
+ && I386_DR_GET_RW_LEN (i) == len_rw_bits)
+ {
+ dr_ref_count[i]++;
+ return 0;
+ }
+ }
+
+ /* Next, look for a vacant debug register. */
+ ALL_DEBUG_REGISTERS(i)
+ {
+ if (I386_DR_VACANT (i))
+ break;
+ }
+
+ /* No more debug registers! */
+ if (i >= DR_NADDR)
+ return -1;
+
+ /* Now set up the register I to watch our region. */
+
+ /* Record the info in our local mirrored array. */
+ dr_mirror[i] = addr;
+ dr_ref_count[i] = 1;
+ I386_DR_SET_RW_LEN (i, len_rw_bits);
+ /* Note: we only enable the watchpoint locally, i.e. in the current
+ task. Currently, no x86 target allows or supports global
+ watchpoints; however, if any target would want that in the
+ future, GDB should probably provide a command to control whether
+ to enable watchpoints globally or locally, and the code below
+ should use global or local enable and slow-down flags as
+ appropriate. */
+ I386_DR_LOCAL_ENABLE (i);
+ dr_control_mirror |= DR_LOCAL_SLOWDOWN;
+ dr_control_mirror &= I386_DR_CONTROL_MASK;
+
+ /* Finally, actually pass the info to the inferior. */
+ I386_DR_LOW_SET_ADDR (i, addr);
+ I386_DR_LOW_SET_CONTROL (dr_control_mirror);
+
+ return 0;
+}
+
+/* Remove a watchpoint at address ADDR, which is assumed to be aligned
+ according to the length of the region to watch. LEN_RW_BITS is the
+ value of the bits from DR7 which describes the length and access
+ type of the region watched by this watchpoint. Return 0 on
+ success, -1 on failure. */
+static int
+i386_remove_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits)
+{
+ int i, retval = -1;
+
+ ALL_DEBUG_REGISTERS(i)
+ {
+ if (!I386_DR_VACANT (i)
+ && dr_mirror[i] == addr
+ && I386_DR_GET_RW_LEN (i) == len_rw_bits)
+ {
+ if (--dr_ref_count[i] == 0) /* no longer in use? */
+ {
+ /* Reset our mirror. */
+ dr_mirror[i] = 0;
+ I386_DR_DISABLE (i);
+ /* Reset it in the inferior. */
+ I386_DR_LOW_SET_CONTROL (dr_control_mirror);
+ I386_DR_LOW_RESET_ADDR (i);
+ }
+ retval = 0;
+ }
+ }
+
+ return retval;
+}
+
+/* Insert or remove a (possibly non-aligned) watchpoint, or count the
+ number of debug registers required to watch a region at address
+ ADDR whose length is LEN for accesses of type TYPE. Return 0 on
+ successful insertion or removal, a positive number when queried
+ about the number of registers, or -1 on failure. If WHAT is not
+ a valid value, bombs through internal_error. */
+static int
+i386_handle_nonaligned_watchpoint (i386_wp_op_t what, CORE_ADDR addr, int len,
+ enum target_hw_bp_type type)
+{
+ int align;
+ int size;
+ int rv = 0, status = 0;
+ int max_wp_len = TARGET_HAS_DR_LEN_8 ? 8 : 4;
+
+ static int size_try_array[8][8] =
+ {
+ {1, 1, 1, 1, 1, 1, 1, 1}, /* trying size one */
+ {2, 1, 2, 1, 2, 1, 2, 1}, /* trying size two */
+ {2, 1, 2, 1, 2, 1, 2, 1}, /* trying size three */
+ {4, 1, 2, 1, 4, 1, 2, 1}, /* trying size four */
+ {4, 1, 2, 1, 4, 1, 2, 1}, /* trying size five */
+ {4, 1, 2, 1, 4, 1, 2, 1}, /* trying size six */
+ {4, 1, 2, 1, 4, 1, 2, 1}, /* trying size seven */
+ {8, 1, 2, 1, 4, 1, 2, 1}, /* trying size eight */
+ };
+
+ while (len > 0)
+ {
+ align = addr % max_wp_len;
+ /* Four(eigth on x86_64) is the maximum length an x86 debug register
+ can watch. */
+ size = size_try_array[len > max_wp_len ? (max_wp_len - 1) : len - 1][align];
+ if (what == WP_COUNT)
+ /* size_try_array[] is defined so that each iteration through
+ the loop is guaranteed to produce an address and a size
+ that can be watched with a single debug register. Thus,
+ for counting the registers required to watch a region, we
+ simply need to increment the count on each iteration. */
+ rv++;
+ else
+ {
+ unsigned len_rw = i386_length_and_rw_bits (size, type);
+
+ if (what == WP_INSERT)
+ status = i386_insert_aligned_watchpoint (addr, len_rw);
+ else if (what == WP_REMOVE)
+ status = i386_remove_aligned_watchpoint (addr, len_rw);
+ else
+ internal_error (__FILE__, __LINE__, "\
+Invalid value %d of operation in i386_handle_nonaligned_watchpoint.\n",
+ (int)what);
+ /* We keep the loop going even after a failure, because some
+ of the other aligned watchpoints might still succeed
+ (e.g. if they watch addresses that are already watched,
+ in which case we just increment the reference counts of
+ occupied debug registers). If we break out of the loop
+ too early, we could cause those addresses watched by
+ other watchpoints to be disabled when breakpoint.c reacts
+ to our failure to insert this watchpoint and tries to
+ remove it. */
+ if (status)
+ rv = status;
+ }
+ addr += size;
+ len -= size;
+ }
+ return rv;
+}
+
+/* Insert a watchpoint to watch a memory region which starts at
+ address ADDR and whose length is LEN bytes. Watch memory accesses
+ of the type TYPE. Return 0 on success, -1 on failure. */
+int
+i386_insert_watchpoint (CORE_ADDR addr, int len, int type)
+{
+ int retval;
+
+ if (((len != 1 && len !=2 && len !=4) && !(TARGET_HAS_DR_LEN_8 && len == 8))
+ || addr % len != 0)
+ retval = i386_handle_nonaligned_watchpoint (WP_INSERT, addr, len, type);
+ else
+ {
+ unsigned len_rw = i386_length_and_rw_bits (len, type);
+
+ retval = i386_insert_aligned_watchpoint (addr, len_rw);
+ }
+
+ if (maint_show_dr)
+ i386_show_dr ("insert_watchpoint", addr, len, type);
+
+ return retval;
+}
+
+/* Remove a watchpoint that watched the memory region which starts at
+ address ADDR, whose length is LEN bytes, and for accesses of the
+ type TYPE. Return 0 on success, -1 on failure. */
+int
+i386_remove_watchpoint (CORE_ADDR addr, int len, int type)
+{
+ int retval;
+
+ if (((len != 1 && len !=2 && len !=4) && !(TARGET_HAS_DR_LEN_8 && len == 8))
+ || addr % len != 0)
+ retval = i386_handle_nonaligned_watchpoint (WP_REMOVE, addr, len, type);
+ else
+ {
+ unsigned len_rw = i386_length_and_rw_bits (len, type);
+
+ retval = i386_remove_aligned_watchpoint (addr, len_rw);
+ }
+
+ if (maint_show_dr)
+ i386_show_dr ("remove_watchpoint", addr, len, type);
+
+ return retval;
+}
+
+/* Return non-zero if we can watch a memory region that starts at
+ address ADDR and whose length is LEN bytes. */
+int
+i386_region_ok_for_watchpoint (CORE_ADDR addr, int len)
+{
+ /* Compute how many aligned watchpoints we would need to cover this
+ region. */
+ int nregs = i386_handle_nonaligned_watchpoint (WP_COUNT, addr, len,
+ hw_write);
+
+ return nregs <= DR_NADDR ? 1 : 0;
+}
+
+/* If the inferior has some watchpoint that triggered, return the
+ address associated with that watchpoint. Otherwise, return
+ zero. */
+CORE_ADDR
+i386_stopped_data_address (void)
+{
+ int i;
+ CORE_ADDR ret = 0;
+
+ dr_status_mirror = I386_DR_LOW_GET_STATUS ();
+
+ ALL_DEBUG_REGISTERS(i)
+ {
+ if (I386_DR_WATCH_HIT (i)
+ /* This second condition makes sure DRi is set up for a data
+ watchpoint, not a hardware breakpoint. The reason is
+ that GDB doesn't call the target_stopped_data_address
+ method except for data watchpoints. In other words, I'm
+ being paranoiac. */
+ && I386_DR_GET_RW_LEN (i) != 0)
+ {
+ ret = dr_mirror[i];
+ if (maint_show_dr)
+ i386_show_dr ("watchpoint_hit", ret, -1, hw_write);
+ }
+ }
+ if (maint_show_dr && ret == 0)
+ i386_show_dr ("stopped_data_addr", 0, 0, hw_write);
+
+ return ret;
+}
+
+/* Return non-zero if the inferior has some break/watchpoint that
+ triggered. */
+int
+i386_stopped_by_hwbp (void)
+{
+ int i;
+
+ dr_status_mirror = I386_DR_LOW_GET_STATUS ();
+ if (maint_show_dr)
+ i386_show_dr ("stopped_by_hwbp", 0, 0, hw_execute);
+
+ ALL_DEBUG_REGISTERS(i)
+ {
+ if (I386_DR_WATCH_HIT (i))
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Insert a hardware-assisted breakpoint at address ADDR. SHADOW is
+ unused. Return 0 on success, EBUSY on failure. */
+int
+i386_insert_hw_breakpoint (CORE_ADDR addr, void *shadow)
+{
+ unsigned len_rw = i386_length_and_rw_bits (1, hw_execute);
+ int retval = i386_insert_aligned_watchpoint (addr, len_rw) ? EBUSY : 0;
+
+ if (maint_show_dr)
+ i386_show_dr ("insert_hwbp", addr, 1, hw_execute);
+
+ return retval;
+}
+
+/* Remove a hardware-assisted breakpoint at address ADDR. SHADOW is
+ unused. Return 0 on success, -1 on failure. */
+int
+i386_remove_hw_breakpoint (CORE_ADDR addr, void *shadow)
+{
+ unsigned len_rw = i386_length_and_rw_bits (1, hw_execute);
+ int retval = i386_remove_aligned_watchpoint (addr, len_rw);
+
+ if (maint_show_dr)
+ i386_show_dr ("remove_hwbp", addr, 1, hw_execute);
+
+ return retval;
+}
+
+#endif /* I386_USE_GENERIC_WATCHPOINTS */
+
+
+void
+_initialize_i386_nat (void)
+{
+#ifdef I386_USE_GENERIC_WATCHPOINTS
+ /* A maintenance command to enable printing the internal DRi mirror
+ variables. */
+ add_set_cmd ("show-debug-regs", class_maintenance,
+ var_boolean, (char *) &maint_show_dr,
+ "\
+Set whether to show variables that mirror the x86 debug registers.\n\
+Use \"on\" to enable, \"off\" to disable.\n\
+If enabled, the debug registers values are shown when GDB inserts\n\
+or removes a hardware breakpoint or watchpoint, and when the inferior\n\
+triggers a breakpoint or watchpoint.", &maintenancelist);
+#endif
+}
diff --git a/gdb/i386-stub.c b/gdb/i386-stub.c
new file mode 100644
index 00000000000..1251567e912
--- /dev/null
+++ b/gdb/i386-stub.c
@@ -0,0 +1,952 @@
+/****************************************************************************
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ HP offers the following for use in the public domain. HP makes no
+ warranty with regard to the software or it's performance and the
+ user accepts the software "AS IS" with all faults.
+
+ HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+ TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ * Module name: remcom.c $
+ * Revision: 1.34 $
+ * Date: 91/03/09 12:29:49 $
+ * Contributor: Lake Stevens Instrument Division$
+ *
+ * Description: low level support for gdb debugger. $
+ *
+ * Considerations: only works on target hardware $
+ *
+ * Written by: Glenn Engel $
+ * ModuleState: Experimental $
+ *
+ * NOTES: See Below $
+ *
+ * Modified for 386 by Jim Kingdon, Cygnus Support.
+ *
+ * To enable debugger support, two things need to happen. One, a
+ * call to set_debug_traps() is necessary in order to allow any breakpoints
+ * or error conditions to be properly intercepted and reported to gdb.
+ * Two, a breakpoint needs to be generated to begin communication. This
+ * is most easily accomplished by a call to breakpoint(). Breakpoint()
+ * simulates a breakpoint by executing a trap #1.
+ *
+ * The external function exceptionHandler() is
+ * used to attach a specific handler to a specific 386 vector number.
+ * It should use the same privilege level it runs at. It should
+ * install it as an interrupt gate so that interrupts are masked
+ * while the handler runs.
+ *
+ * Because gdb will sometimes write to the stack area to execute function
+ * calls, this program cannot rely on using the supervisor stack so it
+ * uses it's own stack area reserved in the int array remcomStack.
+ *
+ *************
+ *
+ * The following gdb commands are supported:
+ *
+ * command function Return value
+ *
+ * g return the value of the CPU registers hex data or ENN
+ * G set the value of the CPU registers OK or ENN
+ *
+ * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
+ * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
+ *
+ * c Resume at current address SNN ( signal NN)
+ * cAA..AA Continue at address AA..AA SNN
+ *
+ * s Step one instruction SNN
+ * sAA..AA Step one instruction from AA..AA SNN
+ *
+ * k kill
+ *
+ * ? What was the last sigval ? SNN (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum. A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer. '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host: Reply:
+ * $m0,10#2a +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+
+extern void putDebugChar(); /* write a single character */
+extern int getDebugChar(); /* read and return a single char */
+extern void exceptionHandler(); /* assign an exception handler */
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 400
+
+static char initialized; /* boolean flag. != 0 means we've been initialized */
+
+int remote_debug;
+/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
+
+static const char hexchars[]="0123456789abcdef";
+
+/* Number of registers. */
+#define NUMREGS 16
+
+/* Number of bytes of registers. */
+#define NUMREGBYTES (NUMREGS * 4)
+
+enum regnames {EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
+ PC /* also known as eip */,
+ PS /* also known as eflags */,
+ CS, SS, DS, ES, FS, GS};
+
+/*
+ * these should not be static cuz they can be used outside this module
+ */
+int registers[NUMREGS];
+
+#define STACKSIZE 10000
+int remcomStack[STACKSIZE/sizeof(int)];
+static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
+
+/*************************** ASSEMBLY CODE MACROS *************************/
+/* */
+
+extern void
+return_to_prog ();
+
+/* Restore the program's registers (including the stack pointer, which
+ means we get the right stack and don't have to worry about popping our
+ return address and any stack frames and so on) and return. */
+asm(".text");
+asm(".globl _return_to_prog");
+asm("_return_to_prog:");
+asm(" movw _registers+44, %ss");
+asm(" movl _registers+16, %esp");
+asm(" movl _registers+4, %ecx");
+asm(" movl _registers+8, %edx");
+asm(" movl _registers+12, %ebx");
+asm(" movl _registers+20, %ebp");
+asm(" movl _registers+24, %esi");
+asm(" movl _registers+28, %edi");
+asm(" movw _registers+48, %ds");
+asm(" movw _registers+52, %es");
+asm(" movw _registers+56, %fs");
+asm(" movw _registers+60, %gs");
+asm(" movl _registers+36, %eax");
+asm(" pushl %eax"); /* saved eflags */
+asm(" movl _registers+40, %eax");
+asm(" pushl %eax"); /* saved cs */
+asm(" movl _registers+32, %eax");
+asm(" pushl %eax"); /* saved eip */
+asm(" movl _registers, %eax");
+/* use iret to restore pc and flags together so
+ that trace flag works right. */
+asm(" iret");
+
+#define BREAKPOINT() asm(" int $3");
+
+/* Put the error code here just in case the user cares. */
+int gdb_i386errcode;
+/* Likewise, the vector number here (since GDB only gets the signal
+ number through the usual means, and that's not very specific). */
+int gdb_i386vector = -1;
+
+/* GDB stores segment registers in 32-bit words (that's just the way
+ m-i386v.h is written). So zero the appropriate areas in registers. */
+#define SAVE_REGISTERS1() \
+ asm ("movl %eax, _registers"); \
+ asm ("movl %ecx, _registers+4"); \
+ asm ("movl %edx, _registers+8"); \
+ asm ("movl %ebx, _registers+12"); \
+ asm ("movl %ebp, _registers+20"); \
+ asm ("movl %esi, _registers+24"); \
+ asm ("movl %edi, _registers+28"); \
+ asm ("movw $0, %ax"); \
+ asm ("movw %ds, _registers+48"); \
+ asm ("movw %ax, _registers+50"); \
+ asm ("movw %es, _registers+52"); \
+ asm ("movw %ax, _registers+54"); \
+ asm ("movw %fs, _registers+56"); \
+ asm ("movw %ax, _registers+58"); \
+ asm ("movw %gs, _registers+60"); \
+ asm ("movw %ax, _registers+62");
+#define SAVE_ERRCODE() \
+ asm ("popl %ebx"); \
+ asm ("movl %ebx, _gdb_i386errcode");
+#define SAVE_REGISTERS2() \
+ asm ("popl %ebx"); /* old eip */ \
+ asm ("movl %ebx, _registers+32"); \
+ asm ("popl %ebx"); /* old cs */ \
+ asm ("movl %ebx, _registers+40"); \
+ asm ("movw %ax, _registers+42"); \
+ asm ("popl %ebx"); /* old eflags */ \
+ asm ("movl %ebx, _registers+36"); \
+ /* Now that we've done the pops, we can save the stack pointer."); */ \
+ asm ("movw %ss, _registers+44"); \
+ asm ("movw %ax, _registers+46"); \
+ asm ("movl %esp, _registers+16");
+
+/* See if mem_fault_routine is set, if so just IRET to that address. */
+#define CHECK_FAULT() \
+ asm ("cmpl $0, _mem_fault_routine"); \
+ asm ("jne mem_fault");
+
+asm (".text");
+asm ("mem_fault:");
+/* OK to clobber temp registers; we're just going to end up in set_mem_err. */
+/* Pop error code from the stack and save it. */
+asm (" popl %eax");
+asm (" movl %eax, _gdb_i386errcode");
+
+asm (" popl %eax"); /* eip */
+/* We don't want to return there, we want to return to the function
+ pointed to by mem_fault_routine instead. */
+asm (" movl _mem_fault_routine, %eax");
+asm (" popl %ecx"); /* cs (low 16 bits; junk in hi 16 bits). */
+asm (" popl %edx"); /* eflags */
+
+/* Remove this stack frame; when we do the iret, we will be going to
+ the start of a function, so we want the stack to look just like it
+ would after a "call" instruction. */
+asm (" leave");
+
+/* Push the stuff that iret wants. */
+asm (" pushl %edx"); /* eflags */
+asm (" pushl %ecx"); /* cs */
+asm (" pushl %eax"); /* eip */
+
+/* Zero mem_fault_routine. */
+asm (" movl $0, %eax");
+asm (" movl %eax, _mem_fault_routine");
+
+asm ("iret");
+
+#define CALL_HOOK() asm("call _remcomHandler");
+
+/* This function is called when a i386 exception occurs. It saves
+ * all the cpu regs in the _registers array, munges the stack a bit,
+ * and invokes an exception handler (remcom_handler).
+ *
+ * stack on entry: stack on exit:
+ * old eflags vector number
+ * old cs (zero-filled to 32 bits)
+ * old eip
+ *
+ */
+extern void _catchException3();
+asm(".text");
+asm(".globl __catchException3");
+asm("__catchException3:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $3");
+CALL_HOOK();
+
+/* Same thing for exception 1. */
+extern void _catchException1();
+asm(".text");
+asm(".globl __catchException1");
+asm("__catchException1:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $1");
+CALL_HOOK();
+
+/* Same thing for exception 0. */
+extern void _catchException0();
+asm(".text");
+asm(".globl __catchException0");
+asm("__catchException0:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $0");
+CALL_HOOK();
+
+/* Same thing for exception 4. */
+extern void _catchException4();
+asm(".text");
+asm(".globl __catchException4");
+asm("__catchException4:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $4");
+CALL_HOOK();
+
+/* Same thing for exception 5. */
+extern void _catchException5();
+asm(".text");
+asm(".globl __catchException5");
+asm("__catchException5:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $5");
+CALL_HOOK();
+
+/* Same thing for exception 6. */
+extern void _catchException6();
+asm(".text");
+asm(".globl __catchException6");
+asm("__catchException6:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $6");
+CALL_HOOK();
+
+/* Same thing for exception 7. */
+extern void _catchException7();
+asm(".text");
+asm(".globl __catchException7");
+asm("__catchException7:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $7");
+CALL_HOOK();
+
+/* Same thing for exception 8. */
+extern void _catchException8();
+asm(".text");
+asm(".globl __catchException8");
+asm("__catchException8:");
+SAVE_REGISTERS1();
+SAVE_ERRCODE();
+SAVE_REGISTERS2();
+asm ("pushl $8");
+CALL_HOOK();
+
+/* Same thing for exception 9. */
+extern void _catchException9();
+asm(".text");
+asm(".globl __catchException9");
+asm("__catchException9:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $9");
+CALL_HOOK();
+
+/* Same thing for exception 10. */
+extern void _catchException10();
+asm(".text");
+asm(".globl __catchException10");
+asm("__catchException10:");
+SAVE_REGISTERS1();
+SAVE_ERRCODE();
+SAVE_REGISTERS2();
+asm ("pushl $10");
+CALL_HOOK();
+
+/* Same thing for exception 12. */
+extern void _catchException12();
+asm(".text");
+asm(".globl __catchException12");
+asm("__catchException12:");
+SAVE_REGISTERS1();
+SAVE_ERRCODE();
+SAVE_REGISTERS2();
+asm ("pushl $12");
+CALL_HOOK();
+
+/* Same thing for exception 16. */
+extern void _catchException16();
+asm(".text");
+asm(".globl __catchException16");
+asm("__catchException16:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $16");
+CALL_HOOK();
+
+/* For 13, 11, and 14 we have to deal with the CHECK_FAULT stuff. */
+
+/* Same thing for exception 13. */
+extern void _catchException13 ();
+asm (".text");
+asm (".globl __catchException13");
+asm ("__catchException13:");
+CHECK_FAULT();
+SAVE_REGISTERS1();
+SAVE_ERRCODE();
+SAVE_REGISTERS2();
+asm ("pushl $13");
+CALL_HOOK();
+
+/* Same thing for exception 11. */
+extern void _catchException11 ();
+asm (".text");
+asm (".globl __catchException11");
+asm ("__catchException11:");
+CHECK_FAULT();
+SAVE_REGISTERS1();
+SAVE_ERRCODE();
+SAVE_REGISTERS2();
+asm ("pushl $11");
+CALL_HOOK();
+
+/* Same thing for exception 14. */
+extern void _catchException14 ();
+asm (".text");
+asm (".globl __catchException14");
+asm ("__catchException14:");
+CHECK_FAULT();
+SAVE_REGISTERS1();
+SAVE_ERRCODE();
+SAVE_REGISTERS2();
+asm ("pushl $14");
+CALL_HOOK();
+
+/*
+ * remcomHandler is a front end for handle_exception. It moves the
+ * stack pointer into an area reserved for debugger use.
+ */
+asm("_remcomHandler:");
+asm(" popl %eax"); /* pop off return address */
+asm(" popl %eax"); /* get the exception number */
+asm(" movl _stackPtr, %esp"); /* move to remcom stack area */
+asm(" pushl %eax"); /* push exception onto stack */
+asm(" call _handle_exception"); /* this never returns */
+
+void
+_returnFromException ()
+{
+ return_to_prog ();
+}
+
+int
+hex (ch)
+ char ch;
+{
+ if ((ch >= 'a') && (ch <= 'f'))
+ return (ch - 'a' + 10);
+ if ((ch >= '0') && (ch <= '9'))
+ return (ch - '0');
+ if ((ch >= 'A') && (ch <= 'F'))
+ return (ch - 'A' + 10);
+ return (-1);
+}
+
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+/* scan for the sequence $<data>#<checksum> */
+
+unsigned char *
+getpacket (void)
+{
+ unsigned char *buffer = &remcomInBuffer[0];
+ unsigned char checksum;
+ unsigned char xmitcsum;
+ int count;
+ char ch;
+
+ while (1)
+ {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = getDebugChar ()) != '$')
+ ;
+
+ retry:
+ checksum = 0;
+ xmitcsum = -1;
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX)
+ {
+ ch = getDebugChar ();
+ if (ch == '$')
+ goto retry;
+ if (ch == '#')
+ break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+ buffer[count] = 0;
+
+ if (ch == '#')
+ {
+ ch = getDebugChar ();
+ xmitcsum = hex (ch) << 4;
+ ch = getDebugChar ();
+ xmitcsum += hex (ch);
+
+ if (checksum != xmitcsum)
+ {
+ if (remote_debug)
+ {
+ fprintf (stderr,
+ "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n",
+ checksum, xmitcsum, buffer);
+ }
+ putDebugChar ('-'); /* failed checksum */
+ }
+ else
+ {
+ putDebugChar ('+'); /* successful transfer */
+
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':')
+ {
+ putDebugChar (buffer[0]);
+ putDebugChar (buffer[1]);
+
+ return &buffer[3];
+ }
+
+ return &buffer[0];
+ }
+ }
+ }
+}
+
+/* send the packet in buffer. */
+
+void
+putpacket (unsigned char *buffer)
+{
+ unsigned char checksum;
+ int count;
+ char ch;
+
+ /* $<packet info>#<checksum>. */
+ do
+ {
+ putDebugChar ('$');
+ checksum = 0;
+ count = 0;
+
+ while (ch = buffer[count])
+ {
+ putDebugChar (ch);
+ checksum += ch;
+ count += 1;
+ }
+
+ putDebugChar ('#');
+ putDebugChar (hexchars[checksum >> 4]);
+ putDebugChar (hexchars[checksum % 16]);
+
+ }
+ while (getDebugChar () != '+');
+}
+
+void
+debug_error (format, parm)
+ char *format;
+ char *parm;
+{
+ if (remote_debug)
+ fprintf (stderr, format, parm);
+}
+
+/* Address of a routine to RTE to if we get a memory fault. */
+static void (*volatile mem_fault_routine) () = NULL;
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an
+ error. */
+static volatile int mem_err = 0;
+
+void
+set_mem_err (void)
+{
+ mem_err = 1;
+}
+
+/* These are separate functions so that they are so short and sweet
+ that the compiler won't save any registers (if there is a fault
+ to mem_fault, they won't get restored, so there better not be any
+ saved). */
+int
+get_char (char *addr)
+{
+ return *addr;
+}
+
+void
+set_char (char *addr, int val)
+{
+ *addr = val;
+}
+
+/* convert the memory pointed to by mem into hex, placing result in buf */
+/* return a pointer to the last char put in buf (null) */
+/* If MAY_FAULT is non-zero, then we should set mem_err in response to
+ a fault; if zero treat a fault like any other fault in the stub. */
+char *
+mem2hex (mem, buf, count, may_fault)
+ char *mem;
+ char *buf;
+ int count;
+ int may_fault;
+{
+ int i;
+ unsigned char ch;
+
+ if (may_fault)
+ mem_fault_routine = set_mem_err;
+ for (i = 0; i < count; i++)
+ {
+ ch = get_char (mem++);
+ if (may_fault && mem_err)
+ return (buf);
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch % 16];
+ }
+ *buf = 0;
+ if (may_fault)
+ mem_fault_routine = NULL;
+ return (buf);
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem */
+/* return a pointer to the character AFTER the last byte written */
+char *
+hex2mem (buf, mem, count, may_fault)
+ char *buf;
+ char *mem;
+ int count;
+ int may_fault;
+{
+ int i;
+ unsigned char ch;
+
+ if (may_fault)
+ mem_fault_routine = set_mem_err;
+ for (i = 0; i < count; i++)
+ {
+ ch = hex (*buf++) << 4;
+ ch = ch + hex (*buf++);
+ set_char (mem++, ch);
+ if (may_fault && mem_err)
+ return (mem);
+ }
+ if (may_fault)
+ mem_fault_routine = NULL;
+ return (mem);
+}
+
+/* this function takes the 386 exception vector and attempts to
+ translate this number into a unix compatible signal value */
+int
+computeSignal (int exceptionVector)
+{
+ int sigval;
+ switch (exceptionVector)
+ {
+ case 0:
+ sigval = 8;
+ break; /* divide by zero */
+ case 1:
+ sigval = 5;
+ break; /* debug exception */
+ case 3:
+ sigval = 5;
+ break; /* breakpoint */
+ case 4:
+ sigval = 16;
+ break; /* into instruction (overflow) */
+ case 5:
+ sigval = 16;
+ break; /* bound instruction */
+ case 6:
+ sigval = 4;
+ break; /* Invalid opcode */
+ case 7:
+ sigval = 8;
+ break; /* coprocessor not available */
+ case 8:
+ sigval = 7;
+ break; /* double fault */
+ case 9:
+ sigval = 11;
+ break; /* coprocessor segment overrun */
+ case 10:
+ sigval = 11;
+ break; /* Invalid TSS */
+ case 11:
+ sigval = 11;
+ break; /* Segment not present */
+ case 12:
+ sigval = 11;
+ break; /* stack exception */
+ case 13:
+ sigval = 11;
+ break; /* general protection */
+ case 14:
+ sigval = 11;
+ break; /* page fault */
+ case 16:
+ sigval = 7;
+ break; /* coprocessor error */
+ default:
+ sigval = 7; /* "software generated" */
+ }
+ return (sigval);
+}
+
+/**********************************************/
+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
+/* RETURN NUMBER OF CHARS PROCESSED */
+/**********************************************/
+int
+hexToInt (char **ptr, int *intValue)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+
+ while (**ptr)
+ {
+ hexValue = hex (**ptr);
+ if (hexValue >= 0)
+ {
+ *intValue = (*intValue << 4) | hexValue;
+ numChars++;
+ }
+ else
+ break;
+
+ (*ptr)++;
+ }
+
+ return (numChars);
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb.
+ */
+void
+handle_exception (int exceptionVector)
+{
+ int sigval, stepping;
+ int addr, length;
+ char *ptr;
+ int newPC;
+
+ gdb_i386vector = exceptionVector;
+
+ if (remote_debug)
+ {
+ printf ("vector=%d, sr=0x%x, pc=0x%x\n",
+ exceptionVector, registers[PS], registers[PC]);
+ }
+
+ /* reply to host that an exception has occurred */
+ sigval = computeSignal (exceptionVector);
+
+ ptr = remcomOutBuffer;
+
+ *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */
+ *ptr++ = hexchars[sigval >> 4];
+ *ptr++ = hexchars[sigval & 0xf];
+
+ *ptr++ = hexchars[ESP];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[ESP], ptr, 4, 0); /* SP */
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[EBP];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[EBP], ptr, 4, 0); /* FP */
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[PC];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[PC], ptr, 4, 0); /* PC */
+ *ptr++ = ';';
+
+ *ptr = '\0'
+
+ putpacket (remcomOutBuffer);
+
+ stepping = 0;
+
+ while (1 == 1)
+ {
+ remcomOutBuffer[0] = 0;
+ ptr = getpacket ();
+
+ switch (*ptr++)
+ {
+ case '?':
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval % 16];
+ remcomOutBuffer[3] = 0;
+ break;
+ case 'd':
+ remote_debug = !(remote_debug); /* toggle debug flag */
+ break;
+ case 'g': /* return the value of the CPU registers */
+ mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES, 0);
+ break;
+ case 'G': /* set the value of the CPU registers - return OK */
+ hex2mem (ptr, (char *) registers, NUMREGBYTES, 0);
+ strcpy (remcomOutBuffer, "OK");
+ break;
+ case 'P': /* set the value of a single CPU register - return OK */
+ {
+ int regno;
+
+ if (hexToInt (&ptr, &regno) && *ptr++ == '=')
+ if (regno >= 0 && regno < NUMREGS)
+ {
+ hex2mem (ptr, (char *) &registers[regno], 4, 0);
+ strcpy (remcomOutBuffer, "OK");
+ break;
+ }
+
+ strcpy (remcomOutBuffer, "E01");
+ break;
+ }
+
+ /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ case 'm':
+ /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
+ if (hexToInt (&ptr, &addr))
+ if (*(ptr++) == ',')
+ if (hexToInt (&ptr, &length))
+ {
+ ptr = 0;
+ mem_err = 0;
+ mem2hex ((char *) addr, remcomOutBuffer, length, 1);
+ if (mem_err)
+ {
+ strcpy (remcomOutBuffer, "E03");
+ debug_error ("memory fault");
+ }
+ }
+
+ if (ptr)
+ {
+ strcpy (remcomOutBuffer, "E01");
+ }
+ break;
+
+ /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ case 'M':
+ /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
+ if (hexToInt (&ptr, &addr))
+ if (*(ptr++) == ',')
+ if (hexToInt (&ptr, &length))
+ if (*(ptr++) == ':')
+ {
+ mem_err = 0;
+ hex2mem (ptr, (char *) addr, length, 1);
+
+ if (mem_err)
+ {
+ strcpy (remcomOutBuffer, "E03");
+ debug_error ("memory fault");
+ }
+ else
+ {
+ strcpy (remcomOutBuffer, "OK");
+ }
+
+ ptr = 0;
+ }
+ if (ptr)
+ {
+ strcpy (remcomOutBuffer, "E02");
+ }
+ break;
+
+ /* cAA..AA Continue at address AA..AA(optional) */
+ /* sAA..AA Step one instruction from AA..AA(optional) */
+ case 's':
+ stepping = 1;
+ case 'c':
+ /* try to read optional parameter, pc unchanged if no parm */
+ if (hexToInt (&ptr, &addr))
+ registers[PC] = addr;
+
+ newPC = registers[PC];
+
+ /* clear the trace bit */
+ registers[PS] &= 0xfffffeff;
+
+ /* set the trace bit if we're stepping */
+ if (stepping)
+ registers[PS] |= 0x100;
+
+ _returnFromException (); /* this is a jump */
+ break;
+
+ /* kill the program */
+ case 'k': /* do nothing */
+#if 0
+ /* Huh? This doesn't look like "nothing".
+ m68k-stub.c and sparc-stub.c don't have it. */
+ BREAKPOINT ();
+#endif
+ break;
+ } /* switch */
+
+ /* reply to the request */
+ putpacket (remcomOutBuffer);
+ }
+}
+
+/* this function is used to set up exception handlers for tracing and
+ breakpoints */
+void
+set_debug_traps (void)
+{
+ stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
+
+ exceptionHandler (0, _catchException0);
+ exceptionHandler (1, _catchException1);
+ exceptionHandler (3, _catchException3);
+ exceptionHandler (4, _catchException4);
+ exceptionHandler (5, _catchException5);
+ exceptionHandler (6, _catchException6);
+ exceptionHandler (7, _catchException7);
+ exceptionHandler (8, _catchException8);
+ exceptionHandler (9, _catchException9);
+ exceptionHandler (10, _catchException10);
+ exceptionHandler (11, _catchException11);
+ exceptionHandler (12, _catchException12);
+ exceptionHandler (13, _catchException13);
+ exceptionHandler (14, _catchException14);
+ exceptionHandler (16, _catchException16);
+
+ initialized = 1;
+}
+
+/* This function will generate a breakpoint exception. It is used at the
+ beginning of a program to sync up with a debugger and can be used
+ otherwise as a quick means to stop program execution and "break" into
+ the debugger. */
+
+void
+breakpoint (void)
+{
+ if (initialized)
+ BREAKPOINT ();
+}
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
new file mode 100644
index 00000000000..54746eeb865
--- /dev/null
+++ b/gdb/i386-tdep.c
@@ -0,0 +1,1547 @@
+/* Intel 386 target-dependent stuff.
+
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+#include "gdb_string.h"
+#include "frame.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "floatformat.h"
+#include "symtab.h"
+#include "gdbcmd.h"
+#include "command.h"
+#include "arch-utils.h"
+#include "regcache.h"
+#include "doublest.h"
+#include "value.h"
+#include "gdb_assert.h"
+
+#include "elf-bfd.h"
+
+#include "i386-tdep.h"
+
+/* Names of the registers. The first 10 registers match the register
+ numbering scheme used by GCC for stabs and DWARF. */
+static char *i386_register_names[] =
+{
+ "eax", "ecx", "edx", "ebx",
+ "esp", "ebp", "esi", "edi",
+ "eip", "eflags", "cs", "ss",
+ "ds", "es", "fs", "gs",
+ "st0", "st1", "st2", "st3",
+ "st4", "st5", "st6", "st7",
+ "fctrl", "fstat", "ftag", "fiseg",
+ "fioff", "foseg", "fooff", "fop",
+ "xmm0", "xmm1", "xmm2", "xmm3",
+ "xmm4", "xmm5", "xmm6", "xmm7",
+ "mxcsr"
+};
+
+/* i386_register_offset[i] is the offset into the register file of the
+ start of register number i. We initialize this from
+ i386_register_size. */
+static int i386_register_offset[MAX_NUM_REGS];
+
+/* i386_register_size[i] is the number of bytes of storage in GDB's
+ register array occupied by register i. */
+static int i386_register_size[MAX_NUM_REGS] = {
+ 4, 4, 4, 4,
+ 4, 4, 4, 4,
+ 4, 4, 4, 4,
+ 4, 4, 4, 4,
+ 10, 10, 10, 10,
+ 10, 10, 10, 10,
+ 4, 4, 4, 4,
+ 4, 4, 4, 4,
+ 16, 16, 16, 16,
+ 16, 16, 16, 16,
+ 4
+};
+
+/* Return the name of register REG. */
+
+char *
+i386_register_name (int reg)
+{
+ if (reg < 0)
+ return NULL;
+ if (reg >= sizeof (i386_register_names) / sizeof (*i386_register_names))
+ return NULL;
+
+ return i386_register_names[reg];
+}
+
+/* Return the offset into the register array of the start of register
+ number REG. */
+int
+i386_register_byte (int reg)
+{
+ return i386_register_offset[reg];
+}
+
+/* Return the number of bytes of storage in GDB's register array
+ occupied by register REG. */
+
+int
+i386_register_raw_size (int reg)
+{
+ return i386_register_size[reg];
+}
+
+/* Return the size in bytes of the virtual type of register REG. */
+
+int
+i386_register_virtual_size (int reg)
+{
+ return TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (reg));
+}
+
+/* Convert stabs register number REG to the appropriate register
+ number used by GDB. */
+
+int
+i386_stab_reg_to_regnum (int reg)
+{
+ /* This implements what GCC calls the "default" register map. */
+ if (reg >= 0 && reg <= 7)
+ {
+ /* General registers. */
+ return reg;
+ }
+ else if (reg >= 12 && reg <= 19)
+ {
+ /* Floating-point registers. */
+ return reg - 12 + FP0_REGNUM;
+ }
+ else if (reg >= 21 && reg <= 28)
+ {
+ /* SSE registers. */
+ return reg - 21 + XMM0_REGNUM;
+ }
+ else if (reg >= 29 && reg <= 36)
+ {
+ /* MMX registers. */
+ /* FIXME: kettenis/2001-07-28: Should we have the MMX registers
+ as pseudo-registers? */
+ return reg - 29 + FP0_REGNUM;
+ }
+
+ /* This will hopefully provoke a warning. */
+ return NUM_REGS + NUM_PSEUDO_REGS;
+}
+
+/* Convert Dwarf register number REG to the appropriate register
+ number used by GDB. */
+
+int
+i386_dwarf_reg_to_regnum (int reg)
+{
+ /* The DWARF register numbering includes %eip and %eflags, and
+ numbers the floating point registers differently. */
+ if (reg >= 0 && reg <= 9)
+ {
+ /* General registers. */
+ return reg;
+ }
+ else if (reg >= 11 && reg <= 18)
+ {
+ /* Floating-point registers. */
+ return reg - 11 + FP0_REGNUM;
+ }
+ else if (reg >= 21)
+ {
+ /* The SSE and MMX registers have identical numbers as in stabs. */
+ return i386_stab_reg_to_regnum (reg);
+ }
+
+ /* This will hopefully provoke a warning. */
+ return NUM_REGS + NUM_PSEUDO_REGS;
+}
+
+
+/* This is the variable that is set with "set disassembly-flavor", and
+ its legitimate values. */
+static const char att_flavor[] = "att";
+static const char intel_flavor[] = "intel";
+static const char *valid_flavors[] =
+{
+ att_flavor,
+ intel_flavor,
+ NULL
+};
+static const char *disassembly_flavor = att_flavor;
+
+/* Stdio style buffering was used to minimize calls to ptrace, but
+ this buffering did not take into account that the code section
+ being accessed may not be an even number of buffers long (even if
+ the buffer is only sizeof(int) long). In cases where the code
+ section size happened to be a non-integral number of buffers long,
+ attempting to read the last buffer would fail. Simply using
+ target_read_memory and ignoring errors, rather than read_memory, is
+ not the correct solution, since legitimate access errors would then
+ be totally ignored. To properly handle this situation and continue
+ to use buffering would require that this code be able to determine
+ the minimum code section size granularity (not the alignment of the
+ section itself, since the actual failing case that pointed out this
+ problem had a section alignment of 4 but was not a multiple of 4
+ bytes long), on a target by target basis, and then adjust it's
+ buffer size accordingly. This is messy, but potentially feasible.
+ It probably needs the bfd library's help and support. For now, the
+ buffer size is set to 1. (FIXME -fnf) */
+
+#define CODESTREAM_BUFSIZ 1 /* Was sizeof(int), see note above. */
+static CORE_ADDR codestream_next_addr;
+static CORE_ADDR codestream_addr;
+static unsigned char codestream_buf[CODESTREAM_BUFSIZ];
+static int codestream_off;
+static int codestream_cnt;
+
+#define codestream_tell() (codestream_addr + codestream_off)
+#define codestream_peek() \
+ (codestream_cnt == 0 ? \
+ codestream_fill(1) : codestream_buf[codestream_off])
+#define codestream_get() \
+ (codestream_cnt-- == 0 ? \
+ codestream_fill(0) : codestream_buf[codestream_off++])
+
+static unsigned char
+codestream_fill (int peek_flag)
+{
+ codestream_addr = codestream_next_addr;
+ codestream_next_addr += CODESTREAM_BUFSIZ;
+ codestream_off = 0;
+ codestream_cnt = CODESTREAM_BUFSIZ;
+ read_memory (codestream_addr, (char *) codestream_buf, CODESTREAM_BUFSIZ);
+
+ if (peek_flag)
+ return (codestream_peek ());
+ else
+ return (codestream_get ());
+}
+
+static void
+codestream_seek (CORE_ADDR place)
+{
+ codestream_next_addr = place / CODESTREAM_BUFSIZ;
+ codestream_next_addr *= CODESTREAM_BUFSIZ;
+ codestream_cnt = 0;
+ codestream_fill (1);
+ while (codestream_tell () != place)
+ codestream_get ();
+}
+
+static void
+codestream_read (unsigned char *buf, int count)
+{
+ unsigned char *p;
+ int i;
+ p = buf;
+ for (i = 0; i < count; i++)
+ *p++ = codestream_get ();
+}
+
+
+/* If the next instruction is a jump, move to its target. */
+
+static void
+i386_follow_jump (void)
+{
+ unsigned char buf[4];
+ long delta;
+
+ int data16;
+ CORE_ADDR pos;
+
+ pos = codestream_tell ();
+
+ data16 = 0;
+ if (codestream_peek () == 0x66)
+ {
+ codestream_get ();
+ data16 = 1;
+ }
+
+ switch (codestream_get ())
+ {
+ case 0xe9:
+ /* Relative jump: if data16 == 0, disp32, else disp16. */
+ if (data16)
+ {
+ codestream_read (buf, 2);
+ delta = extract_signed_integer (buf, 2);
+
+ /* Include the size of the jmp instruction (including the
+ 0x66 prefix). */
+ pos += delta + 4;
+ }
+ else
+ {
+ codestream_read (buf, 4);
+ delta = extract_signed_integer (buf, 4);
+
+ pos += delta + 5;
+ }
+ break;
+ case 0xeb:
+ /* Relative jump, disp8 (ignore data16). */
+ codestream_read (buf, 1);
+ /* Sign-extend it. */
+ delta = extract_signed_integer (buf, 1);
+
+ pos += delta + 2;
+ break;
+ }
+ codestream_seek (pos);
+}
+
+/* Find & return the amount a local space allocated, and advance the
+ codestream to the first register push (if any).
+
+ If the entry sequence doesn't make sense, return -1, and leave
+ codestream pointer at a random spot. */
+
+static long
+i386_get_frame_setup (CORE_ADDR pc)
+{
+ unsigned char op;
+
+ codestream_seek (pc);
+
+ i386_follow_jump ();
+
+ op = codestream_get ();
+
+ if (op == 0x58) /* popl %eax */
+ {
+ /* This function must start with
+
+ popl %eax 0x58
+ xchgl %eax, (%esp) 0x87 0x04 0x24
+ or xchgl %eax, 0(%esp) 0x87 0x44 0x24 0x00
+
+ (the System V compiler puts out the second `xchg'
+ instruction, and the assembler doesn't try to optimize it, so
+ the 'sib' form gets generated). This sequence is used to get
+ the address of the return buffer for a function that returns
+ a structure. */
+ int pos;
+ unsigned char buf[4];
+ static unsigned char proto1[3] = { 0x87, 0x04, 0x24 };
+ static unsigned char proto2[4] = { 0x87, 0x44, 0x24, 0x00 };
+
+ pos = codestream_tell ();
+ codestream_read (buf, 4);
+ if (memcmp (buf, proto1, 3) == 0)
+ pos += 3;
+ else if (memcmp (buf, proto2, 4) == 0)
+ pos += 4;
+
+ codestream_seek (pos);
+ op = codestream_get (); /* Update next opcode. */
+ }
+
+ if (op == 0x68 || op == 0x6a)
+ {
+ /* This function may start with
+
+ pushl constant
+ call _probe
+ addl $4, %esp
+
+ followed by
+
+ pushl %ebp
+
+ etc. */
+ int pos;
+ unsigned char buf[8];
+
+ /* Skip past the `pushl' instruction; it has either a one-byte
+ or a four-byte operand, depending on the opcode. */
+ pos = codestream_tell ();
+ if (op == 0x68)
+ pos += 4;
+ else
+ pos += 1;
+ codestream_seek (pos);
+
+ /* Read the following 8 bytes, which should be "call _probe" (6
+ bytes) followed by "addl $4,%esp" (2 bytes). */
+ codestream_read (buf, sizeof (buf));
+ if (buf[0] == 0xe8 && buf[6] == 0xc4 && buf[7] == 0x4)
+ pos += sizeof (buf);
+ codestream_seek (pos);
+ op = codestream_get (); /* Update next opcode. */
+ }
+
+ if (op == 0x55) /* pushl %ebp */
+ {
+ /* Check for "movl %esp, %ebp" -- can be written in two ways. */
+ switch (codestream_get ())
+ {
+ case 0x8b:
+ if (codestream_get () != 0xec)
+ return -1;
+ break;
+ case 0x89:
+ if (codestream_get () != 0xe5)
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+ /* Check for stack adjustment
+
+ subl $XXX, %esp
+
+ NOTE: You can't subtract a 16 bit immediate from a 32 bit
+ reg, so we don't have to worry about a data16 prefix. */
+ op = codestream_peek ();
+ if (op == 0x83)
+ {
+ /* `subl' with 8 bit immediate. */
+ codestream_get ();
+ if (codestream_get () != 0xec)
+ /* Some instruction starting with 0x83 other than `subl'. */
+ {
+ codestream_seek (codestream_tell () - 2);
+ return 0;
+ }
+ /* `subl' with signed byte immediate (though it wouldn't
+ make sense to be negative). */
+ return (codestream_get ());
+ }
+ else if (op == 0x81)
+ {
+ char buf[4];
+ /* Maybe it is `subl' with a 32 bit immedediate. */
+ codestream_get ();
+ if (codestream_get () != 0xec)
+ /* Some instruction starting with 0x81 other than `subl'. */
+ {
+ codestream_seek (codestream_tell () - 2);
+ return 0;
+ }
+ /* It is `subl' with a 32 bit immediate. */
+ codestream_read ((unsigned char *) buf, 4);
+ return extract_signed_integer (buf, 4);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else if (op == 0xc8)
+ {
+ char buf[2];
+ /* `enter' with 16 bit unsigned immediate. */
+ codestream_read ((unsigned char *) buf, 2);
+ codestream_get (); /* Flush final byte of enter instruction. */
+ return extract_unsigned_integer (buf, 2);
+ }
+ return (-1);
+}
+
+/* Return the chain-pointer for FRAME. In the case of the i386, the
+ frame's nominal address is the address of a 4-byte word containing
+ the calling frame's address. */
+
+CORE_ADDR
+i386_frame_chain (struct frame_info *frame)
+{
+ if (frame->signal_handler_caller)
+ return frame->frame;
+
+ if (! inside_entry_file (frame->pc))
+ return read_memory_unsigned_integer (frame->frame, 4);
+
+ return 0;
+}
+
+/* Determine whether the function invocation represented by FRAME does
+ not have a from on the stack associated with it. If it does not,
+ return non-zero, otherwise return zero. */
+
+int
+i386_frameless_function_invocation (struct frame_info *frame)
+{
+ if (frame->signal_handler_caller)
+ return 0;
+
+ return frameless_look_for_prologue (frame);
+}
+
+/* Return the saved program counter for FRAME. */
+
+CORE_ADDR
+i386_frame_saved_pc (struct frame_info *frame)
+{
+ /* FIXME: kettenis/2001-05-09: Conditionalizing the next bit of code
+ on SIGCONTEXT_PC_OFFSET and I386V4_SIGTRAMP_SAVED_PC should be
+ considered a temporary hack. I plan to come up with something
+ better when we go multi-arch. */
+#if defined (SIGCONTEXT_PC_OFFSET) || defined (I386V4_SIGTRAMP_SAVED_PC)
+ if (frame->signal_handler_caller)
+ return sigtramp_saved_pc (frame);
+#endif
+
+ return read_memory_unsigned_integer (frame->frame + 4, 4);
+}
+
+CORE_ADDR
+i386go32_frame_saved_pc (struct frame_info *frame)
+{
+ return read_memory_integer (frame->frame + 4, 4);
+}
+
+/* Immediately after a function call, return the saved pc. */
+
+CORE_ADDR
+i386_saved_pc_after_call (struct frame_info *frame)
+{
+ return read_memory_unsigned_integer (read_register (SP_REGNUM), 4);
+}
+
+/* Return number of args passed to a frame.
+ Can return -1, meaning no way to tell. */
+
+int
+i386_frame_num_args (struct frame_info *fi)
+{
+#if 1
+ return -1;
+#else
+ /* This loses because not only might the compiler not be popping the
+ args right after the function call, it might be popping args from
+ both this call and a previous one, and we would say there are
+ more args than there really are. */
+
+ int retpc;
+ unsigned char op;
+ struct frame_info *pfi;
+
+ /* On the i386, the instruction following the call could be:
+ popl %ecx - one arg
+ addl $imm, %esp - imm/4 args; imm may be 8 or 32 bits
+ anything else - zero args. */
+
+ int frameless;
+
+ frameless = FRAMELESS_FUNCTION_INVOCATION (fi);
+ if (frameless)
+ /* In the absence of a frame pointer, GDB doesn't get correct
+ values for nameless arguments. Return -1, so it doesn't print
+ any nameless arguments. */
+ return -1;
+
+ pfi = get_prev_frame (fi);
+ if (pfi == 0)
+ {
+ /* NOTE: This can happen if we are looking at the frame for
+ main, because FRAME_CHAIN_VALID won't let us go into start.
+ If we have debugging symbols, that's not really a big deal;
+ it just means it will only show as many arguments to main as
+ are declared. */
+ return -1;
+ }
+ else
+ {
+ retpc = pfi->pc;
+ op = read_memory_integer (retpc, 1);
+ if (op == 0x59) /* pop %ecx */
+ return 1;
+ else if (op == 0x83)
+ {
+ op = read_memory_integer (retpc + 1, 1);
+ if (op == 0xc4)
+ /* addl $<signed imm 8 bits>, %esp */
+ return (read_memory_integer (retpc + 2, 1) & 0xff) / 4;
+ else
+ return 0;
+ }
+ else if (op == 0x81) /* `add' with 32 bit immediate. */
+ {
+ op = read_memory_integer (retpc + 1, 1);
+ if (op == 0xc4)
+ /* addl $<imm 32>, %esp */
+ return read_memory_integer (retpc + 2, 4) / 4;
+ else
+ return 0;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+#endif
+}
+
+/* Parse the first few instructions the function to see what registers
+ were stored.
+
+ We handle these cases:
+
+ The startup sequence can be at the start of the function, or the
+ function can start with a branch to startup code at the end.
+
+ %ebp can be set up with either the 'enter' instruction, or "pushl
+ %ebp, movl %esp, %ebp" (`enter' is too slow to be useful, but was
+ once used in the System V compiler).
+
+ Local space is allocated just below the saved %ebp by either the
+ 'enter' instruction, or by "subl $<size>, %esp". 'enter' has a 16
+ bit unsigned argument for space to allocate, and the 'addl'
+ instruction could have either a signed byte, or 32 bit immediate.
+
+ Next, the registers used by this function are pushed. With the
+ System V compiler they will always be in the order: %edi, %esi,
+ %ebx (and sometimes a harmless bug causes it to also save but not
+ restore %eax); however, the code below is willing to see the pushes
+ in any order, and will handle up to 8 of them.
+
+ If the setup sequence is at the end of the function, then the next
+ instruction will be a branch back to the start. */
+
+void
+i386_frame_init_saved_regs (struct frame_info *fip)
+{
+ long locals = -1;
+ unsigned char op;
+ CORE_ADDR dummy_bottom;
+ CORE_ADDR addr;
+ CORE_ADDR pc;
+ int i;
+
+ if (fip->saved_regs)
+ return;
+
+ frame_saved_regs_zalloc (fip);
+
+ /* If the frame is the end of a dummy, compute where the beginning
+ would be. */
+ dummy_bottom = fip->frame - 4 - REGISTER_BYTES - CALL_DUMMY_LENGTH;
+
+ /* Check if the PC points in the stack, in a dummy frame. */
+ if (dummy_bottom <= fip->pc && fip->pc <= fip->frame)
+ {
+ /* All registers were saved by push_call_dummy. */
+ addr = fip->frame;
+ for (i = 0; i < NUM_REGS; i++)
+ {
+ addr -= REGISTER_RAW_SIZE (i);
+ fip->saved_regs[i] = addr;
+ }
+ return;
+ }
+
+ pc = get_pc_function_start (fip->pc);
+ if (pc != 0)
+ locals = i386_get_frame_setup (pc);
+
+ if (locals >= 0)
+ {
+ addr = fip->frame - 4 - locals;
+ for (i = 0; i < 8; i++)
+ {
+ op = codestream_get ();
+ if (op < 0x50 || op > 0x57)
+ break;
+#ifdef I386_REGNO_TO_SYMMETRY
+ /* Dynix uses different internal numbering. Ick. */
+ fip->saved_regs[I386_REGNO_TO_SYMMETRY (op - 0x50)] = addr;
+#else
+ fip->saved_regs[op - 0x50] = addr;
+#endif
+ addr -= 4;
+ }
+ }
+
+ fip->saved_regs[PC_REGNUM] = fip->frame + 4;
+ fip->saved_regs[FP_REGNUM] = fip->frame;
+}
+
+/* Return PC of first real instruction. */
+
+int
+i386_skip_prologue (int pc)
+{
+ unsigned char op;
+ int i;
+ static unsigned char pic_pat[6] =
+ { 0xe8, 0, 0, 0, 0, /* call 0x0 */
+ 0x5b, /* popl %ebx */
+ };
+ CORE_ADDR pos;
+
+ if (i386_get_frame_setup (pc) < 0)
+ return (pc);
+
+ /* Found valid frame setup -- codestream now points to start of push
+ instructions for saving registers. */
+
+ /* Skip over register saves. */
+ for (i = 0; i < 8; i++)
+ {
+ op = codestream_peek ();
+ /* Break if not `pushl' instrunction. */
+ if (op < 0x50 || op > 0x57)
+ break;
+ codestream_get ();
+ }
+
+ /* The native cc on SVR4 in -K PIC mode inserts the following code
+ to get the address of the global offset table (GOT) into register
+ %ebx
+
+ call 0x0
+ popl %ebx
+ movl %ebx,x(%ebp) (optional)
+ addl y,%ebx
+
+ This code is with the rest of the prologue (at the end of the
+ function), so we have to skip it to get to the first real
+ instruction at the start of the function. */
+
+ pos = codestream_tell ();
+ for (i = 0; i < 6; i++)
+ {
+ op = codestream_get ();
+ if (pic_pat[i] != op)
+ break;
+ }
+ if (i == 6)
+ {
+ unsigned char buf[4];
+ long delta = 6;
+
+ op = codestream_get ();
+ if (op == 0x89) /* movl %ebx, x(%ebp) */
+ {
+ op = codestream_get ();
+ if (op == 0x5d) /* One byte offset from %ebp. */
+ {
+ delta += 3;
+ codestream_read (buf, 1);
+ }
+ else if (op == 0x9d) /* Four byte offset from %ebp. */
+ {
+ delta += 6;
+ codestream_read (buf, 4);
+ }
+ else /* Unexpected instruction. */
+ delta = -1;
+ op = codestream_get ();
+ }
+ /* addl y,%ebx */
+ if (delta > 0 && op == 0x81 && codestream_get () == 0xc3)
+ {
+ pos += delta + 6;
+ }
+ }
+ codestream_seek (pos);
+
+ i386_follow_jump ();
+
+ return (codestream_tell ());
+}
+
+void
+i386_push_dummy_frame (void)
+{
+ CORE_ADDR sp = read_register (SP_REGNUM);
+ CORE_ADDR fp;
+ int regnum;
+ char regbuf[MAX_REGISTER_RAW_SIZE];
+
+ sp = push_word (sp, read_register (PC_REGNUM));
+ sp = push_word (sp, read_register (FP_REGNUM));
+ fp = sp;
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ {
+ read_register_gen (regnum, regbuf);
+ sp = push_bytes (sp, regbuf, REGISTER_RAW_SIZE (regnum));
+ }
+ write_register (SP_REGNUM, sp);
+ write_register (FP_REGNUM, fp);
+}
+
+/* Insert the (relative) function address into the call sequence
+ stored at DYMMY. */
+
+void
+i386_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+ struct value **args, struct type *type, int gcc_p)
+{
+ int from, to, delta, loc;
+
+ loc = (int)(read_register (SP_REGNUM) - CALL_DUMMY_LENGTH);
+ from = loc + 5;
+ to = (int)(fun);
+ delta = to - from;
+
+ *((char *)(dummy) + 1) = (delta & 0xff);
+ *((char *)(dummy) + 2) = ((delta >> 8) & 0xff);
+ *((char *)(dummy) + 3) = ((delta >> 16) & 0xff);
+ *((char *)(dummy) + 4) = ((delta >> 24) & 0xff);
+}
+
+void
+i386_pop_frame (void)
+{
+ struct frame_info *frame = get_current_frame ();
+ CORE_ADDR fp;
+ int regnum;
+ char regbuf[MAX_REGISTER_RAW_SIZE];
+
+ fp = FRAME_FP (frame);
+ i386_frame_init_saved_regs (frame);
+
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ {
+ CORE_ADDR addr;
+ addr = frame->saved_regs[regnum];
+ if (addr)
+ {
+ read_memory (addr, regbuf, REGISTER_RAW_SIZE (regnum));
+ write_register_bytes (REGISTER_BYTE (regnum), regbuf,
+ REGISTER_RAW_SIZE (regnum));
+ }
+ }
+ write_register (FP_REGNUM, read_memory_integer (fp, 4));
+ write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
+ write_register (SP_REGNUM, fp + 8);
+ flush_cached_frames ();
+}
+
+
+#ifdef GET_LONGJMP_TARGET
+
+/* FIXME: Multi-arching does not set JB_PC and JB_ELEMENT_SIZE yet.
+ Fill in with dummy value to enable compilation. */
+#ifndef JB_PC
+#define JB_PC 0
+#endif /* JB_PC */
+
+#ifndef JB_ELEMENT_SIZE
+#define JB_ELEMENT_SIZE 4
+#endif /* JB_ELEMENT_SIZE */
+
+/* Figure out where the longjmp will land. Slurp the args out of the
+ stack. We expect the first arg to be a pointer to the jmp_buf
+ structure from which we extract the pc (JB_PC) that we will land
+ at. The pc is copied into PC. This routine returns true on
+ success. */
+
+int
+get_longjmp_target (CORE_ADDR *pc)
+{
+ char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
+ CORE_ADDR sp, jb_addr;
+
+ sp = read_register (SP_REGNUM);
+
+ if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack. */
+ buf,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ return 1;
+}
+
+#endif /* GET_LONGJMP_TARGET */
+
+
+CORE_ADDR
+i386_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ sp = default_push_arguments (nargs, args, sp, struct_return, struct_addr);
+
+ if (struct_return)
+ {
+ char buf[4];
+
+ sp -= 4;
+ store_address (buf, 4, struct_addr);
+ write_memory (sp, buf, 4);
+ }
+
+ return sp;
+}
+
+void
+i386_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ /* Do nothing. Everything was already done by i386_push_arguments. */
+}
+
+/* These registers are used for returning integers (and on some
+ targets also for returning `struct' and `union' values when their
+ size and alignment match an integer type). */
+#define LOW_RETURN_REGNUM 0 /* %eax */
+#define HIGH_RETURN_REGNUM 2 /* %edx */
+
+/* Extract from an array REGBUF containing the (raw) register state, a
+ function return value of TYPE, and copy that, in virtual format,
+ into VALBUF. */
+
+void
+i386_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ int len = TYPE_LENGTH (type);
+
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ && TYPE_NFIELDS (type) == 1)
+ {
+ i386_extract_return_value (TYPE_FIELD_TYPE (type, 0), regbuf, valbuf);
+ return;
+ }
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
+ if (NUM_FREGS == 0)
+ {
+ warning ("Cannot find floating-point return value.");
+ memset (valbuf, 0, len);
+ return;
+ }
+
+ /* Floating-point return values can be found in %st(0). Convert
+ its contents to the desired type. This is probably not
+ exactly how it would happen on the target itself, but it is
+ the best we can do. */
+ convert_typed_floating (&regbuf[REGISTER_BYTE (FP0_REGNUM)],
+ builtin_type_i387_ext, valbuf, type);
+ }
+ else
+ {
+ int low_size = REGISTER_RAW_SIZE (LOW_RETURN_REGNUM);
+ int high_size = REGISTER_RAW_SIZE (HIGH_RETURN_REGNUM);
+
+ if (len <= low_size)
+ memcpy (valbuf, &regbuf[REGISTER_BYTE (LOW_RETURN_REGNUM)], len);
+ else if (len <= (low_size + high_size))
+ {
+ memcpy (valbuf,
+ &regbuf[REGISTER_BYTE (LOW_RETURN_REGNUM)], low_size);
+ memcpy (valbuf + low_size,
+ &regbuf[REGISTER_BYTE (HIGH_RETURN_REGNUM)], len - low_size);
+ }
+ else
+ internal_error (__FILE__, __LINE__,
+ "Cannot extract return value of %d bytes long.", len);
+ }
+}
+
+/* Write into the appropriate registers a function return value stored
+ in VALBUF of type TYPE, given in virtual format. */
+
+void
+i386_store_return_value (struct type *type, char *valbuf)
+{
+ int len = TYPE_LENGTH (type);
+
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ && TYPE_NFIELDS (type) == 1)
+ {
+ i386_store_return_value (TYPE_FIELD_TYPE (type, 0), valbuf);
+ return;
+ }
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
+ unsigned int fstat;
+ char buf[FPU_REG_RAW_SIZE];
+
+ if (NUM_FREGS == 0)
+ {
+ warning ("Cannot set floating-point return value.");
+ return;
+ }
+
+ /* Returning floating-point values is a bit tricky. Apart from
+ storing the return value in %st(0), we have to simulate the
+ state of the FPU at function return point. */
+
+ /* Convert the value found in VALBUF to the extended
+ floating-point format used by the FPU. This is probably
+ not exactly how it would happen on the target itself, but
+ it is the best we can do. */
+ convert_typed_floating (valbuf, type, buf, builtin_type_i387_ext);
+ write_register_bytes (REGISTER_BYTE (FP0_REGNUM), buf,
+ FPU_REG_RAW_SIZE);
+
+ /* Set the top of the floating-point register stack to 7. The
+ actual value doesn't really matter, but 7 is what a normal
+ function return would end up with if the program started out
+ with a freshly initialized FPU. */
+ fstat = read_register (FSTAT_REGNUM);
+ fstat |= (7 << 11);
+ write_register (FSTAT_REGNUM, fstat);
+
+ /* Mark %st(1) through %st(7) as empty. Since we set the top of
+ the floating-point register stack to 7, the appropriate value
+ for the tag word is 0x3fff. */
+ write_register (FTAG_REGNUM, 0x3fff);
+ }
+ else
+ {
+ int low_size = REGISTER_RAW_SIZE (LOW_RETURN_REGNUM);
+ int high_size = REGISTER_RAW_SIZE (HIGH_RETURN_REGNUM);
+
+ if (len <= low_size)
+ write_register_bytes (REGISTER_BYTE (LOW_RETURN_REGNUM), valbuf, len);
+ else if (len <= (low_size + high_size))
+ {
+ write_register_bytes (REGISTER_BYTE (LOW_RETURN_REGNUM),
+ valbuf, low_size);
+ write_register_bytes (REGISTER_BYTE (HIGH_RETURN_REGNUM),
+ valbuf + low_size, len - low_size);
+ }
+ else
+ internal_error (__FILE__, __LINE__,
+ "Cannot store return value of %d bytes long.", len);
+ }
+}
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR. */
+
+CORE_ADDR
+i386_extract_struct_value_address (char *regbuf)
+{
+ return extract_address (&regbuf[REGISTER_BYTE (LOW_RETURN_REGNUM)],
+ REGISTER_RAW_SIZE (LOW_RETURN_REGNUM));
+}
+
+
+/* Return the GDB type object for the "standard" data type of data in
+ register REGNUM. Perhaps %esi and %edi should go here, but
+ potentially they could be used for things other than address. */
+
+struct type *
+i386_register_virtual_type (int regnum)
+{
+ if (regnum == PC_REGNUM || regnum == FP_REGNUM || regnum == SP_REGNUM)
+ return lookup_pointer_type (builtin_type_void);
+
+ if (IS_FP_REGNUM (regnum))
+ return builtin_type_i387_ext;
+
+ if (IS_SSE_REGNUM (regnum))
+ return builtin_type_vec128i;
+
+ return builtin_type_int;
+}
+
+/* Return true iff register REGNUM's virtual format is different from
+ its raw format. Note that this definition assumes that the host
+ supports IEEE 32-bit floats, since it doesn't say that SSE
+ registers need conversion. Even if we can't find a counterexample,
+ this is still sloppy. */
+
+int
+i386_register_convertible (int regnum)
+{
+ return IS_FP_REGNUM (regnum);
+}
+
+/* Convert data from raw format for register REGNUM in buffer FROM to
+ virtual format with type TYPE in buffer TO. */
+
+void
+i386_register_convert_to_virtual (int regnum, struct type *type,
+ char *from, char *to)
+{
+ gdb_assert (IS_FP_REGNUM (regnum));
+
+ /* We only support floating-point values. */
+ if (TYPE_CODE (type) != TYPE_CODE_FLT)
+ {
+ warning ("Cannot convert floating-point register value "
+ "to non-floating-point type.");
+ memset (to, 0, TYPE_LENGTH (type));
+ return;
+ }
+
+ /* Convert to TYPE. This should be a no-op if TYPE is equivalent to
+ the extended floating-point format used by the FPU. */
+ convert_typed_floating (from, builtin_type_i387_ext, to, type);
+}
+
+/* Convert data from virtual format with type TYPE in buffer FROM to
+ raw format for register REGNUM in buffer TO. */
+
+void
+i386_register_convert_to_raw (struct type *type, int regnum,
+ char *from, char *to)
+{
+ gdb_assert (IS_FP_REGNUM (regnum));
+
+ /* We only support floating-point values. */
+ if (TYPE_CODE (type) != TYPE_CODE_FLT)
+ {
+ warning ("Cannot convert non-floating-point type "
+ "to floating-point register value.");
+ memset (to, 0, TYPE_LENGTH (type));
+ return;
+ }
+
+ /* Convert from TYPE. This should be a no-op if TYPE is equivalent
+ to the extended floating-point format used by the FPU. */
+ convert_typed_floating (from, type, to, builtin_type_i387_ext);
+}
+
+
+#ifdef I386V4_SIGTRAMP_SAVED_PC
+/* Get saved user PC for sigtramp from the pushed ucontext on the
+ stack for all three variants of SVR4 sigtramps. */
+
+CORE_ADDR
+i386v4_sigtramp_saved_pc (struct frame_info *frame)
+{
+ CORE_ADDR saved_pc_offset = 4;
+ char *name = NULL;
+
+ find_pc_partial_function (frame->pc, &name, NULL, NULL);
+ if (name)
+ {
+ if (STREQ (name, "_sigreturn"))
+ saved_pc_offset = 132 + 14 * 4;
+ else if (STREQ (name, "_sigacthandler"))
+ saved_pc_offset = 80 + 14 * 4;
+ else if (STREQ (name, "sigvechandler"))
+ saved_pc_offset = 120 + 14 * 4;
+ }
+
+ if (frame->next)
+ return read_memory_integer (frame->next->frame + saved_pc_offset, 4);
+ return read_memory_integer (read_register (SP_REGNUM) + saved_pc_offset, 4);
+}
+#endif /* I386V4_SIGTRAMP_SAVED_PC */
+
+
+#ifdef STATIC_TRANSFORM_NAME
+/* SunPRO encodes the static variables. This is not related to C++
+ mangling, it is done for C too. */
+
+char *
+sunpro_static_transform_name (char *name)
+{
+ char *p;
+ if (IS_STATIC_TRANSFORM_NAME (name))
+ {
+ /* For file-local statics there will be a period, a bunch of
+ junk (the contents of which match a string given in the
+ N_OPT), a period and the name. For function-local statics
+ there will be a bunch of junk (which seems to change the
+ second character from 'A' to 'B'), a period, the name of the
+ function, and the name. So just skip everything before the
+ last period. */
+ p = strrchr (name, '.');
+ if (p != NULL)
+ name = p + 1;
+ }
+ return name;
+}
+#endif /* STATIC_TRANSFORM_NAME */
+
+
+/* Stuff for WIN32 PE style DLL's but is pretty generic really. */
+
+CORE_ADDR
+skip_trampoline_code (CORE_ADDR pc, char *name)
+{
+ if (pc && read_memory_unsigned_integer (pc, 2) == 0x25ff) /* jmp *(dest) */
+ {
+ unsigned long indirect = read_memory_unsigned_integer (pc + 2, 4);
+ struct minimal_symbol *indsym =
+ indirect ? lookup_minimal_symbol_by_pc (indirect) : 0;
+ char *symname = indsym ? SYMBOL_NAME (indsym) : 0;
+
+ if (symname)
+ {
+ if (strncmp (symname, "__imp_", 6) == 0
+ || strncmp (symname, "_imp_", 5) == 0)
+ return name ? 1 : read_memory_unsigned_integer (indirect, 4);
+ }
+ }
+ return 0; /* Not a trampoline. */
+}
+
+
+/* We have two flavours of disassembly. The machinery on this page
+ deals with switching between those. */
+
+static int
+gdb_print_insn_i386 (bfd_vma memaddr, disassemble_info *info)
+{
+ if (disassembly_flavor == att_flavor)
+ return print_insn_i386_att (memaddr, info);
+ else if (disassembly_flavor == intel_flavor)
+ return print_insn_i386_intel (memaddr, info);
+ /* Never reached -- disassembly_flavour is always either att_flavor
+ or intel_flavor. */
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+}
+
+
+/* This table matches the indices assigned to enum i386_abi. Keep
+ them in sync. */
+static const char * const i386_abi_names[] =
+{
+ "<unknown>",
+ "SVR4",
+ "NetBSD",
+ "GNU/Linux",
+ "GNU/Hurd",
+ "Solaris",
+ "FreeBSD",
+ NULL
+};
+
+
+#define ABI_TAG_OS_GNU_LINUX I386_ABI_LINUX
+#define ABI_TAG_OS_GNU_HURD I386_ABI_HURD
+#define ABI_TAG_OS_GNU_SOLARIS I386_ABI_INVALID
+#define ABI_TAG_OS_FREEBSD I386_ABI_FREEBSD
+#define ABI_TAG_OS_NETBSD I386_ABI_NETBSD
+
+static void
+process_note_sections (bfd *abfd, asection *sect, void *obj)
+{
+ int *abi = obj;
+ const char *name;
+ unsigned int sectsize;
+
+ name = bfd_get_section_name (abfd, sect);
+ sectsize = bfd_section_size (abfd, sect);
+
+ if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
+ {
+ unsigned int name_length, data_length, note_type;
+ char *note;
+
+ /* If the section is larger than this, it's probably not what we
+ are looking for. */
+ if (sectsize > 128)
+ sectsize = 128;
+
+ note = alloca (sectsize);
+
+ bfd_get_section_contents (abfd, sect, note,
+ (file_ptr) 0, (bfd_size_type) sectsize);
+
+ name_length = bfd_h_get_32 (abfd, note);
+ data_length = bfd_h_get_32 (abfd, note + 4);
+ note_type = bfd_h_get_32 (abfd, note + 8);
+
+ if (name_length == 4 && data_length == 16
+ && note_type == NT_GNU_ABI_TAG
+ && strcmp (note + 12, "GNU") == 0)
+ {
+ int abi_tag_os = bfd_h_get_32 (abfd, note + 16);
+
+ /* The case numbers are from abi-tags in glibc. */
+ switch (abi_tag_os)
+ {
+ case GNU_ABI_TAG_LINUX:
+ *abi = ABI_TAG_OS_GNU_LINUX;
+ break;
+
+ case GNU_ABI_TAG_HURD:
+ *abi = ABI_TAG_OS_GNU_HURD;
+ break;
+
+ case GNU_ABI_TAG_SOLARIS:
+ *abi = ABI_TAG_OS_GNU_SOLARIS;
+ break;
+
+ default:
+ internal_error
+ (__FILE__, __LINE__,
+ "process_note_abi_sections: unknown ABI OS tag %d",
+ abi_tag_os);
+ break;
+ }
+ }
+ else if (name_length == 8 && data_length == 4
+ && note_type == NT_FREEBSD_ABI_TAG
+ && strcmp (note + 12, "FreeBSD") == 0)
+ *abi = ABI_TAG_OS_FREEBSD;
+ }
+ /* NetBSD uses a similar trick. */
+ else if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0)
+ {
+ unsigned int name_length, desc_length, note_type;
+ char *note;
+
+ /* If the section is larger than this, it's probably not what we are
+ looking for. */
+ if (sectsize > 128)
+ sectsize = 128;
+
+ note = alloca (sectsize);
+
+ bfd_get_section_contents (abfd, sect, note,
+ (file_ptr) 0, (bfd_size_type) sectsize);
+
+ name_length = bfd_h_get_32 (abfd, note);
+ desc_length = bfd_h_get_32 (abfd, note + 4);
+ note_type = bfd_h_get_32 (abfd, note + 8);
+
+ if (name_length == 7 && desc_length == 4
+ && note_type == NT_NETBSD_IDENT
+ && strcmp (note + 12, "NetBSD") == 0)
+ *abi = ABI_TAG_OS_NETBSD;
+ }
+}
+
+static int
+i386_elf_abi_from_note (bfd *abfd)
+{
+ enum i386_abi abi = I386_ABI_UNKNOWN;
+
+ bfd_map_over_sections (abfd, process_note_sections, &abi);
+
+ return abi;
+}
+
+static enum i386_abi
+i386_elf_abi (bfd *abfd)
+{
+ int elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
+
+ /* The fact that the EI_OSABI byte is set to ELFOSABI_NONE doesn't
+ necessarily mean that this is a System V ELF binary. To further
+ distinguish between binaries for differens operating systems,
+ check for vendor-specific note elements. */
+ if (elfosabi == ELFOSABI_NONE)
+ {
+ enum i386_abi abi = i386_elf_abi_from_note (abfd);
+
+ if (abi != I386_ABI_UNKNOWN)
+ return abi;
+
+ /* FreeBSD folks are naughty; they stored the string "FreeBSD"
+ in the padding of the e_ident field of the ELF header. */
+ if (strcmp (&elf_elfheader (abfd)->e_ident[8], "FreeBSD") == 0)
+ return I386_ABI_FREEBSD;
+ }
+
+ switch (elfosabi)
+ {
+ case ELFOSABI_NONE:
+ return I386_ABI_SVR4;
+ case ELFOSABI_FREEBSD:
+ return I386_ABI_FREEBSD;
+ }
+
+ return I386_ABI_UNKNOWN;
+}
+
+struct i386_abi_handler
+{
+ struct i386_abi_handler *next;
+ enum i386_abi abi;
+ void (*init_abi)(struct gdbarch_info, struct gdbarch *);
+};
+
+struct i386_abi_handler *i386_abi_handler_list = NULL;
+
+void
+i386_gdbarch_register_os_abi (enum i386_abi abi,
+ void (*init_abi)(struct gdbarch_info,
+ struct gdbarch *))
+{
+ struct i386_abi_handler **handler_p;
+
+ for (handler_p = &i386_abi_handler_list; *handler_p != NULL;
+ handler_p = &(*handler_p)->next)
+ {
+ if ((*handler_p)->abi == abi)
+ {
+ internal_error
+ (__FILE__, __LINE__,
+ "i386_gdbarch_register_abi: A handler for this ABI variant "
+ "(%d) has already been registered", (int) abi);
+ /* If user wants to continue, override previous definition. */
+ (*handler_p)->init_abi = init_abi;
+ return;
+ }
+ }
+ (*handler_p)
+ = (struct i386_abi_handler *) xmalloc (sizeof (struct i386_abi_handler));
+ (*handler_p)->next = NULL;
+ (*handler_p)->abi = abi;
+ (*handler_p)->init_abi = init_abi;
+}
+
+struct gdbarch *
+i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch_tdep *tdep;
+ struct gdbarch *gdbarch;
+ enum i386_abi abi = I386_ABI_UNKNOWN;
+ struct i386_abi_handler *abi_handler;
+
+ if (info.abfd != NULL)
+ {
+ switch (bfd_get_flavour (info.abfd))
+ {
+ case bfd_target_elf_flavour:
+ abi= i386_elf_abi (info.abfd);
+ break;
+
+ default:
+ /* Not sure what to do here, leave the ABI as unknown. */
+ break;
+ }
+ }
+
+ /* Find a candidate among extant architectures. */
+ for (arches = gdbarch_list_lookup_by_info (arches, &info);
+ arches != NULL;
+ arches = gdbarch_list_lookup_by_info (arches->next, &info))
+ {
+ /* Make sure the ABI selection matches. */
+ tdep = gdbarch_tdep (arches->gdbarch);
+ if (tdep && tdep->abi == abi)
+ return arches->gdbarch;
+ }
+
+ /* Allocate space for the new architecture. */
+ tdep = XMALLOC (struct gdbarch_tdep);
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ tdep->abi = abi;
+
+ /* FIXME: kettenis/2001-11-24: Although not all IA-32 processors
+ have the SSE registers, it's easier to set the default to 8. */
+ tdep->num_xmm_regs = 8;
+
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
+
+ /* Call dummy code. */
+ set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 5);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+
+ set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+ set_gdbarch_push_arguments (gdbarch, i386_push_arguments);
+
+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
+
+ /* NOTE: tm-i386nw.h and tm-i386v4.h override this. */
+ set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
+
+ /* NOTE: tm-i386aix.h, tm-i386bsd.h, tm-i386os9k.h, tm-linux.h,
+ tm-ptx.h, tm-symmetry.h currently override this. Sigh. */
+ set_gdbarch_num_regs (gdbarch, NUM_GREGS + NUM_FREGS + NUM_SSE_REGS);
+
+ /* Hook in ABI-specific overrides, if they have been registered. */
+ if (abi == I386_ABI_UNKNOWN)
+ {
+ /* Don't complain about not knowing the ABI variant if we don't
+ have an inferior. */
+ if (info.abfd)
+ fprintf_filtered
+ (gdb_stderr, "GDB doesn't recognize the ABI of the inferior. "
+ "Attempting to continue with the default i386 settings");
+ }
+ else
+ {
+ for (abi_handler = i386_abi_handler_list; abi_handler != NULL;
+ abi_handler = abi_handler->next)
+ if (abi_handler->abi == abi)
+ break;
+
+ if (abi_handler)
+ abi_handler->init_abi (info, gdbarch);
+ else
+ {
+ /* We assume that if GDB_MULTI_ARCH is less than
+ GDB_MULTI_ARCH_TM that an ABI variant can be supported by
+ overriding definitions in this file. */
+ if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ fprintf_filtered
+ (gdb_stderr,
+ "A handler for the ABI variant \"%s\" is not built into this "
+ "configuration of GDB. "
+ "Attempting to continue with the default i386 settings",
+ i386_abi_names[abi]);
+ }
+ }
+
+ return gdbarch;
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_i386_tdep (void);
+
+void
+_initialize_i386_tdep (void)
+{
+ register_gdbarch_init (bfd_arch_i386, i386_gdbarch_init);
+
+ /* Initialize the table saying where each register starts in the
+ register file. */
+ {
+ int i, offset;
+
+ offset = 0;
+ for (i = 0; i < MAX_NUM_REGS; i++)
+ {
+ i386_register_offset[i] = offset;
+ offset += i386_register_size[i];
+ }
+ }
+
+ tm_print_insn = gdb_print_insn_i386;
+ tm_print_insn_info.mach = bfd_lookup_arch (bfd_arch_i386, 0)->mach;
+
+ /* Add the variable that controls the disassembly flavor. */
+ {
+ struct cmd_list_element *new_cmd;
+
+ new_cmd = add_set_enum_cmd ("disassembly-flavor", no_class,
+ valid_flavors,
+ &disassembly_flavor,
+ "\
+Set the disassembly flavor, the valid values are \"att\" and \"intel\", \
+and the default value is \"att\".",
+ &setlist);
+ add_show_from_set (new_cmd, &showlist);
+ }
+}
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
new file mode 100644
index 00000000000..0bdbb057e2f
--- /dev/null
+++ b/gdb/i386-tdep.h
@@ -0,0 +1,136 @@
+/* Target-dependent code for GDB, the GNU debugger.
+ Copyright 2001
+ 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. */
+
+#ifndef I386_TDEP_H
+#define I386_TDEP_H
+
+/* GDB's i386 target supports both the 32-bit Intel Architecture
+ (IA-32) and the 64-bit AMD x86-64 architecture. Internally it uses
+ a similar register layout for both.
+
+ - General purpose registers
+ - FPU data registers
+ - FPU control registers
+ - SSE data registers
+ - SSE control register
+
+ The general purpose registers for the x86-64 architecture are quite
+ different from IA-32. Therefore, the FP0_REGNUM target macro
+ determines the register number at which the FPU data registers
+ start. The number of FPU data and control registers is the same
+ for both architectures. The number of SSE registers however,
+ differs and is determined by the num_xmm_regs member of `struct
+ gdbarch_tdep'. */
+
+/* ABI variants that we know about. */
+enum i386_abi
+{
+ I386_ABI_UNKNOWN = 0,
+
+ /* ELF */
+ I386_ABI_SVR4, /* This is the default. */
+ I386_ABI_NETBSD,
+ I386_ABI_LINUX,
+ I386_ABI_HURD,
+ I386_ABI_SOLARIS,
+ I386_ABI_FREEBSD,
+
+ I386_ABI_INVALID = -1
+};
+
+/* i386 architecture specific information. */
+struct gdbarch_tdep
+{
+ /* ABI. */
+ enum i386_abi abi;
+
+ /* Number of SSE registers. */
+ int num_xmm_regs;
+};
+
+/* Floating-point registers. */
+
+#define FPU_REG_RAW_SIZE 10
+
+/* All FPU control regusters (except for FIOFF and FOOFF) are 16-bit
+ (at most) in the FPU, but are zero-extended to 32 bits in GDB's
+ register cache. */
+
+/* "Generic" floating point control register. */
+#define FPC_REGNUM (FP0_REGNUM + 8)
+
+/* FPU control word. */
+#define FCTRL_REGNUM FPC_REGNUM
+
+/* FPU status word. */
+#define FSTAT_REGNUM (FPC_REGNUM + 1)
+
+/* FPU register tag word. */
+#define FTAG_REGNUM (FPC_REGNUM + 2)
+
+/* FPU instruction's code segment selector, called "FPU Instruction
+ Pointer Selector" in the IA-32 manuals. */
+#define FISEG_REGNUM (FPC_REGNUM + 3)
+
+/* FPU instruction's offset within segment. */
+#define FIOFF_REGNUM (FPC_REGNUM + 4)
+
+/* FPU operand's data segment. */
+#define FOSEG_REGNUM (FPC_REGNUM + 5)
+
+/* FPU operand's offset within segment */
+#define FOOFF_REGNUM (FPC_REGNUM + 6)
+
+/* FPU opcode, bottom eleven bits. */
+#define FOP_REGNUM (FPC_REGNUM + 7)
+
+/* Return non-zero if N corresponds to a FPU data registers. */
+#define FP_REGNUM_P(n) (FP0_REGNUM <= (n) && (n) < FPC_REGNUM)
+
+/* Return non-zero if N corresponds to a FPU control register. */
+#define FPC_REGNUM_P(n) (FPC_REGNUM <= (n) && (n) < XMM0_REGNUM)
+
+/* SSE registers. */
+
+/* First SSE data register. */
+#define XMM0_REGNUM (FPC_REGNUM + 8)
+
+/* SSE control/status register. */
+#define MXCSR_REGNUM \
+ (XMM0_REGNUM + gdbarch_tdep (current_gdbarch)->num_xmm_regs)
+
+/* Return non-zero if N corresponds to a SSE data register. */
+#define SSE_REGNUM_P(n) (XMM0_REGNUM <= (n) && (n) < MXCSR_REGNUM)
+
+/* FIXME: kettenis/2001-11-24: Obsolete macro's. */
+#define FCS_REGNUM FISEG_REGNUM
+#define FCOFF_REGNUM FIOFF_REGNUM
+#define FDS_REGNUM FOSEG_REGNUM
+#define FDOFF_REGNUM FOOFF_REGNUM
+#define IS_FP_REGNUM(n) FP_REGNUM_P (n)
+#define IS_FPU_CTRL_REGNUM(n) FPC_REGNUM_P (n)
+#define IS_SSE_REGNUM(n) SSE_REGNUM_P (n)
+
+void i386_gdbarch_register_os_abi (enum i386_abi,
+ void (*init_abi)(struct gdbarch_info,
+ struct gdbarch *));
+
+#endif /* i386-tdep.h */
diff --git a/gdb/i386aix-nat.c b/gdb/i386aix-nat.c
new file mode 100644
index 00000000000..2d8d7b9c710
--- /dev/null
+++ b/gdb/i386aix-nat.c
@@ -0,0 +1,377 @@
+/* Intel 386 native support.
+ Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
+ 2000, 2001 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "language.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/user.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+#include <sys/file.h>
+#include "gdb_stat.h"
+
+#include <stddef.h>
+#include <sys/ptrace.h>
+
+/* Does AIX define this in <errno.h>? */
+extern int errno;
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+#include "floatformat.h"
+
+#include "target.h"
+
+static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
+
+
+/* this table must line up with REGISTER_NAMES in tm-i386v.h */
+/* symbols like 'EAX' come from <sys/reg.h> */
+static int regmap[] =
+{
+ EAX, ECX, EDX, EBX,
+ USP, EBP, ESI, EDI,
+ EIP, EFL, CS, SS,
+ DS, ES, FS, GS,
+};
+
+/* blockend is the value of u.u_ar0, and points to the
+ * place where GS is stored
+ */
+
+int
+i386_register_u_addr (int blockend, int regnum)
+{
+#if 0
+ /* this will be needed if fp registers are reinstated */
+ /* for now, you can look at them with 'info float'
+ * sys5 wont let you change them with ptrace anyway
+ */
+ if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM)
+ {
+ int ubase, fpstate;
+ struct user u;
+ ubase = blockend + 4 * (SS + 1) - KSTKSZ;
+ fpstate = ubase + ((char *) &u.u_fpstate - (char *) &u);
+ return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM));
+ }
+ else
+#endif
+ return (blockend + 4 * regmap[regnum]);
+
+}
+
+/* The code below only work on the aix ps/2 (i386-ibm-aix) -
+ * mtranle@paris - Sat Apr 11 10:34:12 1992
+ */
+
+struct env387
+{
+ unsigned short control;
+ unsigned short r0;
+ unsigned short status;
+ unsigned short r1;
+ unsigned short tag;
+ unsigned short r2;
+ unsigned long eip;
+ unsigned short code_seg;
+ unsigned short opcode;
+ unsigned long operand;
+ unsigned short operand_seg;
+ unsigned short r3;
+ unsigned char regs[8][10];
+};
+
+static
+print_387_status (unsigned short status, struct env387 *ep)
+{
+ int i;
+ int bothstatus;
+ int top;
+ int fpreg;
+ unsigned char *p;
+
+ bothstatus = ((status != 0) && (ep->status != 0));
+ if (status != 0)
+ {
+ if (bothstatus)
+ printf_unfiltered ("u: ");
+ print_387_status_word (status);
+ }
+
+ if (ep->status != 0)
+ {
+ if (bothstatus)
+ printf_unfiltered ("e: ");
+ print_387_status_word (ep->status);
+ }
+
+ print_387_control_word (ep->control);
+ printf_unfiltered ("last exception: ");
+ printf_unfiltered ("opcode %s; ", local_hex_string (ep->opcode));
+ printf_unfiltered ("pc %s:", local_hex_string (ep->code_seg));
+ printf_unfiltered ("%s; ", local_hex_string (ep->eip));
+ printf_unfiltered ("operand %s", local_hex_string (ep->operand_seg));
+ printf_unfiltered (":%s\n", local_hex_string (ep->operand));
+
+ top = ((ep->status >> 11) & 7);
+
+ printf_unfiltered ("regno tag msb lsb value\n");
+ for (fpreg = 7; fpreg >= 0; fpreg--)
+ {
+ double val;
+
+ printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
+
+ switch ((ep->tag >> ((7 - fpreg) * 2)) & 3)
+ {
+ case 0:
+ printf_unfiltered ("valid ");
+ break;
+ case 1:
+ printf_unfiltered ("zero ");
+ break;
+ case 2:
+ printf_unfiltered ("trap ");
+ break;
+ case 3:
+ printf_unfiltered ("empty ");
+ break;
+ }
+ for (i = 9; i >= 0; i--)
+ printf_unfiltered ("%02x", ep->regs[fpreg][i]);
+
+ i387_to_double ((char *) ep->regs[fpreg], (char *) &val);
+ printf_unfiltered (" %#g\n", val);
+ }
+}
+
+static struct env387 core_env387;
+
+void
+i386_float_info (void)
+{
+ struct env387 fps;
+ int fpsaved = 0;
+ /* We need to reverse the order of the registers. Apparently AIX stores
+ the highest-numbered ones first. */
+ struct env387 fps_fixed;
+ int i;
+
+ if (! ptid_equal (inferior_ptid, null_ptid))
+ {
+ char buf[10];
+ unsigned short status;
+
+ ptrace (PT_READ_FPR, PIDGET (inferior_ptid), buf,
+ offsetof (struct env387, status));
+ memcpy (&status, buf, sizeof (status));
+ fpsaved = status;
+ }
+ else
+ {
+ if ((fpsaved = core_env387.status) != 0)
+ memcpy (&fps, &core_env387, sizeof (fps));
+ }
+
+ if (fpsaved == 0)
+ {
+ printf_unfiltered ("no floating point status saved\n");
+ return;
+ }
+
+ if (! ptid_equal (inferior_ptid, null_ptid))
+ {
+ int offset;
+ for (offset = 0; offset < sizeof (fps); offset += 10)
+ {
+ char buf[10];
+ ptrace (PT_READ_FPR, PIDGET (inferior_ptid), buf, offset);
+ memcpy ((char *) &fps.control + offset, buf,
+ MIN (10, sizeof (fps) - offset));
+ }
+ }
+ fps_fixed = fps;
+ for (i = 0; i < 8; ++i)
+ memcpy (fps_fixed.regs[i], fps.regs[7 - i], 10);
+ print_387_status (0, &fps_fixed);
+}
+
+/* Fetch one register. */
+static void
+fetch_register (int regno)
+{
+ char buf[MAX_REGISTER_RAW_SIZE];
+ if (regno < FP0_REGNUM)
+ *(int *) buf = ptrace (PT_READ_GPR, PIDGET (inferior_ptid),
+ PT_REG (regmap[regno]), 0, 0);
+ else
+ ptrace (PT_READ_FPR, PIDGET (inferior_ptid), buf,
+ (regno - FP0_REGNUM) * 10 + offsetof (struct env387, regs));
+ supply_register (regno, buf);
+}
+
+void
+fetch_inferior_registers (int regno)
+{
+ if (regno < 0)
+ for (regno = 0; regno < NUM_REGS; regno++)
+ fetch_register (regno);
+ else
+ fetch_register (regno);
+}
+
+/* store one register */
+static void
+store_register (int regno)
+{
+ char buf[80];
+ errno = 0;
+ if (regno < FP0_REGNUM)
+ ptrace (PT_WRITE_GPR, PIDGET (inferior_ptid), PT_REG (regmap[regno]),
+ *(int *) &registers[REGISTER_BYTE (regno)], 0);
+ else
+ ptrace (PT_WRITE_FPR, PIDGET (inferior_ptid),
+ &registers[REGISTER_BYTE (regno)],
+ (regno - FP0_REGNUM) * 10 + offsetof (struct env387, regs));
+
+ if (errno != 0)
+ {
+ sprintf (buf, "writing register number %d", regno);
+ perror_with_name (buf);
+ }
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+void
+store_inferior_registers (int regno)
+{
+ if (regno < 0)
+ for (regno = 0; regno < NUM_REGS; regno++)
+ store_register (regno);
+ else
+ store_register (regno);
+}
+
+#ifndef CD_AX /* defined in sys/i386/coredump.h */
+#define CD_AX 0
+#define CD_BX 1
+#define CD_CX 2
+#define CD_DX 3
+#define CD_SI 4
+#define CD_DI 5
+#define CD_BP 6
+#define CD_SP 7
+#define CD_FL 8
+#define CD_IP 9
+#define CD_CS 10
+#define CD_DS 11
+#define CD_ES 12
+#define CD_FS 13
+#define CD_GS 14
+#define CD_SS 15
+#endif
+
+/*
+ * The order here in core_regmap[] has to be the same as in
+ * regmap[] above.
+ */
+static int core_regmap[] =
+{
+ CD_AX, CD_CX, CD_DX, CD_BX,
+ CD_SP, CD_BP, CD_SI, CD_DI,
+ CD_IP, CD_FL, CD_CS, CD_SS,
+ CD_DS, CD_ES, CD_FS, CD_GS,
+};
+
+/* Provide registers to GDB from a core file.
+
+ CORE_REG_SECT points to an array of bytes, which were obtained from
+ a core file which BFD thinks might contain register contents.
+ CORE_REG_SIZE is its size.
+
+ WHICH says which register set corelow suspects this is:
+ 0 --- the general-purpose register set
+ 2 --- the floating-point register set
+
+ REG_ADDR isn't used. */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+
+ if (which == 0)
+ {
+ /* Integer registers */
+
+#define cd_regs(n) ((int *)core_reg_sect)[n]
+#define regs(n) *((int *) &registers[REGISTER_BYTE (n)])
+
+ int i;
+ for (i = 0; i < FP0_REGNUM; i++)
+ regs (i) = cd_regs (core_regmap[i]);
+ }
+ else if (which == 2)
+ {
+ /* Floating point registers */
+
+ if (core_reg_size >= sizeof (core_env387))
+ memcpy (&core_env387, core_reg_sect, core_reg_size);
+ else
+ fprintf_unfiltered (gdb_stderr, "Couldn't read float regs from core file\n");
+ }
+}
+
+
+/* Register that we are able to handle i386aix core file formats.
+ FIXME: is this really bfd_target_unknown_flavour? */
+
+static struct core_fns i386aix_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_i386aix (void)
+{
+ add_core_fns (&i386aix_core_fns);
+}
diff --git a/gdb/i386b-nat.c b/gdb/i386b-nat.c
new file mode 100644
index 00000000000..be8fd4508d4
--- /dev/null
+++ b/gdb/i386b-nat.c
@@ -0,0 +1,291 @@
+/* Native-dependent code for BSD Unix running on i386's, for GDB.
+ Copyright 1988, 1989, 1991, 1992, 1994, 1995, 1996, 1998, 1999, 2000,
+ 2001 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 "defs.h"
+
+#ifdef FETCH_INFERIOR_REGISTERS
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+#include "inferior.h"
+#include "gdbcore.h" /* for registers_fetched() */
+#include "regcache.h"
+
+void
+fetch_inferior_registers (int regno)
+{
+ struct reg inferior_registers;
+
+ ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0);
+ memcpy (&registers[REGISTER_BYTE (0)], &inferior_registers, 4 * NUM_REGS);
+ registers_fetched ();
+}
+
+void
+store_inferior_registers (int regno)
+{
+ struct reg inferior_registers;
+
+ memcpy (&inferior_registers, &registers[REGISTER_BYTE (0)], 4 * NUM_REGS);
+ ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0);
+}
+
+struct md_core
+{
+ struct reg intreg;
+ struct fpreg freg;
+};
+
+void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR ignore)
+{
+ struct md_core *core_reg = (struct md_core *) core_reg_sect;
+
+ /* integer registers */
+ memcpy (&registers[REGISTER_BYTE (0)], &core_reg->intreg,
+ sizeof (struct reg));
+ /* floating point registers */
+ /* XXX */
+}
+
+#else
+
+#include <machine/reg.h>
+
+/* this table must line up with REGISTER_NAMES in tm-i386.h */
+/* symbols like 'tEAX' come from <machine/reg.h> */
+static int tregmap[] =
+{
+ tEAX, tECX, tEDX, tEBX,
+ tESP, tEBP, tESI, tEDI,
+ tEIP, tEFLAGS, tCS, tSS
+};
+
+#ifdef sEAX
+static int sregmap[] =
+{
+ sEAX, sECX, sEDX, sEBX,
+ sESP, sEBP, sESI, sEDI,
+ sEIP, sEFLAGS, sCS, sSS
+};
+#else /* No sEAX */
+
+/* FreeBSD has decided to collapse the s* and t* symbols. So if the s*
+ ones aren't around, use the t* ones for sregmap too. */
+
+static int sregmap[] =
+{
+ tEAX, tECX, tEDX, tEBX,
+ tESP, tEBP, tESI, tEDI,
+ tEIP, tEFLAGS, tCS, tSS
+};
+#endif /* No sEAX */
+
+/* blockend is the value of u.u_ar0, and points to the
+ place where ES is stored. */
+
+int
+i386_register_u_addr (int blockend, int regnum)
+{
+ /* The following condition is a kludge to get at the proper register map
+ depending upon the state of pcb_flag.
+ The proper condition would be
+ if (u.u_pcb.pcb_flag & FM_TRAP)
+ but that would require a ptrace call here and wouldn't work
+ for corefiles. */
+
+ if (blockend < 0x1fcc)
+ return (blockend + 4 * tregmap[regnum]);
+ else
+ return (blockend + 4 * sregmap[regnum]);
+}
+
+#endif /* !FETCH_INFERIOR_REGISTERS */
+
+#ifdef FLOAT_INFO
+#include "expression.h"
+#include "language.h" /* for local_hex_string */
+#include "floatformat.h"
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+#include <a.out.h>
+
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/uio.h>
+#define curpcb Xcurpcb /* XXX avoid leaking declaration from pcb.h */
+#include <sys/user.h>
+#undef curpcb
+#include <sys/file.h>
+#include "gdb_stat.h"
+#include <sys/ptrace.h>
+
+extern void print_387_control_word (); /* i387-tdep.h */
+extern void print_387_status_word ();
+
+#define fpstate save87
+#define U_FPSTATE(u) u.u_pcb.pcb_savefpu
+
+struct env387
+ {
+ unsigned short control;
+ unsigned short r0;
+ unsigned short status;
+ unsigned short r1;
+ unsigned short tag;
+ unsigned short r2;
+ unsigned long eip;
+ unsigned short code_seg;
+ unsigned short opcode;
+ unsigned long operand;
+ unsigned short operand_seg;
+ unsigned short r3;
+ unsigned char regs[8][10];
+ };
+
+static void
+print_387_status (unsigned short status, struct env387 *ep)
+{
+ int i;
+ int bothstatus;
+ int top;
+ int fpreg;
+
+ bothstatus = ((status != 0) && (ep->status != 0));
+ if (status != 0)
+ {
+ if (bothstatus)
+ printf_unfiltered ("u: ");
+ print_387_status_word ((unsigned int) status);
+ }
+
+ if (ep->status != 0)
+ {
+ if (bothstatus)
+ printf_unfiltered ("e: ");
+ print_387_status_word ((unsigned int) ep->status);
+ }
+
+ print_387_control_word ((unsigned int) ep->control);
+ printf_unfiltered ("last exception: ");
+ printf_unfiltered ("opcode %s; ", local_hex_string (ep->opcode));
+ printf_unfiltered ("pc %s:", local_hex_string (ep->code_seg));
+ printf_unfiltered ("%s; ", local_hex_string (ep->eip));
+ printf_unfiltered ("operand %s", local_hex_string (ep->operand_seg));
+ printf_unfiltered (":%s\n", local_hex_string (ep->operand));
+
+ top = (ep->status >> 11) & 7;
+
+ printf_unfiltered ("regno tag msb lsb value\n");
+ for (fpreg = 7; fpreg >= 0; fpreg--)
+ {
+ double val;
+
+ printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
+
+ switch ((ep->tag >> (fpreg * 2)) & 3)
+ {
+ case 0:
+ printf_unfiltered ("valid ");
+ break;
+ case 1:
+ printf_unfiltered ("zero ");
+ break;
+ case 2:
+ printf_unfiltered ("trap ");
+ break;
+ case 3:
+ printf_unfiltered ("empty ");
+ break;
+ }
+ for (i = 9; i >= 0; i--)
+ printf_unfiltered ("%02x", ep->regs[fpreg][i]);
+
+ floatformat_to_double (&floatformat_i387_ext, (char *) ep->regs[fpreg],
+ &val);
+ printf_unfiltered (" %g\n", val);
+ }
+}
+
+i386_float_info (void)
+{
+ struct user u; /* just for address computations */
+ int i;
+ /* fpstate defined in <sys/user.h> */
+ struct fpstate *fpstatep;
+ char buf[sizeof (struct fpstate) + 2 * sizeof (int)];
+ unsigned int uaddr;
+ char fpvalid;
+ unsigned int rounded_addr;
+ unsigned int rounded_size;
+ /*extern int corechan; */
+ int skip;
+
+ uaddr = (char *) &U_FPSTATE (u) - (char *) &u;
+ if (! ptid_equal (inferior_ptid, null_ptid))
+ {
+ int *ip;
+
+ rounded_addr = uaddr & -sizeof (int);
+ rounded_size = (((uaddr + sizeof (struct fpstate)) - uaddr) +
+ sizeof (int) - 1) / sizeof (int);
+ skip = uaddr - rounded_addr;
+
+ ip = (int *) buf;
+ for (i = 0; i < rounded_size; i++)
+ {
+ *ip++ = ptrace (PT_READ_U, PIDGET (inferior_ptid),
+ (caddr_t) rounded_addr, 0);
+ rounded_addr += sizeof (int);
+ }
+ }
+ else
+ {
+ printf ("float info: can't do a core file (yet)\n");
+ return;
+#if 0
+ if (lseek (corechan, uaddr, 0) < 0)
+ perror_with_name ("seek on core file");
+ if (myread (corechan, buf, sizeof (struct fpstate)) < 0)
+ perror_with_name ("read from core file");
+ skip = 0;
+#endif
+ }
+
+ print_387_status (0, (struct env387 *) buf);
+}
+
+int
+kernel_u_size (void)
+{
+ return (sizeof (struct user));
+}
+
+#endif
diff --git a/gdb/i386bsd-nat.c b/gdb/i386bsd-nat.c
new file mode 100644
index 00000000000..ad5a3013f34
--- /dev/null
+++ b/gdb/i386bsd-nat.c
@@ -0,0 +1,400 @@
+/* Native-dependent code for modern i386 BSD's.
+ Copyright 2000, 2001, 2002 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 "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include "gdb_assert.h"
+#include <signal.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+
+#ifdef HAVE_SYS_PROCFS_H
+#include <sys/procfs.h>
+#endif
+
+#ifndef HAVE_GREGSET_T
+typedef struct reg gregset_t;
+#endif
+
+#ifndef HAVE_FPREGSET_T
+typedef struct fpreg fpregset_t;
+#endif
+
+#include "gregset.h"
+
+
+/* In older BSD versions we cannot get at some of the segment
+ registers. FreeBSD for example didn't support the %fs and %gs
+ registers until the 3.0 release. We have autoconf checks for their
+ presence, and deal gracefully with their absence. */
+
+/* Registers we shouldn't try to fetch. */
+#if !defined (CANNOT_FETCH_REGISTER)
+#define CANNOT_FETCH_REGISTER(regno) cannot_fetch_register (regno)
+#endif
+
+/* Registers we shouldn't try to store. */
+#if !defined (CANNOT_STORE_REGISTER)
+#define CANNOT_STORE_REGISTER(regno) cannot_fetch_register (regno)
+#endif
+
+/* Offset to the gregset_t location where REG is stored. */
+#define REG_OFFSET(reg) offsetof (gregset_t, reg)
+
+/* At reg_offset[REGNO] you'll find the offset to the gregset_t
+ location where the GDB register REGNO is stored. Unsupported
+ registers are marked with `-1'. */
+static int reg_offset[] =
+{
+ REG_OFFSET (r_eax),
+ REG_OFFSET (r_ecx),
+ REG_OFFSET (r_edx),
+ REG_OFFSET (r_ebx),
+ REG_OFFSET (r_esp),
+ REG_OFFSET (r_ebp),
+ REG_OFFSET (r_esi),
+ REG_OFFSET (r_edi),
+ REG_OFFSET (r_eip),
+ REG_OFFSET (r_eflags),
+ REG_OFFSET (r_cs),
+ REG_OFFSET (r_ss),
+ REG_OFFSET (r_ds),
+ REG_OFFSET (r_es),
+#ifdef HAVE_STRUCT_REG_R_FS
+ REG_OFFSET (r_fs),
+#else
+ -1,
+#endif
+#ifdef HAVE_STRUCT_REG_R_GS
+ REG_OFFSET (r_gs)
+#else
+ -1
+#endif
+};
+
+#define REG_ADDR(regset, regno) ((char *) (regset) + reg_offset[regno])
+
+/* Macro to determine if a register is fetched with PT_GETREGS. */
+#define GETREGS_SUPPLIES(regno) \
+ ((0 <= (regno) && (regno) <= 15))
+
+#ifdef HAVE_PT_GETXMMREGS
+/* Set to 1 if the kernel supports PT_GETXMMREGS. Initialized to -1
+ so that we try PT_GETXMMREGS the first time around. */
+static int have_ptrace_xmmregs = -1;
+#endif
+
+/* Return nonzero if we shouldn't try to fetch register REGNO. */
+
+static int
+cannot_fetch_register (int regno)
+{
+ return (reg_offset[regno] == -1);
+}
+
+
+/* Transfering the registers between GDB, inferiors and core files. */
+
+/* Fill GDB's register array with the general-purpose register values
+ in *GREGSETP. */
+
+void
+supply_gregset (gregset_t *gregsetp)
+{
+ int i;
+
+ for (i = 0; i < NUM_GREGS; i++)
+ {
+ if (CANNOT_FETCH_REGISTER (i))
+ supply_register (i, NULL);
+ else
+ supply_register (i, REG_ADDR (gregsetp, i));
+ }
+}
+
+/* Fill register REGNO (if it is a general-purpose register) in
+ *GREGSETPS with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+
+void
+fill_gregset (gregset_t *gregsetp, int regno)
+{
+ int i;
+
+ for (i = 0; i < NUM_GREGS; i++)
+ if ((regno == -1 || regno == i) && ! CANNOT_STORE_REGISTER (i))
+ regcache_collect (i, REG_ADDR (gregsetp, i));
+}
+
+#include "i387-tdep.h"
+
+/* Fill GDB's register array with the floating-point register values
+ in *FPREGSETP. */
+
+void
+supply_fpregset (fpregset_t *fpregsetp)
+{
+ i387_supply_fsave ((char *) fpregsetp);
+}
+
+/* Fill register REGNO (if it is a floating-point register) in
+ *FPREGSETP with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+
+void
+fill_fpregset (fpregset_t *fpregsetp, int regno)
+{
+ i387_fill_fsave ((char *) fpregsetp, regno);
+}
+
+/* Fetch register REGNO from the inferior. If REGNO is -1, do this
+ for all registers (including the floating point registers). */
+
+void
+fetch_inferior_registers (int regno)
+{
+
+ if (regno == -1 || GETREGS_SUPPLIES (regno))
+ {
+ gregset_t gregs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ supply_gregset (&gregs);
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1 || regno >= FP0_REGNUM)
+ {
+ fpregset_t fpregs;
+#ifdef HAVE_PT_GETXMMREGS
+ char xmmregs[512];
+
+ if (have_ptrace_xmmregs != 0 &&
+ ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) xmmregs, 0) == 0)
+ {
+ have_ptrace_xmmregs = 1;
+ i387_supply_fxsave (xmmregs);
+ }
+ else
+ {
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point status");
+
+ supply_fpregset (&fpregs);
+ }
+#else
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point status");
+
+ supply_fpregset (&fpregs);
+#endif
+ }
+}
+
+/* Store register REGNO back into the inferior. If REGNO is -1, do
+ this for all registers (including the floating point registers). */
+
+void
+store_inferior_registers (int regno)
+{
+
+ if (regno == -1 || GETREGS_SUPPLIES (regno))
+ {
+ gregset_t gregs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ fill_gregset (&gregs, regno);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
+ perror_with_name ("Couldn't write registers");
+
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1 || regno >= FP0_REGNUM)
+ {
+ fpregset_t fpregs;
+#ifdef HAVE_PT_GETXMMREGS
+ char xmmregs[512];
+
+ if (have_ptrace_xmmregs != 0 &&
+ ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) xmmregs, 0) == 0)
+ {
+ have_ptrace_xmmregs = 1;
+
+ i387_fill_fxsave (xmmregs, regno);
+
+ if (ptrace (PT_SETXMMREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) xmmregs, 0) == -1)
+ perror_with_name ("Couldn't write XMM registers");
+ }
+ else
+ {
+ have_ptrace_xmmregs = 0;
+#endif
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point status");
+
+ fill_fpregset (&fpregs, regno);
+
+ if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't write floating point status");
+#ifdef HAVE_PT_GETXMMREGS
+ }
+#endif
+ }
+}
+
+
+/* Support for debug registers. */
+
+#ifdef HAVE_PT_GETDBREGS
+
+/* Not all versions of FreeBSD/i386 that support the debug registers
+ have this macro. */
+#ifndef DBREG_DRX
+#define DBREG_DRX(d, x) ((&d->dr0)[x])
+#endif
+
+static void
+i386bsd_dr_set (int regnum, unsigned int value)
+{
+ struct dbreg dbregs;
+
+ if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &dbregs, 0) == -1)
+ perror_with_name ("Couldn't get debug registers");
+
+ /* For some mysterious reason, some of the reserved bits in the
+ debug control register get set. Mask these off, otherwise the
+ ptrace call below will fail. */
+ dbregs.dr7 &= ~(0x0000fc00);
+
+ DBREG_DRX ((&dbregs), regnum) = value;
+
+ if (ptrace (PT_SETDBREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &dbregs, 0) == -1)
+ perror_with_name ("Couldn't write debug registers");
+}
+
+void
+i386bsd_dr_set_control (unsigned long control)
+{
+ i386bsd_dr_set (7, control);
+}
+
+void
+i386bsd_dr_set_addr (int regnum, CORE_ADDR addr)
+{
+ gdb_assert (regnum >= 0 && regnum <= 4);
+
+ i386bsd_dr_set (regnum, addr);
+}
+
+void
+i386bsd_dr_reset_addr (int regnum)
+{
+ gdb_assert (regnum >= 0 && regnum <= 4);
+
+ i386bsd_dr_set (regnum, 0);
+}
+
+unsigned long
+i386bsd_dr_get_status (void)
+{
+ struct dbreg dbregs;
+
+ /* FIXME: kettenis/2001-03-31: Calling perror_with_name if the
+ ptrace call fails breaks debugging remote targets. The correct
+ way to fix this is to add the hardware breakpoint and watchpoint
+ stuff to the target vector. For now, just return zero if the
+ ptrace call fails. */
+ if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & dbregs, 0) == -1)
+#if 0
+ perror_with_name ("Couldn't read debug registers");
+#else
+ return 0;
+#endif
+
+ return dbregs.dr6;
+}
+
+#endif /* PT_GETDBREGS */
+
+
+/* Support for the user struct. */
+
+/* Return the address register REGNO. BLOCKEND is the value of
+ u.u_ar0, which should point to the registers. */
+
+CORE_ADDR
+register_u_addr (CORE_ADDR blockend, int regno)
+{
+ return (CORE_ADDR) REG_ADDR (blockend, regno);
+}
+
+#include <sys/param.h>
+#include <sys/user.h>
+
+/* Return the size of the user struct. */
+
+int
+kernel_u_size (void)
+{
+ return (sizeof (struct user));
+}
+
+/* See i386bsd-tdep.c. */
+extern int i386bsd_sigcontext_pc_offset;
+
+void
+_initialize_i386bsd_nat (void)
+{
+ /* To support the recognition of signal handlers, i386bsd-tdep.c
+ hardcodes some constants. Inclusion of this file means that we
+ are compiling a native debugger, which means that we can use the
+ system header files and sysctl(3) to get at the relevant
+ information. */
+
+ /* Override the default value for the offset of the program counter
+ in the sigcontext structure. */
+ i386bsd_sigcontext_pc_offset = offsetof (struct sigcontext, sc_pc);
+}
diff --git a/gdb/i386bsd-tdep.c b/gdb/i386bsd-tdep.c
new file mode 100644
index 00000000000..a01ed6b89e6
--- /dev/null
+++ b/gdb/i386bsd-tdep.c
@@ -0,0 +1,84 @@
+/* Target-dependent code for i386 BSD's.
+ Copyright 2001 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 "defs.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+/* Support for signal handlers. */
+
+/* Range in which to find the signaltramp routine, traditionally found
+ on the use stack, just below the user area. Initialized to values
+ that work for NetBSD and FreeBSD. */
+
+CORE_ADDR i386bsd_sigtramp_start = 0xbfbfdf20;
+CORE_ADDR i386bsd_sigtramp_end = 0xbfbfdff0;
+
+/* Return whether PC is in a BSD sigtramp routine. */
+
+int
+i386bsd_in_sigtramp (CORE_ADDR pc, char *name)
+{
+ return (pc >= i386bsd_sigtramp_start && pc < i386bsd_sigtramp_end);
+}
+
+/* Offset in the sigcontext structure of the program counter.
+ Initialized to the value from 4.4 BSD Lite. */
+int i386bsd_sigcontext_pc_offset = 20;
+
+/* Assuming FRAME is for a BSD sigtramp routine, return the address of
+ the associated sigcontext structure. */
+
+static CORE_ADDR
+i386bsd_sigcontext_addr (struct frame_info *frame)
+{
+ if (frame->next)
+ /* If this isn't the top frame, the next frame must be for the
+ signal handler itself. A pointer to the sigcontext structure
+ is passed as the third argument to the signal handler. */
+ return read_memory_unsigned_integer (frame->next->frame + 16, 4);
+
+ /* This is the top frame. We'll have to find the address of the
+ sigcontext structure by looking at the stack pointer. */
+ return read_memory_unsigned_integer (read_register (SP_REGNUM) + 8, 4);
+}
+
+/* Assuming FRAME is for a BSD sigtramp routine, return the saved
+ program counter. */
+
+static CORE_ADDR
+i386bsd_sigtramp_saved_pc (struct frame_info *frame)
+{
+ CORE_ADDR addr;
+ addr = i386bsd_sigcontext_addr (frame);
+ return read_memory_unsigned_integer (addr + i386bsd_sigcontext_pc_offset, 4);
+}
+
+/* Return the saved program counter for FRAME. */
+
+CORE_ADDR
+i386bsd_frame_saved_pc (struct frame_info *frame)
+{
+ if (frame->signal_handler_caller)
+ return i386bsd_sigtramp_saved_pc (frame);
+
+ return read_memory_unsigned_integer (frame->frame + 4, 4);
+}
diff --git a/gdb/i386fbsd-nat.c b/gdb/i386fbsd-nat.c
new file mode 100644
index 00000000000..1c19ac87eb4
--- /dev/null
+++ b/gdb/i386fbsd-nat.c
@@ -0,0 +1,102 @@
+/* Native-dependent code for FreeBSD/i386.
+ Copyright 2001 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 "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/sysctl.h>
+
+/* Prevent warning from -Wmissing-prototypes. */
+void _initialize_i386fbsd_nat (void);
+
+/* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+void
+child_resume (ptid_t ptid, int step, enum target_signal signal)
+{
+ pid_t pid = ptid_get_pid (ptid);
+ int request = PT_STEP;
+
+ if (pid == -1)
+ /* Resume all threads. This only gets used in the non-threaded
+ case, where "resume all threads" and "resume inferior_ptid" are
+ the same. */
+ pid = ptid_get_pid (inferior_ptid);
+
+ if (!step)
+ {
+ unsigned int eflags;
+
+ /* Workaround for a bug in FreeBSD. Make sure that the trace
+ flag is off when doing a continue. There is a code path
+ through the kernel which leaves the flag set when it should
+ have been cleared. If a process has a signal pending (such
+ as SIGALRM) and we do a PT_STEP, the process never really has
+ a chance to run because the kernel needs to notify the
+ debugger that a signal is being sent. Therefore, the process
+ never goes through the kernel's trap() function which would
+ normally clear it. */
+
+ eflags = read_register (PS_REGNUM);
+ if (eflags & 0x0100)
+ write_register (PS_REGNUM, eflags & ~0x0100);
+
+ request = PT_CONTINUE;
+ }
+
+ /* An addres of (caddr_t) 1 tells ptrace to continue from where it
+ was. (If GDB wanted it to start some other way, we have already
+ written a new PC value to the child.) */
+ if (ptrace (request, pid, (caddr_t) 1,
+ target_signal_to_host (signal)) == -1)
+ perror_with_name ("ptrace");
+}
+
+void
+_initialize_i386fbsd_nat (void)
+{
+ /* FreeBSD provides a kern.ps_strings sysctl that we can use to
+ locate the sigtramp. That way we can still recognize a sigtramp
+ if it's location is changed in a new kernel. Of course this is
+ still based on the assumption that the sigtramp is placed
+ directly under the location where the program arguments and
+ environment can be found. */
+#ifdef KERN_PS_STRINGS
+ {
+ int mib[2];
+ int ps_strings;
+ size_t len;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PS_STRINGS;
+ len = sizeof (ps_strings);
+ if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0)
+ {
+ i386bsd_sigtramp_start = ps_strings - 128;
+ i386bsd_sigtramp_end = ps_strings;
+ }
+ }
+#endif
+}
diff --git a/gdb/i386gnu-nat.c b/gdb/i386gnu-nat.c
new file mode 100644
index 00000000000..329ef2fd17a
--- /dev/null
+++ b/gdb/i386gnu-nat.c
@@ -0,0 +1,293 @@
+/* Low level interface to i386 running the GNU Hurd.
+ Copyright 1992, 1995, 1996, 1998, 2000, 2001
+ 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 "defs.h"
+#include "inferior.h"
+#include "floatformat.h"
+#include "regcache.h"
+
+#include "gdb_assert.h"
+#include <errno.h>
+#include <stdio.h>
+
+#include <mach.h>
+#include <mach_error.h>
+#include <mach/message.h>
+#include <mach/exception.h>
+
+#include "i386-tdep.h"
+
+#include "gnu-nat.h"
+#include "i387-tdep.h"
+
+#ifdef HAVE_SYS_PROCFS_H
+# include <sys/procfs.h>
+# include "gregset.h"
+#endif
+
+/* Offset to the thread_state_t location where REG is stored. */
+#define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
+
+/* At REG_OFFSET[N] is the offset to the thread_state_t location where
+ the GDB register N is stored. */
+static int reg_offset[] =
+{
+ REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx),
+ REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi),
+ REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss),
+ REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs)
+};
+
+#define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
+
+
+/* Get the whole floating-point state of THREAD and record the
+ values of the corresponding (pseudo) registers. */
+static void
+fetch_fpregs (struct proc *thread)
+{
+ mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
+ struct i386_float_state state;
+ error_t err;
+
+ err = thread_get_state (thread->port, i386_FLOAT_STATE,
+ (thread_state_t) &state, &count);
+ if (err)
+ {
+ warning ("Couldn't fetch floating-point state from %s",
+ proc_string (thread));
+ return;
+ }
+
+ if (!state.initialized)
+ /* The floating-point state isn't initialized. */
+ {
+ int i;
+
+ for (i = FP0_REGNUM; i <= FOP_REGNUM; i++)
+ supply_register (i, NULL);
+
+ return;
+ }
+
+ /* Supply the floating-point registers. */
+ i387_supply_fsave (state.hw_state);
+}
+
+#ifdef HAVE_SYS_PROCFS_H
+/* These two calls are used by the core-regset.c code for
+ reading ELF core files. */
+void
+supply_gregset (gdb_gregset_t *gregs)
+{
+ int i;
+ for (i = 0; i < NUM_GREGS; i++)
+ supply_register (i, REG_ADDR (gregs, i));
+}
+
+void
+supply_fpregset (gdb_fpregset_t *fpregs)
+{
+ i387_supply_fsave ((char *) fpregs);
+}
+#endif
+
+/* Fetch register REGNO, or all regs if REGNO is -1. */
+void
+gnu_fetch_registers (int regno)
+{
+ struct proc *thread;
+
+ /* Make sure we know about new threads. */
+ inf_update_procs (current_inferior);
+
+ thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid));
+ if (!thread)
+ error ("Can't fetch registers from thread %d: No such thread",
+ PIDGET (inferior_ptid));
+
+ if (regno < NUM_GREGS || regno == -1)
+ {
+ thread_state_t state;
+
+ /* This does the dirty work for us. */
+ state = proc_get_state (thread, 0);
+ if (!state)
+ {
+ warning ("Couldn't fetch registers from %s",
+ proc_string (thread));
+ return;
+ }
+
+ if (regno == -1)
+ {
+ int i;
+
+ proc_debug (thread, "fetching all register");
+
+ for (i = 0; i < NUM_GREGS; i++)
+ supply_register (i, REG_ADDR (state, i));
+ thread->fetched_regs = ~0;
+ }
+ else
+ {
+ proc_debug (thread, "fetching register %s", REGISTER_NAME (regno));
+
+ supply_register (regno, REG_ADDR (state, regno));
+ thread->fetched_regs |= (1 << regno);
+ }
+ }
+
+ if (regno >= NUM_GREGS || regno == -1)
+ {
+ proc_debug (thread, "fetching floating-point registers");
+
+ fetch_fpregs (thread);
+ }
+}
+
+
+/* Store the whole floating-point state into THREAD using information
+ from the corresponding (pseudo) registers. */
+static void
+store_fpregs (struct proc *thread, int regno)
+{
+ mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
+ struct i386_float_state state;
+ error_t err;
+
+ err = thread_get_state (thread->port, i386_FLOAT_STATE,
+ (thread_state_t) &state, &count);
+ if (err)
+ {
+ warning ("Couldn't fetch floating-point state from %s",
+ proc_string (thread));
+ return;
+ }
+
+ /* FIXME: kettenis/2001-07-15: Is this right? Should we somehow
+ take into account REGISTER_VALID like the old code did? */
+ i387_fill_fsave (state.hw_state, regno);
+
+ err = thread_set_state (thread->port, i386_FLOAT_STATE,
+ (thread_state_t) &state, i386_FLOAT_STATE_COUNT);
+ if (err)
+ {
+ warning ("Couldn't store floating-point state into %s",
+ proc_string (thread));
+ return;
+ }
+}
+
+/* Store at least register REGNO, or all regs if REGNO == -1. */
+void
+gnu_store_registers (int regno)
+{
+ struct proc *thread;
+
+ /* Make sure we know about new threads. */
+ inf_update_procs (current_inferior);
+
+ thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid));
+ if (!thread)
+ error ("Couldn't store registers into thread %d: No such thread",
+ PIDGET (inferior_ptid));
+
+ if (regno < NUM_GREGS || regno == -1)
+ {
+ thread_state_t state;
+ thread_state_data_t old_state;
+ int was_aborted = thread->aborted;
+ int was_valid = thread->state_valid;
+ int trace;
+
+ if (!was_aborted && was_valid)
+ memcpy (&old_state, &thread->state, sizeof (old_state));
+
+ state = proc_get_state (thread, 1);
+ if (!state)
+ {
+ warning ("Couldn't store registers into %s", proc_string (thread));
+ return;
+ }
+
+ /* Save the T bit. We might try to restore the %eflags register
+ below, but changing the T bit would seriously confuse GDB. */
+ trace = ((struct i386_thread_state *)state)->efl & 0x100;
+
+ if (!was_aborted && was_valid)
+ /* See which registers have changed after aborting the thread. */
+ {
+ int check_regno;
+
+ for (check_regno = 0; check_regno < NUM_GREGS; check_regno++)
+ if ((thread->fetched_regs & (1 << check_regno))
+ && memcpy (REG_ADDR (&old_state, check_regno),
+ REG_ADDR (state, check_regno),
+ REGISTER_RAW_SIZE (check_regno)))
+ /* Register CHECK_REGNO has changed! Ack! */
+ {
+ warning ("Register %s changed after the thread was aborted",
+ REGISTER_NAME (check_regno));
+ if (regno >= 0 && regno != check_regno)
+ /* Update GDB's copy of the register. */
+ supply_register (check_regno, REG_ADDR (state, check_regno));
+ else
+ warning ("... also writing this register! Suspicious...");
+ }
+ }
+
+#define fill(state, regno) \
+ memcpy (REG_ADDR(state, regno), &registers[REGISTER_BYTE (regno)], \
+ REGISTER_RAW_SIZE (regno))
+
+ if (regno == -1)
+ {
+ int i;
+
+ proc_debug (thread, "storing all registers");
+
+ for (i = 0; i < NUM_GREGS; i++)
+ if (register_valid[i])
+ fill (state, i);
+ }
+ else
+ {
+ proc_debug (thread, "storing register %s", REGISTER_NAME (regno));
+
+ gdb_assert (register_valid[regno]);
+ fill (state, regno);
+ }
+
+ /* Restore the T bit. */
+ ((struct i386_thread_state *)state)->efl &= ~0x100;
+ ((struct i386_thread_state *)state)->efl |= trace;
+ }
+
+#undef fill
+
+ if (regno >= NUM_GREGS || regno == -1)
+ {
+ proc_debug (thread, "storing floating-point registers");
+
+ store_fpregs (thread, regno);
+ }
+}
diff --git a/gdb/i386ly-tdep.c b/gdb/i386ly-tdep.c
new file mode 100644
index 00000000000..92b544deabd
--- /dev/null
+++ b/gdb/i386ly-tdep.c
@@ -0,0 +1,45 @@
+/* Target-dependent code for Intel 386 running LynxOS.
+ Copyright 1993, 1996, 2000, 2001 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 "defs.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+/* Return the PC of the caller from the call frame. Assumes the subr prologue
+ has already been executed, and the frame pointer setup. If this is the
+ outermost frame, we check to see if we are in a system call by examining the
+ previous instruction. If so, then the return PC is actually at SP+4 because
+ system calls use a different calling sequence. */
+
+CORE_ADDR
+i386lynx_saved_pc_after_call (struct frame_info *frame)
+{
+ char opcode[7];
+ static const unsigned char call_inst[] =
+ {0x9a, 0, 0, 0, 0, 8, 0}; /* lcall 0x8,0x0 */
+
+ read_memory (frame->pc - 7, opcode, 7);
+ if (memcmp (opcode, call_inst, 7) == 0)
+ return read_memory_integer (read_register (SP_REGNUM) + 4, 4);
+
+ return read_memory_integer (read_register (SP_REGNUM), 4);
+}
diff --git a/gdb/i386m3-nat.c b/gdb/i386m3-nat.c
new file mode 100644
index 00000000000..8fbd1e8e81c
--- /dev/null
+++ b/gdb/i386m3-nat.c
@@ -0,0 +1,426 @@
+/* Low level interface to I386 running mach 3.0.
+ Copyright 1992, 1993, 1994, 1996, 2000, 2001
+ 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 "defs.h"
+#include "inferior.h"
+#include "floatformat.h"
+#include "regcache.h"
+
+#include <stdio.h>
+
+#include <mach.h>
+#include <mach/message.h>
+#include <mach/exception.h>
+#include <mach_error.h>
+
+/* Hmmm... Should this not be here?
+ * Now for i386_float_info() target_has_execution
+ */
+#include <target.h>
+
+/* This mess is duplicated in bfd/i386mach3.h
+
+ * This is an ugly way to hack around the incorrect
+ * definition of UPAGES in i386/machparam.h.
+ *
+ * The definition should specify the size reserved
+ * for "struct user" in core files in PAGES,
+ * but instead it gives it in 512-byte core-clicks
+ * for i386 and i860.
+ */
+#include <sys/param.h>
+#if UPAGES == 16
+#define UAREA_SIZE ctob(UPAGES)
+#elif UPAGES == 2
+#define UAREA_SIZE (NBPG*UPAGES)
+#else
+FIXME ! !UPAGES is neither 2 nor 16
+#endif
+
+/* @@@ Should move print_387_status() to i387-tdep.c */
+extern void print_387_control_word (); /* i387-tdep.h */
+extern void print_387_status_word ();
+
+#define private static
+
+
+/* Find offsets to thread states at compile time.
+ * If your compiler does not grok this, calculate offsets
+ * offsets yourself and use them (or get a compatible compiler :-)
+ */
+
+#define REG_OFFSET(reg) (int)(&((struct i386_thread_state *)0)->reg)
+
+/* at reg_offset[i] is the offset to the i386_thread_state
+ * location where the gdb registers[i] is stored.
+ */
+
+static int reg_offset[] =
+{
+ REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx),
+ REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi),
+ REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss),
+ REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs)
+};
+
+#define REG_ADDRESS(state,regnum) ((char *)(state)+reg_offset[regnum])
+
+/* Fetch COUNT contiguous registers from thread STATE starting from REGNUM
+ * Caller knows that the regs handled in one transaction are of same size.
+ */
+#define FETCH_REGS(state, regnum, count) \
+ memcpy (&registers[REGISTER_BYTE (regnum)], \
+ REG_ADDRESS (state, regnum), \
+ count*REGISTER_SIZE)
+
+/* Store COUNT contiguous registers to thread STATE starting from REGNUM */
+#define STORE_REGS(state, regnum, count) \
+ memcpy (REG_ADDRESS (state, regnum), \
+ &registers[REGISTER_BYTE (regnum)], \
+ count*REGISTER_SIZE)
+
+/*
+ * Fetch inferiors registers for gdb.
+ * REGNO specifies which (as gdb views it) register, -1 for all.
+ */
+
+void
+fetch_inferior_registers (int regno)
+{
+ kern_return_t ret;
+ thread_state_data_t state;
+ unsigned int stateCnt = i386_THREAD_STATE_COUNT;
+ int index;
+
+ if (!MACH_PORT_VALID (current_thread))
+ error ("fetch inferior registers: Invalid thread");
+
+ if (must_suspend_thread)
+ setup_thread (current_thread, 1);
+
+ ret = thread_get_state (current_thread,
+ i386_THREAD_STATE,
+ state,
+ &stateCnt);
+
+ if (ret != KERN_SUCCESS)
+ warning ("fetch_inferior_registers: %s ",
+ mach_error_string (ret));
+#if 0
+ /* It may be more effective to store validate all of them,
+ * since we fetched them all anyway
+ */
+ else if (regno != -1)
+ supply_register (regno, (char *) state + reg_offset[regno]);
+#endif
+ else
+ {
+ for (index = 0; index < NUM_REGS; index++)
+ supply_register (index, (char *) state + reg_offset[index]);
+ }
+
+ if (must_suspend_thread)
+ setup_thread (current_thread, 0);
+}
+
+/* Store our register values back into the inferior.
+ * If REGNO is -1, do this for all registers.
+ * Otherwise, REGNO specifies which register
+ *
+ * On mach3 all registers are always saved in one call.
+ */
+void
+store_inferior_registers (int regno)
+{
+ kern_return_t ret;
+ thread_state_data_t state;
+ unsigned int stateCnt = i386_THREAD_STATE_COUNT;
+ register int index;
+
+ if (!MACH_PORT_VALID (current_thread))
+ error ("store inferior registers: Invalid thread");
+
+ if (must_suspend_thread)
+ setup_thread (current_thread, 1);
+
+ /* Fetch the state of the current thread */
+ ret = thread_get_state (current_thread,
+ i386_THREAD_STATE,
+ state,
+ &stateCnt);
+
+ if (ret != KERN_SUCCESS)
+ {
+ warning ("store_inferior_registers (get): %s",
+ mach_error_string (ret));
+ if (must_suspend_thread)
+ setup_thread (current_thread, 0);
+ return;
+ }
+
+ /* move gdb's registers to thread's state
+
+ * Since we save all registers anyway, save the ones
+ * that gdb thinks are valid (e.g. ignore the regno
+ * parameter)
+ */
+#if 0
+ if (regno != -1)
+ STORE_REGS (state, regno, 1);
+ else
+#endif
+ {
+ for (index = 0; index < NUM_REGS; index++)
+ STORE_REGS (state, index, 1);
+ }
+
+ /* Write gdb's current view of register to the thread
+ */
+ ret = thread_set_state (current_thread,
+ i386_THREAD_STATE,
+ state,
+ i386_THREAD_STATE_COUNT);
+
+ if (ret != KERN_SUCCESS)
+ warning ("store_inferior_registers (set): %s",
+ mach_error_string (ret));
+
+ if (must_suspend_thread)
+ setup_thread (current_thread, 0);
+}
+
+
+
+/* Return the address in the core dump or inferior of register REGNO.
+ * BLOCKEND should be the address of the end of the UPAGES area read
+ * in memory, but it's not?
+ *
+ * Currently our UX server dumps the whole thread state to the
+ * core file. If your UX does something else, adapt the routine
+ * below to return the offset to the given register.
+ *
+ * Called by core-aout.c(fetch_core_registers)
+ */
+
+CORE_ADDR
+register_addr (int regno, CORE_ADDR blockend)
+{
+ CORE_ADDR addr;
+
+ if (regno < 0 || regno >= NUM_REGS)
+ error ("Invalid register number %d.", regno);
+
+ /* UAREA_SIZE == 8 kB in i386 */
+ addr = (unsigned int) REG_ADDRESS (UAREA_SIZE - sizeof (struct i386_thread_state), regno);
+
+ return addr;
+}
+
+/* jtv@hut.fi: I copied and modified this 387 code from
+ * gdb/i386-xdep.c. Modifications for Mach 3.0.
+ *
+ * i387 status dumper. See also i387-tdep.c
+ */
+struct env387
+{
+ unsigned short control;
+ unsigned short r0;
+ unsigned short status;
+ unsigned short r1;
+ unsigned short tag;
+ unsigned short r2;
+ unsigned long eip;
+ unsigned short code_seg;
+ unsigned short opcode;
+ unsigned long operand;
+ unsigned short operand_seg;
+ unsigned short r3;
+ unsigned char regs[8][10];
+};
+/* This routine is machine independent?
+ * Should move it to i387-tdep.c but you need to export struct env387
+ */
+private
+print_387_status (unsigned short status, struct env387 *ep)
+{
+ int i;
+ int bothstatus;
+ int top;
+ int fpreg;
+ unsigned char *p;
+
+ bothstatus = ((status != 0) && (ep->status != 0));
+ if (status != 0)
+ {
+ if (bothstatus)
+ printf_unfiltered ("u: ");
+ print_387_status_word (status);
+ }
+
+ if (ep->status != 0)
+ {
+ if (bothstatus)
+ printf_unfiltered ("e: ");
+ print_387_status_word (ep->status);
+ }
+
+ print_387_control_word (ep->control);
+ printf_unfiltered ("last exception: ");
+ printf_unfiltered ("opcode %s; ", local_hex_string (ep->opcode));
+ printf_unfiltered ("pc %s:", local_hex_string (ep->code_seg));
+ printf_unfiltered ("%s; ", local_hex_string (ep->eip));
+ printf_unfiltered ("operand %s", local_hex_string (ep->operand_seg));
+ printf_unfiltered (":%s\n", local_hex_string (ep->operand));
+
+ top = (ep->status >> 11) & 7;
+
+ printf_unfiltered ("regno tag msb lsb value\n");
+ for (fpreg = 7; fpreg >= 0; fpreg--)
+ {
+ double val;
+
+ printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
+
+ switch ((ep->tag >> (fpreg * 2)) & 3)
+ {
+ case 0:
+ printf_unfiltered ("valid ");
+ break;
+ case 1:
+ printf_unfiltered ("zero ");
+ break;
+ case 2:
+ printf_unfiltered ("trap ");
+ break;
+ case 3:
+ printf_unfiltered ("empty ");
+ break;
+ }
+ for (i = 9; i >= 0; i--)
+ printf_unfiltered ("%02x", ep->regs[fpreg][i]);
+
+ floatformat_to_double (&floatformat_i387_ext, (char *) ep->regs[fpreg],
+ &val);
+ printf_unfiltered (" %g\n", val);
+ }
+ if (ep->r0)
+ printf_unfiltered ("warning: reserved0 is %s\n", local_hex_string (ep->r0));
+ if (ep->r1)
+ printf_unfiltered ("warning: reserved1 is %s\n", local_hex_string (ep->r1));
+ if (ep->r2)
+ printf_unfiltered ("warning: reserved2 is %s\n", local_hex_string (ep->r2));
+ if (ep->r3)
+ printf_unfiltered ("warning: reserved3 is %s\n", local_hex_string (ep->r3));
+}
+
+/*
+ * values that go into fp_kind (from <i386/fpreg.h>)
+ */
+#define FP_NO 0 /* no fp chip, no emulator (no fp support) */
+#define FP_SW 1 /* no fp chip, using software emulator */
+#define FP_HW 2 /* chip present bit */
+#define FP_287 2 /* 80287 chip present */
+#define FP_387 3 /* 80387 chip present */
+
+typedef struct fpstate
+{
+#if 1
+ unsigned char state[FP_STATE_BYTES]; /* "hardware" state */
+#else
+ struct env387 state; /* Actually this */
+#endif
+ int status; /* Duplicate status */
+}
+ *fpstate_t;
+
+/* Mach 3 specific routines.
+ */
+private boolean_t
+get_i387_state (struct fpstate *fstate)
+{
+ kern_return_t ret;
+ thread_state_data_t state;
+ unsigned int fsCnt = i386_FLOAT_STATE_COUNT;
+ struct i386_float_state *fsp;
+
+ ret = thread_get_state (current_thread,
+ i386_FLOAT_STATE,
+ state,
+ &fsCnt);
+
+ if (ret != KERN_SUCCESS)
+ {
+ warning ("Can not get live floating point state: %s",
+ mach_error_string (ret));
+ return FALSE;
+ }
+
+ fsp = (struct i386_float_state *) state;
+ /* The 387 chip (also 486 counts) or a software emulator? */
+ if (!fsp->initialized || (fsp->fpkind != FP_387 && fsp->fpkind != FP_SW))
+ return FALSE;
+
+ /* Clear the target then copy thread's float state there.
+ Make a copy of the status word, for some reason?
+ */
+ memset (fstate, 0, sizeof (struct fpstate));
+
+ fstate->status = fsp->exc_status;
+
+ memcpy (fstate->state, (char *) &fsp->hw_state, FP_STATE_BYTES);
+
+ return TRUE;
+}
+
+private boolean_t
+get_i387_core_state (struct fpstate *fstate)
+{
+ /* Not implemented yet. Core files do not contain float state. */
+ return FALSE;
+}
+
+/*
+ * This is called by "info float" command
+ */
+void
+i386_mach3_float_info (void)
+{
+ char buf[sizeof (struct fpstate) + 2 * sizeof (int)];
+ boolean_t valid = FALSE;
+ fpstate_t fps;
+
+ if (target_has_execution)
+ valid = get_i387_state (buf);
+#if 0
+ else if (WE HAVE CORE FILE) /* @@@@ Core files not supported */
+ valid = get_i387_core_state (buf);
+#endif
+
+ if (!valid)
+ {
+ warning ("no floating point status saved");
+ return;
+ }
+
+ fps = (fpstate_t) buf;
+
+ print_387_status (fps->status, (struct env387 *) fps->state);
+}
diff --git a/gdb/i386mach-nat.c b/gdb/i386mach-nat.c
new file mode 100644
index 00000000000..6d4980be4c6
--- /dev/null
+++ b/gdb/i386mach-nat.c
@@ -0,0 +1,172 @@
+/* Native dependent code for Mach 386's for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1995, 1996, 1999, 2000,
+ 2001 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include <sys/file.h>
+#include "gdb_stat.h"
+#include <sys/core.h>
+
+static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
+
+void
+fetch_inferior_registers (int regno)
+{
+ struct regs inferior_registers;
+ struct fp_state inferior_fp_registers;
+
+ registers_fetched ();
+
+ ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers);
+ ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers);
+
+ memcpy (registers, &inferior_registers, sizeof inferior_registers);
+
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)],
+ inferior_fp_registers.f_st,
+ sizeof inferior_fp_registers.f_st);
+ memcpy (&registers[REGISTER_BYTE (FPC_REGNUM)],
+ &inferior_fp_registers.f_ctrl,
+ sizeof inferior_fp_registers - sizeof inferior_fp_registers.f_st);
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ struct regs inferior_registers;
+ struct fp_state inferior_fp_registers;
+
+ memcpy (&inferior_registers, registers, 20 * 4);
+
+ memcpy (inferior_fp_registers.f_st, &registers[REGISTER_BYTE (FP0_REGNUM)],
+ sizeof inferior_fp_registers.f_st);
+ memcpy (&inferior_fp_registers.f_ctrl,
+ &registers[REGISTER_BYTE (FPC_REGNUM)],
+ sizeof inferior_fp_registers - sizeof inferior_fp_registers.f_st);
+
+#ifdef PTRACE_FP_BUG
+ if (regno == FP_REGNUM || regno == -1)
+ /* Storing the frame pointer requires a gross hack, in which an
+ instruction that moves eax into ebp gets single-stepped. */
+ {
+ int stack = inferior_registers.r_reg[SP_REGNUM];
+ int stuff = ptrace (PTRACE_PEEKDATA, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) stack);
+ int reg = inferior_registers.r_reg[EAX];
+ inferior_registers.r_reg[EAX] =
+ inferior_registers.r_reg[FP_REGNUM];
+ ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers);
+ ptrace (PTRACE_POKEDATA, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) stack, 0xc589);
+ ptrace (PTRACE_SINGLESTEP, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) stack, 0);
+ wait (0);
+ ptrace (PTRACE_POKEDATA, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) stack, stuff);
+ inferior_registers.r_reg[EAX] = reg;
+ }
+#endif
+ ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers);
+ ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers);
+}
+
+
+
+/* Provide registers to GDB from a core file.
+
+ CORE_REG_SECT points to an array of bytes, which were obtained from
+ a core file which BFD thinks might contain register contents.
+ CORE_REG_SIZE is its size.
+
+ WHICH says which register set corelow suspects this is:
+ 0 --- the general-purpose register set
+ 2 --- the floating-point register set
+
+ REG_ADDR isn't used. */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+ int val;
+
+ switch (which)
+ {
+ case 0:
+ case 1:
+ memcpy (registers, core_reg_sect, core_reg_size);
+ break;
+
+ case 2:
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)],
+ core_reg_sect,
+ core_reg_size); /* FIXME, probably bogus */
+#ifdef FPC_REGNUM
+ memcpy (&registers[REGISTER_BYTE (FPC_REGNUM)],
+ &corestr.c_fpu.f_fpstatus.f_ctrl,
+ sizeof corestr.c_fpu.f_fpstatus -
+ sizeof corestr.c_fpu.f_fpstatus.f_st);
+#endif
+ break;
+ }
+}
+
+
+/* Register that we are able to handle i386mach core file formats.
+ FIXME: is this really bfd_target_unknown_flavour? */
+
+static struct core_fns i386mach_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_i386mach (void)
+{
+ add_core_fns (&i386mach_core_fns);
+}
diff --git a/gdb/i386nbsd-tdep.c b/gdb/i386nbsd-tdep.c
new file mode 100644
index 00000000000..02ba77c7be9
--- /dev/null
+++ b/gdb/i386nbsd-tdep.c
@@ -0,0 +1,155 @@
+/* Target-dependent code for NetBSD/i386, for GDB.
+ Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001, 2002
+ 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 "defs.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#include "i387-tdep.h"
+
+/* Map a GDB register number to an offset in the reg structure. */
+static int regmap[] =
+{
+ ( 0 * 4), /* %eax */
+ ( 1 * 4), /* %ecx */
+ ( 2 * 4), /* %edx */
+ ( 3 * 4), /* %ebx */
+ ( 4 * 4), /* %esp */
+ ( 5 * 4), /* %epb */
+ ( 6 * 4), /* %esi */
+ ( 7 * 4), /* %edi */
+ ( 8 * 4), /* %eip */
+ ( 9 * 4), /* %eflags */
+ (10 * 4), /* %cs */
+ (11 * 4), /* %ss */
+ (12 * 4), /* %ds */
+ (13 * 4), /* %es */
+ (14 * 4), /* %fs */
+ (15 * 4), /* %gs */
+};
+
+#define SIZEOF_STRUCT_REG (16 * 4)
+
+static void
+i386nbsd_supply_reg (char *regs, int regno)
+{
+ int i;
+
+ for (i = 0; i <= 15; i++)
+ if (regno == i || regno == -1)
+ supply_register (i, regs + regmap[i]);
+}
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR ignore)
+{
+ char *regs, *fsave;
+
+ /* We get everything from one section. */
+ if (which != 0)
+ return;
+
+ if (core_reg_size < (SIZEOF_STRUCT_REG + 108))
+ {
+ warning ("Wrong size register set in core file.");
+ return;
+ }
+
+ regs = core_reg_sect;
+ fsave = core_reg_sect + SIZEOF_STRUCT_REG;
+
+ /* Integer registers. */
+ i386nbsd_supply_reg (regs, -1);
+
+ /* Floating point registers. */
+ i387_supply_fsave (fsave);
+}
+
+static void
+fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR ignore)
+{
+ switch (which)
+ {
+ case 0: /* Integer registers. */
+ if (core_reg_size != SIZEOF_STRUCT_REG)
+ warning ("Wrong size register set in core file.");
+ else
+ i386nbsd_supply_reg (core_reg_sect, -1);
+ break;
+
+ case 2: /* Floating point registers. */
+ if (core_reg_size != 108)
+ warning ("Wrong size FP register set in core file.");
+ else
+ i387_supply_fsave (core_reg_sect);
+ break;
+
+ case 3: /* "Extended" floating point registers. This is gdb-speak
+ for SSE/SSE2. */
+ if (core_reg_size != 512)
+ warning ("Wrong size XMM register set in core file.");
+ else
+ i387_supply_fxsave (core_reg_sect);
+ break;
+
+ default:
+ /* Don't know what kind of register request this is; just ignore it. */
+ break;
+ }
+}
+
+static struct core_fns i386nbsd_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+static struct core_fns i386nbsd_elfcore_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_elfcore_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+/* FIXME: should be multi-arch'd */
+int
+i386nbsd_aout_use_struct_convention (int gcc_p, struct type *type)
+{
+ return !(TYPE_LENGTH (type) == 1
+ || TYPE_LENGTH (type) == 2
+ || TYPE_LENGTH (type) == 4
+ || TYPE_LENGTH (type) == 8);
+}
+
+void
+_initialize_i386nbsd_tdep (void)
+{
+ add_core_fns (&i386nbsd_core_fns);
+ add_core_fns (&i386nbsd_elfcore_fns);
+}
diff --git a/gdb/i386v-nat.c b/gdb/i386v-nat.c
new file mode 100644
index 00000000000..672ddfbf808
--- /dev/null
+++ b/gdb/i386v-nat.c
@@ -0,0 +1,289 @@
+/* Intel 386 native support for SYSV systems (pre-SVR4).
+
+ Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
+ 1999, 2000, 2002 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 "defs.h"
+
+#ifdef HAVE_PTRACE_H
+#include <ptrace.h>
+#else
+#ifdef HAVE_SYS_PTRACE_H
+#include <sys/ptrace.h>
+#endif
+#endif
+
+#include "frame.h"
+#include "inferior.h"
+#include "language.h"
+#include "gdbcore.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/user.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+
+/* FIXME: 1998-10-21/jsm: The following used to be just "#include
+ <sys/debugreg.h>", but the the Linux kernel (version 2.1.x) and
+ glibc 2.0.x are not in sync; including <sys/debugreg.h> will result
+ in an error. With luck, these losers will get their act together
+ and we can trash this hack in the near future. */
+
+#ifdef TARGET_HAS_HARDWARE_WATCHPOINTS
+#ifdef HAVE_ASM_DEBUGREG_H
+#include <asm/debugreg.h>
+#else
+#include <sys/debugreg.h>
+#endif
+#endif
+
+#include <sys/file.h>
+#include "gdb_stat.h"
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+#include "floatformat.h"
+
+#include "target.h"
+
+
+/* this table must line up with REGISTER_NAMES in tm-i386v.h */
+/* symbols like 'EAX' come from <sys/reg.h> */
+static int regmap[] =
+{
+ EAX, ECX, EDX, EBX,
+ UESP, EBP, ESI, EDI,
+ EIP, EFL, CS, SS,
+ DS, ES, FS, GS,
+};
+
+/* blockend is the value of u.u_ar0, and points to the
+ * place where GS is stored
+ */
+
+int
+i386_register_u_addr (int blockend, int regnum)
+{
+ struct user u;
+ int fpstate;
+ int ubase;
+
+ ubase = blockend;
+ /* FIXME: Should have better way to test floating point range */
+ if (regnum >= FP0_REGNUM && regnum <= (FP0_REGNUM + 7))
+ {
+#ifdef KSTKSZ /* SCO, and others? */
+ ubase += 4 * (SS + 1) - KSTKSZ;
+ fpstate = ubase + ((char *) &u.u_fps.u_fpstate - (char *) &u);
+ return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM));
+#else
+ fpstate = ubase + ((char *) &u.i387.st_space - (char *) &u);
+ return (fpstate + 10 * (regnum - FP0_REGNUM));
+#endif
+ }
+ else
+ {
+ return (ubase + 4 * regmap[regnum]);
+ }
+
+}
+
+int
+kernel_u_size (void)
+{
+ return (sizeof (struct user));
+}
+
+#ifdef TARGET_HAS_HARDWARE_WATCHPOINTS
+
+#if !defined (offsetof)
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+#endif
+
+/* Record the value of the debug control register. */
+static int debug_control_mirror;
+
+/* Record which address associates with which register. */
+static CORE_ADDR address_lookup[DR_LASTADDR - DR_FIRSTADDR + 1];
+
+static int
+i386_insert_aligned_watchpoint (int, CORE_ADDR, CORE_ADDR, int, int);
+
+static int
+i386_insert_nonaligned_watchpoint (int, CORE_ADDR, CORE_ADDR, int, int);
+
+/* Insert a watchpoint. */
+
+int
+i386_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw)
+{
+ return i386_insert_aligned_watchpoint (pid, addr, addr, len, rw);
+}
+
+static int
+i386_insert_aligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr,
+ int len, int rw)
+{
+ int i;
+ int read_write_bits, len_bits;
+ int free_debug_register;
+ int register_number;
+
+ /* Look for a free debug register. */
+ for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++)
+ {
+ if (address_lookup[i - DR_FIRSTADDR] == 0)
+ break;
+ }
+
+ /* No more debug registers! */
+ if (i > DR_LASTADDR)
+ return -1;
+
+ read_write_bits = (rw & 1) ? DR_RW_READ : DR_RW_WRITE;
+
+ if (len == 1)
+ len_bits = DR_LEN_1;
+ else if (len == 2)
+ {
+ if (addr % 2)
+ return i386_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw);
+ len_bits = DR_LEN_2;
+ }
+
+ else if (len == 4)
+ {
+ if (addr % 4)
+ return i386_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw);
+ len_bits = DR_LEN_4;
+ }
+ else
+ return i386_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw);
+
+ free_debug_register = i;
+ register_number = free_debug_register - DR_FIRSTADDR;
+ debug_control_mirror |=
+ ((read_write_bits | len_bits)
+ << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * register_number));
+ debug_control_mirror |=
+ (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * register_number));
+ debug_control_mirror |= DR_LOCAL_SLOWDOWN;
+ debug_control_mirror &= ~DR_CONTROL_RESERVED;
+
+ ptrace (6, pid, offsetof (struct user, u_debugreg[DR_CONTROL]),
+ debug_control_mirror);
+ ptrace (6, pid, offsetof (struct user, u_debugreg[free_debug_register]),
+ addr);
+
+ /* Record where we came from. */
+ address_lookup[register_number] = addr;
+ return 0;
+}
+
+static int
+i386_insert_nonaligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr,
+ int len, int rw)
+{
+ int align;
+ int size;
+ int rv;
+
+ static int size_try_array[4][4] =
+ {
+ { 1, 1, 1, 1 }, /* trying size one */
+ { 2, 1, 2, 1 }, /* trying size two */
+ { 2, 1, 2, 1 }, /* trying size three */
+ { 4, 1, 2, 1 } /* trying size four */
+ };
+
+ rv = 0;
+ while (len > 0)
+ {
+ align = addr % 4;
+ /* Four is the maximum length for 386. */
+ size = size_try_array[len > 4 ? 3 : len - 1][align];
+
+ rv = i386_insert_aligned_watchpoint (pid, waddr, addr, size, rw);
+ if (rv)
+ {
+ i386_remove_watchpoint (pid, waddr, size);
+ return rv;
+ }
+ addr += size;
+ len -= size;
+ }
+ return rv;
+}
+
+/* Remove a watchpoint. */
+
+int
+i386_remove_watchpoint (int pid, CORE_ADDR addr, int len)
+{
+ int i;
+ int register_number;
+
+ for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++)
+ {
+ register_number = i - DR_FIRSTADDR;
+ if (address_lookup[register_number] == addr)
+ {
+ debug_control_mirror &=
+ ~(1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * register_number));
+ address_lookup[register_number] = 0;
+ }
+ }
+ ptrace (6, pid, offsetof (struct user, u_debugreg[DR_CONTROL]),
+ debug_control_mirror);
+ ptrace (6, pid, offsetof (struct user, u_debugreg[DR_STATUS]), 0);
+
+ return 0;
+}
+
+/* Check if stopped by a watchpoint. */
+
+CORE_ADDR
+i386_stopped_by_watchpoint (int pid)
+{
+ int i;
+ int status;
+
+ status = ptrace (3, pid, offsetof (struct user, u_debugreg[DR_STATUS]), 0);
+ ptrace (6, pid, offsetof (struct user, u_debugreg[DR_STATUS]), 0);
+
+ for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++)
+ {
+ if (status & (1 << (i - DR_FIRSTADDR)))
+ return address_lookup[i - DR_FIRSTADDR];
+ }
+
+ return 0;
+}
+
+#endif /* TARGET_HAS_HARDWARE_WATCHPOINTS */
diff --git a/gdb/i386v4-nat.c b/gdb/i386v4-nat.c
new file mode 100644
index 00000000000..c67f1fb2f44
--- /dev/null
+++ b/gdb/i386v4-nat.c
@@ -0,0 +1,184 @@
+/* Native-dependent code for SVR4 Unix running on i386's, for GDB.
+ Copyright 1988, 1989, 1991, 1992, 1996, 1997, 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "value.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+#include "i387-tdep.h"
+
+
+#ifdef HAVE_SYS_PROCFS_H
+
+#include <sys/procfs.h>
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* The /proc interface divides the target machine's register set up into
+ two different sets, the general register set (gregset) and the floating
+ point register set (fpregset). For each set, there is an ioctl to get
+ the current register set and another ioctl to set the current values.
+
+ The actual structure passed through the ioctl interface is, of course,
+ naturally machine dependent, and is different for each set of registers.
+ For the i386 for example, the general register set is typically defined
+ by:
+
+ typedef int gregset_t[19]; (in <sys/regset.h>)
+
+ #define GS 0 (in <sys/reg.h>)
+ #define FS 1
+ ...
+ #define UESP 17
+ #define SS 18
+
+ and the floating point set by:
+
+ typedef struct fpregset
+ {
+ union
+ {
+ struct fpchip_state // fp extension state //
+ {
+ int state[27]; // 287/387 saved state //
+ int status; // status word saved at exception //
+ } fpchip_state;
+ struct fp_emul_space // for emulators //
+ {
+ char fp_emul[246];
+ char fp_epad[2];
+ } fp_emul_space;
+ int f_fpregs[62]; // union of the above //
+ } fp_reg_set;
+ long f_wregs[33]; // saved weitek state //
+ } fpregset_t;
+
+ These routines provide the packing and unpacking of gregset_t and
+ fpregset_t formatted data.
+
+ */
+
+#ifdef HAVE_GREGSET_T
+
+/* This is a duplicate of the table in i386-xdep.c. */
+
+static int regmap[] =
+{
+ EAX, ECX, EDX, EBX,
+ UESP, EBP, ESI, EDI,
+ EIP, EFL, CS, SS,
+ DS, ES, FS, GS,
+};
+
+/* Prototypes for local functions */
+
+void fill_gregset (gregset_t *, int);
+
+void supply_gregset (gregset_t *);
+
+void supply_fpregset (fpregset_t *);
+
+void fill_fpregset (fpregset_t *, int);
+
+
+/* FIXME: These routine absolutely depends upon (NUM_REGS - NUM_FREGS)
+ being less than or equal to the number of registers that can be stored
+ in a gregset_t. Note that with the current scheme there will typically
+ be more registers actually stored in a gregset_t that what we know
+ about. This is bogus and should be fixed. */
+
+/* Given a pointer to a general register set in /proc format (gregset_t *),
+ unpack the register contents and supply them as gdb's idea of the current
+ register values. */
+
+void
+supply_gregset (gregset_t *gregsetp)
+{
+ register int regi;
+ register greg_t *regp = (greg_t *) gregsetp;
+ extern int regmap[];
+
+ for (regi = 0; regi < (NUM_REGS - NUM_FREGS); regi++)
+ {
+ supply_register (regi, (char *) (regp + regmap[regi]));
+ }
+}
+
+void
+fill_gregset (gregset_t *gregsetp, int regno)
+{
+ int regi;
+ register greg_t *regp = (greg_t *) gregsetp;
+ extern int regmap[];
+
+ for (regi = 0; regi < (NUM_REGS - NUM_FREGS); regi++)
+ {
+ if ((regno == -1) || (regno == regi))
+ {
+ *(regp + regmap[regi]) = *(int *) &registers[REGISTER_BYTE (regi)];
+ }
+ }
+}
+
+#endif /* HAVE_GREGSET_T */
+
+#if defined (HAVE_FPREGSET_T)
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), unpack the register contents and supply them as gdb's
+ idea of the current floating point register values. */
+
+/* FIXME: Assumes that fpregsetp contains an i387 FSAVE area. */
+#if !defined(FPREGSET_FSAVE_OFFSET)
+#define FPREGSET_FSAVE_OFFSET 0
+#endif
+
+void
+supply_fpregset (fpregset_t *fpregsetp)
+{
+ if (NUM_FREGS == 0)
+ return;
+
+ i387_supply_fsave ((char *) fpregsetp + FPREGSET_FSAVE_OFFSET);
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), update the register specified by REGNO from gdb's idea
+ of the current floating point register set. If REGNO is -1, update
+ them all. */
+
+void
+fill_fpregset (fpregset_t *fpregsetp, int regno)
+{
+ if (NUM_FREGS == 0)
+ return;
+
+ i387_fill_fsave ((char *) fpregsetp + FPREGSET_FSAVE_OFFSET, regno);
+}
+
+#endif /* defined (HAVE_FPREGSET_T) */
+
+#endif /* HAVE_SYS_PROCFS_H */
diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
new file mode 100644
index 00000000000..59b60d77a9d
--- /dev/null
+++ b/gdb/i387-tdep.c
@@ -0,0 +1,704 @@
+/* Intel 387 floating point stuff.
+ Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000,
+ 2001, 2002 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "language.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "floatformat.h"
+#include "regcache.h"
+#include "gdb_assert.h"
+#include "doublest.h"
+
+#include "i386-tdep.h"
+
+/* FIXME: Eliminate the next two functions when we have the time to
+ change all the callers. */
+
+void i387_to_double (char *from, char *to);
+void double_to_i387 (char *from, char *to);
+
+void
+i387_to_double (char *from, char *to)
+{
+ floatformat_to_double (&floatformat_i387_ext, from, (double *) to);
+}
+
+void
+double_to_i387 (char *from, char *to)
+{
+ floatformat_from_double (&floatformat_i387_ext, (double *) from, to);
+}
+
+
+/* FIXME: The functions on this page are used by the old `info float'
+ implementations that a few of the i386 targets provide. These
+ functions should be removed if all of these have been converted to
+ use the generic implementation based on the new register file
+ layout. */
+
+static void print_387_control_bits (unsigned int control);
+static void print_387_status_bits (unsigned int status);
+
+static void
+print_387_control_bits (unsigned int control)
+{
+ switch ((control >> 8) & 3)
+ {
+ case 0:
+ puts_unfiltered (" 24 bit; ");
+ break;
+ case 1:
+ puts_unfiltered (" (bad); ");
+ break;
+ case 2:
+ puts_unfiltered (" 53 bit; ");
+ break;
+ case 3:
+ puts_unfiltered (" 64 bit; ");
+ break;
+ }
+ switch ((control >> 10) & 3)
+ {
+ case 0:
+ puts_unfiltered ("NEAR; ");
+ break;
+ case 1:
+ puts_unfiltered ("DOWN; ");
+ break;
+ case 2:
+ puts_unfiltered ("UP; ");
+ break;
+ case 3:
+ puts_unfiltered ("CHOP; ");
+ break;
+ }
+ if (control & 0x3f)
+ {
+ puts_unfiltered ("mask");
+ if (control & 0x0001)
+ puts_unfiltered (" INVAL");
+ if (control & 0x0002)
+ puts_unfiltered (" DENOR");
+ if (control & 0x0004)
+ puts_unfiltered (" DIVZ");
+ if (control & 0x0008)
+ puts_unfiltered (" OVERF");
+ if (control & 0x0010)
+ puts_unfiltered (" UNDER");
+ if (control & 0x0020)
+ puts_unfiltered (" LOS");
+ puts_unfiltered (";");
+ }
+
+ if (control & 0xe080)
+ warning ("\nreserved bits on: %s",
+ local_hex_string (control & 0xe080));
+}
+
+void
+print_387_control_word (unsigned int control)
+{
+ printf_filtered ("control %s:", local_hex_string(control & 0xffff));
+ print_387_control_bits (control);
+ puts_unfiltered ("\n");
+}
+
+static void
+print_387_status_bits (unsigned int status)
+{
+ printf_unfiltered (" flags %d%d%d%d; ",
+ (status & 0x4000) != 0,
+ (status & 0x0400) != 0,
+ (status & 0x0200) != 0,
+ (status & 0x0100) != 0);
+ printf_unfiltered ("top %d; ", (status >> 11) & 7);
+ if (status & 0xff)
+ {
+ puts_unfiltered ("excep");
+ if (status & 0x0001) puts_unfiltered (" INVAL");
+ if (status & 0x0002) puts_unfiltered (" DENOR");
+ if (status & 0x0004) puts_unfiltered (" DIVZ");
+ if (status & 0x0008) puts_unfiltered (" OVERF");
+ if (status & 0x0010) puts_unfiltered (" UNDER");
+ if (status & 0x0020) puts_unfiltered (" LOS");
+ if (status & 0x0040) puts_unfiltered (" STACK");
+ }
+}
+
+void
+print_387_status_word (unsigned int status)
+{
+ printf_filtered ("status %s:", local_hex_string (status & 0xffff));
+ print_387_status_bits (status);
+ puts_unfiltered ("\n");
+}
+
+
+/* Implement the `info float' layout based on the register definitions
+ in `tm-i386.h'. */
+
+/* Print the floating point number specified by RAW. */
+static void
+print_i387_value (char *raw)
+{
+ DOUBLEST value;
+
+ /* Using extract_typed_floating here might affect the representation
+ of certain numbers such as NaNs, even if GDB is running natively.
+ This is fine since our caller already detects such special
+ numbers and we print the hexadecimal representation anyway. */
+ value = extract_typed_floating (raw, builtin_type_i387_ext);
+
+ /* We try to print 19 digits. The last digit may or may not contain
+ garbage, but we'd better print one too many. We need enough room
+ to print the value, 1 position for the sign, 1 for the decimal
+ point, 19 for the digits and 6 for the exponent adds up to 27. */
+#ifdef PRINTF_HAS_LONG_DOUBLE
+ printf_filtered (" %-+27.19Lg", (long double) value);
+#else
+ printf_filtered (" %-+27.19g", (double) value);
+#endif
+}
+
+/* Print the classification for the register contents RAW. */
+static void
+print_i387_ext (unsigned char *raw)
+{
+ int sign;
+ int integer;
+ unsigned int exponent;
+ unsigned long fraction[2];
+
+ sign = raw[9] & 0x80;
+ integer = raw[7] & 0x80;
+ exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
+ fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
+ fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
+ | (raw[5] << 8) | raw[4]);
+
+ if (exponent == 0x7fff && integer)
+ {
+ if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000)
+ /* Infinity. */
+ printf_filtered (" %cInf", (sign ? '-' : '+'));
+ else if (sign && fraction[0] == 0x00000000 && fraction[1] == 0x40000000)
+ /* Real Indefinite (QNaN). */
+ puts_unfiltered (" Real Indefinite (QNaN)");
+ else if (fraction[1] & 0x40000000)
+ /* QNaN. */
+ puts_filtered (" QNaN");
+ else
+ /* SNaN. */
+ puts_filtered (" SNaN");
+ }
+ else if (exponent < 0x7fff && exponent > 0x0000 && integer)
+ /* Normal. */
+ print_i387_value (raw);
+ else if (exponent == 0x0000)
+ {
+ /* Denormal or zero. */
+ print_i387_value (raw);
+
+ if (integer)
+ /* Pseudo-denormal. */
+ puts_filtered (" Pseudo-denormal");
+ else if (fraction[0] || fraction[1])
+ /* Denormal. */
+ puts_filtered (" Denormal");
+ }
+ else
+ /* Unsupported. */
+ puts_filtered (" Unsupported");
+}
+
+/* Print the status word STATUS. */
+static void
+print_i387_status_word (unsigned int status)
+{
+ printf_filtered ("Status Word: %s",
+ local_hex_string_custom (status, "04"));
+ puts_filtered (" ");
+ printf_filtered (" %s", (status & 0x0001) ? "IE" : " ");
+ printf_filtered (" %s", (status & 0x0002) ? "DE" : " ");
+ printf_filtered (" %s", (status & 0x0004) ? "ZE" : " ");
+ printf_filtered (" %s", (status & 0x0008) ? "OE" : " ");
+ printf_filtered (" %s", (status & 0x0010) ? "UE" : " ");
+ printf_filtered (" %s", (status & 0x0020) ? "PE" : " ");
+ puts_filtered (" ");
+ printf_filtered (" %s", (status & 0x0080) ? "ES" : " ");
+ puts_filtered (" ");
+ printf_filtered (" %s", (status & 0x0040) ? "SF" : " ");
+ puts_filtered (" ");
+ printf_filtered (" %s", (status & 0x0100) ? "C0" : " ");
+ printf_filtered (" %s", (status & 0x0200) ? "C1" : " ");
+ printf_filtered (" %s", (status & 0x0400) ? "C2" : " ");
+ printf_filtered (" %s", (status & 0x4000) ? "C3" : " ");
+
+ puts_filtered ("\n");
+
+ printf_filtered (" TOP: %d\n", ((status >> 11) & 7));
+}
+
+/* Print the control word CONTROL. */
+static void
+print_i387_control_word (unsigned int control)
+{
+ printf_filtered ("Control Word: %s",
+ local_hex_string_custom (control, "04"));
+ puts_filtered (" ");
+ printf_filtered (" %s", (control & 0x0001) ? "IM" : " ");
+ printf_filtered (" %s", (control & 0x0002) ? "DM" : " ");
+ printf_filtered (" %s", (control & 0x0004) ? "ZM" : " ");
+ printf_filtered (" %s", (control & 0x0008) ? "OM" : " ");
+ printf_filtered (" %s", (control & 0x0010) ? "UM" : " ");
+ printf_filtered (" %s", (control & 0x0020) ? "PM" : " ");
+
+ puts_filtered ("\n");
+
+ puts_filtered (" PC: ");
+ switch ((control >> 8) & 3)
+ {
+ case 0:
+ puts_filtered ("Single Precision (24-bits)\n");
+ break;
+ case 1:
+ puts_filtered ("Reserved\n");
+ break;
+ case 2:
+ puts_filtered ("Double Precision (53-bits)\n");
+ break;
+ case 3:
+ puts_filtered ("Extended Precision (64-bits)\n");
+ break;
+ }
+
+ puts_filtered (" RC: ");
+ switch ((control >> 10) & 3)
+ {
+ case 0:
+ puts_filtered ("Round to nearest\n");
+ break;
+ case 1:
+ puts_filtered ("Round down\n");
+ break;
+ case 2:
+ puts_filtered ("Round up\n");
+ break;
+ case 3:
+ puts_filtered ("Round toward zero\n");
+ break;
+ }
+}
+
+/* Print out the i387 floating poin state. */
+void
+i387_float_info (void)
+{
+ unsigned int fctrl;
+ unsigned int fstat;
+ unsigned int ftag;
+ unsigned int fiseg;
+ unsigned int fioff;
+ unsigned int foseg;
+ unsigned int fooff;
+ unsigned int fop;
+ int fpreg;
+ int top;
+
+ fctrl = read_register (FCTRL_REGNUM);
+ fstat = read_register (FSTAT_REGNUM);
+ ftag = read_register (FTAG_REGNUM);
+ fiseg = read_register (FCS_REGNUM);
+ fioff = read_register (FCOFF_REGNUM);
+ foseg = read_register (FDS_REGNUM);
+ fooff = read_register (FDOFF_REGNUM);
+ fop = read_register (FOP_REGNUM);
+
+ top = ((fstat >> 11) & 7);
+
+ for (fpreg = 7; fpreg >= 0; fpreg--)
+ {
+ unsigned char raw[FPU_REG_RAW_SIZE];
+ int tag = (ftag >> (fpreg * 2)) & 3;
+ int i;
+
+ printf_filtered ("%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
+
+ switch (tag)
+ {
+ case 0:
+ puts_filtered ("Valid ");
+ break;
+ case 1:
+ puts_filtered ("Zero ");
+ break;
+ case 2:
+ puts_filtered ("Special ");
+ break;
+ case 3:
+ puts_filtered ("Empty ");
+ break;
+ }
+
+ read_register_gen ((fpreg + 8 - top) % 8 + FP0_REGNUM, raw);
+
+ puts_filtered ("0x");
+ for (i = 9; i >= 0; i--)
+ printf_filtered ("%02x", raw[i]);
+
+ if (tag != 3)
+ print_i387_ext (raw);
+
+ puts_filtered ("\n");
+ }
+
+ puts_filtered ("\n");
+
+ print_i387_status_word (fstat);
+ print_i387_control_word (fctrl);
+ printf_filtered ("Tag Word: %s\n",
+ local_hex_string_custom (ftag, "04"));
+ printf_filtered ("Instruction Pointer: %s:",
+ local_hex_string_custom (fiseg, "02"));
+ printf_filtered ("%s\n", local_hex_string_custom (fioff, "08"));
+ printf_filtered ("Operand Pointer: %s:",
+ local_hex_string_custom (foseg, "02"));
+ printf_filtered ("%s\n", local_hex_string_custom (fooff, "08"));
+ printf_filtered ("Opcode: %s\n",
+ local_hex_string_custom (fop ? (fop | 0xd800) : 0, "04"));
+}
+
+/* FIXME: kettenis/2000-05-21: Right now more than a few i386 targets
+ define their own routines to manage the floating-point registers in
+ GDB's register array. Most (if not all) of these targets use the
+ format used by the "fsave" instruction in their communication with
+ the OS. They should all be converted to use the routines below. */
+
+/* At fsave_offset[REGNUM] you'll find the offset to the location in
+ the data structure used by the "fsave" instruction where GDB
+ register REGNUM is stored. */
+
+static int fsave_offset[] =
+{
+ 28 + 0 * FPU_REG_RAW_SIZE, /* FP0_REGNUM through ... */
+ 28 + 1 * FPU_REG_RAW_SIZE,
+ 28 + 2 * FPU_REG_RAW_SIZE,
+ 28 + 3 * FPU_REG_RAW_SIZE,
+ 28 + 4 * FPU_REG_RAW_SIZE,
+ 28 + 5 * FPU_REG_RAW_SIZE,
+ 28 + 6 * FPU_REG_RAW_SIZE,
+ 28 + 7 * FPU_REG_RAW_SIZE, /* ... FP7_REGNUM. */
+ 0, /* FCTRL_REGNUM (16 bits). */
+ 4, /* FSTAT_REGNUM (16 bits). */
+ 8, /* FTAG_REGNUM (16 bits). */
+ 16, /* FISEG_REGNUM (16 bits). */
+ 12, /* FIOFF_REGNUM. */
+ 24, /* FOSEG_REGNUM. */
+ 20, /* FOOFF_REGNUM. */
+ 18 /* FOP_REGNUM (bottom 11 bits). */
+};
+
+#define FSAVE_ADDR(fsave, regnum) (fsave + fsave_offset[regnum - FP0_REGNUM])
+
+
+/* Fill register REGNUM in GDB's register array with the appropriate
+ value from *FSAVE. This function masks off any of the reserved
+ bits in *FSAVE. */
+
+void
+i387_supply_register (int regnum, char *fsave)
+{
+ /* Most of the FPU control registers occupy only 16 bits in
+ the fsave area. Give those a special treatment. */
+ if (regnum >= FPC_REGNUM
+ && regnum != FIOFF_REGNUM && regnum != FOOFF_REGNUM)
+ {
+ unsigned char val[4];
+
+ memcpy (val, FSAVE_ADDR (fsave, regnum), 2);
+ val[2] = val[3] = 0;
+ if (regnum == FOP_REGNUM)
+ val[1] &= ((1 << 3) - 1);
+ supply_register (regnum, val);
+ }
+ else
+ supply_register (regnum, FSAVE_ADDR (fsave, regnum));
+}
+
+/* Fill GDB's register array with the floating-point register values
+ in *FSAVE. This function masks off any of the reserved
+ bits in *FSAVE. */
+
+void
+i387_supply_fsave (char *fsave)
+{
+ int i;
+
+ for (i = FP0_REGNUM; i < XMM0_REGNUM; i++)
+ i387_supply_register (i, fsave);
+}
+
+/* Fill register REGNUM (if it is a floating-point register) in *FSAVE
+ with the value in GDB's register array. If REGNUM is -1, do this
+ for all registers. This function doesn't touch any of the reserved
+ bits in *FSAVE. */
+
+void
+i387_fill_fsave (char *fsave, int regnum)
+{
+ int i;
+
+ for (i = FP0_REGNUM; i < XMM0_REGNUM; i++)
+ if (regnum == -1 || regnum == i)
+ {
+ /* Most of the FPU control registers occupy only 16 bits in
+ the fsave area. Give those a special treatment. */
+ if (i >= FPC_REGNUM
+ && i != FIOFF_REGNUM && i != FOOFF_REGNUM)
+ {
+ unsigned char buf[4];
+
+ regcache_collect (i, buf);
+
+ if (i == FOP_REGNUM)
+ {
+ /* The opcode occupies only 11 bits. Make sure we
+ don't touch the other bits. */
+ buf[1] &= ((1 << 3) - 1);
+ buf[1] |= ((FSAVE_ADDR (fsave, i))[1] & ~((1 << 3) - 1));
+ }
+ memcpy (FSAVE_ADDR (fsave, i), buf, 2);
+ }
+ else
+ regcache_collect (i, FSAVE_ADDR (fsave, i));
+ }
+}
+
+
+/* At fxsave_offset[REGNUM] you'll find the offset to the location in
+ the data structure used by the "fxsave" instruction where GDB
+ register REGNUM is stored. */
+
+static int fxsave_offset[] =
+{
+ 32, /* FP0_REGNUM through ... */
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 144, /* ... FP7_REGNUM (80 bits each). */
+ 0, /* FCTRL_REGNUM (16 bits). */
+ 2, /* FSTAT_REGNUM (16 bits). */
+ 4, /* FTAG_REGNUM (16 bits). */
+ 12, /* FISEG_REGNUM (16 bits). */
+ 8, /* FIOFF_REGNUM. */
+ 20, /* FOSEG_REGNUM (16 bits). */
+ 16, /* FOOFF_REGNUM. */
+ 6, /* FOP_REGNUM (bottom 11 bits). */
+ 160, /* XMM0_REGNUM through ... */
+ 176,
+ 192,
+ 208,
+ 224,
+ 240,
+ 256,
+ 272, /* ... XMM7_REGNUM (128 bits each). */
+ 24, /* MXCSR_REGNUM. */
+};
+
+#define FXSAVE_ADDR(fxsave, regnum) \
+ (fxsave + fxsave_offset[regnum - FP0_REGNUM])
+
+static int i387_tag (unsigned char *raw);
+
+
+/* Fill GDB's register array with the floating-point and SSE register
+ values in *FXSAVE. This function masks off any of the reserved
+ bits in *FXSAVE. */
+
+void
+i387_supply_fxsave (char *fxsave)
+{
+ int i, last_regnum = MXCSR_REGNUM;
+
+ if (gdbarch_tdep (current_gdbarch)->num_xmm_regs == 0)
+ last_regnum = FOP_REGNUM;
+
+ for (i = FP0_REGNUM; i <= last_regnum; i++)
+ {
+ /* Most of the FPU control registers occupy only 16 bits in
+ the fxsave area. Give those a special treatment. */
+ if (i >= FPC_REGNUM && i < XMM0_REGNUM
+ && i != FIOFF_REGNUM && i != FOOFF_REGNUM)
+ {
+ unsigned char val[4];
+
+ memcpy (val, FXSAVE_ADDR (fxsave, i), 2);
+ val[2] = val[3] = 0;
+ if (i == FOP_REGNUM)
+ val[1] &= ((1 << 3) - 1);
+ else if (i== FTAG_REGNUM)
+ {
+ /* The fxsave area contains a simplified version of the
+ tag word. We have to look at the actual 80-bit FP
+ data to recreate the traditional i387 tag word. */
+
+ unsigned long ftag = 0;
+ int fpreg;
+ int top;
+
+ top = (((FXSAVE_ADDR (fxsave, FSTAT_REGNUM))[1] >> 3) & 0x7);
+
+ for (fpreg = 7; fpreg >= 0; fpreg--)
+ {
+ int tag;
+
+ if (val[0] & (1 << fpreg))
+ {
+ int regnum = (fpreg + 8 - top) % 8 + FP0_REGNUM;
+ tag = i387_tag (FXSAVE_ADDR (fxsave, regnum));
+ }
+ else
+ tag = 3; /* Empty */
+
+ ftag |= tag << (2 * fpreg);
+ }
+ val[0] = ftag & 0xff;
+ val[1] = (ftag >> 8) & 0xff;
+ }
+ supply_register (i, val);
+ }
+ else
+ supply_register (i, FXSAVE_ADDR (fxsave, i));
+ }
+}
+
+/* Fill register REGNUM (if it is a floating-point or SSE register) in
+ *FXSAVE with the value in GDB's register array. If REGNUM is -1, do
+ this for all registers. This function doesn't touch any of the
+ reserved bits in *FXSAVE. */
+
+void
+i387_fill_fxsave (char *fxsave, int regnum)
+{
+ int i, last_regnum = MXCSR_REGNUM;
+
+ if (gdbarch_tdep (current_gdbarch)->num_xmm_regs == 0)
+ last_regnum = FOP_REGNUM;
+
+ for (i = FP0_REGNUM; i <= last_regnum; i++)
+ if (regnum == -1 || regnum == i)
+ {
+ /* Most of the FPU control registers occupy only 16 bits in
+ the fxsave area. Give those a special treatment. */
+ if (i >= FPC_REGNUM && i < XMM0_REGNUM
+ && i != FIOFF_REGNUM && i != FDOFF_REGNUM)
+ {
+ unsigned char buf[4];
+
+ regcache_collect (i, buf);
+
+ if (i == FOP_REGNUM)
+ {
+ /* The opcode occupies only 11 bits. Make sure we
+ don't touch the other bits. */
+ buf[1] &= ((1 << 3) - 1);
+ buf[1] |= ((FXSAVE_ADDR (fxsave, i))[1] & ~((1 << 3) - 1));
+ }
+ else if (i == FTAG_REGNUM)
+ {
+ /* Converting back is much easier. */
+
+ unsigned short ftag;
+ int fpreg;
+
+ ftag = (buf[1] << 8) | buf[0];
+ buf[0] = 0;
+ buf[1] = 0;
+
+ for (fpreg = 7; fpreg >= 0; fpreg--)
+ {
+ int tag = (ftag >> (fpreg * 2)) & 3;
+
+ if (tag != 3)
+ buf[0] |= (1 << fpreg);
+ }
+ }
+ memcpy (FXSAVE_ADDR (fxsave, i), buf, 2);
+ }
+ else
+ regcache_collect (i, FXSAVE_ADDR (fxsave, i));
+ }
+}
+
+/* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
+ *RAW. */
+
+static int
+i387_tag (unsigned char *raw)
+{
+ int integer;
+ unsigned int exponent;
+ unsigned long fraction[2];
+
+ integer = raw[7] & 0x80;
+ exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
+ fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
+ fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
+ | (raw[5] << 8) | raw[4]);
+
+ if (exponent == 0x7fff)
+ {
+ /* Special. */
+ return (2);
+ }
+ else if (exponent == 0x0000)
+ {
+ if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
+ {
+ /* Zero. */
+ return (1);
+ }
+ else
+ {
+ /* Special. */
+ return (2);
+ }
+ }
+ else
+ {
+ if (integer)
+ {
+ /* Valid. */
+ return (0);
+ }
+ else
+ {
+ /* Special. */
+ return (2);
+ }
+ }
+}
diff --git a/gdb/i387-tdep.h b/gdb/i387-tdep.h
new file mode 100644
index 00000000000..5bfd06eb710
--- /dev/null
+++ b/gdb/i387-tdep.h
@@ -0,0 +1,56 @@
+/* Target-dependent code for the i387.
+ Copyright 2000, 2001 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. */
+
+#ifndef I387_TDEP_H
+#define I387_TDEP_H
+
+/* Fill register REGNUM in GDB's register array with the appropriate
+ value from *FSAVE. This function masks off any of the reserved
+ bits in *FSAVE. */
+
+extern void i387_supply_register (int regnum, char *fsave);
+
+/* Fill GDB's register array with the floating-point register values
+ in *FSAVE. This function masks off any of the reserved
+ bits in *FSAVE. */
+
+extern void i387_supply_fsave (char *fsave);
+
+/* Fill register REGNUM (if it is a floating-point register) in *FSAVE
+ with the value in GDB's register array. If REGNUM is -1, do this
+ for all registers. This function doesn't touch any of the reserved
+ bits in *FSAVE. */
+
+extern void i387_fill_fsave (char *fsave, int regnum);
+
+/* Fill GDB's register array with the floating-point and SSE register
+ values in *FXSAVE. This function masks off any of the reserved
+ bits in *FXSAVE. */
+
+extern void i387_supply_fxsave (char *fxsave);
+
+/* Fill register REGNUM (if it is a floating-point or SSE register) in
+ *FXSAVE with the value in GDB's register array. If REGNUM is -1, do
+ this for all registers. This function doesn't touch any of the
+ reserved bits in *FXSAVE. */
+
+extern void i387_fill_fxsave (char *fxsave, int regnum);
+
+#endif /* i387-tdep.h */
diff --git a/gdb/i960-tdep.c b/gdb/i960-tdep.c
new file mode 100644
index 00000000000..98718a387a0
--- /dev/null
+++ b/gdb/i960-tdep.c
@@ -0,0 +1,1055 @@
+/* Target-machine dependent code for the Intel 960
+
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
+ 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Intel Corporation.
+ examine_prologue and other parts contributed by Wind River Systems.
+
+ 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 "defs.h"
+#include "symtab.h"
+#include "value.h"
+#include "frame.h"
+#include "floatformat.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+
+static CORE_ADDR next_insn (CORE_ADDR memaddr,
+ unsigned int *pword1, unsigned int *pword2);
+
+struct type *
+i960_register_type (int regnum)
+{
+ if (regnum < FP0_REGNUM)
+ return builtin_type_int32;
+ else
+ return builtin_type_i960_ext;
+}
+
+
+/* Does the specified function use the "struct returning" convention
+ or the "value returning" convention? The "value returning" convention
+ almost invariably returns the entire value in registers. The
+ "struct returning" convention often returns the entire value in
+ memory, and passes a pointer (out of or into the function) saying
+ where the value (is or should go).
+
+ Since this sometimes depends on whether it was compiled with GCC,
+ this is also an argument. This is used in call_function to build a
+ stack, and in value_being_returned to print return values.
+
+ On i960, a structure is returned in registers g0-g3, if it will fit.
+ If it's more than 16 bytes long, g13 pointed to it on entry. */
+
+int
+i960_use_struct_convention (int gcc_p, struct type *type)
+{
+ return (TYPE_LENGTH (type) > 16);
+}
+
+/* gdb960 is always running on a non-960 host. Check its characteristics.
+ This routine must be called as part of gdb initialization. */
+
+static void
+check_host (void)
+{
+ int i;
+
+ static struct typestruct
+ {
+ int hostsize; /* Size of type on host */
+ int i960size; /* Size of type on i960 */
+ char *typename; /* Name of type, for error msg */
+ }
+ types[] =
+ {
+ {
+ sizeof (short), 2, "short"
+ }
+ ,
+ {
+ sizeof (int), 4, "int"
+ }
+ ,
+ {
+ sizeof (long), 4, "long"
+ }
+ ,
+ {
+ sizeof (float), 4, "float"
+ }
+ ,
+ {
+ sizeof (double), 8, "double"
+ }
+ ,
+ {
+ sizeof (char *), 4, "pointer"
+ }
+ ,
+ };
+#define TYPELEN (sizeof(types) / sizeof(struct typestruct))
+
+ /* Make sure that host type sizes are same as i960
+ */
+ for (i = 0; i < TYPELEN; i++)
+ {
+ if (types[i].hostsize != types[i].i960size)
+ {
+ printf_unfiltered ("sizeof(%s) != %d: PROCEED AT YOUR OWN RISK!\n",
+ types[i].typename, types[i].i960size);
+ }
+
+ }
+}
+
+/* Is this register part of the register window system? A yes answer
+ implies that 1) The name of this register will not be the same in
+ other frames, and 2) This register is automatically "saved" upon
+ subroutine calls and thus there is no need to search more than one
+ stack frame for it.
+
+ On the i960, in fact, the name of this register in another frame is
+ "mud" -- there is no overlap between the windows. Each window is
+ simply saved into the stack (true for our purposes, after having been
+ flushed; normally they reside on-chip and are restored from on-chip
+ without ever going to memory). */
+
+static int
+register_in_window_p (int regnum)
+{
+ return regnum <= R15_REGNUM;
+}
+
+/* i960_find_saved_register ()
+
+ Return the address in which frame FRAME's value of register REGNUM
+ has been saved in memory. Or return zero if it has not been saved.
+ If REGNUM specifies the SP, the value we return is actually the SP
+ value, not an address where it was saved. */
+
+static CORE_ADDR
+i960_find_saved_register (struct frame_info *frame, int regnum)
+{
+ register struct frame_info *frame1 = NULL;
+ register CORE_ADDR addr = 0;
+
+ if (frame == NULL) /* No regs saved if want current frame */
+ return 0;
+
+ /* We assume that a register in a register window will only be saved
+ in one place (since the name changes and/or disappears as you go
+ towards inner frames), so we only call get_frame_saved_regs on
+ the current frame. This is directly in contradiction to the
+ usage below, which assumes that registers used in a frame must be
+ saved in a lower (more interior) frame. This change is a result
+ of working on a register window machine; get_frame_saved_regs
+ always returns the registers saved within a frame, within the
+ context (register namespace) of that frame. */
+
+ /* However, note that we don't want this to return anything if
+ nothing is saved (if there's a frame inside of this one). Also,
+ callers to this routine asking for the stack pointer want the
+ stack pointer saved for *this* frame; this is returned from the
+ next frame. */
+
+ if (register_in_window_p (regnum))
+ {
+ frame1 = get_next_frame (frame);
+ if (!frame1)
+ return 0; /* Registers of this frame are active. */
+
+ /* Get the SP from the next frame in; it will be this
+ current frame. */
+ if (regnum != SP_REGNUM)
+ frame1 = frame;
+
+ FRAME_INIT_SAVED_REGS (frame1);
+ return frame1->saved_regs[regnum]; /* ... which might be zero */
+ }
+
+ /* Note that this next routine assumes that registers used in
+ frame x will be saved only in the frame that x calls and
+ frames interior to it. This is not true on the sparc, but the
+ above macro takes care of it, so we should be all right. */
+ while (1)
+ {
+ QUIT;
+ frame1 = get_next_frame (frame);
+ if (frame1 == 0)
+ break;
+ frame = frame1;
+ FRAME_INIT_SAVED_REGS (frame1);
+ if (frame1->saved_regs[regnum])
+ addr = frame1->saved_regs[regnum];
+ }
+
+ return addr;
+}
+
+/* i960_get_saved_register ()
+
+ Find register number REGNUM relative to FRAME and put its (raw,
+ target format) contents in *RAW_BUFFER. Set *OPTIMIZED if the
+ variable was optimized out (and thus can't be fetched). Set *LVAL
+ to lval_memory, lval_register, or not_lval, depending on whether
+ the value was fetched from memory, from a register, or in a strange
+ and non-modifiable way (e.g. a frame pointer which was calculated
+ rather than fetched). Set *ADDRP to the address, either in memory
+ on as a REGISTER_BYTE offset into the registers array.
+
+ Note that this implementation never sets *LVAL to not_lval. But it
+ can be replaced by defining GET_SAVED_REGISTER and supplying your
+ own.
+
+ The argument RAW_BUFFER must point to aligned memory. */
+
+void
+i960_get_saved_register (char *raw_buffer,
+ int *optimized,
+ CORE_ADDR *addrp,
+ struct frame_info *frame,
+ int regnum,
+ enum lval_type *lval)
+{
+ CORE_ADDR addr;
+
+ if (!target_has_registers)
+ error ("No registers.");
+
+ /* Normal systems don't optimize out things with register numbers. */
+ if (optimized != NULL)
+ *optimized = 0;
+ addr = i960_find_saved_register (frame, regnum);
+ if (addr != 0)
+ {
+ if (lval != NULL)
+ *lval = lval_memory;
+ if (regnum == SP_REGNUM)
+ {
+ if (raw_buffer != NULL)
+ {
+ /* Put it back in target format. */
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
+ (LONGEST) addr);
+ }
+ if (addrp != NULL)
+ *addrp = 0;
+ return;
+ }
+ if (raw_buffer != NULL)
+ target_read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum));
+ }
+ else
+ {
+ if (lval != NULL)
+ *lval = lval_register;
+ addr = REGISTER_BYTE (regnum);
+ if (raw_buffer != NULL)
+ read_register_gen (regnum, raw_buffer);
+ }
+ if (addrp != NULL)
+ *addrp = addr;
+}
+
+/* Examine an i960 function prologue, recording the addresses at which
+ registers are saved explicitly by the prologue code, and returning
+ the address of the first instruction after the prologue (but not
+ after the instruction at address LIMIT, as explained below).
+
+ LIMIT places an upper bound on addresses of the instructions to be
+ examined. If the prologue code scan reaches LIMIT, the scan is
+ aborted and LIMIT is returned. This is used, when examining the
+ prologue for the current frame, to keep examine_prologue () from
+ claiming that a given register has been saved when in fact the
+ instruction that saves it has not yet been executed. LIMIT is used
+ at other times to stop the scan when we hit code after the true
+ function prologue (e.g. for the first source line) which might
+ otherwise be mistaken for function prologue.
+
+ The format of the function prologue matched by this routine is
+ derived from examination of the source to gcc960 1.21, particularly
+ the routine i960_function_prologue (). A "regular expression" for
+ the function prologue is given below:
+
+ (lda LRn, g14
+ mov g14, g[0-7]
+ (mov 0, g14) | (lda 0, g14))?
+
+ (mov[qtl]? g[0-15], r[4-15])*
+ ((addo [1-31], sp, sp) | (lda n(sp), sp))?
+ (st[qtl]? g[0-15], n(fp))*
+
+ (cmpobne 0, g14, LFn
+ mov sp, g14
+ lda 0x30(sp), sp
+ LFn: stq g0, (g14)
+ stq g4, 0x10(g14)
+ stq g8, 0x20(g14))?
+
+ (st g14, n(fp))?
+ (mov g13,r[4-15])?
+ */
+
+/* Macros for extracting fields from i960 instructions. */
+
+#define BITMASK(pos, width) (((0x1 << (width)) - 1) << (pos))
+#define EXTRACT_FIELD(val, pos, width) ((val) >> (pos) & BITMASK (0, width))
+
+#define REG_SRC1(insn) EXTRACT_FIELD (insn, 0, 5)
+#define REG_SRC2(insn) EXTRACT_FIELD (insn, 14, 5)
+#define REG_SRCDST(insn) EXTRACT_FIELD (insn, 19, 5)
+#define MEM_SRCDST(insn) EXTRACT_FIELD (insn, 19, 5)
+#define MEMA_OFFSET(insn) EXTRACT_FIELD (insn, 0, 12)
+
+/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
+ is not the address of a valid instruction, the address of the next
+ instruction beyond ADDR otherwise. *PWORD1 receives the first word
+ of the instruction, and (for two-word instructions), *PWORD2 receives
+ the second. */
+
+#define NEXT_PROLOGUE_INSN(addr, lim, pword1, pword2) \
+ (((addr) < (lim)) ? next_insn (addr, pword1, pword2) : 0)
+
+static CORE_ADDR
+examine_prologue (register CORE_ADDR ip, register CORE_ADDR limit,
+ CORE_ADDR frame_addr, struct frame_saved_regs *fsr)
+{
+ register CORE_ADDR next_ip;
+ register int src, dst;
+ register unsigned int *pcode;
+ unsigned int insn1, insn2;
+ int size;
+ int within_leaf_prologue;
+ CORE_ADDR save_addr;
+ static unsigned int varargs_prologue_code[] =
+ {
+ 0x3507a00c, /* cmpobne 0x0, g14, LFn */
+ 0x5cf01601, /* mov sp, g14 */
+ 0x8c086030, /* lda 0x30(sp), sp */
+ 0xb2879000, /* LFn: stq g0, (g14) */
+ 0xb2a7a010, /* stq g4, 0x10(g14) */
+ 0xb2c7a020 /* stq g8, 0x20(g14) */
+ };
+
+ /* Accept a leaf procedure prologue code fragment if present.
+ Note that ip might point to either the leaf or non-leaf
+ entry point; we look for the non-leaf entry point first: */
+
+ within_leaf_prologue = 0;
+ if ((next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2))
+ && ((insn1 & 0xfffff000) == 0x8cf00000 /* lda LRx, g14 (MEMA) */
+ || (insn1 & 0xfffffc60) == 0x8cf03000)) /* lda LRx, g14 (MEMB) */
+ {
+ within_leaf_prologue = 1;
+ next_ip = NEXT_PROLOGUE_INSN (next_ip, limit, &insn1, &insn2);
+ }
+
+ /* Now look for the prologue code at a leaf entry point: */
+
+ if (next_ip
+ && (insn1 & 0xff87ffff) == 0x5c80161e /* mov g14, gx */
+ && REG_SRCDST (insn1) <= G0_REGNUM + 7)
+ {
+ within_leaf_prologue = 1;
+ if ((next_ip = NEXT_PROLOGUE_INSN (next_ip, limit, &insn1, &insn2))
+ && (insn1 == 0x8cf00000 /* lda 0, g14 */
+ || insn1 == 0x5cf01e00)) /* mov 0, g14 */
+ {
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+ within_leaf_prologue = 0;
+ }
+ }
+
+ /* If something that looks like the beginning of a leaf prologue
+ has been seen, but the remainder of the prologue is missing, bail.
+ We don't know what we've got. */
+
+ if (within_leaf_prologue)
+ return (ip);
+
+ /* Accept zero or more instances of "mov[qtl]? gx, ry", where y >= 4.
+ This may cause us to mistake the moving of a register
+ parameter to a local register for the saving of a callee-saved
+ register, but that can't be helped, since with the
+ "-fcall-saved" flag, any register can be made callee-saved. */
+
+ while (next_ip
+ && (insn1 & 0xfc802fb0) == 0x5c000610
+ && (dst = REG_SRCDST (insn1)) >= (R0_REGNUM + 4))
+ {
+ src = REG_SRC1 (insn1);
+ size = EXTRACT_FIELD (insn1, 24, 2) + 1;
+ save_addr = frame_addr + ((dst - R0_REGNUM) * 4);
+ while (size--)
+ {
+ fsr->regs[src++] = save_addr;
+ save_addr += 4;
+ }
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+ }
+
+ /* Accept an optional "addo n, sp, sp" or "lda n(sp), sp". */
+
+ if (next_ip &&
+ ((insn1 & 0xffffffe0) == 0x59084800 /* addo n, sp, sp */
+ || (insn1 & 0xfffff000) == 0x8c086000 /* lda n(sp), sp (MEMA) */
+ || (insn1 & 0xfffffc60) == 0x8c087400)) /* lda n(sp), sp (MEMB) */
+ {
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+ }
+
+ /* Accept zero or more instances of "st[qtl]? gx, n(fp)".
+ This may cause us to mistake the copying of a register
+ parameter to the frame for the saving of a callee-saved
+ register, but that can't be helped, since with the
+ "-fcall-saved" flag, any register can be made callee-saved.
+ We can, however, refuse to accept a save of register g14,
+ since that is matched explicitly below. */
+
+ while (next_ip &&
+ ((insn1 & 0xf787f000) == 0x9287e000 /* stl? gx, n(fp) (MEMA) */
+ || (insn1 & 0xf787fc60) == 0x9287f400 /* stl? gx, n(fp) (MEMB) */
+ || (insn1 & 0xef87f000) == 0xa287e000 /* st[tq] gx, n(fp) (MEMA) */
+ || (insn1 & 0xef87fc60) == 0xa287f400) /* st[tq] gx, n(fp) (MEMB) */
+ && ((src = MEM_SRCDST (insn1)) != G14_REGNUM))
+ {
+ save_addr = frame_addr + ((insn1 & BITMASK (12, 1))
+ ? insn2 : MEMA_OFFSET (insn1));
+ size = (insn1 & BITMASK (29, 1)) ? ((insn1 & BITMASK (28, 1)) ? 4 : 3)
+ : ((insn1 & BITMASK (27, 1)) ? 2 : 1);
+ while (size--)
+ {
+ fsr->regs[src++] = save_addr;
+ save_addr += 4;
+ }
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+ }
+
+ /* Accept the varargs prologue code if present. */
+
+ size = sizeof (varargs_prologue_code) / sizeof (int);
+ pcode = varargs_prologue_code;
+ while (size-- && next_ip && *pcode++ == insn1)
+ {
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+ }
+
+ /* Accept an optional "st g14, n(fp)". */
+
+ if (next_ip &&
+ ((insn1 & 0xfffff000) == 0x92f7e000 /* st g14, n(fp) (MEMA) */
+ || (insn1 & 0xfffffc60) == 0x92f7f400)) /* st g14, n(fp) (MEMB) */
+ {
+ fsr->regs[G14_REGNUM] = frame_addr + ((insn1 & BITMASK (12, 1))
+ ? insn2 : MEMA_OFFSET (insn1));
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+ }
+
+ /* Accept zero or one instance of "mov g13, ry", where y >= 4.
+ This is saving the address where a struct should be returned. */
+
+ if (next_ip
+ && (insn1 & 0xff802fbf) == 0x5c00061d
+ && (dst = REG_SRCDST (insn1)) >= (R0_REGNUM + 4))
+ {
+ save_addr = frame_addr + ((dst - R0_REGNUM) * 4);
+ fsr->regs[G0_REGNUM + 13] = save_addr;
+ ip = next_ip;
+#if 0 /* We'll need this once there is a subsequent instruction examined. */
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+#endif
+ }
+
+ return (ip);
+}
+
+/* Given an ip value corresponding to the start of a function,
+ return the ip of the first instruction after the function
+ prologue. */
+
+CORE_ADDR
+i960_skip_prologue (CORE_ADDR ip)
+{
+ struct frame_saved_regs saved_regs_dummy;
+ struct symtab_and_line sal;
+ CORE_ADDR limit;
+
+ sal = find_pc_line (ip, 0);
+ limit = (sal.end) ? sal.end : 0xffffffff;
+
+ return (examine_prologue (ip, limit, (CORE_ADDR) 0, &saved_regs_dummy));
+}
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame.
+
+ We cache the result of doing this in the frame_obstack, since it is
+ fairly expensive. */
+
+void
+frame_find_saved_regs (struct frame_info *fi, struct frame_saved_regs *fsr)
+{
+ register CORE_ADDR next_addr;
+ register CORE_ADDR *saved_regs;
+ register int regnum;
+ register struct frame_saved_regs *cache_fsr;
+ CORE_ADDR ip;
+ struct symtab_and_line sal;
+ CORE_ADDR limit;
+
+ if (!fi->fsr)
+ {
+ cache_fsr = (struct frame_saved_regs *)
+ frame_obstack_alloc (sizeof (struct frame_saved_regs));
+ memset (cache_fsr, '\0', sizeof (struct frame_saved_regs));
+ fi->fsr = cache_fsr;
+
+ /* Find the start and end of the function prologue. If the PC
+ is in the function prologue, we only consider the part that
+ has executed already. */
+
+ ip = get_pc_function_start (fi->pc);
+ sal = find_pc_line (ip, 0);
+ limit = (sal.end && sal.end < fi->pc) ? sal.end : fi->pc;
+
+ examine_prologue (ip, limit, fi->frame, cache_fsr);
+
+ /* Record the addresses at which the local registers are saved.
+ Strictly speaking, we should only do this for non-leaf procedures,
+ but no one will ever look at these values if it is a leaf procedure,
+ since local registers are always caller-saved. */
+
+ next_addr = (CORE_ADDR) fi->frame;
+ saved_regs = cache_fsr->regs;
+ for (regnum = R0_REGNUM; regnum <= R15_REGNUM; regnum++)
+ {
+ *saved_regs++ = next_addr;
+ next_addr += 4;
+ }
+
+ cache_fsr->regs[FP_REGNUM] = cache_fsr->regs[PFP_REGNUM];
+ }
+
+ *fsr = *fi->fsr;
+
+ /* Fetch the value of the sp from memory every time, since it
+ is conceivable that it has changed since the cache was flushed.
+ This unfortunately undoes much of the savings from caching the
+ saved register values. I suggest adding an argument to
+ get_frame_saved_regs () specifying the register number we're
+ interested in (or -1 for all registers). This would be passed
+ through to FRAME_FIND_SAVED_REGS (), permitting more efficient
+ computation of saved register addresses (e.g., on the i960,
+ we don't have to examine the prologue to find local registers).
+ -- markf@wrs.com
+ FIXME, we don't need to refetch this, since the cache is cleared
+ every time the child process is restarted. If GDB itself
+ modifies SP, it has to clear the cache by hand (does it?). -gnu */
+
+ fsr->regs[SP_REGNUM] = read_memory_integer (fsr->regs[SP_REGNUM], 4);
+}
+
+/* Return the address of the argument block for the frame
+ described by FI. Returns 0 if the address is unknown. */
+
+CORE_ADDR
+frame_args_address (struct frame_info *fi, int must_be_correct)
+{
+ struct frame_saved_regs fsr;
+ CORE_ADDR ap;
+
+ /* If g14 was saved in the frame by the function prologue code, return
+ the saved value. If the frame is current and we are being sloppy,
+ return the value of g14. Otherwise, return zero. */
+
+ get_frame_saved_regs (fi, &fsr);
+ if (fsr.regs[G14_REGNUM])
+ ap = read_memory_integer (fsr.regs[G14_REGNUM], 4);
+ else
+ {
+ if (must_be_correct)
+ return 0; /* Don't cache this result */
+ if (get_next_frame (fi))
+ ap = 0;
+ else
+ ap = read_register (G14_REGNUM);
+ if (ap == 0)
+ ap = fi->frame;
+ }
+ fi->arg_pointer = ap; /* Cache it for next time */
+ return ap;
+}
+
+/* Return the address of the return struct for the frame
+ described by FI. Returns 0 if the address is unknown. */
+
+CORE_ADDR
+frame_struct_result_address (struct frame_info *fi)
+{
+ struct frame_saved_regs fsr;
+ CORE_ADDR ap;
+
+ /* If the frame is non-current, check to see if g14 was saved in the
+ frame by the function prologue code; return the saved value if so,
+ zero otherwise. If the frame is current, return the value of g14.
+
+ FIXME, shouldn't this use the saved value as long as we are past
+ the function prologue, and only use the current value if we have
+ no saved value and are at TOS? -- gnu@cygnus.com */
+
+ if (get_next_frame (fi))
+ {
+ get_frame_saved_regs (fi, &fsr);
+ if (fsr.regs[G13_REGNUM])
+ ap = read_memory_integer (fsr.regs[G13_REGNUM], 4);
+ else
+ ap = 0;
+ }
+ else
+ ap = read_register (G13_REGNUM);
+
+ return ap;
+}
+
+/* Return address to which the currently executing leafproc will return,
+ or 0 if IP, the value of the instruction pointer from the currently
+ executing function, is not in a leafproc (or if we can't tell if it
+ is).
+
+ Do this by finding the starting address of the routine in which IP lies.
+ If the instruction there is "mov g14, gx" (where x is in [0,7]), this
+ is a leafproc and the return address is in register gx. Well, this is
+ true unless the return address points at a RET instruction in the current
+ procedure, which indicates that we have a 'dual entry' routine that
+ has been entered through the CALL entry point. */
+
+CORE_ADDR
+leafproc_return (CORE_ADDR ip)
+{
+ register struct minimal_symbol *msymbol;
+ char *p;
+ int dst;
+ unsigned int insn1, insn2;
+ CORE_ADDR return_addr;
+
+ if ((msymbol = lookup_minimal_symbol_by_pc (ip)) != NULL)
+ {
+ if ((p = strchr (SYMBOL_NAME (msymbol), '.')) && STREQ (p, ".lf"))
+ {
+ if (next_insn (SYMBOL_VALUE_ADDRESS (msymbol), &insn1, &insn2)
+ && (insn1 & 0xff87ffff) == 0x5c80161e /* mov g14, gx */
+ && (dst = REG_SRCDST (insn1)) <= G0_REGNUM + 7)
+ {
+ /* Get the return address. If the "mov g14, gx"
+ instruction hasn't been executed yet, read
+ the return address from g14; otherwise, read it
+ from the register into which g14 was moved. */
+
+ return_addr =
+ read_register ((ip == SYMBOL_VALUE_ADDRESS (msymbol))
+ ? G14_REGNUM : dst);
+
+ /* We know we are in a leaf procedure, but we don't know
+ whether the caller actually did a "bal" to the ".lf"
+ entry point, or a normal "call" to the non-leaf entry
+ point one instruction before. In the latter case, the
+ return address will be the address of a "ret"
+ instruction within the procedure itself. We test for
+ this below. */
+
+ if (!next_insn (return_addr, &insn1, &insn2)
+ || (insn1 & 0xff000000) != 0xa000000 /* ret */
+ || lookup_minimal_symbol_by_pc (return_addr) != msymbol)
+ return (return_addr);
+ }
+ }
+ }
+
+ return (0);
+}
+
+/* Immediately after a function call, return the saved pc.
+ Can't go through the frames for this because on some machines
+ the new frame is not set up until the new function executes
+ some instructions.
+ On the i960, the frame *is* set up immediately after the call,
+ unless the function is a leaf procedure. */
+
+CORE_ADDR
+saved_pc_after_call (struct frame_info *frame)
+{
+ CORE_ADDR saved_pc;
+
+ saved_pc = leafproc_return (get_frame_pc (frame));
+ if (!saved_pc)
+ saved_pc = FRAME_SAVED_PC (frame);
+
+ return saved_pc;
+}
+
+/* Discard from the stack the innermost frame,
+ restoring all saved registers. */
+
+void
+i960_pop_frame (void)
+{
+ register struct frame_info *current_fi, *prev_fi;
+ register int i;
+ CORE_ADDR save_addr;
+ CORE_ADDR leaf_return_addr;
+ struct frame_saved_regs fsr;
+ char local_regs_buf[16 * 4];
+
+ current_fi = get_current_frame ();
+
+ /* First, undo what the hardware does when we return.
+ If this is a non-leaf procedure, restore local registers from
+ the save area in the calling frame. Otherwise, load the return
+ address obtained from leafproc_return () into the rip. */
+
+ leaf_return_addr = leafproc_return (current_fi->pc);
+ if (!leaf_return_addr)
+ {
+ /* Non-leaf procedure. Restore local registers, incl IP. */
+ prev_fi = get_prev_frame (current_fi);
+ read_memory (prev_fi->frame, local_regs_buf, sizeof (local_regs_buf));
+ write_register_bytes (REGISTER_BYTE (R0_REGNUM), local_regs_buf,
+ sizeof (local_regs_buf));
+
+ /* Restore frame pointer. */
+ write_register (FP_REGNUM, prev_fi->frame);
+ }
+ else
+ {
+ /* Leaf procedure. Just restore the return address into the IP. */
+ write_register (RIP_REGNUM, leaf_return_addr);
+ }
+
+ /* Now restore any global regs that the current function had saved. */
+ get_frame_saved_regs (current_fi, &fsr);
+ for (i = G0_REGNUM; i < G14_REGNUM; i++)
+ {
+ save_addr = fsr.regs[i];
+ if (save_addr != 0)
+ write_register (i, read_memory_integer (save_addr, 4));
+ }
+
+ /* Flush the frame cache, create a frame for the new innermost frame,
+ and make it the current frame. */
+
+ flush_cached_frames ();
+}
+
+/* Given a 960 stop code (fault or trace), return the signal which
+ corresponds. */
+
+enum target_signal
+i960_fault_to_signal (int fault)
+{
+ switch (fault)
+ {
+ case 0:
+ return TARGET_SIGNAL_BUS; /* parallel fault */
+ case 1:
+ return TARGET_SIGNAL_UNKNOWN;
+ case 2:
+ return TARGET_SIGNAL_ILL; /* operation fault */
+ case 3:
+ return TARGET_SIGNAL_FPE; /* arithmetic fault */
+ case 4:
+ return TARGET_SIGNAL_FPE; /* floating point fault */
+
+ /* constraint fault. This appears not to distinguish between
+ a range constraint fault (which should be SIGFPE) and a privileged
+ fault (which should be SIGILL). */
+ case 5:
+ return TARGET_SIGNAL_ILL;
+
+ case 6:
+ return TARGET_SIGNAL_SEGV; /* virtual memory fault */
+
+ /* protection fault. This is for an out-of-range argument to
+ "calls". I guess it also could be SIGILL. */
+ case 7:
+ return TARGET_SIGNAL_SEGV;
+
+ case 8:
+ return TARGET_SIGNAL_BUS; /* machine fault */
+ case 9:
+ return TARGET_SIGNAL_BUS; /* structural fault */
+ case 0xa:
+ return TARGET_SIGNAL_ILL; /* type fault */
+ case 0xb:
+ return TARGET_SIGNAL_UNKNOWN; /* reserved fault */
+ case 0xc:
+ return TARGET_SIGNAL_BUS; /* process fault */
+ case 0xd:
+ return TARGET_SIGNAL_SEGV; /* descriptor fault */
+ case 0xe:
+ return TARGET_SIGNAL_BUS; /* event fault */
+ case 0xf:
+ return TARGET_SIGNAL_UNKNOWN; /* reserved fault */
+ case 0x10:
+ return TARGET_SIGNAL_TRAP; /* single-step trace */
+ case 0x11:
+ return TARGET_SIGNAL_TRAP; /* branch trace */
+ case 0x12:
+ return TARGET_SIGNAL_TRAP; /* call trace */
+ case 0x13:
+ return TARGET_SIGNAL_TRAP; /* return trace */
+ case 0x14:
+ return TARGET_SIGNAL_TRAP; /* pre-return trace */
+ case 0x15:
+ return TARGET_SIGNAL_TRAP; /* supervisor call trace */
+ case 0x16:
+ return TARGET_SIGNAL_TRAP; /* breakpoint trace */
+ default:
+ return TARGET_SIGNAL_UNKNOWN;
+ }
+}
+
+/****************************************/
+/* MEM format */
+/****************************************/
+
+struct tabent
+{
+ char *name;
+ char numops;
+};
+
+/* Return instruction length, either 4 or 8. When NOPRINT is non-zero
+ (TRUE), don't output any text. (Actually, as implemented, if NOPRINT
+ is 0, abort() is called.) */
+
+static int
+mem (unsigned long memaddr, unsigned long word1, unsigned long word2,
+ int noprint)
+{
+ int i, j;
+ int len;
+ int mode;
+ int offset;
+ const char *reg1, *reg2, *reg3;
+
+ /* This lookup table is too sparse to make it worth typing in, but not
+ * so large as to make a sparse array necessary. We allocate the
+ * table at runtime, initialize all entries to empty, and copy the
+ * real ones in from an initialization table.
+ *
+ * NOTE: In this table, the meaning of 'numops' is:
+ * 1: single operand
+ * 2: 2 operands, load instruction
+ * -2: 2 operands, store instruction
+ */
+ static struct tabent *mem_tab = NULL;
+/* Opcodes of 0x8X, 9X, aX, bX, and cX must be in the table. */
+#define MEM_MIN 0x80
+#define MEM_MAX 0xcf
+#define MEM_SIZ ((MEM_MAX-MEM_MIN+1) * sizeof(struct tabent))
+
+ static struct
+ {
+ int opcode;
+ char *name;
+ char numops;
+ }
+ mem_init[] =
+ {
+ 0x80, "ldob", 2,
+ 0x82, "stob", -2,
+ 0x84, "bx", 1,
+ 0x85, "balx", 2,
+ 0x86, "callx", 1,
+ 0x88, "ldos", 2,
+ 0x8a, "stos", -2,
+ 0x8c, "lda", 2,
+ 0x90, "ld", 2,
+ 0x92, "st", -2,
+ 0x98, "ldl", 2,
+ 0x9a, "stl", -2,
+ 0xa0, "ldt", 2,
+ 0xa2, "stt", -2,
+ 0xb0, "ldq", 2,
+ 0xb2, "stq", -2,
+ 0xc0, "ldib", 2,
+ 0xc2, "stib", -2,
+ 0xc8, "ldis", 2,
+ 0xca, "stis", -2,
+ 0, NULL, 0
+ };
+
+ if (mem_tab == NULL)
+ {
+ mem_tab = (struct tabent *) xmalloc (MEM_SIZ);
+ memset (mem_tab, '\0', MEM_SIZ);
+ for (i = 0; mem_init[i].opcode != 0; i++)
+ {
+ j = mem_init[i].opcode - MEM_MIN;
+ mem_tab[j].name = mem_init[i].name;
+ mem_tab[j].numops = mem_init[i].numops;
+ }
+ }
+
+ i = ((word1 >> 24) & 0xff) - MEM_MIN;
+ mode = (word1 >> 10) & 0xf;
+
+ if ((mem_tab[i].name != NULL) /* Valid instruction */
+ && ((mode == 5) || (mode >= 12)))
+ { /* With 32-bit displacement */
+ len = 8;
+ }
+ else
+ {
+ len = 4;
+ }
+
+ if (noprint)
+ {
+ return len;
+ }
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+}
+
+/* Read the i960 instruction at 'memaddr' and return the address of
+ the next instruction after that, or 0 if 'memaddr' is not the
+ address of a valid instruction. The first word of the instruction
+ is stored at 'pword1', and the second word, if any, is stored at
+ 'pword2'. */
+
+static CORE_ADDR
+next_insn (CORE_ADDR memaddr, unsigned int *pword1, unsigned int *pword2)
+{
+ int len;
+ char buf[8];
+
+ /* Read the two (potential) words of the instruction at once,
+ to eliminate the overhead of two calls to read_memory ().
+ FIXME: Loses if the first one is readable but the second is not
+ (e.g. last word of the segment). */
+
+ read_memory (memaddr, buf, 8);
+ *pword1 = extract_unsigned_integer (buf, 4);
+ *pword2 = extract_unsigned_integer (buf + 4, 4);
+
+ /* Divide instruction set into classes based on high 4 bits of opcode */
+
+ switch ((*pword1 >> 28) & 0xf)
+ {
+ case 0x0:
+ case 0x1: /* ctrl */
+
+ case 0x2:
+ case 0x3: /* cobr */
+
+ case 0x5:
+ case 0x6:
+ case 0x7: /* reg */
+ len = 4;
+ break;
+
+ case 0x8:
+ case 0x9:
+ case 0xa:
+ case 0xb:
+ case 0xc:
+ len = mem (memaddr, *pword1, *pword2, 1);
+ break;
+
+ default: /* invalid instruction */
+ len = 0;
+ break;
+ }
+
+ if (len)
+ return memaddr + len;
+ else
+ return 0;
+}
+
+/* 'start_frame' is a variable in the MON960 runtime startup routine
+ that contains the frame pointer of the 'start' routine (the routine
+ that calls 'main'). By reading its contents out of remote memory,
+ we can tell where the frame chain ends: backtraces should halt before
+ they display this frame. */
+
+int
+mon960_frame_chain_valid (CORE_ADDR chain, struct frame_info *curframe)
+{
+ struct symbol *sym;
+ struct minimal_symbol *msymbol;
+
+ /* crtmon960.o is an assembler module that is assumed to be linked
+ * first in an i80960 executable. It contains the true entry point;
+ * it performs startup up initialization and then calls 'main'.
+ *
+ * 'sf' is the name of a variable in crtmon960.o that is set
+ * during startup to the address of the first frame.
+ *
+ * 'a' is the address of that variable in 80960 memory.
+ */
+ static char sf[] = "start_frame";
+ CORE_ADDR a;
+
+
+ chain &= ~0x3f; /* Zero low 6 bits because previous frame pointers
+ contain return status info in them. */
+ if (chain == 0)
+ {
+ return 0;
+ }
+
+ sym = lookup_symbol (sf, 0, VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ if (sym != 0)
+ {
+ a = SYMBOL_VALUE (sym);
+ }
+ else
+ {
+ msymbol = lookup_minimal_symbol (sf, NULL, NULL);
+ if (msymbol == NULL)
+ return 0;
+ a = SYMBOL_VALUE_ADDRESS (msymbol);
+ }
+
+ return (chain != read_memory_integer (a, 4));
+}
+
+
+void
+_initialize_i960_tdep (void)
+{
+ check_host ();
+
+ tm_print_insn = print_insn_i960;
+}
diff --git a/gdb/ia64-aix-nat.c b/gdb/ia64-aix-nat.c
new file mode 100644
index 00000000000..c41cc7cc88c
--- /dev/null
+++ b/gdb/ia64-aix-nat.c
@@ -0,0 +1,161 @@
+/* Functions specific to running gdb native on IA-64 running AIX.
+ Copyright 2000, 2001 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 "defs.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include <sys/procfs.h>
+
+#include "symtab.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "gdb_stat.h"
+
+void
+supply_gregset (prgregset_t *gregsetp)
+{
+ int regi;
+
+ for (regi = IA64_GR0_REGNUM; regi <= IA64_GR31_REGNUM; regi++)
+ {
+ supply_register (regi,
+ (char *) &(gregsetp->__gpr[regi - IA64_GR0_REGNUM]));
+ }
+
+ for (regi = IA64_BR0_REGNUM; regi <= IA64_BR7_REGNUM; regi++)
+ {
+ supply_register (regi,
+ (char *) &(gregsetp->__br[regi - IA64_BR0_REGNUM]));
+ }
+
+ supply_register (IA64_PSR_REGNUM, (char *) &(gregsetp->__psr));
+ supply_register (IA64_IP_REGNUM, (char *) &(gregsetp->__ip));
+ supply_register (IA64_CFM_REGNUM, (char *) &(gregsetp->__ifs));
+ supply_register (IA64_RSC_REGNUM, (char *) &(gregsetp->__rsc));
+ supply_register (IA64_BSP_REGNUM, (char *) &(gregsetp->__bsp));
+ supply_register (IA64_BSPSTORE_REGNUM, (char *) &(gregsetp->__bspstore));
+ supply_register (IA64_RNAT_REGNUM, (char *) &(gregsetp->__rnat));
+ supply_register (IA64_PFS_REGNUM, (char *) &(gregsetp->__pfs));
+ supply_register (IA64_UNAT_REGNUM, (char *) &(gregsetp->__unat));
+ supply_register (IA64_PR_REGNUM, (char *) &(gregsetp->__preds));
+ supply_register (IA64_CCV_REGNUM, (char *) &(gregsetp->__ccv));
+ supply_register (IA64_LC_REGNUM, (char *) &(gregsetp->__lc));
+ supply_register (IA64_EC_REGNUM, (char *) &(gregsetp->__ec));
+ /* FIXME: __nats */
+ supply_register (IA64_FPSR_REGNUM, (char *) &(gregsetp->__fpsr));
+
+ /* These (for the most part) are pseudo registers and are obtained
+ by other means. Those that aren't are already handled by the
+ code above. */
+ for (regi = IA64_GR32_REGNUM; regi <= IA64_GR127_REGNUM; regi++)
+ register_valid[regi] = 1;
+ for (regi = IA64_PR0_REGNUM; regi <= IA64_PR63_REGNUM; regi++)
+ register_valid[regi] = 1;
+ for (regi = IA64_VFP_REGNUM; regi <= NUM_REGS; regi++)
+ register_valid[regi] = 1;
+}
+
+void
+fill_gregset (prgregset_t *gregsetp, int regno)
+{
+ int regi;
+
+#define COPY_REG(_fld_,_regi_) \
+ if ((regno == -1) || regno == _regi_) \
+ memcpy (&(gregsetp->_fld_), &registers[REGISTER_BYTE (_regi_)], \
+ REGISTER_RAW_SIZE (_regi_))
+
+ for (regi = IA64_GR0_REGNUM; regi <= IA64_GR31_REGNUM; regi++)
+ {
+ COPY_REG (__gpr[regi - IA64_GR0_REGNUM], regi);
+ }
+
+ for (regi = IA64_BR0_REGNUM; regi <= IA64_BR7_REGNUM; regi++)
+ {
+ COPY_REG (__br[regi - IA64_BR0_REGNUM], regi);
+ }
+ COPY_REG (__psr, IA64_PSR_REGNUM);
+ COPY_REG (__ip, IA64_IP_REGNUM);
+ COPY_REG (__ifs, IA64_CFM_REGNUM);
+ COPY_REG (__rsc, IA64_RSC_REGNUM);
+ COPY_REG (__bsp, IA64_BSP_REGNUM);
+
+ /* Bad things happen if we don't update both bsp and bspstore at the
+ same time. */
+ if (regno == IA64_BSP_REGNUM || regno == -1)
+ {
+ memcpy (&(gregsetp->__bspstore),
+ &registers[REGISTER_BYTE (IA64_BSP_REGNUM)],
+ REGISTER_RAW_SIZE (IA64_BSP_REGNUM));
+ memcpy (&registers[REGISTER_BYTE (IA64_BSPSTORE_REGNUM)],
+ &registers[REGISTER_BYTE (IA64_BSP_REGNUM)],
+ REGISTER_RAW_SIZE (IA64_BSP_REGNUM));
+ }
+
+#if 0
+ /* We never actually write to bspstore, or we'd have to do the same thing
+ here too. */
+ COPY_REG (__bspstore, IA64_BSPSTORE_REGNUM);
+#endif
+ COPY_REG (__rnat, IA64_RNAT_REGNUM);
+ COPY_REG (__pfs, IA64_PFS_REGNUM);
+ COPY_REG (__unat, IA64_UNAT_REGNUM);
+ COPY_REG (__preds, IA64_PR_REGNUM);
+ COPY_REG (__ccv, IA64_CCV_REGNUM);
+ COPY_REG (__lc, IA64_LC_REGNUM);
+ COPY_REG (__ec, IA64_EC_REGNUM);
+ /* FIXME: __nats */
+ COPY_REG (__fpsr, IA64_FPSR_REGNUM);
+#undef COPY_REG
+}
+
+void
+supply_fpregset (prfpregset_t *fpregsetp)
+{
+ register int regi;
+
+ for (regi = IA64_FR0_REGNUM; regi <= IA64_FR127_REGNUM; regi++)
+ supply_register (regi,
+ (char *) &(fpregsetp->__fpr[regi - IA64_FR0_REGNUM]));
+}
+
+void
+fill_fpregset (prfpregset_t *fpregsetp, int regno)
+{
+ int regi;
+ char *to;
+ char *from;
+
+ for (regi = IA64_FR0_REGNUM; regi <= IA64_FR127_REGNUM; regi++)
+ {
+ if ((regno == -1) || (regno == regi))
+ {
+ from = (char *) &registers[REGISTER_BYTE (regi)];
+ to = (char *) &(fpregsetp->__fpr[regi - IA64_FR0_REGNUM]);
+ memcpy (to, from, REGISTER_RAW_SIZE (regi));
+ }
+ }
+}
diff --git a/gdb/ia64-aix-tdep.c b/gdb/ia64-aix-tdep.c
new file mode 100644
index 00000000000..26eca6b59cb
--- /dev/null
+++ b/gdb/ia64-aix-tdep.c
@@ -0,0 +1,107 @@
+/* Target-dependent code for the IA-64 for GDB, the GNU debugger.
+ Copyright 2000, 2001
+ 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 "defs.h"
+
+/* External hook for finding gate addresses on AIX. */
+void (*aix5_find_gate_addresses_hook) (CORE_ADDR *, CORE_ADDR *) = 0;
+
+/* Offset to sc_context member of sigcontext structure from frame of handler */
+#define IA64_AIX_SIGCONTEXT_OFFSET 64
+
+/* Return a non-zero value iff PC is in a signal trampoline. On
+ AIX, we determine this by seeing if the pc is in a special
+ execute only page called the ``gate page''. The addresses in
+ question are determined by letting the AIX native portion of
+ the code determine these addresses via its own nefarious
+ means. */
+
+int
+ia64_aix_in_sigtramp (CORE_ADDR pc, char *func_name)
+{
+ CORE_ADDR gate_area_start, gate_area_end;
+
+ if (aix5_find_gate_addresses_hook == 0)
+ return 0;
+
+ (*aix5_find_gate_addresses_hook) (&gate_area_start, &gate_area_end);
+
+ return (pc >= gate_area_start && pc < gate_area_end);
+}
+
+
+/* IA-64 AIX specific function which, given a frame address and
+ a register number, returns the address at which that register may be
+ found. 0 is returned for registers which aren't stored in the
+ sigcontext structure. */
+
+CORE_ADDR
+ia64_aix_sigcontext_register_address (CORE_ADDR sp, int regno)
+{
+ /* The hardcoded offsets that follow are actually offsets to the
+ corresponding members in struct __context in
+ /usr/include/sys/context.h (on an IA-64 AIX5 box). */
+ if (IA64_GR0_REGNUM <= regno && regno <= IA64_GR31_REGNUM)
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 152 + 8 * (regno - IA64_GR0_REGNUM);
+ else if (IA64_BR0_REGNUM <= regno && regno <= IA64_BR7_REGNUM)
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 408 + 8 * (regno - IA64_BR0_REGNUM);
+ else if (IA64_FR0_REGNUM <= regno && regno <= IA64_FR127_REGNUM)
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 480 + 16 * (regno - IA64_FR0_REGNUM);
+ else
+ switch (regno)
+ {
+ case IA64_PSR_REGNUM :
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 0;
+ case IA64_IP_REGNUM :
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 8;
+ /* iipa is at 16.
+ isr is at 24.
+ ifa is at 32.
+ iim is at 40. */
+ case IA64_CFM_REGNUM :
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 48; /* ifs, actually */
+ case IA64_RSC_REGNUM :
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 56;
+ case IA64_BSP_REGNUM :
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 64;
+ case IA64_BSPSTORE_REGNUM :
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 72;
+ case IA64_RNAT_REGNUM :
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 80;
+ case IA64_PFS_REGNUM :
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 88;
+ case IA64_UNAT_REGNUM :
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 96;
+ case IA64_PR_REGNUM :
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 104;
+ case IA64_CCV_REGNUM :
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 112;
+ case IA64_LC_REGNUM :
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 120;
+ case IA64_EC_REGNUM :
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 128;
+ /* nats is at 136; this is an address independent NaT bitmask */
+ case IA64_FPSR_REGNUM :
+ return sp + IA64_AIX_SIGCONTEXT_OFFSET + 144;
+ default :
+ return 0;
+ }
+}
diff --git a/gdb/ia64-linux-nat.c b/gdb/ia64-linux-nat.c
new file mode 100644
index 00000000000..82695ef57ae
--- /dev/null
+++ b/gdb/ia64-linux-nat.c
@@ -0,0 +1,644 @@
+/* Functions specific to running gdb native on IA-64 running
+ GNU/Linux.
+
+ Copyright 1999, 2000, 2001, 2002 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 "defs.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#include <signal.h>
+#include <sys/ptrace.h>
+#include <sys/wait.h>
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+#include <sys/user.h>
+
+#include <asm/ptrace_offsets.h>
+#include <sys/procfs.h>
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* These must match the order of the register names.
+
+ Some sort of lookup table is needed because the offsets associated
+ with the registers are all over the board. */
+
+static int u_offsets[] =
+ {
+ /* general registers */
+ -1, /* gr0 not available; i.e, it's always zero */
+ PT_R1,
+ PT_R2,
+ PT_R3,
+ PT_R4,
+ PT_R5,
+ PT_R6,
+ PT_R7,
+ PT_R8,
+ PT_R9,
+ PT_R10,
+ PT_R11,
+ PT_R12,
+ PT_R13,
+ PT_R14,
+ PT_R15,
+ PT_R16,
+ PT_R17,
+ PT_R18,
+ PT_R19,
+ PT_R20,
+ PT_R21,
+ PT_R22,
+ PT_R23,
+ PT_R24,
+ PT_R25,
+ PT_R26,
+ PT_R27,
+ PT_R28,
+ PT_R29,
+ PT_R30,
+ PT_R31,
+ /* gr32 through gr127 not directly available via the ptrace interface */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ /* Floating point registers */
+ -1, -1, /* f0 and f1 not available (f0 is +0.0 and f1 is +1.0) */
+ PT_F2,
+ PT_F3,
+ PT_F4,
+ PT_F5,
+ PT_F6,
+ PT_F7,
+ PT_F8,
+ PT_F9,
+ PT_F10,
+ PT_F11,
+ PT_F12,
+ PT_F13,
+ PT_F14,
+ PT_F15,
+ PT_F16,
+ PT_F17,
+ PT_F18,
+ PT_F19,
+ PT_F20,
+ PT_F21,
+ PT_F22,
+ PT_F23,
+ PT_F24,
+ PT_F25,
+ PT_F26,
+ PT_F27,
+ PT_F28,
+ PT_F29,
+ PT_F30,
+ PT_F31,
+ PT_F32,
+ PT_F33,
+ PT_F34,
+ PT_F35,
+ PT_F36,
+ PT_F37,
+ PT_F38,
+ PT_F39,
+ PT_F40,
+ PT_F41,
+ PT_F42,
+ PT_F43,
+ PT_F44,
+ PT_F45,
+ PT_F46,
+ PT_F47,
+ PT_F48,
+ PT_F49,
+ PT_F50,
+ PT_F51,
+ PT_F52,
+ PT_F53,
+ PT_F54,
+ PT_F55,
+ PT_F56,
+ PT_F57,
+ PT_F58,
+ PT_F59,
+ PT_F60,
+ PT_F61,
+ PT_F62,
+ PT_F63,
+ PT_F64,
+ PT_F65,
+ PT_F66,
+ PT_F67,
+ PT_F68,
+ PT_F69,
+ PT_F70,
+ PT_F71,
+ PT_F72,
+ PT_F73,
+ PT_F74,
+ PT_F75,
+ PT_F76,
+ PT_F77,
+ PT_F78,
+ PT_F79,
+ PT_F80,
+ PT_F81,
+ PT_F82,
+ PT_F83,
+ PT_F84,
+ PT_F85,
+ PT_F86,
+ PT_F87,
+ PT_F88,
+ PT_F89,
+ PT_F90,
+ PT_F91,
+ PT_F92,
+ PT_F93,
+ PT_F94,
+ PT_F95,
+ PT_F96,
+ PT_F97,
+ PT_F98,
+ PT_F99,
+ PT_F100,
+ PT_F101,
+ PT_F102,
+ PT_F103,
+ PT_F104,
+ PT_F105,
+ PT_F106,
+ PT_F107,
+ PT_F108,
+ PT_F109,
+ PT_F110,
+ PT_F111,
+ PT_F112,
+ PT_F113,
+ PT_F114,
+ PT_F115,
+ PT_F116,
+ PT_F117,
+ PT_F118,
+ PT_F119,
+ PT_F120,
+ PT_F121,
+ PT_F122,
+ PT_F123,
+ PT_F124,
+ PT_F125,
+ PT_F126,
+ PT_F127,
+ /* predicate registers - we don't fetch these individually */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ /* branch registers */
+ PT_B0,
+ PT_B1,
+ PT_B2,
+ PT_B3,
+ PT_B4,
+ PT_B5,
+ PT_B6,
+ PT_B7,
+ /* virtual frame pointer and virtual return address pointer */
+ -1, -1,
+ /* other registers */
+ PT_PR,
+ PT_CR_IIP, /* ip */
+ PT_CR_IPSR, /* psr */
+ PT_CFM, /* cfm */
+ /* kernel registers not visible via ptrace interface (?) */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ /* hole */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ PT_AR_RSC,
+ PT_AR_BSP,
+ PT_AR_BSPSTORE,
+ PT_AR_RNAT,
+ -1,
+ -1, /* Not available: FCR, IA32 floating control register */
+ -1, -1,
+ -1, /* Not available: EFLAG */
+ -1, /* Not available: CSD */
+ -1, /* Not available: SSD */
+ -1, /* Not available: CFLG */
+ -1, /* Not available: FSR */
+ -1, /* Not available: FIR */
+ -1, /* Not available: FDR */
+ -1,
+ PT_AR_CCV,
+ -1, -1, -1,
+ PT_AR_UNAT,
+ -1, -1, -1,
+ PT_AR_FPSR,
+ -1, -1, -1,
+ -1, /* Not available: ITC */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ PT_AR_PFS,
+ PT_AR_LC,
+ -1, /* Not available: EC, the Epilog Count register */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1,
+ /* nat bits - not fetched directly; instead we obtain these bits from
+ either rnat or unat or from memory. */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ };
+
+CORE_ADDR
+register_addr (int regno, CORE_ADDR blockend)
+{
+ CORE_ADDR addr;
+
+ if (regno < 0 || regno >= NUM_REGS)
+ error ("Invalid register number %d.", regno);
+
+ if (u_offsets[regno] == -1)
+ addr = 0;
+ else
+ addr = (CORE_ADDR) u_offsets[regno];
+
+ return addr;
+}
+
+int ia64_cannot_fetch_register (regno)
+ int regno;
+{
+ return regno < 0 || regno >= NUM_REGS || u_offsets[regno] == -1;
+}
+
+int ia64_cannot_store_register (regno)
+ int regno;
+{
+ /* Rationale behind not permitting stores to bspstore...
+
+ The IA-64 architecture provides bspstore and bsp which refer
+ memory locations in the RSE's backing store. bspstore is the
+ next location which will be written when the RSE needs to write
+ to memory. bsp is the address at which r32 in the current frame
+ would be found if it were written to the backing store.
+
+ The IA-64 architecture provides read-only access to bsp and
+ read/write access to bspstore (but only when the RSE is in
+ the enforced lazy mode). It should be noted that stores
+ to bspstore also affect the value of bsp. Changing bspstore
+ does not affect the number of dirty entries between bspstore
+ and bsp, so changing bspstore by N words will also cause bsp
+ to be changed by (roughly) N as well. (It could be N-1 or N+1
+ depending upon where the NaT collection bits fall.)
+
+ OTOH, the Linux kernel provides read/write access to bsp (and
+ currently read/write access to bspstore as well). But it
+ is definitely the case that if you change one, the other
+ will change at the same time. It is more useful to gdb to
+ be able to change bsp. So in order to prevent strange and
+ undesirable things from happening when a dummy stack frame
+ is popped (after calling an inferior function), we allow
+ bspstore to be read, but not written. (Note that popping
+ a (generic) dummy stack frame causes all registers that
+ were previously read from the inferior process to be written
+ back.) */
+
+ return regno < 0 || regno >= NUM_REGS || u_offsets[regno] == -1
+ || regno == IA64_BSPSTORE_REGNUM;
+}
+
+void
+supply_gregset (gregset_t *gregsetp)
+{
+ int regi;
+ greg_t *regp = (greg_t *) gregsetp;
+
+ for (regi = IA64_GR0_REGNUM; regi <= IA64_GR31_REGNUM; regi++)
+ {
+ supply_register (regi, (char *) (regp + (regi - IA64_GR0_REGNUM)));
+ }
+
+ /* FIXME: NAT collection bits are at index 32; gotta deal with these
+ somehow... */
+
+ supply_register (IA64_PR_REGNUM, (char *) (regp + 33));
+
+ for (regi = IA64_BR0_REGNUM; regi <= IA64_BR7_REGNUM; regi++)
+ {
+ supply_register (regi, (char *) (regp + 34 + (regi - IA64_BR0_REGNUM)));
+ }
+
+ supply_register (IA64_IP_REGNUM, (char *) (regp + 42));
+ supply_register (IA64_CFM_REGNUM, (char *) (regp + 43));
+ supply_register (IA64_PSR_REGNUM, (char *) (regp + 44));
+ supply_register (IA64_RSC_REGNUM, (char *) (regp + 45));
+ supply_register (IA64_BSP_REGNUM, (char *) (regp + 46));
+ supply_register (IA64_BSPSTORE_REGNUM, (char *) (regp + 47));
+ supply_register (IA64_RNAT_REGNUM, (char *) (regp + 48));
+ supply_register (IA64_CCV_REGNUM, (char *) (regp + 49));
+ supply_register (IA64_UNAT_REGNUM, (char *) (regp + 50));
+ supply_register (IA64_FPSR_REGNUM, (char *) (regp + 51));
+ supply_register (IA64_PFS_REGNUM, (char *) (regp + 52));
+ supply_register (IA64_LC_REGNUM, (char *) (regp + 53));
+ supply_register (IA64_EC_REGNUM, (char *) (regp + 54));
+}
+
+void
+fill_gregset (gregset_t *gregsetp, int regno)
+{
+ int regi;
+ greg_t *regp = (greg_t *) gregsetp;
+
+#define COPY_REG(_idx_,_regi_) \
+ if ((regno == -1) || regno == _regi_) \
+ memcpy (regp + _idx_, &registers[REGISTER_BYTE (_regi_)], \
+ REGISTER_RAW_SIZE (_regi_))
+
+ for (regi = IA64_GR0_REGNUM; regi <= IA64_GR31_REGNUM; regi++)
+ {
+ COPY_REG (regi - IA64_GR0_REGNUM, regi);
+ }
+
+ /* FIXME: NAT collection bits at index 32? */
+
+ COPY_REG (33, IA64_PR_REGNUM);
+
+ for (regi = IA64_BR0_REGNUM; regi <= IA64_BR7_REGNUM; regi++)
+ {
+ COPY_REG (34 + (regi - IA64_BR0_REGNUM), regi);
+ }
+
+ COPY_REG (42, IA64_IP_REGNUM);
+ COPY_REG (43, IA64_CFM_REGNUM);
+ COPY_REG (44, IA64_PSR_REGNUM);
+ COPY_REG (45, IA64_RSC_REGNUM);
+ COPY_REG (46, IA64_BSP_REGNUM);
+ COPY_REG (47, IA64_BSPSTORE_REGNUM);
+ COPY_REG (48, IA64_RNAT_REGNUM);
+ COPY_REG (49, IA64_CCV_REGNUM);
+ COPY_REG (50, IA64_UNAT_REGNUM);
+ COPY_REG (51, IA64_FPSR_REGNUM);
+ COPY_REG (52, IA64_PFS_REGNUM);
+ COPY_REG (53, IA64_LC_REGNUM);
+ COPY_REG (54, IA64_EC_REGNUM);
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), unpack the register contents and supply them as gdb's
+ idea of the current floating point register values. */
+
+void
+supply_fpregset (fpregset_t *fpregsetp)
+{
+ register int regi;
+ char *from;
+
+ for (regi = IA64_FR0_REGNUM; regi <= IA64_FR127_REGNUM; regi++)
+ {
+ from = (char *) &((*fpregsetp)[regi - IA64_FR0_REGNUM]);
+ supply_register (regi, from);
+ }
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), update the register specified by REGNO from gdb's idea
+ of the current floating point register set. If REGNO is -1, update
+ them all. */
+
+void
+fill_fpregset (fpregset_t *fpregsetp, int regno)
+{
+ int regi;
+ char *to;
+ char *from;
+
+ for (regi = IA64_FR0_REGNUM; regi <= IA64_FR127_REGNUM; regi++)
+ {
+ if ((regno == -1) || (regno == regi))
+ {
+ from = (char *) &registers[REGISTER_BYTE (regi)];
+ to = (char *) &((*fpregsetp)[regi - IA64_FR0_REGNUM]);
+ memcpy (to, from, REGISTER_RAW_SIZE (regi));
+ }
+ }
+}
+
+#define IA64_PSR_DB (1UL << 24)
+#define IA64_PSR_DD (1UL << 39)
+
+static void
+enable_watchpoints_in_psr (ptid_t ptid)
+{
+ CORE_ADDR psr;
+
+ psr = read_register_pid (IA64_PSR_REGNUM, ptid);
+ if (!(psr & IA64_PSR_DB))
+ {
+ psr |= IA64_PSR_DB; /* Set the db bit - this enables hardware
+ watchpoints and breakpoints. */
+ write_register_pid (IA64_PSR_REGNUM, psr, ptid);
+ }
+}
+
+static long
+fetch_debug_register (ptid_t ptid, int idx)
+{
+ long val;
+ int tid;
+
+ tid = TIDGET (ptid);
+ if (tid == 0)
+ tid = PIDGET (ptid);
+
+ val = ptrace (PT_READ_U, tid, (PTRACE_ARG3_TYPE) (PT_DBR + 8 * idx), 0);
+
+ return val;
+}
+
+static void
+store_debug_register (ptid_t ptid, int idx, long val)
+{
+ int tid;
+
+ tid = TIDGET (ptid);
+ if (tid == 0)
+ tid = PIDGET (ptid);
+
+ (void) ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) (PT_DBR + 8 * idx), val);
+}
+
+static void
+fetch_debug_register_pair (ptid_t ptid, int idx, long *dbr_addr, long *dbr_mask)
+{
+ if (dbr_addr)
+ *dbr_addr = fetch_debug_register (ptid, 2 * idx);
+ if (dbr_mask)
+ *dbr_mask = fetch_debug_register (ptid, 2 * idx + 1);
+}
+
+static void
+store_debug_register_pair (ptid_t ptid, int idx, long *dbr_addr, long *dbr_mask)
+{
+ if (dbr_addr)
+ store_debug_register (ptid, 2 * idx, *dbr_addr);
+ if (dbr_mask)
+ store_debug_register (ptid, 2 * idx + 1, *dbr_mask);
+}
+
+static int
+is_power_of_2 (int val)
+{
+ int i, onecount;
+
+ onecount = 0;
+ for (i = 0; i < 8 * sizeof (val); i++)
+ if (val & (1 << i))
+ onecount++;
+
+ return onecount <= 1;
+}
+
+int
+ia64_linux_insert_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rw)
+{
+ int idx;
+ long dbr_addr, dbr_mask;
+ int max_watchpoints = 4;
+
+ if (len <= 0 || !is_power_of_2 (len))
+ return -1;
+
+ for (idx = 0; idx < max_watchpoints; idx++)
+ {
+ fetch_debug_register_pair (ptid, idx, NULL, &dbr_mask);
+ if ((dbr_mask & (0x3UL << 62)) == 0)
+ {
+ /* Exit loop if both r and w bits clear */
+ break;
+ }
+ }
+
+ if (idx == max_watchpoints)
+ return -1;
+
+ dbr_addr = (long) addr;
+ dbr_mask = (~(len - 1) & 0x00ffffffffffffffL); /* construct mask to match */
+ dbr_mask |= 0x0800000000000000L; /* Only match privilege level 3 */
+ switch (rw)
+ {
+ case hw_write:
+ dbr_mask |= (1L << 62); /* Set w bit */
+ break;
+ case hw_read:
+ dbr_mask |= (1L << 63); /* Set r bit */
+ break;
+ case hw_access:
+ dbr_mask |= (3L << 62); /* Set both r and w bits */
+ break;
+ default:
+ return -1;
+ }
+
+ store_debug_register_pair (ptid, idx, &dbr_addr, &dbr_mask);
+ enable_watchpoints_in_psr (ptid);
+
+ return 0;
+}
+
+int
+ia64_linux_remove_watchpoint (ptid_t ptid, CORE_ADDR addr, int len)
+{
+ int idx;
+ long dbr_addr, dbr_mask;
+ int max_watchpoints = 4;
+
+ if (len <= 0 || !is_power_of_2 (len))
+ return -1;
+
+ for (idx = 0; idx < max_watchpoints; idx++)
+ {
+ fetch_debug_register_pair (ptid, idx, &dbr_addr, &dbr_mask);
+ if ((dbr_mask & (0x3UL << 62)) && addr == (CORE_ADDR) dbr_addr)
+ {
+ dbr_addr = 0;
+ dbr_mask = 0;
+ store_debug_register_pair (ptid, idx, &dbr_addr, &dbr_mask);
+ return 0;
+ }
+ }
+ return -1;
+}
+
+CORE_ADDR
+ia64_linux_stopped_by_watchpoint (ptid_t ptid)
+{
+ CORE_ADDR psr;
+ int tid;
+ struct siginfo siginfo;
+
+ tid = TIDGET(ptid);
+ if (tid == 0)
+ tid = PIDGET (ptid);
+
+ errno = 0;
+ ptrace (PTRACE_GETSIGINFO, tid, (PTRACE_ARG3_TYPE) 0, &siginfo);
+
+ if (errno != 0 || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
+ return 0;
+
+ psr = read_register_pid (IA64_PSR_REGNUM, ptid);
+ psr |= IA64_PSR_DD; /* Set the dd bit - this will disable the watchpoint
+ for the next instruction */
+ write_register_pid (IA64_PSR_REGNUM, psr, ptid);
+
+ return (CORE_ADDR) siginfo.si_addr;
+}
diff --git a/gdb/ia64-linux-tdep.c b/gdb/ia64-linux-tdep.c
new file mode 100644
index 00000000000..97f88142bb3
--- /dev/null
+++ b/gdb/ia64-linux-tdep.c
@@ -0,0 +1,87 @@
+/* Target-dependent code for the IA-64 for GDB, the GNU debugger.
+ Copyright 2000
+ 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 "defs.h"
+#include "arch-utils.h"
+
+/* The sigtramp code is in a non-readable (executable-only) region
+ of memory called the ``gate page''. The addresses in question
+ were determined by examining the system headers. They are
+ overly generous to allow for different pages sizes. */
+
+#define GATE_AREA_START 0xa000000000000100LL
+#define GATE_AREA_END 0xa000000000010000LL
+
+/* Offset to sigcontext structure from frame of handler */
+#define IA64_LINUX_SIGCONTEXT_OFFSET 192
+
+int
+ia64_linux_in_sigtramp (CORE_ADDR pc, char *func_name)
+{
+ return (pc >= (CORE_ADDR) GATE_AREA_START && pc < (CORE_ADDR) GATE_AREA_END);
+}
+
+/* IA-64 GNU/Linux specific function which, given a frame address and
+ a register number, returns the address at which that register may be
+ found. 0 is returned for registers which aren't stored in the the
+ sigcontext structure. */
+
+CORE_ADDR
+ia64_linux_sigcontext_register_address (CORE_ADDR sp, int regno)
+{
+ if (IA64_GR0_REGNUM <= regno && regno <= IA64_GR31_REGNUM)
+ return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 200 + 8 * (regno - IA64_GR0_REGNUM);
+ else if (IA64_BR0_REGNUM <= regno && regno <= IA64_BR7_REGNUM)
+ return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 136 + 8 * (regno - IA64_BR0_REGNUM);
+ else if (IA64_FR0_REGNUM <= regno && regno <= IA64_FR127_REGNUM)
+ return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 464 + 16 * (regno - IA64_FR0_REGNUM);
+ else
+ switch (regno)
+ {
+ case IA64_IP_REGNUM :
+ return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 40;
+ case IA64_CFM_REGNUM :
+ return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 48;
+ case IA64_PSR_REGNUM :
+ return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 56; /* user mask only */
+ /* sc_ar_rsc is provided, from which we could compute bspstore, but
+ I don't think it's worth it. Anyway, if we want it, it's at offset
+ 64 */
+ case IA64_BSP_REGNUM :
+ return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 72;
+ case IA64_RNAT_REGNUM :
+ return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 80;
+ case IA64_CCV_REGNUM :
+ return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 88;
+ case IA64_UNAT_REGNUM :
+ return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 96;
+ case IA64_FPSR_REGNUM :
+ return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 104;
+ case IA64_PFS_REGNUM :
+ return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 112;
+ case IA64_LC_REGNUM :
+ return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 120;
+ case IA64_PR_REGNUM :
+ return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 128;
+ default :
+ return 0;
+ }
+}
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
new file mode 100644
index 00000000000..ab7e4674f75
--- /dev/null
+++ b/gdb/ia64-tdep.c
@@ -0,0 +1,2259 @@
+/* Target-dependent code for the IA-64 for GDB, the GNU debugger.
+
+ Copyright 1999, 2000, 2001, 2002 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 "defs.h"
+#include "inferior.h"
+#include "symfile.h" /* for entry_point_address */
+#include "gdbcore.h"
+#include "arch-utils.h"
+#include "floatformat.h"
+#include "regcache.h"
+#include "doublest.h"
+#include "value.h"
+
+#include "objfiles.h"
+#include "elf/common.h" /* for DT_PLTGOT value */
+#include "elf-bfd.h"
+
+/* Hook for determining the global pointer when calling functions in
+ the inferior under AIX. The initialization code in ia64-aix-nat.c
+ sets this hook to the address of a function which will find the
+ global pointer for a given address.
+
+ The generic code which uses the dynamic section in the inferior for
+ finding the global pointer is not of much use on AIX since the
+ values obtained from the inferior have not been relocated. */
+
+CORE_ADDR (*native_find_global_pointer) (CORE_ADDR) = 0;
+
+/* An enumeration of the different IA-64 instruction types. */
+
+typedef enum instruction_type
+{
+ A, /* Integer ALU ; I-unit or M-unit */
+ I, /* Non-ALU integer; I-unit */
+ M, /* Memory ; M-unit */
+ F, /* Floating-point ; F-unit */
+ B, /* Branch ; B-unit */
+ L, /* Extended (L+X) ; I-unit */
+ X, /* Extended (L+X) ; I-unit */
+ undefined /* undefined or reserved */
+} instruction_type;
+
+/* We represent IA-64 PC addresses as the value of the instruction
+ pointer or'd with some bit combination in the low nibble which
+ represents the slot number in the bundle addressed by the
+ instruction pointer. The problem is that the Linux kernel
+ multiplies its slot numbers (for exceptions) by one while the
+ disassembler multiplies its slot numbers by 6. In addition, I've
+ heard it said that the simulator uses 1 as the multiplier.
+
+ I've fixed the disassembler so that the bytes_per_line field will
+ be the slot multiplier. If bytes_per_line comes in as zero, it
+ is set to six (which is how it was set up initially). -- objdump
+ displays pretty disassembly dumps with this value. For our purposes,
+ we'll set bytes_per_line to SLOT_MULTIPLIER. This is okay since we
+ never want to also display the raw bytes the way objdump does. */
+
+#define SLOT_MULTIPLIER 1
+
+/* Length in bytes of an instruction bundle */
+
+#define BUNDLE_LEN 16
+
+/* FIXME: These extern declarations should go in ia64-tdep.h. */
+extern CORE_ADDR ia64_linux_sigcontext_register_address (CORE_ADDR, int);
+extern CORE_ADDR ia64_aix_sigcontext_register_address (CORE_ADDR, int);
+
+static gdbarch_init_ftype ia64_gdbarch_init;
+
+static gdbarch_register_name_ftype ia64_register_name;
+static gdbarch_register_raw_size_ftype ia64_register_raw_size;
+static gdbarch_register_virtual_size_ftype ia64_register_virtual_size;
+static gdbarch_register_virtual_type_ftype ia64_register_virtual_type;
+static gdbarch_register_byte_ftype ia64_register_byte;
+static gdbarch_breakpoint_from_pc_ftype ia64_breakpoint_from_pc;
+static gdbarch_frame_chain_ftype ia64_frame_chain;
+static gdbarch_frame_saved_pc_ftype ia64_frame_saved_pc;
+static gdbarch_skip_prologue_ftype ia64_skip_prologue;
+static gdbarch_frame_init_saved_regs_ftype ia64_frame_init_saved_regs;
+static gdbarch_get_saved_register_ftype ia64_get_saved_register;
+static gdbarch_extract_return_value_ftype ia64_extract_return_value;
+static gdbarch_extract_struct_value_address_ftype ia64_extract_struct_value_address;
+static gdbarch_use_struct_convention_ftype ia64_use_struct_convention;
+static gdbarch_frameless_function_invocation_ftype ia64_frameless_function_invocation;
+static gdbarch_init_extra_frame_info_ftype ia64_init_extra_frame_info;
+static gdbarch_store_return_value_ftype ia64_store_return_value;
+static gdbarch_store_struct_return_ftype ia64_store_struct_return;
+static gdbarch_push_arguments_ftype ia64_push_arguments;
+static gdbarch_push_return_address_ftype ia64_push_return_address;
+static gdbarch_pop_frame_ftype ia64_pop_frame;
+static gdbarch_saved_pc_after_call_ftype ia64_saved_pc_after_call;
+static void ia64_pop_frame_regular (struct frame_info *frame);
+static struct type *is_float_or_hfa_type (struct type *t);
+
+static int ia64_num_regs = 590;
+
+static int pc_regnum = IA64_IP_REGNUM;
+static int sp_regnum = IA64_GR12_REGNUM;
+static int fp_regnum = IA64_VFP_REGNUM;
+static int lr_regnum = IA64_VRAP_REGNUM;
+
+static LONGEST ia64_call_dummy_words[] = {0};
+
+/* Array of register names; There should be ia64_num_regs strings in
+ the initializer. */
+
+static char *ia64_register_names[] =
+{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
+ "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
+ "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
+ "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63",
+ "r64", "r65", "r66", "r67", "r68", "r69", "r70", "r71",
+ "r72", "r73", "r74", "r75", "r76", "r77", "r78", "r79",
+ "r80", "r81", "r82", "r83", "r84", "r85", "r86", "r87",
+ "r88", "r89", "r90", "r91", "r92", "r93", "r94", "r95",
+ "r96", "r97", "r98", "r99", "r100", "r101", "r102", "r103",
+ "r104", "r105", "r106", "r107", "r108", "r109", "r110", "r111",
+ "r112", "r113", "r114", "r115", "r116", "r117", "r118", "r119",
+ "r120", "r121", "r122", "r123", "r124", "r125", "r126", "r127",
+
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+ "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
+ "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
+ "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
+ "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
+ "f64", "f65", "f66", "f67", "f68", "f69", "f70", "f71",
+ "f72", "f73", "f74", "f75", "f76", "f77", "f78", "f79",
+ "f80", "f81", "f82", "f83", "f84", "f85", "f86", "f87",
+ "f88", "f89", "f90", "f91", "f92", "f93", "f94", "f95",
+ "f96", "f97", "f98", "f99", "f100", "f101", "f102", "f103",
+ "f104", "f105", "f106", "f107", "f108", "f109", "f110", "f111",
+ "f112", "f113", "f114", "f115", "f116", "f117", "f118", "f119",
+ "f120", "f121", "f122", "f123", "f124", "f125", "f126", "f127",
+
+ "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
+ "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",
+ "p16", "p17", "p18", "p19", "p20", "p21", "p22", "p23",
+ "p24", "p25", "p26", "p27", "p28", "p29", "p30", "p31",
+ "p32", "p33", "p34", "p35", "p36", "p37", "p38", "p39",
+ "p40", "p41", "p42", "p43", "p44", "p45", "p46", "p47",
+ "p48", "p49", "p50", "p51", "p52", "p53", "p54", "p55",
+ "p56", "p57", "p58", "p59", "p60", "p61", "p62", "p63",
+
+ "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7",
+
+ "vfp", "vrap",
+
+ "pr", "ip", "psr", "cfm",
+
+ "kr0", "kr1", "kr2", "kr3", "kr4", "kr5", "kr6", "kr7",
+ "", "", "", "", "", "", "", "",
+ "rsc", "bsp", "bspstore", "rnat",
+ "", "fcr", "", "",
+ "eflag", "csd", "ssd", "cflg", "fsr", "fir", "fdr", "",
+ "ccv", "", "", "", "unat", "", "", "",
+ "fpsr", "", "", "", "itc",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "",
+ "pfs", "lc", "ec",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "",
+ "nat0", "nat1", "nat2", "nat3", "nat4", "nat5", "nat6", "nat7",
+ "nat8", "nat9", "nat10", "nat11", "nat12", "nat13", "nat14", "nat15",
+ "nat16", "nat17", "nat18", "nat19", "nat20", "nat21", "nat22", "nat23",
+ "nat24", "nat25", "nat26", "nat27", "nat28", "nat29", "nat30", "nat31",
+ "nat32", "nat33", "nat34", "nat35", "nat36", "nat37", "nat38", "nat39",
+ "nat40", "nat41", "nat42", "nat43", "nat44", "nat45", "nat46", "nat47",
+ "nat48", "nat49", "nat50", "nat51", "nat52", "nat53", "nat54", "nat55",
+ "nat56", "nat57", "nat58", "nat59", "nat60", "nat61", "nat62", "nat63",
+ "nat64", "nat65", "nat66", "nat67", "nat68", "nat69", "nat70", "nat71",
+ "nat72", "nat73", "nat74", "nat75", "nat76", "nat77", "nat78", "nat79",
+ "nat80", "nat81", "nat82", "nat83", "nat84", "nat85", "nat86", "nat87",
+ "nat88", "nat89", "nat90", "nat91", "nat92", "nat93", "nat94", "nat95",
+ "nat96", "nat97", "nat98", "nat99", "nat100","nat101","nat102","nat103",
+ "nat104","nat105","nat106","nat107","nat108","nat109","nat110","nat111",
+ "nat112","nat113","nat114","nat115","nat116","nat117","nat118","nat119",
+ "nat120","nat121","nat122","nat123","nat124","nat125","nat126","nat127",
+};
+
+struct frame_extra_info
+ {
+ CORE_ADDR bsp; /* points at r32 for the current frame */
+ CORE_ADDR cfm; /* cfm value for current frame */
+ int sof; /* Size of frame (decoded from cfm value) */
+ int sol; /* Size of locals (decoded from cfm value) */
+ CORE_ADDR after_prologue;
+ /* Address of first instruction after the last
+ prologue instruction; Note that there may
+ be instructions from the function's body
+ intermingled with the prologue. */
+ int mem_stack_frame_size;
+ /* Size of the memory stack frame (may be zero),
+ or -1 if it has not been determined yet. */
+ int fp_reg; /* Register number (if any) used a frame pointer
+ for this frame. 0 if no register is being used
+ as the frame pointer. */
+ };
+
+struct gdbarch_tdep
+ {
+ int os_ident; /* From the ELF header, one of the ELFOSABI_
+ constants: ELFOSABI_LINUX, ELFOSABI_AIX,
+ etc. */
+ CORE_ADDR (*sigcontext_register_address) (CORE_ADDR, int);
+ /* OS specific function which, given a frame address
+ and register number, returns the offset to the
+ given register from the start of the frame. */
+ CORE_ADDR (*find_global_pointer) (CORE_ADDR);
+ };
+
+#define SIGCONTEXT_REGISTER_ADDRESS \
+ (gdbarch_tdep (current_gdbarch)->sigcontext_register_address)
+#define FIND_GLOBAL_POINTER \
+ (gdbarch_tdep (current_gdbarch)->find_global_pointer)
+
+static char *
+ia64_register_name (int reg)
+{
+ return ia64_register_names[reg];
+}
+
+int
+ia64_register_raw_size (int reg)
+{
+ return (IA64_FR0_REGNUM <= reg && reg <= IA64_FR127_REGNUM) ? 16 : 8;
+}
+
+int
+ia64_register_virtual_size (int reg)
+{
+ return (IA64_FR0_REGNUM <= reg && reg <= IA64_FR127_REGNUM) ? 16 : 8;
+}
+
+/* Return true iff register N's virtual format is different from
+ its raw format. */
+int
+ia64_register_convertible (int nr)
+{
+ return (IA64_FR0_REGNUM <= nr && nr <= IA64_FR127_REGNUM);
+}
+
+const struct floatformat floatformat_ia64_ext =
+{
+ floatformat_little, 82, 0, 1, 17, 65535, 0x1ffff, 18, 64,
+ floatformat_intbit_yes
+};
+
+void
+ia64_register_convert_to_virtual (int regnum, struct type *type,
+ char *from, char *to)
+{
+ if (regnum >= IA64_FR0_REGNUM && regnum <= IA64_FR127_REGNUM)
+ {
+ DOUBLEST val;
+ floatformat_to_doublest (&floatformat_ia64_ext, from, &val);
+ store_floating(to, TYPE_LENGTH(type), val);
+ }
+ else
+ error("ia64_register_convert_to_virtual called with non floating point register number");
+}
+
+void
+ia64_register_convert_to_raw (struct type *type, int regnum,
+ char *from, char *to)
+{
+ if (regnum >= IA64_FR0_REGNUM && regnum <= IA64_FR127_REGNUM)
+ {
+ DOUBLEST val = extract_floating (from, TYPE_LENGTH(type));
+ floatformat_from_doublest (&floatformat_ia64_ext, &val, to);
+ }
+ else
+ error("ia64_register_convert_to_raw called with non floating point register number");
+}
+
+struct type *
+ia64_register_virtual_type (int reg)
+{
+ if (reg >= IA64_FR0_REGNUM && reg <= IA64_FR127_REGNUM)
+ return builtin_type_long_double;
+ else
+ return builtin_type_long;
+}
+
+int
+ia64_register_byte (int reg)
+{
+ return (8 * reg) +
+ (reg <= IA64_FR0_REGNUM ? 0 : 8 * ((reg > IA64_FR127_REGNUM) ? 128 : reg - IA64_FR0_REGNUM));
+}
+
+/* Read the given register from a sigcontext structure in the
+ specified frame. */
+
+static CORE_ADDR
+read_sigcontext_register (struct frame_info *frame, int regnum)
+{
+ CORE_ADDR regaddr;
+
+ if (frame == NULL)
+ internal_error (__FILE__, __LINE__,
+ "read_sigcontext_register: NULL frame");
+ if (!frame->signal_handler_caller)
+ internal_error (__FILE__, __LINE__,
+ "read_sigcontext_register: frame not a signal_handler_caller");
+ if (SIGCONTEXT_REGISTER_ADDRESS == 0)
+ internal_error (__FILE__, __LINE__,
+ "read_sigcontext_register: SIGCONTEXT_REGISTER_ADDRESS is 0");
+
+ regaddr = SIGCONTEXT_REGISTER_ADDRESS (frame->frame, regnum);
+ if (regaddr)
+ return read_memory_integer (regaddr, REGISTER_RAW_SIZE (regnum));
+ else
+ internal_error (__FILE__, __LINE__,
+ "read_sigcontext_register: Register %d not in struct sigcontext", regnum);
+}
+
+/* Extract ``len'' bits from an instruction bundle starting at
+ bit ``from''. */
+
+static long long
+extract_bit_field (char *bundle, int from, int len)
+{
+ long long result = 0LL;
+ int to = from + len;
+ int from_byte = from / 8;
+ int to_byte = to / 8;
+ unsigned char *b = (unsigned char *) bundle;
+ unsigned char c;
+ int lshift;
+ int i;
+
+ c = b[from_byte];
+ if (from_byte == to_byte)
+ c = ((unsigned char) (c << (8 - to % 8))) >> (8 - to % 8);
+ result = c >> (from % 8);
+ lshift = 8 - (from % 8);
+
+ for (i = from_byte+1; i < to_byte; i++)
+ {
+ result |= ((long long) b[i]) << lshift;
+ lshift += 8;
+ }
+
+ if (from_byte < to_byte && (to % 8 != 0))
+ {
+ c = b[to_byte];
+ c = ((unsigned char) (c << (8 - to % 8))) >> (8 - to % 8);
+ result |= ((long long) c) << lshift;
+ }
+
+ return result;
+}
+
+/* Replace the specified bits in an instruction bundle */
+
+static void
+replace_bit_field (char *bundle, long long val, int from, int len)
+{
+ int to = from + len;
+ int from_byte = from / 8;
+ int to_byte = to / 8;
+ unsigned char *b = (unsigned char *) bundle;
+ unsigned char c;
+
+ if (from_byte == to_byte)
+ {
+ unsigned char left, right;
+ c = b[from_byte];
+ left = (c >> (to % 8)) << (to % 8);
+ right = ((unsigned char) (c << (8 - from % 8))) >> (8 - from % 8);
+ c = (unsigned char) (val & 0xff);
+ c = (unsigned char) (c << (from % 8 + 8 - to % 8)) >> (8 - to % 8);
+ c |= right | left;
+ b[from_byte] = c;
+ }
+ else
+ {
+ int i;
+ c = b[from_byte];
+ c = ((unsigned char) (c << (8 - from % 8))) >> (8 - from % 8);
+ c = c | (val << (from % 8));
+ b[from_byte] = c;
+ val >>= 8 - from % 8;
+
+ for (i = from_byte+1; i < to_byte; i++)
+ {
+ c = val & 0xff;
+ val >>= 8;
+ b[i] = c;
+ }
+
+ if (to % 8 != 0)
+ {
+ unsigned char cv = (unsigned char) val;
+ c = b[to_byte];
+ c = c >> (to % 8) << (to % 8);
+ c |= ((unsigned char) (cv << (8 - to % 8))) >> (8 - to % 8);
+ b[to_byte] = c;
+ }
+ }
+}
+
+/* Return the contents of slot N (for N = 0, 1, or 2) in
+ and instruction bundle */
+
+static long long
+slotN_contents (char *bundle, int slotnum)
+{
+ return extract_bit_field (bundle, 5+41*slotnum, 41);
+}
+
+/* Store an instruction in an instruction bundle */
+
+static void
+replace_slotN_contents (char *bundle, long long instr, int slotnum)
+{
+ replace_bit_field (bundle, instr, 5+41*slotnum, 41);
+}
+
+static enum instruction_type template_encoding_table[32][3] =
+{
+ { M, I, I }, /* 00 */
+ { M, I, I }, /* 01 */
+ { M, I, I }, /* 02 */
+ { M, I, I }, /* 03 */
+ { M, L, X }, /* 04 */
+ { M, L, X }, /* 05 */
+ { undefined, undefined, undefined }, /* 06 */
+ { undefined, undefined, undefined }, /* 07 */
+ { M, M, I }, /* 08 */
+ { M, M, I }, /* 09 */
+ { M, M, I }, /* 0A */
+ { M, M, I }, /* 0B */
+ { M, F, I }, /* 0C */
+ { M, F, I }, /* 0D */
+ { M, M, F }, /* 0E */
+ { M, M, F }, /* 0F */
+ { M, I, B }, /* 10 */
+ { M, I, B }, /* 11 */
+ { M, B, B }, /* 12 */
+ { M, B, B }, /* 13 */
+ { undefined, undefined, undefined }, /* 14 */
+ { undefined, undefined, undefined }, /* 15 */
+ { B, B, B }, /* 16 */
+ { B, B, B }, /* 17 */
+ { M, M, B }, /* 18 */
+ { M, M, B }, /* 19 */
+ { undefined, undefined, undefined }, /* 1A */
+ { undefined, undefined, undefined }, /* 1B */
+ { M, F, B }, /* 1C */
+ { M, F, B }, /* 1D */
+ { undefined, undefined, undefined }, /* 1E */
+ { undefined, undefined, undefined }, /* 1F */
+};
+
+/* Fetch and (partially) decode an instruction at ADDR and return the
+ address of the next instruction to fetch. */
+
+static CORE_ADDR
+fetch_instruction (CORE_ADDR addr, instruction_type *it, long long *instr)
+{
+ char bundle[BUNDLE_LEN];
+ int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER;
+ long long template;
+ int val;
+
+ /* Warn about slot numbers greater than 2. We used to generate
+ an error here on the assumption that the user entered an invalid
+ address. But, sometimes GDB itself requests an invalid address.
+ This can (easily) happen when execution stops in a function for
+ which there are no symbols. The prologue scanner will attempt to
+ find the beginning of the function - if the nearest symbol
+ happens to not be aligned on a bundle boundary (16 bytes), the
+ resulting starting address will cause GDB to think that the slot
+ number is too large.
+
+ So we warn about it and set the slot number to zero. It is
+ not necessarily a fatal condition, particularly if debugging
+ at the assembly language level. */
+ if (slotnum > 2)
+ {
+ warning ("Can't fetch instructions for slot numbers greater than 2.\n"
+ "Using slot 0 instead");
+ slotnum = 0;
+ }
+
+ addr &= ~0x0f;
+
+ val = target_read_memory (addr, bundle, BUNDLE_LEN);
+
+ if (val != 0)
+ return 0;
+
+ *instr = slotN_contents (bundle, slotnum);
+ template = extract_bit_field (bundle, 0, 5);
+ *it = template_encoding_table[(int)template][slotnum];
+
+ if (slotnum == 2 || (slotnum == 1 && *it == L))
+ addr += 16;
+ else
+ addr += (slotnum + 1) * SLOT_MULTIPLIER;
+
+ return addr;
+}
+
+/* There are 5 different break instructions (break.i, break.b,
+ break.m, break.f, and break.x), but they all have the same
+ encoding. (The five bit template in the low five bits of the
+ instruction bundle distinguishes one from another.)
+
+ The runtime architecture manual specifies that break instructions
+ used for debugging purposes must have the upper two bits of the 21
+ bit immediate set to a 0 and a 1 respectively. A breakpoint
+ instruction encodes the most significant bit of its 21 bit
+ immediate at bit 36 of the 41 bit instruction. The penultimate msb
+ is at bit 25 which leads to the pattern below.
+
+ Originally, I had this set up to do, e.g, a "break.i 0x80000" But
+ it turns out that 0x80000 was used as the syscall break in the early
+ simulators. So I changed the pattern slightly to do "break.i 0x080001"
+ instead. But that didn't work either (I later found out that this
+ pattern was used by the simulator that I was using.) So I ended up
+ using the pattern seen below. */
+
+#if 0
+#define BREAKPOINT 0x00002000040LL
+#endif
+#define BREAKPOINT 0x00003333300LL
+
+static int
+ia64_memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ char bundle[BUNDLE_LEN];
+ int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER;
+ long long instr;
+ int val;
+ int template;
+
+ if (slotnum > 2)
+ error("Can't insert breakpoint for slot numbers greater than 2.");
+
+ addr &= ~0x0f;
+
+ val = target_read_memory (addr, bundle, BUNDLE_LEN);
+
+ /* Check for L type instruction in 2nd slot, if present then
+ bump up the slot number to the 3rd slot */
+ template = extract_bit_field (bundle, 0, 5);
+ if (slotnum == 1 && template_encoding_table[template][1] == L)
+ {
+ slotnum = 2;
+ }
+
+ instr = slotN_contents (bundle, slotnum);
+ memcpy(contents_cache, &instr, sizeof(instr));
+ replace_slotN_contents (bundle, BREAKPOINT, slotnum);
+ if (val == 0)
+ target_write_memory (addr, bundle, BUNDLE_LEN);
+
+ return val;
+}
+
+static int
+ia64_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ char bundle[BUNDLE_LEN];
+ int slotnum = (addr & 0x0f) / SLOT_MULTIPLIER;
+ long long instr;
+ int val;
+ int template;
+
+ addr &= ~0x0f;
+
+ val = target_read_memory (addr, bundle, BUNDLE_LEN);
+
+ /* Check for L type instruction in 2nd slot, if present then
+ bump up the slot number to the 3rd slot */
+ template = extract_bit_field (bundle, 0, 5);
+ if (slotnum == 1 && template_encoding_table[template][1] == L)
+ {
+ slotnum = 2;
+ }
+
+ memcpy (&instr, contents_cache, sizeof instr);
+ replace_slotN_contents (bundle, instr, slotnum);
+ if (val == 0)
+ target_write_memory (addr, bundle, BUNDLE_LEN);
+
+ return val;
+}
+
+/* We don't really want to use this, but remote.c needs to call it in order
+ to figure out if Z-packets are supported or not. Oh, well. */
+const unsigned char *
+ia64_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+ static unsigned char breakpoint[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ *lenptr = sizeof (breakpoint);
+#if 0
+ *pcptr &= ~0x0f;
+#endif
+ return breakpoint;
+}
+
+CORE_ADDR
+ia64_read_pc (ptid_t ptid)
+{
+ CORE_ADDR psr_value = read_register_pid (IA64_PSR_REGNUM, ptid);
+ CORE_ADDR pc_value = read_register_pid (IA64_IP_REGNUM, ptid);
+ int slot_num = (psr_value >> 41) & 3;
+
+ return pc_value | (slot_num * SLOT_MULTIPLIER);
+}
+
+void
+ia64_write_pc (CORE_ADDR new_pc, ptid_t ptid)
+{
+ int slot_num = (int) (new_pc & 0xf) / SLOT_MULTIPLIER;
+ CORE_ADDR psr_value = read_register_pid (IA64_PSR_REGNUM, ptid);
+ psr_value &= ~(3LL << 41);
+ psr_value |= (CORE_ADDR)(slot_num & 0x3) << 41;
+
+ new_pc &= ~0xfLL;
+
+ write_register_pid (IA64_PSR_REGNUM, psr_value, ptid);
+ write_register_pid (IA64_IP_REGNUM, new_pc, ptid);
+}
+
+#define IS_NaT_COLLECTION_ADDR(addr) ((((addr) >> 3) & 0x3f) == 0x3f)
+
+/* Returns the address of the slot that's NSLOTS slots away from
+ the address ADDR. NSLOTS may be positive or negative. */
+static CORE_ADDR
+rse_address_add(CORE_ADDR addr, int nslots)
+{
+ CORE_ADDR new_addr;
+ int mandatory_nat_slots = nslots / 63;
+ int direction = nslots < 0 ? -1 : 1;
+
+ new_addr = addr + 8 * (nslots + mandatory_nat_slots);
+
+ if ((new_addr >> 9) != ((addr + 8 * 64 * mandatory_nat_slots) >> 9))
+ new_addr += 8 * direction;
+
+ if (IS_NaT_COLLECTION_ADDR(new_addr))
+ new_addr += 8 * direction;
+
+ return new_addr;
+}
+
+/* The IA-64 frame chain is a bit odd. We won't always have a frame
+ pointer, so we use the SP value as the FP for the purpose of
+ creating a frame. There is sometimes a register (not fixed) which
+ is used as a frame pointer. When this register exists, it is not
+ especially hard to determine which one is being used. It isn't
+ even really hard to compute the frame chain, but it can be
+ computationally expensive. So, instead of making life difficult
+ (and slow), we pick a more convenient representation of the frame
+ chain, knowing that we'll have to make some small adjustments in
+ other places. (E.g, note that read_fp() is actually read_sp() in
+ ia64_gdbarch_init() below.)
+
+ Okay, so what is the frame chain exactly? It'll be the SP value
+ at the time that the function in question was entered.
+
+ Note that this *should* actually the frame pointer for the current
+ function! But as I note above, if we were to attempt to find the
+ address of the beginning of the previous frame, we'd waste a lot
+ of cycles for no good reason. So instead, we simply choose to
+ represent the frame chain as the end of the previous frame instead
+ of the beginning. */
+
+CORE_ADDR
+ia64_frame_chain (struct frame_info *frame)
+{
+ if (frame->signal_handler_caller)
+ return read_sigcontext_register (frame, sp_regnum);
+ else if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ return frame->frame;
+ else
+ {
+ FRAME_INIT_SAVED_REGS (frame);
+ if (frame->saved_regs[IA64_VFP_REGNUM])
+ return read_memory_integer (frame->saved_regs[IA64_VFP_REGNUM], 8);
+ else
+ return frame->frame + frame->extra_info->mem_stack_frame_size;
+ }
+}
+
+CORE_ADDR
+ia64_frame_saved_pc (struct frame_info *frame)
+{
+ if (frame->signal_handler_caller)
+ return read_sigcontext_register (frame, pc_regnum);
+ else if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ return generic_read_register_dummy (frame->pc, frame->frame, pc_regnum);
+ else
+ {
+ FRAME_INIT_SAVED_REGS (frame);
+
+ if (frame->saved_regs[IA64_VRAP_REGNUM])
+ return read_memory_integer (frame->saved_regs[IA64_VRAP_REGNUM], 8);
+ else if (frame->next && frame->next->signal_handler_caller)
+ return read_sigcontext_register (frame->next, IA64_BR0_REGNUM);
+ else /* either frameless, or not far enough along in the prologue... */
+ return ia64_saved_pc_after_call (frame);
+ }
+}
+
+/* Limit the number of skipped non-prologue instructions since examining
+ of the prologue is expensive. */
+static int max_skip_non_prologue_insns = 10;
+
+/* Given PC representing the starting address of a function, and
+ LIM_PC which is the (sloppy) limit to which to scan when looking
+ for a prologue, attempt to further refine this limit by using
+ the line data in the symbol table. If successful, a better guess
+ on where the prologue ends is returned, otherwise the previous
+ value of lim_pc is returned. TRUST_LIMIT is a pointer to a flag
+ which will be set to indicate whether the returned limit may be
+ used with no further scanning in the event that the function is
+ frameless. */
+
+static CORE_ADDR
+refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc, int *trust_limit)
+{
+ struct symtab_and_line prologue_sal;
+ CORE_ADDR start_pc = pc;
+
+ /* Start off not trusting the limit. */
+ *trust_limit = 0;
+
+ prologue_sal = find_pc_line (pc, 0);
+ if (prologue_sal.line != 0)
+ {
+ int i;
+ CORE_ADDR addr = prologue_sal.end;
+
+ /* Handle the case in which compiler's optimizer/scheduler
+ has moved instructions into the prologue. We scan ahead
+ in the function looking for address ranges whose corresponding
+ line number is less than or equal to the first one that we
+ found for the function. (It can be less than when the
+ scheduler puts a body instruction before the first prologue
+ instruction.) */
+ for (i = 2 * max_skip_non_prologue_insns;
+ i > 0 && (lim_pc == 0 || addr < lim_pc);
+ i--)
+ {
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (addr, 0);
+ if (sal.line == 0)
+ break;
+ if (sal.line <= prologue_sal.line
+ && sal.symtab == prologue_sal.symtab)
+ {
+ prologue_sal = sal;
+ }
+ addr = sal.end;
+ }
+
+ if (lim_pc == 0 || prologue_sal.end < lim_pc)
+ {
+ lim_pc = prologue_sal.end;
+ if (start_pc == get_pc_function_start (lim_pc))
+ *trust_limit = 1;
+ }
+ }
+ return lim_pc;
+}
+
+#define isScratch(_regnum_) ((_regnum_) == 2 || (_regnum_) == 3 \
+ || (8 <= (_regnum_) && (_regnum_) <= 11) \
+ || (14 <= (_regnum_) && (_regnum_) <= 31))
+#define imm9(_instr_) \
+ ( ((((_instr_) & 0x01000000000LL) ? -1 : 0) << 8) \
+ | (((_instr_) & 0x00008000000LL) >> 20) \
+ | (((_instr_) & 0x00000001fc0LL) >> 6))
+
+static CORE_ADDR
+examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
+{
+ CORE_ADDR next_pc;
+ CORE_ADDR last_prologue_pc = pc;
+ instruction_type it;
+ long long instr;
+ int do_fsr_stuff = 0;
+
+ int cfm_reg = 0;
+ int ret_reg = 0;
+ int fp_reg = 0;
+ int unat_save_reg = 0;
+ int pr_save_reg = 0;
+ int mem_stack_frame_size = 0;
+ int spill_reg = 0;
+ CORE_ADDR spill_addr = 0;
+ char instores[8];
+ char infpstores[8];
+ int trust_limit;
+
+ memset (instores, 0, sizeof instores);
+ memset (infpstores, 0, sizeof infpstores);
+
+ if (frame && !frame->saved_regs)
+ {
+ frame_saved_regs_zalloc (frame);
+ do_fsr_stuff = 1;
+ }
+
+ if (frame
+ && !do_fsr_stuff
+ && frame->extra_info->after_prologue != 0
+ && frame->extra_info->after_prologue <= lim_pc)
+ return frame->extra_info->after_prologue;
+
+ lim_pc = refine_prologue_limit (pc, lim_pc, &trust_limit);
+
+ /* Must start with an alloc instruction */
+ next_pc = fetch_instruction (pc, &it, &instr);
+ if (pc < lim_pc && next_pc
+ && it == M && ((instr & 0x1ee0000003fLL) == 0x02c00000000LL))
+ {
+ /* alloc */
+ int sor = (int) ((instr & 0x00078000000LL) >> 27);
+ int sol = (int) ((instr & 0x00007f00000LL) >> 20);
+ int sof = (int) ((instr & 0x000000fe000LL) >> 13);
+ /* Okay, so sor, sol, and sof aren't used right now; but perhaps
+ we could compare against the size given to us via the cfm as
+ either a sanity check or possibly to see if the frame has been
+ changed by a later alloc instruction... */
+ int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
+ cfm_reg = rN;
+ last_prologue_pc = next_pc;
+ pc = next_pc;
+ }
+ else
+ {
+ pc = lim_pc; /* Frameless: We're done early. */
+ if (trust_limit)
+ last_prologue_pc = lim_pc;
+ }
+
+ /* Loop, looking for prologue instructions, keeping track of
+ where preserved registers were spilled. */
+ while (pc < lim_pc)
+ {
+ next_pc = fetch_instruction (pc, &it, &instr);
+ if (next_pc == 0)
+ break;
+
+ if ((it == B && ((instr & 0x1e1f800003f) != 0x04000000000))
+ || ((instr & 0x3fLL) != 0LL))
+ {
+ /* Exit loop upon hitting a non-nop branch instruction
+ or a predicated instruction. */
+ break;
+ }
+ else if (it == I && ((instr & 0x1eff8000000LL) == 0x00188000000LL))
+ {
+ /* Move from BR */
+ int b2 = (int) ((instr & 0x0000000e000LL) >> 13);
+ int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
+ int qp = (int) (instr & 0x0000000003f);
+
+ if (qp == 0 && b2 == 0 && rN >= 32 && ret_reg == 0)
+ {
+ ret_reg = rN;
+ last_prologue_pc = next_pc;
+ }
+ }
+ else if ((it == I || it == M)
+ && ((instr & 0x1ee00000000LL) == 0x10800000000LL))
+ {
+ /* adds rN = imm14, rM (or mov rN, rM when imm14 is 0) */
+ int imm = (int) ((((instr & 0x01000000000LL) ? -1 : 0) << 13)
+ | ((instr & 0x001f8000000LL) >> 20)
+ | ((instr & 0x000000fe000LL) >> 13));
+ int rM = (int) ((instr & 0x00007f00000LL) >> 20);
+ int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
+ int qp = (int) (instr & 0x0000000003fLL);
+
+ if (qp == 0 && rN >= 32 && imm == 0 && rM == 12 && fp_reg == 0)
+ {
+ /* mov rN, r12 */
+ fp_reg = rN;
+ last_prologue_pc = next_pc;
+ }
+ else if (qp == 0 && rN == 12 && rM == 12)
+ {
+ /* adds r12, -mem_stack_frame_size, r12 */
+ mem_stack_frame_size -= imm;
+ last_prologue_pc = next_pc;
+ }
+ else if (qp == 0 && rN == 2
+ && ((rM == fp_reg && fp_reg != 0) || rM == 12))
+ {
+ /* adds r2, spilloffset, rFramePointer
+ or
+ adds r2, spilloffset, r12
+
+ Get ready for stf.spill or st8.spill instructions.
+ The address to start spilling at is loaded into r2.
+ FIXME: Why r2? That's what gcc currently uses; it
+ could well be different for other compilers. */
+
+ /* Hmm... whether or not this will work will depend on
+ where the pc is. If it's still early in the prologue
+ this'll be wrong. FIXME */
+ spill_addr = (frame ? frame->frame : 0)
+ + (rM == 12 ? 0 : mem_stack_frame_size)
+ + imm;
+ spill_reg = rN;
+ last_prologue_pc = next_pc;
+ }
+ }
+ else if (it == M
+ && ( ((instr & 0x1efc0000000LL) == 0x0eec0000000LL)
+ || ((instr & 0x1ffc8000000LL) == 0x0cec0000000LL) ))
+ {
+ /* stf.spill [rN] = fM, imm9
+ or
+ stf.spill [rN] = fM */
+
+ int imm = imm9(instr);
+ int rN = (int) ((instr & 0x00007f00000LL) >> 20);
+ int fM = (int) ((instr & 0x000000fe000LL) >> 13);
+ int qp = (int) (instr & 0x0000000003fLL);
+ if (qp == 0 && rN == spill_reg && spill_addr != 0
+ && ((2 <= fM && fM <= 5) || (16 <= fM && fM <= 31)))
+ {
+ if (do_fsr_stuff)
+ frame->saved_regs[IA64_FR0_REGNUM + fM] = spill_addr;
+
+ if ((instr & 0x1efc0000000) == 0x0eec0000000)
+ spill_addr += imm;
+ else
+ spill_addr = 0; /* last one; must be done */
+ last_prologue_pc = next_pc;
+ }
+ }
+ else if ((it == M && ((instr & 0x1eff8000000LL) == 0x02110000000LL))
+ || (it == I && ((instr & 0x1eff8000000LL) == 0x00050000000LL)) )
+ {
+ /* mov.m rN = arM
+ or
+ mov.i rN = arM */
+
+ int arM = (int) ((instr & 0x00007f00000LL) >> 20);
+ int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
+ int qp = (int) (instr & 0x0000000003fLL);
+ if (qp == 0 && isScratch (rN) && arM == 36 /* ar.unat */)
+ {
+ /* We have something like "mov.m r3 = ar.unat". Remember the
+ r3 (or whatever) and watch for a store of this register... */
+ unat_save_reg = rN;
+ last_prologue_pc = next_pc;
+ }
+ }
+ else if (it == I && ((instr & 0x1eff8000000LL) == 0x00198000000LL))
+ {
+ /* mov rN = pr */
+ int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
+ int qp = (int) (instr & 0x0000000003fLL);
+ if (qp == 0 && isScratch (rN))
+ {
+ pr_save_reg = rN;
+ last_prologue_pc = next_pc;
+ }
+ }
+ else if (it == M
+ && ( ((instr & 0x1ffc8000000LL) == 0x08cc0000000LL)
+ || ((instr & 0x1efc0000000LL) == 0x0acc0000000LL)))
+ {
+ /* st8 [rN] = rM
+ or
+ st8 [rN] = rM, imm9 */
+ int rN = (int) ((instr & 0x00007f00000LL) >> 20);
+ int rM = (int) ((instr & 0x000000fe000LL) >> 13);
+ int qp = (int) (instr & 0x0000000003fLL);
+ if (qp == 0 && rN == spill_reg && spill_addr != 0
+ && (rM == unat_save_reg || rM == pr_save_reg))
+ {
+ /* We've found a spill of either the UNAT register or the PR
+ register. (Well, not exactly; what we've actually found is
+ a spill of the register that UNAT or PR was moved to).
+ Record that fact and move on... */
+ if (rM == unat_save_reg)
+ {
+ /* Track UNAT register */
+ if (do_fsr_stuff)
+ frame->saved_regs[IA64_UNAT_REGNUM] = spill_addr;
+ unat_save_reg = 0;
+ }
+ else
+ {
+ /* Track PR register */
+ if (do_fsr_stuff)
+ frame->saved_regs[IA64_PR_REGNUM] = spill_addr;
+ pr_save_reg = 0;
+ }
+ if ((instr & 0x1efc0000000LL) == 0x0acc0000000LL)
+ /* st8 [rN] = rM, imm9 */
+ spill_addr += imm9(instr);
+ else
+ spill_addr = 0; /* must be done spilling */
+ last_prologue_pc = next_pc;
+ }
+ else if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32])
+ {
+ /* Allow up to one store of each input register. */
+ instores[rM-32] = 1;
+ last_prologue_pc = next_pc;
+ }
+ }
+ else if (it == M && ((instr & 0x1ff08000000LL) == 0x08c00000000LL))
+ {
+ /* One of
+ st1 [rN] = rM
+ st2 [rN] = rM
+ st4 [rN] = rM
+ st8 [rN] = rM
+ Note that the st8 case is handled in the clause above.
+
+ Advance over stores of input registers. One store per input
+ register is permitted. */
+ int rM = (int) ((instr & 0x000000fe000LL) >> 13);
+ int qp = (int) (instr & 0x0000000003fLL);
+ if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32])
+ {
+ instores[rM-32] = 1;
+ last_prologue_pc = next_pc;
+ }
+ }
+ else if (it == M && ((instr & 0x1ff88000000LL) == 0x0cc80000000LL))
+ {
+ /* Either
+ stfs [rN] = fM
+ or
+ stfd [rN] = fM
+
+ Advance over stores of floating point input registers. Again
+ one store per register is permitted */
+ int fM = (int) ((instr & 0x000000fe000LL) >> 13);
+ int qp = (int) (instr & 0x0000000003fLL);
+ if (qp == 0 && 8 <= fM && fM < 16 && !infpstores[fM - 8])
+ {
+ infpstores[fM-8] = 1;
+ last_prologue_pc = next_pc;
+ }
+ }
+ else if (it == M
+ && ( ((instr & 0x1ffc8000000LL) == 0x08ec0000000LL)
+ || ((instr & 0x1efc0000000LL) == 0x0aec0000000LL)))
+ {
+ /* st8.spill [rN] = rM
+ or
+ st8.spill [rN] = rM, imm9 */
+ int rN = (int) ((instr & 0x00007f00000LL) >> 20);
+ int rM = (int) ((instr & 0x000000fe000LL) >> 13);
+ int qp = (int) (instr & 0x0000000003fLL);
+ if (qp == 0 && rN == spill_reg && 4 <= rM && rM <= 7)
+ {
+ /* We've found a spill of one of the preserved general purpose
+ regs. Record the spill address and advance the spill
+ register if appropriate. */
+ if (do_fsr_stuff)
+ frame->saved_regs[IA64_GR0_REGNUM + rM] = spill_addr;
+ if ((instr & 0x1efc0000000LL) == 0x0aec0000000LL)
+ /* st8.spill [rN] = rM, imm9 */
+ spill_addr += imm9(instr);
+ else
+ spill_addr = 0; /* Done spilling */
+ last_prologue_pc = next_pc;
+ }
+ }
+
+ pc = next_pc;
+ }
+
+ if (do_fsr_stuff) {
+ int i;
+ CORE_ADDR addr;
+ int sor, rrb_gr;
+
+ /* Extract the size of the rotating portion of the stack
+ frame and the register rename base from the current
+ frame marker. */
+ sor = ((frame->extra_info->cfm >> 14) & 0xf) * 8;
+ rrb_gr = (frame->extra_info->cfm >> 18) & 0x7f;
+
+ for (i = 0, addr = frame->extra_info->bsp;
+ i < frame->extra_info->sof;
+ i++, addr += 8)
+ {
+ if (IS_NaT_COLLECTION_ADDR (addr))
+ {
+ addr += 8;
+ }
+ if (i < sor)
+ frame->saved_regs[IA64_GR32_REGNUM + ((i + (sor - rrb_gr)) % sor)]
+ = addr;
+ else
+ frame->saved_regs[IA64_GR32_REGNUM + i] = addr;
+
+ if (i+32 == cfm_reg)
+ frame->saved_regs[IA64_CFM_REGNUM] = addr;
+ if (i+32 == ret_reg)
+ frame->saved_regs[IA64_VRAP_REGNUM] = addr;
+ if (i+32 == fp_reg)
+ frame->saved_regs[IA64_VFP_REGNUM] = addr;
+ }
+ }
+
+ if (frame && frame->extra_info) {
+ frame->extra_info->after_prologue = last_prologue_pc;
+ frame->extra_info->mem_stack_frame_size = mem_stack_frame_size;
+ frame->extra_info->fp_reg = fp_reg;
+ }
+
+ return last_prologue_pc;
+}
+
+CORE_ADDR
+ia64_skip_prologue (CORE_ADDR pc)
+{
+ return examine_prologue (pc, pc+1024, 0);
+}
+
+void
+ia64_frame_init_saved_regs (struct frame_info *frame)
+{
+ if (frame->saved_regs)
+ return;
+
+ if (frame->signal_handler_caller && SIGCONTEXT_REGISTER_ADDRESS)
+ {
+ int regno;
+
+ frame_saved_regs_zalloc (frame);
+
+ frame->saved_regs[IA64_VRAP_REGNUM] =
+ SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_IP_REGNUM);
+ frame->saved_regs[IA64_CFM_REGNUM] =
+ SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_CFM_REGNUM);
+ frame->saved_regs[IA64_PSR_REGNUM] =
+ SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_PSR_REGNUM);
+#if 0
+ frame->saved_regs[IA64_BSP_REGNUM] =
+ SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_BSP_REGNUM);
+#endif
+ frame->saved_regs[IA64_RNAT_REGNUM] =
+ SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_RNAT_REGNUM);
+ frame->saved_regs[IA64_CCV_REGNUM] =
+ SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_CCV_REGNUM);
+ frame->saved_regs[IA64_UNAT_REGNUM] =
+ SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_UNAT_REGNUM);
+ frame->saved_regs[IA64_FPSR_REGNUM] =
+ SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_FPSR_REGNUM);
+ frame->saved_regs[IA64_PFS_REGNUM] =
+ SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_PFS_REGNUM);
+ frame->saved_regs[IA64_LC_REGNUM] =
+ SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_LC_REGNUM);
+ for (regno = IA64_GR1_REGNUM; regno <= IA64_GR31_REGNUM; regno++)
+ if (regno != sp_regnum)
+ frame->saved_regs[regno] =
+ SIGCONTEXT_REGISTER_ADDRESS (frame->frame, regno);
+ for (regno = IA64_BR0_REGNUM; regno <= IA64_BR7_REGNUM; regno++)
+ frame->saved_regs[regno] =
+ SIGCONTEXT_REGISTER_ADDRESS (frame->frame, regno);
+ for (regno = IA64_FR2_REGNUM; regno <= IA64_BR7_REGNUM; regno++)
+ frame->saved_regs[regno] =
+ SIGCONTEXT_REGISTER_ADDRESS (frame->frame, regno);
+ }
+ else
+ {
+ CORE_ADDR func_start;
+
+ func_start = get_pc_function_start (frame->pc);
+ examine_prologue (func_start, frame->pc, frame);
+ }
+}
+
+void
+ia64_get_saved_register (char *raw_buffer,
+ int *optimized,
+ CORE_ADDR *addrp,
+ struct frame_info *frame,
+ int regnum,
+ enum lval_type *lval)
+{
+ int is_dummy_frame;
+
+ if (!target_has_registers)
+ error ("No registers.");
+
+ if (optimized != NULL)
+ *optimized = 0;
+
+ if (addrp != NULL)
+ *addrp = 0;
+
+ if (lval != NULL)
+ *lval = not_lval;
+
+ is_dummy_frame = PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame);
+
+ if (regnum == SP_REGNUM && frame->next)
+ {
+ /* Handle SP values for all frames but the topmost. */
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), frame->frame);
+ }
+ else if (regnum == IA64_BSP_REGNUM)
+ {
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
+ frame->extra_info->bsp);
+ }
+ else if (regnum == IA64_VFP_REGNUM)
+ {
+ /* If the function in question uses an automatic register (r32-r127)
+ for the frame pointer, it'll be found by ia64_find_saved_register()
+ above. If the function lacks one of these frame pointers, we can
+ still provide a value since we know the size of the frame */
+ CORE_ADDR vfp = frame->frame + frame->extra_info->mem_stack_frame_size;
+ store_address (raw_buffer, REGISTER_RAW_SIZE (IA64_VFP_REGNUM), vfp);
+ }
+ else if (IA64_PR0_REGNUM <= regnum && regnum <= IA64_PR63_REGNUM)
+ {
+ char *pr_raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
+ int pr_optim;
+ enum lval_type pr_lval;
+ CORE_ADDR pr_addr;
+ int prN_val;
+ ia64_get_saved_register (pr_raw_buffer, &pr_optim, &pr_addr,
+ frame, IA64_PR_REGNUM, &pr_lval);
+ if (IA64_PR16_REGNUM <= regnum && regnum <= IA64_PR63_REGNUM)
+ {
+ /* Fetch predicate register rename base from current frame
+ marker for this frame. */
+ int rrb_pr = (frame->extra_info->cfm >> 32) & 0x3f;
+
+ /* Adjust the register number to account for register rotation. */
+ regnum = IA64_PR16_REGNUM
+ + ((regnum - IA64_PR16_REGNUM) + rrb_pr) % 48;
+ }
+ prN_val = extract_bit_field ((unsigned char *) pr_raw_buffer,
+ regnum - IA64_PR0_REGNUM, 1);
+ store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum), prN_val);
+ }
+ else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
+ {
+ char *unat_raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
+ int unat_optim;
+ enum lval_type unat_lval;
+ CORE_ADDR unat_addr;
+ int unatN_val;
+ ia64_get_saved_register (unat_raw_buffer, &unat_optim, &unat_addr,
+ frame, IA64_UNAT_REGNUM, &unat_lval);
+ unatN_val = extract_bit_field ((unsigned char *) unat_raw_buffer,
+ regnum - IA64_NAT0_REGNUM, 1);
+ store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum),
+ unatN_val);
+ }
+ else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
+ {
+ int natval = 0;
+ /* Find address of general register corresponding to nat bit we're
+ interested in. */
+ CORE_ADDR gr_addr = 0;
+
+ if (!is_dummy_frame)
+ {
+ FRAME_INIT_SAVED_REGS (frame);
+ gr_addr = frame->saved_regs[ regnum - IA64_NAT0_REGNUM
+ + IA64_GR0_REGNUM];
+ }
+ if (gr_addr)
+ {
+ /* Compute address of nat collection bits */
+ CORE_ADDR nat_addr = gr_addr | 0x1f8;
+ CORE_ADDR bsp = read_register (IA64_BSP_REGNUM);
+ CORE_ADDR nat_collection;
+ int nat_bit;
+ /* If our nat collection address is bigger than bsp, we have to get
+ the nat collection from rnat. Otherwise, we fetch the nat
+ collection from the computed address. */
+ if (nat_addr >= bsp)
+ nat_collection = read_register (IA64_RNAT_REGNUM);
+ else
+ nat_collection = read_memory_integer (nat_addr, 8);
+ nat_bit = (gr_addr >> 3) & 0x3f;
+ natval = (nat_collection >> nat_bit) & 1;
+ }
+ store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum), natval);
+ }
+ else if (regnum == IA64_IP_REGNUM)
+ {
+ CORE_ADDR pc;
+ if (frame->next)
+ {
+ /* FIXME: Set *addrp, *lval when possible. */
+ pc = ia64_frame_saved_pc (frame->next);
+ }
+ else
+ {
+ pc = read_pc ();
+ }
+ store_address (raw_buffer, REGISTER_RAW_SIZE (IA64_IP_REGNUM), pc);
+ }
+ else if (IA64_GR32_REGNUM <= regnum && regnum <= IA64_GR127_REGNUM)
+ {
+ CORE_ADDR addr = 0;
+ if (!is_dummy_frame)
+ {
+ FRAME_INIT_SAVED_REGS (frame);
+ addr = frame->saved_regs[regnum];
+ }
+
+ if (addr != 0)
+ {
+ if (lval != NULL)
+ *lval = lval_memory;
+ if (addrp != NULL)
+ *addrp = addr;
+ read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum));
+ }
+ else
+ {
+ /* r32 - r127 must be fetchable via memory. If they aren't,
+ then the register is unavailable */
+ memset (raw_buffer, 0, REGISTER_RAW_SIZE (regnum));
+ }
+ }
+ else
+ {
+ if (IA64_FR32_REGNUM <= regnum && regnum <= IA64_FR127_REGNUM)
+ {
+ /* Fetch floating point register rename base from current
+ frame marker for this frame. */
+ int rrb_fr = (frame->extra_info->cfm >> 25) & 0x7f;
+
+ /* Adjust the floating point register number to account for
+ register rotation. */
+ regnum = IA64_FR32_REGNUM
+ + ((regnum - IA64_FR32_REGNUM) + rrb_fr) % 96;
+ }
+
+ generic_get_saved_register (raw_buffer, optimized, addrp, frame,
+ regnum, lval);
+ }
+}
+
+/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of
+ EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc
+ and TYPE is the type (which is known to be struct, union or array). */
+int
+ia64_use_struct_convention (int gcc_p, struct type *type)
+{
+ struct type *float_elt_type;
+
+ /* HFAs are structures (or arrays) consisting entirely of floating
+ point values of the same length. Up to 8 of these are returned
+ in registers. Don't use the struct convention when this is the
+ case. */
+ float_elt_type = is_float_or_hfa_type (type);
+ if (float_elt_type != NULL
+ && TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type) <= 8)
+ return 0;
+
+ /* Other structs of length 32 or less are returned in r8-r11.
+ Don't use the struct convention for those either. */
+ return TYPE_LENGTH (type) > 32;
+}
+
+void
+ia64_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ struct type *float_elt_type;
+
+ float_elt_type = is_float_or_hfa_type (type);
+ if (float_elt_type != NULL)
+ {
+ int offset = 0;
+ int regnum = IA64_FR8_REGNUM;
+ int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);
+
+ while (n-- > 0)
+ {
+ ia64_register_convert_to_virtual (regnum, float_elt_type,
+ &regbuf[REGISTER_BYTE (regnum)], valbuf + offset);
+ offset += TYPE_LENGTH (float_elt_type);
+ regnum++;
+ }
+ }
+ else
+ memcpy (valbuf, &regbuf[REGISTER_BYTE (IA64_GR8_REGNUM)],
+ TYPE_LENGTH (type));
+}
+
+/* FIXME: Turn this into a stack of some sort. Unfortunately, something
+ like this is necessary though since the IA-64 calling conventions specify
+ that r8 is not preserved. */
+static CORE_ADDR struct_return_address;
+
+CORE_ADDR
+ia64_extract_struct_value_address (char *regbuf)
+{
+ /* FIXME: See above. */
+ return struct_return_address;
+}
+
+void
+ia64_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ /* FIXME: See above. */
+ /* Note that most of the work was done in ia64_push_arguments() */
+ struct_return_address = addr;
+}
+
+int
+ia64_frameless_function_invocation (struct frame_info *frame)
+{
+ FRAME_INIT_SAVED_REGS (frame);
+ return (frame->extra_info->mem_stack_frame_size == 0);
+}
+
+CORE_ADDR
+ia64_saved_pc_after_call (struct frame_info *frame)
+{
+ return read_register (IA64_BR0_REGNUM);
+}
+
+CORE_ADDR
+ia64_frame_args_address (struct frame_info *frame)
+{
+ /* frame->frame points at the SP for this frame; But we want the start
+ of the frame, not the end. Calling frame chain will get his for us. */
+ return ia64_frame_chain (frame);
+}
+
+CORE_ADDR
+ia64_frame_locals_address (struct frame_info *frame)
+{
+ /* frame->frame points at the SP for this frame; But we want the start
+ of the frame, not the end. Calling frame chain will get his for us. */
+ return ia64_frame_chain (frame);
+}
+
+void
+ia64_init_extra_frame_info (int fromleaf, struct frame_info *frame)
+{
+ CORE_ADDR bsp, cfm;
+ int next_frame_is_call_dummy = ((frame->next != NULL)
+ && PC_IN_CALL_DUMMY (frame->next->pc, frame->next->frame,
+ frame->next->frame));
+
+ frame->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+
+ if (frame->next == 0)
+ {
+ bsp = read_register (IA64_BSP_REGNUM);
+ cfm = read_register (IA64_CFM_REGNUM);
+
+ }
+ else if (frame->next->signal_handler_caller)
+ {
+ bsp = read_sigcontext_register (frame->next, IA64_BSP_REGNUM);
+ cfm = read_sigcontext_register (frame->next, IA64_CFM_REGNUM);
+ }
+ else if (next_frame_is_call_dummy)
+ {
+ bsp = generic_read_register_dummy (frame->next->pc, frame->next->frame,
+ IA64_BSP_REGNUM);
+ cfm = generic_read_register_dummy (frame->next->pc, frame->next->frame,
+ IA64_CFM_REGNUM);
+ }
+ else
+ {
+ struct frame_info *frn = frame->next;
+
+ FRAME_INIT_SAVED_REGS (frn);
+
+ if (frn->saved_regs[IA64_CFM_REGNUM] != 0)
+ cfm = read_memory_integer (frn->saved_regs[IA64_CFM_REGNUM], 8);
+ else if (frn->next && frn->next->signal_handler_caller)
+ cfm = read_sigcontext_register (frn->next, IA64_PFS_REGNUM);
+ else if (frn->next
+ && PC_IN_CALL_DUMMY (frn->next->pc, frn->next->frame,
+ frn->next->frame))
+ cfm = generic_read_register_dummy (frn->next->pc, frn->next->frame,
+ IA64_PFS_REGNUM);
+ else
+ cfm = read_register (IA64_PFS_REGNUM);
+
+ bsp = frn->extra_info->bsp;
+ }
+ frame->extra_info->cfm = cfm;
+ frame->extra_info->sof = cfm & 0x7f;
+ frame->extra_info->sol = (cfm >> 7) & 0x7f;
+ if (frame->next == 0
+ || frame->next->signal_handler_caller
+ || next_frame_is_call_dummy)
+ frame->extra_info->bsp = rse_address_add (bsp, -frame->extra_info->sof);
+ else
+ frame->extra_info->bsp = rse_address_add (bsp, -frame->extra_info->sol);
+
+ frame->extra_info->after_prologue = 0;
+ frame->extra_info->mem_stack_frame_size = -1; /* Not yet determined */
+ frame->extra_info->fp_reg = 0;
+}
+
+static int
+is_float_or_hfa_type_recurse (struct type *t, struct type **etp)
+{
+ switch (TYPE_CODE (t))
+ {
+ case TYPE_CODE_FLT:
+ if (*etp)
+ return TYPE_LENGTH (*etp) == TYPE_LENGTH (t);
+ else
+ {
+ *etp = t;
+ return 1;
+ }
+ break;
+ case TYPE_CODE_ARRAY:
+ return
+ is_float_or_hfa_type_recurse (check_typedef (TYPE_TARGET_TYPE (t)),
+ etp);
+ break;
+ case TYPE_CODE_STRUCT:
+ {
+ int i;
+
+ for (i = 0; i < TYPE_NFIELDS (t); i++)
+ if (!is_float_or_hfa_type_recurse
+ (check_typedef (TYPE_FIELD_TYPE (t, i)), etp))
+ return 0;
+ return 1;
+ }
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+/* Determine if the given type is one of the floating point types or
+ and HFA (which is a struct, array, or combination thereof whose
+ bottom-most elements are all of the same floating point type.) */
+
+static struct type *
+is_float_or_hfa_type (struct type *t)
+{
+ struct type *et = 0;
+
+ return is_float_or_hfa_type_recurse (t, &et) ? et : 0;
+}
+
+
+/* Return 1 if the alignment of T is such that the next even slot
+ should be used. Return 0, if the next available slot should
+ be used. (See section 8.5.1 of the IA-64 Software Conventions
+ and Runtime manual.) */
+
+static int
+slot_alignment_is_next_even (struct type *t)
+{
+ switch (TYPE_CODE (t))
+ {
+ case TYPE_CODE_INT:
+ case TYPE_CODE_FLT:
+ if (TYPE_LENGTH (t) > 8)
+ return 1;
+ else
+ return 0;
+ case TYPE_CODE_ARRAY:
+ return
+ slot_alignment_is_next_even (check_typedef (TYPE_TARGET_TYPE (t)));
+ case TYPE_CODE_STRUCT:
+ {
+ int i;
+
+ for (i = 0; i < TYPE_NFIELDS (t); i++)
+ if (slot_alignment_is_next_even
+ (check_typedef (TYPE_FIELD_TYPE (t, i))))
+ return 1;
+ return 0;
+ }
+ default:
+ return 0;
+ }
+}
+
+/* Attempt to find (and return) the global pointer for the given
+ function.
+
+ This is a rather nasty bit of code searchs for the .dynamic section
+ in the objfile corresponding to the pc of the function we're trying
+ to call. Once it finds the addresses at which the .dynamic section
+ lives in the child process, it scans the Elf64_Dyn entries for a
+ DT_PLTGOT tag. If it finds one of these, the corresponding
+ d_un.d_ptr value is the global pointer. */
+
+static CORE_ADDR
+generic_elf_find_global_pointer (CORE_ADDR faddr)
+{
+ struct obj_section *faddr_sect;
+
+ faddr_sect = find_pc_section (faddr);
+ if (faddr_sect != NULL)
+ {
+ struct obj_section *osect;
+
+ ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
+ {
+ if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0)
+ break;
+ }
+
+ if (osect < faddr_sect->objfile->sections_end)
+ {
+ CORE_ADDR addr;
+
+ addr = osect->addr;
+ while (addr < osect->endaddr)
+ {
+ int status;
+ LONGEST tag;
+ char buf[8];
+
+ status = target_read_memory (addr, buf, sizeof (buf));
+ if (status != 0)
+ break;
+ tag = extract_signed_integer (buf, sizeof (buf));
+
+ if (tag == DT_PLTGOT)
+ {
+ CORE_ADDR global_pointer;
+
+ status = target_read_memory (addr + 8, buf, sizeof (buf));
+ if (status != 0)
+ break;
+ global_pointer = extract_address (buf, sizeof (buf));
+
+ /* The payoff... */
+ return global_pointer;
+ }
+
+ if (tag == DT_NULL)
+ break;
+
+ addr += 16;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Given a function's address, attempt to find (and return) the
+ corresponding (canonical) function descriptor. Return 0 if
+ not found. */
+static CORE_ADDR
+find_extant_func_descr (CORE_ADDR faddr)
+{
+ struct obj_section *faddr_sect;
+
+ /* Return early if faddr is already a function descriptor */
+ faddr_sect = find_pc_section (faddr);
+ if (faddr_sect && strcmp (faddr_sect->the_bfd_section->name, ".opd") == 0)
+ return faddr;
+
+ if (faddr_sect != NULL)
+ {
+ struct obj_section *osect;
+ ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
+ {
+ if (strcmp (osect->the_bfd_section->name, ".opd") == 0)
+ break;
+ }
+
+ if (osect < faddr_sect->objfile->sections_end)
+ {
+ CORE_ADDR addr;
+
+ addr = osect->addr;
+ while (addr < osect->endaddr)
+ {
+ int status;
+ LONGEST faddr2;
+ char buf[8];
+
+ status = target_read_memory (addr, buf, sizeof (buf));
+ if (status != 0)
+ break;
+ faddr2 = extract_signed_integer (buf, sizeof (buf));
+
+ if (faddr == faddr2)
+ return addr;
+
+ addr += 16;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Attempt to find a function descriptor corresponding to the
+ given address. If none is found, construct one on the
+ stack using the address at fdaptr */
+
+static CORE_ADDR
+find_func_descr (CORE_ADDR faddr, CORE_ADDR *fdaptr)
+{
+ CORE_ADDR fdesc;
+
+ fdesc = find_extant_func_descr (faddr);
+
+ if (fdesc == 0)
+ {
+ CORE_ADDR global_pointer;
+ char buf[16];
+
+ fdesc = *fdaptr;
+ *fdaptr += 16;
+
+ global_pointer = FIND_GLOBAL_POINTER (faddr);
+
+ if (global_pointer == 0)
+ global_pointer = read_register (IA64_GR1_REGNUM);
+
+ store_address (buf, 8, faddr);
+ store_address (buf + 8, 8, global_pointer);
+
+ write_memory (fdesc, buf, 16);
+ }
+
+ return fdesc;
+}
+
+CORE_ADDR
+ia64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int argno;
+ struct value *arg;
+ struct type *type;
+ int len, argoffset;
+ int nslots, rseslots, memslots, slotnum, nfuncargs;
+ int floatreg;
+ CORE_ADDR bsp, cfm, pfs, new_bsp, funcdescaddr;
+
+ nslots = 0;
+ nfuncargs = 0;
+ /* Count the number of slots needed for the arguments */
+ for (argno = 0; argno < nargs; argno++)
+ {
+ arg = args[argno];
+ type = check_typedef (VALUE_TYPE (arg));
+ len = TYPE_LENGTH (type);
+
+ if ((nslots & 1) && slot_alignment_is_next_even (type))
+ nslots++;
+
+ if (TYPE_CODE (type) == TYPE_CODE_FUNC)
+ nfuncargs++;
+
+ nslots += (len + 7) / 8;
+ }
+
+ /* Divvy up the slots between the RSE and the memory stack */
+ rseslots = (nslots > 8) ? 8 : nslots;
+ memslots = nslots - rseslots;
+
+ /* Allocate a new RSE frame */
+ cfm = read_register (IA64_CFM_REGNUM);
+
+ bsp = read_register (IA64_BSP_REGNUM);
+ bsp = rse_address_add (bsp, cfm & 0x7f);
+ new_bsp = rse_address_add (bsp, rseslots);
+ write_register (IA64_BSP_REGNUM, new_bsp);
+
+ pfs = read_register (IA64_PFS_REGNUM);
+ pfs &= 0xc000000000000000LL;
+ pfs |= (cfm & 0xffffffffffffLL);
+ write_register (IA64_PFS_REGNUM, pfs);
+
+ cfm &= 0xc000000000000000LL;
+ cfm |= rseslots;
+ write_register (IA64_CFM_REGNUM, cfm);
+
+ /* We will attempt to find function descriptors in the .opd segment,
+ but if we can't we'll construct them ourselves. That being the
+ case, we'll need to reserve space on the stack for them. */
+ funcdescaddr = sp - nfuncargs * 16;
+ funcdescaddr &= ~0xfLL;
+
+ /* Adjust the stack pointer to it's new value. The calling conventions
+ require us to have 16 bytes of scratch, plus whatever space is
+ necessary for the memory slots and our function descriptors */
+ sp = sp - 16 - (memslots + nfuncargs) * 8;
+ sp &= ~0xfLL; /* Maintain 16 byte alignment */
+
+ /* Place the arguments where they belong. The arguments will be
+ either placed in the RSE backing store or on the memory stack.
+ In addition, floating point arguments or HFAs are placed in
+ floating point registers. */
+ slotnum = 0;
+ floatreg = IA64_FR8_REGNUM;
+ for (argno = 0; argno < nargs; argno++)
+ {
+ struct type *float_elt_type;
+
+ arg = args[argno];
+ type = check_typedef (VALUE_TYPE (arg));
+ len = TYPE_LENGTH (type);
+
+ /* Special handling for function parameters */
+ if (len == 8
+ && TYPE_CODE (type) == TYPE_CODE_PTR
+ && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC)
+ {
+ char val_buf[8];
+
+ store_address (val_buf, 8,
+ find_func_descr (extract_address (VALUE_CONTENTS (arg), 8),
+ &funcdescaddr));
+ if (slotnum < rseslots)
+ write_memory (rse_address_add (bsp, slotnum), val_buf, 8);
+ else
+ write_memory (sp + 16 + 8 * (slotnum - rseslots), val_buf, 8);
+ slotnum++;
+ continue;
+ }
+
+ /* Normal slots */
+
+ /* Skip odd slot if necessary... */
+ if ((slotnum & 1) && slot_alignment_is_next_even (type))
+ slotnum++;
+
+ argoffset = 0;
+ while (len > 0)
+ {
+ char val_buf[8];
+
+ memset (val_buf, 0, 8);
+ memcpy (val_buf, VALUE_CONTENTS (arg) + argoffset, (len > 8) ? 8 : len);
+
+ if (slotnum < rseslots)
+ write_memory (rse_address_add (bsp, slotnum), val_buf, 8);
+ else
+ write_memory (sp + 16 + 8 * (slotnum - rseslots), val_buf, 8);
+
+ argoffset += 8;
+ len -= 8;
+ slotnum++;
+ }
+
+ /* Handle floating point types (including HFAs) */
+ float_elt_type = is_float_or_hfa_type (type);
+ if (float_elt_type != NULL)
+ {
+ argoffset = 0;
+ len = TYPE_LENGTH (type);
+ while (len > 0 && floatreg < IA64_FR16_REGNUM)
+ {
+ ia64_register_convert_to_raw (
+ float_elt_type,
+ floatreg,
+ VALUE_CONTENTS (arg) + argoffset,
+ &registers[REGISTER_BYTE (floatreg)]);
+ floatreg++;
+ argoffset += TYPE_LENGTH (float_elt_type);
+ len -= TYPE_LENGTH (float_elt_type);
+ }
+ }
+ }
+
+ /* Store the struct return value in r8 if necessary. */
+ if (struct_return)
+ {
+ store_address (&registers[REGISTER_BYTE (IA64_GR8_REGNUM)],
+ REGISTER_RAW_SIZE (IA64_GR8_REGNUM),
+ struct_addr);
+ }
+
+ /* Sync gdb's idea of what the registers are with the target. */
+ target_store_registers (-1);
+
+ /* FIXME: This doesn't belong here! Instead, SAVE_DUMMY_FRAME_TOS needs
+ to be defined to call generic_save_dummy_frame_tos(). But at the
+ time of this writing, SAVE_DUMMY_FRAME_TOS wasn't gdbarch'd, so
+ I chose to put this call here instead of using the old mechanisms.
+ Once SAVE_DUMMY_FRAME_TOS is gdbarch'd, all we need to do is add the
+ line
+
+ set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
+
+ to ia64_gdbarch_init() and remove the line below. */
+ generic_save_dummy_frame_tos (sp);
+
+ return sp;
+}
+
+CORE_ADDR
+ia64_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ CORE_ADDR global_pointer = FIND_GLOBAL_POINTER (pc);
+
+ if (global_pointer != 0)
+ write_register (IA64_GR1_REGNUM, global_pointer);
+
+ write_register (IA64_BR0_REGNUM, CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+void
+ia64_store_return_value (struct type *type, char *valbuf)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
+ ia64_register_convert_to_raw (type, IA64_FR8_REGNUM, valbuf,
+ &registers[REGISTER_BYTE (IA64_FR8_REGNUM)]);
+ target_store_registers (IA64_FR8_REGNUM);
+ }
+ else
+ write_register_bytes (REGISTER_BYTE (IA64_GR8_REGNUM),
+ valbuf, TYPE_LENGTH (type));
+}
+
+void
+ia64_pop_frame (void)
+{
+ generic_pop_current_frame (ia64_pop_frame_regular);
+}
+
+static void
+ia64_pop_frame_regular (struct frame_info *frame)
+{
+ int regno;
+ CORE_ADDR bsp, cfm, pfs;
+
+ FRAME_INIT_SAVED_REGS (frame);
+
+ for (regno = 0; regno < ia64_num_regs; regno++)
+ {
+ if (frame->saved_regs[regno]
+ && (!(IA64_GR32_REGNUM <= regno && regno <= IA64_GR127_REGNUM))
+ && regno != pc_regnum
+ && regno != sp_regnum
+ && regno != IA64_PFS_REGNUM
+ && regno != IA64_CFM_REGNUM
+ && regno != IA64_BSP_REGNUM
+ && regno != IA64_BSPSTORE_REGNUM)
+ {
+ write_register (regno,
+ read_memory_integer (frame->saved_regs[regno],
+ REGISTER_RAW_SIZE (regno)));
+ }
+ }
+
+ write_register (sp_regnum, FRAME_CHAIN (frame));
+ write_pc (FRAME_SAVED_PC (frame));
+
+ cfm = read_register (IA64_CFM_REGNUM);
+
+ if (frame->saved_regs[IA64_PFS_REGNUM])
+ {
+ pfs = read_memory_integer (frame->saved_regs[IA64_PFS_REGNUM],
+ REGISTER_RAW_SIZE (IA64_PFS_REGNUM));
+ }
+ else
+ pfs = read_register (IA64_PFS_REGNUM);
+
+ /* Compute the new bsp by *adding* the difference between the
+ size of the frame and the size of the locals (both wrt the
+ frame that we're going back to). This seems kind of strange,
+ especially since it seems like we ought to be subtracting the
+ size of the locals... and we should; but the Linux kernel
+ wants bsp to be set at the end of all used registers. It's
+ likely that this code will need to be revised to accomodate
+ other operating systems. */
+ bsp = rse_address_add (frame->extra_info->bsp,
+ (pfs & 0x7f) - ((pfs >> 7) & 0x7f));
+ write_register (IA64_BSP_REGNUM, bsp);
+
+ /* FIXME: What becomes of the epilog count in the PFS? */
+ cfm = (cfm & ~0xffffffffffffLL) | (pfs & 0xffffffffffffLL);
+ write_register (IA64_CFM_REGNUM, cfm);
+
+ flush_cached_frames ();
+}
+
+static void
+ia64_remote_translate_xfer_address (CORE_ADDR memaddr, int nr_bytes,
+ CORE_ADDR *targ_addr, int *targ_len)
+{
+ *targ_addr = memaddr;
+ *targ_len = nr_bytes;
+}
+
+static void
+process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
+{
+ int *os_ident_ptr = obj;
+ const char *name;
+ unsigned int sectsize;
+
+ name = bfd_get_section_name (abfd, sect);
+ sectsize = bfd_section_size (abfd, sect);
+ if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
+ {
+ unsigned int name_length, data_length, note_type;
+ char *note = alloca (sectsize);
+
+ bfd_get_section_contents (abfd, sect, note,
+ (file_ptr) 0, (bfd_size_type) sectsize);
+
+ name_length = bfd_h_get_32 (abfd, note);
+ data_length = bfd_h_get_32 (abfd, note + 4);
+ note_type = bfd_h_get_32 (abfd, note + 8);
+
+ if (name_length == 4 && data_length == 16 && note_type == 1
+ && strcmp (note + 12, "GNU") == 0)
+ {
+ int os_number = bfd_h_get_32 (abfd, note + 16);
+
+ /* The case numbers are from abi-tags in glibc */
+ switch (os_number)
+ {
+ case 0 :
+ *os_ident_ptr = ELFOSABI_LINUX;
+ break;
+ case 1 :
+ *os_ident_ptr = ELFOSABI_HURD;
+ break;
+ case 2 :
+ *os_ident_ptr = ELFOSABI_SOLARIS;
+ break;
+ default :
+ internal_error (__FILE__, __LINE__,
+ "process_note_abi_sections: unknown OS number %d", os_number);
+ break;
+ }
+ }
+ }
+}
+
+static struct gdbarch *
+ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch *gdbarch;
+ struct gdbarch_tdep *tdep;
+ int os_ident;
+
+ if (info.abfd != NULL
+ && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
+ {
+ os_ident = elf_elfheader (info.abfd)->e_ident[EI_OSABI];
+
+ /* If os_ident is 0, it is not necessarily the case that we're
+ on a SYSV system. (ELFOSABI_NONE is defined to be 0.)
+ GNU/Linux uses a note section to record OS/ABI info, but
+ leaves e_ident[EI_OSABI] zero. So we have to check for note
+ sections too. */
+ if (os_ident == 0)
+ {
+ bfd_map_over_sections (info.abfd,
+ process_note_abi_tag_sections,
+ &os_ident);
+ }
+ }
+ else
+ os_ident = -1;
+
+ for (arches = gdbarch_list_lookup_by_info (arches, &info);
+ arches != NULL;
+ arches = gdbarch_list_lookup_by_info (arches->next, &info))
+ {
+ tdep = gdbarch_tdep (arches->gdbarch);
+ if (tdep &&tdep->os_ident == os_ident)
+ return arches->gdbarch;
+ }
+
+ tdep = xmalloc (sizeof (struct gdbarch_tdep));
+ gdbarch = gdbarch_alloc (&info, tdep);
+ tdep->os_ident = os_ident;
+
+
+ /* Set the method of obtaining the sigcontext addresses at which
+ registers are saved. The method of checking to see if
+ native_find_global_pointer is nonzero to indicate that we're
+ on AIX is kind of hokey, but I can't think of a better way
+ to do it. */
+ if (os_ident == ELFOSABI_LINUX)
+ tdep->sigcontext_register_address = ia64_linux_sigcontext_register_address;
+ else if (native_find_global_pointer != 0)
+ tdep->sigcontext_register_address = ia64_aix_sigcontext_register_address;
+ else
+ tdep->sigcontext_register_address = 0;
+
+ /* We know that GNU/Linux won't have to resort to the
+ native_find_global_pointer hackery. But that's the only one we
+ know about so far, so if native_find_global_pointer is set to
+ something non-zero, then use it. Otherwise fall back to using
+ generic_elf_find_global_pointer. This arrangement should (in
+ theory) allow us to cross debug GNU/Linux binaries from an AIX
+ machine. */
+ if (os_ident == ELFOSABI_LINUX)
+ tdep->find_global_pointer = generic_elf_find_global_pointer;
+ else if (native_find_global_pointer != 0)
+ tdep->find_global_pointer = native_find_global_pointer;
+ else
+ tdep->find_global_pointer = generic_elf_find_global_pointer;
+
+ set_gdbarch_short_bit (gdbarch, 16);
+ set_gdbarch_int_bit (gdbarch, 32);
+ set_gdbarch_long_bit (gdbarch, 64);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+ set_gdbarch_float_bit (gdbarch, 32);
+ set_gdbarch_double_bit (gdbarch, 64);
+ set_gdbarch_long_double_bit (gdbarch, 64);
+ set_gdbarch_ptr_bit (gdbarch, 64);
+
+ set_gdbarch_num_regs (gdbarch, ia64_num_regs);
+ set_gdbarch_sp_regnum (gdbarch, sp_regnum);
+ set_gdbarch_fp_regnum (gdbarch, fp_regnum);
+ set_gdbarch_pc_regnum (gdbarch, pc_regnum);
+ set_gdbarch_fp0_regnum (gdbarch, IA64_FR0_REGNUM);
+
+ set_gdbarch_register_name (gdbarch, ia64_register_name);
+ set_gdbarch_register_size (gdbarch, 8);
+ set_gdbarch_register_bytes (gdbarch, ia64_num_regs * 8 + 128*8);
+ set_gdbarch_register_byte (gdbarch, ia64_register_byte);
+ set_gdbarch_register_raw_size (gdbarch, ia64_register_raw_size);
+ set_gdbarch_max_register_raw_size (gdbarch, 16);
+ set_gdbarch_register_virtual_size (gdbarch, ia64_register_virtual_size);
+ set_gdbarch_max_register_virtual_size (gdbarch, 16);
+ set_gdbarch_register_virtual_type (gdbarch, ia64_register_virtual_type);
+
+ set_gdbarch_skip_prologue (gdbarch, ia64_skip_prologue);
+
+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+ set_gdbarch_frameless_function_invocation (gdbarch, ia64_frameless_function_invocation);
+
+ set_gdbarch_saved_pc_after_call (gdbarch, ia64_saved_pc_after_call);
+
+ set_gdbarch_frame_chain (gdbarch, ia64_frame_chain);
+ set_gdbarch_frame_chain_valid (gdbarch, generic_func_frame_chain_valid);
+ set_gdbarch_frame_saved_pc (gdbarch, ia64_frame_saved_pc);
+
+ set_gdbarch_frame_init_saved_regs (gdbarch, ia64_frame_init_saved_regs);
+ set_gdbarch_get_saved_register (gdbarch, ia64_get_saved_register);
+
+ set_gdbarch_register_convertible (gdbarch, ia64_register_convertible);
+ set_gdbarch_register_convert_to_virtual (gdbarch, ia64_register_convert_to_virtual);
+ set_gdbarch_register_convert_to_raw (gdbarch, ia64_register_convert_to_raw);
+
+ set_gdbarch_use_struct_convention (gdbarch, ia64_use_struct_convention);
+ set_gdbarch_extract_return_value (gdbarch, ia64_extract_return_value);
+
+ set_gdbarch_store_struct_return (gdbarch, ia64_store_struct_return);
+ set_gdbarch_store_return_value (gdbarch, ia64_store_return_value);
+ set_gdbarch_extract_struct_value_address (gdbarch, ia64_extract_struct_value_address);
+
+ set_gdbarch_memory_insert_breakpoint (gdbarch, ia64_memory_insert_breakpoint);
+ set_gdbarch_memory_remove_breakpoint (gdbarch, ia64_memory_remove_breakpoint);
+ set_gdbarch_breakpoint_from_pc (gdbarch, ia64_breakpoint_from_pc);
+ set_gdbarch_read_pc (gdbarch, ia64_read_pc);
+ set_gdbarch_write_pc (gdbarch, ia64_write_pc);
+
+ /* Settings for calling functions in the inferior. */
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_push_arguments (gdbarch, ia64_push_arguments);
+ set_gdbarch_push_return_address (gdbarch, ia64_push_return_address);
+ set_gdbarch_pop_frame (gdbarch, ia64_pop_frame);
+
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_words (gdbarch, ia64_call_dummy_words);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (ia64_call_dummy_words));
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_init_extra_frame_info (gdbarch, ia64_init_extra_frame_info);
+ set_gdbarch_frame_args_address (gdbarch, ia64_frame_args_address);
+ set_gdbarch_frame_locals_address (gdbarch, ia64_frame_locals_address);
+
+ /* We won't necessarily have a frame pointer and even if we do,
+ it winds up being extraordinarly messy when attempting to find
+ the frame chain. So for the purposes of creating frames (which
+ is all read_fp() is used for), simply use the stack pointer value
+ instead. */
+ set_gdbarch_read_fp (gdbarch, generic_target_read_sp);
+
+ /* Settings that should be unnecessary. */
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+
+ set_gdbarch_read_sp (gdbarch, generic_target_read_sp);
+ set_gdbarch_write_sp (gdbarch, generic_target_write_sp);
+
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+ set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
+
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+ set_gdbarch_function_start_offset (gdbarch, 0);
+ set_gdbarch_frame_args_skip (gdbarch, 0);
+
+ set_gdbarch_remote_translate_xfer_address (
+ gdbarch, ia64_remote_translate_xfer_address);
+
+ return gdbarch;
+}
+
+void
+_initialize_ia64_tdep (void)
+{
+ register_gdbarch_init (bfd_arch_ia64, ia64_gdbarch_init);
+
+ tm_print_insn = print_insn_ia64;
+ tm_print_insn_info.bytes_per_line = SLOT_MULTIPLIER;
+}
diff --git a/gdb/inf-loop.c b/gdb/inf-loop.c
new file mode 100644
index 00000000000..ed60cc32301
--- /dev/null
+++ b/gdb/inf-loop.c
@@ -0,0 +1,132 @@
+/* Handling of inferior events for the event loop for GDB, the GNU debugger.
+ Copyright 1999 Free Software Foundation, Inc.
+ Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
+
+ 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 "defs.h"
+#include "inferior.h" /* For fetch_inferior_event. */
+#include "target.h" /* For enum inferior_event_type. */
+#include "event-loop.h"
+#include "event-top.h"
+#include "inf-loop.h"
+#include "remote.h"
+
+static int fetch_inferior_event_wrapper (gdb_client_data client_data);
+static void complete_execution (void);
+
+void
+inferior_event_handler_wrapper (gdb_client_data client_data)
+{
+ inferior_event_handler (INF_QUIT_REQ, client_data);
+}
+
+/* General function to handle events in the inferior. So far it just
+ takes care of detecting errors reported by select() or poll(),
+ otherwise it assumes that all is OK, and goes on reading data from
+ the fd. This however may not always be what we want to do. */
+void
+inferior_event_handler (enum inferior_event_type event_type,
+ gdb_client_data client_data)
+{
+ switch (event_type)
+ {
+ case INF_ERROR:
+ printf_unfiltered ("error detected from target.\n");
+ target_async (NULL, 0);
+ pop_target ();
+ discard_all_continuations ();
+ do_exec_error_cleanups (ALL_CLEANUPS);
+ break;
+
+ case INF_REG_EVENT:
+ /* Use catch errors for now, until the inner layers of
+ fetch_inferior_event (i.e. readchar) can return meaningful
+ error status. If an error occurs while getting an event from
+ the target, just get rid of the target. */
+ if (!catch_errors (fetch_inferior_event_wrapper,
+ client_data, "", RETURN_MASK_ALL))
+ {
+ target_async (NULL, 0);
+ pop_target ();
+ discard_all_continuations ();
+ do_exec_error_cleanups (ALL_CLEANUPS);
+ display_gdb_prompt (0);
+ }
+ break;
+
+ case INF_EXEC_COMPLETE:
+ /* Is there anything left to do for the command issued to
+ complete? */
+ do_all_continuations ();
+ /* Reset things after target has stopped for the async commands. */
+ complete_execution ();
+ break;
+
+ case INF_EXEC_CONTINUE:
+ /* Is there anything left to do for the command issued to
+ complete? */
+ do_all_intermediate_continuations ();
+ break;
+
+ case INF_QUIT_REQ:
+ /* FIXME: ezannoni 1999-10-04. This call should really be a
+ target vector entry, so that it can be used for any kind of
+ targets. */
+ async_remote_interrupt_twice (NULL);
+ break;
+
+ case INF_TIMER:
+ default:
+ printf_unfiltered ("Event type not recognized.\n");
+ break;
+ }
+}
+
+static int
+fetch_inferior_event_wrapper (gdb_client_data client_data)
+{
+ fetch_inferior_event (client_data);
+ return 1;
+}
+
+/* Reset proper settings after an asynchronous command has finished.
+ If the execution command was in synchronous mode, register stdin
+ with the event loop, and reset the prompt. */
+
+static void
+complete_execution (void)
+{
+ target_executing = 0;
+
+ /* Unregister the inferior from the event loop. This is done so that
+ when the inferior is not running we don't get distracted by
+ spurious inferior output. */
+ target_async (NULL, 0);
+
+ if (sync_execution)
+ {
+ do_exec_error_cleanups (ALL_CLEANUPS);
+ display_gdb_prompt (0);
+ }
+ else
+ {
+ if (exec_done_display_p)
+ printf_unfiltered ("completed.\n");
+ }
+}
diff --git a/gdb/inf-loop.h b/gdb/inf-loop.h
new file mode 100644
index 00000000000..9f1713cf052
--- /dev/null
+++ b/gdb/inf-loop.h
@@ -0,0 +1,29 @@
+/* Interface to the inferior event handling code for GDB, the GNU debugger.
+ Copyright 1999 Free Software Foundation, Inc.
+ Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
+
+ 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. */
+
+#ifndef INF_LOOP_H
+#define INF_LOOP_H
+
+extern void inferior_event_handler (enum inferior_event_type event_type,
+ void* client_data);
+extern void inferior_event_handler_wrapper (void *client_data);
+
+#endif /* #ifndef INF_LOOP_H */
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
new file mode 100644
index 00000000000..400ac552d2d
--- /dev/null
+++ b/gdb/infcmd.c
@@ -0,0 +1,2047 @@
+/* Memory-access and commands for "inferior" process, for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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 "defs.h"
+#include <signal.h>
+#include "gdb_string.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "frame.h"
+#include "inferior.h"
+#include "environ.h"
+#include "value.h"
+#include "gdbcmd.h"
+#include "symfile.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "language.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "completer.h"
+#include "ui-out.h"
+#include "event-top.h"
+#include "parser-defs.h"
+
+/* Functions exported for general use: */
+
+void nofp_registers_info (char *, int);
+
+void all_registers_info (char *, int);
+
+void registers_info (char *, int);
+
+/* Local functions: */
+
+void continue_command (char *, int);
+
+static void print_return_value (int struct_return, struct type *value_type);
+
+static void finish_command_continuation (struct continuation_arg *);
+
+static void until_next_command (int);
+
+static void until_command (char *, int);
+
+static void path_info (char *, int);
+
+static void path_command (char *, int);
+
+static void unset_command (char *, int);
+
+static void float_info (char *, int);
+
+static void detach_command (char *, int);
+
+static void interrupt_target_command (char *args, int from_tty);
+
+static void unset_environment_command (char *, int);
+
+static void set_environment_command (char *, int);
+
+static void environment_info (char *, int);
+
+static void program_info (char *, int);
+
+static void finish_command (char *, int);
+
+static void signal_command (char *, int);
+
+static void jump_command (char *, int);
+
+static void step_1 (int, int, char *);
+static void step_once (int skip_subroutines, int single_inst, int count);
+static void step_1_continuation (struct continuation_arg *arg);
+
+void nexti_command (char *, int);
+
+void stepi_command (char *, int);
+
+static void next_command (char *, int);
+
+static void step_command (char *, int);
+
+static void run_command (char *, int);
+
+static void run_no_args_command (char *args, int from_tty);
+
+static void go_command (char *line_no, int from_tty);
+
+static int strip_bg_char (char **);
+
+void _initialize_infcmd (void);
+
+#define GO_USAGE "Usage: go <location>\n"
+
+static void breakpoint_auto_delete_contents (PTR);
+
+#define ERROR_NO_INFERIOR \
+ if (!target_has_execution) error ("The program is not being run.");
+
+/* String containing arguments to give to the program, separated by spaces.
+ Empty string (pointer to '\0') means no args. */
+
+static char *inferior_args;
+
+/* The inferior arguments as a vector. If INFERIOR_ARGC is nonzero,
+ then we must compute INFERIOR_ARGS from this (via the target). */
+
+static int inferior_argc;
+static char **inferior_argv;
+
+/* File name for default use for standard in/out in the inferior. */
+
+char *inferior_io_terminal;
+
+/* Pid of our debugged inferior, or 0 if no inferior now.
+ Since various parts of infrun.c test this to see whether there is a program
+ being debugged it should be nonzero (currently 3 is used) for remote
+ debugging. */
+
+ptid_t inferior_ptid;
+
+/* Last signal that the inferior received (why it stopped). */
+
+enum target_signal stop_signal;
+
+/* Address at which inferior stopped. */
+
+CORE_ADDR stop_pc;
+
+/* Chain containing status of breakpoint(s) that we have stopped at. */
+
+bpstat stop_bpstat;
+
+/* Flag indicating that a command has proceeded the inferior past the
+ current breakpoint. */
+
+int breakpoint_proceeded;
+
+/* Nonzero if stopped due to a step command. */
+
+int stop_step;
+
+/* Nonzero if stopped due to completion of a stack dummy routine. */
+
+int stop_stack_dummy;
+
+/* Nonzero if stopped due to a random (unexpected) signal in inferior
+ process. */
+
+int stopped_by_random_signal;
+
+/* Range to single step within.
+ If this is nonzero, respond to a single-step signal
+ by continuing to step if the pc is in this range. */
+
+CORE_ADDR step_range_start; /* Inclusive */
+CORE_ADDR step_range_end; /* Exclusive */
+
+/* Stack frame address as of when stepping command was issued.
+ This is how we know when we step into a subroutine call,
+ and how to set the frame for the breakpoint used to step out. */
+
+CORE_ADDR step_frame_address;
+
+/* Our notion of the current stack pointer. */
+
+CORE_ADDR step_sp;
+
+enum step_over_calls_kind step_over_calls;
+
+/* If stepping, nonzero means step count is > 1
+ so don't print frame next time inferior stops
+ if it stops due to stepping. */
+
+int step_multi;
+
+/* Environment to use for running inferior,
+ in format described in environ.h. */
+
+struct environ *inferior_environ;
+
+/* Accessor routines. */
+
+char *
+get_inferior_args (void)
+{
+ if (inferior_argc != 0)
+ {
+ char *n, *old;
+
+ n = gdbarch_construct_inferior_arguments (current_gdbarch,
+ inferior_argc, inferior_argv);
+ old = set_inferior_args (n);
+ xfree (old);
+ }
+
+ if (inferior_args == NULL)
+ inferior_args = xstrdup ("");
+
+ return inferior_args;
+}
+
+char *
+set_inferior_args (char *newargs)
+{
+ char *saved_args = inferior_args;
+
+ inferior_args = newargs;
+ inferior_argc = 0;
+ inferior_argv = 0;
+
+ return saved_args;
+}
+
+void
+set_inferior_args_vector (int argc, char **argv)
+{
+ inferior_argc = argc;
+ inferior_argv = argv;
+}
+
+/* Notice when `set args' is run. */
+static void
+notice_args_set (char *args, int from_tty, struct cmd_list_element *c)
+{
+ inferior_argc = 0;
+ inferior_argv = 0;
+}
+
+/* Notice when `show args' is run. */
+static void
+notice_args_read (char *args, int from_tty, struct cmd_list_element *c)
+{
+ /* Might compute the value. */
+ get_inferior_args ();
+}
+
+
+/* Compute command-line string given argument vector. This does the
+ same shell processing as fork_inferior. */
+/* ARGSUSED */
+char *
+construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv)
+{
+ char *result;
+
+ if (STARTUP_WITH_SHELL)
+ {
+ /* This holds all the characters considered special to the
+ typical Unix shells. We include `^' because the SunOS
+ /bin/sh treats it as a synonym for `|'. */
+ char *special = "\"!#$&*()\\|[]{}<>?'\"`~^; \t\n";
+ int i;
+ int length = 0;
+ char *out, *cp;
+
+ /* We over-compute the size. It shouldn't matter. */
+ for (i = 0; i < argc; ++i)
+ length += 2 * strlen (argv[i]) + 1;
+
+ result = (char *) xmalloc (length);
+ out = result;
+
+ for (i = 0; i < argc; ++i)
+ {
+ if (i > 0)
+ *out++ = ' ';
+
+ for (cp = argv[i]; *cp; ++cp)
+ {
+ if (strchr (special, *cp) != NULL)
+ *out++ = '\\';
+ *out++ = *cp;
+ }
+ }
+ *out = '\0';
+ }
+ else
+ {
+ /* In this case we can't handle arguments that contain spaces,
+ tabs, or newlines -- see breakup_args(). */
+ int i;
+ int length = 0;
+
+ for (i = 0; i < argc; ++i)
+ {
+ char *cp = strchr (argv[i], ' ');
+ if (cp == NULL)
+ cp = strchr (argv[i], '\t');
+ if (cp == NULL)
+ cp = strchr (argv[i], '\n');
+ if (cp != NULL)
+ error ("can't handle command-line argument containing whitespace");
+ length += strlen (argv[i]) + 1;
+ }
+
+ result = (char *) xmalloc (length);
+ result[0] = '\0';
+ for (i = 0; i < argc; ++i)
+ {
+ if (i > 0)
+ strcat (result, " ");
+ strcat (result, argv[i]);
+ }
+ }
+
+ return result;
+}
+
+
+/* This function detects whether or not a '&' character (indicating
+ background execution) has been added as *the last* of the arguments ARGS
+ of a command. If it has, it removes it and returns 1. Otherwise it
+ does nothing and returns 0. */
+static int
+strip_bg_char (char **args)
+{
+ char *p = NULL;
+
+ p = strchr (*args, '&');
+
+ if (p)
+ {
+ if (p == (*args + strlen (*args) - 1))
+ {
+ if (strlen (*args) > 1)
+ {
+ do
+ p--;
+ while (*p == ' ' || *p == '\t');
+ *(p + 1) = '\0';
+ }
+ else
+ *args = 0;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* ARGSUSED */
+void
+tty_command (char *file, int from_tty)
+{
+ if (file == 0)
+ error_no_arg ("terminal name for running target process");
+
+ inferior_io_terminal = savestring (file, strlen (file));
+}
+
+static void
+run_command (char *args, int from_tty)
+{
+ char *exec_file;
+
+ dont_repeat ();
+
+ if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution)
+ {
+ if (from_tty
+ && !query ("The program being debugged has been started already.\n\
+Start it from the beginning? "))
+ error ("Program not restarted.");
+ target_kill ();
+#if defined(SOLIB_RESTART)
+ SOLIB_RESTART ();
+#endif
+ init_wait_for_inferior ();
+ }
+
+ clear_breakpoint_hit_counts ();
+
+ /* Purge old solib objfiles. */
+ objfile_purge_solibs ();
+
+ do_run_cleanups (NULL);
+
+ /* The comment here used to read, "The exec file is re-read every
+ time we do a generic_mourn_inferior, so we just have to worry
+ about the symbol file." The `generic_mourn_inferior' function
+ gets called whenever the program exits. However, suppose the
+ program exits, and *then* the executable file changes? We need
+ to check again here. Since reopen_exec_file doesn't do anything
+ if the timestamp hasn't changed, I don't see the harm. */
+ reopen_exec_file ();
+ reread_symbols ();
+
+ exec_file = (char *) get_exec_file (0);
+
+ /* We keep symbols from add-symbol-file, on the grounds that the
+ user might want to add some symbols before running the program
+ (right?). But sometimes (dynamic loading where the user manually
+ introduces the new symbols with add-symbol-file), the code which
+ the symbols describe does not persist between runs. Currently
+ the user has to manually nuke all symbols between runs if they
+ want them to go away (PR 2207). This is probably reasonable. */
+
+ if (!args)
+ {
+ if (event_loop_p && target_can_async_p ())
+ async_disable_stdin ();
+ }
+ else
+ {
+ int async_exec = strip_bg_char (&args);
+
+ /* If we get a request for running in the bg but the target
+ doesn't support it, error out. */
+ if (event_loop_p && async_exec && !target_can_async_p ())
+ error ("Asynchronous execution not supported on this target.");
+
+ /* If we don't get a request of running in the bg, then we need
+ to simulate synchronous (fg) execution. */
+ if (event_loop_p && !async_exec && target_can_async_p ())
+ {
+ /* Simulate synchronous execution */
+ async_disable_stdin ();
+ }
+
+ /* If there were other args, beside '&', process them. */
+ if (args)
+ {
+ char *old_args = set_inferior_args (xstrdup (args));
+ xfree (old_args);
+ }
+ }
+
+ if (from_tty)
+ {
+ ui_out_field_string (uiout, NULL, "Starting program");
+ ui_out_text (uiout, ": ");
+ if (exec_file)
+ ui_out_field_string (uiout, "execfile", exec_file);
+ ui_out_spaces (uiout, 1);
+ /* We call get_inferior_args() because we might need to compute
+ the value now. */
+ ui_out_field_string (uiout, "infargs", get_inferior_args ());
+ ui_out_text (uiout, "\n");
+ ui_out_flush (uiout);
+ }
+
+ /* We call get_inferior_args() because we might need to compute
+ the value now. */
+ target_create_inferior (exec_file, get_inferior_args (),
+ environ_vector (inferior_environ));
+}
+
+
+static void
+run_no_args_command (char *args, int from_tty)
+{
+ char *old_args = set_inferior_args (xstrdup (""));
+ xfree (old_args);
+}
+
+
+void
+continue_command (char *proc_count_exp, int from_tty)
+{
+ int async_exec = 0;
+ ERROR_NO_INFERIOR;
+
+ /* Find out whether we must run in the background. */
+ if (proc_count_exp != NULL)
+ async_exec = strip_bg_char (&proc_count_exp);
+
+ /* If we must run in the background, but the target can't do it,
+ error out. */
+ if (event_loop_p && async_exec && !target_can_async_p ())
+ error ("Asynchronous execution not supported on this target.");
+
+ /* If we are not asked to run in the bg, then prepare to run in the
+ foreground, synchronously. */
+ if (event_loop_p && !async_exec && target_can_async_p ())
+ {
+ /* Simulate synchronous execution */
+ async_disable_stdin ();
+ }
+
+ /* If have argument (besides '&'), set proceed count of breakpoint
+ we stopped at. */
+ if (proc_count_exp != NULL)
+ {
+ bpstat bs = stop_bpstat;
+ int num = bpstat_num (&bs);
+ if (num == 0 && from_tty)
+ {
+ printf_filtered
+ ("Not stopped at any breakpoint; argument ignored.\n");
+ }
+ while (num != 0)
+ {
+ set_ignore_count (num,
+ parse_and_eval_long (proc_count_exp) - 1,
+ from_tty);
+ /* set_ignore_count prints a message ending with a period.
+ So print two spaces before "Continuing.". */
+ if (from_tty)
+ printf_filtered (" ");
+ num = bpstat_num (&bs);
+ }
+ }
+
+ if (from_tty)
+ printf_filtered ("Continuing.\n");
+
+ clear_proceed_status ();
+
+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+}
+
+/* Step until outside of current statement. */
+
+/* ARGSUSED */
+static void
+step_command (char *count_string, int from_tty)
+{
+ step_1 (0, 0, count_string);
+}
+
+/* Likewise, but skip over subroutine calls as if single instructions. */
+
+/* ARGSUSED */
+static void
+next_command (char *count_string, int from_tty)
+{
+ step_1 (1, 0, count_string);
+}
+
+/* Likewise, but step only one instruction. */
+
+/* ARGSUSED */
+void
+stepi_command (char *count_string, int from_tty)
+{
+ step_1 (0, 1, count_string);
+}
+
+/* ARGSUSED */
+void
+nexti_command (char *count_string, int from_tty)
+{
+ step_1 (1, 1, count_string);
+}
+
+static void
+disable_longjmp_breakpoint_cleanup (void *ignore)
+{
+ disable_longjmp_breakpoint ();
+}
+
+static void
+step_1 (int skip_subroutines, int single_inst, char *count_string)
+{
+ register int count = 1;
+ struct frame_info *frame;
+ struct cleanup *cleanups = 0;
+ int async_exec = 0;
+
+ ERROR_NO_INFERIOR;
+
+ if (count_string)
+ async_exec = strip_bg_char (&count_string);
+
+ /* If we get a request for running in the bg but the target
+ doesn't support it, error out. */
+ if (event_loop_p && async_exec && !target_can_async_p ())
+ error ("Asynchronous execution not supported on this target.");
+
+ /* If we don't get a request of running in the bg, then we need
+ to simulate synchronous (fg) execution. */
+ if (event_loop_p && !async_exec && target_can_async_p ())
+ {
+ /* Simulate synchronous execution */
+ async_disable_stdin ();
+ }
+
+ count = count_string ? parse_and_eval_long (count_string) : 1;
+
+ if (!single_inst || skip_subroutines) /* leave si command alone */
+ {
+ enable_longjmp_breakpoint ();
+ if (!event_loop_p || !target_can_async_p ())
+ cleanups = make_cleanup (disable_longjmp_breakpoint_cleanup, 0 /*ignore*/);
+ else
+ make_exec_cleanup (disable_longjmp_breakpoint_cleanup, 0 /*ignore*/);
+ }
+
+ /* In synchronous case, all is well, just use the regular for loop. */
+ if (!event_loop_p || !target_can_async_p ())
+ {
+ for (; count > 0; count--)
+ {
+ clear_proceed_status ();
+
+ frame = get_current_frame ();
+ if (!frame) /* Avoid coredump here. Why tho? */
+ error ("No current frame");
+ step_frame_address = FRAME_FP (frame);
+ step_sp = read_sp ();
+
+ if (!single_inst)
+ {
+ find_pc_line_pc_range (stop_pc, &step_range_start, &step_range_end);
+ if (step_range_end == 0)
+ {
+ char *name;
+ if (find_pc_partial_function (stop_pc, &name, &step_range_start,
+ &step_range_end) == 0)
+ error ("Cannot find bounds of current function");
+
+ target_terminal_ours ();
+ printf_filtered ("\
+Single stepping until exit from function %s, \n\
+which has no line number information.\n", name);
+ }
+ }
+ else
+ {
+ /* Say we are stepping, but stop after one insn whatever it does. */
+ step_range_start = step_range_end = 1;
+ if (!skip_subroutines)
+ /* It is stepi.
+ Don't step over function calls, not even to functions lacking
+ line numbers. */
+ step_over_calls = STEP_OVER_NONE;
+ }
+
+ if (skip_subroutines)
+ step_over_calls = STEP_OVER_ALL;
+
+ step_multi = (count > 1);
+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
+
+ if (!stop_step)
+ break;
+
+ /* FIXME: On nexti, this may have already been done (when we hit the
+ step resume break, I think). Probably this should be moved to
+ wait_for_inferior (near the top). */
+#if defined (SHIFT_INST_REGS)
+ SHIFT_INST_REGS ();
+#endif
+ }
+
+ if (!single_inst || skip_subroutines)
+ do_cleanups (cleanups);
+ return;
+ }
+ /* In case of asynchronous target things get complicated, do only
+ one step for now, before returning control to the event loop. Let
+ the continuation figure out how many other steps we need to do,
+ and handle them one at the time, through step_once(). */
+ else
+ {
+ if (event_loop_p && target_can_async_p ())
+ step_once (skip_subroutines, single_inst, count);
+ }
+}
+
+/* Called after we are done with one step operation, to check whether
+ we need to step again, before we print the prompt and return control
+ to the user. If count is > 1, we will need to do one more call to
+ proceed(), via step_once(). Basically it is like step_once and
+ step_1_continuation are co-recursive. */
+static void
+step_1_continuation (struct continuation_arg *arg)
+{
+ int count;
+ int skip_subroutines;
+ int single_inst;
+
+ skip_subroutines = arg->data.integer;
+ single_inst = arg->next->data.integer;
+ count = arg->next->next->data.integer;
+
+ if (stop_step)
+ {
+ /* FIXME: On nexti, this may have already been done (when we hit the
+ step resume break, I think). Probably this should be moved to
+ wait_for_inferior (near the top). */
+#if defined (SHIFT_INST_REGS)
+ SHIFT_INST_REGS ();
+#endif
+ step_once (skip_subroutines, single_inst, count - 1);
+ }
+ else
+ if (!single_inst || skip_subroutines)
+ do_exec_cleanups (ALL_CLEANUPS);
+}
+
+/* Do just one step operation. If count >1 we will have to set up a
+ continuation to be done after the target stops (after this one
+ step). This is useful to implement the 'step n' kind of commands, in
+ case of asynchronous targets. We had to split step_1 into two parts,
+ one to be done before proceed() and one afterwards. This function is
+ called in case of step n with n>1, after the first step operation has
+ been completed.*/
+static void
+step_once (int skip_subroutines, int single_inst, int count)
+{
+ struct continuation_arg *arg1;
+ struct continuation_arg *arg2;
+ struct continuation_arg *arg3;
+ struct frame_info *frame;
+
+ if (count > 0)
+ {
+ clear_proceed_status ();
+
+ frame = get_current_frame ();
+ if (!frame) /* Avoid coredump here. Why tho? */
+ error ("No current frame");
+ step_frame_address = FRAME_FP (frame);
+ step_sp = read_sp ();
+
+ if (!single_inst)
+ {
+ find_pc_line_pc_range (stop_pc, &step_range_start, &step_range_end);
+
+ /* If we have no line info, switch to stepi mode. */
+ if (step_range_end == 0 && step_stop_if_no_debug)
+ {
+ step_range_start = step_range_end = 1;
+ }
+ else if (step_range_end == 0)
+ {
+ char *name;
+ if (find_pc_partial_function (stop_pc, &name, &step_range_start,
+ &step_range_end) == 0)
+ error ("Cannot find bounds of current function");
+
+ target_terminal_ours ();
+ printf_filtered ("\
+Single stepping until exit from function %s, \n\
+which has no line number information.\n", name);
+ }
+ }
+ else
+ {
+ /* Say we are stepping, but stop after one insn whatever it does. */
+ step_range_start = step_range_end = 1;
+ if (!skip_subroutines)
+ /* It is stepi.
+ Don't step over function calls, not even to functions lacking
+ line numbers. */
+ step_over_calls = STEP_OVER_NONE;
+ }
+
+ if (skip_subroutines)
+ step_over_calls = STEP_OVER_ALL;
+
+ step_multi = (count > 1);
+ arg1 =
+ (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+ arg2 =
+ (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+ arg3 =
+ (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+ arg1->next = arg2;
+ arg1->data.integer = skip_subroutines;
+ arg2->next = arg3;
+ arg2->data.integer = single_inst;
+ arg3->next = NULL;
+ arg3->data.integer = count;
+ add_intermediate_continuation (step_1_continuation, arg1);
+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
+ }
+}
+
+
+/* Continue program at specified address. */
+
+static void
+jump_command (char *arg, int from_tty)
+{
+ register CORE_ADDR addr;
+ struct symtabs_and_lines sals;
+ struct symtab_and_line sal;
+ struct symbol *fn;
+ struct symbol *sfn;
+ int async_exec = 0;
+
+ ERROR_NO_INFERIOR;
+
+ /* Find out whether we must run in the background. */
+ if (arg != NULL)
+ async_exec = strip_bg_char (&arg);
+
+ /* If we must run in the background, but the target can't do it,
+ error out. */
+ if (event_loop_p && async_exec && !target_can_async_p ())
+ error ("Asynchronous execution not supported on this target.");
+
+ /* If we are not asked to run in the bg, then prepare to run in the
+ foreground, synchronously. */
+ if (event_loop_p && !async_exec && target_can_async_p ())
+ {
+ /* Simulate synchronous execution */
+ async_disable_stdin ();
+ }
+
+ if (!arg)
+ error_no_arg ("starting address");
+
+ sals = decode_line_spec_1 (arg, 1);
+ if (sals.nelts != 1)
+ {
+ error ("Unreasonable jump request");
+ }
+
+ sal = sals.sals[0];
+ xfree (sals.sals);
+
+ if (sal.symtab == 0 && sal.pc == 0)
+ error ("No source file has been specified.");
+
+ resolve_sal_pc (&sal); /* May error out */
+
+ /* See if we are trying to jump to another function. */
+ fn = get_frame_function (get_current_frame ());
+ sfn = find_pc_function (sal.pc);
+ if (fn != NULL && sfn != fn)
+ {
+ if (!query ("Line %d is not in `%s'. Jump anyway? ", sal.line,
+ SYMBOL_SOURCE_NAME (fn)))
+ {
+ error ("Not confirmed.");
+ /* NOTREACHED */
+ }
+ }
+
+ if (sfn != NULL)
+ {
+ fixup_symbol_section (sfn, 0);
+ if (section_is_overlay (SYMBOL_BFD_SECTION (sfn)) &&
+ !section_is_mapped (SYMBOL_BFD_SECTION (sfn)))
+ {
+ if (!query ("WARNING!!! Destination is in unmapped overlay! Jump anyway? "))
+ {
+ error ("Not confirmed.");
+ /* NOTREACHED */
+ }
+ }
+ }
+
+ addr = sal.pc;
+
+ if (from_tty)
+ {
+ printf_filtered ("Continuing at ");
+ print_address_numeric (addr, 1, gdb_stdout);
+ printf_filtered (".\n");
+ }
+
+ clear_proceed_status ();
+ proceed (addr, TARGET_SIGNAL_0, 0);
+}
+
+
+/* Go to line or address in current procedure */
+static void
+go_command (char *line_no, int from_tty)
+{
+ if (line_no == (char *) NULL || !*line_no)
+ printf_filtered (GO_USAGE);
+ else
+ {
+ tbreak_command (line_no, from_tty);
+ jump_command (line_no, from_tty);
+ }
+}
+
+
+/* Continue program giving it specified signal. */
+
+static void
+signal_command (char *signum_exp, int from_tty)
+{
+ enum target_signal oursig;
+
+ dont_repeat (); /* Too dangerous. */
+ ERROR_NO_INFERIOR;
+
+ if (!signum_exp)
+ error_no_arg ("signal number");
+
+ /* It would be even slicker to make signal names be valid expressions,
+ (the type could be "enum $signal" or some such), then the user could
+ assign them to convenience variables. */
+ oursig = target_signal_from_name (signum_exp);
+
+ if (oursig == TARGET_SIGNAL_UNKNOWN)
+ {
+ /* No, try numeric. */
+ int num = parse_and_eval_long (signum_exp);
+
+ if (num == 0)
+ oursig = TARGET_SIGNAL_0;
+ else
+ oursig = target_signal_from_command (num);
+ }
+
+ if (from_tty)
+ {
+ if (oursig == TARGET_SIGNAL_0)
+ printf_filtered ("Continuing with no signal.\n");
+ else
+ printf_filtered ("Continuing with signal %s.\n",
+ target_signal_to_name (oursig));
+ }
+
+ clear_proceed_status ();
+ /* "signal 0" should not get stuck if we are stopped at a breakpoint.
+ FIXME: Neither should "signal foo" but when I tried passing
+ (CORE_ADDR)-1 unconditionally I got a testsuite failure which I haven't
+ tried to track down yet. */
+ proceed (oursig == TARGET_SIGNAL_0 ? (CORE_ADDR) -1 : stop_pc, oursig, 0);
+}
+
+/* Call breakpoint_auto_delete on the current contents of the bpstat
+ pointed to by arg (which is really a bpstat *). */
+
+static void
+breakpoint_auto_delete_contents (PTR arg)
+{
+ breakpoint_auto_delete (*(bpstat *) arg);
+}
+
+
+/* Execute a "stack dummy", a piece of code stored in the stack
+ by the debugger to be executed in the inferior.
+
+ To call: first, do PUSH_DUMMY_FRAME.
+ Then push the contents of the dummy. It should end with a breakpoint insn.
+ Then call here, passing address at which to start the dummy.
+
+ The contents of all registers are saved before the dummy frame is popped
+ and copied into the buffer BUFFER.
+
+ The dummy's frame is automatically popped whenever that break is hit.
+ If that is the first time the program stops, run_stack_dummy
+ returns to its caller with that frame already gone and returns 0.
+
+ Otherwise, run_stack-dummy returns a non-zero value.
+ If the called function receives a random signal, we do not allow the user
+ to continue executing it as this may not work. The dummy frame is poped
+ and we return 1.
+ If we hit a breakpoint, we leave the frame in place and return 2 (the frame
+ will eventually be popped when we do hit the dummy end breakpoint). */
+
+int
+run_stack_dummy (CORE_ADDR addr, char *buffer)
+{
+ struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
+ int saved_async = 0;
+
+ /* Now proceed, having reached the desired place. */
+ clear_proceed_status ();
+
+ if (CALL_DUMMY_BREAKPOINT_OFFSET_P)
+ {
+ struct breakpoint *bpt;
+ struct symtab_and_line sal;
+
+ INIT_SAL (&sal); /* initialize to zeroes */
+ if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
+ {
+ sal.pc = CALL_DUMMY_ADDRESS ();
+ }
+ else
+ {
+ sal.pc = addr - CALL_DUMMY_START_OFFSET + CALL_DUMMY_BREAKPOINT_OFFSET;
+ }
+ sal.section = find_pc_overlay (sal.pc);
+
+ /* Set up a FRAME for the dummy frame so we can pass it to
+ set_momentary_breakpoint. We need to give the breakpoint a
+ frame in case there is only one copy of the dummy (e.g.
+ CALL_DUMMY_LOCATION == AFTER_TEXT_END). */
+ flush_cached_frames ();
+ set_current_frame (create_new_frame (read_fp (), sal.pc));
+
+ /* If defined, CALL_DUMMY_BREAKPOINT_OFFSET is where we need to put
+ a breakpoint instruction. If not, the call dummy already has the
+ breakpoint instruction in it.
+
+ addr is the address of the call dummy plus the CALL_DUMMY_START_OFFSET,
+ so we need to subtract the CALL_DUMMY_START_OFFSET. */
+ bpt = set_momentary_breakpoint (sal,
+ get_current_frame (),
+ bp_call_dummy);
+ bpt->disposition = disp_del;
+
+ /* If all error()s out of proceed ended up calling normal_stop (and
+ perhaps they should; it already does in the special case of error
+ out of resume()), then we wouldn't need this. */
+ make_cleanup (breakpoint_auto_delete_contents, &stop_bpstat);
+ }
+
+ disable_watchpoints_before_interactive_call_start ();
+ proceed_to_finish = 1; /* We want stop_registers, please... */
+
+ if (target_can_async_p ())
+ saved_async = target_async_mask (0);
+
+ proceed (addr, TARGET_SIGNAL_0, 0);
+
+ if (saved_async)
+ target_async_mask (saved_async);
+
+ enable_watchpoints_after_interactive_call_stop ();
+
+ discard_cleanups (old_cleanups);
+
+ /* We can stop during an inferior call because a signal is received. */
+ if (stopped_by_random_signal)
+ return 1;
+
+ /* We may also stop prematurely because we hit a breakpoint in the
+ called routine. */
+ if (!stop_stack_dummy)
+ return 2;
+
+ /* On normal return, the stack dummy has been popped already. */
+
+ memcpy (buffer, stop_registers, REGISTER_BYTES);
+ return 0;
+}
+
+/* Proceed until we reach a different source line with pc greater than
+ our current one or exit the function. We skip calls in both cases.
+
+ Note that eventually this command should probably be changed so
+ that only source lines are printed out when we hit the breakpoint
+ we set. This may involve changes to wait_for_inferior and the
+ proceed status code. */
+
+/* ARGSUSED */
+static void
+until_next_command (int from_tty)
+{
+ struct frame_info *frame;
+ CORE_ADDR pc;
+ struct symbol *func;
+ struct symtab_and_line sal;
+
+ clear_proceed_status ();
+
+ frame = get_current_frame ();
+
+ /* Step until either exited from this function or greater
+ than the current line (if in symbolic section) or pc (if
+ not). */
+
+ pc = read_pc ();
+ func = find_pc_function (pc);
+
+ if (!func)
+ {
+ struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
+
+ if (msymbol == NULL)
+ error ("Execution is not within a known function.");
+
+ step_range_start = SYMBOL_VALUE_ADDRESS (msymbol);
+ step_range_end = pc;
+ }
+ else
+ {
+ sal = find_pc_line (pc, 0);
+
+ step_range_start = BLOCK_START (SYMBOL_BLOCK_VALUE (func));
+ step_range_end = sal.end;
+ }
+
+ step_over_calls = STEP_OVER_ALL;
+ step_frame_address = FRAME_FP (frame);
+ step_sp = read_sp ();
+
+ step_multi = 0; /* Only one call to proceed */
+
+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
+}
+
+static void
+until_command (char *arg, int from_tty)
+{
+ int async_exec = 0;
+
+ if (!target_has_execution)
+ error ("The program is not running.");
+
+ /* Find out whether we must run in the background. */
+ if (arg != NULL)
+ async_exec = strip_bg_char (&arg);
+
+ /* If we must run in the background, but the target can't do it,
+ error out. */
+ if (event_loop_p && async_exec && !target_can_async_p ())
+ error ("Asynchronous execution not supported on this target.");
+
+ /* If we are not asked to run in the bg, then prepare to run in the
+ foreground, synchronously. */
+ if (event_loop_p && !async_exec && target_can_async_p ())
+ {
+ /* Simulate synchronous execution */
+ async_disable_stdin ();
+ }
+
+ if (arg)
+ until_break_command (arg, from_tty);
+ else
+ until_next_command (from_tty);
+}
+
+
+/* Print the result of a function at the end of a 'finish' command. */
+static void
+print_return_value (int structure_return, struct type *value_type)
+{
+ struct value *value;
+ static struct ui_stream *stb = NULL;
+
+ if (!structure_return)
+ {
+ value = value_being_returned (value_type, stop_registers, structure_return);
+ stb = ui_out_stream_new (uiout);
+ ui_out_text (uiout, "Value returned is ");
+ ui_out_field_fmt (uiout, "gdb-result-var", "$%d", record_latest_value (value));
+ ui_out_text (uiout, " = ");
+ value_print (value, stb->stream, 0, Val_no_prettyprint);
+ ui_out_field_stream (uiout, "return-value", stb);
+ ui_out_text (uiout, "\n");
+ }
+ else
+ {
+ /* We cannot determine the contents of the structure because
+ it is on the stack, and we don't know where, since we did not
+ initiate the call, as opposed to the call_function_by_hand case */
+#ifdef VALUE_RETURNED_FROM_STACK
+ value = 0;
+ ui_out_text (uiout, "Value returned has type: ");
+ ui_out_field_string (uiout, "return-type", TYPE_NAME (value_type));
+ ui_out_text (uiout, ".");
+ ui_out_text (uiout, " Cannot determine contents\n");
+#else
+ value = value_being_returned (value_type, stop_registers, structure_return);
+ stb = ui_out_stream_new (uiout);
+ ui_out_text (uiout, "Value returned is ");
+ ui_out_field_fmt (uiout, "gdb-result-var", "$%d", record_latest_value (value));
+ ui_out_text (uiout, " = ");
+ value_print (value, stb->stream, 0, Val_no_prettyprint);
+ ui_out_field_stream (uiout, "return-value", stb);
+ ui_out_text (uiout, "\n");
+#endif
+ }
+}
+
+/* Stuff that needs to be done by the finish command after the target
+ has stopped. In asynchronous mode, we wait for the target to stop in
+ the call to poll or select in the event loop, so it is impossible to
+ do all the stuff as part of the finish_command function itself. The
+ only chance we have to complete this command is in
+ fetch_inferior_event, which is called by the event loop as soon as it
+ detects that the target has stopped. This function is called via the
+ cmd_continuation pointer. */
+void
+finish_command_continuation (struct continuation_arg *arg)
+{
+ register struct symbol *function;
+ struct breakpoint *breakpoint;
+ struct cleanup *cleanups;
+
+ breakpoint = (struct breakpoint *) arg->data.pointer;
+ function = (struct symbol *) arg->next->data.pointer;
+ cleanups = (struct cleanup *) arg->next->next->data.pointer;
+
+ if (bpstat_find_breakpoint (stop_bpstat, breakpoint) != NULL
+ && function != 0)
+ {
+ struct type *value_type;
+ CORE_ADDR funcaddr;
+ int struct_return;
+
+ value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
+ if (!value_type)
+ internal_error (__FILE__, __LINE__,
+ "finish_command: function has no target type");
+
+ if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
+ {
+ do_exec_cleanups (cleanups);
+ return;
+ }
+
+ funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function));
+
+ struct_return = using_struct_return (value_of_variable (function, NULL),
+ funcaddr,
+ check_typedef (value_type),
+ BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function)));
+
+ print_return_value (struct_return, value_type);
+ }
+ do_exec_cleanups (cleanups);
+}
+
+/* "finish": Set a temporary breakpoint at the place
+ the selected frame will return to, then continue. */
+
+static void
+finish_command (char *arg, int from_tty)
+{
+ struct symtab_and_line sal;
+ register struct frame_info *frame;
+ register struct symbol *function;
+ struct breakpoint *breakpoint;
+ struct cleanup *old_chain;
+ struct continuation_arg *arg1, *arg2, *arg3;
+
+ int async_exec = 0;
+
+ /* Find out whether we must run in the background. */
+ if (arg != NULL)
+ async_exec = strip_bg_char (&arg);
+
+ /* If we must run in the background, but the target can't do it,
+ error out. */
+ if (event_loop_p && async_exec && !target_can_async_p ())
+ error ("Asynchronous execution not supported on this target.");
+
+ /* If we are not asked to run in the bg, then prepare to run in the
+ foreground, synchronously. */
+ if (event_loop_p && !async_exec && target_can_async_p ())
+ {
+ /* Simulate synchronous execution */
+ async_disable_stdin ();
+ }
+
+ if (arg)
+ error ("The \"finish\" command does not take any arguments.");
+ if (!target_has_execution)
+ error ("The program is not running.");
+ if (selected_frame == NULL)
+ error ("No selected frame.");
+
+ frame = get_prev_frame (selected_frame);
+ if (frame == 0)
+ error ("\"finish\" not meaningful in the outermost frame.");
+
+ clear_proceed_status ();
+
+ sal = find_pc_line (frame->pc, 0);
+ sal.pc = frame->pc;
+
+ breakpoint = set_momentary_breakpoint (sal, frame, bp_finish);
+
+ if (!event_loop_p || !target_can_async_p ())
+ old_chain = make_cleanup_delete_breakpoint (breakpoint);
+ else
+ old_chain = make_exec_cleanup_delete_breakpoint (breakpoint);
+
+ /* Find the function we will return from. */
+
+ function = find_pc_function (selected_frame->pc);
+
+ /* Print info on the selected frame, including level number
+ but not source. */
+ if (from_tty)
+ {
+ printf_filtered ("Run till exit from ");
+ print_stack_frame (selected_frame,
+ frame_relative_level (selected_frame), 0);
+ }
+
+ /* If running asynchronously and the target support asynchronous
+ execution, set things up for the rest of the finish command to be
+ completed later on, when gdb has detected that the target has
+ stopped, in fetch_inferior_event. */
+ if (event_loop_p && target_can_async_p ())
+ {
+ arg1 =
+ (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+ arg2 =
+ (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+ arg3 =
+ (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+ arg1->next = arg2;
+ arg2->next = arg3;
+ arg3->next = NULL;
+ arg1->data.pointer = breakpoint;
+ arg2->data.pointer = function;
+ arg3->data.pointer = old_chain;
+ add_continuation (finish_command_continuation, arg1);
+ }
+
+ proceed_to_finish = 1; /* We want stop_registers, please... */
+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+
+ /* Do this only if not running asynchronously or if the target
+ cannot do async execution. Otherwise, complete this command when
+ the target actually stops, in fetch_inferior_event. */
+ if (!event_loop_p || !target_can_async_p ())
+ {
+
+ /* Did we stop at our breakpoint? */
+ if (bpstat_find_breakpoint (stop_bpstat, breakpoint) != NULL
+ && function != 0)
+ {
+ struct type *value_type;
+ CORE_ADDR funcaddr;
+ int struct_return;
+
+ value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
+ if (!value_type)
+ internal_error (__FILE__, __LINE__,
+ "finish_command: function has no target type");
+
+ /* FIXME: Shouldn't we do the cleanups before returning? */
+ if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
+ return;
+
+ funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function));
+
+ struct_return =
+ using_struct_return (value_of_variable (function, NULL),
+ funcaddr,
+ check_typedef (value_type),
+ BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function)));
+
+ print_return_value (struct_return, value_type);
+ }
+ do_cleanups (old_chain);
+ }
+}
+
+/* ARGSUSED */
+static void
+program_info (char *args, int from_tty)
+{
+ bpstat bs = stop_bpstat;
+ int num = bpstat_num (&bs);
+
+ if (!target_has_execution)
+ {
+ printf_filtered ("The program being debugged is not being run.\n");
+ return;
+ }
+
+ target_files_info ();
+ printf_filtered ("Program stopped at %s.\n",
+ local_hex_string ((unsigned long) stop_pc));
+ if (stop_step)
+ printf_filtered ("It stopped after being stepped.\n");
+ else if (num != 0)
+ {
+ /* There may be several breakpoints in the same place, so this
+ isn't as strange as it seems. */
+ while (num != 0)
+ {
+ if (num < 0)
+ {
+ printf_filtered ("It stopped at a breakpoint that has ");
+ printf_filtered ("since been deleted.\n");
+ }
+ else
+ printf_filtered ("It stopped at breakpoint %d.\n", num);
+ num = bpstat_num (&bs);
+ }
+ }
+ else if (stop_signal != TARGET_SIGNAL_0)
+ {
+ printf_filtered ("It stopped with signal %s, %s.\n",
+ target_signal_to_name (stop_signal),
+ target_signal_to_string (stop_signal));
+ }
+
+ if (!from_tty)
+ {
+ printf_filtered ("Type \"info stack\" or \"info registers\" ");
+ printf_filtered ("for more information.\n");
+ }
+}
+
+static void
+environment_info (char *var, int from_tty)
+{
+ if (var)
+ {
+ register char *val = get_in_environ (inferior_environ, var);
+ if (val)
+ {
+ puts_filtered (var);
+ puts_filtered (" = ");
+ puts_filtered (val);
+ puts_filtered ("\n");
+ }
+ else
+ {
+ puts_filtered ("Environment variable \"");
+ puts_filtered (var);
+ puts_filtered ("\" not defined.\n");
+ }
+ }
+ else
+ {
+ register char **vector = environ_vector (inferior_environ);
+ while (*vector)
+ {
+ puts_filtered (*vector++);
+ puts_filtered ("\n");
+ }
+ }
+}
+
+static void
+set_environment_command (char *arg, int from_tty)
+{
+ register char *p, *val, *var;
+ int nullset = 0;
+
+ if (arg == 0)
+ error_no_arg ("environment variable and value");
+
+ /* Find seperation between variable name and value */
+ p = (char *) strchr (arg, '=');
+ val = (char *) strchr (arg, ' ');
+
+ if (p != 0 && val != 0)
+ {
+ /* We have both a space and an equals. If the space is before the
+ equals, walk forward over the spaces til we see a nonspace
+ (possibly the equals). */
+ if (p > val)
+ while (*val == ' ')
+ val++;
+
+ /* Now if the = is after the char following the spaces,
+ take the char following the spaces. */
+ if (p > val)
+ p = val - 1;
+ }
+ else if (val != 0 && p == 0)
+ p = val;
+
+ if (p == arg)
+ error_no_arg ("environment variable to set");
+
+ if (p == 0 || p[1] == 0)
+ {
+ nullset = 1;
+ if (p == 0)
+ p = arg + strlen (arg); /* So that savestring below will work */
+ }
+ else
+ {
+ /* Not setting variable value to null */
+ val = p + 1;
+ while (*val == ' ' || *val == '\t')
+ val++;
+ }
+
+ while (p != arg && (p[-1] == ' ' || p[-1] == '\t'))
+ p--;
+
+ var = savestring (arg, p - arg);
+ if (nullset)
+ {
+ printf_filtered ("Setting environment variable ");
+ printf_filtered ("\"%s\" to null value.\n", var);
+ set_in_environ (inferior_environ, var, "");
+ }
+ else
+ set_in_environ (inferior_environ, var, val);
+ xfree (var);
+}
+
+static void
+unset_environment_command (char *var, int from_tty)
+{
+ if (var == 0)
+ {
+ /* If there is no argument, delete all environment variables.
+ Ask for confirmation if reading from the terminal. */
+ if (!from_tty || query ("Delete all environment variables? "))
+ {
+ free_environ (inferior_environ);
+ inferior_environ = make_environ ();
+ }
+ }
+ else
+ unset_in_environ (inferior_environ, var);
+}
+
+/* Handle the execution path (PATH variable) */
+
+static const char path_var_name[] = "PATH";
+
+/* ARGSUSED */
+static void
+path_info (char *args, int from_tty)
+{
+ puts_filtered ("Executable and object file path: ");
+ puts_filtered (get_in_environ (inferior_environ, path_var_name));
+ puts_filtered ("\n");
+}
+
+/* Add zero or more directories to the front of the execution path. */
+
+static void
+path_command (char *dirname, int from_tty)
+{
+ char *exec_path;
+ char *env;
+ dont_repeat ();
+ env = get_in_environ (inferior_environ, path_var_name);
+ /* Can be null if path is not set */
+ if (!env)
+ env = "";
+ exec_path = xstrdup (env);
+ mod_path (dirname, &exec_path);
+ set_in_environ (inferior_environ, path_var_name, exec_path);
+ xfree (exec_path);
+ if (from_tty)
+ path_info ((char *) NULL, from_tty);
+}
+
+
+#ifdef REGISTER_NAMES
+char *gdb_register_names[] = REGISTER_NAMES;
+#endif
+/* Print out the machine register regnum. If regnum is -1,
+ print all registers (fpregs == 1) or all non-float registers
+ (fpregs == 0).
+
+ For most machines, having all_registers_info() print the
+ register(s) one per line is good enough. If a different format
+ is required, (eg, for MIPS or Pyramid 90x, which both have
+ lots of regs), or there is an existing convention for showing
+ all the registers, define the macro DO_REGISTERS_INFO(regnum, fp)
+ to provide that format. */
+
+void
+do_registers_info (int regnum, int fpregs)
+{
+ register int i;
+ int numregs = NUM_REGS + NUM_PSEUDO_REGS;
+ char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ char *virtual_buffer = (char*) alloca (MAX_REGISTER_VIRTUAL_SIZE);
+
+ for (i = 0; i < numregs; i++)
+ {
+ /* Decide between printing all regs, nonfloat regs, or specific reg. */
+ if (regnum == -1)
+ {
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT && !fpregs)
+ continue;
+ }
+ else
+ {
+ if (i != regnum)
+ continue;
+ }
+
+ /* If the register name is empty, it is undefined for this
+ processor, so don't display anything. */
+ if (REGISTER_NAME (i) == NULL || *(REGISTER_NAME (i)) == '\0')
+ continue;
+
+ fputs_filtered (REGISTER_NAME (i), gdb_stdout);
+ print_spaces_filtered (15 - strlen (REGISTER_NAME (i)), gdb_stdout);
+
+ /* Get the data in raw format. */
+ if (! frame_register_read (selected_frame, i, raw_buffer))
+ {
+ printf_filtered ("*value not available*\n");
+ continue;
+ }
+
+ /* Convert raw data to virtual format if necessary. */
+ if (REGISTER_CONVERTIBLE (i))
+ {
+ REGISTER_CONVERT_TO_VIRTUAL (i, REGISTER_VIRTUAL_TYPE (i),
+ raw_buffer, virtual_buffer);
+ }
+ else
+ {
+ memcpy (virtual_buffer, raw_buffer,
+ REGISTER_VIRTUAL_SIZE (i));
+ }
+
+ /* If virtual format is floating, print it that way, and in raw hex. */
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
+ {
+ register int j;
+
+ val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
+ gdb_stdout, 0, 1, 0, Val_pretty_default);
+
+ printf_filtered ("\t(raw 0x");
+ for (j = 0; j < REGISTER_RAW_SIZE (i); j++)
+ {
+ register int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j
+ : REGISTER_RAW_SIZE (i) - 1 - j;
+ printf_filtered ("%02x", (unsigned char) raw_buffer[idx]);
+ }
+ printf_filtered (")");
+ }
+ /* Else print as integer in hex and in decimal. */
+ else
+ {
+ val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
+ gdb_stdout, 'x', 1, 0, Val_pretty_default);
+ printf_filtered ("\t");
+ val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
+ gdb_stdout, 0, 1, 0, Val_pretty_default);
+ }
+
+ /* The SPARC wants to print even-numbered float regs as doubles
+ in addition to printing them as floats. */
+#ifdef PRINT_REGISTER_HOOK
+ PRINT_REGISTER_HOOK (i);
+#endif
+
+ printf_filtered ("\n");
+ }
+}
+
+void
+registers_info (char *addr_exp, int fpregs)
+{
+ int regnum, numregs;
+ register char *end;
+
+ if (!target_has_registers)
+ error ("The program has no registers now.");
+ if (selected_frame == NULL)
+ error ("No selected frame.");
+
+ if (!addr_exp)
+ {
+ DO_REGISTERS_INFO (-1, fpregs);
+ return;
+ }
+
+ do
+ {
+ if (addr_exp[0] == '$')
+ addr_exp++;
+ end = addr_exp;
+ while (*end != '\0' && *end != ' ' && *end != '\t')
+ ++end;
+ numregs = NUM_REGS + NUM_PSEUDO_REGS;
+
+ regnum = target_map_name_to_register (addr_exp, end - addr_exp);
+ if (regnum >= 0)
+ goto found;
+
+ regnum = numregs;
+
+ if (*addr_exp >= '0' && *addr_exp <= '9')
+ regnum = atoi (addr_exp); /* Take a number */
+ if (regnum >= numregs) /* Bad name, or bad number */
+ error ("%.*s: invalid register", (int) (end - addr_exp), addr_exp);
+
+ found:
+ DO_REGISTERS_INFO (regnum, fpregs);
+
+ addr_exp = end;
+ while (*addr_exp == ' ' || *addr_exp == '\t')
+ ++addr_exp;
+ }
+ while (*addr_exp != '\0');
+}
+
+void
+all_registers_info (char *addr_exp, int from_tty)
+{
+ registers_info (addr_exp, 1);
+}
+
+void
+nofp_registers_info (char *addr_exp, int from_tty)
+{
+ registers_info (addr_exp, 0);
+}
+
+
+/*
+ * TODO:
+ * Should save/restore the tty state since it might be that the
+ * program to be debugged was started on this tty and it wants
+ * the tty in some state other than what we want. If it's running
+ * on another terminal or without a terminal, then saving and
+ * restoring the tty state is a harmless no-op.
+ * This only needs to be done if we are attaching to a process.
+ */
+
+/*
+ attach_command --
+ takes a program started up outside of gdb and ``attaches'' to it.
+ This stops it cold in its tracks and allows us to start debugging it.
+ and wait for the trace-trap that results from attaching. */
+
+void
+attach_command (char *args, int from_tty)
+{
+ char *exec_file;
+ char *full_exec_path = NULL;
+
+ dont_repeat (); /* Not for the faint of heart */
+
+ if (target_has_execution)
+ {
+ if (query ("A program is being debugged already. Kill it? "))
+ target_kill ();
+ else
+ error ("Not killed.");
+ }
+
+ target_attach (args, from_tty);
+
+ /* Set up the "saved terminal modes" of the inferior
+ based on what modes we are starting it with. */
+ target_terminal_init ();
+
+ /* Install inferior's terminal modes. */
+ target_terminal_inferior ();
+
+ /* Set up execution context to know that we should return from
+ wait_for_inferior as soon as the target reports a stop. */
+ init_wait_for_inferior ();
+ clear_proceed_status ();
+
+ /* No traps are generated when attaching to inferior under Mach 3
+ or GNU hurd. */
+#ifndef ATTACH_NO_WAIT
+ stop_soon_quietly = 1;
+ wait_for_inferior ();
+#endif
+
+ /*
+ * If no exec file is yet known, try to determine it from the
+ * process itself.
+ */
+ exec_file = (char *) get_exec_file (0);
+ if (!exec_file)
+ {
+ exec_file = target_pid_to_exec_file (PIDGET (inferior_ptid));
+ if (exec_file)
+ {
+ /* It's possible we don't have a full path, but rather just a
+ filename. Some targets, such as HP-UX, don't provide the
+ full path, sigh.
+
+ Attempt to qualify the filename against the source path.
+ (If that fails, we'll just fall back on the original
+ filename. Not much more we can do...)
+ */
+ if (!source_full_path_of (exec_file, &full_exec_path))
+ full_exec_path = savestring (exec_file, strlen (exec_file));
+
+ exec_file_attach (full_exec_path, from_tty);
+ symbol_file_add_main (full_exec_path, from_tty);
+ }
+ }
+
+#ifdef SOLIB_ADD
+ /* Add shared library symbols from the newly attached process, if any. */
+ SOLIB_ADD ((char *) 0, from_tty, &current_target, auto_solib_add);
+ re_enable_breakpoints_in_shlibs ();
+#endif
+
+ /* Take any necessary post-attaching actions for this platform.
+ */
+ target_post_attach (PIDGET (inferior_ptid));
+
+ normal_stop ();
+
+ if (attach_hook)
+ attach_hook ();
+}
+
+/*
+ * detach_command --
+ * takes a program previously attached to and detaches it.
+ * The program resumes execution and will no longer stop
+ * on signals, etc. We better not have left any breakpoints
+ * in the program or it'll die when it hits one. For this
+ * to work, it may be necessary for the process to have been
+ * previously attached. It *might* work if the program was
+ * started via the normal ptrace (PTRACE_TRACEME).
+ */
+
+static void
+detach_command (char *args, int from_tty)
+{
+ dont_repeat (); /* Not for the faint of heart */
+ target_detach (args, from_tty);
+#if defined(SOLIB_RESTART)
+ SOLIB_RESTART ();
+#endif
+ if (detach_hook)
+ detach_hook ();
+}
+
+/* Stop the execution of the target while running in async mode, in
+ the backgound. */
+
+void
+interrupt_target_command_wrapper (char *args, int from_tty)
+{
+ interrupt_target_command (args, from_tty);
+}
+
+static void
+interrupt_target_command (char *args, int from_tty)
+{
+ if (event_loop_p && target_can_async_p ())
+ {
+ dont_repeat (); /* Not for the faint of heart */
+ target_stop ();
+ }
+}
+
+/* ARGSUSED */
+static void
+float_info (char *addr_exp, int from_tty)
+{
+ PRINT_FLOAT_INFO ();
+}
+
+/* ARGSUSED */
+static void
+unset_command (char *args, int from_tty)
+{
+ printf_filtered ("\"unset\" must be followed by the name of ");
+ printf_filtered ("an unset subcommand.\n");
+ help_list (unsetlist, "unset ", -1, gdb_stdout);
+}
+
+void
+_initialize_infcmd (void)
+{
+ struct cmd_list_element *c;
+
+ c = add_com ("tty", class_run, tty_command,
+ "Set terminal for future runs of program being debugged.");
+ set_cmd_completer (c, filename_completer);
+
+ c = add_set_cmd ("args", class_run, var_string_noescape,
+ (char *) &inferior_args,
+ "Set argument list to give program being debugged when it is started.\n\
+Follow this command with any number of args, to be passed to the program.",
+ &setlist);
+ set_cmd_completer (c, filename_completer);
+ set_cmd_sfunc (c, notice_args_set);
+ c = add_show_from_set (c, &showlist);
+ set_cmd_sfunc (c, notice_args_read);
+
+ c = add_cmd
+ ("environment", no_class, environment_info,
+ "The environment to give the program, or one variable's value.\n\
+With an argument VAR, prints the value of environment variable VAR to\n\
+give the program being debugged. With no arguments, prints the entire\n\
+environment to be given to the program.", &showlist);
+ set_cmd_completer (c, noop_completer);
+
+ add_prefix_cmd ("unset", no_class, unset_command,
+ "Complement to certain \"set\" commands.",
+ &unsetlist, "unset ", 0, &cmdlist);
+
+ c = add_cmd ("environment", class_run, unset_environment_command,
+ "Cancel environment variable VAR for the program.\n\
+This does not affect the program until the next \"run\" command.",
+ &unsetlist);
+ set_cmd_completer (c, noop_completer);
+
+ c = add_cmd ("environment", class_run, set_environment_command,
+ "Set environment variable value to give the program.\n\
+Arguments are VAR VALUE where VAR is variable name and VALUE is value.\n\
+VALUES of environment variables are uninterpreted strings.\n\
+This does not affect the program until the next \"run\" command.",
+ &setlist);
+ set_cmd_completer (c, noop_completer);
+
+ c = add_com ("path", class_files, path_command,
+ "Add directory DIR(s) to beginning of search path for object files.\n\
+$cwd in the path means the current working directory.\n\
+This path is equivalent to the $PATH shell variable. It is a list of\n\
+directories, separated by colons. These directories are searched to find\n\
+fully linked executable files and separately compiled object files as needed.");
+ set_cmd_completer (c, filename_completer);
+
+ c = add_cmd ("paths", no_class, path_info,
+ "Current search path for finding object files.\n\
+$cwd in the path means the current working directory.\n\
+This path is equivalent to the $PATH shell variable. It is a list of\n\
+directories, separated by colons. These directories are searched to find\n\
+fully linked executable files and separately compiled object files as needed.",
+ &showlist);
+ set_cmd_completer (c, noop_completer);
+
+ add_com ("attach", class_run, attach_command,
+ "Attach to a process or file outside of GDB.\n\
+This command attaches to another target, of the same type as your last\n\
+\"target\" command (\"info files\" will show your target stack).\n\
+The command may take as argument a process id or a device file.\n\
+For a process id, you must have permission to send the process a signal,\n\
+and it must have the same effective uid as the debugger.\n\
+When using \"attach\" with a process id, the debugger finds the\n\
+program running in the process, looking first in the current working\n\
+directory, or (if not found there) using the source file search path\n\
+(see the \"directory\" command). You can also use the \"file\" command\n\
+to specify the program, and to load its symbol table.");
+
+ add_com ("detach", class_run, detach_command,
+ "Detach a process or file previously attached.\n\
+If a process, it is no longer traced, and it continues its execution. If\n\
+you were debugging a file, the file is closed and gdb no longer accesses it.");
+
+ add_com ("signal", class_run, signal_command,
+ "Continue program giving it signal specified by the argument.\n\
+An argument of \"0\" means continue program without giving it a signal.");
+
+ add_com ("stepi", class_run, stepi_command,
+ "Step one instruction exactly.\n\
+Argument N means do this N times (or till program stops for another reason).");
+ add_com_alias ("si", "stepi", class_alias, 0);
+
+ add_com ("nexti", class_run, nexti_command,
+ "Step one instruction, but proceed through subroutine calls.\n\
+Argument N means do this N times (or till program stops for another reason).");
+ add_com_alias ("ni", "nexti", class_alias, 0);
+
+ add_com ("finish", class_run, finish_command,
+ "Execute until selected stack frame returns.\n\
+Upon return, the value returned is printed and put in the value history.");
+
+ add_com ("next", class_run, next_command,
+ "Step program, proceeding through subroutine calls.\n\
+Like the \"step\" command as long as subroutine calls do not happen;\n\
+when they do, the call is treated as one instruction.\n\
+Argument N means do this N times (or till program stops for another reason).");
+ add_com_alias ("n", "next", class_run, 1);
+ if (xdb_commands)
+ add_com_alias ("S", "next", class_run, 1);
+
+ add_com ("step", class_run, step_command,
+ "Step program until it reaches a different source line.\n\
+Argument N means do this N times (or till program stops for another reason).");
+ add_com_alias ("s", "step", class_run, 1);
+
+ c = add_com ("until", class_run, until_command,
+ "Execute until the program reaches a source line greater than the current\n\
+or a specified line or address or function (same args as break command).\n\
+Execution will also stop upon exit from the current stack frame.");
+ set_cmd_completer (c, location_completer);
+ add_com_alias ("u", "until", class_run, 1);
+
+ c = add_com ("jump", class_run, jump_command,
+ "Continue program being debugged at specified line or address.\n\
+Give as argument either LINENUM or *ADDR, where ADDR is an expression\n\
+for an address to start at.");
+ set_cmd_completer (c, location_completer);
+
+ if (xdb_commands)
+ {
+ c = add_com ("go", class_run, go_command,
+ "Usage: go <location>\n\
+Continue program being debugged, stopping at specified line or \n\
+address.\n\
+Give as argument either LINENUM or *ADDR, where ADDR is an \n\
+expression for an address to start at.\n\
+This command is a combination of tbreak and jump.");
+ set_cmd_completer (c, location_completer);
+ }
+
+ if (xdb_commands)
+ add_com_alias ("g", "go", class_run, 1);
+
+ add_com ("continue", class_run, continue_command,
+ "Continue program being debugged, after signal or breakpoint.\n\
+If proceeding from breakpoint, a number N may be used as an argument,\n\
+which means to set the ignore count of that breakpoint to N - 1 (so that\n\
+the breakpoint won't break until the Nth time it is reached).");
+ add_com_alias ("c", "cont", class_run, 1);
+ add_com_alias ("fg", "cont", class_run, 1);
+
+ c = add_com ("run", class_run, run_command,
+ "Start debugged program. You may specify arguments to give it.\n\
+Args may include \"*\", or \"[...]\"; they are expanded using \"sh\".\n\
+Input and output redirection with \">\", \"<\", or \">>\" are also allowed.\n\n\
+With no arguments, uses arguments last specified (with \"run\" or \"set args\").\n\
+To cancel previous arguments and run with no arguments,\n\
+use \"set args\" without arguments.");
+ set_cmd_completer (c, filename_completer);
+ add_com_alias ("r", "run", class_run, 1);
+ if (xdb_commands)
+ add_com ("R", class_run, run_no_args_command,
+ "Start debugged program with no arguments.");
+
+ add_com ("interrupt", class_run, interrupt_target_command,
+ "Interrupt the execution of the debugged program.");
+
+ add_info ("registers", nofp_registers_info,
+ "List of integer registers and their contents, for selected stack frame.\n\
+Register name as argument means describe only that register.");
+ add_info_alias ("r", "registers", 1);
+
+ if (xdb_commands)
+ add_com ("lr", class_info, nofp_registers_info,
+ "List of integer registers and their contents, for selected stack frame.\n\
+ Register name as argument means describe only that register.");
+ add_info ("all-registers", all_registers_info,
+ "List of all registers and their contents, for selected stack frame.\n\
+Register name as argument means describe only that register.");
+
+ add_info ("program", program_info,
+ "Execution status of the program.");
+
+ add_info ("float", float_info,
+ "Print the status of the floating point unit\n");
+
+ inferior_environ = make_environ ();
+ init_environ (inferior_environ);
+}
diff --git a/gdb/inferior.h b/gdb/inferior.h
new file mode 100644
index 00000000000..2c05f35b3ce
--- /dev/null
+++ b/gdb/inferior.h
@@ -0,0 +1,549 @@
+/* Variables that describe the inferior process running under GDB:
+ Where it is, why it stopped, and how to step it.
+ Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1998, 1999, 2000, 2001 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. */
+
+#if !defined (INFERIOR_H)
+#define INFERIOR_H 1
+
+struct gdbarch;
+
+/* For bpstat. */
+#include "breakpoint.h"
+
+/* For enum target_signal. */
+#include "target.h"
+
+/* Structure in which to save the status of the inferior. Create/Save
+ through "save_inferior_status", restore through
+ "restore_inferior_status".
+
+ This pair of routines should be called around any transfer of
+ control to the inferior which you don't want showing up in your
+ control variables. */
+
+struct inferior_status;
+
+extern struct inferior_status *save_inferior_status (int);
+
+extern void restore_inferior_status (struct inferior_status *);
+
+extern struct cleanup *make_cleanup_restore_inferior_status (struct inferior_status *);
+
+extern void discard_inferior_status (struct inferior_status *);
+
+extern void write_inferior_status_register (struct inferior_status
+ *inf_status, int regno,
+ LONGEST val);
+
+/* The -1 ptid, often used to indicate either an error condition
+ or a "don't care" condition, i.e, "run all threads." */
+extern ptid_t minus_one_ptid;
+
+/* The null or zero ptid, often used to indicate no process. */
+extern ptid_t null_ptid;
+
+/* Attempt to find and return an existing ptid with the given PID, LWP,
+ and TID components. If none exists, create a new one and return
+ that. */
+ptid_t ptid_build (int pid, long lwp, long tid);
+
+/* Find/Create a ptid from just a pid. */
+ptid_t pid_to_ptid (int pid);
+
+/* Fetch the pid (process id) component from a ptid. */
+int ptid_get_pid (ptid_t ptid);
+
+/* Fetch the lwp (lightweight process) component from a ptid. */
+long ptid_get_lwp (ptid_t ptid);
+
+/* Fetch the tid (thread id) component from a ptid. */
+long ptid_get_tid (ptid_t ptid);
+
+/* Compare two ptids to see if they are equal */
+extern int ptid_equal (ptid_t p1, ptid_t p2);
+
+/* Save value of inferior_ptid so that it may be restored by
+ a later call to do_cleanups(). Returns the struct cleanup
+ pointer needed for later doing the cleanup. */
+extern struct cleanup * save_inferior_ptid (void);
+
+extern void set_sigint_trap (void);
+
+extern void clear_sigint_trap (void);
+
+extern void set_sigio_trap (void);
+
+extern void clear_sigio_trap (void);
+
+/* File name for default use for standard in/out in the inferior. */
+
+extern char *inferior_io_terminal;
+
+/* Collected pid, tid, etc. of the debugged inferior. When there's
+ no inferior, PIDGET (inferior_ptid) will be 0. */
+
+extern ptid_t inferior_ptid;
+
+/* Is the inferior running right now, as a result of a 'run&',
+ 'continue&' etc command? This is used in asycn gdb to determine
+ whether a command that the user enters while the target is running
+ is allowed or not. */
+extern int target_executing;
+
+/* Are we simulating synchronous execution? This is used in async gdb
+ to implement the 'run', 'continue' etc commands, which will not
+ redisplay the prompt until the execution is actually over. */
+extern int sync_execution;
+
+/* This is only valid when inferior_ptid is non-zero.
+
+ If this is 0, then exec events should be noticed and responded to
+ by the debugger (i.e., be reported to the user).
+
+ If this is > 0, then that many subsequent exec events should be
+ ignored (i.e., not be reported to the user).
+ */
+extern int inferior_ignoring_startup_exec_events;
+
+/* This is only valid when inferior_ignoring_startup_exec_events is
+ zero.
+
+ Some targets (stupidly) report more than one exec event per actual
+ call to an event() system call. If only the last such exec event
+ need actually be noticed and responded to by the debugger (i.e.,
+ be reported to the user), then this is the number of "leading"
+ exec events which should be ignored.
+ */
+extern int inferior_ignoring_leading_exec_events;
+
+/* Inferior environment. */
+
+extern struct environ *inferior_environ;
+
+extern void clear_proceed_status (void);
+
+extern void proceed (CORE_ADDR, enum target_signal, int);
+
+/* When set, stop the 'step' command if we enter a function which has
+ no line number information. The normal behavior is that we step
+ over such function. */
+extern int step_stop_if_no_debug;
+
+extern void kill_inferior (void);
+
+extern void generic_mourn_inferior (void);
+
+extern void terminal_ours (void);
+
+extern int run_stack_dummy (CORE_ADDR, char *);
+
+extern CORE_ADDR read_pc (void);
+
+extern CORE_ADDR read_pc_pid (ptid_t);
+
+extern CORE_ADDR generic_target_read_pc (ptid_t);
+
+extern void write_pc (CORE_ADDR);
+
+extern void write_pc_pid (CORE_ADDR, ptid_t);
+
+extern void generic_target_write_pc (CORE_ADDR, ptid_t);
+
+extern CORE_ADDR read_sp (void);
+
+extern CORE_ADDR generic_target_read_sp (void);
+
+extern void write_sp (CORE_ADDR);
+
+extern void generic_target_write_sp (CORE_ADDR);
+
+extern CORE_ADDR read_fp (void);
+
+extern CORE_ADDR generic_target_read_fp (void);
+
+extern CORE_ADDR unsigned_pointer_to_address (struct type *type, void *buf);
+
+extern void unsigned_address_to_pointer (struct type *type, void *buf,
+ CORE_ADDR addr);
+extern CORE_ADDR signed_pointer_to_address (struct type *type, void *buf);
+extern void address_to_signed_pointer (struct type *type, void *buf,
+ CORE_ADDR addr);
+
+extern void wait_for_inferior (void);
+
+extern void fetch_inferior_event (void *);
+
+extern void init_wait_for_inferior (void);
+
+extern void close_exec_file (void);
+
+extern void reopen_exec_file (void);
+
+/* The `resume' routine should only be called in special circumstances.
+ Normally, use `proceed', which handles a lot of bookkeeping. */
+
+extern void resume (int, enum target_signal);
+
+/* From misc files */
+
+extern void do_registers_info (int, int);
+
+extern void store_inferior_registers (int);
+
+extern void fetch_inferior_registers (int);
+
+extern void solib_create_inferior_hook (void);
+
+extern void child_terminal_info (char *, int);
+
+extern void term_info (char *, int);
+
+extern void terminal_ours_for_output (void);
+
+extern void terminal_inferior (void);
+
+extern void terminal_init_inferior (void);
+
+extern void terminal_init_inferior_with_pgrp (int pgrp);
+
+/* From infptrace.c or infttrace.c */
+
+extern int attach (int);
+
+#if !defined(REQUIRE_ATTACH)
+#define REQUIRE_ATTACH attach
+#endif
+
+#if !defined(REQUIRE_DETACH)
+#define REQUIRE_DETACH(pid,siggnal) detach (siggnal)
+#endif
+
+extern void detach (int);
+
+/* PTRACE method of waiting for inferior process. */
+int ptrace_wait (ptid_t, int *);
+
+extern void child_resume (ptid_t, int, enum target_signal);
+
+#ifndef PTRACE_ARG3_TYPE
+#define PTRACE_ARG3_TYPE int /* Correct definition for most systems. */
+#endif
+
+extern int call_ptrace (int, int, PTRACE_ARG3_TYPE, int);
+
+extern void pre_fork_inferior (void);
+
+/* From procfs.c */
+
+extern int proc_iterate_over_mappings (int (*)(int, CORE_ADDR));
+
+extern ptid_t procfs_first_available (void);
+
+/* From fork-child.c */
+
+extern void fork_inferior (char *, char *, char **,
+ void (*)(void),
+ void (*)(int), void (*)(void), char *);
+
+
+extern void clone_and_follow_inferior (int, int *);
+
+extern void startup_inferior (int);
+
+extern char *construct_inferior_arguments (struct gdbarch *, int, char **);
+
+/* From inflow.c */
+
+extern void new_tty_prefork (char *);
+
+extern int gdb_has_a_terminal (void);
+
+/* From infrun.c */
+
+extern void start_remote (void);
+
+extern void normal_stop (void);
+
+extern int signal_stop_state (int);
+
+extern int signal_print_state (int);
+
+extern int signal_pass_state (int);
+
+extern int signal_stop_update (int, int);
+
+extern int signal_print_update (int, int);
+
+extern int signal_pass_update (int, int);
+
+extern void get_last_target_status(ptid_t *ptid,
+ struct target_waitstatus *status);
+
+/* From infcmd.c */
+
+extern void tty_command (char *, int);
+
+extern void attach_command (char *, int);
+
+extern char *get_inferior_args (void);
+
+extern char *set_inferior_args (char *);
+
+extern void set_inferior_args_vector (int, char **);
+
+/* Last signal that the inferior received (why it stopped). */
+
+extern enum target_signal stop_signal;
+
+/* Address at which inferior stopped. */
+
+extern CORE_ADDR stop_pc;
+
+/* Chain containing status of breakpoint(s) that we have stopped at. */
+
+extern bpstat stop_bpstat;
+
+/* Flag indicating that a command has proceeded the inferior past the
+ current breakpoint. */
+
+extern int breakpoint_proceeded;
+
+/* Nonzero if stopped due to a step command. */
+
+extern int stop_step;
+
+/* Nonzero if stopped due to completion of a stack dummy routine. */
+
+extern int stop_stack_dummy;
+
+/* Nonzero if program stopped due to a random (unexpected) signal in
+ inferior process. */
+
+extern int stopped_by_random_signal;
+
+/* Range to single step within.
+ If this is nonzero, respond to a single-step signal
+ by continuing to step if the pc is in this range.
+
+ If step_range_start and step_range_end are both 1, it means to step for
+ a single instruction (FIXME: it might clean up wait_for_inferior in a
+ minor way if this were changed to the address of the instruction and
+ that address plus one. But maybe not.). */
+
+extern CORE_ADDR step_range_start; /* Inclusive */
+extern CORE_ADDR step_range_end; /* Exclusive */
+
+/* Stack frame address as of when stepping command was issued.
+ This is how we know when we step into a subroutine call,
+ and how to set the frame for the breakpoint used to step out. */
+
+extern CORE_ADDR step_frame_address;
+
+/* Our notion of the current stack pointer. */
+
+extern CORE_ADDR step_sp;
+
+/* 1 means step over all subroutine calls.
+ -1 means step over calls to undebuggable functions. */
+
+enum step_over_calls_kind
+ {
+ STEP_OVER_NONE,
+ STEP_OVER_ALL,
+ STEP_OVER_UNDEBUGGABLE
+ };
+
+extern enum step_over_calls_kind step_over_calls;
+
+/* If stepping, nonzero means step count is > 1
+ so don't print frame next time inferior stops
+ if it stops due to stepping. */
+
+extern int step_multi;
+
+/* Nonzero means expecting a trap and caller will handle it themselves.
+ It is used after attach, due to attaching to a process;
+ when running in the shell before the child program has been exec'd;
+ and when running some kinds of remote stuff (FIXME?). */
+
+extern int stop_soon_quietly;
+
+/* Nonzero if proceed is being used for a "finish" command or a similar
+ situation when stop_registers should be saved. */
+
+extern int proceed_to_finish;
+
+/* Save register contents here when about to pop a stack dummy frame,
+ if-and-only-if proceed_to_finish is set.
+ Thus this contains the return value from the called function (assuming
+ values are returned in a register). */
+
+extern char *stop_registers;
+
+/* Nonzero if the child process in inferior_ptid was attached rather
+ than forked. */
+
+extern int attach_flag;
+
+/* Possible values for CALL_DUMMY_LOCATION. */
+#define ON_STACK 1
+#define BEFORE_TEXT_END 2
+#define AFTER_TEXT_END 3
+#define AT_ENTRY_POINT 4
+
+#if !defined (USE_GENERIC_DUMMY_FRAMES)
+#define USE_GENERIC_DUMMY_FRAMES 0
+#endif
+
+#if !defined (CALL_DUMMY_LOCATION)
+#define CALL_DUMMY_LOCATION ON_STACK
+#endif /* No CALL_DUMMY_LOCATION. */
+
+#if !defined (CALL_DUMMY_ADDRESS)
+#define CALL_DUMMY_ADDRESS() (internal_error (__FILE__, __LINE__, "CALL_DUMMY_ADDRESS"), 0)
+#endif
+#if !defined (CALL_DUMMY_START_OFFSET)
+#define CALL_DUMMY_START_OFFSET (internal_error (__FILE__, __LINE__, "CALL_DUMMY_START_OFFSET"), 0)
+#endif
+#if !defined (CALL_DUMMY_BREAKPOINT_OFFSET)
+#define CALL_DUMMY_BREAKPOINT_OFFSET_P (0)
+#define CALL_DUMMY_BREAKPOINT_OFFSET (internal_error (__FILE__, __LINE__, "CALL_DUMMY_BREAKPOINT_OFFSET"), 0)
+#endif
+#if !defined CALL_DUMMY_BREAKPOINT_OFFSET_P
+#define CALL_DUMMY_BREAKPOINT_OFFSET_P (1)
+#endif
+#if !defined (CALL_DUMMY_LENGTH)
+#define CALL_DUMMY_LENGTH (internal_error (__FILE__, __LINE__, "CALL_DUMMY_LENGTH"), 0)
+#endif
+
+#if defined (CALL_DUMMY_STACK_ADJUST)
+#if !defined (CALL_DUMMY_STACK_ADJUST_P)
+#define CALL_DUMMY_STACK_ADJUST_P (1)
+#endif
+#endif
+#if !defined (CALL_DUMMY_STACK_ADJUST)
+#define CALL_DUMMY_STACK_ADJUST (internal_error (__FILE__, __LINE__, "CALL_DUMMY_STACK_ADJUST"), 0)
+#endif
+#if !defined (CALL_DUMMY_STACK_ADJUST_P)
+#define CALL_DUMMY_STACK_ADJUST_P (0)
+#endif
+
+/* FIXME: cagney/2000-04-17: gdbarch should manage this. The default
+ shouldn't be necessary. */
+
+#if !defined (CALL_DUMMY_P)
+#if defined (CALL_DUMMY)
+#define CALL_DUMMY_P 1
+#else
+#define CALL_DUMMY_P 0
+#endif
+#endif
+
+#if !defined PUSH_DUMMY_FRAME
+#define PUSH_DUMMY_FRAME (internal_error (__FILE__, __LINE__, "PUSH_DUMMY_FRAME"), 0)
+#endif
+
+#if !defined FIX_CALL_DUMMY
+#define FIX_CALL_DUMMY(a1,a2,a3,a4,a5,a6,a7) (internal_error (__FILE__, __LINE__, "FIX_CALL_DUMMY"), 0)
+#endif
+
+#if !defined STORE_STRUCT_RETURN
+#define STORE_STRUCT_RETURN(a1,a2) (internal_error (__FILE__, __LINE__, "STORE_STRUCT_RETURN"), 0)
+#endif
+
+
+/* Are we in a call dummy? */
+
+extern int pc_in_call_dummy_before_text_end (CORE_ADDR pc, CORE_ADDR sp,
+ CORE_ADDR frame_address);
+#if !GDB_MULTI_ARCH
+#if !defined (PC_IN_CALL_DUMMY) && CALL_DUMMY_LOCATION == BEFORE_TEXT_END
+#define PC_IN_CALL_DUMMY(pc, sp, frame_address) pc_in_call_dummy_before_text_end (pc, sp, frame_address)
+#endif /* Before text_end. */
+#endif
+
+extern int pc_in_call_dummy_after_text_end (CORE_ADDR pc, CORE_ADDR sp,
+ CORE_ADDR frame_address);
+#if !GDB_MULTI_ARCH
+#if !defined (PC_IN_CALL_DUMMY) && CALL_DUMMY_LOCATION == AFTER_TEXT_END
+#define PC_IN_CALL_DUMMY(pc, sp, frame_address) pc_in_call_dummy_after_text_end (pc, sp, frame_address)
+#endif
+#endif
+
+extern int pc_in_call_dummy_on_stack (CORE_ADDR pc, CORE_ADDR sp,
+ CORE_ADDR frame_address);
+#if !GDB_MULTI_ARCH
+#if !defined (PC_IN_CALL_DUMMY) && CALL_DUMMY_LOCATION == ON_STACK
+#define PC_IN_CALL_DUMMY(pc, sp, frame_address) pc_in_call_dummy_on_stack (pc, sp, frame_address)
+#endif
+#endif
+
+extern int pc_in_call_dummy_at_entry_point (CORE_ADDR pc, CORE_ADDR sp,
+ CORE_ADDR frame_address);
+#if !GDB_MULTI_ARCH
+#if !defined (PC_IN_CALL_DUMMY) && CALL_DUMMY_LOCATION == AT_ENTRY_POINT
+#define PC_IN_CALL_DUMMY(pc, sp, frame_address) pc_in_call_dummy_at_entry_point (pc, sp, frame_address)
+#endif
+#endif
+
+/* It's often not enough for our clients to know whether the PC is merely
+ somewhere within the call dummy. They may need to know whether the
+ call dummy has actually completed. (For example, wait_for_inferior
+ wants to know when it should truly stop because the call dummy has
+ completed. If we're single-stepping because of slow watchpoints,
+ then we may find ourselves stopped at the entry of the call dummy,
+ and want to continue stepping until we reach the end.)
+
+ Note that this macro is intended for targets (like HP-UX) which
+ require more than a single breakpoint in their call dummies, and
+ therefore cannot use the CALL_DUMMY_BREAKPOINT_OFFSET mechanism.
+
+ If a target does define CALL_DUMMY_BREAKPOINT_OFFSET, then this
+ default implementation of CALL_DUMMY_HAS_COMPLETED is sufficient.
+ Else, a target may wish to supply an implementation that works in
+ the presense of multiple breakpoints in its call dummy.
+ */
+#if !defined(CALL_DUMMY_HAS_COMPLETED)
+#define CALL_DUMMY_HAS_COMPLETED(pc, sp, frame_address) \
+ PC_IN_CALL_DUMMY((pc), (sp), (frame_address))
+#endif
+
+/* If STARTUP_WITH_SHELL is set, GDB's "run"
+ will attempts to start up the debugee under a shell.
+ This is in order for argument-expansion to occur. E.g.,
+ (gdb) run *
+ The "*" gets expanded by the shell into a list of files.
+ While this is a nice feature, it turns out to interact badly
+ with some of the catch-fork/catch-exec features we have added.
+ In particular, if the shell does any fork/exec's before
+ the exec of the target program, that can confuse GDB.
+ To disable this feature, set STARTUP_WITH_SHELL to 0.
+ To enable this feature, set STARTUP_WITH_SHELL to 1.
+ The catch-exec traps expected during start-up will
+ be 1 if target is not started up with a shell, 2 if it is.
+ - RT
+ If you disable this, you need to decrement
+ START_INFERIOR_TRAPS_EXPECTED in tm.h. */
+#define STARTUP_WITH_SHELL 1
+#if !defined(START_INFERIOR_TRAPS_EXPECTED)
+#define START_INFERIOR_TRAPS_EXPECTED 2
+#endif
+#endif /* !defined (INFERIOR_H) */
diff --git a/gdb/inflow.c b/gdb/inflow.c
new file mode 100644
index 00000000000..526acdfdc7e
--- /dev/null
+++ b/gdb/inflow.c
@@ -0,0 +1,771 @@
+/* Low level interface to ptrace, for GDB when running under Unix.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1998, 1999, 2000, 2001 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "command.h"
+#include "serial.h"
+#include "terminal.h"
+#include "target.h"
+#include "gdbthread.h"
+
+#include "gdb_string.h"
+#include <signal.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#ifdef HAVE_TERMIOS
+#define PROCESS_GROUP_TYPE pid_t
+#endif
+
+#ifdef HAVE_TERMIO
+#define PROCESS_GROUP_TYPE int
+#endif
+
+#ifdef HAVE_SGTTY
+#ifdef SHORT_PGRP
+/* This is only used for the ultra. Does it have pid_t? */
+#define PROCESS_GROUP_TYPE short
+#else
+#define PROCESS_GROUP_TYPE int
+#endif
+#endif /* sgtty */
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#if defined (SIGIO) && defined (FASYNC) && defined (FD_SET) && defined (F_SETOWN)
+static void handle_sigio (int);
+#endif
+
+extern void _initialize_inflow (void);
+
+static void pass_signal (int);
+
+static void kill_command (char *, int);
+
+static void terminal_ours_1 (int);
+
+/* Record terminal status separately for debugger and inferior. */
+
+static struct serial *stdin_serial;
+
+/* TTY state for the inferior. We save it whenever the inferior stops, and
+ restore it when it resumes. */
+static serial_ttystate inferior_ttystate;
+
+/* Our own tty state, which we restore every time we need to deal with the
+ terminal. We only set it once, when GDB first starts. The settings of
+ flags which readline saves and restores and unimportant. */
+static serial_ttystate our_ttystate;
+
+/* fcntl flags for us and the inferior. Saved and restored just like
+ {our,inferior}_ttystate. */
+static int tflags_inferior;
+static int tflags_ours;
+
+#ifdef PROCESS_GROUP_TYPE
+/* Process group for us and the inferior. Saved and restored just like
+ {our,inferior}_ttystate. */
+PROCESS_GROUP_TYPE our_process_group;
+PROCESS_GROUP_TYPE inferior_process_group;
+#endif
+
+/* While the inferior is running, we want SIGINT and SIGQUIT to go to the
+ inferior only. If we have job control, that takes care of it. If not,
+ we save our handlers in these two variables and set SIGINT and SIGQUIT
+ to SIG_IGN. */
+
+static void (*sigint_ours) ();
+static void (*sigquit_ours) ();
+
+/* The name of the tty (from the `tty' command) that we gave to the inferior
+ when it was last started. */
+
+static char *inferior_thisrun_terminal;
+
+/* Nonzero if our terminal settings are in effect. Zero if the
+ inferior's settings are in effect. Ignored if !gdb_has_a_terminal
+ (). */
+
+int terminal_is_ours;
+
+enum
+ {
+ yes, no, have_not_checked
+ }
+gdb_has_a_terminal_flag = have_not_checked;
+
+/* Does GDB have a terminal (on stdin)? */
+int
+gdb_has_a_terminal (void)
+{
+ switch (gdb_has_a_terminal_flag)
+ {
+ case yes:
+ return 1;
+ case no:
+ return 0;
+ case have_not_checked:
+ /* Get all the current tty settings (including whether we have a
+ tty at all!). Can't do this in _initialize_inflow because
+ serial_fdopen() won't work until the serial_ops_list is
+ initialized. */
+
+#ifdef F_GETFL
+ tflags_ours = fcntl (0, F_GETFL, 0);
+#endif
+
+ gdb_has_a_terminal_flag = no;
+ stdin_serial = serial_fdopen (0);
+ if (stdin_serial != NULL)
+ {
+ our_ttystate = serial_get_tty_state (stdin_serial);
+
+ if (our_ttystate != NULL)
+ {
+ gdb_has_a_terminal_flag = yes;
+#ifdef HAVE_TERMIOS
+ our_process_group = tcgetpgrp (0);
+#endif
+#ifdef HAVE_TERMIO
+ our_process_group = getpgrp ();
+#endif
+#ifdef HAVE_SGTTY
+ ioctl (0, TIOCGPGRP, &our_process_group);
+#endif
+ }
+ }
+
+ return gdb_has_a_terminal_flag == yes;
+ default:
+ /* "Can't happen". */
+ return 0;
+ }
+}
+
+/* Macro for printing errors from ioctl operations */
+
+#define OOPSY(what) \
+ if (result == -1) \
+ fprintf_unfiltered(gdb_stderr, "[%s failed in terminal_inferior: %s]\n", \
+ what, safe_strerror (errno))
+
+static void terminal_ours_1 (int);
+
+/* Initialize the terminal settings we record for the inferior,
+ before we actually run the inferior. */
+
+void
+terminal_init_inferior_with_pgrp (int pgrp)
+{
+ if (gdb_has_a_terminal ())
+ {
+ /* We could just as well copy our_ttystate (if we felt like
+ adding a new function serial_copy_tty_state()). */
+ if (inferior_ttystate)
+ xfree (inferior_ttystate);
+ inferior_ttystate = serial_get_tty_state (stdin_serial);
+
+#ifdef PROCESS_GROUP_TYPE
+ inferior_process_group = pgrp;
+#endif
+
+ /* Make sure that next time we call terminal_inferior (which will be
+ before the program runs, as it needs to be), we install the new
+ process group. */
+ terminal_is_ours = 1;
+ }
+}
+
+void
+terminal_init_inferior (void)
+{
+#ifdef PROCESS_GROUP_TYPE
+ /* This is for Lynx, and should be cleaned up by having Lynx be a separate
+ debugging target with a version of target_terminal_init_inferior which
+ passes in the process group to a generic routine which does all the work
+ (and the non-threaded child_terminal_init_inferior can just pass in
+ inferior_ptid to the same routine). */
+ /* We assume INFERIOR_PID is also the child's process group. */
+ terminal_init_inferior_with_pgrp (PIDGET (inferior_ptid));
+#endif /* PROCESS_GROUP_TYPE */
+}
+
+/* Put the inferior's terminal settings into effect.
+ This is preparation for starting or resuming the inferior. */
+
+void
+terminal_inferior (void)
+{
+ if (gdb_has_a_terminal () && terminal_is_ours
+ && inferior_thisrun_terminal == 0)
+ {
+ int result;
+
+#ifdef F_GETFL
+ /* Is there a reason this is being done twice? It happens both
+ places we use F_SETFL, so I'm inclined to think perhaps there
+ is some reason, however perverse. Perhaps not though... */
+ result = fcntl (0, F_SETFL, tflags_inferior);
+ result = fcntl (0, F_SETFL, tflags_inferior);
+ OOPSY ("fcntl F_SETFL");
+#endif
+
+ /* Because we were careful to not change in or out of raw mode in
+ terminal_ours, we will not change in our out of raw mode with
+ this call, so we don't flush any input. */
+ result = serial_set_tty_state (stdin_serial, inferior_ttystate);
+ OOPSY ("setting tty state");
+
+ if (!job_control)
+ {
+ sigint_ours = (void (*)()) signal (SIGINT, SIG_IGN);
+#ifdef SIGQUIT
+ sigquit_ours = (void (*)()) signal (SIGQUIT, SIG_IGN);
+#endif
+ }
+
+ /* If attach_flag is set, we don't know whether we are sharing a
+ terminal with the inferior or not. (attaching a process
+ without a terminal is one case where we do not; attaching a
+ process which we ran from the same shell as GDB via `&' is
+ one case where we do, I think (but perhaps this is not
+ `sharing' in the sense that we need to save and restore tty
+ state)). I don't know if there is any way to tell whether we
+ are sharing a terminal. So what we do is to go through all
+ the saving and restoring of the tty state, but ignore errors
+ setting the process group, which will happen if we are not
+ sharing a terminal). */
+
+ if (job_control)
+ {
+#ifdef HAVE_TERMIOS
+ result = tcsetpgrp (0, inferior_process_group);
+ if (!attach_flag)
+ OOPSY ("tcsetpgrp");
+#endif
+
+#ifdef HAVE_SGTTY
+ result = ioctl (0, TIOCSPGRP, &inferior_process_group);
+ if (!attach_flag)
+ OOPSY ("TIOCSPGRP");
+#endif
+ }
+
+ }
+ terminal_is_ours = 0;
+}
+
+/* Put some of our terminal settings into effect,
+ enough to get proper results from our output,
+ but do not change into or out of RAW mode
+ so that no input is discarded.
+
+ After doing this, either terminal_ours or terminal_inferior
+ should be called to get back to a normal state of affairs. */
+
+void
+terminal_ours_for_output (void)
+{
+ terminal_ours_1 (1);
+}
+
+/* Put our terminal settings into effect.
+ First record the inferior's terminal settings
+ so they can be restored properly later. */
+
+void
+terminal_ours (void)
+{
+ terminal_ours_1 (0);
+}
+
+/* output_only is not used, and should not be used unless we introduce
+ separate terminal_is_ours and terminal_is_ours_for_output
+ flags. */
+
+static void
+terminal_ours_1 (int output_only)
+{
+ /* Checking inferior_thisrun_terminal is necessary so that
+ if GDB is running in the background, it won't block trying
+ to do the ioctl()'s below. Checking gdb_has_a_terminal
+ avoids attempting all the ioctl's when running in batch. */
+ if (inferior_thisrun_terminal != 0 || gdb_has_a_terminal () == 0)
+ return;
+
+ if (!terminal_is_ours)
+ {
+#ifdef SIGTTOU
+ /* Ignore this signal since it will happen when we try to set the
+ pgrp. */
+ void (*osigttou) () = NULL;
+#endif
+ int result;
+
+ terminal_is_ours = 1;
+
+#ifdef SIGTTOU
+ if (job_control)
+ osigttou = (void (*)()) signal (SIGTTOU, SIG_IGN);
+#endif
+
+ if (inferior_ttystate)
+ xfree (inferior_ttystate);
+ inferior_ttystate = serial_get_tty_state (stdin_serial);
+#ifdef HAVE_TERMIOS
+ inferior_process_group = tcgetpgrp (0);
+#endif
+#ifdef HAVE_TERMIO
+ inferior_process_group = getpgrp ();
+#endif
+#ifdef HAVE_SGTTY
+ ioctl (0, TIOCGPGRP, &inferior_process_group);
+#endif
+
+ /* Here we used to set ICANON in our ttystate, but I believe this
+ was an artifact from before when we used readline. Readline sets
+ the tty state when it needs to.
+ FIXME-maybe: However, query() expects non-raw mode and doesn't
+ use readline. Maybe query should use readline (on the other hand,
+ this only matters for HAVE_SGTTY, not termio or termios, I think). */
+
+ /* Set tty state to our_ttystate. We don't change in our out of raw
+ mode, to avoid flushing input. We need to do the same thing
+ regardless of output_only, because we don't have separate
+ terminal_is_ours and terminal_is_ours_for_output flags. It's OK,
+ though, since readline will deal with raw mode when/if it needs to.
+ */
+
+ serial_noflush_set_tty_state (stdin_serial, our_ttystate,
+ inferior_ttystate);
+
+ if (job_control)
+ {
+#ifdef HAVE_TERMIOS
+ result = tcsetpgrp (0, our_process_group);
+#if 0
+ /* This fails on Ultrix with EINVAL if you run the testsuite
+ in the background with nohup, and then log out. GDB never
+ used to check for an error here, so perhaps there are other
+ such situations as well. */
+ if (result == -1)
+ fprintf_unfiltered (gdb_stderr, "[tcsetpgrp failed in terminal_ours: %s]\n",
+ safe_strerror (errno));
+#endif
+#endif /* termios */
+
+#ifdef HAVE_SGTTY
+ result = ioctl (0, TIOCSPGRP, &our_process_group);
+#endif
+ }
+
+#ifdef SIGTTOU
+ if (job_control)
+ signal (SIGTTOU, osigttou);
+#endif
+
+ if (!job_control)
+ {
+ signal (SIGINT, sigint_ours);
+#ifdef SIGQUIT
+ signal (SIGQUIT, sigquit_ours);
+#endif
+ }
+
+#ifdef F_GETFL
+ tflags_inferior = fcntl (0, F_GETFL, 0);
+
+ /* Is there a reason this is being done twice? It happens both
+ places we use F_SETFL, so I'm inclined to think perhaps there
+ is some reason, however perverse. Perhaps not though... */
+ result = fcntl (0, F_SETFL, tflags_ours);
+ result = fcntl (0, F_SETFL, tflags_ours);
+#endif
+
+ result = result; /* lint */
+ }
+}
+
+/* ARGSUSED */
+void
+term_info (char *arg, int from_tty)
+{
+ target_terminal_info (arg, from_tty);
+}
+
+/* ARGSUSED */
+void
+child_terminal_info (char *args, int from_tty)
+{
+ if (!gdb_has_a_terminal ())
+ {
+ printf_filtered ("This GDB does not control a terminal.\n");
+ return;
+ }
+
+ printf_filtered ("Inferior's terminal status (currently saved by GDB):\n");
+
+ /* First the fcntl flags. */
+ {
+ int flags;
+
+ flags = tflags_inferior;
+
+ printf_filtered ("File descriptor flags = ");
+
+#ifndef O_ACCMODE
+#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
+#endif
+ /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
+ switch (flags & (O_ACCMODE))
+ {
+ case O_RDONLY:
+ printf_filtered ("O_RDONLY");
+ break;
+ case O_WRONLY:
+ printf_filtered ("O_WRONLY");
+ break;
+ case O_RDWR:
+ printf_filtered ("O_RDWR");
+ break;
+ }
+ flags &= ~(O_ACCMODE);
+
+#ifdef O_NONBLOCK
+ if (flags & O_NONBLOCK)
+ printf_filtered (" | O_NONBLOCK");
+ flags &= ~O_NONBLOCK;
+#endif
+
+#if defined (O_NDELAY)
+ /* If O_NDELAY and O_NONBLOCK are defined to the same thing, we will
+ print it as O_NONBLOCK, which is good cause that is what POSIX
+ has, and the flag will already be cleared by the time we get here. */
+ if (flags & O_NDELAY)
+ printf_filtered (" | O_NDELAY");
+ flags &= ~O_NDELAY;
+#endif
+
+ if (flags & O_APPEND)
+ printf_filtered (" | O_APPEND");
+ flags &= ~O_APPEND;
+
+#if defined (O_BINARY)
+ if (flags & O_BINARY)
+ printf_filtered (" | O_BINARY");
+ flags &= ~O_BINARY;
+#endif
+
+ if (flags)
+ printf_filtered (" | 0x%x", flags);
+ printf_filtered ("\n");
+ }
+
+#ifdef PROCESS_GROUP_TYPE
+ printf_filtered ("Process group = %d\n",
+ (int) inferior_process_group);
+#endif
+
+ serial_print_tty_state (stdin_serial, inferior_ttystate, gdb_stdout);
+}
+
+/* NEW_TTY_PREFORK is called before forking a new child process,
+ so we can record the state of ttys in the child to be formed.
+ TTYNAME is null if we are to share the terminal with gdb;
+ or points to a string containing the name of the desired tty.
+
+ NEW_TTY is called in new child processes under Unix, which will
+ become debugger target processes. This actually switches to
+ the terminal specified in the NEW_TTY_PREFORK call. */
+
+void
+new_tty_prefork (char *ttyname)
+{
+ /* Save the name for later, for determining whether we and the child
+ are sharing a tty. */
+ inferior_thisrun_terminal = ttyname;
+}
+
+void
+new_tty (void)
+{
+ register int tty;
+
+ if (inferior_thisrun_terminal == 0)
+ return;
+#if !defined(__GO32__) && !defined(_WIN32)
+#ifdef TIOCNOTTY
+ /* Disconnect the child process from our controlling terminal. On some
+ systems (SVR4 for example), this may cause a SIGTTOU, so temporarily
+ ignore SIGTTOU. */
+ tty = open ("/dev/tty", O_RDWR);
+ if (tty > 0)
+ {
+ void (*osigttou) ();
+
+ osigttou = (void (*)()) signal (SIGTTOU, SIG_IGN);
+ ioctl (tty, TIOCNOTTY, 0);
+ close (tty);
+ signal (SIGTTOU, osigttou);
+ }
+#endif
+
+ /* Now open the specified new terminal. */
+
+#ifdef USE_O_NOCTTY
+ tty = open (inferior_thisrun_terminal, O_RDWR | O_NOCTTY);
+#else
+ tty = open (inferior_thisrun_terminal, O_RDWR);
+#endif
+ if (tty == -1)
+ {
+ print_sys_errmsg (inferior_thisrun_terminal, errno);
+ _exit (1);
+ }
+
+ /* Avoid use of dup2; doesn't exist on all systems. */
+ if (tty != 0)
+ {
+ close (0);
+ dup (tty);
+ }
+ if (tty != 1)
+ {
+ close (1);
+ dup (tty);
+ }
+ if (tty != 2)
+ {
+ close (2);
+ dup (tty);
+ }
+ if (tty > 2)
+ close (tty);
+#endif /* !go32 && !win32 */
+}
+
+/* Kill the inferior process. Make us have no inferior. */
+
+/* ARGSUSED */
+static void
+kill_command (char *arg, int from_tty)
+{
+ /* FIXME: This should not really be inferior_ptid (or target_has_execution).
+ It should be a distinct flag that indicates that a target is active, cuz
+ some targets don't have processes! */
+
+ if (ptid_equal (inferior_ptid, null_ptid))
+ error ("The program is not being run.");
+ if (!query ("Kill the program being debugged? "))
+ error ("Not confirmed.");
+ target_kill ();
+
+ init_thread_list (); /* Destroy thread info */
+
+ /* Killing off the inferior can leave us with a core file. If so,
+ print the state we are left in. */
+ if (target_has_stack)
+ {
+ printf_filtered ("In %s,\n", target_longname);
+ if (selected_frame == NULL)
+ fputs_filtered ("No selected stack frame.\n", gdb_stdout);
+ else
+ print_stack_frame (selected_frame,
+ frame_relative_level (selected_frame), 1);
+ }
+}
+
+/* Call set_sigint_trap when you need to pass a signal on to an attached
+ process when handling SIGINT */
+
+/* ARGSUSED */
+static void
+pass_signal (int signo)
+{
+#ifndef _WIN32
+ kill (PIDGET (inferior_ptid), SIGINT);
+#endif
+}
+
+static void (*osig) ();
+
+void
+set_sigint_trap (void)
+{
+ if (attach_flag || inferior_thisrun_terminal)
+ {
+ osig = (void (*)()) signal (SIGINT, pass_signal);
+ }
+}
+
+void
+clear_sigint_trap (void)
+{
+ if (attach_flag || inferior_thisrun_terminal)
+ {
+ signal (SIGINT, osig);
+ }
+}
+
+#if defined (SIGIO) && defined (FASYNC) && defined (FD_SET) && defined (F_SETOWN)
+static void (*old_sigio) ();
+
+static void
+handle_sigio (int signo)
+{
+ int numfds;
+ fd_set readfds;
+
+ signal (SIGIO, handle_sigio);
+
+ FD_ZERO (&readfds);
+ FD_SET (target_activity_fd, &readfds);
+ numfds = select (target_activity_fd + 1, &readfds, NULL, NULL, NULL);
+ if (numfds >= 0 && FD_ISSET (target_activity_fd, &readfds))
+ {
+#ifndef _WIN32
+ if ((*target_activity_function) ())
+ kill (PIDGET (inferior_ptid), SIGINT);
+#endif
+ }
+}
+
+static int old_fcntl_flags;
+
+void
+set_sigio_trap (void)
+{
+ if (target_activity_function)
+ {
+ old_sigio = (void (*)()) signal (SIGIO, handle_sigio);
+ fcntl (target_activity_fd, F_SETOWN, getpid ());
+ old_fcntl_flags = fcntl (target_activity_fd, F_GETFL, 0);
+ fcntl (target_activity_fd, F_SETFL, old_fcntl_flags | FASYNC);
+ }
+}
+
+void
+clear_sigio_trap (void)
+{
+ if (target_activity_function)
+ {
+ signal (SIGIO, old_sigio);
+ fcntl (target_activity_fd, F_SETFL, old_fcntl_flags);
+ }
+}
+#else /* No SIGIO. */
+void
+set_sigio_trap (void)
+{
+ if (target_activity_function)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+}
+
+void
+clear_sigio_trap (void)
+{
+ if (target_activity_function)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+}
+#endif /* No SIGIO. */
+
+
+/* This is here because this is where we figure out whether we (probably)
+ have job control. Just using job_control only does part of it because
+ setpgid or setpgrp might not exist on a system without job control.
+ It might be considered misplaced (on the other hand, process groups and
+ job control are closely related to ttys).
+
+ For a more clean implementation, in libiberty, put a setpgid which merely
+ calls setpgrp and a setpgrp which does nothing (any system with job control
+ will have one or the other). */
+int
+gdb_setpgid (void)
+{
+ int retval = 0;
+
+ if (job_control)
+ {
+#if defined (HAVE_TERMIOS) || defined (TIOCGPGRP)
+#ifdef HAVE_SETPGID
+ /* The call setpgid (0, 0) is supposed to work and mean the same
+ thing as this, but on Ultrix 4.2A it fails with EPERM (and
+ setpgid (getpid (), getpid ()) succeeds). */
+ retval = setpgid (getpid (), getpid ());
+#else
+#ifdef HAVE_SETPGRP
+#ifdef SETPGRP_VOID
+ retval = setpgrp ();
+#else
+ retval = setpgrp (getpid (), getpid ());
+#endif
+#endif /* HAVE_SETPGRP */
+#endif /* HAVE_SETPGID */
+#endif /* defined (HAVE_TERMIOS) || defined (TIOCGPGRP) */
+ }
+
+ return retval;
+}
+
+void
+_initialize_inflow (void)
+{
+ add_info ("terminal", term_info,
+ "Print inferior's saved terminal status.");
+
+ add_com ("kill", class_run, kill_command,
+ "Kill execution of program being debugged.");
+
+ inferior_ptid = null_ptid;
+
+ terminal_is_ours = 1;
+
+ /* OK, figure out whether we have job control. If neither termios nor
+ sgtty (i.e. termio or go32), leave job_control 0. */
+
+#if defined (HAVE_TERMIOS)
+ /* Do all systems with termios have the POSIX way of identifying job
+ control? I hope so. */
+#ifdef _POSIX_JOB_CONTROL
+ job_control = 1;
+#else
+#ifdef _SC_JOB_CONTROL
+ job_control = sysconf (_SC_JOB_CONTROL);
+#else
+ job_control = 0; /* have to assume the worst */
+#endif /* _SC_JOB_CONTROL */
+#endif /* _POSIX_JOB_CONTROL */
+#endif /* HAVE_TERMIOS */
+
+#ifdef HAVE_SGTTY
+#ifdef TIOCGPGRP
+ job_control = 1;
+#else
+ job_control = 0;
+#endif /* TIOCGPGRP */
+#endif /* sgtty */
+}
diff --git a/gdb/infptrace.c b/gdb/infptrace.c
new file mode 100644
index 00000000000..777a5b491ed
--- /dev/null
+++ b/gdb/infptrace.c
@@ -0,0 +1,654 @@
+/* Low level Unix child interface to ptrace, for GDB when running under Unix.
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1998, 1999, 2000, 2001, 2002
+ 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdb_string.h"
+#include "regcache.h"
+
+#include "gdb_wait.h"
+
+#include "command.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <sys/param.h>
+#include "gdb_dirent.h"
+#include <signal.h>
+#include <sys/ioctl.h>
+
+#ifdef HAVE_PTRACE_H
+#include <ptrace.h>
+#else
+#ifdef HAVE_SYS_PTRACE_H
+#include <sys/ptrace.h>
+#endif
+#endif
+
+#if !defined (PT_READ_I)
+#define PT_READ_I 1 /* Read word from text space */
+#endif
+#if !defined (PT_READ_D)
+#define PT_READ_D 2 /* Read word from data space */
+#endif
+#if !defined (PT_READ_U)
+#define PT_READ_U 3 /* Read word from kernel user struct */
+#endif
+#if !defined (PT_WRITE_I)
+#define PT_WRITE_I 4 /* Write word to text space */
+#endif
+#if !defined (PT_WRITE_D)
+#define PT_WRITE_D 5 /* Write word to data space */
+#endif
+#if !defined (PT_WRITE_U)
+#define PT_WRITE_U 6 /* Write word to kernel user struct */
+#endif
+#if !defined (PT_CONTINUE)
+#define PT_CONTINUE 7 /* Continue after signal */
+#endif
+#if !defined (PT_STEP)
+#define PT_STEP 9 /* Set flag for single stepping */
+#endif
+#if !defined (PT_KILL)
+#define PT_KILL 8 /* Send child a SIGKILL signal */
+#endif
+
+#ifndef PT_ATTACH
+#define PT_ATTACH PTRACE_ATTACH
+#endif
+#ifndef PT_DETACH
+#define PT_DETACH PTRACE_DETACH
+#endif
+
+#include "gdbcore.h"
+#ifndef NO_SYS_FILE
+#include <sys/file.h>
+#endif
+#if 0
+/* Don't think this is used anymore. On the sequent (not sure whether it's
+ dynix or ptx or both), it is included unconditionally by sys/user.h and
+ not protected against multiple inclusion. */
+#include "gdb_stat.h"
+#endif
+
+#if !defined (FETCH_INFERIOR_REGISTERS)
+#include <sys/user.h> /* Probably need to poke the user structure */
+#if defined (KERNEL_U_ADDR_BSD)
+#include <a.out.h> /* For struct nlist */
+#endif /* KERNEL_U_ADDR_BSD. */
+#endif /* !FETCH_INFERIOR_REGISTERS */
+
+#if !defined (CHILD_XFER_MEMORY)
+static void udot_info (char *, int);
+#endif
+
+#if !defined (FETCH_INFERIOR_REGISTERS)
+static void fetch_register (int);
+static void store_register (int);
+#endif
+
+void _initialize_kernel_u_addr (void);
+void _initialize_infptrace (void);
+
+
+/* This function simply calls ptrace with the given arguments.
+ It exists so that all calls to ptrace are isolated in this
+ machine-dependent file. */
+int
+call_ptrace (int request, int pid, PTRACE_ARG3_TYPE addr, int data)
+{
+ int pt_status = 0;
+
+#if 0
+ int saved_errno;
+
+ printf ("call_ptrace(request=%d, pid=%d, addr=0x%x, data=0x%x)",
+ request, pid, addr, data);
+#endif
+#if defined(PT_SETTRC)
+ /* If the parent can be told to attach to us, try to do it. */
+ if (request == PT_SETTRC)
+ {
+ errno = 0;
+#if !defined (FIVE_ARG_PTRACE)
+ pt_status = ptrace (PT_SETTRC, pid, addr, data);
+#else
+ /* Deal with HPUX 8.0 braindamage. We never use the
+ calls which require the fifth argument. */
+ pt_status = ptrace (PT_SETTRC, pid, addr, data, 0);
+#endif
+ if (errno)
+ perror_with_name ("ptrace");
+#if 0
+ printf (" = %d\n", pt_status);
+#endif
+ if (pt_status < 0)
+ return pt_status;
+ else
+ return parent_attach_all (pid, addr, data);
+ }
+#endif
+
+#if defined(PT_CONTIN1)
+ /* On HPUX, PT_CONTIN1 is a form of continue that preserves pending
+ signals. If it's available, use it. */
+ if (request == PT_CONTINUE)
+ request = PT_CONTIN1;
+#endif
+
+#if defined(PT_SINGLE1)
+ /* On HPUX, PT_SINGLE1 is a form of step that preserves pending
+ signals. If it's available, use it. */
+ if (request == PT_STEP)
+ request = PT_SINGLE1;
+#endif
+
+#if 0
+ saved_errno = errno;
+ errno = 0;
+#endif
+#if !defined (FIVE_ARG_PTRACE)
+ pt_status = ptrace (request, pid, addr, data);
+#else
+ /* Deal with HPUX 8.0 braindamage. We never use the
+ calls which require the fifth argument. */
+ pt_status = ptrace (request, pid, addr, data, 0);
+#endif
+
+#if 0
+ if (errno)
+ printf (" [errno = %d]", errno);
+
+ errno = saved_errno;
+ printf (" = 0x%x\n", pt_status);
+#endif
+ return pt_status;
+}
+
+
+#if defined (DEBUG_PTRACE) || defined (FIVE_ARG_PTRACE)
+/* For the rest of the file, use an extra level of indirection */
+/* This lets us breakpoint usefully on call_ptrace. */
+#define ptrace call_ptrace
+#endif
+
+/* Wait for a process to finish, possibly running a target-specific
+ hook before returning. */
+
+int
+ptrace_wait (ptid_t ptid, int *status)
+{
+ int wstate;
+
+ wstate = wait (status);
+ target_post_wait (pid_to_ptid (wstate), *status);
+ return wstate;
+}
+
+void
+kill_inferior (void)
+{
+ int status;
+ int pid = PIDGET (inferior_ptid);
+
+ if (pid == 0)
+ return;
+
+ /* This once used to call "kill" to kill the inferior just in case
+ the inferior was still running. As others have noted in the past
+ (kingdon) there shouldn't be any way to get here if the inferior
+ is still running -- else there's a major problem elsewere in gdb
+ and it needs to be fixed.
+
+ The kill call causes problems under hpux10, so it's been removed;
+ if this causes problems we'll deal with them as they arise. */
+ ptrace (PT_KILL, pid, (PTRACE_ARG3_TYPE) 0, 0);
+ ptrace_wait (null_ptid, &status);
+ target_mourn_inferior ();
+}
+
+#ifndef CHILD_RESUME
+
+/* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+void
+child_resume (ptid_t ptid, int step, enum target_signal signal)
+{
+ int pid = PIDGET (ptid);
+
+ errno = 0;
+
+ if (pid == -1)
+ /* Resume all threads. */
+ /* I think this only gets used in the non-threaded case, where "resume
+ all threads" and "resume inferior_ptid" are the same. */
+ pid = PIDGET (inferior_ptid);
+
+ /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where
+ it was. (If GDB wanted it to start some other way, we have already
+ written a new PC value to the child.)
+
+ If this system does not support PT_STEP, a higher level function will
+ have called single_step() to transmute the step request into a
+ continue request (by setting breakpoints on all possible successor
+ instructions), so we don't have to worry about that here. */
+
+ if (step)
+ {
+ if (SOFTWARE_SINGLE_STEP_P ())
+ internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* Make sure this doesn't happen. */
+ else
+ ptrace (PT_STEP, pid, (PTRACE_ARG3_TYPE) 1,
+ target_signal_to_host (signal));
+ }
+ else
+ ptrace (PT_CONTINUE, pid, (PTRACE_ARG3_TYPE) 1,
+ target_signal_to_host (signal));
+
+ if (errno)
+ {
+ perror_with_name ("ptrace");
+ }
+}
+#endif /* CHILD_RESUME */
+
+
+#ifdef ATTACH_DETACH
+/* Start debugging the process whose number is PID. */
+int
+attach (int pid)
+{
+ errno = 0;
+ ptrace (PT_ATTACH, pid, (PTRACE_ARG3_TYPE) 0, 0);
+ if (errno)
+ perror_with_name ("ptrace");
+ attach_flag = 1;
+ return pid;
+}
+
+/* Stop debugging the process whose number is PID
+ and continue it with signal number SIGNAL.
+ SIGNAL = 0 means just continue it. */
+
+void
+detach (int signal)
+{
+ errno = 0;
+ ptrace (PT_DETACH, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) 1,
+ signal);
+ if (errno)
+ perror_with_name ("ptrace");
+ attach_flag = 0;
+}
+#endif /* ATTACH_DETACH */
+
+/* Default the type of the ptrace transfer to int. */
+#ifndef PTRACE_XFER_TYPE
+#define PTRACE_XFER_TYPE int
+#endif
+
+/* KERNEL_U_ADDR is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+#if defined (KERNEL_U_ADDR_BSD) && !defined (FETCH_INFERIOR_REGISTERS)
+/* Get kernel_u_addr using BSD-style nlist(). */
+CORE_ADDR kernel_u_addr;
+#endif /* KERNEL_U_ADDR_BSD. */
+
+void
+_initialize_kernel_u_addr (void)
+{
+#if defined (KERNEL_U_ADDR_BSD) && !defined (FETCH_INFERIOR_REGISTERS)
+ struct nlist names[2];
+
+ names[0].n_un.n_name = "_u";
+ names[1].n_un.n_name = NULL;
+ if (nlist ("/vmunix", names) == 0)
+ kernel_u_addr = names[0].n_value;
+ else
+ internal_error (__FILE__, __LINE__,
+ "Unable to get kernel u area address.");
+#endif /* KERNEL_U_ADDR_BSD. */
+}
+
+#if !defined (FETCH_INFERIOR_REGISTERS)
+
+#if !defined (offsetof)
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+#endif
+
+/* U_REGS_OFFSET is the offset of the registers within the u area. */
+#if !defined (U_REGS_OFFSET)
+#define U_REGS_OFFSET \
+ ptrace (PT_READ_U, PIDGET (inferior_ptid), \
+ (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
+ - KERNEL_U_ADDR
+#endif
+
+/* Fetch one register. */
+
+static void
+fetch_register (int regno)
+{
+ /* This isn't really an address. But ptrace thinks of it as one. */
+ CORE_ADDR regaddr;
+ char mess[128]; /* For messages */
+ register int i;
+ unsigned int offset; /* Offset of registers within the u area. */
+ char *buf = alloca (MAX_REGISTER_RAW_SIZE);
+ int tid;
+
+ if (CANNOT_FETCH_REGISTER (regno))
+ {
+ memset (buf, '\0', REGISTER_RAW_SIZE (regno)); /* Supply zeroes */
+ supply_register (regno, buf);
+ return;
+ }
+
+ /* Overload thread id onto process id */
+ if ((tid = TIDGET (inferior_ptid)) == 0)
+ tid = PIDGET (inferior_ptid); /* no thread id, just use process id */
+
+ offset = U_REGS_OFFSET;
+
+ regaddr = register_addr (regno, offset);
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ *(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid,
+ (PTRACE_ARG3_TYPE) regaddr, 0);
+ regaddr += sizeof (PTRACE_XFER_TYPE);
+ if (errno != 0)
+ {
+ sprintf (mess, "reading register %s (#%d)",
+ REGISTER_NAME (regno), regno);
+ perror_with_name (mess);
+ }
+ }
+ supply_register (regno, buf);
+}
+
+
+/* Fetch register values from the inferior.
+ If REGNO is negative, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+fetch_inferior_registers (int regno)
+{
+ if (regno >= 0)
+ {
+ fetch_register (regno);
+ }
+ else
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ {
+ fetch_register (regno);
+ }
+ }
+}
+
+/* Store one register. */
+
+static void
+store_register (int regno)
+{
+ /* This isn't really an address. But ptrace thinks of it as one. */
+ CORE_ADDR regaddr;
+ char mess[128]; /* For messages */
+ register int i;
+ unsigned int offset; /* Offset of registers within the u area. */
+ int tid;
+ char *buf = alloca (MAX_REGISTER_RAW_SIZE);
+
+ if (CANNOT_STORE_REGISTER (regno))
+ {
+ return;
+ }
+
+ /* Overload thread id onto process id */
+ if ((tid = TIDGET (inferior_ptid)) == 0)
+ tid = PIDGET (inferior_ptid); /* no thread id, just use process id */
+
+ offset = U_REGS_OFFSET;
+
+ regaddr = register_addr (regno, offset);
+
+ /* Put the contents of regno into a local buffer */
+ regcache_collect (regno, buf);
+
+ /* Store the local buffer into the inferior a chunk at the time. */
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,
+ *(PTRACE_XFER_TYPE *) (buf + i));
+ regaddr += sizeof (PTRACE_XFER_TYPE);
+ if (errno != 0)
+ {
+ sprintf (mess, "writing register %s (#%d)",
+ REGISTER_NAME (regno), regno);
+ perror_with_name (mess);
+ }
+ }
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is negative, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ if (regno >= 0)
+ {
+ store_register (regno);
+ }
+ else
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ {
+ store_register (regno);
+ }
+ }
+}
+#endif /* !defined (FETCH_INFERIOR_REGISTERS). */
+
+
+/* Set an upper limit on alloca. */
+#ifndef GDB_MAX_ALLOCA
+#define GDB_MAX_ALLOCA 0x1000
+#endif
+
+#if !defined (CHILD_XFER_MEMORY)
+/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
+ in the NEW_SUN_PTRACE case. It ought to be straightforward. But
+ it appears that writing did not write the data that I specified. I
+ cannot understand where it got the data that it actually did write. */
+
+/* Copy LEN bytes to or from inferior's memory starting at MEMADDR to
+ debugger memory starting at MYADDR. Copy to inferior if WRITE is
+ nonzero. TARGET is ignored.
+
+ Returns the length copied, which is either the LEN argument or
+ zero. This xfer function does not do partial moves, since
+ child_ops doesn't allow memory operations to cross below us in the
+ target stack anyway. */
+
+int
+child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib, struct target_ops *target)
+{
+ int i;
+ /* Round starting address down to longword boundary. */
+ CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
+ /* Round ending address up; get number of longwords that makes. */
+ int count = ((((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
+ / sizeof (PTRACE_XFER_TYPE));
+ int alloc = count * sizeof (PTRACE_XFER_TYPE);
+ PTRACE_XFER_TYPE *buffer;
+ struct cleanup *old_chain = NULL;
+
+ /* Allocate buffer of that many longwords. */
+ if (len < GDB_MAX_ALLOCA)
+ {
+ buffer = (PTRACE_XFER_TYPE *) alloca (alloc);
+ }
+ else
+ {
+ buffer = (PTRACE_XFER_TYPE *) xmalloc (alloc);
+ old_chain = make_cleanup (xfree, buffer);
+ }
+
+ if (write)
+ {
+ /* Fill start and end extra bytes of buffer with existing memory
+ data. */
+ if (addr != memaddr || len < (int) sizeof (PTRACE_XFER_TYPE))
+ {
+ /* Need part of initial word -- fetch it. */
+ buffer[0] = ptrace (PT_READ_I, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) addr, 0);
+ }
+
+ if (count > 1) /* FIXME, avoid if even boundary. */
+ {
+ buffer[count - 1] =
+ ptrace (PT_READ_I, PIDGET (inferior_ptid),
+ ((PTRACE_ARG3_TYPE)
+ (addr + (count - 1) * sizeof (PTRACE_XFER_TYPE))), 0);
+ }
+
+ /* Copy data to be written over corresponding part of buffer. */
+ memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
+ myaddr, len);
+
+ /* Write the entire buffer. */
+ for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ ptrace (PT_WRITE_D, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) addr, buffer[i]);
+ if (errno)
+ {
+ /* Using the appropriate one (I or D) is necessary for
+ Gould NP1, at least. */
+ errno = 0;
+ ptrace (PT_WRITE_I, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) addr, buffer[i]);
+ }
+ if (errno)
+ return 0;
+ }
+#ifdef CLEAR_INSN_CACHE
+ CLEAR_INSN_CACHE ();
+#endif
+ }
+ else
+ {
+ /* Read all the longwords. */
+ for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ buffer[i] = ptrace (PT_READ_I, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) addr, 0);
+ if (errno)
+ return 0;
+ QUIT;
+ }
+
+ /* Copy appropriate bytes out of the buffer. */
+ memcpy (myaddr,
+ (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
+ len);
+ }
+
+ if (old_chain != NULL)
+ do_cleanups (old_chain);
+ return len;
+}
+
+
+static void
+udot_info (char *dummy1, int dummy2)
+{
+#if defined (KERNEL_U_SIZE)
+ int udot_off; /* Offset into user struct */
+ int udot_val; /* Value from user struct at udot_off */
+ char mess[128]; /* For messages */
+#endif
+
+ if (!target_has_execution)
+ {
+ error ("The program is not being run.");
+ }
+
+#if !defined (KERNEL_U_SIZE)
+
+ /* Adding support for this command is easy. Typically you just add a
+ routine, called "kernel_u_size" that returns the size of the user
+ struct, to the appropriate *-nat.c file and then add to the native
+ config file "#define KERNEL_U_SIZE kernel_u_size()" */
+ error ("Don't know how large ``struct user'' is in this version of gdb.");
+
+#else
+
+ for (udot_off = 0; udot_off < KERNEL_U_SIZE; udot_off += sizeof (udot_val))
+ {
+ if ((udot_off % 24) == 0)
+ {
+ if (udot_off > 0)
+ {
+ printf_filtered ("\n");
+ }
+ printf_filtered ("%04x:", udot_off);
+ }
+ udot_val = ptrace (PT_READ_U, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) udot_off, 0);
+ if (errno != 0)
+ {
+ sprintf (mess, "\nreading user struct at offset 0x%x", udot_off);
+ perror_with_name (mess);
+ }
+ /* Avoid using nonportable (?) "*" in print specs */
+ printf_filtered (sizeof (int) == 4 ? " 0x%08x" : " 0x%16x", udot_val);
+ }
+ printf_filtered ("\n");
+
+#endif
+}
+#endif /* !defined (CHILD_XFER_MEMORY). */
+
+
+void
+_initialize_infptrace (void)
+{
+#if !defined (CHILD_XFER_MEMORY)
+ add_info ("udot", udot_info,
+ "Print contents of kernel ``struct user'' for current child.");
+#endif
+}
diff --git a/gdb/infrun.c b/gdb/infrun.c
new file mode 100644
index 00000000000..e9fea2a0ac7
--- /dev/null
+++ b/gdb/infrun.c
@@ -0,0 +1,4382 @@
+/* Target-struct-independent code to start (run) and stop an inferior
+ process.
+
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+#include "gdb_string.h"
+#include <ctype.h>
+#include "symtab.h"
+#include "frame.h"
+#include "inferior.h"
+#include "breakpoint.h"
+#include "gdb_wait.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "cli/cli-script.h"
+#include "target.h"
+#include "gdbthread.h"
+#include "annotate.h"
+#include "symfile.h"
+#include "top.h"
+#include <signal.h>
+#include "inf-loop.h"
+#include "regcache.h"
+#include "value.h"
+
+/* Prototypes for local functions */
+
+static void signals_info (char *, int);
+
+static void handle_command (char *, int);
+
+static void sig_print_info (enum target_signal);
+
+static void sig_print_header (void);
+
+static void resume_cleanups (void *);
+
+static int hook_stop_stub (void *);
+
+static void delete_breakpoint_current_contents (void *);
+
+static void set_follow_fork_mode_command (char *arg, int from_tty,
+ struct cmd_list_element * c);
+
+static struct inferior_status *xmalloc_inferior_status (void);
+
+static void free_inferior_status (struct inferior_status *);
+
+static int restore_selected_frame (void *);
+
+static void build_infrun (void);
+
+static void follow_inferior_fork (int parent_pid, int child_pid,
+ int has_forked, int has_vforked);
+
+static void follow_fork (int parent_pid, int child_pid);
+
+static void follow_vfork (int parent_pid, int child_pid);
+
+static void set_schedlock_func (char *args, int from_tty,
+ struct cmd_list_element * c);
+
+struct execution_control_state;
+
+static int currently_stepping (struct execution_control_state *ecs);
+
+static void xdb_handle_command (char *args, int from_tty);
+
+void _initialize_infrun (void);
+
+int inferior_ignoring_startup_exec_events = 0;
+int inferior_ignoring_leading_exec_events = 0;
+
+/* When set, stop the 'step' command if we enter a function which has
+ no line number information. The normal behavior is that we step
+ over such function. */
+int step_stop_if_no_debug = 0;
+
+/* In asynchronous mode, but simulating synchronous execution. */
+
+int sync_execution = 0;
+
+/* wait_for_inferior and normal_stop use this to notify the user
+ when the inferior stopped in a different thread than it had been
+ running in. */
+
+static ptid_t previous_inferior_ptid;
+
+/* This is true for configurations that may follow through execl() and
+ similar functions. At present this is only true for HP-UX native. */
+
+#ifndef MAY_FOLLOW_EXEC
+#define MAY_FOLLOW_EXEC (0)
+#endif
+
+static int may_follow_exec = MAY_FOLLOW_EXEC;
+
+/* Dynamic function trampolines are similar to solib trampolines in that they
+ are between the caller and the callee. The difference is that when you
+ enter a dynamic trampoline, you can't determine the callee's address. Some
+ (usually complex) code needs to run in the dynamic trampoline to figure out
+ the callee's address. This macro is usually called twice. First, when we
+ enter the trampoline (looks like a normal function call at that point). It
+ should return the PC of a point within the trampoline where the callee's
+ address is known. Second, when we hit the breakpoint, this routine returns
+ the callee's address. At that point, things proceed as per a step resume
+ breakpoint. */
+
+#ifndef DYNAMIC_TRAMPOLINE_NEXTPC
+#define DYNAMIC_TRAMPOLINE_NEXTPC(pc) 0
+#endif
+
+/* If the program uses ELF-style shared libraries, then calls to
+ functions in shared libraries go through stubs, which live in a
+ table called the PLT (Procedure Linkage Table). The first time the
+ function is called, the stub sends control to the dynamic linker,
+ which looks up the function's real address, patches the stub so
+ that future calls will go directly to the function, and then passes
+ control to the function.
+
+ If we are stepping at the source level, we don't want to see any of
+ this --- we just want to skip over the stub and the dynamic linker.
+ The simple approach is to single-step until control leaves the
+ dynamic linker.
+
+ However, on some systems (e.g., Red Hat's 5.2 distribution) the
+ dynamic linker calls functions in the shared C library, so you
+ can't tell from the PC alone whether the dynamic linker is still
+ running. In this case, we use a step-resume breakpoint to get us
+ past the dynamic linker, as if we were using "next" to step over a
+ function call.
+
+ IN_SOLIB_DYNSYM_RESOLVE_CODE says whether we're in the dynamic
+ linker code or not. Normally, this means we single-step. However,
+ if SKIP_SOLIB_RESOLVER then returns non-zero, then its value is an
+ address where we can place a step-resume breakpoint to get past the
+ linker's symbol resolution function.
+
+ IN_SOLIB_DYNSYM_RESOLVE_CODE can generally be implemented in a
+ pretty portable way, by comparing the PC against the address ranges
+ of the dynamic linker's sections.
+
+ SKIP_SOLIB_RESOLVER is generally going to be system-specific, since
+ it depends on internal details of the dynamic linker. It's usually
+ not too hard to figure out where to put a breakpoint, but it
+ certainly isn't portable. SKIP_SOLIB_RESOLVER should do plenty of
+ sanity checking. If it can't figure things out, returning zero and
+ getting the (possibly confusing) stepping behavior is better than
+ signalling an error, which will obscure the change in the
+ inferior's state. */
+
+#ifndef IN_SOLIB_DYNSYM_RESOLVE_CODE
+#define IN_SOLIB_DYNSYM_RESOLVE_CODE(pc) 0
+#endif
+
+#ifndef SKIP_SOLIB_RESOLVER
+#define SKIP_SOLIB_RESOLVER(pc) 0
+#endif
+
+/* In some shared library schemes, the return path from a shared library
+ call may need to go through a trampoline too. */
+
+#ifndef IN_SOLIB_RETURN_TRAMPOLINE
+#define IN_SOLIB_RETURN_TRAMPOLINE(pc,name) 0
+#endif
+
+/* This function returns TRUE if pc is the address of an instruction
+ that lies within the dynamic linker (such as the event hook, or the
+ dld itself).
+
+ This function must be used only when a dynamic linker event has
+ been caught, and the inferior is being stepped out of the hook, or
+ undefined results are guaranteed. */
+
+#ifndef SOLIB_IN_DYNAMIC_LINKER
+#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) 0
+#endif
+
+/* On MIPS16, a function that returns a floating point value may call
+ a library helper function to copy the return value to a floating point
+ register. The IGNORE_HELPER_CALL macro returns non-zero if we
+ should ignore (i.e. step over) this function call. */
+#ifndef IGNORE_HELPER_CALL
+#define IGNORE_HELPER_CALL(pc) 0
+#endif
+
+/* On some systems, the PC may be left pointing at an instruction that won't
+ actually be executed. This is usually indicated by a bit in the PSW. If
+ we find ourselves in such a state, then we step the target beyond the
+ nullified instruction before returning control to the user so as to avoid
+ confusion. */
+
+#ifndef INSTRUCTION_NULLIFIED
+#define INSTRUCTION_NULLIFIED 0
+#endif
+
+/* We can't step off a permanent breakpoint in the ordinary way, because we
+ can't remove it. Instead, we have to advance the PC to the next
+ instruction. This macro should expand to a pointer to a function that
+ does that, or zero if we have no such function. If we don't have a
+ definition for it, we have to report an error. */
+#ifndef SKIP_PERMANENT_BREAKPOINT
+#define SKIP_PERMANENT_BREAKPOINT (default_skip_permanent_breakpoint)
+static void
+default_skip_permanent_breakpoint (void)
+{
+ error ("\
+The program is stopped at a permanent breakpoint, but GDB does not know\n\
+how to step past a permanent breakpoint on this architecture. Try using\n\
+a command like `return' or `jump' to continue execution.");
+}
+#endif
+
+
+/* Convert the #defines into values. This is temporary until wfi control
+ flow is completely sorted out. */
+
+#ifndef HAVE_STEPPABLE_WATCHPOINT
+#define HAVE_STEPPABLE_WATCHPOINT 0
+#else
+#undef HAVE_STEPPABLE_WATCHPOINT
+#define HAVE_STEPPABLE_WATCHPOINT 1
+#endif
+
+#ifndef HAVE_NONSTEPPABLE_WATCHPOINT
+#define HAVE_NONSTEPPABLE_WATCHPOINT 0
+#else
+#undef HAVE_NONSTEPPABLE_WATCHPOINT
+#define HAVE_NONSTEPPABLE_WATCHPOINT 1
+#endif
+
+#ifndef HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT 0
+#else
+#undef HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT 1
+#endif
+
+#ifndef CANNOT_STEP_HW_WATCHPOINTS
+#define CANNOT_STEP_HW_WATCHPOINTS 0
+#else
+#undef CANNOT_STEP_HW_WATCHPOINTS
+#define CANNOT_STEP_HW_WATCHPOINTS 1
+#endif
+
+/* Tables of how to react to signals; the user sets them. */
+
+static unsigned char *signal_stop;
+static unsigned char *signal_print;
+static unsigned char *signal_program;
+
+#define SET_SIGS(nsigs,sigs,flags) \
+ do { \
+ int signum = (nsigs); \
+ while (signum-- > 0) \
+ if ((sigs)[signum]) \
+ (flags)[signum] = 1; \
+ } while (0)
+
+#define UNSET_SIGS(nsigs,sigs,flags) \
+ do { \
+ int signum = (nsigs); \
+ while (signum-- > 0) \
+ if ((sigs)[signum]) \
+ (flags)[signum] = 0; \
+ } while (0)
+
+/* Value to pass to target_resume() to cause all threads to resume */
+
+#define RESUME_ALL (pid_to_ptid (-1))
+
+/* Command list pointer for the "stop" placeholder. */
+
+static struct cmd_list_element *stop_command;
+
+/* Nonzero if breakpoints are now inserted in the inferior. */
+
+static int breakpoints_inserted;
+
+/* Function inferior was in as of last step command. */
+
+static struct symbol *step_start_function;
+
+/* Nonzero if we are expecting a trace trap and should proceed from it. */
+
+static int trap_expected;
+
+#ifdef SOLIB_ADD
+/* Nonzero if we want to give control to the user when we're notified
+ of shared library events by the dynamic linker. */
+static int stop_on_solib_events;
+#endif
+
+#ifdef HP_OS_BUG
+/* Nonzero if the next time we try to continue the inferior, it will
+ step one instruction and generate a spurious trace trap.
+ This is used to compensate for a bug in HP-UX. */
+
+static int trap_expected_after_continue;
+#endif
+
+/* Nonzero means expecting a trace trap
+ and should stop the inferior and return silently when it happens. */
+
+int stop_after_trap;
+
+/* Nonzero means expecting a trap and caller will handle it themselves.
+ It is used after attach, due to attaching to a process;
+ when running in the shell before the child program has been exec'd;
+ and when running some kinds of remote stuff (FIXME?). */
+
+int stop_soon_quietly;
+
+/* Nonzero if proceed is being used for a "finish" command or a similar
+ situation when stop_registers should be saved. */
+
+int proceed_to_finish;
+
+/* Save register contents here when about to pop a stack dummy frame,
+ if-and-only-if proceed_to_finish is set.
+ Thus this contains the return value from the called function (assuming
+ values are returned in a register). */
+
+char *stop_registers;
+
+/* Nonzero if program stopped due to error trying to insert breakpoints. */
+
+static int breakpoints_failed;
+
+/* Nonzero after stop if current stack frame should be printed. */
+
+static int stop_print_frame;
+
+static struct breakpoint *step_resume_breakpoint = NULL;
+static struct breakpoint *through_sigtramp_breakpoint = NULL;
+
+/* On some platforms (e.g., HP-UX), hardware watchpoints have bad
+ interactions with an inferior that is running a kernel function
+ (aka, a system call or "syscall"). wait_for_inferior therefore
+ may have a need to know when the inferior is in a syscall. This
+ is a count of the number of inferior threads which are known to
+ currently be running in a syscall. */
+static int number_of_threads_in_syscalls;
+
+/* This is a cached copy of the pid/waitstatus of the last event
+ returned by target_wait()/target_wait_hook(). This information is
+ returned by get_last_target_status(). */
+static ptid_t target_last_wait_ptid;
+static struct target_waitstatus target_last_waitstatus;
+
+/* This is used to remember when a fork, vfork or exec event
+ was caught by a catchpoint, and thus the event is to be
+ followed at the next resume of the inferior, and not
+ immediately. */
+static struct
+ {
+ enum target_waitkind kind;
+ struct
+ {
+ int parent_pid;
+ int saw_parent_fork;
+ int child_pid;
+ int saw_child_fork;
+ int saw_child_exec;
+ }
+ fork_event;
+ char *execd_pathname;
+ }
+pending_follow;
+
+/* Some platforms don't allow us to do anything meaningful with a
+ vforked child until it has exec'd. Vforked processes on such
+ platforms can only be followed after they've exec'd.
+
+ When this is set to 0, a vfork can be immediately followed,
+ and an exec can be followed merely as an exec. When this is
+ set to 1, a vfork event has been seen, but cannot be followed
+ until the exec is seen.
+
+ (In the latter case, inferior_ptid is still the parent of the
+ vfork, and pending_follow.fork_event.child_pid is the child. The
+ appropriate process is followed, according to the setting of
+ follow-fork-mode.) */
+static int follow_vfork_when_exec;
+
+static const char follow_fork_mode_ask[] = "ask";
+static const char follow_fork_mode_both[] = "both";
+static const char follow_fork_mode_child[] = "child";
+static const char follow_fork_mode_parent[] = "parent";
+
+static const char *follow_fork_mode_kind_names[] =
+{
+ follow_fork_mode_ask,
+ /* ??rehrauer: The "both" option is broken, by what may be a 10.20
+ kernel problem. It's also not terribly useful without a GUI to
+ help the user drive two debuggers. So for now, I'm disabling the
+ "both" option. */
+ /* follow_fork_mode_both, */
+ follow_fork_mode_child,
+ follow_fork_mode_parent,
+ NULL
+};
+
+static const char *follow_fork_mode_string = follow_fork_mode_parent;
+
+
+static void
+follow_inferior_fork (int parent_pid, int child_pid, int has_forked,
+ int has_vforked)
+{
+ int followed_parent = 0;
+ int followed_child = 0;
+
+ /* Which process did the user want us to follow? */
+ const char *follow_mode = follow_fork_mode_string;
+
+ /* Or, did the user not know, and want us to ask? */
+ if (follow_fork_mode_string == follow_fork_mode_ask)
+ {
+ internal_error (__FILE__, __LINE__,
+ "follow_inferior_fork: \"ask\" mode not implemented");
+ /* follow_mode = follow_fork_mode_...; */
+ }
+
+ /* If we're to be following the parent, then detach from child_pid.
+ We're already following the parent, so need do nothing explicit
+ for it. */
+ if (follow_mode == follow_fork_mode_parent)
+ {
+ followed_parent = 1;
+
+ /* We're already attached to the parent, by default. */
+
+ /* Before detaching from the child, remove all breakpoints from
+ it. (This won't actually modify the breakpoint list, but will
+ physically remove the breakpoints from the child.) */
+ if (!has_vforked || !follow_vfork_when_exec)
+ {
+ detach_breakpoints (child_pid);
+#ifdef SOLIB_REMOVE_INFERIOR_HOOK
+ SOLIB_REMOVE_INFERIOR_HOOK (child_pid);
+#endif
+ }
+
+ /* Detach from the child. */
+ dont_repeat ();
+
+ target_require_detach (child_pid, "", 1);
+ }
+
+ /* If we're to be following the child, then attach to it, detach
+ from inferior_ptid, and set inferior_ptid to child_pid. */
+ else if (follow_mode == follow_fork_mode_child)
+ {
+ char child_pid_spelling[100]; /* Arbitrary length. */
+
+ followed_child = 1;
+
+ /* Before detaching from the parent, detach all breakpoints from
+ the child. But only if we're forking, or if we follow vforks
+ as soon as they happen. (If we're following vforks only when
+ the child has exec'd, then it's very wrong to try to write
+ back the "shadow contents" of inserted breakpoints now -- they
+ belong to the child's pre-exec'd a.out.) */
+ if (!has_vforked || !follow_vfork_when_exec)
+ {
+ detach_breakpoints (child_pid);
+ }
+
+ /* Before detaching from the parent, remove all breakpoints from it. */
+ remove_breakpoints ();
+
+ /* Also reset the solib inferior hook from the parent. */
+#ifdef SOLIB_REMOVE_INFERIOR_HOOK
+ SOLIB_REMOVE_INFERIOR_HOOK (PIDGET (inferior_ptid));
+#endif
+
+ /* Detach from the parent. */
+ dont_repeat ();
+ target_detach (NULL, 1);
+
+ /* Attach to the child. */
+ inferior_ptid = pid_to_ptid (child_pid);
+ sprintf (child_pid_spelling, "%d", child_pid);
+ dont_repeat ();
+
+ target_require_attach (child_pid_spelling, 1);
+
+ /* Was there a step_resume breakpoint? (There was if the user
+ did a "next" at the fork() call.) If so, explicitly reset its
+ thread number.
+
+ step_resumes are a form of bp that are made to be per-thread.
+ Since we created the step_resume bp when the parent process
+ was being debugged, and now are switching to the child process,
+ from the breakpoint package's viewpoint, that's a switch of
+ "threads". We must update the bp's notion of which thread
+ it is for, or it'll be ignored when it triggers... */
+ if (step_resume_breakpoint &&
+ (!has_vforked || !follow_vfork_when_exec))
+ breakpoint_re_set_thread (step_resume_breakpoint);
+
+ /* Reinsert all breakpoints in the child. (The user may've set
+ breakpoints after catching the fork, in which case those
+ actually didn't get set in the child, but only in the parent.) */
+ if (!has_vforked || !follow_vfork_when_exec)
+ {
+ breakpoint_re_set ();
+ insert_breakpoints ();
+ }
+ }
+
+ /* If we're to be following both parent and child, then fork ourselves,
+ and attach the debugger clone to the child. */
+ else if (follow_mode == follow_fork_mode_both)
+ {
+ char pid_suffix[100]; /* Arbitrary length. */
+
+ /* Clone ourselves to follow the child. This is the end of our
+ involvement with child_pid; our clone will take it from here... */
+ dont_repeat ();
+ target_clone_and_follow_inferior (child_pid, &followed_child);
+ followed_parent = !followed_child;
+
+ /* We continue to follow the parent. To help distinguish the two
+ debuggers, though, both we and our clone will reset our prompts. */
+ sprintf (pid_suffix, "[%d] ", PIDGET (inferior_ptid));
+ set_prompt (strcat (get_prompt (), pid_suffix));
+ }
+
+ /* The parent and child of a vfork share the same address space.
+ Also, on some targets the order in which vfork and exec events
+ are received for parent in child requires some delicate handling
+ of the events.
+
+ For instance, on ptrace-based HPUX we receive the child's vfork
+ event first, at which time the parent has been suspended by the
+ OS and is essentially untouchable until the child's exit or second
+ exec event arrives. At that time, the parent's vfork event is
+ delivered to us, and that's when we see and decide how to follow
+ the vfork. But to get to that point, we must continue the child
+ until it execs or exits. To do that smoothly, all breakpoints
+ must be removed from the child, in case there are any set between
+ the vfork() and exec() calls. But removing them from the child
+ also removes them from the parent, due to the shared-address-space
+ nature of a vfork'd parent and child. On HPUX, therefore, we must
+ take care to restore the bp's to the parent before we continue it.
+ Else, it's likely that we may not stop in the expected place. (The
+ worst scenario is when the user tries to step over a vfork() call;
+ the step-resume bp must be restored for the step to properly stop
+ in the parent after the call completes!)
+
+ Sequence of events, as reported to gdb from HPUX:
+
+ Parent Child Action for gdb to take
+ -------------------------------------------------------
+ 1 VFORK Continue child
+ 2 EXEC
+ 3 EXEC or EXIT
+ 4 VFORK */
+ if (has_vforked)
+ {
+ target_post_follow_vfork (parent_pid,
+ followed_parent,
+ child_pid,
+ followed_child);
+ }
+
+ pending_follow.fork_event.saw_parent_fork = 0;
+ pending_follow.fork_event.saw_child_fork = 0;
+}
+
+static void
+follow_fork (int parent_pid, int child_pid)
+{
+ follow_inferior_fork (parent_pid, child_pid, 1, 0);
+}
+
+
+/* Forward declaration. */
+static void follow_exec (int, char *);
+
+static void
+follow_vfork (int parent_pid, int child_pid)
+{
+ follow_inferior_fork (parent_pid, child_pid, 0, 1);
+
+ /* Did we follow the child? Had it exec'd before we saw the parent vfork? */
+ if (pending_follow.fork_event.saw_child_exec
+ && (PIDGET (inferior_ptid) == child_pid))
+ {
+ pending_follow.fork_event.saw_child_exec = 0;
+ pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
+ follow_exec (PIDGET (inferior_ptid), pending_follow.execd_pathname);
+ xfree (pending_follow.execd_pathname);
+ }
+}
+
+/* EXECD_PATHNAME is assumed to be non-NULL. */
+
+static void
+follow_exec (int pid, char *execd_pathname)
+{
+ int saved_pid = pid;
+ struct target_ops *tgt;
+
+ if (!may_follow_exec)
+ return;
+
+ /* Did this exec() follow a vfork()? If so, we must follow the
+ vfork now too. Do it before following the exec. */
+ if (follow_vfork_when_exec &&
+ (pending_follow.kind == TARGET_WAITKIND_VFORKED))
+ {
+ pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
+ follow_vfork (PIDGET (inferior_ptid),
+ pending_follow.fork_event.child_pid);
+ follow_vfork_when_exec = 0;
+ saved_pid = PIDGET (inferior_ptid);
+
+ /* Did we follow the parent? If so, we're done. If we followed
+ the child then we must also follow its exec(). */
+ if (PIDGET (inferior_ptid) == pending_follow.fork_event.parent_pid)
+ return;
+ }
+
+ /* This is an exec event that we actually wish to pay attention to.
+ Refresh our symbol table to the newly exec'd program, remove any
+ momentary bp's, etc.
+
+ If there are breakpoints, they aren't really inserted now,
+ since the exec() transformed our inferior into a fresh set
+ of instructions.
+
+ We want to preserve symbolic breakpoints on the list, since
+ we have hopes that they can be reset after the new a.out's
+ symbol table is read.
+
+ However, any "raw" breakpoints must be removed from the list
+ (e.g., the solib bp's), since their address is probably invalid
+ now.
+
+ And, we DON'T want to call delete_breakpoints() here, since
+ that may write the bp's "shadow contents" (the instruction
+ value that was overwritten witha TRAP instruction). Since
+ we now have a new a.out, those shadow contents aren't valid. */
+ update_breakpoints_after_exec ();
+
+ /* If there was one, it's gone now. We cannot truly step-to-next
+ statement through an exec(). */
+ step_resume_breakpoint = NULL;
+ step_range_start = 0;
+ step_range_end = 0;
+
+ /* If there was one, it's gone now. */
+ through_sigtramp_breakpoint = NULL;
+
+ /* What is this a.out's name? */
+ printf_unfiltered ("Executing new program: %s\n", execd_pathname);
+
+ /* We've followed the inferior through an exec. Therefore, the
+ inferior has essentially been killed & reborn. */
+
+ /* First collect the run target in effect. */
+ tgt = find_run_target ();
+ /* If we can't find one, things are in a very strange state... */
+ if (tgt == NULL)
+ error ("Could find run target to save before following exec");
+
+ gdb_flush (gdb_stdout);
+ target_mourn_inferior ();
+ inferior_ptid = pid_to_ptid (saved_pid);
+ /* Because mourn_inferior resets inferior_ptid. */
+ push_target (tgt);
+
+ /* That a.out is now the one to use. */
+ exec_file_attach (execd_pathname, 0);
+
+ /* And also is where symbols can be found. */
+ symbol_file_add_main (execd_pathname, 0);
+
+ /* Reset the shared library package. This ensures that we get
+ a shlib event when the child reaches "_start", at which point
+ the dld will have had a chance to initialize the child. */
+#if defined(SOLIB_RESTART)
+ SOLIB_RESTART ();
+#endif
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+ SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
+#endif
+
+ /* Reinsert all breakpoints. (Those which were symbolic have
+ been reset to the proper address in the new a.out, thanks
+ to symbol_file_command...) */
+ insert_breakpoints ();
+
+ /* The next resume of this inferior should bring it to the shlib
+ startup breakpoints. (If the user had also set bp's on
+ "main" from the old (parent) process, then they'll auto-
+ matically get reset there in the new process.) */
+}
+
+/* Non-zero if we just simulating a single-step. This is needed
+ because we cannot remove the breakpoints in the inferior process
+ until after the `wait' in `wait_for_inferior'. */
+static int singlestep_breakpoints_inserted_p = 0;
+
+
+/* Things to clean up if we QUIT out of resume (). */
+/* ARGSUSED */
+static void
+resume_cleanups (void *ignore)
+{
+ normal_stop ();
+}
+
+static const char schedlock_off[] = "off";
+static const char schedlock_on[] = "on";
+static const char schedlock_step[] = "step";
+static const char *scheduler_mode = schedlock_off;
+static const char *scheduler_enums[] =
+{
+ schedlock_off,
+ schedlock_on,
+ schedlock_step,
+ NULL
+};
+
+static void
+set_schedlock_func (char *args, int from_tty, struct cmd_list_element *c)
+{
+ /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones
+ the set command passed as a parameter. The clone operation will
+ include (BUG?) any ``set'' command callback, if present.
+ Commands like ``info set'' call all the ``show'' command
+ callbacks. Unfortunatly, for ``show'' commands cloned from
+ ``set'', this includes callbacks belonging to ``set'' commands.
+ Making this worse, this only occures if add_show_from_set() is
+ called after add_cmd_sfunc() (BUG?). */
+ if (cmd_type (c) == set_cmd)
+ if (!target_can_lock_scheduler)
+ {
+ scheduler_mode = schedlock_off;
+ error ("Target '%s' cannot support this command.",
+ target_shortname);
+ }
+}
+
+
+/* Resume the inferior, but allow a QUIT. This is useful if the user
+ wants to interrupt some lengthy single-stepping operation
+ (for child processes, the SIGINT goes to the inferior, and so
+ we get a SIGINT random_signal, but for remote debugging and perhaps
+ other targets, that's not true).
+
+ STEP nonzero if we should step (zero to continue instead).
+ SIG is the signal to give the inferior (zero for none). */
+void
+resume (int step, enum target_signal sig)
+{
+ int should_resume = 1;
+ struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0);
+ QUIT;
+
+ /* FIXME: calling breakpoint_here_p (read_pc ()) three times! */
+
+
+ /* Some targets (e.g. Solaris x86) have a kernel bug when stepping
+ over an instruction that causes a page fault without triggering
+ a hardware watchpoint. The kernel properly notices that it shouldn't
+ stop, because the hardware watchpoint is not triggered, but it forgets
+ the step request and continues the program normally.
+ Work around the problem by removing hardware watchpoints if a step is
+ requested, GDB will check for a hardware watchpoint trigger after the
+ step anyway. */
+ if (CANNOT_STEP_HW_WATCHPOINTS && step && breakpoints_inserted)
+ remove_hw_watchpoints ();
+
+
+ /* Normally, by the time we reach `resume', the breakpoints are either
+ removed or inserted, as appropriate. The exception is if we're sitting
+ at a permanent breakpoint; we need to step over it, but permanent
+ breakpoints can't be removed. So we have to test for it here. */
+ if (breakpoint_here_p (read_pc ()) == permanent_breakpoint_here)
+ SKIP_PERMANENT_BREAKPOINT ();
+
+ if (SOFTWARE_SINGLE_STEP_P () && step)
+ {
+ /* Do it the hard way, w/temp breakpoints */
+ SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ );
+ /* ...and don't ask hardware to do it. */
+ step = 0;
+ /* and do not pull these breakpoints until after a `wait' in
+ `wait_for_inferior' */
+ singlestep_breakpoints_inserted_p = 1;
+ }
+
+ /* Handle any optimized stores to the inferior NOW... */
+#ifdef DO_DEFERRED_STORES
+ DO_DEFERRED_STORES;
+#endif
+
+ /* If there were any forks/vforks/execs that were caught and are
+ now to be followed, then do so. */
+ switch (pending_follow.kind)
+ {
+ case (TARGET_WAITKIND_FORKED):
+ pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
+ follow_fork (PIDGET (inferior_ptid),
+ pending_follow.fork_event.child_pid);
+ break;
+
+ case (TARGET_WAITKIND_VFORKED):
+ {
+ int saw_child_exec = pending_follow.fork_event.saw_child_exec;
+
+ pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
+ follow_vfork (PIDGET (inferior_ptid),
+ pending_follow.fork_event.child_pid);
+
+ /* Did we follow the child, but not yet see the child's exec event?
+ If so, then it actually ought to be waiting for us; we respond to
+ parent vfork events. We don't actually want to resume the child
+ in this situation; we want to just get its exec event. */
+ if (!saw_child_exec &&
+ (PIDGET (inferior_ptid) == pending_follow.fork_event.child_pid))
+ should_resume = 0;
+ }
+ break;
+
+ case (TARGET_WAITKIND_EXECD):
+ /* If we saw a vfork event but couldn't follow it until we saw
+ an exec, then now might be the time! */
+ pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
+ /* follow_exec is called as soon as the exec event is seen. */
+ break;
+
+ default:
+ break;
+ }
+
+ /* Install inferior's terminal modes. */
+ target_terminal_inferior ();
+
+ if (should_resume)
+ {
+ ptid_t resume_ptid;
+
+ resume_ptid = RESUME_ALL; /* Default */
+
+ if ((step || singlestep_breakpoints_inserted_p) &&
+ !breakpoints_inserted && breakpoint_here_p (read_pc ()))
+ {
+ /* Stepping past a breakpoint without inserting breakpoints.
+ Make sure only the current thread gets to step, so that
+ other threads don't sneak past breakpoints while they are
+ not inserted. */
+
+ resume_ptid = inferior_ptid;
+ }
+
+ if ((scheduler_mode == schedlock_on) ||
+ (scheduler_mode == schedlock_step &&
+ (step || singlestep_breakpoints_inserted_p)))
+ {
+ /* User-settable 'scheduler' mode requires solo thread resume. */
+ resume_ptid = inferior_ptid;
+ }
+
+#ifdef CANNOT_STEP_BREAKPOINT
+ /* Most targets can step a breakpoint instruction, thus executing it
+ normally. But if this one cannot, just continue and we will hit
+ it anyway. */
+ if (step && breakpoints_inserted && breakpoint_here_p (read_pc ()))
+ step = 0;
+#endif
+ target_resume (resume_ptid, step, sig);
+ }
+
+ discard_cleanups (old_cleanups);
+}
+
+
+/* Clear out all variables saying what to do when inferior is continued.
+ First do this, then set the ones you want, then call `proceed'. */
+
+void
+clear_proceed_status (void)
+{
+ trap_expected = 0;
+ step_range_start = 0;
+ step_range_end = 0;
+ step_frame_address = 0;
+ step_over_calls = STEP_OVER_UNDEBUGGABLE;
+ stop_after_trap = 0;
+ stop_soon_quietly = 0;
+ proceed_to_finish = 0;
+ breakpoint_proceeded = 1; /* We're about to proceed... */
+
+ /* Discard any remaining commands or status from previous stop. */
+ bpstat_clear (&stop_bpstat);
+}
+
+/* Basic routine for continuing the program in various fashions.
+
+ ADDR is the address to resume at, or -1 for resume where stopped.
+ SIGGNAL is the signal to give it, or 0 for none,
+ or -1 for act according to how it stopped.
+ STEP is nonzero if should trap after one instruction.
+ -1 means return after that and print nothing.
+ You should probably set various step_... variables
+ before calling here, if you are stepping.
+
+ You should call clear_proceed_status before calling proceed. */
+
+void
+proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
+{
+ int oneproc = 0;
+
+ if (step > 0)
+ step_start_function = find_pc_function (read_pc ());
+ if (step < 0)
+ stop_after_trap = 1;
+
+ if (addr == (CORE_ADDR) -1)
+ {
+ /* If there is a breakpoint at the address we will resume at,
+ step one instruction before inserting breakpoints
+ so that we do not stop right away (and report a second
+ hit at this breakpoint). */
+
+ if (read_pc () == stop_pc && breakpoint_here_p (read_pc ()))
+ oneproc = 1;
+
+#ifndef STEP_SKIPS_DELAY
+#define STEP_SKIPS_DELAY(pc) (0)
+#define STEP_SKIPS_DELAY_P (0)
+#endif
+ /* Check breakpoint_here_p first, because breakpoint_here_p is fast
+ (it just checks internal GDB data structures) and STEP_SKIPS_DELAY
+ is slow (it needs to read memory from the target). */
+ if (STEP_SKIPS_DELAY_P
+ && breakpoint_here_p (read_pc () + 4)
+ && STEP_SKIPS_DELAY (read_pc ()))
+ oneproc = 1;
+ }
+ else
+ {
+ write_pc (addr);
+ }
+
+#ifdef PREPARE_TO_PROCEED
+ /* In a multi-threaded task we may select another thread
+ and then continue or step.
+
+ But if the old thread was stopped at a breakpoint, it
+ will immediately cause another breakpoint stop without
+ any execution (i.e. it will report a breakpoint hit
+ incorrectly). So we must step over it first.
+
+ PREPARE_TO_PROCEED checks the current thread against the thread
+ that reported the most recent event. If a step-over is required
+ it returns TRUE and sets the current thread to the old thread. */
+ if (PREPARE_TO_PROCEED (1) && breakpoint_here_p (read_pc ()))
+ {
+ oneproc = 1;
+ }
+
+#endif /* PREPARE_TO_PROCEED */
+
+#ifdef HP_OS_BUG
+ if (trap_expected_after_continue)
+ {
+ /* If (step == 0), a trap will be automatically generated after
+ the first instruction is executed. Force step one
+ instruction to clear this condition. This should not occur
+ if step is nonzero, but it is harmless in that case. */
+ oneproc = 1;
+ trap_expected_after_continue = 0;
+ }
+#endif /* HP_OS_BUG */
+
+ if (oneproc)
+ /* We will get a trace trap after one instruction.
+ Continue it automatically and insert breakpoints then. */
+ trap_expected = 1;
+ else
+ {
+ int temp = insert_breakpoints ();
+ if (temp)
+ {
+ print_sys_errmsg ("insert_breakpoints", temp);
+ error ("Cannot insert breakpoints.\n\
+The same program may be running in another process,\n\
+or you may have requested too many hardware\n\
+breakpoints and/or watchpoints.\n");
+ }
+
+ breakpoints_inserted = 1;
+ }
+
+ if (siggnal != TARGET_SIGNAL_DEFAULT)
+ stop_signal = siggnal;
+ /* If this signal should not be seen by program,
+ give it zero. Used for debugging signals. */
+ else if (!signal_program[stop_signal])
+ stop_signal = TARGET_SIGNAL_0;
+
+ annotate_starting ();
+
+ /* Make sure that output from GDB appears before output from the
+ inferior. */
+ gdb_flush (gdb_stdout);
+
+ /* Resume inferior. */
+ resume (oneproc || step || bpstat_should_step (), stop_signal);
+
+ /* Wait for it to stop (if not standalone)
+ and in any case decode why it stopped, and act accordingly. */
+ /* Do this only if we are not using the event loop, or if the target
+ does not support asynchronous execution. */
+ if (!event_loop_p || !target_can_async_p ())
+ {
+ wait_for_inferior ();
+ normal_stop ();
+ }
+}
+
+/* Record the pc and sp of the program the last time it stopped.
+ These are just used internally by wait_for_inferior, but need
+ to be preserved over calls to it and cleared when the inferior
+ is started. */
+static CORE_ADDR prev_pc;
+static CORE_ADDR prev_func_start;
+static char *prev_func_name;
+
+
+/* Start remote-debugging of a machine over a serial link. */
+
+void
+start_remote (void)
+{
+ init_thread_list ();
+ init_wait_for_inferior ();
+ stop_soon_quietly = 1;
+ trap_expected = 0;
+
+ /* Always go on waiting for the target, regardless of the mode. */
+ /* FIXME: cagney/1999-09-23: At present it isn't possible to
+ indicate to wait_for_inferior that a target should timeout if
+ nothing is returned (instead of just blocking). Because of this,
+ targets expecting an immediate response need to, internally, set
+ things up so that the target_wait() is forced to eventually
+ timeout. */
+ /* FIXME: cagney/1999-09-24: It isn't possible for target_open() to
+ differentiate to its caller what the state of the target is after
+ the initial open has been performed. Here we're assuming that
+ the target has stopped. It should be possible to eventually have
+ target_open() return to the caller an indication that the target
+ is currently running and GDB state should be set to the same as
+ for an async run. */
+ wait_for_inferior ();
+ normal_stop ();
+}
+
+/* Initialize static vars when a new inferior begins. */
+
+void
+init_wait_for_inferior (void)
+{
+ /* These are meaningless until the first time through wait_for_inferior. */
+ prev_pc = 0;
+ prev_func_start = 0;
+ prev_func_name = NULL;
+
+#ifdef HP_OS_BUG
+ trap_expected_after_continue = 0;
+#endif
+ breakpoints_inserted = 0;
+ breakpoint_init_inferior (inf_starting);
+
+ /* Don't confuse first call to proceed(). */
+ stop_signal = TARGET_SIGNAL_0;
+
+ /* The first resume is not following a fork/vfork/exec. */
+ pending_follow.kind = TARGET_WAITKIND_SPURIOUS; /* I.e., none. */
+ pending_follow.fork_event.saw_parent_fork = 0;
+ pending_follow.fork_event.saw_child_fork = 0;
+ pending_follow.fork_event.saw_child_exec = 0;
+
+ /* See wait_for_inferior's handling of SYSCALL_ENTRY/RETURN events. */
+ number_of_threads_in_syscalls = 0;
+
+ clear_proceed_status ();
+}
+
+static void
+delete_breakpoint_current_contents (void *arg)
+{
+ struct breakpoint **breakpointp = (struct breakpoint **) arg;
+ if (*breakpointp != NULL)
+ {
+ delete_breakpoint (*breakpointp);
+ *breakpointp = NULL;
+ }
+}
+
+/* This enum encodes possible reasons for doing a target_wait, so that
+ wfi can call target_wait in one place. (Ultimately the call will be
+ moved out of the infinite loop entirely.) */
+
+enum infwait_states
+{
+ infwait_normal_state,
+ infwait_thread_hop_state,
+ infwait_nullified_state,
+ infwait_nonstep_watch_state
+};
+
+/* Why did the inferior stop? Used to print the appropriate messages
+ to the interface from within handle_inferior_event(). */
+enum inferior_stop_reason
+{
+ /* We don't know why. */
+ STOP_UNKNOWN,
+ /* Step, next, nexti, stepi finished. */
+ END_STEPPING_RANGE,
+ /* Found breakpoint. */
+ BREAKPOINT_HIT,
+ /* Inferior terminated by signal. */
+ SIGNAL_EXITED,
+ /* Inferior exited. */
+ EXITED,
+ /* Inferior received signal, and user asked to be notified. */
+ SIGNAL_RECEIVED
+};
+
+/* This structure contains what used to be local variables in
+ wait_for_inferior. Probably many of them can return to being
+ locals in handle_inferior_event. */
+
+struct execution_control_state
+ {
+ struct target_waitstatus ws;
+ struct target_waitstatus *wp;
+ int another_trap;
+ int random_signal;
+ CORE_ADDR stop_func_start;
+ CORE_ADDR stop_func_end;
+ char *stop_func_name;
+ struct symtab_and_line sal;
+ int remove_breakpoints_on_following_step;
+ int current_line;
+ struct symtab *current_symtab;
+ int handling_longjmp; /* FIXME */
+ ptid_t ptid;
+ ptid_t saved_inferior_ptid;
+ int update_step_sp;
+ int stepping_through_solib_after_catch;
+ bpstat stepping_through_solib_catchpoints;
+ int enable_hw_watchpoints_after_wait;
+ int stepping_through_sigtramp;
+ int new_thread_event;
+ struct target_waitstatus tmpstatus;
+ enum infwait_states infwait_state;
+ ptid_t waiton_ptid;
+ int wait_some_more;
+ };
+
+void init_execution_control_state (struct execution_control_state * ecs);
+
+void handle_inferior_event (struct execution_control_state * ecs);
+
+static void check_sigtramp2 (struct execution_control_state *ecs);
+static void step_into_function (struct execution_control_state *ecs);
+static void step_over_function (struct execution_control_state *ecs);
+static void stop_stepping (struct execution_control_state *ecs);
+static void prepare_to_wait (struct execution_control_state *ecs);
+static void keep_going (struct execution_control_state *ecs);
+static void print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info);
+
+/* Wait for control to return from inferior to debugger.
+ If inferior gets a signal, we may decide to start it up again
+ instead of returning. That is why there is a loop in this function.
+ When this function actually returns it means the inferior
+ should be left stopped and GDB should read more commands. */
+
+void
+wait_for_inferior (void)
+{
+ struct cleanup *old_cleanups;
+ struct execution_control_state ecss;
+ struct execution_control_state *ecs;
+
+ old_cleanups = make_cleanup (delete_step_resume_breakpoint,
+ &step_resume_breakpoint);
+ make_cleanup (delete_breakpoint_current_contents,
+ &through_sigtramp_breakpoint);
+
+ /* wfi still stays in a loop, so it's OK just to take the address of
+ a local to get the ecs pointer. */
+ ecs = &ecss;
+
+ /* Fill in with reasonable starting values. */
+ init_execution_control_state (ecs);
+
+ /* We'll update this if & when we switch to a new thread. */
+ previous_inferior_ptid = inferior_ptid;
+
+ overlay_cache_invalid = 1;
+
+ /* We have to invalidate the registers BEFORE calling target_wait
+ because they can be loaded from the target while in target_wait.
+ This makes remote debugging a bit more efficient for those
+ targets that provide critical registers as part of their normal
+ status mechanism. */
+
+ registers_changed ();
+
+ while (1)
+ {
+ if (target_wait_hook)
+ ecs->ptid = target_wait_hook (ecs->waiton_ptid, ecs->wp);
+ else
+ ecs->ptid = target_wait (ecs->waiton_ptid, ecs->wp);
+
+ /* Now figure out what to do with the result of the result. */
+ handle_inferior_event (ecs);
+
+ if (!ecs->wait_some_more)
+ break;
+ }
+ do_cleanups (old_cleanups);
+}
+
+/* Asynchronous version of wait_for_inferior. It is called by the
+ event loop whenever a change of state is detected on the file
+ descriptor corresponding to the target. It can be called more than
+ once to complete a single execution command. In such cases we need
+ to keep the state in a global variable ASYNC_ECSS. If it is the
+ last time that this function is called for a single execution
+ command, then report to the user that the inferior has stopped, and
+ do the necessary cleanups. */
+
+struct execution_control_state async_ecss;
+struct execution_control_state *async_ecs;
+
+void
+fetch_inferior_event (void *client_data)
+{
+ static struct cleanup *old_cleanups;
+
+ async_ecs = &async_ecss;
+
+ if (!async_ecs->wait_some_more)
+ {
+ old_cleanups = make_exec_cleanup (delete_step_resume_breakpoint,
+ &step_resume_breakpoint);
+ make_exec_cleanup (delete_breakpoint_current_contents,
+ &through_sigtramp_breakpoint);
+
+ /* Fill in with reasonable starting values. */
+ init_execution_control_state (async_ecs);
+
+ /* We'll update this if & when we switch to a new thread. */
+ previous_inferior_ptid = inferior_ptid;
+
+ overlay_cache_invalid = 1;
+
+ /* We have to invalidate the registers BEFORE calling target_wait
+ because they can be loaded from the target while in target_wait.
+ This makes remote debugging a bit more efficient for those
+ targets that provide critical registers as part of their normal
+ status mechanism. */
+
+ registers_changed ();
+ }
+
+ if (target_wait_hook)
+ async_ecs->ptid = target_wait_hook (async_ecs->waiton_ptid, async_ecs->wp);
+ else
+ async_ecs->ptid = target_wait (async_ecs->waiton_ptid, async_ecs->wp);
+
+ /* Now figure out what to do with the result of the result. */
+ handle_inferior_event (async_ecs);
+
+ if (!async_ecs->wait_some_more)
+ {
+ /* Do only the cleanups that have been added by this
+ function. Let the continuations for the commands do the rest,
+ if there are any. */
+ do_exec_cleanups (old_cleanups);
+ normal_stop ();
+ if (step_multi && stop_step)
+ inferior_event_handler (INF_EXEC_CONTINUE, NULL);
+ else
+ inferior_event_handler (INF_EXEC_COMPLETE, NULL);
+ }
+}
+
+/* Prepare an execution control state for looping through a
+ wait_for_inferior-type loop. */
+
+void
+init_execution_control_state (struct execution_control_state *ecs)
+{
+ /* ecs->another_trap? */
+ ecs->random_signal = 0;
+ ecs->remove_breakpoints_on_following_step = 0;
+ ecs->handling_longjmp = 0; /* FIXME */
+ ecs->update_step_sp = 0;
+ ecs->stepping_through_solib_after_catch = 0;
+ ecs->stepping_through_solib_catchpoints = NULL;
+ ecs->enable_hw_watchpoints_after_wait = 0;
+ ecs->stepping_through_sigtramp = 0;
+ ecs->sal = find_pc_line (prev_pc, 0);
+ ecs->current_line = ecs->sal.line;
+ ecs->current_symtab = ecs->sal.symtab;
+ ecs->infwait_state = infwait_normal_state;
+ ecs->waiton_ptid = pid_to_ptid (-1);
+ ecs->wp = &(ecs->ws);
+}
+
+/* Call this function before setting step_resume_breakpoint, as a
+ sanity check. There should never be more than one step-resume
+ breakpoint per thread, so we should never be setting a new
+ step_resume_breakpoint when one is already active. */
+static void
+check_for_old_step_resume_breakpoint (void)
+{
+ if (step_resume_breakpoint)
+ warning ("GDB bug: infrun.c (wait_for_inferior): dropping old step_resume breakpoint");
+}
+
+/* Return the cached copy of the last pid/waitstatus returned by
+ target_wait()/target_wait_hook(). The data is actually cached by
+ handle_inferior_event(), which gets called immediately after
+ target_wait()/target_wait_hook(). */
+
+void
+get_last_target_status(ptid_t *ptidp, struct target_waitstatus *status)
+{
+ *ptidp = target_last_wait_ptid;
+ *status = target_last_waitstatus;
+}
+
+/* Switch thread contexts, maintaining "infrun state". */
+
+static void
+context_switch (struct execution_control_state *ecs)
+{
+ /* Caution: it may happen that the new thread (or the old one!)
+ is not in the thread list. In this case we must not attempt
+ to "switch context", or we run the risk that our context may
+ be lost. This may happen as a result of the target module
+ mishandling thread creation. */
+
+ if (in_thread_list (inferior_ptid) && in_thread_list (ecs->ptid))
+ { /* Perform infrun state context switch: */
+ /* Save infrun state for the old thread. */
+ save_infrun_state (inferior_ptid, prev_pc,
+ prev_func_start, prev_func_name,
+ trap_expected, step_resume_breakpoint,
+ through_sigtramp_breakpoint, step_range_start,
+ step_range_end, step_frame_address,
+ ecs->handling_longjmp, ecs->another_trap,
+ ecs->stepping_through_solib_after_catch,
+ ecs->stepping_through_solib_catchpoints,
+ ecs->stepping_through_sigtramp,
+ ecs->current_line, ecs->current_symtab,
+ step_sp);
+
+ /* Load infrun state for the new thread. */
+ load_infrun_state (ecs->ptid, &prev_pc,
+ &prev_func_start, &prev_func_name,
+ &trap_expected, &step_resume_breakpoint,
+ &through_sigtramp_breakpoint, &step_range_start,
+ &step_range_end, &step_frame_address,
+ &ecs->handling_longjmp, &ecs->another_trap,
+ &ecs->stepping_through_solib_after_catch,
+ &ecs->stepping_through_solib_catchpoints,
+ &ecs->stepping_through_sigtramp,
+ &ecs->current_line, &ecs->current_symtab,
+ &step_sp);
+ }
+ inferior_ptid = ecs->ptid;
+}
+
+
+/* Given an execution control state that has been freshly filled in
+ by an event from the inferior, figure out what it means and take
+ appropriate action. */
+
+void
+handle_inferior_event (struct execution_control_state *ecs)
+{
+ CORE_ADDR tmp;
+ int stepped_after_stopped_by_watchpoint;
+
+ /* Cache the last pid/waitstatus. */
+ target_last_wait_ptid = ecs->ptid;
+ target_last_waitstatus = *ecs->wp;
+
+ /* Keep this extra brace for now, minimizes diffs. */
+ {
+ switch (ecs->infwait_state)
+ {
+ case infwait_thread_hop_state:
+ /* Cancel the waiton_ptid. */
+ ecs->waiton_ptid = pid_to_ptid (-1);
+ /* Fall thru to the normal_state case. */
+
+ case infwait_normal_state:
+ /* See comments where a TARGET_WAITKIND_SYSCALL_RETURN event
+ is serviced in this loop, below. */
+ if (ecs->enable_hw_watchpoints_after_wait)
+ {
+ TARGET_ENABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid));
+ ecs->enable_hw_watchpoints_after_wait = 0;
+ }
+ stepped_after_stopped_by_watchpoint = 0;
+ break;
+
+ case infwait_nullified_state:
+ break;
+
+ case infwait_nonstep_watch_state:
+ insert_breakpoints ();
+
+ /* FIXME-maybe: is this cleaner than setting a flag? Does it
+ handle things like signals arriving and other things happening
+ in combination correctly? */
+ stepped_after_stopped_by_watchpoint = 1;
+ break;
+ }
+ ecs->infwait_state = infwait_normal_state;
+
+ flush_cached_frames ();
+
+ /* If it's a new process, add it to the thread database */
+
+ ecs->new_thread_event = (! ptid_equal (ecs->ptid, inferior_ptid)
+ && ! in_thread_list (ecs->ptid));
+
+ if (ecs->ws.kind != TARGET_WAITKIND_EXITED
+ && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
+ && ecs->new_thread_event)
+ {
+ add_thread (ecs->ptid);
+
+ ui_out_text (uiout, "[New ");
+ ui_out_text (uiout, target_pid_or_tid_to_str (ecs->ptid));
+ ui_out_text (uiout, "]\n");
+
+#if 0
+ /* NOTE: This block is ONLY meant to be invoked in case of a
+ "thread creation event"! If it is invoked for any other
+ sort of event (such as a new thread landing on a breakpoint),
+ the event will be discarded, which is almost certainly
+ a bad thing!
+
+ To avoid this, the low-level module (eg. target_wait)
+ should call in_thread_list and add_thread, so that the
+ new thread is known by the time we get here. */
+
+ /* We may want to consider not doing a resume here in order
+ to give the user a chance to play with the new thread.
+ It might be good to make that a user-settable option. */
+
+ /* At this point, all threads are stopped (happens
+ automatically in either the OS or the native code).
+ Therefore we need to continue all threads in order to
+ make progress. */
+
+ target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0);
+ prepare_to_wait (ecs);
+ return;
+#endif
+ }
+
+ switch (ecs->ws.kind)
+ {
+ case TARGET_WAITKIND_LOADED:
+ /* Ignore gracefully during startup of the inferior, as it
+ might be the shell which has just loaded some objects,
+ otherwise add the symbols for the newly loaded objects. */
+#ifdef SOLIB_ADD
+ if (!stop_soon_quietly)
+ {
+ /* Remove breakpoints, SOLIB_ADD might adjust
+ breakpoint addresses via breakpoint_re_set. */
+ if (breakpoints_inserted)
+ remove_breakpoints ();
+
+ /* Check for any newly added shared libraries if we're
+ supposed to be adding them automatically. Switch
+ terminal for any messages produced by
+ breakpoint_re_set. */
+ target_terminal_ours_for_output ();
+ SOLIB_ADD (NULL, 0, NULL, auto_solib_add);
+ target_terminal_inferior ();
+
+ /* Reinsert breakpoints and continue. */
+ if (breakpoints_inserted)
+ insert_breakpoints ();
+ }
+#endif
+ resume (0, TARGET_SIGNAL_0);
+ prepare_to_wait (ecs);
+ return;
+
+ case TARGET_WAITKIND_SPURIOUS:
+ resume (0, TARGET_SIGNAL_0);
+ prepare_to_wait (ecs);
+ return;
+
+ case TARGET_WAITKIND_EXITED:
+ target_terminal_ours (); /* Must do this before mourn anyway */
+ print_stop_reason (EXITED, ecs->ws.value.integer);
+
+ /* Record the exit code in the convenience variable $_exitcode, so
+ that the user can inspect this again later. */
+ set_internalvar (lookup_internalvar ("_exitcode"),
+ value_from_longest (builtin_type_int,
+ (LONGEST) ecs->ws.value.integer));
+ gdb_flush (gdb_stdout);
+ target_mourn_inferior ();
+ singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P() */
+ stop_print_frame = 0;
+ stop_stepping (ecs);
+ return;
+
+ case TARGET_WAITKIND_SIGNALLED:
+ stop_print_frame = 0;
+ stop_signal = ecs->ws.value.sig;
+ target_terminal_ours (); /* Must do this before mourn anyway */
+
+ /* Note: By definition of TARGET_WAITKIND_SIGNALLED, we shouldn't
+ reach here unless the inferior is dead. However, for years
+ target_kill() was called here, which hints that fatal signals aren't
+ really fatal on some systems. If that's true, then some changes
+ may be needed. */
+ target_mourn_inferior ();
+
+ print_stop_reason (SIGNAL_EXITED, stop_signal);
+ singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P() */
+ stop_stepping (ecs);
+ return;
+
+ /* The following are the only cases in which we keep going;
+ the above cases end in a continue or goto. */
+ case TARGET_WAITKIND_FORKED:
+ stop_signal = TARGET_SIGNAL_TRAP;
+ pending_follow.kind = ecs->ws.kind;
+
+ /* Ignore fork events reported for the parent; we're only
+ interested in reacting to forks of the child. Note that
+ we expect the child's fork event to be available if we
+ waited for it now. */
+ if (ptid_equal (inferior_ptid, ecs->ptid))
+ {
+ pending_follow.fork_event.saw_parent_fork = 1;
+ pending_follow.fork_event.parent_pid = PIDGET (ecs->ptid);
+ pending_follow.fork_event.child_pid = ecs->ws.value.related_pid;
+ prepare_to_wait (ecs);
+ return;
+ }
+ else
+ {
+ pending_follow.fork_event.saw_child_fork = 1;
+ pending_follow.fork_event.child_pid = PIDGET (ecs->ptid);
+ pending_follow.fork_event.parent_pid = ecs->ws.value.related_pid;
+ }
+
+ stop_pc = read_pc_pid (ecs->ptid);
+ ecs->saved_inferior_ptid = inferior_ptid;
+ inferior_ptid = ecs->ptid;
+ /* The second argument of bpstat_stop_status is meant to help
+ distinguish between a breakpoint trap and a singlestep trap.
+ This is only important on targets where DECR_PC_AFTER_BREAK
+ is non-zero. The prev_pc test is meant to distinguish between
+ singlestepping a trap instruction, and singlestepping thru a
+ jump to the instruction following a trap instruction. */
+
+ stop_bpstat = bpstat_stop_status (&stop_pc,
+ currently_stepping (ecs) &&
+ prev_pc !=
+ stop_pc - DECR_PC_AFTER_BREAK);
+ ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
+ inferior_ptid = ecs->saved_inferior_ptid;
+ goto process_event_stop_test;
+
+ /* If this a platform which doesn't allow a debugger to touch a
+ vfork'd inferior until after it exec's, then we'd best keep
+ our fingers entirely off the inferior, other than continuing
+ it. This has the unfortunate side-effect that catchpoints
+ of vforks will be ignored. But since the platform doesn't
+ allow the inferior be touched at vfork time, there's really
+ little choice. */
+ case TARGET_WAITKIND_VFORKED:
+ stop_signal = TARGET_SIGNAL_TRAP;
+ pending_follow.kind = ecs->ws.kind;
+
+ /* Is this a vfork of the parent? If so, then give any
+ vfork catchpoints a chance to trigger now. (It's
+ dangerous to do so if the child canot be touched until
+ it execs, and the child has not yet exec'd. We probably
+ should warn the user to that effect when the catchpoint
+ triggers...) */
+ if (ptid_equal (ecs->ptid, inferior_ptid))
+ {
+ pending_follow.fork_event.saw_parent_fork = 1;
+ pending_follow.fork_event.parent_pid = PIDGET (ecs->ptid);
+ pending_follow.fork_event.child_pid = ecs->ws.value.related_pid;
+ }
+
+ /* If we've seen the child's vfork event but cannot really touch
+ the child until it execs, then we must continue the child now.
+ Else, give any vfork catchpoints a chance to trigger now. */
+ else
+ {
+ pending_follow.fork_event.saw_child_fork = 1;
+ pending_follow.fork_event.child_pid = PIDGET (ecs->ptid);
+ pending_follow.fork_event.parent_pid = ecs->ws.value.related_pid;
+ target_post_startup_inferior (
+ pid_to_ptid (pending_follow.fork_event.child_pid));
+ follow_vfork_when_exec = !target_can_follow_vfork_prior_to_exec ();
+ if (follow_vfork_when_exec)
+ {
+ target_resume (ecs->ptid, 0, TARGET_SIGNAL_0);
+ prepare_to_wait (ecs);
+ return;
+ }
+ }
+
+ stop_pc = read_pc ();
+ /* The second argument of bpstat_stop_status is meant to help
+ distinguish between a breakpoint trap and a singlestep trap.
+ This is only important on targets where DECR_PC_AFTER_BREAK
+ is non-zero. The prev_pc test is meant to distinguish between
+ singlestepping a trap instruction, and singlestepping thru a
+ jump to the instruction following a trap instruction. */
+
+ stop_bpstat = bpstat_stop_status (&stop_pc,
+ currently_stepping (ecs) &&
+ prev_pc !=
+ stop_pc - DECR_PC_AFTER_BREAK);
+ ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
+ goto process_event_stop_test;
+
+ case TARGET_WAITKIND_EXECD:
+ stop_signal = TARGET_SIGNAL_TRAP;
+
+ /* Is this a target which reports multiple exec events per actual
+ call to exec()? (HP-UX using ptrace does, for example.) If so,
+ ignore all but the last one. Just resume the exec'r, and wait
+ for the next exec event. */
+ if (inferior_ignoring_leading_exec_events)
+ {
+ inferior_ignoring_leading_exec_events--;
+ if (pending_follow.kind == TARGET_WAITKIND_VFORKED)
+ ENSURE_VFORKING_PARENT_REMAINS_STOPPED (pending_follow.fork_event.parent_pid);
+ target_resume (ecs->ptid, 0, TARGET_SIGNAL_0);
+ prepare_to_wait (ecs);
+ return;
+ }
+ inferior_ignoring_leading_exec_events =
+ target_reported_exec_events_per_exec_call () - 1;
+
+ pending_follow.execd_pathname =
+ savestring (ecs->ws.value.execd_pathname,
+ strlen (ecs->ws.value.execd_pathname));
+
+ /* Did inferior_ptid exec, or did a (possibly not-yet-followed)
+ child of a vfork exec?
+
+ ??rehrauer: This is unabashedly an HP-UX specific thing. On
+ HP-UX, events associated with a vforking inferior come in
+ threes: a vfork event for the child (always first), followed
+ a vfork event for the parent and an exec event for the child.
+ The latter two can come in either order.
+
+ If we get the parent vfork event first, life's good: We follow
+ either the parent or child, and then the child's exec event is
+ a "don't care".
+
+ But if we get the child's exec event first, then we delay
+ responding to it until we handle the parent's vfork. Because,
+ otherwise we can't satisfy a "catch vfork". */
+ if (pending_follow.kind == TARGET_WAITKIND_VFORKED)
+ {
+ pending_follow.fork_event.saw_child_exec = 1;
+
+ /* On some targets, the child must be resumed before
+ the parent vfork event is delivered. A single-step
+ suffices. */
+ if (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK ())
+ target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
+ /* We expect the parent vfork event to be available now. */
+ prepare_to_wait (ecs);
+ return;
+ }
+
+ /* This causes the eventpoints and symbol table to be reset. Must
+ do this now, before trying to determine whether to stop. */
+ follow_exec (PIDGET (inferior_ptid), pending_follow.execd_pathname);
+ xfree (pending_follow.execd_pathname);
+
+ stop_pc = read_pc_pid (ecs->ptid);
+ ecs->saved_inferior_ptid = inferior_ptid;
+ inferior_ptid = ecs->ptid;
+ /* The second argument of bpstat_stop_status is meant to help
+ distinguish between a breakpoint trap and a singlestep trap.
+ This is only important on targets where DECR_PC_AFTER_BREAK
+ is non-zero. The prev_pc test is meant to distinguish between
+ singlestepping a trap instruction, and singlestepping thru a
+ jump to the instruction following a trap instruction. */
+
+ stop_bpstat = bpstat_stop_status (&stop_pc,
+ currently_stepping (ecs) &&
+ prev_pc !=
+ stop_pc - DECR_PC_AFTER_BREAK);
+ ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
+ inferior_ptid = ecs->saved_inferior_ptid;
+ goto process_event_stop_test;
+
+ /* These syscall events are returned on HP-UX, as part of its
+ implementation of page-protection-based "hardware" watchpoints.
+ HP-UX has unfortunate interactions between page-protections and
+ some system calls. Our solution is to disable hardware watches
+ when a system call is entered, and reenable them when the syscall
+ completes. The downside of this is that we may miss the precise
+ point at which a watched piece of memory is modified. "Oh well."
+
+ Note that we may have multiple threads running, which may each
+ enter syscalls at roughly the same time. Since we don't have a
+ good notion currently of whether a watched piece of memory is
+ thread-private, we'd best not have any page-protections active
+ when any thread is in a syscall. Thus, we only want to reenable
+ hardware watches when no threads are in a syscall.
+
+ Also, be careful not to try to gather much state about a thread
+ that's in a syscall. It's frequently a losing proposition. */
+ case TARGET_WAITKIND_SYSCALL_ENTRY:
+ number_of_threads_in_syscalls++;
+ if (number_of_threads_in_syscalls == 1)
+ {
+ TARGET_DISABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid));
+ }
+ resume (0, TARGET_SIGNAL_0);
+ prepare_to_wait (ecs);
+ return;
+
+ /* Before examining the threads further, step this thread to
+ get it entirely out of the syscall. (We get notice of the
+ event when the thread is just on the verge of exiting a
+ syscall. Stepping one instruction seems to get it back
+ into user code.)
+
+ Note that although the logical place to reenable h/w watches
+ is here, we cannot. We cannot reenable them before stepping
+ the thread (this causes the next wait on the thread to hang).
+
+ Nor can we enable them after stepping until we've done a wait.
+ Thus, we simply set the flag ecs->enable_hw_watchpoints_after_wait
+ here, which will be serviced immediately after the target
+ is waited on. */
+ case TARGET_WAITKIND_SYSCALL_RETURN:
+ target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
+
+ if (number_of_threads_in_syscalls > 0)
+ {
+ number_of_threads_in_syscalls--;
+ ecs->enable_hw_watchpoints_after_wait =
+ (number_of_threads_in_syscalls == 0);
+ }
+ prepare_to_wait (ecs);
+ return;
+
+ case TARGET_WAITKIND_STOPPED:
+ stop_signal = ecs->ws.value.sig;
+ break;
+
+ /* We had an event in the inferior, but we are not interested
+ in handling it at this level. The lower layers have already
+ done what needs to be done, if anything. This case can
+ occur only when the target is async or extended-async. One
+ of the circumstamces for this to happen is when the
+ inferior produces output for the console. The inferior has
+ not stopped, and we are ignoring the event. */
+ case TARGET_WAITKIND_IGNORE:
+ ecs->wait_some_more = 1;
+ return;
+ }
+
+ /* We may want to consider not doing a resume here in order to give
+ the user a chance to play with the new thread. It might be good
+ to make that a user-settable option. */
+
+ /* At this point, all threads are stopped (happens automatically in
+ either the OS or the native code). Therefore we need to continue
+ all threads in order to make progress. */
+ if (ecs->new_thread_event)
+ {
+ target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0);
+ prepare_to_wait (ecs);
+ return;
+ }
+
+ stop_pc = read_pc_pid (ecs->ptid);
+
+ /* See if a thread hit a thread-specific breakpoint that was meant for
+ another thread. If so, then step that thread past the breakpoint,
+ and continue it. */
+
+ if (stop_signal == TARGET_SIGNAL_TRAP)
+ {
+ if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ ecs->random_signal = 0;
+ else if (breakpoints_inserted
+ && breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK))
+ {
+ ecs->random_signal = 0;
+ if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK,
+ ecs->ptid))
+ {
+ int remove_status;
+
+ /* Saw a breakpoint, but it was hit by the wrong thread.
+ Just continue. */
+ if (DECR_PC_AFTER_BREAK)
+ write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, ecs->ptid);
+
+ remove_status = remove_breakpoints ();
+ /* Did we fail to remove breakpoints? If so, try
+ to set the PC past the bp. (There's at least
+ one situation in which we can fail to remove
+ the bp's: On HP-UX's that use ttrace, we can't
+ change the address space of a vforking child
+ process until the child exits (well, okay, not
+ then either :-) or execs. */
+ if (remove_status != 0)
+ {
+ /* FIXME! This is obviously non-portable! */
+ write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK + 4,
+ ecs->ptid);
+ /* We need to restart all the threads now,
+ * unles we're running in scheduler-locked mode.
+ * Use currently_stepping to determine whether to
+ * step or continue.
+ */
+ /* FIXME MVS: is there any reason not to call resume()? */
+ if (scheduler_mode == schedlock_on)
+ target_resume (ecs->ptid,
+ currently_stepping (ecs),
+ TARGET_SIGNAL_0);
+ else
+ target_resume (RESUME_ALL,
+ currently_stepping (ecs),
+ TARGET_SIGNAL_0);
+ prepare_to_wait (ecs);
+ return;
+ }
+ else
+ { /* Single step */
+ breakpoints_inserted = 0;
+ if (!ptid_equal (inferior_ptid, ecs->ptid))
+ context_switch (ecs);
+ ecs->waiton_ptid = ecs->ptid;
+ ecs->wp = &(ecs->ws);
+ ecs->another_trap = 1;
+
+ ecs->infwait_state = infwait_thread_hop_state;
+ keep_going (ecs);
+ registers_changed ();
+ return;
+ }
+ }
+ }
+ }
+ else
+ ecs->random_signal = 1;
+
+ /* See if something interesting happened to the non-current thread. If
+ so, then switch to that thread, and eventually give control back to
+ the user.
+
+ Note that if there's any kind of pending follow (i.e., of a fork,
+ vfork or exec), we don't want to do this now. Rather, we'll let
+ the next resume handle it. */
+ if (! ptid_equal (ecs->ptid, inferior_ptid) &&
+ (pending_follow.kind == TARGET_WAITKIND_SPURIOUS))
+ {
+ int printed = 0;
+
+ /* If it's a random signal for a non-current thread, notify user
+ if he's expressed an interest. */
+ if (ecs->random_signal
+ && signal_print[stop_signal])
+ {
+/* ??rehrauer: I don't understand the rationale for this code. If the
+ inferior will stop as a result of this signal, then the act of handling
+ the stop ought to print a message that's couches the stoppage in user
+ terms, e.g., "Stopped for breakpoint/watchpoint". If the inferior
+ won't stop as a result of the signal -- i.e., if the signal is merely
+ a side-effect of something GDB's doing "under the covers" for the
+ user, such as stepping threads over a breakpoint they shouldn't stop
+ for -- then the message seems to be a serious annoyance at best.
+
+ For now, remove the message altogether. */
+#if 0
+ printed = 1;
+ target_terminal_ours_for_output ();
+ printf_filtered ("\nProgram received signal %s, %s.\n",
+ target_signal_to_name (stop_signal),
+ target_signal_to_string (stop_signal));
+ gdb_flush (gdb_stdout);
+#endif
+ }
+
+ /* If it's not SIGTRAP and not a signal we want to stop for, then
+ continue the thread. */
+
+ if (stop_signal != TARGET_SIGNAL_TRAP
+ && !signal_stop[stop_signal])
+ {
+ if (printed)
+ target_terminal_inferior ();
+
+ /* Clear the signal if it should not be passed. */
+ if (signal_program[stop_signal] == 0)
+ stop_signal = TARGET_SIGNAL_0;
+
+ target_resume (ecs->ptid, 0, stop_signal);
+ prepare_to_wait (ecs);
+ return;
+ }
+
+ /* It's a SIGTRAP or a signal we're interested in. Switch threads,
+ and fall into the rest of wait_for_inferior(). */
+
+ context_switch (ecs);
+
+ if (context_hook)
+ context_hook (pid_to_thread_id (ecs->ptid));
+
+ flush_cached_frames ();
+ }
+
+ if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ {
+ /* Pull the single step breakpoints out of the target. */
+ SOFTWARE_SINGLE_STEP (0, 0);
+ singlestep_breakpoints_inserted_p = 0;
+ }
+
+ /* If PC is pointing at a nullified instruction, then step beyond
+ it so that the user won't be confused when GDB appears to be ready
+ to execute it. */
+
+ /* if (INSTRUCTION_NULLIFIED && currently_stepping (ecs)) */
+ if (INSTRUCTION_NULLIFIED)
+ {
+ registers_changed ();
+ target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
+
+ /* We may have received a signal that we want to pass to
+ the inferior; therefore, we must not clobber the waitstatus
+ in WS. */
+
+ ecs->infwait_state = infwait_nullified_state;
+ ecs->waiton_ptid = ecs->ptid;
+ ecs->wp = &(ecs->tmpstatus);
+ prepare_to_wait (ecs);
+ return;
+ }
+
+ /* It may not be necessary to disable the watchpoint to stop over
+ it. For example, the PA can (with some kernel cooperation)
+ single step over a watchpoint without disabling the watchpoint. */
+ if (HAVE_STEPPABLE_WATCHPOINT && STOPPED_BY_WATCHPOINT (ecs->ws))
+ {
+ resume (1, 0);
+ prepare_to_wait (ecs);
+ return;
+ }
+
+ /* It is far more common to need to disable a watchpoint to step
+ the inferior over it. FIXME. What else might a debug
+ register or page protection watchpoint scheme need here? */
+ if (HAVE_NONSTEPPABLE_WATCHPOINT && STOPPED_BY_WATCHPOINT (ecs->ws))
+ {
+ /* At this point, we are stopped at an instruction which has
+ attempted to write to a piece of memory under control of
+ a watchpoint. The instruction hasn't actually executed
+ yet. If we were to evaluate the watchpoint expression
+ now, we would get the old value, and therefore no change
+ would seem to have occurred.
+
+ In order to make watchpoints work `right', we really need
+ to complete the memory write, and then evaluate the
+ watchpoint expression. The following code does that by
+ removing the watchpoint (actually, all watchpoints and
+ breakpoints), single-stepping the target, re-inserting
+ watchpoints, and then falling through to let normal
+ single-step processing handle proceed. Since this
+ includes evaluating watchpoints, things will come to a
+ stop in the correct manner. */
+
+ if (DECR_PC_AFTER_BREAK)
+ write_pc (stop_pc - DECR_PC_AFTER_BREAK);
+
+ remove_breakpoints ();
+ registers_changed ();
+ target_resume (ecs->ptid, 1, TARGET_SIGNAL_0); /* Single step */
+
+ ecs->waiton_ptid = ecs->ptid;
+ ecs->wp = &(ecs->ws);
+ ecs->infwait_state = infwait_nonstep_watch_state;
+ prepare_to_wait (ecs);
+ return;
+ }
+
+ /* It may be possible to simply continue after a watchpoint. */
+ if (HAVE_CONTINUABLE_WATCHPOINT)
+ STOPPED_BY_WATCHPOINT (ecs->ws);
+
+ ecs->stop_func_start = 0;
+ ecs->stop_func_end = 0;
+ ecs->stop_func_name = 0;
+ /* Don't care about return value; stop_func_start and stop_func_name
+ will both be 0 if it doesn't work. */
+ find_pc_partial_function (stop_pc, &ecs->stop_func_name,
+ &ecs->stop_func_start, &ecs->stop_func_end);
+ ecs->stop_func_start += FUNCTION_START_OFFSET;
+ ecs->another_trap = 0;
+ bpstat_clear (&stop_bpstat);
+ stop_step = 0;
+ stop_stack_dummy = 0;
+ stop_print_frame = 1;
+ ecs->random_signal = 0;
+ stopped_by_random_signal = 0;
+ breakpoints_failed = 0;
+
+ /* Look at the cause of the stop, and decide what to do.
+ The alternatives are:
+ 1) break; to really stop and return to the debugger,
+ 2) drop through to start up again
+ (set ecs->another_trap to 1 to single step once)
+ 3) set ecs->random_signal to 1, and the decision between 1 and 2
+ will be made according to the signal handling tables. */
+
+ /* First, distinguish signals caused by the debugger from signals
+ that have to do with the program's own actions.
+ Note that breakpoint insns may cause SIGTRAP or SIGILL
+ or SIGEMT, depending on the operating system version.
+ Here we detect when a SIGILL or SIGEMT is really a breakpoint
+ and change it to SIGTRAP. */
+
+ if (stop_signal == TARGET_SIGNAL_TRAP
+ || (breakpoints_inserted &&
+ (stop_signal == TARGET_SIGNAL_ILL
+ || stop_signal == TARGET_SIGNAL_EMT
+ ))
+ || stop_soon_quietly)
+ {
+ if (stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap)
+ {
+ stop_print_frame = 0;
+ stop_stepping (ecs);
+ return;
+ }
+ if (stop_soon_quietly)
+ {
+ stop_stepping (ecs);
+ return;
+ }
+
+ /* Don't even think about breakpoints
+ if just proceeded over a breakpoint.
+
+ However, if we are trying to proceed over a breakpoint
+ and end up in sigtramp, then through_sigtramp_breakpoint
+ will be set and we should check whether we've hit the
+ step breakpoint. */
+ if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected
+ && through_sigtramp_breakpoint == NULL)
+ bpstat_clear (&stop_bpstat);
+ else
+ {
+ /* See if there is a breakpoint at the current PC. */
+
+ /* The second argument of bpstat_stop_status is meant to help
+ distinguish between a breakpoint trap and a singlestep trap.
+ This is only important on targets where DECR_PC_AFTER_BREAK
+ is non-zero. The prev_pc test is meant to distinguish between
+ singlestepping a trap instruction, and singlestepping thru a
+ jump to the instruction following a trap instruction. */
+
+ stop_bpstat = bpstat_stop_status
+ (&stop_pc,
+ /* Pass TRUE if our reason for stopping is something other
+ than hitting a breakpoint. We do this by checking that
+ 1) stepping is going on and 2) we didn't hit a breakpoint
+ in a signal handler without an intervening stop in
+ sigtramp, which is detected by a new stack pointer value
+ below any usual function calling stack adjustments. */
+ (currently_stepping (ecs)
+ && prev_pc != stop_pc - DECR_PC_AFTER_BREAK
+ && !(step_range_end
+ && INNER_THAN (read_sp (), (step_sp - 16))))
+ );
+ /* Following in case break condition called a
+ function. */
+ stop_print_frame = 1;
+ }
+
+ if (stop_signal == TARGET_SIGNAL_TRAP)
+ ecs->random_signal
+ = !(bpstat_explains_signal (stop_bpstat)
+ || trap_expected
+ || (!CALL_DUMMY_BREAKPOINT_OFFSET_P
+ && PC_IN_CALL_DUMMY (stop_pc, read_sp (),
+ FRAME_FP (get_current_frame ())))
+ || (step_range_end && step_resume_breakpoint == NULL));
+
+ else
+ {
+ ecs->random_signal
+ = !(bpstat_explains_signal (stop_bpstat)
+ /* End of a stack dummy. Some systems (e.g. Sony
+ news) give another signal besides SIGTRAP, so
+ check here as well as above. */
+ || (!CALL_DUMMY_BREAKPOINT_OFFSET_P
+ && PC_IN_CALL_DUMMY (stop_pc, read_sp (),
+ FRAME_FP (get_current_frame ())))
+ );
+ if (!ecs->random_signal)
+ stop_signal = TARGET_SIGNAL_TRAP;
+ }
+ }
+
+ /* When we reach this point, we've pretty much decided
+ that the reason for stopping must've been a random
+ (unexpected) signal. */
+
+ else
+ ecs->random_signal = 1;
+ /* If a fork, vfork or exec event was seen, then there are two
+ possible responses we can make:
+
+ 1. If a catchpoint triggers for the event (ecs->random_signal == 0),
+ then we must stop now and issue a prompt. We will resume
+ the inferior when the user tells us to.
+ 2. If no catchpoint triggers for the event (ecs->random_signal == 1),
+ then we must resume the inferior now and keep checking.
+
+ In either case, we must take appropriate steps to "follow" the
+ the fork/vfork/exec when the inferior is resumed. For example,
+ if follow-fork-mode is "child", then we must detach from the
+ parent inferior and follow the new child inferior.
+
+ In either case, setting pending_follow causes the next resume()
+ to take the appropriate following action. */
+ process_event_stop_test:
+ if (ecs->ws.kind == TARGET_WAITKIND_FORKED)
+ {
+ if (ecs->random_signal) /* I.e., no catchpoint triggered for this. */
+ {
+ trap_expected = 1;
+ stop_signal = TARGET_SIGNAL_0;
+ keep_going (ecs);
+ return;
+ }
+ }
+ else if (ecs->ws.kind == TARGET_WAITKIND_VFORKED)
+ {
+ if (ecs->random_signal) /* I.e., no catchpoint triggered for this. */
+ {
+ stop_signal = TARGET_SIGNAL_0;
+ keep_going (ecs);
+ return;
+ }
+ }
+ else if (ecs->ws.kind == TARGET_WAITKIND_EXECD)
+ {
+ pending_follow.kind = ecs->ws.kind;
+ if (ecs->random_signal) /* I.e., no catchpoint triggered for this. */
+ {
+ trap_expected = 1;
+ stop_signal = TARGET_SIGNAL_0;
+ keep_going (ecs);
+ return;
+ }
+ }
+
+ /* For the program's own signals, act according to
+ the signal handling tables. */
+
+ if (ecs->random_signal)
+ {
+ /* Signal not for debugging purposes. */
+ int printed = 0;
+
+ stopped_by_random_signal = 1;
+
+ if (signal_print[stop_signal])
+ {
+ printed = 1;
+ target_terminal_ours_for_output ();
+ print_stop_reason (SIGNAL_RECEIVED, stop_signal);
+ }
+ if (signal_stop[stop_signal])
+ {
+ stop_stepping (ecs);
+ return;
+ }
+ /* If not going to stop, give terminal back
+ if we took it away. */
+ else if (printed)
+ target_terminal_inferior ();
+
+ /* Clear the signal if it should not be passed. */
+ if (signal_program[stop_signal] == 0)
+ stop_signal = TARGET_SIGNAL_0;
+
+ /* I'm not sure whether this needs to be check_sigtramp2 or
+ whether it could/should be keep_going.
+
+ This used to jump to step_over_function if we are stepping,
+ which is wrong.
+
+ Suppose the user does a `next' over a function call, and while
+ that call is in progress, the inferior receives a signal for
+ which GDB does not stop (i.e., signal_stop[SIG] is false). In
+ that case, when we reach this point, there is already a
+ step-resume breakpoint established, right where it should be:
+ immediately after the function call the user is "next"-ing
+ over. If we call step_over_function now, two bad things
+ happen:
+
+ - we'll create a new breakpoint, at wherever the current
+ frame's return address happens to be. That could be
+ anywhere, depending on what function call happens to be on
+ the top of the stack at that point. Point is, it's probably
+ not where we need it.
+
+ - the existing step-resume breakpoint (which is at the correct
+ address) will get orphaned: step_resume_breakpoint will point
+ to the new breakpoint, and the old step-resume breakpoint
+ will never be cleaned up.
+
+ The old behavior was meant to help HP-UX single-step out of
+ sigtramps. It would place the new breakpoint at prev_pc, which
+ was certainly wrong. I don't know the details there, so fixing
+ this probably breaks that. As with anything else, it's up to
+ the HP-UX maintainer to furnish a fix that doesn't break other
+ platforms. --JimB, 20 May 1999 */
+ check_sigtramp2 (ecs);
+ keep_going (ecs);
+ return;
+ }
+
+ /* Handle cases caused by hitting a breakpoint. */
+ {
+ CORE_ADDR jmp_buf_pc;
+ struct bpstat_what what;
+
+ what = bpstat_what (stop_bpstat);
+
+ if (what.call_dummy)
+ {
+ stop_stack_dummy = 1;
+#ifdef HP_OS_BUG
+ trap_expected_after_continue = 1;
+#endif
+ }
+
+ switch (what.main_action)
+ {
+ case BPSTAT_WHAT_SET_LONGJMP_RESUME:
+ /* If we hit the breakpoint at longjmp, disable it for the
+ duration of this command. Then, install a temporary
+ breakpoint at the target of the jmp_buf. */
+ disable_longjmp_breakpoint ();
+ remove_breakpoints ();
+ breakpoints_inserted = 0;
+ if (!GET_LONGJMP_TARGET_P ()
+ || !GET_LONGJMP_TARGET (&jmp_buf_pc))
+ {
+ keep_going (ecs);
+ return;
+ }
+
+ /* Need to blow away step-resume breakpoint, as it
+ interferes with us */
+ if (step_resume_breakpoint != NULL)
+ {
+ delete_step_resume_breakpoint (&step_resume_breakpoint);
+ }
+ /* Not sure whether we need to blow this away too, but probably
+ it is like the step-resume breakpoint. */
+ if (through_sigtramp_breakpoint != NULL)
+ {
+ delete_breakpoint (through_sigtramp_breakpoint);
+ through_sigtramp_breakpoint = NULL;
+ }
+
+#if 0
+ /* FIXME - Need to implement nested temporary breakpoints */
+ if (step_over_calls > 0)
+ set_longjmp_resume_breakpoint (jmp_buf_pc,
+ get_current_frame ());
+ else
+#endif /* 0 */
+ set_longjmp_resume_breakpoint (jmp_buf_pc, NULL);
+ ecs->handling_longjmp = 1; /* FIXME */
+ keep_going (ecs);
+ return;
+
+ case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
+ case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE:
+ remove_breakpoints ();
+ breakpoints_inserted = 0;
+#if 0
+ /* FIXME - Need to implement nested temporary breakpoints */
+ if (step_over_calls
+ && (INNER_THAN (FRAME_FP (get_current_frame ()),
+ step_frame_address)))
+ {
+ ecs->another_trap = 1;
+ keep_going (ecs);
+ return;
+ }
+#endif /* 0 */
+ disable_longjmp_breakpoint ();
+ ecs->handling_longjmp = 0; /* FIXME */
+ if (what.main_action == BPSTAT_WHAT_CLEAR_LONGJMP_RESUME)
+ break;
+ /* else fallthrough */
+
+ case BPSTAT_WHAT_SINGLE:
+ if (breakpoints_inserted)
+ {
+ remove_breakpoints ();
+ }
+ breakpoints_inserted = 0;
+ ecs->another_trap = 1;
+ /* Still need to check other stuff, at least the case
+ where we are stepping and step out of the right range. */
+ break;
+
+ case BPSTAT_WHAT_STOP_NOISY:
+ stop_print_frame = 1;
+
+ /* We are about to nuke the step_resume_breakpoint and
+ through_sigtramp_breakpoint via the cleanup chain, so
+ no need to worry about it here. */
+
+ stop_stepping (ecs);
+ return;
+
+ case BPSTAT_WHAT_STOP_SILENT:
+ stop_print_frame = 0;
+
+ /* We are about to nuke the step_resume_breakpoint and
+ through_sigtramp_breakpoint via the cleanup chain, so
+ no need to worry about it here. */
+
+ stop_stepping (ecs);
+ return;
+
+ case BPSTAT_WHAT_STEP_RESUME:
+ /* This proably demands a more elegant solution, but, yeah
+ right...
+
+ This function's use of the simple variable
+ step_resume_breakpoint doesn't seem to accomodate
+ simultaneously active step-resume bp's, although the
+ breakpoint list certainly can.
+
+ If we reach here and step_resume_breakpoint is already
+ NULL, then apparently we have multiple active
+ step-resume bp's. We'll just delete the breakpoint we
+ stopped at, and carry on.
+
+ Correction: what the code currently does is delete a
+ step-resume bp, but it makes no effort to ensure that
+ the one deleted is the one currently stopped at. MVS */
+
+ if (step_resume_breakpoint == NULL)
+ {
+ step_resume_breakpoint =
+ bpstat_find_step_resume_breakpoint (stop_bpstat);
+ }
+ delete_step_resume_breakpoint (&step_resume_breakpoint);
+ break;
+
+ case BPSTAT_WHAT_THROUGH_SIGTRAMP:
+ if (through_sigtramp_breakpoint)
+ delete_breakpoint (through_sigtramp_breakpoint);
+ through_sigtramp_breakpoint = NULL;
+
+ /* If were waiting for a trap, hitting the step_resume_break
+ doesn't count as getting it. */
+ if (trap_expected)
+ ecs->another_trap = 1;
+ break;
+
+ case BPSTAT_WHAT_CHECK_SHLIBS:
+ case BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK:
+#ifdef SOLIB_ADD
+ {
+ /* Remove breakpoints, we eventually want to step over the
+ shlib event breakpoint, and SOLIB_ADD might adjust
+ breakpoint addresses via breakpoint_re_set. */
+ if (breakpoints_inserted)
+ remove_breakpoints ();
+ breakpoints_inserted = 0;
+
+ /* Check for any newly added shared libraries if we're
+ supposed to be adding them automatically. Switch
+ terminal for any messages produced by
+ breakpoint_re_set. */
+ target_terminal_ours_for_output ();
+ SOLIB_ADD (NULL, 0, NULL, auto_solib_add);
+ target_terminal_inferior ();
+
+ /* Try to reenable shared library breakpoints, additional
+ code segments in shared libraries might be mapped in now. */
+ re_enable_breakpoints_in_shlibs ();
+
+ /* If requested, stop when the dynamic linker notifies
+ gdb of events. This allows the user to get control
+ and place breakpoints in initializer routines for
+ dynamically loaded objects (among other things). */
+ if (stop_on_solib_events)
+ {
+ stop_stepping (ecs);
+ return;
+ }
+
+ /* If we stopped due to an explicit catchpoint, then the
+ (see above) call to SOLIB_ADD pulled in any symbols
+ from a newly-loaded library, if appropriate.
+
+ We do want the inferior to stop, but not where it is
+ now, which is in the dynamic linker callback. Rather,
+ we would like it stop in the user's program, just after
+ the call that caused this catchpoint to trigger. That
+ gives the user a more useful vantage from which to
+ examine their program's state. */
+ else if (what.main_action == BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK)
+ {
+ /* ??rehrauer: If I could figure out how to get the
+ right return PC from here, we could just set a temp
+ breakpoint and resume. I'm not sure we can without
+ cracking open the dld's shared libraries and sniffing
+ their unwind tables and text/data ranges, and that's
+ not a terribly portable notion.
+
+ Until that time, we must step the inferior out of the
+ dld callback, and also out of the dld itself (and any
+ code or stubs in libdld.sl, such as "shl_load" and
+ friends) until we reach non-dld code. At that point,
+ we can stop stepping. */
+ bpstat_get_triggered_catchpoints (stop_bpstat,
+ &ecs->stepping_through_solib_catchpoints);
+ ecs->stepping_through_solib_after_catch = 1;
+
+ /* Be sure to lift all breakpoints, so the inferior does
+ actually step past this point... */
+ ecs->another_trap = 1;
+ break;
+ }
+ else
+ {
+ /* We want to step over this breakpoint, then keep going. */
+ ecs->another_trap = 1;
+ break;
+ }
+ }
+#endif
+ break;
+
+ case BPSTAT_WHAT_LAST:
+ /* Not a real code, but listed here to shut up gcc -Wall. */
+
+ case BPSTAT_WHAT_KEEP_CHECKING:
+ break;
+ }
+ }
+
+ /* We come here if we hit a breakpoint but should not
+ stop for it. Possibly we also were stepping
+ and should stop for that. So fall through and
+ test for stepping. But, if not stepping,
+ do not stop. */
+
+ /* Are we stepping to get the inferior out of the dynamic
+ linker's hook (and possibly the dld itself) after catching
+ a shlib event? */
+ if (ecs->stepping_through_solib_after_catch)
+ {
+#if defined(SOLIB_ADD)
+ /* Have we reached our destination? If not, keep going. */
+ if (SOLIB_IN_DYNAMIC_LINKER (PIDGET (ecs->ptid), stop_pc))
+ {
+ ecs->another_trap = 1;
+ keep_going (ecs);
+ return;
+ }
+#endif
+ /* Else, stop and report the catchpoint(s) whose triggering
+ caused us to begin stepping. */
+ ecs->stepping_through_solib_after_catch = 0;
+ bpstat_clear (&stop_bpstat);
+ stop_bpstat = bpstat_copy (ecs->stepping_through_solib_catchpoints);
+ bpstat_clear (&ecs->stepping_through_solib_catchpoints);
+ stop_print_frame = 1;
+ stop_stepping (ecs);
+ return;
+ }
+
+ if (!CALL_DUMMY_BREAKPOINT_OFFSET_P)
+ {
+ /* This is the old way of detecting the end of the stack dummy.
+ An architecture which defines CALL_DUMMY_BREAKPOINT_OFFSET gets
+ handled above. As soon as we can test it on all of them, all
+ architectures should define it. */
+
+ /* If this is the breakpoint at the end of a stack dummy,
+ just stop silently, unless the user was doing an si/ni, in which
+ case she'd better know what she's doing. */
+
+ if (CALL_DUMMY_HAS_COMPLETED (stop_pc, read_sp (),
+ FRAME_FP (get_current_frame ()))
+ && !step_range_end)
+ {
+ stop_print_frame = 0;
+ stop_stack_dummy = 1;
+#ifdef HP_OS_BUG
+ trap_expected_after_continue = 1;
+#endif
+ stop_stepping (ecs);
+ return;
+ }
+ }
+
+ if (step_resume_breakpoint)
+ {
+ /* Having a step-resume breakpoint overrides anything
+ else having to do with stepping commands until
+ that breakpoint is reached. */
+ /* I'm not sure whether this needs to be check_sigtramp2 or
+ whether it could/should be keep_going. */
+ check_sigtramp2 (ecs);
+ keep_going (ecs);
+ return;
+ }
+
+ if (step_range_end == 0)
+ {
+ /* Likewise if we aren't even stepping. */
+ /* I'm not sure whether this needs to be check_sigtramp2 or
+ whether it could/should be keep_going. */
+ check_sigtramp2 (ecs);
+ keep_going (ecs);
+ return;
+ }
+
+ /* If stepping through a line, keep going if still within it.
+
+ Note that step_range_end is the address of the first instruction
+ beyond the step range, and NOT the address of the last instruction
+ within it! */
+ if (stop_pc >= step_range_start
+ && stop_pc < step_range_end)
+ {
+ /* We might be doing a BPSTAT_WHAT_SINGLE and getting a signal.
+ So definately need to check for sigtramp here. */
+ check_sigtramp2 (ecs);
+ keep_going (ecs);
+ return;
+ }
+
+ /* We stepped out of the stepping range. */
+
+ /* If we are stepping at the source level and entered the runtime
+ loader dynamic symbol resolution code, we keep on single stepping
+ until we exit the run time loader code and reach the callee's
+ address. */
+ if (step_over_calls == STEP_OVER_UNDEBUGGABLE && IN_SOLIB_DYNSYM_RESOLVE_CODE (stop_pc))
+ {
+ CORE_ADDR pc_after_resolver = SKIP_SOLIB_RESOLVER (stop_pc);
+
+ if (pc_after_resolver)
+ {
+ /* Set up a step-resume breakpoint at the address
+ indicated by SKIP_SOLIB_RESOLVER. */
+ struct symtab_and_line sr_sal;
+ INIT_SAL (&sr_sal);
+ sr_sal.pc = pc_after_resolver;
+
+ check_for_old_step_resume_breakpoint ();
+ step_resume_breakpoint =
+ set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
+ if (breakpoints_inserted)
+ insert_breakpoints ();
+ }
+
+ keep_going (ecs);
+ return;
+ }
+
+ /* We can't update step_sp every time through the loop, because
+ reading the stack pointer would slow down stepping too much.
+ But we can update it every time we leave the step range. */
+ ecs->update_step_sp = 1;
+
+ /* Did we just take a signal? */
+ if (PC_IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
+ && !PC_IN_SIGTRAMP (prev_pc, prev_func_name)
+ && INNER_THAN (read_sp (), step_sp))
+ {
+ /* We've just taken a signal; go until we are back to
+ the point where we took it and one more. */
+
+ /* Note: The test above succeeds not only when we stepped
+ into a signal handler, but also when we step past the last
+ statement of a signal handler and end up in the return stub
+ of the signal handler trampoline. To distinguish between
+ these two cases, check that the frame is INNER_THAN the
+ previous one below. pai/1997-09-11 */
+
+
+ {
+ CORE_ADDR current_frame = FRAME_FP (get_current_frame ());
+
+ if (INNER_THAN (current_frame, step_frame_address))
+ {
+ /* We have just taken a signal; go until we are back to
+ the point where we took it and one more. */
+
+ /* This code is needed at least in the following case:
+ The user types "next" and then a signal arrives (before
+ the "next" is done). */
+
+ /* Note that if we are stopped at a breakpoint, then we need
+ the step_resume breakpoint to override any breakpoints at
+ the same location, so that we will still step over the
+ breakpoint even though the signal happened. */
+ struct symtab_and_line sr_sal;
+
+ INIT_SAL (&sr_sal);
+ sr_sal.symtab = NULL;
+ sr_sal.line = 0;
+ sr_sal.pc = prev_pc;
+ /* We could probably be setting the frame to
+ step_frame_address; I don't think anyone thought to
+ try it. */
+ check_for_old_step_resume_breakpoint ();
+ step_resume_breakpoint =
+ set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
+ if (breakpoints_inserted)
+ insert_breakpoints ();
+ }
+ else
+ {
+ /* We just stepped out of a signal handler and into
+ its calling trampoline.
+
+ Normally, we'd call step_over_function from
+ here, but for some reason GDB can't unwind the
+ stack correctly to find the real PC for the point
+ user code where the signal trampoline will return
+ -- FRAME_SAVED_PC fails, at least on HP-UX 10.20.
+ But signal trampolines are pretty small stubs of
+ code, anyway, so it's OK instead to just
+ single-step out. Note: assuming such trampolines
+ don't exhibit recursion on any platform... */
+ find_pc_partial_function (stop_pc, &ecs->stop_func_name,
+ &ecs->stop_func_start,
+ &ecs->stop_func_end);
+ /* Readjust stepping range */
+ step_range_start = ecs->stop_func_start;
+ step_range_end = ecs->stop_func_end;
+ ecs->stepping_through_sigtramp = 1;
+ }
+ }
+
+
+ /* If this is stepi or nexti, make sure that the stepping range
+ gets us past that instruction. */
+ if (step_range_end == 1)
+ /* FIXME: Does this run afoul of the code below which, if
+ we step into the middle of a line, resets the stepping
+ range? */
+ step_range_end = (step_range_start = prev_pc) + 1;
+
+ ecs->remove_breakpoints_on_following_step = 1;
+ keep_going (ecs);
+ return;
+ }
+
+ if (stop_pc == ecs->stop_func_start /* Quick test */
+ || (in_prologue (stop_pc, ecs->stop_func_start) &&
+ !IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name))
+ || IN_SOLIB_CALL_TRAMPOLINE (stop_pc, ecs->stop_func_name)
+ || ecs->stop_func_name == 0)
+ {
+ /* It's a subroutine call. */
+
+ if ((step_over_calls == STEP_OVER_NONE)
+ || ((step_range_end == 1)
+ && in_prologue (prev_pc, ecs->stop_func_start)))
+ {
+ /* I presume that step_over_calls is only 0 when we're
+ supposed to be stepping at the assembly language level
+ ("stepi"). Just stop. */
+ /* Also, maybe we just did a "nexti" inside a prolog,
+ so we thought it was a subroutine call but it was not.
+ Stop as well. FENN */
+ stop_step = 1;
+ print_stop_reason (END_STEPPING_RANGE, 0);
+ stop_stepping (ecs);
+ return;
+ }
+
+ if (step_over_calls == STEP_OVER_ALL || IGNORE_HELPER_CALL (stop_pc))
+ {
+ /* We're doing a "next". */
+
+ if (PC_IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
+ && INNER_THAN (step_frame_address, read_sp()))
+ /* We stepped out of a signal handler, and into its
+ calling trampoline. This is misdetected as a
+ subroutine call, but stepping over the signal
+ trampoline isn't such a bad idea. In order to do
+ that, we have to ignore the value in
+ step_frame_address, since that doesn't represent the
+ frame that'll reach when we return from the signal
+ trampoline. Otherwise we'll probably continue to the
+ end of the program. */
+ step_frame_address = 0;
+
+ step_over_function (ecs);
+ keep_going (ecs);
+ return;
+ }
+
+ /* If we are in a function call trampoline (a stub between
+ the calling routine and the real function), locate the real
+ function. That's what tells us (a) whether we want to step
+ into it at all, and (b) what prologue we want to run to
+ the end of, if we do step into it. */
+ tmp = SKIP_TRAMPOLINE_CODE (stop_pc);
+ if (tmp != 0)
+ ecs->stop_func_start = tmp;
+ else
+ {
+ tmp = DYNAMIC_TRAMPOLINE_NEXTPC (stop_pc);
+ if (tmp)
+ {
+ struct symtab_and_line xxx;
+ /* Why isn't this s_a_l called "sr_sal", like all of the
+ other s_a_l's where this code is duplicated? */
+ INIT_SAL (&xxx); /* initialize to zeroes */
+ xxx.pc = tmp;
+ xxx.section = find_pc_overlay (xxx.pc);
+ check_for_old_step_resume_breakpoint ();
+ step_resume_breakpoint =
+ set_momentary_breakpoint (xxx, NULL, bp_step_resume);
+ insert_breakpoints ();
+ keep_going (ecs);
+ return;
+ }
+ }
+
+ /* If we have line number information for the function we
+ are thinking of stepping into, step into it.
+
+ If there are several symtabs at that PC (e.g. with include
+ files), just want to know whether *any* of them have line
+ numbers. find_pc_line handles this. */
+ {
+ struct symtab_and_line tmp_sal;
+
+ tmp_sal = find_pc_line (ecs->stop_func_start, 0);
+ if (tmp_sal.line != 0)
+ {
+ step_into_function (ecs);
+ return;
+ }
+ }
+
+ /* If we have no line number and the step-stop-if-no-debug
+ is set, we stop the step so that the user has a chance to
+ switch in assembly mode. */
+ if (step_over_calls == STEP_OVER_UNDEBUGGABLE && step_stop_if_no_debug)
+ {
+ stop_step = 1;
+ print_stop_reason (END_STEPPING_RANGE, 0);
+ stop_stepping (ecs);
+ return;
+ }
+
+ step_over_function (ecs);
+ keep_going (ecs);
+ return;
+
+ }
+
+ /* We've wandered out of the step range. */
+
+ ecs->sal = find_pc_line (stop_pc, 0);
+
+ if (step_range_end == 1)
+ {
+ /* It is stepi or nexti. We always want to stop stepping after
+ one instruction. */
+ stop_step = 1;
+ print_stop_reason (END_STEPPING_RANGE, 0);
+ stop_stepping (ecs);
+ return;
+ }
+
+ /* If we're in the return path from a shared library trampoline,
+ we want to proceed through the trampoline when stepping. */
+ if (IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name))
+ {
+ CORE_ADDR tmp;
+
+ /* Determine where this trampoline returns. */
+ tmp = SKIP_TRAMPOLINE_CODE (stop_pc);
+
+ /* Only proceed through if we know where it's going. */
+ if (tmp)
+ {
+ /* And put the step-breakpoint there and go until there. */
+ struct symtab_and_line sr_sal;
+
+ INIT_SAL (&sr_sal); /* initialize to zeroes */
+ sr_sal.pc = tmp;
+ sr_sal.section = find_pc_overlay (sr_sal.pc);
+ /* Do not specify what the fp should be when we stop
+ since on some machines the prologue
+ is where the new fp value is established. */
+ check_for_old_step_resume_breakpoint ();
+ step_resume_breakpoint =
+ set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
+ if (breakpoints_inserted)
+ insert_breakpoints ();
+
+ /* Restart without fiddling with the step ranges or
+ other state. */
+ keep_going (ecs);
+ return;
+ }
+ }
+
+ if (ecs->sal.line == 0)
+ {
+ /* We have no line number information. That means to stop
+ stepping (does this always happen right after one instruction,
+ when we do "s" in a function with no line numbers,
+ or can this happen as a result of a return or longjmp?). */
+ stop_step = 1;
+ print_stop_reason (END_STEPPING_RANGE, 0);
+ stop_stepping (ecs);
+ return;
+ }
+
+ if ((stop_pc == ecs->sal.pc)
+ && (ecs->current_line != ecs->sal.line || ecs->current_symtab != ecs->sal.symtab))
+ {
+ /* We are at the start of a different line. So stop. Note that
+ we don't stop if we step into the middle of a different line.
+ That is said to make things like for (;;) statements work
+ better. */
+ stop_step = 1;
+ print_stop_reason (END_STEPPING_RANGE, 0);
+ stop_stepping (ecs);
+ return;
+ }
+
+ /* We aren't done stepping.
+
+ Optimize by setting the stepping range to the line.
+ (We might not be in the original line, but if we entered a
+ new line in mid-statement, we continue stepping. This makes
+ things like for(;;) statements work better.) */
+
+ if (ecs->stop_func_end && ecs->sal.end >= ecs->stop_func_end)
+ {
+ /* If this is the last line of the function, don't keep stepping
+ (it would probably step us out of the function).
+ This is particularly necessary for a one-line function,
+ in which after skipping the prologue we better stop even though
+ we will be in mid-line. */
+ stop_step = 1;
+ print_stop_reason (END_STEPPING_RANGE, 0);
+ stop_stepping (ecs);
+ return;
+ }
+ step_range_start = ecs->sal.pc;
+ step_range_end = ecs->sal.end;
+ step_frame_address = FRAME_FP (get_current_frame ());
+ ecs->current_line = ecs->sal.line;
+ ecs->current_symtab = ecs->sal.symtab;
+
+ /* In the case where we just stepped out of a function into the middle
+ of a line of the caller, continue stepping, but step_frame_address
+ must be modified to current frame */
+ {
+ CORE_ADDR current_frame = FRAME_FP (get_current_frame ());
+ if (!(INNER_THAN (current_frame, step_frame_address)))
+ step_frame_address = current_frame;
+ }
+
+ keep_going (ecs);
+
+ } /* extra brace, to preserve old indentation */
+}
+
+/* Are we in the middle of stepping? */
+
+static int
+currently_stepping (struct execution_control_state *ecs)
+{
+ return ((through_sigtramp_breakpoint == NULL
+ && !ecs->handling_longjmp
+ && ((step_range_end && step_resume_breakpoint == NULL)
+ || trap_expected))
+ || ecs->stepping_through_solib_after_catch
+ || bpstat_should_step ());
+}
+
+static void
+check_sigtramp2 (struct execution_control_state *ecs)
+{
+ if (trap_expected
+ && PC_IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
+ && !PC_IN_SIGTRAMP (prev_pc, prev_func_name)
+ && INNER_THAN (read_sp (), step_sp))
+ {
+ /* What has happened here is that we have just stepped the
+ inferior with a signal (because it is a signal which
+ shouldn't make us stop), thus stepping into sigtramp.
+
+ So we need to set a step_resume_break_address breakpoint and
+ continue until we hit it, and then step. FIXME: This should
+ be more enduring than a step_resume breakpoint; we should
+ know that we will later need to keep going rather than
+ re-hitting the breakpoint here (see the testsuite,
+ gdb.base/signals.exp where it says "exceedingly difficult"). */
+
+ struct symtab_and_line sr_sal;
+
+ INIT_SAL (&sr_sal); /* initialize to zeroes */
+ sr_sal.pc = prev_pc;
+ sr_sal.section = find_pc_overlay (sr_sal.pc);
+ /* We perhaps could set the frame if we kept track of what the
+ frame corresponding to prev_pc was. But we don't, so don't. */
+ through_sigtramp_breakpoint =
+ set_momentary_breakpoint (sr_sal, NULL, bp_through_sigtramp);
+ if (breakpoints_inserted)
+ insert_breakpoints ();
+
+ ecs->remove_breakpoints_on_following_step = 1;
+ ecs->another_trap = 1;
+ }
+}
+
+/* Subroutine call with source code we should not step over. Do step
+ to the first line of code in it. */
+
+static void
+step_into_function (struct execution_control_state *ecs)
+{
+ struct symtab *s;
+ struct symtab_and_line sr_sal;
+
+ s = find_pc_symtab (stop_pc);
+ if (s && s->language != language_asm)
+ ecs->stop_func_start = SKIP_PROLOGUE (ecs->stop_func_start);
+
+ ecs->sal = find_pc_line (ecs->stop_func_start, 0);
+ /* Use the step_resume_break to step until the end of the prologue,
+ even if that involves jumps (as it seems to on the vax under
+ 4.2). */
+ /* If the prologue ends in the middle of a source line, continue to
+ the end of that source line (if it is still within the function).
+ Otherwise, just go to end of prologue. */
+#ifdef PROLOGUE_FIRSTLINE_OVERLAP
+ /* no, don't either. It skips any code that's legitimately on the
+ first line. */
+#else
+ if (ecs->sal.end
+ && ecs->sal.pc != ecs->stop_func_start
+ && ecs->sal.end < ecs->stop_func_end)
+ ecs->stop_func_start = ecs->sal.end;
+#endif
+
+ if (ecs->stop_func_start == stop_pc)
+ {
+ /* We are already there: stop now. */
+ stop_step = 1;
+ print_stop_reason (END_STEPPING_RANGE, 0);
+ stop_stepping (ecs);
+ return;
+ }
+ else
+ {
+ /* Put the step-breakpoint there and go until there. */
+ INIT_SAL (&sr_sal); /* initialize to zeroes */
+ sr_sal.pc = ecs->stop_func_start;
+ sr_sal.section = find_pc_overlay (ecs->stop_func_start);
+ /* Do not specify what the fp should be when we stop since on
+ some machines the prologue is where the new fp value is
+ established. */
+ check_for_old_step_resume_breakpoint ();
+ step_resume_breakpoint =
+ set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
+ if (breakpoints_inserted)
+ insert_breakpoints ();
+
+ /* And make sure stepping stops right away then. */
+ step_range_end = step_range_start;
+ }
+ keep_going (ecs);
+}
+
+/* We've just entered a callee, and we wish to resume until it returns
+ to the caller. Setting a step_resume breakpoint on the return
+ address will catch a return from the callee.
+
+ However, if the callee is recursing, we want to be careful not to
+ catch returns of those recursive calls, but only of THIS instance
+ of the call.
+
+ To do this, we set the step_resume bp's frame to our current
+ caller's frame (step_frame_address, which is set by the "next" or
+ "until" command, before execution begins). */
+
+static void
+step_over_function (struct execution_control_state *ecs)
+{
+ struct symtab_and_line sr_sal;
+
+ INIT_SAL (&sr_sal); /* initialize to zeros */
+ sr_sal.pc = ADDR_BITS_REMOVE (SAVED_PC_AFTER_CALL (get_current_frame ()));
+ sr_sal.section = find_pc_overlay (sr_sal.pc);
+
+ check_for_old_step_resume_breakpoint ();
+ step_resume_breakpoint =
+ set_momentary_breakpoint (sr_sal, get_current_frame (), bp_step_resume);
+
+ if (step_frame_address && !IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc))
+ step_resume_breakpoint->frame = step_frame_address;
+
+ if (breakpoints_inserted)
+ insert_breakpoints ();
+}
+
+static void
+stop_stepping (struct execution_control_state *ecs)
+{
+ if (target_has_execution)
+ {
+ /* Are we stopping for a vfork event? We only stop when we see
+ the child's event. However, we may not yet have seen the
+ parent's event. And, inferior_ptid is still set to the
+ parent's pid, until we resume again and follow either the
+ parent or child.
+
+ To ensure that we can really touch inferior_ptid (aka, the
+ parent process) -- which calls to functions like read_pc
+ implicitly do -- wait on the parent if necessary. */
+ if ((pending_follow.kind == TARGET_WAITKIND_VFORKED)
+ && !pending_follow.fork_event.saw_parent_fork)
+ {
+ ptid_t parent_ptid;
+
+ do
+ {
+ if (target_wait_hook)
+ parent_ptid = target_wait_hook (pid_to_ptid (-1), &(ecs->ws));
+ else
+ parent_ptid = target_wait (pid_to_ptid (-1), &(ecs->ws));
+ }
+ while (! ptid_equal (parent_ptid, inferior_ptid));
+ }
+
+ /* Assuming the inferior still exists, set these up for next
+ time, just like we did above if we didn't break out of the
+ loop. */
+ prev_pc = read_pc ();
+ prev_func_start = ecs->stop_func_start;
+ prev_func_name = ecs->stop_func_name;
+ }
+
+ /* Let callers know we don't want to wait for the inferior anymore. */
+ ecs->wait_some_more = 0;
+}
+
+/* This function handles various cases where we need to continue
+ waiting for the inferior. */
+/* (Used to be the keep_going: label in the old wait_for_inferior) */
+
+static void
+keep_going (struct execution_control_state *ecs)
+{
+ /* ??rehrauer: ttrace on HP-UX theoretically allows one to debug a
+ vforked child between its creation and subsequent exit or call to
+ exec(). However, I had big problems in this rather creaky exec
+ engine, getting that to work. The fundamental problem is that
+ I'm trying to debug two processes via an engine that only
+ understands a single process with possibly multiple threads.
+
+ Hence, this spot is known to have problems when
+ target_can_follow_vfork_prior_to_exec returns 1. */
+
+ /* Save the pc before execution, to compare with pc after stop. */
+ prev_pc = read_pc (); /* Might have been DECR_AFTER_BREAK */
+ prev_func_start = ecs->stop_func_start; /* Ok, since if DECR_PC_AFTER
+ BREAK is defined, the
+ original pc would not have
+ been at the start of a
+ function. */
+ prev_func_name = ecs->stop_func_name;
+
+ if (ecs->update_step_sp)
+ step_sp = read_sp ();
+ ecs->update_step_sp = 0;
+
+ /* If we did not do break;, it means we should keep running the
+ inferior and not return to debugger. */
+
+ if (trap_expected && stop_signal != TARGET_SIGNAL_TRAP)
+ {
+ /* We took a signal (which we are supposed to pass through to
+ the inferior, else we'd have done a break above) and we
+ haven't yet gotten our trap. Simply continue. */
+ resume (currently_stepping (ecs), stop_signal);
+ }
+ else
+ {
+ /* Either the trap was not expected, but we are continuing
+ anyway (the user asked that this signal be passed to the
+ child)
+ -- or --
+ The signal was SIGTRAP, e.g. it was our signal, but we
+ decided we should resume from it.
+
+ We're going to run this baby now!
+
+ Insert breakpoints now, unless we are trying to one-proceed
+ past a breakpoint. */
+ /* If we've just finished a special step resume and we don't
+ want to hit a breakpoint, pull em out. */
+ if (step_resume_breakpoint == NULL
+ && through_sigtramp_breakpoint == NULL
+ && ecs->remove_breakpoints_on_following_step)
+ {
+ ecs->remove_breakpoints_on_following_step = 0;
+ remove_breakpoints ();
+ breakpoints_inserted = 0;
+ }
+ else if (!breakpoints_inserted &&
+ (through_sigtramp_breakpoint != NULL || !ecs->another_trap))
+ {
+ breakpoints_failed = insert_breakpoints ();
+ if (breakpoints_failed)
+ {
+ stop_stepping (ecs);
+ return;
+ }
+ breakpoints_inserted = 1;
+ }
+
+ trap_expected = ecs->another_trap;
+
+ /* Do not deliver SIGNAL_TRAP (except when the user explicitly
+ specifies that such a signal should be delivered to the
+ target program).
+
+ Typically, this would occure when a user is debugging a
+ target monitor on a simulator: the target monitor sets a
+ breakpoint; the simulator encounters this break-point and
+ halts the simulation handing control to GDB; GDB, noteing
+ that the break-point isn't valid, returns control back to the
+ simulator; the simulator then delivers the hardware
+ equivalent of a SIGNAL_TRAP to the program being debugged. */
+
+ if (stop_signal == TARGET_SIGNAL_TRAP
+ && !signal_program[stop_signal])
+ stop_signal = TARGET_SIGNAL_0;
+
+#ifdef SHIFT_INST_REGS
+ /* I'm not sure when this following segment applies. I do know,
+ now, that we shouldn't rewrite the regs when we were stopped
+ by a random signal from the inferior process. */
+ /* FIXME: Shouldn't this be based on the valid bit of the SXIP?
+ (this is only used on the 88k). */
+
+ if (!bpstat_explains_signal (stop_bpstat)
+ && (stop_signal != TARGET_SIGNAL_CHLD)
+ && !stopped_by_random_signal)
+ SHIFT_INST_REGS ();
+#endif /* SHIFT_INST_REGS */
+
+ resume (currently_stepping (ecs), stop_signal);
+ }
+
+ prepare_to_wait (ecs);
+}
+
+/* This function normally comes after a resume, before
+ handle_inferior_event exits. It takes care of any last bits of
+ housekeeping, and sets the all-important wait_some_more flag. */
+
+static void
+prepare_to_wait (struct execution_control_state *ecs)
+{
+ if (ecs->infwait_state == infwait_normal_state)
+ {
+ overlay_cache_invalid = 1;
+
+ /* We have to invalidate the registers BEFORE calling
+ target_wait because they can be loaded from the target while
+ in target_wait. This makes remote debugging a bit more
+ efficient for those targets that provide critical registers
+ as part of their normal status mechanism. */
+
+ registers_changed ();
+ ecs->waiton_ptid = pid_to_ptid (-1);
+ ecs->wp = &(ecs->ws);
+ }
+ /* This is the old end of the while loop. Let everybody know we
+ want to wait for the inferior some more and get called again
+ soon. */
+ ecs->wait_some_more = 1;
+}
+
+/* Print why the inferior has stopped. We always print something when
+ the inferior exits, or receives a signal. The rest of the cases are
+ dealt with later on in normal_stop() and print_it_typical(). Ideally
+ there should be a call to this function from handle_inferior_event()
+ each time stop_stepping() is called.*/
+static void
+print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
+{
+ switch (stop_reason)
+ {
+ case STOP_UNKNOWN:
+ /* We don't deal with these cases from handle_inferior_event()
+ yet. */
+ break;
+ case END_STEPPING_RANGE:
+ /* We are done with a step/next/si/ni command. */
+ /* For now print nothing. */
+ /* Print a message only if not in the middle of doing a "step n"
+ operation for n > 1 */
+ if (!step_multi || !stop_step)
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "reason", "end-stepping-range");
+ break;
+ case BREAKPOINT_HIT:
+ /* We found a breakpoint. */
+ /* For now print nothing. */
+ break;
+ case SIGNAL_EXITED:
+ /* The inferior was terminated by a signal. */
+ annotate_signalled ();
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "reason", "exited-signalled");
+ ui_out_text (uiout, "\nProgram terminated with signal ");
+ annotate_signal_name ();
+ ui_out_field_string (uiout, "signal-name", target_signal_to_name (stop_info));
+ annotate_signal_name_end ();
+ ui_out_text (uiout, ", ");
+ annotate_signal_string ();
+ ui_out_field_string (uiout, "signal-meaning", target_signal_to_string (stop_info));
+ annotate_signal_string_end ();
+ ui_out_text (uiout, ".\n");
+ ui_out_text (uiout, "The program no longer exists.\n");
+ break;
+ case EXITED:
+ /* The inferior program is finished. */
+ annotate_exited (stop_info);
+ if (stop_info)
+ {
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "reason", "exited");
+ ui_out_text (uiout, "\nProgram exited with code ");
+ ui_out_field_fmt (uiout, "exit-code", "0%o", (unsigned int) stop_info);
+ ui_out_text (uiout, ".\n");
+ }
+ else
+ {
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "reason", "exited-normally");
+ ui_out_text (uiout, "\nProgram exited normally.\n");
+ }
+ break;
+ case SIGNAL_RECEIVED:
+ /* Signal received. The signal table tells us to print about
+ it. */
+ annotate_signal ();
+ ui_out_text (uiout, "\nProgram received signal ");
+ annotate_signal_name ();
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "reason", "signal-received");
+ ui_out_field_string (uiout, "signal-name", target_signal_to_name (stop_info));
+ annotate_signal_name_end ();
+ ui_out_text (uiout, ", ");
+ annotate_signal_string ();
+ ui_out_field_string (uiout, "signal-meaning", target_signal_to_string (stop_info));
+ annotate_signal_string_end ();
+ ui_out_text (uiout, ".\n");
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "print_stop_reason: unrecognized enum value");
+ break;
+ }
+}
+
+
+/* Here to return control to GDB when the inferior stops for real.
+ Print appropriate messages, remove breakpoints, give terminal our modes.
+
+ STOP_PRINT_FRAME nonzero means print the executing frame
+ (pc, function, args, file, line number and line text).
+ BREAKPOINTS_FAILED nonzero means stop was due to error
+ attempting to insert breakpoints. */
+
+void
+normal_stop (void)
+{
+ /* As with the notification of thread events, we want to delay
+ notifying the user that we've switched thread context until
+ the inferior actually stops.
+
+ (Note that there's no point in saying anything if the inferior
+ has exited!) */
+ if (! ptid_equal (previous_inferior_ptid, inferior_ptid)
+ && target_has_execution)
+ {
+ target_terminal_ours_for_output ();
+ printf_filtered ("[Switching to %s]\n",
+ target_pid_or_tid_to_str (inferior_ptid));
+ previous_inferior_ptid = inferior_ptid;
+ }
+
+ /* Make sure that the current_frame's pc is correct. This
+ is a correction for setting up the frame info before doing
+ DECR_PC_AFTER_BREAK */
+ if (target_has_execution && get_current_frame ())
+ (get_current_frame ())->pc = read_pc ();
+
+ if (breakpoints_failed)
+ {
+ target_terminal_ours_for_output ();
+ print_sys_errmsg ("While inserting breakpoints", breakpoints_failed);
+ printf_filtered ("Stopped; cannot insert breakpoints.\n\
+The same program may be running in another process,\n\
+or you may have requested too many hardware breakpoints\n\
+and/or watchpoints.\n");
+ }
+
+ if (target_has_execution && breakpoints_inserted)
+ {
+ if (remove_breakpoints ())
+ {
+ target_terminal_ours_for_output ();
+ printf_filtered ("Cannot remove breakpoints because ");
+ printf_filtered ("program is no longer writable.\n");
+ printf_filtered ("It might be running in another process.\n");
+ printf_filtered ("Further execution is probably impossible.\n");
+ }
+ }
+ breakpoints_inserted = 0;
+
+ /* Delete the breakpoint we stopped at, if it wants to be deleted.
+ Delete any breakpoint that is to be deleted at the next stop. */
+
+ breakpoint_auto_delete (stop_bpstat);
+
+ /* If an auto-display called a function and that got a signal,
+ delete that auto-display to avoid an infinite recursion. */
+
+ if (stopped_by_random_signal)
+ disable_current_display ();
+
+ /* Don't print a message if in the middle of doing a "step n"
+ operation for n > 1 */
+ if (step_multi && stop_step)
+ goto done;
+
+ target_terminal_ours ();
+
+ /* Look up the hook_stop and run it (CLI internally handles problem
+ of stop_command's pre-hook not existing). */
+ if (stop_command)
+ catch_errors (hook_stop_stub, stop_command,
+ "Error while running hook_stop:\n", RETURN_MASK_ALL);
+
+ if (!target_has_stack)
+ {
+
+ goto done;
+ }
+
+ /* Select innermost stack frame - i.e., current frame is frame 0,
+ and current location is based on that.
+ Don't do this on return from a stack dummy routine,
+ or if the program has exited. */
+
+ if (!stop_stack_dummy)
+ {
+ select_frame (get_current_frame ());
+
+ /* Print current location without a level number, if
+ we have changed functions or hit a breakpoint.
+ Print source line if we have one.
+ bpstat_print() contains the logic deciding in detail
+ what to print, based on the event(s) that just occurred. */
+
+ if (stop_print_frame
+ && selected_frame)
+ {
+ int bpstat_ret;
+ int source_flag;
+ int do_frame_printing = 1;
+
+ bpstat_ret = bpstat_print (stop_bpstat);
+ switch (bpstat_ret)
+ {
+ case PRINT_UNKNOWN:
+ if (stop_step
+ && step_frame_address == FRAME_FP (get_current_frame ())
+ && step_start_function == find_pc_function (stop_pc))
+ source_flag = SRC_LINE; /* finished step, just print source line */
+ else
+ source_flag = SRC_AND_LOC; /* print location and source line */
+ break;
+ case PRINT_SRC_AND_LOC:
+ source_flag = SRC_AND_LOC; /* print location and source line */
+ break;
+ case PRINT_SRC_ONLY:
+ source_flag = SRC_LINE;
+ break;
+ case PRINT_NOTHING:
+ source_flag = SRC_LINE; /* something bogus */
+ do_frame_printing = 0;
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "Unknown value.");
+ }
+ /* For mi, have the same behavior every time we stop:
+ print everything but the source line. */
+ if (ui_out_is_mi_like_p (uiout))
+ source_flag = LOC_AND_ADDRESS;
+
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_int (uiout, "thread-id",
+ pid_to_thread_id (inferior_ptid));
+ /* The behavior of this routine with respect to the source
+ flag is:
+ SRC_LINE: Print only source line
+ LOCATION: Print only location
+ SRC_AND_LOC: Print location and source line */
+ if (do_frame_printing)
+ show_and_print_stack_frame (selected_frame, -1, source_flag);
+
+ /* Display the auto-display expressions. */
+ do_displays ();
+ }
+ }
+
+ /* Save the function value return registers, if we care.
+ We might be about to restore their previous contents. */
+ if (proceed_to_finish)
+ read_register_bytes (0, stop_registers, REGISTER_BYTES);
+
+ if (stop_stack_dummy)
+ {
+ /* Pop the empty frame that contains the stack dummy.
+ POP_FRAME ends with a setting of the current frame, so we
+ can use that next. */
+ POP_FRAME;
+ /* Set stop_pc to what it was before we called the function.
+ Can't rely on restore_inferior_status because that only gets
+ called if we don't stop in the called function. */
+ stop_pc = read_pc ();
+ select_frame (get_current_frame ());
+ }
+
+done:
+ annotate_stopped ();
+}
+
+static int
+hook_stop_stub (void *cmd)
+{
+ execute_cmd_pre_hook ((struct cmd_list_element *) cmd);
+ return (0);
+}
+
+int
+signal_stop_state (int signo)
+{
+ return signal_stop[signo];
+}
+
+int
+signal_print_state (int signo)
+{
+ return signal_print[signo];
+}
+
+int
+signal_pass_state (int signo)
+{
+ return signal_program[signo];
+}
+
+int signal_stop_update (signo, state)
+ int signo;
+ int state;
+{
+ int ret = signal_stop[signo];
+ signal_stop[signo] = state;
+ return ret;
+}
+
+int signal_print_update (signo, state)
+ int signo;
+ int state;
+{
+ int ret = signal_print[signo];
+ signal_print[signo] = state;
+ return ret;
+}
+
+int signal_pass_update (signo, state)
+ int signo;
+ int state;
+{
+ int ret = signal_program[signo];
+ signal_program[signo] = state;
+ return ret;
+}
+
+static void
+sig_print_header (void)
+{
+ printf_filtered ("\
+Signal Stop\tPrint\tPass to program\tDescription\n");
+}
+
+static void
+sig_print_info (enum target_signal oursig)
+{
+ char *name = target_signal_to_name (oursig);
+ int name_padding = 13 - strlen (name);
+
+ if (name_padding <= 0)
+ name_padding = 0;
+
+ printf_filtered ("%s", name);
+ printf_filtered ("%*.*s ", name_padding, name_padding,
+ " ");
+ printf_filtered ("%s\t", signal_stop[oursig] ? "Yes" : "No");
+ printf_filtered ("%s\t", signal_print[oursig] ? "Yes" : "No");
+ printf_filtered ("%s\t\t", signal_program[oursig] ? "Yes" : "No");
+ printf_filtered ("%s\n", target_signal_to_string (oursig));
+}
+
+/* Specify how various signals in the inferior should be handled. */
+
+static void
+handle_command (char *args, int from_tty)
+{
+ char **argv;
+ int digits, wordlen;
+ int sigfirst, signum, siglast;
+ enum target_signal oursig;
+ int allsigs;
+ int nsigs;
+ unsigned char *sigs;
+ struct cleanup *old_chain;
+
+ if (args == NULL)
+ {
+ error_no_arg ("signal to handle");
+ }
+
+ /* Allocate and zero an array of flags for which signals to handle. */
+
+ nsigs = (int) TARGET_SIGNAL_LAST;
+ sigs = (unsigned char *) alloca (nsigs);
+ memset (sigs, 0, nsigs);
+
+ /* Break the command line up into args. */
+
+ argv = buildargv (args);
+ if (argv == NULL)
+ {
+ nomem (0);
+ }
+ old_chain = make_cleanup_freeargv (argv);
+
+ /* Walk through the args, looking for signal oursigs, signal names, and
+ actions. Signal numbers and signal names may be interspersed with
+ actions, with the actions being performed for all signals cumulatively
+ specified. Signal ranges can be specified as <LOW>-<HIGH>. */
+
+ while (*argv != NULL)
+ {
+ wordlen = strlen (*argv);
+ for (digits = 0; isdigit ((*argv)[digits]); digits++)
+ {;
+ }
+ allsigs = 0;
+ sigfirst = siglast = -1;
+
+ if (wordlen >= 1 && !strncmp (*argv, "all", wordlen))
+ {
+ /* Apply action to all signals except those used by the
+ debugger. Silently skip those. */
+ allsigs = 1;
+ sigfirst = 0;
+ siglast = nsigs - 1;
+ }
+ else if (wordlen >= 1 && !strncmp (*argv, "stop", wordlen))
+ {
+ SET_SIGS (nsigs, sigs, signal_stop);
+ SET_SIGS (nsigs, sigs, signal_print);
+ }
+ else if (wordlen >= 1 && !strncmp (*argv, "ignore", wordlen))
+ {
+ UNSET_SIGS (nsigs, sigs, signal_program);
+ }
+ else if (wordlen >= 2 && !strncmp (*argv, "print", wordlen))
+ {
+ SET_SIGS (nsigs, sigs, signal_print);
+ }
+ else if (wordlen >= 2 && !strncmp (*argv, "pass", wordlen))
+ {
+ SET_SIGS (nsigs, sigs, signal_program);
+ }
+ else if (wordlen >= 3 && !strncmp (*argv, "nostop", wordlen))
+ {
+ UNSET_SIGS (nsigs, sigs, signal_stop);
+ }
+ else if (wordlen >= 3 && !strncmp (*argv, "noignore", wordlen))
+ {
+ SET_SIGS (nsigs, sigs, signal_program);
+ }
+ else if (wordlen >= 4 && !strncmp (*argv, "noprint", wordlen))
+ {
+ UNSET_SIGS (nsigs, sigs, signal_print);
+ UNSET_SIGS (nsigs, sigs, signal_stop);
+ }
+ else if (wordlen >= 4 && !strncmp (*argv, "nopass", wordlen))
+ {
+ UNSET_SIGS (nsigs, sigs, signal_program);
+ }
+ else if (digits > 0)
+ {
+ /* It is numeric. The numeric signal refers to our own
+ internal signal numbering from target.h, not to host/target
+ signal number. This is a feature; users really should be
+ using symbolic names anyway, and the common ones like
+ SIGHUP, SIGINT, SIGALRM, etc. will work right anyway. */
+
+ sigfirst = siglast = (int)
+ target_signal_from_command (atoi (*argv));
+ if ((*argv)[digits] == '-')
+ {
+ siglast = (int)
+ target_signal_from_command (atoi ((*argv) + digits + 1));
+ }
+ if (sigfirst > siglast)
+ {
+ /* Bet he didn't figure we'd think of this case... */
+ signum = sigfirst;
+ sigfirst = siglast;
+ siglast = signum;
+ }
+ }
+ else
+ {
+ oursig = target_signal_from_name (*argv);
+ if (oursig != TARGET_SIGNAL_UNKNOWN)
+ {
+ sigfirst = siglast = (int) oursig;
+ }
+ else
+ {
+ /* Not a number and not a recognized flag word => complain. */
+ error ("Unrecognized or ambiguous flag word: \"%s\".", *argv);
+ }
+ }
+
+ /* If any signal numbers or symbol names were found, set flags for
+ which signals to apply actions to. */
+
+ for (signum = sigfirst; signum >= 0 && signum <= siglast; signum++)
+ {
+ switch ((enum target_signal) signum)
+ {
+ case TARGET_SIGNAL_TRAP:
+ case TARGET_SIGNAL_INT:
+ if (!allsigs && !sigs[signum])
+ {
+ if (query ("%s is used by the debugger.\n\
+Are you sure you want to change it? ",
+ target_signal_to_name
+ ((enum target_signal) signum)))
+ {
+ sigs[signum] = 1;
+ }
+ else
+ {
+ printf_unfiltered ("Not confirmed, unchanged.\n");
+ gdb_flush (gdb_stdout);
+ }
+ }
+ break;
+ case TARGET_SIGNAL_0:
+ case TARGET_SIGNAL_DEFAULT:
+ case TARGET_SIGNAL_UNKNOWN:
+ /* Make sure that "all" doesn't print these. */
+ break;
+ default:
+ sigs[signum] = 1;
+ break;
+ }
+ }
+
+ argv++;
+ }
+
+ target_notice_signals (inferior_ptid);
+
+ if (from_tty)
+ {
+ /* Show the results. */
+ sig_print_header ();
+ for (signum = 0; signum < nsigs; signum++)
+ {
+ if (sigs[signum])
+ {
+ sig_print_info (signum);
+ }
+ }
+ }
+
+ do_cleanups (old_chain);
+}
+
+static void
+xdb_handle_command (char *args, int from_tty)
+{
+ char **argv;
+ struct cleanup *old_chain;
+
+ /* Break the command line up into args. */
+
+ argv = buildargv (args);
+ if (argv == NULL)
+ {
+ nomem (0);
+ }
+ old_chain = make_cleanup_freeargv (argv);
+ if (argv[1] != (char *) NULL)
+ {
+ char *argBuf;
+ int bufLen;
+
+ bufLen = strlen (argv[0]) + 20;
+ argBuf = (char *) xmalloc (bufLen);
+ if (argBuf)
+ {
+ int validFlag = 1;
+ enum target_signal oursig;
+
+ oursig = target_signal_from_name (argv[0]);
+ memset (argBuf, 0, bufLen);
+ if (strcmp (argv[1], "Q") == 0)
+ sprintf (argBuf, "%s %s", argv[0], "noprint");
+ else
+ {
+ if (strcmp (argv[1], "s") == 0)
+ {
+ if (!signal_stop[oursig])
+ sprintf (argBuf, "%s %s", argv[0], "stop");
+ else
+ sprintf (argBuf, "%s %s", argv[0], "nostop");
+ }
+ else if (strcmp (argv[1], "i") == 0)
+ {
+ if (!signal_program[oursig])
+ sprintf (argBuf, "%s %s", argv[0], "pass");
+ else
+ sprintf (argBuf, "%s %s", argv[0], "nopass");
+ }
+ else if (strcmp (argv[1], "r") == 0)
+ {
+ if (!signal_print[oursig])
+ sprintf (argBuf, "%s %s", argv[0], "print");
+ else
+ sprintf (argBuf, "%s %s", argv[0], "noprint");
+ }
+ else
+ validFlag = 0;
+ }
+ if (validFlag)
+ handle_command (argBuf, from_tty);
+ else
+ printf_filtered ("Invalid signal handling flag.\n");
+ if (argBuf)
+ xfree (argBuf);
+ }
+ }
+ do_cleanups (old_chain);
+}
+
+/* Print current contents of the tables set by the handle command.
+ It is possible we should just be printing signals actually used
+ by the current target (but for things to work right when switching
+ targets, all signals should be in the signal tables). */
+
+static void
+signals_info (char *signum_exp, int from_tty)
+{
+ enum target_signal oursig;
+ sig_print_header ();
+
+ if (signum_exp)
+ {
+ /* First see if this is a symbol name. */
+ oursig = target_signal_from_name (signum_exp);
+ if (oursig == TARGET_SIGNAL_UNKNOWN)
+ {
+ /* No, try numeric. */
+ oursig =
+ target_signal_from_command (parse_and_eval_long (signum_exp));
+ }
+ sig_print_info (oursig);
+ return;
+ }
+
+ printf_filtered ("\n");
+ /* These ugly casts brought to you by the native VAX compiler. */
+ for (oursig = TARGET_SIGNAL_FIRST;
+ (int) oursig < (int) TARGET_SIGNAL_LAST;
+ oursig = (enum target_signal) ((int) oursig + 1))
+ {
+ QUIT;
+
+ if (oursig != TARGET_SIGNAL_UNKNOWN
+ && oursig != TARGET_SIGNAL_DEFAULT
+ && oursig != TARGET_SIGNAL_0)
+ sig_print_info (oursig);
+ }
+
+ printf_filtered ("\nUse the \"handle\" command to change these tables.\n");
+}
+
+struct inferior_status
+{
+ enum target_signal stop_signal;
+ CORE_ADDR stop_pc;
+ bpstat stop_bpstat;
+ int stop_step;
+ int stop_stack_dummy;
+ int stopped_by_random_signal;
+ int trap_expected;
+ CORE_ADDR step_range_start;
+ CORE_ADDR step_range_end;
+ CORE_ADDR step_frame_address;
+ enum step_over_calls_kind step_over_calls;
+ CORE_ADDR step_resume_break_address;
+ int stop_after_trap;
+ int stop_soon_quietly;
+ CORE_ADDR selected_frame_address;
+ char *stop_registers;
+
+ /* These are here because if call_function_by_hand has written some
+ registers and then decides to call error(), we better not have changed
+ any registers. */
+ char *registers;
+
+ int selected_level;
+ int breakpoint_proceeded;
+ int restore_stack_info;
+ int proceed_to_finish;
+};
+
+static struct inferior_status *
+xmalloc_inferior_status (void)
+{
+ struct inferior_status *inf_status;
+ inf_status = xmalloc (sizeof (struct inferior_status));
+ inf_status->stop_registers = xmalloc (REGISTER_BYTES);
+ inf_status->registers = xmalloc (REGISTER_BYTES);
+ return inf_status;
+}
+
+static void
+free_inferior_status (struct inferior_status *inf_status)
+{
+ xfree (inf_status->registers);
+ xfree (inf_status->stop_registers);
+ xfree (inf_status);
+}
+
+void
+write_inferior_status_register (struct inferior_status *inf_status, int regno,
+ LONGEST val)
+{
+ int size = REGISTER_RAW_SIZE (regno);
+ void *buf = alloca (size);
+ store_signed_integer (buf, size, val);
+ memcpy (&inf_status->registers[REGISTER_BYTE (regno)], buf, size);
+}
+
+/* Save all of the information associated with the inferior<==>gdb
+ connection. INF_STATUS is a pointer to a "struct inferior_status"
+ (defined in inferior.h). */
+
+struct inferior_status *
+save_inferior_status (int restore_stack_info)
+{
+ struct inferior_status *inf_status = xmalloc_inferior_status ();
+
+ inf_status->stop_signal = stop_signal;
+ inf_status->stop_pc = stop_pc;
+ inf_status->stop_step = stop_step;
+ inf_status->stop_stack_dummy = stop_stack_dummy;
+ inf_status->stopped_by_random_signal = stopped_by_random_signal;
+ inf_status->trap_expected = trap_expected;
+ inf_status->step_range_start = step_range_start;
+ inf_status->step_range_end = step_range_end;
+ inf_status->step_frame_address = step_frame_address;
+ inf_status->step_over_calls = step_over_calls;
+ inf_status->stop_after_trap = stop_after_trap;
+ inf_status->stop_soon_quietly = stop_soon_quietly;
+ /* Save original bpstat chain here; replace it with copy of chain.
+ If caller's caller is walking the chain, they'll be happier if we
+ hand them back the original chain when restore_inferior_status is
+ called. */
+ inf_status->stop_bpstat = stop_bpstat;
+ stop_bpstat = bpstat_copy (stop_bpstat);
+ inf_status->breakpoint_proceeded = breakpoint_proceeded;
+ inf_status->restore_stack_info = restore_stack_info;
+ inf_status->proceed_to_finish = proceed_to_finish;
+
+ memcpy (inf_status->stop_registers, stop_registers, REGISTER_BYTES);
+
+ read_register_bytes (0, inf_status->registers, REGISTER_BYTES);
+
+ record_selected_frame (&(inf_status->selected_frame_address),
+ &(inf_status->selected_level));
+ return inf_status;
+}
+
+struct restore_selected_frame_args
+{
+ CORE_ADDR frame_address;
+ int level;
+};
+
+static int
+restore_selected_frame (void *args)
+{
+ struct restore_selected_frame_args *fr =
+ (struct restore_selected_frame_args *) args;
+ struct frame_info *frame;
+ int level = fr->level;
+
+ frame = find_relative_frame (get_current_frame (), &level);
+
+ /* If inf_status->selected_frame_address is NULL, there was no
+ previously selected frame. */
+ if (frame == NULL ||
+ /* FRAME_FP (frame) != fr->frame_address || */
+ /* elz: deleted this check as a quick fix to the problem that
+ for function called by hand gdb creates no internal frame
+ structure and the real stack and gdb's idea of stack are
+ different if nested calls by hands are made.
+
+ mvs: this worries me. */
+ level != 0)
+ {
+ warning ("Unable to restore previously selected frame.\n");
+ return 0;
+ }
+
+ select_frame (frame);
+
+ return (1);
+}
+
+void
+restore_inferior_status (struct inferior_status *inf_status)
+{
+ stop_signal = inf_status->stop_signal;
+ stop_pc = inf_status->stop_pc;
+ stop_step = inf_status->stop_step;
+ stop_stack_dummy = inf_status->stop_stack_dummy;
+ stopped_by_random_signal = inf_status->stopped_by_random_signal;
+ trap_expected = inf_status->trap_expected;
+ step_range_start = inf_status->step_range_start;
+ step_range_end = inf_status->step_range_end;
+ step_frame_address = inf_status->step_frame_address;
+ step_over_calls = inf_status->step_over_calls;
+ stop_after_trap = inf_status->stop_after_trap;
+ stop_soon_quietly = inf_status->stop_soon_quietly;
+ bpstat_clear (&stop_bpstat);
+ stop_bpstat = inf_status->stop_bpstat;
+ breakpoint_proceeded = inf_status->breakpoint_proceeded;
+ proceed_to_finish = inf_status->proceed_to_finish;
+
+ /* FIXME: Is the restore of stop_registers always needed */
+ memcpy (stop_registers, inf_status->stop_registers, REGISTER_BYTES);
+
+ /* The inferior can be gone if the user types "print exit(0)"
+ (and perhaps other times). */
+ if (target_has_execution)
+ write_register_bytes (0, inf_status->registers, REGISTER_BYTES);
+
+ /* FIXME: If we are being called after stopping in a function which
+ is called from gdb, we should not be trying to restore the
+ selected frame; it just prints a spurious error message (The
+ message is useful, however, in detecting bugs in gdb (like if gdb
+ clobbers the stack)). In fact, should we be restoring the
+ inferior status at all in that case? . */
+
+ if (target_has_stack && inf_status->restore_stack_info)
+ {
+ struct restore_selected_frame_args fr;
+ fr.level = inf_status->selected_level;
+ fr.frame_address = inf_status->selected_frame_address;
+ /* The point of catch_errors is that if the stack is clobbered,
+ walking the stack might encounter a garbage pointer and error()
+ trying to dereference it. */
+ if (catch_errors (restore_selected_frame, &fr,
+ "Unable to restore previously selected frame:\n",
+ RETURN_MASK_ERROR) == 0)
+ /* Error in restoring the selected frame. Select the innermost
+ frame. */
+
+
+ select_frame (get_current_frame ());
+
+ }
+
+ free_inferior_status (inf_status);
+}
+
+static void
+do_restore_inferior_status_cleanup (void *sts)
+{
+ restore_inferior_status (sts);
+}
+
+struct cleanup *
+make_cleanup_restore_inferior_status (struct inferior_status *inf_status)
+{
+ return make_cleanup (do_restore_inferior_status_cleanup, inf_status);
+}
+
+void
+discard_inferior_status (struct inferior_status *inf_status)
+{
+ /* See save_inferior_status for info on stop_bpstat. */
+ bpstat_clear (&inf_status->stop_bpstat);
+ free_inferior_status (inf_status);
+}
+
+/* Oft used ptids */
+ptid_t null_ptid;
+ptid_t minus_one_ptid;
+
+/* Create a ptid given the necessary PID, LWP, and TID components. */
+
+ptid_t
+ptid_build (int pid, long lwp, long tid)
+{
+ ptid_t ptid;
+
+ ptid.pid = pid;
+ ptid.lwp = lwp;
+ ptid.tid = tid;
+ return ptid;
+}
+
+/* Create a ptid from just a pid. */
+
+ptid_t
+pid_to_ptid (int pid)
+{
+ return ptid_build (pid, 0, 0);
+}
+
+/* Fetch the pid (process id) component from a ptid. */
+
+int
+ptid_get_pid (ptid_t ptid)
+{
+ return ptid.pid;
+}
+
+/* Fetch the lwp (lightweight process) component from a ptid. */
+
+long
+ptid_get_lwp (ptid_t ptid)
+{
+ return ptid.lwp;
+}
+
+/* Fetch the tid (thread id) component from a ptid. */
+
+long
+ptid_get_tid (ptid_t ptid)
+{
+ return ptid.tid;
+}
+
+/* ptid_equal() is used to test equality of two ptids. */
+
+int
+ptid_equal (ptid_t ptid1, ptid_t ptid2)
+{
+ return (ptid1.pid == ptid2.pid && ptid1.lwp == ptid2.lwp
+ && ptid1.tid == ptid2.tid);
+}
+
+/* restore_inferior_ptid() will be used by the cleanup machinery
+ to restore the inferior_ptid value saved in a call to
+ save_inferior_ptid(). */
+
+static void
+restore_inferior_ptid (void *arg)
+{
+ ptid_t *saved_ptid_ptr = arg;
+ inferior_ptid = *saved_ptid_ptr;
+ xfree (arg);
+}
+
+/* Save the value of inferior_ptid so that it may be restored by a
+ later call to do_cleanups(). Returns the struct cleanup pointer
+ needed for later doing the cleanup. */
+
+struct cleanup *
+save_inferior_ptid (void)
+{
+ ptid_t *saved_ptid_ptr;
+
+ saved_ptid_ptr = xmalloc (sizeof (ptid_t));
+ *saved_ptid_ptr = inferior_ptid;
+ return make_cleanup (restore_inferior_ptid, saved_ptid_ptr);
+}
+
+
+static void
+build_infrun (void)
+{
+ stop_registers = xmalloc (REGISTER_BYTES);
+}
+
+void
+_initialize_infrun (void)
+{
+ register int i;
+ register int numsigs;
+ struct cmd_list_element *c;
+
+ build_infrun ();
+
+ register_gdbarch_swap (&stop_registers, sizeof (stop_registers), NULL);
+ register_gdbarch_swap (NULL, 0, build_infrun);
+
+ add_info ("signals", signals_info,
+ "What debugger does when program gets various signals.\n\
+Specify a signal as argument to print info on that signal only.");
+ add_info_alias ("handle", "signals", 0);
+
+ add_com ("handle", class_run, handle_command,
+ concat ("Specify how to handle a signal.\n\
+Args are signals and actions to apply to those signals.\n\
+Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals\n\
+from 1-15 are allowed for compatibility with old versions of GDB.\n\
+Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).\n\
+The special arg \"all\" is recognized to mean all signals except those\n\
+used by the debugger, typically SIGTRAP and SIGINT.\n",
+ "Recognized actions include \"stop\", \"nostop\", \"print\", \"noprint\",\n\
+\"pass\", \"nopass\", \"ignore\", or \"noignore\".\n\
+Stop means reenter debugger if this signal happens (implies print).\n\
+Print means print a message if this signal happens.\n\
+Pass means let program see this signal; otherwise program doesn't know.\n\
+Ignore is a synonym for nopass and noignore is a synonym for pass.\n\
+Pass and Stop may be combined.", NULL));
+ if (xdb_commands)
+ {
+ add_com ("lz", class_info, signals_info,
+ "What debugger does when program gets various signals.\n\
+Specify a signal as argument to print info on that signal only.");
+ add_com ("z", class_run, xdb_handle_command,
+ concat ("Specify how to handle a signal.\n\
+Args are signals and actions to apply to those signals.\n\
+Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals\n\
+from 1-15 are allowed for compatibility with old versions of GDB.\n\
+Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).\n\
+The special arg \"all\" is recognized to mean all signals except those\n\
+used by the debugger, typically SIGTRAP and SIGINT.\n",
+ "Recognized actions include \"s\" (toggles between stop and nostop), \n\
+\"r\" (toggles between print and noprint), \"i\" (toggles between pass and \
+nopass), \"Q\" (noprint)\n\
+Stop means reenter debugger if this signal happens (implies print).\n\
+Print means print a message if this signal happens.\n\
+Pass means let program see this signal; otherwise program doesn't know.\n\
+Ignore is a synonym for nopass and noignore is a synonym for pass.\n\
+Pass and Stop may be combined.", NULL));
+ }
+
+ if (!dbx_commands)
+ stop_command = add_cmd ("stop", class_obscure, not_just_help_class_command,
+ "There is no `stop' command, but you can set a hook on `stop'.\n\
+This allows you to set a list of commands to be run each time execution\n\
+of the program stops.", &cmdlist);
+
+ numsigs = (int) TARGET_SIGNAL_LAST;
+ signal_stop = (unsigned char *)
+ xmalloc (sizeof (signal_stop[0]) * numsigs);
+ signal_print = (unsigned char *)
+ xmalloc (sizeof (signal_print[0]) * numsigs);
+ signal_program = (unsigned char *)
+ xmalloc (sizeof (signal_program[0]) * numsigs);
+ for (i = 0; i < numsigs; i++)
+ {
+ signal_stop[i] = 1;
+ signal_print[i] = 1;
+ signal_program[i] = 1;
+ }
+
+ /* Signals caused by debugger's own actions
+ should not be given to the program afterwards. */
+ signal_program[TARGET_SIGNAL_TRAP] = 0;
+ signal_program[TARGET_SIGNAL_INT] = 0;
+
+ /* Signals that are not errors should not normally enter the debugger. */
+ signal_stop[TARGET_SIGNAL_ALRM] = 0;
+ signal_print[TARGET_SIGNAL_ALRM] = 0;
+ signal_stop[TARGET_SIGNAL_VTALRM] = 0;
+ signal_print[TARGET_SIGNAL_VTALRM] = 0;
+ signal_stop[TARGET_SIGNAL_PROF] = 0;
+ signal_print[TARGET_SIGNAL_PROF] = 0;
+ signal_stop[TARGET_SIGNAL_CHLD] = 0;
+ signal_print[TARGET_SIGNAL_CHLD] = 0;
+ signal_stop[TARGET_SIGNAL_IO] = 0;
+ signal_print[TARGET_SIGNAL_IO] = 0;
+ signal_stop[TARGET_SIGNAL_POLL] = 0;
+ signal_print[TARGET_SIGNAL_POLL] = 0;
+ signal_stop[TARGET_SIGNAL_URG] = 0;
+ signal_print[TARGET_SIGNAL_URG] = 0;
+ signal_stop[TARGET_SIGNAL_WINCH] = 0;
+ signal_print[TARGET_SIGNAL_WINCH] = 0;
+
+ /* These signals are used internally by user-level thread
+ implementations. (See signal(5) on Solaris.) Like the above
+ signals, a healthy program receives and handles them as part of
+ its normal operation. */
+ signal_stop[TARGET_SIGNAL_LWP] = 0;
+ signal_print[TARGET_SIGNAL_LWP] = 0;
+ signal_stop[TARGET_SIGNAL_WAITING] = 0;
+ signal_print[TARGET_SIGNAL_WAITING] = 0;
+ signal_stop[TARGET_SIGNAL_CANCEL] = 0;
+ signal_print[TARGET_SIGNAL_CANCEL] = 0;
+
+#ifdef SOLIB_ADD
+ add_show_from_set
+ (add_set_cmd ("stop-on-solib-events", class_support, var_zinteger,
+ (char *) &stop_on_solib_events,
+ "Set stopping for shared library events.\n\
+If nonzero, gdb will give control to the user when the dynamic linker\n\
+notifies gdb of shared library events. The most common event of interest\n\
+to the user would be loading/unloading of a new library.\n",
+ &setlist),
+ &showlist);
+#endif
+
+ c = add_set_enum_cmd ("follow-fork-mode",
+ class_run,
+ follow_fork_mode_kind_names,
+ &follow_fork_mode_string,
+/* ??rehrauer: The "both" option is broken, by what may be a 10.20
+ kernel problem. It's also not terribly useful without a GUI to
+ help the user drive two debuggers. So for now, I'm disabling
+ the "both" option. */
+/* "Set debugger response to a program call of fork \
+ or vfork.\n\
+ A fork or vfork creates a new process. follow-fork-mode can be:\n\
+ parent - the original process is debugged after a fork\n\
+ child - the new process is debugged after a fork\n\
+ both - both the parent and child are debugged after a fork\n\
+ ask - the debugger will ask for one of the above choices\n\
+ For \"both\", another copy of the debugger will be started to follow\n\
+ the new child process. The original debugger will continue to follow\n\
+ the original parent process. To distinguish their prompts, the\n\
+ debugger copy's prompt will be changed.\n\
+ For \"parent\" or \"child\", the unfollowed process will run free.\n\
+ By default, the debugger will follow the parent process.",
+ */
+ "Set debugger response to a program call of fork \
+or vfork.\n\
+A fork or vfork creates a new process. follow-fork-mode can be:\n\
+ parent - the original process is debugged after a fork\n\
+ child - the new process is debugged after a fork\n\
+ ask - the debugger will ask for one of the above choices\n\
+For \"parent\" or \"child\", the unfollowed process will run free.\n\
+By default, the debugger will follow the parent process.",
+ &setlist);
+ add_show_from_set (c, &showlist);
+
+ c = add_set_enum_cmd ("scheduler-locking", class_run,
+ scheduler_enums, /* array of string names */
+ &scheduler_mode, /* current mode */
+ "Set mode for locking scheduler during execution.\n\
+off == no locking (threads may preempt at any time)\n\
+on == full locking (no thread except the current thread may run)\n\
+step == scheduler locked during every single-step operation.\n\
+ In this mode, no other thread may run during a step command.\n\
+ Other threads may run while stepping over a function call ('next').",
+ &setlist);
+
+ set_cmd_sfunc (c, set_schedlock_func); /* traps on target vector */
+ add_show_from_set (c, &showlist);
+
+ c = add_set_cmd ("step-mode", class_run,
+ var_boolean, (char*) &step_stop_if_no_debug,
+"Set mode of the step operation. When set, doing a step over a\n\
+function without debug line information will stop at the first\n\
+instruction of that function. Otherwise, the function is skipped and\n\
+the step command stops at a different source line.",
+ &setlist);
+ add_show_from_set (c, &showlist);
+
+ /* ptid initializations */
+ null_ptid = ptid_build (0, 0, 0);
+ minus_one_ptid = ptid_build (-1, 0, 0);
+ inferior_ptid = null_ptid;
+ target_last_wait_ptid = minus_one_ptid;
+}
diff --git a/gdb/inftarg.c b/gdb/inftarg.c
new file mode 100644
index 00000000000..9035310c494
--- /dev/null
+++ b/gdb/inftarg.c
@@ -0,0 +1,856 @@
+/* Target-vector operations for controlling Unix child processes, for GDB.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
+ 2000, 2002
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+
+ ## Contains temporary hacks..
+
+ 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 "defs.h"
+#include "frame.h" /* required by inferior.h */
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "gdb_stat.h"
+#include <signal.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include "gdb_wait.h"
+
+extern struct symtab_and_line *child_enable_exception_callback (enum
+ exception_event_kind,
+ int);
+
+extern struct exception_event_record
+ *child_get_current_exception_event (void);
+
+extern void _initialize_inftarg (void);
+
+static void child_prepare_to_store (void);
+
+#ifndef CHILD_WAIT
+static ptid_t child_wait (ptid_t, struct target_waitstatus *);
+#endif /* CHILD_WAIT */
+
+#if !defined(CHILD_POST_WAIT)
+void child_post_wait (ptid_t, int);
+#endif
+
+static void child_open (char *, int);
+
+static void child_files_info (struct target_ops *);
+
+static void child_detach (char *, int);
+
+static void child_detach_from_process (int, char *, int, int);
+
+static void child_attach (char *, int);
+
+static void child_attach_to_process (char *, int, int);
+
+#if !defined(CHILD_POST_ATTACH)
+extern void child_post_attach (int);
+#endif
+
+static void child_require_attach (char *, int);
+
+static void child_require_detach (int, char *, int);
+
+static void ptrace_me (void);
+
+static void ptrace_him (int);
+
+static void child_create_inferior (char *, char *, char **);
+
+static void child_mourn_inferior (void);
+
+static int child_can_run (void);
+
+static void child_stop (void);
+
+#ifndef CHILD_THREAD_ALIVE
+int child_thread_alive (ptid_t);
+#endif
+
+static void init_child_ops (void);
+
+extern char **environ;
+
+struct target_ops child_ops;
+
+int child_suppress_run = 0; /* Non-zero if inftarg should pretend not to
+ be a runnable target. Used by targets
+ that can sit atop inftarg, such as HPUX
+ thread support. */
+
+#ifndef CHILD_WAIT
+
+/*## */
+/* Enable HACK for ttrace work. In
+ * infttrace.c/require_notification_of_events,
+ * this is set to 0 so that the loop in child_wait
+ * won't loop.
+ */
+int not_same_real_pid = 1;
+/*## */
+
+
+/* Wait for child to do something. Return pid of child, or -1 in case
+ of error; store status through argument pointer OURSTATUS. */
+
+static ptid_t
+child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+{
+ int save_errno;
+ int status;
+ char *execd_pathname = NULL;
+ int exit_status;
+ int related_pid;
+ int syscall_id;
+ enum target_waitkind kind;
+ int pid;
+
+ do
+ {
+ set_sigint_trap (); /* Causes SIGINT to be passed on to the
+ attached process. */
+ set_sigio_trap ();
+
+ pid = ptrace_wait (inferior_ptid, &status);
+
+ save_errno = errno;
+
+ clear_sigio_trap ();
+
+ clear_sigint_trap ();
+
+ if (pid == -1)
+ {
+ if (save_errno == EINTR)
+ continue;
+
+ fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
+ safe_strerror (save_errno));
+
+ /* Claim it exited with unknown signal. */
+ ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
+ ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
+ return pid_to_ptid (-1);
+ }
+
+ /* Did it exit?
+ */
+ if (target_has_exited (pid, status, &exit_status))
+ {
+ /* ??rehrauer: For now, ignore this. */
+ continue;
+ }
+
+ if (!target_thread_alive (pid_to_ptid (pid)))
+ {
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+ return pid_to_ptid (pid);
+ }
+
+ if (target_has_forked (pid, &related_pid)
+ && ((pid == PIDGET (inferior_ptid))
+ || (related_pid == PIDGET (inferior_ptid))))
+ {
+ ourstatus->kind = TARGET_WAITKIND_FORKED;
+ ourstatus->value.related_pid = related_pid;
+ return pid_to_ptid (pid);
+ }
+
+ if (target_has_vforked (pid, &related_pid)
+ && ((pid == PIDGET (inferior_ptid))
+ || (related_pid == PIDGET (inferior_ptid))))
+ {
+ ourstatus->kind = TARGET_WAITKIND_VFORKED;
+ ourstatus->value.related_pid = related_pid;
+ return pid_to_ptid (pid);
+ }
+
+ if (target_has_execd (pid, &execd_pathname))
+ {
+ /* Are we ignoring initial exec events? (This is likely because
+ we're in the process of starting up the inferior, and another
+ (older) mechanism handles those.) If so, we'll report this
+ as a regular stop, not an exec.
+ */
+ if (inferior_ignoring_startup_exec_events)
+ {
+ inferior_ignoring_startup_exec_events--;
+ }
+ else
+ {
+ ourstatus->kind = TARGET_WAITKIND_EXECD;
+ ourstatus->value.execd_pathname = execd_pathname;
+ return pid_to_ptid (pid);
+ }
+ }
+
+ /* All we must do with these is communicate their occurrence
+ to wait_for_inferior...
+ */
+ if (target_has_syscall_event (pid, &kind, &syscall_id))
+ {
+ ourstatus->kind = kind;
+ ourstatus->value.syscall_id = syscall_id;
+ return pid_to_ptid (pid);
+ }
+
+ /*## } while (pid != PIDGET (inferior_ptid)); ## *//* Some other child died or stopped */
+/* hack for thread testing */
+ }
+ while ((pid != PIDGET (inferior_ptid)) && not_same_real_pid);
+/*## */
+
+ store_waitstatus (ourstatus, status);
+ return pid_to_ptid (pid);
+}
+#endif /* CHILD_WAIT */
+
+#if !defined(CHILD_POST_WAIT)
+void
+child_post_wait (ptid_t ptid, int wait_status)
+{
+ /* This version of Unix doesn't require a meaningful "post wait"
+ operation.
+ */
+}
+#endif
+
+
+#ifndef CHILD_THREAD_ALIVE
+
+/* Check to see if the given thread is alive.
+
+ FIXME: Is kill() ever the right way to do this? I doubt it, but
+ for now we're going to try and be compatable with the old thread
+ code. */
+int
+child_thread_alive (ptid_t ptid)
+{
+ pid_t pid = PIDGET (ptid);
+
+ return (kill (pid, 0) != -1);
+}
+
+#endif
+
+static void
+child_attach_to_process (char *args, int from_tty, int after_fork)
+{
+ if (!args)
+ error_no_arg ("process-id to attach");
+
+#ifndef ATTACH_DETACH
+ error ("Can't attach to a process on this machine.");
+#else
+ {
+ char *exec_file;
+ int pid;
+ char *dummy;
+
+ dummy = args;
+ pid = strtol (args, &dummy, 0);
+ /* Some targets don't set errno on errors, grrr! */
+ if ((pid == 0) && (args == dummy))
+ error ("Illegal process-id: %s\n", args);
+
+ if (pid == getpid ()) /* Trying to masturbate? */
+ error ("I refuse to debug myself!");
+
+ if (from_tty)
+ {
+ exec_file = (char *) get_exec_file (0);
+
+ if (after_fork)
+ printf_unfiltered ("Attaching after fork to %s\n",
+ target_pid_to_str (pid_to_ptid (pid)));
+ else if (exec_file)
+ printf_unfiltered ("Attaching to program: %s, %s\n", exec_file,
+ target_pid_to_str (pid_to_ptid (pid)));
+ else
+ printf_unfiltered ("Attaching to %s\n",
+ target_pid_to_str (pid_to_ptid (pid)));
+
+ gdb_flush (gdb_stdout);
+ }
+
+ if (!after_fork)
+ attach (pid);
+ else
+ REQUIRE_ATTACH (pid);
+
+ inferior_ptid = pid_to_ptid (pid);
+ push_target (&child_ops);
+ }
+#endif /* ATTACH_DETACH */
+}
+
+
+/* Attach to process PID, then initialize for debugging it. */
+
+static void
+child_attach (char *args, int from_tty)
+{
+ child_attach_to_process (args, from_tty, 0);
+}
+
+#if !defined(CHILD_POST_ATTACH)
+void
+child_post_attach (int pid)
+{
+ /* This version of Unix doesn't require a meaningful "post attach"
+ operation by a debugger. */
+}
+#endif
+
+static void
+child_require_attach (char *args, int from_tty)
+{
+ child_attach_to_process (args, from_tty, 1);
+}
+
+static void
+child_detach_from_process (int pid, char *args, int from_tty, int after_fork)
+{
+#ifdef ATTACH_DETACH
+ {
+ int siggnal = 0;
+
+ if (from_tty)
+ {
+ char *exec_file = get_exec_file (0);
+ if (exec_file == 0)
+ exec_file = "";
+ if (after_fork)
+ printf_unfiltered ("Detaching after fork from %s\n",
+ target_pid_to_str (pid_to_ptid (pid)));
+ else
+ printf_unfiltered ("Detaching from program: %s, %s\n", exec_file,
+ target_pid_to_str (pid_to_ptid (pid)));
+ gdb_flush (gdb_stdout);
+ }
+ if (args)
+ siggnal = atoi (args);
+
+ if (!after_fork)
+ detach (siggnal);
+ else
+ REQUIRE_DETACH (pid, siggnal);
+ }
+#else
+ error ("This version of Unix does not support detaching a process.");
+#endif
+}
+
+/* Take a program previously attached to and detaches it.
+ The program resumes execution and will no longer stop
+ on signals, etc. We'd better not have left any breakpoints
+ in the program or it'll die when it hits one. For this
+ to work, it may be necessary for the process to have been
+ previously attached. It *might* work if the program was
+ started via the normal ptrace (PTRACE_TRACEME). */
+
+static void
+child_detach (char *args, int from_tty)
+{
+ child_detach_from_process (PIDGET (inferior_ptid), args, from_tty, 0);
+ inferior_ptid = null_ptid;
+ unpush_target (&child_ops);
+}
+
+static void
+child_require_detach (int pid, char *args, int from_tty)
+{
+ child_detach_from_process (pid, args, from_tty, 1);
+}
+
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+static void
+child_prepare_to_store (void)
+{
+#ifdef CHILD_PREPARE_TO_STORE
+ CHILD_PREPARE_TO_STORE ();
+#endif
+}
+
+/* Print status information about what we're accessing. */
+
+static void
+child_files_info (struct target_ops *ignore)
+{
+ printf_unfiltered ("\tUsing the running image of %s %s.\n",
+ attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
+}
+
+/* ARGSUSED */
+static void
+child_open (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. */
+
+static void
+ptrace_me (void)
+{
+ /* "Trace me, Dr. Memory!" */
+ call_ptrace (0, 0, (PTRACE_ARG3_TYPE) 0, 0);
+}
+
+/* Stub function which causes the GDB that runs it, to start ptrace-ing
+ the child process. */
+
+static void
+ptrace_him (int pid)
+{
+ push_target (&child_ops);
+
+ /* On some targets, there must be some explicit synchronization
+ between the parent and child processes after the debugger
+ forks, and before the child execs the debuggee program. This
+ call basically gives permission for the child to exec.
+ */
+
+ target_acknowledge_created_inferior (pid);
+
+ /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h,
+ * and will be 1 or 2 depending on whether we're starting
+ * without or with a shell.
+ */
+ startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
+
+ /* On some targets, there must be some explicit actions taken after
+ the inferior has been started up.
+ */
+ target_post_startup_inferior (pid_to_ptid (pid));
+}
+
+/* Start an inferior Unix child process and sets inferior_ptid 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 (char *exec_file, char *allargs, char **env)
+{
+#ifdef HPUXHPPA
+ fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, pre_fork_inferior, NULL);
+#else
+ fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, NULL, NULL);
+#endif
+ /* We are at the first instruction we care about. */
+ /* Pedal to the metal... */
+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
+}
+
+#if !defined(CHILD_POST_STARTUP_INFERIOR)
+void
+child_post_startup_inferior (ptid_t ptid)
+{
+ /* This version of Unix doesn't require a meaningful "post startup inferior"
+ operation by a debugger.
+ */
+}
+#endif
+
+#if !defined(CHILD_ACKNOWLEDGE_CREATED_INFERIOR)
+void
+child_acknowledge_created_inferior (int pid)
+{
+ /* This version of Unix doesn't require a meaningful "acknowledge created inferior"
+ operation by a debugger.
+ */
+}
+#endif
+
+
+void
+child_clone_and_follow_inferior (int child_pid, int *followed_child)
+{
+ clone_and_follow_inferior (child_pid, followed_child);
+
+ /* Don't resume CHILD_PID; it's stopped where it ought to be, until
+ the decision gets made elsewhere how to continue it.
+ */
+}
+
+
+#if !defined(CHILD_POST_FOLLOW_INFERIOR_BY_CLONE)
+void
+child_post_follow_inferior_by_clone (void)
+{
+ /* This version of Unix doesn't require a meaningful "post follow inferior"
+ operation by a clone debugger.
+ */
+}
+#endif
+
+#if !defined(CHILD_INSERT_FORK_CATCHPOINT)
+int
+child_insert_fork_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of fork events. */
+ return 0;
+}
+#endif
+
+#if !defined(CHILD_REMOVE_FORK_CATCHPOINT)
+int
+child_remove_fork_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of fork events. */
+ return 0;
+}
+#endif
+
+#if !defined(CHILD_INSERT_VFORK_CATCHPOINT)
+int
+child_insert_vfork_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of vfork events. */
+ return 0;
+}
+#endif
+
+#if !defined(CHILD_REMOVE_VFORK_CATCHPOINT)
+int
+child_remove_vfork_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of vfork events. */
+ return 0;
+}
+#endif
+
+#if !defined(CHILD_HAS_FORKED)
+int
+child_has_forked (int pid, int *child_pid)
+{
+ /* This version of Unix doesn't support notification of fork events. */
+ return 0;
+}
+#endif
+
+
+#if !defined(CHILD_HAS_VFORKED)
+int
+child_has_vforked (int pid, int *child_pid)
+{
+ /* This version of Unix doesn't support notification of vfork events.
+ */
+ return 0;
+}
+#endif
+
+
+#if !defined(CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC)
+int
+child_can_follow_vfork_prior_to_exec (void)
+{
+ /* This version of Unix doesn't support notification of vfork events.
+ However, if it did, it probably wouldn't allow vforks to be followed
+ before the following exec.
+ */
+ return 0;
+}
+#endif
+
+
+#if !defined(CHILD_POST_FOLLOW_VFORK)
+void
+child_post_follow_vfork (int parent_pid, int followed_parent, int child_pid,
+ int followed_child)
+{
+ /* This version of Unix doesn't require a meaningful "post follow vfork"
+ operation by a clone debugger.
+ */
+}
+#endif
+
+#if !defined(CHILD_INSERT_EXEC_CATCHPOINT)
+int
+child_insert_exec_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of exec events. */
+ return 0;
+}
+#endif
+
+#if !defined(CHILD_REMOVE_EXEC_CATCHPOINT)
+int
+child_remove_exec_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of exec events. */
+ return 0;
+}
+#endif
+
+#if !defined(CHILD_HAS_EXECD)
+int
+child_has_execd (int pid, char **execd_pathname)
+{
+ /* This version of Unix doesn't support notification of exec events.
+ */
+ return 0;
+}
+#endif
+
+
+#if !defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL)
+int
+child_reported_exec_events_per_exec_call (void)
+{
+ /* This version of Unix doesn't support notification of exec events.
+ */
+ return 1;
+}
+#endif
+
+
+#if !defined(CHILD_HAS_SYSCALL_EVENT)
+int
+child_has_syscall_event (int pid, enum target_waitkind *kind, int *syscall_id)
+{
+ /* This version of Unix doesn't support notification of syscall events.
+ */
+ return 0;
+}
+#endif
+
+
+#if !defined(CHILD_HAS_EXITED)
+int
+child_has_exited (int pid, int wait_status, int *exit_status)
+{
+ if (WIFEXITED (wait_status))
+ {
+ *exit_status = WEXITSTATUS (wait_status);
+ return 1;
+ }
+
+ if (WIFSIGNALED (wait_status))
+ {
+ *exit_status = 0; /* ?? Don't know what else to say here. */
+ return 1;
+ }
+
+ /* ?? Do we really need to consult the event state, too? Assume the
+ wait_state alone suffices.
+ */
+ return 0;
+}
+#endif
+
+
+static void
+child_mourn_inferior (void)
+{
+ unpush_target (&child_ops);
+ generic_mourn_inferior ();
+}
+
+static int
+child_can_run (void)
+{
+ /* This variable is controlled by modules that sit atop inftarg that may layer
+ their own process structure atop that provided here. hpux-thread.c does
+ this because of the Hpux user-mode level thread model. */
+
+ return !child_suppress_run;
+}
+
+/* Send a SIGINT to the process group. This acts just like the user typed a
+ ^C on the controlling terminal.
+
+ XXX - This may not be correct for all systems. Some may want to use
+ killpg() instead of kill (-pgrp). */
+
+static void
+child_stop (void)
+{
+ extern pid_t inferior_process_group;
+
+ kill (-inferior_process_group, SIGINT);
+}
+
+#if !defined(CHILD_ENABLE_EXCEPTION_CALLBACK)
+struct symtab_and_line *
+child_enable_exception_callback (enum exception_event_kind kind, int enable)
+{
+ return (struct symtab_and_line *) NULL;
+}
+#endif
+
+#if !defined(CHILD_GET_CURRENT_EXCEPTION_EVENT)
+struct exception_event_record *
+child_get_current_exception_event (void)
+{
+ return (struct exception_event_record *) NULL;
+}
+#endif
+
+
+#if !defined(CHILD_PID_TO_EXEC_FILE)
+char *
+child_pid_to_exec_file (int pid)
+{
+ /* This version of Unix doesn't support translation of a process ID
+ to the filename of the executable file.
+ */
+ return NULL;
+}
+#endif
+
+char *
+child_core_file_to_sym_file (char *core)
+{
+ /* The target stratum for a running executable need not support
+ this operation.
+ */
+ return NULL;
+}
+
+
+#if !defined(CHILD_PID_TO_STR)
+char *
+child_pid_to_str (ptid_t ptid)
+{
+ return normal_pid_to_str (ptid);
+}
+#endif
+
+static void
+init_child_ops (void)
+{
+ child_ops.to_shortname = "child";
+ child_ops.to_longname = "Unix child process";
+ child_ops.to_doc = "Unix child process (started by the \"run\" command).";
+ child_ops.to_open = child_open;
+ child_ops.to_attach = child_attach;
+ child_ops.to_post_attach = child_post_attach;
+ child_ops.to_require_attach = child_require_attach;
+ child_ops.to_detach = child_detach;
+ child_ops.to_require_detach = child_require_detach;
+ child_ops.to_resume = child_resume;
+ child_ops.to_wait = child_wait;
+ child_ops.to_post_wait = child_post_wait;
+ child_ops.to_fetch_registers = fetch_inferior_registers;
+ child_ops.to_store_registers = store_inferior_registers;
+ child_ops.to_prepare_to_store = child_prepare_to_store;
+ child_ops.to_xfer_memory = child_xfer_memory;
+ child_ops.to_files_info = child_files_info;
+ child_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ child_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ child_ops.to_terminal_init = terminal_init_inferior;
+ child_ops.to_terminal_inferior = terminal_inferior;
+ child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ child_ops.to_terminal_ours = terminal_ours;
+ child_ops.to_terminal_info = child_terminal_info;
+ child_ops.to_kill = kill_inferior;
+ child_ops.to_create_inferior = child_create_inferior;
+ child_ops.to_post_startup_inferior = child_post_startup_inferior;
+ child_ops.to_acknowledge_created_inferior = child_acknowledge_created_inferior;
+ child_ops.to_clone_and_follow_inferior = child_clone_and_follow_inferior;
+ child_ops.to_post_follow_inferior_by_clone = child_post_follow_inferior_by_clone;
+ child_ops.to_insert_fork_catchpoint = child_insert_fork_catchpoint;
+ child_ops.to_remove_fork_catchpoint = child_remove_fork_catchpoint;
+ child_ops.to_insert_vfork_catchpoint = child_insert_vfork_catchpoint;
+ child_ops.to_remove_vfork_catchpoint = child_remove_vfork_catchpoint;
+ child_ops.to_has_forked = child_has_forked;
+ child_ops.to_has_vforked = child_has_vforked;
+ child_ops.to_can_follow_vfork_prior_to_exec = child_can_follow_vfork_prior_to_exec;
+ child_ops.to_post_follow_vfork = child_post_follow_vfork;
+ child_ops.to_insert_exec_catchpoint = child_insert_exec_catchpoint;
+ child_ops.to_remove_exec_catchpoint = child_remove_exec_catchpoint;
+ child_ops.to_has_execd = child_has_execd;
+ child_ops.to_reported_exec_events_per_exec_call = child_reported_exec_events_per_exec_call;
+ child_ops.to_has_syscall_event = child_has_syscall_event;
+ child_ops.to_has_exited = child_has_exited;
+ child_ops.to_mourn_inferior = child_mourn_inferior;
+ child_ops.to_can_run = child_can_run;
+ child_ops.to_thread_alive = child_thread_alive;
+ child_ops.to_pid_to_str = child_pid_to_str;
+ child_ops.to_stop = child_stop;
+ child_ops.to_enable_exception_callback = child_enable_exception_callback;
+ child_ops.to_get_current_exception_event = child_get_current_exception_event;
+ child_ops.to_pid_to_exec_file = child_pid_to_exec_file;
+ child_ops.to_stratum = process_stratum;
+ child_ops.to_has_all_memory = 1;
+ child_ops.to_has_memory = 1;
+ child_ops.to_has_stack = 1;
+ child_ops.to_has_registers = 1;
+ child_ops.to_has_execution = 1;
+ child_ops.to_magic = OPS_MAGIC;
+}
+
+/* Take over the 'find_mapped_memory' vector from inftarg.c. */
+extern void
+inftarg_set_find_memory_regions (int (*func) (int (*) (CORE_ADDR,
+ unsigned long,
+ int, int, int,
+ void *),
+ void *))
+{
+ child_ops.to_find_memory_regions = func;
+}
+
+/* Take over the 'make_corefile_notes' vector from inftarg.c. */
+extern void
+inftarg_set_make_corefile_notes (char * (*func) (bfd *, int *))
+{
+ child_ops.to_make_corefile_notes = func;
+}
+
+void
+_initialize_inftarg (void)
+{
+#ifdef HAVE_OPTIONAL_PROC_FS
+ char procname[32];
+ int fd;
+
+ /* If we have an optional /proc filesystem (e.g. under OSF/1),
+ don't add ptrace support if we can access the running GDB via /proc. */
+#ifndef PROC_NAME_FMT
+#define PROC_NAME_FMT "/proc/%05d"
+#endif
+ sprintf (procname, PROC_NAME_FMT, getpid ());
+ if ((fd = open (procname, O_RDONLY)) >= 0)
+ {
+ close (fd);
+ return;
+ }
+#endif
+
+ init_child_ops ();
+ add_target (&child_ops);
+}
diff --git a/gdb/infttrace.c b/gdb/infttrace.c
new file mode 100644
index 00000000000..7433b7c7292
--- /dev/null
+++ b/gdb/infttrace.c
@@ -0,0 +1,5754 @@
+/* Low level Unix child interface to ttrace, for GDB when running under HP-UX.
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
+ 1999, 2000, 2001
+ 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdb_string.h"
+#include "gdb_wait.h"
+#include "command.h"
+
+/* We need pstat functionality so that we can get the exec file
+ for a process we attach to.
+
+ According to HP, we should use the 64bit interfaces, so we
+ define _PSTAT64 to achieve this. */
+#define _PSTAT64
+#include <sys/pstat.h>
+
+/* Some hackery to work around a use of the #define name NO_FLAGS
+ * in both gdb and HPUX (bfd.h and /usr/include/machine/vmparam.h).
+ */
+#ifdef NO_FLAGS
+#define INFTTRACE_TEMP_HACK NO_FLAGS
+#undef NO_FLAGS
+#endif
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+
+#include <sys/ttrace.h>
+#include <sys/mman.h>
+
+#ifndef NO_PTRACE_H
+#ifdef PTRACE_IN_WRONG_PLACE
+#include <ptrace.h>
+#else
+#include <sys/ptrace.h>
+#endif
+#endif /* NO_PTRACE_H */
+
+/* Second half of the hackery above. Non-ANSI C, so
+ * we can't use "#error", alas.
+ */
+#ifdef NO_FLAGS
+#if (NO_FLAGS != INFTTRACE_TEMP_HACK )
+ /* #error "Hackery to remove warning didn't work right" */
+#else
+ /* Ok, new def'n of NO_FLAGS is same as old one; no action needed. */
+#endif
+#else
+ /* #error "Didn't get expected re-definition of NO_FLAGS" */
+#define NO_FLAGS INFTTRACE_TEMP_HACK
+#endif
+
+#if !defined (PT_SETTRC)
+#define PT_SETTRC 0 /* Make process traceable by parent */
+#endif
+#if !defined (PT_READ_I)
+#define PT_READ_I 1 /* Read word from text space */
+#endif
+#if !defined (PT_READ_D)
+#define PT_READ_D 2 /* Read word from data space */
+#endif
+#if !defined (PT_READ_U)
+#define PT_READ_U 3 /* Read word from kernel user struct */
+#endif
+#if !defined (PT_WRITE_I)
+#define PT_WRITE_I 4 /* Write word to text space */
+#endif
+#if !defined (PT_WRITE_D)
+#define PT_WRITE_D 5 /* Write word to data space */
+#endif
+#if !defined (PT_WRITE_U)
+#define PT_WRITE_U 6 /* Write word to kernel user struct */
+#endif
+#if !defined (PT_CONTINUE)
+#define PT_CONTINUE 7 /* Continue after signal */
+#endif
+#if !defined (PT_STEP)
+#define PT_STEP 9 /* Set flag for single stepping */
+#endif
+#if !defined (PT_KILL)
+#define PT_KILL 8 /* Send child a SIGKILL signal */
+#endif
+
+#ifndef PT_ATTACH
+#define PT_ATTACH PTRACE_ATTACH
+#endif
+#ifndef PT_DETACH
+#define PT_DETACH PTRACE_DETACH
+#endif
+
+#include "gdbcore.h"
+#ifndef NO_SYS_FILE
+#include <sys/file.h>
+#endif
+
+/* This semaphore is used to coordinate the child and parent processes
+ after a fork(), and before an exec() by the child. See parent_attach_all
+ for details.
+ */
+typedef struct
+ {
+ int parent_channel[2]; /* Parent "talks" to [1], child "listens" to [0] */
+ int child_channel[2]; /* Child "talks" to [1], parent "listens" to [0] */
+ }
+startup_semaphore_t;
+
+#define SEM_TALK (1)
+#define SEM_LISTEN (0)
+
+static startup_semaphore_t startup_semaphore;
+
+/* See can_touch_threads_of_process for details. */
+static int vforking_child_pid = 0;
+static int vfork_in_flight = 0;
+
+/* To support PREPARE_TO_PROCEED (hppa_prepare_to_proceed).
+ */
+static pid_t old_gdb_pid = 0;
+static pid_t reported_pid = 0;
+static int reported_bpt = 0;
+
+/* 1 if ok as results of a ttrace or ttrace_wait call, 0 otherwise.
+ */
+#define TT_OK( _status, _errno ) \
+ (((_status) == 1) && ((_errno) == 0))
+
+#define TTRACE_ARG_TYPE uint64_t
+
+/* When supplied as the "addr" operand, ttrace interprets this
+ to mean, "from the current address".
+ */
+#define TT_USE_CURRENT_PC ((TTRACE_ARG_TYPE) TT_NOPC)
+
+/* When supplied as the "addr", "data" or "addr2" operand for most
+ requests, ttrace interprets this to mean, "pay no heed to this
+ argument".
+ */
+#define TT_NIL ((TTRACE_ARG_TYPE) TT_NULLARG)
+
+/* This is capable of holding the value of a 32-bit register. The
+ value is always left-aligned in the buffer; i.e., [0] contains
+ the most-significant byte of the register's value, and [sizeof(reg)]
+ contains the least-significant value.
+
+ ??rehrauer: Yes, this assumes that an int is 32-bits on HP-UX, and
+ that registers are 32-bits on HP-UX. The latter assumption changes
+ with PA2.0.
+ */
+typedef int register_value_t;
+
+/********************************************************************
+
+ How this works:
+
+ 1. Thread numbers
+
+ The rest of GDB sees threads as being things with different
+ "pid" (process id) values. See "thread.c" for details. The
+ separate threads will be seen and reacted to if infttrace passes
+ back different pid values (for _events_). See wait_for_inferior
+ in inftarg.c.
+
+ So infttrace is going to use thread ids externally, pretending
+ they are process ids, and keep track internally so that it can
+ use the real process id (and thread id) when calling ttrace.
+
+ The data structure that supports this is a linked list of the
+ current threads. Since at some date infttrace will have to
+ deal with multiple processes, each list element records its
+ corresponding pid, rather than having a single global.
+
+ Note that the list is only approximately current; that's ok, as
+ it's up to date when we need it (we hope!). Also, it can contain
+ dead threads, as there's no harm if it does.
+
+ The approach taken here is to bury the translation from external
+ to internal inside "call_ttrace" and a few other places.
+
+ There are some wrinkles:
+
+ o When GDB forks itself to create the debug target process,
+ there's only a pid of 0 around in the child, so the
+ TT_PROC_SETTRC operation uses a more direct call to ttrace;
+ Similiarly, the initial setting of the event mask happens
+ early as well, and so is also special-cased, and an attach
+ uses a real pid;
+
+ o We define an unthreaded application as having a "pseudo"
+ thread;
+
+ o To keep from confusing the rest of GDB, we don't switch
+ the PID for the pseudo thread to a TID. A table will help:
+
+ Rest of GDB sees these PIDs: pid tid1 tid2 tid3 ...
+
+ Our thread list stores: pid pid pid pid ...
+ tid0 tid1 tid2 tid3
+
+ Ttrace sees these TIDS: tid0 tid1 tid2 tid3 ...
+
+ Both pid and tid0 will map to tid0, as there are infttrace.c-internal
+ calls to ttrace using tid0.
+
+ 2. Step and Continue
+
+ Since we're implementing the "stop the world" model, sub-model
+ "other threads run during step", we have some stuff to do:
+
+ o User steps require continuing all threads other than the
+ one the user is stepping;
+
+ o Internal debugger steps (such as over a breakpoint or watchpoint,
+ but not out of a library load thunk) require stepping only
+ the selected thread; this means that we have to report the
+ step finish on that thread, which can lead to complications;
+
+ o When a thread is created, it is created running, rather
+ than stopped--so we have to stop it.
+
+ The OS doesn't guarantee the stopped thread list will be stable,
+ no does it guarantee where on the stopped thread list a thread
+ that is single-stepped will wind up: it's possible that it will
+ be off the list for a while, it's possible the step will complete
+ and it will be re-posted to the end...
+
+ This means we have to scan the stopped thread list, build up
+ a work-list, and then run down the work list; we can't do the
+ step/continue during the scan.
+
+ 3. Buffering events
+
+ Then there's the issue of waiting for an event. We do this by
+ noticing how many events are reported at the end of each wait.
+ From then on, we "fake" all resumes and steps, returning instantly,
+ and don't do another wait. Once all pending events are reported,
+ we can really resume again.
+
+ To keep this hidden, all the routines which know about tids and
+ pids or real events and simulated ones are static (file-local).
+
+ This code can make lots of calls to ttrace, in particular it
+ can spin down the list of thread states more than once. If this
+ becomes a performance hit, the spin could be done once and the
+ various "tsp" blocks saved, keeping all later spins in this
+ process.
+
+ The O/S doesn't promise to keep the list straight, and so we must
+ re-scan a lot. By observation, it looks like a single-step/wait
+ puts the stepped thread at the end of the list but doesn't change
+ it otherwise.
+
+****************************************************************
+*/
+
+/* Uncomment these to turn on various debugging output */
+/* #define THREAD_DEBUG */
+/* #define WAIT_BUFFER_DEBUG */
+/* #define PARANOIA */
+
+
+#define INFTTRACE_ALL_THREADS (-1)
+#define INFTTRACE_STEP (1)
+#define INFTTRACE_CONTINUE (0)
+
+/* FIX: this is used in inftarg.c/child_wait, in a hack.
+ */
+extern int not_same_real_pid;
+
+/* This is used to count buffered events.
+ */
+static unsigned int more_events_left = 0;
+
+/* Process state.
+ */
+typedef enum process_state_enum
+ {
+ STOPPED,
+ FAKE_STEPPING,
+ FAKE_CONTINUE, /* For later use */
+ RUNNING,
+ FORKING,
+ VFORKING
+ }
+process_state_t;
+
+static process_state_t process_state = STOPPED;
+
+/* User-specified stepping modality.
+ */
+typedef enum stepping_mode_enum
+ {
+ DO_DEFAULT, /* ...which is a continue! */
+ DO_STEP,
+ DO_CONTINUE
+ }
+stepping_mode_t;
+
+/* Action to take on an attach, depends on
+ * what kind (user command, fork, vfork).
+ *
+ * At the moment, this is either:
+ *
+ * o continue with a SIGTRAP signal, or
+ *
+ * o leave stopped.
+ */
+typedef enum attach_continue_enum
+ {
+ DO_ATTACH_CONTINUE,
+ DONT_ATTACH_CONTINUE
+ }
+attach_continue_t;
+
+/* This flag is true if we are doing a step-over-bpt
+ * with buffered events. We will have to be sure to
+ * report the right thread, as otherwise the spaghetti
+ * code in "infrun.c/wait_for_inferior" will get
+ * confused.
+ */
+static int doing_fake_step = 0;
+static lwpid_t fake_step_tid = 0;
+
+
+/****************************************************
+ * Thread information structure routines and types. *
+ ****************************************************
+ */
+typedef
+struct thread_info_struct
+ {
+ int am_pseudo; /* This is a pseudo-thread for the process. */
+ int pid; /* Process ID */
+ lwpid_t tid; /* Thread ID */
+ int handled; /* 1 if a buffered event was handled. */
+ int seen; /* 1 if this thread was seen on a traverse. */
+ int terminated; /* 1 if thread has terminated. */
+ int have_signal; /* 1 if signal to be sent */
+ enum target_signal signal_value; /* Signal to send */
+ int have_start; /* 1 if alternate starting address */
+ stepping_mode_t stepping_mode; /* Whether to step or continue */
+ CORE_ADDR start; /* Where to start */
+ int have_state; /* 1 if the event state has been set */
+ ttstate_t last_stop_state; /* The most recently-waited event for this thread. */
+ struct thread_info_struct
+ *next; /* All threads are linked via this field. */
+ struct thread_info_struct
+ *next_pseudo; /* All pseudo-threads are linked via this field. */
+ }
+thread_info;
+
+typedef
+struct thread_info_header_struct
+ {
+ int count;
+ thread_info *head;
+ thread_info *head_pseudo;
+
+ }
+thread_info_header;
+
+static thread_info_header thread_head =
+{0, NULL, NULL};
+static thread_info_header deleted_threads =
+{0, NULL, NULL};
+
+static ptid_t saved_real_ptid;
+
+
+/*************************************************
+ * Debugging support functions *
+ *************************************************
+ */
+CORE_ADDR
+get_raw_pc (lwpid_t ttid)
+{
+ unsigned long pc_val;
+ int offset;
+ int res;
+
+ offset = register_addr (PC_REGNUM, U_REGS_OFFSET);
+ res = read_from_register_save_state (
+ ttid,
+ (TTRACE_ARG_TYPE) offset,
+ (char *) &pc_val,
+ sizeof (pc_val));
+ if (res <= 0)
+ {
+ return (CORE_ADDR) pc_val;
+ }
+ else
+ {
+ return (CORE_ADDR) 0;
+ }
+}
+
+static char *
+get_printable_name_of_stepping_mode (stepping_mode_t mode)
+{
+ switch (mode)
+ {
+ case DO_DEFAULT:
+ return "DO_DEFAULT";
+ case DO_STEP:
+ return "DO_STEP";
+ case DO_CONTINUE:
+ return "DO_CONTINUE";
+ default:
+ return "?unknown mode?";
+ }
+}
+
+/* This function returns a pointer to a string describing the
+ * ttrace event being reported.
+ */
+char *
+get_printable_name_of_ttrace_event (ttevents_t event)
+{
+ /* This enumeration is "gappy", so don't use a table. */
+ switch (event)
+ {
+
+ case TTEVT_NONE:
+ return "TTEVT_NONE";
+ case TTEVT_SIGNAL:
+ return "TTEVT_SIGNAL";
+ case TTEVT_FORK:
+ return "TTEVT_FORK";
+ case TTEVT_EXEC:
+ return "TTEVT_EXEC";
+ case TTEVT_EXIT:
+ return "TTEVT_EXIT";
+ case TTEVT_VFORK:
+ return "TTEVT_VFORK";
+ case TTEVT_SYSCALL_RETURN:
+ return "TTEVT_SYSCALL_RETURN";
+ case TTEVT_LWP_CREATE:
+ return "TTEVT_LWP_CREATE";
+ case TTEVT_LWP_TERMINATE:
+ return "TTEVT_LWP_TERMINATE";
+ case TTEVT_LWP_EXIT:
+ return "TTEVT_LWP_EXIT";
+ case TTEVT_LWP_ABORT_SYSCALL:
+ return "TTEVT_LWP_ABORT_SYSCALL";
+ case TTEVT_SYSCALL_ENTRY:
+ return "TTEVT_SYSCALL_ENTRY";
+ case TTEVT_SYSCALL_RESTART:
+ return "TTEVT_SYSCALL_RESTART";
+ default:
+ return "?new event?";
+ }
+}
+
+
+/* This function translates the ttrace request enumeration into
+ * a character string that is its printable (aka "human readable")
+ * name.
+ */
+char *
+get_printable_name_of_ttrace_request (ttreq_t request)
+{
+ if (!IS_TTRACE_REQ (request))
+ return "?bad req?";
+
+ /* This enumeration is "gappy", so don't use a table. */
+ switch (request)
+ {
+ case TT_PROC_SETTRC:
+ return "TT_PROC_SETTRC";
+ case TT_PROC_ATTACH:
+ return "TT_PROC_ATTACH";
+ case TT_PROC_DETACH:
+ return "TT_PROC_DETACH";
+ case TT_PROC_RDTEXT:
+ return "TT_PROC_RDTEXT";
+ case TT_PROC_WRTEXT:
+ return "TT_PROC_WRTEXT";
+ case TT_PROC_RDDATA:
+ return "TT_PROC_RDDATA";
+ case TT_PROC_WRDATA:
+ return "TT_PROC_WRDATA";
+ case TT_PROC_STOP:
+ return "TT_PROC_STOP";
+ case TT_PROC_CONTINUE:
+ return "TT_PROC_CONTINUE";
+ case TT_PROC_GET_PATHNAME:
+ return "TT_PROC_GET_PATHNAME";
+ case TT_PROC_GET_EVENT_MASK:
+ return "TT_PROC_GET_EVENT_MASK";
+ case TT_PROC_SET_EVENT_MASK:
+ return "TT_PROC_SET_EVENT_MASK";
+ case TT_PROC_GET_FIRST_LWP_STATE:
+ return "TT_PROC_GET_FIRST_LWP_STATE";
+ case TT_PROC_GET_NEXT_LWP_STATE:
+ return "TT_PROC_GET_NEXT_LWP_STATE";
+ case TT_PROC_EXIT:
+ return "TT_PROC_EXIT";
+ case TT_PROC_GET_MPROTECT:
+ return "TT_PROC_GET_MPROTECT";
+ case TT_PROC_SET_MPROTECT:
+ return "TT_PROC_SET_MPROTECT";
+ case TT_PROC_SET_SCBM:
+ return "TT_PROC_SET_SCBM";
+ case TT_LWP_STOP:
+ return "TT_LWP_STOP";
+ case TT_LWP_CONTINUE:
+ return "TT_LWP_CONTINUE";
+ case TT_LWP_SINGLE:
+ return "TT_LWP_SINGLE";
+ case TT_LWP_RUREGS:
+ return "TT_LWP_RUREGS";
+ case TT_LWP_WUREGS:
+ return "TT_LWP_WUREGS";
+ case TT_LWP_GET_EVENT_MASK:
+ return "TT_LWP_GET_EVENT_MASK";
+ case TT_LWP_SET_EVENT_MASK:
+ return "TT_LWP_SET_EVENT_MASK";
+ case TT_LWP_GET_STATE:
+ return "TT_LWP_GET_STATE";
+ default:
+ return "?new req?";
+ }
+}
+
+
+/* This function translates the process state enumeration into
+ * a character string that is its printable (aka "human readable")
+ * name.
+ */
+static char *
+get_printable_name_of_process_state (process_state_t process_state)
+{
+ switch (process_state)
+ {
+ case STOPPED:
+ return "STOPPED";
+ case FAKE_STEPPING:
+ return "FAKE_STEPPING";
+ case RUNNING:
+ return "RUNNING";
+ case FORKING:
+ return "FORKING";
+ case VFORKING:
+ return "VFORKING";
+ default:
+ return "?some unknown state?";
+ }
+}
+
+/* Set a ttrace thread state to a safe, initial state.
+ */
+static void
+clear_ttstate_t (ttstate_t *tts)
+{
+ tts->tts_pid = 0;
+ tts->tts_lwpid = 0;
+ tts->tts_user_tid = 0;
+ tts->tts_event = TTEVT_NONE;
+}
+
+/* Copy ttrace thread state TTS_FROM into TTS_TO.
+ */
+static void
+copy_ttstate_t (ttstate_t *tts_to, ttstate_t *tts_from)
+{
+ memcpy ((char *) tts_to, (char *) tts_from, sizeof (*tts_to));
+}
+
+/* Are there any live threads we know about?
+ */
+static int
+any_thread_records (void)
+{
+ return (thread_head.count > 0);
+}
+
+/* Create, fill in and link in a thread descriptor.
+ */
+static thread_info *
+create_thread_info (int pid, lwpid_t tid)
+{
+ thread_info *new_p;
+ thread_info *p;
+ int thread_count_of_pid;
+
+ new_p = xmalloc (sizeof (thread_info));
+ new_p->pid = pid;
+ new_p->tid = tid;
+ new_p->have_signal = 0;
+ new_p->have_start = 0;
+ new_p->have_state = 0;
+ clear_ttstate_t (&new_p->last_stop_state);
+ new_p->am_pseudo = 0;
+ new_p->handled = 0;
+ new_p->seen = 0;
+ new_p->terminated = 0;
+ new_p->next = NULL;
+ new_p->next_pseudo = NULL;
+ new_p->stepping_mode = DO_DEFAULT;
+
+ if (0 == thread_head.count)
+ {
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("First thread, pid %d tid %d!\n", pid, tid);
+#endif
+ saved_real_ptid = inferior_ptid;
+ }
+ else
+ {
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Subsequent thread, pid %d tid %d\n", pid, tid);
+#endif
+ }
+
+ /* Another day, another thread...
+ */
+ thread_head.count++;
+
+ /* The new thread always goes at the head of the list.
+ */
+ new_p->next = thread_head.head;
+ thread_head.head = new_p;
+
+ /* Is this the "pseudo" thread of a process? It is if there's
+ * no other thread for this process on the list. (Note that this
+ * accomodates multiple processes, such as we see even for simple
+ * cases like forking "non-threaded" programs.)
+ */
+ p = thread_head.head;
+ thread_count_of_pid = 0;
+ while (p)
+ {
+ if (p->pid == new_p->pid)
+ thread_count_of_pid++;
+ p = p->next;
+ }
+
+ /* Did we see any other threads for this pid? (Recall that we just
+ * added this thread to the list...)
+ */
+ if (thread_count_of_pid == 1)
+ {
+ new_p->am_pseudo = 1;
+ new_p->next_pseudo = thread_head.head_pseudo;
+ thread_head.head_pseudo = new_p;
+ }
+
+ return new_p;
+}
+
+/* Get rid of our thread info.
+ */
+static void
+clear_thread_info (void)
+{
+ thread_info *p;
+ thread_info *q;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Clearing all thread info\n");
+#endif
+
+ p = thread_head.head;
+ while (p)
+ {
+ q = p;
+ p = p->next;
+ xfree (q);
+ }
+
+ thread_head.head = NULL;
+ thread_head.head_pseudo = NULL;
+ thread_head.count = 0;
+
+ p = deleted_threads.head;
+ while (p)
+ {
+ q = p;
+ p = p->next;
+ xfree (q);
+ }
+
+ deleted_threads.head = NULL;
+ deleted_threads.head_pseudo = NULL;
+ deleted_threads.count = 0;
+
+ /* No threads, so can't have pending events.
+ */
+ more_events_left = 0;
+}
+
+/* Given a tid, find the thread block for it.
+ */
+static thread_info *
+find_thread_info (lwpid_t tid)
+{
+ thread_info *p;
+
+ for (p = thread_head.head; p; p = p->next)
+ {
+ if (p->tid == tid)
+ {
+ return p;
+ }
+ }
+
+ for (p = deleted_threads.head; p; p = p->next)
+ {
+ if (p->tid == tid)
+ {
+ return p;
+ }
+ }
+
+ return NULL;
+}
+
+/* For any but the pseudo thread, this maps to the
+ * thread ID. For the pseudo thread, if you pass either
+ * the thread id or the PID, you get the pseudo thread ID.
+ *
+ * We have to be prepared for core gdb to ask about
+ * deleted threads. We do the map, but we don't like it.
+ */
+static lwpid_t
+map_from_gdb_tid (lwpid_t gdb_tid)
+{
+ thread_info *p;
+
+ /* First assume gdb_tid really is a tid, and try to find a
+ * matching entry on the threads list.
+ */
+ for (p = thread_head.head; p; p = p->next)
+ {
+ if (p->tid == gdb_tid)
+ return gdb_tid;
+ }
+
+ /* It doesn't appear to be a tid; perhaps it's really a pid?
+ * Try to find a "pseudo" thread entry on the threads list.
+ */
+ for (p = thread_head.head_pseudo; p != NULL; p = p->next_pseudo)
+ {
+ if (p->pid == gdb_tid)
+ return p->tid;
+ }
+
+ /* Perhaps it's the tid of a deleted thread we may still
+ * have some knowledge of?
+ */
+ for (p = deleted_threads.head; p; p = p->next)
+ {
+ if (p->tid == gdb_tid)
+ return gdb_tid;
+ }
+
+ /* Or perhaps it's the pid of a deleted process we may still
+ * have knowledge of?
+ */
+ for (p = deleted_threads.head_pseudo; p != NULL; p = p->next_pseudo)
+ {
+ if (p->pid == gdb_tid)
+ return p->tid;
+ }
+
+ return 0; /* Error? */
+}
+
+/* Map the other way: from a real tid to the
+ * "pid" known by core gdb. This tid may be
+ * for a thread that just got deleted, so we
+ * also need to consider deleted threads.
+ */
+static lwpid_t
+map_to_gdb_tid (lwpid_t real_tid)
+{
+ thread_info *p;
+
+ for (p = thread_head.head; p; p = p->next)
+ {
+ if (p->tid == real_tid)
+ {
+ if (p->am_pseudo)
+ return p->pid;
+ else
+ return real_tid;
+ }
+ }
+
+ for (p = deleted_threads.head; p; p = p->next)
+ {
+ if (p->tid == real_tid)
+ if (p->am_pseudo)
+ return p->pid; /* Error? */
+ else
+ return real_tid;
+ }
+
+ return 0; /* Error? Never heard of this thread! */
+}
+
+/* Do any threads have saved signals?
+ */
+static int
+saved_signals_exist (void)
+{
+ thread_info *p;
+
+ for (p = thread_head.head; p; p = p->next)
+ {
+ if (p->have_signal)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* Is this the tid for the zero-th thread?
+ */
+static int
+is_pseudo_thread (lwpid_t tid)
+{
+ thread_info *p = find_thread_info (tid);
+ if (NULL == p || p->terminated)
+ return 0;
+ else
+ return p->am_pseudo;
+}
+
+/* Is this thread terminated?
+ */
+static int
+is_terminated (lwpid_t tid)
+{
+ thread_info *p = find_thread_info (tid);
+
+ if (NULL != p)
+ return p->terminated;
+
+ return 0;
+}
+
+/* Is this pid a real PID or a TID?
+ */
+static int
+is_process_id (int pid)
+{
+ lwpid_t tid;
+ thread_info *tinfo;
+ pid_t this_pid;
+ int this_pid_count;
+
+ /* What does PID really represent?
+ */
+ tid = map_from_gdb_tid (pid);
+ if (tid <= 0)
+ return 0; /* Actually, is probably an error... */
+
+ tinfo = find_thread_info (tid);
+
+ /* Does it appear to be a true thread?
+ */
+ if (!tinfo->am_pseudo)
+ return 0;
+
+ /* Else, it looks like it may be a process. See if there's any other
+ * threads with the same process ID, though. If there are, then TID
+ * just happens to be the first thread of several for this process.
+ */
+ this_pid = tinfo->pid;
+ this_pid_count = 0;
+ for (tinfo = thread_head.head; tinfo; tinfo = tinfo->next)
+ {
+ if (tinfo->pid == this_pid)
+ this_pid_count++;
+ }
+
+ return (this_pid_count == 1);
+}
+
+
+/* Add a thread to our info. Prevent duplicate entries.
+ */
+static thread_info *
+add_tthread (int pid, lwpid_t tid)
+{
+ thread_info *p;
+
+ p = find_thread_info (tid);
+ if (NULL == p)
+ p = create_thread_info (pid, tid);
+
+ return p;
+}
+
+/* Notice that a thread was deleted.
+ */
+static void
+del_tthread (lwpid_t tid)
+{
+ thread_info *p;
+ thread_info *chase;
+
+ if (thread_head.count <= 0)
+ {
+ error ("Internal error in thread database.");
+ return;
+ }
+
+ chase = NULL;
+ for (p = thread_head.head; p; p = p->next)
+ {
+ if (p->tid == tid)
+ {
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Delete here: %d \n", tid);
+#endif
+
+ if (p->am_pseudo)
+ {
+ /*
+ * Deleting a main thread is ok if we're doing
+ * a parent-follow on a child; this is odd but
+ * not wrong. It apparently _doesn't_ happen
+ * on the child-follow, as we don't just delete
+ * the pseudo while keeping the rest of the
+ * threads around--instead, we clear out the whole
+ * thread list at once.
+ */
+ thread_info *q;
+ thread_info *q_chase;
+
+ q_chase = NULL;
+ for (q = thread_head.head_pseudo; q; q = q->next)
+ {
+ if (q == p)
+ {
+ /* Remove from pseudo list.
+ */
+ if (q_chase == NULL)
+ thread_head.head_pseudo = p->next_pseudo;
+ else
+ q_chase->next = p->next_pseudo;
+ }
+ else
+ q_chase = q;
+ }
+ }
+
+ /* Remove from live list.
+ */
+ thread_head.count--;
+
+ if (NULL == chase)
+ thread_head.head = p->next;
+ else
+ chase->next = p->next;
+
+ /* Add to deleted thread list.
+ */
+ p->next = deleted_threads.head;
+ deleted_threads.head = p;
+ deleted_threads.count++;
+ if (p->am_pseudo)
+ {
+ p->next_pseudo = deleted_threads.head_pseudo;
+ deleted_threads.head_pseudo = p;
+ }
+ p->terminated = 1;
+
+ return;
+ }
+
+ else
+ chase = p;
+ }
+}
+
+/* Get the pid for this tid. (Has to be a real TID!).
+ */
+static int
+get_pid_for (lwpid_t tid)
+{
+ thread_info *p;
+
+ for (p = thread_head.head; p; p = p->next)
+ {
+ if (p->tid == tid)
+ {
+ return p->pid;
+ }
+ }
+
+ for (p = deleted_threads.head; p; p = p->next)
+ {
+ if (p->tid == tid)
+ {
+ return p->pid;
+ }
+ }
+
+ return 0;
+}
+
+/* Note that this thread's current event has been handled.
+ */
+static void
+set_handled (int pid, lwpid_t tid)
+{
+ thread_info *p;
+
+ p = find_thread_info (tid);
+ if (NULL == p)
+ p = add_tthread (pid, tid);
+
+ p->handled = 1;
+}
+
+/* Was this thread's current event handled?
+ */
+static int
+was_handled (lwpid_t tid)
+{
+ thread_info *p;
+
+ p = find_thread_info (tid);
+ if (NULL != p)
+ return p->handled;
+
+ return 0; /* New threads have not been handled */
+}
+
+/* Set this thread to unhandled.
+ */
+static void
+clear_handled (lwpid_t tid)
+{
+ thread_info *p;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if (debug_on)
+ printf ("clear_handled %d\n", (int) tid);
+#endif
+
+ p = find_thread_info (tid);
+ if (p == NULL)
+ error ("Internal error: No thread state to clear?");
+
+ p->handled = 0;
+}
+
+/* Set all threads to unhandled.
+ */
+static void
+clear_all_handled (void)
+{
+ thread_info *p;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if (debug_on)
+ printf ("clear_all_handled\n");
+#endif
+
+ for (p = thread_head.head; p; p = p->next)
+ {
+ p->handled = 0;
+ }
+
+ for (p = deleted_threads.head; p; p = p->next)
+ {
+ p->handled = 0;
+ }
+}
+
+/* Set this thread to default stepping mode.
+ */
+static void
+clear_stepping_mode (lwpid_t tid)
+{
+ thread_info *p;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if (debug_on)
+ printf ("clear_stepping_mode %d\n", (int) tid);
+#endif
+
+ p = find_thread_info (tid);
+ if (p == NULL)
+ error ("Internal error: No thread state to clear?");
+
+ p->stepping_mode = DO_DEFAULT;
+}
+
+/* Set all threads to do default continue on resume.
+ */
+static void
+clear_all_stepping_mode (void)
+{
+ thread_info *p;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if (debug_on)
+ printf ("clear_all_stepping_mode\n");
+#endif
+
+ for (p = thread_head.head; p; p = p->next)
+ {
+ p->stepping_mode = DO_DEFAULT;
+ }
+
+ for (p = deleted_threads.head; p; p = p->next)
+ {
+ p->stepping_mode = DO_DEFAULT;
+ }
+}
+
+/* Set all threads to unseen on this pass.
+ */
+static void
+set_all_unseen (void)
+{
+ thread_info *p;
+
+ for (p = thread_head.head; p; p = p->next)
+ {
+ p->seen = 0;
+ }
+}
+
+#if (defined( THREAD_DEBUG ) || defined( PARANOIA ))
+/* debugging routine.
+ */
+static void
+print_tthread (thread_info *p)
+{
+ printf (" Thread pid %d, tid %d", p->pid, p->tid);
+ if (p->have_state)
+ printf (", event is %s",
+ get_printable_name_of_ttrace_event (p->last_stop_state.tts_event));
+
+ if (p->am_pseudo)
+ printf (", pseudo thread");
+
+ if (p->have_signal)
+ printf (", have signal 0x%x", p->signal_value);
+
+ if (p->have_start)
+ printf (", have start at 0x%x", p->start);
+
+ printf (", step is %s", get_printable_name_of_stepping_mode (p->stepping_mode));
+
+ if (p->handled)
+ printf (", handled");
+ else
+ printf (", not handled");
+
+ if (p->seen)
+ printf (", seen");
+ else
+ printf (", not seen");
+
+ printf ("\n");
+}
+
+static void
+print_tthreads (void)
+{
+ thread_info *p;
+
+ if (thread_head.count == 0)
+ printf ("Thread list is empty\n");
+ else
+ {
+ printf ("Thread list has ");
+ if (thread_head.count == 1)
+ printf ("1 entry:\n");
+ else
+ printf ("%d entries:\n", thread_head.count);
+ for (p = thread_head.head; p; p = p->next)
+ {
+ print_tthread (p);
+ }
+ }
+
+ if (deleted_threads.count == 0)
+ printf ("Deleted thread list is empty\n");
+ else
+ {
+ printf ("Deleted thread list has ");
+ if (deleted_threads.count == 1)
+ printf ("1 entry:\n");
+ else
+ printf ("%d entries:\n", deleted_threads.count);
+
+ for (p = deleted_threads.head; p; p = p->next)
+ {
+ print_tthread (p);
+ }
+ }
+}
+#endif
+
+/* Update the thread list based on the "seen" bits.
+ */
+static void
+update_thread_list (void)
+{
+ thread_info *p;
+ thread_info *chase;
+
+ chase = NULL;
+ for (p = thread_head.head; p; p = p->next)
+ {
+ /* Is this an "unseen" thread which really happens to be a process?
+ If so, is it inferior_ptid and is a vfork in flight? If yes to
+ all, then DON'T REMOVE IT! We're in the midst of moving a vfork
+ operation, which is a multiple step thing, to the point where we
+ can touch the parent again. We've most likely stopped to examine
+ the child at a late stage in the vfork, and if we're not following
+ the child, we'd best not treat the parent as a dead "thread"...
+ */
+ if ((!p->seen) && p->am_pseudo && vfork_in_flight
+ && (p->pid != vforking_child_pid))
+ p->seen = 1;
+
+ if (!p->seen)
+ {
+ /* Remove this one
+ */
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Delete unseen thread: %d \n", p->tid);
+#endif
+ del_tthread (p->tid);
+ }
+ }
+}
+
+
+
+/************************************************
+ * O/S call wrappers *
+ ************************************************
+ */
+
+/* This function simply calls ttrace with the given arguments.
+ * It exists so that all calls to ttrace are isolated. All
+ * parameters should be as specified by "man 2 ttrace".
+ *
+ * No other "raw" calls to ttrace should exist in this module.
+ */
+static int
+call_real_ttrace (ttreq_t request, pid_t pid, lwpid_t tid, TTRACE_ARG_TYPE addr,
+ TTRACE_ARG_TYPE data, TTRACE_ARG_TYPE addr2)
+{
+ int tt_status;
+
+ errno = 0;
+ tt_status = ttrace (request, pid, tid, addr, data, addr2);
+
+#ifdef THREAD_DEBUG
+ if (errno)
+ {
+ /* Don't bother for a known benign error: if you ask for the
+ * first thread state, but there is only one thread and it's
+ * not stopped, ttrace complains.
+ *
+ * We have this inside the #ifdef because our caller will do
+ * this check for real.
+ */
+ if (request != TT_PROC_GET_FIRST_LWP_STATE
+ || errno != EPROTO)
+ {
+ if (debug_on)
+ printf ("TT fail for %s, with pid %d, tid %d, status %d \n",
+ get_printable_name_of_ttrace_request (request),
+ pid, tid, tt_status);
+ }
+ }
+#endif
+
+#if 0
+ /* ??rehrauer: It would probably be most robust to catch and report
+ * failed requests here. However, some clients of this interface
+ * seem to expect to catch & deal with them, so we'd best not.
+ */
+ if (errno)
+ {
+ strcpy (reason_for_failure, "ttrace (");
+ strcat (reason_for_failure, get_printable_name_of_ttrace_request (request));
+ strcat (reason_for_failure, ")");
+ printf ("ttrace error, errno = %d\n", errno);
+ perror_with_name (reason_for_failure);
+ }
+#endif
+
+ return tt_status;
+}
+
+
+/* This function simply calls ttrace_wait with the given arguments.
+ * It exists so that all calls to ttrace_wait are isolated.
+ *
+ * No "raw" calls to ttrace_wait should exist elsewhere.
+ */
+static int
+call_real_ttrace_wait (int pid, lwpid_t tid, ttwopt_t option, ttstate_t *tsp,
+ size_t tsp_size)
+{
+ int ttw_status;
+ thread_info *tinfo = NULL;
+
+ errno = 0;
+ ttw_status = ttrace_wait (pid, tid, option, tsp, tsp_size);
+
+ if (errno)
+ {
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("TW fail with pid %d, tid %d \n", pid, tid);
+#endif
+
+ perror_with_name ("ttrace wait");
+ }
+
+ return ttw_status;
+}
+
+
+/* A process may have one or more kernel threads, of which all or
+ none may be stopped. This function returns the ID of the first
+ kernel thread in a stopped state, or 0 if none are stopped.
+
+ This function can be used with get_process_next_stopped_thread_id
+ to iterate over the IDs of all stopped threads of this process.
+ */
+static lwpid_t
+get_process_first_stopped_thread_id (int pid, ttstate_t *thread_state)
+{
+ int tt_status;
+
+ tt_status = call_real_ttrace (TT_PROC_GET_FIRST_LWP_STATE,
+ (pid_t) pid,
+ (lwpid_t) TT_NIL,
+ (TTRACE_ARG_TYPE) thread_state,
+ (TTRACE_ARG_TYPE) sizeof (*thread_state),
+ TT_NIL);
+
+ if (errno)
+ {
+ if (errno == EPROTO)
+ {
+ /* This is an error we can handle: there isn't any stopped
+ * thread. This happens when we're re-starting the application
+ * and it has only one thread. GET_NEXT handles the case of
+ * no more stopped threads well; GET_FIRST doesn't. (A ttrace
+ * "feature".)
+ */
+ tt_status = 1;
+ errno = 0;
+ return 0;
+ }
+ else
+ perror_with_name ("ttrace");
+ }
+
+ if (tt_status < 0)
+ /* Failed somehow.
+ */
+ return 0;
+
+ return thread_state->tts_lwpid;
+}
+
+
+/* This function returns the ID of the "next" kernel thread in a
+ stopped state, or 0 if there are none. "Next" refers to the
+ thread following that of the last successful call to this
+ function or to get_process_first_stopped_thread_id, using
+ the value of thread_state returned by that call.
+
+ This function can be used with get_process_first_stopped_thread_id
+ to iterate over the IDs of all stopped threads of this process.
+ */
+static lwpid_t
+get_process_next_stopped_thread_id (int pid, ttstate_t *thread_state)
+{
+ int tt_status;
+
+ tt_status = call_real_ttrace (
+ TT_PROC_GET_NEXT_LWP_STATE,
+ (pid_t) pid,
+ (lwpid_t) TT_NIL,
+ (TTRACE_ARG_TYPE) thread_state,
+ (TTRACE_ARG_TYPE) sizeof (*thread_state),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+
+ if (tt_status < 0)
+ /* Failed
+ */
+ return 0;
+
+ else if (tt_status == 0)
+ {
+ /* End of list, no next state. Don't return the
+ * tts_lwpid, as it's a meaningless "240".
+ *
+ * This is an HPUX "feature".
+ */
+ return 0;
+ }
+
+ return thread_state->tts_lwpid;
+}
+
+/* ??rehrauer: Eventually this function perhaps should be calling
+ pid_to_thread_id. However, that function currently does nothing
+ for HP-UX. Even then, I'm not clear whether that function
+ will return a "kernel" thread ID, or a "user" thread ID. If
+ the former, we can just call it here. If the latter, we must
+ map from the "user" tid to a "kernel" tid.
+
+ NOTE: currently not called.
+ */
+static lwpid_t
+get_active_tid_of_pid (int pid)
+{
+ ttstate_t thread_state;
+
+ return get_process_first_stopped_thread_id (pid, &thread_state);
+}
+
+/* This function returns 1 if tt_request is a ttrace request that
+ * operates upon all threads of a (i.e., the entire) process.
+ */
+int
+is_process_ttrace_request (ttreq_t tt_request)
+{
+ return IS_TTRACE_PROCREQ (tt_request);
+}
+
+
+/* This function translates a thread ttrace request into
+ * the equivalent process request for a one-thread process.
+ */
+static ttreq_t
+make_process_version (ttreq_t request)
+{
+ if (!IS_TTRACE_REQ (request))
+ {
+ error ("Internal error, bad ttrace request made\n");
+ return -1;
+ }
+
+ switch (request)
+ {
+ case TT_LWP_STOP:
+ return TT_PROC_STOP;
+
+ case TT_LWP_CONTINUE:
+ return TT_PROC_CONTINUE;
+
+ case TT_LWP_GET_EVENT_MASK:
+ return TT_PROC_GET_EVENT_MASK;
+
+ case TT_LWP_SET_EVENT_MASK:
+ return TT_PROC_SET_EVENT_MASK;
+
+ case TT_LWP_SINGLE:
+ case TT_LWP_RUREGS:
+ case TT_LWP_WUREGS:
+ case TT_LWP_GET_STATE:
+ return -1; /* No equivalent */
+
+ default:
+ return request;
+ }
+}
+
+
+/* This function translates the "pid" used by the rest of
+ * gdb to a real pid and a tid. It then calls "call_real_ttrace"
+ * with the given arguments.
+ *
+ * In general, other parts of this module should call this
+ * function when they are dealing with external users, who only
+ * have tids to pass (but they call it "pid" for historical
+ * reasons).
+ */
+static int
+call_ttrace (ttreq_t request, int gdb_tid, TTRACE_ARG_TYPE addr,
+ TTRACE_ARG_TYPE data, TTRACE_ARG_TYPE addr2)
+{
+ lwpid_t real_tid;
+ int real_pid;
+ ttreq_t new_request;
+ int tt_status;
+ char reason_for_failure[100]; /* Arbitrary size, should be big enough. */
+
+#ifdef THREAD_DEBUG
+ int is_interesting = 0;
+
+ if (TT_LWP_RUREGS == request)
+ {
+ is_interesting = 1; /* Adjust code here as desired */
+ }
+
+ if (is_interesting && 0 && debug_on)
+ {
+ if (!is_process_ttrace_request (request))
+ {
+ printf ("TT: Thread request, tid is %d", gdb_tid);
+ printf ("== SINGLE at %x", addr);
+ }
+ else
+ {
+ printf ("TT: Process request, tid is %d\n", gdb_tid);
+ printf ("==! SINGLE at %x", addr);
+ }
+ }
+#endif
+
+ /* The initial SETTRC and SET_EVENT_MASK calls (and all others
+ * which happen before any threads get set up) should go
+ * directly to "call_real_ttrace", so they don't happen here.
+ *
+ * But hardware watchpoints do a SET_EVENT_MASK, so we can't
+ * rule them out....
+ */
+#ifdef THREAD_DEBUG
+ if (request == TT_PROC_SETTRC && debug_on)
+ printf ("Unexpected call for TT_PROC_SETTRC\n");
+#endif
+
+ /* Sometimes we get called with a bogus tid (e.g., if a
+ * thread has terminated, we return 0; inftarg later asks
+ * whether the thread has exited/forked/vforked).
+ */
+ if (gdb_tid == 0)
+ {
+ errno = ESRCH; /* ttrace's response would probably be "No such process". */
+ return -1;
+ }
+
+ /* All other cases should be able to expect that there are
+ * thread records.
+ */
+ if (!any_thread_records ())
+ {
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ warning ("No thread records for ttrace call");
+#endif
+ errno = ESRCH; /* ttrace's response would be "No such process". */
+ return -1;
+ }
+
+ /* OK, now the task is to translate the incoming tid into
+ * a pid/tid pair.
+ */
+ real_tid = map_from_gdb_tid (gdb_tid);
+ real_pid = get_pid_for (real_tid);
+
+ /* Now check the result. "Real_pid" is NULL if our list
+ * didn't find it. We have some tricks we can play to fix
+ * this, however.
+ */
+ if (0 == real_pid)
+ {
+ ttstate_t thread_state;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("No saved pid for tid %d\n", gdb_tid);
+#endif
+
+ if (is_process_ttrace_request (request))
+ {
+
+ /* Ok, we couldn't get a tid. Try to translate to
+ * the equivalent process operation. We expect this
+ * NOT to happen, so this is a desparation-type
+ * move. It can happen if there is an internal
+ * error and so no "wait()" call is ever done.
+ */
+ new_request = make_process_version (request);
+ if (new_request == -1)
+ {
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("...and couldn't make process version of thread operation\n");
+#endif
+
+ /* Use hacky saved pid, which won't always be correct
+ * in the multi-process future. Use tid as thread,
+ * probably dooming this to failure. FIX!
+ */
+ if (! ptid_equal (saved_real_ptid, null_ptid))
+ {
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("...using saved pid %d\n",
+ PIDGET (saved_real_ptid));
+#endif
+
+ real_pid = PIDGET (saved_real_ptid);
+ real_tid = gdb_tid;
+ }
+
+ else
+ error ("Unable to perform thread operation");
+ }
+
+ else
+ {
+ /* Sucessfully translated this to a process request,
+ * which needs no thread value.
+ */
+ real_pid = gdb_tid;
+ real_tid = 0;
+ request = new_request;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ {
+ printf ("Translated thread request to process request\n");
+ if (ptid_equal (saved_real_ptid, null_ptid))
+ printf ("...but there's no saved pid\n");
+
+ else
+ {
+ if (gdb_tid != PIDGET (saved_real_ptid))
+ printf ("...but have the wrong pid (%d rather than %d)\n",
+ gdb_tid, PIDGET (saved_real_ptid));
+ }
+ }
+#endif
+ } /* Translated to a process request */
+ } /* Is a process request */
+
+ else
+ {
+ /* We have to have a thread. Ooops.
+ */
+ error ("Thread request with no threads (%s)",
+ get_printable_name_of_ttrace_request (request));
+ }
+ }
+
+ /* Ttrace doesn't like to see tid values on process requests,
+ * even if we have the right one.
+ */
+ if (is_process_ttrace_request (request))
+ {
+ real_tid = 0;
+ }
+
+#ifdef THREAD_DEBUG
+ if (is_interesting && 0 && debug_on)
+ {
+ printf (" now tid %d, pid %d\n", real_tid, real_pid);
+ printf (" request is %s\n", get_printable_name_of_ttrace_request (request));
+ }
+#endif
+
+ /* Finally, the (almost) real call.
+ */
+ tt_status = call_real_ttrace (request, real_pid, real_tid, addr, data, addr2);
+
+#ifdef THREAD_DEBUG
+ if (is_interesting && debug_on)
+ {
+ if (!TT_OK (tt_status, errno)
+ && !(tt_status == 0 & errno == 0))
+ printf (" got error (errno==%d, status==%d)\n", errno, tt_status);
+ }
+#endif
+
+ return tt_status;
+}
+
+
+/* Stop all the threads of a process.
+
+ * NOTE: use of TT_PROC_STOP can cause a thread with a real event
+ * to get a TTEVT_NONE event, discarding the old event. Be
+ * very careful, and only call TT_PROC_STOP when you mean it!
+ */
+static void
+stop_all_threads_of_process (pid_t real_pid)
+{
+ int ttw_status;
+
+ ttw_status = call_real_ttrace (TT_PROC_STOP,
+ (pid_t) real_pid,
+ (lwpid_t) TT_NIL,
+ (TTRACE_ARG_TYPE) TT_NIL,
+ (TTRACE_ARG_TYPE) TT_NIL,
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace stop of other threads");
+}
+
+
+/* Under some circumstances, it's unsafe to attempt to stop, or even
+ query the state of, a process' threads.
+
+ In ttrace-based HP-UX, an example is a vforking child process. The
+ vforking parent and child are somewhat fragile, w/r/t what we can do
+ what we can do to them with ttrace, until after the child exits or
+ execs, or until the parent's vfork event is delivered. Until that
+ time, we must not try to stop the process' threads, or inquire how
+ many there are, or even alter its data segments, or it typically dies
+ with a SIGILL. Sigh.
+
+ This function returns 1 if this stopped process, and the event that
+ we're told was responsible for its current stopped state, cannot safely
+ have its threads examined.
+ */
+#define CHILD_VFORKED(evt,pid) \
+ (((evt) == TTEVT_VFORK) && ((pid) != PIDGET (inferior_ptid)))
+#define CHILD_URPED(evt,pid) \
+ ((((evt) == TTEVT_EXEC) || ((evt) == TTEVT_EXIT)) && ((pid) != vforking_child_pid))
+#define PARENT_VFORKED(evt,pid) \
+ (((evt) == TTEVT_VFORK) && ((pid) == PIDGET (inferior_ptid)))
+
+static int
+can_touch_threads_of_process (int pid, ttevents_t stopping_event)
+{
+ if (CHILD_VFORKED (stopping_event, pid))
+ {
+ vforking_child_pid = pid;
+ vfork_in_flight = 1;
+ }
+
+ else if (vfork_in_flight &&
+ (PARENT_VFORKED (stopping_event, pid) ||
+ CHILD_URPED (stopping_event, pid)))
+ {
+ vfork_in_flight = 0;
+ vforking_child_pid = 0;
+ }
+
+ return !vfork_in_flight;
+}
+
+
+/* If we can find an as-yet-unhandled thread state of a
+ * stopped thread of this process return 1 and set "tsp".
+ * Return 0 if we can't.
+ *
+ * If this function is used when the threads of PIS haven't
+ * been stopped, undefined behaviour is guaranteed!
+ */
+static int
+select_stopped_thread_of_process (int pid, ttstate_t *tsp)
+{
+ lwpid_t candidate_tid, tid;
+ ttstate_t candidate_tstate, tstate;
+
+ /* If we're not allowed to touch the process now, then just
+ * return the current value of *TSP.
+ *
+ * This supports "vfork". It's ok, really, to double the
+ * current event (the child EXEC, we hope!).
+ */
+ if (!can_touch_threads_of_process (pid, tsp->tts_event))
+ return 1;
+
+ /* Decide which of (possibly more than one) events to
+ * return as the first one. We scan them all so that
+ * we always return the result of a fake-step first.
+ */
+ candidate_tid = 0;
+ for (tid = get_process_first_stopped_thread_id (pid, &tstate);
+ tid != 0;
+ tid = get_process_next_stopped_thread_id (pid, &tstate))
+ {
+ /* TTEVT_NONE events are uninteresting to our clients. They're
+ * an artifact of our "stop the world" model--the thread is
+ * stopped because we stopped it.
+ */
+ if (tstate.tts_event == TTEVT_NONE)
+ {
+ set_handled (pid, tstate.tts_lwpid);
+ }
+
+ /* Did we just single-step a single thread, without letting any
+ * of the others run? Is this an event for that thread?
+ *
+ * If so, we believe our client would prefer to see this event
+ * over any others. (Typically the client wants to just push
+ * one thread a little farther forward, and then go around
+ * checking for what all threads are doing.)
+ */
+ else if (doing_fake_step && (tstate.tts_lwpid == fake_step_tid))
+ {
+#ifdef WAIT_BUFFER_DEBUG
+ /* It's possible here to see either a SIGTRAP (due to
+ * successful completion of a step) or a SYSCALL_ENTRY
+ * (due to a step completion with active hardware
+ * watchpoints).
+ */
+ if (debug_on)
+ printf ("Ending fake step with tid %d, state %s\n",
+ tstate.tts_lwpid,
+ get_printable_name_of_ttrace_event (tstate.tts_event));
+#endif
+
+ /* Remember this one, and throw away any previous
+ * candidate.
+ */
+ candidate_tid = tstate.tts_lwpid;
+ candidate_tstate = tstate;
+ }
+
+#ifdef FORGET_DELETED_BPTS
+
+ /* We can't just do this, as if we do, and then wind
+ * up the loop with no unhandled events, we need to
+ * handle that case--the appropriate reaction is to
+ * just continue, but there's no easy way to do that.
+ *
+ * Better to put this in the ttrace_wait call--if, when
+ * we fake a wait, we update our events based on the
+ * breakpoint_here_pc call and find there are no more events,
+ * then we better continue and so on.
+ *
+ * Or we could put it in the next/continue fake.
+ * But it has to go in the buffering code, not in the
+ * real go/wait code.
+ */
+ else if ((TTEVT_SIGNAL == tstate.tts_event)
+ && (5 == tstate.tts_u.tts_signal.tts_signo)
+ && (0 != get_raw_pc (tstate.tts_lwpid))
+ && !breakpoint_here_p (get_raw_pc (tstate.tts_lwpid)))
+ {
+ /*
+ * If the user deleted a breakpoint while this
+ * breakpoint-hit event was buffered, we can forget
+ * it now.
+ */
+#ifdef WAIT_BUFFER_DEBUG
+ if (debug_on)
+ printf ("Forgetting deleted bp hit for thread %d\n",
+ tstate.tts_lwpid);
+#endif
+
+ set_handled (pid, tstate.tts_lwpid);
+ }
+#endif
+
+ /* Else, is this the first "unhandled" event? If so,
+ * we believe our client wants to see it (if we don't
+ * see a fake-step later on in the scan).
+ */
+ else if (!was_handled (tstate.tts_lwpid) && candidate_tid == 0)
+ {
+ candidate_tid = tstate.tts_lwpid;
+ candidate_tstate = tstate;
+ }
+
+ /* This is either an event that has already been "handled",
+ * and thus we believe is uninteresting to our client, or we
+ * already have a candidate event. Ignore it...
+ */
+ }
+
+ /* What do we report?
+ */
+ if (doing_fake_step)
+ {
+ if (candidate_tid == fake_step_tid)
+ {
+ /* Fake step.
+ */
+ tstate = candidate_tstate;
+ }
+ else
+ {
+ warning ("Internal error: fake-step failed to complete.");
+ return 0;
+ }
+ }
+ else if (candidate_tid != 0)
+ {
+ /* Found a candidate unhandled event.
+ */
+ tstate = candidate_tstate;
+ }
+ else if (tid != 0)
+ {
+ warning ("Internal error in call of ttrace_wait.");
+ return 0;
+ }
+ else
+ {
+ warning ("Internal error: no unhandled thread event to select");
+ return 0;
+ }
+
+ copy_ttstate_t (tsp, &tstate);
+ return 1;
+} /* End of select_stopped_thread_of_process */
+
+#ifdef PARANOIA
+/* Check our internal thread data against the real thing.
+ */
+static void
+check_thread_consistency (pid_t real_pid)
+{
+ int tid; /* really lwpid_t */
+ ttstate_t tstate;
+ thread_info *p;
+
+ /* Spin down the O/S list of threads, checking that they
+ * match what we've got.
+ */
+ for (tid = get_process_first_stopped_thread_id (real_pid, &tstate);
+ tid != 0;
+ tid = get_process_next_stopped_thread_id (real_pid, &tstate))
+ {
+
+ p = find_thread_info (tid);
+
+ if (NULL == p)
+ {
+ warning ("No internal thread data for thread %d.", tid);
+ continue;
+ }
+
+ if (!p->seen)
+ {
+ warning ("Inconsistent internal thread data for thread %d.", tid);
+ }
+
+ if (p->terminated)
+ {
+ warning ("Thread %d is not terminated, internal error.", tid);
+ continue;
+ }
+
+
+#define TT_COMPARE( fld ) \
+ tstate.fld != p->last_stop_state.fld
+
+ if (p->have_state)
+ {
+ if (TT_COMPARE (tts_pid)
+ || TT_COMPARE (tts_lwpid)
+ || TT_COMPARE (tts_user_tid)
+ || TT_COMPARE (tts_event)
+ || TT_COMPARE (tts_flags)
+ || TT_COMPARE (tts_scno)
+ || TT_COMPARE (tts_scnargs))
+ {
+ warning ("Internal thread data for thread %d is wrong.", tid);
+ continue;
+ }
+ }
+ }
+}
+#endif /* PARANOIA */
+
+
+/* This function wraps calls to "call_real_ttrace_wait" so
+ * that a actual wait is only done when all pending events
+ * have been reported.
+ *
+ * Note that typically it is called with a pid of "0", i.e.
+ * the "don't care" value.
+ *
+ * Return value is the status of the pseudo wait.
+ */
+static int
+call_ttrace_wait (int pid, ttwopt_t option, ttstate_t *tsp, size_t tsp_size)
+{
+ /* This holds the actual, for-real, true process ID.
+ */
+ static int real_pid;
+
+ /* As an argument to ttrace_wait, zero pid
+ * means "Any process", and zero tid means
+ * "Any thread of the specified process".
+ */
+ int wait_pid = 0;
+ lwpid_t wait_tid = 0;
+ lwpid_t real_tid;
+
+ int ttw_status = 0; /* To be returned */
+
+ thread_info *tinfo = NULL;
+
+ if (pid != 0)
+ {
+ /* Unexpected case.
+ */
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("TW: Pid to wait on is %d\n", pid);
+#endif
+
+ if (!any_thread_records ())
+ error ("No thread records for ttrace call w. specific pid");
+
+ /* OK, now the task is to translate the incoming tid into
+ * a pid/tid pair.
+ */
+ real_tid = map_from_gdb_tid (pid);
+ real_pid = get_pid_for (real_tid);
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("==TW: real pid %d, real tid %d\n", real_pid, real_tid);
+#endif
+ }
+
+
+ /* Sanity checks and set-up.
+ * Process State
+ *
+ * Stopped Running Fake-step (v)Fork
+ * \________________________________________
+ * |
+ * No buffered events | error wait wait wait
+ * |
+ * Buffered events | debuffer error wait debuffer (?)
+ *
+ */
+ if (more_events_left == 0)
+ {
+
+ if (process_state == RUNNING)
+ {
+ /* OK--normal call of ttrace_wait with no buffered events.
+ */
+ ;
+ }
+ else if (process_state == FAKE_STEPPING)
+ {
+ /* Ok--call of ttrace_wait to support
+ * fake stepping with no buffered events.
+ *
+ * But we better be fake-stepping!
+ */
+ if (!doing_fake_step)
+ {
+ warning ("Inconsistent thread state.");
+ }
+ }
+ else if ((process_state == FORKING)
+ || (process_state == VFORKING))
+ {
+ /* Ok--there are two processes, so waiting
+ * for the second while the first is stopped
+ * is ok. Handled bits stay as they were.
+ */
+ ;
+ }
+ else if (process_state == STOPPED)
+ {
+ warning ("Process not running at wait call.");
+ }
+ else
+ /* No known state.
+ */
+ warning ("Inconsistent process state.");
+ }
+
+ else
+ {
+ /* More events left
+ */
+ if (process_state == STOPPED)
+ {
+ /* OK--buffered events being unbuffered.
+ */
+ ;
+ }
+ else if (process_state == RUNNING)
+ {
+ /* An error--shouldn't have buffered events
+ * when running.
+ */
+ warning ("Trying to continue with buffered events:");
+ }
+ else if (process_state == FAKE_STEPPING)
+ {
+ /*
+ * Better be fake-stepping!
+ */
+ if (!doing_fake_step)
+ {
+ warning ("Losing buffered thread events!\n");
+ }
+ }
+ else if ((process_state == FORKING)
+ || (process_state == VFORKING))
+ {
+ /* Ok--there are two processes, so waiting
+ * for the second while the first is stopped
+ * is ok. Handled bits stay as they were.
+ */
+ ;
+ }
+ else
+ warning ("Process in unknown state with buffered events.");
+ }
+
+ /* Sometimes we have to wait for a particular thread
+ * (if we're stepping over a bpt). In that case, we
+ * _know_ it's going to complete the single-step we
+ * asked for (because we're only doing the step under
+ * certain very well-understood circumstances), so it
+ * can't block.
+ */
+ if (doing_fake_step)
+ {
+ wait_tid = fake_step_tid;
+ wait_pid = get_pid_for (fake_step_tid);
+
+#ifdef WAIT_BUFFER_DEBUG
+ if (debug_on)
+ printf ("Doing a wait after a fake-step for %d, pid %d\n",
+ wait_tid, wait_pid);
+#endif
+ }
+
+ if (more_events_left == 0 /* No buffered events, need real ones. */
+ || process_state != STOPPED)
+ {
+ /* If there are no buffered events, and so we need
+ * real ones, or if we are FORKING, VFORKING,
+ * FAKE_STEPPING or RUNNING, and thus have to do
+ * a real wait, then do a real wait.
+ */
+
+#ifdef WAIT_BUFFER_DEBUG
+ /* Normal case... */
+ if (debug_on)
+ printf ("TW: do it for real; pid %d, tid %d\n", wait_pid, wait_tid);
+#endif
+
+ /* The actual wait call.
+ */
+ ttw_status = call_real_ttrace_wait (wait_pid, wait_tid, option, tsp, tsp_size);
+
+ /* Note that the routines we'll call will be using "call_real_ttrace",
+ * not "call_ttrace", and thus need the real pid rather than the pseudo-tid
+ * the rest of the world uses (which is actually the tid).
+ */
+ real_pid = tsp->tts_pid;
+
+ /* For most events: Stop the world!
+
+ * It's sometimes not safe to stop all threads of a process.
+ * Sometimes it's not even safe to ask for the thread state
+ * of a process!
+ */
+ if (can_touch_threads_of_process (real_pid, tsp->tts_event))
+ {
+ /* If we're really only stepping a single thread, then don't
+ * try to stop all the others -- we only do this single-stepping
+ * business when all others were already stopped...and the stop
+ * would mess up other threads' events.
+ *
+ * Similiarly, if there are other threads with events,
+ * don't do the stop.
+ */
+ if (!doing_fake_step)
+ {
+ if (more_events_left > 0)
+ warning ("Internal error in stopping process");
+
+ stop_all_threads_of_process (real_pid);
+
+ /* At this point, we could scan and update_thread_list(),
+ * and only use the local list for the rest of the
+ * module! We'd get rid of the scans in the various
+ * continue routines (adding one in attach). It'd
+ * be great--UPGRADE ME!
+ */
+ }
+ }
+
+#ifdef PARANOIA
+ else if (debug_on)
+ {
+ if (more_events_left > 0)
+ printf ("== Can't stop process; more events!\n");
+ else
+ printf ("== Can't stop process!\n");
+ }
+#endif
+
+ process_state = STOPPED;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if (debug_on)
+ printf ("Process set to STOPPED\n");
+#endif
+ }
+
+ else
+ {
+ /* Fake a call to ttrace_wait. The process must be
+ * STOPPED, as we aren't going to do any wait.
+ */
+#ifdef WAIT_BUFFER_DEBUG
+ if (debug_on)
+ printf ("TW: fake it\n");
+#endif
+
+ if (process_state != STOPPED)
+ {
+ warning ("Process not stopped at wait call, in state '%s'.\n",
+ get_printable_name_of_process_state (process_state));
+ }
+
+ if (doing_fake_step)
+ error ("Internal error in stepping over breakpoint");
+
+ ttw_status = 0; /* Faking it is always successful! */
+ } /* End of fake or not? if */
+
+ /* Pick an event to pass to our caller. Be paranoid.
+ */
+ if (!select_stopped_thread_of_process (real_pid, tsp))
+ warning ("Can't find event, using previous event.");
+
+ else if (tsp->tts_event == TTEVT_NONE)
+ warning ("Internal error: no thread has a real event.");
+
+ else if (doing_fake_step)
+ {
+ if (fake_step_tid != tsp->tts_lwpid)
+ warning ("Internal error in stepping over breakpoint.");
+
+ /* This wait clears the (current) fake-step if there was one.
+ */
+ doing_fake_step = 0;
+ fake_step_tid = 0;
+ }
+
+ /* We now have a correct tsp and ttw_status for the thread
+ * which we want to report. So it's "handled"! This call
+ * will add it to our list if it's not there already.
+ */
+ set_handled (real_pid, tsp->tts_lwpid);
+
+ /* Save a copy of the ttrace state of this thread, in our local
+ thread descriptor.
+
+ This caches the state. The implementation of queries like
+ target_has_execd can then use this cached state, rather than
+ be forced to make an explicit ttrace call to get it.
+
+ (Guard against the condition that this is the first time we've
+ waited on, i.e., seen this thread, and so haven't yet entered
+ it into our list of threads.)
+ */
+ tinfo = find_thread_info (tsp->tts_lwpid);
+ if (tinfo != NULL)
+ {
+ copy_ttstate_t (&tinfo->last_stop_state, tsp);
+ tinfo->have_state = 1;
+ }
+
+ return ttw_status;
+} /* call_ttrace_wait */
+
+#if defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL)
+int
+child_reported_exec_events_per_exec_call (void)
+{
+ return 1; /* ttrace reports the event once per call. */
+}
+#endif
+
+
+
+/* Our implementation of hardware watchpoints involves making memory
+ pages write-protected. We must remember a page's original permissions,
+ and we must also know when it is appropriate to restore a page's
+ permissions to its original state.
+
+ We use a "dictionary" of hardware-watched pages to do this. Each
+ hardware-watched page is recorded in the dictionary. Each page's
+ dictionary entry contains the original permissions and a reference
+ count. Pages are hashed into the dictionary by their start address.
+
+ When hardware watchpoint is set on page X for the first time, page X
+ is added to the dictionary with a reference count of 1. If other
+ hardware watchpoints are subsequently set on page X, its reference
+ count is incremented. When hardware watchpoints are removed from
+ page X, its reference count is decremented. If a page's reference
+ count drops to 0, it's permissions are restored and the page's entry
+ is thrown out of the dictionary.
+ */
+typedef struct memory_page
+{
+ CORE_ADDR page_start;
+ int reference_count;
+ int original_permissions;
+ struct memory_page *next;
+ struct memory_page *previous;
+}
+memory_page_t;
+
+#define MEMORY_PAGE_DICTIONARY_BUCKET_COUNT 128
+
+static struct
+ {
+ LONGEST page_count;
+ int page_size;
+ int page_protections_allowed;
+ /* These are just the heads of chains of actual page descriptors. */
+ memory_page_t buckets[MEMORY_PAGE_DICTIONARY_BUCKET_COUNT];
+ }
+memory_page_dictionary;
+
+
+static void
+require_memory_page_dictionary (void)
+{
+ int i;
+
+ /* Is the memory page dictionary ready for use? If so, we're done. */
+ if (memory_page_dictionary.page_count >= (LONGEST) 0)
+ return;
+
+ /* Else, initialize it. */
+ memory_page_dictionary.page_count = (LONGEST) 0;
+
+ for (i = 0; i < MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; i++)
+ {
+ memory_page_dictionary.buckets[i].page_start = (CORE_ADDR) 0;
+ memory_page_dictionary.buckets[i].reference_count = 0;
+ memory_page_dictionary.buckets[i].next = NULL;
+ memory_page_dictionary.buckets[i].previous = NULL;
+ }
+}
+
+
+static void
+retire_memory_page_dictionary (void)
+{
+ memory_page_dictionary.page_count = (LONGEST) - 1;
+}
+
+
+/* Write-protect the memory page that starts at this address.
+
+ Returns the original permissions of the page.
+ */
+static int
+write_protect_page (int pid, CORE_ADDR page_start)
+{
+ int tt_status;
+ int original_permissions;
+ int new_permissions;
+
+ tt_status = call_ttrace (TT_PROC_GET_MPROTECT,
+ pid,
+ (TTRACE_ARG_TYPE) page_start,
+ TT_NIL,
+ (TTRACE_ARG_TYPE) & original_permissions);
+ if (errno || (tt_status < 0))
+ {
+ return 0; /* What else can we do? */
+ }
+
+ /* We'll also write-protect the page now, if that's allowed. */
+ if (memory_page_dictionary.page_protections_allowed)
+ {
+ new_permissions = original_permissions & ~PROT_WRITE;
+ tt_status = call_ttrace (TT_PROC_SET_MPROTECT,
+ pid,
+ (TTRACE_ARG_TYPE) page_start,
+ (TTRACE_ARG_TYPE) memory_page_dictionary.page_size,
+ (TTRACE_ARG_TYPE) new_permissions);
+ if (errno || (tt_status < 0))
+ {
+ return 0; /* What else can we do? */
+ }
+ }
+
+ return original_permissions;
+}
+
+
+/* Unwrite-protect the memory page that starts at this address, restoring
+ (what we must assume are) its original permissions.
+ */
+static void
+unwrite_protect_page (int pid, CORE_ADDR page_start, int original_permissions)
+{
+ int tt_status;
+
+ tt_status = call_ttrace (TT_PROC_SET_MPROTECT,
+ pid,
+ (TTRACE_ARG_TYPE) page_start,
+ (TTRACE_ARG_TYPE) memory_page_dictionary.page_size,
+ (TTRACE_ARG_TYPE) original_permissions);
+ if (errno || (tt_status < 0))
+ {
+ return; /* What else can we do? */
+ }
+}
+
+
+/* Memory page-protections are used to implement "hardware" watchpoints
+ on HP-UX.
+
+ For every memory page that is currently being watched (i.e., that
+ presently should be write-protected), write-protect it.
+ */
+void
+hppa_enable_page_protection_events (int pid)
+{
+ int bucket;
+
+ memory_page_dictionary.page_protections_allowed = 1;
+
+ for (bucket = 0; bucket < MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; bucket++)
+ {
+ memory_page_t *page;
+
+ page = memory_page_dictionary.buckets[bucket].next;
+ while (page != NULL)
+ {
+ page->original_permissions = write_protect_page (pid, page->page_start);
+ page = page->next;
+ }
+ }
+}
+
+
+/* Memory page-protections are used to implement "hardware" watchpoints
+ on HP-UX.
+
+ For every memory page that is currently being watched (i.e., that
+ presently is or should be write-protected), un-write-protect it.
+ */
+void
+hppa_disable_page_protection_events (int pid)
+{
+ int bucket;
+
+ for (bucket = 0; bucket < MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; bucket++)
+ {
+ memory_page_t *page;
+
+ page = memory_page_dictionary.buckets[bucket].next;
+ while (page != NULL)
+ {
+ unwrite_protect_page (pid, page->page_start, page->original_permissions);
+ page = page->next;
+ }
+ }
+
+ memory_page_dictionary.page_protections_allowed = 0;
+}
+
+/* Count the number of outstanding events. At this
+ * point, we have selected one thread and its event
+ * as the one to be "reported" upwards to core gdb.
+ * That thread is already marked as "handled".
+ *
+ * Note: we could just scan our own thread list. FIXME!
+ */
+static int
+count_unhandled_events (int real_pid, lwpid_t real_tid)
+{
+ ttstate_t tstate;
+ lwpid_t ttid;
+ int events_left;
+
+ /* Ok, find out how many threads have real events to report.
+ */
+ events_left = 0;
+ ttid = get_process_first_stopped_thread_id (real_pid, &tstate);
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ {
+ if (ttid == 0)
+ printf ("Process %d has no threads\n", real_pid);
+ else
+ printf ("Process %d has these threads:\n", real_pid);
+ }
+#endif
+
+ while (ttid > 0)
+ {
+ if (tstate.tts_event != TTEVT_NONE
+ && !was_handled (ttid))
+ {
+ /* TTEVT_NONE implies we just stopped it ourselves
+ * because we're the stop-the-world guys, so it's
+ * not an event from our point of view.
+ *
+ * If "was_handled" is true, this is an event we
+ * already handled, so don't count it.
+ *
+ * Note that we don't count the thread with the
+ * currently-reported event, as it's already marked
+ * as handled.
+ */
+ events_left++;
+ }
+
+#if defined( THREAD_DEBUG ) || defined( WAIT_BUFFER_DEBUG )
+ if (debug_on)
+ {
+ if (ttid == real_tid)
+ printf ("*"); /* Thread we're reporting */
+ else
+ printf (" ");
+
+ if (tstate.tts_event != TTEVT_NONE)
+ printf ("+"); /* Thread with a real event */
+ else
+ printf (" ");
+
+ if (was_handled (ttid))
+ printf ("h"); /* Thread has been handled */
+ else
+ printf (" ");
+
+ printf (" %d, with event %s", ttid,
+ get_printable_name_of_ttrace_event (tstate.tts_event));
+
+ if (tstate.tts_event == TTEVT_SIGNAL
+ && 5 == tstate.tts_u.tts_signal.tts_signo)
+ {
+ CORE_ADDR pc_val;
+
+ pc_val = get_raw_pc (ttid);
+
+ if (pc_val > 0)
+ printf (" breakpoint at 0x%x\n", pc_val);
+ else
+ printf (" bpt, can't fetch pc.\n");
+ }
+ else
+ printf ("\n");
+ }
+#endif
+
+ ttid = get_process_next_stopped_thread_id (real_pid, &tstate);
+ }
+
+#if defined( THREAD_DEBUG ) || defined( WAIT_BUFFER_DEBUG )
+ if (debug_on)
+ if (events_left > 0)
+ printf ("There are thus %d pending events\n", events_left);
+#endif
+
+ return events_left;
+}
+
+/* This function is provided as a sop to clients that are calling
+ * ptrace_wait to wait for a process to stop. (see the
+ * implementation of child_wait.) Return value is the pid for
+ * the event that ended the wait.
+ *
+ * Note: used by core gdb and so uses the pseudo-pid (really tid).
+ */
+int
+ptrace_wait (ptid_t ptid, int *status)
+{
+ ttstate_t tsp;
+ int ttwait_return;
+ int real_pid;
+ ttstate_t state;
+ lwpid_t real_tid;
+ int return_pid;
+
+ /* The ptrace implementation of this also ignores pid.
+ */
+ *status = 0;
+
+ ttwait_return = call_ttrace_wait (0, TTRACE_WAITOK, &tsp, sizeof (tsp));
+ if (ttwait_return < 0)
+ {
+ /* ??rehrauer: It appears that if our inferior exits and we
+ haven't asked for exit events, that we're not getting any
+ indication save a negative return from ttrace_wait and an
+ errno set to ESRCH?
+ */
+ if (errno == ESRCH)
+ {
+ *status = 0; /* WIFEXITED */
+ return PIDGET (inferior_ptid);
+ }
+
+ warning ("Call of ttrace_wait returned with errno %d.",
+ errno);
+ *status = ttwait_return;
+ return PIDGET (inferior_ptid);
+ }
+
+ real_pid = tsp.tts_pid;
+ real_tid = tsp.tts_lwpid;
+
+ /* One complication is that the "tts_event" structure has
+ * a set of flags, and more than one can be set. So we
+ * either have to force an order (as we do here), or handle
+ * more than one flag at a time.
+ */
+ if (tsp.tts_event & TTEVT_LWP_CREATE)
+ {
+
+ /* Unlike what you might expect, this event is reported in
+ * the _creating_ thread, and the _created_ thread (whose tid
+ * we have) is still running. So we have to stop it. This
+ * has already been done in "call_ttrace_wait", but should we
+ * ever abandon the "stop-the-world" model, here's the command
+ * to use:
+ *
+ * call_ttrace( TT_LWP_STOP, real_tid, TT_NIL, TT_NIL, TT_NIL );
+ *
+ * Note that this would depend on being called _after_ "add_tthread"
+ * below for the tid-to-pid translation to be done in "call_ttrace".
+ */
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("New thread: pid %d, tid %d, creator tid %d\n",
+ real_pid, tsp.tts_u.tts_thread.tts_target_lwpid,
+ real_tid);
+#endif
+
+ /* Now we have to return the tid of the created thread, not
+ * the creating thread, or "wait_for_inferior" won't know we
+ * have a new "process" (thread). Plus we should record it
+ * right, too.
+ */
+ real_tid = tsp.tts_u.tts_thread.tts_target_lwpid;
+
+ add_tthread (real_pid, real_tid);
+ }
+
+ else if ((tsp.tts_event & TTEVT_LWP_TERMINATE)
+ || (tsp.tts_event & TTEVT_LWP_EXIT))
+ {
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Thread dies: %d\n", real_tid);
+#endif
+
+ del_tthread (real_tid);
+ }
+
+ else if (tsp.tts_event & TTEVT_EXEC)
+ {
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Pid %d has zero'th thread %d; inferior pid is %d\n",
+ real_pid, real_tid, PIDGET (inferior_ptid));
+#endif
+
+ add_tthread (real_pid, real_tid);
+ }
+
+#ifdef THREAD_DEBUG
+ else if (debug_on)
+ {
+ printf ("Process-level event %s, using tid %d\n",
+ get_printable_name_of_ttrace_event (tsp.tts_event),
+ real_tid);
+
+ /* OK to do this, as "add_tthread" won't add
+ * duplicate entries. Also OK not to do it,
+ * as this event isn't one which can change the
+ * thread state.
+ */
+ add_tthread (real_pid, real_tid);
+ }
+#endif
+
+
+ /* How many events are left to report later?
+ * In a non-stop-the-world model, this isn't needed.
+ *
+ * Note that it's not always safe to query the thread state of a process,
+ * which is what count_unhandled_events does. (If unsafe, we're left with
+ * no other resort than to assume that no more events remain...)
+ */
+ if (can_touch_threads_of_process (real_pid, tsp.tts_event))
+ more_events_left = count_unhandled_events (real_pid, real_tid);
+
+ else
+ {
+ if (more_events_left > 0)
+ warning ("Vfork or fork causing loss of %d buffered events.",
+ more_events_left);
+
+ more_events_left = 0;
+ }
+
+ /* Attempt to translate the ttrace_wait-returned status into the
+ ptrace equivalent.
+
+ ??rehrauer: This is somewhat fragile. We really ought to rewrite
+ clients that expect to pick apart a ptrace wait status, to use
+ something a little more abstract.
+ */
+ if ((tsp.tts_event & TTEVT_EXEC)
+ || (tsp.tts_event & TTEVT_FORK)
+ || (tsp.tts_event & TTEVT_VFORK))
+ {
+ /* Forks come in pairs (parent and child), so core gdb
+ * will do two waits. Be ready to notice this.
+ */
+ if (tsp.tts_event & TTEVT_FORK)
+ {
+ process_state = FORKING;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if (debug_on)
+ printf ("Process set to FORKING\n");
+#endif
+ }
+ else if (tsp.tts_event & TTEVT_VFORK)
+ {
+ process_state = VFORKING;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if (debug_on)
+ printf ("Process set to VFORKING\n");
+#endif
+ }
+
+ /* Make an exec or fork look like a breakpoint. Definitely a hack,
+ but I don't think non HP-UX-specific clients really carefully
+ inspect the first events they get after inferior startup, so
+ it probably almost doesn't matter what we claim this is.
+ */
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("..a process 'event'\n");
+#endif
+
+ /* Also make fork and exec events look like bpts, so they can be caught.
+ */
+ *status = 0177 | (_SIGTRAP << 8);
+ }
+
+ /* Special-cases: We ask for syscall entry and exit events to implement
+ "fast" (aka "hardware") watchpoints.
+
+ When we get a syscall entry, we want to disable page-protections,
+ and resume the inferior; this isn't an event we wish for
+ wait_for_inferior to see. Note that we must resume ONLY the
+ thread that reported the syscall entry; we don't want to allow
+ other threads to run with the page protections off, as they might
+ then be able to write to watch memory without it being caught.
+
+ When we get a syscall exit, we want to reenable page-protections,
+ but we don't want to resume the inferior; this is an event we wish
+ wait_for_inferior to see. Make it look like the signal we normally
+ get for a single-step completion. This should cause wait_for_inferior
+ to evaluate whether any watchpoint triggered.
+
+ Or rather, that's what we'd LIKE to do for syscall exit; we can't,
+ due to some HP-UX "features". Some syscalls have problems with
+ write-protections on some pages, and some syscalls seem to have
+ pending writes to those pages at the time we're getting the return
+ event. So, we'll single-step the inferior to get out of the syscall,
+ and then reenable protections.
+
+ Note that we're intentionally allowing the syscall exit case to
+ fall through into the succeeding cases, as sometimes we single-
+ step out of one syscall only to immediately enter another...
+ */
+ else if ((tsp.tts_event & TTEVT_SYSCALL_ENTRY)
+ || (tsp.tts_event & TTEVT_SYSCALL_RETURN))
+ {
+ /* Make a syscall event look like a breakpoint. Same comments
+ as for exec & fork events.
+ */
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("..a syscall 'event'\n");
+#endif
+
+ /* Also make syscall events look like bpts, so they can be caught.
+ */
+ *status = 0177 | (_SIGTRAP << 8);
+ }
+
+ else if ((tsp.tts_event & TTEVT_LWP_CREATE)
+ || (tsp.tts_event & TTEVT_LWP_TERMINATE)
+ || (tsp.tts_event & TTEVT_LWP_EXIT))
+ {
+ /* Make a thread event look like a breakpoint. Same comments
+ * as for exec & fork events.
+ */
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("..a thread 'event'\n");
+#endif
+
+ /* Also make thread events look like bpts, so they can be caught.
+ */
+ *status = 0177 | (_SIGTRAP << 8);
+ }
+
+ else if ((tsp.tts_event & TTEVT_EXIT))
+ { /* WIFEXITED */
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("..an exit\n");
+#endif
+
+ /* Prevent rest of gdb from thinking this is
+ * a new thread if for some reason it's never
+ * seen the main thread before.
+ */
+ inferior_ptid = pid_to_ptid (map_to_gdb_tid (real_tid)); /* HACK, FIX */
+
+ *status = 0 | (tsp.tts_u.tts_exit.tts_exitcode);
+ }
+
+ else if (tsp.tts_event & TTEVT_SIGNAL)
+ { /* WIFSTOPPED */
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("..a signal, %d\n", tsp.tts_u.tts_signal.tts_signo);
+#endif
+
+ *status = 0177 | (tsp.tts_u.tts_signal.tts_signo << 8);
+ }
+
+ else
+ { /* !WIFSTOPPED */
+
+ /* This means the process or thread terminated. But we should've
+ caught an explicit exit/termination above. So warn (this is
+ really an internal error) and claim the process or thread
+ terminated with a SIGTRAP.
+ */
+
+ warning ("process_wait: unknown process state");
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Process-level event %s, using tid %d\n",
+ get_printable_name_of_ttrace_event (tsp.tts_event),
+ real_tid);
+#endif
+
+ *status = _SIGTRAP;
+ }
+
+ target_post_wait (pid_to_ptid (tsp.tts_pid), *status);
+
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Done waiting, pid is %d, tid %d\n", real_pid, real_tid);
+#endif
+
+ /* All code external to this module uses the tid, but calls
+ * it "pid". There's some tweaking so that the outside sees
+ * the first thread as having the same number as the starting
+ * pid.
+ */
+ return_pid = map_to_gdb_tid (real_tid);
+
+ /* Remember this for later use in "hppa_prepare_to_proceed".
+ */
+ old_gdb_pid = PIDGET (inferior_ptid);
+ reported_pid = return_pid;
+ reported_bpt = ((tsp.tts_event & TTEVT_SIGNAL) && (5 == tsp.tts_u.tts_signal.tts_signo));
+
+ if (real_tid == 0 || return_pid == 0)
+ {
+ warning ("Internal error: process-wait failed.");
+ }
+
+ return return_pid;
+}
+
+
+/* This function causes the caller's process to be traced by its
+ parent. This is intended to be called after GDB forks itself,
+ and before the child execs the target. Despite the name, it
+ is called by the child.
+
+ Note that HP-UX ttrace is rather funky in how this is done.
+ If the parent wants to get the initial exec event of a child,
+ it must set the ttrace event mask of the child to include execs.
+ (The child cannot do this itself.) This must be done after the
+ child is forked, but before it execs.
+
+ To coordinate the parent and child, we implement a semaphore using
+ pipes. After SETTRC'ing itself, the child tells the parent that
+ it is now traceable by the parent, and waits for the parent's
+ acknowledgement. The parent can then set the child's event mask,
+ and notify the child that it can now exec.
+
+ (The acknowledgement by parent happens as a result of a call to
+ child_acknowledge_created_inferior.)
+ */
+int
+parent_attach_all (void)
+{
+ int tt_status;
+
+ /* We need a memory home for a constant, to pass it to ttrace.
+ The value of the constant is arbitrary, so long as both
+ parent and child use the same value. Might as well use the
+ "magic" constant provided by ttrace...
+ */
+ uint64_t tc_magic_child = TT_VERSION;
+ uint64_t tc_magic_parent = 0;
+
+ tt_status = call_real_ttrace (
+ TT_PROC_SETTRC,
+ (int) TT_NIL,
+ (lwpid_t) TT_NIL,
+ TT_NIL,
+ (TTRACE_ARG_TYPE) TT_VERSION,
+ TT_NIL);
+
+ if (tt_status < 0)
+ return tt_status;
+
+ /* Notify the parent that we're potentially ready to exec(). */
+ write (startup_semaphore.child_channel[SEM_TALK],
+ &tc_magic_child,
+ sizeof (tc_magic_child));
+
+ /* Wait for acknowledgement from the parent. */
+ read (startup_semaphore.parent_channel[SEM_LISTEN],
+ &tc_magic_parent,
+ sizeof (tc_magic_parent));
+
+ if (tc_magic_child != tc_magic_parent)
+ warning ("mismatched semaphore magic");
+
+ /* Discard our copy of the semaphore. */
+ (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
+ (void) close (startup_semaphore.parent_channel[SEM_TALK]);
+ (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
+ (void) close (startup_semaphore.child_channel[SEM_TALK]);
+
+ return tt_status;
+}
+
+/* Despite being file-local, this routine is dealing with
+ * actual process IDs, not thread ids. That's because it's
+ * called before the first "wait" call, and there's no map
+ * yet from tids to pids.
+ *
+ * When it is called, a forked child is running, but waiting on
+ * the semaphore. If you stop the child and re-start it,
+ * things get confused, so don't do that! An attached child is
+ * stopped.
+ *
+ * Since this is called after either attach or run, we
+ * have to be the common part of both.
+ */
+static void
+require_notification_of_events (int real_pid)
+{
+ int tt_status;
+ ttevent_t notifiable_events;
+
+ lwpid_t tid;
+ ttstate_t thread_state;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Require notif, pid is %d\n", real_pid);
+#endif
+
+ /* Temporary HACK: tell inftarg.c/child_wait to not
+ * loop until pids are the same.
+ */
+ not_same_real_pid = 0;
+
+ sigemptyset (&notifiable_events.tte_signals);
+ notifiable_events.tte_opts = TTEO_NONE;
+
+ /* This ensures that forked children inherit their parent's
+ * event mask, which we're setting here.
+ *
+ * NOTE: if you debug gdb with itself, then the ultimate
+ * debuggee gets flags set by the outermost gdb, as
+ * a child of a child will still inherit.
+ */
+ notifiable_events.tte_opts |= TTEO_PROC_INHERIT;
+
+ notifiable_events.tte_events = TTEVT_DEFAULT;
+ notifiable_events.tte_events |= TTEVT_SIGNAL;
+ notifiable_events.tte_events |= TTEVT_EXEC;
+ notifiable_events.tte_events |= TTEVT_EXIT;
+ notifiable_events.tte_events |= TTEVT_FORK;
+ notifiable_events.tte_events |= TTEVT_VFORK;
+ notifiable_events.tte_events |= TTEVT_LWP_CREATE;
+ notifiable_events.tte_events |= TTEVT_LWP_EXIT;
+ notifiable_events.tte_events |= TTEVT_LWP_TERMINATE;
+
+ tt_status = call_real_ttrace (
+ TT_PROC_SET_EVENT_MASK,
+ real_pid,
+ (lwpid_t) TT_NIL,
+ (TTRACE_ARG_TYPE) & notifiable_events,
+ (TTRACE_ARG_TYPE) sizeof (notifiable_events),
+ TT_NIL);
+}
+
+static void
+require_notification_of_exec_events (int real_pid)
+{
+ int tt_status;
+ ttevent_t notifiable_events;
+
+ lwpid_t tid;
+ ttstate_t thread_state;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Require notif, pid is %d\n", real_pid);
+#endif
+
+ /* Temporary HACK: tell inftarg.c/child_wait to not
+ * loop until pids are the same.
+ */
+ not_same_real_pid = 0;
+
+ sigemptyset (&notifiable_events.tte_signals);
+ notifiable_events.tte_opts = TTEO_NOSTRCCHLD;
+
+ /* This ensures that forked children don't inherit their parent's
+ * event mask, which we're setting here.
+ */
+ notifiable_events.tte_opts &= ~TTEO_PROC_INHERIT;
+
+ notifiable_events.tte_events = TTEVT_DEFAULT;
+ notifiable_events.tte_events |= TTEVT_EXEC;
+ notifiable_events.tte_events |= TTEVT_EXIT;
+
+ tt_status = call_real_ttrace (
+ TT_PROC_SET_EVENT_MASK,
+ real_pid,
+ (lwpid_t) TT_NIL,
+ (TTRACE_ARG_TYPE) & notifiable_events,
+ (TTRACE_ARG_TYPE) sizeof (notifiable_events),
+ TT_NIL);
+}
+
+
+/* This function is called by the parent process, with pid being the
+ * ID of the child process, after the debugger has forked.
+ */
+void
+child_acknowledge_created_inferior (int pid)
+{
+ /* We need a memory home for a constant, to pass it to ttrace.
+ The value of the constant is arbitrary, so long as both
+ parent and child use the same value. Might as well use the
+ "magic" constant provided by ttrace...
+ */
+ uint64_t tc_magic_parent = TT_VERSION;
+ uint64_t tc_magic_child = 0;
+
+ /* Wait for the child to tell us that it has forked. */
+ read (startup_semaphore.child_channel[SEM_LISTEN],
+ &tc_magic_child,
+ sizeof (tc_magic_child));
+
+ /* Clear thread info now. We'd like to do this in
+ * "require...", but that messes up attach.
+ */
+ clear_thread_info ();
+
+ /* Tell the "rest of gdb" that the initial thread exists.
+ * This isn't really a hack. Other thread-based versions
+ * of gdb (e.g. gnu-nat.c) seem to do the same thing.
+ *
+ * Q: Why don't we also add this thread to the local
+ * list via "add_tthread"?
+ *
+ * A: Because we don't know the tid, and can't stop the
+ * the process safely to ask what it is. Anyway, we'll
+ * add it when it gets the EXEC event.
+ */
+ add_thread (pid_to_ptid (pid)); /* in thread.c */
+
+ /* We can now set the child's ttrace event mask.
+ */
+ require_notification_of_exec_events (pid);
+
+ /* Tell ourselves that the process is running.
+ */
+ process_state = RUNNING;
+
+ /* Notify the child that it can exec. */
+ write (startup_semaphore.parent_channel[SEM_TALK],
+ &tc_magic_parent,
+ sizeof (tc_magic_parent));
+
+ /* Discard our copy of the semaphore. */
+ (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
+ (void) close (startup_semaphore.parent_channel[SEM_TALK]);
+ (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
+ (void) close (startup_semaphore.child_channel[SEM_TALK]);
+}
+
+
+/*
+ * arrange for notification of all events by
+ * calling require_notification_of_events.
+ */
+void
+child_post_startup_inferior (ptid_t ptid)
+{
+ require_notification_of_events (PIDGET (ptid));
+}
+
+/* From here on, we should expect tids rather than pids.
+ */
+static void
+hppa_enable_catch_fork (int tid)
+{
+ int tt_status;
+ ttevent_t ttrace_events;
+
+ /* Get the set of events that are currently enabled.
+ */
+ tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) & ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+
+ /* Add forks to that set. */
+ ttrace_events.tte_events |= TTEVT_FORK;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("enable fork, tid is %d\n", tid);
+#endif
+
+ tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) & ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+}
+
+
+static void
+hppa_disable_catch_fork (int tid)
+{
+ int tt_status;
+ ttevent_t ttrace_events;
+
+ /* Get the set of events that are currently enabled.
+ */
+ tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) & ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+
+ /* Remove forks from that set. */
+ ttrace_events.tte_events &= ~TTEVT_FORK;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("disable fork, tid is %d\n", tid);
+#endif
+
+ tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) & ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+}
+
+
+#if defined(CHILD_INSERT_FORK_CATCHPOINT)
+int
+child_insert_fork_catchpoint (int tid)
+{
+ /* Enable reporting of fork events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them.
+ */
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_REMOVE_FORK_CATCHPOINT)
+int
+child_remove_fork_catchpoint (int tid)
+{
+ /* Disable reporting of fork events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them.
+ */
+ return 0;
+}
+#endif
+
+
+static void
+hppa_enable_catch_vfork (int tid)
+{
+ int tt_status;
+ ttevent_t ttrace_events;
+
+ /* Get the set of events that are currently enabled.
+ */
+ tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) & ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+
+ /* Add vforks to that set. */
+ ttrace_events.tte_events |= TTEVT_VFORK;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("enable vfork, tid is %d\n", tid);
+#endif
+
+ tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) & ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+}
+
+
+static void
+hppa_disable_catch_vfork (int tid)
+{
+ int tt_status;
+ ttevent_t ttrace_events;
+
+ /* Get the set of events that are currently enabled. */
+ tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) & ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+
+ /* Remove vforks from that set. */
+ ttrace_events.tte_events &= ~TTEVT_VFORK;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("disable vfork, tid is %d\n", tid);
+#endif
+ tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
+ tid,
+ (TTRACE_ARG_TYPE) & ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+}
+
+
+#if defined(CHILD_INSERT_VFORK_CATCHPOINT)
+int
+child_insert_vfork_catchpoint (int tid)
+{
+ /* Enable reporting of vfork events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them.
+ */
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_REMOVE_VFORK_CATCHPOINT)
+int
+child_remove_vfork_catchpoint (int tid)
+{
+ /* Disable reporting of vfork events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them.
+ */
+ return 0;
+}
+#endif
+
+#if defined(CHILD_HAS_FORKED)
+
+/* Q: Do we need to map the returned process ID to a thread ID?
+
+ * A: I don't think so--here we want a _real_ pid. Any later
+ * operations will call "require_notification_of_events" and
+ * start the mapping.
+ */
+int
+child_has_forked (int tid, int *childpid)
+{
+ int tt_status;
+ ttstate_t ttrace_state;
+ thread_info *tinfo;
+
+ /* Do we have cached thread state that we can consult? If so, use it. */
+ tinfo = find_thread_info (map_from_gdb_tid (tid));
+ if (tinfo != NULL)
+ {
+ copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
+ }
+
+ /* Nope, must read the thread's current state */
+ else
+ {
+ tt_status = call_ttrace (TT_LWP_GET_STATE,
+ tid,
+ (TTRACE_ARG_TYPE) & ttrace_state,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_state),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+
+ if (tt_status < 0)
+ return 0;
+ }
+
+ if (ttrace_state.tts_event & TTEVT_FORK)
+ {
+ *childpid = ttrace_state.tts_u.tts_fork.tts_fpid;
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_HAS_VFORKED)
+
+/* See child_has_forked for pid discussion.
+ */
+int
+child_has_vforked (int tid, int *childpid)
+{
+ int tt_status;
+ ttstate_t ttrace_state;
+ thread_info *tinfo;
+
+ /* Do we have cached thread state that we can consult? If so, use it. */
+ tinfo = find_thread_info (map_from_gdb_tid (tid));
+ if (tinfo != NULL)
+ copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
+
+ /* Nope, must read the thread's current state */
+ else
+ {
+ tt_status = call_ttrace (TT_LWP_GET_STATE,
+ tid,
+ (TTRACE_ARG_TYPE) & ttrace_state,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_state),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+
+ if (tt_status < 0)
+ return 0;
+ }
+
+ if (ttrace_state.tts_event & TTEVT_VFORK)
+ {
+ *childpid = ttrace_state.tts_u.tts_fork.tts_fpid;
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC)
+int
+child_can_follow_vfork_prior_to_exec (void)
+{
+ /* ttrace does allow this.
+
+ ??rehrauer: However, I had major-league problems trying to
+ convince wait_for_inferior to handle that case. Perhaps when
+ it is rewritten to grok multiple processes in an explicit way...
+ */
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
+int
+child_insert_exec_catchpoint (int tid)
+{
+ /* Enable reporting of exec events from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them.
+ */
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_REMOVE_EXEC_CATCHPOINT)
+int
+child_remove_exec_catchpoint (int tid)
+{
+ /* Disable reporting of execevents from the kernel. */
+ /* ??rehrauer: For the moment, we're always enabling these events,
+ and just ignoring them if there's no catchpoint to catch them.
+ */
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_HAS_EXECD)
+int
+child_has_execd (int tid, char **execd_pathname)
+{
+ int tt_status;
+ ttstate_t ttrace_state;
+ thread_info *tinfo;
+
+ /* Do we have cached thread state that we can consult? If so, use it. */
+ tinfo = find_thread_info (map_from_gdb_tid (tid));
+ if (tinfo != NULL)
+ copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
+
+ /* Nope, must read the thread's current state */
+ else
+ {
+ tt_status = call_ttrace (TT_LWP_GET_STATE,
+ tid,
+ (TTRACE_ARG_TYPE) & ttrace_state,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_state),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+
+ if (tt_status < 0)
+ return 0;
+ }
+
+ if (ttrace_state.tts_event & TTEVT_EXEC)
+ {
+ /* See child_pid_to_exec_file in this file: this is a macro.
+ */
+ char *exec_file = target_pid_to_exec_file (tid);
+
+ *execd_pathname = savestring (exec_file, strlen (exec_file));
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+
+
+#if defined(CHILD_HAS_SYSCALL_EVENT)
+int
+child_has_syscall_event (int pid, enum target_waitkind *kind, int *syscall_id)
+{
+ int tt_status;
+ ttstate_t ttrace_state;
+ thread_info *tinfo;
+
+ /* Do we have cached thread state that we can consult? If so, use it. */
+ tinfo = find_thread_info (map_from_gdb_tid (pid));
+ if (tinfo != NULL)
+ copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
+
+ /* Nope, must read the thread's current state */
+ else
+ {
+ tt_status = call_ttrace (TT_LWP_GET_STATE,
+ pid,
+ (TTRACE_ARG_TYPE) & ttrace_state,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_state),
+ TT_NIL);
+
+ if (errno)
+ perror_with_name ("ttrace");
+
+ if (tt_status < 0)
+ return 0;
+ }
+
+ *kind = TARGET_WAITKIND_SPURIOUS; /* Until proven otherwise... */
+ *syscall_id = -1;
+
+ if (ttrace_state.tts_event & TTEVT_SYSCALL_ENTRY)
+ *kind = TARGET_WAITKIND_SYSCALL_ENTRY;
+ else if (ttrace_state.tts_event & TTEVT_SYSCALL_RETURN)
+ *kind = TARGET_WAITKIND_SYSCALL_RETURN;
+ else
+ return 0;
+
+ *syscall_id = ttrace_state.tts_scno;
+ return 1;
+}
+#endif
+
+
+
+#if defined(CHILD_THREAD_ALIVE)
+
+/* Check to see if the given thread is alive.
+
+ * We'll trust the thread list, as the more correct
+ * approach of stopping the process and spinning down
+ * the OS's thread list is _very_ expensive.
+ *
+ * May need a FIXME for that reason.
+ */
+int
+child_thread_alive (ptid_t ptid)
+{
+ lwpid_t gdb_tid = PIDGET (ptid);
+ lwpid_t tid;
+
+ /* This spins down the lists twice.
+ * Possible peformance improvement here!
+ */
+ tid = map_from_gdb_tid (gdb_tid);
+ return !is_terminated (tid);
+}
+
+#endif
+
+
+
+/* This function attempts to read the specified number of bytes from the
+ save_state_t that is our view into the hardware registers, starting at
+ ss_offset, and ending at ss_offset + sizeof_buf - 1
+
+ If this function succeeds, it deposits the fetched bytes into buf,
+ and returns 0.
+
+ If it fails, it returns a negative result. The contents of buf are
+ undefined it this function fails.
+ */
+int
+read_from_register_save_state (int tid, TTRACE_ARG_TYPE ss_offset, char *buf,
+ int sizeof_buf)
+{
+ int tt_status;
+ register_value_t register_value = 0;
+
+ tt_status = call_ttrace (TT_LWP_RUREGS,
+ tid,
+ ss_offset,
+ (TTRACE_ARG_TYPE) sizeof_buf,
+ (TTRACE_ARG_TYPE) buf);
+
+ if (tt_status == 1)
+ /* Map ttrace's version of success to our version.
+ * Sometime ttrace returns 0, but that's ok here.
+ */
+ return 0;
+
+ return tt_status;
+}
+
+
+/* This function attempts to write the specified number of bytes to the
+ save_state_t that is our view into the hardware registers, starting at
+ ss_offset, and ending at ss_offset + sizeof_buf - 1
+
+ If this function succeeds, it deposits the bytes in buf, and returns 0.
+
+ If it fails, it returns a negative result. The contents of the save_state_t
+ are undefined it this function fails.
+ */
+int
+write_to_register_save_state (int tid, TTRACE_ARG_TYPE ss_offset, char *buf,
+ int sizeof_buf)
+{
+ int tt_status;
+ register_value_t register_value = 0;
+
+ tt_status = call_ttrace (TT_LWP_WUREGS,
+ tid,
+ ss_offset,
+ (TTRACE_ARG_TYPE) sizeof_buf,
+ (TTRACE_ARG_TYPE) buf);
+ return tt_status;
+}
+
+
+/* This function is a sop to the largeish number of direct calls
+ to call_ptrace that exist in other files. Rather than create
+ functions whose name abstracts away from ptrace, and change all
+ the present callers of call_ptrace, we'll do the expedient (and
+ perhaps only practical) thing.
+
+ Note HP-UX explicitly disallows a mix of ptrace & ttrace on a traced
+ process. Thus, we must translate all ptrace requests into their
+ process-specific, ttrace equivalents.
+ */
+int
+call_ptrace (int pt_request, int gdb_tid, PTRACE_ARG3_TYPE addr, int data)
+{
+ ttreq_t tt_request;
+ TTRACE_ARG_TYPE tt_addr = (TTRACE_ARG_TYPE) addr;
+ TTRACE_ARG_TYPE tt_data = (TTRACE_ARG_TYPE) data;
+ TTRACE_ARG_TYPE tt_addr2 = TT_NIL;
+ int tt_status;
+ register_value_t register_value;
+ int read_buf;
+
+ /* Perform the necessary argument translation. Note that some
+ cases are funky enough in the ttrace realm that we handle them
+ very specially.
+ */
+ switch (pt_request)
+ {
+ /* The following cases cannot conveniently be handled conveniently
+ by merely adjusting the ptrace arguments and feeding into the
+ generic call to ttrace at the bottom of this function.
+
+ Note that because all branches of this switch end in "return",
+ there's no need for any "break" statements.
+ */
+ case PT_SETTRC:
+ return parent_attach_all ();
+
+ case PT_RUREGS:
+ tt_status = read_from_register_save_state (gdb_tid,
+ tt_addr,
+ &register_value,
+ sizeof (register_value));
+ if (tt_status < 0)
+ return tt_status;
+ return register_value;
+
+ case PT_WUREGS:
+ register_value = (int) tt_data;
+ tt_status = write_to_register_save_state (gdb_tid,
+ tt_addr,
+ &register_value,
+ sizeof (register_value));
+ return tt_status;
+ break;
+
+ case PT_READ_I:
+ tt_status = call_ttrace (TT_PROC_RDTEXT, /* Implicit 4-byte xfer becomes block-xfer. */
+ gdb_tid,
+ tt_addr,
+ (TTRACE_ARG_TYPE) 4,
+ (TTRACE_ARG_TYPE) & read_buf);
+ if (tt_status < 0)
+ return tt_status;
+ return read_buf;
+
+ case PT_READ_D:
+ tt_status = call_ttrace (TT_PROC_RDDATA, /* Implicit 4-byte xfer becomes block-xfer. */
+ gdb_tid,
+ tt_addr,
+ (TTRACE_ARG_TYPE) 4,
+ (TTRACE_ARG_TYPE) & read_buf);
+ if (tt_status < 0)
+ return tt_status;
+ return read_buf;
+
+ case PT_ATTACH:
+ tt_status = call_real_ttrace (TT_PROC_ATTACH,
+ map_from_gdb_tid (gdb_tid),
+ (lwpid_t) TT_NIL,
+ tt_addr,
+ (TTRACE_ARG_TYPE) TT_VERSION,
+ tt_addr2);
+ if (tt_status < 0)
+ return tt_status;
+ return tt_status;
+
+ /* The following cases are handled by merely adjusting the ptrace
+ arguments and feeding into the generic call to ttrace.
+ */
+ case PT_DETACH:
+ tt_request = TT_PROC_DETACH;
+ break;
+
+ case PT_WRITE_I:
+ tt_request = TT_PROC_WRTEXT; /* Translates 4-byte xfer to block-xfer. */
+ tt_data = 4; /* This many bytes. */
+ tt_addr2 = (TTRACE_ARG_TYPE) & data; /* Address of xfer source. */
+ break;
+
+ case PT_WRITE_D:
+ tt_request = TT_PROC_WRDATA; /* Translates 4-byte xfer to block-xfer. */
+ tt_data = 4; /* This many bytes. */
+ tt_addr2 = (TTRACE_ARG_TYPE) & data; /* Address of xfer source. */
+ break;
+
+ case PT_RDTEXT:
+ tt_request = TT_PROC_RDTEXT;
+ break;
+
+ case PT_RDDATA:
+ tt_request = TT_PROC_RDDATA;
+ break;
+
+ case PT_WRTEXT:
+ tt_request = TT_PROC_WRTEXT;
+ break;
+
+ case PT_WRDATA:
+ tt_request = TT_PROC_WRDATA;
+ break;
+
+ case PT_CONTINUE:
+ tt_request = TT_PROC_CONTINUE;
+ break;
+
+ case PT_STEP:
+ tt_request = TT_LWP_SINGLE; /* Should not be making this request? */
+ break;
+
+ case PT_KILL:
+ tt_request = TT_PROC_EXIT;
+ break;
+
+ case PT_GET_PROCESS_PATHNAME:
+ tt_request = TT_PROC_GET_PATHNAME;
+ break;
+
+ default:
+ tt_request = pt_request; /* Let ttrace be the one to complain. */
+ break;
+ }
+
+ return call_ttrace (tt_request,
+ gdb_tid,
+ tt_addr,
+ tt_data,
+ tt_addr2);
+}
+
+/* Kill that pesky process!
+ */
+void
+kill_inferior (void)
+{
+ int tid;
+ int wait_status;
+ thread_info *t;
+ thread_info **paranoia;
+ int para_count, i;
+
+ if (PIDGET (inferior_ptid) == 0)
+ return;
+
+ /* Walk the list of "threads", some of which are "pseudo threads",
+ aka "processes". For each that is NOT inferior_ptid, stop it,
+ and detach it.
+
+ You see, we may not have just a single process to kill. If we're
+ restarting or quitting or detaching just after the inferior has
+ forked, then we've actually two processes to clean up.
+
+ But we can't just call target_mourn_inferior() for each, since that
+ zaps the target vector.
+ */
+
+ paranoia = (thread_info **) xmalloc (thread_head.count *
+ sizeof (thread_info *));
+ para_count = 0;
+
+ t = thread_head.head;
+ while (t)
+ {
+
+ paranoia[para_count] = t;
+ for (i = 0; i < para_count; i++)
+ {
+ if (t->next == paranoia[i])
+ {
+ warning ("Bad data in gdb's thread data; repairing.");
+ t->next = 0;
+ }
+ }
+ para_count++;
+
+ if (t->am_pseudo && (t->pid != PIDGET (inferior_ptid)))
+ {
+ call_ttrace (TT_PROC_EXIT,
+ t->pid,
+ TT_NIL,
+ TT_NIL,
+ TT_NIL);
+ }
+ t = t->next;
+ }
+
+ xfree (paranoia);
+
+ call_ttrace (TT_PROC_EXIT,
+ PIDGET (inferior_ptid),
+ TT_NIL,
+ TT_NIL,
+ TT_NIL);
+ target_mourn_inferior ();
+ clear_thread_info ();
+}
+
+
+#ifndef CHILD_RESUME
+
+/* Sanity check a thread about to be continued.
+ */
+static void
+thread_dropping_event_check (thread_info *p)
+{
+ if (!p->handled)
+ {
+ /*
+ * This seems to happen when we "next" over a
+ * "fork()" while following the parent. If it's
+ * the FORK event, that's ok. If it's a SIGNAL
+ * in the unfollowed child, that's ok to--but
+ * how can we know that's what's going on?
+ *
+ * FIXME!
+ */
+ if (p->have_state)
+ {
+ if (p->last_stop_state.tts_event == TTEVT_FORK)
+ {
+ /* Ok */
+ ;
+ }
+ else if (p->last_stop_state.tts_event == TTEVT_SIGNAL)
+ {
+ /* Ok, close eyes and let it happen.
+ */
+ ;
+ }
+ else
+ {
+ /* This shouldn't happen--we're dropping a
+ * real event.
+ */
+ warning ("About to continue process %d, thread %d with unhandled event %s.",
+ p->pid, p->tid,
+ get_printable_name_of_ttrace_event (
+ p->last_stop_state.tts_event));
+
+#ifdef PARANOIA
+ if (debug_on)
+ print_tthread (p);
+#endif
+ }
+ }
+ else
+ {
+ /* No saved state, have to assume it failed.
+ */
+ warning ("About to continue process %d, thread %d with unhandled event.",
+ p->pid, p->tid);
+#ifdef PARANOIA
+ if (debug_on)
+ print_tthread (p);
+#endif
+ }
+ }
+
+} /* thread_dropping_event_check */
+
+/* Use a loop over the threads to continue all the threads but
+ * the one specified, which is to be stepped.
+ */
+static void
+threads_continue_all_but_one (lwpid_t gdb_tid, int signal)
+{
+ thread_info *p;
+ int thread_signal;
+ lwpid_t real_tid;
+ lwpid_t scan_tid;
+ ttstate_t state;
+ int real_pid;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Using loop over threads to step/resume with signals\n");
+#endif
+
+ /* First update the thread list.
+ */
+ set_all_unseen ();
+ real_tid = map_from_gdb_tid (gdb_tid);
+ real_pid = get_pid_for (real_tid);
+
+ scan_tid = get_process_first_stopped_thread_id (real_pid, &state);
+ while (0 != scan_tid)
+ {
+
+#ifdef THREAD_DEBUG
+ /* FIX: later should check state is stopped;
+ * state.tts_flags & TTS_STATEMASK == TTS_WASSUSPENDED
+ */
+ if (debug_on)
+ if (state.tts_flags & TTS_STATEMASK != TTS_WASSUSPENDED)
+ printf ("About to continue non-stopped thread %d\n", scan_tid);
+#endif
+
+ p = find_thread_info (scan_tid);
+ if (NULL == p)
+ {
+ add_tthread (real_pid, scan_tid);
+ p = find_thread_info (scan_tid);
+
+ /* This is either a newly-created thread or the
+ * result of a fork; in either case there's no
+ * actual event to worry about.
+ */
+ p->handled = 1;
+
+ if (state.tts_event != TTEVT_NONE)
+ {
+ /* Oops, do need to worry!
+ */
+ warning ("Unexpected thread with \"%s\" event.",
+ get_printable_name_of_ttrace_event (state.tts_event));
+ }
+ }
+ else if (scan_tid != p->tid)
+ error ("Bad data in thread database.");
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ if (p->terminated)
+ printf ("Why are we continuing a dead thread?\n");
+#endif
+
+ p->seen = 1;
+
+ scan_tid = get_process_next_stopped_thread_id (real_pid, &state);
+ }
+
+ /* Remove unseen threads.
+ */
+ update_thread_list ();
+
+ /* Now run down the thread list and continue or step.
+ */
+ for (p = thread_head.head; p; p = p->next)
+ {
+
+ /* Sanity check.
+ */
+ thread_dropping_event_check (p);
+
+ /* Pass the correct signals along.
+ */
+ if (p->have_signal)
+ {
+ thread_signal = p->signal_value;
+ p->have_signal = 0;
+ }
+ else
+ thread_signal = 0;
+
+ if (p->tid != real_tid)
+ {
+ /*
+ * Not the thread of interest, so continue it
+ * as the user expects.
+ */
+ if (p->stepping_mode == DO_STEP)
+ {
+ /* Just step this thread.
+ */
+ call_ttrace (
+ TT_LWP_SINGLE,
+ p->tid,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host (signal),
+ TT_NIL);
+ }
+ else
+ {
+ /* Regular continue (default case).
+ */
+ call_ttrace (
+ TT_LWP_CONTINUE,
+ p->tid,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host (thread_signal),
+ TT_NIL);
+ }
+ }
+ else
+ {
+ /* Step the thread of interest.
+ */
+ call_ttrace (
+ TT_LWP_SINGLE,
+ real_tid,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host (signal),
+ TT_NIL);
+ }
+ } /* Loop over threads */
+} /* End threads_continue_all_but_one */
+
+/* Use a loop over the threads to continue all the threads.
+ * This is done when a signal must be sent to any of the threads.
+ */
+static void
+threads_continue_all_with_signals (lwpid_t gdb_tid, int signal)
+{
+ thread_info *p;
+ int thread_signal;
+ lwpid_t real_tid;
+ lwpid_t scan_tid;
+ ttstate_t state;
+ int real_pid;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Using loop over threads to resume with signals\n");
+#endif
+
+ /* Scan and update thread list.
+ */
+ set_all_unseen ();
+ real_tid = map_from_gdb_tid (gdb_tid);
+ real_pid = get_pid_for (real_tid);
+
+ scan_tid = get_process_first_stopped_thread_id (real_pid, &state);
+ while (0 != scan_tid)
+ {
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ if (state.tts_flags & TTS_STATEMASK != TTS_WASSUSPENDED)
+ warning ("About to continue non-stopped thread %d\n", scan_tid);
+#endif
+
+ p = find_thread_info (scan_tid);
+ if (NULL == p)
+ {
+ add_tthread (real_pid, scan_tid);
+ p = find_thread_info (scan_tid);
+
+ /* This is either a newly-created thread or the
+ * result of a fork; in either case there's no
+ * actual event to worry about.
+ */
+ p->handled = 1;
+
+ if (state.tts_event != TTEVT_NONE)
+ {
+ /* Oops, do need to worry!
+ */
+ warning ("Unexpected thread with \"%s\" event.",
+ get_printable_name_of_ttrace_event (state.tts_event));
+ }
+ }
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ if (p->terminated)
+ printf ("Why are we continuing a dead thread? (1)\n");
+#endif
+
+ p->seen = 1;
+
+ scan_tid = get_process_next_stopped_thread_id (real_pid, &state);
+ }
+
+ /* Remove unseen threads from our list.
+ */
+ update_thread_list ();
+
+ /* Continue the threads.
+ */
+ for (p = thread_head.head; p; p = p->next)
+ {
+
+ /* Sanity check.
+ */
+ thread_dropping_event_check (p);
+
+ /* Pass the correct signals along.
+ */
+ if (p->tid == real_tid)
+ {
+ thread_signal = signal;
+ p->have_signal = 0;
+ }
+ else if (p->have_signal)
+ {
+ thread_signal = p->signal_value;
+ p->have_signal = 0;
+ }
+ else
+ thread_signal = 0;
+
+ if (p->stepping_mode == DO_STEP)
+ {
+ call_ttrace (
+ TT_LWP_SINGLE,
+ p->tid,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host (signal),
+ TT_NIL);
+ }
+ else
+ {
+ /* Continue this thread (default case).
+ */
+ call_ttrace (
+ TT_LWP_CONTINUE,
+ p->tid,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host (thread_signal),
+ TT_NIL);
+ }
+ }
+} /* End threads_continue_all_with_signals */
+
+/* Step one thread only.
+ */
+static void
+thread_fake_step (lwpid_t tid, enum target_signal signal)
+{
+ thread_info *p;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ {
+ printf ("Doing a fake-step over a bpt, etc. for %d\n", tid);
+
+ if (is_terminated (tid))
+ printf ("Why are we continuing a dead thread? (4)\n");
+ }
+#endif
+
+ if (doing_fake_step)
+ warning ("Step while step already in progress.");
+
+ /* See if there's a saved signal value for this
+ * thread to be passed on, but no current signal.
+ */
+ p = find_thread_info (tid);
+ if (p != NULL)
+ {
+ if (p->have_signal && signal == TARGET_SIGNAL_0)
+ {
+ /* Pass on a saved signal.
+ */
+ signal = p->signal_value;
+ }
+
+ p->have_signal = 0;
+ }
+
+ if (!p->handled)
+ warning ("Internal error: continuing unhandled thread.");
+
+ call_ttrace (TT_LWP_SINGLE,
+ tid,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host (signal),
+ TT_NIL);
+
+ /* Do bookkeeping so "call_ttrace_wait" knows it has to wait
+ * for this thread only, and clear any saved signal info.
+ */
+ doing_fake_step = 1;
+ fake_step_tid = tid;
+
+} /* End thread_fake_step */
+
+/* Continue one thread when a signal must be sent to it.
+ */
+static void
+threads_continue_one_with_signal (lwpid_t gdb_tid, int signal)
+{
+ thread_info *p;
+ lwpid_t real_tid;
+ int real_pid;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Continuing one thread with a signal\n");
+#endif
+
+ real_tid = map_from_gdb_tid (gdb_tid);
+ real_pid = get_pid_for (real_tid);
+
+ p = find_thread_info (real_tid);
+ if (NULL == p)
+ {
+ add_tthread (real_pid, real_tid);
+ }
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ if (p->terminated)
+ printf ("Why are we continuing a dead thread? (2)\n");
+#endif
+
+ if (!p->handled)
+ warning ("Internal error: continuing unhandled thread.");
+
+ p->have_signal = 0;
+
+ call_ttrace (TT_LWP_CONTINUE,
+ gdb_tid,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host (signal),
+ TT_NIL);
+}
+#endif
+
+#ifndef CHILD_RESUME
+
+/* Resume execution of the inferior process.
+
+ * This routine is in charge of setting the "handled" bits.
+ *
+ * If STEP is zero, continue it.
+ * If STEP is nonzero, single-step it.
+ *
+ * If SIGNAL is nonzero, give it that signal.
+ *
+ * If TID is -1, apply to all threads.
+ * If TID is not -1, apply to specified thread.
+ *
+ * STEP
+ * \ !0 0
+ * TID \________________________________________________
+ * |
+ * -1 | Step current Continue all threads
+ * | thread and (but which gets any
+ * | continue others signal?--We look at
+ * | "inferior_ptid")
+ * |
+ * N | Step _this_ thread Continue _this_ thread
+ * | and leave others and leave others
+ * | stopped; internally stopped; used only for
+ * | used by gdb, never hardware watchpoints
+ * | a user command. and attach, never a
+ * | user command.
+ */
+void
+child_resume (ptid_t ptid, int step, enum target_signal signal)
+{
+ int resume_all_threads;
+ lwpid_t tid;
+ process_state_t new_process_state;
+ lwpid_t gdb_tid = PIDGET (ptid);
+
+ resume_all_threads =
+ (gdb_tid == INFTTRACE_ALL_THREADS) ||
+ (vfork_in_flight);
+
+ if (resume_all_threads)
+ {
+ /* Resume all threads, but first pick a tid value
+ * so we can get the pid when in call_ttrace doing
+ * the map.
+ */
+ if (vfork_in_flight)
+ tid = vforking_child_pid;
+ else
+ tid = map_from_gdb_tid (PIDGET (inferior_ptid));
+ }
+ else
+ tid = map_from_gdb_tid (gdb_tid);
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ {
+ if (more_events_left)
+ printf ("More events; ");
+
+ if (signal != 0)
+ printf ("Sending signal %d; ", signal);
+
+ if (resume_all_threads)
+ {
+ if (step == 0)
+ printf ("Continue process %d\n", tid);
+ else
+ printf ("Step/continue thread %d\n", tid);
+ }
+ else
+ {
+ if (step == 0)
+ printf ("Continue thread %d\n", tid);
+ else
+ printf ("Step just thread %d\n", tid);
+ }
+
+ if (vfork_in_flight)
+ printf ("Vfork in flight\n");
+ }
+#endif
+
+ if (process_state == RUNNING)
+ warning ("Internal error in resume logic; doing resume or step anyway.");
+
+ if (!step /* Asked to continue... */
+ && resume_all_threads /* whole process.. */
+ && signal != 0 /* with a signal... */
+ && more_events_left > 0)
+ { /* but we can't yet--save it! */
+
+ /* Continue with signal means we have to set the pending
+ * signal value for this thread.
+ */
+ thread_info *k;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Saving signal %d for thread %d\n", signal, tid);
+#endif
+
+ k = find_thread_info (tid);
+ if (k != NULL)
+ {
+ k->have_signal = 1;
+ k->signal_value = signal;
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ if (k->terminated)
+ printf ("Why are we continuing a dead thread? (3)\n");
+#endif
+
+ }
+
+#ifdef THREAD_DEBUG
+ else if (debug_on)
+ {
+ printf ("No thread info for tid %d\n", tid);
+ }
+#endif
+ }
+
+ /* Are we faking this "continue" or "step"?
+
+ * We used to do steps by continuing all the threads for
+ * which the events had been handled already. While
+ * conceptually nicer (hides it all in a lower level), this
+ * can lead to starvation and a hang (e.g. all but one thread
+ * are unhandled at a breakpoint just before a "join" operation,
+ * and one thread is in the join, and the user wants to step that
+ * thread).
+ */
+ if (resume_all_threads /* Whole process, therefore user command */
+ && more_events_left > 0)
+ { /* But we can't do this yet--fake it! */
+ thread_info *p;
+
+ if (!step)
+ {
+ /* No need to do any notes on a per-thread
+ * basis--we're done!
+ */
+#ifdef WAIT_BUFFER_DEBUG
+ if (debug_on)
+ printf ("Faking a process resume.\n");
+#endif
+
+ return;
+ }
+ else
+ {
+
+#ifdef WAIT_BUFFER_DEBUG
+ if (debug_on)
+ printf ("Faking a process step.\n");
+#endif
+
+ }
+
+ p = find_thread_info (tid);
+ if (p == NULL)
+ {
+ warning ("No thread information for tid %d, 'next' command ignored.\n", tid);
+ return;
+ }
+ else
+ {
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ if (p->terminated)
+ printf ("Why are we continuing a dead thread? (3.5)\n");
+#endif
+
+ if (p->stepping_mode != DO_DEFAULT)
+ {
+ warning ("Step or continue command applied to thread which is already stepping or continuing; command ignored.");
+
+ return;
+ }
+
+ if (step)
+ p->stepping_mode = DO_STEP;
+ else
+ p->stepping_mode = DO_CONTINUE;
+
+ return;
+ } /* Have thread info */
+ } /* Must fake step or go */
+
+ /* Execept for fake-steps, from here on we know we are
+ * going to wind up with a running process which will
+ * need a real wait.
+ */
+ new_process_state = RUNNING;
+
+ /* An address of TT_USE_CURRENT_PC tells ttrace to continue from where
+ * it was. (If GDB wanted it to start some other way, we have already
+ * written a new PC value to the child.)
+ *
+ * If this system does not support PT_STEP, a higher level function will
+ * have called single_step() to transmute the step request into a
+ * continue request (by setting breakpoints on all possible successor
+ * instructions), so we don't have to worry about that here.
+ */
+ if (step)
+ {
+ if (resume_all_threads)
+ {
+ /*
+ * Regular user step: other threads get a "continue".
+ */
+ threads_continue_all_but_one (tid, signal);
+ clear_all_handled ();
+ clear_all_stepping_mode ();
+ }
+
+ else
+ {
+ /* "Fake step": gdb is stepping one thread over a
+ * breakpoint, watchpoint, or out of a library load
+ * event, etc. The rest just stay where they are.
+ *
+ * Also used when there are pending events: we really
+ * step the current thread, but leave the rest stopped.
+ * Users can't request this, but "wait_for_inferior"
+ * does--a lot!
+ */
+ thread_fake_step (tid, signal);
+
+ /* Clear the "handled" state of this thread, because
+ * we'll soon get a new event for it. Other events
+ * stay as they were.
+ */
+ clear_handled (tid);
+ clear_stepping_mode (tid);
+ new_process_state = FAKE_STEPPING;
+ }
+ }
+
+ else
+ {
+ /* TT_LWP_CONTINUE can pass signals to threads,
+ * TT_PROC_CONTINUE can't. So if there are any
+ * signals to pass, we have to use the (slower)
+ * loop over the stopped threads.
+ *
+ * Equally, if we have to not continue some threads,
+ * due to saved events, we have to use the loop.
+ */
+ if ((signal != 0) || saved_signals_exist ())
+ {
+ if (resume_all_threads)
+ {
+
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Doing a continue by loop of all threads\n");
+#endif
+
+ threads_continue_all_with_signals (tid, signal);
+
+ clear_all_handled ();
+ clear_all_stepping_mode ();
+ }
+
+ else
+ {
+#ifdef THREAD_DEBUG
+ printf ("Doing a continue w/signal of just thread %d\n", tid);
+#endif
+
+ threads_continue_one_with_signal (tid, signal);
+
+ /* Clear the "handled" state of this thread, because
+ * we'll soon get a new event for it. Other events
+ * can stay as they were.
+ */
+ clear_handled (tid);
+ clear_stepping_mode (tid);
+ }
+ }
+
+ else
+ {
+ /* No signals to send.
+ */
+ if (resume_all_threads)
+ {
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Doing a continue by process of process %d\n", tid);
+#endif
+
+ if (more_events_left > 0)
+ {
+ warning ("Losing buffered events on continue.");
+ more_events_left = 0;
+ }
+
+ call_ttrace (TT_PROC_CONTINUE,
+ tid,
+ TT_NIL,
+ TT_NIL,
+ TT_NIL);
+
+ clear_all_handled ();
+ clear_all_stepping_mode ();
+ }
+
+ else
+ {
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ {
+ printf ("Doing a continue of just thread %d\n", tid);
+ if (is_terminated (tid))
+ printf ("Why are we continuing a dead thread? (5)\n");
+ }
+#endif
+
+ call_ttrace (TT_LWP_CONTINUE,
+ tid,
+ TT_NIL,
+ TT_NIL,
+ TT_NIL);
+
+ /* Clear the "handled" state of this thread, because
+ * we'll soon get a new event for it. Other events
+ * can stay as they were.
+ */
+ clear_handled (tid);
+ clear_stepping_mode (tid);
+ }
+ }
+ }
+
+ process_state = new_process_state;
+
+#ifdef WAIT_BUFFER_DEBUG
+ if (debug_on)
+ printf ("Process set to %s\n",
+ get_printable_name_of_process_state (process_state));
+#endif
+
+}
+#endif /* CHILD_RESUME */
+
+
+#ifdef ATTACH_DETACH
+/*
+ * Like it says.
+ *
+ * One worry is that we may not be attaching to "inferior_ptid"
+ * and thus may not want to clear out our data. FIXME?
+ *
+ */
+static void
+update_thread_state_after_attach (int pid, attach_continue_t kind_of_go)
+{
+ int tt_status;
+ ttstate_t thread_state;
+ lwpid_t a_thread;
+ lwpid_t tid;
+
+ /* The process better be stopped.
+ */
+ if (process_state != STOPPED
+ && process_state != VFORKING)
+ warning ("Internal error attaching.");
+
+ /* Clear out old tthread info and start over. This has the
+ * side effect of ensuring that the TRAP is reported as being
+ * in the right thread (re-mapped from tid to pid).
+ *
+ * It's because we need to add the tthread _now_ that we
+ * need to call "clear_thread_info" _now_, and that's why
+ * "require_notification_of_events" doesn't clear the thread
+ * info (it's called later than this routine).
+ */
+ clear_thread_info ();
+ a_thread = 0;
+
+ for (tid = get_process_first_stopped_thread_id (pid, &thread_state);
+ tid != 0;
+ tid = get_process_next_stopped_thread_id (pid, &thread_state))
+ {
+ thread_info *p;
+
+ if (a_thread == 0)
+ {
+ a_thread = tid;
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("Attaching to process %d, thread %d\n",
+ pid, a_thread);
+#endif
+ }
+
+ /* Tell ourselves and the "rest of gdb" that this thread
+ * exists.
+ *
+ * This isn't really a hack. Other thread-based versions
+ * of gdb (e.g. gnu-nat.c) seem to do the same thing.
+ *
+ * We don't need to do mapping here, as we know this
+ * is the first thread and thus gets the real pid
+ * (and is "inferior_ptid").
+ *
+ * NOTE: it probably isn't the originating thread,
+ * but that doesn't matter (we hope!).
+ */
+ add_tthread (pid, tid);
+ p = find_thread_info (tid);
+ if (NULL == p) /* ?We just added it! */
+ error ("Internal error adding a thread on attach.");
+
+ copy_ttstate_t (&p->last_stop_state, &thread_state);
+ p->have_state = 1;
+
+ if (DO_ATTACH_CONTINUE == kind_of_go)
+ {
+ /*
+ * If we are going to CONTINUE afterwards,
+ * raising a SIGTRAP, don't bother trying to
+ * handle this event. But check first!
+ */
+ switch (p->last_stop_state.tts_event)
+ {
+
+ case TTEVT_NONE:
+ /* Ok to set this handled.
+ */
+ break;
+
+ default:
+ warning ("Internal error; skipping event %s on process %d, thread %d.",
+ get_printable_name_of_ttrace_event (
+ p->last_stop_state.tts_event),
+ p->pid, p->tid);
+ }
+
+ set_handled (pid, tid);
+
+ }
+ else
+ {
+ /* There will be no "continue" opertion, so the
+ * process remains stopped. Don't set any events
+ * handled except the "gimmies".
+ */
+ switch (p->last_stop_state.tts_event)
+ {
+
+ case TTEVT_NONE:
+ /* Ok to ignore this.
+ */
+ set_handled (pid, tid);
+ break;
+
+ case TTEVT_EXEC:
+ case TTEVT_FORK:
+ /* Expected "other" FORK or EXEC event from a
+ * fork or vfork.
+ */
+ break;
+
+ default:
+ printf ("Internal error: failed to handle event %s on process %d, thread %d.",
+ get_printable_name_of_ttrace_event (
+ p->last_stop_state.tts_event),
+ p->pid, p->tid);
+ }
+ }
+
+ add_thread (pid_to_ptid (pid)); /* in thread.c */
+ }
+
+#ifdef PARANOIA
+ if (debug_on)
+ print_tthreads ();
+#endif
+
+ /* One mustn't call ttrace_wait() after attaching via ttrace,
+ 'cause the process is stopped already.
+
+ However, the upper layers of gdb's execution control will
+ want to wait after attaching (but not after forks, in
+ which case they will be doing a "target_resume", anticipating
+ a later TTEVT_EXEC or TTEVT_FORK event).
+
+ To make this attach() implementation more compatible with
+ others, we'll make the attached-to process raise a SIGTRAP.
+
+ Issue: this continues only one thread. That could be
+ dangerous if the thread is blocked--the process won't run
+ and no trap will be raised. FIX! (check state.tts_flags?
+ need one that's either TTS_WASRUNNING--but we've stopped
+ it and made it TTS_WASSUSPENDED. Hum...FIXME!)
+ */
+ if (DO_ATTACH_CONTINUE == kind_of_go)
+ {
+ tt_status = call_real_ttrace (
+ TT_LWP_CONTINUE,
+ pid,
+ a_thread,
+ TT_USE_CURRENT_PC,
+ (TTRACE_ARG_TYPE) target_signal_to_host (TARGET_SIGNAL_TRAP),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+
+ clear_handled (a_thread); /* So TRAP will be reported. */
+
+ /* Now running.
+ */
+ process_state = RUNNING;
+ }
+
+ attach_flag = 1;
+}
+#endif /* ATTACH_DETACH */
+
+
+#ifdef ATTACH_DETACH
+/* Start debugging the process whose number is PID.
+ * (A _real_ pid).
+ */
+int
+attach (int pid)
+{
+ int tt_status;
+
+ tt_status = call_real_ttrace (
+ TT_PROC_ATTACH,
+ pid,
+ (lwpid_t) TT_NIL,
+ TT_NIL,
+ (TTRACE_ARG_TYPE) TT_VERSION,
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace attach");
+
+ /* If successful, the process is now stopped.
+ */
+ process_state = STOPPED;
+
+ /* Our caller ("attach_command" in "infcmd.c")
+ * expects to do a "wait_for_inferior" after
+ * the attach, so make sure the inferior is
+ * running when we're done.
+ */
+ update_thread_state_after_attach (pid, DO_ATTACH_CONTINUE);
+
+ return pid;
+}
+
+
+#if defined(CHILD_POST_ATTACH)
+void
+child_post_attach (int pid)
+{
+#ifdef THREAD_DEBUG
+ if (debug_on)
+ printf ("child-post-attach call\n");
+#endif
+
+ require_notification_of_events (pid);
+}
+#endif
+
+
+/* Stop debugging the process whose number is PID
+ and continue it with signal number SIGNAL.
+ SIGNAL = 0 means just continue it.
+ */
+void
+detach (int signal)
+{
+ errno = 0;
+ call_ttrace (TT_PROC_DETACH,
+ PIDGET (inferior_ptid),
+ TT_NIL,
+ (TTRACE_ARG_TYPE) signal,
+ TT_NIL);
+ attach_flag = 0;
+
+ clear_thread_info ();
+
+ /* Process-state? */
+}
+#endif /* ATTACH_DETACH */
+
+
+/* Default the type of the ttrace transfer to int. */
+#ifndef TTRACE_XFER_TYPE
+#define TTRACE_XFER_TYPE int
+#endif
+
+void
+_initialize_kernel_u_addr (void)
+{
+}
+
+#if !defined (CHILD_XFER_MEMORY)
+/* NOTE! I tried using TTRACE_READDATA, etc., to read and write memory
+ in the NEW_SUN_TTRACE case.
+ It ought to be straightforward. But it appears that writing did
+ not write the data that I specified. I cannot understand where
+ it got the data that it actually did write. */
+
+/* Copy LEN bytes to or from inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. Copy to inferior if
+ WRITE is nonzero. TARGET is ignored.
+
+ Returns the length copied, which is either the LEN argument or zero.
+ This xfer function does not do partial moves, since child_ops
+ doesn't allow memory operations to cross below us in the target stack
+ anyway. */
+
+int
+child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (TTRACE_XFER_TYPE);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (TTRACE_XFER_TYPE) - 1)
+ / sizeof (TTRACE_XFER_TYPE);
+ /* Allocate buffer of that many longwords. */
+ /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe
+ because it uses alloca to allocate a buffer of arbitrary size.
+ For very large xfers, this could crash GDB's stack. */
+ register TTRACE_XFER_TYPE *buffer
+ = (TTRACE_XFER_TYPE *) alloca (count * sizeof (TTRACE_XFER_TYPE));
+
+ if (write)
+ {
+ /* Fill start and end extra bytes of buffer with existing memory data. */
+
+ if (addr != memaddr || len < (int) sizeof (TTRACE_XFER_TYPE))
+ {
+ /* Need part of initial word -- fetch it. */
+ buffer[0] = call_ttrace (TT_LWP_RDTEXT,
+ PIDGET (inferior_ptid),
+ (TTRACE_ARG_TYPE) addr,
+ TT_NIL,
+ TT_NIL);
+ }
+
+ if (count > 1) /* FIXME, avoid if even boundary */
+ {
+ buffer[count - 1] = call_ttrace (TT_LWP_RDTEXT,
+ PIDGET (inferior_ptid),
+ ((TTRACE_ARG_TYPE)
+ (addr + (count - 1) * sizeof (TTRACE_XFER_TYPE))),
+ TT_NIL,
+ TT_NIL);
+ }
+
+ /* Copy data to be written over corresponding part of buffer */
+
+ memcpy ((char *) buffer + (memaddr & (sizeof (TTRACE_XFER_TYPE) - 1)),
+ myaddr,
+ len);
+
+ /* Write the entire buffer. */
+
+ for (i = 0; i < count; i++, addr += sizeof (TTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ call_ttrace (TT_LWP_WRDATA,
+ PIDGET (inferior_ptid),
+ (TTRACE_ARG_TYPE) addr,
+ (TTRACE_ARG_TYPE) buffer[i],
+ TT_NIL);
+ if (errno)
+ {
+ /* Using the appropriate one (I or D) is necessary for
+ Gould NP1, at least. */
+ errno = 0;
+ call_ttrace (TT_LWP_WRTEXT,
+ PIDGET (inferior_ptid),
+ (TTRACE_ARG_TYPE) addr,
+ (TTRACE_ARG_TYPE) buffer[i],
+ TT_NIL);
+ }
+ if (errno)
+ return 0;
+ }
+ }
+ else
+ {
+ /* Read all the longwords */
+ for (i = 0; i < count; i++, addr += sizeof (TTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ buffer[i] = call_ttrace (TT_LWP_RDTEXT,
+ PIDGET (inferior_ptid),
+ (TTRACE_ARG_TYPE) addr,
+ TT_NIL,
+ TT_NIL);
+ if (errno)
+ return 0;
+ QUIT;
+ }
+
+ /* Copy appropriate bytes out of the buffer. */
+ memcpy (myaddr,
+ (char *) buffer + (memaddr & (sizeof (TTRACE_XFER_TYPE) - 1)),
+ len);
+ }
+ return len;
+}
+
+
+static void
+udot_info (void)
+{
+ int udot_off; /* Offset into user struct */
+ int udot_val; /* Value from user struct at udot_off */
+ char mess[128]; /* For messages */
+
+ if (!target_has_execution)
+ {
+ error ("The program is not being run.");
+ }
+
+#if !defined (KERNEL_U_SIZE)
+
+ /* Adding support for this command is easy. Typically you just add a
+ routine, called "kernel_u_size" that returns the size of the user
+ struct, to the appropriate *-nat.c file and then add to the native
+ config file "#define KERNEL_U_SIZE kernel_u_size()" */
+ error ("Don't know how large ``struct user'' is in this version of gdb.");
+
+#else
+
+ for (udot_off = 0; udot_off < KERNEL_U_SIZE; udot_off += sizeof (udot_val))
+ {
+ if ((udot_off % 24) == 0)
+ {
+ if (udot_off > 0)
+ {
+ printf_filtered ("\n");
+ }
+ printf_filtered ("%04x:", udot_off);
+ }
+ udot_val = call_ttrace (TT_LWP_RUREGS,
+ PIDGET (inferior_ptid),
+ (TTRACE_ARG_TYPE) udot_off,
+ TT_NIL,
+ TT_NIL);
+ if (errno != 0)
+ {
+ sprintf (mess, "\nreading user struct at offset 0x%x", udot_off);
+ perror_with_name (mess);
+ }
+ /* Avoid using nonportable (?) "*" in print specs */
+ printf_filtered (sizeof (int) == 4 ? " 0x%08x" : " 0x%16x", udot_val);
+ }
+ printf_filtered ("\n");
+
+#endif
+}
+#endif /* !defined (CHILD_XFER_MEMORY). */
+
+
+/* TTrace version of "target_pid_to_exec_file"
+ */
+char *
+child_pid_to_exec_file (int tid)
+{
+ int tt_status;
+ static char exec_file_buffer[1024];
+ pid_t pid;
+ static struct pst_status buf;
+
+ /* On various versions of hpux11, this may fail due to a supposed
+ kernel bug. We have alternate methods to get this information
+ (ie pstat). */
+ tt_status = call_ttrace (TT_PROC_GET_PATHNAME,
+ tid,
+ (uint64_t) exec_file_buffer,
+ sizeof (exec_file_buffer) - 1,
+ 0);
+ if (tt_status >= 0)
+ return exec_file_buffer;
+
+ /* Try to get process information via pstat and extract the filename
+ from the pst_cmd field within the pst_status structure. */
+ if (pstat_getproc (&buf, sizeof (struct pst_status), 0, tid) != -1)
+ {
+ char *p = buf.pst_cmd;
+
+ while (*p && *p != ' ')
+ p++;
+ *p = 0;
+
+ return (buf.pst_cmd);
+ }
+
+ return (NULL);
+}
+
+void
+pre_fork_inferior (void)
+{
+ int status;
+
+ status = pipe (startup_semaphore.parent_channel);
+ if (status < 0)
+ {
+ warning ("error getting parent pipe for startup semaphore");
+ return;
+ }
+
+ status = pipe (startup_semaphore.child_channel);
+ if (status < 0)
+ {
+ warning ("error getting child pipe for startup semaphore");
+ return;
+ }
+}
+
+/* Called via #define REQUIRE_ATTACH from inftarg.c,
+ * ultimately from "follow_inferior_fork" in infrun.c,
+ * itself called from "resume".
+ *
+ * This seems to be intended to attach after a fork or
+ * vfork, while "attach" is used to attach to a pid
+ * given by the user. The check for an existing attach
+ * seems odd--it always fails in our test system.
+ */
+int
+hppa_require_attach (int pid)
+{
+ int tt_status;
+ CORE_ADDR pc;
+ CORE_ADDR pc_addr;
+ unsigned int regs_offset;
+ process_state_t old_process_state = process_state;
+
+ /* Are we already attached? There appears to be no explicit
+ * way to answer this via ttrace, so we try something which
+ * should be innocuous if we are attached. If that fails,
+ * then we assume we're not attached, and so attempt to make
+ * it so.
+ */
+ errno = 0;
+ tt_status = call_real_ttrace (TT_PROC_STOP,
+ pid,
+ (lwpid_t) TT_NIL,
+ (TTRACE_ARG_TYPE) TT_NIL,
+ (TTRACE_ARG_TYPE) TT_NIL,
+ TT_NIL);
+
+ if (errno)
+ {
+ /* No change to process-state!
+ */
+ errno = 0;
+ pid = attach (pid);
+ }
+ else
+ {
+ /* If successful, the process is now stopped. But if
+ * we're VFORKING, the parent is still running, so don't
+ * change the process state.
+ */
+ if (process_state != VFORKING)
+ process_state = STOPPED;
+
+ /* If we were already attached, you'd think that we
+ * would need to start going again--but you'd be wrong,
+ * as the fork-following code is actually in the middle
+ * of the "resume" routine in in "infrun.c" and so
+ * will (almost) immediately do a resume.
+ *
+ * On the other hand, if we are VFORKING, which means
+ * that the child and the parent share a process for a
+ * while, we know that "resume" won't be resuming
+ * until the child EXEC event is seen. But we still
+ * don't want to continue, as the event is already
+ * there waiting.
+ */
+ update_thread_state_after_attach (pid, DONT_ATTACH_CONTINUE);
+ } /* STOP succeeded */
+
+ return pid;
+}
+
+int
+hppa_require_detach (int pid, int signal)
+{
+ int tt_status;
+
+ /* If signal is non-zero, we must pass the signal on to the active
+ thread prior to detaching. We do this by continuing the threads
+ with the signal.
+ */
+ if (signal != 0)
+ {
+ errno = 0;
+ threads_continue_all_with_signals (pid, signal);
+ }
+
+ errno = 0;
+ tt_status = call_ttrace (TT_PROC_DETACH,
+ pid,
+ TT_NIL,
+ TT_NIL,
+ TT_NIL);
+
+ errno = 0; /* Ignore any errors. */
+
+ /* process_state? */
+
+ return pid;
+}
+
+/* Given the starting address of a memory page, hash it to a bucket in
+ the memory page dictionary.
+ */
+static int
+get_dictionary_bucket_of_page (CORE_ADDR page_start)
+{
+ int hash;
+
+ hash = (page_start / memory_page_dictionary.page_size);
+ hash = hash % MEMORY_PAGE_DICTIONARY_BUCKET_COUNT;
+
+ return hash;
+}
+
+
+/* Given a memory page's starting address, get (i.e., find an existing
+ or create a new) dictionary entry for the page. The page will be
+ write-protected when this function returns, but may have a reference
+ count of 0 (if the page was newly-added to the dictionary).
+ */
+static memory_page_t *
+get_dictionary_entry_of_page (int pid, CORE_ADDR page_start)
+{
+ int bucket;
+ memory_page_t *page = NULL;
+ memory_page_t *previous_page = NULL;
+
+ /* We're going to be using the dictionary now, than-kew. */
+ require_memory_page_dictionary ();
+
+ /* Try to find an existing dictionary entry for this page. Hash
+ on the page's starting address.
+ */
+ bucket = get_dictionary_bucket_of_page (page_start);
+ page = &memory_page_dictionary.buckets[bucket];
+ while (page != NULL)
+ {
+ if (page->page_start == page_start)
+ break;
+ previous_page = page;
+ page = page->next;
+ }
+
+ /* Did we find a dictionary entry for this page? If not, then
+ add it to the dictionary now.
+ */
+ if (page == NULL)
+ {
+ /* Create a new entry. */
+ page = (memory_page_t *) xmalloc (sizeof (memory_page_t));
+ page->page_start = page_start;
+ page->reference_count = 0;
+ page->next = NULL;
+ page->previous = NULL;
+
+ /* We'll write-protect the page now, if that's allowed. */
+ page->original_permissions = write_protect_page (pid, page_start);
+
+ /* Add the new entry to the dictionary. */
+ page->previous = previous_page;
+ previous_page->next = page;
+
+ memory_page_dictionary.page_count++;
+ }
+
+ return page;
+}
+
+
+static void
+remove_dictionary_entry_of_page (int pid, memory_page_t *page)
+{
+ /* Restore the page's original permissions. */
+ unwrite_protect_page (pid, page->page_start, page->original_permissions);
+
+ /* Kick the page out of the dictionary. */
+ if (page->previous != NULL)
+ page->previous->next = page->next;
+ if (page->next != NULL)
+ page->next->previous = page->previous;
+
+ /* Just in case someone retains a handle to this after it's freed. */
+ page->page_start = (CORE_ADDR) 0;
+
+ memory_page_dictionary.page_count--;
+
+ xfree (page);
+}
+
+
+static void
+hppa_enable_syscall_events (int pid)
+{
+ int tt_status;
+ ttevent_t ttrace_events;
+
+ /* Get the set of events that are currently enabled. */
+ tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
+ pid,
+ (TTRACE_ARG_TYPE) & ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+
+ /* Add syscall events to that set. */
+ ttrace_events.tte_events |= TTEVT_SYSCALL_ENTRY;
+ ttrace_events.tte_events |= TTEVT_SYSCALL_RETURN;
+
+ tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
+ pid,
+ (TTRACE_ARG_TYPE) & ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+}
+
+
+static void
+hppa_disable_syscall_events (int pid)
+{
+ int tt_status;
+ ttevent_t ttrace_events;
+
+ /* Get the set of events that are currently enabled. */
+ tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
+ pid,
+ (TTRACE_ARG_TYPE) & ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+
+ /* Remove syscall events from that set. */
+ ttrace_events.tte_events &= ~TTEVT_SYSCALL_ENTRY;
+ ttrace_events.tte_events &= ~TTEVT_SYSCALL_RETURN;
+
+ tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
+ pid,
+ (TTRACE_ARG_TYPE) & ttrace_events,
+ (TTRACE_ARG_TYPE) sizeof (ttrace_events),
+ TT_NIL);
+ if (errno)
+ perror_with_name ("ttrace");
+}
+
+
+/* The address range beginning with START and ending with START+LEN-1
+ (inclusive) is to be watched via page-protection by a new watchpoint.
+ Set protection for all pages that overlap that range.
+
+ Note that our caller sets TYPE to:
+ 0 for a bp_hardware_watchpoint,
+ 1 for a bp_read_watchpoint,
+ 2 for a bp_access_watchpoint
+
+ (Yes, this is intentionally (though lord only knows why) different
+ from the TYPE that is passed to hppa_remove_hw_watchpoint.)
+ */
+int
+hppa_insert_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len, int type)
+{
+ CORE_ADDR page_start;
+ int dictionary_was_empty;
+ int page_size;
+ int page_id;
+ LONGEST range_size_in_pages;
+
+ if (type != 0)
+ error ("read or access hardware watchpoints not supported on HP-UX");
+
+ /* Examine all pages in the address range. */
+ require_memory_page_dictionary ();
+
+ dictionary_was_empty = (memory_page_dictionary.page_count == (LONGEST) 0);
+
+ page_size = memory_page_dictionary.page_size;
+ page_start = (start / page_size) * page_size;
+ range_size_in_pages = ((LONGEST) len + (LONGEST) page_size - 1) / (LONGEST) page_size;
+
+ for (page_id = 0; page_id < range_size_in_pages; page_id++, page_start += page_size)
+ {
+ memory_page_t *page;
+
+ /* This gets the page entered into the dictionary if it was
+ not already entered.
+ */
+ page = get_dictionary_entry_of_page (pid, page_start);
+ page->reference_count++;
+ }
+
+ /* Our implementation depends on seeing calls to kernel code, for the
+ following reason. Here we ask to be notified of syscalls.
+
+ When a protected page is accessed by user code, HP-UX raises a SIGBUS.
+ Fine.
+
+ But when kernel code accesses the page, it doesn't give a SIGBUS.
+ Rather, the system call that touched the page fails, with errno=EFAULT.
+ Not good for us.
+
+ We could accomodate this "feature" by asking to be notified of syscall
+ entries & exits; upon getting an entry event, disabling page-protections;
+ upon getting an exit event, reenabling page-protections and then checking
+ if any watchpoints triggered.
+
+ However, this turns out to be a real performance loser. syscalls are
+ usually a frequent occurrence. Having to unprotect-reprotect all watched
+ pages, and also to then read all watched memory locations and compare for
+ triggers, can be quite expensive.
+
+ Instead, we'll only ask to be notified of syscall exits. When we get
+ one, we'll check whether errno is set. If not, or if it's not EFAULT,
+ we can just continue the inferior.
+
+ If errno is set upon syscall exit to EFAULT, we must perform some fairly
+ hackish stuff to determine whether the failure really was due to a
+ page-protect trap on a watched location.
+ */
+ if (dictionary_was_empty)
+ hppa_enable_syscall_events (pid);
+
+ return 1;
+}
+
+
+/* The address range beginning with START and ending with START+LEN-1
+ (inclusive) was being watched via page-protection by a watchpoint
+ which has been removed. Remove protection for all pages that
+ overlap that range, which are not also being watched by other
+ watchpoints.
+ */
+int
+hppa_remove_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len,
+ enum bptype type)
+{
+ CORE_ADDR page_start;
+ int dictionary_is_empty;
+ int page_size;
+ int page_id;
+ LONGEST range_size_in_pages;
+
+ if (type != 0)
+ error ("read or access hardware watchpoints not supported on HP-UX");
+
+ /* Examine all pages in the address range. */
+ require_memory_page_dictionary ();
+
+ page_size = memory_page_dictionary.page_size;
+ page_start = (start / page_size) * page_size;
+ range_size_in_pages = ((LONGEST) len + (LONGEST) page_size - 1) / (LONGEST) page_size;
+
+ for (page_id = 0; page_id < range_size_in_pages; page_id++, page_start += page_size)
+ {
+ memory_page_t *page;
+
+ page = get_dictionary_entry_of_page (pid, page_start);
+ page->reference_count--;
+
+ /* Was this the last reference of this page? If so, then we
+ must scrub the entry from the dictionary, and also restore
+ the page's original permissions.
+ */
+ if (page->reference_count == 0)
+ remove_dictionary_entry_of_page (pid, page);
+ }
+
+ dictionary_is_empty = (memory_page_dictionary.page_count == (LONGEST) 0);
+
+ /* If write protections are currently disallowed, then that implies that
+ wait_for_inferior believes that the inferior is within a system call.
+ Since we want to see both syscall entry and return, it's clearly not
+ good to disable syscall events in this state!
+
+ ??rehrauer: Yeah, it'd be better if we had a specific flag that said,
+ "inferior is between syscall events now". Oh well.
+ */
+ if (dictionary_is_empty && memory_page_dictionary.page_protections_allowed)
+ hppa_disable_syscall_events (pid);
+
+ return 1;
+}
+
+
+/* Could we implement a watchpoint of this type via our available
+ hardware support?
+
+ This query does not consider whether a particular address range
+ could be so watched, but just whether support is generally available
+ for such things. See hppa_range_profitable_for_hw_watchpoint for a
+ query that answers whether a particular range should be watched via
+ hardware support.
+ */
+int
+hppa_can_use_hw_watchpoint (enum bptype type, int cnt, enum bptype ot)
+{
+ return (type == bp_hardware_watchpoint);
+}
+
+
+/* Assuming we could set a hardware watchpoint on this address, do
+ we think it would be profitable ("a good idea") to do so? If not,
+ we can always set a regular (aka single-step & test) watchpoint
+ on the address...
+ */
+int
+hppa_range_profitable_for_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len)
+{
+ int range_is_stack_based;
+ int range_is_accessible;
+ CORE_ADDR page_start;
+ int page_size;
+ int page;
+ LONGEST range_size_in_pages;
+
+ /* ??rehrauer: For now, say that all addresses are potentially
+ profitable. Possibly later we'll want to test the address
+ for "stackness"?
+ */
+ range_is_stack_based = 0;
+
+ /* If any page in the range is inaccessible, then we cannot
+ really use hardware watchpointing, even though our client
+ thinks we can. In that case, it's actually an error to
+ attempt to use hw watchpoints, so we'll tell our client
+ that the range is "unprofitable", and hope that they listen...
+ */
+ range_is_accessible = 1; /* Until proven otherwise. */
+
+ /* Examine all pages in the address range. */
+ errno = 0;
+ page_size = sysconf (_SC_PAGE_SIZE);
+
+ /* If we can't determine page size, we're hosed. Tell our
+ client it's unprofitable to use hw watchpoints for this
+ range.
+ */
+ if (errno || (page_size <= 0))
+ {
+ errno = 0;
+ return 0;
+ }
+
+ page_start = (start / page_size) * page_size;
+ range_size_in_pages = len / (LONGEST) page_size;
+
+ for (page = 0; page < range_size_in_pages; page++, page_start += page_size)
+ {
+ int tt_status;
+ int page_permissions;
+
+ /* Is this page accessible? */
+ errno = 0;
+ tt_status = call_ttrace (TT_PROC_GET_MPROTECT,
+ pid,
+ (TTRACE_ARG_TYPE) page_start,
+ TT_NIL,
+ (TTRACE_ARG_TYPE) & page_permissions);
+ if (errno || (tt_status < 0))
+ {
+ errno = 0;
+ range_is_accessible = 0;
+ break;
+ }
+
+ /* Yes, go for another... */
+ }
+
+ return (!range_is_stack_based && range_is_accessible);
+}
+
+
+char *
+hppa_pid_or_tid_to_str (ptid_t ptid)
+{
+ static char buf[100]; /* Static because address returned. */
+ pid_t id = PIDGET (ptid);
+
+ /* Does this appear to be a process? If so, print it that way. */
+ if (is_process_id (id))
+ return child_pid_to_str (ptid);
+
+ /* Else, print both the GDB thread number and the system thread id. */
+ sprintf (buf, "thread %d (", pid_to_thread_id (ptid));
+ strcat (buf, hppa_tid_to_str (ptid));
+ strcat (buf, ")\0");
+
+ return buf;
+}
+
+
+/* If the current pid is not the pid this module reported
+ * from "ptrace_wait" with the most recent event, then the
+ * user has switched threads.
+ *
+ * If the last reported event was a breakpoint, then return
+ * the old thread id, else return 0.
+ */
+pid_t
+hppa_switched_threads (pid_t gdb_pid)
+{
+ if (gdb_pid == old_gdb_pid)
+ {
+ /*
+ * Core gdb is working with the same pid that it
+ * was before we reported the last event. This
+ * is ok: e.g. we reported hitting a thread-specific
+ * breakpoint, but we were reporting the wrong
+ * thread, so the core just ignored the event.
+ *
+ * No thread switch has happened.
+ */
+ return (pid_t) 0;
+ }
+ else if (gdb_pid == reported_pid)
+ {
+ /*
+ * Core gdb is working with the pid we reported, so
+ * any continue or step will be able to figure out
+ * that it needs to step over any hit breakpoints
+ * without our (i.e. PREPARE_TO_PROCEED's) help.
+ */
+ return (pid_t) 0;
+ }
+ else if (!reported_bpt)
+ {
+ /*
+ * The core switched, but we didn't just report a
+ * breakpoint, so there's no just-hit breakpoint
+ * instruction at "reported_pid"'s PC, and thus there
+ * is no need to step over it.
+ */
+ return (pid_t) 0;
+ }
+ else
+ {
+ /* There's been a real switch, and we reported
+ * a hit breakpoint. Let "hppa_prepare_to_proceed"
+ * know, so it can see whether the breakpoint is
+ * still active.
+ */
+ return reported_pid;
+ }
+
+ /* Keep compiler happy with an obvious return at the end.
+ */
+ return (pid_t) 0;
+}
+
+void
+hppa_ensure_vforking_parent_remains_stopped (int pid)
+{
+ /* Nothing to do when using ttrace. Only the ptrace-based implementation
+ must do real work.
+ */
+}
+
+
+int
+hppa_resume_execd_vforking_child_to_get_parent_vfork (void)
+{
+ return 0; /* No, the parent vfork is available now. */
+}
+
+
+/* Write a register as a 64bit value. This may be necessary if the
+ native OS is too braindamaged to allow some (or all) registers to
+ be written in 32bit hunks such as hpux11 and the PC queue registers.
+
+ This is horribly gross and disgusting. */
+
+int
+ttrace_write_reg_64 (int gdb_tid, CORE_ADDR dest_addr, CORE_ADDR src_addr)
+{
+ pid_t pid;
+ lwpid_t tid;
+ int tt_status;
+
+ tid = map_from_gdb_tid (gdb_tid);
+ pid = get_pid_for (tid);
+
+ errno = 0;
+ tt_status = ttrace (TT_LWP_WUREGS,
+ pid,
+ tid,
+ (TTRACE_ARG_TYPE) dest_addr,
+ 8,
+ (TTRACE_ARG_TYPE) src_addr );
+
+#ifdef THREAD_DEBUG
+ if (errno)
+ {
+ /* Don't bother for a known benign error: if you ask for the
+ first thread state, but there is only one thread and it's
+ not stopped, ttrace complains.
+
+ We have this inside the #ifdef because our caller will do
+ this check for real. */
+ if( request != TT_PROC_GET_FIRST_LWP_STATE
+ || errno != EPROTO )
+ {
+ if( debug_on )
+ printf( "TT fail for %s, with pid %d, tid %d, status %d \n",
+ get_printable_name_of_ttrace_request (TT_LWP_WUREGS),
+ pid, tid, tt_status );
+ }
+ }
+#endif
+
+ return tt_status;
+}
+
+void
+_initialize_infttrace (void)
+{
+ /* Initialize the ttrace-based hardware watchpoint implementation. */
+ memory_page_dictionary.page_count = (LONGEST) - 1;
+ memory_page_dictionary.page_protections_allowed = 1;
+
+ errno = 0;
+ memory_page_dictionary.page_size = sysconf (_SC_PAGE_SIZE);
+
+ /* We do a lot of casts from pointers to TTRACE_ARG_TYPE; make sure
+ this is okay. */
+ if (sizeof (TTRACE_ARG_TYPE) < sizeof (void *))
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+ if (errno || (memory_page_dictionary.page_size <= 0))
+ perror_with_name ("sysconf");
+}
diff --git a/gdb/irix4-nat.c b/gdb/irix4-nat.c
new file mode 100644
index 00000000000..0f447767af2
--- /dev/null
+++ b/gdb/irix4-nat.c
@@ -0,0 +1,207 @@
+/* Native support for the SGI Iris running IRIX version 4, for GDB.
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1995, 1996, 1999, 2000,
+ 2001 Free Software Foundation, Inc.
+ Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
+ and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
+ Implemented for Irix 4.x by Garrett A. Wollman.
+
+ 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 "defs.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#include <sys/time.h>
+#include <sys/procfs.h>
+#include <setjmp.h> /* For JB_XXX. */
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* Size of elements in jmpbuf */
+
+#define JB_ELEMENT_SIZE 4
+
+typedef unsigned int greg_t; /* why isn't this defined? */
+
+static void fetch_core_registers (char *, unsigned int, int, CORE_ADDR);
+
+/*
+ * See the comment in m68k-tdep.c regarding the utility of these functions.
+ */
+
+void
+supply_gregset (gregset_t *gregsetp)
+{
+ register int regi;
+ register greg_t *regp = (greg_t *) (gregsetp->gp_regs);
+ static char zerobuf[MAX_REGISTER_RAW_SIZE] =
+ {0};
+
+ /* FIXME: somewhere, there should be a #define for the meaning
+ of this magic number 32; we should use that. */
+ for (regi = 0; regi < 32; regi++)
+ supply_register (regi, (char *) (regp + regi));
+
+ supply_register (PC_REGNUM, (char *) &(gregsetp->gp_pc));
+ supply_register (HI_REGNUM, (char *) &(gregsetp->gp_mdhi));
+ supply_register (LO_REGNUM, (char *) &(gregsetp->gp_mdlo));
+ supply_register (CAUSE_REGNUM, (char *) &(gregsetp->gp_cause));
+
+ /* Fill inaccessible registers with zero. */
+ supply_register (BADVADDR_REGNUM, zerobuf);
+}
+
+void
+fill_gregset (gregset_t *gregsetp, int regno)
+{
+ int regi;
+ register greg_t *regp = (greg_t *) (gregsetp->gp_regs);
+
+ /* same FIXME as above wrt 32 */
+ for (regi = 0; regi < 32; regi++)
+ if ((regno == -1) || (regno == regi))
+ *(regp + regi) = *(greg_t *) & registers[REGISTER_BYTE (regi)];
+
+ if ((regno == -1) || (regno == PC_REGNUM))
+ gregsetp->gp_pc = *(greg_t *) & registers[REGISTER_BYTE (PC_REGNUM)];
+
+ if ((regno == -1) || (regno == CAUSE_REGNUM))
+ gregsetp->gp_cause = *(greg_t *) & registers[REGISTER_BYTE (CAUSE_REGNUM)];
+
+ if ((regno == -1) || (regno == HI_REGNUM))
+ gregsetp->gp_mdhi = *(greg_t *) & registers[REGISTER_BYTE (HI_REGNUM)];
+
+ if ((regno == -1) || (regno == LO_REGNUM))
+ gregsetp->gp_mdlo = *(greg_t *) & registers[REGISTER_BYTE (LO_REGNUM)];
+}
+
+/*
+ * Now we do the same thing for floating-point registers.
+ * We don't bother to condition on FP0_REGNUM since any
+ * reasonable MIPS configuration has an R3010 in it.
+ *
+ * Again, see the comments in m68k-tdep.c.
+ */
+
+void
+supply_fpregset (fpregset_t *fpregsetp)
+{
+ register int regi;
+ static char zerobuf[MAX_REGISTER_RAW_SIZE] =
+ {0};
+
+ for (regi = 0; regi < 32; regi++)
+ supply_register (FP0_REGNUM + regi,
+ (char *) &fpregsetp->fp_r.fp_regs[regi]);
+
+ supply_register (FCRCS_REGNUM, (char *) &fpregsetp->fp_csr);
+
+ /* FIXME: how can we supply FCRIR_REGNUM? SGI doesn't tell us. */
+ supply_register (FCRIR_REGNUM, zerobuf);
+}
+
+void
+fill_fpregset (fpregset_t *fpregsetp, int regno)
+{
+ int regi;
+ char *from, *to;
+
+ for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
+ {
+ if ((regno == -1) || (regno == regi))
+ {
+ from = (char *) &registers[REGISTER_BYTE (regi)];
+ to = (char *) &(fpregsetp->fp_r.fp_regs[regi - FP0_REGNUM]);
+ memcpy (to, from, REGISTER_RAW_SIZE (regi));
+ }
+ }
+
+ if ((regno == -1) || (regno == FCRCS_REGNUM))
+ fpregsetp->fp_csr = *(unsigned *) &registers[REGISTER_BYTE (FCRCS_REGNUM)];
+}
+
+
+/* Figure out where the longjmp will land.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
+ This routine returns true on success. */
+
+int
+get_longjmp_target (CORE_ADDR *pc)
+{
+ char *buf;
+ CORE_ADDR jb_addr;
+
+ buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ jb_addr = read_register (A0_REGNUM);
+
+ if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ return 1;
+}
+
+/* Provide registers to GDB from a core file.
+
+ CORE_REG_SECT points to an array of bytes, which were obtained from
+ a core file which BFD thinks might contain register contents.
+ CORE_REG_SIZE is its size.
+
+ Normally, WHICH says which register set corelow suspects this is:
+ 0 --- the general-purpose register set
+ 2 --- the floating-point register set
+ However, for Irix 4, WHICH isn't used.
+
+ REG_ADDR is also unused. */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+ if (core_reg_size != REGISTER_BYTES)
+ {
+ warning ("wrong size gregset struct in core file");
+ return;
+ }
+
+ memcpy ((char *) registers, core_reg_sect, core_reg_size);
+}
+
+
+/* Register that we are able to handle irix4 core file formats.
+ FIXME: is this really bfd_target_unknown_flavour? */
+
+static struct core_fns irix4_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_irix4 (void)
+{
+ add_core_fns (&irix4_core_fns);
+}
diff --git a/gdb/irix5-nat.c b/gdb/irix5-nat.c
new file mode 100644
index 00000000000..459abe3879c
--- /dev/null
+++ b/gdb/irix5-nat.c
@@ -0,0 +1,1320 @@
+/* Native support for the SGI Iris running IRIX version 5, for GDB.
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
+ 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
+ and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
+ Implemented for Irix 4.x by Garrett A. Wollman.
+ Modified for Irix 5.x by Ian Lance Taylor.
+
+ 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 "defs.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "regcache.h"
+
+#include "gdb_string.h"
+#include <sys/time.h>
+#include <sys/procfs.h>
+#include <setjmp.h> /* For JB_XXX. */
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+static void fetch_core_registers (char *, unsigned int, int, CORE_ADDR);
+
+/* Size of elements in jmpbuf */
+
+#define JB_ELEMENT_SIZE 4
+
+/*
+ * See the comment in m68k-tdep.c regarding the utility of these functions.
+ *
+ * These definitions are from the MIPS SVR4 ABI, so they may work for
+ * any MIPS SVR4 target.
+ */
+
+void
+supply_gregset (gregset_t *gregsetp)
+{
+ register int regi;
+ register greg_t *regp = &(*gregsetp)[0];
+ int gregoff = sizeof (greg_t) - MIPS_REGSIZE;
+ static char zerobuf[MAX_REGISTER_RAW_SIZE] =
+ {0};
+
+ for (regi = 0; regi <= CTX_RA; regi++)
+ supply_register (regi, (char *) (regp + regi) + gregoff);
+
+ supply_register (PC_REGNUM, (char *) (regp + CTX_EPC) + gregoff);
+ supply_register (HI_REGNUM, (char *) (regp + CTX_MDHI) + gregoff);
+ supply_register (LO_REGNUM, (char *) (regp + CTX_MDLO) + gregoff);
+ supply_register (CAUSE_REGNUM, (char *) (regp + CTX_CAUSE) + gregoff);
+
+ /* Fill inaccessible registers with zero. */
+ supply_register (BADVADDR_REGNUM, zerobuf);
+}
+
+void
+fill_gregset (gregset_t *gregsetp, int regno)
+{
+ int regi;
+ register greg_t *regp = &(*gregsetp)[0];
+
+ /* Under Irix6, if GDB is built with N32 ABI and is debugging an O32
+ executable, we have to sign extend the registers to 64 bits before
+ filling in the gregset structure. */
+
+ for (regi = 0; regi <= CTX_RA; regi++)
+ if ((regno == -1) || (regno == regi))
+ *(regp + regi) =
+ extract_signed_integer (&registers[REGISTER_BYTE (regi)],
+ REGISTER_RAW_SIZE (regi));
+
+ if ((regno == -1) || (regno == PC_REGNUM))
+ *(regp + CTX_EPC) =
+ extract_signed_integer (&registers[REGISTER_BYTE (PC_REGNUM)],
+ REGISTER_RAW_SIZE (PC_REGNUM));
+
+ if ((regno == -1) || (regno == CAUSE_REGNUM))
+ *(regp + CTX_CAUSE) =
+ extract_signed_integer (&registers[REGISTER_BYTE (CAUSE_REGNUM)],
+ REGISTER_RAW_SIZE (CAUSE_REGNUM));
+
+ if ((regno == -1) || (regno == HI_REGNUM))
+ *(regp + CTX_MDHI) =
+ extract_signed_integer (&registers[REGISTER_BYTE (HI_REGNUM)],
+ REGISTER_RAW_SIZE (HI_REGNUM));
+
+ if ((regno == -1) || (regno == LO_REGNUM))
+ *(regp + CTX_MDLO) =
+ extract_signed_integer (&registers[REGISTER_BYTE (LO_REGNUM)],
+ REGISTER_RAW_SIZE (LO_REGNUM));
+}
+
+/*
+ * Now we do the same thing for floating-point registers.
+ * We don't bother to condition on FP0_REGNUM since any
+ * reasonable MIPS configuration has an R3010 in it.
+ *
+ * Again, see the comments in m68k-tdep.c.
+ */
+
+void
+supply_fpregset (fpregset_t *fpregsetp)
+{
+ register int regi;
+ static char zerobuf[MAX_REGISTER_RAW_SIZE] =
+ {0};
+
+ /* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs. */
+
+ for (regi = 0; regi < 32; regi++)
+ supply_register (FP0_REGNUM + regi,
+ (char *) &fpregsetp->fp_r.fp_regs[regi]);
+
+ supply_register (FCRCS_REGNUM, (char *) &fpregsetp->fp_csr);
+
+ /* FIXME: how can we supply FCRIR_REGNUM? SGI doesn't tell us. */
+ supply_register (FCRIR_REGNUM, zerobuf);
+}
+
+void
+fill_fpregset (fpregset_t *fpregsetp, int regno)
+{
+ int regi;
+ char *from, *to;
+
+ /* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs. */
+
+ for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
+ {
+ if ((regno == -1) || (regno == regi))
+ {
+ from = (char *) &registers[REGISTER_BYTE (regi)];
+ to = (char *) &(fpregsetp->fp_r.fp_regs[regi - FP0_REGNUM]);
+ memcpy (to, from, REGISTER_RAW_SIZE (regi));
+ }
+ }
+
+ if ((regno == -1) || (regno == FCRCS_REGNUM))
+ fpregsetp->fp_csr = *(unsigned *) &registers[REGISTER_BYTE (FCRCS_REGNUM)];
+}
+
+
+/* Figure out where the longjmp will land.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
+ This routine returns true on success. */
+
+int
+get_longjmp_target (CORE_ADDR *pc)
+{
+ char *buf;
+ CORE_ADDR jb_addr;
+
+ buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ jb_addr = read_register (A0_REGNUM);
+
+ if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ return 1;
+}
+
+/* Provide registers to GDB from a core file.
+
+ CORE_REG_SECT points to an array of bytes, which were obtained from
+ a core file which BFD thinks might contain register contents.
+ CORE_REG_SIZE is its size.
+
+ Normally, WHICH says which register set corelow suspects this is:
+ 0 --- the general-purpose register set
+ 2 --- the floating-point register set
+ However, for Irix 5, WHICH isn't used.
+
+ REG_ADDR is also unused. */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+ if (core_reg_size == REGISTER_BYTES)
+ {
+ memcpy ((char *) registers, core_reg_sect, core_reg_size);
+ }
+ else if (MIPS_REGSIZE == 4 &&
+ core_reg_size == (2 * MIPS_REGSIZE) * NUM_REGS)
+ {
+ /* This is a core file from a N32 executable, 64 bits are saved
+ for all registers. */
+ char *srcp = core_reg_sect;
+ char *dstp = registers;
+ int regno;
+
+ for (regno = 0; regno < NUM_REGS; regno++)
+ {
+ if (regno >= FP0_REGNUM && regno < (FP0_REGNUM + 32))
+ {
+ /* FIXME, this is wrong, N32 has 64 bit FP regs, but GDB
+ currently assumes that they are 32 bit. */
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ if (REGISTER_RAW_SIZE (regno) == 4)
+ {
+ /* copying 4 bytes from eight bytes?
+ I don't see how this can be right... */
+ srcp += 4;
+ }
+ else
+ {
+ /* copy all 8 bytes (sizeof(double)) */
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ }
+ }
+ else
+ {
+ srcp += 4;
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ *dstp++ = *srcp++;
+ }
+ }
+ }
+ else
+ {
+ warning ("wrong size gregset struct in core file");
+ return;
+ }
+
+ registers_fetched ();
+}
+
+/* Irix 5 uses what appears to be a unique form of shared library
+ support. This is a copy of solib.c modified for Irix 5. */
+/* FIXME: Most of this code could be merged with osfsolib.c and solib.c
+ by using next_link_map_member and xfer_link_map_member in solib.c. */
+
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/param.h>
+#include <fcntl.h>
+
+/* <obj.h> includes <sym.h> and <symconst.h>, which causes conflicts
+ with our versions of those files included by tm-mips.h. Prevent
+ <obj.h> from including them with some appropriate defines. */
+#define __SYM_H__
+#define __SYMCONST_H__
+#include <obj.h>
+#ifdef HAVE_OBJLIST_H
+#include <objlist.h>
+#endif
+
+#ifdef NEW_OBJ_INFO_MAGIC
+#define HANDLE_NEW_OBJ_LIST
+#endif
+
+#include "symtab.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "command.h"
+#include "frame.h"
+#include "gdb_regex.h"
+#include "inferior.h"
+#include "language.h"
+#include "gdbcmd.h"
+
+/* The symbol which starts off the list of shared libraries. */
+#define DEBUG_BASE "__rld_obj_head"
+
+/* Irix 6.x introduces a new variant of object lists.
+ To be able to debug O32 executables under Irix 6, we have to handle both
+ variants. */
+
+typedef enum
+{
+ OBJ_LIST_OLD, /* Pre Irix 6.x object list. */
+ OBJ_LIST_32, /* 32 Bit Elf32_Obj_Info. */
+ OBJ_LIST_64 /* 64 Bit Elf64_Obj_Info, FIXME not yet implemented. */
+}
+obj_list_variant;
+
+/* Define our own link_map structure.
+ This will help to share code with osfsolib.c and solib.c. */
+
+struct link_map
+ {
+ obj_list_variant l_variant; /* which variant of object list */
+ CORE_ADDR l_lladdr; /* addr in inferior list was read from */
+ CORE_ADDR l_next; /* address of next object list entry */
+ };
+
+/* Irix 5 shared objects are pre-linked to particular addresses
+ although the dynamic linker may have to relocate them if the
+ address ranges of the libraries used by the main program clash.
+ The offset is the difference between the address where the object
+ is mapped and the binding address of the shared library. */
+#define LM_OFFSET(so) ((so) -> offset)
+/* Loaded address of shared library. */
+#define LM_ADDR(so) ((so) -> lmstart)
+
+char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */
+
+struct so_list
+ {
+ struct so_list *next; /* next structure in linked list */
+ struct link_map lm;
+ CORE_ADDR offset; /* prelink to load address offset */
+ char *so_name; /* shared object lib name */
+ CORE_ADDR lmstart; /* lower addr bound of mapped object */
+ CORE_ADDR lmend; /* upper addr bound of mapped object */
+ char symbols_loaded; /* flag: symbols read in yet? */
+ char from_tty; /* flag: print msgs? */
+ struct objfile *objfile; /* objfile for loaded lib */
+ struct section_table *sections;
+ struct section_table *sections_end;
+ struct section_table *textsection;
+ bfd *abfd;
+ };
+
+static struct so_list *so_list_head; /* List of known shared objects */
+static CORE_ADDR debug_base; /* Base of dynamic linker structures */
+static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */
+
+/* Local function prototypes */
+
+static void sharedlibrary_command (char *, int);
+
+static int enable_break (void);
+
+static int disable_break (void);
+
+static void info_sharedlibrary_command (char *, int);
+
+static int symbol_add_stub (void *);
+
+static struct so_list *find_solib (struct so_list *);
+
+static struct link_map *first_link_map_member (void);
+
+static struct link_map *next_link_map_member (struct so_list *);
+
+static void xfer_link_map_member (struct so_list *, struct link_map *);
+
+static CORE_ADDR locate_base (void);
+
+static int solib_map_sections (void *);
+
+/*
+
+ LOCAL FUNCTION
+
+ solib_map_sections -- open bfd and build sections for shared lib
+
+ SYNOPSIS
+
+ static int solib_map_sections (struct so_list *so)
+
+ DESCRIPTION
+
+ Given a pointer to one of the shared objects in our list
+ of mapped objects, use the recorded name to open a bfd
+ descriptor for the object, build a section table, and then
+ relocate all the section addresses by the base address at
+ which the shared object was mapped.
+
+ FIXMES
+
+ In most (all?) cases the shared object file name recorded in the
+ dynamic linkage tables will be a fully qualified pathname. For
+ cases where it isn't, do we really mimic the systems search
+ mechanism correctly in the below code (particularly the tilde
+ expansion stuff?).
+ */
+
+static int
+solib_map_sections (void *arg)
+{
+ struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
+ char *filename;
+ char *scratch_pathname;
+ int scratch_chan;
+ struct section_table *p;
+ struct cleanup *old_chain;
+ bfd *abfd;
+
+ filename = tilde_expand (so->so_name);
+ old_chain = make_cleanup (xfree, filename);
+
+ scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
+ &scratch_pathname);
+ if (scratch_chan < 0)
+ {
+ scratch_chan = openp (getenv ("LD_LIBRARY_PATH"), 1, filename,
+ O_RDONLY, 0, &scratch_pathname);
+ }
+ if (scratch_chan < 0)
+ {
+ perror_with_name (filename);
+ }
+ /* Leave scratch_pathname allocated. abfd->name will point to it. */
+
+ abfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan);
+ if (!abfd)
+ {
+ close (scratch_chan);
+ error ("Could not open `%s' as an executable file: %s",
+ scratch_pathname, bfd_errmsg (bfd_get_error ()));
+ }
+ /* Leave bfd open, core_xfer_memory and "info files" need it. */
+ so->abfd = abfd;
+ abfd->cacheable = 1;
+
+ if (!bfd_check_format (abfd, bfd_object))
+ {
+ error ("\"%s\": not in executable format: %s.",
+ scratch_pathname, bfd_errmsg (bfd_get_error ()));
+ }
+ if (build_section_table (abfd, &so->sections, &so->sections_end))
+ {
+ error ("Can't find the file sections in `%s': %s",
+ bfd_get_filename (exec_bfd), bfd_errmsg (bfd_get_error ()));
+ }
+
+ for (p = so->sections; p < so->sections_end; p++)
+ {
+ /* Relocate the section binding addresses as recorded in the shared
+ object's file by the offset to get the address to which the
+ object was actually mapped. */
+ p->addr += LM_OFFSET (so);
+ p->endaddr += LM_OFFSET (so);
+ so->lmend = (CORE_ADDR) max (p->endaddr, so->lmend);
+ if (STREQ (p->the_bfd_section->name, ".text"))
+ {
+ so->textsection = p;
+ }
+ }
+
+ /* Free the file names, close the file now. */
+ do_cleanups (old_chain);
+
+ /* must be non-zero */
+ return (1);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ locate_base -- locate the base address of dynamic linker structs
+
+ SYNOPSIS
+
+ CORE_ADDR locate_base (void)
+
+ DESCRIPTION
+
+ For both the SunOS and SVR4 shared library implementations, if the
+ inferior executable has been linked dynamically, there is a single
+ address somewhere in the inferior's data space which is the key to
+ locating all of the dynamic linker's runtime structures. This
+ address is the value of the symbol defined by the macro DEBUG_BASE.
+ The job of this function is to find and return that address, or to
+ return 0 if there is no such address (the executable is statically
+ linked for example).
+
+ For SunOS, the job is almost trivial, since the dynamic linker and
+ all of it's structures are statically linked to the executable at
+ link time. Thus the symbol for the address we are looking for has
+ already been added to the minimal symbol table for the executable's
+ objfile at the time the symbol file's symbols were read, and all we
+ have to do is look it up there. Note that we explicitly do NOT want
+ to find the copies in the shared library.
+
+ The SVR4 version is much more complicated because the dynamic linker
+ and it's structures are located in the shared C library, which gets
+ run as the executable's "interpreter" by the kernel. We have to go
+ to a lot more work to discover the address of DEBUG_BASE. Because
+ of this complexity, we cache the value we find and return that value
+ on subsequent invocations. Note there is no copy in the executable
+ symbol tables.
+
+ Irix 5 is basically like SunOS.
+
+ Note that we can assume nothing about the process state at the time
+ we need to find this address. We may be stopped on the first instruc-
+ tion of the interpreter (C shared library), the first instruction of
+ the executable itself, or somewhere else entirely (if we attached
+ to the process for example).
+
+ */
+
+static CORE_ADDR
+locate_base (void)
+{
+ struct minimal_symbol *msymbol;
+ CORE_ADDR address = 0;
+
+ msymbol = lookup_minimal_symbol (DEBUG_BASE, NULL, symfile_objfile);
+ if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
+ {
+ address = SYMBOL_VALUE_ADDRESS (msymbol);
+ }
+ return (address);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ first_link_map_member -- locate first member in dynamic linker's map
+
+ SYNOPSIS
+
+ static struct link_map *first_link_map_member (void)
+
+ DESCRIPTION
+
+ Read in a copy of the first member in the inferior's dynamic
+ link map from the inferior's dynamic linker structures, and return
+ a pointer to the link map descriptor.
+ */
+
+static struct link_map *
+first_link_map_member (void)
+{
+ struct obj_list *listp;
+ struct obj_list list_old;
+ struct link_map *lm;
+ static struct link_map first_lm;
+ CORE_ADDR lladdr;
+ CORE_ADDR next_lladdr;
+
+ /* We have not already read in the dynamic linking structures
+ from the inferior, lookup the address of the base structure. */
+ debug_base = locate_base ();
+ if (debug_base == 0)
+ return NULL;
+
+ /* Get address of first list entry. */
+ read_memory (debug_base, (char *) &listp, sizeof (struct obj_list *));
+
+ if (listp == NULL)
+ return NULL;
+
+ /* Get first list entry. */
+ /* The MIPS Sign extends addresses. */
+ lladdr = host_pointer_to_address (listp);
+ read_memory (lladdr, (char *) &list_old, sizeof (struct obj_list));
+
+ /* The first entry in the list is the object file we are debugging,
+ so skip it. */
+ next_lladdr = host_pointer_to_address (list_old.next);
+
+#ifdef HANDLE_NEW_OBJ_LIST
+ if (list_old.data == NEW_OBJ_INFO_MAGIC)
+ {
+ Elf32_Obj_Info list_32;
+
+ read_memory (lladdr, (char *) &list_32, sizeof (Elf32_Obj_Info));
+ if (list_32.oi_size != sizeof (Elf32_Obj_Info))
+ return NULL;
+ next_lladdr = (CORE_ADDR) list_32.oi_next;
+ }
+#endif
+
+ if (next_lladdr == 0)
+ return NULL;
+
+ first_lm.l_lladdr = next_lladdr;
+ lm = &first_lm;
+ return lm;
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ next_link_map_member -- locate next member in dynamic linker's map
+
+ SYNOPSIS
+
+ static struct link_map *next_link_map_member (so_list_ptr)
+
+ DESCRIPTION
+
+ Read in a copy of the next member in the inferior's dynamic
+ link map from the inferior's dynamic linker structures, and return
+ a pointer to the link map descriptor.
+ */
+
+static struct link_map *
+next_link_map_member (struct so_list *so_list_ptr)
+{
+ struct link_map *lm = &so_list_ptr->lm;
+ CORE_ADDR next_lladdr = lm->l_next;
+ static struct link_map next_lm;
+
+ if (next_lladdr == 0)
+ {
+ /* We have hit the end of the list, so check to see if any were
+ added, but be quiet if we can't read from the target any more. */
+ int status = 0;
+
+ if (lm->l_variant == OBJ_LIST_OLD)
+ {
+ struct obj_list list_old;
+
+ status = target_read_memory (lm->l_lladdr,
+ (char *) &list_old,
+ sizeof (struct obj_list));
+ next_lladdr = host_pointer_to_address (list_old.next);
+ }
+#ifdef HANDLE_NEW_OBJ_LIST
+ else if (lm->l_variant == OBJ_LIST_32)
+ {
+ Elf32_Obj_Info list_32;
+ status = target_read_memory (lm->l_lladdr,
+ (char *) &list_32,
+ sizeof (Elf32_Obj_Info));
+ next_lladdr = (CORE_ADDR) list_32.oi_next;
+ }
+#endif
+
+ if (status != 0 || next_lladdr == 0)
+ return NULL;
+ }
+
+ next_lm.l_lladdr = next_lladdr;
+ lm = &next_lm;
+ return lm;
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ xfer_link_map_member -- set local variables from dynamic linker's map
+
+ SYNOPSIS
+
+ static void xfer_link_map_member (so_list_ptr, lm)
+
+ DESCRIPTION
+
+ Read in a copy of the requested member in the inferior's dynamic
+ link map from the inferior's dynamic linker structures, and fill
+ in the necessary so_list_ptr elements.
+ */
+
+static void
+xfer_link_map_member (struct so_list *so_list_ptr, struct link_map *lm)
+{
+ struct obj_list list_old;
+ CORE_ADDR lladdr = lm->l_lladdr;
+ struct link_map *new_lm = &so_list_ptr->lm;
+ int errcode;
+
+ read_memory (lladdr, (char *) &list_old, sizeof (struct obj_list));
+
+ new_lm->l_variant = OBJ_LIST_OLD;
+ new_lm->l_lladdr = lladdr;
+ new_lm->l_next = host_pointer_to_address (list_old.next);
+
+#ifdef HANDLE_NEW_OBJ_LIST
+ if (list_old.data == NEW_OBJ_INFO_MAGIC)
+ {
+ Elf32_Obj_Info list_32;
+
+ read_memory (lladdr, (char *) &list_32, sizeof (Elf32_Obj_Info));
+ if (list_32.oi_size != sizeof (Elf32_Obj_Info))
+ return;
+ new_lm->l_variant = OBJ_LIST_32;
+ new_lm->l_next = (CORE_ADDR) list_32.oi_next;
+
+ target_read_string ((CORE_ADDR) list_32.oi_pathname,
+ &so_list_ptr->so_name,
+ list_32.oi_pathname_len + 1, &errcode);
+ if (errcode != 0)
+ memory_error (errcode, (CORE_ADDR) list_32.oi_pathname);
+
+ LM_ADDR (so_list_ptr) = (CORE_ADDR) list_32.oi_ehdr;
+ LM_OFFSET (so_list_ptr) =
+ (CORE_ADDR) list_32.oi_ehdr - (CORE_ADDR) list_32.oi_orig_ehdr;
+ }
+ else
+#endif
+ {
+#if defined (_MIPS_SIM_NABI32) && _MIPS_SIM == _MIPS_SIM_NABI32
+ /* If we are compiling GDB under N32 ABI, the alignments in
+ the obj struct are different from the O32 ABI and we will get
+ wrong values when accessing the struct.
+ As a workaround we use fixed values which are good for
+ Irix 6.2. */
+ char buf[432];
+
+ read_memory ((CORE_ADDR) list_old.data, buf, sizeof (buf));
+
+ target_read_string (extract_address (&buf[236], 4),
+ &so_list_ptr->so_name,
+ INT_MAX, &errcode);
+ if (errcode != 0)
+ memory_error (errcode, extract_address (&buf[236], 4));
+
+ LM_ADDR (so_list_ptr) = extract_address (&buf[196], 4);
+ LM_OFFSET (so_list_ptr) =
+ extract_address (&buf[196], 4) - extract_address (&buf[248], 4);
+#else
+ struct obj obj_old;
+
+ read_memory ((CORE_ADDR) list_old.data, (char *) &obj_old,
+ sizeof (struct obj));
+
+ target_read_string ((CORE_ADDR) obj_old.o_path,
+ &so_list_ptr->so_name,
+ INT_MAX, &errcode);
+ if (errcode != 0)
+ memory_error (errcode, (CORE_ADDR) obj_old.o_path);
+
+ LM_ADDR (so_list_ptr) = (CORE_ADDR) obj_old.o_praw;
+ LM_OFFSET (so_list_ptr) =
+ (CORE_ADDR) obj_old.o_praw - obj_old.o_base_address;
+#endif
+ }
+
+ catch_errors (solib_map_sections, (char *) so_list_ptr,
+ "Error while mapping shared library sections:\n",
+ RETURN_MASK_ALL);
+}
+
+
+/*
+
+ LOCAL FUNCTION
+
+ find_solib -- step through list of shared objects
+
+ SYNOPSIS
+
+ struct so_list *find_solib (struct so_list *so_list_ptr)
+
+ DESCRIPTION
+
+ This module contains the routine which finds the names of any
+ loaded "images" in the current process. The argument in must be
+ NULL on the first call, and then the returned value must be passed
+ in on subsequent calls. This provides the capability to "step" down
+ the list of loaded objects. On the last object, a NULL value is
+ returned.
+ */
+
+static struct so_list *
+find_solib (struct so_list *so_list_ptr)
+{
+ struct so_list *so_list_next = NULL;
+ struct link_map *lm = NULL;
+ struct so_list *new;
+
+ if (so_list_ptr == NULL)
+ {
+ /* We are setting up for a new scan through the loaded images. */
+ if ((so_list_next = so_list_head) == NULL)
+ {
+ /* Find the first link map list member. */
+ lm = first_link_map_member ();
+ }
+ }
+ else
+ {
+ /* We have been called before, and are in the process of walking
+ the shared library list. Advance to the next shared object. */
+ lm = next_link_map_member (so_list_ptr);
+ so_list_next = so_list_ptr->next;
+ }
+ if ((so_list_next == NULL) && (lm != NULL))
+ {
+ new = (struct so_list *) xmalloc (sizeof (struct so_list));
+ memset ((char *) new, 0, sizeof (struct so_list));
+ /* Add the new node as the next node in the list, or as the root
+ node if this is the first one. */
+ if (so_list_ptr != NULL)
+ {
+ so_list_ptr->next = new;
+ }
+ else
+ {
+ so_list_head = new;
+ }
+ so_list_next = new;
+ xfer_link_map_member (new, lm);
+ }
+ return (so_list_next);
+}
+
+/* A small stub to get us past the arg-passing pinhole of catch_errors. */
+
+static int
+symbol_add_stub (void *arg)
+{
+ register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
+ CORE_ADDR text_addr = 0;
+ struct section_addr_info section_addrs;
+
+ memset (&section_addrs, 0, sizeof (section_addrs));
+ if (so->textsection)
+ text_addr = so->textsection->addr;
+ else if (so->abfd != NULL)
+ {
+ asection *lowest_sect;
+
+ /* If we didn't find a mapped non zero sized .text section, set up
+ text_addr so that the relocation in symbol_file_add does no harm. */
+
+ lowest_sect = bfd_get_section_by_name (so->abfd, ".text");
+ if (lowest_sect == NULL)
+ bfd_map_over_sections (so->abfd, find_lowest_section,
+ (PTR) &lowest_sect);
+ if (lowest_sect)
+ text_addr = bfd_section_vma (so->abfd, lowest_sect) + LM_OFFSET (so);
+ }
+
+
+ section_addrs.other[0].name = ".text";
+ section_addrs.other[0].addr = text_addr;
+ so->objfile = symbol_file_add (so->so_name, so->from_tty,
+ &section_addrs, 0, 0);
+ /* must be non-zero */
+ return (1);
+}
+
+/*
+
+ GLOBAL FUNCTION
+
+ solib_add -- add a shared library file to the symtab and section list
+
+ SYNOPSIS
+
+ void solib_add (char *arg_string, int from_tty,
+ struct target_ops *target, int readsyms)
+
+ DESCRIPTION
+
+ */
+
+void
+solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms)
+{
+ register struct so_list *so = NULL; /* link map state variable */
+
+ /* Last shared library that we read. */
+ struct so_list *so_last = NULL;
+
+ char *re_err;
+ int count;
+ int old;
+
+ if (!readsyms)
+ return;
+
+ if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)
+ {
+ error ("Invalid regexp: %s", re_err);
+ }
+
+ /* Add the shared library sections to the section table of the
+ specified target, if any. */
+ if (target)
+ {
+ /* Count how many new section_table entries there are. */
+ so = NULL;
+ count = 0;
+ while ((so = find_solib (so)) != NULL)
+ {
+ if (so->so_name[0])
+ {
+ count += so->sections_end - so->sections;
+ }
+ }
+
+ if (count)
+ {
+ old = target_resize_to_sections (target, count);
+
+ /* Add these section table entries to the target's table. */
+ while ((so = find_solib (so)) != NULL)
+ {
+ if (so->so_name[0])
+ {
+ count = so->sections_end - so->sections;
+ memcpy ((char *) (target->to_sections + old),
+ so->sections,
+ (sizeof (struct section_table)) * count);
+ old += count;
+ }
+ }
+ }
+ }
+
+ /* Now add the symbol files. */
+ while ((so = find_solib (so)) != NULL)
+ {
+ if (so->so_name[0] && re_exec (so->so_name))
+ {
+ so->from_tty = from_tty;
+ if (so->symbols_loaded)
+ {
+ if (from_tty)
+ {
+ printf_unfiltered ("Symbols already loaded for %s\n", so->so_name);
+ }
+ }
+ else if (catch_errors
+ (symbol_add_stub, (char *) so,
+ "Error while reading shared library symbols:\n",
+ RETURN_MASK_ALL))
+ {
+ so_last = so;
+ so->symbols_loaded = 1;
+ }
+ }
+ }
+
+ /* Getting new symbols may change our opinion about what is
+ frameless. */
+ if (so_last)
+ reinit_frame_cache ();
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ info_sharedlibrary_command -- code for "info sharedlibrary"
+
+ SYNOPSIS
+
+ static void info_sharedlibrary_command ()
+
+ DESCRIPTION
+
+ Walk through the shared library list and print information
+ about each attached library.
+ */
+
+static void
+info_sharedlibrary_command (char *ignore, int from_tty)
+{
+ register struct so_list *so = NULL; /* link map state variable */
+ int header_done = 0;
+
+ if (exec_bfd == NULL)
+ {
+ printf_unfiltered ("No executable file.\n");
+ return;
+ }
+ while ((so = find_solib (so)) != NULL)
+ {
+ if (so->so_name[0])
+ {
+ if (!header_done)
+ {
+ printf_unfiltered ("%-12s%-12s%-12s%s\n", "From", "To", "Syms Read",
+ "Shared Object Library");
+ header_done++;
+ }
+ printf_unfiltered ("%-12s",
+ local_hex_string_custom ((unsigned long) LM_ADDR (so),
+ "08l"));
+ printf_unfiltered ("%-12s",
+ local_hex_string_custom ((unsigned long) so->lmend,
+ "08l"));
+ printf_unfiltered ("%-12s", so->symbols_loaded ? "Yes" : "No");
+ printf_unfiltered ("%s\n", so->so_name);
+ }
+ }
+ if (so_list_head == NULL)
+ {
+ printf_unfiltered ("No shared libraries loaded at this time.\n");
+ }
+}
+
+/*
+
+ GLOBAL FUNCTION
+
+ solib_address -- check to see if an address is in a shared lib
+
+ SYNOPSIS
+
+ char *solib_address (CORE_ADDR address)
+
+ DESCRIPTION
+
+ Provides a hook for other gdb routines to discover whether or
+ not a particular address is within the mapped address space of
+ a shared library. Any address between the base mapping address
+ and the first address beyond the end of the last mapping, is
+ considered to be within the shared library address space, for
+ our purposes.
+
+ For example, this routine is called at one point to disable
+ breakpoints which are in shared libraries that are not currently
+ mapped in.
+ */
+
+char *
+solib_address (CORE_ADDR address)
+{
+ register struct so_list *so = 0; /* link map state variable */
+
+ while ((so = find_solib (so)) != NULL)
+ {
+ if (so->so_name[0])
+ {
+ if ((address >= (CORE_ADDR) LM_ADDR (so)) &&
+ (address < (CORE_ADDR) so->lmend))
+ return (so->so_name);
+ }
+ }
+ return (0);
+}
+
+/* Called by free_all_symtabs */
+
+void
+clear_solib (void)
+{
+ struct so_list *next;
+ char *bfd_filename;
+
+ disable_breakpoints_in_shlibs (1);
+
+ while (so_list_head)
+ {
+ if (so_list_head->sections)
+ {
+ xfree (so_list_head->sections);
+ }
+ if (so_list_head->abfd)
+ {
+ remove_target_sections (so_list_head->abfd);
+ bfd_filename = bfd_get_filename (so_list_head->abfd);
+ if (!bfd_close (so_list_head->abfd))
+ warning ("cannot close \"%s\": %s",
+ bfd_filename, bfd_errmsg (bfd_get_error ()));
+ }
+ else
+ /* This happens for the executable on SVR4. */
+ bfd_filename = NULL;
+
+ next = so_list_head->next;
+ if (bfd_filename)
+ xfree (bfd_filename);
+ xfree (so_list_head->so_name);
+ xfree (so_list_head);
+ so_list_head = next;
+ }
+ debug_base = 0;
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ disable_break -- remove the "mapping changed" breakpoint
+
+ SYNOPSIS
+
+ static int disable_break ()
+
+ DESCRIPTION
+
+ Removes the breakpoint that gets hit when the dynamic linker
+ completes a mapping change.
+
+ */
+
+static int
+disable_break (void)
+{
+ int status = 1;
+
+
+ /* Note that breakpoint address and original contents are in our address
+ space, so we just need to write the original contents back. */
+
+ if (memory_remove_breakpoint (breakpoint_addr, shadow_contents) != 0)
+ {
+ status = 0;
+ }
+
+ /* For the SVR4 version, we always know the breakpoint address. For the
+ SunOS version we don't know it until the above code is executed.
+ Grumble if we are stopped anywhere besides the breakpoint address. */
+
+ if (stop_pc != breakpoint_addr)
+ {
+ warning ("stopped at unknown breakpoint while handling shared libraries");
+ }
+
+ return (status);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ enable_break -- arrange for dynamic linker to hit breakpoint
+
+ SYNOPSIS
+
+ int enable_break (void)
+
+ DESCRIPTION
+
+ This functions inserts a breakpoint at the entry point of the
+ main executable, where all shared libraries are mapped in.
+ */
+
+static int
+enable_break (void)
+{
+ if (symfile_objfile != NULL
+ && target_insert_breakpoint (symfile_objfile->ei.entry_point,
+ shadow_contents) == 0)
+ {
+ breakpoint_addr = symfile_objfile->ei.entry_point;
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+
+ GLOBAL FUNCTION
+
+ solib_create_inferior_hook -- shared library startup support
+
+ SYNOPSIS
+
+ void solib_create_inferior_hook()
+
+ DESCRIPTION
+
+ When gdb starts up the inferior, it nurses it along (through the
+ shell) until it is ready to execute it's first instruction. At this
+ point, this function gets called via expansion of the macro
+ SOLIB_CREATE_INFERIOR_HOOK.
+
+ For SunOS executables, this first instruction is typically the
+ one at "_start", or a similar text label, regardless of whether
+ the executable is statically or dynamically linked. The runtime
+ startup code takes care of dynamically linking in any shared
+ libraries, once gdb allows the inferior to continue.
+
+ For SVR4 executables, this first instruction is either the first
+ instruction in the dynamic linker (for dynamically linked
+ executables) or the instruction at "start" for statically linked
+ executables. For dynamically linked executables, the system
+ first exec's /lib/libc.so.N, which contains the dynamic linker,
+ and starts it running. The dynamic linker maps in any needed
+ shared libraries, maps in the actual user executable, and then
+ jumps to "start" in the user executable.
+
+ For both SunOS shared libraries, and SVR4 shared libraries, we
+ can arrange to cooperate with the dynamic linker to discover the
+ names of shared libraries that are dynamically linked, and the
+ base addresses to which they are linked.
+
+ This function is responsible for discovering those names and
+ addresses, and saving sufficient information about them to allow
+ their symbols to be read at a later time.
+
+ FIXME
+
+ Between enable_break() and disable_break(), this code does not
+ properly handle hitting breakpoints which the user might have
+ set in the startup code or in the dynamic linker itself. Proper
+ handling will probably have to wait until the implementation is
+ changed to use the "breakpoint handler function" method.
+
+ Also, what if child has exit()ed? Must exit loop somehow.
+ */
+
+void
+solib_create_inferior_hook (void)
+{
+ if (!enable_break ())
+ {
+ warning ("shared library handler failed to enable breakpoint");
+ return;
+ }
+
+ /* Now run the target. It will eventually hit the breakpoint, at
+ which point all of the libraries will have been mapped in and we
+ can go groveling around in the dynamic linker structures to find
+ out what we need to know about them. */
+
+ clear_proceed_status ();
+ stop_soon_quietly = 1;
+ stop_signal = TARGET_SIGNAL_0;
+ do
+ {
+ target_resume (pid_to_ptid (-1), 0, stop_signal);
+ wait_for_inferior ();
+ }
+ while (stop_signal != TARGET_SIGNAL_TRAP);
+
+ /* We are now either at the "mapping complete" breakpoint (or somewhere
+ else, a condition we aren't prepared to deal with anyway), so adjust
+ the PC as necessary after a breakpoint, disable the breakpoint, and
+ add any shared libraries that were mapped in. */
+
+ if (DECR_PC_AFTER_BREAK)
+ {
+ stop_pc -= DECR_PC_AFTER_BREAK;
+ write_register (PC_REGNUM, stop_pc);
+ }
+
+ if (!disable_break ())
+ {
+ warning ("shared library handler failed to disable breakpoint");
+ }
+
+ /* solib_add will call reinit_frame_cache.
+ But we are stopped in the startup code and we might not have symbols
+ for the startup code, so heuristic_proc_start could be called
+ and will put out an annoying warning.
+ Delaying the resetting of stop_soon_quietly until after symbol loading
+ suppresses the warning. */
+ solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
+ stop_soon_quietly = 0;
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ sharedlibrary_command -- handle command to explicitly add library
+
+ SYNOPSIS
+
+ static void sharedlibrary_command (char *args, int from_tty)
+
+ DESCRIPTION
+
+ */
+
+static void
+sharedlibrary_command (char *args, int from_tty)
+{
+ dont_repeat ();
+ solib_add (args, from_tty, (struct target_ops *) 0, 1);
+}
+
+void
+_initialize_solib (void)
+{
+ add_com ("sharedlibrary", class_files, sharedlibrary_command,
+ "Load shared object library symbols for files matching REGEXP.");
+ add_info ("sharedlibrary", info_sharedlibrary_command,
+ "Status of loaded shared object libraries.");
+
+ add_show_from_set
+ (add_set_cmd ("auto-solib-add", class_support, var_boolean,
+ (char *) &auto_solib_add,
+ "Set autoloading of shared library symbols.\n\
+If \"on\", symbols from all shared object libraries will be loaded\n\
+automatically when the inferior begins execution, when the dynamic linker\n\
+informs gdb that a new library has been loaded, or when attaching to the\n\
+inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.",
+ &setlist),
+ &showlist);
+}
+
+
+/* Register that we are able to handle irix5 core file formats.
+ This really is bfd_target_unknown_flavour */
+
+static struct core_fns irix5_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_irix5 (void)
+{
+ add_core_fns (&irix5_core_fns);
+}
diff --git a/gdb/jv-exp.y b/gdb/jv-exp.y
new file mode 100644
index 00000000000..495bf3e0537
--- /dev/null
+++ b/gdb/jv-exp.y
@@ -0,0 +1,1476 @@
+/* YACC parser for Java expressions, for GDB.
+ Copyright 1997, 1998, 1999, 2000
+ 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. */
+
+/* Parse a Java expression from text in a string,
+ and return the result as a struct expression pointer.
+ That structure contains arithmetic operations in reverse polish,
+ with constants represented by operations that are followed by special data.
+ See expression.h for the details of the format.
+ What is important here is that it can be built up sequentially
+ during the process of parsing; the lower levels of the tree always
+ come first in the result. Well, almost always; see ArrayAccess.
+
+ Note that malloc's and realloc's in this file are transformed to
+ xmalloc and xrealloc respectively by the same sed command in the
+ makefile that remaps any other malloc/realloc inserted by the parser
+ generator. Doing this with #defines and trying to control the interaction
+ with include files (<malloc.h> and <stdlib.h> for example) just became
+ too messy, particularly when such includes can be inserted at random
+ times by the parser generator. */
+
+%{
+
+#include "defs.h"
+#include "gdb_string.h"
+#include <ctype.h>
+#include "expression.h"
+#include "value.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "jv-lang.h"
+#include "bfd.h" /* Required by objfiles.h. */
+#include "symfile.h" /* Required by objfiles.h. */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
+ as well as gratuitiously global symbol names, so we can have multiple
+ yacc generated parsers in gdb. Note that these are only the variables
+ produced by yacc. If other parser generators (bison, byacc, etc) produce
+ additional global names that conflict at link time, then those parser
+ generators need to be fixed instead of adding those names to this list. */
+
+#define yymaxdepth java_maxdepth
+#define yyparse java_parse
+#define yylex java_lex
+#define yyerror java_error
+#define yylval java_lval
+#define yychar java_char
+#define yydebug java_debug
+#define yypact java_pact
+#define yyr1 java_r1
+#define yyr2 java_r2
+#define yydef java_def
+#define yychk java_chk
+#define yypgo java_pgo
+#define yyact java_act
+#define yyexca java_exca
+#define yyerrflag java_errflag
+#define yynerrs java_nerrs
+#define yyps java_ps
+#define yypv java_pv
+#define yys java_s
+#define yy_yys java_yys
+#define yystate java_state
+#define yytmp java_tmp
+#define yyv java_v
+#define yy_yyv java_yyv
+#define yyval java_val
+#define yylloc java_lloc
+#define yyreds java_reds /* With YYDEBUG defined */
+#define yytoks java_toks /* With YYDEBUG defined */
+#define yylhs java_yylhs
+#define yylen java_yylen
+#define yydefred java_yydefred
+#define yydgoto java_yydgoto
+#define yysindex java_yysindex
+#define yyrindex java_yyrindex
+#define yygindex java_yygindex
+#define yytable java_yytable
+#define yycheck java_yycheck
+
+#ifndef YYDEBUG
+#define YYDEBUG 0 /* Default to no yydebug support */
+#endif
+
+int yyparse (void);
+
+static int yylex (void);
+
+void yyerror (char *);
+
+static struct type *java_type_from_name (struct stoken);
+static void push_expression_name (struct stoken);
+static void push_fieldnames (struct stoken);
+
+static struct expression *copy_exp (struct expression *, int);
+static void insert_exp (int, struct expression *);
+
+%}
+
+/* Although the yacc "value" of an expression is not used,
+ since the result is stored in the structure being created,
+ other node types do have values. */
+
+%union
+ {
+ LONGEST lval;
+ struct {
+ LONGEST val;
+ struct type *type;
+ } typed_val_int;
+ struct {
+ DOUBLEST dval;
+ struct type *type;
+ } typed_val_float;
+ struct symbol *sym;
+ struct type *tval;
+ struct stoken sval;
+ struct ttype tsym;
+ struct symtoken ssym;
+ struct block *bval;
+ enum exp_opcode opcode;
+ struct internalvar *ivar;
+ int *ivec;
+ }
+
+%{
+/* YYSTYPE gets defined by %union */
+static int parse_number (char *, int, int, YYSTYPE *);
+%}
+
+%type <lval> rcurly Dims Dims_opt
+%type <tval> ClassOrInterfaceType ClassType /* ReferenceType Type ArrayType */
+%type <tval> IntegralType FloatingPointType NumericType PrimitiveType ArrayType PrimitiveOrArrayType
+
+%token <typed_val_int> INTEGER_LITERAL
+%token <typed_val_float> FLOATING_POINT_LITERAL
+
+%token <sval> IDENTIFIER
+%token <sval> STRING_LITERAL
+%token <lval> BOOLEAN_LITERAL
+%token <tsym> TYPENAME
+%type <sval> Name SimpleName QualifiedName ForcedName
+
+/* A NAME_OR_INT is a symbol which is not known in the symbol table,
+ but which would parse as a valid number in the current input radix.
+ E.g. "c" when input_radix==16. Depending on the parse, it will be
+ turned into a name or into a number. */
+
+%token <sval> NAME_OR_INT
+
+%token ERROR
+
+/* Special type cases, put in to allow the parser to distinguish different
+ legal basetypes. */
+%token LONG SHORT BYTE INT CHAR BOOLEAN DOUBLE FLOAT
+
+%token VARIABLE
+
+%token <opcode> ASSIGN_MODIFY
+
+%token THIS SUPER NEW
+
+%left ','
+%right '=' ASSIGN_MODIFY
+%right '?'
+%left OROR
+%left ANDAND
+%left '|'
+%left '^'
+%left '&'
+%left EQUAL NOTEQUAL
+%left '<' '>' LEQ GEQ
+%left LSH RSH
+%left '+' '-'
+%left '*' '/' '%'
+%right INCREMENT DECREMENT
+%right '.' '[' '('
+
+
+%%
+
+start : exp1
+ | type_exp
+ ;
+
+type_exp: PrimitiveOrArrayType
+ {
+ write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type($1);
+ write_exp_elt_opcode(OP_TYPE);
+ }
+ ;
+
+PrimitiveOrArrayType:
+ PrimitiveType
+ | ArrayType
+ ;
+
+StringLiteral:
+ STRING_LITERAL
+ {
+ write_exp_elt_opcode (OP_STRING);
+ write_exp_string ($1);
+ write_exp_elt_opcode (OP_STRING);
+ }
+;
+
+Literal:
+ INTEGER_LITERAL
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type ($1.type);
+ write_exp_elt_longcst ((LONGEST)($1.val));
+ write_exp_elt_opcode (OP_LONG); }
+| NAME_OR_INT
+ { YYSTYPE val;
+ parse_number ($1.ptr, $1.length, 0, &val);
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (val.typed_val_int.type);
+ write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
+ write_exp_elt_opcode (OP_LONG);
+ }
+| FLOATING_POINT_LITERAL
+ { write_exp_elt_opcode (OP_DOUBLE);
+ write_exp_elt_type ($1.type);
+ write_exp_elt_dblcst ($1.dval);
+ write_exp_elt_opcode (OP_DOUBLE); }
+| BOOLEAN_LITERAL
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (java_boolean_type);
+ write_exp_elt_longcst ((LONGEST)$1);
+ write_exp_elt_opcode (OP_LONG); }
+| StringLiteral
+ ;
+
+/* UNUSED:
+Type:
+ PrimitiveType
+| ReferenceType
+;
+*/
+
+PrimitiveType:
+ NumericType
+| BOOLEAN
+ { $$ = java_boolean_type; }
+;
+
+NumericType:
+ IntegralType
+| FloatingPointType
+;
+
+IntegralType:
+ BYTE
+ { $$ = java_byte_type; }
+| SHORT
+ { $$ = java_short_type; }
+| INT
+ { $$ = java_int_type; }
+| LONG
+ { $$ = java_long_type; }
+| CHAR
+ { $$ = java_char_type; }
+;
+
+FloatingPointType:
+ FLOAT
+ { $$ = java_float_type; }
+| DOUBLE
+ { $$ = java_double_type; }
+;
+
+/* UNUSED:
+ReferenceType:
+ ClassOrInterfaceType
+| ArrayType
+;
+*/
+
+ClassOrInterfaceType:
+ Name
+ { $$ = java_type_from_name ($1); }
+;
+
+ClassType:
+ ClassOrInterfaceType
+;
+
+ArrayType:
+ PrimitiveType Dims
+ { $$ = java_array_type ($1, $2); }
+| Name Dims
+ { $$ = java_array_type (java_type_from_name ($1), $2); }
+;
+
+Name:
+ IDENTIFIER
+| QualifiedName
+;
+
+ForcedName:
+ SimpleName
+| QualifiedName
+;
+
+SimpleName:
+ IDENTIFIER
+| NAME_OR_INT
+;
+
+QualifiedName:
+ Name '.' SimpleName
+ { $$.length = $1.length + $3.length + 1;
+ if ($1.ptr + $1.length + 1 == $3.ptr
+ && $1.ptr[$1.length] == '.')
+ $$.ptr = $1.ptr; /* Optimization. */
+ else
+ {
+ $$.ptr = (char *) malloc ($$.length + 1);
+ make_cleanup (free, $$.ptr);
+ sprintf ($$.ptr, "%.*s.%.*s",
+ $1.length, $1.ptr, $3.length, $3.ptr);
+ } }
+;
+
+/*
+type_exp: type
+ { write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type($1);
+ write_exp_elt_opcode(OP_TYPE);}
+ ;
+ */
+
+/* Expressions, including the comma operator. */
+exp1 : Expression
+ | exp1 ',' Expression
+ { write_exp_elt_opcode (BINOP_COMMA); }
+ ;
+
+Primary:
+ PrimaryNoNewArray
+| ArrayCreationExpression
+;
+
+PrimaryNoNewArray:
+ Literal
+| THIS
+ { write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (OP_THIS); }
+| '(' Expression ')'
+| ClassInstanceCreationExpression
+| FieldAccess
+| MethodInvocation
+| ArrayAccess
+| lcurly ArgumentList rcurly
+ { write_exp_elt_opcode (OP_ARRAY);
+ write_exp_elt_longcst ((LONGEST) 0);
+ write_exp_elt_longcst ((LONGEST) $3);
+ write_exp_elt_opcode (OP_ARRAY); }
+;
+
+lcurly:
+ '{'
+ { start_arglist (); }
+;
+
+rcurly:
+ '}'
+ { $$ = end_arglist () - 1; }
+;
+
+ClassInstanceCreationExpression:
+ NEW ClassType '(' ArgumentList_opt ')'
+ { error ("FIXME - ClassInstanceCreationExpression"); }
+;
+
+ArgumentList:
+ Expression
+ { arglist_len = 1; }
+| ArgumentList ',' Expression
+ { arglist_len++; }
+;
+
+ArgumentList_opt:
+ /* EMPTY */
+ { arglist_len = 0; }
+| ArgumentList
+;
+
+ArrayCreationExpression:
+ NEW PrimitiveType DimExprs Dims_opt
+ { error ("FIXME - ArrayCreatiionExpression"); }
+| NEW ClassOrInterfaceType DimExprs Dims_opt
+ { error ("FIXME - ArrayCreatiionExpression"); }
+;
+
+DimExprs:
+ DimExpr
+| DimExprs DimExpr
+;
+
+DimExpr:
+ '[' Expression ']'
+;
+
+Dims:
+ '[' ']'
+ { $$ = 1; }
+| Dims '[' ']'
+ { $$ = $1 + 1; }
+;
+
+Dims_opt:
+ Dims
+| /* EMPTY */
+ { $$ = 0; }
+;
+
+FieldAccess:
+ Primary '.' SimpleName
+ { push_fieldnames ($3); }
+| VARIABLE '.' SimpleName
+ { push_fieldnames ($3); }
+/*| SUPER '.' SimpleName { FIXME } */
+;
+
+MethodInvocation:
+ Name '(' ArgumentList_opt ')'
+ { error ("method invocation not implemented"); }
+| Primary '.' SimpleName '(' ArgumentList_opt ')'
+ { error ("method invocation not implemented"); }
+| SUPER '.' SimpleName '(' ArgumentList_opt ')'
+ { error ("method invocation not implemented"); }
+;
+
+ArrayAccess:
+ Name '[' Expression ']'
+ {
+ /* Emit code for the Name now, then exchange it in the
+ expout array with the Expression's code. We could
+ introduce a OP_SWAP code or a reversed version of
+ BINOP_SUBSCRIPT, but that makes the rest of GDB pay
+ for our parsing kludges. */
+ struct expression *name_expr;
+
+ push_expression_name ($1);
+ name_expr = copy_exp (expout, expout_ptr);
+ expout_ptr -= name_expr->nelts;
+ insert_exp (expout_ptr-length_of_subexp (expout, expout_ptr),
+ name_expr);
+ free (name_expr);
+ write_exp_elt_opcode (BINOP_SUBSCRIPT);
+ }
+| VARIABLE '[' Expression ']'
+ { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+| PrimaryNoNewArray '[' Expression ']'
+ { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+;
+
+PostfixExpression:
+ Primary
+| Name
+ { push_expression_name ($1); }
+| VARIABLE
+ /* Already written by write_dollar_variable. */
+| PostIncrementExpression
+| PostDecrementExpression
+;
+
+PostIncrementExpression:
+ PostfixExpression INCREMENT
+ { write_exp_elt_opcode (UNOP_POSTINCREMENT); }
+;
+
+PostDecrementExpression:
+ PostfixExpression DECREMENT
+ { write_exp_elt_opcode (UNOP_POSTDECREMENT); }
+;
+
+UnaryExpression:
+ PreIncrementExpression
+| PreDecrementExpression
+| '+' UnaryExpression
+| '-' UnaryExpression
+ { write_exp_elt_opcode (UNOP_NEG); }
+| '*' UnaryExpression
+ { write_exp_elt_opcode (UNOP_IND); } /*FIXME not in Java */
+| UnaryExpressionNotPlusMinus
+;
+
+PreIncrementExpression:
+ INCREMENT UnaryExpression
+ { write_exp_elt_opcode (UNOP_PREINCREMENT); }
+;
+
+PreDecrementExpression:
+ DECREMENT UnaryExpression
+ { write_exp_elt_opcode (UNOP_PREDECREMENT); }
+;
+
+UnaryExpressionNotPlusMinus:
+ PostfixExpression
+| '~' UnaryExpression
+ { write_exp_elt_opcode (UNOP_COMPLEMENT); }
+| '!' UnaryExpression
+ { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
+| CastExpression
+ ;
+
+CastExpression:
+ '(' PrimitiveType Dims_opt ')' UnaryExpression
+ { write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (java_array_type ($2, $3));
+ write_exp_elt_opcode (UNOP_CAST); }
+| '(' Expression ')' UnaryExpressionNotPlusMinus
+ {
+ int exp_size = expout_ptr;
+ int last_exp_size = length_of_subexp(expout, expout_ptr);
+ struct type *type;
+ int i;
+ int base = expout_ptr - last_exp_size - 3;
+ if (base < 0 || expout->elts[base+2].opcode != OP_TYPE)
+ error ("invalid cast expression");
+ type = expout->elts[base+1].type;
+ /* Remove the 'Expression' and slide the
+ UnaryExpressionNotPlusMinus down to replace it. */
+ for (i = 0; i < last_exp_size; i++)
+ expout->elts[base + i] = expout->elts[base + i + 3];
+ expout_ptr -= 3;
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+ type = lookup_pointer_type (type);
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (type);
+ write_exp_elt_opcode (UNOP_CAST);
+ }
+| '(' Name Dims ')' UnaryExpressionNotPlusMinus
+ { write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (java_array_type (java_type_from_name ($2), $3));
+ write_exp_elt_opcode (UNOP_CAST); }
+;
+
+
+MultiplicativeExpression:
+ UnaryExpression
+| MultiplicativeExpression '*' UnaryExpression
+ { write_exp_elt_opcode (BINOP_MUL); }
+| MultiplicativeExpression '/' UnaryExpression
+ { write_exp_elt_opcode (BINOP_DIV); }
+| MultiplicativeExpression '%' UnaryExpression
+ { write_exp_elt_opcode (BINOP_REM); }
+;
+
+AdditiveExpression:
+ MultiplicativeExpression
+| AdditiveExpression '+' MultiplicativeExpression
+ { write_exp_elt_opcode (BINOP_ADD); }
+| AdditiveExpression '-' MultiplicativeExpression
+ { write_exp_elt_opcode (BINOP_SUB); }
+;
+
+ShiftExpression:
+ AdditiveExpression
+| ShiftExpression LSH AdditiveExpression
+ { write_exp_elt_opcode (BINOP_LSH); }
+| ShiftExpression RSH AdditiveExpression
+ { write_exp_elt_opcode (BINOP_RSH); }
+/* | ShiftExpression >>> AdditiveExpression { FIXME } */
+;
+
+RelationalExpression:
+ ShiftExpression
+| RelationalExpression '<' ShiftExpression
+ { write_exp_elt_opcode (BINOP_LESS); }
+| RelationalExpression '>' ShiftExpression
+ { write_exp_elt_opcode (BINOP_GTR); }
+| RelationalExpression LEQ ShiftExpression
+ { write_exp_elt_opcode (BINOP_LEQ); }
+| RelationalExpression GEQ ShiftExpression
+ { write_exp_elt_opcode (BINOP_GEQ); }
+/* | RelationalExpresion INSTANCEOF ReferenceType { FIXME } */
+;
+
+EqualityExpression:
+ RelationalExpression
+| EqualityExpression EQUAL RelationalExpression
+ { write_exp_elt_opcode (BINOP_EQUAL); }
+| EqualityExpression NOTEQUAL RelationalExpression
+ { write_exp_elt_opcode (BINOP_NOTEQUAL); }
+;
+
+AndExpression:
+ EqualityExpression
+| AndExpression '&' EqualityExpression
+ { write_exp_elt_opcode (BINOP_BITWISE_AND); }
+;
+
+ExclusiveOrExpression:
+ AndExpression
+| ExclusiveOrExpression '^' AndExpression
+ { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
+;
+InclusiveOrExpression:
+ ExclusiveOrExpression
+| InclusiveOrExpression '|' ExclusiveOrExpression
+ { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
+;
+
+ConditionalAndExpression:
+ InclusiveOrExpression
+| ConditionalAndExpression ANDAND InclusiveOrExpression
+ { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
+;
+
+ConditionalOrExpression:
+ ConditionalAndExpression
+| ConditionalOrExpression OROR ConditionalAndExpression
+ { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
+;
+
+ConditionalExpression:
+ ConditionalOrExpression
+| ConditionalOrExpression '?' Expression ':' ConditionalExpression
+ { write_exp_elt_opcode (TERNOP_COND); }
+;
+
+AssignmentExpression:
+ ConditionalExpression
+| Assignment
+;
+
+Assignment:
+ LeftHandSide '=' ConditionalExpression
+ { write_exp_elt_opcode (BINOP_ASSIGN); }
+| LeftHandSide ASSIGN_MODIFY ConditionalExpression
+ { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
+ write_exp_elt_opcode ($2);
+ write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
+;
+
+LeftHandSide:
+ ForcedName
+ { push_expression_name ($1); }
+| VARIABLE
+ /* Already written by write_dollar_variable. */
+| FieldAccess
+| ArrayAccess
+;
+
+
+Expression:
+ AssignmentExpression
+;
+
+%%
+/* Take care of parsing a number (anything that starts with a digit).
+ Set yylval and return the token type; update lexptr.
+ LEN is the number of characters in it. */
+
+/*** Needs some error checking for the float case ***/
+
+static int
+parse_number (p, len, parsed_float, putithere)
+ register char *p;
+ register int len;
+ int parsed_float;
+ YYSTYPE *putithere;
+{
+ register ULONGEST n = 0;
+ ULONGEST limit, limit_div_base;
+
+ register int c;
+ register int base = input_radix;
+
+ struct type *type;
+
+ if (parsed_float)
+ {
+ /* It's a float since it contains a point or an exponent. */
+ char c;
+ int num = 0; /* number of tokens scanned by scanf */
+ char saved_char = p[len];
+
+ p[len] = 0; /* null-terminate the token */
+ if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
+ num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval, &c);
+ else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
+ num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval, &c);
+ else
+ {
+#ifdef SCANF_HAS_LONG_DOUBLE
+ num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval, &c);
+#else
+ /* Scan it into a double, then assign it to the long double.
+ This at least wins with values representable in the range
+ of doubles. */
+ double temp;
+ num = sscanf (p, "%lg%c", &temp, &c);
+ putithere->typed_val_float.dval = temp;
+#endif
+ }
+ p[len] = saved_char; /* restore the input stream */
+ if (num != 1) /* check scanf found ONLY a float ... */
+ return ERROR;
+ /* See if it has `f' or `d' suffix (float or double). */
+
+ c = tolower (p[len - 1]);
+
+ if (c == 'f' || c == 'F')
+ putithere->typed_val_float.type = builtin_type_float;
+ else if (isdigit (c) || c == '.' || c == 'd' || c == 'D')
+ putithere->typed_val_float.type = builtin_type_double;
+ else
+ return ERROR;
+
+ return FLOATING_POINT_LITERAL;
+ }
+
+ /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
+ if (p[0] == '0')
+ switch (p[1])
+ {
+ case 'x':
+ case 'X':
+ if (len >= 3)
+ {
+ p += 2;
+ base = 16;
+ len -= 2;
+ }
+ break;
+
+ case 't':
+ case 'T':
+ case 'd':
+ case 'D':
+ if (len >= 3)
+ {
+ p += 2;
+ base = 10;
+ len -= 2;
+ }
+ break;
+
+ default:
+ base = 8;
+ break;
+ }
+
+ c = p[len-1];
+ /* A paranoid calculation of (1<<64)-1. */
+ limit = (ULONGEST)0xffffffff;
+ limit = ((limit << 16) << 16) | limit;
+ if (c == 'l' || c == 'L')
+ {
+ type = java_long_type;
+ len--;
+ }
+ else
+ {
+ type = java_int_type;
+ }
+ limit_div_base = limit / (ULONGEST) base;
+
+ while (--len >= 0)
+ {
+ c = *p++;
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ return ERROR; /* Char not a digit */
+ if (c >= base)
+ return ERROR;
+ if (n > limit_div_base
+ || (n *= base) > limit - c)
+ error ("Numeric constant too large.");
+ n += c;
+ }
+
+ /* If the type is bigger than a 32-bit signed integer can be, implicitly
+ promote to long. Java does not do this, so mark it as builtin_type_uint64
+ rather than java_long_type. 0x80000000 will become -0x80000000 instead
+ of 0x80000000L, because we don't know the sign at this point.
+ */
+ if (type == java_int_type && n > (ULONGEST)0x80000000)
+ type = builtin_type_uint64;
+
+ putithere->typed_val_int.val = n;
+ putithere->typed_val_int.type = type;
+
+ return INTEGER_LITERAL;
+}
+
+struct token
+{
+ char *operator;
+ int token;
+ enum exp_opcode opcode;
+};
+
+static const struct token tokentab3[] =
+ {
+ {">>=", ASSIGN_MODIFY, BINOP_RSH},
+ {"<<=", ASSIGN_MODIFY, BINOP_LSH}
+ };
+
+static const struct token tokentab2[] =
+ {
+ {"+=", ASSIGN_MODIFY, BINOP_ADD},
+ {"-=", ASSIGN_MODIFY, BINOP_SUB},
+ {"*=", ASSIGN_MODIFY, BINOP_MUL},
+ {"/=", ASSIGN_MODIFY, BINOP_DIV},
+ {"%=", ASSIGN_MODIFY, BINOP_REM},
+ {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
+ {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
+ {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
+ {"++", INCREMENT, BINOP_END},
+ {"--", DECREMENT, BINOP_END},
+ {"&&", ANDAND, BINOP_END},
+ {"||", OROR, BINOP_END},
+ {"<<", LSH, BINOP_END},
+ {">>", RSH, BINOP_END},
+ {"==", EQUAL, BINOP_END},
+ {"!=", NOTEQUAL, BINOP_END},
+ {"<=", LEQ, BINOP_END},
+ {">=", GEQ, BINOP_END}
+ };
+
+/* Read one token, getting characters through lexptr. */
+
+static int
+yylex ()
+{
+ int c;
+ int namelen;
+ unsigned int i;
+ char *tokstart;
+ char *tokptr;
+ int tempbufindex;
+ static char *tempbuf;
+ static int tempbufsize;
+
+ retry:
+
+ prev_lexptr = lexptr;
+
+ tokstart = lexptr;
+ /* See if it is a special token of length 3. */
+ for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
+ if (STREQN (tokstart, tokentab3[i].operator, 3))
+ {
+ lexptr += 3;
+ yylval.opcode = tokentab3[i].opcode;
+ return tokentab3[i].token;
+ }
+
+ /* See if it is a special token of length 2. */
+ for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
+ if (STREQN (tokstart, tokentab2[i].operator, 2))
+ {
+ lexptr += 2;
+ yylval.opcode = tokentab2[i].opcode;
+ return tokentab2[i].token;
+ }
+
+ switch (c = *tokstart)
+ {
+ case 0:
+ return 0;
+
+ case ' ':
+ case '\t':
+ case '\n':
+ lexptr++;
+ goto retry;
+
+ case '\'':
+ /* We either have a character constant ('0' or '\177' for example)
+ or we have a quoted symbol reference ('foo(int,int)' in C++
+ for example). */
+ lexptr++;
+ c = *lexptr++;
+ if (c == '\\')
+ c = parse_escape (&lexptr);
+ else if (c == '\'')
+ error ("Empty character constant.");
+
+ yylval.typed_val_int.val = c;
+ yylval.typed_val_int.type = java_char_type;
+
+ c = *lexptr++;
+ if (c != '\'')
+ {
+ namelen = skip_quoted (tokstart) - tokstart;
+ if (namelen > 2)
+ {
+ lexptr = tokstart + namelen;
+ if (lexptr[-1] != '\'')
+ error ("Unmatched single quote.");
+ namelen -= 2;
+ tokstart++;
+ goto tryname;
+ }
+ error ("Invalid character constant.");
+ }
+ return INTEGER_LITERAL;
+
+ case '(':
+ paren_depth++;
+ lexptr++;
+ return c;
+
+ case ')':
+ if (paren_depth == 0)
+ return 0;
+ paren_depth--;
+ lexptr++;
+ return c;
+
+ case ',':
+ if (comma_terminates && paren_depth == 0)
+ return 0;
+ lexptr++;
+ return c;
+
+ case '.':
+ /* Might be a floating point number. */
+ if (lexptr[1] < '0' || lexptr[1] > '9')
+ goto symbol; /* Nope, must be a symbol. */
+ /* FALL THRU into number case. */
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ /* It's a number. */
+ int got_dot = 0, got_e = 0, toktype;
+ register char *p = tokstart;
+ int hex = input_radix > 10;
+
+ if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
+ {
+ p += 2;
+ hex = 1;
+ }
+ else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
+ {
+ p += 2;
+ hex = 0;
+ }
+
+ for (;; ++p)
+ {
+ /* This test includes !hex because 'e' is a valid hex digit
+ and thus does not indicate a floating point number when
+ the radix is hex. */
+ if (!hex && !got_e && (*p == 'e' || *p == 'E'))
+ got_dot = got_e = 1;
+ /* This test does not include !hex, because a '.' always indicates
+ a decimal floating point number regardless of the radix. */
+ else if (!got_dot && *p == '.')
+ got_dot = 1;
+ else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
+ && (*p == '-' || *p == '+'))
+ /* This is the sign of the exponent, not the end of the
+ number. */
+ continue;
+ /* We will take any letters or digits. parse_number will
+ complain if past the radix, or if L or U are not final. */
+ else if ((*p < '0' || *p > '9')
+ && ((*p < 'a' || *p > 'z')
+ && (*p < 'A' || *p > 'Z')))
+ break;
+ }
+ toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
+ if (toktype == ERROR)
+ {
+ char *err_copy = (char *) alloca (p - tokstart + 1);
+
+ memcpy (err_copy, tokstart, p - tokstart);
+ err_copy[p - tokstart] = 0;
+ error ("Invalid number \"%s\".", err_copy);
+ }
+ lexptr = p;
+ return toktype;
+ }
+
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '%':
+ case '|':
+ case '&':
+ case '^':
+ case '~':
+ case '!':
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case '?':
+ case ':':
+ case '=':
+ case '{':
+ case '}':
+ symbol:
+ lexptr++;
+ return c;
+
+ case '"':
+
+ /* Build the gdb internal form of the input string in tempbuf,
+ translating any standard C escape forms seen. Note that the
+ buffer is null byte terminated *only* for the convenience of
+ debugging gdb itself and printing the buffer contents when
+ the buffer contains no embedded nulls. Gdb does not depend
+ upon the buffer being null byte terminated, it uses the length
+ string instead. This allows gdb to handle C strings (as well
+ as strings in other languages) with embedded null bytes */
+
+ tokptr = ++tokstart;
+ tempbufindex = 0;
+
+ do {
+ /* Grow the static temp buffer if necessary, including allocating
+ the first one on demand. */
+ if (tempbufindex + 1 >= tempbufsize)
+ {
+ tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
+ }
+ switch (*tokptr)
+ {
+ case '\0':
+ case '"':
+ /* Do nothing, loop will terminate. */
+ break;
+ case '\\':
+ tokptr++;
+ c = parse_escape (&tokptr);
+ if (c == -1)
+ {
+ continue;
+ }
+ tempbuf[tempbufindex++] = c;
+ break;
+ default:
+ tempbuf[tempbufindex++] = *tokptr++;
+ break;
+ }
+ } while ((*tokptr != '"') && (*tokptr != '\0'));
+ if (*tokptr++ != '"')
+ {
+ error ("Unterminated string in expression.");
+ }
+ tempbuf[tempbufindex] = '\0'; /* See note above */
+ yylval.sval.ptr = tempbuf;
+ yylval.sval.length = tempbufindex;
+ lexptr = tokptr;
+ return (STRING_LITERAL);
+ }
+
+ if (!(c == '_' || c == '$'
+ || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
+ /* We must have come across a bad character (e.g. ';'). */
+ error ("Invalid character '%c' in expression.", c);
+
+ /* It's a name. See how long it is. */
+ namelen = 0;
+ for (c = tokstart[namelen];
+ (c == '_'
+ || c == '$'
+ || (c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || c == '<');
+ )
+ {
+ if (c == '<')
+ {
+ int i = namelen;
+ while (tokstart[++i] && tokstart[i] != '>');
+ if (tokstart[i] == '>')
+ namelen = i;
+ }
+ c = tokstart[++namelen];
+ }
+
+ /* The token "if" terminates the expression and is NOT
+ removed from the input stream. */
+ if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
+ {
+ return 0;
+ }
+
+ lexptr += namelen;
+
+ tryname:
+
+ /* Catch specific keywords. Should be done with a data structure. */
+ switch (namelen)
+ {
+ case 7:
+ if (STREQN (tokstart, "boolean", 7))
+ return BOOLEAN;
+ break;
+ case 6:
+ if (STREQN (tokstart, "double", 6))
+ return DOUBLE;
+ break;
+ case 5:
+ if (STREQN (tokstart, "short", 5))
+ return SHORT;
+ if (STREQN (tokstart, "false", 5))
+ {
+ yylval.lval = 0;
+ return BOOLEAN_LITERAL;
+ }
+ if (STREQN (tokstart, "super", 5))
+ return SUPER;
+ if (STREQN (tokstart, "float", 5))
+ return FLOAT;
+ break;
+ case 4:
+ if (STREQN (tokstart, "long", 4))
+ return LONG;
+ if (STREQN (tokstart, "byte", 4))
+ return BYTE;
+ if (STREQN (tokstart, "char", 4))
+ return CHAR;
+ if (STREQN (tokstart, "true", 4))
+ {
+ yylval.lval = 1;
+ return BOOLEAN_LITERAL;
+ }
+ if (current_language->la_language == language_cplus
+ && STREQN (tokstart, "this", 4))
+ {
+ static const char this_name[] =
+ { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
+
+ if (lookup_symbol (this_name, expression_context_block,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL))
+ return THIS;
+ }
+ break;
+ case 3:
+ if (STREQN (tokstart, "int", 3))
+ return INT;
+ if (STREQN (tokstart, "new", 3))
+ return NEW;
+ break;
+ default:
+ break;
+ }
+
+ yylval.sval.ptr = tokstart;
+ yylval.sval.length = namelen;
+
+ if (*tokstart == '$')
+ {
+ write_dollar_variable (yylval.sval);
+ return VARIABLE;
+ }
+
+ /* Input names that aren't symbols but ARE valid hex numbers,
+ when the input radix permits them, can be names or numbers
+ depending on the parse. Note we support radixes > 16 here. */
+ if (((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
+ (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
+ {
+ YYSTYPE newlval; /* Its value is ignored. */
+ int hextype = parse_number (tokstart, namelen, 0, &newlval);
+ if (hextype == INTEGER_LITERAL)
+ return NAME_OR_INT;
+ }
+ return IDENTIFIER;
+}
+
+void
+yyerror (msg)
+ char *msg;
+{
+ if (prev_lexptr)
+ lexptr = prev_lexptr;
+
+ error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
+}
+
+static struct type *
+java_type_from_name (name)
+ struct stoken name;
+
+{
+ char *tmp = copy_name (name);
+ struct type *typ = java_lookup_class (tmp);
+ if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT)
+ error ("No class named %s.", tmp);
+ return typ;
+}
+
+/* If NAME is a valid variable name in this scope, push it and return 1.
+ Otherwise, return 0. */
+
+static int
+push_variable (name)
+ struct stoken name;
+
+{
+ char *tmp = copy_name (name);
+ int is_a_field_of_this = 0;
+ struct symbol *sym;
+ sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE,
+ &is_a_field_of_this, (struct symtab **) NULL);
+ if (sym && SYMBOL_CLASS (sym) != LOC_TYPEDEF)
+ {
+ if (symbol_read_needs_frame (sym))
+ {
+ if (innermost_block == 0 ||
+ contained_in (block_found, innermost_block))
+ innermost_block = block_found;
+ }
+
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ /* We want to use the selected frame, not another more inner frame
+ which happens to be in the same block. */
+ write_exp_elt_block (NULL);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ return 1;
+ }
+ if (is_a_field_of_this)
+ {
+ /* it hangs off of `this'. Must not inadvertently convert from a
+ method call to data ref. */
+ if (innermost_block == 0 ||
+ contained_in (block_found, innermost_block))
+ innermost_block = block_found;
+ write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (STRUCTOP_PTR);
+ write_exp_string (name);
+ write_exp_elt_opcode (STRUCTOP_PTR);
+ return 1;
+ }
+ return 0;
+}
+
+/* Assuming a reference expression has been pushed, emit the
+ STRUCTOP_STRUCT ops to access the field named NAME. If NAME is a
+ qualified name (has '.'), generate a field access for each part. */
+
+static void
+push_fieldnames (name)
+ struct stoken name;
+{
+ int i;
+ struct stoken token;
+ token.ptr = name.ptr;
+ for (i = 0; ; i++)
+ {
+ if (i == name.length || name.ptr[i] == '.')
+ {
+ /* token.ptr is start of current field name. */
+ token.length = &name.ptr[i] - token.ptr;
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ write_exp_string (token);
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ token.ptr += token.length + 1;
+ }
+ if (i >= name.length)
+ break;
+ }
+}
+
+/* Helper routine for push_expression_name.
+ Handle a qualified name, where DOT_INDEX is the index of the first '.' */
+
+static void
+push_qualified_expression_name (name, dot_index)
+ struct stoken name;
+ int dot_index;
+{
+ struct stoken token;
+ char *tmp;
+ struct type *typ;
+
+ token.ptr = name.ptr;
+ token.length = dot_index;
+
+ if (push_variable (token))
+ {
+ token.ptr = name.ptr + dot_index + 1;
+ token.length = name.length - dot_index - 1;
+ push_fieldnames (token);
+ return;
+ }
+
+ token.ptr = name.ptr;
+ for (;;)
+ {
+ token.length = dot_index;
+ tmp = copy_name (token);
+ typ = java_lookup_class (tmp);
+ if (typ != NULL)
+ {
+ if (dot_index == name.length)
+ {
+ write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type(typ);
+ write_exp_elt_opcode(OP_TYPE);
+ return;
+ }
+ dot_index++; /* Skip '.' */
+ name.ptr += dot_index;
+ name.length -= dot_index;
+ dot_index = 0;
+ while (dot_index < name.length && name.ptr[dot_index] != '.')
+ dot_index++;
+ token.ptr = name.ptr;
+ token.length = dot_index;
+ write_exp_elt_opcode (OP_SCOPE);
+ write_exp_elt_type (typ);
+ write_exp_string (token);
+ write_exp_elt_opcode (OP_SCOPE);
+ if (dot_index < name.length)
+ {
+ dot_index++;
+ name.ptr += dot_index;
+ name.length -= dot_index;
+ push_fieldnames (name);
+ }
+ return;
+ }
+ else if (dot_index >= name.length)
+ break;
+ dot_index++; /* Skip '.' */
+ while (dot_index < name.length && name.ptr[dot_index] != '.')
+ dot_index++;
+ }
+ error ("unknown type `%.*s'", name.length, name.ptr);
+}
+
+/* Handle Name in an expression (or LHS).
+ Handle VAR, TYPE, TYPE.FIELD1....FIELDN and VAR.FIELD1....FIELDN. */
+
+static void
+push_expression_name (name)
+ struct stoken name;
+{
+ char *tmp;
+ struct type *typ;
+ char *ptr;
+ int i;
+
+ for (i = 0; i < name.length; i++)
+ {
+ if (name.ptr[i] == '.')
+ {
+ /* It's a Qualified Expression Name. */
+ push_qualified_expression_name (name, i);
+ return;
+ }
+ }
+
+ /* It's a Simple Expression Name. */
+
+ if (push_variable (name))
+ return;
+ tmp = copy_name (name);
+ typ = java_lookup_class (tmp);
+ if (typ != NULL)
+ {
+ write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type(typ);
+ write_exp_elt_opcode(OP_TYPE);
+ }
+ else
+ {
+ struct minimal_symbol *msymbol;
+
+ msymbol = lookup_minimal_symbol (tmp, NULL, NULL);
+ if (msymbol != NULL)
+ {
+ write_exp_msymbol (msymbol,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
+ }
+ else if (!have_full_symbols () && !have_partial_symbols ())
+ error ("No symbol table is loaded. Use the \"file\" command.");
+ else
+ error ("No symbol \"%s\" in current context.", tmp);
+ }
+
+}
+
+
+/* The following two routines, copy_exp and insert_exp, aren't specific to
+ Java, so they could go in parse.c, but their only purpose is to support
+ the parsing kludges we use in this file, so maybe it's best to isolate
+ them here. */
+
+/* Copy the expression whose last element is at index ENDPOS - 1 in EXPR
+ into a freshly malloc'ed struct expression. Its language_defn is set
+ to null. */
+static struct expression *
+copy_exp (expr, endpos)
+ struct expression *expr;
+ int endpos;
+{
+ int len = length_of_subexp (expr, endpos);
+ struct expression *new
+ = (struct expression *) malloc (sizeof (*new) + EXP_ELEM_TO_BYTES (len));
+ new->nelts = len;
+ memcpy (new->elts, expr->elts + endpos - len, EXP_ELEM_TO_BYTES (len));
+ new->language_defn = 0;
+
+ return new;
+}
+
+/* Insert the expression NEW into the current expression (expout) at POS. */
+static void
+insert_exp (pos, new)
+ int pos;
+ struct expression *new;
+{
+ int newlen = new->nelts;
+
+ /* Grow expout if necessary. In this function's only use at present,
+ this should never be necessary. */
+ if (expout_ptr + newlen > expout_size)
+ {
+ expout_size = max (expout_size * 2, expout_ptr + newlen + 10);
+ expout = (struct expression *)
+ realloc ((char *) expout, (sizeof (struct expression)
+ + EXP_ELEM_TO_BYTES (expout_size)));
+ }
+
+ {
+ int i;
+
+ for (i = expout_ptr - 1; i >= pos; i--)
+ expout->elts[i + newlen] = expout->elts[i];
+ }
+
+ memcpy (expout->elts + pos, new->elts, EXP_ELEM_TO_BYTES (newlen));
+ expout_ptr += newlen;
+}
diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c
new file mode 100644
index 00000000000..e221105ed6f
--- /dev/null
+++ b/gdb/jv-lang.c
@@ -0,0 +1,1097 @@
+/* Java language support routines for GDB, the GNU debugger.
+ Copyright 1997, 1998, 1999, 2000 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "gdbtypes.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdb_string.h"
+#include "value.h"
+#include "c-lang.h"
+#include "jv-lang.h"
+#include "gdbcore.h"
+#include <ctype.h>
+
+struct type *java_int_type;
+struct type *java_byte_type;
+struct type *java_short_type;
+struct type *java_long_type;
+struct type *java_boolean_type;
+struct type *java_char_type;
+struct type *java_float_type;
+struct type *java_double_type;
+struct type *java_void_type;
+
+/* Local functions */
+
+extern void _initialize_java_language (void);
+
+static int java_demangled_signature_length (char *);
+static void java_demangled_signature_copy (char *, char *);
+
+static struct symtab *get_java_class_symtab (void);
+static char *get_java_utf8_name (struct obstack *obstack, struct value *name);
+static int java_class_is_primitive (struct value *clas);
+static struct type *java_lookup_type (char *signature);
+static struct value *java_value_string (char *ptr, int len);
+
+static void java_emit_char (int c, struct ui_file * stream, int quoter);
+
+/* This objfile contains symtabs that have been dynamically created
+ to record dynamically loaded Java classes and dynamically
+ compiled java methods. */
+
+static struct objfile *dynamics_objfile = NULL;
+
+static struct type *java_link_class_type (struct type *, struct value *);
+
+static struct objfile *
+get_dynamics_objfile (void)
+{
+ if (dynamics_objfile == NULL)
+ {
+ dynamics_objfile = allocate_objfile (NULL, 0);
+ }
+ return dynamics_objfile;
+}
+
+#if 1
+/* symtab contains classes read from the inferior. */
+
+static struct symtab *class_symtab = NULL;
+
+/* Maximum number of class in class_symtab before relocation is needed. */
+
+static int class_symtab_space;
+
+static struct symtab *
+get_java_class_symtab (void)
+{
+ if (class_symtab == NULL)
+ {
+ struct objfile *objfile = get_dynamics_objfile ();
+ struct blockvector *bv;
+ struct block *bl;
+ class_symtab = allocate_symtab ("<java-classes>", objfile);
+ class_symtab->language = language_java;
+ bv = (struct blockvector *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct blockvector));
+ BLOCKVECTOR_NBLOCKS (bv) = 1;
+ BLOCKVECTOR (class_symtab) = bv;
+
+ /* Allocate dummy STATIC_BLOCK. */
+ bl = (struct block *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
+ BLOCK_NSYMS (bl) = 0;
+ BLOCK_START (bl) = 0;
+ BLOCK_END (bl) = 0;
+ BLOCK_FUNCTION (bl) = NULL;
+ BLOCK_SUPERBLOCK (bl) = NULL;
+ BLOCK_GCC_COMPILED (bl) = 0;
+ BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
+
+ /* Allocate GLOBAL_BLOCK. This has to be relocatable. */
+ class_symtab_space = 128;
+ bl = xmmalloc (objfile->md,
+ sizeof (struct block)
+ + ((class_symtab_space - 1) * sizeof (struct symbol *)));
+ *bl = *BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
+ class_symtab->free_ptr = (char *) bl;
+ }
+ return class_symtab;
+}
+
+static void
+add_class_symtab_symbol (struct symbol *sym)
+{
+ struct symtab *symtab = get_java_class_symtab ();
+ struct blockvector *bv = BLOCKVECTOR (symtab);
+ struct block *bl = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ if (BLOCK_NSYMS (bl) >= class_symtab_space)
+ {
+ /* Need to re-allocate. */
+ class_symtab_space *= 2;
+ bl = xmrealloc (symtab->objfile->md, bl,
+ sizeof (struct block)
+ + ((class_symtab_space - 1) * sizeof (struct symbol *)));
+ class_symtab->free_ptr = (char *) bl;
+ BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
+ }
+
+ BLOCK_SYM (bl, BLOCK_NSYMS (bl)) = sym;
+ BLOCK_NSYMS (bl) = BLOCK_NSYMS (bl) + 1;
+}
+
+static struct symbol *add_class_symbol (struct type *type, CORE_ADDR addr);
+
+static struct symbol *
+add_class_symbol (struct type *type, CORE_ADDR addr)
+{
+ struct symbol *sym;
+ sym = (struct symbol *)
+ obstack_alloc (&dynamics_objfile->symbol_obstack, sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_LANGUAGE (sym) = language_java;
+ SYMBOL_NAME (sym) = TYPE_TAG_NAME (type);
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ /* SYMBOL_VALUE (sym) = valu; */
+ SYMBOL_TYPE (sym) = type;
+ SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+ SYMBOL_VALUE_ADDRESS (sym) = addr;
+ return sym;
+}
+#endif
+
+struct type *
+java_lookup_class (char *name)
+{
+ struct symbol *sym;
+ sym = lookup_symbol (name, expression_context_block, STRUCT_NAMESPACE,
+ (int *) 0, (struct symtab **) NULL);
+ if (sym != NULL)
+ return SYMBOL_TYPE (sym);
+#if 0
+ CORE_ADDR addr;
+ if (called from parser)
+ {
+ call lookup_class (or similar) in inferior;
+ if not
+ found:
+ return NULL;
+ addr = found in inferior;
+ }
+ else
+ addr = 0;
+ struct type *type;
+ type = alloc_type (objfile);
+ TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ INIT_CPLUS_SPECIFIC (type);
+ TYPE_TAG_NAME (type) = obsavestring (name, strlen (name), &objfile->type_obstack);
+ TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
+ TYPE ? = addr;
+ return type;
+#else
+ /* FIXME - should search inferior's symbol table. */
+ return NULL;
+#endif
+}
+
+/* Return a nul-terminated string (allocated on OBSTACK) for
+ a name given by NAME (which has type Utf8Const*). */
+
+char *
+get_java_utf8_name (struct obstack *obstack, struct value *name)
+{
+ char *chrs;
+ struct value *temp = name;
+ int name_length;
+ CORE_ADDR data_addr;
+ temp = value_struct_elt (&temp, NULL, "length", NULL, "structure");
+ name_length = (int) value_as_long (temp);
+ data_addr = VALUE_ADDRESS (temp) + VALUE_OFFSET (temp)
+ + TYPE_LENGTH (VALUE_TYPE (temp));
+ chrs = obstack_alloc (obstack, name_length + 1);
+ chrs[name_length] = '\0';
+ read_memory (data_addr, chrs, name_length);
+ return chrs;
+}
+
+struct value *
+java_class_from_object (struct value *obj_val)
+{
+ /* This is all rather inefficient, since the offsets of vtable and
+ class are fixed. FIXME */
+ struct value *vtable_val;
+
+ if (TYPE_CODE (VALUE_TYPE (obj_val)) == TYPE_CODE_PTR
+ && TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (obj_val))) == 0)
+ obj_val = value_at (get_java_object_type (),
+ value_as_address (obj_val), NULL);
+
+ vtable_val = value_struct_elt (&obj_val, NULL, "vtable", NULL, "structure");
+ return value_struct_elt (&vtable_val, NULL, "class", NULL, "structure");
+}
+
+/* Check if CLASS_IS_PRIMITIVE(value of clas): */
+static int
+java_class_is_primitive (struct value *clas)
+{
+ struct value *vtable = value_struct_elt (&clas, NULL, "vtable", NULL, "struct");
+ CORE_ADDR i = value_as_address (vtable);
+ return (int) (i & 0x7fffffff) == (int) 0x7fffffff;
+}
+
+/* Read a GCJ Class object, and generated a gdb (TYPE_CODE_STRUCT) type. */
+
+struct type *
+type_from_class (struct value *clas)
+{
+ struct type *type;
+ char *name;
+ struct value *temp;
+ struct objfile *objfile;
+ struct value *utf8_name;
+ char *nptr;
+ CORE_ADDR addr;
+ struct block *bl;
+ int i;
+ int is_array = 0;
+
+ type = check_typedef (VALUE_TYPE (clas));
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ if (value_logical_not (clas))
+ return NULL;
+ clas = value_ind (clas);
+ }
+ addr = VALUE_ADDRESS (clas) + VALUE_OFFSET (clas);
+
+#if 0
+ get_java_class_symtab ();
+ bl = BLOCKVECTOR_BLOCK (BLOCKVECTOR (class_symtab), GLOBAL_BLOCK);
+ for (i = BLOCK_NSYMS (bl); --i >= 0;)
+ {
+ struct symbol *sym = BLOCK_SYM (bl, i);
+ if (SYMBOL_VALUE_ADDRESS (sym) == addr)
+ return SYMBOL_TYPE (sym);
+ }
+#endif
+
+ objfile = get_dynamics_objfile ();
+ if (java_class_is_primitive (clas))
+ {
+ struct value *sig;
+ temp = clas;
+ sig = value_struct_elt (&temp, NULL, "method_count", NULL, "structure");
+ return java_primitive_type (value_as_long (sig));
+ }
+
+ /* Get Class name. */
+ /* if clasloader non-null, prepend loader address. FIXME */
+ temp = clas;
+ utf8_name = value_struct_elt (&temp, NULL, "name", NULL, "structure");
+ name = get_java_utf8_name (&objfile->type_obstack, utf8_name);
+ for (nptr = name; *nptr != 0; nptr++)
+ {
+ if (*nptr == '/')
+ *nptr = '.';
+ }
+
+ type = java_lookup_class (name);
+ if (type != NULL)
+ return type;
+
+ type = alloc_type (objfile);
+ TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ INIT_CPLUS_SPECIFIC (type);
+
+ if (name[0] == '[')
+ {
+ char *signature = name;
+ int namelen = java_demangled_signature_length (signature);
+ if (namelen > strlen (name))
+ name = obstack_alloc (&objfile->type_obstack, namelen + 1);
+ java_demangled_signature_copy (name, signature);
+ name[namelen] = '\0';
+ is_array = 1;
+ temp = clas;
+ /* Set array element type. */
+ temp = value_struct_elt (&temp, NULL, "methods", NULL, "structure");
+ VALUE_TYPE (temp) = lookup_pointer_type (VALUE_TYPE (clas));
+ TYPE_TARGET_TYPE (type) = type_from_class (temp);
+ }
+
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ TYPE_TAG_NAME (type) = name;
+
+ add_class_symtab_symbol (add_class_symbol (type, addr));
+ return java_link_class_type (type, clas);
+}
+
+/* Fill in class TYPE with data from the CLAS value. */
+
+struct type *
+java_link_class_type (struct type *type, struct value *clas)
+{
+ struct value *temp;
+ char *unqualified_name;
+ char *name = TYPE_TAG_NAME (type);
+ int ninterfaces, nfields, nmethods;
+ int type_is_object = 0;
+ struct fn_field *fn_fields;
+ struct fn_fieldlist *fn_fieldlists;
+ struct value *fields;
+ struct value *methods;
+ struct value *method = NULL;
+ struct value *field = NULL;
+ int i, j;
+ struct objfile *objfile = get_dynamics_objfile ();
+ struct type *tsuper;
+
+ unqualified_name = strrchr (name, '.');
+ if (unqualified_name == NULL)
+ unqualified_name = name;
+
+ temp = clas;
+ temp = value_struct_elt (&temp, NULL, "superclass", NULL, "structure");
+ if (name != NULL && strcmp (name, "java.lang.Object") == 0)
+ {
+ tsuper = get_java_object_type ();
+ if (tsuper && TYPE_CODE (tsuper) == TYPE_CODE_PTR)
+ tsuper = TYPE_TARGET_TYPE (tsuper);
+ type_is_object = 1;
+ }
+ else
+ tsuper = type_from_class (temp);
+
+#if 1
+ ninterfaces = 0;
+#else
+ temp = clas;
+ ninterfaces = value_as_long (value_struct_elt (&temp, NULL, "interface_len", NULL, "structure"));
+#endif
+ TYPE_N_BASECLASSES (type) = (tsuper == NULL ? 0 : 1) + ninterfaces;
+ temp = clas;
+ nfields = value_as_long (value_struct_elt (&temp, NULL, "field_count", NULL, "structure"));
+ nfields += TYPE_N_BASECLASSES (type);
+ nfields++; /* Add one for dummy "class" field. */
+ TYPE_NFIELDS (type) = nfields;
+ TYPE_FIELDS (type) = (struct field *)
+ TYPE_ALLOC (type, sizeof (struct field) * nfields);
+
+ memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
+
+ TYPE_FIELD_PRIVATE_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
+
+ TYPE_FIELD_PROTECTED_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
+
+ TYPE_FIELD_IGNORE_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
+
+ TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *)
+ TYPE_ALLOC (type, B_BYTES (TYPE_N_BASECLASSES (type)));
+ B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type));
+
+ if (tsuper != NULL)
+ {
+ TYPE_BASECLASS (type, 0) = tsuper;
+ if (type_is_object)
+ SET_TYPE_FIELD_PRIVATE (type, 0);
+ }
+
+ i = strlen (name);
+ if (i > 2 && name[i - 1] == ']' && tsuper != NULL)
+ {
+ /* FIXME */
+ TYPE_LENGTH (type) = TYPE_LENGTH (tsuper) + 4; /* size with "length" */
+ }
+ else
+ {
+ temp = clas;
+ temp = value_struct_elt (&temp, NULL, "size_in_bytes", NULL, "structure");
+ TYPE_LENGTH (type) = value_as_long (temp);
+ }
+
+ fields = NULL;
+ nfields--; /* First set up dummy "class" field. */
+ SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields),
+ VALUE_ADDRESS (clas) + VALUE_OFFSET (clas));
+ TYPE_FIELD_NAME (type, nfields) = "class";
+ TYPE_FIELD_TYPE (type, nfields) = VALUE_TYPE (clas);
+ SET_TYPE_FIELD_PRIVATE (type, nfields);
+
+ for (i = TYPE_N_BASECLASSES (type); i < nfields; i++)
+ {
+ int accflags;
+ int boffset;
+ if (fields == NULL)
+ {
+ temp = clas;
+ fields = value_struct_elt (&temp, NULL, "fields", NULL, "structure");
+ field = value_ind (fields);
+ }
+ else
+ { /* Re-use field value for next field. */
+ VALUE_ADDRESS (field) += TYPE_LENGTH (VALUE_TYPE (field));
+ VALUE_LAZY (field) = 1;
+ }
+ temp = field;
+ temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
+ TYPE_FIELD_NAME (type, i) =
+ get_java_utf8_name (&objfile->type_obstack, temp);
+ temp = field;
+ accflags = value_as_long (value_struct_elt (&temp, NULL, "accflags",
+ NULL, "structure"));
+ temp = field;
+ temp = value_struct_elt (&temp, NULL, "info", NULL, "structure");
+ boffset = value_as_long (value_struct_elt (&temp, NULL, "boffset",
+ NULL, "structure"));
+ if (accflags & 0x0001) /* public access */
+ {
+ /* ??? */
+ }
+ if (accflags & 0x0002) /* private access */
+ {
+ SET_TYPE_FIELD_PRIVATE (type, i);
+ }
+ if (accflags & 0x0004) /* protected access */
+ {
+ SET_TYPE_FIELD_PROTECTED (type, i);
+ }
+ if (accflags & 0x0008) /* ACC_STATIC */
+ SET_FIELD_PHYSADDR (TYPE_FIELD (type, i), boffset);
+ else
+ TYPE_FIELD_BITPOS (type, i) = 8 * boffset;
+ if (accflags & 0x8000) /* FIELD_UNRESOLVED_FLAG */
+ {
+ TYPE_FIELD_TYPE (type, i) = get_java_object_type (); /* FIXME */
+ }
+ else
+ {
+ struct type *ftype;
+ temp = field;
+ temp = value_struct_elt (&temp, NULL, "type", NULL, "structure");
+ ftype = type_from_class (temp);
+ if (TYPE_CODE (ftype) == TYPE_CODE_STRUCT)
+ ftype = lookup_pointer_type (ftype);
+ TYPE_FIELD_TYPE (type, i) = ftype;
+ }
+ }
+
+ temp = clas;
+ nmethods = value_as_long (value_struct_elt (&temp, NULL, "method_count",
+ NULL, "structure"));
+ TYPE_NFN_FIELDS_TOTAL (type) = nmethods;
+ j = nmethods * sizeof (struct fn_field);
+ fn_fields = (struct fn_field *)
+ obstack_alloc (&dynamics_objfile->symbol_obstack, j);
+ memset (fn_fields, 0, j);
+ fn_fieldlists = (struct fn_fieldlist *)
+ alloca (nmethods * sizeof (struct fn_fieldlist));
+
+ methods = NULL;
+ for (i = 0; i < nmethods; i++)
+ {
+ char *mname;
+ int k;
+ if (methods == NULL)
+ {
+ temp = clas;
+ methods = value_struct_elt (&temp, NULL, "methods", NULL, "structure");
+ method = value_ind (methods);
+ }
+ else
+ { /* Re-use method value for next method. */
+ VALUE_ADDRESS (method) += TYPE_LENGTH (VALUE_TYPE (method));
+ VALUE_LAZY (method) = 1;
+ }
+
+ /* Get method name. */
+ temp = method;
+ temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
+ mname = get_java_utf8_name (&objfile->type_obstack, temp);
+ if (strcmp (mname, "<init>") == 0)
+ mname = unqualified_name;
+
+ /* Check for an existing method with the same name.
+ * This makes building the fn_fieldslists an O(nmethods**2)
+ * operation. That could be using hashing, but I doubt it
+ * is worth it. Note that we do maintain the order of methods
+ * in the inferior's Method table (as long as that is grouped
+ * by method name), which I think is desirable. --PB */
+ for (k = 0, j = TYPE_NFN_FIELDS (type);;)
+ {
+ if (--j < 0)
+ { /* No match - new method name. */
+ j = TYPE_NFN_FIELDS (type)++;
+ fn_fieldlists[j].name = mname;
+ fn_fieldlists[j].length = 1;
+ fn_fieldlists[j].fn_fields = &fn_fields[i];
+ k = i;
+ break;
+ }
+ if (strcmp (mname, fn_fieldlists[j].name) == 0)
+ { /* Found an existing method with the same name. */
+ int l;
+ if (mname != unqualified_name)
+ obstack_free (&objfile->type_obstack, mname);
+ mname = fn_fieldlists[j].name;
+ fn_fieldlists[j].length++;
+ k = i - k; /* Index of new slot. */
+ /* Shift intervening fn_fields (between k and i) down. */
+ for (l = i; l > k; l--)
+ fn_fields[l] = fn_fields[l - 1];
+ for (l = TYPE_NFN_FIELDS (type); --l > j;)
+ fn_fieldlists[l].fn_fields++;
+ break;
+ }
+ k += fn_fieldlists[j].length;
+ }
+ fn_fields[k].physname = "";
+ fn_fields[k].is_stub = 1;
+ fn_fields[k].type = make_function_type (java_void_type, NULL); /* FIXME */
+ TYPE_CODE (fn_fields[k].type) = TYPE_CODE_METHOD;
+ }
+
+ j = TYPE_NFN_FIELDS (type) * sizeof (struct fn_fieldlist);
+ TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
+ obstack_alloc (&dynamics_objfile->symbol_obstack, j);
+ memcpy (TYPE_FN_FIELDLISTS (type), fn_fieldlists, j);
+
+ return type;
+}
+
+static struct type *java_object_type;
+
+struct type *
+get_java_object_type (void)
+{
+ if (java_object_type == NULL)
+ {
+ struct symbol *sym;
+ sym = lookup_symbol ("java.lang.Object", NULL, STRUCT_NAMESPACE,
+ (int *) 0, (struct symtab **) NULL);
+ if (sym == NULL)
+ error ("cannot find java.lang.Object");
+ java_object_type = SYMBOL_TYPE (sym);
+ }
+ return java_object_type;
+}
+
+int
+get_java_object_header_size (void)
+{
+ struct type *objtype = get_java_object_type ();
+ if (objtype == NULL)
+ return (2 * TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ else
+ return TYPE_LENGTH (objtype);
+}
+
+int
+is_object_type (struct type *type)
+{
+ CHECK_TYPEDEF (type);
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ struct type *ttype = check_typedef (TYPE_TARGET_TYPE (type));
+ char *name;
+ if (TYPE_CODE (ttype) != TYPE_CODE_STRUCT)
+ return 0;
+ while (TYPE_N_BASECLASSES (ttype) > 0)
+ ttype = TYPE_BASECLASS (ttype, 0);
+ name = TYPE_TAG_NAME (ttype);
+ if (name != NULL && strcmp (name, "java.lang.Object") == 0)
+ return 1;
+ name = TYPE_NFIELDS (ttype) > 0 ? TYPE_FIELD_NAME (ttype, 0) : (char *) 0;
+ if (name != NULL && strcmp (name, "vtable") == 0)
+ {
+ if (java_object_type == NULL)
+ java_object_type = type;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+struct type *
+java_primitive_type (int signature)
+{
+ switch (signature)
+ {
+ case 'B':
+ return java_byte_type;
+ case 'S':
+ return java_short_type;
+ case 'I':
+ return java_int_type;
+ case 'J':
+ return java_long_type;
+ case 'Z':
+ return java_boolean_type;
+ case 'C':
+ return java_char_type;
+ case 'F':
+ return java_float_type;
+ case 'D':
+ return java_double_type;
+ case 'V':
+ return java_void_type;
+ }
+ error ("unknown signature '%c' for primitive type", (char) signature);
+}
+
+/* If name[0 .. namelen-1] is the name of a primitive Java type,
+ return that type. Otherwise, return NULL. */
+
+struct type *
+java_primitive_type_from_name (char *name, int namelen)
+{
+ switch (name[0])
+ {
+ case 'b':
+ if (namelen == 4 && memcmp (name, "byte", 4) == 0)
+ return java_byte_type;
+ if (namelen == 7 && memcmp (name, "boolean", 7) == 0)
+ return java_boolean_type;
+ break;
+ case 'c':
+ if (namelen == 4 && memcmp (name, "char", 4) == 0)
+ return java_char_type;
+ case 'd':
+ if (namelen == 6 && memcmp (name, "double", 6) == 0)
+ return java_double_type;
+ break;
+ case 'f':
+ if (namelen == 5 && memcmp (name, "float", 5) == 0)
+ return java_float_type;
+ break;
+ case 'i':
+ if (namelen == 3 && memcmp (name, "int", 3) == 0)
+ return java_int_type;
+ break;
+ case 'l':
+ if (namelen == 4 && memcmp (name, "long", 4) == 0)
+ return java_long_type;
+ break;
+ case 's':
+ if (namelen == 5 && memcmp (name, "short", 5) == 0)
+ return java_short_type;
+ break;
+ case 'v':
+ if (namelen == 4 && memcmp (name, "void", 4) == 0)
+ return java_void_type;
+ break;
+ }
+ return NULL;
+}
+
+/* Return the length (in bytes) of demangled name of the Java type
+ signature string SIGNATURE. */
+
+static int
+java_demangled_signature_length (char *signature)
+{
+ int array = 0;
+ for (; *signature == '['; signature++)
+ array += 2; /* Two chars for "[]". */
+ switch (signature[0])
+ {
+ case 'L':
+ /* Subtract 2 for 'L' and ';'. */
+ return strlen (signature) - 2 + array;
+ default:
+ return strlen (TYPE_NAME (java_primitive_type (signature[0]))) + array;
+ }
+}
+
+/* Demangle the Java type signature SIGNATURE, leaving the result in RESULT. */
+
+static void
+java_demangled_signature_copy (char *result, char *signature)
+{
+ int array = 0;
+ char *ptr;
+ int i;
+ while (*signature == '[')
+ {
+ array++;
+ signature++;
+ }
+ switch (signature[0])
+ {
+ case 'L':
+ /* Subtract 2 for 'L' and ';', but add 1 for final nul. */
+ signature++;
+ ptr = result;
+ for (; *signature != ';' && *signature != '\0'; signature++)
+ {
+ if (*signature == '/')
+ *ptr++ = '.';
+ else
+ *ptr++ = *signature;
+ }
+ break;
+ default:
+ ptr = TYPE_NAME (java_primitive_type (signature[0]));
+ i = strlen (ptr);
+ strcpy (result, ptr);
+ ptr = result + i;
+ break;
+ }
+ while (--array >= 0)
+ {
+ *ptr++ = '[';
+ *ptr++ = ']';
+ }
+}
+
+/* Return the demangled name of the Java type signature string SIGNATURE,
+ as a freshly allocated copy. */
+
+char *
+java_demangle_type_signature (char *signature)
+{
+ int length = java_demangled_signature_length (signature);
+ char *result = xmalloc (length + 1);
+ java_demangled_signature_copy (result, signature);
+ result[length] = '\0';
+ return result;
+}
+
+struct type *
+java_lookup_type (char *signature)
+{
+ switch (signature[0])
+ {
+ case 'L':
+ case '[':
+ error ("java_lookup_type not fully implemented");
+ default:
+ return java_primitive_type (signature[0]);
+ }
+}
+
+/* Return the type of TYPE followed by DIMS pairs of [ ].
+ If DIMS == 0, TYPE is returned. */
+
+struct type *
+java_array_type (struct type *type, int dims)
+{
+ struct type *range_type;
+
+ while (dims-- > 0)
+ {
+ range_type = create_range_type (NULL, builtin_type_int, 0, 0);
+ /* FIXME This is bogus! Java arrays are not gdb arrays! */
+ type = create_array_type (NULL, type, range_type);
+ }
+
+ return type;
+}
+
+/* Create a Java string in the inferior from a (Utf8) literal. */
+
+static struct value *
+java_value_string (char *ptr, int len)
+{
+ error ("not implemented - java_value_string"); /* FIXME */
+}
+
+/* Print the character C on STREAM as part of the contents of a literal
+ string whose delimiter is QUOTER. Note that that format for printing
+ characters and strings is language specific. */
+
+static void
+java_emit_char (int c, struct ui_file *stream, int quoter)
+{
+ switch (c)
+ {
+ case '\\':
+ case '\'':
+ fprintf_filtered (stream, "\\%c", c);
+ break;
+ case '\b':
+ fputs_filtered ("\\b", stream);
+ break;
+ case '\t':
+ fputs_filtered ("\\t", stream);
+ break;
+ case '\n':
+ fputs_filtered ("\\n", stream);
+ break;
+ case '\f':
+ fputs_filtered ("\\f", stream);
+ break;
+ case '\r':
+ fputs_filtered ("\\r", stream);
+ break;
+ default:
+ if (isprint (c))
+ fputc_filtered (c, stream);
+ else
+ fprintf_filtered (stream, "\\u%.4x", (unsigned int) c);
+ break;
+ }
+}
+
+static struct value *
+evaluate_subexp_java (struct type *expect_type, register struct expression *exp,
+ register int *pos, enum noside noside)
+{
+ int pc = *pos;
+ int i;
+ char *name;
+ enum exp_opcode op = exp->elts[*pos].opcode;
+ struct value *arg1;
+ struct value *arg2;
+ struct type *type;
+ switch (op)
+ {
+ case UNOP_IND:
+ if (noside == EVAL_SKIP)
+ goto standard;
+ (*pos)++;
+ arg1 = evaluate_subexp_java (NULL_TYPE, exp, pos, EVAL_NORMAL);
+ if (is_object_type (VALUE_TYPE (arg1)))
+ {
+ struct type *type;
+
+ type = type_from_class (java_class_from_object (arg1));
+ arg1 = value_cast (lookup_pointer_type (type), arg1);
+ }
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ return value_ind (arg1);
+
+ case BINOP_SUBSCRIPT:
+ (*pos)++;
+ arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+ arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ /* If the user attempts to subscript something that is not an
+ array or pointer type (like a plain int variable for example),
+ then report this as an error. */
+
+ COERCE_REF (arg1);
+ type = check_typedef (VALUE_TYPE (arg1));
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ type = check_typedef (TYPE_TARGET_TYPE (type));
+ name = TYPE_NAME (type);
+ if (name == NULL)
+ name = TYPE_TAG_NAME (type);
+ i = name == NULL ? 0 : strlen (name);
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ && i > 2 && name[i - 1] == ']')
+ {
+ CORE_ADDR address;
+ long length, index;
+ struct type *el_type;
+ char buf4[4];
+
+ struct value *clas = java_class_from_object (arg1);
+ struct value *temp = clas;
+ /* Get CLASS_ELEMENT_TYPE of the array type. */
+ temp = value_struct_elt (&temp, NULL, "methods",
+ NULL, "structure");
+ VALUE_TYPE (temp) = VALUE_TYPE (clas);
+ el_type = type_from_class (temp);
+ if (TYPE_CODE (el_type) == TYPE_CODE_STRUCT)
+ el_type = lookup_pointer_type (el_type);
+
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (el_type, VALUE_LVAL (arg1));
+ address = value_as_address (arg1);
+ address += JAVA_OBJECT_SIZE;
+ read_memory (address, buf4, 4);
+ length = (long) extract_signed_integer (buf4, 4);
+ index = (long) value_as_long (arg2);
+ if (index >= length || index < 0)
+ error ("array index (%ld) out of bounds (length: %ld)",
+ index, length);
+ address = (address + 4) + index * TYPE_LENGTH (el_type);
+ return value_at (el_type, address, NULL);
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1));
+ else
+ return value_subscript (arg1, arg2);
+ }
+ if (name)
+ error ("cannot subscript something of type `%s'", name);
+ else
+ error ("cannot subscript requested type");
+
+ case OP_STRING:
+ (*pos)++;
+ i = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (i + 1);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ return java_value_string (&exp->elts[pc + 2].string, i);
+
+ case STRUCTOP_STRUCT:
+ arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
+ /* Convert object field (such as TYPE.class) to reference. */
+ if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT)
+ arg1 = value_addr (arg1);
+ return arg1;
+ default:
+ break;
+ }
+standard:
+ return evaluate_subexp_standard (expect_type, exp, pos, noside);
+nosideret:
+ return value_from_longest (builtin_type_long, (LONGEST) 1);
+}
+
+static struct type *
+java_create_fundamental_type (struct objfile *objfile, int typeid)
+{
+ switch (typeid)
+ {
+ case FT_VOID:
+ return java_void_type;
+ case FT_BOOLEAN:
+ return java_boolean_type;
+ case FT_CHAR:
+ return java_char_type;
+ case FT_FLOAT:
+ return java_float_type;
+ case FT_DBL_PREC_FLOAT:
+ return java_double_type;
+ case FT_BYTE:
+ case FT_SIGNED_CHAR:
+ return java_byte_type;
+ case FT_SHORT:
+ case FT_SIGNED_SHORT:
+ return java_short_type;
+ case FT_INTEGER:
+ case FT_SIGNED_INTEGER:
+ return java_int_type;
+ case FT_LONG:
+ case FT_SIGNED_LONG:
+ return java_long_type;
+ }
+ return c_create_fundamental_type (objfile, typeid);
+}
+
+/* Table mapping opcodes into strings for printing operators
+ and precedences of the operators. */
+
+const struct op_print java_op_print_tab[] =
+{
+ {",", BINOP_COMMA, PREC_COMMA, 0},
+ {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
+ {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
+ {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
+ {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
+ {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
+ {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
+ {"==", BINOP_EQUAL, PREC_EQUAL, 0},
+ {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
+ {"<=", BINOP_LEQ, PREC_ORDER, 0},
+ {">=", BINOP_GEQ, PREC_ORDER, 0},
+ {">", BINOP_GTR, PREC_ORDER, 0},
+ {"<", BINOP_LESS, PREC_ORDER, 0},
+ {">>", BINOP_RSH, PREC_SHIFT, 0},
+ {"<<", BINOP_LSH, PREC_SHIFT, 0},
+#if 0
+ {">>>", BINOP_ ? ? ?, PREC_SHIFT, 0},
+#endif
+ {"+", BINOP_ADD, PREC_ADD, 0},
+ {"-", BINOP_SUB, PREC_ADD, 0},
+ {"*", BINOP_MUL, PREC_MUL, 0},
+ {"/", BINOP_DIV, PREC_MUL, 0},
+ {"%", BINOP_REM, PREC_MUL, 0},
+ {"-", UNOP_NEG, PREC_PREFIX, 0},
+ {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
+ {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
+ {"*", UNOP_IND, PREC_PREFIX, 0},
+#if 0
+ {"instanceof", ? ? ?, ? ? ?, 0},
+#endif
+ {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
+ {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
+ {NULL, 0, 0, 0}
+};
+
+const struct language_defn java_language_defn =
+{
+ "java", /* Language name */
+ language_java,
+ c_builtin_types,
+ range_check_off,
+ type_check_off,
+ case_sensitive_on,
+ java_parse,
+ java_error,
+ evaluate_subexp_java,
+ c_printchar, /* Print a character constant */
+ c_printstr, /* Function to print string constant */
+ java_emit_char, /* Function to print a single character */
+ java_create_fundamental_type, /* Create fundamental type in this language */
+ java_print_type, /* Print a type using appropriate syntax */
+ java_val_print, /* Print a value using appropriate syntax */
+ java_value_print, /* Print a top-level value */
+ {"", "", "", ""}, /* Binary format info */
+ {"0%lo", "0", "o", ""}, /* Octal format info */
+ {"%ld", "", "d", ""}, /* Decimal format info */
+ {"0x%lx", "0x", "x", ""}, /* Hex format info */
+ java_op_print_tab, /* expression operators for printing */
+ 0, /* not c-style arrays */
+ 0, /* String lower bound */
+ &builtin_type_char, /* Type of string elements */
+ LANG_MAGIC
+};
+
+void
+_initialize_java_language (void)
+{
+
+ java_int_type = init_type (TYPE_CODE_INT, 4, 0, "int", NULL);
+ java_short_type = init_type (TYPE_CODE_INT, 2, 0, "short", NULL);
+ java_long_type = init_type (TYPE_CODE_INT, 8, 0, "long", NULL);
+ java_byte_type = init_type (TYPE_CODE_INT, 1, 0, "byte", NULL);
+ java_boolean_type = init_type (TYPE_CODE_BOOL, 1, 0, "boolean", NULL);
+ java_char_type = init_type (TYPE_CODE_CHAR, 2, TYPE_FLAG_UNSIGNED, "char", NULL);
+ java_float_type = init_type (TYPE_CODE_FLT, 4, 0, "float", NULL);
+ java_double_type = init_type (TYPE_CODE_FLT, 8, 0, "double", NULL);
+ java_void_type = init_type (TYPE_CODE_VOID, 1, 0, "void", NULL);
+
+ add_language (&java_language_defn);
+}
+
+/* Cleanup code that should be run on every "run".
+ We should use make_run_cleanup to have this be called.
+ But will that mess up values in value histry? FIXME */
+
+extern void java_rerun_cleanup (void);
+void
+java_rerun_cleanup (void)
+{
+ if (class_symtab != NULL)
+ {
+ free_symtab (class_symtab); /* ??? */
+ class_symtab = NULL;
+ }
+ if (dynamics_objfile != NULL)
+ {
+ free_objfile (dynamics_objfile);
+ dynamics_objfile = NULL;
+ }
+
+ java_object_type = NULL;
+}
diff --git a/gdb/jv-lang.h b/gdb/jv-lang.h
new file mode 100644
index 00000000000..61fb9430aed
--- /dev/null
+++ b/gdb/jv-lang.h
@@ -0,0 +1,73 @@
+/* Java language support definitions for GDB, the GNU debugger.
+ Copyright 1997, 1998, 1999, 2000 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. */
+
+#ifndef JV_LANG_H
+#define JV_LANG_H
+
+struct value;
+
+extern int java_parse (void); /* Defined in jv-exp.y */
+
+extern void java_error (char *); /* Defined in jv-exp.y */
+
+/* sizeof (struct Object) */
+#define JAVA_OBJECT_SIZE (get_java_object_header_size ())
+
+extern struct type *java_int_type;
+extern struct type *java_byte_type;
+extern struct type *java_short_type;
+extern struct type *java_long_type;
+extern struct type *java_boolean_type;
+extern struct type *java_char_type;
+extern struct type *java_float_type;
+extern struct type *java_double_type;
+extern struct type *java_void_type;
+
+extern int java_val_print (struct type *, char *, int, CORE_ADDR,
+ struct ui_file *, int, int, int,
+ enum val_prettyprint);
+
+extern int java_value_print (struct value *, struct ui_file *, int,
+ enum val_prettyprint);
+
+extern struct value *java_class_from_object (struct value *);
+
+extern struct type *type_from_class (struct value *);
+
+extern struct type *java_primitive_type (int signature);
+
+extern struct type *java_primitive_type_from_name (char *, int);
+
+extern struct type *java_array_type (struct type *, int);
+
+extern struct type *get_java_object_type (void);
+extern int get_java_object_header_size (void);
+
+extern struct type *java_lookup_class (char *);
+
+extern int is_object_type (struct type *);
+
+/* Defined in jv-typeprint.c */
+extern void java_print_type (struct type *, char *, struct ui_file *, int,
+ int);
+
+extern char *java_demangle_type_signature (char *);
+
+#endif
diff --git a/gdb/jv-typeprint.c b/gdb/jv-typeprint.c
new file mode 100644
index 00000000000..893082cc187
--- /dev/null
+++ b/gdb/jv-typeprint.c
@@ -0,0 +1,343 @@
+/* Support for printing Java types for GDB, the GNU debugger.
+ Copyright 1997, 1998, 1999, 2000 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "value.h"
+#include "demangle.h"
+#include "jv-lang.h"
+#include "gdb_string.h"
+#include "typeprint.h"
+#include "c-lang.h"
+#include "cp-abi.h"
+
+/* Local functions */
+
+static void java_type_print_base (struct type * type,
+ struct ui_file *stream, int show,
+ int level);
+
+static void
+java_type_print_derivation_info (struct ui_file *stream, struct type *type)
+{
+ char *name;
+ int i;
+ int n_bases;
+ int prev;
+
+ n_bases = TYPE_N_BASECLASSES (type);
+
+ for (i = 0, prev = 0; i < n_bases; i++)
+ {
+ int kind;
+
+ kind = BASETYPE_VIA_VIRTUAL (type, i) ? 'I' : 'E';
+
+ fputs_filtered (kind == prev ? ", "
+ : kind == 'I' ? " implements "
+ : " extends ",
+ stream);
+ prev = kind;
+ name = type_name_no_tag (TYPE_BASECLASS (type, i));
+
+ fprintf_filtered (stream, "%s", name ? name : "(null)");
+ }
+
+ if (i > 0)
+ fputs_filtered (" ", stream);
+}
+
+/* Print the name of the type (or the ultimate pointer target,
+ function value or array element), or the description of a
+ structure or union.
+
+ SHOW positive means print details about the type (e.g. enum values),
+ and print structure elements passing SHOW - 1 for show.
+ SHOW negative means just print the type name or struct tag if there is one.
+ If there is no name, print something sensible but concise like
+ "struct {...}".
+ SHOW zero means just print the type name or struct tag if there is one.
+ If there is no name, print something sensible but not as concise like
+ "struct {int x; int y;}".
+
+ LEVEL is the number of spaces to indent by.
+ We increase it for some recursive calls. */
+
+static void
+java_type_print_base (struct type *type, struct ui_file *stream, int show,
+ int level)
+{
+ register int i;
+ register int len;
+ char *mangled_name;
+ char *demangled_name;
+ QUIT;
+
+ wrap_here (" ");
+
+ if (type == NULL)
+ {
+ fputs_filtered ("<type unknown>", stream);
+ return;
+ }
+
+ /* When SHOW is zero or less, and there is a valid type name, then always
+ just print the type name directly from the type. */
+
+ if (show <= 0
+ && TYPE_NAME (type) != NULL)
+ {
+ fputs_filtered (TYPE_NAME (type), stream);
+ return;
+ }
+
+ CHECK_TYPEDEF (type);
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_PTR:
+ java_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
+ break;
+
+ case TYPE_CODE_STRUCT:
+ if (TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[')
+ { /* array type */
+ char *name = java_demangle_type_signature (TYPE_TAG_NAME (type));
+ fputs_filtered (name, stream);
+ xfree (name);
+ break;
+ }
+
+ if (show >= 0)
+ fprintf_filtered (stream, "class ");
+
+ if (TYPE_TAG_NAME (type) != NULL)
+ {
+ fputs_filtered (TYPE_TAG_NAME (type), stream);
+ if (show > 0)
+ fputs_filtered (" ", stream);
+ }
+
+ wrap_here (" ");
+
+ if (show < 0)
+ {
+ /* If we just printed a tag name, no need to print anything else. */
+ if (TYPE_TAG_NAME (type) == NULL)
+ fprintf_filtered (stream, "{...}");
+ }
+ else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
+ {
+ java_type_print_derivation_info (stream, type);
+
+ fprintf_filtered (stream, "{\n");
+ if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
+ {
+ if (TYPE_STUB (type))
+ fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
+ else
+ fprintfi_filtered (level + 4, stream, "<no data fields>\n");
+ }
+
+ /* If there is a base class for this type,
+ do not print the field that it occupies. */
+
+ len = TYPE_NFIELDS (type);
+ for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+ {
+ QUIT;
+ /* Don't print out virtual function table. */
+ if (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5)
+ && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
+ continue;
+
+ /* Don't print the dummy field "class". */
+ if (STREQN (TYPE_FIELD_NAME (type, i), "class", 5))
+ continue;
+
+ print_spaces_filtered (level + 4, stream);
+
+ if (HAVE_CPLUS_STRUCT (type))
+ {
+ if (TYPE_FIELD_PROTECTED (type, i))
+ fprintf_filtered (stream, "protected ");
+ else if (TYPE_FIELD_PRIVATE (type, i))
+ fprintf_filtered (stream, "private ");
+ else
+ fprintf_filtered (stream, "public ");
+ }
+
+ if (TYPE_FIELD_STATIC (type, i))
+ fprintf_filtered (stream, "static ");
+
+ java_print_type (TYPE_FIELD_TYPE (type, i),
+ TYPE_FIELD_NAME (type, i),
+ stream, show - 1, level + 4);
+
+ fprintf_filtered (stream, ";\n");
+ }
+
+ /* If there are both fields and methods, put a space between. */
+ len = TYPE_NFN_FIELDS (type);
+ if (len)
+ fprintf_filtered (stream, "\n");
+
+ /* Print out the methods */
+
+ for (i = 0; i < len; i++)
+ {
+ struct fn_field *f;
+ int j;
+ char *method_name;
+ char *name;
+ int is_constructor;
+ int n_overloads;
+
+ f = TYPE_FN_FIELDLIST1 (type, i);
+ n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i);
+ method_name = TYPE_FN_FIELDLIST_NAME (type, i);
+ name = type_name_no_tag (type);
+ is_constructor = name && STREQ (method_name, name);
+
+ for (j = 0; j < n_overloads; j++)
+ {
+ char *physname;
+ int is_full_physname_constructor;
+
+ physname = TYPE_FN_FIELD_PHYSNAME (f, j);
+
+ is_full_physname_constructor
+ = (is_constructor_name (physname)
+ || is_destructor_name (physname));
+
+ QUIT;
+
+ print_spaces_filtered (level + 4, stream);
+
+ if (TYPE_FN_FIELD_PROTECTED (f, j))
+ fprintf_filtered (stream, "protected ");
+ else if (TYPE_FN_FIELD_PRIVATE (f, j))
+ fprintf_filtered (stream, "private ");
+ else if (TYPE_FN_FIELD_PUBLIC (f, j))
+ fprintf_filtered (stream, "public ");
+
+ if (TYPE_FN_FIELD_ABSTRACT (f, j))
+ fprintf_filtered (stream, "abstract ");
+ if (TYPE_FN_FIELD_STATIC (f, j))
+ fprintf_filtered (stream, "static ");
+ if (TYPE_FN_FIELD_FINAL (f, j))
+ fprintf_filtered (stream, "final ");
+ if (TYPE_FN_FIELD_SYNCHRONIZED (f, j))
+ fprintf_filtered (stream, "synchronized ");
+ if (TYPE_FN_FIELD_NATIVE (f, j))
+ fprintf_filtered (stream, "native ");
+
+ if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
+ {
+ /* Keep GDB from crashing here. */
+ fprintf_filtered (stream, "<undefined type> %s;\n",
+ TYPE_FN_FIELD_PHYSNAME (f, j));
+ break;
+ }
+ else if (!is_constructor && !is_full_physname_constructor)
+ {
+ type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
+ "", stream, -1);
+ fputs_filtered (" ", stream);
+ }
+
+ if (TYPE_FN_FIELD_STUB (f, j))
+ /* Build something we can demangle. */
+ mangled_name = gdb_mangle_name (type, i, j);
+ else
+ mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j);
+
+ demangled_name =
+ cplus_demangle (mangled_name,
+ DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
+
+ if (demangled_name == NULL)
+ demangled_name = xstrdup (mangled_name);
+
+ {
+ char *demangled_no_class;
+ char *ptr;
+
+ ptr = demangled_no_class = demangled_name;
+
+ while (1)
+ {
+ char c;
+
+ c = *ptr++;
+
+ if (c == 0 || c == '(')
+ break;
+ if (c == '.')
+ demangled_no_class = ptr;
+ }
+
+ fputs_filtered (demangled_no_class, stream);
+ xfree (demangled_name);
+ }
+
+ if (TYPE_FN_FIELD_STUB (f, j))
+ xfree (mangled_name);
+
+ fprintf_filtered (stream, ";\n");
+ }
+ }
+
+ fprintfi_filtered (level, stream, "}");
+ }
+ break;
+
+ default:
+ c_type_print_base (type, stream, show, level);
+ }
+}
+
+/* LEVEL is the depth to indent lines by. */
+
+extern void c_type_print_varspec_suffix (struct type *, struct ui_file *,
+ int, int, int);
+
+void
+java_print_type (struct type *type, char *varstring, struct ui_file *stream,
+ int show, int level)
+{
+ int demangled_args;
+
+ java_type_print_base (type, stream, show, level);
+
+ if (varstring != NULL && *varstring != '\0')
+ {
+ fputs_filtered (" ", stream);
+ fputs_filtered (varstring, stream);
+ }
+
+ /* For demangled function names, we have the arglist as part of the name,
+ so don't print an additional pair of ()'s */
+
+ demangled_args = strchr (varstring, '(') != NULL;
+ c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
+}
diff --git a/gdb/jv-valprint.c b/gdb/jv-valprint.c
new file mode 100644
index 00000000000..f0fd0f5ea25
--- /dev/null
+++ b/gdb/jv-valprint.c
@@ -0,0 +1,526 @@
+/* Support for printing Java values for GDB, the GNU debugger.
+ Copyright 1997, 1998, 1999, 2000 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "expression.h"
+#include "value.h"
+#include "demangle.h"
+#include "valprint.h"
+#include "language.h"
+#include "jv-lang.h"
+#include "c-lang.h"
+#include "annotate.h"
+
+/* Local functions */
+
+static void java_print_value_fields (struct type * type, char *valaddr,
+ CORE_ADDR address,
+ struct ui_file *stream, int format,
+ int recurse,
+ enum val_prettyprint pretty);
+
+
+int
+java_value_print (struct value *val, struct ui_file *stream, int format,
+ enum val_prettyprint pretty)
+{
+ struct type *type;
+ CORE_ADDR address;
+ int i;
+ char *name;
+
+ type = VALUE_TYPE (val);
+ address = VALUE_ADDRESS (val) + VALUE_OFFSET (val);
+
+ if (is_object_type (type))
+ {
+ CORE_ADDR obj_addr;
+
+ /* Get the run-time type, and cast the object into that */
+
+ obj_addr = unpack_pointer (type, VALUE_CONTENTS (val));
+
+ if (obj_addr != 0)
+ {
+ type = type_from_class (java_class_from_object (val));
+ type = lookup_pointer_type (type);
+
+ val = value_at (type, address, NULL);
+ }
+ }
+
+ if (TYPE_CODE (type) == TYPE_CODE_PTR && !value_logical_not (val))
+ type_print (TYPE_TARGET_TYPE (type), "", stream, -1);
+
+ name = TYPE_TAG_NAME (type);
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT && name != NULL
+ && (i = strlen (name), name[i - 1] == ']'))
+ {
+ char buf4[4];
+ long length;
+ unsigned int things_printed = 0;
+ int reps;
+ struct type *el_type = java_primitive_type_from_name (name, i - 2);
+
+ i = 0;
+ read_memory (address + JAVA_OBJECT_SIZE, buf4, 4);
+
+ length = (long) extract_signed_integer (buf4, 4);
+ fprintf_filtered (stream, "{length: %ld", length);
+
+ if (el_type == NULL)
+ {
+ CORE_ADDR element;
+ CORE_ADDR next_element = -1; /* dummy initial value */
+
+ address += JAVA_OBJECT_SIZE + 4; /* Skip object header and length. */
+
+ while (i < length && things_printed < print_max)
+ {
+ char *buf;
+
+ buf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT);
+ fputs_filtered (", ", stream);
+ wrap_here (n_spaces (2));
+
+ if (i > 0)
+ element = next_element;
+ else
+ {
+ read_memory (address, buf, sizeof (buf));
+ address += TARGET_PTR_BIT / HOST_CHAR_BIT;
+ element = extract_address (buf, sizeof (buf));
+ }
+
+ for (reps = 1; i + reps < length; reps++)
+ {
+ read_memory (address, buf, sizeof (buf));
+ address += TARGET_PTR_BIT / HOST_CHAR_BIT;
+ next_element = extract_address (buf, sizeof (buf));
+ if (next_element != element)
+ break;
+ }
+
+ if (reps == 1)
+ fprintf_filtered (stream, "%d: ", i);
+ else
+ fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1);
+
+ if (element == 0)
+ fprintf_filtered (stream, "null");
+ else
+ fprintf_filtered (stream, "@%s", paddr_nz (element));
+
+ things_printed++;
+ i += reps;
+ }
+ }
+ else
+ {
+ struct value *v = allocate_value (el_type);
+ struct value *next_v = allocate_value (el_type);
+
+ VALUE_ADDRESS (v) = address + JAVA_OBJECT_SIZE + 4;
+ VALUE_ADDRESS (next_v) = VALUE_ADDRESS (v);
+
+ while (i < length && things_printed < print_max)
+ {
+ fputs_filtered (", ", stream);
+ wrap_here (n_spaces (2));
+
+ if (i > 0)
+ {
+ struct value *tmp;
+
+ tmp = next_v;
+ next_v = v;
+ v = tmp;
+ }
+ else
+ {
+ VALUE_LAZY (v) = 1;
+ VALUE_OFFSET (v) = 0;
+ }
+
+ VALUE_OFFSET (next_v) = VALUE_OFFSET (v);
+
+ for (reps = 1; i + reps < length; reps++)
+ {
+ VALUE_LAZY (next_v) = 1;
+ VALUE_OFFSET (next_v) += TYPE_LENGTH (el_type);
+ if (memcmp (VALUE_CONTENTS (v), VALUE_CONTENTS (next_v),
+ TYPE_LENGTH (el_type)) != 0)
+ break;
+ }
+
+ if (reps == 1)
+ fprintf_filtered (stream, "%d: ", i);
+ else
+ fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1);
+
+ val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0,
+ stream, format, 2, 1, pretty);
+
+ things_printed++;
+ i += reps;
+ }
+ }
+
+ if (i < length)
+ fprintf_filtered (stream, "...");
+
+ fprintf_filtered (stream, "}");
+
+ return 0;
+ }
+
+ /* If it's type String, print it */
+
+ if (TYPE_CODE (type) == TYPE_CODE_PTR
+ && TYPE_TARGET_TYPE (type)
+ && TYPE_NAME (TYPE_TARGET_TYPE (type))
+ && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "java.lang.String") == 0
+ && (format == 0 || format == 's')
+ && address != 0
+ && value_as_address (val) != 0)
+ {
+ struct value *data_val;
+ CORE_ADDR data;
+ struct value *boffset_val;
+ unsigned long boffset;
+ struct value *count_val;
+ unsigned long count;
+ struct value *mark;
+
+ mark = value_mark (); /* Remember start of new values */
+
+ data_val = value_struct_elt (&val, NULL, "data", NULL, NULL);
+ data = value_as_address (data_val);
+
+ boffset_val = value_struct_elt (&val, NULL, "boffset", NULL, NULL);
+ boffset = value_as_address (boffset_val);
+
+ count_val = value_struct_elt (&val, NULL, "count", NULL, NULL);
+ count = value_as_address (count_val);
+
+ value_free_to_mark (mark); /* Release unnecessary values */
+
+ val_print_string (data + boffset, count, 2, stream);
+
+ return 0;
+ }
+
+ return (val_print (type, VALUE_CONTENTS (val), 0, address,
+ stream, format, 1, 0, pretty));
+}
+
+/* TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the
+ same meanings as in cp_print_value and c_val_print.
+
+ DONT_PRINT is an array of baseclass types that we
+ should not print, or zero if called from top level. */
+
+static void
+java_print_value_fields (struct type *type, char *valaddr, CORE_ADDR address,
+ struct ui_file *stream, int format, int recurse,
+ enum val_prettyprint pretty)
+{
+ int i, len, n_baseclasses;
+
+ CHECK_TYPEDEF (type);
+
+ fprintf_filtered (stream, "{");
+ len = TYPE_NFIELDS (type);
+ n_baseclasses = TYPE_N_BASECLASSES (type);
+
+ if (n_baseclasses > 0)
+ {
+ int i, n_baseclasses = TYPE_N_BASECLASSES (type);
+
+ for (i = 0; i < n_baseclasses; i++)
+ {
+ int boffset;
+ struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
+ char *basename = TYPE_NAME (baseclass);
+ char *base_valaddr;
+
+ if (BASETYPE_VIA_VIRTUAL (type, i))
+ continue;
+
+ if (basename != NULL && strcmp (basename, "java.lang.Object") == 0)
+ continue;
+
+ boffset = 0;
+
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 * (recurse + 1), stream);
+ }
+ fputs_filtered ("<", stream);
+ /* Not sure what the best notation is in the case where there is no
+ baseclass name. */
+ fputs_filtered (basename ? basename : "", stream);
+ fputs_filtered ("> = ", stream);
+
+ base_valaddr = valaddr;
+
+ java_print_value_fields (baseclass, base_valaddr, address + boffset,
+ stream, format, recurse + 1, pretty);
+ fputs_filtered (", ", stream);
+
+ flush_it:
+ ;
+ }
+
+ }
+
+ if (!len && n_baseclasses == 1)
+ fprintf_filtered (stream, "<No data fields>");
+ else
+ {
+ extern int inspect_it;
+ int fields_seen = 0;
+
+ for (i = n_baseclasses; i < len; i++)
+ {
+ /* If requested, skip printing of static fields. */
+ if (TYPE_FIELD_STATIC (type, i))
+ {
+ char *name = TYPE_FIELD_NAME (type, i);
+ if (!static_field_print)
+ continue;
+ if (name != NULL && strcmp (name, "class") == 0)
+ continue;
+ }
+ if (fields_seen)
+ fprintf_filtered (stream, ", ");
+ else if (n_baseclasses > 0)
+ {
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ fputs_filtered ("members of ", stream);
+ fputs_filtered (type_name_no_tag (type), stream);
+ fputs_filtered (": ", stream);
+ }
+ }
+ fields_seen = 1;
+
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ else
+ {
+ wrap_here (n_spaces (2 + 2 * recurse));
+ }
+ if (inspect_it)
+ {
+ if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)
+ fputs_filtered ("\"( ptr \"", stream);
+ else
+ fputs_filtered ("\"( nodef \"", stream);
+ if (TYPE_FIELD_STATIC (type, i))
+ fputs_filtered ("static ", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
+ fputs_filtered ("\" \"", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
+ fputs_filtered ("\") \"", stream);
+ }
+ else
+ {
+ annotate_field_begin (TYPE_FIELD_TYPE (type, i));
+
+ if (TYPE_FIELD_STATIC (type, i))
+ fputs_filtered ("static ", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
+ annotate_field_name_end ();
+ fputs_filtered (": ", stream);
+ annotate_field_value ();
+ }
+
+ if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i))
+ {
+ struct value *v;
+
+ /* Bitfields require special handling, especially due to byte
+ order problems. */
+ if (TYPE_FIELD_IGNORE (type, i))
+ {
+ fputs_filtered ("<optimized out or zero length>", stream);
+ }
+ else
+ {
+ v = value_from_longest (TYPE_FIELD_TYPE (type, i),
+ unpack_field_as_long (type, valaddr, i));
+
+ val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0,
+ 0, stream, format, 0, recurse + 1, pretty);
+ }
+ }
+ else
+ {
+ if (TYPE_FIELD_IGNORE (type, i))
+ {
+ fputs_filtered ("<optimized out or zero length>", stream);
+ }
+ else if (TYPE_FIELD_STATIC (type, i))
+ {
+ struct value *v = value_static_field (type, i);
+ if (v == NULL)
+ fputs_filtered ("<optimized out>", stream);
+ else
+ {
+ struct type *t = check_typedef (VALUE_TYPE (v));
+ if (TYPE_CODE (t) == TYPE_CODE_STRUCT)
+ v = value_addr (v);
+ val_print (VALUE_TYPE (v),
+ VALUE_CONTENTS (v), 0, VALUE_ADDRESS (v),
+ stream, format, 0, recurse + 1, pretty);
+ }
+ }
+ else if (TYPE_FIELD_TYPE (type, i) == NULL)
+ fputs_filtered ("<unknown type>", stream);
+ else
+ {
+ val_print (TYPE_FIELD_TYPE (type, i),
+ valaddr + TYPE_FIELD_BITPOS (type, i) / 8, 0,
+ address + TYPE_FIELD_BITPOS (type, i) / 8,
+ stream, format, 0, recurse + 1, pretty);
+ }
+ }
+ annotate_field_end ();
+ }
+
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 * recurse, stream);
+ }
+ }
+ fprintf_filtered (stream, "}");
+}
+
+/* Print data of type TYPE located at VALADDR (within GDB), which came from
+ the inferior at address ADDRESS, onto stdio stream STREAM according to
+ FORMAT (a letter or 0 for natural format). The data at VALADDR is in
+ target byte order.
+
+ If the data are a string pointer, returns the number of string characters
+ printed.
+
+ If DEREF_REF is nonzero, then dereference references, otherwise just print
+ them like pointers.
+
+ The PRETTY parameter controls prettyprinting. */
+
+int
+java_val_print (struct type *type, char *valaddr, int embedded_offset,
+ CORE_ADDR address, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
+{
+ register unsigned int i = 0; /* Number of characters printed */
+ struct type *target_type;
+ CORE_ADDR addr;
+
+ CHECK_TYPEDEF (type);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_PTR:
+ if (format && format != 's')
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ break;
+ }
+#if 0
+ if (vtblprint && cp_is_vtbl_ptr_type (type))
+ {
+ /* Print the unmangled name if desired. */
+ /* Print vtable entry - we only get here if we ARE using
+ -fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */
+ print_address_demangle (extract_address (valaddr, TYPE_LENGTH (type)),
+ stream, demangle);
+ break;
+ }
+#endif
+ addr = unpack_pointer (type, valaddr);
+ if (addr == 0)
+ {
+ fputs_filtered ("null", stream);
+ return i;
+ }
+ target_type = check_typedef (TYPE_TARGET_TYPE (type));
+
+ if (TYPE_CODE (target_type) == TYPE_CODE_FUNC)
+ {
+ /* Try to print what function it points to. */
+ print_address_demangle (addr, stream, demangle);
+ /* Return value is irrelevant except for string pointers. */
+ return (0);
+ }
+
+ if (addressprint && format != 's')
+ {
+ fputs_filtered ("@", stream);
+ print_longest (stream, 'x', 0, (ULONGEST) addr);
+ }
+
+ return i;
+
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_INT:
+ /* Can't just call c_val_print because that prints bytes as C
+ chars. */
+ format = format ? format : output_format;
+ if (format)
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ else if (TYPE_CODE (type) == TYPE_CODE_CHAR
+ || (TYPE_CODE (type) == TYPE_CODE_INT
+ && TYPE_LENGTH (type) == 2
+ && strcmp (TYPE_NAME (type), "char") == 0))
+ LA_PRINT_CHAR ((int) unpack_long (type, valaddr), stream);
+ else
+ val_print_type_code_int (type, valaddr, stream);
+ break;
+
+ case TYPE_CODE_STRUCT:
+ java_print_value_fields (type, valaddr, address, stream, format,
+ recurse, pretty);
+ break;
+
+ default:
+ return c_val_print (type, valaddr, embedded_offset, address, stream,
+ format, deref_ref, recurse, pretty);
+ }
+
+ return 0;
+}
diff --git a/gdb/kod-cisco.c b/gdb/kod-cisco.c
new file mode 100644
index 00000000000..de2b4502666
--- /dev/null
+++ b/gdb/kod-cisco.c
@@ -0,0 +1,317 @@
+/* Kernel Object Display facility for Cisco
+ Copyright 1999, 2000 Free Software Foundation, Inc.
+
+ Written by Tom Tromey <tromey@cygnus.com>.
+
+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 "defs.h"
+#include "gdb_string.h"
+#include "kod.h"
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+/* Define this to turn off communication with target. */
+/* #define FAKE_PACKET */
+
+/* Size of buffer used for remote communication. */
+#define PBUFSIZ 400
+
+/* Pointers to gdb callbacks. */
+static void (*gdb_kod_display) (char *);
+static void (*gdb_kod_query) (char *, char *, int *);
+
+
+
+/* Initialize and return library name and version.
+ The gdb side of KOD, kod.c, passes us two functions: one for
+ displaying output (presumably to the user) and the other for
+ querying the target. */
+char *
+cisco_kod_open (kod_display_callback_ftype *display_func,
+ kod_query_callback_ftype *query_func)
+{
+ char buffer[PBUFSIZ];
+ int bufsiz = PBUFSIZ;
+ int i, count;
+
+ gdb_kod_display = display_func;
+ gdb_kod_query = query_func;
+
+ /* Get the OS info, and check the version field. This is the stub
+ version, which we use to see whether we will understand what
+ comes back. This is lame, but the `qKoL' request doesn't
+ actually provide enough configurability.
+
+ Right now the only defined version number is `0.0.0'.
+ This stub supports qKoI and the `a' (any) object requests qKaL
+ and qKaI. Each `a' object is returned as a 4-byte integer ID.
+ An info request on an object returns a pair of 4-byte integers;
+ the first is the object pointer and the second is the thread ID. */
+
+#ifndef FAKE_PACKET
+ (*gdb_kod_query) ("oI;", buffer, &bufsiz);
+#else
+ strcpy (buffer, "Cisco IOS/Classic/13.4 0.0.0");
+#endif
+
+ count = 2;
+ for (i = 0; count && buffer[i] != '\0'; ++i)
+ {
+ if (buffer[i] == ' ')
+ --count;
+ }
+
+ if (buffer[i] == '\0')
+ error ("Remote returned malformed packet\n");
+ if (strcmp (&buffer[i], "0.0.0"))
+ error ("Remote returned unknown stub version: %s\n", &buffer[i]);
+
+ /* Return name, version, and description. I hope we have enough
+ space. */
+ return (xstrdup ("gdbkodcisco v0.0.0 - Cisco Kernel Object Display"));
+}
+
+/* Close the connection. */
+void
+cisco_kod_close (void)
+{
+}
+
+/* Print a "bad packet" message. */
+static void
+bad_packet (void)
+{
+ (*gdb_kod_display) ("Remote target returned malformed packet.\n");
+}
+
+/* Print information about currently known kernel objects.
+ We currently ignore the argument. There is only one mode of
+ querying the Cisco kernel: we ask for a dump of everything, and
+ it returns it. */
+void
+cisco_kod_request (char *arg, int from_tty)
+{
+ char buffer[PBUFSIZ], command[PBUFSIZ];
+ int done = 0, i;
+ int fail = 0;
+
+ char **sync_ids = NULL;
+ int sync_len = 0;
+ int sync_next = 0;
+ char *prev_id = NULL;
+
+ if (! arg || strcmp (arg, "any"))
+ {
+ /* "Top-level" command. This is really silly, but it also seems
+ to be how KOD is defined. */
+ /* Even sillier is the fact that this first line must start
+ with the word "List". See kod.tcl. */
+ (*gdb_kod_display) ("List of Cisco Kernel Objects\n");
+ (*gdb_kod_display) ("Object\tDescription\n");
+ (*gdb_kod_display) ("any\tAny and all objects\n");
+ return;
+ }
+
+ while (! done)
+ {
+ int off = 0; /* Where we are in the string. */
+ long count; /* Number of objects in this packet. */
+ int bufsiz = PBUFSIZ;
+ char *s_end;
+
+ strcpy (command, "aL");
+ if (prev_id)
+ {
+ strcat (command, ",");
+ strcat (command, prev_id);
+ }
+ strcat (command, ";");
+
+#ifndef FAKE_PACKET
+ /* We talk to the target by calling through the query function
+ passed to us when we were initialized. */
+ (*gdb_kod_query) (command, buffer, &bufsiz);
+#else
+ /* Fake up a multi-part packet. */
+ if (! strncmp (&command[3], "a500005a", 8))
+ strcpy (buffer, "KAL,01,1,f500005f;f500005f;");
+ else
+ strcpy (buffer, "KAL,02,0,a500005a;a500005a;de02869f;");
+#endif
+
+ /* Empty response is an error. */
+ if (strlen (buffer) == 0)
+ {
+ (*gdb_kod_display) ("Remote target did not recognize kernel object query command.\n");
+ fail = 1;
+ break;
+ }
+
+ /* If we don't get a `K' response then the buffer holds the
+ target's error message. */
+ if (buffer[0] != 'K')
+ {
+ (*gdb_kod_display) (buffer);
+ fail = 1;
+ break;
+ }
+
+ /* Make sure we get the response we expect. */
+ if (strncmp (buffer, "KAL,", 4))
+ {
+ bad_packet ();
+ fail = 1;
+ break;
+ }
+ off += 4;
+
+ /* Parse out the count. We expect to convert exactly two
+ characters followed by a comma. */
+ count = strtol (&buffer[off], &s_end, 16);
+ if (s_end - &buffer[off] != 2 || buffer[off + 2] != ',')
+ {
+ bad_packet ();
+ fail = 1;
+ break;
+ }
+ off += 3;
+
+ /* Parse out the `done' flag. */
+ if ((buffer[off] != '0' && buffer[off] != '1')
+ || buffer[off + 1] != ',')
+ {
+ bad_packet ();
+ fail = 1;
+ break;
+ }
+ done = buffer[off] == '1';
+ off += 2;
+
+ /* Id of the last item; we might this to construct the next
+ request. */
+ prev_id = &buffer[off];
+ if (strlen (prev_id) < 8 || buffer[off + 8] != ';')
+ {
+ bad_packet ();
+ fail = 1;
+ break;
+ }
+ buffer[off + 8] = '\0';
+ off += 9;
+
+ sync_len += count;
+ sync_ids = (char **) xrealloc (sync_ids, sync_len * sizeof (char *));
+
+ for (i = 0; i < count; ++i)
+ {
+ if (strlen (&buffer[off]) < 8 || buffer[off + 8] != ';')
+ {
+ bad_packet ();
+ fail = 1;
+ break;
+ }
+ buffer[off + 8] = '\0';
+ sync_ids[sync_next++] = xstrdup (&buffer[off]);
+ off += 9;
+ }
+
+ if (buffer[off] != '\0')
+ {
+ bad_packet ();
+ fail = 1;
+ break;
+ }
+ }
+
+ /* We've collected all the sync object IDs. Now query to get the
+ specific information, and arrange to print this info. */
+ if (! fail)
+ {
+ (*gdb_kod_display) ("Object ID\tObject Pointer\tThread ID\n");
+
+ for (i = 0; i < sync_next; ++i)
+ {
+ int off = 0;
+ int bufsiz = PBUFSIZ;
+
+ /* For now assume a query can be accomplished in a single
+ transaction. This is implied in the protocol document.
+ See comments above, and the KOD protocol document, to
+ understand the parsing of the return value. */
+ strcpy (command, "aI,");
+ strcat (command, sync_ids[i]);
+ strcat (command, ";");
+
+#ifndef FAKE_PACKET
+ (*gdb_kod_query) (command, buffer, &bufsiz);
+#else
+ strcpy (buffer, "KAI,");
+ strcat (buffer, sync_ids[i]);
+ strcat (buffer, ",ffef00a0,cd00123d;");
+#endif
+
+ if (strlen (buffer) == 0)
+ {
+ (*gdb_kod_display) ("Remote target did not recognize KOD command.\n");
+ break;
+ }
+
+ if (strncmp (buffer, "KAI,", 4))
+ {
+ bad_packet ();
+ break;
+ }
+ off += 4;
+
+ if (strncmp (&buffer[off], sync_ids[i], 8)
+ || buffer[off + 8] != ',')
+ {
+ bad_packet ();
+ break;
+ }
+ off += 9;
+
+ /* Extract thread id and sync object pointer. */
+ if (strlen (&buffer[off]) != 2 * 8 + 2
+ || buffer[off + 8] != ','
+ || buffer[off + 17] != ';')
+ {
+ bad_packet ();
+ break;
+ }
+
+ buffer[off + 8] = '\0';
+ buffer[off + 17] = '\0';
+
+ /* Display the result. */
+ (*gdb_kod_display) (sync_ids[i]);
+ (*gdb_kod_display) ("\t");
+ (*gdb_kod_display) (&buffer[off]);
+ (*gdb_kod_display) ("\t");
+ (*gdb_kod_display) (&buffer[off + 9]);
+ (*gdb_kod_display) ("\n");
+ }
+ }
+
+ /* Free memory. */
+ for (i = 0; i < sync_next; ++i)
+ xfree (sync_ids[i]);
+ xfree (sync_ids);
+}
diff --git a/gdb/kod.c b/gdb/kod.c
new file mode 100644
index 00000000000..8f565bb8c36
--- /dev/null
+++ b/gdb/kod.c
@@ -0,0 +1,239 @@
+/* Kernel Object Display generic routines and callbacks
+ Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+
+ Written by Fernando Nasser <fnasser@cygnus.com> for Cygnus Solutions.
+
+ 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 "defs.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "gdb_string.h"
+#include "kod.h"
+
+/* Prototypes for exported functions. */
+void _initialize_kod (void);
+
+/* Prototypes for local functions. */
+static void info_kod_command (char *, int);
+static void load_kod_library (char *);
+
+/* Prototypes for callbacks. These are passed into the KOD modules. */
+static void gdb_kod_display (char *);
+static void gdb_kod_query (char *, char *, int *);
+
+/* These functions are imported from the KOD module.
+
+ gdb_kod_open - initiates the KOD connection to the remote. The
+ first argument is the display function the module should use to
+ communicate with the user. The second argument is the query
+ function the display should use to communicate with the target.
+ This should call error() if there is an error. Otherwise it should
+ return a malloc()d string of the form:
+
+ NAME VERSION - DESCRIPTION
+
+ Neither NAME nor VERSION should contain a hyphen.
+
+
+ gdb_kod_request - This is used when the user enters an "info
+ <module>" request. The remaining arguments are passed as the first
+ argument. The second argument is the standard `from_tty'
+ argument.
+
+
+ gdb_kod_close - This is called when the KOD connection to the
+ remote should be terminated. */
+
+static char *(*gdb_kod_open) (kod_display_callback_ftype *display,
+ kod_query_callback_ftype *query);
+static void (*gdb_kod_request) (char *, int);
+static void (*gdb_kod_close) ();
+
+
+/* Name of inferior's operating system. */
+char *operating_system;
+
+/* We save a copy of the OS so that we can properly reset when
+ switching OS's. */
+static char *old_operating_system;
+
+/* Print a line of data generated by the module. */
+
+static void
+gdb_kod_display (char *arg)
+{
+ printf_filtered ("%s", arg);
+}
+
+/* Queries the target on behalf of the module. */
+
+static void
+gdb_kod_query (char *arg, char *result, int *maxsiz)
+{
+ int bufsiz = 0;
+
+ /* Check if current target has remote_query capabilities.
+ If not, it does not have kod either. */
+ if (! current_target.to_query)
+ {
+ strcpy (result,
+ "ERR: Kernel Object Display not supported by current target\n");
+ return;
+ }
+
+ /* Just get the maximum buffer size. */
+ target_query ((int) 'K', 0, 0, &bufsiz);
+
+ /* Check if *we* were called just for getting the buffer size. */
+ if (*maxsiz == 0)
+ {
+ *maxsiz = bufsiz;
+ strcpy (result, "OK");
+ return;
+ }
+
+ /* Check if caller can handle a buffer this large, if not, adjust. */
+ if (bufsiz > *maxsiz)
+ bufsiz = *maxsiz;
+
+ /* See if buffer can hold the query (usually it can, as the query is
+ short). */
+ if (strlen (arg) >= bufsiz)
+ error ("kod: query argument too long");
+
+ /* Send actual request. */
+ if (target_query ((int) 'K', arg, result, &bufsiz))
+ strcpy (result, "ERR: remote query failed");
+}
+
+/* Print name of kod command after selecting the appropriate kod
+ formatting library module. As a side effect we create a new "info"
+ subcommand which is what the user actually uses to query the OS. */
+
+static void
+kod_set_os (char *arg, int from_tty, struct cmd_list_element *command)
+{
+ char *p;
+
+ /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones
+ the set command passed as a parameter. The clone operation will
+ include (BUG?) any ``set'' command callback, if present.
+ Commands like ``info set'' call all the ``show'' command
+ callbacks. Unfortunatly, for ``show'' commands cloned from
+ ``set'', this includes callbacks belonging to ``set'' commands.
+ Making this worse, this only occures if add_show_from_set() is
+ called after add_cmd_sfunc() (BUG?). */
+
+ if (cmd_type (command) != set_cmd)
+ return;
+
+ /* If we had already had an open OS, close it. */
+ if (gdb_kod_close)
+ (*gdb_kod_close) ();
+
+ /* Also remove the old OS's command. */
+ if (old_operating_system)
+ {
+ delete_cmd (old_operating_system, &infolist);
+ xfree (old_operating_system);
+ }
+
+ if (! operating_system || ! *operating_system)
+ {
+ /* If user set operating system to empty, we want to forget we
+ had a module open. Setting these variables is just nice for
+ debugging and clarity. */
+ gdb_kod_open = NULL;
+ gdb_kod_request = NULL;
+ gdb_kod_close = NULL;
+ }
+ else
+ {
+ char *kodlib;
+
+ old_operating_system = xstrdup (operating_system);
+
+ load_kod_library (operating_system);
+
+ kodlib = (*gdb_kod_open) (gdb_kod_display, gdb_kod_query);
+
+ /* Add kod related info commands to gdb. */
+ add_info (operating_system, info_kod_command,
+ "Displays information about Kernel Objects.");
+
+ p = strrchr (kodlib, '-');
+ if (p != NULL)
+ p++;
+ else
+ p = "Unknown KOD library";
+ printf_filtered ("%s - %s\n", operating_system, p);
+
+ xfree (kodlib);
+ }
+}
+
+/* Print information about currently known kernel objects of the
+ specified type or a list of all known kernel object types if
+ argument is empty. */
+
+static void
+info_kod_command (char *arg, int from_tty)
+{
+ (*gdb_kod_request) (arg, from_tty);
+}
+
+/* Print name of kod command after selecting the appropriate kod
+ formatting library module. */
+
+static void
+load_kod_library (char *lib)
+{
+#if 0
+ /* FIXME: Don't have the eCos code here. */
+ if (! strcmp (lib, "ecos"))
+ {
+ gdb_kod_open = ecos_kod_open;
+ gdb_kod_request = ecos_kod_request;
+ gdb_kod_close = ecos_kod_close;
+ }
+ else
+#endif /* 0 */
+ if (! strcmp (lib, "cisco"))
+ {
+ gdb_kod_open = cisco_kod_open;
+ gdb_kod_request = cisco_kod_request;
+ gdb_kod_close = cisco_kod_close;
+ }
+ else
+ error ("Unknown operating system: %s\n", operating_system);
+}
+
+void
+_initialize_kod (void)
+{
+ struct cmd_list_element *c;
+
+ c = add_set_cmd ("os", no_class, var_string,
+ (char *) &operating_system,
+ "Set operating system",
+ &setlist);
+ set_cmd_sfunc (c, kod_set_os);
+ add_show_from_set (c, &showlist);
+}
diff --git a/gdb/kod.h b/gdb/kod.h
new file mode 100644
index 00000000000..6c4d03a3c7b
--- /dev/null
+++ b/gdb/kod.h
@@ -0,0 +1,61 @@
+/* Kernel Object Display facility for Cisco
+ Copyright 1999 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. */
+
+#ifndef KOD_H
+#define KOD_H
+
+typedef void kod_display_callback_ftype (char *);
+typedef void kod_query_callback_ftype (char *, char *, int *);
+
+/* ???/???: Functions imported from the library for all supported
+ OSes. FIXME: we really should do something better, such as
+ dynamically loading the KOD modules. */
+
+/* FIXME: cagney/1999-09-20: The kod-cisco.c et.al. kernel modules
+ should register themselve with kod.c during the _initialization*()
+ phase. With that implemented the extern declarations below would
+ be replaced with the KOD register function that the various kernel
+ modules should call. An example of this mechanism can be seen in
+ gdbarch.c:register_gdbarch_init(). */
+
+#if 0
+/* Don't have ecos code yet. */
+extern char *ecos_kod_open (kod_display_callback_ftype *display_func,
+ kod_query_callback_ftype *query_func);
+extern void ecos_kod_request (char *, int);
+extern void ecos_kod_close (void);
+#endif
+
+/* Initialize and return library name and version. The gdb side of
+ KOD, kod.c, passes us two functions: one for displaying output
+ (presumably to the user) and the other for querying the target. */
+
+extern char *cisco_kod_open (kod_display_callback_ftype *display_func,
+ kod_query_callback_ftype *query_func);
+
+/* Print information about currently known kernel objects. We
+ currently ignore the argument. There is only one mode of querying
+ the Cisco kernel: we ask for a dump of everything, and it returns
+ it. */
+
+extern void cisco_kod_request (char *arg, int from_tty);
+
+extern void cisco_kod_close (void);
+
+#endif
diff --git a/gdb/language.c b/gdb/language.c
new file mode 100644
index 00000000000..1bfba98c86d
--- /dev/null
+++ b/gdb/language.c
@@ -0,0 +1,1568 @@
+/* Multiple source language support for GDB.
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ Contributed by the Department of Computer Science at the State University
+ of New York at Buffalo.
+
+ 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. */
+
+/* This file contains functions that return things that are specific
+ to languages. Each function should examine current_language if necessary,
+ and return the appropriate result. */
+
+/* FIXME: Most of these would be better organized as macros which
+ return data out of a "language-specific" struct pointer that is set
+ whenever the working language changes. That would be a lot faster. */
+
+#include "defs.h"
+#include <ctype.h>
+#include "gdb_string.h"
+
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "value.h"
+#include "gdbcmd.h"
+#include "expression.h"
+#include "language.h"
+#include "target.h"
+#include "parser-defs.h"
+#include "jv-lang.h"
+
+extern void _initialize_language (void);
+
+static void show_language_command (char *, int);
+
+static void set_language_command (char *, int);
+
+static void show_type_command (char *, int);
+
+static void set_type_command (char *, int);
+
+static void show_range_command (char *, int);
+
+static void set_range_command (char *, int);
+
+static void show_case_command (char *, int);
+
+static void set_case_command (char *, int);
+
+static void set_case_str (void);
+
+static void set_range_str (void);
+
+static void set_type_str (void);
+
+static void set_lang_str (void);
+
+static void unk_lang_error (char *);
+
+static int unk_lang_parser (void);
+
+static void show_check (char *, int);
+
+static void set_check (char *, int);
+
+static void set_type_range_case (void);
+
+static void unk_lang_emit_char (int c, struct ui_file *stream, int quoter);
+
+static void unk_lang_printchar (int c, struct ui_file *stream);
+
+static void unk_lang_printstr (struct ui_file * stream, char *string,
+ unsigned int length, int width,
+ int force_ellipses);
+
+static struct type *unk_lang_create_fundamental_type (struct objfile *, int);
+
+static void unk_lang_print_type (struct type *, char *, struct ui_file *,
+ int, int);
+
+static int unk_lang_val_print (struct type *, char *, int, CORE_ADDR,
+ struct ui_file *, int, int, int,
+ enum val_prettyprint);
+
+static int unk_lang_value_print (struct value *, struct ui_file *, int, enum val_prettyprint);
+
+/* Forward declaration */
+extern const struct language_defn unknown_language_defn;
+
+/* The current (default at startup) state of type and range checking.
+ (If the modes are set to "auto", though, these are changed based
+ on the default language at startup, and then again based on the
+ language of the first source file. */
+
+enum range_mode range_mode = range_mode_auto;
+enum range_check range_check = range_check_off;
+enum type_mode type_mode = type_mode_auto;
+enum type_check type_check = type_check_off;
+enum case_mode case_mode = case_mode_auto;
+enum case_sensitivity case_sensitivity = case_sensitive_on;
+
+/* The current language and language_mode (see language.h) */
+
+const struct language_defn *current_language = &unknown_language_defn;
+enum language_mode language_mode = language_mode_auto;
+
+/* The language that the user expects to be typing in (the language
+ of main(), or the last language we notified them about, or C). */
+
+const struct language_defn *expected_language;
+
+/* The list of supported languages. The list itself is malloc'd. */
+
+static const struct language_defn **languages;
+static unsigned languages_size;
+static unsigned languages_allocsize;
+#define DEFAULT_ALLOCSIZE 4
+
+/* The "set language/type/range" commands all put stuff in these
+ buffers. This is to make them work as set/show commands. The
+ user's string is copied here, then the set_* commands look at
+ them and update them to something that looks nice when it is
+ printed out. */
+
+static char *language;
+static char *type;
+static char *range;
+static char *case_sensitive;
+
+/* Warning issued when current_language and the language of the current
+ frame do not match. */
+char lang_frame_mismatch_warn[] =
+"Warning: the current language does not match this frame.";
+
+
+/* This page contains the functions corresponding to GDB commands
+ and their helpers. */
+
+/* Show command. Display a warning if the language set
+ does not match the frame. */
+static void
+show_language_command (char *ignore, int from_tty)
+{
+ enum language flang; /* The language of the current frame */
+
+ flang = get_frame_language ();
+ if (flang != language_unknown &&
+ language_mode == language_mode_manual &&
+ current_language->la_language != flang)
+ printf_filtered ("%s\n", lang_frame_mismatch_warn);
+}
+
+/* Set command. Change the current working language. */
+static void
+set_language_command (char *ignore, int from_tty)
+{
+ int i;
+ enum language flang;
+ char *err_lang;
+
+ if (!language || !language[0])
+ {
+ printf_unfiltered ("The currently understood settings are:\n\n");
+ printf_unfiltered ("local or auto Automatic setting based on source file\n");
+
+ for (i = 0; i < languages_size; ++i)
+ {
+ /* Already dealt with these above. */
+ if (languages[i]->la_language == language_unknown
+ || languages[i]->la_language == language_auto)
+ continue;
+
+ /* FIXME for now assume that the human-readable name is just
+ a capitalization of the internal name. */
+ printf_unfiltered ("%-16s Use the %c%s language\n",
+ languages[i]->la_name,
+ /* Capitalize first letter of language
+ name. */
+ toupper (languages[i]->la_name[0]),
+ languages[i]->la_name + 1);
+ }
+ /* Restore the silly string. */
+ set_language (current_language->la_language);
+ return;
+ }
+
+ /* Search the list of languages for a match. */
+ for (i = 0; i < languages_size; i++)
+ {
+ if (STREQ (languages[i]->la_name, language))
+ {
+ /* Found it! Go into manual mode, and use this language. */
+ if (languages[i]->la_language == language_auto)
+ {
+ /* Enter auto mode. Set to the current frame's language, if known. */
+ language_mode = language_mode_auto;
+ flang = get_frame_language ();
+ if (flang != language_unknown)
+ set_language (flang);
+ expected_language = current_language;
+ return;
+ }
+ else
+ {
+ /* Enter manual mode. Set the specified language. */
+ language_mode = language_mode_manual;
+ current_language = languages[i];
+ set_type_range_case ();
+ set_lang_str ();
+ expected_language = current_language;
+ return;
+ }
+ }
+ }
+
+ /* Reset the language (esp. the global string "language") to the
+ correct values. */
+ err_lang = savestring (language, strlen (language));
+ make_cleanup (xfree, err_lang); /* Free it after error */
+ set_language (current_language->la_language);
+ error ("Unknown language `%s'.", err_lang);
+}
+
+/* Show command. Display a warning if the type setting does
+ not match the current language. */
+static void
+show_type_command (char *ignore, int from_tty)
+{
+ if (type_check != current_language->la_type_check)
+ printf_unfiltered (
+ "Warning: the current type check setting does not match the language.\n");
+}
+
+/* Set command. Change the setting for type checking. */
+static void
+set_type_command (char *ignore, int from_tty)
+{
+ if (STREQ (type, "on"))
+ {
+ type_check = type_check_on;
+ type_mode = type_mode_manual;
+ }
+ else if (STREQ (type, "warn"))
+ {
+ type_check = type_check_warn;
+ type_mode = type_mode_manual;
+ }
+ else if (STREQ (type, "off"))
+ {
+ type_check = type_check_off;
+ type_mode = type_mode_manual;
+ }
+ else if (STREQ (type, "auto"))
+ {
+ type_mode = type_mode_auto;
+ set_type_range_case ();
+ /* Avoid hitting the set_type_str call below. We
+ did it in set_type_range_case. */
+ return;
+ }
+ else
+ {
+ warning ("Unrecognized type check setting: \"%s\"", type);
+ }
+ set_type_str ();
+ show_type_command ((char *) NULL, from_tty);
+}
+
+/* Show command. Display a warning if the range setting does
+ not match the current language. */
+static void
+show_range_command (char *ignore, int from_tty)
+{
+
+ if (range_check != current_language->la_range_check)
+ printf_unfiltered (
+ "Warning: the current range check setting does not match the language.\n");
+}
+
+/* Set command. Change the setting for range checking. */
+static void
+set_range_command (char *ignore, int from_tty)
+{
+ if (STREQ (range, "on"))
+ {
+ range_check = range_check_on;
+ range_mode = range_mode_manual;
+ }
+ else if (STREQ (range, "warn"))
+ {
+ range_check = range_check_warn;
+ range_mode = range_mode_manual;
+ }
+ else if (STREQ (range, "off"))
+ {
+ range_check = range_check_off;
+ range_mode = range_mode_manual;
+ }
+ else if (STREQ (range, "auto"))
+ {
+ range_mode = range_mode_auto;
+ set_type_range_case ();
+ /* Avoid hitting the set_range_str call below. We
+ did it in set_type_range_case. */
+ return;
+ }
+ else
+ {
+ warning ("Unrecognized range check setting: \"%s\"", range);
+ }
+ set_range_str ();
+ show_range_command ((char *) 0, from_tty);
+}
+
+/* Show command. Display a warning if the case sensitivity setting does
+ not match the current language. */
+static void
+show_case_command (char *ignore, int from_tty)
+{
+ if (case_sensitivity != current_language->la_case_sensitivity)
+ printf_unfiltered(
+"Warning: the current case sensitivity setting does not match the language.\n");
+}
+
+/* Set command. Change the setting for case sensitivity. */
+static void
+set_case_command (char *ignore, int from_tty)
+{
+ if (STREQ (case_sensitive, "on"))
+ {
+ case_sensitivity = case_sensitive_on;
+ case_mode = case_mode_manual;
+ }
+ else if (STREQ (case_sensitive, "off"))
+ {
+ case_sensitivity = case_sensitive_off;
+ case_mode = case_mode_manual;
+ }
+ else if (STREQ (case_sensitive, "auto"))
+ {
+ case_mode = case_mode_auto;
+ set_type_range_case ();
+ /* Avoid hitting the set_case_str call below. We
+ did it in set_type_range_case. */
+ return;
+ }
+ else
+ {
+ warning ("Unrecognized case-sensitive setting: \"%s\"", case_sensitive);
+ }
+ set_case_str();
+ show_case_command ((char *) NULL, from_tty);
+}
+
+/* Set the status of range and type checking and case sensitivity based on
+ the current modes and the current language.
+ If SHOW is non-zero, then print out the current language,
+ type and range checking status. */
+static void
+set_type_range_case (void)
+{
+
+ if (range_mode == range_mode_auto)
+ range_check = current_language->la_range_check;
+
+ if (type_mode == type_mode_auto)
+ type_check = current_language->la_type_check;
+
+ if (case_mode == case_mode_auto)
+ case_sensitivity = current_language->la_case_sensitivity;
+
+ set_type_str ();
+ set_range_str ();
+ set_case_str ();
+}
+
+/* Set current language to (enum language) LANG. Returns previous language. */
+
+enum language
+set_language (enum language lang)
+{
+ int i;
+ enum language prev_language;
+
+ prev_language = current_language->la_language;
+
+ for (i = 0; i < languages_size; i++)
+ {
+ if (languages[i]->la_language == lang)
+ {
+ current_language = languages[i];
+ set_type_range_case ();
+ set_lang_str ();
+ break;
+ }
+ }
+
+ return prev_language;
+}
+
+/* This page contains functions that update the global vars
+ language, type and range. */
+static void
+set_lang_str (void)
+{
+ char *prefix = "";
+
+ if (language)
+ xfree (language);
+ if (language_mode == language_mode_auto)
+ prefix = "auto; currently ";
+
+ language = concat (prefix, current_language->la_name, NULL);
+}
+
+static void
+set_type_str (void)
+{
+ char *tmp = NULL, *prefix = "";
+
+ if (type)
+ xfree (type);
+ if (type_mode == type_mode_auto)
+ prefix = "auto; currently ";
+
+ switch (type_check)
+ {
+ case type_check_on:
+ tmp = "on";
+ break;
+ case type_check_off:
+ tmp = "off";
+ break;
+ case type_check_warn:
+ tmp = "warn";
+ break;
+ default:
+ error ("Unrecognized type check setting.");
+ }
+
+ type = concat (prefix, tmp, NULL);
+}
+
+static void
+set_range_str (void)
+{
+ char *tmp, *pref = "";
+
+ if (range_mode == range_mode_auto)
+ pref = "auto; currently ";
+
+ switch (range_check)
+ {
+ case range_check_on:
+ tmp = "on";
+ break;
+ case range_check_off:
+ tmp = "off";
+ break;
+ case range_check_warn:
+ tmp = "warn";
+ break;
+ default:
+ error ("Unrecognized range check setting.");
+ }
+
+ if (range)
+ xfree (range);
+ range = concat (pref, tmp, NULL);
+}
+
+static void
+set_case_str()
+{
+ char *tmp = NULL, *prefix = "";
+
+ if (case_mode==case_mode_auto)
+ prefix = "auto; currently ";
+
+ switch (case_sensitivity)
+ {
+ case case_sensitive_on:
+ tmp = "on";
+ break;
+ case case_sensitive_off:
+ tmp = "off";
+ break;
+ default:
+ error ("Unrecognized case-sensitive setting.");
+ }
+
+ xfree (case_sensitive);
+ case_sensitive = concat (prefix, tmp, NULL);
+}
+
+/* Print out the current language settings: language, range and
+ type checking. If QUIETLY, print only what has changed. */
+
+void
+language_info (int quietly)
+{
+ if (quietly && expected_language == current_language)
+ return;
+
+ expected_language = current_language;
+ printf_unfiltered ("Current language: %s\n", language);
+ show_language_command ((char *) 0, 1);
+
+ if (!quietly)
+ {
+ printf_unfiltered ("Type checking: %s\n", type);
+ show_type_command ((char *) 0, 1);
+ printf_unfiltered ("Range checking: %s\n", range);
+ show_range_command ((char *) 0, 1);
+ printf_unfiltered ("Case sensitivity: %s\n", case_sensitive);
+ show_case_command ((char *) 0, 1);
+ }
+}
+
+/* Return the result of a binary operation. */
+
+#if 0 /* Currently unused */
+
+struct type *
+binop_result_type (struct value *v1, struct value *v2)
+{
+ int size, uns;
+ struct type *t1 = check_typedef (VALUE_TYPE (v1));
+ struct type *t2 = check_typedef (VALUE_TYPE (v2));
+
+ int l1 = TYPE_LENGTH (t1);
+ int l2 = TYPE_LENGTH (t2);
+
+ switch (current_language->la_language)
+ {
+ case language_c:
+ case language_cplus:
+ if (TYPE_CODE (t1) == TYPE_CODE_FLT)
+ return TYPE_CODE (t2) == TYPE_CODE_FLT && l2 > l1 ?
+ VALUE_TYPE (v2) : VALUE_TYPE (v1);
+ else if (TYPE_CODE (t2) == TYPE_CODE_FLT)
+ return TYPE_CODE (t1) == TYPE_CODE_FLT && l1 > l2 ?
+ VALUE_TYPE (v1) : VALUE_TYPE (v2);
+ else if (TYPE_UNSIGNED (t1) && l1 > l2)
+ return VALUE_TYPE (v1);
+ else if (TYPE_UNSIGNED (t2) && l2 > l1)
+ return VALUE_TYPE (v2);
+ else /* Both are signed. Result is the longer type */
+ return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2);
+ break;
+ case language_m2:
+ /* If we are doing type-checking, l1 should equal l2, so this is
+ not needed. */
+ return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2);
+ break;
+ case language_chill:
+ error ("Missing Chill support in function binop_result_check."); /*FIXME */
+ }
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ return (struct type *) 0; /* For lint */
+}
+
+#endif /* 0 */
+
+
+/* This page contains functions that return format strings for
+ printf for printing out numbers in different formats */
+
+/* Returns the appropriate printf format for hexadecimal
+ numbers. */
+char *
+local_hex_format_custom (char *pre)
+{
+ static char form[50];
+
+ strcpy (form, local_hex_format_prefix ());
+ strcat (form, "%");
+ strcat (form, pre);
+ strcat (form, local_hex_format_specifier ());
+ strcat (form, local_hex_format_suffix ());
+ return form;
+}
+
+/* Converts a LONGEST to custom hexadecimal and stores it in a static
+ string. Returns a pointer to this string. */
+char *
+local_hex_string (LONGEST num)
+{
+ return local_hex_string_custom (num, "l");
+}
+
+/* Converts a LONGEST number to custom hexadecimal and stores it in a static
+ string. Returns a pointer to this string. Note that the width parameter
+ should end with "l", e.g. "08l" as with calls to local_hex_string_custom */
+
+char *
+local_hex_string_custom (LONGEST num, char *width)
+{
+#define RESULT_BUF_LEN 50
+ static char res2[RESULT_BUF_LEN];
+ char format[RESULT_BUF_LEN];
+ int field_width;
+ int num_len;
+ int num_pad_chars;
+ char *pad_char; /* string with one character */
+ int pad_on_left;
+ char *parse_ptr;
+ char temp_nbr_buf[RESULT_BUF_LEN];
+
+ /* Use phex_nz to print the number into a string, then
+ build the result string from local_hex_format_prefix, padding and
+ the hex representation as indicated by "width". */
+ strcpy (temp_nbr_buf, phex_nz (num, sizeof (num)));
+ /* parse width */
+ parse_ptr = width;
+ pad_on_left = 1;
+ pad_char = " ";
+ if (*parse_ptr == '-')
+ {
+ parse_ptr++;
+ pad_on_left = 0;
+ }
+ if (*parse_ptr == '0')
+ {
+ parse_ptr++;
+ if (pad_on_left)
+ pad_char = "0"; /* If padding is on the right, it is blank */
+ }
+ field_width = atoi (parse_ptr);
+ num_len = strlen (temp_nbr_buf);
+ num_pad_chars = field_width - strlen (temp_nbr_buf); /* possibly negative */
+
+ if (strlen (local_hex_format_prefix ()) + num_len + num_pad_chars
+ >= RESULT_BUF_LEN) /* paranoia */
+ internal_error (__FILE__, __LINE__,
+ "local_hex_string_custom: insufficient space to store result");
+
+ strcpy (res2, local_hex_format_prefix ());
+ if (pad_on_left)
+ {
+ while (num_pad_chars > 0)
+ {
+ strcat (res2, pad_char);
+ num_pad_chars--;
+ }
+ }
+ strcat (res2, temp_nbr_buf);
+ if (!pad_on_left)
+ {
+ while (num_pad_chars > 0)
+ {
+ strcat (res2, pad_char);
+ num_pad_chars--;
+ }
+ }
+ return res2;
+
+} /* local_hex_string_custom */
+
+/* Returns the appropriate printf format for octal
+ numbers. */
+char *
+local_octal_format_custom (char *pre)
+{
+ static char form[50];
+
+ strcpy (form, local_octal_format_prefix ());
+ strcat (form, "%");
+ strcat (form, pre);
+ strcat (form, local_octal_format_specifier ());
+ strcat (form, local_octal_format_suffix ());
+ return form;
+}
+
+/* Returns the appropriate printf format for decimal numbers. */
+char *
+local_decimal_format_custom (char *pre)
+{
+ static char form[50];
+
+ strcpy (form, local_decimal_format_prefix ());
+ strcat (form, "%");
+ strcat (form, pre);
+ strcat (form, local_decimal_format_specifier ());
+ strcat (form, local_decimal_format_suffix ());
+ return form;
+}
+
+#if 0
+/* This page contains functions that are used in type/range checking.
+ They all return zero if the type/range check fails.
+
+ It is hoped that these will make extending GDB to parse different
+ languages a little easier. These are primarily used in eval.c when
+ evaluating expressions and making sure that their types are correct.
+ Instead of having a mess of conjucted/disjuncted expressions in an "if",
+ the ideas of type can be wrapped up in the following functions.
+
+ Note that some of them are not currently dependent upon which language
+ is currently being parsed. For example, floats are the same in
+ C and Modula-2 (ie. the only floating point type has TYPE_CODE of
+ TYPE_CODE_FLT), while booleans are different. */
+
+/* Returns non-zero if its argument is a simple type. This is the same for
+ both Modula-2 and for C. In the C case, TYPE_CODE_CHAR will never occur,
+ and thus will never cause the failure of the test. */
+int
+simple_type (struct type *type)
+{
+ CHECK_TYPEDEF (type);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_BOOL:
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+/* Returns non-zero if its argument is of an ordered type.
+ An ordered type is one in which the elements can be tested for the
+ properties of "greater than", "less than", etc, or for which the
+ operations "increment" or "decrement" make sense. */
+int
+ordered_type (struct type *type)
+{
+ CHECK_TYPEDEF (type);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_RANGE:
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+/* Returns non-zero if the two types are the same */
+int
+same_type (struct type *arg1, struct type *arg2)
+{
+ CHECK_TYPEDEF (type);
+ if (structured_type (arg1) ? !structured_type (arg2) : structured_type (arg2))
+ /* One is structured and one isn't */
+ return 0;
+ else if (structured_type (arg1) && structured_type (arg2))
+ return arg1 == arg2;
+ else if (numeric_type (arg1) && numeric_type (arg2))
+ return (TYPE_CODE (arg2) == TYPE_CODE (arg1)) &&
+ (TYPE_UNSIGNED (arg1) == TYPE_UNSIGNED (arg2))
+ ? 1 : 0;
+ else
+ return arg1 == arg2;
+}
+
+/* Returns non-zero if the type is integral */
+int
+integral_type (struct type *type)
+{
+ CHECK_TYPEDEF (type);
+ switch (current_language->la_language)
+ {
+ case language_c:
+ case language_cplus:
+ return (TYPE_CODE (type) != TYPE_CODE_INT) &&
+ (TYPE_CODE (type) != TYPE_CODE_ENUM) ? 0 : 1;
+ case language_m2:
+ case language_pascal:
+ return TYPE_CODE (type) != TYPE_CODE_INT ? 0 : 1;
+ case language_chill:
+ error ("Missing Chill support in function integral_type."); /*FIXME */
+ default:
+ error ("Language not supported.");
+ }
+}
+
+/* Returns non-zero if the value is numeric */
+int
+numeric_type (struct type *type)
+{
+ CHECK_TYPEDEF (type);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_INT:
+ case TYPE_CODE_FLT:
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+/* Returns non-zero if the value is a character type */
+int
+character_type (struct type *type)
+{
+ CHECK_TYPEDEF (type);
+ switch (current_language->la_language)
+ {
+ case language_chill:
+ case language_m2:
+ case language_pascal:
+ return TYPE_CODE (type) != TYPE_CODE_CHAR ? 0 : 1;
+
+ case language_c:
+ case language_cplus:
+ return (TYPE_CODE (type) == TYPE_CODE_INT) &&
+ TYPE_LENGTH (type) == sizeof (char)
+ ? 1 : 0;
+ default:
+ return (0);
+ }
+}
+
+/* Returns non-zero if the value is a string type */
+int
+string_type (struct type *type)
+{
+ CHECK_TYPEDEF (type);
+ switch (current_language->la_language)
+ {
+ case language_chill:
+ case language_m2:
+ case language_pascal:
+ return TYPE_CODE (type) != TYPE_CODE_STRING ? 0 : 1;
+
+ case language_c:
+ case language_cplus:
+ /* C does not have distinct string type. */
+ return (0);
+ default:
+ return (0);
+ }
+}
+
+/* Returns non-zero if the value is a boolean type */
+int
+boolean_type (struct type *type)
+{
+ CHECK_TYPEDEF (type);
+ if (TYPE_CODE (type) == TYPE_CODE_BOOL)
+ return 1;
+ switch (current_language->la_language)
+ {
+ case language_c:
+ case language_cplus:
+ /* Might be more cleanly handled by having a TYPE_CODE_INT_NOT_BOOL
+ for CHILL and such languages, or a TYPE_CODE_INT_OR_BOOL for C. */
+ if (TYPE_CODE (type) == TYPE_CODE_INT)
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+/* Returns non-zero if the value is a floating-point type */
+int
+float_type (struct type *type)
+{
+ CHECK_TYPEDEF (type);
+ return TYPE_CODE (type) == TYPE_CODE_FLT;
+}
+
+/* Returns non-zero if the value is a pointer type */
+int
+pointer_type (struct type *type)
+{
+ return TYPE_CODE (type) == TYPE_CODE_PTR ||
+ TYPE_CODE (type) == TYPE_CODE_REF;
+}
+
+/* Returns non-zero if the value is a structured type */
+int
+structured_type (struct type *type)
+{
+ CHECK_TYPEDEF (type);
+ switch (current_language->la_language)
+ {
+ case language_c:
+ case language_cplus:
+ return (TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
+ (TYPE_CODE (type) == TYPE_CODE_UNION) ||
+ (TYPE_CODE (type) == TYPE_CODE_ARRAY);
+ case language_pascal:
+ return (TYPE_CODE(type) == TYPE_CODE_STRUCT) ||
+ (TYPE_CODE(type) == TYPE_CODE_UNION) ||
+ (TYPE_CODE(type) == TYPE_CODE_SET) ||
+ (TYPE_CODE(type) == TYPE_CODE_ARRAY);
+ case language_m2:
+ return (TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
+ (TYPE_CODE (type) == TYPE_CODE_SET) ||
+ (TYPE_CODE (type) == TYPE_CODE_ARRAY);
+ case language_chill:
+ error ("Missing Chill support in function structured_type."); /*FIXME */
+ default:
+ return (0);
+ }
+}
+#endif
+
+struct type *
+lang_bool_type (void)
+{
+ struct symbol *sym;
+ struct type *type;
+ switch (current_language->la_language)
+ {
+ case language_chill:
+ return builtin_type_chill_bool;
+ case language_fortran:
+ sym = lookup_symbol ("logical", NULL, VAR_NAMESPACE, NULL, NULL);
+ if (sym)
+ {
+ type = SYMBOL_TYPE (sym);
+ if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
+ return type;
+ }
+ return builtin_type_f_logical_s2;
+ case language_cplus:
+ case language_pascal:
+ if (current_language->la_language==language_cplus)
+ {sym = lookup_symbol ("bool", NULL, VAR_NAMESPACE, NULL, NULL);}
+ else
+ {sym = lookup_symbol ("boolean", NULL, VAR_NAMESPACE, NULL, NULL);}
+ if (sym)
+ {
+ type = SYMBOL_TYPE (sym);
+ if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
+ return type;
+ }
+ return builtin_type_bool;
+ case language_java:
+ sym = lookup_symbol ("boolean", NULL, VAR_NAMESPACE, NULL, NULL);
+ if (sym)
+ {
+ type = SYMBOL_TYPE (sym);
+ if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
+ return type;
+ }
+ return java_boolean_type;
+ default:
+ return builtin_type_int;
+ }
+}
+
+/* This page contains functions that return info about
+ (struct value) values used in GDB. */
+
+/* Returns non-zero if the value VAL represents a true value. */
+int
+value_true (struct value *val)
+{
+ /* It is possible that we should have some sort of error if a non-boolean
+ value is used in this context. Possibly dependent on some kind of
+ "boolean-checking" option like range checking. But it should probably
+ not depend on the language except insofar as is necessary to identify
+ a "boolean" value (i.e. in C using a float, pointer, etc., as a boolean
+ should be an error, probably). */
+ return !value_logical_not (val);
+}
+
+/* Returns non-zero if the operator OP is defined on
+ the values ARG1 and ARG2. */
+
+#if 0 /* Currently unused */
+
+void
+binop_type_check (struct value *arg1, struct value *arg2, int op)
+{
+ struct type *t1, *t2;
+
+ /* If we're not checking types, always return success. */
+ if (!STRICT_TYPE)
+ return;
+
+ t1 = VALUE_TYPE (arg1);
+ if (arg2 != NULL)
+ t2 = VALUE_TYPE (arg2);
+ else
+ t2 = NULL;
+
+ switch (op)
+ {
+ case BINOP_ADD:
+ case BINOP_SUB:
+ if ((numeric_type (t1) && pointer_type (t2)) ||
+ (pointer_type (t1) && numeric_type (t2)))
+ {
+ warning ("combining pointer and integer.\n");
+ break;
+ }
+ case BINOP_MUL:
+ case BINOP_LSH:
+ case BINOP_RSH:
+ if (!numeric_type (t1) || !numeric_type (t2))
+ type_op_error ("Arguments to %s must be numbers.", op);
+ else if (!same_type (t1, t2))
+ type_op_error ("Arguments to %s must be of the same type.", op);
+ break;
+
+ case BINOP_LOGICAL_AND:
+ case BINOP_LOGICAL_OR:
+ if (!boolean_type (t1) || !boolean_type (t2))
+ type_op_error ("Arguments to %s must be of boolean type.", op);
+ break;
+
+ case BINOP_EQUAL:
+ if ((pointer_type (t1) && !(pointer_type (t2) || integral_type (t2))) ||
+ (pointer_type (t2) && !(pointer_type (t1) || integral_type (t1))))
+ type_op_error ("A pointer can only be compared to an integer or pointer.", op);
+ else if ((pointer_type (t1) && integral_type (t2)) ||
+ (integral_type (t1) && pointer_type (t2)))
+ {
+ warning ("combining integer and pointer.\n");
+ break;
+ }
+ else if (!simple_type (t1) || !simple_type (t2))
+ type_op_error ("Arguments to %s must be of simple type.", op);
+ else if (!same_type (t1, t2))
+ type_op_error ("Arguments to %s must be of the same type.", op);
+ break;
+
+ case BINOP_REM:
+ case BINOP_MOD:
+ if (!integral_type (t1) || !integral_type (t2))
+ type_op_error ("Arguments to %s must be of integral type.", op);
+ break;
+
+ case BINOP_LESS:
+ case BINOP_GTR:
+ case BINOP_LEQ:
+ case BINOP_GEQ:
+ if (!ordered_type (t1) || !ordered_type (t2))
+ type_op_error ("Arguments to %s must be of ordered type.", op);
+ else if (!same_type (t1, t2))
+ type_op_error ("Arguments to %s must be of the same type.", op);
+ break;
+
+ case BINOP_ASSIGN:
+ if (pointer_type (t1) && !integral_type (t2))
+ type_op_error ("A pointer can only be assigned an integer.", op);
+ else if (pointer_type (t1) && integral_type (t2))
+ {
+ warning ("combining integer and pointer.");
+ break;
+ }
+ else if (!simple_type (t1) || !simple_type (t2))
+ type_op_error ("Arguments to %s must be of simple type.", op);
+ else if (!same_type (t1, t2))
+ type_op_error ("Arguments to %s must be of the same type.", op);
+ break;
+
+ case BINOP_CONCAT:
+ /* FIXME: Needs to handle bitstrings as well. */
+ if (!(string_type (t1) || character_type (t1) || integral_type (t1))
+ || !(string_type (t2) || character_type (t2) || integral_type (t2)))
+ type_op_error ("Arguments to %s must be strings or characters.", op);
+ break;
+
+ /* Unary checks -- arg2 is null */
+
+ case UNOP_LOGICAL_NOT:
+ if (!boolean_type (t1))
+ type_op_error ("Argument to %s must be of boolean type.", op);
+ break;
+
+ case UNOP_PLUS:
+ case UNOP_NEG:
+ if (!numeric_type (t1))
+ type_op_error ("Argument to %s must be of numeric type.", op);
+ break;
+
+ case UNOP_IND:
+ if (integral_type (t1))
+ {
+ warning ("combining pointer and integer.\n");
+ break;
+ }
+ else if (!pointer_type (t1))
+ type_op_error ("Argument to %s must be a pointer.", op);
+ break;
+
+ case UNOP_PREINCREMENT:
+ case UNOP_POSTINCREMENT:
+ case UNOP_PREDECREMENT:
+ case UNOP_POSTDECREMENT:
+ if (!ordered_type (t1))
+ type_op_error ("Argument to %s must be of an ordered type.", op);
+ break;
+
+ default:
+ /* Ok. The following operators have different meanings in
+ different languages. */
+ switch (current_language->la_language)
+ {
+#ifdef _LANG_c
+ case language_c:
+ case language_cplus:
+ switch (op)
+ {
+ case BINOP_DIV:
+ if (!numeric_type (t1) || !numeric_type (t2))
+ type_op_error ("Arguments to %s must be numbers.", op);
+ break;
+ }
+ break;
+#endif
+
+#ifdef _LANG_m2
+ case language_m2:
+ switch (op)
+ {
+ case BINOP_DIV:
+ if (!float_type (t1) || !float_type (t2))
+ type_op_error ("Arguments to %s must be floating point numbers.", op);
+ break;
+ case BINOP_INTDIV:
+ if (!integral_type (t1) || !integral_type (t2))
+ type_op_error ("Arguments to %s must be of integral type.", op);
+ break;
+ }
+#endif
+
+#ifdef _LANG_pascal
+ case language_pascal:
+ switch(op)
+ {
+ case BINOP_DIV:
+ if (!float_type(t1) && !float_type(t2))
+ type_op_error ("Arguments to %s must be floating point numbers.",op);
+ break;
+ case BINOP_INTDIV:
+ if (!integral_type(t1) || !integral_type(t2))
+ type_op_error ("Arguments to %s must be of integral type.",op);
+ break;
+ }
+#endif
+
+#ifdef _LANG_chill
+ case language_chill:
+ error ("Missing Chill support in function binop_type_check."); /*FIXME */
+#endif
+
+ }
+ }
+}
+
+#endif /* 0 */
+
+
+/* This page contains functions for the printing out of
+ error messages that occur during type- and range-
+ checking. */
+
+/* Prints the format string FMT with the operator as a string
+ corresponding to the opcode OP. If FATAL is non-zero, then
+ this is an error and error () is called. Otherwise, it is
+ a warning and printf() is called. */
+void
+op_error (char *fmt, enum exp_opcode op, int fatal)
+{
+ if (fatal)
+ error (fmt, op_string (op));
+ else
+ {
+ warning (fmt, op_string (op));
+ }
+}
+
+/* These are called when a language fails a type- or range-check. The
+ first argument should be a printf()-style format string, and the
+ rest of the arguments should be its arguments. If
+ [type|range]_check is [type|range]_check_on, an error is printed;
+ if [type|range]_check_warn, a warning; otherwise just the
+ message. */
+
+void
+type_error (const char *string,...)
+{
+ va_list args;
+ va_start (args, string);
+
+ switch (type_check)
+ {
+ case type_check_warn:
+ vwarning (string, args);
+ break;
+ case type_check_on:
+ verror (string, args);
+ break;
+ case type_check_off:
+ /* FIXME: cagney/2002-01-30: Should this function print anything
+ when type error is off? */
+ vfprintf_filtered (gdb_stderr, string, args);
+ fprintf_filtered (gdb_stderr, "\n");
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "bad switch");
+ }
+ va_end (args);
+}
+
+void
+range_error (const char *string,...)
+{
+ va_list args;
+ va_start (args, string);
+
+ switch (range_check)
+ {
+ case range_check_warn:
+ vwarning (string, args);
+ break;
+ case range_check_on:
+ verror (string, args);
+ break;
+ case range_check_off:
+ /* FIXME: cagney/2002-01-30: Should this function print anything
+ when range error is off? */
+ vfprintf_filtered (gdb_stderr, string, args);
+ fprintf_filtered (gdb_stderr, "\n");
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "bad switch");
+ }
+ va_end (args);
+}
+
+
+/* This page contains miscellaneous functions */
+
+/* Return the language enum for a given language string. */
+
+enum language
+language_enum (char *str)
+{
+ int i;
+
+ for (i = 0; i < languages_size; i++)
+ if (STREQ (languages[i]->la_name, str))
+ return languages[i]->la_language;
+
+ return language_unknown;
+}
+
+/* Return the language struct for a given language enum. */
+
+const struct language_defn *
+language_def (enum language lang)
+{
+ int i;
+
+ for (i = 0; i < languages_size; i++)
+ {
+ if (languages[i]->la_language == lang)
+ {
+ return languages[i];
+ }
+ }
+ return NULL;
+}
+
+/* Return the language as a string */
+char *
+language_str (enum language lang)
+{
+ int i;
+
+ for (i = 0; i < languages_size; i++)
+ {
+ if (languages[i]->la_language == lang)
+ {
+ return languages[i]->la_name;
+ }
+ }
+ return "Unknown";
+}
+
+static void
+set_check (char *ignore, int from_tty)
+{
+ printf_unfiltered (
+ "\"set check\" must be followed by the name of a check subcommand.\n");
+ help_list (setchecklist, "set check ", -1, gdb_stdout);
+}
+
+static void
+show_check (char *ignore, int from_tty)
+{
+ cmd_show_list (showchecklist, from_tty, "");
+}
+
+/* Add a language to the set of known languages. */
+
+void
+add_language (const struct language_defn *lang)
+{
+ if (lang->la_magic != LANG_MAGIC)
+ {
+ fprintf_unfiltered (gdb_stderr, "Magic number of %s language struct wrong\n",
+ lang->la_name);
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+
+ if (!languages)
+ {
+ languages_allocsize = DEFAULT_ALLOCSIZE;
+ languages = (const struct language_defn **) xmalloc
+ (languages_allocsize * sizeof (*languages));
+ }
+ if (languages_size >= languages_allocsize)
+ {
+ languages_allocsize *= 2;
+ languages = (const struct language_defn **) xrealloc ((char *) languages,
+ languages_allocsize * sizeof (*languages));
+ }
+ languages[languages_size++] = lang;
+}
+
+/* Define the language that is no language. */
+
+static int
+unk_lang_parser (void)
+{
+ return 1;
+}
+
+static void
+unk_lang_error (char *msg)
+{
+ error ("Attempted to parse an expression with unknown language");
+}
+
+static void
+unk_lang_emit_char (register int c, struct ui_file *stream, int quoter)
+{
+ error ("internal error - unimplemented function unk_lang_emit_char called.");
+}
+
+static void
+unk_lang_printchar (register int c, struct ui_file *stream)
+{
+ error ("internal error - unimplemented function unk_lang_printchar called.");
+}
+
+static void
+unk_lang_printstr (struct ui_file *stream, char *string, unsigned int length,
+ int width, int force_ellipses)
+{
+ error ("internal error - unimplemented function unk_lang_printstr called.");
+}
+
+static struct type *
+unk_lang_create_fundamental_type (struct objfile *objfile, int typeid)
+{
+ error ("internal error - unimplemented function unk_lang_create_fundamental_type called.");
+}
+
+static void
+unk_lang_print_type (struct type *type, char *varstring, struct ui_file *stream,
+ int show, int level)
+{
+ error ("internal error - unimplemented function unk_lang_print_type called.");
+}
+
+static int
+unk_lang_val_print (struct type *type, char *valaddr, int embedded_offset,
+ CORE_ADDR address, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
+{
+ error ("internal error - unimplemented function unk_lang_val_print called.");
+}
+
+static int
+unk_lang_value_print (struct value *val, struct ui_file *stream, int format,
+ enum val_prettyprint pretty)
+{
+ error ("internal error - unimplemented function unk_lang_value_print called.");
+}
+
+static struct type **const (unknown_builtin_types[]) =
+{
+ 0
+};
+static const struct op_print unk_op_print_tab[] =
+{
+ {NULL, OP_NULL, PREC_NULL, 0}
+};
+
+const struct language_defn unknown_language_defn =
+{
+ "unknown",
+ language_unknown,
+ &unknown_builtin_types[0],
+ range_check_off,
+ type_check_off,
+ case_sensitive_on,
+ unk_lang_parser,
+ unk_lang_error,
+ evaluate_subexp_standard,
+ unk_lang_printchar, /* Print character constant */
+ unk_lang_printstr,
+ unk_lang_emit_char,
+ unk_lang_create_fundamental_type,
+ unk_lang_print_type, /* Print a type using appropriate syntax */
+ unk_lang_val_print, /* Print a value using appropriate syntax */
+ unk_lang_value_print, /* Print a top-level value */
+ {"", "", "", ""}, /* Binary format info */
+ {"0%lo", "0", "o", ""}, /* Octal format info */
+ {"%ld", "", "d", ""}, /* Decimal format info */
+ {"0x%lx", "0x", "x", ""}, /* Hex format info */
+ unk_op_print_tab, /* expression operators for printing */
+ 1, /* c-style arrays */
+ 0, /* String lower bound */
+ &builtin_type_char, /* Type of string elements */
+ LANG_MAGIC
+};
+
+/* These two structs define fake entries for the "local" and "auto" options. */
+const struct language_defn auto_language_defn =
+{
+ "auto",
+ language_auto,
+ &unknown_builtin_types[0],
+ range_check_off,
+ type_check_off,
+ case_sensitive_on,
+ unk_lang_parser,
+ unk_lang_error,
+ evaluate_subexp_standard,
+ unk_lang_printchar, /* Print character constant */
+ unk_lang_printstr,
+ unk_lang_emit_char,
+ unk_lang_create_fundamental_type,
+ unk_lang_print_type, /* Print a type using appropriate syntax */
+ unk_lang_val_print, /* Print a value using appropriate syntax */
+ unk_lang_value_print, /* Print a top-level value */
+ {"", "", "", ""}, /* Binary format info */
+ {"0%lo", "0", "o", ""}, /* Octal format info */
+ {"%ld", "", "d", ""}, /* Decimal format info */
+ {"0x%lx", "0x", "x", ""}, /* Hex format info */
+ unk_op_print_tab, /* expression operators for printing */
+ 1, /* c-style arrays */
+ 0, /* String lower bound */
+ &builtin_type_char, /* Type of string elements */
+ LANG_MAGIC
+};
+
+const struct language_defn local_language_defn =
+{
+ "local",
+ language_auto,
+ &unknown_builtin_types[0],
+ range_check_off,
+ type_check_off,
+ case_sensitive_on,
+ unk_lang_parser,
+ unk_lang_error,
+ evaluate_subexp_standard,
+ unk_lang_printchar, /* Print character constant */
+ unk_lang_printstr,
+ unk_lang_emit_char,
+ unk_lang_create_fundamental_type,
+ unk_lang_print_type, /* Print a type using appropriate syntax */
+ unk_lang_val_print, /* Print a value using appropriate syntax */
+ unk_lang_value_print, /* Print a top-level value */
+ {"", "", "", ""}, /* Binary format info */
+ {"0%lo", "0", "o", ""}, /* Octal format info */
+ {"%ld", "", "d", ""}, /* Decimal format info */
+ {"0x%lx", "0x", "x", ""}, /* Hex format info */
+ unk_op_print_tab, /* expression operators for printing */
+ 1, /* c-style arrays */
+ 0, /* String lower bound */
+ &builtin_type_char, /* Type of string elements */
+ LANG_MAGIC
+};
+
+/* Initialize the language routines */
+
+void
+_initialize_language (void)
+{
+ struct cmd_list_element *set, *show;
+
+ /* GDB commands for language specific stuff */
+
+ set = add_set_cmd ("language", class_support, var_string_noescape,
+ (char *) &language,
+ "Set the current source language.",
+ &setlist);
+ show = add_show_from_set (set, &showlist);
+ set_cmd_cfunc (set, set_language_command);
+ set_cmd_cfunc (show, show_language_command);
+
+ add_prefix_cmd ("check", no_class, set_check,
+ "Set the status of the type/range checker.",
+ &setchecklist, "set check ", 0, &setlist);
+ add_alias_cmd ("c", "check", no_class, 1, &setlist);
+ add_alias_cmd ("ch", "check", no_class, 1, &setlist);
+
+ add_prefix_cmd ("check", no_class, show_check,
+ "Show the status of the type/range checker.",
+ &showchecklist, "show check ", 0, &showlist);
+ add_alias_cmd ("c", "check", no_class, 1, &showlist);
+ add_alias_cmd ("ch", "check", no_class, 1, &showlist);
+
+ set = add_set_cmd ("type", class_support, var_string_noescape,
+ (char *) &type,
+ "Set type checking. (on/warn/off/auto)",
+ &setchecklist);
+ show = add_show_from_set (set, &showchecklist);
+ set_cmd_cfunc (set, set_type_command);
+ set_cmd_cfunc (show, show_type_command);
+
+ set = add_set_cmd ("range", class_support, var_string_noescape,
+ (char *) &range,
+ "Set range checking. (on/warn/off/auto)",
+ &setchecklist);
+ show = add_show_from_set (set, &showchecklist);
+ set_cmd_cfunc (set, set_range_command);
+ set_cmd_cfunc (show, show_range_command);
+
+ set = add_set_cmd ("case-sensitive", class_support, var_string_noescape,
+ (char *) &case_sensitive,
+ "Set case sensitivity in name search. (on/off/auto)\n\
+For Fortran the default is off; for other languages the default is on.",
+ &setlist);
+ show = add_show_from_set (set, &showlist);
+ set_cmd_cfunc (set, set_case_command);
+ set_cmd_cfunc (show, show_case_command);
+
+ add_language (&unknown_language_defn);
+ add_language (&local_language_defn);
+ add_language (&auto_language_defn);
+
+ language = savestring ("auto", strlen ("auto"));
+ type = savestring ("auto", strlen ("auto"));
+ range = savestring ("auto", strlen ("auto"));
+ case_sensitive = savestring ("auto",strlen ("auto"));
+
+ /* Have the above take effect */
+ set_language (language_auto);
+}
diff --git a/gdb/language.h b/gdb/language.h
new file mode 100644
index 00000000000..301fefd18dd
--- /dev/null
+++ b/gdb/language.h
@@ -0,0 +1,466 @@
+/* Source-language-related definitions for GDB.
+ Copyright 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000
+ Free Software Foundation, Inc.
+ Contributed by the Department of Computer Science at the State University
+ of New York at Buffalo.
+
+ 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. */
+
+#if !defined (LANGUAGE_H)
+#define LANGUAGE_H 1
+
+/* Forward decls for prototypes */
+struct value;
+struct objfile;
+struct expression;
+/* enum exp_opcode; ANSI's `wisdom' didn't include forward enum decls. */
+
+/* This used to be included to configure GDB for one or more specific
+ languages. Now it is left out to configure for all of them. FIXME. */
+/* #include "lang_def.h" */
+#define _LANG_c
+#define _LANG_m2
+#define _LANG_chill
+#define _LANG_fortran
+#define _LANG_pascal
+
+#define MAX_FORTRAN_DIMS 7 /* Maximum number of F77 array dims */
+
+/* range_mode ==
+ range_mode_auto: range_check set automatically to default of language.
+ range_mode_manual: range_check set manually by user. */
+
+extern enum range_mode
+ {
+ range_mode_auto, range_mode_manual
+ }
+range_mode;
+
+/* range_check ==
+ range_check_on: Ranges are checked in GDB expressions, producing errors.
+ range_check_warn: Ranges are checked, producing warnings.
+ range_check_off: Ranges are not checked in GDB expressions. */
+
+extern enum range_check
+ {
+ range_check_off, range_check_warn, range_check_on
+ }
+range_check;
+
+/* type_mode ==
+ type_mode_auto: type_check set automatically to default of language
+ type_mode_manual: type_check set manually by user. */
+
+extern enum type_mode
+ {
+ type_mode_auto, type_mode_manual
+ }
+type_mode;
+
+/* type_check ==
+ type_check_on: Types are checked in GDB expressions, producing errors.
+ type_check_warn: Types are checked, producing warnings.
+ type_check_off: Types are not checked in GDB expressions. */
+
+extern enum type_check
+ {
+ type_check_off, type_check_warn, type_check_on
+ }
+type_check;
+
+/* case_mode ==
+ case_mode_auto: case_sensitivity set upon selection of scope
+ case_mode_manual: case_sensitivity set only by user. */
+
+extern enum case_mode
+ {
+ case_mode_auto, case_mode_manual
+ }
+case_mode;
+
+/* case_sensitivity ==
+ case_sensitive_on: Case sensitivity in name matching is used
+ case_sensitive_off: Case sensitivity in name matching is not used */
+
+extern enum case_sensitivity
+ {
+ case_sensitive_on, case_sensitive_off
+ }
+case_sensitivity;
+
+/* Information for doing language dependent formatting of printed values. */
+
+struct language_format_info
+ {
+ /* The format that can be passed directly to standard C printf functions
+ to generate a completely formatted value in the format appropriate for
+ the language. */
+
+ char *la_format;
+
+ /* The prefix to be used when directly printing a value, or constructing
+ a standard C printf format. This generally is everything up to the
+ conversion specification (the part introduced by the '%' character
+ and terminated by the conversion specifier character). */
+
+ char *la_format_prefix;
+
+ /* The conversion specifier. This is generally everything after the
+ field width and precision, typically only a single character such
+ as 'o' for octal format or 'x' for hexadecimal format. */
+
+ char *la_format_specifier;
+
+ /* The suffix to be used when directly printing a value, or constructing
+ a standard C printf format. This generally is everything after the
+ conversion specification (the part introduced by the '%' character
+ and terminated by the conversion specifier character). */
+
+ char *la_format_suffix; /* Suffix for custom format string */
+ };
+
+/* Structure tying together assorted information about a language. */
+
+struct language_defn
+ {
+ /* Name of the language */
+
+ char *la_name;
+
+ /* its symtab language-enum (defs.h) */
+
+ enum language la_language;
+
+ /* Its builtin types. This is a vector ended by a NULL pointer. These
+ types can be specified by name in parsing types in expressions,
+ regardless of whether the program being debugged actually defines
+ such a type. */
+
+ struct type **const *la_builtin_type_vector;
+
+ /* Default range checking */
+
+ enum range_check la_range_check;
+
+ /* Default type checking */
+
+ enum type_check la_type_check;
+
+ /* Default case sensitivity */
+ enum case_sensitivity la_case_sensitivity;
+
+ /* Parser function. */
+
+ int (*la_parser) (void);
+
+ /* Parser error function */
+
+ void (*la_error) (char *);
+
+ /* Evaluate an expression. */
+ struct value *(*evaluate_exp) (struct type *, struct expression *,
+ int *, enum noside);
+
+ void (*la_printchar) (int ch, struct ui_file * stream);
+
+ void (*la_printstr) (struct ui_file * stream, char *string,
+ unsigned int length, int width,
+ int force_ellipses);
+
+ void (*la_emitchar) (int ch, struct ui_file * stream, int quoter);
+
+ struct type *(*la_fund_type) (struct objfile *, int);
+
+ /* Print a type using syntax appropriate for this language. */
+
+ void (*la_print_type) (struct type *, char *, struct ui_file *, int,
+ int);
+
+ /* Print a value using syntax appropriate for this language. */
+
+ int (*la_val_print) (struct type *, char *, int, CORE_ADDR,
+ struct ui_file *, int, int, int,
+ enum val_prettyprint);
+
+ /* Print a top-level value using syntax appropriate for this language. */
+
+ int (*la_value_print) (struct value *, struct ui_file *,
+ int, enum val_prettyprint);
+
+ /* Base 2 (binary) formats. */
+
+ struct language_format_info la_binary_format;
+
+ /* Base 8 (octal) formats. */
+
+ struct language_format_info la_octal_format;
+
+ /* Base 10 (decimal) formats */
+
+ struct language_format_info la_decimal_format;
+
+ /* Base 16 (hexadecimal) formats */
+
+ struct language_format_info la_hex_format;
+
+ /* Table for printing expressions */
+
+ const struct op_print *la_op_print_tab;
+
+ /* Zero if the language has first-class arrays. True if there are no
+ array values, and array objects decay to pointers, as in C. */
+
+ char c_style_arrays;
+
+ /* Index to use for extracting the first element of a string. */
+ char string_lower_bound;
+
+ /* Type of elements of strings. */
+ struct type **string_char_type;
+
+ /* Add fields above this point, so the magic number is always last. */
+ /* Magic number for compat checking */
+
+ long la_magic;
+
+ };
+
+#define LANG_MAGIC 910823L
+
+/* Pointer to the language_defn for our current language. This pointer
+ always points to *some* valid struct; it can be used without checking
+ it for validity.
+
+ The current language affects expression parsing and evaluation
+ (FIXME: it might be cleaner to make the evaluation-related stuff
+ separate exp_opcodes for each different set of semantics. We
+ should at least think this through more clearly with respect to
+ what happens if the language is changed between parsing and
+ evaluation) and printing of things like types and arrays. It does
+ *not* affect symbol-reading-- each source file in a symbol-file has
+ its own language and we should keep track of that regardless of the
+ language when symbols are read. If we want some manual setting for
+ the language of symbol files (e.g. detecting when ".c" files are
+ C++), it should be a separate setting from the current_language. */
+
+extern const struct language_defn *current_language;
+
+/* Pointer to the language_defn expected by the user, e.g. the language
+ of main(), or the language we last mentioned in a message, or C. */
+
+extern const struct language_defn *expected_language;
+
+/* language_mode ==
+ language_mode_auto: current_language automatically set upon selection
+ of scope (e.g. stack frame)
+ language_mode_manual: current_language set only by user. */
+
+extern enum language_mode
+ {
+ language_mode_auto, language_mode_manual
+ }
+language_mode;
+
+/* These macros define the behaviour of the expression
+ evaluator. */
+
+/* Should we strictly type check expressions? */
+#define STRICT_TYPE (type_check != type_check_off)
+
+/* Should we range check values against the domain of their type? */
+#define RANGE_CHECK (range_check != range_check_off)
+
+/* "cast" really means conversion */
+/* FIXME -- should be a setting in language_defn */
+#define CAST_IS_CONVERSION (current_language->la_language == language_c || \
+ current_language->la_language == language_cplus)
+
+extern void language_info (int);
+
+extern enum language set_language (enum language);
+
+
+/* This page contains functions that return things that are
+ specific to languages. Each of these functions is based on
+ the current setting of working_lang, which the user sets
+ with the "set language" command. */
+
+#define create_fundamental_type(objfile,typeid) \
+ (current_language->la_fund_type(objfile, typeid))
+
+#define LA_PRINT_TYPE(type,varstring,stream,show,level) \
+ (current_language->la_print_type(type,varstring,stream,show,level))
+
+#define LA_VAL_PRINT(type,valaddr,offset,addr,stream,fmt,deref,recurse,pretty) \
+ (current_language->la_val_print(type,valaddr,offset,addr,stream,fmt,deref, \
+ recurse,pretty))
+#define LA_VALUE_PRINT(val,stream,fmt,pretty) \
+ (current_language->la_value_print(val,stream,fmt,pretty))
+
+/* Return a format string for printf that will print a number in one of
+ the local (language-specific) formats. Result is static and is
+ overwritten by the next call. Takes printf options like "08" or "l"
+ (to produce e.g. %08x or %lx). */
+
+#define local_binary_format() \
+ (current_language->la_binary_format.la_format)
+#define local_binary_format_prefix() \
+ (current_language->la_binary_format.la_format_prefix)
+#define local_binary_format_specifier() \
+ (current_language->la_binary_format.la_format_specifier)
+#define local_binary_format_suffix() \
+ (current_language->la_binary_format.la_format_suffix)
+
+#define local_octal_format() \
+ (current_language->la_octal_format.la_format)
+#define local_octal_format_prefix() \
+ (current_language->la_octal_format.la_format_prefix)
+#define local_octal_format_specifier() \
+ (current_language->la_octal_format.la_format_specifier)
+#define local_octal_format_suffix() \
+ (current_language->la_octal_format.la_format_suffix)
+
+#define local_decimal_format() \
+ (current_language->la_decimal_format.la_format)
+#define local_decimal_format_prefix() \
+ (current_language->la_decimal_format.la_format_prefix)
+#define local_decimal_format_specifier() \
+ (current_language->la_decimal_format.la_format_specifier)
+#define local_decimal_format_suffix() \
+ (current_language->la_decimal_format.la_format_suffix)
+
+#define local_hex_format() \
+ (current_language->la_hex_format.la_format)
+#define local_hex_format_prefix() \
+ (current_language->la_hex_format.la_format_prefix)
+#define local_hex_format_specifier() \
+ (current_language->la_hex_format.la_format_specifier)
+#define local_hex_format_suffix() \
+ (current_language->la_hex_format.la_format_suffix)
+
+#define LA_PRINT_CHAR(ch, stream) \
+ (current_language->la_printchar(ch, stream))
+#define LA_PRINT_STRING(stream, string, length, width, force_ellipses) \
+ (current_language->la_printstr(stream, string, length, width, force_ellipses))
+#define LA_EMIT_CHAR(ch, stream, quoter) \
+ (current_language->la_emitchar(ch, stream, quoter))
+
+/* Test a character to decide whether it can be printed in literal form
+ or needs to be printed in another representation. For example,
+ in C the literal form of the character with octal value 141 is 'a'
+ and the "other representation" is '\141'. The "other representation"
+ is program language dependent. */
+
+#define PRINT_LITERAL_FORM(c) \
+ ((c) >= 0x20 \
+ && ((c) < 0x7F || (c) >= 0xA0) \
+ && (!sevenbit_strings || (c) < 0x80))
+
+/* Return a format string for printf that will print a number in one of
+ the local (language-specific) formats. Result is static and is
+ overwritten by the next call. Takes printf options like "08" or "l"
+ (to produce e.g. %08x or %lx). */
+
+extern char *local_decimal_format_custom (char *); /* language.c */
+
+extern char *local_octal_format_custom (char *); /* language.c */
+
+extern char *local_hex_format_custom (char *); /* language.c */
+
+#if 0
+/* FIXME: cagney/2000-03-04: This function does not appear to be used.
+ It can be deleted once 5.0 has been released. */
+/* Return a string that contains the hex digits of the number. No preceeding
+ "0x" */
+
+extern char *longest_raw_hex_string (LONGEST);
+#endif
+
+/* Return a string that contains a number formatted in one of the local
+ (language-specific) formats. Result is static and is overwritten by
+ the next call. Takes printf options like "08l" or "l". */
+
+extern char *local_hex_string (LONGEST); /* language.c */
+
+extern char *local_hex_string_custom (LONGEST, char *); /* language.c */
+
+/* Type predicates */
+
+extern int simple_type (struct type *);
+
+extern int ordered_type (struct type *);
+
+extern int same_type (struct type *, struct type *);
+
+extern int integral_type (struct type *);
+
+extern int numeric_type (struct type *);
+
+extern int character_type (struct type *);
+
+extern int boolean_type (struct type *);
+
+extern int float_type (struct type *);
+
+extern int pointer_type (struct type *);
+
+extern int structured_type (struct type *);
+
+/* Checks Binary and Unary operations for semantic type correctness */
+/* FIXME: Does not appear to be used */
+#define unop_type_check(v,o) binop_type_check((v),NULL,(o))
+
+extern void binop_type_check (struct value *, struct value *, int);
+
+/* Error messages */
+
+extern void op_error (char *fmt, enum exp_opcode, int);
+
+#define type_op_error(f,o) \
+ op_error((f),(o),type_check==type_check_on ? 1 : 0)
+#define range_op_error(f,o) \
+ op_error((f),(o),range_check==range_check_on ? 1 : 0)
+
+extern void type_error (const char *, ...) ATTR_FORMAT (printf, 1, 2);
+
+extern void range_error (const char *, ...) ATTR_FORMAT (printf, 1, 2);
+
+/* Data: Does this value represent "truth" to the current language? */
+
+extern int value_true (struct value *);
+
+extern struct type *lang_bool_type (void);
+
+/* The type used for Boolean values in the current language. */
+#define LA_BOOL_TYPE lang_bool_type ()
+
+/* Misc: The string representing a particular enum language. */
+
+extern enum language language_enum (char *str);
+
+extern const struct language_defn *language_def (enum language);
+
+extern char *language_str (enum language);
+
+/* Add a language to the set known by GDB (at initialization time). */
+
+extern void add_language (const struct language_defn *);
+
+extern enum language get_frame_language (void); /* In stack.c */
+
+#endif /* defined (LANGUAGE_H) */
diff --git a/gdb/lin-lwp.c b/gdb/lin-lwp.c
new file mode 100644
index 00000000000..cb5b19f3148
--- /dev/null
+++ b/gdb/lin-lwp.c
@@ -0,0 +1,1549 @@
+/* Multi-threaded debugging support for GNU/Linux (LWP layer).
+ Copyright 2000, 2001 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 "defs.h"
+
+#include "gdb_assert.h"
+#include <errno.h>
+#include <signal.h>
+#include <sys/ptrace.h>
+#include "gdb_wait.h"
+
+#include "gdbthread.h"
+#include "inferior.h"
+#include "target.h"
+#include "regcache.h"
+#include "gdbcmd.h"
+
+static int debug_lin_lwp;
+extern const char *strsignal (int sig);
+
+/* On GNU/Linux there are no real LWP's. The closest thing to LWP's
+ are processes sharing the same VM space. A multi-threaded process
+ is basically a group of such processes. However, such a grouping
+ is almost entirely a user-space issue; the kernel doesn't enforce
+ such a grouping at all (this might change in the future). In
+ general, we'll rely on the threads library (i.e. the GNU/Linux
+ Threads library) to provide such a grouping.
+
+ It is perfectly well possible to write a multi-threaded application
+ without the assistance of a threads library, by using the clone
+ system call directly. This module should be able to give some
+ rudimentary support for debugging such applications if developers
+ specify the CLONE_PTRACE flag in the clone system call, and are
+ using the Linux kernel 2.4 or above.
+
+ Note that there are some peculiarities in GNU/Linux that affect
+ this code:
+
+ - In general one should specify the __WCLONE flag to waitpid in
+ order to make it report events for any of the cloned processes
+ (and leave it out for the initial process). However, if a cloned
+ process has exited the exit status is only reported if the
+ __WCLONE flag is absent. Linux kernel 2.4 has a __WALL flag, but
+ we cannot use it since GDB must work on older systems too.
+
+ - When a traced, cloned process exits and is waited for by the
+ debugger, the kernel reassigns it to the original parent and
+ keeps it around as a "zombie". Somehow, the GNU/Linux Threads
+ library doesn't notice this, which leads to the "zombie problem":
+ When debugged a multi-threaded process that spawns a lot of
+ threads will run out of processes, even if the threads exit,
+ because the "zombies" stay around. */
+
+/* Structure describing a LWP. */
+struct lwp_info
+{
+ /* The process id of the LWP. This is a combination of the LWP id
+ and overall process id. */
+ ptid_t ptid;
+
+ /* Non-zero if this LWP is cloned. In this context "cloned" means
+ that the LWP is reporting to its parent using a signal other than
+ SIGCHLD. */
+ int cloned;
+
+ /* Non-zero if we sent this LWP a SIGSTOP (but the LWP didn't report
+ it back yet). */
+ int signalled;
+
+ /* Non-zero if this LWP is stopped. */
+ int stopped;
+
+ /* Non-zero if this LWP will be/has been resumed. Note that an LWP
+ can be marked both as stopped and resumed at the same time. This
+ happens if we try to resume an LWP that has a wait status
+ pending. We shouldn't let the LWP run until that wait status has
+ been processed, but we should not report that wait status if GDB
+ didn't try to let the LWP run. */
+ int resumed;
+
+ /* If non-zero, a pending wait status. */
+ int status;
+
+ /* Non-zero if we were stepping this LWP. */
+ int step;
+
+ /* Next LWP in list. */
+ struct lwp_info *next;
+};
+
+/* List of known LWPs. */
+static struct lwp_info *lwp_list;
+
+/* Number of LWPs in the list. */
+static int num_lwps;
+
+/* Non-zero if we're running in "threaded" mode. */
+static int threaded;
+
+
+#define GET_LWP(ptid) ptid_get_lwp (ptid)
+#define GET_PID(ptid) ptid_get_pid (ptid)
+#define is_lwp(ptid) (GET_LWP (ptid) != 0)
+#define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
+
+/* If the last reported event was a SIGTRAP, this variable is set to
+ the process id of the LWP/thread that got it. */
+ptid_t trap_ptid;
+
+
+/* This module's target-specific operations. */
+static struct target_ops lin_lwp_ops;
+
+/* The standard child operations. */
+extern struct target_ops child_ops;
+
+/* Since we cannot wait (in lin_lwp_wait) for the initial process and
+ any cloned processes with a single call to waitpid, we have to use
+ the WNOHANG flag and call waitpid in a loop. To optimize
+ things a bit we use `sigsuspend' to wake us up when a process has
+ something to report (it will send us a SIGCHLD if it has). To make
+ this work we have to juggle with the signal mask. We save the
+ original signal mask such that we can restore it before creating a
+ new process in order to avoid blocking certain signals in the
+ inferior. We then block SIGCHLD during the waitpid/sigsuspend
+ loop. */
+
+/* Original signal mask. */
+static sigset_t normal_mask;
+
+/* Signal mask for use with sigsuspend in lin_lwp_wait, initialized in
+ _initialize_lin_lwp. */
+static sigset_t suspend_mask;
+
+/* Signals to block to make that sigsuspend work. */
+static sigset_t blocked_mask;
+
+
+/* Prototypes for local functions. */
+static int stop_wait_callback (struct lwp_info *lp, void *data);
+
+/* Convert wait status STATUS to a string. Used for printing debug
+ messages only. */
+
+static char *
+status_to_str (int status)
+{
+ static char buf[64];
+
+ if (WIFSTOPPED (status))
+ snprintf (buf, sizeof (buf), "%s (stopped)",
+ strsignal (WSTOPSIG (status)));
+ else if (WIFSIGNALED (status))
+ snprintf (buf, sizeof (buf), "%s (terminated)",
+ strsignal (WSTOPSIG (status)));
+ else
+ snprintf (buf, sizeof (buf), "%d (exited)",
+ WEXITSTATUS (status));
+
+ return buf;
+}
+
+/* Initialize the list of LWPs. Note that this module, contrary to
+ what GDB's generic threads layer does for its thread list,
+ re-initializes the LWP lists whenever we mourn or detach (which
+ doesn't involve mourning) the inferior. */
+
+static void
+init_lwp_list (void)
+{
+ struct lwp_info *lp, *lpnext;
+
+ for (lp = lwp_list; lp; lp = lpnext)
+ {
+ lpnext = lp->next;
+ xfree (lp);
+ }
+
+ lwp_list = NULL;
+ num_lwps = 0;
+ threaded = 0;
+}
+
+/* Add the LWP specified by PID to the list. If this causes the
+ number of LWPs to become larger than one, go into "threaded" mode.
+ Return a pointer to the structure describing the new LWP. */
+
+static struct lwp_info *
+add_lwp (ptid_t ptid)
+{
+ struct lwp_info *lp;
+
+ gdb_assert (is_lwp (ptid));
+
+ lp = (struct lwp_info *) xmalloc (sizeof (struct lwp_info));
+
+ memset (lp, 0, sizeof (struct lwp_info));
+
+ lp->ptid = ptid;
+
+ lp->next = lwp_list;
+ lwp_list = lp;
+ if (++num_lwps > 1)
+ threaded = 1;
+
+ return lp;
+}
+
+/* Remove the LWP specified by PID from the list. */
+
+static void
+delete_lwp (ptid_t ptid)
+{
+ struct lwp_info *lp, *lpprev;
+
+ lpprev = NULL;
+
+ for (lp = lwp_list; lp; lpprev = lp, lp = lp->next)
+ if (ptid_equal (lp->ptid, ptid))
+ break;
+
+ if (!lp)
+ return;
+
+ /* We don't go back to "non-threaded" mode if the number of threads
+ becomes less than two. */
+ num_lwps--;
+
+ if (lpprev)
+ lpprev->next = lp->next;
+ else
+ lwp_list = lp->next;
+
+ xfree (lp);
+}
+
+/* Return a pointer to the structure describing the LWP corresponding
+ to PID. If no corresponding LWP could be found, return NULL. */
+
+static struct lwp_info *
+find_lwp_pid (ptid_t ptid)
+{
+ struct lwp_info *lp;
+ int lwp;
+
+ if (is_lwp (ptid))
+ lwp = GET_LWP (ptid);
+ else
+ lwp = GET_PID (ptid);
+
+ for (lp = lwp_list; lp; lp = lp->next)
+ if (lwp == GET_LWP (lp->ptid))
+ return lp;
+
+ return NULL;
+}
+
+/* Call CALLBACK with its second argument set to DATA for every LWP in
+ the list. If CALLBACK returns 1 for a particular LWP, return a
+ pointer to the structure describing that LWP immediately.
+ Otherwise return NULL. */
+
+struct lwp_info *
+iterate_over_lwps (int (*callback) (struct lwp_info *, void *), void *data)
+{
+ struct lwp_info *lp, *lpnext;
+
+ for (lp = lwp_list; lp; lp = lpnext)
+ {
+ lpnext = lp->next;
+ if ((*callback) (lp, data))
+ return lp;
+ }
+
+ return NULL;
+}
+
+
+/* Implementation of the PREPARE_TO_PROCEED hook for the GNU/Linux LWP
+ layer.
+
+ Note that this implementation is potentially redundant now that
+ default_prepare_to_proceed() has been added.
+
+ FIXME This may not support switching threads after Ctrl-C
+ correctly. The default implementation does support this. */
+
+int
+lin_lwp_prepare_to_proceed (void)
+{
+ if (! ptid_equal (trap_ptid, null_ptid)
+ && ! ptid_equal (inferior_ptid, trap_ptid))
+ {
+ /* Switched over from TRAP_PID. */
+ CORE_ADDR stop_pc = read_pc ();
+ CORE_ADDR trap_pc;
+
+ /* Avoid switching where it wouldn't do any good, i.e. if both
+ threads are at the same breakpoint. */
+ trap_pc = read_pc_pid (trap_ptid);
+ if (trap_pc != stop_pc && breakpoint_here_p (trap_pc))
+ {
+ /* User hasn't deleted the breakpoint. Return non-zero, and
+ switch back to TRAP_PID. */
+ inferior_ptid = trap_ptid;
+
+ /* FIXME: Is this stuff really necessary? */
+ flush_cached_frames ();
+ registers_changed ();
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+#if 0
+static void
+lin_lwp_open (char *args, int from_tty)
+{
+ push_target (&lin_lwp_ops);
+}
+#endif
+
+/* Attach to the LWP specified by PID. If VERBOSE is non-zero, print
+ a message telling the user that a new LWP has been added to the
+ process. */
+
+void
+lin_lwp_attach_lwp (ptid_t ptid, int verbose)
+{
+ struct lwp_info *lp;
+
+ gdb_assert (is_lwp (ptid));
+
+ /* Make sure SIGCHLD is blocked. We don't want SIGCHLD events
+ to interrupt either the ptrace() or waitpid() calls below. */
+ if (! sigismember (&blocked_mask, SIGCHLD))
+ {
+ sigaddset (&blocked_mask, SIGCHLD);
+ sigprocmask (SIG_BLOCK, &blocked_mask, NULL);
+ }
+
+ if (verbose)
+ printf_filtered ("[New %s]\n", target_pid_to_str (ptid));
+
+ lp = find_lwp_pid (ptid);
+ if (lp == NULL)
+ lp = add_lwp (ptid);
+
+ /* We assume that we're already attached to any LWP that has an
+ id equal to the overall process id. */
+ if (GET_LWP (ptid) != GET_PID (ptid))
+ {
+ pid_t pid;
+ int status;
+
+ if (ptrace (PTRACE_ATTACH, GET_LWP (ptid), 0, 0) < 0)
+ error ("Can't attach %s: %s", target_pid_to_str (ptid),
+ safe_strerror (errno));
+
+ pid = waitpid (GET_LWP (ptid), &status, 0);
+ if (pid == -1 && errno == ECHILD)
+ {
+ /* Try again with __WCLONE to check cloned processes. */
+ pid = waitpid (GET_LWP (ptid), &status, __WCLONE);
+ lp->cloned = 1;
+ }
+
+ gdb_assert (pid == GET_LWP (ptid)
+ && WIFSTOPPED (status) && WSTOPSIG (status));
+
+ lp->stopped = 1;
+ }
+ else
+ {
+ /* We assume that the LWP representing the original process
+ is already stopped. Mark it as stopped in the data structure
+ that the lin-lwp layer uses to keep track of threads. Note
+ that this won't have already been done since the main thread
+ will have, we assume, been stopped by an attach from a
+ different layer. */
+ lp->stopped = 1;
+ }
+}
+
+static void
+lin_lwp_attach (char *args, int from_tty)
+{
+ struct lwp_info *lp;
+ pid_t pid;
+ int status;
+
+ /* FIXME: We should probably accept a list of process id's, and
+ attach all of them. */
+ child_ops.to_attach (args, from_tty);
+
+ /* Add the initial process as the first LWP to the list. */
+ lp = add_lwp (BUILD_LWP (GET_PID (inferior_ptid), GET_PID (inferior_ptid)));
+
+ /* Make sure the initial process is stopped. The user-level threads
+ layer might want to poke around in the inferior, and that won't
+ work if things haven't stabilized yet. */
+ pid = waitpid (GET_PID (inferior_ptid), &status, 0);
+ if (pid == -1 && errno == ECHILD)
+ {
+ warning ("%s is a cloned process", target_pid_to_str (inferior_ptid));
+
+ /* Try again with __WCLONE to check cloned processes. */
+ pid = waitpid (GET_PID (inferior_ptid), &status, __WCLONE);
+ lp->cloned = 1;
+ }
+
+ gdb_assert (pid == GET_PID (inferior_ptid)
+ && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP);
+
+ lp->stopped = 1;
+
+ /* Fake the SIGSTOP that core GDB expects. */
+ lp->status = W_STOPCODE (SIGSTOP);
+ lp->resumed = 1;
+}
+
+static int
+detach_callback (struct lwp_info *lp, void *data)
+{
+ gdb_assert (lp->status == 0 || WIFSTOPPED (lp->status));
+
+ if (debug_lin_lwp && lp->status)
+ fprintf_unfiltered (gdb_stdlog, "Pending %s for LWP %ld on detach.\n",
+ strsignal (WSTOPSIG (lp->status)), GET_LWP (lp->ptid));
+
+ while (lp->signalled && lp->stopped)
+ {
+ if (ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0,
+ WSTOPSIG (lp->status)) < 0)
+ error ("Can't continue %s: %s", target_pid_to_str (lp->ptid),
+ safe_strerror (errno));
+
+ lp->stopped = 0;
+ lp->signalled = 0;
+ lp->status = 0;
+ stop_wait_callback (lp, NULL);
+
+ gdb_assert (lp->status == 0 || WIFSTOPPED (lp->status));
+ }
+
+ /* We don't actually detach from the LWP that has an id equal to the
+ overall process id just yet. */
+ if (GET_LWP (lp->ptid) != GET_PID (lp->ptid))
+ {
+ if (ptrace (PTRACE_DETACH, GET_LWP (lp->ptid), 0,
+ WSTOPSIG (lp->status)) < 0)
+ error ("Can't detach %s: %s", target_pid_to_str (lp->ptid),
+ safe_strerror (errno));
+
+ delete_lwp (lp->ptid);
+ }
+
+ return 0;
+}
+
+static void
+lin_lwp_detach (char *args, int from_tty)
+{
+ iterate_over_lwps (detach_callback, NULL);
+
+ /* Only the initial process should be left right now. */
+ gdb_assert (num_lwps == 1);
+
+ trap_ptid = null_ptid;
+
+ /* Destroy LWP info; it's no longer valid. */
+ init_lwp_list ();
+
+ /* Restore the original signal mask. */
+ sigprocmask (SIG_SETMASK, &normal_mask, NULL);
+ sigemptyset (&blocked_mask);
+
+ inferior_ptid = pid_to_ptid (GET_PID (inferior_ptid));
+ child_ops.to_detach (args, from_tty);
+}
+
+
+struct private_thread_info
+{
+ int lwpid;
+};
+
+/* Return non-zero if TP corresponds to the LWP specified by DATA
+ (which is assumed to be a pointer to a `struct lwp_info'. */
+
+static int
+find_lwp_callback (struct thread_info *tp, void *data)
+{
+ struct lwp_info *lp = data;
+
+ if (tp->private->lwpid == GET_LWP (lp->ptid))
+ return 1;
+
+ return 0;
+}
+
+/* Resume LP. */
+
+static int
+resume_callback (struct lwp_info *lp, void *data)
+{
+ if (lp->stopped && lp->status == 0)
+ {
+ struct thread_info *tp;
+
+#if 0
+ /* FIXME: kettenis/2000-08-26: This should really be handled
+ properly by core GDB. */
+
+ tp = find_thread_pid (lp->ptid);
+ if (tp == NULL)
+ tp = iterate_over_threads (find_lwp_callback, lp);
+ gdb_assert (tp);
+
+ /* If we were previously stepping the thread, and now continue
+ the thread we must invalidate the stepping range. However,
+ if there is a step_resume breakpoint for this thread, we must
+ preserve the stepping range to make it possible to continue
+ stepping once we hit it. */
+ if (tp->step_range_end && tp->step_resume_breakpoint == NULL)
+ {
+ gdb_assert (lp->step);
+ tp->step_range_start = tp->step_range_end = 0;
+ }
+#endif
+
+ child_resume (pid_to_ptid (GET_LWP (lp->ptid)), 0, TARGET_SIGNAL_0);
+ lp->stopped = 0;
+ lp->step = 0;
+ }
+
+ return 0;
+}
+
+static int
+resume_clear_callback (struct lwp_info *lp, void *data)
+{
+ lp->resumed = 0;
+ return 0;
+}
+
+static int
+resume_set_callback (struct lwp_info *lp, void *data)
+{
+ lp->resumed = 1;
+ return 0;
+}
+
+static void
+lin_lwp_resume (ptid_t ptid, int step, enum target_signal signo)
+{
+ struct lwp_info *lp;
+ int resume_all;
+
+ /* Apparently the interpretation of PID is dependent on STEP: If
+ STEP is non-zero, a specific PID means `step only this process
+ id'. But if STEP is zero, then PID means `continue *all*
+ processes, but give the signal only to this one'. */
+ resume_all = (PIDGET (ptid) == -1) || !step;
+
+ if (resume_all)
+ iterate_over_lwps (resume_set_callback, NULL);
+ else
+ iterate_over_lwps (resume_clear_callback, NULL);
+
+ /* If PID is -1, it's the current inferior that should be
+ handled specially. */
+ if (PIDGET (ptid) == -1)
+ ptid = inferior_ptid;
+
+ lp = find_lwp_pid (ptid);
+ if (lp)
+ {
+ ptid = pid_to_ptid (GET_LWP (lp->ptid));
+
+ /* Remember if we're stepping. */
+ lp->step = step;
+
+ /* Mark this LWP as resumed. */
+ lp->resumed = 1;
+
+ /* If we have a pending wait status for this thread, there is no
+ point in resuming the process. */
+ if (lp->status)
+ {
+ /* FIXME: What should we do if we are supposed to continue
+ this thread with a signal? */
+ gdb_assert (signo == TARGET_SIGNAL_0);
+ return;
+ }
+
+ /* Mark LWP as not stopped to prevent it from being continued by
+ resume_callback. */
+ lp->stopped = 0;
+ }
+
+ if (resume_all)
+ iterate_over_lwps (resume_callback, NULL);
+
+ child_resume (ptid, step, signo);
+}
+
+
+/* Send a SIGSTOP to LP. */
+
+static int
+stop_callback (struct lwp_info *lp, void *data)
+{
+ if (! lp->stopped && ! lp->signalled)
+ {
+ int ret;
+
+ ret = kill (GET_LWP (lp->ptid), SIGSTOP);
+ gdb_assert (ret == 0);
+
+ lp->signalled = 1;
+ gdb_assert (lp->status == 0);
+ }
+
+ return 0;
+}
+
+/* Wait until LP is stopped. If DATA is non-null it is interpreted as
+ a pointer to a set of signals to be flushed immediately. */
+
+static int
+stop_wait_callback (struct lwp_info *lp, void *data)
+{
+ sigset_t *flush_mask = data;
+
+ if (! lp->stopped && lp->signalled)
+ {
+ pid_t pid;
+ int status;
+
+ gdb_assert (lp->status == 0);
+
+ pid = waitpid (GET_LWP (lp->ptid), &status, lp->cloned ? __WCLONE : 0);
+ if (pid == -1 && errno == ECHILD)
+ /* OK, the proccess has disappeared. We'll catch the actual
+ exit event in lin_lwp_wait. */
+ return 0;
+
+ gdb_assert (pid == GET_LWP (lp->ptid));
+
+ if (WIFEXITED (status) || WIFSIGNALED (status))
+ {
+ gdb_assert (num_lwps > 1);
+
+ if (in_thread_list (lp->ptid))
+ {
+ /* Core GDB cannot deal with us deleting the current
+ thread. */
+ if (!ptid_equal (lp->ptid, inferior_ptid))
+ delete_thread (lp->ptid);
+ printf_unfiltered ("[%s exited]\n",
+ target_pid_to_str (lp->ptid));
+ }
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog,
+ "%s exited.\n", target_pid_to_str (lp->ptid));
+
+ delete_lwp (lp->ptid);
+ return 0;
+ }
+
+ gdb_assert (WIFSTOPPED (status));
+
+ /* Ignore any signals in FLUSH_MASK. */
+ if (flush_mask && sigismember (flush_mask, WSTOPSIG (status)))
+ {
+ ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
+ return stop_wait_callback (lp, flush_mask);
+ }
+
+ if (WSTOPSIG (status) != SIGSTOP)
+ {
+ if (WSTOPSIG (status) == SIGTRAP)
+ {
+ /* If a LWP other than the LWP that we're reporting an
+ event for has hit a GDB breakpoint (as opposed to
+ some random trap signal), then just arrange for it to
+ hit it again later. We don't keep the SIGTRAP status
+ and don't forward the SIGTRAP signal to the LWP. We
+ will handle the current event, eventually we will
+ resume all LWPs, and this one will get its breakpoint
+ trap again.
+
+ If we do not do this, then we run the risk that the
+ user will delete or disable the breakpoint, but the
+ thread will have already tripped on it. */
+
+ /* Now resume this LWP and get the SIGSTOP event. */
+ ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
+ if (debug_lin_lwp)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "SWC: Candidate SIGTRAP event in %ld\n",
+ GET_LWP (lp->ptid));
+ }
+ /* Hold the SIGTRAP for handling by lin_lwp_wait. */
+ stop_wait_callback (lp, data);
+ /* If there's another event, throw it back into the queue. */
+ if (lp->status)
+ kill (GET_LWP (lp->ptid), WSTOPSIG (lp->status));
+ /* Save the sigtrap event. */
+ lp->status = status;
+ return 0;
+ }
+ else
+ {
+ /* The thread was stopped with a signal other than
+ SIGSTOP, and didn't accidentally trip a breakpoint. */
+
+ if (debug_lin_lwp)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "SWC: Pending event %d in %ld\n",
+ WSTOPSIG (status), GET_LWP (lp->ptid));
+ }
+ /* Now resume this LWP and get the SIGSTOP event. */
+ ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
+
+ /* Hold this event/waitstatus while we check to see if
+ there are any more (we still want to get that SIGSTOP). */
+ stop_wait_callback (lp, data);
+ /* If the lp->status field is still empty, use it to hold
+ this event. If not, then this event must be returned
+ to the event queue of the LWP. */
+ if (lp->status == 0)
+ lp->status = status;
+ else
+ kill (GET_LWP (lp->ptid), WSTOPSIG (status));
+ return 0;
+ }
+ }
+ else
+ {
+ /* We caught the SIGSTOP that we intended to catch, so
+ there's no SIGSTOP pending. */
+ lp->stopped = 1;
+ lp->signalled = 0;
+ }
+ }
+
+ return 0;
+}
+
+/* Return non-zero if LP has a wait status pending. */
+
+static int
+status_callback (struct lwp_info *lp, void *data)
+{
+ /* Only report a pending wait status if we pretend that this has
+ indeed been resumed. */
+ return (lp->status != 0 && lp->resumed);
+}
+
+/* Return non-zero if LP isn't stopped. */
+
+static int
+running_callback (struct lwp_info *lp, void *data)
+{
+ return (lp->stopped == 0);
+}
+
+/* Count the LWP's that have had events. */
+
+static int
+count_events_callback (struct lwp_info *lp, void *data)
+{
+ int *count = data;
+
+ gdb_assert (count != NULL);
+
+ /* Count only LWPs that have a SIGTRAP event pending. */
+ if (lp->status != 0
+ && WIFSTOPPED (lp->status) && WSTOPSIG (lp->status) == SIGTRAP)
+ (*count)++;
+
+ return 0;
+}
+
+/* Select the LWP (if any) that is currently being single-stepped. */
+
+static int
+select_singlestep_lwp_callback (struct lwp_info *lp, void *data)
+{
+ if (lp->step && lp->status != 0)
+ return 1;
+ else
+ return 0;
+}
+
+/* Select the Nth LWP that has had a SIGTRAP event. */
+
+static int
+select_event_lwp_callback (struct lwp_info *lp, void *data)
+{
+ int *selector = data;
+
+ gdb_assert (selector != NULL);
+
+ /* Select only LWPs that have a SIGTRAP event pending. */
+ if (lp->status != 0
+ && WIFSTOPPED (lp->status) && WSTOPSIG (lp->status) == SIGTRAP)
+ if ((*selector)-- == 0)
+ return 1;
+
+ return 0;
+}
+
+static int
+cancel_breakpoints_callback (struct lwp_info *lp, void *data)
+{
+ struct lwp_info *event_lp = data;
+
+ /* Leave the LWP that has been elected to receive a SIGTRAP alone. */
+ if (lp == event_lp)
+ return 0;
+
+ /* If a LWP other than the LWP that we're reporting an event for has
+ hit a GDB breakpoint (as opposed to some random trap signal),
+ then just arrange for it to hit it again later. We don't keep
+ the SIGTRAP status and don't forward the SIGTRAP signal to the
+ LWP. We will handle the current event, eventually we will resume
+ all LWPs, and this one will get its breakpoint trap again.
+
+ If we do not do this, then we run the risk that the user will
+ delete or disable the breakpoint, but the LWP will have already
+ tripped on it. */
+
+ if (lp->status != 0
+ && WIFSTOPPED (lp->status) && WSTOPSIG (lp->status) == SIGTRAP
+ && breakpoint_inserted_here_p (read_pc_pid (lp->ptid) -
+ DECR_PC_AFTER_BREAK))
+ {
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog,
+ "Push back breakpoint for LWP %ld\n",
+ GET_LWP (lp->ptid));
+
+ /* Back up the PC if necessary. */
+ if (DECR_PC_AFTER_BREAK)
+ write_pc_pid (read_pc_pid (lp->ptid) - DECR_PC_AFTER_BREAK, lp->ptid);
+
+ /* Throw away the SIGTRAP. */
+ lp->status = 0;
+ }
+
+ return 0;
+}
+
+/* Select one LWP out of those that have events pending. */
+
+static void
+select_event_lwp (struct lwp_info **orig_lp, int *status)
+{
+ int num_events = 0;
+ int random_selector;
+ struct lwp_info *event_lp;
+
+ /* Record the wait status for the origional LWP. */
+ (*orig_lp)->status = *status;
+
+ /* Give preference to any LWP that is being single-stepped. */
+ event_lp = iterate_over_lwps (select_singlestep_lwp_callback, NULL);
+ if (event_lp != NULL)
+ {
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog,
+ "Select single-step LWP %ld\n",
+ GET_LWP (event_lp->ptid));
+ }
+ else
+ {
+ /* No single-stepping LWP. Select one at random, out of those
+ which have had SIGTRAP events. */
+
+ /* First see how many SIGTRAP events we have. */
+ iterate_over_lwps (count_events_callback, &num_events);
+
+ /* Now randomly pick a LWP out of those that have had a SIGTRAP. */
+ random_selector = (int)
+ ((num_events * (double) rand ()) / (RAND_MAX + 1.0));
+
+ if (debug_lin_lwp && num_events > 1)
+ fprintf_unfiltered (gdb_stdlog,
+ "Found %d SIGTRAP events, selecting #%d\n",
+ num_events, random_selector);
+
+ event_lp = iterate_over_lwps (select_event_lwp_callback,
+ &random_selector);
+ }
+
+ if (event_lp != NULL)
+ {
+ /* Switch the event LWP. */
+ *orig_lp = event_lp;
+ *status = event_lp->status;
+ }
+
+ /* Flush the wait status for the event LWP. */
+ (*orig_lp)->status = 0;
+}
+
+/* Return non-zero if LP has been resumed. */
+
+static int
+resumed_callback (struct lwp_info *lp, void *data)
+{
+ return lp->resumed;
+}
+
+#ifdef CHILD_WAIT
+
+/* We need to override child_wait to support attaching to cloned
+ processes, since a normal wait (as done by the default version)
+ ignores those processes. */
+
+/* Wait for child PTID to do something. Return id of the child,
+ minus_one_ptid in case of error; store status into *OURSTATUS. */
+
+ptid_t
+child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+{
+ int save_errno;
+ int status;
+ pid_t pid;
+
+ do
+ {
+ set_sigint_trap (); /* Causes SIGINT to be passed on to the
+ attached process. */
+ set_sigio_trap ();
+
+ pid = waitpid (GET_PID (ptid), &status, 0);
+ if (pid == -1 && errno == ECHILD)
+ /* Try again with __WCLONE to check cloned processes. */
+ pid = waitpid (GET_PID (ptid), &status, __WCLONE);
+ save_errno = errno;
+
+ clear_sigio_trap ();
+ clear_sigint_trap ();
+ }
+ while (pid == -1 && save_errno == EINTR);
+
+ if (pid == -1)
+ {
+ warning ("Child process unexpectedly missing: %s", safe_strerror (errno));
+
+ /* Claim it exited with unknown signal. */
+ ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
+ ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
+ return minus_one_ptid;
+ }
+
+ store_waitstatus (ourstatus, status);
+ return pid_to_ptid (pid);
+}
+
+#endif
+
+static ptid_t
+lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+{
+ struct lwp_info *lp = NULL;
+ int options = 0;
+ int status = 0;
+ pid_t pid = PIDGET (ptid);
+ sigset_t flush_mask;
+
+ sigemptyset (&flush_mask);
+
+ /* Make sure SIGCHLD is blocked. */
+ if (! sigismember (&blocked_mask, SIGCHLD))
+ {
+ sigaddset (&blocked_mask, SIGCHLD);
+ sigprocmask (SIG_BLOCK, &blocked_mask, NULL);
+ }
+
+ retry:
+
+ /* Make sure there is at least one LWP that has been resumed, at
+ least if there are any LWPs at all. */
+ gdb_assert (num_lwps == 0 || iterate_over_lwps (resumed_callback, NULL));
+
+ /* First check if there is a LWP with a wait status pending. */
+ if (pid == -1)
+ {
+ /* Any LWP that's been resumed will do. */
+ lp = iterate_over_lwps (status_callback, NULL);
+ if (lp)
+ {
+ status = lp->status;
+ lp->status = 0;
+
+ if (debug_lin_lwp && status)
+ fprintf_unfiltered (gdb_stdlog,
+ "Using pending wait status %s for LWP %ld.\n",
+ status_to_str (status), GET_LWP (lp->ptid));
+ }
+
+ /* But if we don't fine one, we'll have to wait, and check both
+ cloned and uncloned processes. We start with the cloned
+ processes. */
+ options = __WCLONE | WNOHANG;
+ }
+ else if (is_lwp (ptid))
+ {
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog,
+ "Waiting for specific LWP %ld.\n",
+ GET_LWP (ptid));
+
+ /* We have a specific LWP to check. */
+ lp = find_lwp_pid (ptid);
+ gdb_assert (lp);
+ status = lp->status;
+ lp->status = 0;
+
+ if (debug_lin_lwp && status)
+ fprintf_unfiltered (gdb_stdlog,
+ "Using pending wait status %s for LWP %ld.\n",
+ status_to_str (status), GET_LWP (lp->ptid));
+
+ /* If we have to wait, take into account whether PID is a cloned
+ process or not. And we have to convert it to something that
+ the layer beneath us can understand. */
+ options = lp->cloned ? __WCLONE : 0;
+ pid = GET_LWP (ptid);
+ }
+
+ if (status && lp->signalled)
+ {
+ /* A pending SIGSTOP may interfere with the normal stream of
+ events. In a typical case where interference is a problem,
+ we have a SIGSTOP signal pending for LWP A while
+ single-stepping it, encounter an event in LWP B, and take the
+ pending SIGSTOP while trying to stop LWP A. After processing
+ the event in LWP B, LWP A is continued, and we'll never see
+ the SIGTRAP associated with the last time we were
+ single-stepping LWP A. */
+
+ /* Resume the thread. It should halt immediately returning the
+ pending SIGSTOP. */
+ child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step,
+ TARGET_SIGNAL_0);
+ lp->stopped = 0;
+ gdb_assert (lp->resumed);
+
+ /* This should catch the pending SIGSTOP. */
+ stop_wait_callback (lp, NULL);
+ }
+
+ set_sigint_trap (); /* Causes SIGINT to be passed on to the
+ attached process. */
+ set_sigio_trap ();
+
+ while (status == 0)
+ {
+ pid_t lwpid;
+
+ lwpid = waitpid (pid, &status, options);
+ if (lwpid > 0)
+ {
+ gdb_assert (pid == -1 || lwpid == pid);
+
+ lp = find_lwp_pid (pid_to_ptid (lwpid));
+ if (! lp)
+ {
+ lp = add_lwp (BUILD_LWP (lwpid, GET_PID (inferior_ptid)));
+ if (options & __WCLONE)
+ lp->cloned = 1;
+
+ if (threaded)
+ {
+ gdb_assert (WIFSTOPPED (status)
+ && WSTOPSIG (status) == SIGSTOP);
+ lp->signalled = 1;
+
+ if (! in_thread_list (inferior_ptid))
+ {
+ inferior_ptid = BUILD_LWP (GET_PID (inferior_ptid),
+ GET_PID (inferior_ptid));
+ add_thread (inferior_ptid);
+ }
+
+ add_thread (lp->ptid);
+ printf_unfiltered ("[New %s]\n",
+ target_pid_to_str (lp->ptid));
+ }
+ }
+
+ /* Make sure we don't report a TARGET_WAITKIND_EXITED or
+ TARGET_WAITKIND_SIGNALLED event if there are still LWP's
+ left in the process. */
+ if ((WIFEXITED (status) || WIFSIGNALED (status)) && num_lwps > 1)
+ {
+ if (in_thread_list (lp->ptid))
+ {
+ /* Core GDB cannot deal with us deleting the current
+ thread. */
+ if (! ptid_equal (lp->ptid, inferior_ptid))
+ delete_thread (lp->ptid);
+ printf_unfiltered ("[%s exited]\n",
+ target_pid_to_str (lp->ptid));
+ }
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog,
+ "%s exited.\n",
+ target_pid_to_str (lp->ptid));
+
+ delete_lwp (lp->ptid);
+
+ /* Make sure there is at least one thread running. */
+ gdb_assert (iterate_over_lwps (running_callback, NULL));
+
+ /* Discard the event. */
+ status = 0;
+ continue;
+ }
+
+ /* Make sure we don't report a SIGSTOP that we sent
+ ourselves in an attempt to stop an LWP. */
+ if (lp->signalled && WIFSTOPPED (status)
+ && WSTOPSIG (status) == SIGSTOP)
+ {
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog,
+ "Delayed SIGSTOP caught for %s.\n",
+ target_pid_to_str (lp->ptid));
+
+ /* This is a delayed SIGSTOP. */
+ lp->signalled = 0;
+
+ child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step,
+ TARGET_SIGNAL_0);
+ lp->stopped = 0;
+ gdb_assert (lp->resumed);
+
+ /* Discard the event. */
+ status = 0;
+ continue;
+ }
+
+ break;
+ }
+
+ if (pid == -1)
+ {
+ /* Alternate between checking cloned and uncloned processes. */
+ options ^= __WCLONE;
+
+ /* And suspend every time we have checked both. */
+ if (options & __WCLONE)
+ sigsuspend (&suspend_mask);
+ }
+
+ /* We shouldn't end up here unless we want to try again. */
+ gdb_assert (status == 0);
+ }
+
+ clear_sigio_trap ();
+ clear_sigint_trap ();
+
+ gdb_assert (lp);
+
+ /* Don't report signals that GDB isn't interested in, such as
+ signals that are neither printed nor stopped upon. Stopping all
+ threads can be a bit time-consuming so if we want decent
+ performance with heavily multi-threaded programs, especially when
+ they're using a high frequency timer, we'd better avoid it if we
+ can. */
+
+ if (WIFSTOPPED (status))
+ {
+ int signo = target_signal_from_host (WSTOPSIG (status));
+
+ if (signal_stop_state (signo) == 0
+ && signal_print_state (signo) == 0
+ && signal_pass_state (signo) == 1)
+ {
+ /* FIMXE: kettenis/2001-06-06: Should we resume all threads
+ here? It is not clear we should. GDB may not expect
+ other threads to run. On the other hand, not resuming
+ newly attached threads may cause an unwanted delay in
+ getting them running. */
+ child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step, signo);
+ lp->stopped = 0;
+ status = 0;
+ goto retry;
+ }
+
+ if (signo == TARGET_SIGNAL_INT
+ && signal_pass_state (signo) == 0)
+ {
+ /* If ^C/BREAK is typed at the tty/console, SIGINT gets
+ forwarded to the entire process group, that is, all LWP's
+ will receive it. Since we only want to report it once,
+ we try to flush it from all LWPs except this one. */
+ sigaddset (&flush_mask, SIGINT);
+ }
+ }
+
+ /* This LWP is stopped now. */
+ lp->stopped = 1;
+
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog, "Candidate event %s in LWP %ld.\n",
+ status_to_str (status), GET_LWP (lp->ptid));
+
+ /* Now stop all other LWP's ... */
+ iterate_over_lwps (stop_callback, NULL);
+
+ /* ... and wait until all of them have reported back that they're no
+ longer running. */
+ iterate_over_lwps (stop_wait_callback, &flush_mask);
+
+ /* If we're not waiting for a specific LWP, choose an event LWP from
+ among those that have had events. Giving equal priority to all
+ LWPs that have had events helps prevent starvation. */
+ if (pid == -1)
+ select_event_lwp (&lp, &status);
+
+ /* Now that we've selected our final event LWP, cancel any
+ breakpoints in other LWPs that have hit a GDB breakpoint. See
+ the comment in cancel_breakpoints_callback to find out why. */
+ iterate_over_lwps (cancel_breakpoints_callback, lp);
+
+ /* If we're not running in "threaded" mode, we'll report the bare
+ process id. */
+
+ if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP)
+ {
+ trap_ptid = (threaded ? lp->ptid : pid_to_ptid (GET_LWP (lp->ptid)));
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog,
+ "LLW: trap_ptid is %ld\n",
+ GET_LWP (trap_ptid));
+ }
+ else
+ trap_ptid = null_ptid;
+
+ store_waitstatus (ourstatus, status);
+ return (threaded ? lp->ptid : pid_to_ptid (GET_LWP (lp->ptid)));
+}
+
+static int
+kill_callback (struct lwp_info *lp, void *data)
+{
+ ptrace (PTRACE_KILL, GET_LWP (lp->ptid), 0, 0);
+ return 0;
+}
+
+static int
+kill_wait_callback (struct lwp_info *lp, void *data)
+{
+ pid_t pid;
+
+ /* We must make sure that there are no pending events (delayed
+ SIGSTOPs, pending SIGTRAPs, etc.) to make sure the current
+ program doesn't interfere with any following debugging session. */
+
+ /* For cloned processes we must check both with __WCLONE and
+ without, since the exit status of a cloned process isn't reported
+ with __WCLONE. */
+ if (lp->cloned)
+ {
+ do
+ {
+ pid = waitpid (GET_LWP (lp->ptid), NULL, __WCLONE);
+ }
+ while (pid == GET_LWP (lp->ptid));
+
+ gdb_assert (pid == -1 && errno == ECHILD);
+ }
+
+ do
+ {
+ pid = waitpid (GET_LWP (lp->ptid), NULL, 0);
+ }
+ while (pid == GET_LWP (lp->ptid));
+
+ gdb_assert (pid == -1 && errno == ECHILD);
+ return 0;
+}
+
+static void
+lin_lwp_kill (void)
+{
+ /* Kill all LWP's ... */
+ iterate_over_lwps (kill_callback, NULL);
+
+ /* ... and wait until we've flushed all events. */
+ iterate_over_lwps (kill_wait_callback, NULL);
+
+ target_mourn_inferior ();
+}
+
+static void
+lin_lwp_create_inferior (char *exec_file, char *allargs, char **env)
+{
+ child_ops.to_create_inferior (exec_file, allargs, env);
+}
+
+static void
+lin_lwp_mourn_inferior (void)
+{
+ trap_ptid = null_ptid;
+
+ /* Destroy LWP info; it's no longer valid. */
+ init_lwp_list ();
+
+ /* Restore the original signal mask. */
+ sigprocmask (SIG_SETMASK, &normal_mask, NULL);
+ sigemptyset (&blocked_mask);
+
+ child_ops.to_mourn_inferior ();
+}
+
+static void
+lin_lwp_fetch_registers (int regno)
+{
+ struct cleanup *old_chain = save_inferior_ptid ();
+
+ if (is_lwp (inferior_ptid))
+ inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
+
+ fetch_inferior_registers (regno);
+
+ do_cleanups (old_chain);
+}
+
+static void
+lin_lwp_store_registers (int regno)
+{
+ struct cleanup *old_chain = save_inferior_ptid ();
+
+ if (is_lwp (inferior_ptid))
+ inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
+
+ store_inferior_registers (regno);
+
+ do_cleanups (old_chain);
+}
+
+static int
+lin_lwp_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ struct cleanup *old_chain = save_inferior_ptid ();
+ int xfer;
+
+ if (is_lwp (inferior_ptid))
+ inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
+
+ xfer = child_xfer_memory (memaddr, myaddr, len, write, attrib, target);
+
+ do_cleanups (old_chain);
+ return xfer;
+}
+
+static int
+lin_lwp_thread_alive (ptid_t ptid)
+{
+ gdb_assert (is_lwp (ptid));
+
+ errno = 0;
+ ptrace (PTRACE_PEEKUSER, GET_LWP (ptid), 0, 0);
+ if (errno)
+ return 0;
+
+ return 1;
+}
+
+static char *
+lin_lwp_pid_to_str (ptid_t ptid)
+{
+ static char buf[64];
+
+ if (is_lwp (ptid))
+ {
+ snprintf (buf, sizeof (buf), "LWP %ld", GET_LWP (ptid));
+ return buf;
+ }
+
+ return normal_pid_to_str (ptid);
+}
+
+static void
+init_lin_lwp_ops (void)
+{
+#if 0
+ lin_lwp_ops.to_open = lin_lwp_open;
+#endif
+ lin_lwp_ops.to_shortname = "lwp-layer";
+ lin_lwp_ops.to_longname = "lwp-layer";
+ lin_lwp_ops.to_doc = "Low level threads support (LWP layer)";
+ lin_lwp_ops.to_attach = lin_lwp_attach;
+ lin_lwp_ops.to_detach = lin_lwp_detach;
+ lin_lwp_ops.to_resume = lin_lwp_resume;
+ lin_lwp_ops.to_wait = lin_lwp_wait;
+ lin_lwp_ops.to_fetch_registers = lin_lwp_fetch_registers;
+ lin_lwp_ops.to_store_registers = lin_lwp_store_registers;
+ lin_lwp_ops.to_xfer_memory = lin_lwp_xfer_memory;
+ lin_lwp_ops.to_kill = lin_lwp_kill;
+ lin_lwp_ops.to_create_inferior = lin_lwp_create_inferior;
+ lin_lwp_ops.to_mourn_inferior = lin_lwp_mourn_inferior;
+ lin_lwp_ops.to_thread_alive = lin_lwp_thread_alive;
+ lin_lwp_ops.to_pid_to_str = lin_lwp_pid_to_str;
+ lin_lwp_ops.to_stratum = thread_stratum;
+ lin_lwp_ops.to_has_thread_control = tc_schedlock;
+ lin_lwp_ops.to_magic = OPS_MAGIC;
+}
+
+static void
+sigchld_handler (int signo)
+{
+ /* Do nothing. The only reason for this handler is that it allows
+ us to use sigsuspend in lin_lwp_wait above to wait for the
+ arrival of a SIGCHLD. */
+}
+
+void
+_initialize_lin_lwp (void)
+{
+ struct sigaction action;
+
+ extern void thread_db_init (struct target_ops *);
+
+ init_lin_lwp_ops ();
+ add_target (&lin_lwp_ops);
+ thread_db_init (&lin_lwp_ops);
+
+ /* Save the original signal mask. */
+ sigprocmask (SIG_SETMASK, NULL, &normal_mask);
+
+ action.sa_handler = sigchld_handler;
+ sigemptyset (&action.sa_mask);
+ action.sa_flags = 0;
+ sigaction (SIGCHLD, &action, NULL);
+
+ /* Make sure we don't block SIGCHLD during a sigsuspend. */
+ sigprocmask (SIG_SETMASK, NULL, &suspend_mask);
+ sigdelset (&suspend_mask, SIGCHLD);
+
+ sigemptyset (&blocked_mask);
+
+ add_show_from_set (add_set_cmd ("lin-lwp", no_class, var_zinteger,
+ (char *) &debug_lin_lwp,
+ "Set debugging of GNU/Linux lwp module.\n\
+Enables printf debugging output.\n",
+ &setdebuglist),
+ &showdebuglist);
+}
+
+
+/* FIXME: kettenis/2000-08-26: The stuff on this page is specific to
+ the GNU/Linux Threads library and therefore doesn't really belong
+ here. */
+
+/* Read variable NAME in the target and return its value if found.
+ Otherwise return zero. It is assumed that the type of the variable
+ is `int'. */
+
+static int
+get_signo (const char *name)
+{
+ struct minimal_symbol *ms;
+ int signo;
+
+ ms = lookup_minimal_symbol (name, NULL, NULL);
+ if (ms == NULL)
+ return 0;
+
+ if (target_read_memory (SYMBOL_VALUE_ADDRESS (ms), (char *) &signo,
+ sizeof (signo)) != 0)
+ return 0;
+
+ return signo;
+}
+
+/* Return the set of signals used by the threads library in *SET. */
+
+void
+lin_thread_get_thread_signals (sigset_t *set)
+{
+ struct sigaction action;
+ int restart, cancel;
+
+ sigemptyset (set);
+
+ restart = get_signo ("__pthread_sig_restart");
+ if (restart == 0)
+ return;
+
+ cancel = get_signo ("__pthread_sig_cancel");
+ if (cancel == 0)
+ return;
+
+ sigaddset (set, restart);
+ sigaddset (set, cancel);
+
+ /* The GNU/Linux Threads library makes terminating threads send a
+ special "cancel" signal instead of SIGCHLD. Make sure we catch
+ those (to prevent them from terminating GDB itself, which is
+ likely to be their default action) and treat them the same way as
+ SIGCHLD. */
+
+ action.sa_handler = sigchld_handler;
+ sigemptyset (&action.sa_mask);
+ action.sa_flags = 0;
+ sigaction (cancel, &action, NULL);
+
+ /* We block the "cancel" signal throughout this code ... */
+ sigaddset (&blocked_mask, cancel);
+ sigprocmask (SIG_BLOCK, &blocked_mask, NULL);
+
+ /* ... except during a sigsuspend. */
+ sigdelset (&suspend_mask, cancel);
+}
diff --git a/gdb/linespec.c b/gdb/linespec.c
new file mode 100644
index 00000000000..8e51021fc44
--- /dev/null
+++ b/gdb/linespec.c
@@ -0,0 +1,1270 @@
+/* Parser for linespec for the GNU debugger, GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "symtab.h"
+#include "frame.h"
+#include "command.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "demangle.h"
+#include "value.h"
+#include "completer.h"
+#include "cp-abi.h"
+
+/* Prototype for one function in parser-defs.h,
+ instead of including that entire file. */
+
+extern char *find_template_name_end (char *);
+
+/* We share this one with symtab.c, but it is not exported widely. */
+
+extern char *operator_chars (char *, char **);
+
+/* Prototypes for local functions */
+
+static void cplusplus_error (const char *name, const char *fmt, ...) ATTR_FORMAT (printf, 2, 3);
+
+static int total_number_of_methods (struct type *type);
+
+static int find_methods (struct type *, char *, struct symbol **);
+
+static void build_canonical_line_spec (struct symtab_and_line *,
+ char *, char ***);
+
+static char *find_toplevel_char (char *s, char c);
+
+static struct symtabs_and_lines decode_line_2 (struct symbol *[],
+ int, int, char ***);
+
+/* Helper functions. */
+
+/* Issue a helpful hint on using the command completion feature on
+ single quoted demangled C++ symbols as part of the completion
+ error. */
+
+static void
+cplusplus_error (const char *name, const char *fmt, ...)
+{
+ struct ui_file *tmp_stream;
+ tmp_stream = mem_fileopen ();
+ make_cleanup_ui_file_delete (tmp_stream);
+
+ {
+ va_list args;
+ va_start (args, fmt);
+ vfprintf_unfiltered (tmp_stream, fmt, args);
+ va_end (args);
+ }
+
+ while (*name == '\'')
+ name++;
+ fprintf_unfiltered (tmp_stream,
+ ("Hint: try '%s<TAB> or '%s<ESC-?>\n"
+ "(Note leading single quote.)"),
+ name, name);
+ error_stream (tmp_stream);
+}
+
+/* Return the number of methods described for TYPE, including the
+ methods from types it derives from. This can't be done in the symbol
+ reader because the type of the baseclass might still be stubbed
+ when the definition of the derived class is parsed. */
+
+static int
+total_number_of_methods (struct type *type)
+{
+ int n;
+ int count;
+
+ CHECK_TYPEDEF (type);
+ if (TYPE_CPLUS_SPECIFIC (type) == NULL)
+ return 0;
+ count = TYPE_NFN_FIELDS_TOTAL (type);
+
+ for (n = 0; n < TYPE_N_BASECLASSES (type); n++)
+ count += total_number_of_methods (TYPE_BASECLASS (type, n));
+
+ return count;
+}
+
+/* Recursive helper function for decode_line_1.
+ Look for methods named NAME in type T.
+ Return number of matches.
+ Put matches in SYM_ARR, which should have been allocated with
+ a size of total_number_of_methods (T) * sizeof (struct symbol *).
+ Note that this function is g++ specific. */
+
+static int
+find_methods (struct type *t, char *name, struct symbol **sym_arr)
+{
+ int i1 = 0;
+ int ibase;
+ char *class_name = type_name_no_tag (t);
+
+ /* Ignore this class if it doesn't have a name. This is ugly, but
+ unless we figure out how to get the physname without the name of
+ the class, then the loop can't do any good. */
+ if (class_name
+ && (lookup_symbol (class_name, (struct block *) NULL,
+ STRUCT_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL)))
+ {
+ int method_counter;
+ int name_len = strlen (name);
+
+ CHECK_TYPEDEF (t);
+
+ /* Loop over each method name. At this level, all overloads of a name
+ are counted as a single name. There is an inner loop which loops over
+ each overload. */
+
+ for (method_counter = TYPE_NFN_FIELDS (t) - 1;
+ method_counter >= 0;
+ --method_counter)
+ {
+ int field_counter;
+ char *method_name = TYPE_FN_FIELDLIST_NAME (t, method_counter);
+ char dem_opname[64];
+
+ if (strncmp (method_name, "__", 2) == 0 ||
+ strncmp (method_name, "op", 2) == 0 ||
+ strncmp (method_name, "type", 4) == 0)
+ {
+ if (cplus_demangle_opname (method_name, dem_opname, DMGL_ANSI))
+ method_name = dem_opname;
+ else if (cplus_demangle_opname (method_name, dem_opname, 0))
+ method_name = dem_opname;
+ }
+
+ if (strcmp_iw (name, method_name) == 0)
+ /* Find all the overloaded methods with that name. */
+ for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1;
+ field_counter >= 0;
+ --field_counter)
+ {
+ struct fn_field *f;
+ char *phys_name;
+
+ f = TYPE_FN_FIELDLIST1 (t, method_counter);
+
+ if (TYPE_FN_FIELD_STUB (f, field_counter))
+ {
+ char *tmp_name;
+
+ tmp_name = gdb_mangle_name (t,
+ method_counter,
+ field_counter);
+ phys_name = alloca (strlen (tmp_name) + 1);
+ strcpy (phys_name, tmp_name);
+ xfree (tmp_name);
+ }
+ else
+ phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
+
+ /* Destructor is handled by caller, dont add it to the list */
+ if (is_destructor_name (phys_name) != 0)
+ continue;
+
+ sym_arr[i1] = lookup_symbol (phys_name,
+ NULL, VAR_NAMESPACE,
+ (int *) NULL,
+ (struct symtab **) NULL);
+ if (sym_arr[i1])
+ i1++;
+ else
+ {
+ /* This error message gets printed, but the method
+ still seems to be found
+ fputs_filtered("(Cannot find method ", gdb_stdout);
+ fprintf_symbol_filtered (gdb_stdout, phys_name,
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
+ fputs_filtered(" - possibly inlined.)\n", gdb_stdout);
+ */
+ }
+ }
+ else if (strncmp (class_name, name, name_len) == 0
+ && (class_name[name_len] == '\0'
+ || class_name[name_len] == '<'))
+ {
+ /* For GCC 3.x and stabs, constructors and destructors have names
+ like __base_ctor and __complete_dtor. Check the physname for now
+ if we're looking for a constructor. */
+ for (field_counter
+ = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1;
+ field_counter >= 0;
+ --field_counter)
+ {
+ struct fn_field *f;
+ char *phys_name;
+
+ f = TYPE_FN_FIELDLIST1 (t, method_counter);
+
+ /* GCC 3.x will never produce stabs stub methods, so we don't need
+ to handle this case. */
+ if (TYPE_FN_FIELD_STUB (f, field_counter))
+ continue;
+ phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
+ if (! is_constructor_name (phys_name))
+ continue;
+
+ /* If this method is actually defined, include it in the
+ list. */
+ sym_arr[i1] = lookup_symbol (phys_name,
+ NULL, VAR_NAMESPACE,
+ (int *) NULL,
+ (struct symtab **) NULL);
+ if (sym_arr[i1])
+ i1++;
+ }
+ }
+ }
+ }
+
+ /* Only search baseclasses if there is no match yet, since names in
+ derived classes override those in baseclasses.
+
+ FIXME: The above is not true; it is only true of member functions
+ if they have the same number of arguments (??? - section 13.1 of the
+ ARM says the function members are not in the same scope but doesn't
+ really spell out the rules in a way I understand. In any case, if
+ the number of arguments differ this is a case in which we can overload
+ rather than hiding without any problem, and gcc 2.4.5 does overload
+ rather than hiding in this case). */
+
+ if (i1 == 0)
+ for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
+ i1 += find_methods (TYPE_BASECLASS (t, ibase), name, sym_arr + i1);
+
+ return i1;
+}
+
+/* Helper function for decode_line_1.
+ Build a canonical line spec in CANONICAL if it is non-NULL and if
+ the SAL has a symtab.
+ If SYMNAME is non-NULL the canonical line spec is `filename:symname'.
+ If SYMNAME is NULL the line number from SAL is used and the canonical
+ line spec is `filename:linenum'. */
+
+static void
+build_canonical_line_spec (struct symtab_and_line *sal, char *symname,
+ char ***canonical)
+{
+ char **canonical_arr;
+ char *canonical_name;
+ char *filename;
+ struct symtab *s = sal->symtab;
+
+ if (s == (struct symtab *) NULL
+ || s->filename == (char *) NULL
+ || canonical == (char ***) NULL)
+ return;
+
+ canonical_arr = (char **) xmalloc (sizeof (char *));
+ *canonical = canonical_arr;
+
+ filename = s->filename;
+ if (symname != NULL)
+ {
+ canonical_name = xmalloc (strlen (filename) + strlen (symname) + 2);
+ sprintf (canonical_name, "%s:%s", filename, symname);
+ }
+ else
+ {
+ canonical_name = xmalloc (strlen (filename) + 30);
+ sprintf (canonical_name, "%s:%d", filename, sal->line);
+ }
+ canonical_arr[0] = canonical_name;
+}
+
+
+
+/* Find an instance of the character C in the string S that is outside
+ of all parenthesis pairs, single-quoted strings, and double-quoted
+ strings. Also, ignore the char within a template name, like a ','
+ within foo<int, int>. */
+
+static char *
+find_toplevel_char (char *s, char c)
+{
+ int quoted = 0; /* zero if we're not in quotes;
+ '"' if we're in a double-quoted string;
+ '\'' if we're in a single-quoted string. */
+ int depth = 0; /* number of unclosed parens we've seen */
+ char *scan;
+
+ for (scan = s; *scan; scan++)
+ {
+ if (quoted)
+ {
+ if (*scan == quoted)
+ quoted = 0;
+ else if (*scan == '\\' && *(scan + 1))
+ scan++;
+ }
+ else if (*scan == c && ! quoted && depth == 0)
+ return scan;
+ else if (*scan == '"' || *scan == '\'')
+ quoted = *scan;
+ else if (*scan == '(' || *scan == '<')
+ depth++;
+ else if ((*scan == ')' || *scan == '>') && depth > 0)
+ depth--;
+ }
+
+ return 0;
+}
+
+/* Given a list of NELTS symbols in SYM_ARR, return a list of lines to
+ operate on (ask user if necessary).
+ If CANONICAL is non-NULL return a corresponding array of mangled names
+ as canonical line specs there. */
+
+static struct symtabs_and_lines
+decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline,
+ char ***canonical)
+{
+ struct symtabs_and_lines values, return_values;
+ char *args, *arg1;
+ int i;
+ char *prompt;
+ char *symname;
+ struct cleanup *old_chain;
+ char **canonical_arr = (char **) NULL;
+
+ values.sals = (struct symtab_and_line *)
+ alloca (nelts * sizeof (struct symtab_and_line));
+ return_values.sals = (struct symtab_and_line *)
+ xmalloc (nelts * sizeof (struct symtab_and_line));
+ old_chain = make_cleanup (xfree, return_values.sals);
+
+ if (canonical)
+ {
+ canonical_arr = (char **) xmalloc (nelts * sizeof (char *));
+ make_cleanup (xfree, canonical_arr);
+ memset (canonical_arr, 0, nelts * sizeof (char *));
+ *canonical = canonical_arr;
+ }
+
+ i = 0;
+ printf_unfiltered ("[0] cancel\n[1] all\n");
+ while (i < nelts)
+ {
+ INIT_SAL (&return_values.sals[i]); /* initialize to zeroes */
+ INIT_SAL (&values.sals[i]);
+ if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK)
+ {
+ values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline);
+ printf_unfiltered ("[%d] %s at %s:%d\n",
+ (i + 2),
+ SYMBOL_SOURCE_NAME (sym_arr[i]),
+ values.sals[i].symtab->filename,
+ values.sals[i].line);
+ }
+ else
+ printf_unfiltered ("?HERE\n");
+ i++;
+ }
+
+ if ((prompt = getenv ("PS2")) == NULL)
+ {
+ prompt = "> ";
+ }
+ args = command_line_input (prompt, 0, "overload-choice");
+
+ if (args == 0 || *args == 0)
+ error_no_arg ("one or more choice numbers");
+
+ i = 0;
+ while (*args)
+ {
+ int num;
+
+ arg1 = args;
+ while (*arg1 >= '0' && *arg1 <= '9')
+ arg1++;
+ if (*arg1 && *arg1 != ' ' && *arg1 != '\t')
+ error ("Arguments must be choice numbers.");
+
+ num = atoi (args);
+
+ if (num == 0)
+ error ("canceled");
+ else if (num == 1)
+ {
+ if (canonical_arr)
+ {
+ for (i = 0; i < nelts; i++)
+ {
+ if (canonical_arr[i] == NULL)
+ {
+ symname = SYMBOL_NAME (sym_arr[i]);
+ canonical_arr[i] = savestring (symname, strlen (symname));
+ }
+ }
+ }
+ memcpy (return_values.sals, values.sals,
+ (nelts * sizeof (struct symtab_and_line)));
+ return_values.nelts = nelts;
+ discard_cleanups (old_chain);
+ return return_values;
+ }
+
+ if (num >= nelts + 2)
+ {
+ printf_unfiltered ("No choice number %d.\n", num);
+ }
+ else
+ {
+ num -= 2;
+ if (values.sals[num].pc)
+ {
+ if (canonical_arr)
+ {
+ symname = SYMBOL_NAME (sym_arr[num]);
+ make_cleanup (xfree, symname);
+ canonical_arr[i] = savestring (symname, strlen (symname));
+ }
+ return_values.sals[i++] = values.sals[num];
+ values.sals[num].pc = 0;
+ }
+ else
+ {
+ printf_unfiltered ("duplicate request for %d ignored.\n", num);
+ }
+ }
+
+ args = arg1;
+ while (*args == ' ' || *args == '\t')
+ args++;
+ }
+ return_values.nelts = i;
+ discard_cleanups (old_chain);
+ return return_values;
+}
+
+/* The parser of linespec itself. */
+
+/* Parse a string that specifies a line number.
+ Pass the address of a char * variable; that variable will be
+ advanced over the characters actually parsed.
+
+ The string can be:
+
+ LINENUM -- that line number in current file. PC returned is 0.
+ FILE:LINENUM -- that line in that file. PC returned is 0.
+ FUNCTION -- line number of openbrace of that function.
+ PC returned is the start of the function.
+ VARIABLE -- line number of definition of that variable.
+ PC returned is 0.
+ FILE:FUNCTION -- likewise, but prefer functions in that file.
+ *EXPR -- line in which address EXPR appears.
+
+ This may all be followed by an "if EXPR", which we ignore.
+
+ FUNCTION may be an undebuggable function found in minimal symbol table.
+
+ If the argument FUNFIRSTLINE is nonzero, we want the first line
+ of real code inside a function when a function is specified, and it is
+ not OK to specify a variable or type to get its line number.
+
+ DEFAULT_SYMTAB specifies the file to use if none is specified.
+ It defaults to current_source_symtab.
+ DEFAULT_LINE specifies the line number to use for relative
+ line numbers (that start with signs). Defaults to current_source_line.
+ If CANONICAL is non-NULL, store an array of strings containing the canonical
+ line specs there if necessary. Currently overloaded member functions and
+ line numbers or static functions without a filename yield a canonical
+ line spec. The array and the line spec strings are allocated on the heap,
+ it is the callers responsibility to free them.
+
+ Note that it is possible to return zero for the symtab
+ if no file is validly specified. Callers must check that.
+ Also, the line number returned may be invalid. */
+
+/* We allow single quotes in various places. This is a hideous
+ kludge, which exists because the completer can't yet deal with the
+ lack of single quotes. FIXME: write a linespec_completer which we
+ can use as appropriate instead of make_symbol_completion_list. */
+
+struct symtabs_and_lines
+decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
+ int default_line, char ***canonical)
+{
+ struct symtabs_and_lines values;
+ struct symtab_and_line val;
+ register char *p, *p1;
+ char *q, *pp, *ii, *p2;
+#if 0
+ char *q1;
+#endif
+ register struct symtab *s;
+
+ register struct symbol *sym;
+ /* The symtab that SYM was found in. */
+ struct symtab *sym_symtab;
+
+ register CORE_ADDR pc;
+ register struct minimal_symbol *msymbol;
+ char *copy;
+ struct symbol *sym_class;
+ int i1;
+ int is_quoted;
+ int is_quote_enclosed;
+ int has_parens;
+ int has_if = 0;
+ int has_comma = 0;
+ struct symbol **sym_arr;
+ struct type *t;
+ char *saved_arg = *argptr;
+ extern char *gdb_completer_quote_characters;
+
+ INIT_SAL (&val); /* initialize to zeroes */
+
+ /* Defaults have defaults. */
+
+ if (default_symtab == 0)
+ {
+ default_symtab = current_source_symtab;
+ default_line = current_source_line;
+ }
+
+ /* See if arg is *PC */
+
+ if (**argptr == '*')
+ {
+ (*argptr)++;
+ pc = parse_and_eval_address_1 (argptr);
+
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+
+ values.nelts = 1;
+ values.sals[0] = find_pc_line (pc, 0);
+ values.sals[0].pc = pc;
+ values.sals[0].section = find_pc_overlay (pc);
+
+ return values;
+ }
+
+ /* 'has_if' is for the syntax:
+ * (gdb) break foo if (a==b)
+ */
+ if ((ii = strstr (*argptr, " if ")) != NULL ||
+ (ii = strstr (*argptr, "\tif ")) != NULL ||
+ (ii = strstr (*argptr, " if\t")) != NULL ||
+ (ii = strstr (*argptr, "\tif\t")) != NULL ||
+ (ii = strstr (*argptr, " if(")) != NULL ||
+ (ii = strstr (*argptr, "\tif( ")) != NULL)
+ has_if = 1;
+ /* Temporarily zap out "if (condition)" to not
+ * confuse the parenthesis-checking code below.
+ * This is undone below. Do not change ii!!
+ */
+ if (has_if)
+ {
+ *ii = '\0';
+ }
+
+ /* Set various flags.
+ * 'has_parens' is important for overload checking, where
+ * we allow things like:
+ * (gdb) break c::f(int)
+ */
+
+ /* Maybe arg is FILE : LINENUM or FILE : FUNCTION */
+
+ is_quoted = (**argptr
+ && strchr (get_gdb_completer_quote_characters (),
+ **argptr) != NULL);
+
+ has_parens = ((pp = strchr (*argptr, '(')) != NULL
+ && (pp = strrchr (pp, ')')) != NULL);
+
+ /* Now that we're safely past the has_parens check,
+ * put back " if (condition)" so outer layers can see it
+ */
+ if (has_if)
+ *ii = ' ';
+
+ /* Maybe we were called with a line range FILENAME:LINENUM,FILENAME:LINENUM
+ and we must isolate the first half. Outer layers will call again later
+ for the second half.
+
+ Don't count commas that appear in argument lists of overloaded
+ functions, or in quoted strings. It's stupid to go to this much
+ trouble when the rest of the function is such an obvious roach hotel. */
+ ii = find_toplevel_char (*argptr, ',');
+ has_comma = (ii != 0);
+
+ /* Temporarily zap out second half to not
+ * confuse the code below.
+ * This is undone below. Do not change ii!!
+ */
+ if (has_comma)
+ {
+ *ii = '\0';
+ }
+
+ /* Maybe arg is FILE : LINENUM or FILE : FUNCTION */
+ /* May also be CLASS::MEMBER, or NAMESPACE::NAME */
+ /* Look for ':', but ignore inside of <> */
+
+ s = NULL;
+ p = *argptr;
+ if (p[0] == '"')
+ {
+ is_quote_enclosed = 1;
+ (*argptr)++;
+ p++;
+ }
+ else
+ is_quote_enclosed = 0;
+ for (; *p; p++)
+ {
+ if (p[0] == '<')
+ {
+ char *temp_end = find_template_name_end (p);
+ if (!temp_end)
+ error ("malformed template specification in command");
+ p = temp_end;
+ }
+ /* Check for the end of the first half of the linespec. End of line,
+ a tab, a double colon or the last single colon, or a space. But
+ if enclosed in double quotes we do not break on enclosed spaces */
+ if (!*p
+ || p[0] == '\t'
+ || ((p[0] == ':')
+ && ((p[1] == ':') || (strchr (p + 1, ':') == NULL)))
+ || ((p[0] == ' ') && !is_quote_enclosed))
+ break;
+ if (p[0] == '.' && strchr (p, ':') == NULL) /* Java qualified method. */
+ {
+ /* Find the *last* '.', since the others are package qualifiers. */
+ for (p1 = p; *p1; p1++)
+ {
+ if (*p1 == '.')
+ p = p1;
+ }
+ break;
+ }
+ }
+ while (p[0] == ' ' || p[0] == '\t')
+ p++;
+
+ /* if the closing double quote was left at the end, remove it */
+ if (is_quote_enclosed)
+ {
+ char *closing_quote = strchr (p - 1, '"');
+ if (closing_quote && closing_quote[1] == '\0')
+ *closing_quote = '\0';
+ }
+
+ /* Now that we've safely parsed the first half,
+ * put back ',' so outer layers can see it
+ */
+ if (has_comma)
+ *ii = ',';
+
+ if ((p[0] == ':' || p[0] == '.') && !has_parens)
+ {
+ /* C++ */
+ /* ... or Java */
+ if (is_quoted)
+ *argptr = *argptr + 1;
+ if (p[0] == '.' || p[1] == ':')
+ {
+ char *saved_arg2 = *argptr;
+ char *temp_end;
+ /* First check for "global" namespace specification,
+ of the form "::foo". If found, skip over the colons
+ and jump to normal symbol processing */
+ if (p[0] == ':'
+ && ((*argptr == p) || (p[-1] == ' ') || (p[-1] == '\t')))
+ saved_arg2 += 2;
+
+ /* We have what looks like a class or namespace
+ scope specification (A::B), possibly with many
+ levels of namespaces or classes (A::B::C::D).
+
+ Some versions of the HP ANSI C++ compiler (as also possibly
+ other compilers) generate class/function/member names with
+ embedded double-colons if they are inside namespaces. To
+ handle this, we loop a few times, considering larger and
+ larger prefixes of the string as though they were single
+ symbols. So, if the initially supplied string is
+ A::B::C::D::foo, we have to look up "A", then "A::B",
+ then "A::B::C", then "A::B::C::D", and finally
+ "A::B::C::D::foo" as single, monolithic symbols, because
+ A, B, C or D may be namespaces.
+
+ Note that namespaces can nest only inside other
+ namespaces, and not inside classes. So we need only
+ consider *prefixes* of the string; there is no need to look up
+ "B::C" separately as a symbol in the previous example. */
+
+ p2 = p; /* save for restart */
+ while (1)
+ {
+ /* Extract the class name. */
+ p1 = p;
+ while (p != *argptr && p[-1] == ' ')
+ --p;
+ copy = (char *) alloca (p - *argptr + 1);
+ memcpy (copy, *argptr, p - *argptr);
+ copy[p - *argptr] = 0;
+
+ /* Discard the class name from the arg. */
+ p = p1 + (p1[0] == ':' ? 2 : 1);
+ while (*p == ' ' || *p == '\t')
+ p++;
+ *argptr = p;
+
+ sym_class = lookup_symbol (copy, 0, STRUCT_NAMESPACE, 0,
+ (struct symtab **) NULL);
+
+ if (sym_class &&
+ (t = check_typedef (SYMBOL_TYPE (sym_class)),
+ (TYPE_CODE (t) == TYPE_CODE_STRUCT
+ || TYPE_CODE (t) == TYPE_CODE_UNION)))
+ {
+ /* Arg token is not digits => try it as a function name
+ Find the next token(everything up to end or next blank). */
+ if (**argptr
+ && strchr (get_gdb_completer_quote_characters (),
+ **argptr) != NULL)
+ {
+ p = skip_quoted (*argptr);
+ *argptr = *argptr + 1;
+ }
+ else
+ {
+ p = *argptr;
+ while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':')
+ p++;
+ }
+/*
+ q = operator_chars (*argptr, &q1);
+ if (q1 - q)
+ {
+ char *opname;
+ char *tmp = alloca (q1 - q + 1);
+ memcpy (tmp, q, q1 - q);
+ tmp[q1 - q] = '\0';
+ opname = cplus_mangle_opname (tmp, DMGL_ANSI);
+ if (opname == NULL)
+ {
+ cplusplus_error (saved_arg, "no mangling for \"%s\"\n", tmp);
+ }
+ copy = (char*) alloca (3 + strlen(opname));
+ sprintf (copy, "__%s", opname);
+ p = q1;
+ }
+ else
+ */
+ {
+ copy = (char *) alloca (p - *argptr + 1);
+ memcpy (copy, *argptr, p - *argptr);
+ copy[p - *argptr] = '\0';
+ if (p != *argptr
+ && copy[p - *argptr - 1]
+ && strchr (get_gdb_completer_quote_characters (),
+ copy[p - *argptr - 1]) != NULL)
+ copy[p - *argptr - 1] = '\0';
+ }
+
+ /* no line number may be specified */
+ while (*p == ' ' || *p == '\t')
+ p++;
+ *argptr = p;
+
+ sym = 0;
+ i1 = 0; /* counter for the symbol array */
+ sym_arr = (struct symbol **) alloca (total_number_of_methods (t)
+ * sizeof (struct symbol *));
+
+ if (destructor_name_p (copy, t))
+ {
+ /* Destructors are a special case. */
+ int m_index, f_index;
+
+ if (get_destructor_fn_field (t, &m_index, &f_index))
+ {
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (t, m_index);
+
+ sym_arr[i1] =
+ lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, f_index),
+ NULL, VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ if (sym_arr[i1])
+ i1++;
+ }
+ }
+ else
+ i1 = find_methods (t, copy, sym_arr);
+ if (i1 == 1)
+ {
+ /* There is exactly one field with that name. */
+ sym = sym_arr[0];
+
+ if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
+ {
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ values.nelts = 1;
+ values.sals[0] = find_function_start_sal (sym,
+ funfirstline);
+ }
+ else
+ {
+ values.nelts = 0;
+ }
+ return values;
+ }
+ if (i1 > 0)
+ {
+ /* There is more than one field with that name
+ (overloaded). Ask the user which one to use. */
+ return decode_line_2 (sym_arr, i1, funfirstline, canonical);
+ }
+ else
+ {
+ char *tmp;
+
+ if (is_operator_name (copy))
+ {
+ tmp = (char *) alloca (strlen (copy + 3) + 9);
+ strcpy (tmp, "operator ");
+ strcat (tmp, copy + 3);
+ }
+ else
+ tmp = copy;
+ if (tmp[0] == '~')
+ cplusplus_error (saved_arg,
+ "the class `%s' does not have destructor defined\n",
+ SYMBOL_SOURCE_NAME (sym_class));
+ else
+ cplusplus_error (saved_arg,
+ "the class %s does not have any method named %s\n",
+ SYMBOL_SOURCE_NAME (sym_class), tmp);
+ }
+ }
+
+ /* Move pointer up to next possible class/namespace token */
+ p = p2 + 1; /* restart with old value +1 */
+ /* Move pointer ahead to next double-colon */
+ while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\''))
+ {
+ if (p[0] == '<')
+ {
+ temp_end = find_template_name_end (p);
+ if (!temp_end)
+ error ("malformed template specification in command");
+ p = temp_end;
+ }
+ else if ((p[0] == ':') && (p[1] == ':'))
+ break; /* found double-colon */
+ else
+ p++;
+ }
+
+ if (*p != ':')
+ break; /* out of the while (1) */
+
+ p2 = p; /* save restart for next time around */
+ *argptr = saved_arg2; /* restore argptr */
+ } /* while (1) */
+
+ /* Last chance attempt -- check entire name as a symbol */
+ /* Use "copy" in preparation for jumping out of this block,
+ to be consistent with usage following the jump target */
+ copy = (char *) alloca (p - saved_arg2 + 1);
+ memcpy (copy, saved_arg2, p - saved_arg2);
+ /* Note: if is_quoted should be true, we snuff out quote here anyway */
+ copy[p - saved_arg2] = '\000';
+ /* Set argptr to skip over the name */
+ *argptr = (*p == '\'') ? p + 1 : p;
+ /* Look up entire name */
+ sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab);
+ s = (struct symtab *) 0;
+ /* Prepare to jump: restore the " if (condition)" so outer layers see it */
+ /* Symbol was found --> jump to normal symbol processing.
+ Code following "symbol_found" expects "copy" to have the
+ symbol name, "sym" to have the symbol pointer, "s" to be
+ a specified file's symtab, and sym_symtab to be the symbol's
+ symtab. */
+ /* By jumping there we avoid falling through the FILE:LINE and
+ FILE:FUNC processing stuff below */
+ if (sym)
+ goto symbol_found;
+
+ /* Couldn't find any interpretation as classes/namespaces, so give up */
+ /* The quotes are important if copy is empty. */
+ cplusplus_error (saved_arg,
+ "Can't find member of namespace, class, struct, or union named \"%s\"\n",
+ copy);
+ }
+ /* end of C++ */
+
+
+ /* Extract the file name. */
+ p1 = p;
+ while (p != *argptr && p[-1] == ' ')
+ --p;
+ if ((*p == '"') && is_quote_enclosed)
+ --p;
+ copy = (char *) alloca (p - *argptr + 1);
+ memcpy (copy, *argptr, p - *argptr);
+ /* It may have the ending quote right after the file name */
+ if (is_quote_enclosed && copy[p - *argptr - 1] == '"')
+ copy[p - *argptr - 1] = 0;
+ else
+ copy[p - *argptr] = 0;
+
+ /* Find that file's data. */
+ s = lookup_symtab (copy);
+ if (s == 0)
+ {
+ if (!have_full_symbols () && !have_partial_symbols ())
+ error ("No symbol table is loaded. Use the \"file\" command.");
+ error ("No source file named %s.", copy);
+ }
+
+ /* Discard the file name from the arg. */
+ p = p1 + 1;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ *argptr = p;
+ }
+#if 0
+ /* No one really seems to know why this was added. It certainly
+ breaks the command line, though, whenever the passed
+ name is of the form ClassName::Method. This bit of code
+ singles out the class name, and if funfirstline is set (for
+ example, you are setting a breakpoint at this function),
+ you get an error. This did not occur with earlier
+ verions, so I am ifdef'ing this out. 3/29/99 */
+ else
+ {
+ /* Check if what we have till now is a symbol name */
+
+ /* We may be looking at a template instantiation such
+ as "foo<int>". Check here whether we know about it,
+ instead of falling through to the code below which
+ handles ordinary function names, because that code
+ doesn't like seeing '<' and '>' in a name -- the
+ skip_quoted call doesn't go past them. So see if we
+ can figure it out right now. */
+
+ copy = (char *) alloca (p - *argptr + 1);
+ memcpy (copy, *argptr, p - *argptr);
+ copy[p - *argptr] = '\000';
+ sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab);
+ if (sym)
+ {
+ /* Yes, we have a symbol; jump to symbol processing */
+ /* Code after symbol_found expects S, SYM_SYMTAB, SYM,
+ and COPY to be set correctly */
+ *argptr = (*p == '\'') ? p + 1 : p;
+ s = (struct symtab *) 0;
+ goto symbol_found;
+ }
+ /* Otherwise fall out from here and go to file/line spec
+ processing, etc. */
+ }
+#endif
+
+ /* S is specified file's symtab, or 0 if no file specified.
+ arg no longer contains the file name. */
+
+ /* Check whether arg is all digits (and sign) */
+
+ q = *argptr;
+ if (*q == '-' || *q == '+')
+ q++;
+ while (*q >= '0' && *q <= '9')
+ q++;
+
+ if (q != *argptr && (*q == 0 || *q == ' ' || *q == '\t' || *q == ','))
+ {
+ /* We found a token consisting of all digits -- at least one digit. */
+ enum sign
+ {
+ none, plus, minus
+ }
+ sign = none;
+
+ /* We might need a canonical line spec if no file was specified. */
+ int need_canonical = (s == 0) ? 1 : 0;
+
+ /* This is where we need to make sure that we have good defaults.
+ We must guarantee that this section of code is never executed
+ when we are called with just a function name, since
+ select_source_symtab calls us with such an argument */
+
+ if (s == 0 && default_symtab == 0)
+ {
+ select_source_symtab (0);
+ default_symtab = current_source_symtab;
+ default_line = current_source_line;
+ }
+
+ if (**argptr == '+')
+ sign = plus, (*argptr)++;
+ else if (**argptr == '-')
+ sign = minus, (*argptr)++;
+ val.line = atoi (*argptr);
+ switch (sign)
+ {
+ case plus:
+ if (q == *argptr)
+ val.line = 5;
+ if (s == 0)
+ val.line = default_line + val.line;
+ break;
+ case minus:
+ if (q == *argptr)
+ val.line = 15;
+ if (s == 0)
+ val.line = default_line - val.line;
+ else
+ val.line = 1;
+ break;
+ case none:
+ break; /* No need to adjust val.line. */
+ }
+
+ while (*q == ' ' || *q == '\t')
+ q++;
+ *argptr = q;
+ if (s == 0)
+ s = default_symtab;
+
+ /* It is possible that this source file has more than one symtab,
+ and that the new line number specification has moved us from the
+ default (in s) to a new one. */
+ val.symtab = find_line_symtab (s, val.line, NULL, NULL);
+ if (val.symtab == 0)
+ val.symtab = s;
+
+ val.pc = 0;
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ values.sals[0] = val;
+ values.nelts = 1;
+ if (need_canonical)
+ build_canonical_line_spec (values.sals, NULL, canonical);
+ return values;
+ }
+
+ /* Arg token is not digits => try it as a variable name
+ Find the next token (everything up to end or next whitespace). */
+
+ if (**argptr == '$') /* May be a convenience variable */
+ p = skip_quoted (*argptr + (((*argptr)[1] == '$') ? 2 : 1)); /* One or two $ chars possible */
+ else if (is_quoted)
+ {
+ p = skip_quoted (*argptr);
+ if (p[-1] != '\'')
+ error ("Unmatched single quote.");
+ }
+ else if (has_parens)
+ {
+ p = pp + 1;
+ }
+ else
+ {
+ p = skip_quoted (*argptr);
+ }
+
+ copy = (char *) alloca (p - *argptr + 1);
+ memcpy (copy, *argptr, p - *argptr);
+ copy[p - *argptr] = '\0';
+ if (p != *argptr
+ && copy[0]
+ && copy[0] == copy[p - *argptr - 1]
+ && strchr (get_gdb_completer_quote_characters (), copy[0]) != NULL)
+ {
+ copy[p - *argptr - 1] = '\0';
+ copy++;
+ }
+ while (*p == ' ' || *p == '\t')
+ p++;
+ *argptr = p;
+
+ /* If it starts with $: may be a legitimate variable or routine name
+ (e.g. HP-UX millicode routines such as $$dyncall), or it may
+ be history value, or it may be a convenience variable */
+
+ if (*copy == '$')
+ {
+ struct value *valx;
+ int index = 0;
+ int need_canonical = 0;
+
+ p = (copy[1] == '$') ? copy + 2 : copy + 1;
+ while (*p >= '0' && *p <= '9')
+ p++;
+ if (!*p) /* reached end of token without hitting non-digit */
+ {
+ /* We have a value history reference */
+ sscanf ((copy[1] == '$') ? copy + 2 : copy + 1, "%d", &index);
+ valx = access_value_history ((copy[1] == '$') ? -index : index);
+ if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT)
+ error ("History values used in line specs must have integer values.");
+ }
+ else
+ {
+ /* Not all digits -- may be user variable/function or a
+ convenience variable */
+
+ /* Look up entire name as a symbol first */
+ sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab);
+ s = (struct symtab *) 0;
+ need_canonical = 1;
+ /* Symbol was found --> jump to normal symbol processing.
+ Code following "symbol_found" expects "copy" to have the
+ symbol name, "sym" to have the symbol pointer, "s" to be
+ a specified file's symtab, and sym_symtab to be the symbol's
+ symtab. */
+ if (sym)
+ goto symbol_found;
+
+ /* If symbol was not found, look in minimal symbol tables */
+ msymbol = lookup_minimal_symbol (copy, NULL, NULL);
+ /* Min symbol was found --> jump to minsym processing. */
+ if (msymbol)
+ goto minimal_symbol_found;
+
+ /* Not a user variable or function -- must be convenience variable */
+ need_canonical = (s == 0) ? 1 : 0;
+ valx = value_of_internalvar (lookup_internalvar (copy + 1));
+ if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT)
+ error ("Convenience variables used in line specs must have integer values.");
+ }
+
+ /* Either history value or convenience value from above, in valx */
+ val.symtab = s ? s : default_symtab;
+ val.line = value_as_long (valx);
+ val.pc = 0;
+
+ values.sals = (struct symtab_and_line *) xmalloc (sizeof val);
+ values.sals[0] = val;
+ values.nelts = 1;
+
+ if (need_canonical)
+ build_canonical_line_spec (values.sals, NULL, canonical);
+
+ return values;
+ }
+
+
+ /* Look up that token as a variable.
+ If file specified, use that file's per-file block to start with. */
+
+ sym = lookup_symbol (copy,
+ (s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK)
+ : get_selected_block (0)),
+ VAR_NAMESPACE, 0, &sym_symtab);
+
+symbol_found: /* We also jump here from inside the C++ class/namespace
+ code on finding a symbol of the form "A::B::C" */
+
+ if (sym != NULL)
+ {
+ if (SYMBOL_CLASS (sym) == LOC_BLOCK)
+ {
+ /* Arg is the name of a function */
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ values.sals[0] = find_function_start_sal (sym, funfirstline);
+ values.nelts = 1;
+
+ /* Don't use the SYMBOL_LINE; if used at all it points to
+ the line containing the parameters or thereabouts, not
+ the first line of code. */
+
+ /* We might need a canonical line spec if it is a static
+ function. */
+ if (s == 0)
+ {
+ struct blockvector *bv = BLOCKVECTOR (sym_symtab);
+ struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ if (lookup_block_symbol (b, copy, NULL, VAR_NAMESPACE) != NULL)
+ build_canonical_line_spec (values.sals, copy, canonical);
+ }
+ return values;
+ }
+ else
+ {
+ if (funfirstline)
+ error ("\"%s\" is not a function", copy);
+ else if (SYMBOL_LINE (sym) != 0)
+ {
+ /* We know its line number. */
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ values.nelts = 1;
+ memset (&values.sals[0], 0, sizeof (values.sals[0]));
+ values.sals[0].symtab = sym_symtab;
+ values.sals[0].line = SYMBOL_LINE (sym);
+ return values;
+ }
+ else
+ /* This can happen if it is compiled with a compiler which doesn't
+ put out line numbers for variables. */
+ /* FIXME: Shouldn't we just set .line and .symtab to zero
+ and return? For example, "info line foo" could print
+ the address. */
+ error ("Line number not known for symbol \"%s\"", copy);
+ }
+ }
+
+ msymbol = lookup_minimal_symbol (copy, NULL, NULL);
+
+minimal_symbol_found: /* We also jump here from the case for variables
+ that begin with '$' */
+
+ if (msymbol != NULL)
+ {
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ values.sals[0] = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol),
+ (struct sec *) 0, 0);
+ values.sals[0].section = SYMBOL_BFD_SECTION (msymbol);
+ if (funfirstline)
+ {
+ values.sals[0].pc += FUNCTION_START_OFFSET;
+ values.sals[0].pc = SKIP_PROLOGUE (values.sals[0].pc);
+ }
+ values.nelts = 1;
+ return values;
+ }
+
+ if (!have_full_symbols () &&
+ !have_partial_symbols () && !have_minimal_symbols ())
+ error ("No symbol table is loaded. Use the \"file\" command.");
+
+ error ("Function \"%s\" not defined.", copy);
+ return values; /* for lint */
+}
diff --git a/gdb/linespec.h b/gdb/linespec.h
new file mode 100644
index 00000000000..7c3f90ca268
--- /dev/null
+++ b/gdb/linespec.h
@@ -0,0 +1,27 @@
+/* Header for GDB line completion.
+ Copyright 2000 Free Software Foundation, Inc.
+
+ 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. */
+
+#if !defined (LINESPEC_H)
+#define LINESPEC_H 1
+
+extern struct symtabs_and_lines
+ decode_line_1 (char **argptr, int funfirstline,
+ struct symtab *default_symtab, int default_line,
+ char ***canonical);
+
+#endif /* defined (LINESPEC_H) */
diff --git a/gdb/linux-proc.c b/gdb/linux-proc.c
new file mode 100644
index 00000000000..aa3b5711da0
--- /dev/null
+++ b/gdb/linux-proc.c
@@ -0,0 +1,574 @@
+/* GNU/Linux specific methods for using the /proc file system.
+
+ Copyright 2001, 2002 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 "defs.h"
+#include "inferior.h"
+#include <sys/param.h> /* for MAXPATHLEN */
+#include <sys/procfs.h> /* for elf_gregset etc. */
+#include <sys/stat.h> /* for struct stat */
+#include <ctype.h> /* for isdigit */
+#include "regcache.h" /* for registers_changed */
+#include "gregset.h" /* for gregset */
+#include "gdbcore.h" /* for get_exec_file */
+#include "gdbthread.h" /* for struct thread_info etc. */
+#include "elf-bfd.h" /* for elfcore_write_* */
+#include "cli/cli-decode.h" /* for add_info */
+
+/* Function: child_pid_to_exec_file
+ *
+ * Accepts an integer pid
+ * Returns a string representing a file that can be opened
+ * to get the symbols for the child process.
+ */
+
+char *
+child_pid_to_exec_file (int pid)
+{
+ char *name1, *name2;
+
+ name1 = xmalloc (MAXPATHLEN);
+ name2 = xmalloc (MAXPATHLEN);
+ make_cleanup (xfree, name1);
+ make_cleanup (xfree, name2);
+ memset (name2, 0, MAXPATHLEN);
+
+ sprintf (name1, "/proc/%d/exe", pid);
+ if (readlink (name1, name2, MAXPATHLEN) > 0)
+ return name2;
+ else
+ return name1;
+}
+
+/* Function: read_mappings
+ *
+ * Service function for corefiles and info proc.
+ */
+
+static int
+read_mapping (FILE *mapfile,
+ long long *addr,
+ long long *endaddr,
+ char *permissions,
+ long long *offset,
+ char *device,
+ long long *inode,
+ char *filename)
+{
+ int ret = fscanf (mapfile, "%llx-%llx %s %llx %s %llx",
+ addr, endaddr, permissions, offset, device, inode);
+
+ if (ret > 0 && ret != EOF && *inode != 0)
+ {
+ /* Eat everything up to EOL for the filename. This will prevent
+ weird filenames (such as one with embedded whitespace) from
+ confusing this code. It also makes this code more robust
+ in respect to annotations the kernel may add after the
+ filename.
+
+ Note the filename is used for informational purposes only. */
+ ret += fscanf (mapfile, "%[^\n]\n", filename);
+ }
+ else
+ {
+ filename[0] = '\0'; /* no filename */
+ fscanf (mapfile, "\n");
+ }
+ return (ret != 0 && ret != EOF);
+}
+
+/* Function: linux_find_memory_regions
+ *
+ * Fills the "to_find_memory_regions" target vector.
+ * Lists the memory regions in the inferior for a corefile.
+ */
+
+static int
+linux_find_memory_regions (int (*func) (CORE_ADDR,
+ unsigned long,
+ int, int, int,
+ void *),
+ void *obfd)
+{
+ long long pid = PIDGET (inferior_ptid);
+ char mapsfilename[MAXPATHLEN];
+ FILE *mapsfile;
+ long long addr, endaddr, size, offset, inode;
+ char permissions[8], device[8], filename[MAXPATHLEN];
+ int read, write, exec;
+ int ret;
+
+ /* Compose the filename for the /proc memory map, and open it. */
+ sprintf (mapsfilename, "/proc/%lld/maps", pid);
+ if ((mapsfile = fopen (mapsfilename, "r")) == NULL)
+ error ("Could not open %s\n", mapsfilename);
+
+ if (info_verbose)
+ fprintf_filtered (gdb_stdout,
+ "Reading memory regions from %s\n", mapsfilename);
+
+ /* Now iterate until end-of-file. */
+ while (read_mapping (mapsfile, &addr, &endaddr, &permissions[0],
+ &offset, &device[0], &inode, &filename[0]))
+ {
+ size = endaddr - addr;
+
+ /* Get the segment's permissions. */
+ read = (strchr (permissions, 'r') != 0);
+ write = (strchr (permissions, 'w') != 0);
+ exec = (strchr (permissions, 'x') != 0);
+
+ if (info_verbose)
+ {
+ fprintf_filtered (gdb_stdout,
+ "Save segment, %lld bytes at 0x%s (%c%c%c)",
+ size, paddr_nz (addr),
+ read ? 'r' : ' ',
+ write ? 'w' : ' ',
+ exec ? 'x' : ' ');
+ if (filename && filename[0])
+ fprintf_filtered (gdb_stdout,
+ " for %s", filename);
+ fprintf_filtered (gdb_stdout, "\n");
+ }
+
+ /* Invoke the callback function to create the corefile segment. */
+ func (addr, size, read, write, exec, obfd);
+ }
+ fclose (mapsfile);
+ return 0;
+}
+
+/* Function: linux_do_thread_registers
+ *
+ * Records the thread's register state for the corefile note section.
+ */
+
+static char *
+linux_do_thread_registers (bfd *obfd, ptid_t ptid,
+ char *note_data, int *note_size)
+{
+ gdb_gregset_t gregs;
+ gdb_fpregset_t fpregs;
+#ifdef FILL_FPXREGSET
+ gdb_fpxregset_t fpxregs;
+#endif
+ unsigned long merged_pid = ptid_get_tid (ptid) << 16 | ptid_get_pid (ptid);
+
+ fill_gregset (&gregs, -1);
+ note_data = (char *) elfcore_write_prstatus (obfd,
+ note_data,
+ note_size,
+ merged_pid,
+ stop_signal,
+ &gregs);
+
+ fill_fpregset (&fpregs, -1);
+ note_data = (char *) elfcore_write_prfpreg (obfd,
+ note_data,
+ note_size,
+ &fpregs,
+ sizeof (fpregs));
+#ifdef FILL_FPXREGSET
+ fill_fpxregset (&fpxregs, -1);
+ note_data = (char *) elfcore_write_prxfpreg (obfd,
+ note_data,
+ note_size,
+ &fpxregs,
+ sizeof (fpxregs));
+#endif
+ return note_data;
+}
+
+struct linux_corefile_thread_data {
+ bfd *obfd;
+ char *note_data;
+ int *note_size;
+};
+
+/* Function: linux_corefile_thread_callback
+ *
+ * Called by gdbthread.c once per thread.
+ * Records the thread's register state for the corefile note section.
+ */
+
+static int
+linux_corefile_thread_callback (struct thread_info *ti, void *data)
+{
+ struct linux_corefile_thread_data *args = data;
+ ptid_t saved_ptid = inferior_ptid;
+
+ inferior_ptid = ti->ptid;
+ registers_changed ();
+ target_fetch_registers (-1); /* FIXME should not be necessary;
+ fill_gregset should do it automatically. */
+ args->note_data = linux_do_thread_registers (args->obfd,
+ ti->ptid,
+ args->note_data,
+ args->note_size);
+ inferior_ptid = saved_ptid;
+ registers_changed ();
+ target_fetch_registers (-1); /* FIXME should not be necessary;
+ fill_gregset should do it automatically. */
+ return 0;
+}
+
+/* Function: linux_make_note_section
+ *
+ * Fills the "to_make_corefile_note" target vector.
+ * Builds the note section for a corefile, and returns it
+ * in a malloc buffer.
+ */
+
+static char *
+linux_make_note_section (bfd *obfd, int *note_size)
+{
+ struct linux_corefile_thread_data thread_args;
+ struct cleanup *old_chain;
+ char fname[16] = {'\0'};
+ char psargs[80] = {'\0'};
+ char *note_data = NULL;
+ ptid_t current_ptid = inferior_ptid;
+
+ if (get_exec_file (0))
+ {
+ strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname));
+ strncpy (psargs, get_exec_file (0),
+ sizeof (psargs));
+ if (get_inferior_args ())
+ {
+ strncat (psargs, " ",
+ sizeof (psargs) - strlen (psargs));
+ strncat (psargs, get_inferior_args (),
+ sizeof (psargs) - strlen (psargs));
+ }
+ note_data = (char *) elfcore_write_prpsinfo (obfd,
+ note_data,
+ note_size,
+ fname,
+ psargs);
+ }
+
+ /* Dump information for threads. */
+ thread_args.obfd = obfd;
+ thread_args.note_data = note_data;
+ thread_args.note_size = note_size;
+ iterate_over_threads (linux_corefile_thread_callback, &thread_args);
+ if (thread_args.note_data == note_data)
+ {
+ /* iterate_over_threads didn't come up with any threads;
+ just use inferior_ptid. */
+ note_data = linux_do_thread_registers (obfd, inferior_ptid,
+ note_data, note_size);
+ }
+ else
+ {
+ note_data = thread_args.note_data;
+ }
+
+ make_cleanup (xfree, note_data);
+ return note_data;
+}
+
+/*
+ * Function: linux_info_proc_cmd
+ *
+ * Implement the "info proc" command.
+ */
+
+static void
+linux_info_proc_cmd (char *args, int from_tty)
+{
+ long long pid = PIDGET (inferior_ptid);
+ FILE *procfile;
+ char **argv = NULL;
+ char buffer[MAXPATHLEN];
+ char fname1[MAXPATHLEN], fname2[MAXPATHLEN];
+ int cmdline_f = 1;
+ int cwd_f = 1;
+ int exe_f = 1;
+ int mappings_f = 0;
+ int environ_f = 0;
+ int status_f = 0;
+ int stat_f = 0;
+ int all = 0;
+ struct stat dummy;
+
+ if (args)
+ {
+ /* Break up 'args' into an argv array. */
+ if ((argv = buildargv (args)) == NULL)
+ nomem (0);
+ else
+ make_cleanup_freeargv (argv);
+ }
+ while (argv != NULL && *argv != NULL)
+ {
+ if (isdigit (argv[0][0]))
+ {
+ pid = strtoul (argv[0], NULL, 10);
+ }
+ else if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0)
+ {
+ mappings_f = 1;
+ }
+ else if (strcmp (argv[0], "status") == 0)
+ {
+ status_f = 1;
+ }
+ else if (strcmp (argv[0], "stat") == 0)
+ {
+ stat_f = 1;
+ }
+ else if (strcmp (argv[0], "cmd") == 0)
+ {
+ cmdline_f = 1;
+ }
+ else if (strncmp (argv[0], "exe", strlen (argv[0])) == 0)
+ {
+ exe_f = 1;
+ }
+ else if (strcmp (argv[0], "cwd") == 0)
+ {
+ cwd_f = 1;
+ }
+ else if (strncmp (argv[0], "all", strlen (argv[0])) == 0)
+ {
+ all = 1;
+ }
+ else
+ {
+ /* [...] (future options here) */
+ }
+ argv++;
+ }
+ if (pid == 0)
+ error ("No current process: you must name one.");
+
+ sprintf (fname1, "/proc/%lld", pid);
+ if (stat (fname1, &dummy) != 0)
+ error ("No /proc directory: '%s'", fname1);
+
+ printf_filtered ("process %lld\n", pid);
+ if (cmdline_f || all)
+ {
+ sprintf (fname1, "/proc/%lld/cmdline", pid);
+ if ((procfile = fopen (fname1, "r")) > 0)
+ {
+ fgets (buffer, sizeof (buffer), procfile);
+ printf_filtered ("cmdline = '%s'\n", buffer);
+ fclose (procfile);
+ }
+ else
+ warning ("unable to open /proc file '%s'", fname1);
+ }
+ if (cwd_f || all)
+ {
+ sprintf (fname1, "/proc/%lld/cwd", pid);
+ memset (fname2, 0, sizeof (fname2));
+ if (readlink (fname1, fname2, sizeof (fname2)) > 0)
+ printf_filtered ("cwd = '%s'\n", fname2);
+ else
+ warning ("unable to read link '%s'", fname1);
+ }
+ if (exe_f || all)
+ {
+ sprintf (fname1, "/proc/%lld/exe", pid);
+ memset (fname2, 0, sizeof (fname2));
+ if (readlink (fname1, fname2, sizeof (fname2)) > 0)
+ printf_filtered ("exe = '%s'\n", fname2);
+ else
+ warning ("unable to read link '%s'", fname1);
+ }
+ if (mappings_f || all)
+ {
+ sprintf (fname1, "/proc/%lld/maps", pid);
+ if ((procfile = fopen (fname1, "r")) > 0)
+ {
+ long long addr, endaddr, size, offset, inode;
+ char permissions[8], device[8], filename[MAXPATHLEN];
+ char *header_fmt_string, *data_fmt_string;
+
+ if (TARGET_ADDR_BIT == 32)
+ {
+ header_fmt_string = "\t%10s %10s %10s %10s %7s\n";
+ data_fmt_string = "\t%#10lx %#10lx %#10x %#10x %7s\n";
+ }
+ else
+ {
+ header_fmt_string = " %18s %18s %10s %10s %7s\n";
+ data_fmt_string = " %#18lx %#18lx %#10x %#10x %7s\n";
+ }
+
+ printf_filtered ("Mapped address spaces:\n\n");
+ printf_filtered (header_fmt_string,
+ "Start Addr",
+ " End Addr",
+ " Size",
+ " Offset",
+ "objfile");
+
+ while (read_mapping (procfile, &addr, &endaddr, &permissions[0],
+ &offset, &device[0], &inode, &filename[0]))
+ {
+ size = endaddr - addr;
+ printf_filtered (data_fmt_string,
+ (unsigned long) addr, /* FIXME: pr_addr */
+ (unsigned long) endaddr,
+ (int) size,
+ (unsigned int) offset,
+ filename[0] ? filename : "");
+
+ }
+
+ fclose (procfile);
+ }
+ else
+ warning ("unable to open /proc file '%s'", fname1);
+ }
+ if (status_f || all)
+ {
+ sprintf (fname1, "/proc/%lld/status", pid);
+ if ((procfile = fopen (fname1, "r")) > 0)
+ {
+ while (fgets (buffer, sizeof (buffer), procfile) != NULL)
+ printf_filtered (buffer);
+ fclose (procfile);
+ }
+ else
+ warning ("unable to open /proc file '%s'", fname1);
+ }
+ if (stat_f || all)
+ {
+ sprintf (fname1, "/proc/%lld/stat", pid);
+ if ((procfile = fopen (fname1, "r")) > 0)
+ {
+ int itmp;
+ char ctmp;
+
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("Process: %d\n", itmp);
+ if (fscanf (procfile, "%s ", &buffer[0]) > 0)
+ printf_filtered ("Exec file: %s\n", buffer);
+ if (fscanf (procfile, "%c ", &ctmp) > 0)
+ printf_filtered ("State: %c\n", ctmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("Parent process: %d\n", itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("Process group: %d\n", itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("Session id: %d\n", itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("TTY: %d\n", itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("TTY owner process group: %d\n", itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0)
+ printf_filtered ("Flags: 0x%x\n", itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0)
+ printf_filtered ("Minor faults (no memory page): %u\n",
+ (unsigned int) itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0)
+ printf_filtered ("Minor faults, children: %u\n",
+ (unsigned int) itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0)
+ printf_filtered ("Major faults (memory page faults): %u\n",
+ (unsigned int) itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0)
+ printf_filtered ("Major faults, children: %u\n",
+ (unsigned int) itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("utime: %d\n", itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("stime: %d\n", itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("utime, children: %d\n", itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("stime, children: %d\n", itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("jiffies remaining in current time slice: %d\n",
+ itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("'nice' value: %d\n", itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0)
+ printf_filtered ("jiffies until next timeout: %u\n",
+ (unsigned int) itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0)
+ printf_filtered ("jiffies until next SIGALRM: %u\n",
+ (unsigned int) itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("start time (jiffies since system boot): %d\n",
+ itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0)
+ printf_filtered ("Virtual memory size: %u\n",
+ (unsigned int) itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0)
+ printf_filtered ("Resident set size: %u\n",
+ (unsigned int) itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0)
+ printf_filtered ("rlim: %u\n",
+ (unsigned int) itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0)
+ printf_filtered ("Start of text: 0x%x\n", itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0)
+ printf_filtered ("End of text: 0x%x\n", itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0)
+ printf_filtered ("Start of stack: 0x%x\n", itmp);
+#if 0 /* Don't know how architecture-dependent the rest is...
+ Anyway the signal bitmap info is available from "status". */
+ if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
+ printf_filtered ("Kernel stack pointer: 0x%x\n", itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
+ printf_filtered ("Kernel instr pointer: 0x%x\n", itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("Pending signals bitmap: 0x%x\n", itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("Blocked signals bitmap: 0x%x\n", itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("Ignored signals bitmap: 0x%x\n", itmp);
+ if (fscanf (procfile, "%d ", &itmp) > 0)
+ printf_filtered ("Catched signals bitmap: 0x%x\n", itmp);
+ if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
+ printf_filtered ("wchan (system call): 0x%x\n", itmp);
+#endif
+ fclose (procfile);
+ }
+ else
+ warning ("unable to open /proc file '%s'", fname1);
+ }
+}
+
+void
+_initialize_linux_proc (void)
+{
+ extern void inftarg_set_find_memory_regions ();
+ extern void inftarg_set_make_corefile_notes ();
+
+ inftarg_set_find_memory_regions (linux_find_memory_regions);
+ inftarg_set_make_corefile_notes (linux_make_note_section);
+
+ add_info ("proc", linux_info_proc_cmd,
+ "Show /proc process information about any running process.\n\
+Specify any process id, or use the program being debugged by default.\n\
+Specify any of the following keywords for detailed info:\n\
+ mappings -- list of mapped memory regions.\n\
+ stat -- list a bunch of random process info.\n\
+ status -- list a different bunch of random process info.\n\
+ all -- list all available /proc info.");
+}
diff --git a/gdb/lynx-nat.c b/gdb/lynx-nat.c
new file mode 100644
index 00000000000..9cd1672d336
--- /dev/null
+++ b/gdb/lynx-nat.c
@@ -0,0 +1,829 @@
+/* Native-dependent code for LynxOS.
+ Copyright 1993, 1994, 1995, 1996, 1999, 2000, 2001
+ 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#include <sys/ptrace.h>
+#include <sys/wait.h>
+#include <sys/fpp.h>
+
+static unsigned long registers_addr (int pid);
+static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
+
+#define X(ENTRY)(offsetof(struct econtext, ENTRY))
+
+#ifdef I386
+/* Mappings from tm-i386v.h */
+
+static int regmap[] =
+{
+ X (eax),
+ X (ecx),
+ X (edx),
+ X (ebx),
+ X (esp), /* sp */
+ X (ebp), /* fp */
+ X (esi),
+ X (edi),
+ X (eip), /* pc */
+ X (flags), /* ps */
+ X (cs),
+ X (ss),
+ X (ds),
+ X (es),
+ X (ecode), /* Lynx doesn't give us either fs or gs, so */
+ X (fault), /* we just substitute these two in the hopes
+ that they are useful. */
+};
+#endif /* I386 */
+
+#ifdef M68K
+/* Mappings from tm-m68k.h */
+
+static int regmap[] =
+{
+ X (regs[0]), /* d0 */
+ X (regs[1]), /* d1 */
+ X (regs[2]), /* d2 */
+ X (regs[3]), /* d3 */
+ X (regs[4]), /* d4 */
+ X (regs[5]), /* d5 */
+ X (regs[6]), /* d6 */
+ X (regs[7]), /* d7 */
+ X (regs[8]), /* a0 */
+ X (regs[9]), /* a1 */
+ X (regs[10]), /* a2 */
+ X (regs[11]), /* a3 */
+ X (regs[12]), /* a4 */
+ X (regs[13]), /* a5 */
+ X (regs[14]), /* fp */
+ offsetof (st_t, usp) - offsetof (st_t, ec), /* sp */
+ X (status), /* ps */
+ X (pc),
+
+ X (fregs[0 * 3]), /* fp0 */
+ X (fregs[1 * 3]), /* fp1 */
+ X (fregs[2 * 3]), /* fp2 */
+ X (fregs[3 * 3]), /* fp3 */
+ X (fregs[4 * 3]), /* fp4 */
+ X (fregs[5 * 3]), /* fp5 */
+ X (fregs[6 * 3]), /* fp6 */
+ X (fregs[7 * 3]), /* fp7 */
+
+ X (fcregs[0]), /* fpcontrol */
+ X (fcregs[1]), /* fpstatus */
+ X (fcregs[2]), /* fpiaddr */
+ X (ssw), /* fpcode */
+ X (fault), /* fpflags */
+};
+#endif /* M68K */
+
+#ifdef SPARC
+/* Mappings from tm-sparc.h */
+
+#define FX(ENTRY)(offsetof(struct fcontext, ENTRY))
+
+static int regmap[] =
+{
+ -1, /* g0 */
+ X (g1),
+ X (g2),
+ X (g3),
+ X (g4),
+ -1, /* g5->g7 aren't saved by Lynx */
+ -1,
+ -1,
+
+ X (o[0]),
+ X (o[1]),
+ X (o[2]),
+ X (o[3]),
+ X (o[4]),
+ X (o[5]),
+ X (o[6]), /* sp */
+ X (o[7]), /* ra */
+
+ -1, -1, -1, -1, -1, -1, -1, -1, /* l0 -> l7 */
+
+ -1, -1, -1, -1, -1, -1, -1, -1, /* i0 -> i7 */
+
+ FX (f.fregs[0]), /* f0 */
+ FX (f.fregs[1]),
+ FX (f.fregs[2]),
+ FX (f.fregs[3]),
+ FX (f.fregs[4]),
+ FX (f.fregs[5]),
+ FX (f.fregs[6]),
+ FX (f.fregs[7]),
+ FX (f.fregs[8]),
+ FX (f.fregs[9]),
+ FX (f.fregs[10]),
+ FX (f.fregs[11]),
+ FX (f.fregs[12]),
+ FX (f.fregs[13]),
+ FX (f.fregs[14]),
+ FX (f.fregs[15]),
+ FX (f.fregs[16]),
+ FX (f.fregs[17]),
+ FX (f.fregs[18]),
+ FX (f.fregs[19]),
+ FX (f.fregs[20]),
+ FX (f.fregs[21]),
+ FX (f.fregs[22]),
+ FX (f.fregs[23]),
+ FX (f.fregs[24]),
+ FX (f.fregs[25]),
+ FX (f.fregs[26]),
+ FX (f.fregs[27]),
+ FX (f.fregs[28]),
+ FX (f.fregs[29]),
+ FX (f.fregs[30]),
+ FX (f.fregs[31]),
+
+ X (y),
+ X (psr),
+ X (wim),
+ X (tbr),
+ X (pc),
+ X (npc),
+ FX (fsr), /* fpsr */
+ -1, /* cpsr */
+};
+#endif /* SPARC */
+
+#ifdef rs6000
+
+static int regmap[] =
+{
+ X (iregs[0]), /* r0 */
+ X (iregs[1]),
+ X (iregs[2]),
+ X (iregs[3]),
+ X (iregs[4]),
+ X (iregs[5]),
+ X (iregs[6]),
+ X (iregs[7]),
+ X (iregs[8]),
+ X (iregs[9]),
+ X (iregs[10]),
+ X (iregs[11]),
+ X (iregs[12]),
+ X (iregs[13]),
+ X (iregs[14]),
+ X (iregs[15]),
+ X (iregs[16]),
+ X (iregs[17]),
+ X (iregs[18]),
+ X (iregs[19]),
+ X (iregs[20]),
+ X (iregs[21]),
+ X (iregs[22]),
+ X (iregs[23]),
+ X (iregs[24]),
+ X (iregs[25]),
+ X (iregs[26]),
+ X (iregs[27]),
+ X (iregs[28]),
+ X (iregs[29]),
+ X (iregs[30]),
+ X (iregs[31]),
+
+ X (fregs[0]), /* f0 */
+ X (fregs[1]),
+ X (fregs[2]),
+ X (fregs[3]),
+ X (fregs[4]),
+ X (fregs[5]),
+ X (fregs[6]),
+ X (fregs[7]),
+ X (fregs[8]),
+ X (fregs[9]),
+ X (fregs[10]),
+ X (fregs[11]),
+ X (fregs[12]),
+ X (fregs[13]),
+ X (fregs[14]),
+ X (fregs[15]),
+ X (fregs[16]),
+ X (fregs[17]),
+ X (fregs[18]),
+ X (fregs[19]),
+ X (fregs[20]),
+ X (fregs[21]),
+ X (fregs[22]),
+ X (fregs[23]),
+ X (fregs[24]),
+ X (fregs[25]),
+ X (fregs[26]),
+ X (fregs[27]),
+ X (fregs[28]),
+ X (fregs[29]),
+ X (fregs[30]),
+ X (fregs[31]),
+
+ X (srr0), /* IAR (PC) */
+ X (srr1), /* MSR (PS) */
+ X (cr), /* CR */
+ X (lr), /* LR */
+ X (ctr), /* CTR */
+ X (xer), /* XER */
+ X (mq) /* MQ */
+};
+
+#endif /* rs6000 */
+
+#ifdef SPARC
+
+/* This routine handles some oddball cases for Sparc registers and LynxOS.
+ In partucular, it causes refs to G0, g5->7, and all fp regs to return zero.
+ It also handles knows where to find the I & L regs on the stack. */
+
+void
+fetch_inferior_registers (int regno)
+{
+ int whatregs = 0;
+
+#define WHATREGS_FLOAT 1
+#define WHATREGS_GEN 2
+#define WHATREGS_STACK 4
+
+ if (regno == -1)
+ whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
+ else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
+ whatregs = WHATREGS_STACK;
+ else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
+ whatregs = WHATREGS_FLOAT;
+ else
+ whatregs = WHATREGS_GEN;
+
+ if (whatregs & WHATREGS_GEN)
+ {
+ struct econtext ec; /* general regs */
+ char buf[MAX_REGISTER_RAW_SIZE];
+ int retval;
+ int i;
+
+ errno = 0;
+ retval = ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & ec, 0);
+ if (errno)
+ perror_with_name ("ptrace(PTRACE_GETREGS)");
+
+ memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM));
+ supply_register (G0_REGNUM, buf);
+ supply_register (TBR_REGNUM, (char *) &ec.tbr);
+
+ memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &ec.g1,
+ 4 * REGISTER_RAW_SIZE (G1_REGNUM));
+ for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++)
+ register_valid[i] = 1;
+
+ supply_register (PS_REGNUM, (char *) &ec.psr);
+ supply_register (Y_REGNUM, (char *) &ec.y);
+ supply_register (PC_REGNUM, (char *) &ec.pc);
+ supply_register (NPC_REGNUM, (char *) &ec.npc);
+ supply_register (WIM_REGNUM, (char *) &ec.wim);
+
+ memcpy (&registers[REGISTER_BYTE (O0_REGNUM)], ec.o,
+ 8 * REGISTER_RAW_SIZE (O0_REGNUM));
+ for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++)
+ register_valid[i] = 1;
+ }
+
+ if (whatregs & WHATREGS_STACK)
+ {
+ CORE_ADDR sp;
+ int i;
+
+ sp = read_register (SP_REGNUM);
+
+ target_read_memory (sp + FRAME_SAVED_I0,
+ &registers[REGISTER_BYTE (I0_REGNUM)],
+ 8 * REGISTER_RAW_SIZE (I0_REGNUM));
+ for (i = I0_REGNUM; i <= I7_REGNUM; i++)
+ register_valid[i] = 1;
+
+ target_read_memory (sp + FRAME_SAVED_L0,
+ &registers[REGISTER_BYTE (L0_REGNUM)],
+ 8 * REGISTER_RAW_SIZE (L0_REGNUM));
+ for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++)
+ register_valid[i] = 1;
+ }
+
+ if (whatregs & WHATREGS_FLOAT)
+ {
+ struct fcontext fc; /* fp regs */
+ int retval;
+ int i;
+
+ errno = 0;
+ retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & fc, 0);
+ if (errno)
+ perror_with_name ("ptrace(PTRACE_GETFPREGS)");
+
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs,
+ 32 * REGISTER_RAW_SIZE (FP0_REGNUM));
+ for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
+ register_valid[i] = 1;
+
+ supply_register (FPS_REGNUM, (char *) &fc.fsr);
+ }
+}
+
+/* This routine handles storing of the I & L regs for the Sparc. The trick
+ here is that they actually live on the stack. The really tricky part is
+ that when changing the stack pointer, the I & L regs must be written to
+ where the new SP points, otherwise the regs will be incorrect when the
+ process is started up again. We assume that the I & L regs are valid at
+ this point. */
+
+void
+store_inferior_registers (int regno)
+{
+ int whatregs = 0;
+
+ if (regno == -1)
+ whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
+ else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
+ whatregs = WHATREGS_STACK;
+ else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
+ whatregs = WHATREGS_FLOAT;
+ else if (regno == SP_REGNUM)
+ whatregs = WHATREGS_STACK | WHATREGS_GEN;
+ else
+ whatregs = WHATREGS_GEN;
+
+ if (whatregs & WHATREGS_GEN)
+ {
+ struct econtext ec; /* general regs */
+ int retval;
+
+ ec.tbr = read_register (TBR_REGNUM);
+ memcpy (&ec.g1, &registers[REGISTER_BYTE (G1_REGNUM)],
+ 4 * REGISTER_RAW_SIZE (G1_REGNUM));
+
+ ec.psr = read_register (PS_REGNUM);
+ ec.y = read_register (Y_REGNUM);
+ ec.pc = read_register (PC_REGNUM);
+ ec.npc = read_register (NPC_REGNUM);
+ ec.wim = read_register (WIM_REGNUM);
+
+ memcpy (ec.o, &registers[REGISTER_BYTE (O0_REGNUM)],
+ 8 * REGISTER_RAW_SIZE (O0_REGNUM));
+
+ errno = 0;
+ retval = ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & ec, 0);
+ if (errno)
+ perror_with_name ("ptrace(PTRACE_SETREGS)");
+ }
+
+ if (whatregs & WHATREGS_STACK)
+ {
+ int regoffset;
+ CORE_ADDR sp;
+
+ sp = read_register (SP_REGNUM);
+
+ if (regno == -1 || regno == SP_REGNUM)
+ {
+ if (!register_valid[L0_REGNUM + 5])
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ target_write_memory (sp + FRAME_SAVED_I0,
+ &registers[REGISTER_BYTE (I0_REGNUM)],
+ 8 * REGISTER_RAW_SIZE (I0_REGNUM));
+
+ target_write_memory (sp + FRAME_SAVED_L0,
+ &registers[REGISTER_BYTE (L0_REGNUM)],
+ 8 * REGISTER_RAW_SIZE (L0_REGNUM));
+ }
+ else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
+ {
+ if (!register_valid[regno])
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ if (regno >= L0_REGNUM && regno <= L0_REGNUM + 7)
+ regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM)
+ + FRAME_SAVED_L0;
+ else
+ regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (I0_REGNUM)
+ + FRAME_SAVED_I0;
+ target_write_memory (sp + regoffset,
+ &registers[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE (regno));
+ }
+ }
+
+ if (whatregs & WHATREGS_FLOAT)
+ {
+ struct fcontext fc; /* fp regs */
+ int retval;
+
+/* We read fcontext first so that we can get good values for fq_t... */
+ errno = 0;
+ retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & fc, 0);
+ if (errno)
+ perror_with_name ("ptrace(PTRACE_GETFPREGS)");
+
+ memcpy (fc.f.fregs, &registers[REGISTER_BYTE (FP0_REGNUM)],
+ 32 * REGISTER_RAW_SIZE (FP0_REGNUM));
+
+ fc.fsr = read_register (FPS_REGNUM);
+
+ errno = 0;
+ retval = ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & fc, 0);
+ if (errno)
+ perror_with_name ("ptrace(PTRACE_SETFPREGS)");
+ }
+}
+#endif /* SPARC */
+
+#if defined (I386) || defined (M68K) || defined (rs6000)
+
+/* Return the offset relative to the start of the per-thread data to the
+ saved context block. */
+
+static unsigned long
+registers_addr (int pid)
+{
+ CORE_ADDR stblock;
+ int ecpoff = offsetof (st_t, ecp);
+ CORE_ADDR ecp;
+
+ errno = 0;
+ stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0,
+ 0);
+ if (errno)
+ perror_with_name ("ptrace(PTRACE_THREADUSER)");
+
+ ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) ecpoff,
+ 0);
+ if (errno)
+ perror_with_name ("ptrace(PTRACE_PEEKTHREAD)");
+
+ return ecp - stblock;
+}
+
+/* Fetch one or more registers from the inferior. REGNO == -1 to get
+ them all. We actually fetch more than requested, when convenient,
+ marking them as valid so we won't fetch them again. */
+
+void
+fetch_inferior_registers (int regno)
+{
+ int reglo, reghi;
+ int i;
+ unsigned long ecp;
+
+ if (regno == -1)
+ {
+ reglo = 0;
+ reghi = NUM_REGS - 1;
+ }
+ else
+ reglo = reghi = regno;
+
+ ecp = registers_addr (PIDGET (inferior_ptid));
+
+ for (regno = reglo; regno <= reghi; regno++)
+ {
+ char buf[MAX_REGISTER_RAW_SIZE];
+ int ptrace_fun = PTRACE_PEEKTHREAD;
+
+#ifdef M68K
+ ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
+#endif
+
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+ {
+ unsigned int reg;
+
+ errno = 0;
+ reg = ptrace (ptrace_fun, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), 0);
+ if (errno)
+ perror_with_name ("ptrace(PTRACE_PEEKUSP)");
+
+ *(int *) &buf[i] = reg;
+ }
+ supply_register (regno, buf);
+ }
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ int reglo, reghi;
+ int i;
+ unsigned long ecp;
+
+ if (regno == -1)
+ {
+ reglo = 0;
+ reghi = NUM_REGS - 1;
+ }
+ else
+ reglo = reghi = regno;
+
+ ecp = registers_addr (PIDGET (inferior_ptid));
+
+ for (regno = reglo; regno <= reghi; regno++)
+ {
+ int ptrace_fun = PTRACE_POKEUSER;
+
+ if (CANNOT_STORE_REGISTER (regno))
+ continue;
+
+#ifdef M68K
+ ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
+#endif
+
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+ {
+ unsigned int reg;
+
+ reg = *(unsigned int *) &registers[REGISTER_BYTE (regno) + i];
+
+ errno = 0;
+ ptrace (ptrace_fun, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), reg);
+ if (errno)
+ perror_with_name ("ptrace(PTRACE_POKEUSP)");
+ }
+ }
+}
+#endif /* defined (I386) || defined (M68K) || defined (rs6000) */
+
+/* Wait for child to do something. Return pid of child, or -1 in case
+ of error; store status through argument pointer OURSTATUS. */
+
+ptid_t
+child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+{
+ int save_errno;
+ int thread;
+ union wait status;
+ int pid;
+
+ while (1)
+ {
+ int sig;
+
+ set_sigint_trap (); /* Causes SIGINT to be passed on to the
+ attached process. */
+ pid = wait (&status);
+
+ save_errno = errno;
+
+ clear_sigint_trap ();
+
+ if (pid == -1)
+ {
+ if (save_errno == EINTR)
+ continue;
+ fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
+ safe_strerror (save_errno));
+ /* Claim it exited with unknown signal. */
+ ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
+ ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
+ return -1;
+ }
+
+ if (pid != PIDGET (inferior_ptid)) /* Some other process?!? */
+ continue;
+
+ thread = status.w_tid; /* Get thread id from status */
+
+ /* Initial thread value can only be acquired via wait, so we have to
+ resort to this hack. */
+
+ if (TIDGET (inferior_ptid) == 0 && thread != 0)
+ {
+ inferior_ptid = MERGEPID (PIDGET (inferior_ptid), thread);
+ add_thread (inferior_ptid);
+ }
+
+ ptid = BUILDPID (pid, thread);
+
+ /* We've become a single threaded process again. */
+ if (thread == 0)
+ inferior_ptid = ptid;
+
+ /* Check for thread creation. */
+ if (WIFSTOPPED (status)
+ && WSTOPSIG (status) == SIGTRAP
+ && !in_thread_list (ptid))
+ {
+ int realsig;
+
+ realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
+ (PTRACE_ARG3_TYPE) 0, 0);
+
+ if (realsig == SIGNEWTHREAD)
+ {
+ /* It's a new thread notification. We don't want to much with
+ realsig -- the code in wait_for_inferior expects SIGTRAP. */
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+ ourstatus->value.sig = TARGET_SIGNAL_0;
+ return ptid;
+ }
+ else
+ error ("Signal for unknown thread was not SIGNEWTHREAD");
+ }
+
+ /* Check for thread termination. */
+ else if (WIFSTOPPED (status)
+ && WSTOPSIG (status) == SIGTRAP
+ && in_thread_list (ptid))
+ {
+ int realsig;
+
+ realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
+ (PTRACE_ARG3_TYPE) 0, 0);
+
+ if (realsig == SIGTHREADEXIT)
+ {
+ ptrace (PTRACE_CONT, PIDGET (ptid), (PTRACE_ARG3_TYPE) 0, 0);
+ continue;
+ }
+ }
+
+#ifdef SPARC
+ /* SPARC Lynx uses an byte reversed wait status; we must use the
+ host macros to access it. These lines just a copy of
+ store_waitstatus. We can't use CHILD_SPECIAL_WAITSTATUS
+ because target.c can't include the Lynx <sys/wait.h>. */
+ if (WIFEXITED (status))
+ {
+ ourstatus->kind = TARGET_WAITKIND_EXITED;
+ ourstatus->value.integer = WEXITSTATUS (status);
+ }
+ else if (!WIFSTOPPED (status))
+ {
+ ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
+ ourstatus->value.sig =
+ target_signal_from_host (WTERMSIG (status));
+ }
+ else
+ {
+ ourstatus->kind = TARGET_WAITKIND_STOPPED;
+ ourstatus->value.sig =
+ target_signal_from_host (WSTOPSIG (status));
+ }
+#else
+ store_waitstatus (ourstatus, status.w_status);
+#endif
+
+ return ptid;
+ }
+}
+
+/* Return nonzero if the given thread is still alive. */
+int
+child_thread_alive (ptid_t ptid)
+{
+ int pid = PIDGET (ptid);
+
+ /* Arggh. Apparently pthread_kill only works for threads within
+ the process that calls pthread_kill.
+
+ We want to avoid the lynx signal extensions as they simply don't
+ map well to the generic gdb interface we want to keep.
+
+ All we want to do is determine if a particular thread is alive;
+ it appears as if we can just make a harmless thread specific
+ ptrace call to do that. */
+ return (ptrace (PTRACE_THREADUSER, pid, 0, 0) != -1);
+}
+
+/* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+void
+child_resume (ptid_t ptid, int step, enum target_signal signal)
+{
+ int func;
+ int pid = PIDGET (ptid);
+
+ errno = 0;
+
+ /* If pid == -1, then we want to step/continue all threads, else
+ we only want to step/continue a single thread. */
+ if (pid == -1)
+ {
+ pid = PIDGET (inferior_ptid);
+ func = step ? PTRACE_SINGLESTEP : PTRACE_CONT;
+ }
+ else
+ func = step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT_ONE;
+
+
+ /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where
+ it was. (If GDB wanted it to start some other way, we have already
+ written a new PC value to the child.)
+
+ If this system does not support PT_STEP, a higher level function will
+ have called single_step() to transmute the step request into a
+ continue request (by setting breakpoints on all possible successor
+ instructions), so we don't have to worry about that here. */
+
+ ptrace (func, pid, (PTRACE_ARG3_TYPE) 1, target_signal_to_host (signal));
+
+ if (errno)
+ perror_with_name ("ptrace");
+}
+
+/* Convert a Lynx process ID to a string. Returns the string in a static
+ buffer. */
+
+char *
+child_pid_to_str (ptid_t ptid)
+{
+ static char buf[40];
+
+ sprintf (buf, "process %d thread %d", PIDGET (ptid), TIDGET (ptid));
+
+ return buf;
+}
+
+/* Extract the register values out of the core file and store
+ them where `read_register' will find them.
+
+ CORE_REG_SECT points to the register values themselves, read into memory.
+ CORE_REG_SIZE is the size of that area.
+ WHICH says which set of registers we are handling (0 = int, 2 = float
+ on machines where they are discontiguous).
+ REG_ADDR is the offset from u.u_ar0 to the register values relative to
+ core_reg_sect. This is used with old-fashioned core files to
+ locate the registers in a large upage-plus-stack ".reg" section.
+ Original upage address X is at location core_reg_sect+x+reg_addr.
+ */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR reg_addr)
+{
+ struct st_entry s;
+ unsigned int regno;
+
+ for (regno = 0; regno < NUM_REGS; regno++)
+ if (regmap[regno] != -1)
+ supply_register (regno, core_reg_sect + offsetof (st_t, ec)
+ + regmap[regno]);
+
+#ifdef SPARC
+/* Fetching this register causes all of the I & L regs to be read from the
+ stack and validated. */
+
+ fetch_inferior_registers (I0_REGNUM);
+#endif
+}
+
+
+/* Register that we are able to handle lynx core file formats.
+ FIXME: is this really bfd_target_unknown_flavour? */
+
+static struct core_fns lynx_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_lynx (void)
+{
+ add_core_fns (&lynx_core_fns);
+}
diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y
new file mode 100644
index 00000000000..772c6b7b286
--- /dev/null
+++ b/gdb/m2-exp.y
@@ -0,0 +1,1099 @@
+/* YACC grammar for Modula-2 expressions, for GDB.
+ Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999,
+ 2000
+ Free Software Foundation, Inc.
+ Generated from expread.y (now c-exp.y) and contributed by the Department
+ of Computer Science at the State University of New York at Buffalo, 1991.
+
+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. */
+
+/* Parse a Modula-2 expression from text in a string,
+ and return the result as a struct expression pointer.
+ That structure contains arithmetic operations in reverse polish,
+ with constants represented by operations that are followed by special data.
+ See expression.h for the details of the format.
+ What is important here is that it can be built up sequentially
+ during the process of parsing; the lower levels of the tree always
+ come first in the result.
+
+ Note that malloc's and realloc's in this file are transformed to
+ xmalloc and xrealloc respectively by the same sed command in the
+ makefile that remaps any other malloc/realloc inserted by the parser
+ generator. Doing this with #defines and trying to control the interaction
+ with include files (<malloc.h> and <stdlib.h> for example) just became
+ too messy, particularly when such includes can be inserted at random
+ times by the parser generator. */
+
+%{
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "expression.h"
+#include "language.h"
+#include "value.h"
+#include "parser-defs.h"
+#include "m2-lang.h"
+#include "bfd.h" /* Required by objfiles.h. */
+#include "symfile.h" /* Required by objfiles.h. */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
+ as well as gratuitiously global symbol names, so we can have multiple
+ yacc generated parsers in gdb. Note that these are only the variables
+ produced by yacc. If other parser generators (bison, byacc, etc) produce
+ additional global names that conflict at link time, then those parser
+ generators need to be fixed instead of adding those names to this list. */
+
+#define yymaxdepth m2_maxdepth
+#define yyparse m2_parse
+#define yylex m2_lex
+#define yyerror m2_error
+#define yylval m2_lval
+#define yychar m2_char
+#define yydebug m2_debug
+#define yypact m2_pact
+#define yyr1 m2_r1
+#define yyr2 m2_r2
+#define yydef m2_def
+#define yychk m2_chk
+#define yypgo m2_pgo
+#define yyact m2_act
+#define yyexca m2_exca
+#define yyerrflag m2_errflag
+#define yynerrs m2_nerrs
+#define yyps m2_ps
+#define yypv m2_pv
+#define yys m2_s
+#define yy_yys m2_yys
+#define yystate m2_state
+#define yytmp m2_tmp
+#define yyv m2_v
+#define yy_yyv m2_yyv
+#define yyval m2_val
+#define yylloc m2_lloc
+#define yyreds m2_reds /* With YYDEBUG defined */
+#define yytoks m2_toks /* With YYDEBUG defined */
+#define yylhs m2_yylhs
+#define yylen m2_yylen
+#define yydefred m2_yydefred
+#define yydgoto m2_yydgoto
+#define yysindex m2_yysindex
+#define yyrindex m2_yyrindex
+#define yygindex m2_yygindex
+#define yytable m2_yytable
+#define yycheck m2_yycheck
+
+#ifndef YYDEBUG
+#define YYDEBUG 0 /* Default to no yydebug support */
+#endif
+
+int yyparse (void);
+
+static int yylex (void);
+
+void yyerror (char *);
+
+#if 0
+static char *make_qualname (char *, char *);
+#endif
+
+static int parse_number (int);
+
+/* The sign of the number being parsed. */
+static int number_sign = 1;
+
+/* The block that the module specified by the qualifer on an identifer is
+ contained in, */
+#if 0
+static struct block *modblock=0;
+#endif
+
+%}
+
+/* Although the yacc "value" of an expression is not used,
+ since the result is stored in the structure being created,
+ other node types do have values. */
+
+%union
+ {
+ LONGEST lval;
+ ULONGEST ulval;
+ DOUBLEST dval;
+ struct symbol *sym;
+ struct type *tval;
+ struct stoken sval;
+ int voidval;
+ struct block *bval;
+ enum exp_opcode opcode;
+ struct internalvar *ivar;
+
+ struct type **tvec;
+ int *ivec;
+ }
+
+%type <voidval> exp type_exp start set
+%type <voidval> variable
+%type <tval> type
+%type <bval> block
+%type <sym> fblock
+
+%token <lval> INT HEX ERROR
+%token <ulval> UINT M2_TRUE M2_FALSE CHAR
+%token <dval> FLOAT
+
+/* Both NAME and TYPENAME tokens represent symbols in the input,
+ and both convey their data as strings.
+ But a TYPENAME is a string that happens to be defined as a typedef
+ or builtin type name (such as int or char)
+ and a NAME is any other symbol.
+
+ Contexts where this distinction is not important can use the
+ nonterminal "name", which matches either NAME or TYPENAME. */
+
+%token <sval> STRING
+%token <sval> NAME BLOCKNAME IDENT VARNAME
+%token <sval> TYPENAME
+
+%token SIZE CAP ORD HIGH ABS MIN_FUNC MAX_FUNC FLOAT_FUNC VAL CHR ODD TRUNC
+%token INC DEC INCL EXCL
+
+/* The GDB scope operator */
+%token COLONCOLON
+
+%token <voidval> INTERNAL_VAR
+
+/* M2 tokens */
+%left ','
+%left ABOVE_COMMA
+%nonassoc ASSIGN
+%left '<' '>' LEQ GEQ '=' NOTEQUAL '#' IN
+%left OROR
+%left LOGICAL_AND '&'
+%left '@'
+%left '+' '-'
+%left '*' '/' DIV MOD
+%right UNARY
+%right '^' DOT '[' '('
+%right NOT '~'
+%left COLONCOLON QID
+/* This is not an actual token ; it is used for precedence.
+%right QID
+*/
+
+
+%%
+
+start : exp
+ | type_exp
+ ;
+
+type_exp: type
+ { write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type($1);
+ write_exp_elt_opcode(OP_TYPE);
+ }
+ ;
+
+/* Expressions */
+
+exp : exp '^' %prec UNARY
+ { write_exp_elt_opcode (UNOP_IND); }
+
+exp : '-'
+ { number_sign = -1; }
+ exp %prec UNARY
+ { number_sign = 1;
+ write_exp_elt_opcode (UNOP_NEG); }
+ ;
+
+exp : '+' exp %prec UNARY
+ { write_exp_elt_opcode(UNOP_PLUS); }
+ ;
+
+exp : not_exp exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
+ ;
+
+not_exp : NOT
+ | '~'
+ ;
+
+exp : CAP '(' exp ')'
+ { write_exp_elt_opcode (UNOP_CAP); }
+ ;
+
+exp : ORD '(' exp ')'
+ { write_exp_elt_opcode (UNOP_ORD); }
+ ;
+
+exp : ABS '(' exp ')'
+ { write_exp_elt_opcode (UNOP_ABS); }
+ ;
+
+exp : HIGH '(' exp ')'
+ { write_exp_elt_opcode (UNOP_HIGH); }
+ ;
+
+exp : MIN_FUNC '(' type ')'
+ { write_exp_elt_opcode (UNOP_MIN);
+ write_exp_elt_type ($3);
+ write_exp_elt_opcode (UNOP_MIN); }
+ ;
+
+exp : MAX_FUNC '(' type ')'
+ { write_exp_elt_opcode (UNOP_MAX);
+ write_exp_elt_type ($3);
+ write_exp_elt_opcode (UNOP_MIN); }
+ ;
+
+exp : FLOAT_FUNC '(' exp ')'
+ { write_exp_elt_opcode (UNOP_FLOAT); }
+ ;
+
+exp : VAL '(' type ',' exp ')'
+ { write_exp_elt_opcode (BINOP_VAL);
+ write_exp_elt_type ($3);
+ write_exp_elt_opcode (BINOP_VAL); }
+ ;
+
+exp : CHR '(' exp ')'
+ { write_exp_elt_opcode (UNOP_CHR); }
+ ;
+
+exp : ODD '(' exp ')'
+ { write_exp_elt_opcode (UNOP_ODD); }
+ ;
+
+exp : TRUNC '(' exp ')'
+ { write_exp_elt_opcode (UNOP_TRUNC); }
+ ;
+
+exp : SIZE exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_SIZEOF); }
+ ;
+
+
+exp : INC '(' exp ')'
+ { write_exp_elt_opcode(UNOP_PREINCREMENT); }
+ ;
+
+exp : INC '(' exp ',' exp ')'
+ { write_exp_elt_opcode(BINOP_ASSIGN_MODIFY);
+ write_exp_elt_opcode(BINOP_ADD);
+ write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); }
+ ;
+
+exp : DEC '(' exp ')'
+ { write_exp_elt_opcode(UNOP_PREDECREMENT);}
+ ;
+
+exp : DEC '(' exp ',' exp ')'
+ { write_exp_elt_opcode(BINOP_ASSIGN_MODIFY);
+ write_exp_elt_opcode(BINOP_SUB);
+ write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); }
+ ;
+
+exp : exp DOT NAME
+ { write_exp_elt_opcode (STRUCTOP_STRUCT);
+ write_exp_string ($3);
+ write_exp_elt_opcode (STRUCTOP_STRUCT); }
+ ;
+
+exp : set
+ ;
+
+exp : exp IN set
+ { error("Sets are not implemented.");}
+ ;
+
+exp : INCL '(' exp ',' exp ')'
+ { error("Sets are not implemented.");}
+ ;
+
+exp : EXCL '(' exp ',' exp ')'
+ { error("Sets are not implemented.");}
+
+set : '{' arglist '}'
+ { error("Sets are not implemented.");}
+ | type '{' arglist '}'
+ { error("Sets are not implemented.");}
+ ;
+
+
+/* Modula-2 array subscript notation [a,b,c...] */
+exp : exp '['
+ /* This function just saves the number of arguments
+ that follow in the list. It is *not* specific to
+ function types */
+ { start_arglist(); }
+ non_empty_arglist ']' %prec DOT
+ { write_exp_elt_opcode (MULTI_SUBSCRIPT);
+ write_exp_elt_longcst ((LONGEST) end_arglist());
+ write_exp_elt_opcode (MULTI_SUBSCRIPT); }
+ ;
+
+exp : exp '('
+ /* This is to save the value of arglist_len
+ being accumulated by an outer function call. */
+ { start_arglist (); }
+ arglist ')' %prec DOT
+ { write_exp_elt_opcode (OP_FUNCALL);
+ write_exp_elt_longcst ((LONGEST) end_arglist ());
+ write_exp_elt_opcode (OP_FUNCALL); }
+ ;
+
+arglist :
+ ;
+
+arglist : exp
+ { arglist_len = 1; }
+ ;
+
+arglist : arglist ',' exp %prec ABOVE_COMMA
+ { arglist_len++; }
+ ;
+
+non_empty_arglist
+ : exp
+ { arglist_len = 1; }
+ ;
+
+non_empty_arglist
+ : non_empty_arglist ',' exp %prec ABOVE_COMMA
+ { arglist_len++; }
+ ;
+
+/* GDB construct */
+exp : '{' type '}' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_MEMVAL);
+ write_exp_elt_type ($2);
+ write_exp_elt_opcode (UNOP_MEMVAL); }
+ ;
+
+exp : type '(' exp ')' %prec UNARY
+ { write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type ($1);
+ write_exp_elt_opcode (UNOP_CAST); }
+ ;
+
+exp : '(' exp ')'
+ { }
+ ;
+
+/* Binary operators in order of decreasing precedence. Note that some
+ of these operators are overloaded! (ie. sets) */
+
+/* GDB construct */
+exp : exp '@' exp
+ { write_exp_elt_opcode (BINOP_REPEAT); }
+ ;
+
+exp : exp '*' exp
+ { write_exp_elt_opcode (BINOP_MUL); }
+ ;
+
+exp : exp '/' exp
+ { write_exp_elt_opcode (BINOP_DIV); }
+ ;
+
+exp : exp DIV exp
+ { write_exp_elt_opcode (BINOP_INTDIV); }
+ ;
+
+exp : exp MOD exp
+ { write_exp_elt_opcode (BINOP_REM); }
+ ;
+
+exp : exp '+' exp
+ { write_exp_elt_opcode (BINOP_ADD); }
+ ;
+
+exp : exp '-' exp
+ { write_exp_elt_opcode (BINOP_SUB); }
+ ;
+
+exp : exp '=' exp
+ { write_exp_elt_opcode (BINOP_EQUAL); }
+ ;
+
+exp : exp NOTEQUAL exp
+ { write_exp_elt_opcode (BINOP_NOTEQUAL); }
+ | exp '#' exp
+ { write_exp_elt_opcode (BINOP_NOTEQUAL); }
+ ;
+
+exp : exp LEQ exp
+ { write_exp_elt_opcode (BINOP_LEQ); }
+ ;
+
+exp : exp GEQ exp
+ { write_exp_elt_opcode (BINOP_GEQ); }
+ ;
+
+exp : exp '<' exp
+ { write_exp_elt_opcode (BINOP_LESS); }
+ ;
+
+exp : exp '>' exp
+ { write_exp_elt_opcode (BINOP_GTR); }
+ ;
+
+exp : exp LOGICAL_AND exp
+ { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
+ ;
+
+exp : exp OROR exp
+ { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
+ ;
+
+exp : exp ASSIGN exp
+ { write_exp_elt_opcode (BINOP_ASSIGN); }
+ ;
+
+
+/* Constants */
+
+exp : M2_TRUE
+ { write_exp_elt_opcode (OP_BOOL);
+ write_exp_elt_longcst ((LONGEST) $1);
+ write_exp_elt_opcode (OP_BOOL); }
+ ;
+
+exp : M2_FALSE
+ { write_exp_elt_opcode (OP_BOOL);
+ write_exp_elt_longcst ((LONGEST) $1);
+ write_exp_elt_opcode (OP_BOOL); }
+ ;
+
+exp : INT
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_m2_int);
+ write_exp_elt_longcst ((LONGEST) $1);
+ write_exp_elt_opcode (OP_LONG); }
+ ;
+
+exp : UINT
+ {
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_m2_card);
+ write_exp_elt_longcst ((LONGEST) $1);
+ write_exp_elt_opcode (OP_LONG);
+ }
+ ;
+
+exp : CHAR
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_m2_char);
+ write_exp_elt_longcst ((LONGEST) $1);
+ write_exp_elt_opcode (OP_LONG); }
+ ;
+
+
+exp : FLOAT
+ { write_exp_elt_opcode (OP_DOUBLE);
+ write_exp_elt_type (builtin_type_m2_real);
+ write_exp_elt_dblcst ($1);
+ write_exp_elt_opcode (OP_DOUBLE); }
+ ;
+
+exp : variable
+ ;
+
+exp : SIZE '(' type ')' %prec UNARY
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_int);
+ write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
+ write_exp_elt_opcode (OP_LONG); }
+ ;
+
+exp : STRING
+ { write_exp_elt_opcode (OP_M2_STRING);
+ write_exp_string ($1);
+ write_exp_elt_opcode (OP_M2_STRING); }
+ ;
+
+/* This will be used for extensions later. Like adding modules. */
+block : fblock
+ { $$ = SYMBOL_BLOCK_VALUE($1); }
+ ;
+
+fblock : BLOCKNAME
+ { struct symbol *sym
+ = lookup_symbol (copy_name ($1), expression_context_block,
+ VAR_NAMESPACE, 0, NULL);
+ $$ = sym;}
+ ;
+
+
+/* GDB scope operator */
+fblock : block COLONCOLON BLOCKNAME
+ { struct symbol *tem
+ = lookup_symbol (copy_name ($3), $1,
+ VAR_NAMESPACE, 0, NULL);
+ if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK)
+ error ("No function \"%s\" in specified context.",
+ copy_name ($3));
+ $$ = tem;
+ }
+ ;
+
+/* Useful for assigning to PROCEDURE variables */
+variable: fblock
+ { write_exp_elt_opcode(OP_VAR_VALUE);
+ write_exp_elt_block (NULL);
+ write_exp_elt_sym ($1);
+ write_exp_elt_opcode (OP_VAR_VALUE); }
+ ;
+
+/* GDB internal ($foo) variable */
+variable: INTERNAL_VAR
+ ;
+
+/* GDB scope operator */
+variable: block COLONCOLON NAME
+ { struct symbol *sym;
+ sym = lookup_symbol (copy_name ($3), $1,
+ VAR_NAMESPACE, 0, NULL);
+ if (sym == 0)
+ error ("No symbol \"%s\" in specified context.",
+ copy_name ($3));
+
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ /* block_found is set by lookup_symbol. */
+ write_exp_elt_block (block_found);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE); }
+ ;
+
+/* Base case for variables. */
+variable: NAME
+ { struct symbol *sym;
+ int is_a_field_of_this;
+
+ sym = lookup_symbol (copy_name ($1),
+ expression_context_block,
+ VAR_NAMESPACE,
+ &is_a_field_of_this,
+ NULL);
+ if (sym)
+ {
+ if (symbol_read_needs_frame (sym))
+ {
+ if (innermost_block == 0 ||
+ contained_in (block_found,
+ innermost_block))
+ innermost_block = block_found;
+ }
+
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ /* We want to use the selected frame, not
+ another more inner frame which happens to
+ be in the same block. */
+ write_exp_elt_block (NULL);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ }
+ else
+ {
+ struct minimal_symbol *msymbol;
+ register char *arg = copy_name ($1);
+
+ msymbol =
+ lookup_minimal_symbol (arg, NULL, NULL);
+ if (msymbol != NULL)
+ {
+ write_exp_msymbol
+ (msymbol,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
+ }
+ else if (!have_full_symbols () && !have_partial_symbols ())
+ error ("No symbol table is loaded. Use the \"symbol-file\" command.");
+ else
+ error ("No symbol \"%s\" in current context.",
+ copy_name ($1));
+ }
+ }
+ ;
+
+type
+ : TYPENAME
+ { $$ = lookup_typename (copy_name ($1),
+ expression_context_block, 0); }
+
+ ;
+
+%%
+
+#if 0 /* FIXME! */
+int
+overflow(a,b)
+ long a,b;
+{
+ return (MAX_OF_TYPE(builtin_type_m2_int) - b) < a;
+}
+
+int
+uoverflow(a,b)
+ unsigned long a,b;
+{
+ return (MAX_OF_TYPE(builtin_type_m2_card) - b) < a;
+}
+#endif /* FIXME */
+
+/* Take care of parsing a number (anything that starts with a digit).
+ Set yylval and return the token type; update lexptr.
+ LEN is the number of characters in it. */
+
+/*** Needs some error checking for the float case ***/
+
+static int
+parse_number (olen)
+ int olen;
+{
+ register char *p = lexptr;
+ register LONGEST n = 0;
+ register LONGEST prevn = 0;
+ register int c,i,ischar=0;
+ register int base = input_radix;
+ register int len = olen;
+ int unsigned_p = number_sign == 1 ? 1 : 0;
+
+ if(p[len-1] == 'H')
+ {
+ base = 16;
+ len--;
+ }
+ else if(p[len-1] == 'C' || p[len-1] == 'B')
+ {
+ base = 8;
+ ischar = p[len-1] == 'C';
+ len--;
+ }
+
+ /* Scan the number */
+ for (c = 0; c < len; c++)
+ {
+ if (p[c] == '.' && base == 10)
+ {
+ /* It's a float since it contains a point. */
+ yylval.dval = atof (p);
+ lexptr += len;
+ return FLOAT;
+ }
+ if (p[c] == '.' && base != 10)
+ error("Floating point numbers must be base 10.");
+ if (base == 10 && (p[c] < '0' || p[c] > '9'))
+ error("Invalid digit \'%c\' in number.",p[c]);
+ }
+
+ while (len-- > 0)
+ {
+ c = *p++;
+ n *= base;
+ if( base == 8 && (c == '8' || c == '9'))
+ error("Invalid digit \'%c\' in octal number.",c);
+ if (c >= '0' && c <= '9')
+ i = c - '0';
+ else
+ {
+ if (base == 16 && c >= 'A' && c <= 'F')
+ i = c - 'A' + 10;
+ else
+ return ERROR;
+ }
+ n+=i;
+ if(i >= base)
+ return ERROR;
+ if(!unsigned_p && number_sign == 1 && (prevn >= n))
+ unsigned_p=1; /* Try something unsigned */
+ /* Don't do the range check if n==i and i==0, since that special
+ case will give an overflow error. */
+ if(RANGE_CHECK && n!=i && i)
+ {
+ if((unsigned_p && (unsigned)prevn >= (unsigned)n) ||
+ ((!unsigned_p && number_sign==-1) && -prevn <= -n))
+ range_error("Overflow on numeric constant.");
+ }
+ prevn=n;
+ }
+
+ lexptr = p;
+ if(*p == 'B' || *p == 'C' || *p == 'H')
+ lexptr++; /* Advance past B,C or H */
+
+ if (ischar)
+ {
+ yylval.ulval = n;
+ return CHAR;
+ }
+ else if ( unsigned_p && number_sign == 1)
+ {
+ yylval.ulval = n;
+ return UINT;
+ }
+ else if((unsigned_p && (n<0))) {
+ range_error("Overflow on numeric constant -- number too large.");
+ /* But, this can return if range_check == range_warn. */
+ }
+ yylval.lval = n;
+ return INT;
+}
+
+
+/* Some tokens */
+
+static struct
+{
+ char name[2];
+ int token;
+} tokentab2[] =
+{
+ { {'<', '>'}, NOTEQUAL },
+ { {':', '='}, ASSIGN },
+ { {'<', '='}, LEQ },
+ { {'>', '='}, GEQ },
+ { {':', ':'}, COLONCOLON },
+
+};
+
+/* Some specific keywords */
+
+struct keyword {
+ char keyw[10];
+ int token;
+};
+
+static struct keyword keytab[] =
+{
+ {"OR" , OROR },
+ {"IN", IN },/* Note space after IN */
+ {"AND", LOGICAL_AND},
+ {"ABS", ABS },
+ {"CHR", CHR },
+ {"DEC", DEC },
+ {"NOT", NOT },
+ {"DIV", DIV },
+ {"INC", INC },
+ {"MAX", MAX_FUNC },
+ {"MIN", MIN_FUNC },
+ {"MOD", MOD },
+ {"ODD", ODD },
+ {"CAP", CAP },
+ {"ORD", ORD },
+ {"VAL", VAL },
+ {"EXCL", EXCL },
+ {"HIGH", HIGH },
+ {"INCL", INCL },
+ {"SIZE", SIZE },
+ {"FLOAT", FLOAT_FUNC },
+ {"TRUNC", TRUNC },
+};
+
+
+/* Read one token, getting characters through lexptr. */
+
+/* This is where we will check to make sure that the language and the operators used are
+ compatible */
+
+static int
+yylex ()
+{
+ register int c;
+ register int namelen;
+ register int i;
+ register char *tokstart;
+ register char quote;
+
+ retry:
+
+ prev_lexptr = lexptr;
+
+ tokstart = lexptr;
+
+
+ /* See if it is a special token of length 2 */
+ for( i = 0 ; i < (int) (sizeof tokentab2 / sizeof tokentab2[0]) ; i++)
+ if(STREQN(tokentab2[i].name, tokstart, 2))
+ {
+ lexptr += 2;
+ return tokentab2[i].token;
+ }
+
+ switch (c = *tokstart)
+ {
+ case 0:
+ return 0;
+
+ case ' ':
+ case '\t':
+ case '\n':
+ lexptr++;
+ goto retry;
+
+ case '(':
+ paren_depth++;
+ lexptr++;
+ return c;
+
+ case ')':
+ if (paren_depth == 0)
+ return 0;
+ paren_depth--;
+ lexptr++;
+ return c;
+
+ case ',':
+ if (comma_terminates && paren_depth == 0)
+ return 0;
+ lexptr++;
+ return c;
+
+ case '.':
+ /* Might be a floating point number. */
+ if (lexptr[1] >= '0' && lexptr[1] <= '9')
+ break; /* Falls into number code. */
+ else
+ {
+ lexptr++;
+ return DOT;
+ }
+
+/* These are character tokens that appear as-is in the YACC grammar */
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '^':
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case '=':
+ case '{':
+ case '}':
+ case '#':
+ case '@':
+ case '~':
+ case '&':
+ lexptr++;
+ return c;
+
+ case '\'' :
+ case '"':
+ quote = c;
+ for (namelen = 1; (c = tokstart[namelen]) != quote && c != '\0'; namelen++)
+ if (c == '\\')
+ {
+ c = tokstart[++namelen];
+ if (c >= '0' && c <= '9')
+ {
+ c = tokstart[++namelen];
+ if (c >= '0' && c <= '9')
+ c = tokstart[++namelen];
+ }
+ }
+ if(c != quote)
+ error("Unterminated string or character constant.");
+ yylval.sval.ptr = tokstart + 1;
+ yylval.sval.length = namelen - 1;
+ lexptr += namelen + 1;
+
+ if(namelen == 2) /* Single character */
+ {
+ yylval.ulval = tokstart[1];
+ return CHAR;
+ }
+ else
+ return STRING;
+ }
+
+ /* Is it a number? */
+ /* Note: We have already dealt with the case of the token '.'.
+ See case '.' above. */
+ if ((c >= '0' && c <= '9'))
+ {
+ /* It's a number. */
+ int got_dot = 0, got_e = 0;
+ register char *p = tokstart;
+ int toktype;
+
+ for (++p ;; ++p)
+ {
+ if (!got_e && (*p == 'e' || *p == 'E'))
+ got_dot = got_e = 1;
+ else if (!got_dot && *p == '.')
+ got_dot = 1;
+ else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
+ && (*p == '-' || *p == '+'))
+ /* This is the sign of the exponent, not the end of the
+ number. */
+ continue;
+ else if ((*p < '0' || *p > '9') &&
+ (*p < 'A' || *p > 'F') &&
+ (*p != 'H')) /* Modula-2 hexadecimal number */
+ break;
+ }
+ toktype = parse_number (p - tokstart);
+ if (toktype == ERROR)
+ {
+ char *err_copy = (char *) alloca (p - tokstart + 1);
+
+ memcpy (err_copy, tokstart, p - tokstart);
+ err_copy[p - tokstart] = 0;
+ error ("Invalid number \"%s\".", err_copy);
+ }
+ lexptr = p;
+ return toktype;
+ }
+
+ if (!(c == '_' || c == '$'
+ || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
+ /* We must have come across a bad character (e.g. ';'). */
+ error ("Invalid character '%c' in expression.", c);
+
+ /* It's a name. See how long it is. */
+ namelen = 0;
+ for (c = tokstart[namelen];
+ (c == '_' || c == '$' || (c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
+ c = tokstart[++namelen])
+ ;
+
+ /* The token "if" terminates the expression and is NOT
+ removed from the input stream. */
+ if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
+ {
+ return 0;
+ }
+
+ lexptr += namelen;
+
+ /* Lookup special keywords */
+ for(i = 0 ; i < (int) (sizeof(keytab) / sizeof(keytab[0])) ; i++)
+ if(namelen == strlen(keytab[i].keyw) && STREQN(tokstart,keytab[i].keyw,namelen))
+ return keytab[i].token;
+
+ yylval.sval.ptr = tokstart;
+ yylval.sval.length = namelen;
+
+ if (*tokstart == '$')
+ {
+ write_dollar_variable (yylval.sval);
+ return INTERNAL_VAR;
+ }
+
+ /* Use token-type BLOCKNAME for symbols that happen to be defined as
+ functions. If this is not so, then ...
+ Use token-type TYPENAME for symbols that happen to be defined
+ currently as names of types; NAME for other symbols.
+ The caller is not constrained to care about the distinction. */
+ {
+
+
+ char *tmp = copy_name (yylval.sval);
+ struct symbol *sym;
+
+ if (lookup_partial_symtab (tmp))
+ return BLOCKNAME;
+ sym = lookup_symbol (tmp, expression_context_block,
+ VAR_NAMESPACE, 0, NULL);
+ if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
+ return BLOCKNAME;
+ if (lookup_typename (copy_name (yylval.sval), expression_context_block, 1))
+ return TYPENAME;
+
+ if(sym)
+ {
+ switch(sym->aclass)
+ {
+ case LOC_STATIC:
+ case LOC_REGISTER:
+ case LOC_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_LOCAL:
+ case LOC_LOCAL_ARG:
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
+ case LOC_CONST:
+ case LOC_CONST_BYTES:
+ case LOC_OPTIMIZED_OUT:
+ return NAME;
+
+ case LOC_TYPEDEF:
+ return TYPENAME;
+
+ case LOC_BLOCK:
+ return BLOCKNAME;
+
+ case LOC_UNDEF:
+ error("internal: Undefined class in m2lex()");
+
+ case LOC_LABEL:
+ case LOC_UNRESOLVED:
+ error("internal: Unforseen case in m2lex()");
+
+ default:
+ error ("unhandled token in m2lex()");
+ break;
+ }
+ }
+ else
+ {
+ /* Built-in BOOLEAN type. This is sort of a hack. */
+ if(STREQN(tokstart,"TRUE",4))
+ {
+ yylval.ulval = 1;
+ return M2_TRUE;
+ }
+ else if(STREQN(tokstart,"FALSE",5))
+ {
+ yylval.ulval = 0;
+ return M2_FALSE;
+ }
+ }
+
+ /* Must be another type of name... */
+ return NAME;
+ }
+}
+
+#if 0 /* Unused */
+static char *
+make_qualname(mod,ident)
+ char *mod, *ident;
+{
+ char *new = malloc(strlen(mod)+strlen(ident)+2);
+
+ strcpy(new,mod);
+ strcat(new,".");
+ strcat(new,ident);
+ return new;
+}
+#endif /* 0 */
+
+void
+yyerror (msg)
+ char *msg;
+{
+ if (prev_lexptr)
+ lexptr = prev_lexptr;
+
+ error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
+}
diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
new file mode 100644
index 00000000000..116d85009fd
--- /dev/null
+++ b/gdb/m2-lang.c
@@ -0,0 +1,468 @@
+/* Modula 2 language support routines for GDB, the GNU debugger.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2002
+ 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "m2-lang.h"
+#include "c-lang.h"
+#include "valprint.h"
+
+extern void _initialize_m2_language (void);
+static struct type *m2_create_fundamental_type (struct objfile *, int);
+static void m2_printstr (struct ui_file * stream, char *string,
+ unsigned int length, int width,
+ int force_ellipses);
+static void m2_printchar (int, struct ui_file *);
+static void m2_emit_char (int, struct ui_file *, int);
+
+/* Print the character C on STREAM as part of the contents of a literal
+ string whose delimiter is QUOTER. Note that that format for printing
+ characters and strings is language specific.
+ FIXME: This is a copy of the same function from c-exp.y. It should
+ be replaced with a true Modula version.
+ */
+
+static void
+m2_emit_char (register int c, struct ui_file *stream, int quoter)
+{
+
+ c &= 0xFF; /* Avoid sign bit follies */
+
+ if (PRINT_LITERAL_FORM (c))
+ {
+ if (c == '\\' || c == quoter)
+ {
+ fputs_filtered ("\\", stream);
+ }
+ fprintf_filtered (stream, "%c", c);
+ }
+ else
+ {
+ switch (c)
+ {
+ case '\n':
+ fputs_filtered ("\\n", stream);
+ break;
+ case '\b':
+ fputs_filtered ("\\b", stream);
+ break;
+ case '\t':
+ fputs_filtered ("\\t", stream);
+ break;
+ case '\f':
+ fputs_filtered ("\\f", stream);
+ break;
+ case '\r':
+ fputs_filtered ("\\r", stream);
+ break;
+ case '\033':
+ fputs_filtered ("\\e", stream);
+ break;
+ case '\007':
+ fputs_filtered ("\\a", stream);
+ break;
+ default:
+ fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
+ break;
+ }
+ }
+}
+
+/* FIXME: This is a copy of the same function from c-exp.y. It should
+ be replaced with a true Modula version. */
+
+static void
+m2_printchar (int c, struct ui_file *stream)
+{
+ fputs_filtered ("'", stream);
+ LA_EMIT_CHAR (c, stream, '\'');
+ fputs_filtered ("'", stream);
+}
+
+/* Print the character string STRING, printing at most LENGTH characters.
+ Printing stops early if the number hits print_max; repeat counts
+ are printed as appropriate. Print ellipses at the end if we
+ had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.
+ FIXME: This is a copy of the same function from c-exp.y. It should
+ be replaced with a true Modula version. */
+
+static void
+m2_printstr (struct ui_file *stream, char *string, unsigned int length,
+ int width, int force_ellipses)
+{
+ register unsigned int i;
+ unsigned int things_printed = 0;
+ int in_quotes = 0;
+ int need_comma = 0;
+ extern int inspect_it;
+
+ if (length == 0)
+ {
+ fputs_filtered ("\"\"", gdb_stdout);
+ return;
+ }
+
+ for (i = 0; i < length && things_printed < print_max; ++i)
+ {
+ /* Position of the character we are examining
+ to see whether it is repeated. */
+ unsigned int rep1;
+ /* Number of repetitions we have detected so far. */
+ unsigned int reps;
+
+ QUIT;
+
+ if (need_comma)
+ {
+ fputs_filtered (", ", stream);
+ need_comma = 0;
+ }
+
+ rep1 = i + 1;
+ reps = 1;
+ while (rep1 < length && string[rep1] == string[i])
+ {
+ ++rep1;
+ ++reps;
+ }
+
+ if (reps > repeat_count_threshold)
+ {
+ if (in_quotes)
+ {
+ if (inspect_it)
+ fputs_filtered ("\\\", ", stream);
+ else
+ fputs_filtered ("\", ", stream);
+ in_quotes = 0;
+ }
+ m2_printchar (string[i], stream);
+ fprintf_filtered (stream, " <repeats %u times>", reps);
+ i = rep1 - 1;
+ things_printed += repeat_count_threshold;
+ need_comma = 1;
+ }
+ else
+ {
+ if (!in_quotes)
+ {
+ if (inspect_it)
+ fputs_filtered ("\\\"", stream);
+ else
+ fputs_filtered ("\"", stream);
+ in_quotes = 1;
+ }
+ LA_EMIT_CHAR (string[i], stream, '"');
+ ++things_printed;
+ }
+ }
+
+ /* Terminate the quotes if necessary. */
+ if (in_quotes)
+ {
+ if (inspect_it)
+ fputs_filtered ("\\\"", stream);
+ else
+ fputs_filtered ("\"", stream);
+ }
+
+ if (force_ellipses || i < length)
+ fputs_filtered ("...", stream);
+}
+
+/* FIXME: This is a copy of c_create_fundamental_type(), before
+ all the non-C types were stripped from it. Needs to be fixed
+ by an experienced Modula programmer. */
+
+static struct type *
+m2_create_fundamental_type (struct objfile *objfile, int typeid)
+{
+ register struct type *type = NULL;
+
+ switch (typeid)
+ {
+ default:
+ /* FIXME: For now, if we are asked to produce a type not in this
+ language, create the equivalent of a C integer type with the
+ name "<?type?>". When all the dust settles from the type
+ reconstruction work, this should probably become an error. */
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "<?type?>", objfile);
+ warning ("internal error: no Modula fundamental type %d", typeid);
+ break;
+ case FT_VOID:
+ type = init_type (TYPE_CODE_VOID,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "void", objfile);
+ break;
+ case FT_BOOLEAN:
+ type = init_type (TYPE_CODE_BOOL,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "boolean", objfile);
+ break;
+ case FT_STRING:
+ type = init_type (TYPE_CODE_STRING,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "string", objfile);
+ break;
+ case FT_CHAR:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "char", objfile);
+ break;
+ case FT_SIGNED_CHAR:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "signed char", objfile);
+ break;
+ case FT_UNSIGNED_CHAR:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned char", objfile);
+ break;
+ case FT_SHORT:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ 0, "short", objfile);
+ break;
+ case FT_SIGNED_SHORT:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ 0, "short", objfile); /* FIXME-fnf */
+ break;
+ case FT_UNSIGNED_SHORT:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned short", objfile);
+ break;
+ case FT_INTEGER:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "int", objfile);
+ break;
+ case FT_SIGNED_INTEGER:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "int", objfile); /* FIXME -fnf */
+ break;
+ case FT_UNSIGNED_INTEGER:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned int", objfile);
+ break;
+ case FT_FIXED_DECIMAL:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "fixed decimal", objfile);
+ break;
+ case FT_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "long", objfile);
+ break;
+ case FT_SIGNED_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "long", objfile); /* FIXME -fnf */
+ break;
+ case FT_UNSIGNED_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned long", objfile);
+ break;
+ case FT_LONG_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "long long", objfile);
+ break;
+ case FT_SIGNED_LONG_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "signed long long", objfile);
+ break;
+ case FT_UNSIGNED_LONG_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned long long", objfile);
+ break;
+ case FT_FLOAT:
+ type = init_type (TYPE_CODE_FLT,
+ TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0, "float", objfile);
+ break;
+ case FT_DBL_PREC_FLOAT:
+ type = init_type (TYPE_CODE_FLT,
+ TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "double", objfile);
+ break;
+ case FT_FLOAT_DECIMAL:
+ type = init_type (TYPE_CODE_FLT,
+ TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "floating decimal", objfile);
+ break;
+ case FT_EXT_PREC_FLOAT:
+ type = init_type (TYPE_CODE_FLT,
+ TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "long double", objfile);
+ break;
+ case FT_COMPLEX:
+ type = init_type (TYPE_CODE_COMPLEX,
+ 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0, "complex", objfile);
+ TYPE_TARGET_TYPE (type)
+ = m2_create_fundamental_type (objfile, FT_FLOAT);
+ break;
+ case FT_DBL_PREC_COMPLEX:
+ type = init_type (TYPE_CODE_COMPLEX,
+ 2 * TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "double complex", objfile);
+ TYPE_TARGET_TYPE (type)
+ = m2_create_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+ break;
+ case FT_EXT_PREC_COMPLEX:
+ type = init_type (TYPE_CODE_COMPLEX,
+ 2 * TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "long double complex", objfile);
+ TYPE_TARGET_TYPE (type)
+ = m2_create_fundamental_type (objfile, FT_EXT_PREC_FLOAT);
+ break;
+ }
+ return (type);
+}
+
+
+/* Table of operators and their precedences for printing expressions. */
+
+static const struct op_print m2_op_print_tab[] =
+{
+ {"+", BINOP_ADD, PREC_ADD, 0},
+ {"+", UNOP_PLUS, PREC_PREFIX, 0},
+ {"-", BINOP_SUB, PREC_ADD, 0},
+ {"-", UNOP_NEG, PREC_PREFIX, 0},
+ {"*", BINOP_MUL, PREC_MUL, 0},
+ {"/", BINOP_DIV, PREC_MUL, 0},
+ {"DIV", BINOP_INTDIV, PREC_MUL, 0},
+ {"MOD", BINOP_REM, PREC_MUL, 0},
+ {":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
+ {"OR", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
+ {"AND", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
+ {"NOT", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
+ {"=", BINOP_EQUAL, PREC_EQUAL, 0},
+ {"<>", BINOP_NOTEQUAL, PREC_EQUAL, 0},
+ {"<=", BINOP_LEQ, PREC_ORDER, 0},
+ {">=", BINOP_GEQ, PREC_ORDER, 0},
+ {">", BINOP_GTR, PREC_ORDER, 0},
+ {"<", BINOP_LESS, PREC_ORDER, 0},
+ {"^", UNOP_IND, PREC_PREFIX, 0},
+ {"@", BINOP_REPEAT, PREC_REPEAT, 0},
+ {"CAP", UNOP_CAP, PREC_BUILTIN_FUNCTION, 0},
+ {"CHR", UNOP_CHR, PREC_BUILTIN_FUNCTION, 0},
+ {"ORD", UNOP_ORD, PREC_BUILTIN_FUNCTION, 0},
+ {"FLOAT", UNOP_FLOAT, PREC_BUILTIN_FUNCTION, 0},
+ {"HIGH", UNOP_HIGH, PREC_BUILTIN_FUNCTION, 0},
+ {"MAX", UNOP_MAX, PREC_BUILTIN_FUNCTION, 0},
+ {"MIN", UNOP_MIN, PREC_BUILTIN_FUNCTION, 0},
+ {"ODD", UNOP_ODD, PREC_BUILTIN_FUNCTION, 0},
+ {"TRUNC", UNOP_TRUNC, PREC_BUILTIN_FUNCTION, 0},
+ {NULL, 0, 0, 0}
+};
+
+/* The built-in types of Modula-2. */
+
+struct type *builtin_type_m2_char;
+struct type *builtin_type_m2_int;
+struct type *builtin_type_m2_card;
+struct type *builtin_type_m2_real;
+struct type *builtin_type_m2_bool;
+
+struct type **const (m2_builtin_types[]) =
+{
+ &builtin_type_m2_char,
+ &builtin_type_m2_int,
+ &builtin_type_m2_card,
+ &builtin_type_m2_real,
+ &builtin_type_m2_bool,
+ 0
+};
+
+const struct language_defn m2_language_defn =
+{
+ "modula-2",
+ language_m2,
+ m2_builtin_types,
+ range_check_on,
+ type_check_on,
+ case_sensitive_on,
+ m2_parse, /* parser */
+ m2_error, /* parser error function */
+ evaluate_subexp_standard,
+ m2_printchar, /* Print character constant */
+ m2_printstr, /* function to print string constant */
+ m2_emit_char, /* Function to print a single character */
+ m2_create_fundamental_type, /* Create fundamental type in this language */
+ m2_print_type, /* Print a type using appropriate syntax */
+ m2_val_print, /* Print a value using appropriate syntax */
+ c_value_print, /* Print a top-level value */
+ {"", "", "", ""}, /* Binary format info */
+ {"%loB", "", "o", "B"}, /* Octal format info */
+ {"%ld", "", "d", ""}, /* Decimal format info */
+ {"0%lXH", "0", "X", "H"}, /* Hex format info */
+ m2_op_print_tab, /* expression operators for printing */
+ 0, /* arrays are first-class (not c-style) */
+ 0, /* String lower bound */
+ &builtin_type_m2_char, /* Type of string elements */
+ LANG_MAGIC
+};
+
+/* Initialization for Modula-2 */
+
+void
+_initialize_m2_language (void)
+{
+ /* Modula-2 "pervasive" types. NOTE: these can be redefined!!! */
+ builtin_type_m2_int =
+ init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0,
+ "INTEGER", (struct objfile *) NULL);
+ builtin_type_m2_card =
+ init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "CARDINAL", (struct objfile *) NULL);
+ builtin_type_m2_real =
+ init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0,
+ "REAL", (struct objfile *) NULL);
+ builtin_type_m2_char =
+ init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "CHAR", (struct objfile *) NULL);
+ builtin_type_m2_bool =
+ init_type (TYPE_CODE_BOOL, TARGET_INT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED,
+ "BOOLEAN", (struct objfile *) NULL);
+
+ add_language (&m2_language_defn);
+}
diff --git a/gdb/m2-lang.h b/gdb/m2-lang.h
new file mode 100644
index 00000000000..a31c5ae3084
--- /dev/null
+++ b/gdb/m2-lang.h
@@ -0,0 +1,31 @@
+/* Modula 2 language support definitions for GDB, the GNU debugger.
+ Copyright 1992, 1998, 2000 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. */
+
+extern int m2_parse (void); /* Defined in m2-exp.y */
+
+extern void m2_error (char *); /* Defined in m2-exp.y */
+
+/* Defined in m2-typeprint.c */
+extern void m2_print_type (struct type *, char *, struct ui_file *, int,
+ int);
+
+extern int m2_val_print (struct type *, char *, int, CORE_ADDR,
+ struct ui_file *, int, int, int,
+ enum val_prettyprint);
diff --git a/gdb/m2-typeprint.c b/gdb/m2-typeprint.c
new file mode 100644
index 00000000000..90aefae66e7
--- /dev/null
+++ b/gdb/m2-typeprint.c
@@ -0,0 +1,41 @@
+/* Support for printing Modula 2 types for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1991, 1992, 1995, 2000
+ 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 "defs.h"
+#include "bfd.h" /* Binary File Description */
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "m2-lang.h"
+#include <errno.h>
+
+void
+m2_print_type (struct type *type, char *varstring, struct ui_file *stream,
+ int show, int level)
+{
+ extern void c_print_type (struct type *, char *, struct ui_file *, int,
+ int);
+
+ c_print_type (type, varstring, stream, show, level); /* FIXME */
+}
diff --git a/gdb/m2-valprint.c b/gdb/m2-valprint.c
new file mode 100644
index 00000000000..ec80301da8b
--- /dev/null
+++ b/gdb/m2-valprint.c
@@ -0,0 +1,39 @@
+/* Support for printing Modula 2 values for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1991, 1992, 1996, 1998, 2000
+ 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "m2-lang.h"
+
+/* FIXME: For now, just explicitly declare c_val_print and use it instead */
+
+int
+m2_val_print (struct type *type, char *valaddr, int embedded_offset,
+ CORE_ADDR address, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
+{
+ extern int c_val_print (struct type *, char *, int, CORE_ADDR,
+ struct ui_file *, int, int, int,
+ enum val_prettyprint);
+ return (c_val_print (type, valaddr, 0, address, stream, format, deref_ref,
+ recurse, pretty));
+}
diff --git a/gdb/m3-nat.c b/gdb/m3-nat.c
new file mode 100644
index 00000000000..c29101b9c36
--- /dev/null
+++ b/gdb/m3-nat.c
@@ -0,0 +1,4565 @@
+/* Interface GDB to Mach 3.0 operating systems.
+ (Most) Mach 3.0 related routines live in this file.
+
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+ 2002 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. */
+
+/*
+ * Author: Jukka Virtanen <jtv@hut.fi>
+ * Computing Centre
+ * Helsinki University of Technology
+ * Finland
+ *
+ * Thanks to my friends who helped with ideas and testing:
+ *
+ * Johannes Helander, Antti Louko, Tero Mononen,
+ * jvh@cs.hut.fi alo@hut.fi tmo@cs.hut.fi
+ *
+ * Tero Kivinen and Eamonn McManus
+ * kivinen@cs.hut.fi emcmanus@gr.osf.org
+ *
+ */
+
+#include <stdio.h>
+
+#include <mach.h>
+#include <servers/netname.h>
+#include <servers/machid.h>
+#include <mach/message.h>
+#include <mach/notify.h>
+#include <mach_error.h>
+#include <mach/exception.h>
+#include <mach/vm_attributes.h>
+
+#include "defs.h"
+#include "inferior.h"
+#include "symtab.h"
+#include "value.h"
+#include "language.h"
+#include "target.h"
+#include "gdb_wait.h"
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#if 0
+#include <servers/machid_lib.h>
+#else
+#define MACH_TYPE_TASK 1
+#define MACH_TYPE_THREAD 2
+#endif
+
+/* Included only for signal names and NSIG
+
+ * note: There are many problems in signal handling with
+ * gdb in Mach 3.0 in general.
+ */
+#include <signal.h>
+#define SIG_UNKNOWN 0 /* Exception that has no matching unix signal */
+
+#include <cthreads.h>
+
+/* This is what a cproc looks like. This is here partly because
+ cthread_internals.h is not a header we can just #include, partly with
+ an eye towards perhaps getting this to work with cross-debugging
+ someday. Best solution is if CMU publishes a real interface to this
+ stuff. */
+#define CPROC_NEXT_OFFSET 0
+#define CPROC_NEXT_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT)
+#define CPROC_INCARNATION_OFFSET (CPROC_NEXT_OFFSET + CPROC_NEXT_SIZE)
+#define CPROC_INCARNATION_SIZE (sizeof (cthread_t))
+#define CPROC_LIST_OFFSET (CPROC_INCARNATION_OFFSET + CPROC_INCARNATION_SIZE)
+#define CPROC_LIST_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT)
+#define CPROC_WAIT_OFFSET (CPROC_LIST_OFFSET + CPROC_LIST_SIZE)
+#define CPROC_WAIT_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT)
+#define CPROC_REPLY_OFFSET (CPROC_WAIT_OFFSET + CPROC_WAIT_SIZE)
+#define CPROC_REPLY_SIZE (sizeof (mach_port_t))
+#define CPROC_CONTEXT_OFFSET (CPROC_REPLY_OFFSET + CPROC_REPLY_SIZE)
+#define CPROC_CONTEXT_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT)
+#define CPROC_LOCK_OFFSET (CPROC_CONTEXT_OFFSET + CPROC_CONTEXT_SIZE)
+#define CPROC_LOCK_SIZE (sizeof (spin_lock_t))
+#define CPROC_STATE_OFFSET (CPROC_LOCK_OFFSET + CPROC_LOCK_SIZE)
+#define CPROC_STATE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT)
+#define CPROC_WIRED_OFFSET (CPROC_STATE_OFFSET + CPROC_STATE_SIZE)
+#define CPROC_WIRED_SIZE (sizeof (mach_port_t))
+#define CPROC_BUSY_OFFSET (CPROC_WIRED_OFFSET + CPROC_WIRED_SIZE)
+#define CPROC_BUSY_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT)
+#define CPROC_MSG_OFFSET (CPROC_BUSY_OFFSET + CPROC_BUSY_SIZE)
+#define CPROC_MSG_SIZE (sizeof (mach_msg_header_t))
+#define CPROC_BASE_OFFSET (CPROC_MSG_OFFSET + CPROC_MSG_SIZE)
+#define CPROC_BASE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT)
+#define CPROC_SIZE_OFFSET (CPROC_BASE_OFFSET + CPROC_BASE_SIZE)
+#define CPROC_SIZE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT)
+#define CPROC_SIZE (CPROC_SIZE_OFFSET + CPROC_SIZE_SIZE)
+
+/* Values for the state field in the cproc. */
+#define CPROC_RUNNING 0
+#define CPROC_SWITCHING 1
+#define CPROC_BLOCKED 2
+#define CPROC_CONDWAIT 4
+
+/* For cproc and kernel thread mapping */
+typedef struct gdb_thread
+ {
+ mach_port_t name;
+ CORE_ADDR sp;
+ CORE_ADDR pc;
+ CORE_ADDR fp;
+ boolean_t in_emulator;
+ int slotid;
+
+ /* This is for the mthreads list. It points to the cproc list.
+ Perhaps the two lists should be merged (or perhaps it was a mistake
+ to make them both use a struct gdb_thread). */
+ struct gdb_thread *cproc;
+
+ /* These are for the cproc list, which is linked through the next field
+ of the struct gdb_thread. */
+ char raw_cproc[CPROC_SIZE];
+ /* The cthread which is pointed to by the incarnation field from the
+ cproc. This points to the copy we've read into GDB. */
+ cthread_t cthread;
+ /* Point back to the mthreads list. */
+ int reverse_map;
+ struct gdb_thread *next;
+ }
+ *gdb_thread_t;
+
+/*
+ * Actions for Mach exceptions.
+ *
+ * sigmap field maps the exception to corresponding Unix signal.
+ *
+ * I do not know how to map the exception to unix signal
+ * if SIG_UNKNOWN is specified.
+ */
+
+struct exception_list
+ {
+ char *name;
+ boolean_t forward;
+ boolean_t print;
+ int sigmap;
+ }
+exception_map[] =
+{
+ {
+ "not_mach3_exception", FALSE, TRUE, SIG_UNKNOWN
+ }
+ ,
+ {
+ "EXC_BAD_ACCESS", FALSE, TRUE, SIGSEGV
+ }
+ ,
+ {
+ "EXC_BAD_INSTRUCTION", FALSE, TRUE, SIGILL
+ }
+ ,
+ {
+ "EXC_ARITHMETIC", FALSE, TRUE, SIGFPE
+ }
+ ,
+ {
+ "EXC_EMULATION", FALSE, TRUE, SIGEMT
+ }
+ , /* ??? */
+ {
+ "EXC_SOFTWARE", FALSE, TRUE, SIG_UNKNOWN
+ }
+ ,
+ {
+ "EXC_BREAKPOINT", FALSE, FALSE, SIGTRAP
+ }
+};
+
+/* Mach exception table size */
+int max_exception = sizeof (exception_map) / sizeof (struct exception_list) - 1;
+
+#define MAX_EXCEPTION max_exception
+
+WAITTYPE wait_status;
+
+/* If you define this, intercepted bsd server calls will be
+ * dumped while waiting the inferior to EXEC the correct
+ * program
+ */
+/* #define DUMP_SYSCALL /* debugging interceptor */
+
+/* xx_debug() outputs messages if this is nonzero.
+ * If > 1, DUMP_SYSCALL will dump message contents.
+ */
+int debug_level = 0;
+
+/* "Temporary" debug stuff */
+void
+xx_debug (char *fmt, int a, int b, int c)
+{
+ if (debug_level)
+ warning (fmt, a, b, c);
+}
+
+/* This is in libmach.a */
+extern mach_port_t name_server_port;
+
+/* Set in catch_exception_raise */
+int stop_exception, stop_code, stop_subcode;
+int stopped_in_exception;
+
+/* Thread that was the active thread when we stopped */
+thread_t stop_thread = MACH_PORT_NULL;
+
+char *hostname = "";
+
+/* Set when task is attached or created */
+boolean_t emulator_present = FALSE;
+
+task_t inferior_task;
+thread_t current_thread;
+
+/* Exception ports for inferior task */
+mach_port_t inferior_exception_port = MACH_PORT_NULL;
+mach_port_t inferior_old_exception_port = MACH_PORT_NULL;
+
+/* task exceptions and notifications */
+mach_port_t inferior_wait_port_set = MACH_PORT_NULL;
+mach_port_t our_notify_port = MACH_PORT_NULL;
+
+/* This is "inferior_wait_port_set" when not single stepping, and
+ * "singlestepped_thread_port" when we are single stepping.
+ *
+ * This is protected by a cleanup function: discard_single_step()
+ */
+mach_port_t currently_waiting_for = MACH_PORT_NULL;
+
+/* A port for external messages to gdb.
+ * External in the meaning that they do not come
+ * from the inferior_task, but rather from external
+ * tasks.
+ *
+ * As a debugging feature:
+ * A debugger debugging another debugger can stop the
+ * inferior debugger by the following command sequence
+ * (without running external programs)
+ *
+ * (top-gdb) set stop_inferior_gdb ()
+ * (top-gdb) continue
+ */
+mach_port_t our_message_port = MACH_PORT_NULL;
+
+/* For single stepping */
+mach_port_t thread_exception_port = MACH_PORT_NULL;
+mach_port_t thread_saved_exception_port = MACH_PORT_NULL;
+mach_port_t singlestepped_thread_port = MACH_PORT_NULL;
+
+/* For machid calls */
+mach_port_t mid_server = MACH_PORT_NULL;
+mach_port_t mid_auth = MACH_PORT_NULL;
+
+/* If gdb thinks the inferior task is not suspended, it
+ * must take suspend/abort the threads when it reads the state.
+ */
+int must_suspend_thread = 0;
+
+/* When single stepping, we switch the port that mach_really_wait() listens to.
+ * This cleanup is a guard to prevent the port set from being left to
+ * the singlestepped_thread_port when error() is called.
+ * This is nonzero only when we are single stepping.
+ */
+#define NULL_CLEANUP (struct cleanup *)0
+struct cleanup *cleanup_step = NULL_CLEANUP;
+
+
+static struct target_ops m3_ops;
+
+static void m3_kill_inferior ();
+
+#if 0
+#define MACH_TYPE_EXCEPTION_PORT -1
+#endif
+
+/* Chain of ports to remember requested notifications. */
+
+struct port_chain
+ {
+ struct port_chain *next;
+ mach_port_t port;
+ int type;
+ int mid; /* Now only valid with MACH_TYPE_THREAD and */
+ /* MACH_TYPE_THREAD */
+ };
+typedef struct port_chain *port_chain_t;
+
+/* Room for chain nodes comes from pchain_obstack */
+struct obstack pchain_obstack;
+struct obstack *port_chain_obstack = &pchain_obstack;
+
+/* For thread handling */
+struct obstack Cproc_obstack;
+struct obstack *cproc_obstack = &Cproc_obstack;
+
+/* the list of notified ports */
+port_chain_t notify_chain = (port_chain_t) NULL;
+
+port_chain_t
+port_chain_insert (port_chain_t list, mach_port_t name, int type)
+{
+ kern_return_t ret;
+ port_chain_t new;
+ int mid;
+
+ if (!MACH_PORT_VALID (name))
+ return list;
+
+ if (type == MACH_TYPE_TASK || type == MACH_TYPE_THREAD)
+ {
+ if (!MACH_PORT_VALID (mid_server))
+ {
+ warning ("Machid server port invalid, can not map port 0x%x to MID",
+ name);
+ mid = name;
+ }
+ else
+ {
+ ret = machid_mach_register (mid_server, mid_auth, name, type, &mid);
+
+ if (ret != KERN_SUCCESS)
+ {
+ warning ("Can not map name (0x%x) to MID with machid", name);
+ mid = name;
+ }
+ }
+ }
+ else
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+ new = (port_chain_t) obstack_alloc (port_chain_obstack,
+ sizeof (struct port_chain));
+ new->next = list;
+ new->port = name;
+ new->type = type;
+ new->mid = mid;
+
+ return new;
+}
+
+port_chain_t
+port_chain_delete (port_chain_t list, mach_port_t elem)
+{
+ if (list)
+ if (list->port == elem)
+ list = list->next;
+ else
+ while (list->next)
+ {
+ if (list->next->port == elem)
+ list->next = list->next->next; /* GCd with obstack_free() */
+ else
+ list = list->next;
+ }
+ return list;
+}
+
+void
+port_chain_destroy (struct obstack *ostack)
+{
+ obstack_free (ostack, 0);
+ obstack_init (ostack);
+}
+
+port_chain_t
+port_chain_member (port_chain_t list, mach_port_t elem)
+{
+ while (list)
+ {
+ if (list->port == elem)
+ return list;
+ list = list->next;
+ }
+ return (port_chain_t) NULL;
+}
+
+int
+map_port_name_to_mid (mach_port_t name, int type)
+{
+ port_chain_t elem;
+
+ if (!MACH_PORT_VALID (name))
+ return -1;
+
+ elem = port_chain_member (notify_chain, name);
+
+ if (elem && (elem->type == type))
+ return elem->mid;
+
+ if (elem)
+ return -1;
+
+ if (!MACH_PORT_VALID (mid_server))
+ {
+ warning ("Machid server port invalid, can not map port 0x%x to mid",
+ name);
+ return -1;
+ }
+ else
+ {
+ int mid;
+ kern_return_t ret;
+
+ ret = machid_mach_register (mid_server, mid_auth, name, type, &mid);
+
+ if (ret != KERN_SUCCESS)
+ {
+ warning ("Can not map name (0x%x) to mid with machid", name);
+ return -1;
+ }
+ return mid;
+ }
+}
+
+/* Guard for currently_waiting_for and singlestepped_thread_port */
+static void
+discard_single_step (thread_t thread)
+{
+ currently_waiting_for = inferior_wait_port_set;
+
+ cleanup_step = NULL_CLEANUP;
+ if (MACH_PORT_VALID (thread) && MACH_PORT_VALID (singlestepped_thread_port))
+ setup_single_step (thread, FALSE);
+}
+
+setup_single_step (thread_t thread, boolean_t start_step)
+{
+ kern_return_t ret;
+
+ if (!MACH_PORT_VALID (thread))
+ error ("Invalid thread supplied to setup_single_step");
+ else
+ {
+ mach_port_t teport;
+
+ /* Get the current thread exception port */
+ ret = thread_get_exception_port (thread, &teport);
+ CHK ("Getting thread's exception port", ret);
+
+ if (start_step)
+ {
+ if (MACH_PORT_VALID (singlestepped_thread_port))
+ {
+ warning ("Singlestepped_thread_port (0x%x) is still valid?",
+ singlestepped_thread_port);
+ singlestepped_thread_port = MACH_PORT_NULL;
+ }
+
+ /* If we are already stepping this thread */
+ if (MACH_PORT_VALID (teport) && teport == thread_exception_port)
+ {
+ ret = mach_port_deallocate (mach_task_self (), teport);
+ CHK ("Could not deallocate thread exception port", ret);
+ }
+ else
+ {
+ ret = thread_set_exception_port (thread, thread_exception_port);
+ CHK ("Setting exception port for thread", ret);
+#if 0
+ /* Insert thread exception port to wait port set */
+ ret = mach_port_move_member (mach_task_self (),
+ thread_exception_port,
+ inferior_wait_port_set);
+ CHK ("Moving thread exception port to inferior_wait_port_set",
+ ret);
+#endif
+ thread_saved_exception_port = teport;
+ }
+
+ thread_trace (thread, TRUE);
+
+ singlestepped_thread_port = thread_exception_port;
+ currently_waiting_for = singlestepped_thread_port;
+ cleanup_step = make_cleanup (discard_single_step, thread);
+ }
+ else
+ {
+ if (!MACH_PORT_VALID (teport))
+ error ("Single stepped thread had an invalid exception port?");
+
+ if (teport != thread_exception_port)
+ error ("Single stepped thread had an unknown exception port?");
+
+ ret = mach_port_deallocate (mach_task_self (), teport);
+ CHK ("Couldn't deallocate thread exception port", ret);
+#if 0
+ /* Remove thread exception port from wait port set */
+ ret = mach_port_move_member (mach_task_self (),
+ thread_exception_port,
+ MACH_PORT_NULL);
+ CHK ("Removing thread exception port from inferior_wait_port_set",
+ ret);
+#endif
+ /* Restore thread's old exception port */
+ ret = thread_set_exception_port (thread,
+ thread_saved_exception_port);
+ CHK ("Restoring stepped thread's exception port", ret);
+
+ if (MACH_PORT_VALID (thread_saved_exception_port))
+ (void) mach_port_deallocate (mach_task_self (),
+ thread_saved_exception_port);
+
+ thread_trace (thread, FALSE);
+
+ singlestepped_thread_port = MACH_PORT_NULL;
+ currently_waiting_for = inferior_wait_port_set;
+ if (cleanup_step)
+ discard_cleanups (cleanup_step);
+ }
+ }
+}
+
+static
+request_notify (mach_port_t name, mach_msg_id_t variant, int type)
+{
+ kern_return_t ret;
+ mach_port_t previous_port_dummy = MACH_PORT_NULL;
+
+ if (!MACH_PORT_VALID (name))
+ return;
+
+ if (port_chain_member (notify_chain, name))
+ return;
+
+ ret = mach_port_request_notification (mach_task_self (),
+ name,
+ variant,
+ 1,
+ our_notify_port,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE,
+ &previous_port_dummy);
+ CHK ("Serious: request_notify failed", ret);
+
+ (void) mach_port_deallocate (mach_task_self (),
+ previous_port_dummy);
+
+ notify_chain = port_chain_insert (notify_chain, name, type);
+}
+
+reverse_msg_bits (mach_msg_header_t *msgp, int type)
+{
+ int rbits, lbits;
+ rbits = MACH_MSGH_BITS_REMOTE (msgp->msgh_bits);
+ lbits = type;
+ msgp->msgh_bits =
+ (msgp->msgh_bits & ~MACH_MSGH_BITS_PORTS_MASK) |
+ MACH_MSGH_BITS (lbits, rbits);
+}
+
+/* On the third day He said:
+
+ Let this be global
+ and then it was global.
+
+ When creating the inferior fork, the
+ child code in inflow.c sets the name of the
+ bootstrap_port in its address space to this
+ variable.
+
+ The name is transferred to our address space
+ with mach3_read_inferior().
+
+ Thou shalt not do this with
+ task_get_bootstrap_port() in this task, since
+ the name in the inferior task is different than
+ the one we get.
+
+ For blessed are the meek, as they shall inherit
+ the address space.
+ */
+mach_port_t original_server_port_name = MACH_PORT_NULL;
+
+
+/* Called from inferior after FORK but before EXEC */
+static void
+m3_trace_me (void)
+{
+ kern_return_t ret;
+
+ /* Get the NAME of the bootstrap port in this task
+ so that GDB can read it */
+ ret = task_get_bootstrap_port (mach_task_self (),
+ &original_server_port_name);
+ if (ret != KERN_SUCCESS)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ ret = mach_port_deallocate (mach_task_self (),
+ original_server_port_name);
+ if (ret != KERN_SUCCESS)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+ /* Suspend this task to let the parent change my ports.
+ Resumed by the debugger */
+ ret = task_suspend (mach_task_self ());
+ if (ret != KERN_SUCCESS)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+}
+
+/*
+ * Intercept system calls to Unix server.
+ * After EXEC_COUNTER calls to exec(), return.
+ *
+ * Pre-assertion: Child is suspended. (Not verified)
+ * Post-condition: Child is suspended after EXEC_COUNTER exec() calls.
+ */
+
+void
+intercept_exec_calls (int exec_counter)
+{
+ int terminal_initted = 0;
+
+ struct syscall_msg_t
+ {
+ mach_msg_header_t header;
+ mach_msg_type_t type;
+ char room[2000]; /* Enuff space */
+ };
+
+ struct syscall_msg_t syscall_in, syscall_out;
+
+ mach_port_t fake_server;
+ mach_port_t original_server_send;
+ mach_port_t original_exec_reply;
+ mach_port_t exec_reply;
+ mach_port_t exec_reply_send;
+ mach_msg_type_name_t acquired;
+ mach_port_t emulator_server_port_name;
+ struct task_basic_info info;
+ mach_msg_type_number_t info_count;
+
+ kern_return_t ret;
+
+ if (exec_counter <= 0)
+ return; /* We are already set up in the correct program */
+
+ ret = mach_port_allocate (mach_task_self (),
+ MACH_PORT_RIGHT_RECEIVE,
+ &fake_server);
+ CHK ("create inferior_fake_server port failed", ret);
+
+ /* Wait for inferior_task to suspend itself */
+ while (1)
+ {
+ info_count = sizeof (info);
+ ret = task_info (inferior_task,
+ TASK_BASIC_INFO,
+ (task_info_t) & info,
+ &info_count);
+ CHK ("Task info", ret);
+
+ if (info.suspend_count)
+ break;
+
+ /* Note that the definition of the parameter was undefined
+ * at the time of this writing, so I just use an `ad hoc' value.
+ */
+ (void) swtch_pri (42); /* Universal Priority Value */
+ }
+
+ /* Read the inferior's bootstrap port name */
+ if (!mach3_read_inferior (&original_server_port_name,
+ &original_server_port_name,
+ sizeof (original_server_port_name)))
+ error ("Can't read inferior task bootstrap port name");
+
+ /* @@ BUG: If more than 1 send right GDB will FAIL!!! */
+ /* Should get refs, and set them back when restoring */
+ /* Steal the original bsd server send right from inferior */
+ ret = mach_port_extract_right (inferior_task,
+ original_server_port_name,
+ MACH_MSG_TYPE_MOVE_SEND,
+ &original_server_send,
+ &acquired);
+ CHK ("mach_port_extract_right (bsd server send)", ret);
+
+ if (acquired != MACH_MSG_TYPE_PORT_SEND)
+ error ("Incorrect right extracted, send right to bsd server expected");
+
+ ret = mach_port_insert_right (inferior_task,
+ original_server_port_name,
+ fake_server,
+ MACH_MSG_TYPE_MAKE_SEND);
+ CHK ("mach_port_insert_right (fake server send)", ret);
+
+ xx_debug ("inferior task bsd server ports set up \nfs %x, ospn %x, oss %x\n",
+ fake_server,
+ original_server_port_name, original_server_send);
+
+ /* A receive right to the reply generated by unix server exec() request */
+ ret = mach_port_allocate (mach_task_self (),
+ MACH_PORT_RIGHT_RECEIVE,
+ &exec_reply);
+ CHK ("create intercepted_reply_port port failed", ret);
+
+ /* Pass this send right to Unix server so it replies to us after exec() */
+ ret = mach_port_extract_right (mach_task_self (),
+ exec_reply,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE,
+ &exec_reply_send,
+ &acquired);
+ CHK ("mach_port_extract_right (exec_reply)", ret);
+
+ if (acquired != MACH_MSG_TYPE_PORT_SEND_ONCE)
+ error ("Incorrect right extracted, send once expected for exec reply");
+
+ ret = mach_port_move_member (mach_task_self (),
+ fake_server,
+ inferior_wait_port_set);
+ CHK ("Moving fake syscall port to inferior_wait_port_set", ret);
+
+ xx_debug ("syscall fake server set up, resuming inferior\n");
+
+ ret = task_resume (inferior_task);
+ CHK ("task_resume (startup)", ret);
+
+ /* Read requests from the inferior.
+ Pass directly through everything else except exec() calls.
+ */
+ while (exec_counter > 0)
+ {
+ ret = mach_msg (&syscall_in.header, /* header */
+ MACH_RCV_MSG, /* options */
+ 0, /* send size */
+ sizeof (struct syscall_msg_t), /* receive size */
+ inferior_wait_port_set, /* receive_name */
+ MACH_MSG_TIMEOUT_NONE,
+ MACH_PORT_NULL);
+ CHK ("mach_msg (intercepted sycall)", ret);
+
+#ifdef DUMP_SYSCALL
+ print_msg (&syscall_in.header);
+#endif
+
+ /* ASSERT : msgh_local_port == fake_server */
+
+ if (notify_server (&syscall_in.header, &syscall_out.header))
+ error ("received a notify while intercepting syscalls");
+
+ if (syscall_in.header.msgh_id == MIG_EXEC_SYSCALL_ID)
+ {
+ xx_debug ("Received EXEC SYSCALL, counter = %d\n", exec_counter);
+ if (exec_counter == 1)
+ {
+ original_exec_reply = syscall_in.header.msgh_remote_port;
+ syscall_in.header.msgh_remote_port = exec_reply_send;
+ }
+
+ if (!terminal_initted)
+ {
+ /* Now that the child has exec'd we know it has already set its
+ process group. On POSIX systems, tcsetpgrp will fail with
+ EPERM if we try it before the child's setpgid. */
+
+ /* Set up the "saved terminal modes" of the inferior
+ based on what modes we are starting it with. */
+ target_terminal_init ();
+
+ /* Install inferior's terminal modes. */
+ target_terminal_inferior ();
+
+ terminal_initted = 1;
+ }
+
+ exec_counter--;
+ }
+
+ syscall_in.header.msgh_local_port = syscall_in.header.msgh_remote_port;
+ syscall_in.header.msgh_remote_port = original_server_send;
+
+ reverse_msg_bits (&syscall_in.header, MACH_MSG_TYPE_COPY_SEND);
+
+ ret = mach_msg_send (&syscall_in.header);
+ CHK ("Forwarded syscall", ret);
+ }
+
+ ret = mach_port_move_member (mach_task_self (),
+ fake_server,
+ MACH_PORT_NULL);
+ CHK ("Moving fake syscall out of inferior_wait_port_set", ret);
+
+ ret = mach_port_move_member (mach_task_self (),
+ exec_reply,
+ inferior_wait_port_set);
+ CHK ("Moving exec_reply to inferior_wait_port_set", ret);
+
+ ret = mach_msg (&syscall_in.header, /* header */
+ MACH_RCV_MSG, /* options */
+ 0, /* send size */
+ sizeof (struct syscall_msg_t), /* receive size */
+ inferior_wait_port_set, /* receive_name */
+ MACH_MSG_TIMEOUT_NONE,
+ MACH_PORT_NULL);
+ CHK ("mach_msg (exec reply)", ret);
+
+ ret = task_suspend (inferior_task);
+ CHK ("Suspending inferior after last exec", ret);
+
+ must_suspend_thread = 0;
+
+ xx_debug ("Received exec reply from bsd server, suspended inferior task\n");
+
+#ifdef DUMP_SYSCALL
+ print_msg (&syscall_in.header);
+#endif
+
+ /* Message should appear as if it came from the unix server */
+ syscall_in.header.msgh_local_port = MACH_PORT_NULL;
+
+ /* and go to the inferior task original reply port */
+ syscall_in.header.msgh_remote_port = original_exec_reply;
+
+ reverse_msg_bits (&syscall_in.header, MACH_MSG_TYPE_MOVE_SEND_ONCE);
+
+ ret = mach_msg_send (&syscall_in.header);
+ CHK ("Forwarding exec reply to inferior", ret);
+
+ /* Garbage collect */
+ ret = mach_port_deallocate (inferior_task,
+ original_server_port_name);
+ CHK ("deallocating fake server send right", ret);
+
+ ret = mach_port_insert_right (inferior_task,
+ original_server_port_name,
+ original_server_send,
+ MACH_MSG_TYPE_MOVE_SEND);
+ CHK ("Restoring the original bsd server send right", ret);
+
+ ret = mach_port_destroy (mach_task_self (),
+ fake_server);
+ fake_server = MACH_PORT_DEAD;
+ CHK ("mach_port_destroy (fake_server)", ret);
+
+ ret = mach_port_destroy (mach_task_self (),
+ exec_reply);
+ exec_reply = MACH_PORT_DEAD;
+ CHK ("mach_port_destroy (exec_reply)", ret);
+
+ xx_debug ("Done with exec call interception\n");
+}
+
+void
+consume_send_rights (thread_array_t thread_list, int thread_count)
+{
+ int index;
+
+ if (!thread_count)
+ return;
+
+ for (index = 0; index < thread_count; index++)
+ {
+ /* Since thread kill command kills threads, don't check ret */
+ (void) mach_port_deallocate (mach_task_self (),
+ thread_list[index]);
+ }
+}
+
+/* suspend/abort/resume a thread. */
+setup_thread (mach_port_t thread, int what)
+{
+ kern_return_t ret;
+
+ if (what)
+ {
+ ret = thread_suspend (thread);
+ CHK ("setup_thread thread_suspend", ret);
+
+ ret = thread_abort (thread);
+ CHK ("setup_thread thread_abort", ret);
+ }
+ else
+ {
+ ret = thread_resume (thread);
+ CHK ("setup_thread thread_resume", ret);
+ }
+}
+
+int
+map_slot_to_mid (int slot, thread_array_t threads, int thread_count)
+{
+ kern_return_t ret;
+ int deallocate = 0;
+ int index;
+ int mid;
+
+ if (!threads)
+ {
+ deallocate++;
+ ret = task_threads (inferior_task, &threads, &thread_count);
+ CHK ("Can not select a thread from a dead task", ret);
+ }
+
+ if (slot < 0 || slot >= thread_count)
+ {
+ if (deallocate)
+ {
+ consume_send_rights (threads, thread_count);
+ (void) vm_deallocate (mach_task_self (), (vm_address_t) threads,
+ (thread_count * sizeof (mach_port_t)));
+ }
+ if (slot < 0)
+ error ("invalid slot number");
+ else
+ return -(slot + 1);
+ }
+
+ mid = map_port_name_to_mid (threads[slot], MACH_TYPE_THREAD);
+
+ if (deallocate)
+ {
+ consume_send_rights (threads, thread_count);
+ (void) vm_deallocate (mach_task_self (), (vm_address_t) threads,
+ (thread_count * sizeof (mach_port_t)));
+ }
+
+ return mid;
+}
+
+static int
+parse_thread_id (char *arg, int thread_count, int slots)
+{
+ kern_return_t ret;
+ int mid;
+ int slot;
+ int index;
+
+ if (arg == 0)
+ return 0;
+
+ while (*arg && (*arg == ' ' || *arg == '\t'))
+ arg++;
+
+ if (!*arg)
+ return 0;
+
+ /* Currently parse MID and @SLOTNUMBER */
+ if (*arg != '@')
+ {
+ mid = atoi (arg);
+ if (mid <= 0)
+ error ("valid thread mid expected");
+ return mid;
+ }
+
+ arg++;
+ slot = atoi (arg);
+
+ if (slot < 0)
+ error ("invalid slot number");
+
+ /* If you want slot numbers to remain slot numbers, set slots.
+
+ * Well, since 0 is reserved, return the ordinal number
+ * of the thread rather than the slot number. Awk, this
+ * counts as a kludge.
+ */
+ if (slots)
+ return -(slot + 1);
+
+ if (thread_count && slot >= thread_count)
+ return -(slot + 1);
+
+ mid = map_slot_to_mid (slot);
+
+ return mid;
+}
+
+/* THREAD_ID 0 is special; it selects the first kernel
+ * thread from the list (i.e. SLOTNUMBER 0)
+ * This is used when starting the program with 'run' or when attaching.
+ *
+ * If FLAG is 0 the context is not changed, and the registers, frame, etc
+ * will continue to describe the old thread.
+ *
+ * If FLAG is nonzero, really select the thread.
+ * If FLAG is 2, the THREAD_ID is a slotnumber instead of a mid.
+ *
+ */
+kern_return_t
+select_thread (mach_port_t task, int thread_id, int flag)
+{
+ thread_array_t thread_list;
+ int thread_count;
+ kern_return_t ret;
+ int index;
+ thread_t new_thread = MACH_PORT_NULL;
+
+ if (thread_id < 0)
+ error ("Can't select cprocs without kernel thread");
+
+ ret = task_threads (task, &thread_list, &thread_count);
+ if (ret != KERN_SUCCESS)
+ {
+ warning ("Can not select a thread from a dead task");
+ m3_kill_inferior ();
+ return KERN_FAILURE;
+ }
+
+ if (thread_count == 0)
+ {
+ /* The task can not do anything anymore, but it still
+ * exists as a container for memory and ports.
+ */
+ registers_changed ();
+ warning ("Task %d has no threads",
+ map_port_name_to_mid (task, MACH_TYPE_TASK));
+ current_thread = MACH_PORT_NULL;
+ (void) vm_deallocate (mach_task_self (),
+ (vm_address_t) thread_list,
+ (thread_count * sizeof (mach_port_t)));
+ return KERN_FAILURE;
+ }
+
+ if (!thread_id || flag == 2)
+ {
+ /* First thread or a slotnumber */
+ if (!thread_id)
+ new_thread = thread_list[0];
+ else
+ {
+ if (thread_id < thread_count)
+ new_thread = thread_list[thread_id];
+ else
+ {
+ (void) vm_deallocate (mach_task_self (),
+ (vm_address_t) thread_list,
+ (thread_count * sizeof (mach_port_t)));
+ error ("No such thread slot number : %d", thread_id);
+ }
+ }
+ }
+ else
+ {
+ for (index = 0; index < thread_count; index++)
+ if (thread_id == map_port_name_to_mid (thread_list[index],
+ MACH_TYPE_THREAD))
+ {
+ new_thread = thread_list[index];
+ index = -1;
+ break;
+ }
+
+ if (index != -1)
+ error ("No thread with mid %d", thread_id);
+ }
+
+ /* Notify when the selected thread dies */
+ request_notify (new_thread, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_THREAD);
+
+ ret = vm_deallocate (mach_task_self (),
+ (vm_address_t) thread_list,
+ (thread_count * sizeof (mach_port_t)));
+ CHK ("vm_deallocate", ret);
+
+ if (!flag)
+ current_thread = new_thread;
+ else
+ {
+#if 0
+ if (MACH_PORT_VALID (current_thread))
+ {
+ /* Store the gdb's view of the thread we are deselecting
+
+ * @@ I think gdb updates registers immediately when they are
+ * changed, so don't do this.
+ */
+ ret = thread_abort (current_thread);
+ CHK ("Could not abort system calls when saving state of old thread",
+ ret);
+ target_prepare_to_store ();
+ target_store_registers (-1);
+ }
+#endif
+
+ registers_changed ();
+
+ current_thread = new_thread;
+
+ ret = thread_abort (current_thread);
+ CHK ("Could not abort system calls when selecting a thread", ret);
+
+ stop_pc = read_pc ();
+ flush_cached_frames ();
+
+ select_frame (get_current_frame ());
+ }
+
+ return KERN_SUCCESS;
+}
+
+/*
+ * Switch to use thread named NEW_THREAD.
+ * Return it's MID
+ */
+int
+switch_to_thread (thread_t new_thread)
+{
+ thread_t saved_thread = current_thread;
+ int mid;
+
+ mid = map_port_name_to_mid (new_thread,
+ MACH_TYPE_THREAD);
+ if (mid == -1)
+ warning ("Can't map thread name 0x%x to mid", new_thread);
+ else if (select_thread (inferior_task, mid, 1) != KERN_SUCCESS)
+ {
+ if (current_thread)
+ current_thread = saved_thread;
+ error ("Could not select thread %d", mid);
+ }
+
+ return mid;
+}
+
+/* Do this in gdb after doing FORK but before STARTUP_INFERIOR.
+ * Note that the registers are not yet valid in the inferior task.
+ */
+static int
+m3_trace_him (int pid)
+{
+ kern_return_t ret;
+
+ push_target (&m3_ops);
+
+ inferior_task = task_by_pid (pid);
+
+ if (!MACH_PORT_VALID (inferior_task))
+ error ("Can not map Unix pid %d to Mach task", pid);
+
+ /* Clean up previous notifications and create new ones */
+ setup_notify_port (1);
+
+ /* When notification appears, the inferior task has died */
+ request_notify (inferior_task, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_TASK);
+
+ emulator_present = have_emulator_p (inferior_task);
+
+ /* By default, select the first thread,
+ * If task has no threads, gives a warning
+ * Does not fetch registers, since they are not yet valid.
+ */
+ select_thread (inferior_task, 0, 0);
+
+ inferior_exception_port = MACH_PORT_NULL;
+
+ setup_exception_port ();
+
+ xx_debug ("Now the debugged task is created\n");
+
+ /* One trap to exec the shell, one to exec the program being debugged. */
+ intercept_exec_calls (2);
+
+ return pid;
+}
+
+setup_exception_port (void)
+{
+ kern_return_t ret;
+
+ ret = mach_port_allocate (mach_task_self (),
+ MACH_PORT_RIGHT_RECEIVE,
+ &inferior_exception_port);
+ CHK ("mach_port_allocate", ret);
+
+ /* add send right */
+ ret = mach_port_insert_right (mach_task_self (),
+ inferior_exception_port,
+ inferior_exception_port,
+ MACH_MSG_TYPE_MAKE_SEND);
+ CHK ("mach_port_insert_right", ret);
+
+ ret = mach_port_move_member (mach_task_self (),
+ inferior_exception_port,
+ inferior_wait_port_set);
+ CHK ("mach_port_move_member", ret);
+
+ ret = task_get_special_port (inferior_task,
+ TASK_EXCEPTION_PORT,
+ &inferior_old_exception_port);
+ CHK ("task_get_special_port(old exc)", ret);
+
+ ret = task_set_special_port (inferior_task,
+ TASK_EXCEPTION_PORT,
+ inferior_exception_port);
+ CHK ("task_set_special_port", ret);
+
+ ret = mach_port_deallocate (mach_task_self (),
+ inferior_exception_port);
+ CHK ("mack_port_deallocate", ret);
+
+#if 0
+ /* When notify appears, the inferior_task's exception
+ * port has been destroyed.
+ *
+ * Not used, since the dead_name_notification already
+ * appears when task dies.
+ *
+ */
+ request_notify (inferior_exception_port,
+ MACH_NOTIFY_NO_SENDERS,
+ MACH_TYPE_EXCEPTION_PORT);
+#endif
+}
+
+/* Nonzero if gdb is waiting for a message */
+int mach_really_waiting;
+
+/* Wait for the inferior to stop for some reason.
+ - Loop on notifications until inferior_task dies.
+ - Loop on exceptions until stopped_in_exception comes true.
+ (e.g. we receive a single step trace trap)
+ - a message arrives to gdb's message port
+
+ There is no other way to exit this loop.
+
+ Returns the inferior_ptid for rest of gdb.
+ Side effects: Set *OURSTATUS. */
+ptid_t
+mach_really_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+{
+ kern_return_t ret;
+ int w;
+
+ struct msg
+ {
+ mach_msg_header_t header;
+ mach_msg_type_t foo;
+ int data[8000];
+ }
+ in_msg, out_msg;
+
+ /* Either notify (death), exception or message can stop the inferior */
+ stopped_in_exception = FALSE;
+
+ while (1)
+ {
+ QUIT;
+
+ stop_exception = stop_code = stop_subcode = -1;
+ stop_thread = MACH_PORT_NULL;
+
+ mach_really_waiting = 1;
+ ret = mach_msg (&in_msg.header, /* header */
+ MACH_RCV_MSG, /* options */
+ 0, /* send size */
+ sizeof (struct msg), /* receive size */
+ currently_waiting_for, /* receive name */
+ MACH_MSG_TIMEOUT_NONE,
+ MACH_PORT_NULL);
+ mach_really_waiting = 0;
+ CHK ("mach_msg (receive)", ret);
+
+ /* Check if we received a notify of the childs' death */
+ if (notify_server (&in_msg.header, &out_msg.header))
+ {
+ /* If inferior_task is null then the inferior has
+ gone away and we want to return to command level.
+ Otherwise it was just an informative message and we
+ need to look to see if there are any more. */
+ if (inferior_task != MACH_PORT_NULL)
+ continue;
+ else
+ {
+ /* Collect Unix exit status for gdb */
+
+ wait3 (&w, WNOHANG, 0);
+
+ /* This mess is here to check that the rest of
+ * gdb knows that the inferior died. It also
+ * tries to hack around the fact that Mach 3.0 (mk69)
+ * unix server (ux28) does not always know what
+ * has happened to it's children when mach-magic
+ * is applied on them.
+ */
+ if ((!WIFEXITED (w) && WIFSTOPPED (w)) ||
+ (WIFEXITED (w) && WEXITSTATUS (w) > 0377))
+ {
+ WSETEXIT (w, 0);
+ warning ("Using exit value 0 for terminated task");
+ }
+ else if (!WIFEXITED (w))
+ {
+ int sig = WTERMSIG (w);
+
+ /* Signals cause problems. Warn the user. */
+ if (sig != SIGKILL) /* Bad luck if garbage matches this */
+ warning ("The terminating signal stuff may be nonsense");
+ else if (sig > NSIG)
+ {
+ WSETEXIT (w, 0);
+ warning ("Using exit value 0 for terminated task");
+ }
+ }
+ store_waitstatus (ourstatus, w);
+ return inferior_ptid;
+ }
+ }
+
+ /* Hmm. Check for exception, as it was not a notification.
+ exc_server() does an upcall to catch_exception_raise()
+ if this rpc is an exception. Further actions are decided
+ there.
+ */
+ if (!exc_server (&in_msg.header, &out_msg.header))
+ {
+
+ /* Not an exception, check for message.
+
+ * Messages don't come from the inferior, or if they
+ * do they better be asynchronous or it will hang.
+ */
+ if (gdb_message_server (&in_msg.header))
+ continue;
+
+ error ("Unrecognized message received in mach_really_wait");
+ }
+
+ /* Send the reply of the exception rpc to the suspended task */
+ ret = mach_msg_send (&out_msg.header);
+ CHK ("mach_msg_send (exc reply)", ret);
+
+ if (stopped_in_exception)
+ {
+ /* Get unix state. May be changed in mach3_exception_actions() */
+ wait3 (&w, WNOHANG, 0);
+
+ mach3_exception_actions (&w, FALSE, "Task");
+
+ store_waitstatus (ourstatus, w);
+ return inferior_ptid;
+ }
+ }
+}
+
+/* Called by macro DO_QUIT() in utils.c(quit).
+ * This is called just before calling error() to return to command level
+ */
+void
+mach3_quit (void)
+{
+ int mid;
+ kern_return_t ret;
+
+ if (mach_really_waiting)
+ {
+ ret = task_suspend (inferior_task);
+
+ if (ret != KERN_SUCCESS)
+ {
+ warning ("Could not suspend task for interrupt: %s",
+ mach_error_string (ret));
+ mach_really_waiting = 0;
+ return;
+ }
+ }
+
+ must_suspend_thread = 0;
+ mach_really_waiting = 0;
+
+ mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD);
+ if (mid == -1)
+ {
+ warning ("Selecting first existing kernel thread");
+ mid = 0;
+ }
+
+ current_thread = MACH_PORT_NULL; /* Force setup */
+ select_thread (inferior_task, mid, 1);
+
+ return;
+}
+
+#if 0
+/* bogus bogus bogus. It is NOT OK to quit out of target_wait. */
+
+/* If ^C is typed when we are waiting for a message
+ * and your Unix server is able to notice that we
+ * should quit now.
+ *
+ * Called by REQUEST_QUIT() from utils.c(request_quit)
+ */
+void
+mach3_request_quit (void)
+{
+ if (mach_really_waiting)
+ immediate_quit = 1;
+}
+#endif
+
+/*
+ * Gdb message server.
+ * Currently implemented is the STOP message, that causes
+ * gdb to return to the command level like ^C had been typed from terminal.
+ */
+int
+gdb_message_server (mach_msg_header_t *InP)
+{
+ kern_return_t ret;
+ int mid;
+
+ if (InP->msgh_local_port == our_message_port)
+ {
+ /* A message coming to our_message_port. Check validity */
+ switch (InP->msgh_id)
+ {
+
+ case GDB_MESSAGE_ID_STOP:
+ ret = task_suspend (inferior_task);
+ if (ret != KERN_SUCCESS)
+ warning ("Could not suspend task for stop message: %s",
+ mach_error_string (ret));
+
+ /* QUIT in mach_really_wait() loop. */
+ request_quit (0);
+ break;
+
+ default:
+ warning ("Invalid message id %d received, ignored.",
+ InP->msgh_id);
+ break;
+ }
+
+ return 1;
+ }
+
+ /* Message not handled by this server */
+ return 0;
+}
+
+/* NOTE: This is not an RPC call. It is a simpleroutine.
+
+ * This is not called from this gdb code.
+ *
+ * It may be called by another debugger to cause this
+ * debugger to enter command level:
+ *
+ * (gdb) set stop_inferior_gdb ()
+ * (gdb) continue
+ *
+ * External program "stop-gdb" implements this also.
+ */
+void
+stop_inferior_gdb (void)
+{
+ kern_return_t ret;
+
+ /* Code generated by mig, with minor cleanups :-)
+
+ * simpleroutine stop_inferior_gdb (our_message_port : mach_port_t);
+ */
+
+ typedef struct
+ {
+ mach_msg_header_t Head;
+ }
+ Request;
+
+ Request Mess;
+
+ register Request *InP = &Mess;
+
+ InP->Head.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0);
+
+ /* msgh_size passed as argument */
+ InP->Head.msgh_remote_port = our_message_port;
+ InP->Head.msgh_local_port = MACH_PORT_NULL;
+ InP->Head.msgh_seqno = 0;
+ InP->Head.msgh_id = GDB_MESSAGE_ID_STOP;
+
+ ret = mach_msg (&InP->Head,
+ MACH_SEND_MSG | MACH_MSG_OPTION_NONE,
+ sizeof (Request),
+ 0,
+ MACH_PORT_NULL,
+ MACH_MSG_TIMEOUT_NONE,
+ MACH_PORT_NULL);
+}
+
+#ifdef THREAD_ALLOWED_TO_BREAK
+/*
+ * Return 1 if the MID specifies the thread that caused the
+ * last exception.
+ * Since catch_exception_raise() selects the thread causing
+ * the last exception to current_thread, we just check that
+ * it is selected and the last exception was a breakpoint.
+ */
+int
+mach_thread_for_breakpoint (int mid)
+{
+ int cmid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD);
+
+ if (mid < 0)
+ {
+ mid = map_slot_to_mid (-(mid + 1), 0, 0);
+ if (mid < 0)
+ return 0; /* Don't stop, no such slot */
+ }
+
+ if (!mid || cmid == -1)
+ return 1; /* stop */
+
+ return cmid == mid && stop_exception == EXC_BREAKPOINT;
+}
+#endif /* THREAD_ALLOWED_TO_BREAK */
+
+#ifdef THREAD_PARSE_ID
+/*
+ * Map a thread id string (MID or a @SLOTNUMBER)
+ * to a thread-id.
+ *
+ * 0 matches all threads.
+ * Otherwise the meaning is defined only in this file.
+ * (mach_thread_for_breakpoint uses it)
+ *
+ * @@ This allows non-existent MIDs to be specified.
+ * It now also allows non-existent slots to be
+ * specified. (Slot numbers stored are negative,
+ * and the magnitude is one greater than the actual
+ * slot index. (Since 0 is reserved))
+ */
+int
+mach_thread_parse_id (char *arg)
+{
+ int mid;
+ if (arg == 0)
+ error ("thread id expected");
+ mid = parse_thread_id (arg, 0, 1);
+
+ return mid;
+}
+#endif /* THREAD_PARSE_ID */
+
+#ifdef THREAD_OUTPUT_ID
+char *
+mach_thread_output_id (int mid)
+{
+ static char foobar[20];
+
+ if (mid > 0)
+ sprintf (foobar, "mid %d", mid);
+ else if (mid < 0)
+ sprintf (foobar, "@%d", -(mid + 1));
+ else
+ sprintf (foobar, "*any thread*");
+
+ return foobar;
+}
+#endif /* THREAD_OUTPUT_ID */
+
+/* Called with hook PREPARE_TO_PROCEED() from infrun.c.
+
+ * If we have switched threads and stopped at breakpoint return 1 otherwise 0.
+ *
+ * if SELECT_IT is nonzero, reselect the thread that was active when
+ * we stopped at a breakpoint.
+ *
+ * Note that this implementation is potentially redundant now that
+ * default_prepare_to_proceed() has been added.
+ *
+ * FIXME This may not support switching threads after Ctrl-C
+ * correctly. The default implementation does support this.
+ */
+
+mach3_prepare_to_proceed (int select_it)
+{
+ if (stop_thread &&
+ stop_thread != current_thread &&
+ stop_exception == EXC_BREAKPOINT)
+ {
+ int mid;
+
+ if (!select_it)
+ return 1;
+
+ mid = switch_to_thread (stop_thread);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/* this stuff here is an upcall via libmach/excServer.c
+ and mach_really_wait which does the actual upcall.
+
+ The code will pass the exception to the inferior if:
+
+ - The task that signaled is not the inferior task
+ (e.g. when debugging another debugger)
+
+ - The user has explicitely requested to pass on the exceptions.
+ (e.g to the default unix exception handler, which maps
+ exceptions to signals, or the user has her own exception handler)
+
+ - If the thread that signaled is being single-stepped and it
+ has set it's own exception port and the exception is not
+ EXC_BREAKPOINT. (Maybe this is not desirable?)
+ */
+
+kern_return_t
+catch_exception_raise (mach_port_t port, thread_t thread, task_t task,
+ int exception, int code, int subcode)
+{
+ kern_return_t ret;
+ boolean_t signal_thread;
+ int mid = map_port_name_to_mid (thread, MACH_TYPE_THREAD);
+
+ if (!MACH_PORT_VALID (thread))
+ {
+ /* If the exception was sent and thread dies before we
+ receive it, THREAD will be MACH_PORT_DEAD
+ */
+
+ current_thread = thread = MACH_PORT_NULL;
+ error ("Received exception from nonexistent thread");
+ }
+
+ /* Check if the task died in transit.
+ * @@ Isn't the thread also invalid in such case?
+ */
+ if (!MACH_PORT_VALID (task))
+ {
+ current_thread = thread = MACH_PORT_NULL;
+ error ("Received exception from nonexistent task");
+ }
+
+ if (exception < 0 || exception > MAX_EXCEPTION)
+ internal_error (__FILE__, __LINE__,
+ "catch_exception_raise: unknown exception code %d thread %d",
+ exception,
+ mid);
+
+ if (!MACH_PORT_VALID (inferior_task))
+ error ("got an exception, but inferior_task is null or dead");
+
+ stop_exception = exception;
+ stop_code = code;
+ stop_subcode = subcode;
+ stop_thread = thread;
+
+ signal_thread = exception != EXC_BREAKPOINT &&
+ port == singlestepped_thread_port &&
+ MACH_PORT_VALID (thread_saved_exception_port);
+
+ /* If it was not our inferior or if we want to forward
+ * the exception to the inferior's handler, do it here
+ *
+ * Note: If you have forwarded EXC_BREAKPOINT I trust you know why.
+ */
+ if (task != inferior_task ||
+ signal_thread ||
+ exception_map[exception].forward)
+ {
+ mach_port_t eport = inferior_old_exception_port;
+
+ if (signal_thread)
+ {
+ /*
+ GDB now forwards the exeption to thread's original handler,
+ since the user propably knows what he is doing.
+ Give a message, though.
+ */
+
+ mach3_exception_actions ((WAITTYPE *) NULL, TRUE, "Thread");
+ eport = thread_saved_exception_port;
+ }
+
+ /* Send the exception to the original handler */
+ ret = exception_raise (eport,
+ thread,
+ task,
+ exception,
+ code,
+ subcode);
+
+ (void) mach_port_deallocate (mach_task_self (), task);
+ (void) mach_port_deallocate (mach_task_self (), thread);
+
+ /* If we come here, we don't want to trace any more, since we
+ * will never stop for tracing anyway.
+ */
+ discard_single_step (thread);
+
+ /* Do not stop the inferior */
+ return ret;
+ }
+
+ /* Now gdb handles the exception */
+ stopped_in_exception = TRUE;
+
+ ret = task_suspend (task);
+ CHK ("Error suspending inferior after exception", ret);
+
+ must_suspend_thread = 0;
+
+ if (current_thread != thread)
+ {
+ if (MACH_PORT_VALID (singlestepped_thread_port))
+ /* Cleanup discards single stepping */
+ error ("Exception from thread %d while singlestepping thread %d",
+ mid,
+ map_port_name_to_mid (current_thread, MACH_TYPE_THREAD));
+
+ /* Then select the thread that caused the exception */
+ if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS)
+ error ("Could not select thread %d causing exception", mid);
+ else
+ warning ("Gdb selected thread %d", mid);
+ }
+
+ /* If we receive an exception that is not breakpoint
+ * exception, we interrupt the single step and return to
+ * debugger. Trace condition is cleared.
+ */
+ if (MACH_PORT_VALID (singlestepped_thread_port))
+ {
+ if (stop_exception != EXC_BREAKPOINT)
+ warning ("Single step interrupted by exception");
+ else if (port == singlestepped_thread_port)
+ {
+ /* Single step exception occurred, remove trace bit
+ * and return to gdb.
+ */
+ if (!MACH_PORT_VALID (current_thread))
+ error ("Single stepped thread is not valid");
+
+ /* Resume threads, but leave the task suspended */
+ resume_all_threads (0);
+ }
+ else
+ warning ("Breakpoint while single stepping?");
+
+ discard_single_step (current_thread);
+ }
+
+ (void) mach_port_deallocate (mach_task_self (), task);
+ (void) mach_port_deallocate (mach_task_self (), thread);
+
+ return KERN_SUCCESS;
+}
+
+int
+port_valid (mach_port_t port, int mask)
+{
+ kern_return_t ret;
+ mach_port_type_t type;
+
+ ret = mach_port_type (mach_task_self (),
+ port,
+ &type);
+ if (ret != KERN_SUCCESS || (type & mask) != mask)
+ return 0;
+ return 1;
+}
+
+/* @@ No vm read cache implemented yet */
+boolean_t vm_read_cache_valid = FALSE;
+
+/*
+ * Read inferior task's LEN bytes from ADDR and copy it to MYADDR
+ * in gdb's address space.
+ *
+ * Return 0 on failure; number of bytes read otherwise.
+ */
+int
+mach3_read_inferior (CORE_ADDR addr, char *myaddr, int length)
+{
+ kern_return_t ret;
+ vm_address_t low_address = (vm_address_t) trunc_page (addr);
+ vm_size_t aligned_length =
+ (vm_size_t) round_page (addr + length) - low_address;
+ pointer_t copied_memory;
+ int copy_count;
+
+ /* Get memory from inferior with page aligned addresses */
+ ret = vm_read (inferior_task,
+ low_address,
+ aligned_length,
+ &copied_memory,
+ &copy_count);
+ if (ret != KERN_SUCCESS)
+ {
+ /* the problem is that the inferior might be killed for whatever reason
+ * before we go to mach_really_wait. This is one place that ought to
+ * catch many of those errors.
+ * @@ A better fix would be to make all external events to GDB
+ * to arrive via a SINGLE port set. (Including user input!)
+ */
+
+ if (!port_valid (inferior_task, MACH_PORT_TYPE_SEND))
+ {
+ m3_kill_inferior ();
+ error ("Inferior killed (task port invalid)");
+ }
+ else
+ {
+#ifdef OSF
+ extern int errno;
+ /* valprint.c gives nicer format if this does not
+ screw it. Eamonn seems to like this, so I enable
+ it if OSF is defined...
+ */
+ warning ("[read inferior %x failed: %s]",
+ addr, mach_error_string (ret));
+ errno = 0;
+#endif
+ return 0;
+ }
+ }
+
+ memcpy (myaddr, (char *) addr - low_address + copied_memory, length);
+
+ ret = vm_deallocate (mach_task_self (),
+ copied_memory,
+ copy_count);
+ CHK ("mach3_read_inferior vm_deallocate failed", ret);
+
+ return length;
+}
+
+#define CHK_GOTO_OUT(str,ret) \
+ do if (ret != KERN_SUCCESS) { errstr = #str; goto out; } while(0)
+
+struct vm_region_list
+{
+ struct vm_region_list *next;
+ vm_prot_t protection;
+ vm_address_t start;
+ vm_size_t length;
+};
+
+struct obstack region_obstack;
+
+/*
+ * Write inferior task's LEN bytes from ADDR and copy it to MYADDR
+ * in gdb's address space.
+ */
+int
+mach3_write_inferior (CORE_ADDR addr, char *myaddr, int length)
+{
+ kern_return_t ret;
+ vm_address_t low_address = (vm_address_t) trunc_page (addr);
+ vm_size_t aligned_length =
+ (vm_size_t) round_page (addr + length) - low_address;
+ pointer_t copied_memory;
+ int copy_count;
+ int deallocate = 0;
+
+ char *errstr = "Bug in mach3_write_inferior";
+
+ struct vm_region_list *region_element;
+ struct vm_region_list *region_head = (struct vm_region_list *) NULL;
+
+ /* Get memory from inferior with page aligned addresses */
+ ret = vm_read (inferior_task,
+ low_address,
+ aligned_length,
+ &copied_memory,
+ &copy_count);
+ CHK_GOTO_OUT ("mach3_write_inferior vm_read failed", ret);
+
+ deallocate++;
+
+ memcpy ((char *) addr - low_address + copied_memory, myaddr, length);
+
+ obstack_init (&region_obstack);
+
+ /* Do writes atomically.
+ * First check for holes and unwritable memory.
+ */
+ {
+ vm_size_t remaining_length = aligned_length;
+ vm_address_t region_address = low_address;
+
+ struct vm_region_list *scan;
+
+ while (region_address < low_address + aligned_length)
+ {
+ vm_prot_t protection;
+ vm_prot_t max_protection;
+ vm_inherit_t inheritance;
+ boolean_t shared;
+ mach_port_t object_name;
+ vm_offset_t offset;
+ vm_size_t region_length = remaining_length;
+ vm_address_t old_address = region_address;
+
+ ret = vm_region (inferior_task,
+ &region_address,
+ &region_length,
+ &protection,
+ &max_protection,
+ &inheritance,
+ &shared,
+ &object_name,
+ &offset);
+ CHK_GOTO_OUT ("vm_region failed", ret);
+
+ /* Check for holes in memory */
+ if (old_address != region_address)
+ {
+ warning ("No memory at 0x%x. Nothing written",
+ old_address);
+ ret = KERN_SUCCESS;
+ length = 0;
+ goto out;
+ }
+
+ if (!(max_protection & VM_PROT_WRITE))
+ {
+ warning ("Memory at address 0x%x is unwritable. Nothing written",
+ old_address);
+ ret = KERN_SUCCESS;
+ length = 0;
+ goto out;
+ }
+
+ /* Chain the regions for later use */
+ region_element =
+ (struct vm_region_list *)
+ obstack_alloc (&region_obstack, sizeof (struct vm_region_list));
+
+ region_element->protection = protection;
+ region_element->start = region_address;
+ region_element->length = region_length;
+
+ /* Chain the regions along with protections */
+ region_element->next = region_head;
+ region_head = region_element;
+
+ region_address += region_length;
+ remaining_length = remaining_length - region_length;
+ }
+
+ /* If things fail after this, we give up.
+ * Somebody is messing up inferior_task's mappings.
+ */
+
+ /* Enable writes to the chained vm regions */
+ for (scan = region_head; scan; scan = scan->next)
+ {
+ boolean_t protection_changed = FALSE;
+
+ if (!(scan->protection & VM_PROT_WRITE))
+ {
+ ret = vm_protect (inferior_task,
+ scan->start,
+ scan->length,
+ FALSE,
+ scan->protection | VM_PROT_WRITE);
+ CHK_GOTO_OUT ("vm_protect: enable write failed", ret);
+ }
+ }
+
+ ret = vm_write (inferior_task,
+ low_address,
+ copied_memory,
+ aligned_length);
+ CHK_GOTO_OUT ("vm_write failed", ret);
+
+ /* Set up the original region protections, if they were changed */
+ for (scan = region_head; scan; scan = scan->next)
+ {
+ boolean_t protection_changed = FALSE;
+
+ if (!(scan->protection & VM_PROT_WRITE))
+ {
+ ret = vm_protect (inferior_task,
+ scan->start,
+ scan->length,
+ FALSE,
+ scan->protection);
+ CHK_GOTO_OUT ("vm_protect: enable write failed", ret);
+ }
+ }
+ }
+
+out:
+ if (deallocate)
+ {
+ obstack_free (&region_obstack, 0);
+
+ (void) vm_deallocate (mach_task_self (),
+ copied_memory,
+ copy_count);
+ }
+
+ if (ret != KERN_SUCCESS)
+ {
+ warning ("%s %s", errstr, mach_error_string (ret));
+ return 0;
+ }
+
+ return length;
+}
+
+/* Return 0 on failure, number of bytes handled otherwise. TARGET is
+ ignored. */
+static int
+m3_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct target_ops *target)
+{
+ int result;
+
+ if (write)
+ result = mach3_write_inferior (memaddr, myaddr, len);
+ else
+ result = mach3_read_inferior (memaddr, myaddr, len);
+
+ return result;
+}
+
+
+static char *
+translate_state (int state)
+{
+ switch (state)
+ {
+ case TH_STATE_RUNNING:
+ return ("R");
+ case TH_STATE_STOPPED:
+ return ("S");
+ case TH_STATE_WAITING:
+ return ("W");
+ case TH_STATE_UNINTERRUPTIBLE:
+ return ("U");
+ case TH_STATE_HALTED:
+ return ("H");
+ default:
+ return ("?");
+ }
+}
+
+static char *
+translate_cstate (int state)
+{
+ switch (state)
+ {
+ case CPROC_RUNNING:
+ return "R";
+ case CPROC_SWITCHING:
+ return "S";
+ case CPROC_BLOCKED:
+ return "B";
+ case CPROC_CONDWAIT:
+ return "C";
+ case CPROC_CONDWAIT | CPROC_SWITCHING:
+ return "CS";
+ default:
+ return "?";
+ }
+}
+
+/* type == MACH_MSG_TYPE_COPY_SEND || type == MACH_MSG_TYPE_MAKE_SEND */
+
+mach_port_t /* no mach_port_name_t found in include files. */
+map_inferior_port_name (mach_port_t inferior_name, mach_msg_type_name_t type)
+{
+ kern_return_t ret;
+ mach_msg_type_name_t acquired;
+ mach_port_t iport;
+
+ ret = mach_port_extract_right (inferior_task,
+ inferior_name,
+ type,
+ &iport,
+ &acquired);
+ CHK ("mach_port_extract_right (map_inferior_port_name)", ret);
+
+ if (acquired != MACH_MSG_TYPE_PORT_SEND)
+ error ("Incorrect right extracted, (map_inferior_port_name)");
+
+ ret = mach_port_deallocate (mach_task_self (),
+ iport);
+ CHK ("Deallocating mapped port (map_inferior_port_name)", ret);
+
+ return iport;
+}
+
+/*
+ * Naming convention:
+ * Always return user defined name if found.
+ * _K == A kernel thread with no matching CPROC
+ * _C == A cproc with no current cthread
+ * _t == A cthread with no user defined name
+ *
+ * The digits that follow the _names are the SLOT number of the
+ * kernel thread if there is such a thing, otherwise just a negation
+ * of the sequential number of such cprocs.
+ */
+
+static char buf[7];
+
+static char *
+get_thread_name (gdb_thread_t one_cproc, int id)
+{
+ if (one_cproc)
+ if (one_cproc->cthread == NULL)
+ {
+ /* cproc not mapped to any cthread */
+ sprintf (buf, "_C%d", id);
+ }
+ else if (!one_cproc->cthread->name)
+ {
+ /* cproc and cthread, but no name */
+ sprintf (buf, "_t%d", id);
+ }
+ else
+ return (char *) (one_cproc->cthread->name);
+ else
+ {
+ if (id < 0)
+ warning ("Inconsistency in thread name id %d", id);
+
+ /* Kernel thread without cproc */
+ sprintf (buf, "_K%d", id);
+ }
+
+ return buf;
+}
+
+int
+fetch_thread_info (mach_port_t task, gdb_thread_t *mthreads_out)
+{
+ kern_return_t ret;
+ thread_array_t th_table;
+ int th_count;
+ gdb_thread_t mthreads = NULL;
+ int index;
+
+ ret = task_threads (task, &th_table, &th_count);
+ if (ret != KERN_SUCCESS)
+ {
+ warning ("Error getting inferior's thread list:%s",
+ mach_error_string (ret));
+ m3_kill_inferior ();
+ return -1;
+ }
+
+ mthreads = (gdb_thread_t)
+ obstack_alloc
+ (cproc_obstack,
+ th_count * sizeof (struct gdb_thread));
+
+ for (index = 0; index < th_count; index++)
+ {
+ thread_t saved_thread = MACH_PORT_NULL;
+ int mid;
+
+ if (must_suspend_thread)
+ setup_thread (th_table[index], 1);
+
+ if (th_table[index] != current_thread)
+ {
+ saved_thread = current_thread;
+
+ mid = switch_to_thread (th_table[index]);
+ }
+
+ mthreads[index].name = th_table[index];
+ mthreads[index].cproc = NULL; /* map_cprocs_to_kernel_threads() */
+ mthreads[index].in_emulator = FALSE;
+ mthreads[index].slotid = index;
+
+ mthreads[index].sp = read_register (SP_REGNUM);
+ mthreads[index].fp = read_register (FP_REGNUM);
+ mthreads[index].pc = read_pc ();
+
+ if (MACH_PORT_VALID (saved_thread))
+ mid = switch_to_thread (saved_thread);
+
+ if (must_suspend_thread)
+ setup_thread (th_table[index], 0);
+ }
+
+ consume_send_rights (th_table, th_count);
+ ret = vm_deallocate (mach_task_self (), (vm_address_t) th_table,
+ (th_count * sizeof (mach_port_t)));
+ if (ret != KERN_SUCCESS)
+ {
+ warning ("Error trying to deallocate thread list : %s",
+ mach_error_string (ret));
+ }
+
+ *mthreads_out = mthreads;
+
+ return th_count;
+}
+
+
+/*
+ * Current emulator always saves the USP on top of
+ * emulator stack below struct emul_stack_top stuff.
+ */
+CORE_ADDR
+fetch_usp_from_emulator_stack (CORE_ADDR sp)
+{
+ CORE_ADDR stack_pointer;
+
+ sp = (sp & ~(EMULATOR_STACK_SIZE - 1)) +
+ EMULATOR_STACK_SIZE - sizeof (struct emul_stack_top);
+
+ if (mach3_read_inferior (sp,
+ &stack_pointer,
+ sizeof (CORE_ADDR)) != sizeof (CORE_ADDR))
+ {
+ warning ("Can't read user sp from emulator stack address 0x%x", sp);
+ return 0;
+ }
+
+ return stack_pointer;
+}
+
+#ifdef MK67
+
+/* get_emulation_vector() interface was changed after mk67 */
+#define EMUL_VECTOR_COUNT 400 /* Value does not matter too much */
+
+#endif /* MK67 */
+
+/* Check if the emulator exists at task's address space.
+ */
+boolean_t
+have_emulator_p (task_t task)
+{
+ kern_return_t ret;
+#ifndef EMUL_VECTOR_COUNT
+ vm_offset_t *emulation_vector;
+ int n;
+#else
+ vm_offset_t emulation_vector[EMUL_VECTOR_COUNT];
+ int n = EMUL_VECTOR_COUNT;
+#endif
+ int i;
+ int vector_start;
+
+ ret = task_get_emulation_vector (task,
+ &vector_start,
+#ifndef EMUL_VECTOR_COUNT
+ &emulation_vector,
+#else
+ emulation_vector,
+#endif
+ &n);
+ CHK ("task_get_emulation_vector", ret);
+ xx_debug ("%d vectors from %d at 0x%08x\n",
+ n, vector_start, emulation_vector);
+
+ for (i = 0; i < n; i++)
+ {
+ vm_offset_t entry = emulation_vector[i];
+
+ if (EMULATOR_BASE <= entry && entry <= EMULATOR_END)
+ return TRUE;
+ else if (entry)
+ {
+ static boolean_t informed = FALSE;
+ if (!informed)
+ {
+ warning ("Emulation vector address 0x08%x outside emulator space",
+ entry);
+ informed = TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+/* Map cprocs to kernel threads and vice versa. */
+
+void
+map_cprocs_to_kernel_threads (gdb_thread_t cprocs, gdb_thread_t mthreads,
+ int thread_count)
+{
+ int index;
+ gdb_thread_t scan;
+ boolean_t all_mapped = TRUE;
+ LONGEST stack_base;
+ LONGEST stack_size;
+
+ for (scan = cprocs; scan; scan = scan->next)
+ {
+ /* Default to: no kernel thread for this cproc */
+ scan->reverse_map = -1;
+
+ /* Check if the cproc is found by its stack */
+ for (index = 0; index < thread_count; index++)
+ {
+ stack_base =
+ extract_signed_integer (scan->raw_cproc + CPROC_BASE_OFFSET,
+ CPROC_BASE_SIZE);
+ stack_size =
+ extract_signed_integer (scan->raw_cproc + CPROC_SIZE_OFFSET,
+ CPROC_SIZE_SIZE);
+ if ((mthreads + index)->sp > stack_base &&
+ (mthreads + index)->sp <= stack_base + stack_size)
+ {
+ (mthreads + index)->cproc = scan;
+ scan->reverse_map = index;
+ break;
+ }
+ }
+ all_mapped &= (scan->reverse_map != -1);
+ }
+
+ /* Check for threads that are currently in the emulator.
+ * If so, they have a different stack, and the still unmapped
+ * cprocs may well get mapped to these threads.
+ *
+ * If:
+ * - cproc stack does not match any kernel thread stack pointer
+ * - there is at least one extra kernel thread
+ * that has no cproc mapped above.
+ * - some kernel thread stack pointer points to emulator space
+ * then we find the user stack pointer saved in the emulator
+ * stack, and try to map that to the cprocs.
+ *
+ * Also set in_emulator for kernel threads.
+ */
+
+ if (emulator_present)
+ {
+ for (index = 0; index < thread_count; index++)
+ {
+ CORE_ADDR emul_sp;
+ CORE_ADDR usp;
+
+ gdb_thread_t mthread = (mthreads + index);
+ emul_sp = mthread->sp;
+
+ if (mthread->cproc == NULL &&
+ EMULATOR_BASE <= emul_sp && emul_sp <= EMULATOR_END)
+ {
+ mthread->in_emulator = emulator_present;
+
+ if (!all_mapped && cprocs)
+ {
+ usp = fetch_usp_from_emulator_stack (emul_sp);
+
+ /* @@ Could be more accurate */
+ if (!usp)
+ error ("Zero stack pointer read from emulator?");
+
+ /* Try to match this stack pointer to the cprocs that
+ * don't yet have a kernel thread.
+ */
+ for (scan = cprocs; scan; scan = scan->next)
+ {
+
+ /* Check is this unmapped CPROC stack contains
+ * the user stack pointer saved in the
+ * emulator.
+ */
+ if (scan->reverse_map == -1)
+ {
+ stack_base =
+ extract_signed_integer
+ (scan->raw_cproc + CPROC_BASE_OFFSET,
+ CPROC_BASE_SIZE);
+ stack_size =
+ extract_signed_integer
+ (scan->raw_cproc + CPROC_SIZE_OFFSET,
+ CPROC_SIZE_SIZE);
+ if (usp > stack_base &&
+ usp <= stack_base + stack_size)
+ {
+ mthread->cproc = scan;
+ scan->reverse_map = index;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Format of the thread_list command
+ *
+ * slot mid sel name emul ks susp cstate wired address
+ */
+#define TL_FORMAT "%-2.2s %5d%c %-10.10s %1.1s%s%-5.5s %-2.2s %-5.5s "
+
+#define TL_HEADER "\n@ MID Name KState CState Where\n"
+
+void
+print_tl_address (struct ui_file *stream, CORE_ADDR pc)
+{
+ if (!lookup_minimal_symbol_by_pc (pc))
+ fprintf_filtered (stream, local_hex_format (), pc);
+ else
+ {
+ extern int addressprint;
+ extern int asm_demangle;
+
+ int store = addressprint;
+ addressprint = 0;
+ print_address_symbolic (pc, stream, asm_demangle, "");
+ addressprint = store;
+ }
+}
+
+/* For thread names, but also for gdb_message_port external name */
+#define MAX_NAME_LEN 50
+
+/* Returns the address of variable NAME or 0 if not found */
+CORE_ADDR
+lookup_address_of_variable (char *name)
+{
+ struct symbol *sym;
+ CORE_ADDR symaddr = 0;
+ struct minimal_symbol *msymbol;
+
+ sym = lookup_symbol (name,
+ (struct block *) NULL,
+ VAR_NAMESPACE,
+ (int *) NULL,
+ (struct symtab **) NULL);
+
+ if (sym)
+ symaddr = SYMBOL_VALUE (sym);
+
+ if (!symaddr)
+ {
+ msymbol = lookup_minimal_symbol (name, NULL, NULL);
+
+ if (msymbol && msymbol->type == mst_data)
+ symaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+ }
+
+ return symaddr;
+}
+
+static gdb_thread_t
+get_cprocs (void)
+{
+ gdb_thread_t cproc_head;
+ gdb_thread_t cproc_copy;
+ CORE_ADDR their_cprocs;
+ char *buf;
+ char *name;
+ cthread_t cthread;
+ CORE_ADDR symaddr;
+
+ buf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT);
+ symaddr = lookup_address_of_variable ("cproc_list");
+
+ if (!symaddr)
+ {
+ /* cproc_list is not in a file compiled with debugging
+ symbols, but don't give up yet */
+
+ symaddr = lookup_address_of_variable ("cprocs");
+
+ if (symaddr)
+ {
+ static int informed = 0;
+ if (!informed)
+ {
+ informed++;
+ warning ("Your program is loaded with an old threads library.");
+ warning ("GDB does not know the old form of threads");
+ warning ("so things may not work.");
+ }
+ }
+ }
+
+ /* Stripped or no -lthreads loaded or "cproc_list" is in wrong segment. */
+ if (!symaddr)
+ return NULL;
+
+ /* Get the address of the first cproc in the task */
+ if (!mach3_read_inferior (symaddr,
+ buf,
+ TARGET_PTR_BIT / HOST_CHAR_BIT))
+ error ("Can't read cproc master list at address (0x%x).", symaddr);
+ their_cprocs = extract_address (buf, TARGET_PTR_BIT / HOST_CHAR_BIT);
+
+ /* Scan the CPROCs in the task.
+ CPROCs are chained with LIST field, not NEXT field, which
+ chains mutexes, condition variables and queues */
+
+ cproc_head = NULL;
+
+ while (their_cprocs != (CORE_ADDR) 0)
+ {
+ CORE_ADDR cproc_copy_incarnation;
+ cproc_copy = (gdb_thread_t) obstack_alloc (cproc_obstack,
+ sizeof (struct gdb_thread));
+
+ if (!mach3_read_inferior (their_cprocs,
+ &cproc_copy->raw_cproc[0],
+ CPROC_SIZE))
+ error ("Can't read next cproc at 0x%x.", their_cprocs);
+
+ their_cprocs =
+ extract_address (cproc_copy->raw_cproc + CPROC_LIST_OFFSET,
+ CPROC_LIST_SIZE);
+ cproc_copy_incarnation =
+ extract_address (cproc_copy->raw_cproc + CPROC_INCARNATION_OFFSET,
+ CPROC_INCARNATION_SIZE);
+
+ if (cproc_copy_incarnation == (CORE_ADDR) 0)
+ cproc_copy->cthread = NULL;
+ else
+ {
+ /* This CPROC has an attached CTHREAD. Get its name */
+ cthread = (cthread_t) obstack_alloc (cproc_obstack,
+ sizeof (struct cthread));
+
+ if (!mach3_read_inferior (cproc_copy_incarnation,
+ cthread,
+ sizeof (struct cthread)))
+ error ("Can't read next thread at 0x%x.",
+ cproc_copy_incarnation);
+
+ cproc_copy->cthread = cthread;
+
+ if (cthread->name)
+ {
+ name = (char *) obstack_alloc (cproc_obstack, MAX_NAME_LEN);
+
+ if (!mach3_read_inferior (cthread->name, name, MAX_NAME_LEN))
+ error ("Can't read next thread's name at 0x%x.", cthread->name);
+
+ cthread->name = name;
+ }
+ }
+
+ /* insert in front */
+ cproc_copy->next = cproc_head;
+ cproc_head = cproc_copy;
+ }
+ return cproc_head;
+}
+
+#ifndef FETCH_CPROC_STATE
+/*
+ * Check if your machine does not grok the way this routine
+ * fetches the FP,PC and SP of a cproc that is not
+ * currently attached to any kernel thread (e.g. its cproc.context
+ * field points to the place in stack where the context
+ * is saved).
+ *
+ * If it doesn't, define your own routine.
+ */
+#define FETCH_CPROC_STATE(mth) mach3_cproc_state (mth)
+
+int
+mach3_cproc_state (gdb_thread_t mthread)
+{
+ int context;
+
+ if (!mthread || !mthread->cproc)
+ return -1;
+
+ context = extract_signed_integer
+ (mthread->cproc->raw_cproc + CPROC_CONTEXT_OFFSET,
+ CPROC_CONTEXT_SIZE);
+ if (context == 0)
+ return -1;
+
+ mthread->sp = context + MACHINE_CPROC_SP_OFFSET;
+
+ if (mach3_read_inferior (context + MACHINE_CPROC_PC_OFFSET,
+ &mthread->pc,
+ sizeof (CORE_ADDR)) != sizeof (CORE_ADDR))
+ {
+ warning ("Can't read cproc pc from inferior");
+ return -1;
+ }
+
+ if (mach3_read_inferior (context + MACHINE_CPROC_FP_OFFSET,
+ &mthread->fp,
+ sizeof (CORE_ADDR)) != sizeof (CORE_ADDR))
+ {
+ warning ("Can't read cproc fp from inferior");
+ return -1;
+ }
+
+ return 0;
+}
+#endif /* FETCH_CPROC_STATE */
+
+
+void
+thread_list_command (void)
+{
+ thread_basic_info_data_t ths;
+ int thread_count;
+ gdb_thread_t cprocs;
+ gdb_thread_t scan;
+ int index;
+ char *name;
+ char selected;
+ char *wired;
+ int infoCnt;
+ kern_return_t ret;
+ mach_port_t mid_or_port;
+ gdb_thread_t their_threads;
+ gdb_thread_t kthread;
+
+ int neworder = 1;
+
+ char *fmt = "There are %d kernel threads in task %d.\n";
+
+ int tmid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK);
+
+ MACH_ERROR_NO_INFERIOR;
+
+ thread_count = fetch_thread_info (inferior_task,
+ &their_threads);
+ if (thread_count == -1)
+ return;
+
+ if (thread_count == 1)
+ fmt = "There is %d kernel thread in task %d.\n";
+
+ printf_filtered (fmt, thread_count, tmid);
+
+ puts_filtered (TL_HEADER);
+
+ cprocs = get_cprocs ();
+
+ map_cprocs_to_kernel_threads (cprocs, their_threads, thread_count);
+
+ for (scan = cprocs; scan; scan = scan->next)
+ {
+ int mid;
+ char buf[10];
+ char slot[3];
+ int cproc_state =
+ extract_signed_integer
+ (scan->raw_cproc + CPROC_STATE_OFFSET, CPROC_STATE_SIZE);
+
+ selected = ' ';
+
+ /* a wired cproc? */
+ wired = (extract_address (scan->raw_cproc + CPROC_WIRED_OFFSET,
+ CPROC_WIRED_SIZE)
+ ? "wired" : "");
+
+ if (scan->reverse_map != -1)
+ kthread = (their_threads + scan->reverse_map);
+ else
+ kthread = NULL;
+
+ if (kthread)
+ {
+ /* These cprocs have a kernel thread */
+
+ mid = map_port_name_to_mid (kthread->name, MACH_TYPE_THREAD);
+
+ infoCnt = THREAD_BASIC_INFO_COUNT;
+
+ ret = thread_info (kthread->name,
+ THREAD_BASIC_INFO,
+ (thread_info_t) & ths,
+ &infoCnt);
+
+ if (ret != KERN_SUCCESS)
+ {
+ warning ("Unable to get basic info on thread %d : %s",
+ mid,
+ mach_error_string (ret));
+ continue;
+ }
+
+ /* Who is the first to have more than 100 threads */
+ sprintf (slot, "%d", kthread->slotid % 100);
+
+ if (kthread->name == current_thread)
+ selected = '*';
+
+ if (ths.suspend_count)
+ sprintf (buf, "%d", ths.suspend_count);
+ else
+ buf[0] = '\000';
+
+#if 0
+ if (ths.flags & TH_FLAGS_SWAPPED)
+ strcat (buf, "S");
+#endif
+
+ if (ths.flags & TH_FLAGS_IDLE)
+ strcat (buf, "I");
+
+ printf_filtered (TL_FORMAT,
+ slot,
+ mid,
+ selected,
+ get_thread_name (scan, kthread->slotid),
+ kthread->in_emulator ? "E" : "",
+ translate_state (ths.run_state),
+ buf,
+ translate_cstate (cproc_state),
+ wired);
+ print_tl_address (gdb_stdout, kthread->pc);
+ }
+ else
+ {
+ /* These cprocs don't have a kernel thread.
+ * find out the calling frame with
+ * FETCH_CPROC_STATE.
+ */
+
+ struct gdb_thread state;
+
+#if 0
+ /* jtv -> emcmanus: why do you want this here? */
+ if (scan->incarnation == NULL)
+ continue; /* EMcM */
+#endif
+
+ printf_filtered (TL_FORMAT,
+ "-",
+ -neworder, /* Pseudo MID */
+ selected,
+ get_thread_name (scan, -neworder),
+ "",
+ "-", /* kernel state */
+ "",
+ translate_cstate (cproc_state),
+ "");
+ state.cproc = scan;
+
+ if (FETCH_CPROC_STATE (&state) == -1)
+ puts_filtered ("???");
+ else
+ print_tl_address (gdb_stdout, state.pc);
+
+ neworder++;
+ }
+ puts_filtered ("\n");
+ }
+
+ /* Scan for kernel threads without cprocs */
+ for (index = 0; index < thread_count; index++)
+ {
+ if (!their_threads[index].cproc)
+ {
+ int mid;
+
+ char buf[10];
+ char slot[3];
+
+ mach_port_t name = their_threads[index].name;
+
+ mid = map_port_name_to_mid (name, MACH_TYPE_THREAD);
+
+ infoCnt = THREAD_BASIC_INFO_COUNT;
+
+ ret = thread_info (name,
+ THREAD_BASIC_INFO,
+ (thread_info_t) & ths,
+ &infoCnt);
+
+ if (ret != KERN_SUCCESS)
+ {
+ warning ("Unable to get basic info on thread %d : %s",
+ mid,
+ mach_error_string (ret));
+ continue;
+ }
+
+ sprintf (slot, "%d", index % 100);
+
+ if (name == current_thread)
+ selected = '*';
+ else
+ selected = ' ';
+
+ if (ths.suspend_count)
+ sprintf (buf, "%d", ths.suspend_count);
+ else
+ buf[0] = '\000';
+
+#if 0
+ if (ths.flags & TH_FLAGS_SWAPPED)
+ strcat (buf, "S");
+#endif
+
+ if (ths.flags & TH_FLAGS_IDLE)
+ strcat (buf, "I");
+
+ printf_filtered (TL_FORMAT,
+ slot,
+ mid,
+ selected,
+ get_thread_name (NULL, index),
+ their_threads[index].in_emulator ? "E" : "",
+ translate_state (ths.run_state),
+ buf,
+ "", /* No cproc state */
+ ""); /* Can't be wired */
+ print_tl_address (gdb_stdout, their_threads[index].pc);
+ puts_filtered ("\n");
+ }
+ }
+
+ obstack_free (cproc_obstack, 0);
+ obstack_init (cproc_obstack);
+}
+
+void
+thread_select_command (char *args, int from_tty)
+{
+ int mid;
+ thread_array_t thread_list;
+ int thread_count;
+ kern_return_t ret;
+ int is_slot = 0;
+
+ MACH_ERROR_NO_INFERIOR;
+
+ if (!args)
+ error_no_arg ("MID or @SLOTNUMBER to specify a thread to select");
+
+ while (*args == ' ' || *args == '\t')
+ args++;
+
+ if (*args == '@')
+ {
+ is_slot++;
+ args++;
+ }
+
+ mid = atoi (args);
+
+ if (mid == 0)
+ if (!is_slot || *args != '0') /* Rudimentary checks */
+ error ("You must select threads by MID or @SLOTNUMBER");
+
+ if (select_thread (inferior_task, mid, is_slot ? 2 : 1) != KERN_SUCCESS)
+ return;
+
+ if (from_tty)
+ printf_filtered ("Thread %d selected\n",
+ is_slot ? map_port_name_to_mid (current_thread,
+ MACH_TYPE_THREAD) : mid);
+}
+
+thread_trace (mach_port_t thread, boolean_t set)
+{
+ int flavor = TRACE_FLAVOR;
+ unsigned int stateCnt = TRACE_FLAVOR_SIZE;
+ kern_return_t ret;
+ thread_state_data_t state;
+
+ if (!MACH_PORT_VALID (thread))
+ {
+ warning ("thread_trace: invalid thread");
+ return;
+ }
+
+ if (must_suspend_thread)
+ setup_thread (thread, 1);
+
+ ret = thread_get_state (thread, flavor, state, &stateCnt);
+ CHK ("thread_trace: error reading thread state", ret);
+
+ if (set)
+ {
+ TRACE_SET (thread, state);
+ }
+ else
+ {
+ if (!TRACE_CLEAR (thread, state))
+ {
+ if (must_suspend_thread)
+ setup_thread (thread, 0);
+ return;
+ }
+ }
+
+ ret = thread_set_state (thread, flavor, state, stateCnt);
+ CHK ("thread_trace: error writing thread state", ret);
+ if (must_suspend_thread)
+ setup_thread (thread, 0);
+}
+
+#ifdef FLUSH_INFERIOR_CACHE
+
+/* When over-writing code on some machines the I-Cache must be flushed
+ explicitly, because it is not kept coherent by the lazy hardware.
+ This definitely includes breakpoints, for instance, or else we
+ end up looping in mysterious Bpt traps */
+
+flush_inferior_icache (CORE_ADDR pc, int amount)
+{
+ vm_machine_attribute_val_t flush = MATTR_VAL_ICACHE_FLUSH;
+ kern_return_t ret;
+
+ ret = vm_machine_attribute (inferior_task,
+ pc,
+ amount,
+ MATTR_CACHE,
+ &flush);
+ if (ret != KERN_SUCCESS)
+ warning ("Error flushing inferior's cache : %s",
+ mach_error_string (ret));
+}
+#endif /* FLUSH_INFERIOR_CACHE */
+
+
+static
+suspend_all_threads (int from_tty)
+{
+ kern_return_t ret;
+ thread_array_t thread_list;
+ int thread_count, index;
+ int infoCnt;
+ thread_basic_info_data_t th_info;
+
+
+ ret = task_threads (inferior_task, &thread_list, &thread_count);
+ if (ret != KERN_SUCCESS)
+ {
+ warning ("Could not suspend inferior threads.");
+ m3_kill_inferior ();
+ throw_exception (RETURN_ERROR);
+ }
+
+ for (index = 0; index < thread_count; index++)
+ {
+ int mid;
+
+ mid = map_port_name_to_mid (thread_list[index],
+ MACH_TYPE_THREAD);
+
+ ret = thread_suspend (thread_list[index]);
+
+ if (ret != KERN_SUCCESS)
+ warning ("Error trying to suspend thread %d : %s",
+ mid, mach_error_string (ret));
+
+ if (from_tty)
+ {
+ infoCnt = THREAD_BASIC_INFO_COUNT;
+ ret = thread_info (thread_list[index],
+ THREAD_BASIC_INFO,
+ (thread_info_t) & th_info,
+ &infoCnt);
+ CHK ("suspend can't get thread info", ret);
+
+ warning ("Thread %d suspend count is %d",
+ mid, th_info.suspend_count);
+ }
+ }
+
+ consume_send_rights (thread_list, thread_count);
+ ret = vm_deallocate (mach_task_self (),
+ (vm_address_t) thread_list,
+ (thread_count * sizeof (int)));
+ CHK ("Error trying to deallocate thread list", ret);
+}
+
+void
+thread_suspend_command (char *args, int from_tty)
+{
+ kern_return_t ret;
+ int mid;
+ mach_port_t saved_thread;
+ int infoCnt;
+ thread_basic_info_data_t th_info;
+
+ MACH_ERROR_NO_INFERIOR;
+
+ if (!strcasecmp (args, "all"))
+ {
+ suspend_all_threads (from_tty);
+ return;
+ }
+
+ saved_thread = current_thread;
+
+ mid = parse_thread_id (args, 0, 0);
+
+ if (mid < 0)
+ error ("You can suspend only existing kernel threads with MID or @SLOTNUMBER");
+
+ if (mid == 0)
+ mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD);
+ else if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS)
+ {
+ if (current_thread)
+ current_thread = saved_thread;
+ error ("Could not select thread %d", mid);
+ }
+
+ ret = thread_suspend (current_thread);
+ if (ret != KERN_SUCCESS)
+ warning ("thread_suspend failed : %s",
+ mach_error_string (ret));
+
+ infoCnt = THREAD_BASIC_INFO_COUNT;
+ ret = thread_info (current_thread,
+ THREAD_BASIC_INFO,
+ (thread_info_t) & th_info,
+ &infoCnt);
+ CHK ("suspend can't get thread info", ret);
+
+ warning ("Thread %d suspend count is %d", mid, th_info.suspend_count);
+
+ current_thread = saved_thread;
+}
+
+resume_all_threads (int from_tty)
+{
+ kern_return_t ret;
+ thread_array_t thread_list;
+ int thread_count, index;
+ int mid;
+ int infoCnt;
+ thread_basic_info_data_t th_info;
+
+ ret = task_threads (inferior_task, &thread_list, &thread_count);
+ if (ret != KERN_SUCCESS)
+ {
+ m3_kill_inferior ();
+ error ("task_threads", mach_error_string (ret));
+ }
+
+ for (index = 0; index < thread_count; index++)
+ {
+ infoCnt = THREAD_BASIC_INFO_COUNT;
+ ret = thread_info (thread_list[index],
+ THREAD_BASIC_INFO,
+ (thread_info_t) & th_info,
+ &infoCnt);
+ CHK ("resume_all can't get thread info", ret);
+
+ mid = map_port_name_to_mid (thread_list[index],
+ MACH_TYPE_THREAD);
+
+ if (!th_info.suspend_count)
+ {
+ if (mid != -1 && from_tty)
+ warning ("Thread %d is not suspended", mid);
+ continue;
+ }
+
+ ret = thread_resume (thread_list[index]);
+
+ if (ret != KERN_SUCCESS)
+ warning ("Error trying to resume thread %d : %s",
+ mid, mach_error_string (ret));
+ else if (mid != -1 && from_tty)
+ warning ("Thread %d suspend count is %d",
+ mid, --th_info.suspend_count);
+ }
+
+ consume_send_rights (thread_list, thread_count);
+ ret = vm_deallocate (mach_task_self (),
+ (vm_address_t) thread_list,
+ (thread_count * sizeof (int)));
+ CHK ("Error trying to deallocate thread list", ret);
+}
+
+void
+thread_resume_command (char *args, int from_tty)
+{
+ int mid;
+ mach_port_t saved_thread;
+ kern_return_t ret;
+ thread_basic_info_data_t th_info;
+ int infoCnt = THREAD_BASIC_INFO_COUNT;
+
+ MACH_ERROR_NO_INFERIOR;
+
+ if (!strcasecmp (args, "all"))
+ {
+ resume_all_threads (from_tty);
+ return;
+ }
+
+ saved_thread = current_thread;
+
+ mid = parse_thread_id (args, 0, 0);
+
+ if (mid < 0)
+ error ("You can resume only existing kernel threads with MID or @SLOTNUMBER");
+
+ if (mid == 0)
+ mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD);
+ else if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS)
+ {
+ if (current_thread)
+ current_thread = saved_thread;
+ throw_exception (RETURN_ERROR);
+ }
+
+ ret = thread_info (current_thread,
+ THREAD_BASIC_INFO,
+ (thread_info_t) & th_info,
+ &infoCnt);
+ CHK ("resume can't get thread info", ret);
+
+ if (!th_info.suspend_count)
+ {
+ warning ("Thread %d is not suspended", mid);
+ goto out;
+ }
+
+ ret = thread_resume (current_thread);
+ if (ret != KERN_SUCCESS)
+ warning ("thread_resume failed : %s",
+ mach_error_string (ret));
+ else
+ {
+ th_info.suspend_count--;
+ warning ("Thread %d suspend count is %d", mid, th_info.suspend_count);
+ }
+
+out:
+ current_thread = saved_thread;
+}
+
+void
+thread_kill_command (char *args, int from_tty)
+{
+ int mid;
+ kern_return_t ret;
+ int thread_count;
+ thread_array_t thread_table;
+ int index;
+ mach_port_t thread_to_kill = MACH_PORT_NULL;
+
+
+ MACH_ERROR_NO_INFERIOR;
+
+ if (!args)
+ error_no_arg ("thread mid to kill from the inferior task");
+
+ mid = parse_thread_id (args, 0, 0);
+
+ if (mid < 0)
+ error ("You can kill only existing kernel threads with MID or @SLOTNUMBER");
+
+ if (mid)
+ {
+ ret = machid_mach_port (mid_server, mid_auth, mid, &thread_to_kill);
+ CHK ("thread_kill_command: machid_mach_port map failed", ret);
+ }
+ else
+ mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD);
+
+ /* Don't allow gdb to kill *any* thread in the system. Use mkill program for that */
+ ret = task_threads (inferior_task, &thread_table, &thread_count);
+ CHK ("Error getting inferior's thread list", ret);
+
+ if (thread_to_kill == current_thread)
+ {
+ ret = thread_terminate (thread_to_kill);
+ CHK ("Thread could not be terminated", ret);
+
+ if (select_thread (inferior_task, 0, 1) != KERN_SUCCESS)
+ warning ("Last thread was killed, use \"kill\" command to kill task");
+ }
+ else
+ for (index = 0; index < thread_count; index++)
+ if (thread_table[index] == thread_to_kill)
+ {
+ ret = thread_terminate (thread_to_kill);
+ CHK ("Thread could not be terminated", ret);
+ }
+
+ if (thread_count > 1)
+ consume_send_rights (thread_table, thread_count);
+
+ ret = vm_deallocate (mach_task_self (), (vm_address_t) thread_table,
+ (thread_count * sizeof (mach_port_t)));
+ CHK ("Error trying to deallocate thread list", ret);
+
+ warning ("Thread %d killed", mid);
+}
+
+
+/* Task specific commands; add more if you like */
+
+void
+task_resume_command (char *args, int from_tty)
+{
+ kern_return_t ret;
+ task_basic_info_data_t ta_info;
+ int infoCnt = TASK_BASIC_INFO_COUNT;
+ int mid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK);
+
+ MACH_ERROR_NO_INFERIOR;
+
+ /* Would be trivial to change, but is it desirable? */
+ if (args)
+ error ("Currently gdb can resume only it's inferior task");
+
+ ret = task_info (inferior_task,
+ TASK_BASIC_INFO,
+ (task_info_t) & ta_info,
+ &infoCnt);
+ CHK ("task_resume_command: task_info failed", ret);
+
+ if (ta_info.suspend_count == 0)
+ error ("Inferior task %d is not suspended", mid);
+ else if (ta_info.suspend_count == 1 &&
+ from_tty &&
+ !query ("Suspend count is now 1. Do you know what you are doing? "))
+ error ("Task not resumed");
+
+ ret = task_resume (inferior_task);
+ CHK ("task_resume_command: task_resume", ret);
+
+ if (ta_info.suspend_count == 1)
+ {
+ warning ("Inferior task %d is no longer suspended", mid);
+ must_suspend_thread = 1;
+ /* @@ This is not complete: Registers change all the time when not
+ suspended! */
+ registers_changed ();
+ }
+ else
+ warning ("Inferior task %d suspend count is now %d",
+ mid, ta_info.suspend_count - 1);
+}
+
+
+void
+task_suspend_command (char *args, int from_tty)
+{
+ kern_return_t ret;
+ task_basic_info_data_t ta_info;
+ int infoCnt = TASK_BASIC_INFO_COUNT;
+ int mid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK);
+
+ MACH_ERROR_NO_INFERIOR;
+
+ /* Would be trivial to change, but is it desirable? */
+ if (args)
+ error ("Currently gdb can suspend only it's inferior task");
+
+ ret = task_suspend (inferior_task);
+ CHK ("task_suspend_command: task_suspend", ret);
+
+ must_suspend_thread = 0;
+
+ ret = task_info (inferior_task,
+ TASK_BASIC_INFO,
+ (task_info_t) & ta_info,
+ &infoCnt);
+ CHK ("task_suspend_command: task_info failed", ret);
+
+ warning ("Inferior task %d suspend count is now %d",
+ mid, ta_info.suspend_count);
+}
+
+static char *
+get_size (int bytes)
+{
+ static char size[30];
+ int zz = bytes / 1024;
+
+ if (zz / 1024)
+ sprintf (size, "%-2.1f M", ((float) bytes) / (1024.0 * 1024.0));
+ else
+ sprintf (size, "%d K", zz);
+
+ return size;
+}
+
+/* Does this require the target task to be suspended?? I don't think so. */
+void
+task_info_command (char *args, int from_tty)
+{
+ int mid = -5;
+ mach_port_t task;
+ kern_return_t ret;
+ task_basic_info_data_t ta_info;
+ int infoCnt = TASK_BASIC_INFO_COUNT;
+ int page_size = round_page (1);
+ int thread_count = 0;
+
+ if (MACH_PORT_VALID (inferior_task))
+ mid = map_port_name_to_mid (inferior_task,
+ MACH_TYPE_TASK);
+
+ task = inferior_task;
+
+ if (args)
+ {
+ int tmid = atoi (args);
+
+ if (tmid <= 0)
+ error ("Invalid mid %d for task info", tmid);
+
+ if (tmid != mid)
+ {
+ mid = tmid;
+ ret = machid_mach_port (mid_server, mid_auth, tmid, &task);
+ CHK ("task_info_command: machid_mach_port map failed", ret);
+ }
+ }
+
+ if (mid < 0)
+ error ("You have to give the task MID as an argument");
+
+ ret = task_info (task,
+ TASK_BASIC_INFO,
+ (task_info_t) & ta_info,
+ &infoCnt);
+ CHK ("task_info_command: task_info failed", ret);
+
+ printf_filtered ("\nTask info for task %d:\n\n", mid);
+ printf_filtered (" Suspend count : %d\n", ta_info.suspend_count);
+ printf_filtered (" Base priority : %d\n", ta_info.base_priority);
+ printf_filtered (" Virtual size : %s\n", get_size (ta_info.virtual_size));
+ printf_filtered (" Resident size : %s\n", get_size (ta_info.resident_size));
+
+ {
+ thread_array_t thread_list;
+
+ ret = task_threads (task, &thread_list, &thread_count);
+ CHK ("task_info_command: task_threads", ret);
+
+ printf_filtered (" Thread count : %d\n", thread_count);
+
+ consume_send_rights (thread_list, thread_count);
+ ret = vm_deallocate (mach_task_self (),
+ (vm_address_t) thread_list,
+ (thread_count * sizeof (int)));
+ CHK ("Error trying to deallocate thread list", ret);
+ }
+ if (have_emulator_p (task))
+ printf_filtered (" Emulator at : 0x%x..0x%x\n",
+ EMULATOR_BASE, EMULATOR_END);
+ else
+ printf_filtered (" No emulator.\n");
+
+ if (thread_count && task == inferior_task)
+ printf_filtered ("\nUse the \"thread list\" command to see the threads\n");
+}
+
+/* You may either FORWARD the exception to the inferior, or KEEP
+ * it and return to GDB command level.
+ *
+ * exception mid [ forward | keep ]
+ */
+
+static void
+exception_command (char *args, int from_tty)
+{
+ char *scan = args;
+ int exception;
+ int len;
+
+ if (!args)
+ error_no_arg ("exception number action");
+
+ while (*scan == ' ' || *scan == '\t')
+ scan++;
+
+ if ('0' <= *scan && *scan <= '9')
+ while ('0' <= *scan && *scan <= '9')
+ scan++;
+ else
+ error ("exception number action");
+
+ exception = atoi (args);
+ if (exception <= 0 || exception > MAX_EXCEPTION)
+ error ("Allowed exception numbers are in range 1..%d",
+ MAX_EXCEPTION);
+
+ if (*scan != ' ' && *scan != '\t')
+ error ("exception number must be followed by a space");
+ else
+ while (*scan == ' ' || *scan == '\t')
+ scan++;
+
+ args = scan;
+ len = 0;
+ while (*scan)
+ {
+ len++;
+ scan++;
+ }
+
+ if (!len)
+ error ("exception number action");
+
+ if (!strncasecmp (args, "forward", len))
+ exception_map[exception].forward = TRUE;
+ else if (!strncasecmp (args, "keep", len))
+ exception_map[exception].forward = FALSE;
+ else
+ error ("exception action is either \"keep\" or \"forward\"");
+}
+
+static void
+print_exception_info (int exception)
+{
+ boolean_t forward = exception_map[exception].forward;
+
+ printf_filtered ("%s\t(%d): ", exception_map[exception].name,
+ exception);
+ if (!forward)
+ if (exception_map[exception].sigmap != SIG_UNKNOWN)
+ printf_filtered ("keep and handle as signal %d\n",
+ exception_map[exception].sigmap);
+ else
+ printf_filtered ("keep and handle as unknown signal %d\n",
+ exception_map[exception].sigmap);
+ else
+ printf_filtered ("forward exception to inferior\n");
+}
+
+void
+exception_info (char *args, int from_tty)
+{
+ int exception;
+
+ if (!args)
+ for (exception = 1; exception <= MAX_EXCEPTION; exception++)
+ print_exception_info (exception);
+ else
+ {
+ exception = atoi (args);
+
+ if (exception <= 0 || exception > MAX_EXCEPTION)
+ error ("Invalid exception number, values from 1 to %d allowed",
+ MAX_EXCEPTION);
+ print_exception_info (exception);
+ }
+}
+
+/* Check for actions for mach exceptions.
+ */
+mach3_exception_actions (WAITTYPE *w, boolean_t force_print_only, char *who)
+{
+ boolean_t force_print = FALSE;
+
+
+ if (force_print_only ||
+ exception_map[stop_exception].sigmap == SIG_UNKNOWN)
+ force_print = TRUE;
+ else
+ WSETSTOP (*w, exception_map[stop_exception].sigmap);
+
+ if (exception_map[stop_exception].print || force_print)
+ {
+ target_terminal_ours ();
+
+ printf_filtered ("\n%s received %s exception : ",
+ who,
+ exception_map[stop_exception].name);
+
+ wrap_here (" ");
+
+ switch (stop_exception)
+ {
+ case EXC_BAD_ACCESS:
+ printf_filtered ("referencing address 0x%x : %s\n",
+ stop_subcode,
+ mach_error_string (stop_code));
+ break;
+ case EXC_BAD_INSTRUCTION:
+ printf_filtered
+ ("illegal or undefined instruction. code %d subcode %d\n",
+ stop_code, stop_subcode);
+ break;
+ case EXC_ARITHMETIC:
+ printf_filtered ("code %d\n", stop_code);
+ break;
+ case EXC_EMULATION:
+ printf_filtered ("code %d subcode %d\n", stop_code, stop_subcode);
+ break;
+ case EXC_SOFTWARE:
+ printf_filtered ("%s specific, code 0x%x\n",
+ stop_code < 0xffff ? "hardware" : "os emulation",
+ stop_code);
+ break;
+ case EXC_BREAKPOINT:
+ printf_filtered ("type %d (machine dependent)\n",
+ stop_code);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "Unknown exception");
+ }
+ }
+}
+
+setup_notify_port (int create_new)
+{
+ kern_return_t ret;
+
+ if (MACH_PORT_VALID (our_notify_port))
+ {
+ ret = mach_port_destroy (mach_task_self (), our_notify_port);
+ CHK ("Could not destroy our_notify_port", ret);
+ }
+
+ our_notify_port = MACH_PORT_NULL;
+ notify_chain = (port_chain_t) NULL;
+ port_chain_destroy (port_chain_obstack);
+
+ if (create_new)
+ {
+ ret = mach_port_allocate (mach_task_self (),
+ MACH_PORT_RIGHT_RECEIVE,
+ &our_notify_port);
+ if (ret != KERN_SUCCESS)
+ internal_error (__FILE__, __LINE__,
+ "Creating notify port %s", mach_error_string (ret));
+
+ ret = mach_port_move_member (mach_task_self (),
+ our_notify_port,
+ inferior_wait_port_set);
+ if (ret != KERN_SUCCESS)
+ internal_error (__FILE__, __LINE__,
+ "initial move member %s", mach_error_string (ret));
+ }
+}
+
+/*
+ * Register our message port to the net name server
+ *
+ * Currently used only by the external stop-gdb program
+ * since ^C does not work if you would like to enter
+ * gdb command level while debugging your program.
+ *
+ * NOTE: If the message port is sometimes used for other
+ * purposes also, the NAME must not be a guessable one.
+ * Then, there should be a way to change it.
+ */
+
+char registered_name[MAX_NAME_LEN];
+
+void
+message_port_info (char *args, int from_tty)
+{
+ if (registered_name[0])
+ printf_filtered ("gdb's message port name: '%s'\n",
+ registered_name);
+ else
+ printf_filtered ("gdb's message port is not currently registered\n");
+}
+
+void
+gdb_register_port (char *name, mach_port_t port)
+{
+ kern_return_t ret;
+ static int already_signed = 0;
+ int len;
+
+ if (!MACH_PORT_VALID (port) || !name || !*name)
+ {
+ warning ("Invalid registration request");
+ return;
+ }
+
+ if (!already_signed)
+ {
+ ret = mach_port_insert_right (mach_task_self (),
+ our_message_port,
+ our_message_port,
+ MACH_MSG_TYPE_MAKE_SEND);
+ CHK ("Failed to create a signature to our_message_port", ret);
+ already_signed = 1;
+ }
+ else if (already_signed > 1)
+ {
+ ret = netname_check_out (name_server_port,
+ registered_name,
+ our_message_port);
+ CHK ("Failed to check out gdb's message port", ret);
+ registered_name[0] = '\000';
+ already_signed = 1;
+ }
+
+ ret = netname_check_in (name_server_port, /* Name server port */
+ name, /* Name of service */
+ our_message_port, /* Signature */
+ port); /* Creates a new send right */
+ CHK ("Failed to check in the port", ret);
+
+ len = 0;
+ while (len < MAX_NAME_LEN && *(name + len))
+ {
+ registered_name[len] = *(name + len);
+ len++;
+ }
+ registered_name[len] = '\000';
+ already_signed = 2;
+}
+
+struct cmd_list_element *cmd_thread_list;
+struct cmd_list_element *cmd_task_list;
+
+/*ARGSUSED */
+static void
+thread_command (char *arg, int from_tty)
+{
+ printf_unfiltered ("\"thread\" must be followed by the name of a thread command.\n");
+ help_list (cmd_thread_list, "thread ", -1, gdb_stdout);
+}
+
+/*ARGSUSED */
+static void
+task_command (char *arg, int from_tty)
+{
+ printf_unfiltered ("\"task\" must be followed by the name of a task command.\n");
+ help_list (cmd_task_list, "task ", -1, gdb_stdout);
+}
+
+add_mach_specific_commands (void)
+{
+ /* Thread handling commands */
+
+ /* FIXME: Move our thread support into the generic thread.c stuff so we
+ can share that code. */
+ add_prefix_cmd ("mthread", class_stack, thread_command,
+ "Generic command for handling Mach threads in the debugged task.",
+ &cmd_thread_list, "thread ", 0, &cmdlist);
+
+ add_com_alias ("th", "mthread", class_stack, 1);
+
+ add_cmd ("select", class_stack, thread_select_command,
+ "Select and print MID of the selected thread",
+ &cmd_thread_list);
+ add_cmd ("list", class_stack, thread_list_command,
+ "List info of task's threads. Selected thread is marked with '*'",
+ &cmd_thread_list);
+ add_cmd ("suspend", class_run, thread_suspend_command,
+ "Suspend one or all of the threads in the selected task.",
+ &cmd_thread_list);
+ add_cmd ("resume", class_run, thread_resume_command,
+ "Resume one or all of the threads in the selected task.",
+ &cmd_thread_list);
+ add_cmd ("kill", class_run, thread_kill_command,
+ "Kill the specified thread MID from inferior task.",
+ &cmd_thread_list);
+#if 0
+ /* The rest of this support (condition_thread) was not merged. It probably
+ should not be merged in this form, but instead added to the generic GDB
+ thread support. */
+ add_cmd ("break", class_breakpoint, condition_thread,
+ "Breakpoint N will only be effective for thread MID or @SLOT\n\
+ If MID/@SLOT is omitted allow all threads to break at breakpoint",
+ &cmd_thread_list);
+#endif
+ /* Thread command shorthands (for backward compatibility) */
+ add_alias_cmd ("ts", "mthread select", 0, 0, &cmdlist);
+ add_alias_cmd ("tl", "mthread list", 0, 0, &cmdlist);
+
+ /* task handling commands */
+
+ add_prefix_cmd ("task", class_stack, task_command,
+ "Generic command for handling debugged task.",
+ &cmd_task_list, "task ", 0, &cmdlist);
+
+ add_com_alias ("ta", "task", class_stack, 1);
+
+ add_cmd ("suspend", class_run, task_suspend_command,
+ "Suspend the inferior task.",
+ &cmd_task_list);
+ add_cmd ("resume", class_run, task_resume_command,
+ "Resume the inferior task.",
+ &cmd_task_list);
+ add_cmd ("info", no_class, task_info_command,
+ "Print information about the specified task.",
+ &cmd_task_list);
+
+ /* Print my message port name */
+
+ add_info ("message-port", message_port_info,
+ "Returns the name of gdb's message port in the netnameserver");
+
+ /* Exception commands */
+
+ add_info ("exceptions", exception_info,
+ "What debugger does when program gets various exceptions.\n\
+Specify an exception number as argument to print info on that\n\
+exception only.");
+
+ add_com ("exception", class_run, exception_command,
+ "Specify how to handle an exception.\n\
+Args are exception number followed by \"forward\" or \"keep\".\n\
+`Forward' means forward the exception to the program's normal exception\n\
+handler.\n\
+`Keep' means reenter debugger if this exception happens, and GDB maps\n\
+the exception to some signal (see info exception)\n\
+Normally \"keep\" is used to return to GDB on exception.");
+}
+
+kern_return_t
+do_mach_notify_dead_name (mach_port_t notify, mach_port_t name)
+{
+ kern_return_t kr = KERN_SUCCESS;
+
+ /* Find the thing that notified */
+ port_chain_t element = port_chain_member (notify_chain, name);
+
+ /* Take name of from unreceived dead name notification list */
+ notify_chain = port_chain_delete (notify_chain, name);
+
+ if (!element)
+ error ("Received a dead name notify from unchained port (0x%x)", name);
+
+ switch (element->type)
+ {
+
+ case MACH_TYPE_THREAD:
+ target_terminal_ours_for_output ();
+ if (name == current_thread)
+ {
+ printf_filtered ("\nCurrent thread %d died", element->mid);
+ current_thread = MACH_PORT_NULL;
+ }
+ else
+ printf_filtered ("\nThread %d died", element->mid);
+
+ break;
+
+ case MACH_TYPE_TASK:
+ target_terminal_ours_for_output ();
+ if (name != inferior_task)
+ printf_filtered ("Task %d died, but it was not the selected task",
+ element->mid);
+ else
+ {
+ printf_filtered ("Current task %d died", element->mid);
+
+ mach_port_destroy (mach_task_self (), name);
+ inferior_task = MACH_PORT_NULL;
+
+ if (notify_chain)
+ warning ("There were still unreceived dead_name_notifications???");
+
+ /* Destroy the old notifications */
+ setup_notify_port (0);
+
+ }
+ break;
+
+ default:
+ error ("Unregistered dead_name 0x%x notification received. Type is %d, mid is 0x%x",
+ name, element->type, element->mid);
+ break;
+ }
+
+ return KERN_SUCCESS;
+}
+
+kern_return_t
+do_mach_notify_msg_accepted (mach_port_t notify, mach_port_t name)
+{
+ warning ("do_mach_notify_msg_accepted : notify %x, name %x",
+ notify, name);
+ return KERN_SUCCESS;
+}
+
+kern_return_t
+do_mach_notify_no_senders (mach_port_t notify, mach_port_mscount_t mscount)
+{
+ warning ("do_mach_notify_no_senders : notify %x, mscount %x",
+ notify, mscount);
+ return KERN_SUCCESS;
+}
+
+kern_return_t
+do_mach_notify_port_deleted (mach_port_t notify, mach_port_t name)
+{
+ warning ("do_mach_notify_port_deleted : notify %x, name %x",
+ notify, name);
+ return KERN_SUCCESS;
+}
+
+kern_return_t
+do_mach_notify_port_destroyed (mach_port_t notify, mach_port_t rights)
+{
+ warning ("do_mach_notify_port_destroyed : notify %x, rights %x",
+ notify, rights);
+ return KERN_SUCCESS;
+}
+
+kern_return_t
+do_mach_notify_send_once (mach_port_t notify)
+{
+#ifdef DUMP_SYSCALL
+ /* MANY of these are generated. */
+ warning ("do_mach_notify_send_once : notify %x",
+ notify);
+#endif
+ return KERN_SUCCESS;
+}
+
+/* Kills the inferior. It's gone when you call this */
+static void
+kill_inferior_fast (void)
+{
+ WAITTYPE w;
+
+ if (PIDGET (inferior_ptid) == 0 || PIDGET (inferior_ptid) == 1)
+ return;
+
+ /* kill() it, since the Unix server does not otherwise notice when
+ * killed with task_terminate().
+ */
+ if (PIDGET (inferior_ptid) > 0)
+ kill (PIDGET (inferior_ptid), SIGKILL);
+
+ /* It's propably terminate already */
+ (void) task_terminate (inferior_task);
+
+ inferior_task = MACH_PORT_NULL;
+ current_thread = MACH_PORT_NULL;
+
+ wait3 (&w, WNOHANG, 0);
+
+ setup_notify_port (0);
+}
+
+static void
+m3_kill_inferior (void)
+{
+ kill_inferior_fast ();
+ target_mourn_inferior ();
+}
+
+/* Clean up after the inferior dies. */
+
+static void
+m3_mourn_inferior (void)
+{
+ unpush_target (&m3_ops);
+ generic_mourn_inferior ();
+}
+
+
+/* Fork an inferior process, and start debugging it. */
+
+static void
+m3_create_inferior (char *exec_file, char *allargs, char **env)
+{
+ fork_inferior (exec_file, allargs, env, m3_trace_me, m3_trace_him, NULL, NULL);
+ /* We are at the first instruction we care about. */
+ /* Pedal to the metal... */
+ proceed ((CORE_ADDR) -1, 0, 0);
+}
+
+/* Mark our target-struct as eligible for stray "run" and "attach"
+ commands. */
+static int
+m3_can_run (void)
+{
+ return 1;
+}
+
+/* Mach 3.0 does not need ptrace for anything
+ * Make sure nobody uses it on mach.
+ */
+ptrace (int a, int b, int c, int d)
+{
+ error ("Lose, Lose! Somebody called ptrace\n");
+}
+
+/* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+void
+m3_resume (ptid_t ptid, int step, enum target_signal signal)
+{
+ kern_return_t ret;
+
+ if (step)
+ {
+ thread_basic_info_data_t th_info;
+ unsigned int infoCnt = THREAD_BASIC_INFO_COUNT;
+
+ /* There is no point in single stepping when current_thread
+ * is dead.
+ */
+ if (!MACH_PORT_VALID (current_thread))
+ error ("No thread selected; can not single step");
+
+ /* If current_thread is suspended, tracing it would never return.
+ */
+ ret = thread_info (current_thread,
+ THREAD_BASIC_INFO,
+ (thread_info_t) & th_info,
+ &infoCnt);
+ CHK ("child_resume: can't get thread info", ret);
+
+ if (th_info.suspend_count)
+ error ("Can't trace a suspended thread. Use \"thread resume\" command to resume it");
+ }
+
+ vm_read_cache_valid = FALSE;
+
+ if (signal && PIDGET (inferior_ptid) > 0) /* Do not signal, if attached by MID */
+ kill (PIDGET (inferior_ptid), target_signal_to_host (signal));
+
+ if (step)
+ {
+ suspend_all_threads (0);
+
+ setup_single_step (current_thread, TRUE);
+
+ ret = thread_resume (current_thread);
+ CHK ("thread_resume", ret);
+ }
+
+ ret = task_resume (inferior_task);
+ if (ret == KERN_FAILURE)
+ warning ("Task was not suspended");
+ else
+ CHK ("Resuming task", ret);
+
+ /* HACK HACK This is needed by the multiserver system HACK HACK */
+ while ((ret = task_resume (inferior_task)) == KERN_SUCCESS)
+ /* make sure it really runs */ ;
+ /* HACK HACK This is needed by the multiserver system HACK HACK */
+}
+
+#ifdef ATTACH_DETACH
+
+/* Start debugging the process with the given task */
+void
+task_attach (task_t tid)
+{
+ kern_return_t ret;
+ inferior_task = tid;
+
+ ret = task_suspend (inferior_task);
+ CHK ("task_attach: task_suspend", ret);
+
+ must_suspend_thread = 0;
+
+ setup_notify_port (1);
+
+ request_notify (inferior_task, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_TASK);
+
+ setup_exception_port ();
+
+ emulator_present = have_emulator_p (inferior_task);
+
+ attach_flag = 1;
+}
+
+/* Well, we can call error also here and leave the
+ * target stack inconsistent. Sigh.
+ * Fix this sometime (the only way to fail here is that
+ * the task has no threads at all, which is rare, but
+ * possible; or if the target task has died, which is also
+ * possible, but unlikely, since it has been suspended.
+ * (Someone must have killed it))
+ */
+void
+attach_to_thread (void)
+{
+ if (select_thread (inferior_task, 0, 1) != KERN_SUCCESS)
+ error ("Could not select any threads to attach to");
+}
+
+mid_attach (int mid)
+{
+ kern_return_t ret;
+
+ ret = machid_mach_port (mid_server, mid_auth, mid, &inferior_task);
+ CHK ("mid_attach: machid_mach_port", ret);
+
+ task_attach (inferior_task);
+
+ return mid;
+}
+
+/*
+ * Start debugging the process whose unix process-id is PID.
+ * A negative "pid" value is legal and signifies a mach_id not a unix pid.
+ *
+ * Prevent (possible unwanted) dangerous operations by enabled users
+ * like "atta 0" or "atta foo" (equal to the previous :-) and
+ * "atta pidself". Anyway, the latter is allowed by specifying a MID.
+ */
+static int
+m3_do_attach (int pid)
+{
+ kern_return_t ret;
+
+ if (pid == 0)
+ error ("MID=0, Debugging the master unix server does not compute");
+
+ /* Foo. This assumes gdb has a unix pid */
+ if (pid == getpid ())
+ error ("I will debug myself only by mid. (Gdb would suspend itself!)");
+
+ if (pid < 0)
+ {
+ mid_attach (-(pid));
+
+ /* inferior_ptid will be NEGATIVE! */
+ inferior_ptid = pid_to_ptid (pid);
+
+ return PIDGET (inferior_ptid);
+ }
+
+ inferior_task = task_by_pid (pid);
+ if (!MACH_PORT_VALID (inferior_task))
+ error ("Cannot map Unix pid %d to Mach task port", pid);
+
+ task_attach (inferior_task);
+
+ inferior_ptid = pid_to_ptid (pid);
+
+ return PIDGET (inferior_ptid);
+}
+
+/* Attach to process PID, then initialize for debugging it
+ and wait for the trace-trap that results from attaching. */
+
+static void
+m3_attach (char *args, int from_tty)
+{
+ char *exec_file;
+ int pid;
+
+ if (!args)
+ error_no_arg ("process-id to attach");
+
+ pid = atoi (args);
+
+ if (pid == getpid ()) /* Trying to masturbate? */
+ error ("I refuse to debug myself!");
+
+ if (from_tty)
+ {
+ exec_file = (char *) get_exec_file (0);
+
+ if (exec_file)
+ printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
+ target_pid_to_str (pid_to_ptid (pid)));
+ else
+ printf_unfiltered ("Attaching to %s\n",
+ target_pid_to_str (pid_to_ptid (pid)));
+
+ gdb_flush (gdb_stdout);
+ }
+
+ m3_do_attach (pid_to_ptid (pid));
+ inferior_ptid = pid_to_ptid (pid);
+ push_target (&m3_ops);
+}
+
+void
+deallocate_inferior_ports (void)
+{
+ kern_return_t ret;
+ thread_array_t thread_list;
+ int thread_count, index;
+
+ if (!MACH_PORT_VALID (inferior_task))
+ return;
+
+ ret = task_threads (inferior_task, &thread_list, &thread_count);
+ if (ret != KERN_SUCCESS)
+ {
+ warning ("deallocate_inferior_ports: task_threads",
+ mach_error_string (ret));
+ return;
+ }
+
+ /* Get rid of send rights to task threads */
+ for (index = 0; index < thread_count; index++)
+ {
+ int rights;
+ ret = mach_port_get_refs (mach_task_self (),
+ thread_list[index],
+ MACH_PORT_RIGHT_SEND,
+ &rights);
+ CHK ("deallocate_inferior_ports: get refs", ret);
+
+ if (rights > 0)
+ {
+ ret = mach_port_mod_refs (mach_task_self (),
+ thread_list[index],
+ MACH_PORT_RIGHT_SEND,
+ -rights);
+ CHK ("deallocate_inferior_ports: mod refs", ret);
+ }
+ }
+
+ ret = mach_port_mod_refs (mach_task_self (),
+ inferior_exception_port,
+ MACH_PORT_RIGHT_RECEIVE,
+ -1);
+ CHK ("deallocate_inferior_ports: cannot get rid of exception port", ret);
+
+ ret = mach_port_deallocate (mach_task_self (),
+ inferior_task);
+ CHK ("deallocate_task_port: deallocating inferior_task", ret);
+
+ current_thread = MACH_PORT_NULL;
+ inferior_task = MACH_PORT_NULL;
+}
+
+/* Stop debugging the process whose number is PID
+ and continue it with signal number SIGNAL.
+ SIGNAL = 0 means just continue it. */
+
+static void
+m3_do_detach (int signal)
+{
+ kern_return_t ret;
+
+ MACH_ERROR_NO_INFERIOR;
+
+ if (current_thread != MACH_PORT_NULL)
+ {
+ /* Store the gdb's view of the thread we are deselecting
+ * before we detach.
+ * @@ I am really not sure if this is ever needeed.
+ */
+ target_prepare_to_store ();
+ target_store_registers (-1);
+ }
+
+ ret = task_set_special_port (inferior_task,
+ TASK_EXCEPTION_PORT,
+ inferior_old_exception_port);
+ CHK ("task_set_special_port", ret);
+
+ /* Discard all requested notifications */
+ setup_notify_port (0);
+
+ if (remove_breakpoints ())
+ warning ("Could not remove breakpoints when detaching");
+
+ if (signal && PIDGET (inferior_ptid) > 0)
+ kill (PIDGET (inferior_ptid), signal);
+
+ /* the task might be dead by now */
+ (void) task_resume (inferior_task);
+
+ deallocate_inferior_ports ();
+
+ attach_flag = 0;
+}
+
+/* Take a program previously attached to and detaches it.
+ The program resumes execution and will no longer stop
+ on signals, etc. We'd better not have left any breakpoints
+ in the program or it'll die when it hits one. For this
+ to work, it may be necessary for the process to have been
+ previously attached. It *might* work if the program was
+ started via fork. */
+
+static void
+m3_detach (char *args, int from_tty)
+{
+ int siggnal = 0;
+
+ 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_ptid));
+ gdb_flush (gdb_stdout);
+ }
+ if (args)
+ siggnal = atoi (args);
+
+ m3_do_detach (siggnal);
+ inferior_ptid = null_ptid;
+ unpush_target (&m3_ops); /* Pop out of handling an inferior */
+}
+#endif /* ATTACH_DETACH */
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+static void
+m3_prepare_to_store (void)
+{
+#ifdef CHILD_PREPARE_TO_STORE
+ CHILD_PREPARE_TO_STORE ();
+#endif
+}
+
+/* Print status information about what we're accessing. */
+
+static void
+m3_files_info (struct target_ops *ignore)
+{
+ /* FIXME: should print MID and all that crap. */
+ printf_unfiltered ("\tUsing the running image of %s %s.\n",
+ attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
+}
+
+static void
+m3_open (char *arg, int from_tty)
+{
+ error ("Use the \"run\" command to start a Unix child process.");
+}
+
+#ifdef DUMP_SYSCALL
+#define STR(x) #x
+
+char *bsd1_names[] =
+{
+ "execve",
+ "fork",
+ "take_signal",
+ "sigreturn",
+ "getrusage",
+ "chdir",
+ "chroot",
+ "open",
+ "creat",
+ "mknod",
+ "link",
+ "symlink",
+ "unlink",
+ "access",
+ "stat",
+ "readlink",
+ "chmod",
+ "chown",
+ "utimes",
+ "truncate",
+ "rename",
+ "mkdir",
+ "rmdir",
+ "xutimes",
+ "mount",
+ "umount",
+ "acct",
+ "setquota",
+ "write_short",
+ "write_long",
+ "send_short",
+ "send_long",
+ "sendto_short",
+ "sendto_long",
+ "select",
+ "task_by_pid",
+ "recvfrom_short",
+ "recvfrom_long",
+ "setgroups",
+ "setrlimit",
+ "sigvec",
+ "sigstack",
+ "settimeofday",
+ "adjtime",
+ "setitimer",
+ "sethostname",
+ "bind",
+ "accept",
+ "connect",
+ "setsockopt",
+ "getsockopt",
+ "getsockname",
+ "getpeername",
+ "init_process",
+ "table_set",
+ "table_get",
+ "pioctl",
+ "emulator_error",
+ "readwrite",
+ "share_wakeup",
+ 0,
+ "maprw_request_it",
+ "maprw_release_it",
+ "maprw_remap",
+ "pid_by_task",
+};
+
+int bsd1_nnames = sizeof (bsd1_names) / sizeof (bsd1_names[0]);
+
+char *
+name_str (int name, char *buf)
+{
+ switch (name)
+ {
+ case MACH_MSG_TYPE_BOOLEAN:
+ return "boolean";
+ case MACH_MSG_TYPE_INTEGER_16:
+ return "short";
+ case MACH_MSG_TYPE_INTEGER_32:
+ return "long";
+ case MACH_MSG_TYPE_CHAR:
+ return "char";
+ case MACH_MSG_TYPE_BYTE:
+ return "byte";
+ case MACH_MSG_TYPE_REAL:
+ return "real";
+ case MACH_MSG_TYPE_STRING:
+ return "string";
+ default:
+ sprintf (buf, "%d", name);
+ return buf;
+ }
+}
+
+char *
+id_str (int id, char *buf)
+{
+ char *p;
+ if (id >= 101000 && id < 101000 + bsd1_nnames)
+ {
+ if (p = bsd1_names[id - 101000])
+ return p;
+ }
+ if (id == 102000)
+ return "psignal_retry";
+ if (id == 100000)
+ return "syscall";
+ sprintf (buf, "%d", id);
+ return buf;
+}
+
+print_msg (mach_msg_header_t *mp)
+{
+ char *fmt_x = "%20s : 0x%08x\n";
+ char *fmt_d = "%20s : %10d\n";
+ char *fmt_s = "%20s : %s\n";
+ char buf[100];
+
+ puts_filtered ("\n");
+#define pr(fmt,h,x) printf_filtered(fmt,STR(x),(h).x)
+ pr (fmt_x, (*mp), msgh_bits);
+ pr (fmt_d, (*mp), msgh_size);
+ pr (fmt_x, (*mp), msgh_remote_port);
+ pr (fmt_x, (*mp), msgh_local_port);
+ pr (fmt_d, (*mp), msgh_kind);
+ printf_filtered (fmt_s, STR (msgh_id), id_str (mp->msgh_id, buf));
+
+ if (debug_level > 1)
+ {
+ char *p, *ep, *dp;
+ int plen;
+ p = (char *) mp;
+ ep = p + mp->msgh_size;
+ p += sizeof (*mp);
+ for (; p < ep; p += plen)
+ {
+ mach_msg_type_t *tp;
+ mach_msg_type_long_t *tlp;
+ int name, size, number;
+ tp = (mach_msg_type_t *) p;
+ if (tp->msgt_longform)
+ {
+ tlp = (mach_msg_type_long_t *) tp;
+ name = tlp->msgtl_name;
+ size = tlp->msgtl_size;
+ number = tlp->msgtl_number;
+ plen = sizeof (*tlp);
+ }
+ else
+ {
+ name = tp->msgt_name;
+ size = tp->msgt_size;
+ number = tp->msgt_number;
+ plen = sizeof (*tp);
+ }
+ printf_filtered ("name=%-16s size=%2d number=%7d inline=%d long=%d deal=%d\n",
+ name_str (name, buf), size, number, tp->msgt_inline,
+ tp->msgt_longform, tp->msgt_deallocate);
+ dp = p + plen;
+ if (tp->msgt_inline)
+ {
+ int l;
+ l = size * number / 8;
+ l = (l + sizeof (long) - 1) & ~((sizeof (long)) - 1);
+ plen += l;
+ print_data (dp, size, number);
+ }
+ else
+ {
+ plen += sizeof (int *);
+ }
+ printf_filtered ("plen=%d\n", plen);
+ }
+ }
+}
+
+print_data (char *p, int size, int number)
+{
+ int *ip;
+ short *sp;
+ int i;
+
+ switch (size)
+ {
+ case 8:
+ for (i = 0; i < number; i++)
+ {
+ printf_filtered (" %02x", p[i]);
+ }
+ break;
+ case 16:
+ sp = (short *) p;
+ for (i = 0; i < number; i++)
+ {
+ printf_filtered (" %04x", sp[i]);
+ }
+ break;
+ case 32:
+ ip = (int *) p;
+ for (i = 0; i < number; i++)
+ {
+ printf_filtered (" %08x", ip[i]);
+ }
+ break;
+ }
+ puts_filtered ("\n");
+}
+#endif /* DUMP_SYSCALL */
+
+static void
+m3_stop (void)
+{
+ error ("to_stop target function not implemented");
+}
+
+static char *
+m3_pid_to_exec_file (int pid)
+{
+ error ("to_pid_to_exec_file target function not implemented");
+ return NULL; /* To keep all compilers happy. */
+}
+
+static void
+init_m3_ops (void)
+{
+ m3_ops.to_shortname = "mach";
+ m3_ops.to_longname = "Mach child process";
+ m3_ops.to_doc = "Mach child process (started by the \"run\" command).";
+ m3_ops.to_open = m3_open;
+ m3_ops.to_attach = m3_attach;
+ m3_ops.to_detach = m3_detach;
+ m3_ops.to_resume = m3_resume;
+ m3_ops.to_wait = mach_really_wait;
+ m3_ops.to_fetch_registers = fetch_inferior_registers;
+ m3_ops.to_store_registers = store_inferior_registers;
+ m3_ops.to_prepare_to_store = m3_prepare_to_store;
+ m3_ops.to_xfer_memory = m3_xfer_memory;
+ m3_ops.to_files_info = m3_files_info;
+ m3_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ m3_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ m3_ops.to_terminal_init = terminal_init_inferior;
+ m3_ops.to_terminal_inferior = terminal_inferior;
+ m3_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ m3_ops.to_terminal_ours = terminal_ours;
+ m3_ops.to_terminal_info = child_terminal_info;
+ m3_ops.to_kill = m3_kill_inferior;
+ m3_ops.to_create_inferior = m3_create_inferior;
+ m3_ops.to_mourn_inferior = m3_mourn_inferior;
+ m3_ops.to_can_run = m3_can_run;
+ m3_ops.to_stop = m3_stop;
+ m3_ops.to_pid_to_exec_file = m3_pid_to_exec_file;
+ m3_ops.to_stratum = process_stratum;
+ m3_ops.to_has_all_memory = 1;
+ m3_ops.to_has_memory = 1;
+ m3_ops.to_has_stack = 1;
+ m3_ops.to_has_registers = 1;
+ m3_ops.to_has_execution = 1;
+ m3_ops.to_magic = OPS_MAGIC;
+}
+
+void
+_initialize_m3_nat (void)
+{
+ kern_return_t ret;
+
+ init_m3_ops ();
+ add_target (&m3_ops);
+
+ ret = mach_port_allocate (mach_task_self (),
+ MACH_PORT_RIGHT_PORT_SET,
+ &inferior_wait_port_set);
+ if (ret != KERN_SUCCESS)
+ internal_error (__FILE__, __LINE__,
+ "initial port set %s", mach_error_string (ret));
+
+ /* mach_really_wait now waits for this */
+ currently_waiting_for = inferior_wait_port_set;
+
+ ret = netname_look_up (name_server_port, hostname, "MachID", &mid_server);
+ if (ret != KERN_SUCCESS)
+ {
+ mid_server = MACH_PORT_NULL;
+
+ warning ("initialize machid: netname_lookup_up(MachID) : %s",
+ mach_error_string (ret));
+ warning ("Some (most?) features disabled...");
+ }
+
+ mid_auth = mach_privileged_host_port ();
+ if (mid_auth == MACH_PORT_NULL)
+ mid_auth = mach_task_self ();
+
+ obstack_init (port_chain_obstack);
+
+ ret = mach_port_allocate (mach_task_self (),
+ MACH_PORT_RIGHT_RECEIVE,
+ &thread_exception_port);
+ CHK ("Creating thread_exception_port for single stepping", ret);
+
+ ret = mach_port_insert_right (mach_task_self (),
+ thread_exception_port,
+ thread_exception_port,
+ MACH_MSG_TYPE_MAKE_SEND);
+ CHK ("Inserting send right to thread_exception_port", ret);
+
+ /* Allocate message port */
+ ret = mach_port_allocate (mach_task_self (),
+ MACH_PORT_RIGHT_RECEIVE,
+ &our_message_port);
+ if (ret != KERN_SUCCESS)
+ warning ("Creating message port %s", mach_error_string (ret));
+ else
+ {
+ char buf[MAX_NAME_LEN];
+ ret = mach_port_move_member (mach_task_self (),
+ our_message_port,
+ inferior_wait_port_set);
+ if (ret != KERN_SUCCESS)
+ warning ("message move member %s", mach_error_string (ret));
+
+
+ /* @@@@ No way to change message port name currently */
+ /* Foo. This assumes gdb has a unix pid */
+ sprintf (buf, "gdb-%d", getpid ());
+ gdb_register_port (buf, our_message_port);
+ }
+
+ /* Heap for thread commands */
+ obstack_init (cproc_obstack);
+
+ add_mach_specific_commands ();
+}
diff --git a/gdb/m32r-rom.c b/gdb/m32r-rom.c
new file mode 100644
index 00000000000..b4bfefdf210
--- /dev/null
+++ b/gdb/m32r-rom.c
@@ -0,0 +1,626 @@
+/* Remote debugging interface to m32r and mon2000 ROM monitors for GDB,
+ the GNU debugger.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+
+ Adapted by Michael Snyder of 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 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. */
+
+/* This module defines communication with the Mitsubishi m32r monitor */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "symtab.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "symfile.h" /* for generic load */
+#include <time.h> /* for time_t */
+#include "gdb_string.h"
+#include "objfiles.h" /* for ALL_OBJFILES etc. */
+#include "inferior.h" /* for write_pc() */
+#include <ctype.h>
+#include "regcache.h"
+
+extern void report_transfer_performance (unsigned long, time_t, time_t);
+
+/*
+ * All this stuff just to get my host computer's IP address!
+ */
+#include <sys/types.h>
+#include <netdb.h> /* for hostent */
+#include <netinet/in.h> /* for struct in_addr */
+#if 1
+#include <arpa/inet.h> /* for inet_ntoa */
+#endif
+
+static char *board_addr; /* user-settable IP address for M32R-EVA */
+static char *server_addr; /* user-settable IP address for gdb host */
+static char *download_path; /* user-settable path for SREC files */
+
+
+/*
+ * Function: m32r_load_1 (helper function)
+ */
+
+static void
+m32r_load_section (bfd *abfd, asection *s, void *obj)
+{
+ unsigned int *data_count = obj;
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_size_type section_size = bfd_section_size (abfd, s);
+ bfd_vma section_base = bfd_section_lma (abfd, s);
+ unsigned int buffer, i;
+
+ *data_count += section_size;
+
+ printf_filtered ("Loading section %s, size 0x%lx lma ",
+ bfd_section_name (abfd, s), section_size);
+ print_address_numeric (section_base, 1, gdb_stdout);
+ printf_filtered ("\n");
+ gdb_flush (gdb_stdout);
+ monitor_printf ("%s mw\r", paddr_nz (section_base));
+ for (i = 0; i < section_size; i += 4)
+ {
+ QUIT;
+ monitor_expect (" -> ", NULL, 0);
+ bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4);
+ monitor_printf ("%x\n", buffer);
+ }
+ monitor_expect (" -> ", NULL, 0);
+ monitor_printf ("q\n");
+ monitor_expect_prompt (NULL, 0);
+ }
+}
+
+static int
+m32r_load_1 (void *dummy)
+{
+ int data_count = 0;
+
+ bfd_map_over_sections ((bfd *) dummy, m32r_load_section, &data_count);
+ return data_count;
+}
+
+/*
+ * Function: m32r_load (an alternate way to load)
+ */
+
+static void
+m32r_load (char *filename, int from_tty)
+{
+ bfd *abfd;
+ asection *s;
+ unsigned int i, data_count = 0;
+ time_t start_time, end_time; /* for timing of download */
+
+ if (filename == NULL || filename[0] == 0)
+ filename = get_exec_file (1);
+
+ abfd = bfd_openr (filename, 0);
+ if (!abfd)
+ error ("Unable to open file %s\n", filename);
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ error ("File is not an object file\n");
+ start_time = time (NULL);
+#if 0
+ for (s = abfd->sections; s; s = s->next)
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_size_type section_size = bfd_section_size (abfd, s);
+ bfd_vma section_base = bfd_section_vma (abfd, s);
+ unsigned int buffer;
+
+ data_count += section_size;
+
+ printf_filtered ("Loading section %s, size 0x%lx vma ",
+ bfd_section_name (abfd, s), section_size);
+ print_address_numeric (section_base, 1, gdb_stdout);
+ printf_filtered ("\n");
+ gdb_flush (gdb_stdout);
+ monitor_printf ("%x mw\r", section_base);
+ for (i = 0; i < section_size; i += 4)
+ {
+ monitor_expect (" -> ", NULL, 0);
+ bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4);
+ monitor_printf ("%x\n", buffer);
+ }
+ monitor_expect (" -> ", NULL, 0);
+ monitor_printf ("q\n");
+ monitor_expect_prompt (NULL, 0);
+ }
+#else
+ if (!(catch_errors (m32r_load_1, abfd, "Load aborted!\n", RETURN_MASK_ALL)))
+ {
+ monitor_printf ("q\n");
+ return;
+ }
+#endif
+ end_time = time (NULL);
+ printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd));
+ report_transfer_performance (data_count, start_time, end_time);
+
+ /* Finally, make the PC point at the start address */
+ if (exec_bfd)
+ write_pc (bfd_get_start_address (exec_bfd));
+
+ inferior_ptid = null_ptid; /* No process now */
+
+ /* This is necessary because many things were based on the PC at the
+ time that we attached to the monitor, which is no longer valid
+ now that we have loaded new code (and just changed the PC).
+ Another way to do this might be to call normal_stop, except that
+ the stack may not be valid, and things would get horribly
+ confused... */
+
+ clear_symtab_users ();
+}
+
+static void
+m32r_load_gen (char *filename, int from_tty)
+{
+ generic_load (filename, from_tty);
+}
+
+static void m32r_open (char *args, int from_tty);
+static void mon2000_open (char *args, int from_tty);
+
+/* This array of registers needs to match the indexes used by GDB. The
+ whole reason this exists is because the various ROM monitors use
+ different names than GDB does, and don't support all the registers
+ either. So, typing "info reg sp" becomes an "A7". */
+
+static char *m32r_regnames[] =
+{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "psw", "cbr", "spi", "spu", "bpc", "pc", "accl", "acch",
+};
+
+static void
+m32r_supply_register (char *regname, int regnamelen, char *val, int vallen)
+{
+ int regno;
+ int num_regs = sizeof (m32r_regnames) / sizeof (m32r_regnames[0]);
+
+ for (regno = 0; regno < num_regs; regno++)
+ if (strncmp (regname, m32r_regnames[regno], regnamelen) == 0)
+ break;
+
+ if (regno >= num_regs)
+ return; /* no match */
+
+ if (regno == ACCL_REGNUM)
+ { /* special handling for 64-bit acc reg */
+ monitor_supply_register (ACCH_REGNUM, val);
+ val = strchr (val, ':'); /* skip past ':' to get 2nd word */
+ if (val != NULL)
+ monitor_supply_register (ACCL_REGNUM, val + 1);
+ }
+ else
+ {
+ monitor_supply_register (regno, val);
+ if (regno == PSW_REGNUM)
+ {
+ unsigned long psw = strtoul (val, NULL, 16);
+ char *zero = "00000000", *one = "00000001";
+
+#ifdef SM_REGNUM
+ /* Stack mode bit */
+ monitor_supply_register (SM_REGNUM, (psw & 0x80) ? one : zero);
+#endif
+#ifdef BSM_REGNUM
+ /* Backup stack mode bit */
+ monitor_supply_register (BSM_REGNUM, (psw & 0x8000) ? one : zero);
+#endif
+#ifdef IE_REGNUM
+ /* Interrupt enable bit */
+ monitor_supply_register (IE_REGNUM, (psw & 0x40) ? one : zero);
+#endif
+#ifdef BIE_REGNUM
+ /* Backup interrupt enable bit */
+ monitor_supply_register (BIE_REGNUM, (psw & 0x4000) ? one : zero);
+#endif
+#ifdef COND_REGNUM
+ /* Condition bit (carry etc.) */
+ monitor_supply_register (COND_REGNUM, (psw & 0x1) ? one : zero);
+#endif
+#ifdef CBR_REGNUM
+ monitor_supply_register (CBR_REGNUM, (psw & 0x1) ? one : zero);
+#endif
+#ifdef BPC_REGNUM
+ monitor_supply_register (BPC_REGNUM, zero); /* KLUDGE: (???????) */
+#endif
+#ifdef BCARRY_REGNUM
+ monitor_supply_register (BCARRY_REGNUM, zero); /* KLUDGE: (??????) */
+#endif
+ }
+
+ if (regno == SPI_REGNUM || regno == SPU_REGNUM)
+ { /* special handling for stack pointer (spu or spi) */
+ unsigned long stackmode = read_register (PSW_REGNUM) & 0x80;
+
+ if (regno == SPI_REGNUM && !stackmode) /* SP == SPI */
+ monitor_supply_register (SP_REGNUM, val);
+ else if (regno == SPU_REGNUM && stackmode) /* SP == SPU */
+ monitor_supply_register (SP_REGNUM, val);
+ }
+ }
+}
+
+/* m32r RevC board monitor */
+
+static struct target_ops m32r_ops;
+
+static char *m32r_inits[] =
+{"\r", NULL};
+
+static struct monitor_ops m32r_cmds;
+
+static void
+init_m32r_cmds (void)
+{
+ m32r_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST;
+ m32r_cmds.init = m32r_inits; /* Init strings */
+ m32r_cmds.cont = "go\r"; /* continue command */
+ m32r_cmds.step = "step\r"; /* single step */
+ m32r_cmds.stop = NULL; /* interrupt command */
+ m32r_cmds.set_break = "%x +bp\r"; /* set a breakpoint */
+ m32r_cmds.clr_break = "%x -bp\r"; /* clear a breakpoint */
+ m32r_cmds.clr_all_break = "bpoff\r"; /* clear all breakpoints */
+ m32r_cmds.fill = "%x %x %x fill\r"; /* fill (start length val) */
+ m32r_cmds.setmem.cmdb = "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) */
+ m32r_cmds.setmem.cmdw = "%x 1 %x fillh\r"; /* setmem.cmdw (addr, value) */
+ m32r_cmds.setmem.cmdl = "%x 1 %x fillw\r"; /* setmem.cmdl (addr, value) */
+ m32r_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ m32r_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */
+ m32r_cmds.setmem.term = NULL; /* setmem.term */
+ m32r_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */
+ m32r_cmds.getmem.cmdb = "%x %x dump\r"; /* getmem.cmdb (addr, len) */
+ m32r_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */
+ m32r_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */
+ m32r_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ m32r_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
+ m32r_cmds.getmem.term = NULL; /* getmem.term */
+ m32r_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
+ m32r_cmds.setreg.cmd = "%x to %%%s\r"; /* setreg.cmd (name, value) */
+ m32r_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ m32r_cmds.setreg.term = NULL; /* setreg.term */
+ m32r_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
+ m32r_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */
+ m32r_cmds.getreg.resp_delim = NULL; /* getreg.resp_delim */
+ m32r_cmds.getreg.term = NULL; /* getreg.term */
+ m32r_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
+ m32r_cmds.dump_registers = ".reg\r"; /* dump_registers */
+ m32r_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
+ m32r_cmds.supply_register = m32r_supply_register; /* supply_register */
+ m32r_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ m32r_cmds.load = NULL; /* download command */
+ m32r_cmds.loadresp = NULL; /* load response */
+ m32r_cmds.prompt = "ok "; /* monitor command prompt */
+ m32r_cmds.line_term = "\r"; /* end-of-line terminator */
+ m32r_cmds.cmd_end = NULL; /* optional command terminator */
+ m32r_cmds.target = &m32r_ops; /* target operations */
+ m32r_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ m32r_cmds.regnames = m32r_regnames; /* registers names */
+ m32r_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+} /* init_m32r_cmds */
+
+static void
+m32r_open (char *args, int from_tty)
+{
+ monitor_open (args, &m32r_cmds, from_tty);
+}
+
+/* Mon2000 monitor (MSA2000 board) */
+
+static struct target_ops mon2000_ops;
+static struct monitor_ops mon2000_cmds;
+
+static void
+init_mon2000_cmds (void)
+{
+ mon2000_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST;
+ mon2000_cmds.init = m32r_inits; /* Init strings */
+ mon2000_cmds.cont = "go\r"; /* continue command */
+ mon2000_cmds.step = "step\r"; /* single step */
+ mon2000_cmds.stop = NULL; /* interrupt command */
+ mon2000_cmds.set_break = "%x +bp\r"; /* set a breakpoint */
+ mon2000_cmds.clr_break = "%x -bp\r"; /* clear a breakpoint */
+ mon2000_cmds.clr_all_break = "bpoff\r"; /* clear all breakpoints */
+ mon2000_cmds.fill = "%x %x %x fill\r"; /* fill (start length val) */
+ mon2000_cmds.setmem.cmdb = "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) */
+ mon2000_cmds.setmem.cmdw = "%x 1 %x fillh\r"; /* setmem.cmdw (addr, value) */
+ mon2000_cmds.setmem.cmdl = "%x 1 %x fillw\r"; /* setmem.cmdl (addr, value) */
+ mon2000_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ mon2000_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */
+ mon2000_cmds.setmem.term = NULL; /* setmem.term */
+ mon2000_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */
+ mon2000_cmds.getmem.cmdb = "%x %x dump\r"; /* getmem.cmdb (addr, len) */
+ mon2000_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */
+ mon2000_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */
+ mon2000_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ mon2000_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
+ mon2000_cmds.getmem.term = NULL; /* getmem.term */
+ mon2000_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
+ mon2000_cmds.setreg.cmd = "%x to %%%s\r"; /* setreg.cmd (name, value) */
+ mon2000_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ mon2000_cmds.setreg.term = NULL; /* setreg.term */
+ mon2000_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
+ mon2000_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */
+ mon2000_cmds.getreg.resp_delim = NULL; /* getreg.resp_delim */
+ mon2000_cmds.getreg.term = NULL; /* getreg.term */
+ mon2000_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
+ mon2000_cmds.dump_registers = ".reg\r"; /* dump_registers */
+ mon2000_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
+ mon2000_cmds.supply_register = m32r_supply_register; /* supply_register */
+ mon2000_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ mon2000_cmds.load = NULL; /* download command */
+ mon2000_cmds.loadresp = NULL; /* load response */
+ mon2000_cmds.prompt = "Mon2000>"; /* monitor command prompt */
+ mon2000_cmds.line_term = "\r"; /* end-of-line terminator */
+ mon2000_cmds.cmd_end = NULL; /* optional command terminator */
+ mon2000_cmds.target = &mon2000_ops; /* target operations */
+ mon2000_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ mon2000_cmds.regnames = m32r_regnames; /* registers names */
+ mon2000_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+} /* init_mon2000_cmds */
+
+static void
+mon2000_open (char *args, int from_tty)
+{
+ monitor_open (args, &mon2000_cmds, from_tty);
+}
+
+/* Function: set_board_address
+ Tell the BootOne monitor what it's ethernet IP address is. */
+
+static void
+m32r_set_board_address (char *args, int from_tty)
+{
+ int resp_len;
+ char buf[1024];
+
+ if (args && *args)
+ {
+ monitor_printf ("ulip %s\n", args);
+ resp_len = monitor_expect_prompt (buf, sizeof (buf));
+ /* now parse the result for success */
+ }
+ else
+ error ("Requires argument (IP address for M32R-EVA board)");
+}
+
+/* Function: set_server_address
+ Tell the BootOne monitor what gdb's ethernet IP address is. */
+
+static void
+m32r_set_server_address (char *args, int from_tty)
+{
+ int resp_len;
+ char buf[1024];
+
+ if (args && *args)
+ {
+ monitor_printf ("uhip %s\n", args);
+ resp_len = monitor_expect_prompt (buf, sizeof (buf));
+ /* now parse the result for success */
+ }
+ else
+ error ("Requires argument (IP address of GDB's host computer)");
+}
+
+/* Function: set_download_path
+ Tell the BootOne monitor the default path for downloadable SREC files. */
+
+static void
+m32r_set_download_path (char *args, int from_tty)
+{
+ int resp_len;
+ char buf[1024];
+
+ if (args && *args)
+ {
+ monitor_printf ("up %s\n", args);
+ resp_len = monitor_expect_prompt (buf, sizeof (buf));
+ /* now parse the result for success */
+ }
+ else
+ error ("Requires argument (default path for downloadable SREC files)");
+}
+
+static void
+m32r_upload_command (char *args, int from_tty)
+{
+ bfd *abfd;
+ asection *s;
+ time_t start_time, end_time; /* for timing of download */
+ int resp_len, data_count = 0;
+ char buf[1024];
+ struct hostent *hostent;
+ struct in_addr inet_addr;
+
+ /* first check to see if there's an ethernet port! */
+ monitor_printf ("ust\r");
+ resp_len = monitor_expect_prompt (buf, sizeof (buf));
+ if (!strchr (buf, ':'))
+ error ("No ethernet connection!");
+
+ if (board_addr == 0)
+ {
+ /* scan second colon in the output from the "ust" command */
+ char *myIPaddress = strchr (strchr (buf, ':') + 1, ':') + 1;
+
+ while (isspace (*myIPaddress))
+ myIPaddress++;
+
+ if (!strncmp (myIPaddress, "0.0.", 4)) /* empty */
+ error ("Please use 'set board-address' to set the M32R-EVA board's IP address.");
+ if (strchr (myIPaddress, '('))
+ *(strchr (myIPaddress, '(')) = '\0'; /* delete trailing junk */
+ board_addr = xstrdup (myIPaddress);
+ }
+ if (server_addr == 0)
+ {
+ buf[0] = 0;
+ gethostname (buf, sizeof (buf));
+ if (buf[0] != 0)
+ hostent = gethostbyname (buf);
+ if (hostent != 0)
+ {
+#if 1
+ memcpy (&inet_addr.s_addr, hostent->h_addr,
+ sizeof (inet_addr.s_addr));
+ server_addr = (char *) inet_ntoa (inet_addr);
+#else
+ server_addr = (char *) inet_ntoa (hostent->h_addr);
+#endif
+ }
+ if (server_addr == 0) /* failed? */
+ error ("Need to know gdb host computer's IP address (use 'set server-address')");
+ }
+
+ if (args == 0 || args[0] == 0) /* no args: upload the current file */
+ args = get_exec_file (1);
+
+ if (args[0] != '/' && download_path == 0)
+ {
+ if (current_directory)
+ download_path = xstrdup (current_directory);
+ else
+ error ("Need to know default download path (use 'set download-path')");
+ }
+
+ start_time = time (NULL);
+ monitor_printf ("uhip %s\r", server_addr);
+ resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */
+ monitor_printf ("ulip %s\r", board_addr);
+ resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */
+ if (args[0] != '/')
+ monitor_printf ("up %s\r", download_path); /* use default path */
+ else
+ monitor_printf ("up\r"); /* rooted filename/path */
+ resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */
+
+ if (strrchr (args, '.') && !strcmp (strrchr (args, '.'), ".srec"))
+ monitor_printf ("ul %s\r", args);
+ else /* add ".srec" suffix */
+ monitor_printf ("ul %s.srec\r", args);
+ resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */
+
+ if (buf[0] == 0 || strstr (buf, "complete") == 0)
+ error ("Upload file not found: %s.srec\nCheck IP addresses and download path.", args);
+ else
+ printf_filtered (" -- Ethernet load complete.\n");
+
+ end_time = time (NULL);
+ abfd = bfd_openr (args, 0);
+ if (abfd != NULL)
+ { /* Download is done -- print section statistics */
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ {
+ printf_filtered ("File is not an object file\n");
+ }
+ for (s = abfd->sections; s; s = s->next)
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_size_type section_size = bfd_section_size (abfd, s);
+ bfd_vma section_base = bfd_section_lma (abfd, s);
+ unsigned int buffer;
+
+ data_count += section_size;
+
+ printf_filtered ("Loading section %s, size 0x%lx lma ",
+ bfd_section_name (abfd, s), section_size);
+ print_address_numeric (section_base, 1, gdb_stdout);
+ printf_filtered ("\n");
+ gdb_flush (gdb_stdout);
+ }
+ /* Finally, make the PC point at the start address */
+ write_pc (bfd_get_start_address (abfd));
+ report_transfer_performance (data_count, start_time, end_time);
+ printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd));
+ }
+ inferior_ptid = null_ptid; /* No process now */
+
+ /* This is necessary because many things were based on the PC at the
+ time that we attached to the monitor, which is no longer valid
+ now that we have loaded new code (and just changed the PC).
+ Another way to do this might be to call normal_stop, except that
+ the stack may not be valid, and things would get horribly
+ confused... */
+
+ clear_symtab_users ();
+}
+
+void
+_initialize_m32r_rom (void)
+{
+ /* Initialize m32r RevC monitor target */
+ init_m32r_cmds ();
+ init_monitor_ops (&m32r_ops);
+
+ m32r_ops.to_shortname = "m32r";
+ m32r_ops.to_longname = "m32r monitor";
+ m32r_ops.to_load = m32r_load_gen; /* monitor lacks a download command */
+ m32r_ops.to_doc = "Debug via the m32r monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ m32r_ops.to_open = m32r_open;
+ add_target (&m32r_ops);
+
+ /* Initialize mon2000 monitor target */
+ init_mon2000_cmds ();
+ init_monitor_ops (&mon2000_ops);
+
+ mon2000_ops.to_shortname = "mon2000";
+ mon2000_ops.to_longname = "Mon2000 monitor";
+ mon2000_ops.to_load = m32r_load_gen; /* monitor lacks a download command */
+ mon2000_ops.to_doc = "Debug via the Mon2000 monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ mon2000_ops.to_open = mon2000_open;
+ add_target (&mon2000_ops);
+
+ add_show_from_set
+ (add_set_cmd ("download-path", class_obscure, var_string,
+ (char *) &download_path,
+ "Set the default path for downloadable SREC files.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("board-address", class_obscure, var_string,
+ (char *) &board_addr,
+ "Set IP address for M32R-EVA target board.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("server-address", class_obscure, var_string,
+ (char *) &server_addr,
+ "Set IP address for download server (GDB's host computer).",
+ &setlist),
+ &showlist);
+
+ add_com ("upload", class_obscure, m32r_upload_command,
+ "Upload the srec file via the monitor's Ethernet upload capability.");
+
+ add_com ("tload", class_obscure, m32r_load, "test upload command.");
+}
diff --git a/gdb/m32r-stub.c b/gdb/m32r-stub.c
new file mode 100644
index 00000000000..cb956264d67
--- /dev/null
+++ b/gdb/m32r-stub.c
@@ -0,0 +1,1711 @@
+/****************************************************************************
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ HP offers the following for use in the public domain. HP makes no
+ warranty with regard to the software or it's performance and the
+ user accepts the software "AS IS" with all faults.
+
+ HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+ TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ * Module name: remcom.c $
+ * Revision: 1.34 $
+ * Date: 91/03/09 12:29:49 $
+ * Contributor: Lake Stevens Instrument Division$
+ *
+ * Description: low level support for gdb debugger. $
+ *
+ * Considerations: only works on target hardware $
+ *
+ * Written by: Glenn Engel $
+ * ModuleState: Experimental $
+ *
+ * NOTES: See Below $
+ *
+ * Modified for M32R by Michael Snyder, Cygnus Support.
+ *
+ * To enable debugger support, two things need to happen. One, a
+ * call to set_debug_traps() is necessary in order to allow any breakpoints
+ * or error conditions to be properly intercepted and reported to gdb.
+ * Two, a breakpoint needs to be generated to begin communication. This
+ * is most easily accomplished by a call to breakpoint(). Breakpoint()
+ * simulates a breakpoint by executing a trap #1.
+ *
+ * The external function exceptionHandler() is
+ * used to attach a specific handler to a specific M32R vector number.
+ * It should use the same privilege level it runs at. It should
+ * install it as an interrupt gate so that interrupts are masked
+ * while the handler runs.
+ *
+ * Because gdb will sometimes write to the stack area to execute function
+ * calls, this program cannot rely on using the supervisor stack so it
+ * uses it's own stack area reserved in the int array remcomStack.
+ *
+ *************
+ *
+ * The following gdb commands are supported:
+ *
+ * command function Return value
+ *
+ * g return the value of the CPU registers hex data or ENN
+ * G set the value of the CPU registers OK or ENN
+ *
+ * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
+ * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
+ * XAA..AA,LLLL: Write LLLL binary bytes at address OK or ENN
+ * AA..AA
+ *
+ * c Resume at current address SNN ( signal NN)
+ * cAA..AA Continue at address AA..AA SNN
+ *
+ * s Step one instruction SNN
+ * sAA..AA Step one instruction from AA..AA SNN
+ *
+ * k kill
+ *
+ * ? What was the last sigval ? SNN (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum. A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum> :: <two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer. '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host: Reply:
+ * $m0,10#2a +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+extern void putDebugChar(); /* write a single character */
+extern int getDebugChar(); /* read and return a single char */
+extern void exceptionHandler(); /* assign an exception handler */
+
+/*****************************************************************************
+ * BUFMAX defines the maximum number of characters in inbound/outbound buffers
+ * at least NUMREGBYTES*2 are needed for register packets
+ */
+#define BUFMAX 400
+
+static char initialized; /* boolean flag. != 0 means we've been initialized */
+
+int remote_debug;
+/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
+
+static const unsigned char hexchars[]="0123456789abcdef";
+
+#define NUMREGS 24
+
+/* Number of bytes of registers. */
+#define NUMREGBYTES (NUMREGS * 4)
+enum regnames { R0, R1, R2, R3, R4, R5, R6, R7,
+ R8, R9, R10, R11, R12, R13, R14, R15,
+ PSW, CBR, SPI, SPU, BPC, PC, ACCL, ACCH };
+
+enum SYS_calls {
+ SYS_null,
+ SYS_exit,
+ SYS_open,
+ SYS_close,
+ SYS_read,
+ SYS_write,
+ SYS_lseek,
+ SYS_unlink,
+ SYS_getpid,
+ SYS_kill,
+ SYS_fstat,
+ SYS_sbrk,
+ SYS_fork,
+ SYS_execve,
+ SYS_wait4,
+ SYS_link,
+ SYS_chdir,
+ SYS_stat,
+ SYS_utime,
+ SYS_chown,
+ SYS_chmod,
+ SYS_time,
+ SYS_pipe };
+
+static int registers[NUMREGS];
+
+#define STACKSIZE 8096
+static unsigned char remcomInBuffer[BUFMAX];
+static unsigned char remcomOutBuffer[BUFMAX];
+static int remcomStack[STACKSIZE/sizeof(int)];
+static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
+
+static unsigned int save_vectors[18]; /* previous exception vectors */
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an error. */
+static volatile int mem_err = 0;
+
+/* Store the vector number here (since GDB only gets the signal
+ number through the usual means, and that's not very specific). */
+int gdb_m32r_vector = -1;
+
+#if 0
+#include "syscall.h" /* for SYS_exit, SYS_write etc. */
+#endif
+
+/* Global entry points:
+ */
+
+extern void handle_exception(int);
+extern void set_debug_traps(void);
+extern void breakpoint(void);
+
+/* Local functions:
+ */
+
+static int computeSignal(int);
+static void putpacket(unsigned char *);
+static unsigned char *getpacket(void);
+
+static unsigned char *mem2hex(unsigned char *, unsigned char *, int, int);
+static unsigned char *hex2mem(unsigned char *, unsigned char *, int, int);
+static int hexToInt(unsigned char **, int *);
+static unsigned char *bin2mem(unsigned char *, unsigned char *, int, int);
+static void stash_registers(void);
+static void restore_registers(void);
+static int prepare_to_step(int);
+static int finish_from_step(void);
+static unsigned long crc32 (unsigned char *, int, unsigned long);
+
+static void gdb_error(char *, char *);
+static int gdb_putchar(int), gdb_puts(char *), gdb_write(char *, int);
+
+static unsigned char *strcpy (unsigned char *, const unsigned char *);
+static int strlen (const unsigned char *);
+
+/*
+ * This function does all command procesing for interfacing to gdb.
+ */
+
+void
+handle_exception(int exceptionVector)
+{
+ int sigval, stepping;
+ int addr, length, i;
+ unsigned char * ptr;
+ unsigned char buf[16];
+ int binary;
+
+ if (!finish_from_step())
+ return; /* "false step": let the target continue */
+
+ gdb_m32r_vector = exceptionVector;
+
+ if (remote_debug)
+ {
+ mem2hex((unsigned char *) &exceptionVector, buf, 4, 0);
+ gdb_error("Handle exception %s, ", buf);
+ mem2hex((unsigned char *) &registers[PC], buf, 4, 0);
+ gdb_error("PC == 0x%s\n", buf);
+ }
+
+ /* reply to host that an exception has occurred */
+ sigval = computeSignal( exceptionVector );
+
+ ptr = remcomOutBuffer;
+
+ *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */
+ *ptr++ = hexchars[sigval >> 4];
+ *ptr++ = hexchars[sigval & 0xf];
+
+ *ptr++ = hexchars[PC >> 4];
+ *ptr++ = hexchars[PC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)&registers[PC], ptr, 4, 0); /* PC */
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[R13 >> 4];
+ *ptr++ = hexchars[R13 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)&registers[R13], ptr, 4, 0); /* FP */
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[R15 >> 4];
+ *ptr++ = hexchars[R15 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)&registers[R15], ptr, 4, 0); /* SP */
+ *ptr++ = ';';
+ *ptr++ = 0;
+
+ if (exceptionVector == 0) /* simulated SYS call stuff */
+ {
+ mem2hex((unsigned char *) &registers[PC], buf, 4, 0);
+ switch (registers[R0]) {
+ case SYS_exit:
+ gdb_error("Target program has exited at %s\n", buf);
+ ptr = remcomOutBuffer;
+ *ptr++ = 'W';
+ sigval = registers[R1] & 0xff;
+ *ptr++ = hexchars[sigval >> 4];
+ *ptr++ = hexchars[sigval & 0xf];
+ *ptr++ = 0;
+ break;
+ case SYS_open:
+ gdb_error("Target attempts SYS_open call at %s\n", buf);
+ break;
+ case SYS_close:
+ gdb_error("Target attempts SYS_close call at %s\n", buf);
+ break;
+ case SYS_read:
+ gdb_error("Target attempts SYS_read call at %s\n", buf);
+ break;
+ case SYS_write:
+ if (registers[R1] == 1 || /* write to stdout */
+ registers[R1] == 2) /* write to stderr */
+ { /* (we can do that) */
+ registers[R0] = gdb_write((void *) registers[R2], registers[R3]);
+ return;
+ }
+ else
+ gdb_error("Target attempts SYS_write call at %s\n", buf);
+ break;
+ case SYS_lseek:
+ gdb_error("Target attempts SYS_lseek call at %s\n", buf);
+ break;
+ case SYS_unlink:
+ gdb_error("Target attempts SYS_unlink call at %s\n", buf);
+ break;
+ case SYS_getpid:
+ gdb_error("Target attempts SYS_getpid call at %s\n", buf);
+ break;
+ case SYS_kill:
+ gdb_error("Target attempts SYS_kill call at %s\n", buf);
+ break;
+ case SYS_fstat:
+ gdb_error("Target attempts SYS_fstat call at %s\n", buf);
+ break;
+ default:
+ gdb_error("Target attempts unknown SYS call at %s\n", buf);
+ break;
+ }
+ }
+
+ putpacket(remcomOutBuffer);
+
+ stepping = 0;
+
+ while (1==1) {
+ remcomOutBuffer[0] = 0;
+ ptr = getpacket();
+ binary = 0;
+ switch (*ptr++) {
+ default: /* Unknown code. Return an empty reply message. */
+ break;
+ case 'R':
+ if (hexToInt (&ptr, &addr))
+ registers[PC] = addr;
+ strcpy(remcomOutBuffer, "OK");
+ break;
+ case '!':
+ strcpy(remcomOutBuffer, "OK");
+ break;
+ case 'X': /* XAA..AA,LLLL:<binary data>#cs */
+ binary = 1;
+ case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
+ {
+ if (hexToInt(&ptr,&addr))
+ if (*(ptr++) == ',')
+ if (hexToInt(&ptr,&length))
+ if (*(ptr++) == ':')
+ {
+ mem_err = 0;
+ if (binary)
+ bin2mem (ptr, (unsigned char *) addr, length, 1);
+ else
+ hex2mem(ptr, (unsigned char*) addr, length, 1);
+ if (mem_err) {
+ strcpy (remcomOutBuffer, "E03");
+ gdb_error ("memory fault", "");
+ } else {
+ strcpy(remcomOutBuffer,"OK");
+ }
+ ptr = 0;
+ }
+ if (ptr)
+ {
+ strcpy(remcomOutBuffer,"E02");
+ }
+ }
+ break;
+ case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
+ if (hexToInt(&ptr,&addr))
+ if (*(ptr++) == ',')
+ if (hexToInt(&ptr,&length))
+ {
+ ptr = 0;
+ mem_err = 0;
+ mem2hex((unsigned char*) addr, remcomOutBuffer, length, 1);
+ if (mem_err) {
+ strcpy (remcomOutBuffer, "E03");
+ gdb_error ("memory fault", "");
+ }
+ }
+ if (ptr)
+ {
+ strcpy(remcomOutBuffer,"E01");
+ }
+ break;
+ case '?':
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval % 16];
+ remcomOutBuffer[3] = 0;
+ break;
+ case 'd':
+ remote_debug = !(remote_debug); /* toggle debug flag */
+ break;
+ case 'g': /* return the value of the CPU registers */
+ mem2hex((unsigned char*) registers, remcomOutBuffer, NUMREGBYTES, 0);
+ break;
+ case 'P': /* set the value of a single CPU register - return OK */
+ {
+ int regno;
+
+ if (hexToInt (&ptr, &regno) && *ptr++ == '=')
+ if (regno >= 0 && regno < NUMREGS)
+ {
+ int stackmode;
+
+ hex2mem (ptr, (unsigned char *) &registers[regno], 4, 0);
+ /*
+ * Since we just changed a single CPU register, let's
+ * make sure to keep the several stack pointers consistant.
+ */
+ stackmode = registers[PSW] & 0x80;
+ if (regno == R15) /* stack pointer changed */
+ { /* need to change SPI or SPU */
+ if (stackmode == 0)
+ registers[SPI] = registers[R15];
+ else
+ registers[SPU] = registers[R15];
+ }
+ else if (regno == SPU) /* "user" stack pointer changed */
+ {
+ if (stackmode != 0) /* stack in user mode: copy SP */
+ registers[R15] = registers[SPU];
+ }
+ else if (regno == SPI) /* "interrupt" stack pointer changed */
+ {
+ if (stackmode == 0) /* stack in interrupt mode: copy SP */
+ registers[R15] = registers[SPI];
+ }
+ else if (regno == PSW) /* stack mode may have changed! */
+ { /* force SP to either SPU or SPI */
+ if (stackmode == 0) /* stack in user mode */
+ registers[R15] = registers[SPI];
+ else /* stack in interrupt mode */
+ registers[R15] = registers[SPU];
+ }
+ strcpy (remcomOutBuffer, "OK");
+ break;
+ }
+ strcpy (remcomOutBuffer, "E01");
+ break;
+ }
+ case 'G': /* set the value of the CPU registers - return OK */
+ hex2mem(ptr, (unsigned char*) registers, NUMREGBYTES, 0);
+ strcpy(remcomOutBuffer,"OK");
+ break;
+ case 's': /* sAA..AA Step one instruction from AA..AA(optional) */
+ stepping = 1;
+ case 'c': /* cAA..AA Continue from address AA..AA(optional) */
+ /* try to read optional parameter, pc unchanged if no parm */
+ if (hexToInt(&ptr,&addr))
+ registers[ PC ] = addr;
+
+ if (stepping) /* single-stepping */
+ {
+ if (!prepare_to_step(0)) /* set up for single-step */
+ {
+ /* prepare_to_step has already emulated the target insn:
+ Send SIGTRAP to gdb, don't resume the target at all. */
+ ptr = remcomOutBuffer;
+ *ptr++ = 'T'; /* Simulate stopping with SIGTRAP */
+ *ptr++ = '0';
+ *ptr++ = '5';
+
+ *ptr++ = hexchars[PC >> 4]; /* send PC */
+ *ptr++ = hexchars[PC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)&registers[PC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[R13 >> 4]; /* send FP */
+ *ptr++ = hexchars[R13 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)&registers[R13], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[R15 >> 4]; /* send SP */
+ *ptr++ = hexchars[R15 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)&registers[R15], ptr, 4, 0);
+ *ptr++ = ';';
+ *ptr++ = 0;
+
+ break;
+ }
+ }
+ else /* continuing, not single-stepping */
+ {
+ /* OK, about to do a "continue". First check to see if the
+ target pc is on an odd boundary (second instruction in the
+ word). If so, we must do a single-step first, because
+ ya can't jump or return back to an odd boundary! */
+ if ((registers[PC] & 2) != 0)
+ prepare_to_step(1);
+ }
+
+ return;
+
+ case 'D': /* Detach */
+#if 0
+ /* I am interpreting this to mean, release the board from control
+ by the remote stub. To do this, I am restoring the original
+ (or at least previous) exception vectors.
+ */
+ for (i = 0; i < 18; i++)
+ exceptionHandler (i, save_vectors[i]);
+ putpacket ("OK");
+ return; /* continue the inferior */
+#else
+ strcpy(remcomOutBuffer,"OK");
+ break;
+#endif
+ case 'q':
+ if (*ptr++ == 'C' &&
+ *ptr++ == 'R' &&
+ *ptr++ == 'C' &&
+ *ptr++ == ':')
+ {
+ unsigned long start, len, our_crc;
+
+ if (hexToInt (&ptr, (int *) &start) &&
+ *ptr++ == ',' &&
+ hexToInt (&ptr, (int *) &len))
+ {
+ remcomOutBuffer[0] = 'C';
+ our_crc = crc32 ((unsigned char *) start, len, 0xffffffff);
+ mem2hex ((char *) &our_crc,
+ &remcomOutBuffer[1],
+ sizeof (long),
+ 0);
+ } /* else do nothing */
+ } /* else do nothing */
+ break;
+
+ case 'k': /* kill the program */
+ continue;
+ } /* switch */
+
+ /* reply to the request */
+ putpacket(remcomOutBuffer);
+ }
+}
+
+/* qCRC support */
+
+/* Table used by the crc32 function to calcuate the checksum. */
+static unsigned long crc32_table[256] = {0, 0};
+
+static unsigned long
+crc32 (unsigned char *buf, int len, unsigned long crc)
+{
+ if (! crc32_table[1])
+ {
+ /* Initialize the CRC table and the decoding table. */
+ int i, j;
+ unsigned long c;
+
+ for (i = 0; i < 256; i++)
+ {
+ for (c = i << 24, j = 8; j > 0; --j)
+ c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
+ crc32_table[i] = c;
+ }
+ }
+
+ while (len--)
+ {
+ crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
+ buf++;
+ }
+ return crc;
+}
+
+static int
+hex (unsigned char ch)
+{
+ if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10);
+ if ((ch >= '0') && (ch <= '9')) return (ch-'0');
+ if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10);
+ return (-1);
+}
+
+/* scan for the sequence $<data>#<checksum> */
+
+unsigned char *
+getpacket (void)
+{
+ unsigned char *buffer = &remcomInBuffer[0];
+ unsigned char checksum;
+ unsigned char xmitcsum;
+ int count;
+ char ch;
+
+ while (1)
+ {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = getDebugChar ()) != '$')
+ ;
+
+retry:
+ checksum = 0;
+ xmitcsum = -1;
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX)
+ {
+ ch = getDebugChar ();
+ if (ch == '$')
+ goto retry;
+ if (ch == '#')
+ break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+ buffer[count] = 0;
+
+ if (ch == '#')
+ {
+ ch = getDebugChar ();
+ xmitcsum = hex (ch) << 4;
+ ch = getDebugChar ();
+ xmitcsum += hex (ch);
+
+ if (checksum != xmitcsum)
+ {
+ if (remote_debug)
+ {
+ unsigned char buf[16];
+
+ mem2hex((unsigned char *) &checksum, buf, 4, 0);
+ gdb_error("Bad checksum: my count = %s, ", buf);
+ mem2hex((unsigned char *) &xmitcsum, buf, 4, 0);
+ gdb_error("sent count = %s\n", buf);
+ gdb_error(" -- Bad buffer: \"%s\"\n", buffer);
+ }
+ putDebugChar ('-'); /* failed checksum */
+ }
+ else
+ {
+ putDebugChar ('+'); /* successful transfer */
+
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':')
+ {
+ putDebugChar (buffer[0]);
+ putDebugChar (buffer[1]);
+
+ return &buffer[3];
+ }
+
+ return &buffer[0];
+ }
+ }
+ }
+}
+
+/* send the packet in buffer. */
+
+static void
+putpacket (unsigned char *buffer)
+{
+ unsigned char checksum;
+ int count;
+ char ch;
+
+ /* $<packet info>#<checksum>. */
+ do {
+ putDebugChar('$');
+ checksum = 0;
+ count = 0;
+
+ while (ch=buffer[count]) {
+ putDebugChar(ch);
+ checksum += ch;
+ count += 1;
+ }
+ putDebugChar('#');
+ putDebugChar(hexchars[checksum >> 4]);
+ putDebugChar(hexchars[checksum % 16]);
+ } while (getDebugChar() != '+');
+}
+
+/* Address of a routine to RTE to if we get a memory fault. */
+
+static void (*volatile mem_fault_routine)() = 0;
+
+static void
+set_mem_err (void)
+{
+ mem_err = 1;
+}
+
+/* Check the address for safe access ranges. As currently defined,
+ this routine will reject the "expansion bus" address range(s).
+ To make those ranges useable, someone must implement code to detect
+ whether there's anything connected to the expansion bus. */
+
+static int
+mem_safe (unsigned char *addr)
+{
+#define BAD_RANGE_ONE_START ((unsigned char *) 0x600000)
+#define BAD_RANGE_ONE_END ((unsigned char *) 0xa00000)
+#define BAD_RANGE_TWO_START ((unsigned char *) 0xff680000)
+#define BAD_RANGE_TWO_END ((unsigned char *) 0xff800000)
+
+ if (addr < BAD_RANGE_ONE_START) return 1; /* safe */
+ if (addr < BAD_RANGE_ONE_END) return 0; /* unsafe */
+ if (addr < BAD_RANGE_TWO_START) return 1; /* safe */
+ if (addr < BAD_RANGE_TWO_END) return 0; /* unsafe */
+}
+
+/* These are separate functions so that they are so short and sweet
+ that the compiler won't save any registers (if there is a fault
+ to mem_fault, they won't get restored, so there better not be any
+ saved). */
+static int
+get_char (unsigned char *addr)
+{
+#if 1
+ if (mem_fault_routine && !mem_safe(addr))
+ {
+ mem_fault_routine ();
+ return 0;
+ }
+#endif
+ return *addr;
+}
+
+static void
+set_char (unsigned char *addr, unsigned char val)
+{
+#if 1
+ if (mem_fault_routine && !mem_safe (addr))
+ {
+ mem_fault_routine ();
+ return;
+ }
+#endif
+ *addr = val;
+}
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+ Return a pointer to the last char put in buf (null).
+ If MAY_FAULT is non-zero, then we should set mem_err in response to
+ a fault; if zero treat a fault like any other fault in the stub. */
+
+static unsigned char *
+mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault)
+{
+ int i;
+ unsigned char ch;
+
+ if (may_fault)
+ mem_fault_routine = set_mem_err;
+ for (i=0;i<count;i++) {
+ ch = get_char (mem++);
+ if (may_fault && mem_err)
+ return (buf);
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch % 16];
+ }
+ *buf = 0;
+ if (may_fault)
+ mem_fault_routine = 0;
+ return(buf);
+}
+
+/* Convert the hex array pointed to by buf into binary to be placed in mem.
+ Return a pointer to the character AFTER the last byte written. */
+
+static unsigned char*
+hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
+{
+ int i;
+ unsigned char ch;
+
+ if (may_fault)
+ mem_fault_routine = set_mem_err;
+ for (i=0;i<count;i++) {
+ ch = hex(*buf++) << 4;
+ ch = ch + hex(*buf++);
+ set_char (mem++, ch);
+ if (may_fault && mem_err)
+ return (mem);
+ }
+ if (may_fault)
+ mem_fault_routine = 0;
+ return(mem);
+}
+
+/* Convert the binary stream in BUF to memory.
+
+ Gdb will escape $, #, and the escape char (0x7d).
+ COUNT is the total number of bytes to write into
+ memory. */
+static unsigned char *
+bin2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
+{
+ int i;
+ unsigned char ch;
+
+ if (may_fault)
+ mem_fault_routine = set_mem_err;
+ for (i = 0; i < count; i++)
+ {
+ /* Check for any escaped characters. Be paranoid and
+ only unescape chars that should be escaped. */
+ if (*buf == 0x7d)
+ {
+ switch (*(buf+1))
+ {
+ case 0x3: /* # */
+ case 0x4: /* $ */
+ case 0x5d: /* escape char */
+ buf++;
+ *buf |= 0x20;
+ break;
+ default:
+ /* nothing */
+ break;
+ }
+ }
+
+ set_char (mem++, *buf++);
+
+ if (may_fault && mem_err)
+ return mem;
+ }
+
+ if (may_fault)
+ mem_fault_routine = 0;
+ return mem;
+}
+
+/* this function takes the m32r exception vector and attempts to
+ translate this number into a unix compatible signal value */
+
+static int
+computeSignal (int exceptionVector)
+{
+ int sigval;
+ switch (exceptionVector) {
+ case 0 : sigval = 23; break; /* I/O trap */
+ case 1 : sigval = 5; break; /* breakpoint */
+ case 2 : sigval = 5; break; /* breakpoint */
+ case 3 : sigval = 5; break; /* breakpoint */
+ case 4 : sigval = 5; break; /* breakpoint */
+ case 5 : sigval = 5; break; /* breakpoint */
+ case 6 : sigval = 5; break; /* breakpoint */
+ case 7 : sigval = 5; break; /* breakpoint */
+ case 8 : sigval = 5; break; /* breakpoint */
+ case 9 : sigval = 5; break; /* breakpoint */
+ case 10 : sigval = 5; break; /* breakpoint */
+ case 11 : sigval = 5; break; /* breakpoint */
+ case 12 : sigval = 5; break; /* breakpoint */
+ case 13 : sigval = 5; break; /* breakpoint */
+ case 14 : sigval = 5; break; /* breakpoint */
+ case 15 : sigval = 5; break; /* breakpoint */
+ case 16 : sigval = 10; break; /* BUS ERROR (alignment) */
+ case 17 : sigval = 2; break; /* INTerrupt */
+ default : sigval = 7; break; /* "software generated" */
+ }
+ return (sigval);
+}
+
+/**********************************************/
+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
+/* RETURN NUMBER OF CHARS PROCESSED */
+/**********************************************/
+static int
+hexToInt (unsigned char **ptr, int *intValue)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+ while (**ptr)
+ {
+ hexValue = hex(**ptr);
+ if (hexValue >=0)
+ {
+ *intValue = (*intValue <<4) | hexValue;
+ numChars ++;
+ }
+ else
+ break;
+ (*ptr)++;
+ }
+ return (numChars);
+}
+
+/*
+ Table of branch instructions:
+
+ 10B6 RTE return from trap or exception
+ 1FCr JMP jump
+ 1ECr JL jump and link
+ 7Fxx BRA branch
+ FFxxxxxx BRA branch (long)
+ B09rxxxx BNEZ branch not-equal-zero
+ Br1rxxxx BNE branch not-equal
+ 7Dxx BNC branch not-condition
+ FDxxxxxx BNC branch not-condition (long)
+ B0Arxxxx BLTZ branch less-than-zero
+ B0Crxxxx BLEZ branch less-equal-zero
+ 7Exx BL branch and link
+ FExxxxxx BL branch and link (long)
+ B0Drxxxx BGTZ branch greater-than-zero
+ B0Brxxxx BGEZ branch greater-equal-zero
+ B08rxxxx BEQZ branch equal-zero
+ Br0rxxxx BEQ branch equal
+ 7Cxx BC branch condition
+ FCxxxxxx BC branch condition (long)
+ */
+
+static int
+isShortBranch (unsigned char *instr)
+{
+ unsigned char instr0 = instr[0] & 0x7F; /* mask off high bit */
+
+ if (instr0 == 0x10 && instr[1] == 0xB6) /* RTE */
+ return 1; /* return from trap or exception */
+
+ if (instr0 == 0x1E || instr0 == 0x1F) /* JL or JMP */
+ if ((instr[1] & 0xF0) == 0xC0)
+ return 2; /* jump thru a register */
+
+ if (instr0 == 0x7C || instr0 == 0x7D || /* BC, BNC, BL, BRA */
+ instr0 == 0x7E || instr0 == 0x7F)
+ return 3; /* eight bit PC offset */
+
+ return 0;
+}
+
+static int
+isLongBranch (unsigned char *instr)
+{
+ if (instr[0] == 0xFC || instr[0] == 0xFD || /* BRA, BNC, BL, BC */
+ instr[0] == 0xFE || instr[0] == 0xFF) /* 24 bit relative */
+ return 4;
+ if ((instr[0] & 0xF0) == 0xB0) /* 16 bit relative */
+ {
+ if ((instr[1] & 0xF0) == 0x00 || /* BNE, BEQ */
+ (instr[1] & 0xF0) == 0x10)
+ return 5;
+ if (instr[0] == 0xB0) /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ, BEQZ */
+ if ((instr[1] & 0xF0) == 0x80 || (instr[1] & 0xF0) == 0x90 ||
+ (instr[1] & 0xF0) == 0xA0 || (instr[1] & 0xF0) == 0xB0 ||
+ (instr[1] & 0xF0) == 0xC0 || (instr[1] & 0xF0) == 0xD0)
+ return 6;
+ }
+ return 0;
+}
+
+/* if address is NOT on a 4-byte boundary, or high-bit of instr is zero,
+ then it's a 2-byte instruction, else it's a 4-byte instruction. */
+
+#define INSTRUCTION_SIZE(addr) \
+ ((((int) addr & 2) || (((unsigned char *) addr)[0] & 0x80) == 0) ? 2 : 4)
+
+static int
+isBranch (unsigned char *instr)
+{
+ if (INSTRUCTION_SIZE(instr) == 2)
+ return isShortBranch(instr);
+ else
+ return isLongBranch(instr);
+}
+
+static int
+willBranch (unsigned char *instr, int branchCode)
+{
+ switch (branchCode)
+ {
+ case 0: return 0; /* not a branch */
+ case 1: return 1; /* RTE */
+ case 2: return 1; /* JL or JMP */
+ case 3: /* BC, BNC, BL, BRA (short) */
+ case 4: /* BC, BNC, BL, BRA (long) */
+ switch (instr[0] & 0x0F)
+ {
+ case 0xC: /* Branch if Condition Register */
+ return (registers[CBR] != 0);
+ case 0xD: /* Branch if NOT Condition Register */
+ return (registers[CBR] == 0);
+ case 0xE: /* Branch and Link */
+ case 0xF: /* Branch (unconditional) */
+ return 1;
+ default: /* oops? */
+ return 0;
+ }
+ case 5: /* BNE, BEQ */
+ switch (instr[1] & 0xF0)
+ {
+ case 0x00: /* Branch if r1 equal to r2 */
+ return (registers[instr[0] & 0x0F] == registers[instr[1] & 0x0F]);
+ case 0x10: /* Branch if r1 NOT equal to r2 */
+ return (registers[instr[0] & 0x0F] != registers[instr[1] & 0x0F]);
+ default: /* oops? */
+ return 0;
+ }
+ case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ */
+ switch (instr[1] & 0xF0)
+ {
+ case 0x80: /* Branch if reg equal to zero */
+ return (registers[instr[1] & 0x0F] == 0);
+ case 0x90: /* Branch if reg NOT equal to zero */
+ return (registers[instr[1] & 0x0F] != 0);
+ case 0xA0: /* Branch if reg less than zero */
+ return (registers[instr[1] & 0x0F] < 0);
+ case 0xB0: /* Branch if reg greater or equal to zero */
+ return (registers[instr[1] & 0x0F] >= 0);
+ case 0xC0: /* Branch if reg less than or equal to zero */
+ return (registers[instr[1] & 0x0F] <= 0);
+ case 0xD0: /* Branch if reg greater than zero */
+ return (registers[instr[1] & 0x0F] > 0);
+ default: /* oops? */
+ return 0;
+ }
+ default: /* oops? */
+ return 0;
+ }
+}
+
+static int
+branchDestination (unsigned char *instr, int branchCode)
+{
+ switch (branchCode) {
+ default:
+ case 0: /* not a branch */
+ return 0;
+ case 1: /* RTE */
+ return registers[BPC] & ~3; /* pop BPC into PC */
+ case 2: /* JL or JMP */
+ return registers[instr[1] & 0x0F] & ~3; /* jump thru a register */
+ case 3: /* BC, BNC, BL, BRA (short, 8-bit relative offset) */
+ return (((int) instr) & ~3) + ((char) instr[1] << 2);
+ case 4: /* BC, BNC, BL, BRA (long, 24-bit relative offset) */
+ return ((int) instr +
+ ((((char) instr[1] << 16) | (instr[2] << 8) | (instr[3])) << 2));
+ case 5: /* BNE, BEQ (16-bit relative offset) */
+ case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ (ditto) */
+ return ((int) instr + ((((char) instr[2] << 8) | (instr[3])) << 2));
+ }
+
+ /* An explanatory note: in the last three return expressions, I have
+ cast the most-significant byte of the return offset to char.
+ What this accomplishes is sign extension. If the other
+ less-significant bytes were signed as well, they would get sign
+ extended too and, if negative, their leading bits would clobber
+ the bits of the more-significant bytes ahead of them. There are
+ other ways I could have done this, but sign extension from
+ odd-sized integers is always a pain. */
+}
+
+static void
+branchSideEffects (unsigned char *instr, int branchCode)
+{
+ switch (branchCode)
+ {
+ case 1: /* RTE */
+ return; /* I <THINK> this is already handled... */
+ case 2: /* JL (or JMP) */
+ case 3: /* BL (or BC, BNC, BRA) */
+ case 4:
+ if ((instr[0] & 0x0F) == 0x0E) /* branch/jump and link */
+ registers[R14] = (registers[PC] & ~3) + 4;
+ return;
+ default: /* any other branch has no side effects */
+ return;
+ }
+}
+
+static struct STEPPING_CONTEXT {
+ int stepping; /* true when we've started a single-step */
+ unsigned long target_addr; /* the instr we're trying to execute */
+ unsigned long target_size; /* the size of the target instr */
+ unsigned long noop_addr; /* where we've inserted a no-op, if any */
+ unsigned long trap1_addr; /* the trap following the target instr */
+ unsigned long trap2_addr; /* the trap at a branch destination, if any */
+ unsigned short noop_save; /* instruction overwritten by our no-op */
+ unsigned short trap1_save; /* instruction overwritten by trap1 */
+ unsigned short trap2_save; /* instruction overwritten by trap2 */
+ unsigned short continue_p; /* true if NOT returning to gdb after step */
+} stepping;
+
+/* Function: prepare_to_step
+ Called from handle_exception to prepare the user program to single-step.
+ Places a trap instruction after the target instruction, with special
+ extra handling for branch instructions and for instructions in the
+ second half-word of a word.
+
+ Returns: True if we should actually execute the instruction;
+ False if we are going to emulate executing the instruction,
+ in which case we simply report to GDB that the instruction
+ has already been executed. */
+
+#define TRAP1 0x10f1; /* trap #1 instruction */
+#define NOOP 0x7000; /* noop instruction */
+
+static unsigned short trap1 = TRAP1;
+static unsigned short noop = NOOP;
+
+static int
+prepare_to_step(continue_p)
+ int continue_p; /* if this isn't REALLY a single-step (see below) */
+{
+ unsigned long pc = registers[PC];
+ int branchCode = isBranch((unsigned char *) pc);
+ unsigned char *p;
+
+ /* zero out the stepping context
+ (paranoia -- it should already be zeroed) */
+ for (p = (unsigned char *) &stepping;
+ p < ((unsigned char *) &stepping) + sizeof(stepping);
+ p++)
+ *p = 0;
+
+ if (branchCode != 0) /* next instruction is a branch */
+ {
+ branchSideEffects((unsigned char *) pc, branchCode);
+ if (willBranch((unsigned char *)pc, branchCode))
+ registers[PC] = branchDestination((unsigned char *) pc, branchCode);
+ else
+ registers[PC] = pc + INSTRUCTION_SIZE(pc);
+ return 0; /* branch "executed" -- just notify GDB */
+ }
+ else if (((int) pc & 2) != 0) /* "second-slot" instruction */
+ {
+ /* insert no-op before pc */
+ stepping.noop_addr = pc - 2;
+ stepping.noop_save = *(unsigned short *) stepping.noop_addr;
+ *(unsigned short *) stepping.noop_addr = noop;
+ /* insert trap after pc */
+ stepping.trap1_addr = pc + 2;
+ stepping.trap1_save = *(unsigned short *) stepping.trap1_addr;
+ *(unsigned short *) stepping.trap1_addr = trap1;
+ }
+ else /* "first-slot" instruction */
+ {
+ /* insert trap after pc */
+ stepping.trap1_addr = pc + INSTRUCTION_SIZE(pc);
+ stepping.trap1_save = *(unsigned short *) stepping.trap1_addr;
+ *(unsigned short *) stepping.trap1_addr = trap1;
+ }
+ /* "continue_p" means that we are actually doing a continue, and not
+ being requested to single-step by GDB. Sometimes we have to do
+ one single-step before continuing, because the PC is on a half-word
+ boundary. There's no way to simply resume at such an address. */
+ stepping.continue_p = continue_p;
+ stepping.stepping = 1; /* starting a single-step */
+ return 1;
+}
+
+/* Function: finish_from_step
+ Called from handle_exception to finish up when the user program
+ returns from a single-step. Replaces the instructions that had
+ been overwritten by traps or no-ops,
+
+ Returns: True if we should notify GDB that the target stopped.
+ False if we only single-stepped because we had to before we
+ could continue (ie. we were trying to continue at a
+ half-word boundary). In that case don't notify GDB:
+ just "continue continuing". */
+
+static int
+finish_from_step (void)
+{
+ if (stepping.stepping) /* anything to do? */
+ {
+ int continue_p = stepping.continue_p;
+ unsigned char *p;
+
+ if (stepping.noop_addr) /* replace instr "under" our no-op */
+ *(unsigned short *) stepping.noop_addr = stepping.noop_save;
+ if (stepping.trap1_addr) /* replace instr "under" our trap */
+ *(unsigned short *) stepping.trap1_addr = stepping.trap1_save;
+ if (stepping.trap2_addr) /* ditto our other trap, if any */
+ *(unsigned short *) stepping.trap2_addr = stepping.trap2_save;
+
+ for (p = (unsigned char *) &stepping; /* zero out the stepping context */
+ p < ((unsigned char *) &stepping) + sizeof(stepping);
+ p++)
+ *p = 0;
+
+ return !(continue_p);
+ }
+ else /* we didn't single-step, therefore this must be a legitimate stop */
+ return 1;
+}
+
+struct PSWreg { /* separate out the bit flags in the PSW register */
+ int pad1 : 16;
+ int bsm : 1;
+ int bie : 1;
+ int pad2 : 5;
+ int bc : 1;
+ int sm : 1;
+ int ie : 1;
+ int pad3 : 5;
+ int c : 1;
+} *psw;
+
+/* Upon entry the value for LR to save has been pushed.
+ We unpush that so that the value for the stack pointer saved is correct.
+ Upon entry, all other registers are assumed to have not been modified
+ since the interrupt/trap occured. */
+
+asm ("
+stash_registers:
+ push r0
+ push r1
+ seth r1, #shigh(registers)
+ add3 r1, r1, #low(registers)
+ pop r0 ; r1
+ st r0, @(4,r1)
+ pop r0 ; r0
+ st r0, @r1
+ addi r1, #4 ; only add 4 as subsequent saves are `pre inc'
+ st r2, @+r1
+ st r3, @+r1
+ st r4, @+r1
+ st r5, @+r1
+ st r6, @+r1
+ st r7, @+r1
+ st r8, @+r1
+ st r9, @+r1
+ st r10, @+r1
+ st r11, @+r1
+ st r12, @+r1
+ st r13, @+r1 ; fp
+ pop r0 ; lr (r14)
+ st r0, @+r1
+ st sp, @+r1 ; sp contains right value at this point
+ mvfc r0, cr0
+ st r0, @+r1 ; cr0 == PSW
+ mvfc r0, cr1
+ st r0, @+r1 ; cr1 == CBR
+ mvfc r0, cr2
+ st r0, @+r1 ; cr2 == SPI
+ mvfc r0, cr3
+ st r0, @+r1 ; cr3 == SPU
+ mvfc r0, cr6
+ st r0, @+r1 ; cr6 == BPC
+ st r0, @+r1 ; PC == BPC
+ mvfaclo r0
+ st r0, @+r1 ; ACCL
+ mvfachi r0
+ st r0, @+r1 ; ACCH
+ jmp lr");
+
+/* C routine to clean up what stash_registers did.
+ It is called after calling stash_registers.
+ This is separate from stash_registers as we want to do this in C
+ but doing stash_registers in C isn't straightforward. */
+
+static void
+cleanup_stash (void)
+{
+ psw = (struct PSWreg *) &registers[PSW]; /* fields of PSW register */
+ psw->sm = psw->bsm; /* fix up pre-trap values of psw fields */
+ psw->ie = psw->bie;
+ psw->c = psw->bc;
+ registers[CBR] = psw->bc; /* fix up pre-trap "C" register */
+
+#if 0 /* FIXME: Was in previous version. Necessary?
+ (Remember that we use the "rte" insn to return from the
+ trap/interrupt so the values of bsm, bie, bc are important. */
+ psw->bsm = psw->bie = psw->bc = 0; /* zero post-trap values */
+#endif
+
+ /* FIXME: Copied from previous version. This can probably be deleted
+ since methinks stash_registers has already done this. */
+ registers[PC] = registers[BPC]; /* pre-trap PC */
+
+ /* FIXME: Copied from previous version. Necessary? */
+ if (psw->sm) /* copy R15 into (psw->sm ? SPU : SPI) */
+ registers[SPU] = registers[R15];
+ else
+ registers[SPI] = registers[R15];
+}
+
+asm ("
+restore_and_return:
+ seth r0, #shigh(registers+8)
+ add3 r0, r0, #low(registers+8)
+ ld r2, @r0+ ; restore r2
+ ld r3, @r0+ ; restore r3
+ ld r4, @r0+ ; restore r4
+ ld r5, @r0+ ; restore r5
+ ld r6, @r0+ ; restore r6
+ ld r7, @r0+ ; restore r7
+ ld r8, @r0+ ; restore r8
+ ld r9, @r0+ ; restore r9
+ ld r10, @r0+ ; restore r10
+ ld r11, @r0+ ; restore r11
+ ld r12, @r0+ ; restore r12
+ ld r13, @r0+ ; restore r13
+ ld r14, @r0+ ; restore r14
+ ld r15, @r0+ ; restore r15
+ ld r1, @r0+ ; restore cr0 == PSW
+ mvtc r1, cr0
+ ld r1, @r0+ ; restore cr1 == CBR (no-op, because it's read only)
+ mvtc r1, cr1
+ ld r1, @r0+ ; restore cr2 == SPI
+ mvtc r1, cr2
+ ld r1, @r0+ ; restore cr3 == SPU
+ mvtc r1, cr3
+ addi r0, #4 ; skip BPC
+ ld r1, @r0+ ; restore cr6 (BPC) == PC
+ mvtc r1, cr6
+ ld r1, @r0+ ; restore ACCL
+ mvtaclo r1
+ ld r1, @r0+ ; restore ACCH
+ mvtachi r1
+ seth r0, #shigh(registers)
+ add3 r0, r0, #low(registers)
+ ld r1, @(4,r0) ; restore r1
+ ld r0, @r0 ; restore r0
+ rte");
+
+/* General trap handler, called after the registers have been stashed.
+ NUM is the trap/exception number. */
+
+static void
+process_exception (int num)
+{
+ cleanup_stash ();
+ asm volatile ("
+ seth r1, #shigh(stackPtr)
+ add3 r1, r1, #low(stackPtr)
+ ld r15, @r1 ; setup local stack (protect user stack)
+ mv r0, %0
+ bl handle_exception
+ bl restore_and_return"
+ : : "r" (num) : "r0", "r1");
+}
+
+void _catchException0 ();
+
+asm ("
+_catchException0:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #0
+ bl process_exception");
+
+void _catchException1 ();
+
+asm ("
+_catchException1:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ bl cleanup_stash
+ seth r1, #shigh(stackPtr)
+ add3 r1, r1, #low(stackPtr)
+ ld r15, @r1 ; setup local stack (protect user stack)
+ seth r1, #shigh(registers + 21*4) ; PC
+ add3 r1, r1, #low(registers + 21*4)
+ ld r0, @r1
+ addi r0, #-4 ; back up PC for breakpoint trap.
+ st r0, @r1 ; FIXME: what about bp in right slot?
+ ldi r0, #1
+ bl handle_exception
+ bl restore_and_return");
+
+void _catchException2 ();
+
+asm ("
+_catchException2:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #2
+ bl process_exception");
+
+void _catchException3 ();
+
+asm ("
+_catchException3:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #3
+ bl process_exception");
+
+void _catchException4 ();
+
+asm ("
+_catchException4:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #4
+ bl process_exception");
+
+void _catchException5 ();
+
+asm ("
+_catchException5:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #5
+ bl process_exception");
+
+void _catchException6 ();
+
+asm ("
+_catchException6:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #6
+ bl process_exception");
+
+void _catchException7 ();
+
+asm ("
+_catchException7:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #7
+ bl process_exception");
+
+void _catchException8 ();
+
+asm ("
+_catchException8:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #8
+ bl process_exception");
+
+void _catchException9 ();
+
+asm ("
+_catchException9:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #9
+ bl process_exception");
+
+void _catchException10 ();
+
+asm ("
+_catchException10:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #10
+ bl process_exception");
+
+void _catchException11 ();
+
+asm ("
+_catchException11:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #11
+ bl process_exception");
+
+void _catchException12 ();
+
+asm ("
+_catchException12:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #12
+ bl process_exception");
+
+void _catchException13 ();
+
+asm ("
+_catchException13:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #13
+ bl process_exception");
+
+void _catchException14 ();
+
+asm ("
+_catchException14:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #14
+ bl process_exception");
+
+void _catchException15 ();
+
+asm ("
+_catchException15:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #15
+ bl process_exception");
+
+void _catchException16 ();
+
+asm ("
+_catchException16:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #16
+ bl process_exception");
+
+void _catchException17 ();
+
+asm ("
+_catchException17:
+ push lr
+ bl stash_registers
+ ; Note that at this point the pushed value of `lr' has been popped
+ ldi r0, #17
+ bl process_exception");
+
+
+/* this function is used to set up exception handlers for tracing and
+ breakpoints */
+void
+set_debug_traps (void)
+{
+ /* extern void remcomHandler(); */
+ int i;
+
+ for (i = 0; i < 18; i++) /* keep a copy of old vectors */
+ if (save_vectors[i] == 0) /* only copy them the first time */
+ save_vectors[i] = getExceptionHandler (i);
+
+ stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
+
+ exceptionHandler (0, _catchException0);
+ exceptionHandler (1, _catchException1);
+ exceptionHandler (2, _catchException2);
+ exceptionHandler (3, _catchException3);
+ exceptionHandler (4, _catchException4);
+ exceptionHandler (5, _catchException5);
+ exceptionHandler (6, _catchException6);
+ exceptionHandler (7, _catchException7);
+ exceptionHandler (8, _catchException8);
+ exceptionHandler (9, _catchException9);
+ exceptionHandler (10, _catchException10);
+ exceptionHandler (11, _catchException11);
+ exceptionHandler (12, _catchException12);
+ exceptionHandler (13, _catchException13);
+ exceptionHandler (14, _catchException14);
+ exceptionHandler (15, _catchException15);
+ exceptionHandler (16, _catchException16);
+ /* exceptionHandler (17, _catchException17); */
+
+ initialized = 1;
+}
+
+/* This function will generate a breakpoint exception. It is used at the
+ beginning of a program to sync up with a debugger and can be used
+ otherwise as a quick means to stop program execution and "break" into
+ the debugger. */
+
+#define BREAKPOINT() asm volatile (" trap #2");
+
+void
+breakpoint (void)
+{
+ if (initialized)
+ BREAKPOINT();
+}
+
+/* STDOUT section:
+ Stuff pertaining to simulating stdout by sending chars to gdb to be echoed.
+ Functions: gdb_putchar(char ch)
+ gdb_puts(char *str)
+ gdb_write(char *str, int len)
+ gdb_error(char *format, char *parm)
+ */
+
+/* Function: gdb_putchar(int)
+ Make gdb write a char to stdout.
+ Returns: the char */
+
+static int
+gdb_putchar (int ch)
+{
+ char buf[4];
+
+ buf[0] = 'O';
+ buf[1] = hexchars[ch >> 4];
+ buf[2] = hexchars[ch & 0x0F];
+ buf[3] = 0;
+ putpacket(buf);
+ return ch;
+}
+
+/* Function: gdb_write(char *, int)
+ Make gdb write n bytes to stdout (not assumed to be null-terminated).
+ Returns: number of bytes written */
+
+static int
+gdb_write (char *data, int len)
+{
+ char *buf, *cpy;
+ int i;
+
+ buf = remcomOutBuffer;
+ buf[0] = 'O';
+ i = 0;
+ while (i < len)
+ {
+ for (cpy = buf+1;
+ i < len && cpy < buf + sizeof(remcomOutBuffer) - 3;
+ i++)
+ {
+ *cpy++ = hexchars[data[i] >> 4];
+ *cpy++ = hexchars[data[i] & 0x0F];
+ }
+ *cpy = 0;
+ putpacket(buf);
+ }
+ return len;
+}
+
+/* Function: gdb_puts(char *)
+ Make gdb write a null-terminated string to stdout.
+ Returns: the length of the string */
+
+static int
+gdb_puts (char *str)
+{
+ return gdb_write(str, strlen(str));
+}
+
+/* Function: gdb_error(char *, char *)
+ Send an error message to gdb's stdout.
+ First string may have 1 (one) optional "%s" in it, which
+ will cause the optional second string to be inserted. */
+
+static void
+gdb_error (char *format, char *parm)
+{
+ char buf[400], *cpy;
+ int len;
+
+ if (remote_debug)
+ {
+ if (format && *format)
+ len = strlen(format);
+ else
+ return; /* empty input */
+
+ if (parm && *parm)
+ len += strlen(parm);
+
+ for (cpy = buf; *format; )
+ {
+ if (format[0] == '%' && format[1] == 's') /* include second string */
+ {
+ format += 2; /* advance two chars instead of just one */
+ while (parm && *parm)
+ *cpy++ = *parm++;
+ }
+ else
+ *cpy++ = *format++;
+ }
+ *cpy = '\0';
+ gdb_puts(buf);
+ }
+}
+
+static unsigned char *
+strcpy (unsigned char *dest, const unsigned char *src)
+{
+ unsigned char *ret = dest;
+
+ if (dest && src)
+ {
+ while (*src)
+ *dest++ = *src++;
+ *dest = 0;
+ }
+ return ret;
+}
+
+static int
+strlen (const unsigned char *src)
+{
+ int ret;
+
+ for (ret = 0; *src; src++)
+ ret++;
+
+ return ret;
+}
+
+#if 0
+void exit (code)
+ int code;
+{
+ _exit (code);
+}
+
+int atexit (void *p)
+{
+ return 0;
+}
+
+void abort (void)
+{
+ _exit (1);
+}
+#endif
diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c
new file mode 100644
index 00000000000..4b883fb213e
--- /dev/null
+++ b/gdb/m32r-tdep.c
@@ -0,0 +1,705 @@
+/* Target-dependent code for the Mitsubishi m32r for GDB, the GNU debugger.
+ Copyright 1996, 1998, 1999, 2000, 2001 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "obstack.h"
+#include "target.h"
+#include "value.h"
+#include "bfd.h"
+#include "gdb_string.h"
+#include "gdbcore.h"
+#include "symfile.h"
+#include "regcache.h"
+
+/* Function: m32r_use_struct_convention
+ Return nonzero if call_function should allocate stack space for a
+ struct return? */
+int
+m32r_use_struct_convention (int gcc_p, struct type *type)
+{
+ return (TYPE_LENGTH (type) > 8);
+}
+
+/* Function: frame_find_saved_regs
+ Return the frame_saved_regs structure for the frame.
+ Doesn't really work for dummy frames, but it does pass back
+ an empty frame_saved_regs, so I guess that's better than total failure */
+
+void
+m32r_frame_find_saved_regs (struct frame_info *fi,
+ struct frame_saved_regs *regaddr)
+{
+ memcpy (regaddr, &fi->fsr, sizeof (struct frame_saved_regs));
+}
+
+/* Turn this on if you want to see just how much instruction decoding
+ if being done, its quite a lot
+ */
+#if 0
+static void
+dump_insn (char *commnt, CORE_ADDR pc, int insn)
+{
+ printf_filtered (" %s %08x %08x ",
+ commnt, (unsigned int) pc, (unsigned int) insn);
+ TARGET_PRINT_INSN (pc, &tm_print_insn_info);
+ printf_filtered ("\n");
+}
+#define insn_debug(args) { printf_filtered args; }
+#else
+#define dump_insn(a,b,c) {}
+#define insn_debug(args) {}
+#endif
+
+#define DEFAULT_SEARCH_LIMIT 44
+
+/* Function: scan_prologue
+ This function decodes the target function prologue to determine
+ 1) the size of the stack frame, and 2) which registers are saved on it.
+ It saves the offsets of saved regs in the frame_saved_regs argument,
+ and returns the frame size. */
+
+/*
+ The sequence it currently generates is:
+
+ if (varargs function) { ddi sp,#n }
+ push registers
+ if (additional stack <= 256) { addi sp,#-stack }
+ else if (additional stack < 65k) { add3 sp,sp,#-stack
+
+ } else if (additional stack) {
+ seth sp,#(stack & 0xffff0000)
+ or3 sp,sp,#(stack & 0x0000ffff)
+ sub sp,r4
+ }
+ if (frame pointer) {
+ mv sp,fp
+ }
+
+ These instructions are scheduled like everything else, so you should stop at
+ the first branch instruction.
+
+ */
+
+/* This is required by skip prologue and by m32r_init_extra_frame_info.
+ The results of decoding a prologue should be cached because this
+ thrashing is getting nuts.
+ I am thinking of making a container class with two indexes, name and
+ address. It may be better to extend the symbol table.
+ */
+
+static void
+decode_prologue (CORE_ADDR start_pc, CORE_ADDR scan_limit, CORE_ADDR *pl_endptr, /* var parameter */
+ unsigned long *framelength, struct frame_info *fi,
+ struct frame_saved_regs *fsr)
+{
+ unsigned long framesize;
+ int insn;
+ int op1;
+ int maybe_one_more = 0;
+ CORE_ADDR after_prologue = 0;
+ CORE_ADDR after_stack_adjust = 0;
+ CORE_ADDR current_pc;
+
+
+ framesize = 0;
+ after_prologue = 0;
+ insn_debug (("rd prolog l(%d)\n", scan_limit - current_pc));
+
+ for (current_pc = start_pc; current_pc < scan_limit; current_pc += 2)
+ {
+
+ insn = read_memory_unsigned_integer (current_pc, 2);
+ dump_insn ("insn-1", current_pc, insn); /* MTZ */
+
+ /* If this is a 32 bit instruction, we dont want to examine its
+ immediate data as though it were an instruction */
+ if (current_pc & 0x02)
+ { /* Clear the parallel execution bit from 16 bit instruction */
+ if (maybe_one_more)
+ { /* The last instruction was a branch, usually terminates
+ the series, but if this is a parallel instruction,
+ it may be a stack framing instruction */
+ if (!(insn & 0x8000))
+ {
+ insn_debug (("Really done"));
+ break; /* nope, we are really done */
+ }
+ }
+ insn &= 0x7fff; /* decode this instruction further */
+ }
+ else
+ {
+ if (maybe_one_more)
+ break; /* This isnt the one more */
+ if (insn & 0x8000)
+ {
+ insn_debug (("32 bit insn\n"));
+ if (current_pc == scan_limit)
+ scan_limit += 2; /* extend the search */
+ current_pc += 2; /* skip the immediate data */
+ if (insn == 0x8faf) /* add3 sp, sp, xxxx */
+ /* add 16 bit sign-extended offset */
+ {
+ insn_debug (("stack increment\n"));
+ framesize += -((short) read_memory_unsigned_integer (current_pc, 2));
+ }
+ else
+ {
+ if (((insn >> 8) == 0xe4) && /* ld24 r4, xxxxxx; sub sp, r4 */
+ read_memory_unsigned_integer (current_pc + 2, 2) == 0x0f24)
+ { /* subtract 24 bit sign-extended negative-offset */
+ dump_insn ("insn-2", current_pc + 2, insn);
+ insn = read_memory_unsigned_integer (current_pc - 2, 4);
+ dump_insn ("insn-3(l4)", current_pc - 2, insn);
+ if (insn & 0x00800000) /* sign extend */
+ insn |= 0xff000000; /* negative */
+ else
+ insn &= 0x00ffffff; /* positive */
+ framesize += insn;
+ }
+ }
+ after_prologue = current_pc;
+ continue;
+ }
+ }
+ op1 = insn & 0xf000; /* isolate just the first nibble */
+
+ if ((insn & 0xf0ff) == 0x207f)
+ { /* st reg, @-sp */
+ int regno;
+ insn_debug (("push\n"));
+#if 0 /* No, PUSH FP is not an indication that we will use a frame pointer. */
+ if (((insn & 0xffff) == 0x2d7f) && fi)
+ fi->using_frame_pointer = 1;
+#endif
+ framesize += 4;
+#if 0
+/* Why should we increase the scan limit, just because we did a push?
+ And if there is a reason, surely we would only want to do it if we
+ had already reached the scan limit... */
+ if (current_pc == scan_limit)
+ scan_limit += 2;
+#endif
+ regno = ((insn >> 8) & 0xf);
+ if (fsr) /* save_regs offset */
+ fsr->regs[regno] = framesize;
+ after_prologue = 0;
+ continue;
+ }
+ if ((insn >> 8) == 0x4f) /* addi sp, xx */
+ /* add 8 bit sign-extended offset */
+ {
+ int stack_adjust = (char) (insn & 0xff);
+
+ /* there are probably two of these stack adjustments:
+ 1) A negative one in the prologue, and
+ 2) A positive one in the epilogue.
+ We are only interested in the first one. */
+
+ if (stack_adjust < 0)
+ {
+ framesize -= stack_adjust;
+ after_prologue = 0;
+ /* A frameless function may have no "mv fp, sp".
+ In that case, this is the end of the prologue. */
+ after_stack_adjust = current_pc + 2;
+ }
+ continue;
+ }
+ if (insn == 0x1d8f)
+ { /* mv fp, sp */
+ if (fi)
+ fi->using_frame_pointer = 1; /* fp is now valid */
+ insn_debug (("done fp found\n"));
+ after_prologue = current_pc + 2;
+ break; /* end of stack adjustments */
+ }
+ if (insn == 0x7000) /* Nop looks like a branch, continue explicitly */
+ {
+ insn_debug (("nop\n"));
+ after_prologue = current_pc + 2;
+ continue; /* nop occurs between pushes */
+ }
+ /* End of prolog if any of these are branch instructions */
+ if ((op1 == 0x7000)
+ || (op1 == 0xb000)
+ || (op1 == 0xf000))
+ {
+ after_prologue = current_pc;
+ insn_debug (("Done: branch\n"));
+ maybe_one_more = 1;
+ continue;
+ }
+ /* Some of the branch instructions are mixed with other types */
+ if (op1 == 0x1000)
+ {
+ int subop = insn & 0x0ff0;
+ if ((subop == 0x0ec0) || (subop == 0x0fc0))
+ {
+ insn_debug (("done: jmp\n"));
+ after_prologue = current_pc;
+ maybe_one_more = 1;
+ continue; /* jmp , jl */
+ }
+ }
+ }
+
+ if (current_pc >= scan_limit)
+ {
+ if (pl_endptr)
+ {
+#if 1
+ if (after_stack_adjust != 0)
+ /* We did not find a "mv fp,sp", but we DID find
+ a stack_adjust. Is it safe to use that as the
+ end of the prologue? I just don't know. */
+ {
+ *pl_endptr = after_stack_adjust;
+ if (framelength)
+ *framelength = framesize;
+ }
+ else
+#endif
+ /* We reached the end of the loop without finding the end
+ of the prologue. No way to win -- we should report failure.
+ The way we do that is to return the original start_pc.
+ GDB will set a breakpoint at the start of the function (etc.) */
+ *pl_endptr = start_pc;
+ }
+ return;
+ }
+ if (after_prologue == 0)
+ after_prologue = current_pc;
+
+ insn_debug ((" framesize %d, firstline %08x\n", framesize, after_prologue));
+ if (framelength)
+ *framelength = framesize;
+ if (pl_endptr)
+ *pl_endptr = after_prologue;
+} /* decode_prologue */
+
+/* Function: skip_prologue
+ Find end of function prologue */
+
+CORE_ADDR
+m32r_skip_prologue (CORE_ADDR pc)
+{
+ CORE_ADDR func_addr, func_end;
+ struct symtab_and_line sal;
+
+ /* See what the symbol table says */
+
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ sal = find_pc_line (func_addr, 0);
+
+ if (sal.line != 0 && sal.end <= func_end)
+ {
+
+ insn_debug (("BP after prologue %08x\n", sal.end));
+ func_end = sal.end;
+ }
+ else
+ /* Either there's no line info, or the line after the prologue is after
+ the end of the function. In this case, there probably isn't a
+ prologue. */
+ {
+ insn_debug (("No line info, line(%x) sal_end(%x) funcend(%x)\n",
+ sal.line, sal.end, func_end));
+ func_end = min (func_end, func_addr + DEFAULT_SEARCH_LIMIT);
+ }
+ }
+ else
+ func_end = pc + DEFAULT_SEARCH_LIMIT;
+ decode_prologue (pc, func_end, &sal.end, 0, 0, 0);
+ return sal.end;
+}
+
+static unsigned long
+m32r_scan_prologue (struct frame_info *fi, struct frame_saved_regs *fsr)
+{
+ struct symtab_and_line sal;
+ CORE_ADDR prologue_start, prologue_end, current_pc;
+ unsigned long framesize = 0;
+
+ /* this code essentially duplicates skip_prologue,
+ but we need the start address below. */
+
+ if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end))
+ {
+ sal = find_pc_line (prologue_start, 0);
+
+ if (sal.line == 0) /* no line info, use current PC */
+ if (prologue_start == entry_point_address ())
+ return 0;
+ }
+ else
+ {
+ prologue_start = fi->pc;
+ prologue_end = prologue_start + 48; /* We're in the boondocks:
+ allow for 16 pushes, an add,
+ and "mv fp,sp" */
+ }
+#if 0
+ prologue_end = min (prologue_end, fi->pc);
+#endif
+ insn_debug (("fipc(%08x) start(%08x) end(%08x)\n",
+ fi->pc, prologue_start, prologue_end));
+ prologue_end = min (prologue_end, prologue_start + DEFAULT_SEARCH_LIMIT);
+ decode_prologue (prologue_start, prologue_end, &prologue_end, &framesize,
+ fi, fsr);
+ return framesize;
+}
+
+/* Function: init_extra_frame_info
+ This function actually figures out the frame address for a given pc and
+ sp. This is tricky on the m32r because we sometimes don't use an explicit
+ frame pointer, and the previous stack pointer isn't necessarily recorded
+ on the stack. The only reliable way to get this info is to
+ examine the prologue. */
+
+void
+m32r_init_extra_frame_info (struct frame_info *fi)
+{
+ int reg;
+
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs);
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ /* We need to setup fi->frame here because run_stack_dummy gets it wrong
+ by assuming it's always FP. */
+ fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
+ fi->framesize = 0;
+ return;
+ }
+ else
+ {
+ fi->using_frame_pointer = 0;
+ fi->framesize = m32r_scan_prologue (fi, &fi->fsr);
+
+ if (!fi->next)
+ if (fi->using_frame_pointer)
+ {
+ fi->frame = read_register (FP_REGNUM);
+ }
+ else
+ fi->frame = read_register (SP_REGNUM);
+ else
+ /* fi->next means this is not the innermost frame */ if (fi->using_frame_pointer)
+ /* we have an FP */
+ if (fi->next->fsr.regs[FP_REGNUM] != 0) /* caller saved our FP */
+ fi->frame = read_memory_integer (fi->next->fsr.regs[FP_REGNUM], 4);
+ for (reg = 0; reg < NUM_REGS; reg++)
+ if (fi->fsr.regs[reg] != 0)
+ fi->fsr.regs[reg] = fi->frame + fi->framesize - fi->fsr.regs[reg];
+ }
+}
+
+/* Function: m32r_virtual_frame_pointer
+ Return the register that the function uses for a frame pointer,
+ plus any necessary offset to be applied to the register before
+ any frame pointer offsets. */
+
+void
+m32r_virtual_frame_pointer (CORE_ADDR pc, long *reg, long *offset)
+{
+ struct frame_info fi;
+
+ /* Set up a dummy frame_info. */
+ fi.next = NULL;
+ fi.prev = NULL;
+ fi.frame = 0;
+ fi.pc = pc;
+
+ /* Analyze the prolog and fill in the extra info. */
+ m32r_init_extra_frame_info (&fi);
+
+
+ /* Results will tell us which type of frame it uses. */
+ if (fi.using_frame_pointer)
+ {
+ *reg = FP_REGNUM;
+ *offset = 0;
+ }
+ else
+ {
+ *reg = SP_REGNUM;
+ *offset = 0;
+ }
+}
+
+/* Function: find_callers_reg
+ Find REGNUM on the stack. Otherwise, it's in an active register. One thing
+ we might want to do here is to check REGNUM against the clobber mask, and
+ somehow flag it as invalid if it isn't saved on the stack somewhere. This
+ would provide a graceful failure mode when trying to get the value of
+ caller-saves registers for an inner frame. */
+
+CORE_ADDR
+m32r_find_callers_reg (struct frame_info *fi, int regnum)
+{
+ for (; fi; fi = fi->next)
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, regnum);
+ else if (fi->fsr.regs[regnum] != 0)
+ return read_memory_integer (fi->fsr.regs[regnum],
+ REGISTER_RAW_SIZE (regnum));
+ return read_register (regnum);
+}
+
+/* Function: frame_chain
+ Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+ For m32r, we save the frame size when we initialize the frame_info. */
+
+CORE_ADDR
+m32r_frame_chain (struct frame_info *fi)
+{
+ CORE_ADDR fn_start, callers_pc, fp;
+
+ /* is this a dummy frame? */
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return fi->frame; /* dummy frame same as caller's frame */
+
+ /* is caller-of-this a dummy frame? */
+ callers_pc = FRAME_SAVED_PC (fi); /* find out who called us: */
+ fp = m32r_find_callers_reg (fi, FP_REGNUM);
+ if (PC_IN_CALL_DUMMY (callers_pc, fp, fp))
+ return fp; /* dummy frame's frame may bear no relation to ours */
+
+ if (find_pc_partial_function (fi->pc, 0, &fn_start, 0))
+ if (fn_start == entry_point_address ())
+ return 0; /* in _start fn, don't chain further */
+ if (fi->framesize == 0)
+ {
+ printf_filtered ("cannot determine frame size @ %s , pc(%s)\n",
+ paddr (fi->frame),
+ paddr (fi->pc));
+ return 0;
+ }
+ insn_debug (("m32rx frame %08x\n", fi->frame + fi->framesize));
+ return fi->frame + fi->framesize;
+}
+
+/* Function: push_return_address (pc)
+ Set up the return address for the inferior function call.
+ Necessary for targets that don't actually execute a JSR/BSR instruction
+ (ie. when using an empty CALL_DUMMY) */
+
+CORE_ADDR
+m32r_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ write_register (RP_REGNUM, CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+
+/* Function: pop_frame
+ Discard from the stack the innermost frame,
+ restoring all saved registers. */
+
+struct frame_info *
+m32r_pop_frame (struct frame_info *frame)
+{
+ int regnum;
+
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ generic_pop_dummy_frame ();
+ else
+ {
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ if (frame->fsr.regs[regnum] != 0)
+ write_register (regnum,
+ read_memory_integer (frame->fsr.regs[regnum], 4));
+
+ write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
+ write_register (SP_REGNUM, read_register (FP_REGNUM));
+ if (read_register (PSW_REGNUM) & 0x80)
+ write_register (SPU_REGNUM, read_register (SP_REGNUM));
+ else
+ write_register (SPI_REGNUM, read_register (SP_REGNUM));
+ }
+ flush_cached_frames ();
+ return NULL;
+}
+
+/* Function: frame_saved_pc
+ Find the caller of this frame. We do this by seeing if RP_REGNUM is saved
+ in the stack anywhere, otherwise we get it from the registers. */
+
+CORE_ADDR
+m32r_frame_saved_pc (struct frame_info *fi)
+{
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
+ else
+ return m32r_find_callers_reg (fi, RP_REGNUM);
+}
+
+/* Function: push_arguments
+ Setup the function arguments for calling a function in the inferior.
+
+ On the Mitsubishi M32R architecture, there are four registers (R0 to R3)
+ which are dedicated for passing function arguments. Up to the first
+ four arguments (depending on size) may go into these registers.
+ The rest go on the stack.
+
+ Arguments that are smaller than 4 bytes will still take up a whole
+ register or a whole 32-bit word on the stack, and will be
+ right-justified in the register or the stack word. This includes
+ chars, shorts, and small aggregate types.
+
+ Arguments of 8 bytes size are split between two registers, if
+ available. If only one register is available, the argument will
+ be split between the register and the stack. Otherwise it is
+ passed entirely on the stack. Aggregate types with sizes between
+ 4 and 8 bytes are passed entirely on the stack, and are left-justified
+ within the double-word (as opposed to aggregates smaller than 4 bytes
+ which are right-justified).
+
+ Aggregates of greater than 8 bytes are first copied onto the stack,
+ and then a pointer to the copy is passed in the place of the normal
+ argument (either in a register if available, or on the stack).
+
+ Functions that must return an aggregate type can return it in the
+ normal return value registers (R0 and R1) if its size is 8 bytes or
+ less. For larger return values, the caller must allocate space for
+ the callee to copy the return value to. A pointer to this space is
+ passed as an implicit first argument, always in R0. */
+
+CORE_ADDR
+m32r_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ unsigned char struct_return, CORE_ADDR struct_addr)
+{
+ int stack_offset, stack_alloc;
+ int argreg;
+ int argnum;
+ struct type *type;
+ CORE_ADDR regval;
+ char *val;
+ char valbuf[4];
+ int len;
+ int odd_sized_struct;
+
+ /* first force sp to a 4-byte alignment */
+ sp = sp & ~3;
+
+ argreg = ARG0_REGNUM;
+ /* The "struct return pointer" pseudo-argument goes in R0 */
+ if (struct_return)
+ write_register (argreg++, struct_addr);
+
+ /* Now make sure there's space on the stack */
+ for (argnum = 0, stack_alloc = 0;
+ argnum < nargs; argnum++)
+ stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3);
+ sp -= stack_alloc; /* make room on stack for args */
+
+
+ /* Now load as many as possible of the first arguments into
+ registers, and push the rest onto the stack. There are 16 bytes
+ in four registers available. Loop thru args from first to last. */
+
+ argreg = ARG0_REGNUM;
+ for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
+ {
+ type = VALUE_TYPE (args[argnum]);
+ len = TYPE_LENGTH (type);
+ memset (valbuf, 0, sizeof (valbuf));
+ if (len < 4)
+ { /* value gets right-justified in the register or stack word */
+ memcpy (valbuf + (4 - len),
+ (char *) VALUE_CONTENTS (args[argnum]), len);
+ val = valbuf;
+ }
+ else
+ val = (char *) VALUE_CONTENTS (args[argnum]);
+
+ if (len > 4 && (len & 3) != 0)
+ odd_sized_struct = 1; /* such structs go entirely on stack */
+ else
+ odd_sized_struct = 0;
+ while (len > 0)
+ {
+ if (argreg > ARGLAST_REGNUM || odd_sized_struct)
+ { /* must go on the stack */
+ write_memory (sp + stack_offset, val, 4);
+ stack_offset += 4;
+ }
+ /* NOTE WELL!!!!! This is not an "else if" clause!!!
+ That's because some *&^%$ things get passed on the stack
+ AND in the registers! */
+ if (argreg <= ARGLAST_REGNUM)
+ { /* there's room in a register */
+ regval = extract_address (val, REGISTER_RAW_SIZE (argreg));
+ write_register (argreg++, regval);
+ }
+ /* Store the value 4 bytes at a time. This means that things
+ larger than 4 bytes may go partly in registers and partly
+ on the stack. */
+ len -= REGISTER_RAW_SIZE (argreg);
+ val += REGISTER_RAW_SIZE (argreg);
+ }
+ }
+ return sp;
+}
+
+/* Function: fix_call_dummy
+ If there is real CALL_DUMMY code (eg. on the stack), this function
+ has the responsability to insert the address of the actual code that
+ is the target of the target function call. */
+
+void
+m32r_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+ struct value **args, struct type *type, int gcc_p)
+{
+ /* ld24 r8, <(imm24) fun> */
+ *(unsigned long *) (dummy) = (fun & 0x00ffffff) | 0xe8000000;
+}
+
+
+/* Function: m32r_write_sp
+ Because SP is really a read-only register that mirrors either SPU or SPI,
+ we must actually write one of those two as well, depending on PSW. */
+
+void
+m32r_write_sp (CORE_ADDR val)
+{
+ unsigned long psw = read_register (PSW_REGNUM);
+
+ if (psw & 0x80) /* stack mode: user or interrupt */
+ write_register (SPU_REGNUM, val);
+ else
+ write_register (SPI_REGNUM, val);
+ write_register (SP_REGNUM, val);
+}
+
+void
+_initialize_m32r_tdep (void)
+{
+ tm_print_insn = print_insn_m32r;
+}
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
new file mode 100644
index 00000000000..6d00ab1faf5
--- /dev/null
+++ b/gdb/m68hc11-tdep.c
@@ -0,0 +1,1172 @@
+/* Target-dependent code for Motorola 68HC11 & 68HC12
+ Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Stephane Carrez, stcarrez@worldnet.fr
+
+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 "defs.h"
+#include "frame.h"
+#include "obstack.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "gdb_string.h"
+#include "value.h"
+#include "inferior.h"
+#include "dis-asm.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "arch-utils.h"
+#include "regcache.h"
+
+#include "target.h"
+#include "opcode/m68hc11.h"
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define HARD_X_REGNUM 0
+#define HARD_D_REGNUM 1
+#define HARD_Y_REGNUM 2
+#define HARD_SP_REGNUM 3
+#define HARD_PC_REGNUM 4
+
+#define HARD_A_REGNUM 5
+#define HARD_B_REGNUM 6
+#define HARD_CCR_REGNUM 7
+#define M68HC11_LAST_HARD_REG (HARD_CCR_REGNUM)
+
+/* Z is replaced by X or Y by gcc during machine reorg.
+ ??? There is no way to get it and even know whether
+ it's in X or Y or in ZS. */
+#define SOFT_Z_REGNUM 8
+
+/* Soft registers. These registers are special. There are treated
+ like normal hard registers by gcc and gdb (ie, within dwarf2 info).
+ They are physically located in memory. */
+#define SOFT_FP_REGNUM 9
+#define SOFT_TMP_REGNUM 10
+#define SOFT_ZS_REGNUM 11
+#define SOFT_XY_REGNUM 12
+#define SOFT_UNUSED_REGNUM 13
+#define SOFT_D1_REGNUM 14
+#define SOFT_D32_REGNUM (SOFT_D1_REGNUM+31)
+#define M68HC11_MAX_SOFT_REGS 32
+
+#define M68HC11_NUM_REGS (8)
+#define M68HC11_NUM_PSEUDO_REGS (M68HC11_MAX_SOFT_REGS+5)
+#define M68HC11_ALL_REGS (M68HC11_NUM_REGS+M68HC11_NUM_PSEUDO_REGS)
+
+#define M68HC11_REG_SIZE (2)
+
+struct insn_sequence;
+struct gdbarch_tdep
+ {
+ /* Stack pointer correction value. For 68hc11, the stack pointer points
+ to the next push location. An offset of 1 must be applied to obtain
+ the address where the last value is saved. For 68hc12, the stack
+ pointer points to the last value pushed. No offset is necessary. */
+ int stack_correction;
+
+ /* Description of instructions in the prologue. */
+ struct insn_sequence *prologue;
+ };
+
+#define M6811_TDEP gdbarch_tdep (current_gdbarch)
+#define STACK_CORRECTION (M6811_TDEP->stack_correction)
+
+struct frame_extra_info
+{
+ int frame_reg;
+ CORE_ADDR return_pc;
+ CORE_ADDR dummy;
+ int frameless;
+ int size;
+};
+
+/* Table of registers for 68HC11. This includes the hard registers
+ and the soft registers used by GCC. */
+static char *
+m68hc11_register_names[] =
+{
+ "x", "d", "y", "sp", "pc", "a", "b",
+ "ccr", "z", "frame","tmp", "zs", "xy", 0,
+ "d1", "d2", "d3", "d4", "d5", "d6", "d7",
+ "d8", "d9", "d10", "d11", "d12", "d13", "d14",
+ "d15", "d16", "d17", "d18", "d19", "d20", "d21",
+ "d22", "d23", "d24", "d25", "d26", "d27", "d28",
+ "d29", "d30", "d31", "d32"
+};
+
+struct m68hc11_soft_reg
+{
+ const char *name;
+ CORE_ADDR addr;
+};
+
+static struct m68hc11_soft_reg soft_regs[M68HC11_ALL_REGS];
+
+#define M68HC11_FP_ADDR soft_regs[SOFT_FP_REGNUM].addr
+
+static int soft_min_addr;
+static int soft_max_addr;
+static int soft_reg_initialized = 0;
+
+/* Look in the symbol table for the address of a pseudo register
+ in memory. If we don't find it, pretend the register is not used
+ and not available. */
+static void
+m68hc11_get_register_info (struct m68hc11_soft_reg *reg, const char *name)
+{
+ struct minimal_symbol *msymbol;
+
+ msymbol = lookup_minimal_symbol (name, NULL, NULL);
+ if (msymbol)
+ {
+ reg->addr = SYMBOL_VALUE_ADDRESS (msymbol);
+ reg->name = xstrdup (name);
+
+ /* Keep track of the address range for soft registers. */
+ if (reg->addr < (CORE_ADDR) soft_min_addr)
+ soft_min_addr = reg->addr;
+ if (reg->addr > (CORE_ADDR) soft_max_addr)
+ soft_max_addr = reg->addr;
+ }
+ else
+ {
+ reg->name = 0;
+ reg->addr = 0;
+ }
+}
+
+/* Initialize the table of soft register addresses according
+ to the symbol table. */
+ static void
+m68hc11_initialize_register_info (void)
+{
+ int i;
+
+ if (soft_reg_initialized)
+ return;
+
+ soft_min_addr = INT_MAX;
+ soft_max_addr = 0;
+ for (i = 0; i < M68HC11_ALL_REGS; i++)
+ {
+ soft_regs[i].name = 0;
+ }
+
+ m68hc11_get_register_info (&soft_regs[SOFT_FP_REGNUM], "_.frame");
+ m68hc11_get_register_info (&soft_regs[SOFT_TMP_REGNUM], "_.tmp");
+ m68hc11_get_register_info (&soft_regs[SOFT_ZS_REGNUM], "_.z");
+ soft_regs[SOFT_Z_REGNUM] = soft_regs[SOFT_ZS_REGNUM];
+ m68hc11_get_register_info (&soft_regs[SOFT_XY_REGNUM], "_.xy");
+
+ for (i = SOFT_D1_REGNUM; i < M68HC11_MAX_SOFT_REGS; i++)
+ {
+ char buf[10];
+
+ sprintf (buf, "_.d%d", i - SOFT_D1_REGNUM + 1);
+ m68hc11_get_register_info (&soft_regs[i], buf);
+ }
+
+ if (soft_regs[SOFT_FP_REGNUM].name == 0)
+ {
+ warning ("No frame soft register found in the symbol table.\n");
+ warning ("Stack backtrace will not work.\n");
+ }
+ soft_reg_initialized = 1;
+}
+
+/* Given an address in memory, return the soft register number if
+ that address corresponds to a soft register. Returns -1 if not. */
+static int
+m68hc11_which_soft_register (CORE_ADDR addr)
+{
+ int i;
+
+ if (addr < soft_min_addr || addr > soft_max_addr)
+ return -1;
+
+ for (i = SOFT_FP_REGNUM; i < M68HC11_ALL_REGS; i++)
+ {
+ if (soft_regs[i].name && soft_regs[i].addr == addr)
+ return i;
+ }
+ return -1;
+}
+
+/* Fetch a pseudo register. The 68hc11 soft registers are treated like
+ pseudo registers. They are located in memory. Translate the register
+ fetch into a memory read. */
+void
+m68hc11_fetch_pseudo_register (int regno)
+{
+ char buf[MAX_REGISTER_RAW_SIZE];
+
+ m68hc11_initialize_register_info ();
+
+ /* Fetch a soft register: translate into a memory read. */
+ if (soft_regs[regno].name)
+ {
+ target_read_memory (soft_regs[regno].addr, buf, 2);
+ }
+ else
+ {
+ memset (buf, 0, 2);
+ }
+ supply_register (regno, buf);
+}
+
+/* Store a pseudo register. Translate the register store
+ into a memory write. */
+static void
+m68hc11_store_pseudo_register (int regno)
+{
+ m68hc11_initialize_register_info ();
+
+ /* Store a soft register: translate into a memory write. */
+ if (soft_regs[regno].name)
+ {
+ char buf[MAX_REGISTER_RAW_SIZE];
+
+ read_register_gen (regno, buf);
+ target_write_memory (soft_regs[regno].addr, buf, 2);
+ }
+}
+
+static char *
+m68hc11_register_name (int reg_nr)
+{
+ if (reg_nr < 0)
+ return NULL;
+ if (reg_nr >= M68HC11_ALL_REGS)
+ return NULL;
+
+ /* If we don't know the address of a soft register, pretend it
+ does not exist. */
+ if (reg_nr > M68HC11_LAST_HARD_REG && soft_regs[reg_nr].name == 0)
+ return NULL;
+ return m68hc11_register_names[reg_nr];
+}
+
+static const unsigned char *
+m68hc11_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+ static unsigned char breakpoint[] = {0x0};
+
+ *lenptr = sizeof (breakpoint);
+ return breakpoint;
+}
+
+/* Immediately after a function call, return the saved pc before the frame
+ is setup. */
+
+static CORE_ADDR
+m68hc11_saved_pc_after_call (struct frame_info *frame)
+{
+ CORE_ADDR addr;
+
+ addr = read_register (HARD_SP_REGNUM) + STACK_CORRECTION;
+ addr &= 0x0ffff;
+ return read_memory_integer (addr, 2) & 0x0FFFF;
+}
+
+static CORE_ADDR
+m68hc11_frame_saved_pc (struct frame_info *frame)
+{
+ return frame->extra_info->return_pc;
+}
+
+static CORE_ADDR
+m68hc11_frame_args_address (struct frame_info *frame)
+{
+ return frame->frame + frame->extra_info->size + STACK_CORRECTION + 2;
+}
+
+static CORE_ADDR
+m68hc11_frame_locals_address (struct frame_info *frame)
+{
+ return frame->frame;
+}
+
+/* Discard from the stack the innermost frame, restoring all saved
+ registers. */
+
+static void
+m68hc11_pop_frame (void)
+{
+ register struct frame_info *frame = get_current_frame ();
+ register CORE_ADDR fp, sp;
+ register int regnum;
+
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ generic_pop_dummy_frame ();
+ else
+ {
+ fp = FRAME_FP (frame);
+ FRAME_INIT_SAVED_REGS (frame);
+
+ /* Copy regs from where they were saved in the frame. */
+ for (regnum = 0; regnum < M68HC11_ALL_REGS; regnum++)
+ if (frame->saved_regs[regnum])
+ write_register (regnum,
+ read_memory_integer (frame->saved_regs[regnum], 2));
+
+ write_register (HARD_PC_REGNUM, frame->extra_info->return_pc);
+ sp = (fp + frame->extra_info->size + 2) & 0x0ffff;
+ write_register (HARD_SP_REGNUM, sp);
+ }
+ flush_cached_frames ();
+}
+
+
+/* 68HC11 & 68HC12 prologue analysis.
+
+ */
+#define MAX_CODES 12
+
+/* 68HC11 opcodes. */
+#undef M6811_OP_PAGE2
+#define M6811_OP_PAGE2 (0x18)
+#define M6811_OP_LDX (0xde)
+#define M6811_OP_PSHX (0x3c)
+#define M6811_OP_STS (0x9f)
+#define M6811_OP_TSX (0x30)
+#define M6811_OP_XGDX (0x8f)
+#define M6811_OP_ADDD (0xc3)
+#define M6811_OP_TXS (0x35)
+#define M6811_OP_DES (0x34)
+
+/* 68HC12 opcodes. */
+#define M6812_OP_PAGE2 (0x18)
+#define M6812_OP_MOVW (0x01)
+#define M6812_PB_PSHW (0xae)
+#define M6812_OP_STS (0x7f)
+#define M6812_OP_LEAS (0x1b)
+
+/* Operand extraction. */
+#define OP_DIRECT (0x100) /* 8-byte direct addressing. */
+#define OP_IMM_LOW (0x200) /* Low part of 16-bit constant/address. */
+#define OP_IMM_HIGH (0x300) /* High part of 16-bit constant/address. */
+#define OP_PBYTE (0x400) /* 68HC12 indexed operand. */
+
+/* Identification of the sequence. */
+enum m6811_seq_type
+{
+ P_LAST = 0,
+ P_SAVE_REG, /* Save a register on the stack. */
+ P_SET_FRAME, /* Setup the frame pointer. */
+ P_LOCAL_1, /* Allocate 1 byte for locals. */
+ P_LOCAL_2, /* Allocate 2 bytes for locals. */
+ P_LOCAL_N /* Allocate N bytes for locals. */
+};
+
+struct insn_sequence {
+ enum m6811_seq_type type;
+ unsigned length;
+ unsigned short code[MAX_CODES];
+};
+
+/* Sequence of instructions in the 68HC11 function prologue. */
+static struct insn_sequence m6811_prologue[] = {
+ /* Sequences to save a soft-register. */
+ { P_SAVE_REG, 3, { M6811_OP_LDX, OP_DIRECT,
+ M6811_OP_PSHX } },
+ { P_SAVE_REG, 5, { M6811_OP_PAGE2, M6811_OP_LDX, OP_DIRECT,
+ M6811_OP_PAGE2, M6811_OP_PSHX } },
+
+ /* Sequences to allocate local variables. */
+ { P_LOCAL_N, 7, { M6811_OP_TSX,
+ M6811_OP_XGDX,
+ M6811_OP_ADDD, OP_IMM_HIGH, OP_IMM_LOW,
+ M6811_OP_XGDX,
+ M6811_OP_TXS } },
+ { P_LOCAL_N, 11, { M6811_OP_PAGE2, M6811_OP_TSX,
+ M6811_OP_PAGE2, M6811_OP_XGDX,
+ M6811_OP_ADDD, OP_IMM_HIGH, OP_IMM_LOW,
+ M6811_OP_PAGE2, M6811_OP_XGDX,
+ M6811_OP_PAGE2, M6811_OP_TXS } },
+ { P_LOCAL_1, 1, { M6811_OP_DES } },
+ { P_LOCAL_2, 1, { M6811_OP_PSHX } },
+ { P_LOCAL_2, 2, { M6811_OP_PAGE2, M6811_OP_PSHX } },
+
+ /* Initialize the frame pointer. */
+ { P_SET_FRAME, 2, { M6811_OP_STS, OP_DIRECT } },
+ { P_LAST, 0, { 0 } }
+};
+
+
+/* Sequence of instructions in the 68HC12 function prologue. */
+static struct insn_sequence m6812_prologue[] = {
+ { P_SAVE_REG, 5, { M6812_OP_PAGE2, M6812_OP_MOVW, M6812_PB_PSHW,
+ OP_IMM_HIGH, OP_IMM_LOW } },
+ { P_SET_FRAME, 3, { M6812_OP_STS, OP_IMM_HIGH, OP_IMM_LOW } },
+ { P_LOCAL_N, 2, { M6812_OP_LEAS, OP_PBYTE } },
+ { P_LAST, 0 }
+};
+
+
+/* Analyze the sequence of instructions starting at the given address.
+ Returns a pointer to the sequence when it is recognized and
+ the optional value (constant/address) associated with it.
+ Advance the pc for the next sequence. */
+static struct insn_sequence *
+m68hc11_analyze_instruction (struct insn_sequence *seq, CORE_ADDR *pc,
+ CORE_ADDR *val)
+{
+ unsigned char buffer[MAX_CODES];
+ unsigned bufsize;
+ unsigned j;
+ CORE_ADDR cur_val;
+ short v = 0;
+
+ bufsize = 0;
+ for (; seq->type != P_LAST; seq++)
+ {
+ cur_val = 0;
+ for (j = 0; j < seq->length; j++)
+ {
+ if (bufsize < j + 1)
+ {
+ buffer[bufsize] = read_memory_unsigned_integer (*pc + bufsize,
+ 1);
+ bufsize++;
+ }
+ /* Continue while we match the opcode. */
+ if (seq->code[j] == buffer[j])
+ continue;
+
+ if ((seq->code[j] & 0xf00) == 0)
+ break;
+
+ /* Extract a sequence parameter (address or constant). */
+ switch (seq->code[j])
+ {
+ case OP_DIRECT:
+ cur_val = (CORE_ADDR) buffer[j];
+ break;
+
+ case OP_IMM_HIGH:
+ cur_val = cur_val & 0x0ff;
+ cur_val |= (buffer[j] << 8);
+ break;
+
+ case OP_IMM_LOW:
+ cur_val &= 0x0ff00;
+ cur_val |= buffer[j];
+ break;
+
+ case OP_PBYTE:
+ if ((buffer[j] & 0xE0) == 0x80)
+ {
+ v = buffer[j] & 0x1f;
+ if (v & 0x10)
+ v |= 0xfff0;
+ }
+ else if ((buffer[j] & 0xfe) == 0xf0)
+ {
+ v = read_memory_unsigned_integer (*pc + j + 1, 1);
+ if (buffer[j] & 1)
+ v |= 0xff00;
+ *pc = *pc + 1;
+ }
+ else if (buffer[j] == 0xf2)
+ {
+ v = read_memory_unsigned_integer (*pc + j + 1, 2);
+ *pc = *pc + 2;
+ }
+ cur_val = v;
+ break;
+ }
+ }
+
+ /* We have a full match. */
+ if (j == seq->length)
+ {
+ *val = cur_val;
+ *pc = *pc + j;
+ return seq;
+ }
+ }
+ return 0;
+}
+
+/* Analyze the function prologue to find some information
+ about the function:
+ - the PC of the first line (for m68hc11_skip_prologue)
+ - the offset of the previous frame saved address (from current frame)
+ - the soft registers which are pushed. */
+static void
+m68hc11_guess_from_prologue (CORE_ADDR pc, CORE_ADDR fp,
+ CORE_ADDR *first_line,
+ int *frame_offset, CORE_ADDR *pushed_regs)
+{
+ CORE_ADDR save_addr;
+ CORE_ADDR func_end;
+ int size;
+ int found_frame_point;
+ int saved_reg;
+ CORE_ADDR first_pc;
+ int done = 0;
+ struct insn_sequence *seq_table;
+
+ first_pc = get_pc_function_start (pc);
+ size = 0;
+
+ m68hc11_initialize_register_info ();
+ if (first_pc == 0)
+ {
+ *frame_offset = 0;
+ *first_line = pc;
+ return;
+ }
+
+ seq_table = gdbarch_tdep (current_gdbarch)->prologue;
+
+ /* The 68hc11 stack is as follows:
+
+
+ | |
+ +-----------+
+ | |
+ | args |
+ | |
+ +-----------+
+ | PC-return |
+ +-----------+
+ | Old frame |
+ +-----------+
+ | |
+ | Locals |
+ | |
+ +-----------+ <--- current frame
+ | |
+
+ With most processors (like 68K) the previous frame can be computed
+ easily because it is always at a fixed offset (see link/unlink).
+ That is, locals are accessed with negative offsets, arguments are
+ accessed with positive ones. Since 68hc11 only supports offsets
+ in the range [0..255], the frame is defined at the bottom of
+ locals (see picture).
+
+ The purpose of the analysis made here is to find out the size
+ of locals in this function. An alternative to this is to use
+ DWARF2 info. This would be better but I don't know how to
+ access dwarf2 debug from this function.
+
+ Walk from the function entry point to the point where we save
+ the frame. While walking instructions, compute the size of bytes
+ which are pushed. This gives us the index to access the previous
+ frame.
+
+ We limit the search to 128 bytes so that the algorithm is bounded
+ in case of random and wrong code. We also stop and abort if
+ we find an instruction which is not supposed to appear in the
+ prologue (as generated by gcc 2.95, 2.96).
+ */
+ pc = first_pc;
+ func_end = pc + 128;
+ found_frame_point = 0;
+ *frame_offset = 0;
+ save_addr = fp + STACK_CORRECTION;
+ while (!done && pc + 2 < func_end)
+ {
+ struct insn_sequence *seq;
+ CORE_ADDR val;
+
+ seq = m68hc11_analyze_instruction (seq_table, &pc, &val);
+ if (seq == 0)
+ break;
+
+ if (seq->type == P_SAVE_REG)
+ {
+ if (found_frame_point)
+ {
+ saved_reg = m68hc11_which_soft_register (val);
+ if (saved_reg < 0)
+ break;
+
+ save_addr -= 2;
+ if (pushed_regs)
+ pushed_regs[saved_reg] = save_addr;
+ }
+ else
+ {
+ size += 2;
+ }
+ }
+ else if (seq->type == P_SET_FRAME)
+ {
+ found_frame_point = 1;
+ *frame_offset = size;
+ }
+ else if (seq->type == P_LOCAL_1)
+ {
+ size += 1;
+ }
+ else if (seq->type == P_LOCAL_2)
+ {
+ size += 2;
+ }
+ else if (seq->type == P_LOCAL_N)
+ {
+ /* Stack pointer is decremented for the allocation. */
+ if (val & 0x8000)
+ size -= (int) (val) | 0xffff0000;
+ else
+ size -= val;
+ }
+ }
+ *first_line = pc;
+}
+
+static CORE_ADDR
+m68hc11_skip_prologue (CORE_ADDR pc)
+{
+ CORE_ADDR func_addr, func_end;
+ struct symtab_and_line sal;
+ int frame_offset;
+
+ /* If we have line debugging information, then the end of the
+ prologue should be the first assembly instruction of the
+ first source line. */
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ sal = find_pc_line (func_addr, 0);
+ if (sal.end && sal.end < func_end)
+ return sal.end;
+ }
+
+ m68hc11_guess_from_prologue (pc, 0, &pc, &frame_offset, 0);
+ return pc;
+}
+
+/* Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+*/
+
+static CORE_ADDR
+m68hc11_frame_chain (struct frame_info *frame)
+{
+ CORE_ADDR addr;
+
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ return frame->frame; /* dummy frame same as caller's frame */
+
+ if (frame->extra_info->return_pc == 0
+ || inside_entry_file (frame->extra_info->return_pc))
+ return (CORE_ADDR) 0;
+
+ if (frame->frame == 0)
+ {
+ return (CORE_ADDR) 0;
+ }
+
+ addr = frame->frame + frame->extra_info->size + STACK_CORRECTION - 2;
+ addr = read_memory_unsigned_integer (addr, 2) & 0x0FFFF;
+ if (addr == 0)
+ {
+ return (CORE_ADDR) 0;
+ }
+
+ return addr;
+}
+
+/* Put here the code to store, into a struct frame_saved_regs, the
+ addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special: the address we
+ return for it IS the sp for the next frame. */
+static void
+m68hc11_frame_init_saved_regs (struct frame_info *fi)
+{
+ CORE_ADDR pc;
+ CORE_ADDR addr;
+
+ if (fi->saved_regs == NULL)
+ frame_saved_regs_zalloc (fi);
+ else
+ memset (fi->saved_regs, 0, sizeof (fi->saved_regs));
+
+ pc = fi->pc;
+ m68hc11_guess_from_prologue (pc, fi->frame, &pc, &fi->extra_info->size,
+ fi->saved_regs);
+
+ addr = fi->frame + fi->extra_info->size + STACK_CORRECTION;
+ if (soft_regs[SOFT_FP_REGNUM].name)
+ fi->saved_regs[SOFT_FP_REGNUM] = addr - 2;
+ fi->saved_regs[HARD_SP_REGNUM] = addr;
+ fi->saved_regs[HARD_PC_REGNUM] = fi->saved_regs[HARD_SP_REGNUM];
+}
+
+static void
+m68hc11_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ CORE_ADDR addr;
+
+ fi->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ m68hc11_frame_init_saved_regs (fi);
+
+ if (fromleaf)
+ {
+ fi->extra_info->return_pc = m68hc11_saved_pc_after_call (fi);
+ }
+ else
+ {
+ addr = fi->frame + fi->extra_info->size + STACK_CORRECTION;
+ addr = read_memory_unsigned_integer (addr, 2) & 0x0ffff;
+ fi->extra_info->return_pc = addr;
+#if 0
+ printf ("Pc@0x%04x, FR 0x%04x, size %d, read ret @0x%04x -> 0x%04x\n",
+ fi->pc,
+ fi->frame, fi->size,
+ addr & 0x0ffff,
+ fi->return_pc);
+#endif
+ }
+}
+
+/* Same as 'info reg' but prints the registers in a different way. */
+static void
+show_regs (char *args, int from_tty)
+{
+ int ccr = read_register (HARD_CCR_REGNUM);
+ int i;
+ int nr;
+
+ printf_filtered ("PC=%04x SP=%04x FP=%04x CCR=%02x %c%c%c%c%c%c%c%c\n",
+ (int) read_register (HARD_PC_REGNUM),
+ (int) read_register (HARD_SP_REGNUM),
+ (int) read_register (SOFT_FP_REGNUM),
+ ccr,
+ ccr & M6811_S_BIT ? 'S' : '-',
+ ccr & M6811_X_BIT ? 'X' : '-',
+ ccr & M6811_H_BIT ? 'H' : '-',
+ ccr & M6811_I_BIT ? 'I' : '-',
+ ccr & M6811_N_BIT ? 'N' : '-',
+ ccr & M6811_Z_BIT ? 'Z' : '-',
+ ccr & M6811_V_BIT ? 'V' : '-',
+ ccr & M6811_C_BIT ? 'C' : '-');
+
+ printf_filtered ("D=%04x IX=%04x IY=%04x\n",
+ (int) read_register (HARD_D_REGNUM),
+ (int) read_register (HARD_X_REGNUM),
+ (int) read_register (HARD_Y_REGNUM));
+
+ nr = 0;
+ for (i = SOFT_D1_REGNUM; i < M68HC11_ALL_REGS; i++)
+ {
+ /* Skip registers which are not defined in the symbol table. */
+ if (soft_regs[i].name == 0)
+ continue;
+
+ printf_filtered ("D%d=%04x",
+ i - SOFT_D1_REGNUM + 1,
+ (int) read_register (i));
+ nr++;
+ if ((nr % 8) == 7)
+ printf_filtered ("\n");
+ else
+ printf_filtered (" ");
+ }
+ if (nr && (nr % 8) != 7)
+ printf_filtered ("\n");
+}
+
+static CORE_ADDR
+m68hc11_stack_align (CORE_ADDR addr)
+{
+ return ((addr + 1) & -2);
+}
+
+static CORE_ADDR
+m68hc11_push_arguments (int nargs,
+ struct value **args,
+ CORE_ADDR sp,
+ int struct_return,
+ CORE_ADDR struct_addr)
+{
+ int stack_alloc;
+ int argnum;
+ int first_stack_argnum;
+ int stack_offset;
+ struct type *type;
+ char *val;
+ int len;
+
+ stack_alloc = 0;
+ first_stack_argnum = 0;
+ if (struct_return)
+ {
+ /* The struct is allocated on the stack and gdb used the stack
+ pointer for the address of that struct. We must apply the
+ stack offset on the address. */
+ write_register (HARD_D_REGNUM, struct_addr + STACK_CORRECTION);
+ }
+ else if (nargs > 0)
+ {
+ type = VALUE_TYPE (args[0]);
+ len = TYPE_LENGTH (type);
+
+ /* First argument is passed in D and X registers. */
+ if (len <= 4)
+ {
+ LONGEST v = extract_unsigned_integer (VALUE_CONTENTS (args[0]), len);
+ first_stack_argnum = 1;
+ write_register (HARD_D_REGNUM, v);
+ if (len > 2)
+ {
+ v >>= 16;
+ write_register (HARD_X_REGNUM, v);
+ }
+ }
+ }
+ for (argnum = first_stack_argnum; argnum < nargs; argnum++)
+ {
+ type = VALUE_TYPE (args[argnum]);
+ stack_alloc += (TYPE_LENGTH (type) + 1) & -2;
+ }
+ sp -= stack_alloc;
+
+ stack_offset = STACK_CORRECTION;
+ for (argnum = first_stack_argnum; argnum < nargs; argnum++)
+ {
+ type = VALUE_TYPE (args[argnum]);
+ len = TYPE_LENGTH (type);
+
+ val = (char*) VALUE_CONTENTS (args[argnum]);
+ write_memory (sp + stack_offset, val, len);
+ stack_offset += len;
+ if (len & 1)
+ {
+ static char zero = 0;
+
+ write_memory (sp + stack_offset, &zero, 1);
+ stack_offset++;
+ }
+ }
+ return sp;
+}
+
+
+/* Return a location where we can set a breakpoint that will be hit
+ when an inferior function call returns. */
+CORE_ADDR
+m68hc11_call_dummy_address (void)
+{
+ return entry_point_address ();
+}
+
+static struct type *
+m68hc11_register_virtual_type (int reg_nr)
+{
+ return builtin_type_uint16;
+}
+
+static void
+m68hc11_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ /* The struct address computed by gdb is on the stack.
+ It uses the stack pointer so we must apply the stack
+ correction offset. */
+ write_register (HARD_D_REGNUM, addr + STACK_CORRECTION);
+}
+
+static void
+m68hc11_store_return_value (struct type *type, char *valbuf)
+{
+ int len;
+
+ len = TYPE_LENGTH (type);
+
+ /* First argument is passed in D and X registers. */
+ if (len <= 4)
+ {
+ LONGEST v = extract_unsigned_integer (valbuf, len);
+
+ write_register (HARD_D_REGNUM, v);
+ if (len > 2)
+ {
+ v >>= 16;
+ write_register (HARD_X_REGNUM, v);
+ }
+ }
+ else
+ error ("return of value > 4 is not supported.");
+}
+
+
+/* Given a return value in `regbuf' with a type `type',
+ extract and copy its value into `valbuf'. */
+
+static void
+m68hc11_extract_return_value (struct type *type,
+ char *regbuf,
+ char *valbuf)
+{
+ int len = TYPE_LENGTH (type);
+
+ switch (len)
+ {
+ case 1:
+ memcpy (valbuf, &regbuf[HARD_D_REGNUM * 2 + 1], len);
+ break;
+
+ case 2:
+ memcpy (valbuf, &regbuf[HARD_D_REGNUM * 2], len);
+ break;
+
+ case 3:
+ memcpy (&valbuf[0], &regbuf[HARD_X_REGNUM * 2 + 1], 1);
+ memcpy (&valbuf[1], &regbuf[HARD_D_REGNUM * 2], 2);
+ break;
+
+ case 4:
+ memcpy (&valbuf[0], &regbuf[HARD_X_REGNUM * 2], 2);
+ memcpy (&valbuf[2], &regbuf[HARD_D_REGNUM * 2], 2);
+ break;
+
+ default:
+ error ("bad size for return value");
+ }
+}
+
+/* Should call_function allocate stack space for a struct return? */
+static int
+m68hc11_use_struct_convention (int gcc_p, struct type *type)
+{
+ return (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION
+ || TYPE_LENGTH (type) > 4);
+}
+
+static int
+m68hc11_return_value_on_stack (struct type *type)
+{
+ return TYPE_LENGTH (type) > 4;
+}
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+static CORE_ADDR
+m68hc11_extract_struct_value_address (char *regbuf)
+{
+ return extract_address (&regbuf[HARD_D_REGNUM * 2],
+ REGISTER_RAW_SIZE (HARD_D_REGNUM));
+}
+
+/* Function: push_return_address (pc)
+ Set up the return address for the inferior function call.
+ Needed for targets where we don't actually execute a JSR/BSR instruction */
+
+static CORE_ADDR
+m68hc11_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ char valbuf[2];
+
+ pc = CALL_DUMMY_ADDRESS ();
+ sp -= 2;
+ store_unsigned_integer (valbuf, 2, pc);
+ write_memory (sp + STACK_CORRECTION, valbuf, 2);
+ return sp;
+}
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+static int
+m68hc11_register_byte (int reg_nr)
+{
+ return (reg_nr * M68HC11_REG_SIZE);
+}
+
+static int
+m68hc11_register_raw_size (int reg_nr)
+{
+ return M68HC11_REG_SIZE;
+}
+
+static int
+gdb_print_insn_m68hc11 (bfd_vma memaddr, disassemble_info *info)
+{
+ if (TARGET_ARCHITECTURE->arch == bfd_arch_m68hc11)
+ return print_insn_m68hc11 (memaddr, info);
+ else
+ return print_insn_m68hc12 (memaddr, info);
+}
+
+static struct gdbarch *
+m68hc11_gdbarch_init (struct gdbarch_info info,
+ struct gdbarch_list *arches)
+{
+ static LONGEST m68hc11_call_dummy_words[] =
+ {0};
+ struct gdbarch *gdbarch;
+ struct gdbarch_tdep *tdep;
+
+ soft_reg_initialized = 0;
+
+ /* try to find a pre-existing architecture */
+ for (arches = gdbarch_list_lookup_by_info (arches, &info);
+ arches != NULL;
+ arches = gdbarch_list_lookup_by_info (arches->next, &info))
+ {
+ return arches->gdbarch;
+ }
+
+ /* Need a new architecture. Fill in a target specific vector. */
+ tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ switch (info.bfd_arch_info->arch)
+ {
+ case bfd_arch_m68hc11:
+ tdep->stack_correction = 1;
+ tdep->prologue = m6811_prologue;
+ break;
+
+ case bfd_arch_m68hc12:
+ tdep->stack_correction = 0;
+ tdep->prologue = m6812_prologue;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Initially set everything according to the ABI.
+ Use 16-bit integers since it will be the case for most
+ programs. The size of these types should normally be set
+ according to the dwarf2 debug information. */
+ set_gdbarch_short_bit (gdbarch, 16);
+ set_gdbarch_int_bit (gdbarch, 16);
+ set_gdbarch_float_bit (gdbarch, 32);
+ set_gdbarch_double_bit (gdbarch, 64);
+ set_gdbarch_long_double_bit (gdbarch, 64);
+ set_gdbarch_long_bit (gdbarch, 32);
+ set_gdbarch_ptr_bit (gdbarch, 16);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+
+ /* Set register info. */
+ set_gdbarch_fp0_regnum (gdbarch, -1);
+ set_gdbarch_max_register_raw_size (gdbarch, 2);
+ set_gdbarch_max_register_virtual_size (gdbarch, 2);
+ set_gdbarch_register_raw_size (gdbarch, m68hc11_register_raw_size);
+ set_gdbarch_register_virtual_size (gdbarch, m68hc11_register_raw_size);
+ set_gdbarch_register_byte (gdbarch, m68hc11_register_byte);
+ set_gdbarch_frame_init_saved_regs (gdbarch, m68hc11_frame_init_saved_regs);
+ set_gdbarch_frame_args_skip (gdbarch, 0);
+
+ set_gdbarch_read_pc (gdbarch, generic_target_read_pc);
+ set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
+ set_gdbarch_read_fp (gdbarch, generic_target_read_fp);
+ set_gdbarch_read_sp (gdbarch, generic_target_read_sp);
+ set_gdbarch_write_sp (gdbarch, generic_target_write_sp);
+
+ set_gdbarch_num_regs (gdbarch, M68HC11_NUM_REGS);
+ set_gdbarch_num_pseudo_regs (gdbarch, M68HC11_NUM_PSEUDO_REGS);
+ set_gdbarch_sp_regnum (gdbarch, HARD_SP_REGNUM);
+ set_gdbarch_fp_regnum (gdbarch, SOFT_FP_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, HARD_PC_REGNUM);
+ set_gdbarch_register_name (gdbarch, m68hc11_register_name);
+ set_gdbarch_register_size (gdbarch, 2);
+ set_gdbarch_register_bytes (gdbarch, M68HC11_ALL_REGS * 2);
+ set_gdbarch_register_virtual_type (gdbarch, m68hc11_register_virtual_type);
+ set_gdbarch_fetch_pseudo_register (gdbarch, m68hc11_fetch_pseudo_register);
+ set_gdbarch_store_pseudo_register (gdbarch, m68hc11_store_pseudo_register);
+
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_address (gdbarch, m68hc11_call_dummy_address);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1); /*???*/
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
+ set_gdbarch_call_dummy_words (gdbarch, m68hc11_call_dummy_words);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch,
+ sizeof (m68hc11_call_dummy_words));
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+ set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
+ set_gdbarch_extract_return_value (gdbarch, m68hc11_extract_return_value);
+ set_gdbarch_push_arguments (gdbarch, m68hc11_push_arguments);
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+ set_gdbarch_push_return_address (gdbarch, m68hc11_push_return_address);
+ set_gdbarch_return_value_on_stack (gdbarch, m68hc11_return_value_on_stack);
+
+ set_gdbarch_store_struct_return (gdbarch, m68hc11_store_struct_return);
+ set_gdbarch_store_return_value (gdbarch, m68hc11_store_return_value);
+ set_gdbarch_extract_struct_value_address (gdbarch,
+ m68hc11_extract_struct_value_address);
+ set_gdbarch_register_convertible (gdbarch, generic_register_convertible_not);
+
+
+ set_gdbarch_frame_chain (gdbarch, m68hc11_frame_chain);
+ set_gdbarch_frame_chain_valid (gdbarch, generic_file_frame_chain_valid);
+ set_gdbarch_frame_saved_pc (gdbarch, m68hc11_frame_saved_pc);
+ set_gdbarch_frame_args_address (gdbarch, m68hc11_frame_args_address);
+ set_gdbarch_frame_locals_address (gdbarch, m68hc11_frame_locals_address);
+ set_gdbarch_saved_pc_after_call (gdbarch, m68hc11_saved_pc_after_call);
+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+
+ set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
+ set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+
+ set_gdbarch_store_struct_return (gdbarch, m68hc11_store_struct_return);
+ set_gdbarch_store_return_value (gdbarch, m68hc11_store_return_value);
+ set_gdbarch_extract_struct_value_address
+ (gdbarch, m68hc11_extract_struct_value_address);
+ set_gdbarch_use_struct_convention (gdbarch, m68hc11_use_struct_convention);
+ set_gdbarch_init_extra_frame_info (gdbarch, m68hc11_init_extra_frame_info);
+ set_gdbarch_pop_frame (gdbarch, m68hc11_pop_frame);
+ set_gdbarch_skip_prologue (gdbarch, m68hc11_skip_prologue);
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+ set_gdbarch_function_start_offset (gdbarch, 0);
+ set_gdbarch_breakpoint_from_pc (gdbarch, m68hc11_breakpoint_from_pc);
+ set_gdbarch_stack_align (gdbarch, m68hc11_stack_align);
+ set_gdbarch_print_insn (gdbarch, gdb_print_insn_m68hc11);
+
+ set_gdbarch_believe_pcc_promotion (gdbarch, 1);
+
+ return gdbarch;
+}
+
+void
+_initialize_m68hc11_tdep (void)
+{
+ register_gdbarch_init (bfd_arch_m68hc11, m68hc11_gdbarch_init);
+ register_gdbarch_init (bfd_arch_m68hc12, m68hc11_gdbarch_init);
+
+ add_com ("regs", class_vars, show_regs, "Print all registers");
+}
+
diff --git a/gdb/m68k-stub.c b/gdb/m68k-stub.c
new file mode 100644
index 00000000000..54e06b13ccb
--- /dev/null
+++ b/gdb/m68k-stub.c
@@ -0,0 +1,1098 @@
+/****************************************************************************
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ HP offers the following for use in the public domain. HP makes no
+ warranty with regard to the software or it's performance and the
+ user accepts the software "AS IS" with all faults.
+
+ HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+ TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ * Module name: remcom.c $
+ * Revision: 1.34 $
+ * Date: 91/03/09 12:29:49 $
+ * Contributor: Lake Stevens Instrument Division$
+ *
+ * Description: low level support for gdb debugger. $
+ *
+ * Considerations: only works on target hardware $
+ *
+ * Written by: Glenn Engel $
+ * ModuleState: Experimental $
+ *
+ * NOTES: See Below $
+ *
+ * To enable debugger support, two things need to happen. One, a
+ * call to set_debug_traps() is necessary in order to allow any breakpoints
+ * or error conditions to be properly intercepted and reported to gdb.
+ * Two, a breakpoint needs to be generated to begin communication. This
+ * is most easily accomplished by a call to breakpoint(). Breakpoint()
+ * simulates a breakpoint by executing a trap #1. The breakpoint instruction
+ * is hardwired to trap #1 because not to do so is a compatibility problem--
+ * there either should be a standard breakpoint instruction, or the protocol
+ * should be extended to provide some means to communicate which breakpoint
+ * instruction is in use (or have the stub insert the breakpoint).
+ *
+ * Some explanation is probably necessary to explain how exceptions are
+ * handled. When an exception is encountered the 68000 pushes the current
+ * program counter and status register onto the supervisor stack and then
+ * transfers execution to a location specified in it's vector table.
+ * The handlers for the exception vectors are hardwired to jmp to an address
+ * given by the relation: (exception - 256) * 6. These are decending
+ * addresses starting from -6, -12, -18, ... By allowing 6 bytes for
+ * each entry, a jsr, jmp, bsr, ... can be used to enter the exception
+ * handler. Using a jsr to handle an exception has an added benefit of
+ * allowing a single handler to service several exceptions and use the
+ * return address as the key differentiation. The vector number can be
+ * computed from the return address by [ exception = (addr + 1530) / 6 ].
+ * The sole purpose of the routine _catchException is to compute the
+ * exception number and push it on the stack in place of the return address.
+ * The external function exceptionHandler() is
+ * used to attach a specific handler to a specific m68k exception.
+ * For 68020 machines, the ability to have a return address around just
+ * so the vector can be determined is not necessary because the '020 pushes an
+ * extra word onto the stack containing the vector offset
+ *
+ * Because gdb will sometimes write to the stack area to execute function
+ * calls, this program cannot rely on using the supervisor stack so it
+ * uses it's own stack area reserved in the int array remcomStack.
+ *
+ *************
+ *
+ * The following gdb commands are supported:
+ *
+ * command function Return value
+ *
+ * g return the value of the CPU registers hex data or ENN
+ * G set the value of the CPU registers OK or ENN
+ *
+ * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
+ * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
+ *
+ * c Resume at current address SNN ( signal NN)
+ * cAA..AA Continue at address AA..AA SNN
+ *
+ * s Step one instruction SNN
+ * sAA..AA Step one instruction from AA..AA SNN
+ *
+ * k kill
+ *
+ * ? What was the last sigval ? SNN (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum. A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer. '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host: Reply:
+ * $m0,10#2a +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <setjmp.h>
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+typedef void (*ExceptionHook)(int); /* pointer to function with int parm */
+typedef void (*Function)(); /* pointer to a function */
+
+extern void putDebugChar(); /* write a single character */
+extern int getDebugChar(); /* read and return a single char */
+
+extern Function exceptionHandler(); /* assign an exception handler */
+extern ExceptionHook exceptionHook; /* hook variable for errors/exceptions */
+
+/************************/
+/* FORWARD DECLARATIONS */
+/************************/
+static void
+initializeRemcomErrorFrame ();
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 400
+
+static char initialized; /* boolean flag. != 0 means we've been initialized */
+
+int remote_debug;
+/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
+
+static const char hexchars[]="0123456789abcdef";
+
+/* there are 180 bytes of registers on a 68020 w/68881 */
+/* many of the fpa registers are 12 byte (96 bit) registers */
+#define NUMREGBYTES 180
+enum regnames {D0,D1,D2,D3,D4,D5,D6,D7,
+ A0,A1,A2,A3,A4,A5,A6,A7,
+ PS,PC,
+ FP0,FP1,FP2,FP3,FP4,FP5,FP6,FP7,
+ FPCONTROL,FPSTATUS,FPIADDR
+ };
+
+
+/* We keep a whole frame cache here. "Why?", I hear you cry, "doesn't
+ GDB handle that sort of thing?" Well, yes, I believe the only
+ reason for this cache is to save and restore floating point state
+ (fsave/frestore). A cleaner way to do this would be to make the
+ fsave data part of the registers which GDB deals with like any
+ other registers. This should not be a performance problem if the
+ ability to read individual registers is added to the protocol. */
+
+typedef struct FrameStruct
+{
+ struct FrameStruct *previous;
+ int exceptionPC; /* pc value when this frame created */
+ int exceptionVector; /* cpu vector causing exception */
+ short frameSize; /* size of cpu frame in words */
+ short sr; /* for 68000, this not always sr */
+ int pc;
+ short format;
+ int fsaveHeader;
+ int morejunk[0]; /* exception frame, fp save... */
+} Frame;
+
+#define FRAMESIZE 500
+int gdbFrameStack[FRAMESIZE];
+static Frame *lastFrame;
+
+/*
+ * these should not be static cuz they can be used outside this module
+ */
+int registers[NUMREGBYTES/4];
+int superStack;
+
+#define STACKSIZE 10000
+int remcomStack[STACKSIZE/sizeof(int)];
+static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
+
+/*
+ * In many cases, the system will want to continue exception processing
+ * when a continue command is given.
+ * oldExceptionHook is a function to invoke in this case.
+ */
+
+static ExceptionHook oldExceptionHook;
+
+#ifdef mc68020
+/* the size of the exception stack on the 68020 varies with the type of
+ * exception. The following table is the number of WORDS used
+ * for each exception format.
+ */
+const short exceptionSize[] = { 4,4,6,4,4,4,4,4,29,10,16,46,12,4,4,4 };
+#endif
+
+#ifdef mc68332
+static const short exceptionSize[] = { 4,4,6,4,4,4,4,4,4,4,4,4,16,4,4,4 };
+#endif
+
+/************* jump buffer used for setjmp/longjmp **************************/
+jmp_buf remcomEnv;
+
+/*************************** ASSEMBLY CODE MACROS *************************/
+/* */
+
+#ifdef __HAVE_68881__
+/* do an fsave, then remember the address to begin a restore from */
+#define SAVE_FP_REGS() asm(" fsave a0@-"); \
+ asm(" fmovemx fp0-fp7,_registers+72"); \
+ asm(" fmoveml fpcr/fpsr/fpi,_registers+168");
+#define RESTORE_FP_REGS() \
+asm(" \n\
+ fmoveml _registers+168,fpcr/fpsr/fpi \n\
+ fmovemx _registers+72,fp0-fp7 \n\
+ cmpl #-1,a0@ | skip frestore flag set ? \n\
+ beq skip_frestore \n\
+ frestore a0@+ \n\
+skip_frestore: \n\
+");
+
+#else
+#define SAVE_FP_REGS()
+#define RESTORE_FP_REGS()
+#endif /* __HAVE_68881__ */
+
+void return_to_super();
+void return_to_user();
+
+asm("
+.text
+.globl _return_to_super
+_return_to_super:
+ movel _registers+60,sp /* get new stack pointer */
+ movel _lastFrame,a0 /* get last frame info */
+ bra return_to_any
+
+.globl _return_to_user
+_return_to_user:
+ movel _registers+60,a0 /* get usp */
+ movel a0,usp /* set usp */
+ movel _superStack,sp /* get original stack pointer */
+
+return_to_any:
+ movel _lastFrame,a0 /* get last frame info */
+ movel a0@+,_lastFrame /* link in previous frame */
+ addql #8,a0 /* skip over pc, vector#*/
+ movew a0@+,d0 /* get # of words in cpu frame */
+ addw d0,a0 /* point to end of data */
+ addw d0,a0 /* point to end of data */
+ movel a0,a1
+#
+# copy the stack frame
+ subql #1,d0
+copyUserLoop:
+ movew a1@-,sp@-
+ dbf d0,copyUserLoop
+");
+ RESTORE_FP_REGS()
+ asm(" moveml _registers,d0-d7/a0-a6");
+ asm(" rte"); /* pop and go! */
+
+#define DISABLE_INTERRUPTS() asm(" oriw #0x0700,sr");
+#define BREAKPOINT() asm(" trap #1");
+
+/* this function is called immediately when a level 7 interrupt occurs */
+/* if the previous interrupt level was 7 then we're already servicing */
+/* this interrupt and an rte is in order to return to the debugger. */
+/* For the 68000, the offset for sr is 6 due to the jsr return address */
+asm("
+.text
+.globl __debug_level7
+__debug_level7:
+ movew d0,sp@-");
+#if defined (mc68020) || defined (mc68332)
+asm(" movew sp@(2),d0");
+#else
+asm(" movew sp@(6),d0");
+#endif
+asm(" andiw #0x700,d0
+ cmpiw #0x700,d0
+ beq _already7
+ movew sp@+,d0
+ bra __catchException
+_already7:
+ movew sp@+,d0");
+#if !defined (mc68020) && !defined (mc68332)
+asm(" lea sp@(4),sp"); /* pull off 68000 return address */
+#endif
+asm(" rte");
+
+extern void _catchException ();
+
+#if defined (mc68020) || defined (mc68332)
+/* This function is called when a 68020 exception occurs. It saves
+ * all the cpu and fpcp regs in the _registers array, creates a frame on a
+ * linked list of frames which has the cpu and fpcp stack frames needed
+ * to properly restore the context of these processors, and invokes
+ * an exception handler (remcom_handler).
+ *
+ * stack on entry: stack on exit:
+ * N bytes of junk exception # MSWord
+ * Exception Format Word exception # MSWord
+ * Program counter LSWord
+ * Program counter MSWord
+ * Status Register
+ *
+ *
+ */
+asm("
+.text
+.globl __catchException
+__catchException:");
+DISABLE_INTERRUPTS();
+asm("
+ moveml d0-d7/a0-a6,_registers /* save registers */
+ movel _lastFrame,a0 /* last frame pointer */
+");
+SAVE_FP_REGS();
+asm("
+ lea _registers,a5 /* get address of registers */
+ movew sp@,d1 /* get status register */
+ movew d1,a5@(66) /* save sr */
+ movel sp@(2),a4 /* save pc in a4 for later use */
+ movel a4,a5@(68) /* save pc in _regisers[] */
+
+#
+# figure out how many bytes in the stack frame
+ movew sp@(6),d0 /* get '020 exception format */
+ movew d0,d2 /* make a copy of format word */
+ andiw #0xf000,d0 /* mask off format type */
+ rolw #5,d0 /* rotate into the low byte *2 */
+ lea _exceptionSize,a1
+ addw d0,a1 /* index into the table */
+ movew a1@,d0 /* get number of words in frame */
+ movew d0,d3 /* save it */
+ subw d0,a0 /* adjust save pointer */
+ subw d0,a0 /* adjust save pointer(bytes) */
+ movel a0,a1 /* copy save pointer */
+ subql #1,d0 /* predecrement loop counter */
+#
+# copy the frame
+saveFrameLoop:
+ movew sp@+,a1@+
+ dbf d0,saveFrameLoop
+#
+# now that the stack has been clenaed,
+# save the a7 in use at time of exception
+ movel sp,_superStack /* save supervisor sp */
+ andiw #0x2000,d1 /* were we in supervisor mode ? */
+ beq userMode
+ movel a7,a5@(60) /* save a7 */
+ bra a7saveDone
+userMode:
+ movel usp,a1
+ movel a1,a5@(60) /* save user stack pointer */
+a7saveDone:
+
+#
+# save size of frame
+ movew d3,a0@-
+
+#
+# compute exception number
+ andl #0xfff,d2 /* mask off vector offset */
+ lsrw #2,d2 /* divide by 4 to get vect num */
+ movel d2,a0@- /* save it */
+#
+# save pc causing exception
+ movel a4,a0@-
+#
+# save old frame link and set the new value
+ movel _lastFrame,a1 /* last frame pointer */
+ movel a1,a0@- /* save pointer to prev frame */
+ movel a0,_lastFrame
+
+ movel d2,sp@- /* push exception num */
+ movel _exceptionHook,a0 /* get address of handler */
+ jbsr a0@ /* and call it */
+ clrl sp@ /* replace exception num parm with frame ptr */
+ jbsr __returnFromException /* jbsr, but never returns */
+");
+#else /* mc68000 */
+/* This function is called when an exception occurs. It translates the
+ * return address found on the stack into an exception vector # which
+ * is then handled by either handle_exception or a system handler.
+ * _catchException provides a front end for both.
+ *
+ * stack on entry: stack on exit:
+ * Program counter MSWord exception # MSWord
+ * Program counter LSWord exception # MSWord
+ * Status Register
+ * Return Address MSWord
+ * Return Address LSWord
+ */
+asm("
+.text
+.globl __catchException
+__catchException:");
+DISABLE_INTERRUPTS();
+asm("
+ moveml d0-d7/a0-a6,_registers /* save registers */
+ movel _lastFrame,a0 /* last frame pointer */
+");
+SAVE_FP_REGS();
+asm("
+ lea _registers,a5 /* get address of registers */
+ movel sp@+,d2 /* pop return address */
+ addl #1530,d2 /* convert return addr to */
+ divs #6,d2 /* exception number */
+ extl d2
+
+ moveql #3,d3 /* assume a three word frame */
+
+ cmpiw #3,d2 /* bus error or address error ? */
+ bgt normal /* if >3 then normal error */
+ movel sp@+,a0@- /* copy error info to frame buff*/
+ movel sp@+,a0@- /* these are never used */
+ moveql #7,d3 /* this is a 7 word frame */
+
+normal:
+ movew sp@+,d1 /* pop status register */
+ movel sp@+,a4 /* pop program counter */
+ movew d1,a5@(66) /* save sr */
+ movel a4,a5@(68) /* save pc in _regisers[] */
+ movel a4,a0@- /* copy pc to frame buffer */
+ movew d1,a0@- /* copy sr to frame buffer */
+
+ movel sp,_superStack /* save supervisor sp */
+
+ andiw #0x2000,d1 /* were we in supervisor mode ? */
+ beq userMode
+ movel a7,a5@(60) /* save a7 */
+ bra saveDone
+userMode:
+ movel usp,a1 /* save user stack pointer */
+ movel a1,a5@(60) /* save user stack pointer */
+saveDone:
+
+ movew d3,a0@- /* push frame size in words */
+ movel d2,a0@- /* push vector number */
+ movel a4,a0@- /* push exception pc */
+
+#
+# save old frame link and set the new value
+ movel _lastFrame,a1 /* last frame pointer */
+ movel a1,a0@- /* save pointer to prev frame */
+ movel a0,_lastFrame
+
+ movel d2,sp@- /* push exception num */
+ movel _exceptionHook,a0 /* get address of handler */
+ jbsr a0@ /* and call it */
+ clrl sp@ /* replace exception num parm with frame ptr */
+ jbsr __returnFromException /* jbsr, but never returns */
+");
+#endif
+
+
+/*
+ * remcomHandler is a front end for handle_exception. It moves the
+ * stack pointer into an area reserved for debugger use in case the
+ * breakpoint happened in supervisor mode.
+ */
+asm("_remcomHandler:");
+asm(" addl #4,sp"); /* pop off return address */
+asm(" movel sp@+,d0"); /* get the exception number */
+asm(" movel _stackPtr,sp"); /* move to remcom stack area */
+asm(" movel d0,sp@-"); /* push exception onto stack */
+asm(" jbsr _handle_exception"); /* this never returns */
+asm(" rts"); /* return */
+
+void
+_returnFromException (Frame * frame)
+{
+ /* if no passed in frame, use the last one */
+ if (!frame)
+ {
+ frame = lastFrame;
+ frame->frameSize = 4;
+ frame->format = 0;
+ frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info */
+ }
+
+#if !defined (mc68020) && !defined (mc68332)
+ /* a 68000 cannot use the internal info pushed onto a bus error
+ * or address error frame when doing an RTE so don't put this info
+ * onto the stack or the stack will creep every time this happens.
+ */
+ frame->frameSize = 3;
+#endif
+
+ /* throw away any frames in the list after this frame */
+ lastFrame = frame;
+
+ frame->sr = registers[(int) PS];
+ frame->pc = registers[(int) PC];
+
+ if (registers[(int) PS] & 0x2000)
+ {
+ /* return to supervisor mode... */
+ return_to_super ();
+ }
+ else
+ { /* return to user mode */
+ return_to_user ();
+ }
+}
+
+int
+hex (ch)
+ char ch;
+{
+ if ((ch >= 'a') && (ch <= 'f'))
+ return (ch - 'a' + 10);
+ if ((ch >= '0') && (ch <= '9'))
+ return (ch - '0');
+ if ((ch >= 'A') && (ch <= 'F'))
+ return (ch - 'A' + 10);
+ return (-1);
+}
+
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+/* scan for the sequence $<data>#<checksum> */
+
+unsigned char *
+getpacket (void)
+{
+ unsigned char *buffer = &remcomInBuffer[0];
+ unsigned char checksum;
+ unsigned char xmitcsum;
+ int count;
+ char ch;
+
+ while (1)
+ {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = getDebugChar ()) != '$')
+ ;
+
+ retry:
+ checksum = 0;
+ xmitcsum = -1;
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX)
+ {
+ ch = getDebugChar ();
+ if (ch == '$')
+ goto retry;
+ if (ch == '#')
+ break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+ buffer[count] = 0;
+
+ if (ch == '#')
+ {
+ ch = getDebugChar ();
+ xmitcsum = hex (ch) << 4;
+ ch = getDebugChar ();
+ xmitcsum += hex (ch);
+
+ if (checksum != xmitcsum)
+ {
+ if (remote_debug)
+ {
+ fprintf (stderr,
+ "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n",
+ checksum, xmitcsum, buffer);
+ }
+ putDebugChar ('-'); /* failed checksum */
+ }
+ else
+ {
+ putDebugChar ('+'); /* successful transfer */
+
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':')
+ {
+ putDebugChar (buffer[0]);
+ putDebugChar (buffer[1]);
+
+ return &buffer[3];
+ }
+
+ return &buffer[0];
+ }
+ }
+ }
+}
+
+/* send the packet in buffer. */
+
+void
+putpacket (buffer)
+ char *buffer;
+{
+ unsigned char checksum;
+ int count;
+ char ch;
+
+ /* $<packet info>#<checksum>. */
+ do
+ {
+ putDebugChar ('$');
+ checksum = 0;
+ count = 0;
+
+ while (ch = buffer[count])
+ {
+ putDebugChar (ch);
+ checksum += ch;
+ count += 1;
+ }
+
+ putDebugChar ('#');
+ putDebugChar (hexchars[checksum >> 4]);
+ putDebugChar (hexchars[checksum % 16]);
+
+ }
+ while (getDebugChar () != '+');
+
+}
+
+void
+debug_error (format, parm)
+ char *format;
+ char *parm;
+{
+ if (remote_debug)
+ fprintf (stderr, format, parm);
+}
+
+/* convert the memory pointed to by mem into hex, placing result in buf */
+/* return a pointer to the last char put in buf (null) */
+char *
+mem2hex (mem, buf, count)
+ char *mem;
+ char *buf;
+ int count;
+{
+ int i;
+ unsigned char ch;
+ for (i = 0; i < count; i++)
+ {
+ ch = *mem++;
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch % 16];
+ }
+ *buf = 0;
+ return (buf);
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem */
+/* return a pointer to the character AFTER the last byte written */
+char *
+hex2mem (buf, mem, count)
+ char *buf;
+ char *mem;
+ int count;
+{
+ int i;
+ unsigned char ch;
+ for (i = 0; i < count; i++)
+ {
+ ch = hex (*buf++) << 4;
+ ch = ch + hex (*buf++);
+ *mem++ = ch;
+ }
+ return (mem);
+}
+
+/* a bus error has occurred, perform a longjmp
+ to return execution and allow handling of the error */
+
+void
+handle_buserror ()
+{
+ longjmp (remcomEnv, 1);
+}
+
+/* this function takes the 68000 exception number and attempts to
+ translate this number into a unix compatible signal value */
+int
+computeSignal (exceptionVector)
+ int exceptionVector;
+{
+ int sigval;
+ switch (exceptionVector)
+ {
+ case 2:
+ sigval = 10;
+ break; /* bus error */
+ case 3:
+ sigval = 10;
+ break; /* address error */
+ case 4:
+ sigval = 4;
+ break; /* illegal instruction */
+ case 5:
+ sigval = 8;
+ break; /* zero divide */
+ case 6:
+ sigval = 8;
+ break; /* chk instruction */
+ case 7:
+ sigval = 8;
+ break; /* trapv instruction */
+ case 8:
+ sigval = 11;
+ break; /* privilege violation */
+ case 9:
+ sigval = 5;
+ break; /* trace trap */
+ case 10:
+ sigval = 4;
+ break; /* line 1010 emulator */
+ case 11:
+ sigval = 4;
+ break; /* line 1111 emulator */
+
+ /* Coprocessor protocol violation. Using a standard MMU or FPU
+ this cannot be triggered by software. Call it a SIGBUS. */
+ case 13:
+ sigval = 10;
+ break;
+
+ case 31:
+ sigval = 2;
+ break; /* interrupt */
+ case 33:
+ sigval = 5;
+ break; /* breakpoint */
+
+ /* This is a trap #8 instruction. Apparently it is someone's software
+ convention for some sort of SIGFPE condition. Whose? How many
+ people are being screwed by having this code the way it is?
+ Is there a clean solution? */
+ case 40:
+ sigval = 8;
+ break; /* floating point err */
+
+ case 48:
+ sigval = 8;
+ break; /* floating point err */
+ case 49:
+ sigval = 8;
+ break; /* floating point err */
+ case 50:
+ sigval = 8;
+ break; /* zero divide */
+ case 51:
+ sigval = 8;
+ break; /* underflow */
+ case 52:
+ sigval = 8;
+ break; /* operand error */
+ case 53:
+ sigval = 8;
+ break; /* overflow */
+ case 54:
+ sigval = 8;
+ break; /* NAN */
+ default:
+ sigval = 7; /* "software generated" */
+ }
+ return (sigval);
+}
+
+/**********************************************/
+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
+/* RETURN NUMBER OF CHARS PROCESSED */
+/**********************************************/
+int
+hexToInt (char **ptr, int *intValue)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+
+ while (**ptr)
+ {
+ hexValue = hex (**ptr);
+ if (hexValue >= 0)
+ {
+ *intValue = (*intValue << 4) | hexValue;
+ numChars++;
+ }
+ else
+ break;
+
+ (*ptr)++;
+ }
+
+ return (numChars);
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb.
+ */
+void
+handle_exception (int exceptionVector)
+{
+ int sigval, stepping;
+ int addr, length;
+ char *ptr;
+ int newPC;
+ Frame *frame;
+
+ if (remote_debug)
+ printf ("vector=%d, sr=0x%x, pc=0x%x\n",
+ exceptionVector, registers[PS], registers[PC]);
+
+ /* reply to host that an exception has occurred */
+ sigval = computeSignal (exceptionVector);
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval % 16];
+ remcomOutBuffer[3] = 0;
+
+ putpacket (remcomOutBuffer);
+
+ stepping = 0;
+
+ while (1 == 1)
+ {
+ remcomOutBuffer[0] = 0;
+ ptr = getpacket ();
+ switch (*ptr++)
+ {
+ case '?':
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval % 16];
+ remcomOutBuffer[3] = 0;
+ break;
+ case 'd':
+ remote_debug = !(remote_debug); /* toggle debug flag */
+ break;
+ case 'g': /* return the value of the CPU registers */
+ mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES);
+ break;
+ case 'G': /* set the value of the CPU registers - return OK */
+ hex2mem (ptr, (char *) registers, NUMREGBYTES);
+ strcpy (remcomOutBuffer, "OK");
+ break;
+
+ /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ case 'm':
+ if (setjmp (remcomEnv) == 0)
+ {
+ exceptionHandler (2, handle_buserror);
+
+ /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
+ if (hexToInt (&ptr, &addr))
+ if (*(ptr++) == ',')
+ if (hexToInt (&ptr, &length))
+ {
+ ptr = 0;
+ mem2hex ((char *) addr, remcomOutBuffer, length);
+ }
+
+ if (ptr)
+ {
+ strcpy (remcomOutBuffer, "E01");
+ }
+ }
+ else
+ {
+ exceptionHandler (2, _catchException);
+ strcpy (remcomOutBuffer, "E03");
+ debug_error ("bus error");
+ }
+
+ /* restore handler for bus error */
+ exceptionHandler (2, _catchException);
+ break;
+
+ /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ case 'M':
+ if (setjmp (remcomEnv) == 0)
+ {
+ exceptionHandler (2, handle_buserror);
+
+ /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
+ if (hexToInt (&ptr, &addr))
+ if (*(ptr++) == ',')
+ if (hexToInt (&ptr, &length))
+ if (*(ptr++) == ':')
+ {
+ hex2mem (ptr, (char *) addr, length);
+ ptr = 0;
+ strcpy (remcomOutBuffer, "OK");
+ }
+ if (ptr)
+ {
+ strcpy (remcomOutBuffer, "E02");
+ }
+ }
+ else
+ {
+ exceptionHandler (2, _catchException);
+ strcpy (remcomOutBuffer, "E03");
+ debug_error ("bus error");
+ }
+
+ /* restore handler for bus error */
+ exceptionHandler (2, _catchException);
+ break;
+
+ /* cAA..AA Continue at address AA..AA(optional) */
+ /* sAA..AA Step one instruction from AA..AA(optional) */
+ case 's':
+ stepping = 1;
+ case 'c':
+ /* try to read optional parameter, pc unchanged if no parm */
+ if (hexToInt (&ptr, &addr))
+ registers[PC] = addr;
+
+ newPC = registers[PC];
+
+ /* clear the trace bit */
+ registers[PS] &= 0x7fff;
+
+ /* set the trace bit if we're stepping */
+ if (stepping)
+ registers[PS] |= 0x8000;
+
+ /*
+ * look for newPC in the linked list of exception frames.
+ * if it is found, use the old frame it. otherwise,
+ * fake up a dummy frame in returnFromException().
+ */
+ if (remote_debug)
+ printf ("new pc = 0x%x\n", newPC);
+ frame = lastFrame;
+ while (frame)
+ {
+ if (remote_debug)
+ printf ("frame at 0x%x has pc=0x%x, except#=%d\n",
+ frame, frame->exceptionPC, frame->exceptionVector);
+ if (frame->exceptionPC == newPC)
+ break; /* bingo! a match */
+ /*
+ * for a breakpoint instruction, the saved pc may
+ * be off by two due to re-executing the instruction
+ * replaced by the trap instruction. Check for this.
+ */
+ if ((frame->exceptionVector == 33) &&
+ (frame->exceptionPC == (newPC + 2)))
+ break;
+ if (frame == frame->previous)
+ {
+ frame = 0; /* no match found */
+ break;
+ }
+ frame = frame->previous;
+ }
+
+ /*
+ * If we found a match for the PC AND we are not returning
+ * as a result of a breakpoint (33),
+ * trace exception (9), nmi (31), jmp to
+ * the old exception handler as if this code never ran.
+ */
+ if (frame)
+ {
+ if ((frame->exceptionVector != 9) &&
+ (frame->exceptionVector != 31) &&
+ (frame->exceptionVector != 33))
+ {
+ /*
+ * invoke the previous handler.
+ */
+ if (oldExceptionHook)
+ (*oldExceptionHook) (frame->exceptionVector);
+ newPC = registers[PC]; /* pc may have changed */
+ if (newPC != frame->exceptionPC)
+ {
+ if (remote_debug)
+ printf ("frame at 0x%x has pc=0x%x, except#=%d\n",
+ frame, frame->exceptionPC,
+ frame->exceptionVector);
+ /* re-use the last frame, we're skipping it (longjump?) */
+ frame = (Frame *) 0;
+ _returnFromException (frame); /* this is a jump */
+ }
+ }
+ }
+
+ /* if we couldn't find a frame, create one */
+ if (frame == 0)
+ {
+ frame = lastFrame - 1;
+
+ /* by using a bunch of print commands with breakpoints,
+ it's possible for the frame stack to creep down. If it creeps
+ too far, give up and reset it to the top. Normal use should
+ not see this happen.
+ */
+ if ((unsigned int) (frame - 2) < (unsigned int) &gdbFrameStack)
+ {
+ initializeRemcomErrorFrame ();
+ frame = lastFrame;
+ }
+ frame->previous = lastFrame;
+ lastFrame = frame;
+ frame = 0; /* null so _return... will properly initialize it */
+ }
+
+ _returnFromException (frame); /* this is a jump */
+
+ break;
+
+ /* kill the program */
+ case 'k': /* do nothing */
+ break;
+ } /* switch */
+
+ /* reply to the request */
+ putpacket (remcomOutBuffer);
+ }
+}
+
+
+void
+initializeRemcomErrorFrame (void)
+{
+ lastFrame = ((Frame *) & gdbFrameStack[FRAMESIZE - 1]) - 1;
+ lastFrame->previous = lastFrame;
+}
+
+/* this function is used to set up exception handlers for tracing and
+ breakpoints */
+void
+set_debug_traps ()
+{
+ extern void _debug_level7 ();
+ extern void remcomHandler ();
+ int exception;
+
+ initializeRemcomErrorFrame ();
+ stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
+
+ for (exception = 2; exception <= 23; exception++)
+ exceptionHandler (exception, _catchException);
+
+ /* level 7 interrupt */
+ exceptionHandler (31, _debug_level7);
+
+ /* breakpoint exception (trap #1) */
+ exceptionHandler (33, _catchException);
+
+ /* This is a trap #8 instruction. Apparently it is someone's software
+ convention for some sort of SIGFPE condition. Whose? How many
+ people are being screwed by having this code the way it is?
+ Is there a clean solution? */
+ exceptionHandler (40, _catchException);
+
+ /* 48 to 54 are floating point coprocessor errors */
+ for (exception = 48; exception <= 54; exception++)
+ exceptionHandler (exception, _catchException);
+
+ if (oldExceptionHook != remcomHandler)
+ {
+ oldExceptionHook = exceptionHook;
+ exceptionHook = remcomHandler;
+ }
+
+ initialized = 1;
+
+}
+
+/* This function will generate a breakpoint exception. It is used at the
+ beginning of a program to sync up with a debugger and can be used
+ otherwise as a quick means to stop program execution and "break" into
+ the debugger. */
+
+void
+breakpoint ()
+{
+ if (initialized)
+ BREAKPOINT ();
+}
diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c
new file mode 100644
index 00000000000..1c4bc4d4d1f
--- /dev/null
+++ b/gdb/m68k-tdep.c
@@ -0,0 +1,685 @@
+/* Target dependent code for the Motorola 68000 series.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001
+ 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 "defs.h"
+#include "frame.h"
+#include "symtab.h"
+#include "gdbcore.h"
+#include "value.h"
+#include "gdb_string.h"
+#include "inferior.h"
+#include "regcache.h"
+
+
+#define P_LINKL_FP 0x480e
+#define P_LINKW_FP 0x4e56
+#define P_PEA_FP 0x4856
+#define P_MOVL_SP_FP 0x2c4f
+#define P_MOVL 0x207c
+#define P_JSR 0x4eb9
+#define P_BSR 0x61ff
+#define P_LEAL 0x43fb
+#define P_MOVML 0x48ef
+#define P_FMOVM 0xf237
+#define P_TRAP 0x4e40
+
+/* The only reason this is here is the tm-altos.h reference below. It
+ was moved back here from tm-m68k.h. FIXME? */
+
+extern CORE_ADDR
+altos_skip_prologue (CORE_ADDR pc)
+{
+ register int op = read_memory_integer (pc, 2);
+ if (op == P_LINKW_FP)
+ pc += 4; /* Skip link #word */
+ else if (op == P_LINKL_FP)
+ pc += 6; /* Skip link #long */
+ /* Not sure why branches are here. */
+ /* From tm-altos.h */
+ else if (op == 0060000)
+ pc += 4; /* Skip bra #word */
+ else if (op == 00600377)
+ pc += 6; /* skip bra #long */
+ else if ((op & 0177400) == 0060000)
+ pc += 2; /* skip bra #char */
+ return pc;
+}
+
+int
+delta68_in_sigtramp (CORE_ADDR pc, char *name)
+{
+ if (name != NULL)
+ return strcmp (name, "_sigcode") == 0;
+ else
+ return 0;
+}
+
+CORE_ADDR
+delta68_frame_args_address (struct frame_info *frame_info)
+{
+ /* we assume here that the only frameless functions are the system calls
+ or other functions who do not put anything on the stack. */
+ if (frame_info->signal_handler_caller)
+ return frame_info->frame + 12;
+ else if (frameless_look_for_prologue (frame_info))
+ {
+ /* Check for an interrupted system call */
+ if (frame_info->next && frame_info->next->signal_handler_caller)
+ return frame_info->next->frame + 16;
+ else
+ return frame_info->frame + 4;
+ }
+ else
+ return frame_info->frame;
+}
+
+CORE_ADDR
+delta68_frame_saved_pc (struct frame_info *frame_info)
+{
+ return read_memory_integer (delta68_frame_args_address (frame_info) + 4, 4);
+}
+
+/* Return number of args passed to a frame.
+ Can return -1, meaning no way to tell. */
+
+int
+isi_frame_num_args (struct frame_info *fi)
+{
+ int val;
+ CORE_ADDR pc = FRAME_SAVED_PC (fi);
+ int insn = 0177777 & read_memory_integer (pc, 2);
+ val = 0;
+ if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */
+ val = read_memory_integer (pc + 2, 2);
+ else if ((insn & 0170777) == 0050217 /* addql #N, sp */
+ || (insn & 0170777) == 0050117) /* addqw */
+ {
+ val = (insn >> 9) & 7;
+ if (val == 0)
+ val = 8;
+ }
+ else if (insn == 0157774) /* addal #WW, sp */
+ val = read_memory_integer (pc + 2, 4);
+ val >>= 2;
+ return val;
+}
+
+int
+delta68_frame_num_args (struct frame_info *fi)
+{
+ int val;
+ CORE_ADDR pc = FRAME_SAVED_PC (fi);
+ int insn = 0177777 & read_memory_integer (pc, 2);
+ val = 0;
+ if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */
+ val = read_memory_integer (pc + 2, 2);
+ else if ((insn & 0170777) == 0050217 /* addql #N, sp */
+ || (insn & 0170777) == 0050117) /* addqw */
+ {
+ val = (insn >> 9) & 7;
+ if (val == 0)
+ val = 8;
+ }
+ else if (insn == 0157774) /* addal #WW, sp */
+ val = read_memory_integer (pc + 2, 4);
+ val >>= 2;
+ return val;
+}
+
+int
+news_frame_num_args (struct frame_info *fi)
+{
+ int val;
+ CORE_ADDR pc = FRAME_SAVED_PC (fi);
+ int insn = 0177777 & read_memory_integer (pc, 2);
+ val = 0;
+ if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */
+ val = read_memory_integer (pc + 2, 2);
+ else if ((insn & 0170777) == 0050217 /* addql #N, sp */
+ || (insn & 0170777) == 0050117) /* addqw */
+ {
+ val = (insn >> 9) & 7;
+ if (val == 0)
+ val = 8;
+ }
+ else if (insn == 0157774) /* addal #WW, sp */
+ val = read_memory_integer (pc + 2, 4);
+ val >>= 2;
+ return val;
+}
+
+/* Push an empty stack frame, to record the current PC, etc. */
+
+void
+m68k_push_dummy_frame (void)
+{
+ register CORE_ADDR sp = read_register (SP_REGNUM);
+ register int regnum;
+ char raw_buffer[12];
+
+ sp = push_word (sp, read_register (PC_REGNUM));
+ sp = push_word (sp, read_register (FP_REGNUM));
+ write_register (FP_REGNUM, sp);
+
+ /* Always save the floating-point registers, whether they exist on
+ this target or not. */
+ for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
+ {
+ read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
+ sp = push_bytes (sp, raw_buffer, 12);
+ }
+
+ for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
+ {
+ sp = push_word (sp, read_register (regnum));
+ }
+ sp = push_word (sp, read_register (PS_REGNUM));
+ write_register (SP_REGNUM, sp);
+}
+
+/* Discard from the stack the innermost frame,
+ restoring all saved registers. */
+
+void
+m68k_pop_frame (void)
+{
+ register struct frame_info *frame = get_current_frame ();
+ register CORE_ADDR fp;
+ register int regnum;
+ struct frame_saved_regs fsr;
+ char raw_buffer[12];
+
+ fp = FRAME_FP (frame);
+ get_frame_saved_regs (frame, &fsr);
+ for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
+ {
+ if (fsr.regs[regnum])
+ {
+ read_memory (fsr.regs[regnum], raw_buffer, 12);
+ write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
+ }
+ }
+ for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
+ {
+ if (fsr.regs[regnum])
+ {
+ write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
+ }
+ }
+ if (fsr.regs[PS_REGNUM])
+ {
+ write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4));
+ }
+ write_register (FP_REGNUM, read_memory_integer (fp, 4));
+ write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
+ write_register (SP_REGNUM, fp + 8);
+ flush_cached_frames ();
+}
+
+
+/* Given an ip value corresponding to the start of a function,
+ return the ip of the first instruction after the function
+ prologue. This is the generic m68k support. Machines which
+ require something different can override the SKIP_PROLOGUE
+ macro to point elsewhere.
+
+ Some instructions which typically may appear in a function
+ prologue include:
+
+ A link instruction, word form:
+
+ link.w %a6,&0 4e56 XXXX
+
+ A link instruction, long form:
+
+ link.l %fp,&F%1 480e XXXX XXXX
+
+ A movm instruction to preserve integer regs:
+
+ movm.l &M%1,(4,%sp) 48ef XXXX XXXX
+
+ A fmovm instruction to preserve float regs:
+
+ fmovm &FPM%1,(FPO%1,%sp) f237 XXXX XXXX XXXX XXXX
+
+ Some profiling setup code (FIXME, not recognized yet):
+
+ lea.l (.L3,%pc),%a1 43fb XXXX XXXX XXXX
+ bsr _mcount 61ff XXXX XXXX
+
+ */
+
+CORE_ADDR
+m68k_skip_prologue (CORE_ADDR ip)
+{
+ register CORE_ADDR limit;
+ struct symtab_and_line sal;
+ register int op;
+
+ /* Find out if there is a known limit for the extent of the prologue.
+ If so, ensure we don't go past it. If not, assume "infinity". */
+
+ sal = find_pc_line (ip, 0);
+ limit = (sal.end) ? sal.end : (CORE_ADDR) ~ 0;
+
+ while (ip < limit)
+ {
+ op = read_memory_integer (ip, 2);
+ op &= 0xFFFF;
+
+ if (op == P_LINKW_FP)
+ ip += 4; /* Skip link.w */
+ else if (op == P_PEA_FP)
+ ip += 2; /* Skip pea %fp */
+ else if (op == P_MOVL_SP_FP)
+ ip += 2; /* Skip move.l %sp, %fp */
+ else if (op == P_LINKL_FP)
+ ip += 6; /* Skip link.l */
+ else if (op == P_MOVML)
+ ip += 6; /* Skip movm.l */
+ else if (op == P_FMOVM)
+ ip += 10; /* Skip fmovm */
+ else
+ break; /* Found unknown code, bail out. */
+ }
+ return (ip);
+}
+
+void
+m68k_find_saved_regs (struct frame_info *frame_info,
+ struct frame_saved_regs *saved_regs)
+{
+ register int regnum;
+ register int regmask;
+ register CORE_ADDR next_addr;
+ register CORE_ADDR pc;
+
+ /* First possible address for a pc in a call dummy for this frame. */
+ CORE_ADDR possible_call_dummy_start =
+ (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4 - 8 * 12;
+
+ int nextinsn;
+ memset (saved_regs, 0, sizeof (*saved_regs));
+ if ((frame_info)->pc >= possible_call_dummy_start
+ && (frame_info)->pc <= (frame_info)->frame)
+ {
+
+ /* It is a call dummy. We could just stop now, since we know
+ what the call dummy saves and where. But this code proceeds
+ to parse the "prologue" which is part of the call dummy.
+ This is needlessly complex and confusing. FIXME. */
+
+ next_addr = (frame_info)->frame;
+ pc = possible_call_dummy_start;
+ }
+ else
+ {
+ pc = get_pc_function_start ((frame_info)->pc);
+
+ nextinsn = read_memory_integer (pc, 2);
+ if (P_PEA_FP == nextinsn
+ && P_MOVL_SP_FP == read_memory_integer (pc + 2, 2))
+ {
+ /* pea %fp
+ move.l %sp, %fp */
+ next_addr = frame_info->frame;
+ pc += 4;
+ }
+ else if (P_LINKL_FP == nextinsn)
+ /* link.l %fp */
+ /* Find the address above the saved
+ regs using the amount of storage from the link instruction. */
+ {
+ next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 4);
+ pc += 6;
+ }
+ else if (P_LINKW_FP == nextinsn)
+ /* link.w %fp */
+ /* Find the address above the saved
+ regs using the amount of storage from the link instruction. */
+ {
+ next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 2);
+ pc += 4;
+ }
+ else
+ goto lose;
+
+ /* If have an addal #-n, sp next, adjust next_addr. */
+ if ((0177777 & read_memory_integer (pc, 2)) == 0157774)
+ next_addr += read_memory_integer (pc += 2, 4), pc += 4;
+ }
+
+ for ( ; ; )
+ {
+ nextinsn = 0xffff & read_memory_integer (pc, 2);
+ regmask = read_memory_integer (pc + 2, 2);
+ /* fmovemx to -(sp) */
+ if (0xf227 == nextinsn && (regmask & 0xff00) == 0xe000)
+ {
+ /* Regmask's low bit is for register fp7, the first pushed */
+ for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
+ if (regmask & 1)
+ saved_regs->regs[regnum] = (next_addr -= 12);
+ pc += 4;
+ }
+ /* fmovemx to (fp + displacement) */
+ else if (0171056 == nextinsn && (regmask & 0xff00) == 0xf000)
+ {
+ register CORE_ADDR addr;
+
+ addr = (frame_info)->frame + read_memory_integer (pc + 4, 2);
+ /* Regmask's low bit is for register fp7, the first pushed */
+ for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
+ if (regmask & 1)
+ {
+ saved_regs->regs[regnum] = addr;
+ addr += 12;
+ }
+ pc += 6;
+ }
+ /* moveml to (sp) */
+ else if (0044327 == nextinsn)
+ {
+ /* Regmask's low bit is for register 0, the first written */
+ for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
+ if (regmask & 1)
+ {
+ saved_regs->regs[regnum] = next_addr;
+ next_addr += 4;
+ }
+ pc += 4;
+ }
+ /* moveml to (fp + displacement) */
+ else if (0044356 == nextinsn)
+ {
+ register CORE_ADDR addr;
+
+ addr = (frame_info)->frame + read_memory_integer (pc + 4, 2);
+ /* Regmask's low bit is for register 0, the first written */
+ for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
+ if (regmask & 1)
+ {
+ saved_regs->regs[regnum] = addr;
+ addr += 4;
+ }
+ pc += 6;
+ }
+ /* moveml to -(sp) */
+ else if (0044347 == nextinsn)
+ {
+ /* Regmask's low bit is for register 15, the first pushed */
+ for (regnum = 16; --regnum >= 0; regmask >>= 1)
+ if (regmask & 1)
+ saved_regs->regs[regnum] = (next_addr -= 4);
+ pc += 4;
+ }
+ /* movl r,-(sp) */
+ else if (0x2f00 == (0xfff0 & nextinsn))
+ {
+ regnum = 0xf & nextinsn;
+ saved_regs->regs[regnum] = (next_addr -= 4);
+ pc += 2;
+ }
+ /* fmovemx to index of sp */
+ else if (0xf236 == nextinsn && (regmask & 0xff00) == 0xf000)
+ {
+ /* Regmask's low bit is for register fp0, the first written */
+ for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
+ if (regmask & 1)
+ {
+ saved_regs->regs[regnum] = next_addr;
+ next_addr += 12;
+ }
+ pc += 10;
+ }
+ /* clrw -(sp); movw ccr,-(sp) */
+ else if (0x4267 == nextinsn && 0x42e7 == regmask)
+ {
+ saved_regs->regs[PS_REGNUM] = (next_addr -= 4);
+ pc += 4;
+ }
+ else
+ break;
+ }
+lose:;
+ saved_regs->regs[SP_REGNUM] = (frame_info)->frame + 8;
+ saved_regs->regs[FP_REGNUM] = (frame_info)->frame;
+ saved_regs->regs[PC_REGNUM] = (frame_info)->frame + 4;
+#ifdef SIG_SP_FP_OFFSET
+ /* Adjust saved SP_REGNUM for fake _sigtramp frames. */
+ if (frame_info->signal_handler_caller && frame_info->next)
+ saved_regs->regs[SP_REGNUM] = frame_info->next->frame + SIG_SP_FP_OFFSET;
+#endif
+}
+
+
+#ifdef USE_PROC_FS /* Target dependent support for /proc */
+
+#include <sys/procfs.h>
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* The /proc interface divides the target machine's register set up into
+ two different sets, the general register set (gregset) and the floating
+ point register set (fpregset). For each set, there is an ioctl to get
+ the current register set and another ioctl to set the current values.
+
+ The actual structure passed through the ioctl interface is, of course,
+ naturally machine dependent, and is different for each set of registers.
+ For the m68k for example, the general register set is typically defined
+ by:
+
+ typedef int gregset_t[18];
+
+ #define R_D0 0
+ ...
+ #define R_PS 17
+
+ and the floating point set by:
+
+ typedef struct fpregset {
+ int f_pcr;
+ int f_psr;
+ int f_fpiaddr;
+ int f_fpregs[8][3]; (8 regs, 96 bits each)
+ } fpregset_t;
+
+ These routines provide the packing and unpacking of gregset_t and
+ fpregset_t formatted data.
+
+ */
+
+/* Atari SVR4 has R_SR but not R_PS */
+
+#if !defined (R_PS) && defined (R_SR)
+#define R_PS R_SR
+#endif
+
+/* Given a pointer to a general register set in /proc format (gregset_t *),
+ unpack the register contents and supply them as gdb's idea of the current
+ register values. */
+
+void
+supply_gregset (gregset_t *gregsetp)
+{
+ register int regi;
+ register greg_t *regp = (greg_t *) gregsetp;
+
+ for (regi = 0; regi < R_PC; regi++)
+ {
+ supply_register (regi, (char *) (regp + regi));
+ }
+ supply_register (PS_REGNUM, (char *) (regp + R_PS));
+ supply_register (PC_REGNUM, (char *) (regp + R_PC));
+}
+
+void
+fill_gregset (gregset_t *gregsetp, int regno)
+{
+ register int regi;
+ register greg_t *regp = (greg_t *) gregsetp;
+
+ for (regi = 0; regi < R_PC; regi++)
+ {
+ if ((regno == -1) || (regno == regi))
+ {
+ *(regp + regi) = *(int *) &registers[REGISTER_BYTE (regi)];
+ }
+ }
+ if ((regno == -1) || (regno == PS_REGNUM))
+ {
+ *(regp + R_PS) = *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
+ }
+ if ((regno == -1) || (regno == PC_REGNUM))
+ {
+ *(regp + R_PC) = *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
+ }
+}
+
+#if defined (FP0_REGNUM)
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), unpack the register contents and supply them as gdb's
+ idea of the current floating point register values. */
+
+void
+supply_fpregset (fpregset_t *fpregsetp)
+{
+ register int regi;
+ char *from;
+
+ for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
+ {
+ from = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
+ supply_register (regi, from);
+ }
+ supply_register (FPC_REGNUM, (char *) &(fpregsetp->f_pcr));
+ supply_register (FPS_REGNUM, (char *) &(fpregsetp->f_psr));
+ supply_register (FPI_REGNUM, (char *) &(fpregsetp->f_fpiaddr));
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), update the register specified by REGNO from gdb's idea
+ of the current floating point register set. If REGNO is -1, update
+ them all. */
+
+void
+fill_fpregset (fpregset_t *fpregsetp, int regno)
+{
+ int regi;
+ char *to;
+ char *from;
+
+ for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
+ {
+ if ((regno == -1) || (regno == regi))
+ {
+ from = (char *) &registers[REGISTER_BYTE (regi)];
+ to = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
+ memcpy (to, from, REGISTER_RAW_SIZE (regi));
+ }
+ }
+ if ((regno == -1) || (regno == FPC_REGNUM))
+ {
+ fpregsetp->f_pcr = *(int *) &registers[REGISTER_BYTE (FPC_REGNUM)];
+ }
+ if ((regno == -1) || (regno == FPS_REGNUM))
+ {
+ fpregsetp->f_psr = *(int *) &registers[REGISTER_BYTE (FPS_REGNUM)];
+ }
+ if ((regno == -1) || (regno == FPI_REGNUM))
+ {
+ fpregsetp->f_fpiaddr = *(int *) &registers[REGISTER_BYTE (FPI_REGNUM)];
+ }
+}
+
+#endif /* defined (FP0_REGNUM) */
+
+#endif /* USE_PROC_FS */
+
+/* Figure out where the longjmp will land. Slurp the args out of the stack.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
+ This routine returns true on success. */
+
+/* NOTE: cagney/2000-11-08: For this function to be fully multi-arched
+ the macro's JB_PC and JB_ELEMENT_SIZE would need to be moved into
+ the ``struct gdbarch_tdep'' object and then set on a target ISA/ABI
+ dependant basis. */
+
+int
+m68k_get_longjmp_target (CORE_ADDR *pc)
+{
+#if defined (JB_PC) && defined (JB_ELEMENT_SIZE)
+ char *buf;
+ CORE_ADDR sp, jb_addr;
+
+ buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ sp = read_register (SP_REGNUM);
+
+ if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */
+ buf,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ return 1;
+#else
+ internal_error (__FILE__, __LINE__,
+ "m68k_get_longjmp_target: not implemented");
+ return 0;
+#endif
+}
+
+/* Immediately after a function call, return the saved pc before the frame
+ is setup. For sun3's, we check for the common case of being inside of a
+ system call, and if so, we know that Sun pushes the call # on the stack
+ prior to doing the trap. */
+
+CORE_ADDR
+m68k_saved_pc_after_call (struct frame_info *frame)
+{
+#ifdef SYSCALL_TRAP
+ int op;
+
+ op = read_memory_integer (frame->pc - SYSCALL_TRAP_OFFSET, 2);
+
+ if (op == SYSCALL_TRAP)
+ return read_memory_integer (read_register (SP_REGNUM) + 4, 4);
+ else
+#endif /* SYSCALL_TRAP */
+ return read_memory_integer (read_register (SP_REGNUM), 4);
+}
+
+
+void
+_initialize_m68k_tdep (void)
+{
+ tm_print_insn = print_insn_m68k;
+}
diff --git a/gdb/m68klinux-nat.c b/gdb/m68klinux-nat.c
new file mode 100644
index 00000000000..82a6124a7aa
--- /dev/null
+++ b/gdb/m68klinux-nat.c
@@ -0,0 +1,710 @@
+/* Motorola m68k native support for GNU/Linux.
+
+ Copyright 1996, 1998, 2000, 2001, 2002 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "language.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/ptrace.h>
+#include <sys/user.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <sys/procfs.h>
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+#include <sys/file.h>
+#include "gdb_stat.h"
+
+#include "floatformat.h"
+
+#include "target.h"
+
+
+/* This table must line up with REGISTER_NAMES in tm-m68k.h */
+static const int regmap[] =
+{
+ PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
+ PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
+ PT_SR, PT_PC,
+ /* PT_FP0, ..., PT_FP7 */
+ 21, 24, 27, 30, 33, 36, 39, 42,
+ /* PT_FPCR, PT_FPSR, PT_FPIAR */
+ 45, 46, 47
+};
+
+/* Which ptrace request retrieves which registers?
+ These apply to the corresponding SET requests as well. */
+#define NUM_GREGS (18)
+#define MAX_NUM_REGS (NUM_GREGS + 11)
+
+int
+getregs_supplies (int regno)
+{
+ return 0 <= regno && regno < NUM_GREGS;
+}
+
+int
+getfpregs_supplies (int regno)
+{
+ return FP0_REGNUM <= regno && regno <= FPI_REGNUM;
+}
+
+/* Does the current host support the GETREGS request? */
+int have_ptrace_getregs =
+#ifdef HAVE_PTRACE_GETREGS
+ 1
+#else
+ 0
+#endif
+;
+
+
+
+/* BLOCKEND is the value of u.u_ar0, and points to the place where GS
+ is stored. */
+
+int
+m68k_linux_register_u_addr (int blockend, int regnum)
+{
+ return (blockend + 4 * regmap[regnum]);
+}
+
+
+/* Fetching registers directly from the U area, one at a time. */
+
+/* FIXME: This duplicates code from `inptrace.c'. The problem is that we
+ define FETCH_INFERIOR_REGISTERS since we want to use our own versions
+ of {fetch,store}_inferior_registers that use the GETREGS request. This
+ means that the code in `infptrace.c' is #ifdef'd out. But we need to
+ fall back on that code when GDB is running on top of a kernel that
+ doesn't support the GETREGS request. */
+
+#ifndef PT_READ_U
+#define PT_READ_U PTRACE_PEEKUSR
+#endif
+#ifndef PT_WRITE_U
+#define PT_WRITE_U PTRACE_POKEUSR
+#endif
+
+/* Default the type of the ptrace transfer to int. */
+#ifndef PTRACE_XFER_TYPE
+#define PTRACE_XFER_TYPE int
+#endif
+
+/* Fetch one register. */
+
+static void
+fetch_register (int regno)
+{
+ /* This isn't really an address. But ptrace thinks of it as one. */
+ CORE_ADDR regaddr;
+ char mess[128]; /* For messages */
+ register int i;
+ unsigned int offset; /* Offset of registers within the u area. */
+ char buf[MAX_REGISTER_RAW_SIZE];
+ int tid;
+
+ if (CANNOT_FETCH_REGISTER (regno))
+ {
+ memset (buf, '\0', REGISTER_RAW_SIZE (regno)); /* Supply zeroes */
+ supply_register (regno, buf);
+ return;
+ }
+
+ /* Overload thread id onto process id */
+ if ((tid = TIDGET (inferior_ptid)) == 0)
+ tid = PIDGET (inferior_ptid); /* no thread id, just use process id */
+
+ offset = U_REGS_OFFSET;
+
+ regaddr = register_addr (regno, offset);
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ *(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid,
+ (PTRACE_ARG3_TYPE) regaddr, 0);
+ regaddr += sizeof (PTRACE_XFER_TYPE);
+ if (errno != 0)
+ {
+ sprintf (mess, "reading register %s (#%d)",
+ REGISTER_NAME (regno), regno);
+ perror_with_name (mess);
+ }
+ }
+ supply_register (regno, buf);
+}
+
+/* Fetch register values from the inferior.
+ If REGNO is negative, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+old_fetch_inferior_registers (int regno)
+{
+ if (regno >= 0)
+ {
+ fetch_register (regno);
+ }
+ else
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ {
+ fetch_register (regno);
+ }
+ }
+}
+
+/* Store one register. */
+
+static void
+store_register (int regno)
+{
+ /* This isn't really an address. But ptrace thinks of it as one. */
+ CORE_ADDR regaddr;
+ char mess[128]; /* For messages */
+ register int i;
+ unsigned int offset; /* Offset of registers within the u area. */
+ int tid;
+ char *buf = alloca (MAX_REGISTER_RAW_SIZE);
+
+ if (CANNOT_STORE_REGISTER (regno))
+ {
+ return;
+ }
+
+ /* Overload thread id onto process id */
+ if ((tid = TIDGET (inferior_ptid)) == 0)
+ tid = PIDGET (inferior_ptid); /* no thread id, just use process id */
+
+ offset = U_REGS_OFFSET;
+
+ regaddr = register_addr (regno, offset);
+
+ /* Put the contents of regno into a local buffer */
+ regcache_collect (regno, buf);
+
+ /* Store the local buffer into the inferior a chunk at the time. */
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,
+ *(PTRACE_XFER_TYPE *) (buf + i));
+ regaddr += sizeof (PTRACE_XFER_TYPE);
+ if (errno != 0)
+ {
+ sprintf (mess, "writing register %s (#%d)",
+ REGISTER_NAME (regno), regno);
+ perror_with_name (mess);
+ }
+ }
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is negative, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+old_store_inferior_registers (int regno)
+{
+ if (regno >= 0)
+ {
+ store_register (regno);
+ }
+ else
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ {
+ store_register (regno);
+ }
+ }
+}
+
+/* Given a pointer to a general register set in /proc format
+ (elf_gregset_t *), unpack the register contents and supply
+ them as gdb's idea of the current register values. */
+
+
+/* Note both m68k-tdep.c and m68klinux-nat.c contain definitions
+ for supply_gregset and supply_fpregset. The definitions
+ in m68k-tdep.c are valid if USE_PROC_FS is defined. Otherwise,
+ the definitions in m68klinux-nat.c will be used. This is a
+ bit of a hack. The supply_* routines do not belong in
+ *_tdep.c files. But, there are several lynx ports that currently
+ depend on these definitions. */
+
+#ifndef USE_PROC_FS
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+void
+supply_gregset (elf_gregset_t *gregsetp)
+{
+ elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ int regi;
+
+ for (regi = D0_REGNUM; regi <= SP_REGNUM; regi++)
+ supply_register (regi, (char *) &regp[regmap[regi]]);
+ supply_register (PS_REGNUM, (char *) &regp[PT_SR]);
+ supply_register (PC_REGNUM, (char *) &regp[PT_PC]);
+}
+
+/* Fill register REGNO (if it is a general-purpose register) in
+ *GREGSETPS with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+void
+fill_gregset (elf_gregset_t *gregsetp, int regno)
+{
+ elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ int i;
+
+ for (i = 0; i < NUM_GREGS; i++)
+ if ((regno == -1 || regno == i))
+ regcache_collect (i, regp + regmap[i]);
+}
+
+#ifdef HAVE_PTRACE_GETREGS
+
+/* Fetch all general-purpose registers from process/thread TID and
+ store their values in GDB's register array. */
+
+static void
+fetch_regs (int tid)
+{
+ elf_gregset_t regs;
+
+ if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
+ {
+ if (errno == EIO)
+ {
+ /* The kernel we're running on doesn't support the GETREGS
+ request. Reset `have_ptrace_getregs'. */
+ have_ptrace_getregs = 0;
+ return;
+ }
+
+ perror_with_name ("Couldn't get registers");
+ }
+
+ supply_gregset (&regs);
+}
+
+/* Store all valid general-purpose registers in GDB's register array
+ into the process/thread specified by TID. */
+
+static void
+store_regs (int tid, int regno)
+{
+ elf_gregset_t regs;
+
+ if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
+ perror_with_name ("Couldn't get registers");
+
+ fill_gregset (&regs, regno);
+
+ if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
+ perror_with_name ("Couldn't write registers");
+}
+
+#else
+
+static void fetch_regs (int tid) {}
+static void store_regs (int tid, int regno) {}
+
+#endif
+
+
+/* Transfering floating-point registers between GDB, inferiors and cores. */
+
+/* What is the address of fpN within the floating-point register set F? */
+#define FPREG_ADDR(f, n) ((char *) &(f)->fpregs[(n) * 3])
+
+/* Fill GDB's register array with the floating-point register values in
+ *FPREGSETP. */
+
+void
+supply_fpregset (elf_fpregset_t *fpregsetp)
+{
+ int regi;
+
+ for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
+ supply_register (regi, FPREG_ADDR (fpregsetp, regi - FP0_REGNUM));
+ supply_register (FPC_REGNUM, (char *) &fpregsetp->fpcntl[0]);
+ supply_register (FPS_REGNUM, (char *) &fpregsetp->fpcntl[1]);
+ supply_register (FPI_REGNUM, (char *) &fpregsetp->fpcntl[2]);
+}
+
+/* Fill register REGNO (if it is a floating-point register) in
+ *FPREGSETP with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+
+void
+fill_fpregset (elf_fpregset_t *fpregsetp, int regno)
+{
+ int i;
+
+ /* Fill in the floating-point registers. */
+ for (i = FP0_REGNUM; i < FP0_REGNUM + 8; i++)
+ if (regno == -1 || regno == i)
+ regcache_collect (regno, FPREG_ADDR (fpregsetp, regno - FP0_REGNUM));
+
+ /* Fill in the floating-point control registers. */
+ for (i = FPC_REGNUM; i <= FPI_REGNUM; i++)
+ if (regno == -1 || regno == i)
+ regcache_collect (regno, (char *) &fpregsetp->fpcntl[regno - FPC_REGNUM]);
+}
+
+#ifdef HAVE_PTRACE_GETREGS
+
+/* Fetch all floating-point registers from process/thread TID and store
+ thier values in GDB's register array. */
+
+static void
+fetch_fpregs (int tid)
+{
+ elf_fpregset_t fpregs;
+
+ if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
+ perror_with_name ("Couldn't get floating point status");
+
+ supply_fpregset (&fpregs);
+}
+
+/* Store all valid floating-point registers in GDB's register array
+ into the process/thread specified by TID. */
+
+static void
+store_fpregs (int tid, int regno)
+{
+ elf_fpregset_t fpregs;
+
+ if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
+ perror_with_name ("Couldn't get floating point status");
+
+ fill_fpregset (&fpregs, regno);
+
+ if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
+ perror_with_name ("Couldn't write floating point status");
+}
+
+#else
+
+static void fetch_fpregs (int tid) {}
+static void store_fpregs (int tid, int regno) {}
+
+#endif
+
+#endif
+
+/* Transferring arbitrary registers between GDB and inferior. */
+
+/* Fetch register REGNO from the child process. If REGNO is -1, do
+ this for all registers (including the floating point and SSE
+ registers). */
+
+void
+fetch_inferior_registers (int regno)
+{
+ int tid;
+
+ /* Use the old method of peeking around in `struct user' if the
+ GETREGS request isn't available. */
+ if (! have_ptrace_getregs)
+ {
+ old_fetch_inferior_registers (regno);
+ return;
+ }
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ if ((tid = TIDGET (inferior_ptid)) == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ /* Use the PTRACE_GETFPXREGS request whenever possible, since it
+ transfers more registers in one system call, and we'll cache the
+ results. But remember that fetch_fpxregs can fail, and return
+ zero. */
+ if (regno == -1)
+ {
+ fetch_regs (tid);
+
+ /* The call above might reset `have_ptrace_getregs'. */
+ if (! have_ptrace_getregs)
+ {
+ old_fetch_inferior_registers (-1);
+ return;
+ }
+
+ fetch_fpregs (tid);
+ return;
+ }
+
+ if (getregs_supplies (regno))
+ {
+ fetch_regs (tid);
+ return;
+ }
+
+ if (getfpregs_supplies (regno))
+ {
+ fetch_fpregs (tid);
+ return;
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "Got request for bad register number %d.", regno);
+}
+
+/* Store register REGNO back into the child process. If REGNO is -1,
+ do this for all registers (including the floating point and SSE
+ registers). */
+void
+store_inferior_registers (int regno)
+{
+ int tid;
+
+ /* Use the old method of poking around in `struct user' if the
+ SETREGS request isn't available. */
+ if (! have_ptrace_getregs)
+ {
+ old_store_inferior_registers (regno);
+ return;
+ }
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ if ((tid = TIDGET (inferior_ptid)) == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ /* Use the PTRACE_SETFPREGS requests whenever possible, since it
+ transfers more registers in one system call. But remember that
+ store_fpregs can fail, and return zero. */
+ if (regno == -1)
+ {
+ store_regs (tid, regno);
+ store_fpregs (tid, regno);
+ return;
+ }
+
+ if (getregs_supplies (regno))
+ {
+ store_regs (tid, regno);
+ return;
+ }
+
+ if (getfpregs_supplies (regno))
+ {
+ store_fpregs (tid, regno);
+ return;
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "Got request to store bad register number %d.", regno);
+}
+
+/* Interpreting register set info found in core files. */
+
+/* Provide registers to GDB from a core file.
+
+ (We can't use the generic version of this function in
+ core-regset.c, because we need to use elf_gregset_t instead of
+ gregset_t.)
+
+ CORE_REG_SECT points to an array of bytes, which are the contents
+ of a `note' from a core file which BFD thinks might contain
+ register contents. CORE_REG_SIZE is its size.
+
+ WHICH says which register set corelow suspects this is:
+ 0 --- the general-purpose register set, in elf_gregset_t format
+ 2 --- the floating-point register set, in elf_fpregset_t format
+
+ REG_ADDR isn't used on GNU/Linux. */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+ elf_gregset_t gregset;
+ elf_fpregset_t fpregset;
+
+ switch (which)
+ {
+ case 0:
+ if (core_reg_size != sizeof (gregset))
+ warning ("Wrong size gregset in core file.");
+ else
+ {
+ memcpy (&gregset, core_reg_sect, sizeof (gregset));
+ supply_gregset (&gregset);
+ }
+ break;
+
+ case 2:
+ if (core_reg_size != sizeof (fpregset))
+ warning ("Wrong size fpregset in core file.");
+ else
+ {
+ memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
+ supply_fpregset (&fpregset);
+ }
+ break;
+
+ default:
+ /* We've covered all the kinds of registers we know about here,
+ so this must be something we wouldn't know what to do with
+ anyway. Just ignore it. */
+ break;
+ }
+}
+
+
+int
+kernel_u_size (void)
+{
+ return (sizeof (struct user));
+}
+
+/* Check whether insn1 and insn2 are parts of a signal trampoline. */
+
+#define IS_SIGTRAMP(insn1, insn2) \
+ (/* addaw #20,sp; moveq #119,d0; trap #0 */ \
+ (insn1 == 0xdefc0014 && insn2 == 0x70774e40) \
+ /* moveq #119,d0; trap #0 */ \
+ || insn1 == 0x70774e40)
+
+#define IS_RT_SIGTRAMP(insn1, insn2) \
+ (/* movel #173,d0; trap #0 */ \
+ (insn1 == 0x203c0000 && insn2 == 0x00ad4e40) \
+ /* moveq #82,d0; notb d0; trap #0 */ \
+ || (insn1 == 0x70524600 && (insn2 >> 16) == 0x4e40))
+
+/* Return non-zero if PC points into the signal trampoline. For the sake
+ of m68k_linux_frame_saved_pc we also distinguish between non-RT and RT
+ signal trampolines. */
+
+int
+m68k_linux_in_sigtramp (CORE_ADDR pc)
+{
+ CORE_ADDR sp;
+ char buf[12];
+ unsigned long insn0, insn1, insn2;
+
+ if (read_memory_nobpt (pc - 4, buf, sizeof (buf)))
+ return 0;
+ insn1 = extract_unsigned_integer (buf + 4, 4);
+ insn2 = extract_unsigned_integer (buf + 8, 4);
+ if (IS_SIGTRAMP (insn1, insn2))
+ return 1;
+ if (IS_RT_SIGTRAMP (insn1, insn2))
+ return 2;
+
+ insn0 = extract_unsigned_integer (buf, 4);
+ if (IS_SIGTRAMP (insn0, insn1))
+ return 1;
+ if (IS_RT_SIGTRAMP (insn0, insn1))
+ return 2;
+
+ insn0 = (insn0 << 16) | (insn1 >> 16);
+ insn1 = (insn1 << 16) | (insn2 >> 16);
+ if (IS_SIGTRAMP (insn0, insn1))
+ return 1;
+ if (IS_RT_SIGTRAMP (insn0, insn1))
+ return 2;
+
+ return 0;
+}
+
+/* Offset to saved PC in sigcontext, from <asm/sigcontext.h>. */
+#define SIGCONTEXT_PC_OFFSET 26
+
+/* Offset to saved PC in ucontext, from <asm/ucontext.h>. */
+#define UCONTEXT_PC_OFFSET 88
+
+/* Get saved user PC for sigtramp from sigcontext or ucontext. */
+
+static CORE_ADDR
+m68k_linux_sigtramp_saved_pc (struct frame_info *frame)
+{
+ CORE_ADDR sigcontext_addr;
+ char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
+ int ptrbytes = TARGET_PTR_BIT / TARGET_CHAR_BIT;
+ int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT;
+
+ /* Get sigcontext address, it is the third parameter on the stack. */
+ if (frame->next)
+ sigcontext_addr = read_memory_integer (FRAME_ARGS_ADDRESS (frame->next)
+ + FRAME_ARGS_SKIP
+ + sigcontext_offs,
+ ptrbytes);
+ else
+ sigcontext_addr = read_memory_integer (read_register (SP_REGNUM)
+ + sigcontext_offs,
+ ptrbytes);
+
+ /* Don't cause a memory_error when accessing sigcontext in case the
+ stack layout has changed or the stack is corrupt. */
+ if (m68k_linux_in_sigtramp (frame->pc) == 2)
+ target_read_memory (sigcontext_addr + UCONTEXT_PC_OFFSET, buf, ptrbytes);
+ else
+ target_read_memory (sigcontext_addr + SIGCONTEXT_PC_OFFSET, buf, ptrbytes);
+ return extract_unsigned_integer (buf, ptrbytes);
+}
+
+/* Return the saved program counter for FRAME. */
+
+CORE_ADDR
+m68k_linux_frame_saved_pc (struct frame_info *frame)
+{
+ if (frame->signal_handler_caller)
+ return m68k_linux_sigtramp_saved_pc (frame);
+
+ return read_memory_integer (frame->frame + 4, 4);
+}
+
+/* Register that we are able to handle GNU/Linux ELF core file
+ formats. */
+
+static struct core_fns linux_elf_core_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_m68k_linux_nat ()
+{
+ add_core_fns (&linux_elf_core_fns);
+}
diff --git a/gdb/m68knbsd-nat.c b/gdb/m68knbsd-nat.c
new file mode 100644
index 00000000000..ec986eeb364
--- /dev/null
+++ b/gdb/m68knbsd-nat.c
@@ -0,0 +1,103 @@
+/* Native-dependent code for Motorola m68k's running NetBSD, for GDB.
+ Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001
+ 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 "defs.h"
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+#include "inferior.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+void
+fetch_inferior_registers (int regno)
+{
+ struct reg inferior_registers;
+ struct fpreg inferior_fp_registers;
+
+ ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0);
+ memcpy (&registers[REGISTER_BYTE (0)], &inferior_registers,
+ sizeof (inferior_registers));
+
+ ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0);
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
+ sizeof (inferior_fp_registers));
+
+ registers_fetched ();
+}
+
+void
+store_inferior_registers (int regno)
+{
+ struct reg inferior_registers;
+ struct fpreg inferior_fp_registers;
+
+ memcpy (&inferior_registers, &registers[REGISTER_BYTE (0)],
+ sizeof (inferior_registers));
+ ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0);
+
+ memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
+ sizeof (inferior_fp_registers));
+ ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0);
+}
+
+struct md_core
+{
+ struct reg intreg;
+ struct fpreg freg;
+};
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR ignore)
+{
+ struct md_core *core_reg = (struct md_core *) core_reg_sect;
+
+ /* Integer registers */
+ memcpy (&registers[REGISTER_BYTE (0)],
+ &core_reg->intreg, sizeof (struct reg));
+ /* Floating point registers */
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)],
+ &core_reg->freg, sizeof (struct fpreg));
+}
+
+/* Register that we are able to handle m68knbsd core file formats.
+ FIXME: is this really bfd_target_unknown_flavour? */
+
+static struct core_fns m68knbsd_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_m68knbsd_nat (void)
+{
+ add_core_fns (&m68knbsd_core_fns);
+}
diff --git a/gdb/m68knbsd-tdep.c b/gdb/m68knbsd-tdep.c
new file mode 100644
index 00000000000..520d14fa47f
--- /dev/null
+++ b/gdb/m68knbsd-tdep.c
@@ -0,0 +1,33 @@
+/* Target-dependent code for NetBSD/i386, for GDB.
+ Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001
+ 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 "defs.h"
+#include "gdbtypes.h"
+#include "regcache.h"
+
+int
+m68knbsd_use_struct_convention (int gcc_p, struct type *type)
+{
+ return !(TYPE_LENGTH (type) == 1
+ || TYPE_LENGTH (type) == 2
+ || TYPE_LENGTH (type) == 4
+ || TYPE_LENGTH (type) == 8);
+}
diff --git a/gdb/m88k-nat.c b/gdb/m88k-nat.c
new file mode 100644
index 00000000000..b631cda2735
--- /dev/null
+++ b/gdb/m88k-nat.c
@@ -0,0 +1,290 @@
+/* Native-dependent Motorola 88xxx support for GDB, the GNU Debugger.
+ Copyright 1988, 1990, 1991, 1992, 1993, 1995, 1999, 2000, 2001
+ 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include "gdbcore.h"
+#include <sys/user.h>
+
+#ifndef USER /* added to support BCS ptrace_user */
+#define USER ptrace_user
+#endif
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <sys/file.h>
+#include "gdb_stat.h"
+
+#include "symtab.h"
+#include "setjmp.h"
+#include "value.h"
+
+#ifdef DELTA88
+#include <sys/ptrace.h>
+
+/* define offsets to the pc instruction offsets in ptrace_user struct */
+#define SXIP_OFFSET ((char *)&u.pt_sigframe.sig_sxip - (char *)&u)
+#define SNIP_OFFSET ((char *)&u.pt_sigframe.sig_snip - (char *)&u)
+#define SFIP_OFFSET ((char *)&u.pt_sigframe.sig_sfip - (char *)&u)
+#else
+/* define offsets to the pc instruction offsets in ptrace_user struct */
+#define SXIP_OFFSET ((char *)&u.pt_sigframe.dg_sigframe.sc_sxip - (char *)&u)
+#define SNIP_OFFSET ((char *)&u.pt_sigframe.dg_sigframe.sc_snip - (char *)&u)
+#define SFIP_OFFSET ((char *)&u.pt_sigframe.dg_sigframe.sc_sfip - (char *)&u)
+#endif
+
+extern int have_symbol_file_p ();
+
+extern jmp_buf stack_jmp;
+
+extern int errno;
+
+void
+fetch_inferior_registers (int regno)
+{
+ register unsigned int regaddr;
+ char buf[MAX_REGISTER_RAW_SIZE];
+ register int i;
+
+ struct USER u;
+ unsigned int offset;
+
+ offset = (char *) &u.pt_r0 - (char *) &u;
+ regaddr = offset; /* byte offset to r0; */
+
+/* offset = ptrace (3, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) offset, 0) - KERNEL_U_ADDR; */
+ for (regno = 0; regno < NUM_REGS; regno++)
+ {
+ /*regaddr = register_addr (regno, offset); */
+ /* 88k enhancement */
+
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+ {
+ *(int *) &buf[i] = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) regaddr, 0);
+ regaddr += sizeof (int);
+ }
+ supply_register (regno, buf);
+ }
+ /* now load up registers 36 - 38; special pc registers */
+ *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SXIP_OFFSET, 0);
+ supply_register (SXIP_REGNUM, buf);
+ *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SNIP_OFFSET, 0);
+ supply_register (SNIP_REGNUM, buf);
+ *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SFIP_OFFSET, 0);
+ supply_register (SFIP_REGNUM, buf);
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ register unsigned int regaddr;
+ char buf[80];
+
+ struct USER u;
+
+ unsigned int offset = (char *) &u.pt_r0 - (char *) &u;
+
+ regaddr = offset;
+
+ /* Don't try to deal with EXIP_REGNUM or ENIP_REGNUM, because I think either
+ svr3 doesn't run on an 88110, or the kernel isolates the different (not
+ completely sure this is true, but seems to be. */
+ if (regno >= 0)
+ {
+ /* regaddr = register_addr (regno, offset); */
+ if (regno < PC_REGNUM)
+ {
+ regaddr = offset + regno * sizeof (int);
+ errno = 0;
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) regaddr, read_register (regno));
+ if (errno != 0)
+ {
+ sprintf (buf, "writing register number %d", regno);
+ perror_with_name (buf);
+ }
+ }
+ else if (regno == SXIP_REGNUM)
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register (regno));
+ else if (regno == SNIP_REGNUM)
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register (regno));
+ else if (regno == SFIP_REGNUM)
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register (regno));
+ else
+ printf_unfiltered ("Bad register number for store_inferior routine\n");
+ }
+ else
+ {
+ for (regno = 0; regno < PC_REGNUM; regno++)
+ {
+ /* regaddr = register_addr (regno, offset); */
+ errno = 0;
+ regaddr = offset + regno * sizeof (int);
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) regaddr, read_register (regno));
+ if (errno != 0)
+ {
+ sprintf (buf, "writing register number %d", regno);
+ perror_with_name (buf);
+ }
+ }
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register (SXIP_REGNUM));
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register (SNIP_REGNUM));
+ ptrace (6, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register (SFIP_REGNUM));
+ }
+}
+
+
+/* blockend is the address of the end of the user structure */
+m88k_register_u_addr (int blockend, int regnum)
+{
+ struct USER u;
+ int ustart = blockend - sizeof (struct USER);
+ switch (regnum)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ case 22:
+ case 23:
+ case 24:
+ case 25:
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ case 30:
+ case 31:
+ return (ustart + ((int) &u.pt_r0 - (int) &u) + REGISTER_SIZE * regnum);
+ case PSR_REGNUM:
+ return (ustart + ((int) &u.pt_psr - (int) &u));
+ case FPSR_REGNUM:
+ return (ustart + ((int) &u.pt_fpsr - (int) &u));
+ case FPCR_REGNUM:
+ return (ustart + ((int) &u.pt_fpcr - (int) &u));
+ case SXIP_REGNUM:
+ return (ustart + SXIP_OFFSET);
+ case SNIP_REGNUM:
+ return (ustart + SNIP_OFFSET);
+ case SFIP_REGNUM:
+ return (ustart + SFIP_OFFSET);
+ default:
+ if (regnum < NUM_REGS)
+ /* The register is one of those which is not defined...
+ give it zero */
+ return (ustart + ((int) &u.pt_r0 - (int) &u));
+ else
+ return (blockend + REGISTER_SIZE * regnum);
+ }
+}
+
+#ifdef USE_PROC_FS
+
+#include <sys/procfs.h>
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* Given a pointer to a general register set in /proc format (gregset_t *),
+ unpack the register contents and supply them as gdb's idea of the current
+ register values. */
+
+void
+supply_gregset (gregset_t *gregsetp)
+{
+ register int regi;
+ register greg_t *regp = (greg_t *) gregsetp;
+
+ for (regi = 0; regi <= SP_REGNUM; regi++)
+ supply_register (regi, (char *) (regp + regi));
+
+ supply_register (SXIP_REGNUM, (char *) (regp + R_XIP));
+ supply_register (SNIP_REGNUM, (char *) (regp + R_NIP));
+ supply_register (SFIP_REGNUM, (char *) (regp + R_FIP));
+ supply_register (PSR_REGNUM, (char *) (regp + R_PSR));
+ supply_register (FPSR_REGNUM, (char *) (regp + R_FPSR));
+ supply_register (FPCR_REGNUM, (char *) (regp + R_FPCR));
+}
+
+void
+fill_gregset (gregset_t *gregsetp, int regno)
+{
+ int regi;
+ register greg_t *regp = (greg_t *) gregsetp;
+
+ for (regi = 0; regi <= R_R31; regi++)
+ if ((regno == -1) || (regno == regi))
+ *(regp + regi) = *(int *) &registers[REGISTER_BYTE (regi)];
+
+ if ((regno == -1) || (regno == SXIP_REGNUM))
+ *(regp + R_XIP) = *(int *) &registers[REGISTER_BYTE (SXIP_REGNUM)];
+ if ((regno == -1) || (regno == SNIP_REGNUM))
+ *(regp + R_NIP) = *(int *) &registers[REGISTER_BYTE (SNIP_REGNUM)];
+ if ((regno == -1) || (regno == SFIP_REGNUM))
+ *(regp + R_FIP) = *(int *) &registers[REGISTER_BYTE (SFIP_REGNUM)];
+ if ((regno == -1) || (regno == PSR_REGNUM))
+ *(regp + R_PSR) = *(int *) &registers[REGISTER_BYTE (PSR_REGNUM)];
+ if ((regno == -1) || (regno == FPSR_REGNUM))
+ *(regp + R_FPSR) = *(int *) &registers[REGISTER_BYTE (FPSR_REGNUM)];
+ if ((regno == -1) || (regno == FPCR_REGNUM))
+ *(regp + R_FPCR) = *(int *) &registers[REGISTER_BYTE (FPCR_REGNUM)];
+}
+
+#endif /* USE_PROC_FS */
diff --git a/gdb/m88k-tdep.c b/gdb/m88k-tdep.c
new file mode 100644
index 00000000000..3c96d37a8de
--- /dev/null
+++ b/gdb/m88k-tdep.c
@@ -0,0 +1,661 @@
+/* Target-machine dependent code for Motorola 88000 series, for GDB.
+
+ Copyright 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
+ 2000, 2001, 2002 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "symtab.h"
+#include "setjmp.h"
+#include "value.h"
+#include "regcache.h"
+
+/* Size of an instruction */
+#define BYTES_PER_88K_INSN 4
+
+void frame_find_saved_regs ();
+
+/* Is this target an m88110? Otherwise assume m88100. This has
+ relevance for the ways in which we screw with instruction pointers. */
+
+int target_is_m88110 = 0;
+
+void
+m88k_target_write_pc (CORE_ADDR pc, ptid_t ptid)
+{
+ /* According to the MC88100 RISC Microprocessor User's Manual,
+ section 6.4.3.1.2:
+
+ ... can be made to return to a particular instruction by placing
+ a valid instruction address in the SNIP and the next sequential
+ instruction address in the SFIP (with V bits set and E bits
+ clear). The rte resumes execution at the instruction pointed to
+ by the SNIP, then the SFIP.
+
+ The E bit is the least significant bit (bit 0). The V (valid)
+ bit is bit 1. This is why we logical or 2 into the values we are
+ writing below. It turns out that SXIP plays no role when
+ returning from an exception so nothing special has to be done
+ with it. We could even (presumably) give it a totally bogus
+ value.
+
+ -- Kevin Buettner */
+
+ write_register_pid (SXIP_REGNUM, pc, ptid);
+ write_register_pid (SNIP_REGNUM, (pc | 2), ptid);
+ write_register_pid (SFIP_REGNUM, (pc | 2) + 4, ptid);
+}
+
+/* The type of a register. */
+struct type *
+m88k_register_type (int regnum)
+{
+ if (regnum >= XFP_REGNUM)
+ return builtin_type_m88110_ext;
+ else if (regnum == PC_REGNUM || regnum == FP_REGNUM || regnum == SP_REGNUM)
+ return builtin_type_void_func_ptr;
+ else
+ return builtin_type_int32;
+}
+
+
+/* The m88k kernel aligns all instructions on 4-byte boundaries. The
+ kernel also uses the least significant two bits for its own hocus
+ pocus. When gdb receives an address from the kernel, it needs to
+ preserve those right-most two bits, but gdb also needs to be careful
+ to realize that those two bits are not really a part of the address
+ of an instruction. Shrug. */
+
+CORE_ADDR
+m88k_addr_bits_remove (CORE_ADDR addr)
+{
+ return ((addr) & ~3);
+}
+
+
+/* Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+
+ For us, the frame address is its stack pointer value, so we look up
+ the function prologue to determine the caller's sp value, and return it. */
+
+CORE_ADDR
+frame_chain (struct frame_info *thisframe)
+{
+
+ frame_find_saved_regs (thisframe, (struct frame_saved_regs *) 0);
+ /* NOTE: this depends on frame_find_saved_regs returning the VALUE, not
+ the ADDRESS, of SP_REGNUM. It also depends on the cache of
+ frame_find_saved_regs results. */
+ if (thisframe->fsr->regs[SP_REGNUM])
+ return thisframe->fsr->regs[SP_REGNUM];
+ else
+ return thisframe->frame; /* Leaf fn -- next frame up has same SP. */
+}
+
+int
+frameless_function_invocation (struct frame_info *frame)
+{
+
+ frame_find_saved_regs (frame, (struct frame_saved_regs *) 0);
+ /* NOTE: this depends on frame_find_saved_regs returning the VALUE, not
+ the ADDRESS, of SP_REGNUM. It also depends on the cache of
+ frame_find_saved_regs results. */
+ if (frame->fsr->regs[SP_REGNUM])
+ return 0; /* Frameful -- return addr saved somewhere */
+ else
+ return 1; /* Frameless -- no saved return address */
+}
+
+void
+init_extra_frame_info (int fromleaf, struct frame_info *frame)
+{
+ frame->fsr = 0; /* Not yet allocated */
+ frame->args_pointer = 0; /* Unknown */
+ frame->locals_pointer = 0; /* Unknown */
+}
+
+/* Examine an m88k function prologue, recording the addresses at which
+ registers are saved explicitly by the prologue code, and returning
+ the address of the first instruction after the prologue (but not
+ after the instruction at address LIMIT, as explained below).
+
+ LIMIT places an upper bound on addresses of the instructions to be
+ examined. If the prologue code scan reaches LIMIT, the scan is
+ aborted and LIMIT is returned. This is used, when examining the
+ prologue for the current frame, to keep examine_prologue () from
+ claiming that a given register has been saved when in fact the
+ instruction that saves it has not yet been executed. LIMIT is used
+ at other times to stop the scan when we hit code after the true
+ function prologue (e.g. for the first source line) which might
+ otherwise be mistaken for function prologue.
+
+ The format of the function prologue matched by this routine is
+ derived from examination of the source to gcc 1.95, particularly
+ the routine output_prologue () in config/out-m88k.c.
+
+ subu r31,r31,n # stack pointer update
+
+ (st rn,r31,offset)? # save incoming regs
+ (st.d rn,r31,offset)?
+
+ (addu r30,r31,n)? # frame pointer update
+
+ (pic sequence)? # PIC code prologue
+
+ (or rn,rm,0)? # Move parameters to other regs
+ */
+
+/* Macros for extracting fields from instructions. */
+
+#define BITMASK(pos, width) (((0x1 << (width)) - 1) << (pos))
+#define EXTRACT_FIELD(val, pos, width) ((val) >> (pos) & BITMASK (0, width))
+#define SUBU_OFFSET(x) ((unsigned)(x & 0xFFFF))
+#define ST_OFFSET(x) ((unsigned)((x) & 0xFFFF))
+#define ST_SRC(x) EXTRACT_FIELD ((x), 21, 5)
+#define ADDU_OFFSET(x) ((unsigned)(x & 0xFFFF))
+
+/*
+ * prologue_insn_tbl is a table of instructions which may comprise a
+ * function prologue. Associated with each table entry (corresponding
+ * to a single instruction or group of instructions), is an action.
+ * This action is used by examine_prologue (below) to determine
+ * the state of certain machine registers and where the stack frame lives.
+ */
+
+enum prologue_insn_action
+{
+ PIA_SKIP, /* don't care what the instruction does */
+ PIA_NOTE_ST, /* note register stored and where */
+ PIA_NOTE_STD, /* note pair of registers stored and where */
+ PIA_NOTE_SP_ADJUSTMENT, /* note stack pointer adjustment */
+ PIA_NOTE_FP_ASSIGNMENT, /* note frame pointer assignment */
+ PIA_NOTE_PROLOGUE_END, /* no more prologue */
+};
+
+struct prologue_insns
+ {
+ unsigned long insn;
+ unsigned long mask;
+ enum prologue_insn_action action;
+ };
+
+struct prologue_insns prologue_insn_tbl[] =
+{
+ /* Various register move instructions */
+ {0x58000000, 0xf800ffff, PIA_SKIP}, /* or/or.u with immed of 0 */
+ {0xf4005800, 0xfc1fffe0, PIA_SKIP}, /* or rd, r0, rs */
+ {0xf4005800, 0xfc00ffff, PIA_SKIP}, /* or rd, rs, r0 */
+
+ /* Stack pointer setup: "subu sp, sp, n" where n is a multiple of 8 */
+ {0x67ff0000, 0xffff0007, PIA_NOTE_SP_ADJUSTMENT},
+
+ /* Frame pointer assignment: "addu r30, r31, n" */
+ {0x63df0000, 0xffff0000, PIA_NOTE_FP_ASSIGNMENT},
+
+ /* Store to stack instructions; either "st rx, sp, n" or "st.d rx, sp, n" */
+ {0x241f0000, 0xfc1f0000, PIA_NOTE_ST}, /* st rx, sp, n */
+ {0x201f0000, 0xfc1f0000, PIA_NOTE_STD}, /* st.d rs, sp, n */
+
+ /* Instructions needed for setting up r25 for pic code. */
+ {0x5f200000, 0xffff0000, PIA_SKIP}, /* or.u r25, r0, offset_high */
+ {0xcc000002, 0xffffffff, PIA_SKIP}, /* bsr.n Lab */
+ {0x5b390000, 0xffff0000, PIA_SKIP}, /* or r25, r25, offset_low */
+ {0xf7396001, 0xffffffff, PIA_SKIP}, /* Lab: addu r25, r25, r1 */
+
+ /* Various branch or jump instructions which have a delay slot -- these
+ do not form part of the prologue, but the instruction in the delay
+ slot might be a store instruction which should be noted. */
+ {0xc4000000, 0xe4000000, PIA_NOTE_PROLOGUE_END},
+ /* br.n, bsr.n, bb0.n, or bb1.n */
+ {0xec000000, 0xfc000000, PIA_NOTE_PROLOGUE_END}, /* bcnd.n */
+ {0xf400c400, 0xfffff7e0, PIA_NOTE_PROLOGUE_END} /* jmp.n or jsr.n */
+
+};
+
+
+/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
+ is not the address of a valid instruction, the address of the next
+ instruction beyond ADDR otherwise. *PWORD1 receives the first word
+ of the instruction. */
+
+#define NEXT_PROLOGUE_INSN(addr, lim, pword1) \
+ (((addr) < (lim)) ? next_insn (addr, pword1) : 0)
+
+/* Read the m88k instruction at 'memaddr' and return the address of
+ the next instruction after that, or 0 if 'memaddr' is not the
+ address of a valid instruction. The instruction
+ is stored at 'pword1'. */
+
+CORE_ADDR
+next_insn (CORE_ADDR memaddr, unsigned long *pword1)
+{
+ *pword1 = read_memory_integer (memaddr, BYTES_PER_88K_INSN);
+ return memaddr + BYTES_PER_88K_INSN;
+}
+
+/* Read a register from frames called by us (or from the hardware regs). */
+
+static int
+read_next_frame_reg (struct frame_info *frame, int regno)
+{
+ for (; frame; frame = frame->next)
+ {
+ if (regno == SP_REGNUM)
+ return FRAME_FP (frame);
+ else if (frame->fsr->regs[regno])
+ return read_memory_integer (frame->fsr->regs[regno], 4);
+ }
+ return read_register (regno);
+}
+
+/* Examine the prologue of a function. `ip' points to the first instruction.
+ `limit' is the limit of the prologue (e.g. the addr of the first
+ linenumber, or perhaps the program counter if we're stepping through).
+ `frame_sp' is the stack pointer value in use in this frame.
+ `fsr' is a pointer to a frame_saved_regs structure into which we put
+ info about the registers saved by this frame.
+ `fi' is a struct frame_info pointer; we fill in various fields in it
+ to reflect the offsets of the arg pointer and the locals pointer. */
+
+static CORE_ADDR
+examine_prologue (register CORE_ADDR ip, register CORE_ADDR limit,
+ CORE_ADDR frame_sp, struct frame_saved_regs *fsr,
+ struct frame_info *fi)
+{
+ register CORE_ADDR next_ip;
+ register int src;
+ unsigned long insn;
+ int size, offset;
+ char must_adjust[32]; /* If set, must adjust offsets in fsr */
+ int sp_offset = -1; /* -1 means not set (valid must be mult of 8) */
+ int fp_offset = -1; /* -1 means not set */
+ CORE_ADDR frame_fp;
+ CORE_ADDR prologue_end = 0;
+
+ memset (must_adjust, '\0', sizeof (must_adjust));
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn);
+
+ while (next_ip)
+ {
+ struct prologue_insns *pip;
+
+ for (pip = prologue_insn_tbl; (insn & pip->mask) != pip->insn;)
+ if (++pip >= prologue_insn_tbl + sizeof prologue_insn_tbl)
+ goto end_of_prologue_found; /* not a prologue insn */
+
+ switch (pip->action)
+ {
+ case PIA_NOTE_ST:
+ case PIA_NOTE_STD:
+ if (sp_offset != -1)
+ {
+ src = ST_SRC (insn);
+ offset = ST_OFFSET (insn);
+ must_adjust[src] = 1;
+ fsr->regs[src++] = offset; /* Will be adjusted later */
+ if (pip->action == PIA_NOTE_STD && src < 32)
+ {
+ offset += 4;
+ must_adjust[src] = 1;
+ fsr->regs[src++] = offset;
+ }
+ }
+ else
+ goto end_of_prologue_found;
+ break;
+ case PIA_NOTE_SP_ADJUSTMENT:
+ if (sp_offset == -1)
+ sp_offset = -SUBU_OFFSET (insn);
+ else
+ goto end_of_prologue_found;
+ break;
+ case PIA_NOTE_FP_ASSIGNMENT:
+ if (fp_offset == -1)
+ fp_offset = ADDU_OFFSET (insn);
+ else
+ goto end_of_prologue_found;
+ break;
+ case PIA_NOTE_PROLOGUE_END:
+ if (!prologue_end)
+ prologue_end = ip;
+ break;
+ case PIA_SKIP:
+ default:
+ /* Do nothing */
+ break;
+ }
+
+ ip = next_ip;
+ next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn);
+ }
+
+end_of_prologue_found:
+
+ if (prologue_end)
+ ip = prologue_end;
+
+ /* We're done with the prologue. If we don't care about the stack
+ frame itself, just return. (Note that fsr->regs has been trashed,
+ but the one caller who calls with fi==0 passes a dummy there.) */
+
+ if (fi == 0)
+ return ip;
+
+ /*
+ OK, now we have:
+
+ sp_offset original (before any alloca calls) displacement of SP
+ (will be negative).
+
+ fp_offset displacement from original SP to the FP for this frame
+ or -1.
+
+ fsr->regs[0..31] displacement from original SP to the stack
+ location where reg[0..31] is stored.
+
+ must_adjust[0..31] set if corresponding offset was set.
+
+ If alloca has been called between the function prologue and the current
+ IP, then the current SP (frame_sp) will not be the original SP as set by
+ the function prologue. If the current SP is not the original SP, then the
+ compiler will have allocated an FP for this frame, fp_offset will be set,
+ and we can use it to calculate the original SP.
+
+ Then, we figure out where the arguments and locals are, and relocate the
+ offsets in fsr->regs to absolute addresses. */
+
+ if (fp_offset != -1)
+ {
+ /* We have a frame pointer, so get it, and base our calc's on it. */
+ frame_fp = (CORE_ADDR) read_next_frame_reg (fi->next, ACTUAL_FP_REGNUM);
+ frame_sp = frame_fp - fp_offset;
+ }
+ else
+ {
+ /* We have no frame pointer, therefore frame_sp is still the same value
+ as set by prologue. But where is the frame itself? */
+ if (must_adjust[SRP_REGNUM])
+ {
+ /* Function header saved SRP (r1), the return address. Frame starts
+ 4 bytes down from where it was saved. */
+ frame_fp = frame_sp + fsr->regs[SRP_REGNUM] - 4;
+ fi->locals_pointer = frame_fp;
+ }
+ else
+ {
+ /* Function header didn't save SRP (r1), so we are in a leaf fn or
+ are otherwise confused. */
+ frame_fp = -1;
+ }
+ }
+
+ /* The locals are relative to the FP (whether it exists as an allocated
+ register, or just as an assumed offset from the SP) */
+ fi->locals_pointer = frame_fp;
+
+ /* The arguments are just above the SP as it was before we adjusted it
+ on entry. */
+ fi->args_pointer = frame_sp - sp_offset;
+
+ /* Now that we know the SP value used by the prologue, we know where
+ it saved all the registers. */
+ for (src = 0; src < 32; src++)
+ if (must_adjust[src])
+ fsr->regs[src] += frame_sp;
+
+ /* The saved value of the SP is always known. */
+ /* (we hope...) */
+ if (fsr->regs[SP_REGNUM] != 0
+ && fsr->regs[SP_REGNUM] != frame_sp - sp_offset)
+ fprintf_unfiltered (gdb_stderr, "Bad saved SP value %lx != %lx, offset %x!\n",
+ fsr->regs[SP_REGNUM],
+ frame_sp - sp_offset, sp_offset);
+
+ fsr->regs[SP_REGNUM] = frame_sp - sp_offset;
+
+ return (ip);
+}
+
+/* Given an ip value corresponding to the start of a function,
+ return the ip of the first instruction after the function
+ prologue. */
+
+CORE_ADDR
+m88k_skip_prologue (CORE_ADDR ip)
+{
+ struct frame_saved_regs saved_regs_dummy;
+ struct symtab_and_line sal;
+ CORE_ADDR limit;
+
+ sal = find_pc_line (ip, 0);
+ limit = (sal.end) ? sal.end : 0xffffffff;
+
+ return (examine_prologue (ip, limit, (CORE_ADDR) 0, &saved_regs_dummy,
+ (struct frame_info *) 0));
+}
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame.
+
+ We cache the result of doing this in the frame_obstack, since it is
+ fairly expensive. */
+
+void
+frame_find_saved_regs (struct frame_info *fi, struct frame_saved_regs *fsr)
+{
+ register struct frame_saved_regs *cache_fsr;
+ CORE_ADDR ip;
+ struct symtab_and_line sal;
+ CORE_ADDR limit;
+
+ if (!fi->fsr)
+ {
+ cache_fsr = (struct frame_saved_regs *)
+ frame_obstack_alloc (sizeof (struct frame_saved_regs));
+ memset (cache_fsr, '\0', sizeof (struct frame_saved_regs));
+ fi->fsr = cache_fsr;
+
+ /* Find the start and end of the function prologue. If the PC
+ is in the function prologue, we only consider the part that
+ has executed already. In the case where the PC is not in
+ the function prologue, we set limit to two instructions beyond
+ where the prologue ends in case if any of the prologue instructions
+ were moved into a delay slot of a branch instruction. */
+
+ ip = get_pc_function_start (fi->pc);
+ sal = find_pc_line (ip, 0);
+ limit = (sal.end && sal.end < fi->pc) ? sal.end + 2 * BYTES_PER_88K_INSN
+ : fi->pc;
+
+ /* This will fill in fields in *fi as well as in cache_fsr. */
+#ifdef SIGTRAMP_FRAME_FIXUP
+ if (fi->signal_handler_caller)
+ SIGTRAMP_FRAME_FIXUP (fi->frame);
+#endif
+ examine_prologue (ip, limit, fi->frame, cache_fsr, fi);
+#ifdef SIGTRAMP_SP_FIXUP
+ if (fi->signal_handler_caller && fi->fsr->regs[SP_REGNUM])
+ SIGTRAMP_SP_FIXUP (fi->fsr->regs[SP_REGNUM]);
+#endif
+ }
+
+ if (fsr)
+ *fsr = *fi->fsr;
+}
+
+/* Return the address of the locals block for the frame
+ described by FI. Returns 0 if the address is unknown.
+ NOTE! Frame locals are referred to by negative offsets from the
+ argument pointer, so this is the same as frame_args_address(). */
+
+CORE_ADDR
+frame_locals_address (struct frame_info *fi)
+{
+ struct frame_saved_regs fsr;
+
+ if (fi->args_pointer) /* Cached value is likely there. */
+ return fi->args_pointer;
+
+ /* Nope, generate it. */
+
+ get_frame_saved_regs (fi, &fsr);
+
+ return fi->args_pointer;
+}
+
+/* Return the address of the argument block for the frame
+ described by FI. Returns 0 if the address is unknown. */
+
+CORE_ADDR
+frame_args_address (struct frame_info *fi)
+{
+ struct frame_saved_regs fsr;
+
+ if (fi->args_pointer) /* Cached value is likely there. */
+ return fi->args_pointer;
+
+ /* Nope, generate it. */
+
+ get_frame_saved_regs (fi, &fsr);
+
+ return fi->args_pointer;
+}
+
+/* Return the saved PC from this frame.
+
+ If the frame has a memory copy of SRP_REGNUM, use that. If not,
+ just use the register SRP_REGNUM itself. */
+
+CORE_ADDR
+frame_saved_pc (struct frame_info *frame)
+{
+ return read_next_frame_reg (frame, SRP_REGNUM);
+}
+
+
+#define DUMMY_FRAME_SIZE 192
+
+static void
+write_word (CORE_ADDR sp, ULONGEST word)
+{
+ register int len = REGISTER_SIZE;
+ char buffer[MAX_REGISTER_RAW_SIZE];
+
+ store_unsigned_integer (buffer, len, word);
+ write_memory (sp, buffer, len);
+}
+
+void
+m88k_push_dummy_frame (void)
+{
+ register CORE_ADDR sp = read_register (SP_REGNUM);
+ register int rn;
+ int offset;
+
+ sp -= DUMMY_FRAME_SIZE; /* allocate a bunch of space */
+
+ for (rn = 0, offset = 0; rn <= SP_REGNUM; rn++, offset += 4)
+ write_word (sp + offset, read_register (rn));
+
+ write_word (sp + offset, read_register (SXIP_REGNUM));
+ offset += 4;
+
+ write_word (sp + offset, read_register (SNIP_REGNUM));
+ offset += 4;
+
+ write_word (sp + offset, read_register (SFIP_REGNUM));
+ offset += 4;
+
+ write_word (sp + offset, read_register (PSR_REGNUM));
+ offset += 4;
+
+ write_word (sp + offset, read_register (FPSR_REGNUM));
+ offset += 4;
+
+ write_word (sp + offset, read_register (FPCR_REGNUM));
+ offset += 4;
+
+ write_register (SP_REGNUM, sp);
+ write_register (ACTUAL_FP_REGNUM, sp);
+}
+
+void
+pop_frame (void)
+{
+ register struct frame_info *frame = get_current_frame ();
+ register int regnum;
+ struct frame_saved_regs fsr;
+
+ get_frame_saved_regs (frame, &fsr);
+
+ if (PC_IN_CALL_DUMMY (read_pc (), read_register (SP_REGNUM), frame->frame))
+ {
+ /* FIXME: I think get_frame_saved_regs should be handling this so
+ that we can deal with the saved registers properly (e.g. frame
+ 1 is a call dummy, the user types "frame 2" and then "print $ps"). */
+ register CORE_ADDR sp = read_register (ACTUAL_FP_REGNUM);
+ int offset;
+
+ for (regnum = 0, offset = 0; regnum <= SP_REGNUM; regnum++, offset += 4)
+ (void) write_register (regnum, read_memory_integer (sp + offset, 4));
+
+ write_register (SXIP_REGNUM, read_memory_integer (sp + offset, 4));
+ offset += 4;
+
+ write_register (SNIP_REGNUM, read_memory_integer (sp + offset, 4));
+ offset += 4;
+
+ write_register (SFIP_REGNUM, read_memory_integer (sp + offset, 4));
+ offset += 4;
+
+ write_register (PSR_REGNUM, read_memory_integer (sp + offset, 4));
+ offset += 4;
+
+ write_register (FPSR_REGNUM, read_memory_integer (sp + offset, 4));
+ offset += 4;
+
+ write_register (FPCR_REGNUM, read_memory_integer (sp + offset, 4));
+ offset += 4;
+
+ }
+ else
+ {
+ for (regnum = FP_REGNUM; regnum > 0; regnum--)
+ if (fsr.regs[regnum])
+ write_register (regnum,
+ read_memory_integer (fsr.regs[regnum], 4));
+ write_pc (frame_saved_pc (frame));
+ }
+ reinit_frame_cache ();
+}
+
+void
+_initialize_m88k_tdep (void)
+{
+ tm_print_insn = print_insn_m88k;
+}
diff --git a/gdb/macrocmd.c b/gdb/macrocmd.c
new file mode 100644
index 00000000000..1d14735bbe6
--- /dev/null
+++ b/gdb/macrocmd.c
@@ -0,0 +1,287 @@
+/* C preprocessor macro expansion commands for GDB.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Red Hat, 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 "defs.h"
+#include "macrotab.h"
+#include "macroexp.h"
+#include "macroscope.h"
+#include "command.h"
+#include "gdbcmd.h"
+
+
+/* The `macro' prefix command. */
+
+static struct cmd_list_element *macrolist;
+
+static void
+macro_command (char *arg, int from_tty)
+{
+ printf_unfiltered
+ ("\"macro\" must be followed by the name of a macro command.\n");
+ help_list (macrolist, "macro ", -1, gdb_stdout);
+}
+
+
+
+/* Macro expansion commands. */
+
+
+static void
+macro_expand_command (char *exp, int from_tty)
+{
+ struct macro_scope *ms = NULL;
+ char *expanded = NULL;
+ struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &ms);
+ make_cleanup (free_current_contents, &expanded);
+
+ /* You know, when the user doesn't specify any expression, it would be
+ really cool if this defaulted to the last expression evaluated.
+ Then it would be easy to ask, "Hey, what did I just evaluate?" But
+ at the moment, the `print' commands don't save the last expression
+ evaluated, just its value. */
+ if (! exp || ! *exp)
+ error ("You must follow the `macro expand' command with the"
+ " expression you\n"
+ "want to expand.");
+
+ ms = default_macro_scope ();
+ if (ms)
+ {
+ expanded = macro_expand (exp, standard_macro_lookup, ms);
+ fputs_filtered ("expands to: ", gdb_stdout);
+ fputs_filtered (expanded, gdb_stdout);
+ fputs_filtered ("\n", gdb_stdout);
+ }
+ else
+ fputs_filtered ("GDB has no preprocessor macro information for "
+ "that code.\n",
+ gdb_stdout);
+
+ do_cleanups (cleanup_chain);
+ return;
+}
+
+
+static void
+macro_expand_once_command (char *exp, int from_tty)
+{
+ struct macro_scope *ms = NULL;
+ char *expanded = NULL;
+ struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &ms);
+ make_cleanup (free_current_contents, &expanded);
+
+ /* You know, when the user doesn't specify any expression, it would be
+ really cool if this defaulted to the last expression evaluated.
+ And it should set the once-expanded text as the new `last
+ expression'. That way, you could just hit return over and over and
+ see the expression expanded one level at a time. */
+ if (! exp || ! *exp)
+ error ("You must follow the `macro expand-once' command with"
+ " the expression\n"
+ "you want to expand.");
+
+ ms = default_macro_scope ();
+ if (ms)
+ {
+ expanded = macro_expand_once (exp, standard_macro_lookup, ms);
+ fputs_filtered ("expands to: ", gdb_stdout);
+ fputs_filtered (expanded, gdb_stdout);
+ fputs_filtered ("\n", gdb_stdout);
+ }
+ else
+ fputs_filtered ("GDB has no preprocessor macro information for "
+ "that code.\n",
+ gdb_stdout);
+
+ do_cleanups (cleanup_chain);
+ return;
+}
+
+
+static void
+show_pp_source_pos (struct ui_file *stream,
+ struct macro_source_file *file,
+ int line)
+{
+ fprintf_filtered (stream, "%s:%d\n", file->filename, line);
+
+ while (file->included_by)
+ {
+ fprintf_filtered (gdb_stdout, " included at %s:%d\n",
+ file->included_by->filename,
+ file->included_at_line);
+ file = file->included_by;
+ }
+}
+
+
+static void
+show_macro_command (char *name, int from_tty)
+{
+ struct macro_scope *ms = NULL;
+ struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &ms);
+ struct macro_definition *d;
+
+ if (! name || ! *name)
+ error ("You must follow the `show macro' command with the name"
+ " of the macro\n"
+ "whose definition you want to see.");
+
+ ms = default_macro_scope ();
+ if (! ms)
+ error ("GDB has no preprocessor macro information for that code.\n");
+
+ d = macro_lookup_definition (ms->file, ms->line, name);
+ if (d)
+ {
+ int line;
+ struct macro_source_file *file
+ = macro_definition_location (ms->file, ms->line, name, &line);
+
+ fprintf_filtered (gdb_stdout, "Defined at ");
+ show_pp_source_pos (gdb_stdout, file, line);
+ fprintf_filtered (gdb_stdout, "#define %s", name);
+ if (d->kind == macro_function_like)
+ {
+ int i;
+
+ fputs_filtered ("(", gdb_stdout);
+ for (i = 0; i < d->argc; i++)
+ {
+ fputs_filtered (d->argv[i], gdb_stdout);
+ if (i + 1 < d->argc)
+ fputs_filtered (", ", gdb_stdout);
+ }
+ fputs_filtered (")", gdb_stdout);
+ }
+ fprintf_filtered (gdb_stdout, " %s\n", d->replacement);
+ }
+ else
+ {
+ fprintf_filtered (gdb_stdout,
+ "The symbol `%s' has no definition as a C/C++"
+ " preprocessor macro\n"
+ "at ", name);
+ show_pp_source_pos (gdb_stdout, ms->file, ms->line);
+ }
+
+ do_cleanups (cleanup_chain);
+}
+
+
+
+/* User-defined macros. */
+
+/* A table of user-defined macros. Unlike the macro tables used for
+ symtabs, this one uses xmalloc for all its allocation, not an
+ obstack, and it doesn't bcache anything; it just xmallocs things. So
+ it's perfectly possible to remove things from this, or redefine
+ things. */
+static struct macro_table *user_macros;
+
+static void
+macro_define_command (char *exp, int from_tty)
+{
+ error ("Command not implemented yet.");
+}
+
+
+static void
+macro_undef_command (char *exp, int from_tty)
+{
+ error ("Command not implemented yet.");
+}
+
+
+static void
+macro_list_command (char *exp, int from_tty)
+{
+ error ("Command not implemented yet.");
+}
+
+
+
+/* Initializing the `macrocmd' module. */
+
+void
+_initialize_macrocmd (void)
+{
+ struct cmd_list_element *c;
+
+ /* We introduce a new command prefix, `macro', under which we'll put
+ the various commands for working with preprocessor macros. */
+ add_prefix_cmd
+ ("macro", class_info, macro_command,
+ "Prefix for commands dealing with C preprocessor macros.",
+ &macrolist, "macro ", 0, &cmdlist);
+
+ add_cmd
+ ("expand", no_class, macro_expand_command,
+ "Fully expand any C/C++ preprocessor macro invocations in EXPRESSION.\n"
+ "Show the expanded expression.",
+ &macrolist);
+ add_alias_cmd ("exp", "expand", no_class, 1, &macrolist);
+ add_cmd
+ ("expand-once", no_class, macro_expand_once_command,
+ "Expand C/C++ preprocessor macro invocations appearing directly in"
+ " EXPRESSION.\n"
+ "Show the expanded expression.\n"
+ "\n"
+ "This command differs from `macro expand' in that it only expands macro\n"
+ "invocations that appear directly in EXPRESSION; if expanding a macro\n"
+ "introduces further macro invocations, those are left unexpanded.\n"
+ "\n"
+ "`macro expand-once' helps you see how a particular macro expands,\n"
+ "whereas `macro expand' shows you how all the macros involved in an\n"
+ "expression work together to yield a pre-processed expression.",
+ &macrolist);
+ add_alias_cmd ("exp1", "expand-once", no_class, 1, &macrolist);
+
+ add_cmd
+ ("macro", no_class, show_macro_command,
+ "Show the definition of MACRO, and its source location.",
+ &showlist);
+
+ add_cmd
+ ("define", no_class, macro_define_command,
+ "Define a new C/C++ preprocessor macro.\n"
+ "The GDB command `macro define DEFINITION' is equivalent to placing a\n"
+ "preprocessor directive of the form `#define DEFINITION' such that the\n"
+ "definition is visible in all the inferior's source files.\n"
+ "For example:\n"
+ " (gdb) macro define PI (3.1415926)\n"
+ " (gdb) macro define MIN(x,y) ((x) < (y) ? (x) : (y))",
+ &macrolist);
+
+ add_cmd
+ ("undef", no_class, macro_undef_command,
+ "Remove the definition of the C/C++ preprocessor macro with the"
+ " given name.",
+ &macrolist);
+
+ add_cmd
+ ("list", no_class, macro_list_command,
+ "List all the macros defined using the `macro define' command.",
+ &macrolist);
+
+ user_macros = new_macro_table (0, 0);
+}
diff --git a/gdb/macroexp.c b/gdb/macroexp.c
new file mode 100644
index 00000000000..061c63a00cf
--- /dev/null
+++ b/gdb/macroexp.c
@@ -0,0 +1,1169 @@
+/* C preprocessor macro expansion for GDB.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Red Hat, 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 "defs.h"
+#include "obstack.h"
+#include "bcache.h"
+#include "macrotab.h"
+#include "macroexp.h"
+#include "gdb_assert.h"
+
+
+
+/* A resizeable, substringable string type. */
+
+
+/* A string type that we can resize, quickly append to, and use to
+ refer to substrings of other strings. */
+struct macro_buffer
+{
+ /* An array of characters. The first LEN bytes are the real text,
+ but there are SIZE bytes allocated to the array. If SIZE is
+ zero, then this doesn't point to a malloc'ed block. If SHARED is
+ non-zero, then this buffer is actually a pointer into some larger
+ string, and we shouldn't append characters to it, etc. Because
+ of sharing, we can't assume in general that the text is
+ null-terminated. */
+ char *text;
+
+ /* The number of characters in the string. */
+ int len;
+
+ /* The number of characters allocated to the string. If SHARED is
+ non-zero, this is meaningless; in this case, we set it to zero so
+ that any "do we have room to append something?" tests will fail,
+ so we don't always have to check SHARED before using this field. */
+ int size;
+
+ /* Zero if TEXT can be safely realloc'ed (i.e., it's its own malloc
+ block). Non-zero if TEXT is actually pointing into the middle of
+ some other block, and we shouldn't reallocate it. */
+ int shared;
+
+ /* For detecting token splicing.
+
+ This is the index in TEXT of the first character of the token
+ that abuts the end of TEXT. If TEXT contains no tokens, then we
+ set this equal to LEN. If TEXT ends in whitespace, then there is
+ no token abutting the end of TEXT (it's just whitespace), and
+ again, we set this equal to LEN. We set this to -1 if we don't
+ know the nature of TEXT. */
+ int last_token;
+
+ /* If this buffer is holding the result from get_token, then this
+ is non-zero if it is an identifier token, zero otherwise. */
+ int is_identifier;
+};
+
+
+/* Set the macro buffer *B to the empty string, guessing that its
+ final contents will fit in N bytes. (It'll get resized if it
+ doesn't, so the guess doesn't have to be right.) Allocate the
+ initial storage with xmalloc. */
+static void
+init_buffer (struct macro_buffer *b, int n)
+{
+ /* Small value for initial testing. */
+ n = 1;
+
+ b->size = n;
+ if (n > 0)
+ b->text = (char *) xmalloc (n);
+ else
+ b->text = NULL;
+ b->len = 0;
+ b->shared = 0;
+ b->last_token = -1;
+}
+
+
+/* Set the macro buffer *BUF to refer to the LEN bytes at ADDR, as a
+ shared substring. */
+static void
+init_shared_buffer (struct macro_buffer *buf, char *addr, int len)
+{
+ buf->text = addr;
+ buf->len = len;
+ buf->shared = 1;
+ buf->size = 0;
+ buf->last_token = -1;
+}
+
+
+/* Free the text of the buffer B. Raise an error if B is shared. */
+static void
+free_buffer (struct macro_buffer *b)
+{
+ gdb_assert (! b->shared);
+ if (b->size)
+ xfree (b->text);
+}
+
+
+/* A cleanup function for macro buffers. */
+static void
+cleanup_macro_buffer (void *untyped_buf)
+{
+ free_buffer ((struct macro_buffer *) untyped_buf);
+}
+
+
+/* Resize the buffer B to be at least N bytes long. Raise an error if
+ B shouldn't be resized. */
+static void
+resize_buffer (struct macro_buffer *b, int n)
+{
+ /* We shouldn't be trying to resize shared strings. */
+ gdb_assert (! b->shared);
+
+ if (b->size == 0)
+ b->size = n;
+ else
+ while (b->size <= n)
+ b->size *= 2;
+
+ b->text = xrealloc (b->text, b->size);
+}
+
+
+/* Append the character C to the buffer B. */
+static inline void
+appendc (struct macro_buffer *b, int c)
+{
+ int new_len = b->len + 1;
+
+ if (new_len > b->size)
+ resize_buffer (b, new_len);
+
+ b->text[b->len] = c;
+ b->len = new_len;
+}
+
+
+/* Append the LEN bytes at ADDR to the buffer B. */
+static inline void
+appendmem (struct macro_buffer *b, char *addr, int len)
+{
+ int new_len = b->len + len;
+
+ if (new_len > b->size)
+ resize_buffer (b, new_len);
+
+ memcpy (b->text + b->len, addr, len);
+ b->len = new_len;
+}
+
+
+
+/* Recognizing preprocessor tokens. */
+
+
+static int
+is_whitespace (int c)
+{
+ return (c == ' '
+ || c == '\t'
+ || c == '\n'
+ || c == '\v'
+ || c == '\f');
+}
+
+
+static int
+is_digit (int c)
+{
+ return ('0' <= c && c <= '9');
+}
+
+
+static int
+is_identifier_nondigit (int c)
+{
+ return (c == '_'
+ || ('a' <= c && c <= 'z')
+ || ('A' <= c && c <= 'Z'));
+}
+
+
+static void
+set_token (struct macro_buffer *tok, char *start, char *end)
+{
+ init_shared_buffer (tok, start, end - start);
+ tok->last_token = 0;
+
+ /* Presumed; get_identifier may overwrite this. */
+ tok->is_identifier = 0;
+}
+
+
+static int
+get_comment (struct macro_buffer *tok, char *p, char *end)
+{
+ if (p + 2 > end)
+ return 0;
+ else if (p[0] == '/'
+ && p[1] == '*')
+ {
+ char *tok_start = p;
+
+ p += 2;
+
+ for (; p < end; p++)
+ if (p + 2 <= end
+ && p[0] == '*'
+ && p[1] == '/')
+ {
+ p += 2;
+ set_token (tok, tok_start, p);
+ return 1;
+ }
+
+ error ("Unterminated comment in macro expansion.");
+ }
+ else if (p[0] == '/'
+ && p[1] == '/')
+ {
+ char *tok_start = p;
+
+ p += 2;
+ for (; p < end; p++)
+ if (*p == '\n')
+ break;
+
+ set_token (tok, tok_start, p);
+ return 1;
+ }
+ else
+ return 0;
+}
+
+
+static int
+get_identifier (struct macro_buffer *tok, char *p, char *end)
+{
+ if (p < end
+ && is_identifier_nondigit (*p))
+ {
+ char *tok_start = p;
+
+ while (p < end
+ && (is_identifier_nondigit (*p)
+ || is_digit (*p)))
+ p++;
+
+ set_token (tok, tok_start, p);
+ tok->is_identifier = 1;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+
+static int
+get_pp_number (struct macro_buffer *tok, char *p, char *end)
+{
+ if (p < end
+ && (is_digit (*p)
+ || *p == '.'))
+ {
+ char *tok_start = p;
+
+ while (p < end)
+ {
+ if (is_digit (*p)
+ || is_identifier_nondigit (*p)
+ || *p == '.')
+ p++;
+ else if (p + 2 <= end
+ && strchr ("eEpP.", *p)
+ && (p[1] == '+' || p[1] == '-'))
+ p += 2;
+ else
+ break;
+ }
+
+ set_token (tok, tok_start, p);
+ return 1;
+ }
+ else
+ return 0;
+}
+
+
+
+/* If the text starting at P going up to (but not including) END
+ starts with a character constant, set *TOK to point to that
+ character constant, and return 1. Otherwise, return zero.
+ Signal an error if it contains a malformed or incomplete character
+ constant. */
+static int
+get_character_constant (struct macro_buffer *tok, char *p, char *end)
+{
+ /* ISO/IEC 9899:1999 (E) Section 6.4.4.4 paragraph 1
+ But of course, what really matters is that we handle it the same
+ way GDB's C/C++ lexer does. So we call parse_escape in utils.c
+ to handle escape sequences. */
+ if ((p + 1 <= end && *p == '\'')
+ || (p + 2 <= end && p[0] == 'L' && p[1] == '\''))
+ {
+ char *tok_start = p;
+ char *body_start;
+
+ if (*p == '\'')
+ p++;
+ else if (*p == 'L')
+ p += 2;
+ else
+ gdb_assert (0);
+
+ body_start = p;
+ for (;;)
+ {
+ if (p >= end)
+ error ("Unmatched single quote.");
+ else if (*p == '\'')
+ {
+ if (p == body_start)
+ error ("A character constant must contain at least one "
+ "character.");
+ p++;
+ break;
+ }
+ else if (*p == '\\')
+ {
+ p++;
+ parse_escape (&p);
+ }
+ else
+ p++;
+ }
+
+ set_token (tok, tok_start, p);
+ return 1;
+ }
+ else
+ return 0;
+}
+
+
+/* If the text starting at P going up to (but not including) END
+ starts with a string literal, set *TOK to point to that string
+ literal, and return 1. Otherwise, return zero. Signal an error if
+ it contains a malformed or incomplete string literal. */
+static int
+get_string_literal (struct macro_buffer *tok, char *p, char *end)
+{
+ if ((p + 1 <= end
+ && *p == '\"')
+ || (p + 2 <= end
+ && p[0] == 'L'
+ && p[1] == '\"'))
+ {
+ char *tok_start = p;
+
+ if (*p == '\"')
+ p++;
+ else if (*p == 'L')
+ p += 2;
+ else
+ gdb_assert (0);
+
+ for (;;)
+ {
+ if (p >= end)
+ error ("Unterminated string in expression.");
+ else if (*p == '\"')
+ {
+ p++;
+ break;
+ }
+ else if (*p == '\n')
+ error ("Newline characters may not appear in string "
+ "constants.");
+ else if (*p == '\\')
+ {
+ p++;
+ parse_escape (&p);
+ }
+ else
+ p++;
+ }
+
+ set_token (tok, tok_start, p);
+ return 1;
+ }
+ else
+ return 0;
+}
+
+
+static int
+get_punctuator (struct macro_buffer *tok, char *p, char *end)
+{
+ /* Here, speed is much less important than correctness and clarity. */
+
+ /* ISO/IEC 9899:1999 (E) Section 6.4.6 Paragraph 1 */
+ static const char * const punctuators[] = {
+ "[", "]", "(", ")", "{", "}", ".", "->",
+ "++", "--", "&", "*", "+", "-", "~", "!",
+ "/", "%", "<<", ">>", "<", ">", "<=", ">=", "==", "!=",
+ "^", "|", "&&", "||",
+ "?", ":", ";", "...",
+ "=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "^=", "|=",
+ ",", "#", "##",
+ "<:", ":>", "<%", "%>", "%:", "%:%:",
+ 0
+ };
+
+ int i;
+
+ if (p + 1 <= end)
+ {
+ for (i = 0; punctuators[i]; i++)
+ {
+ const char *punctuator = punctuators[i];
+
+ if (p[0] == punctuator[0])
+ {
+ int len = strlen (punctuator);
+
+ if (p + len <= end
+ && ! memcmp (p, punctuator, len))
+ {
+ set_token (tok, p, p + len);
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+/* Peel the next preprocessor token off of SRC, and put it in TOK.
+ Mutate TOK to refer to the first token in SRC, and mutate SRC to
+ refer to the text after that token. SRC must be a shared buffer;
+ the resulting TOK will be shared, pointing into the same string SRC
+ does. Initialize TOK's last_token field. Return non-zero if we
+ succeed, or 0 if we didn't find any more tokens in SRC. */
+static int
+get_token (struct macro_buffer *tok,
+ struct macro_buffer *src)
+{
+ char *p = src->text;
+ char *end = p + src->len;
+
+ gdb_assert (src->shared);
+
+ /* From the ISO C standard, ISO/IEC 9899:1999 (E), section 6.4:
+
+ preprocessing-token:
+ header-name
+ identifier
+ pp-number
+ character-constant
+ string-literal
+ punctuator
+ each non-white-space character that cannot be one of the above
+
+ We don't have to deal with header-name tokens, since those can
+ only occur after a #include, which we will never see. */
+
+ while (p < end)
+ if (is_whitespace (*p))
+ p++;
+ else if (get_comment (tok, p, end))
+ p += tok->len;
+ else if (get_pp_number (tok, p, end)
+ || get_character_constant (tok, p, end)
+ || get_string_literal (tok, p, end)
+ /* Note: the grammar in the standard seems to be
+ ambiguous: L'x' can be either a wide character
+ constant, or an identifier followed by a normal
+ character constant. By trying `get_identifier' after
+ we try get_character_constant and get_string_literal,
+ we give the wide character syntax precedence. Now,
+ since GDB doesn't handle wide character constants
+ anyway, is this the right thing to do? */
+ || get_identifier (tok, p, end)
+ || get_punctuator (tok, p, end))
+ {
+ /* How many characters did we consume, including whitespace? */
+ int consumed = p - src->text + tok->len;
+ src->text += consumed;
+ src->len -= consumed;
+ return 1;
+ }
+ else
+ {
+ /* We have found a "non-whitespace character that cannot be
+ one of the above." Make a token out of it. */
+ int consumed;
+
+ set_token (tok, p, p + 1);
+ consumed = p - src->text + tok->len;
+ src->text += consumed;
+ src->len -= consumed;
+ return 1;
+ }
+
+ return 0;
+}
+
+
+
+/* Appending token strings, with and without splicing */
+
+
+/* Append the macro buffer SRC to the end of DEST, and ensure that
+ doing so doesn't splice the token at the end of SRC with the token
+ at the beginning of DEST. SRC and DEST must have their last_token
+ fields set. Upon return, DEST's last_token field is set correctly.
+
+ For example:
+
+ If DEST is "(" and SRC is "y", then we can return with
+ DEST set to "(y" --- we've simply appended the two buffers.
+
+ However, if DEST is "x" and SRC is "y", then we must not return
+ with DEST set to "xy" --- that would splice the two tokens "x" and
+ "y" together to make a single token "xy". However, it would be
+ fine to return with DEST set to "x y". Similarly, "<" and "<" must
+ yield "< <", not "<<", etc. */
+static void
+append_tokens_without_splicing (struct macro_buffer *dest,
+ struct macro_buffer *src)
+{
+ int original_dest_len = dest->len;
+ struct macro_buffer dest_tail, new_token;
+
+ gdb_assert (src->last_token != -1);
+ gdb_assert (dest->last_token != -1);
+
+ /* First, just try appending the two, and call get_token to see if
+ we got a splice. */
+ appendmem (dest, src->text, src->len);
+
+ /* If DEST originally had no token abutting its end, then we can't
+ have spliced anything, so we're done. */
+ if (dest->last_token == original_dest_len)
+ {
+ dest->last_token = original_dest_len + src->last_token;
+ return;
+ }
+
+ /* Set DEST_TAIL to point to the last token in DEST, followed by
+ all the stuff we just appended. */
+ init_shared_buffer (&dest_tail,
+ dest->text + dest->last_token,
+ dest->len - dest->last_token);
+
+ /* Re-parse DEST's last token. We know that DEST used to contain
+ at least one token, so if it doesn't contain any after the
+ append, then we must have spliced "/" and "*" or "/" and "/" to
+ make a comment start. (Just for the record, I got this right
+ the first time. This is not a bug fix.) */
+ if (get_token (&new_token, &dest_tail)
+ && (new_token.text + new_token.len
+ == dest->text + original_dest_len))
+ {
+ /* No splice, so we're done. */
+ dest->last_token = original_dest_len + src->last_token;
+ return;
+ }
+
+ /* Okay, a simple append caused a splice. Let's chop dest back to
+ its original length and try again, but separate the texts with a
+ space. */
+ dest->len = original_dest_len;
+ appendc (dest, ' ');
+ appendmem (dest, src->text, src->len);
+
+ init_shared_buffer (&dest_tail,
+ dest->text + dest->last_token,
+ dest->len - dest->last_token);
+
+ /* Try to re-parse DEST's last token, as above. */
+ if (get_token (&new_token, &dest_tail)
+ && (new_token.text + new_token.len
+ == dest->text + original_dest_len))
+ {
+ /* No splice, so we're done. */
+ dest->last_token = original_dest_len + 1 + src->last_token;
+ return;
+ }
+
+ /* As far as I know, there's no case where inserting a space isn't
+ enough to prevent a splice. */
+ internal_error (__FILE__, __LINE__,
+ "unable to avoid splicing tokens during macro expansion");
+}
+
+
+
+/* Expanding macros! */
+
+
+/* A singly-linked list of the names of the macros we are currently
+ expanding --- for detecting expansion loops. */
+struct macro_name_list {
+ const char *name;
+ struct macro_name_list *next;
+};
+
+
+/* Return non-zero if we are currently expanding the macro named NAME,
+ according to LIST; otherwise, return zero.
+
+ You know, it would be possible to get rid of all the NO_LOOP
+ arguments to these functions by simply generating a new lookup
+ function and baton which refuses to find the definition for a
+ particular macro, and otherwise delegates the decision to another
+ function/baton pair. But that makes the linked list of excluded
+ macros chained through untyped baton pointers, which will make it
+ harder to debug. :( */
+static int
+currently_rescanning (struct macro_name_list *list, const char *name)
+{
+ for (; list; list = list->next)
+ if (strcmp (name, list->name) == 0)
+ return 1;
+
+ return 0;
+}
+
+
+/* Gather the arguments to a macro expansion.
+
+ NAME is the name of the macro being invoked. (It's only used for
+ printing error messages.)
+
+ Assume that SRC is the text of the macro invocation immediately
+ following the macro name. For example, if we're processing the
+ text foo(bar, baz), then NAME would be foo and SRC will be (bar,
+ baz).
+
+ If SRC doesn't start with an open paren ( token at all, return
+ zero, leave SRC unchanged, and don't set *ARGC_P to anything.
+
+ If SRC doesn't contain a properly terminated argument list, then
+ raise an error.
+
+ Otherwise, return a pointer to the first element of an array of
+ macro buffers referring to the argument texts, and set *ARGC_P to
+ the number of arguments we found --- the number of elements in the
+ array. The macro buffers share their text with SRC, and their
+ last_token fields are initialized. The array is allocated with
+ xmalloc, and the caller is responsible for freeing it.
+
+ NOTE WELL: if SRC starts with a open paren ( token followed
+ immediately by a close paren ) token (e.g., the invocation looks
+ like "foo()"), we treat that as one argument, which happens to be
+ the empty list of tokens. The caller should keep in mind that such
+ a sequence of tokens is a valid way to invoke one-parameter
+ function-like macros, but also a valid way to invoke zero-parameter
+ function-like macros. Eeew.
+
+ Consume the tokens from SRC; after this call, SRC contains the text
+ following the invocation. */
+
+static struct macro_buffer *
+gather_arguments (const char *name, struct macro_buffer *src, int *argc_p)
+{
+ struct macro_buffer tok;
+ int args_len, args_size;
+ struct macro_buffer *args = NULL;
+ struct cleanup *back_to = make_cleanup (free_current_contents, &args);
+
+ /* Does SRC start with an opening paren token? Read from a copy of
+ SRC, so SRC itself is unaffected if we don't find an opening
+ paren. */
+ {
+ struct macro_buffer temp;
+ init_shared_buffer (&temp, src->text, src->len);
+
+ if (! get_token (&tok, &temp)
+ || tok.len != 1
+ || tok.text[0] != '(')
+ {
+ discard_cleanups (back_to);
+ return 0;
+ }
+ }
+
+ /* Consume SRC's opening paren. */
+ get_token (&tok, src);
+
+ args_len = 0;
+ args_size = 1; /* small for initial testing */
+ args = (struct macro_buffer *) xmalloc (sizeof (*args) * args_size);
+
+ for (;;)
+ {
+ struct macro_buffer *arg;
+ int depth;
+
+ /* Make sure we have room for the next argument. */
+ if (args_len >= args_size)
+ {
+ args_size *= 2;
+ args = xrealloc (args, sizeof (*args) * args_size);
+ }
+
+ /* Initialize the next argument. */
+ arg = &args[args_len++];
+ set_token (arg, src->text, src->text);
+
+ /* Gather the argument's tokens. */
+ depth = 0;
+ for (;;)
+ {
+ char *start = src->text;
+
+ if (! get_token (&tok, src))
+ error ("Malformed argument list for macro `%s'.", name);
+
+ /* Is tok an opening paren? */
+ if (tok.len == 1 && tok.text[0] == '(')
+ depth++;
+
+ /* Is tok is a closing paren? */
+ else if (tok.len == 1 && tok.text[0] == ')')
+ {
+ /* If it's a closing paren at the top level, then that's
+ the end of the argument list. */
+ if (depth == 0)
+ {
+ discard_cleanups (back_to);
+ *argc_p = args_len;
+ return args;
+ }
+
+ depth--;
+ }
+
+ /* If tok is a comma at top level, then that's the end of
+ the current argument. */
+ else if (tok.len == 1 && tok.text[0] == ',' && depth == 0)
+ break;
+
+ /* Extend the current argument to enclose this token. If
+ this is the current argument's first token, leave out any
+ leading whitespace, just for aesthetics. */
+ if (arg->len == 0)
+ {
+ arg->text = tok.text;
+ arg->len = tok.len;
+ arg->last_token = 0;
+ }
+ else
+ {
+ arg->len = (tok.text + tok.len) - arg->text;
+ arg->last_token = tok.text - arg->text;
+ }
+ }
+ }
+}
+
+
+/* The `expand' and `substitute_args' functions both invoke `scan'
+ recursively, so we need a forward declaration somewhere. */
+static void scan (struct macro_buffer *dest,
+ struct macro_buffer *src,
+ struct macro_name_list *no_loop,
+ macro_lookup_ftype *lookup_func,
+ void *lookup_baton);
+
+
+/* Given the macro definition DEF, being invoked with the actual
+ arguments given by ARGC and ARGV, substitute the arguments into the
+ replacement list, and store the result in DEST.
+
+ If it is necessary to expand macro invocations in one of the
+ arguments, use LOOKUP_FUNC and LOOKUP_BATON to find the macro
+ definitions, and don't expand invocations of the macros listed in
+ NO_LOOP. */
+static void
+substitute_args (struct macro_buffer *dest,
+ struct macro_definition *def,
+ int argc, struct macro_buffer *argv,
+ struct macro_name_list *no_loop,
+ macro_lookup_ftype *lookup_func,
+ void *lookup_baton)
+{
+ /* A macro buffer for the macro's replacement list. */
+ struct macro_buffer replacement_list;
+
+ init_shared_buffer (&replacement_list, (char *) def->replacement,
+ strlen (def->replacement));
+
+ gdb_assert (dest->len == 0);
+ dest->last_token = 0;
+
+ for (;;)
+ {
+ struct macro_buffer tok;
+ char *original_rl_start = replacement_list.text;
+ int substituted = 0;
+
+ /* Find the next token in the replacement list. */
+ if (! get_token (&tok, &replacement_list))
+ break;
+
+ /* Just for aesthetics. If we skipped some whitespace, copy
+ that to DEST. */
+ if (tok.text > original_rl_start)
+ {
+ appendmem (dest, original_rl_start, tok.text - original_rl_start);
+ dest->last_token = dest->len;
+ }
+
+ /* Is this token the stringification operator? */
+ if (tok.len == 1
+ && tok.text[0] == '#')
+ error ("Stringification is not implemented yet.");
+
+ /* Is this token the splicing operator? */
+ if (tok.len == 2
+ && tok.text[0] == '#'
+ && tok.text[1] == '#')
+ error ("Token splicing is not implemented yet.");
+
+ /* Is this token an identifier? */
+ if (tok.is_identifier)
+ {
+ int i;
+
+ /* Is it the magic varargs parameter? */
+ if (tok.len == 11
+ && ! memcmp (tok.text, "__VA_ARGS__", 11))
+ error ("Variable-arity macros not implemented yet.");
+
+ /* Is it one of the parameters? */
+ for (i = 0; i < def->argc; i++)
+ if (tok.len == strlen (def->argv[i])
+ && ! memcmp (tok.text, def->argv[i], tok.len))
+ {
+ struct macro_buffer arg_src;
+
+ /* Expand any macro invocations in the argument text,
+ and append the result to dest. Remember that scan
+ mutates its source, so we need to scan a new buffer
+ referring to the argument's text, not the argument
+ itself. */
+ init_shared_buffer (&arg_src, argv[i].text, argv[i].len);
+ scan (dest, &arg_src, no_loop, lookup_func, lookup_baton);
+ substituted = 1;
+ break;
+ }
+ }
+
+ /* If it wasn't a parameter, then just copy it across. */
+ if (! substituted)
+ append_tokens_without_splicing (dest, &tok);
+ }
+}
+
+
+/* Expand a call to a macro named ID, whose definition is DEF. Append
+ its expansion to DEST. SRC is the input text following the ID
+ token. We are currently rescanning the expansions of the macros
+ named in NO_LOOP; don't re-expand them. Use LOOKUP_FUNC and
+ LOOKUP_BATON to find definitions for any nested macro references.
+
+ Return 1 if we decided to expand it, zero otherwise. (If it's a
+ function-like macro name that isn't followed by an argument list,
+ we don't expand it.) If we return zero, leave SRC unchanged. */
+static int
+expand (const char *id,
+ struct macro_definition *def,
+ struct macro_buffer *dest,
+ struct macro_buffer *src,
+ struct macro_name_list *no_loop,
+ macro_lookup_ftype *lookup_func,
+ void *lookup_baton)
+{
+ struct macro_name_list new_no_loop;
+
+ /* Create a new node to be added to the front of the no-expand list.
+ This list is appropriate for re-scanning replacement lists, but
+ it is *not* appropriate for scanning macro arguments; invocations
+ of the macro whose arguments we are gathering *do* get expanded
+ there. */
+ new_no_loop.name = id;
+ new_no_loop.next = no_loop;
+
+ /* What kind of macro are we expanding? */
+ if (def->kind == macro_object_like)
+ {
+ struct macro_buffer replacement_list;
+
+ init_shared_buffer (&replacement_list, (char *) def->replacement,
+ strlen (def->replacement));
+
+ scan (dest, &replacement_list, &new_no_loop, lookup_func, lookup_baton);
+ return 1;
+ }
+ else if (def->kind == macro_function_like)
+ {
+ struct cleanup *back_to = make_cleanup (null_cleanup, 0);
+ int argc;
+ struct macro_buffer *argv = NULL;
+ struct macro_buffer substituted;
+ struct macro_buffer substituted_src;
+
+ if (def->argc >= 1
+ && strcmp (def->argv[def->argc - 1], "...") == 0)
+ error ("Varargs macros not implemented yet.");
+
+ make_cleanup (free_current_contents, &argv);
+ argv = gather_arguments (id, src, &argc);
+
+ /* If we couldn't find any argument list, then we don't expand
+ this macro. */
+ if (! argv)
+ {
+ do_cleanups (back_to);
+ return 0;
+ }
+
+ /* Check that we're passing an acceptable number of arguments for
+ this macro. */
+ if (argc != def->argc)
+ {
+ /* Remember that a sequence of tokens like "foo()" is a
+ valid invocation of a macro expecting either zero or one
+ arguments. */
+ if (! (argc == 1
+ && argv[0].len == 0
+ && def->argc == 0))
+ error ("Wrong number of arguments to macro `%s' "
+ "(expected %d, got %d).",
+ id, def->argc, argc);
+ }
+
+ /* Note that we don't expand macro invocations in the arguments
+ yet --- we let subst_args take care of that. Parameters that
+ appear as operands of the stringifying operator "#" or the
+ splicing operator "##" don't get macro references expanded,
+ so we can't really tell whether it's appropriate to macro-
+ expand an argument until we see how it's being used. */
+ init_buffer (&substituted, 0);
+ make_cleanup (cleanup_macro_buffer, &substituted);
+ substitute_args (&substituted, def, argc, argv, no_loop,
+ lookup_func, lookup_baton);
+
+ /* Now `substituted' is the macro's replacement list, with all
+ argument values substituted into it properly. Re-scan it for
+ macro references, but don't expand invocations of this macro.
+
+ We create a new buffer, `substituted_src', which points into
+ `substituted', and scan that. We can't scan `substituted'
+ itself, since the tokenization process moves the buffer's
+ text pointer around, and we still need to be able to find
+ `substituted's original text buffer after scanning it so we
+ can free it. */
+ init_shared_buffer (&substituted_src, substituted.text, substituted.len);
+ scan (dest, &substituted_src, &new_no_loop, lookup_func, lookup_baton);
+
+ do_cleanups (back_to);
+
+ return 1;
+ }
+ else
+ internal_error (__FILE__, __LINE__, "bad macro definition kind");
+}
+
+
+/* If the single token in SRC_FIRST followed by the tokens in SRC_REST
+ constitute a macro invokation not forbidden in NO_LOOP, append its
+ expansion to DEST and return non-zero. Otherwise, return zero, and
+ leave DEST unchanged.
+
+ SRC_FIRST and SRC_REST must be shared buffers; DEST must not be one.
+ SRC_FIRST must be a string built by get_token. */
+static int
+maybe_expand (struct macro_buffer *dest,
+ struct macro_buffer *src_first,
+ struct macro_buffer *src_rest,
+ struct macro_name_list *no_loop,
+ macro_lookup_ftype *lookup_func,
+ void *lookup_baton)
+{
+ gdb_assert (src_first->shared);
+ gdb_assert (src_rest->shared);
+ gdb_assert (! dest->shared);
+
+ /* Is this token an identifier? */
+ if (src_first->is_identifier)
+ {
+ /* Make a null-terminated copy of it, since that's what our
+ lookup function expects. */
+ char *id = xmalloc (src_first->len + 1);
+ struct cleanup *back_to = make_cleanup (xfree, id);
+ memcpy (id, src_first->text, src_first->len);
+ id[src_first->len] = 0;
+
+ /* If we're currently re-scanning the result of expanding
+ this macro, don't expand it again. */
+ if (! currently_rescanning (no_loop, id))
+ {
+ /* Does this identifier have a macro definition in scope? */
+ struct macro_definition *def = lookup_func (id, lookup_baton);
+
+ if (def && expand (id, def, dest, src_rest, no_loop,
+ lookup_func, lookup_baton))
+ {
+ do_cleanups (back_to);
+ return 1;
+ }
+ }
+
+ do_cleanups (back_to);
+ }
+
+ return 0;
+}
+
+
+/* Expand macro references in SRC, appending the results to DEST.
+ Assume we are re-scanning the result of expanding the macros named
+ in NO_LOOP, and don't try to re-expand references to them.
+
+ SRC must be a shared buffer; DEST must not be one. */
+static void
+scan (struct macro_buffer *dest,
+ struct macro_buffer *src,
+ struct macro_name_list *no_loop,
+ macro_lookup_ftype *lookup_func,
+ void *lookup_baton)
+{
+ gdb_assert (src->shared);
+ gdb_assert (! dest->shared);
+
+ for (;;)
+ {
+ struct macro_buffer tok;
+ char *original_src_start = src->text;
+
+ /* Find the next token in SRC. */
+ if (! get_token (&tok, src))
+ break;
+
+ /* Just for aesthetics. If we skipped some whitespace, copy
+ that to DEST. */
+ if (tok.text > original_src_start)
+ {
+ appendmem (dest, original_src_start, tok.text - original_src_start);
+ dest->last_token = dest->len;
+ }
+
+ if (! maybe_expand (dest, &tok, src, no_loop, lookup_func, lookup_baton))
+ /* We didn't end up expanding tok as a macro reference, so
+ simply append it to dest. */
+ append_tokens_without_splicing (dest, &tok);
+ }
+
+ /* Just for aesthetics. If there was any trailing whitespace in
+ src, copy it to dest. */
+ if (src->len)
+ {
+ appendmem (dest, src->text, src->len);
+ dest->last_token = dest->len;
+ }
+}
+
+
+char *
+macro_expand (const char *source,
+ macro_lookup_ftype *lookup_func,
+ void *lookup_func_baton)
+{
+ struct macro_buffer src, dest;
+ struct cleanup *back_to;
+
+ init_shared_buffer (&src, (char *) source, strlen (source));
+
+ init_buffer (&dest, 0);
+ dest.last_token = 0;
+ back_to = make_cleanup (cleanup_macro_buffer, &dest);
+
+ scan (&dest, &src, 0, lookup_func, lookup_func_baton);
+
+ appendc (&dest, '\0');
+
+ discard_cleanups (back_to);
+ return dest.text;
+}
+
+
+char *
+macro_expand_once (const char *source,
+ macro_lookup_ftype *lookup_func,
+ void *lookup_func_baton)
+{
+ error ("Expand-once not implemented yet.");
+}
+
+
+char *
+macro_expand_next (char **lexptr,
+ macro_lookup_ftype *lookup_func,
+ void *lookup_baton)
+{
+ struct macro_buffer src, dest, tok;
+ struct cleanup *back_to;
+
+ /* Set up SRC to refer to the input text, pointed to by *lexptr. */
+ init_shared_buffer (&src, *lexptr, strlen (*lexptr));
+
+ /* Set up DEST to receive the expansion, if there is one. */
+ init_buffer (&dest, 0);
+ dest.last_token = 0;
+ back_to = make_cleanup (cleanup_macro_buffer, &dest);
+
+ /* Get the text's first preprocessing token. */
+ if (! get_token (&tok, &src))
+ {
+ do_cleanups (back_to);
+ return 0;
+ }
+
+ /* If it's a macro invocation, expand it. */
+ if (maybe_expand (&dest, &tok, &src, 0, lookup_func, lookup_baton))
+ {
+ /* It was a macro invocation! Package up the expansion as a
+ null-terminated string and return it. Set *lexptr to the
+ start of the next token in the input. */
+ appendc (&dest, '\0');
+ discard_cleanups (back_to);
+ *lexptr = src.text;
+ return dest.text;
+ }
+ else
+ {
+ /* It wasn't a macro invocation. */
+ do_cleanups (back_to);
+ return 0;
+ }
+}
diff --git a/gdb/macroexp.h b/gdb/macroexp.h
new file mode 100644
index 00000000000..57269fa22f8
--- /dev/null
+++ b/gdb/macroexp.h
@@ -0,0 +1,90 @@
+/* Interface to C preprocessor macro expansion for GDB.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Red Hat, 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. */
+
+
+#ifndef MACROEXP_H
+#define MACROEXP_H
+
+/* A function for looking up preprocessor macro definitions. Return
+ the preprocessor definition of NAME in scope according to BATON, or
+ zero if NAME is not defined as a preprocessor macro.
+
+ The caller must not free or modify the definition returned. It is
+ probably unwise for the caller to hold pointers to it for very
+ long; it probably lives in some objfile's obstacks. */
+typedef struct macro_definition *(macro_lookup_ftype) (const char *name,
+ void *baton);
+
+
+/* Expand any preprocessor macros in SOURCE, and return the expanded
+ text. Use LOOKUP_FUNC and LOOKUP_FUNC_BATON to find identifiers'
+ preprocessor definitions. SOURCE is a null-terminated string. The
+ result is a null-terminated string, allocated using xmalloc; it is
+ the caller's responsibility to free it. */
+char *macro_expand (const char *source,
+ macro_lookup_ftype *lookup_func,
+ void *lookup_func_baton);
+
+
+/* Expand all preprocessor macro references that appear explicitly in
+ SOURCE, but do not expand any new macro references introduced by
+ that first level of expansion. Use LOOKUP_FUNC and
+ LOOKUP_FUNC_BATON to find identifiers' preprocessor definitions.
+ SOURCE is a null-terminated string. The result is a
+ null-terminated string, allocated using xmalloc; it is the caller's
+ responsibility to free it. */
+char *macro_expand_once (const char *source,
+ macro_lookup_ftype *lookup_func,
+ void *lookup_func_baton);
+
+
+/* If the null-terminated string pointed to by *LEXPTR begins with a
+ macro invocation, return the result of expanding that invocation as
+ a null-terminated string, and set *LEXPTR to the next character
+ after the invocation. The result is completely expanded; it
+ contains no further macro invocations.
+
+ Otherwise, if *LEXPTR does not start with a macro invocation,
+ return zero, and leave *LEXPTR unchanged.
+
+ Use LOOKUP_FUNC and LOOKUP_BATON to find macro definitions.
+
+ If this function returns a string, the caller is responsible for
+ freeing it, using xfree.
+
+ We need this expand-one-token-at-a-time interface in order to
+ accomodate GDB's C expression parser, which may not consume the
+ entire string. When the user enters a command like
+
+ (gdb) break *func+20 if x == 5
+
+ the parser is expected to consume `func+20', and then stop when it
+ sees the "if". But of course, "if" appearing in a character string
+ or as part of a larger identifier doesn't count. So you pretty
+ much have to do tokenization to find the end of the string that
+ needs to be macro-expanded. Our C/C++ tokenizer isn't really
+ designed to be called by anything but the yacc parser engine. */
+char *macro_expand_next (char **lexptr,
+ macro_lookup_ftype *lookup_func,
+ void *lookup_baton);
+
+
+#endif /* MACROEXP_H */
diff --git a/gdb/macroscope.c b/gdb/macroscope.c
new file mode 100644
index 00000000000..4441be3103f
--- /dev/null
+++ b/gdb/macroscope.c
@@ -0,0 +1,107 @@
+/* Functions for deciding which macros are currently in scope.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Red Hat, 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 "defs.h"
+
+#include "macroscope.h"
+#include "symtab.h"
+#include "target.h"
+#include "frame.h"
+#include "inferior.h"
+
+
+struct macro_scope *
+sal_macro_scope (struct symtab_and_line sal)
+{
+ struct macro_source_file *main;
+ struct macro_scope *ms;
+
+ if (! sal.symtab
+ || ! sal.symtab->macro_table)
+ return 0;
+
+ ms = (struct macro_scope *) xmalloc (sizeof (*ms));
+
+ main = macro_main (sal.symtab->macro_table);
+ ms->file = macro_lookup_inclusion (main, sal.symtab->filename);
+
+ if (! ms->file)
+ internal_error
+ (__FILE__, __LINE__,
+ "\n"
+ "the symtab `%s' refers to a preprocessor macro table which doesn't\n"
+ "have any record of processing a file by that name.\n",
+ sal.symtab->filename);
+
+ ms->line = sal.line;
+
+ return ms;
+}
+
+
+struct macro_scope *
+default_macro_scope ()
+{
+ struct symtab_and_line sal;
+ struct macro_source_file *main;
+ struct macro_scope *ms;
+
+ /* If there's a selected frame, use its PC. */
+ if (selected_frame)
+ sal = find_pc_line (selected_frame->pc, 0);
+
+ /* If the target has any registers at all, then use its PC. Why we
+ would have registers but no stack, I'm not sure. */
+ else if (target_has_registers)
+ sal = find_pc_line (read_pc (), 0);
+
+ /* If all else fails, fall back to the current listing position. */
+ else
+ {
+ /* Don't call select_source_symtab here. That can raise an
+ error if symbols aren't loaded, but GDB calls the expression
+ evaluator in all sorts of contexts.
+
+ For example, commands like `set width' call the expression
+ evaluator to evaluate their numeric arguments. If the
+ current language is C, then that may call this function to
+ choose a scope for macro expansion. If you don't have any
+ symbol files loaded, then select_source_symtab will raise an
+ error. But `set width' shouldn't raise an error just because
+ it can't decide which scope to macro-expand its argument in. */
+ sal.symtab = current_source_symtab;
+ sal.line = current_source_line;
+ }
+
+ return sal_macro_scope (sal);
+}
+
+
+/* Look up the definition of the macro named NAME in scope at the source
+ location given by BATON, which must be a pointer to a `struct
+ macro_scope' structure. */
+struct macro_definition *
+standard_macro_lookup (const char *name, void *baton)
+{
+ struct macro_scope *ms = (struct macro_scope *) baton;
+
+ return macro_lookup_definition (ms->file, ms->line, name);
+}
diff --git a/gdb/macroscope.h b/gdb/macroscope.h
new file mode 100644
index 00000000000..fc10b6dcd60
--- /dev/null
+++ b/gdb/macroscope.h
@@ -0,0 +1,63 @@
+/* Interface to functions for deciding which macros are currently in scope.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Red Hat, 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. */
+
+#ifndef MACROSCOPE_H
+#define MACROSCOPE_H
+
+#include "macrotab.h"
+#include "symtab.h"
+
+
+/* All the information we need to decide which macro definitions are
+ in scope: a source file (either a main source file or an
+ #inclusion), and a line number in that file. */
+struct macro_scope {
+ struct macro_source_file *file;
+ int line;
+};
+
+
+/* Return a `struct macro_scope' object corresponding to the symtab
+ and line given in SAL. If we have no macro information for that
+ location, or if SAL's pc is zero, return zero. */
+struct macro_scope *sal_macro_scope (struct symtab_and_line sal);
+
+
+/* Return a `struct macro_scope' object describing the scope the `macro
+ expand' and `macro expand-once' commands should use for looking up
+ macros. If we have a selected frame, this is the source location of
+ its PC; otherwise, this is the last listing position.
+
+ If we have no macro information for the current location, return zero.
+
+ The object returned is allocated using xmalloc; the caller is
+ responsible for freeing it. */
+struct macro_scope *default_macro_scope (void);
+
+
+/* Look up the definition of the macro named NAME in scope at the source
+ location given by BATON, which must be a pointer to a `struct
+ macro_scope' structure. This function is suitable for use as
+ a macro_lookup_ftype function. */
+struct macro_definition *standard_macro_lookup (const char *name, void *baton);
+
+
+#endif /* MACROSCOPE_H */
diff --git a/gdb/macrotab.c b/gdb/macrotab.c
new file mode 100644
index 00000000000..bb615a55723
--- /dev/null
+++ b/gdb/macrotab.c
@@ -0,0 +1,905 @@
+/* C preprocessor macro tables for GDB.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Red Hat, 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 "defs.h"
+#include "obstack.h"
+#include "splay-tree.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "macrotab.h"
+#include "gdb_assert.h"
+#include "bcache.h"
+#include "complaints.h"
+
+
+/* The macro table structure. */
+
+struct macro_table
+{
+ /* The obstack this table's data should be allocated in, or zero if
+ we should use xmalloc. */
+ struct obstack *obstack;
+
+ /* The bcache we should use to hold macro names, argument names, and
+ definitions, or zero if we should use xmalloc. */
+ struct bcache *bcache;
+
+ /* The main source file for this compilation unit --- the one whose
+ name was given to the compiler. This is the root of the
+ #inclusion tree; everything else is #included from here. */
+ struct macro_source_file *main_source;
+
+ /* The table of macro definitions. This is a splay tree (an ordered
+ binary tree that stays balanced, effectively), sorted by macro
+ name. Where a macro gets defined more than once (presumably with
+ an #undefinition in between), we sort the definitions by the
+ order they would appear in the preprocessor's output. That is,
+ if `a.c' #includes `m.h' and then #includes `n.h', and both
+ header files #define X (with an #undef somewhere in between),
+ then the definition from `m.h' appears in our splay tree before
+ the one from `n.h'.
+
+ The splay tree's keys are `struct macro_key' pointers;
+ the values are `struct macro_definition' pointers.
+
+ The splay tree, its nodes, and the keys and values are allocated
+ in obstack, if it's non-zero, or with xmalloc otherwise. The
+ macro names, argument names, argument name arrays, and definition
+ strings are all allocated in bcache, if non-zero, or with xmalloc
+ otherwise. */
+ splay_tree definitions;
+};
+
+
+
+/* Allocation and freeing functions. */
+
+/* Allocate SIZE bytes of memory appropriately for the macro table T.
+ This just checks whether T has an obstack, or whether its pieces
+ should be allocated with xmalloc. */
+static void *
+macro_alloc (int size, struct macro_table *t)
+{
+ if (t->obstack)
+ return obstack_alloc (t->obstack, size);
+ else
+ return xmalloc (size);
+}
+
+
+static void
+macro_free (void *object, struct macro_table *t)
+{
+ gdb_assert (! t->obstack);
+ xfree (object);
+}
+
+
+/* If the macro table T has a bcache, then cache the LEN bytes at ADDR
+ there, and return the cached copy. Otherwise, just xmalloc a copy
+ of the bytes, and return a pointer to that. */
+static const void *
+macro_bcache (struct macro_table *t, const void *addr, int len)
+{
+ if (t->bcache)
+ return bcache (addr, len, t->bcache);
+ else
+ {
+ void *copy = xmalloc (len);
+ memcpy (copy, addr, len);
+ return copy;
+ }
+}
+
+
+/* If the macro table T has a bcache, cache the null-terminated string
+ S there, and return a pointer to the cached copy. Otherwise,
+ xmalloc a copy and return that. */
+static const char *
+macro_bcache_str (struct macro_table *t, const char *s)
+{
+ return (char *) macro_bcache (t, s, strlen (s) + 1);
+}
+
+
+/* Free a possibly bcached object OBJ. That is, if the macro table T
+ has a bcache, it's an error; otherwise, xfree OBJ. */
+void
+macro_bcache_free (struct macro_table *t, void *obj)
+{
+ gdb_assert (! t->bcache);
+ xfree (obj);
+}
+
+
+
+/* Macro tree keys, w/their comparison, allocation, and freeing functions. */
+
+/* A key in the splay tree. */
+struct macro_key
+{
+ /* The table we're in. We only need this in order to free it, since
+ the splay tree library's key and value freeing functions require
+ that the key or value contain all the information needed to free
+ themselves. */
+ struct macro_table *table;
+
+ /* The name of the macro. This is in the table's bcache, if it has
+ one. */
+ const char *name;
+
+ /* The source file and line number where the definition's scope
+ begins. This is also the line of the definition itself. */
+ struct macro_source_file *start_file;
+ int start_line;
+
+ /* The first source file and line after the definition's scope.
+ (That is, the scope does not include this endpoint.) If end_file
+ is zero, then the definition extends to the end of the
+ compilation unit. */
+ struct macro_source_file *end_file;
+ int end_line;
+};
+
+
+/* Return the #inclusion depth of the source file FILE. This is the
+ number of #inclusions it took to reach this file. For the main
+ source file, the #inclusion depth is zero; for a file it #includes
+ directly, the depth would be one; and so on. */
+static int
+inclusion_depth (struct macro_source_file *file)
+{
+ int depth;
+
+ for (depth = 0; file->included_by; depth++)
+ file = file->included_by;
+
+ return depth;
+}
+
+
+/* Compare two source locations (from the same compilation unit).
+ This is part of the comparison function for the tree of
+ definitions.
+
+ LINE1 and LINE2 are line numbers in the source files FILE1 and
+ FILE2. Return a value:
+ - less than zero if {LINE,FILE}1 comes before {LINE,FILE}2,
+ - greater than zero if {LINE,FILE}1 comes after {LINE,FILE}2, or
+ - zero if they are equal.
+
+ When the two locations are in different source files --- perhaps
+ one is in a header, while another is in the main source file --- we
+ order them by where they would appear in the fully pre-processed
+ sources, where all the #included files have been substituted into
+ their places. */
+static int
+compare_locations (struct macro_source_file *file1, int line1,
+ struct macro_source_file *file2, int line2)
+{
+ /* We want to treat positions in an #included file as coming *after*
+ the line containing the #include, but *before* the line after the
+ include. As we walk up the #inclusion tree toward the main
+ source file, we update fileX and lineX as we go; includedX
+ indicates whether the original position was from the #included
+ file. */
+ int included1 = 0;
+ int included2 = 0;
+
+ /* If a file is zero, that means "end of compilation unit." Handle
+ that specially. */
+ if (! file1)
+ {
+ if (! file2)
+ return 0;
+ else
+ return 1;
+ }
+ else if (! file2)
+ return -1;
+
+ /* If the two files are not the same, find their common ancestor in
+ the #inclusion tree. */
+ if (file1 != file2)
+ {
+ /* If one file is deeper than the other, walk up the #inclusion
+ chain until the two files are at least at the same *depth*.
+ Then, walk up both files in synchrony until they're the same
+ file. That file is the common ancestor. */
+ int depth1 = inclusion_depth (file1);
+ int depth2 = inclusion_depth (file2);
+
+ /* Only one of these while loops will ever execute in any given
+ case. */
+ while (depth1 > depth2)
+ {
+ line1 = file1->included_at_line;
+ file1 = file1->included_by;
+ included1 = 1;
+ depth1--;
+ }
+ while (depth2 > depth1)
+ {
+ line2 = file2->included_at_line;
+ file2 = file2->included_by;
+ included2 = 1;
+ depth2--;
+ }
+
+ /* Now both file1 and file2 are at the same depth. Walk toward
+ the root of the tree until we find where the branches meet. */
+ while (file1 != file2)
+ {
+ line1 = file1->included_at_line;
+ file1 = file1->included_by;
+ /* At this point, we know that the case the includedX flags
+ are trying to deal with won't come up, but we'll just
+ maintain them anyway. */
+ included1 = 1;
+
+ line2 = file2->included_at_line;
+ file2 = file2->included_by;
+ included2 = 1;
+
+ /* Sanity check. If file1 and file2 are really from the
+ same compilation unit, then they should both be part of
+ the same tree, and this shouldn't happen. */
+ gdb_assert (file1 && file2);
+ }
+ }
+
+ /* Now we've got two line numbers in the same file. */
+ if (line1 == line2)
+ {
+ /* They can't both be from #included files. Then we shouldn't
+ have walked up this far. */
+ gdb_assert (! included1 || ! included2);
+
+ /* Any #included position comes after a non-#included position
+ with the same line number in the #including file. */
+ if (included1)
+ return 1;
+ else if (included2)
+ return -1;
+ else
+ return 0;
+ }
+ else
+ return line1 - line2;
+}
+
+
+/* Compare a macro key KEY against NAME, the source file FILE, and
+ line number LINE.
+
+ Sort definitions by name; for two definitions with the same name,
+ place the one whose definition comes earlier before the one whose
+ definition comes later.
+
+ Return -1, 0, or 1 if key comes before, is identical to, or comes
+ after NAME, FILE, and LINE. */
+static int
+key_compare (struct macro_key *key,
+ const char *name, struct macro_source_file *file, int line)
+{
+ int names = strcmp (key->name, name);
+ if (names)
+ return names;
+
+ return compare_locations (key->start_file, key->start_line,
+ file, line);
+}
+
+
+/* The macro tree comparison function, typed for the splay tree
+ library's happiness. */
+static int
+macro_tree_compare (splay_tree_key untyped_key1,
+ splay_tree_key untyped_key2)
+{
+ struct macro_key *key1 = (struct macro_key *) untyped_key1;
+ struct macro_key *key2 = (struct macro_key *) untyped_key2;
+
+ return key_compare (key1, key2->name, key2->start_file, key2->start_line);
+}
+
+
+/* Construct a new macro key node for a macro in table T whose name is
+ NAME, and whose scope starts at LINE in FILE; register the name in
+ the bcache. */
+static struct macro_key *
+new_macro_key (struct macro_table *t,
+ const char *name,
+ struct macro_source_file *file,
+ int line)
+{
+ struct macro_key *k = macro_alloc (sizeof (*k), t);
+
+ memset (k, 0, sizeof (*k));
+ k->table = t;
+ k->name = macro_bcache_str (t, name);
+ k->start_file = file;
+ k->start_line = line;
+ k->end_file = 0;
+
+ return k;
+}
+
+
+static void
+macro_tree_delete_key (void *untyped_key)
+{
+ struct macro_key *key = (struct macro_key *) untyped_key;
+
+ macro_bcache_free (key->table, (char *) key->name);
+ macro_free (key, key->table);
+}
+
+
+
+/* Building and querying the tree of #included files. */
+
+
+/* Allocate and initialize a new source file structure. */
+static struct macro_source_file *
+new_source_file (struct macro_table *t,
+ const char *filename)
+{
+ /* Get space for the source file structure itself. */
+ struct macro_source_file *f = macro_alloc (sizeof (*f), t);
+
+ memset (f, 0, sizeof (*f));
+ f->table = t;
+ f->filename = macro_bcache_str (t, filename);
+ f->includes = 0;
+
+ return f;
+}
+
+
+/* Free a source file, and all the source files it #included. */
+static void
+free_macro_source_file (struct macro_source_file *src)
+{
+ struct macro_source_file *child, *next_child;
+
+ /* Free this file's children. */
+ for (child = src->includes; child; child = next_child)
+ {
+ next_child = child->next_included;
+ free_macro_source_file (child);
+ }
+
+ macro_bcache_free (src->table, (char *) src->filename);
+ macro_free (src, src->table);
+}
+
+
+struct macro_source_file *
+macro_set_main (struct macro_table *t,
+ const char *filename)
+{
+ /* You can't change a table's main source file. What would that do
+ to the tree? */
+ gdb_assert (! t->main_source);
+
+ t->main_source = new_source_file (t, filename);
+
+ return t->main_source;
+}
+
+
+struct macro_source_file *
+macro_main (struct macro_table *t)
+{
+ gdb_assert (t->main_source);
+
+ return t->main_source;
+}
+
+
+struct macro_source_file *
+macro_include (struct macro_source_file *source,
+ int line,
+ const char *included)
+{
+ struct macro_source_file *new;
+ struct macro_source_file **link;
+
+ /* Find the right position in SOURCE's `includes' list for the new
+ file. Scan until we find the first file we shouldn't follow ---
+ which is therefore the file we should directly precede --- or
+ reach the end of the list. */
+ for (link = &source->includes;
+ *link && line < (*link)->included_at_line;
+ link = &(*link)->next_included)
+ ;
+
+ /* Did we find another file already #included at the same line as
+ the new one? */
+ if (*link && line == (*link)->included_at_line)
+ {
+ /* This means the compiler is emitting bogus debug info. (GCC
+ circa March 2002 did this.) It also means that the splay
+ tree ordering function, macro_tree_compare, will abort,
+ because it can't tell which #inclusion came first. But GDB
+ should tolerate bad debug info. So:
+
+ First, squawk. */
+ static struct complaint bogus_inclusion_line = {
+ "both `%s' and `%s' allegedly #included at %s:%d", 0, 0
+ };
+
+ complain (&bogus_inclusion_line,
+ included, (*link)->filename, source->filename, line);
+
+ /* Now, choose a new, unoccupied line number for this
+ #inclusion, after the alleged #inclusion line. */
+ while (*link && line == (*link)->included_at_line)
+ {
+ /* This line number is taken, so try the next line. */
+ line++;
+ link = &(*link)->next_included;
+ }
+ }
+
+ /* At this point, we know that LINE is an unused line number, and
+ *LINK points to the entry an #inclusion at that line should
+ precede. */
+ new = new_source_file (source->table, included);
+ new->included_by = source;
+ new->included_at_line = line;
+ new->next_included = *link;
+ *link = new;
+
+ return new;
+}
+
+
+struct macro_source_file *
+macro_lookup_inclusion (struct macro_source_file *source, const char *name)
+{
+ /* Is SOURCE itself named NAME? */
+ if (strcmp (name, source->filename) == 0)
+ return source;
+
+ /* The filename in the source structure is probably a full path, but
+ NAME could be just the final component of the name. */
+ {
+ int name_len = strlen (name);
+ int src_name_len = strlen (source->filename);
+
+ /* We do mean < here, and not <=; if the lengths are the same,
+ then the strcmp above should have triggered, and we need to
+ check for a slash here. */
+ if (name_len < src_name_len
+ && source->filename[src_name_len - name_len - 1] == '/'
+ && strcmp (name, source->filename + src_name_len - name_len) == 0)
+ return source;
+ }
+
+ /* It's not us. Try all our children, and return the lowest. */
+ {
+ struct macro_source_file *child;
+ struct macro_source_file *best = NULL;
+ int best_depth = 0;
+
+ for (child = source->includes; child; child = child->next_included)
+ {
+ struct macro_source_file *result
+ = macro_lookup_inclusion (child, name);
+
+ if (result)
+ {
+ int result_depth = inclusion_depth (result);
+
+ if (! best || result_depth < best_depth)
+ {
+ best = result;
+ best_depth = result_depth;
+ }
+ }
+ }
+
+ return best;
+ }
+}
+
+
+
+/* Registering and looking up macro definitions. */
+
+
+/* Construct a definition for a macro in table T. Cache all strings,
+ and the macro_definition structure itself, in T's bcache. */
+static struct macro_definition *
+new_macro_definition (struct macro_table *t,
+ enum macro_kind kind,
+ int argc, const char **argv,
+ const char *replacement)
+{
+ struct macro_definition *d = macro_alloc (sizeof (*d), t);
+
+ memset (d, 0, sizeof (*d));
+ d->table = t;
+ d->kind = kind;
+ d->replacement = macro_bcache_str (t, replacement);
+
+ if (kind == macro_function_like)
+ {
+ int i;
+ const char **cached_argv;
+ int cached_argv_size = argc * sizeof (*cached_argv);
+
+ /* Bcache all the arguments. */
+ cached_argv = alloca (cached_argv_size);
+ for (i = 0; i < argc; i++)
+ cached_argv[i] = macro_bcache_str (t, argv[i]);
+
+ /* Now bcache the array of argument pointers itself. */
+ d->argv = macro_bcache (t, cached_argv, cached_argv_size);
+ d->argc = argc;
+ }
+
+ /* We don't bcache the entire definition structure because it's got
+ a pointer to the macro table in it; since each compilation unit
+ has its own macro table, you'd only get bcache hits for identical
+ definitions within a compilation unit, which seems unlikely.
+
+ "So, why do macro definitions have pointers to their macro tables
+ at all?" Well, when the splay tree library wants to free a
+ node's value, it calls the value freeing function with nothing
+ but the value itself. It makes the (apparently reasonable)
+ assumption that the value carries enough information to free
+ itself. But not all macro tables have bcaches, so not all macro
+ definitions would be bcached. There's no way to tell whether a
+ given definition is bcached without knowing which table the
+ definition belongs to. ... blah. The thing's only sixteen
+ bytes anyway, and we can still bcache the name, args, and
+ definition, so we just don't bother bcaching the definition
+ structure itself. */
+ return d;
+}
+
+
+/* Free a macro definition. */
+static void
+macro_tree_delete_value (void *untyped_definition)
+{
+ struct macro_definition *d = (struct macro_definition *) untyped_definition;
+ struct macro_table *t = d->table;
+
+ if (d->kind == macro_function_like)
+ {
+ int i;
+
+ for (i = 0; i < d->argc; i++)
+ macro_bcache_free (t, (char *) d->argv[i]);
+ macro_bcache_free (t, (char **) d->argv);
+ }
+
+ macro_bcache_free (t, (char *) d->replacement);
+ macro_free (d, t);
+}
+
+
+/* Find the splay tree node for the definition of NAME at LINE in
+ SOURCE, or zero if there is none. */
+static splay_tree_node
+find_definition (const char *name,
+ struct macro_source_file *file,
+ int line)
+{
+ struct macro_table *t = file->table;
+ splay_tree_node n;
+
+ /* Construct a macro_key object, just for the query. */
+ struct macro_key query;
+
+ query.name = name;
+ query.start_file = file;
+ query.start_line = line;
+ query.end_file = NULL;
+
+ n = splay_tree_lookup (t->definitions, (splay_tree_key) &query);
+ if (! n)
+ {
+ /* It's okay for us to do two queries like this: the real work
+ of the searching is done when we splay, and splaying the tree
+ a second time at the same key is a constant time operation.
+ If this still bugs you, you could always just extend the
+ splay tree library with a predecessor-or-equal operation, and
+ use that. */
+ splay_tree_node pred = splay_tree_predecessor (t->definitions,
+ (splay_tree_key) &query);
+
+ if (pred)
+ {
+ /* Make sure this predecessor actually has the right name.
+ We just want to search within a given name's definitions. */
+ struct macro_key *found = (struct macro_key *) pred->key;
+
+ if (strcmp (found->name, name) == 0)
+ n = pred;
+ }
+ }
+
+ if (n)
+ {
+ struct macro_key *found = (struct macro_key *) n->key;
+
+ /* Okay, so this definition has the right name, and its scope
+ begins before the given source location. But does its scope
+ end after the given source location? */
+ if (compare_locations (file, line, found->end_file, found->end_line) < 0)
+ return n;
+ else
+ return 0;
+ }
+ else
+ return 0;
+}
+
+
+/* If NAME already has a definition in scope at LINE in SOURCE, return
+ the key. If the old definition is different from the definition
+ given by KIND, ARGC, ARGV, and REPLACEMENT, complain, too.
+ Otherwise, return zero. (ARGC and ARGV are meaningless unless KIND
+ is `macro_function_like'.) */
+static struct macro_key *
+check_for_redefinition (struct macro_source_file *source, int line,
+ const char *name, enum macro_kind kind,
+ int argc, const char **argv,
+ const char *replacement)
+{
+ splay_tree_node n = find_definition (name, source, line);
+
+ if (n)
+ {
+ struct macro_key *found_key = (struct macro_key *) n->key;
+ struct macro_definition *found_def
+ = (struct macro_definition *) n->value;
+ int same = 1;
+
+ /* Is this definition the same as the existing one?
+ According to the standard, this comparison needs to be done
+ on lists of tokens, not byte-by-byte, as we do here. But
+ that's too hard for us at the moment, and comparing
+ byte-by-byte will only yield false negatives (i.e., extra
+ warning messages), not false positives (i.e., unnoticed
+ definition changes). */
+ if (kind != found_def->kind)
+ same = 0;
+ else if (strcmp (replacement, found_def->replacement))
+ same = 0;
+ else if (kind == macro_function_like)
+ {
+ if (argc != found_def->argc)
+ same = 0;
+ else
+ {
+ int i;
+
+ for (i = 0; i < argc; i++)
+ if (strcmp (argv[i], found_def->argv[i]))
+ same = 0;
+ }
+ }
+
+ if (! same)
+ {
+ static struct complaint macro_redefined = {
+ "macro `%s' redefined at %s:%d; original definition at %s:%d",
+ 0, 0
+ };
+ complain (&macro_redefined,
+ name,
+ source->filename, line,
+ found_key->start_file->filename,
+ found_key->start_line);
+ }
+
+ return found_key;
+ }
+ else
+ return 0;
+}
+
+
+void
+macro_define_object (struct macro_source_file *source, int line,
+ const char *name, const char *replacement)
+{
+ struct macro_table *t = source->table;
+ struct macro_key *k;
+ struct macro_definition *d;
+
+ k = check_for_redefinition (source, line,
+ name, macro_object_like,
+ 0, 0,
+ replacement);
+
+ /* If we're redefining a symbol, and the existing key would be
+ identical to our new key, then the splay_tree_insert function
+ will try to delete the old definition. When the definition is
+ living on an obstack, this isn't a happy thing.
+
+ Since this only happens in the presence of questionable debug
+ info, we just ignore all definitions after the first. The only
+ case I know of where this arises is in GCC's output for
+ predefined macros, and all the definitions are the same in that
+ case. */
+ if (k && ! key_compare (k, name, source, line))
+ return;
+
+ k = new_macro_key (t, name, source, line);
+ d = new_macro_definition (t, macro_object_like, 0, 0, replacement);
+ splay_tree_insert (t->definitions, (splay_tree_key) k, (splay_tree_value) d);
+}
+
+
+void
+macro_define_function (struct macro_source_file *source, int line,
+ const char *name, int argc, const char **argv,
+ const char *replacement)
+{
+ struct macro_table *t = source->table;
+ struct macro_key *k;
+ struct macro_definition *d;
+
+ k = check_for_redefinition (source, line,
+ name, macro_function_like,
+ argc, argv,
+ replacement);
+
+ /* See comments about duplicate keys in macro_define_object. */
+ if (k && ! key_compare (k, name, source, line))
+ return;
+
+ /* We should also check here that all the argument names in ARGV are
+ distinct. */
+
+ k = new_macro_key (t, name, source, line);
+ d = new_macro_definition (t, macro_function_like, argc, argv, replacement);
+ splay_tree_insert (t->definitions, (splay_tree_key) k, (splay_tree_value) d);
+}
+
+
+void
+macro_undef (struct macro_source_file *source, int line,
+ const char *name)
+{
+ splay_tree_node n = find_definition (name, source, line);
+
+ if (n)
+ {
+ /* This function is the only place a macro's end-of-scope
+ location gets set to anything other than "end of the
+ compilation unit" (i.e., end_file is zero). So if this macro
+ already has its end-of-scope set, then we're probably seeing
+ a second #undefinition for the same #definition. */
+ struct macro_key *key = (struct macro_key *) n->key;
+
+ if (key->end_file)
+ {
+ static struct complaint double_undef = {
+ "macro '%s' is #undefined twice, at %s:%d and %s:%d",
+ 0, 0
+ };
+ complain (&double_undef, name, source->filename, line,
+ key->end_file->filename, key->end_line);
+ }
+
+ /* Whatever the case, wipe out the old ending point, and
+ make this the ending point. */
+ key->end_file = source;
+ key->end_line = line;
+ }
+ else
+ {
+ /* According to the ISO C standard, an #undef for a symbol that
+ has no macro definition in scope is ignored. So we should
+ ignore it too. */
+#if 0
+ static struct complaint no_macro_to_undefine = {
+ "no definition for macro `%s' in scope to #undef at %s:%d",
+ 0, 0
+ };
+ complain (&no_macro_to_undefine, name, source->filename, line);
+#endif
+ }
+}
+
+
+struct macro_definition *
+macro_lookup_definition (struct macro_source_file *source,
+ int line, const char *name)
+{
+ splay_tree_node n = find_definition (name, source, line);
+
+ if (n)
+ return (struct macro_definition *) n->value;
+ else
+ return 0;
+}
+
+
+struct macro_source_file *
+macro_definition_location (struct macro_source_file *source,
+ int line,
+ const char *name,
+ int *definition_line)
+{
+ splay_tree_node n = find_definition (name, source, line);
+
+ if (n)
+ {
+ struct macro_key *key = (struct macro_key *) n->key;
+ *definition_line = key->start_line;
+ return key->start_file;
+ }
+ else
+ return 0;
+}
+
+
+
+/* Creating and freeing macro tables. */
+
+
+struct macro_table *
+new_macro_table (struct obstack *obstack,
+ struct bcache *b)
+{
+ struct macro_table *t;
+
+ /* First, get storage for the `struct macro_table' itself. */
+ if (obstack)
+ t = obstack_alloc (obstack, sizeof (*t));
+ else
+ t = xmalloc (sizeof (*t));
+
+ memset (t, 0, sizeof (*t));
+ t->obstack = obstack;
+ t->bcache = b;
+ t->main_source = NULL;
+ t->definitions = (splay_tree_new_with_allocator
+ (macro_tree_compare,
+ ((splay_tree_delete_key_fn) macro_tree_delete_key),
+ ((splay_tree_delete_value_fn) macro_tree_delete_value),
+ ((splay_tree_allocate_fn) macro_alloc),
+ ((splay_tree_deallocate_fn) macro_free),
+ t));
+
+ return t;
+}
+
+
+void
+free_macro_table (struct macro_table *table)
+{
+ /* Free the source file tree. */
+ free_macro_source_file (table->main_source);
+
+ /* Free the table of macro definitions. */
+ splay_tree_delete (table->definitions);
+}
diff --git a/gdb/macrotab.h b/gdb/macrotab.h
new file mode 100644
index 00000000000..cbc6d1b53d7
--- /dev/null
+++ b/gdb/macrotab.h
@@ -0,0 +1,295 @@
+/* Interface to C preprocessor macro tables for GDB.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Red Hat, 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. */
+
+#ifndef MACROTAB_H
+#define MACROTAB_H
+
+#include "obstack.h"
+#include "bcache.h"
+
+/* How do we represent a source location? I mean, how should we
+ represent them within GDB; the user wants to use all sorts of
+ ambiguous abbreviations, like "break 32" and "break foo.c:32"
+ ("foo.c" may have been #included into several compilation units),
+ but what do we disambiguate those things to?
+
+ - Answer 1: "Filename and line number." (Or column number, if
+ you're picky.) That's not quite good enough. For example, the
+ same source file can be #included into several different
+ compilation units --- which #inclusion do you mean?
+
+ - Answer 2: "Compilation unit, filename, and line number." This is
+ a pretty good answer; GDB's `struct symtab_and_line' basically
+ embodies this representation. But it's still ambiguous; what if a
+ given compilation unit #includes the same file twice --- how can I
+ set a breakpoint on line 12 of the fifth #inclusion of "foo.c"?
+
+ - Answer 3: "Compilation unit, chain of #inclusions, and line
+ number." This is analogous to the way GCC reports errors in
+ #include files:
+
+ $ gcc -c base.c
+ In file included from header2.h:8,
+ from header1.h:3,
+ from base.c:5:
+ header3.h:1: parse error before ')' token
+ $
+
+ GCC tells you exactly what path of #inclusions led you to the
+ problem. It gives you complete information, in a way that the
+ following would not:
+
+ $ gcc -c base.c
+ header3.h:1: parse error before ')' token
+ $
+
+ Converting all of GDB to use this is a big task, and I'm not really
+ suggesting it should be a priority. But this module's whole
+ purpose is to maintain structures describing the macro expansion
+ process, so I think it's appropriate for us to take a little care
+ to do that in a complete fashion.
+
+ In this interface, the first line of a file is numbered 1, not 0.
+ This is the same convention the rest of GDB uses. */
+
+
+/* A table of all the macro definitions for a given compilation unit. */
+struct macro_table;
+
+
+/* A source file that participated in a compilation unit --- either a
+ main file, or an #included file. If a file is #included more than
+ once, the presence of the `included_from' and `included_at_line'
+ members means that we need to make one instance of this structure
+ for each #inclusion. Taken as a group, these structures form a
+ tree mapping the #inclusions that contributed to the compilation
+ unit, with the main source file as its root.
+
+ It's worth noting that libcpp has a simpler way of representing all
+ this, which we should consider switching to. It might even be
+ suitable for ordinary non-macro line number info.
+
+ Suppose you take your main source file, and after each line
+ containing an #include directive you insert the text of the
+ #included file. The result is a big file that pretty much
+ corresponds to the full text the compiler's going to see. There's
+ a one-to-one correspondence between lines in the big file and
+ per-inclusion lines in the source files. (Obviously, #include
+ directives that are #if'd out don't count. And you'll need to
+ append a newline to any file that doesn't end in one, to avoid
+ splicing the last #included line with the next line of the
+ #including file.)
+
+ Libcpp calls line numbers in this big imaginary file "logical line
+ numbers", and has a data structure called a "line map" that can map
+ logical line numbers onto actual source filenames and line numbers,
+ and also tell you the chain of #inclusions responsible for any
+ particular logical line number. Basically, this means you can pass
+ around a single line number and some kind of "compilation unit"
+ object and you get nice, unambiguous source code locations that
+ distinguish between multiple #inclusions of the same file, etc.
+
+ Pretty neat, huh? */
+
+struct macro_source_file
+{
+
+ /* The macro table for the compilation unit this source location is
+ a part of. */
+ struct macro_table *table;
+
+ /* A source file --- possibly a header file. */
+ const char *filename;
+
+ /* The location we were #included from, or zero if we are the
+ compilation unit's main source file. */
+ struct macro_source_file *included_by;
+
+ /* If `included_from' is non-zero, the line number in that source
+ file at which we were included. */
+ int included_at_line;
+
+ /* Head of a linked list of the source files #included by this file;
+ our children in the #inclusion tree. This list is sorted by its
+ elements' `included_at_line' values, which are unique. (The
+ macro splay tree's ordering function needs this property.) */
+ struct macro_source_file *includes;
+
+ /* The next file #included by our `included_from' file; our sibling
+ in the #inclusion tree. */
+ struct macro_source_file *next_included;
+};
+
+
+/* Create a new, empty macro table. Allocate it in OBSTACK, or use
+ xmalloc if OBSTACK is zero. Use BCACHE to store all macro names,
+ arguments, definitions, and anything else that might be the same
+ amongst compilation units in an executable file; if BCACHE is zero,
+ don't cache these things.
+
+ Note that, if either OBSTACK or BCACHE are non-zero, then you
+ should only ever add information the macro table --- you should
+ never remove things from it. You'll get an error if you try. At
+ the moment, since we only provide obstacks and bcaches for macro
+ tables for symtabs, this restriction makes a nice sanity check.
+ Obstacks and bcaches are pretty much grow-only structures anyway.
+ However, if we find that it's occasionally useful to delete things
+ even from the symtab's tables, and the storage leak isn't a
+ problem, this restriction could be lifted. */
+struct macro_table *new_macro_table (struct obstack *obstack,
+ struct bcache *bcache);
+
+
+/* Free TABLE, and any macro definitions, source file structures,
+ etc. it owns. This will raise an internal error if TABLE was
+ allocated on an obstack, or if it uses a bcache. */
+void free_macro_table (struct macro_table *table);
+
+
+/* Set FILENAME as the main source file of TABLE. Return a source
+ file structure describing that file; if we record the #definition
+ of macros, or the #inclusion of other files into FILENAME, we'll
+ use that source file structure to indicate the context.
+
+ The "main source file" is the one that was given to the compiler;
+ all other source files that contributed to the compilation unit are
+ #included, directly or indirectly, from this one.
+
+ The macro table makes its own copy of FILENAME; the caller is
+ responsible for freeing FILENAME when it is no longer needed. */
+struct macro_source_file *macro_set_main (struct macro_table *table,
+ const char *filename);
+
+
+/* Return the main source file of the macro table TABLE. */
+struct macro_source_file *macro_main (struct macro_table *table);
+
+
+/* Record a #inclusion.
+ Record in SOURCE's macro table that, at line number LINE in SOURCE,
+ we #included the file INCLUDED. Return a source file structure we
+ can use for symbols #defined or files #included into that. If we've
+ already created a source file structure for this #inclusion, return
+ the same structure we created last time.
+
+ The first line of the source file has a line number of 1, not 0.
+
+ The macro table makes its own copy of INCLUDED; the caller is
+ responsible for freeing INCLUDED when it is no longer needed. */
+struct macro_source_file *macro_include (struct macro_source_file *source,
+ int line,
+ const char *included);
+
+
+/* Find any source file structure for a file named NAME, either
+ included into SOURCE, or SOURCE itself. Return zero if we have
+ none. NAME is only the final portion of the filename, not the full
+ path. e.g., `stdio.h', not `/usr/include/stdio.h'. If NAME
+ appears more than once in the inclusion tree, return the
+ least-nested inclusion --- the one closest to the main source file. */
+struct macro_source_file *(macro_lookup_inclusion
+ (struct macro_source_file *source,
+ const char *name));
+
+
+/* Record an object-like #definition (i.e., one with no parameter list).
+ Record in SOURCE's macro table that, at line number LINE in SOURCE,
+ we #defined a preprocessor symbol named NAME, whose replacement
+ string is REPLACEMENT. This function makes copies of NAME and
+ REPLACEMENT; the caller is responsible for freeing them. */
+void macro_define_object (struct macro_source_file *source, int line,
+ const char *name, const char *replacement);
+
+
+/* Record an function-like #definition (i.e., one with a parameter list).
+
+ Record in SOURCE's macro table that, at line number LINE in SOURCE,
+ we #defined a preprocessor symbol named NAME, with ARGC arguments
+ whose names are given in ARGV, whose replacement string is REPLACEMENT. If
+ the macro takes a variable number of arguments, then ARGC should be
+ one greater than the number of named arguments, and ARGV[ARGC-1]
+ should be the string "...". This function makes its own copies of
+ NAME, ARGV, and REPLACEMENT; the caller is responsible for freeing
+ them. */
+void macro_define_function (struct macro_source_file *source, int line,
+ const char *name, int argc, const char **argv,
+ const char *replacement);
+
+
+/* Record an #undefinition.
+ Record in SOURCE's macro table that, at line number LINE in SOURCE,
+ we removed the definition for the preprocessor symbol named NAME. */
+void macro_undef (struct macro_source_file *source, int line,
+ const char *name);
+
+
+/* Different kinds of macro definitions. */
+enum macro_kind
+{
+ macro_object_like,
+ macro_function_like
+};
+
+
+/* A preprocessor symbol definition. */
+struct macro_definition
+{
+ /* The table this definition lives in. */
+ struct macro_table *table;
+
+ /* What kind of macro it is. */
+ enum macro_kind kind;
+
+ /* If `kind' is `macro_function_like', the number of arguments it
+ takes, and their names. The names, and the array of pointers to
+ them, are in the table's bcache, if it has one. */
+ int argc;
+ const char * const *argv;
+
+ /* The replacement string (body) of the macro. This is in the
+ table's bcache, if it has one. */
+ const char *replacement;
+};
+
+
+/* Return a pointer to the macro definition for NAME in scope at line
+ number LINE of SOURCE. If LINE is -1, return the definition in
+ effect at the end of the file. The macro table owns the structure;
+ the caller need not free it. Return zero if NAME is not #defined
+ at that point. */
+struct macro_definition *(macro_lookup_definition
+ (struct macro_source_file *source,
+ int line, const char *name));
+
+
+/* Return the source location of the definition for NAME in scope at
+ line number LINE of SOURCE. Set *DEFINITION_LINE to the line
+ number of the definition, and return a source file structure for
+ the file. Return zero if NAME has no definition in scope at that
+ point, and leave *DEFINITION_LINE unchanged. */
+struct macro_source_file *(macro_definition_location
+ (struct macro_source_file *source,
+ int line,
+ const char *name,
+ int *definition_line));
+
+
+#endif /* MACROTAB_H */
diff --git a/gdb/maint.c b/gdb/maint.c
new file mode 100644
index 00000000000..ddaa390b683
--- /dev/null
+++ b/gdb/maint.c
@@ -0,0 +1,798 @@
+/* Support for GDB maintenance commands.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ Written by Fred Fish at 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 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 "defs.h"
+#include <ctype.h>
+#include <signal.h>
+#include "command.h"
+#include "gdbcmd.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "demangle.h"
+#include "gdbcore.h"
+#include "expression.h" /* For language.h */
+#include "language.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "value.h"
+
+#include "cli/cli-decode.h"
+
+extern void _initialize_maint_cmds (void);
+
+static void maintenance_command (char *, int);
+
+static void maintenance_dump_me (char *, int);
+
+static void maintenance_internal_error (char *args, int from_tty);
+
+static void maintenance_demangle (char *, int);
+
+static void maintenance_time_display (char *, int);
+
+static void maintenance_space_display (char *, int);
+
+static void maintenance_info_command (char *, int);
+
+static void print_section_table (bfd *, asection *, void *);
+
+static void maintenance_info_sections (char *, int);
+
+static void maintenance_print_command (char *, int);
+
+static void maintenance_do_deprecate (char *, int);
+
+/* Set this to the maximum number of seconds to wait instead of waiting forever
+ in target_wait(). If this timer times out, then it generates an error and
+ the command is aborted. This replaces most of the need for timeouts in the
+ GDB test suite, and makes it possible to distinguish between a hung target
+ and one with slow communications. */
+
+int watchdog = 0;
+
+/*
+
+ LOCAL FUNCTION
+
+ maintenance_command -- access the maintenance subcommands
+
+ SYNOPSIS
+
+ void maintenance_command (char *args, int from_tty)
+
+ DESCRIPTION
+
+ */
+
+static void
+maintenance_command (char *args, int from_tty)
+{
+ printf_unfiltered ("\"maintenance\" must be followed by the name of a maintenance command.\n");
+ help_list (maintenancelist, "maintenance ", -1, gdb_stdout);
+}
+
+#ifndef _WIN32
+/* ARGSUSED */
+static void
+maintenance_dump_me (char *args, int from_tty)
+{
+ if (query ("Should GDB dump core? "))
+ {
+#ifdef __DJGPP__
+ /* SIGQUIT by default is ignored, so use SIGABRT instead. */
+ signal (SIGABRT, SIG_DFL);
+ kill (getpid (), SIGABRT);
+#else
+ signal (SIGQUIT, SIG_DFL);
+ kill (getpid (), SIGQUIT);
+#endif
+ }
+}
+#endif
+
+/* Stimulate the internal error mechanism that GDB uses when an
+ internal problem is detected. Allows testing of the mechanism.
+ Also useful when the user wants to drop a core file but not exit
+ GDB. */
+
+static void
+maintenance_internal_error (char *args, int from_tty)
+{
+ internal_error (__FILE__, __LINE__,
+ "internal maintenance");
+}
+
+/* Someday we should allow demangling for things other than just
+ explicit strings. For example, we might want to be able to specify
+ the address of a string in either GDB's process space or the
+ debuggee's process space, and have gdb fetch and demangle that
+ string. If we have a char* pointer "ptr" that points to a string,
+ we might want to be able to given just the name and have GDB
+ demangle and print what it points to, etc. (FIXME) */
+
+static void
+maintenance_demangle (char *args, int from_tty)
+{
+ char *demangled;
+
+ if (args == NULL || *args == '\0')
+ {
+ printf_unfiltered ("\"maintenance demangle\" takes an argument to demangle.\n");
+ }
+ else
+ {
+ demangled = cplus_demangle (args, DMGL_ANSI | DMGL_PARAMS);
+ if (demangled != NULL)
+ {
+ printf_unfiltered ("%s\n", demangled);
+ xfree (demangled);
+ }
+ else
+ {
+ printf_unfiltered ("Can't demangle \"%s\"\n", args);
+ }
+ }
+}
+
+static void
+maintenance_time_display (char *args, int from_tty)
+{
+ extern int display_time;
+
+ if (args == NULL || *args == '\0')
+ printf_unfiltered ("\"maintenance time\" takes a numeric argument.\n");
+ else
+ display_time = strtol (args, NULL, 10);
+}
+
+static void
+maintenance_space_display (char *args, int from_tty)
+{
+ extern int display_space;
+
+ if (args == NULL || *args == '\0')
+ printf_unfiltered ("\"maintenance space\" takes a numeric argument.\n");
+ else
+ display_space = strtol (args, NULL, 10);
+}
+
+/* The "maintenance info" command is defined as a prefix, with
+ allow_unknown 0. Therefore, its own definition is called only for
+ "maintenance info" with no args. */
+
+/* ARGSUSED */
+static void
+maintenance_info_command (char *arg, int from_tty)
+{
+ printf_unfiltered ("\"maintenance info\" must be followed by the name of an info command.\n");
+ help_list (maintenanceinfolist, "maintenance info ", -1, gdb_stdout);
+}
+
+/* Mini tokenizing lexer for 'maint info sections' command. */
+
+static int
+match_substring (const char *string, const char *substr)
+{
+ int substr_len = strlen(substr);
+ const char *tok;
+
+ while ((tok = strstr (string, substr)) != NULL)
+ {
+ /* Got a partial match. Is it a whole word? */
+ if (tok == string
+ || tok[-1] == ' '
+ || tok[-1] == '\t')
+ {
+ /* Token is delimited at the front... */
+ if (tok[substr_len] == ' '
+ || tok[substr_len] == '\t'
+ || tok[substr_len] == '\0')
+ {
+ /* Token is delimited at the rear. Got a whole-word match. */
+ return 1;
+ }
+ }
+ /* Token didn't match as a whole word. Advance and try again. */
+ string = tok + 1;
+ }
+ return 0;
+}
+
+static int
+match_bfd_flags (char *string, flagword flags)
+{
+ if (flags & SEC_ALLOC)
+ if (match_substring (string, "ALLOC"))
+ return 1;
+ if (flags & SEC_LOAD)
+ if (match_substring (string, "LOAD"))
+ return 1;
+ if (flags & SEC_RELOC)
+ if (match_substring (string, "RELOC"))
+ return 1;
+ if (flags & SEC_READONLY)
+ if (match_substring (string, "READONLY"))
+ return 1;
+ if (flags & SEC_CODE)
+ if (match_substring (string, "CODE"))
+ return 1;
+ if (flags & SEC_DATA)
+ if (match_substring (string, "DATA"))
+ return 1;
+ if (flags & SEC_ROM)
+ if (match_substring (string, "ROM"))
+ return 1;
+ if (flags & SEC_CONSTRUCTOR)
+ if (match_substring (string, "CONSTRUCTOR"))
+ return 1;
+ if (flags & SEC_HAS_CONTENTS)
+ if (match_substring (string, "HAS_CONTENTS"))
+ return 1;
+ if (flags & SEC_NEVER_LOAD)
+ if (match_substring (string, "NEVER_LOAD"))
+ return 1;
+ if (flags & SEC_COFF_SHARED_LIBRARY)
+ if (match_substring (string, "COFF_SHARED_LIBRARY"))
+ return 1;
+ if (flags & SEC_IS_COMMON)
+ if (match_substring (string, "IS_COMMON"))
+ return 1;
+
+ return 0;
+}
+
+static void
+print_bfd_flags (flagword flags)
+{
+ if (flags & SEC_ALLOC)
+ printf_filtered (" ALLOC");
+ if (flags & SEC_LOAD)
+ printf_filtered (" LOAD");
+ if (flags & SEC_RELOC)
+ printf_filtered (" RELOC");
+ if (flags & SEC_READONLY)
+ printf_filtered (" READONLY");
+ if (flags & SEC_CODE)
+ printf_filtered (" CODE");
+ if (flags & SEC_DATA)
+ printf_filtered (" DATA");
+ if (flags & SEC_ROM)
+ printf_filtered (" ROM");
+ if (flags & SEC_CONSTRUCTOR)
+ printf_filtered (" CONSTRUCTOR");
+ if (flags & SEC_HAS_CONTENTS)
+ printf_filtered (" HAS_CONTENTS");
+ if (flags & SEC_NEVER_LOAD)
+ printf_filtered (" NEVER_LOAD");
+ if (flags & SEC_COFF_SHARED_LIBRARY)
+ printf_filtered (" COFF_SHARED_LIBRARY");
+ if (flags & SEC_IS_COMMON)
+ printf_filtered (" IS_COMMON");
+}
+
+static void
+maint_print_section_info (const char *name, flagword flags,
+ CORE_ADDR addr, CORE_ADDR endaddr,
+ unsigned long filepos)
+{
+ /* FIXME-32x64: Need print_address_numeric with field width. */
+ printf_filtered (" 0x%s", paddr (addr));
+ printf_filtered ("->0x%s", paddr (endaddr));
+ printf_filtered (" at %s",
+ local_hex_string_custom ((unsigned long) filepos, "08l"));
+ printf_filtered (": %s", name);
+ print_bfd_flags (flags);
+ printf_filtered ("\n");
+}
+
+static void
+print_bfd_section_info (bfd *abfd,
+ asection *asect,
+ void *arg)
+{
+ flagword flags = bfd_get_section_flags (abfd, asect);
+ const char *name = bfd_section_name (abfd, asect);
+
+ if (arg == NULL || *((char *) arg) == '\0'
+ || match_substring ((char *) arg, name)
+ || match_bfd_flags ((char *) arg, flags))
+ {
+ CORE_ADDR addr, endaddr;
+
+ addr = bfd_section_vma (abfd, asect);
+ endaddr = addr + bfd_section_size (abfd, asect);
+ maint_print_section_info (name, flags, addr, endaddr, asect->filepos);
+ }
+}
+
+static void
+print_objfile_section_info (bfd *abfd,
+ struct obj_section *asect,
+ char *string)
+{
+ flagword flags = bfd_get_section_flags (abfd, asect->the_bfd_section);
+ const char *name = bfd_section_name (abfd, asect->the_bfd_section);
+
+ if (string == NULL || *string == '\0'
+ || match_substring (string, name)
+ || match_bfd_flags (string, flags))
+ {
+ maint_print_section_info (name, flags, asect->addr, asect->endaddr,
+ asect->the_bfd_section->filepos);
+ }
+}
+
+/* ARGSUSED */
+static void
+maintenance_info_sections (char *arg, int from_tty)
+{
+ if (exec_bfd)
+ {
+ printf_filtered ("Exec file:\n");
+ printf_filtered (" `%s', ", bfd_get_filename (exec_bfd));
+ wrap_here (" ");
+ printf_filtered ("file type %s.\n", bfd_get_target (exec_bfd));
+ if (arg && *arg && match_substring (arg, "ALLOBJ"))
+ {
+ struct objfile *ofile;
+ struct obj_section *osect;
+
+ /* Only this function cares about the 'ALLOBJ' argument;
+ if 'ALLOBJ' is the only argument, discard it rather than
+ passing it down to print_objfile_section_info (which
+ wouldn't know how to handle it). */
+ if (strcmp (arg, "ALLOBJ") == 0)
+ arg = NULL;
+
+ ALL_OBJFILES (ofile)
+ {
+ printf_filtered (" Object file: %s\n",
+ bfd_get_filename (ofile->obfd));
+ ALL_OBJFILE_OSECTIONS (ofile, osect)
+ {
+ print_objfile_section_info (ofile->obfd, osect, arg);
+ }
+ }
+ }
+ else
+ bfd_map_over_sections (exec_bfd, print_bfd_section_info, arg);
+ }
+
+ if (core_bfd)
+ {
+ printf_filtered ("Core file:\n");
+ printf_filtered (" `%s', ", bfd_get_filename (core_bfd));
+ wrap_here (" ");
+ printf_filtered ("file type %s.\n", bfd_get_target (core_bfd));
+ bfd_map_over_sections (core_bfd, print_bfd_section_info, arg);
+ }
+}
+
+/* ARGSUSED */
+void
+maintenance_print_statistics (char *args, int from_tty)
+{
+ print_objfile_statistics ();
+ print_symbol_bcache_statistics ();
+}
+
+void
+maintenance_print_architecture (char *args, int from_tty)
+{
+ if (args == NULL)
+ gdbarch_dump (current_gdbarch, gdb_stdout);
+ else
+ {
+ struct ui_file *file = gdb_fopen (args, "w");
+ if (file == NULL)
+ perror_with_name ("maintenance print architecture");
+ gdbarch_dump (current_gdbarch, file);
+ ui_file_delete (file);
+ }
+}
+
+/* The "maintenance print" command is defined as a prefix, with
+ allow_unknown 0. Therefore, its own definition is called only for
+ "maintenance print" with no args. */
+
+/* ARGSUSED */
+static void
+maintenance_print_command (char *arg, int from_tty)
+{
+ printf_unfiltered ("\"maintenance print\" must be followed by the name of a print command.\n");
+ help_list (maintenanceprintlist, "maintenance print ", -1, gdb_stdout);
+}
+
+/* The "maintenance translate-address" command converts a section and address
+ to a symbol. This can be called in two ways:
+ maintenance translate-address <secname> <addr>
+ or maintenance translate-address <addr>
+ */
+
+static void
+maintenance_translate_address (char *arg, int from_tty)
+{
+ CORE_ADDR address;
+ asection *sect;
+ char *p;
+ struct minimal_symbol *sym;
+ struct objfile *objfile;
+
+ if (arg == NULL || *arg == 0)
+ error ("requires argument (address or section + address)");
+
+ sect = NULL;
+ p = arg;
+
+ if (!isdigit (*p))
+ { /* See if we have a valid section name */
+ while (*p && !isspace (*p)) /* Find end of section name */
+ p++;
+ if (*p == '\000') /* End of command? */
+ error ("Need to specify <section-name> and <address>");
+ *p++ = '\000';
+ while (isspace (*p))
+ p++; /* Skip whitespace */
+
+ ALL_OBJFILES (objfile)
+ {
+ sect = bfd_get_section_by_name (objfile->obfd, arg);
+ if (sect != NULL)
+ break;
+ }
+
+ if (!sect)
+ error ("Unknown section %s.", arg);
+ }
+
+ address = parse_and_eval_address (p);
+
+ if (sect)
+ sym = lookup_minimal_symbol_by_pc_section (address, sect);
+ else
+ sym = lookup_minimal_symbol_by_pc (address);
+
+ if (sym)
+ printf_filtered ("%s+%s\n",
+ SYMBOL_SOURCE_NAME (sym),
+ paddr_u (address - SYMBOL_VALUE_ADDRESS (sym)));
+ else if (sect)
+ printf_filtered ("no symbol at %s:0x%s\n", sect->name, paddr (address));
+ else
+ printf_filtered ("no symbol at 0x%s\n", paddr (address));
+
+ return;
+}
+
+
+/* When a command is deprecated the user will be warned the first time
+ the command is used. If possible, a replacement will be
+ offered. */
+
+static void
+maintenance_deprecate (char *args, int from_tty)
+{
+ if (args == NULL || *args == '\0')
+ {
+ printf_unfiltered ("\"maintenance deprecate\" takes an argument, \n\
+the command you want to deprecate, and optionally the replacement command \n\
+enclosed in quotes.\n");
+ }
+
+ maintenance_do_deprecate (args, 1);
+
+}
+
+
+static void
+maintenance_undeprecate (char *args, int from_tty)
+{
+ if (args == NULL || *args == '\0')
+ {
+ printf_unfiltered ("\"maintenance undeprecate\" takes an argument, \n\
+the command you want to undeprecate.\n");
+ }
+
+ maintenance_do_deprecate (args, 0);
+
+}
+
+/* You really shouldn't be using this. It is just for the testsuite.
+ Rather, you should use deprecate_cmd() when the command is created
+ in _initialize_blah().
+
+ This function deprecates a command and optionally assigns it a
+ replacement. */
+
+static void
+maintenance_do_deprecate (char *text, int deprecate)
+{
+
+ struct cmd_list_element *alias = NULL;
+ struct cmd_list_element *prefix_cmd = NULL;
+ struct cmd_list_element *cmd = NULL;
+
+ char *start_ptr = NULL;
+ char *end_ptr = NULL;
+ int len;
+ char *replacement = NULL;
+
+ if (text == NULL)
+ return;
+
+ if (!lookup_cmd_composition (text, &alias, &prefix_cmd, &cmd))
+ {
+ printf_filtered ("Can't find command '%s' to deprecate.\n", text);
+ return;
+ }
+
+ if (deprecate)
+ {
+ /* look for a replacement command */
+ start_ptr = strchr (text, '\"');
+ if (start_ptr != NULL)
+ {
+ start_ptr++;
+ end_ptr = strrchr (start_ptr, '\"');
+ if (end_ptr != NULL)
+ {
+ len = end_ptr - start_ptr;
+ start_ptr[len] = '\0';
+ replacement = xstrdup (start_ptr);
+ }
+ }
+ }
+
+ if (!start_ptr || !end_ptr)
+ replacement = NULL;
+
+
+ /* If they used an alias, we only want to deprecate the alias.
+
+ Note the MALLOCED_REPLACEMENT test. If the command's replacement
+ string was allocated at compile time we don't want to free the
+ memory. */
+ if (alias)
+ {
+
+ if (alias->flags & MALLOCED_REPLACEMENT)
+ xfree (alias->replacement);
+
+ if (deprecate)
+ alias->flags |= (DEPRECATED_WARN_USER | CMD_DEPRECATED);
+ else
+ alias->flags &= ~(DEPRECATED_WARN_USER | CMD_DEPRECATED);
+ alias->replacement = replacement;
+ alias->flags |= MALLOCED_REPLACEMENT;
+ return;
+ }
+ else if (cmd)
+ {
+ if (cmd->flags & MALLOCED_REPLACEMENT)
+ xfree (cmd->replacement);
+
+ if (deprecate)
+ cmd->flags |= (DEPRECATED_WARN_USER | CMD_DEPRECATED);
+ else
+ cmd->flags &= ~(DEPRECATED_WARN_USER | CMD_DEPRECATED);
+ cmd->replacement = replacement;
+ cmd->flags |= MALLOCED_REPLACEMENT;
+ return;
+ }
+}
+
+/* Maintenance set/show framework. */
+
+static struct cmd_list_element *maintenance_set_cmdlist;
+static struct cmd_list_element *maintenance_show_cmdlist;
+
+static void
+maintenance_set_cmd (char *args, int from_tty)
+{
+ printf_unfiltered ("\"maintenance set\" must be followed by the name of a set command.\n");
+ help_list (maintenance_set_cmdlist, "maintenance set ", -1, gdb_stdout);
+}
+
+static void
+maintenance_show_cmd (char *args, int from_tty)
+{
+ cmd_show_list (maintenance_show_cmdlist, from_tty, "");
+}
+
+#ifdef NOTYET
+/* Profiling support. */
+
+static int maintenance_profile_p;
+
+static void
+maintenance_set_profile_cmd (char *args, int from_tty, struct cmd_list_element *c)
+{
+ maintenance_profile_p = 0;
+ warning ("\"maintenance set profile\" command not supported.\n");
+}
+#endif
+
+void
+_initialize_maint_cmds (void)
+{
+ struct cmd_list_element *tmpcmd;
+
+ add_prefix_cmd ("maintenance", class_maintenance, maintenance_command,
+ "Commands for use by GDB maintainers.\n\
+Includes commands to dump specific internal GDB structures in\n\
+a human readable form, to cause GDB to deliberately dump core,\n\
+to test internal functions such as the C++ demangler, etc.",
+ &maintenancelist, "maintenance ", 0,
+ &cmdlist);
+
+ add_com_alias ("mt", "maintenance", class_maintenance, 1);
+
+ add_prefix_cmd ("info", class_maintenance, maintenance_info_command,
+ "Commands for showing internal info about the program being debugged.",
+ &maintenanceinfolist, "maintenance info ", 0,
+ &maintenancelist);
+ add_alias_cmd ("i", "info", class_maintenance, 1, &maintenancelist);
+
+ add_cmd ("sections", class_maintenance, maintenance_info_sections,
+ "List the BFD sections of the exec and core files. \n\
+Arguments may be any combination of:\n\
+ [one or more section names]\n\
+ ALLOC LOAD RELOC READONLY CODE DATA ROM CONSTRUCTOR\n\
+ HAS_CONTENTS NEVER_LOAD COFF_SHARED_LIBRARY IS_COMMON\n\
+Sections matching any argument will be listed (no argument\n\
+implies all sections). In addition, the special argument\n\
+ ALLOBJ\n\
+lists all sections from all object files, including shared libraries.",
+ &maintenanceinfolist);
+
+ add_prefix_cmd ("print", class_maintenance, maintenance_print_command,
+ "Maintenance command for printing GDB internal state.",
+ &maintenanceprintlist, "maintenance print ", 0,
+ &maintenancelist);
+
+ add_prefix_cmd ("set", class_maintenance, maintenance_set_cmd, "\
+Set GDB internal variables used by the GDB maintainer.\n\
+Configure variables internal to GDB that aid in GDB's maintenance",
+ &maintenance_set_cmdlist, "maintenance set ",
+ 0/*allow-unknown*/,
+ &maintenancelist);
+
+ add_prefix_cmd ("show", class_maintenance, maintenance_show_cmd, "\
+Show GDB internal variables used by the GDB maintainer.\n\
+Configure variables internal to GDB that aid in GDB's maintenance",
+ &maintenance_show_cmdlist, "maintenance show ",
+ 0/*allow-unknown*/,
+ &maintenancelist);
+
+#ifndef _WIN32
+ add_cmd ("dump-me", class_maintenance, maintenance_dump_me,
+ "Get fatal error; make debugger dump its core.\n\
+GDB sets it's handling of SIGQUIT back to SIG_DFL and then sends\n\
+itself a SIGQUIT signal.",
+ &maintenancelist);
+#endif
+
+ add_cmd ("internal-error", class_maintenance, maintenance_internal_error,
+ "Give GDB an internal error.\n\
+Cause GDB to behave as if an internal error was detected.",
+ &maintenancelist);
+
+ add_cmd ("demangle", class_maintenance, maintenance_demangle,
+ "Demangle a C++ mangled name.\n\
+Call internal GDB demangler routine to demangle a C++ link name\n\
+and prints the result.",
+ &maintenancelist);
+
+ add_cmd ("time", class_maintenance, maintenance_time_display,
+ "Set the display of time usage.\n\
+If nonzero, will cause the execution time for each command to be\n\
+displayed, following the command's output.",
+ &maintenancelist);
+
+ add_cmd ("space", class_maintenance, maintenance_space_display,
+ "Set the display of space usage.\n\
+If nonzero, will cause the execution space for each command to be\n\
+displayed, following the command's output.",
+ &maintenancelist);
+
+ add_cmd ("type", class_maintenance, maintenance_print_type,
+ "Print a type chain for a given symbol.\n\
+For each node in a type chain, print the raw data for each member of\n\
+the type structure, and the interpretation of the data.",
+ &maintenanceprintlist);
+
+ add_cmd ("symbols", class_maintenance, maintenance_print_symbols,
+ "Print dump of current symbol definitions.\n\
+Entries in the full symbol table are dumped to file OUTFILE.\n\
+If a SOURCE file is specified, dump only that file's symbols.",
+ &maintenanceprintlist);
+
+ add_cmd ("msymbols", class_maintenance, maintenance_print_msymbols,
+ "Print dump of current minimal symbol definitions.\n\
+Entries in the minimal symbol table are dumped to file OUTFILE.\n\
+If a SOURCE file is specified, dump only that file's minimal symbols.",
+ &maintenanceprintlist);
+
+ add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols,
+ "Print dump of current partial symbol definitions.\n\
+Entries in the partial symbol table are dumped to file OUTFILE.\n\
+If a SOURCE file is specified, dump only that file's partial symbols.",
+ &maintenanceprintlist);
+
+ add_cmd ("objfiles", class_maintenance, maintenance_print_objfiles,
+ "Print dump of current object file definitions.",
+ &maintenanceprintlist);
+
+ add_cmd ("statistics", class_maintenance, maintenance_print_statistics,
+ "Print statistics about internal gdb state.",
+ &maintenanceprintlist);
+
+ add_cmd ("architecture", class_maintenance, maintenance_print_architecture,
+ "Print the internal architecture configuration.\
+Takes an optional file parameter.",
+ &maintenanceprintlist);
+
+ add_cmd ("check-symtabs", class_maintenance, maintenance_check_symtabs,
+ "Check consistency of psymtabs and symtabs.",
+ &maintenancelist);
+
+ add_cmd ("translate-address", class_maintenance, maintenance_translate_address,
+ "Translate a section name and address to a symbol.",
+ &maintenancelist);
+
+ add_cmd ("deprecate", class_maintenance, maintenance_deprecate,
+ "Deprecate a command. Note that this is just in here so the \n\
+testsuite can check the comamnd deprecator. You probably shouldn't use this,\n\
+rather you should use the C function deprecate_cmd(). If you decide you \n\
+want to use it: maintenance deprecate 'commandname' \"replacement\". The \n\
+replacement is optional.", &maintenancelist);
+
+ add_cmd ("undeprecate", class_maintenance, maintenance_undeprecate,
+ "Undeprecate a command. Note that this is just in here so the \n\
+testsuite can check the comamnd deprecator. You probably shouldn't use this,\n\
+If you decide you want to use it: maintenance undeprecate 'commandname'",
+ &maintenancelist);
+
+ add_show_from_set (
+ add_set_cmd ("watchdog", class_maintenance, var_zinteger, (char *) &watchdog,
+ "Set watchdog timer.\n\
+When non-zero, this timeout is used instead of waiting forever for a target to\n\
+finish a low-level step or continue operation. If the specified amount of time\n\
+passes without a response from the target, an error occurs.", &setlist),
+ &showlist);
+
+
+#ifdef NOTYET
+ /* FIXME: cagney/2001-09-24: A patch introducing a
+ add_set_boolean_cmd() is pending, the below should probably use
+ it. A patch implementing profiling is pending, this just sets up
+ the framework. */
+ tmpcmd = add_set_cmd ("profile", class_maintenance,
+ var_boolean, &maintenance_profile_p,
+ "Set internal profiling.\n\
+When enabled GDB is profiled.",
+ &maintenance_set_cmdlist);
+ set_cmd_sfunc (tmpcmd, maintenance_set_profile_cmd);
+ add_show_from_set (tmpcmd, &maintenance_show_cmdlist);
+#endif
+}
diff --git a/gdb/mcore-rom.c b/gdb/mcore-rom.c
new file mode 100644
index 00000000000..339c64096d6
--- /dev/null
+++ b/gdb/mcore-rom.c
@@ -0,0 +1,208 @@
+/* Remote debugging interface to Motorola picobug monitor for gdb,
+ the GNU debugger.
+ Copyright 1999, 2000, 2001 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "gdb_string.h"
+#include "regcache.h"
+#include "serial.h"
+
+/* Functions used only in this file. */
+
+static void init_picobug_cmds (void);
+
+
+/* Functions exported from this file. */
+
+void _initialize_picobug_rom (void);
+
+void picobug_open (char *args, int from_tty);
+
+int picobug_dumpregs (void);
+
+
+static char *picobug_inits[] =
+{"\r", NULL};
+
+static struct target_ops picobug_ops;
+static struct monitor_ops picobug_cmds;
+
+/* Picobug only supports a subset of registers from MCore. In reality,
+ it doesn't support ss1, either. */
+/* *INDENT-OFF* */
+static char *picobug_regnames[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ "psr", "vbr", "epsr", "fpsr", "epc", "fpc", 0, "ss1",
+ "ss2", "ss3", "ss4", 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ "pc" };
+/* *INDENT-ON* */
+
+
+
+void
+picobug_open (char *args, int from_tty)
+{
+ monitor_open (args, &picobug_cmds, from_tty);
+}
+/* *INDENT-OFF* */
+/* We choose to write our own dumpregs routine, since the output of
+ the register dumping is rather difficult to encapsulate in a
+ regexp:
+
+picobug> rd
+ pc 2f00031e epc 2f00031e fpc 00000000
+ psr 80000101 epsr 80000101 fpsr 00000000
+ss0-ss4 bad0beef 00000000 00000000 00000000 00000000 vbr 30005c00
+ r0-r7 2f0fff4c 00000090 00000001 00000002 00000003 00000004 00000005 00000006
+ r8-r15 2f0fff64 00000000 00000000 00000000 00000000 00000000 00000000 2f00031e */
+/* *INDENT-ON* */
+
+
+
+int
+picobug_dumpregs (void)
+{
+ char buf[1024];
+ int resp_len;
+ char *p;
+
+ /* Send the dump register command to the monitor and
+ get the reply. */
+ monitor_printf (picobug_cmds.dump_registers);
+ resp_len = monitor_expect_prompt (buf, sizeof (buf));
+
+ p = strtok (buf, " \t\r\n");
+ while (p)
+ {
+ if (strchr (p, '-'))
+ {
+ /* got a range. either r0-r7, r8-r15 or ss0-ss4 */
+ if (STREQN (p, "r0", 2) || STREQN (p, "r8", 2))
+ {
+ int rn = (p[1] == '0' ? 0 : 8);
+ int i = 0;
+
+ /* Get the next 8 values and record them. */
+ while (i < 8)
+ {
+ p = strtok (NULL, " \t\r\n");
+ if (p)
+ monitor_supply_register (rn + i, p);
+ i++;
+ }
+ }
+ else if (STREQN (p, "ss", 2))
+ {
+ /* get the next five values, ignoring the first */
+ int rn;
+ p = strtok (NULL, " \t\r\n");
+ for (rn = 39; rn < 43; rn++)
+ {
+ p = strtok (NULL, " \t\r\n");
+ if (p)
+ monitor_supply_register (rn, p);
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ /* Simple register type, paired */
+ char *name = p;
+ int i;
+
+ /* Get and record value */
+ p = strtok (NULL, " \t\r\n");
+ if (p)
+ {
+ for (i = 0; i < NUM_REGS; i++)
+ {
+ if (picobug_regnames[i] && STREQ (picobug_regnames[i], name))
+ break;
+ }
+
+ if (i <= NUM_REGS)
+ monitor_supply_register (i, p);
+ }
+ }
+ p = strtok (NULL, " \t\r\n");
+ }
+
+ return 0;
+}
+
+static void
+init_picobug_cmds (void)
+{
+ picobug_cmds.flags = MO_GETMEM_NEEDS_RANGE | MO_CLR_BREAK_USES_ADDR | MO_PRINT_PROGRAM_OUTPUT;
+
+ picobug_cmds.init = picobug_inits; /* Init strings */
+ picobug_cmds.cont = "g\n"; /* continue command */
+ picobug_cmds.step = "s\n"; /* single step */
+ picobug_cmds.set_break = "br %x\n"; /* set a breakpoint */
+ picobug_cmds.clr_break = "nobr %x\n"; /* clear a breakpoint */
+ picobug_cmds.clr_all_break = "nobr\n"; /* clear all breakpoints */
+ picobug_cmds.setmem.cmdb = "mm %x %x ;b\n"; /* setmem.cmdb (addr, value) */
+ picobug_cmds.setmem.cmdw = "mm %x %x ;h\n"; /* setmem.cmdw (addr, value) */
+ picobug_cmds.setmem.cmdl = "mm %x %x ;w\n"; /* setmem.cmdl (addr, value) */
+ picobug_cmds.getmem.cmdb = "md %x %x\n"; /* getmem.cmdb (start addr, end addr) */
+ picobug_cmds.getmem.resp_delim = ":"; /* getmem.resp_delim */
+ picobug_cmds.setreg.cmd = "rm %s %x\n"; /* setreg.cmd (name, value) */
+ picobug_cmds.getreg.cmd = "rd %s\n"; /* getreg.cmd (name) */
+ picobug_cmds.getreg.resp_delim = ":"; /* getreg.resp_delim */
+ picobug_cmds.dump_registers = "rd\n"; /* dump_registers */
+ picobug_cmds.dumpregs = picobug_dumpregs; /* dump registers parser */
+ picobug_cmds.load = "lo\n"; /* download command */
+ picobug_cmds.prompt = "picobug> "; /* monitor command prompt */
+ picobug_cmds.line_term = "\n"; /* end-of-line terminator */
+ picobug_cmds.target = &picobug_ops; /* target operations */
+ picobug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ picobug_cmds.regnames = picobug_regnames; /* registers names */
+ picobug_cmds.num_breakpoints = 20; /* number of breakpoints */
+ picobug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+}
+
+void
+_initialize_picobug_rom (void)
+{
+ int i;
+
+ /* Initialize m32r RevC monitor target */
+ init_picobug_cmds ();
+ init_monitor_ops (&picobug_ops);
+ picobug_ops.to_shortname = "picobug";
+ picobug_ops.to_longname = "picobug monitor";
+ picobug_ops.to_doc = "Debug via the picobug monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ picobug_ops.to_open = picobug_open;
+
+ add_target (&picobug_ops);
+}
diff --git a/gdb/mcore-tdep.c b/gdb/mcore-tdep.c
new file mode 100644
index 00000000000..0e6ffc80a68
--- /dev/null
+++ b/gdb/mcore-tdep.c
@@ -0,0 +1,996 @@
+/* Target-machine dependent code for Motorola MCore for GDB, the GNU debugger
+ Copyright 1999, 2000, 2001 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 "defs.h"
+#include "frame.h"
+#include "symtab.h"
+#include "value.h"
+#include "gdbcmd.h"
+#include "regcache.h"
+#include "symfile.h"
+#include "gdbcore.h"
+#include "inferior.h"
+
+/* Functions declared and used only in this file */
+
+static CORE_ADDR mcore_analyze_prologue (struct frame_info *fi, CORE_ADDR pc, int skip_prologue);
+
+static struct frame_info *analyze_dummy_frame (CORE_ADDR pc, CORE_ADDR frame);
+
+static int get_insn (CORE_ADDR pc);
+
+/* Functions exported from this file */
+
+int mcore_use_struct_convention (int gcc_p, struct type *type);
+
+void _initialize_mcore (void);
+
+void mcore_init_extra_frame_info (struct frame_info *fi);
+
+CORE_ADDR mcore_frame_saved_pc (struct frame_info *fi);
+
+CORE_ADDR mcore_find_callers_reg (struct frame_info *fi, int regnum);
+
+CORE_ADDR mcore_frame_args_address (struct frame_info *fi);
+
+CORE_ADDR mcore_frame_locals_address (struct frame_info *fi);
+
+CORE_ADDR mcore_push_return_address (CORE_ADDR pc, CORE_ADDR sp);
+
+CORE_ADDR mcore_push_arguments (int nargs, struct value ** args, CORE_ADDR sp,
+ unsigned char struct_return, CORE_ADDR struct_addr);
+
+void mcore_pop_frame (struct frame_info *fi);
+
+CORE_ADDR mcore_skip_prologue (CORE_ADDR pc);
+
+CORE_ADDR mcore_frame_chain (struct frame_info *fi);
+
+const unsigned char *mcore_breakpoint_from_pc (CORE_ADDR * bp_addr, int *bp_size);
+
+int mcore_use_struct_convention (int gcc_p, struct type *type);
+
+void mcore_store_return_value (struct type *type, char *valbuf);
+
+CORE_ADDR mcore_extract_struct_value_address (char *regbuf);
+
+void mcore_extract_return_value (struct type *type, char *regbuf, char *valbuf);
+
+#ifdef MCORE_DEBUG
+int mcore_debug = 0;
+#endif
+
+/* The registers of the Motorola MCore processors */
+/* *INDENT-OFF* */
+char *mcore_register_names[] =
+{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "ar0", "ar1", "ar2", "ar3", "ar4", "ar5", "ar6", "ar7",
+ "ar8", "ar9", "ar10", "ar11", "ar12", "ar13", "ar14", "ar15",
+ "psr", "vbr", "epsr", "fpsr", "epc", "fpc", "ss0", "ss1",
+ "ss2", "ss3", "ss4", "gcr", "gsr", "cr13", "cr14", "cr15",
+ "cr16", "cr17", "cr18", "cr19", "cr20", "cr21", "cr22", "cr23",
+ "cr24", "cr25", "cr26", "cr27", "cr28", "cr29", "cr30", "cr31",
+ "pc" };
+/* *INDENT-ON* */
+
+
+
+/* Additional info that we use for managing frames */
+struct frame_extra_info
+ {
+ /* A generic status word */
+ int status;
+
+ /* Size of this frame */
+ int framesize;
+
+ /* The register that is acting as a frame pointer, if
+ it is being used. This is undefined if status
+ does not contain the flag MY_FRAME_IN_FP. */
+ int fp_regnum;
+ };
+
+/* frame_extra_info status flags */
+
+/* The base of the current frame is actually in the stack pointer.
+ This happens when there is no frame pointer (MCore ABI does not
+ require a frame pointer) or when we're stopped in the prologue or
+ epilogue itself. In these cases, mcore_analyze_prologue will need
+ to update fi->frame before returning or analyzing the register
+ save instructions. */
+#define MY_FRAME_IN_SP 0x1
+
+/* The base of the current frame is in a frame pointer register.
+ This register is noted in frame_extra_info->fp_regnum.
+
+ Note that the existence of an FP might also indicate that the
+ function has called alloca. */
+#define MY_FRAME_IN_FP 0x2
+
+/* This flag is set to indicate that this frame is the top-most
+ frame. This tells frame chain not to bother trying to unwind
+ beyond this frame. */
+#define NO_MORE_FRAMES 0x4
+
+/* Instruction macros used for analyzing the prologue */
+#define IS_SUBI0(x) (((x) & 0xfe0f) == 0x2400) /* subi r0,oimm5 */
+#define IS_STM(x) (((x) & 0xfff0) == 0x0070) /* stm rf-r15,r0 */
+#define IS_STWx0(x) (((x) & 0xf00f) == 0x9000) /* stw rz,(r0,disp) */
+#define IS_STWxy(x) (((x) & 0xf000) == 0x9000) /* stw rx,(ry,disp) */
+#define IS_MOVx0(x) (((x) & 0xfff0) == 0x1200) /* mov rn,r0 */
+#define IS_LRW1(x) (((x) & 0xff00) == 0x7100) /* lrw r1,literal */
+#define IS_MOVI1(x) (((x) & 0xf80f) == 0x6001) /* movi r1,imm7 */
+#define IS_BGENI1(x) (((x) & 0xfe0f) == 0x3201) /* bgeni r1,imm5 */
+#define IS_BMASKI1(x) (((x) & 0xfe0f) == 0x2C01) /* bmaski r1,imm5 */
+#define IS_ADDI1(x) (((x) & 0xfe0f) == 0x2001) /* addi r1,oimm5 */
+#define IS_SUBI1(x) (((x) & 0xfe0f) == 0x2401) /* subi r1,oimm5 */
+#define IS_RSUBI1(x) (((x) & 0xfe0f) == 0x2801) /* rsubi r1,imm5 */
+#define IS_NOT1(x) (((x) & 0xffff) == 0x01f1) /* not r1 */
+#define IS_ROTLI1(x) (((x) & 0xfe0f) == 0x3801) /* rotli r1,imm5 */
+#define IS_BSETI1(x) (((x) & 0xfe0f) == 0x3401) /* bseti r1,imm5 */
+#define IS_BCLRI1(x) (((x) & 0xfe0f) == 0x3001) /* bclri r1,imm5 */
+#define IS_IXH1(x) (((x) & 0xffff) == 0x1d11) /* ixh r1,r1 */
+#define IS_IXW1(x) (((x) & 0xffff) == 0x1511) /* ixw r1,r1 */
+#define IS_SUB01(x) (((x) & 0xffff) == 0x0510) /* subu r0,r1 */
+#define IS_RTS(x) (((x) & 0xffff) == 0x00cf) /* jmp r15 */
+
+#define IS_R1_ADJUSTER(x) \
+ (IS_ADDI1(x) || IS_SUBI1(x) || IS_ROTLI1(x) || IS_BSETI1(x) \
+ || IS_BCLRI1(x) || IS_RSUBI1(x) || IS_NOT1(x) \
+ || IS_IXH1(x) || IS_IXW1(x))
+
+
+#ifdef MCORE_DEBUG
+static void
+mcore_dump_insn (char *commnt, CORE_ADDR pc, int insn)
+{
+ if (mcore_debug)
+ {
+ printf_filtered ("MCORE: %s %08x %08x ",
+ commnt, (unsigned int) pc, (unsigned int) insn);
+ TARGET_PRINT_INSN (pc, &tm_print_insn_info);
+ printf_filtered ("\n");
+ }
+}
+#define mcore_insn_debug(args) { if (mcore_debug) printf_filtered args; }
+#else /* !MCORE_DEBUG */
+#define mcore_dump_insn(a,b,c) {}
+#define mcore_insn_debug(args) {}
+#endif
+
+/* Given the address at which to insert a breakpoint (BP_ADDR),
+ what will that breakpoint be?
+
+ For MCore, we have a breakpoint instruction. Since all MCore
+ instructions are 16 bits, this is all we need, regardless of
+ address. bpkt = 0x0000 */
+
+const unsigned char *
+mcore_breakpoint_from_pc (CORE_ADDR * bp_addr, int *bp_size)
+{
+ static char breakpoint[] =
+ {0x00, 0x00};
+ *bp_size = 2;
+ return breakpoint;
+}
+
+/* Helper function for several routines below. This funtion simply
+ sets up a fake, aka dummy, frame (not a _call_ dummy frame) that
+ we can analyze with mcore_analyze_prologue. */
+
+static struct frame_info *
+analyze_dummy_frame (CORE_ADDR pc, CORE_ADDR frame)
+{
+ static struct frame_info *dummy = NULL;
+
+ if (dummy == NULL)
+ {
+ dummy = (struct frame_info *) xmalloc (sizeof (struct frame_info));
+ dummy->saved_regs = (CORE_ADDR *) xmalloc (SIZEOF_FRAME_SAVED_REGS);
+ dummy->extra_info =
+ (struct frame_extra_info *) xmalloc (sizeof (struct frame_extra_info));
+ }
+
+ dummy->next = NULL;
+ dummy->prev = NULL;
+ dummy->pc = pc;
+ dummy->frame = frame;
+ dummy->extra_info->status = 0;
+ dummy->extra_info->framesize = 0;
+ memset (dummy->saved_regs, '\000', SIZEOF_FRAME_SAVED_REGS);
+ mcore_analyze_prologue (dummy, 0, 0);
+ return dummy;
+}
+
+/* Function prologues on the Motorola MCore processors consist of:
+
+ - adjustments to the stack pointer (r1 used as scratch register)
+ - store word/multiples that use r0 as the base address
+ - making a copy of r0 into another register (a "frame" pointer)
+
+ Note that the MCore really doesn't have a real frame pointer.
+ Instead, the compiler may copy the SP into a register (usually
+ r8) to act as an arg pointer. For our target-dependent purposes,
+ the frame info's "frame" member will be the beginning of the
+ frame. The SP could, in fact, point below this.
+
+ The prologue ends when an instruction fails to meet either of
+ the first two criteria or when an FP is made. We make a special
+ exception for gcc. When compiling unoptimized code, gcc will
+ setup stack slots. We need to make sure that we skip the filling
+ of these stack slots as much as possible. This is only done
+ when SKIP_PROLOGUE is set, so that it does not mess up
+ backtraces. */
+
+/* Analyze the prologue of frame FI to determine where registers are saved,
+ the end of the prologue, etc. Return the address of the first line
+ of "real" code (i.e., the end of the prologue). */
+
+static CORE_ADDR
+mcore_analyze_prologue (struct frame_info *fi, CORE_ADDR pc, int skip_prologue)
+{
+ CORE_ADDR func_addr, func_end, addr, stop;
+ CORE_ADDR stack_size;
+ int insn, rn;
+ int status;
+ int fp_regnum = 0; /* dummy, valid when (flags & MY_FRAME_IN_FP) */
+ int flags;
+ int framesize;
+ int register_offsets[NUM_REGS];
+ char *name;
+
+ /* If provided, use the PC in the frame to look up the
+ start of this function. */
+ pc = (fi == NULL ? pc : fi->pc);
+
+ /* Find the start of this function. */
+ status = find_pc_partial_function (pc, &name, &func_addr, &func_end);
+
+ /* If the start of this function could not be found or if the debbuger
+ is stopped at the first instruction of the prologue, do nothing. */
+ if (status == 0)
+ return pc;
+
+ /* If the debugger is entry function, give up. */
+ if (func_addr == entry_point_address ())
+ {
+ if (fi != NULL)
+ fi->extra_info->status |= NO_MORE_FRAMES;
+ return pc;
+ }
+
+ /* At the start of a function, our frame is in the stack pointer. */
+ flags = MY_FRAME_IN_SP;
+
+ /* Start decoding the prologue. We start by checking two special cases:
+
+ 1. We're about to return
+ 2. We're at the first insn of the prologue.
+
+ If we're about to return, our frame has already been deallocated.
+ If we are stopped at the first instruction of a prologue,
+ then our frame has not yet been set up. */
+
+ /* Get the first insn from memory (all MCore instructions are 16 bits) */
+ mcore_insn_debug (("MCORE: starting prologue decoding\n"));
+ insn = get_insn (pc);
+ mcore_dump_insn ("got 1: ", pc, insn);
+
+ /* Check for return. */
+ if (fi != NULL && IS_RTS (insn))
+ {
+ mcore_insn_debug (("MCORE: got jmp r15"));
+ if (fi->next == NULL)
+ fi->frame = read_sp ();
+ return fi->pc;
+ }
+
+ /* Check for first insn of prologue */
+ if (fi != NULL && fi->pc == func_addr)
+ {
+ if (fi->next == NULL)
+ fi->frame = read_sp ();
+ return fi->pc;
+ }
+
+ /* Figure out where to stop scanning */
+ stop = (fi ? fi->pc : func_end);
+
+ /* Don't walk off the end of the function */
+ stop = (stop > func_end ? func_end : stop);
+
+ /* REGISTER_OFFSETS will contain offsets, from the top of the frame
+ (NOT the frame pointer), for the various saved registers or -1
+ if the register is not saved. */
+ for (rn = 0; rn < NUM_REGS; rn++)
+ register_offsets[rn] = -1;
+
+ /* Analyze the prologue. Things we determine from analyzing the
+ prologue include:
+ * the size of the frame
+ * where saved registers are located (and which are saved)
+ * FP used? */
+ mcore_insn_debug (("MCORE: Scanning prologue: func_addr=0x%x, stop=0x%x\n",
+ (unsigned int) func_addr, (unsigned int) stop));
+
+ framesize = 0;
+ for (addr = func_addr; addr < stop; addr += 2)
+ {
+ /* Get next insn */
+ insn = get_insn (addr);
+ mcore_dump_insn ("got 2: ", addr, insn);
+
+ if (IS_SUBI0 (insn))
+ {
+ int offset = 1 + ((insn >> 4) & 0x1f);
+ mcore_insn_debug (("MCORE: got subi r0,%d; continuing\n", offset));
+ framesize += offset;
+ continue;
+ }
+ else if (IS_STM (insn))
+ {
+ /* Spill register(s) */
+ int offset;
+ int start_register;
+
+ /* BIG WARNING! The MCore ABI does not restrict functions
+ to taking only one stack allocation. Therefore, when
+ we save a register, we record the offset of where it was
+ saved relative to the current framesize. This will
+ then give an offset from the SP upon entry to our
+ function. Remember, framesize is NOT constant until
+ we're done scanning the prologue. */
+ start_register = (insn & 0xf);
+ mcore_insn_debug (("MCORE: got stm r%d-r15,(r0)\n", start_register));
+
+ for (rn = start_register, offset = 0; rn <= 15; rn++, offset += 4)
+ {
+ register_offsets[rn] = framesize - offset;
+ mcore_insn_debug (("MCORE: r%d saved at 0x%x (offset %d)\n", rn,
+ register_offsets[rn], offset));
+ }
+ mcore_insn_debug (("MCORE: continuing\n"));
+ continue;
+ }
+ else if (IS_STWx0 (insn))
+ {
+ /* Spill register: see note for IS_STM above. */
+ int imm;
+
+ rn = (insn >> 8) & 0xf;
+ imm = (insn >> 4) & 0xf;
+ register_offsets[rn] = framesize - (imm << 2);
+ mcore_insn_debug (("MCORE: r%d saved at offset 0x%x\n", rn, register_offsets[rn]));
+ mcore_insn_debug (("MCORE: continuing\n"));
+ continue;
+ }
+ else if (IS_MOVx0 (insn))
+ {
+ /* We have a frame pointer, so this prologue is over. Note
+ the register which is acting as the frame pointer. */
+ flags |= MY_FRAME_IN_FP;
+ flags &= ~MY_FRAME_IN_SP;
+ fp_regnum = insn & 0xf;
+ mcore_insn_debug (("MCORE: Found a frame pointer: r%d\n", fp_regnum));
+
+ /* If we found an FP, we're at the end of the prologue. */
+ mcore_insn_debug (("MCORE: end of prologue\n"));
+ if (skip_prologue)
+ continue;
+
+ /* If we're decoding prologue, stop here. */
+ addr += 2;
+ break;
+ }
+ else if (IS_STWxy (insn) && (flags & MY_FRAME_IN_FP) && ((insn & 0xf) == fp_regnum))
+ {
+ /* Special case. Skip over stack slot allocs, too. */
+ mcore_insn_debug (("MCORE: push arg onto stack.\n"));
+ continue;
+ }
+ else if (IS_LRW1 (insn) || IS_MOVI1 (insn)
+ || IS_BGENI1 (insn) || IS_BMASKI1 (insn))
+ {
+ int adjust = 0;
+ int offset = 0;
+ int insn2;
+
+ mcore_insn_debug (("MCORE: looking at large frame\n"));
+ if (IS_LRW1 (insn))
+ {
+ adjust =
+ read_memory_integer ((addr + 2 + ((insn & 0xff) << 2)) & 0xfffffffc, 4);
+ }
+ else if (IS_MOVI1 (insn))
+ adjust = (insn >> 4) & 0x7f;
+ else if (IS_BGENI1 (insn))
+ adjust = 1 << ((insn >> 4) & 0x1f);
+ else /* IS_BMASKI (insn) */
+ adjust = (1 << (adjust >> 4) & 0x1f) - 1;
+
+ mcore_insn_debug (("MCORE: base framesize=0x%x\n", adjust));
+
+ /* May have zero or more insns which modify r1 */
+ mcore_insn_debug (("MCORE: looking for r1 adjusters...\n"));
+ offset = 2;
+ insn2 = get_insn (addr + offset);
+ while (IS_R1_ADJUSTER (insn2))
+ {
+ int imm;
+
+ imm = (insn2 >> 4) & 0x1f;
+ mcore_dump_insn ("got 3: ", addr + offset, insn);
+ if (IS_ADDI1 (insn2))
+ {
+ adjust += (imm + 1);
+ mcore_insn_debug (("MCORE: addi r1,%d\n", imm + 1));
+ }
+ else if (IS_SUBI1 (insn2))
+ {
+ adjust -= (imm + 1);
+ mcore_insn_debug (("MCORE: subi r1,%d\n", imm + 1));
+ }
+ else if (IS_RSUBI1 (insn2))
+ {
+ adjust = imm - adjust;
+ mcore_insn_debug (("MCORE: rsubi r1,%d\n", imm + 1));
+ }
+ else if (IS_NOT1 (insn2))
+ {
+ adjust = ~adjust;
+ mcore_insn_debug (("MCORE: not r1\n"));
+ }
+ else if (IS_ROTLI1 (insn2))
+ {
+ adjust <<= imm;
+ mcore_insn_debug (("MCORE: rotli r1,%d\n", imm + 1));
+ }
+ else if (IS_BSETI1 (insn2))
+ {
+ adjust |= (1 << imm);
+ mcore_insn_debug (("MCORE: bseti r1,%d\n", imm));
+ }
+ else if (IS_BCLRI1 (insn2))
+ {
+ adjust &= ~(1 << imm);
+ mcore_insn_debug (("MCORE: bclri r1,%d\n", imm));
+ }
+ else if (IS_IXH1 (insn2))
+ {
+ adjust *= 3;
+ mcore_insn_debug (("MCORE: ix.h r1,r1\n"));
+ }
+ else if (IS_IXW1 (insn2))
+ {
+ adjust *= 5;
+ mcore_insn_debug (("MCORE: ix.w r1,r1\n"));
+ }
+
+ offset += 2;
+ insn2 = get_insn (addr + offset);
+ };
+
+ mcore_insn_debug (("MCORE: done looking for r1 adjusters\n"));
+
+ /* If the next insn adjusts the stack pointer, we keep everything;
+ if not, we scrap it and we've found the end of the prologue. */
+ if (IS_SUB01 (insn2))
+ {
+ addr += offset;
+ framesize += adjust;
+ mcore_insn_debug (("MCORE: found stack adjustment of 0x%x bytes.\n", adjust));
+ mcore_insn_debug (("MCORE: skipping to new address 0x%x\n", addr));
+ mcore_insn_debug (("MCORE: continuing\n"));
+ continue;
+ }
+
+ /* None of these instructions are prologue, so don't touch
+ anything. */
+ mcore_insn_debug (("MCORE: no subu r1,r0, NOT altering framesize.\n"));
+ break;
+ }
+
+ /* This is not a prologue insn, so stop here. */
+ mcore_insn_debug (("MCORE: insn is not a prologue insn -- ending scan\n"));
+ break;
+ }
+
+ mcore_insn_debug (("MCORE: done analyzing prologue\n"));
+ mcore_insn_debug (("MCORE: prologue end = 0x%x\n", addr));
+
+ /* Save everything we have learned about this frame into FI. */
+ if (fi != NULL)
+ {
+ fi->extra_info->framesize = framesize;
+ fi->extra_info->fp_regnum = fp_regnum;
+ fi->extra_info->status = flags;
+
+ /* Fix the frame pointer. When gcc uses r8 as a frame pointer,
+ it is really an arg ptr. We adjust fi->frame to be a "real"
+ frame pointer. */
+ if (fi->next == NULL)
+ {
+ if (fi->extra_info->status & MY_FRAME_IN_SP)
+ fi->frame = read_sp () + framesize;
+ else
+ fi->frame = read_register (fp_regnum) + framesize;
+ }
+
+ /* Note where saved registers are stored. The offsets in REGISTER_OFFSETS
+ are computed relative to the top of the frame. */
+ for (rn = 0; rn < NUM_REGS; rn++)
+ {
+ if (register_offsets[rn] >= 0)
+ {
+ fi->saved_regs[rn] = fi->frame - register_offsets[rn];
+ mcore_insn_debug (("Saved register %s stored at 0x%08x, value=0x%08x\n",
+ mcore_register_names[rn], fi->saved_regs[rn],
+ read_memory_integer (fi->saved_regs[rn], 4)));
+ }
+ }
+ }
+
+ /* Return addr of first non-prologue insn. */
+ return addr;
+}
+
+/* Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame. */
+
+CORE_ADDR
+mcore_frame_chain (struct frame_info * fi)
+{
+ struct frame_info *dummy;
+ CORE_ADDR callers_addr;
+
+ /* Analyze the prologue of this function. */
+ if (fi->extra_info->status == 0)
+ mcore_analyze_prologue (fi, 0, 0);
+
+ /* If mcore_analyze_prologue set NO_MORE_FRAMES, quit now. */
+ if (fi->extra_info->status & NO_MORE_FRAMES)
+ return 0;
+
+ /* Now that we've analyzed our prologue, we can start to ask
+ for information about our caller. The easiest way to do
+ this is to analyze our caller's prologue.
+
+ If our caller has a frame pointer, then we need to find
+ the value of that register upon entry to our frame.
+ This value is either in fi->saved_regs[rn] if it's saved,
+ or it's still in a register.
+
+ If our caller does not have a frame pointer, then his frame base
+ is <our base> + -<caller's frame size>. */
+ dummy = analyze_dummy_frame (FRAME_SAVED_PC (fi), fi->frame);
+
+ if (dummy->extra_info->status & MY_FRAME_IN_FP)
+ {
+ int fp = dummy->extra_info->fp_regnum;
+
+ /* Our caller has a frame pointer. */
+ if (fi->saved_regs[fp] != 0)
+ {
+ /* The "FP" was saved on the stack. Don't forget to adjust
+ the "FP" with the framesize to get a real FP. */
+ callers_addr = read_memory_integer (fi->saved_regs[fp], REGISTER_SIZE)
+ + dummy->extra_info->framesize;
+ }
+ else
+ {
+ /* It's still in the register. Don't forget to adjust
+ the "FP" with the framesize to get a real FP. */
+ callers_addr = read_register (fp) + dummy->extra_info->framesize;
+ }
+ }
+ else
+ {
+ /* Our caller does not have a frame pointer. */
+ callers_addr = fi->frame + dummy->extra_info->framesize;
+ }
+
+ return callers_addr;
+}
+
+/* Skip the prologue of the function at PC. */
+
+CORE_ADDR
+mcore_skip_prologue (CORE_ADDR pc)
+{
+ CORE_ADDR func_addr, func_end;
+ struct symtab_and_line sal;
+
+ /* If we have line debugging information, then the end of the
+ prologue should be the first assembly instruction of the first
+ source line */
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ sal = find_pc_line (func_addr, 0);
+ if (sal.end && sal.end < func_end)
+ return sal.end;
+ }
+
+ return mcore_analyze_prologue (NULL, pc, 1);
+}
+
+/* Return the address at which function arguments are offset. */
+CORE_ADDR
+mcore_frame_args_address (struct frame_info * fi)
+{
+ return fi->frame - fi->extra_info->framesize;
+}
+
+CORE_ADDR
+mcore_frame_locals_address (struct frame_info * fi)
+{
+ return fi->frame - fi->extra_info->framesize;
+}
+
+/* Return the frame pointer in use at address PC. */
+
+void
+mcore_virtual_frame_pointer (CORE_ADDR pc, int *reg, LONGEST *offset)
+{
+ struct frame_info *dummy = analyze_dummy_frame (pc, 0);
+ if (dummy->extra_info->status & MY_FRAME_IN_SP)
+ {
+ *reg = SP_REGNUM;
+ *offset = 0;
+ }
+ else
+ {
+ *reg = dummy->extra_info->fp_regnum;
+ *offset = 0;
+ }
+}
+
+/* Find the value of register REGNUM in frame FI. */
+
+CORE_ADDR
+mcore_find_callers_reg (struct frame_info *fi, int regnum)
+{
+ for (; fi != NULL; fi = fi->next)
+ {
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, regnum);
+ else if (fi->saved_regs[regnum] != 0)
+ return read_memory_integer (fi->saved_regs[regnum],
+ REGISTER_SIZE);
+ }
+
+ return read_register (regnum);
+}
+
+/* Find the saved pc in frame FI. */
+
+CORE_ADDR
+mcore_frame_saved_pc (struct frame_info * fi)
+{
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
+ else
+ return mcore_find_callers_reg (fi, PR_REGNUM);
+}
+
+/* INFERIOR FUNCTION CALLS */
+
+/* This routine gets called when either the user uses the "return"
+ command, or the call dummy breakpoint gets hit. */
+
+void
+mcore_pop_frame (struct frame_info *fi)
+{
+ int rn;
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ generic_pop_dummy_frame ();
+ else
+ {
+ /* Write out the PC we saved. */
+ write_register (PC_REGNUM, FRAME_SAVED_PC (fi));
+
+ /* Restore any saved registers. */
+ for (rn = 0; rn < NUM_REGS; rn++)
+ {
+ if (fi->saved_regs[rn] != 0)
+ {
+ ULONGEST value;
+
+ value = read_memory_unsigned_integer (fi->saved_regs[rn],
+ REGISTER_SIZE);
+ write_register (rn, value);
+ }
+ }
+
+ /* Actually cut back the stack. */
+ write_register (SP_REGNUM, FRAME_FP (fi));
+ }
+
+ /* Finally, throw away any cached frame information. */
+ flush_cached_frames ();
+}
+
+/* Setup arguments and PR for a call to the target. First six arguments
+ go in FIRST_ARGREG -> LAST_ARGREG, subsequent args go on to the stack.
+
+ * Types with lengths greater than REGISTER_SIZE may not be split
+ between registers and the stack, and they must start in an even-numbered
+ register. Subsequent args will go onto the stack.
+
+ * Structs may be split between registers and stack, left-aligned.
+
+ * If the function returns a struct which will not fit into registers (it's
+ more than eight bytes), we must allocate for that, too. Gdb will tell
+ us where this buffer is (STRUCT_ADDR), and we simply place it into
+ FIRST_ARGREG, since the MCORE treats struct returns (of less than eight
+ bytes) as hidden first arguments. */
+
+CORE_ADDR
+mcore_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ unsigned char struct_return, CORE_ADDR struct_addr)
+{
+ int argreg;
+ int argnum;
+ struct stack_arg
+ {
+ int len;
+ char *val;
+ }
+ *stack_args;
+ int nstack_args = 0;
+
+ stack_args = (struct stack_arg *) alloca (nargs * sizeof (struct stack_arg));
+
+ argreg = FIRST_ARGREG;
+
+ /* Align the stack. This is mostly a nop, but not always. It will be needed
+ if we call a function which has argument overflow. */
+ sp &= ~3;
+
+ /* If this function returns a struct which does not fit in the
+ return registers, we must pass a buffer to the function
+ which it can use to save the return value. */
+ if (struct_return)
+ write_register (argreg++, struct_addr);
+
+ /* FIXME: what about unions? */
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ char *val = (char *) VALUE_CONTENTS (args[argnum]);
+ int len = TYPE_LENGTH (VALUE_TYPE (args[argnum]));
+ struct type *type = VALUE_TYPE (args[argnum]);
+ int olen;
+
+ mcore_insn_debug (("MCORE PUSH: argreg=%d; len=%d; %s\n",
+ argreg, len, TYPE_CODE (type) == TYPE_CODE_STRUCT ? "struct" : "not struct"));
+ /* Arguments larger than a register must start in an even
+ numbered register. */
+ olen = len;
+
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT && len > REGISTER_SIZE && argreg % 2)
+ {
+ mcore_insn_debug (("MCORE PUSH: %d > REGISTER_SIZE: and %s is not even\n",
+ len, mcore_register_names[argreg]));
+ argreg++;
+ }
+
+ if ((argreg <= LAST_ARGREG && len <= (LAST_ARGREG - argreg + 1) * REGISTER_SIZE)
+ || (TYPE_CODE (type) == TYPE_CODE_STRUCT))
+ {
+ /* Something that will fit entirely into registers (or a struct
+ which may be split between registers and stack). */
+ mcore_insn_debug (("MCORE PUSH: arg %d going into regs\n", argnum));
+
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT && olen < REGISTER_SIZE)
+ {
+ /* Small structs must be right aligned within the register,
+ the most significant bits are undefined. */
+ write_register (argreg, extract_unsigned_integer (val, len));
+ argreg++;
+ len = 0;
+ }
+
+ while (len > 0 && argreg <= LAST_ARGREG)
+ {
+ write_register (argreg, extract_unsigned_integer (val, REGISTER_SIZE));
+ argreg++;
+ val += REGISTER_SIZE;
+ len -= REGISTER_SIZE;
+ }
+
+ /* Any remainder for the stack is noted below... */
+ }
+ else if (TYPE_CODE (VALUE_TYPE (args[argnum])) != TYPE_CODE_STRUCT
+ && len > REGISTER_SIZE)
+ {
+ /* All subsequent args go onto the stack. */
+ mcore_insn_debug (("MCORE PUSH: does not fit into regs, going onto stack\n"));
+ argnum = LAST_ARGREG + 1;
+ }
+
+ if (len > 0)
+ {
+ /* Note that this must be saved onto the stack */
+ mcore_insn_debug (("MCORE PUSH: adding arg %d to stack\n", argnum));
+ stack_args[nstack_args].val = val;
+ stack_args[nstack_args].len = len;
+ nstack_args++;
+ }
+
+ }
+
+ /* We're done with registers and stack allocation. Now do the actual
+ stack pushes. */
+ while (nstack_args--)
+ {
+ sp -= stack_args[nstack_args].len;
+ write_memory (sp, stack_args[nstack_args].val, stack_args[nstack_args].len);
+ }
+
+ /* Return adjusted stack pointer. */
+ return sp;
+}
+
+/* Store the return address for the call dummy. For MCore, we've
+ opted to use generic call dummies, so we simply store the
+ CALL_DUMMY_ADDRESS into the PR register (r15). */
+
+CORE_ADDR
+mcore_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ write_register (PR_REGNUM, CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+/* Setting/getting return values from functions.
+
+ The Motorola MCore processors use r2/r3 to return anything
+ not larger than 32 bits. Everything else goes into a caller-
+ supplied buffer, which is passed in via a hidden first
+ argument.
+
+ For gdb, this leaves us two routes, based on what
+ USE_STRUCT_CONVENTION (mcore_use_struct_convention) returns.
+ If this macro returns 1, gdb will call STORE_STRUCT_RETURN and
+ EXTRACT_STRUCT_VALUE_ADDRESS.
+
+ If USE_STRUCT_CONVENTION retruns 0, then gdb uses STORE_RETURN_VALUE
+ and EXTRACT_RETURN_VALUE to store/fetch the functions return value. */
+
+/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of
+ EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc
+ and TYPE is the type (which is known to be struct, union or array). */
+
+int
+mcore_use_struct_convention (int gcc_p, struct type *type)
+{
+ return (TYPE_LENGTH (type) > 8);
+}
+
+/* Where is the return value saved? For MCore, a pointer to
+ this buffer was passed as a hidden first argument, so
+ just return that address. */
+
+CORE_ADDR
+mcore_extract_struct_value_address (char *regbuf)
+{
+ return extract_address (regbuf + REGISTER_BYTE (FIRST_ARGREG), REGISTER_SIZE);
+}
+
+/* Given a function which returns a value of type TYPE, extract the
+ the function's return value and place the result into VALBUF.
+ REGBUF is the register contents of the target. */
+
+void
+mcore_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ /* Copy the return value (starting) in RETVAL_REGNUM to VALBUF. */
+ /* Only getting the first byte! if len = 1, we need the last byte of
+ the register, not the first. */
+ memcpy (valbuf, regbuf + REGISTER_BYTE (RETVAL_REGNUM) +
+ (TYPE_LENGTH (type) < 4 ? 4 - TYPE_LENGTH (type) : 0), TYPE_LENGTH (type));
+}
+
+/* Store the return value in VALBUF (of type TYPE) where the caller
+ expects to see it.
+
+ Values less than 32 bits are stored in r2, right justified and
+ sign or zero extended.
+
+ Values between 32 and 64 bits are stored in r2 (most
+ significant word) and r3 (least significant word, left justified).
+ Note that this includes structures of less than eight bytes, too. */
+
+void
+mcore_store_return_value (struct type *type, char *valbuf)
+{
+ int value_size;
+ int return_size;
+ int offset;
+ char *zeros;
+
+ value_size = TYPE_LENGTH (type);
+
+ /* Return value fits into registers. */
+ return_size = (value_size + REGISTER_SIZE - 1) & ~(REGISTER_SIZE - 1);
+ offset = REGISTER_BYTE (RETVAL_REGNUM) + (return_size - value_size);
+ zeros = alloca (return_size);
+ memset (zeros, 0, return_size);
+
+ write_register_bytes (REGISTER_BYTE (RETVAL_REGNUM), zeros, return_size);
+ write_register_bytes (offset, valbuf, value_size);
+}
+
+/* Initialize our target-dependent "stuff" for this newly created frame.
+
+ This includes allocating space for saved registers and analyzing
+ the prologue of this frame. */
+
+void
+mcore_init_extra_frame_info (struct frame_info *fi)
+{
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ frame_saved_regs_zalloc (fi);
+
+ fi->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+ fi->extra_info->status = 0;
+ fi->extra_info->framesize = 0;
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ /* We need to setup fi->frame here because run_stack_dummy gets it wrong
+ by assuming it's always FP. */
+ fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
+ }
+ else
+ mcore_analyze_prologue (fi, 0, 0);
+}
+
+/* Get an insturction from memory. */
+
+static int
+get_insn (CORE_ADDR pc)
+{
+ char buf[4];
+ int status = read_memory_nobpt (pc, buf, 2);
+ if (status != 0)
+ return 0;
+
+ return extract_unsigned_integer (buf, 2);
+}
+
+void
+_initialize_mcore_tdep (void)
+{
+ extern int print_insn_mcore (bfd_vma, disassemble_info *);
+ tm_print_insn = print_insn_mcore;
+
+#ifdef MCORE_DEBUG
+ add_show_from_set (add_set_cmd ("mcoredebug", no_class,
+ var_boolean, (char *) &mcore_debug,
+ "Set mcore debugging.\n", &setlist),
+ &showlist);
+#endif
+}
diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
new file mode 100644
index 00000000000..14d2c0f753e
--- /dev/null
+++ b/gdb/mdebugread.c
@@ -0,0 +1,5036 @@
+/* Read a symbol table in ECOFF format (Third-Eye).
+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ Original version contributed by Alessandro Forin (af@cs.cmu.edu) at
+ CMU. Major work by Per Bothner, John Gilmore and Ian Lance Taylor
+ at 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 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. */
+
+/* This module provides the function mdebug_build_psymtabs. It reads
+ ECOFF debugging information into partial symbol tables. The
+ debugging information is read from two structures. A struct
+ ecoff_debug_swap includes the sizes of each ECOFF structure and
+ swapping routines; these are fixed for a particular target. A
+ struct ecoff_debug_info points to the debugging information for a
+ particular object file.
+
+ ECOFF symbol tables are mostly written in the byte order of the
+ target machine. However, one section of the table (the auxiliary
+ symbol information) is written in the host byte order. There is a
+ bit in the other symbol info which describes which host byte order
+ was used. ECOFF thereby takes the trophy from Intel `b.out' for
+ the most brain-dead adaptation of a file format to byte order.
+
+ This module can read all four of the known byte-order combinations,
+ on any type of host. */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "obstack.h"
+#include "buildsym.h"
+#include "stabsread.h"
+#include "complaints.h"
+#include "demangle.h"
+
+/* These are needed if the tm.h file does not contain the necessary
+ mips specific definitions. */
+
+#ifndef MIPS_EFI_SYMBOL_NAME
+#define MIPS_EFI_SYMBOL_NAME "__GDB_EFI_INFO__"
+extern void ecoff_relocate_efi (struct symbol *, CORE_ADDR);
+#include "coff/sym.h"
+#include "coff/symconst.h"
+typedef struct mips_extra_func_info
+ {
+ long numargs;
+ PDR pdr;
+ }
+ *mips_extra_func_info_t;
+#ifndef RA_REGNUM
+#define RA_REGNUM 0
+#endif
+#endif
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include "gdb_stat.h"
+#include "gdb_string.h"
+
+#include "bfd.h"
+
+#include "coff/ecoff.h" /* COFF-like aspects of ecoff files */
+
+#include "libaout.h" /* Private BFD a.out information. */
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h" /* STABS information */
+
+#include "expression.h"
+#include "language.h" /* For local_hex_string() */
+
+extern void _initialize_mdebugread (void);
+
+/* Provide a way to test if we have both ECOFF and ELF symbol tables.
+ We use this define in order to know whether we should override a
+ symbol's ECOFF section with its ELF section. This is necessary in
+ case the symbol's ELF section could not be represented in ECOFF. */
+#define ECOFF_IN_ELF(bfd) (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && bfd_get_section_by_name (bfd, ".mdebug") != NULL)
+
+
+/* We put a pointer to this structure in the read_symtab_private field
+ of the psymtab. */
+
+struct symloc
+ {
+ /* Our running best guess as to the range of text addresses for
+ this psymtab. After we've read everything in, we use this to
+ build pst->text_addrs. */
+ CORE_ADDR textlow, texthigh;
+
+ /* Index of the FDR that this psymtab represents. */
+ int fdr_idx;
+ /* The BFD that the psymtab was created from. */
+ bfd *cur_bfd;
+ const struct ecoff_debug_swap *debug_swap;
+ struct ecoff_debug_info *debug_info;
+ struct mdebug_pending **pending_list;
+ /* Pointer to external symbols for this file. */
+ EXTR *extern_tab;
+ /* Size of extern_tab. */
+ int extern_count;
+ enum language pst_language;
+ };
+
+#define PST_PRIVATE(p) ((struct symloc *)(p)->read_symtab_private)
+#define TEXTLOW(p) (PST_PRIVATE(p)->textlow)
+#define TEXTHIGH(p) (PST_PRIVATE(p)->texthigh)
+#define FDR_IDX(p) (PST_PRIVATE(p)->fdr_idx)
+#define CUR_BFD(p) (PST_PRIVATE(p)->cur_bfd)
+#define DEBUG_SWAP(p) (PST_PRIVATE(p)->debug_swap)
+#define DEBUG_INFO(p) (PST_PRIVATE(p)->debug_info)
+#define PENDING_LIST(p) (PST_PRIVATE(p)->pending_list)
+
+#define SC_IS_TEXT(sc) ((sc) == scText \
+ || (sc) == scRConst \
+ || (sc) == scInit \
+ || (sc) == scFini)
+#define SC_IS_DATA(sc) ((sc) == scData \
+ || (sc) == scSData \
+ || (sc) == scRData \
+ || (sc) == scPData \
+ || (sc) == scXData)
+#define SC_IS_COMMON(sc) ((sc) == scCommon || (sc) == scSCommon)
+#define SC_IS_BSS(sc) ((sc) == scBss)
+#define SC_IS_SBSS(sc) ((sc) == scSBss)
+#define SC_IS_UNDEF(sc) ((sc) == scUndefined || (sc) == scSUndefined)
+
+/* Various complaints about symbol reading that don't abort the process */
+
+static struct complaint bad_file_number_complaint =
+{"bad file number %d", 0, 0};
+
+static struct complaint index_complaint =
+{"bad aux index at symbol %s", 0, 0};
+
+static struct complaint aux_index_complaint =
+{"bad proc end in aux found from symbol %s", 0, 0};
+
+static struct complaint block_index_complaint =
+{"bad aux index at block symbol %s", 0, 0};
+
+static struct complaint unknown_ext_complaint =
+{"unknown external symbol %s", 0, 0};
+
+static struct complaint unknown_sym_complaint =
+{"unknown local symbol %s", 0, 0};
+
+static struct complaint unknown_st_complaint =
+{"with type %d", 0, 0};
+
+static struct complaint block_overflow_complaint =
+{"block containing %s overfilled", 0, 0};
+
+static struct complaint basic_type_complaint =
+{"cannot map ECOFF basic type 0x%x for %s", 0, 0};
+
+static struct complaint unknown_type_qual_complaint =
+{"unknown type qualifier 0x%x", 0, 0};
+
+static struct complaint array_index_type_complaint =
+{"illegal array index type for %s, assuming int", 0, 0};
+
+static struct complaint bad_tag_guess_complaint =
+{"guessed tag type of %s incorrectly", 0, 0};
+
+static struct complaint block_member_complaint =
+{"declaration block contains unhandled symbol type %d", 0, 0};
+
+static struct complaint stEnd_complaint =
+{"stEnd with storage class %d not handled", 0, 0};
+
+static struct complaint unknown_mdebug_symtype_complaint =
+{"unknown symbol type 0x%x", 0, 0};
+
+static struct complaint stab_unknown_complaint =
+{"unknown stabs symbol %s", 0, 0};
+
+static struct complaint pdr_for_nonsymbol_complaint =
+{"PDR for %s, but no symbol", 0, 0};
+
+static struct complaint pdr_static_symbol_complaint =
+{"can't handle PDR for static proc at 0x%lx", 0, 0};
+
+static struct complaint bad_setjmp_pdr_complaint =
+{"fixing bad setjmp PDR from libc", 0, 0};
+
+static struct complaint bad_fbitfield_complaint =
+{"can't handle TIR fBitfield for %s", 0, 0};
+
+static struct complaint bad_continued_complaint =
+{"illegal TIR continued for %s", 0, 0};
+
+static struct complaint bad_rfd_entry_complaint =
+{"bad rfd entry for %s: file %d, index %d", 0, 0};
+
+static struct complaint unexpected_type_code_complaint =
+{"unexpected type code for %s", 0, 0};
+
+static struct complaint unable_to_cross_ref_complaint =
+{"unable to cross ref btTypedef for %s", 0, 0};
+
+static struct complaint bad_indirect_xref_complaint =
+{"unable to cross ref btIndirect for %s", 0, 0};
+
+static struct complaint illegal_forward_tq0_complaint =
+{"illegal tq0 in forward typedef for %s", 0, 0};
+
+static struct complaint illegal_forward_bt_complaint =
+{"illegal bt %d in forward typedef for %s", 0, 0};
+
+static struct complaint bad_linetable_guess_complaint =
+{"guessed size of linetable for %s incorrectly", 0, 0};
+
+static struct complaint bad_ext_ifd_complaint =
+{"bad ifd for external symbol: %d (max %d)", 0, 0};
+
+static struct complaint bad_ext_iss_complaint =
+{"bad iss for external symbol: %ld (max %ld)", 0, 0};
+
+/* Macros and extra defs */
+
+/* Puns: hard to find whether -g was used and how */
+
+#define MIN_GLEVEL GLEVEL_0
+#define compare_glevel(a,b) \
+ (((a) == GLEVEL_3) ? ((b) < GLEVEL_3) : \
+ ((b) == GLEVEL_3) ? -1 : (int)((b) - (a)))
+
+/* Things that really are local to this module */
+
+/* Remember what we deduced to be the source language of this psymtab. */
+
+static enum language psymtab_language = language_unknown;
+
+/* Current BFD. */
+
+static bfd *cur_bfd;
+
+/* How to parse debugging information for CUR_BFD. */
+
+static const struct ecoff_debug_swap *debug_swap;
+
+/* Pointers to debugging information for CUR_BFD. */
+
+static struct ecoff_debug_info *debug_info;
+
+/* Pointer to current file decriptor record, and its index */
+
+static FDR *cur_fdr;
+static int cur_fd;
+
+/* Index of current symbol */
+
+static int cur_sdx;
+
+/* Note how much "debuggable" this image is. We would like
+ to see at least one FDR with full symbols */
+
+static int max_gdbinfo;
+static int max_glevel;
+
+/* When examining .o files, report on undefined symbols */
+
+static int n_undef_symbols, n_undef_labels, n_undef_vars, n_undef_procs;
+
+/* Pseudo symbol to use when putting stabs into the symbol table. */
+
+static char stabs_symbol[] = STABS_SYMBOL;
+
+/* Types corresponding to mdebug format bt* basic types. */
+
+static struct type *mdebug_type_void;
+static struct type *mdebug_type_char;
+static struct type *mdebug_type_short;
+static struct type *mdebug_type_int_32;
+#define mdebug_type_int mdebug_type_int_32
+static struct type *mdebug_type_int_64;
+static struct type *mdebug_type_long_32;
+static struct type *mdebug_type_long_64;
+static struct type *mdebug_type_long_long_64;
+static struct type *mdebug_type_unsigned_char;
+static struct type *mdebug_type_unsigned_short;
+static struct type *mdebug_type_unsigned_int_32;
+static struct type *mdebug_type_unsigned_int_64;
+static struct type *mdebug_type_unsigned_long_32;
+static struct type *mdebug_type_unsigned_long_64;
+static struct type *mdebug_type_unsigned_long_long_64;
+static struct type *mdebug_type_adr_32;
+static struct type *mdebug_type_adr_64;
+static struct type *mdebug_type_float;
+static struct type *mdebug_type_double;
+static struct type *mdebug_type_complex;
+static struct type *mdebug_type_double_complex;
+static struct type *mdebug_type_fixed_dec;
+static struct type *mdebug_type_float_dec;
+static struct type *mdebug_type_string;
+
+/* Types for symbols from files compiled without debugging info. */
+
+static struct type *nodebug_func_symbol_type;
+static struct type *nodebug_var_symbol_type;
+
+/* Nonzero if we have seen ecoff debugging info for a file. */
+
+static int found_ecoff_debugging_info;
+
+/* Forward declarations */
+
+static int upgrade_type (int, struct type **, int, union aux_ext *,
+ int, char *);
+
+static void parse_partial_symbols (struct objfile *);
+
+static int has_opaque_xref (FDR *, SYMR *);
+
+static int cross_ref (int, union aux_ext *, struct type **, enum type_code,
+ char **, int, char *);
+
+static struct symbol *new_symbol (char *);
+
+static struct type *new_type (char *);
+
+static struct block *new_block (int);
+
+static struct symtab *new_symtab (char *, int, int, struct objfile *);
+
+static struct linetable *new_linetable (int);
+
+static struct blockvector *new_bvect (int);
+
+static struct type *parse_type (int, union aux_ext *, unsigned int, int *,
+ int, char *);
+
+static struct symbol *mylookup_symbol (char *, struct block *, namespace_enum,
+ enum address_class);
+
+static struct block *shrink_block (struct block *, struct symtab *);
+
+static void sort_blocks (struct symtab *);
+
+static struct partial_symtab *new_psymtab (char *, struct objfile *);
+
+static void psymtab_to_symtab_1 (struct partial_symtab *, char *);
+
+static void add_block (struct block *, struct symtab *);
+
+static void add_symbol (struct symbol *, struct block *);
+
+static int add_line (struct linetable *, int, CORE_ADDR, int);
+
+static struct linetable *shrink_linetable (struct linetable *);
+
+static void handle_psymbol_enumerators (struct objfile *, FDR *, int,
+ CORE_ADDR);
+
+static char *mdebug_next_symbol_text (struct objfile *);
+
+/* Address bounds for the signal trampoline in inferior, if any */
+
+CORE_ADDR sigtramp_address, sigtramp_end;
+
+/* Allocate zeroed memory */
+
+static void *
+xzalloc (unsigned int size)
+{
+ void *p = xmalloc (size);
+
+ memset (p, 0, size);
+ return p;
+}
+
+/* Exported procedure: Builds a symtab from the PST partial one.
+ Restores the environment in effect when PST was created, delegates
+ most of the work to an ancillary procedure, and sorts
+ and reorders the symtab list at the end */
+
+static void
+mdebug_psymtab_to_symtab (struct partial_symtab *pst)
+{
+
+ if (!pst)
+ return;
+
+ if (info_verbose)
+ {
+ printf_filtered ("Reading in symbols for %s...", pst->filename);
+ gdb_flush (gdb_stdout);
+ }
+
+ next_symbol_text_func = mdebug_next_symbol_text;
+
+ psymtab_to_symtab_1 (pst, pst->filename);
+
+ /* Match with global symbols. This only needs to be done once,
+ after all of the symtabs and dependencies have been read in. */
+ scan_file_globals (pst->objfile);
+
+ if (info_verbose)
+ printf_filtered ("done.\n");
+}
+
+/* File-level interface functions */
+
+/* Find a file descriptor given its index RF relative to a file CF */
+
+static FDR *
+get_rfd (int cf, int rf)
+{
+ FDR *fdrs;
+ register FDR *f;
+ RFDT rfd;
+
+ fdrs = debug_info->fdr;
+ f = fdrs + cf;
+ /* Object files do not have the RFD table, all refs are absolute */
+ if (f->rfdBase == 0)
+ return fdrs + rf;
+ (*debug_swap->swap_rfd_in) (cur_bfd,
+ ((char *) debug_info->external_rfd
+ + ((f->rfdBase + rf)
+ * debug_swap->external_rfd_size)),
+ &rfd);
+ return fdrs + rfd;
+}
+
+/* Return a safer print NAME for a file descriptor */
+
+static char *
+fdr_name (FDR *f)
+{
+ if (f->rss == -1)
+ return "<stripped file>";
+ if (f->rss == 0)
+ return "<NFY>";
+ return debug_info->ss + f->issBase + f->rss;
+}
+
+
+/* Read in and parse the symtab of the file OBJFILE. Symbols from
+ different sections are relocated via the SECTION_OFFSETS. */
+
+void
+mdebug_build_psymtabs (struct objfile *objfile,
+ const struct ecoff_debug_swap *swap,
+ struct ecoff_debug_info *info)
+{
+ cur_bfd = objfile->obfd;
+ debug_swap = swap;
+ debug_info = info;
+
+ stabsread_new_init ();
+ buildsym_new_init ();
+ free_header_files ();
+ init_header_files ();
+
+ /* Make sure all the FDR information is swapped in. */
+ if (info->fdr == (FDR *) NULL)
+ {
+ char *fdr_src;
+ char *fdr_end;
+ FDR *fdr_ptr;
+
+ info->fdr = (FDR *) obstack_alloc (&objfile->psymbol_obstack,
+ (info->symbolic_header.ifdMax
+ * sizeof (FDR)));
+ fdr_src = info->external_fdr;
+ fdr_end = (fdr_src
+ + info->symbolic_header.ifdMax * swap->external_fdr_size);
+ fdr_ptr = info->fdr;
+ for (; fdr_src < fdr_end; fdr_src += swap->external_fdr_size, fdr_ptr++)
+ (*swap->swap_fdr_in) (objfile->obfd, fdr_src, fdr_ptr);
+ }
+
+ parse_partial_symbols (objfile);
+
+ /* Take the text ranges the partial symbol scanner computed for each
+ of the psymtabs and convert it into the canonical form for
+ psymtabs. */
+ {
+ struct partial_symtab *p;
+
+ ALL_OBJFILE_PSYMTABS (objfile, p)
+ {
+ p->textlow = TEXTLOW (p);
+ p->texthigh = TEXTHIGH (p);
+ }
+ }
+
+#if 0
+ /* Check to make sure file was compiled with -g. If not, warn the
+ user of this limitation. */
+ if (compare_glevel (max_glevel, GLEVEL_2) < 0)
+ {
+ if (max_gdbinfo == 0)
+ printf_unfiltered ("\n%s not compiled with -g, debugging support is limited.\n",
+ objfile->name);
+ printf_unfiltered ("You should compile with -g2 or -g3 for best debugging support.\n");
+ gdb_flush (gdb_stdout);
+ }
+#endif
+}
+
+/* Local utilities */
+
+/* Map of FDR indexes to partial symtabs */
+
+struct pst_map
+{
+ struct partial_symtab *pst; /* the psymtab proper */
+ long n_globals; /* exported globals (external symbols) */
+ long globals_offset; /* cumulative */
+};
+
+
+/* Utility stack, used to nest procedures and blocks properly.
+ It is a doubly linked list, to avoid too many alloc/free.
+ Since we might need it quite a few times it is NOT deallocated
+ after use. */
+
+static struct parse_stack
+ {
+ struct parse_stack *next, *prev;
+ struct symtab *cur_st; /* Current symtab. */
+ struct block *cur_block; /* Block in it. */
+
+ /* What are we parsing. stFile, or stBlock are for files and
+ blocks. stProc or stStaticProc means we have seen the start of a
+ procedure, but not the start of the block within in. When we see
+ the start of that block, we change it to stNil, without pushing a
+ new block, i.e. stNil means both a procedure and a block. */
+
+ int blocktype;
+
+ int maxsyms; /* Max symbols in this block. */
+ struct type *cur_type; /* Type we parse fields for. */
+ int cur_field; /* Field number in cur_type. */
+ CORE_ADDR procadr; /* Start addres of this procedure */
+ int numargs; /* Its argument count */
+ }
+
+ *top_stack; /* Top stack ptr */
+
+
+/* Enter a new lexical context */
+
+static void
+push_parse_stack (void)
+{
+ struct parse_stack *new;
+
+ /* Reuse frames if possible */
+ if (top_stack && top_stack->prev)
+ new = top_stack->prev;
+ else
+ new = (struct parse_stack *) xzalloc (sizeof (struct parse_stack));
+ /* Initialize new frame with previous content */
+ if (top_stack)
+ {
+ register struct parse_stack *prev = new->prev;
+
+ *new = *top_stack;
+ top_stack->prev = new;
+ new->prev = prev;
+ new->next = top_stack;
+ }
+ top_stack = new;
+}
+
+/* Exit a lexical context */
+
+static void
+pop_parse_stack (void)
+{
+ if (!top_stack)
+ return;
+ if (top_stack->next)
+ top_stack = top_stack->next;
+}
+
+
+/* Cross-references might be to things we haven't looked at
+ yet, e.g. type references. To avoid too many type
+ duplications we keep a quick fixup table, an array
+ of lists of references indexed by file descriptor */
+
+struct mdebug_pending
+{
+ struct mdebug_pending *next; /* link */
+ char *s; /* the unswapped symbol */
+ struct type *t; /* its partial type descriptor */
+};
+
+
+/* The pending information is kept for an entire object file, and used
+ to be in the sym_private field. I took it out when I split
+ mdebugread from mipsread, because this might not be the only type
+ of symbols read from an object file. Instead, we allocate the
+ pending information table when we create the partial symbols, and
+ we store a pointer to the single table in each psymtab. */
+
+static struct mdebug_pending **pending_list;
+
+/* Check whether we already saw symbol SH in file FH */
+
+static struct mdebug_pending *
+is_pending_symbol (FDR *fh, char *sh)
+{
+ int f_idx = fh - debug_info->fdr;
+ register struct mdebug_pending *p;
+
+ /* Linear search is ok, list is typically no more than 10 deep */
+ for (p = pending_list[f_idx]; p; p = p->next)
+ if (p->s == sh)
+ break;
+ return p;
+}
+
+/* Add a new symbol SH of type T */
+
+static void
+add_pending (FDR *fh, char *sh, struct type *t)
+{
+ int f_idx = fh - debug_info->fdr;
+ struct mdebug_pending *p = is_pending_symbol (fh, sh);
+
+ /* Make sure we do not make duplicates */
+ if (!p)
+ {
+ p = ((struct mdebug_pending *)
+ obstack_alloc (&current_objfile->psymbol_obstack,
+ sizeof (struct mdebug_pending)));
+ p->s = sh;
+ p->t = t;
+ p->next = pending_list[f_idx];
+ pending_list[f_idx] = p;
+ }
+}
+
+
+/* Parsing Routines proper. */
+
+/* Parse a single symbol. Mostly just make up a GDB symbol for it.
+ For blocks, procedures and types we open a new lexical context.
+ This is basically just a big switch on the symbol's type. Argument
+ AX is the base pointer of aux symbols for this file (fh->iauxBase).
+ EXT_SH points to the unswapped symbol, which is needed for struct,
+ union, etc., types; it is NULL for an EXTR. BIGEND says whether
+ aux symbols are big-endian or little-endian. Return count of
+ SYMR's handled (normally one). */
+
+static int
+parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
+ struct section_offsets *section_offsets, struct objfile *objfile)
+{
+ const bfd_size_type external_sym_size = debug_swap->external_sym_size;
+ void (*const swap_sym_in) (bfd *, void *, SYMR *) = debug_swap->swap_sym_in;
+ char *name;
+ struct symbol *s;
+ struct block *b;
+ struct mdebug_pending *pend;
+ struct type *t;
+ struct field *f;
+ int count = 1;
+ enum address_class class;
+ TIR tir;
+ long svalue = sh->value;
+ int bitsize;
+
+ if (ext_sh == (char *) NULL)
+ name = debug_info->ssext + sh->iss;
+ else
+ name = debug_info->ss + cur_fdr->issBase + sh->iss;
+
+ switch (sh->sc)
+ {
+ case scText:
+ case scRConst:
+ /* Do not relocate relative values.
+ The value of a stEnd symbol is the displacement from the
+ corresponding start symbol value.
+ The value of a stBlock symbol is the displacement from the
+ procedure address. */
+ if (sh->st != stEnd && sh->st != stBlock)
+ sh->value += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+ break;
+ case scData:
+ case scSData:
+ case scRData:
+ case scPData:
+ case scXData:
+ sh->value += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
+ break;
+ case scBss:
+ case scSBss:
+ sh->value += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
+ break;
+ }
+
+ switch (sh->st)
+ {
+ case stNil:
+ break;
+
+ case stGlobal: /* external symbol, goes into global block */
+ class = LOC_STATIC;
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (top_stack->cur_st),
+ GLOBAL_BLOCK);
+ s = new_symbol (name);
+ SYMBOL_VALUE_ADDRESS (s) = (CORE_ADDR) sh->value;
+ goto data;
+
+ case stStatic: /* static data, goes into current block. */
+ class = LOC_STATIC;
+ b = top_stack->cur_block;
+ s = new_symbol (name);
+ if (SC_IS_COMMON (sh->sc))
+ {
+ /* It is a FORTRAN common block. At least for SGI Fortran the
+ address is not in the symbol; we need to fix it later in
+ scan_file_globals. */
+ int bucket = hashname (SYMBOL_NAME (s));
+ SYMBOL_VALUE_CHAIN (s) = global_sym_chain[bucket];
+ global_sym_chain[bucket] = s;
+ }
+ else
+ SYMBOL_VALUE_ADDRESS (s) = (CORE_ADDR) sh->value;
+ goto data;
+
+ case stLocal: /* local variable, goes into current block */
+ if (sh->sc == scRegister)
+ {
+ class = LOC_REGISTER;
+ svalue = ECOFF_REG_TO_REGNUM (svalue);
+ }
+ else
+ class = LOC_LOCAL;
+ b = top_stack->cur_block;
+ s = new_symbol (name);
+ SYMBOL_VALUE (s) = svalue;
+
+ data: /* Common code for symbols describing data */
+ SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
+ SYMBOL_CLASS (s) = class;
+ add_symbol (s, b);
+
+ /* Type could be missing if file is compiled without debugging info. */
+ if (SC_IS_UNDEF (sh->sc)
+ || sh->sc == scNil || sh->index == indexNil)
+ SYMBOL_TYPE (s) = nodebug_var_symbol_type;
+ else
+ SYMBOL_TYPE (s) = parse_type (cur_fd, ax, sh->index, 0, bigend, name);
+ /* Value of a data symbol is its memory address */
+ break;
+
+ case stParam: /* arg to procedure, goes into current block */
+ max_gdbinfo++;
+ found_ecoff_debugging_info = 1;
+ top_stack->numargs++;
+
+ /* Special GNU C++ name. */
+ if (is_cplus_marker (name[0]) && name[1] == 't' && name[2] == 0)
+ name = "this"; /* FIXME, not alloc'd in obstack */
+ s = new_symbol (name);
+
+ SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
+ switch (sh->sc)
+ {
+ case scRegister:
+ /* Pass by value in register. */
+ SYMBOL_CLASS (s) = LOC_REGPARM;
+ svalue = ECOFF_REG_TO_REGNUM (svalue);
+ break;
+ case scVar:
+ /* Pass by reference on stack. */
+ SYMBOL_CLASS (s) = LOC_REF_ARG;
+ break;
+ case scVarRegister:
+ /* Pass by reference in register. */
+ SYMBOL_CLASS (s) = LOC_REGPARM_ADDR;
+ svalue = ECOFF_REG_TO_REGNUM (svalue);
+ break;
+ default:
+ /* Pass by value on stack. */
+ SYMBOL_CLASS (s) = LOC_ARG;
+ break;
+ }
+ SYMBOL_VALUE (s) = svalue;
+ SYMBOL_TYPE (s) = parse_type (cur_fd, ax, sh->index, 0, bigend, name);
+ add_symbol (s, top_stack->cur_block);
+ break;
+
+ case stLabel: /* label, goes into current block */
+ s = new_symbol (name);
+ SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; /* so that it can be used */
+ SYMBOL_CLASS (s) = LOC_LABEL; /* but not misused */
+ SYMBOL_VALUE_ADDRESS (s) = (CORE_ADDR) sh->value;
+ SYMBOL_TYPE (s) = mdebug_type_int;
+ add_symbol (s, top_stack->cur_block);
+ break;
+
+ case stProc: /* Procedure, usually goes into global block */
+ case stStaticProc: /* Static procedure, goes into current block */
+ s = new_symbol (name);
+ SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
+ SYMBOL_CLASS (s) = LOC_BLOCK;
+ /* Type of the return value */
+ if (SC_IS_UNDEF (sh->sc) || sh->sc == scNil)
+ t = mdebug_type_int;
+ else
+ {
+ t = parse_type (cur_fd, ax, sh->index + 1, 0, bigend, name);
+ if (STREQ (name, "malloc") && TYPE_CODE (t) == TYPE_CODE_VOID)
+ {
+ /* I don't know why, but, at least under Alpha GNU/Linux,
+ when linking against a malloc without debugging
+ symbols, its read as a function returning void---this
+ is bad because it means we cannot call functions with
+ string arguments interactively; i.e., "call
+ printf("howdy\n")" would fail with the error message
+ "program has no memory available". To avoid this, we
+ patch up the type and make it void*
+ instead. (davidm@azstarnet.com)
+ */
+ t = make_pointer_type (t, NULL);
+ }
+ }
+ b = top_stack->cur_block;
+ if (sh->st == stProc)
+ {
+ struct blockvector *bv = BLOCKVECTOR (top_stack->cur_st);
+ /* The next test should normally be true, but provides a
+ hook for nested functions (which we don't want to make
+ global). */
+ if (b == BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK))
+ b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ /* Irix 5 sometimes has duplicate names for the same
+ function. We want to add such names up at the global
+ level, not as a nested function. */
+ else if (sh->value == top_stack->procadr)
+ b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ }
+ add_symbol (s, b);
+
+ /* Make a type for the procedure itself */
+ SYMBOL_TYPE (s) = lookup_function_type (t);
+
+ /* Create and enter a new lexical context */
+ b = new_block (top_stack->maxsyms);
+ SYMBOL_BLOCK_VALUE (s) = b;
+ BLOCK_FUNCTION (b) = s;
+ BLOCK_START (b) = BLOCK_END (b) = sh->value;
+ BLOCK_SUPERBLOCK (b) = top_stack->cur_block;
+ add_block (b, top_stack->cur_st);
+
+ /* Not if we only have partial info */
+ if (SC_IS_UNDEF (sh->sc) || sh->sc == scNil)
+ break;
+
+ push_parse_stack ();
+ top_stack->cur_block = b;
+ top_stack->blocktype = sh->st;
+ top_stack->cur_type = SYMBOL_TYPE (s);
+ top_stack->cur_field = -1;
+ top_stack->procadr = sh->value;
+ top_stack->numargs = 0;
+ break;
+
+ /* Beginning of code for structure, union, and enum definitions.
+ They all share a common set of local variables, defined here. */
+ {
+ enum type_code type_code;
+ char *ext_tsym;
+ int nfields;
+ long max_value;
+ struct field *f;
+
+ case stStruct: /* Start a block defining a struct type */
+ type_code = TYPE_CODE_STRUCT;
+ goto structured_common;
+
+ case stUnion: /* Start a block defining a union type */
+ type_code = TYPE_CODE_UNION;
+ goto structured_common;
+
+ case stEnum: /* Start a block defining an enum type */
+ type_code = TYPE_CODE_ENUM;
+ goto structured_common;
+
+ case stBlock: /* Either a lexical block, or some type */
+ if (sh->sc != scInfo && !SC_IS_COMMON (sh->sc))
+ goto case_stBlock_code; /* Lexical block */
+
+ type_code = TYPE_CODE_UNDEF; /* We have a type. */
+
+ /* Common code for handling struct, union, enum, and/or as-yet-
+ unknown-type blocks of info about structured data. `type_code'
+ has been set to the proper TYPE_CODE, if we know it. */
+ structured_common:
+ found_ecoff_debugging_info = 1;
+ push_parse_stack ();
+ top_stack->blocktype = stBlock;
+
+ /* First count the number of fields and the highest value. */
+ nfields = 0;
+ max_value = 0;
+ for (ext_tsym = ext_sh + external_sym_size;
+ ;
+ ext_tsym += external_sym_size)
+ {
+ SYMR tsym;
+
+ (*swap_sym_in) (cur_bfd, ext_tsym, &tsym);
+
+ switch (tsym.st)
+ {
+ case stEnd:
+ goto end_of_fields;
+
+ case stMember:
+ if (nfields == 0 && type_code == TYPE_CODE_UNDEF)
+ {
+ /* If the type of the member is Nil (or Void),
+ without qualifiers, assume the tag is an
+ enumeration.
+ Alpha cc -migrate enums are recognized by a zero
+ index and a zero symbol value.
+ DU 4.0 cc enums are recognized by a member type of
+ btEnum without qualifiers and a zero symbol value. */
+ if (tsym.index == indexNil
+ || (tsym.index == 0 && sh->value == 0))
+ type_code = TYPE_CODE_ENUM;
+ else
+ {
+ (*debug_swap->swap_tir_in) (bigend,
+ &ax[tsym.index].a_ti,
+ &tir);
+ if ((tir.bt == btNil || tir.bt == btVoid
+ || (tir.bt == btEnum && sh->value == 0))
+ && tir.tq0 == tqNil)
+ type_code = TYPE_CODE_ENUM;
+ }
+ }
+ nfields++;
+ if (tsym.value > max_value)
+ max_value = tsym.value;
+ break;
+
+ case stBlock:
+ case stUnion:
+ case stEnum:
+ case stStruct:
+ {
+#if 0
+ /* This is a no-op; is it trying to tell us something
+ we should be checking? */
+ if (tsym.sc == scVariant); /*UNIMPLEMENTED */
+#endif
+ if (tsym.index != 0)
+ {
+ /* This is something like a struct within a
+ struct. Skip over the fields of the inner
+ struct. The -1 is because the for loop will
+ increment ext_tsym. */
+ ext_tsym = ((char *) debug_info->external_sym
+ + ((cur_fdr->isymBase + tsym.index - 1)
+ * external_sym_size));
+ }
+ }
+ break;
+
+ case stTypedef:
+ /* mips cc puts out a typedef for struct x if it is not yet
+ defined when it encounters
+ struct y { struct x *xp; };
+ Just ignore it. */
+ break;
+
+ case stIndirect:
+ /* Irix5 cc puts out a stIndirect for struct x if it is not
+ yet defined when it encounters
+ struct y { struct x *xp; };
+ Just ignore it. */
+ break;
+
+ default:
+ complain (&block_member_complaint, tsym.st);
+ }
+ }
+ end_of_fields:;
+
+ /* In an stBlock, there is no way to distinguish structs,
+ unions, and enums at this point. This is a bug in the
+ original design (that has been fixed with the recent
+ addition of the stStruct, stUnion, and stEnum symbol
+ types.) The way you can tell is if/when you see a variable
+ or field of that type. In that case the variable's type
+ (in the AUX table) says if the type is struct, union, or
+ enum, and points back to the stBlock here. So you can
+ patch the tag kind up later - but only if there actually is
+ a variable or field of that type.
+
+ So until we know for sure, we will guess at this point.
+ The heuristic is:
+ If the first member has index==indexNil or a void type,
+ assume we have an enumeration.
+ Otherwise, if there is more than one member, and all
+ the members have offset 0, assume we have a union.
+ Otherwise, assume we have a struct.
+
+ The heuristic could guess wrong in the case of of an
+ enumeration with no members or a union with one (or zero)
+ members, or when all except the last field of a struct have
+ width zero. These are uncommon and/or illegal situations,
+ and in any case guessing wrong probably doesn't matter
+ much.
+
+ But if we later do find out we were wrong, we fixup the tag
+ kind. Members of an enumeration must be handled
+ differently from struct/union fields, and that is harder to
+ patch up, but luckily we shouldn't need to. (If there are
+ any enumeration members, we can tell for sure it's an enum
+ here.) */
+
+ if (type_code == TYPE_CODE_UNDEF)
+ {
+ if (nfields > 1 && max_value == 0)
+ type_code = TYPE_CODE_UNION;
+ else
+ type_code = TYPE_CODE_STRUCT;
+ }
+
+ /* Create a new type or use the pending type. */
+ pend = is_pending_symbol (cur_fdr, ext_sh);
+ if (pend == (struct mdebug_pending *) NULL)
+ {
+ t = new_type (NULL);
+ add_pending (cur_fdr, ext_sh, t);
+ }
+ else
+ t = pend->t;
+
+ /* Do not set the tag name if it is a compiler generated tag name
+ (.Fxx or .xxfake or empty) for unnamed struct/union/enums.
+ Alpha cc puts out an sh->iss of zero for those. */
+ if (sh->iss == 0 || name[0] == '.' || name[0] == '\0')
+ TYPE_TAG_NAME (t) = NULL;
+ else
+ TYPE_TAG_NAME (t) = obconcat (&current_objfile->symbol_obstack,
+ "", "", name);
+
+ TYPE_CODE (t) = type_code;
+ TYPE_LENGTH (t) = sh->value;
+ TYPE_NFIELDS (t) = nfields;
+ TYPE_FIELDS (t) = f = ((struct field *)
+ TYPE_ALLOC (t,
+ nfields * sizeof (struct field)));
+
+ if (type_code == TYPE_CODE_ENUM)
+ {
+ int unsigned_enum = 1;
+
+ /* This is a non-empty enum. */
+
+ /* DEC c89 has the number of enumerators in the sh.value field,
+ not the type length, so we have to compensate for that
+ incompatibility quirk.
+ This might do the wrong thing for an enum with one or two
+ enumerators and gcc -gcoff -fshort-enums, but these cases
+ are hopefully rare enough.
+ Alpha cc -migrate has a sh.value field of zero, we adjust
+ that too. */
+ if (TYPE_LENGTH (t) == TYPE_NFIELDS (t)
+ || TYPE_LENGTH (t) == 0)
+ TYPE_LENGTH (t) = TARGET_INT_BIT / HOST_CHAR_BIT;
+ for (ext_tsym = ext_sh + external_sym_size;
+ ;
+ ext_tsym += external_sym_size)
+ {
+ SYMR tsym;
+ struct symbol *enum_sym;
+
+ (*swap_sym_in) (cur_bfd, ext_tsym, &tsym);
+
+ if (tsym.st != stMember)
+ break;
+
+ FIELD_BITPOS (*f) = tsym.value;
+ FIELD_TYPE (*f) = t;
+ FIELD_NAME (*f) = debug_info->ss + cur_fdr->issBase + tsym.iss;
+ FIELD_BITSIZE (*f) = 0;
+
+ enum_sym = ((struct symbol *)
+ obstack_alloc (&current_objfile->symbol_obstack,
+ sizeof (struct symbol)));
+ memset (enum_sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (enum_sym) =
+ obsavestring (f->name, strlen (f->name),
+ &current_objfile->symbol_obstack);
+ SYMBOL_CLASS (enum_sym) = LOC_CONST;
+ SYMBOL_TYPE (enum_sym) = t;
+ SYMBOL_NAMESPACE (enum_sym) = VAR_NAMESPACE;
+ SYMBOL_VALUE (enum_sym) = tsym.value;
+ if (SYMBOL_VALUE (enum_sym) < 0)
+ unsigned_enum = 0;
+ add_symbol (enum_sym, top_stack->cur_block);
+
+ /* Skip the stMembers that we've handled. */
+ count++;
+ f++;
+ }
+ if (unsigned_enum)
+ TYPE_FLAGS (t) |= TYPE_FLAG_UNSIGNED;
+ }
+ /* make this the current type */
+ top_stack->cur_type = t;
+ top_stack->cur_field = 0;
+
+ /* Do not create a symbol for alpha cc unnamed structs. */
+ if (sh->iss == 0)
+ break;
+
+ /* gcc puts out an empty struct for an opaque struct definitions,
+ do not create a symbol for it either. */
+ if (TYPE_NFIELDS (t) == 0)
+ {
+ TYPE_FLAGS (t) |= TYPE_FLAG_STUB;
+ break;
+ }
+
+ s = new_symbol (name);
+ SYMBOL_NAMESPACE (s) = STRUCT_NAMESPACE;
+ SYMBOL_CLASS (s) = LOC_TYPEDEF;
+ SYMBOL_VALUE (s) = 0;
+ SYMBOL_TYPE (s) = t;
+ add_symbol (s, top_stack->cur_block);
+ break;
+
+ /* End of local variables shared by struct, union, enum, and
+ block (as yet unknown struct/union/enum) processing. */
+ }
+
+ case_stBlock_code:
+ found_ecoff_debugging_info = 1;
+ /* beginnning of (code) block. Value of symbol
+ is the displacement from procedure start */
+ push_parse_stack ();
+
+ /* Do not start a new block if this is the outermost block of a
+ procedure. This allows the LOC_BLOCK symbol to point to the
+ block with the local variables, so funcname::var works. */
+ if (top_stack->blocktype == stProc
+ || top_stack->blocktype == stStaticProc)
+ {
+ top_stack->blocktype = stNil;
+ break;
+ }
+
+ top_stack->blocktype = stBlock;
+ b = new_block (top_stack->maxsyms);
+ BLOCK_START (b) = sh->value + top_stack->procadr;
+ BLOCK_SUPERBLOCK (b) = top_stack->cur_block;
+ top_stack->cur_block = b;
+ add_block (b, top_stack->cur_st);
+ break;
+
+ case stEnd: /* end (of anything) */
+ if (sh->sc == scInfo || SC_IS_COMMON (sh->sc))
+ {
+ /* Finished with type */
+ top_stack->cur_type = 0;
+ }
+ else if (sh->sc == scText &&
+ (top_stack->blocktype == stProc ||
+ top_stack->blocktype == stStaticProc))
+ {
+ /* Finished with procedure */
+ struct blockvector *bv = BLOCKVECTOR (top_stack->cur_st);
+ struct mips_extra_func_info *e;
+ struct block *b;
+ struct type *ftype = top_stack->cur_type;
+ int i;
+
+ BLOCK_END (top_stack->cur_block) += sh->value; /* size */
+
+ /* Make up special symbol to contain procedure specific info */
+ s = new_symbol (MIPS_EFI_SYMBOL_NAME);
+ SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE;
+ SYMBOL_CLASS (s) = LOC_CONST;
+ SYMBOL_TYPE (s) = mdebug_type_void;
+ e = ((struct mips_extra_func_info *)
+ obstack_alloc (&current_objfile->symbol_obstack,
+ sizeof (struct mips_extra_func_info)));
+ memset (e, 0, sizeof (struct mips_extra_func_info));
+ SYMBOL_VALUE (s) = (long) e;
+ e->numargs = top_stack->numargs;
+ e->pdr.framereg = -1;
+ add_symbol (s, top_stack->cur_block);
+
+ /* Reallocate symbols, saving memory */
+ b = shrink_block (top_stack->cur_block, top_stack->cur_st);
+
+ /* f77 emits proc-level with address bounds==[0,0],
+ So look for such child blocks, and patch them. */
+ for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); i++)
+ {
+ struct block *b_bad = BLOCKVECTOR_BLOCK (bv, i);
+ if (BLOCK_SUPERBLOCK (b_bad) == b
+ && BLOCK_START (b_bad) == top_stack->procadr
+ && BLOCK_END (b_bad) == top_stack->procadr)
+ {
+ BLOCK_START (b_bad) = BLOCK_START (b);
+ BLOCK_END (b_bad) = BLOCK_END (b);
+ }
+ }
+
+ if (TYPE_NFIELDS (ftype) <= 0)
+ {
+ /* No parameter type information is recorded with the function's
+ type. Set that from the type of the parameter symbols. */
+ int nparams = top_stack->numargs;
+ int iparams;
+ struct symbol *sym;
+
+ if (nparams > 0)
+ {
+ TYPE_NFIELDS (ftype) = nparams;
+ TYPE_FIELDS (ftype) = (struct field *)
+ TYPE_ALLOC (ftype, nparams * sizeof (struct field));
+
+ for (i = iparams = 0; iparams < nparams; i++)
+ {
+ sym = BLOCK_SYM (b, i);
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym);
+ TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
+ iparams++;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ else if (sh->sc == scText && top_stack->blocktype == stBlock)
+ {
+ /* End of (code) block. The value of the symbol is the
+ displacement from the procedure`s start address of the
+ end of this block. */
+ BLOCK_END (top_stack->cur_block) = sh->value + top_stack->procadr;
+ shrink_block (top_stack->cur_block, top_stack->cur_st);
+ }
+ else if (sh->sc == scText && top_stack->blocktype == stNil)
+ {
+ /* End of outermost block. Pop parse stack and ignore. The
+ following stEnd of stProc will take care of the block. */
+ ;
+ }
+ else if (sh->sc == scText && top_stack->blocktype == stFile)
+ {
+ /* End of file. Pop parse stack and ignore. Higher
+ level code deals with this. */
+ ;
+ }
+ else
+ complain (&stEnd_complaint, sh->sc);
+
+ pop_parse_stack (); /* restore previous lexical context */
+ break;
+
+ case stMember: /* member of struct or union */
+ f = &TYPE_FIELDS (top_stack->cur_type)[top_stack->cur_field++];
+ FIELD_NAME (*f) = name;
+ FIELD_BITPOS (*f) = sh->value;
+ bitsize = 0;
+ FIELD_TYPE (*f) = parse_type (cur_fd, ax, sh->index, &bitsize, bigend, name);
+ FIELD_BITSIZE (*f) = bitsize;
+ break;
+
+ case stIndirect: /* forward declaration on Irix5 */
+ /* Forward declarations from Irix5 cc are handled by cross_ref,
+ skip them. */
+ break;
+
+ case stTypedef: /* type definition */
+ found_ecoff_debugging_info = 1;
+
+ /* Typedefs for forward declarations and opaque structs from alpha cc
+ are handled by cross_ref, skip them. */
+ if (sh->iss == 0)
+ break;
+
+ /* Parse the type or use the pending type. */
+ pend = is_pending_symbol (cur_fdr, ext_sh);
+ if (pend == (struct mdebug_pending *) NULL)
+ {
+ t = parse_type (cur_fd, ax, sh->index, (int *) NULL, bigend, name);
+ add_pending (cur_fdr, ext_sh, t);
+ }
+ else
+ t = pend->t;
+
+ /* mips cc puts out a typedef with the name of the struct for forward
+ declarations. These should not go into the symbol table and
+ TYPE_NAME should not be set for them.
+ They can't be distinguished from an intentional typedef to
+ the same name however:
+ x.h:
+ struct x { int ix; int jx; };
+ struct xx;
+ x.c:
+ typedef struct x x;
+ struct xx {int ixx; int jxx; };
+ generates a cross referencing stTypedef for x and xx.
+ The user visible effect of this is that the type of a pointer
+ to struct foo sometimes is given as `foo *' instead of `struct foo *'.
+ The problem is fixed with alpha cc and Irix5 cc. */
+
+ /* However if the typedef cross references to an opaque aggregate, it
+ is safe to omit it from the symbol table. */
+
+ if (has_opaque_xref (cur_fdr, sh))
+ break;
+ s = new_symbol (name);
+ SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
+ SYMBOL_CLASS (s) = LOC_TYPEDEF;
+ SYMBOL_BLOCK_VALUE (s) = top_stack->cur_block;
+ SYMBOL_TYPE (s) = t;
+ add_symbol (s, top_stack->cur_block);
+
+ /* Incomplete definitions of structs should not get a name. */
+ if (TYPE_NAME (SYMBOL_TYPE (s)) == NULL
+ && (TYPE_NFIELDS (SYMBOL_TYPE (s)) != 0
+ || (TYPE_CODE (SYMBOL_TYPE (s)) != TYPE_CODE_STRUCT
+ && TYPE_CODE (SYMBOL_TYPE (s)) != TYPE_CODE_UNION)))
+ {
+ if (TYPE_CODE (SYMBOL_TYPE (s)) == TYPE_CODE_PTR
+ || TYPE_CODE (SYMBOL_TYPE (s)) == TYPE_CODE_FUNC)
+ {
+ /* If we are giving a name to a type such as "pointer to
+ foo" or "function returning foo", we better not set
+ the TYPE_NAME. If the program contains "typedef char
+ *caddr_t;", we don't want all variables of type char
+ * to print as caddr_t. This is not just a
+ consequence of GDB's type management; CC and GCC (at
+ least through version 2.4) both output variables of
+ either type char * or caddr_t with the type
+ refering to the stTypedef symbol for caddr_t. If a future
+ compiler cleans this up it GDB is not ready for it
+ yet, but if it becomes ready we somehow need to
+ disable this check (without breaking the PCC/GCC2.4
+ case).
+
+ Sigh.
+
+ Fortunately, this check seems not to be necessary
+ for anything except pointers or functions. */
+ }
+ else
+ TYPE_NAME (SYMBOL_TYPE (s)) = SYMBOL_NAME (s);
+ }
+ break;
+
+ case stFile: /* file name */
+ push_parse_stack ();
+ top_stack->blocktype = sh->st;
+ break;
+
+ /* I`ve never seen these for C */
+ case stRegReloc:
+ break; /* register relocation */
+ case stForward:
+ break; /* forwarding address */
+ case stConstant:
+ break; /* constant */
+ default:
+ complain (&unknown_mdebug_symtype_complaint, sh->st);
+ break;
+ }
+
+ return count;
+}
+
+/* Parse the type information provided in the raw AX entries for
+ the symbol SH. Return the bitfield size in BS, in case.
+ We must byte-swap the AX entries before we use them; BIGEND says whether
+ they are big-endian or little-endian (from fh->fBigendian). */
+
+static struct type *
+parse_type (int fd, union aux_ext *ax, unsigned int aux_index, int *bs,
+ int bigend, char *sym_name)
+{
+ /* Null entries in this map are treated specially */
+ static struct type **map_bt[] =
+ {
+ &mdebug_type_void, /* btNil */
+ &mdebug_type_adr_32, /* btAdr */
+ &mdebug_type_char, /* btChar */
+ &mdebug_type_unsigned_char, /* btUChar */
+ &mdebug_type_short, /* btShort */
+ &mdebug_type_unsigned_short, /* btUShort */
+ &mdebug_type_int_32, /* btInt */
+ &mdebug_type_unsigned_int_32, /* btUInt */
+ &mdebug_type_long_32, /* btLong */
+ &mdebug_type_unsigned_long_32, /* btULong */
+ &mdebug_type_float, /* btFloat */
+ &mdebug_type_double, /* btDouble */
+ 0, /* btStruct */
+ 0, /* btUnion */
+ 0, /* btEnum */
+ 0, /* btTypedef */
+ 0, /* btRange */
+ 0, /* btSet */
+ &mdebug_type_complex, /* btComplex */
+ &mdebug_type_double_complex, /* btDComplex */
+ 0, /* btIndirect */
+ &mdebug_type_fixed_dec, /* btFixedDec */
+ &mdebug_type_float_dec, /* btFloatDec */
+ &mdebug_type_string, /* btString */
+ 0, /* btBit */
+ 0, /* btPicture */
+ &mdebug_type_void, /* btVoid */
+ 0, /* DEC C++: Pointer to member */
+ 0, /* DEC C++: Virtual function table */
+ 0, /* DEC C++: Class (Record) */
+ &mdebug_type_long_64, /* btLong64 */
+ &mdebug_type_unsigned_long_64, /* btULong64 */
+ &mdebug_type_long_long_64, /* btLongLong64 */
+ &mdebug_type_unsigned_long_long_64, /* btULongLong64 */
+ &mdebug_type_adr_64, /* btAdr64 */
+ &mdebug_type_int_64, /* btInt64 */
+ &mdebug_type_unsigned_int_64, /* btUInt64 */
+ };
+
+ TIR t[1];
+ struct type *tp = 0;
+ enum type_code type_code = TYPE_CODE_UNDEF;
+
+ /* Handle undefined types, they have indexNil. */
+ if (aux_index == indexNil)
+ return mdebug_type_int;
+
+ /* Handle corrupt aux indices. */
+ if (aux_index >= (debug_info->fdr + fd)->caux)
+ {
+ complain (&index_complaint, sym_name);
+ return mdebug_type_int;
+ }
+ ax += aux_index;
+
+ /* Use aux as a type information record, map its basic type. */
+ (*debug_swap->swap_tir_in) (bigend, &ax->a_ti, t);
+ if (t->bt >= (sizeof (map_bt) / sizeof (*map_bt)))
+ {
+ complain (&basic_type_complaint, t->bt, sym_name);
+ return mdebug_type_int;
+ }
+ if (map_bt[t->bt])
+ {
+ tp = *map_bt[t->bt];
+ }
+ else
+ {
+ tp = NULL;
+ /* Cannot use builtin types -- build our own */
+ switch (t->bt)
+ {
+ case btStruct:
+ type_code = TYPE_CODE_STRUCT;
+ break;
+ case btUnion:
+ type_code = TYPE_CODE_UNION;
+ break;
+ case btEnum:
+ type_code = TYPE_CODE_ENUM;
+ break;
+ case btRange:
+ type_code = TYPE_CODE_RANGE;
+ break;
+ case btSet:
+ type_code = TYPE_CODE_SET;
+ break;
+ case btIndirect:
+ /* alpha cc -migrate uses this for typedefs. The true type will
+ be obtained by crossreferencing below. */
+ type_code = TYPE_CODE_ERROR;
+ break;
+ case btTypedef:
+ /* alpha cc uses this for typedefs. The true type will be
+ obtained by crossreferencing below. */
+ type_code = TYPE_CODE_ERROR;
+ break;
+ default:
+ complain (&basic_type_complaint, t->bt, sym_name);
+ return mdebug_type_int;
+ }
+ }
+
+ /* Move on to next aux */
+ ax++;
+
+ if (t->fBitfield)
+ {
+ int width = AUX_GET_WIDTH (bigend, ax);
+
+ /* Inhibit core dumps with some cfront generated objects that
+ corrupt the TIR. */
+ if (bs == (int *) NULL)
+ {
+ /* Alpha cc -migrate encodes char and unsigned char types
+ as short and unsigned short types with a field width of 8.
+ Enum types also have a field width which we ignore for now. */
+ if (t->bt == btShort && width == 8)
+ tp = mdebug_type_char;
+ else if (t->bt == btUShort && width == 8)
+ tp = mdebug_type_unsigned_char;
+ else if (t->bt == btEnum)
+ ;
+ else
+ complain (&bad_fbitfield_complaint, sym_name);
+ }
+ else
+ *bs = width;
+ ax++;
+ }
+
+ /* A btIndirect entry cross references to an aux entry containing
+ the type. */
+ if (t->bt == btIndirect)
+ {
+ RNDXR rn[1];
+ int rf;
+ FDR *xref_fh;
+ int xref_fd;
+
+ (*debug_swap->swap_rndx_in) (bigend, &ax->a_rndx, rn);
+ ax++;
+ if (rn->rfd == 0xfff)
+ {
+ rf = AUX_GET_ISYM (bigend, ax);
+ ax++;
+ }
+ else
+ rf = rn->rfd;
+
+ if (rf == -1)
+ {
+ complain (&bad_indirect_xref_complaint, sym_name);
+ return mdebug_type_int;
+ }
+ xref_fh = get_rfd (fd, rf);
+ xref_fd = xref_fh - debug_info->fdr;
+ tp = parse_type (xref_fd, debug_info->external_aux + xref_fh->iauxBase,
+ rn->index, (int *) NULL, xref_fh->fBigendian, sym_name);
+ }
+
+ /* All these types really point to some (common) MIPS type
+ definition, and only the type-qualifiers fully identify
+ them. We'll make the same effort at sharing. */
+ if (t->bt == btStruct ||
+ t->bt == btUnion ||
+ t->bt == btEnum ||
+
+ /* btSet (I think) implies that the name is a tag name, not a typedef
+ name. This apparently is a MIPS extension for C sets. */
+ t->bt == btSet)
+ {
+ char *name;
+
+ /* Try to cross reference this type, build new type on failure. */
+ ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name);
+ if (tp == (struct type *) NULL)
+ tp = init_type (type_code, 0, 0, (char *) NULL, current_objfile);
+
+ /* DEC c89 produces cross references to qualified aggregate types,
+ dereference them. */
+ while (TYPE_CODE (tp) == TYPE_CODE_PTR
+ || TYPE_CODE (tp) == TYPE_CODE_ARRAY)
+ tp = TYPE_TARGET_TYPE (tp);
+
+ /* Make sure that TYPE_CODE(tp) has an expected type code.
+ Any type may be returned from cross_ref if file indirect entries
+ are corrupted. */
+ if (TYPE_CODE (tp) != TYPE_CODE_STRUCT
+ && TYPE_CODE (tp) != TYPE_CODE_UNION
+ && TYPE_CODE (tp) != TYPE_CODE_ENUM)
+ {
+ complain (&unexpected_type_code_complaint, sym_name);
+ }
+ else
+ {
+
+ /* Usually, TYPE_CODE(tp) is already type_code. The main
+ exception is if we guessed wrong re struct/union/enum.
+ But for struct vs. union a wrong guess is harmless, so
+ don't complain(). */
+ if ((TYPE_CODE (tp) == TYPE_CODE_ENUM
+ && type_code != TYPE_CODE_ENUM)
+ || (TYPE_CODE (tp) != TYPE_CODE_ENUM
+ && type_code == TYPE_CODE_ENUM))
+ {
+ complain (&bad_tag_guess_complaint, sym_name);
+ }
+
+ if (TYPE_CODE (tp) != type_code)
+ {
+ TYPE_CODE (tp) = type_code;
+ }
+
+ /* Do not set the tag name if it is a compiler generated tag name
+ (.Fxx or .xxfake or empty) for unnamed struct/union/enums. */
+ if (name[0] == '.' || name[0] == '\0')
+ TYPE_TAG_NAME (tp) = NULL;
+ else if (TYPE_TAG_NAME (tp) == NULL
+ || !STREQ (TYPE_TAG_NAME (tp), name))
+ TYPE_TAG_NAME (tp) = obsavestring (name, strlen (name),
+ &current_objfile->type_obstack);
+ }
+ }
+
+ /* All these types really point to some (common) MIPS type
+ definition, and only the type-qualifiers fully identify
+ them. We'll make the same effort at sharing.
+ FIXME: We are not doing any guessing on range types. */
+ if (t->bt == btRange)
+ {
+ char *name;
+
+ /* Try to cross reference this type, build new type on failure. */
+ ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name);
+ if (tp == (struct type *) NULL)
+ tp = init_type (type_code, 0, 0, (char *) NULL, current_objfile);
+
+ /* Make sure that TYPE_CODE(tp) has an expected type code.
+ Any type may be returned from cross_ref if file indirect entries
+ are corrupted. */
+ if (TYPE_CODE (tp) != TYPE_CODE_RANGE)
+ {
+ complain (&unexpected_type_code_complaint, sym_name);
+ }
+ else
+ {
+ /* Usually, TYPE_CODE(tp) is already type_code. The main
+ exception is if we guessed wrong re struct/union/enum. */
+ if (TYPE_CODE (tp) != type_code)
+ {
+ complain (&bad_tag_guess_complaint, sym_name);
+ TYPE_CODE (tp) = type_code;
+ }
+ if (TYPE_NAME (tp) == NULL || !STREQ (TYPE_NAME (tp), name))
+ TYPE_NAME (tp) = obsavestring (name, strlen (name),
+ &current_objfile->type_obstack);
+ }
+ }
+ if (t->bt == btTypedef)
+ {
+ char *name;
+
+ /* Try to cross reference this type, it should succeed. */
+ ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name);
+ if (tp == (struct type *) NULL)
+ {
+ complain (&unable_to_cross_ref_complaint, sym_name);
+ tp = mdebug_type_int;
+ }
+ }
+
+ /* Deal with range types */
+ if (t->bt == btRange)
+ {
+ TYPE_NFIELDS (tp) = 2;
+ TYPE_FIELDS (tp) = ((struct field *)
+ TYPE_ALLOC (tp, 2 * sizeof (struct field)));
+ TYPE_FIELD_NAME (tp, 0) = obsavestring ("Low", strlen ("Low"),
+ &current_objfile->type_obstack);
+ TYPE_FIELD_BITPOS (tp, 0) = AUX_GET_DNLOW (bigend, ax);
+ ax++;
+ TYPE_FIELD_NAME (tp, 1) = obsavestring ("High", strlen ("High"),
+ &current_objfile->type_obstack);
+ TYPE_FIELD_BITPOS (tp, 1) = AUX_GET_DNHIGH (bigend, ax);
+ ax++;
+ }
+
+ /* Parse all the type qualifiers now. If there are more
+ than 6 the game will continue in the next aux */
+
+ while (1)
+ {
+#define PARSE_TQ(tq) \
+ if (t->tq != tqNil) \
+ ax += upgrade_type(fd, &tp, t->tq, ax, bigend, sym_name); \
+ else \
+ break;
+
+ PARSE_TQ (tq0);
+ PARSE_TQ (tq1);
+ PARSE_TQ (tq2);
+ PARSE_TQ (tq3);
+ PARSE_TQ (tq4);
+ PARSE_TQ (tq5);
+#undef PARSE_TQ
+
+ /* mips cc 2.x and gcc never put out continued aux entries. */
+ if (!t->continued)
+ break;
+
+ (*debug_swap->swap_tir_in) (bigend, &ax->a_ti, t);
+ ax++;
+ }
+
+ /* Complain for illegal continuations due to corrupt aux entries. */
+ if (t->continued)
+ complain (&bad_continued_complaint, sym_name);
+
+ return tp;
+}
+
+/* Make up a complex type from a basic one. Type is passed by
+ reference in TPP and side-effected as necessary. The type
+ qualifier TQ says how to handle the aux symbols at AX for
+ the symbol SX we are currently analyzing. BIGEND says whether
+ aux symbols are big-endian or little-endian.
+ Returns the number of aux symbols we parsed. */
+
+static int
+upgrade_type (int fd, struct type **tpp, int tq, union aux_ext *ax, int bigend,
+ char *sym_name)
+{
+ int off;
+ struct type *t;
+
+ /* Used in array processing */
+ int rf, id;
+ FDR *fh;
+ struct type *range;
+ struct type *indx;
+ int lower, upper;
+ RNDXR rndx;
+
+ switch (tq)
+ {
+ case tqPtr:
+ t = lookup_pointer_type (*tpp);
+ *tpp = t;
+ return 0;
+
+ case tqProc:
+ t = lookup_function_type (*tpp);
+ *tpp = t;
+ return 0;
+
+ case tqArray:
+ off = 0;
+
+ /* Determine and record the domain type (type of index) */
+ (*debug_swap->swap_rndx_in) (bigend, &ax->a_rndx, &rndx);
+ id = rndx.index;
+ rf = rndx.rfd;
+ if (rf == 0xfff)
+ {
+ ax++;
+ rf = AUX_GET_ISYM (bigend, ax);
+ off++;
+ }
+ fh = get_rfd (fd, rf);
+
+ indx = parse_type (fh - debug_info->fdr,
+ debug_info->external_aux + fh->iauxBase,
+ id, (int *) NULL, bigend, sym_name);
+
+ /* The bounds type should be an integer type, but might be anything
+ else due to corrupt aux entries. */
+ if (TYPE_CODE (indx) != TYPE_CODE_INT)
+ {
+ complain (&array_index_type_complaint, sym_name);
+ indx = mdebug_type_int;
+ }
+
+ /* Get the bounds, and create the array type. */
+ ax++;
+ lower = AUX_GET_DNLOW (bigend, ax);
+ ax++;
+ upper = AUX_GET_DNHIGH (bigend, ax);
+ ax++;
+ rf = AUX_GET_WIDTH (bigend, ax); /* bit size of array element */
+
+ range = create_range_type ((struct type *) NULL, indx,
+ lower, upper);
+
+ t = create_array_type ((struct type *) NULL, *tpp, range);
+
+ /* We used to fill in the supplied array element bitsize
+ here if the TYPE_LENGTH of the target type was zero.
+ This happens for a `pointer to an array of anonymous structs',
+ but in this case the array element bitsize is also zero,
+ so nothing is gained.
+ And we used to check the TYPE_LENGTH of the target type against
+ the supplied array element bitsize.
+ gcc causes a mismatch for `pointer to array of object',
+ since the sdb directives it uses do not have a way of
+ specifying the bitsize, but it does no harm (the
+ TYPE_LENGTH should be correct) and we should be able to
+ ignore the erroneous bitsize from the auxiliary entry safely.
+ dbx seems to ignore it too. */
+
+ /* TYPE_FLAG_TARGET_STUB now takes care of the zero TYPE_LENGTH
+ problem. */
+ if (TYPE_LENGTH (*tpp) == 0)
+ {
+ TYPE_FLAGS (t) |= TYPE_FLAG_TARGET_STUB;
+ }
+
+ *tpp = t;
+ return 4 + off;
+
+ case tqVol:
+ /* Volatile -- currently ignored */
+ return 0;
+
+ case tqConst:
+ /* Const -- currently ignored */
+ return 0;
+
+ default:
+ complain (&unknown_type_qual_complaint, tq);
+ return 0;
+ }
+}
+
+
+/* Parse a procedure descriptor record PR. Note that the procedure is
+ parsed _after_ the local symbols, now we just insert the extra
+ information we need into a MIPS_EFI_SYMBOL_NAME symbol that has
+ already been placed in the procedure's main block. Note also that
+ images that have been partially stripped (ld -x) have been deprived
+ of local symbols, and we have to cope with them here. FIRST_OFF is
+ the offset of the first procedure for this FDR; we adjust the
+ address by this amount, but I don't know why. SEARCH_SYMTAB is the symtab
+ to look for the function which contains the MIPS_EFI_SYMBOL_NAME symbol
+ in question, or NULL to use top_stack->cur_block. */
+
+static void parse_procedure (PDR *, struct symtab *, struct partial_symtab *);
+
+static void
+parse_procedure (PDR *pr, struct symtab *search_symtab,
+ struct partial_symtab *pst)
+{
+ struct symbol *s, *i;
+ struct block *b;
+ struct mips_extra_func_info *e;
+ char *sh_name;
+
+ /* Simple rule to find files linked "-x" */
+ if (cur_fdr->rss == -1)
+ {
+ if (pr->isym == -1)
+ {
+ /* Static procedure at address pr->adr. Sigh. */
+ /* FIXME-32x64. assuming pr->adr fits in long. */
+ complain (&pdr_static_symbol_complaint, (unsigned long) pr->adr);
+ return;
+ }
+ else
+ {
+ /* external */
+ EXTR she;
+
+ (*debug_swap->swap_ext_in) (cur_bfd,
+ ((char *) debug_info->external_ext
+ + (pr->isym
+ * debug_swap->external_ext_size)),
+ &she);
+ sh_name = debug_info->ssext + she.asym.iss;
+ }
+ }
+ else
+ {
+ /* Full symbols */
+ SYMR sh;
+
+ (*debug_swap->swap_sym_in) (cur_bfd,
+ ((char *) debug_info->external_sym
+ + ((cur_fdr->isymBase + pr->isym)
+ * debug_swap->external_sym_size)),
+ &sh);
+ sh_name = debug_info->ss + cur_fdr->issBase + sh.iss;
+ }
+
+ if (search_symtab != NULL)
+ {
+#if 0
+ /* This loses both in the case mentioned (want a static, find a global),
+ but also if we are looking up a non-mangled name which happens to
+ match the name of a mangled function. */
+ /* We have to save the cur_fdr across the call to lookup_symbol.
+ If the pdr is for a static function and if a global function with
+ the same name exists, lookup_symbol will eventually read in the symtab
+ for the global function and clobber cur_fdr. */
+ FDR *save_cur_fdr = cur_fdr;
+ s = lookup_symbol (sh_name, NULL, VAR_NAMESPACE, 0, NULL);
+ cur_fdr = save_cur_fdr;
+#else
+ s = mylookup_symbol
+ (sh_name,
+ BLOCKVECTOR_BLOCK (BLOCKVECTOR (search_symtab), STATIC_BLOCK),
+ VAR_NAMESPACE,
+ LOC_BLOCK);
+#endif
+ }
+ else
+ s = mylookup_symbol (sh_name, top_stack->cur_block,
+ VAR_NAMESPACE, LOC_BLOCK);
+
+ if (s != 0)
+ {
+ b = SYMBOL_BLOCK_VALUE (s);
+ }
+ else
+ {
+ complain (&pdr_for_nonsymbol_complaint, sh_name);
+#if 1
+ return;
+#else
+/* FIXME -- delete. We can't do symbol allocation now; it's all done. */
+ s = new_symbol (sh_name);
+ SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
+ SYMBOL_CLASS (s) = LOC_BLOCK;
+ /* Donno its type, hope int is ok */
+ SYMBOL_TYPE (s) = lookup_function_type (mdebug_type_int);
+ add_symbol (s, top_stack->cur_block);
+ /* Wont have symbols for this one */
+ b = new_block (2);
+ SYMBOL_BLOCK_VALUE (s) = b;
+ BLOCK_FUNCTION (b) = s;
+ BLOCK_START (b) = pr->adr;
+ /* BOUND used to be the end of procedure's text, but the
+ argument is no longer passed in. */
+ BLOCK_END (b) = bound;
+ BLOCK_SUPERBLOCK (b) = top_stack->cur_block;
+ add_block (b, top_stack->cur_st);
+#endif
+ }
+
+ i = mylookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE, LOC_CONST);
+
+ if (i)
+ {
+ e = (struct mips_extra_func_info *) SYMBOL_VALUE (i);
+ e->pdr = *pr;
+ e->pdr.isym = (long) s;
+
+ /* GDB expects the absolute function start address for the
+ procedure descriptor in e->pdr.adr.
+ As the address in the procedure descriptor is usually relative,
+ we would have to relocate e->pdr.adr with cur_fdr->adr and
+ ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (pst->objfile)).
+ Unfortunately cur_fdr->adr and e->pdr.adr are both absolute
+ in shared libraries on some systems, and on other systems
+ e->pdr.adr is sometimes offset by a bogus value.
+ To work around these problems, we replace e->pdr.adr with
+ the start address of the function. */
+ e->pdr.adr = BLOCK_START (b);
+
+ /* Correct incorrect setjmp procedure descriptor from the library
+ to make backtrace through setjmp work. */
+ if (e->pdr.pcreg == 0 && STREQ (sh_name, "setjmp"))
+ {
+ complain (&bad_setjmp_pdr_complaint, 0);
+ e->pdr.pcreg = RA_REGNUM;
+ e->pdr.regmask = 0x80000000;
+ e->pdr.regoffset = -4;
+ }
+ }
+
+ /* It would be reasonable that functions that have been compiled
+ without debugging info have a btNil type for their return value,
+ and functions that are void and are compiled with debugging info
+ have btVoid.
+ gcc and DEC f77 put out btNil types for both cases, so btNil is mapped
+ to TYPE_CODE_VOID in parse_type to get the `compiled with debugging info'
+ case right.
+ The glevel field in cur_fdr could be used to determine the presence
+ of debugging info, but GCC doesn't always pass the -g switch settings
+ to the assembler and GAS doesn't set the glevel field from the -g switch
+ settings.
+ To work around these problems, the return value type of a TYPE_CODE_VOID
+ function is adjusted accordingly if no debugging info was found in the
+ compilation unit. */
+
+ if (processing_gcc_compilation == 0
+ && found_ecoff_debugging_info == 0
+ && TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (s))) == TYPE_CODE_VOID)
+ SYMBOL_TYPE (s) = nodebug_func_symbol_type;
+}
+
+/* Relocate the extra function info pointed to by the symbol table. */
+
+void
+ecoff_relocate_efi (struct symbol *sym, CORE_ADDR delta)
+{
+ struct mips_extra_func_info *e;
+
+ e = (struct mips_extra_func_info *) SYMBOL_VALUE (sym);
+
+ e->pdr.adr += delta;
+}
+
+/* Parse the external symbol ES. Just call parse_symbol() after
+ making sure we know where the aux are for it.
+ BIGEND says whether aux entries are big-endian or little-endian.
+
+ This routine clobbers top_stack->cur_block and ->cur_st. */
+
+static void parse_external (EXTR *, int, struct section_offsets *,
+ struct objfile *);
+
+static void
+parse_external (EXTR *es, int bigend, struct section_offsets *section_offsets,
+ struct objfile *objfile)
+{
+ union aux_ext *ax;
+
+ if (es->ifd != ifdNil)
+ {
+ cur_fd = es->ifd;
+ cur_fdr = debug_info->fdr + cur_fd;
+ ax = debug_info->external_aux + cur_fdr->iauxBase;
+ }
+ else
+ {
+ cur_fdr = debug_info->fdr;
+ ax = 0;
+ }
+
+ /* Reading .o files */
+ if (SC_IS_UNDEF (es->asym.sc) || es->asym.sc == scNil)
+ {
+ char *what;
+ switch (es->asym.st)
+ {
+ case stNil:
+ /* These are generated for static symbols in .o files,
+ ignore them. */
+ return;
+ case stStaticProc:
+ case stProc:
+ what = "procedure";
+ n_undef_procs++;
+ break;
+ case stGlobal:
+ what = "variable";
+ n_undef_vars++;
+ break;
+ case stLabel:
+ what = "label";
+ n_undef_labels++;
+ break;
+ default:
+ what = "symbol";
+ break;
+ }
+ n_undef_symbols++;
+ /* FIXME: Turn this into a complaint? */
+ if (info_verbose)
+ printf_filtered ("Warning: %s `%s' is undefined (in %s)\n",
+ what, debug_info->ssext + es->asym.iss,
+ fdr_name (cur_fdr));
+ return;
+ }
+
+ switch (es->asym.st)
+ {
+ case stProc:
+ case stStaticProc:
+ /* There is no need to parse the external procedure symbols.
+ If they are from objects compiled without -g, their index will
+ be indexNil, and the symbol definition from the minimal symbol
+ is preferrable (yielding a function returning int instead of int).
+ If the index points to a local procedure symbol, the local
+ symbol already provides the correct type.
+ Note that the index of the external procedure symbol points
+ to the local procedure symbol in the local symbol table, and
+ _not_ to the auxiliary symbol info. */
+ break;
+ case stGlobal:
+ case stLabel:
+ /* Global common symbols are resolved by the runtime loader,
+ ignore them. */
+ if (SC_IS_COMMON (es->asym.sc))
+ break;
+
+ /* Note that the case of a symbol with indexNil must be handled
+ anyways by parse_symbol(). */
+ parse_symbol (&es->asym, ax, (char *) NULL, bigend, section_offsets, objfile);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Parse the line number info for file descriptor FH into
+ GDB's linetable LT. MIPS' encoding requires a little bit
+ of magic to get things out. Note also that MIPS' line
+ numbers can go back and forth, apparently we can live
+ with that and do not need to reorder our linetables */
+
+static void parse_lines (FDR *, PDR *, struct linetable *, int,
+ struct partial_symtab *, CORE_ADDR);
+
+static void
+parse_lines (FDR *fh, PDR *pr, struct linetable *lt, int maxlines,
+ struct partial_symtab *pst, CORE_ADDR lowest_pdr_addr)
+{
+ unsigned char *base;
+ int j, k;
+ int delta, count, lineno = 0;
+
+ if (fh->cbLine == 0)
+ return;
+
+ /* Scan by procedure descriptors */
+ k = 0;
+ for (j = 0; j < fh->cpd; j++, pr++)
+ {
+ CORE_ADDR l;
+ CORE_ADDR adr;
+ unsigned char *halt;
+
+ /* No code for this one */
+ if (pr->iline == ilineNil ||
+ pr->lnLow == -1 || pr->lnHigh == -1)
+ continue;
+
+ /* Determine start and end address of compressed line bytes for
+ this procedure. */
+ base = debug_info->line + fh->cbLineOffset;
+ if (j != (fh->cpd - 1))
+ halt = base + pr[1].cbLineOffset;
+ else
+ halt = base + fh->cbLine;
+ base += pr->cbLineOffset;
+
+ adr = TEXTLOW (pst) + pr->adr - lowest_pdr_addr;
+
+ l = adr >> 2; /* in words */
+ for (lineno = pr->lnLow; base < halt;)
+ {
+ count = *base & 0x0f;
+ delta = *base++ >> 4;
+ if (delta >= 8)
+ delta -= 16;
+ if (delta == -8)
+ {
+ delta = (base[0] << 8) | base[1];
+ if (delta >= 0x8000)
+ delta -= 0x10000;
+ base += 2;
+ }
+ lineno += delta; /* first delta is 0 */
+
+ /* Complain if the line table overflows. Could happen
+ with corrupt binaries. */
+ if (lt->nitems >= maxlines)
+ {
+ complain (&bad_linetable_guess_complaint, fdr_name (fh));
+ break;
+ }
+ k = add_line (lt, lineno, l, k);
+ l += count + 1;
+ }
+ }
+}
+
+/* Master parsing procedure for first-pass reading of file symbols
+ into a partial_symtab. */
+
+static void
+parse_partial_symbols (struct objfile *objfile)
+{
+ const bfd_size_type external_sym_size = debug_swap->external_sym_size;
+ const bfd_size_type external_rfd_size = debug_swap->external_rfd_size;
+ const bfd_size_type external_ext_size = debug_swap->external_ext_size;
+ void (*const swap_ext_in) (bfd *, void *, EXTR *) = debug_swap->swap_ext_in;
+ void (*const swap_sym_in) (bfd *, void *, SYMR *) = debug_swap->swap_sym_in;
+ void (*const swap_rfd_in) (bfd *, void *, RFDT *) = debug_swap->swap_rfd_in;
+ int f_idx, s_idx;
+ HDRR *hdr = &debug_info->symbolic_header;
+ /* Running pointers */
+ FDR *fh;
+ char *ext_out;
+ char *ext_out_end;
+ EXTR *ext_block;
+ register EXTR *ext_in;
+ EXTR *ext_in_end;
+ SYMR sh;
+ struct partial_symtab *pst;
+ int textlow_not_set = 1;
+ int past_first_source_file = 0;
+
+ /* List of current psymtab's include files */
+ char **psymtab_include_list;
+ int includes_allocated;
+ int includes_used;
+ EXTR *extern_tab;
+ struct pst_map *fdr_to_pst;
+ /* Index within current psymtab dependency list */
+ struct partial_symtab **dependency_list;
+ int dependencies_used, dependencies_allocated;
+ struct cleanup *old_chain;
+ char *name;
+ enum language prev_language;
+ asection *text_sect;
+ int relocatable = 0;
+
+ /* Irix 5.2 shared libraries have a fh->adr field of zero, but
+ the shared libraries are prelinked at a high memory address.
+ We have to adjust the start address of the object file for this case,
+ by setting it to the start address of the first procedure in the file.
+ But we should do no adjustments if we are debugging a .o file, where
+ the text section (and fh->adr) really starts at zero. */
+ text_sect = bfd_get_section_by_name (cur_bfd, ".text");
+ if (text_sect != NULL
+ && (bfd_get_section_flags (cur_bfd, text_sect) & SEC_RELOC))
+ relocatable = 1;
+
+ extern_tab = (EXTR *) obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (EXTR) * hdr->iextMax);
+
+ includes_allocated = 30;
+ includes_used = 0;
+ psymtab_include_list = (char **) alloca (includes_allocated *
+ sizeof (char *));
+ next_symbol_text_func = mdebug_next_symbol_text;
+
+ dependencies_allocated = 30;
+ dependencies_used = 0;
+ dependency_list =
+ (struct partial_symtab **) alloca (dependencies_allocated *
+ sizeof (struct partial_symtab *));
+
+ last_source_file = NULL;
+
+ /*
+ * Big plan:
+ *
+ * Only parse the Local and External symbols, and the Relative FDR.
+ * Fixup enough of the loader symtab to be able to use it.
+ * Allocate space only for the file's portions we need to
+ * look at. (XXX)
+ */
+
+ max_gdbinfo = 0;
+ max_glevel = MIN_GLEVEL;
+
+ /* Allocate the map FDR -> PST.
+ Minor hack: -O3 images might claim some global data belongs
+ to FDR -1. We`ll go along with that */
+ fdr_to_pst = (struct pst_map *) xzalloc ((hdr->ifdMax + 1) * sizeof *fdr_to_pst);
+ old_chain = make_cleanup (xfree, fdr_to_pst);
+ fdr_to_pst++;
+ {
+ struct partial_symtab *pst = new_psymtab ("", objfile);
+ fdr_to_pst[-1].pst = pst;
+ FDR_IDX (pst) = -1;
+ }
+
+ /* Allocate the global pending list. */
+ pending_list =
+ ((struct mdebug_pending **)
+ obstack_alloc (&objfile->psymbol_obstack,
+ hdr->ifdMax * sizeof (struct mdebug_pending *)));
+ memset (pending_list, 0,
+ hdr->ifdMax * sizeof (struct mdebug_pending *));
+
+ /* Pass 0 over external syms: swap them in. */
+ ext_block = (EXTR *) xmalloc (hdr->iextMax * sizeof (EXTR));
+ make_cleanup (xfree, ext_block);
+
+ ext_out = (char *) debug_info->external_ext;
+ ext_out_end = ext_out + hdr->iextMax * external_ext_size;
+ ext_in = ext_block;
+ for (; ext_out < ext_out_end; ext_out += external_ext_size, ext_in++)
+ (*swap_ext_in) (cur_bfd, ext_out, ext_in);
+
+ /* Pass 1 over external syms: Presize and partition the list */
+ ext_in = ext_block;
+ ext_in_end = ext_in + hdr->iextMax;
+ for (; ext_in < ext_in_end; ext_in++)
+ {
+ /* See calls to complain below. */
+ if (ext_in->ifd >= -1
+ && ext_in->ifd < hdr->ifdMax
+ && ext_in->asym.iss >= 0
+ && ext_in->asym.iss < hdr->issExtMax)
+ fdr_to_pst[ext_in->ifd].n_globals++;
+ }
+
+ /* Pass 1.5 over files: partition out global symbol space */
+ s_idx = 0;
+ for (f_idx = -1; f_idx < hdr->ifdMax; f_idx++)
+ {
+ fdr_to_pst[f_idx].globals_offset = s_idx;
+ s_idx += fdr_to_pst[f_idx].n_globals;
+ fdr_to_pst[f_idx].n_globals = 0;
+ }
+
+ /* ECOFF in ELF:
+
+ For ECOFF in ELF, we skip the creation of the minimal symbols.
+ The ECOFF symbols should be a subset of the Elf symbols, and the
+ section information of the elf symbols will be more accurate.
+ FIXME! What about Irix 5's native linker?
+
+ By default, Elf sections which don't exist in ECOFF
+ get put in ECOFF's absolute section by the gnu linker.
+ Since absolute sections don't get relocated, we
+ end up calculating an address different from that of
+ the symbol's minimal symbol (created earlier from the
+ Elf symtab).
+
+ To fix this, either :
+ 1) don't create the duplicate symbol
+ (assumes ECOFF symtab is a subset of the ELF symtab;
+ assumes no side-effects result from ignoring ECOFF symbol)
+ 2) create it, only if lookup for existing symbol in ELF's minimal
+ symbols fails
+ (inefficient;
+ assumes no side-effects result from ignoring ECOFF symbol)
+ 3) create it, but lookup ELF's minimal symbol and use it's section
+ during relocation, then modify "uniqify" phase to merge and
+ eliminate the duplicate symbol
+ (highly inefficient)
+
+ I've implemented #1 here...
+ Skip the creation of the minimal symbols based on the ECOFF
+ symbol table. */
+
+ /* Pass 2 over external syms: fill in external symbols */
+ ext_in = ext_block;
+ ext_in_end = ext_in + hdr->iextMax;
+ for (; ext_in < ext_in_end; ext_in++)
+ {
+ enum minimal_symbol_type ms_type = mst_text;
+ CORE_ADDR svalue = ext_in->asym.value;
+
+ /* The Irix 5 native tools seem to sometimes generate bogus
+ external symbols. */
+ if (ext_in->ifd < -1 || ext_in->ifd >= hdr->ifdMax)
+ {
+ complain (&bad_ext_ifd_complaint, ext_in->ifd, hdr->ifdMax);
+ continue;
+ }
+ if (ext_in->asym.iss < 0 || ext_in->asym.iss >= hdr->issExtMax)
+ {
+ complain (&bad_ext_iss_complaint, ext_in->asym.iss,
+ hdr->issExtMax);
+ continue;
+ }
+
+ extern_tab[fdr_to_pst[ext_in->ifd].globals_offset
+ + fdr_to_pst[ext_in->ifd].n_globals++] = *ext_in;
+
+
+ if (SC_IS_UNDEF (ext_in->asym.sc) || ext_in->asym.sc == scNil)
+ continue;
+
+
+ /* Pass 3 over files, over local syms: fill in static symbols */
+ name = debug_info->ssext + ext_in->asym.iss;
+
+ /* Process ECOFF Symbol Types and Storage Classes */
+ switch (ext_in->asym.st)
+ {
+ case stProc:
+ /* Beginnning of Procedure */
+ svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ break;
+ case stStaticProc:
+ /* Load time only static procs */
+ ms_type = mst_file_text;
+ svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ break;
+ case stGlobal:
+ /* External symbol */
+ if (SC_IS_COMMON (ext_in->asym.sc))
+ {
+ /* The value of a common symbol is its size, not its address.
+ Ignore it. */
+ continue;
+ }
+ else if (SC_IS_DATA (ext_in->asym.sc))
+ {
+ ms_type = mst_data;
+ svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ }
+ else if (SC_IS_BSS (ext_in->asym.sc))
+ {
+ ms_type = mst_bss;
+ svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+ }
+ else if (SC_IS_SBSS (ext_in->asym.sc))
+ {
+ ms_type = mst_bss;
+ svalue += ANOFFSET (objfile->section_offsets,
+ get_section_index (objfile, ".sbss"));
+ }
+ else
+ ms_type = mst_abs;
+ break;
+ case stLabel:
+ /* Label */
+
+ /* On certain platforms, some extra label symbols can be
+ generated by the linker. One possible usage for this kind
+ of symbols is to represent the address of the begining of a
+ given section. For instance, on Tru64 5.1, the address of
+ the _ftext label is the start address of the .text section.
+
+ The storage class of these symbols is usually directly
+ related to the section to which the symbol refers. For
+ instance, on Tru64 5.1, the storage class for the _fdata
+ label is scData, refering to the .data section.
+
+ It is actually possible that the section associated to the
+ storage class of the label does not exist. On True64 5.1
+ for instance, the libm.so shared library does not contain
+ any .data section, although it contains a _fpdata label
+ which storage class is scData... Since these symbols are
+ usually useless for the debugger user anyway, we just
+ discard these symbols.
+ */
+
+ if (SC_IS_TEXT (ext_in->asym.sc))
+ {
+ if (objfile->sect_index_text == -1)
+ continue;
+
+ ms_type = mst_file_text;
+ svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ }
+ else if (SC_IS_DATA (ext_in->asym.sc))
+ {
+ if (objfile->sect_index_data == -1)
+ continue;
+
+ ms_type = mst_file_data;
+ svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ }
+ else if (SC_IS_BSS (ext_in->asym.sc))
+ {
+ if (objfile->sect_index_bss == -1)
+ continue;
+
+ ms_type = mst_file_bss;
+ svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+ }
+ else if (SC_IS_SBSS (ext_in->asym.sc))
+ {
+ const int sbss_sect_index = get_section_index (objfile, ".sbss");
+
+ if (sbss_sect_index == -1)
+ continue;
+
+ ms_type = mst_file_bss;
+ svalue += ANOFFSET (objfile->section_offsets, sbss_sect_index);
+ }
+ else
+ ms_type = mst_abs;
+ break;
+ case stLocal:
+ case stNil:
+ /* The alpha has the section start addresses in stLocal symbols
+ whose name starts with a `.'. Skip those but complain for all
+ other stLocal symbols.
+ Irix6 puts the section start addresses in stNil symbols, skip
+ those too. */
+ if (name[0] == '.')
+ continue;
+ /* Fall through. */
+ default:
+ ms_type = mst_unknown;
+ complain (&unknown_ext_complaint, name);
+ }
+ if (!ECOFF_IN_ELF (cur_bfd))
+ prim_record_minimal_symbol (name, svalue, ms_type, objfile);
+ }
+
+ /* Pass 3 over files, over local syms: fill in static symbols */
+ for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++)
+ {
+ struct partial_symtab *save_pst;
+ EXTR *ext_ptr;
+ CORE_ADDR textlow;
+
+ cur_fdr = fh = debug_info->fdr + f_idx;
+
+ if (fh->csym == 0)
+ {
+ fdr_to_pst[f_idx].pst = NULL;
+ continue;
+ }
+
+ /* Determine the start address for this object file from the
+ file header and relocate it, except for Irix 5.2 zero fh->adr. */
+ if (fh->cpd)
+ {
+ textlow = fh->adr;
+ if (relocatable || textlow != 0)
+ textlow += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ }
+ else
+ textlow = 0;
+ pst = start_psymtab_common (objfile, objfile->section_offsets,
+ fdr_name (fh),
+ textlow,
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ pst->read_symtab_private = ((char *)
+ obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct symloc)));
+ memset (pst->read_symtab_private, 0, sizeof (struct symloc));
+
+ save_pst = pst;
+ TEXTLOW (pst) = pst->textlow;
+ TEXTHIGH (pst) = pst->texthigh;
+ FDR_IDX (pst) = f_idx;
+ CUR_BFD (pst) = cur_bfd;
+ DEBUG_SWAP (pst) = debug_swap;
+ DEBUG_INFO (pst) = debug_info;
+ PENDING_LIST (pst) = pending_list;
+
+ /* The way to turn this into a symtab is to call... */
+ pst->read_symtab = mdebug_psymtab_to_symtab;
+
+ /* Set up language for the pst.
+ The language from the FDR is used if it is unambigious (e.g. cfront
+ with native cc and g++ will set the language to C).
+ Otherwise we have to deduce the language from the filename.
+ Native ecoff has every header file in a separate FDR, so
+ deduce_language_from_filename will return language_unknown for
+ a header file, which is not what we want.
+ But the FDRs for the header files are after the FDR for the source
+ file, so we can assign the language of the source file to the
+ following header files. Then we save the language in the private
+ pst data so that we can reuse it when building symtabs. */
+ prev_language = psymtab_language;
+
+ switch (fh->lang)
+ {
+ case langCplusplusV2:
+ psymtab_language = language_cplus;
+ break;
+ default:
+ psymtab_language = deduce_language_from_filename (fdr_name (fh));
+ break;
+ }
+ if (psymtab_language == language_unknown)
+ psymtab_language = prev_language;
+ PST_PRIVATE (pst)->pst_language = psymtab_language;
+
+ TEXTHIGH (pst) = TEXTLOW (pst);
+
+ /* For stabs-in-ecoff files, the second symbol must be @stab.
+ This symbol is emitted by mips-tfile to signal that the
+ current object file uses encapsulated stabs instead of mips
+ ecoff for local symbols. (It is the second symbol because
+ the first symbol is the stFile used to signal the start of a
+ file). */
+ processing_gcc_compilation = 0;
+ if (fh->csym >= 2)
+ {
+ (*swap_sym_in) (cur_bfd,
+ ((char *) debug_info->external_sym
+ + (fh->isymBase + 1) * external_sym_size),
+ &sh);
+ if (STREQ (debug_info->ss + fh->issBase + sh.iss, stabs_symbol))
+ processing_gcc_compilation = 2;
+ }
+
+ if (processing_gcc_compilation != 0)
+ {
+ for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++)
+ {
+ int type_code;
+ char *namestring;
+
+ (*swap_sym_in) (cur_bfd,
+ (((char *) debug_info->external_sym)
+ + (fh->isymBase + cur_sdx) * external_sym_size),
+ &sh);
+ type_code = ECOFF_UNMARK_STAB (sh.index);
+ if (!ECOFF_IS_STAB (&sh))
+ {
+ if (sh.st == stProc || sh.st == stStaticProc)
+ {
+ CORE_ADDR procaddr;
+ long isym;
+
+ sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ if (sh.st == stStaticProc)
+ {
+ namestring = debug_info->ss + fh->issBase + sh.iss;
+ prim_record_minimal_symbol_and_info (namestring,
+ sh.value,
+ mst_file_text,
+ NULL,
+ SECT_OFF_TEXT (objfile),
+ NULL,
+ objfile);
+ }
+ procaddr = sh.value;
+
+ isym = AUX_GET_ISYM (fh->fBigendian,
+ (debug_info->external_aux
+ + fh->iauxBase
+ + sh.index));
+ (*swap_sym_in) (cur_bfd,
+ ((char *) debug_info->external_sym
+ + ((fh->isymBase + isym - 1)
+ * external_sym_size)),
+ &sh);
+ if (sh.st == stEnd)
+ {
+ CORE_ADDR high = procaddr + sh.value;
+
+ /* Kludge for Irix 5.2 zero fh->adr. */
+ if (!relocatable
+ && (TEXTLOW (pst) == 0 || procaddr < TEXTLOW (pst)))
+ TEXTLOW (pst) = procaddr;
+ if (high > TEXTHIGH (pst))
+ TEXTHIGH (pst) = high;
+ }
+ }
+ else if (sh.st == stStatic)
+ {
+ switch (sh.sc)
+ {
+ case scUndefined:
+ case scSUndefined:
+ case scNil:
+ case scAbs:
+ break;
+
+ case scData:
+ case scSData:
+ case scRData:
+ case scPData:
+ case scXData:
+ namestring = debug_info->ss + fh->issBase + sh.iss;
+ sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ prim_record_minimal_symbol_and_info (namestring,
+ sh.value,
+ mst_file_data,
+ NULL,
+ SECT_OFF_DATA (objfile),
+ NULL,
+ objfile);
+ break;
+
+ default:
+ /* FIXME! Shouldn't this use cases for bss,
+ then have the default be abs? */
+ namestring = debug_info->ss + fh->issBase + sh.iss;
+ sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+ prim_record_minimal_symbol_and_info (namestring,
+ sh.value,
+ mst_file_bss,
+ NULL,
+ SECT_OFF_BSS (objfile),
+ NULL,
+ objfile);
+ break;
+ }
+ }
+ continue;
+ }
+ /* Handle stabs continuation */
+ {
+ char *stabstring = debug_info->ss + fh->issBase + sh.iss;
+ int len = strlen (stabstring);
+ while (stabstring[len - 1] == '\\')
+ {
+ SYMR sh2;
+ char *stabstring1 = stabstring;
+ char *stabstring2;
+ int len2;
+
+ /* Ignore continuation char from 1st string */
+ len--;
+
+ /* Read next stabstring */
+ cur_sdx++;
+ (*swap_sym_in) (cur_bfd,
+ (((char *) debug_info->external_sym)
+ + (fh->isymBase + cur_sdx)
+ * external_sym_size),
+ &sh2);
+ stabstring2 = debug_info->ss + fh->issBase + sh2.iss;
+ len2 = strlen (stabstring2);
+
+ /* Concatinate stabstring2 with stabstring1 */
+ if (stabstring
+ && stabstring != debug_info->ss + fh->issBase + sh.iss)
+ stabstring = xrealloc (stabstring, len + len2 + 1);
+ else
+ {
+ stabstring = xmalloc (len + len2 + 1);
+ strcpy (stabstring, stabstring1);
+ }
+ strcpy (stabstring + len, stabstring2);
+ len += len2;
+ }
+
+ switch (type_code)
+ {
+ static struct complaint function_outside_compilation_unit = {
+ "function `%s' appears to be defined outside of all compilation units", 0, 0
+ };
+ char *p;
+ /*
+ * Standard, external, non-debugger, symbols
+ */
+
+ case N_TEXT | N_EXT:
+ case N_NBTEXT | N_EXT:
+ sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ goto record_it;
+
+ case N_DATA | N_EXT:
+ case N_NBDATA | N_EXT:
+ sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ goto record_it;
+
+ case N_BSS:
+ case N_BSS | N_EXT:
+ case N_NBBSS | N_EXT:
+ case N_SETV | N_EXT: /* FIXME, is this in BSS? */
+ sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+ goto record_it;
+
+ case N_ABS | N_EXT:
+ record_it:
+ continue;
+
+ /* Standard, local, non-debugger, symbols */
+
+ case N_NBTEXT:
+
+ /* We need to be able to deal with both N_FN or N_TEXT,
+ because we have no way of knowing whether the sys-supplied ld
+ or GNU ld was used to make the executable. Sequents throw
+ in another wrinkle -- they renumbered N_FN. */
+
+ case N_FN:
+ case N_FN_SEQ:
+ case N_TEXT:
+ continue;
+
+ case N_DATA:
+ sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ goto record_it;
+
+ case N_UNDF | N_EXT:
+ continue; /* Just undefined, not COMMON */
+
+ case N_UNDF:
+ continue;
+
+ /* Lots of symbol types we can just ignore. */
+
+ case N_ABS:
+ case N_NBDATA:
+ case N_NBBSS:
+ continue;
+
+ /* Keep going . . . */
+
+ /*
+ * Special symbol types for GNU
+ */
+ case N_INDR:
+ case N_INDR | N_EXT:
+ case N_SETA:
+ case N_SETA | N_EXT:
+ case N_SETT:
+ case N_SETT | N_EXT:
+ case N_SETD:
+ case N_SETD | N_EXT:
+ case N_SETB:
+ case N_SETB | N_EXT:
+ case N_SETV:
+ continue;
+
+ /*
+ * Debugger symbols
+ */
+
+ case N_SO:
+ {
+ CORE_ADDR valu;
+ static int prev_so_symnum = -10;
+ static int first_so_symnum;
+ char *p;
+ int prev_textlow_not_set;
+
+ valu = sh.value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+ prev_textlow_not_set = textlow_not_set;
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ /* A zero value is probably an indication for the SunPRO 3.0
+ compiler. end_psymtab explicitly tests for zero, so
+ don't relocate it. */
+
+ if (sh.value == 0)
+ {
+ textlow_not_set = 1;
+ valu = 0;
+ }
+ else
+ textlow_not_set = 0;
+#else
+ textlow_not_set = 0;
+#endif
+ past_first_source_file = 1;
+
+ if (prev_so_symnum != symnum - 1)
+ { /* Here if prev stab wasn't N_SO */
+ first_so_symnum = symnum;
+
+ if (pst)
+ {
+ pst = (struct partial_symtab *) 0;
+ includes_used = 0;
+ dependencies_used = 0;
+ }
+ }
+
+ prev_so_symnum = symnum;
+
+ /* End the current partial symtab and start a new one */
+
+ /* SET_NAMESTRING ();*/
+ namestring = stabstring;
+
+ /* Null name means end of .o file. Don't start a new one. */
+ if (*namestring == '\000')
+ continue;
+
+ /* Some compilers (including gcc) emit a pair of initial N_SOs.
+ The first one is a directory name; the second the file name.
+ If pst exists, is empty, and has a filename ending in '/',
+ we assume the previous N_SO was a directory name. */
+
+ p = strrchr (namestring, '/');
+ if (p && *(p + 1) == '\000')
+ continue; /* Simply ignore directory name SOs */
+
+ /* Some other compilers (C++ ones in particular) emit useless
+ SOs for non-existant .c files. We ignore all subsequent SOs that
+ immediately follow the first. */
+
+ if (!pst)
+ pst = save_pst;
+ continue;
+ }
+
+ case N_BINCL:
+ continue;
+
+ case N_SOL:
+ {
+ enum language tmp_language;
+ /* Mark down an include file in the current psymtab */
+
+ /* SET_NAMESTRING ();*/
+ namestring = stabstring;
+
+ tmp_language = deduce_language_from_filename (namestring);
+
+ /* Only change the psymtab's language if we've learned
+ something useful (eg. tmp_language is not language_unknown).
+ In addition, to match what start_subfile does, never change
+ from C++ to C. */
+ if (tmp_language != language_unknown
+ && (tmp_language != language_c
+ || psymtab_language != language_cplus))
+ psymtab_language = tmp_language;
+
+ /* In C++, one may expect the same filename to come round many
+ times, when code is coming alternately from the main file
+ and from inline functions in other files. So I check to see
+ if this is a file we've seen before -- either the main
+ source file, or a previously included file.
+
+ This seems to be a lot of time to be spending on N_SOL, but
+ things like "break c-exp.y:435" need to work (I
+ suppose the psymtab_include_list could be hashed or put
+ in a binary tree, if profiling shows this is a major hog). */
+ if (pst && STREQ (namestring, pst->filename))
+ continue;
+ {
+ register int i;
+ for (i = 0; i < includes_used; i++)
+ if (STREQ (namestring, psymtab_include_list[i]))
+ {
+ i = -1;
+ break;
+ }
+ if (i == -1)
+ continue;
+ }
+
+ psymtab_include_list[includes_used++] = namestring;
+ if (includes_used >= includes_allocated)
+ {
+ char **orig = psymtab_include_list;
+
+ psymtab_include_list = (char **)
+ alloca ((includes_allocated *= 2) *
+ sizeof (char *));
+ memcpy ((PTR) psymtab_include_list, (PTR) orig,
+ includes_used * sizeof (char *));
+ }
+ continue;
+ }
+ case N_LSYM: /* Typedef or automatic variable. */
+ case N_STSYM: /* Data seg var -- static */
+ case N_LCSYM: /* BSS " */
+ case N_ROSYM: /* Read-only data seg var -- static. */
+ case N_NBSTS: /* Gould nobase. */
+ case N_NBLCS: /* symbols. */
+ case N_FUN:
+ case N_GSYM: /* Global (extern) variable; can be
+ data or bss (sigh FIXME). */
+
+ /* Following may probably be ignored; I'll leave them here
+ for now (until I do Pascal and Modula 2 extensions). */
+
+ case N_PC: /* I may or may not need this; I
+ suspect not. */
+ case N_M2C: /* I suspect that I can ignore this here. */
+ case N_SCOPE: /* Same. */
+
+ /* SET_NAMESTRING ();*/
+ namestring = stabstring;
+ p = (char *) strchr (namestring, ':');
+ if (!p)
+ continue; /* Not a debugging symbol. */
+
+
+
+ /* Main processing section for debugging symbols which
+ the initial read through the symbol tables needs to worry
+ about. If we reach this point, the symbol which we are
+ considering is definitely one we are interested in.
+ p must also contain the (valid) index into the namestring
+ which indicates the debugging type symbol. */
+
+ switch (p[1])
+ {
+ case 'S':
+ sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+#ifdef STATIC_TRANSFORM_NAME
+ namestring = STATIC_TRANSFORM_NAME (namestring);
+#endif
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->static_psymbols,
+ 0, sh.value,
+ psymtab_language, objfile);
+ continue;
+ case 'G':
+ sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ /* The addresses in these entries are reported to be
+ wrong. See the code that reads 'G's for symtabs. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->global_psymbols,
+ 0, sh.value,
+ psymtab_language, objfile);
+ continue;
+
+ case 'T':
+ /* When a 'T' entry is defining an anonymous enum, it
+ may have a name which is the empty string, or a
+ single space. Since they're not really defining a
+ symbol, those shouldn't go in the partial symbol
+ table. We do pick up the elements of such enums at
+ 'check_enum:', below. */
+ if (p >= namestring + 2
+ || (p == namestring + 1
+ && namestring[0] != ' '))
+ {
+ add_psymbol_to_list (namestring, p - namestring,
+ STRUCT_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ sh.value, 0,
+ psymtab_language, objfile);
+ if (p[2] == 't')
+ {
+ /* Also a typedef with the same name. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ sh.value, 0,
+ psymtab_language, objfile);
+ p += 1;
+ }
+ /* The semantics of C++ state that "struct foo { ... }"
+ also defines a typedef for "foo". Unfortuantely, cfront
+ never makes the typedef when translating from C++ to C.
+ We make the typedef here so that "ptype foo" works as
+ expected for cfront translated code. */
+ else if (psymtab_language == language_cplus)
+ {
+ /* Also a typedef with the same name. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ sh.value, 0,
+ psymtab_language, objfile);
+ }
+ }
+ goto check_enum;
+ case 't':
+ if (p != namestring) /* a name is there, not just :T... */
+ {
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ sh.value, 0,
+ psymtab_language, objfile);
+ }
+ check_enum:
+ /* If this is an enumerated type, we need to
+ add all the enum constants to the partial symbol
+ table. This does not cover enums without names, e.g.
+ "enum {a, b} c;" in C, but fortunately those are
+ rare. There is no way for GDB to find those from the
+ enum type without spending too much time on it. Thus
+ to solve this problem, the compiler needs to put out the
+ enum in a nameless type. GCC2 does this. */
+
+ /* We are looking for something of the form
+ <name> ":" ("t" | "T") [<number> "="] "e"
+ {<constant> ":" <value> ","} ";". */
+
+ /* Skip over the colon and the 't' or 'T'. */
+ p += 2;
+ /* This type may be given a number. Also, numbers can come
+ in pairs like (0,26). Skip over it. */
+ while ((*p >= '0' && *p <= '9')
+ || *p == '(' || *p == ',' || *p == ')'
+ || *p == '=')
+ p++;
+
+ if (*p++ == 'e')
+ {
+ /* The aix4 compiler emits extra crud before the members. */
+ if (*p == '-')
+ {
+ /* Skip over the type (?). */
+ while (*p != ':')
+ p++;
+
+ /* Skip over the colon. */
+ p++;
+ }
+
+ /* We have found an enumerated type. */
+ /* According to comments in read_enum_type
+ a comma could end it instead of a semicolon.
+ I don't know where that happens.
+ Accept either. */
+ while (*p && *p != ';' && *p != ',')
+ {
+ char *q;
+
+ /* Check for and handle cretinous dbx symbol name
+ continuation! */
+ if (*p == '\\' || (*p == '?' && p[1] == '\0'))
+ p = next_symbol_text (objfile);
+
+ /* Point to the character after the name
+ of the enum constant. */
+ for (q = p; *q && *q != ':'; q++)
+ ;
+ /* Note that the value doesn't matter for
+ enum constants in psymtabs, just in symtabs. */
+ add_psymbol_to_list (p, q - p,
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols, 0,
+ 0, psymtab_language, objfile);
+ /* Point past the name. */
+ p = q;
+ /* Skip over the value. */
+ while (*p && *p != ',')
+ p++;
+ /* Advance past the comma. */
+ if (*p)
+ p++;
+ }
+ }
+ continue;
+ case 'c':
+ /* Constant, e.g. from "const" in Pascal. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols, sh.value,
+ 0, psymtab_language, objfile);
+ continue;
+
+ case 'f':
+ if (! pst)
+ {
+ int name_len = p - namestring;
+ char *name = xmalloc (name_len + 1);
+ memcpy (name, namestring, name_len);
+ name[name_len] = '\0';
+ complain (&function_outside_compilation_unit, name);
+ xfree (name);
+ }
+ sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->static_psymbols,
+ 0, sh.value,
+ psymtab_language, objfile);
+ continue;
+
+ /* Global functions were ignored here, but now they
+ are put into the global psymtab like one would expect.
+ They're also in the minimal symbol table. */
+ case 'F':
+ if (! pst)
+ {
+ int name_len = p - namestring;
+ char *name = xmalloc (name_len + 1);
+ memcpy (name, namestring, name_len);
+ name[name_len] = '\0';
+ complain (&function_outside_compilation_unit, name);
+ xfree (name);
+ }
+ sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->global_psymbols,
+ 0, sh.value,
+ psymtab_language, objfile);
+ continue;
+
+ /* Two things show up here (hopefully); static symbols of
+ local scope (static used inside braces) or extensions
+ of structure symbols. We can ignore both. */
+ case 'V':
+ case '(':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ case '#': /* for symbol identification (used in live ranges) */
+ /* added to support cfront stabs strings */
+ case 'Z': /* for definition continuations */
+ case 'P': /* for prototypes */
+ continue;
+
+ case ':':
+ /* It is a C++ nested symbol. We don't need to record it
+ (I don't think); if we try to look up foo::bar::baz,
+ then symbols for the symtab containing foo should get
+ read in, I think. */
+ /* Someone says sun cc puts out symbols like
+ /foo/baz/maclib::/usr/local/bin/maclib,
+ which would get here with a symbol type of ':'. */
+ continue;
+
+ default:
+ /* Unexpected symbol descriptor. The second and subsequent stabs
+ of a continued stab can show up here. The question is
+ whether they ever can mimic a normal stab--it would be
+ nice if not, since we certainly don't want to spend the
+ time searching to the end of every string looking for
+ a backslash. */
+
+ complain (&unknown_symchar_complaint, p[1]);
+
+ /* Ignore it; perhaps it is an extension that we don't
+ know about. */
+ continue;
+ }
+
+ case N_EXCL:
+ continue;
+
+ case N_ENDM:
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ /* Solaris 2 end of module, finish current partial symbol table.
+ END_PSYMTAB will set TEXTHIGH (pst) to the proper value, which
+ is necessary if a module compiled without debugging info
+ follows this module. */
+ if (pst)
+ {
+ pst = (struct partial_symtab *) 0;
+ includes_used = 0;
+ dependencies_used = 0;
+ }
+#endif
+ continue;
+
+ case N_RBRAC:
+ if (sh.value > TEXTHIGH (save_pst))
+ TEXTHIGH (save_pst) = sh.value;
+ continue;
+ case N_EINCL:
+ case N_DSLINE:
+ case N_BSLINE:
+ case N_SSYM: /* Claim: Structure or union element.
+ Hopefully, I can ignore this. */
+ case N_ENTRY: /* Alternate entry point; can ignore. */
+ case N_MAIN: /* Can definitely ignore this. */
+ case N_CATCH: /* These are GNU C++ extensions */
+ case N_EHDECL: /* that can safely be ignored here. */
+ case N_LENG:
+ case N_BCOMM:
+ case N_ECOMM:
+ case N_ECOML:
+ case N_FNAME:
+ case N_SLINE:
+ case N_RSYM:
+ case N_PSYM:
+ case N_LBRAC:
+ case N_NSYMS: /* Ultrix 4.0: symbol count */
+ case N_DEFD: /* GNU Modula-2 */
+ case N_ALIAS: /* SunPro F77: alias name, ignore for now. */
+
+ case N_OBJ: /* useless types from Solaris */
+ case N_OPT:
+ /* These symbols aren't interesting; don't worry about them */
+
+ continue;
+
+ default:
+ /* If we haven't found it yet, ignore it. It's probably some
+ new type we don't know about yet. */
+ complain (&unknown_symtype_complaint,
+ local_hex_string (type_code)); /*CUR_SYMBOL_TYPE*/
+ continue;
+ }
+ if (stabstring
+ && stabstring != debug_info->ss + fh->issBase + sh.iss)
+ xfree (stabstring);
+ }
+ /* end - Handle continuation */
+ }
+ }
+ else
+ {
+ for (cur_sdx = 0; cur_sdx < fh->csym;)
+ {
+ char *name;
+ enum address_class class;
+
+ (*swap_sym_in) (cur_bfd,
+ ((char *) debug_info->external_sym
+ + ((fh->isymBase + cur_sdx)
+ * external_sym_size)),
+ &sh);
+
+ if (ECOFF_IS_STAB (&sh))
+ {
+ cur_sdx++;
+ continue;
+ }
+
+ /* Non absolute static symbols go into the minimal table. */
+ if (SC_IS_UNDEF (sh.sc) || sh.sc == scNil
+ || (sh.index == indexNil
+ && (sh.st != stStatic || sh.sc == scAbs)))
+ {
+ /* FIXME, premature? */
+ cur_sdx++;
+ continue;
+ }
+
+ name = debug_info->ss + fh->issBase + sh.iss;
+
+ switch (sh.sc)
+ {
+ case scText:
+ case scRConst:
+ /* The value of a stEnd symbol is the displacement from the
+ corresponding start symbol value, do not relocate it. */
+ if (sh.st != stEnd)
+ sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ break;
+ case scData:
+ case scSData:
+ case scRData:
+ case scPData:
+ case scXData:
+ sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ break;
+ case scBss:
+ case scSBss:
+ sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+ break;
+ }
+
+ switch (sh.st)
+ {
+ CORE_ADDR high;
+ CORE_ADDR procaddr;
+ int new_sdx;
+
+ case stStaticProc:
+ prim_record_minimal_symbol_and_info (name, sh.value,
+ mst_file_text, NULL,
+ SECT_OFF_TEXT (objfile), NULL,
+ objfile);
+
+ /* FALLTHROUGH */
+
+ case stProc:
+ /* Usually there is a local and a global stProc symbol
+ for a function. This means that the function name
+ has already been entered into the mimimal symbol table
+ while processing the global symbols in pass 2 above.
+ One notable exception is the PROGRAM name from
+ f77 compiled executables, it is only put out as
+ local stProc symbol, and a global MAIN__ stProc symbol
+ points to it. It doesn't matter though, as gdb is
+ still able to find the PROGRAM name via the partial
+ symbol table, and the MAIN__ symbol via the minimal
+ symbol table. */
+ if (sh.st == stProc)
+ add_psymbol_to_list (name, strlen (name),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->global_psymbols,
+ 0, sh.value, psymtab_language, objfile);
+ else
+ add_psymbol_to_list (name, strlen (name),
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->static_psymbols,
+ 0, sh.value, psymtab_language, objfile);
+
+ /* Skip over procedure to next one. */
+ if (sh.index >= hdr->iauxMax)
+ {
+ /* Should not happen, but does when cross-compiling
+ with the MIPS compiler. FIXME -- pull later. */
+ complain (&index_complaint, name);
+ new_sdx = cur_sdx + 1; /* Don't skip at all */
+ }
+ else
+ new_sdx = AUX_GET_ISYM (fh->fBigendian,
+ (debug_info->external_aux
+ + fh->iauxBase
+ + sh.index));
+ procaddr = sh.value;
+
+ if (new_sdx <= cur_sdx)
+ {
+ /* This should not happen either... FIXME. */
+ complain (&aux_index_complaint, name);
+ new_sdx = cur_sdx + 1; /* Don't skip backward */
+ }
+
+ cur_sdx = new_sdx;
+ (*swap_sym_in) (cur_bfd,
+ ((char *) debug_info->external_sym
+ + ((fh->isymBase + cur_sdx - 1)
+ * external_sym_size)),
+ &sh);
+ if (sh.st != stEnd)
+ continue;
+
+ /* Kludge for Irix 5.2 zero fh->adr. */
+ if (!relocatable
+ && (TEXTLOW (pst) == 0 || procaddr < TEXTLOW (pst)))
+ TEXTLOW (pst) = procaddr;
+
+ high = procaddr + sh.value;
+ if (high > TEXTHIGH (pst))
+ TEXTHIGH (pst) = high;
+ continue;
+
+ case stStatic: /* Variable */
+ if (SC_IS_DATA (sh.sc))
+ prim_record_minimal_symbol_and_info (name, sh.value,
+ mst_file_data, NULL,
+ SECT_OFF_DATA (objfile),
+ NULL,
+ objfile);
+ else
+ prim_record_minimal_symbol_and_info (name, sh.value,
+ mst_file_bss, NULL,
+ SECT_OFF_BSS (objfile),
+ NULL,
+ objfile);
+ class = LOC_STATIC;
+ break;
+
+ case stIndirect: /* Irix5 forward declaration */
+ /* Skip forward declarations from Irix5 cc */
+ goto skip;
+
+ case stTypedef: /* Typedef */
+ /* Skip typedefs for forward declarations and opaque
+ structs from alpha and mips cc. */
+ if (sh.iss == 0 || has_opaque_xref (fh, &sh))
+ goto skip;
+ class = LOC_TYPEDEF;
+ break;
+
+ case stConstant: /* Constant decl */
+ class = LOC_CONST;
+ break;
+
+ case stUnion:
+ case stStruct:
+ case stEnum:
+ case stBlock: /* { }, str, un, enum */
+ /* Do not create a partial symbol for cc unnamed aggregates
+ and gcc empty aggregates. */
+ if ((sh.sc == scInfo
+ || SC_IS_COMMON (sh.sc))
+ && sh.iss != 0
+ && sh.index != cur_sdx + 2)
+ {
+ add_psymbol_to_list (name, strlen (name),
+ STRUCT_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0,
+ psymtab_language, objfile);
+ }
+ handle_psymbol_enumerators (objfile, fh, sh.st, sh.value);
+
+ /* Skip over the block */
+ new_sdx = sh.index;
+ if (new_sdx <= cur_sdx)
+ {
+ /* This happens with the Ultrix kernel. */
+ complain (&block_index_complaint, name);
+ new_sdx = cur_sdx + 1; /* Don't skip backward */
+ }
+ cur_sdx = new_sdx;
+ continue;
+
+ case stFile: /* File headers */
+ case stLabel: /* Labels */
+ case stEnd: /* Ends of files */
+ goto skip;
+
+ case stLocal: /* Local variables */
+ /* Normally these are skipped because we skip over
+ all blocks we see. However, these can occur
+ as visible symbols in a .h file that contains code. */
+ goto skip;
+
+ default:
+ /* Both complaints are valid: one gives symbol name,
+ the other the offending symbol type. */
+ complain (&unknown_sym_complaint, name);
+ complain (&unknown_st_complaint, sh.st);
+ cur_sdx++;
+ continue;
+ }
+ /* Use this gdb symbol */
+ add_psymbol_to_list (name, strlen (name),
+ VAR_NAMESPACE, class,
+ &objfile->static_psymbols,
+ 0, sh.value, psymtab_language, objfile);
+ skip:
+ cur_sdx++; /* Go to next file symbol */
+ }
+
+ /* Now do enter the external symbols. */
+ ext_ptr = &extern_tab[fdr_to_pst[f_idx].globals_offset];
+ cur_sdx = fdr_to_pst[f_idx].n_globals;
+ PST_PRIVATE (save_pst)->extern_count = cur_sdx;
+ PST_PRIVATE (save_pst)->extern_tab = ext_ptr;
+ for (; --cur_sdx >= 0; ext_ptr++)
+ {
+ enum address_class class;
+ SYMR *psh;
+ char *name;
+ CORE_ADDR svalue;
+
+ if (ext_ptr->ifd != f_idx)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ psh = &ext_ptr->asym;
+
+ /* Do not add undefined symbols to the partial symbol table. */
+ if (SC_IS_UNDEF (psh->sc) || psh->sc == scNil)
+ continue;
+
+ svalue = psh->value;
+ switch (psh->sc)
+ {
+ case scText:
+ case scRConst:
+ svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ break;
+ case scData:
+ case scSData:
+ case scRData:
+ case scPData:
+ case scXData:
+ svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ break;
+ case scBss:
+ case scSBss:
+ svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+ break;
+ }
+
+ switch (psh->st)
+ {
+ case stNil:
+ /* These are generated for static symbols in .o files,
+ ignore them. */
+ continue;
+ case stProc:
+ case stStaticProc:
+ /* External procedure symbols have been entered
+ into the minimal symbol table in pass 2 above.
+ Ignore them, as parse_external will ignore them too. */
+ continue;
+ case stLabel:
+ class = LOC_LABEL;
+ break;
+ default:
+ complain (&unknown_ext_complaint,
+ debug_info->ssext + psh->iss);
+ /* Fall through, pretend it's global. */
+ case stGlobal:
+ /* Global common symbols are resolved by the runtime loader,
+ ignore them. */
+ if (SC_IS_COMMON (psh->sc))
+ continue;
+
+ class = LOC_STATIC;
+ break;
+ }
+ name = debug_info->ssext + psh->iss;
+ add_psymbol_to_list (name, strlen (name),
+ VAR_NAMESPACE, class,
+ &objfile->global_psymbols,
+ 0, svalue,
+ psymtab_language, objfile);
+ }
+ }
+
+ /* Link pst to FDR. end_psymtab returns NULL if the psymtab was
+ empty and put on the free list. */
+ fdr_to_pst[f_idx].pst = end_psymtab (save_pst,
+ psymtab_include_list, includes_used,
+ -1, TEXTHIGH (save_pst),
+ dependency_list, dependencies_used, textlow_not_set);
+ includes_used = 0;
+ dependencies_used = 0;
+
+ if (objfile->ei.entry_point >= TEXTLOW (save_pst) &&
+ objfile->ei.entry_point < TEXTHIGH (save_pst))
+ {
+ objfile->ei.entry_file_lowpc = TEXTLOW (save_pst);
+ objfile->ei.entry_file_highpc = TEXTHIGH (save_pst);
+ }
+
+ /* The objfile has its functions reordered if this partial symbol
+ table overlaps any other partial symbol table.
+ We cannot assume a reordered objfile if a partial symbol table
+ is contained within another partial symbol table, as partial symbol
+ tables for include files with executable code are contained
+ within the partial symbol table for the including source file,
+ and we do not want to flag the objfile reordered for these cases.
+
+ This strategy works well for Irix-5.2 shared libraries, but we
+ might have to use a more elaborate (and slower) algorithm for
+ other cases. */
+ save_pst = fdr_to_pst[f_idx].pst;
+ if (save_pst != NULL
+ && TEXTLOW (save_pst) != 0
+ && !(objfile->flags & OBJF_REORDERED))
+ {
+ ALL_OBJFILE_PSYMTABS (objfile, pst)
+ {
+ if (save_pst != pst
+ && TEXTLOW (save_pst) >= TEXTLOW (pst)
+ && TEXTLOW (save_pst) < TEXTHIGH (pst)
+ && TEXTHIGH (save_pst) > TEXTHIGH (pst))
+ {
+ objfile->flags |= OBJF_REORDERED;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Now scan the FDRs for dependencies */
+ for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++)
+ {
+ fh = f_idx + debug_info->fdr;
+ pst = fdr_to_pst[f_idx].pst;
+
+ if (pst == (struct partial_symtab *) NULL)
+ continue;
+
+ /* This should catch stabs-in-ecoff. */
+ if (fh->crfd <= 1)
+ continue;
+
+ /* Skip the first file indirect entry as it is a self dependency
+ for source files or a reverse .h -> .c dependency for header files. */
+ pst->number_of_dependencies = 0;
+ pst->dependencies =
+ ((struct partial_symtab **)
+ obstack_alloc (&objfile->psymbol_obstack,
+ ((fh->crfd - 1)
+ * sizeof (struct partial_symtab *))));
+ for (s_idx = 1; s_idx < fh->crfd; s_idx++)
+ {
+ RFDT rh;
+
+ (*swap_rfd_in) (cur_bfd,
+ ((char *) debug_info->external_rfd
+ + (fh->rfdBase + s_idx) * external_rfd_size),
+ &rh);
+ if (rh < 0 || rh >= hdr->ifdMax)
+ {
+ complain (&bad_file_number_complaint, rh);
+ continue;
+ }
+
+ /* Skip self dependencies of header files. */
+ if (rh == f_idx)
+ continue;
+
+ /* Do not add to dependeny list if psymtab was empty. */
+ if (fdr_to_pst[rh].pst == (struct partial_symtab *) NULL)
+ continue;
+ pst->dependencies[pst->number_of_dependencies++] = fdr_to_pst[rh].pst;
+ }
+ }
+
+ /* Remove the dummy psymtab created for -O3 images above, if it is
+ still empty, to enable the detection of stripped executables. */
+ if (objfile->psymtabs->next == NULL
+ && objfile->psymtabs->number_of_dependencies == 0
+ && objfile->psymtabs->n_global_syms == 0
+ && objfile->psymtabs->n_static_syms == 0)
+ objfile->psymtabs = NULL;
+ do_cleanups (old_chain);
+}
+
+/* If the current psymbol has an enumerated type, we need to add
+ all the the enum constants to the partial symbol table. */
+
+static void
+handle_psymbol_enumerators (struct objfile *objfile, FDR *fh, int stype,
+ CORE_ADDR svalue)
+{
+ const bfd_size_type external_sym_size = debug_swap->external_sym_size;
+ void (*const swap_sym_in) (bfd *, void *, SYMR *) = debug_swap->swap_sym_in;
+ char *ext_sym = ((char *) debug_info->external_sym
+ + ((fh->isymBase + cur_sdx + 1) * external_sym_size));
+ SYMR sh;
+ TIR tir;
+
+ switch (stype)
+ {
+ case stEnum:
+ break;
+
+ case stBlock:
+ /* It is an enumerated type if the next symbol entry is a stMember
+ and its auxiliary index is indexNil or its auxiliary entry
+ is a plain btNil or btVoid.
+ Alpha cc -migrate enums are recognized by a zero index and
+ a zero symbol value.
+ DU 4.0 cc enums are recognized by a member type of btEnum without
+ qualifiers and a zero symbol value. */
+ (*swap_sym_in) (cur_bfd, ext_sym, &sh);
+ if (sh.st != stMember)
+ return;
+
+ if (sh.index == indexNil
+ || (sh.index == 0 && svalue == 0))
+ break;
+ (*debug_swap->swap_tir_in) (fh->fBigendian,
+ &(debug_info->external_aux
+ + fh->iauxBase + sh.index)->a_ti,
+ &tir);
+ if ((tir.bt != btNil
+ && tir.bt != btVoid
+ && (tir.bt != btEnum || svalue != 0))
+ || tir.tq0 != tqNil)
+ return;
+ break;
+
+ default:
+ return;
+ }
+
+ for (;;)
+ {
+ char *name;
+
+ (*swap_sym_in) (cur_bfd, ext_sym, &sh);
+ if (sh.st != stMember)
+ break;
+ name = debug_info->ss + cur_fdr->issBase + sh.iss;
+
+ /* Note that the value doesn't matter for enum constants
+ in psymtabs, just in symtabs. */
+ add_psymbol_to_list (name, strlen (name),
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols, 0,
+ (CORE_ADDR) 0, psymtab_language, objfile);
+ ext_sym += external_sym_size;
+ }
+}
+
+/* Get the next symbol. OBJFILE is unused. */
+
+static char *
+mdebug_next_symbol_text (struct objfile *objfile)
+{
+ SYMR sh;
+
+ cur_sdx++;
+ (*debug_swap->swap_sym_in) (cur_bfd,
+ ((char *) debug_info->external_sym
+ + ((cur_fdr->isymBase + cur_sdx)
+ * debug_swap->external_sym_size)),
+ &sh);
+ return debug_info->ss + cur_fdr->issBase + sh.iss;
+}
+
+/* Ancillary function to psymtab_to_symtab(). Does all the work
+ for turning the partial symtab PST into a symtab, recurring
+ first on all dependent psymtabs. The argument FILENAME is
+ only passed so we can see in debug stack traces what file
+ is being read.
+
+ This function has a split personality, based on whether the
+ symbol table contains ordinary ecoff symbols, or stabs-in-ecoff.
+ The flow of control and even the memory allocation differs. FIXME. */
+
+static void
+psymtab_to_symtab_1 (struct partial_symtab *pst, char *filename)
+{
+ bfd_size_type external_sym_size;
+ bfd_size_type external_pdr_size;
+ void (*swap_sym_in) (bfd *, void *, SYMR *);
+ void (*swap_pdr_in) (bfd *, void *, PDR *);
+ int i;
+ struct symtab *st = NULL;
+ FDR *fh;
+ struct linetable *lines;
+ CORE_ADDR lowest_pdr_addr = 0;
+ int last_symtab_ended = 0;
+
+ if (pst->readin)
+ return;
+ pst->readin = 1;
+
+ /* Read in all partial symbtabs on which this one is dependent.
+ NOTE that we do have circular dependencies, sigh. We solved
+ that by setting pst->readin before this point. */
+
+ for (i = 0; i < pst->number_of_dependencies; i++)
+ if (!pst->dependencies[i]->readin)
+ {
+ /* Inform about additional files to be read in. */
+ if (info_verbose)
+ {
+ fputs_filtered (" ", gdb_stdout);
+ wrap_here ("");
+ fputs_filtered ("and ", gdb_stdout);
+ wrap_here ("");
+ printf_filtered ("%s...",
+ pst->dependencies[i]->filename);
+ wrap_here (""); /* Flush output */
+ gdb_flush (gdb_stdout);
+ }
+ /* We only pass the filename for debug purposes */
+ psymtab_to_symtab_1 (pst->dependencies[i],
+ pst->dependencies[i]->filename);
+ }
+
+ /* Do nothing if this is a dummy psymtab. */
+
+ if (pst->n_global_syms == 0 && pst->n_static_syms == 0
+ && TEXTLOW (pst) == 0 && TEXTHIGH (pst) == 0)
+ return;
+
+ /* Now read the symbols for this symtab */
+
+ cur_bfd = CUR_BFD (pst);
+ debug_swap = DEBUG_SWAP (pst);
+ debug_info = DEBUG_INFO (pst);
+ pending_list = PENDING_LIST (pst);
+ external_sym_size = debug_swap->external_sym_size;
+ external_pdr_size = debug_swap->external_pdr_size;
+ swap_sym_in = debug_swap->swap_sym_in;
+ swap_pdr_in = debug_swap->swap_pdr_in;
+ current_objfile = pst->objfile;
+ cur_fd = FDR_IDX (pst);
+ fh = ((cur_fd == -1)
+ ? (FDR *) NULL
+ : debug_info->fdr + cur_fd);
+ cur_fdr = fh;
+
+ /* See comment in parse_partial_symbols about the @stabs sentinel. */
+ processing_gcc_compilation = 0;
+ if (fh != (FDR *) NULL && fh->csym >= 2)
+ {
+ SYMR sh;
+
+ (*swap_sym_in) (cur_bfd,
+ ((char *) debug_info->external_sym
+ + (fh->isymBase + 1) * external_sym_size),
+ &sh);
+ if (STREQ (debug_info->ss + fh->issBase + sh.iss,
+ stabs_symbol))
+ {
+ /* We indicate that this is a GCC compilation so that certain
+ features will be enabled in stabsread/dbxread. */
+ processing_gcc_compilation = 2;
+ }
+ }
+
+ if (processing_gcc_compilation != 0)
+ {
+
+ /* This symbol table contains stabs-in-ecoff entries. */
+
+ /* Parse local symbols first */
+
+ if (fh->csym <= 2) /* FIXME, this blows psymtab->symtab ptr */
+ {
+ current_objfile = NULL;
+ return;
+ }
+ for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++)
+ {
+ SYMR sh;
+ char *name;
+ CORE_ADDR valu;
+
+ (*swap_sym_in) (cur_bfd,
+ (((char *) debug_info->external_sym)
+ + (fh->isymBase + cur_sdx) * external_sym_size),
+ &sh);
+ name = debug_info->ss + fh->issBase + sh.iss;
+ valu = sh.value;
+ /* XXX This is a hack. It will go away! */
+ if (ECOFF_IS_STAB (&sh) || (name[0] == '#'))
+ {
+ int type_code = ECOFF_UNMARK_STAB (sh.index);
+
+ /* We should never get non N_STAB symbols here, but they
+ should be harmless, so keep process_one_symbol from
+ complaining about them. */
+ if (type_code & N_STAB)
+ {
+ /* If we found a trailing N_SO with no name, process
+ it here instead of in process_one_symbol, so we
+ can keep a handle to its symtab. The symtab
+ would otherwise be ended twice, once in
+ process_one_symbol, and once after this loop. */
+ if (type_code == N_SO
+ && last_source_file
+ && previous_stab_code != (unsigned char) N_SO
+ && *name == '\000')
+ {
+ valu += ANOFFSET (pst->section_offsets,
+ SECT_OFF_TEXT (pst->objfile));
+ previous_stab_code = N_SO;
+ st = end_symtab (valu, pst->objfile,
+ SECT_OFF_TEXT (pst->objfile));
+ end_stabs ();
+ last_symtab_ended = 1;
+ }
+ else
+ {
+ last_symtab_ended = 0;
+ process_one_symbol (type_code, 0, valu, name,
+ pst->section_offsets, pst->objfile);
+ }
+ }
+ /* Similarly a hack. */
+ else if (name[0] == '#')
+ {
+ process_one_symbol (N_SLINE, 0, valu, name,
+ pst->section_offsets, pst->objfile);
+ }
+ if (type_code == N_FUN)
+ {
+ /* Make up special symbol to contain
+ procedure specific info */
+ struct mips_extra_func_info *e =
+ ((struct mips_extra_func_info *)
+ obstack_alloc (&current_objfile->symbol_obstack,
+ sizeof (struct mips_extra_func_info)));
+ struct symbol *s = new_symbol (MIPS_EFI_SYMBOL_NAME);
+
+ memset (e, 0, sizeof (struct mips_extra_func_info));
+ SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE;
+ SYMBOL_CLASS (s) = LOC_CONST;
+ SYMBOL_TYPE (s) = mdebug_type_void;
+ SYMBOL_VALUE (s) = (long) e;
+ e->pdr.framereg = -1;
+ add_symbol_to_list (s, &local_symbols);
+ }
+ }
+ else if (sh.st == stLabel)
+ {
+ if (sh.index == indexNil)
+ {
+ /* This is what the gcc2_compiled and __gnu_compiled_*
+ show up as. So don't complain. */
+ ;
+ }
+ else
+ {
+ /* Handle encoded stab line number. */
+ valu += ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (pst->objfile));
+ record_line (current_subfile, sh.index, valu);
+ }
+ }
+ else if (sh.st == stProc || sh.st == stStaticProc
+ || sh.st == stStatic || sh.st == stEnd)
+ /* These are generated by gcc-2.x, do not complain */
+ ;
+ else
+ complain (&stab_unknown_complaint, name);
+ }
+
+ if (! last_symtab_ended)
+ {
+ st = end_symtab (TEXTHIGH (pst), pst->objfile, SECT_OFF_TEXT (pst->objfile));
+ end_stabs ();
+ }
+
+ /* Sort the symbol table now, we are done adding symbols to it.
+ We must do this before parse_procedure calls lookup_symbol. */
+ sort_symtab_syms (st);
+
+ /* There used to be a call to sort_blocks here, but this should not
+ be necessary for stabs symtabs. And as sort_blocks modifies the
+ start address of the GLOBAL_BLOCK to the FIRST_LOCAL_BLOCK,
+ it did the wrong thing if the first procedure in a file was
+ generated via asm statements. */
+
+ /* Fill in procedure info next. */
+ if (fh->cpd > 0)
+ {
+ PDR *pr_block;
+ struct cleanup *old_chain;
+ char *pdr_ptr;
+ char *pdr_end;
+ PDR *pdr_in;
+ PDR *pdr_in_end;
+
+ pr_block = (PDR *) xmalloc (fh->cpd * sizeof (PDR));
+ old_chain = make_cleanup (xfree, pr_block);
+
+ pdr_ptr = ((char *) debug_info->external_pdr
+ + fh->ipdFirst * external_pdr_size);
+ pdr_end = pdr_ptr + fh->cpd * external_pdr_size;
+ pdr_in = pr_block;
+ for (;
+ pdr_ptr < pdr_end;
+ pdr_ptr += external_pdr_size, pdr_in++)
+ {
+ (*swap_pdr_in) (cur_bfd, pdr_ptr, pdr_in);
+
+ /* Determine lowest PDR address, the PDRs are not always
+ sorted. */
+ if (pdr_in == pr_block)
+ lowest_pdr_addr = pdr_in->adr;
+ else if (pdr_in->adr < lowest_pdr_addr)
+ lowest_pdr_addr = pdr_in->adr;
+ }
+
+ pdr_in = pr_block;
+ pdr_in_end = pdr_in + fh->cpd;
+ for (; pdr_in < pdr_in_end; pdr_in++)
+ parse_procedure (pdr_in, st, pst);
+
+ do_cleanups (old_chain);
+ }
+ }
+ else
+ {
+ /* This symbol table contains ordinary ecoff entries. */
+
+ int f_max;
+ int maxlines;
+ EXTR *ext_ptr;
+
+ /* How many symbols will we need */
+ /* FIXME, this does not count enum values. */
+ f_max = pst->n_global_syms + pst->n_static_syms;
+ if (fh == 0)
+ {
+ maxlines = 0;
+ st = new_symtab ("unknown", f_max, 0, pst->objfile);
+ }
+ else
+ {
+ f_max += fh->csym + fh->cpd;
+ maxlines = 2 * fh->cline;
+ st = new_symtab (pst->filename, 2 * f_max, maxlines, pst->objfile);
+
+ /* The proper language was already determined when building
+ the psymtab, use it. */
+ st->language = PST_PRIVATE (pst)->pst_language;
+ }
+
+ psymtab_language = st->language;
+
+ lines = LINETABLE (st);
+
+ /* Get a new lexical context */
+
+ push_parse_stack ();
+ top_stack->cur_st = st;
+ top_stack->cur_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (st),
+ STATIC_BLOCK);
+ BLOCK_START (top_stack->cur_block) = TEXTLOW (pst);
+ BLOCK_END (top_stack->cur_block) = 0;
+ top_stack->blocktype = stFile;
+ top_stack->maxsyms = 2 * f_max;
+ top_stack->cur_type = 0;
+ top_stack->procadr = 0;
+ top_stack->numargs = 0;
+ found_ecoff_debugging_info = 0;
+
+ if (fh)
+ {
+ char *sym_ptr;
+ char *sym_end;
+
+ /* Parse local symbols first */
+ sym_ptr = ((char *) debug_info->external_sym
+ + fh->isymBase * external_sym_size);
+ sym_end = sym_ptr + fh->csym * external_sym_size;
+ while (sym_ptr < sym_end)
+ {
+ SYMR sh;
+ int c;
+
+ (*swap_sym_in) (cur_bfd, sym_ptr, &sh);
+ c = parse_symbol (&sh,
+ debug_info->external_aux + fh->iauxBase,
+ sym_ptr, fh->fBigendian, pst->section_offsets, pst->objfile);
+ sym_ptr += c * external_sym_size;
+ }
+
+ /* Linenumbers. At the end, check if we can save memory.
+ parse_lines has to look ahead an arbitrary number of PDR
+ structures, so we swap them all first. */
+ if (fh->cpd > 0)
+ {
+ PDR *pr_block;
+ struct cleanup *old_chain;
+ char *pdr_ptr;
+ char *pdr_end;
+ PDR *pdr_in;
+ PDR *pdr_in_end;
+
+ pr_block = (PDR *) xmalloc (fh->cpd * sizeof (PDR));
+
+ old_chain = make_cleanup (xfree, pr_block);
+
+ pdr_ptr = ((char *) debug_info->external_pdr
+ + fh->ipdFirst * external_pdr_size);
+ pdr_end = pdr_ptr + fh->cpd * external_pdr_size;
+ pdr_in = pr_block;
+ for (;
+ pdr_ptr < pdr_end;
+ pdr_ptr += external_pdr_size, pdr_in++)
+ {
+ (*swap_pdr_in) (cur_bfd, pdr_ptr, pdr_in);
+
+ /* Determine lowest PDR address, the PDRs are not always
+ sorted. */
+ if (pdr_in == pr_block)
+ lowest_pdr_addr = pdr_in->adr;
+ else if (pdr_in->adr < lowest_pdr_addr)
+ lowest_pdr_addr = pdr_in->adr;
+ }
+
+ parse_lines (fh, pr_block, lines, maxlines, pst, lowest_pdr_addr);
+ if (lines->nitems < fh->cline)
+ lines = shrink_linetable (lines);
+
+ /* Fill in procedure info next. */
+ pdr_in = pr_block;
+ pdr_in_end = pdr_in + fh->cpd;
+ for (; pdr_in < pdr_in_end; pdr_in++)
+ parse_procedure (pdr_in, 0, pst);
+
+ do_cleanups (old_chain);
+ }
+ }
+
+ LINETABLE (st) = lines;
+
+ /* .. and our share of externals.
+ XXX use the global list to speed up things here. how?
+ FIXME, Maybe quit once we have found the right number of ext's? */
+ top_stack->cur_st = st;
+ top_stack->cur_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (top_stack->cur_st),
+ GLOBAL_BLOCK);
+ top_stack->blocktype = stFile;
+ top_stack->maxsyms
+ = (debug_info->symbolic_header.isymMax
+ + debug_info->symbolic_header.ipdMax
+ + debug_info->symbolic_header.iextMax);
+
+ ext_ptr = PST_PRIVATE (pst)->extern_tab;
+ for (i = PST_PRIVATE (pst)->extern_count; --i >= 0; ext_ptr++)
+ parse_external (ext_ptr, fh->fBigendian, pst->section_offsets, pst->objfile);
+
+ /* If there are undefined symbols, tell the user.
+ The alpha has an undefined symbol for every symbol that is
+ from a shared library, so tell the user only if verbose is on. */
+ if (info_verbose && n_undef_symbols)
+ {
+ printf_filtered ("File %s contains %d unresolved references:",
+ st->filename, n_undef_symbols);
+ printf_filtered ("\n\t%4d variables\n\t%4d procedures\n\t%4d labels\n",
+ n_undef_vars, n_undef_procs, n_undef_labels);
+ n_undef_symbols = n_undef_labels = n_undef_vars = n_undef_procs = 0;
+
+ }
+ pop_parse_stack ();
+
+ st->primary = 1;
+
+ /* Sort the symbol table now, we are done adding symbols to it. */
+ sort_symtab_syms (st);
+
+ sort_blocks (st);
+ }
+
+ /* Now link the psymtab and the symtab. */
+ pst->symtab = st;
+
+ current_objfile = NULL;
+}
+
+/* Ancillary parsing procedures. */
+
+/* Return 1 if the symbol pointed to by SH has a cross reference
+ to an opaque aggregate type, else 0. */
+
+static int
+has_opaque_xref (FDR *fh, SYMR *sh)
+{
+ TIR tir;
+ union aux_ext *ax;
+ RNDXR rn[1];
+ unsigned int rf;
+
+ if (sh->index == indexNil)
+ return 0;
+
+ ax = debug_info->external_aux + fh->iauxBase + sh->index;
+ (*debug_swap->swap_tir_in) (fh->fBigendian, &ax->a_ti, &tir);
+ if (tir.bt != btStruct && tir.bt != btUnion && tir.bt != btEnum)
+ return 0;
+
+ ax++;
+ (*debug_swap->swap_rndx_in) (fh->fBigendian, &ax->a_rndx, rn);
+ if (rn->rfd == 0xfff)
+ rf = AUX_GET_ISYM (fh->fBigendian, ax + 1);
+ else
+ rf = rn->rfd;
+ if (rf != -1)
+ return 0;
+ return 1;
+}
+
+/* Lookup the type at relative index RN. Return it in TPP
+ if found and in any event come up with its name PNAME.
+ BIGEND says whether aux symbols are big-endian or not (from fh->fBigendian).
+ Return value says how many aux symbols we ate. */
+
+static int
+cross_ref (int fd, union aux_ext *ax, struct type **tpp, enum type_code type_code, /* Use to alloc new type if none is found. */
+ char **pname, int bigend, char *sym_name)
+{
+ RNDXR rn[1];
+ unsigned int rf;
+ int result = 1;
+ FDR *fh;
+ char *esh;
+ SYMR sh;
+ int xref_fd;
+ struct mdebug_pending *pend;
+
+ *tpp = (struct type *) NULL;
+
+ (*debug_swap->swap_rndx_in) (bigend, &ax->a_rndx, rn);
+
+ /* Escape index means 'the next one' */
+ if (rn->rfd == 0xfff)
+ {
+ result++;
+ rf = AUX_GET_ISYM (bigend, ax + 1);
+ }
+ else
+ {
+ rf = rn->rfd;
+ }
+
+ /* mips cc uses a rf of -1 for opaque struct definitions.
+ Set TYPE_FLAG_STUB for these types so that check_typedef will
+ resolve them if the struct gets defined in another compilation unit. */
+ if (rf == -1)
+ {
+ *pname = "<undefined>";
+ *tpp = init_type (type_code, 0, TYPE_FLAG_STUB, (char *) NULL, current_objfile);
+ return result;
+ }
+
+ /* mips cc uses an escaped rn->index of 0 for struct return types
+ of procedures that were compiled without -g. These will always remain
+ undefined. */
+ if (rn->rfd == 0xfff && rn->index == 0)
+ {
+ *pname = "<undefined>";
+ return result;
+ }
+
+ /* Find the relative file descriptor and the symbol in it. */
+ fh = get_rfd (fd, rf);
+ xref_fd = fh - debug_info->fdr;
+
+ if (rn->index >= fh->csym)
+ {
+ /* File indirect entry is corrupt. */
+ *pname = "<illegal>";
+ complain (&bad_rfd_entry_complaint,
+ sym_name, xref_fd, rn->index);
+ return result;
+ }
+
+ /* If we have processed this symbol then we left a forwarding
+ pointer to the type in the pending list. If not, we`ll put
+ it in a list of pending types, to be processed later when
+ the file will be. In any event, we collect the name for the
+ type here. */
+
+ esh = ((char *) debug_info->external_sym
+ + ((fh->isymBase + rn->index)
+ * debug_swap->external_sym_size));
+ (*debug_swap->swap_sym_in) (cur_bfd, esh, &sh);
+
+ /* Make sure that this type of cross reference can be handled. */
+ if ((sh.sc != scInfo
+ || (sh.st != stBlock && sh.st != stTypedef && sh.st != stIndirect
+ && sh.st != stStruct && sh.st != stUnion
+ && sh.st != stEnum))
+ && (sh.st != stBlock || !SC_IS_COMMON (sh.sc)))
+ {
+ /* File indirect entry is corrupt. */
+ *pname = "<illegal>";
+ complain (&bad_rfd_entry_complaint,
+ sym_name, xref_fd, rn->index);
+ return result;
+ }
+
+ *pname = debug_info->ss + fh->issBase + sh.iss;
+
+ pend = is_pending_symbol (fh, esh);
+ if (pend)
+ *tpp = pend->t;
+ else
+ {
+ /* We have not yet seen this type. */
+
+ if ((sh.iss == 0 && sh.st == stTypedef) || sh.st == stIndirect)
+ {
+ TIR tir;
+
+ /* alpha cc puts out a stTypedef with a sh.iss of zero for
+ two cases:
+ a) forward declarations of structs/unions/enums which are not
+ defined in this compilation unit.
+ For these the type will be void. This is a bad design decision
+ as cross referencing across compilation units is impossible
+ due to the missing name.
+ b) forward declarations of structs/unions/enums/typedefs which
+ are defined later in this file or in another file in the same
+ compilation unit. Irix5 cc uses a stIndirect symbol for this.
+ Simply cross reference those again to get the true type.
+ The forward references are not entered in the pending list and
+ in the symbol table. */
+
+ (*debug_swap->swap_tir_in) (bigend,
+ &(debug_info->external_aux
+ + fh->iauxBase + sh.index)->a_ti,
+ &tir);
+ if (tir.tq0 != tqNil)
+ complain (&illegal_forward_tq0_complaint, sym_name);
+ switch (tir.bt)
+ {
+ case btVoid:
+ *tpp = init_type (type_code, 0, 0, (char *) NULL,
+ current_objfile);
+ *pname = "<undefined>";
+ break;
+
+ case btStruct:
+ case btUnion:
+ case btEnum:
+ cross_ref (xref_fd,
+ (debug_info->external_aux
+ + fh->iauxBase + sh.index + 1),
+ tpp, type_code, pname,
+ fh->fBigendian, sym_name);
+ break;
+
+ case btTypedef:
+ /* Follow a forward typedef. This might recursively
+ call cross_ref till we get a non typedef'ed type.
+ FIXME: This is not correct behaviour, but gdb currently
+ cannot handle typedefs without type copying. Type
+ copying is impossible as we might have mutual forward
+ references between two files and the copied type would not
+ get filled in when we later parse its definition. */
+ *tpp = parse_type (xref_fd,
+ debug_info->external_aux + fh->iauxBase,
+ sh.index,
+ (int *) NULL,
+ fh->fBigendian,
+ debug_info->ss + fh->issBase + sh.iss);
+ add_pending (fh, esh, *tpp);
+ break;
+
+ default:
+ complain (&illegal_forward_bt_complaint, tir.bt, sym_name);
+ *tpp = init_type (type_code, 0, 0, (char *) NULL,
+ current_objfile);
+ break;
+ }
+ return result;
+ }
+ else if (sh.st == stTypedef)
+ {
+ /* Parse the type for a normal typedef. This might recursively call
+ cross_ref till we get a non typedef'ed type.
+ FIXME: This is not correct behaviour, but gdb currently
+ cannot handle typedefs without type copying. But type copying is
+ impossible as we might have mutual forward references between
+ two files and the copied type would not get filled in when
+ we later parse its definition. */
+ *tpp = parse_type (xref_fd,
+ debug_info->external_aux + fh->iauxBase,
+ sh.index,
+ (int *) NULL,
+ fh->fBigendian,
+ debug_info->ss + fh->issBase + sh.iss);
+ }
+ else
+ {
+ /* Cross reference to a struct/union/enum which is defined
+ in another file in the same compilation unit but that file
+ has not been parsed yet.
+ Initialize the type only, it will be filled in when
+ it's definition is parsed. */
+ *tpp = init_type (type_code, 0, 0, (char *) NULL, current_objfile);
+ }
+ add_pending (fh, esh, *tpp);
+ }
+
+ /* We used one auxent normally, two if we got a "next one" rf. */
+ return result;
+}
+
+
+/* Quick&dirty lookup procedure, to avoid the MI ones that require
+ keeping the symtab sorted */
+
+static struct symbol *
+mylookup_symbol (char *name, register struct block *block,
+ namespace_enum namespace, enum address_class class)
+{
+ int i, inc;
+ struct symbol *sym;
+
+ inc = name[0];
+ ALL_BLOCK_SYMBOLS (block, i, sym)
+ {
+ if (SYMBOL_NAME (sym)[0] == inc
+ && SYMBOL_NAMESPACE (sym) == namespace
+ && SYMBOL_CLASS (sym) == class
+ && strcmp (SYMBOL_NAME (sym), name) == 0)
+ return sym;
+ }
+
+ block = BLOCK_SUPERBLOCK (block);
+ if (block)
+ return mylookup_symbol (name, block, namespace, class);
+ return 0;
+}
+
+
+/* Add a new symbol S to a block B.
+ Infrequently, we will need to reallocate the block to make it bigger.
+ We only detect this case when adding to top_stack->cur_block, since
+ that's the only time we know how big the block is. FIXME. */
+
+static void
+add_symbol (struct symbol *s, struct block *b)
+{
+ int nsyms = BLOCK_NSYMS (b)++;
+ struct block *origb;
+ struct parse_stack *stackp;
+
+ if (b == top_stack->cur_block &&
+ nsyms >= top_stack->maxsyms)
+ {
+ complain (&block_overflow_complaint, SYMBOL_NAME (s));
+ /* In this case shrink_block is actually grow_block, since
+ BLOCK_NSYMS(b) is larger than its current size. */
+ origb = b;
+ b = shrink_block (top_stack->cur_block, top_stack->cur_st);
+
+ /* Now run through the stack replacing pointers to the
+ original block. shrink_block has already done this
+ for the blockvector and BLOCK_FUNCTION. */
+ for (stackp = top_stack; stackp; stackp = stackp->next)
+ {
+ if (stackp->cur_block == origb)
+ {
+ stackp->cur_block = b;
+ stackp->maxsyms = BLOCK_NSYMS (b);
+ }
+ }
+ }
+ BLOCK_SYM (b, nsyms) = s;
+}
+
+/* Add a new block B to a symtab S */
+
+static void
+add_block (struct block *b, struct symtab *s)
+{
+ struct blockvector *bv = BLOCKVECTOR (s);
+
+ bv = (struct blockvector *) xrealloc ((void *) bv,
+ (sizeof (struct blockvector)
+ + BLOCKVECTOR_NBLOCKS (bv)
+ * sizeof (bv->block)));
+ if (bv != BLOCKVECTOR (s))
+ BLOCKVECTOR (s) = bv;
+
+ BLOCKVECTOR_BLOCK (bv, BLOCKVECTOR_NBLOCKS (bv)++) = b;
+}
+
+/* Add a new linenumber entry (LINENO,ADR) to a linevector LT.
+ MIPS' linenumber encoding might need more than one byte
+ to describe it, LAST is used to detect these continuation lines.
+
+ Combining lines with the same line number seems like a bad idea.
+ E.g: There could be a line number entry with the same line number after the
+ prologue and GDB should not ignore it (this is a better way to find
+ a prologue than mips_skip_prologue).
+ But due to the compressed line table format there are line number entries
+ for the same line which are needed to bridge the gap to the next
+ line number entry. These entries have a bogus address info with them
+ and we are unable to tell them from intended duplicate line number
+ entries.
+ This is another reason why -ggdb debugging format is preferable. */
+
+static int
+add_line (struct linetable *lt, int lineno, CORE_ADDR adr, int last)
+{
+ /* DEC c89 sometimes produces zero linenos which confuse gdb.
+ Change them to something sensible. */
+ if (lineno == 0)
+ lineno = 1;
+ if (last == 0)
+ last = -2; /* make sure we record first line */
+
+ if (last == lineno) /* skip continuation lines */
+ return lineno;
+
+ lt->item[lt->nitems].line = lineno;
+ lt->item[lt->nitems++].pc = adr << 2;
+ return lineno;
+}
+
+/* Sorting and reordering procedures */
+
+/* Blocks with a smaller low bound should come first */
+
+static int
+compare_blocks (const void *arg1, const void *arg2)
+{
+ register int addr_diff;
+ struct block **b1 = (struct block **) arg1;
+ struct block **b2 = (struct block **) arg2;
+
+ addr_diff = (BLOCK_START ((*b1))) - (BLOCK_START ((*b2)));
+ if (addr_diff == 0)
+ return (BLOCK_END ((*b2))) - (BLOCK_END ((*b1)));
+ return addr_diff;
+}
+
+/* Sort the blocks of a symtab S.
+ Reorder the blocks in the blockvector by code-address,
+ as required by some MI search routines */
+
+static void
+sort_blocks (struct symtab *s)
+{
+ struct blockvector *bv = BLOCKVECTOR (s);
+
+ if (BLOCKVECTOR_NBLOCKS (bv) <= 2)
+ {
+ /* Cosmetic */
+ if (BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) == 0)
+ BLOCK_START (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) = 0;
+ if (BLOCK_END (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) == 0)
+ BLOCK_START (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) = 0;
+ return;
+ }
+ /*
+ * This is very unfortunate: normally all functions are compiled in
+ * the order they are found, but if the file is compiled -O3 things
+ * are very different. It would be nice to find a reliable test
+ * to detect -O3 images in advance.
+ */
+ if (BLOCKVECTOR_NBLOCKS (bv) > 3)
+ qsort (&BLOCKVECTOR_BLOCK (bv, FIRST_LOCAL_BLOCK),
+ BLOCKVECTOR_NBLOCKS (bv) - FIRST_LOCAL_BLOCK,
+ sizeof (struct block *),
+ compare_blocks);
+
+ {
+ register CORE_ADDR high = 0;
+ register int i, j = BLOCKVECTOR_NBLOCKS (bv);
+
+ for (i = FIRST_LOCAL_BLOCK; i < j; i++)
+ if (high < BLOCK_END (BLOCKVECTOR_BLOCK (bv, i)))
+ high = BLOCK_END (BLOCKVECTOR_BLOCK (bv, i));
+ BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) = high;
+ }
+
+ BLOCK_START (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) =
+ BLOCK_START (BLOCKVECTOR_BLOCK (bv, FIRST_LOCAL_BLOCK));
+
+ BLOCK_START (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) =
+ BLOCK_START (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
+ BLOCK_END (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) =
+ BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
+}
+
+
+/* Constructor/restructor/destructor procedures */
+
+/* Allocate a new symtab for NAME. Needs an estimate of how many symbols
+ MAXSYMS and linenumbers MAXLINES we'll put in it */
+
+static struct symtab *
+new_symtab (char *name, int maxsyms, int maxlines, struct objfile *objfile)
+{
+ struct symtab *s = allocate_symtab (name, objfile);
+
+ LINETABLE (s) = new_linetable (maxlines);
+
+ /* All symtabs must have at least two blocks */
+ BLOCKVECTOR (s) = new_bvect (2);
+ BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK) = new_block (maxsyms);
+ BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK) = new_block (maxsyms);
+ BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK)) =
+ BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+
+ s->free_code = free_linetable;
+ s->debugformat = obsavestring ("ECOFF", 5,
+ &objfile->symbol_obstack);
+ return (s);
+}
+
+/* Allocate a new partial_symtab NAME */
+
+static struct partial_symtab *
+new_psymtab (char *name, struct objfile *objfile)
+{
+ struct partial_symtab *psymtab;
+
+ psymtab = allocate_psymtab (name, objfile);
+ psymtab->section_offsets = objfile->section_offsets;
+
+ /* Keep a backpointer to the file's symbols */
+
+ psymtab->read_symtab_private = ((char *)
+ obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct symloc)));
+ memset (psymtab->read_symtab_private, 0, sizeof (struct symloc));
+ CUR_BFD (psymtab) = cur_bfd;
+ DEBUG_SWAP (psymtab) = debug_swap;
+ DEBUG_INFO (psymtab) = debug_info;
+ PENDING_LIST (psymtab) = pending_list;
+
+ /* The way to turn this into a symtab is to call... */
+ psymtab->read_symtab = mdebug_psymtab_to_symtab;
+ return (psymtab);
+}
+
+
+/* Allocate a linetable array of the given SIZE. Since the struct
+ already includes one item, we subtract one when calculating the
+ proper size to allocate. */
+
+static struct linetable *
+new_linetable (int size)
+{
+ struct linetable *l;
+
+ size = (size - 1) * sizeof (l->item) + sizeof (struct linetable);
+ l = (struct linetable *) xmalloc (size);
+ l->nitems = 0;
+ return l;
+}
+
+/* Oops, too big. Shrink it. This was important with the 2.4 linetables,
+ I am not so sure about the 3.4 ones.
+
+ Since the struct linetable already includes one item, we subtract one when
+ calculating the proper size to allocate. */
+
+static struct linetable *
+shrink_linetable (struct linetable *lt)
+{
+
+ return (struct linetable *) xrealloc ((void *) lt,
+ (sizeof (struct linetable)
+ + ((lt->nitems - 1)
+ * sizeof (lt->item))));
+}
+
+/* Allocate and zero a new blockvector of NBLOCKS blocks. */
+
+static struct blockvector *
+new_bvect (int nblocks)
+{
+ struct blockvector *bv;
+ int size;
+
+ size = sizeof (struct blockvector) + nblocks * sizeof (struct block *);
+ bv = (struct blockvector *) xzalloc (size);
+
+ BLOCKVECTOR_NBLOCKS (bv) = nblocks;
+
+ return bv;
+}
+
+/* Allocate and zero a new block of MAXSYMS symbols */
+
+static struct block *
+new_block (int maxsyms)
+{
+ int size = sizeof (struct block) + (maxsyms - 1) * sizeof (struct symbol *);
+
+ return (struct block *) xzalloc (size);
+}
+
+/* Ooops, too big. Shrink block B in symtab S to its minimal size.
+ Shrink_block can also be used by add_symbol to grow a block. */
+
+static struct block *
+shrink_block (struct block *b, struct symtab *s)
+{
+ struct block *new;
+ struct blockvector *bv = BLOCKVECTOR (s);
+ int i;
+
+ /* Just reallocate it and fix references to the old one */
+
+ new = (struct block *) xrealloc ((void *) b,
+ (sizeof (struct block)
+ + ((BLOCK_NSYMS (b) - 1)
+ * sizeof (struct symbol *))));
+
+ /* Should chase pointers to old one. Fortunately, that`s just
+ the block`s function and inferior blocks */
+ if (BLOCK_FUNCTION (new) && SYMBOL_BLOCK_VALUE (BLOCK_FUNCTION (new)) == b)
+ SYMBOL_BLOCK_VALUE (BLOCK_FUNCTION (new)) = new;
+ for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); i++)
+ if (BLOCKVECTOR_BLOCK (bv, i) == b)
+ BLOCKVECTOR_BLOCK (bv, i) = new;
+ else if (BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (bv, i)) == b)
+ BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (bv, i)) = new;
+ return new;
+}
+
+/* Create a new symbol with printname NAME */
+
+static struct symbol *
+new_symbol (char *name)
+{
+ struct symbol *s = ((struct symbol *)
+ obstack_alloc (&current_objfile->symbol_obstack,
+ sizeof (struct symbol)));
+
+ memset (s, 0, sizeof (*s));
+ SYMBOL_NAME (s) = obsavestring (name, strlen (name),
+ &current_objfile->symbol_obstack);
+ SYMBOL_LANGUAGE (s) = psymtab_language;
+ SYMBOL_INIT_DEMANGLED_NAME (s, &current_objfile->symbol_obstack);
+ return s;
+}
+
+/* Create a new type with printname NAME */
+
+static struct type *
+new_type (char *name)
+{
+ struct type *t;
+
+ t = alloc_type (current_objfile);
+ TYPE_NAME (t) = name;
+ TYPE_CPLUS_SPECIFIC (t) = (struct cplus_struct_type *) &cplus_struct_default;
+ return t;
+}
+
+/* Read ECOFF debugging information from a BFD section. This is
+ called from elfread.c. It parses the section into a
+ ecoff_debug_info struct, and then lets the rest of the file handle
+ it as normal. */
+
+void
+elfmdebug_build_psymtabs (struct objfile *objfile,
+ const struct ecoff_debug_swap *swap, asection *sec)
+{
+ bfd *abfd = objfile->obfd;
+ struct ecoff_debug_info *info;
+
+ info = ((struct ecoff_debug_info *)
+ obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct ecoff_debug_info)));
+
+ if (!(*swap->read_debug_info) (abfd, sec, info))
+ error ("Error reading ECOFF debugging information: %s",
+ bfd_errmsg (bfd_get_error ()));
+
+ mdebug_build_psymtabs (objfile, swap, info);
+}
+
+
+/* Things used for calling functions in the inferior.
+ These functions are exported to our companion
+ mips-tdep.c file and are here because they play
+ with the symbol-table explicitly. */
+
+/* Sigtramp: make sure we have all the necessary information
+ about the signal trampoline code. Since the official code
+ from MIPS does not do so, we make up that information ourselves.
+ If they fix the library (unlikely) this code will neutralize itself. */
+
+/* FIXME: This function is called only by mips-tdep.c. It needs to be
+ here because it calls functions defined in this file, but perhaps
+ this could be handled in a better way. Only compile it in when
+ tm-mips.h is included. */
+
+#ifdef TM_MIPS_H
+
+void
+fixup_sigtramp (void)
+{
+ struct symbol *s;
+ struct symtab *st;
+ struct block *b, *b0 = NULL;
+
+ sigtramp_address = -1;
+
+ /* We have to handle the following cases here:
+ a) The Mips library has a sigtramp label within sigvec.
+ b) Irix has a _sigtramp which we want to use, but it also has sigvec. */
+ s = lookup_symbol ("sigvec", 0, VAR_NAMESPACE, 0, NULL);
+ if (s != 0)
+ {
+ b0 = SYMBOL_BLOCK_VALUE (s);
+ s = lookup_symbol ("sigtramp", b0, VAR_NAMESPACE, 0, NULL);
+ }
+ if (s == 0)
+ {
+ /* No sigvec or no sigtramp inside sigvec, try _sigtramp. */
+ s = lookup_symbol ("_sigtramp", 0, VAR_NAMESPACE, 0, NULL);
+ }
+
+ /* But maybe this program uses its own version of sigvec */
+ if (s == 0)
+ return;
+
+ /* Did we or MIPSco fix the library ? */
+ if (SYMBOL_CLASS (s) == LOC_BLOCK)
+ {
+ sigtramp_address = BLOCK_START (SYMBOL_BLOCK_VALUE (s));
+ sigtramp_end = BLOCK_END (SYMBOL_BLOCK_VALUE (s));
+ return;
+ }
+
+ sigtramp_address = SYMBOL_VALUE (s);
+ sigtramp_end = sigtramp_address + 0x88; /* black magic */
+
+ /* But what symtab does it live in ? */
+ st = find_pc_symtab (SYMBOL_VALUE (s));
+
+ /*
+ * Ok, there goes the fix: turn it into a procedure, with all the
+ * needed info. Note we make it a nested procedure of sigvec,
+ * which is the way the (assembly) code is actually written.
+ */
+ SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
+ SYMBOL_CLASS (s) = LOC_BLOCK;
+ SYMBOL_TYPE (s) = init_type (TYPE_CODE_FUNC, 4, 0, (char *) NULL,
+ st->objfile);
+ TYPE_TARGET_TYPE (SYMBOL_TYPE (s)) = mdebug_type_void;
+
+ /* Need a block to allocate MIPS_EFI_SYMBOL_NAME in */
+ b = new_block (1);
+ SYMBOL_BLOCK_VALUE (s) = b;
+ BLOCK_START (b) = sigtramp_address;
+ BLOCK_END (b) = sigtramp_end;
+ BLOCK_FUNCTION (b) = s;
+ BLOCK_SUPERBLOCK (b) = BLOCK_SUPERBLOCK (b0);
+ add_block (b, st);
+ sort_blocks (st);
+
+ /* Make a MIPS_EFI_SYMBOL_NAME entry for it */
+ {
+ struct mips_extra_func_info *e =
+ ((struct mips_extra_func_info *)
+ xzalloc (sizeof (struct mips_extra_func_info)));
+
+ e->numargs = 0; /* the kernel thinks otherwise */
+ e->pdr.frameoffset = 32;
+ e->pdr.framereg = SP_REGNUM;
+ /* Note that setting pcreg is no longer strictly necessary as
+ mips_frame_saved_pc is now aware of signal handler frames. */
+ e->pdr.pcreg = PC_REGNUM;
+ e->pdr.regmask = -2;
+ /* Offset to saved r31, in the sigtramp case the saved registers
+ are above the frame in the sigcontext.
+ We have 4 alignment bytes, 12 bytes for onstack, mask and pc,
+ 32 * 4 bytes for the general registers, 12 bytes for mdhi, mdlo, ownedfp
+ and 32 * 4 bytes for the floating point registers. */
+ e->pdr.regoffset = 4 + 12 + 31 * 4;
+ e->pdr.fregmask = -1;
+ /* Offset to saved f30 (first saved *double* register). */
+ e->pdr.fregoffset = 4 + 12 + 32 * 4 + 12 + 30 * 4;
+ e->pdr.isym = (long) s;
+ e->pdr.adr = sigtramp_address;
+
+ current_objfile = st->objfile; /* Keep new_symbol happy */
+ s = new_symbol (MIPS_EFI_SYMBOL_NAME);
+ SYMBOL_VALUE (s) = (long) e;
+ SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE;
+ SYMBOL_CLASS (s) = LOC_CONST;
+ SYMBOL_TYPE (s) = mdebug_type_void;
+ current_objfile = NULL;
+ }
+
+ BLOCK_SYM (b, BLOCK_NSYMS (b)++) = s;
+}
+
+#endif /* TM_MIPS_H */
+
+void
+_initialize_mdebugread (void)
+{
+ mdebug_type_void =
+ init_type (TYPE_CODE_VOID, 1,
+ 0,
+ "void", (struct objfile *) NULL);
+ mdebug_type_char =
+ init_type (TYPE_CODE_INT, 1,
+ 0,
+ "char", (struct objfile *) NULL);
+ mdebug_type_unsigned_char =
+ init_type (TYPE_CODE_INT, 1,
+ TYPE_FLAG_UNSIGNED,
+ "unsigned char", (struct objfile *) NULL);
+ mdebug_type_short =
+ init_type (TYPE_CODE_INT, 2,
+ 0,
+ "short", (struct objfile *) NULL);
+ mdebug_type_unsigned_short =
+ init_type (TYPE_CODE_INT, 2,
+ TYPE_FLAG_UNSIGNED,
+ "unsigned short", (struct objfile *) NULL);
+ mdebug_type_int_32 =
+ init_type (TYPE_CODE_INT, 4,
+ 0,
+ "int", (struct objfile *) NULL);
+ mdebug_type_unsigned_int_32 =
+ init_type (TYPE_CODE_INT, 4,
+ TYPE_FLAG_UNSIGNED,
+ "unsigned int", (struct objfile *) NULL);
+ mdebug_type_int_64 =
+ init_type (TYPE_CODE_INT, 8,
+ 0,
+ "int", (struct objfile *) NULL);
+ mdebug_type_unsigned_int_64 =
+ init_type (TYPE_CODE_INT, 8,
+ TYPE_FLAG_UNSIGNED,
+ "unsigned int", (struct objfile *) NULL);
+ mdebug_type_long_32 =
+ init_type (TYPE_CODE_INT, 4,
+ 0,
+ "long", (struct objfile *) NULL);
+ mdebug_type_unsigned_long_32 =
+ init_type (TYPE_CODE_INT, 4,
+ TYPE_FLAG_UNSIGNED,
+ "unsigned long", (struct objfile *) NULL);
+ mdebug_type_long_64 =
+ init_type (TYPE_CODE_INT, 8,
+ 0,
+ "long", (struct objfile *) NULL);
+ mdebug_type_unsigned_long_64 =
+ init_type (TYPE_CODE_INT, 8,
+ TYPE_FLAG_UNSIGNED,
+ "unsigned long", (struct objfile *) NULL);
+ mdebug_type_long_long_64 =
+ init_type (TYPE_CODE_INT, 8,
+ 0,
+ "long long", (struct objfile *) NULL);
+ mdebug_type_unsigned_long_long_64 =
+ init_type (TYPE_CODE_INT, 8,
+ TYPE_FLAG_UNSIGNED,
+ "unsigned long long", (struct objfile *) NULL);
+ mdebug_type_adr_32 =
+ init_type (TYPE_CODE_PTR, 4,
+ TYPE_FLAG_UNSIGNED,
+ "adr_32", (struct objfile *) NULL);
+ TYPE_TARGET_TYPE (mdebug_type_adr_32) = mdebug_type_void;
+ mdebug_type_adr_64 =
+ init_type (TYPE_CODE_PTR, 8,
+ TYPE_FLAG_UNSIGNED,
+ "adr_64", (struct objfile *) NULL);
+ TYPE_TARGET_TYPE (mdebug_type_adr_64) = mdebug_type_void;
+ mdebug_type_float =
+ init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0,
+ "float", (struct objfile *) NULL);
+ mdebug_type_double =
+ init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0,
+ "double", (struct objfile *) NULL);
+ mdebug_type_complex =
+ init_type (TYPE_CODE_COMPLEX, 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0,
+ "complex", (struct objfile *) NULL);
+ TYPE_TARGET_TYPE (mdebug_type_complex) = mdebug_type_float;
+ mdebug_type_double_complex =
+ init_type (TYPE_CODE_COMPLEX, 2 * TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0,
+ "double complex", (struct objfile *) NULL);
+ TYPE_TARGET_TYPE (mdebug_type_double_complex) = mdebug_type_double;
+
+ /* Is a "string" the way btString means it the same as TYPE_CODE_STRING?
+ FIXME. */
+ mdebug_type_string =
+ init_type (TYPE_CODE_STRING,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "string",
+ (struct objfile *) NULL);
+
+ /* We use TYPE_CODE_INT to print these as integers. Does this do any
+ good? Would we be better off with TYPE_CODE_ERROR? Should
+ TYPE_CODE_ERROR print things in hex if it knows the size? */
+ mdebug_type_fixed_dec =
+ init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "fixed decimal",
+ (struct objfile *) NULL);
+
+ mdebug_type_float_dec =
+ init_type (TYPE_CODE_ERROR,
+ TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "floating decimal",
+ (struct objfile *) NULL);
+
+ nodebug_func_symbol_type = init_type (TYPE_CODE_FUNC, 1, 0,
+ "<function, no debug info>", NULL);
+ TYPE_TARGET_TYPE (nodebug_func_symbol_type) = mdebug_type_int;
+ nodebug_var_symbol_type =
+ init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0,
+ "<variable, no debug info>", NULL);
+}
diff --git a/gdb/mem-break.c b/gdb/mem-break.c
new file mode 100644
index 00000000000..9cf638e4c62
--- /dev/null
+++ b/gdb/mem-break.c
@@ -0,0 +1,135 @@
+/* Simulate breakpoints by patching locations in the target system, for GDB.
+
+ Copyright 1990, 1991, 1992, 1993, 1995, 1997, 1998, 1999, 2000,
+ 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Support. Written by John Gilmore.
+
+ 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 "defs.h"
+
+/* This file is only useful if BREAKPOINT is set. If not, we punt. */
+
+#include "symtab.h"
+#include "breakpoint.h"
+#include "inferior.h"
+#include "target.h"
+
+
+/* Use the program counter to determine the contents and size
+ of a breakpoint instruction. If no target-dependent macro
+ BREAKPOINT_FROM_PC has been defined to implement this function,
+ assume that the breakpoint doesn't depend on the PC, and
+ use the values of the BIG_BREAKPOINT and LITTLE_BREAKPOINT macros.
+ Return a pointer to a string of bytes that encode a breakpoint
+ instruction, stores the length of the string to *lenptr,
+ and optionally adjust the pc to point to the correct memory location
+ for inserting the breakpoint. */
+
+const unsigned char *
+memory_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+ /* {BIG_,LITTLE_}BREAKPOINT is the sequence of bytes we insert for a
+ breakpoint. On some machines, breakpoints are handled by the
+ target environment and we don't have to worry about them here. */
+#ifdef BIG_BREAKPOINT
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ static unsigned char big_break_insn[] = BIG_BREAKPOINT;
+ *lenptr = sizeof (big_break_insn);
+ return big_break_insn;
+ }
+#endif
+#ifdef LITTLE_BREAKPOINT
+ if (TARGET_BYTE_ORDER != BFD_ENDIAN_BIG)
+ {
+ static unsigned char little_break_insn[] = LITTLE_BREAKPOINT;
+ *lenptr = sizeof (little_break_insn);
+ return little_break_insn;
+ }
+#endif
+#ifdef BREAKPOINT
+ {
+ static unsigned char break_insn[] = BREAKPOINT;
+ *lenptr = sizeof (break_insn);
+ return break_insn;
+ }
+#endif
+ *lenptr = 0;
+ return NULL;
+}
+
+
+/* Insert a breakpoint on targets that don't have any better breakpoint
+ support. We read the contents of the target location and stash it,
+ then overwrite it with a breakpoint instruction. ADDR is the target
+ location in the target machine. CONTENTS_CACHE is a pointer to
+ memory allocated for saving the target contents. It is guaranteed
+ by the caller to be long enough to save BREAKPOINT_LEN bytes (this
+ is accomplished via BREAKPOINT_MAX). */
+
+int
+default_memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ int val;
+ const unsigned char *bp;
+ int bplen;
+
+ /* Determine appropriate breakpoint contents and size for this address. */
+ bp = BREAKPOINT_FROM_PC (&addr, &bplen);
+ if (bp == NULL)
+ error ("Software breakpoints not implemented for this target.");
+
+ /* Save the memory contents. */
+ val = target_read_memory (addr, contents_cache, bplen);
+
+ /* Write the breakpoint. */
+ if (val == 0)
+ val = target_write_memory (addr, (char *) bp, bplen);
+
+ return val;
+}
+
+
+int
+default_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ const unsigned char *bp;
+ int bplen;
+
+ /* Determine appropriate breakpoint contents and size for this address. */
+ bp = BREAKPOINT_FROM_PC (&addr, &bplen);
+ if (bp == NULL)
+ error ("Software breakpoints not implemented for this target.");
+
+ return target_write_memory (addr, contents_cache, bplen);
+}
+
+
+int
+memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ return MEMORY_INSERT_BREAKPOINT(addr, contents_cache);
+}
+
+int
+memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ return MEMORY_REMOVE_BREAKPOINT(addr, contents_cache);
+}
diff --git a/gdb/memattr.c b/gdb/memattr.c
new file mode 100644
index 00000000000..8c46d7eb168
--- /dev/null
+++ b/gdb/memattr.c
@@ -0,0 +1,536 @@
+/* Memory attributes support, for GDB.
+
+ Copyright 2001, 2002 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 "defs.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "memattr.h"
+#include "target.h"
+#include "value.h"
+#include "language.h"
+#include "gdb_string.h"
+
+const struct mem_attrib default_mem_attrib =
+{
+ MEM_RW, /* mode */
+ MEM_WIDTH_UNSPECIFIED,
+ 0, /* hwbreak */
+ 0, /* cache */
+ 0 /* verify */
+};
+
+static struct mem_region *mem_region_chain = NULL;
+static int mem_number = 0;
+
+static struct mem_region *
+create_mem_region (CORE_ADDR lo, CORE_ADDR hi,
+ const struct mem_attrib *attrib)
+{
+ struct mem_region *n, *new;
+
+ /* lo == hi is a useless empty region */
+ if (lo >= hi)
+ {
+ printf_unfiltered ("invalid memory region: low >= high\n");
+ return NULL;
+ }
+
+ n = mem_region_chain;
+ while (n)
+ {
+ /* overlapping node */
+ if ((lo >= n->lo && lo < n->hi) ||
+ (hi > n->lo && hi <= n->hi))
+ {
+ printf_unfiltered ("overlapping memory region\n");
+ return NULL;
+ }
+ n = n->next;
+ }
+
+ new = xmalloc (sizeof (struct mem_region));
+ new->lo = lo;
+ new->hi = hi;
+ new->number = ++mem_number;
+ new->enabled_p = 1;
+ new->attrib = *attrib;
+
+ /* link in new node */
+ new->next = mem_region_chain;
+ mem_region_chain = new;
+
+ return new;
+}
+
+static void
+delete_mem_region (struct mem_region *m)
+{
+ xfree (m);
+}
+
+/*
+ * Look up the memory region cooresponding to ADDR.
+ */
+struct mem_region *
+lookup_mem_region (CORE_ADDR addr)
+{
+ static struct mem_region region;
+ struct mem_region *m;
+ CORE_ADDR lo;
+ CORE_ADDR hi;
+
+ /* First we initialize LO and HI so that they describe the entire
+ memory space. As we process the memory region chain, they are
+ redefined to describe the minimal region containing ADDR. LO
+ and HI are used in the case where no memory region is defined
+ that contains ADDR. If a memory region is disabled, it is
+ treated as if it does not exist. */
+
+ lo = (CORE_ADDR) 0;
+ hi = (CORE_ADDR) ~ 0;
+
+ for (m = mem_region_chain; m; m = m->next)
+ {
+ if (m->enabled_p == 1)
+ {
+ if (addr >= m->lo && addr < m->hi)
+ return m;
+
+ if (addr >= m->hi && lo < m->hi)
+ lo = m->hi;
+
+ if (addr <= m->lo && hi > m->lo)
+ hi = m->lo;
+ }
+ }
+
+ /* Because no region was found, we must cons up one based on what
+ was learned above. */
+ region.lo = lo;
+ region.hi = hi;
+ region.attrib = default_mem_attrib;
+ return &region;
+}
+
+
+static void
+mem_command (char *args, int from_tty)
+{
+ CORE_ADDR lo, hi;
+ char *tok;
+ struct mem_attrib attrib;
+
+ if (!args)
+ error_no_arg ("No mem");
+
+ tok = strtok (args, " \t");
+ if (!tok)
+ error ("no lo address");
+ lo = parse_and_eval_address (tok);
+
+ tok = strtok (NULL, " \t");
+ if (!tok)
+ error ("no hi address");
+ hi = parse_and_eval_address (tok);
+
+ attrib = default_mem_attrib;
+ while ((tok = strtok (NULL, " \t")) != NULL)
+ {
+ if (strcmp (tok, "rw") == 0)
+ attrib.mode = MEM_RW;
+ else if (strcmp (tok, "ro") == 0)
+ attrib.mode = MEM_RO;
+ else if (strcmp (tok, "wo") == 0)
+ attrib.mode = MEM_WO;
+
+ else if (strcmp (tok, "8") == 0)
+ attrib.width = MEM_WIDTH_8;
+ else if (strcmp (tok, "16") == 0)
+ {
+ if ((lo % 2 != 0) || (hi % 2 != 0))
+ error ("region bounds not 16 bit aligned");
+ attrib.width = MEM_WIDTH_16;
+ }
+ else if (strcmp (tok, "32") == 0)
+ {
+ if ((lo % 4 != 0) || (hi % 4 != 0))
+ error ("region bounds not 32 bit aligned");
+ attrib.width = MEM_WIDTH_32;
+ }
+ else if (strcmp (tok, "64") == 0)
+ {
+ if ((lo % 8 != 0) || (hi % 8 != 0))
+ error ("region bounds not 64 bit aligned");
+ attrib.width = MEM_WIDTH_64;
+ }
+
+#if 0
+ else if (strcmp (tok, "hwbreak") == 0)
+ attrib.hwbreak = 1;
+ else if (strcmp (tok, "swbreak") == 0)
+ attrib.hwbreak = 0;
+#endif
+
+ else if (strcmp (tok, "cache") == 0)
+ attrib.cache = 1;
+ else if (strcmp (tok, "nocache") == 0)
+ attrib.cache = 0;
+
+#if 0
+ else if (strcmp (tok, "verify") == 0)
+ attrib.verify = 1;
+ else if (strcmp (tok, "noverify") == 0)
+ attrib.verify = 0;
+#endif
+
+ else
+ error ("unknown attribute: %s", tok);
+ }
+
+ create_mem_region (lo, hi, &attrib);
+}
+
+
+static void
+mem_info_command (char *args, int from_tty)
+{
+ struct mem_region *m;
+ struct mem_attrib *attrib;
+
+ if (!mem_region_chain)
+ {
+ printf_unfiltered ("There are no memory regions defined.\n");
+ return;
+ }
+
+ printf_filtered ("Num ");
+ printf_filtered ("Enb ");
+ printf_filtered ("Low Addr ");
+ if (TARGET_ADDR_BIT > 32)
+ printf_filtered (" ");
+ printf_filtered ("High Addr ");
+ if (TARGET_ADDR_BIT > 32)
+ printf_filtered (" ");
+ printf_filtered ("Attrs ");
+ printf_filtered ("\n");
+
+ for (m = mem_region_chain; m; m = m->next)
+ {
+ char *tmp;
+ printf_filtered ("%-3d %-3c\t",
+ m->number,
+ m->enabled_p ? 'y' : 'n');
+ if (TARGET_ADDR_BIT <= 32)
+ tmp = local_hex_string_custom ((unsigned long) m->lo, "08l");
+ else
+ tmp = local_hex_string_custom ((unsigned long) m->lo, "016l");
+
+ printf_filtered ("%s ", tmp);
+
+ if (TARGET_ADDR_BIT <= 32)
+ tmp = local_hex_string_custom ((unsigned long) m->hi, "08l");
+ else
+ tmp = local_hex_string_custom ((unsigned long) m->hi, "016l");
+
+ printf_filtered ("%s ", tmp);
+
+ /* Print a token for each attribute.
+
+ * FIXME: Should we output a comma after each token? It may
+ * make it easier for users to read, but we'd lose the ability
+ * to cut-and-paste the list of attributes when defining a new
+ * region. Perhaps that is not important.
+ *
+ * FIXME: If more attributes are added to GDB, the output may
+ * become cluttered and difficult for users to read. At that
+ * time, we may want to consider printing tokens only if they
+ * are different from the default attribute. */
+
+ attrib = &m->attrib;
+ switch (attrib->mode)
+ {
+ case MEM_RW:
+ printf_filtered ("rw ");
+ break;
+ case MEM_RO:
+ printf_filtered ("ro ");
+ break;
+ case MEM_WO:
+ printf_filtered ("wo ");
+ break;
+ }
+
+ switch (attrib->width)
+ {
+ case MEM_WIDTH_8:
+ printf_filtered ("8 ");
+ break;
+ case MEM_WIDTH_16:
+ printf_filtered ("16 ");
+ break;
+ case MEM_WIDTH_32:
+ printf_filtered ("32 ");
+ break;
+ case MEM_WIDTH_64:
+ printf_filtered ("64 ");
+ break;
+ case MEM_WIDTH_UNSPECIFIED:
+ break;
+ }
+
+#if 0
+ if (attrib->hwbreak)
+ printf_filtered ("hwbreak");
+ else
+ printf_filtered ("swbreak");
+#endif
+
+ if (attrib->cache)
+ printf_filtered ("cache ");
+ else
+ printf_filtered ("nocache ");
+
+#if 0
+ if (attrib->verify)
+ printf_filtered ("verify ");
+ else
+ printf_filtered ("noverify ");
+#endif
+
+ printf_filtered ("\n");
+
+ gdb_flush (gdb_stdout);
+ }
+}
+
+
+/* Enable the memory region number NUM. */
+
+static void
+mem_enable (int num)
+{
+ struct mem_region *m;
+
+ for (m = mem_region_chain; m; m = m->next)
+ if (m->number == num)
+ {
+ m->enabled_p = 1;
+ return;
+ }
+ printf_unfiltered ("No memory region number %d.\n", num);
+}
+
+static void
+mem_enable_command (char *args, int from_tty)
+{
+ char *p = args;
+ char *p1;
+ int num;
+ struct mem_region *m;
+
+ dcache_invalidate (target_dcache);
+
+ if (p == 0)
+ {
+ for (m = mem_region_chain; m; m = m->next)
+ m->enabled_p = 1;
+ }
+ else
+ while (*p)
+ {
+ p1 = p;
+ while (*p1 >= '0' && *p1 <= '9')
+ p1++;
+ if (*p1 && *p1 != ' ' && *p1 != '\t')
+ error ("Arguments must be memory region numbers.");
+
+ num = atoi (p);
+ mem_enable (num);
+
+ p = p1;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ }
+}
+
+
+/* Disable the memory region number NUM. */
+
+static void
+mem_disable (int num)
+{
+ struct mem_region *m;
+
+ for (m = mem_region_chain; m; m = m->next)
+ if (m->number == num)
+ {
+ m->enabled_p = 0;
+ return;
+ }
+ printf_unfiltered ("No memory region number %d.\n", num);
+}
+
+static void
+mem_disable_command (char *args, int from_tty)
+{
+ char *p = args;
+ char *p1;
+ int num;
+ struct mem_region *m;
+
+ dcache_invalidate (target_dcache);
+
+ if (p == 0)
+ {
+ for (m = mem_region_chain; m; m = m->next)
+ m->enabled_p = 0;
+ }
+ else
+ while (*p)
+ {
+ p1 = p;
+ while (*p1 >= '0' && *p1 <= '9')
+ p1++;
+ if (*p1 && *p1 != ' ' && *p1 != '\t')
+ error ("Arguments must be memory region numbers.");
+
+ num = atoi (p);
+ mem_disable (num);
+
+ p = p1;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ }
+}
+
+/* Clear memory region list */
+
+static void
+mem_clear (void)
+{
+ struct mem_region *m;
+
+ while ((m = mem_region_chain) != 0)
+ {
+ mem_region_chain = m->next;
+ delete_mem_region (m);
+ }
+}
+
+/* Delete the memory region number NUM. */
+
+static void
+mem_delete (int num)
+{
+ struct mem_region *m1, *m;
+
+ if (!mem_region_chain)
+ {
+ printf_unfiltered ("No memory region number %d.\n", num);
+ return;
+ }
+
+ if (mem_region_chain->number == num)
+ {
+ m1 = mem_region_chain;
+ mem_region_chain = m1->next;
+ delete_mem_region (m1);
+ }
+ else
+ for (m = mem_region_chain; m->next; m = m->next)
+ {
+ if (m->next->number == num)
+ {
+ m1 = m->next;
+ m->next = m1->next;
+ delete_mem_region (m1);
+ break;
+ }
+ }
+}
+
+static void
+mem_delete_command (char *args, int from_tty)
+{
+ char *p = args;
+ char *p1;
+ int num;
+
+ dcache_invalidate (target_dcache);
+
+ if (p == 0)
+ {
+ if (query ("Delete all memory regions? "))
+ mem_clear ();
+ dont_repeat ();
+ return;
+ }
+
+ while (*p)
+ {
+ p1 = p;
+ while (*p1 >= '0' && *p1 <= '9')
+ p1++;
+ if (*p1 && *p1 != ' ' && *p1 != '\t')
+ error ("Arguments must be memory region numbers.");
+
+ num = atoi (p);
+ mem_delete (num);
+
+ p = p1;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ }
+
+ dont_repeat ();
+}
+
+void
+_initialize_mem ()
+{
+ add_com ("mem", class_vars, mem_command,
+ "Define attributes for memory region.\n\
+Usage: mem <lo addr> <hi addr> [<mode> <width> <cache>], \n\
+where <mode> may be rw (read/write), ro (read-only) or wo (write-only), \n\
+ <width> may be 8, 16, 32, or 64, and \n\
+ <cache> may be cache or nocache");
+
+ add_cmd ("mem", class_vars, mem_enable_command,
+ "Enable memory region.\n\
+Arguments are the code numbers of the memory regions to enable.\n\
+Usage: enable mem <code number>\n\
+Do \"info mem\" to see current list of code numbers.", &enablelist);
+
+ add_cmd ("mem", class_vars, mem_disable_command,
+ "Disable memory region.\n\
+Arguments are the code numbers of the memory regions to disable.\n\
+Usage: disable mem <code number>\n\
+Do \"info mem\" to see current list of code numbers.", &disablelist);
+
+ add_cmd ("mem", class_vars, mem_delete_command,
+ "Delete memory region.\n\
+Arguments are the code numbers of the memory regions to delete.\n\
+Usage: delete mem <code number>\n\
+Do \"info mem\" to see current list of code numbers.", &deletelist);
+
+ add_info ("mem", mem_info_command,
+ "Memory region attributes");
+}
diff --git a/gdb/memattr.h b/gdb/memattr.h
new file mode 100644
index 00000000000..8643a23cec8
--- /dev/null
+++ b/gdb/memattr.h
@@ -0,0 +1,91 @@
+/* Memory attributes support, for GDB.
+ Copyright 2001 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. */
+
+#ifndef MEMATTR_H
+#define MEMATTR_H
+
+enum mem_access_mode
+{
+ MEM_RW, /* read/write */
+ MEM_RO, /* read only */
+ MEM_WO /* write only */
+};
+
+enum mem_access_width
+{
+ MEM_WIDTH_UNSPECIFIED,
+ MEM_WIDTH_8, /* 8 bit accesses */
+ MEM_WIDTH_16, /* 16 " " */
+ MEM_WIDTH_32, /* 32 " " */
+ MEM_WIDTH_64 /* 64 " " */
+};
+
+/* The set of all attributes that can be set for a memory region.
+
+ This structure was created so that memory attributes can be passed
+ to target_ functions without exposing the details of memory region
+ list, which would be necessary if these fields were simply added to
+ the mem_region structure.
+
+ FIXME: It would be useful if there was a mechanism for targets to
+ add their own attributes. For example, the number of wait states. */
+
+struct mem_attrib
+{
+ /* read/write, read-only, or write-only */
+ enum mem_access_mode mode;
+
+ enum mem_access_width width;
+
+ /* enables hardware breakpoints */
+ int hwbreak;
+
+ /* enables host-side caching of memory region data */
+ int cache;
+
+ /* enables memory verification. after a write, memory is re-read
+ to verify that the write was successful. */
+ int verify;
+};
+
+struct mem_region
+{
+ /* FIXME: memory regions are stored in an unsorted singly-linked
+ list. This probably won't scale to handle hundreds of memory
+ regions --- that many could be needed to describe the allowed
+ access modes for memory mapped i/o device registers. */
+ struct mem_region *next;
+
+ CORE_ADDR lo;
+ CORE_ADDR hi;
+
+ /* Item number of this memory region. */
+ int number;
+
+ /* Status of this memory region (enabled if non-zero, otherwise disabled) */
+ int enabled_p;
+
+ /* Attributes for this region */
+ struct mem_attrib attrib;
+};
+
+extern struct mem_region *lookup_mem_region(CORE_ADDR);
+
+#endif /* MEMATTR_H */
diff --git a/gdb/mi/ChangeLog b/gdb/mi/ChangeLog
new file mode 100644
index 00000000000..a750d8c2571
--- /dev/null
+++ b/gdb/mi/ChangeLog
@@ -0,0 +1,1818 @@
+2002-05-20 Keith Seitz <keiths@redhat.com>
+
+ * mi-main.c (captured_mi_execute_command): Add uiout parameter.
+ "data" is now a structure which is used to pass data to/from this
+ function to mi_execute_command.
+ Modify function to comply with requirements from catch_exceptions.
+ Store real return result and command's return result in data.
+ (mi_execute_command): Use catch_exceptions.
+ Use enum to handle actions to be performed instead of overloading
+ catch_errors return result and the mi return result.
+
+2002-04-14 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-main.c (mi_cmd_exec_return):
+
+2002-04-09 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-main.c (register_changed_p): Use frame_register_read instead
+ of read_relative_register_raw_bytes.
+ (get_register): Delete out-of-date comment.
+
+2002-04-07 Elena Zannoni <ezannoni@redhat.com>
+
+ * mi-cmd-disas.c: Run through indent.
+
+2002-04-07 Elena Zannoni <ezannoni@redhat.com>
+
+ * mi-cmd-disas.c (dump_insns): New function.
+ (do_mixed_source_and_assembly): New function.
+ (do_assembly_only): New function.
+ (do_disassembly): New function.
+ (mi_cmd_disassemble): Rewrite using smaller, more modular
+ functions.
+
+2002-04-05 Jim Blandy <jimb@redhat.com>
+
+ * mi-cmd-stack.c (list_args_or_locals): Pass new arg to
+ get_frame_block. (See entry in gdb/ChangeLog.)
+
+2002-04-05 Elena Zannoni <ezannoni@redhat.com>
+
+ * mi-cmd-disas.c (mi_cmd_disassemble): Use TARGET_PRINT_INSN
+ instead of tm_print_insn.
+ Update copyright year.
+
+2002-04-04 Daniel Jacobowitz <drow@mvista.com>
+
+ * mi-cmd-disas.c (mi_cmd_disassemble): Skip end-of-function
+ markers in the line table.
+
+2002-03-15 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-main.c (XMALLOC): Delete macro.
+ * mi-out.c (XMALLOC): Ditto.
+ * mi-parse.c (XMALLOC): Ditto.
+ * mi-console.c (XMALLOC): Ditto.
+ * mi-cmd-var.c (XMALLOC): Ditto.
+ * mi-cmd-break.c (XMALLOC): Ditto.
+
+ * mi/mi-cmd-var.c, mi/mi-console.c, mi/mi-out.c: Update copyright
+ * mi/mi-parse.c: Ditto.
+
+2002-02-24 Andrew Cagney <ac131313@redhat.com>
+
+ From wiz at danbala:
+ * gdbmi.texinfo: Fix grammar and typos.
+ Fix PR gdb/287.
+
+2002-02-03 Jim Blandy <jimb@redhat.com>
+
+ * mi-cmd-stack.c (list_args_or_locals): Move declaration of
+ print_me inside the loop body, so it gets re-initialized every
+ iteration. The cases for the different symbol kinds leave
+ print_me unchanged if they don't want the symbol printed.
+
+2002-01-22 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbmi.texinfo: Remove makeinfo 3.12 hacks.
+
+2002-01-21 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-cmd-stack.c: Remove #else clause of #ifdef UI_OUT.
+ * mi-cmd-break.c: Ditto.
+ * mi-main.c: Ditto.
+
+2001-12-30 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdbmi.texinfo: Fix the application of GFDL in the Copyright notice.
+
+2001-10-12 Daniel Jacobowitz <drow@mvista.com>
+
+ * mi-cmd-stack.c (list_args_or_locals): Use ALL_BLOCK_SYMBOLS.
+
+2001-09-18 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-main.c (mi_cmd_thread_select): Pass uiout to
+ gdb_thread_select.
+ (mi_cmd_thread_list_ids): Pass uiout to gdb_list_thread_ids.
+
+ * mi-cmd-break.c (breakpoint_notify): Pass uiout to
+ gdb_breakpoint_query.
+
+2001-08-17 Keith Seitz <keiths@redhat.com>
+
+ * mi-cmd-var.c (varobj_update_one): Update call to
+ varobj_update to reflect recent api change.
+
+2001-07-26 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-main.c: Include "gdb.h".
+ * mi-cmd-break.c: Include "gdb.h".
+
+2001-07-12 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-main.c (mi_execute_command): Flush output after ``(gdb)''
+ prompt. Bug reported by David Whedon.
+ (mi_execute_async_cli_command): Ditto.
+ (mi_exec_async_cli_cmd_continuation): Ditto.
+ (mi_command_loop): Ditto.
+
+2001-07-10 Mark Kettenis <kettenis@gnu.org>
+
+ * mi-out.c (mi_out_new): Initialize suppress_ouput field of newly
+ created `struct ui_out_data'.
+
+2001-07-09 Kevin Buettner <kevinb@redhat.com>
+
+ * mi-main.c (register_changed_p, get_register): Use alloca()
+ to allocate space previously allocated via gcc's
+ variable-length array extension.
+ (mi_cmd_data_write_register_values, mi_cmd_data_write_memory):
+ Change type of ``buffer'' to ``void *''. Don't cast return value
+ from xmalloc(). Add a cleanup to free the xmalloc'd buffer.
+
+2001-07-07 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-main.c (mi_cmd_data_evaluate_expression): Replace value_ptr
+ with `struct value *'.
+
+2001-07-08 Kevin Buettner <kevinb@redhat.com>
+
+ * mi-out.c (mi_table_header, mi_field_int, mi_field_skip)
+ (mi_field_string) Make function declarators match earlier
+ declarations.
+
+2001-07-04 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-out.c (mi_ui_out_impl): Initialize is_mi_like_p to one.
+
+2001-06-27 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-out.c (mi_table_begin): Include nr_cols and nr_rows in mi1
+ table output.
+ * mi-out.c (mi_table_begin): Only suppress output when mi0. Change
+ the header to a list.
+ (mi_table_body): For mi1, close the header list and open a table
+ body list.
+ (mi_table_end): For mi1, close the body list.
+ (mi_table_header): For mi1, output a tuple containing all the
+ header information.
+ (mi_open, mi_close): Reverse logic of mi_version test.
+ * gdbmi.texinfo (GDB/MI Breakpoint Table Commands): Update.
+
+2001-06-26 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbmi.texinfo (GDB/MI Output Syntax): Delete reference to query
+ packet.
+
+2001-06-26 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-cmd-stack.c (list_args_or_locals): Output a list of "args" or
+ "locals" entries.
+ * gdbmi.texinfo (stack-list-locals, stack-list-arguments)
+ (exec-interrupt, target-select, thread-select): Update
+ documentation.
+
+2001-06-26 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-cmd-stack.c (mi_cmd_stack_list_frames): Output a list of
+ "stack" entries.
+ (mi_cmd_stack_list_args): Ditto for "stack-args".
+ * gdbmi.texinfo (stack-list-frames, stack-list-arguments): Update
+ documentation.
+ (GDB/MI Stack Manipulation Commands): Fix section title. Was
+ Stack Manipulation Commands in GDB/MI.
+
+2001-06-25 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbmi.texinfo: Update output examples that contain stop reason
+ output, change the args=.... to a list.
+ (exec-return): Ditto.
+
+2001-06-25 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-main.c (mi_cmd_data_read_memory): Output the memory contents
+ - memory and data - as a list.
+ * gdbmi.texinfo (data-read-memory): Update documentation.
+
+2001-06-25 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-main.c (mi_cmd_data_list_register_values): Output a list of
+ register values.
+ * gdbmi.texinfo (data-list-register-values): Update documentation.
+
+2001-06-25 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-main.c (mi_cmd_data_list_register_names): Output a list of
+ register names.
+ (mi_cmd_data_list_register_names): Include the pseudo registers.
+ (mi_cmd_data_list_register_names): Don't leave holes in the list,
+ output "" for NULL registers.
+ * gdbmi.texinfo (data-list-register-names): Update documentation.
+
+2001-06-23 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-main.c (mi_cmd_data_list_changed_registers): Output a list of
+ register numbers.
+ * gdbmi.texinfo (data-list-changed-registers): Update
+ documentation.
+
+2001-06-23 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbmi.texinfo (data-disassemble): Update documentation of
+ output. Produces a list of instructions and a list of source
+ lines.
+
+2001-06-22 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-cmd-disas.c (mi_cmd_disassemble): For "-data-disassemble",
+ output a list instead of a tupple.
+
+2001-06-21 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-out.c (struct ui_out_data): Replace field first_header with
+ suppress_output.
+ (mi_begin, mi_end): Check suppress_header.
+ (mi_field_int, mi_field_skip): Ditto.
+ (mi_field_string, mi_field_fmt): Ditto.
+ (mi_table_begin): When nr_rows is zero, set suppress_header else,
+ output the start of the header.
+ (mi_table_body): Clear suppress header.
+
+2001-06-21 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-out.c (mi_open): For lists, when mi_version > 0, use ``[''.
+ (mi_close): Ditto for ``]''.
+
+2001-06-20 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-out.c (mi_table_header): Add parameter ``col_name''.
+
+2001-06-18 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-out.c: Include "gdb_assert.h".
+ (mi_table_begin): Add parameter ``nr_rows''.
+
+2001-06-18 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-main.c: Use strncmp as the "mi" test. Allow "mi", "mi0" and
+ "mi1".
+ (mi_command_loop): Add parameter mi_version, pass to mi_out_new.
+ (mi1_command_loop, mi0_command_loop): New functions.
+ (_initialize_mi_main): Recognize "mi", "mi0" and "mi1".
+ * mi-out.c (mi_out_new): Add parameter mi_version.
+ (struct ui_out_data): Add field mi_version.
+ * mi-out.h (mi_out_new): Update.
+
+2001-06-07 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbmi.texinfo (GDB/MI Output Syntax): Add tuples and lists to
+ syntax.
+ (GDB/MI Draft Changes to Output Syntax): Delete section.
+
+Mon Jun 11 17:22:25 2001 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-out.c: Fix typo. s/supress/suppress/.
+
+2001-06-09 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-out.c (mi_table_end, mi_table_begin, mi_begin, mi_end): Move
+ supress_field_separator updates from here.
+ (mi_open, mi_close): To here.
+ (mi_open): Add parameter name. Output a field_separator.
+ (mi_table_begin): Update.
+ (mi_table_header): Update.
+ (mi_begin): Update.
+
+2001-06-09 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-out.c (mi_table_begin): Make char* parameters constant.
+ (mi_table_header): Ditto.
+ (mi_field_int): Ditto.
+ (mi_field_skip): Ditto.
+ (mi_field_string): Ditto.
+ (mi_field_fmt): Ditto.
+ (mi_text): Ditto.
+ (mi_message): Ditto.
+
+2001-05-12 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-out.c (mi_close, mi_open): Output ``[]'' when a list.
+
+Fri May 11 13:55:07 2001 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmd-var.c: Replace ui_out_list_begin, ui_out_list_end and
+ make_cleanup_ui_out_list_end with ui_out_tupple_begin,
+ ui_out_tupple_end and make_cleanup_ui_out_tupple_begin_end.
+ * mi-cmd-stack.c: Ditto.
+ * mi-cmd-disas.c: Ditto.
+ * mi-main.c: Ditto.
+
+2001-05-10 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-out.c (mi_open, mi_close): Replace list_open and list_close.
+ (mi_table_begin): Update.
+ (mi_table_header): Update.
+ (mi_begin): Update.
+ (mi_table_body): Update.
+ (mi_table_end): Update.
+ (mi_end): Update.
+
+Thu May 10 16:28:13 2001 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_execute_async_cli_command): Always initialize
+ old_cleanups.
+
+2001-05-08 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-out.c (mi_begin, mi_end): Replace mi_list_begin and
+ mi_list_end.
+ (mi_ui_out_impl): Update.
+
+2001-03-28 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-main.c (mi_cmd_data_read_memory): Use xcalloc.
+
+2001-03-26 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdbmi.texinfo: Update copyright. Change Permissions to GFDL.
+
+2001-03-20 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-cmd-disas.c (mi_cmd_disassemble): Initialize ``file_string''
+ and ``line_num''. Consolidate declaration of argument variables.
+
+2001-03-19 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-out.h: Remove #ifdef __STDC__.
+
+2001-03-08 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-main.c (mi_cmd_data_list_register_names): Use NUM_REGS, not
+ ARCH_NUM_REGS.
+ (mi_cmd_data_list_changed_registers): Ditto.
+ (mi_cmd_data_list_register_values): Ditto.
+ (mi_cmd_data_write_register_values): Ditto.
+
+2001-03-06 Kevin Buettner <kevinb@redhat.com>
+
+ * gdbmi.texinfo, mi-cmd-disas.c, mi-cmd-stack.c, mi-cmd-var.c,
+ mi-cmds.c, mi-cmds.h, mi-console.c, mi-console.h, mi-getopt.c,
+ mi-getopt.h, mi-out.c, mi-out.h, mi-parse.c, mi-parse.h:
+ Update/correct copyright notices.
+
+Wed Feb 7 19:50:37 2001 Andrew Cagney <cagney@redhat.com>
+
+ * mi-getopt.c: Add __FILE__ and __LINE__ parameter to calls to
+ internal_error.
+ * mi-console.c: Ditto.
+ * mi-cmds.c: Ditto.
+ * mi-cmd-break.c: Ditto.
+
+2001-01-27 Fernando Nasser <fnasser@redhat.com>
+
+ From Momchil Velikov <velco@fadata.bg>
+ * mi-cmd-disas.c (gdb_dis_asm_read_memory): Add missing memory
+ attributes argument in the call to `xfer_memory'.
+
+2000-12-14 Kevin Buettner <kevinb@redhat.com>
+
+ * mi-cmd-disas.c, mi-cmd-var.c, mi-console.c, mi-main.c,
+ mi-parse.c: Replace occurrences of free() with xfree().
+
+Fri Nov 17 16:07:23 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c: Replace asprintf with xasprintf.
+ * mi-cmd-var.c (mi_cmd_var_create): Ditto.
+
+2000-10-16 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdbmi.texinfo (GDB/MI Variable Objects): Dimensions of
+ multitable changed to "@columnfractions .4 .6". Suggested by
+ Dmitry Sivachenko <dima@Chg.RU>.
+
+2000-08-23 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdbmi.texinfo: Change flathead -> @sc{gdb/mi}.
+ Fix typos and markup mistakes (from Dmitry S.
+ Sivachenko <dima@Chg.RU>).
+
+2000-07-24 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdbmi.texinfo: Change GDB -> @value{GDBN}, and
+ (gdb) -> (@value{GDBP}). Fix a few typos and some markup. From
+ Dmitry S. Sivachenko <dima@Chg.RU>.
+
+Tue May 16 14:13:41 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_cmd_execute): Use free_current_contents.
+ (free_and_reset): Delete.
+
+Mon May 15 16:17:56 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_cmd_data_assign, mi_cmd_data_evaluate_expression),
+ mi-cmd-var.c (mi_cmd_var_create, mi_cmd_var_delete): Delete
+ make_cleanup_func casts. Not needed.
+
+2000-05-07 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdbmi.texinfo: Lots of typos and grammar fixes from Brian
+ Youmans <3diff@flib.gnu.ai.mit.edu>.
+
+Wed Apr 26 18:35:19 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbmi.texinfo (GDB/MI Output Syntax v2.0): Convert Draft 2.0
+ Output Syntax into a new section. Cross reference.
+ (menu): Fix tipo. GDB/MI Compatibility with CLI.
+
+2000-04-23 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * gdbmi.texinfo: Lots of changes, to include this document as part
+ of the GDB manual.
+
+2000-03-13 James Ingham <jingham@leda.cygnus.com>
+
+ * mi-cmd-var.c (mi_cmd_var_create): Add special frame cookie "@"
+ to indicate an "USE_CURRENT_FRAME" variable.
+ (varobj_update_one): Add "in_scope" and "type_changed" to the
+ result.
+
+2000-03-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.h: Export mi_cmd_data_write_register_values.
+
+ * mi-cmds.c (mi_cmds): Implement data-write-register-values with
+ mi_cmd_data_write_register_values.
+
+ * mi-main.c (mi_cmd_data_write_register_values): New
+ function. Write a value into a register.
+
+2000-03-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Update data-disassemble documentation.
+
+2000-03-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmd-disas.c (mi_cmd_disassemble): Use
+ ui_out_field_core_addr() instead of print_address_numeric(), to
+ maintain consistency throughout MI.
+
+Wed Feb 23 17:09:39 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmd-break.c, mi-cmd-disas.c, mi-cmd-stack.c, mi-cmd-var.c,
+ mi-cmds.c, mi-cmds.h, mi-console.c, mi-console.h, mi-getopt.c,
+ mi-getopt.h, mi-main.c, mi-out.c, mi-out.h, mi-parse.c,
+ mi-parse.h: Update copyright information.
+
+Wed Feb 23 13:31:16 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmd-disas.c (gdb_dis_asm_read_memory): Change LEN to unsigned
+ long. Match ../include/dis-asm.h change.
+
+Wed Feb 23 10:30:55 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbmi.texinfo: Update copyright - FSF. Update version
+ information.
+
+ mi-cmd-break.c, mi-cmd-disas.c, mi-cmd-stack.c, mi-cmd-var.c,
+ mi-cmds.h, mi-main.c, mi-parse.c, mi-parse.h: Re-format using GNU
+ indent.
+
+2000-02-21 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c: Add include of gdbcore.h for write_memory()
+ prototype.
+
+2000-02-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmd-disas.c (mi_cmd_disassemble): Change syntax of
+ command. Now use options.
+ Instead of printing the symbolic address of instructions via
+ print_address_symbolic(), use build_address_symbolic() and format
+ properly for output.
+ (gdb_do_disassmble): Delete.
+
+2000-02-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmd-disas.c (mi_cmd_disassemble):
+
+2000-02-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_data_write_memory): New function. Write a
+ value into target memory.
+
+ * mi-cmds.h (mi_cmd_data_write_memory): Export.
+
+ * mi-cmds.c (mi_cmds): Hook up data-write-memory to
+ mi_cmd_data_write_memory().
+
+2000-02-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_target_download): Correct error message to
+ report right function name.
+ (mi_cmd_target_select): Add doing exec cleanups at end.
+ (mi_cmd_data_read_memory): Correct typo.
+ (mi_cmd_execute): Do not simply free last_async_command, but reset
+ it to NULL as well.
+ (free_and_reset): New function, free the argument and set it to
+ NULL.
+ (mi_cmd_target_select_continuation): Delete prototype.
+
+Tue Feb 1 00:17:12 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmd-disas.c, mi-cmds.h, mi-console.c, mi-console.h,
+ mi-main.c, mi-out.c, mi-out.h: Update to reflect rename of
+ gdb-file / GDB_FILE to ui-file / ``struct ui_file''.
+
+Mon Jan 31 18:33:28 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_command_loop): Delete reference to
+ fputs_unfiltered_hook.
+
+2000-01-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Update entries for
+ mi_cmd_data_list_register_names,
+ mi_cmd_data_list_changed_registers,
+ mi_cmd_data_list_register_values.
+
+ * mi-cmds.h (mi_cmd_data_list_register_names,
+ mi_cmd_data_list_changed_registers,
+ mi_cmd_data_list_register_values): Update to mi_cmd_argv_ftype.
+
+ * mi-main.c (mi_cmd_data_list_register_names,
+ mi_cmd_data_list_changed_registers,
+ mi_cmd_data_list_register_values): Update to use argc, argv
+ parameters.
+
+2000-01-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_data_read_memory): Correct the computation of
+ next-row.
+
+2000-01-27 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmd-var.c (mi_cmd_var_create): Test for NULL type.
+ (mi_cmd_var_set_format, mi_cmd_var_show_format,
+ mi_cmd_var_info_num_children, mi_cmd_var_list_children,
+ mi_cmd_var_info_type, mi_cmd_var_info_expression,
+ mi_cmd_var_show_attributes, mi_cmd_var_evaluate_expression,
+ mi_cmd_var_assign, mi_cmd_var_update): Prevent possibility of memory
+ leak on error.
+
+2000-01-27 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c (mi_field_string): Test for NULL string pointer.
+
+2000-01-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmd-stack.c (mi_cmd_stack_list_frames): Call
+ print_frmae_info() with the correct arguments.
+
+ * mi-main.c (mi_cmd_exec_return): Call
+ show_and_print_stack_frame() with LOC_AND_ADDRESS, so it does the
+ right thing. Update Copyright.
+
+2000-01-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c: Move disassemble commands from here.
+
+ * mi-cmd-disas.c: To here. New file.
+
+2000-01-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmd-stack.c: Remove include of mi-out.h.
+
+ * mi-main.c (mi_cmd_disassemble): Update function to use argc/argv
+ interface.
+
+ * mi-cmds.h: Ditto.
+
+ * mi-cmds.c: Ditto.
+
+2000-01-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Update stack commands descriptions.
+ Add thread commands descriptions and examples.
+
+ * mi-main.c (mi_cmd_thread_list_ids): Fix typo.
+
+2000-01-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_thread_list_ids): New function, print a list
+ of currently known threads ids, and the total number of threads.
+ (mi_cmd_thread_select): New function. Switch current thread.
+
+ * mi-cmds.c (mi_cmds): Implement thread-list-ids by
+ mi_cmd_thread_list_ids, and thread-select by mi_cmd_thread_select.
+
+ * mi-cmds.h (mi_cmd_thread_select, mi_cmd_thread_list_ids): Export.
+
+2000-01-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c: Move stack commands from here.
+
+ * mi-cmd-stack.c: To here. New file.
+
+2000-01-07 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (list_args_or_locals): Add a new paramter, the frame
+ for which to display args or locals. Don't use selected_frame
+ anymore, use the new parameter instead. Return void instead of
+ mi_cmd_result, let callers do so.
+ (mi_cmd_stack_list_args): Change interface. Now accept low and
+ high frame numbers to display args for a range of frames. Without
+ these two, display args for the whole stack.
+ (mi_cmd_stack_list_locals): Adapt to new interface for
+ list_args_or_locals.
+
+2000-01-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_stack_info_depth, mi_cmd_stack_list_args,
+ mi_cmd_stack_list_frames, mi_cmd_stack_list_locals,
+ mi_cmd_stack_select_frame): Change to use argv type of parameters.
+
+ * mi-cmds.c (mi_cmds): Change stack-info-depth,
+ stack-list-arguments, stack-list-frames, stack-list-locals,
+ stack-select-frame to use argv parameters.
+
+ * mi-cmds.h (mi_cmd_stack_info_depth, mi_cmd_stack_list_args,
+ mi_cmd_stack_list_frames, mi_cmd_stack_list_locals,
+ mi_cmd_stack_select_frame): Update definitions.
+
+Tue Jan 4 12:38:54 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_command_loop): Force the MI interface to use seven
+ bit strings.
+ * gdbmi.texinfo: Make it clear that a quoted C string is seven
+ bit.
+
+Thu Dec 30 14:15:22 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-getopt.c (mi_getopt): Rewrite. Allow long options.
+ * mi-getopt.h (struct mi_opt): Declare.
+ (mi_getopt): Update.
+
+ * mi-main.c (mi_cmd_data_read_memory), mi-cmd-break.c
+ (mi_cmd_break_insert, mi_cmd_break_watch): Update.
+
+Wed Dec 29 23:38:35 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmd-break.c (mi_cmd_break_insert): Add support for -c
+ <condition>, -i <ignore-count> and -p <thread>.
+ (breakpoint_notify): New function.
+ (mi_cmd_break_insert): Wrap GDB call with callback hooks so that
+ MI is notified when ever a breakpoint is created.
+
+ * gdbmi.texinfo: Update.
+
+Fri Dec 24 11:23:22 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (gdb_do_disassemble): Strip out more useless #ifdef
+ UI_OUTs.
+
+1999-12-23 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (gdb_do_disassemble): Fix output. Lines that have no
+ assembly instructions must still be outputted, to keep the source
+ line numbering correct.
+ Remove #ifdef UI_OUT's, they are useless.
+
+1999-12-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (gdb_do_disassemble): Don't print a new list in mixed
+ mode, every time. Just do it when we actually encounter a new
+ source line.
+
+1999-12-17 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmd-var.c (mi_cmd_var_list_children): Add test for C++ pseudo
+ variable objects (private, public, protected) as these do not have
+ a type and the -var-list-children operation was dumping core.
+
+Fri Dec 17 20:23:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbmi.texinfo: Document recommended syntax for options.
+
+ * mi-main.c (mi_cmd_data_read_memory): Add support for ``-o
+ <offset>''.
+ * gdbmi.texinfo: Document.
+
+Wed Dec 15 17:43:08 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-getopt.h (mi_getopt): Change optarg to a char pointer. Check
+ optind.
+ * mi-cmd-break.c (mi_cmd_break_insert): Update.
+
+ * mi-main.c (mi_cmd_data_read_memory): Add fields "next-row-addr",
+ "prev-row-addr", "next-page-addr", "prev-page-addr" and a per row
+ "addr".
+ * gdbmi.texinfo: Update.
+
+Wed Dec 15 01:05:40 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h (mi_cmd_result): Add MI_CMD_CAUGHT_ERROR for when the
+ error is caught.
+
+ * mi-main.c (captured_mi_execute_command): When
+ MI_CMD_CAUGHT_ERROR return 0 rethrowing the eror.
+
+1999-12-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmd-break.c (mi_cmd_break_insert): Remove unused var.
+
+ * mi-cmd-var.c (mi_cmd_var_update): Remove unused variables.
+
+Mon Dec 13 18:43:36 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-parse.c (mi_parse): Quote the command when printing it.
+ (mi_parse_argv): Fix handling of quoted strings. Was not
+ de-quoting them.
+ (mi_parse_argv): Make static.
+
+Mon Dec 13 18:30:03 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h (mi_cmd_break_insert, mi_cmd_break_watch): Change type
+ to mi_cmd_argv_ftype.
+ * mi-cmds.c (mi_cmds): Update.
+ * mi-cmd-break.c (mi_cmd_break_insert, mi_cmd_break_watch): Change
+ to new style of arguments with argc and argv. Parse arguments
+ using mi_getopt.
+
+ * mi-cmd-break.c (mi_cmd_break_insert): Wrap body in #ifdef UI_OUT
+ to avoid non-ui compile problems.
+
+Mon Dec 13 15:08:36 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-getopt.h, mi-getopt.c: New files. Similar to getopt but with
+ well defined semantics.
+
+Mon Dec 13 14:22:21 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_cmd_break_insert, mi_cmd_break_watch, enum
+ wp_type, enum bp_type): Move from here.
+ * mi-cmd-break.c: To here. New file.
+ (mi_cmd_break_insert, mi_cmd_break_insert, mi_cmd_break_watch):
+ Use error to report problems.
+
+1999-12-09 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Update description of exec-interrupt.
+
+ * mi-main.c (mi_cmd_exec_interrupt): If the program is not
+ executing, don't try to interrupt it, but error out instead. Make
+ sure previous_async_command is not null before duplicating it into
+ last_async_command.
+
+ * gdbmi.texinfo: Add examples for data-evaluate-expression.
+
+1999-12-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmd-var.c (mi_cmd_var_assign, mi_cmd_var_create,
+ mi_cmd_var_delete, mi_cmd_var_evaluate_expression,
+ mi_cmd_var_info_expression, mi_cmd_var_info_num_children,
+ mi_cmd_var_info_type, mi_cmd_var_list_children,
+ mi_cmd_var_set_format, mi_cmd_var_show_attributes,
+ mi_cmd_var_show_format, mi_cmd_var_update): Change to use new
+ style of arguments with argc and argv.
+ (next_arg): Delete.
+ (which_var): Delete.
+
+ * mi-cmds.c (mi_cmds): Update entries for mi_cmd_var_assign,
+ mi_cmd_var_create, mi_cmd_var_delete,
+ mi_cmd_var_evaluate_expression, mi_cmd_var_info_expression,
+ mi_cmd_var_info_num_children, mi_cmd_var_info_type,
+ mi_cmd_var_list_children, mi_cmd_var_set_format,
+ mi_cmd_var_show_attributes, mi_cmd_var_show_format,
+ mi_cmd_var_update.
+
+ * mi-cmds.h (mi_cmd_var_assign, mi_cmd_var_create,
+ mi_cmd_var_delete, mi_cmd_var_evaluate_expression,
+ mi_cmd_var_info_expression, mi_cmd_var_info_num_children,
+ mi_cmd_var_info_type, mi_cmd_var_list_children,
+ mi_cmd_var_set_format, mi_cmd_var_show_attributes,
+ mi_cmd_var_show_format, mi_cmd_var_update): Update declarations.
+
+1999-12-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Comment out -data-assign command. * mi-main.c
+ (mi_cmd_data_assign): Do not use, comment out. * mi-cmds.h
+ (mi_cmd_data_assign): Remove. * mi-cmds.c: Remove -data-assign
+ command from MI interface.
+
+1999-12-07 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-parse.c (mi_parse): Add '\n' at end of error messages, so
+ that prompt comes out on new line.
+
+ * gdbmi.texinfo: Update disassembly command output.
+
+1999-12-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (gdb_do_disassemble): Update output for UI_OUT case.
+
+1999-12-02 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Update exec-until output, including the reason
+ for stopping.
+
+Thu Dec 2 17:17:22 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.c: Include <string.h> for memset.
+
+1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_exec_return): ifdef the references to
+ return_command_wrapper().
+
+1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_gdb_exit, mi_cmd_exec_interrupt,
+ mi_cmd_target_select, mi_execute_async_cli_command,
+ mi_exec_async_cli_cmd_continuation, mi_load_progress): Don't print
+ last_async_command if it is NULL.
+ (mi_cmd_exec_return):
+
+1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_exec_return): Reimplement using
+ return_command() instead of mi_execute_async_cli_command().
+
+1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.h: Export mi_cmd_data_assign and
+ mi_cmd_data_evaluate_expression.
+
+ * mi-cmds.c (mi_cmds): Hook data-assign to mi_cmd_data_assign and
+ data-evaluate-expression to mi_cmd_data_evaluate_expression.
+
+ * mi-main.c (mi_cmd_data_assign): New function. Implement
+ data-assign command.
+ (mi_cmd_data_evaluate_expression): New function. Implement
+ data-evaluate-expression command.
+
+1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Fix some texinfo formatting errors.
+
+1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Update data-list-register-values description.
+
+ * mi-cmds.h: Export mi_cmd_data_list_register_values.
+
+ * mi-cmds.c (mi_cmds): Hook data-list-register-values to
+ mi_cmd_data_list_register_values.
+
+ * mi-main.c (mi_cmd_data_list_register_values): New
+ function. Implements the -data-list-register-values command.
+ (get_register): New function. Output the contents of a given
+ register.
+
+Wed Dec 1 20:27:22 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_execute_async_cli_command): Append missing "\n"
+ for synchronous stopped message.
+
+1999-11-30 James Ingham <jingham@leda.cygnus.com>
+
+ * gdbmi.texinfo: Fix obvious typo in @end statement.
+
+Wed Dec 1 12:36:27 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmd-var.c: Include "value.h".
+ * mi-console.c: Include <string.h>.
+
+Wed Dec 1 00:21:03 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (captured_mi_execute_command): For a CLI command, pass
+ "%s" to mi_execute_cli_command to stop core dumps.
+ (captured_mi_execute_command): Echo CLI commands on gdb_stdlog.
+
+Wed Dec 1 00:10:07 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbmi.texinfo: Explain NR-BYTES and ADDR.
+
+Tue Nov 30 23:31:57 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmd-var.c (mi_cmd_var_create, mi_cmd_var_delete,
+ mi_cmd_var_set_format, mi_cmd_var_show_format,
+ mi_cmd_var_info_num_children, mi_cmd_var_list_children,
+ mi_cmd_var_info_type, mi_cmd_var_info_expression,
+ mi_cmd_var_show_attributes, mi_cmd_var_evaluate_expression,
+ mi_cmd_var_assign, mi_cmd_var_update, varobj_update_one, next_arg,
+ which_var): New file. Move varobj commands to here from
+ mi-main.c.
+
+ * mi-console.h, mi-console.c (mi_console_file_new,
+ mi_console_file_delete, mi_console_file_fputs,
+ mi_console_raw_packet, mi_console_file_flush): New files. Move
+ mi_console_file to here from mi-main.c.
+
+Tue Nov 30 19:37:25 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (captured_mi_execute_command): Use fputstr_unfiltered
+ when printing error messages.
+ (mi_cmd_execute): Ditto.
+
+1999-11-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Describe -data-list-changed-registers,
+ -data-list-register-names. Add examples for
+ -exec-next-instruction, exec-step-instruction, -exec-run,
+ -exec-until. Format examples for -data-read-memory.
+ update example for -target-download.
+
+1999-11-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Remove mentioning of inaccurate watchpoint hit
+ count.
+
+Mon Nov 29 19:28:55 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_execute_async_cli_command): Return ``enum
+ mi_cmd_cmd_result''. mi_cmd_exec_run, mi_cmd_exec_next,
+ mi_cmd_exec_step, mi_cmd_exec_step_instruction,
+ mi_cmd_exec_finish, mi_cmd_exec_until, mi_cmd_exec_return,
+ mi_cmd_exec_continue): Update call.
+ (mi_execute_async_cli_command): When target is synchronous, fake
+ asynchronous behavour (ulgh). Allows tests to be run on built-in
+ simulator and native targets.
+
+Mon Nov 29 15:15:16 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h (mi_cmd_gdb_exit), mi-cmds.c (mi_cmds), mi-main.c
+ (mi_cmd_gdb_exit): Change function signature to mi_cmd_argv_ftype.
+
+1999-11-28 Andew Cagney <cagney@rat-in-a-hat.cygnus.com>
+
+ * mi-parse.c: Include <ctype.h> and <string.h>
+
+1999-11-26 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Added watchpoint command descriptions and
+ examples.
+
+ * mi-main.c (mi_load_progress): Add parameter for total sent so far.
+ Print it as well.
+
+Fri Nov 26 10:17:49 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbmi.texinfo (section Output Syntax): For lists, the <string>
+ part of a <result> is optional. Clarify syntax.
+ (appendix Proposed v2.0 Output Syntax): New section. Provide
+ record of discussion of possible changes to syntax.
+
+Wed Nov 24 19:41:35 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_cmd_data_read_memory): Simplify. Fix coredump
+ when arguments were bad.
+ (mi_cmd_execute): Change parameter to ``struct mi_parse''. Handle
+ case of argv_func as well as args_func.
+ (captured_mi_execute_command): Update.
+
+ * mi-cmds.c (struct mi_cmd): Add field for mi_cmd_argv_ftype.
+ (mi_cmds): Update mi_cmd_data_read_memory.
+ (mi_lookup): Return
+
+ * mi-cmds.h (mi_cmd_args_ftype): Rename mi_cmd_ftype. Make all
+ functions of type this type.
+ (mi_cmd_argv_ftype): Declare.
+ (mi_cmd_data_read_memory): Change type to mi_cmd_argv_fytpe.
+ (struct mi_cmd): Move declaration to here from mi-cmds.c.
+ (mi_lookup): Return a pointer to ``struct mi_cmd''.
+
+Wed Nov 24 15:03:34 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-parse.c (mi_parse): Initialize TOKEN when a CLI command.
+
+ * gdbmi.texinfo: Allow a <token> before a CLI command.
+
+ * mi-parse.h (struct mi_parse): Declare.
+ (mi_parse): Change to return a ``struct mi_parse''.
+ (enum mi_command_type): Delete PARSE_ERROR.
+
+ * mi-main.c (struct mi_execute_command_context): Delete.
+ (captured_mi_execute_command): Update
+ (mi_execute_command): Update. Check for mi_parse returning NULL.
+
+Wed Nov 24 12:57:14 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-parse.h: Remove const, from cmd parameter. Causes cascading
+ warnings.
+
+Wed Nov 24 15:03:34 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-parse.c (mi_parse): New function. Move parse code to here.
+ * mi-main.c (parse): From here. Delete.
+
+Wed Nov 24 12:57:14 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-parse.c, mi-parse.h: New files. Implement mi_parse_env.
+
+Wed Nov 24 11:24:05 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-out.c (mi_field_string): Make string parameter constant.
+
+1999-11-23 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.h (mi_cmd_target_download): Export.
+
+ * mi-cmds.c (mi_cmds): Add mi_cmd_target_download.
+
+ * mi-main.c: Include <sys/time.h>.
+ (mi_cmd_target_download): New function, implement the
+ target-download command.
+ (mi_load_progress): New function. Called via the
+ show_load_progress hook. Prints updates every 0.5 secs.
+ (mi_command_loop): Initialize the show_load_progress hook.
+
+1999-11-22 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_exec_until): New function. Implement until
+ command.
+ (mi_cmd_exec_step_instruction): New function. Implement stepi
+ command.
+ (mi_cmd_exec_next_instruction): New function. Implement nexti
+ command.
+
+ * mi-cmds.c (mi_cmds): Add mi_cmd_exec_step_instruction,
+ mi_cmd_exec_next_instruction, mi_cmd_exec_until.
+
+ * mi-cmds.h (mi_cmd_exec_step_instruction,
+ mi_cmd_exec_next_instruction, mi_cmd_exec_until): Export.
+
+Tue Nov 23 00:30:37 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi/gdbmi.texinfo: Document -data-read-memory.
+
+ * mi-main.c (mi_cmd_data_read_memory): Fix off-by-one check of
+ argc.
+ (mi_cmd_data_read_memory): Label the output table with "memory".
+
+Thu Nov 18 18:15:53 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_cmd_exec_interrupt, mi_cmd_break_insert,
+ mi_cmd_break_watch, mi_cmd_disassemble, mi_cmd_execute): Replace
+ strdup with xstrdup.
+
+Thu Nov 18 20:50:09 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_cmd_data_read_memory): New function. Implement
+ data-read-memory.
+
+ * mi-cmds.h, mi-cmds.c: Add mi_cmd_data_read_memory.
+ * mi-cmds.c (mi_cmds): Ditto.
+
+1999-11-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.h (mi_cmd_break_watch): Export.
+
+ * mi-cmds.c (mi_cmds): Hook up break-watch to function
+ mi_cmd_break_watch.
+
+ * mi-main.c (wp_type): New enumeration for the possible types of
+ watchpoints.
+ (mi_cmd_break_watch): New function, implements the break-watch
+ command.
+
+1999-11-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_break_insert): Handle case in which the command is
+ just a -break-insert w/o args.
+
+Fri Nov 12 00:01:52 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-out.c (mi_field_string): Always quote the string.
+
+1999-11-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.h(mi_cmd_data_list_changed_registers,
+ mi_cmd_data_list_register_names): Export.
+
+ * mi-cmds.c (mi_cmds): Hook up data-list-changed-registers to
+ mi_cmd_data_list_changed_registers and data-list-register-names to
+ mi_cmd_data_list_register_names.
+
+ * mi-main.c (mi_cmd_data_list_changed_registers): New function,
+ implements the data-list-changed-registers command.
+ (mi_cmd_data_list_register_names): New function, implements the
+ data-list-register-names command.
+ (register_changed_p): New function. Decide whether the register
+ contents have changed.
+ (setup_architecture_data): New function. Initialize registers
+ memory.
+ (_initialize_mi_main): Call setup_architecture_data(), and
+ register_gdbarch_swap().
+
+Wed Nov 10 18:35:08 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_execute_command): Correctly quote error messages.
+
+Wed Nov 10 11:05:14 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi/gdbmi.texinfo: Delete <stream-output>. Replaced by
+ <c-string>.
+
+ * mi-main.c (mi_console_raw_packet): Always quote console output.
+
+Tue Nov 9 17:53:05 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_console_file_new), mi-out.c (mi_out_new): Replace
+ the tui_file with a mem_file. Ya!
+
+ * mi-out.c (do_write): New function, wrapper to gdb_file_write.
+ (mi_out_put): Pass do_write to gdb_file_put.
+
+ * mi-main.c (mi_console_file_flush): Rewrite. Use
+ mi_console_raw_packet to send data to the console.
+ (mi_console_raw_packet): New function. Correctly
+ create quoted C string packets.
+
+1999-11-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Break-insert is now implemented by
+ mi_cmd_break_insert.
+ * mi-cmds.h (mi_cmd_break_insert): Export.
+ * mi-main.c (bp_type): New enumeration.
+ (mi_cmd_break_insert): New function. Implements all flavors of
+ breakpoint insertion.
+
+Mon Nov 8 17:49:17 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_console_file_flush): Replace gdb_file_get_strbuf
+ with tui_file_get_strbuf.
+
+Fri Nov 5 17:06:07 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_console_file_delete, mi_console_file_fputs,
+ mi_console_file_flush): Call internal_error instead of error.
+
+Thu Nov 4 19:53:32 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (captured_mi_execute_command): New function.
+ (mi_execute_command): Rewrite. Replace SET_TOP_LEVEL() with call
+ to captured_mi_execute_command via catch_errors.
+
+Thu Nov 4 20:33:58 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (clean): Delete.
+ (mi_command_loop): Delete extern declaration of
+ mi_execute_command.
+
+1999-10-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_stack_select_frame): Conditionalize the body
+ on UI_OUT, because select_frame_command_wrapper is only defined if
+ UI_OUT is.
+ (mi_cmd_exec_interrupt): Conditionalize the body on UI_OUT,
+ because interrupt_target_command_wrapper is only defined if UI_OUT is.
+
+ * mi-cmds.c (mi_cmds): Implement command exec-interrupt by
+ mi_cmd_exec_interrupt.
+
+ * mi-main.c (mi_cmd_exec_interrupt): New function. Implements
+ exec-interrupt command.
+ (mi_cmd_execute): If the target is running save execution command
+ token in previous_async_command. If the command is not 'interrupt'
+ and the target is running, reject it.
+ (clean): New function. Free the arg and reset it to NULL.
+
+ * mi-cmds.h (mi_cmd_exec_interrupt):Export.
+
+1999-10-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Implement command stack-select-frame by
+ mi_cmd_stack_select_frame.
+
+ * mi-main.c (mi_cmd_stack_select_frame): New function. Implements
+ stack-select-frame command.
+
+ * mi-cmds.h (mi_cmd_select_frame):Export.
+
+1999-10-26 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Implement commands stack-list-locals and
+ stack-list-arguments by mi_cmd_stack_list_locals and
+ mi_cmd_stack_list_args.
+
+ * mi-main.c (mi_cmd_stack_list_locals): New function. Implements
+ stack-list-locals command.
+ (mi_cmd_stack_list_args): New function. Implements
+ stack-list-arguments command.
+ (list_args_or_locals): New function. Do all the work for the
+ listing of locals or arguments.
+
+ * mi-cmds.h (mi_cmd_stack_list_args,mi_cmd_stack_list_locals) :
+ Export.
+
+1999-10-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Add new command stack-info-depth.
+
+ * mi-main.c (mi_cmd_stack_info_depth): New function. Implements
+ the stack-info-depth command.
+ * mi-cmds.h (mi_cmd_stack_info_depth): Export.
+
+
+1999-10-22 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_execute_command): Handle MI_CMD_ERROR case
+ properly, for command that return error code and don't set
+ mi_error_message.
+
+ * mi-cmds.c (mi_cmds): Hook stack-list-frames command to
+ mi_cmd_stack_list_frames function.
+ * mi-cmds.h (mi_cmd_stack_list_frames): Export.
+
+ * mi-main.c (mi_execute_command): Deal with a return code of
+ MI_CMD_ERROR from the execution of mi commands.
+ (mi_error_message): Static string variable, to contain the error
+ message from mi commands.
+ (mi_cmd_stack_list_frames): New function. Prints a backtrace.
+
+1999-10-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_disassemble): Handle the new command line
+ parameter that specifies the number of disassembly lines to be
+ displayed.
+ (gdb_do_disassemble): Add new parameter. Count the number of lines
+ that have been displayed, and stop when limit is reached.
+
+Wed Oct 13 18:04:13 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_command_loop): Don't initialize ``flush_hook''.
+
+1999-10-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi/gdbmi.texinfo: More reformatting of the grammars.
+
+1999-10-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi/gdbmi.texinfo: More TeX formatting.
+
+1999-10-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi/gdbmi.texinfo: First pass completed. All commands should have
+ some comments/info.
+ Escape '@' output special char.
+ Reformat for TeX.
+
+1999-10-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi/gdbmi.texinfo: Filled in part of file command section, and
+ stack section.
+
+1999-10-07 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi/gdbmi.texinfo: Filled in some sections about execution
+ commands.
+
+Tue Oct 5 15:27:28 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h: Sort table
+ * mi-cmds.c: Ditto.
+ (MI_TABLE_SIZE): Increase to 251.
+
+1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_cmd_var_create, mi_cmd_var_delete): Add missing
+ cleanups.
+
+1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (next_arg): Returns lenght as well.
+ (which_var, mi_cmd_var_create, mi_cmd_var_delete,
+ mi_cmd_var_set_format, mi_cmd_var_update): Do not modify the input
+ string, use allocated storage instead.
+ (mi_cmd_var_assign): Adjust call to next_arg() to include new
+ argument.
+
+1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_execute_command): Fix handling of errors.
+
+1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c (mi_out_new): Call tui_sfileopen() instead of
+ deprecated gdb_file_init_astream().
+ * mi-main.c (mi_console_file_new): Ditto.
+
+Mon Oct 4 15:17:29 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h: Sort function declarations.
+ (mi_lookup): Add extern.
+
+ * mi-cmds.c (mi_lookup): Delete dead code.
+ (build_table): Call internal_error instead of error.
+ (build_table): Send trace output to gdb_stdlog.
+
+1999-10-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_execute_async_cli_command): Don't do the cleanups
+ if target_executing is null.
+
+1999-09-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (async_p): Change var name to event_loop_p.
+
+Mon Sep 27 15:11:00 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_execute_async_cli_command, mi_execute_command):
+ Replace target_has_async with function target_can_async_p.
+
+Sun Sep 26 00:12:52 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_cmd_target_select_continuation): Delete function.
+ (mi_cmd_target_select): Simplify. target-connect is guarenteed to
+ be synchronous.
+
+Sun Sep 26 00:12:52 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h (mi_cmd_ftype): Replace mi_impl_ftype.
+ (enum mi_cmd_result): Define.
+ * mi-cmds.c (struct mi_cmd): Update.
+ (mi_lookup): Update.
+ * mi-main.c (mi_cmd_execute): Update.
+
+ * mi-main.c (mi_cmd_gdb_exit, mi_cmd_exec_run, mi_cmd_exec_next,
+ mi_cmd_exec_step, mi_cmd_target_select, mi_cmd_exec_continue,
+ mi_cmd_exec_return, mi_cmd_exec_finish, mi_cmd_disassemble,
+ mi_cmd_var_create, mi_cmd_var_delete, mi_cmd_var_set_format,
+ mi_cmd_var_show_format, mi_cmd_var_info_num_children,
+ mi_cmd_var_list_children, mi_cmd_var_info_type,
+ mi_cmd_var_info_expression, mi_cmd_var_show_attributes,
+ mi_cmd_var_evaluate_expression, mi_cmd_var_update): Update.
+ Return MI_CMD_DONE.
+
+1999-09-22 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_cmd_var_create): Use paddr() to format address
+ on trace output.
+
+1999-09-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_cmd_var_create): Test for varobjdebug before
+ printing trace and send it to gdb_stdlog.
+
+Mon Sep 20 13:41:04 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (mi-out.o): Add dependency list.
+ * mi-out.c: Include "mi-out.h".
+
+1999-09-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (_initialize_mi_main): Events on stadin are now
+ handled by stdin_event_handler.
+
+1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Add var-* commands.
+
+1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_cmd_var_create, mi_cmd_var_delete,
+ mi_cmd_var_set_format, mi_cmd_var_show_format,
+ mi_cmd_var_info_num_children, mi_cmd_var_list_children,
+ mi_cmd_var_info_type, mi_cmd_var_info_expression,
+ mi_cmd_var_show_attributes, mi_cmd_var_evaluate_expression,
+ mi_cmd_var_assign, mi_cmd_var_update, varobj_update_one,
+ which_var, next_arg): New functions. Implement the -var-*
+ commands.
+ * mi-cmds.h: Add prototypes for the above.
+
+1999-09-14 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Add detach command.
+
+1999-09-09 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmds.c (lookup_table): Fix typo.
+
+1999-09-09 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Fix typo and missing command.
+
+1999-09-09 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c: Properly align function prototypes.
+ (mi_cmd_target_select): Proper check for NULL value.
+
+1999-09-09 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_execute_async_cli_command): Fix for native targets
+ that do not have async yet.
+
+1999-09-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_disassemble): Remove unused var.
+ (gdb_do_disassemble): Ditto.
+
+1999-08-30 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c: Replace all the occurrences of 'asynch' in variable
+ or function names with 'async' to make it consistent with the rest
+ of gdb.
+
+Mon Aug 30 18:16:39 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c: #include <ctype.h> for isspace().
+
+1999-08-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (gdb_do_disassemble): This function returns void, not
+ int.
+
+1999-08-26 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_disassemble): Don't use atoi() on the high
+ address string, just treat it same as address low.
+ (gdb_do_disassemble): Parse high_address string before seeing if
+ it is zero.
+
+1999-08-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_disassemble): New function to produce
+ disassembly output for mi.
+ (gdb_dis_asm_read_memory): New function. Read the disassembly from
+ the executable file, instead of target memory.
+ (compare_lines): New function. Compare order of disassembly lines.
+ (gdb_do_disassemble): New function. Do the real job of getting the
+ assembly code out.
+
+ * mi-cmds.c (mi_cmds): Do data-disassemble mi command via the
+ mi_cmd_disassemble function.
+
+ * mi-cmds.h: Export new function mi_cmd_disassemble.
+
+Wed Aug 25 15:58:31 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_command_loop): Remove references to ui-hooks.
+
+1999-08-21 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_execute_asynch_cli_command): Fix the incorrect
+ usage of strcat(): allocate enough space for the string.
+
+1999-08-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Christopher Faylor <cgf@cygnus.com>
+ * mi-main.c (mi_execute_command): Make sure we flush all the
+ output after each command.
+
+1999-08-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (_initialize_mi_main): Remove casting in call to
+ add_file_handler.
+
+Sun Aug 8 17:20:57 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_cmd_target_select, mi_execute_asynch_cli_command):
+ Replace call to fatal with call to internal_error.
+
+1999-07-26 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_cmd_execute): Add return code.
+ (mi_execute_command): Make appropriate changes when calling the
+ function mentioned above.
+ (mi_cmd_gdb_exit, mi_cmd_target_select,
+ mi_cmd_target_select_continuation, mi_execute_command,
+ mi_exec_asynch_cli_cmd, mi_exec_asynch_cli_cmd_continuation):
+ Print token, prefix, class and output (if any) in one single group
+ of statements.
+ (mi_execute_command, mi_cmd_execute): Fix error prefix.
+ (mi_cmd_execute): Use exec cleanup for token.
+ * mi-out.c (mi_out_rewind): New function.
+ * mi-out.h: Prototype for the above.
+
+1999-07-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_cmd_gdb_exit): Use buffer for exit message.
+ (mi_cmd_execute): Route error messages to correct file.
+ (mi_execute_asynch_cli_command): Insert line feed after running
+ message.
+
+1999-07-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.h (mi_out_buffered): Add extern declaration.
+ * mi-out.c (mi_out_buffered): New function. Insert a string at the
+ current buffer position.
+ * mi-main.c (mi_cmd_target_select, mi_execute_command,
+ mi_cmd_execute, mi_execute_asynch_cli_command): Use the above
+ function instead of printing to raw_stdout.
+ (mi_cmd_target_select, mi_cmd_target_select_continuation,
+ mi_execute_command, mi_cmd_execute, mi_execute_cli_command,
+ mi_exec_asynch_cli_cmd_continuation): Fix handling of token and
+ prefix.
+ (mi_execute_cli_command): Remove parameter no longer needed.
+
+1999-07-15 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_target_select_continuation): Print the numeric
+ token when we are connected.
+ (mi_execute_command): Don't print the token now, do it later.
+ (mi_execute_cli_command): Add a new parameter for the numeric
+ token. Print the token, the prefix and the class after the
+ command has executed, not before.
+ (mi_execute_asynch_cli_command): Don't print an extra blank line.
+
+1999-07-15 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_gdb_exit): Add \n at the end.
+
+1999-07-15 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_cmd_execute): New function. Dispatch a mi operation.
+ (mi_execute_command): Use the above.
+
+1999-07-15 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c: Fix identation.
+
+1999-07-15 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c: Include target.h and inferior.h.
+ (mi_cmd_target_select): New function to execute the target-select
+ mi operation.
+ (mi_cmd_target_select_continuation): New function. Continuation
+ for the target-select operation.
+ (mi_execute_command): In case of an MI command which requires
+ asynchronous execution, do not try to display the result now. If
+ the execution has to look synchronous don't display the "(gdb)"
+ prompt.
+ (mi_execute_asynch_cli_command): Invoke real asynchronous
+ commands, set up exec_cleanups, and continuations.
+ (mi_exec_asynch_cli_cmd_continuation): New function. Continuation
+ for all the MI execution commands except 'target-select'.
+ (mi_execute_command): Handle null commands by exiting gdb, instead
+ of core dumping.
+
+ * mi-cmds.c (mi_cmds): Hook up -target-select operation to new mi
+ function.
+
+ * mi-cmds.h (mi_cmd_target_select): Add extern declaration.
+
+Thu Jul 15 10:31:39 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (struct mi_console_file): Add field ``prefix''.
+ (mi_console_file_new): Add argument prefix. Initialize prefix
+ field.
+ (mi_console_file_flush): Use ``prefix'' instead of "~" as the
+ prefix string.
+ (mi_command_loop): Update stream output prefixes. gdb_stdout ==
+ "~", gdb_stderr / gdb_stdlog == "&", gdb_stdtarg == "@".
+
+1999-07-13 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (ui_out_data): New field first_header. Fix output when
+ no breakpoints are found.
+ (mi_table_begin, mi_table_body, mi_table_header): Test for
+ first_header.
+ (mi_table_end): Test for supress_field_separator.
+ (mi_message): Remove messages from MI output.
+
+1999-06-30 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmds.c (mi_cmds[]): Delete gdb-cli operation.
+ * mi-main.c (parse): Remove ifdefs for cli commands parsing.
+ (mi-execute-command): Ditto.
+
+Mon Jun 28 13:06:52 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-out.h: New file.
+ (mi_out_new, mi_out_put): Move mi specific delcarations to here.
+ * ui-out.h: From here.
+
+ * mi-main.c: Include "mi-out.h".
+
+1999-06-25 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * top.c (print_gdb_version): Add the word HEADLESS when output
+ follows headless format.
+ (print_command_lines): Fix typo.
+
+1999-06-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-loop.h: Export input_fd.
+ * mi-main.c (mi_command_loop): Use the event loop if running
+ asynchronously.
+ (mi_execute_command_wrapper): New function.
+ (_initialize_mi-main): Set things up for running asynchronously.
+
+1999-06-18 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmds.c (mi_lookup): Deleted.
+ (lookup_table): New function. Replaces old mi_lookup() for local
+ use.
+ (mi_lookup): New function. External interface for command table
+ searchs.
+ (build_table): New definition.
+ (mi_cmds[]): Add several command implementations and the gdb-cli
+ special operation.
+ (mi_cmd_execute): Deleted.
+ * mi-cmds.h: Add type definition for command implementation
+ function pointers, add declaration for new implementation
+ functions and a declaration for mi_lookup().
+ * mi-main.c (mi_execute_asynch_cli_command): New
+ function. Captures code that was repeated for all asynch
+ operations.
+ (mi_cmd_exec_*): Use the above new function.
+ (mi_gdb_cmd_exit): Fix the output, printing something appropriate.
+ (mi_cmd_exec_finish): New operation implementation function.
+ (mi_cmd_exec_return): Ditto.
+ (parse): Prepare to remove cli commands.
+ (mi_execute_command): Fix the output and change the way mi-cmds is
+ used.
+
+1999-06-18 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c (mi_table_begin): Add missing field separator call.
+
+Thu Jun 17 21:05:40 1999 Fernando Nasser <fnasser@tofu.to.cygnus.com>
+
+ * breakpoint.c (breakpoint_1): Remove space in breakpoint table
+ id.
+ (mention): Use ui_out for last new line (forgotten).
+
+1999-06-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_console_file_flush): Prevent prefix printing when
+ buffer empty; change prefix to '~'.
+ (mi_cmd_exec_*): Prefix normal output with '^' instead of
+ ','; remove unwanted new lines before "stopped".
+
+1999-06-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmds.c (struct mi_cmds): Updated entries for -exec-continue
+ and exec-next operations.
+ (mi_cmd_execute): New text for error messages.
+ * mi-cmds.h: Add declaration for mi_cmd_exec_next and
+ mi_cmd_exec_continue.
+ * mi-main.c (mi_cmd_exec_next): New function. Implements exec-next
+ operation.
+ (mi_cmd_exec_continue): New function. Implements exec-continue
+ operation.
+ (mi_execute_comand): Add missing space to prompt.
+ (mi_cmd_exec_run): Ditto.
+ (mi_cmd_exec_step): Ditto.
+ * mi-out.c (mi_out_new): Add flags argument to ui_out_new call.
+ (ui_list_end): Reset supress_field_separator flag.
+
+Sat Jun 12 11:49:10 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h. mi-cmds.c (exec step): Command implemented by
+ mi_cmd_exec_step instead of cli call.
+ * mi-main.c (mi_cmd_exec_step): New function.
+
+ * mi-cmds.h. mi-cmds.c (exec run): Command implemented by
+ mi_cmd_exec_run instead of cli call.
+ * mi-main.c (mi_cmd_exec_run): New function.
+
+ * mi-cmds.h. mi-cmds.c (gdb exit): Command implemented by
+ mi_cmd_gdb_exit instead of quit_force.
+ * mi-main.c (mi_cmd_gdb_exit): New function.
+
+Sat Jun 12 11:33:23 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_command_loop): Pass mi_input to
+ simplified_command_loop.
+ (mi_input): New function. Calls gdb_readline with no prompt.
+
+Sat Jun 12 11:19:02 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_console_file_fputs): Re-implement. Use a buffer
+ to accumulate output.
+
+ * mi-main.c (struct mi_console_file): Add a buffer.
+ (mi_console_file_new): Create a buffer.
+ (mi_console_file_flush): New function.
+
+Sat Jun 12 10:59:39 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h (raw_stdout): Declare. Will be moved later.
+ * mi-cmds.c (mi_cmd_execute): Send error messages to RAW stdout.
+ (mi_cmds): Sort by class.
+
+ * mi-main.c (raw_stdout): Make global.
+ * mi-main.c: Remove #ifdef UI_OUT. File assumes UI_OUT is
+ present.
+ * mi-main.c: Include "gdb_string.h".
+ (mi_out_put): Delete declaration.
+
+1999-06-11 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c: Add pre-processor test for UI_OUT.
+ (mi_execute_command): Add pre-processor test for UI_OUT.
+
+Fri Jun 11 23:11:41 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (raw_stdout): New variable.
+ (mi_execute_command): Write mi-out direct to raw_stdout.
+ (mi_command_loop): Create raw_stdout. Attach gdb_stdout to the
+ console.
+ (mi_console_file_fputs, mi_console_file_delete,
+ mi_console_file_new): New functions.
+ (struct mi_console_file): Declare.
+
+Fri Jun 11 18:34:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_execute_command): Call mi_out_put to display the
+ result.
+ * mi-out.c (mi_out_put): New function.
+ * ui-out.h (mi_out_put): Add declare. Will move later.
+ * Makefile.in (mi-cmds.o, mi-main.o): Add dependency on ui-out.h.
+
+ * mi-out.c (mi_field_string, mi_field_fmt, mi_message, mi_flush,
+ out_field_fmt, list_open, list_close): Replace gdb_stdout with
+ data->buffer.
+ (field_separator, list_open, list_close): Add uiout parameter.
+ (mi_table_begin, mi_table_body, mi_table_end, mi_list_begin,
+ mi_list_end, mi_field_string, mi_field_fmt, out_field_fmt,
+ out_field_fmt): Update.
+
+ * mi-out.c (mi_out_new): Initialize supress_field_separator.
+ (supress_field_separator): Move into mi-out local data object.
+ (mi_table_begin, mi_list_begin, field_separator): Update.
+
+Fri Jun 11 16:08:37 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-out.c (mi_out_new): New function, replace init_mi_out.
+ * mi-main.c (mi_command_loop): Call mi_out_new().
+
+ * ui-out.h (mi_out_new): Add declaration. Will move later.
+ (mi_ui_out_impl): Delete.
+
+Wed Jun 9 16:42:16 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c: Include "ui-hooks.h".
+ (mi_init_ui, mi_command_loop): New functions.
+ (_initialize_mi_main): Install ``mi'' as the interpreter when
+ selected.
+
+Mon Jun 7 18:43:43 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Fernando Nasser <fnasser@totem.to.cygnus.com>
+ * mi-cmds.c (build_table): Clean up error message.
+ * mi-cmds.c (mi_cmd_execute), mi-main.c (mi_execute_command): Only
+ print debug information when mi_debug_p.
+ * mi-cmds.h (mi_debug_p), mi-main.c: Global, control debug messages.
+
+Thu Jun 3 00:44:52 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Fernando Nasser <fnasser@totem.to.cygnus.com>:
+ * mi-cmds.c: Add CLI definitions for "exec-arguments",
+ "exec-next", "gdb-exit", "break-list", "break-info", "exec-step"
+ and "stack-list-frames" to mi_cmds.
+ (struct mi_command): Add ``from_tty'' argument to func.
+ * mi-cmds.h (quit_force): Declare.
+
+1999-05-31 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c (mi_table_end): Remove unwanted "\n".
+
+Thu May 27 14:59:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c: Include "ui-hooks.h".
+ (call_interp_loop): Tempoary. Pass mi_execute_command to
+ simplified_command_loop. Initialize gdb_stdout & gdb_stderr to
+ stdio gdb_file streams. Force all hooks to null.
+
+ * mi-cmds.h, mi-main.c, mi-cmds.c: New files.
+ * Makefile.in (SFILES): Add mi-main.c, mi-cmds.c
+ (COMMON_OBS): Add mi-main.o, mi-cmds.o.
+ (mi_cmds_h): Define.
+
+Wed May 26 12:39:49 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c (call_interp_loop): Hack. Add extern declaration for
+ mi_ui_out_impl.
+
+1999-05-25 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c: New table syntax.
+
+Mon May 24 16:16:29 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ mi-out.c (_initialize_mi_out): Add external declaration.
+
+1999-05-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c (mi_table_begin): Added missing parameter.
+
+1999-05-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c: Changed table markers and added table id.
+
+1999-05-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c: New file. Implements low-level ui-out primitives for
+ CLI-based interaction.
+
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/mi/gdbmi.texinfo b/gdb/mi/gdbmi.texinfo
new file mode 100644
index 00000000000..f924214caa5
--- /dev/null
+++ b/gdb/mi/gdbmi.texinfo
@@ -0,0 +1,3810 @@
+@c \input texinfo @c -*-texinfo-*-
+@c @c %**start of header
+@c @setfilename gdbmi.info
+@c @settitle GDB/MI Machine Interface
+@c @setchapternewpage off
+@c @c %**end of header
+
+@c @ifinfo
+@c This file documents GDB/MI, a Machine Interface to GDB.
+
+@c Copyright 2000, 2001 Free Software Foundation, Inc.
+@c Contributed by Cygnus Solutions.
+
+@c Permission is granted to copy, distribute and/or modify this document
+@c under the terms of the GNU Free Documentation License, Version 1.1 or
+@c any later version published by the Free Software Foundation; with no
+@c Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
+@c and with the Back-Cover Texts as in (a) below.
+
+@c (a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
+@c this GNU Manual, like GNU software. Copies published by the Free
+@c Software Foundation raise funds for GNU development.''
+@c @end ifinfo
+
+@c @c This title page illustrates only one of the
+@c @c two methods of forming a title page.
+
+@c @titlepage
+@c @title GDB/MI
+@c @subtitle Version 0.3
+@c @subtitle Apr 2001
+@c @author Andrew Cagney, Fernando Nasser and Elena Zannoni
+
+@c @c The following two commands
+@c @c start the copyright page.
+@c @page
+@c @vskip 0pt plus 1filll
+
+@c Copyright @copyright{} 2000, 2001 Free Software Foundation, Inc.
+
+@c Permission is granted to copy, distribute and/or modify this document
+@c under the terms of the GNU Free Documentation License, Version 1.1 or
+@c any later version published by the Free Software Foundation; with no
+@c Invariant Sections, with the Front-Cover texts being ``A GNU Manual,''
+@c and with the Back-Cover Texts as in (a) below.
+
+@c (a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
+@c this GNU Manual, like GNU software. Copies published by the Free
+@c Software Foundation raise funds for GNU development.''
+@c @end titlepage
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI
+@chapter The @sc{gdb/mi} Interface
+
+@unnumberedsec Function and Purpose
+
+@cindex @sc{gdb/mi}, its purpose
+@sc{gdb/mi} is a line based machine oriented text interface to @value{GDBN}. It is
+specifically intended to support the development of systems which use
+the debugger as just one small component of a larger system.
+
+This chapter is a specification of the @sc{gdb/mi} interface. It is written
+in the form of a reference manual.
+
+Note that @sc{gdb/mi} is still under construction, so some of the
+features described below are incomplete and subject to change.
+
+@unnumberedsec Notation and Terminology
+
+@cindex notational conventions, for @sc{gdb/mi}
+This chapter uses the following notation:
+
+@itemize @bullet
+@item
+@code{|} separates two alternatives.
+
+@item
+@code{[ @var{something} ]} indicates that @var{something} is optional:
+it may or may not be given.
+
+@item
+@code{( @var{group} )*} means that @var{group} inside the parentheses
+may repeat zero or more times.
+
+@item
+@code{( @var{group} )+} means that @var{group} inside the parentheses
+may repeat one or more times.
+
+@item
+@code{"@var{string}"} means a literal @var{string}.
+@end itemize
+
+@ignore
+@heading Dependencies
+@end ignore
+
+@heading Acknowledgments
+
+In alphabetic order: Andrew Cagney, Fernando Nasser, Stan Shebs and
+Elena Zannoni.
+
+@menu
+* GDB/MI Command Syntax::
+* GDB/MI Compatibility with CLI::
+* GDB/MI Output Records::
+* GDB/MI Command Description Format::
+* GDB/MI Breakpoint Table Commands::
+* GDB/MI Data Manipulation::
+* GDB/MI Program Control::
+* GDB/MI Miscellaneous Commands::
+@ignore
+* GDB/MI Kod Commands::
+* GDB/MI Memory Overlay Commands::
+* GDB/MI Signal Handling Commands::
+@end ignore
+* GDB/MI Stack Manipulation::
+* GDB/MI Symbol Query::
+* GDB/MI Target Manipulation::
+* GDB/MI Thread Commands::
+* GDB/MI Tracepoint Commands::
+* GDB/MI Variable Objects::
+@end menu
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Command Syntax
+@section @sc{gdb/mi} Command Syntax
+
+@menu
+* GDB/MI Input Syntax::
+* GDB/MI Output Syntax::
+* GDB/MI Simple Examples::
+@end menu
+
+@node GDB/MI Input Syntax
+@subsection @sc{gdb/mi} Input Syntax
+
+@cindex input syntax for @sc{gdb/mi}
+@cindex @sc{gdb/mi}, input syntax
+@table @code
+@item @var{command} @expansion{}
+@code{@var{cli-command} | @var{mi-command}}
+
+@item @var{cli-command} @expansion{}
+@code{[ @var{token} ] @var{cli-command} @var{nl}}, where
+@var{cli-command} is any existing @value{GDBN} CLI command.
+
+@item @var{mi-command} @expansion{}
+@code{[ @var{token} ] "-" @var{operation} ( " " @var{option} )*
+@code{[} " --" @code{]} ( " " @var{parameter} )* @var{nl}}
+
+@item @var{token} @expansion{}
+"any sequence of digits"
+
+@item @var{option} @expansion{}
+@code{"-" @var{parameter} [ " " @var{parameter} ]}
+
+@item @var{parameter} @expansion{}
+@code{@var{non-blank-sequence} | @var{c-string}}
+
+@item @var{operation} @expansion{}
+@emph{any of the operations described in this chapter}
+
+@item @var{non-blank-sequence} @expansion{}
+@emph{anything, provided it doesn't contain special characters such as
+"-", @var{nl}, """ and of course " "}
+
+@item @var{c-string} @expansion{}
+@code{""" @var{seven-bit-iso-c-string-content} """}
+
+@item @var{nl} @expansion{}
+@code{CR | CR-LF}
+@end table
+
+@noindent
+Notes:
+
+@itemize @bullet
+@item
+The CLI commands are still handled by the @sc{mi} interpreter; their
+output is described below.
+
+@item
+The @code{@var{token}}, when present, is passed back when the command
+finishes.
+
+@item
+Some @sc{mi} commands accept optional arguments as part of the parameter
+list. Each option is identified by a leading @samp{-} (dash) and may be
+followed by an optional argument parameter. Options occur first in the
+parameter list and can be delimited from normal parameters using
+@samp{--} (this is useful when some parameters begin with a dash).
+@end itemize
+
+Pragmatics:
+
+@itemize @bullet
+@item
+We want easy access to the existing CLI syntax (for debugging).
+
+@item
+We want it to be easy to spot a @sc{mi} operation.
+@end itemize
+
+@node GDB/MI Output Syntax
+@subsection @sc{gdb/mi} Output Syntax
+
+@cindex output syntax of @sc{gdb/mi}
+@cindex @sc{gdb/mi}, output syntax
+The output from @sc{gdb/mi} consists of zero or more out-of-band records
+followed, optionally, by a single result record. This result record
+is for the most recent command. The sequence of output records is
+terminated by @samp{(@value{GDBP})}.
+
+If an input command was prefixed with a @code{@var{token}} then the
+corresponding output for that command will also be prefixed by that same
+@var{token}.
+
+@table @code
+@item @var{output} @expansion{}
+@code{( @var{out-of-band-record} )* [ @var{result-record} ] "(gdb)" @var{nl}}
+
+@item @var{result-record} @expansion{}
+@code{ [ @var{token} ] "^" @var{result-class} ( "," @var{result} )* @var{nl}}
+
+@item @var{out-of-band-record} @expansion{}
+@code{@var{async-record} | @var{stream-record}}
+
+@item @var{async-record} @expansion{}
+@code{@var{exec-async-output} | @var{status-async-output} | @var{notify-async-output}}
+
+@item @var{exec-async-output} @expansion{}
+@code{[ @var{token} ] "*" @var{async-output}}
+
+@item @var{status-async-output} @expansion{}
+@code{[ @var{token} ] "+" @var{async-output}}
+
+@item @var{notify-async-output} @expansion{}
+@code{[ @var{token} ] "=" @var{async-output}}
+
+@item @var{async-output} @expansion{}
+@code{@var{async-class} ( "," @var{result} )* @var{nl}}
+
+@item @var{result-class} @expansion{}
+@code{"done" | "running" | "connected" | "error" | "exit"}
+
+@item @var{async-class} @expansion{}
+@code{"stopped" | @var{others}} (where @var{others} will be added
+depending on the needs---this is still in development).
+
+@item @var{result} @expansion{}
+@code{ @var{variable} "=" @var{value}}
+
+@item @var{variable} @expansion{}
+@code{ @var{string} }
+
+@item @var{value} @expansion{}
+@code{ @var{const} | @var{tuple} | @var{list} }
+
+@item @var{const} @expansion{}
+@code{@var{c-string}}
+
+@item @var{tuple} @expansion{}
+@code{ "@{@}" | "@{" @var{result} ( "," @var{result} )* "@}" }
+
+@item @var{list} @expansion{}
+@code{ "[]" | "[" @var{value} ( "," @var{value} )* "]" | "["
+@var{result} ( "," @var{result} )* "]" }
+
+@item @var{stream-record} @expansion{}
+@code{@var{console-stream-output} | @var{target-stream-output} | @var{log-stream-output}}
+
+@item @var{console-stream-output} @expansion{}
+@code{"~" @var{c-string}}
+
+@item @var{target-stream-output} @expansion{}
+@code{"@@" @var{c-string}}
+
+@item @var{log-stream-output} @expansion{}
+@code{"&" @var{c-string}}
+
+@item @var{nl} @expansion{}
+@code{CR | CR-LF}
+
+@item @var{token} @expansion{}
+@emph{any sequence of digits}.
+@end table
+
+@noindent
+Notes:
+
+@itemize @bullet
+@item
+All output sequences end in a single line containing a period.
+
+@item
+The @code{@var{token}} is from the corresponding request. If an execution
+command is interrupted by the @samp{-exec-interrupt} command, the
+@var{token} associated with the @samp{*stopped} message is the one of the
+original execution command, not the one of the interrupt command.
+
+@item
+@cindex status output in @sc{gdb/mi}
+@var{status-async-output} contains on-going status information about the
+progress of a slow operation. It can be discarded. All status output is
+prefixed by @samp{+}.
+
+@item
+@cindex async output in @sc{gdb/mi}
+@var{exec-async-output} contains asynchronous state change on the target
+(stopped, started, disappeared). All async output is prefixed by
+@samp{*}.
+
+@item
+@cindex notify output in @sc{gdb/mi}
+@var{notify-async-output} contains supplementary information that the
+client should handle (e.g., a new breakpoint information). All notify
+output is prefixed by @samp{=}.
+
+@item
+@cindex console output in @sc{gdb/mi}
+@var{console-stream-output} is output that should be displayed as is in the
+console. It is the textual response to a CLI command. All the console
+output is prefixed by @samp{~}.
+
+@item
+@cindex target output in @sc{gdb/mi}
+@var{target-stream-output} is the output produced by the target program.
+All the target output is prefixed by @samp{@@}.
+
+@item
+@cindex log output in @sc{gdb/mi}
+@var{log-stream-output} is output text coming from @value{GDBN}'s internals, for
+instance messages that should be displayed as part of an error log. All
+the log output is prefixed by @samp{&}.
+
+@item
+@cindex list output in @sc{gdb/mi}
+New @sc{gdb/mi} commands should only output @var{lists} containing
+@var{values}.
+
+
+@end itemize
+
+@xref{GDB/MI Stream Records, , @sc{gdb/mi} Stream Records}, for more
+details about the various output records.
+
+@node GDB/MI Simple Examples
+@subsection Simple Examples of @sc{gdb/mi} Interaction
+@cindex @sc{gdb/mi}, simple examples
+
+This subsection presents several simple examples of interaction using
+the @sc{gdb/mi} interface. In these examples, @samp{->} means that the
+following line is passed to @sc{gdb/mi} as input, while @samp{<-} means
+the output received from @sc{gdb/mi}.
+
+@subsubheading Target Stop
+
+Here's an example of stopping the inferior process:
+
+@example
+-> -stop
+<- (@value{GDBP})
+@end example
+
+@noindent
+and later:
+
+@example
+<- *stop,reason="stop",address="0x123",source="a.c:123"
+<- (@value{GDBP})
+@end example
+
+@subsubheading Simple CLI Command
+
+Here's an example of a simple CLI command being passed through
+@sc{gdb/mi} and on to the CLI.
+
+@example
+-> print 1+2
+<- ~3\n
+<- (@value{GDBP})
+@end example
+
+@subsubheading Command With Side Effects
+
+@example
+-> -symbol-file xyz.exe
+<- *breakpoint,nr="3",address="0x123",source="a.c:123"
+<- (@value{GDBP})
+@end example
+
+@subsubheading A Bad Command
+
+Here's what happens if you pass a non-existent command:
+
+@example
+-> -rubbish
+<- error,"Rubbish not found"
+<- (@value{GDBP})
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Compatibility with CLI
+@section @sc{gdb/mi} Compatibility with CLI
+
+@cindex compatibility, @sc{gdb/mi} and CLI
+@cindex @sc{gdb/mi}, compatibility with CLI
+To help users familiar with @value{GDBN}'s existing CLI interface, @sc{gdb/mi}
+accepts existing CLI commands. As specified by the syntax, such
+commands can be directly entered into the @sc{gdb/mi} interface and @value{GDBN} will
+respond.
+
+This mechanism is provided as an aid to developers of @sc{gdb/mi}
+clients and not as a reliable interface into the CLI. Since the command
+is being interpreteted in an environment that assumes @sc{gdb/mi}
+behaviour, the exact output of such commands is likely to end up being
+an un-supported hybrid of @sc{gdb/mi} and CLI output.
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Output Records
+@section @sc{gdb/mi} Output Records
+
+@menu
+* GDB/MI Result Records::
+* GDB/MI Stream Records::
+* GDB/MI Out-of-band Records::
+@end menu
+
+@node GDB/MI Result Records
+@subsection @sc{gdb/mi} Result Records
+
+@cindex result records in @sc{gdb/mi}
+@cindex @sc{gdb/mi}, result records
+In addition to a number of out-of-band notifications, the response to a
+@sc{gdb/mi} command includes one of the following result indications:
+
+@table @code
+@findex ^done
+@item "^done" [ "," @var{results} ]
+The synchronous operation was successful, @code{@var{results}} are the return
+values.
+
+@item "^running"
+@findex ^running
+@c Is this one correct? Should it be an out-of-band notification?
+The asynchronous operation was successfully started. The target is
+running.
+
+@item "^error" "," @var{c-string}
+@findex ^error
+The operation failed. The @code{@var{c-string}} contains the corresponding
+error message.
+@end table
+
+@node GDB/MI Stream Records
+@subsection @sc{gdb/mi} Stream Records
+
+@cindex @sc{gdb/mi}, stream records
+@cindex stream records in @sc{gdb/mi}
+@value{GDBN} internally maintains a number of output streams: the console, the
+target, and the log. The output intended for each of these streams is
+funneled through the @sc{gdb/mi} interface using @dfn{stream records}.
+
+Each stream record begins with a unique @dfn{prefix character} which
+identifies its stream (@pxref{GDB/MI Output Syntax, , @sc{gdb/mi} Output
+Syntax}). In addition to the prefix, each stream record contains a
+@code{@var{string-output}}. This is either raw text (with an implicit new
+line) or a quoted C string (which does not contain an implicit newline).
+
+@table @code
+@item "~" @var{string-output}
+The console output stream contains text that should be displayed in the
+CLI console window. It contains the textual responses to CLI commands.
+
+@item "@@" @var{string-output}
+The target output stream contains any textual output from the running
+target.
+
+@item "&" @var{string-output}
+The log stream contains debugging messages being produced by @value{GDBN}'s
+internals.
+@end table
+
+@node GDB/MI Out-of-band Records
+@subsection @sc{gdb/mi} Out-of-band Records
+
+@cindex out-of-band records in @sc{gdb/mi}
+@cindex @sc{gdb/mi}, out-of-band records
+@dfn{Out-of-band} records are used to notify the @sc{gdb/mi} client of
+additional changes that have occurred. Those changes can either be a
+consequence of @sc{gdb/mi} (e.g., a breakpoint modified) or a result of
+target activity (e.g., target stopped).
+
+The following is a preliminary list of possible out-of-band records.
+
+@table @code
+@item "*" "stop"
+@end table
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Command Description Format
+@section @sc{gdb/mi} Command Description Format
+
+The remaining sections describe blocks of commands. Each block of
+commands is laid out in a fashion similar to this section.
+
+Note the the line breaks shown in the examples are here only for
+readability. They don't appear in the real output.
+Also note that the commands with a non-available example (N.A.@:) are
+not yet implemented.
+
+@subheading Motivation
+
+The motivation for this collection of commands.
+
+@subheading Introduction
+
+A brief introduction to this collection of commands as a whole.
+
+@subheading Commands
+
+For each command in the block, the following is described:
+
+@subsubheading Synopsis
+
+@example
+ -command @var{args}@dots{}
+@end example
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} CLI command.
+
+@subsubheading Result
+
+@subsubheading Out-of-band
+
+@subsubheading Notes
+
+@subsubheading Example
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Breakpoint Table Commands
+@section @sc{gdb/mi} Breakpoint table commands
+
+@cindex breakpoint commands for @sc{gdb/mi}
+@cindex @sc{gdb/mi}, breakpoint commands
+This section documents @sc{gdb/mi} commands for manipulating
+breakpoints.
+
+@subheading The @code{-break-after} Command
+@findex -break-after
+
+@subsubheading Synopsis
+
+@example
+ -break-after @var{number} @var{count}
+@end example
+
+The breakpoint number @var{number} is not in effect until it has been
+hit @var{count} times. To see how this is reflected in the output of
+the @samp{-break-list} command, see the description of the
+@samp{-break-list} command below.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{ignore}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-insert main
+^done,bkpt=@{number="1",addr="0x000100d0",file="hello.c",line="5"@}
+(@value{GDBP})
+-break-after 1 3
+~
+^done
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="1",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0",
+ignore="3"@}]@}
+(@value{GDBP})
+@end smallexample
+
+@ignore
+@subheading The @code{-break-catch} Command
+@findex -break-catch
+
+@subheading The @code{-break-commands} Command
+@findex -break-commands
+@end ignore
+
+
+@subheading The @code{-break-condition} Command
+@findex -break-condition
+
+@subsubheading Synopsis
+
+@example
+ -break-condition @var{number} @var{expr}
+@end example
+
+Breakpoint @var{number} will stop the program only if the condition in
+@var{expr} is true. The condition becomes part of the
+@samp{-break-list} output (see the description of the @samp{-break-list}
+command below).
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{condition}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-condition 1 1
+^done
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="1",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",cond="1",
+times="0",ignore="3"@}]@}
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-break-delete} Command
+@findex -break-delete
+
+@subsubheading Synopsis
+
+@example
+ -break-delete ( @var{breakpoint} )+
+@end example
+
+Delete the breakpoint(s) whose number(s) are specified in the argument
+list. This is obviously reflected in the breakpoint list.
+
+@subsubheading @value{GDBN} command
+
+The corresponding @value{GDBN} command is @samp{delete}.
+
+@subsubheading Example
+
+@example
+(@value{GDBP})
+-break-delete 1
+^done
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="0",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[]@}
+(@value{GDBP})
+@end example
+
+@subheading The @code{-break-disable} Command
+@findex -break-disable
+
+@subsubheading Synopsis
+
+@example
+ -break-disable ( @var{breakpoint} )+
+@end example
+
+Disable the named @var{breakpoint}(s). The field @samp{enabled} in the
+break list is now set to @samp{n} for the named @var{breakpoint}(s).
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{disable}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-disable 2
+^done
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="1",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="2",type="breakpoint",disp="keep",enabled="n",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@}]@}
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-break-enable} Command
+@findex -break-enable
+
+@subsubheading Synopsis
+
+@example
+ -break-enable ( @var{breakpoint} )+
+@end example
+
+Enable (previously disabled) @var{breakpoint}(s).
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{enable}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-enable 2
+^done
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="1",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="2",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@}]@}
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-break-info} Command
+@findex -break-info
+
+@subsubheading Synopsis
+
+@example
+ -break-info @var{breakpoint}
+@end example
+
+@c REDUNDANT???
+Get information about a single breakpoint.
+
+@subsubheading @value{GDBN} command
+
+The corresponding @value{GDBN} command is @samp{info break @var{breakpoint}}.
+
+@subsubheading Example
+N.A.
+
+@subheading The @code{-break-insert} Command
+@findex -break-insert
+
+@subsubheading Synopsis
+
+@example
+ -break-insert [ -t ] [ -h ] [ -r ]
+ [ -c @var{condition} ] [ -i @var{ignore-count} ]
+ [ -p @var{thread} ] [ @var{line} | @var{addr} ]
+@end example
+
+@noindent
+If specified, @var{line}, can be one of:
+
+@itemize @bullet
+@item function
+@c @item +offset
+@c @item -offset
+@c @item linenum
+@item filename:linenum
+@item filename:function
+@item *address
+@end itemize
+
+The possible optional parameters of this command are:
+
+@table @samp
+@item -t
+Insert a tempoary breakpoint.
+@item -h
+Insert a hardware breakpoint.
+@item -c @var{condition}
+Make the breakpoint conditional on @var{condition}.
+@item -i @var{ignore-count}
+Initialize the @var{ignore-count}.
+@item -r
+Insert a regular breakpoint in all the functions whose names match the
+given regular expression. Other flags are not applicable to regular
+expresson.
+@end table
+
+@subsubheading Result
+
+The result is in the form:
+
+@example
+ ^done,bkptno="@var{number}",func="@var{funcname}",
+ file="@var{filename}",line="@var{lineno}"
+@end example
+
+@noindent
+where @var{number} is the @value{GDBN} number for this breakpoint, @var{funcname}
+is the name of the function where the breakpoint was inserted,
+@var{filename} is the name of the source file which contains this
+function, and @var{lineno} is the source line number within that file.
+
+Note: this format is open to change.
+@c An out-of-band breakpoint instead of part of the result?
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} commands are @samp{break}, @samp{tbreak},
+@samp{hbreak}, @samp{thbreak}, and @samp{rbreak}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-insert main
+^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c",line="4"@}
+(@value{GDBP})
+-break-insert -t foo
+^done,bkpt=@{number="2",addr="0x00010774",file="recursive2.c",line="11"@}
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="2",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x0001072c", func="main",file="recursive2.c",line="4",times="0"@},
+bkpt=@{number="2",type="breakpoint",disp="del",enabled="y",
+addr="0x00010774",func="foo",file="recursive2.c",line="11",times="0"@}]@}
+(@value{GDBP})
+-break-insert -r foo.*
+~int foo(int, int);
+^done,bkpt=@{number="3",addr="0x00010774",file="recursive2.c",line="11"@}
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-break-list} Command
+@findex -break-list
+
+@subsubheading Synopsis
+
+@example
+ -break-list
+@end example
+
+Displays the list of inserted breakpoints, showing the following fields:
+
+@table @samp
+@item Number
+number of the breakpoint
+@item Type
+type of the breakpoint: @samp{breakpoint} or @samp{watchpoint}
+@item Disposition
+should the breakpoint be deleted or disabled when it is hit: @samp{keep}
+or @samp{nokeep}
+@item Enabled
+is the breakpoint enabled or no: @samp{y} or @samp{n}
+@item Address
+memory location at which the breakpoint is set
+@item What
+logical location of the breakpoint, expressed by function name, file
+name, line number
+@item Times
+number of times the breakpoint has been hit
+@end table
+
+If there are no breakpoints or watchpoints, the @code{BreakpointTable}
+@code{body} field is an empty list.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info break}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="2",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@},
+bkpt=@{number="2",type="breakpoint",disp="keep",enabled="y",
+addr="0x00010114",func="foo",file="hello.c",line="13",times="0"@}]@}
+(@value{GDBP})
+@end smallexample
+
+Here's an example of the result when there are no breakpoints:
+
+@smallexample
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="0",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[]@}
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-break-watch} Command
+@findex -break-watch
+
+@subsubheading Synopsis
+
+@example
+ -break-watch [ -a | -r ]
+@end example
+
+Create a watchpoint. With the @samp{-a} option it will create an
+@dfn{access} watchpoint, i.e. a watchpoint that triggers either on a
+read from or on a write to the memory location. With the @samp{-r}
+option, the watchpoint created is a @dfn{read} watchpoint, i.e. it will
+trigger only when the memory location is accessed for reading. Without
+either of the options, the watchpoint created is a regular watchpoint,
+i.e. it will trigger when the memory location is accessed for writing.
+@xref{Set Watchpoints, , Setting watchpoints}.
+
+Note that @samp{-break-list} will report a single list of watchpoints and
+breakpoints inserted.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} commands are @samp{watch}, @samp{awatch}, and
+@samp{rwatch}.
+
+@subsubheading Example
+
+Setting a watchpoint on a variable in the @code{main} function:
+
+@smallexample
+(@value{GDBP})
+-break-watch x
+^done,wpt=@{number="2",exp="x"@}
+(@value{GDBP})
+-exec-continue
+^running
+^done,reason="watchpoint-trigger",wpt=@{number="2",exp="x"@},
+value=@{old="-268439212",new="55"@},
+frame=@{func="main",args=[],file="recursive2.c",line="5"@}
+(@value{GDBP})
+@end smallexample
+
+Setting a watchpoint on a variable local to a function. @value{GDBN} will stop
+the program execution twice: first for the variable changing value, then
+for the watchpoint going out of scope.
+
+@smallexample
+(@value{GDBP})
+-break-watch C
+^done,wpt=@{number="5",exp="C"@}
+(@value{GDBP})
+-exec-continue
+^running
+^done,reason="watchpoint-trigger",
+wpt=@{number="5",exp="C"@},value=@{old="-276895068",new="3"@},
+frame=@{func="callee4",args=[],
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="13"@}
+(@value{GDBP})
+-exec-continue
+^running
+^done,reason="watchpoint-scope",wpnum="5",
+frame=@{func="callee3",args=[@{name="strarg",
+value="0x11940 \"A string argument.\""@}],
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@}
+(@value{GDBP})
+@end smallexample
+
+Listing breakpoints and watchpoints, at different points in the program
+execution. Note that once the watchpoint goes out of scope, it is
+deleted.
+
+@smallexample
+(@value{GDBP})
+-break-watch C
+^done,wpt=@{number="2",exp="C"@}
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="2",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x00010734",func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@},
+bkpt=@{number="2",type="watchpoint",disp="keep",
+enabled="y",addr="",what="C",times="0"@}]@}
+(@value{GDBP})
+-exec-continue
+^running
+^done,reason="watchpoint-trigger",wpt=@{number="2",exp="C"@},
+value=@{old="-276895068",new="3"@},
+frame=@{func="callee4",args=[],
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="13"@}
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="2",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x00010734",func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@},
+bkpt=@{number="2",type="watchpoint",disp="keep",
+enabled="y",addr="",what="C",times="-5"@}]@}
+(@value{GDBP})
+-exec-continue
+^running
+^done,reason="watchpoint-scope",wpnum="2",
+frame=@{func="callee3",args=[@{name="strarg",
+value="0x11940 \"A string argument.\""@}],
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@}
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="1",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x00010734",func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@}]@}
+(@value{GDBP})
+@end smallexample
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Data Manipulation
+@section @sc{gdb/mi} Data Manipulation
+
+@cindex data manipulation, in @sc{gdb/mi}
+@cindex @sc{gdb/mi}, data manipulation
+This section describes the @sc{gdb/mi} commands that manipulate data:
+examine memory and registers, evaluate expressions, etc.
+
+@c REMOVED FROM THE INTERFACE.
+@c @subheading -data-assign
+@c Change the value of a program variable. Plenty of side effects.
+@c @subsubheading GDB command
+@c set variable
+@c @subsubheading Example
+@c N.A.
+
+@subheading The @code{-data-disassemble} Command
+@findex -data-disassemble
+
+@subsubheading Synopsis
+
+@example
+ -data-disassemble
+ [ -s @var{start-addr} -e @var{end-addr} ]
+ | [ -f @var{filename} -l @var{linenum} [ -n @var{lines} ] ]
+ -- @var{mode}
+@end example
+
+@noindent
+Where:
+
+@table @samp
+@item @var{start-addr}
+is the beginning address (or @code{$pc})
+@item @var{end-addr}
+is the end address
+@item @var{filename}
+is the name of the file to disassemble
+@item @var{linenum}
+is the line number to disassemble around
+@item @var{lines}
+is the the number of disassembly lines to be produced. If it is -1,
+the whole function will be disassembled, in case no @var{end-addr} is
+specified. If @var{end-addr} is specified as a non-zero value, and
+@var{lines} is lower than the number of disassembly lines between
+@var{start-addr} and @var{end-addr}, only @var{lines} lines are
+displayed; if @var{lines} is higher than the number of lines between
+@var{start-addr} and @var{end-addr}, only the lines up to @var{end-addr}
+are displayed.
+@item @var{mode}
+is either 0 (meaning only disassembly) or 1 (meaning mixed source and
+disassembly).
+@end table
+
+@subsubheading Result
+
+The output for each instruction is composed of four fields:
+
+@itemize @bullet
+@item Address
+@item Func-name
+@item Offset
+@item Instruction
+@end itemize
+
+Note that whatever included in the instruction field, is not manipulated
+directely by @sc{gdb/mi}, i.e. it is not possible to adjust its format.
+
+@subsubheading @value{GDBN} Command
+
+There's no direct mapping from this command to the CLI.
+
+@subsubheading Example
+
+Disassemble from the current value of @code{$pc} to @code{$pc + 20}:
+
+@smallexample
+(@value{GDBP})
+-data-disassemble -s $pc -e "$pc + 20" -- 0
+^done,
+asm_insns=[
+@{address="0x000107c0",func-name="main",offset="4",
+inst="mov 2, %o0"@},
+@{address="0x000107c4",func-name="main",offset="8",
+inst="sethi %hi(0x11800), %o2"@},
+@{address="0x000107c8",func-name="main",offset="12",
+inst="or %o2, 0x140, %o1\t! 0x11940 <_lib_version+8>"@},
+@{address="0x000107cc",func-name="main",offset="16",
+inst="sethi %hi(0x11800), %o2"@},
+@{address="0x000107d0",func-name="main",offset="20",
+inst="or %o2, 0x168, %o4\t! 0x11968 <_lib_version+48>"@}]
+(@value{GDBP})
+@end smallexample
+
+Disassemble the whole @code{main} function. Line 32 is part of
+@code{main}.
+
+@smallexample
+-data-disassemble -f basics.c -l 32 -- 0
+^done,asm_insns=[
+@{address="0x000107bc",func-name="main",offset="0",
+inst="save %sp, -112, %sp"@},
+@{address="0x000107c0",func-name="main",offset="4",
+inst="mov 2, %o0"@},
+@{address="0x000107c4",func-name="main",offset="8",
+inst="sethi %hi(0x11800), %o2"@},
+[@dots{}]
+@{address="0x0001081c",func-name="main",offset="96",inst="ret "@},
+@{address="0x00010820",func-name="main",offset="100",inst="restore "@}]
+(@value{GDBP})
+@end smallexample
+
+Disassemble 3 instructions from the start of @code{main}:
+
+@smallexample
+(@value{GDBP})
+-data-disassemble -f basics.c -l 32 -n 3 -- 0
+^done,asm_insns=[
+@{address="0x000107bc",func-name="main",offset="0",
+inst="save %sp, -112, %sp"@},
+@{address="0x000107c0",func-name="main",offset="4",
+inst="mov 2, %o0"@},
+@{address="0x000107c4",func-name="main",offset="8",
+inst="sethi %hi(0x11800), %o2"@}]
+(@value{GDBP})
+@end smallexample
+
+Disassemble 3 instructions from the start of @code{main} in mixed mode:
+
+@smallexample
+(@value{GDBP})
+-data-disassemble -f basics.c -l 32 -n 3 -- 1
+^done,asm_insns=[
+src_and_asm_line=@{line="31",
+file="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb/ \
+ testsuite/gdb.mi/basics.c",line_asm_insn=[
+@{address="0x000107bc",func-name="main",offset="0",
+inst="save %sp, -112, %sp"@}]@},
+src_and_asm_line=@{line="32",
+file="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb/ \
+ testsuite/gdb.mi/basics.c",line_asm_insn=[
+@{address="0x000107c0",func-name="main",offset="4",
+inst="mov 2, %o0"@},
+@{address="0x000107c4",func-name="main",offset="8",
+inst="sethi %hi(0x11800), %o2"@}]@}]
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-data-evaluate-expression} Command
+@findex -data-evaluate-expression
+
+@subsubheading Synopsis
+
+@example
+ -data-evaluate-expression @var{expr}
+@end example
+
+Evaluate @var{expr} as an expression. The expression could contain an
+inferior function call. The function call will execute synchronously.
+If the expression contains spaces, it must be enclosed in double quotes.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} commands are @samp{print}, @samp{output}, and
+@samp{call}. In @code{gdbtk} only, there's a corresponding
+@samp{gdb_eval} command.
+
+@subsubheading Example
+
+In the following example, the numbers that precede the commands are the
+@dfn{tokens} described in @ref{GDB/MI Command Syntax, ,@sc{gdb/mi}
+Command Syntax}. Notice how @sc{gdb/mi} returns the same tokens in its
+output.
+
+@smallexample
+211-data-evaluate-expression A
+211^done,value="1"
+(@value{GDBP})
+311-data-evaluate-expression &A
+311^done,value="0xefffeb7c"
+(@value{GDBP})
+411-data-evaluate-expression A+3
+411^done,value="4"
+(@value{GDBP})
+511-data-evaluate-expression "A + 3"
+511^done,value="4"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-data-list-changed-registers} Command
+@findex -data-list-changed-registers
+
+@subsubheading Synopsis
+
+@example
+ -data-list-changed-registers
+@end example
+
+Display a list of the registers that have changed.
+
+@subsubheading @value{GDBN} Command
+
+@value{GDBN} doesn't have a direct analog for this command; @code{gdbtk}
+has the corresponding command @samp{gdb_changed_register_list}.
+
+@subsubheading Example
+
+On a PPC MBX board:
+
+@smallexample
+(@value{GDBP})
+-exec-continue
+^running
+
+(@value{GDBP})
+*stopped,reason="breakpoint-hit",bkptno="1",frame=@{func="main",
+args=[],file="try.c",line="5"@}
+(@value{GDBP})
+-data-list-changed-registers
+^done,changed-registers=["0","1","2","4","5","6","7","8","9",
+"10","11","13","14","15","16","17","18","19","20","21","22","23",
+"24","25","26","27","28","30","31","64","65","66","67","69"]
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-data-list-register-names} Command
+@findex -data-list-register-names
+
+@subsubheading Synopsis
+
+@example
+ -data-list-register-names [ ( @var{regno} )+ ]
+@end example
+
+Show a list of register names for the current target. If no arguments
+are given, it shows a list of the names of all the registers. If
+integer numbers are given as arguments, it will print a list of the
+names of the registers corresponding to the arguments. To ensure
+consistency between a register name and its number, the output list may
+include empty register names.
+
+@subsubheading @value{GDBN} Command
+
+@value{GDBN} does not have a command which corresponds to
+@samp{-data-list-register-names}. In @code{gdbtk} there is a
+corresponding command @samp{gdb_regnames}.
+
+@subsubheading Example
+
+For the PPC MBX board:
+@smallexample
+(@value{GDBP})
+-data-list-register-names
+^done,register-names=["r0","r1","r2","r3","r4","r5","r6","r7",
+"r8","r9","r10","r11","r12","r13","r14","r15","r16","r17","r18",
+"r19","r20","r21","r22","r23","r24","r25","r26","r27","r28","r29",
+"r30","r31","f0","f1","f2","f3","f4","f5","f6","f7","f8","f9",
+"f10","f11","f12","f13","f14","f15","f16","f17","f18","f19","f20",
+"f21","f22","f23","f24","f25","f26","f27","f28","f29","f30","f31",
+"", "pc","ps","cr","lr","ctr","xer"]
+(@value{GDBP})
+-data-list-register-names 1 2 3
+^done,register-names=["r1","r2","r3"]
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-data-list-register-values} Command
+@findex -data-list-register-values
+
+@subsubheading Synopsis
+
+@example
+ -data-list-register-values @var{fmt} [ ( @var{regno} )*]
+@end example
+
+Display the registers' contents. @var{fmt} is the format according to
+which the registers' contents are to be returned, followed by an optional
+list of numbers specifying the registers to display. A missing list of
+numbers indicates that the contents of all the registers must be returned.
+
+Allowed formats for @var{fmt} are:
+
+@table @code
+@item x
+Hexadecimal
+@item o
+Octal
+@item t
+Binary
+@item d
+Decimal
+@item r
+Raw
+@item N
+Natural
+@end table
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} commands are @samp{info reg}, @samp{info
+all-reg}, and (in @code{gdbtk}) @samp{gdb_fetch_registers}.
+
+@subsubheading Example
+
+For a PPC MBX board (note: line breaks are for readability only, they
+don't appear in the actual output):
+
+@smallexample
+(@value{GDBP})
+-data-list-register-values r 64 65
+^done,register-values=[@{number="64",value="0xfe00a300"@},
+@{number="65",value="0x00029002"@}]
+(@value{GDBP})
+-data-list-register-values x
+^done,register-values=[@{number="0",value="0xfe0043c8"@},
+@{number="1",value="0x3fff88"@},@{number="2",value="0xfffffffe"@},
+@{number="3",value="0x0"@},@{number="4",value="0xa"@},
+@{number="5",value="0x3fff68"@},@{number="6",value="0x3fff58"@},
+@{number="7",value="0xfe011e98"@},@{number="8",value="0x2"@},
+@{number="9",value="0xfa202820"@},@{number="10",value="0xfa202808"@},
+@{number="11",value="0x1"@},@{number="12",value="0x0"@},
+@{number="13",value="0x4544"@},@{number="14",value="0xffdfffff"@},
+@{number="15",value="0xffffffff"@},@{number="16",value="0xfffffeff"@},
+@{number="17",value="0xefffffed"@},@{number="18",value="0xfffffffe"@},
+@{number="19",value="0xffffffff"@},@{number="20",value="0xffffffff"@},
+@{number="21",value="0xffffffff"@},@{number="22",value="0xfffffff7"@},
+@{number="23",value="0xffffffff"@},@{number="24",value="0xffffffff"@},
+@{number="25",value="0xffffffff"@},@{number="26",value="0xfffffffb"@},
+@{number="27",value="0xffffffff"@},@{number="28",value="0xf7bfffff"@},
+@{number="29",value="0x0"@},@{number="30",value="0xfe010000"@},
+@{number="31",value="0x0"@},@{number="32",value="0x0"@},
+@{number="33",value="0x0"@},@{number="34",value="0x0"@},
+@{number="35",value="0x0"@},@{number="36",value="0x0"@},
+@{number="37",value="0x0"@},@{number="38",value="0x0"@},
+@{number="39",value="0x0"@},@{number="40",value="0x0"@},
+@{number="41",value="0x0"@},@{number="42",value="0x0"@},
+@{number="43",value="0x0"@},@{number="44",value="0x0"@},
+@{number="45",value="0x0"@},@{number="46",value="0x0"@},
+@{number="47",value="0x0"@},@{number="48",value="0x0"@},
+@{number="49",value="0x0"@},@{number="50",value="0x0"@},
+@{number="51",value="0x0"@},@{number="52",value="0x0"@},
+@{number="53",value="0x0"@},@{number="54",value="0x0"@},
+@{number="55",value="0x0"@},@{number="56",value="0x0"@},
+@{number="57",value="0x0"@},@{number="58",value="0x0"@},
+@{number="59",value="0x0"@},@{number="60",value="0x0"@},
+@{number="61",value="0x0"@},@{number="62",value="0x0"@},
+@{number="63",value="0x0"@},@{number="64",value="0xfe00a300"@},
+@{number="65",value="0x29002"@},@{number="66",value="0x202f04b5"@},
+@{number="67",value="0xfe0043b0"@},@{number="68",value="0xfe00b3e4"@},
+@{number="69",value="0x20002b03"@}]
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-data-read-memory} Command
+@findex -data-read-memory
+
+@subsubheading Synopsis
+
+@example
+ -data-read-memory [ -o @var{byte-offset} ]
+ @var{address} @var{word-format} @var{word-size}
+ @var{nr-rows} @var{nr-cols} [ @var{aschar} ]
+@end example
+
+@noindent
+where:
+
+@table @samp
+@item @var{address}
+An expression specifying the address of the first memory word to be
+read. Complex expressions containing embedded white space should be
+quoted using the C convention.
+
+@item @var{word-format}
+The format to be used to print the memory words. The notation is the
+same as for @value{GDBN}'s @code{print} command (@pxref{Output Formats,
+,Output formats}).
+
+@item @var{word-size}
+The size of each memory word in bytes.
+
+@item @var{nr-rows}
+The number of rows in the output table.
+
+@item @var{nr-cols}
+The number of columns in the output table.
+
+@item @var{aschar}
+If present, indicates that each row should include an @sc{ascii} dump. The
+value of @var{aschar} is used as a padding character when a byte is not a
+member of the printable @sc{ascii} character set (printable @sc{ascii}
+characters are those whose code is between 32 and 126, inclusively).
+
+@item @var{byte-offset}
+An offset to add to the @var{address} before fetching memory.
+@end table
+
+This command displays memory contents as a table of @var{nr-rows} by
+@var{nr-cols} words, each word being @var{word-size} bytes. In total,
+@code{@var{nr-rows} * @var{nr-cols} * @var{word-size}} bytes are read
+(returned as @samp{total-bytes}). Should less than the requested number
+of bytes be returned by the target, the missing words are identified
+using @samp{N/A}. The number of bytes read from the target is returned
+in @samp{nr-bytes} and the starting address used to read memory in
+@samp{addr}.
+
+The address of the next/previous row or page is available in
+@samp{next-row} and @samp{prev-row}, @samp{next-page} and
+@samp{prev-page}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{x}. @code{gdbtk} has
+@samp{gdb_get_mem} memory read command.
+
+@subsubheading Example
+
+Read six bytes of memory starting at @code{bytes+6} but then offset by
+@code{-6} bytes. Format as three rows of two columns. One byte per
+word. Display each word in hex.
+
+@smallexample
+(@value{GDBP})
+9-data-read-memory -o -6 -- bytes+6 x 1 3 2
+9^done,addr="0x00001390",nr-bytes="6",total-bytes="6",
+next-row="0x00001396",prev-row="0x0000138e",next-page="0x00001396",
+prev-page="0x0000138a",memory=[
+@{addr="0x00001390",data=["0x00","0x01"]@},
+@{addr="0x00001392",data=["0x02","0x03"]@},
+@{addr="0x00001394",data=["0x04","0x05"]@}]
+(@value{GDBP})
+@end smallexample
+
+Read two bytes of memory starting at address @code{shorts + 64} and
+display as a single word formatted in decimal.
+
+@smallexample
+(@value{GDBP})
+5-data-read-memory shorts+64 d 2 1 1
+5^done,addr="0x00001510",nr-bytes="2",total-bytes="2",
+next-row="0x00001512",prev-row="0x0000150e",
+next-page="0x00001512",prev-page="0x0000150e",memory=[
+@{addr="0x00001510",data=["128"]@}]
+(@value{GDBP})
+@end smallexample
+
+Read thirty two bytes of memory starting at @code{bytes+16} and format
+as eight rows of four columns. Include a string encoding with @samp{x}
+used as the non-printable character.
+
+@smallexample
+(@value{GDBP})
+4-data-read-memory bytes+16 x 1 8 4 x
+4^done,addr="0x000013a0",nr-bytes="32",total-bytes="32",
+next-row="0x000013c0",prev-row="0x0000139c",
+next-page="0x000013c0",prev-page="0x00001380",memory=[
+@{addr="0x000013a0",data=["0x10","0x11","0x12","0x13"],ascii="xxxx"@},
+@{addr="0x000013a4",data=["0x14","0x15","0x16","0x17"],ascii="xxxx"@},
+@{addr="0x000013a8",data=["0x18","0x19","0x1a","0x1b"],ascii="xxxx"@},
+@{addr="0x000013ac",data=["0x1c","0x1d","0x1e","0x1f"],ascii="xxxx"@},
+@{addr="0x000013b0",data=["0x20","0x21","0x22","0x23"],ascii=" !\"#"@},
+@{addr="0x000013b4",data=["0x24","0x25","0x26","0x27"],ascii="$%&'"@},
+@{addr="0x000013b8",data=["0x28","0x29","0x2a","0x2b"],ascii="()*+"@},
+@{addr="0x000013bc",data=["0x2c","0x2d","0x2e","0x2f"],ascii=",-./"@}]
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-display-delete} Command
+@findex -display-delete
+
+@subsubheading Synopsis
+
+@example
+ -display-delete @var{number}
+@end example
+
+Delete the display @var{number}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{delete display}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-display-disable} Command
+@findex -display-disable
+
+@subsubheading Synopsis
+
+@example
+ -display-disable @var{number}
+@end example
+
+Disable display @var{number}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{disable display}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-display-enable} Command
+@findex -display-enable
+
+@subsubheading Synopsis
+
+@example
+ -display-enable @var{number}
+@end example
+
+Enable display @var{number}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{enable display}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-display-insert} Command
+@findex -display-insert
+
+@subsubheading Synopsis
+
+@example
+ -display-insert @var{expression}
+@end example
+
+Display @var{expression} every time the program stops.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{display}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-display-list} Command
+@findex -display-list
+
+@subsubheading Synopsis
+
+@example
+ -display-list
+@end example
+
+List the displays. Do not show the current values.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info display}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-environment-cd} Command
+@findex -environment-cd
+
+@subsubheading Synopsis
+
+@example
+ -environment-cd @var{pathdir}
+@end example
+
+Set @value{GDBN}'s working directory.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{cd}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-environment-cd /kwikemart/marge/ezannoni/flathead-dev/devo/gdb
+^done
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-environment-directory} Command
+@findex -environment-directory
+
+@subsubheading Synopsis
+
+@example
+ -environment-directory @var{pathdir}
+@end example
+
+Add directory @var{pathdir} to beginning of search path for source files.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{dir}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-environment-directory /kwikemart/marge/ezannoni/flathead-dev/devo/gdb
+^done
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-environment-path} Command
+@findex -environment-path
+
+@subsubheading Synopsis
+
+@example
+ -environment-path ( @var{pathdir} )+
+@end example
+
+Add directories @var{pathdir} to beginning of search path for object files.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{path}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-environment-path /kwikemart/marge/ezannoni/flathead-dev/ppc-eabi/gdb
+^done
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-environment-pwd} Command
+@findex -environment-pwd
+
+@subsubheading Synopsis
+
+@example
+ -environment-pwd
+@end example
+
+Show the current working directory.
+
+@subsubheading @value{GDBN} command
+
+The corresponding @value{GDBN} command is @samp{pwd}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-environment-pwd
+~Working directory /kwikemart/marge/ezannoni/flathead-dev/devo/gdb.
+^done
+(@value{GDBP})
+@end smallexample
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Program Control
+@section @sc{gdb/mi} Program control
+
+@subsubheading Program termination
+
+As a result of execution, the inferior program can run to completion, if
+it doesn't encounter any breakpoints. In this case the output will
+include an exit code, if the program has exited exceptionally.
+
+@subsubheading Examples
+
+@noindent
+Program exited normally:
+
+@smallexample
+(@value{GDBP})
+-exec-run
+^running
+(@value{GDBP})
+x = 55
+*stopped,reason="exited-normally"
+(@value{GDBP})
+@end smallexample
+
+@noindent
+Program exited exceptionally:
+
+@smallexample
+(@value{GDBP})
+-exec-run
+^running
+(@value{GDBP})
+x = 55
+*stopped,reason="exited",exit-code="01"
+(@value{GDBP})
+@end smallexample
+
+Another way the program can terminate is if it receives a signal such as
+@code{SIGINT}. In this case, @sc{gdb/mi} displays this:
+
+@smallexample
+(@value{GDBP})
+*stopped,reason="exited-signalled",signal-name="SIGINT",
+signal-meaning="Interrupt"
+@end smallexample
+
+
+@subheading The @code{-exec-abort} Command
+@findex -exec-abort
+
+@subsubheading Synopsis
+
+@example
+ -exec-abort
+@end example
+
+Kill the inferior running program.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{kill}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-exec-arguments} Command
+@findex -exec-arguments
+
+@subsubheading Synopsis
+
+@example
+ -exec-arguments @var{args}
+@end example
+
+Set the inferior program arguments, to be used in the next
+@samp{-exec-run}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{set args}.
+
+@subsubheading Example
+
+@c FIXME!
+Don't have one around.
+
+
+@subheading The @code{-exec-continue} Command
+@findex -exec-continue
+
+@subsubheading Synopsis
+
+@example
+ -exec-continue
+@end example
+
+Asynchronous command. Resumes the execution of the inferior program
+until a breakpoint is encountered, or until the inferior exits.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} corresponding is @samp{continue}.
+
+@subsubheading Example
+
+@smallexample
+-exec-continue
+^running
+(@value{GDBP})
+@@Hello world
+*stopped,reason="breakpoint-hit",bkptno="2",frame=@{func="foo",args=[],
+file="hello.c",line="13"@}
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-finish} Command
+@findex -exec-finish
+
+@subsubheading Synopsis
+
+@example
+ -exec-finish
+@end example
+
+Asynchronous command. Resumes the execution of the inferior program
+until the current function is exited. Displays the results returned by
+the function.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{finish}.
+
+@subsubheading Example
+
+Function returning @code{void}.
+
+@smallexample
+-exec-finish
+^running
+(@value{GDBP})
+@@hello from foo
+*stopped,reason="function-finished",frame=@{func="main",args=[],
+file="hello.c",line="7"@}
+(@value{GDBP})
+@end smallexample
+
+Function returning other than @code{void}. The name of the internal
+@value{GDBN} variable storing the result is printed, together with the
+value itself.
+
+@smallexample
+-exec-finish
+^running
+(@value{GDBP})
+*stopped,reason="function-finished",frame=@{addr="0x000107b0",func="foo",
+args=[@{name="a",value="1"],@{name="b",value="9"@}@},
+file="recursive2.c",line="14"@},
+gdb-result-var="$1",return-value="0"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-interrupt} Command
+@findex -exec-interrupt
+
+@subsubheading Synopsis
+
+@example
+ -exec-interrupt
+@end example
+
+Asynchronous command. Interrupts the background execution of the target.
+Note how the token associated with the stop message is the one for the
+execution command that has been interrupted. The token for the interrupt
+itself only appears in the @samp{^done} output. If the user is trying to
+interrupt a non-running program, an error message will be printed.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{interrupt}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+111-exec-continue
+111^running
+
+(@value{GDBP})
+222-exec-interrupt
+222^done
+(@value{GDBP})
+111*stopped,signal-name="SIGINT",signal-meaning="Interrupt",
+frame=@{addr="0x00010140",func="foo",args=[],file="try.c",line="13"@}
+(@value{GDBP})
+
+(@value{GDBP})
+-exec-interrupt
+^error,msg="mi_cmd_exec_interrupt: Inferior not executing."
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-next} Command
+@findex -exec-next
+
+@subsubheading Synopsis
+
+@example
+ -exec-next
+@end example
+
+Asynchronous command. Resumes execution of the inferior program, stopping
+when the beginning of the next source line is reached.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{next}.
+
+@subsubheading Example
+
+@smallexample
+-exec-next
+^running
+(@value{GDBP})
+*stopped,reason="end-stepping-range",line="8",file="hello.c"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-next-instruction} Command
+@findex -exec-next-instruction
+
+@subsubheading Synopsis
+
+@example
+ -exec-next-instruction
+@end example
+
+Asynchronous command. Executes one machine instruction. If the
+instruction is a function call continues until the function returns. If
+the program stops at an instruction in the middle of a source line, the
+address will be printed as well.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{nexti}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-exec-next-instruction
+^running
+
+(@value{GDBP})
+*stopped,reason="end-stepping-range",
+addr="0x000100d4",line="5",file="hello.c"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-return} Command
+@findex -exec-return
+
+@subsubheading Synopsis
+
+@example
+ -exec-return
+@end example
+
+Makes current function return immediately. Doesn't execute the inferior.
+Displays the new current frame.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{return}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+200-break-insert callee4
+200^done,bkpt=@{number="1",addr="0x00010734",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@}
+(@value{GDBP})
+000-exec-run
+000^running
+(@value{GDBP})
+000*stopped,reason="breakpoint-hit",bkptno="1",
+frame=@{func="callee4",args=[],
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@}
+(@value{GDBP})
+205-break-delete
+205^done
+(@value{GDBP})
+111-exec-return
+111^done,frame=@{level="0 ",func="callee3",
+args=[@{name="strarg",
+value="0x11940 \"A string argument.\""@}],
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@}
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-run} Command
+@findex -exec-run
+
+@subsubheading Synopsis
+
+@example
+ -exec-run
+@end example
+
+Asynchronous command. Starts execution of the inferior from the
+beginning. The inferior executes until either a breakpoint is
+encountered or the program exits.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{run}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-insert main
+^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c",line="4"@}
+(@value{GDBP})
+-exec-run
+^running
+(@value{GDBP})
+*stopped,reason="breakpoint-hit",bkptno="1",
+frame=@{func="main",args=[],file="recursive2.c",line="4"@}
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-show-arguments} Command
+@findex -exec-show-arguments
+
+@subsubheading Synopsis
+
+@example
+ -exec-show-arguments
+@end example
+
+Print the arguments of the program.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{show args}.
+
+@subsubheading Example
+N.A.
+
+@c @subheading -exec-signal
+
+@subheading The @code{-exec-step} Command
+@findex -exec-step
+
+@subsubheading Synopsis
+
+@example
+ -exec-step
+@end example
+
+Asynchronous command. Resumes execution of the inferior program, stopping
+when the beginning of the next source line is reached, if the next
+source line is not a function call. If it is, stop at the first
+instruction of the called function.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{step}.
+
+@subsubheading Example
+
+Stepping into a function:
+
+@smallexample
+-exec-step
+^running
+(@value{GDBP})
+*stopped,reason="end-stepping-range",
+frame=@{func="foo",args=[@{name="a",value="10"@},
+@{name="b",value="0"@}],file="recursive2.c",line="11"@}
+(@value{GDBP})
+@end smallexample
+
+Regular stepping:
+
+@smallexample
+-exec-step
+^running
+(@value{GDBP})
+*stopped,reason="end-stepping-range",line="14",file="recursive2.c"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-step-instruction} Command
+@findex -exec-step-instruction
+
+@subsubheading Synopsis
+
+@example
+ -exec-step-instruction
+@end example
+
+Asynchronous command. Resumes the inferior which executes one machine
+instruction. The output, once @value{GDBN} has stopped, will vary depending on
+whether we have stopped in the middle of a source line or not. In the
+former case, the address at which the program stopped will be printed as
+well.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{stepi}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-exec-step-instruction
+^running
+
+(@value{GDBP})
+*stopped,reason="end-stepping-range",
+frame=@{func="foo",args=[],file="try.c",line="10"@}
+(@value{GDBP})
+-exec-step-instruction
+^running
+
+(@value{GDBP})
+*stopped,reason="end-stepping-range",
+frame=@{addr="0x000100f4",func="foo",args=[],file="try.c",line="10"@}
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-until} Command
+@findex -exec-until
+
+@subsubheading Synopsis
+
+@example
+ -exec-until [ @var{location} ]
+@end example
+
+Asynchronous command. Executes the inferior until the @var{location}
+specified in the argument is reached. If there is no argument, the inferior
+executes until a source line greater than the current one is reached.
+The reason for stopping in this case will be @samp{location-reached}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{until}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-exec-until recursive2.c:6
+^running
+(@value{GDBP})
+x = 55
+*stopped,reason="location-reached",frame=@{func="main",args=[],
+file="recursive2.c",line="6"@}
+(@value{GDBP})
+@end smallexample
+
+@ignore
+@subheading -file-clear
+Is this going away????
+@end ignore
+
+
+@subheading The @code{-file-exec-and-symbols} Command
+@findex -file-exec-and-symbols
+
+@subsubheading Synopsis
+
+@example
+ -file-exec-and-symbols @var{file}
+@end example
+
+Specify the executable file to be debugged. This file is the one from
+which the symbol table is also read. If no file is specified, the
+command clears the executable and symbol information. If breakpoints
+are set when using this command with no arguments, @value{GDBN} will produce
+error messages. Otherwise, no output is produced, except a completion
+notification.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{file}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-file-exec-and-symbols /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx
+^done
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-file-exec-file} Command
+@findex -file-exec-file
+
+@subsubheading Synopsis
+
+@example
+ -file-exec-file @var{file}
+@end example
+
+Specify the executable file to be debugged. Unlike
+@samp{-file-exec-and-symbols}, the symbol table is @emph{not} read
+from this file. If used without argument, @value{GDBN} clears the information
+about the executable file. No output is produced, except a completion
+notification.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{exec-file}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-file-exec-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx
+^done
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-file-list-exec-sections} Command
+@findex -file-list-exec-sections
+
+@subsubheading Synopsis
+
+@example
+ -file-list-exec-sections
+@end example
+
+List the sections of the current executable file.
+
+@subsubheading @value{GDBN} Command
+
+The @value{GDBN} command @samp{info file} shows, among the rest, the same
+information as this command. @code{gdbtk} has a corresponding command
+@samp{gdb_load_info}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-file-list-exec-source-files} Command
+@findex -file-list-exec-source-files
+
+@subsubheading Synopsis
+
+@example
+ -file-list-exec-source-files
+@end example
+
+List the source files for the current executable.
+
+@subsubheading @value{GDBN} Command
+
+There's no @value{GDBN} command which directly corresponds to this one.
+@code{gdbtk} has an analogous command @samp{gdb_listfiles}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-file-list-shared-libraries} Command
+@findex -file-list-shared-libraries
+
+@subsubheading Synopsis
+
+@example
+ -file-list-shared-libraries
+@end example
+
+List the shared libraries in the program.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info shared}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-file-list-symbol-files} Command
+@findex -file-list-symbol-files
+
+@subsubheading Synopsis
+
+@example
+ -file-list-symbol-files
+@end example
+
+List symbol files.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info file} (part of it).
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-file-symbol-file} Command
+@findex -file-symbol-file
+
+@subsubheading Synopsis
+
+@example
+ -file-symbol-file @var{file}
+@end example
+
+Read symbol table info from the specified @var{file} argument. When
+used without arguments, clears @value{GDBN}'s symbol table info. No output is
+produced, except for a completion notification.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{symbol-file}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-file-symbol-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx
+^done
+(@value{GDBP})
+@end smallexample
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Miscellaneous Commands
+@section Miscellaneous @value{GDBN} commands in @sc{gdb/mi}
+
+@c @subheading -gdb-complete
+
+@subheading The @code{-gdb-exit} Command
+@findex -gdb-exit
+
+@subsubheading Synopsis
+
+@example
+ -gdb-exit
+@end example
+
+Exit @value{GDBN} immediately.
+
+@subsubheading @value{GDBN} Command
+
+Approximately corresponds to @samp{quit}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-gdb-exit
+@end smallexample
+
+@subheading The @code{-gdb-set} Command
+@findex -gdb-set
+
+@subsubheading Synopsis
+
+@example
+ -gdb-set
+@end example
+
+Set an internal @value{GDBN} variable.
+@c IS THIS A DOLLAR VARIABLE? OR SOMETHING LIKE ANNOTATE ?????
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{set}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-gdb-set $foo=3
+^done
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-gdb-show} Command
+@findex -gdb-show
+
+@subsubheading Synopsis
+
+@example
+ -gdb-show
+@end example
+
+Show the current value of a @value{GDBN} variable.
+
+@subsubheading @value{GDBN} command
+
+The corresponding @value{GDBN} command is @samp{show}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-gdb-show annotate
+^done,value="0"
+(@value{GDBP})
+@end smallexample
+
+@c @subheading -gdb-source
+
+
+@subheading The @code{-gdb-version} Command
+@findex -gdb-version
+
+@subsubheading Synopsis
+
+@example
+ -gdb-version
+@end example
+
+Show version information for @value{GDBN}. Used mostly in testing.
+
+@subsubheading @value{GDBN} Command
+
+There's no equivalent @value{GDBN} command. @value{GDBN} by default shows this
+information when you start an interactive session.
+
+@subsubheading Example
+
+@c This example modifies the actual output from GDB to avoid overfull
+@c box in TeX.
+@smallexample
+(@value{GDBP})
+-gdb-version
+~GNU gdb 5.2.1
+~Copyright 2000 Free Software Foundation, Inc.
+~GDB is free software, covered by the GNU General Public License, and
+~you are welcome to change it and/or distribute copies of it under
+~ certain conditions.
+~Type "show copying" to see the conditions.
+~There is absolutely no warranty for GDB. Type "show warranty" for
+~ details.
+~This GDB was configured as
+ "--host=sparc-sun-solaris2.5.1 --target=ppc-eabi".
+^done
+(@value{GDBP})
+@end smallexample
+
+@ignore
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Kod Commands
+@section @sc{gdb/mi} Kod Commands
+
+The Kod commands are not implemented.
+
+@c @subheading -kod-info
+
+@c @subheading -kod-list
+
+@c @subheading -kod-list-object-types
+
+@c @subheading -kod-show
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Memory Overlay Commands
+@section @sc{gdb/mi} Memory Overlay Commands
+
+The memory overlay commands are not implemented.
+
+@c @subheading -overlay-auto
+
+@c @subheading -overlay-list-mapping-state
+
+@c @subheading -overlay-list-overlays
+
+@c @subheading -overlay-map
+
+@c @subheading -overlay-off
+
+@c @subheading -overlay-on
+
+@c @subheading -overlay-unmap
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Signal Handling Commands
+@section @sc{gdb/mi} Signal Handling Commands
+
+Signal handling commands are not implemented.
+
+@c @subheading -signal-handle
+
+@c @subheading -signal-list-handle-actions
+
+@c @subheading -signal-list-signal-types
+@end ignore
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Stack Manipulation
+@section @sc{gdb/mi} Stack Manipulation Commands
+
+
+@subheading The @code{-stack-info-frame} Command
+@findex -stack-info-frame
+
+@subsubheading Synopsis
+
+@example
+ -stack-info-frame
+@end example
+
+Get info on the current frame.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info frame} or @samp{frame}
+(without arguments).
+
+@subsubheading Example
+N.A.
+
+@subheading The @code{-stack-info-depth} Command
+@findex -stack-info-depth
+
+@subsubheading Synopsis
+
+@example
+ -stack-info-depth [ @var{max-depth} ]
+@end example
+
+Return the depth of the stack. If the integer argument @var{max-depth}
+is specified, do not count beyond @var{max-depth} frames.
+
+@subsubheading @value{GDBN} Command
+
+There's no equivalent @value{GDBN} command.
+
+@subsubheading Example
+
+For a stack with frame levels 0 through 11:
+
+@smallexample
+(@value{GDBP})
+-stack-info-depth
+^done,depth="12"
+(@value{GDBP})
+-stack-info-depth 4
+^done,depth="4"
+(@value{GDBP})
+-stack-info-depth 12
+^done,depth="12"
+(@value{GDBP})
+-stack-info-depth 11
+^done,depth="11"
+(@value{GDBP})
+-stack-info-depth 13
+^done,depth="12"
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-stack-list-arguments} Command
+@findex -stack-list-arguments
+
+@subsubheading Synopsis
+
+@example
+ -stack-list-arguments @var{show-values}
+ [ @var{low-frame} @var{high-frame} ]
+@end example
+
+Display a list of the arguments for the frames between @var{low-frame}
+and @var{high-frame} (inclusive). If @var{low-frame} and
+@var{high-frame} are not provided, list the arguments for the whole call
+stack.
+
+The @var{show-values} argument must have a value of 0 or 1. A value of
+0 means that only the names of the arguments are listed, a value of 1
+means that both names and values of the arguments are printed.
+
+@subsubheading @value{GDBN} Command
+
+@value{GDBN} does not have an equivalent command. @code{gdbtk} has a
+@samp{gdb_get_args} command which partially overlaps with the
+functionality of @samp{-stack-list-arguments}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-stack-list-frames
+^done,
+stack=[
+frame=@{level="0 ",addr="0x00010734",func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@},
+frame=@{level="1 ",addr="0x0001076c",func="callee3",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="17"@},
+frame=@{level="2 ",addr="0x0001078c",func="callee2",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="22"@},
+frame=@{level="3 ",addr="0x000107b4",func="callee1",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="27"@},
+frame=@{level="4 ",addr="0x000107e0",func="main",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="32"@}]
+(@value{GDBP})
+-stack-list-arguments 0
+^done,
+stack-args=[
+frame=@{level="0",args=[]@},
+frame=@{level="1",args=[name="strarg"]@},
+frame=@{level="2",args=[name="intarg",name="strarg"]@},
+frame=@{level="3",args=[name="intarg",name="strarg",name="fltarg"]@},
+frame=@{level="4",args=[]@}]
+(@value{GDBP})
+-stack-list-arguments 1
+^done,
+stack-args=[
+frame=@{level="0",args=[]@},
+frame=@{level="1",
+ args=[@{name="strarg",value="0x11940 \"A string argument.\""@}]@},
+frame=@{level="2",args=[
+@{name="intarg",value="2"@},
+@{name="strarg",value="0x11940 \"A string argument.\""@}]@},
+@{frame=@{level="3",args=[
+@{name="intarg",value="2"@},
+@{name="strarg",value="0x11940 \"A string argument.\""@},
+@{name="fltarg",value="3.5"@}]@},
+frame=@{level="4",args=[]@}]
+(@value{GDBP})
+-stack-list-arguments 0 2 2
+^done,stack-args=[frame=@{level="2",args=[name="intarg",name="strarg"]@}]
+(@value{GDBP})
+-stack-list-arguments 1 2 2
+^done,stack-args=[frame=@{level="2",
+args=[@{name="intarg",value="2"@},
+@{name="strarg",value="0x11940 \"A string argument.\""@}]@}]
+(@value{GDBP})
+@end smallexample
+
+@c @subheading -stack-list-exception-handlers
+
+
+@subheading The @code{-stack-list-frames} Command
+@findex -stack-list-frames
+
+@subsubheading Synopsis
+
+@example
+ -stack-list-frames [ @var{low-frame} @var{high-frame} ]
+@end example
+
+List the frames currently on the stack. For each frame it displays the
+following info:
+
+@table @samp
+@item @var{level}
+The frame number, 0 being the topmost frame, i.e. the innermost function.
+@item @var{addr}
+The @code{$pc} value for that frame.
+@item @var{func}
+Function name.
+@item @var{file}
+File name of the source file where the function lives.
+@item @var{line}
+Line number corresponding to the @code{$pc}.
+@end table
+
+If invoked without arguments, this command prints a backtrace for the
+whole stack. If given two integer arguments, it shows the frames whose
+levels are between the two arguments (inclusive). If the two arguments
+are equal, it shows the single frame at the corresponding level.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} commands are @samp{backtrace} and @samp{where}.
+
+@subsubheading Example
+
+Full stack backtrace:
+
+@smallexample
+(@value{GDBP})
+-stack-list-frames
+^done,stack=
+[frame=@{level="0 ",addr="0x0001076c",func="foo",
+ file="recursive2.c",line="11"@},
+frame=@{level="1 ",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="2 ",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="3 ",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="4 ",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="5 ",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="6 ",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="7 ",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="8 ",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="9 ",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="10",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="11",addr="0x00010738",func="main",
+ file="recursive2.c",line="4"@}]
+(@value{GDBP})
+@end smallexample
+
+Show frames between @var{low_frame} and @var{high_frame}:
+
+@smallexample
+(@value{GDBP})
+-stack-list-frames 3 5
+^done,stack=
+[frame=@{level="3 ",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="4 ",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="5 ",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@}]
+(@value{GDBP})
+@end smallexample
+
+Show a single frame:
+
+@smallexample
+(@value{GDBP})
+-stack-list-frames 3 3
+^done,stack=
+[frame=@{level="3 ",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@}]
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-stack-list-locals} Command
+@findex -stack-list-locals
+
+@subsubheading Synopsis
+
+@example
+ -stack-list-locals @var{print-values}
+@end example
+
+Display the local variable names for the current frame. With an
+argument of 0 prints only the names of the variables, with argument of 1
+prints also their values.
+
+@subsubheading @value{GDBN} Command
+
+@samp{info locals} in @value{GDBN}, @samp{gdb_get_locals} in @code{gdbtk}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-stack-list-locals 0
+^done,locals=[name="A",name="B",name="C"]
+(@value{GDBP})
+-stack-list-locals 1
+^done,locals=[@{name="A",value="1"@},@{name="B",value="2"@},
+ @{name="C",value="3"@}]
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-stack-select-frame} Command
+@findex -stack-select-frame
+
+@subsubheading Synopsis
+
+@example
+ -stack-select-frame @var{framenum}
+@end example
+
+Change the current frame. Select a different frame @var{framenum} on
+the stack.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} commands are @samp{frame}, @samp{up},
+@samp{down}, @samp{select-frame}, @samp{up-silent}, and @samp{down-silent}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-stack-select-frame 2
+^done
+(@value{GDBP})
+@end smallexample
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Symbol Query
+@section @sc{gdb/mi} Symbol Query Commands
+
+
+@subheading The @code{-symbol-info-address} Command
+@findex -symbol-info-address
+
+@subsubheading Synopsis
+
+@example
+ -symbol-info-address @var{symbol}
+@end example
+
+Describe where @var{symbol} is stored.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info address}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-info-file} Command
+@findex -symbol-info-file
+
+@subsubheading Synopsis
+
+@example
+ -symbol-info-file
+@end example
+
+Show the file for the symbol.
+
+@subsubheading @value{GDBN} Command
+
+There's no equivalent @value{GDBN} command. @code{gdbtk} has
+@samp{gdb_find_file}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-info-function} Command
+@findex -symbol-info-function
+
+@subsubheading Synopsis
+
+@example
+ -symbol-info-function
+@end example
+
+Show which function the symbol lives in.
+
+@subsubheading @value{GDBN} Command
+
+@samp{gdb_get_function} in @code{gdbtk}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-info-line} Command
+@findex -symbol-info-line
+
+@subsubheading Synopsis
+
+@example
+ -symbol-info-line
+@end example
+
+Show the core addresses of the code for a source line.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} comamnd is @samp{info line}.
+@code{gdbtk} has the @samp{gdb_get_line} and @samp{gdb_get_file} commands.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-info-symbol} Command
+@findex -symbol-info-symbol
+
+@subsubheading Synopsis
+
+@example
+ -symbol-info-symbol @var{addr}
+@end example
+
+Describe what symbol is at location @var{addr}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info symbol}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-list-functions} Command
+@findex -symbol-list-functions
+
+@subsubheading Synopsis
+
+@example
+ -symbol-list-functions
+@end example
+
+List the functions in the executable.
+
+@subsubheading @value{GDBN} Command
+
+@samp{info functions} in @value{GDBN}, @samp{gdb_listfunc} and
+@samp{gdb_search} in @code{gdbtk}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-list-types} Command
+@findex -symbol-list-types
+
+@subsubheading Synopsis
+
+@example
+ -symbol-list-types
+@end example
+
+List all the type names.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding commands are @samp{info types} in @value{GDBN},
+@samp{gdb_search} in @code{gdbtk}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-list-variables} Command
+@findex -symbol-list-variables
+
+@subsubheading Synopsis
+
+@example
+ -symbol-list-variables
+@end example
+
+List all the global and static variable names.
+
+@subsubheading @value{GDBN} Command
+
+@samp{info variables} in @value{GDBN}, @samp{gdb_search} in @code{gdbtk}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-locate} Command
+@findex -symbol-locate
+
+@subsubheading Synopsis
+
+@example
+ -symbol-locate
+@end example
+
+@subsubheading @value{GDBN} Command
+
+@samp{gdb_loc} in @code{gdbtk}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-type} Command
+@findex -symbol-type
+
+@subsubheading Synopsis
+
+@example
+ -symbol-type @var{variable}
+@end example
+
+Show type of @var{variable}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{ptype}, @code{gdbtk} has
+@samp{gdb_obj_variable}.
+
+@subsubheading Example
+N.A.
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Target Manipulation
+@section @sc{gdb/mi} Target Manipulation Commands
+
+
+@subheading The @code{-target-attach} Command
+@findex -target-attach
+
+@subsubheading Synopsis
+
+@example
+ -target-attach @var{pid} | @var{file}
+@end example
+
+Attach to a process @var{pid} or a file @var{file} outside of @value{GDBN}.
+
+@subsubheading @value{GDBN} command
+
+The corresponding @value{GDBN} command is @samp{attach}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-target-compare-sections} Command
+@findex -target-compare-sections
+
+@subsubheading Synopsis
+
+@example
+ -target-compare-sections [ @var{section} ]
+@end example
+
+Compare data of section @var{section} on target to the exec file.
+Without the argument, all sections are compared.
+
+@subsubheading @value{GDBN} Command
+
+The @value{GDBN} equivalent is @samp{compare-sections}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-target-detach} Command
+@findex -target-detach
+
+@subsubheading Synopsis
+
+@example
+ -target-detach
+@end example
+
+Disconnect from the remote target. There's no output.
+
+@subsubheading @value{GDBN} command
+
+The corresponding @value{GDBN} command is @samp{detach}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-target-detach
+^done
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-target-download} Command
+@findex -target-download
+
+@subsubheading Synopsis
+
+@example
+ -target-download
+@end example
+
+Loads the executable onto the remote target.
+It prints out an update message every half second, which includes the fields:
+
+@table @samp
+@item section
+The name of the section.
+@item section-sent
+The size of what has been sent so far for that section.
+@item section-size
+The size of the section.
+@item total-sent
+The total size of what was sent so far (the current and the previous sections).
+@item total-size
+The size of the overall executable to download.
+@end table
+
+@noindent
+Each message is sent as status record (@pxref{GDB/MI Output Syntax, ,
+@sc{gdb/mi} Output Syntax}).
+
+In addition, it prints the name and size of the sections, as they are
+downloaded. These messages include the following fields:
+
+@table @samp
+@item section
+The name of the section.
+@item section-size
+The size of the section.
+@item total-size
+The size of the overall executable to download.
+@end table
+
+@noindent
+At the end, a summary is printed.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{load}.
+
+@subsubheading Example
+
+Note: each status message appears on a single line. Here the messages
+have been broken down so that they can fit onto a page.
+
+@smallexample
+(@value{GDBP})
+-target-download
++download,@{section=".text",section-size="6668",total-size="9880"@}
++download,@{section=".text",section-sent="512",section-size="6668",
+total-sent="512",total-size="9880"@}
++download,@{section=".text",section-sent="1024",section-size="6668",
+total-sent="1024",total-size="9880"@}
++download,@{section=".text",section-sent="1536",section-size="6668",
+total-sent="1536",total-size="9880"@}
++download,@{section=".text",section-sent="2048",section-size="6668",
+total-sent="2048",total-size="9880"@}
++download,@{section=".text",section-sent="2560",section-size="6668",
+total-sent="2560",total-size="9880"@}
++download,@{section=".text",section-sent="3072",section-size="6668",
+total-sent="3072",total-size="9880"@}
++download,@{section=".text",section-sent="3584",section-size="6668",
+total-sent="3584",total-size="9880"@}
++download,@{section=".text",section-sent="4096",section-size="6668",
+total-sent="4096",total-size="9880"@}
++download,@{section=".text",section-sent="4608",section-size="6668",
+total-sent="4608",total-size="9880"@}
++download,@{section=".text",section-sent="5120",section-size="6668",
+total-sent="5120",total-size="9880"@}
++download,@{section=".text",section-sent="5632",section-size="6668",
+total-sent="5632",total-size="9880"@}
++download,@{section=".text",section-sent="6144",section-size="6668",
+total-sent="6144",total-size="9880"@}
++download,@{section=".text",section-sent="6656",section-size="6668",
+total-sent="6656",total-size="9880"@}
++download,@{section=".init",section-size="28",total-size="9880"@}
++download,@{section=".fini",section-size="28",total-size="9880"@}
++download,@{section=".data",section-size="3156",total-size="9880"@}
++download,@{section=".data",section-sent="512",section-size="3156",
+total-sent="7236",total-size="9880"@}
++download,@{section=".data",section-sent="1024",section-size="3156",
+total-sent="7748",total-size="9880"@}
++download,@{section=".data",section-sent="1536",section-size="3156",
+total-sent="8260",total-size="9880"@}
++download,@{section=".data",section-sent="2048",section-size="3156",
+total-sent="8772",total-size="9880"@}
++download,@{section=".data",section-sent="2560",section-size="3156",
+total-sent="9284",total-size="9880"@}
++download,@{section=".data",section-sent="3072",section-size="3156",
+total-sent="9796",total-size="9880"@}
+^done,address="0x10004",load-size="9880",transfer-rate="6586",
+write-rate="429"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-target-exec-status} Command
+@findex -target-exec-status
+
+@subsubheading Synopsis
+
+@example
+ -target-exec-status
+@end example
+
+Provide information on the state of the target (whether it is running or
+not, for instance).
+
+@subsubheading @value{GDBN} Command
+
+There's no equivalent @value{GDBN} command.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-target-list-available-targets} Command
+@findex -target-list-available-targets
+
+@subsubheading Synopsis
+
+@example
+ -target-list-available-targets
+@end example
+
+List the possible targets to connect to.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{help target}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-target-list-current-targets} Command
+@findex -target-list-current-targets
+
+@subsubheading Synopsis
+
+@example
+ -target-list-current-targets
+@end example
+
+Describe the current target.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding information is printed by @samp{info file} (among
+other things).
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-target-list-parameters} Command
+@findex -target-list-parameters
+
+@subsubheading Synopsis
+
+@example
+ -target-list-parameters
+@end example
+
+@c ????
+
+@subsubheading @value{GDBN} Command
+
+No equivalent.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-target-select} Command
+@findex -target-select
+
+@subsubheading Synopsis
+
+@example
+ -target-select @var{type} @var{parameters @dots{}}
+@end example
+
+Connect @value{GDBN} to the remote target. This command takes two args:
+
+@table @samp
+@item @var{type}
+The type of target, for instance @samp{async}, @samp{remote}, etc.
+@item @var{parameters}
+Device names, host names and the like. @xref{Target Commands, ,
+Commands for managing targets}, for more details.
+@end table
+
+The output is a connection notification, followed by the address at
+which the target program is, in the following form:
+
+@smallexample
+^connected,addr="@var{address}",func="@var{function name}",
+ args=[@var{arg list}]
+@end smallexample
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{target}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-target-select async /dev/ttya
+^connected,addr="0xfe00a300",func="??",args=[]
+(@value{GDBP})
+@end smallexample
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Thread Commands
+@section @sc{gdb/mi} Thread Commands
+
+
+@subheading The @code{-thread-info} Command
+@findex -thread-info
+
+@subsubheading Synopsis
+
+@example
+ -thread-info
+@end example
+
+@subsubheading @value{GDBN} command
+
+No equivalent.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-thread-list-all-threads} Command
+@findex -thread-list-all-threads
+
+@subsubheading Synopsis
+
+@example
+ -thread-list-all-threads
+@end example
+
+@subsubheading @value{GDBN} Command
+
+The equivalent @value{GDBN} command is @samp{info threads}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-thread-list-ids} Command
+@findex -thread-list-ids
+
+@subsubheading Synopsis
+
+@example
+ -thread-list-ids
+@end example
+
+Produces a list of the currently known @value{GDBN} thread ids. At the
+end of the list it also prints the total number of such threads.
+
+@subsubheading @value{GDBN} Command
+
+Part of @samp{info threads} supplies the same information.
+
+@subsubheading Example
+
+No threads present, besides the main process:
+
+@smallexample
+(@value{GDBP})
+-thread-list-ids
+^done,thread-ids=@{@},number-of-threads="0"
+(@value{GDBP})
+@end smallexample
+
+
+Several threads:
+
+@smallexample
+(@value{GDBP})
+-thread-list-ids
+^done,thread-ids=@{thread-id="3",thread-id="2",thread-id="1"@},
+number-of-threads="3"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-thread-select} Command
+@findex -thread-select
+
+@subsubheading Synopsis
+
+@example
+ -thread-select @var{threadnum}
+@end example
+
+Make @var{threadnum} the current thread. It prints the number of the new
+current thread, and the topmost frame for that thread.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{thread}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-exec-next
+^running
+(@value{GDBP})
+*stopped,reason="end-stepping-range",thread-id="2",line="187",
+file="../../../devo/gdb/testsuite/gdb.threads/linux-dp.c"
+(@value{GDBP})
+-thread-list-ids
+^done,
+thread-ids=@{thread-id="3",thread-id="2",thread-id="1"@},
+number-of-threads="3"
+(@value{GDBP})
+-thread-select 3
+^done,new-thread-id="3",
+frame=@{level="0 ",func="vprintf",
+args=[@{name="format",value="0x8048e9c \"%*s%c %d %c\\n\""@},
+@{name="arg",value="0x2"@}],file="vprintf.c",line="31"@}
+(@value{GDBP})
+@end smallexample
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Tracepoint Commands
+@section @sc{gdb/mi} Tracepoint Commands
+
+The tracepoint commands are not yet implemented.
+
+@c @subheading -trace-actions
+
+@c @subheading -trace-delete
+
+@c @subheading -trace-disable
+
+@c @subheading -trace-dump
+
+@c @subheading -trace-enable
+
+@c @subheading -trace-exists
+
+@c @subheading -trace-find
+
+@c @subheading -trace-frame-number
+
+@c @subheading -trace-info
+
+@c @subheading -trace-insert
+
+@c @subheading -trace-list
+
+@c @subheading -trace-pass-count
+
+@c @subheading -trace-save
+
+@c @subheading -trace-start
+
+@c @subheading -trace-stop
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Variable Objects
+@section @sc{gdb/mi} Variable Objects
+
+
+@subheading Motivation for Variable Objects in @sc{gdb/mi}
+
+For the implementation of a variable debugger window (locals, watched
+expressions, etc.), we are proposing the adaptation of the existing code
+used by @code{Insight}.
+
+The two main reasons for that are:
+
+@enumerate 1
+@item
+It has been proven in practice (it is already on its second generation).
+
+@item
+It will shorten development time (needless to say how important it is
+now).
+@end enumerate
+
+The original interface was designed to be used by Tcl code, so it was
+slightly changed so it could be used through @sc{gdb/mi}. This section
+describes the @sc{gdb/mi} operations that will be available and gives some
+hints about their use.
+
+@emph{Note}: In addition to the set of operations described here, we
+expect the @sc{gui} implementation of a variable window to require, at
+least, the following operations:
+
+@itemize @bullet
+@item @code{-gdb-show} @code{output-radix}
+@item @code{-stack-list-arguments}
+@item @code{-stack-list-locals}
+@item @code{-stack-select-frame}
+@end itemize
+
+@subheading Introduction to Variable Objects in @sc{gdb/mi}
+
+@cindex variable objects in @sc{gdb/mi}
+The basic idea behind variable objects is the creation of a named object
+to represent a variable, an expression, a memory location or even a CPU
+register. For each object created, a set of operations is available for
+examining or changing its properties.
+
+Furthermore, complex data types, such as C structures, are represented
+in a tree format. For instance, the @code{struct} type variable is the
+root and the children will represent the struct members. If a child
+is itself of a complex type, it will also have children of its own.
+Appropriate language differences are handled for C, C@t{++} and Java.
+
+When returning the actual values of the objects, this facility allows
+for the individual selection of the display format used in the result
+creation. It can be chosen among: binary, decimal, hexadecimal, octal
+and natural. Natural refers to a default format automatically
+chosen based on the variable type (like decimal for an @code{int}, hex
+for pointers, etc.).
+
+The following is the complete set of @sc{gdb/mi} operations defined to
+access this functionality:
+
+@multitable @columnfractions .4 .6
+@item @strong{Operation}
+@tab @strong{Description}
+
+@item @code{-var-create}
+@tab create a variable object
+@item @code{-var-delete}
+@tab delete the variable object and its children
+@item @code{-var-set-format}
+@tab set the display format of this variable
+@item @code{-var-show-format}
+@tab show the display format of this variable
+@item @code{-var-info-num-children}
+@tab tells how many children this object has
+@item @code{-var-list-children}
+@tab return a list of the object's children
+@item @code{-var-info-type}
+@tab show the type of this variable object
+@item @code{-var-info-expression}
+@tab print what this variable object represents
+@item @code{-var-show-attributes}
+@tab is this variable editable? does it exist here?
+@item @code{-var-evaluate-expression}
+@tab get the value of this variable
+@item @code{-var-assign}
+@tab set the value of this variable
+@item @code{-var-update}
+@tab update the variable and its children
+@end multitable
+
+In the next subsection we describe each operation in detail and suggest
+how it can be used.
+
+@subheading Description And Use of Operations on Variable Objects
+
+@subheading The @code{-var-create} Command
+@findex -var-create
+
+@subsubheading Synopsis
+
+@example
+ -var-create @{@var{name} | "-"@}
+ @{@var{frame-addr} | "*"@} @var{expression}
+@end example
+
+This operation creates a variable object, which allows the monitoring of
+a variable, the result of an expression, a memory cell or a CPU
+register.
+
+The @var{name} parameter is the string by which the object can be
+referenced. It must be unique. If @samp{-} is specified, the varobj
+system will generate a string ``varNNNNNN'' automatically. It will be
+unique provided that one does not specify @var{name} on that format.
+The command fails if a duplicate name is found.
+
+The frame under which the expression should be evaluated can be
+specified by @var{frame-addr}. A @samp{*} indicates that the current
+frame should be used.
+
+@var{expression} is any expression valid on the current language set (must not
+begin with a @samp{*}), or one of the following:
+
+@itemize @bullet
+@item
+@samp{*@var{addr}}, where @var{addr} is the address of a memory cell
+
+@item
+@samp{*@var{addr}-@var{addr}} --- a memory address range (TBD)
+
+@item
+@samp{$@var{regname}} --- a CPU register name
+@end itemize
+
+@subsubheading Result
+
+This operation returns the name, number of children and the type of the
+object created. Type is returned as a string as the ones generated by
+the @value{GDBN} CLI:
+
+@example
+ name="@var{name}",numchild="N",type="@var{type}"
+@end example
+
+
+@subheading The @code{-var-delete} Command
+@findex -var-delete
+
+@subsubheading Synopsis
+
+@example
+ -var-delete @var{name}
+@end example
+
+Deletes a previously created variable object and all of its children.
+
+Returns an error if the object @var{name} is not found.
+
+
+@subheading The @code{-var-set-format} Command
+@findex -var-set-format
+
+@subsubheading Synopsis
+
+@example
+ -var-set-format @var{name} @var{format-spec}
+@end example
+
+Sets the output format for the value of the object @var{name} to be
+@var{format-spec}.
+
+The syntax for the @var{format-spec} is as follows:
+
+@example
+ @var{format-spec} @expansion{}
+ @{binary | decimal | hexadecimal | octal | natural@}
+@end example
+
+
+@subheading The @code{-var-show-format} Command
+@findex -var-show-format
+
+@subsubheading Synopsis
+
+@example
+ -var-show-format @var{name}
+@end example
+
+Returns the format used to display the value of the object @var{name}.
+
+@example
+ @var{format} @expansion{}
+ @var{format-spec}
+@end example
+
+
+@subheading The @code{-var-info-num-children} Command
+@findex -var-info-num-children
+
+@subsubheading Synopsis
+
+@example
+ -var-info-num-children @var{name}
+@end example
+
+Returns the number of children of a variable object @var{name}:
+
+@example
+ numchild=@var{n}
+@end example
+
+
+@subheading The @code{-var-list-children} Command
+@findex -var-list-children
+
+@subsubheading Synopsis
+
+@example
+ -var-list-children @var{name}
+@end example
+
+Returns a list of the children of the specified variable object:
+
+@example
+ numchild=@var{n},children=@{@{name=@var{name},
+ numchild=@var{n},type=@var{type}@},@r{(repeats N times)}@}
+@end example
+
+
+@subheading The @code{-var-info-type} Command
+@findex -var-info-type
+
+@subsubheading Synopsis
+
+@example
+ -var-info-type @var{name}
+@end example
+
+Returns the type of the specified variable @var{name}. The type is
+returned as a string in the same format as it is output by the
+@value{GDBN} CLI:
+
+@example
+ type=@var{typename}
+@end example
+
+
+@subheading The @code{-var-info-expression} Command
+@findex -var-info-expression
+
+@subsubheading Synopsis
+
+@example
+ -var-info-expression @var{name}
+@end example
+
+Returns what is represented by the variable object @var{name}:
+
+@example
+ lang=@var{lang-spec},exp=@var{expression}
+@end example
+
+@noindent
+where @var{lang-spec} is @code{@{"C" | "C++" | "Java"@}}.
+
+@subheading The @code{-var-show-attributes} Command
+@findex -var-show-attributes
+
+@subsubheading Synopsis
+
+@example
+ -var-show-attributes @var{name}
+@end example
+
+List attributes of the specified variable object @var{name}:
+
+@example
+ status=@var{attr} [ ( ,@var{attr} )* ]
+@end example
+
+@noindent
+where @var{attr} is @code{@{ @{ editable | noneditable @} | TBD @}}.
+
+@subheading The @code{-var-evaluate-expression} Command
+@findex -var-evaluate-expression
+
+@subsubheading Synopsis
+
+@example
+ -var-evaluate-expression @var{name}
+@end example
+
+Evaluates the expression that is represented by the specified variable
+object and returns its value as a string in the current format specified
+for the object:
+
+@example
+ value=@var{value}
+@end example
+
+@subheading The @code{-var-assign} Command
+@findex -var-assign
+
+@subsubheading Synopsis
+
+@example
+ -var-assign @var{name} @var{expression}
+@end example
+
+Assigns the value of @var{expression} to the variable object specified
+by @var{name}. The object must be @samp{editable}.
+
+@subheading The @code{-var-update} Command
+@findex -var-update
+
+@subsubheading Synopsis
+
+@example
+ -var-update @{@var{name} | "*"@}
+@end example
+
+Update the value of the variable object @var{name} by evaluating its
+expression after fetching all the new values from memory or registers.
+A @samp{*} causes all existing variable objects to be updated.
diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c
new file mode 100644
index 00000000000..5d15aa98b8a
--- /dev/null
+++ b/gdb/mi/mi-cmd-break.c
@@ -0,0 +1,240 @@
+/* MI Command Set - breakpoint and watchpoint commands.
+ Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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 "defs.h"
+#include "mi-cmds.h"
+#include "ui-out.h"
+#include "mi-out.h"
+#include "breakpoint.h"
+#include "gdb_string.h"
+#include "mi-getopt.h"
+#include "gdb-events.h"
+#include "gdb.h"
+
+enum
+ {
+ FROM_TTY = 0
+ };
+
+/* Output a single breakpoint. */
+
+static void
+breakpoint_notify (int b)
+{
+ gdb_breakpoint_query (uiout, b);
+}
+
+
+struct gdb_events breakpoint_hooks =
+{
+ breakpoint_notify,
+ breakpoint_notify,
+ breakpoint_notify,
+};
+
+
+enum bp_type
+ {
+ REG_BP,
+ HW_BP,
+ REGEXP_BP
+ };
+
+/* Insert a breakpoint. The type of breakpoint is specified by the
+ first argument: -break-insert <location> --> insert a regular
+ breakpoint. -break-insert -t <location> --> insert a temporary
+ breakpoint. -break-insert -h <location> --> insert an hardware
+ breakpoint. -break-insert -t -h <location> --> insert a temporary
+ hw bp.
+ -break-insert -r <regexp> --> insert a bp at functions matching
+ <regexp> */
+
+enum mi_cmd_result
+mi_cmd_break_insert (char *command, char **argv, int argc)
+{
+ char *address = NULL;
+ enum bp_type type = REG_BP;
+ int temp_p = 0;
+ int thread = -1;
+ int ignore_count = 0;
+ char *condition = NULL;
+ enum gdb_rc rc;
+ struct gdb_events *old_hooks;
+ enum opt
+ {
+ HARDWARE_OPT, TEMP_OPT /*, REGEXP_OPT */ , CONDITION_OPT,
+ IGNORE_COUNT_OPT, THREAD_OPT
+ };
+ static struct mi_opt opts[] =
+ {
+ {"h", HARDWARE_OPT, 0},
+ {"t", TEMP_OPT, 0},
+ {"c", CONDITION_OPT, 1},
+ {"i", IGNORE_COUNT_OPT, 1},
+ {"p", THREAD_OPT, 1},
+ 0
+ };
+
+ /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
+ to denote the end of the option list. */
+ int optind = 0;
+ char *optarg;
+ while (1)
+ {
+ int opt = mi_getopt ("mi_cmd_break_insert", argc, argv, opts, &optind, &optarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case TEMP_OPT:
+ temp_p = 1;
+ break;
+ case HARDWARE_OPT:
+ type = HW_BP;
+ break;
+#if 0
+ case REGEXP_OPT:
+ type = REGEXP_BP;
+ break;
+#endif
+ case CONDITION_OPT:
+ condition = optarg;
+ break;
+ case IGNORE_COUNT_OPT:
+ ignore_count = atol (optarg);
+ break;
+ case THREAD_OPT:
+ thread = atol (optarg);
+ break;
+ }
+ }
+
+ if (optind >= argc)
+ error ("mi_cmd_break_insert: Missing <location>");
+ if (optind < argc - 1)
+ error ("mi_cmd_break_insert: Garbage following <location>");
+ address = argv[optind];
+
+ /* Now we have what we need, let's insert the breakpoint! */
+ old_hooks = set_gdb_event_hooks (&breakpoint_hooks);
+ switch (type)
+ {
+ case REG_BP:
+ rc = gdb_breakpoint (address, condition,
+ 0 /*hardwareflag */ , temp_p,
+ thread, ignore_count);
+ break;
+ case HW_BP:
+ rc = gdb_breakpoint (address, condition,
+ 1 /*hardwareflag */ , temp_p,
+ thread, ignore_count);
+ break;
+#if 0
+ case REGEXP_BP:
+ if (temp_p)
+ error ("mi_cmd_break_insert: Unsupported tempoary regexp breakpoint");
+ else
+ rbreak_command_wrapper (address, FROM_TTY);
+ return MI_CMD_DONE;
+ break;
+#endif
+ default:
+ internal_error (__FILE__, __LINE__,
+ "mi_cmd_break_insert: Bad switch.");
+ }
+ set_gdb_event_hooks (old_hooks);
+
+ if (rc == GDB_RC_FAIL)
+ return MI_CMD_CAUGHT_ERROR;
+ else
+ return MI_CMD_DONE;
+}
+
+enum wp_type
+{
+ REG_WP,
+ READ_WP,
+ ACCESS_WP
+};
+
+/* Insert a watchpoint. The type of watchpoint is specified by the
+ first argument:
+ -break-watch <expr> --> insert a regular wp.
+ -break-watch -r <expr> --> insert a read watchpoint.
+ -break-watch -a <expr> --> insert an access wp. */
+
+enum mi_cmd_result
+mi_cmd_break_watch (char *command, char **argv, int argc)
+{
+ char *expr = NULL;
+ enum wp_type type = REG_WP;
+ enum opt
+ {
+ READ_OPT, ACCESS_OPT
+ };
+ static struct mi_opt opts[] =
+ {
+ {"r", READ_OPT, 0},
+ {"a", ACCESS_OPT, 0},
+ 0
+ };
+
+ /* Parse arguments. */
+ int optind = 0;
+ char *optarg;
+ while (1)
+ {
+ int opt = mi_getopt ("mi_cmd_break_watch", argc, argv, opts, &optind, &optarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case READ_OPT:
+ type = READ_WP;
+ break;
+ case ACCESS_OPT:
+ type = ACCESS_WP;
+ break;
+ }
+ }
+ if (optind >= argc)
+ error ("mi_cmd_break_watch: Missing <expression>");
+ if (optind < argc - 1)
+ error ("mi_cmd_break_watch: Garbage following <expression>");
+ expr = argv[optind];
+
+ /* Now we have what we need, let's insert the watchpoint! */
+ switch (type)
+ {
+ case REG_WP:
+ watch_command_wrapper (expr, FROM_TTY);
+ break;
+ case READ_WP:
+ rwatch_command_wrapper (expr, FROM_TTY);
+ break;
+ case ACCESS_WP:
+ awatch_command_wrapper (expr, FROM_TTY);
+ break;
+ default:
+ error ("mi_cmd_break_watch: Unknown watchpoint type.");
+ }
+ return MI_CMD_DONE;
+}
diff --git a/gdb/mi/mi-cmd-disas.c b/gdb/mi/mi-cmd-disas.c
new file mode 100644
index 00000000000..70054c635c8
--- /dev/null
+++ b/gdb/mi/mi-cmd-disas.c
@@ -0,0 +1,499 @@
+/* MI Command Set - disassemble commands.
+ Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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 "defs.h"
+#include "target.h"
+#include "value.h"
+#include "mi-cmds.h"
+#include "mi-getopt.h"
+#include "ui-out.h"
+
+/* Disassemble functions. FIXME: these do not really belong here. We
+ should get rid of all the duplicate code in gdb that does the same
+ thing: disassemble_command() and the gdbtk variation. */
+
+/* This Structure is used in mi_cmd_disassemble.
+ We need a different sort of line table from the normal one cuz we can't
+ depend upon implicit line-end pc's for lines to do the
+ reordering in this function. */
+
+struct dis_line_entry
+{
+ int line;
+ CORE_ADDR start_pc;
+ CORE_ADDR end_pc;
+};
+
+/* This variable determines where memory used for disassembly is read from. */
+int gdb_disassemble_from_exec = -1;
+
+/* This is the memory_read_func for gdb_disassemble when we are
+ disassembling from the exec file. */
+static int
+gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr,
+ unsigned int len, disassemble_info * info)
+{
+ extern struct target_ops exec_ops;
+ int res;
+
+ errno = 0;
+ res = xfer_memory (memaddr, myaddr, len, 0, 0, &exec_ops);
+
+ if (res == len)
+ return 0;
+ else if (errno == 0)
+ return EIO;
+ else
+ return errno;
+}
+
+static int
+compare_lines (const PTR mle1p, const PTR mle2p)
+{
+ struct dis_line_entry *mle1, *mle2;
+ int val;
+
+ mle1 = (struct dis_line_entry *) mle1p;
+ mle2 = (struct dis_line_entry *) mle2p;
+
+ val = mle1->line - mle2->line;
+
+ if (val != 0)
+ return val;
+
+ return mle1->start_pc - mle2->start_pc;
+}
+
+static int
+dump_insns (disassemble_info * di, CORE_ADDR low, CORE_ADDR high,
+ int how_many, struct ui_stream *stb)
+{
+ int num_displayed = 0;
+ CORE_ADDR pc;
+
+ /* parts of the symbolic representation of the address */
+ int unmapped;
+ char *filename = NULL;
+ char *name = NULL;
+ int offset;
+ int line;
+
+ for (pc = low; pc < high;)
+ {
+ QUIT;
+ if (how_many >= 0)
+ {
+ if (num_displayed >= how_many)
+ break;
+ else
+ num_displayed++;
+ }
+ ui_out_tuple_begin (uiout, NULL);
+ ui_out_field_core_addr (uiout, "address", pc);
+
+ if (!build_address_symbolic (pc, 0, &name, &offset, &filename,
+ &line, &unmapped))
+ {
+ /* We don't care now about line, filename and
+ unmapped. But we might in the future. */
+ ui_out_field_string (uiout, "func-name", name);
+ ui_out_field_int (uiout, "offset", offset);
+ }
+ if (filename != NULL)
+ xfree (filename);
+ if (name != NULL)
+ xfree (name);
+
+ ui_file_rewind (stb->stream);
+ pc += TARGET_PRINT_INSN (pc, di);
+ ui_out_field_stream (uiout, "inst", stb);
+ ui_file_rewind (stb->stream);
+ ui_out_tuple_end (uiout);
+ }
+ return num_displayed;
+}
+
+/* The idea here is to present a source-O-centric view of a
+ function to the user. This means that things are presented
+ in source order, with (possibly) out of order assembly
+ immediately following. */
+static void
+do_mixed_source_and_assembly (struct disassemble_info *di, int nlines,
+ struct linetable_entry *le,
+ CORE_ADDR low, CORE_ADDR high,
+ struct symtab *symtab,
+ int how_many, struct ui_stream *stb)
+{
+ int newlines = 0;
+ struct dis_line_entry *mle;
+ struct symtab_and_line sal;
+ int i;
+ int out_of_order = 0;
+ int next_line = 0;
+ CORE_ADDR pc;
+ int num_displayed = 0;
+
+ mle = (struct dis_line_entry *) alloca (nlines
+ * sizeof (struct dis_line_entry));
+
+ /* Copy linetable entries for this function into our data
+ structure, creating end_pc's and setting out_of_order as
+ appropriate. */
+
+ /* First, skip all the preceding functions. */
+
+ for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
+
+ /* Now, copy all entries before the end of this function. */
+
+ for (; i < nlines - 1 && le[i].pc < high; i++)
+ {
+ if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
+ continue; /* Ignore duplicates */
+
+ /* Skip any end-of-function markers. */
+ if (le[i].line == 0)
+ continue;
+
+ mle[newlines].line = le[i].line;
+ if (le[i].line > le[i + 1].line)
+ out_of_order = 1;
+ mle[newlines].start_pc = le[i].pc;
+ mle[newlines].end_pc = le[i + 1].pc;
+ newlines++;
+ }
+
+ /* If we're on the last line, and it's part of the function,
+ then we need to get the end pc in a special way. */
+
+ if (i == nlines - 1 && le[i].pc < high)
+ {
+ mle[newlines].line = le[i].line;
+ mle[newlines].start_pc = le[i].pc;
+ sal = find_pc_line (le[i].pc, 0);
+ mle[newlines].end_pc = sal.end;
+ newlines++;
+ }
+
+ /* Now, sort mle by line #s (and, then by addresses within
+ lines). */
+
+ if (out_of_order)
+ qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines);
+
+ /* Now, for each line entry, emit the specified lines (unless
+ they have been emitted before), followed by the assembly code
+ for that line. */
+
+ ui_out_list_begin (uiout, "asm_insns");
+
+ for (i = 0; i < newlines; i++)
+ {
+ int close_list = 1;
+ /* Print out everything from next_line to the current line. */
+ if (mle[i].line >= next_line)
+ {
+ if (next_line != 0)
+ {
+ /* Just one line to print. */
+ if (next_line == mle[i].line)
+ {
+ ui_out_tuple_begin (uiout, "src_and_asm_line");
+ print_source_lines (symtab, next_line, mle[i].line + 1, 0);
+ }
+ else
+ {
+ /* Several source lines w/o asm instructions associated. */
+ for (; next_line < mle[i].line; next_line++)
+ {
+ ui_out_tuple_begin (uiout, "src_and_asm_line");
+ print_source_lines (symtab, next_line, next_line + 1,
+ 0);
+ ui_out_list_begin (uiout, "line_asm_insn");
+ ui_out_list_end (uiout);
+ ui_out_tuple_end (uiout);
+ }
+ /* Print the last line and leave list open for
+ asm instructions to be added. */
+ ui_out_tuple_begin (uiout, "src_and_asm_line");
+ print_source_lines (symtab, next_line, mle[i].line + 1, 0);
+ }
+ }
+ else
+ {
+ ui_out_tuple_begin (uiout, "src_and_asm_line");
+ print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
+ }
+
+ next_line = mle[i].line + 1;
+ ui_out_list_begin (uiout, "line_asm_insn");
+ /* Don't close the list if the lines are not in order. */
+ if (i < (newlines - 1) && mle[i + 1].line <= mle[i].line)
+ close_list = 0;
+ }
+
+ num_displayed += dump_insns (di, mle[i].start_pc, mle[i].end_pc,
+ how_many, stb);
+ if (close_list)
+ {
+ ui_out_list_end (uiout);
+ ui_out_tuple_end (uiout);
+ close_list = 0;
+ }
+ if (how_many >= 0)
+ if (num_displayed >= how_many)
+ break;
+ }
+ ui_out_list_end (uiout);
+}
+
+
+static void
+do_assembly_only (disassemble_info * di, CORE_ADDR low,
+ CORE_ADDR high, int how_many, struct ui_stream *stb)
+{
+ int num_displayed = 0;
+
+ ui_out_list_begin (uiout, "asm_insns");
+
+ num_displayed = dump_insns (di, low, high, how_many, stb);
+
+ ui_out_list_end (uiout);
+}
+
+enum mi_cmd_result
+do_disassembly (char *file_string,
+ int line_num,
+ int mixed_source_and_assembly,
+ int how_many, CORE_ADDR low, CORE_ADDR high)
+{
+ static disassemble_info di;
+ static int di_initialized;
+ /* To collect the instruction outputted from opcodes. */
+ static struct ui_stream *stb = NULL;
+ struct symtab *symtab = NULL;
+ struct linetable_entry *le = NULL;
+ int nlines = -1;
+
+ if (!di_initialized)
+ {
+ /* We don't add a cleanup for this, because the allocation of
+ the stream is done once only for each gdb run, and we need to
+ keep it around until the end. Hopefully there won't be any
+ errors in the init code below, that make this function bail
+ out. */
+ stb = ui_out_stream_new (uiout);
+ INIT_DISASSEMBLE_INFO_NO_ARCH (di, stb->stream,
+ (fprintf_ftype) fprintf_unfiltered);
+ di.flavour = bfd_target_unknown_flavour;
+ di.memory_error_func = dis_asm_memory_error;
+ di.print_address_func = dis_asm_print_address;
+ di_initialized = 1;
+ }
+
+ di.mach = TARGET_PRINT_INSN_INFO->mach;
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ di.endian = BFD_ENDIAN_BIG;
+ else
+ di.endian = BFD_ENDIAN_LITTLE;
+
+ /* If gdb_disassemble_from_exec == -1, then we use the following heuristic to
+ determine whether or not to do disassembly from target memory or from the
+ exec file:
+
+ If we're debugging a local process, read target memory, instead of the
+ exec file. This makes disassembly of functions in shared libs work
+ correctly. Also, read target memory if we are debugging native threads.
+
+ Else, we're debugging a remote process, and should disassemble from the
+ exec file for speed. However, this is no good if the target modifies its
+ code (for relocation, or whatever). */
+
+ if (gdb_disassemble_from_exec == -1)
+ {
+ if (strcmp (target_shortname, "child") == 0
+ || strcmp (target_shortname, "procfs") == 0
+ || strcmp (target_shortname, "vxprocess") == 0
+ || strstr (target_shortname, "-threads") != NULL)
+ gdb_disassemble_from_exec = 0; /* It's a child process, read inferior mem */
+ else
+ gdb_disassemble_from_exec = 1; /* It's remote, read the exec file */
+ }
+
+ if (gdb_disassemble_from_exec)
+ di.read_memory_func = gdb_dis_asm_read_memory;
+ else
+ di.read_memory_func = dis_asm_read_memory;
+
+ /* Assume symtab is valid for whole PC range */
+ symtab = find_pc_symtab (low);
+
+ if (symtab != NULL && symtab->linetable != NULL)
+ {
+ /* Convert the linetable to a bunch of my_line_entry's. */
+ le = symtab->linetable->item;
+ nlines = symtab->linetable->nitems;
+ }
+
+ if (!mixed_source_and_assembly || nlines <= 0
+ || symtab == NULL || symtab->linetable == NULL)
+ do_assembly_only (&di, low, high, how_many, stb);
+
+ else if (mixed_source_and_assembly)
+ do_mixed_source_and_assembly (&di, nlines, le, low,
+ high, symtab, how_many, stb);
+
+ gdb_flush (gdb_stdout);
+
+ return MI_CMD_DONE;
+}
+
+/* The arguments to be passed on the command line and parsed here are:
+
+ either:
+
+ START-ADDRESS: address to start the disassembly at.
+ END-ADDRESS: address to end the disassembly at.
+
+ or:
+
+ FILENAME: The name of the file where we want disassemble from.
+ LINE: The line around which we want to disassemble. It will
+ disassemble the function that contins that line.
+ HOW_MANY: Number of disassembly lines to display. In mixed mode, it
+ is the number of disassembly lines only, not counting the source
+ lines.
+
+ always required:
+
+ MODE: 0 or 1 for disassembly only, or mixed source and disassembly,
+ respectively. */
+enum mi_cmd_result
+mi_cmd_disassemble (char *command, char **argv, int argc)
+{
+ enum mi_cmd_result retval;
+ CORE_ADDR start;
+
+ int mixed_source_and_assembly;
+ struct symtab *s;
+
+ /* Which options have we processed ... */
+ int file_seen = 0;
+ int line_seen = 0;
+ int num_seen = 0;
+ int start_seen = 0;
+ int end_seen = 0;
+
+ /* ... and their corresponding value. */
+ char *file_string = NULL;
+ int line_num = -1;
+ int how_many = -1;
+ CORE_ADDR low = 0;
+ CORE_ADDR high = 0;
+
+ /* Options processing stuff. */
+ int optind = 0;
+ char *optarg;
+ enum opt
+ {
+ FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT
+ };
+ static struct mi_opt opts[] = {
+ {"f", FILE_OPT, 1},
+ {"l", LINE_OPT, 1},
+ {"n", NUM_OPT, 1},
+ {"s", START_OPT, 1},
+ {"e", END_OPT, 1},
+ 0
+ };
+
+ /* Get the options with their arguments. Keep track of what we
+ encountered. */
+ while (1)
+ {
+ int opt = mi_getopt ("mi_cmd_disassemble", argc, argv, opts,
+ &optind, &optarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case FILE_OPT:
+ file_string = xstrdup (optarg);
+ file_seen = 1;
+ break;
+ case LINE_OPT:
+ line_num = atoi (optarg);
+ line_seen = 1;
+ break;
+ case NUM_OPT:
+ how_many = atoi (optarg);
+ num_seen = 1;
+ break;
+ case START_OPT:
+ low = parse_and_eval_address (optarg);
+ start_seen = 1;
+ break;
+ case END_OPT:
+ high = parse_and_eval_address (optarg);
+ end_seen = 1;
+ break;
+ }
+ }
+ argv += optind;
+ argc -= optind;
+
+ /* Allow only filename + linenum (with how_many which is not
+ required) OR start_addr + and_addr */
+
+ if (!((line_seen && file_seen && num_seen && !start_seen && !end_seen)
+ || (line_seen && file_seen && !num_seen && !start_seen && !end_seen)
+ || (!line_seen && !file_seen && !num_seen && start_seen && end_seen)))
+ error
+ ("mi_cmd_disassemble: Usage: ( [-f filename -l linenum [-n howmany]] | [-s startaddr -e endaddr]) [--] mixed_mode.");
+
+ if (argc != 1)
+ error
+ ("mi_cmd_disassemble: Usage: [-f filename -l linenum [-n howmany]] [-s startaddr -e endaddr] [--] mixed_mode.");
+
+ mixed_source_and_assembly = atoi (argv[0]);
+ if ((mixed_source_and_assembly != 0) && (mixed_source_and_assembly != 1))
+ error ("mi_cmd_disassemble: Mixed_mode argument must be 0 or 1.");
+
+
+ /* We must get the function beginning and end where line_num is
+ contained. */
+
+ if (line_seen && file_seen)
+ {
+ s = lookup_symtab (file_string);
+ if (s == NULL)
+ error ("mi_cmd_disassemble: Invalid filename.");
+ if (!find_line_pc (s, line_num, &start))
+ error ("mi_cmd_disassemble: Invalid line number");
+ if (find_pc_partial_function (start, NULL, &low, &high) == 0)
+ error ("mi_cmd_disassemble: No function contains specified address");
+ }
+
+ retval = do_disassembly (file_string,
+ line_num,
+ mixed_source_and_assembly, how_many, low, high);
+ return retval;
+}
diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
new file mode 100644
index 00000000000..b4bae47716d
--- /dev/null
+++ b/gdb/mi/mi-cmd-stack.c
@@ -0,0 +1,309 @@
+/* MI Command Set - stack commands.
+ Copyright 2000, 2002 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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 "defs.h"
+#include "target.h"
+#include "frame.h"
+#include "value.h"
+#include "mi-cmds.h"
+#include "ui-out.h"
+#include "symtab.h"
+
+/* FIXME: these should go in some .h file but stack.c doesn't have a
+ corresponding .h file. These wrappers will be obsolete anyway, once
+ we pull the plug on the sanitization. */
+extern void select_frame_command_wrapper (char *, int);
+
+static void list_args_or_locals (int locals, int values, struct frame_info *fi);
+
+/* Print a list of the stack frames. Args can be none, in which case
+ we want to print the whole backtrace, or a pair of numbers
+ specifying the frame numbers at which to start and stop the
+ display. If the two numbers are equal, a single frame will be
+ displayed. */
+enum mi_cmd_result
+mi_cmd_stack_list_frames (char *command, char **argv, int argc)
+{
+ int frame_low;
+ int frame_high;
+ int i;
+ struct frame_info *fi;
+
+ if (!target_has_stack)
+ error ("mi_cmd_stack_list_frames: No stack.");
+
+ if (argc > 2 || argc == 1)
+ error ("mi_cmd_stack_list_frames: Usage: [FRAME_LOW FRAME_HIGH]");
+
+ if (argc == 2)
+ {
+ frame_low = atoi (argv[0]);
+ frame_high = atoi (argv[1]);
+ }
+ else
+ {
+ /* Called with no arguments, it means we want the whole
+ backtrace. */
+ frame_low = -1;
+ frame_high = -1;
+ }
+
+ /* Let's position fi on the frame at which to start the
+ display. Could be the innermost frame if the whole stack needs
+ displaying, or if frame_low is 0. */
+ for (i = 0, fi = get_current_frame ();
+ fi && i < frame_low;
+ i++, fi = get_prev_frame (fi));
+
+ if (fi == NULL)
+ error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
+
+ ui_out_list_begin (uiout, "stack");
+
+ /* Now let;s print the frames up to frame_high, or until there are
+ frames in the stack. */
+ for (;
+ fi && (i <= frame_high || frame_high == -1);
+ i++, fi = get_prev_frame (fi))
+ {
+ QUIT;
+ /* level == i: always print the level 'i'
+ source == LOC_AND_ADDRESS: print the location and the address
+ always, even for level 0.
+ args == 0: don't print the arguments. */
+ print_frame_info (fi /* frame info */ ,
+ i /* level */ ,
+ LOC_AND_ADDRESS /* source */ ,
+ 0 /* args */ );
+ }
+
+ ui_out_list_end (uiout);
+ if (i < frame_high)
+ error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
+
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_stack_info_depth (char *command, char **argv, int argc)
+{
+ int frame_high;
+ int i;
+ struct frame_info *fi;
+
+ if (!target_has_stack)
+ error ("mi_cmd_stack_info_depth: No stack.");
+
+ if (argc > 1)
+ error ("mi_cmd_stack_info_depth: Usage: [MAX_DEPTH]");
+
+ if (argc == 1)
+ frame_high = atoi (argv[0]);
+ else
+ /* Called with no arguments, it means we want the real depth of
+ the stack. */
+ frame_high = -1;
+
+ for (i = 0, fi = get_current_frame ();
+ fi && (i < frame_high || frame_high == -1);
+ i++, fi = get_prev_frame (fi))
+ QUIT;
+
+ ui_out_field_int (uiout, "depth", i);
+
+ return MI_CMD_DONE;
+}
+
+/* Print a list of the locals for the current frame. With argument of
+ 0, print only the names, with argument of 1 print also the
+ values. */
+enum mi_cmd_result
+mi_cmd_stack_list_locals (char *command, char **argv, int argc)
+{
+ if (argc != 1)
+ error ("mi_cmd_stack_list_locals: Usage: PRINT_VALUES");
+
+ list_args_or_locals (1, atoi (argv[0]), selected_frame);
+ return MI_CMD_DONE;
+}
+
+/* Print a list of the arguments for the current frame. With argument
+ of 0, print only the names, with argument of 1 print also the
+ values. */
+enum mi_cmd_result
+mi_cmd_stack_list_args (char *command, char **argv, int argc)
+{
+ int frame_low;
+ int frame_high;
+ int i;
+ struct frame_info *fi;
+
+ if (argc < 1 || argc > 3 || argc == 2)
+ error ("mi_cmd_stack_list_args: Usage: PRINT_VALUES [FRAME_LOW FRAME_HIGH]");
+
+ if (argc == 3)
+ {
+ frame_low = atoi (argv[1]);
+ frame_high = atoi (argv[2]);
+ }
+ else
+ {
+ /* Called with no arguments, it means we want args for the whole
+ backtrace. */
+ frame_low = -1;
+ frame_high = -1;
+ }
+
+ /* Let's position fi on the frame at which to start the
+ display. Could be the innermost frame if the whole stack needs
+ displaying, or if frame_low is 0. */
+ for (i = 0, fi = get_current_frame ();
+ fi && i < frame_low;
+ i++, fi = get_prev_frame (fi));
+
+ if (fi == NULL)
+ error ("mi_cmd_stack_list_args: Not enough frames in stack.");
+
+ ui_out_list_begin (uiout, "stack-args");
+
+ /* Now let's print the frames up to frame_high, or until there are
+ frames in the stack. */
+ for (;
+ fi && (i <= frame_high || frame_high == -1);
+ i++, fi = get_prev_frame (fi))
+ {
+ QUIT;
+ ui_out_tuple_begin (uiout, "frame");
+ ui_out_field_int (uiout, "level", i);
+ list_args_or_locals (0, atoi (argv[0]), fi);
+ ui_out_tuple_end (uiout);
+ }
+
+ ui_out_list_end (uiout);
+ if (i < frame_high)
+ error ("mi_cmd_stack_list_args: Not enough frames in stack.");
+
+ return MI_CMD_DONE;
+}
+
+/* Print a list of the locals or the arguments for the currently
+ selected frame. If the argument passed is 0, printonly the names
+ of the variables, if an argument of 1 is passed, print the values
+ as well. */
+static void
+list_args_or_locals (int locals, int values, struct frame_info *fi)
+{
+ struct block *block;
+ struct symbol *sym;
+ int i, nsyms;
+ static struct ui_stream *stb = NULL;
+
+ stb = ui_out_stream_new (uiout);
+
+ block = get_frame_block (fi, 0);
+
+ ui_out_list_begin (uiout, locals ? "locals" : "args");
+
+ while (block != 0)
+ {
+ ALL_BLOCK_SYMBOLS (block, i, sym)
+ {
+ int print_me = 0;
+
+ switch (SYMBOL_CLASS (sym))
+ {
+ default:
+ case LOC_UNDEF: /* catches errors */
+ case LOC_CONST: /* constant */
+ case LOC_TYPEDEF: /* local typedef */
+ case LOC_LABEL: /* local label */
+ case LOC_BLOCK: /* local function */
+ case LOC_CONST_BYTES: /* loc. byte seq. */
+ case LOC_UNRESOLVED: /* unresolved static */
+ case LOC_OPTIMIZED_OUT: /* optimized out */
+ print_me = 0;
+ break;
+
+ case LOC_ARG: /* argument */
+ case LOC_REF_ARG: /* reference arg */
+ case LOC_REGPARM: /* register arg */
+ case LOC_REGPARM_ADDR: /* indirect register arg */
+ case LOC_LOCAL_ARG: /* stack arg */
+ case LOC_BASEREG_ARG: /* basereg arg */
+ if (!locals)
+ print_me = 1;
+ break;
+
+ case LOC_LOCAL: /* stack local */
+ case LOC_BASEREG: /* basereg local */
+ case LOC_STATIC: /* static */
+ case LOC_REGISTER: /* register */
+ if (locals)
+ print_me = 1;
+ break;
+ }
+ if (print_me)
+ {
+ if (values)
+ ui_out_tuple_begin (uiout, NULL);
+ ui_out_field_string (uiout, "name", SYMBOL_NAME (sym));
+
+ if (values)
+ {
+ struct symbol *sym2;
+ if (!locals)
+ sym2 = lookup_symbol (SYMBOL_NAME (sym),
+ block, VAR_NAMESPACE,
+ (int *) NULL,
+ (struct symtab **) NULL);
+ else
+ sym2 = sym;
+ print_variable_value (sym2, fi, stb->stream);
+ ui_out_field_stream (uiout, "value", stb);
+ ui_out_tuple_end (uiout);
+ }
+ }
+ }
+ if (BLOCK_FUNCTION (block))
+ break;
+ else
+ block = BLOCK_SUPERBLOCK (block);
+ }
+ ui_out_list_end (uiout);
+ ui_out_stream_delete (stb);
+}
+
+enum mi_cmd_result
+mi_cmd_stack_select_frame (char *command, char **argv, int argc)
+{
+ if (!target_has_stack)
+ error ("mi_cmd_stack_select_frame: No stack.");
+
+ if (argc > 1)
+ error ("mi_cmd_stack_select_frame: Usage: [FRAME_SPEC]");
+
+ /* with no args, don't change frame */
+ if (argc == 0)
+ select_frame_command_wrapper (0, 1 /* not used */ );
+ else
+ select_frame_command_wrapper (argv[0], 1 /* not used */ );
+ return MI_CMD_DONE;
+}
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
new file mode 100644
index 00000000000..4848a4e29c1
--- /dev/null
+++ b/gdb/mi/mi-cmd-var.c
@@ -0,0 +1,498 @@
+/* MI Command Set - varobj commands.
+
+ Copyright 2000, 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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 "defs.h"
+#include "mi-cmds.h"
+#include "ui-out.h"
+#include "mi-out.h"
+#include "varobj.h"
+#include "value.h"
+#include <ctype.h>
+
+extern int varobjdebug; /* defined in varobj.c */
+
+static int varobj_update_one (struct varobj *var);
+
+/* VAROBJ operations */
+
+enum mi_cmd_result
+mi_cmd_var_create (char *command, char **argv, int argc)
+{
+ CORE_ADDR frameaddr = 0;
+ struct varobj *var;
+ char *name;
+ char *frame;
+ char *expr;
+ char *type;
+ struct cleanup *old_cleanups;
+ enum varobj_type var_type;
+
+ if (argc != 3)
+ {
+ /* xasprintf (&mi_error_message,
+ "mi_cmd_var_create: Usage: .");
+ return MI_CMD_ERROR; */
+ error ("mi_cmd_var_create: Usage: NAME FRAME EXPRESSION.");
+ }
+
+ name = xstrdup (argv[0]);
+ /* Add cleanup for name. Must be free_current_contents as
+ name can be reallocated */
+ old_cleanups = make_cleanup (free_current_contents, &name);
+
+ frame = xstrdup (argv[1]);
+ old_cleanups = make_cleanup (xfree, frame);
+
+ expr = xstrdup (argv[2]);
+
+ if (strcmp (name, "-") == 0)
+ {
+ xfree (name);
+ name = varobj_gen_name ();
+ }
+ else if (!isalpha (*name))
+ error ("mi_cmd_var_create: name of object must begin with a letter");
+
+ if (strcmp (frame, "*") == 0)
+ var_type = USE_CURRENT_FRAME;
+ else if (strcmp (frame, "@") == 0)
+ var_type = USE_SELECTED_FRAME;
+ else
+ {
+ var_type = USE_SPECIFIED_FRAME;
+ frameaddr = parse_and_eval_address (frame);
+ }
+
+ if (varobjdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "Name=\"%s\", Frame=\"%s\" (0x%s), Expression=\"%s\"\n",
+ name, frame, paddr (frameaddr), expr);
+
+ var = varobj_create (name, expr, frameaddr, var_type);
+
+ if (var == NULL)
+ error ("mi_cmd_var_create: unable to create variable object");
+
+ ui_out_field_string (uiout, "name", name);
+ ui_out_field_int (uiout, "numchild", varobj_get_num_children (var));
+ type = varobj_get_type (var);
+ if (type == NULL)
+ ui_out_field_string (uiout, "type", "");
+ else
+ {
+ ui_out_field_string (uiout, "type", type);
+ xfree (type);
+ }
+
+ do_cleanups (old_cleanups);
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_delete (char *command, char **argv, int argc)
+{
+ char *name;
+ char *expr;
+ struct varobj *var;
+ int numdel;
+ int children_only_p = 0;
+ struct cleanup *old_cleanups;
+
+ if (argc < 1 || argc > 2)
+ error ("mi_cmd_var_delete: Usage: [-c] EXPRESSION.");
+
+ name = xstrdup (argv[0]);
+ /* Add cleanup for name. Must be free_current_contents as
+ name can be reallocated */
+ old_cleanups = make_cleanup (free_current_contents, &name);
+
+ /* If we have one single argument it cannot be '-c' or any string
+ starting with '-'. */
+ if (argc == 1)
+ {
+ if (strcmp (name, "-c") == 0)
+ error ("mi_cmd_var_delete: Missing required argument after '-c': variable object name");
+ if (*name == '-')
+ error ("mi_cmd_var_delete: Illegal variable object name");
+ }
+
+ /* If we have 2 arguments they must be '-c' followed by a string
+ which would be the variable name. */
+ if (argc == 2)
+ {
+ expr = xstrdup (argv[1]);
+ if (strcmp (name, "-c") != 0)
+ error ("mi_cmd_var_delete: Invalid option.");
+ children_only_p = 1;
+ xfree (name);
+ name = xstrdup (expr);
+ xfree (expr);
+ }
+
+ /* If we didn't error out, now NAME contains the name of the
+ variable. */
+
+ var = varobj_get_handle (name);
+
+ if (var == NULL)
+ error ("mi_cmd_var_delete: Variable object not found.");
+
+ numdel = varobj_delete (var, NULL, children_only_p);
+
+ ui_out_field_int (uiout, "ndeleted", numdel);
+
+ do_cleanups (old_cleanups);
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_set_format (char *command, char **argv, int argc)
+{
+ enum varobj_display_formats format;
+ int len;
+ struct varobj *var;
+ char *formspec;
+
+ if (argc != 2)
+ error ("mi_cmd_var_set_format: Usage: NAME FORMAT.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+
+ if (var == NULL)
+ error ("mi_cmd_var_set_format: Variable object not found");
+
+ formspec = xstrdup (argv[1]);
+ if (formspec == NULL)
+ error ("mi_cmd_var_set_format: Must specify the format as: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\"");
+
+ len = strlen (formspec);
+
+ if (STREQN (formspec, "natural", len))
+ format = FORMAT_NATURAL;
+ else if (STREQN (formspec, "binary", len))
+ format = FORMAT_BINARY;
+ else if (STREQN (formspec, "decimal", len))
+ format = FORMAT_DECIMAL;
+ else if (STREQN (formspec, "hexadecimal", len))
+ format = FORMAT_HEXADECIMAL;
+ else if (STREQN (formspec, "octal", len))
+ format = FORMAT_OCTAL;
+ else
+ error ("mi_cmd_var_set_format: Unknown display format: must be: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\"");
+
+ /* Set the format of VAR to given format */
+ varobj_set_display_format (var, format);
+
+ /* Report the new current format */
+ ui_out_field_string (uiout, "format", varobj_format_string[(int) format]);
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_show_format (char *command, char **argv, int argc)
+{
+ enum varobj_display_formats format;
+ struct varobj *var;
+
+ if (argc != 1)
+ error ("mi_cmd_var_show_format: Usage: NAME.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_show_format: Variable object not found");
+
+ format = varobj_get_display_format (var);
+
+ /* Report the current format */
+ ui_out_field_string (uiout, "format", varobj_format_string[(int) format]);
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_info_num_children (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+
+ if (argc != 1)
+ error ("mi_cmd_var_info_num_children: Usage: NAME.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_info_num_children: Variable object not found");
+
+ ui_out_field_int (uiout, "numchild", varobj_get_num_children (var));
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_list_children (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+ struct varobj **childlist;
+ struct varobj **cc;
+ int numchild;
+ char *type;
+
+ if (argc != 1)
+ error ("mi_cmd_var_list_children: Usage: NAME.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_list_children: Variable object not found");
+
+ numchild = varobj_list_children (var, &childlist);
+ ui_out_field_int (uiout, "numchild", numchild);
+
+ if (numchild <= 0)
+ return MI_CMD_DONE;
+
+ ui_out_tuple_begin (uiout, "children");
+ cc = childlist;
+ while (*cc != NULL)
+ {
+ ui_out_tuple_begin (uiout, "child");
+ ui_out_field_string (uiout, "name", varobj_get_objname (*cc));
+ ui_out_field_string (uiout, "exp", varobj_get_expression (*cc));
+ ui_out_field_int (uiout, "numchild", varobj_get_num_children (*cc));
+ type = varobj_get_type (*cc);
+ /* C++ pseudo-variables (public, private, protected) do not have a type */
+ if (type)
+ ui_out_field_string (uiout, "type", varobj_get_type (*cc));
+ ui_out_tuple_end (uiout);
+ cc++;
+ }
+ ui_out_tuple_end (uiout);
+ xfree (childlist);
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_info_type (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+
+ if (argc != 1)
+ error ("mi_cmd_var_info_type: Usage: NAME.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_info_type: Variable object not found");
+
+ ui_out_field_string (uiout, "type", varobj_get_type (var));
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_info_expression (char *command, char **argv, int argc)
+{
+ enum varobj_languages lang;
+ struct varobj *var;
+
+ if (argc != 1)
+ error ("mi_cmd_var_info_expression: Usage: NAME.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_info_expression: Variable object not found");
+
+ lang = varobj_get_language (var);
+
+ ui_out_field_string (uiout, "lang", varobj_language_string[(int) lang]);
+ ui_out_field_string (uiout, "exp", varobj_get_expression (var));
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_show_attributes (char *command, char **argv, int argc)
+{
+ int attr;
+ char *attstr;
+ struct varobj *var;
+
+ if (argc != 1)
+ error ("mi_cmd_var_show_attributes: Usage: NAME.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_show_attributes: Variable object not found");
+
+ attr = varobj_get_attributes (var);
+ /* FIXME: define masks for attributes */
+ if (attr & 0x00000001)
+ attstr = "editable";
+ else
+ attstr = "noneditable";
+
+ ui_out_field_string (uiout, "attr", attstr);
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_evaluate_expression (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+
+ if (argc != 1)
+ error ("mi_cmd_var_evaluate_expression: Usage: NAME.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_evaluate_expression: Variable object not found");
+
+ ui_out_field_string (uiout, "value", varobj_get_value (var));
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_assign (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+ char *expression;
+
+ if (argc != 2)
+ error ("mi_cmd_var_assign: Usage: NAME EXPRESSION.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_assign: Variable object not found");
+
+ /* FIXME: define masks for attributes */
+ if (!(varobj_get_attributes (var) & 0x00000001))
+ error ("mi_cmd_var_assign: Variable object is not editable");
+
+ expression = xstrdup (argv[1]);
+
+ if (!varobj_set_value (var, expression))
+ error ("mi_cmd_var_assign: Could not assign expression to varible object");
+
+ ui_out_field_string (uiout, "value", varobj_get_value (var));
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_update (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+ struct varobj **rootlist;
+ struct varobj **cr;
+ char *name;
+ int nv;
+
+ if (argc != 1)
+ error ("mi_cmd_var_update: Usage: NAME.");
+
+ name = argv[0];
+
+ /* Check if the parameter is a "*" which means that we want
+ to update all variables */
+
+ if ((*name == '*') && (*(name + 1) == '\0'))
+ {
+ nv = varobj_list (&rootlist);
+ ui_out_tuple_begin (uiout, "changelist");
+ if (nv <= 0)
+ {
+ ui_out_tuple_end (uiout);
+ return MI_CMD_DONE;
+ }
+ cr = rootlist;
+ while (*cr != NULL)
+ {
+ varobj_update_one (*cr);
+ cr++;
+ }
+ xfree (rootlist);
+ ui_out_tuple_end (uiout);
+ }
+ else
+ {
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (name);
+ if (var == NULL)
+ error ("mi_cmd_var_update: Variable object not found");
+
+ ui_out_tuple_begin (uiout, "changelist");
+ varobj_update_one (var);
+ ui_out_tuple_end (uiout);
+ }
+ return MI_CMD_DONE;
+}
+
+/* Helper for mi_cmd_var_update() Returns 0 if the update for
+ the variable fails (usually because the variable is out of
+ scope), and 1 if it succeeds. */
+
+static int
+varobj_update_one (struct varobj *var)
+{
+ struct varobj **changelist;
+ struct varobj **cc;
+ int nc;
+
+ nc = varobj_update (&var, &changelist);
+
+ /* nc == 0 means that nothing has changed.
+ nc == -1 means that an error occured in updating the variable.
+ nc == -2 means the variable has changed type. */
+
+ if (nc == 0)
+ return 1;
+ else if (nc == -1)
+ {
+ ui_out_field_string (uiout, "name", varobj_get_objname(var));
+ ui_out_field_string (uiout, "in_scope", "false");
+ return -1;
+ }
+ else if (nc == -2)
+ {
+ ui_out_field_string (uiout, "name", varobj_get_objname (var));
+ ui_out_field_string (uiout, "in_scope", "true");
+ ui_out_field_string (uiout, "new_type", varobj_get_type(var));
+ ui_out_field_int (uiout, "new_num_children",
+ varobj_get_num_children(var));
+ }
+ else
+ {
+
+ cc = changelist;
+ while (*cc != NULL)
+ {
+ ui_out_field_string (uiout, "name", varobj_get_objname (*cc));
+ ui_out_field_string (uiout, "in_scope", "true");
+ ui_out_field_string (uiout, "type_changed", "false");
+ cc++;
+ }
+ xfree (changelist);
+ return 1;
+ }
+ return 1;
+}
diff --git a/gdb/mi/mi-console.c b/gdb/mi/mi-console.c
new file mode 100644
index 00000000000..c1b6e9f7b33
--- /dev/null
+++ b/gdb/mi/mi-console.c
@@ -0,0 +1,115 @@
+/* MI Console code.
+
+ Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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 "defs.h"
+#include "mi-console.h"
+#include "gdb_string.h"
+
+/* MI-console: send output to std-out but correcty encapsulated */
+
+static ui_file_fputs_ftype mi_console_file_fputs;
+static ui_file_flush_ftype mi_console_file_flush;
+static ui_file_delete_ftype mi_console_file_delete;
+
+struct mi_console_file
+ {
+ int *magic;
+ struct ui_file *raw;
+ struct ui_file *buffer;
+ const char *prefix;
+ };
+
+int mi_console_file_magic;
+
+struct ui_file *
+mi_console_file_new (struct ui_file *raw,
+ const char *prefix)
+{
+ struct ui_file *ui_file = ui_file_new ();
+ struct mi_console_file *mi_console = XMALLOC (struct mi_console_file);
+ mi_console->magic = &mi_console_file_magic;
+ mi_console->raw = raw;
+ mi_console->buffer = mem_fileopen ();
+ mi_console->prefix = prefix;
+ set_ui_file_fputs (ui_file, mi_console_file_fputs);
+ set_ui_file_flush (ui_file, mi_console_file_flush);
+ set_ui_file_data (ui_file, mi_console, mi_console_file_delete);
+ return ui_file;
+}
+
+static void
+mi_console_file_delete (struct ui_file *file)
+{
+ struct mi_console_file *mi_console = ui_file_data (file);
+ if (mi_console->magic != &mi_console_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "mi_console_file_delete: bad magic number");
+ xfree (mi_console);
+}
+
+static void
+mi_console_file_fputs (const char *buf,
+ struct ui_file *file)
+{
+ struct mi_console_file *mi_console = ui_file_data (file);
+ if (mi_console->magic != &mi_console_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "mi_console_file_fputs: bad magic number");
+ /* Append the text to our internal buffer */
+ fputs_unfiltered (buf, mi_console->buffer);
+ /* Flush when an embedded \n */
+ if (strchr (buf, '\n') != NULL)
+ gdb_flush (file);
+}
+
+/* Transform a byte sequence into a console output packet. */
+static void
+mi_console_raw_packet (void *data,
+ const char *buf,
+ long length_buf)
+{
+ struct mi_console_file *mi_console = data;
+ if (mi_console->magic != &mi_console_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "mi_console_file_transform: bad magic number");
+
+ if (length_buf > 0)
+ {
+ fputs_unfiltered (mi_console->prefix, mi_console->raw);
+ fputs_unfiltered ("\"", mi_console->raw);
+ fputstrn_unfiltered (buf, length_buf, '"', mi_console->raw);
+ fputs_unfiltered ("\"\n", mi_console->raw);
+ gdb_flush (mi_console->raw);
+ }
+}
+
+static void
+mi_console_file_flush (struct ui_file *file)
+{
+ struct mi_console_file *mi_console = ui_file_data (file);
+ if (mi_console->magic != &mi_console_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "mi_console_file_flush: bad magic number");
+ ui_file_put (mi_console->buffer, mi_console_raw_packet, mi_console);
+ ui_file_rewind (mi_console->buffer);
+}
diff --git a/gdb/mi/mi-console.h b/gdb/mi/mi-console.h
new file mode 100644
index 00000000000..6bd03cbd924
--- /dev/null
+++ b/gdb/mi/mi-console.h
@@ -0,0 +1,27 @@
+/* MI Command Set - MI Console.
+ Copyright 2000 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef MI_CONSOLE_H
+#define MI_CONSOLE_H
+
+extern struct ui_file *mi_console_file_new (struct ui_file *raw, const char *prefix);
+
+#endif
diff --git a/gdb/mi/mi-getopt.c b/gdb/mi/mi-getopt.c
new file mode 100644
index 00000000000..59ccdf3efd0
--- /dev/null
+++ b/gdb/mi/mi-getopt.c
@@ -0,0 +1,76 @@
+/* MI Command Set - MI Option Parser.
+ Copyright 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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 "defs.h"
+#include "mi-getopt.h"
+#include "gdb_string.h"
+
+int
+mi_getopt (const char *prefix,
+ int argc, char **argv,
+ struct mi_opt *opts,
+ int *optind, char **optarg)
+{
+ char *arg;
+ struct mi_opt *opt;
+ /* We assume that argv/argc are ok. */
+ if (*optind > argc || *optind < 0)
+ internal_error (__FILE__, __LINE__,
+ "mi_getopt_long: optind out of bounds");
+ if (*optind == argc)
+ return -1;
+ arg = argv[*optind];
+ /* ``--''? */
+ if (strcmp (arg, "--") == 0)
+ {
+ *optind += 1;
+ *optarg = NULL;
+ return -1;
+ }
+ /* End of option list. */
+ if (arg[0] != '-')
+ {
+ *optarg = NULL;
+ return -1;
+ }
+ /* Look the option up. */
+ for (opt = opts; opt->name != NULL; opt++)
+ {
+ if (strcmp (opt->name, arg + 1) != 0)
+ continue;
+ if (opt->arg_p)
+ {
+ /* A non-simple optarg option. */
+ if (argc < *optind + 2)
+ error ("%s: Option %s requires an argument", prefix, arg);
+ *optarg = argv[(*optind) + 1];
+ *optind = (*optind) + 2;
+ return opt->index;
+ }
+ else
+ {
+ *optarg = NULL;
+ *optind = (*optind) + 1;
+ return opt->index;
+ }
+ }
+ error ("%s: Unknown option ``%s''", prefix, arg + 1);
+}
diff --git a/gdb/mi/mi-getopt.h b/gdb/mi/mi-getopt.h
new file mode 100644
index 00000000000..6b31adf029a
--- /dev/null
+++ b/gdb/mi/mi-getopt.h
@@ -0,0 +1,60 @@
+/* MI Option Parser.
+ Copyright 2000 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef MI_GETOPT_H
+#define MI_GETOPT_H
+
+/* Like getopt() but with simpler semantics.
+
+ An option has the form ``-<name>''. The special option ``--''
+ denotes the end of the option list. An option can be followed by a
+ separate argument (on a per option basis).
+
+ On entry OPTIND contains the index of the next element of ARGV that
+ needs parsing. OPTIND is updated to indicate the index of the next
+ argument before mi_getopt() returns.
+
+ If ARGV[OPTIND] is an option, that options INDEX is returned.
+ OPTARG is set to the options argument or NULL. OPTIND is updated.
+
+ If ARGV[OPTIND] is not an option, -1 is returned and OPTIND updated
+ to specify the non-option argument. OPTARG is set to NULL.
+
+ mi_getopt() calls ``error("%s: Unknown option %c", prefix,
+ option)'' if an unknown option is encountered. */
+
+struct mi_opt;
+extern int mi_getopt (const char *prefix, int argc, char **argv,
+ struct mi_opt *opt, int *optind, char **optarg);
+
+/* The option list. Terminated by NAME==NULL. ARG_P that the option
+ requires an argument. INDEX is returned to identify th option. */
+
+struct mi_opt
+ {
+ const char *name;
+ int index;
+ int arg_p;
+ };
+
+struct mi_opt;
+
+#endif
diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
new file mode 100644
index 00000000000..947720bc10c
--- /dev/null
+++ b/gdb/mi/mi-out.c
@@ -0,0 +1,452 @@
+/* MI Command Set - output generating routines.
+
+ Copyright 2000, 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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 "defs.h"
+#include "ui-out.h"
+#include "mi-out.h"
+
+struct ui_out_data
+ {
+ int suppress_field_separator;
+ int suppress_output;
+ int mi_version;
+ struct ui_file *buffer;
+ };
+
+/* These are the MI output functions */
+
+static void mi_table_begin (struct ui_out *uiout, int nbrofcols,
+ int nr_rows, const char *tblid);
+static void mi_table_body (struct ui_out *uiout);
+static void mi_table_end (struct ui_out *uiout);
+static void mi_table_header (struct ui_out *uiout, int width,
+ enum ui_align alig, const char *col_name,
+ const char *colhdr);
+static void mi_begin (struct ui_out *uiout, enum ui_out_type type,
+ int level, const char *id);
+static void mi_end (struct ui_out *uiout, enum ui_out_type type, int level);
+static void mi_field_int (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alig, const char *fldname, int value);
+static void mi_field_skip (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alig, const char *fldname);
+static void mi_field_string (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alig, const char *fldname,
+ const char *string);
+static void mi_field_fmt (struct ui_out *uiout, int fldno,
+ int width, enum ui_align align,
+ const char *fldname, const char *format,
+ va_list args);
+static void mi_spaces (struct ui_out *uiout, int numspaces);
+static void mi_text (struct ui_out *uiout, const char *string);
+static void mi_message (struct ui_out *uiout, int verbosity,
+ const char *format, va_list args);
+static void mi_wrap_hint (struct ui_out *uiout, char *identstring);
+static void mi_flush (struct ui_out *uiout);
+
+/* This is the MI ui-out implementation functions vector */
+
+/* FIXME: This can be initialized dynamically after default is set to
+ handle initial output in main.c */
+
+struct ui_out_impl mi_ui_out_impl =
+{
+ mi_table_begin,
+ mi_table_body,
+ mi_table_end,
+ mi_table_header,
+ mi_begin,
+ mi_end,
+ mi_field_int,
+ mi_field_skip,
+ mi_field_string,
+ mi_field_fmt,
+ mi_spaces,
+ mi_text,
+ mi_message,
+ mi_wrap_hint,
+ mi_flush,
+ 1, /* Needs MI hacks. */
+};
+
+/* Prototypes for local functions */
+
+extern void _initialize_mi_out (void);
+static void field_separator (struct ui_out *uiout);
+static void mi_open (struct ui_out *uiout, const char *name,
+ enum ui_out_type type);
+static void mi_close (struct ui_out *uiout, enum ui_out_type type);
+
+static void out_field_fmt (struct ui_out *uiout, int fldno, char *fldname,
+ char *format,...);
+
+/* Mark beginning of a table */
+
+void
+mi_table_begin (struct ui_out *uiout,
+ int nr_cols,
+ int nr_rows,
+ const char *tblid)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ mi_open (uiout, tblid, ui_out_type_tuple);
+ if (data->mi_version == 0)
+ {
+ if (nr_rows == 0)
+ data->suppress_output = 1;
+ else
+ mi_open (uiout, "hdr", ui_out_type_list);
+ return;
+ }
+ mi_field_int (uiout, -1/*fldno*/, -1/*width*/, -1/*alin*/,
+ "nr_rows", nr_rows);
+ mi_field_int (uiout, -1/*fldno*/, -1/*width*/, -1/*alin*/,
+ "nr_cols", nr_cols);
+ mi_open (uiout, "hdr", ui_out_type_list);
+}
+
+/* Mark beginning of a table body */
+
+void
+mi_table_body (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ /* close the table header line if there were any headers */
+ mi_close (uiout, ui_out_type_list);
+ if (data->mi_version == 0)
+ return;
+ mi_open (uiout, "body", ui_out_type_list);
+}
+
+/* Mark end of a table */
+
+void
+mi_table_end (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ data->suppress_output = 0;
+ if (data->mi_version == 0)
+ {
+ mi_close (uiout, ui_out_type_tuple);
+ return;
+ }
+ mi_close (uiout, ui_out_type_list); /* body */
+ mi_close (uiout, ui_out_type_tuple);
+}
+
+/* Specify table header */
+
+void
+mi_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
+ const char *col_name,
+ const char *colhdr)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ if (data->mi_version == 0)
+ {
+ mi_field_string (uiout, 0, width, alignment, 0, colhdr);
+ return;
+ }
+ mi_open (uiout, NULL, ui_out_type_tuple);
+ mi_field_int (uiout, 0, 0, 0, "width", width);
+ mi_field_int (uiout, 0, 0, 0, "alignment", alignment);
+ mi_field_string (uiout, 0, 0, 0, "col_name", col_name);
+ mi_field_string (uiout, 0, width, alignment, "colhdr", colhdr);
+ mi_close (uiout, ui_out_type_tuple);
+}
+
+/* Mark beginning of a list */
+
+void
+mi_begin (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level,
+ const char *id)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ mi_open (uiout, id, type);
+}
+
+/* Mark end of a list */
+
+void
+mi_end (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ mi_close (uiout, type);
+}
+
+/* output an int field */
+
+void
+mi_field_int (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alignment, const char *fldname, int value)
+{
+ char buffer[20]; /* FIXME: how many chars long a %d can become? */
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+
+ sprintf (buffer, "%d", value);
+ mi_field_string (uiout, fldno, width, alignment, fldname, buffer);
+}
+
+/* used to ommit a field */
+
+void
+mi_field_skip (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alignment, const char *fldname)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ mi_field_string (uiout, fldno, width, alignment, fldname, "");
+}
+
+/* other specific mi_field_* end up here so alignment and field
+ separators are both handled by mi_field_string */
+
+void
+mi_field_string (struct ui_out *uiout,
+ int fldno,
+ int width,
+ enum ui_align align,
+ const char *fldname,
+ const char *string)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ field_separator (uiout);
+ if (fldname)
+ fprintf_unfiltered (data->buffer, "%s=", fldname);
+ fprintf_unfiltered (data->buffer, "\"");
+ if (string)
+ fputstr_unfiltered (string, '"', data->buffer);
+ fprintf_unfiltered (data->buffer, "\"");
+}
+
+/* This is the only field function that does not align */
+
+void
+mi_field_fmt (struct ui_out *uiout, int fldno,
+ int width, enum ui_align align,
+ const char *fldname,
+ const char *format,
+ va_list args)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ field_separator (uiout);
+ if (fldname)
+ fprintf_unfiltered (data->buffer, "%s=\"", fldname);
+ else
+ fputs_unfiltered ("\"", data->buffer);
+ vfprintf_unfiltered (data->buffer, format, args);
+ fputs_unfiltered ("\"", data->buffer);
+}
+
+void
+mi_spaces (struct ui_out *uiout, int numspaces)
+{
+}
+
+void
+mi_text (struct ui_out *uiout, const char *string)
+{
+}
+
+void
+mi_message (struct ui_out *uiout, int verbosity,
+ const char *format,
+ va_list args)
+{
+}
+
+void
+mi_wrap_hint (struct ui_out *uiout, char *identstring)
+{
+ wrap_here (identstring);
+}
+
+void
+mi_flush (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ gdb_flush (data->buffer);
+}
+
+/* local functions */
+
+/* Like mi_field_fmt, but takes a variable number of args
+ and makes a va_list and does not insert a separator */
+
+/* VARARGS */
+static void
+out_field_fmt (struct ui_out *uiout, int fldno, char *fldname,
+ char *format,...)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ va_list args;
+
+ field_separator (uiout);
+ if (fldname)
+ fprintf_unfiltered (data->buffer, "%s=\"", fldname);
+ else
+ fputs_unfiltered ("\"", data->buffer);
+
+ va_start (args, format);
+ vfprintf_unfiltered (data->buffer, format, args);
+
+ fputs_unfiltered ("\"", data->buffer);
+
+ va_end (args);
+}
+
+/* access to ui_out format private members */
+
+static void
+field_separator (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_field_separator)
+ data->suppress_field_separator = 0;
+ else
+ fputc_unfiltered (',', data->buffer);
+}
+
+static void
+mi_open (struct ui_out *uiout,
+ const char *name,
+ enum ui_out_type type)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ field_separator (uiout);
+ data->suppress_field_separator = 1;
+ if (name)
+ fprintf_unfiltered (data->buffer, "%s=", name);
+ switch (type)
+ {
+ case ui_out_type_tuple:
+ fputc_unfiltered ('{', data->buffer);
+ break;
+ case ui_out_type_list:
+ if (data->mi_version == 0)
+ fputc_unfiltered ('{', data->buffer);
+ else
+ fputc_unfiltered ('[', data->buffer);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "bad switch");
+ }
+}
+
+static void
+mi_close (struct ui_out *uiout,
+ enum ui_out_type type)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ switch (type)
+ {
+ case ui_out_type_tuple:
+ fputc_unfiltered ('}', data->buffer);
+ break;
+ case ui_out_type_list:
+ if (data->mi_version == 0)
+ fputc_unfiltered ('}', data->buffer);
+ else
+ fputc_unfiltered (']', data->buffer);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "bad switch");
+ }
+ data->suppress_field_separator = 0;
+}
+
+/* add a string to the buffer */
+
+void
+mi_out_buffered (struct ui_out *uiout, char *string)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ fprintf_unfiltered (data->buffer, "%s", string);
+}
+
+/* clear the buffer */
+
+void
+mi_out_rewind (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ ui_file_rewind (data->buffer);
+}
+
+/* dump the buffer onto the specified stream */
+
+static void
+do_write (void *data, const char *buffer, long length_buffer)
+{
+ ui_file_write (data, buffer, length_buffer);
+}
+
+void
+mi_out_put (struct ui_out *uiout,
+ struct ui_file *stream)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ ui_file_put (data->buffer, do_write, stream);
+ ui_file_rewind (data->buffer);
+}
+
+/* initalize private members at startup */
+
+struct ui_out *
+mi_out_new (int mi_version)
+{
+ int flags = 0;
+ struct ui_out_data *data = XMALLOC (struct ui_out_data);
+ data->suppress_field_separator = 0;
+ data->suppress_output = 0;
+ data->mi_version = mi_version;
+ /* FIXME: This code should be using a ``string_file'' and not the
+ TUI buffer hack. */
+ data->buffer = mem_fileopen ();
+ return ui_out_new (&mi_ui_out_impl, data, flags);
+}
+
+/* standard gdb initialization hook */
+void
+_initialize_mi_out (void)
+{
+ /* nothing happens here */
+}
diff --git a/gdb/mi/mi-out.h b/gdb/mi/mi-out.h
new file mode 100644
index 00000000000..1ae693f4761
--- /dev/null
+++ b/gdb/mi/mi-out.h
@@ -0,0 +1,33 @@
+/* MI Command Set - MI output generating routines for GDB.
+ Copyright 2000 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef MI_OUT_H
+#define MI_OUT_H 1
+
+struct ui_out;
+struct ui_file;
+
+extern struct ui_out *mi_out_new (int mi_version);
+extern void mi_out_put (struct ui_out *uiout, struct ui_file *stream);
+extern void mi_out_rewind (struct ui_out *uiout);
+extern void mi_out_buffered (struct ui_out *uiout, char *string);
+
+#endif /* MI_OUT_H */
diff --git a/gdb/mi/mi-parse.c b/gdb/mi/mi-parse.c
new file mode 100644
index 00000000000..caefd5936a5
--- /dev/null
+++ b/gdb/mi/mi-parse.c
@@ -0,0 +1,238 @@
+/* MI Command Set - MI parser.
+
+ Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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 "defs.h"
+#include "mi-cmds.h"
+#include "mi-parse.h"
+
+#include <ctype.h>
+#include "gdb_string.h"
+
+static void
+mi_parse_argv (char *args, struct mi_parse *parse)
+{
+ char *chp = args;
+ int argc = 0;
+ char **argv = xmalloc ((argc + 1) * sizeof (char *));
+ argv[argc] = NULL;
+ while (1)
+ {
+ char *arg;
+ /* skip leading white space */
+ while (isspace (*chp))
+ chp++;
+ /* Three possibilities: EOF, quoted string, or other text. */
+ switch (*chp)
+ {
+ case '\0':
+ parse->argv = argv;
+ parse->argc = argc;
+ return;
+ case '"':
+ {
+ /* A quoted string. */
+ int len;
+ char *start = chp + 1;
+ /* Determine the buffer size. */
+ chp = start;
+ len = 0;
+ while (*chp != '\0' && *chp != '"')
+ {
+ if (*chp == '\\')
+ {
+ chp++;
+ if (parse_escape (&chp) <= 0)
+ {
+ /* Do not allow split lines or "\000" */
+ freeargv (argv);
+ return;
+ }
+ }
+ else
+ chp++;
+ len++;
+ }
+ /* Insist on a closing quote. */
+ if (*chp != '"')
+ {
+ freeargv (argv);
+ return;
+ }
+ /* Insist on trailing white space. */
+ if (chp[1] != '\0' && !isspace (chp[1]))
+ {
+ freeargv (argv);
+ return;
+ }
+ /* create the buffer. */
+ arg = xmalloc ((len + 1) * sizeof (char));
+ /* And copy the characters in. */
+ chp = start;
+ len = 0;
+ while (*chp != '\0' && *chp != '"')
+ {
+ if (*chp == '\\')
+ {
+ chp++;
+ arg[len] = parse_escape (&chp);
+ }
+ else
+ arg[len] = *chp++;
+ len++;
+ }
+ arg[len] = '\0';
+ chp++; /* that closing quote. */
+ break;
+ }
+ default:
+ {
+ /* An unquoted string. Accumulate all non blank
+ characters into a buffer. */
+ int len;
+ char *start = chp;
+ while (*chp != '\0' && !isspace (*chp))
+ {
+ chp++;
+ }
+ len = chp - start;
+ arg = xmalloc ((len + 1) * sizeof (char));
+ strncpy (arg, start, len);
+ arg[len] = '\0';
+ break;
+ }
+ }
+ /* Append arg to argv. */
+ argv = xrealloc (argv, (argc + 2) * sizeof (char *));
+ argv[argc++] = arg;
+ argv[argc] = NULL;
+ }
+}
+
+
+void
+mi_parse_free (struct mi_parse *parse)
+{
+ if (parse == NULL)
+ return;
+ if (parse->command != NULL)
+ xfree (parse->command);
+ if (parse->token != NULL)
+ xfree (parse->token);
+ if (parse->args != NULL)
+ xfree (parse->args);
+ if (parse->argv != NULL)
+ freeargv (parse->argv);
+ xfree (parse);
+}
+
+
+struct mi_parse *
+mi_parse (char *cmd)
+{
+ char *chp;
+ struct mi_parse *parse = XMALLOC (struct mi_parse);
+ memset (parse, 0, sizeof (*parse));
+
+ /* Before starting, skip leading white space. */
+ while (isspace (*cmd))
+ cmd++;
+
+ /* Find/skip any token and then extract it. */
+ for (chp = cmd; *chp >= '0' && *chp <= '9'; chp++)
+ ;
+ parse->token = xmalloc ((chp - cmd + 1) * sizeof (char *));
+ memcpy (parse->token, cmd, (chp - cmd));
+ parse->token[chp - cmd] = '\0';
+
+ /* This wasn't a real MI command. Return it as a CLI_COMMAND. */
+ if (*chp != '-')
+ {
+ while (isspace (*chp))
+ chp++;
+ parse->command = xstrdup (chp);
+ parse->op = CLI_COMMAND;
+ return parse;
+ }
+
+ /* Extract the command. */
+ {
+ char *tmp = chp + 1; /* discard ``-'' */
+ for (; *chp && !isspace (*chp); chp++)
+ ;
+ parse->command = xmalloc ((chp - tmp + 1) * sizeof (char *));
+ memcpy (parse->command, tmp, chp - tmp);
+ parse->command[chp - tmp] = '\0';
+ }
+
+ /* Find the command in the MI table. */
+ parse->cmd = mi_lookup (parse->command);
+ if (parse->cmd == NULL)
+ {
+ /* FIXME: This should be a function call. */
+ fprintf_unfiltered
+ (raw_stdout,
+ "%s^error,msg=\"Undefined MI command: %s\"\n",
+ parse->token, parse->command);
+ mi_parse_free (parse);
+ return NULL;
+ }
+
+ /* Skip white space following the command. */
+ while (isspace (*chp))
+ chp++;
+
+ /* For new argv commands, attempt to return the parsed argument
+ list. */
+ if (parse->cmd->argv_func != NULL)
+ {
+ mi_parse_argv (chp, parse);
+ if (parse->argv == NULL)
+ {
+ /* FIXME: This should be a function call. */
+ fprintf_unfiltered
+ (raw_stdout,
+ "%s^error,msg=\"Problem parsing arguments: %s %s\"\n",
+ parse->token, parse->command, chp);
+ mi_parse_free (parse);
+ return NULL;
+ }
+ }
+
+ /* FIXME: DELETE THIS */
+ /* For CLI and old ARGS commands, also return the remainder of the
+ command line as a single string. */
+ if (parse->cmd->args_func != NULL
+ || parse->cmd->cli != NULL)
+ {
+ parse->args = xstrdup (chp);
+ }
+
+ /* Fully parsed. */
+ parse->op = MI_COMMAND;
+ return parse;
+}
+
+void
+_initialize_mi_parse (void)
+{
+}
diff --git a/gdb/mi/mi-parse.h b/gdb/mi/mi-parse.h
new file mode 100644
index 00000000000..ae9f181f90c
--- /dev/null
+++ b/gdb/mi/mi-parse.h
@@ -0,0 +1,55 @@
+/* MI Command Set - MI Command Parser.
+ Copyright 2000 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef MI_PARSE_H
+#define MI_PARSE_H
+
+/* MI parser */
+
+enum mi_command_type
+ {
+ MI_COMMAND, CLI_COMMAND
+ };
+
+struct mi_parse
+ {
+ enum mi_command_type op;
+ char *command;
+ char *token;
+ const struct mi_cmd *cmd;
+ char *args;
+ char **argv;
+ int argc;
+ };
+
+/* Attempts to parse CMD returning a ``struct mi_command''. If CMD is
+ invalid, an error mesage is reported (MI format) and NULL is
+ returned. For a CLI_COMMAND, COMMAND, TOKEN and OP are initialized.
+ For an MI_COMMAND COMMAND, TOKEN, ARGS and OP are
+ initialized. Un-initialized fields are zero. */
+
+extern struct mi_parse *mi_parse (char *cmd);
+
+/* Free a command returned by mi_parse_command. */
+
+extern void mi_parse_free (struct mi_parse *cmd);
+
+#endif
diff --git a/gdb/minimon.h b/gdb/minimon.h
new file mode 100644
index 00000000000..94fd774a375
--- /dev/null
+++ b/gdb/minimon.h
@@ -0,0 +1,601 @@
+/* Definitions and macros for support of AMD's remote debugger, MiniMON.
+ Copyright 1990, 1991 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. */
+
+/*
+ * Some basic types. FIXME, this should be done by declaring bitfield
+ * sizes in the structs. We can't portably depend on a "long int" being
+ * 32 bits, etc.
+ */
+typedef long int INT32; /* 32 bit integer */
+typedef unsigned long int UINT32; /* 32 bit integer (unsigned) */
+typedef unsigned long int ADDR32; /* 32 bit address */
+typedef unsigned long int INST32; /* 32 bit instruction */
+typedef long int BOOLEAN; /* Boolean value (32 bit) */
+typedef unsigned char BYTE; /* byte (8 bit) */
+typedef short int INT16; /* 16 bit integer */
+typedef unsigned short int UINT16; /* 16 bit integer (unsigned) */
+
+/****************************************************************************/
+/************************* Message Information ******************************/
+/****************************************************************************/
+
+/*
+ * Error codes
+ */
+
+/* General errors */
+#define EMUSAGE 1 /* Bad args / flags */
+#define EMFAIL 2 /* Unrecoverable error */
+#define EMBADADDR 3 /* Illegal address */
+#define EMBADREG 4 /* Illegal register */
+#define EMSYNTAX 5 /* Illegal command syntax */
+#define EMACCESS 6 /* Could not access memory */
+#define EMALLOC 7 /* Could not allocate memory */
+#define EMTARGET 8 /* Unknown target type */
+#define EMHINIT 9 /* Could not initialize host */
+#define EMCOMM 10 /* Could not open communication channel */
+
+/* Message errors */
+#define EMBADMSG 11 /* Unknown message type */
+#define EMMSG2BIG 12 /* Message to large for buffer */
+#define EMNOSEND 13 /* Could not send message */
+#define EMNORECV 14 /* Could not receive message */
+
+#define EMRESET 15 /* Could not RESET target */
+#define EMCONFIG 16 /* Could not get target CONFIG */
+#define EMSTATUS 17 /* Could not get target STATUS */
+#define EMREAD 18 /* Could not READ target memory */
+#define EMWRITE 19 /* Could not WRITE target memory */
+#define EMBKPTSET 20 /* Could not set breakpoint */
+#define EMBKPTRM 21 /* Could not remove breakpoint */
+#define EMBKPTSTAT 22 /* Could not get breakpoint status */
+#define EMBKPTNONE 23 /* All breakpoints in use */
+#define EMBKPTUSED 24 /* Breakpoints already in use */
+#define EMCOPY 25 /* Could not COPY target memory */
+#define EMFILL 26 /* Could not FILL target memory */
+#define EMINIT 27 /* Could not initialize target memory */
+#define EMGO 28 /* Could not start execution */
+#define EMSTEP 29 /* Could not single step */
+#define EMBREAK 30 /* Could not BREAK */
+#define EMHIF 31 /* Could not perform HIF service */
+#define EMCHANNEL0 32 /* Could not read CHANNEL0 */
+#define EMCHANNEL1 33 /* Could not write CHANNEL1 */
+
+/* COFF file loader errors */
+#define EMOPEN 34 /* Could not open COFF file */
+#define EMHDR 35 /* Could not read COFF header */
+#define EMMAGIC 36 /* Bad magic number */
+#define EMAOUT 37 /* Could not read COFF a.out header */
+#define EMSCNHDR 38 /* Could not read COFF section header */
+#define EMSCN 39 /* Could not read COFF section */
+#define EMCLOSE 40 /* Could not close COFF file */
+
+/* Log file errors */
+#define EMLOGOPEN 41 /* Could not open log file */
+#define EMLOGREAD 42 /* Could not read log file */
+#define EMLOGWRITE 43 /* Could not write to log file */
+#define EMLOGCLOSE 44 /* Could not close log file */
+
+/* Command file errors */
+#define EMCMDOPEN 45 /* Could not open command file */
+#define EMCMDREAD 46 /* Could not read command file */
+#define EMCMDWRITE 47 /* Could not write to command file */
+#define EMCMDCLOSE 48 /* Could not close comand file */
+
+#define EMTIMEOUT 49 /* Host timed out waiting for a message */
+#define EMCOMMTYPE 50 /* A '-t' flag must be specified */
+#define EMCOMMERR 51 /* Communication error */
+#define EMBAUD 52 /* Invalid baud rate specified */
+/*
+ * Memory Spaces
+ */
+#define LOCAL_REG 0 /* Local processor register */
+#define GLOBAL_REG 1 /* Global processor register */
+#define SPECIAL_REG 2 /* Special processor register */
+#define TLB_REG 3 /* Translation Lookaside Buffer */
+#define COPROC_REG 4 /* Coprocessor register */
+#define I_MEM 5 /* Instruction Memory */
+#define D_MEM 6 /* Data Memory */
+#define I_ROM 7 /* Instruction ROM */
+#define D_ROM 8 /* Data ROM */
+#define I_O 9 /* Input/Output */
+#define I_CACHE 10 /* Instruction Cache */
+#define D_CACHE 11 /* Data Cache */
+
+/* To supress warnings for zero length array definitions */
+#define DUMMY 1
+
+/*
+ ** Host to target definitions
+ */
+
+#define RESET 0
+#define CONFIG_REQ 1
+#define STATUS_REQ 2
+#define READ_REQ 3
+#define WRITE_REQ 4
+#define BKPT_SET 5
+#define BKPT_RM 6
+#define BKPT_STAT 7
+#define COPY 8
+#define FILL 9
+#define INIT 10
+#define GO 11
+#define STEP 12
+#define BREAK 13
+
+#define HIF_CALL_RTN 64
+#define CHANNEL0 65
+#define CHANNEL1_ACK 66
+
+
+/*
+ ** Target to host definitions
+ */
+
+#define RESET_ACK 32
+#define CONFIG 33
+#define STATUS 34
+#define READ_ACK 35
+#define WRITE_ACK 36
+#define BKPT_SET_ACK 37
+#define BKPT_RM_ACK 38
+#define BKPT_STAT_ACK 39
+#define COPY_ACK 40
+#define FILL_ACK 41
+#define INIT_ACK 42
+#define HALT 43
+
+#define ERROR 63
+
+#define HIF_CALL 96
+#define CHANNEL0_ACK 97
+#define CHANNEL1 98
+
+
+/* A "generic" message */
+struct generic_msg_t
+ {
+ INT32 code; /* generic */
+ INT32 length;
+ BYTE byte[DUMMY];
+ };
+
+
+/* A "generic" message (with an INT32 array) */
+struct generic_int32_msg_t
+ {
+ INT32 code; /* generic */
+ INT32 length;
+ INT32 int32[DUMMY];
+ };
+
+
+/*
+ ** Host to target messages
+ */
+
+struct reset_msg_t
+ {
+ INT32 code; /* 0 */
+ INT32 length;
+ };
+
+
+struct config_req_msg_t
+ {
+ INT32 code; /* 1 */
+ INT32 length;
+ };
+
+
+struct status_req_msg_t
+ {
+ INT32 code; /* 2 */
+ INT32 length;
+ };
+
+
+struct read_req_msg_t
+ {
+ INT32 code; /* 3 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 address;
+ INT32 byte_count;
+ };
+
+
+struct write_req_msg_t
+ {
+ INT32 code; /* 4 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 address;
+ INT32 byte_count;
+ BYTE data[DUMMY];
+ };
+
+
+struct write_r_msg_t
+ {
+ INT32 code; /* 4 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 address;
+ INT32 byte_count;
+ INT32 data[DUMMY];
+ };
+
+
+struct bkpt_set_msg_t
+ {
+ INT32 code; /* 5 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 bkpt_addr;
+ INT32 pass_count;
+ INT32 bkpt_type;
+ };
+
+
+struct bkpt_rm_msg_t
+ {
+ INT32 code; /* 6 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 bkpt_addr;
+ };
+
+
+struct bkpt_stat_msg_t
+ {
+ INT32 code; /* 7 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 bkpt_addr;
+ };
+
+
+struct copy_msg_t
+ {
+ INT32 code; /* 8 */
+ INT32 length;
+ INT32 source_space;
+ ADDR32 source_addr;
+ INT32 dest_space;
+ ADDR32 dest_addr;
+ INT32 byte_count;
+ };
+
+
+struct fill_msg_t
+ {
+ INT32 code; /* 9 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 start_addr;
+ INT32 fill_count;
+ INT32 byte_count;
+ BYTE fill_data[DUMMY];
+ };
+
+
+struct init_msg_t
+ {
+ INT32 code; /* 10 */
+ INT32 length;
+ ADDR32 text_start;
+ ADDR32 text_end;
+ ADDR32 data_start;
+ ADDR32 data_end;
+ ADDR32 entry_point;
+ INT32 mem_stack_size;
+ INT32 reg_stack_size;
+ ADDR32 arg_start;
+ INT32 os_control;
+ };
+
+
+struct go_msg_t
+ {
+ INT32 code; /* 11 */
+ INT32 length;
+ };
+
+
+struct step_msg_t
+ {
+ INT32 code; /* 12 */
+ INT32 length;
+ INT32 count;
+ };
+
+
+struct break_msg_t
+ {
+ INT32 code; /* 13 */
+ INT32 length;
+ };
+
+
+struct hif_call_rtn_msg_t
+ {
+ INT32 code; /* 64 */
+ INT32 length;
+ INT32 service_number;
+ INT32 gr121;
+ INT32 gr96;
+ INT32 gr97;
+ };
+
+
+struct channel0_msg_t
+ {
+ INT32 code; /* 65 */
+ INT32 length;
+ BYTE data;
+ };
+
+
+struct channel1_ack_msg_t
+ {
+ INT32 code; /* 66 */
+ INT32 length;
+ };
+
+
+/*
+ ** Target to host messages
+ */
+
+
+struct reset_ack_msg_t
+ {
+ INT32 code; /* 32 */
+ INT32 length;
+ };
+
+
+struct config_msg_t
+ {
+ INT32 code; /* 33 */
+ INT32 length;
+ INT32 processor_id;
+ INT32 version;
+ ADDR32 I_mem_start;
+ INT32 I_mem_size;
+ ADDR32 D_mem_start;
+ INT32 D_mem_size;
+ ADDR32 ROM_start;
+ INT32 ROM_size;
+ INT32 max_msg_size;
+ INT32 max_bkpts;
+ INT32 coprocessor;
+ INT32 reserved;
+ };
+
+
+struct status_msg_t
+ {
+ INT32 code; /* 34 */
+ INT32 length;
+ INT32 msgs_sent;
+ INT32 msgs_received;
+ INT32 errors;
+ INT32 bkpts_hit;
+ INT32 bkpts_free;
+ INT32 traps;
+ INT32 fills;
+ INT32 spills;
+ INT32 cycles;
+ INT32 reserved;
+ };
+
+
+struct read_ack_msg_t
+ {
+ INT32 code; /* 35 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 address;
+ INT32 byte_count;
+ BYTE data[DUMMY];
+ };
+
+struct read_r_ack_msg_t
+ {
+ INT32 code; /* 35 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 address;
+ INT32 byte_count;
+ INT32 data[DUMMY];
+ };
+
+
+struct write_ack_msg_t
+ {
+ INT32 code; /* 36 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 address;
+ INT32 byte_count;
+ };
+
+
+struct bkpt_set_ack_msg_t
+ {
+ INT32 code; /* 37 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 address;
+ INT32 pass_count;
+ INT32 bkpt_type;
+ };
+
+
+struct bkpt_rm_ack_msg_t
+ {
+ INT32 code; /* 38 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 address;
+ };
+
+
+struct bkpt_stat_ack_msg_t
+ {
+ INT32 code; /* 39 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 address;
+ INT32 pass_count;
+ INT32 bkpt_type;
+ };
+
+
+struct copy_ack_msg_t
+ {
+ INT32 code; /* 40 */
+ INT32 length;
+ INT32 source_space;
+ ADDR32 source_addr;
+ INT32 dest_space;
+ ADDR32 dest_addr;
+ INT32 byte_count;
+ };
+
+
+struct fill_ack_msg_t
+ {
+ INT32 code; /* 41 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 start_addr;
+ INT32 fill_count;
+ INT32 byte_count;
+ };
+
+
+struct init_ack_msg_t
+ {
+ INT32 code; /* 42 */
+ INT32 length;
+ };
+
+
+struct halt_msg_t
+ {
+ INT32 code; /* 43 */
+ INT32 length;
+ INT32 memory_space;
+ ADDR32 pc0;
+ ADDR32 pc1;
+ INT32 trap_number;
+ };
+
+
+struct error_msg_t
+ {
+ INT32 code; /* 63 */
+ INT32 length;
+ INT32 error_code;
+ INT32 memory_space;
+ ADDR32 address;
+ };
+
+
+struct hif_call_msg_t
+ {
+ INT32 code; /* 96 */
+ INT32 length;
+ INT32 service_number;
+ INT32 lr2;
+ INT32 lr3;
+ INT32 lr4;
+ };
+
+
+struct channel0_ack_msg_t
+ {
+ INT32 code; /* 97 */
+ INT32 length;
+ };
+
+
+struct channel1_msg_t
+ {
+ INT32 code; /* 98 */
+ INT32 length;
+ BYTE data[DUMMY];
+ };
+
+
+
+/*
+ ** Union all of the message types together
+ */
+
+union msg_t
+ {
+ struct generic_msg_t generic_msg;
+ struct generic_int32_msg_t generic_int32_msg;
+
+ struct reset_msg_t reset_msg;
+ struct config_req_msg_t config_req_msg;
+ struct status_req_msg_t status_req_msg;
+ struct read_req_msg_t read_req_msg;
+ struct write_req_msg_t write_req_msg;
+ struct write_r_msg_t write_r_msg;
+ struct bkpt_set_msg_t bkpt_set_msg;
+ struct bkpt_rm_msg_t bkpt_rm_msg;
+ struct bkpt_stat_msg_t bkpt_stat_msg;
+ struct copy_msg_t copy_msg;
+ struct fill_msg_t fill_msg;
+ struct init_msg_t init_msg;
+ struct go_msg_t go_msg;
+ struct step_msg_t step_msg;
+ struct break_msg_t break_msg;
+
+ struct hif_call_rtn_msg_t hif_call_rtn_msg;
+ struct channel0_msg_t channel0_msg;
+ struct channel1_ack_msg_t channel1_ack_msg;
+
+ struct reset_ack_msg_t reset_ack_msg;
+ struct config_msg_t config_msg;
+ struct status_msg_t status_msg;
+ struct read_ack_msg_t read_ack_msg;
+ struct read_r_ack_msg_t read_r_ack_msg;
+ struct write_ack_msg_t write_ack_msg;
+ struct bkpt_set_ack_msg_t bkpt_set_ack_msg;
+ struct bkpt_rm_ack_msg_t bkpt_rm_ack_msg;
+ struct bkpt_stat_ack_msg_t bkpt_stat_ack_msg;
+ struct copy_ack_msg_t copy_ack_msg;
+ struct fill_ack_msg_t fill_ack_msg;
+ struct init_ack_msg_t init_ack_msg;
+ struct halt_msg_t halt_msg;
+
+ struct error_msg_t error_msg;
+
+ struct hif_call_msg_t hif_call_msg;
+ struct channel0_ack_msg_t channel0_ack_msg;
+ struct channel1_msg_t channel1_msg;
+ };
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
new file mode 100644
index 00000000000..4fa1d911f08
--- /dev/null
+++ b/gdb/minsyms.c
@@ -0,0 +1,987 @@
+/* GDB routines for manipulating the minimal symbol tables.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support, using pieces from other GDB modules.
+
+ 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. */
+
+
+/* This file contains support routines for creating, manipulating, and
+ destroying minimal symbol tables.
+
+ Minimal symbol tables are used to hold some very basic information about
+ all defined global symbols (text, data, bss, abs, etc). The only two
+ required pieces of information are the symbol's name and the address
+ associated with that symbol.
+
+ In many cases, even if a file was compiled with no special options for
+ debugging at all, as long as was not stripped it will contain sufficient
+ information to build useful minimal symbol tables using this structure.
+
+ Even when a file contains enough debugging information to build a full
+ symbol table, these minimal symbols are still useful for quickly mapping
+ between names and addresses, and vice versa. They are also sometimes used
+ to figure out what full symbol table entries need to be read in. */
+
+
+#include "defs.h"
+#include <ctype.h>
+#include "gdb_string.h"
+#include "symtab.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "demangle.h"
+#include "value.h"
+#include "cp-abi.h"
+
+/* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE.
+ At the end, copy them all into one newly allocated location on an objfile's
+ symbol obstack. */
+
+#define BUNCH_SIZE 127
+
+struct msym_bunch
+ {
+ struct msym_bunch *next;
+ struct minimal_symbol contents[BUNCH_SIZE];
+ };
+
+/* Bunch currently being filled up.
+ The next field points to chain of filled bunches. */
+
+static struct msym_bunch *msym_bunch;
+
+/* Number of slots filled in current bunch. */
+
+static int msym_bunch_index;
+
+/* Total number of minimal symbols recorded so far for the objfile. */
+
+static int msym_count;
+
+/* Compute a hash code based using the same criteria as `strcmp_iw'. */
+
+unsigned int
+msymbol_hash_iw (const char *string)
+{
+ unsigned int hash = 0;
+ while (*string && *string != '(')
+ {
+ while (isspace (*string))
+ ++string;
+ if (*string && *string != '(')
+ {
+ hash = hash * 67 + *string - 113;
+ ++string;
+ }
+ }
+ return hash % MINIMAL_SYMBOL_HASH_SIZE;
+}
+
+/* Compute a hash code for a string. */
+
+unsigned int
+msymbol_hash (const char *string)
+{
+ unsigned int hash = 0;
+ for (; *string; ++string)
+ hash = hash * 67 + *string - 113;
+ return hash % MINIMAL_SYMBOL_HASH_SIZE;
+}
+
+/* Add the minimal symbol SYM to an objfile's minsym hash table, TABLE. */
+void
+add_minsym_to_hash_table (struct minimal_symbol *sym,
+ struct minimal_symbol **table)
+{
+ if (sym->hash_next == NULL)
+ {
+ unsigned int hash = msymbol_hash (SYMBOL_NAME (sym));
+ sym->hash_next = table[hash];
+ table[hash] = sym;
+ }
+}
+
+/* Add the minimal symbol SYM to an objfile's minsym demangled hash table,
+ TABLE. */
+static void
+add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
+ struct minimal_symbol **table)
+{
+ if (sym->demangled_hash_next == NULL)
+ {
+ unsigned int hash = msymbol_hash_iw (SYMBOL_DEMANGLED_NAME (sym));
+ sym->demangled_hash_next = table[hash];
+ table[hash] = sym;
+ }
+}
+
+
+/* Look through all the current minimal symbol tables and find the
+ first minimal symbol that matches NAME. If OBJF is non-NULL, limit
+ the search to that objfile. If SFILE is non-NULL, limit the search
+ to that source file. Returns a pointer to the minimal symbol that
+ matches, or NULL if no match is found.
+
+ Note: One instance where there may be duplicate minimal symbols with
+ the same name is when the symbol tables for a shared library and the
+ symbol tables for an executable contain global symbols with the same
+ names (the dynamic linker deals with the duplication). */
+
+struct minimal_symbol *
+lookup_minimal_symbol (register const char *name, const char *sfile,
+ struct objfile *objf)
+{
+ struct objfile *objfile;
+ struct minimal_symbol *msymbol;
+ struct minimal_symbol *found_symbol = NULL;
+ struct minimal_symbol *found_file_symbol = NULL;
+ struct minimal_symbol *trampoline_symbol = NULL;
+
+ unsigned int hash = msymbol_hash (name);
+ unsigned int dem_hash = msymbol_hash_iw (name);
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ if (sfile != NULL)
+ {
+ char *p = strrchr (sfile, '/');
+ if (p != NULL)
+ sfile = p + 1;
+ }
+#endif
+
+ for (objfile = object_files;
+ objfile != NULL && found_symbol == NULL;
+ objfile = objfile->next)
+ {
+ if (objf == NULL || objf == objfile)
+ {
+ /* Do two passes: the first over the ordinary hash table,
+ and the second over the demangled hash table. */
+ int pass;
+
+ for (pass = 1; pass <= 2 && found_symbol == NULL; pass++)
+ {
+ /* Select hash list according to pass. */
+ if (pass == 1)
+ msymbol = objfile->msymbol_hash[hash];
+ else
+ msymbol = objfile->msymbol_demangled_hash[dem_hash];
+
+ while (msymbol != NULL && found_symbol == NULL)
+ {
+ if (SYMBOL_MATCHES_NAME (msymbol, name))
+ {
+ switch (MSYMBOL_TYPE (msymbol))
+ {
+ case mst_file_text:
+ case mst_file_data:
+ case mst_file_bss:
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ if (sfile == NULL || STREQ (msymbol->filename, sfile))
+ found_file_symbol = msymbol;
+#else
+ /* We have neither the ability nor the need to
+ deal with the SFILE parameter. If we find
+ more than one symbol, just return the latest
+ one (the user can't expect useful behavior in
+ that case). */
+ found_file_symbol = msymbol;
+#endif
+ break;
+
+ case mst_solib_trampoline:
+
+ /* If a trampoline symbol is found, we prefer to
+ keep looking for the *real* symbol. If the
+ actual symbol is not found, then we'll use the
+ trampoline entry. */
+ if (trampoline_symbol == NULL)
+ trampoline_symbol = msymbol;
+ break;
+
+ case mst_unknown:
+ default:
+ found_symbol = msymbol;
+ break;
+ }
+ }
+
+ /* Find the next symbol on the hash chain. */
+ if (pass == 1)
+ msymbol = msymbol->hash_next;
+ else
+ msymbol = msymbol->demangled_hash_next;
+ }
+ }
+ }
+ }
+ /* External symbols are best. */
+ if (found_symbol)
+ return found_symbol;
+
+ /* File-local symbols are next best. */
+ if (found_file_symbol)
+ return found_file_symbol;
+
+ /* Symbols for shared library trampolines are next best. */
+ if (trampoline_symbol)
+ return trampoline_symbol;
+
+ return NULL;
+}
+
+/* Look through all the current minimal symbol tables and find the
+ first minimal symbol that matches NAME and of text type.
+ If OBJF is non-NULL, limit
+ the search to that objfile. If SFILE is non-NULL, limit the search
+ to that source file. Returns a pointer to the minimal symbol that
+ matches, or NULL if no match is found.
+ */
+
+struct minimal_symbol *
+lookup_minimal_symbol_text (register const char *name, const char *sfile,
+ struct objfile *objf)
+{
+ struct objfile *objfile;
+ struct minimal_symbol *msymbol;
+ struct minimal_symbol *found_symbol = NULL;
+ struct minimal_symbol *found_file_symbol = NULL;
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ if (sfile != NULL)
+ {
+ char *p = strrchr (sfile, '/');
+ if (p != NULL)
+ sfile = p + 1;
+ }
+#endif
+
+ for (objfile = object_files;
+ objfile != NULL && found_symbol == NULL;
+ objfile = objfile->next)
+ {
+ if (objf == NULL || objf == objfile)
+ {
+ for (msymbol = objfile->msymbols;
+ msymbol != NULL && SYMBOL_NAME (msymbol) != NULL &&
+ found_symbol == NULL;
+ msymbol++)
+ {
+ if (SYMBOL_MATCHES_NAME (msymbol, name) &&
+ (MSYMBOL_TYPE (msymbol) == mst_text ||
+ MSYMBOL_TYPE (msymbol) == mst_file_text))
+ {
+ switch (MSYMBOL_TYPE (msymbol))
+ {
+ case mst_file_text:
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ if (sfile == NULL || STREQ (msymbol->filename, sfile))
+ found_file_symbol = msymbol;
+#else
+ /* We have neither the ability nor the need to
+ deal with the SFILE parameter. If we find
+ more than one symbol, just return the latest
+ one (the user can't expect useful behavior in
+ that case). */
+ found_file_symbol = msymbol;
+#endif
+ break;
+ default:
+ found_symbol = msymbol;
+ break;
+ }
+ }
+ }
+ }
+ }
+ /* External symbols are best. */
+ if (found_symbol)
+ return found_symbol;
+
+ /* File-local symbols are next best. */
+ if (found_file_symbol)
+ return found_file_symbol;
+
+ return NULL;
+}
+
+/* Look through all the current minimal symbol tables and find the
+ first minimal symbol that matches NAME and of solib trampoline type.
+ If OBJF is non-NULL, limit
+ the search to that objfile. If SFILE is non-NULL, limit the search
+ to that source file. Returns a pointer to the minimal symbol that
+ matches, or NULL if no match is found.
+ */
+
+struct minimal_symbol *
+lookup_minimal_symbol_solib_trampoline (register const char *name,
+ const char *sfile, struct objfile *objf)
+{
+ struct objfile *objfile;
+ struct minimal_symbol *msymbol;
+ struct minimal_symbol *found_symbol = NULL;
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ if (sfile != NULL)
+ {
+ char *p = strrchr (sfile, '/');
+ if (p != NULL)
+ sfile = p + 1;
+ }
+#endif
+
+ for (objfile = object_files;
+ objfile != NULL && found_symbol == NULL;
+ objfile = objfile->next)
+ {
+ if (objf == NULL || objf == objfile)
+ {
+ for (msymbol = objfile->msymbols;
+ msymbol != NULL && SYMBOL_NAME (msymbol) != NULL &&
+ found_symbol == NULL;
+ msymbol++)
+ {
+ if (SYMBOL_MATCHES_NAME (msymbol, name) &&
+ MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
+ return msymbol;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+/* Search through the minimal symbol table for each objfile and find
+ the symbol whose address is the largest address that is still less
+ than or equal to PC, and matches SECTION (if non-null). Returns a
+ pointer to the minimal symbol if such a symbol is found, or NULL if
+ PC is not in a suitable range. Note that we need to look through
+ ALL the minimal symbol tables before deciding on the symbol that
+ comes closest to the specified PC. This is because objfiles can
+ overlap, for example objfile A has .text at 0x100 and .data at
+ 0x40000 and objfile B has .text at 0x234 and .data at 0x40048. */
+
+struct minimal_symbol *
+lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
+{
+ int lo;
+ int hi;
+ int new;
+ struct objfile *objfile;
+ struct minimal_symbol *msymbol;
+ struct minimal_symbol *best_symbol = NULL;
+
+ /* pc has to be in a known section. This ensures that anything beyond
+ the end of the last segment doesn't appear to be part of the last
+ function in the last segment. */
+ if (find_pc_section (pc) == NULL)
+ return NULL;
+
+ for (objfile = object_files;
+ objfile != NULL;
+ objfile = objfile->next)
+ {
+ /* If this objfile has a minimal symbol table, go search it using
+ a binary search. Note that a minimal symbol table always consists
+ of at least two symbols, a "real" symbol and the terminating
+ "null symbol". If there are no real symbols, then there is no
+ minimal symbol table at all. */
+
+ if ((msymbol = objfile->msymbols) != NULL)
+ {
+ lo = 0;
+ hi = objfile->minimal_symbol_count - 1;
+
+ /* This code assumes that the minimal symbols are sorted by
+ ascending address values. If the pc value is greater than or
+ equal to the first symbol's address, then some symbol in this
+ minimal symbol table is a suitable candidate for being the
+ "best" symbol. This includes the last real symbol, for cases
+ where the pc value is larger than any address in this vector.
+
+ By iterating until the address associated with the current
+ hi index (the endpoint of the test interval) is less than
+ or equal to the desired pc value, we accomplish two things:
+ (1) the case where the pc value is larger than any minimal
+ symbol address is trivially solved, (2) the address associated
+ with the hi index is always the one we want when the interation
+ terminates. In essence, we are iterating the test interval
+ down until the pc value is pushed out of it from the high end.
+
+ Warning: this code is trickier than it would appear at first. */
+
+ /* Should also require that pc is <= end of objfile. FIXME! */
+ if (pc >= SYMBOL_VALUE_ADDRESS (&msymbol[lo]))
+ {
+ while (SYMBOL_VALUE_ADDRESS (&msymbol[hi]) > pc)
+ {
+ /* pc is still strictly less than highest address */
+ /* Note "new" will always be >= lo */
+ new = (lo + hi) / 2;
+ if ((SYMBOL_VALUE_ADDRESS (&msymbol[new]) >= pc) ||
+ (lo == new))
+ {
+ hi = new;
+ }
+ else
+ {
+ lo = new;
+ }
+ }
+
+ /* If we have multiple symbols at the same address, we want
+ hi to point to the last one. That way we can find the
+ right symbol if it has an index greater than hi. */
+ while (hi < objfile->minimal_symbol_count - 1
+ && (SYMBOL_VALUE_ADDRESS (&msymbol[hi])
+ == SYMBOL_VALUE_ADDRESS (&msymbol[hi + 1])))
+ hi++;
+
+ /* The minimal symbol indexed by hi now is the best one in this
+ objfile's minimal symbol table. See if it is the best one
+ overall. */
+
+ /* Skip any absolute symbols. This is apparently what adb
+ and dbx do, and is needed for the CM-5. There are two
+ known possible problems: (1) on ELF, apparently end, edata,
+ etc. are absolute. Not sure ignoring them here is a big
+ deal, but if we want to use them, the fix would go in
+ elfread.c. (2) I think shared library entry points on the
+ NeXT are absolute. If we want special handling for this
+ it probably should be triggered by a special
+ mst_abs_or_lib or some such. */
+ while (hi >= 0
+ && msymbol[hi].type == mst_abs)
+ --hi;
+
+ /* If "section" specified, skip any symbol from wrong section */
+ /* This is the new code that distinguishes it from the old function */
+ if (section)
+ while (hi >= 0
+ /* Some types of debug info, such as COFF,
+ don't fill the bfd_section member, so don't
+ throw away symbols on those platforms. */
+ && SYMBOL_BFD_SECTION (&msymbol[hi]) != NULL
+ && SYMBOL_BFD_SECTION (&msymbol[hi]) != section)
+ --hi;
+
+ if (hi >= 0
+ && ((best_symbol == NULL) ||
+ (SYMBOL_VALUE_ADDRESS (best_symbol) <
+ SYMBOL_VALUE_ADDRESS (&msymbol[hi]))))
+ {
+ best_symbol = &msymbol[hi];
+ }
+ }
+ }
+ }
+ return (best_symbol);
+}
+
+/* Backward compatibility: search through the minimal symbol table
+ for a matching PC (no section given) */
+
+struct minimal_symbol *
+lookup_minimal_symbol_by_pc (CORE_ADDR pc)
+{
+ return lookup_minimal_symbol_by_pc_section (pc, find_pc_mapped_section (pc));
+}
+
+
+/* Return leading symbol character for a BFD. If BFD is NULL,
+ return the leading symbol character from the main objfile. */
+
+static int get_symbol_leading_char (bfd *);
+
+static int
+get_symbol_leading_char (bfd *abfd)
+{
+ if (abfd != NULL)
+ return bfd_get_symbol_leading_char (abfd);
+ if (symfile_objfile != NULL && symfile_objfile->obfd != NULL)
+ return bfd_get_symbol_leading_char (symfile_objfile->obfd);
+ return 0;
+}
+
+/* Prepare to start collecting minimal symbols. Note that presetting
+ msym_bunch_index to BUNCH_SIZE causes the first call to save a minimal
+ symbol to allocate the memory for the first bunch. */
+
+void
+init_minimal_symbol_collection (void)
+{
+ msym_count = 0;
+ msym_bunch = NULL;
+ msym_bunch_index = BUNCH_SIZE;
+}
+
+void
+prim_record_minimal_symbol (const char *name, CORE_ADDR address,
+ enum minimal_symbol_type ms_type,
+ struct objfile *objfile)
+{
+ int section;
+
+ switch (ms_type)
+ {
+ case mst_text:
+ case mst_file_text:
+ case mst_solib_trampoline:
+ section = SECT_OFF_TEXT (objfile);
+ break;
+ case mst_data:
+ case mst_file_data:
+ section = SECT_OFF_DATA (objfile);
+ break;
+ case mst_bss:
+ case mst_file_bss:
+ section = SECT_OFF_BSS (objfile);
+ break;
+ default:
+ section = -1;
+ }
+
+ prim_record_minimal_symbol_and_info (name, address, ms_type,
+ NULL, section, NULL, objfile);
+}
+
+/* Record a minimal symbol in the msym bunches. Returns the symbol
+ newly created. */
+
+struct minimal_symbol *
+prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address,
+ enum minimal_symbol_type ms_type,
+ char *info, int section,
+ asection *bfd_section,
+ struct objfile *objfile)
+{
+ register struct msym_bunch *new;
+ register struct minimal_symbol *msymbol;
+
+ if (ms_type == mst_file_text)
+ {
+ /* Don't put gcc_compiled, __gnu_compiled_cplus, and friends into
+ the minimal symbols, because if there is also another symbol
+ at the same address (e.g. the first function of the file),
+ lookup_minimal_symbol_by_pc would have no way of getting the
+ right one. */
+ if (name[0] == 'g'
+ && (strcmp (name, GCC_COMPILED_FLAG_SYMBOL) == 0
+ || strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) == 0))
+ return (NULL);
+
+ {
+ const char *tempstring = name;
+ if (tempstring[0] == get_symbol_leading_char (objfile->obfd))
+ ++tempstring;
+ if (STREQN (tempstring, "__gnu_compiled", 14))
+ return (NULL);
+ }
+ }
+
+ if (msym_bunch_index == BUNCH_SIZE)
+ {
+ new = (struct msym_bunch *) xmalloc (sizeof (struct msym_bunch));
+ msym_bunch_index = 0;
+ new->next = msym_bunch;
+ msym_bunch = new;
+ }
+ msymbol = &msym_bunch->contents[msym_bunch_index];
+ SYMBOL_NAME (msymbol) = obsavestring ((char *) name, strlen (name),
+ &objfile->symbol_obstack);
+ SYMBOL_INIT_LANGUAGE_SPECIFIC (msymbol, language_unknown);
+ SYMBOL_VALUE_ADDRESS (msymbol) = address;
+ SYMBOL_SECTION (msymbol) = section;
+ SYMBOL_BFD_SECTION (msymbol) = bfd_section;
+
+ MSYMBOL_TYPE (msymbol) = ms_type;
+ /* FIXME: This info, if it remains, needs its own field. */
+ MSYMBOL_INFO (msymbol) = info; /* FIXME! */
+
+ /* The hash pointers must be cleared! If they're not,
+ add_minsym_to_hash_table will NOT add this msymbol to the hash table. */
+ msymbol->hash_next = NULL;
+ msymbol->demangled_hash_next = NULL;
+
+ msym_bunch_index++;
+ msym_count++;
+ OBJSTAT (objfile, n_minsyms++);
+ return msymbol;
+}
+
+/* Compare two minimal symbols by address and return a signed result based
+ on unsigned comparisons, so that we sort into unsigned numeric order.
+ Within groups with the same address, sort by name. */
+
+static int
+compare_minimal_symbols (const void *fn1p, const void *fn2p)
+{
+ register const struct minimal_symbol *fn1;
+ register const struct minimal_symbol *fn2;
+
+ fn1 = (const struct minimal_symbol *) fn1p;
+ fn2 = (const struct minimal_symbol *) fn2p;
+
+ if (SYMBOL_VALUE_ADDRESS (fn1) < SYMBOL_VALUE_ADDRESS (fn2))
+ {
+ return (-1); /* addr 1 is less than addr 2 */
+ }
+ else if (SYMBOL_VALUE_ADDRESS (fn1) > SYMBOL_VALUE_ADDRESS (fn2))
+ {
+ return (1); /* addr 1 is greater than addr 2 */
+ }
+ else
+ /* addrs are equal: sort by name */
+ {
+ char *name1 = SYMBOL_NAME (fn1);
+ char *name2 = SYMBOL_NAME (fn2);
+
+ if (name1 && name2) /* both have names */
+ return strcmp (name1, name2);
+ else if (name2)
+ return 1; /* fn1 has no name, so it is "less" */
+ else if (name1) /* fn2 has no name, so it is "less" */
+ return -1;
+ else
+ return (0); /* neither has a name, so they're equal. */
+ }
+}
+
+/* Discard the currently collected minimal symbols, if any. If we wish
+ to save them for later use, we must have already copied them somewhere
+ else before calling this function.
+
+ FIXME: We could allocate the minimal symbol bunches on their own
+ obstack and then simply blow the obstack away when we are done with
+ it. Is it worth the extra trouble though? */
+
+static void
+do_discard_minimal_symbols_cleanup (void *arg)
+{
+ register struct msym_bunch *next;
+
+ while (msym_bunch != NULL)
+ {
+ next = msym_bunch->next;
+ xfree (msym_bunch);
+ msym_bunch = next;
+ }
+}
+
+struct cleanup *
+make_cleanup_discard_minimal_symbols (void)
+{
+ return make_cleanup (do_discard_minimal_symbols_cleanup, 0);
+}
+
+
+
+/* Compact duplicate entries out of a minimal symbol table by walking
+ through the table and compacting out entries with duplicate addresses
+ and matching names. Return the number of entries remaining.
+
+ On entry, the table resides between msymbol[0] and msymbol[mcount].
+ On exit, it resides between msymbol[0] and msymbol[result_count].
+
+ When files contain multiple sources of symbol information, it is
+ possible for the minimal symbol table to contain many duplicate entries.
+ As an example, SVR4 systems use ELF formatted object files, which
+ usually contain at least two different types of symbol tables (a
+ standard ELF one and a smaller dynamic linking table), as well as
+ DWARF debugging information for files compiled with -g.
+
+ Without compacting, the minimal symbol table for gdb itself contains
+ over a 1000 duplicates, about a third of the total table size. Aside
+ from the potential trap of not noticing that two successive entries
+ identify the same location, this duplication impacts the time required
+ to linearly scan the table, which is done in a number of places. So we
+ just do one linear scan here and toss out the duplicates.
+
+ Note that we are not concerned here about recovering the space that
+ is potentially freed up, because the strings themselves are allocated
+ on the symbol_obstack, and will get automatically freed when the symbol
+ table is freed. The caller can free up the unused minimal symbols at
+ the end of the compacted region if their allocation strategy allows it.
+
+ Also note we only go up to the next to last entry within the loop
+ and then copy the last entry explicitly after the loop terminates.
+
+ Since the different sources of information for each symbol may
+ have different levels of "completeness", we may have duplicates
+ that have one entry with type "mst_unknown" and the other with a
+ known type. So if the one we are leaving alone has type mst_unknown,
+ overwrite its type with the type from the one we are compacting out. */
+
+static int
+compact_minimal_symbols (struct minimal_symbol *msymbol, int mcount,
+ struct objfile *objfile)
+{
+ struct minimal_symbol *copyfrom;
+ struct minimal_symbol *copyto;
+
+ if (mcount > 0)
+ {
+ copyfrom = copyto = msymbol;
+ while (copyfrom < msymbol + mcount - 1)
+ {
+ if (SYMBOL_VALUE_ADDRESS (copyfrom) ==
+ SYMBOL_VALUE_ADDRESS ((copyfrom + 1)) &&
+ (STREQ (SYMBOL_NAME (copyfrom), SYMBOL_NAME ((copyfrom + 1)))))
+ {
+ if (MSYMBOL_TYPE ((copyfrom + 1)) == mst_unknown)
+ {
+ MSYMBOL_TYPE ((copyfrom + 1)) = MSYMBOL_TYPE (copyfrom);
+ }
+ copyfrom++;
+ }
+ else
+ *copyto++ = *copyfrom++;
+ }
+ *copyto++ = *copyfrom++;
+ mcount = copyto - msymbol;
+ }
+ return (mcount);
+}
+
+/* Build (or rebuild) the minimal symbol hash tables. This is necessary
+ after compacting or sorting the table since the entries move around
+ thus causing the internal minimal_symbol pointers to become jumbled. */
+
+static void
+build_minimal_symbol_hash_tables (struct objfile *objfile)
+{
+ int i;
+ struct minimal_symbol *msym;
+
+ /* Clear the hash tables. */
+ for (i = 0; i < MINIMAL_SYMBOL_HASH_SIZE; i++)
+ {
+ objfile->msymbol_hash[i] = 0;
+ objfile->msymbol_demangled_hash[i] = 0;
+ }
+
+ /* Now, (re)insert the actual entries. */
+ for (i = objfile->minimal_symbol_count, msym = objfile->msymbols;
+ i > 0;
+ i--, msym++)
+ {
+ msym->hash_next = 0;
+ add_minsym_to_hash_table (msym, objfile->msymbol_hash);
+
+ msym->demangled_hash_next = 0;
+ if (SYMBOL_DEMANGLED_NAME (msym) != NULL)
+ add_minsym_to_demangled_hash_table (msym,
+ objfile->msymbol_demangled_hash);
+ }
+}
+
+/* Add the minimal symbols in the existing bunches to the objfile's official
+ minimal symbol table. In most cases there is no minimal symbol table yet
+ for this objfile, and the existing bunches are used to create one. Once
+ in a while (for shared libraries for example), we add symbols (e.g. common
+ symbols) to an existing objfile.
+
+ Because of the way minimal symbols are collected, we generally have no way
+ of knowing what source language applies to any particular minimal symbol.
+ Specifically, we have no way of knowing if the minimal symbol comes from a
+ C++ compilation unit or not. So for the sake of supporting cached
+ demangled C++ names, we have no choice but to try and demangle each new one
+ that comes in. If the demangling succeeds, then we assume it is a C++
+ symbol and set the symbol's language and demangled name fields
+ appropriately. Note that in order to avoid unnecessary demanglings, and
+ allocating obstack space that subsequently can't be freed for the demangled
+ names, we mark all newly added symbols with language_auto. After
+ compaction of the minimal symbols, we go back and scan the entire minimal
+ symbol table looking for these new symbols. For each new symbol we attempt
+ to demangle it, and if successful, record it as a language_cplus symbol
+ and cache the demangled form on the symbol obstack. Symbols which don't
+ demangle are marked as language_unknown symbols, which inhibits future
+ attempts to demangle them if we later add more minimal symbols. */
+
+void
+install_minimal_symbols (struct objfile *objfile)
+{
+ register int bindex;
+ register int mcount;
+ register struct msym_bunch *bunch;
+ register struct minimal_symbol *msymbols;
+ int alloc_count;
+ register char leading_char;
+
+ if (msym_count > 0)
+ {
+ /* Allocate enough space in the obstack, into which we will gather the
+ bunches of new and existing minimal symbols, sort them, and then
+ compact out the duplicate entries. Once we have a final table,
+ we will give back the excess space. */
+
+ alloc_count = msym_count + objfile->minimal_symbol_count + 1;
+ obstack_blank (&objfile->symbol_obstack,
+ alloc_count * sizeof (struct minimal_symbol));
+ msymbols = (struct minimal_symbol *)
+ obstack_base (&objfile->symbol_obstack);
+
+ /* Copy in the existing minimal symbols, if there are any. */
+
+ if (objfile->minimal_symbol_count)
+ memcpy ((char *) msymbols, (char *) objfile->msymbols,
+ objfile->minimal_symbol_count * sizeof (struct minimal_symbol));
+
+ /* Walk through the list of minimal symbol bunches, adding each symbol
+ to the new contiguous array of symbols. Note that we start with the
+ current, possibly partially filled bunch (thus we use the current
+ msym_bunch_index for the first bunch we copy over), and thereafter
+ each bunch is full. */
+
+ mcount = objfile->minimal_symbol_count;
+ leading_char = get_symbol_leading_char (objfile->obfd);
+
+ for (bunch = msym_bunch; bunch != NULL; bunch = bunch->next)
+ {
+ for (bindex = 0; bindex < msym_bunch_index; bindex++, mcount++)
+ {
+ msymbols[mcount] = bunch->contents[bindex];
+ SYMBOL_LANGUAGE (&msymbols[mcount]) = language_auto;
+ if (SYMBOL_NAME (&msymbols[mcount])[0] == leading_char)
+ {
+ SYMBOL_NAME (&msymbols[mcount])++;
+ }
+ }
+ msym_bunch_index = BUNCH_SIZE;
+ }
+
+ /* Sort the minimal symbols by address. */
+
+ qsort (msymbols, mcount, sizeof (struct minimal_symbol),
+ compare_minimal_symbols);
+
+ /* Compact out any duplicates, and free up whatever space we are
+ no longer using. */
+
+ mcount = compact_minimal_symbols (msymbols, mcount, objfile);
+
+ obstack_blank (&objfile->symbol_obstack,
+ (mcount + 1 - alloc_count) * sizeof (struct minimal_symbol));
+ msymbols = (struct minimal_symbol *)
+ obstack_finish (&objfile->symbol_obstack);
+
+ /* We also terminate the minimal symbol table with a "null symbol",
+ which is *not* included in the size of the table. This makes it
+ easier to find the end of the table when we are handed a pointer
+ to some symbol in the middle of it. Zero out the fields in the
+ "null symbol" allocated at the end of the array. Note that the
+ symbol count does *not* include this null symbol, which is why it
+ is indexed by mcount and not mcount-1. */
+
+ SYMBOL_NAME (&msymbols[mcount]) = NULL;
+ SYMBOL_VALUE_ADDRESS (&msymbols[mcount]) = 0;
+ MSYMBOL_INFO (&msymbols[mcount]) = NULL;
+ MSYMBOL_TYPE (&msymbols[mcount]) = mst_unknown;
+ SYMBOL_INIT_LANGUAGE_SPECIFIC (&msymbols[mcount], language_unknown);
+
+ /* Attach the minimal symbol table to the specified objfile.
+ The strings themselves are also located in the symbol_obstack
+ of this objfile. */
+
+ objfile->minimal_symbol_count = mcount;
+ objfile->msymbols = msymbols;
+
+ /* Try to guess the appropriate C++ ABI by looking at the names
+ of the minimal symbols in the table. */
+ {
+ int i;
+
+ for (i = 0; i < mcount; i++)
+ {
+ const char *name = SYMBOL_NAME (&objfile->msymbols[i]);
+ if (name[0] == '_' && name[1] == 'Z')
+ {
+ switch_to_cp_abi ("gnu-v3");
+ break;
+ }
+ }
+ }
+
+ /* Now walk through all the minimal symbols, selecting the newly added
+ ones and attempting to cache their C++ demangled names. */
+ for (; mcount-- > 0; msymbols++)
+ SYMBOL_INIT_DEMANGLED_NAME (msymbols, &objfile->symbol_obstack);
+
+ /* Now build the hash tables; we can't do this incrementally
+ at an earlier point since we weren't finished with the obstack
+ yet. (And if the msymbol obstack gets moved, all the internal
+ pointers to other msymbols need to be adjusted.) */
+ build_minimal_symbol_hash_tables (objfile);
+ }
+}
+
+/* Sort all the minimal symbols in OBJFILE. */
+
+void
+msymbols_sort (struct objfile *objfile)
+{
+ qsort (objfile->msymbols, objfile->minimal_symbol_count,
+ sizeof (struct minimal_symbol), compare_minimal_symbols);
+ build_minimal_symbol_hash_tables (objfile);
+}
+
+/* Check if PC is in a shared library trampoline code stub.
+ Return minimal symbol for the trampoline entry or NULL if PC is not
+ in a trampoline code stub. */
+
+struct minimal_symbol *
+lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc)
+{
+ struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
+
+ if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
+ return msymbol;
+ return NULL;
+}
+
+/* If PC is in a shared library trampoline code stub, return the
+ address of the `real' function belonging to the stub.
+ Return 0 if PC is not in a trampoline code stub or if the real
+ function is not found in the minimal symbol table.
+
+ We may fail to find the right function if a function with the
+ same name is defined in more than one shared library, but this
+ is considered bad programming style. We could return 0 if we find
+ a duplicate function in case this matters someday. */
+
+CORE_ADDR
+find_solib_trampoline_target (CORE_ADDR pc)
+{
+ struct objfile *objfile;
+ struct minimal_symbol *msymbol;
+ struct minimal_symbol *tsymbol = lookup_solib_trampoline_symbol_by_pc (pc);
+
+ if (tsymbol != NULL)
+ {
+ ALL_MSYMBOLS (objfile, msymbol)
+ {
+ if (MSYMBOL_TYPE (msymbol) == mst_text
+ && STREQ (SYMBOL_NAME (msymbol), SYMBOL_NAME (tsymbol)))
+ return SYMBOL_VALUE_ADDRESS (msymbol);
+ }
+ }
+ return 0;
+}
diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c
new file mode 100644
index 00000000000..cec16d3175f
--- /dev/null
+++ b/gdb/mips-linux-nat.c
@@ -0,0 +1,58 @@
+/* Native-dependent code for GNU/Linux on MIPS processors.
+ Copyright 2001 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 "defs.h"
+
+/* Pseudo registers can not be read. ptrace does not provide a way to
+ read (or set) PS_REGNUM, and there's no point in reading or setting
+ ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via
+ ptrace(). */
+
+int
+mips_linux_cannot_fetch_register (int regno)
+{
+ if (regno >= FP_REGNUM)
+ return 1;
+ else if (regno == PS_REGNUM)
+ return 1;
+ else if (regno == ZERO_REGNUM)
+ return 1;
+ else
+ return 0;
+}
+
+int
+mips_linux_cannot_store_register (int regno)
+{
+ if (regno >= FP_REGNUM)
+ return 1;
+ else if (regno == PS_REGNUM)
+ return 1;
+ else if (regno == ZERO_REGNUM)
+ return 1;
+ else if (regno == BADVADDR_REGNUM)
+ return 1;
+ else if (regno == CAUSE_REGNUM)
+ return 1;
+ else if (regno == FCRIR_REGNUM)
+ return 1;
+ else
+ return 0;
+}
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
new file mode 100644
index 00000000000..3706e2d8673
--- /dev/null
+++ b/gdb/mips-linux-tdep.c
@@ -0,0 +1,344 @@
+/* Target-dependent code for GNU/Linux on MIPS processors.
+ Copyright 2001 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "solib-svr4.h"
+
+/* Copied from <asm/elf.h>. */
+#define ELF_NGREG 45
+#define ELF_NFPREG 33
+
+typedef unsigned char elf_greg_t[4];
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef unsigned char elf_fpreg_t[8];
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+/* 0 - 31 are integer registers, 32 - 63 are fp registers. */
+#define FPR_BASE 32
+#define PC 64
+#define CAUSE 65
+#define BADVADDR 66
+#define MMHI 67
+#define MMLO 68
+#define FPC_CSR 69
+#define FPC_EIR 70
+
+#define EF_REG0 6
+#define EF_REG31 37
+#define EF_LO 38
+#define EF_HI 39
+#define EF_CP0_EPC 40
+#define EF_CP0_BADVADDR 41
+#define EF_CP0_STATUS 42
+#define EF_CP0_CAUSE 43
+
+#define EF_SIZE 180
+
+/* Figure out where the longjmp will land.
+ We expect the first arg to be a pointer to the jmp_buf structure from
+ which we extract the pc (JB_PC) that we will land at. The pc is copied
+ into PC. This routine returns 1 on success. */
+
+int
+mips_linux_get_longjmp_target (CORE_ADDR *pc)
+{
+ CORE_ADDR jb_addr;
+ char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
+
+ jb_addr = read_register (A0_REGNUM);
+
+ if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ return 1;
+}
+
+/* Unpack an elf_gregset_t into GDB's register cache. */
+
+void
+supply_gregset (elf_gregset_t *gregsetp)
+{
+ int regi;
+ elf_greg_t *regp = *gregsetp;
+ static char zerobuf[MAX_REGISTER_RAW_SIZE] = {0};
+
+ for (regi = EF_REG0; regi <= EF_REG31; regi++)
+ supply_register ((regi - EF_REG0), (char *)(regp + regi));
+
+ supply_register (LO_REGNUM, (char *)(regp + EF_LO));
+ supply_register (HI_REGNUM, (char *)(regp + EF_HI));
+
+ supply_register (PC_REGNUM, (char *)(regp + EF_CP0_EPC));
+ supply_register (BADVADDR_REGNUM, (char *)(regp + EF_CP0_BADVADDR));
+ supply_register (PS_REGNUM, (char *)(regp + EF_CP0_STATUS));
+ supply_register (CAUSE_REGNUM, (char *)(regp + EF_CP0_CAUSE));
+
+ /* Fill inaccessible registers with zero. */
+ supply_register (FP_REGNUM, zerobuf);
+ supply_register (UNUSED_REGNUM, zerobuf);
+ for (regi = FIRST_EMBED_REGNUM; regi < LAST_EMBED_REGNUM; regi++)
+ supply_register (regi, zerobuf);
+}
+
+/* Pack our registers (or one register) into an elf_gregset_t. */
+
+void
+fill_gregset (elf_gregset_t *gregsetp, int regno)
+{
+ int regaddr, regi;
+ elf_greg_t *regp = *gregsetp;
+ void *src, *dst;
+
+ if (regno == -1)
+ {
+ memset (regp, 0, sizeof (elf_gregset_t));
+ for (regi = 0; regi < 32; regi++)
+ fill_gregset (gregsetp, regi);
+ fill_gregset (gregsetp, LO_REGNUM);
+ fill_gregset (gregsetp, HI_REGNUM);
+ fill_gregset (gregsetp, PC_REGNUM);
+ fill_gregset (gregsetp, BADVADDR_REGNUM);
+ fill_gregset (gregsetp, PS_REGNUM);
+ fill_gregset (gregsetp, CAUSE_REGNUM);
+
+ return;
+ }
+
+ if (regno < 32)
+ {
+ src = &registers[REGISTER_BYTE (regno)];
+ dst = regp + regno + EF_REG0;
+ memcpy (dst, src, sizeof (elf_greg_t));
+ return;
+ }
+
+ regaddr = -1;
+ switch (regno)
+ {
+ case LO_REGNUM:
+ regaddr = EF_LO;
+ break;
+ case HI_REGNUM:
+ regaddr = EF_HI;
+ break;
+ case PC_REGNUM:
+ regaddr = EF_CP0_EPC;
+ break;
+ case BADVADDR_REGNUM:
+ regaddr = EF_CP0_BADVADDR;
+ break;
+ case PS_REGNUM:
+ regaddr = EF_CP0_STATUS;
+ break;
+ case CAUSE_REGNUM:
+ regaddr = EF_CP0_CAUSE;
+ break;
+ }
+
+ if (regaddr != -1)
+ {
+ src = &registers[REGISTER_BYTE (regno)];
+ dst = regp + regaddr;
+ memcpy (dst, src, sizeof (elf_greg_t));
+ }
+}
+
+/* Likewise, unpack an elf_fpregset_t. */
+
+void
+supply_fpregset (elf_fpregset_t *fpregsetp)
+{
+ register int regi;
+ static char zerobuf[MAX_REGISTER_RAW_SIZE] = {0};
+
+ for (regi = 0; regi < 32; regi++)
+ supply_register (FP0_REGNUM + regi,
+ (char *)(*fpregsetp + regi));
+
+ supply_register (FCRCS_REGNUM, (char *)(*fpregsetp + 32));
+
+ /* FIXME: how can we supply FCRIR_REGNUM? The ABI doesn't tell us. */
+ supply_register (FCRIR_REGNUM, zerobuf);
+}
+
+/* Likewise, pack one or all floating point registers into an
+ elf_fpregset_t. */
+
+void
+fill_fpregset (elf_fpregset_t *fpregsetp, int regno)
+{
+ char *from, *to;
+
+ if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
+ {
+ from = (char *) &registers[REGISTER_BYTE (regno)];
+ to = (char *) (*fpregsetp + regno - FP0_REGNUM);
+ memcpy (to, from, REGISTER_RAW_SIZE (regno - FP0_REGNUM));
+ }
+ else if (regno == FCRCS_REGNUM)
+ {
+ from = (char *) &registers[REGISTER_BYTE (regno)];
+ to = (char *) (*fpregsetp + 32);
+ memcpy (to, from, REGISTER_RAW_SIZE (regno));
+ }
+ else if (regno == -1)
+ {
+ int regi;
+
+ for (regi = 0; regi < 32; regi++)
+ fill_fpregset (fpregsetp, FP0_REGNUM + regi);
+ fill_fpregset(fpregsetp, FCRCS_REGNUM);
+ }
+}
+
+/* Map gdb internal register number to ptrace ``address''.
+ These ``addresses'' are normally defined in <asm/ptrace.h>. */
+
+CORE_ADDR
+register_addr (int regno, CORE_ADDR blockend)
+{
+ int regaddr;
+
+ if (regno < 0 || regno >= NUM_REGS)
+ error ("Bogon register number %d.", regno);
+
+ if (regno < 32)
+ regaddr = regno;
+ else if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
+ regaddr = FPR_BASE + (regno - FP0_REGNUM);
+ else if (regno == PC_REGNUM)
+ regaddr = PC;
+ else if (regno == CAUSE_REGNUM)
+ regaddr = CAUSE;
+ else if (regno == BADVADDR_REGNUM)
+ regaddr = BADVADDR;
+ else if (regno == LO_REGNUM)
+ regaddr = MMLO;
+ else if (regno == HI_REGNUM)
+ regaddr = MMHI;
+ else if (regno == FCRCS_REGNUM)
+ regaddr = FPC_CSR;
+ else if (regno == FCRIR_REGNUM)
+ regaddr = FPC_EIR;
+ else
+ error ("Unknowable register number %d.", regno);
+
+ return regaddr;
+}
+
+/* Use a local version of this function to get the correct types for
+ regsets, until multi-arch core support is ready. */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+ elf_gregset_t gregset;
+ elf_fpregset_t fpregset;
+
+ if (which == 0)
+ {
+ if (core_reg_size != sizeof (gregset))
+ {
+ warning ("wrong size gregset struct in core file");
+ }
+ else
+ {
+ memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset));
+ supply_gregset (&gregset);
+ }
+ }
+ else if (which == 2)
+ {
+ if (core_reg_size != sizeof (fpregset))
+ {
+ warning ("wrong size fpregset struct in core file");
+ }
+ else
+ {
+ memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset));
+ supply_fpregset (&fpregset);
+ }
+ }
+}
+
+/* Register that we are able to handle ELF file formats using standard
+ procfs "regset" structures. */
+
+static struct core_fns regset_core_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+/* Fetch (and possibly build) an appropriate link_map_offsets
+ structure for native GNU/Linux MIPS targets using the struct offsets
+ defined in link.h (but without actual reference to that file).
+
+ This makes it possible to access GNU/Linux MIPS shared libraries from a
+ GDB that was built on a different host platform (for cross debugging). */
+
+struct link_map_offsets *
+mips_linux_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_debug_size = 8; /* The actual size is 20 bytes, but
+ this is all we need. */
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 4;
+
+ lmo.link_map_size = 20;
+
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 4;
+
+ lmo.l_name_offset = 4;
+ lmo.l_name_size = 4;
+
+ lmo.l_next_offset = 12;
+ lmo.l_next_size = 4;
+
+ lmo.l_prev_offset = 16;
+ lmo.l_prev_size = 4;
+ }
+
+ return lmp;
+}
+
+void
+_initialize_mips_linux_tdep (void)
+{
+ add_core_fns (&regset_core_fns);
+}
diff --git a/gdb/mips-nat.c b/gdb/mips-nat.c
new file mode 100644
index 00000000000..545c74171c3
--- /dev/null
+++ b/gdb/mips-nat.c
@@ -0,0 +1,246 @@
+/* Low level DECstation interface to ptrace, for GDB when running native.
+ Copyright 1988, 1989, 1991, 1992, 1993, 1995, 1996, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+ Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
+ and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
+
+ 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 "defs.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#undef JB_S0
+#undef JB_S1
+#undef JB_S2
+#undef JB_S3
+#undef JB_S4
+#undef JB_S5
+#undef JB_S6
+#undef JB_S7
+#undef JB_SP
+#undef JB_S8
+#undef JB_PC
+#undef JB_SR
+#undef NJBREGS
+#include <setjmp.h> /* For JB_XXX. */
+
+/* Size of elements in jmpbuf */
+
+#define JB_ELEMENT_SIZE 4
+
+/* Map gdb internal register number to ptrace ``address''.
+ These ``addresses'' are defined in DECstation <sys/ptrace.h> */
+
+#define REGISTER_PTRACE_ADDR(regno) \
+ (regno < 32 ? GPR_BASE + regno \
+ : regno == PC_REGNUM ? PC \
+ : regno == CAUSE_REGNUM ? CAUSE \
+ : regno == HI_REGNUM ? MMHI \
+ : regno == LO_REGNUM ? MMLO \
+ : regno == FCRCS_REGNUM ? FPC_CSR \
+ : regno == FCRIR_REGNUM ? FPC_EIR \
+ : regno >= FP0_REGNUM ? FPR_BASE + (regno - FP0_REGNUM) \
+ : 0)
+
+static char zerobuf[MAX_REGISTER_RAW_SIZE] =
+{0};
+
+static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
+
+/* Get all registers from the inferior */
+
+void
+fetch_inferior_registers (int regno)
+{
+ register unsigned int regaddr;
+ char buf[MAX_REGISTER_RAW_SIZE];
+ register int i;
+
+ registers_fetched ();
+
+ for (regno = 1; regno < NUM_REGS; regno++)
+ {
+ regaddr = REGISTER_PTRACE_ADDR (regno);
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+ {
+ *(int *) &buf[i] = ptrace (PT_READ_U, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) regaddr, 0);
+ regaddr += sizeof (int);
+ }
+ supply_register (regno, buf);
+ }
+
+ supply_register (ZERO_REGNUM, zerobuf);
+ /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */
+ supply_register (FP_REGNUM, zerobuf);
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ register unsigned int regaddr;
+ char buf[80];
+
+ if (regno > 0)
+ {
+ if (regno == ZERO_REGNUM || regno == PS_REGNUM
+ || regno == BADVADDR_REGNUM || regno == CAUSE_REGNUM
+ || regno == FCRIR_REGNUM || regno == FP_REGNUM
+ || (regno >= FIRST_EMBED_REGNUM && regno <= LAST_EMBED_REGNUM))
+ return;
+ regaddr = REGISTER_PTRACE_ADDR (regno);
+ errno = 0;
+ ptrace (PT_WRITE_U, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr,
+ read_register (regno));
+ if (errno != 0)
+ {
+ sprintf (buf, "writing register number %d", regno);
+ perror_with_name (buf);
+ }
+ }
+ else
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ store_inferior_registers (regno);
+ }
+}
+
+
+/* Figure out where the longjmp will land.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
+ This routine returns true on success. */
+
+int
+get_longjmp_target (CORE_ADDR *pc)
+{
+ CORE_ADDR jb_addr;
+ char *buf;
+
+ buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ jb_addr = read_register (A0_REGNUM);
+
+ if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ return 1;
+}
+
+/* Extract the register values out of the core file and store
+ them where `read_register' will find them.
+
+ CORE_REG_SECT points to the register values themselves, read into memory.
+ CORE_REG_SIZE is the size of that area.
+ WHICH says which set of registers we are handling (0 = int, 2 = float
+ on machines where they are discontiguous).
+ REG_ADDR is the offset from u.u_ar0 to the register values relative to
+ core_reg_sect. This is used with old-fashioned core files to
+ locate the registers in a large upage-plus-stack ".reg" section.
+ Original upage address X is at location core_reg_sect+x+reg_addr.
+ */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR reg_addr)
+{
+ register int regno;
+ register unsigned int addr;
+ int bad_reg = -1;
+ register reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */
+
+ /* If u.u_ar0 was an absolute address in the core file, relativize it now,
+ so we can use it as an offset into core_reg_sect. When we're done,
+ "register 0" will be at core_reg_sect+reg_ptr, and we can use
+ register_addr to offset to the other registers. If this is a modern
+ core file without a upage, reg_ptr will be zero and this is all a big
+ NOP. */
+ if (reg_ptr > core_reg_size)
+#ifdef KERNEL_U_ADDR
+ reg_ptr -= KERNEL_U_ADDR;
+#else
+ error ("Old mips core file can't be processed on this machine.");
+#endif
+
+ for (regno = 0; regno < NUM_REGS; regno++)
+ {
+ addr = register_addr (regno, reg_ptr);
+ if (addr >= core_reg_size)
+ {
+ if (bad_reg < 0)
+ bad_reg = regno;
+ }
+ else
+ {
+ supply_register (regno, core_reg_sect + addr);
+ }
+ }
+ if (bad_reg >= 0)
+ {
+ error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
+ }
+ supply_register (ZERO_REGNUM, zerobuf);
+ /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */
+ supply_register (FP_REGNUM, zerobuf);
+}
+
+/* Return the address in the core dump or inferior of register REGNO.
+ BLOCKEND is the address of the end of the user structure. */
+
+CORE_ADDR
+register_addr (int regno, CORE_ADDR blockend)
+{
+ CORE_ADDR addr;
+
+ if (regno < 0 || regno >= NUM_REGS)
+ error ("Invalid register number %d.", regno);
+
+ REGISTER_U_ADDR (addr, blockend, regno);
+
+ return addr;
+}
+
+
+/* Register that we are able to handle mips core file formats.
+ FIXME: is this really bfd_target_unknown_flavour? */
+
+static struct core_fns mips_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_mips (void)
+{
+ add_core_fns (&mips_core_fns);
+}
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
new file mode 100644
index 00000000000..67409f6d18a
--- /dev/null
+++ b/gdb/mips-tdep.c
@@ -0,0 +1,5002 @@
+/* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
+
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
+ and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
+
+ 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 "defs.h"
+#include "gdb_string.h"
+#include "frame.h"
+#include "inferior.h"
+#include "symtab.h"
+#include "value.h"
+#include "gdbcmd.h"
+#include "language.h"
+#include "gdbcore.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbtypes.h"
+#include "target.h"
+#include "arch-utils.h"
+#include "regcache.h"
+#include "osabi.h"
+
+#include "opcode/mips.h"
+#include "elf/mips.h"
+#include "elf-bfd.h"
+#include "symcat.h"
+
+/* A useful bit in the CP0 status register (PS_REGNUM). */
+/* This bit is set if we are emulating 32-bit FPRs on a 64-bit chip. */
+#define ST0_FR (1 << 26)
+
+/* The sizes of floating point registers. */
+
+enum
+{
+ MIPS_FPU_SINGLE_REGSIZE = 4,
+ MIPS_FPU_DOUBLE_REGSIZE = 8
+};
+
+/* All the possible MIPS ABIs. */
+
+enum mips_abi
+ {
+ MIPS_ABI_UNKNOWN,
+ MIPS_ABI_N32,
+ MIPS_ABI_O32,
+ MIPS_ABI_O64,
+ MIPS_ABI_EABI32,
+ MIPS_ABI_EABI64
+ };
+
+struct frame_extra_info
+ {
+ mips_extra_func_info_t proc_desc;
+ int num_args;
+ };
+
+/* Various MIPS ISA options (related to stack analysis) can be
+ overridden dynamically. Establish an enum/array for managing
+ them. */
+
+static const char size_auto[] = "auto";
+static const char size_32[] = "32";
+static const char size_64[] = "64";
+
+static const char *size_enums[] = {
+ size_auto,
+ size_32,
+ size_64,
+ 0
+};
+
+/* Some MIPS boards don't support floating point while others only
+ support single-precision floating-point operations. See also
+ FP_REGISTER_DOUBLE. */
+
+enum mips_fpu_type
+ {
+ MIPS_FPU_DOUBLE, /* Full double precision floating point. */
+ MIPS_FPU_SINGLE, /* Single precision floating point (R4650). */
+ MIPS_FPU_NONE /* No floating point. */
+ };
+
+#ifndef MIPS_DEFAULT_FPU_TYPE
+#define MIPS_DEFAULT_FPU_TYPE MIPS_FPU_DOUBLE
+#endif
+static int mips_fpu_type_auto = 1;
+static enum mips_fpu_type mips_fpu_type = MIPS_DEFAULT_FPU_TYPE;
+#define MIPS_FPU_TYPE mips_fpu_type
+
+/* Do not use "TARGET_IS_MIPS64" to test the size of floating point registers */
+#ifndef FP_REGISTER_DOUBLE
+#define FP_REGISTER_DOUBLE (REGISTER_VIRTUAL_SIZE(FP0_REGNUM) == 8)
+#endif
+
+static int mips_debug = 0;
+
+/* MIPS specific per-architecture information */
+struct gdbarch_tdep
+ {
+ /* from the elf header */
+ int elf_flags;
+
+ /* mips options */
+ enum mips_abi mips_abi;
+ const char *mips_abi_string;
+ enum mips_fpu_type mips_fpu_type;
+ int mips_last_arg_regnum;
+ int mips_last_fp_arg_regnum;
+ int mips_default_saved_regsize;
+ int mips_fp_register_double;
+ int mips_regs_have_home_p;
+ int mips_default_stack_argsize;
+ int gdb_target_is_mips64;
+ int default_mask_address_p;
+
+ enum gdb_osabi osabi;
+ };
+
+#if GDB_MULTI_ARCH
+#undef MIPS_EABI
+#define MIPS_EABI (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI32 \
+ || gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI64)
+#endif
+
+#if GDB_MULTI_ARCH
+#undef MIPS_LAST_FP_ARG_REGNUM
+#define MIPS_LAST_FP_ARG_REGNUM (gdbarch_tdep (current_gdbarch)->mips_last_fp_arg_regnum)
+#endif
+
+#if GDB_MULTI_ARCH
+#undef MIPS_LAST_ARG_REGNUM
+#define MIPS_LAST_ARG_REGNUM (gdbarch_tdep (current_gdbarch)->mips_last_arg_regnum)
+#endif
+
+#if GDB_MULTI_ARCH
+#undef MIPS_FPU_TYPE
+#define MIPS_FPU_TYPE (gdbarch_tdep (current_gdbarch)->mips_fpu_type)
+#endif
+
+/* Return the currently configured (or set) saved register size. */
+
+#if GDB_MULTI_ARCH
+#undef MIPS_DEFAULT_SAVED_REGSIZE
+#define MIPS_DEFAULT_SAVED_REGSIZE (gdbarch_tdep (current_gdbarch)->mips_default_saved_regsize)
+#elif !defined (MIPS_DEFAULT_SAVED_REGSIZE)
+#define MIPS_DEFAULT_SAVED_REGSIZE MIPS_REGSIZE
+#endif
+
+static const char *mips_saved_regsize_string = size_auto;
+
+#define MIPS_SAVED_REGSIZE (mips_saved_regsize())
+
+static unsigned int
+mips_saved_regsize (void)
+{
+ if (mips_saved_regsize_string == size_auto)
+ return MIPS_DEFAULT_SAVED_REGSIZE;
+ else if (mips_saved_regsize_string == size_64)
+ return 8;
+ else /* if (mips_saved_regsize_string == size_32) */
+ return 4;
+}
+
+/* Determine if a MIPS3 or later cpu is operating in MIPS{1,2} FPU
+ compatiblity mode. A return value of 1 means that we have
+ physical 64-bit registers, but should treat them as 32-bit registers. */
+
+static int
+mips2_fp_compat (void)
+{
+ /* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not
+ meaningful. */
+ if (REGISTER_RAW_SIZE (FP0_REGNUM) == 4)
+ return 0;
+
+#if 0
+ /* FIXME drow 2002-03-10: This is disabled until we can do it consistently,
+ in all the places we deal with FP registers. PR gdb/413. */
+ /* Otherwise check the FR bit in the status register - it controls
+ the FP compatiblity mode. If it is clear we are in compatibility
+ mode. */
+ if ((read_register (PS_REGNUM) & ST0_FR) == 0)
+ return 1;
+#endif
+
+ return 0;
+}
+
+/* Indicate that the ABI makes use of double-precision registers
+ provided by the FPU (rather than combining pairs of registers to
+ form double-precision values). Do not use "TARGET_IS_MIPS64" to
+ determine if the ABI is using double-precision registers. See also
+ MIPS_FPU_TYPE. */
+#if GDB_MULTI_ARCH
+#undef FP_REGISTER_DOUBLE
+#define FP_REGISTER_DOUBLE (gdbarch_tdep (current_gdbarch)->mips_fp_register_double)
+#endif
+
+/* Does the caller allocate a ``home'' for each register used in the
+ function call? The N32 ABI and MIPS_EABI do not, the others do. */
+
+#if GDB_MULTI_ARCH
+#undef MIPS_REGS_HAVE_HOME_P
+#define MIPS_REGS_HAVE_HOME_P (gdbarch_tdep (current_gdbarch)->mips_regs_have_home_p)
+#elif !defined (MIPS_REGS_HAVE_HOME_P)
+#define MIPS_REGS_HAVE_HOME_P (!MIPS_EABI)
+#endif
+
+/* The amount of space reserved on the stack for registers. This is
+ different to MIPS_SAVED_REGSIZE as it determines the alignment of
+ data allocated after the registers have run out. */
+
+#if GDB_MULTI_ARCH
+#undef MIPS_DEFAULT_STACK_ARGSIZE
+#define MIPS_DEFAULT_STACK_ARGSIZE (gdbarch_tdep (current_gdbarch)->mips_default_stack_argsize)
+#elif !defined (MIPS_DEFAULT_STACK_ARGSIZE)
+#define MIPS_DEFAULT_STACK_ARGSIZE (MIPS_DEFAULT_SAVED_REGSIZE)
+#endif
+
+#define MIPS_STACK_ARGSIZE (mips_stack_argsize ())
+
+static const char *mips_stack_argsize_string = size_auto;
+
+static unsigned int
+mips_stack_argsize (void)
+{
+ if (mips_stack_argsize_string == size_auto)
+ return MIPS_DEFAULT_STACK_ARGSIZE;
+ else if (mips_stack_argsize_string == size_64)
+ return 8;
+ else /* if (mips_stack_argsize_string == size_32) */
+ return 4;
+}
+
+#if GDB_MULTI_ARCH
+#undef GDB_TARGET_IS_MIPS64
+#define GDB_TARGET_IS_MIPS64 (gdbarch_tdep (current_gdbarch)->gdb_target_is_mips64 + 0)
+#endif
+
+#if GDB_MULTI_ARCH
+#undef MIPS_DEFAULT_MASK_ADDRESS_P
+#define MIPS_DEFAULT_MASK_ADDRESS_P (gdbarch_tdep (current_gdbarch)->default_mask_address_p)
+#elif !defined (MIPS_DEFAULT_MASK_ADDRESS_P)
+#define MIPS_DEFAULT_MASK_ADDRESS_P (0)
+#endif
+
+#define VM_MIN_ADDRESS (CORE_ADDR)0x400000
+
+int gdb_print_insn_mips (bfd_vma, disassemble_info *);
+
+static void mips_print_register (int, int);
+
+static mips_extra_func_info_t
+heuristic_proc_desc (CORE_ADDR, CORE_ADDR, struct frame_info *, int);
+
+static CORE_ADDR heuristic_proc_start (CORE_ADDR);
+
+static CORE_ADDR read_next_frame_reg (struct frame_info *, int);
+
+int mips_set_processor_type (char *);
+
+static void mips_show_processor_type_command (char *, int);
+
+static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
+
+static mips_extra_func_info_t
+find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame, int cur_frame);
+
+static CORE_ADDR after_prologue (CORE_ADDR pc,
+ mips_extra_func_info_t proc_desc);
+
+static void mips_read_fp_register_single (int regno, char *rare_buffer);
+static void mips_read_fp_register_double (int regno, char *rare_buffer);
+
+static struct type *mips_float_register_type (void);
+static struct type *mips_double_register_type (void);
+
+/* This value is the model of MIPS in use. It is derived from the value
+ of the PrID register. */
+
+char *mips_processor_type;
+
+char *tmp_mips_processor_type;
+
+/* The list of available "set mips " and "show mips " commands */
+
+static struct cmd_list_element *setmipscmdlist = NULL;
+static struct cmd_list_element *showmipscmdlist = NULL;
+
+/* A set of original names, to be used when restoring back to generic
+ registers from a specific set. */
+
+char *mips_generic_reg_names[] = MIPS_REGISTER_NAMES;
+char **mips_processor_reg_names = mips_generic_reg_names;
+
+char *
+mips_register_name (int i)
+{
+ return mips_processor_reg_names[i];
+}
+/* *INDENT-OFF* */
+/* Names of IDT R3041 registers. */
+
+char *mips_r3041_reg_names[] = {
+ "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
+ "sr", "lo", "hi", "bad", "cause","pc",
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+ "fsr", "fir", "fp", "",
+ "", "", "bus", "ccfg", "", "", "", "",
+ "", "", "port", "cmp", "", "", "epc", "prid",
+};
+
+/* Names of IDT R3051 registers. */
+
+char *mips_r3051_reg_names[] = {
+ "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
+ "sr", "lo", "hi", "bad", "cause","pc",
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+ "fsr", "fir", "fp", "",
+ "inx", "rand", "elo", "", "ctxt", "", "", "",
+ "", "", "ehi", "", "", "", "epc", "prid",
+};
+
+/* Names of IDT R3081 registers. */
+
+char *mips_r3081_reg_names[] = {
+ "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
+ "sr", "lo", "hi", "bad", "cause","pc",
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+ "fsr", "fir", "fp", "",
+ "inx", "rand", "elo", "cfg", "ctxt", "", "", "",
+ "", "", "ehi", "", "", "", "epc", "prid",
+};
+
+/* Names of LSI 33k registers. */
+
+char *mips_lsi33k_reg_names[] = {
+ "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
+ "epc", "hi", "lo", "sr", "cause","badvaddr",
+ "dcic", "bpc", "bda", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+};
+
+struct {
+ char *name;
+ char **regnames;
+} mips_processor_type_table[] = {
+ { "generic", mips_generic_reg_names },
+ { "r3041", mips_r3041_reg_names },
+ { "r3051", mips_r3051_reg_names },
+ { "r3071", mips_r3081_reg_names },
+ { "r3081", mips_r3081_reg_names },
+ { "lsi33k", mips_lsi33k_reg_names },
+ { NULL, NULL }
+};
+/* *INDENT-ON* */
+
+
+
+
+/* Table to translate MIPS16 register field to actual register number. */
+static int mips16_to_32_reg[8] =
+{16, 17, 2, 3, 4, 5, 6, 7};
+
+/* Heuristic_proc_start may hunt through the text section for a long
+ time across a 2400 baud serial line. Allows the user to limit this
+ search. */
+
+static unsigned int heuristic_fence_post = 0;
+
+#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) /* least address */
+#define PROC_HIGH_ADDR(proc) ((proc)->high_addr) /* upper address bound */
+#define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset)
+#define PROC_FRAME_REG(proc) ((proc)->pdr.framereg)
+#define PROC_FRAME_ADJUST(proc) ((proc)->frame_adjust)
+#define PROC_REG_MASK(proc) ((proc)->pdr.regmask)
+#define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask)
+#define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset)
+#define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset)
+#define PROC_PC_REG(proc) ((proc)->pdr.pcreg)
+#define PROC_SYMBOL(proc) (*(struct symbol**)&(proc)->pdr.isym)
+#define _PROC_MAGIC_ 0x0F0F0F0F
+#define PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym == _PROC_MAGIC_)
+#define SET_PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym = _PROC_MAGIC_)
+
+struct linked_proc_info
+ {
+ struct mips_extra_func_info info;
+ struct linked_proc_info *next;
+ }
+ *linked_proc_desc_table = NULL;
+
+void
+mips_print_extra_frame_info (struct frame_info *fi)
+{
+ if (fi
+ && fi->extra_info
+ && fi->extra_info->proc_desc
+ && fi->extra_info->proc_desc->pdr.framereg < NUM_REGS)
+ printf_filtered (" frame pointer is at %s+%s\n",
+ REGISTER_NAME (fi->extra_info->proc_desc->pdr.framereg),
+ paddr_d (fi->extra_info->proc_desc->pdr.frameoffset));
+}
+
+/* Number of bytes of storage in the actual machine representation for
+ register N. NOTE: This indirectly defines the register size
+ transfered by the GDB protocol. */
+
+static int mips64_transfers_32bit_regs_p = 0;
+
+int
+mips_register_raw_size (int reg_nr)
+{
+ if (mips64_transfers_32bit_regs_p)
+ return REGISTER_VIRTUAL_SIZE (reg_nr);
+ else if (reg_nr >= FP0_REGNUM && reg_nr < FP0_REGNUM + 32
+ && FP_REGISTER_DOUBLE)
+ /* For MIPS_ABI_N32 (for example) we need 8 byte floating point
+ registers. */
+ return 8;
+ else
+ return MIPS_REGSIZE;
+}
+
+/* Convert between RAW and VIRTUAL registers. The RAW register size
+ defines the remote-gdb packet. */
+
+int
+mips_register_convertible (int reg_nr)
+{
+ if (mips64_transfers_32bit_regs_p)
+ return 0;
+ else
+ return (REGISTER_RAW_SIZE (reg_nr) > REGISTER_VIRTUAL_SIZE (reg_nr));
+}
+
+void
+mips_register_convert_to_virtual (int n, struct type *virtual_type,
+ char *raw_buf, char *virt_buf)
+{
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ memcpy (virt_buf,
+ raw_buf + (REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)),
+ TYPE_LENGTH (virtual_type));
+ else
+ memcpy (virt_buf,
+ raw_buf,
+ TYPE_LENGTH (virtual_type));
+}
+
+void
+mips_register_convert_to_raw (struct type *virtual_type, int n,
+ char *virt_buf, char *raw_buf)
+{
+ memset (raw_buf, 0, REGISTER_RAW_SIZE (n));
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ memcpy (raw_buf + (REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)),
+ virt_buf,
+ TYPE_LENGTH (virtual_type));
+ else
+ memcpy (raw_buf,
+ virt_buf,
+ TYPE_LENGTH (virtual_type));
+}
+
+/* Should the upper word of 64-bit addresses be zeroed? */
+enum cmd_auto_boolean mask_address_var = CMD_AUTO_BOOLEAN_AUTO;
+
+static int
+mips_mask_address_p (void)
+{
+ switch (mask_address_var)
+ {
+ case CMD_AUTO_BOOLEAN_TRUE:
+ return 1;
+ case CMD_AUTO_BOOLEAN_FALSE:
+ return 0;
+ break;
+ case CMD_AUTO_BOOLEAN_AUTO:
+ return MIPS_DEFAULT_MASK_ADDRESS_P;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "mips_mask_address_p: bad switch");
+ return -1;
+ }
+}
+
+static void
+show_mask_address (char *cmd, int from_tty)
+{
+ switch (mask_address_var)
+ {
+ case CMD_AUTO_BOOLEAN_TRUE:
+ printf_filtered ("The 32 bit mips address mask is enabled\n");
+ break;
+ case CMD_AUTO_BOOLEAN_FALSE:
+ printf_filtered ("The 32 bit mips address mask is disabled\n");
+ break;
+ case CMD_AUTO_BOOLEAN_AUTO:
+ printf_filtered ("The 32 bit address mask is set automatically. Currently %s\n",
+ mips_mask_address_p () ? "enabled" : "disabled");
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "show_mask_address: bad switch");
+ break;
+ }
+}
+
+/* Should call_function allocate stack space for a struct return? */
+int
+mips_use_struct_convention (int gcc_p, struct type *type)
+{
+ if (MIPS_EABI)
+ return (TYPE_LENGTH (type) > 2 * MIPS_SAVED_REGSIZE);
+ else
+ return 1; /* Structures are returned by ref in extra arg0 */
+}
+
+/* Tell if the program counter value in MEMADDR is in a MIPS16 function. */
+
+static int
+pc_is_mips16 (bfd_vma memaddr)
+{
+ struct minimal_symbol *sym;
+
+ /* If bit 0 of the address is set, assume this is a MIPS16 address. */
+ if (IS_MIPS16_ADDR (memaddr))
+ return 1;
+
+ /* A flag indicating that this is a MIPS16 function is stored by elfread.c in
+ the high bit of the info field. Use this to decide if the function is
+ MIPS16 or normal MIPS. */
+ sym = lookup_minimal_symbol_by_pc (memaddr);
+ if (sym)
+ return MSYMBOL_IS_SPECIAL (sym);
+ else
+ return 0;
+}
+
+/* MIPS believes that the PC has a sign extended value. Perhaphs the
+ all registers should be sign extended for simplicity? */
+
+static CORE_ADDR
+mips_read_pc (ptid_t ptid)
+{
+ return read_signed_register_pid (PC_REGNUM, ptid);
+}
+
+/* This returns the PC of the first inst after the prologue. If we can't
+ find the prologue, then return 0. */
+
+static CORE_ADDR
+after_prologue (CORE_ADDR pc,
+ mips_extra_func_info_t proc_desc)
+{
+ struct symtab_and_line sal;
+ CORE_ADDR func_addr, func_end;
+
+ /* Pass cur_frame == 0 to find_proc_desc. We should not attempt
+ to read the stack pointer from the current machine state, because
+ the current machine state has nothing to do with the information
+ we need from the proc_desc; and the process may or may not exist
+ right now. */
+ if (!proc_desc)
+ proc_desc = find_proc_desc (pc, NULL, 0);
+
+ if (proc_desc)
+ {
+ /* If function is frameless, then we need to do it the hard way. I
+ strongly suspect that frameless always means prologueless... */
+ if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
+ && PROC_FRAME_OFFSET (proc_desc) == 0)
+ return 0;
+ }
+
+ if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ return 0; /* Unknown */
+
+ sal = find_pc_line (func_addr, 0);
+
+ if (sal.end < func_end)
+ return sal.end;
+
+ /* The line after the prologue is after the end of the function. In this
+ case, tell the caller to find the prologue the hard way. */
+
+ return 0;
+}
+
+/* Decode a MIPS32 instruction that saves a register in the stack, and
+ set the appropriate bit in the general register mask or float register mask
+ to indicate which register is saved. This is a helper function
+ for mips_find_saved_regs. */
+
+static void
+mips32_decode_reg_save (t_inst inst, unsigned long *gen_mask,
+ unsigned long *float_mask)
+{
+ int reg;
+
+ if ((inst & 0xffe00000) == 0xafa00000 /* sw reg,n($sp) */
+ || (inst & 0xffe00000) == 0xafc00000 /* sw reg,n($r30) */
+ || (inst & 0xffe00000) == 0xffa00000) /* sd reg,n($sp) */
+ {
+ /* It might be possible to use the instruction to
+ find the offset, rather than the code below which
+ is based on things being in a certain order in the
+ frame, but figuring out what the instruction's offset
+ is relative to might be a little tricky. */
+ reg = (inst & 0x001f0000) >> 16;
+ *gen_mask |= (1 << reg);
+ }
+ else if ((inst & 0xffe00000) == 0xe7a00000 /* swc1 freg,n($sp) */
+ || (inst & 0xffe00000) == 0xe7c00000 /* swc1 freg,n($r30) */
+ || (inst & 0xffe00000) == 0xf7a00000) /* sdc1 freg,n($sp) */
+
+ {
+ reg = ((inst & 0x001f0000) >> 16);
+ *float_mask |= (1 << reg);
+ }
+}
+
+/* Decode a MIPS16 instruction that saves a register in the stack, and
+ set the appropriate bit in the general register or float register mask
+ to indicate which register is saved. This is a helper function
+ for mips_find_saved_regs. */
+
+static void
+mips16_decode_reg_save (t_inst inst, unsigned long *gen_mask)
+{
+ if ((inst & 0xf800) == 0xd000) /* sw reg,n($sp) */
+ {
+ int reg = mips16_to_32_reg[(inst & 0x700) >> 8];
+ *gen_mask |= (1 << reg);
+ }
+ else if ((inst & 0xff00) == 0xf900) /* sd reg,n($sp) */
+ {
+ int reg = mips16_to_32_reg[(inst & 0xe0) >> 5];
+ *gen_mask |= (1 << reg);
+ }
+ else if ((inst & 0xff00) == 0x6200 /* sw $ra,n($sp) */
+ || (inst & 0xff00) == 0xfa00) /* sd $ra,n($sp) */
+ *gen_mask |= (1 << RA_REGNUM);
+}
+
+
+/* Fetch and return instruction from the specified location. If the PC
+ is odd, assume it's a MIPS16 instruction; otherwise MIPS32. */
+
+static t_inst
+mips_fetch_instruction (CORE_ADDR addr)
+{
+ char buf[MIPS_INSTLEN];
+ int instlen;
+ int status;
+
+ if (pc_is_mips16 (addr))
+ {
+ instlen = MIPS16_INSTLEN;
+ addr = UNMAKE_MIPS16_ADDR (addr);
+ }
+ else
+ instlen = MIPS_INSTLEN;
+ status = read_memory_nobpt (addr, buf, instlen);
+ if (status)
+ memory_error (status, addr);
+ return extract_unsigned_integer (buf, instlen);
+}
+
+
+/* These the fields of 32 bit mips instructions */
+#define mips32_op(x) (x >> 26)
+#define itype_op(x) (x >> 26)
+#define itype_rs(x) ((x >> 21) & 0x1f)
+#define itype_rt(x) ((x >> 16) & 0x1f)
+#define itype_immediate(x) (x & 0xffff)
+
+#define jtype_op(x) (x >> 26)
+#define jtype_target(x) (x & 0x03ffffff)
+
+#define rtype_op(x) (x >> 26)
+#define rtype_rs(x) ((x >> 21) & 0x1f)
+#define rtype_rt(x) ((x >> 16) & 0x1f)
+#define rtype_rd(x) ((x >> 11) & 0x1f)
+#define rtype_shamt(x) ((x >> 6) & 0x1f)
+#define rtype_funct(x) (x & 0x3f)
+
+static CORE_ADDR
+mips32_relative_offset (unsigned long inst)
+{
+ long x;
+ x = itype_immediate (inst);
+ if (x & 0x8000) /* sign bit set */
+ {
+ x |= 0xffff0000; /* sign extension */
+ }
+ x = x << 2;
+ return x;
+}
+
+/* Determine whate to set a single step breakpoint while considering
+ branch prediction */
+CORE_ADDR
+mips32_next_pc (CORE_ADDR pc)
+{
+ unsigned long inst;
+ int op;
+ inst = mips_fetch_instruction (pc);
+ if ((inst & 0xe0000000) != 0) /* Not a special, jump or branch instruction */
+ {
+ if (itype_op (inst) >> 2 == 5)
+ /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */
+ {
+ op = (itype_op (inst) & 0x03);
+ switch (op)
+ {
+ case 0: /* BEQL */
+ goto equal_branch;
+ case 1: /* BNEL */
+ goto neq_branch;
+ case 2: /* BLEZL */
+ goto less_branch;
+ case 3: /* BGTZ */
+ goto greater_branch;
+ default:
+ pc += 4;
+ }
+ }
+ else if (itype_op (inst) == 17 && itype_rs (inst) == 8)
+ /* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */
+ {
+ int tf = itype_rt (inst) & 0x01;
+ int cnum = itype_rt (inst) >> 2;
+ int fcrcs = read_signed_register (FCRCS_REGNUM);
+ int cond = ((fcrcs >> 24) & 0x0e) | ((fcrcs >> 23) & 0x01);
+
+ if (((cond >> cnum) & 0x01) == tf)
+ pc += mips32_relative_offset (inst) + 4;
+ else
+ pc += 8;
+ }
+ else
+ pc += 4; /* Not a branch, next instruction is easy */
+ }
+ else
+ { /* This gets way messy */
+
+ /* Further subdivide into SPECIAL, REGIMM and other */
+ switch (op = itype_op (inst) & 0x07) /* extract bits 28,27,26 */
+ {
+ case 0: /* SPECIAL */
+ op = rtype_funct (inst);
+ switch (op)
+ {
+ case 8: /* JR */
+ case 9: /* JALR */
+ /* Set PC to that address */
+ pc = read_signed_register (rtype_rs (inst));
+ break;
+ default:
+ pc += 4;
+ }
+
+ break; /* end SPECIAL */
+ case 1: /* REGIMM */
+ {
+ op = itype_rt (inst); /* branch condition */
+ switch (op)
+ {
+ case 0: /* BLTZ */
+ case 2: /* BLTZL */
+ case 16: /* BLTZAL */
+ case 18: /* BLTZALL */
+ less_branch:
+ if (read_signed_register (itype_rs (inst)) < 0)
+ pc += mips32_relative_offset (inst) + 4;
+ else
+ pc += 8; /* after the delay slot */
+ break;
+ case 1: /* BGEZ */
+ case 3: /* BGEZL */
+ case 17: /* BGEZAL */
+ case 19: /* BGEZALL */
+ greater_equal_branch:
+ if (read_signed_register (itype_rs (inst)) >= 0)
+ pc += mips32_relative_offset (inst) + 4;
+ else
+ pc += 8; /* after the delay slot */
+ break;
+ /* All of the other instructions in the REGIMM category */
+ default:
+ pc += 4;
+ }
+ }
+ break; /* end REGIMM */
+ case 2: /* J */
+ case 3: /* JAL */
+ {
+ unsigned long reg;
+ reg = jtype_target (inst) << 2;
+ /* Upper four bits get never changed... */
+ pc = reg + ((pc + 4) & 0xf0000000);
+ }
+ break;
+ /* FIXME case JALX : */
+ {
+ unsigned long reg;
+ reg = jtype_target (inst) << 2;
+ pc = reg + ((pc + 4) & 0xf0000000) + 1; /* yes, +1 */
+ /* Add 1 to indicate 16 bit mode - Invert ISA mode */
+ }
+ break; /* The new PC will be alternate mode */
+ case 4: /* BEQ, BEQL */
+ equal_branch:
+ if (read_signed_register (itype_rs (inst)) ==
+ read_signed_register (itype_rt (inst)))
+ pc += mips32_relative_offset (inst) + 4;
+ else
+ pc += 8;
+ break;
+ case 5: /* BNE, BNEL */
+ neq_branch:
+ if (read_signed_register (itype_rs (inst)) !=
+ read_signed_register (itype_rt (inst)))
+ pc += mips32_relative_offset (inst) + 4;
+ else
+ pc += 8;
+ break;
+ case 6: /* BLEZ, BLEZL */
+ less_zero_branch:
+ if (read_signed_register (itype_rs (inst) <= 0))
+ pc += mips32_relative_offset (inst) + 4;
+ else
+ pc += 8;
+ break;
+ case 7:
+ default:
+ greater_branch: /* BGTZ, BGTZL */
+ if (read_signed_register (itype_rs (inst) > 0))
+ pc += mips32_relative_offset (inst) + 4;
+ else
+ pc += 8;
+ break;
+ } /* switch */
+ } /* else */
+ return pc;
+} /* mips32_next_pc */
+
+/* Decoding the next place to set a breakpoint is irregular for the
+ mips 16 variant, but fortunately, there fewer instructions. We have to cope
+ ith extensions for 16 bit instructions and a pair of actual 32 bit instructions.
+ We dont want to set a single step instruction on the extend instruction
+ either.
+ */
+
+/* Lots of mips16 instruction formats */
+/* Predicting jumps requires itype,ritype,i8type
+ and their extensions extItype,extritype,extI8type
+ */
+enum mips16_inst_fmts
+{
+ itype, /* 0 immediate 5,10 */
+ ritype, /* 1 5,3,8 */
+ rrtype, /* 2 5,3,3,5 */
+ rritype, /* 3 5,3,3,5 */
+ rrrtype, /* 4 5,3,3,3,2 */
+ rriatype, /* 5 5,3,3,1,4 */
+ shifttype, /* 6 5,3,3,3,2 */
+ i8type, /* 7 5,3,8 */
+ i8movtype, /* 8 5,3,3,5 */
+ i8mov32rtype, /* 9 5,3,5,3 */
+ i64type, /* 10 5,3,8 */
+ ri64type, /* 11 5,3,3,5 */
+ jalxtype, /* 12 5,1,5,5,16 - a 32 bit instruction */
+ exiItype, /* 13 5,6,5,5,1,1,1,1,1,1,5 */
+ extRitype, /* 14 5,6,5,5,3,1,1,1,5 */
+ extRRItype, /* 15 5,5,5,5,3,3,5 */
+ extRRIAtype, /* 16 5,7,4,5,3,3,1,4 */
+ EXTshifttype, /* 17 5,5,1,1,1,1,1,1,5,3,3,1,1,1,2 */
+ extI8type, /* 18 5,6,5,5,3,1,1,1,5 */
+ extI64type, /* 19 5,6,5,5,3,1,1,1,5 */
+ extRi64type, /* 20 5,6,5,5,3,3,5 */
+ extshift64type /* 21 5,5,1,1,1,1,1,1,5,1,1,1,3,5 */
+};
+/* I am heaping all the fields of the formats into one structure and
+ then, only the fields which are involved in instruction extension */
+struct upk_mips16
+ {
+ CORE_ADDR offset;
+ unsigned int regx; /* Function in i8 type */
+ unsigned int regy;
+ };
+
+
+/* The EXT-I, EXT-ri nad EXT-I8 instructions all have the same format
+ for the bits which make up the immediatate extension. */
+
+static CORE_ADDR
+extended_offset (unsigned int extension)
+{
+ CORE_ADDR value;
+ value = (extension >> 21) & 0x3f; /* * extract 15:11 */
+ value = value << 6;
+ value |= (extension >> 16) & 0x1f; /* extrace 10:5 */
+ value = value << 5;
+ value |= extension & 0x01f; /* extract 4:0 */
+ return value;
+}
+
+/* Only call this function if you know that this is an extendable
+ instruction, It wont malfunction, but why make excess remote memory references?
+ If the immediate operands get sign extended or somthing, do it after
+ the extension is performed.
+ */
+/* FIXME: Every one of these cases needs to worry about sign extension
+ when the offset is to be used in relative addressing */
+
+
+static unsigned int
+fetch_mips_16 (CORE_ADDR pc)
+{
+ char buf[8];
+ pc &= 0xfffffffe; /* clear the low order bit */
+ target_read_memory (pc, buf, 2);
+ return extract_unsigned_integer (buf, 2);
+}
+
+static void
+unpack_mips16 (CORE_ADDR pc,
+ unsigned int extension,
+ unsigned int inst,
+ enum mips16_inst_fmts insn_format,
+ struct upk_mips16 *upk)
+{
+ CORE_ADDR offset;
+ int regx;
+ int regy;
+ switch (insn_format)
+ {
+ case itype:
+ {
+ CORE_ADDR value;
+ if (extension)
+ {
+ value = extended_offset (extension);
+ value = value << 11; /* rom for the original value */
+ value |= inst & 0x7ff; /* eleven bits from instruction */
+ }
+ else
+ {
+ value = inst & 0x7ff;
+ /* FIXME : Consider sign extension */
+ }
+ offset = value;
+ regx = -1;
+ regy = -1;
+ }
+ break;
+ case ritype:
+ case i8type:
+ { /* A register identifier and an offset */
+ /* Most of the fields are the same as I type but the
+ immediate value is of a different length */
+ CORE_ADDR value;
+ if (extension)
+ {
+ value = extended_offset (extension);
+ value = value << 8; /* from the original instruction */
+ value |= inst & 0xff; /* eleven bits from instruction */
+ regx = (extension >> 8) & 0x07; /* or i8 funct */
+ if (value & 0x4000) /* test the sign bit , bit 26 */
+ {
+ value &= ~0x3fff; /* remove the sign bit */
+ value = -value;
+ }
+ }
+ else
+ {
+ value = inst & 0xff; /* 8 bits */
+ regx = (inst >> 8) & 0x07; /* or i8 funct */
+ /* FIXME: Do sign extension , this format needs it */
+ if (value & 0x80) /* THIS CONFUSES ME */
+ {
+ value &= 0xef; /* remove the sign bit */
+ value = -value;
+ }
+ }
+ offset = value;
+ regy = -1;
+ break;
+ }
+ case jalxtype:
+ {
+ unsigned long value;
+ unsigned int nexthalf;
+ value = ((inst & 0x1f) << 5) | ((inst >> 5) & 0x1f);
+ value = value << 16;
+ nexthalf = mips_fetch_instruction (pc + 2); /* low bit still set */
+ value |= nexthalf;
+ offset = value;
+ regx = -1;
+ regy = -1;
+ break;
+ }
+ default:
+ internal_error (__FILE__, __LINE__,
+ "bad switch");
+ }
+ upk->offset = offset;
+ upk->regx = regx;
+ upk->regy = regy;
+}
+
+
+static CORE_ADDR
+add_offset_16 (CORE_ADDR pc, int offset)
+{
+ return ((offset << 2) | ((pc + 2) & (0xf0000000)));
+
+}
+
+static CORE_ADDR
+extended_mips16_next_pc (CORE_ADDR pc,
+ unsigned int extension,
+ unsigned int insn)
+{
+ int op = (insn >> 11);
+ switch (op)
+ {
+ case 2: /* Branch */
+ {
+ CORE_ADDR offset;
+ struct upk_mips16 upk;
+ unpack_mips16 (pc, extension, insn, itype, &upk);
+ offset = upk.offset;
+ if (offset & 0x800)
+ {
+ offset &= 0xeff;
+ offset = -offset;
+ }
+ pc += (offset << 1) + 2;
+ break;
+ }
+ case 3: /* JAL , JALX - Watch out, these are 32 bit instruction */
+ {
+ struct upk_mips16 upk;
+ unpack_mips16 (pc, extension, insn, jalxtype, &upk);
+ pc = add_offset_16 (pc, upk.offset);
+ if ((insn >> 10) & 0x01) /* Exchange mode */
+ pc = pc & ~0x01; /* Clear low bit, indicate 32 bit mode */
+ else
+ pc |= 0x01;
+ break;
+ }
+ case 4: /* beqz */
+ {
+ struct upk_mips16 upk;
+ int reg;
+ unpack_mips16 (pc, extension, insn, ritype, &upk);
+ reg = read_signed_register (upk.regx);
+ if (reg == 0)
+ pc += (upk.offset << 1) + 2;
+ else
+ pc += 2;
+ break;
+ }
+ case 5: /* bnez */
+ {
+ struct upk_mips16 upk;
+ int reg;
+ unpack_mips16 (pc, extension, insn, ritype, &upk);
+ reg = read_signed_register (upk.regx);
+ if (reg != 0)
+ pc += (upk.offset << 1) + 2;
+ else
+ pc += 2;
+ break;
+ }
+ case 12: /* I8 Formats btez btnez */
+ {
+ struct upk_mips16 upk;
+ int reg;
+ unpack_mips16 (pc, extension, insn, i8type, &upk);
+ /* upk.regx contains the opcode */
+ reg = read_signed_register (24); /* Test register is 24 */
+ if (((upk.regx == 0) && (reg == 0)) /* BTEZ */
+ || ((upk.regx == 1) && (reg != 0))) /* BTNEZ */
+ /* pc = add_offset_16(pc,upk.offset) ; */
+ pc += (upk.offset << 1) + 2;
+ else
+ pc += 2;
+ break;
+ }
+ case 29: /* RR Formats JR, JALR, JALR-RA */
+ {
+ struct upk_mips16 upk;
+ /* upk.fmt = rrtype; */
+ op = insn & 0x1f;
+ if (op == 0)
+ {
+ int reg;
+ upk.regx = (insn >> 8) & 0x07;
+ upk.regy = (insn >> 5) & 0x07;
+ switch (upk.regy)
+ {
+ case 0:
+ reg = upk.regx;
+ break;
+ case 1:
+ reg = 31;
+ break; /* Function return instruction */
+ case 2:
+ reg = upk.regx;
+ break;
+ default:
+ reg = 31;
+ break; /* BOGUS Guess */
+ }
+ pc = read_signed_register (reg);
+ }
+ else
+ pc += 2;
+ break;
+ }
+ case 30:
+ /* This is an instruction extension. Fetch the real instruction
+ (which follows the extension) and decode things based on
+ that. */
+ {
+ pc += 2;
+ pc = extended_mips16_next_pc (pc, insn, fetch_mips_16 (pc));
+ break;
+ }
+ default:
+ {
+ pc += 2;
+ break;
+ }
+ }
+ return pc;
+}
+
+CORE_ADDR
+mips16_next_pc (CORE_ADDR pc)
+{
+ unsigned int insn = fetch_mips_16 (pc);
+ return extended_mips16_next_pc (pc, 0, insn);
+}
+
+/* The mips_next_pc function supports single_step when the remote
+ target monitor or stub is not developed enough to do a single_step.
+ It works by decoding the current instruction and predicting where a
+ branch will go. This isnt hard because all the data is available.
+ The MIPS32 and MIPS16 variants are quite different */
+CORE_ADDR
+mips_next_pc (CORE_ADDR pc)
+{
+ if (pc & 0x01)
+ return mips16_next_pc (pc);
+ else
+ return mips32_next_pc (pc);
+}
+
+/* Guaranteed to set fci->saved_regs to some values (it never leaves it
+ NULL). */
+
+void
+mips_find_saved_regs (struct frame_info *fci)
+{
+ int ireg;
+ CORE_ADDR reg_position;
+ /* r0 bit means kernel trap */
+ int kernel_trap;
+ /* What registers have been saved? Bitmasks. */
+ unsigned long gen_mask, float_mask;
+ mips_extra_func_info_t proc_desc;
+ t_inst inst;
+
+ frame_saved_regs_zalloc (fci);
+
+ /* If it is the frame for sigtramp, the saved registers are located
+ in a sigcontext structure somewhere on the stack.
+ If the stack layout for sigtramp changes we might have to change these
+ constants and the companion fixup_sigtramp in mdebugread.c */
+#ifndef SIGFRAME_BASE
+/* To satisfy alignment restrictions, sigcontext is located 4 bytes
+ above the sigtramp frame. */
+#define SIGFRAME_BASE MIPS_REGSIZE
+/* FIXME! Are these correct?? */
+#define SIGFRAME_PC_OFF (SIGFRAME_BASE + 2 * MIPS_REGSIZE)
+#define SIGFRAME_REGSAVE_OFF (SIGFRAME_BASE + 3 * MIPS_REGSIZE)
+#define SIGFRAME_FPREGSAVE_OFF \
+ (SIGFRAME_REGSAVE_OFF + MIPS_NUMREGS * MIPS_REGSIZE + 3 * MIPS_REGSIZE)
+#endif
+#ifndef SIGFRAME_REG_SIZE
+/* FIXME! Is this correct?? */
+#define SIGFRAME_REG_SIZE MIPS_REGSIZE
+#endif
+ if (fci->signal_handler_caller)
+ {
+ for (ireg = 0; ireg < MIPS_NUMREGS; ireg++)
+ {
+ reg_position = fci->frame + SIGFRAME_REGSAVE_OFF
+ + ireg * SIGFRAME_REG_SIZE;
+ fci->saved_regs[ireg] = reg_position;
+ }
+ for (ireg = 0; ireg < MIPS_NUMREGS; ireg++)
+ {
+ reg_position = fci->frame + SIGFRAME_FPREGSAVE_OFF
+ + ireg * SIGFRAME_REG_SIZE;
+ fci->saved_regs[FP0_REGNUM + ireg] = reg_position;
+ }
+ fci->saved_regs[PC_REGNUM] = fci->frame + SIGFRAME_PC_OFF;
+ return;
+ }
+
+ proc_desc = fci->extra_info->proc_desc;
+ if (proc_desc == NULL)
+ /* I'm not sure how/whether this can happen. Normally when we can't
+ find a proc_desc, we "synthesize" one using heuristic_proc_desc
+ and set the saved_regs right away. */
+ return;
+
+ kernel_trap = PROC_REG_MASK (proc_desc) & 1;
+ gen_mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK (proc_desc);
+ float_mask = kernel_trap ? 0xFFFFFFFF : PROC_FREG_MASK (proc_desc);
+
+ if ( /* In any frame other than the innermost or a frame interrupted by
+ a signal, we assume that all registers have been saved.
+ This assumes that all register saves in a function happen before
+ the first function call. */
+ (fci->next == NULL || fci->next->signal_handler_caller)
+
+ /* In a dummy frame we know exactly where things are saved. */
+ && !PROC_DESC_IS_DUMMY (proc_desc)
+
+ /* Don't bother unless we are inside a function prologue. Outside the
+ prologue, we know where everything is. */
+
+ && in_prologue (fci->pc, PROC_LOW_ADDR (proc_desc))
+
+ /* Not sure exactly what kernel_trap means, but if it means
+ the kernel saves the registers without a prologue doing it,
+ we better not examine the prologue to see whether registers
+ have been saved yet. */
+ && !kernel_trap)
+ {
+ /* We need to figure out whether the registers that the proc_desc
+ claims are saved have been saved yet. */
+
+ CORE_ADDR addr;
+
+ /* Bitmasks; set if we have found a save for the register. */
+ unsigned long gen_save_found = 0;
+ unsigned long float_save_found = 0;
+ int instlen;
+
+ /* If the address is odd, assume this is MIPS16 code. */
+ addr = PROC_LOW_ADDR (proc_desc);
+ instlen = pc_is_mips16 (addr) ? MIPS16_INSTLEN : MIPS_INSTLEN;
+
+ /* Scan through this function's instructions preceding the current
+ PC, and look for those that save registers. */
+ while (addr < fci->pc)
+ {
+ inst = mips_fetch_instruction (addr);
+ if (pc_is_mips16 (addr))
+ mips16_decode_reg_save (inst, &gen_save_found);
+ else
+ mips32_decode_reg_save (inst, &gen_save_found, &float_save_found);
+ addr += instlen;
+ }
+ gen_mask = gen_save_found;
+ float_mask = float_save_found;
+ }
+
+ /* Fill in the offsets for the registers which gen_mask says
+ were saved. */
+ reg_position = fci->frame + PROC_REG_OFFSET (proc_desc);
+ for (ireg = MIPS_NUMREGS - 1; gen_mask; --ireg, gen_mask <<= 1)
+ if (gen_mask & 0x80000000)
+ {
+ fci->saved_regs[ireg] = reg_position;
+ reg_position -= MIPS_SAVED_REGSIZE;
+ }
+
+ /* The MIPS16 entry instruction saves $s0 and $s1 in the reverse order
+ of that normally used by gcc. Therefore, we have to fetch the first
+ instruction of the function, and if it's an entry instruction that
+ saves $s0 or $s1, correct their saved addresses. */
+ if (pc_is_mips16 (PROC_LOW_ADDR (proc_desc)))
+ {
+ inst = mips_fetch_instruction (PROC_LOW_ADDR (proc_desc));
+ if ((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700) /* entry */
+ {
+ int reg;
+ int sreg_count = (inst >> 6) & 3;
+
+ /* Check if the ra register was pushed on the stack. */
+ reg_position = fci->frame + PROC_REG_OFFSET (proc_desc);
+ if (inst & 0x20)
+ reg_position -= MIPS_SAVED_REGSIZE;
+
+ /* Check if the s0 and s1 registers were pushed on the stack. */
+ for (reg = 16; reg < sreg_count + 16; reg++)
+ {
+ fci->saved_regs[reg] = reg_position;
+ reg_position -= MIPS_SAVED_REGSIZE;
+ }
+ }
+ }
+
+ /* Fill in the offsets for the registers which float_mask says
+ were saved. */
+ reg_position = fci->frame + PROC_FREG_OFFSET (proc_desc);
+
+ /* The freg_offset points to where the first *double* register
+ is saved. So skip to the high-order word. */
+ if (!GDB_TARGET_IS_MIPS64)
+ reg_position += MIPS_SAVED_REGSIZE;
+
+ /* Fill in the offsets for the float registers which float_mask says
+ were saved. */
+ for (ireg = MIPS_NUMREGS - 1; float_mask; --ireg, float_mask <<= 1)
+ if (float_mask & 0x80000000)
+ {
+ fci->saved_regs[FP0_REGNUM + ireg] = reg_position;
+ reg_position -= MIPS_SAVED_REGSIZE;
+ }
+
+ fci->saved_regs[PC_REGNUM] = fci->saved_regs[RA_REGNUM];
+}
+
+static CORE_ADDR
+read_next_frame_reg (struct frame_info *fi, int regno)
+{
+ for (; fi; fi = fi->next)
+ {
+ /* We have to get the saved sp from the sigcontext
+ if it is a signal handler frame. */
+ if (regno == SP_REGNUM && !fi->signal_handler_caller)
+ return fi->frame;
+ else
+ {
+ if (fi->saved_regs == NULL)
+ mips_find_saved_regs (fi);
+ if (fi->saved_regs[regno])
+ return read_memory_integer (ADDR_BITS_REMOVE (fi->saved_regs[regno]), MIPS_SAVED_REGSIZE);
+ }
+ }
+ return read_signed_register (regno);
+}
+
+/* mips_addr_bits_remove - remove useless address bits */
+
+static CORE_ADDR
+mips_addr_bits_remove (CORE_ADDR addr)
+{
+ if (GDB_TARGET_IS_MIPS64)
+ {
+ if (mips_mask_address_p () && (addr >> 32 == (CORE_ADDR) 0xffffffff))
+ {
+ /* This hack is a work-around for existing boards using
+ PMON, the simulator, and any other 64-bit targets that
+ doesn't have true 64-bit addressing. On these targets,
+ the upper 32 bits of addresses are ignored by the
+ hardware. Thus, the PC or SP are likely to have been
+ sign extended to all 1s by instruction sequences that
+ load 32-bit addresses. For example, a typical piece of
+ code that loads an address is this:
+ lui $r2, <upper 16 bits>
+ ori $r2, <lower 16 bits>
+ But the lui sign-extends the value such that the upper 32
+ bits may be all 1s. The workaround is simply to mask off
+ these bits. In the future, gcc may be changed to support
+ true 64-bit addressing, and this masking will have to be
+ disabled. */
+ addr &= (CORE_ADDR) 0xffffffff;
+ }
+ }
+ else if (mips_mask_address_p ())
+ {
+ /* FIXME: This is wrong! mips_addr_bits_remove() shouldn't be
+ masking off bits, instead, the actual target should be asking
+ for the address to be converted to a valid pointer. */
+ /* Even when GDB is configured for some 32-bit targets
+ (e.g. mips-elf), BFD is configured to handle 64-bit targets,
+ so CORE_ADDR is 64 bits. So we still have to mask off
+ useless bits from addresses. */
+ addr &= (CORE_ADDR) 0xffffffff;
+ }
+ return addr;
+}
+
+/* mips_software_single_step() is called just before we want to resume
+ the inferior, if we want to single-step it but there is no hardware
+ or kernel single-step support (MIPS on GNU/Linux for example). We find
+ the target of the coming instruction and breakpoint it.
+
+ single_step is also called just after the inferior stops. If we had
+ set up a simulated single-step, we undo our damage. */
+
+void
+mips_software_single_step (enum target_signal sig, int insert_breakpoints_p)
+{
+ static CORE_ADDR next_pc;
+ typedef char binsn_quantum[BREAKPOINT_MAX];
+ static binsn_quantum break_mem;
+ CORE_ADDR pc;
+
+ if (insert_breakpoints_p)
+ {
+ pc = read_register (PC_REGNUM);
+ next_pc = mips_next_pc (pc);
+
+ target_insert_breakpoint (next_pc, break_mem);
+ }
+ else
+ target_remove_breakpoint (next_pc, break_mem);
+}
+
+static void
+mips_init_frame_pc_first (int fromleaf, struct frame_info *prev)
+{
+ CORE_ADDR pc, tmp;
+
+ pc = ((fromleaf) ? SAVED_PC_AFTER_CALL (prev->next) :
+ prev->next ? FRAME_SAVED_PC (prev->next) : read_pc ());
+ tmp = mips_skip_stub (pc);
+ prev->pc = tmp ? tmp : pc;
+}
+
+
+CORE_ADDR
+mips_frame_saved_pc (struct frame_info *frame)
+{
+ CORE_ADDR saved_pc;
+ mips_extra_func_info_t proc_desc = frame->extra_info->proc_desc;
+ /* We have to get the saved pc from the sigcontext
+ if it is a signal handler frame. */
+ int pcreg = frame->signal_handler_caller ? PC_REGNUM
+ : (proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM);
+
+ if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
+ saved_pc = read_memory_integer (frame->frame - MIPS_SAVED_REGSIZE, MIPS_SAVED_REGSIZE);
+ else
+ saved_pc = read_next_frame_reg (frame, pcreg);
+
+ return ADDR_BITS_REMOVE (saved_pc);
+}
+
+static struct mips_extra_func_info temp_proc_desc;
+static CORE_ADDR temp_saved_regs[NUM_REGS];
+
+/* Set a register's saved stack address in temp_saved_regs. If an address
+ has already been set for this register, do nothing; this way we will
+ only recognize the first save of a given register in a function prologue.
+ This is a helper function for mips{16,32}_heuristic_proc_desc. */
+
+static void
+set_reg_offset (int regno, CORE_ADDR offset)
+{
+ if (temp_saved_regs[regno] == 0)
+ temp_saved_regs[regno] = offset;
+}
+
+
+/* Test whether the PC points to the return instruction at the
+ end of a function. */
+
+static int
+mips_about_to_return (CORE_ADDR pc)
+{
+ if (pc_is_mips16 (pc))
+ /* This mips16 case isn't necessarily reliable. Sometimes the compiler
+ generates a "jr $ra"; other times it generates code to load
+ the return address from the stack to an accessible register (such
+ as $a3), then a "jr" using that register. This second case
+ is almost impossible to distinguish from an indirect jump
+ used for switch statements, so we don't even try. */
+ return mips_fetch_instruction (pc) == 0xe820; /* jr $ra */
+ else
+ return mips_fetch_instruction (pc) == 0x3e00008; /* jr $ra */
+}
+
+
+/* This fencepost looks highly suspicious to me. Removing it also
+ seems suspicious as it could affect remote debugging across serial
+ lines. */
+
+static CORE_ADDR
+heuristic_proc_start (CORE_ADDR pc)
+{
+ CORE_ADDR start_pc;
+ CORE_ADDR fence;
+ int instlen;
+ int seen_adjsp = 0;
+
+ pc = ADDR_BITS_REMOVE (pc);
+ start_pc = pc;
+ fence = start_pc - heuristic_fence_post;
+ if (start_pc == 0)
+ return 0;
+
+ if (heuristic_fence_post == UINT_MAX
+ || fence < VM_MIN_ADDRESS)
+ fence = VM_MIN_ADDRESS;
+
+ instlen = pc_is_mips16 (pc) ? MIPS16_INSTLEN : MIPS_INSTLEN;
+
+ /* search back for previous return */
+ for (start_pc -= instlen;; start_pc -= instlen)
+ if (start_pc < fence)
+ {
+ /* It's not clear to me why we reach this point when
+ stop_soon_quietly, but with this test, at least we
+ don't print out warnings for every child forked (eg, on
+ decstation). 22apr93 rich@cygnus.com. */
+ if (!stop_soon_quietly)
+ {
+ static int blurb_printed = 0;
+
+ warning ("Warning: GDB can't find the start of the function at 0x%s.",
+ paddr_nz (pc));
+
+ if (!blurb_printed)
+ {
+ /* This actually happens frequently in embedded
+ development, when you first connect to a board
+ and your stack pointer and pc are nowhere in
+ particular. This message needs to give people
+ in that situation enough information to
+ determine that it's no big deal. */
+ printf_filtered ("\n\
+ GDB is unable to find the start of the function at 0x%s\n\
+and thus can't determine the size of that function's stack frame.\n\
+This means that GDB may be unable to access that stack frame, or\n\
+the frames below it.\n\
+ This problem is most likely caused by an invalid program counter or\n\
+stack pointer.\n\
+ However, if you think GDB should simply search farther back\n\
+from 0x%s for code which looks like the beginning of a\n\
+function, you can increase the range of the search using the `set\n\
+heuristic-fence-post' command.\n",
+ paddr_nz (pc), paddr_nz (pc));
+ blurb_printed = 1;
+ }
+ }
+
+ return 0;
+ }
+ else if (pc_is_mips16 (start_pc))
+ {
+ unsigned short inst;
+
+ /* On MIPS16, any one of the following is likely to be the
+ start of a function:
+ entry
+ addiu sp,-n
+ daddiu sp,-n
+ extend -n followed by 'addiu sp,+n' or 'daddiu sp,+n' */
+ inst = mips_fetch_instruction (start_pc);
+ if (((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700) /* entry */
+ || (inst & 0xff80) == 0x6380 /* addiu sp,-n */
+ || (inst & 0xff80) == 0xfb80 /* daddiu sp,-n */
+ || ((inst & 0xf810) == 0xf010 && seen_adjsp)) /* extend -n */
+ break;
+ else if ((inst & 0xff00) == 0x6300 /* addiu sp */
+ || (inst & 0xff00) == 0xfb00) /* daddiu sp */
+ seen_adjsp = 1;
+ else
+ seen_adjsp = 0;
+ }
+ else if (mips_about_to_return (start_pc))
+ {
+ start_pc += 2 * MIPS_INSTLEN; /* skip return, and its delay slot */
+ break;
+ }
+
+ return start_pc;
+}
+
+/* Fetch the immediate value from a MIPS16 instruction.
+ If the previous instruction was an EXTEND, use it to extend
+ the upper bits of the immediate value. This is a helper function
+ for mips16_heuristic_proc_desc. */
+
+static int
+mips16_get_imm (unsigned short prev_inst, /* previous instruction */
+ unsigned short inst, /* current instruction */
+ int nbits, /* number of bits in imm field */
+ int scale, /* scale factor to be applied to imm */
+ int is_signed) /* is the imm field signed? */
+{
+ int offset;
+
+ if ((prev_inst & 0xf800) == 0xf000) /* prev instruction was EXTEND? */
+ {
+ offset = ((prev_inst & 0x1f) << 11) | (prev_inst & 0x7e0);
+ if (offset & 0x8000) /* check for negative extend */
+ offset = 0 - (0x10000 - (offset & 0xffff));
+ return offset | (inst & 0x1f);
+ }
+ else
+ {
+ int max_imm = 1 << nbits;
+ int mask = max_imm - 1;
+ int sign_bit = max_imm >> 1;
+
+ offset = inst & mask;
+ if (is_signed && (offset & sign_bit))
+ offset = 0 - (max_imm - offset);
+ return offset * scale;
+ }
+}
+
+
+/* Fill in values in temp_proc_desc based on the MIPS16 instruction
+ stream from start_pc to limit_pc. */
+
+static void
+mips16_heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
+ struct frame_info *next_frame, CORE_ADDR sp)
+{
+ CORE_ADDR cur_pc;
+ CORE_ADDR frame_addr = 0; /* Value of $r17, used as frame pointer */
+ unsigned short prev_inst = 0; /* saved copy of previous instruction */
+ unsigned inst = 0; /* current instruction */
+ unsigned entry_inst = 0; /* the entry instruction */
+ int reg, offset;
+
+ PROC_FRAME_OFFSET (&temp_proc_desc) = 0; /* size of stack frame */
+ PROC_FRAME_ADJUST (&temp_proc_desc) = 0; /* offset of FP from SP */
+
+ for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS16_INSTLEN)
+ {
+ /* Save the previous instruction. If it's an EXTEND, we'll extract
+ the immediate offset extension from it in mips16_get_imm. */
+ prev_inst = inst;
+
+ /* Fetch and decode the instruction. */
+ inst = (unsigned short) mips_fetch_instruction (cur_pc);
+ if ((inst & 0xff00) == 0x6300 /* addiu sp */
+ || (inst & 0xff00) == 0xfb00) /* daddiu sp */
+ {
+ offset = mips16_get_imm (prev_inst, inst, 8, 8, 1);
+ if (offset < 0) /* negative stack adjustment? */
+ PROC_FRAME_OFFSET (&temp_proc_desc) -= offset;
+ else
+ /* Exit loop if a positive stack adjustment is found, which
+ usually means that the stack cleanup code in the function
+ epilogue is reached. */
+ break;
+ }
+ else if ((inst & 0xf800) == 0xd000) /* sw reg,n($sp) */
+ {
+ offset = mips16_get_imm (prev_inst, inst, 8, 4, 0);
+ reg = mips16_to_32_reg[(inst & 0x700) >> 8];
+ PROC_REG_MASK (&temp_proc_desc) |= (1 << reg);
+ set_reg_offset (reg, sp + offset);
+ }
+ else if ((inst & 0xff00) == 0xf900) /* sd reg,n($sp) */
+ {
+ offset = mips16_get_imm (prev_inst, inst, 5, 8, 0);
+ reg = mips16_to_32_reg[(inst & 0xe0) >> 5];
+ PROC_REG_MASK (&temp_proc_desc) |= (1 << reg);
+ set_reg_offset (reg, sp + offset);
+ }
+ else if ((inst & 0xff00) == 0x6200) /* sw $ra,n($sp) */
+ {
+ offset = mips16_get_imm (prev_inst, inst, 8, 4, 0);
+ PROC_REG_MASK (&temp_proc_desc) |= (1 << RA_REGNUM);
+ set_reg_offset (RA_REGNUM, sp + offset);
+ }
+ else if ((inst & 0xff00) == 0xfa00) /* sd $ra,n($sp) */
+ {
+ offset = mips16_get_imm (prev_inst, inst, 8, 8, 0);
+ PROC_REG_MASK (&temp_proc_desc) |= (1 << RA_REGNUM);
+ set_reg_offset (RA_REGNUM, sp + offset);
+ }
+ else if (inst == 0x673d) /* move $s1, $sp */
+ {
+ frame_addr = sp;
+ PROC_FRAME_REG (&temp_proc_desc) = 17;
+ }
+ else if ((inst & 0xff00) == 0x0100) /* addiu $s1,sp,n */
+ {
+ offset = mips16_get_imm (prev_inst, inst, 8, 4, 0);
+ frame_addr = sp + offset;
+ PROC_FRAME_REG (&temp_proc_desc) = 17;
+ PROC_FRAME_ADJUST (&temp_proc_desc) = offset;
+ }
+ else if ((inst & 0xFF00) == 0xd900) /* sw reg,offset($s1) */
+ {
+ offset = mips16_get_imm (prev_inst, inst, 5, 4, 0);
+ reg = mips16_to_32_reg[(inst & 0xe0) >> 5];
+ PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
+ set_reg_offset (reg, frame_addr + offset);
+ }
+ else if ((inst & 0xFF00) == 0x7900) /* sd reg,offset($s1) */
+ {
+ offset = mips16_get_imm (prev_inst, inst, 5, 8, 0);
+ reg = mips16_to_32_reg[(inst & 0xe0) >> 5];
+ PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
+ set_reg_offset (reg, frame_addr + offset);
+ }
+ else if ((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700) /* entry */
+ entry_inst = inst; /* save for later processing */
+ else if ((inst & 0xf800) == 0x1800) /* jal(x) */
+ cur_pc += MIPS16_INSTLEN; /* 32-bit instruction */
+ }
+
+ /* The entry instruction is typically the first instruction in a function,
+ and it stores registers at offsets relative to the value of the old SP
+ (before the prologue). But the value of the sp parameter to this
+ function is the new SP (after the prologue has been executed). So we
+ can't calculate those offsets until we've seen the entire prologue,
+ and can calculate what the old SP must have been. */
+ if (entry_inst != 0)
+ {
+ int areg_count = (entry_inst >> 8) & 7;
+ int sreg_count = (entry_inst >> 6) & 3;
+
+ /* The entry instruction always subtracts 32 from the SP. */
+ PROC_FRAME_OFFSET (&temp_proc_desc) += 32;
+
+ /* Now we can calculate what the SP must have been at the
+ start of the function prologue. */
+ sp += PROC_FRAME_OFFSET (&temp_proc_desc);
+
+ /* Check if a0-a3 were saved in the caller's argument save area. */
+ for (reg = 4, offset = 0; reg < areg_count + 4; reg++)
+ {
+ PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
+ set_reg_offset (reg, sp + offset);
+ offset += MIPS_SAVED_REGSIZE;
+ }
+
+ /* Check if the ra register was pushed on the stack. */
+ offset = -4;
+ if (entry_inst & 0x20)
+ {
+ PROC_REG_MASK (&temp_proc_desc) |= 1 << RA_REGNUM;
+ set_reg_offset (RA_REGNUM, sp + offset);
+ offset -= MIPS_SAVED_REGSIZE;
+ }
+
+ /* Check if the s0 and s1 registers were pushed on the stack. */
+ for (reg = 16; reg < sreg_count + 16; reg++)
+ {
+ PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
+ set_reg_offset (reg, sp + offset);
+ offset -= MIPS_SAVED_REGSIZE;
+ }
+ }
+}
+
+static void
+mips32_heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
+ struct frame_info *next_frame, CORE_ADDR sp)
+{
+ CORE_ADDR cur_pc;
+ CORE_ADDR frame_addr = 0; /* Value of $r30. Used by gcc for frame-pointer */
+restart:
+ memset (temp_saved_regs, '\0', SIZEOF_FRAME_SAVED_REGS);
+ PROC_FRAME_OFFSET (&temp_proc_desc) = 0;
+ PROC_FRAME_ADJUST (&temp_proc_desc) = 0; /* offset of FP from SP */
+ for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS_INSTLEN)
+ {
+ unsigned long inst, high_word, low_word;
+ int reg;
+
+ /* Fetch the instruction. */
+ inst = (unsigned long) mips_fetch_instruction (cur_pc);
+
+ /* Save some code by pre-extracting some useful fields. */
+ high_word = (inst >> 16) & 0xffff;
+ low_word = inst & 0xffff;
+ reg = high_word & 0x1f;
+
+ if (high_word == 0x27bd /* addiu $sp,$sp,-i */
+ || high_word == 0x23bd /* addi $sp,$sp,-i */
+ || high_word == 0x67bd) /* daddiu $sp,$sp,-i */
+ {
+ if (low_word & 0x8000) /* negative stack adjustment? */
+ PROC_FRAME_OFFSET (&temp_proc_desc) += 0x10000 - low_word;
+ else
+ /* Exit loop if a positive stack adjustment is found, which
+ usually means that the stack cleanup code in the function
+ epilogue is reached. */
+ break;
+ }
+ else if ((high_word & 0xFFE0) == 0xafa0) /* sw reg,offset($sp) */
+ {
+ PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
+ set_reg_offset (reg, sp + low_word);
+ }
+ else if ((high_word & 0xFFE0) == 0xffa0) /* sd reg,offset($sp) */
+ {
+ /* Irix 6.2 N32 ABI uses sd instructions for saving $gp and $ra,
+ but the register size used is only 32 bits. Make the address
+ for the saved register point to the lower 32 bits. */
+ PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
+ set_reg_offset (reg, sp + low_word + 8 - MIPS_REGSIZE);
+ }
+ else if (high_word == 0x27be) /* addiu $30,$sp,size */
+ {
+ /* Old gcc frame, r30 is virtual frame pointer. */
+ if ((long) low_word != PROC_FRAME_OFFSET (&temp_proc_desc))
+ frame_addr = sp + low_word;
+ else if (PROC_FRAME_REG (&temp_proc_desc) == SP_REGNUM)
+ {
+ unsigned alloca_adjust;
+ PROC_FRAME_REG (&temp_proc_desc) = 30;
+ frame_addr = read_next_frame_reg (next_frame, 30);
+ alloca_adjust = (unsigned) (frame_addr - (sp + low_word));
+ if (alloca_adjust > 0)
+ {
+ /* FP > SP + frame_size. This may be because
+ * of an alloca or somethings similar.
+ * Fix sp to "pre-alloca" value, and try again.
+ */
+ sp += alloca_adjust;
+ goto restart;
+ }
+ }
+ }
+ /* move $30,$sp. With different versions of gas this will be either
+ `addu $30,$sp,$zero' or `or $30,$sp,$zero' or `daddu 30,sp,$0'.
+ Accept any one of these. */
+ else if (inst == 0x03A0F021 || inst == 0x03a0f025 || inst == 0x03a0f02d)
+ {
+ /* New gcc frame, virtual frame pointer is at r30 + frame_size. */
+ if (PROC_FRAME_REG (&temp_proc_desc) == SP_REGNUM)
+ {
+ unsigned alloca_adjust;
+ PROC_FRAME_REG (&temp_proc_desc) = 30;
+ frame_addr = read_next_frame_reg (next_frame, 30);
+ alloca_adjust = (unsigned) (frame_addr - sp);
+ if (alloca_adjust > 0)
+ {
+ /* FP > SP + frame_size. This may be because
+ * of an alloca or somethings similar.
+ * Fix sp to "pre-alloca" value, and try again.
+ */
+ sp += alloca_adjust;
+ goto restart;
+ }
+ }
+ }
+ else if ((high_word & 0xFFE0) == 0xafc0) /* sw reg,offset($30) */
+ {
+ PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
+ set_reg_offset (reg, frame_addr + low_word);
+ }
+ }
+}
+
+static mips_extra_func_info_t
+heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
+ struct frame_info *next_frame, int cur_frame)
+{
+ CORE_ADDR sp;
+
+ if (cur_frame)
+ sp = read_next_frame_reg (next_frame, SP_REGNUM);
+ else
+ sp = 0;
+
+ if (start_pc == 0)
+ return NULL;
+ memset (&temp_proc_desc, '\0', sizeof (temp_proc_desc));
+ memset (&temp_saved_regs, '\0', SIZEOF_FRAME_SAVED_REGS);
+ PROC_LOW_ADDR (&temp_proc_desc) = start_pc;
+ PROC_FRAME_REG (&temp_proc_desc) = SP_REGNUM;
+ PROC_PC_REG (&temp_proc_desc) = RA_REGNUM;
+
+ if (start_pc + 200 < limit_pc)
+ limit_pc = start_pc + 200;
+ if (pc_is_mips16 (start_pc))
+ mips16_heuristic_proc_desc (start_pc, limit_pc, next_frame, sp);
+ else
+ mips32_heuristic_proc_desc (start_pc, limit_pc, next_frame, sp);
+ return &temp_proc_desc;
+}
+
+static mips_extra_func_info_t
+non_heuristic_proc_desc (CORE_ADDR pc, CORE_ADDR *addrptr)
+{
+ CORE_ADDR startaddr;
+ mips_extra_func_info_t proc_desc;
+ struct block *b = block_for_pc (pc);
+ struct symbol *sym;
+
+ find_pc_partial_function (pc, NULL, &startaddr, NULL);
+ if (addrptr)
+ *addrptr = startaddr;
+ if (b == NULL || PC_IN_CALL_DUMMY (pc, 0, 0))
+ sym = NULL;
+ else
+ {
+ if (startaddr > BLOCK_START (b))
+ /* This is the "pathological" case referred to in a comment in
+ print_frame_info. It might be better to move this check into
+ symbol reading. */
+ sym = NULL;
+ else
+ sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE, 0, NULL);
+ }
+
+ /* If we never found a PDR for this function in symbol reading, then
+ examine prologues to find the information. */
+ if (sym)
+ {
+ proc_desc = (mips_extra_func_info_t) SYMBOL_VALUE (sym);
+ if (PROC_FRAME_REG (proc_desc) == -1)
+ return NULL;
+ else
+ return proc_desc;
+ }
+ else
+ return NULL;
+}
+
+
+static mips_extra_func_info_t
+find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame, int cur_frame)
+{
+ mips_extra_func_info_t proc_desc;
+ CORE_ADDR startaddr;
+
+ proc_desc = non_heuristic_proc_desc (pc, &startaddr);
+
+ if (proc_desc)
+ {
+ /* IF this is the topmost frame AND
+ * (this proc does not have debugging information OR
+ * the PC is in the procedure prologue)
+ * THEN create a "heuristic" proc_desc (by analyzing
+ * the actual code) to replace the "official" proc_desc.
+ */
+ if (next_frame == NULL)
+ {
+ struct symtab_and_line val;
+ struct symbol *proc_symbol =
+ PROC_DESC_IS_DUMMY (proc_desc) ? 0 : PROC_SYMBOL (proc_desc);
+
+ if (proc_symbol)
+ {
+ val = find_pc_line (BLOCK_START
+ (SYMBOL_BLOCK_VALUE (proc_symbol)),
+ 0);
+ val.pc = val.end ? val.end : pc;
+ }
+ if (!proc_symbol || pc < val.pc)
+ {
+ mips_extra_func_info_t found_heuristic =
+ heuristic_proc_desc (PROC_LOW_ADDR (proc_desc),
+ pc, next_frame, cur_frame);
+ if (found_heuristic)
+ proc_desc = found_heuristic;
+ }
+ }
+ }
+ else
+ {
+ /* Is linked_proc_desc_table really necessary? It only seems to be used
+ by procedure call dummys. However, the procedures being called ought
+ to have their own proc_descs, and even if they don't,
+ heuristic_proc_desc knows how to create them! */
+
+ register struct linked_proc_info *link;
+
+ for (link = linked_proc_desc_table; link; link = link->next)
+ if (PROC_LOW_ADDR (&link->info) <= pc
+ && PROC_HIGH_ADDR (&link->info) > pc)
+ return &link->info;
+
+ if (startaddr == 0)
+ startaddr = heuristic_proc_start (pc);
+
+ proc_desc =
+ heuristic_proc_desc (startaddr, pc, next_frame, cur_frame);
+ }
+ return proc_desc;
+}
+
+static CORE_ADDR
+get_frame_pointer (struct frame_info *frame,
+ mips_extra_func_info_t proc_desc)
+{
+ return ADDR_BITS_REMOVE (
+ read_next_frame_reg (frame, PROC_FRAME_REG (proc_desc)) +
+ PROC_FRAME_OFFSET (proc_desc) - PROC_FRAME_ADJUST (proc_desc));
+}
+
+mips_extra_func_info_t cached_proc_desc;
+
+CORE_ADDR
+mips_frame_chain (struct frame_info *frame)
+{
+ mips_extra_func_info_t proc_desc;
+ CORE_ADDR tmp;
+ CORE_ADDR saved_pc = FRAME_SAVED_PC (frame);
+
+ if (saved_pc == 0 || inside_entry_file (saved_pc))
+ return 0;
+
+ /* Check if the PC is inside a call stub. If it is, fetch the
+ PC of the caller of that stub. */
+ if ((tmp = mips_skip_stub (saved_pc)) != 0)
+ saved_pc = tmp;
+
+ /* Look up the procedure descriptor for this PC. */
+ proc_desc = find_proc_desc (saved_pc, frame, 1);
+ if (!proc_desc)
+ return 0;
+
+ cached_proc_desc = proc_desc;
+
+ /* If no frame pointer and frame size is zero, we must be at end
+ of stack (or otherwise hosed). If we don't check frame size,
+ we loop forever if we see a zero size frame. */
+ if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
+ && PROC_FRAME_OFFSET (proc_desc) == 0
+ /* The previous frame from a sigtramp frame might be frameless
+ and have frame size zero. */
+ && !frame->signal_handler_caller)
+ return 0;
+ else
+ return get_frame_pointer (frame, proc_desc);
+}
+
+void
+mips_init_extra_frame_info (int fromleaf, struct frame_info *fci)
+{
+ int regnum;
+
+ /* Use proc_desc calculated in frame_chain */
+ mips_extra_func_info_t proc_desc =
+ fci->next ? cached_proc_desc : find_proc_desc (fci->pc, fci->next, 1);
+
+ fci->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+
+ fci->saved_regs = NULL;
+ fci->extra_info->proc_desc =
+ proc_desc == &temp_proc_desc ? 0 : proc_desc;
+ if (proc_desc)
+ {
+ /* Fixup frame-pointer - only needed for top frame */
+ /* This may not be quite right, if proc has a real frame register.
+ Get the value of the frame relative sp, procedure might have been
+ interrupted by a signal at it's very start. */
+ if (fci->pc == PROC_LOW_ADDR (proc_desc)
+ && !PROC_DESC_IS_DUMMY (proc_desc))
+ fci->frame = read_next_frame_reg (fci->next, SP_REGNUM);
+ else
+ fci->frame = get_frame_pointer (fci->next, proc_desc);
+
+ if (proc_desc == &temp_proc_desc)
+ {
+ char *name;
+
+ /* Do not set the saved registers for a sigtramp frame,
+ mips_find_saved_registers will do that for us.
+ We can't use fci->signal_handler_caller, it is not yet set. */
+ find_pc_partial_function (fci->pc, &name,
+ (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
+ if (!PC_IN_SIGTRAMP (fci->pc, name))
+ {
+ frame_saved_regs_zalloc (fci);
+ memcpy (fci->saved_regs, temp_saved_regs, SIZEOF_FRAME_SAVED_REGS);
+ fci->saved_regs[PC_REGNUM]
+ = fci->saved_regs[RA_REGNUM];
+ }
+ }
+
+ /* hack: if argument regs are saved, guess these contain args */
+ /* assume we can't tell how many args for now */
+ fci->extra_info->num_args = -1;
+ for (regnum = MIPS_LAST_ARG_REGNUM; regnum >= A0_REGNUM; regnum--)
+ {
+ if (PROC_REG_MASK (proc_desc) & (1 << regnum))
+ {
+ fci->extra_info->num_args = regnum - A0_REGNUM + 1;
+ break;
+ }
+ }
+ }
+}
+
+/* MIPS stack frames are almost impenetrable. When execution stops,
+ we basically have to look at symbol information for the function
+ that we stopped in, which tells us *which* register (if any) is
+ the base of the frame pointer, and what offset from that register
+ the frame itself is at.
+
+ This presents a problem when trying to examine a stack in memory
+ (that isn't executing at the moment), using the "frame" command. We
+ don't have a PC, nor do we have any registers except SP.
+
+ This routine takes two arguments, SP and PC, and tries to make the
+ cached frames look as if these two arguments defined a frame on the
+ cache. This allows the rest of info frame to extract the important
+ arguments without difficulty. */
+
+struct frame_info *
+setup_arbitrary_frame (int argc, CORE_ADDR *argv)
+{
+ if (argc != 2)
+ error ("MIPS frame specifications require two arguments: sp and pc");
+
+ return create_new_frame (argv[0], argv[1]);
+}
+
+/* According to the current ABI, should the type be passed in a
+ floating-point register (assuming that there is space)? When there
+ is no FPU, FP are not even considered as possibile candidates for
+ FP registers and, consequently this returns false - forces FP
+ arguments into integer registers. */
+
+static int
+fp_register_arg_p (enum type_code typecode, struct type *arg_type)
+{
+ return ((typecode == TYPE_CODE_FLT
+ || (MIPS_EABI
+ && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
+ && TYPE_NFIELDS (arg_type) == 1
+ && TYPE_CODE (TYPE_FIELD_TYPE (arg_type, 0)) == TYPE_CODE_FLT))
+ && MIPS_FPU_TYPE != MIPS_FPU_NONE);
+}
+
+/* On o32, argument passing in GPRs depends on the alignment of the type being
+ passed. Return 1 if this type must be aligned to a doubleword boundary. */
+
+static int
+mips_type_needs_double_align (struct type *type)
+{
+ enum type_code typecode = TYPE_CODE (type);
+
+ if (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8)
+ return 1;
+ else if (typecode == TYPE_CODE_STRUCT)
+ {
+ if (TYPE_NFIELDS (type) < 1)
+ return 0;
+ return mips_type_needs_double_align (TYPE_FIELD_TYPE (type, 0));
+ }
+ else if (typecode == TYPE_CODE_UNION)
+ {
+ int i, n;
+
+ n = TYPE_NFIELDS (type);
+ for (i = 0; i < n; i++)
+ if (mips_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
+ return 1;
+ return 0;
+ }
+ return 0;
+}
+
+CORE_ADDR
+mips_push_arguments (int nargs,
+ struct value **args,
+ CORE_ADDR sp,
+ int struct_return,
+ CORE_ADDR struct_addr)
+{
+ int argreg;
+ int float_argreg;
+ int argnum;
+ int len = 0;
+ int stack_offset = 0;
+
+ /* Macros to round N up or down to the next A boundary; A must be
+ a power of two. */
+#define ROUND_DOWN(n,a) ((n) & ~((a)-1))
+#define ROUND_UP(n,a) (((n)+(a)-1) & ~((a)-1))
+
+ /* First ensure that the stack and structure return address (if any)
+ are properly aligned. The stack has to be at least 64-bit aligned
+ even on 32-bit machines, because doubles must be 64-bit aligned.
+ On at least one MIPS variant, stack frames need to be 128-bit
+ aligned, so we round to this widest known alignment. */
+ sp = ROUND_DOWN (sp, 16);
+ struct_addr = ROUND_DOWN (struct_addr, 16);
+
+ /* Now make space on the stack for the args. We allocate more
+ than necessary for EABI, because the first few arguments are
+ passed in registers, but that's OK. */
+ for (argnum = 0; argnum < nargs; argnum++)
+ len += ROUND_UP (TYPE_LENGTH (VALUE_TYPE (args[argnum])), MIPS_STACK_ARGSIZE);
+ sp -= ROUND_UP (len, 16);
+
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stdlog, "mips_push_arguments: sp=0x%lx allocated %d\n",
+ (long) sp, ROUND_UP (len, 16));
+
+ /* Initialize the integer and float register pointers. */
+ argreg = A0_REGNUM;
+ float_argreg = FPA0_REGNUM;
+
+ /* the struct_return pointer occupies the first parameter-passing reg */
+ if (struct_return)
+ {
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "mips_push_arguments: struct_return reg=%d 0x%lx\n",
+ argreg, (long) struct_addr);
+ write_register (argreg++, struct_addr);
+ if (MIPS_REGS_HAVE_HOME_P)
+ stack_offset += MIPS_STACK_ARGSIZE;
+ }
+
+ /* Now load as many as possible of the first arguments into
+ registers, and push the rest onto the stack. Loop thru args
+ from first to last. */
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ char *val;
+ char valbuf[MAX_REGISTER_RAW_SIZE];
+ struct value *arg = args[argnum];
+ struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+ int len = TYPE_LENGTH (arg_type);
+ enum type_code typecode = TYPE_CODE (arg_type);
+
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "mips_push_arguments: %d len=%d type=%d",
+ argnum + 1, len, (int) typecode);
+
+ /* The EABI passes structures that do not fit in a register by
+ reference. In all other cases, pass the structure by value. */
+ if (MIPS_EABI
+ && len > MIPS_SAVED_REGSIZE
+ && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
+ {
+ store_address (valbuf, MIPS_SAVED_REGSIZE, VALUE_ADDRESS (arg));
+ typecode = TYPE_CODE_PTR;
+ len = MIPS_SAVED_REGSIZE;
+ val = valbuf;
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stdlog, " push");
+ }
+ else
+ val = (char *) VALUE_CONTENTS (arg);
+
+ /* 32-bit ABIs always start floating point arguments in an
+ even-numbered floating point register. Round the FP register
+ up before the check to see if there are any FP registers
+ left. Non MIPS_EABI targets also pass the FP in the integer
+ registers so also round up normal registers. */
+ if (!FP_REGISTER_DOUBLE
+ && fp_register_arg_p (typecode, arg_type))
+ {
+ if ((float_argreg & 1))
+ float_argreg++;
+ }
+
+ /* Floating point arguments passed in registers have to be
+ treated specially. On 32-bit architectures, doubles
+ are passed in register pairs; the even register gets
+ the low word, and the odd register gets the high word.
+ On non-EABI processors, the first two floating point arguments are
+ also copied to general registers, because MIPS16 functions
+ don't use float registers for arguments. This duplication of
+ arguments in general registers can't hurt non-MIPS16 functions
+ because those registers are normally skipped. */
+ /* MIPS_EABI squeezes a struct that contains a single floating
+ point value into an FP register instead of pushing it onto the
+ stack. */
+ if (fp_register_arg_p (typecode, arg_type)
+ && float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
+ {
+ if (!FP_REGISTER_DOUBLE && len == 8)
+ {
+ int low_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
+ unsigned long regval;
+
+ /* Write the low word of the double to the even register(s). */
+ regval = extract_unsigned_integer (val + low_offset, 4);
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
+ float_argreg, phex (regval, 4));
+ write_register (float_argreg++, regval);
+ if (!MIPS_EABI)
+ {
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
+ argreg, phex (regval, 4));
+ write_register (argreg++, regval);
+ }
+
+ /* Write the high word of the double to the odd register(s). */
+ regval = extract_unsigned_integer (val + 4 - low_offset, 4);
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
+ float_argreg, phex (regval, 4));
+ write_register (float_argreg++, regval);
+ if (!MIPS_EABI)
+ {
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
+ argreg, phex (regval, 4));
+ write_register (argreg++, regval);
+ }
+
+ }
+ else
+ {
+ /* This is a floating point value that fits entirely
+ in a single register. */
+ /* On 32 bit ABI's the float_argreg is further adjusted
+ above to ensure that it is even register aligned. */
+ LONGEST regval = extract_unsigned_integer (val, len);
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
+ float_argreg, phex (regval, len));
+ write_register (float_argreg++, regval);
+ if (!MIPS_EABI)
+ {
+ /* CAGNEY: 32 bit MIPS ABI's always reserve two FP
+ registers for each argument. The below is (my
+ guess) to ensure that the corresponding integer
+ register has reserved the same space. */
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
+ argreg, phex (regval, len));
+ write_register (argreg, regval);
+ argreg += FP_REGISTER_DOUBLE ? 1 : 2;
+ }
+ }
+ /* Reserve space for the FP register. */
+ if (MIPS_REGS_HAVE_HOME_P)
+ stack_offset += ROUND_UP (len, MIPS_STACK_ARGSIZE);
+ }
+ else
+ {
+ /* Copy the argument to general registers or the stack in
+ register-sized pieces. Large arguments are split between
+ registers and stack. */
+ /* Note: structs whose size is not a multiple of MIPS_REGSIZE
+ are treated specially: Irix cc passes them in registers
+ where gcc sometimes puts them on the stack. For maximum
+ compatibility, we will put them in both places. */
+ int odd_sized_struct = ((len > MIPS_SAVED_REGSIZE) &&
+ (len % MIPS_SAVED_REGSIZE != 0));
+ /* Structures should be aligned to eight bytes (even arg registers)
+ on MIPS_ABI_O32 if their first member has double precision. */
+ if (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_O32
+ && mips_type_needs_double_align (arg_type))
+ {
+ if ((argreg & 1))
+ argreg++;
+ }
+ /* Note: Floating-point values that didn't fit into an FP
+ register are only written to memory. */
+ while (len > 0)
+ {
+ /* Rememer if the argument was written to the stack. */
+ int stack_used_p = 0;
+ int partial_len = len < MIPS_SAVED_REGSIZE ? len : MIPS_SAVED_REGSIZE;
+
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stdlog, " -- partial=%d",
+ partial_len);
+
+ /* Write this portion of the argument to the stack. */
+ if (argreg > MIPS_LAST_ARG_REGNUM
+ || odd_sized_struct
+ || fp_register_arg_p (typecode, arg_type))
+ {
+ /* Should shorter than int integer values be
+ promoted to int before being stored? */
+ int longword_offset = 0;
+ CORE_ADDR addr;
+ stack_used_p = 1;
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ if (MIPS_STACK_ARGSIZE == 8 &&
+ (typecode == TYPE_CODE_INT ||
+ typecode == TYPE_CODE_PTR ||
+ typecode == TYPE_CODE_FLT) && len <= 4)
+ longword_offset = MIPS_STACK_ARGSIZE - len;
+ else if ((typecode == TYPE_CODE_STRUCT ||
+ typecode == TYPE_CODE_UNION) &&
+ TYPE_LENGTH (arg_type) < MIPS_STACK_ARGSIZE)
+ longword_offset = MIPS_STACK_ARGSIZE - len;
+ }
+
+ if (mips_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, " - stack_offset=0x%lx",
+ (long) stack_offset);
+ fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%lx",
+ (long) longword_offset);
+ }
+
+ addr = sp + stack_offset + longword_offset;
+
+ if (mips_debug)
+ {
+ int i;
+ fprintf_unfiltered (gdb_stdlog, " @0x%lx ", (long) addr);
+ for (i = 0; i < partial_len; i++)
+ {
+ fprintf_unfiltered (gdb_stdlog, "%02x", val[i] & 0xff);
+ }
+ }
+ write_memory (addr, val, partial_len);
+ }
+
+ /* Note!!! This is NOT an else clause. Odd sized
+ structs may go thru BOTH paths. Floating point
+ arguments will not. */
+ /* Write this portion of the argument to a general
+ purpose register. */
+ if (argreg <= MIPS_LAST_ARG_REGNUM
+ && !fp_register_arg_p (typecode, arg_type))
+ {
+ LONGEST regval = extract_unsigned_integer (val, partial_len);
+
+ /* A non-floating-point argument being passed in a
+ general register. If a struct or union, and if
+ the remaining length is smaller than the register
+ size, we have to adjust the register value on
+ big endian targets.
+
+ It does not seem to be necessary to do the
+ same for integral types.
+
+ Also don't do this adjustment on EABI and O64
+ binaries.
+
+ cagney/2001-07-23: gdb/179: Also, GCC, when
+ outputting LE O32 with sizeof (struct) <
+ MIPS_SAVED_REGSIZE, generates a left shift as
+ part of storing the argument in a register a
+ register (the left shift isn't generated when
+ sizeof (struct) >= MIPS_SAVED_REGSIZE). Since it
+ is quite possible that this is GCC contradicting
+ the LE/O32 ABI, GDB has not been adjusted to
+ accommodate this. Either someone needs to
+ demonstrate that the LE/O32 ABI specifies such a
+ left shift OR this new ABI gets identified as
+ such and GDB gets tweaked accordingly. */
+
+ if (!MIPS_EABI
+ && MIPS_SAVED_REGSIZE < 8
+ && TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ && partial_len < MIPS_SAVED_REGSIZE
+ && (typecode == TYPE_CODE_STRUCT ||
+ typecode == TYPE_CODE_UNION))
+ regval <<= ((MIPS_SAVED_REGSIZE - partial_len) *
+ TARGET_CHAR_BIT);
+
+ if (mips_debug)
+ fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
+ argreg,
+ phex (regval, MIPS_SAVED_REGSIZE));
+ write_register (argreg, regval);
+ argreg++;
+
+ /* If this is the old ABI, prevent subsequent floating
+ point arguments from being passed in floating point
+ registers. */
+ if (!MIPS_EABI)
+ float_argreg = MIPS_LAST_FP_ARG_REGNUM + 1;
+ }
+
+ len -= partial_len;
+ val += partial_len;
+
+ /* Compute the the offset into the stack at which we
+ will copy the next parameter.
+
+ In older ABIs, the caller reserved space for
+ registers that contained arguments. This was loosely
+ refered to as their "home". Consequently, space is
+ always allocated.
+
+ In the new EABI (and the NABI32), the stack_offset
+ only needs to be adjusted when it has been used.. */
+
+ if (MIPS_REGS_HAVE_HOME_P || stack_used_p)
+ stack_offset += ROUND_UP (partial_len, MIPS_STACK_ARGSIZE);
+ }
+ }
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stdlog, "\n");
+ }
+
+ /* Return adjusted stack pointer. */
+ return sp;
+}
+
+CORE_ADDR
+mips_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ /* Set the return address register to point to the entry
+ point of the program, where a breakpoint lies in wait. */
+ write_register (RA_REGNUM, CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+static void
+mips_push_register (CORE_ADDR * sp, int regno)
+{
+ char buffer[MAX_REGISTER_RAW_SIZE];
+ int regsize;
+ int offset;
+ if (MIPS_SAVED_REGSIZE < REGISTER_RAW_SIZE (regno))
+ {
+ regsize = MIPS_SAVED_REGSIZE;
+ offset = (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ ? REGISTER_RAW_SIZE (regno) - MIPS_SAVED_REGSIZE
+ : 0);
+ }
+ else
+ {
+ regsize = REGISTER_RAW_SIZE (regno);
+ offset = 0;
+ }
+ *sp -= regsize;
+ read_register_gen (regno, buffer);
+ write_memory (*sp, buffer + offset, regsize);
+}
+
+/* MASK(i,j) == (1<<i) + (1<<(i+1)) + ... + (1<<j)). Assume i<=j<(MIPS_NUMREGS-1). */
+#define MASK(i,j) (((1 << ((j)+1))-1) ^ ((1 << (i))-1))
+
+void
+mips_push_dummy_frame (void)
+{
+ int ireg;
+ struct linked_proc_info *link = (struct linked_proc_info *)
+ xmalloc (sizeof (struct linked_proc_info));
+ mips_extra_func_info_t proc_desc = &link->info;
+ CORE_ADDR sp = ADDR_BITS_REMOVE (read_signed_register (SP_REGNUM));
+ CORE_ADDR old_sp = sp;
+ link->next = linked_proc_desc_table;
+ linked_proc_desc_table = link;
+
+/* FIXME! are these correct ? */
+#define PUSH_FP_REGNUM 16 /* must be a register preserved across calls */
+#define GEN_REG_SAVE_MASK MASK(1,16)|MASK(24,28)|(1<<(MIPS_NUMREGS-1))
+#define FLOAT_REG_SAVE_MASK MASK(0,19)
+#define FLOAT_SINGLE_REG_SAVE_MASK \
+ ((1<<18)|(1<<16)|(1<<14)|(1<<12)|(1<<10)|(1<<8)|(1<<6)|(1<<4)|(1<<2)|(1<<0))
+ /*
+ * The registers we must save are all those not preserved across
+ * procedure calls. Dest_Reg (see tm-mips.h) must also be saved.
+ * In addition, we must save the PC, PUSH_FP_REGNUM, MMLO/-HI
+ * and FP Control/Status registers.
+ *
+ *
+ * Dummy frame layout:
+ * (high memory)
+ * Saved PC
+ * Saved MMHI, MMLO, FPC_CSR
+ * Saved R31
+ * Saved R28
+ * ...
+ * Saved R1
+ * Saved D18 (i.e. F19, F18)
+ * ...
+ * Saved D0 (i.e. F1, F0)
+ * Argument build area and stack arguments written via mips_push_arguments
+ * (low memory)
+ */
+
+ /* Save special registers (PC, MMHI, MMLO, FPC_CSR) */
+ PROC_FRAME_REG (proc_desc) = PUSH_FP_REGNUM;
+ PROC_FRAME_OFFSET (proc_desc) = 0;
+ PROC_FRAME_ADJUST (proc_desc) = 0;
+ mips_push_register (&sp, PC_REGNUM);
+ mips_push_register (&sp, HI_REGNUM);
+ mips_push_register (&sp, LO_REGNUM);
+ mips_push_register (&sp, MIPS_FPU_TYPE == MIPS_FPU_NONE ? 0 : FCRCS_REGNUM);
+
+ /* Save general CPU registers */
+ PROC_REG_MASK (proc_desc) = GEN_REG_SAVE_MASK;
+ /* PROC_REG_OFFSET is the offset of the first saved register from FP. */
+ PROC_REG_OFFSET (proc_desc) = sp - old_sp - MIPS_SAVED_REGSIZE;
+ for (ireg = 32; --ireg >= 0;)
+ if (PROC_REG_MASK (proc_desc) & (1 << ireg))
+ mips_push_register (&sp, ireg);
+
+ /* Save floating point registers starting with high order word */
+ PROC_FREG_MASK (proc_desc) =
+ MIPS_FPU_TYPE == MIPS_FPU_DOUBLE ? FLOAT_REG_SAVE_MASK
+ : MIPS_FPU_TYPE == MIPS_FPU_SINGLE ? FLOAT_SINGLE_REG_SAVE_MASK : 0;
+ /* PROC_FREG_OFFSET is the offset of the first saved *double* register
+ from FP. */
+ PROC_FREG_OFFSET (proc_desc) = sp - old_sp - 8;
+ for (ireg = 32; --ireg >= 0;)
+ if (PROC_FREG_MASK (proc_desc) & (1 << ireg))
+ mips_push_register (&sp, ireg + FP0_REGNUM);
+
+ /* Update the frame pointer for the call dummy and the stack pointer.
+ Set the procedure's starting and ending addresses to point to the
+ call dummy address at the entry point. */
+ write_register (PUSH_FP_REGNUM, old_sp);
+ write_register (SP_REGNUM, sp);
+ PROC_LOW_ADDR (proc_desc) = CALL_DUMMY_ADDRESS ();
+ PROC_HIGH_ADDR (proc_desc) = CALL_DUMMY_ADDRESS () + 4;
+ SET_PROC_DESC_IS_DUMMY (proc_desc);
+ PROC_PC_REG (proc_desc) = RA_REGNUM;
+}
+
+void
+mips_pop_frame (void)
+{
+ register int regnum;
+ struct frame_info *frame = get_current_frame ();
+ CORE_ADDR new_sp = FRAME_FP (frame);
+
+ mips_extra_func_info_t proc_desc = frame->extra_info->proc_desc;
+
+ write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
+ if (frame->saved_regs == NULL)
+ mips_find_saved_regs (frame);
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ {
+ if (regnum != SP_REGNUM && regnum != PC_REGNUM
+ && frame->saved_regs[regnum])
+ write_register (regnum,
+ read_memory_integer (frame->saved_regs[regnum],
+ MIPS_SAVED_REGSIZE));
+ }
+ write_register (SP_REGNUM, new_sp);
+ flush_cached_frames ();
+
+ if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
+ {
+ struct linked_proc_info *pi_ptr, *prev_ptr;
+
+ for (pi_ptr = linked_proc_desc_table, prev_ptr = NULL;
+ pi_ptr != NULL;
+ prev_ptr = pi_ptr, pi_ptr = pi_ptr->next)
+ {
+ if (&pi_ptr->info == proc_desc)
+ break;
+ }
+
+ if (pi_ptr == NULL)
+ error ("Can't locate dummy extra frame info\n");
+
+ if (prev_ptr != NULL)
+ prev_ptr->next = pi_ptr->next;
+ else
+ linked_proc_desc_table = pi_ptr->next;
+
+ xfree (pi_ptr);
+
+ write_register (HI_REGNUM,
+ read_memory_integer (new_sp - 2 * MIPS_SAVED_REGSIZE,
+ MIPS_SAVED_REGSIZE));
+ write_register (LO_REGNUM,
+ read_memory_integer (new_sp - 3 * MIPS_SAVED_REGSIZE,
+ MIPS_SAVED_REGSIZE));
+ if (MIPS_FPU_TYPE != MIPS_FPU_NONE)
+ write_register (FCRCS_REGNUM,
+ read_memory_integer (new_sp - 4 * MIPS_SAVED_REGSIZE,
+ MIPS_SAVED_REGSIZE));
+ }
+}
+
+/* Floating point register management.
+
+ Background: MIPS1 & 2 fp registers are 32 bits wide. To support
+ 64bit operations, these early MIPS cpus treat fp register pairs
+ (f0,f1) as a single register (d0). Later MIPS cpu's have 64 bit fp
+ registers and offer a compatibility mode that emulates the MIPS2 fp
+ model. When operating in MIPS2 fp compat mode, later cpu's split
+ double precision floats into two 32-bit chunks and store them in
+ consecutive fp regs. To display 64-bit floats stored in this
+ fashion, we have to combine 32 bits from f0 and 32 bits from f1.
+ Throw in user-configurable endianness and you have a real mess.
+
+ The way this works is:
+ - If we are in 32-bit mode or on a 32-bit processor, then a 64-bit
+ double-precision value will be split across two logical registers.
+ The lower-numbered logical register will hold the low-order bits,
+ regardless of the processor's endianness.
+ - If we are on a 64-bit processor, and we are looking for a
+ single-precision value, it will be in the low ordered bits
+ of a 64-bit GPR (after mfc1, for example) or a 64-bit register
+ save slot in memory.
+ - If we are in 64-bit mode, everything is straightforward.
+
+ Note that this code only deals with "live" registers at the top of the
+ stack. We will attempt to deal with saved registers later, when
+ the raw/cooked register interface is in place. (We need a general
+ interface that can deal with dynamic saved register sizes -- fp
+ regs could be 32 bits wide in one frame and 64 on the frame above
+ and below). */
+
+static struct type *
+mips_float_register_type (void)
+{
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ return builtin_type_ieee_single_big;
+ else
+ return builtin_type_ieee_single_little;
+}
+
+static struct type *
+mips_double_register_type (void)
+{
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ return builtin_type_ieee_double_big;
+ else
+ return builtin_type_ieee_double_little;
+}
+
+/* Copy a 32-bit single-precision value from the current frame
+ into rare_buffer. */
+
+static void
+mips_read_fp_register_single (int regno, char *rare_buffer)
+{
+ int raw_size = REGISTER_RAW_SIZE (regno);
+ char *raw_buffer = alloca (raw_size);
+
+ if (!frame_register_read (selected_frame, regno, raw_buffer))
+ error ("can't read register %d (%s)", regno, REGISTER_NAME (regno));
+ if (raw_size == 8)
+ {
+ /* We have a 64-bit value for this register. Find the low-order
+ 32 bits. */
+ int offset;
+
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ offset = 4;
+ else
+ offset = 0;
+
+ memcpy (rare_buffer, raw_buffer + offset, 4);
+ }
+ else
+ {
+ memcpy (rare_buffer, raw_buffer, 4);
+ }
+}
+
+/* Copy a 64-bit double-precision value from the current frame into
+ rare_buffer. This may include getting half of it from the next
+ register. */
+
+static void
+mips_read_fp_register_double (int regno, char *rare_buffer)
+{
+ int raw_size = REGISTER_RAW_SIZE (regno);
+
+ if (raw_size == 8 && !mips2_fp_compat ())
+ {
+ /* We have a 64-bit value for this register, and we should use
+ all 64 bits. */
+ if (!frame_register_read (selected_frame, regno, rare_buffer))
+ error ("can't read register %d (%s)", regno, REGISTER_NAME (regno));
+ }
+ else
+ {
+ if ((regno - FP0_REGNUM) & 1)
+ internal_error (__FILE__, __LINE__,
+ "mips_read_fp_register_double: bad access to "
+ "odd-numbered FP register");
+
+ /* mips_read_fp_register_single will find the correct 32 bits from
+ each register. */
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ mips_read_fp_register_single (regno, rare_buffer + 4);
+ mips_read_fp_register_single (regno + 1, rare_buffer);
+ }
+ else
+ {
+ mips_read_fp_register_single (regno, rare_buffer);
+ mips_read_fp_register_single (regno + 1, rare_buffer + 4);
+ }
+ }
+}
+
+static void
+mips_print_register (int regnum, int all)
+{
+ char raw_buffer[MAX_REGISTER_RAW_SIZE];
+
+ /* Get the data in raw format. */
+ if (!frame_register_read (selected_frame, regnum, raw_buffer))
+ {
+ printf_filtered ("%s: [Invalid]", REGISTER_NAME (regnum));
+ return;
+ }
+
+ /* If we have a actual 32-bit floating point register (or we are in
+ 32-bit compatibility mode), and the register is even-numbered,
+ also print it as a double (spanning two registers). */
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT
+ && (REGISTER_RAW_SIZE (regnum) == 4
+ || mips2_fp_compat ())
+ && !((regnum - FP0_REGNUM) & 1))
+ {
+ char dbuffer[2 * MAX_REGISTER_RAW_SIZE];
+
+ mips_read_fp_register_double (regnum, dbuffer);
+
+ printf_filtered ("(d%d: ", regnum - FP0_REGNUM);
+ val_print (mips_double_register_type (), dbuffer, 0, 0,
+ gdb_stdout, 0, 1, 0, Val_pretty_default);
+ printf_filtered ("); ");
+ }
+ fputs_filtered (REGISTER_NAME (regnum), gdb_stdout);
+
+ /* The problem with printing numeric register names (r26, etc.) is that
+ the user can't use them on input. Probably the best solution is to
+ fix it so that either the numeric or the funky (a2, etc.) names
+ are accepted on input. */
+ if (regnum < MIPS_NUMREGS)
+ printf_filtered ("(r%d): ", regnum);
+ else
+ printf_filtered (": ");
+
+ /* If virtual format is floating, print it that way. */
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
+ if (REGISTER_RAW_SIZE (regnum) == 8 && !mips2_fp_compat ())
+ {
+ /* We have a meaningful 64-bit value in this register. Show
+ it as a 32-bit float and a 64-bit double. */
+ int offset = 4 * (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG);
+
+ printf_filtered (" (float) ");
+ val_print (mips_float_register_type (), raw_buffer + offset, 0, 0,
+ gdb_stdout, 0, 1, 0, Val_pretty_default);
+ printf_filtered (", (double) ");
+ val_print (mips_double_register_type (), raw_buffer, 0, 0,
+ gdb_stdout, 0, 1, 0, Val_pretty_default);
+ }
+ else
+ val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0, 0,
+ gdb_stdout, 0, 1, 0, Val_pretty_default);
+ /* Else print as integer in hex. */
+ else
+ {
+ int offset;
+
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ offset = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
+ else
+ offset = 0;
+
+ print_scalar_formatted (raw_buffer + offset,
+ REGISTER_VIRTUAL_TYPE (regnum),
+ 'x', 0, gdb_stdout);
+ }
+}
+
+/* Replacement for generic do_registers_info.
+ Print regs in pretty columns. */
+
+static int
+do_fp_register_row (int regnum)
+{ /* do values for FP (float) regs */
+ char *raw_buffer;
+ double doub, flt1, flt2; /* doubles extracted from raw hex data */
+ int inv1, inv2, inv3;
+
+ raw_buffer = (char *) alloca (2 * REGISTER_RAW_SIZE (FP0_REGNUM));
+
+ if (REGISTER_RAW_SIZE (regnum) == 4 || mips2_fp_compat ())
+ {
+ /* 4-byte registers: we can fit two registers per row. */
+ /* Also print every pair of 4-byte regs as an 8-byte double. */
+ mips_read_fp_register_single (regnum, raw_buffer);
+ flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1);
+
+ mips_read_fp_register_single (regnum + 1, raw_buffer);
+ flt2 = unpack_double (mips_float_register_type (), raw_buffer, &inv2);
+
+ mips_read_fp_register_double (regnum, raw_buffer);
+ doub = unpack_double (mips_double_register_type (), raw_buffer, &inv3);
+
+ printf_filtered (" %-5s", REGISTER_NAME (regnum));
+ if (inv1)
+ printf_filtered (": <invalid float>");
+ else
+ printf_filtered ("%-17.9g", flt1);
+
+ printf_filtered (" %-5s", REGISTER_NAME (regnum + 1));
+ if (inv2)
+ printf_filtered (": <invalid float>");
+ else
+ printf_filtered ("%-17.9g", flt2);
+
+ printf_filtered (" dbl: ");
+ if (inv3)
+ printf_filtered ("<invalid double>");
+ else
+ printf_filtered ("%-24.17g", doub);
+ printf_filtered ("\n");
+
+ /* may want to do hex display here (future enhancement) */
+ regnum += 2;
+ }
+ else
+ {
+ /* Eight byte registers: print each one as float AND as double. */
+ mips_read_fp_register_single (regnum, raw_buffer);
+ flt1 = unpack_double (mips_double_register_type (), raw_buffer, &inv1);
+
+ mips_read_fp_register_double (regnum, raw_buffer);
+ doub = unpack_double (mips_double_register_type (), raw_buffer, &inv3);
+
+ printf_filtered (" %-5s: ", REGISTER_NAME (regnum));
+ if (inv1)
+ printf_filtered ("<invalid float>");
+ else
+ printf_filtered ("flt: %-17.9g", flt1);
+
+ printf_filtered (" dbl: ");
+ if (inv3)
+ printf_filtered ("<invalid double>");
+ else
+ printf_filtered ("%-24.17g", doub);
+
+ printf_filtered ("\n");
+ /* may want to do hex display here (future enhancement) */
+ regnum++;
+ }
+ return regnum;
+}
+
+/* Print a row's worth of GP (int) registers, with name labels above */
+
+static int
+do_gp_register_row (int regnum)
+{
+ /* do values for GP (int) regs */
+ char raw_buffer[MAX_REGISTER_RAW_SIZE];
+ int ncols = (MIPS_REGSIZE == 8 ? 4 : 8); /* display cols per row */
+ int col, byte;
+ int start_regnum = regnum;
+ int numregs = NUM_REGS;
+
+
+ /* For GP registers, we print a separate row of names above the vals */
+ printf_filtered (" ");
+ for (col = 0; col < ncols && regnum < numregs; regnum++)
+ {
+ if (*REGISTER_NAME (regnum) == '\0')
+ continue; /* unused register */
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
+ break; /* end the row: reached FP register */
+ printf_filtered (MIPS_REGSIZE == 8 ? "%17s" : "%9s",
+ REGISTER_NAME (regnum));
+ col++;
+ }
+ printf_filtered (start_regnum < MIPS_NUMREGS ? "\n R%-4d" : "\n ",
+ start_regnum); /* print the R0 to R31 names */
+
+ regnum = start_regnum; /* go back to start of row */
+ /* now print the values in hex, 4 or 8 to the row */
+ for (col = 0; col < ncols && regnum < numregs; regnum++)
+ {
+ if (*REGISTER_NAME (regnum) == '\0')
+ continue; /* unused register */
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
+ break; /* end row: reached FP register */
+ /* OK: get the data in raw format. */
+ if (!frame_register_read (selected_frame, regnum, raw_buffer))
+ error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
+ /* pad small registers */
+ for (byte = 0; byte < (MIPS_REGSIZE - REGISTER_VIRTUAL_SIZE (regnum)); byte++)
+ printf_filtered (" ");
+ /* Now print the register value in hex, endian order. */
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
+ byte < REGISTER_RAW_SIZE (regnum);
+ byte++)
+ printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
+ else
+ for (byte = REGISTER_VIRTUAL_SIZE (regnum) - 1;
+ byte >= 0;
+ byte--)
+ printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
+ printf_filtered (" ");
+ col++;
+ }
+ if (col > 0) /* ie. if we actually printed anything... */
+ printf_filtered ("\n");
+
+ return regnum;
+}
+
+/* MIPS_DO_REGISTERS_INFO(): called by "info register" command */
+
+void
+mips_do_registers_info (int regnum, int fpregs)
+{
+ if (regnum != -1) /* do one specified register */
+ {
+ if (*(REGISTER_NAME (regnum)) == '\0')
+ error ("Not a valid register for the current processor type");
+
+ mips_print_register (regnum, 0);
+ printf_filtered ("\n");
+ }
+ else
+ /* do all (or most) registers */
+ {
+ regnum = 0;
+ while (regnum < NUM_REGS)
+ {
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
+ if (fpregs) /* true for "INFO ALL-REGISTERS" command */
+ regnum = do_fp_register_row (regnum); /* FP regs */
+ else
+ regnum += MIPS_NUMREGS; /* skip floating point regs */
+ else
+ regnum = do_gp_register_row (regnum); /* GP (int) regs */
+ }
+ }
+}
+
+/* Return number of args passed to a frame. described by FIP.
+ Can return -1, meaning no way to tell. */
+
+int
+mips_frame_num_args (struct frame_info *frame)
+{
+ return -1;
+}
+
+/* Is this a branch with a delay slot? */
+
+static int is_delayed (unsigned long);
+
+static int
+is_delayed (unsigned long insn)
+{
+ int i;
+ for (i = 0; i < NUMOPCODES; ++i)
+ if (mips_opcodes[i].pinfo != INSN_MACRO
+ && (insn & mips_opcodes[i].mask) == mips_opcodes[i].match)
+ break;
+ return (i < NUMOPCODES
+ && (mips_opcodes[i].pinfo & (INSN_UNCOND_BRANCH_DELAY
+ | INSN_COND_BRANCH_DELAY
+ | INSN_COND_BRANCH_LIKELY)));
+}
+
+int
+mips_step_skips_delay (CORE_ADDR pc)
+{
+ char buf[MIPS_INSTLEN];
+
+ /* There is no branch delay slot on MIPS16. */
+ if (pc_is_mips16 (pc))
+ return 0;
+
+ if (target_read_memory (pc, buf, MIPS_INSTLEN) != 0)
+ /* If error reading memory, guess that it is not a delayed branch. */
+ return 0;
+ return is_delayed ((unsigned long) extract_unsigned_integer (buf, MIPS_INSTLEN));
+}
+
+
+/* Skip the PC past function prologue instructions (32-bit version).
+ This is a helper function for mips_skip_prologue. */
+
+static CORE_ADDR
+mips32_skip_prologue (CORE_ADDR pc)
+{
+ t_inst inst;
+ CORE_ADDR end_pc;
+ int seen_sp_adjust = 0;
+ int load_immediate_bytes = 0;
+
+ /* Skip the typical prologue instructions. These are the stack adjustment
+ instruction and the instructions that save registers on the stack
+ or in the gcc frame. */
+ for (end_pc = pc + 100; pc < end_pc; pc += MIPS_INSTLEN)
+ {
+ unsigned long high_word;
+
+ inst = mips_fetch_instruction (pc);
+ high_word = (inst >> 16) & 0xffff;
+
+ if (high_word == 0x27bd /* addiu $sp,$sp,offset */
+ || high_word == 0x67bd) /* daddiu $sp,$sp,offset */
+ seen_sp_adjust = 1;
+ else if (inst == 0x03a1e823 || /* subu $sp,$sp,$at */
+ inst == 0x03a8e823) /* subu $sp,$sp,$t0 */
+ seen_sp_adjust = 1;
+ else if (((inst & 0xFFE00000) == 0xAFA00000 /* sw reg,n($sp) */
+ || (inst & 0xFFE00000) == 0xFFA00000) /* sd reg,n($sp) */
+ && (inst & 0x001F0000)) /* reg != $zero */
+ continue;
+
+ else if ((inst & 0xFFE00000) == 0xE7A00000) /* swc1 freg,n($sp) */
+ continue;
+ else if ((inst & 0xF3E00000) == 0xA3C00000 && (inst & 0x001F0000))
+ /* sx reg,n($s8) */
+ continue; /* reg != $zero */
+
+ /* move $s8,$sp. With different versions of gas this will be either
+ `addu $s8,$sp,$zero' or `or $s8,$sp,$zero' or `daddu s8,sp,$0'.
+ Accept any one of these. */
+ else if (inst == 0x03A0F021 || inst == 0x03a0f025 || inst == 0x03a0f02d)
+ continue;
+
+ else if ((inst & 0xFF9F07FF) == 0x00800021) /* move reg,$a0-$a3 */
+ continue;
+ else if (high_word == 0x3c1c) /* lui $gp,n */
+ continue;
+ else if (high_word == 0x279c) /* addiu $gp,$gp,n */
+ continue;
+ else if (inst == 0x0399e021 /* addu $gp,$gp,$t9 */
+ || inst == 0x033ce021) /* addu $gp,$t9,$gp */
+ continue;
+ /* The following instructions load $at or $t0 with an immediate
+ value in preparation for a stack adjustment via
+ subu $sp,$sp,[$at,$t0]. These instructions could also initialize
+ a local variable, so we accept them only before a stack adjustment
+ instruction was seen. */
+ else if (!seen_sp_adjust)
+ {
+ if (high_word == 0x3c01 || /* lui $at,n */
+ high_word == 0x3c08) /* lui $t0,n */
+ {
+ load_immediate_bytes += MIPS_INSTLEN; /* FIXME!! */
+ continue;
+ }
+ else if (high_word == 0x3421 || /* ori $at,$at,n */
+ high_word == 0x3508 || /* ori $t0,$t0,n */
+ high_word == 0x3401 || /* ori $at,$zero,n */
+ high_word == 0x3408) /* ori $t0,$zero,n */
+ {
+ load_immediate_bytes += MIPS_INSTLEN; /* FIXME!! */
+ continue;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+
+ /* In a frameless function, we might have incorrectly
+ skipped some load immediate instructions. Undo the skipping
+ if the load immediate was not followed by a stack adjustment. */
+ if (load_immediate_bytes && !seen_sp_adjust)
+ pc -= load_immediate_bytes;
+ return pc;
+}
+
+/* Skip the PC past function prologue instructions (16-bit version).
+ This is a helper function for mips_skip_prologue. */
+
+static CORE_ADDR
+mips16_skip_prologue (CORE_ADDR pc)
+{
+ CORE_ADDR end_pc;
+ int extend_bytes = 0;
+ int prev_extend_bytes;
+
+ /* Table of instructions likely to be found in a function prologue. */
+ static struct
+ {
+ unsigned short inst;
+ unsigned short mask;
+ }
+ table[] =
+ {
+ {
+ 0x6300, 0xff00
+ }
+ , /* addiu $sp,offset */
+ {
+ 0xfb00, 0xff00
+ }
+ , /* daddiu $sp,offset */
+ {
+ 0xd000, 0xf800
+ }
+ , /* sw reg,n($sp) */
+ {
+ 0xf900, 0xff00
+ }
+ , /* sd reg,n($sp) */
+ {
+ 0x6200, 0xff00
+ }
+ , /* sw $ra,n($sp) */
+ {
+ 0xfa00, 0xff00
+ }
+ , /* sd $ra,n($sp) */
+ {
+ 0x673d, 0xffff
+ }
+ , /* move $s1,sp */
+ {
+ 0xd980, 0xff80
+ }
+ , /* sw $a0-$a3,n($s1) */
+ {
+ 0x6704, 0xff1c
+ }
+ , /* move reg,$a0-$a3 */
+ {
+ 0xe809, 0xf81f
+ }
+ , /* entry pseudo-op */
+ {
+ 0x0100, 0xff00
+ }
+ , /* addiu $s1,$sp,n */
+ {
+ 0, 0
+ } /* end of table marker */
+ };
+
+ /* Skip the typical prologue instructions. These are the stack adjustment
+ instruction and the instructions that save registers on the stack
+ or in the gcc frame. */
+ for (end_pc = pc + 100; pc < end_pc; pc += MIPS16_INSTLEN)
+ {
+ unsigned short inst;
+ int i;
+
+ inst = mips_fetch_instruction (pc);
+
+ /* Normally we ignore an extend instruction. However, if it is
+ not followed by a valid prologue instruction, we must adjust
+ the pc back over the extend so that it won't be considered
+ part of the prologue. */
+ if ((inst & 0xf800) == 0xf000) /* extend */
+ {
+ extend_bytes = MIPS16_INSTLEN;
+ continue;
+ }
+ prev_extend_bytes = extend_bytes;
+ extend_bytes = 0;
+
+ /* Check for other valid prologue instructions besides extend. */
+ for (i = 0; table[i].mask != 0; i++)
+ if ((inst & table[i].mask) == table[i].inst) /* found, get out */
+ break;
+ if (table[i].mask != 0) /* it was in table? */
+ continue; /* ignore it */
+ else
+ /* non-prologue */
+ {
+ /* Return the current pc, adjusted backwards by 2 if
+ the previous instruction was an extend. */
+ return pc - prev_extend_bytes;
+ }
+ }
+ return pc;
+}
+
+/* To skip prologues, I use this predicate. Returns either PC itself
+ if the code at PC does not look like a function prologue; otherwise
+ returns an address that (if we're lucky) follows the prologue. If
+ LENIENT, then we must skip everything which is involved in setting
+ up the frame (it's OK to skip more, just so long as we don't skip
+ anything which might clobber the registers which are being saved.
+ We must skip more in the case where part of the prologue is in the
+ delay slot of a non-prologue instruction). */
+
+CORE_ADDR
+mips_skip_prologue (CORE_ADDR pc)
+{
+ /* See if we can determine the end of the prologue via the symbol table.
+ If so, then return either PC, or the PC after the prologue, whichever
+ is greater. */
+
+ CORE_ADDR post_prologue_pc = after_prologue (pc, NULL);
+
+ if (post_prologue_pc != 0)
+ return max (pc, post_prologue_pc);
+
+ /* Can't determine prologue from the symbol table, need to examine
+ instructions. */
+
+ if (pc_is_mips16 (pc))
+ return mips16_skip_prologue (pc);
+ else
+ return mips32_skip_prologue (pc);
+}
+
+/* Determine how a return value is stored within the MIPS register
+ file, given the return type `valtype'. */
+
+struct return_value_word
+{
+ int len;
+ int reg;
+ int reg_offset;
+ int buf_offset;
+};
+
+static void
+return_value_location (struct type *valtype,
+ struct return_value_word *hi,
+ struct return_value_word *lo)
+{
+ int len = TYPE_LENGTH (valtype);
+
+ if (TYPE_CODE (valtype) == TYPE_CODE_FLT
+ && ((MIPS_FPU_TYPE == MIPS_FPU_DOUBLE && (len == 4 || len == 8))
+ || (MIPS_FPU_TYPE == MIPS_FPU_SINGLE && len == 4)))
+ {
+ if (!FP_REGISTER_DOUBLE && len == 8)
+ {
+ /* We need to break a 64bit float in two 32 bit halves and
+ spread them across a floating-point register pair. */
+ lo->buf_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
+ hi->buf_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 0 : 4;
+ lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ && REGISTER_RAW_SIZE (FP0_REGNUM) == 8)
+ ? 4 : 0);
+ hi->reg_offset = lo->reg_offset;
+ lo->reg = FP0_REGNUM + 0;
+ hi->reg = FP0_REGNUM + 1;
+ lo->len = 4;
+ hi->len = 4;
+ }
+ else
+ {
+ /* The floating point value fits in a single floating-point
+ register. */
+ lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ && REGISTER_RAW_SIZE (FP0_REGNUM) == 8
+ && len == 4)
+ ? 4 : 0);
+ lo->reg = FP0_REGNUM;
+ lo->len = len;
+ lo->buf_offset = 0;
+ hi->len = 0;
+ hi->reg_offset = 0;
+ hi->buf_offset = 0;
+ hi->reg = 0;
+ }
+ }
+ else
+ {
+ /* Locate a result possibly spread across two registers. */
+ int regnum = 2;
+ lo->reg = regnum + 0;
+ hi->reg = regnum + 1;
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ && len < MIPS_SAVED_REGSIZE)
+ {
+ /* "un-left-justify" the value in the low register */
+ lo->reg_offset = MIPS_SAVED_REGSIZE - len;
+ lo->len = len;
+ hi->reg_offset = 0;
+ hi->len = 0;
+ }
+ else if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ && len > MIPS_SAVED_REGSIZE /* odd-size structs */
+ && len < MIPS_SAVED_REGSIZE * 2
+ && (TYPE_CODE (valtype) == TYPE_CODE_STRUCT ||
+ TYPE_CODE (valtype) == TYPE_CODE_UNION))
+ {
+ /* "un-left-justify" the value spread across two registers. */
+ lo->reg_offset = 2 * MIPS_SAVED_REGSIZE - len;
+ lo->len = MIPS_SAVED_REGSIZE - lo->reg_offset;
+ hi->reg_offset = 0;
+ hi->len = len - lo->len;
+ }
+ else
+ {
+ /* Only perform a partial copy of the second register. */
+ lo->reg_offset = 0;
+ hi->reg_offset = 0;
+ if (len > MIPS_SAVED_REGSIZE)
+ {
+ lo->len = MIPS_SAVED_REGSIZE;
+ hi->len = len - MIPS_SAVED_REGSIZE;
+ }
+ else
+ {
+ lo->len = len;
+ hi->len = 0;
+ }
+ }
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ && REGISTER_RAW_SIZE (regnum) == 8
+ && MIPS_SAVED_REGSIZE == 4)
+ {
+ /* Account for the fact that only the least-signficant part
+ of the register is being used */
+ lo->reg_offset += 4;
+ hi->reg_offset += 4;
+ }
+ lo->buf_offset = 0;
+ hi->buf_offset = lo->len;
+ }
+}
+
+/* Given a return value in `regbuf' with a type `valtype', extract and
+ copy its value into `valbuf'. */
+
+void
+mips_extract_return_value (struct type *valtype,
+ char regbuf[REGISTER_BYTES],
+ char *valbuf)
+{
+ struct return_value_word lo;
+ struct return_value_word hi;
+ return_value_location (valtype, &hi, &lo);
+
+ memcpy (valbuf + lo.buf_offset,
+ regbuf + REGISTER_BYTE (lo.reg) + lo.reg_offset,
+ lo.len);
+
+ if (hi.len > 0)
+ memcpy (valbuf + hi.buf_offset,
+ regbuf + REGISTER_BYTE (hi.reg) + hi.reg_offset,
+ hi.len);
+}
+
+/* Given a return value in `valbuf' with a type `valtype', write it's
+ value into the appropriate register. */
+
+void
+mips_store_return_value (struct type *valtype, char *valbuf)
+{
+ char raw_buffer[MAX_REGISTER_RAW_SIZE];
+ struct return_value_word lo;
+ struct return_value_word hi;
+ return_value_location (valtype, &hi, &lo);
+
+ memset (raw_buffer, 0, sizeof (raw_buffer));
+ memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len);
+ write_register_bytes (REGISTER_BYTE (lo.reg),
+ raw_buffer,
+ REGISTER_RAW_SIZE (lo.reg));
+
+ if (hi.len > 0)
+ {
+ memset (raw_buffer, 0, sizeof (raw_buffer));
+ memcpy (raw_buffer + hi.reg_offset, valbuf + hi.buf_offset, hi.len);
+ write_register_bytes (REGISTER_BYTE (hi.reg),
+ raw_buffer,
+ REGISTER_RAW_SIZE (hi.reg));
+ }
+}
+
+/* Exported procedure: Is PC in the signal trampoline code */
+
+int
+in_sigtramp (CORE_ADDR pc, char *ignore)
+{
+ if (sigtramp_address == 0)
+ fixup_sigtramp ();
+ return (pc >= sigtramp_address && pc < sigtramp_end);
+}
+
+/* Root of all "set mips "/"show mips " commands. This will eventually be
+ used for all MIPS-specific commands. */
+
+static void
+show_mips_command (char *args, int from_tty)
+{
+ help_list (showmipscmdlist, "show mips ", all_commands, gdb_stdout);
+}
+
+static void
+set_mips_command (char *args, int from_tty)
+{
+ printf_unfiltered ("\"set mips\" must be followed by an appropriate subcommand.\n");
+ help_list (setmipscmdlist, "set mips ", all_commands, gdb_stdout);
+}
+
+/* Commands to show/set the MIPS FPU type. */
+
+static void
+show_mipsfpu_command (char *args, int from_tty)
+{
+ char *fpu;
+ switch (MIPS_FPU_TYPE)
+ {
+ case MIPS_FPU_SINGLE:
+ fpu = "single-precision";
+ break;
+ case MIPS_FPU_DOUBLE:
+ fpu = "double-precision";
+ break;
+ case MIPS_FPU_NONE:
+ fpu = "absent (none)";
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "bad switch");
+ }
+ if (mips_fpu_type_auto)
+ printf_unfiltered ("The MIPS floating-point coprocessor is set automatically (currently %s)\n",
+ fpu);
+ else
+ printf_unfiltered ("The MIPS floating-point coprocessor is assumed to be %s\n",
+ fpu);
+}
+
+
+static void
+set_mipsfpu_command (char *args, int from_tty)
+{
+ printf_unfiltered ("\"set mipsfpu\" must be followed by \"double\", \"single\",\"none\" or \"auto\".\n");
+ show_mipsfpu_command (args, from_tty);
+}
+
+static void
+set_mipsfpu_single_command (char *args, int from_tty)
+{
+ mips_fpu_type = MIPS_FPU_SINGLE;
+ mips_fpu_type_auto = 0;
+ if (GDB_MULTI_ARCH)
+ {
+ gdbarch_tdep (current_gdbarch)->mips_fpu_type = MIPS_FPU_SINGLE;
+ }
+}
+
+static void
+set_mipsfpu_double_command (char *args, int from_tty)
+{
+ mips_fpu_type = MIPS_FPU_DOUBLE;
+ mips_fpu_type_auto = 0;
+ if (GDB_MULTI_ARCH)
+ {
+ gdbarch_tdep (current_gdbarch)->mips_fpu_type = MIPS_FPU_DOUBLE;
+ }
+}
+
+static void
+set_mipsfpu_none_command (char *args, int from_tty)
+{
+ mips_fpu_type = MIPS_FPU_NONE;
+ mips_fpu_type_auto = 0;
+ if (GDB_MULTI_ARCH)
+ {
+ gdbarch_tdep (current_gdbarch)->mips_fpu_type = MIPS_FPU_NONE;
+ }
+}
+
+static void
+set_mipsfpu_auto_command (char *args, int from_tty)
+{
+ mips_fpu_type_auto = 1;
+}
+
+/* Command to set the processor type. */
+
+void
+mips_set_processor_type_command (char *args, int from_tty)
+{
+ int i;
+
+ if (tmp_mips_processor_type == NULL || *tmp_mips_processor_type == '\0')
+ {
+ printf_unfiltered ("The known MIPS processor types are as follows:\n\n");
+ for (i = 0; mips_processor_type_table[i].name != NULL; ++i)
+ printf_unfiltered ("%s\n", mips_processor_type_table[i].name);
+
+ /* Restore the value. */
+ tmp_mips_processor_type = xstrdup (mips_processor_type);
+
+ return;
+ }
+
+ if (!mips_set_processor_type (tmp_mips_processor_type))
+ {
+ error ("Unknown processor type `%s'.", tmp_mips_processor_type);
+ /* Restore its value. */
+ tmp_mips_processor_type = xstrdup (mips_processor_type);
+ }
+}
+
+static void
+mips_show_processor_type_command (char *args, int from_tty)
+{
+}
+
+/* Modify the actual processor type. */
+
+int
+mips_set_processor_type (char *str)
+{
+ int i;
+
+ if (str == NULL)
+ return 0;
+
+ for (i = 0; mips_processor_type_table[i].name != NULL; ++i)
+ {
+ if (strcasecmp (str, mips_processor_type_table[i].name) == 0)
+ {
+ mips_processor_type = str;
+ mips_processor_reg_names = mips_processor_type_table[i].regnames;
+ return 1;
+ /* FIXME tweak fpu flag too */
+ }
+ }
+
+ return 0;
+}
+
+/* Attempt to identify the particular processor model by reading the
+ processor id. */
+
+char *
+mips_read_processor_type (void)
+{
+ CORE_ADDR prid;
+
+ prid = read_register (PRID_REGNUM);
+
+ if ((prid & ~0xf) == 0x700)
+ return savestring ("r3041", strlen ("r3041"));
+
+ return NULL;
+}
+
+/* Just like reinit_frame_cache, but with the right arguments to be
+ callable as an sfunc. */
+
+static void
+reinit_frame_cache_sfunc (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ reinit_frame_cache ();
+}
+
+int
+gdb_print_insn_mips (bfd_vma memaddr, disassemble_info *info)
+{
+ mips_extra_func_info_t proc_desc;
+
+ /* Search for the function containing this address. Set the low bit
+ of the address when searching, in case we were given an even address
+ that is the start of a 16-bit function. If we didn't do this,
+ the search would fail because the symbol table says the function
+ starts at an odd address, i.e. 1 byte past the given address. */
+ memaddr = ADDR_BITS_REMOVE (memaddr);
+ proc_desc = non_heuristic_proc_desc (MAKE_MIPS16_ADDR (memaddr), NULL);
+
+ /* Make an attempt to determine if this is a 16-bit function. If
+ the procedure descriptor exists and the address therein is odd,
+ it's definitely a 16-bit function. Otherwise, we have to just
+ guess that if the address passed in is odd, it's 16-bits. */
+ if (proc_desc)
+ info->mach = pc_is_mips16 (PROC_LOW_ADDR (proc_desc)) ?
+ bfd_mach_mips16 : TM_PRINT_INSN_MACH;
+ else
+ info->mach = pc_is_mips16 (memaddr) ?
+ bfd_mach_mips16 : TM_PRINT_INSN_MACH;
+
+ /* Round down the instruction address to the appropriate boundary. */
+ memaddr &= (info->mach == bfd_mach_mips16 ? ~1 : ~3);
+
+ /* Call the appropriate disassembler based on the target endian-ness. */
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ return print_insn_big_mips (memaddr, info);
+ else
+ return print_insn_little_mips (memaddr, info);
+}
+
+/* Old-style breakpoint macros.
+ The IDT board uses an unusual breakpoint value, and sometimes gets
+ confused when it sees the usual MIPS breakpoint instruction. */
+
+#define BIG_BREAKPOINT {0, 0x5, 0, 0xd}
+#define LITTLE_BREAKPOINT {0xd, 0, 0x5, 0}
+#define PMON_BIG_BREAKPOINT {0, 0, 0, 0xd}
+#define PMON_LITTLE_BREAKPOINT {0xd, 0, 0, 0}
+#define IDT_BIG_BREAKPOINT {0, 0, 0x0a, 0xd}
+#define IDT_LITTLE_BREAKPOINT {0xd, 0x0a, 0, 0}
+#define MIPS16_BIG_BREAKPOINT {0xe8, 0xa5}
+#define MIPS16_LITTLE_BREAKPOINT {0xa5, 0xe8}
+
+/* This function implements the BREAKPOINT_FROM_PC macro. It uses the program
+ counter value to determine whether a 16- or 32-bit breakpoint should be
+ used. It returns a pointer to a string of bytes that encode a breakpoint
+ instruction, stores the length of the string to *lenptr, and adjusts pc
+ (if necessary) to point to the actual memory location where the
+ breakpoint should be inserted. */
+
+const unsigned char *
+mips_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
+{
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ if (pc_is_mips16 (*pcptr))
+ {
+ static unsigned char mips16_big_breakpoint[] =
+ MIPS16_BIG_BREAKPOINT;
+ *pcptr = UNMAKE_MIPS16_ADDR (*pcptr);
+ *lenptr = sizeof (mips16_big_breakpoint);
+ return mips16_big_breakpoint;
+ }
+ else
+ {
+ static unsigned char big_breakpoint[] = BIG_BREAKPOINT;
+ static unsigned char pmon_big_breakpoint[] = PMON_BIG_BREAKPOINT;
+ static unsigned char idt_big_breakpoint[] = IDT_BIG_BREAKPOINT;
+
+ *lenptr = sizeof (big_breakpoint);
+
+ if (strcmp (target_shortname, "mips") == 0)
+ return idt_big_breakpoint;
+ else if (strcmp (target_shortname, "ddb") == 0
+ || strcmp (target_shortname, "pmon") == 0
+ || strcmp (target_shortname, "lsi") == 0)
+ return pmon_big_breakpoint;
+ else
+ return big_breakpoint;
+ }
+ }
+ else
+ {
+ if (pc_is_mips16 (*pcptr))
+ {
+ static unsigned char mips16_little_breakpoint[] =
+ MIPS16_LITTLE_BREAKPOINT;
+ *pcptr = UNMAKE_MIPS16_ADDR (*pcptr);
+ *lenptr = sizeof (mips16_little_breakpoint);
+ return mips16_little_breakpoint;
+ }
+ else
+ {
+ static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT;
+ static unsigned char pmon_little_breakpoint[] =
+ PMON_LITTLE_BREAKPOINT;
+ static unsigned char idt_little_breakpoint[] =
+ IDT_LITTLE_BREAKPOINT;
+
+ *lenptr = sizeof (little_breakpoint);
+
+ if (strcmp (target_shortname, "mips") == 0)
+ return idt_little_breakpoint;
+ else if (strcmp (target_shortname, "ddb") == 0
+ || strcmp (target_shortname, "pmon") == 0
+ || strcmp (target_shortname, "lsi") == 0)
+ return pmon_little_breakpoint;
+ else
+ return little_breakpoint;
+ }
+ }
+}
+
+/* If PC is in a mips16 call or return stub, return the address of the target
+ PC, which is either the callee or the caller. There are several
+ cases which must be handled:
+
+ * If the PC is in __mips16_ret_{d,s}f, this is a return stub and the
+ target PC is in $31 ($ra).
+ * If the PC is in __mips16_call_stub_{1..10}, this is a call stub
+ and the target PC is in $2.
+ * If the PC at the start of __mips16_call_stub_{s,d}f_{0..10}, i.e.
+ before the jal instruction, this is effectively a call stub
+ and the the target PC is in $2. Otherwise this is effectively
+ a return stub and the target PC is in $18.
+
+ See the source code for the stubs in gcc/config/mips/mips16.S for
+ gory details.
+
+ This function implements the SKIP_TRAMPOLINE_CODE macro.
+ */
+
+CORE_ADDR
+mips_skip_stub (CORE_ADDR pc)
+{
+ char *name;
+ CORE_ADDR start_addr;
+
+ /* Find the starting address and name of the function containing the PC. */
+ if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0)
+ return 0;
+
+ /* If the PC is in __mips16_ret_{d,s}f, this is a return stub and the
+ target PC is in $31 ($ra). */
+ if (strcmp (name, "__mips16_ret_sf") == 0
+ || strcmp (name, "__mips16_ret_df") == 0)
+ return read_signed_register (RA_REGNUM);
+
+ if (strncmp (name, "__mips16_call_stub_", 19) == 0)
+ {
+ /* If the PC is in __mips16_call_stub_{1..10}, this is a call stub
+ and the target PC is in $2. */
+ if (name[19] >= '0' && name[19] <= '9')
+ return read_signed_register (2);
+
+ /* If the PC at the start of __mips16_call_stub_{s,d}f_{0..10}, i.e.
+ before the jal instruction, this is effectively a call stub
+ and the the target PC is in $2. Otherwise this is effectively
+ a return stub and the target PC is in $18. */
+ else if (name[19] == 's' || name[19] == 'd')
+ {
+ if (pc == start_addr)
+ {
+ /* Check if the target of the stub is a compiler-generated
+ stub. Such a stub for a function bar might have a name
+ like __fn_stub_bar, and might look like this:
+ mfc1 $4,$f13
+ mfc1 $5,$f12
+ mfc1 $6,$f15
+ mfc1 $7,$f14
+ la $1,bar (becomes a lui/addiu pair)
+ jr $1
+ So scan down to the lui/addi and extract the target
+ address from those two instructions. */
+
+ CORE_ADDR target_pc = read_signed_register (2);
+ t_inst inst;
+ int i;
+
+ /* See if the name of the target function is __fn_stub_*. */
+ if (find_pc_partial_function (target_pc, &name, NULL, NULL) == 0)
+ return target_pc;
+ if (strncmp (name, "__fn_stub_", 10) != 0
+ && strcmp (name, "etext") != 0
+ && strcmp (name, "_etext") != 0)
+ return target_pc;
+
+ /* Scan through this _fn_stub_ code for the lui/addiu pair.
+ The limit on the search is arbitrarily set to 20
+ instructions. FIXME. */
+ for (i = 0, pc = 0; i < 20; i++, target_pc += MIPS_INSTLEN)
+ {
+ inst = mips_fetch_instruction (target_pc);
+ if ((inst & 0xffff0000) == 0x3c010000) /* lui $at */
+ pc = (inst << 16) & 0xffff0000; /* high word */
+ else if ((inst & 0xffff0000) == 0x24210000) /* addiu $at */
+ return pc | (inst & 0xffff); /* low word */
+ }
+
+ /* Couldn't find the lui/addui pair, so return stub address. */
+ return target_pc;
+ }
+ else
+ /* This is the 'return' part of a call stub. The return
+ address is in $r18. */
+ return read_signed_register (18);
+ }
+ }
+ return 0; /* not a stub */
+}
+
+
+/* Return non-zero if the PC is inside a call thunk (aka stub or trampoline).
+ This implements the IN_SOLIB_CALL_TRAMPOLINE macro. */
+
+int
+mips_in_call_stub (CORE_ADDR pc, char *name)
+{
+ CORE_ADDR start_addr;
+
+ /* Find the starting address of the function containing the PC. If the
+ caller didn't give us a name, look it up at the same time. */
+ if (find_pc_partial_function (pc, name ? NULL : &name, &start_addr, NULL) == 0)
+ return 0;
+
+ if (strncmp (name, "__mips16_call_stub_", 19) == 0)
+ {
+ /* If the PC is in __mips16_call_stub_{1..10}, this is a call stub. */
+ if (name[19] >= '0' && name[19] <= '9')
+ return 1;
+ /* If the PC at the start of __mips16_call_stub_{s,d}f_{0..10}, i.e.
+ before the jal instruction, this is effectively a call stub. */
+ else if (name[19] == 's' || name[19] == 'd')
+ return pc == start_addr;
+ }
+
+ return 0; /* not a stub */
+}
+
+
+/* Return non-zero if the PC is inside a return thunk (aka stub or trampoline).
+ This implements the IN_SOLIB_RETURN_TRAMPOLINE macro. */
+
+int
+mips_in_return_stub (CORE_ADDR pc, char *name)
+{
+ CORE_ADDR start_addr;
+
+ /* Find the starting address of the function containing the PC. */
+ if (find_pc_partial_function (pc, NULL, &start_addr, NULL) == 0)
+ return 0;
+
+ /* If the PC is in __mips16_ret_{d,s}f, this is a return stub. */
+ if (strcmp (name, "__mips16_ret_sf") == 0
+ || strcmp (name, "__mips16_ret_df") == 0)
+ return 1;
+
+ /* If the PC is in __mips16_call_stub_{s,d}f_{0..10} but not at the start,
+ i.e. after the jal instruction, this is effectively a return stub. */
+ if (strncmp (name, "__mips16_call_stub_", 19) == 0
+ && (name[19] == 's' || name[19] == 'd')
+ && pc != start_addr)
+ return 1;
+
+ return 0; /* not a stub */
+}
+
+
+/* Return non-zero if the PC is in a library helper function that should
+ be ignored. This implements the IGNORE_HELPER_CALL macro. */
+
+int
+mips_ignore_helper (CORE_ADDR pc)
+{
+ char *name;
+
+ /* Find the starting address and name of the function containing the PC. */
+ if (find_pc_partial_function (pc, &name, NULL, NULL) == 0)
+ return 0;
+
+ /* If the PC is in __mips16_ret_{d,s}f, this is a library helper function
+ that we want to ignore. */
+ return (strcmp (name, "__mips16_ret_sf") == 0
+ || strcmp (name, "__mips16_ret_df") == 0);
+}
+
+
+/* Return a location where we can set a breakpoint that will be hit
+ when an inferior function call returns. This is normally the
+ program's entry point. Executables that don't have an entry
+ point (e.g. programs in ROM) should define a symbol __CALL_DUMMY_ADDRESS
+ whose address is the location where the breakpoint should be placed. */
+
+CORE_ADDR
+mips_call_dummy_address (void)
+{
+ struct minimal_symbol *sym;
+
+ sym = lookup_minimal_symbol ("__CALL_DUMMY_ADDRESS", NULL, NULL);
+ if (sym)
+ return SYMBOL_VALUE_ADDRESS (sym);
+ else
+ return entry_point_address ();
+}
+
+
+/* If the current gcc for this target does not produce correct debugging
+ information for float parameters, both prototyped and unprototyped, then
+ define this macro. This forces gdb to always assume that floats are
+ passed as doubles and then converted in the callee.
+
+ For the mips chip, it appears that the debug info marks the parameters as
+ floats regardless of whether the function is prototyped, but the actual
+ values are passed as doubles for the non-prototyped case and floats for
+ the prototyped case. Thus we choose to make the non-prototyped case work
+ for C and break the prototyped case, since the non-prototyped case is
+ probably much more common. (FIXME). */
+
+static int
+mips_coerce_float_to_double (struct type *formal, struct type *actual)
+{
+ return current_language->la_language == language_c;
+}
+
+/* When debugging a 64 MIPS target running a 32 bit ABI, the size of
+ the register stored on the stack (32) is different to its real raw
+ size (64). The below ensures that registers are fetched from the
+ stack using their ABI size and then stored into the RAW_BUFFER
+ using their raw size.
+
+ The alternative to adding this function would be to add an ABI
+ macro - REGISTER_STACK_SIZE(). */
+
+static void
+mips_get_saved_register (char *raw_buffer,
+ int *optimized,
+ CORE_ADDR *addrp,
+ struct frame_info *frame,
+ int regnum,
+ enum lval_type *lval)
+{
+ CORE_ADDR addr;
+
+ if (!target_has_registers)
+ error ("No registers.");
+
+ /* Normal systems don't optimize out things with register numbers. */
+ if (optimized != NULL)
+ *optimized = 0;
+ addr = find_saved_register (frame, regnum);
+ if (addr != 0)
+ {
+ if (lval != NULL)
+ *lval = lval_memory;
+ if (regnum == SP_REGNUM)
+ {
+ if (raw_buffer != NULL)
+ {
+ /* Put it back in target format. */
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
+ (LONGEST) addr);
+ }
+ if (addrp != NULL)
+ *addrp = 0;
+ return;
+ }
+ if (raw_buffer != NULL)
+ {
+ LONGEST val;
+ if (regnum < 32)
+ /* Only MIPS_SAVED_REGSIZE bytes of GP registers are
+ saved. */
+ val = read_memory_integer (addr, MIPS_SAVED_REGSIZE);
+ else
+ val = read_memory_integer (addr, REGISTER_RAW_SIZE (regnum));
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), val);
+ }
+ }
+ else
+ {
+ if (lval != NULL)
+ *lval = lval_register;
+ addr = REGISTER_BYTE (regnum);
+ if (raw_buffer != NULL)
+ read_register_gen (regnum, raw_buffer);
+ }
+ if (addrp != NULL)
+ *addrp = addr;
+}
+
+/* Immediately after a function call, return the saved pc.
+ Can't always go through the frames for this because on some machines
+ the new frame is not set up until the new function executes
+ some instructions. */
+
+static CORE_ADDR
+mips_saved_pc_after_call (struct frame_info *frame)
+{
+ return read_signed_register (RA_REGNUM);
+}
+
+
+/* Convert a dbx stab register number (from `r' declaration) to a gdb
+ REGNUM */
+
+static int
+mips_stab_reg_to_regnum (int num)
+{
+ if (num < 32)
+ return num;
+ else
+ return num + FP0_REGNUM - 38;
+}
+
+/* Convert a ecoff register number to a gdb REGNUM */
+
+static int
+mips_ecoff_reg_to_regnum (int num)
+{
+ if (num < 32)
+ return num;
+ else
+ return num + FP0_REGNUM - 32;
+}
+
+/* Convert an integer into an address. By first converting the value
+ into a pointer and then extracting it signed, the address is
+ guarenteed to be correctly sign extended. */
+
+static CORE_ADDR
+mips_integer_to_address (struct type *type, void *buf)
+{
+ char *tmp = alloca (TYPE_LENGTH (builtin_type_void_data_ptr));
+ LONGEST val = unpack_long (type, buf);
+ store_signed_integer (tmp, TYPE_LENGTH (builtin_type_void_data_ptr), val);
+ return extract_signed_integer (tmp,
+ TYPE_LENGTH (builtin_type_void_data_ptr));
+}
+
+static struct gdbarch *
+mips_gdbarch_init (struct gdbarch_info info,
+ struct gdbarch_list *arches)
+{
+ static LONGEST mips_call_dummy_words[] =
+ {0};
+ struct gdbarch *gdbarch;
+ struct gdbarch_tdep *tdep;
+ int elf_flags;
+ enum mips_abi mips_abi;
+ enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
+
+ /* Reset the disassembly info, in case it was set to something
+ non-default. */
+ tm_print_insn_info.flavour = bfd_target_unknown_flavour;
+ tm_print_insn_info.arch = bfd_arch_unknown;
+ tm_print_insn_info.mach = 0;
+
+ elf_flags = 0;
+
+ if (info.abfd)
+ {
+ /* First of all, extract the elf_flags, if available. */
+ if (bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
+ elf_flags = elf_elfheader (info.abfd)->e_flags;
+
+ /* Try to determine the OS ABI of the object we are loading. If
+ we end up with `unknown', just leave it that way. */
+ osabi = gdbarch_lookup_osabi (info.abfd);
+ }
+
+ /* Check ELF_FLAGS to see if it specifies the ABI being used. */
+ switch ((elf_flags & EF_MIPS_ABI))
+ {
+ case E_MIPS_ABI_O32:
+ mips_abi = MIPS_ABI_O32;
+ break;
+ case E_MIPS_ABI_O64:
+ mips_abi = MIPS_ABI_O64;
+ break;
+ case E_MIPS_ABI_EABI32:
+ mips_abi = MIPS_ABI_EABI32;
+ break;
+ case E_MIPS_ABI_EABI64:
+ mips_abi = MIPS_ABI_EABI64;
+ break;
+ default:
+ if ((elf_flags & EF_MIPS_ABI2))
+ mips_abi = MIPS_ABI_N32;
+ else
+ mips_abi = MIPS_ABI_UNKNOWN;
+ break;
+ }
+
+ /* Try the architecture for any hint of the corect ABI */
+ if (mips_abi == MIPS_ABI_UNKNOWN
+ && info.bfd_arch_info != NULL
+ && info.bfd_arch_info->arch == bfd_arch_mips)
+ {
+ switch (info.bfd_arch_info->mach)
+ {
+ case bfd_mach_mips3900:
+ mips_abi = MIPS_ABI_EABI32;
+ break;
+ case bfd_mach_mips4100:
+ case bfd_mach_mips5000:
+ mips_abi = MIPS_ABI_EABI64;
+ break;
+ case bfd_mach_mips8000:
+ case bfd_mach_mips10000:
+ mips_abi = MIPS_ABI_N32;
+ break;
+ }
+ }
+#ifdef MIPS_DEFAULT_ABI
+ if (mips_abi == MIPS_ABI_UNKNOWN)
+ mips_abi = MIPS_DEFAULT_ABI;
+#endif
+
+ if (gdbarch_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "mips_gdbarch_init: elf_flags = 0x%08x\n",
+ elf_flags);
+ fprintf_unfiltered (gdb_stdlog,
+ "mips_gdbarch_init: mips_abi = %d\n",
+ mips_abi);
+ }
+
+ /* try to find a pre-existing architecture */
+ for (arches = gdbarch_list_lookup_by_info (arches, &info);
+ arches != NULL;
+ arches = gdbarch_list_lookup_by_info (arches->next, &info))
+ {
+ /* MIPS needs to be pedantic about which ABI the object is
+ using. */
+ if (gdbarch_tdep (arches->gdbarch)->elf_flags != elf_flags)
+ continue;
+ if (gdbarch_tdep (arches->gdbarch)->mips_abi != mips_abi)
+ continue;
+ if (gdbarch_tdep (arches->gdbarch)->osabi == osabi)
+ return arches->gdbarch;
+ }
+
+ /* Need a new architecture. Fill in a target specific vector. */
+ tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
+ gdbarch = gdbarch_alloc (&info, tdep);
+ tdep->elf_flags = elf_flags;
+ tdep->osabi = osabi;
+
+ /* Initially set everything according to the default ABI/ISA. */
+ set_gdbarch_short_bit (gdbarch, 16);
+ set_gdbarch_int_bit (gdbarch, 32);
+ set_gdbarch_float_bit (gdbarch, 32);
+ set_gdbarch_double_bit (gdbarch, 64);
+ set_gdbarch_long_double_bit (gdbarch, 64);
+ set_gdbarch_register_raw_size (gdbarch, mips_register_raw_size);
+ tdep->mips_abi = mips_abi;
+
+ switch (mips_abi)
+ {
+ case MIPS_ABI_O32:
+ tdep->mips_abi_string = "o32";
+ tdep->mips_default_saved_regsize = 4;
+ tdep->mips_default_stack_argsize = 4;
+ tdep->mips_fp_register_double = 0;
+ tdep->mips_last_arg_regnum = A0_REGNUM + 4 - 1;
+ tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 4 - 1;
+ tdep->mips_regs_have_home_p = 1;
+ tdep->gdb_target_is_mips64 = 0;
+ tdep->default_mask_address_p = 0;
+ set_gdbarch_long_bit (gdbarch, 32);
+ set_gdbarch_ptr_bit (gdbarch, 32);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+ break;
+ case MIPS_ABI_O64:
+ tdep->mips_abi_string = "o64";
+ tdep->mips_default_saved_regsize = 8;
+ tdep->mips_default_stack_argsize = 8;
+ tdep->mips_fp_register_double = 1;
+ tdep->mips_last_arg_regnum = A0_REGNUM + 4 - 1;
+ tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 4 - 1;
+ tdep->mips_regs_have_home_p = 1;
+ tdep->gdb_target_is_mips64 = 1;
+ tdep->default_mask_address_p = 0;
+ set_gdbarch_long_bit (gdbarch, 32);
+ set_gdbarch_ptr_bit (gdbarch, 32);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+ break;
+ case MIPS_ABI_EABI32:
+ tdep->mips_abi_string = "eabi32";
+ tdep->mips_default_saved_regsize = 4;
+ tdep->mips_default_stack_argsize = 4;
+ tdep->mips_fp_register_double = 0;
+ tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
+ tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
+ tdep->mips_regs_have_home_p = 0;
+ tdep->gdb_target_is_mips64 = 0;
+ tdep->default_mask_address_p = 0;
+ set_gdbarch_long_bit (gdbarch, 32);
+ set_gdbarch_ptr_bit (gdbarch, 32);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+ break;
+ case MIPS_ABI_EABI64:
+ tdep->mips_abi_string = "eabi64";
+ tdep->mips_default_saved_regsize = 8;
+ tdep->mips_default_stack_argsize = 8;
+ tdep->mips_fp_register_double = 1;
+ tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
+ tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
+ tdep->mips_regs_have_home_p = 0;
+ tdep->gdb_target_is_mips64 = 1;
+ tdep->default_mask_address_p = 0;
+ set_gdbarch_long_bit (gdbarch, 64);
+ set_gdbarch_ptr_bit (gdbarch, 64);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+ break;
+ case MIPS_ABI_N32:
+ tdep->mips_abi_string = "n32";
+ tdep->mips_default_saved_regsize = 4;
+ tdep->mips_default_stack_argsize = 8;
+ tdep->mips_fp_register_double = 1;
+ tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
+ tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
+ tdep->mips_regs_have_home_p = 0;
+ tdep->gdb_target_is_mips64 = 0;
+ tdep->default_mask_address_p = 0;
+ set_gdbarch_long_bit (gdbarch, 32);
+ set_gdbarch_ptr_bit (gdbarch, 32);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+
+ /* Set up the disassembler info, so that we get the right
+ register names from libopcodes. */
+ tm_print_insn_info.flavour = bfd_target_elf_flavour;
+ tm_print_insn_info.arch = bfd_arch_mips;
+ if (info.bfd_arch_info != NULL
+ && info.bfd_arch_info->arch == bfd_arch_mips
+ && info.bfd_arch_info->mach)
+ tm_print_insn_info.mach = info.bfd_arch_info->mach;
+ else
+ tm_print_insn_info.mach = bfd_mach_mips8000;
+ break;
+ default:
+ tdep->mips_abi_string = "default";
+ tdep->mips_default_saved_regsize = MIPS_REGSIZE;
+ tdep->mips_default_stack_argsize = MIPS_REGSIZE;
+ tdep->mips_fp_register_double = (REGISTER_VIRTUAL_SIZE (FP0_REGNUM) == 8);
+ tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
+ tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
+ tdep->mips_regs_have_home_p = 1;
+ tdep->gdb_target_is_mips64 = 0;
+ tdep->default_mask_address_p = 0;
+ set_gdbarch_long_bit (gdbarch, 32);
+ set_gdbarch_ptr_bit (gdbarch, 32);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+ break;
+ }
+
+ /* FIXME: jlarmour/2000-04-07: There *is* a flag EF_MIPS_32BIT_MODE
+ that could indicate -gp32 BUT gas/config/tc-mips.c contains the
+ comment:
+
+ ``We deliberately don't allow "-gp32" to set the MIPS_32BITMODE
+ flag in object files because to do so would make it impossible to
+ link with libraries compiled without "-gp32". This is
+ unnecessarily restrictive.
+
+ We could solve this problem by adding "-gp32" multilibs to gcc,
+ but to set this flag before gcc is built with such multilibs will
+ break too many systems.''
+
+ But even more unhelpfully, the default linker output target for
+ mips64-elf is elf32-bigmips, and has EF_MIPS_32BIT_MODE set, even
+ for 64-bit programs - you need to change the ABI to change this,
+ and not all gcc targets support that currently. Therefore using
+ this flag to detect 32-bit mode would do the wrong thing given
+ the current gcc - it would make GDB treat these 64-bit programs
+ as 32-bit programs by default. */
+
+ /* enable/disable the MIPS FPU */
+ if (!mips_fpu_type_auto)
+ tdep->mips_fpu_type = mips_fpu_type;
+ else if (info.bfd_arch_info != NULL
+ && info.bfd_arch_info->arch == bfd_arch_mips)
+ switch (info.bfd_arch_info->mach)
+ {
+ case bfd_mach_mips3900:
+ case bfd_mach_mips4100:
+ case bfd_mach_mips4111:
+ tdep->mips_fpu_type = MIPS_FPU_NONE;
+ break;
+ case bfd_mach_mips4650:
+ tdep->mips_fpu_type = MIPS_FPU_SINGLE;
+ break;
+ default:
+ tdep->mips_fpu_type = MIPS_FPU_DOUBLE;
+ break;
+ }
+ else
+ tdep->mips_fpu_type = MIPS_FPU_DOUBLE;
+
+ /* MIPS version of register names. NOTE: At present the MIPS
+ register name management is part way between the old -
+ #undef/#define REGISTER_NAMES and the new REGISTER_NAME(nr).
+ Further work on it is required. */
+ set_gdbarch_register_name (gdbarch, mips_register_name);
+ set_gdbarch_read_pc (gdbarch, mips_read_pc);
+ set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
+ set_gdbarch_read_fp (gdbarch, generic_target_read_fp);
+ set_gdbarch_read_sp (gdbarch, generic_target_read_sp);
+ set_gdbarch_write_sp (gdbarch, generic_target_write_sp);
+
+ /* Add/remove bits from an address. The MIPS needs be careful to
+ ensure that all 32 bit addresses are sign extended to 64 bits. */
+ set_gdbarch_addr_bits_remove (gdbarch, mips_addr_bits_remove);
+
+ /* There's a mess in stack frame creation. See comments in
+ blockframe.c near reference to INIT_FRAME_PC_FIRST. */
+ set_gdbarch_init_frame_pc_first (gdbarch, mips_init_frame_pc_first);
+ set_gdbarch_init_frame_pc (gdbarch, init_frame_pc_noop);
+
+ /* Map debug register numbers onto internal register numbers. */
+ set_gdbarch_stab_reg_to_regnum (gdbarch, mips_stab_reg_to_regnum);
+ set_gdbarch_ecoff_reg_to_regnum (gdbarch, mips_ecoff_reg_to_regnum);
+
+ /* Initialize a frame */
+ set_gdbarch_init_extra_frame_info (gdbarch, mips_init_extra_frame_info);
+
+ /* MIPS version of CALL_DUMMY */
+
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_address (gdbarch, mips_call_dummy_address);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
+ set_gdbarch_call_dummy_words (gdbarch, mips_call_dummy_words);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (mips_call_dummy_words));
+ set_gdbarch_push_return_address (gdbarch, mips_push_return_address);
+ set_gdbarch_push_arguments (gdbarch, mips_push_arguments);
+ set_gdbarch_register_convertible (gdbarch, generic_register_convertible_not);
+ set_gdbarch_coerce_float_to_double (gdbarch, mips_coerce_float_to_double);
+
+ set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
+ set_gdbarch_get_saved_register (gdbarch, mips_get_saved_register);
+
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+ set_gdbarch_breakpoint_from_pc (gdbarch, mips_breakpoint_from_pc);
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+
+ set_gdbarch_skip_prologue (gdbarch, mips_skip_prologue);
+ set_gdbarch_saved_pc_after_call (gdbarch, mips_saved_pc_after_call);
+
+ set_gdbarch_pointer_to_address (gdbarch, signed_pointer_to_address);
+ set_gdbarch_address_to_pointer (gdbarch, address_to_signed_pointer);
+ set_gdbarch_integer_to_address (gdbarch, mips_integer_to_address);
+
+ /* Hook in OS ABI-specific overrides, if they have been registered. */
+ gdbarch_init_osabi (info, gdbarch, osabi);
+
+ return gdbarch;
+}
+
+static void
+mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ if (tdep != NULL)
+ {
+ int ef_mips_arch;
+ int ef_mips_32bitmode;
+ /* determine the ISA */
+ switch (tdep->elf_flags & EF_MIPS_ARCH)
+ {
+ case E_MIPS_ARCH_1:
+ ef_mips_arch = 1;
+ break;
+ case E_MIPS_ARCH_2:
+ ef_mips_arch = 2;
+ break;
+ case E_MIPS_ARCH_3:
+ ef_mips_arch = 3;
+ break;
+ case E_MIPS_ARCH_4:
+ ef_mips_arch = 4;
+ break;
+ default:
+ ef_mips_arch = 0;
+ break;
+ }
+ /* determine the size of a pointer */
+ ef_mips_32bitmode = (tdep->elf_flags & EF_MIPS_32BITMODE);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: tdep->elf_flags = 0x%x\n",
+ tdep->elf_flags);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: ef_mips_32bitmode = %d\n",
+ ef_mips_32bitmode);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: ef_mips_arch = %d\n",
+ ef_mips_arch);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: tdep->mips_abi = %d (%s)\n",
+ tdep->mips_abi,
+ tdep->mips_abi_string);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: mips_mask_address_p() %d (default %d)\n",
+ mips_mask_address_p (),
+ tdep->default_mask_address_p);
+ }
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: FP_REGISTER_DOUBLE = %d\n",
+ FP_REGISTER_DOUBLE);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_DEFAULT_FPU_TYPE = %d (%s)\n",
+ MIPS_DEFAULT_FPU_TYPE,
+ (MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_NONE ? "none"
+ : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_SINGLE ? "single"
+ : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_DOUBLE ? "double"
+ : "???"));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_EABI = %d\n",
+ MIPS_EABI);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_LAST_FP_ARG_REGNUM = %d (%d regs)\n",
+ MIPS_LAST_FP_ARG_REGNUM,
+ MIPS_LAST_FP_ARG_REGNUM - FPA0_REGNUM + 1);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_FPU_TYPE = %d (%s)\n",
+ MIPS_FPU_TYPE,
+ (MIPS_FPU_TYPE == MIPS_FPU_NONE ? "none"
+ : MIPS_FPU_TYPE == MIPS_FPU_SINGLE ? "single"
+ : MIPS_FPU_TYPE == MIPS_FPU_DOUBLE ? "double"
+ : "???"));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_DEFAULT_SAVED_REGSIZE = %d\n",
+ MIPS_DEFAULT_SAVED_REGSIZE);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: FP_REGISTER_DOUBLE = %d\n",
+ FP_REGISTER_DOUBLE);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_REGS_HAVE_HOME_P = %d\n",
+ MIPS_REGS_HAVE_HOME_P);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_DEFAULT_STACK_ARGSIZE = %d\n",
+ MIPS_DEFAULT_STACK_ARGSIZE);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_STACK_ARGSIZE = %d\n",
+ MIPS_STACK_ARGSIZE);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_REGSIZE = %d\n",
+ MIPS_REGSIZE);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: A0_REGNUM = %d\n",
+ A0_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: ADDR_BITS_REMOVE # %s\n",
+ XSTRING (ADDR_BITS_REMOVE(ADDR)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: ATTACH_DETACH # %s\n",
+ XSTRING (ATTACH_DETACH));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: BADVADDR_REGNUM = %d\n",
+ BADVADDR_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: BIG_BREAKPOINT = delete?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: CAUSE_REGNUM = %d\n",
+ CAUSE_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: CPLUS_MARKER = %c\n",
+ CPLUS_MARKER);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: DEFAULT_MIPS_TYPE = %s\n",
+ DEFAULT_MIPS_TYPE);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: DO_REGISTERS_INFO # %s\n",
+ XSTRING (DO_REGISTERS_INFO));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: DWARF_REG_TO_REGNUM # %s\n",
+ XSTRING (DWARF_REG_TO_REGNUM (REGNUM)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: ECOFF_REG_TO_REGNUM # %s\n",
+ XSTRING (ECOFF_REG_TO_REGNUM (REGNUM)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: ELF_MAKE_MSYMBOL_SPECIAL # %s\n",
+ XSTRING (ELF_MAKE_MSYMBOL_SPECIAL (SYM, MSYM)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: FCRCS_REGNUM = %d\n",
+ FCRCS_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: FCRIR_REGNUM = %d\n",
+ FCRIR_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: FIRST_EMBED_REGNUM = %d\n",
+ FIRST_EMBED_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: FPA0_REGNUM = %d\n",
+ FPA0_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: GDB_TARGET_IS_MIPS64 = %d\n",
+ GDB_TARGET_IS_MIPS64);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: GDB_TARGET_MASK_DISAS_PC # %s\n",
+ XSTRING (GDB_TARGET_MASK_DISAS_PC (PC)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: GDB_TARGET_UNMASK_DISAS_PC # %s\n",
+ XSTRING (GDB_TARGET_UNMASK_DISAS_PC (PC)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: GEN_REG_SAVE_MASK = %d\n",
+ GEN_REG_SAVE_MASK);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: HAVE_NONSTEPPABLE_WATCHPOINT # %s\n",
+ XSTRING (HAVE_NONSTEPPABLE_WATCHPOINT));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: HI_REGNUM = %d\n",
+ HI_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: IDT_BIG_BREAKPOINT = delete?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: IDT_LITTLE_BREAKPOINT = delete?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: IGNORE_HELPER_CALL # %s\n",
+ XSTRING (IGNORE_HELPER_CALL (PC)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: IN_SOLIB_CALL_TRAMPOLINE # %s\n",
+ XSTRING (IN_SOLIB_CALL_TRAMPOLINE (PC, NAME)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: IN_SOLIB_RETURN_TRAMPOLINE # %s\n",
+ XSTRING (IN_SOLIB_RETURN_TRAMPOLINE (PC, NAME)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: IS_MIPS16_ADDR = FIXME!\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: LAST_EMBED_REGNUM = %d\n",
+ LAST_EMBED_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: LITTLE_BREAKPOINT = delete?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: LO_REGNUM = %d\n",
+ LO_REGNUM);
+#ifdef MACHINE_CPROC_FP_OFFSET
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MACHINE_CPROC_FP_OFFSET = %d\n",
+ MACHINE_CPROC_FP_OFFSET);
+#endif
+#ifdef MACHINE_CPROC_PC_OFFSET
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MACHINE_CPROC_PC_OFFSET = %d\n",
+ MACHINE_CPROC_PC_OFFSET);
+#endif
+#ifdef MACHINE_CPROC_SP_OFFSET
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MACHINE_CPROC_SP_OFFSET = %d\n",
+ MACHINE_CPROC_SP_OFFSET);
+#endif
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MAKE_MIPS16_ADDR = FIXME!\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS16_BIG_BREAKPOINT = delete?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS16_INSTLEN = %d\n",
+ MIPS16_INSTLEN);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS16_LITTLE_BREAKPOINT = delete?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_DEFAULT_ABI = FIXME!\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_EFI_SYMBOL_NAME = multi-arch!!\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_INSTLEN = %d\n",
+ MIPS_INSTLEN);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_LAST_ARG_REGNUM = %d (%d regs)\n",
+ MIPS_LAST_ARG_REGNUM,
+ MIPS_LAST_ARG_REGNUM - A0_REGNUM + 1);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_NUMREGS = %d\n",
+ MIPS_NUMREGS);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_REGISTER_NAMES = delete?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MIPS_SAVED_REGSIZE = %d\n",
+ MIPS_SAVED_REGSIZE);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MSYMBOL_IS_SPECIAL = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: MSYMBOL_SIZE # %s\n",
+ XSTRING (MSYMBOL_SIZE (MSYM)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: OP_LDFPR = used?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: OP_LDGPR = used?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PMON_BIG_BREAKPOINT = delete?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PMON_LITTLE_BREAKPOINT = delete?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PRID_REGNUM = %d\n",
+ PRID_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PRINT_EXTRA_FRAME_INFO # %s\n",
+ XSTRING (PRINT_EXTRA_FRAME_INFO (FRAME)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PROC_DESC_IS_DUMMY = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PROC_FRAME_ADJUST = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PROC_FRAME_OFFSET = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PROC_FRAME_REG = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PROC_FREG_MASK = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PROC_FREG_OFFSET = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PROC_HIGH_ADDR = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PROC_LOW_ADDR = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PROC_PC_REG = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PROC_REG_MASK = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PROC_REG_OFFSET = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PROC_SYMBOL = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PS_REGNUM = %d\n",
+ PS_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: PUSH_FP_REGNUM = %d\n",
+ PUSH_FP_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: RA_REGNUM = %d\n",
+ RA_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: REGISTER_CONVERT_FROM_TYPE # %s\n",
+ XSTRING (REGISTER_CONVERT_FROM_TYPE (REGNUM, VALTYPE, RAW_BUFFER)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: REGISTER_CONVERT_TO_TYPE # %s\n",
+ XSTRING (REGISTER_CONVERT_TO_TYPE (REGNUM, VALTYPE, RAW_BUFFER)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: REGISTER_NAMES = delete?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: ROUND_DOWN = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: ROUND_UP = function?\n");
+#ifdef SAVED_BYTES
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: SAVED_BYTES = %d\n",
+ SAVED_BYTES);
+#endif
+#ifdef SAVED_FP
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: SAVED_FP = %d\n",
+ SAVED_FP);
+#endif
+#ifdef SAVED_PC
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: SAVED_PC = %d\n",
+ SAVED_PC);
+#endif
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: SETUP_ARBITRARY_FRAME # %s\n",
+ XSTRING (SETUP_ARBITRARY_FRAME (NUMARGS, ARGS)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: SET_PROC_DESC_IS_DUMMY = function?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: SIGFRAME_BASE = %d\n",
+ SIGFRAME_BASE);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: SIGFRAME_FPREGSAVE_OFF = %d\n",
+ SIGFRAME_FPREGSAVE_OFF);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: SIGFRAME_PC_OFF = %d\n",
+ SIGFRAME_PC_OFF);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: SIGFRAME_REGSAVE_OFF = %d\n",
+ SIGFRAME_REGSAVE_OFF);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: SIGFRAME_REG_SIZE = %d\n",
+ SIGFRAME_REG_SIZE);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: SKIP_TRAMPOLINE_CODE # %s\n",
+ XSTRING (SKIP_TRAMPOLINE_CODE (PC)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: SOFTWARE_SINGLE_STEP # %s\n",
+ XSTRING (SOFTWARE_SINGLE_STEP (SIG, BP_P)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: SOFTWARE_SINGLE_STEP_P () = %d\n",
+ SOFTWARE_SINGLE_STEP_P ());
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: STAB_REG_TO_REGNUM # %s\n",
+ XSTRING (STAB_REG_TO_REGNUM (REGNUM)));
+#ifdef STACK_END_ADDR
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: STACK_END_ADDR = %d\n",
+ STACK_END_ADDR);
+#endif
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: STEP_SKIPS_DELAY # %s\n",
+ XSTRING (STEP_SKIPS_DELAY (PC)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: STEP_SKIPS_DELAY_P = %d\n",
+ STEP_SKIPS_DELAY_P);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: STOPPED_BY_WATCHPOINT # %s\n",
+ XSTRING (STOPPED_BY_WATCHPOINT (WS)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: T9_REGNUM = %d\n",
+ T9_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: TABULAR_REGISTER_OUTPUT = used?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: TARGET_CAN_USE_HARDWARE_WATCHPOINT # %s\n",
+ XSTRING (TARGET_CAN_USE_HARDWARE_WATCHPOINT (TYPE,CNT,OTHERTYPE)));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: TARGET_HAS_HARDWARE_WATCHPOINTS # %s\n",
+ XSTRING (TARGET_HAS_HARDWARE_WATCHPOINTS));
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: TARGET_MIPS = used?\n");
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: TM_PRINT_INSN_MACH # %s\n",
+ XSTRING (TM_PRINT_INSN_MACH));
+#ifdef TRACE_CLEAR
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: TRACE_CLEAR # %s\n",
+ XSTRING (TRACE_CLEAR (THREAD, STATE)));
+#endif
+#ifdef TRACE_FLAVOR
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: TRACE_FLAVOR = %d\n",
+ TRACE_FLAVOR);
+#endif
+#ifdef TRACE_FLAVOR_SIZE
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: TRACE_FLAVOR_SIZE = %d\n",
+ TRACE_FLAVOR_SIZE);
+#endif
+#ifdef TRACE_SET
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: TRACE_SET # %s\n",
+ XSTRING (TRACE_SET (X,STATE)));
+#endif
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: UNMAKE_MIPS16_ADDR = function?\n");
+#ifdef UNUSED_REGNUM
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: UNUSED_REGNUM = %d\n",
+ UNUSED_REGNUM);
+#endif
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: V0_REGNUM = %d\n",
+ V0_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: VM_MIN_ADDRESS = %ld\n",
+ (long) VM_MIN_ADDRESS);
+#ifdef VX_NUM_REGS
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: VX_NUM_REGS = %d (used?)\n",
+ VX_NUM_REGS);
+#endif
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: ZERO_REGNUM = %d\n",
+ ZERO_REGNUM);
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: _PROC_MAGIC_ = %d\n",
+ _PROC_MAGIC_);
+
+ fprintf_unfiltered (file,
+ "mips_dump_tdep: OS ABI = %s\n",
+ gdbarch_osabi_name (tdep->osabi));
+}
+
+void
+_initialize_mips_tdep (void)
+{
+ static struct cmd_list_element *mipsfpulist = NULL;
+ struct cmd_list_element *c;
+
+ gdbarch_register (bfd_arch_mips, mips_gdbarch_init, mips_dump_tdep);
+ if (!tm_print_insn) /* Someone may have already set it */
+ tm_print_insn = gdb_print_insn_mips;
+
+ /* Add root prefix command for all "set mips"/"show mips" commands */
+ add_prefix_cmd ("mips", no_class, set_mips_command,
+ "Various MIPS specific commands.",
+ &setmipscmdlist, "set mips ", 0, &setlist);
+
+ add_prefix_cmd ("mips", no_class, show_mips_command,
+ "Various MIPS specific commands.",
+ &showmipscmdlist, "show mips ", 0, &showlist);
+
+ /* Allow the user to override the saved register size. */
+ add_show_from_set (add_set_enum_cmd ("saved-gpreg-size",
+ class_obscure,
+ size_enums,
+ &mips_saved_regsize_string, "\
+Set size of general purpose registers saved on the stack.\n\
+This option can be set to one of:\n\
+ 32 - Force GDB to treat saved GP registers as 32-bit\n\
+ 64 - Force GDB to treat saved GP registers as 64-bit\n\
+ auto - Allow GDB to use the target's default setting or autodetect the\n\
+ saved GP register size from information contained in the executable.\n\
+ (default: auto)",
+ &setmipscmdlist),
+ &showmipscmdlist);
+
+ /* Allow the user to override the argument stack size. */
+ add_show_from_set (add_set_enum_cmd ("stack-arg-size",
+ class_obscure,
+ size_enums,
+ &mips_stack_argsize_string, "\
+Set the amount of stack space reserved for each argument.\n\
+This option can be set to one of:\n\
+ 32 - Force GDB to allocate 32-bit chunks per argument\n\
+ 64 - Force GDB to allocate 64-bit chunks per argument\n\
+ auto - Allow GDB to determine the correct setting from the current\n\
+ target and executable (default)",
+ &setmipscmdlist),
+ &showmipscmdlist);
+
+ /* Let the user turn off floating point and set the fence post for
+ heuristic_proc_start. */
+
+ add_prefix_cmd ("mipsfpu", class_support, set_mipsfpu_command,
+ "Set use of MIPS floating-point coprocessor.",
+ &mipsfpulist, "set mipsfpu ", 0, &setlist);
+ add_cmd ("single", class_support, set_mipsfpu_single_command,
+ "Select single-precision MIPS floating-point coprocessor.",
+ &mipsfpulist);
+ add_cmd ("double", class_support, set_mipsfpu_double_command,
+ "Select double-precision MIPS floating-point coprocessor.",
+ &mipsfpulist);
+ add_alias_cmd ("on", "double", class_support, 1, &mipsfpulist);
+ add_alias_cmd ("yes", "double", class_support, 1, &mipsfpulist);
+ add_alias_cmd ("1", "double", class_support, 1, &mipsfpulist);
+ add_cmd ("none", class_support, set_mipsfpu_none_command,
+ "Select no MIPS floating-point coprocessor.",
+ &mipsfpulist);
+ add_alias_cmd ("off", "none", class_support, 1, &mipsfpulist);
+ add_alias_cmd ("no", "none", class_support, 1, &mipsfpulist);
+ add_alias_cmd ("0", "none", class_support, 1, &mipsfpulist);
+ add_cmd ("auto", class_support, set_mipsfpu_auto_command,
+ "Select MIPS floating-point coprocessor automatically.",
+ &mipsfpulist);
+ add_cmd ("mipsfpu", class_support, show_mipsfpu_command,
+ "Show current use of MIPS floating-point coprocessor target.",
+ &showlist);
+
+#if !GDB_MULTI_ARCH
+ c = add_set_cmd ("processor", class_support, var_string_noescape,
+ (char *) &tmp_mips_processor_type,
+ "Set the type of MIPS processor in use.\n\
+Set this to be able to access processor-type-specific registers.\n\
+",
+ &setlist);
+ set_cmd_cfunc (c, mips_set_processor_type_command);
+ c = add_show_from_set (c, &showlist);
+ set_cmd_cfunc (c, mips_show_processor_type_command);
+
+ tmp_mips_processor_type = xstrdup (DEFAULT_MIPS_TYPE);
+ mips_set_processor_type_command (xstrdup (DEFAULT_MIPS_TYPE), 0);
+#endif
+
+ /* We really would like to have both "0" and "unlimited" work, but
+ command.c doesn't deal with that. So make it a var_zinteger
+ because the user can always use "999999" or some such for unlimited. */
+ c = add_set_cmd ("heuristic-fence-post", class_support, var_zinteger,
+ (char *) &heuristic_fence_post,
+ "\
+Set the distance searched for the start of a function.\n\
+If you are debugging a stripped executable, GDB needs to search through the\n\
+program for the start of a function. This command sets the distance of the\n\
+search. The only need to set it is when debugging a stripped executable.",
+ &setlist);
+ /* We need to throw away the frame cache when we set this, since it
+ might change our ability to get backtraces. */
+ set_cmd_sfunc (c, reinit_frame_cache_sfunc);
+ add_show_from_set (c, &showlist);
+
+ /* Allow the user to control whether the upper bits of 64-bit
+ addresses should be zeroed. */
+ c = add_set_auto_boolean_cmd ("mask-address", no_class, &mask_address_var,
+ "Set zeroing of upper 32 bits of 64-bit addresses.\n\
+Use \"on\" to enable the masking, \"off\" to disable it and \"auto\" to allow GDB to determine\n\
+the correct value.\n",
+ &setmipscmdlist);
+ add_cmd ("mask-address", no_class, show_mask_address,
+ "Show current mask-address value", &showmipscmdlist);
+
+ /* Allow the user to control the size of 32 bit registers within the
+ raw remote packet. */
+ add_show_from_set (add_set_cmd ("remote-mips64-transfers-32bit-regs",
+ class_obscure,
+ var_boolean,
+ (char *)&mips64_transfers_32bit_regs_p, "\
+Set compatibility with MIPS targets that transfers 32 and 64 bit quantities.\n\
+Use \"on\" to enable backward compatibility with older MIPS 64 GDB+target\n\
+that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\
+64 bits for others. Use \"off\" to disable compatibility mode",
+ &setlist),
+ &showlist);
+
+ /* Debug this files internals. */
+ add_show_from_set (add_set_cmd ("mips", class_maintenance, var_zinteger,
+ &mips_debug, "Set mips debugging.\n\
+When non-zero, mips specific debugging is enabled.", &setdebuglist),
+ &showdebuglist);
+}
diff --git a/gdb/mipsm3-nat.c b/gdb/mipsm3-nat.c
new file mode 100644
index 00000000000..62d68600bc7
--- /dev/null
+++ b/gdb/mipsm3-nat.c
@@ -0,0 +1,386 @@
+/* Definitions to make GDB run on a mips box under Mach 3.0
+ Copyright 1992, 1993, 1998, 2000, 2001 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. */
+
+/* Mach specific routines for little endian mips (e.g. pmax)
+ * running Mach 3.0
+ *
+ * Author: Jukka Virtanen <jtv@hut.fi>
+ */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <stdio.h>
+
+#include <mach.h>
+#include <mach/message.h>
+#include <mach/exception.h>
+#include <mach_error.h>
+
+/* Find offsets to thread states at compile time.
+ * If your compiler does not grok this, check the hand coded
+ * offsets and use them.
+ */
+
+#if 1
+
+#define REG_OFFSET(reg) (int)(&((struct mips_thread_state *)0)->reg)
+#define CREG_OFFSET(reg) (int)(&((struct mips_float_state *)0)->reg)
+#define EREG_OFFSET(reg) (int)(&((struct mips_exc_state *)0)->reg)
+
+/* at reg_offset[i] is the offset to the mips_thread_state
+ * location where the gdb registers[i] is stored.
+ *
+ * -1 means mach does not save it anywhere.
+ */
+static int reg_offset[] =
+{
+ /* zero at v0 v1 */
+ -1, REG_OFFSET (r1), REG_OFFSET (r2), REG_OFFSET (r3),
+
+ /* a0 a1 a2 a3 */
+ REG_OFFSET (r4), REG_OFFSET (r5), REG_OFFSET (r6), REG_OFFSET (r7),
+
+ /* t0 t1 t2 t3 */
+ REG_OFFSET (r8), REG_OFFSET (r9), REG_OFFSET (r10), REG_OFFSET (r11),
+
+ /* t4 t5 t6 t7 */
+ REG_OFFSET (r12), REG_OFFSET (r13), REG_OFFSET (r14), REG_OFFSET (r15),
+
+ /* s0 s1 s2 s3 */
+ REG_OFFSET (r16), REG_OFFSET (r17), REG_OFFSET (r18), REG_OFFSET (r19),
+
+ /* s4 s5 s6 s7 */
+ REG_OFFSET (r20), REG_OFFSET (r21), REG_OFFSET (r22), REG_OFFSET (r23),
+
+ /* t8 t9 k0 k1 */
+ REG_OFFSET (r24), REG_OFFSET (r25), REG_OFFSET (r26), REG_OFFSET (r27),
+
+ /* gp sp s8(30) == fp(72) ra */
+ REG_OFFSET (r28), REG_OFFSET (r29), REG_OFFSET (r30), REG_OFFSET (r31),
+
+ /* sr(32) PS_REGNUM */
+ EREG_OFFSET (coproc_state),
+
+ /* lo(33) hi(34) */
+ REG_OFFSET (mdlo), REG_OFFSET (mdhi),
+
+ /* bad(35) cause(36) pc(37) */
+ EREG_OFFSET (address), EREG_OFFSET (cause), REG_OFFSET (pc),
+
+ /* f0(38) f1(39) f2(40) f3(41) */
+ CREG_OFFSET (r0), CREG_OFFSET (r1), CREG_OFFSET (r2), CREG_OFFSET (r3),
+ CREG_OFFSET (r4), CREG_OFFSET (r5), CREG_OFFSET (r6), CREG_OFFSET (r7),
+ CREG_OFFSET (r8), CREG_OFFSET (r9), CREG_OFFSET (r10), CREG_OFFSET (r11),
+ CREG_OFFSET (r12), CREG_OFFSET (r13), CREG_OFFSET (r14), CREG_OFFSET (r15),
+ CREG_OFFSET (r16), CREG_OFFSET (r17), CREG_OFFSET (r18), CREG_OFFSET (r19),
+ CREG_OFFSET (r20), CREG_OFFSET (r21), CREG_OFFSET (r22), CREG_OFFSET (r23),
+ CREG_OFFSET (r24), CREG_OFFSET (r25), CREG_OFFSET (r26), CREG_OFFSET (r27),
+ CREG_OFFSET (r28), CREG_OFFSET (r29), CREG_OFFSET (r30), CREG_OFFSET (r31),
+
+ /* fsr(70) fir(71) fp(72) == s8(30) */
+ CREG_OFFSET (csr), CREG_OFFSET (esr), REG_OFFSET (r30)
+};
+#else
+/* If the compiler does not grok the above defines */
+static int reg_offset[] =
+{
+/* mach_thread_state offsets: */
+ -1, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56,
+ 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120,
+/*sr, lo, hi,addr,cause,pc */
+ 8, 124, 128, 4, 0, 132,
+/* mach_float_state offsets: */
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
+ 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
+/*fsr,fir */
+ 128, 132,
+/* FP_REGNUM pseudo maps to s8==r30 in mach_thread_state */
+ 116
+};
+#endif
+
+/* Fetch COUNT contiguous registers from thread STATE starting from REGNUM
+ * Caller knows that the regs handled in one transaction are of same size.
+ */
+#define FETCH_REGS(state, regnum, count) \
+ memcpy (&registers[REGISTER_BYTE (regnum)], \
+ (char *)state+reg_offset[ regnum ], \
+ count*REGISTER_SIZE)
+
+/* Store COUNT contiguous registers to thread STATE starting from REGNUM */
+#define STORE_REGS(state, regnum, count) \
+ memcpy ((char *)state+reg_offset[ regnum ], \
+ &registers[REGISTER_BYTE (regnum)], \
+ count*REGISTER_SIZE)
+
+#define REGS_ALL -1
+#define REGS_NORMAL 1
+#define REGS_EXC 2
+#define REGS_COP1 4
+
+/* Hardware regs that matches FP_REGNUM */
+#define MACH_FP_REGNUM 30
+
+/* Fech thread's registers. if regno == -1, fetch all regs */
+void
+fetch_inferior_registers (int regno)
+{
+ kern_return_t ret;
+
+ thread_state_data_t state;
+ struct mips_exc_state exc_state;
+
+ int stateCnt = MIPS_THREAD_STATE_COUNT;
+
+ int which_regs = 0; /* A bit mask */
+
+ if (!MACH_PORT_VALID (current_thread))
+ error ("fetch inferior registers: Invalid thread");
+
+ if (regno < -1 || regno >= NUM_REGS)
+ error ("invalid register %d supplied to fetch_inferior_registers", regno);
+
+ if (regno == -1)
+ which_regs = REGS_ALL;
+ else if (regno == ZERO_REGNUM)
+ {
+ int zero = 0;
+ supply_register (ZERO_REGNUM, &zero);
+ return;
+ }
+ else if ((ZERO_REGNUM < regno && regno < PS_REGNUM)
+ || regno == FP_REGNUM
+ || regno == LO_REGNUM
+ || regno == HI_REGNUM
+ || regno == PC_REGNUM)
+ which_regs = REGS_NORMAL;
+ else if (FP0_REGNUM <= regno && regno <= FCRIR_REGNUM)
+ which_regs = REGS_COP1 | REGS_EXC;
+ else
+ which_regs = REGS_EXC;
+
+ /* fetch regs saved to mips_thread_state */
+ if (which_regs & REGS_NORMAL)
+ {
+ ret = thread_get_state (current_thread,
+ MIPS_THREAD_STATE,
+ state,
+ &stateCnt);
+ CHK ("fetch inferior registers: thread_get_state", ret);
+
+ if (which_regs == REGS_NORMAL)
+ {
+ /* Fetch also FP_REGNUM if fetching MACH_FP_REGNUM and vice versa */
+ if (regno == MACH_FP_REGNUM || regno == FP_REGNUM)
+ {
+ supply_register (FP_REGNUM,
+ (char *) state + reg_offset[MACH_FP_REGNUM]);
+ supply_register (MACH_FP_REGNUM,
+ (char *) state + reg_offset[MACH_FP_REGNUM]);
+ }
+ else
+ supply_register (regno,
+ (char *) state + reg_offset[regno]);
+ return;
+ }
+
+ /* ZERO_REGNUM is always zero */
+ *(int *) registers = 0;
+
+ /* Copy thread saved regs 1..31 to gdb's reg value array
+ * Luckily, they are contiquous
+ */
+ FETCH_REGS (state, 1, 31);
+
+ /* Copy mdlo and mdhi */
+ FETCH_REGS (state, LO_REGNUM, 2);
+
+ /* Copy PC */
+ FETCH_REGS (state, PC_REGNUM, 1);
+
+ /* Mach 3.0 saves FP to MACH_FP_REGNUM.
+ * For some reason gdb wants to assign a pseudo register for it.
+ */
+ FETCH_REGS (state, FP_REGNUM, 1);
+ }
+
+ /* Read exc state. Also read if need to fetch floats */
+ if (which_regs & REGS_EXC)
+ {
+ stateCnt = MIPS_EXC_STATE_COUNT;
+ ret = thread_get_state (current_thread,
+ MIPS_EXC_STATE,
+ (thread_state_t) & exc_state,
+ &stateCnt);
+ CHK ("fetch inferior regs (exc): thread_get_state", ret);
+
+ /* We need to fetch exc_state to see if the floating
+ * state is valid for the thread.
+ */
+
+ /* cproc_state: Which coprocessors the thread uses */
+ supply_register (PS_REGNUM,
+ (char *) &exc_state + reg_offset[PS_REGNUM]);
+
+ if (which_regs == REGS_EXC || which_regs == REGS_ALL)
+ {
+ supply_register (BADVADDR_REGNUM,
+ (char *) &exc_state + reg_offset[BADVADDR_REGNUM]);
+
+ supply_register (CAUSE_REGNUM,
+ (char *) &exc_state + reg_offset[CAUSE_REGNUM]);
+ if (which_regs == REGS_EXC)
+ return;
+ }
+ }
+
+
+ if (which_regs & REGS_COP1)
+ {
+ /* If the thread does not have saved COPROC1, set regs to zero */
+
+ if (!(exc_state.coproc_state & MIPS_STATUS_USE_COP1))
+ bzero (&registers[REGISTER_BYTE (FP0_REGNUM)],
+ sizeof (struct mips_float_state));
+ else
+ {
+ stateCnt = MIPS_FLOAT_STATE_COUNT;
+ ret = thread_get_state (current_thread,
+ MIPS_FLOAT_STATE,
+ state,
+ &stateCnt);
+ CHK ("fetch inferior regs (floats): thread_get_state", ret);
+
+ if (regno != -1)
+ {
+ supply_register (regno,
+ (char *) state + reg_offset[regno]);
+ return;
+ }
+
+ FETCH_REGS (state, FP0_REGNUM, 34);
+ }
+ }
+
+ /* All registers are valid, if not returned yet */
+ registers_fetched ();
+}
+
+/* Store gdb's view of registers to the thread.
+ * All registers are always valid when entering here.
+ * @@ ahem, maybe that is too strict, we could validate the necessary ones
+ * here.
+ *
+ * Hmm. It seems that gdb set $reg=value command first reads everything,
+ * then sets the reg and then stores everything. -> we must make sure
+ * that the immutable registers are not changed by reading them first.
+ */
+
+void
+store_inferior_registers (register int regno)
+{
+ thread_state_data_t state;
+ kern_return_t ret;
+
+ if (!MACH_PORT_VALID (current_thread))
+ error ("store inferior registers: Invalid thread");
+
+ /* Check for read only regs.
+ * @@ If some of these is can be changed, fix this
+ */
+ if (regno == ZERO_REGNUM ||
+ regno == PS_REGNUM ||
+ regno == BADVADDR_REGNUM ||
+ regno == CAUSE_REGNUM ||
+ regno == FCRIR_REGNUM)
+ {
+ message ("You can not alter read-only register `%s'",
+ REGISTER_NAME (regno));
+ fetch_inferior_registers (regno);
+ return;
+ }
+
+ if (regno == -1)
+ {
+ /* Don't allow these to change */
+
+ /* ZERO_REGNUM */
+ *(int *) registers = 0;
+
+ fetch_inferior_registers (PS_REGNUM);
+ fetch_inferior_registers (BADVADDR_REGNUM);
+ fetch_inferior_registers (CAUSE_REGNUM);
+ fetch_inferior_registers (FCRIR_REGNUM);
+ }
+
+ if (regno == -1 || (ZERO_REGNUM < regno && regno <= PC_REGNUM))
+ {
+#if 1
+ /* Mach 3.0 saves thread's FP to MACH_FP_REGNUM.
+ * GDB wants assigns a pseudo register FP_REGNUM for frame pointer.
+ *
+ * @@@ Here I assume (!) that gdb's FP has the value that
+ * should go to threads frame pointer. If not true, this
+ * fails badly!!!!!
+ */
+ memcpy (&registers[REGISTER_BYTE (MACH_FP_REGNUM)],
+ &registers[REGISTER_BYTE (FP_REGNUM)],
+ REGISTER_RAW_SIZE (FP_REGNUM));
+#endif
+
+ /* Save gdb's regs 1..31 to thread saved regs 1..31
+ * Luckily, they are contiquous
+ */
+ STORE_REGS (state, 1, 31);
+
+ /* Save mdlo, mdhi */
+ STORE_REGS (state, LO_REGNUM, 2);
+
+ /* Save PC */
+ STORE_REGS (state, PC_REGNUM, 1);
+
+ ret = thread_set_state (current_thread,
+ MIPS_THREAD_STATE,
+ state,
+ MIPS_FLOAT_STATE_COUNT);
+ CHK ("store inferior regs : thread_set_state", ret);
+ }
+
+ if (regno == -1 || regno >= FP0_REGNUM)
+ {
+ /* If thread has floating state, save it */
+ if (read_register (PS_REGNUM) & MIPS_STATUS_USE_COP1)
+ {
+ /* Do NOT save FCRIR_REGNUM */
+ STORE_REGS (state, FP0_REGNUM, 33);
+
+ ret = thread_set_state (current_thread,
+ MIPS_FLOAT_STATE,
+ state,
+ MIPS_FLOAT_STATE_COUNT);
+ CHK ("store inferior registers (floats): thread_set_state", ret);
+ }
+ else if (regno != -1)
+ message
+ ("Thread does not use floating point unit, floating regs not saved");
+ }
+}
diff --git a/gdb/mipsnbsd-nat.c b/gdb/mipsnbsd-nat.c
new file mode 100644
index 00000000000..16521f67617
--- /dev/null
+++ b/gdb/mipsnbsd-nat.c
@@ -0,0 +1,101 @@
+/* Native-dependent code for MIPS systems running NetBSD.
+ Copyright 2000, 2001, 2002 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 "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include "mipsnbsd-tdep.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+/* Determine if PT_GETREGS fetches this register. */
+static int
+getregs_supplies (int regno)
+{
+ return ((regno) >= ZERO_REGNUM && (regno) <= PC_REGNUM);
+}
+
+void
+fetch_inferior_registers (int regno)
+{
+ if (regno == -1 || getregs_supplies (regno))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ mipsnbsd_supply_reg ((char *) &regs, regno);
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1 || regno >= FP0_REGNUM)
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point status");
+
+ mipsnbsd_supply_fpreg ((char *) &fpregs, regno);
+ }
+}
+
+void
+store_inferior_registers (int regno)
+{
+ if (regno == -1 || getregs_supplies (regno))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ mipsnbsd_fill_reg ((char *) &regs, regno);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't write registers");
+
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1 || regno >= FP0_REGNUM)
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point status");
+
+ mipsnbsd_fill_fpreg ((char *) &fpregs, regno);
+
+ if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't write floating point status");
+ }
+}
diff --git a/gdb/mipsnbsd-tdep.c b/gdb/mipsnbsd-tdep.c
new file mode 100644
index 00000000000..029ae6f28bc
--- /dev/null
+++ b/gdb/mipsnbsd-tdep.c
@@ -0,0 +1,367 @@
+/* Target-dependent code for MIPS systems running NetBSD.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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 "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "target.h"
+#include "value.h"
+#include "osabi.h"
+
+#include "mipsnbsd-tdep.h"
+
+#include "solib-svr4.h"
+
+/* Conveniently, GDB uses the same register numbering as the
+ ptrace register structure used by NetBSD/mips. */
+
+void
+mipsnbsd_supply_reg (char *regs, int regno)
+{
+ int i;
+
+ for (i = 0; i <= PC_REGNUM; i++)
+ {
+ if (regno == i || regno == -1)
+ {
+ if (CANNOT_FETCH_REGISTER (i))
+ supply_register (i, NULL);
+ else
+ supply_register (i, regs + (i * MIPS_REGSIZE));
+ }
+ }
+}
+
+void
+mipsnbsd_fill_reg (char *regs, int regno)
+{
+ int i;
+
+ for (i = 0; i <= PC_REGNUM; i++)
+ if ((regno == i || regno == -1) && ! CANNOT_STORE_REGISTER (i))
+ regcache_collect (i, regs + (i * MIPS_REGSIZE));
+}
+
+void
+mipsnbsd_supply_fpreg (char *fpregs, int regno)
+{
+ int i;
+
+ for (i = FP0_REGNUM; i <= FCRIR_REGNUM; i++)
+ {
+ if (regno == i || regno == -1)
+ {
+ if (CANNOT_FETCH_REGISTER (i))
+ supply_register (i, NULL);
+ else
+ supply_register (i, fpregs + ((i - FP0_REGNUM) * MIPS_REGSIZE));
+ }
+ }
+}
+
+void
+mipsnbsd_fill_fpreg (char *fpregs, int regno)
+{
+ int i;
+
+ for (i = FP0_REGNUM; i <= FCRCS_REGNUM; i++)
+ if ((regno == i || regno == -1) && ! CANNOT_STORE_REGISTER (i))
+ regcache_collect (i, fpregs + ((i - FP0_REGNUM) * MIPS_REGSIZE));
+}
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR ignore)
+{
+ char *regs, *fpregs;
+
+ /* We get everything from one section. */
+ if (which != 0)
+ return;
+
+ regs = core_reg_sect;
+ fpregs = core_reg_sect + SIZEOF_STRUCT_REG;
+
+ /* Integer registers. */
+ mipsnbsd_supply_reg (regs, -1);
+
+ /* Floating point registers. */
+ mipsnbsd_supply_fpreg (regs, -1);
+}
+
+static void
+fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR ignore)
+{
+ switch (which)
+ {
+ case 0: /* Integer registers. */
+ if (core_reg_size != SIZEOF_STRUCT_REG)
+ warning ("Wrong size register set in core file.");
+ else
+ mipsnbsd_supply_reg (core_reg_sect, -1);
+ break;
+
+ case 2: /* Floating point registers. */
+ if (core_reg_size != SIZEOF_STRUCT_FPREG)
+ warning ("Wrong size register set in core file.");
+ else
+ mipsnbsd_supply_fpreg (core_reg_sect, -1);
+ break;
+
+ default:
+ /* Don't know what kind of register request this is; just ignore it. */
+ break;
+ }
+}
+
+static struct core_fns mipsnbsd_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+static struct core_fns mipsnbsd_elfcore_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_elfcore_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+/* Under NetBSD/mips, signal handler invocations can be identified by the
+ designated code sequence that is used to return from a signal handler.
+ In particular, the return address of a signal handler points to the
+ following code sequence:
+
+ addu a0, sp, 16
+ li v0, 295 # __sigreturn14
+ syscall
+
+ Each instruction has a unique encoding, so we simply attempt to match
+ the instruction the PC is pointing to with any of the above instructions.
+ If there is a hit, we know the offset to the start of the designated
+ sequence and can then check whether we really are executing in the
+ signal trampoline. If not, -1 is returned, otherwise the offset from the
+ start of the return sequence is returned. */
+
+#define RETCODE_NWORDS 3
+#define RETCODE_SIZE (RETCODE_NWORDS * 4)
+
+static const unsigned char sigtramp_retcode_mipsel[RETCODE_SIZE] =
+{
+ 0x10, 0x00, 0xa4, 0x27, /* addu a0, sp, 16 */
+ 0x27, 0x01, 0x02, 0x24, /* li v0, 295 */
+ 0x0c, 0x00, 0x00, 0x00, /* syscall */
+};
+
+static const unsigned char sigtramp_retcode_mipseb[RETCODE_SIZE] =
+{
+ 0x27, 0xa4, 0x00, 0x10, /* addu a0, sp, 16 */
+ 0x24, 0x02, 0x01, 0x27, /* li v0, 295 */
+ 0x00, 0x00, 0x00, 0x0c, /* syscall */
+};
+
+static LONGEST
+mipsnbsd_sigtramp_offset (CORE_ADDR pc)
+{
+ const char *retcode = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ ? sigtramp_retcode_mipseb : sigtramp_retcode_mipsel;
+ unsigned char ret[RETCODE_SIZE], w[4];
+ LONGEST off;
+ int i;
+
+ if (read_memory_nobpt (pc, (char *) w, sizeof (w)) != 0)
+ return -1;
+
+ for (i = 0; i < RETCODE_NWORDS; i++)
+ {
+ if (memcmp (w, retcode + (i * 4), 4) == 0)
+ break;
+ }
+ if (i == RETCODE_NWORDS)
+ return -1;
+
+ off = i * 4;
+ pc -= off;
+
+ if (read_memory_nobpt (pc, (char *) ret, sizeof (ret)) != 0)
+ return -1;
+
+ if (memcmp (ret, retcode, RETCODE_SIZE) == 0)
+ return off;
+
+ return -1;
+}
+
+static int
+mipsnbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name)
+{
+ return (mipsnbsd_sigtramp_offset (pc) >= 0);
+}
+
+/* Figure out where the longjmp will land. We expect that we have
+ just entered longjmp and haven't yet setup the stack frame, so
+ the args are still in the argument regs. A0_REGNUM points at the
+ jmp_buf structure from which we extract the PC that we will land
+ at. The PC is copied into *pc. This routine returns true on
+ success. */
+
+#define NBSD_MIPS_JB_PC (2 * 4)
+#define NBSD_MIPS_JB_ELEMENT_SIZE MIPS_REGSIZE
+#define NBSD_MIPS_JB_OFFSET (NBSD_MIPS_JB_PC * \
+ NBSD_MIPS_JB_ELEMENT_SIZE)
+
+static int
+mipsnbsd_get_longjmp_target (CORE_ADDR *pc)
+{
+ CORE_ADDR jb_addr;
+ char *buf;
+
+ buf = alloca (NBSD_MIPS_JB_ELEMENT_SIZE);
+
+ jb_addr = read_register (A0_REGNUM);
+
+ if (target_read_memory (jb_addr + NBSD_MIPS_JB_OFFSET, buf,
+ NBSD_MIPS_JB_ELEMENT_SIZE))
+ return 0;
+
+ *pc = extract_address (buf, NBSD_MIPS_JB_ELEMENT_SIZE);
+
+ return 1;
+}
+
+static int
+mipsnbsd_cannot_fetch_register (int regno)
+{
+ return (regno >= FP_REGNUM
+ || regno == ZERO_REGNUM
+ || regno == FCRIR_REGNUM);
+}
+
+static int
+mipsnbsd_cannot_store_register (int regno)
+{
+ return (regno >= FP_REGNUM
+ || regno == ZERO_REGNUM
+ || regno == FCRIR_REGNUM);
+}
+
+/* NetBSD/mips uses a slightly different link_map structure from the
+ other NetBSD platforms. */
+static struct link_map_offsets *
+mipsnbsd_ilp32_solib_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_debug_size = 16;
+
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 4;
+
+ lmo.link_map_size = 24;
+
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 4;
+
+ lmo.l_name_offset = 8;
+ lmo.l_name_size = 4;
+
+ lmo.l_next_offset = 16;
+ lmo.l_next_size = 4;
+
+ lmo.l_prev_offset = 20;
+ lmo.l_prev_size = 4;
+ }
+
+ return lmp;
+}
+
+static struct link_map_offsets *
+mipsnbsd_lp64_solib_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_debug_size = 32;
+
+ lmo.r_map_offset = 8;
+ lmo.r_map_size = 8;
+
+ lmo.link_map_size = 48;
+
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 8;
+
+ lmo.l_name_offset = 16;
+ lmo.l_name_size = 8;
+
+ lmo.l_next_offset = 32;
+ lmo.l_next_size = 8;
+
+ lmo.l_prev_offset = 40;
+ lmo.l_prev_size = 8;
+ }
+
+ return lmp;
+}
+
+static void
+mipsnbsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ set_gdbarch_pc_in_sigtramp (gdbarch, mipsnbsd_pc_in_sigtramp);
+
+ set_gdbarch_get_longjmp_target (gdbarch, mipsnbsd_get_longjmp_target);
+
+ set_gdbarch_cannot_fetch_register (gdbarch, mipsnbsd_cannot_fetch_register);
+ set_gdbarch_cannot_store_register (gdbarch, mipsnbsd_cannot_store_register);
+
+ set_gdbarch_software_single_step (gdbarch, mips_software_single_step);
+
+ set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ gdbarch_ptr_bit (gdbarch) == 32 ?
+ mipsnbsd_ilp32_solib_svr4_fetch_link_map_offsets :
+ mipsnbsd_lp64_solib_svr4_fetch_link_map_offsets);
+}
+
+void
+_initialize_mipsnbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_mips, GDB_OSABI_NETBSD_ELF,
+ mipsnbsd_init_abi);
+
+ add_core_fns (&mipsnbsd_core_fns);
+ add_core_fns (&mipsnbsd_elfcore_fns);
+}
diff --git a/gdb/mipsnbsd-tdep.h b/gdb/mipsnbsd-tdep.h
new file mode 100644
index 00000000000..6e9f50ed7c2
--- /dev/null
+++ b/gdb/mipsnbsd-tdep.h
@@ -0,0 +1,33 @@
+/* Common target dependent code for GDB on MIPS systems running NetBSD.
+ Copyright 2002 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. */
+
+#ifndef MIPSNBSD_TDEP_H
+#define MIPSNBSD_TDEP_H
+
+void mipsnbsd_supply_reg (char *, int);
+void mipsnbsd_fill_reg (char *, int);
+
+void mipsnbsd_supply_fpreg (char *, int);
+void mipsnbsd_fill_fpreg (char *, int);
+
+#define SIZEOF_STRUCT_REG (38 * MIPS_REGSIZE)
+#define SIZEOF_STRUCT_FPREG (33 * MIPS_REGSIZE)
+
+#endif /* MIPSNBSD_TDEP_H */
diff --git a/gdb/mipsread.c b/gdb/mipsread.c
new file mode 100644
index 00000000000..1f869f4b015
--- /dev/null
+++ b/gdb/mipsread.c
@@ -0,0 +1,445 @@
+/* Read a symbol table in MIPS' format (Third-Eye).
+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+ Contributed by Alessandro Forin (af@cs.cmu.edu) at CMU. Major work
+ by Per Bothner, John Gilmore and Ian Lance Taylor at 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 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. */
+
+/* Read symbols from an ECOFF file. Most of the work is done in
+ mdebugread.c. */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "bfd.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "stabsread.h"
+
+#include "coff/sym.h"
+#include "coff/internal.h"
+#include "coff/ecoff.h"
+#include "libcoff.h" /* Private BFD COFF information. */
+#include "libecoff.h" /* Private BFD ECOFF information. */
+#include "elf/common.h"
+#include "elf/mips.h"
+
+extern void _initialize_mipsread (void);
+
+static void mipscoff_new_init (struct objfile *);
+
+static void mipscoff_symfile_init (struct objfile *);
+
+static void mipscoff_symfile_read (struct objfile *, int);
+
+static void mipscoff_symfile_finish (struct objfile *);
+
+static void
+read_alphacoff_dynamic_symtab (struct section_offsets *,
+ struct objfile *objfile);
+
+/* Initialize anything that needs initializing when a completely new
+ symbol file is specified (not just adding some symbols from another
+ file, e.g. a shared library). */
+
+extern CORE_ADDR sigtramp_address;
+
+static void
+mipscoff_new_init (struct objfile *ignore)
+{
+ sigtramp_address = 0;
+ stabsread_new_init ();
+ buildsym_new_init ();
+}
+
+/* Initialize to read a symbol file (nothing to do). */
+
+static void
+mipscoff_symfile_init (struct objfile *objfile)
+{
+}
+
+/* Read a symbol file from a file. */
+
+static void
+mipscoff_symfile_read (struct objfile *objfile, int mainline)
+{
+ bfd *abfd = objfile->obfd;
+ struct cleanup *back_to;
+
+ init_minimal_symbol_collection ();
+ back_to = make_cleanup_discard_minimal_symbols ();
+
+ /* Now that the executable file is positioned at symbol table,
+ process it and define symbols accordingly. */
+
+ if (!((*ecoff_backend (abfd)->debug_swap.read_debug_info)
+ (abfd, (asection *) NULL, &ecoff_data (abfd)->debug_info)))
+ error ("Error reading symbol table: %s", bfd_errmsg (bfd_get_error ()));
+
+ mdebug_build_psymtabs (objfile, &ecoff_backend (abfd)->debug_swap,
+ &ecoff_data (abfd)->debug_info);
+
+ /* Add alpha coff dynamic symbols. */
+
+ read_alphacoff_dynamic_symtab (objfile->section_offsets, objfile);
+
+ /* Install any minimal symbols that have been collected as the current
+ minimal symbols for this objfile. */
+
+ install_minimal_symbols (objfile);
+
+ /* If the entry_file bounds are still unknown after processing the
+ partial symbols, then try to set them from the minimal symbols
+ surrounding the entry_point. */
+
+ if (mainline
+ && objfile->ei.entry_point != INVALID_ENTRY_POINT
+ && objfile->ei.entry_file_lowpc == INVALID_ENTRY_LOWPC)
+ {
+ struct minimal_symbol *m;
+
+ m = lookup_minimal_symbol_by_pc (objfile->ei.entry_point);
+ if (m && SYMBOL_NAME (m + 1))
+ {
+ objfile->ei.entry_file_lowpc = SYMBOL_VALUE_ADDRESS (m);
+ objfile->ei.entry_file_highpc = SYMBOL_VALUE_ADDRESS (m + 1);
+ }
+ }
+
+ do_cleanups (back_to);
+}
+
+/* Perform any local cleanups required when we are done with a
+ particular objfile. */
+
+static void
+mipscoff_symfile_finish (struct objfile *objfile)
+{
+}
+
+/* Alpha OSF/1 encapsulates the dynamic symbols in ELF format in a
+ standard coff section. The ELF format for the symbols differs from
+ the format defined in elf/external.h. It seems that a normal ELF 32 bit
+ format is used, and the representation only changes because longs are
+ 64 bit on the alpha. In addition, the handling of text/data section
+ indices for symbols is different from the ELF ABI.
+ As the BFD linker currently does not support dynamic linking on the alpha,
+ there seems to be no reason to pollute BFD with another mixture of object
+ file formats for now. */
+
+/* Format of an alpha external ELF symbol. */
+
+typedef struct
+{
+ unsigned char st_name[4]; /* Symbol name, index in string tbl */
+ unsigned char st_pad[4]; /* Pad to long word boundary */
+ unsigned char st_value[8]; /* Value of the symbol */
+ unsigned char st_size[4]; /* Associated symbol size */
+ unsigned char st_info[1]; /* Type and binding attributes */
+ unsigned char st_other[1]; /* No defined meaning, 0 */
+ unsigned char st_shndx[2]; /* Associated section index */
+}
+Elfalpha_External_Sym;
+
+/* Format of an alpha external ELF dynamic info structure. */
+
+typedef struct
+ {
+ unsigned char d_tag[4]; /* Tag */
+ unsigned char d_pad[4]; /* Pad to long word boundary */
+ union
+ {
+ unsigned char d_ptr[8]; /* Pointer value */
+ unsigned char d_val[4]; /* Integer value */
+ }
+ d_un;
+ }
+Elfalpha_External_Dyn;
+
+/* Struct to obtain the section pointers for alpha dynamic symbol info. */
+
+struct alphacoff_dynsecinfo
+ {
+ asection *sym_sect; /* Section pointer for .dynsym section */
+ asection *str_sect; /* Section pointer for .dynstr section */
+ asection *dyninfo_sect; /* Section pointer for .dynamic section */
+ asection *got_sect; /* Section pointer for .got section */
+ };
+
+/* We are called once per section from read_alphacoff_dynamic_symtab.
+ We need to examine each section we are passed, check to see
+ if it is something we are interested in processing, and
+ if so, stash away some access information for the section. */
+
+static void
+alphacoff_locate_sections (bfd *ignore_abfd, asection *sectp, void *sip)
+{
+ register struct alphacoff_dynsecinfo *si;
+
+ si = (struct alphacoff_dynsecinfo *) sip;
+
+ if (STREQ (sectp->name, ".dynsym"))
+ {
+ si->sym_sect = sectp;
+ }
+ else if (STREQ (sectp->name, ".dynstr"))
+ {
+ si->str_sect = sectp;
+ }
+ else if (STREQ (sectp->name, ".dynamic"))
+ {
+ si->dyninfo_sect = sectp;
+ }
+ else if (STREQ (sectp->name, ".got"))
+ {
+ si->got_sect = sectp;
+ }
+}
+
+/* Scan an alpha dynamic symbol table for symbols of interest and
+ add them to the minimal symbol table. */
+
+static void
+read_alphacoff_dynamic_symtab (struct section_offsets *section_offsets,
+ struct objfile *objfile)
+{
+ bfd *abfd = objfile->obfd;
+ struct alphacoff_dynsecinfo si;
+ char *sym_secptr;
+ char *str_secptr;
+ char *dyninfo_secptr;
+ char *got_secptr;
+ bfd_size_type sym_secsize;
+ bfd_size_type str_secsize;
+ bfd_size_type dyninfo_secsize;
+ bfd_size_type got_secsize;
+ int sym_count;
+ int i;
+ int stripped;
+ Elfalpha_External_Sym *x_symp;
+ char *dyninfo_p;
+ char *dyninfo_end;
+ int got_entry_size = 8;
+ int dt_mips_local_gotno = -1;
+ int dt_mips_gotsym = -1;
+ struct cleanup *cleanups;
+
+
+ /* We currently only know how to handle alpha dynamic symbols. */
+ if (bfd_get_arch (abfd) != bfd_arch_alpha)
+ return;
+
+ /* Locate the dynamic symbols sections and read them in. */
+ memset ((char *) &si, 0, sizeof (si));
+ bfd_map_over_sections (abfd, alphacoff_locate_sections, (void *) & si);
+ if (si.sym_sect == NULL
+ || si.str_sect == NULL
+ || si.dyninfo_sect == NULL
+ || si.got_sect == NULL)
+ return;
+
+ sym_secsize = bfd_get_section_size_before_reloc (si.sym_sect);
+ str_secsize = bfd_get_section_size_before_reloc (si.str_sect);
+ dyninfo_secsize = bfd_get_section_size_before_reloc (si.dyninfo_sect);
+ got_secsize = bfd_get_section_size_before_reloc (si.got_sect);
+ sym_secptr = xmalloc (sym_secsize);
+ cleanups = make_cleanup (free, sym_secptr);
+ str_secptr = xmalloc (str_secsize);
+ make_cleanup (free, str_secptr);
+ dyninfo_secptr = xmalloc (dyninfo_secsize);
+ make_cleanup (free, dyninfo_secptr);
+ got_secptr = xmalloc (got_secsize);
+ make_cleanup (free, got_secptr);
+
+ if (!bfd_get_section_contents (abfd, si.sym_sect, sym_secptr,
+ (file_ptr) 0, sym_secsize))
+ return;
+ if (!bfd_get_section_contents (abfd, si.str_sect, str_secptr,
+ (file_ptr) 0, str_secsize))
+ return;
+ if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_secptr,
+ (file_ptr) 0, dyninfo_secsize))
+ return;
+ if (!bfd_get_section_contents (abfd, si.got_sect, got_secptr,
+ (file_ptr) 0, got_secsize))
+ return;
+
+ /* Find the number of local GOT entries and the index for the
+ the first dynamic symbol in the GOT. */
+ for (dyninfo_p = dyninfo_secptr, dyninfo_end = dyninfo_p + dyninfo_secsize;
+ dyninfo_p < dyninfo_end;
+ dyninfo_p += sizeof (Elfalpha_External_Dyn))
+ {
+ Elfalpha_External_Dyn *x_dynp = (Elfalpha_External_Dyn *) dyninfo_p;
+ long dyn_tag;
+
+ dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_tag);
+ if (dyn_tag == DT_NULL)
+ break;
+ else if (dyn_tag == DT_MIPS_LOCAL_GOTNO)
+ {
+ if (dt_mips_local_gotno < 0)
+ dt_mips_local_gotno
+ = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
+ }
+ else if (dyn_tag == DT_MIPS_GOTSYM)
+ {
+ if (dt_mips_gotsym < 0)
+ dt_mips_gotsym
+ = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
+ }
+ }
+ if (dt_mips_local_gotno < 0 || dt_mips_gotsym < 0)
+ return;
+
+ /* Scan all dynamic symbols and enter them into the minimal symbol table
+ if appropriate. */
+ sym_count = sym_secsize / sizeof (Elfalpha_External_Sym);
+ stripped = (bfd_get_symcount (abfd) == 0);
+
+ /* Skip first symbol, which is a null dummy. */
+ for (i = 1, x_symp = (Elfalpha_External_Sym *) sym_secptr + 1;
+ i < sym_count;
+ i++, x_symp++)
+ {
+ unsigned long strx;
+ char *name;
+ bfd_vma sym_value;
+ unsigned char sym_info;
+ unsigned int sym_shndx;
+ int isglobal;
+ enum minimal_symbol_type ms_type;
+
+ strx = bfd_h_get_32 (abfd, (bfd_byte *) x_symp->st_name);
+ if (strx >= str_secsize)
+ continue;
+ name = str_secptr + strx;
+ if (*name == '\0' || *name == '.')
+ continue;
+
+ sym_value = bfd_h_get_64 (abfd, (bfd_byte *) x_symp->st_value);
+ sym_info = bfd_h_get_8 (abfd, (bfd_byte *) x_symp->st_info);
+ sym_shndx = bfd_h_get_16 (abfd, (bfd_byte *) x_symp->st_shndx);
+ isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL);
+
+ if (sym_shndx == SHN_UNDEF)
+ {
+ /* Handle undefined functions which are defined in a shared
+ library. */
+ if (ELF_ST_TYPE (sym_info) != STT_FUNC
+ || ELF_ST_BIND (sym_info) != STB_GLOBAL)
+ continue;
+
+ ms_type = mst_solib_trampoline;
+
+ /* If sym_value is nonzero, it points to the shared library
+ trampoline entry, which is what we are looking for.
+
+ If sym_value is zero, then we have to get the GOT entry
+ for the symbol.
+ If the GOT entry is nonzero, it represents the quickstart
+ address of the function and we use that as the symbol value.
+
+ If the GOT entry is zero, the function address has to be resolved
+ by the runtime loader before the executable is started.
+ We are unable to find any meaningful address for these
+ functions in the executable file, so we skip them. */
+ if (sym_value == 0)
+ {
+ int got_entry_offset =
+ (i - dt_mips_gotsym + dt_mips_local_gotno) * got_entry_size;
+
+ if (got_entry_offset < 0 || got_entry_offset >= got_secsize)
+ continue;
+ sym_value =
+ bfd_h_get_64 (abfd,
+ (bfd_byte *) (got_secptr + got_entry_offset));
+ if (sym_value == 0)
+ continue;
+ }
+ }
+ else
+ {
+ /* Symbols defined in the executable itself. We only care about
+ them if this is a stripped executable, otherwise they have
+ been retrieved from the normal symbol table already. */
+ if (!stripped)
+ continue;
+
+ if (sym_shndx == SHN_MIPS_TEXT)
+ {
+ if (isglobal)
+ ms_type = mst_text;
+ else
+ ms_type = mst_file_text;
+ sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+ }
+ else if (sym_shndx == SHN_MIPS_DATA)
+ {
+ if (isglobal)
+ ms_type = mst_data;
+ else
+ ms_type = mst_file_data;
+ sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
+ }
+ else if (sym_shndx == SHN_MIPS_ACOMMON)
+ {
+ if (isglobal)
+ ms_type = mst_bss;
+ else
+ ms_type = mst_file_bss;
+ sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
+ }
+ else if (sym_shndx == SHN_ABS)
+ {
+ ms_type = mst_abs;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ prim_record_minimal_symbol (name, sym_value, ms_type, objfile);
+ }
+
+ do_cleanups (cleanups);
+}
+
+/* Initialization */
+
+static struct sym_fns ecoff_sym_fns =
+{
+ bfd_target_ecoff_flavour,
+ mipscoff_new_init, /* sym_new_init: init anything gbl to entire symtab */
+ mipscoff_symfile_init, /* sym_init: read initial info, setup for sym_read() */
+ mipscoff_symfile_read, /* sym_read: read a symbol file into symtab */
+ mipscoff_symfile_finish, /* sym_finish: finished with file, cleanup */
+ default_symfile_offsets, /* sym_offsets: dummy FIXME til implem sym reloc */
+ NULL /* next: pointer to next struct sym_fns */
+};
+
+void
+_initialize_mipsread (void)
+{
+ add_symtab_fns (&ecoff_sym_fns);
+}
diff --git a/gdb/mipsv4-nat.c b/gdb/mipsv4-nat.c
new file mode 100644
index 00000000000..901f9b0e39f
--- /dev/null
+++ b/gdb/mipsv4-nat.c
@@ -0,0 +1,160 @@
+/* Native support for MIPS running SVR4, for GDB.
+ Copyright 1994, 1995, 2000, 2001 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 "defs.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "regcache.h"
+
+#include <sys/time.h>
+#include <sys/procfs.h>
+#include <setjmp.h> /* For JB_XXX. */
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* Size of elements in jmpbuf */
+
+#define JB_ELEMENT_SIZE 4
+
+/*
+ * See the comment in m68k-tdep.c regarding the utility of these functions.
+ *
+ * These definitions are from the MIPS SVR4 ABI, so they may work for
+ * any MIPS SVR4 target.
+ */
+
+void
+supply_gregset (gregset_t *gregsetp)
+{
+ register int regi;
+ register greg_t *regp = &(*gregsetp)[0];
+ static char zerobuf[MAX_REGISTER_RAW_SIZE] =
+ {0};
+
+ for (regi = 0; regi <= CXT_RA; regi++)
+ supply_register (regi, (char *) (regp + regi));
+
+ supply_register (PC_REGNUM, (char *) (regp + CXT_EPC));
+ supply_register (HI_REGNUM, (char *) (regp + CXT_MDHI));
+ supply_register (LO_REGNUM, (char *) (regp + CXT_MDLO));
+ supply_register (CAUSE_REGNUM, (char *) (regp + CXT_CAUSE));
+
+ /* Fill inaccessible registers with zero. */
+ supply_register (PS_REGNUM, zerobuf);
+ supply_register (BADVADDR_REGNUM, zerobuf);
+ supply_register (FP_REGNUM, zerobuf);
+ supply_register (UNUSED_REGNUM, zerobuf);
+ for (regi = FIRST_EMBED_REGNUM; regi <= LAST_EMBED_REGNUM; regi++)
+ supply_register (regi, zerobuf);
+}
+
+void
+fill_gregset (gregset_t *gregsetp, int regno)
+{
+ int regi;
+ register greg_t *regp = &(*gregsetp)[0];
+
+ for (regi = 0; regi <= 32; regi++)
+ if ((regno == -1) || (regno == regi))
+ *(regp + regi) = *(greg_t *) & registers[REGISTER_BYTE (regi)];
+
+ if ((regno == -1) || (regno == PC_REGNUM))
+ *(regp + CXT_EPC) = *(greg_t *) & registers[REGISTER_BYTE (PC_REGNUM)];
+
+ if ((regno == -1) || (regno == CAUSE_REGNUM))
+ *(regp + CXT_CAUSE) = *(greg_t *) & registers[REGISTER_BYTE (CAUSE_REGNUM)];
+
+ if ((regno == -1) || (regno == HI_REGNUM))
+ *(regp + CXT_MDHI) = *(greg_t *) & registers[REGISTER_BYTE (HI_REGNUM)];
+
+ if ((regno == -1) || (regno == LO_REGNUM))
+ *(regp + CXT_MDLO) = *(greg_t *) & registers[REGISTER_BYTE (LO_REGNUM)];
+}
+
+/*
+ * Now we do the same thing for floating-point registers.
+ * We don't bother to condition on FP0_REGNUM since any
+ * reasonable MIPS configuration has an R3010 in it.
+ *
+ * Again, see the comments in m68k-tdep.c.
+ */
+
+void
+supply_fpregset (fpregset_t *fpregsetp)
+{
+ register int regi;
+ static char zerobuf[MAX_REGISTER_RAW_SIZE] =
+ {0};
+
+ for (regi = 0; regi < 32; regi++)
+ supply_register (FP0_REGNUM + regi,
+ (char *) &fpregsetp->fp_r.fp_regs[regi]);
+
+ supply_register (FCRCS_REGNUM, (char *) &fpregsetp->fp_csr);
+
+ /* FIXME: how can we supply FCRIR_REGNUM? The ABI doesn't tell us. */
+ supply_register (FCRIR_REGNUM, zerobuf);
+}
+
+void
+fill_fpregset (fpregset_t *fpregsetp, int regno)
+{
+ int regi;
+ char *from, *to;
+
+ for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
+ {
+ if ((regno == -1) || (regno == regi))
+ {
+ from = (char *) &registers[REGISTER_BYTE (regi)];
+ to = (char *) &(fpregsetp->fp_r.fp_regs[regi - FP0_REGNUM]);
+ memcpy (to, from, REGISTER_RAW_SIZE (regi));
+ }
+ }
+
+ if ((regno == -1) || (regno == FCRCS_REGNUM))
+ fpregsetp->fp_csr = *(unsigned *) &registers[REGISTER_BYTE (FCRCS_REGNUM)];
+}
+
+
+/* Figure out where the longjmp will land.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (_JB_PC) that we will land at. The pc is copied into PC.
+ This routine returns true on success. */
+
+int
+get_longjmp_target (CORE_ADDR *pc)
+{
+ char *buf;
+ CORE_ADDR jb_addr;
+
+ buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ jb_addr = read_register (A0_REGNUM);
+
+ if (target_read_memory (jb_addr + _JB_PC * JB_ELEMENT_SIZE, buf,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ return 1;
+}
diff --git a/gdb/mn10200-tdep.c b/gdb/mn10200-tdep.c
new file mode 100644
index 00000000000..1126d3119d6
--- /dev/null
+++ b/gdb/mn10200-tdep.c
@@ -0,0 +1,892 @@
+/* Target-dependent code for the Matsushita MN10200 for GDB, the GNU debugger.
+ Copyright 1997, 1998, 1999, 2000, 2001 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "obstack.h"
+#include "target.h"
+#include "value.h"
+#include "bfd.h"
+#include "gdb_string.h"
+#include "gdbcore.h"
+#include "symfile.h"
+#include "regcache.h"
+
+
+/* Should call_function allocate stack space for a struct return? */
+int
+mn10200_use_struct_convention (int gcc_p, struct type *type)
+{
+ return (TYPE_NFIELDS (type) > 1 || TYPE_LENGTH (type) > 8);
+}
+/* *INDENT-OFF* */
+/* The main purpose of this file is dealing with prologues to extract
+ information about stack frames and saved registers.
+
+ For reference here's how prologues look on the mn10200:
+
+ With frame pointer:
+ mov fp,a0
+ mov sp,fp
+ add <size>,sp
+ Register saves for d2, d3, a1, a2 as needed. Saves start
+ at fp - <size> + <outgoing_args_size> and work towards higher
+ addresses. Note that the saves are actually done off the stack
+ pointer in the prologue! This makes for smaller code and easier
+ prologue scanning as the displacement fields will unlikely
+ be more than 8 bits!
+
+ Without frame pointer:
+ add <size>,sp
+ Register saves for d2, d3, a1, a2 as needed. Saves start
+ at sp + <outgoing_args_size> and work towards higher addresses.
+
+ Out of line prologue:
+ add <local size>,sp -- optional
+ jsr __prologue
+ add <outgoing_size>,sp -- optional
+
+ The stack pointer remains constant throughout the life of most
+ functions. As a result the compiler will usually omit the
+ frame pointer, so we must handle frame pointerless functions. */
+
+/* Analyze the prologue to determine where registers are saved,
+ the end of the prologue, etc etc. Return the end of the prologue
+ scanned.
+
+ We store into FI (if non-null) several tidbits of information:
+
+ * stack_size -- size of this stack frame. Note that if we stop in
+ certain parts of the prologue/epilogue we may claim the size of the
+ current frame is zero. This happens when the current frame has
+ not been allocated yet or has already been deallocated.
+
+ * fsr -- Addresses of registers saved in the stack by this frame.
+
+ * status -- A (relatively) generic status indicator. It's a bitmask
+ with the following bits:
+
+ MY_FRAME_IN_SP: The base of the current frame is actually in
+ the stack pointer. This can happen for frame pointerless
+ functions, or cases where we're stopped in the prologue/epilogue
+ itself. For these cases mn10200_analyze_prologue will need up
+ update fi->frame before returning or analyzing the register
+ save instructions.
+
+ MY_FRAME_IN_FP: The base of the current frame is in the
+ frame pointer register ($a2).
+
+ CALLER_A2_IN_A0: $a2 from the caller's frame is temporarily
+ in $a0. This can happen if we're stopped in the prologue.
+
+ NO_MORE_FRAMES: Set this if the current frame is "start" or
+ if the first instruction looks like mov <imm>,sp. This tells
+ frame chain to not bother trying to unwind past this frame. */
+/* *INDENT-ON* */
+
+
+
+
+#define MY_FRAME_IN_SP 0x1
+#define MY_FRAME_IN_FP 0x2
+#define CALLER_A2_IN_A0 0x4
+#define NO_MORE_FRAMES 0x8
+
+static CORE_ADDR
+mn10200_analyze_prologue (struct frame_info *fi, CORE_ADDR pc)
+{
+ CORE_ADDR func_addr, func_end, addr, stop;
+ CORE_ADDR stack_size = 0;
+ unsigned char buf[4];
+ int status;
+ char *name;
+ int out_of_line_prologue = 0;
+
+ /* Use the PC in the frame if it's provided to look up the
+ start of this function. */
+ pc = (fi ? fi->pc : pc);
+
+ /* Find the start of this function. */
+ status = find_pc_partial_function (pc, &name, &func_addr, &func_end);
+
+ /* Do nothing if we couldn't find the start of this function or if we're
+ stopped at the first instruction in the prologue. */
+ if (status == 0)
+ return pc;
+
+ /* If we're in start, then give up. */
+ if (strcmp (name, "start") == 0)
+ {
+ if (fi)
+ fi->status = NO_MORE_FRAMES;
+ return pc;
+ }
+
+ /* At the start of a function our frame is in the stack pointer. */
+ if (fi)
+ fi->status = MY_FRAME_IN_SP;
+
+ /* If we're physically on an RTS instruction, then our frame has already
+ been deallocated.
+
+ fi->frame is bogus, we need to fix it. */
+ if (fi && fi->pc + 1 == func_end)
+ {
+ status = target_read_memory (fi->pc, buf, 1);
+ if (status != 0)
+ {
+ if (fi->next == NULL)
+ fi->frame = read_sp ();
+ return fi->pc;
+ }
+
+ if (buf[0] == 0xfe)
+ {
+ if (fi->next == NULL)
+ fi->frame = read_sp ();
+ return fi->pc;
+ }
+ }
+
+ /* Similarly if we're stopped on the first insn of a prologue as our
+ frame hasn't been allocated yet. */
+ if (fi && fi->pc == func_addr)
+ {
+ if (fi->next == NULL)
+ fi->frame = read_sp ();
+ return fi->pc;
+ }
+
+ /* Figure out where to stop scanning. */
+ stop = fi ? fi->pc : func_end;
+
+ /* Don't walk off the end of the function. */
+ stop = stop > func_end ? func_end : stop;
+
+ /* Start scanning on the first instruction of this function. */
+ addr = func_addr;
+
+ status = target_read_memory (addr, buf, 2);
+ if (status != 0)
+ {
+ if (fi && fi->next == NULL && fi->status & MY_FRAME_IN_SP)
+ fi->frame = read_sp ();
+ return addr;
+ }
+
+ /* First see if this insn sets the stack pointer; if so, it's something
+ we won't understand, so quit now. */
+ if (buf[0] == 0xdf
+ || (buf[0] == 0xf4 && buf[1] == 0x77))
+ {
+ if (fi)
+ fi->status = NO_MORE_FRAMES;
+ return addr;
+ }
+
+ /* Now see if we have a frame pointer.
+
+ Search for mov a2,a0 (0xf278)
+ then mov a3,a2 (0xf27e). */
+
+ if (buf[0] == 0xf2 && buf[1] == 0x78)
+ {
+ /* Our caller's $a2 will be found in $a0 now. Note it for
+ our callers. */
+ if (fi)
+ fi->status |= CALLER_A2_IN_A0;
+ addr += 2;
+ if (addr >= stop)
+ {
+ /* We still haven't allocated our local stack. Handle this
+ as if we stopped on the first or last insn of a function. */
+ if (fi && fi->next == NULL)
+ fi->frame = read_sp ();
+ return addr;
+ }
+
+ status = target_read_memory (addr, buf, 2);
+ if (status != 0)
+ {
+ if (fi && fi->next == NULL)
+ fi->frame = read_sp ();
+ return addr;
+ }
+ if (buf[0] == 0xf2 && buf[1] == 0x7e)
+ {
+ addr += 2;
+
+ /* Our frame pointer is valid now. */
+ if (fi)
+ {
+ fi->status |= MY_FRAME_IN_FP;
+ fi->status &= ~MY_FRAME_IN_SP;
+ }
+ if (addr >= stop)
+ return addr;
+ }
+ else
+ {
+ if (fi && fi->next == NULL)
+ fi->frame = read_sp ();
+ return addr;
+ }
+ }
+
+ /* Next we should allocate the local frame.
+
+ Search for add imm8,a3 (0xd3XX)
+ or add imm16,a3 (0xf70bXXXX)
+ or add imm24,a3 (0xf467XXXXXX).
+
+ If none of the above was found, then this prologue has
+ no stack, and therefore can't have any register saves,
+ so quit now. */
+ status = target_read_memory (addr, buf, 2);
+ if (status != 0)
+ {
+ if (fi && fi->next == NULL && (fi->status & MY_FRAME_IN_SP))
+ fi->frame = read_sp ();
+ return addr;
+ }
+ if (buf[0] == 0xd3)
+ {
+ stack_size = extract_signed_integer (&buf[1], 1);
+ if (fi)
+ fi->stack_size = stack_size;
+ addr += 2;
+ if (addr >= stop)
+ {
+ if (fi && fi->next == NULL && (fi->status & MY_FRAME_IN_SP))
+ fi->frame = read_sp () - stack_size;
+ return addr;
+ }
+ }
+ else if (buf[0] == 0xf7 && buf[1] == 0x0b)
+ {
+ status = target_read_memory (addr + 2, buf, 2);
+ if (status != 0)
+ {
+ if (fi && fi->next == NULL && (fi->status & MY_FRAME_IN_SP))
+ fi->frame = read_sp ();
+ return addr;
+ }
+ stack_size = extract_signed_integer (buf, 2);
+ if (fi)
+ fi->stack_size = stack_size;
+ addr += 4;
+ if (addr >= stop)
+ {
+ if (fi && fi->next == NULL && (fi->status & MY_FRAME_IN_SP))
+ fi->frame = read_sp () - stack_size;
+ return addr;
+ }
+ }
+ else if (buf[0] == 0xf4 && buf[1] == 0x67)
+ {
+ status = target_read_memory (addr + 2, buf, 3);
+ if (status != 0)
+ {
+ if (fi && fi->next == NULL && (fi->status & MY_FRAME_IN_SP))
+ fi->frame = read_sp ();
+ return addr;
+ }
+ stack_size = extract_signed_integer (buf, 3);
+ if (fi)
+ fi->stack_size = stack_size;
+ addr += 5;
+ if (addr >= stop)
+ {
+ if (fi && fi->next == NULL && (fi->status & MY_FRAME_IN_SP))
+ fi->frame = read_sp () - stack_size;
+ return addr;
+ }
+ }
+
+ /* Now see if we have a call to __prologue for an out of line
+ prologue. */
+ status = target_read_memory (addr, buf, 2);
+ if (status != 0)
+ return addr;
+
+ /* First check for 16bit pc-relative call to __prologue. */
+ if (buf[0] == 0xfd)
+ {
+ CORE_ADDR temp;
+ status = target_read_memory (addr + 1, buf, 2);
+ if (status != 0)
+ {
+ if (fi && fi->next == NULL && (fi->status & MY_FRAME_IN_SP))
+ fi->frame = read_sp ();
+ return addr;
+ }
+
+ /* Get the PC this instruction will branch to. */
+ temp = (extract_signed_integer (buf, 2) + addr + 3) & 0xffffff;
+
+ /* Get the name of the function at the target address. */
+ status = find_pc_partial_function (temp, &name, NULL, NULL);
+ if (status == 0)
+ {
+ if (fi && fi->next == NULL && (fi->status & MY_FRAME_IN_SP))
+ fi->frame = read_sp ();
+ return addr;
+ }
+
+ /* Note if it is an out of line prologue. */
+ out_of_line_prologue = (strcmp (name, "__prologue") == 0);
+
+ /* This sucks up 3 bytes of instruction space. */
+ if (out_of_line_prologue)
+ addr += 3;
+
+ if (addr >= stop)
+ {
+ if (fi && fi->next == NULL)
+ {
+ fi->stack_size -= 16;
+ fi->frame = read_sp () - fi->stack_size;
+ }
+ return addr;
+ }
+ }
+ /* Now check for the 24bit pc-relative call to __prologue. */
+ else if (buf[0] == 0xf4 && buf[1] == 0xe1)
+ {
+ CORE_ADDR temp;
+ status = target_read_memory (addr + 2, buf, 3);
+ if (status != 0)
+ {
+ if (fi && fi->next == NULL && (fi->status & MY_FRAME_IN_SP))
+ fi->frame = read_sp ();
+ return addr;
+ }
+
+ /* Get the PC this instruction will branch to. */
+ temp = (extract_signed_integer (buf, 3) + addr + 5) & 0xffffff;
+
+ /* Get the name of the function at the target address. */
+ status = find_pc_partial_function (temp, &name, NULL, NULL);
+ if (status == 0)
+ {
+ if (fi && fi->next == NULL && (fi->status & MY_FRAME_IN_SP))
+ fi->frame = read_sp ();
+ return addr;
+ }
+
+ /* Note if it is an out of line prologue. */
+ out_of_line_prologue = (strcmp (name, "__prologue") == 0);
+
+ /* This sucks up 5 bytes of instruction space. */
+ if (out_of_line_prologue)
+ addr += 5;
+
+ if (addr >= stop)
+ {
+ if (fi && fi->next == NULL && (fi->status & MY_FRAME_IN_SP))
+ {
+ fi->stack_size -= 16;
+ fi->frame = read_sp () - fi->stack_size;
+ }
+ return addr;
+ }
+ }
+
+ /* Now actually handle the out of line prologue. */
+ if (out_of_line_prologue)
+ {
+ int outgoing_args_size = 0;
+
+ /* First adjust the stack size for this function. The out of
+ line prologue saves 4 registers (16bytes of data). */
+ if (fi)
+ fi->stack_size -= 16;
+
+ /* Update fi->frame if necessary. */
+ if (fi && fi->next == NULL)
+ fi->frame = read_sp () - fi->stack_size;
+
+ /* After the out of line prologue, there may be another
+ stack adjustment for the outgoing arguments.
+
+ Search for add imm8,a3 (0xd3XX)
+ or add imm16,a3 (0xf70bXXXX)
+ or add imm24,a3 (0xf467XXXXXX). */
+
+ status = target_read_memory (addr, buf, 2);
+ if (status != 0)
+ {
+ if (fi)
+ {
+ fi->fsr.regs[2] = fi->frame + fi->stack_size + 4;
+ fi->fsr.regs[3] = fi->frame + fi->stack_size + 8;
+ fi->fsr.regs[5] = fi->frame + fi->stack_size + 12;
+ fi->fsr.regs[6] = fi->frame + fi->stack_size + 16;
+ }
+ return addr;
+ }
+
+ if (buf[0] == 0xd3)
+ {
+ outgoing_args_size = extract_signed_integer (&buf[1], 1);
+ addr += 2;
+ }
+ else if (buf[0] == 0xf7 && buf[1] == 0x0b)
+ {
+ status = target_read_memory (addr + 2, buf, 2);
+ if (status != 0)
+ {
+ if (fi)
+ {
+ fi->fsr.regs[2] = fi->frame + fi->stack_size + 4;
+ fi->fsr.regs[3] = fi->frame + fi->stack_size + 8;
+ fi->fsr.regs[5] = fi->frame + fi->stack_size + 12;
+ fi->fsr.regs[6] = fi->frame + fi->stack_size + 16;
+ }
+ return addr;
+ }
+ outgoing_args_size = extract_signed_integer (buf, 2);
+ addr += 4;
+ }
+ else if (buf[0] == 0xf4 && buf[1] == 0x67)
+ {
+ status = target_read_memory (addr + 2, buf, 3);
+ if (status != 0)
+ {
+ if (fi && fi->next == NULL)
+ {
+ fi->fsr.regs[2] = fi->frame + fi->stack_size + 4;
+ fi->fsr.regs[3] = fi->frame + fi->stack_size + 8;
+ fi->fsr.regs[5] = fi->frame + fi->stack_size + 12;
+ fi->fsr.regs[6] = fi->frame + fi->stack_size + 16;
+ }
+ return addr;
+ }
+ outgoing_args_size = extract_signed_integer (buf, 3);
+ addr += 5;
+ }
+ else
+ outgoing_args_size = 0;
+
+ /* Now that we know the size of the outgoing arguments, fix
+ fi->frame again if this is the innermost frame. */
+ if (fi && fi->next == NULL)
+ fi->frame -= outgoing_args_size;
+
+ /* Note the register save information and update the stack
+ size for this frame too. */
+ if (fi)
+ {
+ fi->fsr.regs[2] = fi->frame + fi->stack_size + 4;
+ fi->fsr.regs[3] = fi->frame + fi->stack_size + 8;
+ fi->fsr.regs[5] = fi->frame + fi->stack_size + 12;
+ fi->fsr.regs[6] = fi->frame + fi->stack_size + 16;
+ fi->stack_size += outgoing_args_size;
+ }
+ /* There can be no more prologue insns, so return now. */
+ return addr;
+ }
+
+ /* At this point fi->frame needs to be correct.
+
+ If MY_FRAME_IN_SP is set and we're the innermost frame, then we
+ need to fix fi->frame so that backtracing, find_frame_saved_regs,
+ etc work correctly. */
+ if (fi && fi->next == NULL && (fi->status & MY_FRAME_IN_SP) != 0)
+ fi->frame = read_sp () - fi->stack_size;
+
+ /* And last we have the register saves. These are relatively
+ simple because they're physically done off the stack pointer,
+ and thus the number of different instructions we need to
+ check is greatly reduced because we know the displacements
+ will be small.
+
+ Search for movx d2,(X,a3) (0xf55eXX)
+ then movx d3,(X,a3) (0xf55fXX)
+ then mov a1,(X,a3) (0x5dXX) No frame pointer case
+ then mov a2,(X,a3) (0x5eXX) No frame pointer case
+ or mov a0,(X,a3) (0x5cXX) Frame pointer case. */
+
+ status = target_read_memory (addr, buf, 2);
+ if (status != 0)
+ return addr;
+ if (buf[0] == 0xf5 && buf[1] == 0x5e)
+ {
+ if (fi)
+ {
+ status = target_read_memory (addr + 2, buf, 1);
+ if (status != 0)
+ return addr;
+ fi->fsr.regs[2] = (fi->frame + stack_size
+ + extract_signed_integer (buf, 1));
+ }
+ addr += 3;
+ if (addr >= stop)
+ return addr;
+ status = target_read_memory (addr, buf, 2);
+ if (status != 0)
+ return addr;
+ }
+ if (buf[0] == 0xf5 && buf[1] == 0x5f)
+ {
+ if (fi)
+ {
+ status = target_read_memory (addr + 2, buf, 1);
+ if (status != 0)
+ return addr;
+ fi->fsr.regs[3] = (fi->frame + stack_size
+ + extract_signed_integer (buf, 1));
+ }
+ addr += 3;
+ if (addr >= stop)
+ return addr;
+ status = target_read_memory (addr, buf, 2);
+ if (status != 0)
+ return addr;
+ }
+ if (buf[0] == 0x5d)
+ {
+ if (fi)
+ {
+ status = target_read_memory (addr + 1, buf, 1);
+ if (status != 0)
+ return addr;
+ fi->fsr.regs[5] = (fi->frame + stack_size
+ + extract_signed_integer (buf, 1));
+ }
+ addr += 2;
+ if (addr >= stop)
+ return addr;
+ status = target_read_memory (addr, buf, 2);
+ if (status != 0)
+ return addr;
+ }
+ if (buf[0] == 0x5e || buf[0] == 0x5c)
+ {
+ if (fi)
+ {
+ status = target_read_memory (addr + 1, buf, 1);
+ if (status != 0)
+ return addr;
+ fi->fsr.regs[6] = (fi->frame + stack_size
+ + extract_signed_integer (buf, 1));
+ fi->status &= ~CALLER_A2_IN_A0;
+ }
+ addr += 2;
+ if (addr >= stop)
+ return addr;
+ return addr;
+ }
+ return addr;
+}
+
+/* Function: frame_chain
+ Figure out and return the caller's frame pointer given current
+ frame_info struct.
+
+ We don't handle dummy frames yet but we would probably just return the
+ stack pointer that was in use at the time the function call was made? */
+
+CORE_ADDR
+mn10200_frame_chain (struct frame_info *fi)
+{
+ struct frame_info dummy_frame;
+
+ /* Walk through the prologue to determine the stack size,
+ location of saved registers, end of the prologue, etc. */
+ if (fi->status == 0)
+ mn10200_analyze_prologue (fi, (CORE_ADDR) 0);
+
+ /* Quit now if mn10200_analyze_prologue set NO_MORE_FRAMES. */
+ if (fi->status & NO_MORE_FRAMES)
+ return 0;
+
+ /* Now that we've analyzed our prologue, determine the frame
+ pointer for our caller.
+
+ If our caller has a frame pointer, then we need to
+ find the entry value of $a2 to our function.
+
+ If CALLER_A2_IN_A0, then the chain is in $a0.
+
+ If fsr.regs[6] is nonzero, then it's at the memory
+ location pointed to by fsr.regs[6].
+
+ Else it's still in $a2.
+
+ If our caller does not have a frame pointer, then his
+ frame base is fi->frame + -caller's stack size + 4. */
+
+ /* The easiest way to get that info is to analyze our caller's frame.
+
+ So we set up a dummy frame and call mn10200_analyze_prologue to
+ find stuff for us. */
+ dummy_frame.pc = FRAME_SAVED_PC (fi);
+ dummy_frame.frame = fi->frame;
+ memset (dummy_frame.fsr.regs, '\000', sizeof dummy_frame.fsr.regs);
+ dummy_frame.status = 0;
+ dummy_frame.stack_size = 0;
+ mn10200_analyze_prologue (&dummy_frame, 0);
+
+ if (dummy_frame.status & MY_FRAME_IN_FP)
+ {
+ /* Our caller has a frame pointer. So find the frame in $a2, $a0,
+ or in the stack. */
+ if (fi->fsr.regs[6])
+ return (read_memory_integer (fi->fsr.regs[FP_REGNUM], REGISTER_SIZE)
+ & 0xffffff);
+ else if (fi->status & CALLER_A2_IN_A0)
+ return read_register (4);
+ else
+ return read_register (FP_REGNUM);
+ }
+ else
+ {
+ /* Our caller does not have a frame pointer. So his frame starts
+ at the base of our frame (fi->frame) + <his size> + 4 (saved pc). */
+ return fi->frame + -dummy_frame.stack_size + 4;
+ }
+}
+
+/* Function: skip_prologue
+ Return the address of the first inst past the prologue of the function. */
+
+CORE_ADDR
+mn10200_skip_prologue (CORE_ADDR pc)
+{
+ /* We used to check the debug symbols, but that can lose if
+ we have a null prologue. */
+ return mn10200_analyze_prologue (NULL, pc);
+}
+
+/* Function: pop_frame
+ This routine gets called when either the user uses the `return'
+ command, or the call dummy breakpoint gets hit. */
+
+void
+mn10200_pop_frame (struct frame_info *frame)
+{
+ int regnum;
+
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ generic_pop_dummy_frame ();
+ else
+ {
+ write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
+
+ /* Restore any saved registers. */
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ if (frame->fsr.regs[regnum] != 0)
+ {
+ ULONGEST value;
+
+ value = read_memory_unsigned_integer (frame->fsr.regs[regnum],
+ REGISTER_RAW_SIZE (regnum));
+ write_register (regnum, value);
+ }
+
+ /* Actually cut back the stack. */
+ write_register (SP_REGNUM, FRAME_FP (frame));
+
+ /* Don't we need to set the PC?!? XXX FIXME. */
+ }
+
+ /* Throw away any cached frame information. */
+ flush_cached_frames ();
+}
+
+/* Function: push_arguments
+ Setup arguments for a call to the target. Arguments go in
+ order on the stack. */
+
+CORE_ADDR
+mn10200_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ unsigned char struct_return, CORE_ADDR struct_addr)
+{
+ int argnum = 0;
+ int len = 0;
+ int stack_offset = 0;
+ int regsused = struct_return ? 1 : 0;
+
+ /* This should be a nop, but align the stack just in case something
+ went wrong. Stacks are two byte aligned on the mn10200. */
+ sp &= ~1;
+
+ /* Now make space on the stack for the args.
+
+ XXX This doesn't appear to handle pass-by-invisible reference
+ arguments. */
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ int arg_length = (TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 1) & ~1;
+
+ /* If we've used all argument registers, then this argument is
+ pushed. */
+ if (regsused >= 2 || arg_length > 4)
+ {
+ regsused = 2;
+ len += arg_length;
+ }
+ /* We know we've got some arg register space left. If this argument
+ will fit entirely in regs, then put it there. */
+ else if (arg_length <= 2
+ || TYPE_CODE (VALUE_TYPE (args[argnum])) == TYPE_CODE_PTR)
+ {
+ regsused++;
+ }
+ else if (regsused == 0)
+ {
+ regsused = 2;
+ }
+ else
+ {
+ regsused = 2;
+ len += arg_length;
+ }
+ }
+
+ /* Allocate stack space. */
+ sp -= len;
+
+ regsused = struct_return ? 1 : 0;
+ /* Push all arguments onto the stack. */
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ int len;
+ char *val;
+
+ /* XXX Check this. What about UNIONS? */
+ if (TYPE_CODE (VALUE_TYPE (*args)) == TYPE_CODE_STRUCT
+ && TYPE_LENGTH (VALUE_TYPE (*args)) > 8)
+ {
+ /* XXX Wrong, we want a pointer to this argument. */
+ len = TYPE_LENGTH (VALUE_TYPE (*args));
+ val = (char *) VALUE_CONTENTS (*args);
+ }
+ else
+ {
+ len = TYPE_LENGTH (VALUE_TYPE (*args));
+ val = (char *) VALUE_CONTENTS (*args);
+ }
+
+ if (regsused < 2
+ && (len <= 2
+ || TYPE_CODE (VALUE_TYPE (*args)) == TYPE_CODE_PTR))
+ {
+ write_register (regsused, extract_unsigned_integer (val, 4));
+ regsused++;
+ }
+ else if (regsused == 0 && len == 4)
+ {
+ write_register (regsused, extract_unsigned_integer (val, 2));
+ write_register (regsused + 1, extract_unsigned_integer (val + 2, 2));
+ regsused = 2;
+ }
+ else
+ {
+ regsused = 2;
+ while (len > 0)
+ {
+ write_memory (sp + stack_offset, val, 2);
+
+ len -= 2;
+ val += 2;
+ stack_offset += 2;
+ }
+ }
+ args++;
+ }
+
+ return sp;
+}
+
+/* Function: push_return_address (pc)
+ Set up the return address for the inferior function call.
+ Needed for targets where we don't actually execute a JSR/BSR instruction */
+
+CORE_ADDR
+mn10200_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ unsigned char buf[4];
+
+ store_unsigned_integer (buf, 4, CALL_DUMMY_ADDRESS ());
+ write_memory (sp - 4, buf, 4);
+ return sp - 4;
+}
+
+/* Function: store_struct_return (addr,sp)
+ Store the structure value return address for an inferior function
+ call. */
+
+CORE_ADDR
+mn10200_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ /* The structure return address is passed as the first argument. */
+ write_register (0, addr);
+ return sp;
+}
+
+/* Function: frame_saved_pc
+ Find the caller of this frame. We do this by seeing if RP_REGNUM
+ is saved in the stack anywhere, otherwise we get it from the
+ registers. If the inner frame is a dummy frame, return its PC
+ instead of RP, because that's where "caller" of the dummy-frame
+ will be found. */
+
+CORE_ADDR
+mn10200_frame_saved_pc (struct frame_info *fi)
+{
+ /* The saved PC will always be at the base of the current frame. */
+ return (read_memory_integer (fi->frame, REGISTER_SIZE) & 0xffffff);
+}
+
+/* Function: init_extra_frame_info
+ Setup the frame's frame pointer, pc, and frame addresses for saved
+ registers. Most of the work is done in mn10200_analyze_prologue().
+
+ Note that when we are called for the last frame (currently active frame),
+ that fi->pc and fi->frame will already be setup. However, fi->frame will
+ be valid only if this routine uses FP. For previous frames, fi-frame will
+ always be correct. mn10200_analyze_prologue will fix fi->frame if
+ it's not valid.
+
+ We can be called with the PC in the call dummy under two circumstances.
+ First, during normal backtracing, second, while figuring out the frame
+ pointer just prior to calling the target function (see run_stack_dummy). */
+
+void
+mn10200_init_extra_frame_info (struct frame_info *fi)
+{
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs);
+ fi->status = 0;
+ fi->stack_size = 0;
+
+ mn10200_analyze_prologue (fi, 0);
+}
+
+void
+_initialize_mn10200_tdep (void)
+{
+ tm_print_insn = print_insn_mn10200;
+}
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
new file mode 100644
index 00000000000..0a5704b1704
--- /dev/null
+++ b/gdb/mn10300-tdep.c
@@ -0,0 +1,1223 @@
+/* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger.
+
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "obstack.h"
+#include "target.h"
+#include "value.h"
+#include "bfd.h"
+#include "gdb_string.h"
+#include "gdbcore.h"
+#include "symfile.h"
+#include "regcache.h"
+#include "arch-utils.h"
+
+#define D0_REGNUM 0
+#define D2_REGNUM 2
+#define D3_REGNUM 3
+#define A0_REGNUM 4
+#define A2_REGNUM 6
+#define A3_REGNUM 7
+#define MDR_REGNUM 10
+#define PSW_REGNUM 11
+#define LIR_REGNUM 12
+#define LAR_REGNUM 13
+#define MDRQ_REGNUM 14
+#define E0_REGNUM 15
+#define MCRH_REGNUM 26
+#define MCRL_REGNUM 27
+#define MCVF_REGNUM 28
+
+enum movm_register_bits {
+ movm_exother_bit = 0x01,
+ movm_exreg1_bit = 0x02,
+ movm_exreg0_bit = 0x04,
+ movm_other_bit = 0x08,
+ movm_a3_bit = 0x10,
+ movm_a2_bit = 0x20,
+ movm_d3_bit = 0x40,
+ movm_d2_bit = 0x80
+};
+
+extern void _initialize_mn10300_tdep (void);
+static CORE_ADDR mn10300_analyze_prologue (struct frame_info *fi,
+ CORE_ADDR pc);
+
+/* mn10300 private data */
+struct gdbarch_tdep
+{
+ int am33_mode;
+#define AM33_MODE (gdbarch_tdep (current_gdbarch)->am33_mode)
+};
+
+/* Additional info used by the frame */
+
+struct frame_extra_info
+ {
+ int status;
+ int stack_size;
+ };
+
+
+static char *
+register_name (int reg, char **regs, long sizeof_regs)
+{
+ if (reg < 0 || reg >= sizeof_regs / sizeof (regs[0]))
+ return NULL;
+ else
+ return regs[reg];
+}
+
+static char *
+mn10300_generic_register_name (int reg)
+{
+ static char *regs[] =
+ { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3",
+ "sp", "pc", "mdr", "psw", "lir", "lar", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "fp"
+ };
+ return register_name (reg, regs, sizeof regs);
+}
+
+
+static char *
+am33_register_name (int reg)
+{
+ static char *regs[] =
+ { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3",
+ "sp", "pc", "mdr", "psw", "lir", "lar", "",
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "ssp", "msp", "usp", "mcrh", "mcrl", "mcvf", "", "", ""
+ };
+ return register_name (reg, regs, sizeof regs);
+}
+
+static CORE_ADDR
+mn10300_saved_pc_after_call (struct frame_info *fi)
+{
+ return read_memory_integer (read_register (SP_REGNUM), 4);
+}
+
+static void
+mn10300_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ memcpy (valbuf, regbuf + REGISTER_BYTE (4), TYPE_LENGTH (type));
+ else
+ memcpy (valbuf, regbuf + REGISTER_BYTE (0), TYPE_LENGTH (type));
+}
+
+static CORE_ADDR
+mn10300_extract_struct_value_address (char *regbuf)
+{
+ return extract_address (regbuf + REGISTER_BYTE (4),
+ REGISTER_RAW_SIZE (4));
+}
+
+static void
+mn10300_store_return_value (struct type *type, char *valbuf)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ write_register_bytes (REGISTER_BYTE (4), valbuf, TYPE_LENGTH (type));
+ else
+ write_register_bytes (REGISTER_BYTE (0), valbuf, TYPE_LENGTH (type));
+}
+
+static struct frame_info *analyze_dummy_frame (CORE_ADDR, CORE_ADDR);
+static struct frame_info *
+analyze_dummy_frame (CORE_ADDR pc, CORE_ADDR frame)
+{
+ static struct frame_info *dummy = NULL;
+ if (dummy == NULL)
+ {
+ dummy = xmalloc (sizeof (struct frame_info));
+ dummy->saved_regs = xmalloc (SIZEOF_FRAME_SAVED_REGS);
+ dummy->extra_info = xmalloc (sizeof (struct frame_extra_info));
+ }
+ dummy->next = NULL;
+ dummy->prev = NULL;
+ dummy->pc = pc;
+ dummy->frame = frame;
+ dummy->extra_info->status = 0;
+ dummy->extra_info->stack_size = 0;
+ memset (dummy->saved_regs, '\000', SIZEOF_FRAME_SAVED_REGS);
+ mn10300_analyze_prologue (dummy, 0);
+ return dummy;
+}
+
+/* Values for frame_info.status */
+
+#define MY_FRAME_IN_SP 0x1
+#define MY_FRAME_IN_FP 0x2
+#define NO_MORE_FRAMES 0x4
+
+
+/* Should call_function allocate stack space for a struct return? */
+static int
+mn10300_use_struct_convention (int gcc_p, struct type *type)
+{
+ return (TYPE_NFIELDS (type) > 1 || TYPE_LENGTH (type) > 8);
+}
+
+/* The breakpoint instruction must be the same size as the smallest
+ instruction in the instruction set.
+
+ The Matsushita mn10x00 processors have single byte instructions
+ so we need a single byte breakpoint. Matsushita hasn't defined
+ one, so we defined it ourselves. */
+
+const static unsigned char *
+mn10300_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size)
+{
+ static char breakpoint[] =
+ {0xff};
+ *bp_size = 1;
+ return breakpoint;
+}
+
+
+/* Fix fi->frame if it's bogus at this point. This is a helper
+ function for mn10300_analyze_prologue. */
+
+static void
+fix_frame_pointer (struct frame_info *fi, int stack_size)
+{
+ if (fi && fi->next == NULL)
+ {
+ if (fi->extra_info->status & MY_FRAME_IN_SP)
+ fi->frame = read_sp () - stack_size;
+ else if (fi->extra_info->status & MY_FRAME_IN_FP)
+ fi->frame = read_register (A3_REGNUM);
+ }
+}
+
+
+/* Set offsets of registers saved by movm instruction.
+ This is a helper function for mn10300_analyze_prologue. */
+
+static void
+set_movm_offsets (struct frame_info *fi, int movm_args)
+{
+ int offset = 0;
+
+ if (fi == NULL || movm_args == 0)
+ return;
+
+ if (movm_args & movm_other_bit)
+ {
+ /* The `other' bit leaves a blank area of four bytes at the
+ beginning of its block of saved registers, making it 32 bytes
+ long in total. */
+ fi->saved_regs[LAR_REGNUM] = fi->frame + offset + 4;
+ fi->saved_regs[LIR_REGNUM] = fi->frame + offset + 8;
+ fi->saved_regs[MDR_REGNUM] = fi->frame + offset + 12;
+ fi->saved_regs[A0_REGNUM + 1] = fi->frame + offset + 16;
+ fi->saved_regs[A0_REGNUM] = fi->frame + offset + 20;
+ fi->saved_regs[D0_REGNUM + 1] = fi->frame + offset + 24;
+ fi->saved_regs[D0_REGNUM] = fi->frame + offset + 28;
+ offset += 32;
+ }
+ if (movm_args & movm_a3_bit)
+ {
+ fi->saved_regs[A3_REGNUM] = fi->frame + offset;
+ offset += 4;
+ }
+ if (movm_args & movm_a2_bit)
+ {
+ fi->saved_regs[A2_REGNUM] = fi->frame + offset;
+ offset += 4;
+ }
+ if (movm_args & movm_d3_bit)
+ {
+ fi->saved_regs[D3_REGNUM] = fi->frame + offset;
+ offset += 4;
+ }
+ if (movm_args & movm_d2_bit)
+ {
+ fi->saved_regs[D2_REGNUM] = fi->frame + offset;
+ offset += 4;
+ }
+ if (AM33_MODE)
+ {
+ if (movm_args & movm_exother_bit)
+ {
+ fi->saved_regs[MCVF_REGNUM] = fi->frame + offset;
+ fi->saved_regs[MCRL_REGNUM] = fi->frame + offset + 4;
+ fi->saved_regs[MCRH_REGNUM] = fi->frame + offset + 8;
+ fi->saved_regs[MDRQ_REGNUM] = fi->frame + offset + 12;
+ fi->saved_regs[E0_REGNUM + 1] = fi->frame + offset + 16;
+ fi->saved_regs[E0_REGNUM + 0] = fi->frame + offset + 20;
+ offset += 24;
+ }
+ if (movm_args & movm_exreg1_bit)
+ {
+ fi->saved_regs[E0_REGNUM + 7] = fi->frame + offset;
+ fi->saved_regs[E0_REGNUM + 6] = fi->frame + offset + 4;
+ fi->saved_regs[E0_REGNUM + 5] = fi->frame + offset + 8;
+ fi->saved_regs[E0_REGNUM + 4] = fi->frame + offset + 12;
+ offset += 16;
+ }
+ if (movm_args & movm_exreg0_bit)
+ {
+ fi->saved_regs[E0_REGNUM + 3] = fi->frame + offset;
+ fi->saved_regs[E0_REGNUM + 2] = fi->frame + offset + 4;
+ offset += 8;
+ }
+ }
+}
+
+
+/* The main purpose of this file is dealing with prologues to extract
+ information about stack frames and saved registers.
+
+ In gcc/config/mn13000/mn10300.c, the expand_prologue prologue
+ function is pretty readable, and has a nice explanation of how the
+ prologue is generated. The prologues generated by that code will
+ have the following form (NOTE: the current code doesn't handle all
+ this!):
+
+ + If this is an old-style varargs function, then its arguments
+ need to be flushed back to the stack:
+
+ mov d0,(4,sp)
+ mov d1,(4,sp)
+
+ + If we use any of the callee-saved registers, save them now.
+
+ movm [some callee-saved registers],(sp)
+
+ + If we have any floating-point registers to save:
+
+ - Decrement the stack pointer to reserve space for the registers.
+ If the function doesn't need a frame pointer, we may combine
+ this with the adjustment that reserves space for the frame.
+
+ add -SIZE, sp
+
+ - Save the floating-point registers. We have two possible
+ strategies:
+
+ . Save them at fixed offset from the SP:
+
+ fmov fsN,(OFFSETN,sp)
+ fmov fsM,(OFFSETM,sp)
+ ...
+
+ Note that, if OFFSETN happens to be zero, you'll get the
+ different opcode: fmov fsN,(sp)
+
+ . Or, set a0 to the start of the save area, and then use
+ post-increment addressing to save the FP registers.
+
+ mov sp, a0
+ add SIZE, a0
+ fmov fsN,(a0+)
+ fmov fsM,(a0+)
+ ...
+
+ + If the function needs a frame pointer, we set it here.
+
+ mov sp, a3
+
+ + Now we reserve space for the stack frame proper. This could be
+ merged into the `add -SIZE, sp' instruction for FP saves up
+ above, unless we needed to set the frame pointer in the previous
+ step, or the frame is so large that allocating the whole thing at
+ once would put the FP register save slots out of reach of the
+ addressing mode (128 bytes).
+
+ add -SIZE, sp
+
+ One day we might keep the stack pointer constant, that won't
+ change the code for prologues, but it will make the frame
+ pointerless case much more common. */
+
+/* Analyze the prologue to determine where registers are saved,
+ the end of the prologue, etc etc. Return the end of the prologue
+ scanned.
+
+ We store into FI (if non-null) several tidbits of information:
+
+ * stack_size -- size of this stack frame. Note that if we stop in
+ certain parts of the prologue/epilogue we may claim the size of the
+ current frame is zero. This happens when the current frame has
+ not been allocated yet or has already been deallocated.
+
+ * fsr -- Addresses of registers saved in the stack by this frame.
+
+ * status -- A (relatively) generic status indicator. It's a bitmask
+ with the following bits:
+
+ MY_FRAME_IN_SP: The base of the current frame is actually in
+ the stack pointer. This can happen for frame pointerless
+ functions, or cases where we're stopped in the prologue/epilogue
+ itself. For these cases mn10300_analyze_prologue will need up
+ update fi->frame before returning or analyzing the register
+ save instructions.
+
+ MY_FRAME_IN_FP: The base of the current frame is in the
+ frame pointer register ($a3).
+
+ NO_MORE_FRAMES: Set this if the current frame is "start" or
+ if the first instruction looks like mov <imm>,sp. This tells
+ frame chain to not bother trying to unwind past this frame. */
+
+static CORE_ADDR
+mn10300_analyze_prologue (struct frame_info *fi, CORE_ADDR pc)
+{
+ CORE_ADDR func_addr, func_end, addr, stop;
+ CORE_ADDR stack_size;
+ int imm_size;
+ unsigned char buf[4];
+ int status, movm_args = 0;
+ char *name;
+
+ /* Use the PC in the frame if it's provided to look up the
+ start of this function. */
+ pc = (fi ? fi->pc : pc);
+
+ /* Find the start of this function. */
+ status = find_pc_partial_function (pc, &name, &func_addr, &func_end);
+
+ /* Do nothing if we couldn't find the start of this function or if we're
+ stopped at the first instruction in the prologue. */
+ if (status == 0)
+ {
+ return pc;
+ }
+
+ /* If we're in start, then give up. */
+ if (strcmp (name, "start") == 0)
+ {
+ if (fi != NULL)
+ fi->extra_info->status = NO_MORE_FRAMES;
+ return pc;
+ }
+
+ /* At the start of a function our frame is in the stack pointer. */
+ if (fi)
+ fi->extra_info->status = MY_FRAME_IN_SP;
+
+ /* Get the next two bytes into buf, we need two because rets is a two
+ byte insn and the first isn't enough to uniquely identify it. */
+ status = read_memory_nobpt (pc, buf, 2);
+ if (status != 0)
+ return pc;
+
+ /* If we're physically on an "rets" instruction, then our frame has
+ already been deallocated. Note this can also be true for retf
+ and ret if they specify a size of zero.
+
+ In this case fi->frame is bogus, we need to fix it. */
+ if (fi && buf[0] == 0xf0 && buf[1] == 0xfc)
+ {
+ if (fi->next == NULL)
+ fi->frame = read_sp ();
+ return fi->pc;
+ }
+
+ /* Similarly if we're stopped on the first insn of a prologue as our
+ frame hasn't been allocated yet. */
+ if (fi && fi->pc == func_addr)
+ {
+ if (fi->next == NULL)
+ fi->frame = read_sp ();
+ return fi->pc;
+ }
+
+ /* Figure out where to stop scanning. */
+ stop = fi ? fi->pc : func_end;
+
+ /* Don't walk off the end of the function. */
+ stop = stop > func_end ? func_end : stop;
+
+ /* Start scanning on the first instruction of this function. */
+ addr = func_addr;
+
+ /* Suck in two bytes. */
+ status = read_memory_nobpt (addr, buf, 2);
+ if (status != 0)
+ {
+ fix_frame_pointer (fi, 0);
+ return addr;
+ }
+
+ /* First see if this insn sets the stack pointer from a register; if
+ so, it's probably the initialization of the stack pointer in _start,
+ so mark this as the bottom-most frame. */
+ if (buf[0] == 0xf2 && (buf[1] & 0xf3) == 0xf0)
+ {
+ if (fi)
+ fi->extra_info->status = NO_MORE_FRAMES;
+ return addr;
+ }
+
+ /* Now look for movm [regs],sp, which saves the callee saved registers.
+
+ At this time we don't know if fi->frame is valid, so we only note
+ that we encountered a movm instruction. Later, we'll set the entries
+ in fsr.regs as needed. */
+ if (buf[0] == 0xcf)
+ {
+ /* Extract the register list for the movm instruction. */
+ status = read_memory_nobpt (addr + 1, buf, 1);
+ movm_args = *buf;
+
+ addr += 2;
+
+ /* Quit now if we're beyond the stop point. */
+ if (addr >= stop)
+ {
+ /* Fix fi->frame since it's bogus at this point. */
+ if (fi && fi->next == NULL)
+ fi->frame = read_sp ();
+
+ /* Note if/where callee saved registers were saved. */
+ set_movm_offsets (fi, movm_args);
+ return addr;
+ }
+
+ /* Get the next two bytes so the prologue scan can continue. */
+ status = read_memory_nobpt (addr, buf, 2);
+ if (status != 0)
+ {
+ /* Fix fi->frame since it's bogus at this point. */
+ if (fi && fi->next == NULL)
+ fi->frame = read_sp ();
+
+ /* Note if/where callee saved registers were saved. */
+ set_movm_offsets (fi, movm_args);
+ return addr;
+ }
+ }
+
+ /* Now see if we set up a frame pointer via "mov sp,a3" */
+ if (buf[0] == 0x3f)
+ {
+ addr += 1;
+
+ /* The frame pointer is now valid. */
+ if (fi)
+ {
+ fi->extra_info->status |= MY_FRAME_IN_FP;
+ fi->extra_info->status &= ~MY_FRAME_IN_SP;
+ }
+
+ /* Quit now if we're beyond the stop point. */
+ if (addr >= stop)
+ {
+ /* Fix fi->frame if it's bogus at this point. */
+ fix_frame_pointer (fi, 0);
+
+ /* Note if/where callee saved registers were saved. */
+ set_movm_offsets (fi, movm_args);
+ return addr;
+ }
+
+ /* Get two more bytes so scanning can continue. */
+ status = read_memory_nobpt (addr, buf, 2);
+ if (status != 0)
+ {
+ /* Fix fi->frame if it's bogus at this point. */
+ fix_frame_pointer (fi, 0);
+
+ /* Note if/where callee saved registers were saved. */
+ set_movm_offsets (fi, movm_args);
+ return addr;
+ }
+ }
+
+ /* Next we should allocate the local frame. No more prologue insns
+ are found after allocating the local frame.
+
+ Search for add imm8,sp (0xf8feXX)
+ or add imm16,sp (0xfafeXXXX)
+ or add imm32,sp (0xfcfeXXXXXXXX).
+
+ If none of the above was found, then this prologue has no
+ additional stack. */
+
+ status = read_memory_nobpt (addr, buf, 2);
+ if (status != 0)
+ {
+ /* Fix fi->frame if it's bogus at this point. */
+ fix_frame_pointer (fi, 0);
+
+ /* Note if/where callee saved registers were saved. */
+ set_movm_offsets (fi, movm_args);
+ return addr;
+ }
+
+ imm_size = 0;
+ if (buf[0] == 0xf8 && buf[1] == 0xfe)
+ imm_size = 1;
+ else if (buf[0] == 0xfa && buf[1] == 0xfe)
+ imm_size = 2;
+ else if (buf[0] == 0xfc && buf[1] == 0xfe)
+ imm_size = 4;
+
+ if (imm_size != 0)
+ {
+ /* Suck in imm_size more bytes, they'll hold the size of the
+ current frame. */
+ status = read_memory_nobpt (addr + 2, buf, imm_size);
+ if (status != 0)
+ {
+ /* Fix fi->frame if it's bogus at this point. */
+ fix_frame_pointer (fi, 0);
+
+ /* Note if/where callee saved registers were saved. */
+ set_movm_offsets (fi, movm_args);
+ return addr;
+ }
+
+ /* Note the size of the stack in the frame info structure. */
+ stack_size = extract_signed_integer (buf, imm_size);
+ if (fi)
+ fi->extra_info->stack_size = stack_size;
+
+ /* We just consumed 2 + imm_size bytes. */
+ addr += 2 + imm_size;
+
+ /* No more prologue insns follow, so begin preparation to return. */
+ /* Fix fi->frame if it's bogus at this point. */
+ fix_frame_pointer (fi, stack_size);
+
+ /* Note if/where callee saved registers were saved. */
+ set_movm_offsets (fi, movm_args);
+ return addr;
+ }
+
+ /* We never found an insn which allocates local stack space, regardless
+ this is the end of the prologue. */
+ /* Fix fi->frame if it's bogus at this point. */
+ fix_frame_pointer (fi, 0);
+
+ /* Note if/where callee saved registers were saved. */
+ set_movm_offsets (fi, movm_args);
+ return addr;
+}
+
+
+/* Function: saved_regs_size
+ Return the size in bytes of the register save area, based on the
+ saved_regs array in FI. */
+static int
+saved_regs_size (struct frame_info *fi)
+{
+ int adjust = 0;
+ int i;
+
+ /* Reserve four bytes for every register saved. */
+ for (i = 0; i < NUM_REGS; i++)
+ if (fi->saved_regs[i])
+ adjust += 4;
+
+ /* If we saved LIR, then it's most likely we used a `movm'
+ instruction with the `other' bit set, in which case the SP is
+ decremented by an extra four bytes, "to simplify calculation
+ of the transfer area", according to the processor manual. */
+ if (fi->saved_regs[LIR_REGNUM])
+ adjust += 4;
+
+ return adjust;
+}
+
+
+/* Function: frame_chain
+ Figure out and return the caller's frame pointer given current
+ frame_info struct.
+
+ We don't handle dummy frames yet but we would probably just return the
+ stack pointer that was in use at the time the function call was made? */
+
+static CORE_ADDR
+mn10300_frame_chain (struct frame_info *fi)
+{
+ struct frame_info *dummy;
+ /* Walk through the prologue to determine the stack size,
+ location of saved registers, end of the prologue, etc. */
+ if (fi->extra_info->status == 0)
+ mn10300_analyze_prologue (fi, (CORE_ADDR) 0);
+
+ /* Quit now if mn10300_analyze_prologue set NO_MORE_FRAMES. */
+ if (fi->extra_info->status & NO_MORE_FRAMES)
+ return 0;
+
+ /* Now that we've analyzed our prologue, determine the frame
+ pointer for our caller.
+
+ If our caller has a frame pointer, then we need to
+ find the entry value of $a3 to our function.
+
+ If fsr.regs[A3_REGNUM] is nonzero, then it's at the memory
+ location pointed to by fsr.regs[A3_REGNUM].
+
+ Else it's still in $a3.
+
+ If our caller does not have a frame pointer, then his
+ frame base is fi->frame + -caller's stack size. */
+
+ /* The easiest way to get that info is to analyze our caller's frame.
+ So we set up a dummy frame and call mn10300_analyze_prologue to
+ find stuff for us. */
+ dummy = analyze_dummy_frame (FRAME_SAVED_PC (fi), fi->frame);
+
+ if (dummy->extra_info->status & MY_FRAME_IN_FP)
+ {
+ /* Our caller has a frame pointer. So find the frame in $a3 or
+ in the stack. */
+ if (fi->saved_regs[A3_REGNUM])
+ return (read_memory_integer (fi->saved_regs[A3_REGNUM], REGISTER_SIZE));
+ else
+ return read_register (A3_REGNUM);
+ }
+ else
+ {
+ int adjust = saved_regs_size (fi);
+
+ /* Our caller does not have a frame pointer. So his frame starts
+ at the base of our frame (fi->frame) + register save space
+ + <his size>. */
+ return fi->frame + adjust + -dummy->extra_info->stack_size;
+ }
+}
+
+/* Function: skip_prologue
+ Return the address of the first inst past the prologue of the function. */
+
+static CORE_ADDR
+mn10300_skip_prologue (CORE_ADDR pc)
+{
+ /* We used to check the debug symbols, but that can lose if
+ we have a null prologue. */
+ return mn10300_analyze_prologue (NULL, pc);
+}
+
+/* generic_pop_current_frame calls this function if the current
+ frame isn't a dummy frame. */
+static void
+mn10300_pop_frame_regular (struct frame_info *frame)
+{
+ int regnum;
+
+ write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
+
+ /* Restore any saved registers. */
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ if (frame->saved_regs[regnum] != 0)
+ {
+ ULONGEST value;
+
+ value = read_memory_unsigned_integer (frame->saved_regs[regnum],
+ REGISTER_RAW_SIZE (regnum));
+ write_register (regnum, value);
+ }
+
+ /* Actually cut back the stack. */
+ write_register (SP_REGNUM, FRAME_FP (frame));
+
+ /* Don't we need to set the PC?!? XXX FIXME. */
+}
+
+/* Function: pop_frame
+ This routine gets called when either the user uses the `return'
+ command, or the call dummy breakpoint gets hit. */
+static void
+mn10300_pop_frame (void)
+{
+ /* This function checks for and handles generic dummy frames, and
+ calls back to our function for ordinary frames. */
+ generic_pop_current_frame (mn10300_pop_frame_regular);
+
+ /* Throw away any cached frame information. */
+ flush_cached_frames ();
+}
+
+/* Function: push_arguments
+ Setup arguments for a call to the target. Arguments go in
+ order on the stack. */
+
+static CORE_ADDR
+mn10300_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int argnum = 0;
+ int len = 0;
+ int stack_offset = 0;
+ int regsused = struct_return ? 1 : 0;
+
+ /* This should be a nop, but align the stack just in case something
+ went wrong. Stacks are four byte aligned on the mn10300. */
+ sp &= ~3;
+
+ /* Now make space on the stack for the args.
+
+ XXX This doesn't appear to handle pass-by-invisible reference
+ arguments. */
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ int arg_length = (TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3;
+
+ while (regsused < 2 && arg_length > 0)
+ {
+ regsused++;
+ arg_length -= 4;
+ }
+ len += arg_length;
+ }
+
+ /* Allocate stack space. */
+ sp -= len;
+
+ regsused = struct_return ? 1 : 0;
+ /* Push all arguments onto the stack. */
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ int len;
+ char *val;
+
+ /* XXX Check this. What about UNIONS? */
+ if (TYPE_CODE (VALUE_TYPE (*args)) == TYPE_CODE_STRUCT
+ && TYPE_LENGTH (VALUE_TYPE (*args)) > 8)
+ {
+ /* XXX Wrong, we want a pointer to this argument. */
+ len = TYPE_LENGTH (VALUE_TYPE (*args));
+ val = (char *) VALUE_CONTENTS (*args);
+ }
+ else
+ {
+ len = TYPE_LENGTH (VALUE_TYPE (*args));
+ val = (char *) VALUE_CONTENTS (*args);
+ }
+
+ while (regsused < 2 && len > 0)
+ {
+ write_register (regsused, extract_unsigned_integer (val, 4));
+ val += 4;
+ len -= 4;
+ regsused++;
+ }
+
+ while (len > 0)
+ {
+ write_memory (sp + stack_offset, val, 4);
+ len -= 4;
+ val += 4;
+ stack_offset += 4;
+ }
+
+ args++;
+ }
+
+ /* Make space for the flushback area. */
+ sp -= 8;
+ return sp;
+}
+
+/* Function: push_return_address (pc)
+ Set up the return address for the inferior function call.
+ Needed for targets where we don't actually execute a JSR/BSR instruction */
+
+static CORE_ADDR
+mn10300_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ unsigned char buf[4];
+
+ store_unsigned_integer (buf, 4, CALL_DUMMY_ADDRESS ());
+ write_memory (sp - 4, buf, 4);
+ return sp - 4;
+}
+
+/* Function: store_struct_return (addr,sp)
+ Store the structure value return address for an inferior function
+ call. */
+
+static void
+mn10300_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ /* The structure return address is passed as the first argument. */
+ write_register (0, addr);
+}
+
+/* Function: frame_saved_pc
+ Find the caller of this frame. We do this by seeing if RP_REGNUM
+ is saved in the stack anywhere, otherwise we get it from the
+ registers. If the inner frame is a dummy frame, return its PC
+ instead of RP, because that's where "caller" of the dummy-frame
+ will be found. */
+
+static CORE_ADDR
+mn10300_frame_saved_pc (struct frame_info *fi)
+{
+ int adjust = saved_regs_size (fi);
+
+ return (read_memory_integer (fi->frame + adjust, REGISTER_SIZE));
+}
+
+/* Function: mn10300_init_extra_frame_info
+ Setup the frame's frame pointer, pc, and frame addresses for saved
+ registers. Most of the work is done in mn10300_analyze_prologue().
+
+ Note that when we are called for the last frame (currently active frame),
+ that fi->pc and fi->frame will already be setup. However, fi->frame will
+ be valid only if this routine uses FP. For previous frames, fi-frame will
+ always be correct. mn10300_analyze_prologue will fix fi->frame if
+ it's not valid.
+
+ We can be called with the PC in the call dummy under two circumstances.
+ First, during normal backtracing, second, while figuring out the frame
+ pointer just prior to calling the target function (see run_stack_dummy). */
+
+static void
+mn10300_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ frame_saved_regs_zalloc (fi);
+ fi->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+
+ fi->extra_info->status = 0;
+ fi->extra_info->stack_size = 0;
+
+ mn10300_analyze_prologue (fi, 0);
+}
+
+
+/* This function's job is handled by init_extra_frame_info. */
+static void
+mn10300_frame_init_saved_regs (struct frame_info *frame)
+{
+}
+
+
+/* Function: mn10300_virtual_frame_pointer
+ Return the register that the function uses for a frame pointer,
+ plus any necessary offset to be applied to the register before
+ any frame pointer offsets. */
+
+static void
+mn10300_virtual_frame_pointer (CORE_ADDR pc,
+ int *reg,
+ LONGEST *offset)
+{
+ struct frame_info *dummy = analyze_dummy_frame (pc, 0);
+ /* Set up a dummy frame_info, Analyze the prolog and fill in the
+ extra info. */
+ /* Results will tell us which type of frame it uses. */
+ if (dummy->extra_info->status & MY_FRAME_IN_SP)
+ {
+ *reg = SP_REGNUM;
+ *offset = -(dummy->extra_info->stack_size);
+ }
+ else
+ {
+ *reg = A3_REGNUM;
+ *offset = 0;
+ }
+}
+
+static int
+mn10300_reg_struct_has_addr (int gcc_p, struct type *type)
+{
+ return (TYPE_LENGTH (type) > 8);
+}
+
+static struct type *
+mn10300_register_virtual_type (int reg)
+{
+ return builtin_type_int;
+}
+
+static int
+mn10300_register_byte (int reg)
+{
+ return (reg * 4);
+}
+
+static int
+mn10300_register_virtual_size (int reg)
+{
+ return 4;
+}
+
+static int
+mn10300_register_raw_size (int reg)
+{
+ return 4;
+}
+
+/* If DWARF2 is a register number appearing in Dwarf2 debug info, then
+ mn10300_dwarf2_reg_to_regnum (DWARF2) is the corresponding GDB
+ register number. Why don't Dwarf2 and GDB use the same numbering?
+ Who knows? But since people have object files lying around with
+ the existing Dwarf2 numbering, and other people have written stubs
+ to work with the existing GDB, neither of them can change. So we
+ just have to cope. */
+static int
+mn10300_dwarf2_reg_to_regnum (int dwarf2)
+{
+ /* This table is supposed to be shaped like the REGISTER_NAMES
+ initializer in gcc/config/mn10300/mn10300.h. Registers which
+ appear in GCC's numbering, but have no counterpart in GDB's
+ world, are marked with a -1. */
+ static int dwarf2_to_gdb[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, -1, 8,
+ 15, 16, 17, 18, 19, 20, 21, 22
+ };
+ int gdb;
+
+ if (dwarf2 < 0
+ || dwarf2 >= (sizeof (dwarf2_to_gdb) / sizeof (dwarf2_to_gdb[0]))
+ || dwarf2_to_gdb[dwarf2] == -1)
+ internal_error (__FILE__, __LINE__,
+ "bogus register number in debug info: %d", dwarf2);
+
+ return dwarf2_to_gdb[dwarf2];
+}
+
+static void
+mn10300_print_register (const char *name, int regnum, int reg_width)
+{
+ char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
+
+ if (reg_width)
+ printf_filtered ("%*s: ", reg_width, name);
+ else
+ printf_filtered ("%s: ", name);
+
+ /* Get the data */
+ if (!frame_register_read (selected_frame, regnum, raw_buffer))
+ {
+ printf_filtered ("[invalid]");
+ return;
+ }
+ else
+ {
+ int byte;
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
+ byte < REGISTER_RAW_SIZE (regnum);
+ byte++)
+ printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
+ }
+ else
+ {
+ for (byte = REGISTER_VIRTUAL_SIZE (regnum) - 1;
+ byte >= 0;
+ byte--)
+ printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
+ }
+ }
+}
+
+static void
+mn10300_do_registers_info (int regnum, int fpregs)
+{
+ if (regnum >= 0)
+ {
+ const char *name = REGISTER_NAME (regnum);
+ if (name == NULL || name[0] == '\0')
+ error ("Not a valid register for the current processor type");
+ mn10300_print_register (name, regnum, 0);
+ printf_filtered ("\n");
+ }
+ else
+ {
+ /* print registers in an array 4x8 */
+ int r;
+ int reg;
+ const int nr_in_row = 4;
+ const int reg_width = 4;
+ for (r = 0; r < NUM_REGS; r += nr_in_row)
+ {
+ int c;
+ int printing = 0;
+ int padding = 0;
+ for (c = r; c < r + nr_in_row; c++)
+ {
+ const char *name = REGISTER_NAME (c);
+ if (name != NULL && *name != '\0')
+ {
+ printing = 1;
+ while (padding > 0)
+ {
+ printf_filtered (" ");
+ padding--;
+ }
+ mn10300_print_register (name, c, reg_width);
+ printf_filtered (" ");
+ }
+ else
+ {
+ padding += (reg_width + 2 + 8 + 1);
+ }
+ }
+ if (printing)
+ printf_filtered ("\n");
+ }
+ }
+}
+
+/* Dump out the mn10300 speciic architecture information. */
+
+static void
+mn10300_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ fprintf_unfiltered (file, "mn10300_dump_tdep: am33_mode = %d\n",
+ tdep->am33_mode);
+}
+
+static struct gdbarch *
+mn10300_gdbarch_init (struct gdbarch_info info,
+ struct gdbarch_list *arches)
+{
+ static LONGEST mn10300_call_dummy_words[] = { 0 };
+ struct gdbarch *gdbarch;
+ struct gdbarch_tdep *tdep = NULL;
+ int am33_mode;
+ gdbarch_register_name_ftype *register_name;
+ int mach;
+ int num_regs;
+
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+ if (arches != NULL)
+ return arches->gdbarch;
+ tdep = xmalloc (sizeof (struct gdbarch_tdep));
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ if (info.bfd_arch_info != NULL
+ && info.bfd_arch_info->arch == bfd_arch_mn10300)
+ mach = info.bfd_arch_info->mach;
+ else
+ mach = 0;
+ switch (mach)
+ {
+ case 0:
+ case bfd_mach_mn10300:
+ am33_mode = 0;
+ register_name = mn10300_generic_register_name;
+ num_regs = 32;
+ break;
+ case bfd_mach_am33:
+ am33_mode = 1;
+ register_name = am33_register_name;
+ num_regs = 32;
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "mn10300_gdbarch_init: Unknown mn10300 variant");
+ return NULL; /* keep GCC happy. */
+ }
+
+ /* Registers. */
+ set_gdbarch_num_regs (gdbarch, num_regs);
+ set_gdbarch_register_name (gdbarch, register_name);
+ set_gdbarch_register_size (gdbarch, 4);
+ set_gdbarch_register_bytes (gdbarch,
+ num_regs * gdbarch_register_size (gdbarch));
+ set_gdbarch_max_register_raw_size (gdbarch, 4);
+ set_gdbarch_register_raw_size (gdbarch, mn10300_register_raw_size);
+ set_gdbarch_register_byte (gdbarch, mn10300_register_byte);
+ set_gdbarch_max_register_virtual_size (gdbarch, 4);
+ set_gdbarch_register_virtual_size (gdbarch, mn10300_register_virtual_size);
+ set_gdbarch_register_virtual_type (gdbarch, mn10300_register_virtual_type);
+ set_gdbarch_dwarf2_reg_to_regnum (gdbarch, mn10300_dwarf2_reg_to_regnum);
+ set_gdbarch_do_registers_info (gdbarch, mn10300_do_registers_info);
+ set_gdbarch_sp_regnum (gdbarch, 8);
+ set_gdbarch_pc_regnum (gdbarch, 9);
+ set_gdbarch_fp_regnum (gdbarch, 31);
+ set_gdbarch_virtual_frame_pointer (gdbarch, mn10300_virtual_frame_pointer);
+
+ /* Breakpoints. */
+ set_gdbarch_breakpoint_from_pc (gdbarch, mn10300_breakpoint_from_pc);
+ set_gdbarch_function_start_offset (gdbarch, 0);
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+
+ /* Stack unwinding. */
+ set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+ set_gdbarch_frame_chain_valid (gdbarch, generic_file_frame_chain_valid);
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+ set_gdbarch_frame_chain_valid (gdbarch, generic_file_frame_chain_valid);
+ set_gdbarch_saved_pc_after_call (gdbarch, mn10300_saved_pc_after_call);
+ set_gdbarch_init_extra_frame_info (gdbarch, mn10300_init_extra_frame_info);
+ set_gdbarch_init_frame_pc (gdbarch, init_frame_pc_noop);
+ set_gdbarch_frame_init_saved_regs (gdbarch, mn10300_frame_init_saved_regs);
+ set_gdbarch_frame_chain (gdbarch, mn10300_frame_chain);
+ set_gdbarch_frame_saved_pc (gdbarch, mn10300_frame_saved_pc);
+ set_gdbarch_extract_return_value (gdbarch, mn10300_extract_return_value);
+ set_gdbarch_extract_struct_value_address
+ (gdbarch, mn10300_extract_struct_value_address);
+ set_gdbarch_store_return_value (gdbarch, mn10300_store_return_value);
+ set_gdbarch_store_struct_return (gdbarch, mn10300_store_struct_return);
+ set_gdbarch_pop_frame (gdbarch, mn10300_pop_frame);
+ set_gdbarch_skip_prologue (gdbarch, mn10300_skip_prologue);
+ set_gdbarch_frame_args_skip (gdbarch, 0);
+ set_gdbarch_frame_args_address (gdbarch, default_frame_address);
+ set_gdbarch_frame_locals_address (gdbarch, default_frame_address);
+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+ /* That's right, we're using the stack pointer as our frame pointer. */
+ set_gdbarch_read_fp (gdbarch, generic_target_read_sp);
+
+ /* Calling functions in the inferior from GDB. */
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
+ set_gdbarch_call_dummy_words (gdbarch, mn10300_call_dummy_words);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch,
+ sizeof (mn10300_call_dummy_words));
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+ set_gdbarch_push_arguments (gdbarch, mn10300_push_arguments);
+ set_gdbarch_reg_struct_has_addr (gdbarch, mn10300_reg_struct_has_addr);
+ set_gdbarch_push_return_address (gdbarch, mn10300_push_return_address);
+ set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
+ set_gdbarch_use_struct_convention (gdbarch, mn10300_use_struct_convention);
+
+ tdep->am33_mode = am33_mode;
+
+ return gdbarch;
+}
+
+void
+_initialize_mn10300_tdep (void)
+{
+/* printf("_initialize_mn10300_tdep\n"); */
+
+ tm_print_insn = print_insn_mn10300;
+
+ register_gdbarch_init (bfd_arch_mn10300, mn10300_gdbarch_init);
+}
diff --git a/gdb/mon960-rom.c b/gdb/mon960-rom.c
new file mode 100644
index 00000000000..2b7fe5fd58d
--- /dev/null
+++ b/gdb/mon960-rom.c
@@ -0,0 +1,260 @@
+/* Remote target glue for the Intel 960 MON960 ROM monitor.
+ Copyright 1995, 1996, 1997, 1998, 1999, 2000
+ 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "srec.h"
+#include "xmodem.h"
+#include "symtab.h"
+#include "symfile.h" /* for generic_load */
+#include "inferior.h" /* for write_pc() */
+
+#define USE_GENERIC_LOAD
+
+static struct target_ops mon960_ops;
+
+static void mon960_open (char *args, int from_tty);
+
+#ifdef USE_GENERIC_LOAD
+
+static void
+mon960_load_gen (char *filename, int from_tty)
+{
+ generic_load (filename, from_tty);
+ /* Finally, make the PC point at the start address */
+ if (exec_bfd)
+ write_pc (bfd_get_start_address (exec_bfd));
+
+ inferior_ptid = null_ptid; /* No process now */
+}
+
+#else
+
+static void
+mon960_load (struct serial *desc, char *file, int hashmark)
+{
+ bfd *abfd;
+ asection *s;
+ char *buffer;
+ int i;
+
+ buffer = alloca (XMODEM_PACKETSIZE);
+ abfd = bfd_openr (file, 0);
+ if (!abfd)
+ {
+ printf_filtered ("Unable to open file %s\n", file);
+ return;
+ }
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ {
+ printf_filtered ("File is not an object file\n");
+ return;
+ }
+ for (s = abfd->sections; s; s = s->next)
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_size_type section_size;
+ printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma,
+ s->vma + s->_raw_size);
+ gdb_flush (gdb_stdout);
+ monitor_printf (current_monitor->load, s->vma);
+ if (current_monitor->loadresp)
+ monitor_expect (current_monitor->loadresp, NULL, 0);
+ xmodem_init_xfer (desc);
+ section_size = bfd_section_size (abfd, s);
+ for (i = 0; i < section_size; i += XMODEM_DATASIZE)
+ {
+ int numbytes;
+ numbytes = min (XMODEM_DATASIZE, section_size - i);
+ bfd_get_section_contents (abfd, s, buffer + XMODEM_DATAOFFSET, i,
+ numbytes);
+ xmodem_send_packet (desc, buffer, numbytes, hashmark);
+ if (hashmark)
+ {
+ putchar_unfiltered ('#');
+ gdb_flush (gdb_stdout);
+ }
+ } /* Per-packet (or S-record) loop */
+ xmodem_finish_xfer (desc);
+ monitor_expect_prompt (NULL, 0);
+ putchar_unfiltered ('\n');
+ } /* Loadable sections */
+ if (hashmark)
+ putchar_unfiltered ('\n');
+}
+
+#endif /* USE_GENERIC_LOAD */
+
+/* This array of registers need to match the indexes used by GDB.
+ This exists because the various ROM monitors use different strings
+ than does GDB, and don't necessarily support all the registers
+ either. So, typing "info reg sp" becomes a "r30". */
+
+/* these correspond to the offsets from tm-* files from config directories */
+/* g0-g14, fp, pfp, sp, rip,r3-15, pc, ac, tc, fp0-3 */
+/* NOTE: "ip" is documented as "ir" in the Mon960 UG. */
+/* NOTE: "ir" can't be accessed... but there's an ip and rip. */
+static char *full_regnames[NUM_REGS] =
+{
+ /* 0 */ "pfp", "sp", "rip", "r3", "r4", "r5", "r6", "r7",
+ /* 8 */ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ /* 16 */ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ /* 24 */ "g8", "g9", "g10", "g11", "g12", "g13", "g14", "fp",
+ /* 32 */ "pc", "ac", "tc", "ip", "fp0", "fp1", "fp2", "fp3",
+};
+
+static char *mon960_regnames[NUM_REGS];
+
+/* Define the monitor command strings. Since these are passed directly
+ through to a printf style function, we may include formatting
+ strings. We also need a CR or LF on the end. */
+
+/* need to pause the monitor for timing reasons, so slow it down */
+
+#if 0
+/* FIXME: this extremely long init string causes MON960 to return two NAKS
+ instead of performing the autobaud recognition, at least when gdb
+ is running on GNU/Linux. The short string below works on Linux, and on
+ SunOS using a tcp serial connection. Must retest on SunOS using a
+ direct serial connection; if that works, get rid of the long string. */
+static char *mon960_inits[] =
+{"\n\r\r\r\r\r\r\r\r\r\r\r\r\r\r\n\r\n\r\n", NULL};
+#else
+static char *mon960_inits[] =
+{"\r", NULL};
+#endif
+
+static struct monitor_ops mon960_cmds;
+
+static void
+init_mon960_cmds (void)
+{
+ mon960_cmds.flags = MO_CLR_BREAK_USES_ADDR
+ | MO_NO_ECHO_ON_OPEN | MO_SEND_BREAK_ON_STOP | MO_GETMEM_READ_SINGLE; /* flags */
+ mon960_cmds.init = mon960_inits; /* Init strings */
+ mon960_cmds.cont = "go\n\r"; /* continue command */
+ mon960_cmds.step = "st\n\r"; /* single step */
+ mon960_cmds.stop = NULL; /* break interrupts the program */
+ mon960_cmds.set_break = NULL; /* set a breakpoint */
+ mon960_cmds.clr_break = /* can't use "br" because only 2 hw bps are supported */
+ mon960_cmds.clr_all_break = NULL; /* clear a breakpoint - "de" is for hw bps */
+ NULL, /* clear all breakpoints */
+ mon960_cmds.fill = NULL; /* fill (start end val) */
+ /* can't use "fi" because it takes words, not bytes */
+ /* can't use "mb", "md" or "mo" because they require interaction */
+ mon960_cmds.setmem.cmdb = NULL; /* setmem.cmdb (addr, value) */
+ mon960_cmds.setmem.cmdw = NULL; /* setmem.cmdw (addr, value) */
+ mon960_cmds.setmem.cmdl = "md %x %x\n\r"; /* setmem.cmdl (addr, value) */
+ mon960_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ mon960_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */
+ mon960_cmds.setmem.term = NULL; /* setmem.term */
+ mon960_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */
+ /* since the parsing of multiple bytes is difficult due to
+ interspersed addresses, we'll only read 1 value at a time,
+ even tho these can handle a count */
+ mon960_cmds.getmem.cmdb = "db %x\n\r"; /* getmem.cmdb (addr, #bytes) */
+ mon960_cmds.getmem.cmdw = "ds %x\n\r"; /* getmem.cmdw (addr, #swords) */
+ mon960_cmds.getmem.cmdl = "di %x\n\r"; /* getmem.cmdl (addr, #words) */
+ mon960_cmds.getmem.cmdll = "dd %x\n\r"; /* getmem.cmdll (addr, #dwords) */
+ mon960_cmds.getmem.resp_delim = " : "; /* getmem.resp_delim */
+ mon960_cmds.getmem.term = NULL; /* getmem.term */
+ mon960_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
+ mon960_cmds.setreg.cmd = "md %s %x\n\r"; /* setreg.cmd (name, value) */
+ mon960_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ mon960_cmds.setreg.term = NULL; /* setreg.term */
+ mon960_cmds.setreg.term_cmd = NULL, /* setreg.term_cmd */
+ mon960_cmds.getreg.cmd = "di %s\n\r"; /* getreg.cmd (name) */
+ mon960_cmds.getreg.resp_delim = " : "; /* getreg.resp_delim */
+ mon960_cmds.getreg.term = NULL; /* getreg.term */
+ mon960_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
+ mon960_cmds.dump_registers = "re\n\r"; /* dump_registers */
+ mon960_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */
+ mon960_cmds.supply_register = NULL; /* supply_register */
+#ifdef USE_GENERIC_LOAD
+ mon960_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ mon960_cmds.load = NULL; /* download command */
+ mon960_cmds.loadresp = NULL; /* load response */
+#else
+ mon960_cmds.load_routine = mon960_load; /* load_routine (defaults to SRECs) */
+ mon960_cmds.load = "do\n\r"; /* download command */
+ mon960_cmds.loadresp = "Downloading\n\r"; /* load response */
+#endif
+ mon960_cmds.prompt = "=>"; /* monitor command prompt */
+ mon960_cmds.line_term = "\n\r"; /* end-of-command delimitor */
+ mon960_cmds.cmd_end = NULL; /* optional command terminator */
+ mon960_cmds.target = &mon960_ops; /* target operations */
+ mon960_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ mon960_cmds.regnames = mon960_regnames; /* registers names */
+ mon960_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+};
+
+static void
+mon960_open (char *args, int from_tty)
+{
+ char buf[64];
+
+ monitor_open (args, &mon960_cmds, from_tty);
+
+ /* Attempt to fetch the value of the first floating point register (fp0).
+ If the monitor returns a string containing the word "Bad" we'll assume
+ this processor has no floating point registers, and nullify the
+ regnames entries that refer to FP registers. */
+
+ monitor_printf (mon960_cmds.getreg.cmd, full_regnames[FP0_REGNUM]); /* di fp0 */
+ if (monitor_expect_prompt (buf, sizeof (buf)) != -1)
+ if (strstr (buf, "Bad") != NULL)
+ {
+ int i;
+
+ for (i = FP0_REGNUM; i < FP0_REGNUM + 4; i++)
+ mon960_regnames[i] = NULL;
+ }
+}
+
+void
+_initialize_mon960 (void)
+{
+ memcpy (mon960_regnames, full_regnames, sizeof (full_regnames));
+
+ init_mon960_cmds ();
+
+ init_monitor_ops (&mon960_ops);
+
+ mon960_ops.to_shortname = "mon960"; /* for the target command */
+ mon960_ops.to_longname = "Intel 960 MON960 monitor";
+#ifdef USE_GENERIC_LOAD
+ mon960_ops.to_load = mon960_load_gen; /* FIXME - should go back and try "do" */
+#endif
+ /* use SW breaks; target only supports 2 HW breakpoints */
+ mon960_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ mon960_ops.to_remove_breakpoint = memory_remove_breakpoint;
+
+ mon960_ops.to_doc =
+ "Use an Intel 960 board running the MON960 debug monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+
+ mon960_ops.to_open = mon960_open;
+ add_target (&mon960_ops);
+}
diff --git a/gdb/monitor.c b/gdb/monitor.c
new file mode 100644
index 00000000000..81340d4be02
--- /dev/null
+++ b/gdb/monitor.c
@@ -0,0 +1,2386 @@
+/* Remote debugging interface for boot monitors, for GDB.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
+ Resurrected from the ashes by Stu Grossman.
+
+ 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. */
+
+/* This file was derived from various remote-* modules. It is a collection
+ of generic support functions so GDB can talk directly to a ROM based
+ monitor. This saves use from having to hack an exception based handler
+ into existence, and makes for quick porting.
+
+ This module talks to a debug monitor called 'MONITOR', which
+ We communicate with MONITOR via either a direct serial line, or a TCP
+ (or possibly TELNET) stream to a terminal multiplexor,
+ which in turn talks to the target board. */
+
+/* FIXME 32x64: This code assumes that registers and addresses are at
+ most 32 bits long. If they can be larger, you will need to declare
+ values as LONGEST and use %llx or some such to print values when
+ building commands to send to the monitor. Since we don't know of
+ any actual 64-bit targets with ROM monitors that use this code,
+ it's not an issue right now. -sts 4/18/96 */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include <signal.h>
+#include <ctype.h>
+#include "gdb_string.h"
+#include <sys/types.h>
+#include "command.h"
+#include "serial.h"
+#include "monitor.h"
+#include "gdbcmd.h"
+#include "inferior.h"
+#include "gdb_regex.h"
+#include "srec.h"
+#include "regcache.h"
+
+static char *dev_name;
+static struct target_ops *targ_ops;
+
+static void monitor_vsprintf (char *sndbuf, char *pattern, va_list args);
+
+static int readchar (int timeout);
+
+static void monitor_fetch_register (int regno);
+static void monitor_store_register (int regno);
+
+static void monitor_printable_string (char *newstr, char *oldstr, int len);
+static void monitor_error (char *function, char *message, CORE_ADDR memaddr, int len, char *string, int final_char);
+static void monitor_detach (char *args, int from_tty);
+static void monitor_resume (ptid_t ptid, int step, enum target_signal sig);
+static void monitor_interrupt (int signo);
+static void monitor_interrupt_twice (int signo);
+static void monitor_interrupt_query (void);
+static void monitor_wait_cleanup (void *old_timeout);
+
+static ptid_t monitor_wait (ptid_t ptid, struct target_waitstatus *status);
+static void monitor_fetch_registers (int regno);
+static void monitor_store_registers (int regno);
+static void monitor_prepare_to_store (void);
+static int monitor_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int write,
+ struct mem_attrib *attrib,
+ struct target_ops *target);
+static void monitor_files_info (struct target_ops *ops);
+static int monitor_insert_breakpoint (CORE_ADDR addr, char *shadow);
+static int monitor_remove_breakpoint (CORE_ADDR addr, char *shadow);
+static void monitor_kill (void);
+static void monitor_load (char *file, int from_tty);
+static void monitor_mourn_inferior (void);
+static void monitor_stop (void);
+
+static int monitor_read_memory (CORE_ADDR addr, char *myaddr, int len);
+static int monitor_write_memory (CORE_ADDR addr, char *myaddr, int len);
+static int monitor_write_memory_bytes (CORE_ADDR addr, char *myaddr, int len);
+static int monitor_write_memory_block (CORE_ADDR memaddr,
+ char *myaddr, int len);
+static int monitor_expect_regexp (struct re_pattern_buffer *pat,
+ char *buf, int buflen);
+static void monitor_dump_regs (void);
+#if 0
+static int from_hex (int a);
+static unsigned long get_hex_word (void);
+#endif
+static void parse_register_dump (char *, int);
+
+static struct monitor_ops *current_monitor;
+
+static int hashmark; /* flag set by "set hash" */
+
+static int timeout = 30;
+
+static int in_monitor_wait = 0; /* Non-zero means we are in monitor_wait() */
+
+static void (*ofunc) (); /* Old SIGINT signal handler */
+
+static CORE_ADDR *breakaddr;
+
+/* Descriptor for I/O to remote machine. Initialize it to NULL so
+ that monitor_open knows that we don't have a file open when the
+ program starts. */
+
+static struct serial *monitor_desc = NULL;
+
+/* Pointer to regexp pattern matching data */
+
+static struct re_pattern_buffer register_pattern;
+static char register_fastmap[256];
+
+static struct re_pattern_buffer getmem_resp_delim_pattern;
+static char getmem_resp_delim_fastmap[256];
+
+static struct re_pattern_buffer setmem_resp_delim_pattern;
+static char setmem_resp_delim_fastmap[256];
+
+static struct re_pattern_buffer setreg_resp_delim_pattern;
+static char setreg_resp_delim_fastmap[256];
+
+static int dump_reg_flag; /* Non-zero means do a dump_registers cmd when
+ monitor_wait wakes up. */
+
+static int first_time = 0; /* is this the first time we're executing after
+ gaving created the child proccess? */
+
+#define TARGET_BUF_SIZE 2048
+
+/* Monitor specific debugging information. Typically only useful to
+ the developer of a new monitor interface. */
+
+static void monitor_debug (const char *fmt, ...) ATTR_FORMAT(printf, 1, 2);
+
+static int monitor_debug_p = 0;
+
+/* NOTE: This file alternates between monitor_debug_p and remote_debug
+ when determining if debug information is printed. Perhaphs this
+ could be simplified. */
+
+static void
+monitor_debug (const char *fmt, ...)
+{
+ if (monitor_debug_p)
+ {
+ va_list args;
+ va_start (args, fmt);
+ vfprintf_filtered (gdb_stdlog, fmt, args);
+ va_end (args);
+ }
+}
+
+
+/* Convert a string into a printable representation, Return # byte in
+ the new string. When LEN is >0 it specifies the size of the
+ string. Otherwize strlen(oldstr) is used. */
+
+static void
+monitor_printable_string (char *newstr, char *oldstr, int len)
+{
+ int ch;
+ int i;
+
+ if (len <= 0)
+ len = strlen (oldstr);
+
+ for (i = 0; i < len; i++)
+ {
+ ch = oldstr[i];
+ switch (ch)
+ {
+ default:
+ if (isprint (ch))
+ *newstr++ = ch;
+
+ else
+ {
+ sprintf (newstr, "\\x%02x", ch & 0xff);
+ newstr += 4;
+ }
+ break;
+
+ case '\\':
+ *newstr++ = '\\';
+ *newstr++ = '\\';
+ break;
+ case '\b':
+ *newstr++ = '\\';
+ *newstr++ = 'b';
+ break;
+ case '\f':
+ *newstr++ = '\\';
+ *newstr++ = 't';
+ break;
+ case '\n':
+ *newstr++ = '\\';
+ *newstr++ = 'n';
+ break;
+ case '\r':
+ *newstr++ = '\\';
+ *newstr++ = 'r';
+ break;
+ case '\t':
+ *newstr++ = '\\';
+ *newstr++ = 't';
+ break;
+ case '\v':
+ *newstr++ = '\\';
+ *newstr++ = 'v';
+ break;
+ }
+ }
+
+ *newstr++ = '\0';
+}
+
+/* Print monitor errors with a string, converting the string to printable
+ representation. */
+
+static void
+monitor_error (char *function, char *message,
+ CORE_ADDR memaddr, int len, char *string, int final_char)
+{
+ int real_len = (len == 0 && string != (char *) 0) ? strlen (string) : len;
+ char *safe_string = alloca ((real_len * 4) + 1);
+ monitor_printable_string (safe_string, string, real_len);
+
+ if (final_char)
+ error ("%s (0x%s): %s: %s%c", function, paddr_nz (memaddr), message, safe_string, final_char);
+ else
+ error ("%s (0x%s): %s: %s", function, paddr_nz (memaddr), message, safe_string);
+}
+
+/* Convert hex digit A to a number. */
+
+static int
+fromhex (int a)
+{
+ if (a >= '0' && a <= '9')
+ return a - '0';
+ else if (a >= 'a' && a <= 'f')
+ return a - 'a' + 10;
+ else if (a >= 'A' && a <= 'F')
+ return a - 'A' + 10;
+ else
+ error ("Invalid hex digit %d", a);
+}
+
+/* monitor_vsprintf - similar to vsprintf but handles 64-bit addresses
+
+ This function exists to get around the problem that many host platforms
+ don't have a printf that can print 64-bit addresses. The %A format
+ specification is recognized as a special case, and causes the argument
+ to be printed as a 64-bit hexadecimal address.
+
+ Only format specifiers of the form "[0-9]*[a-z]" are recognized.
+ If it is a '%s' format, the argument is a string; otherwise the
+ argument is assumed to be a long integer.
+
+ %% is also turned into a single %.
+ */
+
+static void
+monitor_vsprintf (char *sndbuf, char *pattern, va_list args)
+{
+ char format[10];
+ char fmt;
+ char *p;
+ int i;
+ long arg_int;
+ CORE_ADDR arg_addr;
+ char *arg_string;
+
+ for (p = pattern; *p; p++)
+ {
+ if (*p == '%')
+ {
+ /* Copy the format specifier to a separate buffer. */
+ format[0] = *p++;
+ for (i = 1; *p >= '0' && *p <= '9' && i < (int) sizeof (format) - 2;
+ i++, p++)
+ format[i] = *p;
+ format[i] = fmt = *p;
+ format[i + 1] = '\0';
+
+ /* Fetch the next argument and print it. */
+ switch (fmt)
+ {
+ case '%':
+ strcpy (sndbuf, "%");
+ break;
+ case 'A':
+ arg_addr = va_arg (args, CORE_ADDR);
+ strcpy (sndbuf, paddr_nz (arg_addr));
+ break;
+ case 's':
+ arg_string = va_arg (args, char *);
+ sprintf (sndbuf, format, arg_string);
+ break;
+ default:
+ arg_int = va_arg (args, long);
+ sprintf (sndbuf, format, arg_int);
+ break;
+ }
+ sndbuf += strlen (sndbuf);
+ }
+ else
+ *sndbuf++ = *p;
+ }
+ *sndbuf = '\0';
+}
+
+
+/* monitor_printf_noecho -- Send data to monitor, but don't expect an echo.
+ Works just like printf. */
+
+void
+monitor_printf_noecho (char *pattern,...)
+{
+ va_list args;
+ char sndbuf[2000];
+ int len;
+
+ va_start (args, pattern);
+
+ monitor_vsprintf (sndbuf, pattern, args);
+
+ len = strlen (sndbuf);
+ if (len + 1 > sizeof sndbuf)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+ if (monitor_debug_p)
+ {
+ char *safe_string = (char *) alloca ((strlen (sndbuf) * 4) + 1);
+ monitor_printable_string (safe_string, sndbuf, 0);
+ fprintf_unfiltered (gdb_stdlog, "sent[%s]\n", safe_string);
+ }
+
+ monitor_write (sndbuf, len);
+}
+
+/* monitor_printf -- Send data to monitor and check the echo. Works just like
+ printf. */
+
+void
+monitor_printf (char *pattern,...)
+{
+ va_list args;
+ char sndbuf[2000];
+ int len;
+
+ va_start (args, pattern);
+
+ monitor_vsprintf (sndbuf, pattern, args);
+
+ len = strlen (sndbuf);
+ if (len + 1 > sizeof sndbuf)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+ if (monitor_debug_p)
+ {
+ char *safe_string = (char *) alloca ((len * 4) + 1);
+ monitor_printable_string (safe_string, sndbuf, 0);
+ fprintf_unfiltered (gdb_stdlog, "sent[%s]\n", safe_string);
+ }
+
+ monitor_write (sndbuf, len);
+
+ /* We used to expect that the next immediate output was the characters we
+ just output, but sometimes some extra junk appeared before the characters
+ we expected, like an extra prompt, or a portmaster sending telnet negotiations.
+ So, just start searching for what we sent, and skip anything unknown. */
+ monitor_debug ("ExpectEcho\n");
+ monitor_expect (sndbuf, (char *) 0, 0);
+}
+
+
+/* Write characters to the remote system. */
+
+void
+monitor_write (char *buf, int buflen)
+{
+ if (serial_write (monitor_desc, buf, buflen))
+ fprintf_unfiltered (gdb_stderr, "serial_write failed: %s\n",
+ safe_strerror (errno));
+}
+
+
+/* Read a binary character from the remote system, doing all the fancy
+ timeout stuff, but without interpreting the character in any way,
+ and without printing remote debug information. */
+
+int
+monitor_readchar (void)
+{
+ int c;
+ int looping;
+
+ do
+ {
+ looping = 0;
+ c = serial_readchar (monitor_desc, timeout);
+
+ if (c >= 0)
+ c &= 0xff; /* don't lose bit 7 */
+ }
+ while (looping);
+
+ if (c >= 0)
+ return c;
+
+ if (c == SERIAL_TIMEOUT)
+ error ("Timeout reading from remote system.");
+
+ perror_with_name ("remote-monitor");
+}
+
+
+/* Read a character from the remote system, doing all the fancy
+ timeout stuff. */
+
+static int
+readchar (int timeout)
+{
+ int c;
+ static enum
+ {
+ last_random, last_nl, last_cr, last_crnl
+ }
+ state = last_random;
+ int looping;
+
+ do
+ {
+ looping = 0;
+ c = serial_readchar (monitor_desc, timeout);
+
+ if (c >= 0)
+ {
+ c &= 0x7f;
+ /* This seems to interfere with proper function of the
+ input stream */
+ if (monitor_debug_p || remote_debug)
+ {
+ char buf[2];
+ buf[0] = c;
+ buf[1] = '\0';
+ puts_debug ("read -->", buf, "<--");
+ }
+
+ }
+
+ /* Canonicialize \n\r combinations into one \r */
+ if ((current_monitor->flags & MO_HANDLE_NL) != 0)
+ {
+ if ((c == '\r' && state == last_nl)
+ || (c == '\n' && state == last_cr))
+ {
+ state = last_crnl;
+ looping = 1;
+ }
+ else if (c == '\r')
+ state = last_cr;
+ else if (c != '\n')
+ state = last_random;
+ else
+ {
+ state = last_nl;
+ c = '\r';
+ }
+ }
+ }
+ while (looping);
+
+ if (c >= 0)
+ return c;
+
+ if (c == SERIAL_TIMEOUT)
+#if 0
+ /* I fail to see how detaching here can be useful */
+ if (in_monitor_wait) /* Watchdog went off */
+ {
+ target_mourn_inferior ();
+ error ("GDB serial timeout has expired. Target detached.\n");
+ }
+ else
+#endif
+ error ("Timeout reading from remote system.");
+
+ perror_with_name ("remote-monitor");
+}
+
+/* Scan input from the remote system, until STRING is found. If BUF is non-
+ zero, then collect input until we have collected either STRING or BUFLEN-1
+ chars. In either case we terminate BUF with a 0. If input overflows BUF
+ because STRING can't be found, return -1, else return number of chars in BUF
+ (minus the terminating NUL). Note that in the non-overflow case, STRING
+ will be at the end of BUF. */
+
+int
+monitor_expect (char *string, char *buf, int buflen)
+{
+ char *p = string;
+ int obuflen = buflen;
+ int c;
+ extern struct target_ops *targ_ops;
+
+ if (monitor_debug_p)
+ {
+ char *safe_string = (char *) alloca ((strlen (string) * 4) + 1);
+ monitor_printable_string (safe_string, string, 0);
+ fprintf_unfiltered (gdb_stdlog, "MON Expecting '%s'\n", safe_string);
+ }
+
+ immediate_quit++;
+ while (1)
+ {
+ if (buf)
+ {
+ if (buflen < 2)
+ {
+ *buf = '\000';
+ immediate_quit--;
+ return -1;
+ }
+
+ c = readchar (timeout);
+ if (c == '\000')
+ continue;
+ *buf++ = c;
+ buflen--;
+ }
+ else
+ c = readchar (timeout);
+
+ /* Don't expect any ^C sent to be echoed */
+
+ if (*p == '\003' || c == *p)
+ {
+ p++;
+ if (*p == '\0')
+ {
+ immediate_quit--;
+
+ if (buf)
+ {
+ *buf++ = '\000';
+ return obuflen - buflen;
+ }
+ else
+ return 0;
+ }
+ }
+ else if ((c == '\021' || c == '\023') &&
+ (STREQ (targ_ops->to_shortname, "m32r")
+ || STREQ (targ_ops->to_shortname, "mon2000")))
+ { /* m32r monitor emits random DC1/DC3 chars */
+ continue;
+ }
+ else
+ {
+ /* We got a character that doesn't match the string. We need to
+ back up p, but how far? If we're looking for "..howdy" and the
+ monitor sends "...howdy"? There's certainly a match in there,
+ but when we receive the third ".", we won't find it if we just
+ restart the matching at the beginning of the string.
+
+ This is a Boyer-Moore kind of situation. We want to reset P to
+ the end of the longest prefix of STRING that is a suffix of
+ what we've read so far. In the example above, that would be
+ ".." --- the longest prefix of "..howdy" that is a suffix of
+ "...". This longest prefix could be the empty string, if C
+ is nowhere to be found in STRING.
+
+ If this longest prefix is not the empty string, it must contain
+ C, so let's search from the end of STRING for instances of C,
+ and see if the portion of STRING before that is a suffix of
+ what we read before C. Actually, we can search backwards from
+ p, since we know no prefix can be longer than that.
+
+ Note that we can use STRING itself, along with C, as a record
+ of what we've received so far. :) */
+ int i;
+
+ for (i = (p - string) - 1; i >= 0; i--)
+ if (string[i] == c)
+ {
+ /* Is this prefix a suffix of what we've read so far?
+ In other words, does
+ string[0 .. i-1] == string[p - i, p - 1]? */
+ if (! memcmp (string, p - i, i))
+ {
+ p = string + i + 1;
+ break;
+ }
+ }
+ if (i < 0)
+ p = string;
+ }
+ }
+}
+
+/* Search for a regexp. */
+
+static int
+monitor_expect_regexp (struct re_pattern_buffer *pat, char *buf, int buflen)
+{
+ char *mybuf;
+ char *p;
+ monitor_debug ("MON Expecting regexp\n");
+ if (buf)
+ mybuf = buf;
+ else
+ {
+ mybuf = alloca (TARGET_BUF_SIZE);
+ buflen = TARGET_BUF_SIZE;
+ }
+
+ p = mybuf;
+ while (1)
+ {
+ int retval;
+
+ if (p - mybuf >= buflen)
+ { /* Buffer about to overflow */
+
+/* On overflow, we copy the upper half of the buffer to the lower half. Not
+ great, but it usually works... */
+
+ memcpy (mybuf, mybuf + buflen / 2, buflen / 2);
+ p = mybuf + buflen / 2;
+ }
+
+ *p++ = readchar (timeout);
+
+ retval = re_search (pat, mybuf, p - mybuf, 0, p - mybuf, NULL);
+ if (retval >= 0)
+ return 1;
+ }
+}
+
+/* Keep discarding input until we see the MONITOR prompt.
+
+ The convention for dealing with the prompt is that you
+ o give your command
+ o *then* wait for the prompt.
+
+ Thus the last thing that a procedure does with the serial line will
+ be an monitor_expect_prompt(). Exception: monitor_resume does not
+ wait for the prompt, because the terminal is being handed over to
+ the inferior. However, the next thing which happens after that is
+ a monitor_wait which does wait for the prompt. Note that this
+ includes abnormal exit, e.g. error(). This is necessary to prevent
+ getting into states from which we can't recover. */
+
+int
+monitor_expect_prompt (char *buf, int buflen)
+{
+ monitor_debug ("MON Expecting prompt\n");
+ return monitor_expect (current_monitor->prompt, buf, buflen);
+}
+
+/* Get N 32-bit words from remote, each preceded by a space, and put
+ them in registers starting at REGNO. */
+
+#if 0
+static unsigned long
+get_hex_word (void)
+{
+ unsigned long val;
+ int i;
+ int ch;
+
+ do
+ ch = readchar (timeout);
+ while (isspace (ch));
+
+ val = from_hex (ch);
+
+ for (i = 7; i >= 1; i--)
+ {
+ ch = readchar (timeout);
+ if (!isxdigit (ch))
+ break;
+ val = (val << 4) | from_hex (ch);
+ }
+
+ return val;
+}
+#endif
+
+static void
+compile_pattern (char *pattern, struct re_pattern_buffer *compiled_pattern,
+ char *fastmap)
+{
+ int tmp;
+ const char *val;
+
+ compiled_pattern->fastmap = fastmap;
+
+ tmp = re_set_syntax (RE_SYNTAX_EMACS);
+ val = re_compile_pattern (pattern,
+ strlen (pattern),
+ compiled_pattern);
+ re_set_syntax (tmp);
+
+ if (val)
+ error ("compile_pattern: Can't compile pattern string `%s': %s!", pattern, val);
+
+ if (fastmap)
+ re_compile_fastmap (compiled_pattern);
+}
+
+/* Open a connection to a remote debugger. NAME is the filename used
+ for communication. */
+
+void
+monitor_open (char *args, struct monitor_ops *mon_ops, int from_tty)
+{
+ char *name;
+ char **p;
+
+ if (mon_ops->magic != MONITOR_OPS_MAGIC)
+ error ("Magic number of monitor_ops struct wrong.");
+
+ targ_ops = mon_ops->target;
+ name = targ_ops->to_shortname;
+
+ if (!args)
+ error ("Use `target %s DEVICE-NAME' to use a serial port, or \n\
+`target %s HOST-NAME:PORT-NUMBER' to use a network connection.", name, name);
+
+ target_preopen (from_tty);
+
+ /* Setup pattern for register dump */
+
+ if (mon_ops->register_pattern)
+ compile_pattern (mon_ops->register_pattern, &register_pattern,
+ register_fastmap);
+
+ if (mon_ops->getmem.resp_delim)
+ compile_pattern (mon_ops->getmem.resp_delim, &getmem_resp_delim_pattern,
+ getmem_resp_delim_fastmap);
+
+ if (mon_ops->setmem.resp_delim)
+ compile_pattern (mon_ops->setmem.resp_delim, &setmem_resp_delim_pattern,
+ setmem_resp_delim_fastmap);
+
+ if (mon_ops->setreg.resp_delim)
+ compile_pattern (mon_ops->setreg.resp_delim, &setreg_resp_delim_pattern,
+ setreg_resp_delim_fastmap);
+
+ unpush_target (targ_ops);
+
+ if (dev_name)
+ xfree (dev_name);
+ dev_name = xstrdup (args);
+
+ monitor_desc = serial_open (dev_name);
+
+ if (!monitor_desc)
+ perror_with_name (dev_name);
+
+ if (baud_rate != -1)
+ {
+ if (serial_setbaudrate (monitor_desc, baud_rate))
+ {
+ serial_close (monitor_desc);
+ perror_with_name (dev_name);
+ }
+ }
+
+ serial_raw (monitor_desc);
+
+ serial_flush_input (monitor_desc);
+
+ /* some systems only work with 2 stop bits */
+
+ serial_setstopbits (monitor_desc, mon_ops->stopbits);
+
+ current_monitor = mon_ops;
+
+ /* See if we can wake up the monitor. First, try sending a stop sequence,
+ then send the init strings. Last, remove all breakpoints. */
+
+ if (current_monitor->stop)
+ {
+ monitor_stop ();
+ if ((current_monitor->flags & MO_NO_ECHO_ON_OPEN) == 0)
+ {
+ monitor_debug ("EXP Open echo\n");
+ monitor_expect_prompt (NULL, 0);
+ }
+ }
+
+ /* wake up the monitor and see if it's alive */
+ for (p = mon_ops->init; *p != NULL; p++)
+ {
+ /* Some of the characters we send may not be echoed,
+ but we hope to get a prompt at the end of it all. */
+
+ if ((current_monitor->flags & MO_NO_ECHO_ON_OPEN) == 0)
+ monitor_printf (*p);
+ else
+ monitor_printf_noecho (*p);
+ monitor_expect_prompt (NULL, 0);
+ }
+
+ serial_flush_input (monitor_desc);
+
+ /* Alloc breakpoints */
+ if (mon_ops->set_break != NULL)
+ {
+ if (mon_ops->num_breakpoints == 0)
+ mon_ops->num_breakpoints = 8;
+
+ breakaddr = (CORE_ADDR *) xmalloc (mon_ops->num_breakpoints * sizeof (CORE_ADDR));
+ memset (breakaddr, 0, mon_ops->num_breakpoints * sizeof (CORE_ADDR));
+ }
+
+ /* Remove all breakpoints */
+
+ if (mon_ops->clr_all_break)
+ {
+ monitor_printf (mon_ops->clr_all_break);
+ monitor_expect_prompt (NULL, 0);
+ }
+
+ if (from_tty)
+ printf_unfiltered ("Remote target %s connected to %s\n", name, dev_name);
+
+ push_target (targ_ops);
+
+ inferior_ptid = pid_to_ptid (42000); /* Make run command think we are busy... */
+
+ /* Give monitor_wait something to read */
+
+ monitor_printf (current_monitor->line_term);
+
+ start_remote ();
+}
+
+/* Close out all files and local state before this target loses
+ control. */
+
+void
+monitor_close (int quitting)
+{
+ if (monitor_desc)
+ serial_close (monitor_desc);
+
+ /* Free breakpoint memory */
+ if (breakaddr != NULL)
+ {
+ xfree (breakaddr);
+ breakaddr = NULL;
+ }
+
+ monitor_desc = NULL;
+}
+
+/* Terminate the open connection to the remote debugger. Use this
+ when you want to detach and do something else with your gdb. */
+
+static void
+monitor_detach (char *args, int from_tty)
+{
+ pop_target (); /* calls monitor_close to do the real work */
+ if (from_tty)
+ printf_unfiltered ("Ending remote %s debugging\n", target_shortname);
+}
+
+/* Convert VALSTR into the target byte-ordered value of REGNO and store it. */
+
+char *
+monitor_supply_register (int regno, char *valstr)
+{
+ ULONGEST val;
+ unsigned char regbuf[MAX_REGISTER_RAW_SIZE];
+ char *p;
+
+ val = 0;
+ p = valstr;
+ while (p && *p != '\0')
+ {
+ if (*p == '\r' || *p == '\n')
+ {
+ while (*p != '\0')
+ p++;
+ break;
+ }
+ if (isspace (*p))
+ {
+ p++;
+ continue;
+ }
+ if (!isxdigit (*p) && *p != 'x')
+ {
+ break;
+ }
+
+ val <<= 4;
+ val += fromhex (*p++);
+ }
+ monitor_debug ("Supplying Register %d %s\n", regno, valstr);
+
+ if (val == 0 && valstr == p)
+ error ("monitor_supply_register (%d): bad value from monitor: %s.",
+ regno, valstr);
+
+ /* supply register stores in target byte order, so swap here */
+
+ store_unsigned_integer (regbuf, REGISTER_RAW_SIZE (regno), val);
+
+ supply_register (regno, regbuf);
+
+ return p;
+}
+
+/* Tell the remote machine to resume. */
+
+static void
+monitor_resume (ptid_t ptid, int step, enum target_signal sig)
+{
+ /* Some monitors require a different command when starting a program */
+ monitor_debug ("MON resume\n");
+ if (current_monitor->flags & MO_RUN_FIRST_TIME && first_time == 1)
+ {
+ first_time = 0;
+ monitor_printf ("run\r");
+ if (current_monitor->flags & MO_NEED_REGDUMP_AFTER_CONT)
+ dump_reg_flag = 1;
+ return;
+ }
+ if (step)
+ monitor_printf (current_monitor->step);
+ else
+ {
+ if (current_monitor->continue_hook)
+ (*current_monitor->continue_hook) ();
+ else
+ monitor_printf (current_monitor->cont);
+ if (current_monitor->flags & MO_NEED_REGDUMP_AFTER_CONT)
+ dump_reg_flag = 1;
+ }
+}
+
+/* Parse the output of a register dump command. A monitor specific
+ regexp is used to extract individual register descriptions of the
+ form REG=VAL. Each description is split up into a name and a value
+ string which are passed down to monitor specific code. */
+
+static void
+parse_register_dump (char *buf, int len)
+{
+ monitor_debug ("MON Parsing register dump\n");
+ while (1)
+ {
+ int regnamelen, vallen;
+ char *regname, *val;
+ /* Element 0 points to start of register name, and element 1
+ points to the start of the register value. */
+ struct re_registers register_strings;
+
+ memset (&register_strings, 0, sizeof (struct re_registers));
+
+ if (re_search (&register_pattern, buf, len, 0, len,
+ &register_strings) == -1)
+ break;
+
+ regnamelen = register_strings.end[1] - register_strings.start[1];
+ regname = buf + register_strings.start[1];
+ vallen = register_strings.end[2] - register_strings.start[2];
+ val = buf + register_strings.start[2];
+
+ current_monitor->supply_register (regname, regnamelen, val, vallen);
+
+ buf += register_strings.end[0];
+ len -= register_strings.end[0];
+ }
+}
+
+/* Send ^C to target to halt it. Target will respond, and send us a
+ packet. */
+
+static void
+monitor_interrupt (int signo)
+{
+ /* If this doesn't work, try more severe steps. */
+ signal (signo, monitor_interrupt_twice);
+
+ if (monitor_debug_p || remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "monitor_interrupt called\n");
+
+ target_stop ();
+}
+
+/* The user typed ^C twice. */
+
+static void
+monitor_interrupt_twice (int signo)
+{
+ signal (signo, ofunc);
+
+ monitor_interrupt_query ();
+
+ signal (signo, monitor_interrupt);
+}
+
+/* Ask the user what to do when an interrupt is received. */
+
+static void
+monitor_interrupt_query (void)
+{
+ target_terminal_ours ();
+
+ if (query ("Interrupted while waiting for the program.\n\
+Give up (and stop debugging it)? "))
+ {
+ target_mourn_inferior ();
+ throw_exception (RETURN_QUIT);
+ }
+
+ target_terminal_inferior ();
+}
+
+static void
+monitor_wait_cleanup (void *old_timeout)
+{
+ timeout = *(int *) old_timeout;
+ signal (SIGINT, ofunc);
+ in_monitor_wait = 0;
+}
+
+
+
+void
+monitor_wait_filter (char *buf,
+ int bufmax,
+ int *ext_resp_len,
+ struct target_waitstatus *status
+)
+{
+ int resp_len;
+ do
+ {
+ resp_len = monitor_expect_prompt (buf, bufmax);
+ *ext_resp_len = resp_len;
+
+ if (resp_len <= 0)
+ fprintf_unfiltered (gdb_stderr, "monitor_wait: excessive response from monitor: %s.", buf);
+ }
+ while (resp_len < 0);
+
+ /* Print any output characters that were preceded by ^O. */
+ /* FIXME - This would be great as a user settabgle flag */
+ if (monitor_debug_p || remote_debug
+ || current_monitor->flags & MO_PRINT_PROGRAM_OUTPUT)
+ {
+ int i;
+
+ for (i = 0; i < resp_len - 1; i++)
+ if (buf[i] == 0x0f)
+ putchar_unfiltered (buf[++i]);
+ }
+}
+
+
+
+/* Wait until the remote machine stops, then return, storing status in
+ status just as `wait' would. */
+
+static ptid_t
+monitor_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ int old_timeout = timeout;
+ char buf[TARGET_BUF_SIZE];
+ int resp_len;
+ struct cleanup *old_chain;
+
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = 0;
+
+ old_chain = make_cleanup (monitor_wait_cleanup, &old_timeout);
+ monitor_debug ("MON wait\n");
+
+#if 0
+ /* This is somthing other than a maintenance command */
+ in_monitor_wait = 1;
+ timeout = watchdog > 0 ? watchdog : -1;
+#else
+ timeout = -1; /* Don't time out -- user program is running. */
+#endif
+
+ ofunc = (void (*)()) signal (SIGINT, monitor_interrupt);
+
+ if (current_monitor->wait_filter)
+ (*current_monitor->wait_filter) (buf, sizeof (buf), &resp_len, status);
+ else
+ monitor_wait_filter (buf, sizeof (buf), &resp_len, status);
+
+#if 0 /* Transferred to monitor wait filter */
+ do
+ {
+ resp_len = monitor_expect_prompt (buf, sizeof (buf));
+
+ if (resp_len <= 0)
+ fprintf_unfiltered (gdb_stderr, "monitor_wait: excessive response from monitor: %s.", buf);
+ }
+ while (resp_len < 0);
+
+ /* Print any output characters that were preceded by ^O. */
+ /* FIXME - This would be great as a user settabgle flag */
+ if (monitor_debug_p || remote_debug
+ || current_monitor->flags & MO_PRINT_PROGRAM_OUTPUT)
+ {
+ int i;
+
+ for (i = 0; i < resp_len - 1; i++)
+ if (buf[i] == 0x0f)
+ putchar_unfiltered (buf[++i]);
+ }
+#endif
+
+ signal (SIGINT, ofunc);
+
+ timeout = old_timeout;
+#if 0
+ if (dump_reg_flag && current_monitor->dump_registers)
+ {
+ dump_reg_flag = 0;
+ monitor_printf (current_monitor->dump_registers);
+ resp_len = monitor_expect_prompt (buf, sizeof (buf));
+ }
+
+ if (current_monitor->register_pattern)
+ parse_register_dump (buf, resp_len);
+#else
+ monitor_debug ("Wait fetching registers after stop\n");
+ monitor_dump_regs ();
+#endif
+
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+
+ discard_cleanups (old_chain);
+
+ in_monitor_wait = 0;
+
+ return inferior_ptid;
+}
+
+/* Fetch register REGNO, or all registers if REGNO is -1. Returns
+ errno value. */
+
+static void
+monitor_fetch_register (int regno)
+{
+ char *name;
+ char *zerobuf;
+ char *regbuf;
+ int i;
+
+ regbuf = alloca (MAX_REGISTER_RAW_SIZE * 2 + 1);
+ zerobuf = alloca (MAX_REGISTER_RAW_SIZE);
+ memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE);
+
+ name = current_monitor->regnames[regno];
+ monitor_debug ("MON fetchreg %d '%s'\n", regno, name ? name : "(null name)");
+
+ if (!name || (*name == '\0'))
+ {
+ monitor_debug ("No register known for %d\n", regno);
+ supply_register (regno, zerobuf);
+ return;
+ }
+
+ /* send the register examine command */
+
+ monitor_printf (current_monitor->getreg.cmd, name);
+
+ /* If RESP_DELIM is specified, we search for that as a leading
+ delimiter for the register value. Otherwise, we just start
+ searching from the start of the buf. */
+
+ if (current_monitor->getreg.resp_delim)
+ {
+ monitor_debug ("EXP getreg.resp_delim\n");
+ monitor_expect (current_monitor->getreg.resp_delim, NULL, 0);
+ /* Handle case of first 32 registers listed in pairs. */
+ if (current_monitor->flags & MO_32_REGS_PAIRED
+ && (regno & 1) != 0 && regno < 32)
+ {
+ monitor_debug ("EXP getreg.resp_delim\n");
+ monitor_expect (current_monitor->getreg.resp_delim, NULL, 0);
+ }
+ }
+
+ /* Skip leading spaces and "0x" if MO_HEX_PREFIX flag is set */
+ if (current_monitor->flags & MO_HEX_PREFIX)
+ {
+ int c;
+ c = readchar (timeout);
+ while (c == ' ')
+ c = readchar (timeout);
+ if ((c == '0') && ((c = readchar (timeout)) == 'x'))
+ ;
+ else
+ error ("Bad value returned from monitor while fetching register %x.",
+ regno);
+ }
+
+ /* Read upto the maximum number of hex digits for this register, skipping
+ spaces, but stop reading if something else is seen. Some monitors
+ like to drop leading zeros. */
+
+ for (i = 0; i < REGISTER_RAW_SIZE (regno) * 2; i++)
+ {
+ int c;
+ c = readchar (timeout);
+ while (c == ' ')
+ c = readchar (timeout);
+
+ if (!isxdigit (c))
+ break;
+
+ regbuf[i] = c;
+ }
+
+ regbuf[i] = '\000'; /* terminate the number */
+ monitor_debug ("REGVAL '%s'\n", regbuf);
+
+ /* If TERM is present, we wait for that to show up. Also, (if TERM
+ is present), we will send TERM_CMD if that is present. In any
+ case, we collect all of the output into buf, and then wait for
+ the normal prompt. */
+
+ if (current_monitor->getreg.term)
+ {
+ monitor_debug ("EXP getreg.term\n");
+ monitor_expect (current_monitor->getreg.term, NULL, 0); /* get response */
+ }
+
+ if (current_monitor->getreg.term_cmd)
+ {
+ monitor_debug ("EMIT getreg.term.cmd\n");
+ monitor_printf (current_monitor->getreg.term_cmd);
+ }
+ if (!current_monitor->getreg.term || /* Already expected or */
+ current_monitor->getreg.term_cmd) /* ack expected */
+ monitor_expect_prompt (NULL, 0); /* get response */
+
+ monitor_supply_register (regno, regbuf);
+}
+
+/* Sometimes, it takes several commands to dump the registers */
+/* This is a primitive for use by variations of monitor interfaces in
+ case they need to compose the operation.
+ */
+int
+monitor_dump_reg_block (char *block_cmd)
+{
+ char buf[TARGET_BUF_SIZE];
+ int resp_len;
+ monitor_printf (block_cmd);
+ resp_len = monitor_expect_prompt (buf, sizeof (buf));
+ parse_register_dump (buf, resp_len);
+ return 1;
+}
+
+
+/* Read the remote registers into the block regs. */
+/* Call the specific function if it has been provided */
+
+static void
+monitor_dump_regs (void)
+{
+ char buf[TARGET_BUF_SIZE];
+ int resp_len;
+ if (current_monitor->dumpregs)
+ (*(current_monitor->dumpregs)) (); /* call supplied function */
+ else if (current_monitor->dump_registers) /* default version */
+ {
+ monitor_printf (current_monitor->dump_registers);
+ resp_len = monitor_expect_prompt (buf, sizeof (buf));
+ parse_register_dump (buf, resp_len);
+ }
+ else
+ internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* Need some way to read registers */
+}
+
+static void
+monitor_fetch_registers (int regno)
+{
+ monitor_debug ("MON fetchregs\n");
+ if (current_monitor->getreg.cmd)
+ {
+ if (regno >= 0)
+ {
+ monitor_fetch_register (regno);
+ return;
+ }
+
+ for (regno = 0; regno < NUM_REGS; regno++)
+ monitor_fetch_register (regno);
+ }
+ else
+ {
+ monitor_dump_regs ();
+ }
+}
+
+/* Store register REGNO, or all if REGNO == 0. Return errno value. */
+
+static void
+monitor_store_register (int regno)
+{
+ char *name;
+ ULONGEST val;
+
+ name = current_monitor->regnames[regno];
+ if (!name || (*name == '\0'))
+ {
+ monitor_debug ("MON Cannot store unknown register\n");
+ return;
+ }
+
+ val = read_register (regno);
+ monitor_debug ("MON storeg %d %s\n", regno,
+ phex (val, REGISTER_RAW_SIZE (regno)));
+
+ /* send the register deposit command */
+
+ if (current_monitor->flags & MO_REGISTER_VALUE_FIRST)
+ monitor_printf (current_monitor->setreg.cmd, val, name);
+ else if (current_monitor->flags & MO_SETREG_INTERACTIVE)
+ monitor_printf (current_monitor->setreg.cmd, name);
+ else
+ monitor_printf (current_monitor->setreg.cmd, name, val);
+
+ if (current_monitor->setreg.resp_delim)
+ {
+ monitor_debug ("EXP setreg.resp_delim\n");
+ monitor_expect_regexp (&setreg_resp_delim_pattern, NULL, 0);
+ if (current_monitor->flags & MO_SETREG_INTERACTIVE)
+ monitor_printf ("%s\r", paddr_nz (val));
+ }
+ if (current_monitor->setreg.term)
+ {
+ monitor_debug ("EXP setreg.term\n");
+ monitor_expect (current_monitor->setreg.term, NULL, 0);
+ if (current_monitor->flags & MO_SETREG_INTERACTIVE)
+ monitor_printf ("%s\r", paddr_nz (val));
+ monitor_expect_prompt (NULL, 0);
+ }
+ else
+ monitor_expect_prompt (NULL, 0);
+ if (current_monitor->setreg.term_cmd) /* Mode exit required */
+ {
+ monitor_debug ("EXP setreg_termcmd\n");
+ monitor_printf ("%s", current_monitor->setreg.term_cmd);
+ monitor_expect_prompt (NULL, 0);
+ }
+} /* monitor_store_register */
+
+/* Store the remote registers. */
+
+static void
+monitor_store_registers (int regno)
+{
+ if (regno >= 0)
+ {
+ monitor_store_register (regno);
+ return;
+ }
+
+ for (regno = 0; regno < NUM_REGS; regno++)
+ monitor_store_register (regno);
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+static void
+monitor_prepare_to_store (void)
+{
+ /* Do nothing, since we can store individual regs */
+}
+
+static void
+monitor_files_info (struct target_ops *ops)
+{
+ printf_unfiltered ("\tAttached to %s at %d baud.\n", dev_name, baud_rate);
+}
+
+static int
+monitor_write_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ unsigned int val, hostval;
+ char *cmd;
+ int i;
+
+ monitor_debug ("MON write %d %s\n", len, paddr (memaddr));
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ memaddr = ADDR_BITS_REMOVE (memaddr);
+
+ /* Use memory fill command for leading 0 bytes. */
+
+ if (current_monitor->fill)
+ {
+ for (i = 0; i < len; i++)
+ if (myaddr[i] != 0)
+ break;
+
+ if (i > 4) /* More than 4 zeros is worth doing */
+ {
+ monitor_debug ("MON FILL %d\n", i);
+ if (current_monitor->flags & MO_FILL_USES_ADDR)
+ monitor_printf (current_monitor->fill, memaddr, (memaddr + i) - 1, 0);
+ else
+ monitor_printf (current_monitor->fill, memaddr, i, 0);
+
+ monitor_expect_prompt (NULL, 0);
+
+ return i;
+ }
+ }
+
+#if 0
+ /* Can't actually use long longs if VAL is an int (nice idea, though). */
+ if ((memaddr & 0x7) == 0 && len >= 8 && current_monitor->setmem.cmdll)
+ {
+ len = 8;
+ cmd = current_monitor->setmem.cmdll;
+ }
+ else
+#endif
+ if ((memaddr & 0x3) == 0 && len >= 4 && current_monitor->setmem.cmdl)
+ {
+ len = 4;
+ cmd = current_monitor->setmem.cmdl;
+ }
+ else if ((memaddr & 0x1) == 0 && len >= 2 && current_monitor->setmem.cmdw)
+ {
+ len = 2;
+ cmd = current_monitor->setmem.cmdw;
+ }
+ else
+ {
+ len = 1;
+ cmd = current_monitor->setmem.cmdb;
+ }
+
+ val = extract_unsigned_integer (myaddr, len);
+
+ if (len == 4)
+ {
+ hostval = *(unsigned int *) myaddr;
+ monitor_debug ("Hostval(%08x) val(%08x)\n", hostval, val);
+ }
+
+
+ if (current_monitor->flags & MO_NO_ECHO_ON_SETMEM)
+ monitor_printf_noecho (cmd, memaddr, val);
+ else if (current_monitor->flags & MO_SETMEM_INTERACTIVE)
+ {
+
+ monitor_printf_noecho (cmd, memaddr);
+
+ if (current_monitor->setmem.resp_delim)
+ {
+ monitor_debug ("EXP setmem.resp_delim");
+ monitor_expect_regexp (&setmem_resp_delim_pattern, NULL, 0);
+ monitor_printf ("%x\r", val);
+ }
+ if (current_monitor->setmem.term)
+ {
+ monitor_debug ("EXP setmem.term");
+ monitor_expect (current_monitor->setmem.term, NULL, 0);
+ monitor_printf ("%x\r", val);
+ }
+ if (current_monitor->setmem.term_cmd)
+ { /* Emit this to get out of the memory editing state */
+ monitor_printf ("%s", current_monitor->setmem.term_cmd);
+ /* Drop through to expecting a prompt */
+ }
+ }
+ else
+ monitor_printf (cmd, memaddr, val);
+
+ monitor_expect_prompt (NULL, 0);
+
+ return len;
+}
+
+
+static int
+monitor_write_even_block (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ unsigned int val;
+ int written = 0;;
+ /* Enter the sub mode */
+ monitor_printf (current_monitor->setmem.cmdl, memaddr);
+ monitor_expect_prompt (NULL, 0);
+
+ while (len)
+ {
+ val = extract_unsigned_integer (myaddr, 4); /* REALLY */
+ monitor_printf ("%x\r", val);
+ myaddr += 4;
+ memaddr += 4;
+ written += 4;
+ monitor_debug (" @ %s\n", paddr (memaddr));
+ /* If we wanted to, here we could validate the address */
+ monitor_expect_prompt (NULL, 0);
+ }
+ /* Now exit the sub mode */
+ monitor_printf (current_monitor->getreg.term_cmd);
+ monitor_expect_prompt (NULL, 0);
+ return written;
+}
+
+
+static int
+monitor_write_memory_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ unsigned char val;
+ int written = 0;
+ if (len == 0)
+ return 0;
+ /* Enter the sub mode */
+ monitor_printf (current_monitor->setmem.cmdb, memaddr);
+ monitor_expect_prompt (NULL, 0);
+ while (len)
+ {
+ val = *myaddr;
+ monitor_printf ("%x\r", val);
+ myaddr++;
+ memaddr++;
+ written++;
+ /* If we wanted to, here we could validate the address */
+ monitor_expect_prompt (NULL, 0);
+ len--;
+ }
+ /* Now exit the sub mode */
+ monitor_printf (current_monitor->getreg.term_cmd);
+ monitor_expect_prompt (NULL, 0);
+ return written;
+}
+
+
+static void
+longlongendswap (unsigned char *a)
+{
+ int i, j;
+ unsigned char x;
+ i = 0;
+ j = 7;
+ while (i < 4)
+ {
+ x = *(a + i);
+ *(a + i) = *(a + j);
+ *(a + j) = x;
+ i++, j--;
+ }
+}
+/* Format 32 chars of long long value, advance the pointer */
+static char *hexlate = "0123456789abcdef";
+static char *
+longlong_hexchars (unsigned long long value,
+ char *outbuff)
+{
+ if (value == 0)
+ {
+ *outbuff++ = '0';
+ return outbuff;
+ }
+ else
+ {
+ static unsigned char disbuf[8]; /* disassembly buffer */
+ unsigned char *scan, *limit; /* loop controls */
+ unsigned char c, nib;
+ int leadzero = 1;
+ scan = disbuf;
+ limit = scan + 8;
+ {
+ unsigned long long *dp;
+ dp = (unsigned long long *) scan;
+ *dp = value;
+ }
+ longlongendswap (disbuf); /* FIXME: ONly on big endian hosts */
+ while (scan < limit)
+ {
+ c = *scan++; /* a byte of our long long value */
+ if (leadzero)
+ {
+ if (c == 0)
+ continue;
+ else
+ leadzero = 0; /* henceforth we print even zeroes */
+ }
+ nib = c >> 4; /* high nibble bits */
+ *outbuff++ = hexlate[nib];
+ nib = c & 0x0f; /* low nibble bits */
+ *outbuff++ = hexlate[nib];
+ }
+ return outbuff;
+ }
+} /* longlong_hexchars */
+
+
+
+/* I am only going to call this when writing virtual byte streams.
+ Which possably entails endian conversions
+ */
+static int
+monitor_write_memory_longlongs (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ static char hexstage[20]; /* At least 16 digits required, plus null */
+ char *endstring;
+ long long *llptr;
+ long long value;
+ int written = 0;
+ llptr = (unsigned long long *) myaddr;
+ if (len == 0)
+ return 0;
+ monitor_printf (current_monitor->setmem.cmdll, memaddr);
+ monitor_expect_prompt (NULL, 0);
+ while (len >= 8)
+ {
+ value = *llptr;
+ endstring = longlong_hexchars (*llptr, hexstage);
+ *endstring = '\0'; /* NUll terminate for printf */
+ monitor_printf ("%s\r", hexstage);
+ llptr++;
+ memaddr += 8;
+ written += 8;
+ /* If we wanted to, here we could validate the address */
+ monitor_expect_prompt (NULL, 0);
+ len -= 8;
+ }
+ /* Now exit the sub mode */
+ monitor_printf (current_monitor->getreg.term_cmd);
+ monitor_expect_prompt (NULL, 0);
+ return written;
+} /* */
+
+
+
+/* ----- MONITOR_WRITE_MEMORY_BLOCK ---------------------------- */
+/* This is for the large blocks of memory which may occur in downloading.
+ And for monitors which use interactive entry,
+ And for monitors which do not have other downloading methods.
+ Without this, we will end up calling monitor_write_memory many times
+ and do the entry and exit of the sub mode many times
+ This currently assumes...
+ MO_SETMEM_INTERACTIVE
+ ! MO_NO_ECHO_ON_SETMEM
+ To use this, the you have to patch the monitor_cmds block with
+ this function. Otherwise, its not tuned up for use by all
+ monitor variations.
+ */
+
+static int
+monitor_write_memory_block (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ int written;
+ written = 0;
+ /* FIXME: This would be a good place to put the zero test */
+#if 1
+ if ((len > 8) && (((len & 0x07)) == 0) && current_monitor->setmem.cmdll)
+ {
+ return monitor_write_memory_longlongs (memaddr, myaddr, len);
+ }
+#endif
+#if 0
+ if (len > 4)
+ {
+ int sublen;
+ written = monitor_write_even_block (memaddr, myaddr, len);
+ /* Adjust calling parameters by written amount */
+ memaddr += written;
+ myaddr += written;
+ len -= written;
+ }
+#endif
+ written = monitor_write_memory_bytes (memaddr, myaddr, len);
+ return written;
+}
+
+/* This is an alternate form of monitor_read_memory which is used for monitors
+ which can only read a single byte/word/etc. at a time. */
+
+static int
+monitor_read_memory_single (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ unsigned int val;
+ char membuf[sizeof (int) * 2 + 1];
+ char *p;
+ char *cmd;
+
+ monitor_debug ("MON read single\n");
+#if 0
+ /* Can't actually use long longs (nice idea, though). In fact, the
+ call to strtoul below will fail if it tries to convert a value
+ that's too big to fit in a long. */
+ if ((memaddr & 0x7) == 0 && len >= 8 && current_monitor->getmem.cmdll)
+ {
+ len = 8;
+ cmd = current_monitor->getmem.cmdll;
+ }
+ else
+#endif
+ if ((memaddr & 0x3) == 0 && len >= 4 && current_monitor->getmem.cmdl)
+ {
+ len = 4;
+ cmd = current_monitor->getmem.cmdl;
+ }
+ else if ((memaddr & 0x1) == 0 && len >= 2 && current_monitor->getmem.cmdw)
+ {
+ len = 2;
+ cmd = current_monitor->getmem.cmdw;
+ }
+ else
+ {
+ len = 1;
+ cmd = current_monitor->getmem.cmdb;
+ }
+
+ /* Send the examine command. */
+
+ monitor_printf (cmd, memaddr);
+
+ /* If RESP_DELIM is specified, we search for that as a leading
+ delimiter for the memory value. Otherwise, we just start
+ searching from the start of the buf. */
+
+ if (current_monitor->getmem.resp_delim)
+ {
+ monitor_debug ("EXP getmem.resp_delim\n");
+ monitor_expect_regexp (&getmem_resp_delim_pattern, NULL, 0);
+ }
+
+ /* Now, read the appropriate number of hex digits for this loc,
+ skipping spaces. */
+
+ /* Skip leading spaces and "0x" if MO_HEX_PREFIX flag is set. */
+ if (current_monitor->flags & MO_HEX_PREFIX)
+ {
+ int c;
+
+ c = readchar (timeout);
+ while (c == ' ')
+ c = readchar (timeout);
+ if ((c == '0') && ((c = readchar (timeout)) == 'x'))
+ ;
+ else
+ monitor_error ("monitor_read_memory_single",
+ "bad response from monitor",
+ memaddr, 0, NULL, 0);
+ }
+
+ {
+ int i;
+ for (i = 0; i < len * 2; i++)
+ {
+ int c;
+
+ while (1)
+ {
+ c = readchar (timeout);
+ if (isxdigit (c))
+ break;
+ if (c == ' ')
+ continue;
+
+ monitor_error ("monitor_read_memory_single",
+ "bad response from monitor",
+ memaddr, i, membuf, 0);
+ }
+ membuf[i] = c;
+ }
+ membuf[i] = '\000'; /* terminate the number */
+ }
+
+/* If TERM is present, we wait for that to show up. Also, (if TERM is
+ present), we will send TERM_CMD if that is present. In any case, we collect
+ all of the output into buf, and then wait for the normal prompt. */
+
+ if (current_monitor->getmem.term)
+ {
+ monitor_expect (current_monitor->getmem.term, NULL, 0); /* get response */
+
+ if (current_monitor->getmem.term_cmd)
+ {
+ monitor_printf (current_monitor->getmem.term_cmd);
+ monitor_expect_prompt (NULL, 0);
+ }
+ }
+ else
+ monitor_expect_prompt (NULL, 0); /* get response */
+
+ p = membuf;
+ val = strtoul (membuf, &p, 16);
+
+ if (val == 0 && membuf == p)
+ monitor_error ("monitor_read_memory_single",
+ "bad value from monitor",
+ memaddr, 0, membuf, 0);
+
+ /* supply register stores in target byte order, so swap here */
+
+ store_unsigned_integer (myaddr, len, val);
+
+ return len;
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's
+ memory at MEMADDR. Returns length moved. Currently, we do no more
+ than 16 bytes at a time. */
+
+static int
+monitor_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ unsigned int val;
+ char buf[512];
+ char *p, *p1;
+ int resp_len;
+ int i;
+ CORE_ADDR dumpaddr;
+
+ if (len <= 0)
+ {
+ monitor_debug ("Zero length call to monitor_read_memory\n");
+ return 0;
+ }
+
+ monitor_debug ("MON read block ta(%s) ha(%lx) %d\n",
+ paddr_nz (memaddr), (long) myaddr, len);
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ memaddr = ADDR_BITS_REMOVE (memaddr);
+
+ if (current_monitor->flags & MO_GETMEM_READ_SINGLE)
+ return monitor_read_memory_single (memaddr, myaddr, len);
+
+ len = min (len, 16);
+
+ /* Some dumpers align the first data with the preceeding 16
+ byte boundary. Some print blanks and start at the
+ requested boundary. EXACT_DUMPADDR
+ */
+
+ dumpaddr = (current_monitor->flags & MO_EXACT_DUMPADDR)
+ ? memaddr : memaddr & ~0x0f;
+
+ /* See if xfer would cross a 16 byte boundary. If so, clip it. */
+ if (((memaddr ^ (memaddr + len - 1)) & ~0xf) != 0)
+ len = ((memaddr + len) & ~0xf) - memaddr;
+
+ /* send the memory examine command */
+
+ if (current_monitor->flags & MO_GETMEM_NEEDS_RANGE)
+ monitor_printf (current_monitor->getmem.cmdb, memaddr, memaddr + len);
+ else if (current_monitor->flags & MO_GETMEM_16_BOUNDARY)
+ monitor_printf (current_monitor->getmem.cmdb, dumpaddr);
+ else
+ monitor_printf (current_monitor->getmem.cmdb, memaddr, len);
+
+ /* If TERM is present, we wait for that to show up. Also, (if TERM
+ is present), we will send TERM_CMD if that is present. In any
+ case, we collect all of the output into buf, and then wait for
+ the normal prompt. */
+
+ if (current_monitor->getmem.term)
+ {
+ resp_len = monitor_expect (current_monitor->getmem.term, buf, sizeof buf); /* get response */
+
+ if (resp_len <= 0)
+ monitor_error ("monitor_read_memory",
+ "excessive response from monitor",
+ memaddr, resp_len, buf, 0);
+
+ if (current_monitor->getmem.term_cmd)
+ {
+ serial_write (monitor_desc, current_monitor->getmem.term_cmd,
+ strlen (current_monitor->getmem.term_cmd));
+ monitor_expect_prompt (NULL, 0);
+ }
+ }
+ else
+ resp_len = monitor_expect_prompt (buf, sizeof buf); /* get response */
+
+ p = buf;
+
+ /* If RESP_DELIM is specified, we search for that as a leading
+ delimiter for the values. Otherwise, we just start searching
+ from the start of the buf. */
+
+ if (current_monitor->getmem.resp_delim)
+ {
+ int retval, tmp;
+ struct re_registers resp_strings;
+ monitor_debug ("MON getmem.resp_delim %s\n", current_monitor->getmem.resp_delim);
+
+ memset (&resp_strings, 0, sizeof (struct re_registers));
+ tmp = strlen (p);
+ retval = re_search (&getmem_resp_delim_pattern, p, tmp, 0, tmp,
+ &resp_strings);
+
+ if (retval < 0)
+ monitor_error ("monitor_read_memory",
+ "bad response from monitor",
+ memaddr, resp_len, buf, 0);
+
+ p += resp_strings.end[0];
+#if 0
+ p = strstr (p, current_monitor->getmem.resp_delim);
+ if (!p)
+ monitor_error ("monitor_read_memory",
+ "bad response from monitor",
+ memaddr, resp_len, buf, 0);
+ p += strlen (current_monitor->getmem.resp_delim);
+#endif
+ }
+ monitor_debug ("MON scanning %d ,%lx '%s'\n", len, (long) p, p);
+ if (current_monitor->flags & MO_GETMEM_16_BOUNDARY)
+ {
+ char c;
+ int fetched = 0;
+ i = len;
+ c = *p;
+
+
+ while (!(c == '\000' || c == '\n' || c == '\r') && i > 0)
+ {
+ if (isxdigit (c))
+ {
+ if ((dumpaddr >= memaddr) && (i > 0))
+ {
+ val = fromhex (c) * 16 + fromhex (*(p + 1));
+ *myaddr++ = val;
+ if (monitor_debug_p || remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "[%02x]", val);
+ --i;
+ fetched++;
+ }
+ ++dumpaddr;
+ ++p;
+ }
+ ++p; /* skip a blank or other non hex char */
+ c = *p;
+ }
+ if (fetched == 0)
+ error ("Failed to read via monitor");
+ if (monitor_debug_p || remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "\n");
+ return fetched; /* Return the number of bytes actually read */
+ }
+ monitor_debug ("MON scanning bytes\n");
+
+ for (i = len; i > 0; i--)
+ {
+ /* Skip non-hex chars, but bomb on end of string and newlines */
+
+ while (1)
+ {
+ if (isxdigit (*p))
+ break;
+
+ if (*p == '\000' || *p == '\n' || *p == '\r')
+ monitor_error ("monitor_read_memory",
+ "badly terminated response from monitor",
+ memaddr, resp_len, buf, 0);
+ p++;
+ }
+
+ val = strtoul (p, &p1, 16);
+
+ if (val == 0 && p == p1)
+ monitor_error ("monitor_read_memory",
+ "bad value from monitor",
+ memaddr, resp_len, buf, 0);
+
+ *myaddr++ = val;
+
+ if (i == 1)
+ break;
+
+ p = p1;
+ }
+
+ return len;
+}
+
+/* Transfer LEN bytes between target address MEMADDR and GDB address
+ MYADDR. Returns 0 for success, errno code for failure. TARGET is
+ unused. */
+
+static int
+monitor_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib, struct target_ops *target)
+{
+ int res;
+
+ if (write)
+ {
+ if (current_monitor->flags & MO_HAS_BLOCKWRITES)
+ res = monitor_write_memory_block(memaddr, myaddr, len);
+ else
+ res = monitor_write_memory(memaddr, myaddr, len);
+ }
+ else
+ {
+ res = monitor_read_memory(memaddr, myaddr, len);
+ }
+
+ return res;
+}
+
+static void
+monitor_kill (void)
+{
+ return; /* ignore attempts to kill target system */
+}
+
+/* All we actually do is set the PC to the start address of exec_bfd, and start
+ the program at that point. */
+
+static void
+monitor_create_inferior (char *exec_file, char *args, char **env)
+{
+ if (args && (*args != '\000'))
+ error ("Args are not supported by the monitor.");
+
+ first_time = 1;
+ clear_proceed_status ();
+ proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
+}
+
+/* Clean up when a program exits.
+ The program actually lives on in the remote processor's RAM, and may be
+ run again without a download. Don't leave it full of breakpoint
+ instructions. */
+
+static void
+monitor_mourn_inferior (void)
+{
+ unpush_target (targ_ops);
+ generic_mourn_inferior (); /* Do all the proper things now */
+}
+
+/* Tell the monitor to add a breakpoint. */
+
+static int
+monitor_insert_breakpoint (CORE_ADDR addr, char *shadow)
+{
+ int i;
+ const unsigned char *bp;
+ int bplen;
+
+ monitor_debug ("MON inst bkpt %s\n", paddr (addr));
+ if (current_monitor->set_break == NULL)
+ error ("No set_break defined for this monitor");
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ addr = ADDR_BITS_REMOVE (addr);
+
+ /* Determine appropriate breakpoint size for this address. */
+ bp = memory_breakpoint_from_pc (&addr, &bplen);
+
+ for (i = 0; i < current_monitor->num_breakpoints; i++)
+ {
+ if (breakaddr[i] == 0)
+ {
+ breakaddr[i] = addr;
+ monitor_read_memory (addr, shadow, bplen);
+ monitor_printf (current_monitor->set_break, addr);
+ monitor_expect_prompt (NULL, 0);
+ return 0;
+ }
+ }
+
+ error ("Too many breakpoints (> %d) for monitor.", current_monitor->num_breakpoints);
+}
+
+/* Tell the monitor to remove a breakpoint. */
+
+static int
+monitor_remove_breakpoint (CORE_ADDR addr, char *shadow)
+{
+ int i;
+
+ monitor_debug ("MON rmbkpt %s\n", paddr (addr));
+ if (current_monitor->clr_break == NULL)
+ error ("No clr_break defined for this monitor");
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ addr = ADDR_BITS_REMOVE (addr);
+
+ for (i = 0; i < current_monitor->num_breakpoints; i++)
+ {
+ if (breakaddr[i] == addr)
+ {
+ breakaddr[i] = 0;
+ /* some monitors remove breakpoints based on the address */
+ if (current_monitor->flags & MO_CLR_BREAK_USES_ADDR)
+ monitor_printf (current_monitor->clr_break, addr);
+ else if (current_monitor->flags & MO_CLR_BREAK_1_BASED)
+ monitor_printf (current_monitor->clr_break, i + 1);
+ else
+ monitor_printf (current_monitor->clr_break, i);
+ monitor_expect_prompt (NULL, 0);
+ return 0;
+ }
+ }
+ fprintf_unfiltered (gdb_stderr,
+ "Can't find breakpoint associated with 0x%s\n",
+ paddr_nz (addr));
+ return 1;
+}
+
+/* monitor_wait_srec_ack -- wait for the target to send an acknowledgement for
+ an S-record. Return non-zero if the ACK is received properly. */
+
+static int
+monitor_wait_srec_ack (void)
+{
+ int ch;
+
+ if (current_monitor->flags & MO_SREC_ACK_PLUS)
+ {
+ return (readchar (timeout) == '+');
+ }
+ else if (current_monitor->flags & MO_SREC_ACK_ROTATE)
+ {
+ /* Eat two backspaces, a "rotating" char (|/-\), and a space. */
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ }
+ return 1;
+}
+
+/* monitor_load -- download a file. */
+
+static void
+monitor_load (char *file, int from_tty)
+{
+ monitor_debug ("MON load\n");
+
+ if (current_monitor->load_routine)
+ current_monitor->load_routine (monitor_desc, file, hashmark);
+ else
+ { /* The default is ascii S-records */
+ int n;
+ unsigned long load_offset;
+ char buf[128];
+
+ /* enable user to specify address for downloading as 2nd arg to load */
+ n = sscanf (file, "%s 0x%lx", buf, &load_offset);
+ if (n > 1)
+ file = buf;
+ else
+ load_offset = 0;
+
+ monitor_printf (current_monitor->load);
+ if (current_monitor->loadresp)
+ monitor_expect (current_monitor->loadresp, NULL, 0);
+
+ load_srec (monitor_desc, file, (bfd_vma) load_offset,
+ 32, SREC_ALL, hashmark,
+ current_monitor->flags & MO_SREC_ACK ?
+ monitor_wait_srec_ack : NULL);
+
+ monitor_expect_prompt (NULL, 0);
+ }
+
+ /* Finally, make the PC point at the start address */
+ if (exec_bfd)
+ write_pc (bfd_get_start_address (exec_bfd));
+
+ /* There used to be code here which would clear inferior_ptid and
+ call clear_symtab_users. None of that should be necessary:
+ monitor targets should behave like remote protocol targets, and
+ since generic_load does none of those things, this function
+ shouldn't either.
+
+ Furthermore, clearing inferior_ptid is *incorrect*. After doing
+ a load, we still have a valid connection to the monitor, with a
+ live processor state to fiddle with. The user can type
+ `continue' or `jump *start' and make the program run. If they do
+ these things, however, GDB will be talking to a running program
+ while inferior_ptid is null_ptid; this makes things like
+ reinit_frame_cache very confused. */
+}
+
+static void
+monitor_stop (void)
+{
+ monitor_debug ("MON stop\n");
+ if ((current_monitor->flags & MO_SEND_BREAK_ON_STOP) != 0)
+ serial_send_break (monitor_desc);
+ if (current_monitor->stop)
+ monitor_printf_noecho (current_monitor->stop);
+}
+
+/* Put a COMMAND string out to MONITOR. Output from MONITOR is placed
+ in OUTPUT until the prompt is seen. FIXME: We read the characters
+ ourseleves here cause of a nasty echo. */
+
+static void
+monitor_rcmd (char *command,
+ struct ui_file *outbuf)
+{
+ char *p;
+ int resp_len;
+ char buf[1000];
+
+ if (monitor_desc == NULL)
+ error ("monitor target not open.");
+
+ p = current_monitor->prompt;
+
+ /* Send the command. Note that if no args were supplied, then we're
+ just sending the monitor a newline, which is sometimes useful. */
+
+ monitor_printf ("%s\r", (command ? command : ""));
+
+ resp_len = monitor_expect_prompt (buf, sizeof buf);
+
+ fputs_unfiltered (buf, outbuf); /* Output the response */
+}
+
+/* Convert hex digit A to a number. */
+
+#if 0
+static int
+from_hex (int a)
+{
+ if (a >= '0' && a <= '9')
+ return a - '0';
+ if (a >= 'a' && a <= 'f')
+ return a - 'a' + 10;
+ if (a >= 'A' && a <= 'F')
+ return a - 'A' + 10;
+
+ error ("Reply contains invalid hex digit 0x%x", a);
+}
+#endif
+
+char *
+monitor_get_dev_name (void)
+{
+ return dev_name;
+}
+
+static struct target_ops monitor_ops;
+
+static void
+init_base_monitor_ops (void)
+{
+ monitor_ops.to_shortname = NULL;
+ monitor_ops.to_longname = NULL;
+ monitor_ops.to_doc = NULL;
+ monitor_ops.to_open = NULL;
+ monitor_ops.to_close = monitor_close;
+ monitor_ops.to_attach = NULL;
+ monitor_ops.to_post_attach = NULL;
+ monitor_ops.to_require_attach = NULL;
+ monitor_ops.to_detach = monitor_detach;
+ monitor_ops.to_require_detach = NULL;
+ monitor_ops.to_resume = monitor_resume;
+ monitor_ops.to_wait = monitor_wait;
+ monitor_ops.to_post_wait = NULL;
+ monitor_ops.to_fetch_registers = monitor_fetch_registers;
+ monitor_ops.to_store_registers = monitor_store_registers;
+ monitor_ops.to_prepare_to_store = monitor_prepare_to_store;
+ monitor_ops.to_xfer_memory = monitor_xfer_memory;
+ monitor_ops.to_files_info = monitor_files_info;
+ monitor_ops.to_insert_breakpoint = monitor_insert_breakpoint;
+ monitor_ops.to_remove_breakpoint = monitor_remove_breakpoint;
+ monitor_ops.to_terminal_init = 0;
+ monitor_ops.to_terminal_inferior = 0;
+ monitor_ops.to_terminal_ours_for_output = 0;
+ monitor_ops.to_terminal_ours = 0;
+ monitor_ops.to_terminal_info = 0;
+ monitor_ops.to_kill = monitor_kill;
+ monitor_ops.to_load = monitor_load;
+ monitor_ops.to_lookup_symbol = 0;
+ monitor_ops.to_create_inferior = monitor_create_inferior;
+ monitor_ops.to_post_startup_inferior = NULL;
+ monitor_ops.to_acknowledge_created_inferior = NULL;
+ monitor_ops.to_clone_and_follow_inferior = NULL;
+ monitor_ops.to_post_follow_inferior_by_clone = NULL;
+ monitor_ops.to_insert_fork_catchpoint = NULL;
+ monitor_ops.to_remove_fork_catchpoint = NULL;
+ monitor_ops.to_insert_vfork_catchpoint = NULL;
+ monitor_ops.to_remove_vfork_catchpoint = NULL;
+ monitor_ops.to_has_forked = NULL;
+ monitor_ops.to_has_vforked = NULL;
+ monitor_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ monitor_ops.to_post_follow_vfork = NULL;
+ monitor_ops.to_insert_exec_catchpoint = NULL;
+ monitor_ops.to_remove_exec_catchpoint = NULL;
+ monitor_ops.to_has_execd = NULL;
+ monitor_ops.to_reported_exec_events_per_exec_call = NULL;
+ monitor_ops.to_has_exited = NULL;
+ monitor_ops.to_mourn_inferior = monitor_mourn_inferior;
+ monitor_ops.to_can_run = 0;
+ monitor_ops.to_notice_signals = 0;
+ monitor_ops.to_thread_alive = 0;
+ monitor_ops.to_stop = monitor_stop;
+ monitor_ops.to_rcmd = monitor_rcmd;
+ monitor_ops.to_pid_to_exec_file = NULL;
+ monitor_ops.to_stratum = process_stratum;
+ monitor_ops.DONT_USE = 0;
+ monitor_ops.to_has_all_memory = 1;
+ monitor_ops.to_has_memory = 1;
+ monitor_ops.to_has_stack = 1;
+ monitor_ops.to_has_registers = 1;
+ monitor_ops.to_has_execution = 1;
+ monitor_ops.to_sections = 0;
+ monitor_ops.to_sections_end = 0;
+ monitor_ops.to_magic = OPS_MAGIC;
+} /* init_base_monitor_ops */
+
+/* Init the target_ops structure pointed at by OPS */
+
+void
+init_monitor_ops (struct target_ops *ops)
+{
+ if (monitor_ops.to_magic != OPS_MAGIC)
+ init_base_monitor_ops ();
+
+ memcpy (ops, &monitor_ops, sizeof monitor_ops);
+}
+
+/* Define additional commands that are usually only used by monitors. */
+
+void
+_initialize_remote_monitors (void)
+{
+ init_base_monitor_ops ();
+ add_show_from_set (add_set_cmd ("hash", no_class, var_boolean,
+ (char *) &hashmark,
+ "Set display of activity while downloading a file.\n\
+When enabled, a hashmark \'#\' is displayed.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("monitor", no_class, var_zinteger,
+ (char *) &monitor_debug_p,
+ "Set debugging of remote monitor communication.\n\
+When enabled, communication between GDB and the remote monitor\n\
+is displayed.", &setdebuglist),
+ &showdebuglist);
+}
diff --git a/gdb/monitor.h b/gdb/monitor.h
new file mode 100644
index 00000000000..85a44ff7e71
--- /dev/null
+++ b/gdb/monitor.h
@@ -0,0 +1,254 @@
+/* Definitions for remote debugging interface for ROM monitors.
+ Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
+
+ 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.
+ */
+
+#ifndef MONITOR_H
+#define MONITOR_H
+
+struct serial;
+
+/* This structure describes the strings necessary to give small command
+ sequences to the monitor, and parse the response.
+
+ CMD is the actual command typed at the monitor. Usually this has
+ embedded sequences ala printf, which are substituted with the
+ arguments appropriate to that type of command. Ie: to examine a
+ register, we substitute the register name for the first arg. To
+ modify memory, we substitute the memory location and the new
+ contents for the first and second args, etc...
+
+ RESP_DELIM used to home in on the response string, and is used to
+ disambiguate the answer within the pile of text returned by the
+ monitor. This should be a unique string that immediately precedes
+ the answer. Ie: if your monitor prints out `PC: 00000001= ' in
+ response to asking for the PC, you should use `: ' as the
+ RESP_DELIM. RESP_DELIM may be NULL if the res- ponse is going to
+ be ignored, or has no particular leading text.
+
+ TERM is the string that the monitor outputs to indicate that it is
+ idle, and waiting for input. This is usually a prompt of some
+ sort. In the previous example, it would be `= '. It is important
+ that TERM really means that the monitor is idle, otherwise GDB may
+ try to type at it when it isn't ready for input. This is a problem
+ because many monitors cannot deal with type-ahead. TERM may be
+ NULL if the normal prompt is output.
+
+ TERM_CMD is used to quit out of the subcommand mode and get back to
+ the main prompt. TERM_CMD may be NULL if it isn't necessary. It
+ will also be ignored if TERM is NULL. */
+
+struct memrw_cmd
+ {
+ char *cmdb; /* Command to send for byte read/write */
+ char *cmdw; /* Command for word (16 bit) read/write */
+ char *cmdl; /* Command for long (32 bit) read/write */
+ char *cmdll; /* Command for long long (64 bit) read/write */
+ char *resp_delim; /* String just prior to the desired value */
+ char *term; /* Terminating string to search for */
+ char *term_cmd; /* String to get out of sub-mode (if necessary) */
+ };
+
+struct regrw_cmd
+ {
+ char *cmd; /* Command to send for reg read/write */
+ char *resp_delim; /* String (actually a regexp if getmem) just
+ prior to the desired value */
+ char *term; /* Terminating string to search for */
+ char *term_cmd; /* String to get out of sub-mode (if necessary) */
+ };
+
+struct monitor_ops
+ {
+ int flags; /* See below */
+ char **init; /* List of init commands. NULL terminated. */
+ char *cont; /* continue command */
+ char *step; /* single step */
+ char *stop; /* Interrupt program string */
+ char *set_break; /* set a breakpoint. If NULL, monitor implementation
+ sets its own to_insert_breakpoint method. */
+ char *clr_break; /* clear a breakpoint */
+ char *clr_all_break; /* Clear all breakpoints */
+ char *fill; /* Memory fill cmd (addr len val) */
+ struct memrw_cmd setmem; /* set memory to a value */
+ struct memrw_cmd getmem; /* display memory */
+ struct regrw_cmd setreg; /* set a register */
+ struct regrw_cmd getreg; /* get a register */
+ /* Some commands can dump a bunch of registers
+ at once. This comes as a set of REG=VAL
+ pairs. This should be called for each pair
+ of registers that we can parse to supply
+ GDB with the value of a register. */
+ char *dump_registers; /* Command to dump all regs at once */
+ char *register_pattern; /* Pattern that picks out register from reg dump */
+ void (*supply_register) (char *name, int namelen, char *val, int vallen);
+ void (*load_routine) (struct serial *desc, char *file,
+ int hashmark); /* Download routine */
+ int (*dumpregs) (void); /* routine to dump all registers */
+ int (*continue_hook) (void); /* Emit the continue command */
+ int (*wait_filter) (char *buf, /* Maybe contains registers */
+ int bufmax,
+ int *response_length,
+ struct target_waitstatus * status);
+ char *load; /* load command */
+ char *loadresp; /* Response to load command */
+ char *prompt; /* monitor command prompt */
+ char *line_term; /* end-of-command delimitor */
+ char *cmd_end; /* optional command terminator */
+ struct target_ops *target; /* target operations */
+ int stopbits; /* number of stop bits */
+ char **regnames; /* array of register names in ascii */
+ int num_breakpoints; /* If set_break != NULL, number of supported
+ breakpoints */
+ int magic; /* Check value */
+ };
+
+/* The monitor ops magic number, used to detect if an ops structure doesn't
+ have the right number of entries filled in. */
+
+#define MONITOR_OPS_MAGIC 600925
+
+/* Flag definitions. */
+
+/* If set, then clear breakpoint command uses address, otherwise it
+ uses an index returned by the monitor. */
+
+#define MO_CLR_BREAK_USES_ADDR 0x1
+
+/* If set, then memory fill command uses STARTADDR, ENDADDR+1, VALUE
+ as args, else it uses STARTADDR, LENGTH, VALUE as args. */
+
+#define MO_FILL_USES_ADDR 0x2
+
+/* If set, then monitor doesn't automatically supply register dump
+ when coming back after a continue. */
+
+#define MO_NEED_REGDUMP_AFTER_CONT 0x4
+
+/* getmem needs start addr and end addr */
+
+#define MO_GETMEM_NEEDS_RANGE 0x8
+
+/* getmem can only read one loc at a time */
+
+#define MO_GETMEM_READ_SINGLE 0x10
+
+/* handle \r\n combinations */
+
+#define MO_HANDLE_NL 0x20
+
+/* don't expect echos in monitor_open */
+
+#define MO_NO_ECHO_ON_OPEN 0x40
+
+/* If set, send break to stop monitor */
+
+#define MO_SEND_BREAK_ON_STOP 0x80
+
+/* If set, target sends an ACK after each S-record */
+
+#define MO_SREC_ACK 0x100
+
+/* Allow 0x prefix on addresses retured from monitor */
+
+#define MO_HEX_PREFIX 0x200
+
+/* Some monitors require a different command when starting a program */
+
+#define MO_RUN_FIRST_TIME 0x400
+
+/* Don't expect echos when getting memory */
+
+#define MO_NO_ECHO_ON_SETMEM 0x800
+
+/* If set, then register store command expects value BEFORE regname */
+
+#define MO_REGISTER_VALUE_FIRST 0x1000
+
+/* If set, then the monitor displays registers as pairs. */
+
+#define MO_32_REGS_PAIRED 0x2000
+
+/* If set, then register setting happens interactively. */
+
+#define MO_SETREG_INTERACTIVE 0x4000
+
+/* If set, then memory setting happens interactively. */
+
+#define MO_SETMEM_INTERACTIVE 0x8000
+
+/* If set, then memory dumps are always on 16-byte boundaries, even
+ when less is desired. */
+
+#define MO_GETMEM_16_BOUNDARY 0x10000
+
+/* If set, then the monitor numbers its breakpoints starting from 1. */
+
+#define MO_CLR_BREAK_1_BASED 0x20000
+
+/* If set, then the monitor acks srecords with a plus sign. */
+
+#define MO_SREC_ACK_PLUS 0x40000
+
+/* If set, then the monitor "acks" srecords with rotating lines. */
+
+#define MO_SREC_ACK_ROTATE 0x80000
+
+/* If set, then remove useless address bits from memory addresses. */
+
+#define MO_ADDR_BITS_REMOVE 0x100000
+
+/* If set, then display target program output if prefixed by ^O. */
+
+#define MO_PRINT_PROGRAM_OUTPUT 0x200000
+
+/* Some dump bytes commands align the first data with the preceeding
+ 16 byte boundary. Some print blanks and start at the exactly the
+ requested boundary. */
+
+#define MO_EXACT_DUMPADDR 0x400000
+
+/* Rather entering and exiting the write memory dialog for each word byte,
+ we can save time by transferring the whole block without exiting
+ the memory editing mode. You only need to worry about this
+ if you are doing memory downloading.
+ This engages a new write function registered with dcache.
+ */
+#define MO_HAS_BLOCKWRITES 0x800000
+
+#define SREC_SIZE 160
+
+extern void monitor_open (char *args, struct monitor_ops *ops, int from_tty);
+extern void monitor_close (int quitting);
+extern char *monitor_supply_register (int regno, char *valstr);
+extern int monitor_expect (char *prompt, char *buf, int buflen);
+extern int monitor_expect_prompt (char *buf, int buflen);
+extern void monitor_printf (char *, ...) ATTR_FORMAT (printf, 1, 2);
+extern void
+monitor_printf_noecho (char *, ...)
+ATTR_FORMAT (printf, 1, 2);
+extern void monitor_write (char *buf, int buflen);
+extern int monitor_readchar (void);
+extern char *monitor_get_dev_name (void);
+extern void init_monitor_ops (struct target_ops *);
+extern int monitor_dump_reg_block (char *dump_cmd);
+
+#endif
diff --git a/gdb/msg.defs b/gdb/msg.defs
new file mode 100644
index 00000000000..7c9fcd15f54
--- /dev/null
+++ b/gdb/msg.defs
@@ -0,0 +1 @@
+#include <hurd/msg.defs>
diff --git a/gdb/msg_reply.defs b/gdb/msg_reply.defs
new file mode 100644
index 00000000000..049bfa87cfa
--- /dev/null
+++ b/gdb/msg_reply.defs
@@ -0,0 +1 @@
+#include <hurd/msg_reply.defs>
diff --git a/gdb/nbsd-tdep.c b/gdb/nbsd-tdep.c
new file mode 100644
index 00000000000..71e229d57b0
--- /dev/null
+++ b/gdb/nbsd-tdep.c
@@ -0,0 +1,98 @@
+/* Common target-dependent code for NetBSD systems.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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 "defs.h"
+#include "solib-svr4.h"
+
+/* Fetch (and possibly build) an appropriate link_map_offsets
+ structure for NetBSD targets using the struct offsets defined
+ in <link.h> (but without actual reference to that file).
+
+ This makes it possible to access NetBSD shared libraries from a
+ GDB that was not built on the same platform (for cross debugging).
+
+ We provide versions for ILP32 and LP64 NetBSD targets here. */
+
+struct link_map_offsets *
+nbsd_ilp32_solib_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_debug_size = 16;
+
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 4;
+
+ lmo.link_map_size = 20;
+
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 4;
+
+ lmo.l_name_offset = 4;
+ lmo.l_name_size = 4;
+
+ lmo.l_next_offset = 12;
+ lmo.l_next_size = 4;
+
+ lmo.l_prev_offset = 16;
+ lmo.l_prev_size = 4;
+ }
+
+ return lmp;
+}
+
+struct link_map_offsets *
+nbsd_lp64_solib_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_debug_size = 32;
+
+ lmo.r_map_offset = 8;
+ lmo.r_map_size = 8;
+
+ lmo.link_map_size = 40;
+
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 8;
+
+ lmo.l_name_offset = 8;
+ lmo.l_name_size = 8;
+
+ lmo.l_next_offset = 24;
+ lmo.l_next_size = 8;
+
+ lmo.l_prev_offset = 32;
+ lmo.l_prev_size = 8;
+ }
+
+ return lmp;
+}
diff --git a/gdb/nbsd-tdep.h b/gdb/nbsd-tdep.h
new file mode 100644
index 00000000000..ca40965184f
--- /dev/null
+++ b/gdb/nbsd-tdep.h
@@ -0,0 +1,28 @@
+/* Common target-dependent definitions for NetBSD systems.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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. */
+
+#ifndef NBSD_TDEP_H
+#define NBSD_TDEP_H
+
+struct link_map_offsets *nbsd_ilp32_solib_svr4_fetch_link_map_offsets (void);
+struct link_map_offsets *nbsd_lp64_solib_svr4_fetch_link_map_offsets (void);
+
+#endif /* NBSD_TDEP_H */
diff --git a/gdb/nindy-share/Makefile b/gdb/nindy-share/Makefile
new file mode 100644
index 00000000000..5ec99ba38e7
--- /dev/null
+++ b/gdb/nindy-share/Makefile
@@ -0,0 +1,117 @@
+#Copyright 1992 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.
+
+#-----------------------------------------------------------------------------
+# Makefile for toolib.a -- host code shAred by more than one tool
+#-----------------------------------------------------------------------------
+
+RANLIB = ranlib
+
+# The following lines should be uncommented for system V (i386v).
+#__i386v__#USG = -DUSG
+#__i386v__#SYSV_INCL = ${IPATH}/sysv.h
+#__i386v__#RANLIB = echo >/dev/null
+
+# The following line should be uncommented for HP-UX
+#__hp9000__#USG = -DUSG
+#__hp9000__#SYSV_INCL = ${IPATH}/sysv.h
+#__hp9000__#RANLIB = echo >/dev/null
+
+# Essential under System V, harmless elsewhere
+SHELL = /bin/sh
+
+#'HOST' will be defined in the host-specific makefile by 'make make'
+
+TARG = toolib.a
+OPT = -g
+IPATH = ../../include
+CFLAGS = ${OPT} ${USG} -I${IPATH} -DHOST=\"${HOST}\"
+OBJS = coffstrip.o nindy.o ttybreak.o ttyflush.o Onindy.o
+
+${TARG}: ${OBJS} VERSION
+ make ver960.o
+ rm -f ${TARG}
+ ar cvr ${TARG} ${OBJS} ver960.o
+ ${RANLIB} ${TARG}
+
+coffstrip.o: ${IPATH}/b.out.h ${IPATH}/coff.h ${IPATH}/sysv.h
+nindy.o: ${IPATH}/block_io.h ${IPATH}/env.h ${IPATH}/sysv.h
+nindy.o: ${IPATH}/ttycntl.h ${IPATH}/wait.h
+ttybreak.o: ${IPATH}/ttycntl.h
+ttyflush.o: ${IPATH}/ttycntl.h
+Onindy.o: ${IPATH}/block_io.h ${IPATH}/env.h ${IPATH}/sysv.h
+Onindy.o: ${IPATH}/ttycntl.h ${IPATH}/wait.h
+
+
+#-----------------------------------------------------------------------------
+# 'STANDARD' GNU/960 TARGETS BELOW THIS POINT
+#
+# 'VERSION' file must be present and contain a string of the form "x.y"
+#-----------------------------------------------------------------------------
+
+ver960.c: FORCE
+ rm -f ver960.c
+ echo "char toolib_ver[]= \"${TARG} `cat VERSION`, `date`\";" > ver960.c
+
+
+# This target should be invoked before building a new release.
+# 'VERSION' file must be present and contain a string of the form "x.y"
+#
+roll:
+ @V=`cat VERSION` ; \
+ MAJ=`sed 's/\..*//' VERSION` ; \
+ MIN=`sed 's/.*\.//' VERSION` ; \
+ V=$$MAJ.`expr $$MIN + 1` ; \
+ rm -f VERSION ; \
+ echo $$V >VERSION ; \
+ echo Version $$V
+
+# Dummy target to force execution of dependent targets.
+#
+FORCE:
+
+# 'G960BASE' will be defined at invocation
+#
+install:
+ make ${TARG}
+ mv -f ${TARG} ${G960BASE}/lib
+
+clean:
+ rm -f ${TARG} *.o core
+
+# Target to uncomment host-specific lines in this makefile. Such lines must
+# have the following string beginning in column 1: #__<hostname>__#
+# Original Makefile is backed up as 'Makefile.old'.
+#
+# Invoke with: make make HOST=xxx
+#
+make:
+ -@if test $(HOST)x = x ; then \
+ echo 'Specify "make make HOST=???"'; \
+ exit 1; \
+ fi ; \
+ grep -s "^#The next line was generated by 'make make'" Makefile; \
+ if test $$? = 0 ; then \
+ echo "Makefile has already been processed with 'make make'";\
+ exit 1; \
+ fi ; \
+ mv -f Makefile Makefile.old; \
+ echo "#The next line was generated by 'make make'" >Makefile ; \
+ echo "HOST=$(HOST)" >>Makefile ; \
+ echo >>Makefile ; \
+ sed "s/^#__$(HOST)__#//" < Makefile.old >>Makefile
diff --git a/gdb/nindy-share/Onindy.c b/gdb/nindy-share/Onindy.c
new file mode 100644
index 00000000000..f544183c4cb
--- /dev/null
+++ b/gdb/nindy-share/Onindy.c
@@ -0,0 +1,743 @@
+/* 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. */
+
+/* This started out life as code shared between the nindy monitor and
+ GDB. For various reasons, this is no longer true. Eventually, it
+ probably should be merged into remote-nindy.c. */
+
+/******************************************************************************
+ *
+ * NINDY INTERFACE ROUTINES
+ *
+ * This version of the NINDY interface routines supports NINDY versions
+ * 2.13 and older. The older versions used a hex communication protocol,
+ * instead of the (faster) current binary protocol. These routines have
+ * been renamed by prepending the letter 'O' to their names, to avoid
+ * conflict with the current version. The old versions are kept only for
+ * backward compatibility, and well disappear in a future release.
+ *
+ **************************************************************************/
+
+/* Having these in a separate file from nindy.c is really ugly, and should
+ be merged with nindy.c. */
+
+#include <stdio.h>
+#if 0
+#include <sys/ioctl.h>
+#include <sys/types.h> /* Needed by file.h on Sys V */
+#include <sys/file.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <fcntl.h> /* Needed on Sys V */
+#include "ttycntl.h"
+#endif
+#include "defs.h"
+#include "serial.h"
+
+#include "block_io.h"
+#include "gdb_wait.h"
+#include "env.h"
+
+/* Number of bytes that we send to nindy. I believe this is defined by
+ the protocol (it does not agree with REGISTER_BYTES). */
+#define OLD_NINDY_REGISTER_BYTES ((36*4) + (4*8))
+
+extern int quiet; /* 1 => stifle unnecessary messages */
+
+/* tty connected to 960/NINDY board. */
+extern struct serial *nindy_serial;
+
+static OninStrGet();
+
+ /****************************
+ * *
+ * MISCELLANEOUS UTILTIES *
+ * *
+ ****************************/
+
+
+/******************************************************************************
+ * fromhex:
+ * Convert a hex ascii digit h to a binary integer
+ ******************************************************************************/
+static
+int
+fromhex( h )
+ int h;
+{
+ if (h >= '0' && h <= '9'){
+ h -= '0';
+ } else if (h >= 'a' && h <= 'f'){
+ h -= 'a' - 10;
+ } else {
+ h = 0;
+ }
+ return (h & 0xff);
+}
+
+
+/******************************************************************************
+ * hexbin:
+ * Convert a string of ASCII hex digits to a string of binary bytes.
+ ******************************************************************************/
+static
+hexbin( n, hexp, binp )
+ int n; /* Number of bytes to convert (twice this many digits)*/
+ char *hexp; /* Get hex from here */
+ char *binp; /* Put binary here */
+{
+ while ( n-- ){
+ *binp++ = (fromhex(*hexp) << 4) | fromhex(*(hexp+1));
+ hexp += 2;
+ }
+}
+
+
+/******************************************************************************
+ * binhex:
+ * Convert a string of binary bytes to a string of ASCII hex digits
+ ******************************************************************************/
+static
+binhex( n, binp, hexp )
+ int n; /* Number of bytes to convert */
+ char *binp; /* Get binary from here */
+ char *hexp; /* Place hex here */
+{
+ static char tohex[] = "0123456789abcdef";
+
+ while ( n-- ){
+ *hexp++ = tohex[ (*binp >> 4) & 0xf ];
+ *hexp++ = tohex[ *binp & 0xf ];
+ binp++;
+ }
+}
+
+/******************************************************************************
+ * byte_order:
+ * If the host byte order is different from 960 byte order (i.e., the
+ * host is big-endian), reverse the bytes in the passed value; otherwise,
+ * return the passed value unchanged.
+ *
+ ******************************************************************************/
+static
+long
+byte_order( n )
+ long n;
+{
+ long rev;
+ int i;
+ static short test = 0x1234;
+
+ if (*((char *) &test) == 0x12) {
+ /*
+ * Big-endian host, swap the bytes.
+ */
+ rev = 0;
+ for ( i = 0; i < sizeof(n); i++ ){
+ rev <<= 8;
+ rev |= n & 0xff;
+ n >>= 8;
+ }
+ n = rev;
+ }
+ return n;
+}
+
+/******************************************************************************
+ * say:
+ * This is a printf that takes at most two arguments (in addition to the
+ * format string) and that outputs nothing if verbose output has been
+ * suppressed.
+ ******************************************************************************/
+static
+say( fmt, arg1, arg2 )
+ char *fmt;
+ int arg1, arg2;
+{
+ if ( !quiet ){
+ printf( fmt, arg1, arg2 );
+ fflush( stdout );
+ }
+}
+
+ /*****************************
+ * *
+ * LOW-LEVEL COMMUNICATION *
+ * *
+ *****************************/
+
+/* Read a single character from the remote end. */
+
+static int
+readchar()
+{
+ /* FIXME: Do we really want to be reading without a timeout? */
+ return serial_readchar (nindy_serial, -1);
+}
+
+/******************************************************************************
+ * getpkt:
+ * Read a packet from a remote NINDY, with error checking, and return
+ * it in the indicated buffer.
+ ******************************************************************************/
+static
+getpkt (buf)
+ char *buf;
+{
+ unsigned char recv; /* Checksum received */
+ unsigned char csum; /* Checksum calculated */
+ char *bp; /* Poointer into the buffer */
+ int c;
+
+ while (1){
+ csum = 0;
+ bp = buf;
+ /* FIXME: check for error from readchar (). */
+ while ( (c = readchar()) != '#' ){
+ *bp++ = c;
+ csum += c;
+ }
+ *bp = 0;
+
+ /* FIXME: check for error from readchar (). */
+ recv = fromhex(readchar()) << 4;
+ recv |= fromhex(readchar());
+ if ( csum == recv ){
+ break;
+ }
+
+ fprintf(stderr,
+ "Bad checksum (recv=0x%02x; calc=0x%02x); retrying\r\n",
+ recv, csum );
+ serial_write (nindy_serial, "-", 1);
+ }
+
+ serial_write (nindy_serial, "+", 1);
+}
+
+
+/******************************************************************************
+ * putpkt:
+ * Checksum and send a gdb command to a remote NINDY, and wait for
+ * positive acknowledgement.
+ *
+ ******************************************************************************/
+static
+putpkt( cmd )
+ char *cmd; /* Command to be sent, without lead ^P (\020)
+ * or trailing checksum
+ */
+{
+ char ack; /* Response received from NINDY */
+ char checksum[4];
+ char *p;
+ unsigned int s;
+ char resend;
+
+ for ( s='\020', p=cmd; *p; p++ ){
+ s += *p;
+ }
+ sprintf( checksum, "#%02x", s & 0xff );
+
+ /* Send checksummed message over and over until we get a positive ack
+ */
+ resend = 1;
+ do {
+ if ( resend ) {
+ serial_write ( nindy_serial, "\020", 1 );
+ serial_write( nindy_serial, cmd, strlen(cmd) );
+ serial_write( nindy_serial, checksum, strlen(checksum) );
+ }
+ /* FIXME: do we really want to be reading without timeout? */
+ ack = serial_readchar (nindy_serial, -1);
+ if (ack < 0)
+ {
+ fprintf (stderr, "error reading from serial port\n");
+ }
+ if ( ack == '-' ){
+ fprintf( stderr, "Remote NAK, resending\r\n" );
+ resend = 1;
+ } else if ( ack != '+' ){
+ fprintf( stderr, "Bad ACK, ignored: <%c>\r\n", ack );
+ resend = 0;
+ }
+ } while ( ack != '+' );
+}
+
+
+
+/******************************************************************************
+ * send:
+ * Send a message to a remote NINDY and return the reply in the same
+ * buffer (clobbers the input message). Check for error responses
+ * as indicated by the second argument.
+ *
+ ******************************************************************************/
+static
+send( buf, ack_required )
+ char *buf; /* Message to be sent to NINDY; replaced by
+ * NINDY's response.
+ */
+ int ack_required; /* 1 means NINDY's response MUST be either "X00" (no
+ * error) or an error code "Xnn".
+ * 0 means the it's OK as long as it doesn't
+ * begin with "Xnn".
+ */
+{
+ int errnum;
+ static char *errmsg[] = {
+ "", /* X00 */
+ "Buffer overflow", /* X01 */
+ "Unknown command", /* X02 */
+ "Wrong amount of data to load register(s)", /* X03 */
+ "Missing command argument(s)", /* X04 */
+ "Odd number of digits sent to load memory", /* X05 */
+ "Unknown register name", /* X06 */
+ "No such memory segment", /* X07 */
+ "No breakpoint available", /* X08 */
+ "Can't set requested baud rate", /* X09 */
+ };
+# define NUMERRS ( sizeof(errmsg) / sizeof(errmsg[0]) )
+
+ static char err0[] = "NINDY failed to acknowledge command: <%s>\r\n";
+ static char err1[] = "Unknown error response from NINDY: <%s>\r\n";
+ static char err2[] = "Error response %s from NINDY: %s\r\n";
+
+ putpkt (buf);
+ getpkt (buf);
+
+ if ( buf[0] != 'X' ){
+ if ( ack_required ){
+ fprintf( stderr, err0, buf );
+ abort();
+ }
+
+ } else if ( strcmp(buf,"X00") ){
+ sscanf( &buf[1], "%x", &errnum );
+ if ( errnum > NUMERRS ){
+ fprintf( stderr, err1, buf );
+ } else{
+ fprintf( stderr, err2, buf, errmsg[errnum] );
+ }
+ abort();
+ }
+}
+
+ /**********************************
+ * *
+ * NINDY INTERFACE ROUTINES *
+ * *
+ * ninConnect *MUST* be the first *
+ * one of these routines called. *
+ **********************************/
+
+/******************************************************************************
+ * ninBptDel:
+ * Ask NINDY to delete the specified type of *hardware* breakpoint at
+ * the specified address. If the 'addr' is -1, all breakpoints of
+ * the specified type are deleted.
+ ******************************************************************************/
+OninBptDel( addr, data )
+ long addr; /* Address in 960 memory */
+ int data; /* '1' => data bkpt, '0' => instruction breakpoint */
+{
+ char buf[100];
+
+ if ( addr == -1 ){
+ sprintf( buf, "b%c", data ? '1' : '0' );
+ } else {
+ sprintf( buf, "b%c%x", data ? '1' : '0', addr );
+ }
+ return send( buf, 0 );
+}
+
+
+/******************************************************************************
+ * ninBptSet:
+ * Ask NINDY to set the specified type of *hardware* breakpoint at
+ * the specified address.
+ ******************************************************************************/
+OninBptSet( addr, data )
+ long addr; /* Address in 960 memory */
+ int data; /* '1' => data bkpt, '0' => instruction breakpoint */
+{
+ char buf[100];
+
+ sprintf( buf, "B%c%x", data ? '1' : '0', addr );
+ return send( buf, 0 );
+}
+
+/******************************************************************************
+ * ninGdbExit:
+ * Ask NINDY to leave GDB mode and print a NINDY prompt.
+ * Since it'll no longer be in GDB mode, don't wait for a response.
+ ******************************************************************************/
+OninGdbExit()
+{
+ putpkt( "E" );
+}
+
+/******************************************************************************
+ * ninGo:
+ * Ask NINDY to start or continue execution of an application program
+ * in it's memory at the current ip.
+ ******************************************************************************/
+OninGo( step_flag )
+ int step_flag; /* 1 => run in single-step mode */
+{
+ putpkt( step_flag ? "s" : "c" );
+}
+
+
+/******************************************************************************
+ * ninMemGet:
+ * Read a string of bytes from NINDY's address space (960 memory).
+ ******************************************************************************/
+OninMemGet(ninaddr, hostaddr, len)
+ long ninaddr; /* Source address, in the 960 memory space */
+ char *hostaddr; /* Destination address, in our memory space */
+ int len; /* Number of bytes to read */
+{
+ /* How much do we send at a time? */
+#define OLD_NINDY_MEMBYTES 1024
+ /* Buffer: hex in, binary out */
+ char buf[2*OLD_NINDY_MEMBYTES+20];
+
+ int cnt; /* Number of bytes in next transfer */
+
+ for ( ; len > 0; len -= OLD_NINDY_MEMBYTES ){
+ cnt = len > OLD_NINDY_MEMBYTES ? OLD_NINDY_MEMBYTES : len;
+
+ sprintf( buf, "m%x,%x", ninaddr, cnt );
+ send( buf, 0 );
+ hexbin( cnt, buf, hostaddr );
+
+ ninaddr += cnt;
+ hostaddr += cnt;
+ }
+}
+
+
+/******************************************************************************
+ * ninMemPut:
+ * Write a string of bytes into NINDY's address space (960 memory).
+ ******************************************************************************/
+OninMemPut( destaddr, srcaddr, len )
+ long destaddr; /* Destination address, in NINDY memory space */
+ char *srcaddr; /* Source address, in our memory space */
+ int len; /* Number of bytes to write */
+{
+ char buf[2*OLD_NINDY_MEMBYTES+20]; /* Buffer: binary in, hex out */
+ char *p; /* Pointer into buffer */
+ int cnt; /* Number of bytes in next transfer */
+
+ for ( ; len > 0; len -= OLD_NINDY_MEMBYTES ){
+ cnt = len > OLD_NINDY_MEMBYTES ? OLD_NINDY_MEMBYTES : len;
+
+ sprintf( buf, "M%x,", destaddr );
+ p = buf + strlen(buf);
+ binhex( cnt, srcaddr, p );
+ *(p+(2*cnt)) = '\0';
+ send( buf, 1 );
+
+ srcaddr += cnt;
+ destaddr += cnt;
+ }
+}
+
+/******************************************************************************
+ * ninRegGet:
+ * Retrieve the contents of a 960 register, and return them as a long
+ * in host byte order.
+ *
+ * THIS ROUTINE CAN ONLY BE USED TO READ THE LOCAL, GLOBAL, AND
+ * ip/ac/pc/tc REGISTERS.
+ *
+ ******************************************************************************/
+long
+OninRegGet( regname )
+ char *regname; /* Register name recognized by NINDY, subject to the
+ * above limitations.
+ */
+{
+ char buf[200];
+ long val;
+
+ sprintf( buf, "u%s", regname );
+ send( buf, 0 );
+ hexbin( 4, buf, (char *)&val );
+ return byte_order(val);
+}
+
+/******************************************************************************
+ * ninRegPut:
+ * Set the contents of a 960 register.
+ *
+ * THIS ROUTINE CAN ONLY BE USED TO SET THE LOCAL, GLOBAL, AND
+ * ip/ac/pc/tc REGISTERS.
+ *
+ ******************************************************************************/
+OninRegPut( regname, val )
+ char *regname; /* Register name recognized by NINDY, subject to the
+ * above limitations.
+ */
+ long val; /* New contents of register, in host byte-order */
+{
+ char buf[200];
+
+ sprintf( buf, "U%s,%08x", regname, byte_order(val) );
+ send( buf, 1 );
+}
+
+/******************************************************************************
+ * ninRegsGet:
+ * Get a dump of the contents of the entire 960 register set. The
+ * individual registers appear in the dump in the following order:
+ *
+ * pfp sp rip r3 r4 r5 r6 r7
+ * r8 r9 r10 r11 r12 r13 r14 r15
+ * g0 g1 g2 g3 g4 g5 g6 g7
+ * g8 g9 g10 g11 g12 g13 g14 fp
+ * pc ac ip tc fp0 fp1 fp2 fp3
+ *
+ * Each individual register comprises exactly 4 bytes, except for
+ * fp0-fp3, which are 8 bytes.
+ *
+ * WARNING:
+ * Each register value is in 960 (little-endian) byte order.
+ *
+ ******************************************************************************/
+OninRegsGet( regp )
+ char *regp; /* Where to place the register dump */
+{
+ char buf[(2*OLD_NINDY_REGISTER_BYTES)+10]; /* Registers in ASCII hex */
+
+ strcpy( buf, "r" );
+ send( buf, 0 );
+ hexbin( OLD_NINDY_REGISTER_BYTES, buf, regp );
+}
+
+/******************************************************************************
+ * ninRegsPut:
+ * Initialize the entire 960 register set to a specified set of values.
+ * The format of the register value data should be the same as that
+ * returned by ninRegsGet.
+ *
+ * WARNING:
+ * Each register value should be in 960 (little-endian) byte order.
+ *
+ ******************************************************************************/
+OninRegsPut( regp )
+ char *regp; /* Pointer to desired values of registers */
+{
+ char buf[(2*OLD_NINDY_REGISTER_BYTES)+10]; /* Registers in ASCII hex */
+
+ buf[0] = 'R';
+ binhex( OLD_NINDY_REGISTER_BYTES, regp, buf+1 );
+ buf[ (2*OLD_NINDY_REGISTER_BYTES)+1 ] = '\0';
+
+ send( buf, 1 );
+}
+
+
+/******************************************************************************
+ * ninReset:
+ * Ask NINDY to perform a soft reset; wait for the reset to complete.
+ ******************************************************************************/
+OninReset()
+{
+
+ putpkt( "X" );
+ /* FIXME: check for error from readchar (). */
+ while ( readchar() != '+' ){
+ ;
+ }
+}
+
+
+/******************************************************************************
+ * ninSrq:
+ * Assume NINDY has stopped execution of the 960 application program in
+ * order to process a host service request (srq). Ask NINDY for the
+ * srq arguments, perform the requested service, and send an "srq
+ * complete" message so NINDY will return control to the application.
+ *
+ ******************************************************************************/
+OninSrq()
+{
+ /* FIXME: Imposes arbitrary limits on lengths of pathnames and such. */
+ char buf[BUFSIZE];
+ int retcode;
+ unsigned char srqnum;
+ char *p;
+ char *argp;
+ int nargs;
+ int arg[MAX_SRQ_ARGS];
+
+
+ /* Get srq number and arguments
+ */
+ strcpy( buf, "!" );
+ send( buf, 0 );
+ hexbin( 1, buf, (char *)&srqnum );
+
+ /* Set up array of pointers the each of the individual
+ * comma-separated args
+ */
+ nargs=0;
+ argp = p = buf+2;
+ while ( 1 ){
+ while ( *p != ',' && *p != '\0' ){
+ p++;
+ }
+ sscanf( argp, "%x", &arg[nargs++] );
+ if ( *p == '\0' || nargs == MAX_SRQ_ARGS ){
+ break;
+ }
+ argp = ++p;
+ }
+
+ /* Process Srq
+ */
+ switch( srqnum ){
+ case BS_CLOSE:
+ /* args: file descriptor */
+ if ( arg[0] > 2 ){
+ retcode = close( arg[0] );
+ } else {
+ retcode = 0;
+ }
+ break;
+ case BS_CREAT:
+ /* args: filename, mode */
+ OninStrGet( arg[0], buf );
+ retcode = creat(buf,arg[1]);
+ break;
+ case BS_OPEN:
+ /* args: filename, flags, mode */
+ OninStrGet( arg[0], buf );
+ retcode = open(buf,arg[1],arg[2]);
+ break;
+ case BS_READ:
+ /* args: file descriptor, buffer, count */
+ retcode = read(arg[0],buf,arg[2]);
+ if ( retcode > 0 ){
+ OninMemPut( arg[1], buf, retcode );
+ }
+ break;
+ case BS_SEEK:
+ /* args: file descriptor, offset, whence */
+ retcode = lseek(arg[0],arg[1],arg[2]);
+ break;
+ case BS_WRITE:
+ /* args: file descriptor, buffer, count */
+ OninMemGet( arg[1], buf, arg[2] );
+ retcode = write(arg[0],buf,arg[2]);
+ break;
+ default:
+ retcode = -1;
+ break;
+ }
+
+ /* Tell NINDY to continue
+ */
+ sprintf( buf, "e%x", retcode );
+ send( buf, 1 );
+}
+
+
+/******************************************************************************
+ * ninStopWhy:
+ * Assume the application program has stopped (i.e., a DLE was received
+ * from NINDY). Ask NINDY for status information describing the
+ * reason for the halt.
+ *
+ * Returns a non-zero value if the user program has exited, 0 otherwise.
+ * Also returns the following information, through passed pointers:
+ * - why: an exit code if program the exited; otherwise the reason
+ * why the program halted (see stop.h for values).
+ * - contents of register ip (little-endian byte order)
+ * - contents of register sp (little-endian byte order)
+ * - contents of register fp (little-endian byte order)
+ ******************************************************************************/
+char
+OninStopWhy( whyp, ipp, fpp, spp )
+ char *whyp; /* Return the 'why' code through this pointer */
+ char *ipp; /* Return contents of register ip through this pointer */
+ char *fpp; /* Return contents of register fp through this pointer */
+ char *spp; /* Return contents of register sp through this pointer */
+{
+ char buf[30];
+ char stop_exit;
+
+ strcpy( buf, "?" );
+ send( buf, 0 );
+ hexbin( 1, buf, &stop_exit );
+ hexbin( 1, buf+2, whyp );
+ hexbin( 4, buf+4, ipp );
+ hexbin( 4, buf+12, fpp );
+ hexbin( 4, buf+20, spp );
+ return stop_exit;
+}
+
+/******************************************************************************
+ * ninStrGet:
+ * Read a '\0'-terminated string of data out of the 960 memory space.
+ *
+ ******************************************************************************/
+static
+OninStrGet( ninaddr, hostaddr )
+ unsigned long ninaddr; /* Address of string in NINDY memory space */
+ char *hostaddr; /* Address of the buffer to which string should
+ * be copied.
+ */
+{
+ /* FIXME: seems to be an arbitrary limit on the length of the string. */
+ char buf[BUFSIZE]; /* String as 2 ASCII hex digits per byte */
+ int numchars; /* Length of string in bytes. */
+
+ sprintf( buf, "\"%x", ninaddr );
+ send( buf, 0 );
+ numchars = strlen(buf)/2;
+ hexbin( numchars, buf, hostaddr );
+ hostaddr[numchars] = '\0';
+}
+
+#if 0
+/* never used. */
+
+/******************************************************************************
+ * ninVersion:
+ * Ask NINDY for version information about itself.
+ * The information is sent as an ascii string in the form "x.xx,<arch>",
+ * where,
+ * x.xx is the version number
+ * <arch> is the processor architecture: "KA", "KB", "MC", "CA" *
+ *
+ ******************************************************************************/
+int
+OninVersion( p )
+ char *p; /* Where to place version string */
+{
+ /* FIXME: this is an arbitrary limit on the length of version string. */
+ char buf[BUFSIZE];
+
+ strcpy( buf, "v" );
+ send( buf, 0 );
+ strcpy( p, buf );
+ return strlen( buf );
+}
+#endif
diff --git a/gdb/nindy-share/README b/gdb/nindy-share/README
new file mode 100644
index 00000000000..3f217ad9527
--- /dev/null
+++ b/gdb/nindy-share/README
@@ -0,0 +1,3 @@
+The files in this directory started out life as code shared between
+the nindy monitor and GDB. For various reasons, this is no longer
+true. Eventually, they probably should be merged into remote-nindy.c.
diff --git a/gdb/nindy-share/VERSION b/gdb/nindy-share/VERSION
new file mode 100644
index 00000000000..5625e59da88
--- /dev/null
+++ b/gdb/nindy-share/VERSION
@@ -0,0 +1 @@
+1.2
diff --git a/gdb/nindy-share/b.out.h b/gdb/nindy-share/b.out.h
new file mode 100644
index 00000000000..a82c261a7fd
--- /dev/null
+++ b/gdb/nindy-share/b.out.h
@@ -0,0 +1,158 @@
+/* Copyright 1992 Free Software Foundation, Inc.
+ *
+ * This file is a modified version of 'a.out.h'. It is to be used in all
+ * all GNU tools modified to support the i80960 (or tools that operate on
+ * object files created by such tools).
+ *
+ * All i80960 development is done in a CROSS-DEVELOPMENT environment. I.e.,
+ * object code is generated on, and executed under the direction of a symbolic
+ * debugger running on, a host system. We do not want to be subject to the
+ * vagaries of which host it is or whether it supports COFF or a.out format,
+ * or anything else. We DO want to:
+ *
+ * o always generate the same format object files, regardless of host.
+ *
+ * o have an 'a.out' header that we can modify for our own purposes
+ * (the 80960 is typically an embedded processor and may require
+ * enhanced linker support that the normal a.out.h header can't
+ * accommodate).
+ *
+ * As for byte-ordering, the following rules apply:
+ *
+ * o Text and data that is actually downloaded to the target is always
+ * in i80960 (little-endian) order.
+ *
+ * o All other numbers (in the header, symbols, relocation directives)
+ * are in host byte-order: object files CANNOT be lifted from a
+ * little-end host and used on a big-endian (or vice versa) without
+ * modification.
+ *
+ * o The downloader ('comm960') takes care to generate a pseudo-header
+ * with correct (i80960) byte-ordering before shipping text and data
+ * off to the NINDY monitor in the target systems. Symbols and
+ * relocation info are never sent to the target.
+ */
+
+
+#define BMAGIC 0415
+/* We don't accept the following (see N_BADMAG macro).
+ * They're just here so GNU code will compile.
+ */
+#define OMAGIC 0407 /* old impure format */
+#define NMAGIC 0410 /* read-only text */
+#define ZMAGIC 0413 /* demand load format */
+
+/* FILE HEADER
+ * All 'lengths' are given as a number of bytes.
+ * All 'alignments' are for relinkable files only; an alignment of
+ * 'n' indicates the corresponding segment must begin at an
+ * address that is a multiple of (2**n).
+ */
+struct exec {
+ /* Standard stuff */
+ unsigned long a_magic; /* Identifies this as a b.out file */
+ unsigned long a_text; /* Length of text */
+ unsigned long a_data; /* Length of data */
+ unsigned long a_bss; /* Length of runtime uninitialized data area */
+ unsigned long a_syms; /* Length of symbol table */
+ unsigned long a_entry; /* Runtime start address */
+ unsigned long a_trsize; /* Length of text relocation info */
+ unsigned long a_drsize; /* Length of data relocation info */
+
+ /* Added for i960 */
+ unsigned long a_tload; /* Text runtime load address */
+ unsigned long a_dload; /* Data runtime load address */
+ unsigned char a_talign; /* Alignment of text segment */
+ unsigned char a_dalign; /* Alignment of data segment */
+ unsigned char a_balign; /* Alignment of bss segment */
+ unsigned char unused; /* (Just to make struct size a multiple of 4) */
+};
+
+#define N_BADMAG(x) (((x).a_magic)!=BMAGIC)
+#define N_TXTOFF(x) ( sizeof(struct exec) )
+#define N_DATOFF(x) ( N_TXTOFF(x) + (x).a_text )
+#define N_TROFF(x) ( N_DATOFF(x) + (x).a_data )
+#define N_DROFF(x) ( N_TROFF(x) + (x).a_trsize )
+#define N_SYMOFF(x) ( N_DROFF(x) + (x).a_drsize )
+#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms )
+
+/* A single entry in the symbol table
+ */
+struct nlist {
+ union {
+ char *n_name;
+ struct nlist *n_next;
+ long n_strx; /* Index into string table */
+ } n_un;
+ unsigned char n_type; /* See below */
+ char n_other; /* Used in i80960 support -- see below */
+ short n_desc;
+ unsigned long n_value;
+};
+
+
+/* Legal values of n_type
+ */
+#define N_UNDF 0 /* Undefined symbol */
+#define N_ABS 2 /* Absolute symbol */
+#define N_TEXT 4 /* Text symbol */
+#define N_DATA 6 /* Data symbol */
+#define N_BSS 8 /* BSS symbol */
+#define N_FN 31 /* Filename symbol */
+
+#define N_EXT 1 /* External symbol (OR'd in with one of above) */
+#define N_TYPE 036 /* Mask for all the type bits */
+#define N_STAB 0340 /* Mask for all bits used for SDB entries */
+
+/* MEANING OF 'n_other'
+ *
+ * If non-zero, the 'n_other' fields indicates either a leaf procedure or
+ * a system procedure, as follows:
+ *
+ * 1 <= n_other <= 32 :
+ * The symbol is the entry point to a system procedure.
+ * 'n_value' is the address of the entry, as for any other
+ * procedure. The system procedure number (which can be used in
+ * a 'calls' instruction) is (n_other-1). These entries come from
+ * '.sysproc' directives.
+ *
+ * n_other == N_CALLNAME
+ * the symbol is the 'call' entry point to a leaf procedure.
+ * The *next* symbol in the symbol table must be the corresponding
+ * 'bal' entry point to the procedure (see following). These
+ * entries come from '.leafproc' directives in which two different
+ * symbols are specified (the first one is represented here).
+ *
+ *
+ * n_other == N_BALNAME
+ * the symbol is the 'bal' entry point to a leaf procedure.
+ * These entries result from '.leafproc' directives in which only
+ * one symbol is specified, or in which the same symbol is
+ * specified twice.
+ *
+ * Note that an N_CALLNAME entry *must* have a corresponding N_BALNAME entry,
+ * but not every N_BALNAME entry must have an N_CALLNAME entry.
+ */
+#define N_CALLNAME -1
+#define N_BALNAME -2
+
+
+struct relocation_info {
+ int r_address; /* File address of item to be relocated */
+ unsigned
+ r_symbolnum:24,/* Index of symbol on which relocation is based*/
+ r_pcrel:1, /* 1 => relocate PC-relative; else absolute
+ * On i960, pc-relative implies 24-bit
+ * address, absolute implies 32-bit.
+ */
+ r_length:2, /* Number of bytes to relocate:
+ * 0 => 1 byte
+ * 1 => 2 bytes
+ * 2 => 4 bytes -- only value used for i960
+ */
+ r_extern:1,
+ r_bsr:1, /* Something for the GNU NS32K assembler */
+ r_disp:1, /* Something for the GNU NS32K assembler */
+ r_callj:1, /* 1 if relocation target is an i960 'callj' */
+ nuthin:1; /* Unused */
+};
diff --git a/gdb/nindy-share/block_io.h b/gdb/nindy-share/block_io.h
new file mode 100644
index 00000000000..6521cdb9b05
--- /dev/null
+++ b/gdb/nindy-share/block_io.h
@@ -0,0 +1,68 @@
+/******************************************************************
+ Copyright 1990, 1992 Free Software Foundation, Inc.
+
+ This code was donated by Intel Corp.
+
+ Intel hereby grants you permission to copy, modify, and
+ distribute this software and its documentation. Intel grants
+ this permission provided that the above copyright notice
+ appears in all copies and that both the copyright notice and
+ this permission notice appear in supporting documentation. In
+ addition, Intel grants this permission provided that you
+ prominently mark as not part of the original any modifications
+ made to this software or documentation, and that the name of
+ Intel Corporation not be used in advertising or publicity
+ pertaining to distribution of the software or the documentation
+ without specific, written prior permission.
+
+ Intel Corporation does not warrant, guarantee or make any
+ representations regarding the use of, or the results of the use
+ of, the software and documentation in terms of correctness,
+ accuracy, reliability, currentness, or otherwise; and you rely
+ on the software, documentation and results solely at your own
+ risk. */
+/******************************************************************/
+
+/*****************************************************************************
+ * Structures and definitions supporting NINDY requests for services by a
+ * remote host. Used by NINDY monitor, library libnin, comm960, gdb960,
+ * etc. Also contains some defines for NINDY console I/O requests.
+ *****************************************************************************/
+
+/* the following four are hardware dependent */
+#define BIT_16 short
+#define BIT_32 int
+#define UBIT_16 unsigned short
+#define UBIT_32 unsigned int
+
+/* Service request numbers -- these are the services that can be asked of the
+ * host.
+ */
+#define BS_ACCESS 0x10
+#define BS_CLOSE 0x20
+#define BS_CREAT 0x30
+#define BS_SEEK 0x40
+#define BS_OPEN 0x50
+#define BS_READ 0x60
+#define BS_STAT 0x70
+#define BS_SYSTEMD 0x80
+#define BS_TIME 0x90
+#define BS_UNMASK 0xa0
+#define BS_UNLINK 0xb0
+#define BS_WRITE 0xc0
+
+
+/* Maximum number of arguments to any of the above service requests
+ * (in addition to the request number).
+ */
+#define MAX_SRQ_ARGS 3
+
+/* Number of bytes of data that can be read or written by a single I/O request
+ */
+#define BUFSIZE 1024
+
+/* NINDY console I/O requests: CO sends a single character to stdout,
+ * CI reads one.
+ */
+#define CI 0
+#define CO 1
diff --git a/gdb/nindy-share/coff.h b/gdb/nindy-share/coff.h
new file mode 100644
index 00000000000..b169b71ec53
--- /dev/null
+++ b/gdb/nindy-share/coff.h
@@ -0,0 +1,336 @@
+/* Copyright 1990, 1992 Free Software Foundation, Inc.
+ *
+ * This code was donated by Intel Corp.
+ *
+ * This is a coff version of a.out.h to support 80960 debugging from
+ * a Unix (possibly BSD) host. It's used by:
+ * o gdb960 to symbols in code generated with Intel (non-GNU) tools.
+ * o comm960 to convert a b.out file to a coff file for download.
+ */
+
+
+/********************** FILE HEADER **********************/
+
+struct filehdr {
+ unsigned short f_magic; /* magic number */
+ unsigned short f_nscns; /* number of sections */
+ long f_timdat; /* time & date stamp */
+ long f_symptr; /* file pointer to symtab */
+ long f_nsyms; /* number of symtab entries */
+ unsigned short f_opthdr; /* sizeof(optional hdr) */
+ unsigned short f_flags; /* flags */
+};
+
+
+/* Bits for f_flags:
+ * F_RELFLG relocation info stripped from file
+ * F_EXEC file is executable (no unresolved externel references)
+ * F_LNNO line nunbers stripped from file
+ * F_LSYMS local symbols stripped from file
+ * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax)
+ */
+#define F_RELFLG 0000001
+#define F_EXEC 0000002
+#define F_LNNO 0000004
+#define F_LSYMS 0000010
+#define F_AR32WR 0000400
+
+
+/*
+ * Intel 80960 (I960) processor flags.
+ * F_I960TYPE == mask for processor type field.
+ */
+#define F_I960TYPE 0170000
+#define F_I960CA 0010000
+#define F_I960FLOAT 0020000
+#define F_I960BA 0030000
+#define F_I960XA 0040000
+
+/*
+ * i80960 Magic Numbers
+ */
+#define I960ROMAGIC 0540 /* read-only text segments */
+#define I960RWMAGIC 0541 /* read-write text segments */
+
+#define I960BADMAG(x) (((x).f_magic!=I960ROMAGIC) && ((x).f_magic!=I960RWMAGIC))
+
+#define FILHDR struct filehdr
+#define FILHSZ sizeof(FILHDR)
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+typedef struct {
+ unsigned long phys_addr;
+ unsigned long bitarray;
+} TAGBITS;
+
+typedef struct aouthdr {
+ short magic; /* type of file */
+ short vstamp; /* version stamp */
+ unsigned long tsize; /* text size in bytes, padded to FW bdry*/
+ unsigned long dsize; /* initialized data " " */
+ unsigned long bsize; /* uninitialized data " " */
+#if U3B
+ unsigned long dum1;
+ unsigned long dum2; /* pad to entry point */
+#endif
+ unsigned long entry; /* entry pt. */
+ unsigned long text_start; /* base of text used for this file */
+ unsigned long data_start; /* base of data used for this file */
+ unsigned long tagentries; /* number of tag entries to follow */
+} AOUTHDR;
+
+/* return a pointer to the tag bits array */
+
+#define TAGPTR(aout) ((TAGBITS *) (&(aout.tagentries)+1))
+
+/* compute size of a header */
+
+#define AOUTSZ(aout) (sizeof(AOUTHDR)+(aout.tagentries*sizeof(TAGBITS)))
+
+/********************** STORAGE CLASSES **********************/
+
+#define C_EFCN -1 /* physical end of function */
+#define C_NULL 0
+#define C_AUTO 1 /* automatic variable */
+#define C_EXT 2 /* external symbol */
+#define C_STAT 3 /* static */
+#define C_REG 4 /* register variable */
+#define C_EXTDEF 5 /* external definition */
+#define C_LABEL 6 /* label */
+#define C_ULABEL 7 /* undefined label */
+#define C_MOS 8 /* member of structure */
+#define C_ARG 9 /* function argument */
+#define C_STRTAG 10 /* structure tag */
+#define C_MOU 11 /* member of union */
+#define C_UNTAG 12 /* union tag */
+#define C_TPDEF 13 /* type definition */
+#define C_USTATIC 14 /* undefined static */
+#define C_ENTAG 15 /* enumeration tag */
+#define C_MOE 16 /* member of enumeration */
+#define C_REGPARM 17 /* register parameter */
+#define C_FIELD 18 /* bit field */
+#define C_BLOCK 100 /* ".bb" or ".eb" */
+#define C_FCN 101 /* ".bf" or ".ef" */
+#define C_EOS 102 /* end of structure */
+#define C_FILE 103 /* file name */
+#define C_LINE 104 /* line # reformatted as symbol table entry */
+#define C_ALIAS 105 /* duplicate tag */
+#define C_HIDDEN 106 /* ext symbol in dmert public lib */
+
+ /* New storage classes for 80960 */
+
+#define C_SCALL 107 /* Procedure reachable via system call */
+#define C_LEAFPROC 108 /* Leaf procedure, "call" via BAL */
+
+
+/********************** SECTION HEADER **********************/
+
+struct scnhdr {
+ char s_name[8]; /* section name */
+ long s_paddr; /* physical address, aliased s_nlib */
+ long s_vaddr; /* virtual address */
+ long s_size; /* section size */
+ long s_scnptr; /* file ptr to raw data for section */
+ long s_relptr; /* file ptr to relocation */
+ long s_lnnoptr; /* file ptr to line numbers */
+ unsigned short s_nreloc; /* number of relocation entries */
+ unsigned short s_nlnno; /* number of line number entries*/
+ long s_flags; /* flags */
+ unsigned long s_align; /* section alignment */
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+
+/*
+ * s_flags "type"
+ */
+#define STYP_TEXT 0x20 /* section contains text only */
+#define STYP_DATA 0x40 /* section contains data only */
+#define STYP_BSS 0x80 /* section contains bss only */
+
+#define SCNHDR struct scnhdr
+#define SCNHSZ sizeof(SCNHDR)
+
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct lineno{
+ union {
+ long l_symndx; /* function name symbol index, iff l_lnno == 0*/
+ long l_paddr; /* (physical) address of line number */
+ } l_addr;
+ unsigned short l_lnno; /* line number */
+ char padding[2]; /* force alignment */
+};
+
+#define LINENO struct lineno
+#define LINESZ sizeof(LINENO)
+
+
+/********************** SYMBOLS **********************/
+
+#define SYMNMLEN 8 /* # characters in a symbol name */
+#define FILNMLEN 14 /* # characters in a file name */
+#define DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+
+struct syment {
+ union {
+ char _n_name[SYMNMLEN]; /* old COFF version */
+ struct {
+ long _n_zeroes; /* new == 0 */
+ long _n_offset; /* offset into string table */
+ } _n_n;
+ char *_n_nptr[2]; /* allows for overlaying */
+ } _n;
+ long n_value; /* value of symbol */
+ short n_scnum; /* section number */
+ char pad1[2]; /* force alignment */
+ unsigned long n_type; /* type and derived type */
+ char n_sclass; /* storage class */
+ char n_numaux; /* number of aux. entries */
+ char pad2[2]; /* force alignment */
+};
+
+#define n_name _n._n_name
+#define n_zeroes _n._n_n._n_zeroes
+#define n_offset _n._n_n._n_offset
+
+/*
+ * Relocatable symbols have number of the section in which they are defined,
+ * or one of the following:
+ */
+#define N_UNDEF 0 /* undefined symbol */
+#define N_ABS -1 /* value of symbol is absolute */
+#define N_DEBUG -2 /* debugging symbol -- symbol value is meaningless */
+
+/*
+ * Type of a symbol, in low 4 bits of the word
+ */
+#define T_NULL 0
+#define T_VOID 1 /* function argument (only used by compiler) */
+#define T_CHAR 2 /* character */
+#define T_SHORT 3 /* short integer */
+#define T_INT 4 /* integer */
+#define T_LONG 5 /* long integer */
+#define T_FLOAT 6 /* floating point */
+#define T_DOUBLE 7 /* double word */
+#define T_STRUCT 8 /* structure */
+#define T_UNION 9 /* union */
+#define T_ENUM 10 /* enumeration */
+#define T_MOE 11 /* member of enumeration*/
+#define T_UCHAR 12 /* unsigned character */
+#define T_USHORT 13 /* unsigned short */
+#define T_UINT 14 /* unsigned integer */
+#define T_ULONG 15 /* unsigned long */
+#define T_LNGDBL 16 /* long double */
+
+
+/*
+ * derived types
+ */
+#define DT_PTR 1 /* pointer */
+#define DT_FCN 2 /* function */
+#define DT_ARY 3 /* array */
+
+#define N_BTMASK 037
+#define N_TMASK 0140
+#define N_BTSHFT 5
+#define N_TSHIFT 2
+
+#define BTYPE(x) ((x) & N_BTMASK)
+
+
+#define ISPTR(x) (((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
+#define ISFCN(x) (((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
+#define ISARY(x) (((x) & N_TMASK) == (DT_ARY << N_BTSHFT))
+
+#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))
+
+union auxent {
+ struct {
+ long x_tagndx; /* str, un, or enum tag indx */
+ union {
+ struct {
+ unsigned short x_lnno; /* declaration line number */
+ unsigned short x_size; /* str/union/array size */
+ } x_lnsz;
+ long x_fsize; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ long x_lnnoptr; /* ptr to fcn line # */
+ long x_endndx; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ unsigned short x_dimen[DIMNUM];
+ } x_ary;
+ } x_fcnary;
+ unsigned short x_tvndx; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[FILNMLEN];
+ struct {
+ long x_zeroes;
+ long x_offset;
+ } x_n;
+ } x_file;
+
+ struct {
+ long x_scnlen; /* section length */
+ unsigned short x_nreloc; /* # relocation entries */
+ unsigned short x_nlinno; /* # line numbers */
+ } x_scn;
+
+ struct {
+ long x_stdindx;
+ } x_sc;
+
+ struct {
+ unsigned long x_balntry;
+ } x_bal;
+
+ char a[sizeof(struct syment)]; /* force auxent/syment sizes to match */
+};
+
+#define SYMENT struct syment
+#define SYMESZ sizeof(SYMENT)
+#define AUXENT union auxent
+#define AUXESZ sizeof(AUXENT)
+
+#if VAX || I960
+# define _ETEXT "_etext"
+#else
+# define _ETEXT "etext"
+#endif
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+struct reloc {
+ long r_vaddr; /* Virtual address of reference */
+ long r_symndx; /* Index into symbol table */
+ unsigned short r_type; /* Relocation type */
+ char pad[2]; /* Unused */
+};
+
+/* Only values of r_type GNU/960 cares about */
+#define R_RELLONG 17 /* Direct 32-bit relocation */
+#define R_IPRMED 25 /* 24-bit ip-relative relocation */
+#define R_OPTCALL 27 /* 32-bit optimizable call (leafproc/sysproc) */
+
+
+#define RELOC struct reloc
+#define RELSZ sizeof(RELOC)
diff --git a/gdb/nindy-share/env.h b/gdb/nindy-share/env.h
new file mode 100644
index 00000000000..4343d8b4c01
--- /dev/null
+++ b/gdb/nindy-share/env.h
@@ -0,0 +1,12 @@
+/* Copyright 1990, 1991 Free Software Foundation, Inc.
+ *
+ * This code was donated by Intel Corp.
+ *
+ * GNU/960 tool runtime environment
+ */
+
+
+/* Base directory at which GNU/960 tools are assumed to be installed, if
+ * the environment variable G960BASE is not defined.
+ */
+#define DEFAULT_BASE "/usr/local/g960"
diff --git a/gdb/nindy-share/nindy.c b/gdb/nindy-share/nindy.c
new file mode 100644
index 00000000000..77dd734fac2
--- /dev/null
+++ b/gdb/nindy-share/nindy.c
@@ -0,0 +1,1154 @@
+/* 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. */
+
+/* This started out life as code shared between the nindy monitor and
+ GDB. For various reasons, this is no longer true. Eventually, it
+ probably should be merged into remote-nindy.c. */
+
+/******************************************************************************
+ *
+ * NINDY INTERFACE ROUTINES
+ *
+ * The caller of these routines should be aware that:
+ *
+ * (1) ninConnect() should be called to open communications with the
+ * remote NINDY board before any of the other routines are invoked.
+ *
+ * (2) almost all interactions are driven by the host: nindy sends information
+ * in response to host commands.
+ *
+ * (3) the lone exception to (2) is the single character DLE (^P, 0x10).
+ * Receipt of a DLE from NINDY indicates that the application program
+ * running under NINDY has stopped execution and that NINDY is now
+ * available to talk to the host (all other communication received after
+ * the application has been started should be presumed to come from the
+ * application and should be passed on by the host to stdout).
+ *
+ * (4) the reason the application program stopped can be determined with the
+ * ninStopWhy() function. There are three classes of stop reasons:
+ *
+ * (a) the application has terminated execution.
+ * The host should take appropriate action.
+ *
+ * (b) the application had a fault or trace event.
+ * The host should take appropriate action.
+ *
+ * (c) the application wishes to make a service request (srq) of the host;
+ * e.g., to open/close a file, read/write a file, etc. The ninSrq()
+ * function should be called to determine the nature of the request
+ * and process it.
+ */
+
+#include <stdio.h>
+#include "defs.h"
+#include "serial.h"
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY)
+#define HAVE_SGTTY
+#endif
+
+#ifdef HAVE_SGTTY
+#include <sys/ioctl.h>
+#endif
+
+#include <sys/types.h> /* Needed by file.h on Sys V */
+#include <sys/file.h>
+#include <signal.h>
+#include <sys/stat.h>
+
+#if 0
+#include "ttycntl.h"
+#endif
+#include "block_io.h"
+#include "gdb_wait.h"
+#include "env.h"
+
+#define DLE 0x10 /* ^P */
+#define XON 0x11 /* ^Q */
+#define XOFF 0x13 /* ^S */
+#define ESC 0x1b
+
+#define TIMEOUT -1
+
+int quiet = 0; /* 1 => stifle unnecessary messages */
+struct serial *nindy_serial;
+
+static int old_nindy = 0; /* 1 => use old (hex) communication protocol */
+static ninStrGet();
+
+ /****************************
+ * *
+ * MISCELLANEOUS UTILTIES *
+ * *
+ ****************************/
+
+/******************************************************************************
+ * say:
+ * This is a printf that takes at most two arguments (in addition to the
+ * format string) and that outputs nothing if verbose output has been
+ * suppressed.
+ *****************************************************************************/
+
+/* VARARGS */
+static void
+#ifdef ANSI_PROTOTYPES
+say (char *fmt, ...)
+#else
+say (va_alist)
+ va_dcl
+#endif
+{
+ va_list args;
+#ifdef ANSI_PROTOTYPES
+ va_start(args, fmt);
+#else
+ char *fmt;
+
+ va_start (args);
+ fmt = va_arg (args, char *);
+#endif
+
+ if (!quiet)
+ {
+ vfprintf_unfiltered (gdb_stdout, fmt, args);
+ gdb_flush (gdb_stdout);
+ }
+ va_end (args);
+}
+
+/******************************************************************************
+ * exists:
+ * Creates a full pathname by concatenating up to three name components
+ * onto a specified base name; optionally looks up the base name as a
+ * runtime environment variable; and checks to see if the file or
+ * directory specified by the pathname actually exists.
+ *
+ * Returns: the full pathname if it exists, NULL otherwise.
+ * (returned pathname is in malloc'd memory and must be freed
+ * by caller).
+ *****************************************************************************/
+static char *
+exists( base, c1, c2, c3, env )
+ char *base; /* Base directory of path */
+ char *c1, *c2, *c3; /* Components (subdirectories and/or file name) to be
+ * appended onto the base directory name. One or
+ * more may be omitted by passing NULL pointers.
+ */
+ int env; /* If 1, '*base' is the name of an environment variable
+ * to be examined for the base directory name;
+ * otherwise, '*base' is the actual name of the
+ * base directory.
+ */
+{
+ struct stat buf;/* For call to 'stat' -- never examined */
+ char *path; /* Pointer to full pathname (malloc'd memory) */
+ int len; /* Length of full pathname (incl. terminator) */
+ extern char *getenv();
+
+
+ if ( env ){
+ base = getenv( base );
+ if ( base == NULL ){
+ return NULL;
+ }
+ }
+
+ len = strlen(base) + 4;
+ /* +4 for terminator and "/" before each component */
+ if ( c1 != NULL ){
+ len += strlen(c1);
+ }
+ if ( c2 != NULL ){
+ len += strlen(c2);
+ }
+ if ( c3 != NULL ){
+ len += strlen(c3);
+ }
+
+ path = xmalloc (len);
+
+ strcpy( path, base );
+ if ( c1 != NULL ){
+ strcat( path, "/" );
+ strcat( path, c1 );
+ if ( c2 != NULL ){
+ strcat( path, "/" );
+ strcat( path, c2 );
+ if ( c3 != NULL ){
+ strcat( path, "/" );
+ strcat( path, c3 );
+ }
+ }
+ }
+
+ if ( stat(path,&buf) != 0 ){
+ free( path );
+ path = NULL;
+ }
+ return path;
+}
+
+ /*****************************
+ * *
+ * LOW-LEVEL COMMUNICATION *
+ * *
+ *****************************/
+
+/* Read *exactly* N characters from the NINDY tty, and put them in
+ *BUF. Translate escape sequences into single characters, counting
+ each such sequence as 1 character.
+
+ An escape sequence consists of ESC and a following character. The
+ ESC is discarded and the other character gets bit 0x40 cleared --
+ thus ESC P == ^P, ESC S == ^S, ESC [ == ESC, etc.
+
+ Return 1 if successful, 0 if more than TIMEOUT seconds pass without
+ any input. */
+
+static int
+rdnin (buf,n,timeout)
+ unsigned char * buf; /* Where to place characters read */
+ int n; /* Number of characters to read */
+ int timeout; /* Timeout, in seconds */
+{
+ int escape_seen; /* 1 => last character of a read was an ESC */
+ int c;
+
+ escape_seen = 0;
+ while (n)
+ {
+ c = serial_readchar (nindy_serial, timeout);
+ switch (c)
+ {
+ case SERIAL_ERROR:
+ case SERIAL_TIMEOUT:
+ case SERIAL_EOF:
+ return 0;
+
+ case ESC:
+ escape_seen = 1;
+ break;
+
+ default:
+ if (escape_seen)
+ {
+ escape_seen = 0;
+ c &= ~0x40;
+ }
+ *buf++ = c;
+ --n;
+ break;
+ }
+ }
+ return 1;
+}
+
+
+/******************************************************************************
+ * getpkt:
+ * Read a packet from a remote NINDY, with error checking, into the
+ * indicated buffer.
+ *
+ * Return packet status byte on success, TIMEOUT on failure.
+ ******************************************************************************/
+static
+int
+getpkt(buf)
+ unsigned char *buf;
+{
+ int i;
+ unsigned char hdr[3]; /* Packet header:
+ * hdr[0] = low byte of message length
+ * hdr[1] = high byte of message length
+ * hdr[2] = message status
+ */
+ int cnt; /* Message length (status byte + data) */
+ unsigned char cs_calc; /* Checksum calculated */
+ unsigned char cs_recv; /* Checksum received */
+ static char errfmt[] =
+ "Bad checksum (recv=0x%02x; calc=0x%02x); retrying\r\n";
+
+ while (1){
+ if ( !rdnin(hdr,3,5) ){
+ return TIMEOUT;
+ }
+ cnt = (hdr[1]<<8) + hdr[0] - 1;
+ /* -1 for status byte (already read) */
+
+ /* Caller's buffer may only be big enough for message body,
+ * without status byte and checksum, so make sure to read
+ * checksum into a separate buffer.
+ */
+ if ( !rdnin(buf,cnt,5) || !rdnin(&cs_recv,1,5) ){
+ return TIMEOUT;
+ }
+
+ /* Calculate checksum
+ */
+ cs_calc = hdr[0] + hdr[1] + hdr[2];
+ for ( i = 0; i < cnt; i++ ){
+ cs_calc += buf[i];
+ }
+ if ( cs_calc == cs_recv ){
+ serial_write (nindy_serial, "+", 1);
+ return hdr[2];
+ }
+
+ /* Bad checksum: report, send NAK, and re-receive
+ */
+ fprintf(stderr, errfmt, cs_recv, cs_calc );
+ serial_write (nindy_serial, "-", 1);
+ }
+}
+
+
+/******************************************************************************
+ * putpkt:
+ * Send a packet to NINDY, checksumming it and converting special
+ * characters to escape sequences.
+ ******************************************************************************/
+
+/* This macro puts the character 'c' into the buffer pointed at by 'p',
+ * and increments the pointer. If 'c' is one of the 4 special characters
+ * in the transmission protocol, it is converted into a 2-character
+ * escape sequence.
+ */
+#define PUTBUF(c,p) \
+ if ( c == DLE || c == ESC || c == XON || c == XOFF ){ \
+ *p++ = ESC; \
+ *p++ = c | 0x40; \
+ } else { \
+ *p++ = c; \
+ }
+
+static
+putpkt( msg, len )
+ unsigned char *msg; /* Command to be sent, without lead ^P (\020) or checksum */
+ int len; /* Number of bytes in message */
+{
+ static char *buf = NULL;/* Local buffer -- build packet here */
+ static int maxbuf = 0; /* Current length of buffer */
+ unsigned char ack; /* Response received from NINDY */
+ unsigned char checksum; /* Packet checksum */
+ char *p; /* Pointer into buffer */
+ int lenhi, lenlo; /* High and low bytes of message length */
+ int i;
+
+
+ /* Make sure local buffer is big enough. Must include space for
+ * packet length, message body, and checksum. And in the worst
+ * case, each character would expand into a 2-character escape
+ * sequence.
+ */
+ if ( maxbuf < ((2*len)+10) ){
+ if ( buf ){
+ free( buf );
+ }
+ buf = xmalloc( maxbuf=((2*len)+10) );
+ }
+
+ /* Attention, NINDY!
+ */
+ serial_write (nindy_serial, "\020", 1);
+
+
+ lenlo = len & 0xff;
+ lenhi = (len>>8) & 0xff;
+ checksum = lenlo + lenhi;
+ p = buf;
+
+ PUTBUF( lenlo, p );
+ PUTBUF( lenhi, p );
+
+ for ( i=0; i<len; i++ ){
+ PUTBUF( msg[i], p );
+ checksum += msg[i];
+ }
+
+ PUTBUF( checksum, p );
+
+ /* Send checksummed message over and over until we get a positive ack
+ */
+ serial_write (nindy_serial, buf, p - buf);
+ while (1){
+ if ( !rdnin(&ack,1,5) ){
+ /* timed out */
+ fprintf(stderr,"ACK timed out; resending\r\n");
+ /* Attention, NINDY! */
+ serial_write (nindy_serial, "\020", 1);
+ serial_write (nindy_serial, buf, p - buf);
+ } else if ( ack == '+' ){
+ return;
+ } else if ( ack == '-' ){
+ fprintf( stderr, "Remote NAK; resending\r\n" );
+ serial_write (nindy_serial, buf, p - buf);
+ } else {
+ fprintf( stderr, "Bad ACK, ignored: <%c>\r\n", ack );
+ }
+ }
+}
+
+
+
+/******************************************************************************
+ * send:
+ * Send a message to a remote NINDY. Check message status byte
+ * for error responses. If no error, return NINDY reponse (if any).
+ ******************************************************************************/
+static
+send( out, len, in )
+ unsigned char *out; /* Message to be sent to NINDY */
+ int len; /* Number of meaningful bytes in out buffer */
+ unsigned char *in; /* Where to put response received from NINDY */
+{
+ char *fmt;
+ int status;
+ static char *errmsg[] = {
+ "", /* 0 */
+ "Buffer overflow", /* 1 */
+ "Unknown command", /* 2 */
+ "Wrong amount of data to load register(s)", /* 3 */
+ "Missing command argument(s)", /* 4 */
+ "Odd number of digits sent to load memory", /* 5 */
+ "Unknown register name", /* 6 */
+ "No such memory segment", /* 7 */
+ "No breakpoint available", /* 8 */
+ "Can't set requested baud rate", /* 9 */
+ };
+# define NUMERRS ( sizeof(errmsg) / sizeof(errmsg[0]) )
+
+ static char err1[] = "Unknown error response from NINDY: #%d\r\n";
+ static char err2[] = "Error response #%d from NINDY: %s\r\n";
+
+ while (1){
+ putpkt(out,len);
+ status = getpkt(in);
+ if ( status == TIMEOUT ){
+ fprintf( stderr, "Response timed out; resending\r\n" );
+ } else {
+ break;
+ }
+ }
+
+ if ( status ){
+ fmt = status > NUMERRS ? err1 : err2;
+ fprintf( stderr, fmt, status, errmsg[status] );
+ abort();
+ }
+}
+
+ /************************
+ * *
+ * BAUD RATE ROUTINES *
+ * *
+ ************************/
+
+/* Table of baudrates known to be acceptable to NINDY. Each baud rate
+ * appears both as character string and as a Unix baud rate constant.
+ */
+struct baudrate {
+ char *string;
+ int rate;
+};
+
+static struct baudrate baudtab[] = {
+ "1200", 1200,
+ "2400", 2400,
+ "4800", 4800,
+ "9600", 9600,
+ "19200", 19200,
+ "38400", 38400,
+ NULL, 0 /* End of table */
+};
+
+/******************************************************************************
+ * parse_baudrate:
+ * Look up the passed baud rate in the baudrate table. If found, change
+ * our internal record of the current baud rate, but don't do anything
+ * about the tty just now.
+ *
+ * Return pointer to baudrate structure on success, NULL on failure.
+ ******************************************************************************/
+static
+struct baudrate *
+parse_baudrate(s)
+ char *s; /* Desired baud rate, as an ASCII (decimal) string */
+{
+ int i;
+
+ for ( i=0; baudtab[i].string != NULL; i++ ){
+ if ( !strcmp(baudtab[i].string,s) ){
+ return &baudtab[i];
+ }
+ }
+ return NULL;
+}
+
+/******************************************************************************
+ * try_baudrate:
+ * Try speaking to NINDY via the specified file descriptor at the
+ * specified baudrate. Assume success if we can send an empty command
+ * with a bogus checksum and receive a NAK (response of '-') back within
+ * one second.
+ *
+ * Return 1 on success, 0 on failure.
+ ***************************************************************************/
+
+static int
+try_baudrate (serial, brp)
+ struct serial *serial;
+ struct baudrate *brp;
+{
+ unsigned char c;
+
+ /* Set specified baud rate and flush all pending input */
+ serial_setbaudrate (serial, brp->rate);
+ tty_flush (serial);
+
+ /* Send empty command with bad checksum, hope for NAK ('-') response */
+ serial_write (serial, "\020\0\0\001", 4);
+
+ /* Anything but a quick '-', including error, eof, or timeout, means that
+ this baudrate doesn't work. */
+ return serial_readchar (serial, 1) == '-';
+}
+
+/******************************************************************************
+ * autobaud:
+ * Get NINDY talking over the specified file descriptor at the specified
+ * baud rate. First see if NINDY's already talking at 'baudrate'. If
+ * not, run through all the legal baudrates in 'baudtab' until one works,
+ * and then tell NINDY to talk at 'baudrate' instead.
+ ******************************************************************************/
+static
+autobaud( serial, brp )
+ struct serial *serial;
+ struct baudrate *brp;
+{
+ int i;
+ int failures;
+
+ say("NINDY at wrong baud rate? Trying to autobaud...\n");
+ failures = i = 0;
+ while (1)
+ {
+ say( "\r%s... ", baudtab[i].string );
+ if (try_baudrate(serial, &baudtab[i]))
+ {
+ break;
+ }
+ if (baudtab[++i].string == NULL)
+ {
+ /* End of table -- wraparound */
+ i = 0;
+ if ( failures++ )
+ {
+ say("\nAutobaud failed again. Giving up.\n");
+ exit(1);
+ }
+ else
+ {
+ say("\nAutobaud failed. Trying again...\n");
+ }
+ }
+ }
+
+ /* Found NINDY's current baud rate; now change it. */
+ say("Changing NINDY baudrate to %s\n", brp->string);
+ ninBaud (brp->string);
+
+ /* Change our baud rate back to rate to which we just set NINDY. */
+ serial_setbaudrate (serial, brp->rate);
+}
+
+ /**********************************
+ * *
+ * NINDY INTERFACE ROUTINES *
+ * *
+ * ninConnect *MUST* be the first *
+ * one of these routines called. *
+ **********************************/
+
+
+/******************************************************************************
+ * ninBaud:
+ * Ask NINDY to change the baud rate on its serial port.
+ * Assumes we know the baud rate at which NINDY's currently talking.
+ ******************************************************************************/
+ninBaud( baudrate )
+ char *baudrate; /* Desired baud rate, as a string of ASCII decimal
+ * digits.
+ */
+{
+ unsigned char msg[100];
+
+ tty_flush (nindy_serial);
+
+ if (old_nindy)
+ {
+ char *p; /* Pointer into buffer */
+ unsigned char csum; /* Calculated checksum */
+
+ /* Can't use putpkt() because after the baudrate change NINDY's
+ ack/nak will look like gibberish. */
+
+ for (p=baudrate, csum=020+'z'; *p; p++)
+ {
+ csum += *p;
+ }
+ sprintf (msg, "\020z%s#%02x", baudrate, csum);
+ serial_write (nindy_serial, msg, strlen (msg));
+ }
+ else
+ {
+ /* Can't use "send" because NINDY reply will be unreadable after
+ baud rate change. */
+ sprintf( msg, "z%s", baudrate );
+ putpkt( msg, strlen(msg)+1 ); /* "+1" to send terminator too */
+ }
+}
+
+/******************************************************************************
+ * ninBptDel:
+ * Ask NINDY to delete the specified type of *hardware* breakpoint at
+ * the specified address. If the 'addr' is -1, all breakpoints of
+ * the specified type are deleted.
+ ***************************************************************************/
+ninBptDel( addr, type )
+ long addr; /* Address in 960 memory */
+ char type; /* 'd' => data bkpt, 'i' => instruction breakpoint */
+{
+ unsigned char buf[10];
+
+ if ( old_nindy ){
+ OninBptDel( addr, type == 'd' ? 1 : 0 );
+ return;
+ }
+
+ buf[0] = 'b';
+ buf[1] = type;
+
+ if ( addr == -1 ){
+ send( buf, 2, NULL );
+ } else {
+ store_unsigned_integer (&buf[2], 4, addr);
+ send( buf, 6, NULL );
+ }
+}
+
+
+/******************************************************************************
+ * ninBptSet:
+ * Ask NINDY to set the specified type of *hardware* breakpoint at
+ * the specified address.
+ ******************************************************************************/
+ninBptSet( addr, type )
+ long addr; /* Address in 960 memory */
+ char type; /* 'd' => data bkpt, 'i' => instruction breakpoint */
+{
+ unsigned char buf[10];
+
+ if ( old_nindy ){
+ OninBptSet( addr, type == 'd' ? 1 : 0 );
+ return;
+ }
+
+
+ buf[0] = 'B';
+ buf[1] = type;
+ store_unsigned_integer (&buf[2], 4, addr);
+ send( buf, 6, NULL );
+}
+
+
+/******************************************************************************
+ * ninConnect:
+ * Open the specified tty. Get communications working at the specified
+ * baud rate. Flush any pending I/O on the tty.
+ *
+ * Return the file descriptor, or -1 on failure.
+ ******************************************************************************/
+int
+ninConnect( name, baudrate, brk, silent, old_protocol )
+ char *name; /* "/dev/ttyXX" to be opened */
+ char *baudrate;/* baud rate: a string of ascii decimal digits (eg,"9600")*/
+ int brk; /* 1 => send break to tty first thing after opening it*/
+ int silent; /* 1 => stifle unnecessary messages when talking to
+ * this tty.
+ */
+ int old_protocol;
+{
+ int i;
+ char *p;
+ struct baudrate *brp;
+
+ /* We will try each of the following paths when trying to open the tty
+ */
+ static char *prefix[] = { "", "/dev/", "/dev/tty", NULL };
+
+ if ( old_protocol ){
+ old_nindy = 1;
+ }
+
+ quiet = silent; /* Make global to this file */
+
+ for ( i=0; prefix[i] != NULL; i++ ){
+ p = xmalloc(strlen(prefix[i]) + strlen(name) + 1 );
+ strcpy( p, prefix[i] );
+ strcat( p, name );
+ nindy_serial = serial_open (p);
+ if (nindy_serial != NULL) {
+#ifdef TIOCEXCL
+ /* Exclusive use mode (hp9000 does not support it) */
+ ioctl(nindy_serial->fd,TIOCEXCL,NULL);
+#endif
+ serial_raw (nindy_serial);
+
+ if (brk)
+ {
+ serial_send_break (nindy_serial);
+ }
+
+ brp = parse_baudrate( baudrate );
+ if ( brp == NULL ){
+ say("Illegal baudrate %s ignored; using 9600\n",
+ baudrate);
+ brp = parse_baudrate( "9600" );
+ }
+
+ if ( !try_baudrate(nindy_serial, brp) ){
+ autobaud(nindy_serial, brp);
+ }
+ tty_flush (nindy_serial);
+ say( "Connected to %s\n", p );
+ free(p);
+ break;
+ }
+ free(p);
+ }
+ return 0;
+}
+
+#if 0
+
+/* Currently unused; shouldn't we be doing this on target_kill and
+perhaps target_mourn? FIXME. */
+
+/******************************************************************************
+ * ninGdbExit:
+ * Ask NINDY to leave GDB mode and print a NINDY prompt.
+ ****************************************************************************/
+ninGdbExit()
+{
+ if ( old_nindy ){
+ OninGdbExit();
+ return;
+ }
+ putpkt((unsigned char *) "E", 1 );
+}
+#endif
+
+/******************************************************************************
+ * ninGo:
+ * Ask NINDY to start or continue execution of an application program
+ * in it's memory at the current ip.
+ ******************************************************************************/
+ninGo( step_flag )
+ int step_flag; /* 1 => run in single-step mode */
+{
+ if ( old_nindy ){
+ OninGo( step_flag );
+ return;
+ }
+ putpkt((unsigned char *) (step_flag ? "s" : "c"), 1 );
+}
+
+
+/******************************************************************************
+ * ninMemGet:
+ * Read a string of bytes from NINDY's address space (960 memory).
+ ******************************************************************************/
+int
+ninMemGet(ninaddr, hostaddr, len)
+ long ninaddr; /* Source address, in the 960 memory space */
+ unsigned char *hostaddr; /* Destination address, in our memory space */
+ int len; /* Number of bytes to read */
+{
+ unsigned char buf[BUFSIZE+20];
+ int cnt; /* Number of bytes in next transfer */
+ int origlen = len;
+
+ if ( old_nindy ){
+ OninMemGet(ninaddr, hostaddr, len);
+ return;
+ }
+
+ for ( ; len > 0; len -= BUFSIZE ){
+ cnt = len > BUFSIZE ? BUFSIZE : len;
+
+ buf[0] = 'm';
+ store_unsigned_integer (&buf[1], 4, ninaddr);
+ buf[5] = cnt & 0xff;
+ buf[6] = (cnt>>8) & 0xff;
+
+ send( buf, 7, hostaddr );
+
+ ninaddr += cnt;
+ hostaddr += cnt;
+ }
+ return origlen;
+}
+
+
+/******************************************************************************
+ * ninMemPut:
+ * Write a string of bytes into NINDY's address space (960 memory).
+ ******************************************************************************/
+int
+ninMemPut( ninaddr, hostaddr, len )
+ long ninaddr; /* Destination address, in NINDY memory space */
+ unsigned char *hostaddr; /* Source address, in our memory space */
+ int len; /* Number of bytes to write */
+{
+ unsigned char buf[BUFSIZE+20];
+ int cnt; /* Number of bytes in next transfer */
+ int origlen = len;
+
+ if ( old_nindy ){
+ OninMemPut( ninaddr, hostaddr, len );
+ return;
+ }
+ for ( ; len > 0; len -= BUFSIZE ){
+ cnt = len > BUFSIZE ? BUFSIZE : len;
+
+ buf[0] = 'M';
+ store_unsigned_integer (&buf[1], 4, ninaddr);
+ memcpy(buf + 5, hostaddr, cnt);
+ send( buf, cnt+5, NULL );
+
+ ninaddr += cnt;
+ hostaddr += cnt;
+ }
+ return origlen;
+}
+
+/******************************************************************************
+ * ninRegGet:
+ * Retrieve the contents of a 960 register, and return them as a long
+ * in host byte order.
+ *
+ * THIS ROUTINE CAN ONLY BE USED TO READ THE LOCAL, GLOBAL, AND
+ * ip/ac/pc/tc REGISTERS.
+ *
+ ******************************************************************************/
+long
+ninRegGet( regname )
+ char *regname; /* Register name recognized by NINDY, subject to the
+ * above limitations.
+ */
+{
+ unsigned char outbuf[10];
+ unsigned char inbuf[20];
+
+ if ( old_nindy ){
+ return OninRegGet( regname );
+ }
+
+ sprintf( outbuf, "u%s:", regname );
+ send( outbuf, strlen(outbuf), inbuf );
+ return extract_unsigned_integer (inbuf, 4);
+}
+
+/******************************************************************************
+ * ninRegPut:
+ * Set the contents of a 960 register.
+ *
+ * THIS ROUTINE CAN ONLY BE USED TO SET THE LOCAL, GLOBAL, AND
+ * ip/ac/pc/tc REGISTERS.
+ *
+ ******************************************************************************/
+ninRegPut( regname, val )
+ char *regname; /* Register name recognized by NINDY, subject to the
+ * above limitations.
+ */
+ long val; /* New contents of register, in host byte-order */
+{
+ unsigned char buf[20];
+ int len;
+
+ if ( old_nindy ){
+ OninRegPut( regname, val );
+ return;
+ }
+
+ sprintf( buf, "U%s:", regname );
+ len = strlen(buf);
+ store_unsigned_integer (&buf[len], 4, val);
+ send( buf, len+4, NULL );
+}
+
+/******************************************************************************
+ * ninRegsGet:
+ * Get a dump of the contents of the entire 960 register set. The
+ * individual registers appear in the dump in the following order:
+ *
+ * pfp sp rip r3 r4 r5 r6 r7
+ * r8 r9 r10 r11 r12 r13 r14 r15
+ * g0 g1 g2 g3 g4 g5 g6 g7
+ * g8 g9 g10 g11 g12 g13 g14 fp
+ * pc ac ip tc fp0 fp1 fp2 fp3
+ *
+ * Each individual register comprises exactly 4 bytes, except for
+ * fp0-fp3, which are 8 bytes. All register values are in 960
+ * (little-endian) byte order.
+ *
+ ******************************************************************************/
+ninRegsGet( regp )
+ unsigned char *regp; /* Where to place the register dump */
+{
+ if ( old_nindy ){
+ OninRegsGet( regp );
+ return;
+ }
+ send( (unsigned char *) "r", 1, regp );
+}
+
+
+/******************************************************************************
+ * ninRegsPut:
+ * Initialize the entire 960 register set to a specified set of values.
+ * The format of the register value data should be the same as that
+ * returned by ninRegsGet.
+ *
+ * WARNING:
+ * All register values must be in 960 (little-endian) byte order.
+ *
+ ******************************************************************************/
+ninRegsPut( regp )
+ char *regp; /* Pointer to desired values of registers */
+{
+/* Number of bytes that we send to nindy. I believe this is defined by
+ the protocol (it does not agree with REGISTER_BYTES). */
+#define NINDY_REGISTER_BYTES ((36*4) + (4*8))
+ unsigned char buf[NINDY_REGISTER_BYTES+10];
+
+ if ( old_nindy ){
+ OninRegsPut( regp );
+ return;
+ }
+
+ buf[0] = 'R';
+ memcpy(buf+1, regp, NINDY_REGISTER_BYTES );
+ send( buf, NINDY_REGISTER_BYTES+1, NULL );
+}
+
+
+/******************************************************************************
+ * ninReset:
+ * Ask NINDY to perform a soft reset; wait for the reset to complete.
+ *
+ ******************************************************************************/
+ninReset()
+{
+ unsigned char ack;
+
+ if ( old_nindy ){
+ OninReset();
+ return;
+ }
+
+ while (1){
+ putpkt((unsigned char *) "X", 1 );
+ while (1){
+ if ( !rdnin(&ack,1,5) ){
+ /* Timed out */
+ break; /* Resend */
+ }
+ if ( ack == '+' ){
+ return;
+ }
+ }
+ }
+}
+
+
+/******************************************************************************
+ * ninSrq:
+ * Assume NINDY has stopped execution of the 960 application program in
+ * order to process a host service request (srq). Ask NINDY for the
+ * srq arguments, perform the requested service, and send an "srq
+ * complete" message so NINDY will return control to the application.
+ *
+ ******************************************************************************/
+ninSrq()
+{
+ /* FIXME: Imposes arbitrary limits on lengths of pathnames and such. */
+ unsigned char buf[BUFSIZE];
+ int retcode;
+ unsigned char srqnum;
+ int i;
+ int offset;
+ int arg[MAX_SRQ_ARGS];
+
+ if ( old_nindy ){
+ OninSrq();
+ return;
+ }
+
+
+ /* Get srq number and arguments
+ */
+ send((unsigned char *) "!", 1, buf );
+
+ srqnum = buf[0];
+ for ( i=0, offset=1; i < MAX_SRQ_ARGS; i++, offset+=4 ){
+ arg[i] = extract_unsigned_integer (&buf[offset], 4);
+ }
+
+ /* Process Srq
+ */
+ switch( srqnum ){
+ case BS_CLOSE:
+ /* args: file descriptor */
+ if ( arg[0] > 2 ){
+ retcode = close( arg[0] );
+ } else {
+ retcode = 0;
+ }
+ break;
+ case BS_CREAT:
+ /* args: filename, mode */
+ ninStrGet( arg[0], buf );
+ retcode = creat(buf,arg[1]);
+ break;
+ case BS_OPEN:
+ /* args: filename, flags, mode */
+ ninStrGet( arg[0], buf );
+ retcode = open(buf,arg[1],arg[2]);
+ break;
+ case BS_READ:
+ /* args: file descriptor, buffer, count */
+ retcode = read(arg[0],buf,arg[2]);
+ if ( retcode > 0 ){
+ ninMemPut( arg[1], buf, retcode );
+ }
+ break;
+ case BS_SEEK:
+ /* args: file descriptor, offset, whence */
+ retcode = lseek(arg[0],arg[1],arg[2]);
+ break;
+ case BS_WRITE:
+ /* args: file descriptor, buffer, count */
+ ninMemGet( arg[1], buf, arg[2] );
+ retcode = write(arg[0],buf,arg[2]);
+ break;
+ default:
+ retcode = -1;
+ break;
+ }
+
+ /* Send request termination status to NINDY
+ */
+ buf[0] = 'e';
+ store_unsigned_integer (&buf[1], 4, retcode);
+ send( buf, 5, NULL );
+}
+
+
+/******************************************************************************
+ * ninStopWhy:
+ * Assume the application program has stopped (i.e., a DLE was received
+ * from NINDY). Ask NINDY for status information describing the
+ * reason for the halt.
+ *
+ * Returns a non-zero value if the user program has exited, 0 otherwise.
+ * Also returns the following information, through passed pointers:
+ * - why: an exit code if program the exited; otherwise the reason
+ * why the program halted (see stop.h for values).
+ * - contents of register ip (little-endian byte order)
+ * - contents of register sp (little-endian byte order)
+ * - contents of register fp (little-endian byte order)
+ ******************************************************************************/
+char
+ninStopWhy( whyp, ipp, fpp, spp )
+ unsigned char *whyp; /* Return the 'why' code through this pointer */
+ long *ipp; /* Return contents of register ip through this pointer */
+ long *fpp; /* Return contents of register fp through this pointer */
+ long *spp; /* Return contents of register sp through this pointer */
+{
+ unsigned char buf[30];
+ extern char OninStopWhy ();
+
+ if ( old_nindy ){
+ return OninStopWhy( whyp, ipp, fpp, spp );
+ }
+ send((unsigned char *) "?", 1, buf );
+
+ *whyp = buf[1];
+ memcpy ((char *)ipp, &buf[2], sizeof (*ipp));
+ memcpy ((char *)fpp, &buf[6], sizeof (*ipp));
+ memcpy ((char *)spp, &buf[10], sizeof (*ipp));
+ return buf[0];
+}
+
+/******************************************************************************
+ * ninStrGet:
+ * Read a '\0'-terminated string of data out of the 960 memory space.
+ *
+ ******************************************************************************/
+static
+ninStrGet( ninaddr, hostaddr )
+ unsigned long ninaddr; /* Address of string in NINDY memory space */
+ unsigned char *hostaddr; /* Address of the buffer to which string should
+ * be copied.
+ */
+{
+ unsigned char cmd[5];
+
+ cmd[0] = '"';
+ store_unsigned_integer (&cmd[1], 4, ninaddr);
+ send( cmd, 5, hostaddr );
+}
+
+#if 0
+/* Not used. */
+
+/******************************************************************************
+ * ninVersion:
+ * Ask NINDY for version information about itself.
+ * The information is sent as an ascii string in the form "x.xx,<arch>",
+ * where,
+ * x.xx is the version number
+ * <arch> is the processor architecture: "KA", "KB", "MC", "CA" *
+ *
+ ******************************************************************************/
+int
+ninVersion( p )
+ unsigned char *p; /* Where to place version string */
+{
+
+ if ( old_nindy ){
+ return OninVersion( p );
+ }
+ send((unsigned char *) "v", 1, p );
+ return strlen(p);
+}
+#endif /* 0 */
diff --git a/gdb/nindy-share/stop.h b/gdb/nindy-share/stop.h
new file mode 100644
index 00000000000..82a90a54840
--- /dev/null
+++ b/gdb/nindy-share/stop.h
@@ -0,0 +1,86 @@
+/******************************************************************
+ Copyright 1990, 1992 Free Software Foundation, Inc.
+
+ This code was donated by Intel Corp.
+
+ Intel hereby grants you permission to copy, modify, and
+ distribute this software and its documentation. Intel grants
+ this permission provided that the above copyright notice
+ appears in all copies and that both the copyright notice and
+ this permission notice appear in supporting documentation. In
+ addition, Intel grants this permission provided that you
+ prominently mark as not part of the original any modifications
+ made to this software or documentation, and that the name of
+ Intel Corporation not be used in advertising or publicity
+ pertaining to distribution of the software or the documentation
+ without specific, written prior permission.
+
+ Intel Corporation does not warrant, guarantee or make any
+ representations regarding the use of, or the results of the use
+ of, the software and documentation in terms of correctness,
+ accuracy, reliability, currentness, or otherwise; and you rely
+ on the software, documentation and results solely at your own
+ risk. */
+/******************************************************************/
+
+
+/******************************************************************
+ *
+ * REASONS WHY NINDY CAN STOP EXECUTING AN APPLICATION PROGRAM
+ *
+ * When NINDY stops executing an application program that was running
+ * under remote host ("gdb") control, it signals the host by sending
+ * a single ^P. The host can then query as to the reason for the halt.
+ * NINDY responds with two bytes of information.
+ *
+ * The first byte is a boolean flag that indicates whether or not
+ * the application has exited.
+ *
+ * If the flag is true, the second byte contains the exit code.
+ *
+ * If the flag is false, the second byte contains a "reason for
+ * stopping" code. This file defines the possible values of that
+ * code.
+ *
+ * There are three categories of reasons why the halt may have occurred:
+ * faults, traces, and software interactions. The first two categories
+ * are processor-dependent; the values of these codes are tightly coupled
+ * to the hardware and should not be changed without first examining
+ * src/nindy/common/fault.c. The software interactions involve
+ * communication between NINDY and the host debugger; their codes are
+ * arbitrary.
+ *
+ ******************************************************************/
+
+#define FAULT_PARALLEL 0x00
+#define FAULT_UNKNOWN 0x01
+#define FAULT_OPERATION 0x02
+#define FAULT_ARITH 0x03
+#define FAULT_FP 0x04
+#define FAULT_CONSTR 0x05
+#define FAULT_VM 0x06
+#define FAULT_PROTECT 0x07
+#define FAULT_MACHINE 0x08
+#define FAULT_STRUCT 0x09
+#define FAULT_TYPE 0x0a
+ /* 0x0b reserved */
+#define FAULT_PROCESS 0x0c
+#define FAULT_DESC 0x0d
+#define FAULT_EVENT 0x0e
+ /* 0x0f reserved */
+
+#define LAST_FAULT 0x0f
+
+#define TRACE_STEP 0x10
+#define TRACE_BRANCH 0x11
+#define TRACE_CALL 0x12
+#define TRACE_RET 0x13
+#define TRACE_PRERET 0x14
+#define TRACE_SVC 0x15
+#define TRACE_BKPT 0x16
+
+#define STOP_SRQ 0xfe
+ /* Application program has service request to make of host */
+
+#define STOP_GDB_BPT 0xff
+ /* Application program has reached breakpoint (fmark) set by host */
diff --git a/gdb/nindy-share/ttyflush.c b/gdb/nindy-share/ttyflush.c
new file mode 100644
index 00000000000..f9aaa2edf4f
--- /dev/null
+++ b/gdb/nindy-share/ttyflush.c
@@ -0,0 +1,48 @@
+/* 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. */
+
+/* This started out life as code shared between the nindy monitor and
+ GDB. For various reasons, this is no longer true. Eventually, it
+ probably should be merged into remote-nindy.c. */
+
+#include <stdio.h>
+#include "defs.h"
+#include "serial.h"
+
+/* Flush all pending input and output for SERIAL, wait for a second, and
+ then if there is a character pending, discard it and flush again. */
+
+int
+tty_flush (serial)
+ struct serial *serial;
+{
+ while (1)
+ {
+ serial_flush_input (serial);
+ serial_flush_output (serial);
+ sleep(1);
+ switch (serial_readchar (serial, 0))
+ {
+ case SERIAL_TIMEOUT:
+ case SERIAL_ERROR:
+ case SERIAL_EOF:
+ return 0;
+ default:
+ /* We read something. Eeek. Try again. */
+ break;
+ }
+ }
+}
diff --git a/gdb/nindy-tdep.c b/gdb/nindy-tdep.c
new file mode 100644
index 00000000000..1f35062e2bd
--- /dev/null
+++ b/gdb/nindy-tdep.c
@@ -0,0 +1,78 @@
+/* Target-machine dependent code for the NINDY monitor running on the Intel 960
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 2000
+ Free Software Foundation, Inc.
+ Contributed by Intel Corporation.
+
+ 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. */
+
+/* Miscellaneous NINDY-dependent routines.
+ Some replace macros normally defined in "tm.h". */
+
+#include "defs.h"
+#include "symtab.h"
+#include "frame.h"
+#include "gdbcore.h"
+
+/* 'start_frame' is a variable in the NINDY runtime startup routine
+ that contains the frame pointer of the 'start' routine (the routine
+ that calls 'main'). By reading its contents out of remote memory,
+ we can tell where the frame chain ends: backtraces should halt before
+ they display this frame. */
+
+int
+nindy_frame_chain_valid (CORE_ADDR chain, struct frame_info *curframe)
+{
+ struct symbol *sym;
+ struct minimal_symbol *msymbol;
+
+ /* crtnindy.o is an assembler module that is assumed to be linked
+ * first in an i80960 executable. It contains the true entry point;
+ * it performs startup up initialization and then calls 'main'.
+ *
+ * 'sf' is the name of a variable in crtnindy.o that is set
+ * during startup to the address of the first frame.
+ *
+ * 'a' is the address of that variable in 80960 memory.
+ */
+ static char sf[] = "start_frame";
+ CORE_ADDR a;
+
+
+ chain &= ~0x3f; /* Zero low 6 bits because previous frame pointers
+ contain return status info in them. */
+ if (chain == 0)
+ {
+ return 0;
+ }
+
+ sym = lookup_symbol (sf, 0, VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ if (sym != 0)
+ {
+ a = SYMBOL_VALUE (sym);
+ }
+ else
+ {
+ msymbol = lookup_minimal_symbol (sf, NULL, NULL);
+ if (msymbol == NULL)
+ return 0;
+ a = SYMBOL_VALUE_ADDRESS (msymbol);
+ }
+
+ return (chain != read_memory_integer (a, 4));
+}
diff --git a/gdb/nlm/Makefile.in b/gdb/nlm/Makefile.in
new file mode 100644
index 00000000000..6b3cf8c9ddf
--- /dev/null
+++ b/gdb/nlm/Makefile.in
@@ -0,0 +1,176 @@
+#Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999
+#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.
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+host_alias = @host_alias@
+target_alias = @target_alias@
+program_transform_name = @program_transform_name@
+bindir = @bindir@
+libdir = @libdir@
+tooldir = $(libdir)/$(target_alias)
+
+datadir = @datadir@
+mandir = @mandir@
+man1dir = $(mandir)/man1
+man2dir = $(mandir)/man2
+man3dir = $(mandir)/man3
+man4dir = $(mandir)/man4
+man5dir = $(mandir)/man5
+man6dir = $(mandir)/man6
+man7dir = $(mandir)/man7
+man8dir = $(mandir)/man8
+man9dir = $(mandir)/man9
+infodir = @infodir@
+htmldir = $(prefix)/html
+includedir = @includedir@
+
+SHELL = @SHELL@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+CC_FOR_TARGET = ` \
+ if [ -f ../../gcc/xgcc ] ; then \
+ echo ../../gcc/xgcc -B../../gcc/; \
+ else \
+ t='$(program_transform_name)'; echo gcc | sed -e '' $$t; \
+ fi`
+
+NLMCONV_FOR_TARGET = ` \
+ if [ -f ../../binutils/nlmconv ] ; then \
+ echo ../../binutils/nlmconv; \
+ else \
+ t='$(program_transform_name)'; echo nlmconv | sed -e '' $$t; \
+ fi`
+
+# All the includes used for CFLAGS and for lint.
+INCLUDE_CFLAGS = -I. -I${srcdir}
+
+# CFLAGS is specifically reserved for setting from the command line
+# when running make. I.E. "make CFLAGS=-Wmissing-prototypes".
+CFLAGS = -g
+# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
+INTERNAL_CFLAGS = ${CFLAGS} ${INCLUDE_CFLAGS} ${USER_CFLAGS}
+LDFLAGS = $(CFLAGS)
+
+# Perhaps should come from parent Makefile
+VERSION = gdbserve-4.12
+DIST=gdb
+
+# target-dependent makefile fragment come in here.
+@target_makefile_frag@
+# End target-dependent makefile fragment
+
+# All source files that go into linking GDB remote server.
+
+DEPFILES = $(GDBSERVE_DEPFILES)
+
+SOURCES = $(ALLDEPFILES)
+TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
+
+# Prevent Sun make from putting in the machine type. Setting
+# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1.
+.c.o:
+ ${CC_FOR_TARGET} -c ${INTERNAL_CFLAGS} $<
+
+.S.o:
+ ${CC_FOR_TARGET} -c ${INTERNAL_CFLAGS} $<
+
+all: gdbserve.nlm
+
+# Traditionally "install" depends on "all". But it may be useful
+# not to; for example, if the user has made some trivial change to a
+# source file and doesn't care about rebuilding or just wants to save the
+# time it takes for make to check that all is up to date.
+# install-only is intended to address that need.
+install: all install-only
+install-only:
+ $(INSTALL) gdbserve.nlm $(bindir)/gdbserve.nlm
+
+uninstall: force
+ rm -f $(bindir)/gdbserve.nlm
+
+installcheck:
+check:
+info dvi:
+install-info:
+clean-info:
+html:
+install-html:
+
+gdbserve.nlm: gdbserve.O $(srcdir)/gdbserve.def
+ ${NLMCONV_FOR_TARGET} -T $(srcdir)/gdbserve.def
+
+gdbserve.O: prelude.o gdbserve.o $(TDEPFILES)
+ ${CC_FOR_TARGET} $(LDFLAGS) -r -o gdbserve.O prelude.o gdbserve.o ${TDEPFILES}
+
+# Put the proper machine-specific files first, so M-. on a machine
+# specific routine gets the one for the correct machine.
+# The xyzzy stuff below deals with empty DEPFILES
+TAGS: ${TAGFILES}
+ etags `find ${srcdir}/../config -name $(TM_FILE) -print` \
+ `find ${srcdir}/../config -name ${XM_FILE} -print` \
+ `find ${srcdir}/../config -name ${NAT_FILE} -print` \
+ `for i in yzzy ${DEPFILES}; do \
+ if [ x$$i != xyzzy ]; then \
+ echo ${srcdir}/$$i | sed -e 's/\.o$$/\.c/' ; \
+ fi; \
+ done` \
+ ${TAGFILES}
+tags: TAGS
+
+clean:
+ rm -f *.o ${ADD_FILES} *~
+ rm -f gdbserve.O gdbserve.nlm core make.log
+
+distclean: clean TAGS
+ rm -f config.log config.cache config.status
+ rm -f Makefile
+
+maintainer-clean realclean: clean
+ rm -f TAGS
+ rm -f config.log config.cache config.status
+ rm -f Makefile
+
+Makefile: Makefile.in config.status @target_makefile_frag_path@
+ $(SHELL) config.status
+
+config.status: configure
+ $(SHELL) config.status --recheck
+
+force:
+
+# GNU Make has an annoying habit of putting *all* the Makefile variables
+# into the environment, unless you include this target as a circumvention.
+# Rumor is that this will be fixed (and this target can be removed)
+# in GNU Make 4.0.
+.NOEXPORT:
+
+# GNU Make 3.63 has a different problem: it keeps tacking command line
+# overrides onto the definition of $(MAKE). This variable setting
+# will remove them.
+MAKEOVERRIDES=
+
+# This is the end of "Makefile.in".
diff --git a/gdb/nlm/configure b/gdb/nlm/configure
new file mode 100755
index 00000000000..3918fee794c
--- /dev/null
+++ b/gdb/nlm/configure
@@ -0,0 +1,1074 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.2
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.2"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=gdbserve.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../.. $srcdir/`cd $srcdir;pwd`/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../.. $srcdir/`cd $srcdir;pwd`/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:573: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:594: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:612: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:666: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ 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
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+# Map target cpu into the config cpu subdirectory name.
+# The default is $target_cpu.
+case "${target_cpu}" in
+alpha) gdb_target_cpu=alpha ;;
+c[12]) gdb_target_cpu=convex ;;
+hppa*) gdb_target_cpu=pa ;;
+i[3456]86) gdb_target_cpu=i386 ;;
+m68*) gdb_target_cpu=m68k ;;
+np1) gdb_target_cpu=gould ;;
+pn) gdb_target_cpu=gould ;;
+pyramid) gdb_target_cpu=pyr ;;
+sparc*) gdb_target_cpu=sparc ;;
+*) gdb_target_cpu=$target_cpu ;;
+esac
+
+target_makefile_frag=${srcdir}/../config/${gdb_target_cpu}/gdbserve.mt
+if ! -f ${target_makefile_frag} ; then
+ { echo "configure: error: "*** GDBSERVE does not support target ${target}"" 1>&2; exit 1; }
+fi
+
+target_makefile_frag_path=$target_makefile_frag
+
+
+
+cpufile=`sed -n '
+s/CPU_FILE *= *\(^ *\)/\1/p
+' ${target_makefile_frag}
+
+files=
+links=
+rm -f cpu.h
+if "${cpufile}" != "" ; then
+ files="${files} ${cpufile}.h"
+ links="${links} cpu.h"
+fi
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.12.2"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@target_makefile_frag_path@%$target_makefile_frag_path%g
+/@target_makefile_frag@/r $target_makefile_frag
+s%@target_makefile_frag@%%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+ac_sources="$files"
+ac_dests="$links"
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+srcdir=$ac_given_srcdir
+while test -n "$ac_sources"; do
+ set $ac_dests; ac_dest=$1; shift; ac_dests=$*
+ set $ac_sources; ac_source=$1; shift; ac_sources=$*
+
+ echo "linking $srcdir/$ac_source to $ac_dest"
+
+ if test ! -r $srcdir/$ac_source; then
+ { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; }
+ fi
+ rm -f $ac_dest
+
+ # Make relative symlinks.
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then
+ # The dest file is in a subdirectory.
+ test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir"
+ ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dest_dir_suffix.
+ ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dest_dir_suffix= ac_dots=
+ fi
+
+ case "$srcdir" in
+ [/$]*) ac_rel_source="$srcdir/$ac_source" ;;
+ *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;;
+ esac
+
+ # Make a symlink if possible; otherwise try a hard link.
+ if ln -s $ac_rel_source $ac_dest 2>/dev/null ||
+ ln $srcdir/$ac_source $ac_dest; then :
+ else
+ { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; }
+ fi
+done
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+
diff --git a/gdb/nlm/configure.in b/gdb/nlm/configure.in
new file mode 100644
index 00000000000..845b486e524
--- /dev/null
+++ b/gdb/nlm/configure.in
@@ -0,0 +1,55 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.12.1)dnl
+AC_INIT(gdbserve.c)
+
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../..)
+AC_CANONICAL_SYSTEM
+AC_ARG_PROGRAM
+
+AC_PROG_INSTALL
+
+# Map target cpu into the config cpu subdirectory name.
+# The default is $target_cpu.
+changequote(,)dnl
+case "${target_cpu}" in
+alpha) gdb_target_cpu=alpha ;;
+c[12]) gdb_target_cpu=convex ;;
+hppa*) gdb_target_cpu=pa ;;
+i[3456]86) gdb_target_cpu=i386 ;;
+m68*) gdb_target_cpu=m68k ;;
+np1) gdb_target_cpu=gould ;;
+pn) gdb_target_cpu=gould ;;
+pyramid) gdb_target_cpu=pyr ;;
+sparc*) gdb_target_cpu=sparc ;;
+*) gdb_target_cpu=$target_cpu ;;
+esac
+changequote([,])dnl
+
+target_makefile_frag=${srcdir}/../config/${gdb_target_cpu}/gdbserve.mt
+if [ ! -f ${target_makefile_frag} ]; then
+ AC_MSG_ERROR("*** GDBSERVE does not support target ${target}")
+fi
+
+dnl We have to assign the same value to other variables because autoconf
+dnl doesn't provide a mechanism to substitute a replacement keyword with
+dnl arbitrary data or pathnames.
+dnl
+target_makefile_frag_path=$target_makefile_frag
+AC_SUBST(target_makefile_frag_path)
+AC_SUBST_FILE(target_makefile_frag)
+
+cpufile=`sed -n '
+s/CPU_FILE[ ]*=[ ]*\([^ ]*\)/\1/p
+' ${target_makefile_frag}
+
+files=
+links=
+rm -f cpu.h
+if [ "${cpufile}" != "" ]; then
+ files="${files} ${cpufile}.h"
+ links="${links} cpu.h"
+fi
+
+AC_LINK_FILES($files, $links)
+AC_OUTPUT(Makefile)
+
diff --git a/gdb/nlm/gdbserve.c b/gdb/nlm/gdbserve.c
new file mode 100644
index 00000000000..990a3f9ebd4
--- /dev/null
+++ b/gdb/nlm/gdbserve.c
@@ -0,0 +1,1033 @@
+/* gdbserve.c -- NLM debugging stub for Novell NetWare.
+
+ This is originally based on an m68k software stub written by Glenn
+ Engel at HP, but has changed quite a bit. It was modified for the
+ i386 by Jim Kingdon, Cygnus Support. It was modified to run under
+ NetWare by Ian Lance Taylor, Cygnus Support.
+
+ This code is intended to produce an NLM (a NetWare Loadable Module)
+ to run under Novell NetWare. To create the NLM, compile this code
+ into an object file using the NLM SDK on any i386 host, and use the
+ nlmconv program (available in the GNU binutils) to transform the
+ resulting object file into an NLM. */
+
+/****************************************************************************
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ HP offers the following for use in the public domain. HP makes no
+ warranty with regard to the software or it's performance and the
+ user accepts the software "AS IS" with all faults.
+
+ HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+ TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ *
+ * The following gdb commands are supported:
+ *
+ * command function Return value
+ *
+ * g return the value of the CPU registers hex data or ENN
+ * G set the value of the CPU registers OK or ENN
+ *
+ * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
+ * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
+ *
+ * c Resume at current address SNN ( signal NN)
+ * cAA..AA Continue at address AA..AA SNN
+ *
+ * s Step one instruction SNN
+ * sAA..AA Step one instruction from AA..AA SNN
+ *
+ * k kill
+ *
+ * ? What was the last sigval ? SNN (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum. A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer. '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host: Reply:
+ * $m0,10#2a +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <time.h>
+
+#ifdef __i386__
+#include <dfs.h>
+#include <conio.h>
+#include <advanced.h>
+#include <debugapi.h>
+#include <process.h>
+#else
+#include <nwtypes.h>
+#include <nwdfs.h>
+#include <nwconio.h>
+#include <nwadv.h>
+#include <nwdbgapi.h>
+#include <nwthread.h>
+#endif
+
+#include <aio.h>
+#include "cpu.h"
+
+
+/****************************************************/
+/* This information is from Novell. It is not in any of the standard
+ NetWare header files. */
+
+struct DBG_LoadDefinitionStructure
+{
+ void *reserved1[4];
+ LONG reserved5;
+ LONG LDCodeImageOffset;
+ LONG LDCodeImageLength;
+ LONG LDDataImageOffset;
+ LONG LDDataImageLength;
+ LONG LDUninitializedDataLength;
+ LONG LDCustomDataOffset;
+ LONG LDCustomDataSize;
+ LONG reserved6[2];
+ LONG (*LDInitializationProcedure)(void);
+};
+
+#define LO_NORMAL 0x0000
+#define LO_STARTUP 0x0001
+#define LO_PROTECT 0x0002
+#define LO_DEBUG 0x0004
+#define LO_AUTO_LOAD 0x0008
+
+/* Loader returned error codes */
+#define LOAD_COULD_NOT_FIND_FILE 1
+#define LOAD_ERROR_READING_FILE 2
+#define LOAD_NOT_NLM_FILE_FORMAT 3
+#define LOAD_WRONG_NLM_FILE_VERSION 4
+#define LOAD_REENTRANT_INITIALIZE_FAILURE 5
+#define LOAD_CAN_NOT_LOAD_MULTIPLE_COPIES 6
+#define LOAD_ALREADY_IN_PROGRESS 7
+#define LOAD_NOT_ENOUGH_MEMORY 8
+#define LOAD_INITIALIZE_FAILURE 9
+#define LOAD_INCONSISTENT_FILE_FORMAT 10
+#define LOAD_CAN_NOT_LOAD_AT_STARTUP 11
+#define LOAD_AUTO_LOAD_MODULES_NOT_LOADED 12
+#define LOAD_UNRESOLVED_EXTERNAL 13
+#define LOAD_PUBLIC_ALREADY_DEFINED 14
+/****************************************************/
+
+/* The main thread ID. */
+static int mainthread;
+
+/* An error message for the main thread to print. */
+static char *error_message;
+
+/* The AIO port handle. */
+static int AIOhandle;
+
+/* BUFMAX defines the maximum number of characters in inbound/outbound
+ buffers. At least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX (REGISTER_BYTES * 2 + 16)
+
+/* remote_debug > 0 prints ill-formed commands in valid packets and
+ checksum errors. */
+static int remote_debug = 1;
+
+static const char hexchars[] = "0123456789abcdef";
+
+unsigned char breakpoint_insn[] = BREAKPOINT;
+
+char *mem2hex (void *mem, char *buf, int count, int may_fault);
+char *hex2mem (char *buf, void *mem, int count, int may_fault);
+extern void set_step_traps (struct StackFrame *);
+extern void clear_step_traps (struct StackFrame *);
+
+static int __main() {};
+
+/* Read a character from the serial port. This must busy wait, but
+ that's OK because we will be the only thread running anyhow. */
+
+static int
+getDebugChar (void)
+{
+ int err;
+ LONG got;
+ unsigned char ret;
+
+ do
+ {
+ err = AIOReadData (AIOhandle, (char *) &ret, 1, &got);
+ if (err != 0)
+ {
+ error_message = "AIOReadData failed";
+ ResumeThread (mainthread);
+ return -1;
+ }
+ }
+ while (got == 0);
+
+ return ret;
+}
+
+/* Write a character to the serial port. Returns 0 on failure,
+ non-zero on success. */
+
+static int
+putDebugChar (unsigned char c)
+{
+ int err;
+ LONG put;
+
+ put = 0;
+ while (put < 1)
+ {
+ err = AIOWriteData (AIOhandle, (char *) &c, 1, &put);
+ if (err != 0)
+ ConsolePrintf ("AIOWriteData: err = %d, put = %d\r\n", err, put);
+ }
+ return 1;
+}
+
+/* Turn a hex character into a number. */
+
+static int
+hex (char ch)
+{
+ if ((ch >= 'a') && (ch <= 'f'))
+ return (ch-'a'+10);
+ if ((ch >= '0') && (ch <= '9'))
+ return (ch-'0');
+ if ((ch >= 'A') && (ch <= 'F'))
+ return (ch-'A'+10);
+ return (-1);
+}
+
+/* Scan for the sequence $<data>#<checksum>. Returns 0 on failure,
+ non-zero on success. */
+
+static int
+getpacket (char *buffer)
+{
+ unsigned char checksum;
+ unsigned char xmitcsum;
+ int i;
+ int count;
+ int ch;
+
+ do
+ {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = getDebugChar()) != '$')
+ if (ch == -1)
+ return 0;
+ checksum = 0;
+ xmitcsum = -1;
+
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX)
+ {
+ ch = getDebugChar();
+ if (ch == -1)
+ return 0;
+ if (ch == '#')
+ break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+ buffer[count] = 0;
+
+ if (ch == '#')
+ {
+ ch = getDebugChar ();
+ if (ch == -1)
+ return 0;
+ xmitcsum = hex(ch) << 4;
+ ch = getDebugChar ();
+ if (ch == -1)
+ return 0;
+ xmitcsum += hex(ch);
+
+ if (checksum != xmitcsum)
+ {
+ if (remote_debug)
+ ConsolePrintf ("bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n",
+ checksum,xmitcsum,buffer);
+ /* failed checksum */
+ if (! putDebugChar('-'))
+ return 0;
+ return 1;
+ }
+ else
+ {
+ /* successful transfer */
+ if (! putDebugChar('+'))
+ return 0;
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':')
+ {
+ if (! putDebugChar (buffer[0])
+ || ! putDebugChar (buffer[1]))
+ return 0;
+ /* remove sequence chars from buffer */
+ count = strlen(buffer);
+ for (i=3; i <= count; i++)
+ buffer[i-3] = buffer[i];
+ }
+ }
+ }
+ }
+ while (checksum != xmitcsum);
+
+ if (remote_debug)
+ ConsolePrintf ("Received packet \"%s\"\r\n", buffer);
+
+ return 1;
+}
+
+/* Send the packet in buffer. Returns 0 on failure, non-zero on
+ success. */
+
+static int
+putpacket (char *buffer)
+{
+ unsigned char checksum;
+ int count;
+ int ch;
+
+ if (remote_debug)
+ ConsolePrintf ("Sending packet \"%s\"\r\n", buffer);
+
+ /* $<packet info>#<checksum>. */
+ do
+ {
+ if (! putDebugChar('$'))
+ return 0;
+ checksum = 0;
+ count = 0;
+
+ while (ch=buffer[count])
+ {
+ if (! putDebugChar(ch))
+ return 0;
+ checksum += ch;
+ count += 1;
+ }
+
+ if (! putDebugChar('#')
+ || ! putDebugChar(hexchars[checksum >> 4])
+ || ! putDebugChar(hexchars[checksum % 16]))
+ return 0;
+
+ ch = getDebugChar ();
+ if (ch == -1)
+ return 0;
+ }
+ while (ch != '+');
+
+ return 1;
+}
+
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+static short error;
+
+static void
+debug_error (char *format, char *parm)
+{
+ if (remote_debug)
+ {
+ ConsolePrintf (format, parm);
+ ConsolePrintf ("\n");
+ }
+}
+
+/* This is set if we could get a memory access fault. */
+static int mem_may_fault;
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an
+ error. */
+volatile int mem_err = 0;
+
+#ifndef ALTERNATE_MEM_FUNCS
+/* These are separate functions so that they are so short and sweet
+ that the compiler won't save any registers (if there is a fault
+ to mem_fault, they won't get restored, so there better not be any
+ saved). */
+
+int
+get_char (char *addr)
+{
+ return *addr;
+}
+
+void
+set_char (char *addr, int val)
+{
+ *addr = val;
+}
+#endif /* ALTERNATE_MEM_FUNCS */
+
+/* convert the memory pointed to by mem into hex, placing result in buf */
+/* return a pointer to the last char put in buf (null) */
+/* If MAY_FAULT is non-zero, then we should set mem_err in response to
+ a fault; if zero treat a fault like any other fault in the stub. */
+
+char *
+mem2hex (void *mem, char *buf, int count, int may_fault)
+{
+ int i;
+ unsigned char ch;
+ char *ptr = mem;
+
+ mem_may_fault = may_fault;
+ for (i = 0; i < count; i++)
+ {
+ ch = get_char (ptr++);
+ if (may_fault && mem_err)
+ return (buf);
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch % 16];
+ }
+ *buf = 0;
+ mem_may_fault = 0;
+ return(buf);
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem */
+/* return a pointer to the character AFTER the last byte written */
+
+char *
+hex2mem (char *buf, void *mem, int count, int may_fault)
+{
+ int i;
+ unsigned char ch;
+ char *ptr = mem;
+
+ mem_may_fault = may_fault;
+ for (i=0;i<count;i++)
+ {
+ ch = hex(*buf++) << 4;
+ ch = ch + hex(*buf++);
+ set_char (ptr++, ch);
+ if (may_fault && mem_err)
+ return (ptr);
+ }
+ mem_may_fault = 0;
+ return(mem);
+}
+
+/* This function takes the 386 exception vector and attempts to
+ translate this number into a unix compatible signal value. */
+
+int
+computeSignal (int exceptionVector)
+{
+ int sigval;
+ switch (exceptionVector)
+ {
+ case 0 : sigval = 8; break; /* divide by zero */
+ case 1 : sigval = 5; break; /* debug exception */
+ case 3 : sigval = 5; break; /* breakpoint */
+ case 4 : sigval = 16; break; /* into instruction (overflow) */
+ case 5 : sigval = 16; break; /* bound instruction */
+ case 6 : sigval = 4; break; /* Invalid opcode */
+ case 7 : sigval = 8; break; /* coprocessor not available */
+ case 8 : sigval = 7; break; /* double fault */
+ case 9 : sigval = 11; break; /* coprocessor segment overrun */
+ case 10 : sigval = 11; break; /* Invalid TSS */
+ case 11 : sigval = 11; break; /* Segment not present */
+ case 12 : sigval = 11; break; /* stack exception */
+ case 13 : sigval = 11; break; /* general protection */
+ case 14 : sigval = 11; break; /* page fault */
+ case 16 : sigval = 7; break; /* coprocessor error */
+ default:
+ sigval = 7; /* "software generated"*/
+ }
+ return (sigval);
+}
+
+/**********************************************/
+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
+/* RETURN NUMBER OF CHARS PROCESSED */
+/**********************************************/
+static int
+hexToInt (char **ptr, int *intValue)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+
+ while (**ptr)
+ {
+ hexValue = hex(**ptr);
+ if (hexValue >=0)
+ {
+ *intValue = (*intValue <<4) | hexValue;
+ numChars ++;
+ }
+ else
+ break;
+
+ (*ptr)++;
+ }
+
+ return (numChars);
+}
+
+/* This function does all command processing for interfacing to gdb.
+ It is called whenever an exception occurs in the module being
+ debugged. */
+
+static LONG
+handle_exception (struct StackFrame *frame)
+{
+ int addr, length;
+ char *ptr;
+ static struct DBG_LoadDefinitionStructure *ldinfo = 0;
+ static unsigned char first_insn[BREAKPOINT_SIZE]; /* The first instruction in the program. */
+
+#if 0
+ /* According to some documentation from Novell, the bell sometimes
+ may be ringing at this point. This can be stopped on Netware 4
+ systems by calling the undocumented StopBell() function. */
+
+ StopBell ();
+#endif
+
+ if (remote_debug)
+ {
+ ConsolePrintf ("vector=%d: %s, pc=%08x, thread=%08x\r\n",
+ frame->ExceptionNumber,
+ frame->ExceptionDescription,
+ frame->ExceptionPC,
+ GetThreadID ());
+ }
+
+ switch (frame->ExceptionNumber)
+ {
+ case START_NLM_EVENT:
+ /* If the NLM just started, we record the module load information
+ and the thread ID, and set a breakpoint at the first instruction
+ in the program. */
+
+ ldinfo = ((struct DBG_LoadDefinitionStructure *)
+ frame->ExceptionErrorCode);
+ memcpy (first_insn, ldinfo->LDInitializationProcedure,
+ BREAKPOINT_SIZE);
+ memcpy (ldinfo->LDInitializationProcedure, breakpoint_insn,
+ BREAKPOINT_SIZE);
+ flush_i_cache ();
+ return RETURN_TO_PROGRAM;
+
+ case ENTER_DEBUGGER_EVENT:
+ case KEYBOARD_BREAK_EVENT:
+ /* Pass some events on to the next debugger, in case it will handle
+ them. */
+ return RETURN_TO_NEXT_DEBUGGER;
+
+ case 3: /* Breakpoint */
+ /* After we've reached the initial breakpoint, reset it. */
+ if (frame->ExceptionPC - DECR_PC_AFTER_BREAK == (LONG) ldinfo->LDInitializationProcedure
+ && memcmp (ldinfo->LDInitializationProcedure, breakpoint_insn,
+ BREAKPOINT_SIZE) == 0)
+ {
+ memcpy (ldinfo->LDInitializationProcedure, first_insn,
+ BREAKPOINT_SIZE);
+ frame->ExceptionPC -= DECR_PC_AFTER_BREAK;
+ flush_i_cache ();
+ }
+ /* Normal breakpoints end up here */
+ do_status (remcomOutBuffer, frame);
+ break;
+
+ default:
+ /* At the moment, we don't care about most of the unusual NetWare
+ exceptions. */
+ if (frame->ExceptionNumber > 31)
+ return RETURN_TO_PROGRAM;
+
+ /* Most machine level exceptions end up here */
+ do_status (remcomOutBuffer, frame);
+ break;
+
+ case 11: /* Segment not present */
+ case 13: /* General protection */
+ case 14: /* Page fault */
+ /* If we get a GP fault, and mem_may_fault is set, and the
+ instruction pointer is near set_char or get_char, then we caused
+ the fault ourselves accessing an illegal memory location. */
+ if (mem_may_fault
+ && ((frame->ExceptionPC >= (long) &set_char
+ && frame->ExceptionPC < (long) &set_char + 50)
+ || (frame->ExceptionPC >= (long) &get_char
+ && frame->ExceptionPC < (long) &get_char + 50)))
+ {
+ mem_err = 1;
+ /* Point the instruction pointer at an assembly language stub
+ which just returns from the function. */
+
+ frame->ExceptionPC += 4; /* Skip the load or store */
+
+ /* Keep going. This will act as though it returned from
+ set_char or get_char. The calling routine will check
+ mem_err, and do the right thing. */
+ return RETURN_TO_PROGRAM;
+ }
+ /* Random mem fault, report it */
+ do_status (remcomOutBuffer, frame);
+ break;
+
+ case TERMINATE_NLM_EVENT:
+ /* There is no way to get the exit status. */
+ sprintf (remcomOutBuffer, "W%02x", 0);
+ break; /* We generate our own status */
+ }
+
+ /* FIXME: How do we know that this exception has anything to do with
+ the program we are debugging? We can check whether the PC is in
+ the range of the module we are debugging, but that doesn't help
+ much since an error could occur in a library routine. */
+
+ clear_step_traps (frame);
+
+ if (! putpacket(remcomOutBuffer))
+ return RETURN_TO_NEXT_DEBUGGER;
+
+ if (frame->ExceptionNumber == TERMINATE_NLM_EVENT)
+ {
+ ResumeThread (mainthread);
+ return RETURN_TO_PROGRAM;
+ }
+
+ while (1)
+ {
+ error = 0;
+ remcomOutBuffer[0] = 0;
+ if (! getpacket (remcomInBuffer))
+ return RETURN_TO_NEXT_DEBUGGER;
+ switch (remcomInBuffer[0])
+ {
+ case '?':
+ do_status (remcomOutBuffer, frame);
+ break;
+ case 'd':
+ remote_debug = !(remote_debug); /* toggle debug flag */
+ break;
+ case 'g':
+ /* return the value of the CPU registers */
+ frame_to_registers (frame, remcomOutBuffer);
+ break;
+ case 'G':
+ /* set the value of the CPU registers - return OK */
+ registers_to_frame (&remcomInBuffer[1], frame);
+ strcpy(remcomOutBuffer,"OK");
+ break;
+
+ case 'm':
+ /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
+ ptr = &remcomInBuffer[1];
+ if (hexToInt(&ptr,&addr))
+ if (*(ptr++) == ',')
+ if (hexToInt(&ptr,&length))
+ {
+ ptr = 0;
+ mem_err = 0;
+ mem2hex((char*) addr, remcomOutBuffer, length, 1);
+ if (mem_err)
+ {
+ strcpy (remcomOutBuffer, "E03");
+ debug_error ("memory fault");
+ }
+ }
+
+ if (ptr)
+ {
+ strcpy(remcomOutBuffer,"E01");
+ debug_error("malformed read memory command: %s",remcomInBuffer);
+ }
+ break;
+
+ case 'M':
+ /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
+ ptr = &remcomInBuffer[1];
+ if (hexToInt(&ptr,&addr))
+ if (*(ptr++) == ',')
+ if (hexToInt(&ptr,&length))
+ if (*(ptr++) == ':')
+ {
+ mem_err = 0;
+ hex2mem(ptr, (char*) addr, length, 1);
+
+ if (mem_err)
+ {
+ strcpy (remcomOutBuffer, "E03");
+ debug_error ("memory fault");
+ }
+ else
+ {
+ strcpy(remcomOutBuffer,"OK");
+ }
+
+ ptr = 0;
+ }
+ if (ptr)
+ {
+ strcpy(remcomOutBuffer,"E02");
+ debug_error("malformed write memory command: %s",remcomInBuffer);
+ }
+ break;
+
+ case 'c':
+ case 's':
+ /* cAA..AA Continue at address AA..AA(optional) */
+ /* sAA..AA Step one instruction from AA..AA(optional) */
+ /* try to read optional parameter, pc unchanged if no parm */
+ ptr = &remcomInBuffer[1];
+ if (hexToInt(&ptr,&addr))
+ {
+/* registers[PC_REGNUM].lo = addr;*/
+ fprintf (stderr, "Setting PC to 0x%x\n", addr);
+ while (1);
+ }
+
+ if (remcomInBuffer[0] == 's')
+ set_step_traps (frame);
+
+ flush_i_cache ();
+ return RETURN_TO_PROGRAM;
+
+ case 'k':
+ /* kill the program */
+ KillMe (ldinfo);
+ ResumeThread (mainthread);
+ return RETURN_TO_PROGRAM;
+
+ case 'q': /* Query message */
+ if (strcmp (&remcomInBuffer[1], "Offsets") == 0)
+ {
+ sprintf (remcomOutBuffer, "Text=%x;Data=%x;Bss=%x",
+ ldinfo->LDCodeImageOffset,
+ ldinfo->LDDataImageOffset,
+ ldinfo->LDDataImageOffset + ldinfo->LDDataImageLength);
+ }
+ else
+ sprintf (remcomOutBuffer, "E04, Unknown query %s", &remcomInBuffer[1]);
+ break;
+ }
+
+ /* reply to the request */
+ if (! putpacket(remcomOutBuffer))
+ return RETURN_TO_NEXT_DEBUGGER;
+ }
+}
+
+char *progname;
+
+struct bitRate {
+ BYTE bitRate;
+ const char *bitRateString;
+};
+
+struct bitRate bitRateTable[] =
+{
+ { AIO_BAUD_50 , "50" },
+ { AIO_BAUD_75 , "75" },
+ { AIO_BAUD_110 , "110" },
+ { AIO_BAUD_134p5 , "134.5" },
+ { AIO_BAUD_150 , "150" },
+ { AIO_BAUD_300 , "300" },
+ { AIO_BAUD_600 , "600" },
+ { AIO_BAUD_1200 , "1200" },
+ { AIO_BAUD_1800 , "1800" },
+ { AIO_BAUD_2000 , "2000" },
+ { AIO_BAUD_2400 , "2400" },
+ { AIO_BAUD_3600 , "3600" },
+ { AIO_BAUD_4800 , "4800" },
+ { AIO_BAUD_7200 , "7200" },
+ { AIO_BAUD_9600 , "9600" },
+ { AIO_BAUD_19200 , "19200" },
+ { AIO_BAUD_38400 , "38400" },
+ { AIO_BAUD_57600 , "57600" },
+ { AIO_BAUD_115200, "115200" },
+ { -1, NULL }
+};
+
+char dataBitsTable[] = "5678";
+
+char *stopBitsTable[] = { "1", "1.5", "2" };
+
+char parity[] = "NOEMS";
+
+/* Start up. The main thread opens the named serial I/O port, loads
+ the named NLM module and then goes to sleep. The serial I/O port
+ is named as a board number and a port number. It would be more DOS
+ like to provide a menu of available serial ports, but I don't want
+ to have to figure out how to do that. */
+
+int
+main (int argc, char **argv)
+{
+ int hardware, board, port;
+ BYTE bitRate;
+ BYTE dataBits;
+ BYTE stopBits;
+ BYTE parityMode;
+ LONG err;
+ struct debuggerStructure s;
+ int cmdindx;
+ char *cmdlin;
+ int i;
+
+ /* set progname */
+ progname = "gdbserve";
+
+ /* set default serial line */
+ hardware = -1;
+ board = 0;
+ port = 0;
+
+ /* set default serial line characteristics */
+ bitRate = AIO_BAUD_9600;
+ dataBits = AIO_DATA_BITS_8;
+ stopBits = AIO_STOP_BITS_1;
+ parityMode = AIO_PARITY_NONE;
+
+ cmdindx = 0;
+ for (argc--, argv++; *argv; argc--, argv++)
+ {
+ char *bp;
+ char *ep;
+
+ if (strnicmp(*argv, "BAUD=", 5) == 0)
+ {
+ struct bitRate *brp;
+
+ bp = *argv + 5;
+ for (brp = bitRateTable; brp->bitRate != (BYTE) -1; brp++)
+ {
+ if (strcmp(brp->bitRateString, bp) == 0)
+ {
+ bitRate = brp->bitRate;
+ break;
+ }
+ }
+
+ if (brp->bitRateString == NULL)
+ {
+ fprintf(stderr, "%s: %s: unknown or unsupported bit rate",
+ progname, bp);
+ exit (1);
+ }
+ }
+ else if (strnicmp(*argv, "BOARD=", 6) == 0)
+ {
+ bp = *argv + 6;
+ board = strtol (bp, &ep, 0);
+ if (ep == bp || *ep != '\0')
+ {
+ fprintf (stderr, "%s: %s: expected integer argument\n",
+ progname, bp);
+ exit(1);
+ }
+ }
+#if 1 /* FIXME: this option has been depricated */
+ else if (strnicmp(*argv, "NODE=", 5) == 0)
+ {
+ bp = *argv + 5;
+ board = strtol (bp, &ep, 0);
+ if (ep == bp || *ep != '\0')
+ {
+ fprintf (stderr, "%s: %s: expected integer argument\n",
+ progname, bp);
+ exit(1);
+ }
+ }
+#endif
+ else if (strnicmp(*argv, "PORT=", 5) == 0)
+ {
+ bp = *argv + 5;
+ port = strtol (bp, &ep, 0);
+ if (ep == bp || *ep != '\0')
+ {
+ fprintf (stderr, "%s: %s: expected integer argument\n",
+ progname, bp);
+ exit(1);
+ }
+ }
+ else
+ {
+ break;
+ }
+
+ cmdindx++;
+ }
+
+ if (argc == 0)
+ {
+ fprintf (stderr,
+ "Usage: load %s [options] program [arguments]\n", progname);
+ exit (1);
+ }
+
+ err = AIOAcquirePort (&hardware, &board, &port, &AIOhandle);
+ if (err != AIO_SUCCESS)
+ {
+ switch (err)
+ {
+ case AIO_PORT_NOT_AVAILABLE:
+ fprintf (stderr, "Port not available\n");
+ break;
+
+ case AIO_BOARD_NUMBER_INVALID:
+ case AIO_PORT_NUMBER_INVALID:
+ fprintf (stderr, "No such port\n");
+ break;
+
+ default:
+ fprintf (stderr, "Could not open port: %d\n", err);
+ break;
+ }
+
+ exit (1);
+ }
+
+ err = AIOConfigurePort (AIOhandle, bitRate, dataBits, stopBits, parityMode,
+ AIO_HARDWARE_FLOW_CONTROL_OFF);
+
+ if (err == AIO_QUALIFIED_SUCCESS)
+ {
+ AIOPORTCONFIG portConfig;
+
+ fprintf (stderr, "Port configuration changed!\n");
+
+ portConfig.returnLength = sizeof(portConfig);
+ AIOGetPortConfiguration (AIOhandle, &portConfig, NULL);
+
+ fprintf (stderr,
+ " Bit Rate: %s, Data Bits: %c, Stop Bits: %s, Parity: %c,\
+ Flow:%s\n",
+ bitRateTable[portConfig.bitRate].bitRateString,
+ dataBitsTable[portConfig.dataBits],
+ stopBitsTable[portConfig.stopBits],
+ parity[portConfig.parityMode],
+ portConfig.flowCtrlMode ? "ON" : "OFF");
+ }
+ else if (err != AIO_SUCCESS)
+ {
+ fprintf (stderr, "Could not configure port: %d\n", err);
+ AIOReleasePort (AIOhandle);
+ exit (1);
+ }
+
+ if (AIOSetExternalControl(AIOhandle, AIO_EXTERNAL_CONTROL,
+ (AIO_EXTCTRL_DTR | AIO_EXTCTRL_RTS))
+ != AIO_SUCCESS)
+ {
+ LONG extStatus, chgdExtStatus;
+
+ fprintf (stderr, "Could not set desired port controls!\n");
+ AIOGetExternalStatus (AIOhandle, &extStatus, &chgdExtStatus);
+ fprintf (stderr, "Port controls now: %d, %d\n", extStatus,
+ chgdExtStatus);
+ }
+
+ /* Register ourselves as an alternate debugger. */
+ memset (&s, 0, sizeof s);
+ s.DDSResourceTag = ((struct ResourceTagStructure *)
+ AllocateResourceTag (GetNLMHandle (),
+ (BYTE *)"gdbserver",
+ DebuggerSignature));
+ if (s.DDSResourceTag == 0)
+ {
+ fprintf (stderr, "AllocateResourceTag failed\n");
+ AIOReleasePort (AIOhandle);
+ exit (1);
+ }
+ s.DDSdebuggerEntry = handle_exception;
+ s.DDSFlags = TSS_FRAME_BIT;
+
+ err = RegisterDebuggerRTag (&s, AT_FIRST);
+ if (err != 0)
+ {
+ fprintf (stderr, "RegisterDebuggerRTag failed\n");
+ AIOReleasePort (AIOhandle);
+ exit (1);
+ }
+
+ /* Get the command line we were invoked with, and advance it past
+ our name and the board and port arguments. */
+ cmdlin = getcmd ((char *) NULL);
+ for (i = 0; i < cmdindx; i++)
+ {
+ while (! isspace (*cmdlin))
+ ++cmdlin;
+ while (isspace (*cmdlin))
+ ++cmdlin;
+ }
+
+ /* In case GDB is started before us, ack any packets (presumably
+ "$?#xx") sitting there. */
+ if (! putDebugChar ('+'))
+ {
+ fprintf (stderr, "putDebugChar failed\n");
+ UnRegisterDebugger (&s);
+ AIOReleasePort (AIOhandle);
+ exit (1);
+ }
+
+ mainthread = GetThreadID ();
+
+ if (remote_debug > 0)
+ ConsolePrintf ("About to call LoadModule with \"%s\" %08x\r\n",
+ cmdlin, __GetScreenID (GetCurrentScreen()));
+
+ /* Start up the module to be debugged. */
+ err = LoadModule ((struct ScreenStruct *) __GetScreenID (GetCurrentScreen()),
+ (BYTE *)cmdlin, LO_DEBUG);
+ if (err != 0)
+ {
+ fprintf (stderr, "LoadModule failed: %d\n", err);
+ UnRegisterDebugger (&s);
+ AIOReleasePort (AIOhandle);
+ exit (1);
+ }
+
+ /* Wait for the debugger to wake us up. */
+ if (remote_debug > 0)
+ ConsolePrintf ("Suspending main thread (%08x)\r\n", mainthread);
+ SuspendThread (mainthread);
+ if (remote_debug > 0)
+ ConsolePrintf ("Resuming main thread (%08x)\r\n", mainthread);
+
+ /* If we are woken up, print an optional error message, deregister
+ ourselves and exit. */
+ if (error_message != NULL)
+ fprintf (stderr, "%s\n", error_message);
+ UnRegisterDebugger (&s);
+ AIOReleasePort (AIOhandle);
+ exit (0);
+}
diff --git a/gdb/nlm/gdbserve.def b/gdb/nlm/gdbserve.def
new file mode 100644
index 00000000000..588028d6f33
--- /dev/null
+++ b/gdb/nlm/gdbserve.def
@@ -0,0 +1,42 @@
+description "GDB debugger stub"
+version 1,2
+debug
+module clib
+screenname "System Console"
+input gdbserve.O
+output gdbserve.nlm
+start _Prelude
+exit _Stop
+import
+ AllocateResourceTag
+ ConsolePrintf
+ GetCurrentScreen
+ GetNLMHandle
+ GetThreadID
+ KillMe
+ LoadModule
+ ReadByteAltDebugger
+ RegisterDebuggerRTag
+ ResumeThread
+ SuspendThread
+ UnRegisterDebugger
+ WriteByteAltDebugger
+ _GetCLibNLMLibHandle
+ _NWRegisterNLMLibraryUser
+ _SetupArgv
+ _StartNLM
+ _TerminateNLM
+ __GetScreenID
+ __get_errno_ptr
+ exit
+ fprintf
+ getcmd
+ memcmp
+ memcpy
+ memset
+ sprintf
+ strcmp
+ strcpy
+ strlen
+ strnicmp
+ strtol
diff --git a/gdb/nlm/i386.c b/gdb/nlm/i386.c
new file mode 100644
index 00000000000..b8ab480b996
--- /dev/null
+++ b/gdb/nlm/i386.c
@@ -0,0 +1,100 @@
+#include <dfs.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <time.h>
+#include <conio.h>
+#include <advanced.h>
+#include <debugapi.h>
+#include <process.h>
+#include <errno.h>
+#include "i386.h"
+
+extern char *mem2hex (void *mem, char *buf, int count, int may_fault);
+extern char *hex2mem (char *buf, void *mem, int count, int may_fault);
+extern int computeSignal (int exceptionVector);
+
+void
+flush_i_cache (void)
+{
+}
+
+/* Get the registers out of the frame information. */
+
+void
+frame_to_registers (struct StackFrame *frame, char *regs)
+{
+ /* Copy EAX -> EDI */
+ mem2hex (&frame->ExceptionEAX, &regs[0 * 4 * 2], 4 * 8, 0);
+
+ /* Copy EIP & PS */
+ mem2hex (&frame->ExceptionPC, &regs[8 * 4 * 2], 4 * 2, 0);
+
+ /* Copy CS, SS, DS */
+ mem2hex (&frame->ExceptionCS, &regs[10 * 4 * 2], 4 * 3, 0);
+
+ /* Copy ES */
+ mem2hex (&frame->ExceptionES, &regs[13 * 4 * 2], 4 * 1, 0);
+
+ /* Copy FS & GS */
+ mem2hex (&frame->ExceptionFS, &regs[14 * 4 * 2], 4 * 2, 0);
+}
+
+/* Put the registers back into the frame information. */
+
+void
+registers_to_frame (char *regs, struct StackFrame *frame)
+{
+ /* Copy EAX -> EDI */
+ hex2mem (&regs[0 * 4 * 2], &frame->ExceptionEAX, 4 * 8, 0);
+
+ /* Copy EIP & PS */
+ hex2mem (&regs[8 * 4 * 2], &frame->ExceptionPC, 4 * 2, 0);
+
+ /* Copy CS, SS, DS */
+ hex2mem (&regs[10 * 4 * 2], &frame->ExceptionCS, 4 * 3, 0);
+
+ /* Copy ES */
+ hex2mem (&regs[13 * 4 * 2], &frame->ExceptionES, 4 * 1, 0);
+
+ /* Copy FS & GS */
+ hex2mem (&regs[14 * 4 * 2], &frame->ExceptionFS, 4 * 2, 0);
+}
+
+void
+set_step_traps (struct StackFrame *frame)
+{
+ frame->ExceptionSystemFlags |= 0x100;
+}
+
+void
+clear_step_traps (struct StackFrame *frame)
+{
+ frame->ExceptionSystemFlags &= ~0x100;
+}
+
+void
+do_status (char *ptr, struct StackFrame *frame)
+{
+ int sigval;
+
+ sigval = computeSignal (frame->ExceptionNumber);
+
+ sprintf (ptr, "T%02x", sigval);
+ ptr += 3;
+
+ sprintf (ptr, "%02x:", PC_REGNUM);
+ ptr = mem2hex (&frame->ExceptionPC, ptr + 3, 4, 0);
+ *ptr++ = ';';
+
+ sprintf (ptr, "%02x:", SP_REGNUM);
+ ptr = mem2hex (&frame->ExceptionESP, ptr + 3, 4, 0);
+ *ptr++ = ';';
+
+ sprintf (ptr, "%02x:", FP_REGNUM);
+ ptr = mem2hex (&frame->ExceptionEBP, ptr + 3, 4, 0);
+ *ptr++ = ';';
+
+ *ptr = '\000';
+}
diff --git a/gdb/nlm/i386.h b/gdb/nlm/i386.h
new file mode 100644
index 00000000000..155702bd503
--- /dev/null
+++ b/gdb/nlm/i386.h
@@ -0,0 +1,13 @@
+/* Register values. All of these values *MUST* agree with tm.h */
+#define SP_REGNUM 4 /* Contains address of top of stack */
+#define PC_REGNUM 8 /* Contains program counter */
+#define FP_REGNUM 5 /* Virtual frame pointer */
+#define NUM_REGS 16 /* Number of machine registers */
+#define REGISTER_BYTES (NUM_REGS * 4) /* Total size of registers array */
+
+#define ExceptionPC ExceptionEIP
+#define DECR_PC_AFTER_BREAK 1 /* int 3 leaves PC pointing after insn */
+#define BREAKPOINT {0xcc}
+#define BREAKPOINT_SIZE (sizeof breakpoint_insn)
+
+#define StackFrame T_TSS_StackFrame
diff --git a/gdb/nlm/ppc.c b/gdb/nlm/ppc.c
new file mode 100644
index 00000000000..c5850abcd77
--- /dev/null
+++ b/gdb/nlm/ppc.c
@@ -0,0 +1,244 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <errno.h>
+
+#include <nwtypes.h>
+#include <nwdfs.h>
+#include <nwconio.h>
+#include <nwadv.h>
+#include <nwdbgapi.h>
+#include <nwthread.h>
+#include "ppc.h"
+
+extern char *mem2hex (void *mem, char *buf, int count, int may_fault);
+extern char *hex2mem (char *buf, void *mem, int count, int may_fault);
+extern int computeSignal (int exceptionVector);
+
+void
+flush_i_cache (void)
+{
+}
+
+/* Get the registers out of the frame information. */
+
+void
+frame_to_registers (struct StackFrame *frame, char *regs)
+{
+ mem2hex (&frame->ExceptionState.CsavedRegs, &regs[GP0_REGNUM * 4 * 2], 4 * 32, 0);
+
+ mem2hex (&frame->ExceptionState.CSavedFPRegs, &regs[FP0_REGNUM * 4 * 2], 4 * 32, 0);
+
+ mem2hex (&frame->ExceptionPC, &regs[PC_REGNUM * 4 * 2], 4 * 1, 0);
+
+ mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, &regs[CR_REGNUM * 4 * 2], 4 * 1, 0);
+ mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, &regs[LR_REGNUM * 4 * 2], 4 * 1, 0);
+ mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, &regs[CTR_REGNUM * 4 * 2], 4 * 1, 0);
+ mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, &regs[XER_REGNUM * 4 * 2], 4 * 1, 0);
+ mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, &regs[MQ_REGNUM * 4 * 2], 4 * 1, 0);
+}
+
+/* Put the registers back into the frame information. */
+
+void
+registers_to_frame (char *regs, struct StackFrame *frame)
+{
+ hex2mem (&regs[GP0_REGNUM * 4 * 2], &frame->ExceptionState.CsavedRegs, 4 * 32, 0);
+
+ hex2mem (&regs[FP0_REGNUM * 4 * 2], &frame->ExceptionState.CSavedFPRegs, 4 * 32, 0);
+
+ hex2mem (&regs[PC_REGNUM * 4 * 2], &frame->ExceptionPC, 4 * 1, 0);
+
+ hex2mem (&regs[CR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, 4 * 1, 0);
+ hex2mem (&regs[LR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, 4 * 1, 0);
+ hex2mem (&regs[CTR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, 4 * 1, 0);
+ hex2mem (&regs[XER_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, 4 * 1, 0);
+ hex2mem (&regs[MQ_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, 4 * 1, 0);
+}
+
+
+extern volatile int mem_err;
+
+#ifdef ALTERNATE_MEM_FUNCS
+extern int ReadByteAltDebugger (char* addr, char *theByte);
+extern int WriteByteAltDebugger (char* addr, char theByte);
+int
+get_char (char *addr)
+{
+ char c;
+
+ if (!ReadByteAltDebugger (addr, &c))
+ mem_err = 1;
+
+ return c;
+}
+
+void
+set_char (char *addr, int val)
+{
+ if (!WriteByteAltDebugger (addr, val))
+ mem_err = 1;
+}
+#endif
+
+int
+mem_write (char *dst, char *src, int len)
+{
+ while (len-- && !mem_err)
+ set_char (dst++, *src++);
+
+ return mem_err;
+}
+
+union inst
+{
+ LONG l;
+
+ struct
+ {
+ union
+ {
+ struct /* Unconditional branch */
+ {
+ unsigned opcode : 6; /* 18 */
+ signed li : 24;
+ unsigned aa : 1;
+ unsigned lk : 1;
+ } b;
+ struct /* Conditional branch */
+ {
+ unsigned opcode : 6; /* 16 */
+ unsigned bo : 5;
+ unsigned bi : 5;
+ signed bd : 14;
+ unsigned aa : 1;
+ unsigned lk : 1;
+ } bc;
+ struct /* Conditional branch to ctr or lr reg */
+ {
+ unsigned opcode : 6; /* 19 */
+ unsigned bo : 5;
+ unsigned bi : 5;
+ unsigned type : 15; /* 528 = ctr, 16 = lr */
+ unsigned lk : 1;
+ } bclr;
+ } variant;
+ } inst;
+};
+
+static LONG saved_inst;
+static LONG *saved_inst_pc = 0;
+static LONG saved_target_inst;
+static LONG *saved_target_inst_pc = 0;
+
+void
+set_step_traps (struct StackFrame *frame)
+{
+ union inst inst;
+ LONG *target;
+ int opcode;
+ int ra, rb;
+ LONG *pc = (LONG *)frame->ExceptionPC;
+
+ inst.l = *pc++;
+
+ opcode = inst.inst.variant.b.opcode;
+
+ target = pc;
+
+ switch (opcode)
+ {
+ case 18: /* Unconditional branch */
+
+ if (inst.inst.variant.b.aa) /* Absolute? */
+ target = 0;
+ target += inst.inst.variant.b.li;
+
+ break;
+ case 16: /* Conditional branch */
+
+ if (!inst.inst.variant.bc.aa) /* Absolute? */
+ target = 0;
+ target += inst.inst.variant.bc.bd;
+
+ break;
+ case 19: /* Cond. branch via ctr or lr reg */
+ switch (inst.inst.variant.bclr.type)
+ {
+ case 528: /* ctr */
+ target = (LONG *)frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR;
+ break;
+ case 16: /* lr */
+ target = (LONG *)frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR;
+ break;
+ }
+ break;
+ }
+
+ saved_inst = *pc;
+ mem_write (pc, breakpoint_insn, BREAKPOINT_SIZE);
+ saved_inst_pc = pc;
+
+ if (target != pc)
+ {
+ saved_target_inst = *target;
+ mem_write (target, breakpoint_insn, BREAKPOINT_SIZE);
+ saved_target_inst_pc = target;
+ }
+}
+
+/* Remove step breakpoints. Returns non-zero if pc was at a step breakpoint,
+ zero otherwise. This routine works even if there were no step breakpoints
+ set. */
+
+int
+clear_step_traps (struct StackFrame *frame)
+{
+ int retcode;
+ LONG *pc = (LONG *)frame->ExceptionPC;
+
+ if (saved_inst_pc == pc || saved_target_inst_pc == pc)
+ retcode = 1;
+ else
+ retcode = 0;
+
+ if (saved_inst_pc)
+ {
+ mem_write (saved_inst_pc, saved_inst, BREAKPOINT_SIZE);
+ saved_inst_pc = 0;
+ }
+
+ if (saved_target_inst_pc)
+ {
+ mem_write (saved_target_inst_pc, saved_target_inst, BREAKPOINT_SIZE);
+ saved_target_inst_pc = 0;
+ }
+
+ return retcode;
+}
+
+void
+do_status (char *ptr, struct StackFrame *frame)
+{
+ int sigval;
+
+ sigval = computeSignal (frame->ExceptionNumber);
+
+ sprintf (ptr, "T%02x", sigval);
+ ptr += 3;
+
+ sprintf (ptr, "%02x:", PC_REGNUM);
+ ptr = mem2hex (&frame->ExceptionPC, ptr + 3, 4, 0);
+ *ptr++ = ';';
+
+ sprintf (ptr, "%02x:", SP_REGNUM);
+ ptr = mem2hex (&frame->ExceptionState.CsavedRegs[SP_REGNUM], ptr + 3, 4, 0);
+ *ptr++ = ';';
+
+ sprintf (ptr, "%02x:", LR_REGNUM);
+ ptr = mem2hex (&frame->ExceptionState.CsavedRegs[LR_REGNUM], ptr + 3, 4, 0);
+ *ptr++ = ';';
+
+ *ptr = '\000';
+}
diff --git a/gdb/nlm/ppc.h b/gdb/nlm/ppc.h
new file mode 100644
index 00000000000..84cee6b11a3
--- /dev/null
+++ b/gdb/nlm/ppc.h
@@ -0,0 +1,165 @@
+typedef long Long;
+
+/* The following enum is used to access the special registers in
+ the saved machine state. */
+
+typedef enum
+{
+ kDc_SavedPC = 0, /* really SRR0 */
+ kDc_SavedMSR = 1, /* really SRR1 */
+ kDc_SavedCR = 2,
+ kDc_SavedLR = 3,
+ kDc_SavedDSISR = 4,
+ kDc_SavedDAR = 5,
+ kDc_SavedXER = 6,
+ kDc_SavedCTR = 7,
+ kDc_SavedSDR1 = 8,
+ kDc_SavedRTCU = 9,
+ kDc_SavedRTCL = 10,
+ kDc_SavedDEC = 11,
+ kDc_SavedSR00 = 12, /* The Segement Registers are consecutive */
+ kDc_SavedSR01 = 13, /* kDc_SavedSR00 + n is supported */
+ kDc_SavedSR02 = 14,
+ kDc_SavedSR03 = 15,
+ kDc_SavedSR04 = 16,
+ kDc_SavedSR05 = 17,
+ kDc_SavedSR06 = 18,
+ kDc_SavedSR07 = 19,
+ kDc_SavedSR08 = 20,
+ kDc_SavedSR09 = 21,
+ kDc_SavedSR10 = 22,
+ kDc_SavedSR11 = 23,
+ kDc_SavedSR12 = 24,
+ kDc_SavedSR13 = 25,
+ kDc_SavedSR14 = 26,
+ kDc_SavedSR15 = 27,
+ kDc_SavedFPSCR = 29,
+ kDc_SavedMQ = 30,
+ kDc_SavedBAT0U = 31,
+ kDc_SavedBAT0L = 32,
+ kDc_SavedBAT1U = 33,
+ kDc_SavedBAT1L = 34,
+ kDc_SavedBAT2U = 35,
+ kDc_SavedBAT2L = 36,
+ kDc_SavedBAT3U = 37,
+ kDc_SavedBAT3L = 38,
+
+ kNumberSpecialRegisters = 39
+} Dc_SavedRegisterName;
+
+/* Access to floating points is not very easy. This allows the number to be
+ accessed both as a floating number and as a pair of Longs. */
+
+typedef union
+{
+ double asfloat; /* access the variable as a floating number */
+ struct
+ {
+ Long high;
+ Long low;
+ }
+ asLONG; /* access the variable as two Longs */
+} FloatingPoints;
+
+/* The following is the standard record for Saving a machine state */
+
+struct SavedMachineState
+{
+ FloatingPoints CSavedFPRegs[32]; /* The floating point registers [0->31] */
+ /* ***32bit assumption*** */
+ Long CsavedRegs[32]; /* space to save the General Registers */
+ /* These are saved 0->31 */
+ Long CexReason;
+ Long SavedDomainID;
+ union
+ { /* must be 8-byte aligned, so doubleFPSCR is 8-byte aligned */
+ struct
+ {
+ Long CsavedSRR0; /* Index 0 - The saved PC */
+ Long CsavedSRR1; /* 1 saved MSR */
+ Long CsavedCR; /* 2 */
+ Long CsavedLR; /* 3 */
+ Long CsavedDSISR; /* 4 */
+ Long CsavedDAR; /* 5 */
+
+ Long CsavedXER; /* 6 */
+ Long CsavedCTR; /* 7 */
+ Long CsavedSDR1; /* 8 */
+ Long CsavedRTCU; /* 9 */
+ Long CsavedRTCL; /* 10 */
+ Long CsavedDEC; /* 11 */
+ Long CsavedSR0; /* 12 */
+ Long CsavedSR1; /* 13 */
+ Long CsavedSR2; /* 14 */
+ Long CsavedSR3; /* 15 */
+ Long CsavedSR4; /* 16 */
+ Long CsavedSR5; /* 17 */
+ Long CsavedSR6; /* 18 */
+ Long CsavedSR7; /* 19 */
+ Long CsavedSR8; /* 20 */
+ Long CsavedSR9; /* 21 */
+ Long CsavedSR10; /* 22 */
+ Long CsavedSR11; /* 23 */
+ Long CsavedSR12; /* 24 */
+ Long CsavedSR13; /* 25 */
+ Long CsavedSR14; /* 26 */
+ Long CsavedSR15; /* 27 */
+ /* CdoubleFPSCR must be double word aligned */
+ Long CdoubleFPSCR; /* 28 this is the upper part of the store and has
+ no meaning */
+ Long CsavedFPSCR; /* 29 */
+ Long CsavedMQ; /* 30 */
+ Long CsavedBAT0U; /* 31 */
+ Long CsavedBAT0L; /* 32 */
+ Long CsavedBAT1U; /* 33 */
+ Long CsavedBAT1L; /* 34 */
+ Long CsavedBAT2U; /* 35 */
+ Long CsavedBAT2L; /* 36 */
+ Long CsavedBAT3U; /* 37 */
+ Long CsavedBAT3L; /* 38 */
+ }
+ SpecialRegistersEnumerated;
+
+ Long SpecialRegistersIndexed[kNumberSpecialRegisters];
+ } u;
+
+ Long Padding[3]; /* Needed for quad-word alignment */
+};
+
+struct StackFrame
+{
+ LONG *ExceptionDomainID;
+ /*ProcessorStructure*/ int *ExceptionProcessorID;
+ BYTE *ExceptionDescription;
+ LONG ExceptionFlags;
+ LONG ExceptionErrorCode;
+ LONG ExceptionNumber;
+ struct SavedMachineState ExceptionState;
+};
+
+/* Register values. All of these values *MUST* agree with tm.h */
+#define GP0_REGNUM 0 /* GPR register 0 */
+#define SP_REGNUM 1 /* Contains address of top of stack */
+#define FP0_REGNUM 32 /* FPR (Floating point) register 0 */
+#define PC_REGNUM 64 /* Contains program counter */
+#define PS_REGNUM 65 /* Processor (or machine) status (%msr) */
+#define CR_REGNUM 66 /* Condition register */
+#define LR_REGNUM 67 /* Link register */
+#define CTR_REGNUM 68 /* Count register */
+#define XER_REGNUM 69 /* Fixed point exception registers */
+#define MQ_REGNUM 70 /* Multiply/quotient register */
+#define NUM_REGS 71 /* Number of machine registers */
+#define REGISTER_BYTES (420) /* Total size of registers array */
+
+#define ExceptionPC ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR0
+#define DECR_PC_AFTER_BREAK 0 /* PPCs get this right! */
+#define BREAKPOINT {0x7d, 0x82, 0x10, 0x08}
+extern unsigned char breakpoint_insn[];
+#define BREAKPOINT_SIZE 4
+
+#if 0
+#define ALTERNATE_MEM_FUNCS /* We need our own get_char/set_char */
+#endif
+
+extern int get_char (char *addr);
+extern void set_char (char *addr, int val);
diff --git a/gdb/nlm/prelude.c b/gdb/nlm/prelude.c
new file mode 100644
index 00000000000..37e12c89a2b
--- /dev/null
+++ b/gdb/nlm/prelude.c
@@ -0,0 +1,67 @@
+/*===========================================================================
+= Novell Standard C Library for NetWare Loadable Modules
+=
+= Unpublished Copyright (C) 1993 by Novell, Inc. All rights reserved.
+=
+= No part of this file may be duplicated, revised, translated, localized or
+= modified in any manner or compiled, linked or uploaded or downloaded to or
+= from any computer system without the prior written consent of Novell, Inc.
+==============================================================================
+= The object produced by compiling this file is for use by the client of this
+= library and is not linked in; Prelude.Obj is therefore one of the files to
+= be distributed with CLib.NLM and its headers.
+==============================================================================
+*/
+
+#include <stddef.h>
+#if defined(__netware__) && defined(__i386__)
+#define TERMINATE_BY_UNLOAD 5
+#else
+#include <nwpre.h>
+#endif
+/*#include "libhooks.h"*/
+
+extern int main (int, char **);
+
+static int NLMID;
+
+
+void _Stop( void )
+{
+ _TerminateNLM(NLMID, NULL, TERMINATE_BY_UNLOAD);
+}
+
+int _cstart_( void )
+{
+ return _SetupArgv(main);
+}
+
+int _Prelude
+(
+ int NLMHandle,
+ int initErrorScreenID,
+ char *commandLine,
+ char *loadDirectoryPath,
+ int uninitializedDataLength,
+ int NLMFileHandle,
+ int (*readRoutineP)(),
+ int customDataOffset,
+ int customDataSize
+)
+{
+ int rc;
+
+ rc = _StartNLM(NLMHandle,
+ initErrorScreenID,
+ commandLine,
+ loadDirectoryPath,
+ uninitializedDataLength,
+ NLMFileHandle,
+ readRoutineP,
+ customDataOffset,
+ customDataSize,
+ &NLMID,
+ _cstart_);
+
+ return rc;
+}
diff --git a/gdb/nlmread.c b/gdb/nlmread.c
new file mode 100644
index 00000000000..eaa9ddeb2f3
--- /dev/null
+++ b/gdb/nlmread.c
@@ -0,0 +1,248 @@
+/* Read NLM (NetWare Loadable Module) format executable files for GDB.
+ Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000
+ Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus Support (fnf@cygnus.com).
+
+ 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 "defs.h"
+#include "bfd.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "stabsread.h"
+
+extern void _initialize_nlmread (void);
+
+static void nlm_new_init (struct objfile *);
+
+static void nlm_symfile_init (struct objfile *);
+
+static void nlm_symfile_read (struct objfile *, int);
+
+static void nlm_symfile_finish (struct objfile *);
+
+static void nlm_symtab_read (bfd *, CORE_ADDR, struct objfile *);
+
+/* Initialize anything that needs initializing when a completely new symbol
+ file is specified (not just adding some symbols from another file, e.g. a
+ shared library).
+
+ We reinitialize buildsym, since gdb will be able to read stabs from an NLM
+ file at some point in the near future. */
+
+static void
+nlm_new_init (struct objfile *ignore)
+{
+ stabsread_new_init ();
+ buildsym_new_init ();
+}
+
+
+/* NLM specific initialization routine for reading symbols.
+
+ It is passed a pointer to a struct sym_fns which contains, among other
+ things, the BFD for the file whose symbols are being read, and a slot for
+ a pointer to "private data" which we can fill with goodies.
+
+ For now at least, we have nothing in particular to do, so this function is
+ just a stub. */
+
+static void
+nlm_symfile_init (struct objfile *ignore)
+{
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ nlm_symtab_read -- read the symbol table of an NLM file
+
+ SYNOPSIS
+
+ void nlm_symtab_read (bfd *abfd, CORE_ADDR addr,
+ struct objfile *objfile)
+
+ DESCRIPTION
+
+ Given an open bfd, a base address to relocate symbols to, and a
+ flag that specifies whether or not this bfd is for an executable
+ or not (may be shared library for example), add all the global
+ function and data symbols to the minimal symbol table.
+ */
+
+static void
+nlm_symtab_read (bfd *abfd, CORE_ADDR addr, struct objfile *objfile)
+{
+ long storage_needed;
+ asymbol *sym;
+ asymbol **symbol_table;
+ long number_of_symbols;
+ long i;
+ struct cleanup *back_to;
+ CORE_ADDR symaddr;
+ enum minimal_symbol_type ms_type;
+
+ storage_needed = bfd_get_symtab_upper_bound (abfd);
+ if (storage_needed < 0)
+ error ("Can't read symbols from %s: %s", bfd_get_filename (abfd),
+ bfd_errmsg (bfd_get_error ()));
+ if (storage_needed > 0)
+ {
+ symbol_table = (asymbol **) xmalloc (storage_needed);
+ back_to = make_cleanup (xfree, symbol_table);
+ number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
+ if (number_of_symbols < 0)
+ error ("Can't read symbols from %s: %s", bfd_get_filename (abfd),
+ bfd_errmsg (bfd_get_error ()));
+
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ sym = symbol_table[i];
+ if ( /*sym -> flags & BSF_GLOBAL */ 1)
+ {
+ /* Bfd symbols are section relative. */
+ symaddr = sym->value + sym->section->vma;
+ /* Relocate all non-absolute symbols by base address. */
+ if (sym->section != &bfd_abs_section)
+ symaddr += addr;
+
+ /* For non-absolute symbols, use the type of the section
+ they are relative to, to intuit text/data. BFD provides
+ no way of figuring this out for absolute symbols. */
+ if (sym->section->flags & SEC_CODE)
+ ms_type = mst_text;
+ else if (sym->section->flags & SEC_DATA)
+ ms_type = mst_data;
+ else
+ ms_type = mst_unknown;
+
+ prim_record_minimal_symbol (sym->name, symaddr, ms_type,
+ objfile);
+ }
+ }
+ do_cleanups (back_to);
+ }
+}
+
+
+/* Scan and build partial symbols for a symbol file.
+ We have been initialized by a call to nlm_symfile_init, which
+ currently does nothing.
+
+ SECTION_OFFSETS is a set of offsets to apply to relocate the symbols
+ in each section. We simplify it down to a single offset for all
+ symbols. FIXME.
+
+ MAINLINE is true if we are reading the main symbol
+ table (as opposed to a shared lib or dynamically loaded file).
+
+ This function only does the minimum work necessary for letting the
+ user "name" things symbolically; it does not read the entire symtab.
+ Instead, it reads the external and static symbols and puts them in partial
+ symbol tables. When more extensive information is requested of a
+ file, the corresponding partial symbol table is mutated into a full
+ fledged symbol table by going back and reading the symbols
+ for real.
+
+ Note that NLM files have two sets of information that is potentially
+ useful for building gdb's minimal symbol table. The first is a list
+ of the publically exported symbols, and is currently used to build
+ bfd's canonical symbol table. The second is an optional native debugging
+ format which contains additional symbols (and possibly duplicates of
+ the publically exported symbols). The optional native debugging format
+ is not currently used. */
+
+static void
+nlm_symfile_read (struct objfile *objfile, int mainline)
+{
+ bfd *abfd = objfile->obfd;
+ struct cleanup *back_to;
+ CORE_ADDR offset;
+ struct symbol *mainsym;
+
+ init_minimal_symbol_collection ();
+ back_to = make_cleanup_discard_minimal_symbols ();
+
+ /* FIXME, should take a section_offsets param, not just an offset. */
+
+ offset = ANOFFSET (objfile->section_offsets, 0);
+
+ /* Process the NLM export records, which become the bfd's canonical symbol
+ table. */
+
+ nlm_symtab_read (abfd, offset, objfile);
+
+ stabsect_build_psymtabs (objfile, mainline, ".stab",
+ ".stabstr", ".text");
+
+ mainsym = lookup_symbol (main_name (), NULL, VAR_NAMESPACE, NULL, NULL);
+
+ if (mainsym
+ && SYMBOL_CLASS (mainsym) == LOC_BLOCK)
+ {
+ objfile->ei.main_func_lowpc = BLOCK_START (SYMBOL_BLOCK_VALUE (mainsym));
+ objfile->ei.main_func_highpc = BLOCK_END (SYMBOL_BLOCK_VALUE (mainsym));
+ }
+
+ /* FIXME: We could locate and read the optional native debugging format
+ here and add the symbols to the minimal symbol table. */
+
+ /* Install any minimal symbols that have been collected as the current
+ minimal symbols for this objfile. */
+
+ install_minimal_symbols (objfile);
+
+ do_cleanups (back_to);
+}
+
+
+/* Perform any local cleanups required when we are done with a particular
+ objfile. I.E, we are in the process of discarding all symbol information
+ for an objfile, freeing up all memory held for it, and unlinking the
+ objfile struct from the global list of known objfiles. */
+
+static void
+nlm_symfile_finish (struct objfile *objfile)
+{
+ if (objfile->sym_private != NULL)
+ {
+ xmfree (objfile->md, objfile->sym_private);
+ }
+}
+
+/* Register that we are able to handle NLM file format. */
+
+static struct sym_fns nlm_sym_fns =
+{
+ bfd_target_nlm_flavour,
+ nlm_new_init, /* sym_new_init: init anything gbl to entire symtab */
+ nlm_symfile_init, /* sym_init: read initial info, setup for sym_read() */
+ nlm_symfile_read, /* sym_read: read a symbol file into symtab */
+ nlm_symfile_finish, /* sym_finish: finished with file, cleanup */
+ default_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */
+ NULL /* next: pointer to next struct sym_fns */
+};
+
+void
+_initialize_nlmread (void)
+{
+ add_symtab_fns (&nlm_sym_fns);
+}
diff --git a/gdb/notify.defs b/gdb/notify.defs
new file mode 100644
index 00000000000..2014be5ca44
--- /dev/null
+++ b/gdb/notify.defs
@@ -0,0 +1 @@
+#include <mach/notify.defs>
diff --git a/gdb/ns32k-tdep.c b/gdb/ns32k-tdep.c
new file mode 100644
index 00000000000..5d4a885674b
--- /dev/null
+++ b/gdb/ns32k-tdep.c
@@ -0,0 +1,673 @@
+/* Target dependent code for the NS32000, for GDB.
+ Copyright 1986, 1988, 1991, 1992, 1994, 1995, 1998, 1999, 2000, 2001,
+ 2002 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 "defs.h"
+#include "frame.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+
+#include "arch-utils.h"
+
+#include "ns32k-tdep.h"
+
+static int sign_extend (int value, int bits);
+static CORE_ADDR ns32k_get_enter_addr (CORE_ADDR);
+static int ns32k_localcount (CORE_ADDR enter_pc);
+static void flip_bytes (void *, int);
+
+static char *
+ns32k_register_name_32082 (int regno)
+{
+ static char *register_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "sp", "fp", "pc", "ps",
+ "l0", "l1", "l2", "l3", "xx",
+ };
+
+ if (regno < 0)
+ return NULL;
+ if (regno >= sizeof (register_names) / sizeof (*register_names))
+ return NULL;
+
+ return (register_names[regno]);
+}
+
+static char *
+ns32k_register_name_32382 (int regno)
+{
+ static char *register_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "sp", "fp", "pc", "ps",
+ "fsr",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", "xx",
+ };
+
+ if (regno < 0)
+ return NULL;
+ if (regno >= sizeof (register_names) / sizeof (*register_names))
+ return NULL;
+
+ return (register_names[regno]);
+}
+
+static int
+ns32k_register_byte_32082 (int regno)
+{
+ if (regno >= NS32K_LP0_REGNUM)
+ return (NS32K_LP0_REGNUM * 4) + ((regno - NS32K_LP0_REGNUM) * 8);
+
+ return (regno * 4);
+}
+
+static int
+ns32k_register_byte_32382 (int regno)
+{
+ /* This is a bit yuk. The even numbered double precision floating
+ point long registers occupy the same space as the even:odd numbered
+ single precision floating point registers, but the extra 32381 FPU
+ registers are at the end. Doing it this way is compatible for both
+ 32081 and 32381 equipped machines. */
+
+ return ((regno < NS32K_LP0_REGNUM ? regno
+ : (regno - NS32K_LP0_REGNUM) & 1 ? regno - 1
+ : (regno - NS32K_LP0_REGNUM + FP0_REGNUM)) * 4);
+}
+
+static int
+ns32k_register_raw_size (int regno)
+{
+ /* All registers are 4 bytes, except for the doubled floating
+ registers. */
+
+ return ((regno >= NS32K_LP0_REGNUM) ? 8 : 4);
+}
+
+static int
+ns32k_register_virtual_size (int regno)
+{
+ return ((regno >= NS32K_LP0_REGNUM) ? 8 : 4);
+}
+
+static struct type *
+ns32k_register_virtual_type (int regno)
+{
+ if (regno < FP0_REGNUM)
+ return (builtin_type_int);
+
+ if (regno < FP0_REGNUM + 8)
+ return (builtin_type_float);
+
+ if (regno < NS32K_LP0_REGNUM)
+ return (builtin_type_int);
+
+ return (builtin_type_double);
+}
+
+/* Immediately after a function call, return the saved PC. Can't
+ always go through the frames for this because on some systems,
+ the new frame is not set up until the new function executes some
+ instructions. */
+
+static CORE_ADDR
+ns32k_saved_pc_after_call (struct frame_info *frame)
+{
+ return (read_memory_integer (read_register (SP_REGNUM), 4));
+}
+
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code. */
+
+static CORE_ADDR
+umax_skip_prologue (CORE_ADDR pc)
+{
+ register unsigned char op = read_memory_integer (pc, 1);
+ if (op == 0x82)
+ {
+ op = read_memory_integer (pc + 2, 1);
+ if ((op & 0x80) == 0)
+ pc += 3;
+ else if ((op & 0xc0) == 0x80)
+ pc += 4;
+ else
+ pc += 6;
+ }
+ return pc;
+}
+
+static const unsigned char *
+ns32k_breakpoint_from_pc (CORE_ADDR *pcp, int *lenp)
+{
+ static const unsigned char breakpoint_insn[] = { 0xf2 };
+
+ *lenp = sizeof (breakpoint_insn);
+ return breakpoint_insn;
+}
+
+/* Return number of args passed to a frame.
+ Can return -1, meaning no way to tell.
+ Encore's C compiler often reuses same area on stack for args,
+ so this will often not work properly. If the arg names
+ are known, it's likely most of them will be printed. */
+
+static int
+umax_frame_num_args (struct frame_info *fi)
+{
+ int numargs;
+ CORE_ADDR pc;
+ CORE_ADDR enter_addr;
+ unsigned int insn;
+ unsigned int addr_mode;
+ int width;
+
+ numargs = -1;
+ enter_addr = ns32k_get_enter_addr ((fi)->pc);
+ if (enter_addr > 0)
+ {
+ pc = ((enter_addr == 1)
+ ? SAVED_PC_AFTER_CALL (fi)
+ : FRAME_SAVED_PC (fi));
+ insn = read_memory_integer (pc, 2);
+ addr_mode = (insn >> 11) & 0x1f;
+ insn = insn & 0x7ff;
+ if ((insn & 0x7fc) == 0x57c
+ && addr_mode == 0x14) /* immediate */
+ {
+ if (insn == 0x57c) /* adjspb */
+ width = 1;
+ else if (insn == 0x57d) /* adjspw */
+ width = 2;
+ else if (insn == 0x57f) /* adjspd */
+ width = 4;
+ else
+ internal_error (__FILE__, __LINE__, "bad else");
+ numargs = read_memory_integer (pc + 2, width);
+ if (width > 1)
+ flip_bytes (&numargs, width);
+ numargs = -sign_extend (numargs, width * 8) / 4;
+ }
+ }
+ return numargs;
+}
+
+static int
+sign_extend (int value, int bits)
+{
+ value = value & ((1 << bits) - 1);
+ return (value & (1 << (bits - 1))
+ ? value | (~((1 << bits) - 1))
+ : value);
+}
+
+static void
+flip_bytes (void *p, int count)
+{
+ char tmp;
+ char *ptr = 0;
+
+ while (count > 0)
+ {
+ tmp = *ptr;
+ ptr[0] = ptr[count - 1];
+ ptr[count - 1] = tmp;
+ ptr++;
+ count -= 2;
+ }
+}
+
+/* Return the number of locals in the current frame given a
+ pc pointing to the enter instruction. This is used by
+ ns32k_frame_init_saved_regs. */
+
+static int
+ns32k_localcount (CORE_ADDR enter_pc)
+{
+ unsigned char localtype;
+ int localcount;
+
+ localtype = read_memory_integer (enter_pc + 2, 1);
+ if ((localtype & 0x80) == 0)
+ localcount = localtype;
+ else if ((localtype & 0xc0) == 0x80)
+ localcount = (((localtype & 0x3f) << 8)
+ | (read_memory_integer (enter_pc + 3, 1) & 0xff));
+ else
+ localcount = (((localtype & 0x3f) << 24)
+ | ((read_memory_integer (enter_pc + 3, 1) & 0xff) << 16)
+ | ((read_memory_integer (enter_pc + 4, 1) & 0xff) << 8)
+ | (read_memory_integer (enter_pc + 5, 1) & 0xff));
+ return localcount;
+}
+
+
+/* Nonzero if instruction at PC is a return instruction. */
+
+static int
+ns32k_about_to_return (CORE_ADDR pc)
+{
+ return (read_memory_integer (pc, 1) == 0x12);
+}
+
+/* Get the address of the enter opcode for this function, if it is active.
+ Returns positive address > 1 if pc is between enter/exit,
+ 1 if pc before enter or after exit, 0 otherwise. */
+static CORE_ADDR
+ns32k_get_enter_addr (CORE_ADDR pc)
+{
+ CORE_ADDR enter_addr;
+ unsigned char op;
+
+ if (pc == 0)
+ return 0;
+
+ if (ns32k_about_to_return (pc))
+ return 1; /* after exit */
+
+ enter_addr = get_pc_function_start (pc);
+
+ if (pc == enter_addr)
+ return 1; /* before enter */
+
+ op = read_memory_integer (enter_addr, 1);
+
+ if (op != 0x82)
+ return 0; /* function has no enter/exit */
+
+ return enter_addr; /* pc is between enter and exit */
+}
+
+static CORE_ADDR
+ns32k_frame_chain (struct frame_info *frame)
+{
+ /* In the case of the NS32000 series, the frame's nominal address is the
+ FP value, and that address is saved at the previous FP value as a
+ 4-byte word. */
+
+ if (inside_entry_file (frame->pc))
+ return 0;
+
+ return (read_memory_integer (frame->frame, 4));
+}
+
+static CORE_ADDR
+ns32k_frame_saved_pc (struct frame_info *frame)
+{
+ if (frame->signal_handler_caller)
+ return (sigtramp_saved_pc (frame)); /* XXXJRT */
+
+ return (read_memory_integer (frame->frame + 4, 4));
+}
+
+static CORE_ADDR
+ns32k_frame_args_address (struct frame_info *frame)
+{
+ if (ns32k_get_enter_addr (frame->pc) > 1)
+ return (frame->frame);
+
+ return (read_register (SP_REGNUM) - 4);
+}
+
+static CORE_ADDR
+ns32k_frame_locals_address (struct frame_info *frame)
+{
+ return (frame->frame);
+}
+
+static void
+ns32k_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp,
+ struct frame_info *frame, int regnum,
+ enum lval_type *lval)
+{
+ CORE_ADDR addr;
+
+ if (!target_has_registers)
+ error ("No registers.");
+
+ /* Normal systems don't optimize out things with register numbers. */
+ if (optimized != NULL)
+ *optimized = 0;
+ addr = find_saved_register (frame, regnum);
+ if (addr != 0)
+ {
+ if (lval != NULL)
+ *lval = lval_memory;
+ if (regnum == SP_REGNUM)
+ {
+ if (raw_buffer != NULL)
+ {
+ /* Put it back in target format. */
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
+ (LONGEST) addr);
+ }
+ if (addrp != NULL)
+ *addrp = 0;
+ return;
+ }
+ if (raw_buffer != NULL)
+ target_read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum));
+ }
+ else
+ {
+ if (lval != NULL)
+ *lval = lval_register;
+ addr = REGISTER_BYTE (regnum);
+ if (raw_buffer != NULL)
+ read_register_gen (regnum, raw_buffer);
+ }
+ if (addrp != NULL)
+ *addrp = addr;
+}
+
+/* Code to initialize the addresses of the saved registers of frame described
+ by FRAME_INFO. This includes special registers such as pc and fp saved in
+ special ways in the stack frame. sp is even more special: the address we
+ return for it IS the sp for the next frame. */
+
+static void
+ns32k_frame_init_saved_regs (struct frame_info *frame)
+{
+ int regmask, regnum;
+ int localcount;
+ CORE_ADDR enter_addr, next_addr;
+
+ if (frame->saved_regs)
+ return;
+
+ frame_saved_regs_zalloc (frame);
+
+ enter_addr = ns32k_get_enter_addr (frame->pc);
+ if (enter_addr > 1)
+ {
+ regmask = read_memory_integer (enter_addr + 1, 1) & 0xff;
+ localcount = ns32k_localcount (enter_addr);
+ next_addr = frame->frame + localcount;
+
+ for (regnum = 0; regnum < 8; regnum++)
+ {
+ if (regmask & (1 << regnum))
+ frame->saved_regs[regnum] = next_addr -= 4;
+ }
+
+ frame->saved_regs[SP_REGNUM] = frame->frame + 4;
+ frame->saved_regs[PC_REGNUM] = frame->frame + 4;
+ frame->saved_regs[FP_REGNUM] = read_memory_integer (frame->frame, 4);
+ }
+ else if (enter_addr == 1)
+ {
+ CORE_ADDR sp = read_register (SP_REGNUM);
+ frame->saved_regs[PC_REGNUM] = sp;
+ frame->saved_regs[SP_REGNUM] = sp + 4;
+ }
+}
+
+static void
+ns32k_push_dummy_frame (void)
+{
+ CORE_ADDR sp = read_register (SP_REGNUM);
+ int regnum;
+
+ sp = push_word (sp, read_register (PC_REGNUM));
+ sp = push_word (sp, read_register (FP_REGNUM));
+ write_register (FP_REGNUM, sp);
+
+ for (regnum = 0; regnum < 8; regnum++)
+ sp = push_word (sp, read_register (regnum));
+
+ write_register (SP_REGNUM, sp);
+}
+
+static void
+ns32k_pop_frame (void)
+{
+ struct frame_info *frame = get_current_frame ();
+ CORE_ADDR fp;
+ int regnum;
+
+ fp = frame->frame;
+ FRAME_INIT_SAVED_REGS (frame);
+
+ for (regnum = 0; regnum < 8; regnum++)
+ if (frame->saved_regs[regnum])
+ write_register (regnum,
+ read_memory_integer (frame->saved_regs[regnum], 4));
+
+ write_register (FP_REGNUM, read_memory_integer (fp, 4));
+ write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
+ write_register (SP_REGNUM, fp + 8);
+ flush_cached_frames ();
+}
+
+/* The NS32000 call dummy sequence:
+
+ enter 0xff,0 82 ff 00
+ jsr @0x00010203 7f ae c0 01 02 03
+ adjspd 0x69696969 7f a5 01 02 03 04
+ bpt f2
+
+ It is 16 bytes long. */
+
+static LONGEST ns32k_call_dummy_words[] =
+{
+ 0x7f00ff82,
+ 0x0201c0ae,
+ 0x01a57f03,
+ 0xf2040302
+};
+static int sizeof_ns32k_call_dummy_words = sizeof (ns32k_call_dummy_words);
+
+#define NS32K_CALL_DUMMY_ADDR 5
+#define NS32K_CALL_DUMMY_NARGS 11
+
+static void
+ns32k_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+ struct value **args, struct type *type, int gcc_p)
+{
+ int flipped;
+
+ flipped = fun | 0xc0000000;
+ flip_bytes (&flipped, 4);
+ store_unsigned_integer (dummy + NS32K_CALL_DUMMY_ADDR, 4, flipped);
+
+ flipped = - nargs * 4;
+ flip_bytes (&flipped, 4);
+ store_unsigned_integer (dummy + NS32K_CALL_DUMMY_NARGS, 4, flipped);
+}
+
+static void
+ns32k_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ /* On this machine, this is a no-op (Encore Umax didn't use GCC). */
+}
+
+static void
+ns32k_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
+{
+ memcpy (valbuf,
+ regbuf + REGISTER_BYTE (TYPE_CODE (valtype) == TYPE_CODE_FLT ?
+ FP0_REGNUM : 0), TYPE_LENGTH (valtype));
+}
+
+static void
+ns32k_store_return_value (struct type *valtype, char *valbuf)
+{
+ write_register_bytes (TYPE_CODE (valtype) == TYPE_CODE_FLT ?
+ FP0_REGNUM : 0, valbuf, TYPE_LENGTH (valtype));
+}
+
+static CORE_ADDR
+ns32k_extract_struct_value_address (char *regbuf)
+{
+ return (extract_address (regbuf + REGISTER_BYTE (0), REGISTER_RAW_SIZE (0)));
+}
+
+void
+ns32k_gdbarch_init_32082 (struct gdbarch *gdbarch)
+{
+ set_gdbarch_num_regs (gdbarch, NS32K_NUM_REGS_32082);
+
+ set_gdbarch_register_name (gdbarch, ns32k_register_name_32082);
+ set_gdbarch_register_bytes (gdbarch, NS32K_REGISTER_BYTES_32082);
+ set_gdbarch_register_byte (gdbarch, ns32k_register_byte_32082);
+}
+
+void
+ns32k_gdbarch_init_32382 (struct gdbarch *gdbarch)
+{
+ set_gdbarch_num_regs (gdbarch, NS32K_NUM_REGS_32382);
+
+ set_gdbarch_register_name (gdbarch, ns32k_register_name_32382);
+ set_gdbarch_register_bytes (gdbarch, NS32K_REGISTER_BYTES_32382);
+ set_gdbarch_register_byte (gdbarch, ns32k_register_byte_32382);
+}
+
+/* Initialize the current architecture based on INFO. If possible, re-use an
+ architecture from ARCHES, which is a list of architectures already created
+ during this debugging session.
+
+ Called e.g. at program startup, when reading a core file, and when reading
+ a binary file. */
+
+static struct gdbarch *
+ns32k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch_tdep *tdep;
+ struct gdbarch *gdbarch;
+ enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
+
+ /* Try to determine the OS ABI of the object we are loading. */
+ if (info.abfd != NULL)
+ {
+ osabi = gdbarch_lookup_osabi (info.abfd);
+ }
+
+ /* Find a candidate among extant architectures. */
+ for (arches = gdbarch_list_lookup_by_info (arches, &info);
+ arches != NULL;
+ arches = gdbarch_list_lookup_by_info (arches->next, &info))
+ {
+ /* Make sure the OS ABI selection matches. */
+ tdep = gdbarch_tdep (arches->gdbarch);
+ if (tdep && tdep->osabi == osabi)
+ return arches->gdbarch;
+ }
+
+ tdep = xmalloc (sizeof (struct gdbarch_tdep));
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ tdep->osabi = osabi;
+
+ /* Register info */
+ ns32k_gdbarch_init_32082 (gdbarch);
+ set_gdbarch_num_regs (gdbarch, NS32K_SP_REGNUM);
+ set_gdbarch_num_regs (gdbarch, NS32K_FP_REGNUM);
+ set_gdbarch_num_regs (gdbarch, NS32K_PC_REGNUM);
+ set_gdbarch_num_regs (gdbarch, NS32K_PS_REGNUM);
+
+ set_gdbarch_register_size (gdbarch, NS32K_REGISTER_SIZE);
+ set_gdbarch_register_raw_size (gdbarch, ns32k_register_raw_size);
+ set_gdbarch_max_register_raw_size (gdbarch, NS32K_MAX_REGISTER_RAW_SIZE);
+ set_gdbarch_register_virtual_size (gdbarch, ns32k_register_virtual_size);
+ set_gdbarch_max_register_virtual_size (gdbarch,
+ NS32K_MAX_REGISTER_VIRTUAL_SIZE);
+ set_gdbarch_register_virtual_type (gdbarch, ns32k_register_virtual_type);
+
+ /* Frame and stack info */
+ set_gdbarch_skip_prologue (gdbarch, umax_skip_prologue);
+ set_gdbarch_saved_pc_after_call (gdbarch, ns32k_saved_pc_after_call);
+
+ set_gdbarch_frame_num_args (gdbarch, umax_frame_num_args);
+ set_gdbarch_frameless_function_invocation (gdbarch,
+ generic_frameless_function_invocation_not);
+
+ set_gdbarch_frame_chain (gdbarch, ns32k_frame_chain);
+ set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
+ set_gdbarch_frame_saved_pc (gdbarch, ns32k_frame_saved_pc);
+
+ set_gdbarch_frame_args_address (gdbarch, ns32k_frame_args_address);
+ set_gdbarch_frame_locals_address (gdbarch, ns32k_frame_locals_address);
+
+ set_gdbarch_frame_init_saved_regs (gdbarch, ns32k_frame_init_saved_regs);
+
+ set_gdbarch_frame_args_skip (gdbarch, 8);
+
+ set_gdbarch_get_saved_register (gdbarch, ns32k_get_saved_register);
+
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+
+ /* Return value info */
+ set_gdbarch_store_struct_return (gdbarch, ns32k_store_struct_return);
+ set_gdbarch_extract_return_value (gdbarch, ns32k_extract_return_value);
+ set_gdbarch_store_return_value (gdbarch, ns32k_store_return_value);
+ set_gdbarch_extract_struct_value_address (gdbarch,
+ ns32k_extract_struct_value_address);
+
+ /* Call dummy info */
+ set_gdbarch_push_dummy_frame (gdbarch, ns32k_push_dummy_frame);
+ set_gdbarch_pop_frame (gdbarch, ns32k_pop_frame);
+ set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_words (gdbarch, ns32k_call_dummy_words);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof_ns32k_call_dummy_words);
+ set_gdbarch_fix_call_dummy (gdbarch, ns32k_fix_call_dummy);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 3);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 0);
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+
+ /* Breakpoint info */
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+ set_gdbarch_breakpoint_from_pc (gdbarch, ns32k_breakpoint_from_pc);
+
+ /* Misc info */
+ set_gdbarch_function_start_offset (gdbarch, 0);
+
+ /* Hook in OS ABI-specific overrides, if they have been registered. */
+ gdbarch_init_osabi (info, gdbarch, osabi);
+
+ return (gdbarch);
+}
+
+static void
+ns32k_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (tdep == NULL)
+ return;
+
+ fprintf_unfiltered (file, "ns32k_dump_tdep: OS ABI = %s\n",
+ gdbarch_osabi_name (tdep->osabi));
+}
+
+void
+_initialize_ns32k_tdep (void)
+{
+ gdbarch_register (bfd_arch_ns32k, ns32k_gdbarch_init, ns32k_dump_tdep);
+
+ tm_print_insn = print_insn_ns32k;
+}
diff --git a/gdb/ns32k-tdep.h b/gdb/ns32k-tdep.h
new file mode 100644
index 00000000000..c0463247f47
--- /dev/null
+++ b/gdb/ns32k-tdep.h
@@ -0,0 +1,66 @@
+/* Target-dependent definitions for GDB on NS32000 systems.
+ Copyright 1987, 1989, 1991, 1993, 1994, 1998, 1999, 2000, 2001, 2002
+ 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. */
+
+#ifndef NS32K_TDEP_H
+#define NS32K_TDEP_H
+
+#include "osabi.h"
+
+/* Register numbers of various important registers.
+ Note that some of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and some are "phony" register numbers which are too large
+ to be actual register numbers as far as the user is concerned
+ but do serve to get the desired values when passed to read_register. */
+
+#define NS32K_R0_REGNUM 0 /* General register 0 */
+#define NS32K_FP0_REGNUM 8 /* Floating point register 0 */
+#define NS32K_SP_REGNUM 16 /* Contains address of top of stack */
+#define NS32K_AP_REGNUM NS32K_FP_REGNUM
+#define NS32K_FP_REGNUM 17 /* Contains address of executing stack frame */
+#define NS32K_PC_REGNUM 18 /* Contains program counter */
+#define NS32K_PS_REGNUM 19 /* Contains processor status */
+#define NS32K_FPS_REGNUM 20 /* Floating point status register */
+#define NS32K_LP0_REGNUM 21 /* Double register 0 (same as FP0) */
+
+#define NS32K_NUM_REGS_32082 25
+#define NS32K_REGISTER_BYTES_32082 \
+ ((NS32K_NUM_REGS_32082 - 4) * 4 /* size of general purpose regs */ \
+ + 4 * 8 /* size of floating point regs */)
+
+#define NS32K_NUM_REGS_32382 29
+#define NS32K_REGISTER_BYTES_32382 \
+ ((NS32K_NUM_REGS_32382 - 4) * 4 /* size of general purpose regs */ \
+ + 8 * 8 /* size of floating point regs */)
+
+#define NS32K_REGISTER_SIZE 4
+#define NS32K_MAX_REGISTER_RAW_SIZE 8
+#define NS32K_MAX_REGISTER_VIRTUAL_SIZE 8
+
+struct gdbarch_tdep
+{
+ enum gdb_osabi osabi;
+};
+
+void ns32k_gdbarch_init_32082 (struct gdbarch *);
+void ns32k_gdbarch_init_32382 (struct gdbarch *);
+
+#endif /* NS32K_TDEP_H */
diff --git a/gdb/ns32knbsd-nat.c b/gdb/ns32knbsd-nat.c
new file mode 100644
index 00000000000..fd6e6197efc
--- /dev/null
+++ b/gdb/ns32knbsd-nat.c
@@ -0,0 +1,364 @@
+/* Functions specific to running gdb native on an ns32k running NetBSD
+ Copyright 1989, 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001
+ 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 <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+
+#include "defs.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#define RF(dst, src) \
+ memcpy(&registers[REGISTER_BYTE(dst)], &src, sizeof(src))
+
+#define RS(src, dst) \
+ memcpy(&dst, &registers[REGISTER_BYTE(src)], sizeof(dst))
+
+void
+fetch_inferior_registers (int regno)
+{
+ struct reg inferior_registers;
+ struct fpreg inferior_fpregisters;
+
+ ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0);
+ ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_fpregisters, 0);
+
+ RF (R0_REGNUM + 0, inferior_registers.r_r0);
+ RF (R0_REGNUM + 1, inferior_registers.r_r1);
+ RF (R0_REGNUM + 2, inferior_registers.r_r2);
+ RF (R0_REGNUM + 3, inferior_registers.r_r3);
+ RF (R0_REGNUM + 4, inferior_registers.r_r4);
+ RF (R0_REGNUM + 5, inferior_registers.r_r5);
+ RF (R0_REGNUM + 6, inferior_registers.r_r6);
+ RF (R0_REGNUM + 7, inferior_registers.r_r7);
+
+ RF (SP_REGNUM, inferior_registers.r_sp);
+ RF (FP_REGNUM, inferior_registers.r_fp);
+ RF (PC_REGNUM, inferior_registers.r_pc);
+ RF (PS_REGNUM, inferior_registers.r_psr);
+
+ RF (FPS_REGNUM, inferior_fpregisters.r_fsr);
+ RF (FP0_REGNUM + 0, inferior_fpregisters.r_freg[0]);
+ RF (FP0_REGNUM + 2, inferior_fpregisters.r_freg[2]);
+ RF (FP0_REGNUM + 4, inferior_fpregisters.r_freg[4]);
+ RF (FP0_REGNUM + 6, inferior_fpregisters.r_freg[6]);
+ RF (LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]);
+ RF (LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]);
+ RF (LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]);
+ RF (LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]);
+ registers_fetched ();
+}
+
+void
+store_inferior_registers (int regno)
+{
+ struct reg inferior_registers;
+ struct fpreg inferior_fpregisters;
+
+ RS (R0_REGNUM + 0, inferior_registers.r_r0);
+ RS (R0_REGNUM + 1, inferior_registers.r_r1);
+ RS (R0_REGNUM + 2, inferior_registers.r_r2);
+ RS (R0_REGNUM + 3, inferior_registers.r_r3);
+ RS (R0_REGNUM + 4, inferior_registers.r_r4);
+ RS (R0_REGNUM + 5, inferior_registers.r_r5);
+ RS (R0_REGNUM + 6, inferior_registers.r_r6);
+ RS (R0_REGNUM + 7, inferior_registers.r_r7);
+
+ RS (SP_REGNUM, inferior_registers.r_sp);
+ RS (FP_REGNUM, inferior_registers.r_fp);
+ RS (PC_REGNUM, inferior_registers.r_pc);
+ RS (PS_REGNUM, inferior_registers.r_psr);
+
+ RS (FPS_REGNUM, inferior_fpregisters.r_fsr);
+ RS (FP0_REGNUM + 0, inferior_fpregisters.r_freg[0]);
+ RS (FP0_REGNUM + 2, inferior_fpregisters.r_freg[2]);
+ RS (FP0_REGNUM + 4, inferior_fpregisters.r_freg[4]);
+ RS (FP0_REGNUM + 6, inferior_fpregisters.r_freg[6]);
+ RS (LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]);
+ RS (LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]);
+ RS (LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]);
+ RS (LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]);
+
+ ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0);
+ ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_fpregisters, 0);
+}
+
+
+/* XXX - Add this to machine/regs.h instead? */
+struct coreregs
+{
+ struct reg intreg;
+ struct fpreg freg;
+};
+
+/* Get registers from a core file. REG_ADDR is unused. */
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ unsigned int reg_addr)
+{
+ struct coreregs *core_reg;
+
+ core_reg = (struct coreregs *) core_reg_sect;
+
+ /*
+ * We have *all* registers
+ * in the first core section.
+ * Ignore which.
+ */
+
+ if (core_reg_size < sizeof (*core_reg))
+ {
+ fprintf_unfiltered (gdb_stderr, "Couldn't read regs from core file\n");
+ return;
+ }
+
+ /* Integer registers */
+ RF (R0_REGNUM + 0, core_reg->intreg.r_r0);
+ RF (R0_REGNUM + 1, core_reg->intreg.r_r1);
+ RF (R0_REGNUM + 2, core_reg->intreg.r_r2);
+ RF (R0_REGNUM + 3, core_reg->intreg.r_r3);
+ RF (R0_REGNUM + 4, core_reg->intreg.r_r4);
+ RF (R0_REGNUM + 5, core_reg->intreg.r_r5);
+ RF (R0_REGNUM + 6, core_reg->intreg.r_r6);
+ RF (R0_REGNUM + 7, core_reg->intreg.r_r7);
+
+ RF (SP_REGNUM, core_reg->intreg.r_sp);
+ RF (FP_REGNUM, core_reg->intreg.r_fp);
+ RF (PC_REGNUM, core_reg->intreg.r_pc);
+ RF (PS_REGNUM, core_reg->intreg.r_psr);
+
+ /* Floating point registers */
+ RF (FPS_REGNUM, core_reg->freg.r_fsr);
+ RF (FP0_REGNUM + 0, core_reg->freg.r_freg[0]);
+ RF (FP0_REGNUM + 2, core_reg->freg.r_freg[2]);
+ RF (FP0_REGNUM + 4, core_reg->freg.r_freg[4]);
+ RF (FP0_REGNUM + 6, core_reg->freg.r_freg[6]);
+ RF (LP0_REGNUM + 1, core_reg->freg.r_freg[1]);
+ RF (LP0_REGNUM + 3, core_reg->freg.r_freg[3]);
+ RF (LP0_REGNUM + 5, core_reg->freg.r_freg[5]);
+ RF (LP0_REGNUM + 7, core_reg->freg.r_freg[7]);
+ registers_fetched ();
+}
+
+/* Register that we are able to handle ns32knbsd core file formats.
+ FIXME: is this really bfd_target_unknown_flavour? */
+
+static struct core_fns nat_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_ns32knbsd_nat (void)
+{
+ add_core_fns (&nat_core_fns);
+}
+
+
+/*
+ * kernel_u_size() is not helpful on NetBSD because
+ * the "u" struct is NOT in the core dump file.
+ */
+
+#ifdef FETCH_KCORE_REGISTERS
+/*
+ * Get registers from a kernel crash dump or live kernel.
+ * Called by kcore-nbsd.c:get_kcore_registers().
+ */
+void
+fetch_kcore_registers (struct pcb *pcb)
+{
+ struct switchframe sf;
+ struct reg intreg;
+ int dummy;
+
+ /* Integer registers */
+ if (target_read_memory ((CORE_ADDR) pcb->pcb_ksp, (char *) &sf, sizeof sf))
+ error ("Cannot read integer registers.");
+
+ /* We use the psr at kernel entry */
+ if (target_read_memory ((CORE_ADDR) pcb->pcb_onstack, (char *) &intreg, sizeof intreg))
+ error ("Cannot read processor status register.");
+
+ dummy = 0;
+ RF (R0_REGNUM + 0, dummy);
+ RF (R0_REGNUM + 1, dummy);
+ RF (R0_REGNUM + 2, dummy);
+ RF (R0_REGNUM + 3, sf.sf_r3);
+ RF (R0_REGNUM + 4, sf.sf_r4);
+ RF (R0_REGNUM + 5, sf.sf_r5);
+ RF (R0_REGNUM + 6, sf.sf_r6);
+ RF (R0_REGNUM + 7, sf.sf_r7);
+
+ dummy = pcb->pcb_kfp + 8;
+ RF (SP_REGNUM, dummy);
+ RF (FP_REGNUM, sf.sf_fp);
+ RF (PC_REGNUM, sf.sf_pc);
+ RF (PS_REGNUM, intreg.r_psr);
+
+ /* Floating point registers */
+ RF (FPS_REGNUM, pcb->pcb_fsr);
+ RF (FP0_REGNUM + 0, pcb->pcb_freg[0]);
+ RF (FP0_REGNUM + 2, pcb->pcb_freg[2]);
+ RF (FP0_REGNUM + 4, pcb->pcb_freg[4]);
+ RF (FP0_REGNUM + 6, pcb->pcb_freg[6]);
+ RF (LP0_REGNUM + 1, pcb->pcb_freg[1]);
+ RF (LP0_REGNUM + 3, pcb->pcb_freg[3]);
+ RF (LP0_REGNUM + 5, pcb->pcb_freg[5]);
+ RF (LP0_REGNUM + 7, pcb->pcb_freg[7]);
+ registers_fetched ();
+}
+#endif /* FETCH_KCORE_REGISTERS */
+
+void
+clear_regs (void)
+{
+ double zero = 0.0;
+ int null = 0;
+
+ /* Integer registers */
+ RF (R0_REGNUM + 0, null);
+ RF (R0_REGNUM + 1, null);
+ RF (R0_REGNUM + 2, null);
+ RF (R0_REGNUM + 3, null);
+ RF (R0_REGNUM + 4, null);
+ RF (R0_REGNUM + 5, null);
+ RF (R0_REGNUM + 6, null);
+ RF (R0_REGNUM + 7, null);
+
+ RF (SP_REGNUM, null);
+ RF (FP_REGNUM, null);
+ RF (PC_REGNUM, null);
+ RF (PS_REGNUM, null);
+
+ /* Floating point registers */
+ RF (FPS_REGNUM, zero);
+ RF (FP0_REGNUM + 0, zero);
+ RF (FP0_REGNUM + 2, zero);
+ RF (FP0_REGNUM + 4, zero);
+ RF (FP0_REGNUM + 6, zero);
+ RF (LP0_REGNUM + 0, zero);
+ RF (LP0_REGNUM + 1, zero);
+ RF (LP0_REGNUM + 2, zero);
+ RF (LP0_REGNUM + 3, zero);
+ return;
+}
+
+/* Return number of args passed to a frame.
+ Can return -1, meaning no way to tell. */
+
+int
+frame_num_args (struct frame_info *fi)
+{
+ CORE_ADDR enter_addr;
+ CORE_ADDR argp;
+ int inst;
+ int args;
+ int i;
+
+ if (read_memory_integer (fi->frame, 4) == 0 && fi->pc < 0x10000)
+ {
+ /* main is always called with three args */
+ return (3);
+ }
+ enter_addr = ns32k_get_enter_addr (fi->pc);
+ if (enter_addr = 0)
+ return (-1);
+ argp = enter_addr == 1 ? SAVED_PC_AFTER_CALL (fi) : FRAME_SAVED_PC (fi);
+ for (i = 0; i < 16; i++)
+ {
+ /*
+ * After a bsr gcc may emit the following instructions
+ * to remove the arguments from the stack:
+ * cmpqd 0,tos - to remove 4 bytes from the stack
+ * cmpd tos,tos - to remove 8 bytes from the stack
+ * adjsp[bwd] -n - to remove n bytes from the stack
+ * Gcc sometimes delays emitting these instructions and
+ * may even throw a branch between our feet.
+ */
+ inst = read_memory_integer (argp, 4);
+ args = read_memory_integer (argp + 2, 4);
+ if ((inst & 0xff) == 0xea)
+ { /* br */
+ args = ((inst >> 8) & 0xffffff) | (args << 24);
+ if (args & 0x80)
+ {
+ if (args & 0x40)
+ {
+ args = ntohl (args);
+ }
+ else
+ {
+ args = ntohs (args & 0xffff);
+ if (args & 0x2000)
+ args |= 0xc000;
+ }
+ }
+ else
+ {
+ args = args & 0xff;
+ if (args & 0x40)
+ args |= 0x80;
+ }
+ argp += args;
+ continue;
+ }
+ if ((inst & 0xffff) == 0xb81f) /* cmpqd 0,tos */
+ return (1);
+ else if ((inst & 0xffff) == 0xbdc7) /* cmpd tos,tos */
+ return (2);
+ else if ((inst & 0xfffc) == 0xa57c)
+ { /* adjsp[bwd] */
+ switch (inst & 3)
+ {
+ case 0:
+ args = ((args & 0xff) + 0x80);
+ break;
+ case 1:
+ args = ((ntohs (args) & 0xffff) + 0x8000);
+ break;
+ case 3:
+ args = -ntohl (args);
+ break;
+ default:
+ return (-1);
+ }
+ if (args / 4 > 10 || (args & 3) != 0)
+ continue;
+ return (args / 4);
+ }
+ argp += 1;
+ }
+ return (-1);
+}
diff --git a/gdb/ns32knbsd-tdep.c b/gdb/ns32knbsd-tdep.c
new file mode 100644
index 00000000000..1ca0b3b39ac
--- /dev/null
+++ b/gdb/ns32knbsd-tdep.c
@@ -0,0 +1,70 @@
+/* Target-dependent code for NS32000 systems running NetBSD.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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 "defs.h"
+
+#include "ns32k-tdep.h"
+
+static int
+ns32knbsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+ if (strcmp (name, "_DYNAMIC") == 0)
+ return 1;
+
+ return 0;
+}
+
+static void
+ns32knbsd_init_abi_common (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ /* We only support machines with the 32382 FPU. */
+ ns32k_gdbarch_init_32382 (gdbarch);
+}
+
+static void
+ns32knbsd_init_abi_aout (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ ns32knbsd_init_abi_common (info, gdbarch);
+
+ set_gdbarch_in_solib_call_trampoline (gdbarch,
+ ns32knbsd_aout_in_solib_call_trampoline);
+}
+
+static enum gdb_osabi
+ns32knbsd_aout_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "a.out-ns32k-netbsd") == 0)
+ return GDB_OSABI_NETBSD_AOUT;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+void
+_initialize_ns32knbsd_tdep (void)
+{
+ gdbarch_register_osabi_sniffer (bfd_arch_ns32k, bfd_target_aout_flavour,
+ ns32knbsd_aout_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_ns32k, GDB_OSABI_NETBSD_AOUT,
+ ns32knbsd_init_abi_aout);
+}
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
new file mode 100644
index 00000000000..32bda87b91d
--- /dev/null
+++ b/gdb/objfiles.c
@@ -0,0 +1,1010 @@
+/* GDB routines for manipulating objfiles.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support, using pieces from other GDB modules.
+
+ 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. */
+
+/* This file contains support routines for creating, manipulating, and
+ destroying objfile structures. */
+
+#include "defs.h"
+#include "bfd.h" /* Binary File Description */
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include "target.h"
+
+#include <sys/types.h>
+#include "gdb_stat.h"
+#include <fcntl.h>
+#include "obstack.h"
+#include "gdb_string.h"
+
+#include "breakpoint.h"
+
+/* Prototypes for local functions */
+
+#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
+
+#include "mmalloc.h"
+
+static int open_existing_mapped_file (char *, long, int);
+
+static int open_mapped_file (char *filename, long mtime, int flags);
+
+static PTR map_to_file (int);
+
+#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
+
+static void add_to_objfile_sections (bfd *, sec_ptr, PTR);
+
+/* Externally visible variables that are owned by this module.
+ See declarations in objfile.h for more info. */
+
+struct objfile *object_files; /* Linked list of all objfiles */
+struct objfile *current_objfile; /* For symbol file being read in */
+struct objfile *symfile_objfile; /* Main symbol table loaded from */
+struct objfile *rt_common_objfile; /* For runtime common symbols */
+
+int mapped_symbol_files; /* Try to use mapped symbol files */
+
+/* Locate all mappable sections of a BFD file.
+ objfile_p_char is a char * to get it through
+ bfd_map_over_sections; we cast it back to its proper type. */
+
+#ifndef TARGET_KEEP_SECTION
+#define TARGET_KEEP_SECTION(ASECT) 0
+#endif
+
+/* Called via bfd_map_over_sections to build up the section table that
+ the objfile references. The objfile contains pointers to the start
+ of the table (objfile->sections) and to the first location after
+ the end of the table (objfile->sections_end). */
+
+static void
+add_to_objfile_sections (bfd *abfd, sec_ptr asect, PTR objfile_p_char)
+{
+ struct objfile *objfile = (struct objfile *) objfile_p_char;
+ struct obj_section section;
+ flagword aflag;
+
+ aflag = bfd_get_section_flags (abfd, asect);
+
+ if (!(aflag & SEC_ALLOC) && !(TARGET_KEEP_SECTION (asect)))
+ return;
+
+ if (0 == bfd_section_size (abfd, asect))
+ return;
+ section.offset = 0;
+ section.objfile = objfile;
+ section.the_bfd_section = asect;
+ section.ovly_mapped = 0;
+ section.addr = bfd_section_vma (abfd, asect);
+ section.endaddr = section.addr + bfd_section_size (abfd, asect);
+ obstack_grow (&objfile->psymbol_obstack, (char *) &section, sizeof (section));
+ objfile->sections_end = (struct obj_section *) (((unsigned long) objfile->sections_end) + 1);
+}
+
+/* Builds a section table for OBJFILE.
+ Returns 0 if OK, 1 on error (in which case bfd_error contains the
+ error).
+
+ Note that while we are building the table, which goes into the
+ psymbol obstack, we hijack the sections_end pointer to instead hold
+ a count of the number of sections. When bfd_map_over_sections
+ returns, this count is used to compute the pointer to the end of
+ the sections table, which then overwrites the count.
+
+ Also note that the OFFSET and OVLY_MAPPED in each table entry
+ are initialized to zero.
+
+ Also note that if anything else writes to the psymbol obstack while
+ we are building the table, we're pretty much hosed. */
+
+int
+build_objfile_section_table (struct objfile *objfile)
+{
+ /* objfile->sections can be already set when reading a mapped symbol
+ file. I believe that we do need to rebuild the section table in
+ this case (we rebuild other things derived from the bfd), but we
+ can't free the old one (it's in the psymbol_obstack). So we just
+ waste some memory. */
+
+ objfile->sections_end = 0;
+ bfd_map_over_sections (objfile->obfd, add_to_objfile_sections, (char *) objfile);
+ objfile->sections = (struct obj_section *)
+ obstack_finish (&objfile->psymbol_obstack);
+ objfile->sections_end = objfile->sections + (unsigned long) objfile->sections_end;
+ return (0);
+}
+
+/* Given a pointer to an initialized bfd (ABFD) and some flag bits
+ allocate a new objfile struct, fill it in as best we can, link it
+ into the list of all known objfiles, and return a pointer to the
+ new objfile struct.
+
+ The FLAGS word contains various bits (OBJF_*) that can be taken as
+ requests for specific operations, like trying to open a mapped
+ version of the objfile (OBJF_MAPPED). Other bits like
+ OBJF_SHARED are simply copied through to the new objfile flags
+ member. */
+
+struct objfile *
+allocate_objfile (bfd *abfd, int flags)
+{
+ struct objfile *objfile = NULL;
+ struct objfile *last_one = NULL;
+
+ if (mapped_symbol_files)
+ flags |= OBJF_MAPPED;
+
+#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
+ if (abfd != NULL)
+ {
+
+ /* If we can support mapped symbol files, try to open/reopen the
+ mapped file that corresponds to the file from which we wish to
+ read symbols. If the objfile is to be mapped, we must malloc
+ the structure itself using the mmap version, and arrange that
+ all memory allocation for the objfile uses the mmap routines.
+ If we are reusing an existing mapped file, from which we get
+ our objfile pointer, we have to make sure that we update the
+ pointers to the alloc/free functions in the obstack, in case
+ these functions have moved within the current gdb. */
+
+ int fd;
+
+ fd = open_mapped_file (bfd_get_filename (abfd), bfd_get_mtime (abfd),
+ flags);
+ if (fd >= 0)
+ {
+ PTR md;
+
+ if ((md = map_to_file (fd)) == NULL)
+ {
+ close (fd);
+ }
+ else if ((objfile = (struct objfile *) mmalloc_getkey (md, 0)) != NULL)
+ {
+ /* Update memory corruption handler function addresses. */
+ init_malloc (md);
+ objfile->md = md;
+ objfile->mmfd = fd;
+ /* Update pointers to functions to *our* copies */
+ obstack_chunkfun (&objfile->psymbol_cache.cache, xmmalloc);
+ obstack_freefun (&objfile->psymbol_cache.cache, xmfree);
+ obstack_chunkfun (&objfile->macro_cache.cache, xmmalloc);
+ obstack_freefun (&objfile->macro_cache.cache, xmfree);
+ obstack_chunkfun (&objfile->psymbol_obstack, xmmalloc);
+ obstack_freefun (&objfile->psymbol_obstack, xmfree);
+ obstack_chunkfun (&objfile->symbol_obstack, xmmalloc);
+ obstack_freefun (&objfile->symbol_obstack, xmfree);
+ obstack_chunkfun (&objfile->type_obstack, xmmalloc);
+ obstack_freefun (&objfile->type_obstack, xmfree);
+ /* If already in objfile list, unlink it. */
+ unlink_objfile (objfile);
+ /* Forget things specific to a particular gdb, may have changed. */
+ objfile->sf = NULL;
+ }
+ else
+ {
+
+ /* Set up to detect internal memory corruption. MUST be
+ done before the first malloc. See comments in
+ init_malloc() and mmcheck(). */
+
+ init_malloc (md);
+
+ objfile = (struct objfile *)
+ xmmalloc (md, sizeof (struct objfile));
+ memset (objfile, 0, sizeof (struct objfile));
+ objfile->md = md;
+ objfile->mmfd = fd;
+ objfile->flags |= OBJF_MAPPED;
+ mmalloc_setkey (objfile->md, 0, objfile);
+ obstack_specify_allocation_with_arg (&objfile->psymbol_cache.cache,
+ 0, 0, xmmalloc, xmfree,
+ objfile->md);
+ obstack_specify_allocation_with_arg (&objfile->macro_cache.cache,
+ 0, 0, xmmalloc, xmfree,
+ objfile->md);
+ obstack_specify_allocation_with_arg (&objfile->psymbol_obstack,
+ 0, 0, xmmalloc, xmfree,
+ objfile->md);
+ obstack_specify_allocation_with_arg (&objfile->symbol_obstack,
+ 0, 0, xmmalloc, xmfree,
+ objfile->md);
+ obstack_specify_allocation_with_arg (&objfile->type_obstack,
+ 0, 0, xmmalloc, xmfree,
+ objfile->md);
+ }
+ }
+
+ if ((flags & OBJF_MAPPED) && (objfile == NULL))
+ {
+ warning ("symbol table for '%s' will not be mapped",
+ bfd_get_filename (abfd));
+ flags &= ~OBJF_MAPPED;
+ }
+ }
+#else /* !defined(USE_MMALLOC) || !defined(HAVE_MMAP) */
+
+ if (flags & OBJF_MAPPED)
+ {
+ warning ("mapped symbol tables are not supported on this machine; missing or broken mmap().");
+
+ /* Turn off the global flag so we don't try to do mapped symbol tables
+ any more, which shuts up gdb unless the user specifically gives the
+ "mapped" keyword again. */
+
+ mapped_symbol_files = 0;
+ flags &= ~OBJF_MAPPED;
+ }
+
+#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
+
+ /* If we don't support mapped symbol files, didn't ask for the file to be
+ mapped, or failed to open the mapped file for some reason, then revert
+ back to an unmapped objfile. */
+
+ if (objfile == NULL)
+ {
+ objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
+ memset (objfile, 0, sizeof (struct objfile));
+ objfile->md = NULL;
+ obstack_specify_allocation (&objfile->psymbol_cache.cache, 0, 0,
+ xmalloc, xfree);
+ obstack_specify_allocation (&objfile->macro_cache.cache, 0, 0,
+ xmalloc, xfree);
+ obstack_specify_allocation (&objfile->psymbol_obstack, 0, 0, xmalloc,
+ xfree);
+ obstack_specify_allocation (&objfile->symbol_obstack, 0, 0, xmalloc,
+ xfree);
+ obstack_specify_allocation (&objfile->type_obstack, 0, 0, xmalloc,
+ xfree);
+ flags &= ~OBJF_MAPPED;
+ }
+
+ /* Update the per-objfile information that comes from the bfd, ensuring
+ that any data that is reference is saved in the per-objfile data
+ region. */
+
+ objfile->obfd = abfd;
+ if (objfile->name != NULL)
+ {
+ xmfree (objfile->md, objfile->name);
+ }
+ if (abfd != NULL)
+ {
+ objfile->name = mstrsave (objfile->md, bfd_get_filename (abfd));
+ objfile->mtime = bfd_get_mtime (abfd);
+
+ /* Build section table. */
+
+ if (build_objfile_section_table (objfile))
+ {
+ error ("Can't find the file sections in `%s': %s",
+ objfile->name, bfd_errmsg (bfd_get_error ()));
+ }
+ }
+
+ /* Initialize the section indexes for this objfile, so that we can
+ later detect if they are used w/o being properly assigned to. */
+
+ objfile->sect_index_text = -1;
+ objfile->sect_index_data = -1;
+ objfile->sect_index_bss = -1;
+ objfile->sect_index_rodata = -1;
+
+ /* Add this file onto the tail of the linked list of other such files. */
+
+ objfile->next = NULL;
+ if (object_files == NULL)
+ object_files = objfile;
+ else
+ {
+ for (last_one = object_files;
+ last_one->next;
+ last_one = last_one->next);
+ last_one->next = objfile;
+ }
+
+ /* Save passed in flag bits. */
+ objfile->flags |= flags;
+
+ return (objfile);
+}
+
+/* Put OBJFILE at the front of the list. */
+
+void
+objfile_to_front (struct objfile *objfile)
+{
+ struct objfile **objp;
+ for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
+ {
+ if (*objp == objfile)
+ {
+ /* Unhook it from where it is. */
+ *objp = objfile->next;
+ /* Put it in the front. */
+ objfile->next = object_files;
+ object_files = objfile;
+ break;
+ }
+ }
+}
+
+/* Unlink OBJFILE from the list of known objfiles, if it is found in the
+ list.
+
+ It is not a bug, or error, to call this function if OBJFILE is not known
+ to be in the current list. This is done in the case of mapped objfiles,
+ for example, just to ensure that the mapped objfile doesn't appear twice
+ in the list. Since the list is threaded, linking in a mapped objfile
+ twice would create a circular list.
+
+ If OBJFILE turns out to be in the list, we zap it's NEXT pointer after
+ unlinking it, just to ensure that we have completely severed any linkages
+ between the OBJFILE and the list. */
+
+void
+unlink_objfile (struct objfile *objfile)
+{
+ struct objfile **objpp;
+
+ for (objpp = &object_files; *objpp != NULL; objpp = &((*objpp)->next))
+ {
+ if (*objpp == objfile)
+ {
+ *objpp = (*objpp)->next;
+ objfile->next = NULL;
+ return;
+ }
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "unlink_objfile: objfile already unlinked");
+}
+
+
+/* Destroy an objfile and all the symtabs and psymtabs under it. Note
+ that as much as possible is allocated on the symbol_obstack and
+ psymbol_obstack, so that the memory can be efficiently freed.
+
+ Things which we do NOT free because they are not in malloc'd memory
+ or not in memory specific to the objfile include:
+
+ objfile -> sf
+
+ FIXME: If the objfile is using reusable symbol information (via mmalloc),
+ then we need to take into account the fact that more than one process
+ may be using the symbol information at the same time (when mmalloc is
+ extended to support cooperative locking). When more than one process
+ is using the mapped symbol info, we need to be more careful about when
+ we free objects in the reusable area. */
+
+void
+free_objfile (struct objfile *objfile)
+{
+ /* First do any symbol file specific actions required when we are
+ finished with a particular symbol file. Note that if the objfile
+ is using reusable symbol information (via mmalloc) then each of
+ these routines is responsible for doing the correct thing, either
+ freeing things which are valid only during this particular gdb
+ execution, or leaving them to be reused during the next one. */
+
+ if (objfile->sf != NULL)
+ {
+ (*objfile->sf->sym_finish) (objfile);
+ }
+
+ /* We always close the bfd. */
+
+ if (objfile->obfd != NULL)
+ {
+ char *name = bfd_get_filename (objfile->obfd);
+ if (!bfd_close (objfile->obfd))
+ warning ("cannot close \"%s\": %s",
+ name, bfd_errmsg (bfd_get_error ()));
+ xfree (name);
+ }
+
+ /* Remove it from the chain of all objfiles. */
+
+ unlink_objfile (objfile);
+
+ /* If we are going to free the runtime common objfile, mark it
+ as unallocated. */
+
+ if (objfile == rt_common_objfile)
+ rt_common_objfile = NULL;
+
+ /* Before the symbol table code was redone to make it easier to
+ selectively load and remove information particular to a specific
+ linkage unit, gdb used to do these things whenever the monolithic
+ symbol table was blown away. How much still needs to be done
+ is unknown, but we play it safe for now and keep each action until
+ it is shown to be no longer needed. */
+
+ /* I *think* all our callers call clear_symtab_users. If so, no need
+ to call this here. */
+ clear_pc_function_cache ();
+
+ /* The last thing we do is free the objfile struct itself for the
+ non-reusable case, or detach from the mapped file for the
+ reusable case. Note that the mmalloc_detach or the xmfree() is
+ the last thing we can do with this objfile. */
+
+#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
+
+ if (objfile->flags & OBJF_MAPPED)
+ {
+ /* Remember the fd so we can close it. We can't close it before
+ doing the detach, and after the detach the objfile is gone. */
+ int mmfd;
+
+ mmfd = objfile->mmfd;
+ mmalloc_detach (objfile->md);
+ objfile = NULL;
+ close (mmfd);
+ }
+
+#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
+
+ /* If we still have an objfile, then either we don't support reusable
+ objfiles or this one was not reusable. So free it normally. */
+
+ if (objfile != NULL)
+ {
+ if (objfile->name != NULL)
+ {
+ xmfree (objfile->md, objfile->name);
+ }
+ if (objfile->global_psymbols.list)
+ xmfree (objfile->md, objfile->global_psymbols.list);
+ if (objfile->static_psymbols.list)
+ xmfree (objfile->md, objfile->static_psymbols.list);
+ /* Free the obstacks for non-reusable objfiles */
+ free_bcache (&objfile->psymbol_cache);
+ free_bcache (&objfile->macro_cache);
+ obstack_free (&objfile->psymbol_obstack, 0);
+ obstack_free (&objfile->symbol_obstack, 0);
+ obstack_free (&objfile->type_obstack, 0);
+ xmfree (objfile->md, objfile);
+ objfile = NULL;
+ }
+}
+
+static void
+do_free_objfile_cleanup (void *obj)
+{
+ free_objfile (obj);
+}
+
+struct cleanup *
+make_cleanup_free_objfile (struct objfile *obj)
+{
+ return make_cleanup (do_free_objfile_cleanup, obj);
+}
+
+/* Free all the object files at once and clean up their users. */
+
+void
+free_all_objfiles (void)
+{
+ struct objfile *objfile, *temp;
+
+ ALL_OBJFILES_SAFE (objfile, temp)
+ {
+ free_objfile (objfile);
+ }
+ clear_symtab_users ();
+}
+
+/* Relocate OBJFILE to NEW_OFFSETS. There should be OBJFILE->NUM_SECTIONS
+ entries in new_offsets. */
+void
+objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
+{
+ struct section_offsets *delta =
+ (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
+
+ {
+ int i;
+ int something_changed = 0;
+ for (i = 0; i < objfile->num_sections; ++i)
+ {
+ delta->offsets[i] =
+ ANOFFSET (new_offsets, i) - ANOFFSET (objfile->section_offsets, i);
+ if (ANOFFSET (delta, i) != 0)
+ something_changed = 1;
+ }
+ if (!something_changed)
+ return;
+ }
+
+ /* OK, get all the symtabs. */
+ {
+ struct symtab *s;
+
+ ALL_OBJFILE_SYMTABS (objfile, s)
+ {
+ struct linetable *l;
+ struct blockvector *bv;
+ int i;
+
+ /* First the line table. */
+ l = LINETABLE (s);
+ if (l)
+ {
+ for (i = 0; i < l->nitems; ++i)
+ l->item[i].pc += ANOFFSET (delta, s->block_line_section);
+ }
+
+ /* Don't relocate a shared blockvector more than once. */
+ if (!s->primary)
+ continue;
+
+ bv = BLOCKVECTOR (s);
+ for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); ++i)
+ {
+ struct block *b;
+ struct symbol *sym;
+ int j;
+
+ b = BLOCKVECTOR_BLOCK (bv, i);
+ BLOCK_START (b) += ANOFFSET (delta, s->block_line_section);
+ BLOCK_END (b) += ANOFFSET (delta, s->block_line_section);
+
+ ALL_BLOCK_SYMBOLS (b, j, sym)
+ {
+ fixup_symbol_section (sym, objfile);
+
+ /* The RS6000 code from which this was taken skipped
+ any symbols in STRUCT_NAMESPACE or UNDEF_NAMESPACE.
+ But I'm leaving out that test, on the theory that
+ they can't possibly pass the tests below. */
+ if ((SYMBOL_CLASS (sym) == LOC_LABEL
+ || SYMBOL_CLASS (sym) == LOC_STATIC
+ || SYMBOL_CLASS (sym) == LOC_INDIRECT)
+ && SYMBOL_SECTION (sym) >= 0)
+ {
+ SYMBOL_VALUE_ADDRESS (sym) +=
+ ANOFFSET (delta, SYMBOL_SECTION (sym));
+ }
+#ifdef MIPS_EFI_SYMBOL_NAME
+ /* Relocate Extra Function Info for ecoff. */
+
+ else if (SYMBOL_CLASS (sym) == LOC_CONST
+ && SYMBOL_NAMESPACE (sym) == LABEL_NAMESPACE
+ && strcmp (SYMBOL_NAME (sym), MIPS_EFI_SYMBOL_NAME) == 0)
+ ecoff_relocate_efi (sym, ANOFFSET (delta,
+ s->block_line_section));
+#endif
+ }
+ }
+ }
+ }
+
+ {
+ struct partial_symtab *p;
+
+ ALL_OBJFILE_PSYMTABS (objfile, p)
+ {
+ p->textlow += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
+ p->texthigh += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
+ }
+ }
+
+ {
+ struct partial_symbol **psym;
+
+ for (psym = objfile->global_psymbols.list;
+ psym < objfile->global_psymbols.next;
+ psym++)
+ {
+ fixup_psymbol_section (*psym, objfile);
+ if (SYMBOL_SECTION (*psym) >= 0)
+ SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
+ SYMBOL_SECTION (*psym));
+ }
+ for (psym = objfile->static_psymbols.list;
+ psym < objfile->static_psymbols.next;
+ psym++)
+ {
+ fixup_psymbol_section (*psym, objfile);
+ if (SYMBOL_SECTION (*psym) >= 0)
+ SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
+ SYMBOL_SECTION (*psym));
+ }
+ }
+
+ {
+ struct minimal_symbol *msym;
+ ALL_OBJFILE_MSYMBOLS (objfile, msym)
+ if (SYMBOL_SECTION (msym) >= 0)
+ SYMBOL_VALUE_ADDRESS (msym) += ANOFFSET (delta, SYMBOL_SECTION (msym));
+ }
+ /* Relocating different sections by different amounts may cause the symbols
+ to be out of order. */
+ msymbols_sort (objfile);
+
+ {
+ int i;
+ for (i = 0; i < objfile->num_sections; ++i)
+ (objfile->section_offsets)->offsets[i] = ANOFFSET (new_offsets, i);
+ }
+
+ if (objfile->ei.entry_point != ~(CORE_ADDR) 0)
+ {
+ /* Relocate ei.entry_point with its section offset, use SECT_OFF_TEXT
+ only as a fallback. */
+ struct obj_section *s;
+ s = find_pc_section (objfile->ei.entry_point);
+ if (s)
+ objfile->ei.entry_point += ANOFFSET (delta, s->the_bfd_section->index);
+ else
+ objfile->ei.entry_point += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
+ }
+
+ {
+ struct obj_section *s;
+ bfd *abfd;
+
+ abfd = objfile->obfd;
+
+ ALL_OBJFILE_OSECTIONS (objfile, s)
+ {
+ int idx = s->the_bfd_section->index;
+
+ s->addr += ANOFFSET (delta, idx);
+ s->endaddr += ANOFFSET (delta, idx);
+ }
+ }
+
+ if (objfile->ei.entry_func_lowpc != INVALID_ENTRY_LOWPC)
+ {
+ objfile->ei.entry_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
+ objfile->ei.entry_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
+ }
+
+ if (objfile->ei.entry_file_lowpc != INVALID_ENTRY_LOWPC)
+ {
+ objfile->ei.entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
+ objfile->ei.entry_file_highpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
+ }
+
+ if (objfile->ei.main_func_lowpc != INVALID_ENTRY_LOWPC)
+ {
+ objfile->ei.main_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
+ objfile->ei.main_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
+ }
+
+ /* Relocate breakpoints as necessary, after things are relocated. */
+ breakpoint_re_set ();
+}
+
+/* Many places in gdb want to test just to see if we have any partial
+ symbols available. This function returns zero if none are currently
+ available, nonzero otherwise. */
+
+int
+have_partial_symbols (void)
+{
+ struct objfile *ofp;
+
+ ALL_OBJFILES (ofp)
+ {
+ if (ofp->psymtabs != NULL)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Many places in gdb want to test just to see if we have any full
+ symbols available. This function returns zero if none are currently
+ available, nonzero otherwise. */
+
+int
+have_full_symbols (void)
+{
+ struct objfile *ofp;
+
+ ALL_OBJFILES (ofp)
+ {
+ if (ofp->symtabs != NULL)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/* This operations deletes all objfile entries that represent solibs that
+ weren't explicitly loaded by the user, via e.g., the add-symbol-file
+ command.
+ */
+void
+objfile_purge_solibs (void)
+{
+ struct objfile *objf;
+ struct objfile *temp;
+
+ ALL_OBJFILES_SAFE (objf, temp)
+ {
+ /* We assume that the solib package has been purged already, or will
+ be soon.
+ */
+ if (!(objf->flags & OBJF_USERLOADED) && (objf->flags & OBJF_SHARED))
+ free_objfile (objf);
+ }
+}
+
+
+/* Many places in gdb want to test just to see if we have any minimal
+ symbols available. This function returns zero if none are currently
+ available, nonzero otherwise. */
+
+int
+have_minimal_symbols (void)
+{
+ struct objfile *ofp;
+
+ ALL_OBJFILES (ofp)
+ {
+ if (ofp->msymbols != NULL)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
+
+/* Given the name of a mapped symbol file in SYMSFILENAME, and the timestamp
+ of the corresponding symbol file in MTIME, try to open an existing file
+ with the name SYMSFILENAME and verify it is more recent than the base
+ file by checking it's timestamp against MTIME.
+
+ If SYMSFILENAME does not exist (or can't be stat'd), simply returns -1.
+
+ If SYMSFILENAME does exist, but is out of date, we check to see if the
+ user has specified creation of a mapped file. If so, we don't issue
+ any warning message because we will be creating a new mapped file anyway,
+ overwriting the old one. If not, then we issue a warning message so that
+ the user will know why we aren't using this existing mapped symbol file.
+ In either case, we return -1.
+
+ If SYMSFILENAME does exist and is not out of date, but can't be opened for
+ some reason, then prints an appropriate system error message and returns -1.
+
+ Otherwise, returns the open file descriptor. */
+
+static int
+open_existing_mapped_file (char *symsfilename, long mtime, int flags)
+{
+ int fd = -1;
+ struct stat sbuf;
+
+ if (stat (symsfilename, &sbuf) == 0)
+ {
+ if (sbuf.st_mtime < mtime)
+ {
+ if (!(flags & OBJF_MAPPED))
+ {
+ warning ("mapped symbol file `%s' is out of date, ignored it",
+ symsfilename);
+ }
+ }
+ else if ((fd = open (symsfilename, O_RDWR)) < 0)
+ {
+ if (error_pre_print)
+ {
+ printf_unfiltered (error_pre_print);
+ }
+ print_sys_errmsg (symsfilename, errno);
+ }
+ }
+ return (fd);
+}
+
+/* Look for a mapped symbol file that corresponds to FILENAME and is more
+ recent than MTIME. If MAPPED is nonzero, the user has asked that gdb
+ use a mapped symbol file for this file, so create a new one if one does
+ not currently exist.
+
+ If found, then return an open file descriptor for the file, otherwise
+ return -1.
+
+ This routine is responsible for implementing the policy that generates
+ the name of the mapped symbol file from the name of a file containing
+ symbols that gdb would like to read. Currently this policy is to append
+ ".syms" to the name of the file.
+
+ This routine is also responsible for implementing the policy that
+ determines where the mapped symbol file is found (the search path).
+ This policy is that when reading an existing mapped file, a file of
+ the correct name in the current directory takes precedence over a
+ file of the correct name in the same directory as the symbol file.
+ When creating a new mapped file, it is always created in the current
+ directory. This helps to minimize the chances of a user unknowingly
+ creating big mapped files in places like /bin and /usr/local/bin, and
+ allows a local copy to override a manually installed global copy (in
+ /bin for example). */
+
+static int
+open_mapped_file (char *filename, long mtime, int flags)
+{
+ int fd;
+ char *symsfilename;
+
+ /* First try to open an existing file in the current directory, and
+ then try the directory where the symbol file is located. */
+
+ symsfilename = concat ("./", lbasename (filename), ".syms", (char *) NULL);
+ if ((fd = open_existing_mapped_file (symsfilename, mtime, flags)) < 0)
+ {
+ xfree (symsfilename);
+ symsfilename = concat (filename, ".syms", (char *) NULL);
+ fd = open_existing_mapped_file (symsfilename, mtime, flags);
+ }
+
+ /* If we don't have an open file by now, then either the file does not
+ already exist, or the base file has changed since it was created. In
+ either case, if the user has specified use of a mapped file, then
+ create a new mapped file, truncating any existing one. If we can't
+ create one, print a system error message saying why we can't.
+
+ By default the file is rw for everyone, with the user's umask taking
+ care of turning off the permissions the user wants off. */
+
+ if ((fd < 0) && (flags & OBJF_MAPPED))
+ {
+ xfree (symsfilename);
+ symsfilename = concat ("./", lbasename (filename), ".syms",
+ (char *) NULL);
+ if ((fd = open (symsfilename, O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0)
+ {
+ if (error_pre_print)
+ {
+ printf_unfiltered (error_pre_print);
+ }
+ print_sys_errmsg (symsfilename, errno);
+ }
+ }
+
+ xfree (symsfilename);
+ return (fd);
+}
+
+static PTR
+map_to_file (int fd)
+{
+ PTR md;
+ CORE_ADDR mapto;
+
+ md = mmalloc_attach (fd, (PTR) 0);
+ if (md != NULL)
+ {
+ mapto = (CORE_ADDR) mmalloc_getkey (md, 1);
+ md = mmalloc_detach (md);
+ if (md != NULL)
+ {
+ /* FIXME: should figure out why detach failed */
+ md = NULL;
+ }
+ else if (mapto != (CORE_ADDR) NULL)
+ {
+ /* This mapping file needs to be remapped at "mapto" */
+ md = mmalloc_attach (fd, (PTR) mapto);
+ }
+ else
+ {
+ /* This is a freshly created mapping file. */
+ mapto = (CORE_ADDR) mmalloc_findbase (20 * 1024 * 1024);
+ if (mapto != 0)
+ {
+ /* To avoid reusing the freshly created mapping file, at the
+ address selected by mmap, we must truncate it before trying
+ to do an attach at the address we want. */
+ ftruncate (fd, 0);
+ md = mmalloc_attach (fd, (PTR) mapto);
+ if (md != NULL)
+ {
+ mmalloc_setkey (md, 1, (PTR) mapto);
+ }
+ }
+ }
+ }
+ return (md);
+}
+
+#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
+
+/* Returns a section whose range includes PC and SECTION,
+ or NULL if none found. Note the distinction between the return type,
+ struct obj_section (which is defined in gdb), and the input type
+ struct sec (which is a bfd-defined data type). The obj_section
+ contains a pointer to the bfd struct sec section. */
+
+struct obj_section *
+find_pc_sect_section (CORE_ADDR pc, struct sec *section)
+{
+ struct obj_section *s;
+ struct objfile *objfile;
+
+ ALL_OBJSECTIONS (objfile, s)
+ if ((section == 0 || section == s->the_bfd_section) &&
+ s->addr <= pc && pc < s->endaddr)
+ return (s);
+
+ return (NULL);
+}
+
+/* Returns a section whose range includes PC or NULL if none found.
+ Backward compatibility, no section. */
+
+struct obj_section *
+find_pc_section (CORE_ADDR pc)
+{
+ return find_pc_sect_section (pc, find_pc_mapped_section (pc));
+}
+
+
+/* In SVR4, we recognize a trampoline by it's section name.
+ That is, if the pc is in a section named ".plt" then we are in
+ a trampoline. */
+
+int
+in_plt_section (CORE_ADDR pc, char *name)
+{
+ struct obj_section *s;
+ int retval = 0;
+
+ s = find_pc_section (pc);
+
+ retval = (s != NULL
+ && s->the_bfd_section->name != NULL
+ && STREQ (s->the_bfd_section->name, ".plt"));
+ return (retval);
+}
+
+/* Return nonzero if NAME is in the import list of OBJFILE. Else
+ return zero. */
+
+int
+is_in_import_list (char *name, struct objfile *objfile)
+{
+ register int i;
+
+ if (!objfile || !name || !*name)
+ return 0;
+
+ for (i = 0; i < objfile->import_list_size; i++)
+ if (objfile->import_list[i] && STREQ (name, objfile->import_list[i]))
+ return 1;
+ return 0;
+}
+
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
new file mode 100644
index 00000000000..ed4e6b7b32f
--- /dev/null
+++ b/gdb/objfiles.h
@@ -0,0 +1,610 @@
+/* Definitions for symbol file management in GDB.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+ 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. */
+
+#if !defined (OBJFILES_H)
+#define OBJFILES_H
+
+/* This structure maintains information on a per-objfile basis about the
+ "entry point" of the objfile, and the scope within which the entry point
+ exists. It is possible that gdb will see more than one objfile that is
+ executable, each with its own entry point.
+
+ For example, for dynamically linked executables in SVR4, the dynamic linker
+ code is contained within the shared C library, which is actually executable
+ and is run by the kernel first when an exec is done of a user executable
+ that is dynamically linked. The dynamic linker within the shared C library
+ then maps in the various program segments in the user executable and jumps
+ to the user executable's recorded entry point, as if the call had been made
+ directly by the kernel.
+
+ The traditional gdb method of using this info is to use the recorded entry
+ point to set the variables entry_file_lowpc and entry_file_highpc from
+ the debugging information, where these values are the starting address
+ (inclusive) and ending address (exclusive) of the instruction space in the
+ executable which correspond to the "startup file", I.E. crt0.o in most
+ cases. This file is assumed to be a startup file and frames with pc's
+ inside it are treated as nonexistent. Setting these variables is necessary
+ so that backtraces do not fly off the bottom of the stack.
+
+ Gdb also supports an alternate method to avoid running off the bottom
+ of the stack.
+
+ There are two frames that are "special", the frame for the function
+ containing the process entry point, since it has no predecessor frame,
+ and the frame for the function containing the user code entry point
+ (the main() function), since all the predecessor frames are for the
+ process startup code. Since we have no guarantee that the linked
+ in startup modules have any debugging information that gdb can use,
+ we need to avoid following frame pointers back into frames that might
+ have been built in the startup code, as we might get hopelessly
+ confused. However, we almost always have debugging information
+ available for main().
+
+ These variables are used to save the range of PC values which are valid
+ within the main() function and within the function containing the process
+ entry point. If we always consider the frame for main() as the outermost
+ frame when debugging user code, and the frame for the process entry
+ point function as the outermost frame when debugging startup code, then
+ all we have to do is have FRAME_CHAIN_VALID return false whenever a
+ frame's current PC is within the range specified by these variables.
+ In essence, we set "ceilings" in the frame chain beyond which we will
+ not proceed when following the frame chain back up the stack.
+
+ A nice side effect is that we can still debug startup code without
+ running off the end of the frame chain, assuming that we have usable
+ debugging information in the startup modules, and if we choose to not
+ use the block at main, or can't find it for some reason, everything
+ still works as before. And if we have no startup code debugging
+ information but we do have usable information for main(), backtraces
+ from user code don't go wandering off into the startup code.
+
+ To use this method, define your FRAME_CHAIN_VALID macro like:
+
+ #define FRAME_CHAIN_VALID(chain, thisframe) \
+ (chain != 0 \
+ && !(inside_main_func ((thisframe)->pc)) \
+ && !(inside_entry_func ((thisframe)->pc)))
+
+ and add initializations of the four scope controlling variables inside
+ the object file / debugging information processing modules. */
+
+struct entry_info
+ {
+
+ /* The value we should use for this objects entry point.
+ The illegal/unknown value needs to be something other than 0, ~0
+ for instance, which is much less likely than 0. */
+
+ CORE_ADDR entry_point;
+
+#define INVALID_ENTRY_POINT (~0) /* ~0 will not be in any file, we hope. */
+
+ /* Start (inclusive) and end (exclusive) of function containing the
+ entry point. */
+
+ CORE_ADDR entry_func_lowpc;
+ CORE_ADDR entry_func_highpc;
+
+ /* Start (inclusive) and end (exclusive) of object file containing the
+ entry point. */
+
+ CORE_ADDR entry_file_lowpc;
+ CORE_ADDR entry_file_highpc;
+
+ /* Start (inclusive) and end (exclusive) of the user code main() function. */
+
+ CORE_ADDR main_func_lowpc;
+ CORE_ADDR main_func_highpc;
+
+/* Use these values when any of the above ranges is invalid. */
+
+/* We use these values because it guarantees that there is no number that is
+ both >= LOWPC && < HIGHPC. It is also highly unlikely that 3 is a valid
+ module or function start address (as opposed to 0). */
+
+#define INVALID_ENTRY_LOWPC (3)
+#define INVALID_ENTRY_HIGHPC (1)
+
+ };
+
+/* Sections in an objfile.
+
+ It is strange that we have both this notion of "sections"
+ and the one used by section_offsets. Section as used
+ here, (currently at least) means a BFD section, and the sections
+ are set up from the BFD sections in allocate_objfile.
+
+ The sections in section_offsets have their meaning determined by
+ the symbol format, and they are set up by the sym_offsets function
+ for that symbol file format.
+
+ I'm not sure this could or should be changed, however. */
+
+struct obj_section
+ {
+ CORE_ADDR addr; /* lowest address in section */
+ CORE_ADDR endaddr; /* 1+highest address in section */
+
+ /* This field is being used for nefarious purposes by syms_from_objfile.
+ It is said to be redundant with section_offsets; it's not really being
+ used that way, however, it's some sort of hack I don't understand
+ and am not going to try to eliminate (yet, anyway). FIXME.
+
+ It was documented as "offset between (end)addr and actual memory
+ addresses", but that's not true; addr & endaddr are actual memory
+ addresses. */
+ CORE_ADDR offset;
+
+ sec_ptr the_bfd_section; /* BFD section pointer */
+
+ /* Objfile this section is part of. */
+ struct objfile *objfile;
+
+ /* True if this "overlay section" is mapped into an "overlay region". */
+ int ovly_mapped;
+ };
+
+/* An import entry contains information about a symbol that
+ is used in this objfile but not defined in it, and so needs
+ to be imported from some other objfile */
+/* Currently we just store the name; no attributes. 1997-08-05 */
+typedef char *ImportEntry;
+
+
+/* An export entry contains information about a symbol that
+ is defined in this objfile and available for use in other
+ objfiles */
+typedef struct
+ {
+ char *name; /* name of exported symbol */
+ int address; /* offset subject to relocation */
+ /* Currently no other attributes 1997-08-05 */
+ }
+ExportEntry;
+
+
+/* The "objstats" structure provides a place for gdb to record some
+ interesting information about its internal state at runtime, on a
+ per objfile basis, such as information about the number of symbols
+ read, size of string table (if any), etc. */
+
+struct objstats
+ {
+ int n_minsyms; /* Number of minimal symbols read */
+ int n_psyms; /* Number of partial symbols read */
+ int n_syms; /* Number of full symbols read */
+ int n_stabs; /* Number of ".stabs" read (if applicable) */
+ int n_types; /* Number of types */
+ int sz_strtab; /* Size of stringtable, (if applicable) */
+ };
+
+#define OBJSTAT(objfile, expr) (objfile -> stats.expr)
+#define OBJSTATS struct objstats stats
+extern void print_objfile_statistics (void);
+extern void print_symbol_bcache_statistics (void);
+
+/* Number of entries in the minimal symbol hash table. */
+#define MINIMAL_SYMBOL_HASH_SIZE 2039
+
+/* Master structure for keeping track of each file from which
+ gdb reads symbols. There are several ways these get allocated: 1.
+ The main symbol file, symfile_objfile, set by the symbol-file command,
+ 2. Additional symbol files added by the add-symbol-file command,
+ 3. Shared library objfiles, added by ADD_SOLIB, 4. symbol files
+ for modules that were loaded when GDB attached to a remote system
+ (see remote-vx.c). */
+
+struct objfile
+ {
+
+ /* All struct objfile's are chained together by their next pointers.
+ The global variable "object_files" points to the first link in this
+ chain.
+
+ FIXME: There is a problem here if the objfile is reusable, and if
+ multiple users are to be supported. The problem is that the objfile
+ list is linked through a member of the objfile struct itself, which
+ is only valid for one gdb process. The list implementation needs to
+ be changed to something like:
+
+ struct list {struct list *next; struct objfile *objfile};
+
+ where the list structure is completely maintained separately within
+ each gdb process. */
+
+ struct objfile *next;
+
+ /* The object file's name. Malloc'd; free it if you free this struct. */
+
+ char *name;
+
+ /* Some flag bits for this objfile. */
+
+ unsigned short flags;
+
+ /* Each objfile points to a linked list of symtabs derived from this file,
+ one symtab structure for each compilation unit (source file). Each link
+ in the symtab list contains a backpointer to this objfile. */
+
+ struct symtab *symtabs;
+
+ /* Each objfile points to a linked list of partial symtabs derived from
+ this file, one partial symtab structure for each compilation unit
+ (source file). */
+
+ struct partial_symtab *psymtabs;
+
+ /* List of freed partial symtabs, available for re-use */
+
+ struct partial_symtab *free_psymtabs;
+
+ /* The object file's BFD. Can be null if the objfile contains only
+ minimal symbols, e.g. the run time common symbols for SunOS4. */
+
+ bfd *obfd;
+
+ /* The modification timestamp of the object file, as of the last time
+ we read its symbols. */
+
+ long mtime;
+
+ /* Obstacks to hold objects that should be freed when we load a new symbol
+ table from this object file. */
+
+ struct obstack psymbol_obstack; /* Partial symbols */
+ struct obstack symbol_obstack; /* Full symbols */
+ struct obstack type_obstack; /* Types */
+
+ /* A byte cache where we can stash arbitrary "chunks" of bytes that
+ will not change. */
+
+ struct bcache psymbol_cache; /* Byte cache for partial syms */
+ struct bcache macro_cache; /* Byte cache for macros */
+
+ /* Vectors of all partial symbols read in from file. The actual data
+ is stored in the psymbol_obstack. */
+
+ struct psymbol_allocation_list global_psymbols;
+ struct psymbol_allocation_list static_psymbols;
+
+ /* Each file contains a pointer to an array of minimal symbols for all
+ global symbols that are defined within the file. The array is terminated
+ by a "null symbol", one that has a NULL pointer for the name and a zero
+ value for the address. This makes it easy to walk through the array
+ when passed a pointer to somewhere in the middle of it. There is also
+ a count of the number of symbols, which does not include the terminating
+ null symbol. The array itself, as well as all the data that it points
+ to, should be allocated on the symbol_obstack for this file. */
+
+ struct minimal_symbol *msymbols;
+ int minimal_symbol_count;
+
+ /* This is a hash table used to index the minimal symbols by name. */
+
+ struct minimal_symbol *msymbol_hash[MINIMAL_SYMBOL_HASH_SIZE];
+
+ /* This hash table is used to index the minimal symbols by their
+ demangled names. */
+
+ struct minimal_symbol *msymbol_demangled_hash[MINIMAL_SYMBOL_HASH_SIZE];
+
+ /* For object file formats which don't specify fundamental types, gdb
+ can create such types. For now, it maintains a vector of pointers
+ to these internally created fundamental types on a per objfile basis,
+ however it really should ultimately keep them on a per-compilation-unit
+ basis, to account for linkage-units that consist of a number of
+ compilation units that may have different fundamental types, such as
+ linking C modules with ADA modules, or linking C modules that are
+ compiled with 32-bit ints with C modules that are compiled with 64-bit
+ ints (not inherently evil with a smarter linker). */
+
+ struct type **fundamental_types;
+
+ /* The mmalloc() malloc-descriptor for this objfile if we are using
+ the memory mapped malloc() package to manage storage for this objfile's
+ data. NULL if we are not. */
+
+ PTR md;
+
+ /* The file descriptor that was used to obtain the mmalloc descriptor
+ for this objfile. If we call mmalloc_detach with the malloc descriptor
+ we should then close this file descriptor. */
+
+ int mmfd;
+
+ /* Structure which keeps track of functions that manipulate objfile's
+ of the same type as this objfile. I.E. the function to read partial
+ symbols for example. Note that this structure is in statically
+ allocated memory, and is shared by all objfiles that use the
+ object module reader of this type. */
+
+ struct sym_fns *sf;
+
+ /* The per-objfile information about the entry point, the scope (file/func)
+ containing the entry point, and the scope of the user's main() func. */
+
+ struct entry_info ei;
+
+ /* Information about stabs. Will be filled in with a dbx_symfile_info
+ struct by those readers that need it. */
+
+ struct dbx_symfile_info *sym_stab_info;
+
+ /* Hook for information for use by the symbol reader (currently used
+ for information shared by sym_init and sym_read). It is
+ typically a pointer to malloc'd memory. The symbol reader's finish
+ function is responsible for freeing the memory thusly allocated. */
+
+ PTR sym_private;
+
+ /* Hook for target-architecture-specific information. This must
+ point to memory allocated on one of the obstacks in this objfile,
+ so that it gets freed automatically when reading a new object
+ file. */
+
+ PTR obj_private;
+
+ /* Set of relocation offsets to apply to each section.
+ Currently on the psymbol_obstack (which makes no sense, but I'm
+ not sure it's harming anything).
+
+ These offsets indicate that all symbols (including partial and
+ minimal symbols) which have been read have been relocated by this
+ much. Symbols which are yet to be read need to be relocated by
+ it. */
+
+ struct section_offsets *section_offsets;
+ int num_sections;
+
+ /* Indexes in the section_offsets array. These are initialized by the
+ *_symfile_offsets() family of functions (som_symfile_offsets,
+ xcoff_symfile_offsets, default_symfile_offsets). In theory they
+ should correspond to the section indexes used by bfd for the
+ current objfile. The exception to this for the time being is the
+ SOM version. */
+
+ int sect_index_text;
+ int sect_index_data;
+ int sect_index_bss;
+ int sect_index_rodata;
+
+ /* These pointers are used to locate the section table, which
+ among other things, is used to map pc addresses into sections.
+ SECTIONS points to the first entry in the table, and
+ SECTIONS_END points to the first location past the last entry
+ in the table. Currently the table is stored on the
+ psymbol_obstack (which makes no sense, but I'm not sure it's
+ harming anything). */
+
+ struct obj_section
+ *sections, *sections_end;
+
+ /* two auxiliary fields, used to hold the fp of separate symbol files */
+ FILE *auxf1, *auxf2;
+
+ /* Imported symbols */
+ ImportEntry *import_list;
+ int import_list_size;
+
+ /* Exported symbols */
+ ExportEntry *export_list;
+ int export_list_size;
+
+ /* Place to stash various statistics about this objfile */
+ OBJSTATS;
+ };
+
+/* Defines for the objfile flag word. */
+
+/* Gdb can arrange to allocate storage for all objects related to a
+ particular objfile in a designated section of its address space,
+ managed at a low level by mmap() and using a special version of
+ malloc that handles malloc/free/realloc on top of the mmap() interface.
+ This allows the "internal gdb state" for a particular objfile to be
+ dumped to a gdb state file and subsequently reloaded at a later time. */
+
+#define OBJF_MAPPED (1 << 0) /* Objfile data is mmap'd */
+
+/* When using mapped/remapped predigested gdb symbol information, we need
+ a flag that indicates that we have previously done an initial symbol
+ table read from this particular objfile. We can't just look for the
+ absence of any of the three symbol tables (msymbols, psymtab, symtab)
+ because if the file has no symbols for example, none of these will
+ exist. */
+
+#define OBJF_SYMS (1 << 1) /* Have tried to read symbols */
+
+/* When an object file has its functions reordered (currently Irix-5.2
+ shared libraries exhibit this behaviour), we will need an expensive
+ algorithm to locate a partial symtab or symtab via an address.
+ To avoid this penalty for normal object files, we use this flag,
+ whose setting is determined upon symbol table read in. */
+
+#define OBJF_REORDERED (1 << 2) /* Functions are reordered */
+
+/* Distinguish between an objfile for a shared library and a "vanilla"
+ objfile. (If not set, the objfile may still actually be a solib.
+ This can happen if the user created the objfile by using the
+ add-symbol-file command. GDB doesn't in that situation actually
+ check whether the file is a solib. Rather, the target's
+ implementation of the solib interface is responsible for setting
+ this flag when noticing solibs used by an inferior.) */
+
+#define OBJF_SHARED (1 << 3) /* From a shared library */
+
+/* User requested that this objfile be read in it's entirety. */
+
+#define OBJF_READNOW (1 << 4) /* Immediate full read */
+
+/* This objfile was created because the user explicitly caused it
+ (e.g., used the add-symbol-file command). This bit offers a way
+ for run_command to remove old objfile entries which are no longer
+ valid (i.e., are associated with an old inferior), but to preserve
+ ones that the user explicitly loaded via the add-symbol-file
+ command. */
+
+#define OBJF_USERLOADED (1 << 5) /* User loaded */
+
+/* The object file that the main symbol table was loaded from (e.g. the
+ argument to the "symbol-file" or "file" command). */
+
+extern struct objfile *symfile_objfile;
+
+/* The object file that contains the runtime common minimal symbols
+ for SunOS4. Note that this objfile has no associated BFD. */
+
+extern struct objfile *rt_common_objfile;
+
+/* When we need to allocate a new type, we need to know which type_obstack
+ to allocate the type on, since there is one for each objfile. The places
+ where types are allocated are deeply buried in function call hierarchies
+ which know nothing about objfiles, so rather than trying to pass a
+ particular objfile down to them, we just do an end run around them and
+ set current_objfile to be whatever objfile we expect to be using at the
+ time types are being allocated. For instance, when we start reading
+ symbols for a particular objfile, we set current_objfile to point to that
+ objfile, and when we are done, we set it back to NULL, to ensure that we
+ never put a type someplace other than where we are expecting to put it.
+ FIXME: Maybe we should review the entire type handling system and
+ see if there is a better way to avoid this problem. */
+
+extern struct objfile *current_objfile;
+
+/* All known objfiles are kept in a linked list. This points to the
+ root of this list. */
+
+extern struct objfile *object_files;
+
+/* Declarations for functions defined in objfiles.c */
+
+extern struct objfile *allocate_objfile (bfd *, int);
+
+extern int build_objfile_section_table (struct objfile *);
+
+extern void objfile_to_front (struct objfile *);
+
+extern void unlink_objfile (struct objfile *);
+
+extern void free_objfile (struct objfile *);
+
+extern struct cleanup *make_cleanup_free_objfile (struct objfile *);
+
+extern void free_all_objfiles (void);
+
+extern void objfile_relocate (struct objfile *, struct section_offsets *);
+
+extern int have_partial_symbols (void);
+
+extern int have_full_symbols (void);
+
+/* This operation deletes all objfile entries that represent solibs that
+ weren't explicitly loaded by the user, via e.g., the add-symbol-file
+ command.
+ */
+extern void objfile_purge_solibs (void);
+
+/* Functions for dealing with the minimal symbol table, really a misc
+ address<->symbol mapping for things we don't have debug symbols for. */
+
+extern int have_minimal_symbols (void);
+
+extern struct obj_section *find_pc_section (CORE_ADDR pc);
+
+extern struct obj_section *find_pc_sect_section (CORE_ADDR pc,
+ asection * section);
+
+extern int in_plt_section (CORE_ADDR, char *);
+
+extern int is_in_import_list (char *, struct objfile *);
+
+/* Traverse all object files. ALL_OBJFILES_SAFE works even if you delete
+ the objfile during the traversal. */
+
+#define ALL_OBJFILES(obj) \
+ for ((obj) = object_files; (obj) != NULL; (obj) = (obj)->next)
+
+#define ALL_OBJFILES_SAFE(obj,nxt) \
+ for ((obj) = object_files; \
+ (obj) != NULL? ((nxt)=(obj)->next,1) :0; \
+ (obj) = (nxt))
+
+/* Traverse all symtabs in one objfile. */
+
+#define ALL_OBJFILE_SYMTABS(objfile, s) \
+ for ((s) = (objfile) -> symtabs; (s) != NULL; (s) = (s) -> next)
+
+/* Traverse all psymtabs in one objfile. */
+
+#define ALL_OBJFILE_PSYMTABS(objfile, p) \
+ for ((p) = (objfile) -> psymtabs; (p) != NULL; (p) = (p) -> next)
+
+/* Traverse all minimal symbols in one objfile. */
+
+#define ALL_OBJFILE_MSYMBOLS(objfile, m) \
+ for ((m) = (objfile) -> msymbols; SYMBOL_NAME(m) != NULL; (m)++)
+
+/* Traverse all symtabs in all objfiles. */
+
+#define ALL_SYMTABS(objfile, s) \
+ ALL_OBJFILES (objfile) \
+ ALL_OBJFILE_SYMTABS (objfile, s)
+
+/* Traverse all psymtabs in all objfiles. */
+
+#define ALL_PSYMTABS(objfile, p) \
+ ALL_OBJFILES (objfile) \
+ ALL_OBJFILE_PSYMTABS (objfile, p)
+
+/* Traverse all minimal symbols in all objfiles. */
+
+#define ALL_MSYMBOLS(objfile, m) \
+ ALL_OBJFILES (objfile) \
+ if ((objfile)->msymbols) \
+ ALL_OBJFILE_MSYMBOLS (objfile, m)
+
+#define ALL_OBJFILE_OSECTIONS(objfile, osect) \
+ for (osect = objfile->sections; osect < objfile->sections_end; osect++)
+
+#define ALL_OBJSECTIONS(objfile, osect) \
+ ALL_OBJFILES (objfile) \
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+
+#define SECT_OFF_DATA(objfile) \
+ ((objfile->sect_index_data == -1) \
+ ? (internal_error (__FILE__, __LINE__, "sect_index_data not initialized"), -1) \
+ : objfile->sect_index_data)
+
+#define SECT_OFF_RODATA(objfile) \
+ ((objfile->sect_index_rodata == -1) \
+ ? (internal_error (__FILE__, __LINE__, "sect_index_rodata not initialized"), -1) \
+ : objfile->sect_index_rodata)
+
+#define SECT_OFF_TEXT(objfile) \
+ ((objfile->sect_index_text == -1) \
+ ? (internal_error (__FILE__, __LINE__, "sect_index_text not initialized"), -1) \
+ : objfile->sect_index_text)
+
+/* Sometimes the .bss section is missing from the objfile, so we don't
+ want to die here. Let the users of SECT_OFF_BSS deal with an
+ uninitialized section index. */
+#define SECT_OFF_BSS(objfile) (objfile)->sect_index_bss
+
+#endif /* !defined (OBJFILES_H) */
diff --git a/gdb/ocd.c b/gdb/ocd.c
new file mode 100644
index 00000000000..9dd90e9c992
--- /dev/null
+++ b/gdb/ocd.c
@@ -0,0 +1,1388 @@
+/* Target communications support for Macraigor Systems' On-Chip Debugging
+
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+#include "gdbcore.h"
+#include "gdb_string.h"
+#include <fcntl.h>
+#include "frame.h"
+#include "inferior.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "target.h"
+#include "gdbcmd.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include <sys/types.h>
+#include <signal.h>
+#include "serial.h"
+#include "ocd.h"
+#include "regcache.h"
+
+/* Prototypes for local functions */
+
+static int ocd_read_bytes (CORE_ADDR memaddr, char *myaddr, int len);
+
+static int ocd_start_remote (PTR dummy);
+
+static int readchar (int timeout);
+
+static void reset_packet (void);
+
+static void output_packet (void);
+
+static int get_quoted_char (int timeout);
+
+static void put_quoted_char (int c);
+
+static void ocd_interrupt (int signo);
+
+static void ocd_interrupt_twice (int signo);
+
+static void interrupt_query (void);
+
+static unsigned char *ocd_do_command (int cmd, int *statusp, int *lenp);
+
+static void ocd_put_packet (unsigned char *packet, int pktlen);
+
+static unsigned char *ocd_get_packet (int cmd, int *pktlen, int timeout);
+
+static struct target_ops *current_ops = NULL;
+
+static int last_run_status;
+
+/* This was 5 seconds, which is a long time to sit and wait.
+ Unless this is going though some terminal server or multiplexer or
+ other form of hairy serial connection, I would think 2 seconds would
+ be plenty. */
+
+#if 0
+/* FIXME: Change to allow option to set timeout value on a per target
+ basis. */
+static int remote_timeout = 2;
+#endif
+
+/* Descriptor for I/O to remote machine. Initialize it to NULL so that
+ ocd_open knows that we don't have a file open when the program
+ starts. */
+static struct serial *ocd_desc = NULL;
+
+void
+ocd_error (char *s, int error_code)
+{
+ char buf[100];
+
+ fputs_filtered (s, gdb_stderr);
+ fputs_filtered (" ", gdb_stderr);
+
+ switch (error_code)
+ {
+ case 0x1:
+ s = "Unknown fault";
+ break;
+ case 0x2:
+ s = "Power failed";
+ break;
+ case 0x3:
+ s = "Cable disconnected";
+ break;
+ case 0x4:
+ s = "Couldn't enter OCD mode";
+ break;
+ case 0x5:
+ s = "Target stuck in reset";
+ break;
+ case 0x6:
+ s = "OCD hasn't been initialized";
+ break;
+ case 0x7:
+ s = "Write verify failed";
+ break;
+ case 0x8:
+ s = "Reg buff error (during MPC5xx fp reg read/write)";
+ break;
+ case 0x9:
+ s = "Invalid CPU register access attempt failed";
+ break;
+ case 0x11:
+ s = "Bus error";
+ break;
+ case 0x12:
+ s = "Checksum error";
+ break;
+ case 0x13:
+ s = "Illegal command";
+ break;
+ case 0x14:
+ s = "Parameter error";
+ break;
+ case 0x15:
+ s = "Internal error";
+ break;
+ case 0x80:
+ s = "Flash erase error";
+ break;
+ default:
+ sprintf (buf, "Unknown error code %d", error_code);
+ s = buf;
+ }
+
+ error (s);
+}
+
+/* Return nonzero if the thread TH is still alive on the remote system. */
+
+int
+ocd_thread_alive (ptid_t th)
+{
+ return 1;
+}
+
+/* Clean up connection to a remote debugger. */
+
+/* ARGSUSED */
+void
+ocd_close (int quitting)
+{
+ if (ocd_desc)
+ serial_close (ocd_desc);
+ ocd_desc = NULL;
+}
+
+/* Stub for catch_errors. */
+
+static int
+ocd_start_remote (PTR dummy)
+{
+ unsigned char buf[10], *p;
+ int pktlen;
+ int status;
+ int error_code;
+ int speed;
+ enum ocd_target_type target_type;
+
+ target_type = *(enum ocd_target_type *) dummy;
+
+ immediate_quit++; /* Allow user to interrupt it */
+
+ serial_send_break (ocd_desc); /* Wake up the wiggler */
+
+ speed = 80; /* Divide clock by 4000 */
+
+ buf[0] = OCD_INIT;
+ buf[1] = speed >> 8;
+ buf[2] = speed & 0xff;
+ buf[3] = target_type;
+ ocd_put_packet (buf, 4); /* Init OCD params */
+ p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
+
+ if (pktlen < 2)
+ error ("Truncated response packet from OCD device");
+
+ status = p[1];
+ error_code = p[2];
+
+ if (error_code != 0)
+ ocd_error ("OCD_INIT:", error_code);
+
+ ocd_do_command (OCD_AYT, &status, &pktlen);
+
+ p = ocd_do_command (OCD_GET_VERSION, &status, &pktlen);
+
+ printf_unfiltered ("[Wiggler version %x.%x, capability 0x%x]\n",
+ p[0], p[1], (p[2] << 16) | p[3]);
+
+#if 0
+ /* Reset the target */
+
+ ocd_do_command (OCD_RESET_RUN, &status, &pktlen);
+/* ocd_do_command (OCD_RESET, &status, &pktlen); */
+#endif
+
+ /* If processor is still running, stop it. */
+
+ if (!(status & OCD_FLAG_BDM))
+ ocd_stop ();
+
+#if 1
+ /* When using a target box, we want to asynchronously return status when
+ target stops. The OCD_SET_CTL_FLAGS command is ignored by Wigglers.dll
+ when using a parallel Wiggler */
+ buf[0] = OCD_SET_CTL_FLAGS;
+ buf[1] = 0;
+ buf[2] = 1;
+ ocd_put_packet (buf, 3);
+
+ p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
+
+ if (pktlen < 2)
+ error ("Truncated response packet from OCD device");
+
+ status = p[1];
+ error_code = p[2];
+
+ if (error_code != 0)
+ ocd_error ("OCD_SET_CTL_FLAGS:", error_code);
+#endif
+
+ immediate_quit--;
+
+/* This is really the job of start_remote however, that makes an assumption
+ that the target is about to print out a status message of some sort. That
+ doesn't happen here (in fact, it may not be possible to get the monitor to
+ send the appropriate packet). */
+
+ flush_cached_frames ();
+ registers_changed ();
+ stop_pc = read_pc ();
+ set_current_frame (create_new_frame (read_fp (), stop_pc));
+ select_frame (get_current_frame ());
+ print_stack_frame (selected_frame, -1, 1);
+
+ buf[0] = OCD_LOG_FILE;
+ buf[1] = 3; /* close existing WIGGLERS.LOG */
+ ocd_put_packet (buf, 2);
+ p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
+
+ buf[0] = OCD_LOG_FILE;
+ buf[1] = 2; /* append to existing WIGGLERS.LOG */
+ ocd_put_packet (buf, 2);
+ p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
+
+ return 1;
+}
+
+/* Open a connection to a remote debugger.
+ NAME is the filename used for communication. */
+
+void
+ocd_open (char *name, int from_tty, enum ocd_target_type target_type,
+ struct target_ops *ops)
+{
+ unsigned char buf[10], *p;
+ int pktlen;
+
+ if (name == 0)
+ error ("To open an OCD connection, you need to specify the\n\
+device the OCD device is attached to (e.g. /dev/ttya).");
+
+ target_preopen (from_tty);
+
+ current_ops = ops;
+
+ unpush_target (current_ops);
+
+ ocd_desc = serial_open (name);
+ if (!ocd_desc)
+ perror_with_name (name);
+
+ if (baud_rate != -1)
+ {
+ if (serial_setbaudrate (ocd_desc, baud_rate))
+ {
+ serial_close (ocd_desc);
+ perror_with_name (name);
+ }
+ }
+
+ serial_raw (ocd_desc);
+
+ /* If there is something sitting in the buffer we might take it as a
+ response to a command, which would be bad. */
+ serial_flush_input (ocd_desc);
+
+ if (from_tty)
+ {
+ puts_filtered ("Remote target wiggler connected to ");
+ puts_filtered (name);
+ puts_filtered ("\n");
+ }
+ push_target (current_ops); /* Switch to using remote target now */
+
+ /* Without this, some commands which require an active target (such as kill)
+ won't work. This variable serves (at least) double duty as both the pid
+ of the target process (if it has such), and as a flag indicating that a
+ target is active. These functions should be split out into seperate
+ variables, especially since GDB will someday have a notion of debugging
+ several processes. */
+
+ inferior_ptid = pid_to_ptid (42000);
+ /* Start the remote connection; if error (0), discard this target.
+ In particular, if the user quits, be sure to discard it
+ (we'd be in an inconsistent state otherwise). */
+ if (!catch_errors (ocd_start_remote, &target_type,
+ "Couldn't establish connection to remote target\n",
+ RETURN_MASK_ALL))
+ {
+ pop_target ();
+ error ("Failed to connect to OCD.");
+ }
+}
+
+/* This takes a program previously attached to and detaches it. After
+ this is done, GDB can be used to debug some other program. We
+ better not have left any breakpoints in the target program or it'll
+ die when it hits one. */
+
+void
+ocd_detach (char *args, int from_tty)
+{
+ if (args)
+ error ("Argument given to \"detach\" when remotely debugging.");
+
+ pop_target ();
+ if (from_tty)
+ puts_filtered ("Ending remote debugging.\n");
+}
+
+/* Tell the remote machine to resume. */
+
+void
+ocd_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ int pktlen;
+
+ if (step)
+ ocd_do_command (OCD_STEP, &last_run_status, &pktlen);
+ else
+ ocd_do_command (OCD_RUN, &last_run_status, &pktlen);
+}
+
+void
+ocd_stop (void)
+{
+ int status;
+ int pktlen;
+
+ ocd_do_command (OCD_STOP, &status, &pktlen);
+
+ if (!(status & OCD_FLAG_BDM))
+ error ("Can't stop target via BDM");
+}
+
+static volatile int ocd_interrupt_flag;
+
+/* Send ^C to target to halt it. Target will respond, and send us a
+ packet. */
+
+static void
+ocd_interrupt (int signo)
+{
+ /* If this doesn't work, try more severe steps. */
+ signal (signo, ocd_interrupt_twice);
+
+ if (remote_debug)
+ printf_unfiltered ("ocd_interrupt called\n");
+
+ {
+ char buf[1];
+
+ ocd_stop ();
+ buf[0] = OCD_AYT;
+ ocd_put_packet (buf, 1);
+ ocd_interrupt_flag = 1;
+ }
+}
+
+static void (*ofunc) ();
+
+/* The user typed ^C twice. */
+static void
+ocd_interrupt_twice (int signo)
+{
+ signal (signo, ofunc);
+
+ interrupt_query ();
+
+ signal (signo, ocd_interrupt);
+}
+
+/* Ask the user what to do when an interrupt is received. */
+
+static void
+interrupt_query (void)
+{
+ target_terminal_ours ();
+
+ if (query ("Interrupted while waiting for the program.\n\
+Give up (and stop debugging it)? "))
+ {
+ target_mourn_inferior ();
+ throw_exception (RETURN_QUIT);
+ }
+
+ target_terminal_inferior ();
+}
+
+/* If nonzero, ignore the next kill. */
+static int kill_kludge;
+
+/* Wait until the remote machine stops, then return,
+ storing status in STATUS just as `wait' would.
+ Returns "pid" (though it's not clear what, if anything, that
+ means in the case of this target). */
+
+int
+ocd_wait (void)
+{
+ unsigned char *p;
+ int error_code;
+ int pktlen;
+ char buf[1];
+
+ ocd_interrupt_flag = 0;
+
+ /* Target might already be stopped by the time we get here. */
+ /* If we aren't already stopped, we need to loop until we've dropped
+ back into BDM mode */
+
+ while (!(last_run_status & OCD_FLAG_BDM))
+ {
+ buf[0] = OCD_AYT;
+ ocd_put_packet (buf, 1);
+ p = ocd_get_packet (OCD_AYT, &pktlen, -1);
+
+ ofunc = (void (*)()) signal (SIGINT, ocd_interrupt);
+ signal (SIGINT, ofunc);
+
+ if (pktlen < 2)
+ error ("Truncated response packet from OCD device");
+
+ last_run_status = p[1];
+ error_code = p[2];
+
+ if (error_code != 0)
+ ocd_error ("target_wait:", error_code);
+
+ if (last_run_status & OCD_FLAG_PWF)
+ error ("OCD device lost VCC at BDM interface.");
+ else if (last_run_status & OCD_FLAG_CABLE_DISC)
+ error ("OCD device cable appears to have been disconnected.");
+ }
+
+ if (ocd_interrupt_flag)
+ return 1;
+ else
+ return 0;
+}
+
+/* Read registers from the OCD device. Specify the starting and ending
+ register number. Return the number of regs actually read in *NUMREGS.
+ Returns a pointer to a static array containing the register contents. */
+
+unsigned char *
+ocd_read_bdm_registers (int first_bdm_regno, int last_bdm_regno, int *reglen)
+{
+ unsigned char buf[10];
+ int i;
+ unsigned char *p;
+ unsigned char *regs;
+ int error_code, status;
+ int pktlen;
+
+ buf[0] = OCD_READ_REGS;
+ buf[1] = first_bdm_regno >> 8;
+ buf[2] = first_bdm_regno & 0xff;
+ buf[3] = last_bdm_regno >> 8;
+ buf[4] = last_bdm_regno & 0xff;
+
+ ocd_put_packet (buf, 5);
+ p = ocd_get_packet (OCD_READ_REGS, &pktlen, remote_timeout);
+
+ status = p[1];
+ error_code = p[2];
+
+ if (error_code != 0)
+ ocd_error ("read_bdm_registers:", error_code);
+
+ i = p[3];
+ if (i == 0)
+ i = 256;
+
+ if (i > pktlen - 4
+ || ((i & 3) != 0))
+ error ("Register block size bad: %d", i);
+
+ *reglen = i;
+
+ regs = p + 4;
+
+ return regs;
+}
+
+/* Read register BDM_REGNO and returns its value ala read_register() */
+
+CORE_ADDR
+ocd_read_bdm_register (int bdm_regno)
+{
+ int reglen;
+ unsigned char *p;
+ CORE_ADDR regval;
+
+ p = ocd_read_bdm_registers (bdm_regno, bdm_regno, &reglen);
+ regval = extract_unsigned_integer (p, reglen);
+
+ return regval;
+}
+
+void
+ocd_write_bdm_registers (int first_bdm_regno, unsigned char *regptr, int reglen)
+{
+ unsigned char *buf;
+ unsigned char *p;
+ int error_code, status;
+ int pktlen;
+
+ buf = alloca (4 + reglen);
+
+ buf[0] = OCD_WRITE_REGS;
+ buf[1] = first_bdm_regno >> 8;
+ buf[2] = first_bdm_regno & 0xff;
+ buf[3] = reglen;
+ memcpy (buf + 4, regptr, reglen);
+
+ ocd_put_packet (buf, 4 + reglen);
+ p = ocd_get_packet (OCD_WRITE_REGS, &pktlen, remote_timeout);
+
+ if (pktlen < 3)
+ error ("Truncated response packet from OCD device");
+
+ status = p[1];
+ error_code = p[2];
+
+ if (error_code != 0)
+ ocd_error ("ocd_write_bdm_registers:", error_code);
+}
+
+void
+ocd_write_bdm_register (int bdm_regno, CORE_ADDR reg)
+{
+ unsigned char buf[4];
+
+ store_unsigned_integer (buf, 4, reg);
+
+ ocd_write_bdm_registers (bdm_regno, buf, 4);
+}
+
+void
+ocd_prepare_to_store (void)
+{
+}
+
+/* Write memory data directly to the remote machine.
+ This does not inform the data cache; the data cache uses this.
+ MEMADDR is the address in the remote memory space.
+ MYADDR is the address of the buffer in our space.
+ LEN is the number of bytes.
+
+ Returns number of bytes transferred, or 0 for error. */
+
+static int write_mem_command = OCD_WRITE_MEM;
+
+int
+ocd_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ char buf[256 + 10];
+ unsigned char *p;
+ int origlen;
+
+ origlen = len;
+
+ buf[0] = write_mem_command;
+ buf[5] = 1; /* Write as bytes */
+ buf[6] = 0; /* Don't verify */
+
+ while (len > 0)
+ {
+ int numbytes;
+ int pktlen;
+ int status, error_code;
+
+ numbytes = min (len, 256 - 8);
+
+ buf[1] = memaddr >> 24;
+ buf[2] = memaddr >> 16;
+ buf[3] = memaddr >> 8;
+ buf[4] = memaddr;
+
+ buf[7] = numbytes;
+
+ memcpy (&buf[8], myaddr, numbytes);
+ ocd_put_packet (buf, 8 + numbytes);
+ p = ocd_get_packet (OCD_WRITE_MEM, &pktlen, remote_timeout);
+ if (pktlen < 3)
+ error ("Truncated response packet from OCD device");
+
+ status = p[1];
+ error_code = p[2];
+
+ if (error_code == 0x11) /* Got a bus error? */
+ {
+ CORE_ADDR error_address;
+
+ error_address = p[3] << 24;
+ error_address |= p[4] << 16;
+ error_address |= p[5] << 8;
+ error_address |= p[6];
+ numbytes = error_address - memaddr;
+
+ len -= numbytes;
+
+ errno = EIO;
+
+ break;
+ }
+ else if (error_code != 0)
+ ocd_error ("ocd_write_bytes:", error_code);
+
+ len -= numbytes;
+ memaddr += numbytes;
+ myaddr += numbytes;
+ }
+
+ return origlen - len;
+}
+
+/* Read memory data directly from the remote machine.
+ This does not use the data cache; the data cache uses this.
+ MEMADDR is the address in the remote memory space.
+ MYADDR is the address of the buffer in our space.
+ LEN is the number of bytes.
+
+ Returns number of bytes transferred, or 0 for error. */
+
+static int
+ocd_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ char buf[256 + 10];
+ unsigned char *p;
+ int origlen;
+
+ origlen = len;
+
+ buf[0] = OCD_READ_MEM;
+ buf[5] = 1; /* Read as bytes */
+
+ while (len > 0)
+ {
+ int numbytes;
+ int pktlen;
+ int status, error_code;
+
+ numbytes = min (len, 256 - 7);
+
+ buf[1] = memaddr >> 24;
+ buf[2] = memaddr >> 16;
+ buf[3] = memaddr >> 8;
+ buf[4] = memaddr;
+
+ buf[6] = numbytes;
+
+ ocd_put_packet (buf, 7);
+ p = ocd_get_packet (OCD_READ_MEM, &pktlen, remote_timeout);
+ if (pktlen < 4)
+ error ("Truncated response packet from OCD device");
+
+ status = p[1];
+ error_code = p[2];
+
+ if (error_code == 0x11) /* Got a bus error? */
+ {
+ CORE_ADDR error_address;
+
+ error_address = p[3] << 24;
+ error_address |= p[4] << 16;
+ error_address |= p[5] << 8;
+ error_address |= p[6];
+ numbytes = error_address - memaddr;
+
+ len -= numbytes;
+
+ errno = EIO;
+
+ break;
+ }
+ else if (error_code != 0)
+ ocd_error ("ocd_read_bytes:", error_code);
+
+ memcpy (myaddr, &p[4], numbytes);
+
+ len -= numbytes;
+ memaddr += numbytes;
+ myaddr += numbytes;
+ }
+
+ return origlen - len;
+}
+
+/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
+ to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
+ nonzero. Returns length of data written or read; 0 for error. TARGET
+ is ignored. */
+
+/* ARGSUSED */
+int
+ocd_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write,
+ struct mem_attrib *attrib, struct target_ops *target)
+{
+ int res;
+
+ if (should_write)
+ res = ocd_write_bytes (memaddr, myaddr, len);
+ else
+ res = ocd_read_bytes (memaddr, myaddr, len);
+
+ return res;
+}
+
+void
+ocd_files_info (struct target_ops *ignore)
+{
+ puts_filtered ("Debugging a target over a serial line.\n");
+}
+
+/* Stuff for dealing with the packets which are part of this protocol.
+ See comment at top of file for details. */
+
+/* Read a single character from the remote side, handling wierd errors. */
+
+static int
+readchar (int timeout)
+{
+ int ch;
+
+ ch = serial_readchar (ocd_desc, timeout);
+
+ switch (ch)
+ {
+ case SERIAL_EOF:
+ error ("Remote connection closed");
+ case SERIAL_ERROR:
+ perror_with_name ("Remote communication error");
+ case SERIAL_TIMEOUT:
+ default:
+ return ch;
+ }
+}
+
+#if 0
+/* Read a character from the data stream, dequoting as necessary. SYN is
+ treated special. Any SYNs appearing in the data stream are returned as the
+ distinct value RAW_SYN (which has a value > 8 bits and therefore cannot be
+ mistaken for real data). */
+
+static int
+get_quoted_char (int timeout)
+{
+ int ch;
+
+ ch = readchar (timeout);
+
+ switch (ch)
+ {
+ case SERIAL_TIMEOUT:
+ error ("Timeout in mid-packet, aborting");
+ case SYN:
+ return RAW_SYN;
+ case DLE:
+ ch = readchar (timeout);
+ if (ch == SYN)
+ return RAW_SYN;
+ return ch & ~0100;
+ default:
+ return ch;
+ }
+}
+
+static unsigned char pkt[256 * 2 + 10], *pktp; /* Worst case */
+
+static void
+reset_packet (void)
+{
+ pktp = pkt;
+}
+
+static void
+output_packet (void)
+{
+ if (serial_write (ocd_desc, pkt, pktp - pkt))
+ perror_with_name ("output_packet: write failed");
+
+ reset_packet ();
+}
+
+/* Output a quoted character. SYNs and DLEs are quoted. Everything else goes
+ through untouched. */
+
+static void
+put_quoted_char (int c)
+{
+ switch (c)
+ {
+ case SYN:
+ case DLE:
+ *pktp++ = DLE;
+ c |= 0100;
+ }
+
+ *pktp++ = c;
+}
+
+/* Send a packet to the OCD device. The packet framed by a SYN character,
+ a byte count and a checksum. The byte count only counts the number of
+ bytes between the count and the checksum. A count of zero actually
+ means 256. Any SYNs within the packet (including the checksum and
+ count) must be quoted. The quote character must be quoted as well.
+ Quoting is done by replacing the character with the two-character sequence
+ DLE, {char} | 0100. Note that the quoting mechanism has no effect on the
+ byte count. */
+
+static void
+stu_put_packet (unsigned char *buf, int len)
+{
+ unsigned char checksum;
+ unsigned char c;
+
+ if (len == 0 || len > 256)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* Can't represent 0 length packet */
+
+ reset_packet ();
+
+ checksum = 0;
+
+ put_quoted_char (RAW_SYN);
+
+ c = len;
+
+ do
+ {
+ checksum += c;
+
+ put_quoted_char (c);
+
+ c = *buf++;
+ }
+ while (len-- > 0);
+
+ put_quoted_char (-checksum & 0xff);
+
+ output_packet ();
+}
+
+#else
+
+/* Send a packet to the OCD device. The packet framed by a SYN character,
+ a byte count and a checksum. The byte count only counts the number of
+ bytes between the count and the checksum. A count of zero actually
+ means 256. Any SYNs within the packet (including the checksum and
+ count) must be quoted. The quote character must be quoted as well.
+ Quoting is done by replacing the character with the two-character sequence
+ DLE, {char} | 0100. Note that the quoting mechanism has no effect on the
+ byte count. */
+
+static void
+ocd_put_packet (unsigned char *buf, int len)
+{
+ unsigned char checksum;
+ unsigned char c;
+ unsigned char *packet, *packet_ptr;
+
+ packet = alloca (len + 1 + 1); /* packet + SYN + checksum */
+ packet_ptr = packet;
+
+ checksum = 0;
+
+ *packet_ptr++ = 0x55;
+
+ while (len-- > 0)
+ {
+ c = *buf++;
+
+ checksum += c;
+ *packet_ptr++ = c;
+ }
+
+ *packet_ptr++ = -checksum;
+ if (serial_write (ocd_desc, packet, packet_ptr - packet))
+ perror_with_name ("output_packet: write failed");
+}
+#endif
+
+#if 0
+/* Get a packet from the OCD device. Timeout is only enforced for the
+ first byte of the packet. Subsequent bytes are expected to arrive in
+ time <= remote_timeout. Returns a pointer to a static buffer containing
+ the payload of the packet. *LENP contains the length of the packet.
+ */
+
+static unsigned char *
+stu_get_packet (unsigned char cmd, int *lenp, int timeout)
+{
+ int ch;
+ int len;
+ static unsigned char buf[256 + 10], *p;
+ unsigned char checksum;
+
+find_packet:
+
+ ch = get_quoted_char (timeout);
+
+ if (ch < 0)
+ error ("get_packet (readchar): %d", ch);
+
+ if (ch != RAW_SYN)
+ goto find_packet;
+
+found_syn: /* Found the start of a packet */
+
+ p = buf;
+ checksum = 0;
+
+ len = get_quoted_char (remote_timeout);
+
+ if (len == RAW_SYN)
+ goto found_syn;
+
+ checksum += len;
+
+ if (len == 0)
+ len = 256;
+
+ len++; /* Include checksum */
+
+ while (len-- > 0)
+ {
+ ch = get_quoted_char (remote_timeout);
+ if (ch == RAW_SYN)
+ goto found_syn;
+
+ *p++ = ch;
+ checksum += ch;
+ }
+
+ if (checksum != 0)
+ goto find_packet;
+
+ if (cmd != buf[0])
+ error ("Response phase error. Got 0x%x, expected 0x%x", buf[0], cmd);
+
+ *lenp = p - buf - 1;
+ return buf;
+}
+
+#else
+
+/* Get a packet from the OCD device. Timeout is only enforced for the
+ first byte of the packet. Subsequent bytes are expected to arrive in
+ time <= remote_timeout. Returns a pointer to a static buffer containing
+ the payload of the packet. *LENP contains the length of the packet.
+ */
+
+static unsigned char *
+ocd_get_packet (int cmd, int *lenp, int timeout)
+{
+ int ch;
+ int len;
+ static unsigned char packet[512];
+ unsigned char *packet_ptr;
+ unsigned char checksum;
+
+ ch = readchar (timeout);
+
+ if (ch < 0)
+ error ("ocd_get_packet (readchar): %d", ch);
+
+ if (ch != 0x55)
+ error ("ocd_get_packet (readchar): %d", ch);
+
+/* Found the start of a packet */
+
+ packet_ptr = packet;
+ checksum = 0;
+
+/* Read command char. That sort of tells us how long the packet is. */
+
+ ch = readchar (timeout);
+
+ if (ch < 0)
+ error ("ocd_get_packet (readchar): %d", ch);
+
+ *packet_ptr++ = ch;
+ checksum += ch;
+
+/* Get status. */
+
+ ch = readchar (timeout);
+
+ if (ch < 0)
+ error ("ocd_get_packet (readchar): %d", ch);
+ *packet_ptr++ = ch;
+ checksum += ch;
+
+/* Get error code. */
+
+ ch = readchar (timeout);
+
+ if (ch < 0)
+ error ("ocd_get_packet (readchar): %d", ch);
+ *packet_ptr++ = ch;
+ checksum += ch;
+
+ switch (ch) /* Figure out length of packet */
+ {
+ case 0x7: /* Write verify error? */
+ len = 8; /* write address, value read back */
+ break;
+ case 0x11: /* Bus error? */
+ /* write address, read flag */
+ case 0x15: /* Internal error */
+ len = 5; /* error code, vector */
+ break;
+ default: /* Error w/no params */
+ len = 0;
+ break;
+ case 0x0: /* Normal result */
+ switch (packet[0])
+ {
+ case OCD_AYT: /* Are You There? */
+ case OCD_SET_BAUD_RATE: /* Set Baud Rate */
+ case OCD_INIT: /* Initialize OCD device */
+ case OCD_SET_SPEED: /* Set Speed */
+ case OCD_SET_FUNC_CODE: /* Set Function Code */
+ case OCD_SET_CTL_FLAGS: /* Set Control Flags */
+ case OCD_SET_BUF_ADDR: /* Set Register Buffer Address */
+ case OCD_RUN: /* Run Target from PC */
+ case OCD_RUN_ADDR: /* Run Target from Specified Address */
+ case OCD_STOP: /* Stop Target */
+ case OCD_RESET_RUN: /* Reset Target and Run */
+ case OCD_RESET: /* Reset Target and Halt */
+ case OCD_STEP: /* Single Step */
+ case OCD_WRITE_REGS: /* Write Register */
+ case OCD_WRITE_MEM: /* Write Memory */
+ case OCD_FILL_MEM: /* Fill Memory */
+ case OCD_MOVE_MEM: /* Move Memory */
+ case OCD_WRITE_INT_MEM: /* Write Internal Memory */
+ case OCD_JUMP: /* Jump to Subroutine */
+ case OCD_ERASE_FLASH: /* Erase flash memory */
+ case OCD_PROGRAM_FLASH: /* Write flash memory */
+ case OCD_EXIT_MON: /* Exit the flash programming monitor */
+ case OCD_ENTER_MON: /* Enter the flash programming monitor */
+ case OCD_LOG_FILE: /* Make Wigglers.dll save Wigglers.log */
+ case OCD_SET_CONNECTION: /* Set type of connection in Wigglers.dll */
+ len = 0;
+ break;
+ case OCD_GET_VERSION: /* Get Version */
+ len = 10;
+ break;
+ case OCD_GET_STATUS_MASK: /* Get Status Mask */
+ len = 1;
+ break;
+ case OCD_GET_CTRS: /* Get Error Counters */
+ case OCD_READ_REGS: /* Read Register */
+ case OCD_READ_MEM: /* Read Memory */
+ case OCD_READ_INT_MEM: /* Read Internal Memory */
+ len = 257;
+ break;
+ default:
+ error ("ocd_get_packet: unknown packet type 0x%x\n", ch);
+ }
+ }
+
+ if (len == 257) /* Byte stream? */
+ { /* Yes, byte streams contain the length */
+ ch = readchar (timeout);
+
+ if (ch < 0)
+ error ("ocd_get_packet (readchar): %d", ch);
+ *packet_ptr++ = ch;
+ checksum += ch;
+ len = ch;
+ if (len == 0)
+ len = 256;
+ }
+
+ while (len-- >= 0) /* Do rest of packet and checksum */
+ {
+ ch = readchar (timeout);
+
+ if (ch < 0)
+ error ("ocd_get_packet (readchar): %d", ch);
+ *packet_ptr++ = ch;
+ checksum += ch;
+ }
+
+ if (checksum != 0)
+ error ("ocd_get_packet: bad packet checksum");
+
+ if (cmd != -1 && cmd != packet[0])
+ error ("Response phase error. Got 0x%x, expected 0x%x", packet[0], cmd);
+
+ *lenp = packet_ptr - packet - 1; /* Subtract checksum byte */
+ return packet;
+}
+#endif
+
+/* Execute a simple (one-byte) command. Returns a pointer to the data
+ following the error code. */
+
+static unsigned char *
+ocd_do_command (int cmd, int *statusp, int *lenp)
+{
+ unsigned char buf[100], *p;
+ int status, error_code;
+ char errbuf[100];
+
+ unsigned char logbuf[100];
+ int logpktlen;
+
+ buf[0] = cmd;
+ ocd_put_packet (buf, 1); /* Send command */
+ p = ocd_get_packet (*buf, lenp, remote_timeout);
+
+ if (*lenp < 3)
+ error ("Truncated response packet from OCD device");
+
+ status = p[1];
+ error_code = p[2];
+
+ if (error_code != 0)
+ {
+ sprintf (errbuf, "ocd_do_command (0x%x):", cmd);
+ ocd_error (errbuf, error_code);
+ }
+
+ if (status & OCD_FLAG_PWF)
+ error ("OCD device can't detect VCC at BDM interface.");
+ else if (status & OCD_FLAG_CABLE_DISC)
+ error ("BDM cable appears to be disconnected.");
+
+ *statusp = status;
+
+ logbuf[0] = OCD_LOG_FILE;
+ logbuf[1] = 3; /* close existing WIGGLERS.LOG */
+ ocd_put_packet (logbuf, 2);
+ ocd_get_packet (logbuf[0], &logpktlen, remote_timeout);
+
+ logbuf[0] = OCD_LOG_FILE;
+ logbuf[1] = 2; /* append to existing WIGGLERS.LOG */
+ ocd_put_packet (logbuf, 2);
+ ocd_get_packet (logbuf[0], &logpktlen, remote_timeout);
+
+ return p + 3;
+}
+
+void
+ocd_kill (void)
+{
+ /* For some mysterious reason, wait_for_inferior calls kill instead of
+ mourn after it gets TARGET_WAITKIND_SIGNALLED. Work around it. */
+ if (kill_kludge)
+ {
+ kill_kludge = 0;
+ target_mourn_inferior ();
+ return;
+ }
+
+ /* Don't wait for it to die. I'm not really sure it matters whether
+ we do or not. */
+ target_mourn_inferior ();
+}
+
+void
+ocd_mourn (void)
+{
+ unpush_target (current_ops);
+ generic_mourn_inferior ();
+}
+
+/* All we actually do is set the PC to the start address of exec_bfd, and start
+ the program at that point. */
+
+void
+ocd_create_inferior (char *exec_file, char *args, char **env)
+{
+ if (args && (*args != '\000'))
+ error ("Args are not supported by BDM.");
+
+ clear_proceed_status ();
+ proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
+}
+
+void
+ocd_load (char *args, int from_tty)
+{
+ generic_load (args, from_tty);
+
+ inferior_ptid = null_ptid;
+
+/* This is necessary because many things were based on the PC at the time that
+ we attached to the monitor, which is no longer valid now that we have loaded
+ new code (and just changed the PC). Another way to do this might be to call
+ normal_stop, except that the stack may not be valid, and things would get
+ horribly confused... */
+
+ clear_symtab_users ();
+}
+
+/* This should be defined for each target */
+/* But we want to be able to compile this file for some configurations
+ not yet supported fully */
+
+#define BDM_BREAKPOINT {0x0,0x0,0x0,0x0} /* For ppc 8xx */
+#if 0
+#define BDM_BREAKPOINT {0x4a,0xfa} /* BGND insn used for CPU32 */
+#endif
+
+/* BDM (at least on CPU32) uses a different breakpoint */
+
+int
+ocd_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ static char break_insn[] = BDM_BREAKPOINT;
+ int val;
+
+ val = target_read_memory (addr, contents_cache, sizeof (break_insn));
+
+ if (val == 0)
+ val = target_write_memory (addr, break_insn, sizeof (break_insn));
+
+ return val;
+}
+
+int
+ocd_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ static char break_insn[] = BDM_BREAKPOINT;
+ int val;
+
+ val = target_write_memory (addr, contents_cache, sizeof (break_insn));
+
+ return val;
+}
+
+static void
+bdm_command (char *args, int from_tty)
+{
+ error ("bdm command must be followed by `reset'");
+}
+
+static void
+bdm_reset_command (char *args, int from_tty)
+{
+ int status, pktlen;
+
+ if (!ocd_desc)
+ error ("Not connected to OCD device.");
+
+ ocd_do_command (OCD_RESET, &status, &pktlen);
+ dcache_invalidate (target_dcache);
+ registers_changed ();
+}
+
+static void
+bdm_restart_command (char *args, int from_tty)
+{
+ int status, pktlen;
+
+ if (!ocd_desc)
+ error ("Not connected to OCD device.");
+
+ ocd_do_command (OCD_RESET_RUN, &status, &pktlen);
+ last_run_status = status;
+ clear_proceed_status ();
+ wait_for_inferior ();
+ normal_stop ();
+}
+
+/* Temporary replacement for target_store_registers(). This prevents
+ generic_load from trying to set the PC. */
+
+static void
+noop_store_registers (int regno)
+{
+}
+
+static void
+bdm_update_flash_command (char *args, int from_tty)
+{
+ int status, pktlen;
+ struct cleanup *old_chain;
+ void (*store_registers_tmp) (int);
+
+ if (!ocd_desc)
+ error ("Not connected to OCD device.");
+
+ if (!args)
+ error ("Must specify file containing new OCD code.");
+
+/* old_chain = make_cleanup (flash_cleanup, 0); */
+
+ ocd_do_command (OCD_ENTER_MON, &status, &pktlen);
+
+ ocd_do_command (OCD_ERASE_FLASH, &status, &pktlen);
+
+ write_mem_command = OCD_PROGRAM_FLASH;
+ store_registers_tmp = current_target.to_store_registers;
+ current_target.to_store_registers = noop_store_registers;
+
+ generic_load (args, from_tty);
+
+ current_target.to_store_registers = store_registers_tmp;
+ write_mem_command = OCD_WRITE_MEM;
+
+ ocd_do_command (OCD_EXIT_MON, &status, &pktlen);
+
+/* discard_cleanups (old_chain); */
+}
+
+static void
+bdm_read_register_command (char *args, int from_tty)
+{
+ /* XXX repeat should go on to the next register */
+
+ if (!ocd_desc)
+ error ("Not connected to OCD device.");
+
+ if (!args)
+ error ("Must specify BDM register number.");
+
+}
+
+void
+_initialize_remote_ocd (void)
+{
+ extern struct cmd_list_element *cmdlist;
+ static struct cmd_list_element *ocd_cmd_list = NULL;
+
+ add_show_from_set (add_set_cmd ("remotetimeout", no_class,
+ var_integer, (char *) &remote_timeout,
+ "Set timeout value for remote read.\n", &setlist),
+ &showlist);
+
+ add_prefix_cmd ("ocd", class_obscure, bdm_command, "", &ocd_cmd_list, "ocd ",
+ 0, &cmdlist);
+
+ add_cmd ("reset", class_obscure, bdm_reset_command, "", &ocd_cmd_list);
+ add_cmd ("restart", class_obscure, bdm_restart_command, "", &ocd_cmd_list);
+ add_cmd ("update-flash", class_obscure, bdm_update_flash_command, "", &ocd_cmd_list);
+ /* add_cmd ("read-register", class_obscure, bdm_read_register_command, "", &ocd_cmd_list); */
+}
diff --git a/gdb/ocd.h b/gdb/ocd.h
new file mode 100644
index 00000000000..5fa1fb95235
--- /dev/null
+++ b/gdb/ocd.h
@@ -0,0 +1,139 @@
+/* Definitions for the Macraigor Systems BDM Wiggler
+ Copyright 1996, 1997, 1998, 2000, 2001 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. */
+
+#ifndef OCD_H
+#define OCD_H
+
+/* Wiggler serial protocol definitions */
+
+#define DLE 020 /* Quote char */
+#define SYN 026 /* Start of packet */
+#define RAW_SYN ((026 << 8) | 026) /* get_quoted_char found a naked SYN */
+
+/* Status flags */
+
+#define OCD_FLAG_RESET 0x01 /* Target is being reset */
+#define OCD_FLAG_STOPPED 0x02 /* Target is halted */
+#define OCD_FLAG_BDM 0x04 /* Target is in BDM */
+#define OCD_FLAG_PWF 0x08 /* Power failed */
+#define OCD_FLAG_CABLE_DISC 0x10 /* BDM cable disconnected */
+
+/* Commands */
+
+#define OCD_AYT 0x0 /* Are you there? */
+#define OCD_GET_VERSION 0x1 /* Get Version */
+#define OCD_SET_BAUD_RATE 0x2 /* Set Baud Rate */
+#define OCD_INIT 0x10 /* Initialize Wiggler */
+#define OCD_SET_SPEED 0x11 /* Set Speed */
+#define OCD_GET_STATUS_MASK 0x12 /* Get Status Mask */
+#define OCD_GET_CTRS 0x13 /* Get Error Counters */
+#define OCD_SET_FUNC_CODE 0x14 /* Set Function Code */
+#define OCD_SET_CTL_FLAGS 0x15 /* Set Control Flags */
+#define OCD_SET_BUF_ADDR 0x16 /* Set Register Buffer Address */
+#define OCD_RUN 0x20 /* Run Target from PC */
+#define OCD_RUN_ADDR 0x21 /* Run Target from Specified Address */
+#define OCD_STOP 0x22 /* Stop Target */
+#define OCD_RESET_RUN 0x23 /* Reset Target and Run */
+#define OCD_RESET 0x24 /* Reset Target and Halt */
+#define OCD_STEP 0x25 /* Single step */
+#define OCD_READ_REGS 0x30 /* Read Registers */
+#define OCD_WRITE_REGS 0x31 /* Write Registers */
+#define OCD_READ_MEM 0x32 /* Read Memory */
+#define OCD_WRITE_MEM 0x33 /* Write Memory */
+#define OCD_FILL_MEM 0x34 /* Fill Memory */
+#define OCD_MOVE_MEM 0x35 /* Move Memory */
+
+#define OCD_READ_INT_MEM 0x80 /* Read Internal Memory */
+#define OCD_WRITE_INT_MEM 0x81 /* Write Internal Memory */
+#define OCD_JUMP 0x82 /* Jump to Subroutine */
+
+#define OCD_ERASE_FLASH 0x90 /* Erase flash memory */
+#define OCD_PROGRAM_FLASH 0x91 /* Write flash memory */
+#define OCD_EXIT_MON 0x93 /* Exit the flash programming monitor */
+#define OCD_ENTER_MON 0x94 /* Enter the flash programming monitor */
+
+#define OCD_SET_STATUS 0x0a /* Set status */
+#define OCD_SET_CONNECTION 0xf0 /* Set connection (init Wigglers.dll) */
+#define OCD_LOG_FILE 0xf1 /* Cmd to get Wigglers.dll to log cmds */
+#define OCD_FLAG_STOP 0x0 /* Stop the target, enter BDM */
+#define OCD_FLAG_START 0x01 /* Start the target at PC */
+#define OCD_FLAG_RETURN_STATUS 0x04 /* Return async status */
+
+/* Target type (for OCD_INIT command) */
+
+enum ocd_target_type
+ {
+ OCD_TARGET_CPU32 = 0x0, /* Moto cpu32 family */
+ OCD_TARGET_CPU16 = 0x1,
+ OCD_TARGET_MOTO_PPC = 0x2, /* Motorola PPC 5xx/8xx */
+ OCD_TARGET_IBM_PPC = 0x3
+ }; /* IBM PPC 4xx */
+
+void ocd_open (char *name, int from_tty, enum ocd_target_type,
+ struct target_ops *ops);
+
+void ocd_close (int quitting);
+
+void ocd_detach (char *args, int from_tty);
+
+void ocd_resume (ptid_t ptid, int step, enum target_signal siggnal);
+
+void ocd_prepare_to_store (void);
+
+void ocd_stop (void);
+
+void ocd_files_info (struct target_ops *ignore);
+
+
+int ocd_xfer_memory (CORE_ADDR memaddr, char *myaddr,
+ int len, int should_write,
+ struct mem_attrib *attrib,
+ struct target_ops *target);
+
+void ocd_mourn (void);
+
+void ocd_create_inferior (char *exec_file, char *args, char **env);
+
+int ocd_thread_alive (ptid_t th);
+
+void ocd_error (char *s, int error_code);
+
+void ocd_kill (void);
+
+void ocd_load (char *args, int from_tty);
+
+unsigned char *ocd_read_bdm_registers (int first_bdm_regno,
+ int last_bdm_regno, int *reglen);
+
+CORE_ADDR ocd_read_bdm_register (int bdm_regno);
+
+void ocd_write_bdm_registers (int first_bdm_regno,
+ unsigned char *regptr, int reglen);
+
+void ocd_write_bdm_register (int bdm_regno, CORE_ADDR reg);
+
+int ocd_wait (void);
+
+int ocd_insert_breakpoint (CORE_ADDR addr, char *contents_cache);
+int ocd_remove_breakpoint (CORE_ADDR addr, char *contents_cache);
+
+int ocd_write_bytes (CORE_ADDR memaddr, char *myaddr, int len);
+
+#endif /* OCD_H */
diff --git a/gdb/op50-rom.c b/gdb/op50-rom.c
new file mode 100644
index 00000000000..a256c91455b
--- /dev/null
+++ b/gdb/op50-rom.c
@@ -0,0 +1,142 @@
+/* Remote target glue for the Oki op50n based eval board.
+
+ Copyright 1995, 1998, 1999, 2000 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+
+static void op50n_open (char *args, int from_tty);
+
+/*
+ * this array of registers need to match the indexes used by GDB. The
+ * whole reason this exists is cause the various ROM monitors use
+ * different strings than GDB does, and doesn't support all the
+ * registers either. So, typing "info reg sp" becomes a "r30".
+ */
+
+static char *op50n_regnames[NUM_REGS] =
+{
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "cr11", "p", NULL, NULL, NULL, "cr15", "cr19", "cr20",
+ "cr21", "cr22", NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "cr0", "cr8", "cr9", "cr10", "cr12",
+ "cr13", "cr24", "cr25", "cr26",
+};
+
+/*
+ * Define the monitor command strings. Since these are passed directly
+ * through to a printf style function, we need can include formatting
+ * strings. We also need a CR or LF on the end.
+ */
+
+static struct target_ops op50n_ops;
+
+static char *op50n_inits[] =
+{".\r", NULL};
+
+static struct monitor_ops op50n_cmds;
+
+static void
+init_op50n_cmds (void)
+{
+ op50n_cmds.flags = MO_CLR_BREAK_USES_ADDR /*| MO_GETMEM_READ_SINGLE */ ; /* flags */
+ op50n_cmds.init = op50n_inits; /* Init strings */
+ op50n_cmds.cont = "g\r"; /* continue command */
+ op50n_cmds.step = "t\r"; /* single step */
+ op50n_cmds.stop = "\003.\r"; /* Interrupt char */
+ op50n_cmds.set_break = "b %x\r"; /* set a breakpoint */
+ op50n_cmds.clr_break = "b %x;0\r"; /* clear breakpoint at addr */
+ op50n_cmds.clr_all_break = "bx\r"; /* clear all breakpoints */
+ op50n_cmds.fill = "fx %x s%x %x\r"; /* memory fill cmd (addr, len, val) */
+ op50n_cmds.setmem.cmdb = "sx %x %x\r"; /* setmem.cmdb (addr, value) */
+ op50n_cmds.setmem.cmdw = "sh %x %x\r"; /* setmem.cmdw (addr, value) */
+ op50n_cmds.setmem.cmdl = "s %x %x\r"; /* setmem.cmdl (addr, value) */
+ op50n_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ op50n_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */
+ op50n_cmds.setmem.term = NULL; /* setmem.term */
+ op50n_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */
+#if 0
+ {
+ "sx %x\r", /* getmem.cmdb (addr, len) */
+ "sh %x\r", /* getmem.cmdw (addr, len) */
+ "s %x\r", /* getmem.cmdl (addr, len) */
+ NULL, /* getmem.cmdll (addr, len) */
+ " : ", /* getmem.resp_delim */
+ " ", /* getmem.term */
+ ".\r", /* getmem.term_cmd */
+ };
+#else
+ op50n_cmds.getmem.cmdb = "dx %x s%x\r"; /* getmem.cmdb (addr, len) */
+ op50n_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */
+ op50n_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */
+ op50n_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ op50n_cmds.getmem.resp_delim = " : "; /* getmem.resp_delim */
+ op50n_cmds.getmem.term = NULL; /* getmem.term */
+ op50n_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
+#endif
+ op50n_cmds.setreg.cmd = "x %s %x\r"; /* setreg.cmd (name, value) */
+ op50n_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ op50n_cmds.setreg.term = NULL; /* setreg.term */
+ op50n_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
+ op50n_cmds.getreg.cmd = "x %s\r"; /* getreg.cmd (name) */
+ op50n_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */
+ op50n_cmds.getreg.term = " "; /* getreg.term */
+ op50n_cmds.getreg.term_cmd = ".\r"; /* getreg.term_cmd */
+ op50n_cmds.dump_registers = NULL; /* dump_registers */
+ op50n_cmds.register_pattern = NULL; /* register_pattern */
+ op50n_cmds.supply_register = NULL; /* supply_register */
+ op50n_cmds.load_routine = NULL; /* load routine */
+ op50n_cmds.load = "r 0\r"; /* download command */
+ op50n_cmds.loadresp = NULL; /* load response */
+ op50n_cmds.prompt = "\n#"; /* monitor command prompt */
+ op50n_cmds.line_term = "\r"; /* end-of-command delimitor */
+ op50n_cmds.cmd_end = NULL; /* optional command terminator */
+ op50n_cmds.target = &op50n_ops; /* target operations */
+ op50n_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ op50n_cmds.regnames = op50n_regnames; /* register names */
+ op50n_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+};
+
+static void
+op50n_open (char *args, int from_tty)
+{
+ monitor_open (args, &op50n_cmds, from_tty);
+}
+
+void
+_initialize_op50n (void)
+{
+ init_op50n_cmds ();
+ init_monitor_ops (&op50n_ops);
+
+ op50n_ops.to_shortname = "op50n";
+ op50n_ops.to_longname = "Oki's debug monitor for the Op50n Eval board";
+ op50n_ops.to_doc = "Debug on a Oki OP50N eval board.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ op50n_ops.to_open = op50n_open;
+
+ add_target (&op50n_ops);
+}
diff --git a/gdb/os9kread.c b/gdb/os9kread.c
new file mode 100644
index 00000000000..498498ba2b5
--- /dev/null
+++ b/gdb/os9kread.c
@@ -0,0 +1,1621 @@
+/* Read os9/os9k symbol tables and convert to internal format, for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001
+ 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. */
+
+/* This module provides three functions: os9k_symfile_init,
+ which initializes to read a symbol file; os9k_new_init, which
+ discards existing cached information when all symbols are being
+ discarded; and os9k_symfile_read, which reads a symbol table
+ from a file.
+
+ os9k_symfile_read only does the minimum work necessary for letting the
+ user "name" things symbolically; it does not read the entire symtab.
+ Instead, it reads the external and static symbols and puts them in partial
+ symbol tables. When more extensive information is requested of a
+ file, the corresponding partial symbol table is mutated into a full
+ fledged symbol table by going back and reading the symbols
+ for real. os9k_psymtab_to_symtab() is the function that does this */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "gdb_assert.h"
+#include <stdio.h>
+
+#if defined(USG) || defined(__CYGNUSCLIB__)
+#include <sys/types.h>
+#include <fcntl.h>
+#endif
+
+#include "obstack.h"
+#include "gdb_stat.h"
+#include "symtab.h"
+#include "breakpoint.h"
+#include "command.h"
+#include "target.h"
+#include "gdbcore.h" /* for bfd stuff */
+#include "libaout.h" /* FIXME Secret internal BFD stuff for a.out */
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "gdb-stabs.h"
+#include "demangle.h"
+#include "language.h" /* Needed inside partial-stab.h */
+#include "complaints.h"
+#include "os9k.h"
+#include "stabsread.h"
+
+extern void _initialize_os9kread (void);
+
+/* Each partial symbol table entry contains a pointer to private data for the
+ read_symtab() function to use when expanding a partial symbol table entry
+ to a full symbol table entry.
+
+ For dbxread this structure contains the offset within the file symbol table
+ of first local symbol for this file, and count of the section
+ of the symbol table devoted to this file's symbols (actually, the section
+ bracketed may contain more than just this file's symbols). It also contains
+ further information needed to locate the symbols if they are in an ELF file.
+
+ If ldsymcnt is 0, the only reason for this thing's existence is the
+ dependency list. Nothing else will happen when it is read in. */
+
+#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
+#define LDSYMCNT(p) (((struct symloc *)((p)->read_symtab_private))->ldsymnum)
+
+struct symloc
+ {
+ int ldsymoff;
+ int ldsymnum;
+ };
+
+/* Remember what we deduced to be the source language of this psymtab. */
+static enum language psymtab_language = language_unknown;
+
+/* keep partial symbol table file nested depth */
+static int psymfile_depth = 0;
+
+/* keep symbol table file nested depth */
+static int symfile_depth = 0;
+
+extern int previous_stab_code;
+
+/* Name of last function encountered. Used in Solaris to approximate
+ object file boundaries. */
+static char *last_function_name;
+
+/* Complaints about the symbols we have encountered. */
+extern struct complaint lbrac_complaint;
+
+extern struct complaint unknown_symtype_complaint;
+
+extern struct complaint unknown_symchar_complaint;
+
+extern struct complaint lbrac_rbrac_complaint;
+
+extern struct complaint repeated_header_complaint;
+
+extern struct complaint repeated_header_name_complaint;
+
+#if 0
+static struct complaint lbrac_unmatched_complaint =
+{"unmatched Increment Block Entry before symtab pos %d", 0, 0};
+
+static struct complaint lbrac_mismatch_complaint =
+{"IBE/IDE symbol mismatch at symtab pos %d", 0, 0};
+#endif
+
+/* Local function prototypes */
+
+static void read_minimal_symbols (struct objfile *);
+
+static void os9k_read_ofile_symtab (struct partial_symtab *);
+
+static void os9k_psymtab_to_symtab (struct partial_symtab *);
+
+static void os9k_psymtab_to_symtab_1 (struct partial_symtab *);
+
+static void read_os9k_psymtab (struct objfile *, CORE_ADDR, int);
+
+static int fill_sym (FILE *, bfd *);
+
+static void os9k_symfile_init (struct objfile *);
+
+static void os9k_new_init (struct objfile *);
+
+static void os9k_symfile_read (struct objfile *, int);
+
+static void os9k_symfile_finish (struct objfile *);
+
+static void
+os9k_process_one_symbol (int, int, CORE_ADDR, char *,
+ struct section_offsets *, struct objfile *);
+
+static struct partial_symtab *os9k_start_psymtab (struct objfile *, char *,
+ CORE_ADDR, int, int,
+ struct partial_symbol **,
+ struct partial_symbol **);
+
+static struct partial_symtab *os9k_end_psymtab (struct partial_symtab *,
+ char **, int, int, CORE_ADDR,
+ struct partial_symtab **,
+ int);
+
+static void record_minimal_symbol (char *, CORE_ADDR, int, struct objfile *);
+
+#define HANDLE_RBRAC(val) \
+ if ((val) > pst->texthigh) pst->texthigh = (val);
+
+#define SWAP_STBHDR(hdrp, abfd) \
+ { \
+ (hdrp)->fmtno = bfd_get_16(abfd, (unsigned char *)&(hdrp)->fmtno); \
+ (hdrp)->crc = bfd_get_32(abfd, (unsigned char *)&(hdrp)->crc); \
+ (hdrp)->offset = bfd_get_32(abfd, (unsigned char *)&(hdrp)->offset); \
+ (hdrp)->nsym = bfd_get_32(abfd, (unsigned char *)&(hdrp)->nsym); \
+ }
+#define SWAP_STBSYM(symp, abfd) \
+ { \
+ (symp)->value = bfd_get_32(abfd, (unsigned char *)&(symp)->value); \
+ (symp)->type = bfd_get_16(abfd, (unsigned char *)&(symp)->type); \
+ (symp)->stroff = bfd_get_32(abfd, (unsigned char *)&(symp)->stroff); \
+ }
+#define N_DATA 0
+#define N_BSS 1
+#define N_RDATA 2
+#define N_IDATA 3
+#define N_TEXT 4
+#define N_ABS 6
+
+static void
+record_minimal_symbol (char *name, CORE_ADDR address, int type,
+ struct objfile *objfile)
+{
+ enum minimal_symbol_type ms_type;
+
+ switch (type)
+ {
+ case N_TEXT:
+ ms_type = mst_text;
+ address += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ break;
+ case N_DATA:
+ ms_type = mst_data;
+ break;
+ case N_BSS:
+ ms_type = mst_bss;
+ break;
+ case N_RDATA:
+ ms_type = mst_bss;
+ break;
+ case N_IDATA:
+ ms_type = mst_data;
+ break;
+ case N_ABS:
+ ms_type = mst_abs;
+ break;
+ default:
+ ms_type = mst_unknown;
+ break;
+ }
+
+ prim_record_minimal_symbol (name, address, ms_type, objfile);
+}
+
+/* read and process .stb file and store in minimal symbol table */
+typedef char mhhdr[80];
+struct stbhdr
+ {
+ mhhdr comhdr;
+ char *name;
+ short fmtno;
+ int crc;
+ int offset;
+ int nsym;
+ char *pad;
+ };
+struct stbsymbol
+ {
+ int value;
+ short type;
+ int stroff;
+ };
+#define STBSYMSIZE 10
+
+static void
+read_minimal_symbols (struct objfile *objfile)
+{
+ FILE *fp;
+ bfd *abfd;
+ struct stbhdr hdr;
+ struct stbsymbol sym;
+ int ch, i, j, off;
+ char buf[64], buf1[128];
+
+ fp = objfile->auxf1;
+ if (fp == NULL)
+ return;
+ abfd = objfile->obfd;
+ fread (&hdr.comhdr[0], sizeof (mhhdr), 1, fp);
+ i = 0;
+ ch = getc (fp);
+ while (ch != -1)
+ {
+ buf[i] = (char) ch;
+ i++;
+ if (ch == 0)
+ break;
+ ch = getc (fp);
+ };
+ if (i % 2)
+ ch = getc (fp);
+ hdr.name = &buf[0];
+
+ fread (&hdr.fmtno, sizeof (hdr.fmtno), 1, fp);
+ fread (&hdr.crc, sizeof (hdr.crc), 1, fp);
+ fread (&hdr.offset, sizeof (hdr.offset), 1, fp);
+ fread (&hdr.nsym, sizeof (hdr.nsym), 1, fp);
+ SWAP_STBHDR (&hdr, abfd);
+
+ /* read symbols */
+ init_minimal_symbol_collection ();
+ off = hdr.offset;
+ for (i = hdr.nsym; i > 0; i--)
+ {
+ fseek (fp, (long) off, 0);
+ fread (&sym.value, sizeof (sym.value), 1, fp);
+ fread (&sym.type, sizeof (sym.type), 1, fp);
+ fread (&sym.stroff, sizeof (sym.stroff), 1, fp);
+ SWAP_STBSYM (&sym, abfd);
+ fseek (fp, (long) sym.stroff, 0);
+ j = 0;
+ ch = getc (fp);
+ while (ch != -1)
+ {
+ buf1[j] = (char) ch;
+ j++;
+ if (ch == 0)
+ break;
+ ch = getc (fp);
+ };
+ record_minimal_symbol (buf1, sym.value, sym.type & 7, objfile);
+ off += STBSYMSIZE;
+ };
+ install_minimal_symbols (objfile);
+ return;
+}
+
+/* Scan and build partial symbols for a symbol file.
+ We have been initialized by a call to os9k_symfile_init, which
+ put all the relevant info into a "struct os9k_symfile_info",
+ hung off the objfile structure.
+
+ MAINLINE is true if we are reading the main symbol
+ table (as opposed to a shared lib or dynamically loaded file). */
+
+static void
+os9k_symfile_read (struct objfile *objfile, int mainline)
+{
+ bfd *sym_bfd;
+ struct cleanup *back_to;
+
+ sym_bfd = objfile->obfd;
+ /* If we are reinitializing, or if we have never loaded syms yet, init */
+ if (mainline
+ || (objfile->global_psymbols.size == 0
+ && objfile->static_psymbols.size == 0))
+ init_psymbol_list (objfile, DBX_SYMCOUNT (objfile));
+
+ free_pending_blocks ();
+ back_to = make_cleanup (really_free_pendings, 0);
+
+ make_cleanup_discard_minimal_symbols ();
+ read_minimal_symbols (objfile);
+
+ /* Now that the symbol table data of the executable file are all in core,
+ process them and define symbols accordingly. */
+ read_os9k_psymtab (objfile,
+ DBX_TEXT_ADDR (objfile),
+ DBX_TEXT_SIZE (objfile));
+
+ do_cleanups (back_to);
+}
+
+/* Initialize anything that needs initializing when a completely new
+ symbol file is specified (not just adding some symbols from another
+ file, e.g. a shared library). */
+
+static void
+os9k_new_init (struct objfile *ignore)
+{
+ stabsread_new_init ();
+ buildsym_new_init ();
+ psymfile_depth = 0;
+/*
+ init_header_files ();
+ */
+}
+
+/* os9k_symfile_init ()
+ It is passed a struct objfile which contains, among other things,
+ the BFD for the file whose symbols are being read, and a slot for a pointer
+ to "private data" which we fill with goodies.
+
+ Since BFD doesn't know how to read debug symbols in a format-independent
+ way (and may never do so...), we have to do it ourselves. We will never
+ be called unless this is an a.out (or very similar) file.
+ FIXME, there should be a cleaner peephole into the BFD environment here. */
+
+static void
+os9k_symfile_init (struct objfile *objfile)
+{
+ bfd *sym_bfd = objfile->obfd;
+ char *name = bfd_get_filename (sym_bfd);
+ char dbgname[512], stbname[512];
+ FILE *symfile = 0;
+ FILE *minfile = 0;
+ asection *text_sect;
+
+ strcpy (dbgname, name);
+ strcat (dbgname, ".dbg");
+ strcpy (stbname, name);
+ strcat (stbname, ".stb");
+
+ if ((symfile = fopen (dbgname, "r")) == NULL)
+ {
+ warning ("Symbol file %s not found", dbgname);
+ }
+ objfile->auxf2 = symfile;
+
+ if ((minfile = fopen (stbname, "r")) == NULL)
+ {
+ warning ("Symbol file %s not found", stbname);
+ }
+ objfile->auxf1 = minfile;
+
+ /* Allocate struct to keep track of the symfile */
+ objfile->sym_stab_info = (struct dbx_symfile_info *)
+ xmmalloc (objfile->md, sizeof (struct dbx_symfile_info));
+ DBX_SYMFILE_INFO (objfile)->stab_section_info = NULL;
+
+ text_sect = bfd_get_section_by_name (sym_bfd, ".text");
+ if (!text_sect)
+ error ("Can't find .text section in file");
+ DBX_TEXT_ADDR (objfile) = bfd_section_vma (sym_bfd, text_sect);
+ DBX_TEXT_SIZE (objfile) = bfd_section_size (sym_bfd, text_sect);
+
+ DBX_SYMBOL_SIZE (objfile) = 0; /* variable size symbol */
+ DBX_SYMCOUNT (objfile) = 0; /* used to be bfd_get_symcount(sym_bfd) */
+ DBX_SYMTAB_OFFSET (objfile) = 0; /* used to be SYMBOL_TABLE_OFFSET */
+}
+
+/* Perform any local cleanups required when we are done with a particular
+ objfile. I.E, we are in the process of discarding all symbol information
+ for an objfile, freeing up all memory held for it, and unlinking the
+ objfile struct from the global list of known objfiles. */
+
+static void
+os9k_symfile_finish (struct objfile *objfile)
+{
+ if (objfile->sym_stab_info != NULL)
+ {
+ xmfree (objfile->md, objfile->sym_stab_info);
+ }
+/*
+ free_header_files ();
+ */
+}
+
+
+struct st_dbghdr
+{
+ int sync;
+ short rev;
+ int crc;
+ short os;
+ short cpu;
+};
+#define SYNC (int)0xefbefeca
+
+#define SWAP_DBGHDR(hdrp, abfd) \
+ { \
+ (hdrp)->sync = bfd_get_32(abfd, (unsigned char *)&(hdrp)->sync); \
+ (hdrp)->rev = bfd_get_16(abfd, (unsigned char *)&(hdrp)->rev); \
+ (hdrp)->crc = bfd_get_32(abfd, (unsigned char *)&(hdrp)->crc); \
+ (hdrp)->os = bfd_get_16(abfd, (unsigned char *)&(hdrp)->os); \
+ (hdrp)->cpu = bfd_get_16(abfd, (unsigned char *)&(hdrp)->cpu); \
+ }
+
+#define N_SYM_CMPLR 0
+#define N_SYM_SLINE 1
+#define N_SYM_SYM 2
+#define N_SYM_LBRAC 3
+#define N_SYM_RBRAC 4
+#define N_SYM_SE 5
+
+struct internal_symstruct
+ {
+ short n_type;
+ short n_desc;
+ long n_value;
+ char *n_strx;
+ };
+static struct internal_symstruct symbol;
+static struct internal_symstruct *symbuf = &symbol;
+static char strbuf[4096];
+static struct st_dbghdr dbghdr;
+static short cmplrid;
+
+#define VER_PRE_ULTRAC ((short)4)
+#define VER_ULTRAC ((short)5)
+
+static int
+fill_sym (FILE *dbg_file, bfd *abfd)
+{
+ short si, nmask;
+ long li;
+ int ii;
+ char *p;
+
+ int nbytes = fread (&si, sizeof (si), 1, dbg_file);
+ if (nbytes == 0)
+ return 0;
+ if (nbytes < 0)
+ perror_with_name ("reading .dbg file.");
+ symbuf->n_desc = 0;
+ symbuf->n_value = 0;
+ symbuf->n_strx = NULL;
+ symbuf->n_type = bfd_get_16 (abfd, (unsigned char *) &si);
+ symbuf->n_type = 0xf & symbuf->n_type;
+ switch (symbuf->n_type)
+ {
+ case N_SYM_CMPLR:
+ fread (&si, sizeof (si), 1, dbg_file);
+ symbuf->n_desc = bfd_get_16 (abfd, (unsigned char *) &si);
+ cmplrid = symbuf->n_desc & 0xff;
+ break;
+ case N_SYM_SLINE:
+ fread (&li, sizeof (li), 1, dbg_file);
+ symbuf->n_value = bfd_get_32 (abfd, (unsigned char *) &li);
+ fread (&li, sizeof (li), 1, dbg_file);
+ li = bfd_get_32 (abfd, (unsigned char *) &li);
+ symbuf->n_strx = (char *) (li >> 12);
+ symbuf->n_desc = li & 0xfff;
+ break;
+ case N_SYM_SYM:
+ fread (&li, sizeof (li), 1, dbg_file);
+ symbuf->n_value = bfd_get_32 (abfd, (unsigned char *) &li);
+ si = 0;
+ do
+ {
+ ii = getc (dbg_file);
+ strbuf[si++] = (char) ii;
+ }
+ while (ii != 0 || si % 2 != 0);
+ symbuf->n_strx = strbuf;
+ p = (char *) strchr (strbuf, ':');
+ if (!p)
+ break;
+ if ((p[1] == 'F' || p[1] == 'f') && cmplrid == VER_PRE_ULTRAC)
+ {
+ fread (&si, sizeof (si), 1, dbg_file);
+ nmask = bfd_get_16 (abfd, (unsigned char *) &si);
+ for (ii = 0; ii < nmask; ii++)
+ fread (&si, sizeof (si), 1, dbg_file);
+ }
+ break;
+ case N_SYM_LBRAC:
+ fread (&li, sizeof (li), 1, dbg_file);
+ symbuf->n_value = bfd_get_32 (abfd, (unsigned char *) &li);
+ break;
+ case N_SYM_RBRAC:
+ fread (&li, sizeof (li), 1, dbg_file);
+ symbuf->n_value = bfd_get_32 (abfd, (unsigned char *) &li);
+ break;
+ case N_SYM_SE:
+ break;
+ }
+ return 1;
+}
+
+/* Given pointers to an a.out symbol table in core containing dbx
+ style data, setup partial_symtab's describing each source file for
+ which debugging information is available.
+ SYMFILE_NAME is the name of the file we are reading from. */
+
+static void
+read_os9k_psymtab (struct objfile *objfile, CORE_ADDR text_addr, int text_size)
+{
+ register struct internal_symstruct *bufp = 0; /* =0 avoids gcc -Wall glitch */
+ register char *namestring;
+ int past_first_source_file = 0;
+ CORE_ADDR last_o_file_start = 0;
+#if 0
+ struct cleanup *back_to;
+#endif
+ bfd *abfd;
+ FILE *fp;
+
+ /* End of the text segment of the executable file. */
+ static CORE_ADDR end_of_text_addr;
+
+ /* Current partial symtab */
+ static struct partial_symtab *pst = 0;
+
+ /* List of current psymtab's include files */
+ char **psymtab_include_list;
+ int includes_allocated;
+ int includes_used;
+
+ /* Index within current psymtab dependency list */
+ struct partial_symtab **dependency_list;
+ int dependencies_used, dependencies_allocated;
+
+ includes_allocated = 30;
+ includes_used = 0;
+ psymtab_include_list = (char **) alloca (includes_allocated *
+ sizeof (char *));
+
+ dependencies_allocated = 30;
+ dependencies_used = 0;
+ dependency_list =
+ (struct partial_symtab **) alloca (dependencies_allocated *
+ sizeof (struct partial_symtab *));
+
+ last_source_file = NULL;
+
+#ifdef END_OF_TEXT_DEFAULT
+ end_of_text_addr = END_OF_TEXT_DEFAULT;
+#else
+ end_of_text_addr = text_addr + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile))
+ + text_size; /* Relocate */
+#endif
+
+ abfd = objfile->obfd;
+ fp = objfile->auxf2;
+ if (!fp)
+ return;
+
+ fread (&dbghdr.sync, sizeof (dbghdr.sync), 1, fp);
+ fread (&dbghdr.rev, sizeof (dbghdr.rev), 1, fp);
+ fread (&dbghdr.crc, sizeof (dbghdr.crc), 1, fp);
+ fread (&dbghdr.os, sizeof (dbghdr.os), 1, fp);
+ fread (&dbghdr.cpu, sizeof (dbghdr.cpu), 1, fp);
+ SWAP_DBGHDR (&dbghdr, abfd);
+
+ symnum = 0;
+ while (1)
+ {
+ int ret;
+ long cursymoffset;
+
+ /* Get the symbol for this run and pull out some info */
+ QUIT; /* allow this to be interruptable */
+ cursymoffset = ftell (objfile->auxf2);
+ ret = fill_sym (objfile->auxf2, abfd);
+ if (ret <= 0)
+ break;
+ else
+ symnum++;
+ bufp = symbuf;
+
+ /* Special case to speed up readin. */
+ if (bufp->n_type == (short) N_SYM_SLINE)
+ continue;
+
+#define CUR_SYMBOL_VALUE bufp->n_value
+ /* partial-stab.h */
+
+ switch (bufp->n_type)
+ {
+ char *p;
+
+ case N_SYM_CMPLR:
+ continue;
+
+ case N_SYM_SE:
+ CUR_SYMBOL_VALUE += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ if (psymfile_depth == 1 && pst)
+ {
+ os9k_end_psymtab (pst, psymtab_include_list, includes_used,
+ symnum, CUR_SYMBOL_VALUE,
+ dependency_list, dependencies_used);
+ pst = (struct partial_symtab *) 0;
+ includes_used = 0;
+ dependencies_used = 0;
+ }
+ psymfile_depth--;
+ continue;
+
+ case N_SYM_SYM: /* Typedef or automatic variable. */
+ namestring = bufp->n_strx;
+ p = (char *) strchr (namestring, ':');
+ if (!p)
+ continue; /* Not a debugging symbol. */
+
+ /* Main processing section for debugging symbols which
+ the initial read through the symbol tables needs to worry
+ about. If we reach this point, the symbol which we are
+ considering is definitely one we are interested in.
+ p must also contain the (valid) index into the namestring
+ which indicates the debugging type symbol. */
+
+ switch (p[1])
+ {
+ case 'S':
+ {
+ unsigned long valu;
+ enum language tmp_language;
+ char *str, *p;
+ int n;
+
+ valu = CUR_SYMBOL_VALUE;
+ if (valu)
+ valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ past_first_source_file = 1;
+
+ p = strchr (namestring, ':');
+ if (p)
+ n = p - namestring;
+ else
+ n = strlen (namestring);
+ str = alloca (n + 1);
+ strncpy (str, namestring, n);
+ str[n] = '\0';
+
+ if (psymfile_depth == 0)
+ {
+ if (!pst)
+ pst = os9k_start_psymtab (objfile,
+ str, valu,
+ cursymoffset,
+ symnum - 1,
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ }
+ else
+ { /* this is a include file */
+ tmp_language = deduce_language_from_filename (str);
+ if (tmp_language != language_unknown
+ && (tmp_language != language_c
+ || psymtab_language != language_cplus))
+ psymtab_language = tmp_language;
+
+/*
+ if (pst && STREQ (str, pst->filename))
+ continue;
+ {
+ register int i;
+ for (i = 0; i < includes_used; i++)
+ if (STREQ (str, psymtab_include_list[i]))
+ {
+ i = -1;
+ break;
+ }
+ if (i == -1)
+ continue;
+ }
+ */
+
+ psymtab_include_list[includes_used++] = str;
+ if (includes_used >= includes_allocated)
+ {
+ char **orig = psymtab_include_list;
+
+ psymtab_include_list = (char **)
+ alloca ((includes_allocated *= 2) * sizeof (char *));
+ memcpy ((PTR) psymtab_include_list, (PTR) orig,
+ includes_used * sizeof (char *));
+ }
+
+ }
+ psymfile_depth++;
+ continue;
+ }
+
+ case 'v':
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->static_psymbols,
+ 0, CUR_SYMBOL_VALUE,
+ psymtab_language, objfile);
+ continue;
+ case 'V':
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->global_psymbols,
+ 0, CUR_SYMBOL_VALUE,
+ psymtab_language, objfile);
+ continue;
+
+ case 'T':
+ if (p != namestring) /* a name is there, not just :T... */
+ {
+ add_psymbol_to_list (namestring, p - namestring,
+ STRUCT_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ CUR_SYMBOL_VALUE, 0,
+ psymtab_language, objfile);
+ if (p[2] == 't')
+ {
+ /* Also a typedef with the same name. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ CUR_SYMBOL_VALUE, 0, psymtab_language,
+ objfile);
+ p += 1;
+ }
+ /* The semantics of C++ state that "struct foo { ... }"
+ also defines a typedef for "foo". Unfortuantely, cfront
+ never makes the typedef when translating from C++ to C.
+ We make the typedef here so that "ptype foo" works as
+ expected for cfront translated code. */
+ else if (psymtab_language == language_cplus)
+ {
+ /* Also a typedef with the same name. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ CUR_SYMBOL_VALUE, 0, psymtab_language,
+ objfile);
+ }
+ }
+ goto check_enum;
+ case 't':
+ if (p != namestring) /* a name is there, not just :T... */
+ {
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ CUR_SYMBOL_VALUE, 0,
+ psymtab_language, objfile);
+ }
+ check_enum:
+ /* If this is an enumerated type, we need to
+ add all the enum constants to the partial symbol
+ table. This does not cover enums without names, e.g.
+ "enum {a, b} c;" in C, but fortunately those are
+ rare. There is no way for GDB to find those from the
+ enum type without spending too much time on it. Thus
+ to solve this problem, the compiler needs to put out the
+ enum in a nameless type. GCC2 does this. */
+
+ /* We are looking for something of the form
+ <name> ":" ("t" | "T") [<number> "="] "e" <size>
+ {<constant> ":" <value> ","} ";". */
+
+ /* Skip over the colon and the 't' or 'T'. */
+ p += 2;
+ /* This type may be given a number. Also, numbers can come
+ in pairs like (0,26). Skip over it. */
+ while ((*p >= '0' && *p <= '9')
+ || *p == '(' || *p == ',' || *p == ')'
+ || *p == '=')
+ p++;
+
+ if (*p++ == 'e')
+ {
+ /* We have found an enumerated type. skip size */
+ while (*p >= '0' && *p <= '9')
+ p++;
+ /* According to comments in read_enum_type
+ a comma could end it instead of a semicolon.
+ I don't know where that happens.
+ Accept either. */
+ while (*p && *p != ';' && *p != ',')
+ {
+ char *q;
+
+ /* Check for and handle cretinous dbx symbol name
+ continuation!
+ if (*p == '\\')
+ p = next_symbol_text (objfile);
+ */
+
+ /* Point to the character after the name
+ of the enum constant. */
+ for (q = p; *q && *q != ':'; q++)
+ ;
+ /* Note that the value doesn't matter for
+ enum constants in psymtabs, just in symtabs. */
+ add_psymbol_to_list (p, q - p,
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols, 0,
+ 0, psymtab_language, objfile);
+ /* Point past the name. */
+ p = q;
+ /* Skip over the value. */
+ while (*p && *p != ',')
+ p++;
+ /* Advance past the comma. */
+ if (*p)
+ p++;
+ }
+ }
+ continue;
+ case 'c':
+ /* Constant, e.g. from "const" in Pascal. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols, CUR_SYMBOL_VALUE,
+ 0, psymtab_language, objfile);
+ continue;
+
+ case 'f':
+ CUR_SYMBOL_VALUE += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ if (pst && pst->textlow == 0)
+ pst->textlow = CUR_SYMBOL_VALUE;
+
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->static_psymbols, CUR_SYMBOL_VALUE,
+ 0, psymtab_language, objfile);
+ continue;
+
+ case 'F':
+ CUR_SYMBOL_VALUE += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ if (pst && pst->textlow == 0)
+ pst->textlow = CUR_SYMBOL_VALUE;
+
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->global_psymbols, CUR_SYMBOL_VALUE,
+ 0, psymtab_language, objfile);
+ continue;
+
+ case 'p':
+ case 'l':
+ case 's':
+ continue;
+
+ case ':':
+ /* It is a C++ nested symbol. We don't need to record it
+ (I don't think); if we try to look up foo::bar::baz,
+ then symbols for the symtab containing foo should get
+ read in, I think. */
+ /* Someone says sun cc puts out symbols like
+ /foo/baz/maclib::/usr/local/bin/maclib,
+ which would get here with a symbol type of ':'. */
+ continue;
+
+ default:
+ /* Unexpected symbol descriptor. The second and subsequent stabs
+ of a continued stab can show up here. The question is
+ whether they ever can mimic a normal stab--it would be
+ nice if not, since we certainly don't want to spend the
+ time searching to the end of every string looking for
+ a backslash. */
+
+ complain (&unknown_symchar_complaint, p[1]);
+ continue;
+ }
+
+ case N_SYM_RBRAC:
+ CUR_SYMBOL_VALUE += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+#ifdef HANDLE_RBRAC
+ HANDLE_RBRAC (CUR_SYMBOL_VALUE);
+ continue;
+#endif
+ case N_SYM_LBRAC:
+ continue;
+
+ default:
+ /* If we haven't found it yet, ignore it. It's probably some
+ new type we don't know about yet. */
+ complain (&unknown_symtype_complaint,
+ local_hex_string ((unsigned long) bufp->n_type));
+ continue;
+ }
+ }
+
+ DBX_SYMCOUNT (objfile) = symnum;
+
+ /* If there's stuff to be cleaned up, clean it up. */
+ if (DBX_SYMCOUNT (objfile) > 0
+/*FIXME, does this have a bug at start address 0? */
+ && last_o_file_start
+ && objfile->ei.entry_point < bufp->n_value
+ && objfile->ei.entry_point >= last_o_file_start)
+ {
+ objfile->ei.entry_file_lowpc = last_o_file_start;
+ objfile->ei.entry_file_highpc = bufp->n_value;
+ }
+
+ if (pst)
+ {
+ os9k_end_psymtab (pst, psymtab_include_list, includes_used,
+ symnum, end_of_text_addr,
+ dependency_list, dependencies_used);
+ }
+/*
+ do_cleanups (back_to);
+ */
+}
+
+/* Allocate and partially fill a partial symtab. It will be
+ completely filled at the end of the symbol list.
+
+ SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
+ is the address relative to which its symbols are (incremental) or 0
+ (normal). */
+
+
+static struct partial_symtab *
+os9k_start_psymtab (struct objfile *objfile, char *filename, CORE_ADDR textlow,
+ int ldsymoff, int ldsymcnt,
+ struct partial_symbol **global_syms,
+ struct partial_symbol **static_syms)
+{
+ struct partial_symtab *result =
+ start_psymtab_common (objfile, objfile->section_offsets,
+ filename, textlow, global_syms, static_syms);
+
+ result->read_symtab_private = (char *)
+ obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
+
+ LDSYMOFF (result) = ldsymoff;
+ LDSYMCNT (result) = ldsymcnt;
+ result->read_symtab = os9k_psymtab_to_symtab;
+
+ /* Deduce the source language from the filename for this psymtab. */
+ psymtab_language = deduce_language_from_filename (filename);
+ return result;
+}
+
+/* Close off the current usage of PST.
+ Returns PST or NULL if the partial symtab was empty and thrown away.
+ FIXME: List variables and peculiarities of same. */
+
+static struct partial_symtab *
+os9k_end_psymtab (struct partial_symtab *pst, char **include_list,
+ int num_includes, int capping_symbol_cnt,
+ CORE_ADDR capping_text,
+ struct partial_symtab **dependency_list,
+ int number_dependencies)
+{
+ int i;
+ struct partial_symtab *p1;
+ struct objfile *objfile = pst->objfile;
+
+ if (capping_symbol_cnt != -1)
+ LDSYMCNT (pst) = capping_symbol_cnt - LDSYMCNT (pst);
+
+ /* Under Solaris, the N_SO symbols always have a value of 0,
+ instead of the usual address of the .o file. Therefore,
+ we have to do some tricks to fill in texthigh and textlow.
+ The first trick is in partial-stab.h: if we see a static
+ or global function, and the textlow for the current pst
+ is still 0, then we use that function's address for
+ the textlow of the pst.
+
+ Now, to fill in texthigh, we remember the last function seen
+ in the .o file (also in partial-stab.h). Also, there's a hack in
+ bfd/elf.c and gdb/elfread.c to pass the ELF st_size field
+ to here via the misc_info field. Therefore, we can fill in
+ a reliable texthigh by taking the address plus size of the
+ last function in the file.
+
+ Unfortunately, that does not cover the case where the last function
+ in the file is static. See the paragraph below for more comments
+ on this situation.
+
+ Finally, if we have a valid textlow for the current file, we run
+ down the partial_symtab_list filling in previous texthighs that
+ are still unknown. */
+
+ if (pst->texthigh == 0 && last_function_name)
+ {
+ char *p;
+ int n;
+ struct minimal_symbol *minsym;
+
+ p = strchr (last_function_name, ':');
+ if (p == NULL)
+ p = last_function_name;
+ n = p - last_function_name;
+ p = alloca (n + 1);
+ strncpy (p, last_function_name, n);
+ p[n] = 0;
+
+ minsym = lookup_minimal_symbol (p, NULL, objfile);
+
+ if (minsym)
+ {
+ pst->texthigh = SYMBOL_VALUE_ADDRESS (minsym) + (long) MSYMBOL_INFO (minsym);
+ }
+ else
+ {
+ /* This file ends with a static function, and it's
+ difficult to imagine how hard it would be to track down
+ the elf symbol. Luckily, most of the time no one will notice,
+ since the next file will likely be compiled with -g, so
+ the code below will copy the first fuction's start address
+ back to our texthigh variable. (Also, if this file is the
+ last one in a dynamically linked program, texthigh already
+ has the right value.) If the next file isn't compiled
+ with -g, then the last function in this file winds up owning
+ all of the text space up to the next -g file, or the end (minus
+ shared libraries). This only matters for single stepping,
+ and even then it will still work, except that it will single
+ step through all of the covered functions, instead of setting
+ breakpoints around them as it usualy does. This makes it
+ pretty slow, but at least it doesn't fail.
+
+ We can fix this with a fairly big change to bfd, but we need
+ to coordinate better with Cygnus if we want to do that. FIXME. */
+ }
+ last_function_name = NULL;
+ }
+
+ /* this test will be true if the last .o file is only data */
+ if (pst->textlow == 0)
+ pst->textlow = pst->texthigh;
+
+ /* If we know our own starting text address, then walk through all other
+ psymtabs for this objfile, and if any didn't know their ending text
+ address, set it to our starting address. Take care to not set our
+ own ending address to our starting address, nor to set addresses on
+ `dependency' files that have both textlow and texthigh zero. */
+ if (pst->textlow)
+ {
+ ALL_OBJFILE_PSYMTABS (objfile, p1)
+ {
+ if (p1->texthigh == 0 && p1->textlow != 0 && p1 != pst)
+ {
+ p1->texthigh = pst->textlow;
+ /* if this file has only data, then make textlow match texthigh */
+ if (p1->textlow == 0)
+ p1->textlow = p1->texthigh;
+ }
+ }
+ }
+
+ /* End of kludge for patching Solaris textlow and texthigh. */
+
+ pst->n_global_syms =
+ objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
+ pst->n_static_syms =
+ objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset);
+
+ pst->number_of_dependencies = number_dependencies;
+ if (number_dependencies)
+ {
+ pst->dependencies = (struct partial_symtab **)
+ obstack_alloc (&objfile->psymbol_obstack,
+ number_dependencies * sizeof (struct partial_symtab *));
+ memcpy (pst->dependencies, dependency_list,
+ number_dependencies * sizeof (struct partial_symtab *));
+ }
+ else
+ pst->dependencies = 0;
+
+ for (i = 0; i < num_includes; i++)
+ {
+ struct partial_symtab *subpst =
+ allocate_psymtab (include_list[i], objfile);
+
+ subpst->section_offsets = pst->section_offsets;
+ subpst->read_symtab_private =
+ (char *) obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct symloc));
+ LDSYMOFF (subpst) =
+ LDSYMCNT (subpst) =
+ subpst->textlow =
+ subpst->texthigh = 0;
+
+ /* We could save slight bits of space by only making one of these,
+ shared by the entire set of include files. FIXME-someday. */
+ subpst->dependencies = (struct partial_symtab **)
+ obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct partial_symtab *));
+ subpst->dependencies[0] = pst;
+ subpst->number_of_dependencies = 1;
+
+ subpst->globals_offset =
+ subpst->n_global_syms =
+ subpst->statics_offset =
+ subpst->n_static_syms = 0;
+
+ subpst->readin = 0;
+ subpst->symtab = 0;
+ subpst->read_symtab = pst->read_symtab;
+ }
+
+ sort_pst_symbols (pst);
+
+ /* If there is already a psymtab or symtab for a file of this name,
+ remove it.
+ (If there is a symtab, more drastic things also happen.)
+ This happens in VxWorks. */
+ free_named_symtabs (pst->filename);
+
+ if (num_includes == 0
+ && number_dependencies == 0
+ && pst->n_global_syms == 0
+ && pst->n_static_syms == 0)
+ {
+ /* Throw away this psymtab, it's empty. We can't deallocate it, since
+ it is on the obstack, but we can forget to chain it on the list. */
+ /* Indicate that psymtab was thrown away. */
+
+ discard_psymtab (pst);
+
+ pst = (struct partial_symtab *) NULL;
+ }
+ return pst;
+}
+
+static void
+os9k_psymtab_to_symtab_1 (struct partial_symtab *pst)
+{
+ struct cleanup *old_chain;
+ int i;
+
+ if (!pst)
+ return;
+
+ if (pst->readin)
+ {
+ fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
+ pst->filename);
+ return;
+ }
+
+ /* Read in all partial symtabs on which this one is dependent */
+ for (i = 0; i < pst->number_of_dependencies; i++)
+ if (!pst->dependencies[i]->readin)
+ {
+ /* Inform about additional files that need to be read in. */
+ if (info_verbose)
+ {
+ fputs_filtered (" ", gdb_stdout);
+ wrap_here ("");
+ fputs_filtered ("and ", gdb_stdout);
+ wrap_here ("");
+ printf_filtered ("%s...", pst->dependencies[i]->filename);
+ wrap_here (""); /* Flush output */
+ gdb_flush (gdb_stdout);
+ }
+ os9k_psymtab_to_symtab_1 (pst->dependencies[i]);
+ }
+
+ if (LDSYMCNT (pst)) /* Otherwise it's a dummy */
+ {
+ /* Init stuff necessary for reading in symbols */
+ stabsread_init ();
+ buildsym_init ();
+ old_chain = make_cleanup (really_free_pendings, 0);
+
+ /* Read in this file's symbols */
+ os9k_read_ofile_symtab (pst);
+ sort_symtab_syms (pst->symtab);
+ do_cleanups (old_chain);
+ }
+
+ pst->readin = 1;
+}
+
+/* Read in all of the symbols for a given psymtab for real.
+ Be verbose about it if the user wants that. */
+
+static void
+os9k_psymtab_to_symtab (struct partial_symtab *pst)
+{
+ bfd *sym_bfd;
+
+ if (!pst)
+ return;
+
+ if (pst->readin)
+ {
+ fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
+ pst->filename);
+ return;
+ }
+
+ if (LDSYMCNT (pst) || pst->number_of_dependencies)
+ {
+ /* Print the message now, before reading the string table,
+ to avoid disconcerting pauses. */
+ if (info_verbose)
+ {
+ printf_filtered ("Reading in symbols for %s...", pst->filename);
+ gdb_flush (gdb_stdout);
+ }
+
+ sym_bfd = pst->objfile->obfd;
+ os9k_psymtab_to_symtab_1 (pst);
+
+ /* Match with global symbols. This only needs to be done once,
+ after all of the symtabs and dependencies have been read in. */
+ scan_file_globals (pst->objfile);
+
+ /* Finish up the debug error message. */
+ if (info_verbose)
+ printf_filtered ("done.\n");
+ }
+}
+
+/* Read in a defined section of a specific object file's symbols. */
+static void
+os9k_read_ofile_symtab (struct partial_symtab *pst)
+{
+ register struct internal_symstruct *bufp;
+ unsigned char type;
+ unsigned max_symnum;
+ register bfd *abfd;
+ struct objfile *objfile;
+ int sym_offset; /* Offset to start of symbols to read */
+ CORE_ADDR text_offset; /* Start of text segment for symbols */
+ int text_size; /* Size of text segment for symbols */
+ FILE *dbg_file;
+
+ objfile = pst->objfile;
+ sym_offset = LDSYMOFF (pst);
+ max_symnum = LDSYMCNT (pst);
+ text_offset = pst->textlow;
+ text_size = pst->texthigh - pst->textlow;
+
+ current_objfile = objfile;
+ subfile_stack = NULL;
+ last_source_file = NULL;
+
+ abfd = objfile->obfd;
+ dbg_file = objfile->auxf2;
+
+#if 0
+ /* It is necessary to actually read one symbol *before* the start
+ of this symtab's symbols, because the GCC_COMPILED_FLAG_SYMBOL
+ occurs before the N_SO symbol.
+ Detecting this in read_dbx_symtab
+ would slow down initial readin, so we look for it here instead. */
+ if (!processing_acc_compilation && sym_offset >= (int) symbol_size)
+ {
+ fseek (objefile->auxf2, sym_offset, SEEK_CUR);
+ fill_sym (objfile->auxf2, abfd);
+ bufp = symbuf;
+
+ processing_gcc_compilation = 0;
+ if (bufp->n_type == N_TEXT)
+ {
+ if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL))
+ processing_gcc_compilation = 1;
+ else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL))
+ processing_gcc_compilation = 2;
+ }
+
+ /* Try to select a C++ demangling based on the compilation unit
+ producer. */
+
+ if (processing_gcc_compilation)
+ {
+ if (AUTO_DEMANGLING)
+ {
+ set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+ }
+ }
+ }
+ else
+ {
+ /* The N_SO starting this symtab is the first symbol, so we
+ better not check the symbol before it. I'm not this can
+ happen, but it doesn't hurt to check for it. */
+ bfd_seek (symfile_bfd, sym_offset, SEEK_CUR);
+ processing_gcc_compilation = 0;
+ }
+#endif /* 0 */
+
+ fseek (dbg_file, (long) sym_offset, 0);
+/*
+ if (bufp->n_type != (unsigned char)N_SYM_SYM)
+ error("First symbol in segment of executable not a source symbol");
+ */
+
+ for (symnum = 0; symnum < max_symnum; symnum++)
+ {
+ QUIT; /* Allow this to be interruptable */
+ fill_sym (dbg_file, abfd);
+ bufp = symbuf;
+ type = bufp->n_type;
+
+ os9k_process_one_symbol ((int) type, (int) bufp->n_desc,
+ (CORE_ADDR) bufp->n_value, bufp->n_strx, pst->section_offsets, objfile);
+
+ /* We skip checking for a new .o or -l file; that should never
+ happen in this routine. */
+#if 0
+ else
+ if (type == N_TEXT)
+ {
+ /* I don't think this code will ever be executed, because
+ the GCC_COMPILED_FLAG_SYMBOL usually is right before
+ the N_SO symbol which starts this source file.
+ However, there is no reason not to accept
+ the GCC_COMPILED_FLAG_SYMBOL anywhere. */
+
+ if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL))
+ processing_gcc_compilation = 1;
+ else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL))
+ processing_gcc_compilation = 2;
+
+ if (AUTO_DEMANGLING)
+ {
+ set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+ }
+ }
+ else if (type & N_EXT || type == (unsigned char) N_TEXT
+ || type == (unsigned char) N_NBTEXT
+ )
+ {
+ /* Global symbol: see if we came across a dbx defintion for
+ a corresponding symbol. If so, store the value. Remove
+ syms from the chain when their values are stored, but
+ search the whole chain, as there may be several syms from
+ different files with the same name. */
+ /* This is probably not true. Since the files will be read
+ in one at a time, each reference to a global symbol will
+ be satisfied in each file as it appears. So we skip this
+ section. */
+ ;
+ }
+#endif /* 0 */
+ }
+
+ current_objfile = NULL;
+
+ /* In a Solaris elf file, this variable, which comes from the
+ value of the N_SO symbol, will still be 0. Luckily, text_offset,
+ which comes from pst->textlow is correct. */
+ if (last_source_start_addr == 0)
+ last_source_start_addr = text_offset;
+ pst->symtab = end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT (objfile));
+ end_stabs ();
+}
+
+
+/* This handles a single symbol from the symbol-file, building symbols
+ into a GDB symtab. It takes these arguments and an implicit argument.
+
+ TYPE is the type field of the ".stab" symbol entry.
+ DESC is the desc field of the ".stab" entry.
+ VALU is the value field of the ".stab" entry.
+ NAME is the symbol name, in our address space.
+ SECTION_OFFSETS is a set of amounts by which the sections of this object
+ file were relocated when it was loaded into memory.
+ All symbols that refer
+ to memory locations need to be offset by these amounts.
+ OBJFILE is the object file from which we are reading symbols.
+ It is used in end_symtab. */
+
+static void
+os9k_process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
+ struct section_offsets *section_offsets,
+ struct objfile *objfile)
+{
+ register struct context_stack *new;
+ /* The stab type used for the definition of the last function.
+ N_STSYM or N_GSYM for SunOS4 acc; N_FUN for other compilers. */
+ static int function_stab_type = 0;
+
+#if 0
+ /* Something is wrong if we see real data before
+ seeing a source file name. */
+ if (last_source_file == NULL && type != (unsigned char) N_SO)
+ {
+ /* Ignore any symbols which appear before an N_SO symbol.
+ Currently no one puts symbols there, but we should deal
+ gracefully with the case. A complain()t might be in order,
+ but this should not be an error (). */
+ return;
+ }
+#endif /* 0 */
+
+ switch (type)
+ {
+ case N_SYM_LBRAC:
+ /* On most machines, the block addresses are relative to the
+ N_SO, the linker did not relocate them (sigh). */
+ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+ new = push_context (desc, valu);
+ break;
+
+ case N_SYM_RBRAC:
+ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+ new = pop_context ();
+
+#if !defined (OS9K_VARIABLES_INSIDE_BLOCK)
+#define OS9K_VARIABLES_INSIDE_BLOCK(desc, gcc_p) 1
+#endif
+
+ if (!OS9K_VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
+ local_symbols = new->locals;
+
+ if (context_stack_depth > 1)
+ {
+ /* This is not the outermost LBRAC...RBRAC pair in the function,
+ its local symbols preceded it, and are the ones just recovered
+ from the context stack. Define the block for them (but don't
+ bother if the block contains no symbols. Should we complain
+ on blocks without symbols? I can't think of any useful purpose
+ for them). */
+ if (local_symbols != NULL)
+ {
+ /* Muzzle a compiler bug that makes end < start. (which
+ compilers? Is this ever harmful?). */
+ if (new->start_addr > valu)
+ {
+ complain (&lbrac_rbrac_complaint);
+ new->start_addr = valu;
+ }
+ /* Make a block for the local symbols within. */
+ finish_block (0, &local_symbols, new->old_blocks,
+ new->start_addr, valu, objfile);
+ }
+ }
+ else
+ {
+ if (context_stack_depth == 0)
+ {
+ within_function = 0;
+ /* Make a block for the local symbols within. */
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ new->start_addr, valu, objfile);
+ }
+ else
+ {
+ /* attach local_symbols to the end of new->locals */
+ if (!new->locals)
+ new->locals = local_symbols;
+ else
+ {
+ struct pending *p;
+
+ p = new->locals;
+ while (p->next)
+ p = p->next;
+ p->next = local_symbols;
+ }
+ }
+ }
+
+ if (OS9K_VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
+ /* Now pop locals of block just finished. */
+ local_symbols = new->locals;
+ break;
+
+
+ case N_SYM_SLINE:
+ /* This type of "symbol" really just records
+ one line-number -- core-address correspondence.
+ Enter it in the line list for this symbol table. */
+ /* Relocate for dynamic loading and for ELF acc fn-relative syms. */
+ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+ /* FIXME: loses if sizeof (char *) > sizeof (int) */
+ gdb_assert (sizeof (name) <= sizeof (int));
+ record_line (current_subfile, (int) name, valu);
+ break;
+
+ /* The following symbol types need to have the appropriate offset added
+ to their value; then we process symbol definitions in the name. */
+ case N_SYM_SYM:
+
+ if (name)
+ {
+ char deftype;
+ char *dirn, *n;
+ char *p = strchr (name, ':');
+ if (p == NULL)
+ deftype = '\0';
+ else
+ deftype = p[1];
+
+
+ switch (deftype)
+ {
+ case 'S':
+ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+ n = strrchr (name, '/');
+ if (n != NULL)
+ {
+ *n = '\0';
+ n++;
+ dirn = name;
+ }
+ else
+ {
+ n = name;
+ dirn = NULL;
+ }
+ *p = '\0';
+ if (symfile_depth++ == 0)
+ {
+ if (last_source_file)
+ {
+ end_symtab (valu, objfile, SECT_OFF_TEXT (objfile));
+ end_stabs ();
+ }
+ start_stabs ();
+ os9k_stabs = 1;
+ start_symtab (n, dirn, valu);
+ record_debugformat ("OS9");
+ }
+ else
+ {
+ push_subfile ();
+ start_subfile (n, dirn != NULL ? dirn : current_subfile->dirname);
+ }
+ break;
+
+ case 'f':
+ case 'F':
+ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+ function_stab_type = type;
+
+ within_function = 1;
+ new = push_context (0, valu);
+ new->name = define_symbol (valu, name, desc, type, objfile);
+ break;
+
+ case 'V':
+ case 'v':
+ valu += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
+ define_symbol (valu, name, desc, type, objfile);
+ break;
+
+ default:
+ define_symbol (valu, name, desc, type, objfile);
+ break;
+ }
+ }
+ break;
+
+ case N_SYM_SE:
+ if (--symfile_depth != 0)
+ start_subfile (pop_subfile (), current_subfile->dirname);
+ break;
+
+ default:
+ complain (&unknown_symtype_complaint,
+ local_hex_string ((unsigned long) type));
+ /* FALLTHROUGH */
+ break;
+
+ case N_SYM_CMPLR:
+ break;
+ }
+ previous_stab_code = type;
+}
+
+static struct sym_fns os9k_sym_fns =
+{
+ bfd_target_os9k_flavour,
+ os9k_new_init, /* sym_new_init: init anything gbl to entire symtab */
+ os9k_symfile_init, /* sym_init: read initial info, setup for sym_read() */
+ os9k_symfile_read, /* sym_read: read a symbol file into symtab */
+ os9k_symfile_finish, /* sym_finish: finished with file, cleanup */
+ default_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
+ NULL /* next: pointer to next struct sym_fns */
+};
+
+void
+_initialize_os9kread (void)
+{
+ add_symtab_fns (&os9k_sym_fns);
+}
diff --git a/gdb/osabi.c b/gdb/osabi.c
new file mode 100644
index 00000000000..4186cbd5245
--- /dev/null
+++ b/gdb/osabi.c
@@ -0,0 +1,424 @@
+/* OS ABI variant handling for GDB.
+ Copyright 2001, 2002 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 "defs.h"
+#include "osabi.h"
+
+#include "elf-bfd.h"
+
+
+/* This table matches the indices assigned to enum gdb_osabi. Keep
+ them in sync. */
+static const char * const gdb_osabi_names[] =
+{
+ "<unknown>",
+
+ "SVR4",
+ "GNU/Hurd",
+ "Solaris",
+ "OSF/1",
+ "GNU/Linux",
+ "FreeBSD a.out",
+ "FreeBSD ELF",
+ "NetBSD a.out",
+ "NetBSD ELF",
+ "Windows CE",
+
+ "ARM EABI v1",
+ "ARM EABI v2",
+ "ARM APCS",
+
+ "<invalid>"
+};
+
+const char *
+gdbarch_osabi_name (enum gdb_osabi osabi)
+{
+ if (osabi >= GDB_OSABI_UNKNOWN && osabi < GDB_OSABI_INVALID)
+ return gdb_osabi_names[osabi];
+
+ return gdb_osabi_names[GDB_OSABI_INVALID];
+}
+
+/* Handler for a given architecture/OS ABI pair. There should be only
+ one handler for a given OS ABI each architecture family. */
+struct gdb_osabi_handler
+{
+ struct gdb_osabi_handler *next;
+ enum bfd_architecture arch;
+ enum gdb_osabi osabi;
+ void (*init_osabi)(struct gdbarch_info, struct gdbarch *);
+};
+
+static struct gdb_osabi_handler *gdb_osabi_handler_list;
+
+void
+gdbarch_register_osabi (enum bfd_architecture arch, enum gdb_osabi osabi,
+ void (*init_osabi)(struct gdbarch_info,
+ struct gdbarch *))
+{
+ struct gdb_osabi_handler **handler_p;
+
+ /* Registering an OS ABI handler for "unknown" is not allowed. */
+ if (osabi == GDB_OSABI_UNKNOWN)
+ {
+ internal_error
+ (__FILE__, __LINE__,
+ "gdbarch_register_osabi: An attempt to register a handler for "
+ "OS ABI \"%s\" for architecture %s was made. The handler will "
+ "not be registered",
+ gdbarch_osabi_name (osabi),
+ bfd_printable_arch_mach (arch, 0));
+ return;
+ }
+
+ for (handler_p = &gdb_osabi_handler_list; *handler_p != NULL;
+ handler_p = &(*handler_p)->next)
+ {
+ if ((*handler_p)->arch == arch
+ && (*handler_p)->osabi == osabi)
+ {
+ internal_error
+ (__FILE__, __LINE__,
+ "gdbarch_register_osabi: A handler for OS ABI \"%s\" "
+ "has already been registered for architecture %s",
+ gdbarch_osabi_name (osabi),
+ bfd_printable_arch_mach (arch, 0));
+ /* If user wants to continue, override previous definition. */
+ (*handler_p)->init_osabi = init_osabi;
+ return;
+ }
+ }
+
+ (*handler_p)
+ = (struct gdb_osabi_handler *) xmalloc (sizeof (struct gdb_osabi_handler));
+ (*handler_p)->next = NULL;
+ (*handler_p)->arch = arch;
+ (*handler_p)->osabi = osabi;
+ (*handler_p)->init_osabi = init_osabi;
+}
+
+
+/* Sniffer to find the OS ABI for a given file's architecture and flavour.
+ It is legal to have multiple sniffers for each arch/flavour pair, to
+ disambiguate one OS's a.out from another, for example. The first sniffer
+ to return something other than GDB_OSABI_UNKNOWN wins, so a sniffer should
+ be careful to claim a file only if it knows for sure what it is. */
+struct gdb_osabi_sniffer
+{
+ struct gdb_osabi_sniffer *next;
+ enum bfd_architecture arch; /* bfd_arch_unknown == wildcard */
+ enum bfd_flavour flavour;
+ enum gdb_osabi (*sniffer)(bfd *);
+};
+
+static struct gdb_osabi_sniffer *gdb_osabi_sniffer_list;
+
+void
+gdbarch_register_osabi_sniffer (enum bfd_architecture arch,
+ enum bfd_flavour flavour,
+ enum gdb_osabi (*sniffer_fn)(bfd *))
+{
+ struct gdb_osabi_sniffer *sniffer;
+
+ sniffer =
+ (struct gdb_osabi_sniffer *) xmalloc (sizeof (struct gdb_osabi_sniffer));
+ sniffer->arch = arch;
+ sniffer->flavour = flavour;
+ sniffer->sniffer = sniffer_fn;
+
+ sniffer->next = gdb_osabi_sniffer_list;
+ gdb_osabi_sniffer_list = sniffer;
+}
+
+
+enum gdb_osabi
+gdbarch_lookup_osabi (bfd *abfd)
+{
+ struct gdb_osabi_sniffer *sniffer;
+ enum gdb_osabi osabi, match;
+ int match_specific;
+
+ match = GDB_OSABI_UNKNOWN;
+ match_specific = 0;
+
+ for (sniffer = gdb_osabi_sniffer_list; sniffer != NULL;
+ sniffer = sniffer->next)
+ {
+ if ((sniffer->arch == bfd_arch_unknown /* wildcard */
+ || sniffer->arch == bfd_get_arch (abfd))
+ && sniffer->flavour == bfd_get_flavour (abfd))
+ {
+ osabi = (*sniffer->sniffer) (abfd);
+ if (osabi < GDB_OSABI_UNKNOWN || osabi >= GDB_OSABI_INVALID)
+ {
+ internal_error
+ (__FILE__, __LINE__,
+ "gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer "
+ "for architecture %s flavour %d",
+ (int) osabi,
+ bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
+ (int) bfd_get_flavour (abfd));
+ }
+ else if (osabi != GDB_OSABI_UNKNOWN)
+ {
+ /* A specific sniffer always overrides a generic sniffer.
+ Croak on multiple match if the two matches are of the
+ same class. If the user wishes to continue, we'll use
+ the first match. */
+ if (match != GDB_OSABI_UNKNOWN)
+ {
+ if ((match_specific && sniffer->arch != bfd_arch_unknown)
+ || (!match_specific && sniffer->arch == bfd_arch_unknown))
+ {
+ internal_error
+ (__FILE__, __LINE__,
+ "gdbarch_lookup_osabi: multiple %sspecific OS ABI "
+ "match for architecture %s flavour %d: first "
+ "match \"%s\", second match \"%s\"",
+ match_specific ? "" : "non-",
+ bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
+ (int) bfd_get_flavour (abfd),
+ gdbarch_osabi_name (match),
+ gdbarch_osabi_name (osabi));
+ }
+ else if (sniffer->arch != bfd_arch_unknown)
+ {
+ match = osabi;
+ match_specific = 1;
+ }
+ }
+ else
+ {
+ match = osabi;
+ if (sniffer->arch != bfd_arch_unknown)
+ match_specific = 1;
+ }
+ }
+ }
+ }
+
+ return match;
+}
+
+void
+gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch,
+ enum gdb_osabi osabi)
+{
+ struct gdb_osabi_handler *handler;
+ bfd *abfd = info.abfd;
+ const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);
+
+ if (osabi == GDB_OSABI_UNKNOWN)
+ {
+ /* Don't complain about not knowing the OS ABI if we don't
+ have an inferior. */
+ if (info.abfd)
+ fprintf_filtered
+ (gdb_stderr, "GDB doesn't recognize the OS ABI of the inferior. "
+ "Attempting to continue with the default %s settings",
+ bfd_printable_arch_mach (arch_info->arch, arch_info->mach));
+ return;
+ }
+
+ for (handler = gdb_osabi_handler_list; handler != NULL;
+ handler = handler->next)
+ {
+ if (handler->arch == bfd_get_arch (abfd)
+ && handler->osabi == osabi)
+ {
+ (*handler->init_osabi) (info, gdbarch);
+ return;
+ }
+ }
+
+ /* We assume that if GDB_MULTI_ARCH is less than GDB_MULTI_ARCH_TM
+ that an ABI variant can be supported by overriding definitions in
+ the tm-file. */
+ if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+ fprintf_filtered
+ (gdb_stderr,
+ "A handler for the OS ABI \"%s\" is not built into this "
+ "configuration of GDB. "
+ "Attempting to continue with the default %s settings",
+ gdbarch_osabi_name (osabi),
+ bfd_printable_arch_mach (arch_info->arch, arch_info->mach));
+}
+
+
+/* Generic sniffer for ELF flavoured files. */
+
+void
+generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
+{
+ enum gdb_osabi *os_ident_ptr = obj;
+ const char *name;
+ unsigned int sectsize;
+
+ name = bfd_get_section_name (abfd, sect);
+ sectsize = bfd_section_size (abfd, sect);
+
+ /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD. */
+ if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
+ {
+ unsigned int name_length, data_length, note_type;
+ char *note;
+
+ /* If the section is larger than this, it's probably not what we are
+ looking for. */
+ if (sectsize > 128)
+ sectsize = 128;
+
+ note = alloca (sectsize);
+
+ bfd_get_section_contents (abfd, sect, note,
+ (file_ptr) 0, (bfd_size_type) sectsize);
+
+ name_length = bfd_h_get_32 (abfd, note);
+ data_length = bfd_h_get_32 (abfd, note + 4);
+ note_type = bfd_h_get_32 (abfd, note + 8);
+
+ if (name_length == 4 && data_length == 16 && note_type == NT_GNU_ABI_TAG
+ && strcmp (note + 12, "GNU") == 0)
+ {
+ int os_number = bfd_h_get_32 (abfd, note + 16);
+
+ switch (os_number)
+ {
+ case GNU_ABI_TAG_LINUX:
+ *os_ident_ptr = GDB_OSABI_LINUX;
+ break;
+
+ case GNU_ABI_TAG_HURD:
+ *os_ident_ptr = GDB_OSABI_HURD;
+ break;
+
+ case GNU_ABI_TAG_SOLARIS:
+ *os_ident_ptr = GDB_OSABI_SOLARIS;
+ break;
+
+ default:
+ internal_error
+ (__FILE__, __LINE__,
+ "generic_elf_osabi_sniff_abi_tag_sections: unknown OS number %d",
+ os_number);
+ }
+ return;
+ }
+ else if (name_length == 8 && data_length == 4
+ && note_type == NT_FREEBSD_ABI_TAG
+ && strcmp (note + 12, "FreeBSD") == 0)
+ {
+ /* XXX Should we check the version here? Probably not
+ necessary yet. */
+ *os_ident_ptr = GDB_OSABI_FREEBSD_ELF;
+ }
+ return;
+ }
+
+ /* .note.netbsd.ident notes, used by NetBSD. */
+ if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0)
+ {
+ unsigned int name_length, data_length, note_type;
+ char *note;
+
+ /* If the section is larger than this, it's probably not what we are
+ looking for. */
+ if (sectsize > 128)
+ sectsize = 128;
+
+ note = alloca (sectsize);
+
+ bfd_get_section_contents (abfd, sect, note,
+ (file_ptr) 0, (bfd_size_type) sectsize);
+
+ name_length = bfd_h_get_32 (abfd, note);
+ data_length = bfd_h_get_32 (abfd, note + 4);
+ note_type = bfd_h_get_32 (abfd, note + 8);
+
+ if (name_length == 7 && data_length == 4 && note_type == NT_NETBSD_IDENT
+ && strcmp (note + 12, "NetBSD") == 0)
+ {
+ /* XXX Should we check the version here? Probably not
+ necessary yet. */
+ *os_ident_ptr = GDB_OSABI_NETBSD_ELF;
+ }
+ return;
+ }
+}
+
+static enum gdb_osabi
+generic_elf_osabi_sniffer (bfd *abfd)
+{
+ unsigned int elfosabi;
+ enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
+
+ elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
+
+ switch (elfosabi)
+ {
+ case ELFOSABI_NONE:
+ /* When elfosabi is ELFOSABI_NONE (0), then the ELF structures in the
+ file are conforming to the base specification for that machine
+ (there are no OS-specific extensions). In order to determine the
+ real OS in use we must look for OS notes that have been added. */
+ bfd_map_over_sections (abfd,
+ generic_elf_osabi_sniff_abi_tag_sections,
+ &osabi);
+ break;
+
+ case ELFOSABI_FREEBSD:
+ osabi = GDB_OSABI_FREEBSD_ELF;
+ break;
+
+ case ELFOSABI_NETBSD:
+ osabi = GDB_OSABI_NETBSD_ELF;
+ break;
+
+ case ELFOSABI_LINUX:
+ osabi = GDB_OSABI_LINUX;
+ break;
+
+ case ELFOSABI_HURD:
+ osabi = GDB_OSABI_HURD;
+ break;
+
+ case ELFOSABI_SOLARIS:
+ osabi = GDB_OSABI_SOLARIS;
+ break;
+ }
+
+ return osabi;
+}
+
+
+void
+_initialize_gdb_osabi (void)
+{
+ if (strcmp (gdb_osabi_names[GDB_OSABI_INVALID], "<invalid>") != 0)
+ internal_error
+ (__FILE__, __LINE__,
+ "_initialize_gdb_osabi: gdb_osabi_names[] is inconsistent");
+
+ /* Register a generic sniffer for ELF flavoured files. */
+ gdbarch_register_osabi_sniffer (bfd_arch_unknown,
+ bfd_target_elf_flavour,
+ generic_elf_osabi_sniffer);
+}
diff --git a/gdb/osabi.h b/gdb/osabi.h
new file mode 100644
index 00000000000..23e7025d9d5
--- /dev/null
+++ b/gdb/osabi.h
@@ -0,0 +1,78 @@
+/* OS ABI variant handling for GDB.
+ Copyright 2001, 2002 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. */
+
+#ifndef OSABI_H
+#define OSABI_H
+
+/* List of known OS ABIs. If you change this, make sure to update the
+ table in osabi.c. */
+enum gdb_osabi
+{
+ GDB_OSABI_UNKNOWN = 0, /* keep this first */
+
+ GDB_OSABI_SVR4,
+ GDB_OSABI_HURD,
+ GDB_OSABI_SOLARIS,
+ GDB_OSABI_OSF1,
+ GDB_OSABI_LINUX,
+ GDB_OSABI_FREEBSD_AOUT,
+ GDB_OSABI_FREEBSD_ELF,
+ GDB_OSABI_NETBSD_AOUT,
+ GDB_OSABI_NETBSD_ELF,
+ GDB_OSABI_WINCE,
+
+ GDB_OSABI_ARM_EABI_V1,
+ GDB_OSABI_ARM_EABI_V2,
+ GDB_OSABI_ARM_APCS,
+
+ GDB_OSABI_INVALID /* keep this last */
+};
+
+/* Register an OS ABI sniffer. Each arch/flavour may have more than
+ one sniffer. This is used to e.g. differentiate one OS's a.out from
+ another. The first sniffer to return something other than
+ GDB_OSABI_UNKNOWN wins, so a sniffer should be careful to claim a file
+ only if it knows for sure what it is. */
+void gdbarch_register_osabi_sniffer (enum bfd_architecture,
+ enum bfd_flavour,
+ enum gdb_osabi (*)(bfd *));
+
+/* Register a handler for an OS ABI variant for a given architecture. There
+ should be only one handler for a given OS ABI each architecture family. */
+void gdbarch_register_osabi (enum bfd_architecture, enum gdb_osabi,
+ void (*)(struct gdbarch_info,
+ struct gdbarch *));
+
+/* Lookup the OS ABI corresponding to the specified BFD. */
+enum gdb_osabi gdbarch_lookup_osabi (bfd *);
+
+/* Initialize the gdbarch for the specified OS ABI variant. */
+void gdbarch_init_osabi (struct gdbarch_info, struct gdbarch *,
+ enum gdb_osabi);
+
+/* Return the name of the specified OS ABI. */
+const char *gdbarch_osabi_name (enum gdb_osabi);
+
+/* Helper routine for ELF file sniffers. This looks at ABI tag note
+ sections to determine the OS ABI from the note. It should be called
+ via bfd_map_over_sections. */
+void generic_elf_osabi_sniff_abi_tag_sections (bfd *, asection *, void *);
+
+#endif /* OSABI_H */
diff --git a/gdb/osf-share/AT386/cma_thread_io.h b/gdb/osf-share/AT386/cma_thread_io.h
new file mode 100644
index 00000000000..a90dba17583
--- /dev/null
+++ b/gdb/osf-share/AT386/cma_thread_io.h
@@ -0,0 +1,457 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * Header file for thread synchrounous I/O
+ */
+
+#ifndef CMA_THREAD_IO
+#define CMA_THREAD_IO
+
+/*
+ * INCLUDE FILES
+ */
+
+#include <cma_config.h>
+#include <sys/file.h>
+#include <cma.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <cma_init.h>
+#include <cma_errors.h>
+
+/*
+ * CONSTANTS
+ */
+
+/*
+ * Define symbols which indicate whether to compile code for obsolete
+ * "non-blocking mode" flags: FNDELAY and FNBLOCK. If the obsolete
+ * symbols are defined, and if their replacement symbols are defined
+ * and are different or if they are undefined, then define a symbol
+ * that says to compile the code in; otherwise no code will be compiled
+ * for these obsolete symbols.
+ */
+#ifdef FNDELAY
+# ifdef O_NDELAY
+# if O_NDELAY != FNDELAY
+# define _CMA_FNDELAY_
+# endif
+# else
+# define _CMA_FNDELAY_
+# endif
+#endif
+
+#ifdef FNBLOCK
+# ifdef O_NONBLOCK
+# if O_NONBLOCK != FNBLOCK
+# define _CMA_FNBLOCK_
+# endif
+# else
+# define _CMA_FNBLOCK_
+# endif
+#endif
+
+
+extern cma_t_boolean cma_is_open(int);
+/*
+ * Maximum number of files (ie, max_fd+1)
+ */
+#define cma__c_mx_file FD_SETSIZE
+
+/*
+ * Number of bits per file descriptor bit mask (ie number of bytes * bits/byte)
+ */
+#define cma__c_nbpm NFDBITS
+
+/*
+ * TYPE DEFINITIONS
+ */
+
+typedef enum CMA__T_IO_TYPE {
+ cma__c_io_read = 0,
+ cma__c_io_write = 1,
+ cma__c_io_except = 2
+ } cma__t_io_type;
+#define cma__c_max_io_type 2
+
+/*
+ * From our local <sys/types.h>:
+ *
+ * typedef long fd_mask;
+ *
+ * typedef struct fd_set {
+ * fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
+ * } fd_set;
+ *
+ */
+typedef fd_mask cma__t_mask;
+typedef fd_set cma__t_file_mask;
+
+
+/*
+ * GLOBAL DATA
+ */
+
+/*
+ * Maximum number of files (ie, max_fd+1) as determined by getdtablesize().
+ */
+extern int cma__g_mx_file;
+
+/*
+ * Number of submasks (ie "int" sized chunks) per file descriptor mask as
+ * determined by getdtablesize().
+ */
+extern int cma__g_nspm;
+
+/*
+ * MACROS
+ */
+
+/*
+ * Define a constant for the errno value which indicates that the requested
+ * operation was not performed because it would block the process.
+ */
+# define cma__is_blocking(s) \
+ ((s == EAGAIN) || (s == EWOULDBLOCK) || (s == EINPROGRESS) || \
+ (s == EALREADY) || (s == EDEADLK))
+
+/*
+* It is necessary to issue an I/O function, before calling cma__io_wait()
+* in the following cases:
+*
+* * This file descriptor has been set non-blocking by CMA
+* * This file descriptor has been set non-blocking by the user.
+*/
+
+#define cma__issue_io_call(fd) \
+ ( (cma__g_file[fd]->non_blocking) || \
+ (cma__g_file[fd]->user_fl.user_non_blocking) )
+
+
+#define cma__set_user_nonblocking(flags) \
+
+/*
+ * Determine if the file is open
+ */
+/*
+ * If the file gets closed while waiting for the mutex cma__g_file[rfd]
+ * gets set to null. This results in a crash if NDEBUG is set to 0
+ * since cma__int_lock tries to dereference it to set the mutex ownership
+ * after it gets the mutex. The following will still set the ownership
+ * in cma__int_lock so we'll set it back to noone if cma__g_file is null
+ * when we come back just in case it matters. It shouldn't since its no
+ * longer in use but.....
+ * Callers of this should recheck cma__g_file after the reservation to
+ * make sure continueing makes sense.
+ */
+#define cma__fd_reserve(rfd) \
+ { \
+ cma__t_int_mutex *__mutex__; \
+ __mutex__ = cma__g_file[rfd]->mutex; \
+ cma__int_lock (__mutex__); \
+ if(cma__g_file[rfd] == (cma__t_file_obj *)cma_c_null_ptr) \
+ cma__int_unlock(__mutex__); \
+ }
+
+
+/*
+ * Unreserve a file descriptor
+ */
+#define cma__fd_unreserve(ufd) cma__int_unlock (cma__g_file[ufd]->mutex)
+
+/*
+ * AND together two select file descriptor masks
+ */
+#define cma__fdm_and(target,a,b) \
+ { \
+ int __i__ = cma__g_nspm; \
+ while (__i__--) \
+ (target)->fds_bits[__i__] = \
+ (a)->fds_bits[__i__] & (b)->fds_bits[__i__]; \
+ }
+
+/*
+ * Clear a bit in a select file descriptor mask
+ *
+ * FD_CLR(n, p) := ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_clr_bit(n,p) FD_CLR (n, p)
+
+/*
+ * Copy the contents of one file descriptor mask into another. If the
+ * destination operand is null, do nothing; if the source operand is null,
+ * simply zero the destination.
+ */
+#define cma__fdm_copy(src,dst,nfds) { \
+ if (dst) \
+ if (src) { \
+ cma__t_mask *__s__ = (cma__t_mask *)(src); \
+ cma__t_mask *__d__ = (cma__t_mask *)(dst); \
+ int __i__; \
+ for (__i__ = 0; __i__ < (nfds); __i__ += cma__c_nbpm) \
+ *__d__++ = *__s__++; \
+ } \
+ else \
+ cma__fdm_zero (dst); \
+ }
+
+/*
+ * To increment count for each bit set in fd - mask
+ */
+#define cma__fdm_count_bits(map,count) \
+ { \
+ int __i__ = cma__g_nspm; \
+ while (__i__--) { \
+ cma__t_mask __tm__; \
+ __tm__ = (map)->fds_bits[__i__]; \
+ while(__tm__) { \
+ (count)++; \
+ __tm__ &= ~(__tm__ & (-__tm__)); /* Assumes 2's comp */ \
+ } \
+ } \
+ }
+
+/*
+ * Test if a bit is set in a select file descriptor mask
+ *
+ * FD_ISSET(n,p) := ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_is_set(n,p) FD_ISSET (n, p)
+
+/*
+ * OR together two select file descriptor masks
+ */
+#define cma__fdm_or(target,a,b) \
+ { \
+ int __i__ = cma__g_nspm; \
+ while (__i__--) \
+ (target)->fds_bits[__i__] = \
+ (a)->fds_bits[__i__] | (b)->fds_bits[__i__]; \
+ }
+
+/*
+ * Set a bit in a select file descriptor mask
+ *
+ * FD_SET(n,p) := ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_set_bit(n,p) FD_SET (n, p)
+
+/*
+ * Clear a select file descriptor mask.
+ */
+#define cma__fdm_zero(n) \
+ cma__memset ((char *) n, 0, cma__g_nspm * sizeof(cma__t_mask))
+
+
+
+/*
+ * CMA "thread-synchronous" I/O read/write operations
+ */
+
+ /*
+ * Since all CMA "thread-synchronous" I/O (read or write) operations on
+ * U*ix follow the exact same structure, the wrapper routines have been
+ * condensed into a macro.
+ *
+ * The steps performed are as follows:
+ * 1. Check that the file descriptor is a legitimate value.
+ * 2. Check that the entry in the CMA file "database" which corresponds to
+ * the file descriptor indicates that the "file" was "opened" by CMA.
+ * 3. Reserve the file, to serialized access to files. This not only
+ * simplifies things, but also defends against non-reentrancy.
+ * 4. If the "file" is "set" for non-blocking I/O, check if we
+ * have actually set the file non-blocking yet, and if not do so.
+ * Then, issue the I/O operantion.
+ * Success or failure is returned immediately, after unreserving the
+ * file. If the error indicates that the operation would have caused
+ * the process to block, continue to the next step.
+ * 5. The I/O prolog adds this "file" to the global bit mask, which
+ * represents all "files" which have threads waiting to perform I/O on
+ * them, and causes the thread to block on the condition variable for
+ * this "file". Periodically, a select is done on this global bit
+ * mask, and the condition variables corresponding to "files" which
+ * are ready for I/O are signaled, releasing those waiting threads to
+ * perform their I/O.
+ * 6. When the thread returns from the I/O prolog, it can (hopefully)
+ * perform its operation without blocking the process.
+ * 7. The I/O epilog clears the bit in the global mask and/or signals the
+ * the next thread waiting for this "file", as appropriate.
+ * 8. If the I/O failed, continue to loop.
+ * 9. Finally, the "file" is unreserved, as we're done with it, and the
+ * result of the operation is returned.
+ *
+ *
+ * Note: currently, we believe that timeslicing which is based on the
+ * virtual-time timer does not cause system calls to return EINTR.
+ * Threfore, any EINTR returns are relayed directly to the caller.
+ * On platforms which do not support a virtual-time timer, the code
+ * should probably catch EINTR returns and restart the system call.
+ */
+
+/*
+ * This macro is used for both read-type and write-type functions.
+ *
+ * Note: the second call to "func" may require being bracketed in a
+ * cma__interrupt_disable/cma__interrupt_enable pair, but we'll
+ * wait and see if this is necessary.
+ */
+#define cma__ts_func(func,fd,arglist,type,post_process) { \
+ cma_t_integer __res__; \
+ cma_t_boolean __done__ = cma_c_false; \
+ if ((fd < 0) || (fd >= cma__g_mx_file)) return (cma__set_errno (EBADF), -1); \
+ if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
+ cma__fd_reserve (fd); \
+ if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
+ if (cma__issue_io_call(fd)) {\
+ if ((!cma__g_file[fd]->set_non_blocking) && \
+ (cma__g_file[fd]->non_blocking == cma_c_true)) \
+ cma__set_nonblocking(fd); \
+ cma__interrupt_disable (0); \
+ TRY { \
+ __res__ = func arglist; \
+ } \
+ CATCH_ALL { \
+ cma__interrupt_enable (0); \
+ cma__fd_unreserve (fd); \
+ RERAISE; \
+ } \
+ ENDTRY \
+ cma__interrupt_enable (0); \
+ if ((__res__ != -1) \
+ || (!cma__is_blocking (errno)) \
+ || (cma__g_file[fd]->user_fl.user_non_blocking)) \
+ __done__ = cma_c_true; \
+ } \
+ if (__done__) { \
+ cma__fd_unreserve (fd); \
+ } \
+ else { \
+ TRY { \
+ cma__io_prolog (type, fd); \
+ while (!__done__) { \
+ cma__io_wait (type, fd); \
+ __res__ = func arglist; \
+ if ((__res__ != -1) \
+ || (!cma__is_blocking (errno)) \
+ || (cma__g_file[fd]->user_fl.user_non_blocking)) \
+ __done__ = cma_c_true; \
+ } \
+ } \
+ FINALLY { \
+ cma__io_epilog (type, fd); \
+ cma__fd_unreserve (fd); \
+ } \
+ ENDTRY \
+ } \
+ if (__res__ != -1) post_process; \
+ return __res__; \
+ }
+
+ /*
+ * Since most CMA "thread-synchronous" I/O ("open"-type) operations on
+ * U*ix follow the exact same structure, the wrapper routines have been
+ * condensed into a macro.
+ *
+ * The steps performed are as follows:
+ * 1. Issue the open function.
+ * 2. If the value returned indicates an error, return it to the caller.
+ * 3. If the file descriptor returned is larger than what we think is the
+ * maximum value (ie if it is too big for our database) then bugcheck.
+ * 4. "Open" the "file" in the CMA file database.
+ * 5. Return the file descriptor value to the caller.
+ *
+ * FIX-ME: for the time being, if the I/O operation returns EINTR, we
+ * simply return it to the caller; eventually, we should catch this
+ * and "do the right thing" (if we can figure out what that is).
+ */
+
+/*
+ * This macro is used for all "open"-type functions which return a single file
+ * desciptor by immediate value.
+ */
+#define cma__ts_open(func,arglist,post_process) { \
+ int __fd__; \
+ TRY { \
+ cma__int_init (); \
+ cma__int_lock (cma__g_io_data_mutex); \
+ __fd__ = func arglist; \
+ cma__int_unlock (cma__g_io_data_mutex); \
+ if (__fd__ >= 0 && __fd__ < cma__g_mx_file) \
+ post_process; \
+ } \
+ CATCH_ALL \
+ { \
+ cma__set_errno (EBADF); \
+ __fd__ = -1; \
+ } \
+ ENDTRY \
+ if (__fd__ >= cma__g_mx_file) \
+ cma__bugcheck ("cma__ts_open: fd is too large"); \
+ return __fd__; \
+ }
+/*
+ * This macro is used for all "open"-type functions which return a pair of file
+ * desciptors by reference parameter.
+ */
+#define cma__ts_open2(func,fdpair,arglist,post_process) { \
+ int __res__; \
+ TRY { \
+ cma__int_init (); \
+ cma__int_lock (cma__g_io_data_mutex); \
+ __res__ = func arglist; \
+ cma__int_unlock (cma__g_io_data_mutex); \
+ if (__res__ >= 0 && fdpair[0] < cma__g_mx_file \
+ && fdpair[1] < cma__g_mx_file) \
+ post_process; \
+ } \
+ CATCH_ALL \
+ { \
+ cma__set_errno (EBADF); \
+ __res__ = -1; \
+ } \
+ ENDTRY \
+ if ((fdpair[0] >= cma__g_mx_file) || (fdpair[1] >= cma__g_mx_file)) \
+ cma__bugcheck ("cma__ts_open2: one of fd's is too large"); \
+ return __res__; \
+ }
+
+/*
+ * INTERNAL INTERFACES
+ */
+extern void cma__close_general (int);
+
+extern void cma__init_thread_io (void);
+
+extern cma_t_boolean cma__io_available (cma__t_io_type,int,struct timeval *);
+
+extern void cma__io_epilog (cma__t_io_type,int);
+
+extern void cma__io_prolog (cma__t_io_type,int);
+
+extern void cma__io_wait (cma__t_io_type,int);
+
+extern void cma__open_general (int);
+
+extern void cma__reinit_thread_io (int);
+
+extern void cma__set_nonblocking (int);
+
+extern void cma__set_user_nonblock_flags (int,int);
+
+extern cma_t_boolean cma__is_open (int);
+
+
+#endif
diff --git a/gdb/osf-share/HP800/cma_thread_io.h b/gdb/osf-share/HP800/cma_thread_io.h
new file mode 100644
index 00000000000..e9bef3be457
--- /dev/null
+++ b/gdb/osf-share/HP800/cma_thread_io.h
@@ -0,0 +1,432 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *
+ * Header file for thread synchrounous I/O
+ */
+
+#ifndef CMA_THREAD_IO
+#define CMA_THREAD_IO
+
+/*
+ * INCLUDE FILES
+ */
+
+#include <cma_config.h>
+#include <sys/file.h>
+#include <cma.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <cma_init.h>
+#include <cma_errors.h>
+
+/*
+ * CONSTANTS
+ */
+
+
+
+/*
+ * Maximum number of files (ie, max_fd+1)
+ */
+#define cma__c_mx_file FD_SETSIZE
+
+/*
+ * Number of bits per file descriptor bit mask (ie number of bytes * bits/byte)
+ */
+#define cma__c_nbpm NFDBITS
+
+/*
+ * TYPE DEFINITIONS
+ */
+
+typedef enum CMA__T_IO_TYPE {
+ cma__c_io_read = 0,
+ cma__c_io_write = 1,
+ cma__c_io_except = 2
+ } cma__t_io_type;
+#define cma__c_max_io_type 2
+
+/*
+ * From our local <sys/types.h>:
+ *
+ * typedef long fd_mask;
+ *
+ * typedef struct fd_set {
+ * fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
+ * } fd_set;
+ *
+ */
+typedef fd_mask cma__t_mask;
+typedef fd_set cma__t_file_mask;
+
+
+
+/*
+ * GLOBAL DATA
+ */
+
+/*
+ * Maximum number of files (ie, max_fd+1) as determined by getdtablesize().
+ */
+extern int cma__g_mx_file;
+
+/*
+ * Number of submasks (ie "int" sized chunks) per file descriptor mask as
+ * determined by getdtablesize().
+ */
+extern int cma__g_nspm;
+
+/*
+ * MACROS
+ */
+
+/*
+ * Define a constant for the errno value which indicates that the requested
+ * operation was not performed because it would block the process.
+ */
+# define cma__is_blocking(s) \
+ ((s == EAGAIN) || (s == EWOULDBLOCK) || (s == EINPROGRESS) || \
+ (s == EALREADY) || (s == EDEADLK))
+
+/*
+* It is necessary to issue an I/O function, before calling cma__io_wait()
+* in the following cases:
+*
+* * This file descriptor has been set non-blocking by CMA
+* * This file descriptor has been set non-blocking by the user.
+*/
+
+#define cma__issue_io_call(fd) \
+ ( (cma__g_file[fd]->non_blocking) || \
+ (cma__g_file[fd]->user_fl.user_non_blocking) )
+
+
+#define cma__set_user_nonblocking(flags) \
+
+/*
+ * Determine if the file is open
+ */
+/*
+ * If the file gets closed while waiting for the mutex cma__g_file[rfd]
+ * gets set to null. This results in a crash if NDEBUG is set to 0
+ * since cma__int_lock tries to dereference it to set the mutex ownership
+ * after it gets the mutex. The following will still set the ownership
+ * in cma__int_lock so we'll set it back to noone if cma__g_file is null
+ * when we come back just in case it matters. It shouldn't since its no
+ * longer in use but.....
+ * Callers of this should recheck cma__g_file after the reservation to
+ * make sure continueing makes sense.
+ */
+#define cma__fd_reserve(rfd) \
+ { \
+ cma__t_int_mutex *__mutex__; \
+ __mutex__ = cma__g_file[rfd]->mutex; \
+ cma__int_lock (__mutex__); \
+ if(cma__g_file[rfd] == (cma__t_file_obj *)cma_c_null_ptr) \
+ cma__int_unlock(__mutex__); \
+ }
+
+
+/*
+ * Unreserve a file descriptor
+ */
+#define cma__fd_unreserve(ufd) cma__int_unlock (cma__g_file[ufd]->mutex)
+
+/*
+ * AND together two select file descriptor masks
+ */
+#define cma__fdm_and(target,a,b) \
+ { \
+ int __i__ = cma__g_nspm; \
+ while (__i__--) \
+ (target)->fds_bits[__i__] = \
+ (a)->fds_bits[__i__] & (b)->fds_bits[__i__]; \
+ }
+
+/*
+ * Clear a bit in a select file descriptor mask
+ *
+ * FD_CLR(n, p) := ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_clr_bit(n,p) FD_CLR (n, p)
+
+/*
+ * Copy the contents of one file descriptor mask into another. If the
+ * destination operand is null, do nothing; if the source operand is null,
+ * simply zero the destination.
+ */
+#define cma__fdm_copy(src,dst,nfds) { \
+ if (dst) \
+ if (src) { \
+ cma__t_mask *__s__ = (cma__t_mask *)(src); \
+ cma__t_mask *__d__ = (cma__t_mask *)(dst); \
+ int __i__; \
+ for (__i__ = 0; __i__ < (nfds); __i__ += cma__c_nbpm) \
+ *__d__++ = *__s__++; \
+ } \
+ else \
+ cma__fdm_zero (dst); \
+ }
+
+/*
+ * To increment count for each bit set in fd - mask
+ */
+#define cma__fdm_count_bits(map,count) \
+ { \
+ int __i__ = cma__g_nspm; \
+ while (__i__--) { \
+ cma__t_mask __tm__; \
+ __tm__ = (map)->fds_bits[__i__]; \
+ while(__tm__) { \
+ (count)++; \
+ __tm__ &= ~(__tm__ & (-__tm__)); /* Assumes 2's comp */ \
+ } \
+ } \
+ }
+
+/*
+ * Test if a bit is set in a select file descriptor mask
+ *
+ * FD_ISSET(n,p) := ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_is_set(n,p) FD_ISSET (n, p)
+
+/*
+ * OR together two select file descriptor masks
+ */
+#define cma__fdm_or(target,a,b) \
+ { \
+ int __i__ = cma__g_nspm; \
+ while (__i__--) \
+ (target)->fds_bits[__i__] = \
+ (a)->fds_bits[__i__] | (b)->fds_bits[__i__]; \
+ }
+
+/*
+ * Set a bit in a select file descriptor mask
+ *
+ * FD_SET(n,p) := ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_set_bit(n,p) FD_SET (n, p)
+
+/*
+ * Clear a select file descriptor mask.
+ */
+#define cma__fdm_zero(n) \
+ cma__memset ((char *) n, 0, cma__g_nspm * sizeof(cma__t_mask))
+
+
+
+
+
+/*
+ * CMA "thread-synchronous" I/O read/write operations
+ */
+
+ /*
+ * Since all CMA "thread-synchronous" I/O (read or write) operations on
+ * U*ix follow the exact same structure, the wrapper routines have been
+ * condensed into a macro.
+ *
+ * The steps performed are as follows:
+ * 1. Check that the file descriptor is a legitimate value.
+ * 2. Check that the entry in the CMA file "database" which corresponds to
+ * the file descriptor indicates that the "file" was "opened" by CMA.
+ * 3. Reserve the file, to serialized access to files. This not only
+ * simplifies things, but also defends against non-reentrancy.
+ * 4. If the "file" is "set" for non-blocking I/O, check if we
+ * have actually set the file non-blocking yet, and if not do so.
+ * Then, issue the I/O operantion.
+ * Success or failure is returned immediately, after unreserving the
+ * file. If the error indicates that the operation would have caused
+ * the process to block, continue to the next step.
+ * 5. The I/O prolog adds this "file" to the global bit mask, which
+ * represents all "files" which have threads waiting to perform I/O on
+ * them, and causes the thread to block on the condition variable for
+ * this "file". Periodically, a select is done on this global bit
+ * mask, and the condition variables corresponding to "files" which
+ * are ready for I/O are signaled, releasing those waiting threads to
+ * perform their I/O.
+ * 6. When the thread returns from the I/O prolog, it can (hopefully)
+ * perform its operation without blocking the process.
+ * 7. The I/O epilog clears the bit in the global mask and/or signals the
+ * the next thread waiting for this "file", as appropriate.
+ * 8. If the I/O failed, continue to loop.
+ * 9. Finally, the "file" is unreserved, as we're done with it, and the
+ * result of the operation is returned.
+ *
+ *
+ * Note: currently, we believe that timeslicing which is based on the
+ * virtual-time timer does not cause system calls to return EINTR.
+ * Threfore, any EINTR returns are relayed directly to the caller.
+ * On platforms which do not support a virtual-time timer, the code
+ * should probably catch EINTR returns and restart the system call.
+ */
+
+/*
+ * This macro is used for both read-type and write-type functions.
+ *
+ * Note: the second call to "func" may require being bracketed in a
+ * cma__interrupt_disable/cma__interrupt_enable pair, but we'll
+ * wait and see if this is necessary.
+ */
+#define cma__ts_func(func,fd,arglist,type,post_process) { \
+ cma_t_integer __res__; \
+ cma_t_boolean __done__ = cma_c_false; \
+ if ((fd < 0) || (fd >= cma__g_mx_file)) return (cma__set_errno (EBADF), -1); \
+ if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
+ cma__fd_reserve (fd); \
+ if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
+ if (cma__issue_io_call(fd)) {\
+ if ((!cma__g_file[fd]->set_non_blocking) && \
+ (cma__g_file[fd]->non_blocking == cma_c_true)) \
+ cma__set_nonblocking(fd); \
+ cma__interrupt_disable (0); \
+ TRY { \
+ __res__ = func arglist; \
+ } \
+ CATCH_ALL { \
+ cma__interrupt_enable (0); \
+ cma__fd_unreserve (fd); \
+ RERAISE; \
+ } \
+ ENDTRY \
+ cma__interrupt_enable (0); \
+ if ((__res__ != -1) \
+ || (!cma__is_blocking (errno)) \
+ || (cma__g_file[fd]->user_fl.user_non_blocking)) \
+ __done__ = cma_c_true; \
+ } \
+ if (__done__) { \
+ cma__fd_unreserve (fd); \
+ } \
+ else { \
+ TRY { \
+ cma__io_prolog (type, fd); \
+ while (!__done__) { \
+ cma__io_wait (type, fd); \
+ __res__ = func arglist; \
+ if ((__res__ != -1) \
+ || (!cma__is_blocking (errno)) \
+ || (cma__g_file[fd]->user_fl.user_non_blocking)) \
+ __done__ = cma_c_true; \
+ } \
+ } \
+ FINALLY { \
+ cma__io_epilog (type, fd); \
+ cma__fd_unreserve (fd); \
+ } \
+ ENDTRY \
+ } \
+ if (__res__ != -1) post_process; \
+ return __res__; \
+ }
+
+ /*
+ * Since most CMA "thread-synchronous" I/O ("open"-type) operations on
+ * U*ix follow the exact same structure, the wrapper routines have been
+ * condensed into a macro.
+ *
+ * The steps performed are as follows:
+ * 1. Issue the open function.
+ * 2. If the value returned indicates an error, return it to the caller.
+ * 3. If the file descriptor returned is larger than what we think is the
+ * maximum value (ie if it is too big for our database) then bugcheck.
+ * 4. "Open" the "file" in the CMA file database.
+ * 5. Return the file descriptor value to the caller.
+ *
+ * FIX-ME: for the time being, if the I/O operation returns EINTR, we
+ * simply return it to the caller; eventually, we should catch this
+ * and "do the right thing" (if we can figure out what that is).
+ */
+
+/*
+ * This macro is used for all "open"-type functions which return a single file
+ * desciptor by immediate value.
+ */
+#define cma__ts_open(func,arglist,post_process) { \
+ int __fd__; \
+ TRY { \
+ cma__int_init (); \
+ cma__int_lock (cma__g_io_data_mutex); \
+ __fd__ = func arglist; \
+ cma__int_unlock (cma__g_io_data_mutex); \
+ if (__fd__ >= 0 && __fd__ < cma__g_mx_file) \
+ post_process; \
+ } \
+ CATCH_ALL \
+ { \
+ cma__set_errno (EBADF); \
+ __fd__ = -1; \
+ } \
+ ENDTRY \
+ if (__fd__ >= cma__g_mx_file) \
+ cma__bugcheck ("cma__ts_open: fd is too large"); \
+ return __fd__; \
+ }
+/*
+ * This macro is used for all "open"-type functions which return a pair of file
+ * desciptors by reference parameter.
+ */
+#define cma__ts_open2(func,fdpair,arglist,post_process) { \
+ int __res__; \
+ TRY { \
+ cma__int_init (); \
+ cma__int_lock (cma__g_io_data_mutex); \
+ __res__ = func arglist; \
+ cma__int_unlock (cma__g_io_data_mutex); \
+ if (__res__ >= 0 && fdpair[0] < cma__g_mx_file \
+ && fdpair[1] < cma__g_mx_file) \
+ post_process; \
+ } \
+ CATCH_ALL \
+ { \
+ cma__set_errno (EBADF); \
+ __res__ = -1; \
+ } \
+ ENDTRY \
+ if ((fdpair[0] >= cma__g_mx_file) || (fdpair[1] >= cma__g_mx_file)) \
+ cma__bugcheck ("cma__ts_open2: one of fd's is too large"); \
+ return __res__; \
+ }
+
+/*
+ * INTERNAL INTERFACES
+ */
+extern void cma__close_general (int);
+
+extern void cma__init_thread_io (void);
+
+extern cma_t_boolean cma__io_available (cma__t_io_type,int,struct timeval *);
+
+extern void cma__io_epilog (cma__t_io_type,int);
+
+extern void cma__io_prolog (cma__t_io_type,int);
+
+extern void cma__io_wait (cma__t_io_type,int);
+
+extern void cma__open_general (int);
+
+extern void cma__reinit_thread_io (int);
+
+extern void cma__set_nonblocking (int);
+
+extern void cma__set_user_nonblock_flags (int,int);
+
+extern cma_t_boolean cma__is_open (int);
+
+#endif
diff --git a/gdb/osf-share/README b/gdb/osf-share/README
new file mode 100644
index 00000000000..c6d2e0fb532
--- /dev/null
+++ b/gdb/osf-share/README
@@ -0,0 +1,8 @@
+This directory contains header files necessary to build a thread-aware GDB on
+systems based on OSF's CMA threads package.
+
+The latest version of these header files are available for free from:
+
+ http://www.osf.org/mall/dce/SW-code
+
+Currently, the only port of GDB which supports CMA threads is HP/UX-10.10.
diff --git a/gdb/osf-share/RIOS/cma_thread_io.h b/gdb/osf-share/RIOS/cma_thread_io.h
new file mode 100644
index 00000000000..98117caf7d3
--- /dev/null
+++ b/gdb/osf-share/RIOS/cma_thread_io.h
@@ -0,0 +1,434 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * Header file for thread synchrounous I/O
+ */
+
+#ifndef CMA_THREAD_IO
+#define CMA_THREAD_IO
+
+/*
+ * INCLUDE FILES
+ */
+
+#include <cma_config.h>
+#include <sys/select.h>
+#include <cma.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <cma_init.h>
+#include <cma_errors.h>
+
+/*
+ * CONSTANTS
+ */
+
+/*
+ * Maximum number of files (ie, max_fd+1)
+ */
+#define cma__c_mx_file FD_SETSIZE
+
+/*
+ * Number of bits per file descriptor bit mask (ie number of bytes * bits/byte)
+ */
+#define cma__c_nbpm NFDBITS
+
+/*
+ * TYPE DEFINITIONS
+ */
+
+typedef enum CMA__T_IO_TYPE {
+ cma__c_io_read = 0,
+ cma__c_io_write = 1,
+ cma__c_io_except = 2
+ } cma__t_io_type;
+#define cma__c_max_io_type 2
+
+/*
+ * From our local <sys/types.h>:
+ *
+ * typedef long fd_mask;
+ *
+ * typedef struct fd_set {
+ * fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
+ * } fd_set;
+ *
+ */
+typedef fd_mask cma__t_mask;
+typedef fd_set cma__t_file_mask;
+
+
+
+/*
+ * GLOBAL DATA
+ */
+
+/*
+ * Maximum number of files (ie, max_fd+1) as determined by getdtablesize().
+ */
+extern int cma__g_mx_file;
+
+/*
+ * Number of submasks (ie "int" sized chunks) per file descriptor mask as
+ * determined by getdtablesize().
+ */
+extern int cma__g_nspm;
+
+/*
+ * MACROS
+ */
+
+/*
+ * Define a constant for the errno value which indicates that the requested
+ * operation was not performed because it would block the process.
+ */
+# define cma__is_blocking(s) \
+ ((s == EAGAIN) || (s == EWOULDBLOCK) || (s == EINPROGRESS) || \
+ (s == EALREADY) || (s == EDEADLK))
+
+/*
+* It is necessary to issue an I/O function, before calling cma__io_wait()
+* in the following cases:
+*
+* * This file descriptor has been set non-blocking by CMA
+* * This file descriptor has been set non-blocking by the user.
+*/
+
+#define cma__issue_io_call(fd) \
+ ( (cma__g_file[fd]->non_blocking) || \
+ (cma__g_file[fd]->user_fl.user_non_blocking) )
+
+
+#define cma__set_user_nonblocking(flags) \
+
+/*
+ * Determine if the file is open
+ */
+/*
+ * If the file gets closed while waiting for the mutex cma__g_file[rfd]
+ * gets set to null. This results in a crash if NDEBUG is set to 0
+ * since cma__int_lock tries to dereference it to set the mutex ownership
+ * after it gets the mutex. The following will still set the ownership
+ * in cma__int_lock so we'll set it back to noone if cma__g_file is null
+ * when we come back just in case it matters. It shouldn't since its no
+ * longer in use but.....
+ * Callers of this should recheck cma__g_file after the reservation to
+ * make sure continueing makes sense.
+ */
+#define cma__fd_reserve(rfd) \
+ { \
+ cma__t_int_mutex *__mutex__; \
+ __mutex__ = cma__g_file[rfd]->mutex; \
+ cma__int_lock (__mutex__); \
+ if(cma__g_file[rfd] == (cma__t_file_obj *)cma_c_null_ptr) \
+ cma__int_unlock(__mutex__); \
+ }
+
+
+/*
+ * Unreserve a file descriptor
+ */
+#define cma__fd_unreserve(ufd) cma__int_unlock (cma__g_file[ufd]->mutex)
+
+/*
+ * AND together two select file descriptor masks
+ */
+#define cma__fdm_and(target,a,b) \
+ { \
+ int __i__ = cma__g_nspm; \
+ while (__i__--) \
+ (target)->fds_bits[__i__] = \
+ (a)->fds_bits[__i__] & (b)->fds_bits[__i__]; \
+ }
+
+/*
+ * Clear a bit in a select file descriptor mask
+ *
+ * FD_CLR(n, p) := ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_clr_bit(n,p) FD_CLR (n, p)
+
+/*
+ * Copy the contents of one file descriptor mask into another. If the
+ * destination operand is null, do nothing; if the source operand is null,
+ * simply zero the destination.
+ */
+#define cma__fdm_copy(src,dst,nfds) { \
+ if (dst) \
+ if (src) { \
+ cma__t_mask *__s__ = (cma__t_mask *)(src); \
+ cma__t_mask *__d__ = (cma__t_mask *)(dst); \
+ int __i__; \
+ for (__i__ = 0; __i__ < (nfds); __i__ += cma__c_nbpm) \
+ *__d__++ = *__s__++; \
+ } \
+ else \
+ cma__fdm_zero (dst); \
+ }
+
+/*
+ * To increment count for each bit set in fd - mask
+ */
+#define cma__fdm_count_bits(map,count) \
+ { \
+ int __i__ = cma__g_nspm; \
+ while (__i__--) { \
+ cma__t_mask __tm__; \
+ __tm__ = (map)->fds_bits[__i__]; \
+ while(__tm__) { \
+ (count)++; \
+ __tm__ &= ~(__tm__ & (-__tm__)); /* Assumes 2's comp */ \
+ } \
+ } \
+ }
+
+/*
+ * Test if a bit is set in a select file descriptor mask
+ *
+ * FD_ISSET(n,p) := ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_is_set(n,p) FD_ISSET (n, p)
+
+/*
+ * OR together two select file descriptor masks
+ */
+#define cma__fdm_or(target,a,b) \
+ { \
+ int __i__ = cma__g_nspm; \
+ while (__i__--) \
+ (target)->fds_bits[__i__] = \
+ (a)->fds_bits[__i__] | (b)->fds_bits[__i__]; \
+ }
+
+/*
+ * Set a bit in a select file descriptor mask
+ *
+ * FD_SET(n,p) := ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_set_bit(n,p) FD_SET (n, p)
+
+/*
+ * Clear a select file descriptor mask.
+ */
+#define cma__fdm_zero(n) \
+ cma__memset ((char *) n, 0, cma__g_nspm * sizeof(cma__t_mask))
+
+
+
+
+
+/*
+ * CMA "thread-synchronous" I/O read/write operations
+ */
+
+ /*
+ * Since all CMA "thread-synchronous" I/O (read or write) operations on
+ * U*ix follow the exact same structure, the wrapper routines have been
+ * condensed into a macro.
+ *
+ * The steps performed are as follows:
+ * 1. Check that the file descriptor is a legitimate value.
+ * 2. Check that the entry in the CMA file "database" which corresponds to
+ * the file descriptor indicates that the "file" was "opened" by CMA.
+ * 3. Reserve the file, to serialized access to files. This not only
+ * simplifies things, but also defends against non-reentrancy.
+ * 4. If the "file" is "set" for non-blocking I/O, check if we
+ * have actually set the file non-blocking yet, and if not do so.
+ * Then, issue the I/O operantion.
+ * Success or failure is returned immediately, after unreserving the
+ * file. If the error indicates that the operation would have caused
+ * the process to block, continue to the next step.
+ * 5. The I/O prolog adds this "file" to the global bit mask, which
+ * represents all "files" which have threads waiting to perform I/O on
+ * them, and causes the thread to block on the condition variable for
+ * this "file". Periodically, a select is done on this global bit
+ * mask, and the condition variables corresponding to "files" which
+ * are ready for I/O are signaled, releasing those waiting threads to
+ * perform their I/O.
+ * 6. When the thread returns from the I/O prolog, it can (hopefully)
+ * perform its operation without blocking the process.
+ * 7. The I/O epilog clears the bit in the global mask and/or signals the
+ * the next thread waiting for this "file", as appropriate.
+ * 8. If the I/O failed, continue to loop.
+ * 9. Finally, the "file" is unreserved, as we're done with it, and the
+ * result of the operation is returned.
+ *
+ *
+ * Note: currently, we believe that timeslicing which is based on the
+ * virtual-time timer does not cause system calls to return EINTR.
+ * Threfore, any EINTR returns are relayed directly to the caller.
+ * On platforms which do not support a virtual-time timer, the code
+ * should probably catch EINTR returns and restart the system call.
+ */
+
+/*
+ * This macro is used for both read-type and write-type functions.
+ *
+ * Note: the second call to "func" may require being bracketed in a
+ * cma__interrupt_disable/cma__interrupt_enable pair, but we'll
+ * wait and see if this is necessary.
+ */
+#define cma__ts_func(func,fd,arglist,type,post_process) { \
+ cma_t_integer __res__; \
+ cma_t_boolean __done__ = cma_c_false; \
+ if ((fd < 0) || (fd >= cma__g_mx_file)) return (cma__set_errno (EBADF), -1); \
+ if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
+ cma__fd_reserve (fd); \
+ if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
+ if (cma__issue_io_call(fd)) {\
+ if ((!cma__g_file[fd]->set_non_blocking) && \
+ (cma__g_file[fd]->non_blocking == cma_c_true)) \
+ cma__set_nonblocking(fd); \
+ cma__interrupt_disable (0); \
+ TRY { \
+ __res__ = func arglist; \
+ } \
+ CATCH_ALL { \
+ cma__interrupt_enable (0); \
+ cma__fd_unreserve (fd); \
+ RERAISE; \
+ } \
+ ENDTRY \
+ cma__interrupt_enable (0); \
+ if ((__res__ != -1) \
+ || (!cma__is_blocking (errno)) \
+ || (cma__g_file[fd]->user_fl.user_non_blocking)) \
+ __done__ = cma_c_true; \
+ } \
+ if (__done__) { \
+ cma__fd_unreserve (fd); \
+ } \
+ else { \
+ TRY { \
+ cma__io_prolog (type, fd); \
+ while (!__done__) { \
+ cma__io_wait (type, fd); \
+ __res__ = func arglist; \
+ if ((__res__ != -1) \
+ || (!cma__is_blocking (errno)) \
+ || (cma__g_file[fd]->user_fl.user_non_blocking)) \
+ __done__ = cma_c_true; \
+ } \
+ } \
+ FINALLY { \
+ cma__io_epilog (type, fd); \
+ cma__fd_unreserve (fd); \
+ } \
+ ENDTRY \
+ } \
+ if (__res__ != -1) post_process; \
+ return __res__; \
+ }
+
+ /*
+ * Since most CMA "thread-synchronous" I/O ("open"-type) operations on
+ * U*ix follow the exact same structure, the wrapper routines have been
+ * condensed into a macro.
+ *
+ * The steps performed are as follows:
+ * 1. Issue the open function.
+ * 2. If the value returned indicates an error, return it to the caller.
+ * 3. If the file descriptor returned is larger than what we think is the
+ * maximum value (ie if it is too big for our database) then bugcheck.
+ * 4. "Open" the "file" in the CMA file database.
+ * 5. Return the file descriptor value to the caller.
+ *
+ * FIX-ME: for the time being, if the I/O operation returns EINTR, we
+ * simply return it to the caller; eventually, we should catch this
+ * and "do the right thing" (if we can figure out what that is).
+ */
+
+/*
+ * This macro is used for all "open"-type functions which return a single file
+ * desciptor by immediate value.
+ */
+#define cma__ts_open(func,arglist,post_process) { \
+ int __fd__; \
+ TRY { \
+ cma__int_init (); \
+ cma__int_lock (cma__g_io_data_mutex); \
+ __fd__ = func arglist; \
+ cma__int_unlock (cma__g_io_data_mutex); \
+ if (__fd__ >= 0 && __fd__ < cma__g_mx_file) \
+ post_process; \
+ } \
+ CATCH_ALL \
+ { \
+ cma__set_errno (EBADF); \
+ __fd__ = -1; \
+ } \
+ ENDTRY \
+ if (__fd__ >= cma__g_mx_file) \
+ cma__bugcheck ("cma__ts_open: fd is too large"); \
+ return __fd__; \
+ }
+/*
+ * This macro is used for all "open"-type functions which return a pair of file
+ * desciptors by reference parameter.
+ */
+#define cma__ts_open2(func,fdpair,arglist,post_process) { \
+ int __res__; \
+ TRY { \
+ cma__int_init (); \
+ cma__int_lock (cma__g_io_data_mutex); \
+ __res__ = func arglist; \
+ cma__int_unlock (cma__g_io_data_mutex); \
+ if (__res__ >= 0 && fdpair[0] < cma__g_mx_file \
+ && fdpair[1] < cma__g_mx_file) \
+ post_process; \
+ } \
+ CATCH_ALL \
+ { \
+ cma__set_errno (EBADF); \
+ __res__ = -1; \
+ } \
+ ENDTRY \
+ if ((fdpair[0] >= cma__g_mx_file) || (fdpair[1] >= cma__g_mx_file)) \
+ cma__bugcheck ("cma__ts_open2: one of fd's is too large"); \
+ return __res__; \
+ }
+
+/*
+ * INTERNAL INTERFACES
+ */
+extern void cma__close_general (int);
+
+extern void
+cma__init_thread_io (void);
+
+extern cma_t_boolean cma__io_available (cma__t_io_type,int,struct timeval *);
+
+extern void cma__io_epilog (cma__t_io_type,int);
+
+extern void cma__io_prolog (cma__t_io_type,int);
+
+extern void cma__io_wait (cma__t_io_type,int);
+
+extern void cma__open_general (int);
+
+extern void cma__reinit_thread_io (int);
+
+extern void cma__set_nonblocking (int);
+
+extern void cma__set_user_nonblock_flags (int,int);
+
+extern cma_t_boolean
+cma__is_open (int fd);
+
+
+#endif
+
+
diff --git a/gdb/osf-share/cma_attr.h b/gdb/osf-share/cma_attr.h
new file mode 100644
index 00000000000..389fd6fd207
--- /dev/null
+++ b/gdb/osf-share/cma_attr.h
@@ -0,0 +1,341 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * Header file for attributes object
+ */
+
+#ifndef CMA_ATTR
+#define CMA_ATTR
+
+/*
+ * INCLUDE FILES
+ */
+
+#include <cma_defs.h>
+#include <cma_queue.h>
+#ifdef __hpux
+# include <sys/param.h>
+#endif
+#if _CMA_UNIX_TYPE == _CMA__SVR4
+#include <sys/unistd.h>
+#endif
+/*
+ * CONSTANTS AND MACROS
+ */
+
+
+/*
+ * FUNCTIONAL DESCRIPTION:
+ *
+ * cma__int_attr_get_priority - Performs the work of cma_attr_get_priority
+ *
+ * FORMAL PARAMETERS:
+ *
+ * cma_t_attr *_att_ - Attribute object to get from
+ * cma_t_priority *_setting_ - Current setting
+ *
+ * IMPLICIT INPUTS:
+ *
+ * none
+ *
+ * IMPLICIT OUTPUTS:
+ *
+ * priority
+ *
+ * FUNCTION VALUE:
+ *
+ * none
+ *
+ * SIDE EFFECTS:
+ *
+ * none
+ */
+#define cma__int_attr_get_priority(_att_,_setting_) { \
+ cma__t_int_attr *_int_att_; \
+ (_int_att_) = cma__validate_default_attr (_att_); \
+ cma__int_lock ((_int_att_)->mutex); \
+ (*(_setting_)) = (_int_att_)->priority; \
+ cma__int_unlock ((_int_att_)->mutex); \
+ }
+
+
+/*
+ * FUNCTIONAL DESCRIPTION:
+ *
+ * cma__int_attr_get_sched - Performs work of cma_attr_get_sched
+ *
+ * FORMAL PARAMETERS:
+ *
+ * cma_t_attr *_att_ _ Attributes object used
+ * cma_t_sched_policy *_setting_ - Current setting
+ *
+ * IMPLICIT INPUTS:
+ *
+ * none
+ *
+ * IMPLICIT OUTPUTS:
+ *
+ * scheduling policy
+ *
+ * FUNCTION VALUE:
+ *
+ * none
+ *
+ * SIDE EFFECTS:
+ *
+ * none
+ */
+#define cma__int_attr_get_sched(_att_,_setting_) { \
+ cma__t_int_attr *_int_att_; \
+ (_int_att_) = cma__validate_default_attr (_att_); \
+ cma__int_lock ((_int_att_)->mutex); \
+ (*(_setting_)) = (_int_att_)->policy; \
+ cma__int_unlock ((_int_att_)->mutex); \
+ }
+
+
+/*
+ * FUNCTIONAL DESCRIPTION:
+ *
+ * cma__int_attr_get_inherit_sched - Performs work of
+ * cma_attr_get_inherit_sched
+ *
+ * FORMAL PARAMETERS:
+ *
+ * cma_t_attr *_att_ - Attributes object to use
+ * cma_t_sched_inherit *_setting_ - Current setting
+ *
+ * IMPLICIT INPUTS:
+ *
+ * none
+ *
+ * IMPLICIT OUTPUTS:
+ *
+ * Inheritable scheduling policy
+ *
+ * FUNCTION VALUE:
+ *
+ * none
+ *
+ * SIDE EFFECTS:
+ *
+ * none
+ */
+#define cma__int_attr_get_inherit_sched(_att_,_setting_) { \
+ cma__t_int_attr *_int_att_; \
+ (_int_att_) = cma__validate_default_attr (_att_); \
+ cma__int_lock ((_int_att_)->mutex); \
+ (*(_setting_)) \
+ = ((_int_att_)->inherit_sched ? cma_c_sched_inherit : cma_c_sched_use_default); \
+ cma__int_unlock ((_int_att_)->mutex); \
+ }
+
+/*
+ * FUNCTIONAL DESCRIPTION:
+ *
+ * cma__int_attr_set_stacksize - Performs work for cma_attr_set_stacksize
+ *
+ * FORMAL PARAMETERS:
+ *
+ * cma_t_attr *_att_ - Attributes object to use
+ * cma_t_natural _setting_ - Setting
+ *
+ * IMPLICIT INPUTS:
+ *
+ * none
+ *
+ * IMPLICIT OUTPUTS:
+ *
+ * none
+ *
+ * FUNCTION VALUE:
+ *
+ * none
+ *
+ * SIDE EFFECTS:
+ *
+ * Change attribute objects stack size setting
+ */
+#define cma__int_attr_set_stacksize(_att_,_setting_) { \
+ cma__t_int_attr *_int_att_; \
+ if ((_setting_) <= 0) \
+ cma__error (cma_s_badparam); \
+ _int_att_ = cma__validate_attr (_att_); \
+ cma__int_lock ((_int_att_)->mutex); \
+ _int_att_->stack_size = cma__roundup_chunksize(_setting_); \
+ cma__free_cache (_int_att_, cma__c_obj_tcb); \
+ _int_att_->cache[cma__c_obj_tcb].revision++; \
+ _int_att_->cache[cma__c_obj_stack].revision++; \
+ cma__int_unlock (_int_att_->mutex); \
+ }
+
+/*
+ * FUNCTIONAL DESCRIPTION:
+ *
+ * cma__int_attr_get_stacksize - Performs work of cma_attr_get_stacksize
+ *
+ * FORMAL PARAMETERS:
+ *
+ * cma_t_attr *_att_ - Attributes object to use
+ * cma_t_natural *_setting_ - Current setting
+ *
+ * IMPLICIT INPUTS:
+ *
+ * none
+ *
+ * IMPLICIT OUTPUTS:
+ *
+ * Attribute objects stack size setting
+ *
+ * FUNCTION VALUE:
+ *
+ * none
+ *
+ * SIDE EFFECTS:
+ *
+ * none
+ */
+#define cma__int_attr_get_stacksize(_att_,_setting_) { \
+ cma__t_int_attr *_int_att_; \
+ (_int_att_) = cma__validate_default_attr (_att_); \
+ cma__int_lock ((_int_att_)->mutex); \
+ (*(_setting_)) = (_int_att_)->stack_size; \
+ cma__int_unlock ((_int_att_)->mutex); \
+ }
+
+
+/*
+ * FUNCTIONAL DESCRIPTION:
+ *
+ * cma__int_attr_set_guardsize - Performs work for cma_attr_set_guardsize
+ *
+ * FORMAL PARAMETERS:
+ *
+ * cma_t_attr *_att_ - Attributes object to use
+ * cma_t_natural _setting_ - Setting
+ *
+ * IMPLICIT INPUTS:
+ *
+ * none
+ *
+ * IMPLICIT OUTPUTS:
+ *
+ * none
+ *
+ * FUNCTION VALUE:
+ *
+ * none
+ *
+ * SIDE EFFECTS:
+ *
+ * Change attribute objects guard size setting
+ */
+#define cma__int_attr_set_guardsize(_att_,_setting_) { \
+ cma__t_int_attr *_int_att_; \
+ _int_att_ = cma__validate_attr (_att_); \
+ cma__int_lock ((_int_att_)->mutex); \
+ _int_att_->guard_size = cma__roundup_chunksize(_setting_); \
+ cma__free_cache (_int_att_, cma__c_obj_tcb); \
+ _int_att_->cache[cma__c_obj_tcb].revision++; \
+ _int_att_->cache[cma__c_obj_stack].revision++; \
+ cma__int_unlock (_int_att_->mutex); \
+ }
+
+/*
+ * FUNCTIONAL DESCRIPTION:
+ *
+ * cma__int_attr_get_guardsize - Performs work of cma_attr_get_guardsize
+ *
+ * FORMAL PARAMETERS:
+ *
+ * cma_t_attr *_att_ - Attributes object to use
+ * cma_t_natural *_setting_ - Current setting
+ *
+ * IMPLICIT INPUTS:
+ *
+ * none
+ *
+ * IMPLICIT OUTPUTS:
+ *
+ * Attribute objects guard size setting
+ *
+ * FUNCTION VALUE:
+ *
+ * none
+ *
+ * SIDE EFFECTS:
+ *
+ * none
+ */
+#define cma__int_attr_get_guardsize(_att_,_setting_) { \
+ cma__t_int_attr *_int_att_; \
+ (_int_att_) = cma__validate_default_attr (_att_); \
+ cma__int_lock ((_int_att_)->mutex); \
+ (*(_setting_)) = (_int_att_)->guard_size; \
+ cma__int_unlock ((_int_att_)->mutex); \
+ }
+
+/*
+ * TYPEDEFS
+ */
+#ifndef __STDC__
+struct CMA__T_INT_MUTEX; /* Avoid circular dependency */
+#endif
+
+typedef struct CMA__T_CACHE {
+ cma_t_natural revision; /* Revisions */
+ cma_t_natural count;
+ cma__t_queue queue; /* Cache headers */
+ } cma__t_cache;
+
+typedef struct CMA__T_INT_ATTR {
+ cma__t_object header; /* Common header */
+ struct CMA__T_INT_ATTR *attributes; /* Point to controlling attr */
+ struct CMA__T_INT_MUTEX *mutex; /* Serialize access to object */
+ cma_t_priority priority; /* Priority of new thread */
+ cma_t_sched_policy policy; /* Sched policy of thread */
+ cma_t_boolean inherit_sched; /* Is scheduling inherited? */
+ cma_t_natural stack_size; /* Size of stack (bytes) */
+ cma_t_natural guard_size; /* Size of guard (bytes) */
+ cma_t_mutex_kind mutex_kind; /* Mutex kind */
+ cma__t_cache cache[cma__c_obj_num]; /* Cache information */
+ cma_t_boolean delete_pending; /* attr. obj. is deleted */
+ cma_t_natural refcnt; /* Number of objects using attr. obj */
+ } cma__t_int_attr;
+
+/*
+ * GLOBAL DATA
+ */
+
+extern cma__t_int_attr cma__g_def_attr;
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+extern void cma__destroy_attributes (cma__t_int_attr *);
+
+extern void cma__free_attributes (cma__t_int_attr *);
+
+extern void cma__free_cache (cma__t_int_attr *,cma_t_natural );
+
+extern cma__t_int_attr *cma__get_attributes (cma__t_int_attr *);
+
+extern void cma__init_attr (void);
+
+extern void cma__reinit_attr (cma_t_integer);
+
+#endif
diff --git a/gdb/osf-share/cma_deb_core.h b/gdb/osf-share/cma_deb_core.h
new file mode 100644
index 00000000000..f0a9c341670
--- /dev/null
+++ b/gdb/osf-share/cma_deb_core.h
@@ -0,0 +1,164 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * This file defines the internal interface to the core of CMA
+ * debugging services. (The client interface to debugging services
+ * is provided by cma_debug_client.h).
+ */
+
+#ifndef CMA_DEB_CORE
+#define CMA_DEB_CORE
+
+/*
+ * INCLUDE FILES
+ */
+#include <cma.h>
+#include <cma_mutex.h>
+#include <cma_queue.h>
+#include <cma_tcb_defs.h>
+#include <cma_util.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+
+/*
+ * TYPEDEFS
+ */
+
+/*FIX-ME* Need to use sizes that are platform specific */
+typedef long int cma___t_debug_ctx[17];
+
+/*
+ * Type defing the format of known object lists
+ */
+typedef struct CMA__T_KNOWN_OBJECT {
+ cma__t_queue queue; /* Queue header for known objects */
+ cma__t_int_mutex *mutex; /* Mutex to control access to queue */
+ } cma__t_known_object;
+
+
+/*
+ * Type defining the registration for one debug client (e.g. Ada)
+ */
+typedef struct CMA__T_DEB_REGISTRY {
+ cma_t_address entry; /* Client's debug entry point */
+ cma_t_key key; /* Client's context key */
+ cma_t_integer fac; /* Client's debug facility number */
+ cma_t_boolean has_prolog; /* Client's TCBs have std prolog */
+ } cma__t_deb_registry;
+
+#define cma__c_deb_max_clients 10
+
+/*
+ * Type defining the global debugging state for all threads.
+ */
+typedef struct CMA__T_DEBUG_STATE {
+ /*
+ * The following flag is set if changes were made while in the
+ * debugger that may make the ready lists inconsistent. For
+ * example, if a thread priority is changed in the debugger, the
+ * thread is not moved between queues. Making things consistent
+ * is deferred to when the dispatcher is next invoked -- which we
+ * try to make very soon.
+ */
+ cma_t_boolean is_inconsistency; /* Ready lists are inconsistent */
+
+
+ cma_t_boolean events_enabled; /* Set if _any_ event is enabled */
+ cma_t_boolean flags[cma__c_debevt__dim];
+ /* Which events are enabled */
+ cma__t_int_tcb *next_to_run; /* TCB of thread to run next */
+
+ cma__t_int_mutex *mutex; /* Mutex for registering clients */
+ cma_t_integer client_count; /* Count of debug clients */
+ cma__t_deb_registry clients[cma__c_deb_max_clients+1];
+ /* Array of current debug clients */
+ } cma__t_debug_state;
+
+
+/*
+ * Routine that will symbolize and address and print it.
+ */
+typedef void (*cma__t_print_symbol) (cma_t_address);
+
+
+/*
+ * GLOBAL DATA
+ */
+
+/*
+ * Variable holding the global debugging state
+ *
+ * (This is primarily written by the debugger interface and read
+ * by the thread dispatcher).
+ */
+extern cma__t_debug_state cma__g_debug_state;
+
+/*
+ * Known object queues
+ */
+extern cma__t_known_object cma__g_known_atts;
+extern cma__t_known_object cma__g_known_cvs;
+extern cma__t_known_object cma__g_known_mutexes;
+extern cma__t_known_object cma__g_known_threads;
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+/* Get information while in debugger context */
+extern void cma__deb_get
+ (cma__t_int_tcb *,cma_t_debug_get,cma_t_address,cma_t_integer,cma_t_integer);
+
+/* Set information while in debugger context */
+extern void cma__deb_set (cma__t_int_tcb *,cma_t_debug_set,cma_t_address,cma_t_integer);
+
+extern void cma__init_debug (void);
+
+extern void cma__reinit_debug (cma_t_integer);
+
+extern void cma__deb_anytcb_to_tcb (cma_t_tcb_header *,cma__t_int_tcb **);
+
+extern void cma__deb_fac_to_client (cma_t_integer,cma_t_key *);
+
+extern void cma__deb_get_client_info (cma_t_key,cma_t_address *,cma_t_boolean *);
+
+extern void cma__deb_get_context (cma__t_int_tcb *,cma_t_key,cma_t_address *);
+
+extern cma__t_int_tcb *cma__deb_get_self_tcb (void);
+
+extern void cma__deb_get_time_slice (cma_t_interval *);
+
+extern cma__t_int_tcb *cma__deb_next_tcb
+ (cma__t_int_tcb *,cma_t_integer *,cma_t_integer *,cma_t_boolean *);
+
+extern cma_t_boolean cma__deb_set_alert (cma__t_int_tcb *);
+
+extern void cma__deb_set_next_thread (cma__t_int_tcb *);
+
+extern void cma__deb_set_force_dispatch (cma_t_address );
+
+extern void cma__deb_set_time_slice (cma_t_interval);
+
+extern void cma__deb_show_thread
+ (cma__t_int_tcb *,cma_t_boolean,cma_t_boolean,cma___t_debug_ctx,cma__t_eol_routine,
+ cma__t_eol_routine,cma__t_print_symbol);
+
+extern void
+cma__deb_show_stats (cma__t_int_tcb *,cma_t_boolean,cma_t_boolean,cma__t_eol_routine,cma__t_eol_routine,cma__t_print_symbol);
+#endif
diff --git a/gdb/osf-share/cma_debug_client.h b/gdb/osf-share/cma_debug_client.h
new file mode 100644
index 00000000000..adb0909ad7d
--- /dev/null
+++ b/gdb/osf-share/cma_debug_client.h
@@ -0,0 +1,195 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * Header file providing access to CMA clients that implement
+ * language run-times to the CMA debugger capabilities.
+ *
+ * NOTE: the clients that are able to use this interface is
+ * very limited because clients needing task debugging must have
+ * support in the system debugger as well as here (at present).
+ * The following are the only legitimate clients of this interface:
+ * ADA runtime, C++ tasking library, and CMA.
+ *
+ *FIX-ME* We shall endeavor to extend these capabilities so that the
+ * all-platform CMA debugger CMA_DEBUG and any client can layer
+ * on thread debugging. But that is still an open design problem.
+ * The design here does not preclude that extension (for example,
+ * the identity of the debug-client is indicated in an "open"
+ * manner by using the CMA context key as the identifier.
+ */
+
+#ifndef CMA_DEBUG_CLIENT
+#define CMA_DEBUG_CLIENT
+
+/*
+ * INCLUDE FILES
+ */
+#include <cma.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+/*
+ * TYPEDEFS
+ */
+
+/*
+ * Type describing constants for a valid TCB sentinel.
+ * Exactly one value is valid, but we provide a symbolic name for
+ * at least one invalid sentinel as a convenience.
+ */
+typedef enum CMA_T_TCB_SENTINEL {
+ cma_c_tcb_sentinel_nogood = 0, /* Invalid sentinel constant */
+ cma_c_tcb_sentinel = 0x0ACEFACE /* Valid TCB sentinel */
+ } cma_t_tcb_sentinel;
+
+/*
+ * Type describing pad fields needed to align the "standard prolog"
+ * to the right byte at the front of each TCB. These fields are
+ * free to be put to any use by the client.
+ *
+ * This is 32 bytes long and is fixed at this size for all clients
+ * and CMA, for all time.
+ */
+typedef struct CMA_T_TCB_PRIVATE {
+ cma_t_integer pad1;
+ cma_t_integer pad2;
+ cma_t_integer pad3;
+ cma_t_integer pad4;
+ cma_t_integer pad5;
+ cma_t_integer pad6;
+ cma_t_integer pad7;
+ cma_t_integer pad8;
+ } cma_t_tcb_private;
+
+/*
+ * Type describing the "standard prolog" that clients should use
+ * within their task control blocks. We assume that the client will
+ * store their "task control block" as a per-thread context under
+ * the context key specified here.
+ */
+typedef struct CMA_T_TCB_PROLOG {
+ cma_t_tcb_sentinel sentinel; /* Validity sentinel */
+ cma_t_thread client_thread; /* Thread corresonding to task */
+ cma_t_key client_key; /* Context key this is stored under */
+ cma_t_address reserved1; /* Must be zero, reserved to CMA */
+ } cma_t_tcb_prolog;
+
+/*
+ * Type defining the layout of all TCBs and TASKS. This format
+ * ensures that tasks will be self-identifying to the debugger.
+ * this layout must never change as the CMA DEBUG Clients cannot
+ * be changed after CMA ships.
+ */
+typedef struct CMA_T_TCB_HEADER {
+ cma_t_tcb_private IGNORED; /* TCB fields private to the client */
+ cma_t_tcb_prolog prolog; /* The standard prolog goes here */
+ } cma_t_tcb_header;
+
+
+/*
+ * Type describing the kinds of information that a CMA debug
+ * client can GET about a thread.
+ */
+typedef enum CMA_T_DEBUG_GET {
+ /*
+ * All of the following items use a buffer whose size is
+ * four bytes. (That is four must be passed as the buffer_size
+ * parameter to cma_debug_get.)
+ */
+ cma_c_debget_guardsize = 1, /* Current guard size (bytes) */
+ cma_c_debget_is_held = 2, /* Is it on hold? */
+ cma_c_debget_is_initial = 3, /* Is it the initial thread? */
+ cma_c_debget_number = 4, /* Thread's number */
+ cma_c_debget_stack_ptr = 5, /* Current stack pointer */
+ cma_c_debget_stack_base = 6, /* Stack base address */
+ cma_c_debget_stack_top = 7, /* Stack top address */
+ cma_c_debget_sched_state = 8, /* Scheduler state
+ * 0 - run
+ * 1 - ready
+ * 2 - blocked
+ * 3 - terminated
+ */
+ cma_c_debget_reserve_size = 9, /* Size of stack reserve (bytes) */
+ cma_c_debget_base_prio = 10, /* Base priority */
+ cma_c_debget_priority = 11, /* Current priority */
+ cma_c_debget_regs = 12, /* Register set (and proc. state) */
+ cma_c_debget_alt_pending = 13, /* Alert is pending */
+ cma_c_debget_alt_a_enable = 14, /* Asynch alert delivery enabled */
+ cma_c_debget_alt_g_enable = 15, /* General alert delivery enabled */
+ cma_c_debget_substate = 16, /* Substate (or wait state) */
+ cma_c_debget_object_addr = 17, /* Address of thread object */
+ cma_c_debget_thkind = 18, /* Kind of thread */
+ cma_c_debget_detached = 19, /* Thread is detached */
+ cma_c_debget_tcb_size = 20, /* TCB size */
+ cma_c_debget_start_pc = 21, /* Start address */
+ cma_c_debget_next_pc = 22, /* Next instruction */
+ cma_c_debget_policy = 23, /* Sched policy */
+ cma_c_debget_stack_yellow = 24, /* Addr of start of guard area */
+ cma_c_debget_stack_default = 25 /* True if on default stack */
+
+ } cma_t_debug_get;
+
+/*
+ * Type describing the kinds of information that a CMA debug
+ * client can SET (or change) about a thread using cma_debug_set.
+ */
+typedef enum CMA_T_DEBUG_SET {
+ /*
+ * All of the following items use a buffer whose size is
+ * four bytes. (That is four must be passed as the buffer_size
+ * parameter to cma_debug_set.)
+ */
+ cma_c_debset_priority = 1, /* Set the priority */
+ cma_c_debset_policy = 2, /* Set the sched policy */
+ cma_c_debset_hold = 3, /* Put thread on hold */
+ cma_c_debset_regs = 4 /* Set the regs and proc. state */
+
+ } cma_t_debug_set;
+
+
+/*
+ * GLOBAL DATA
+ *
+ * none
+ */
+
+/*
+ * EXTERNAL INTERFACES
+ */
+
+/*
+ * Routine to register with the CMA debug dispatcher.
+ */
+extern void cma_debug_register (cma_t_address,cma_t_key,cma_t_integer,cma_t_boolean);
+
+/*
+ * Routine to get get thread state needed by the CMA debug client.
+ */
+extern void cma_debug_get (cma_t_thread *,cma_t_debug_get,cma_t_address,cma_t_integer);
+
+/*
+ * Get thread context given an sp and a key
+ */
+extern void cma_debug_get_sp_context (cma_t_address,cma_t_key,cma_t_address *);
+
+/*
+ * Routine to set thread state as needed by the CMA debug client.
+ */
+extern void cma_debug_set (cma_t_thread *,cma_t_debug_set,cma_t_address,cma_t_integer);
+
+#endif
diff --git a/gdb/osf-share/cma_errors.h b/gdb/osf-share/cma_errors.h
new file mode 100644
index 00000000000..8ac1795745f
--- /dev/null
+++ b/gdb/osf-share/cma_errors.h
@@ -0,0 +1,55 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * This module is the interface between CMA services and
+ * the platform-specific error reporting mechanism.
+ */
+
+#ifndef CMA_ERRORS
+#define CMA_ERRORS
+
+/*
+ * INCLUDE FILES
+ */
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+/*
+ * TYPEDEFS
+ */
+
+/*
+ * GLOBAL DATA
+ */
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+/*
+ * The cma__bugcheck function will print information to stderr (or sys$error
+ * on VMS), and more extensive information to the file cma_dump.log in the
+ * current working directory.
+ */
+extern void cma__bugcheck (char *,...);
+
+extern void cma__error (int);
+
+extern void cma__unimplemented (void);
+
+#endif
diff --git a/gdb/osf-share/cma_handle.h b/gdb/osf-share/cma_handle.h
new file mode 100644
index 00000000000..e63de018a04
--- /dev/null
+++ b/gdb/osf-share/cma_handle.h
@@ -0,0 +1,182 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * Header file for handles
+ */
+
+#ifndef CMA_HANDLE
+#define CMA_HANDLE
+
+/*
+ * INCLUDE FILES
+ */
+
+#include <cma_defs.h>
+#include <cma_attr.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#define cma__validate_attr(handle) \
+ ((cma__t_int_attr *)cma__validate_handle ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_attr))
+
+#define cma__validate_cv(handle) \
+ ((cma__t_int_cv *)cma__validate_handle ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_cv))
+
+#define cma__validate_mutex(handle) \
+ ((cma__t_int_mutex *)cma__validate_handle ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_mutex))
+
+#define cma__validate_tcb(handle) \
+ ((cma__t_int_tcb *)cma__validate_handle ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_tcb))
+
+#define cma__validate_stack(handle) \
+ ((cma__t_int_stack *)cma__validate_handle ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_stack))
+
+#define cma__validate_null_attr(handle) \
+ ((cma__t_int_attr *)cma__validate_handle_null ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_attr))
+
+#define cma__validate_null_cv(handle) \
+ ((cma__t_int_cv *)cma__validate_handle_null ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_cv))
+
+#define cma__validate_null_mutex(handle) \
+ ((cma__t_int_mutex *)cma__validate_handle_null ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_mutex))
+
+#define cma__validate_null_tcb(handle) \
+ ((cma__t_int_tcb *)cma__validate_handle_null ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_tcb))
+
+#define cma__validate_null_stack(handle) \
+ ((cma__t_int_stack *)cma__validate_handle_null ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_stack))
+
+#define cma__val_attr_stat(handle,obj) \
+ cma__val_hand_stat ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_attr, \
+ (cma__t_object **)obj)
+
+#define cma__val_cv_stat(handle,obj) \
+ cma__val_hand_stat ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_cv, \
+ (cma__t_object **)obj)
+
+#define cma__val_mutex_stat(handle,obj) \
+ cma__val_hand_stat ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_mutex, \
+ (cma__t_object **)obj)
+
+#define cma__val_tcb_stat(handle) \
+ cma__val_hand_stat ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_tcb, \
+ (cma__t_object **)obj)
+
+#define cma__val_stack_stat(handle,obj) \
+ cma__val_hand_stat ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_stack, \
+ (cma__t_object **)obj)
+
+#define cma__val_nullattr_stat(handle,obj) \
+ cma__val_handnull_stat ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_attr, \
+ (cma__t_object **)obj)
+
+#define cma__val_nullcv_stat(handle,obj) \
+ cma__val_handnull_stat ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_cv, \
+ (cma__t_object **)obj)
+
+#define cma__val_nullmutex_stat(handle,obj) \
+ cma__val_handnull_stat ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_mutex, \
+ (cma__t_object **)obj)
+
+#define cma__val_nulltcb_stat(handle,obj) \
+ cma__val_handnull_stat ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_tcb, \
+ (cma__t_object **)obj)
+
+#define cma__val_nullstack_stat(handle) \
+ cma__val_handnull_stat ( \
+ (cma_t_handle *)(handle), \
+ cma__c_obj_stack, \
+ (cma__t_object **)obj)
+
+/*
+ * TYPEDEFS
+ */
+
+/*
+ * Internal format of a handle (to the outside world it's an array of two
+ * addresses, but we know better).
+ */
+typedef struct CMA__T_INT_HANDLE {
+ cma__t_object *pointer; /* Address of internal structure */
+ cma__t_short sequence; /* Sequence number of object */
+ cma__t_short type; /* Type code of object */
+ } cma__t_int_handle;
+
+/*
+ * GLOBAL DATA
+ */
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+extern void cma__clear_handle (cma_t_handle *);
+
+extern void cma__object_to_handle (cma__t_object *,cma_t_handle *);
+
+extern cma__t_int_attr * cma__validate_default_attr (cma_t_handle *);
+
+extern cma_t_status cma__val_defattr_stat (cma_t_handle *,cma__t_int_attr **);
+
+extern cma__t_object * cma__validate_handle (cma_t_handle *,cma_t_natural );
+
+extern cma_t_status cma__val_hand_stat (cma_t_handle *,cma_t_natural,cma__t_object **);
+
+extern cma__t_object *cma__validate_handle_null (cma_t_handle *,cma_t_natural);
+
+extern cma_t_status cma__val_handnull_stat (cma_t_handle *,cma_t_natural,cma__t_object **);
+
+#endif
diff --git a/gdb/osf-share/cma_init.h b/gdb/osf-share/cma_init.h
new file mode 100644
index 00000000000..7309736c19c
--- /dev/null
+++ b/gdb/osf-share/cma_init.h
@@ -0,0 +1,114 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * Header file for CMA initialization
+ */
+
+#ifndef CMA_INIT
+#define CMA_INIT
+
+/*
+ * INCLUDE FILES
+ */
+#include <dce/cma_host.h>
+#include <cma_errors.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#define cma__c_env_maxattr 0
+#define cma__c_env_minattr 1
+#define cma__c_env_maxcond 2
+#define cma__c_env_mincond 3
+#define cma__c_env_maxmutex 4
+#define cma__c_env_minmutex 5
+#define cma__c_env_maxthread 6
+#define cma__c_env_minthread 7
+#define cma__c_env_maxcluster 8
+#define cma__c_env_mincluster 9
+#define cma__c_env_maxvp 10
+#define cma__c_env_multiplex 11
+#define cma__c_env_trace 12
+#define cma__c_env_trace_file 13
+
+#define cma__c_env_count 13
+
+
+/*
+ * cma__int_init
+ *
+ * Initialize the main body of CMA exactly once.
+ *
+ * We raise an exception if, for some odd reason, there are already threads
+ * in the environment (e.g. kernel threads), and one of them is trying to
+ * initialize CMA before the first thread got all the way through the actual
+ * initialization. This code maintains the invariants: "after successfully
+ * calling CMA_INIT, you can call any CMA function", and "CMA is actually
+ * initialized at most once".
+ */
+/*#ifndef _HP_LIBC_R */
+
+#if defined _HP_LIBC_R ||(defined(SNI_SVR4) && !defined(CMA_INIT_NEEDED))
+# define cma__int_init()
+#else
+# define cma__int_init() { \
+ if (!cma__tac_isset(&cma__g_init_started)) { \
+ if (!cma__test_and_set (&cma__g_init_started)) { \
+ cma__init_static (); \
+ cma__test_and_set (&cma__g_init_done); \
+ } \
+ else if (!cma__tac_isset (&cma__g_init_done)) { \
+ cma__error (cma_s_inialrpro); \
+ }}}
+#endif
+
+/*
+ * TYPEDEFS
+ */
+
+typedef enum CMA__T_ENV_TYPE {
+ cma__c_env_type_int,
+ cma__c_env_type_file
+ } cma__t_env_type;
+
+typedef struct CMA__T_ENV {
+ char *name; /* Name of environment variable */
+ cma__t_env_type type; /* Type of variable */
+ cma_t_integer value; /* Numeric value of the variable */
+ } cma__t_env;
+
+/*
+ * GLOBAL DATA
+ */
+
+extern cma__t_env cma__g_env[cma__c_env_count];
+extern cma__t_atomic_bit cma__g_init_started;
+extern cma__t_atomic_bit cma__g_init_done;
+extern char *cma__g_version;
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+extern void
+cma__init_static (void); /* Initialize static data */
+
+#if _CMA_OS_ != _CMA__VMS
+extern void cma__init_atfork (void);
+#endif
+
+#endif
diff --git a/gdb/osf-share/cma_list.h b/gdb/osf-share/cma_list.h
new file mode 100644
index 00000000000..463fa49870f
--- /dev/null
+++ b/gdb/osf-share/cma_list.h
@@ -0,0 +1,84 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * Header file for generic list functions operating on singly linked
+ * null-terminated lists. Items may not be REMOVED from the list! The
+ * intent is that the list can be traversed (for read-only operations)
+ * without locking, since insertion is "safe" (though not truely
+ * atomic). THIS ASSUMES THAT THE HARDWARE MAKES WRITES VISIBLE TO READS
+ * IN THE ORDER IN WHICH THEY OCCURRED! WITHOUT SUCH READ/WRITE
+ * ORDERING, IT MAY BE NECESSARY TO INSERT "BARRIERS" TO PRODUCE THE
+ * REQUIRED VISIBILITY!
+ */
+
+#ifndef CMA_LIST
+#define CMA_LIST
+
+/*
+ * INCLUDE FILES
+ */
+
+#include <cma.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#define cma__c_null_list ((cma__t_list *)cma_c_null_ptr)
+
+/*
+ * Test whether a list is empty. Return cma_c_true if so, else
+ * cma_c_false.
+ */
+#define cma__list_empty(head) ((head)->link == cma__c_null_list)
+
+/*
+ * Initialize a queue header to empty.
+ */
+#define cma__list_init(head) (void)((head)->link = cma__c_null_list)
+
+/*
+ * Insert an element in a list following the specified item (or at the
+ * beginning of the list if "list" is the list head). NOTE: insertion
+ * operations should be interlocked by the caller!
+ */
+#define cma__list_insert(element,list) (void)( \
+ (element)->link = (list)->link, \
+ (list)->link = (element))
+
+/*
+ * Return the next item in a list (or the first, if the address is of the
+ * list header)
+ */
+#define cma__list_next(element) ((element)->link)
+
+/*
+ * TYPEDEFS
+ */
+
+typedef struct CMA__T_LIST {
+ struct CMA__T_LIST *link; /* Forward link */
+ } cma__t_list;
+
+/*
+ * GLOBAL DATA
+ */
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+#endif
diff --git a/gdb/osf-share/cma_mutex.h b/gdb/osf-share/cma_mutex.h
new file mode 100644
index 00000000000..c178630dc84
--- /dev/null
+++ b/gdb/osf-share/cma_mutex.h
@@ -0,0 +1,230 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * Header file for mutex operations
+ */
+
+#ifndef CMA_MUTEX
+#define CMA_MUTEX
+
+/*
+ * INCLUDE FILES
+ */
+
+#include <cma.h>
+#include <cma_attr.h>
+#include <cma_defs.h>
+#include <cma_semaphore_defs.h>
+#include <cma_sequence.h>
+#include <cma_tcb_defs.h>
+#include <cma_stack.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+/*
+ * TYPEDEFS
+ */
+
+typedef struct CMA__T_INT_MUTEX {
+ cma__t_object header; /* Common header (sequence, type) */
+ cma__t_int_attr *attributes; /* Back link */
+ cma__t_int_tcb *owner; /* Current owner (if any) */
+ cma_t_integer nest_count; /* Nesting level for recursive mutex */
+ cma__t_atomic_bit *unlock; /* Pointer used for unlock operation */
+ cma__t_atomic_bit lock; /* Set if currently locked */
+ struct CMA__T_INT_MUTEX *int_lock; /* Internal protection for mutex */
+ cma__t_atomic_bit event; /* Clear when unlock requires action */
+ cma__t_atomic_bit waiters; /* Clear when threads are waiting */
+ cma__t_atomic_bit bitbucket; /* Fake bit to keep friendlies locked */
+ cma_t_mutex_kind mutex_kind; /* Kind of mutex */
+ cma__t_semaphore semaphore; /* Semaphore for low-level wait */
+ } cma__t_int_mutex;
+
+
+/*
+ * FUNCTIONAL DESCRIPTION:
+ *
+ * Lock a mutex (internal)
+ *
+ * FORMAL PARAMETERS:
+ *
+ * mutex Pointer to mutex object to lock
+ *
+ * IMPLICIT INPUTS:
+ *
+ * none
+ *
+ * IMPLICIT OUTPUTS:
+ *
+ * none
+ *
+ * FUNCTION VALUE:
+ *
+ * none
+ *
+ * SIDE EFFECTS:
+ *
+ * none
+ */
+#ifdef NDEBUG
+# define cma__int_lock(mutex) { \
+ if (cma__test_and_set (&((cma__t_int_mutex *)mutex)->lock)) { \
+ cma_t_status res;\
+ res = cma__int_mutex_block ((cma__t_int_mutex *)mutex); \
+ if (res != cma_s_normal) cma__error (res); \
+ } \
+ }
+#else
+# define cma__int_lock(mutex) { \
+ cma__t_int_tcb *__ltcb__; \
+ __ltcb__ = cma__get_self_tcb (); \
+ if (cma__test_and_set (&((cma__t_int_mutex *)mutex)->lock)) { \
+ cma_t_status res;\
+ res = cma__int_mutex_block ((cma__t_int_mutex *)mutex); \
+ if (res != cma_s_normal) cma__error (res); \
+ } \
+ ((cma__t_int_mutex *)mutex)->owner = __ltcb__; \
+ }
+#endif
+
+/*
+ * FUNCTIONAL DESCRIPTION:
+ *
+ * Unlock a mutex (internal)
+ *
+ * FORMAL PARAMETERS:
+ *
+ * mutex Pointer to mutex object to unlock
+ *
+ * IMPLICIT INPUTS:
+ *
+ * none
+ *
+ * IMPLICIT OUTPUTS:
+ *
+ * none
+ *
+ * FUNCTION VALUE:
+ *
+ * none
+ *
+ * SIDE EFFECTS:
+ *
+ * none
+ */
+#ifdef NDEBUG
+# define cma__int_unlock(mutex) { \
+ cma__unset (((cma__t_int_mutex *)mutex)->unlock); \
+ if (!cma__test_and_set (&((cma__t_int_mutex *)mutex)->event)) { \
+ cma_t_status res;\
+ res = cma__int_mutex_unblock ((cma__t_int_mutex *)mutex); \
+ if (res != cma_s_normal) cma__error (res); \
+ } \
+ }
+#else
+# define cma__int_unlock(mutex) { \
+ cma__t_int_tcb *__utcb__; \
+ __utcb__ = cma__get_self_tcb (); \
+ if (((cma__t_int_mutex *)mutex)->mutex_kind == cma_c_mutex_fast) { \
+ cma__assert_warn ( \
+ (__utcb__ == ((cma__t_int_mutex *)mutex)->owner), \
+ "attempt to release mutx owned by another thread"); \
+ ((cma__t_int_mutex *)mutex)->owner = (cma__t_int_tcb *)cma_c_null_ptr; \
+ } \
+ cma__unset (((cma__t_int_mutex *)mutex)->unlock); \
+ if (!cma__test_and_set (&((cma__t_int_mutex *)mutex)->event)) { \
+ cma_t_status res;\
+ res = cma__int_mutex_unblock ((cma__t_int_mutex *)mutex); \
+ if (res != cma_s_normal) cma__error (res); \
+ } \
+ }
+#endif
+
+/*
+ * FUNCTIONAL DESCRIPTION:
+ *
+ * cma__int_mutex_delete - Performs work for cma_mutex_delete
+ *
+ * FORMAL PARAMETERS:
+ *
+ * cma__t_mutex _mutex_ - Mutex to be deleted
+ *
+ * IMPLICIT INPUTS:
+ *
+ * none
+ *
+ * IMPLICIT OUTPUTS:
+ *
+ * none
+ *
+ * FUNCTION VALUE:
+ *
+ * none
+ *
+ * SIDE EFFECTS:
+ *
+ * none
+ */
+#define cma__int_mutex_delete(_mutex_) { \
+ cma__t_int_mutex *_int_mutex_; \
+ _int_mutex_ = cma__validate_null_mutex (_mutex_); \
+ if (_int_mutex_ == (cma__t_int_mutex *)cma_c_null_ptr) \
+ return; \
+ if (cma__int_mutex_locked (_int_mutex_)) \
+ cma__error (cma_s_in_use); \
+ cma__free_mutex (_int_mutex_); \
+ cma__clear_handle (_mutex_); \
+ }
+
+
+/*
+ * GLOBAL DATA
+ */
+
+extern cma__t_sequence cma__g_mutex_seq;
+extern cma__t_int_mutex *cma__g_global_lock;
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+extern void cma__destroy_mutex (cma__t_int_mutex *);
+
+extern void cma__free_mutex (cma__t_int_mutex *);
+
+extern void cma__free_mutex_nolock (cma__t_int_mutex *);
+
+extern cma__t_int_mutex * cma__get_first_mutex (cma__t_int_attr *);
+
+extern cma__t_int_mutex * cma__get_mutex (cma__t_int_attr *);
+
+extern void cma__init_mutex (void);
+
+extern cma_t_status cma__int_mutex_block (cma__t_int_mutex *);
+
+extern cma_t_boolean cma__int_mutex_locked (cma__t_int_mutex *);
+
+extern cma_t_boolean cma__int_try_lock (cma__t_int_mutex *);
+
+extern cma_t_status cma__int_mutex_unblock (cma__t_int_mutex *);
+
+extern cma_t_boolean cma__mutex_locked (cma_t_mutex);
+
+extern void cma__reinit_mutex (cma_t_integer);
+
+#endif
diff --git a/gdb/osf-share/cma_sched.h b/gdb/osf-share/cma_sched.h
new file mode 100644
index 00000000000..6eb78743baf
--- /dev/null
+++ b/gdb/osf-share/cma_sched.h
@@ -0,0 +1,279 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * Header file for priority scheduling
+ */
+
+
+#ifndef CMA_SCHED
+#define CMA_SCHED
+
+/*
+ * INCLUDE FILES
+ */
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+/*
+ * Scaling factor for integer priority calculations
+ */
+#define cma__c_prio_scale 8
+
+#if _CMA_VENDOR_ == _CMA__APOLLO
+/*
+ * FIX-ME: Apollo cc 6.8 blows contant folded "<<" and ">>"
+ */
+# define cma__scale_up(exp) ((exp) * 256)
+# define cma__scale_dn(exp) ((exp) / 256)
+#else
+# define cma__scale_up(exp) ((exp) << cma__c_prio_scale)
+# define cma__scale_dn(exp) ((exp) >> cma__c_prio_scale)
+#endif
+
+
+/*
+ * Min. num. of ticks between self-adjustments for priority adjusting policies.
+ */
+#define cma__c_prio_interval 10
+
+
+/*
+ * Number of queues in each class of queues
+ */
+#define cma__c_prio_n_id 1 /* Very-low-priority class threads */
+#define cma__c_prio_n_bg 8 /* Background class threads */
+#define cma__c_prio_n_0 1 /* Very low priority throughput quartile */
+#define cma__c_prio_n_1 2 /* Low priority throughput quartile */
+#define cma__c_prio_n_2 3 /* Medium priority throughput quartile */
+#define cma__c_prio_n_3 4 /* High priority throughput quartile */
+#define cma__c_prio_n_rt 1 /* Real Time priority queues */
+
+/*
+ * Number of queues to skip (offset) to get to the queues in this section of LA
+ */
+#define cma__c_prio_o_id 0
+#define cma__c_prio_o_bg cma__c_prio_o_id + cma__c_prio_n_id
+#define cma__c_prio_o_0 cma__c_prio_o_bg + cma__c_prio_n_bg
+#define cma__c_prio_o_1 cma__c_prio_o_0 + cma__c_prio_n_0
+#define cma__c_prio_o_2 cma__c_prio_o_1 + cma__c_prio_n_1
+#define cma__c_prio_o_3 cma__c_prio_o_2 + cma__c_prio_n_2
+#define cma__c_prio_o_rt cma__c_prio_o_3 + cma__c_prio_n_3
+
+/*
+ * Ada_low: These threads are queued in the background queues, thus there
+ * must be enough queues to allow one queue for each Ada priority below the
+ * Ada default.
+ */
+#define cma__c_prio_o_al cma__c_prio_o_bg
+
+/*
+ * Total number of ready queues, for declaration purposes
+ */
+#define cma__c_prio_n_tot \
+ cma__c_prio_n_id + cma__c_prio_n_bg + cma__c_prio_n_rt \
+ + cma__c_prio_n_0 + cma__c_prio_n_1 + cma__c_prio_n_2 + cma__c_prio_n_3
+
+/*
+ * Formulae for determining a thread's priority. Variable priorities (such
+ * as foreground and background) are scaled values.
+ */
+#define cma__sched_priority(tcb) \
+ ((tcb)->sched.class == cma__c_class_fore ? cma__sched_prio_fore (tcb) \
+ :((tcb)->sched.class == cma__c_class_back ? cma__sched_prio_back (tcb) \
+ :((tcb)->sched.class == cma__c_class_rt ? cma__sched_prio_rt (tcb) \
+ :((tcb)->sched.class == cma__c_class_idle ? cma__sched_prio_idle (tcb) \
+ :(cma__bugcheck ("cma__sched_priority: unrecognized class"), 0) ))))
+
+#define cma__sched_prio_fore(tcb) cma__sched_prio_fore_var (tcb)
+#define cma__sched_prio_back(tcb) ((tcb)->sched.fixed_prio \
+ ? cma__sched_prio_back_fix (tcb) : cma__sched_prio_back_var (tcb) )
+#define cma__sched_prio_rt(tcb) ((tcb)->sched.priority)
+#define cma__sched_prio_idle(tcb) ((tcb)->sched.priority)
+
+#define cma__sched_prio_back_fix(tcb) \
+ (cma__g_prio_bg_min + (cma__g_prio_bg_max - cma__g_prio_bg_min) \
+ * ((tcb)->sched.priority + cma__c_prio_o_al - cma__c_prio_o_bg) \
+ / cma__c_prio_n_bg)
+
+/*
+ * FIX-ME: Enable after modeling (if we like it)
+ */
+#if 1
+# define cma__sched_prio_fore_var(tcb) \
+ ((cma__g_prio_fg_max + cma__g_prio_fg_min)/2)
+# define cma__sched_prio_back_var(tcb) \
+ ((cma__g_prio_bg_max + cma__g_prio_bg_min)/2)
+#else
+# define cma__sched_prio_back_var(tcb) cma__sched_prio_fore_var (tcb)
+
+# if 1
+/*
+ * Re-scale, since the division removes the scale factor.
+ * Scale and multiply before dividing to avoid loss of precision.
+ */
+# define cma__sched_prio_fore_var(tcb) \
+ ((cma__g_vp_count * cma__scale_up((tcb)->sched.tot_time)) \
+ / (tcb)->sched.cpu_time)
+# else
+/*
+ * Re-scale, since the division removes the scale factor.
+ * Scale and multiply before dividing to avoid loss of precision.
+ * Left shift the numerator to multiply by two.
+ */
+# define cma__sched_prio_fore_var(tcb) \
+ (((cma__g_vp_count * cma__scale_up((tcb)->sched.tot_time) \
+ * (tcb)->sched.priority * cma__g_init_frac_sum) << 1) \
+ / ((tcb)->sched.cpu_time * (tcb)->sched.priority * cma__g_init_frac_sum \
+ + (tcb)->sched.tot_time))
+# endif
+#endif
+
+/*
+ * Update weighted-averaged, scaled tick counters
+ */
+#define cma__sched_update_time(ave, new) \
+ (ave) = (ave) - ((cma__scale_dn((ave)) - (new)) << (cma__c_prio_scale - 4))
+
+#define cma__sched_parameterize(tcb, policy) { \
+ switch (policy) { \
+ case cma_c_sched_fifo : { \
+ (tcb)->sched.rtb = cma_c_true; \
+ (tcb)->sched.spp = cma_c_true; \
+ (tcb)->sched.fixed_prio = cma_c_true; \
+ (tcb)->sched.class = cma__c_class_rt; \
+ break; \
+ } \
+ case cma_c_sched_rr : { \
+ (tcb)->sched.rtb = cma_c_false; \
+ (tcb)->sched.spp = cma_c_true; \
+ (tcb)->sched.fixed_prio = cma_c_true; \
+ (tcb)->sched.class = cma__c_class_rt; \
+ break; \
+ } \
+ case cma_c_sched_throughput : { \
+ (tcb)->sched.rtb = cma_c_false; \
+ (tcb)->sched.spp = cma_c_false; \
+ (tcb)->sched.fixed_prio = cma_c_false; \
+ (tcb)->sched.class = cma__c_class_fore; \
+ break; \
+ } \
+ case cma_c_sched_background : { \
+ (tcb)->sched.rtb = cma_c_false; \
+ (tcb)->sched.spp = cma_c_false; \
+ (tcb)->sched.fixed_prio = cma_c_false; \
+ (tcb)->sched.class = cma__c_class_back; \
+ break; \
+ } \
+ case cma_c_sched_ada_low : { \
+ (tcb)->sched.rtb = cma_c_false; \
+ (tcb)->sched.spp = cma_c_true; \
+ (tcb)->sched.fixed_prio = cma_c_true; \
+ (tcb)->sched.class = cma__c_class_back; \
+ break; \
+ } \
+ case cma_c_sched_idle : { \
+ (tcb)->sched.rtb = cma_c_false; \
+ (tcb)->sched.spp = cma_c_false; \
+ (tcb)->sched.fixed_prio = cma_c_false; \
+ (tcb)->sched.class = cma__c_class_idle; \
+ break; \
+ } \
+ default : { \
+ cma__bugcheck ("cma__sched_parameterize: bad scheduling Policy"); \
+ break; \
+ } \
+ } \
+ }
+
+/*
+ * TYPEDEFS
+ */
+
+/*
+ * Scheduling classes
+ */
+typedef enum CMA__T_SCHED_CLASS {
+ cma__c_class_rt,
+ cma__c_class_fore,
+ cma__c_class_back,
+ cma__c_class_idle
+ } cma__t_sched_class;
+
+/*
+ * GLOBAL DATA
+ */
+
+/*
+ * Minimuma and maximum prioirities, for foreground and background threads,
+ * as of the last time the scheduler ran. (Scaled once.)
+ */
+extern cma_t_integer cma__g_prio_fg_min;
+extern cma_t_integer cma__g_prio_fg_max;
+extern cma_t_integer cma__g_prio_bg_min;
+extern cma_t_integer cma__g_prio_bg_max;
+
+/*
+ * The "m" values are the slopes of the four sections of linear approximation.
+ *
+ * cma__g_prio_m_I = 4*N(I)/cma__g_prio_range (Scaled once.)
+ */
+extern cma_t_integer cma__g_prio_m_0,
+ cma__g_prio_m_1,
+ cma__g_prio_m_2,
+ cma__g_prio_m_3;
+
+/*
+ * The "b" values are the intercepts of the four sections of linear approx.
+ * (Not scaled.)
+ *
+ * cma__g_prio_b_I = -N(I)*(I*prio_max + (4-I)*prio_min)/prio_range + prio_o_I
+ */
+extern cma_t_integer cma__g_prio_b_0,
+ cma__g_prio_b_1,
+ cma__g_prio_b_2,
+ cma__g_prio_b_3;
+
+/*
+ * The "p" values are the end points of the four sections of linear approx.
+ *
+ * cma__g_prio_p_I = cma__g_prio_fg_min + (I/4)*cma__g_prio_range
+ *
+ * [cma__g_prio_p_0 is not defined since it is not used (also, it is the same
+ * as cma__g_prio_fg_min).] (Scaled once.)
+ */
+extern cma_t_integer cma__g_prio_p_1,
+ cma__g_prio_p_2,
+ cma__g_prio_p_3;
+
+/*
+ * Points to the next queue for the dispatcher to check for ready threads.
+ */
+extern cma_t_integer cma__g_next_ready_queue;
+
+/*
+ * Points to the queues of virtual processors (for preempt victim search)
+ */
+extern cma__t_queue cma__g_run_vps;
+extern cma__t_queue cma__g_susp_vps;
+extern cma_t_integer cma__g_vp_count;
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+#endif
diff --git a/gdb/osf-share/cma_semaphore_defs.h b/gdb/osf-share/cma_semaphore_defs.h
new file mode 100644
index 00000000000..e160de33944
--- /dev/null
+++ b/gdb/osf-share/cma_semaphore_defs.h
@@ -0,0 +1,46 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * Header file for semaphore structure definition.
+ */
+#ifndef CMA_SEMAPHORE_DEFS
+#define CMA_SEMAPHORE_DEFS
+
+/*
+ * INCLUDE FILES
+ */
+#include <cma.h>
+#include <cma_queue.h>
+#include <cma_defs.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#define cma__c_semaphore_timeout 1
+#define cma__c_semaphore_event 0
+#define cma__c_select_timeout 2
+
+/*
+ * TYPEDEFS
+ */
+
+typedef struct CMA__T_SEMAPHORE {
+ cma__t_queue queue;
+ cma__t_atomic_bit nopending;
+ } cma__t_semaphore;
+
+#endif
diff --git a/gdb/osf-share/cma_sequence.h b/gdb/osf-share/cma_sequence.h
new file mode 100644
index 00000000000..8d362ed8d87
--- /dev/null
+++ b/gdb/osf-share/cma_sequence.h
@@ -0,0 +1,56 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * Header file for sequence generator functions
+ */
+
+#ifndef CMA_SEQUENCE
+#define CMA_SEQUENCE
+
+/*
+ * INCLUDE FILES
+ */
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+/*
+ * TYPEDEFS
+ */
+
+#ifndef __STDC__
+struct CMA__T_INT_MUTEX;
+#endif
+
+typedef struct CMA__T_SEQUENCE {
+ struct CMA__T_INT_MUTEX *mutex; /* Serialize access to counter */
+ cma_t_natural seq; /* Sequence number for object */
+ } cma__t_sequence;
+
+/*
+ * GLOBAL DATA
+ */
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+extern cma_t_natural cma__assign_sequence (cma__t_sequence *);
+
+extern void cma__init_sequence (cma__t_sequence *);
+
+#endif
diff --git a/gdb/osf-share/cma_stack.h b/gdb/osf-share/cma_stack.h
new file mode 100644
index 00000000000..97a41fd6e95
--- /dev/null
+++ b/gdb/osf-share/cma_stack.h
@@ -0,0 +1,83 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * Header file for stack management
+ */
+#ifndef CMA_STACK
+#define CMA_STACK
+
+/*
+ * INCLUDE FILES
+ */
+
+#include <cma_tcb_defs.h>
+#include <cma.h>
+#include <cma_attr.h>
+#include <cma_queue.h>
+#include <cma_stack_int.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#if _CMA_UNIPROCESSOR_
+# define cma__get_self_tcb() (cma__g_current_thread)
+#endif
+
+/*
+ * Round the given value (a) upto cma__g_chunk_size
+ */
+#define cma__roundup_chunksize(a) (cma__roundup(a,cma__g_chunk_size))
+
+/*
+ * TYPEDEFS
+ */
+
+/*
+ * GLOBAL DATA
+ */
+
+extern cma__t_list cma__g_stack_clusters;
+extern cma__t_int_tcb *cma__g_current_thread;
+extern cma_t_integer cma__g_chunk_size;
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+extern void cma__assign_stack (cma__t_int_stack *,cma__t_int_tcb *);
+
+extern void cma__free_stack (cma__t_int_stack *);
+
+extern void cma__free_stack_list (cma__t_queue *);
+
+#if !_CMA_UNIPROCESSOR_
+extern cma__t_int_tcb * cma__get_self_tcb (void);
+#endif
+
+extern cma__t_int_tcb * cma__get_sp_tcb (cma_t_address);
+
+extern cma__t_int_stack * cma__get_stack (cma__t_int_attr *);
+
+extern void cma__init_stack (void);
+
+extern void cma__reinit_stack (cma_t_integer);
+
+#if _CMA_PROTECT_MEMORY_
+extern void cma__remap_stack_holes (void);
+#endif
+
+#endif
diff --git a/gdb/osf-share/cma_stack_int.h b/gdb/osf-share/cma_stack_int.h
new file mode 100644
index 00000000000..bf76f60756e
--- /dev/null
+++ b/gdb/osf-share/cma_stack_int.h
@@ -0,0 +1,136 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * Header file for stack management (internal to cma_stack.c, but
+ * separate for convenience, and unit testing).
+ */
+
+#ifndef CMA_STACK_INT
+#define CMA_STACK_INT
+
+/*
+ * INCLUDE FILES
+ */
+
+#include <cma.h>
+#include <cma_queue.h>
+#include <cma_list.h>
+#include <cma_tcb_defs.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#define cma___c_first_free_chunk 0
+#define cma___c_min_count 2 /* Smallest number of chunks to leave */
+#define cma___c_end (-1) /* End of free list (flag) */
+#define cma__c_yellow_size 0
+
+/*
+ * Cluster types
+ */
+#define cma___c_cluster 0 /* Default cluster */
+#define cma___c_bigstack 1 /* Looks like a cluster, but it's a stack */
+
+
+#define cma___c_null_cluster (cma___t_cluster *)cma_c_null_ptr
+
+
+/*
+ * TYPEDEFS
+ */
+
+#ifndef __STDC__
+struct CMA__T_INT_STACK;
+#endif
+
+typedef cma_t_natural cma___t_index; /* Type for chunk index */
+
+typedef struct CMA___T_CLU_DESC {
+ cma__t_list list; /* Queue element for cluster list */
+ cma_t_integer type; /* Type of cluster */
+ cma_t_address stacks;
+ cma_t_address limit;
+ } cma___t_clu_desc;
+
+typedef union CMA___T_MAP_ENTRY {
+ struct {
+ cma__t_int_tcb *tcb; /* TCB associated with stack chunk */
+ struct CMA__T_INT_STACK *stack; /* Stack desc. ass. with stack chunk */
+ } mapped;
+ struct {
+ cma___t_index size; /* Number of chunks in block */
+ cma___t_index next; /* Next free block */
+ } free;
+ } cma___t_map_entry;
+
+/*
+ * NOTE: It is VERY IMPORTANT that both cma___t_cluster and cma___t_bigstack
+ * begin with the cma___t_clu_desc structure, as there is some code in the
+ * stack manager that relies on being able to treat both as equivalent!
+ */
+typedef struct CMA___T_CLUSTER {
+ cma___t_clu_desc desc; /* Describe this cluster */
+ cma___t_map_entry map[cma__c_chunk_count]; /* thread map */
+ cma___t_index free; /* First free chunk index */
+ } cma___t_cluster;
+
+/*
+ * NOTE: It is VERY IMPORTANT that both cma___t_cluster and cma___t_bigstack
+ * begin with the cma___t_clu_desc structure, as there is some code in the
+ * stack manager that relies on being able to treat both as equivalent!
+ */
+typedef struct CMA___T_BIGSTACK {
+ cma___t_clu_desc desc; /* Describe this cluster */
+ cma__t_int_tcb *tcb; /* TCB associated with stack */
+ struct CMA__T_INT_STACK *stack; /* Stack desc. ass. with stack */
+ cma_t_natural size; /* Size of big stack */
+ cma_t_boolean in_use; /* Set if allocated */
+ } cma___t_bigstack;
+
+#if _CMA_PROTECT_MEMORY_
+typedef struct CMA___T_INT_HOLE {
+ cma__t_queue link; /* Link holes together */
+ cma_t_boolean protected; /* Set when pages are protected */
+ cma_t_address first; /* First protected byte */
+ cma_t_address last; /* Last protected byte */
+ } cma___t_int_hole;
+#endif
+
+typedef struct CMA__T_INT_STACK {
+ cma__t_object header; /* Common header (sequence, type info */
+ cma__t_int_attr *attributes; /* Backpointer to attr obj */
+ cma___t_cluster *cluster; /* Stack's cluster */
+ cma_t_address stack_base; /* base address of stack */
+ cma_t_address yellow_zone; /* first address of yellow zone */
+ cma_t_address last_guard; /* last address of guard pages */
+ cma_t_natural first_chunk; /* First chunk allocated */
+ cma_t_natural chunk_count; /* Count of chunks allocated */
+ cma__t_int_tcb *tcb; /* TCB backpointer */
+#if _CMA_PROTECT_MEMORY_
+ cma___t_int_hole hole; /* Description of hole */
+#endif
+ } cma__t_int_stack;
+
+/*
+ * GLOBAL DATA
+ */
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+#endif
diff --git a/gdb/osf-share/cma_tcb_defs.h b/gdb/osf-share/cma_tcb_defs.h
new file mode 100644
index 00000000000..6622050cf73
--- /dev/null
+++ b/gdb/osf-share/cma_tcb_defs.h
@@ -0,0 +1,269 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * TCB-related type definitions.
+ */
+
+#ifndef CMA_TCB_DEFS
+#define CMA_TCB_DEFS
+
+/*
+ * INCLUDE FILES
+ */
+# if !_CMA_THREAD_SYNC_IO_
+# include <cma_thread_io.h>
+# endif
+#include <cma.h>
+#include <cma_debug_client.h>
+#include <cma_attr.h>
+#include <cma_defs.h>
+#include <cma_handle.h>
+#include <cma_queue.h>
+#if _CMA_OS_ == _CMA__UNIX
+# if defined(SNI_DCOSX)
+# include <sys/ucontext.h>
+# endif
+# include <signal.h>
+#endif
+#include <cma_sched.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#if _CMA_PLATFORM_ == _CMA__IBMR2_UNIX
+# define cma__c_ibmr2_ctx_stack_size 2048
+# define cma__c_ibmr2_ctx_stack_top (cma__c_ibmr2_ctx_stack_size - 1)
+#endif
+
+/*
+ * TYPEDEFS
+ */
+
+#ifndef __STDC__
+# if _CMA_HARDWARE_ != _CMA__HPPA
+struct CMA__T_SEMAPHORE;
+# endif
+struct CMA__T_INT_CV;
+struct CMA__T_INT_MUTEX;
+struct CMA__T_INT_TCB;
+#endif
+
+typedef cma_t_address *cma__t_context_list;
+
+typedef struct CMA__T_TCB_PAD {
+ /*
+ * Adjust to align the tcb prolog at byte 32.
+ * 12 bytes are required as object header is currently
+ * 20 bytes long.
+ */
+ cma_t_integer pad1; /* pad bytes */
+ cma_t_integer pad2; /* pad bytes */
+ cma_t_integer pad3; /* pad bytes */
+ } cma__t_tcb_pad;
+
+#if (_CMA_OS_ == _CMA__UNIX) && !_CMA_THREAD_SYNC_IO_
+typedef struct CMA__T_TCB_SELECT {
+ cma__t_queue queue;
+#if (_CMA_UNIX_TYPE != _CMA__SVR4)
+ cma__t_file_mask *rfds;
+ cma__t_file_mask *wfds;
+ cma__t_file_mask *efds;
+#else
+ cma__t_poll_info poll_info;
+#endif /* (_CMA_UNIX_TYPE != _CMA__SVR4) */
+ cma_t_integer nfound;
+ } cma__t_tcb_select;
+#endif
+
+typedef struct CMA__T_TCB_TIME {
+ cma__t_queue queue; /* must be first entry! */
+ cma_t_integer mode;
+ struct CMA__T_SEMAPHORE *semaphore; /* used for timed semaphores */
+ cma_t_date_time wakeup_time;
+ cma_t_integer quanta_remaining;
+ } cma__t_tcb_time;
+
+typedef enum CMA__T_DEBEVT {
+ cma__c_debevt_activating = 1, /* First transition to running */
+ cma__c_debevt_running = 2, /* Any transition to running */
+ cma__c_debevt_preempting = 3, /* Preemted (replaced) another thread */
+ cma__c_debevt_blocking = 4, /* Any transition to blocked */
+ cma__c_debevt_terminating = 5, /* Final state transition */
+ cma__c_debevt_term_alert = 6, /* Terminated due to alert/cancel */
+ cma__c_debevt_term_exc = 7, /* Terminated due to exception */
+ cma__c_debevt_exc_handled = 8 /* Exception is being handled */
+ } cma__t_debevt;
+
+#define cma__c_debevt__first ((cma_t_integer)cma__c_debevt_activating)
+#define cma__c_debevt__last ((cma_t_integer)cma__c_debevt_exc_handled)
+#define cma__c_debevt__dim (cma__c_debevt__last + 1)
+
+/*
+ * Type defining thread substate, which is used by the debugger.
+ * If the state is blocked, substate indicates WHY the thread is blocked.
+ */
+typedef enum CMA__T_SUBSTATE {
+ cma__c_substa_normal = 0,
+ cma__c_substa_mutex = 1,
+ cma__c_substa_cv = 2,
+ cma__c_substa_timed_cv = 3,
+ cma__c_substa_term_alt = 4,
+ cma__c_substa_term_exc = 5,
+ cma__c_substa_delay =6,
+ cma__c_substa_not_yet_run = 7
+ } cma__t_substate;
+#define cma__c_substa__first ((cma_t_integer)cma__c_substa_normal)
+#define cma__c_substa__last ((cma_t_integer)cma__c_substa_not_yet_run)
+#define cma__c_substa__dim (cma__c_substa__last + 1)
+
+
+/*
+ * Per-thread state for the debugger
+ */
+typedef struct CMA__T_TCB_DEBUG {
+ cma_t_boolean on_hold; /* Thread was put on hold by debugger */
+ cma_t_boolean activated; /* Activation event was reported */
+ cma_t_boolean did_preempt; /* Thread preempted prior one */
+ cma_t_address start_pc; /* Start routine address */
+ cma_t_address object_addr; /* Addr of thread object */
+ cma__t_substate substate; /* Reason blocked, terminated, etc.*/
+ cma_t_boolean notify_debugger;/* Notify debugger thread is running */
+ cma_t_address SPARE2; /* SPARE */
+ cma_t_address SPARE3; /* SPARE */
+ struct CMA__T_INT_TCB
+ *preempted_tcb; /* TCB of thread that got preempted */
+ cma_t_boolean flags[cma__c_debevt__dim];
+ /* Events enabled for this thread */
+ } cma__t_tcb_debug;
+
+typedef struct CMA__T_TCB_SCHED {
+ cma_t_integer adj_time; /* Abs. time in ticks of last prio adj */
+ cma_t_integer tot_time; /* Weighted ave in ticks (scaled) */
+ cma_t_integer time_stamp; /* Abs. time in ticks of last update */
+ cma_t_integer cpu_time; /* Weighted average in ticks */
+ cma_t_integer cpu_ticks; /* # of ticks while comp. (scaled) */
+ cma_t_integer q_num; /* Number of last ready queue on */
+ cma_t_priority priority; /* Thread priority */
+ cma_t_sched_policy policy; /* Scheduling policy of thread */
+ cma_t_boolean rtb; /* "Run 'Till Block" scheduling */
+ cma_t_boolean spp; /* "Strict Priority Preemption" sched */
+ cma_t_boolean fixed_prio; /* Fixed priority */
+ cma__t_sched_class class; /* Scheduling class */
+ struct CMA__T_VP *processor; /* Current processor (if running) */
+ } cma__t_tcb_sched;
+
+typedef struct CMA__T_INT_ALERT {
+ cma_t_boolean pending : 1; /* alert_pending bit */
+ cma_t_boolean g_enable : 1; /* general delivery state */
+ cma_t_boolean a_enable : 1; /* asynchronous delivery state */
+ cma_t_integer spare : 29; /* Pad to longword */
+ cma_t_natural count; /* Alert scope nesting count */
+ } cma__t_int_alert;
+
+typedef enum CMA__T_STATE {
+ cma__c_state_running = 0, /* For consistency with initial TCB */
+ cma__c_state_ready = 1,
+ cma__c_state_blocked = 2,
+ cma__c_state_terminated = 3
+ } cma__t_state;
+#define cma__c_state__first ((cma_t_integer)cma__c_state_running)
+#define cma__c_state__last ((cma_t_integer)cma__c_state_terminated)
+#define cma__c_state__dim (cma__c_state__last + 1)
+
+typedef enum CMA__T_THKIND {
+ cma__c_thkind_initial = 0, /* Initial thread */
+ cma__c_thkind_normal = 1, /* Normal thread */
+ cma__c_thkind_null = 2 /* A null thread */
+ } cma__t_thkind;
+#define cma__c_thkind__first ((cma_t_integer)cma__c_thkind_initial)
+#define cma__c_thkind__last ((cma_t_integer)cma__c_thkind_null)
+#define cma__c_thkind__dim (cma__c_thkind__last + 1)
+
+typedef enum CMA__T_SYSCALL_STATE {
+ cma__c_syscall_ok = 1, /* syscall was not interrupted */
+ cma__c_syscall_intintrpt = 1, /* syscall was interrupted by VTALRM */
+ cma__c_syscall_extintrpt = 2 /* syscall was interrupted by external signal */
+ } cma__t_syscall_state;
+
+
+typedef struct CMA__T_INT_TCB {
+ /*
+ * Fixed part of TCB.
+ * Modifications to the following three fields must be coordinated.
+ * The object header must always be first, and the prolog must always
+ * remain at the same offset (32) for all time. Thus the object header
+ * must never grow beyond a maximum of 32 bytes.
+ */
+ cma__t_object header; /* Common object header */
+ cma__t_tcb_pad pad1; /* Pad required to align prolog */
+ cma_t_tcb_prolog prolog; /* Standard prolog for tasks, threads */
+
+ /*
+ * Floating part of TCB (fields here on are free to be moved and resized).
+ */
+ cma__t_queue threads; /* List of all known threads */
+ cma__t_int_attr *attributes; /* Backpointer to attr obj */
+ cma__t_state state; /* Current state of thread */
+ cma__t_thkind kind; /* Which kind of thread */
+ struct CMA__T_INT_MUTEX
+ *mutex; /* Mutex to control TCB access */
+ struct CMA__T_INT_CV
+ *term_cv; /* CV for join */
+ struct CMA__T_INT_MUTEX
+ *tswait_mutex; /* Mutex for thread-synchronous waits */
+ struct CMA__T_INT_CV
+ *tswait_cv; /* CV for thread-synchronous waits */
+ cma_t_start_routine start_code; /* Address of start routine */
+ cma_t_address start_arg; /* Argument to pass to start_code */
+ cma__t_queue stack; /* Queue header for stack descr. */
+ cma_t_natural context_count; /* Size of context array */
+ cma__t_context_list contexts; /* Context value array pointer */
+ cma_t_exit_status exit_status; /* Exit status of thread */
+ cma_t_address return_value; /* Thread's return value */
+ cma__t_async_ctx async_ctx; /* Asynchronous context switch info */
+ cma__t_static_ctx static_ctx; /* Static context switch information */
+ cma_t_integer event_status; /* Status of semaphore operation */
+ cma__t_tcb_time timer; /* Time info for dispatcher */
+ cma__t_tcb_sched sched; /* Scheduler info */
+ cma__t_tcb_debug debug; /* Debugger info */
+#if _CMA_OS_ == _CMA__UNIX
+# if !_CMA_THREAD_SYNC_IO_
+ cma__t_tcb_select select; /* Select info for timed selects */
+# endif
+ struct sigaction sigaction_data[NSIG];
+#endif
+ cma_t_natural syscall_state; /* set if one of the cma wrapped syscalls was interrupted. */
+ cma_t_boolean detached; /* Set if already detached */
+ cma_t_boolean terminated; /* Set if terminated */
+ cma_t_integer joiners; /* Count of joiners, for zombie frees */
+ cma__t_int_alert alert; /* Current alert state info */
+ struct CMA__T_INT_CV
+ *wait_cv; /* CV thread is currently waiting on */
+ struct CMA__T_INT_MUTEX
+ *wait_mutex; /* Mutex thread is waiting on */
+ struct EXC_CONTEXT_T
+ *exc_stack; /* Top of exception stack */
+#if _CMA_PLATFORM_ == _CMA__IBMR2_UNIX
+ char ctx_stack[cma__c_ibmr2_ctx_stack_size];
+#endif
+ cma_t_integer thd_errno; /* Per-thread errno value */
+#if _CMA_OS_ == _CMA__VMS
+ cma_t_integer thd_vmserrno; /* Per-thread VMS errno value */
+#endif
+ } cma__t_int_tcb;
+
+#endif
diff --git a/gdb/osf-share/cma_util.h b/gdb/osf-share/cma_util.h
new file mode 100644
index 00000000000..00451c45a34
--- /dev/null
+++ b/gdb/osf-share/cma_util.h
@@ -0,0 +1,125 @@
+/*
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ * Header file for CMA internal UTIL operations
+ */
+
+#ifndef CMA_UTIL
+#define CMA_UTIL
+
+/*
+ * INCLUDE FILES
+ */
+
+#include <cma.h>
+#include <cma_attr.h>
+#include <cma_defs.h>
+
+#if _CMA_OS_ == _CMA__VMS
+# include <cma_rms.h>
+#endif
+
+#if _CMA_VENDOR_ == _CMA__SUN
+# include <sys/time.h>
+#else
+# include <time.h>
+#endif
+
+#if _CMA_OS_ == _CMA__UNIX
+# include <stdio.h>
+#endif
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#define cma__c_buffer_size 256 /* Size of output buffer */
+
+/*
+ * TYPEDEFS
+ */
+
+/*
+ * Alternate eol routine
+ */
+typedef void (*cma__t_eol_routine) (char *);
+
+#if _CMA_OS_ == _CMA__VMS
+ typedef struct CMA__T_VMSFILE {
+ struct RAB rab;
+ struct FAB fab;
+ } cma__t_vmsfile, *cma__t_file;
+#elif ( _CMA_UNIX_TYPE == _CMA__SVR4 )
+ typedef int cma__t_file;
+#else
+ typedef FILE *cma__t_file;
+#endif
+
+/*
+ * GLOBAL DATA
+ */
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+extern void cma__abort (void);
+
+extern cma_t_integer cma__atol (char *);
+
+extern cma_t_integer cma__atoi (char *);
+
+extern char * cma__getenv (char *,char *,int);
+
+extern int cma__gettimespec (struct timespec *);
+
+extern cma__t_file cma__int_fopen (char *,char *);
+
+#ifndef NDEBUG
+extern void cma__init_trace (char *_env);
+#endif
+
+extern char * cma__memcpy (char *,char *,cma_t_integer);
+
+#ifndef cma__memset
+extern char * cma__memset (char *,cma_t_integer,cma_t_integer);
+#endif
+
+extern void cma__putformat (char *,char *,...);
+
+extern void cma__putstring (char *,char *);
+
+extern void cma__putint (char *,cma_t_integer);
+
+extern void cma__putint_5 (char *,cma_t_integer);
+
+extern void cma__putint_10 (char *,cma_t_integer);
+
+extern void cma__puthex (char *,cma_t_integer);
+
+extern void cma__puthex_8 (char *,cma_t_integer);
+
+extern void cma__puteol (char *);
+
+extern void cma__set_eol_routine (cma__t_eol_routine,cma__t_eol_routine *);
+
+extern cma_t_integer cma__strlen (char *);
+
+extern int cma__strncmp (char *,char *,cma_t_integer);
+
+extern char *cma__gets (char *,char *);
+
+#endif
diff --git a/gdb/osfsolib.c b/gdb/osfsolib.c
new file mode 100644
index 00000000000..345ab0831a9
--- /dev/null
+++ b/gdb/osfsolib.c
@@ -0,0 +1,938 @@
+/* Handle OSF/1 shared libraries for GDB, the GNU Debugger.
+ Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000
+ 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. */
+
+/* FIXME: Most of this code could be merged with solib.c by using
+ next_link_map_member and xfer_link_map_member in solib.c. */
+
+#include "defs.h"
+
+#include <sys/types.h>
+#include <signal.h>
+#include "gdb_string.h"
+#include <fcntl.h>
+
+#include "symtab.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "target.h"
+#include "frame.h"
+#include "gdb_regex.h"
+#include "inferior.h"
+#include "language.h"
+#include "gdbcmd.h"
+
+#define MAX_PATH_SIZE 1024 /* FIXME: Should be dynamic */
+
+/* When handling shared libraries, GDB has to find out the pathnames
+ of all shared libraries that are currently loaded (to read in their
+ symbols) and where the shared libraries are loaded in memory
+ (to relocate them properly from their prelinked addresses to the
+ current load address).
+
+ Under OSF/1 there are two possibilities to get at this information:
+ 1) Peek around in the runtime loader structures.
+ These are not documented, and they are not defined in the system
+ header files. The definitions below were obtained by experimentation,
+ but they seem stable enough.
+ 2) Use the undocumented libxproc.a library, which contains the
+ equivalent ldr_* routines.
+ This approach is somewhat cleaner, but it requires that the GDB
+ executable is dynamically linked. In addition it requires a
+ NAT_CLIBS= -lxproc -Wl,-expect_unresolved,ldr_process_context
+ linker specification for GDB and all applications that are using
+ libgdb.
+ We will use the peeking approach until it becomes unwieldy. */
+
+#ifndef USE_LDR_ROUTINES
+
+/* Definition of runtime loader structures, found by experimentation. */
+#define RLD_CONTEXT_ADDRESS 0x3ffc0000000
+
+typedef struct
+ {
+ CORE_ADDR next;
+ CORE_ADDR previous;
+ CORE_ADDR unknown1;
+ char *module_name;
+ CORE_ADDR modinfo_addr;
+ long module_id;
+ CORE_ADDR unknown2;
+ CORE_ADDR unknown3;
+ long region_count;
+ CORE_ADDR regioninfo_addr;
+ }
+ldr_module_info_t;
+
+typedef struct
+ {
+ long unknown1;
+ CORE_ADDR regionname_addr;
+ long protection;
+ CORE_ADDR vaddr;
+ CORE_ADDR mapaddr;
+ long size;
+ long unknown2[5];
+ }
+ldr_region_info_t;
+
+typedef struct
+ {
+ CORE_ADDR unknown1;
+ CORE_ADDR unknown2;
+ CORE_ADDR head;
+ CORE_ADDR tail;
+ }
+ldr_context_t;
+
+static ldr_context_t ldr_context;
+
+#else
+
+#include <loader.h>
+static ldr_process_t fake_ldr_process;
+
+/* Called by ldr_* routines to read memory from the current target. */
+
+static int ldr_read_memory (CORE_ADDR, char *, int, int);
+
+static int
+ldr_read_memory (CORE_ADDR memaddr, char *myaddr, int len, int readstring)
+{
+ int result;
+ char *buffer;
+
+ if (readstring)
+ {
+ target_read_string (memaddr, &buffer, len, &result);
+ if (result == 0)
+ strcpy (myaddr, buffer);
+ xfree (buffer);
+ }
+ else
+ result = target_read_memory (memaddr, myaddr, len);
+
+ if (result != 0)
+ result = -result;
+ return result;
+}
+
+#endif
+
+/* Define our own link_map structure.
+ This will help to share code with solib.c. */
+
+struct link_map
+{
+ CORE_ADDR l_offset; /* prelink to load address offset */
+ char *l_name; /* full name of loaded object */
+ ldr_module_info_t module_info; /* corresponding module info */
+};
+
+#define LM_OFFSET(so) ((so) -> lm.l_offset)
+#define LM_NAME(so) ((so) -> lm.l_name)
+
+struct so_list
+ {
+ struct so_list *next; /* next structure in linked list */
+ struct link_map lm; /* copy of link map from inferior */
+ struct link_map *lmaddr; /* addr in inferior lm was read from */
+ CORE_ADDR lmend; /* upper addr bound of mapped object */
+ char so_name[MAX_PATH_SIZE]; /* shared object lib name (FIXME) */
+ char symbols_loaded; /* flag: symbols read in yet? */
+ char from_tty; /* flag: print msgs? */
+ struct objfile *objfile; /* objfile for loaded lib */
+ struct section_table *sections;
+ struct section_table *sections_end;
+ struct section_table *textsection;
+ bfd *abfd;
+ };
+
+static struct so_list *so_list_head; /* List of known shared objects */
+
+extern int fdmatch (int, int); /* In libiberty */
+
+/* Local function prototypes */
+
+static void sharedlibrary_command (char *, int);
+
+static void info_sharedlibrary_command (char *, int);
+
+static int symbol_add_stub (char *);
+
+static struct so_list *find_solib (struct so_list *);
+
+static struct link_map *first_link_map_member (void);
+
+static struct link_map *next_link_map_member (struct so_list *);
+
+static void xfer_link_map_member (struct so_list *, struct link_map *);
+
+static int solib_map_sections (char *);
+
+/*
+
+ LOCAL FUNCTION
+
+ solib_map_sections -- open bfd and build sections for shared lib
+
+ SYNOPSIS
+
+ static int solib_map_sections (struct so_list *so)
+
+ DESCRIPTION
+
+ Given a pointer to one of the shared objects in our list
+ of mapped objects, use the recorded name to open a bfd
+ descriptor for the object, build a section table, and then
+ relocate all the section addresses by the base address at
+ which the shared object was mapped.
+
+ FIXMES
+
+ In most (all?) cases the shared object file name recorded in the
+ dynamic linkage tables will be a fully qualified pathname. For
+ cases where it isn't, do we really mimic the systems search
+ mechanism correctly in the below code (particularly the tilde
+ expansion stuff?).
+ */
+
+static int
+solib_map_sections (char *arg)
+{
+ struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
+ char *filename;
+ char *scratch_pathname;
+ int scratch_chan;
+ struct section_table *p;
+ struct cleanup *old_chain;
+ bfd *abfd;
+
+ filename = tilde_expand (so->so_name);
+ old_chain = make_cleanup (xfree, filename);
+
+ scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
+ &scratch_pathname);
+ if (scratch_chan < 0)
+ {
+ scratch_chan = openp (getenv ("LD_LIBRARY_PATH"), 1, filename,
+ O_RDONLY, 0, &scratch_pathname);
+ }
+ if (scratch_chan < 0)
+ {
+ perror_with_name (filename);
+ }
+ /* Leave scratch_pathname allocated. bfd->name will point to it. */
+
+ abfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan);
+ if (!abfd)
+ {
+ close (scratch_chan);
+ error ("Could not open `%s' as an executable file: %s",
+ scratch_pathname, bfd_errmsg (bfd_get_error ()));
+ }
+ /* Leave bfd open, core_xfer_memory and "info files" need it. */
+ so->abfd = abfd;
+ abfd->cacheable = 1;
+
+ if (!bfd_check_format (abfd, bfd_object))
+ {
+ error ("\"%s\": not in executable format: %s.",
+ scratch_pathname, bfd_errmsg (bfd_get_error ()));
+ }
+ if (build_section_table (abfd, &so->sections, &so->sections_end))
+ {
+ error ("Can't find the file sections in `%s': %s",
+ bfd_get_filename (exec_bfd), bfd_errmsg (bfd_get_error ()));
+ }
+
+ for (p = so->sections; p < so->sections_end; p++)
+ {
+ /* Relocate the section binding addresses as recorded in the shared
+ object's file by the offset to get the address to which the
+ object was actually mapped. */
+ p->addr += LM_OFFSET (so);
+ p->endaddr += LM_OFFSET (so);
+ so->lmend = (CORE_ADDR) max (p->endaddr, so->lmend);
+ if (STREQ (p->the_bfd_section->name, ".text"))
+ {
+ so->textsection = p;
+ }
+ }
+
+ /* Free the file names, close the file now. */
+ do_cleanups (old_chain);
+
+ return (1);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ first_link_map_member -- locate first member in dynamic linker's map
+
+ SYNOPSIS
+
+ static struct link_map *first_link_map_member (void)
+
+ DESCRIPTION
+
+ Read in a copy of the first member in the inferior's dynamic
+ link map from the inferior's dynamic linker structures, and return
+ a pointer to the copy in our address space.
+ */
+
+static struct link_map *
+first_link_map_member (void)
+{
+ struct link_map *lm = NULL;
+ static struct link_map first_lm;
+
+#ifdef USE_LDR_ROUTINES
+ ldr_module_t mod_id = LDR_NULL_MODULE;
+ size_t retsize;
+
+ fake_ldr_process = ldr_core_process ();
+ ldr_set_core_reader (ldr_read_memory);
+ ldr_xdetach (fake_ldr_process);
+ if (ldr_xattach (fake_ldr_process) != 0
+ || ldr_next_module (fake_ldr_process, &mod_id) != 0
+ || mod_id == LDR_NULL_MODULE
+ || ldr_inq_module (fake_ldr_process, mod_id,
+ &first_lm.module_info, sizeof (ldr_module_info_t),
+ &retsize) != 0)
+ return lm;
+#else
+ CORE_ADDR ldr_context_addr;
+
+ if (target_read_memory ((CORE_ADDR) RLD_CONTEXT_ADDRESS,
+ (char *) &ldr_context_addr,
+ sizeof (CORE_ADDR)) != 0
+ || target_read_memory (ldr_context_addr,
+ (char *) &ldr_context,
+ sizeof (ldr_context_t)) != 0
+ || target_read_memory ((CORE_ADDR) ldr_context.head,
+ (char *) &first_lm.module_info,
+ sizeof (ldr_module_info_t)) != 0)
+ return lm;
+#endif
+
+ lm = &first_lm;
+
+ /* The first entry is for the main program and should be skipped. */
+ lm->l_name = NULL;
+
+ return lm;
+}
+
+static struct link_map *
+next_link_map_member (struct so_list *so_list_ptr)
+{
+ struct link_map *lm = NULL;
+ static struct link_map next_lm;
+#ifdef USE_LDR_ROUTINES
+ ldr_module_t mod_id = so_list_ptr->lm.module_info.lmi_modid;
+ size_t retsize;
+
+ if (ldr_next_module (fake_ldr_process, &mod_id) != 0
+ || mod_id == LDR_NULL_MODULE
+ || ldr_inq_module (fake_ldr_process, mod_id,
+ &next_lm.module_info, sizeof (ldr_module_info_t),
+ &retsize) != 0)
+ return lm;
+
+ lm = &next_lm;
+ lm->l_name = lm->module_info.lmi_name;
+#else
+ CORE_ADDR ldr_context_addr;
+
+ /* Reread context in case ldr_context.tail was updated. */
+
+ if (target_read_memory ((CORE_ADDR) RLD_CONTEXT_ADDRESS,
+ (char *) &ldr_context_addr,
+ sizeof (CORE_ADDR)) != 0
+ || target_read_memory (ldr_context_addr,
+ (char *) &ldr_context,
+ sizeof (ldr_context_t)) != 0
+ || so_list_ptr->lm.module_info.modinfo_addr == ldr_context.tail
+ || target_read_memory (so_list_ptr->lm.module_info.next,
+ (char *) &next_lm.module_info,
+ sizeof (ldr_module_info_t)) != 0)
+ return lm;
+
+ lm = &next_lm;
+ lm->l_name = lm->module_info.module_name;
+#endif
+ return lm;
+}
+
+static void
+xfer_link_map_member (struct so_list *so_list_ptr, struct link_map *lm)
+{
+ int i;
+ so_list_ptr->lm = *lm;
+
+ /* OSF/1 shared libraries are pre-linked to particular addresses,
+ but the runtime loader may have to relocate them if the
+ address ranges of the libraries used by the target executable clash,
+ or if the target executable is linked with the -taso option.
+ The offset is the difference between the address where the shared
+ library is mapped and the pre-linked address of the shared library.
+
+ FIXME: GDB is currently unable to relocate the shared library
+ sections by different offsets. If sections are relocated by
+ different offsets, put out a warning and use the offset of the
+ first section for all remaining sections. */
+ LM_OFFSET (so_list_ptr) = 0;
+
+ /* There is one entry that has no name (for the inferior executable)
+ since it is not a shared object. */
+ if (LM_NAME (so_list_ptr) != 0)
+ {
+
+#ifdef USE_LDR_ROUTINES
+ int len = strlen (LM_NAME (so_list_ptr) + 1);
+
+ if (len > MAX_PATH_SIZE)
+ len = MAX_PATH_SIZE;
+ strncpy (so_list_ptr->so_name, LM_NAME (so_list_ptr), MAX_PATH_SIZE);
+ so_list_ptr->so_name[MAX_PATH_SIZE - 1] = '\0';
+
+ for (i = 0; i < lm->module_info.lmi_nregion; i++)
+ {
+ ldr_region_info_t region_info;
+ size_t retsize;
+ CORE_ADDR region_offset;
+
+ if (ldr_inq_region (fake_ldr_process, lm->module_info.lmi_modid,
+ i, &region_info, sizeof (region_info),
+ &retsize) != 0)
+ break;
+ region_offset = (CORE_ADDR) region_info.lri_mapaddr
+ - (CORE_ADDR) region_info.lri_vaddr;
+ if (i == 0)
+ LM_OFFSET (so_list_ptr) = region_offset;
+ else if (LM_OFFSET (so_list_ptr) != region_offset)
+ warning ("cannot handle shared library relocation for %s (%s)",
+ so_list_ptr->so_name, region_info.lri_name);
+ }
+#else
+ int errcode;
+ char *buffer;
+ target_read_string ((CORE_ADDR) LM_NAME (so_list_ptr), &buffer,
+ MAX_PATH_SIZE - 1, &errcode);
+ if (errcode != 0)
+ error ("xfer_link_map_member: Can't read pathname for load map: %s\n",
+ safe_strerror (errcode));
+ strncpy (so_list_ptr->so_name, buffer, MAX_PATH_SIZE - 1);
+ xfree (buffer);
+ so_list_ptr->so_name[MAX_PATH_SIZE - 1] = '\0';
+
+ for (i = 0; i < lm->module_info.region_count; i++)
+ {
+ ldr_region_info_t region_info;
+ CORE_ADDR region_offset;
+
+ if (target_read_memory (lm->module_info.regioninfo_addr
+ + i * sizeof (region_info),
+ (char *) &region_info,
+ sizeof (region_info)) != 0)
+ break;
+ region_offset = region_info.mapaddr - region_info.vaddr;
+ if (i == 0)
+ LM_OFFSET (so_list_ptr) = region_offset;
+ else if (LM_OFFSET (so_list_ptr) != region_offset)
+ {
+ char *region_name;
+ target_read_string (region_info.regionname_addr, &buffer,
+ MAX_PATH_SIZE - 1, &errcode);
+ if (errcode == 0)
+ region_name = buffer;
+ else
+ region_name = "??";
+ warning ("cannot handle shared library relocation for %s (%s)",
+ so_list_ptr->so_name, region_name);
+ xfree (buffer);
+ }
+ }
+#endif
+
+ catch_errors (solib_map_sections, (char *) so_list_ptr,
+ "Error while mapping shared library sections:\n",
+ RETURN_MASK_ALL);
+ }
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ find_solib -- step through list of shared objects
+
+ SYNOPSIS
+
+ struct so_list *find_solib (struct so_list *so_list_ptr)
+
+ DESCRIPTION
+
+ This module contains the routine which finds the names of any
+ loaded "images" in the current process. The argument in must be
+ NULL on the first call, and then the returned value must be passed
+ in on subsequent calls. This provides the capability to "step" down
+ the list of loaded objects. On the last object, a NULL value is
+ returned.
+
+ The arg and return value are "struct link_map" pointers, as defined
+ in <link.h>.
+ */
+
+static struct so_list *
+find_solib (struct so_list *so_list_ptr)
+{
+ struct so_list *so_list_next = NULL;
+ struct link_map *lm = NULL;
+ struct so_list *new;
+
+ if (so_list_ptr == NULL)
+ {
+ /* We are setting up for a new scan through the loaded images. */
+ if ((so_list_next = so_list_head) == NULL)
+ {
+ /* Find the first link map list member. */
+ lm = first_link_map_member ();
+ }
+ }
+ else
+ {
+ /* We have been called before, and are in the process of walking
+ the shared library list. Advance to the next shared object. */
+ lm = next_link_map_member (so_list_ptr);
+ so_list_next = so_list_ptr->next;
+ }
+ if ((so_list_next == NULL) && (lm != NULL))
+ {
+ /* Get next link map structure from inferior image and build a local
+ abbreviated load_map structure */
+ new = (struct so_list *) xmalloc (sizeof (struct so_list));
+ memset ((char *) new, 0, sizeof (struct so_list));
+ new->lmaddr = lm;
+ /* Add the new node as the next node in the list, or as the root
+ node if this is the first one. */
+ if (so_list_ptr != NULL)
+ {
+ so_list_ptr->next = new;
+ }
+ else
+ {
+ so_list_head = new;
+ }
+ so_list_next = new;
+ xfer_link_map_member (new, lm);
+ }
+ return (so_list_next);
+}
+
+/* A small stub to get us past the arg-passing pinhole of catch_errors. */
+
+static int
+symbol_add_stub (char *arg)
+{
+ register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
+ CORE_ADDR text_addr = 0;
+ struct section_addr_info section_addrs;
+
+ memset (&section_addrs, 0, sizeof (section_addrs));
+ if (so->textsection)
+ text_addr = so->textsection->addr;
+ else if (so->abfd != NULL)
+ {
+ asection *lowest_sect;
+
+ /* If we didn't find a mapped non zero sized .text section, set up
+ text_addr so that the relocation in symbol_file_add does no harm. */
+
+ lowest_sect = bfd_get_section_by_name (so->abfd, ".text");
+ if (lowest_sect == NULL)
+ bfd_map_over_sections (so->abfd, find_lowest_section,
+ (PTR) &lowest_sect);
+ if (lowest_sect)
+ text_addr = bfd_section_vma (so->abfd, lowest_sect) + LM_OFFSET (so);
+ }
+
+ section_addrs.other[0].addr = text_addr;
+ section_addrs.other[0].name = ".text";
+ so->objfile = symbol_file_add (so->so_name, so->from_tty,
+ &section_addrs, 0, OBJF_SHARED);
+ return (1);
+}
+
+/*
+
+ GLOBAL FUNCTION
+
+ solib_add -- add a shared library file to the symtab and section list
+
+ SYNOPSIS
+
+ void solib_add (char *arg_string, int from_tty,
+ struct target_ops *target, int readsyms)
+
+ DESCRIPTION
+
+ */
+
+void
+solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms)
+{
+ register struct so_list *so = NULL; /* link map state variable */
+
+ /* Last shared library that we read. */
+ struct so_list *so_last = NULL;
+
+ char *re_err;
+ int count;
+ int old;
+
+ if (!readsyms)
+ return;
+
+ if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)
+ {
+ error ("Invalid regexp: %s", re_err);
+ }
+
+
+ /* Add the shared library sections to the section table of the
+ specified target, if any. */
+ if (target)
+ {
+ /* Count how many new section_table entries there are. */
+ so = NULL;
+ count = 0;
+ while ((so = find_solib (so)) != NULL)
+ {
+ if (so->so_name[0])
+ {
+ count += so->sections_end - so->sections;
+ }
+ }
+
+ if (count)
+ {
+ /* Add these section table entries to the target's table. */
+
+ old = target_resize_to_sections (target, count);
+
+ while ((so = find_solib (so)) != NULL)
+ {
+ if (so->so_name[0])
+ {
+ count = so->sections_end - so->sections;
+ memcpy ((char *) (target->to_sections + old),
+ so->sections,
+ (sizeof (struct section_table)) * count);
+ old += count;
+ }
+ }
+ }
+ }
+
+ /* Now add the symbol files. */
+ so = NULL;
+ while ((so = find_solib (so)) != NULL)
+ {
+ if (so->so_name[0] && re_exec (so->so_name))
+ {
+ so->from_tty = from_tty;
+ if (so->symbols_loaded)
+ {
+ if (from_tty)
+ {
+ printf_unfiltered ("Symbols already loaded for %s\n", so->so_name);
+ }
+ }
+ else if (catch_errors
+ (symbol_add_stub, (char *) so,
+ "Error while reading shared library symbols:\n",
+ RETURN_MASK_ALL))
+ {
+ so_last = so;
+ so->symbols_loaded = 1;
+ }
+ }
+ }
+
+ /* Getting new symbols may change our opinion about what is
+ frameless. */
+ if (so_last)
+ reinit_frame_cache ();
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ info_sharedlibrary_command -- code for "info sharedlibrary"
+
+ SYNOPSIS
+
+ static void info_sharedlibrary_command ()
+
+ DESCRIPTION
+
+ Walk through the shared library list and print information
+ about each attached library.
+ */
+
+static void
+info_sharedlibrary_command (char *ignore, int from_tty)
+{
+ register struct so_list *so = NULL; /* link map state variable */
+ int header_done = 0;
+
+ if (exec_bfd == NULL)
+ {
+ printf_unfiltered ("No executable file.\n");
+ return;
+ }
+ while ((so = find_solib (so)) != NULL)
+ {
+ if (so->so_name[0])
+ {
+ unsigned long txt_start = 0;
+ unsigned long txt_end = 0;
+
+ if (!header_done)
+ {
+ printf_unfiltered ("%-20s%-20s%-12s%s\n", "From", "To", "Syms Read",
+ "Shared Object Library");
+ header_done++;
+ }
+ if (so->textsection)
+ {
+ txt_start = (unsigned long) so->textsection->addr;
+ txt_end = (unsigned long) so->textsection->endaddr;
+ }
+ printf_unfiltered ("%-20s", local_hex_string_custom (txt_start, "08l"));
+ printf_unfiltered ("%-20s", local_hex_string_custom (txt_end, "08l"));
+ printf_unfiltered ("%-12s", so->symbols_loaded ? "Yes" : "No");
+ printf_unfiltered ("%s\n", so->so_name);
+ }
+ }
+ if (so_list_head == NULL)
+ {
+ printf_unfiltered ("No shared libraries loaded at this time.\n");
+ }
+}
+
+/*
+
+ GLOBAL FUNCTION
+
+ solib_address -- check to see if an address is in a shared lib
+
+ SYNOPSIS
+
+ char *solib_address (CORE_ADDR address)
+
+ DESCRIPTION
+
+ Provides a hook for other gdb routines to discover whether or
+ not a particular address is within the mapped address space of
+ a shared library. Any address between the base mapping address
+ and the first address beyond the end of the last mapping, is
+ considered to be within the shared library address space, for
+ our purposes.
+
+ For example, this routine is called at one point to disable
+ breakpoints which are in shared libraries that are not currently
+ mapped in.
+ */
+
+char *
+solib_address (CORE_ADDR address)
+{
+ register struct so_list *so = 0; /* link map state variable */
+
+ while ((so = find_solib (so)) != NULL)
+ {
+ if (so->so_name[0] && so->textsection)
+ {
+ if ((address >= (CORE_ADDR) so->textsection->addr) &&
+ (address < (CORE_ADDR) so->textsection->endaddr))
+ return (so->so_name);
+ }
+ }
+ return (0);
+}
+
+/* Called by free_all_symtabs */
+
+void
+clear_solib (void)
+{
+ struct so_list *next;
+ char *bfd_filename;
+
+ disable_breakpoints_in_shlibs (1);
+
+ while (so_list_head)
+ {
+ if (so_list_head->sections)
+ {
+ xfree (so_list_head->sections);
+ }
+ if (so_list_head->abfd)
+ {
+ remove_target_sections (so_list_head->abfd);
+ bfd_filename = bfd_get_filename (so_list_head->abfd);
+ if (!bfd_close (so_list_head->abfd))
+ warning ("cannot close \"%s\": %s",
+ bfd_filename, bfd_errmsg (bfd_get_error ()));
+ }
+ else
+ /* This happens for the executable on SVR4. */
+ bfd_filename = NULL;
+
+ next = so_list_head->next;
+ if (bfd_filename)
+ xfree (bfd_filename);
+ xfree (so_list_head);
+ so_list_head = next;
+ }
+}
+
+/*
+
+ GLOBAL FUNCTION
+
+ solib_create_inferior_hook -- shared library startup support
+
+ SYNOPSIS
+
+ void solib_create_inferior_hook()
+
+ DESCRIPTION
+
+ When gdb starts up the inferior, it nurses it along (through the
+ shell) until it is ready to execute it's first instruction. At this
+ point, this function gets called via expansion of the macro
+ SOLIB_CREATE_INFERIOR_HOOK.
+ For a statically bound executable, this first instruction is the
+ one at "_start", or a similar text label. No further processing is
+ needed in that case.
+ For a dynamically bound executable, this first instruction is somewhere
+ in the rld, and the actual user executable is not yet mapped in.
+ We continue the inferior again, rld then maps in the actual user
+ executable and any needed shared libraries and then sends
+ itself a SIGTRAP.
+ At that point we discover the names of all shared libraries and
+ read their symbols in.
+
+ FIXME
+
+ This code does not properly handle hitting breakpoints which the
+ user might have set in the rld itself. Proper handling would have
+ to check if the SIGTRAP happened due to a kill call.
+
+ Also, what if child has exit()ed? Must exit loop somehow.
+ */
+
+void
+solib_create_inferior_hook (void)
+{
+
+ /* Nothing to do for statically bound executables. */
+
+ if (symfile_objfile == NULL
+ || symfile_objfile->obfd == NULL
+ || ((bfd_get_file_flags (symfile_objfile->obfd) & DYNAMIC) == 0))
+ return;
+
+ /* Now run the target. It will eventually get a SIGTRAP, at
+ which point all of the libraries will have been mapped in and we
+ can go groveling around in the rld structures to find
+ out what we need to know about them. */
+
+ clear_proceed_status ();
+ stop_soon_quietly = 1;
+ stop_signal = TARGET_SIGNAL_0;
+ do
+ {
+ target_resume (minus_one_ptid, 0, stop_signal);
+ wait_for_inferior ();
+ }
+ while (stop_signal != TARGET_SIGNAL_TRAP);
+
+ /* solib_add will call reinit_frame_cache.
+ But we are stopped in the runtime loader and we do not have symbols
+ for the runtime loader. So heuristic_proc_start will be called
+ and will put out an annoying warning.
+ Delaying the resetting of stop_soon_quietly until after symbol loading
+ suppresses the warning. */
+ solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
+ stop_soon_quietly = 0;
+}
+
+
+/*
+
+ LOCAL FUNCTION
+
+ sharedlibrary_command -- handle command to explicitly add library
+
+ SYNOPSIS
+
+ static void sharedlibrary_command (char *args, int from_tty)
+
+ DESCRIPTION
+
+ */
+
+static void
+sharedlibrary_command (char *args, int from_tty)
+{
+ dont_repeat ();
+ solib_add (args, from_tty, (struct target_ops *) 0, 1);
+}
+
+void
+_initialize_solib (void)
+{
+ add_com ("sharedlibrary", class_files, sharedlibrary_command,
+ "Load shared object library symbols for files matching REGEXP.");
+ add_info ("sharedlibrary", info_sharedlibrary_command,
+ "Status of loaded shared object libraries.");
+
+ add_show_from_set
+ (add_set_cmd ("auto-solib-add", class_support, var_boolean,
+ (char *) &auto_solib_add,
+ "Set autoloading of shared library symbols.\n\
+If \"on\", symbols from all shared object libraries will be loaded\n\
+automatically when the inferior begins execution, when the dynamic linker\n\
+informs gdb that a new library has been loaded, or when attaching to the\n\
+inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.",
+ &setlist),
+ &showlist);
+}
diff --git a/gdb/p-exp.y b/gdb/p-exp.y
new file mode 100644
index 00000000000..7333f6d04a0
--- /dev/null
+++ b/gdb/p-exp.y
@@ -0,0 +1,1610 @@
+/* YACC parser for Pascal expressions, for GDB.
+ Copyright 2000
+ 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. */
+
+/* This file is derived from c-exp.y */
+
+/* Parse a Pascal expression from text in a string,
+ and return the result as a struct expression pointer.
+ That structure contains arithmetic operations in reverse polish,
+ with constants represented by operations that are followed by special data.
+ See expression.h for the details of the format.
+ What is important here is that it can be built up sequentially
+ during the process of parsing; the lower levels of the tree always
+ come first in the result.
+
+ Note that malloc's and realloc's in this file are transformed to
+ xmalloc and xrealloc respectively by the same sed command in the
+ makefile that remaps any other malloc/realloc inserted by the parser
+ generator. Doing this with #defines and trying to control the interaction
+ with include files (<malloc.h> and <stdlib.h> for example) just became
+ too messy, particularly when such includes can be inserted at random
+ times by the parser generator. */
+
+/* Known bugs or limitations:
+ - pascal string operations are not supported at all.
+ - there are some problems with boolean types.
+ - Pascal type hexadecimal constants are not supported
+ because they conflict with the internal variables format.
+ Probably also lots of other problems, less well defined PM */
+%{
+
+#include "defs.h"
+#include "gdb_string.h"
+#include <ctype.h>
+#include "expression.h"
+#include "value.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "p-lang.h"
+#include "bfd.h" /* Required by objfiles.h. */
+#include "symfile.h" /* Required by objfiles.h. */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
+ as well as gratuitiously global symbol names, so we can have multiple
+ yacc generated parsers in gdb. Note that these are only the variables
+ produced by yacc. If other parser generators (bison, byacc, etc) produce
+ additional global names that conflict at link time, then those parser
+ generators need to be fixed instead of adding those names to this list. */
+
+#define yymaxdepth pascal_maxdepth
+#define yyparse pascal_parse
+#define yylex pascal_lex
+#define yyerror pascal_error
+#define yylval pascal_lval
+#define yychar pascal_char
+#define yydebug pascal_debug
+#define yypact pascal_pact
+#define yyr1 pascal_r1
+#define yyr2 pascal_r2
+#define yydef pascal_def
+#define yychk pascal_chk
+#define yypgo pascal_pgo
+#define yyact pascal_act
+#define yyexca pascal_exca
+#define yyerrflag pascal_errflag
+#define yynerrs pascal_nerrs
+#define yyps pascal_ps
+#define yypv pascal_pv
+#define yys pascal_s
+#define yy_yys pascal_yys
+#define yystate pascal_state
+#define yytmp pascal_tmp
+#define yyv pascal_v
+#define yy_yyv pascal_yyv
+#define yyval pascal_val
+#define yylloc pascal_lloc
+#define yyreds pascal_reds /* With YYDEBUG defined */
+#define yytoks pascal_toks /* With YYDEBUG defined */
+#define yylhs pascal_yylhs
+#define yylen pascal_yylen
+#define yydefred pascal_yydefred
+#define yydgoto pascal_yydgoto
+#define yysindex pascal_yysindex
+#define yyrindex pascal_yyrindex
+#define yygindex pascal_yygindex
+#define yytable pascal_yytable
+#define yycheck pascal_yycheck
+
+#ifndef YYDEBUG
+#define YYDEBUG 0 /* Default to no yydebug support */
+#endif
+
+int yyparse (void);
+
+static int yylex (void);
+
+void
+yyerror (char *);
+
+static char * uptok (char *, int);
+%}
+
+/* Although the yacc "value" of an expression is not used,
+ since the result is stored in the structure being created,
+ other node types do have values. */
+
+%union
+ {
+ LONGEST lval;
+ struct {
+ LONGEST val;
+ struct type *type;
+ } typed_val_int;
+ struct {
+ DOUBLEST dval;
+ struct type *type;
+ } typed_val_float;
+ struct symbol *sym;
+ struct type *tval;
+ struct stoken sval;
+ struct ttype tsym;
+ struct symtoken ssym;
+ int voidval;
+ struct block *bval;
+ enum exp_opcode opcode;
+ struct internalvar *ivar;
+
+ struct type **tvec;
+ int *ivec;
+ }
+
+%{
+/* YYSTYPE gets defined by %union */
+static int
+parse_number (char *, int, int, YYSTYPE *);
+
+static struct type *current_type;
+
+static void push_current_type ();
+static void pop_current_type ();
+static int search_field;
+%}
+
+%type <voidval> exp exp1 type_exp start normal_start variable qualified_name
+%type <tval> type typebase
+/* %type <bval> block */
+
+/* Fancy type parsing. */
+%type <tval> ptype
+
+%token <typed_val_int> INT
+%token <typed_val_float> FLOAT
+
+/* Both NAME and TYPENAME tokens represent symbols in the input,
+ and both convey their data as strings.
+ But a TYPENAME is a string that happens to be defined as a typedef
+ or builtin type name (such as int or char)
+ and a NAME is any other symbol.
+ Contexts where this distinction is not important can use the
+ nonterminal "name", which matches either NAME or TYPENAME. */
+
+%token <sval> STRING
+%token <sval> FIELDNAME
+%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
+%token <tsym> TYPENAME
+%type <sval> name
+%type <ssym> name_not_typename
+
+/* A NAME_OR_INT is a symbol which is not known in the symbol table,
+ but which would parse as a valid number in the current input radix.
+ E.g. "c" when input_radix==16. Depending on the parse, it will be
+ turned into a name or into a number. */
+
+%token <ssym> NAME_OR_INT
+
+%token STRUCT CLASS SIZEOF COLONCOLON
+%token ERROR
+
+/* Special type cases, put in to allow the parser to distinguish different
+ legal basetypes. */
+
+%token <voidval> VARIABLE
+
+
+/* Object pascal */
+%token THIS
+%token <lval> TRUE FALSE
+
+%left ','
+%left ABOVE_COMMA
+%right ASSIGN
+%left NOT
+%left OR
+%left XOR
+%left ANDAND
+%left '=' NOTEQUAL
+%left '<' '>' LEQ GEQ
+%left LSH RSH DIV MOD
+%left '@'
+%left '+' '-'
+%left '*' '/'
+%right UNARY INCREMENT DECREMENT
+%right ARROW '.' '[' '('
+%left '^'
+%token <ssym> BLOCKNAME
+%type <bval> block
+%left COLONCOLON
+
+
+%%
+
+start : { current_type = NULL;
+ search_field = 0;
+ }
+ normal_start;
+
+normal_start :
+ exp1
+ | type_exp
+ ;
+
+type_exp: type
+ { write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type($1);
+ write_exp_elt_opcode(OP_TYPE);
+ current_type = $1; } ;
+
+/* Expressions, including the comma operator. */
+exp1 : exp
+ | exp1 ',' exp
+ { write_exp_elt_opcode (BINOP_COMMA); }
+ ;
+
+/* Expressions, not including the comma operator. */
+exp : exp '^' %prec UNARY
+ { write_exp_elt_opcode (UNOP_IND);
+ if (current_type)
+ current_type = TYPE_TARGET_TYPE (current_type); }
+
+exp : '@' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_ADDR);
+ if (current_type)
+ current_type = TYPE_POINTER_TYPE (current_type); }
+
+exp : '-' exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_NEG); }
+ ;
+
+exp : NOT exp %prec UNARY
+ { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
+ ;
+
+exp : INCREMENT '(' exp ')' %prec UNARY
+ { write_exp_elt_opcode (UNOP_PREINCREMENT); }
+ ;
+
+exp : DECREMENT '(' exp ')' %prec UNARY
+ { write_exp_elt_opcode (UNOP_PREDECREMENT); }
+ ;
+
+exp : exp '.' { search_field = 1; }
+ FIELDNAME
+ /* name */
+ { write_exp_elt_opcode (STRUCTOP_STRUCT);
+ write_exp_string ($4);
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ search_field = 0;
+ if (current_type)
+ { while (TYPE_CODE (current_type) == TYPE_CODE_PTR)
+ current_type = TYPE_TARGET_TYPE (current_type);
+ current_type = lookup_struct_elt_type (
+ current_type, $4.ptr, false); };
+ } ;
+exp : exp '['
+ /* We need to save the current_type value */
+ { char *arrayname;
+ int arrayfieldindex;
+ arrayfieldindex = is_pascal_string_type (
+ current_type, NULL, NULL,
+ NULL, NULL, &arrayname);
+ if (arrayfieldindex)
+ {
+ struct stoken stringsval;
+ stringsval.ptr = alloca (strlen (arrayname) + 1);
+ stringsval.length = strlen (arrayname);
+ strcpy (stringsval.ptr, arrayname);
+ current_type = TYPE_FIELD_TYPE (current_type,
+ arrayfieldindex - 1);
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ write_exp_string (stringsval);
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ }
+ push_current_type (); }
+ exp1 ']'
+ { pop_current_type ();
+ write_exp_elt_opcode (BINOP_SUBSCRIPT);
+ if (current_type)
+ current_type = TYPE_TARGET_TYPE (current_type); }
+
+exp : exp '('
+ /* This is to save the value of arglist_len
+ being accumulated by an outer function call. */
+ { push_current_type ();
+ start_arglist (); }
+ arglist ')' %prec ARROW
+ { write_exp_elt_opcode (OP_FUNCALL);
+ write_exp_elt_longcst ((LONGEST) end_arglist ());
+ write_exp_elt_opcode (OP_FUNCALL);
+ pop_current_type (); }
+ ;
+
+arglist :
+ | exp
+ { arglist_len = 1; }
+ | arglist ',' exp %prec ABOVE_COMMA
+ { arglist_len++; }
+ ;
+
+exp : type '(' exp ')' %prec UNARY
+ { write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type ($1);
+ write_exp_elt_opcode (UNOP_CAST);
+ current_type = $1; }
+ ;
+
+exp : '(' exp1 ')'
+ { }
+ ;
+
+/* Binary operators in order of decreasing precedence. */
+
+exp : exp '*' exp
+ { write_exp_elt_opcode (BINOP_MUL); }
+ ;
+
+exp : exp '/' exp
+ { write_exp_elt_opcode (BINOP_DIV); }
+ ;
+
+exp : exp DIV exp
+ { write_exp_elt_opcode (BINOP_INTDIV); }
+ ;
+
+exp : exp MOD exp
+ { write_exp_elt_opcode (BINOP_REM); }
+ ;
+
+exp : exp '+' exp
+ { write_exp_elt_opcode (BINOP_ADD); }
+ ;
+
+exp : exp '-' exp
+ { write_exp_elt_opcode (BINOP_SUB); }
+ ;
+
+exp : exp LSH exp
+ { write_exp_elt_opcode (BINOP_LSH); }
+ ;
+
+exp : exp RSH exp
+ { write_exp_elt_opcode (BINOP_RSH); }
+ ;
+
+exp : exp '=' exp
+ { write_exp_elt_opcode (BINOP_EQUAL); }
+ ;
+
+exp : exp NOTEQUAL exp
+ { write_exp_elt_opcode (BINOP_NOTEQUAL); }
+ ;
+
+exp : exp LEQ exp
+ { write_exp_elt_opcode (BINOP_LEQ); }
+ ;
+
+exp : exp GEQ exp
+ { write_exp_elt_opcode (BINOP_GEQ); }
+ ;
+
+exp : exp '<' exp
+ { write_exp_elt_opcode (BINOP_LESS); }
+ ;
+
+exp : exp '>' exp
+ { write_exp_elt_opcode (BINOP_GTR); }
+ ;
+
+exp : exp ANDAND exp
+ { write_exp_elt_opcode (BINOP_BITWISE_AND); }
+ ;
+
+exp : exp XOR exp
+ { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
+ ;
+
+exp : exp OR exp
+ { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
+ ;
+
+exp : exp ASSIGN exp
+ { write_exp_elt_opcode (BINOP_ASSIGN); }
+ ;
+
+exp : TRUE
+ { write_exp_elt_opcode (OP_BOOL);
+ write_exp_elt_longcst ((LONGEST) $1);
+ write_exp_elt_opcode (OP_BOOL); }
+ ;
+
+exp : FALSE
+ { write_exp_elt_opcode (OP_BOOL);
+ write_exp_elt_longcst ((LONGEST) $1);
+ write_exp_elt_opcode (OP_BOOL); }
+ ;
+
+exp : INT
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type ($1.type);
+ write_exp_elt_longcst ((LONGEST)($1.val));
+ write_exp_elt_opcode (OP_LONG); }
+ ;
+
+exp : NAME_OR_INT
+ { YYSTYPE val;
+ parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val);
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (val.typed_val_int.type);
+ write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
+ write_exp_elt_opcode (OP_LONG);
+ }
+ ;
+
+
+exp : FLOAT
+ { write_exp_elt_opcode (OP_DOUBLE);
+ write_exp_elt_type ($1.type);
+ write_exp_elt_dblcst ($1.dval);
+ write_exp_elt_opcode (OP_DOUBLE); }
+ ;
+
+exp : variable
+ ;
+
+exp : VARIABLE
+ /* Already written by write_dollar_variable. */
+ ;
+
+exp : SIZEOF '(' type ')' %prec UNARY
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_int);
+ CHECK_TYPEDEF ($3);
+ write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
+ write_exp_elt_opcode (OP_LONG); }
+ ;
+
+exp : STRING
+ { /* C strings are converted into array constants with
+ an explicit null byte added at the end. Thus
+ the array upper bound is the string length.
+ There is no such thing in C as a completely empty
+ string. */
+ char *sp = $1.ptr; int count = $1.length;
+ while (count-- > 0)
+ {
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_char);
+ write_exp_elt_longcst ((LONGEST)(*sp++));
+ write_exp_elt_opcode (OP_LONG);
+ }
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_char);
+ write_exp_elt_longcst ((LONGEST)'\0');
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_opcode (OP_ARRAY);
+ write_exp_elt_longcst ((LONGEST) 0);
+ write_exp_elt_longcst ((LONGEST) ($1.length));
+ write_exp_elt_opcode (OP_ARRAY); }
+ ;
+
+/* Object pascal */
+exp : THIS
+ { write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (OP_THIS); }
+ ;
+
+/* end of object pascal. */
+
+block : BLOCKNAME
+ {
+ if ($1.sym != 0)
+ $$ = SYMBOL_BLOCK_VALUE ($1.sym);
+ else
+ {
+ struct symtab *tem =
+ lookup_symtab (copy_name ($1.stoken));
+ if (tem)
+ $$ = BLOCKVECTOR_BLOCK (BLOCKVECTOR (tem), STATIC_BLOCK);
+ else
+ error ("No file or function \"%s\".",
+ copy_name ($1.stoken));
+ }
+ }
+ ;
+
+block : block COLONCOLON name
+ { struct symbol *tem
+ = lookup_symbol (copy_name ($3), $1,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK)
+ error ("No function \"%s\" in specified context.",
+ copy_name ($3));
+ $$ = SYMBOL_BLOCK_VALUE (tem); }
+ ;
+
+variable: block COLONCOLON name
+ { struct symbol *sym;
+ sym = lookup_symbol (copy_name ($3), $1,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ if (sym == 0)
+ error ("No symbol \"%s\" in specified context.",
+ copy_name ($3));
+
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ /* block_found is set by lookup_symbol. */
+ write_exp_elt_block (block_found);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE); }
+ ;
+
+qualified_name: typebase COLONCOLON name
+ {
+ struct type *type = $1;
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+ && TYPE_CODE (type) != TYPE_CODE_UNION)
+ error ("`%s' is not defined as an aggregate type.",
+ TYPE_NAME (type));
+
+ write_exp_elt_opcode (OP_SCOPE);
+ write_exp_elt_type (type);
+ write_exp_string ($3);
+ write_exp_elt_opcode (OP_SCOPE);
+ }
+ ;
+
+variable: qualified_name
+ | COLONCOLON name
+ {
+ char *name = copy_name ($2);
+ struct symbol *sym;
+ struct minimal_symbol *msymbol;
+
+ sym =
+ lookup_symbol (name, (const struct block *) NULL,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ if (sym)
+ {
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ write_exp_elt_block (NULL);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ break;
+ }
+
+ msymbol = lookup_minimal_symbol (name, NULL, NULL);
+ if (msymbol != NULL)
+ {
+ write_exp_msymbol (msymbol,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
+ }
+ else
+ if (!have_full_symbols () && !have_partial_symbols ())
+ error ("No symbol table is loaded. Use the \"file\" command.");
+ else
+ error ("No symbol \"%s\" in current context.", name);
+ }
+ ;
+
+variable: name_not_typename
+ { struct symbol *sym = $1.sym;
+
+ if (sym)
+ {
+ if (symbol_read_needs_frame (sym))
+ {
+ if (innermost_block == 0 ||
+ contained_in (block_found,
+ innermost_block))
+ innermost_block = block_found;
+ }
+
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ /* We want to use the selected frame, not
+ another more inner frame which happens to
+ be in the same block. */
+ write_exp_elt_block (NULL);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ current_type = sym->type; }
+ else if ($1.is_a_field_of_this)
+ {
+ struct value * this_val;
+ struct type * this_type;
+ /* Object pascal: it hangs off of `this'. Must
+ not inadvertently convert from a method call
+ to data ref. */
+ if (innermost_block == 0 ||
+ contained_in (block_found, innermost_block))
+ innermost_block = block_found;
+ write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (OP_THIS);
+ write_exp_elt_opcode (STRUCTOP_PTR);
+ write_exp_string ($1.stoken);
+ write_exp_elt_opcode (STRUCTOP_PTR);
+ /* we need type of this */
+ this_val = value_of_this (0);
+ if (this_val)
+ this_type = this_val->type;
+ else
+ this_type = NULL;
+ if (this_type)
+ current_type = lookup_struct_elt_type (
+ this_type,
+ $1.stoken.ptr, false);
+ else
+ current_type = NULL;
+ }
+ else
+ {
+ struct minimal_symbol *msymbol;
+ register char *arg = copy_name ($1.stoken);
+
+ msymbol =
+ lookup_minimal_symbol (arg, NULL, NULL);
+ if (msymbol != NULL)
+ {
+ write_exp_msymbol (msymbol,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
+ }
+ else if (!have_full_symbols () && !have_partial_symbols ())
+ error ("No symbol table is loaded. Use the \"file\" command.");
+ else
+ error ("No symbol \"%s\" in current context.",
+ copy_name ($1.stoken));
+ }
+ }
+ ;
+
+
+ptype : typebase
+ ;
+
+/* We used to try to recognize more pointer to member types here, but
+ that didn't work (shift/reduce conflicts meant that these rules never
+ got executed). The problem is that
+ int (foo::bar::baz::bizzle)
+ is a function type but
+ int (foo::bar::baz::bizzle::*)
+ is a pointer to member type. Stroustrup loses again! */
+
+type : ptype
+ | typebase COLONCOLON '*'
+ { $$ = lookup_member_type (builtin_type_int, $1); }
+ ;
+
+typebase /* Implements (approximately): (type-qualifier)* type-specifier */
+ : TYPENAME
+ { $$ = $1.type; }
+ | STRUCT name
+ { $$ = lookup_struct (copy_name ($2),
+ expression_context_block); }
+ | CLASS name
+ { $$ = lookup_struct (copy_name ($2),
+ expression_context_block); }
+ /* "const" and "volatile" are curently ignored. A type qualifier
+ after the type is handled in the ptype rule. I think these could
+ be too. */
+ ;
+
+name : NAME { $$ = $1.stoken; }
+ | BLOCKNAME { $$ = $1.stoken; }
+ | TYPENAME { $$ = $1.stoken; }
+ | NAME_OR_INT { $$ = $1.stoken; }
+ ;
+
+name_not_typename : NAME
+ | BLOCKNAME
+/* These would be useful if name_not_typename was useful, but it is just
+ a fake for "variable", so these cause reduce/reduce conflicts because
+ the parser can't tell whether NAME_OR_INT is a name_not_typename (=variable,
+ =exp) or just an exp. If name_not_typename was ever used in an lvalue
+ context where only a name could occur, this might be useful.
+ | NAME_OR_INT
+ */
+ ;
+
+%%
+
+/* Take care of parsing a number (anything that starts with a digit).
+ Set yylval and return the token type; update lexptr.
+ LEN is the number of characters in it. */
+
+/*** Needs some error checking for the float case ***/
+
+static int
+parse_number (p, len, parsed_float, putithere)
+ register char *p;
+ register int len;
+ int parsed_float;
+ YYSTYPE *putithere;
+{
+ /* FIXME: Shouldn't these be unsigned? We don't deal with negative values
+ here, and we do kind of silly things like cast to unsigned. */
+ register LONGEST n = 0;
+ register LONGEST prevn = 0;
+ ULONGEST un;
+
+ register int i = 0;
+ register int c;
+ register int base = input_radix;
+ int unsigned_p = 0;
+
+ /* Number of "L" suffixes encountered. */
+ int long_p = 0;
+
+ /* We have found a "L" or "U" suffix. */
+ int found_suffix = 0;
+
+ ULONGEST high_bit;
+ struct type *signed_type;
+ struct type *unsigned_type;
+
+ if (parsed_float)
+ {
+ /* It's a float since it contains a point or an exponent. */
+ char c;
+ int num = 0; /* number of tokens scanned by scanf */
+ char saved_char = p[len];
+
+ p[len] = 0; /* null-terminate the token */
+ if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
+ num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval,&c);
+ else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
+ num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval,&c);
+ else
+ {
+#ifdef SCANF_HAS_LONG_DOUBLE
+ num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval,&c);
+#else
+ /* Scan it into a double, then assign it to the long double.
+ This at least wins with values representable in the range
+ of doubles. */
+ double temp;
+ num = sscanf (p, "%lg%c", &temp,&c);
+ putithere->typed_val_float.dval = temp;
+#endif
+ }
+ p[len] = saved_char; /* restore the input stream */
+ if (num != 1) /* check scanf found ONLY a float ... */
+ return ERROR;
+ /* See if it has `f' or `l' suffix (float or long double). */
+
+ c = tolower (p[len - 1]);
+
+ if (c == 'f')
+ putithere->typed_val_float.type = builtin_type_float;
+ else if (c == 'l')
+ putithere->typed_val_float.type = builtin_type_long_double;
+ else if (isdigit (c) || c == '.')
+ putithere->typed_val_float.type = builtin_type_double;
+ else
+ return ERROR;
+
+ return FLOAT;
+ }
+
+ /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
+ if (p[0] == '0')
+ switch (p[1])
+ {
+ case 'x':
+ case 'X':
+ if (len >= 3)
+ {
+ p += 2;
+ base = 16;
+ len -= 2;
+ }
+ break;
+
+ case 't':
+ case 'T':
+ case 'd':
+ case 'D':
+ if (len >= 3)
+ {
+ p += 2;
+ base = 10;
+ len -= 2;
+ }
+ break;
+
+ default:
+ base = 8;
+ break;
+ }
+
+ while (len-- > 0)
+ {
+ c = *p++;
+ if (c >= 'A' && c <= 'Z')
+ c += 'a' - 'A';
+ if (c != 'l' && c != 'u')
+ n *= base;
+ if (c >= '0' && c <= '9')
+ {
+ if (found_suffix)
+ return ERROR;
+ n += i = c - '0';
+ }
+ else
+ {
+ if (base > 10 && c >= 'a' && c <= 'f')
+ {
+ if (found_suffix)
+ return ERROR;
+ n += i = c - 'a' + 10;
+ }
+ else if (c == 'l')
+ {
+ ++long_p;
+ found_suffix = 1;
+ }
+ else if (c == 'u')
+ {
+ unsigned_p = 1;
+ found_suffix = 1;
+ }
+ else
+ return ERROR; /* Char not a digit */
+ }
+ if (i >= base)
+ return ERROR; /* Invalid digit in this base */
+
+ /* Portably test for overflow (only works for nonzero values, so make
+ a second check for zero). FIXME: Can't we just make n and prevn
+ unsigned and avoid this? */
+ if (c != 'l' && c != 'u' && (prevn >= n) && n != 0)
+ unsigned_p = 1; /* Try something unsigned */
+
+ /* Portably test for unsigned overflow.
+ FIXME: This check is wrong; for example it doesn't find overflow
+ on 0x123456789 when LONGEST is 32 bits. */
+ if (c != 'l' && c != 'u' && n != 0)
+ {
+ if ((unsigned_p && (ULONGEST) prevn >= (ULONGEST) n))
+ error ("Numeric constant too large.");
+ }
+ prevn = n;
+ }
+
+ /* An integer constant is an int, a long, or a long long. An L
+ suffix forces it to be long; an LL suffix forces it to be long
+ long. If not forced to a larger size, it gets the first type of
+ the above that it fits in. To figure out whether it fits, we
+ shift it right and see whether anything remains. Note that we
+ can't shift sizeof (LONGEST) * HOST_CHAR_BIT bits or more in one
+ operation, because many compilers will warn about such a shift
+ (which always produces a zero result). Sometimes TARGET_INT_BIT
+ or TARGET_LONG_BIT will be that big, sometimes not. To deal with
+ the case where it is we just always shift the value more than
+ once, with fewer bits each time. */
+
+ un = (ULONGEST)n >> 2;
+ if (long_p == 0
+ && (un >> (TARGET_INT_BIT - 2)) == 0)
+ {
+ high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1);
+
+ /* A large decimal (not hex or octal) constant (between INT_MAX
+ and UINT_MAX) is a long or unsigned long, according to ANSI,
+ never an unsigned int, but this code treats it as unsigned
+ int. This probably should be fixed. GCC gives a warning on
+ such constants. */
+
+ unsigned_type = builtin_type_unsigned_int;
+ signed_type = builtin_type_int;
+ }
+ else if (long_p <= 1
+ && (un >> (TARGET_LONG_BIT - 2)) == 0)
+ {
+ high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1);
+ unsigned_type = builtin_type_unsigned_long;
+ signed_type = builtin_type_long;
+ }
+ else
+ {
+ int shift;
+ if (sizeof (ULONGEST) * HOST_CHAR_BIT < TARGET_LONG_LONG_BIT)
+ /* A long long does not fit in a LONGEST. */
+ shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1);
+ else
+ shift = (TARGET_LONG_LONG_BIT - 1);
+ high_bit = (ULONGEST) 1 << shift;
+ unsigned_type = builtin_type_unsigned_long_long;
+ signed_type = builtin_type_long_long;
+ }
+
+ putithere->typed_val_int.val = n;
+
+ /* If the high bit of the worked out type is set then this number
+ has to be unsigned. */
+
+ if (unsigned_p || (n & high_bit))
+ {
+ putithere->typed_val_int.type = unsigned_type;
+ }
+ else
+ {
+ putithere->typed_val_int.type = signed_type;
+ }
+
+ return INT;
+}
+
+
+struct type_push
+{
+ struct type *stored;
+ struct type_push *next;
+};
+
+static struct type_push *tp_top = NULL;
+
+static void push_current_type ()
+{
+ struct type_push *tpnew;
+ tpnew = (struct type_push *) malloc (sizeof (struct type_push));
+ tpnew->next = tp_top;
+ tpnew->stored = current_type;
+ current_type = NULL;
+ tp_top = tpnew;
+}
+
+static void pop_current_type ()
+{
+ struct type_push *tp = tp_top;
+ if (tp)
+ {
+ current_type = tp->stored;
+ tp_top = tp->next;
+ xfree (tp);
+ }
+}
+
+struct token
+{
+ char *operator;
+ int token;
+ enum exp_opcode opcode;
+};
+
+static const struct token tokentab3[] =
+ {
+ {"shr", RSH, BINOP_END},
+ {"shl", LSH, BINOP_END},
+ {"and", ANDAND, BINOP_END},
+ {"div", DIV, BINOP_END},
+ {"not", NOT, BINOP_END},
+ {"mod", MOD, BINOP_END},
+ {"inc", INCREMENT, BINOP_END},
+ {"dec", DECREMENT, BINOP_END},
+ {"xor", XOR, BINOP_END}
+ };
+
+static const struct token tokentab2[] =
+ {
+ {"or", OR, BINOP_END},
+ {"<>", NOTEQUAL, BINOP_END},
+ {"<=", LEQ, BINOP_END},
+ {">=", GEQ, BINOP_END},
+ {":=", ASSIGN, BINOP_END},
+ {"::", COLONCOLON, BINOP_END} };
+
+/* Allocate uppercased var */
+/* make an uppercased copy of tokstart */
+static char * uptok (tokstart, namelen)
+ char *tokstart;
+ int namelen;
+{
+ int i;
+ char *uptokstart = (char *)malloc(namelen+1);
+ for (i = 0;i <= namelen;i++)
+ {
+ if ((tokstart[i]>='a' && tokstart[i]<='z'))
+ uptokstart[i] = tokstart[i]-('a'-'A');
+ else
+ uptokstart[i] = tokstart[i];
+ }
+ uptokstart[namelen]='\0';
+ return uptokstart;
+}
+/* Read one token, getting characters through lexptr. */
+
+
+static int
+yylex ()
+{
+ int c;
+ int namelen;
+ unsigned int i;
+ char *tokstart;
+ char *uptokstart;
+ char *tokptr;
+ char *p;
+ int explen, tempbufindex;
+ static char *tempbuf;
+ static int tempbufsize;
+
+ retry:
+
+ prev_lexptr = lexptr;
+
+ tokstart = lexptr;
+ explen = strlen (lexptr);
+ /* See if it is a special token of length 3. */
+ if (explen > 2)
+ for (i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++)
+ if (strncasecmp (tokstart, tokentab3[i].operator, 3) == 0
+ && (!isalpha (tokentab3[i].operator[0]) || explen == 3
+ || (!isalpha (tokstart[3]) && !isdigit (tokstart[3]) && tokstart[3] != '_')))
+ {
+ lexptr += 3;
+ yylval.opcode = tokentab3[i].opcode;
+ return tokentab3[i].token;
+ }
+
+ /* See if it is a special token of length 2. */
+ if (explen > 1)
+ for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++)
+ if (strncasecmp (tokstart, tokentab2[i].operator, 2) == 0
+ && (!isalpha (tokentab2[i].operator[0]) || explen == 2
+ || (!isalpha (tokstart[2]) && !isdigit (tokstart[2]) && tokstart[2] != '_')))
+ {
+ lexptr += 2;
+ yylval.opcode = tokentab2[i].opcode;
+ return tokentab2[i].token;
+ }
+
+ switch (c = *tokstart)
+ {
+ case 0:
+ return 0;
+
+ case ' ':
+ case '\t':
+ case '\n':
+ lexptr++;
+ goto retry;
+
+ case '\'':
+ /* We either have a character constant ('0' or '\177' for example)
+ or we have a quoted symbol reference ('foo(int,int)' in object pascal
+ for example). */
+ lexptr++;
+ c = *lexptr++;
+ if (c == '\\')
+ c = parse_escape (&lexptr);
+ else if (c == '\'')
+ error ("Empty character constant.");
+
+ yylval.typed_val_int.val = c;
+ yylval.typed_val_int.type = builtin_type_char;
+
+ c = *lexptr++;
+ if (c != '\'')
+ {
+ namelen = skip_quoted (tokstart) - tokstart;
+ if (namelen > 2)
+ {
+ lexptr = tokstart + namelen;
+ if (lexptr[-1] != '\'')
+ error ("Unmatched single quote.");
+ namelen -= 2;
+ tokstart++;
+ uptokstart = uptok(tokstart,namelen);
+ goto tryname;
+ }
+ error ("Invalid character constant.");
+ }
+ return INT;
+
+ case '(':
+ paren_depth++;
+ lexptr++;
+ return c;
+
+ case ')':
+ if (paren_depth == 0)
+ return 0;
+ paren_depth--;
+ lexptr++;
+ return c;
+
+ case ',':
+ if (comma_terminates && paren_depth == 0)
+ return 0;
+ lexptr++;
+ return c;
+
+ case '.':
+ /* Might be a floating point number. */
+ if (lexptr[1] < '0' || lexptr[1] > '9')
+ goto symbol; /* Nope, must be a symbol. */
+ /* FALL THRU into number case. */
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ /* It's a number. */
+ int got_dot = 0, got_e = 0, toktype;
+ register char *p = tokstart;
+ int hex = input_radix > 10;
+
+ if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
+ {
+ p += 2;
+ hex = 1;
+ }
+ else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
+ {
+ p += 2;
+ hex = 0;
+ }
+
+ for (;; ++p)
+ {
+ /* This test includes !hex because 'e' is a valid hex digit
+ and thus does not indicate a floating point number when
+ the radix is hex. */
+ if (!hex && !got_e && (*p == 'e' || *p == 'E'))
+ got_dot = got_e = 1;
+ /* This test does not include !hex, because a '.' always indicates
+ a decimal floating point number regardless of the radix. */
+ else if (!got_dot && *p == '.')
+ got_dot = 1;
+ else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
+ && (*p == '-' || *p == '+'))
+ /* This is the sign of the exponent, not the end of the
+ number. */
+ continue;
+ /* We will take any letters or digits. parse_number will
+ complain if past the radix, or if L or U are not final. */
+ else if ((*p < '0' || *p > '9')
+ && ((*p < 'a' || *p > 'z')
+ && (*p < 'A' || *p > 'Z')))
+ break;
+ }
+ toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
+ if (toktype == ERROR)
+ {
+ char *err_copy = (char *) alloca (p - tokstart + 1);
+
+ memcpy (err_copy, tokstart, p - tokstart);
+ err_copy[p - tokstart] = 0;
+ error ("Invalid number \"%s\".", err_copy);
+ }
+ lexptr = p;
+ return toktype;
+ }
+
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '|':
+ case '&':
+ case '^':
+ case '~':
+ case '!':
+ case '@':
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case '?':
+ case ':':
+ case '=':
+ case '{':
+ case '}':
+ symbol:
+ lexptr++;
+ return c;
+
+ case '"':
+
+ /* Build the gdb internal form of the input string in tempbuf,
+ translating any standard C escape forms seen. Note that the
+ buffer is null byte terminated *only* for the convenience of
+ debugging gdb itself and printing the buffer contents when
+ the buffer contains no embedded nulls. Gdb does not depend
+ upon the buffer being null byte terminated, it uses the length
+ string instead. This allows gdb to handle C strings (as well
+ as strings in other languages) with embedded null bytes */
+
+ tokptr = ++tokstart;
+ tempbufindex = 0;
+
+ do {
+ /* Grow the static temp buffer if necessary, including allocating
+ the first one on demand. */
+ if (tempbufindex + 1 >= tempbufsize)
+ {
+ tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
+ }
+
+ switch (*tokptr)
+ {
+ case '\0':
+ case '"':
+ /* Do nothing, loop will terminate. */
+ break;
+ case '\\':
+ tokptr++;
+ c = parse_escape (&tokptr);
+ if (c == -1)
+ {
+ continue;
+ }
+ tempbuf[tempbufindex++] = c;
+ break;
+ default:
+ tempbuf[tempbufindex++] = *tokptr++;
+ break;
+ }
+ } while ((*tokptr != '"') && (*tokptr != '\0'));
+ if (*tokptr++ != '"')
+ {
+ error ("Unterminated string in expression.");
+ }
+ tempbuf[tempbufindex] = '\0'; /* See note above */
+ yylval.sval.ptr = tempbuf;
+ yylval.sval.length = tempbufindex;
+ lexptr = tokptr;
+ return (STRING);
+ }
+
+ if (!(c == '_' || c == '$'
+ || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
+ /* We must have come across a bad character (e.g. ';'). */
+ error ("Invalid character '%c' in expression.", c);
+
+ /* It's a name. See how long it is. */
+ namelen = 0;
+ for (c = tokstart[namelen];
+ (c == '_' || c == '$' || (c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');)
+ {
+ /* Template parameter lists are part of the name.
+ FIXME: This mishandles `print $a<4&&$a>3'. */
+ if (c == '<')
+ {
+ int i = namelen;
+ int nesting_level = 1;
+ while (tokstart[++i])
+ {
+ if (tokstart[i] == '<')
+ nesting_level++;
+ else if (tokstart[i] == '>')
+ {
+ if (--nesting_level == 0)
+ break;
+ }
+ }
+ if (tokstart[i] == '>')
+ namelen = i;
+ else
+ break;
+ }
+
+ /* do NOT uppercase internals because of registers !!! */
+ c = tokstart[++namelen];
+ }
+
+ uptokstart = uptok(tokstart,namelen);
+
+ /* The token "if" terminates the expression and is NOT
+ removed from the input stream. */
+ if (namelen == 2 && uptokstart[0] == 'I' && uptokstart[1] == 'F')
+ {
+ return 0;
+ }
+
+ lexptr += namelen;
+
+ tryname:
+
+ /* Catch specific keywords. Should be done with a data structure. */
+ switch (namelen)
+ {
+ case 6:
+ if (STREQ (uptokstart, "OBJECT"))
+ return CLASS;
+ if (STREQ (uptokstart, "RECORD"))
+ return STRUCT;
+ if (STREQ (uptokstart, "SIZEOF"))
+ return SIZEOF;
+ break;
+ case 5:
+ if (STREQ (uptokstart, "CLASS"))
+ return CLASS;
+ if (STREQ (uptokstart, "FALSE"))
+ {
+ yylval.lval = 0;
+ return FALSE;
+ }
+ break;
+ case 4:
+ if (STREQ (uptokstart, "TRUE"))
+ {
+ yylval.lval = 1;
+ return TRUE;
+ }
+ if (STREQ (uptokstart, "SELF"))
+ {
+ /* here we search for 'this' like
+ inserted in FPC stabs debug info */
+ static const char this_name[] =
+ { /* CPLUS_MARKER,*/ 't', 'h', 'i', 's', '\0' };
+
+ if (lookup_symbol (this_name, expression_context_block,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL))
+ return THIS;
+ }
+ break;
+ default:
+ break;
+ }
+
+ yylval.sval.ptr = tokstart;
+ yylval.sval.length = namelen;
+
+ if (*tokstart == '$')
+ {
+ /* $ is the normal prefix for pascal hexadecimal values
+ but this conflicts with the GDB use for debugger variables
+ so in expression to enter hexadecimal values
+ we still need to use C syntax with 0xff */
+ write_dollar_variable (yylval.sval);
+ return VARIABLE;
+ }
+
+ /* Use token-type BLOCKNAME for symbols that happen to be defined as
+ functions or symtabs. If this is not so, then ...
+ Use token-type TYPENAME for symbols that happen to be defined
+ currently as names of types; NAME for other symbols.
+ The caller is not constrained to care about the distinction. */
+ {
+ char *tmp = copy_name (yylval.sval);
+ struct symbol *sym;
+ int is_a_field_of_this = 0;
+ int is_a_field = 0;
+ int hextype;
+
+
+ if (search_field && current_type)
+ is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL);
+ if (is_a_field)
+ sym = NULL;
+ else
+ sym = lookup_symbol (tmp, expression_context_block,
+ VAR_NAMESPACE,
+ &is_a_field_of_this,
+ (struct symtab **) NULL);
+ /* second chance uppercased (as Free Pascal does). */
+ if (!sym && !is_a_field_of_this && !is_a_field)
+ {
+ for (i = 0; i <= namelen; i++)
+ {
+ if ((tmp[i] >= 'a' && tmp[i] <= 'z'))
+ tmp[i] -= ('a'-'A');
+ }
+ if (search_field && current_type)
+ is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL);
+ if (is_a_field)
+ sym = NULL;
+ else
+ sym = lookup_symbol (tmp, expression_context_block,
+ VAR_NAMESPACE,
+ &is_a_field_of_this,
+ (struct symtab **) NULL);
+ if (sym || is_a_field_of_this || is_a_field)
+ for (i = 0; i <= namelen; i++)
+ {
+ if ((tokstart[i] >= 'a' && tokstart[i] <= 'z'))
+ tokstart[i] -= ('a'-'A');
+ }
+ }
+ /* Third chance Capitalized (as GPC does). */
+ if (!sym && !is_a_field_of_this && !is_a_field)
+ {
+ for (i = 0; i <= namelen; i++)
+ {
+ if (i == 0)
+ {
+ if ((tmp[i] >= 'a' && tmp[i] <= 'z'))
+ tmp[i] -= ('a'-'A');
+ }
+ else
+ if ((tmp[i] >= 'A' && tmp[i] <= 'Z'))
+ tmp[i] -= ('A'-'a');
+ }
+ if (search_field && current_type)
+ is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL);
+ if (is_a_field)
+ sym = NULL;
+ else
+ sym = lookup_symbol (tmp, expression_context_block,
+ VAR_NAMESPACE,
+ &is_a_field_of_this,
+ (struct symtab **) NULL);
+ if (sym || is_a_field_of_this || is_a_field)
+ for (i = 0; i <= namelen; i++)
+ {
+ if (i == 0)
+ {
+ if ((tokstart[i] >= 'a' && tokstart[i] <= 'z'))
+ tokstart[i] -= ('a'-'A');
+ }
+ else
+ if ((tokstart[i] >= 'A' && tokstart[i] <= 'Z'))
+ tokstart[i] -= ('A'-'a');
+ }
+ }
+
+ if (is_a_field)
+ {
+ tempbuf = (char *) realloc (tempbuf, namelen + 1);
+ strncpy (tempbuf, tokstart, namelen); tempbuf [namelen] = 0;
+ yylval.sval.ptr = tempbuf;
+ yylval.sval.length = namelen;
+ return FIELDNAME;
+ }
+ /* Call lookup_symtab, not lookup_partial_symtab, in case there are
+ no psymtabs (coff, xcoff, or some future change to blow away the
+ psymtabs once once symbols are read). */
+ if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) ||
+ lookup_symtab (tmp))
+ {
+ yylval.ssym.sym = sym;
+ yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+ return BLOCKNAME;
+ }
+ if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+ {
+#if 1
+ /* Despite the following flaw, we need to keep this code enabled.
+ Because we can get called from check_stub_method, if we don't
+ handle nested types then it screws many operations in any
+ program which uses nested types. */
+ /* In "A::x", if x is a member function of A and there happens
+ to be a type (nested or not, since the stabs don't make that
+ distinction) named x, then this code incorrectly thinks we
+ are dealing with nested types rather than a member function. */
+
+ char *p;
+ char *namestart;
+ struct symbol *best_sym;
+
+ /* Look ahead to detect nested types. This probably should be
+ done in the grammar, but trying seemed to introduce a lot
+ of shift/reduce and reduce/reduce conflicts. It's possible
+ that it could be done, though. Or perhaps a non-grammar, but
+ less ad hoc, approach would work well. */
+
+ /* Since we do not currently have any way of distinguishing
+ a nested type from a non-nested one (the stabs don't tell
+ us whether a type is nested), we just ignore the
+ containing type. */
+
+ p = lexptr;
+ best_sym = sym;
+ while (1)
+ {
+ /* Skip whitespace. */
+ while (*p == ' ' || *p == '\t' || *p == '\n')
+ ++p;
+ if (*p == ':' && p[1] == ':')
+ {
+ /* Skip the `::'. */
+ p += 2;
+ /* Skip whitespace. */
+ while (*p == ' ' || *p == '\t' || *p == '\n')
+ ++p;
+ namestart = p;
+ while (*p == '_' || *p == '$' || (*p >= '0' && *p <= '9')
+ || (*p >= 'a' && *p <= 'z')
+ || (*p >= 'A' && *p <= 'Z'))
+ ++p;
+ if (p != namestart)
+ {
+ struct symbol *cur_sym;
+ /* As big as the whole rest of the expression, which is
+ at least big enough. */
+ char *ncopy = alloca (strlen (tmp)+strlen (namestart)+3);
+ char *tmp1;
+
+ tmp1 = ncopy;
+ memcpy (tmp1, tmp, strlen (tmp));
+ tmp1 += strlen (tmp);
+ memcpy (tmp1, "::", 2);
+ tmp1 += 2;
+ memcpy (tmp1, namestart, p - namestart);
+ tmp1[p - namestart] = '\0';
+ cur_sym = lookup_symbol (ncopy, expression_context_block,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ if (cur_sym)
+ {
+ if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF)
+ {
+ best_sym = cur_sym;
+ lexptr = p;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+
+ yylval.tsym.type = SYMBOL_TYPE (best_sym);
+#else /* not 0 */
+ yylval.tsym.type = SYMBOL_TYPE (sym);
+#endif /* not 0 */
+ return TYPENAME;
+ }
+ if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
+ return TYPENAME;
+
+ /* Input names that aren't symbols but ARE valid hex numbers,
+ when the input radix permits them, can be names or numbers
+ depending on the parse. Note we support radixes > 16 here. */
+ if (!sym &&
+ ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
+ (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
+ {
+ YYSTYPE newlval; /* Its value is ignored. */
+ hextype = parse_number (tokstart, namelen, 0, &newlval);
+ if (hextype == INT)
+ {
+ yylval.ssym.sym = sym;
+ yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+ return NAME_OR_INT;
+ }
+ }
+
+ free(uptokstart);
+ /* Any other kind of symbol */
+ yylval.ssym.sym = sym;
+ yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+ return NAME;
+ }
+}
+
+void
+yyerror (msg)
+ char *msg;
+{
+ if (prev_lexptr)
+ lexptr = prev_lexptr;
+
+ error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
+}
diff --git a/gdb/p-lang.c b/gdb/p-lang.c
new file mode 100644
index 00000000000..8e13b6e860a
--- /dev/null
+++ b/gdb/p-lang.c
@@ -0,0 +1,478 @@
+/* Pascal language support routines for GDB, the GNU debugger.
+ Copyright 2000, 2002 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. */
+
+/* This file is derived from c-lang.c */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "p-lang.h"
+#include "valprint.h"
+#include <ctype.h>
+
+extern void _initialize_pascal_language (void);
+
+
+/* Determines if type TYPE is a pascal string type.
+ Returns 1 if the type is a known pascal type
+ This function is used by p-valprint.c code to allow better string display.
+ If it is a pascal string type, then it also sets info needed
+ to get the length and the data of the string
+ length_pos, length_size and string_pos are given in bytes.
+ char_size gives the element size in bytes.
+ FIXME: if the position or the size of these fields
+ are not multiple of TARGET_CHAR_BIT then the results are wrong
+ but this does not happen for Free Pascal nor for GPC. */
+int
+is_pascal_string_type (struct type *type,int *length_pos,
+ int *length_size, int *string_pos, int *char_size,
+ char **arrayname)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+ {
+ /* Old Borland type pascal strings from Free Pascal Compiler. */
+ /* Two fields: length and st. */
+ if (TYPE_NFIELDS (type) == 2
+ && strcmp (TYPE_FIELDS (type)[0].name, "length") == 0
+ && strcmp (TYPE_FIELDS (type)[1].name, "st") == 0)
+ {
+ if (length_pos)
+ *length_pos = TYPE_FIELD_BITPOS (type, 0) / TARGET_CHAR_BIT;
+ if (length_size)
+ *length_size = TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0));
+ if (string_pos)
+ *string_pos = TYPE_FIELD_BITPOS (type, 1) / TARGET_CHAR_BIT;
+ if (char_size)
+ *char_size = 1;
+ if (arrayname)
+ *arrayname = TYPE_FIELDS (type)[1].name;
+ return 2;
+ };
+ /* GNU pascal strings. */
+ /* Three fields: Capacity, length and schema$ or _p_schema. */
+ if (TYPE_NFIELDS (type) == 3
+ && strcmp (TYPE_FIELDS (type)[0].name, "Capacity") == 0
+ && strcmp (TYPE_FIELDS (type)[1].name, "length") == 0)
+ {
+ if (length_pos)
+ *length_pos = TYPE_FIELD_BITPOS (type, 1) / TARGET_CHAR_BIT;
+ if (length_size)
+ *length_size = TYPE_LENGTH (TYPE_FIELD_TYPE (type, 1));
+ if (string_pos)
+ *string_pos = TYPE_FIELD_BITPOS (type, 2) / TARGET_CHAR_BIT;
+ /* FIXME: how can I detect wide chars in GPC ?? */
+ if (char_size)
+ *char_size = 1;
+ if (arrayname)
+ *arrayname = TYPE_FIELDS (type)[2].name;
+ return 3;
+ };
+ }
+ return 0;
+}
+
+static void pascal_one_char (int, struct ui_file *, int *);
+
+/* Print the character C on STREAM as part of the contents of a literal
+ string.
+ In_quotes is reset to 0 if a char is written with #4 notation */
+
+static void
+pascal_one_char (register int c, struct ui_file *stream, int *in_quotes)
+{
+
+ c &= 0xFF; /* Avoid sign bit follies */
+
+ if ((c == '\'') || (PRINT_LITERAL_FORM (c)))
+ {
+ if (!(*in_quotes))
+ fputs_filtered ("'", stream);
+ *in_quotes = 1;
+ if (c == '\'')
+ {
+ fputs_filtered ("''", stream);
+ }
+ else
+ fprintf_filtered (stream, "%c", c);
+ }
+ else
+ {
+ if (*in_quotes)
+ fputs_filtered ("'", stream);
+ *in_quotes = 0;
+ fprintf_filtered (stream, "#%d", (unsigned int) c);
+ }
+}
+
+static void pascal_emit_char (int c, struct ui_file *stream, int quoter);
+
+/* Print the character C on STREAM as part of the contents of a literal
+ string whose delimiter is QUOTER. Note that that format for printing
+ characters and strings is language specific. */
+
+static void
+pascal_emit_char (register int c, struct ui_file *stream, int quoter)
+{
+ int in_quotes = 0;
+ pascal_one_char (c, stream, &in_quotes);
+ if (in_quotes)
+ fputs_filtered ("'", stream);
+}
+
+void
+pascal_printchar (int c, struct ui_file *stream)
+{
+ int in_quotes = 0;
+ pascal_one_char (c, stream, &in_quotes);
+ if (in_quotes)
+ fputs_filtered ("'", stream);
+}
+
+/* Print the character string STRING, printing at most LENGTH characters.
+ Printing stops early if the number hits print_max; repeat counts
+ are printed as appropriate. Print ellipses at the end if we
+ had to stop before printing LENGTH characters, or if FORCE_ELLIPSES. */
+
+void
+pascal_printstr (struct ui_file *stream, char *string, unsigned int length,
+ int width, int force_ellipses)
+{
+ register unsigned int i;
+ unsigned int things_printed = 0;
+ int in_quotes = 0;
+ int need_comma = 0;
+ extern int inspect_it;
+
+ /* If the string was not truncated due to `set print elements', and
+ the last byte of it is a null, we don't print that, in traditional C
+ style. */
+ if ((!force_ellipses) && length > 0 && string[length - 1] == '\0')
+ length--;
+
+ if (length == 0)
+ {
+ fputs_filtered ("''", stream);
+ return;
+ }
+
+ for (i = 0; i < length && things_printed < print_max; ++i)
+ {
+ /* Position of the character we are examining
+ to see whether it is repeated. */
+ unsigned int rep1;
+ /* Number of repetitions we have detected so far. */
+ unsigned int reps;
+
+ QUIT;
+
+ if (need_comma)
+ {
+ fputs_filtered (", ", stream);
+ need_comma = 0;
+ }
+
+ rep1 = i + 1;
+ reps = 1;
+ while (rep1 < length && string[rep1] == string[i])
+ {
+ ++rep1;
+ ++reps;
+ }
+
+ if (reps > repeat_count_threshold)
+ {
+ if (in_quotes)
+ {
+ if (inspect_it)
+ fputs_filtered ("\\', ", stream);
+ else
+ fputs_filtered ("', ", stream);
+ in_quotes = 0;
+ }
+ pascal_printchar (string[i], stream);
+ fprintf_filtered (stream, " <repeats %u times>", reps);
+ i = rep1 - 1;
+ things_printed += repeat_count_threshold;
+ need_comma = 1;
+ }
+ else
+ {
+ int c = string[i];
+ if ((!in_quotes) && (PRINT_LITERAL_FORM (c)))
+ {
+ if (inspect_it)
+ fputs_filtered ("\\'", stream);
+ else
+ fputs_filtered ("'", stream);
+ in_quotes = 1;
+ }
+ pascal_one_char (c, stream, &in_quotes);
+ ++things_printed;
+ }
+ }
+
+ /* Terminate the quotes if necessary. */
+ if (in_quotes)
+ {
+ if (inspect_it)
+ fputs_filtered ("\\'", stream);
+ else
+ fputs_filtered ("'", stream);
+ }
+
+ if (force_ellipses || i < length)
+ fputs_filtered ("...", stream);
+}
+
+/* Create a fundamental Pascal type using default reasonable for the current
+ target machine.
+
+ Some object/debugging file formats (DWARF version 1, COFF, etc) do not
+ define fundamental types such as "int" or "double". Others (stabs or
+ DWARF version 2, etc) do define fundamental types. For the formats which
+ don't provide fundamental types, gdb can create such types using this
+ function.
+
+ FIXME: Some compilers distinguish explicitly signed integral types
+ (signed short, signed int, signed long) from "regular" integral types
+ (short, int, long) in the debugging information. There is some dis-
+ agreement as to how useful this feature is. In particular, gcc does
+ not support this. Also, only some debugging formats allow the
+ distinction to be passed on to a debugger. For now, we always just
+ use "short", "int", or "long" as the type name, for both the implicit
+ and explicitly signed types. This also makes life easier for the
+ gdb test suite since we don't have to account for the differences
+ in output depending upon what the compiler and debugging format
+ support. We will probably have to re-examine the issue when gdb
+ starts taking it's fundamental type information directly from the
+ debugging information supplied by the compiler. fnf@cygnus.com */
+
+/* Note there might be some discussion about the choosen correspondance
+ because it mainly reflects Free Pascal Compiler setup for now PM */
+
+
+struct type *
+pascal_create_fundamental_type (struct objfile *objfile, int typeid)
+{
+ register struct type *type = NULL;
+
+ switch (typeid)
+ {
+ default:
+ /* FIXME: For now, if we are asked to produce a type not in this
+ language, create the equivalent of a C integer type with the
+ name "<?type?>". When all the dust settles from the type
+ reconstruction work, this should probably become an error. */
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "<?type?>", objfile);
+ warning ("internal error: no Pascal fundamental type %d", typeid);
+ break;
+ case FT_VOID:
+ type = init_type (TYPE_CODE_VOID,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "void", objfile);
+ break;
+ case FT_CHAR:
+ type = init_type (TYPE_CODE_CHAR,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "char", objfile);
+ break;
+ case FT_SIGNED_CHAR:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ 0, "shortint", objfile);
+ break;
+ case FT_UNSIGNED_CHAR:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "byte", objfile);
+ break;
+ case FT_SHORT:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ 0, "integer", objfile);
+ break;
+ case FT_SIGNED_SHORT:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ 0, "integer", objfile); /* FIXME-fnf */
+ break;
+ case FT_UNSIGNED_SHORT:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "word", objfile);
+ break;
+ case FT_INTEGER:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "longint", objfile);
+ break;
+ case FT_SIGNED_INTEGER:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "longint", objfile); /* FIXME -fnf */
+ break;
+ case FT_UNSIGNED_INTEGER:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_INT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "cardinal", objfile);
+ break;
+ case FT_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "long", objfile);
+ break;
+ case FT_SIGNED_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "long", objfile); /* FIXME -fnf */
+ break;
+ case FT_UNSIGNED_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned long", objfile);
+ break;
+ case FT_LONG_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "long long", objfile);
+ break;
+ case FT_SIGNED_LONG_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "signed long long", objfile);
+ break;
+ case FT_UNSIGNED_LONG_LONG:
+ type = init_type (TYPE_CODE_INT,
+ TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned long long", objfile);
+ break;
+ case FT_FLOAT:
+ type = init_type (TYPE_CODE_FLT,
+ TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+ 0, "float", objfile);
+ break;
+ case FT_DBL_PREC_FLOAT:
+ type = init_type (TYPE_CODE_FLT,
+ TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "double", objfile);
+ break;
+ case FT_EXT_PREC_FLOAT:
+ type = init_type (TYPE_CODE_FLT,
+ TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+ 0, "extended", objfile);
+ break;
+ }
+ return (type);
+}
+
+
+/* Table mapping opcodes into strings for printing operators
+ and precedences of the operators. */
+
+const struct op_print pascal_op_print_tab[] =
+{
+ {",", BINOP_COMMA, PREC_COMMA, 0},
+ {":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
+ {"or", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
+ {"xor", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
+ {"and", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
+ {"=", BINOP_EQUAL, PREC_EQUAL, 0},
+ {"<>", BINOP_NOTEQUAL, PREC_EQUAL, 0},
+ {"<=", BINOP_LEQ, PREC_ORDER, 0},
+ {">=", BINOP_GEQ, PREC_ORDER, 0},
+ {">", BINOP_GTR, PREC_ORDER, 0},
+ {"<", BINOP_LESS, PREC_ORDER, 0},
+ {"shr", BINOP_RSH, PREC_SHIFT, 0},
+ {"shl", BINOP_LSH, PREC_SHIFT, 0},
+ {"+", BINOP_ADD, PREC_ADD, 0},
+ {"-", BINOP_SUB, PREC_ADD, 0},
+ {"*", BINOP_MUL, PREC_MUL, 0},
+ {"/", BINOP_DIV, PREC_MUL, 0},
+ {"div", BINOP_INTDIV, PREC_MUL, 0},
+ {"mod", BINOP_REM, PREC_MUL, 0},
+ {"@", BINOP_REPEAT, PREC_REPEAT, 0},
+ {"-", UNOP_NEG, PREC_PREFIX, 0},
+ {"not", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
+ {"^", UNOP_IND, PREC_SUFFIX, 1},
+ {"@", UNOP_ADDR, PREC_PREFIX, 0},
+ {"sizeof", UNOP_SIZEOF, PREC_PREFIX, 0},
+ {NULL, 0, 0, 0}
+};
+
+struct type **const (pascal_builtin_types[]) =
+{
+ &builtin_type_int,
+ &builtin_type_long,
+ &builtin_type_short,
+ &builtin_type_char,
+ &builtin_type_float,
+ &builtin_type_double,
+ &builtin_type_void,
+ &builtin_type_long_long,
+ &builtin_type_signed_char,
+ &builtin_type_unsigned_char,
+ &builtin_type_unsigned_short,
+ &builtin_type_unsigned_int,
+ &builtin_type_unsigned_long,
+ &builtin_type_unsigned_long_long,
+ &builtin_type_long_double,
+ &builtin_type_complex,
+ &builtin_type_double_complex,
+ 0
+};
+
+const struct language_defn pascal_language_defn =
+{
+ "pascal", /* Language name */
+ language_pascal,
+ pascal_builtin_types,
+ range_check_on,
+ type_check_on,
+ case_sensitive_on,
+ pascal_parse,
+ pascal_error,
+ evaluate_subexp_standard,
+ pascal_printchar, /* Print a character constant */
+ pascal_printstr, /* Function to print string constant */
+ pascal_emit_char, /* Print a single char */
+ pascal_create_fundamental_type, /* Create fundamental type in this language */
+ pascal_print_type, /* Print a type using appropriate syntax */
+ pascal_val_print, /* Print a value using appropriate syntax */
+ pascal_value_print, /* Print a top-level value */
+ {"", "%", "b", ""}, /* Binary format info */
+ {"0%lo", "0", "o", ""}, /* Octal format info */
+ {"%ld", "", "d", ""}, /* Decimal format info */
+ {"$%lx", "$", "x", ""}, /* Hex format info */
+ pascal_op_print_tab, /* expression operators for printing */
+ 1, /* c-style arrays */
+ 0, /* String lower bound */
+ &builtin_type_char, /* Type of string elements */
+ LANG_MAGIC
+};
+
+void
+_initialize_pascal_language (void)
+{
+ add_language (&pascal_language_defn);
+}
diff --git a/gdb/p-lang.h b/gdb/p-lang.h
new file mode 100644
index 00000000000..39eb0435f09
--- /dev/null
+++ b/gdb/p-lang.h
@@ -0,0 +1,76 @@
+/* Pascal language support definitions for GDB, the GNU debugger.
+ Copyright 2000 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. */
+
+/* This file is derived from c-lang.h */
+
+struct value;
+
+extern int pascal_parse (void); /* Defined in p-exp.y */
+
+extern void pascal_error (char *); /* Defined in p-exp.y */
+
+/* Defined in p-typeprint.c */
+extern void pascal_print_type (struct type *, char *, struct ui_file *, int, int);
+
+extern int pascal_val_print (struct type *, char *, int, CORE_ADDR, struct ui_file *, int, int,
+ int, enum val_prettyprint);
+
+extern int pascal_value_print (struct value *, struct ui_file *, int, enum val_prettyprint);
+
+extern void pascal_type_print_method_args (char *, char *,
+ struct ui_file *);
+
+/* These are in p-lang.c: */
+
+extern int
+ is_pascal_string_type (struct type *, int *, int *, int *, int *, char **);
+
+extern void pascal_printchar (int, struct ui_file *);
+
+extern void pascal_printstr (struct ui_file *, char *, unsigned int, int, int);
+
+extern struct type *pascal_create_fundamental_type (struct objfile *, int);
+
+extern struct type **const (pascal_builtin_types[]);
+
+/* These are in p-typeprint.c: */
+
+extern void
+ pascal_type_print_base (struct type *, struct ui_file *, int, int);
+
+extern void
+ pascal_type_print_varspec_prefix (struct type *, struct ui_file *, int, int);
+
+/* These are in cp-valprint.c */
+
+extern int vtblprint; /* Controls printing of vtbl's */
+
+extern int static_field_print;
+
+extern void pascal_object_print_class_member (char *, struct type *, struct ui_file *, char *);
+
+extern void pascal_object_print_class_method (char *, struct type *, struct ui_file *);
+
+extern void pascal_object_print_value_fields (struct type *, char *, CORE_ADDR,
+ struct ui_file *, int, int, enum val_prettyprint,
+ struct type **, int);
+
+extern int pascal_object_is_vtbl_ptr_type (struct type *);
+
+extern int pascal_object_is_vtbl_member (struct type *);
diff --git a/gdb/p-typeprint.c b/gdb/p-typeprint.c
new file mode 100644
index 00000000000..e8de7884f1d
--- /dev/null
+++ b/gdb/p-typeprint.c
@@ -0,0 +1,817 @@
+/* Support for printing Pascal types for GDB, the GNU debugger.
+ Copyright 2000, 2001, 2002
+ 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. */
+
+/* This file is derived from p-typeprint.c */
+
+#include "defs.h"
+#include "obstack.h"
+#include "bfd.h" /* Binary File Description */
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "language.h"
+#include "p-lang.h"
+#include "typeprint.h"
+
+#include "gdb_string.h"
+#include <errno.h>
+#include <ctype.h>
+
+static void pascal_type_print_varspec_suffix (struct type *, struct ui_file *, int, int, int);
+
+static void pascal_type_print_derivation_info (struct ui_file *, struct type *);
+
+void pascal_type_print_varspec_prefix (struct type *, struct ui_file *, int, int);
+
+
+/* LEVEL is the depth to indent lines by. */
+
+void
+pascal_print_type (struct type *type, char *varstring, struct ui_file *stream,
+ int show, int level)
+{
+ register enum type_code code;
+ int demangled_args;
+
+ code = TYPE_CODE (type);
+
+ if (show > 0)
+ CHECK_TYPEDEF (type);
+
+ if ((code == TYPE_CODE_FUNC ||
+ code == TYPE_CODE_METHOD))
+ {
+ pascal_type_print_varspec_prefix (type, stream, show, 0);
+ }
+ /* first the name */
+ fputs_filtered (varstring, stream);
+
+ if ((varstring != NULL && *varstring != '\0') &&
+ !(code == TYPE_CODE_FUNC ||
+ code == TYPE_CODE_METHOD))
+ {
+ fputs_filtered (" : ", stream);
+ }
+
+ if (!(code == TYPE_CODE_FUNC ||
+ code == TYPE_CODE_METHOD))
+ {
+ pascal_type_print_varspec_prefix (type, stream, show, 0);
+ }
+
+ pascal_type_print_base (type, stream, show, level);
+ /* For demangled function names, we have the arglist as part of the name,
+ so don't print an additional pair of ()'s */
+
+ demangled_args = varstring ? strchr (varstring, '(') != NULL : 0;
+ pascal_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
+
+}
+
+/* If TYPE is a derived type, then print out derivation information.
+ Print only the actual base classes of this type, not the base classes
+ of the base classes. I.E. for the derivation hierarchy:
+
+ class A { int a; };
+ class B : public A {int b; };
+ class C : public B {int c; };
+
+ Print the type of class C as:
+
+ class C : public B {
+ int c;
+ }
+
+ Not as the following (like gdb used to), which is not legal C++ syntax for
+ derived types and may be confused with the multiple inheritance form:
+
+ class C : public B : public A {
+ int c;
+ }
+
+ In general, gdb should try to print the types as closely as possible to
+ the form that they appear in the source code. */
+
+static void
+pascal_type_print_derivation_info (struct ui_file *stream, struct type *type)
+{
+ char *name;
+ int i;
+
+ for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
+ {
+ fputs_filtered (i == 0 ? ": " : ", ", stream);
+ fprintf_filtered (stream, "%s%s ",
+ BASETYPE_VIA_PUBLIC (type, i) ? "public" : "private",
+ BASETYPE_VIA_VIRTUAL (type, i) ? " virtual" : "");
+ name = type_name_no_tag (TYPE_BASECLASS (type, i));
+ fprintf_filtered (stream, "%s", name ? name : "(null)");
+ }
+ if (i > 0)
+ {
+ fputs_filtered (" ", stream);
+ }
+}
+
+/* Print the Pascal method arguments ARGS to the file STREAM. */
+
+void
+pascal_type_print_method_args (char *physname, char *methodname,
+ struct ui_file *stream)
+{
+ int is_constructor = STREQN (physname, "__ct__", 6);
+ int is_destructor = STREQN (physname, "__dt__", 6);
+
+ if (is_constructor || is_destructor)
+ {
+ physname += 6;
+ }
+
+ fputs_filtered (methodname, stream);
+
+ if (physname && (*physname != 0))
+ {
+ int i = 0;
+ int len = 0;
+ char storec;
+ char *argname;
+ fputs_filtered (" (", stream);
+ /* we must demangle this */
+ while (isdigit (physname[0]))
+ {
+ while (isdigit (physname[len]))
+ {
+ len++;
+ }
+ i = strtol (physname, &argname, 0);
+ physname += len;
+ storec = physname[i];
+ physname[i] = 0;
+ fputs_filtered (physname, stream);
+ physname[i] = storec;
+ physname += i;
+ if (physname[0] != 0)
+ {
+ fputs_filtered (", ", stream);
+ }
+ }
+ fputs_filtered (")", stream);
+ }
+}
+
+/* Print any asterisks or open-parentheses needed before the
+ variable name (to describe its type).
+
+ On outermost call, pass 0 for PASSED_A_PTR.
+ On outermost call, SHOW > 0 means should ignore
+ any typename for TYPE and show its details.
+ SHOW is always zero on recursive calls. */
+
+void
+pascal_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
+ int show, int passed_a_ptr)
+{
+ char *name;
+ if (type == 0)
+ return;
+
+ if (TYPE_NAME (type) && show <= 0)
+ return;
+
+ QUIT;
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_PTR:
+ fprintf_filtered (stream, "^");
+ pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
+ break; /* pointer should be handled normally in pascal */
+
+ case TYPE_CODE_MEMBER:
+ if (passed_a_ptr)
+ fprintf_filtered (stream, "(");
+ pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+ fprintf_filtered (stream, " ");
+ name = type_name_no_tag (TYPE_DOMAIN_TYPE (type));
+ if (name)
+ fputs_filtered (name, stream);
+ else
+ pascal_type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, passed_a_ptr);
+ fprintf_filtered (stream, "::");
+ break;
+
+ case TYPE_CODE_METHOD:
+ if (passed_a_ptr)
+ fprintf_filtered (stream, "(");
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+ {
+ fprintf_filtered (stream, "function ");
+ }
+ else
+ {
+ fprintf_filtered (stream, "procedure ");
+ }
+
+ if (passed_a_ptr)
+ {
+ fprintf_filtered (stream, " ");
+ pascal_type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, passed_a_ptr);
+ fprintf_filtered (stream, "::");
+ }
+ break;
+
+ case TYPE_CODE_REF:
+ pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
+ fprintf_filtered (stream, "&");
+ break;
+
+ case TYPE_CODE_FUNC:
+ if (passed_a_ptr)
+ fprintf_filtered (stream, "(");
+
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+ {
+ fprintf_filtered (stream, "function ");
+ }
+ else
+ {
+ fprintf_filtered (stream, "procedure ");
+ }
+
+ break;
+
+ case TYPE_CODE_ARRAY:
+ if (passed_a_ptr)
+ fprintf_filtered (stream, "(");
+ fprintf_filtered (stream, "array ");
+ if (TYPE_LENGTH (type) >= 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
+ && TYPE_ARRAY_UPPER_BOUND_TYPE (type) != BOUND_CANNOT_BE_DETERMINED)
+ fprintf_filtered (stream, "[%d..%d] ",
+ TYPE_ARRAY_LOWER_BOUND_VALUE (type),
+ TYPE_ARRAY_UPPER_BOUND_VALUE (type)
+ );
+ fprintf_filtered (stream, "of ");
+ break;
+
+ case TYPE_CODE_UNDEF:
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_ERROR:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_SET:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_STRING:
+ case TYPE_CODE_BITSTRING:
+ case TYPE_CODE_COMPLEX:
+ case TYPE_CODE_TYPEDEF:
+ case TYPE_CODE_TEMPLATE:
+ /* These types need no prefix. They are listed here so that
+ gcc -Wall will reveal any types that haven't been handled. */
+ break;
+ default:
+ error ("type not handled in pascal_type_print_varspec_prefix()");
+ break;
+ }
+}
+
+static void
+pascal_print_func_args (struct type *type, struct ui_file *stream)
+{
+ int i, len = TYPE_NFIELDS (type);
+ if (len)
+ {
+ fprintf_filtered (stream, "(");
+ }
+ for (i = 0; i < len; i++)
+ {
+ if (i > 0)
+ {
+ fputs_filtered (", ", stream);
+ wrap_here (" ");
+ }
+ /* can we find if it is a var parameter ??
+ if ( TYPE_FIELD(type, i) == )
+ {
+ fprintf_filtered (stream, "var ");
+ } */
+ pascal_print_type (TYPE_FIELD_TYPE (type, i), "" /* TYPE_FIELD_NAME seems invalid ! */
+ ,stream, -1, 0);
+ }
+ if (len)
+ {
+ fprintf_filtered (stream, ")");
+ }
+}
+
+/* Print any array sizes, function arguments or close parentheses
+ needed after the variable name (to describe its type).
+ Args work like pascal_type_print_varspec_prefix. */
+
+static void
+pascal_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
+ int show, int passed_a_ptr,
+ int demangled_args)
+{
+ if (type == 0)
+ return;
+
+ if (TYPE_NAME (type) && show <= 0)
+ return;
+
+ QUIT;
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ if (passed_a_ptr)
+ fprintf_filtered (stream, ")");
+ break;
+
+ case TYPE_CODE_MEMBER:
+ if (passed_a_ptr)
+ fprintf_filtered (stream, ")");
+ pascal_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0);
+ break;
+
+ case TYPE_CODE_METHOD:
+ if (passed_a_ptr)
+ fprintf_filtered (stream, ")");
+ pascal_type_print_method_args ("",
+ "",
+ stream);
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+ {
+ fprintf_filtered (stream, " : ");
+ pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+ pascal_type_print_base (TYPE_TARGET_TYPE (type), stream, show, 0);
+ pascal_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
+ passed_a_ptr, 0);
+ }
+ break;
+
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_REF:
+ pascal_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1, 0);
+ break;
+
+ case TYPE_CODE_FUNC:
+ if (passed_a_ptr)
+ fprintf_filtered (stream, ")");
+ if (!demangled_args)
+ pascal_print_func_args (type, stream);
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+ {
+ fprintf_filtered (stream, " : ");
+ pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+ pascal_type_print_base (TYPE_TARGET_TYPE (type), stream, show, 0);
+ pascal_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
+ passed_a_ptr, 0);
+ }
+ break;
+
+ case TYPE_CODE_UNDEF:
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_ERROR:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_SET:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_STRING:
+ case TYPE_CODE_BITSTRING:
+ case TYPE_CODE_COMPLEX:
+ case TYPE_CODE_TYPEDEF:
+ case TYPE_CODE_TEMPLATE:
+ /* These types do not need a suffix. They are listed so that
+ gcc -Wall will report types that may not have been considered. */
+ break;
+ default:
+ error ("type not handled in pascal_type_print_varspec_suffix()");
+ break;
+ }
+}
+
+/* Print the name of the type (or the ultimate pointer target,
+ function value or array element), or the description of a
+ structure or union.
+
+ SHOW positive means print details about the type (e.g. enum values),
+ and print structure elements passing SHOW - 1 for show.
+ SHOW negative means just print the type name or struct tag if there is one.
+ If there is no name, print something sensible but concise like
+ "struct {...}".
+ SHOW zero means just print the type name or struct tag if there is one.
+ If there is no name, print something sensible but not as concise like
+ "struct {int x; int y;}".
+
+ LEVEL is the number of spaces to indent by.
+ We increase it for some recursive calls. */
+
+void
+pascal_type_print_base (struct type *type, struct ui_file *stream, int show,
+ int level)
+{
+ register int i;
+ register int len;
+ register int lastval;
+ enum
+ {
+ s_none, s_public, s_private, s_protected
+ }
+ section_type;
+ QUIT;
+
+ wrap_here (" ");
+ if (type == NULL)
+ {
+ fputs_filtered ("<type unknown>", stream);
+ return;
+ }
+
+ /* void pointer */
+ if ((TYPE_CODE (type) == TYPE_CODE_PTR) && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID))
+ {
+ fprintf_filtered (stream,
+ TYPE_NAME (type) ? TYPE_NAME (type) : "pointer");
+ return;
+ }
+ /* When SHOW is zero or less, and there is a valid type name, then always
+ just print the type name directly from the type. */
+
+ if (show <= 0
+ && TYPE_NAME (type) != NULL)
+ {
+ fputs_filtered (TYPE_NAME (type), stream);
+ return;
+ }
+
+ CHECK_TYPEDEF (type);
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_TYPEDEF:
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_MEMBER:
+ case TYPE_CODE_REF:
+ /* case TYPE_CODE_FUNC:
+ case TYPE_CODE_METHOD: */
+ pascal_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
+ break;
+
+ case TYPE_CODE_ARRAY:
+ /* pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+ pascal_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
+ pascal_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0); */
+ pascal_print_type (TYPE_TARGET_TYPE (type), NULL, stream, 0, 0);
+ break;
+
+ case TYPE_CODE_FUNC:
+ case TYPE_CODE_METHOD:
+ /*
+ pascal_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
+ only after args !! */
+ break;
+ case TYPE_CODE_STRUCT:
+ if (TYPE_TAG_NAME (type) != NULL)
+ {
+ fputs_filtered (TYPE_TAG_NAME (type), stream);
+ fputs_filtered (" = ", stream);
+ }
+ if (HAVE_CPLUS_STRUCT (type))
+ {
+ fprintf_filtered (stream, "class ");
+ }
+ else
+ {
+ fprintf_filtered (stream, "record ");
+ }
+ goto struct_union;
+
+ case TYPE_CODE_UNION:
+ if (TYPE_TAG_NAME (type) != NULL)
+ {
+ fputs_filtered (TYPE_TAG_NAME (type), stream);
+ fputs_filtered (" = ", stream);
+ }
+ fprintf_filtered (stream, "case <?> of ");
+
+ struct_union:
+ wrap_here (" ");
+ if (show < 0)
+ {
+ /* If we just printed a tag name, no need to print anything else. */
+ if (TYPE_TAG_NAME (type) == NULL)
+ fprintf_filtered (stream, "{...}");
+ }
+ else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
+ {
+ pascal_type_print_derivation_info (stream, type);
+
+ fprintf_filtered (stream, "\n");
+ if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
+ {
+ if (TYPE_STUB (type))
+ fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
+ else
+ fprintfi_filtered (level + 4, stream, "<no data fields>\n");
+ }
+
+ /* Start off with no specific section type, so we can print
+ one for the first field we find, and use that section type
+ thereafter until we find another type. */
+
+ section_type = s_none;
+
+ /* If there is a base class for this type,
+ do not print the field that it occupies. */
+
+ len = TYPE_NFIELDS (type);
+ for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+ {
+ QUIT;
+ /* Don't print out virtual function table. */
+ if (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5)
+ && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
+ continue;
+
+ /* If this is a pascal object or class we can print the
+ various section labels. */
+
+ if (HAVE_CPLUS_STRUCT (type))
+ {
+ if (TYPE_FIELD_PROTECTED (type, i))
+ {
+ if (section_type != s_protected)
+ {
+ section_type = s_protected;
+ fprintfi_filtered (level + 2, stream,
+ "protected\n");
+ }
+ }
+ else if (TYPE_FIELD_PRIVATE (type, i))
+ {
+ if (section_type != s_private)
+ {
+ section_type = s_private;
+ fprintfi_filtered (level + 2, stream, "private\n");
+ }
+ }
+ else
+ {
+ if (section_type != s_public)
+ {
+ section_type = s_public;
+ fprintfi_filtered (level + 2, stream, "public\n");
+ }
+ }
+ }
+
+ print_spaces_filtered (level + 4, stream);
+ if (TYPE_FIELD_STATIC (type, i))
+ {
+ fprintf_filtered (stream, "static ");
+ }
+ pascal_print_type (TYPE_FIELD_TYPE (type, i),
+ TYPE_FIELD_NAME (type, i),
+ stream, show - 1, level + 4);
+ if (!TYPE_FIELD_STATIC (type, i)
+ && TYPE_FIELD_PACKED (type, i))
+ {
+ /* It is a bitfield. This code does not attempt
+ to look at the bitpos and reconstruct filler,
+ unnamed fields. This would lead to misleading
+ results if the compiler does not put out fields
+ for such things (I don't know what it does). */
+ fprintf_filtered (stream, " : %d",
+ TYPE_FIELD_BITSIZE (type, i));
+ }
+ fprintf_filtered (stream, ";\n");
+ }
+
+ /* If there are both fields and methods, put a space between. */
+ len = TYPE_NFN_FIELDS (type);
+ if (len && section_type != s_none)
+ fprintf_filtered (stream, "\n");
+
+ /* Pbject pascal: print out the methods */
+
+ for (i = 0; i < len; i++)
+ {
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
+ int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i);
+ char *method_name = TYPE_FN_FIELDLIST_NAME (type, i);
+ char *name = type_name_no_tag (type);
+ /* this is GNU C++ specific
+ how can we know constructor/destructor?
+ It might work for GNU pascal */
+ for (j = 0; j < len2; j++)
+ {
+ char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
+
+ int is_constructor = STREQN (physname, "__ct__", 6);
+ int is_destructor = STREQN (physname, "__dt__", 6);
+
+ QUIT;
+ if (TYPE_FN_FIELD_PROTECTED (f, j))
+ {
+ if (section_type != s_protected)
+ {
+ section_type = s_protected;
+ fprintfi_filtered (level + 2, stream,
+ "protected\n");
+ }
+ }
+ else if (TYPE_FN_FIELD_PRIVATE (f, j))
+ {
+ if (section_type != s_private)
+ {
+ section_type = s_private;
+ fprintfi_filtered (level + 2, stream, "private\n");
+ }
+ }
+ else
+ {
+ if (section_type != s_public)
+ {
+ section_type = s_public;
+ fprintfi_filtered (level + 2, stream, "public\n");
+ }
+ }
+
+ print_spaces_filtered (level + 4, stream);
+ if (TYPE_FN_FIELD_STATIC_P (f, j))
+ fprintf_filtered (stream, "static ");
+ if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
+ {
+ /* Keep GDB from crashing here. */
+ fprintf_filtered (stream, "<undefined type> %s;\n",
+ TYPE_FN_FIELD_PHYSNAME (f, j));
+ break;
+ }
+
+ if (is_constructor)
+ {
+ fprintf_filtered (stream, "constructor ");
+ }
+ else if (is_destructor)
+ {
+ fprintf_filtered (stream, "destructor ");
+ }
+ else if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) != 0 &&
+ TYPE_CODE (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j))) != TYPE_CODE_VOID)
+ {
+ fprintf_filtered (stream, "function ");
+ }
+ else
+ {
+ fprintf_filtered (stream, "procedure ");
+ }
+ /* this does not work, no idea why !! */
+
+ pascal_type_print_method_args (physname,
+ method_name,
+ stream);
+
+ if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) != 0 &&
+ TYPE_CODE (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j))) != TYPE_CODE_VOID)
+ {
+ fputs_filtered (" : ", stream);
+ type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
+ "", stream, -1);
+ }
+ if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
+ fprintf_filtered (stream, "; virtual");
+
+ fprintf_filtered (stream, ";\n");
+ }
+ }
+ fprintfi_filtered (level, stream, "end");
+ }
+ break;
+
+ case TYPE_CODE_ENUM:
+ if (TYPE_TAG_NAME (type) != NULL)
+ {
+ fputs_filtered (TYPE_TAG_NAME (type), stream);
+ if (show > 0)
+ fputs_filtered (" ", stream);
+ }
+ /* enum is just defined by
+ type enume_name = (enum_member1,enum_member2,...) */
+ fprintf_filtered (stream, " = ");
+ wrap_here (" ");
+ if (show < 0)
+ {
+ /* If we just printed a tag name, no need to print anything else. */
+ if (TYPE_TAG_NAME (type) == NULL)
+ fprintf_filtered (stream, "(...)");
+ }
+ else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
+ {
+ fprintf_filtered (stream, "(");
+ len = TYPE_NFIELDS (type);
+ lastval = 0;
+ for (i = 0; i < len; i++)
+ {
+ QUIT;
+ if (i)
+ fprintf_filtered (stream, ", ");
+ wrap_here (" ");
+ fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+ if (lastval != TYPE_FIELD_BITPOS (type, i))
+ {
+ fprintf_filtered (stream, " := %d", TYPE_FIELD_BITPOS (type, i));
+ lastval = TYPE_FIELD_BITPOS (type, i);
+ }
+ lastval++;
+ }
+ fprintf_filtered (stream, ")");
+ }
+ break;
+
+ case TYPE_CODE_VOID:
+ fprintf_filtered (stream, "void");
+ break;
+
+ case TYPE_CODE_UNDEF:
+ fprintf_filtered (stream, "record <unknown>");
+ break;
+
+ case TYPE_CODE_ERROR:
+ fprintf_filtered (stream, "<unknown type>");
+ break;
+
+ /* this probably does not work for enums */
+ case TYPE_CODE_RANGE:
+ {
+ struct type *target = TYPE_TARGET_TYPE (type);
+ if (target == NULL)
+ target = builtin_type_long;
+ print_type_scalar (target, TYPE_LOW_BOUND (type), stream);
+ fputs_filtered ("..", stream);
+ print_type_scalar (target, TYPE_HIGH_BOUND (type), stream);
+ }
+ break;
+
+ case TYPE_CODE_SET:
+ fputs_filtered ("set of ", stream);
+ pascal_print_type (TYPE_INDEX_TYPE (type), "", stream,
+ show - 1, level);
+ break;
+
+ case TYPE_CODE_BITSTRING:
+ fputs_filtered ("BitString", stream);
+ break;
+
+ case TYPE_CODE_STRING:
+ fputs_filtered ("String", stream);
+ break;
+
+ default:
+ /* Handle types not explicitly handled by the other cases,
+ such as fundamental types. For these, just print whatever
+ the type name is, as recorded in the type itself. If there
+ is no type name, then complain. */
+ if (TYPE_NAME (type) != NULL)
+ {
+ fputs_filtered (TYPE_NAME (type), stream);
+ }
+ else
+ {
+ /* At least for dump_symtab, it is important that this not be
+ an error (). */
+ fprintf_filtered (stream, "<invalid unnamed pascal type code %d>",
+ TYPE_CODE (type));
+ }
+ break;
+ }
+}
diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
new file mode 100644
index 00000000000..c8060a237ac
--- /dev/null
+++ b/gdb/p-valprint.c
@@ -0,0 +1,1117 @@
+/* Support for printing Pascal values for GDB, the GNU debugger.
+ Copyright 2000, 2001
+ 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. */
+
+/* This file is derived from c-valprint.c */
+
+#include "defs.h"
+#include "obstack.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "demangle.h"
+#include "valprint.h"
+#include "typeprint.h"
+#include "language.h"
+#include "target.h"
+#include "annotate.h"
+#include "p-lang.h"
+#include "cp-abi.h"
+
+
+
+
+/* Print data of type TYPE located at VALADDR (within GDB), which came from
+ the inferior at address ADDRESS, onto stdio stream STREAM according to
+ FORMAT (a letter or 0 for natural format). The data at VALADDR is in
+ target byte order.
+
+ If the data are a string pointer, returns the number of string characters
+ printed.
+
+ If DEREF_REF is nonzero, then dereference references, otherwise just print
+ them like pointers.
+
+ The PRETTY parameter controls prettyprinting. */
+
+
+int
+pascal_val_print (struct type *type, char *valaddr, int embedded_offset,
+ CORE_ADDR address, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
+{
+ register unsigned int i = 0; /* Number of characters printed */
+ unsigned len;
+ struct type *elttype;
+ unsigned eltlen;
+ int length_pos, length_size, string_pos;
+ int char_size;
+ LONGEST val;
+ CORE_ADDR addr;
+
+ CHECK_TYPEDEF (type);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
+ {
+ elttype = check_typedef (TYPE_TARGET_TYPE (type));
+ eltlen = TYPE_LENGTH (elttype);
+ len = TYPE_LENGTH (type) / eltlen;
+ if (prettyprint_arrays)
+ {
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ /* For an array of chars, print with string syntax. */
+ if (eltlen == 1 &&
+ ((TYPE_CODE (elttype) == TYPE_CODE_INT)
+ || ((current_language->la_language == language_m2)
+ && (TYPE_CODE (elttype) == TYPE_CODE_CHAR)))
+ && (format == 0 || format == 's'))
+ {
+ /* If requested, look for the first null char and only print
+ elements up to it. */
+ if (stop_print_at_null)
+ {
+ unsigned int temp_len;
+
+ /* Look for a NULL char. */
+ for (temp_len = 0;
+ (valaddr + embedded_offset)[temp_len]
+ && temp_len < len && temp_len < print_max;
+ temp_len++);
+ len = temp_len;
+ }
+
+ LA_PRINT_STRING (stream, valaddr + embedded_offset, len, 1, 0);
+ i = len;
+ }
+ else
+ {
+ fprintf_filtered (stream, "{");
+ /* If this is a virtual function table, print the 0th
+ entry specially, and the rest of the members normally. */
+ if (pascal_object_is_vtbl_ptr_type (elttype))
+ {
+ i = 1;
+ fprintf_filtered (stream, "%d vtable entries", len - 1);
+ }
+ else
+ {
+ i = 0;
+ }
+ val_print_array_elements (type, valaddr + embedded_offset, address, stream,
+ format, deref_ref, recurse, pretty, i);
+ fprintf_filtered (stream, "}");
+ }
+ break;
+ }
+ /* Array of unspecified length: treat like pointer to first elt. */
+ addr = address;
+ goto print_unpacked_pointer;
+
+ case TYPE_CODE_PTR:
+ if (format && format != 's')
+ {
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+ break;
+ }
+ if (vtblprint && pascal_object_is_vtbl_ptr_type (type))
+ {
+ /* Print the unmangled name if desired. */
+ /* Print vtable entry - we only get here if we ARE using
+ -fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */
+ print_address_demangle (extract_address (valaddr + embedded_offset, TYPE_LENGTH (type)),
+ stream, demangle);
+ break;
+ }
+ elttype = check_typedef (TYPE_TARGET_TYPE (type));
+ if (TYPE_CODE (elttype) == TYPE_CODE_METHOD)
+ {
+ pascal_object_print_class_method (valaddr + embedded_offset, type, stream);
+ }
+ else if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
+ {
+ pascal_object_print_class_member (valaddr + embedded_offset,
+ TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),
+ stream, "&");
+ }
+ else
+ {
+ addr = unpack_pointer (type, valaddr + embedded_offset);
+ print_unpacked_pointer:
+ elttype = check_typedef (TYPE_TARGET_TYPE (type));
+
+ if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
+ {
+ /* Try to print what function it points to. */
+ print_address_demangle (addr, stream, demangle);
+ /* Return value is irrelevant except for string pointers. */
+ return (0);
+ }
+
+ if (addressprint && format != 's')
+ {
+ print_address_numeric (addr, 1, stream);
+ }
+
+ /* For a pointer to char or unsigned char, also print the string
+ pointed to, unless pointer is null. */
+ if (TYPE_LENGTH (elttype) == 1
+ && TYPE_CODE (elttype) == TYPE_CODE_INT
+ && (format == 0 || format == 's')
+ && addr != 0)
+ {
+ /* no wide string yet */
+ i = val_print_string (addr, -1, 1, stream);
+ }
+ /* also for pointers to pascal strings */
+ /* Note: this is Free Pascal specific:
+ as GDB does not recognize stabs pascal strings
+ Pascal strings are mapped to records
+ with lowercase names PM */
+ if (is_pascal_string_type (elttype, &length_pos, &length_size,
+ &string_pos, &char_size, NULL)
+ && addr != 0)
+ {
+ ULONGEST string_length;
+ void *buffer;
+ buffer = xmalloc (length_size);
+ read_memory (addr + length_pos, buffer, length_size);
+ string_length = extract_unsigned_integer (buffer, length_size);
+ xfree (buffer);
+ i = val_print_string (addr + string_pos, string_length, char_size, stream);
+ }
+ else if (pascal_object_is_vtbl_member (type))
+ {
+ /* print vtbl's nicely */
+ CORE_ADDR vt_address = unpack_pointer (type, valaddr + embedded_offset);
+
+ struct minimal_symbol *msymbol =
+ lookup_minimal_symbol_by_pc (vt_address);
+ if ((msymbol != NULL)
+ && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol)))
+ {
+ fputs_filtered (" <", stream);
+ fputs_filtered (SYMBOL_SOURCE_NAME (msymbol), stream);
+ fputs_filtered (">", stream);
+ }
+ if (vt_address && vtblprint)
+ {
+ struct value *vt_val;
+ struct symbol *wsym = (struct symbol *) NULL;
+ struct type *wtype;
+ struct symtab *s;
+ struct block *block = (struct block *) NULL;
+ int is_this_fld;
+
+ if (msymbol != NULL)
+ wsym = lookup_symbol (SYMBOL_NAME (msymbol), block,
+ VAR_NAMESPACE, &is_this_fld, &s);
+
+ if (wsym)
+ {
+ wtype = SYMBOL_TYPE (wsym);
+ }
+ else
+ {
+ wtype = TYPE_TARGET_TYPE (type);
+ }
+ vt_val = value_at (wtype, vt_address, NULL);
+ val_print (VALUE_TYPE (vt_val), VALUE_CONTENTS (vt_val), 0,
+ VALUE_ADDRESS (vt_val), stream, format,
+ deref_ref, recurse + 1, pretty);
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ }
+ }
+
+ /* Return number of characters printed, including the terminating
+ '\0' if we reached the end. val_print_string takes care including
+ the terminating '\0' if necessary. */
+ return i;
+ }
+ break;
+
+ case TYPE_CODE_MEMBER:
+ error ("not implemented: member type in pascal_val_print");
+ break;
+
+ case TYPE_CODE_REF:
+ elttype = check_typedef (TYPE_TARGET_TYPE (type));
+ if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
+ {
+ pascal_object_print_class_member (valaddr + embedded_offset,
+ TYPE_DOMAIN_TYPE (elttype),
+ stream, "");
+ break;
+ }
+ if (addressprint)
+ {
+ fprintf_filtered (stream, "@");
+ print_address_numeric
+ (extract_address (valaddr + embedded_offset,
+ TARGET_PTR_BIT / HOST_CHAR_BIT), 1, stream);
+ if (deref_ref)
+ fputs_filtered (": ", stream);
+ }
+ /* De-reference the reference. */
+ if (deref_ref)
+ {
+ if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
+ {
+ struct value *deref_val =
+ value_at
+ (TYPE_TARGET_TYPE (type),
+ unpack_pointer (lookup_pointer_type (builtin_type_void),
+ valaddr + embedded_offset),
+ NULL);
+ val_print (VALUE_TYPE (deref_val),
+ VALUE_CONTENTS (deref_val), 0,
+ VALUE_ADDRESS (deref_val), stream, format,
+ deref_ref, recurse + 1, pretty);
+ }
+ else
+ fputs_filtered ("???", stream);
+ }
+ break;
+
+ case TYPE_CODE_UNION:
+ if (recurse && !unionprint)
+ {
+ fprintf_filtered (stream, "{...}");
+ break;
+ }
+ /* Fall through. */
+ case TYPE_CODE_STRUCT:
+ if (vtblprint && pascal_object_is_vtbl_ptr_type (type))
+ {
+ /* Print the unmangled name if desired. */
+ /* Print vtable entry - we only get here if NOT using
+ -fvtable_thunks. (Otherwise, look under TYPE_CODE_PTR.) */
+ print_address_demangle (extract_address (
+ valaddr + embedded_offset + TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8,
+ TYPE_LENGTH (TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET))),
+ stream, demangle);
+ }
+ else
+ {
+ if (is_pascal_string_type (type, &length_pos, &length_size,
+ &string_pos, &char_size, NULL))
+ {
+ len = extract_unsigned_integer (valaddr + embedded_offset + length_pos, length_size);
+ LA_PRINT_STRING (stream, valaddr + embedded_offset + string_pos, len, char_size, 0);
+ }
+ else
+ pascal_object_print_value_fields (type, valaddr + embedded_offset, address, stream, format,
+ recurse, pretty, NULL, 0);
+ }
+ break;
+
+ case TYPE_CODE_ENUM:
+ if (format)
+ {
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+ break;
+ }
+ len = TYPE_NFIELDS (type);
+ val = unpack_long (type, valaddr + embedded_offset);
+ for (i = 0; i < len; i++)
+ {
+ QUIT;
+ if (val == TYPE_FIELD_BITPOS (type, i))
+ {
+ break;
+ }
+ }
+ if (i < len)
+ {
+ fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+ }
+ else
+ {
+ print_longest (stream, 'd', 0, val);
+ }
+ break;
+
+ case TYPE_CODE_FUNC:
+ if (format)
+ {
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+ break;
+ }
+ /* FIXME, we should consider, at least for ANSI C language, eliminating
+ the distinction made between FUNCs and POINTERs to FUNCs. */
+ fprintf_filtered (stream, "{");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, "} ");
+ /* Try to print what function it points to, and its address. */
+ print_address_demangle (address, stream, demangle);
+ break;
+
+ case TYPE_CODE_BOOL:
+ format = format ? format : output_format;
+ if (format)
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+ else
+ {
+ val = unpack_long (type, valaddr + embedded_offset);
+ if (val == 0)
+ fputs_filtered ("false", stream);
+ else if (val == 1)
+ fputs_filtered ("true", stream);
+ else
+ {
+ fputs_filtered ("true (", stream);
+ fprintf_filtered (stream, "%ld)", (long int) val);
+ }
+ }
+ break;
+
+ case TYPE_CODE_RANGE:
+ /* FIXME: create_range_type does not set the unsigned bit in a
+ range type (I think it probably should copy it from the target
+ type), so we won't print values which are too large to
+ fit in a signed integer correctly. */
+ /* FIXME: Doesn't handle ranges of enums correctly. (Can't just
+ print with the target type, though, because the size of our type
+ and the target type might differ). */
+ /* FALLTHROUGH */
+
+ case TYPE_CODE_INT:
+ format = format ? format : output_format;
+ if (format)
+ {
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+ }
+ else
+ {
+ val_print_type_code_int (type, valaddr + embedded_offset, stream);
+ }
+ break;
+
+ case TYPE_CODE_CHAR:
+ format = format ? format : output_format;
+ if (format)
+ {
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+ }
+ else
+ {
+ val = unpack_long (type, valaddr + embedded_offset);
+ if (TYPE_UNSIGNED (type))
+ fprintf_filtered (stream, "%u", (unsigned int) val);
+ else
+ fprintf_filtered (stream, "%d", (int) val);
+ fputs_filtered (" ", stream);
+ LA_PRINT_CHAR ((unsigned char) val, stream);
+ }
+ break;
+
+ case TYPE_CODE_FLT:
+ if (format)
+ {
+ print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+ }
+ else
+ {
+ print_floating (valaddr + embedded_offset, type, stream);
+ }
+ break;
+
+ case TYPE_CODE_BITSTRING:
+ case TYPE_CODE_SET:
+ elttype = TYPE_INDEX_TYPE (type);
+ CHECK_TYPEDEF (elttype);
+ if (TYPE_STUB (elttype))
+ {
+ fprintf_filtered (stream, "<incomplete type>");
+ gdb_flush (stream);
+ break;
+ }
+ else
+ {
+ struct type *range = elttype;
+ LONGEST low_bound, high_bound;
+ int i;
+ int is_bitstring = TYPE_CODE (type) == TYPE_CODE_BITSTRING;
+ int need_comma = 0;
+
+ if (is_bitstring)
+ fputs_filtered ("B'", stream);
+ else
+ fputs_filtered ("[", stream);
+
+ i = get_discrete_bounds (range, &low_bound, &high_bound);
+ maybe_bad_bstring:
+ if (i < 0)
+ {
+ fputs_filtered ("<error value>", stream);
+ goto done;
+ }
+
+ for (i = low_bound; i <= high_bound; i++)
+ {
+ int element = value_bit_index (type, valaddr + embedded_offset, i);
+ if (element < 0)
+ {
+ i = element;
+ goto maybe_bad_bstring;
+ }
+ if (is_bitstring)
+ fprintf_filtered (stream, "%d", element);
+ else if (element)
+ {
+ if (need_comma)
+ fputs_filtered (", ", stream);
+ print_type_scalar (range, i, stream);
+ need_comma = 1;
+
+ if (i + 1 <= high_bound && value_bit_index (type, valaddr + embedded_offset, ++i))
+ {
+ int j = i;
+ fputs_filtered ("..", stream);
+ while (i + 1 <= high_bound
+ && value_bit_index (type, valaddr + embedded_offset, ++i))
+ j = i;
+ print_type_scalar (range, j, stream);
+ }
+ }
+ }
+ done:
+ if (is_bitstring)
+ fputs_filtered ("'", stream);
+ else
+ fputs_filtered ("]", stream);
+ }
+ break;
+
+ case TYPE_CODE_VOID:
+ fprintf_filtered (stream, "void");
+ break;
+
+ case TYPE_CODE_ERROR:
+ fprintf_filtered (stream, "<error type>");
+ break;
+
+ case TYPE_CODE_UNDEF:
+ /* This happens (without TYPE_FLAG_STUB set) on systems which don't use
+ dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
+ and no complete type for struct foo in that file. */
+ fprintf_filtered (stream, "<incomplete type>");
+ break;
+
+ default:
+ error ("Invalid pascal type code %d in symbol table.", TYPE_CODE (type));
+ }
+ gdb_flush (stream);
+ return (0);
+}
+
+int
+pascal_value_print (struct value *val, struct ui_file *stream, int format,
+ enum val_prettyprint pretty)
+{
+ struct type *type = VALUE_TYPE (val);
+
+ /* If it is a pointer, indicate what it points to.
+
+ Print type also if it is a reference.
+
+ Object pascal: if it is a member pointer, we will take care
+ of that when we print it. */
+ if (TYPE_CODE (type) == TYPE_CODE_PTR ||
+ TYPE_CODE (type) == TYPE_CODE_REF)
+ {
+ /* Hack: remove (char *) for char strings. Their
+ type is indicated by the quoted string anyway. */
+ if (TYPE_CODE (type) == TYPE_CODE_PTR &&
+ TYPE_NAME (type) == NULL &&
+ TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL &&
+ STREQ (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char"))
+ {
+ /* Print nothing */
+ }
+ else
+ {
+ fprintf_filtered (stream, "(");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, ") ");
+ }
+ }
+ return val_print (type, VALUE_CONTENTS (val), VALUE_EMBEDDED_OFFSET (val),
+ VALUE_ADDRESS (val) + VALUE_OFFSET (val),
+ stream, format, 1, 0, pretty);
+}
+
+
+/******************************************************************************
+ Inserted from cp-valprint
+******************************************************************************/
+
+extern int vtblprint; /* Controls printing of vtbl's */
+extern int objectprint; /* Controls looking up an object's derived type
+ using what we find in its vtables. */
+static int pascal_static_field_print; /* Controls printing of static fields. */
+
+static struct obstack dont_print_vb_obstack;
+static struct obstack dont_print_statmem_obstack;
+
+static void pascal_object_print_static_field (struct type *, struct value *,
+ struct ui_file *, int, int,
+ enum val_prettyprint);
+
+static void
+ pascal_object_print_value (struct type *, char *, CORE_ADDR, struct ui_file *,
+ int, int, enum val_prettyprint, struct type **);
+
+void
+pascal_object_print_class_method (char *valaddr, struct type *type,
+ struct ui_file *stream)
+{
+ struct type *domain;
+ struct fn_field *f = NULL;
+ int j = 0;
+ int len2;
+ int offset;
+ char *kind = "";
+ CORE_ADDR addr;
+ struct symbol *sym;
+ unsigned len;
+ unsigned int i;
+ struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
+
+ domain = TYPE_DOMAIN_TYPE (target_type);
+ if (domain == (struct type *) NULL)
+ {
+ fprintf_filtered (stream, "<unknown>");
+ return;
+ }
+ addr = unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr);
+ if (METHOD_PTR_IS_VIRTUAL (addr))
+ {
+ offset = METHOD_PTR_TO_VOFFSET (addr);
+ len = TYPE_NFN_FIELDS (domain);
+ for (i = 0; i < len; i++)
+ {
+ f = TYPE_FN_FIELDLIST1 (domain, i);
+ len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
+
+ for (j = 0; j < len2; j++)
+ {
+ QUIT;
+ if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
+ {
+ if (TYPE_FN_FIELD_STUB (f, j))
+ check_stub_method (domain, i, j);
+ kind = "virtual ";
+ goto common;
+ }
+ }
+ }
+ }
+ else
+ {
+ sym = find_pc_function (addr);
+ if (sym == 0)
+ {
+ error ("invalid pointer to member function");
+ }
+ len = TYPE_NFN_FIELDS (domain);
+ for (i = 0; i < len; i++)
+ {
+ f = TYPE_FN_FIELDLIST1 (domain, i);
+ len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
+
+ for (j = 0; j < len2; j++)
+ {
+ QUIT;
+ if (TYPE_FN_FIELD_STUB (f, j))
+ check_stub_method (domain, i, j);
+ if (STREQ (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
+ {
+ goto common;
+ }
+ }
+ }
+ }
+common:
+ if (i < len)
+ {
+ char *demangled_name;
+
+ fprintf_filtered (stream, "&");
+ fprintf_filtered (stream, kind);
+ demangled_name = cplus_demangle (TYPE_FN_FIELD_PHYSNAME (f, j),
+ DMGL_ANSI | DMGL_PARAMS);
+ if (demangled_name == NULL)
+ fprintf_filtered (stream, "<badly mangled name %s>",
+ TYPE_FN_FIELD_PHYSNAME (f, j));
+ else
+ {
+ fputs_filtered (demangled_name, stream);
+ xfree (demangled_name);
+ }
+ }
+ else
+ {
+ fprintf_filtered (stream, "(");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, ") %d", (int) addr >> 3);
+ }
+}
+
+/* It was changed to this after 2.4.5. */
+const char pascal_vtbl_ptr_name[] =
+{'_', '_', 'v', 't', 'b', 'l', '_', 'p', 't', 'r', '_', 't', 'y', 'p', 'e', 0};
+
+/* Return truth value for assertion that TYPE is of the type
+ "pointer to virtual function". */
+
+int
+pascal_object_is_vtbl_ptr_type (struct type *type)
+{
+ char *typename = type_name_no_tag (type);
+
+ return (typename != NULL
+ && (STREQ (typename, pascal_vtbl_ptr_name)));
+}
+
+/* Return truth value for the assertion that TYPE is of the type
+ "pointer to virtual function table". */
+
+int
+pascal_object_is_vtbl_member (struct type *type)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ type = TYPE_TARGET_TYPE (type);
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ type = TYPE_TARGET_TYPE (type);
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT /* if not using thunks */
+ || TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */
+ {
+ /* Virtual functions tables are full of pointers
+ to virtual functions. */
+ return pascal_object_is_vtbl_ptr_type (type);
+ }
+ }
+ }
+ return 0;
+}
+
+/* Mutually recursive subroutines of pascal_object_print_value and c_val_print to
+ print out a structure's fields: pascal_object_print_value_fields and pascal_object_print_value.
+
+ TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the
+ same meanings as in pascal_object_print_value and c_val_print.
+
+ DONT_PRINT is an array of baseclass types that we
+ should not print, or zero if called from top level. */
+
+void
+pascal_object_print_value_fields (struct type *type, char *valaddr,
+ CORE_ADDR address, struct ui_file *stream,
+ int format, int recurse,
+ enum val_prettyprint pretty,
+ struct type **dont_print_vb,
+ int dont_print_statmem)
+{
+ int i, len, n_baseclasses;
+ struct obstack tmp_obstack;
+ char *last_dont_print = obstack_next_free (&dont_print_statmem_obstack);
+
+ CHECK_TYPEDEF (type);
+
+ fprintf_filtered (stream, "{");
+ len = TYPE_NFIELDS (type);
+ n_baseclasses = TYPE_N_BASECLASSES (type);
+
+ /* Print out baseclasses such that we don't print
+ duplicates of virtual baseclasses. */
+ if (n_baseclasses > 0)
+ pascal_object_print_value (type, valaddr, address, stream,
+ format, recurse + 1, pretty, dont_print_vb);
+
+ if (!len && n_baseclasses == 1)
+ fprintf_filtered (stream, "<No data fields>");
+ else
+ {
+ extern int inspect_it;
+ int fields_seen = 0;
+
+ if (dont_print_statmem == 0)
+ {
+ /* If we're at top level, carve out a completely fresh
+ chunk of the obstack and use that until this particular
+ invocation returns. */
+ tmp_obstack = dont_print_statmem_obstack;
+ obstack_finish (&dont_print_statmem_obstack);
+ }
+
+ for (i = n_baseclasses; i < len; i++)
+ {
+ /* If requested, skip printing of static fields. */
+ if (!pascal_static_field_print && TYPE_FIELD_STATIC (type, i))
+ continue;
+ if (fields_seen)
+ fprintf_filtered (stream, ", ");
+ else if (n_baseclasses > 0)
+ {
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ fputs_filtered ("members of ", stream);
+ fputs_filtered (type_name_no_tag (type), stream);
+ fputs_filtered (": ", stream);
+ }
+ }
+ fields_seen = 1;
+
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ else
+ {
+ wrap_here (n_spaces (2 + 2 * recurse));
+ }
+ if (inspect_it)
+ {
+ if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)
+ fputs_filtered ("\"( ptr \"", stream);
+ else
+ fputs_filtered ("\"( nodef \"", stream);
+ if (TYPE_FIELD_STATIC (type, i))
+ fputs_filtered ("static ", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
+ fputs_filtered ("\" \"", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
+ fputs_filtered ("\") \"", stream);
+ }
+ else
+ {
+ annotate_field_begin (TYPE_FIELD_TYPE (type, i));
+
+ if (TYPE_FIELD_STATIC (type, i))
+ fputs_filtered ("static ", stream);
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
+ annotate_field_name_end ();
+ fputs_filtered (" = ", stream);
+ annotate_field_value ();
+ }
+
+ if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i))
+ {
+ struct value *v;
+
+ /* Bitfields require special handling, especially due to byte
+ order problems. */
+ if (TYPE_FIELD_IGNORE (type, i))
+ {
+ fputs_filtered ("<optimized out or zero length>", stream);
+ }
+ else
+ {
+ v = value_from_longest (TYPE_FIELD_TYPE (type, i),
+ unpack_field_as_long (type, valaddr, i));
+
+ val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0, 0,
+ stream, format, 0, recurse + 1, pretty);
+ }
+ }
+ else
+ {
+ if (TYPE_FIELD_IGNORE (type, i))
+ {
+ fputs_filtered ("<optimized out or zero length>", stream);
+ }
+ else if (TYPE_FIELD_STATIC (type, i))
+ {
+ /* struct value *v = value_static_field (type, i); v4.17 specific */
+ struct value *v;
+ v = value_from_longest (TYPE_FIELD_TYPE (type, i),
+ unpack_field_as_long (type, valaddr, i));
+
+ if (v == NULL)
+ fputs_filtered ("<optimized out>", stream);
+ else
+ pascal_object_print_static_field (TYPE_FIELD_TYPE (type, i), v,
+ stream, format, recurse + 1,
+ pretty);
+ }
+ else
+ {
+ /* val_print (TYPE_FIELD_TYPE (type, i),
+ valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
+ address + TYPE_FIELD_BITPOS (type, i) / 8, 0,
+ stream, format, 0, recurse + 1, pretty); */
+ val_print (TYPE_FIELD_TYPE (type, i),
+ valaddr, TYPE_FIELD_BITPOS (type, i) / 8,
+ address + TYPE_FIELD_BITPOS (type, i) / 8,
+ stream, format, 0, recurse + 1, pretty);
+ }
+ }
+ annotate_field_end ();
+ }
+
+ if (dont_print_statmem == 0)
+ {
+ /* Free the space used to deal with the printing
+ of the members from top level. */
+ obstack_free (&dont_print_statmem_obstack, last_dont_print);
+ dont_print_statmem_obstack = tmp_obstack;
+ }
+
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 * recurse, stream);
+ }
+ }
+ fprintf_filtered (stream, "}");
+}
+
+/* Special val_print routine to avoid printing multiple copies of virtual
+ baseclasses. */
+
+void
+pascal_object_print_value (struct type *type, char *valaddr, CORE_ADDR address,
+ struct ui_file *stream, int format, int recurse,
+ enum val_prettyprint pretty,
+ struct type **dont_print_vb)
+{
+ struct obstack tmp_obstack;
+ struct type **last_dont_print
+ = (struct type **) obstack_next_free (&dont_print_vb_obstack);
+ int i, n_baseclasses = TYPE_N_BASECLASSES (type);
+
+ if (dont_print_vb == 0)
+ {
+ /* If we're at top level, carve out a completely fresh
+ chunk of the obstack and use that until this particular
+ invocation returns. */
+ tmp_obstack = dont_print_vb_obstack;
+ /* Bump up the high-water mark. Now alpha is omega. */
+ obstack_finish (&dont_print_vb_obstack);
+ }
+
+ for (i = 0; i < n_baseclasses; i++)
+ {
+ int boffset;
+ struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
+ char *basename = TYPE_NAME (baseclass);
+ char *base_valaddr;
+
+ if (BASETYPE_VIA_VIRTUAL (type, i))
+ {
+ struct type **first_dont_print
+ = (struct type **) obstack_base (&dont_print_vb_obstack);
+
+ int j = (struct type **) obstack_next_free (&dont_print_vb_obstack)
+ - first_dont_print;
+
+ while (--j >= 0)
+ if (baseclass == first_dont_print[j])
+ goto flush_it;
+
+ obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
+ }
+
+ boffset = baseclass_offset (type, i, valaddr, address);
+
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 * recurse, stream);
+ }
+ fputs_filtered ("<", stream);
+ /* Not sure what the best notation is in the case where there is no
+ baseclass name. */
+
+ fputs_filtered (basename ? basename : "", stream);
+ fputs_filtered ("> = ", stream);
+
+ /* The virtual base class pointer might have been clobbered by the
+ user program. Make sure that it still points to a valid memory
+ location. */
+
+ if (boffset != -1 && (boffset < 0 || boffset >= TYPE_LENGTH (type)))
+ {
+ /* FIXME (alloc): not safe is baseclass is really really big. */
+ base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
+ if (target_read_memory (address + boffset, base_valaddr,
+ TYPE_LENGTH (baseclass)) != 0)
+ boffset = -1;
+ }
+ else
+ base_valaddr = valaddr + boffset;
+
+ if (boffset == -1)
+ fprintf_filtered (stream, "<invalid address>");
+ else
+ pascal_object_print_value_fields (baseclass, base_valaddr, address + boffset,
+ stream, format, recurse, pretty,
+ (struct type **) obstack_base (&dont_print_vb_obstack),
+ 0);
+ fputs_filtered (", ", stream);
+
+ flush_it:
+ ;
+ }
+
+ if (dont_print_vb == 0)
+ {
+ /* Free the space used to deal with the printing
+ of this type from top level. */
+ obstack_free (&dont_print_vb_obstack, last_dont_print);
+ /* Reset watermark so that we can continue protecting
+ ourselves from whatever we were protecting ourselves. */
+ dont_print_vb_obstack = tmp_obstack;
+ }
+}
+
+/* Print value of a static member.
+ To avoid infinite recursion when printing a class that contains
+ a static instance of the class, we keep the addresses of all printed
+ static member classes in an obstack and refuse to print them more
+ than once.
+
+ VAL contains the value to print, TYPE, STREAM, RECURSE, and PRETTY
+ have the same meanings as in c_val_print. */
+
+static void
+pascal_object_print_static_field (struct type *type, struct value *val,
+ struct ui_file *stream, int format,
+ int recurse, enum val_prettyprint pretty)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+ {
+ CORE_ADDR *first_dont_print;
+ int i;
+
+ first_dont_print
+ = (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack);
+ i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack)
+ - first_dont_print;
+
+ while (--i >= 0)
+ {
+ if (VALUE_ADDRESS (val) == first_dont_print[i])
+ {
+ fputs_filtered ("<same as static member of an already seen type>",
+ stream);
+ return;
+ }
+ }
+
+ obstack_grow (&dont_print_statmem_obstack, (char *) &VALUE_ADDRESS (val),
+ sizeof (CORE_ADDR));
+
+ CHECK_TYPEDEF (type);
+ pascal_object_print_value_fields (type, VALUE_CONTENTS (val), VALUE_ADDRESS (val),
+ stream, format, recurse, pretty, NULL, 1);
+ return;
+ }
+ val_print (type, VALUE_CONTENTS (val), 0, VALUE_ADDRESS (val),
+ stream, format, 0, recurse, pretty);
+}
+
+void
+pascal_object_print_class_member (char *valaddr, struct type *domain,
+ struct ui_file *stream, char *prefix)
+{
+
+ /* VAL is a byte offset into the structure type DOMAIN.
+ Find the name of the field for that offset and
+ print it. */
+ int extra = 0;
+ int bits = 0;
+ register unsigned int i;
+ unsigned len = TYPE_NFIELDS (domain);
+ /* @@ Make VAL into bit offset */
+ LONGEST val = unpack_long (builtin_type_int, valaddr) << 3;
+ for (i = TYPE_N_BASECLASSES (domain); i < len; i++)
+ {
+ int bitpos = TYPE_FIELD_BITPOS (domain, i);
+ QUIT;
+ if (val == bitpos)
+ break;
+ if (val < bitpos && i != 0)
+ {
+ /* Somehow pointing into a field. */
+ i -= 1;
+ extra = (val - TYPE_FIELD_BITPOS (domain, i));
+ if (extra & 0x7)
+ bits = 1;
+ else
+ extra >>= 3;
+ break;
+ }
+ }
+ if (i < len)
+ {
+ char *name;
+ fprintf_filtered (stream, prefix);
+ name = type_name_no_tag (domain);
+ if (name)
+ fputs_filtered (name, stream);
+ else
+ pascal_type_print_base (domain, stream, 0, 0);
+ fprintf_filtered (stream, "::");
+ fputs_filtered (TYPE_FIELD_NAME (domain, i), stream);
+ if (extra)
+ fprintf_filtered (stream, " + %d bytes", extra);
+ if (bits)
+ fprintf_filtered (stream, " (offset in bits)");
+ }
+ else
+ fprintf_filtered (stream, "%ld", (long int) (val >> 3));
+}
+
+
+void
+_initialize_pascal_valprint (void)
+{
+ add_show_from_set
+ (add_set_cmd ("pascal_static-members", class_support, var_boolean,
+ (char *) &pascal_static_field_print,
+ "Set printing of pascal static members.",
+ &setprintlist),
+ &showprintlist);
+ /* Turn on printing of static fields. */
+ pascal_static_field_print = 1;
+
+}
diff --git a/gdb/pa64solib.c b/gdb/pa64solib.c
new file mode 100644
index 00000000000..0058cbf6ead
--- /dev/null
+++ b/gdb/pa64solib.c
@@ -0,0 +1,1244 @@
+/* Handle HP ELF shared libraries for GDB, the GNU Debugger.
+ Copyright 1999, 2000, 2001 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.
+
+ HP in their infinite stupidity choose not to use standard ELF dynamic
+ linker interfaces. They also choose not to make their ELF dymamic
+ linker interfaces compatible with the SOM dynamic linker. The
+ net result is we can not use either of the existing somsolib.c or
+ solib.c. What a crock.
+
+ Even more disgusting. This file depends on functions provided only
+ in certain PA64 libraries. Thus this file is supposed to only be
+ used native. When will HP ever learn that they need to provide the
+ same functionality in all their libraries! */
+
+#include <dlfcn.h>
+#include <elf.h>
+#include <elf_hp.h>
+
+#include "defs.h"
+
+#include "frame.h"
+#include "bfd.h"
+#include "libhppa.h"
+#include "gdbcore.h"
+#include "symtab.h"
+#include "breakpoint.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "inferior.h"
+#include "gdb-stabs.h"
+#include "gdb_stat.h"
+#include "gdbcmd.h"
+#include "assert.h"
+#include "language.h"
+#include "regcache.h"
+
+#include <fcntl.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/* Defined in exec.c; used to prevent dangling pointer bug. */
+extern struct target_ops exec_ops;
+
+static CORE_ADDR bfd_lookup_symbol (bfd *, char *);
+/* This lives in hppa-tdep.c. */
+extern struct unwind_table_entry *find_unwind_entry (CORE_ADDR pc);
+
+/* These ought to be defined in some public interface, but aren't. They
+ identify dynamic linker events. */
+#define DLD_CB_LOAD 1
+#define DLD_CB_UNLOAD 0
+
+/* A structure to keep track of all the known shared objects. */
+struct so_list
+ {
+ bfd *abfd;
+ char *name;
+ struct so_list *next;
+ struct objfile *objfile;
+ CORE_ADDR pa64_solib_desc_addr;
+ struct load_module_desc pa64_solib_desc;
+ struct section_table *sections;
+ struct section_table *sections_end;
+ boolean loaded;
+ };
+
+static struct so_list *so_list_head;
+
+/* This is the cumulative size in bytes of the symbol tables of all
+ shared objects on the so_list_head list. (When we say size, here
+ we mean of the information before it is brought into memory and
+ potentially expanded by GDB.) When adding a new shlib, this value
+ is compared against a threshold size, held by auto_solib_limit (in
+ megabytes). If adding symbols for the new shlib would cause the
+ total size to exceed the threshold, then the new shlib's symbols
+ are not loaded. */
+static LONGEST pa64_solib_total_st_size;
+
+/* When the threshold is reached for any shlib, we refuse to add
+ symbols for subsequent shlibs, even if those shlibs' symbols would
+ be small enough to fit under the threshold. Although this may
+ result in one, early large shlib preventing the loading of later,
+ smaller shlibs' symbols, it allows us to issue one informational
+ message. The alternative, to issue a message for each shlib whose
+ symbols aren't loaded, could be a big annoyance where the threshold
+ is exceeded due to a very large number of shlibs. */
+static int pa64_solib_st_size_threshold_exceeded;
+
+/* When adding fields, be sure to clear them in _initialize_pa64_solib. */
+typedef struct
+ {
+ CORE_ADDR dld_flags_addr;
+ long long dld_flags;
+ sec_ptr dyninfo_sect;
+ boolean have_read_dld_descriptor;
+ boolean is_valid;
+ CORE_ADDR load_map;
+ CORE_ADDR load_map_addr;
+ struct load_module_desc dld_desc;
+ }
+dld_cache_t;
+
+static dld_cache_t dld_cache;
+
+static void pa64_sharedlibrary_info_command (char *, int);
+
+static void pa64_solib_sharedlibrary_command (char *, int);
+
+static void *pa64_target_read_memory (void *, CORE_ADDR, size_t, int);
+
+static boolean read_dld_descriptor (struct target_ops *, int readsyms);
+
+static boolean read_dynamic_info (asection *, dld_cache_t *);
+
+static void add_to_solist (boolean, char *, int, struct load_module_desc *,
+ CORE_ADDR, struct target_ops *);
+
+/* When examining the shared library for debugging information we have to
+ look for HP debug symbols, stabs and dwarf2 debug symbols. */
+static char *pa64_debug_section_names[] = {
+ ".debug_header", ".debug_gntt", ".debug_lntt", ".debug_slt", ".debug_vt",
+ ".stabs", ".stabstr", ".debug_info", ".debug_abbrev", ".debug_aranges",
+ ".debug_macinfo", ".debug_line", ".debug_loc", ".debug_pubnames",
+ ".debug_str", NULL
+};
+
+/* Return a ballbark figure for the amount of memory GDB will need to
+ allocate to read in the debug symbols from FILENAME. */
+static LONGEST
+pa64_solib_sizeof_symbol_table (char *filename)
+{
+ bfd *abfd;
+ int i;
+ int desc;
+ char *absolute_name;
+ LONGEST st_size = (LONGEST) 0;
+ asection *sect;
+
+ /* We believe that filename was handed to us by the dynamic linker, and
+ is therefore always an absolute path. */
+ desc = openp (getenv ("PATH"), 1, filename, O_RDONLY | O_BINARY,
+ 0, &absolute_name);
+ if (desc < 0)
+ {
+ perror_with_name (filename);
+ }
+ filename = absolute_name;
+
+ abfd = bfd_fdopenr (filename, gnutarget, desc);
+ if (!abfd)
+ {
+ close (desc);
+ make_cleanup (xfree, filename);
+ error ("\"%s\": can't open to read symbols: %s.", filename,
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+ if (!bfd_check_format (abfd, bfd_object))
+ {
+ bfd_close (abfd);
+ make_cleanup (xfree, filename);
+ error ("\"%s\": can't read symbols: %s.", filename,
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+ /* Sum the sizes of the various sections that compose debug info. */
+ for (i = 0; pa64_debug_section_names[i] != NULL; i++)
+ {
+ asection *sect;
+
+ sect = bfd_get_section_by_name (abfd, pa64_debug_section_names[i]);
+ if (sect)
+ st_size += (LONGEST)bfd_section_size (abfd, sect);
+ }
+
+ bfd_close (abfd);
+ xfree (filename);
+
+ /* Unfortunately, just summing the sizes of various debug info
+ sections isn't a very accurate measurement of how much heap
+ space the debugger will need to hold them. It also doesn't
+ account for space needed by linker (aka "minimal") symbols.
+
+ Anecdotal evidence suggests that just summing the sizes of
+ debug-info-related sections understates the heap space needed
+ to represent it internally by about an order of magnitude.
+
+ Since it's not exactly brain surgery we're doing here, rather
+ than attempt to more accurately measure the size of a shlib's
+ symbol table in GDB's heap, we'll just apply a 10x fudge-
+ factor to the debug info sections' size-sum. No, this doesn't
+ account for minimal symbols in non-debuggable shlibs. But it
+ all roughly washes out in the end. */
+ return st_size * (LONGEST) 10;
+}
+
+/* Add a shared library to the objfile list and load its symbols into
+ GDB's symbol table. */
+static void
+pa64_solib_add_solib_objfile (struct so_list *so, char *name, int from_tty,
+ CORE_ADDR text_addr)
+{
+ bfd *tmp_bfd;
+ asection *sec;
+ obj_private_data_t *obj_private;
+ struct section_addr_info section_addrs;
+
+ memset (&section_addrs, 0, sizeof (section_addrs));
+ /* We need the BFD so that we can look at its sections. We open up the
+ file temporarily, then close it when we are done. */
+ tmp_bfd = bfd_openr (name, gnutarget);
+ if (tmp_bfd == NULL)
+ {
+ perror_with_name (name);
+ return;
+ }
+
+ if (!bfd_check_format (tmp_bfd, bfd_object))
+ {
+ bfd_close (tmp_bfd);
+ error ("\"%s\" is not an object file: %s", name,
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+
+ /* Undo some braindamage from symfile.c.
+
+ First, symfile.c will subtract the VMA of the first .text section
+ in the shared library that it finds. Undo that. */
+ sec = bfd_get_section_by_name (tmp_bfd, ".text");
+ text_addr += bfd_section_vma (tmp_bfd, sec);
+
+ /* Now find the true lowest section in the shared library. */
+ sec = NULL;
+ bfd_map_over_sections (tmp_bfd, find_lowest_section, (PTR) &sec);
+
+ if (sec)
+ {
+ /* Subtract out the VMA of the lowest section. */
+ text_addr -= bfd_section_vma (tmp_bfd, sec);
+
+ /* ??? Add back in the filepos of that lowest section. */
+ text_addr += sec->filepos;
+ }
+
+ /* We are done with the temporary bfd. Get rid of it and make sure
+ nobody else can us it. */
+ bfd_close (tmp_bfd);
+ tmp_bfd = NULL;
+
+ /* Now let the generic code load up symbols for this library. */
+ section_addrs.other[0].addr = text_addr;
+ section_addrs.other[0].name = ".text";
+ so->objfile = symbol_file_add (name, from_tty, &section_addrs, 0, OBJF_SHARED);
+ so->abfd = so->objfile->obfd;
+
+ /* Mark this as a shared library and save private data. */
+ so->objfile->flags |= OBJF_SHARED;
+
+ if (so->objfile->obj_private == NULL)
+ {
+ obj_private = (obj_private_data_t *)
+ obstack_alloc (&so->objfile->psymbol_obstack,
+ sizeof (obj_private_data_t));
+ obj_private->unwind_info = NULL;
+ obj_private->so_info = NULL;
+ so->objfile->obj_private = (PTR) obj_private;
+ }
+
+ obj_private = (obj_private_data_t *) so->objfile->obj_private;
+ obj_private->so_info = so;
+ obj_private->dp = so->pa64_solib_desc.linkage_ptr;
+}
+
+/* Load debugging information for a shared library. TARGET may be
+ NULL if we are not attaching to a process or reading a core file. */
+
+static void
+pa64_solib_load_symbols (struct so_list *so, char *name, int from_tty,
+ CORE_ADDR text_addr, struct target_ops *target)
+{
+ struct section_table *p;
+ asection *sec;
+ int status;
+ char buf[4];
+ CORE_ADDR presumed_data_start;
+
+ if (text_addr == 0)
+ text_addr = so->pa64_solib_desc.text_base;
+
+ pa64_solib_add_solib_objfile (so, name, from_tty, text_addr);
+
+ /* Now we need to build a section table for this library since
+ we might be debugging a core file from a dynamically linked
+ executable in which the libraries were not privately mapped. */
+ if (build_section_table (so->abfd,
+ &so->sections,
+ &so->sections_end))
+ {
+ error ("Unable to build section table for shared library\n.");
+ return;
+ }
+
+ (so->objfile->section_offsets)->offsets[SECT_OFF_TEXT (so->objfile)]
+ = so->pa64_solib_desc.text_base;
+ (so->objfile->section_offsets)->offsets[SECT_OFF_DATA (so->objfile)]
+ = so->pa64_solib_desc.data_base;
+
+ /* Relocate all the sections based on where they got loaded. */
+ for (p = so->sections; p < so->sections_end; p++)
+ {
+ if (p->the_bfd_section->flags & SEC_CODE)
+ {
+ p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
+ p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
+ }
+ else if (p->the_bfd_section->flags & SEC_DATA)
+ {
+ p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
+ p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
+ }
+ }
+
+ /* Now see if we need to map in the text and data for this shared
+ library (for example debugging a core file which does not use
+ private shared libraries.).
+
+ Carefully peek at the first text address in the library. If the
+ read succeeds, then the libraries were privately mapped and were
+ included in the core dump file.
+
+ If the peek failed, then the libraries were not privately mapped
+ and are not in the core file, we'll have to read them in ourselves. */
+ status = target_read_memory (text_addr, buf, 4);
+ if (status != 0)
+ {
+ int new, old;
+
+ new = so->sections_end - so->sections;
+
+ old = target_resize_to_sections (target, new);
+
+ /* Copy over the old data before it gets clobbered. */
+ memcpy ((char *) (target->to_sections + old),
+ so->sections,
+ ((sizeof (struct section_table)) * new));
+ }
+}
+
+
+/* Add symbols from shared libraries into the symtab list, unless the
+ size threshold specified by auto_solib_limit (in megabytes) would
+ be exceeded. */
+
+void
+pa64_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms)
+{
+ struct minimal_symbol *msymbol;
+ CORE_ADDR addr;
+ asection *shlib_info;
+ int status;
+ unsigned int dld_flags;
+ char buf[4], *re_err;
+ int threshold_warning_given = 0;
+ int dll_index;
+ struct load_module_desc dll_desc;
+ char *dll_path;
+
+ /* First validate our arguments. */
+ if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)
+ {
+ error ("Invalid regexp: %s", re_err);
+ }
+
+ /* If we're debugging a core file, or have attached to a running
+ process, then pa64_solib_create_inferior_hook will not have been
+ called.
+
+ We need to first determine if we're dealing with a dynamically
+ linked executable. If not, then return without an error or warning.
+
+ We also need to examine __dld_flags to determine if the shared library
+ list is valid and to determine if the libraries have been privately
+ mapped. */
+ if (symfile_objfile == NULL)
+ return;
+
+ /* First see if the objfile was dynamically linked. */
+ shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, ".dynamic");
+ if (!shlib_info)
+ return;
+
+ /* It's got a .dynamic section, make sure it's not empty. */
+ if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
+ return;
+
+ /* Read in the load map pointer if we have not done so already. */
+ if (! dld_cache.have_read_dld_descriptor)
+ if (! read_dld_descriptor (target, readsyms))
+ return;
+
+ /* If the libraries were not mapped private, warn the user. */
+ if ((dld_cache.dld_flags & DT_HP_DEBUG_PRIVATE) == 0)
+ warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n");
+
+ /* For each shaerd library, add it to the shared library list. */
+ for (dll_index = 1; ; dll_index++)
+ {
+ /* Read in the load module descriptor. */
+ if (dlgetmodinfo (dll_index, &dll_desc, sizeof (dll_desc),
+ pa64_target_read_memory, 0, dld_cache.load_map)
+ == 0)
+ return;
+
+ /* Get the name of the shared library. */
+ dll_path = (char *)dlgetname (&dll_desc, sizeof (dll_desc),
+ pa64_target_read_memory,
+ 0, dld_cache.load_map);
+
+ if (!dll_path)
+ error ("pa64_solib_add, unable to read shared library path.");
+
+ add_to_solist (from_tty, dll_path, readsyms, &dll_desc, 0, target);
+ }
+}
+
+
+/* This hook gets called just before the first instruction in the
+ inferior process is executed.
+
+ This is our opportunity to set magic flags in the inferior so
+ that GDB can be notified when a shared library is mapped in and
+ to tell the dynamic linker that a private copy of the library is
+ needed (so GDB can set breakpoints in the library).
+
+ We need to set two flag bits in this routine.
+
+ DT_HP_DEBUG_PRIVATE to indicate that shared libraries should be
+ mapped private.
+
+ DT_HP_DEBUG_CALLBACK to indicate that we want the dynamic linker to
+ call the breakpoint routine for significant events. */
+
+void
+pa64_solib_create_inferior_hook (void)
+{
+ struct minimal_symbol *msymbol;
+ unsigned int dld_flags, status;
+ asection *shlib_info, *interp_sect;
+ char buf[4];
+ struct objfile *objfile;
+ CORE_ADDR anaddr;
+
+ /* First, remove all the solib event breakpoints. Their addresses
+ may have changed since the last time we ran the program. */
+ remove_solib_event_breakpoints ();
+
+ if (symfile_objfile == NULL)
+ return;
+
+ /* First see if the objfile was dynamically linked. */
+ shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, ".dynamic");
+ if (!shlib_info)
+ return;
+
+ /* It's got a .dynamic section, make sure it's not empty. */
+ if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
+ return;
+
+ /* Read in the .dynamic section. */
+ if (! read_dynamic_info (shlib_info, &dld_cache))
+ error ("Unable to read the .dynamic section.");
+
+ /* Turn on the flags we care about. */
+ dld_cache.dld_flags |= DT_HP_DEBUG_PRIVATE;
+ dld_cache.dld_flags |= DT_HP_DEBUG_CALLBACK;
+ status = target_write_memory (dld_cache.dld_flags_addr,
+ (char *) &dld_cache.dld_flags,
+ sizeof (dld_cache.dld_flags));
+ if (status != 0)
+ error ("Unable to modify dynamic linker flags.");
+
+ /* Now we have to create a shared library breakpoint in the dynamic
+ linker. This can be somewhat tricky since the symbol is inside
+ the dynamic linker (for which we do not have symbols or a base
+ load address! Luckily I wrote this code for solib.c years ago. */
+ interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
+ if (interp_sect)
+ {
+ unsigned int interp_sect_size;
+ char *buf;
+ CORE_ADDR load_addr;
+ bfd *tmp_bfd;
+ CORE_ADDR sym_addr = 0;
+
+ /* Read the contents of the .interp section into a local buffer;
+ the contents specify the dynamic linker this program uses. */
+ interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
+ buf = alloca (interp_sect_size);
+ bfd_get_section_contents (exec_bfd, interp_sect,
+ buf, 0, interp_sect_size);
+
+ /* Now we need to figure out where the dynamic linker was
+ loaded so that we can load its symbols and place a breakpoint
+ in the dynamic linker itself.
+
+ This address is stored on the stack. However, I've been unable
+ to find any magic formula to find it for Solaris (appears to
+ be trivial on GNU/Linux). Therefore, we have to try an alternate
+ mechanism to find the dynamic linker's base address. */
+ tmp_bfd = bfd_openr (buf, gnutarget);
+ if (tmp_bfd == NULL)
+ goto get_out;
+
+ /* Make sure the dynamic linker's really a useful object. */
+ if (!bfd_check_format (tmp_bfd, bfd_object))
+ {
+ warning ("Unable to grok dynamic linker %s as an object file", buf);
+ bfd_close (tmp_bfd);
+ goto get_out;
+ }
+
+ /* We find the dynamic linker's base address by examining the
+ current pc (which point at the entry point for the dynamic
+ linker) and subtracting the offset of the entry point.
+
+ Also note the breakpoint is the second instruction in the
+ routine. */
+ load_addr = read_pc () - tmp_bfd->start_address;
+ sym_addr = bfd_lookup_symbol (tmp_bfd, "__dld_break");
+ sym_addr = load_addr + sym_addr + 4;
+
+ /* Create the shared library breakpoint. */
+ {
+ struct breakpoint *b
+ = create_solib_event_breakpoint (sym_addr);
+
+ /* The breakpoint is actually hard-coded into the dynamic linker,
+ so we don't need to actually insert a breakpoint instruction
+ there. In fact, the dynamic linker's code is immutable, even to
+ ttrace, so we shouldn't even try to do that. For cases like
+ this, we have "permanent" breakpoints. */
+ make_breakpoint_permanent (b);
+ }
+
+ /* We're done with the temporary bfd. */
+ bfd_close (tmp_bfd);
+ }
+
+get_out:
+ /* Wipe out all knowledge of old shared libraries since their
+ mapping can change from one exec to another! */
+ while (so_list_head)
+ {
+ struct so_list *temp;
+
+ temp = so_list_head;
+ xfree (so_list_head);
+ so_list_head = temp->next;
+ }
+ clear_symtab_users ();
+}
+
+/* This operation removes the "hook" between GDB and the dynamic linker,
+ which causes the dld to notify GDB of shared library events.
+
+ After this operation completes, the dld will no longer notify GDB of
+ shared library events. To resume notifications, GDB must call
+ pa64_solib_create_inferior_hook.
+
+ This operation does not remove any knowledge of shared libraries which
+ GDB may already have been notified of. */
+
+void
+pa64_solib_remove_inferior_hook (int pid)
+{
+ /* Turn off the DT_HP_DEBUG_CALLBACK bit in the dynamic linker flags. */
+ dld_cache.dld_flags &= ~DT_HP_DEBUG_CALLBACK;
+ target_write_memory (dld_cache.dld_flags_addr,
+ (char *)&dld_cache.dld_flags,
+ sizeof (dld_cache.dld_flags));
+}
+
+/* This function creates a breakpoint on the dynamic linker hook, which
+ is called when e.g., a shl_load or shl_unload call is made. This
+ breakpoint will only trigger when a shl_load call is made.
+
+ If filename is NULL, then loads of any dll will be caught. Else,
+ only loads of the file whose pathname is the string contained by
+ filename will be caught.
+
+ Undefined behaviour is guaranteed if this function is called before
+ pa64_solib_create_inferior_hook. */
+
+void
+pa64_solib_create_catch_load_hook (int pid, int tempflag, char *filename,
+ char *cond_string)
+{
+ create_solib_load_event_breakpoint ("", tempflag, filename, cond_string);
+}
+
+/* This function creates a breakpoint on the dynamic linker hook, which
+ is called when e.g., a shl_load or shl_unload call is made. This
+ breakpoint will only trigger when a shl_unload call is made.
+
+ If filename is NULL, then unloads of any dll will be caught. Else,
+ only unloads of the file whose pathname is the string contained by
+ filename will be caught.
+
+ Undefined behaviour is guaranteed if this function is called before
+ pa64_solib_create_inferior_hook. */
+
+void
+pa64_solib_create_catch_unload_hook (int pid, int tempflag, char *filename,
+ char *cond_string)
+{
+ create_solib_unload_event_breakpoint ("", tempflag, filename, cond_string);
+}
+
+/* Return nonzero if the dynamic linker has reproted that a library
+ has been loaded. */
+
+int
+pa64_solib_have_load_event (int pid)
+{
+ CORE_ADDR event_kind;
+
+ event_kind = read_register (ARG0_REGNUM);
+ return (event_kind == DLD_CB_LOAD);
+}
+
+/* Return nonzero if the dynamic linker has reproted that a library
+ has been unloaded. */
+int
+pa64_solib_have_unload_event (int pid)
+{
+ CORE_ADDR event_kind;
+
+ event_kind = read_register (ARG0_REGNUM);
+ return (event_kind == DLD_CB_UNLOAD);
+}
+
+/* Return a pointer to a string indicating the pathname of the most
+ recently loaded library.
+
+ The caller is reposible for copying the string before the inferior is
+ restarted. */
+
+char *
+pa64_solib_loaded_library_pathname (int pid)
+{
+ static char dll_path[MAXPATHLEN];
+ CORE_ADDR dll_path_addr = read_register (ARG3_REGNUM);
+ read_memory_string (dll_path_addr, dll_path, MAXPATHLEN);
+ return dll_path;
+}
+
+/* Return a pointer to a string indicating the pathname of the most
+ recently unloaded library.
+
+ The caller is reposible for copying the string before the inferior is
+ restarted. */
+
+char *
+pa64_solib_unloaded_library_pathname (int pid)
+{
+ static char dll_path[MAXPATHLEN];
+ CORE_ADDR dll_path_addr = read_register (ARG3_REGNUM);
+ read_memory_string (dll_path_addr, dll_path, MAXPATHLEN);
+ return dll_path;
+}
+
+/* Return nonzero if PC is an address inside the dynamic linker. */
+
+int
+pa64_solib_in_dynamic_linker (int pid, CORE_ADDR pc)
+{
+ asection *shlib_info;
+
+ if (symfile_objfile == NULL)
+ return 0;
+
+ if (!dld_cache.have_read_dld_descriptor)
+ if (!read_dld_descriptor (&current_target, auto_solib_add))
+ return 0;
+
+ return (pc >= dld_cache.dld_desc.text_base
+ && pc < dld_cache.dld_desc.text_base + dld_cache.dld_desc.text_size);
+}
+
+
+/* Return the GOT value for the shared library in which ADDR belongs. If
+ ADDR isn't in any known shared library, return zero. */
+
+CORE_ADDR
+pa64_solib_get_got_by_pc (CORE_ADDR addr)
+{
+ struct so_list *so_list = so_list_head;
+ CORE_ADDR got_value = 0;
+
+ while (so_list)
+ {
+ if (so_list->pa64_solib_desc.text_base <= addr
+ && ((so_list->pa64_solib_desc.text_base
+ + so_list->pa64_solib_desc.text_size)
+ > addr))
+ {
+ got_value = so_list->pa64_solib_desc.linkage_ptr;
+ break;
+ }
+ so_list = so_list->next;
+ }
+ return got_value;
+}
+
+/* Return the address of the handle of the shared library in which ADDR
+ belongs. If ADDR isn't in any known shared library, return zero.
+
+ This function is used in hppa_fix_call_dummy in hppa-tdep.c. */
+
+CORE_ADDR
+pa64_solib_get_solib_by_pc (CORE_ADDR addr)
+{
+ struct so_list *so_list = so_list_head;
+ CORE_ADDR retval = 0;
+
+ while (so_list)
+ {
+ if (so_list->pa64_solib_desc.text_base <= addr
+ && ((so_list->pa64_solib_desc.text_base
+ + so_list->pa64_solib_desc.text_size)
+ > addr))
+ {
+ retval = so_list->pa64_solib_desc_addr;
+ break;
+ }
+ so_list = so_list->next;
+ }
+ return retval;
+}
+
+/* Dump information about all the currently loaded shared libraries. */
+
+static void
+pa64_sharedlibrary_info_command (char *ignore, int from_tty)
+{
+ struct so_list *so_list = so_list_head;
+
+ if (exec_bfd == NULL)
+ {
+ printf_unfiltered ("No executable file.\n");
+ return;
+ }
+
+ if (so_list == NULL)
+ {
+ printf_unfiltered ("No shared libraries loaded at this time.\n");
+ return;
+ }
+
+ printf_unfiltered ("Shared Object Libraries\n");
+ printf_unfiltered (" %-19s%-19s%-19s%-19s\n",
+ " text start", " text end",
+ " data start", " data end");
+ while (so_list)
+ {
+ unsigned int flags;
+
+ printf_unfiltered ("%s", so_list->name);
+ if (so_list->objfile == NULL)
+ printf_unfiltered (" (symbols not loaded)");
+ if (so_list->loaded == 0)
+ printf_unfiltered (" (shared library unloaded)");
+ printf_unfiltered (" %-18s",
+ local_hex_string_custom (so_list->pa64_solib_desc.linkage_ptr,
+ "016l"));
+ printf_unfiltered ("\n");
+ printf_unfiltered ("%-18s",
+ local_hex_string_custom (so_list->pa64_solib_desc.text_base,
+ "016l"));
+ printf_unfiltered (" %-18s",
+ local_hex_string_custom ((so_list->pa64_solib_desc.text_base
+ + so_list->pa64_solib_desc.text_size),
+ "016l"));
+ printf_unfiltered (" %-18s",
+ local_hex_string_custom (so_list->pa64_solib_desc.data_base,
+ "016l"));
+ printf_unfiltered (" %-18s\n",
+ local_hex_string_custom ((so_list->pa64_solib_desc.data_base
+ + so_list->pa64_solib_desc.data_size),
+ "016l"));
+ so_list = so_list->next;
+ }
+}
+
+/* Load up one or more shared libraries as directed by the user. */
+
+static void
+pa64_solib_sharedlibrary_command (char *args, int from_tty)
+{
+ dont_repeat ();
+ pa64_solib_add (args, from_tty, (struct target_ops *) 0, 1);
+}
+
+/* Return the name of the shared library containing ADDR or NULL if ADDR
+ is not contained in any known shared library. */
+
+char *
+pa64_solib_address (CORE_ADDR addr)
+{
+ struct so_list *so = so_list_head;
+
+ while (so)
+ {
+ /* Is this address within this shlib's text range? If so,
+ return the shlib's name. */
+ if (addr >= so->pa64_solib_desc.text_base
+ && addr < (so->pa64_solib_desc.text_base
+ | so->pa64_solib_desc.text_size))
+ return so->name;
+
+ /* Nope, keep looking... */
+ so = so->next;
+ }
+
+ /* No, we couldn't prove that the address is within a shlib. */
+ return NULL;
+}
+
+/* We are killing the inferior and restarting the program. */
+
+void
+pa64_solib_restart (void)
+{
+ struct so_list *sl = so_list_head;
+
+ /* Before the shlib info vanishes, use it to disable any breakpoints
+ that may still be active in those shlibs. */
+ disable_breakpoints_in_shlibs (0);
+
+ /* Discard all the shlib descriptors. */
+ while (sl)
+ {
+ struct so_list *next_sl = sl->next;
+ xfree (sl);
+ sl = next_sl;
+ }
+ so_list_head = NULL;
+
+ pa64_solib_total_st_size = (LONGEST) 0;
+ pa64_solib_st_size_threshold_exceeded = 0;
+
+ dld_cache.is_valid = 0;
+ dld_cache.have_read_dld_descriptor = 0;
+ dld_cache.dld_flags_addr = 0;
+ dld_cache.load_map = 0;
+ dld_cache.load_map_addr = 0;
+ dld_cache.dld_desc.data_base = 0;
+ dld_cache.dld_flags = 0;
+ dld_cache.dyninfo_sect = 0;
+}
+
+void
+_initialize_pa64_solib (void)
+{
+ add_com ("sharedlibrary", class_files, pa64_solib_sharedlibrary_command,
+ "Load shared object library symbols for files matching REGEXP.");
+ add_info ("sharedlibrary", pa64_sharedlibrary_info_command,
+ "Status of loaded shared object libraries.");
+
+ add_show_from_set
+ (add_set_cmd ("auto-solib-add", class_support, var_boolean,
+ (char *) &auto_solib_add,
+ "Set autoloading of shared library symbols.\n\
+If \"on\", symbols from all shared object libraries will be loaded\n\
+automatically when the inferior begins execution, when the dynamic linker\n\
+informs gdb that a new library has been loaded, or when attaching to the\n\
+inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("auto-solib-limit", class_support, var_zinteger,
+ (char *) &auto_solib_limit,
+ "Set threshold (in Mb) for autoloading shared library symbols.\n\
+When shared library autoloading is enabled, new libraries will be loaded\n\
+only until the total size of shared library symbols exceeds this\n\
+threshold in megabytes. Is ignored when using `sharedlibrary'.",
+ &setlist),
+ &showlist);
+
+ /* ??rehrauer: On HP-UX, the kernel parameter MAXDSIZ limits how
+ much data space a process can use. We ought to be reading
+ MAXDSIZ and setting auto_solib_limit to some large fraction of
+ that value. If not that, we maybe ought to be setting it smaller
+ than the default for MAXDSIZ (that being 64Mb, I believe).
+ However, [1] this threshold is only crudely approximated rather
+ than actually measured, and [2] 50 Mbytes is too small for
+ debugging gdb itself. Thus, the arbitrary 100 figure. */
+ auto_solib_limit = 100; /* Megabytes */
+
+ pa64_solib_restart ();
+}
+
+/* Get some HPUX-specific data from a shared lib. */
+CORE_ADDR
+so_lib_thread_start_addr (struct so_list *so)
+{
+ return so->pa64_solib_desc.tls_start_addr;
+}
+
+/* Read the dynamic linker's internal shared library descriptor.
+
+ This must happen after dld starts running, so we can't do it in
+ read_dynamic_info. Record the fact that we have loaded the
+ descriptor. If the library is archive bound, then return zero, else
+ return nonzero. */
+
+static boolean
+read_dld_descriptor (struct target_ops *target, int readsyms)
+{
+ char *dll_path;
+ asection *dyninfo_sect;
+
+ /* If necessary call read_dynamic_info to extract the contents of the
+ .dynamic section from the shared library. */
+ if (!dld_cache.is_valid)
+ {
+ if (symfile_objfile == NULL)
+ error ("No object file symbols.");
+
+ dyninfo_sect = bfd_get_section_by_name (symfile_objfile->obfd,
+ ".dynamic");
+ if (!dyninfo_sect)
+ {
+ return 0;
+ }
+
+ if (!read_dynamic_info (dyninfo_sect, &dld_cache))
+ error ("Unable to read in .dynamic section information.");
+ }
+
+ /* Read the load map pointer. */
+ if (target_read_memory (dld_cache.load_map_addr,
+ (char*) &dld_cache.load_map,
+ sizeof(dld_cache.load_map))
+ != 0)
+ {
+ error ("Error while reading in load map pointer.");
+ }
+
+ /* Read in the dld load module descriptor */
+ if (dlgetmodinfo (-1,
+ &dld_cache.dld_desc,
+ sizeof(dld_cache.dld_desc),
+ pa64_target_read_memory,
+ 0,
+ dld_cache.load_map)
+ == 0)
+ {
+ error ("Error trying to get information about dynamic linker.");
+ }
+
+ /* Indicate that we have loaded the dld descriptor. */
+ dld_cache.have_read_dld_descriptor = 1;
+
+ /* Add dld.sl to the list of known shared libraries so that we can
+ do unwind, etc.
+
+ ?!? This may not be correct. Consider of dld.sl contains symbols
+ which are also referenced/defined by the user program or some user
+ shared library. We need to make absolutely sure that we do not
+ pollute the namespace from GDB's point of view. */
+ dll_path = dlgetname (&dld_cache.dld_desc,
+ sizeof(dld_cache.dld_desc),
+ pa64_target_read_memory,
+ 0,
+ dld_cache.load_map);
+ add_to_solist(0, dll_path, readsyms, &dld_cache.dld_desc, 0, target);
+
+ return 1;
+}
+
+/* Read the .dynamic section and extract the information of interest,
+ which is stored in dld_cache. The routine elf_locate_base in solib.c
+ was used as a model for this. */
+
+static boolean
+read_dynamic_info (asection *dyninfo_sect, dld_cache_t *dld_cache_p)
+{
+ char *buf;
+ char *bufend;
+ CORE_ADDR dyninfo_addr;
+ int dyninfo_sect_size;
+ CORE_ADDR entry_addr;
+
+ /* Read in .dynamic section, silently ignore errors. */
+ dyninfo_addr = bfd_section_vma (symfile_objfile->obfd, dyninfo_sect);
+ dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect);
+ buf = alloca (dyninfo_sect_size);
+ if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size))
+ return 0;
+
+ /* Scan the .dynamic section and record the items of interest.
+ In particular, DT_HP_DLD_FLAGS */
+ for (bufend = buf + dyninfo_sect_size, entry_addr = dyninfo_addr;
+ buf < bufend;
+ buf += sizeof (Elf64_Dyn), entry_addr += sizeof (Elf64_Dyn))
+ {
+ Elf64_Dyn *x_dynp = (Elf64_Dyn*)buf;
+ Elf64_Sxword dyn_tag;
+ CORE_ADDR dyn_ptr;
+ char *pbuf;
+
+ pbuf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT);
+ dyn_tag = bfd_h_get_64 (symfile_objfile->obfd,
+ (bfd_byte*) &x_dynp->d_tag);
+
+ /* We can't use a switch here because dyn_tag is 64 bits and HP's
+ lame comiler does not handle 64bit items in switch statements. */
+ if (dyn_tag == DT_NULL)
+ break;
+ else if (dyn_tag == DT_HP_DLD_FLAGS)
+ {
+ /* Set dld_flags_addr and dld_flags in *dld_cache_p */
+ dld_cache_p->dld_flags_addr = entry_addr + offsetof(Elf64_Dyn, d_un);
+ if (target_read_memory (dld_cache_p->dld_flags_addr,
+ (char*) &dld_cache_p->dld_flags,
+ sizeof(dld_cache_p->dld_flags))
+ != 0)
+ {
+ error ("Error while reading in .dynamic section of the program.");
+ }
+ }
+ else if (dyn_tag == DT_HP_LOAD_MAP)
+ {
+ /* Dld will place the address of the load map at load_map_addr
+ after it starts running. */
+ if (target_read_memory (entry_addr + offsetof(Elf64_Dyn,
+ d_un.d_ptr),
+ (char*) &dld_cache_p->load_map_addr,
+ sizeof(dld_cache_p->load_map_addr))
+ != 0)
+ {
+ error ("Error while reading in .dynamic section of the program.");
+ }
+ }
+ else
+ {
+ /* tag is not of interest */
+ }
+ }
+
+ /* Record other information and set is_valid to 1. */
+ dld_cache_p->dyninfo_sect = dyninfo_sect;
+
+ /* Verify that we read in required info. These fields are re-set to zero
+ in pa64_solib_restart. */
+
+ if (dld_cache_p->dld_flags_addr != 0 && dld_cache_p->load_map_addr != 0)
+ dld_cache_p->is_valid = 1;
+ else
+ return 0;
+
+ return 1;
+}
+
+/* Wrapper for target_read_memory to make dlgetmodinfo happy. */
+
+static void *
+pa64_target_read_memory (void *buffer, CORE_ADDR ptr, size_t bufsiz, int ident)
+{
+ if (target_read_memory (ptr, buffer, bufsiz) != 0)
+ return 0;
+ return buffer;
+}
+
+/* Called from handle_dynlink_load_event and pa64_solib_add to add
+ a shared library to so_list_head list and possibly to read in the
+ debug information for the library.
+
+ If load_module_desc_p is NULL, then the load module descriptor must
+ be read from the inferior process at the address load_module_desc_addr. */
+
+static void
+add_to_solist (boolean from_tty, char *dll_path, int readsyms,
+ struct load_module_desc *load_module_desc_p,
+ CORE_ADDR load_module_desc_addr, struct target_ops *target)
+{
+ struct so_list *new_so, *so_list_tail;
+ int pa64_solib_st_size_threshhold_exceeded;
+ LONGEST st_size;
+
+ if (symfile_objfile == NULL)
+ return;
+
+ so_list_tail = so_list_head;
+ /* Find the end of the list of shared objects. */
+ while (so_list_tail && so_list_tail->next)
+ {
+ if (strcmp (so_list_tail->name, dll_path) == 0)
+ return;
+ so_list_tail = so_list_tail->next;
+ }
+
+ if (so_list_tail && strcmp (so_list_tail->name, dll_path) == 0)
+ return;
+
+ /* Add the shared library to the so_list_head list */
+ new_so = (struct so_list *) xmalloc (sizeof (struct so_list));
+ memset ((char *)new_so, 0, sizeof (struct so_list));
+ if (so_list_head == NULL)
+ {
+ so_list_head = new_so;
+ so_list_tail = new_so;
+ }
+ else
+ {
+ so_list_tail->next = new_so;
+ so_list_tail = new_so;
+ }
+
+ /* Initialize the new_so */
+ if (load_module_desc_p)
+ {
+ new_so->pa64_solib_desc = *load_module_desc_p;
+ }
+ else
+ {
+ if (target_read_memory (load_module_desc_addr,
+ (char*) &new_so->pa64_solib_desc,
+ sizeof(struct load_module_desc))
+ != 0)
+ {
+ error ("Error while reading in dynamic library %s", dll_path);
+ }
+ }
+
+ new_so->pa64_solib_desc_addr = load_module_desc_addr;
+ new_so->loaded = 1;
+ new_so->name = obsavestring (dll_path, strlen(dll_path),
+ &symfile_objfile->symbol_obstack);
+
+ /* If we are not going to load the library, tell the user if we
+ haven't already and return. */
+
+ st_size = pa64_solib_sizeof_symbol_table (dll_path);
+ pa64_solib_st_size_threshhold_exceeded =
+ !from_tty
+ && readsyms
+ && ( (st_size + pa64_solib_total_st_size)
+ > (auto_solib_limit * (LONGEST) (1024 * 1024)));
+ if (pa64_solib_st_size_threshhold_exceeded)
+ {
+ pa64_solib_add_solib_objfile (new_so, dll_path, from_tty, 1);
+ return;
+ }
+
+ /* Now read in debug info. */
+ pa64_solib_total_st_size += st_size;
+
+ /* This fills in new_so->objfile, among others. */
+ pa64_solib_load_symbols (new_so,
+ dll_path,
+ from_tty,
+ 0,
+ target);
+ return;
+}
+
+
+/*
+ LOCAL FUNCTION
+
+ bfd_lookup_symbol -- lookup the value for a specific symbol
+
+ SYNOPSIS
+
+ CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname)
+
+ DESCRIPTION
+
+ An expensive way to lookup the value of a single symbol for
+ bfd's that are only temporary anyway. This is used by the
+ shared library support to find the address of the debugger
+ interface structures in the shared library.
+
+ Note that 0 is specifically allowed as an error return (no
+ such symbol).
+ */
+
+static CORE_ADDR
+bfd_lookup_symbol (bfd *abfd, char *symname)
+{
+ unsigned int storage_needed;
+ asymbol *sym;
+ asymbol **symbol_table;
+ unsigned int number_of_symbols;
+ unsigned int i;
+ struct cleanup *back_to;
+ CORE_ADDR symaddr = 0;
+
+ storage_needed = bfd_get_symtab_upper_bound (abfd);
+
+ if (storage_needed > 0)
+ {
+ symbol_table = (asymbol **) xmalloc (storage_needed);
+ back_to = make_cleanup (xfree, (PTR) symbol_table);
+ number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
+
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ sym = *symbol_table++;
+ if (STREQ (sym->name, symname))
+ {
+ /* Bfd symbols are section relative. */
+ symaddr = sym->value + sym->section->vma;
+ break;
+ }
+ }
+ do_cleanups (back_to);
+ }
+ return (symaddr);
+}
+
diff --git a/gdb/pa64solib.h b/gdb/pa64solib.h
new file mode 100644
index 00000000000..7a3a068ff8d
--- /dev/null
+++ b/gdb/pa64solib.h
@@ -0,0 +1,149 @@
+/* HP PA64 ELF Shared library declarations for GDB, the GNU Debugger.
+ Copyright 1999, 2000 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. */
+
+/* Forward decl's for prototypes */
+struct target_ops;
+struct objfile;
+struct section_offsets;
+
+/* Called to add symbols from a shared library to gdb's symbol table. */
+
+#define SOLIB_ADD(filename, from_tty, targ, readsyms) \
+ pa64_solib_add (filename, from_tty, targ, readsyms)
+
+extern void pa64_solib_add (char *, int, struct target_ops *, int);
+
+extern CORE_ADDR pa64_solib_get_got_by_pc (CORE_ADDR);
+
+/* Function to be called when the inferior starts up, to discover the names
+ of shared libraries that are dynamically linked, the base addresses to
+ which they are linked, and sufficient information to read in their symbols
+ at a later time. */
+
+#define SOLIB_CREATE_INFERIOR_HOOK(PID) pa64_solib_create_inferior_hook()
+
+extern void pa64_solib_create_inferior_hook (void);
+
+/* Function to be called to remove the connection between debugger and
+ dynamic linker that was established by SOLIB_CREATE_INFERIOR_HOOK.
+ (This operation does not remove shared library information from
+ the debugger, as CLEAR_SOLIB does.) */
+#define SOLIB_REMOVE_INFERIOR_HOOK(PID) pa64_solib_remove_inferior_hook(PID)
+
+extern void pa64_solib_remove_inferior_hook (int);
+
+/* This function is called by the "catch load" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is loaded. */
+#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag, filename,cond_string) \
+ pa64_solib_create_catch_load_hook (pid, tempflag, filename, cond_string)
+
+extern void pa64_solib_create_catch_load_hook (int, int, char *, char *);
+
+/* This function is called by the "catch unload" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is unloaded. */
+#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename, cond_string) \
+ pa64_solib_create_catch_unload_hook (pid, tempflag, filename, cond_string)
+
+extern void pa64_solib_create_catch_unload_hook (int, int, char *, char *);
+
+/* This function returns TRUE if the dynamic linker has just reported
+ a load of a library.
+
+ This function must be used only when the inferior has stopped in
+ the dynamic linker hook, or undefined results are guaranteed. */
+#define SOLIB_HAVE_LOAD_EVENT(pid) \
+ pa64_solib_have_load_event (pid)
+
+extern int pa64_solib_have_load_event (int);
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been loaded.
+
+ This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the inferior
+ has stopped in the dynamic linker hook, and becomes invalid as soon
+ as the inferior is continued. Clients should make a copy of this
+ string if they wish to continue the inferior and then access the string. */
+#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \
+ pa64_solib_loaded_library_pathname (pid)
+
+extern char *pa64_solib_loaded_library_pathname (int);
+
+/* This function returns TRUE if the dynamic linker has just reported
+ an unload of a library.
+
+ This function must be used only when the inferior has stopped in
+ the dynamic linker hook, or undefined results are guaranteed. */
+#define SOLIB_HAVE_UNLOAD_EVENT(pid) \
+ pa64_solib_have_unload_event (pid)
+
+extern int pa64_solib_have_unload_event (int);
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been unloaded.
+
+ This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the inferior
+ has stopped in the dynamic linker hook, and becomes invalid as soon
+ as the inferior is continued. Clients should make a copy of this
+ string if they wish to continue the inferior and then access the string. */
+#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \
+ pa64_solib_unloaded_library_pathname (pid)
+
+extern char *pa64_solib_unloaded_library_pathname (int);
+
+/* This function returns TRUE if pc is the address of an instruction that
+ lies within the dynamic linker (such as the event hook, or the dld
+ itself).
+
+ This function must be used only when a dynamic linker event has been
+ caught, and the inferior is being stepped out of the hook, or undefined
+ results are guaranteed. */
+#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \
+ pa64_solib_in_dynamic_linker (pid, pc)
+
+extern int pa64_solib_in_dynamic_linker (int, CORE_ADDR);
+
+/* This function must be called when the inferior is killed, and the program
+ restarted. This is not the same as CLEAR_SOLIB, in that it doesn't discard
+ any symbol tables.
+
+ Presently, this functionality is not implemented. */
+#define SOLIB_RESTART() \
+ pa64_solib_restart ()
+
+extern void pa64_solib_restart (void);
+
+/* If we can't set a breakpoint, and it's in a shared library, just
+ disable it. */
+
+#define DISABLE_UNSETTABLE_BREAK(addr) (pa64_solib_address(addr) != NULL)
+
+extern char *pa64_solib_address (CORE_ADDR); /* somsolib.c */
+
+/* If ADDR lies in a shared library, return its name. */
+
+#define PC_SOLIB(addr) pa64_solib_address (addr)
diff --git a/gdb/parse.c b/gdb/parse.c
new file mode 100644
index 00000000000..bc81f221b52
--- /dev/null
+++ b/gdb/parse.c
@@ -0,0 +1,1395 @@
+/* Parse expressions for GDB.
+ Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Modified from expread.y by the Department of Computer Science at the
+ State University of New York at Buffalo, 1991.
+
+ 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. */
+
+/* Parse an expression from text in a string,
+ and return the result as a struct expression pointer.
+ That structure contains arithmetic operations in reverse polish,
+ with constants represented by operations that are followed by special data.
+ See expression.h for the details of the format.
+ What is important here is that it can be built up sequentially
+ during the process of parsing; the lower levels of the tree always
+ come first in the result. */
+
+#include <ctype.h>
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "frame.h"
+#include "expression.h"
+#include "value.h"
+#include "command.h"
+#include "language.h"
+#include "parser-defs.h"
+#include "gdbcmd.h"
+#include "symfile.h" /* for overlay functions */
+#include "inferior.h" /* for NUM_PSEUDO_REGS. NOTE: replace
+ with "gdbarch.h" when appropriate. */
+#include "doublest.h"
+#include "builtin-regs.h"
+#include "gdb_assert.h"
+
+
+/* Symbols which architectures can redefine. */
+
+/* Some systems have routines whose names start with `$'. Giving this
+ macro a non-zero value tells GDB's expression parser to check for
+ such routines when parsing tokens that begin with `$'.
+
+ On HP-UX, certain system routines (millicode) have names beginning
+ with `$' or `$$'. For example, `$$dyncall' is a millicode routine
+ that handles inter-space procedure calls on PA-RISC. */
+#ifndef SYMBOLS_CAN_START_WITH_DOLLAR
+#define SYMBOLS_CAN_START_WITH_DOLLAR (0)
+#endif
+
+
+
+/* Global variables declared in parser-defs.h (and commented there). */
+struct expression *expout;
+int expout_size;
+int expout_ptr;
+struct block *expression_context_block;
+CORE_ADDR expression_context_pc;
+struct block *innermost_block;
+int arglist_len;
+union type_stack_elt *type_stack;
+int type_stack_depth, type_stack_size;
+char *lexptr;
+char *prev_lexptr;
+char *namecopy;
+int paren_depth;
+int comma_terminates;
+
+static int expressiondebug = 0;
+
+extern int hp_som_som_object_present;
+
+static void free_funcalls (void *ignore);
+
+static void prefixify_expression (struct expression *);
+
+static void
+prefixify_subexp (struct expression *, struct expression *, int, int);
+
+void _initialize_parse (void);
+
+/* Data structure for saving values of arglist_len for function calls whose
+ arguments contain other function calls. */
+
+struct funcall
+ {
+ struct funcall *next;
+ int arglist_len;
+ };
+
+static struct funcall *funcall_chain;
+
+/* The generic method for targets to specify how their registers are
+ named. The mapping can be derived from two sources: REGISTER_NAME;
+ or builtin regs. */
+
+int
+target_map_name_to_register (char *str, int len)
+{
+ int i;
+
+ /* Search register name space. */
+ for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+ if (REGISTER_NAME (i) && len == strlen (REGISTER_NAME (i))
+ && STREQN (str, REGISTER_NAME (i), len))
+ {
+ return i;
+ }
+
+ /* Try builtin registers. */
+ i = builtin_reg_map_name_to_regnum (str, len);
+ if (i >= 0)
+ {
+ gdb_assert (i >= NUM_REGS + NUM_PSEUDO_REGS);
+ return i;
+ }
+
+ /* Try builtin registers. */
+ i = builtin_reg_map_name_to_regnum (str, len);
+ if (i >= 0)
+ {
+ gdb_assert (i >= NUM_REGS + NUM_PSEUDO_REGS);
+ return i;
+ }
+
+ return -1;
+}
+
+/* Begin counting arguments for a function call,
+ saving the data about any containing call. */
+
+void
+start_arglist (void)
+{
+ register struct funcall *new;
+
+ new = (struct funcall *) xmalloc (sizeof (struct funcall));
+ new->next = funcall_chain;
+ new->arglist_len = arglist_len;
+ arglist_len = 0;
+ funcall_chain = new;
+}
+
+/* Return the number of arguments in a function call just terminated,
+ and restore the data for the containing function call. */
+
+int
+end_arglist (void)
+{
+ register int val = arglist_len;
+ register struct funcall *call = funcall_chain;
+ funcall_chain = call->next;
+ arglist_len = call->arglist_len;
+ xfree (call);
+ return val;
+}
+
+/* Free everything in the funcall chain.
+ Used when there is an error inside parsing. */
+
+static void
+free_funcalls (void *ignore)
+{
+ register struct funcall *call, *next;
+
+ for (call = funcall_chain; call; call = next)
+ {
+ next = call->next;
+ xfree (call);
+ }
+}
+
+/* This page contains the functions for adding data to the struct expression
+ being constructed. */
+
+/* Add one element to the end of the expression. */
+
+/* To avoid a bug in the Sun 4 compiler, we pass things that can fit into
+ a register through here */
+
+void
+write_exp_elt (union exp_element expelt)
+{
+ if (expout_ptr >= expout_size)
+ {
+ expout_size *= 2;
+ expout = (struct expression *)
+ xrealloc ((char *) expout, sizeof (struct expression)
+ + EXP_ELEM_TO_BYTES (expout_size));
+ }
+ expout->elts[expout_ptr++] = expelt;
+}
+
+void
+write_exp_elt_opcode (enum exp_opcode expelt)
+{
+ union exp_element tmp;
+
+ tmp.opcode = expelt;
+
+ write_exp_elt (tmp);
+}
+
+void
+write_exp_elt_sym (struct symbol *expelt)
+{
+ union exp_element tmp;
+
+ tmp.symbol = expelt;
+
+ write_exp_elt (tmp);
+}
+
+void
+write_exp_elt_block (struct block *b)
+{
+ union exp_element tmp;
+ tmp.block = b;
+ write_exp_elt (tmp);
+}
+
+void
+write_exp_elt_longcst (LONGEST expelt)
+{
+ union exp_element tmp;
+
+ tmp.longconst = expelt;
+
+ write_exp_elt (tmp);
+}
+
+void
+write_exp_elt_dblcst (DOUBLEST expelt)
+{
+ union exp_element tmp;
+
+ tmp.doubleconst = expelt;
+
+ write_exp_elt (tmp);
+}
+
+void
+write_exp_elt_type (struct type *expelt)
+{
+ union exp_element tmp;
+
+ tmp.type = expelt;
+
+ write_exp_elt (tmp);
+}
+
+void
+write_exp_elt_intern (struct internalvar *expelt)
+{
+ union exp_element tmp;
+
+ tmp.internalvar = expelt;
+
+ write_exp_elt (tmp);
+}
+
+/* Add a string constant to the end of the expression.
+
+ String constants are stored by first writing an expression element
+ that contains the length of the string, then stuffing the string
+ constant itself into however many expression elements are needed
+ to hold it, and then writing another expression element that contains
+ the length of the string. I.E. an expression element at each end of
+ the string records the string length, so you can skip over the
+ expression elements containing the actual string bytes from either
+ end of the string. Note that this also allows gdb to handle
+ strings with embedded null bytes, as is required for some languages.
+
+ Don't be fooled by the fact that the string is null byte terminated,
+ this is strictly for the convenience of debugging gdb itself. Gdb
+ Gdb does not depend up the string being null terminated, since the
+ actual length is recorded in expression elements at each end of the
+ string. The null byte is taken into consideration when computing how
+ many expression elements are required to hold the string constant, of
+ course. */
+
+
+void
+write_exp_string (struct stoken str)
+{
+ register int len = str.length;
+ register int lenelt;
+ register char *strdata;
+
+ /* Compute the number of expression elements required to hold the string
+ (including a null byte terminator), along with one expression element
+ at each end to record the actual string length (not including the
+ null byte terminator). */
+
+ lenelt = 2 + BYTES_TO_EXP_ELEM (len + 1);
+
+ /* Ensure that we have enough available expression elements to store
+ everything. */
+
+ if ((expout_ptr + lenelt) >= expout_size)
+ {
+ expout_size = max (expout_size * 2, expout_ptr + lenelt + 10);
+ expout = (struct expression *)
+ xrealloc ((char *) expout, (sizeof (struct expression)
+ + EXP_ELEM_TO_BYTES (expout_size)));
+ }
+
+ /* Write the leading length expression element (which advances the current
+ expression element index), then write the string constant followed by a
+ terminating null byte, and then write the trailing length expression
+ element. */
+
+ write_exp_elt_longcst ((LONGEST) len);
+ strdata = (char *) &expout->elts[expout_ptr];
+ memcpy (strdata, str.ptr, len);
+ *(strdata + len) = '\0';
+ expout_ptr += lenelt - 2;
+ write_exp_elt_longcst ((LONGEST) len);
+}
+
+/* Add a bitstring constant to the end of the expression.
+
+ Bitstring constants are stored by first writing an expression element
+ that contains the length of the bitstring (in bits), then stuffing the
+ bitstring constant itself into however many expression elements are
+ needed to hold it, and then writing another expression element that
+ contains the length of the bitstring. I.E. an expression element at
+ each end of the bitstring records the bitstring length, so you can skip
+ over the expression elements containing the actual bitstring bytes from
+ either end of the bitstring. */
+
+void
+write_exp_bitstring (struct stoken str)
+{
+ register int bits = str.length; /* length in bits */
+ register int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+ register int lenelt;
+ register char *strdata;
+
+ /* Compute the number of expression elements required to hold the bitstring,
+ along with one expression element at each end to record the actual
+ bitstring length in bits. */
+
+ lenelt = 2 + BYTES_TO_EXP_ELEM (len);
+
+ /* Ensure that we have enough available expression elements to store
+ everything. */
+
+ if ((expout_ptr + lenelt) >= expout_size)
+ {
+ expout_size = max (expout_size * 2, expout_ptr + lenelt + 10);
+ expout = (struct expression *)
+ xrealloc ((char *) expout, (sizeof (struct expression)
+ + EXP_ELEM_TO_BYTES (expout_size)));
+ }
+
+ /* Write the leading length expression element (which advances the current
+ expression element index), then write the bitstring constant, and then
+ write the trailing length expression element. */
+
+ write_exp_elt_longcst ((LONGEST) bits);
+ strdata = (char *) &expout->elts[expout_ptr];
+ memcpy (strdata, str.ptr, len);
+ expout_ptr += lenelt - 2;
+ write_exp_elt_longcst ((LONGEST) bits);
+}
+
+/* Add the appropriate elements for a minimal symbol to the end of
+ the expression. The rationale behind passing in text_symbol_type and
+ data_symbol_type was so that Modula-2 could pass in WORD for
+ data_symbol_type. Perhaps it still is useful to have those types vary
+ based on the language, but they no longer have names like "int", so
+ the initial rationale is gone. */
+
+static struct type *msym_text_symbol_type;
+static struct type *msym_data_symbol_type;
+static struct type *msym_unknown_symbol_type;
+
+void
+write_exp_msymbol (struct minimal_symbol *msymbol,
+ struct type *text_symbol_type,
+ struct type *data_symbol_type)
+{
+ CORE_ADDR addr;
+
+ write_exp_elt_opcode (OP_LONG);
+ /* Let's make the type big enough to hold a 64-bit address. */
+ write_exp_elt_type (builtin_type_CORE_ADDR);
+
+ addr = SYMBOL_VALUE_ADDRESS (msymbol);
+ if (overlay_debugging)
+ addr = symbol_overlayed_address (addr, SYMBOL_BFD_SECTION (msymbol));
+ write_exp_elt_longcst ((LONGEST) addr);
+
+ write_exp_elt_opcode (OP_LONG);
+
+ write_exp_elt_opcode (UNOP_MEMVAL);
+ switch (msymbol->type)
+ {
+ case mst_text:
+ case mst_file_text:
+ case mst_solib_trampoline:
+ write_exp_elt_type (msym_text_symbol_type);
+ break;
+
+ case mst_data:
+ case mst_file_data:
+ case mst_bss:
+ case mst_file_bss:
+ write_exp_elt_type (msym_data_symbol_type);
+ break;
+
+ default:
+ write_exp_elt_type (msym_unknown_symbol_type);
+ break;
+ }
+ write_exp_elt_opcode (UNOP_MEMVAL);
+}
+
+/* Recognize tokens that start with '$'. These include:
+
+ $regname A native register name or a "standard
+ register name".
+
+ $variable A convenience variable with a name chosen
+ by the user.
+
+ $digits Value history with index <digits>, starting
+ from the first value which has index 1.
+
+ $$digits Value history with index <digits> relative
+ to the last value. I.E. $$0 is the last
+ value, $$1 is the one previous to that, $$2
+ is the one previous to $$1, etc.
+
+ $ | $0 | $$0 The last value in the value history.
+
+ $$ An abbreviation for the second to the last
+ value in the value history, I.E. $$1
+
+ */
+
+void
+write_dollar_variable (struct stoken str)
+{
+ /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
+ and $$digits (equivalent to $<-digits> if you could type that). */
+
+ int negate = 0;
+ int i = 1;
+ /* Double dollar means negate the number and add -1 as well.
+ Thus $$ alone means -1. */
+ if (str.length >= 2 && str.ptr[1] == '$')
+ {
+ negate = 1;
+ i = 2;
+ }
+ if (i == str.length)
+ {
+ /* Just dollars (one or two) */
+ i = -negate;
+ goto handle_last;
+ }
+ /* Is the rest of the token digits? */
+ for (; i < str.length; i++)
+ if (!(str.ptr[i] >= '0' && str.ptr[i] <= '9'))
+ break;
+ if (i == str.length)
+ {
+ i = atoi (str.ptr + 1 + negate);
+ if (negate)
+ i = -i;
+ goto handle_last;
+ }
+
+ /* Handle tokens that refer to machine registers:
+ $ followed by a register name. */
+ i = target_map_name_to_register (str.ptr + 1, str.length - 1);
+ if (i >= 0)
+ goto handle_register;
+
+ if (SYMBOLS_CAN_START_WITH_DOLLAR)
+ {
+ struct symbol *sym = NULL;
+ struct minimal_symbol *msym = NULL;
+
+ /* On HP-UX, certain system routines (millicode) have names beginning
+ with $ or $$, e.g. $$dyncall, which handles inter-space procedure
+ calls on PA-RISC. Check for those, first. */
+
+ /* This code is not enabled on non HP-UX systems, since worst case
+ symbol table lookup performance is awful, to put it mildly. */
+
+ sym = lookup_symbol (copy_name (str), (struct block *) NULL,
+ VAR_NAMESPACE, (int *) NULL, (struct symtab **) NULL);
+ if (sym)
+ {
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ write_exp_elt_block (block_found); /* set by lookup_symbol */
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ return;
+ }
+ msym = lookup_minimal_symbol (copy_name (str), NULL, NULL);
+ if (msym)
+ {
+ write_exp_msymbol (msym,
+ lookup_function_type (builtin_type_int),
+ builtin_type_int);
+ return;
+ }
+ }
+
+ /* Any other names starting in $ are debugger internal variables. */
+
+ write_exp_elt_opcode (OP_INTERNALVAR);
+ write_exp_elt_intern (lookup_internalvar (copy_name (str) + 1));
+ write_exp_elt_opcode (OP_INTERNALVAR);
+ return;
+handle_last:
+ write_exp_elt_opcode (OP_LAST);
+ write_exp_elt_longcst ((LONGEST) i);
+ write_exp_elt_opcode (OP_LAST);
+ return;
+handle_register:
+ write_exp_elt_opcode (OP_REGISTER);
+ write_exp_elt_longcst (i);
+ write_exp_elt_opcode (OP_REGISTER);
+ return;
+}
+
+
+/* Parse a string that is possibly a namespace / nested class
+ specification, i.e., something of the form A::B::C::x. Input
+ (NAME) is the entire string; LEN is the current valid length; the
+ output is a string, TOKEN, which points to the largest recognized
+ prefix which is a series of namespaces or classes. CLASS_PREFIX is
+ another output, which records whether a nested class spec was
+ recognized (= 1) or a fully qualified variable name was found (=
+ 0). ARGPTR is side-effected (if non-NULL) to point to beyond the
+ string recognized and consumed by this routine.
+
+ The return value is a pointer to the symbol for the base class or
+ variable if found, or NULL if not found. Callers must check this
+ first -- if NULL, the outputs may not be correct.
+
+ This function is used c-exp.y. This is used specifically to get
+ around HP aCC (and possibly other compilers), which insists on
+ generating names with embedded colons for namespace or nested class
+ members.
+
+ (Argument LEN is currently unused. 1997-08-27)
+
+ Callers must free memory allocated for the output string TOKEN. */
+
+static const char coloncolon[2] =
+{':', ':'};
+
+struct symbol *
+parse_nested_classes_for_hpacc (char *name, int len, char **token,
+ int *class_prefix, char **argptr)
+{
+ /* Comment below comes from decode_line_1 which has very similar
+ code, which is called for "break" command parsing. */
+
+ /* We have what looks like a class or namespace
+ scope specification (A::B), possibly with many
+ levels of namespaces or classes (A::B::C::D).
+
+ Some versions of the HP ANSI C++ compiler (as also possibly
+ other compilers) generate class/function/member names with
+ embedded double-colons if they are inside namespaces. To
+ handle this, we loop a few times, considering larger and
+ larger prefixes of the string as though they were single
+ symbols. So, if the initially supplied string is
+ A::B::C::D::foo, we have to look up "A", then "A::B",
+ then "A::B::C", then "A::B::C::D", and finally
+ "A::B::C::D::foo" as single, monolithic symbols, because
+ A, B, C or D may be namespaces.
+
+ Note that namespaces can nest only inside other
+ namespaces, and not inside classes. So we need only
+ consider *prefixes* of the string; there is no need to look up
+ "B::C" separately as a symbol in the previous example. */
+
+ register char *p;
+ char *start, *end;
+ char *prefix = NULL;
+ char *tmp;
+ struct symbol *sym_class = NULL;
+ struct symbol *sym_var = NULL;
+ struct type *t;
+ int prefix_len = 0;
+ int done = 0;
+ char *q;
+
+ /* Check for HP-compiled executable -- in other cases
+ return NULL, and caller must default to standard GDB
+ behaviour. */
+
+ if (!hp_som_som_object_present)
+ return (struct symbol *) NULL;
+
+ p = name;
+
+ /* Skip over whitespace and possible global "::" */
+ while (*p && (*p == ' ' || *p == '\t'))
+ p++;
+ if (p[0] == ':' && p[1] == ':')
+ p += 2;
+ while (*p && (*p == ' ' || *p == '\t'))
+ p++;
+
+ while (1)
+ {
+ /* Get to the end of the next namespace or class spec. */
+ /* If we're looking at some non-token, fail immediately */
+ start = p;
+ if (!(isalpha (*p) || *p == '$' || *p == '_'))
+ return (struct symbol *) NULL;
+ p++;
+ while (*p && (isalnum (*p) || *p == '$' || *p == '_'))
+ p++;
+
+ if (*p == '<')
+ {
+ /* If we have the start of a template specification,
+ scan right ahead to its end */
+ q = find_template_name_end (p);
+ if (q)
+ p = q;
+ }
+
+ end = p;
+
+ /* Skip over "::" and whitespace for next time around */
+ while (*p && (*p == ' ' || *p == '\t'))
+ p++;
+ if (p[0] == ':' && p[1] == ':')
+ p += 2;
+ while (*p && (*p == ' ' || *p == '\t'))
+ p++;
+
+ /* Done with tokens? */
+ if (!*p || !(isalpha (*p) || *p == '$' || *p == '_'))
+ done = 1;
+
+ tmp = (char *) alloca (prefix_len + end - start + 3);
+ if (prefix)
+ {
+ memcpy (tmp, prefix, prefix_len);
+ memcpy (tmp + prefix_len, coloncolon, 2);
+ memcpy (tmp + prefix_len + 2, start, end - start);
+ tmp[prefix_len + 2 + end - start] = '\000';
+ }
+ else
+ {
+ memcpy (tmp, start, end - start);
+ tmp[end - start] = '\000';
+ }
+
+ prefix = tmp;
+ prefix_len = strlen (prefix);
+
+ /* See if the prefix we have now is something we know about */
+
+ if (!done)
+ {
+ /* More tokens to process, so this must be a class/namespace */
+ sym_class = lookup_symbol (prefix, 0, STRUCT_NAMESPACE,
+ 0, (struct symtab **) NULL);
+ }
+ else
+ {
+ /* No more tokens, so try as a variable first */
+ sym_var = lookup_symbol (prefix, 0, VAR_NAMESPACE,
+ 0, (struct symtab **) NULL);
+ /* If failed, try as class/namespace */
+ if (!sym_var)
+ sym_class = lookup_symbol (prefix, 0, STRUCT_NAMESPACE,
+ 0, (struct symtab **) NULL);
+ }
+
+ if (sym_var ||
+ (sym_class &&
+ (t = check_typedef (SYMBOL_TYPE (sym_class)),
+ (TYPE_CODE (t) == TYPE_CODE_STRUCT
+ || TYPE_CODE (t) == TYPE_CODE_UNION))))
+ {
+ /* We found a valid token */
+ *token = (char *) xmalloc (prefix_len + 1);
+ memcpy (*token, prefix, prefix_len);
+ (*token)[prefix_len] = '\000';
+ break;
+ }
+
+ /* No variable or class/namespace found, no more tokens */
+ if (done)
+ return (struct symbol *) NULL;
+ }
+
+ /* Out of loop, so we must have found a valid token */
+ if (sym_var)
+ *class_prefix = 0;
+ else
+ *class_prefix = 1;
+
+ if (argptr)
+ *argptr = done ? p : end;
+
+ return sym_var ? sym_var : sym_class; /* found */
+}
+
+char *
+find_template_name_end (char *p)
+{
+ int depth = 1;
+ int just_seen_right = 0;
+ int just_seen_colon = 0;
+ int just_seen_space = 0;
+
+ if (!p || (*p != '<'))
+ return 0;
+
+ while (*++p)
+ {
+ switch (*p)
+ {
+ case '\'':
+ case '\"':
+ case '{':
+ case '}':
+ /* In future, may want to allow these?? */
+ return 0;
+ case '<':
+ depth++; /* start nested template */
+ if (just_seen_colon || just_seen_right || just_seen_space)
+ return 0; /* but not after : or :: or > or space */
+ break;
+ case '>':
+ if (just_seen_colon || just_seen_right)
+ return 0; /* end a (nested?) template */
+ just_seen_right = 1; /* but not after : or :: */
+ if (--depth == 0) /* also disallow >>, insist on > > */
+ return ++p; /* if outermost ended, return */
+ break;
+ case ':':
+ if (just_seen_space || (just_seen_colon > 1))
+ return 0; /* nested class spec coming up */
+ just_seen_colon++; /* we allow :: but not :::: */
+ break;
+ case ' ':
+ break;
+ default:
+ if (!((*p >= 'a' && *p <= 'z') || /* allow token chars */
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9') ||
+ (*p == '_') || (*p == ',') || /* commas for template args */
+ (*p == '&') || (*p == '*') || /* pointer and ref types */
+ (*p == '(') || (*p == ')') || /* function types */
+ (*p == '[') || (*p == ']'))) /* array types */
+ return 0;
+ }
+ if (*p != ' ')
+ just_seen_space = 0;
+ if (*p != ':')
+ just_seen_colon = 0;
+ if (*p != '>')
+ just_seen_right = 0;
+ }
+ return 0;
+}
+
+
+
+/* Return a null-terminated temporary copy of the name
+ of a string token. */
+
+char *
+copy_name (struct stoken token)
+{
+ memcpy (namecopy, token.ptr, token.length);
+ namecopy[token.length] = 0;
+ return namecopy;
+}
+
+/* Reverse an expression from suffix form (in which it is constructed)
+ to prefix form (in which we can conveniently print or execute it). */
+
+static void
+prefixify_expression (register struct expression *expr)
+{
+ register int len =
+ sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
+ register struct expression *temp;
+ register int inpos = expr->nelts, outpos = 0;
+
+ temp = (struct expression *) alloca (len);
+
+ /* Copy the original expression into temp. */
+ memcpy (temp, expr, len);
+
+ prefixify_subexp (temp, expr, inpos, outpos);
+}
+
+/* Return the number of exp_elements in the subexpression of EXPR
+ whose last exp_element is at index ENDPOS - 1 in EXPR. */
+
+int
+length_of_subexp (register struct expression *expr, register int endpos)
+{
+ register int oplen = 1;
+ register int args = 0;
+ register int i;
+
+ if (endpos < 1)
+ error ("?error in length_of_subexp");
+
+ i = (int) expr->elts[endpos - 1].opcode;
+
+ switch (i)
+ {
+ /* C++ */
+ case OP_SCOPE:
+ oplen = longest_to_int (expr->elts[endpos - 2].longconst);
+ oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
+ break;
+
+ case OP_LONG:
+ case OP_DOUBLE:
+ case OP_VAR_VALUE:
+ oplen = 4;
+ break;
+
+ case OP_TYPE:
+ case OP_BOOL:
+ case OP_LAST:
+ case OP_REGISTER:
+ case OP_INTERNALVAR:
+ oplen = 3;
+ break;
+
+ case OP_COMPLEX:
+ oplen = 1;
+ args = 2;
+ break;
+
+ case OP_FUNCALL:
+ case OP_F77_UNDETERMINED_ARGLIST:
+ oplen = 3;
+ args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
+ break;
+
+ case UNOP_MAX:
+ case UNOP_MIN:
+ oplen = 3;
+ break;
+
+ case BINOP_VAL:
+ case UNOP_CAST:
+ case UNOP_MEMVAL:
+ oplen = 3;
+ args = 1;
+ break;
+
+ case UNOP_ABS:
+ case UNOP_CAP:
+ case UNOP_CHR:
+ case UNOP_FLOAT:
+ case UNOP_HIGH:
+ case UNOP_ODD:
+ case UNOP_ORD:
+ case UNOP_TRUNC:
+ oplen = 1;
+ args = 1;
+ break;
+
+ case OP_LABELED:
+ case STRUCTOP_STRUCT:
+ case STRUCTOP_PTR:
+ args = 1;
+ /* fall through */
+ case OP_M2_STRING:
+ case OP_STRING:
+ case OP_NAME:
+ case OP_EXPRSTRING:
+ oplen = longest_to_int (expr->elts[endpos - 2].longconst);
+ oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
+ break;
+
+ case OP_BITSTRING:
+ oplen = longest_to_int (expr->elts[endpos - 2].longconst);
+ oplen = (oplen + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+ oplen = 4 + BYTES_TO_EXP_ELEM (oplen);
+ break;
+
+ case OP_ARRAY:
+ oplen = 4;
+ args = longest_to_int (expr->elts[endpos - 2].longconst);
+ args -= longest_to_int (expr->elts[endpos - 3].longconst);
+ args += 1;
+ break;
+
+ case TERNOP_COND:
+ case TERNOP_SLICE:
+ case TERNOP_SLICE_COUNT:
+ args = 3;
+ break;
+
+ /* Modula-2 */
+ case MULTI_SUBSCRIPT:
+ oplen = 3;
+ args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
+ break;
+
+ case BINOP_ASSIGN_MODIFY:
+ oplen = 3;
+ args = 2;
+ break;
+
+ /* C++ */
+ case OP_THIS:
+ oplen = 2;
+ break;
+
+ default:
+ args = 1 + (i < (int) BINOP_END);
+ }
+
+ while (args > 0)
+ {
+ oplen += length_of_subexp (expr, endpos - oplen);
+ args--;
+ }
+
+ return oplen;
+}
+
+/* Copy the subexpression ending just before index INEND in INEXPR
+ into OUTEXPR, starting at index OUTBEG.
+ In the process, convert it from suffix to prefix form. */
+
+static void
+prefixify_subexp (register struct expression *inexpr,
+ struct expression *outexpr, register int inend, int outbeg)
+{
+ register int oplen = 1;
+ register int args = 0;
+ register int i;
+ int *arglens;
+ enum exp_opcode opcode;
+
+ /* Compute how long the last operation is (in OPLEN),
+ and also how many preceding subexpressions serve as
+ arguments for it (in ARGS). */
+
+ opcode = inexpr->elts[inend - 1].opcode;
+ switch (opcode)
+ {
+ /* C++ */
+ case OP_SCOPE:
+ oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
+ oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
+ break;
+
+ case OP_LONG:
+ case OP_DOUBLE:
+ case OP_VAR_VALUE:
+ oplen = 4;
+ break;
+
+ case OP_TYPE:
+ case OP_BOOL:
+ case OP_LAST:
+ case OP_REGISTER:
+ case OP_INTERNALVAR:
+ oplen = 3;
+ break;
+
+ case OP_COMPLEX:
+ oplen = 1;
+ args = 2;
+ break;
+
+ case OP_FUNCALL:
+ case OP_F77_UNDETERMINED_ARGLIST:
+ oplen = 3;
+ args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
+ break;
+
+ case UNOP_MIN:
+ case UNOP_MAX:
+ oplen = 3;
+ break;
+
+ case UNOP_CAST:
+ case UNOP_MEMVAL:
+ oplen = 3;
+ args = 1;
+ break;
+
+ case UNOP_ABS:
+ case UNOP_CAP:
+ case UNOP_CHR:
+ case UNOP_FLOAT:
+ case UNOP_HIGH:
+ case UNOP_ODD:
+ case UNOP_ORD:
+ case UNOP_TRUNC:
+ oplen = 1;
+ args = 1;
+ break;
+
+ case STRUCTOP_STRUCT:
+ case STRUCTOP_PTR:
+ case OP_LABELED:
+ args = 1;
+ /* fall through */
+ case OP_M2_STRING:
+ case OP_STRING:
+ case OP_NAME:
+ case OP_EXPRSTRING:
+ oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
+ oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
+ break;
+
+ case OP_BITSTRING:
+ oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
+ oplen = (oplen + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+ oplen = 4 + BYTES_TO_EXP_ELEM (oplen);
+ break;
+
+ case OP_ARRAY:
+ oplen = 4;
+ args = longest_to_int (inexpr->elts[inend - 2].longconst);
+ args -= longest_to_int (inexpr->elts[inend - 3].longconst);
+ args += 1;
+ break;
+
+ case TERNOP_COND:
+ case TERNOP_SLICE:
+ case TERNOP_SLICE_COUNT:
+ args = 3;
+ break;
+
+ case BINOP_ASSIGN_MODIFY:
+ oplen = 3;
+ args = 2;
+ break;
+
+ /* Modula-2 */
+ case MULTI_SUBSCRIPT:
+ oplen = 3;
+ args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
+ break;
+
+ /* C++ */
+ case OP_THIS:
+ oplen = 2;
+ break;
+
+ default:
+ args = 1 + ((int) opcode < (int) BINOP_END);
+ }
+
+ /* Copy the final operator itself, from the end of the input
+ to the beginning of the output. */
+ inend -= oplen;
+ memcpy (&outexpr->elts[outbeg], &inexpr->elts[inend],
+ EXP_ELEM_TO_BYTES (oplen));
+ outbeg += oplen;
+
+ /* Find the lengths of the arg subexpressions. */
+ arglens = (int *) alloca (args * sizeof (int));
+ for (i = args - 1; i >= 0; i--)
+ {
+ oplen = length_of_subexp (inexpr, inend);
+ arglens[i] = oplen;
+ inend -= oplen;
+ }
+
+ /* Now copy each subexpression, preserving the order of
+ the subexpressions, but prefixifying each one.
+ In this loop, inend starts at the beginning of
+ the expression this level is working on
+ and marches forward over the arguments.
+ outbeg does similarly in the output. */
+ for (i = 0; i < args; i++)
+ {
+ oplen = arglens[i];
+ inend += oplen;
+ prefixify_subexp (inexpr, outexpr, inend, outbeg);
+ outbeg += oplen;
+ }
+}
+
+/* This page contains the two entry points to this file. */
+
+/* Read an expression from the string *STRINGPTR points to,
+ parse it, and return a pointer to a struct expression that we malloc.
+ Use block BLOCK as the lexical context for variable names;
+ if BLOCK is zero, use the block of the selected stack frame.
+ Meanwhile, advance *STRINGPTR to point after the expression,
+ at the first nonwhite character that is not part of the expression
+ (possibly a null character).
+
+ If COMMA is nonzero, stop if a comma is reached. */
+
+struct expression *
+parse_exp_1 (char **stringptr, struct block *block, int comma)
+{
+ struct cleanup *old_chain;
+
+ lexptr = *stringptr;
+ prev_lexptr = NULL;
+
+ paren_depth = 0;
+ type_stack_depth = 0;
+
+ comma_terminates = comma;
+
+ if (lexptr == 0 || *lexptr == 0)
+ error_no_arg ("expression to compute");
+
+ old_chain = make_cleanup (free_funcalls, 0 /*ignore*/);
+ funcall_chain = 0;
+
+ if (block)
+ {
+ expression_context_block = block;
+ expression_context_pc = block->startaddr;
+ }
+ else
+ expression_context_block = get_selected_block (&expression_context_pc);
+
+ namecopy = (char *) alloca (strlen (lexptr) + 1);
+ expout_size = 10;
+ expout_ptr = 0;
+ expout = (struct expression *)
+ xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_size));
+ expout->language_defn = current_language;
+ make_cleanup (free_current_contents, &expout);
+
+ if (current_language->la_parser ())
+ current_language->la_error (NULL);
+
+ discard_cleanups (old_chain);
+
+ /* Record the actual number of expression elements, and then
+ reallocate the expression memory so that we free up any
+ excess elements. */
+
+ expout->nelts = expout_ptr;
+ expout = (struct expression *)
+ xrealloc ((char *) expout,
+ sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_ptr));;
+
+ /* Convert expression from postfix form as generated by yacc
+ parser, to a prefix form. */
+
+ if (expressiondebug)
+ dump_prefix_expression (expout, gdb_stdlog,
+ "before conversion to prefix form");
+
+ prefixify_expression (expout);
+
+ if (expressiondebug)
+ dump_postfix_expression (expout, gdb_stdlog,
+ "after conversion to prefix form");
+
+ *stringptr = lexptr;
+ return expout;
+}
+
+/* Parse STRING as an expression, and complain if this fails
+ to use up all of the contents of STRING. */
+
+struct expression *
+parse_expression (char *string)
+{
+ register struct expression *exp;
+ exp = parse_exp_1 (&string, 0, 0);
+ if (*string)
+ error ("Junk after end of expression.");
+ return exp;
+}
+
+/* Stuff for maintaining a stack of types. Currently just used by C, but
+ probably useful for any language which declares its types "backwards". */
+
+static void
+check_type_stack_depth (void)
+{
+ if (type_stack_depth == type_stack_size)
+ {
+ type_stack_size *= 2;
+ type_stack = (union type_stack_elt *)
+ xrealloc ((char *) type_stack, type_stack_size * sizeof (*type_stack));
+ }
+}
+
+void
+push_type (enum type_pieces tp)
+{
+ check_type_stack_depth ();
+ type_stack[type_stack_depth++].piece = tp;
+}
+
+void
+push_type_int (int n)
+{
+ check_type_stack_depth ();
+ type_stack[type_stack_depth++].int_val = n;
+}
+
+void
+push_type_address_space (char *string)
+{
+ push_type_int (address_space_name_to_int (string));
+}
+
+enum type_pieces
+pop_type (void)
+{
+ if (type_stack_depth)
+ return type_stack[--type_stack_depth].piece;
+ return tp_end;
+}
+
+int
+pop_type_int (void)
+{
+ if (type_stack_depth)
+ return type_stack[--type_stack_depth].int_val;
+ /* "Can't happen". */
+ return 0;
+}
+
+/* Pop the type stack and return the type which corresponds to FOLLOW_TYPE
+ as modified by all the stuff on the stack. */
+struct type *
+follow_types (struct type *follow_type)
+{
+ int done = 0;
+ int make_const = 0;
+ int make_volatile = 0;
+ int make_addr_space = 0;
+ int array_size;
+ struct type *range_type;
+
+ while (!done)
+ switch (pop_type ())
+ {
+ case tp_end:
+ done = 1;
+ if (make_const)
+ follow_type = make_cv_type (make_const,
+ TYPE_VOLATILE (follow_type),
+ follow_type, 0);
+ if (make_volatile)
+ follow_type = make_cv_type (TYPE_CONST (follow_type),
+ make_volatile,
+ follow_type, 0);
+ if (make_addr_space)
+ follow_type = make_type_with_address_space (follow_type,
+ make_addr_space);
+ make_const = make_volatile = 0;
+ make_addr_space = 0;
+ break;
+ case tp_const:
+ make_const = 1;
+ break;
+ case tp_volatile:
+ make_volatile = 1;
+ break;
+ case tp_space_identifier:
+ make_addr_space = pop_type_int ();
+ break;
+ case tp_pointer:
+ follow_type = lookup_pointer_type (follow_type);
+ if (make_const)
+ follow_type = make_cv_type (make_const,
+ TYPE_VOLATILE (follow_type),
+ follow_type, 0);
+ if (make_volatile)
+ follow_type = make_cv_type (TYPE_CONST (follow_type),
+ make_volatile,
+ follow_type, 0);
+ if (make_addr_space)
+ follow_type = make_type_with_address_space (follow_type,
+ make_addr_space);
+ make_const = make_volatile = 0;
+ make_addr_space = 0;
+ break;
+ case tp_reference:
+ follow_type = lookup_reference_type (follow_type);
+ if (make_const)
+ follow_type = make_cv_type (make_const,
+ TYPE_VOLATILE (follow_type),
+ follow_type, 0);
+ if (make_volatile)
+ follow_type = make_cv_type (TYPE_CONST (follow_type),
+ make_volatile,
+ follow_type, 0);
+ if (make_addr_space)
+ follow_type = make_type_with_address_space (follow_type,
+ make_addr_space);
+ make_const = make_volatile = 0;
+ make_addr_space = 0;
+ break;
+ case tp_array:
+ array_size = pop_type_int ();
+ /* FIXME-type-allocation: need a way to free this type when we are
+ done with it. */
+ range_type =
+ create_range_type ((struct type *) NULL,
+ builtin_type_int, 0,
+ array_size >= 0 ? array_size - 1 : 0);
+ follow_type =
+ create_array_type ((struct type *) NULL,
+ follow_type, range_type);
+ if (array_size < 0)
+ TYPE_ARRAY_UPPER_BOUND_TYPE (follow_type)
+ = BOUND_CANNOT_BE_DETERMINED;
+ break;
+ case tp_function:
+ /* FIXME-type-allocation: need a way to free this type when we are
+ done with it. */
+ follow_type = lookup_function_type (follow_type);
+ break;
+ }
+ return follow_type;
+}
+
+static void build_parse (void);
+static void
+build_parse (void)
+{
+ int i;
+
+ msym_text_symbol_type =
+ init_type (TYPE_CODE_FUNC, 1, 0, "<text variable, no debug info>", NULL);
+ TYPE_TARGET_TYPE (msym_text_symbol_type) = builtin_type_int;
+ msym_data_symbol_type =
+ init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0,
+ "<data variable, no debug info>", NULL);
+ msym_unknown_symbol_type =
+ init_type (TYPE_CODE_INT, 1, 0,
+ "<variable (not text or data), no debug info>",
+ NULL);
+}
+
+void
+_initialize_parse (void)
+{
+ type_stack_size = 80;
+ type_stack_depth = 0;
+ type_stack = (union type_stack_elt *)
+ xmalloc (type_stack_size * sizeof (*type_stack));
+
+ build_parse ();
+
+ /* FIXME - For the moment, handle types by swapping them in and out.
+ Should be using the per-architecture data-pointer and a large
+ struct. */
+ register_gdbarch_swap (&msym_text_symbol_type, sizeof (msym_text_symbol_type), NULL);
+ register_gdbarch_swap (&msym_data_symbol_type, sizeof (msym_data_symbol_type), NULL);
+ register_gdbarch_swap (&msym_unknown_symbol_type, sizeof (msym_unknown_symbol_type), NULL);
+
+ register_gdbarch_swap (NULL, 0, build_parse);
+
+ add_show_from_set (
+ add_set_cmd ("expression", class_maintenance, var_zinteger,
+ (char *) &expressiondebug,
+ "Set expression debugging.\n\
+When non-zero, the internal representation of expressions will be printed.",
+ &setdebuglist),
+ &showdebuglist);
+}
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
new file mode 100644
index 00000000000..7db1c77e123
--- /dev/null
+++ b/gdb/parser-defs.h
@@ -0,0 +1,219 @@
+/* Parser definitions for GDB.
+
+ Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+
+ Modified from expread.y by the Department of Computer Science at the
+ State University of New York at Buffalo.
+
+ 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. */
+
+#if !defined (PARSER_DEFS_H)
+#define PARSER_DEFS_H 1
+
+#include "doublest.h"
+
+extern struct expression *expout;
+extern int expout_size;
+extern int expout_ptr;
+
+/* If this is nonzero, this block is used as the lexical context
+ for symbol names. */
+
+extern struct block *expression_context_block;
+
+/* If expression_context_block is non-zero, then this is the PC within
+ the block that we want to evaluate expressions at. When debugging
+ C or C++ code, we use this to find the exact line we're at, and
+ then look up the macro definitions active at that point. */
+CORE_ADDR expression_context_pc;
+
+/* The innermost context required by the stack and register variables
+ we've encountered so far. */
+extern struct block *innermost_block;
+
+/* The block in which the most recently discovered symbol was found.
+ FIXME: Should be declared along with lookup_symbol in symtab.h; is not
+ related specifically to parsing. */
+extern struct block *block_found;
+
+/* Number of arguments seen so far in innermost function call. */
+extern int arglist_len;
+
+/* A string token, either a char-string or bit-string. Char-strings are
+ used, for example, for the names of symbols. */
+
+struct stoken
+ {
+ /* Pointer to first byte of char-string or first bit of bit-string */
+ char *ptr;
+ /* Length of string in bytes for char-string or bits for bit-string */
+ int length;
+ };
+
+struct ttype
+ {
+ struct stoken stoken;
+ struct type *type;
+ };
+
+struct symtoken
+ {
+ struct stoken stoken;
+ struct symbol *sym;
+ int is_a_field_of_this;
+ };
+
+/* For parsing of complicated types.
+ An array should be preceded in the list by the size of the array. */
+enum type_pieces
+ {
+ tp_end = -1,
+ tp_pointer,
+ tp_reference,
+ tp_array,
+ tp_function,
+ tp_const,
+ tp_volatile,
+ tp_space_identifier
+ };
+/* The stack can contain either an enum type_pieces or an int. */
+union type_stack_elt
+ {
+ enum type_pieces piece;
+ int int_val;
+ };
+extern union type_stack_elt *type_stack;
+extern int type_stack_depth, type_stack_size;
+
+extern void write_exp_elt (union exp_element);
+
+extern void write_exp_elt_opcode (enum exp_opcode);
+
+extern void write_exp_elt_sym (struct symbol *);
+
+extern void write_exp_elt_longcst (LONGEST);
+
+extern void write_exp_elt_dblcst (DOUBLEST);
+
+extern void write_exp_elt_type (struct type *);
+
+extern void write_exp_elt_intern (struct internalvar *);
+
+extern void write_exp_string (struct stoken);
+
+extern void write_exp_bitstring (struct stoken);
+
+extern void write_exp_elt_block (struct block *);
+
+extern void write_exp_msymbol (struct minimal_symbol *,
+ struct type *, struct type *);
+
+extern void write_dollar_variable (struct stoken str);
+
+extern struct symbol *parse_nested_classes_for_hpacc (char *, int, char **,
+ int *, char **);
+
+extern char *find_template_name_end (char *);
+
+extern void start_arglist (void);
+
+extern int end_arglist (void);
+
+extern char *copy_name (struct stoken);
+
+extern void push_type (enum type_pieces);
+
+extern void push_type_int (int);
+
+extern void push_type_address_space (char *);
+
+extern enum type_pieces pop_type (void);
+
+extern int pop_type_int (void);
+
+extern int length_of_subexp (struct expression *, int);
+
+extern struct type *follow_types (struct type *);
+
+/* During parsing of a C expression, the pointer to the next character
+ is in this variable. */
+
+extern char *lexptr;
+
+/* After a token has been recognized, this variable points to it.
+ Currently used only for error reporting. */
+extern char *prev_lexptr;
+
+/* Tokens that refer to names do so with explicit pointer and length,
+ so they can share the storage that lexptr is parsing.
+
+ When it is necessary to pass a name to a function that expects
+ a null-terminated string, the substring is copied out
+ into a block of storage that namecopy points to.
+
+ namecopy is allocated once, guaranteed big enough, for each parsing. */
+
+extern char *namecopy;
+
+/* Current depth in parentheses within the expression. */
+
+extern int paren_depth;
+
+/* Nonzero means stop parsing on first comma (if not within parentheses). */
+
+extern int comma_terminates;
+
+/* These codes indicate operator precedences for expression printing,
+ least tightly binding first. */
+/* Adding 1 to a precedence value is done for binary operators,
+ on the operand which is more tightly bound, so that operators
+ of equal precedence within that operand will get parentheses. */
+/* PREC_HYPER and PREC_ABOVE_COMMA are not the precedence of any operator;
+ they are used as the "surrounding precedence" to force
+ various kinds of things to be parenthesized. */
+enum precedence
+ {
+ PREC_NULL, PREC_COMMA, PREC_ABOVE_COMMA, PREC_ASSIGN, PREC_LOGICAL_OR,
+ PREC_LOGICAL_AND, PREC_BITWISE_IOR, PREC_BITWISE_AND, PREC_BITWISE_XOR,
+ PREC_EQUAL, PREC_ORDER, PREC_SHIFT, PREC_ADD, PREC_MUL, PREC_REPEAT,
+ PREC_HYPER, PREC_PREFIX, PREC_SUFFIX, PREC_BUILTIN_FUNCTION
+ };
+
+/* Table mapping opcodes into strings for printing operators
+ and precedences of the operators. */
+
+struct op_print
+ {
+ char *string;
+ enum exp_opcode opcode;
+ /* Precedence of operator. These values are used only by comparisons. */
+ enum precedence precedence;
+
+ /* For a binary operator: 1 iff right associate.
+ For a unary operator: 1 iff postfix. */
+ int right_assoc;
+ };
+
+/* The generic method for targets to specify how their registers are
+ named. The mapping can be derived from two sources: REGISTER_NAME;
+ and builtin regs. */
+
+extern int target_map_name_to_register (char *, int);
+
+#endif /* PARSER_DEFS_H */
diff --git a/gdb/ppc-bdm.c b/gdb/ppc-bdm.c
new file mode 100644
index 00000000000..0797e0d64d2
--- /dev/null
+++ b/gdb/ppc-bdm.c
@@ -0,0 +1,388 @@
+/* Remote target communications for the Macraigor Systems BDM Wiggler
+ talking to a Motorola PPC 8xx ADS board
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "gdbcore.h"
+#include "gdb_string.h"
+#include <fcntl.h>
+#include "frame.h"
+#include "inferior.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "target.h"
+#include "gdbcmd.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include <sys/types.h>
+#include "serial.h"
+#include "ocd.h"
+#include "ppc-tdep.h"
+#include "regcache.h"
+
+static void bdm_ppc_open (char *name, int from_tty);
+
+static ptid_t bdm_ppc_wait (ptid_t ptid,
+ struct target_waitstatus *target_status);
+
+static void bdm_ppc_fetch_registers (int regno);
+
+static void bdm_ppc_store_registers (int regno);
+
+extern struct target_ops bdm_ppc_ops; /* Forward decl */
+
+/*#define BDM_NUM_REGS 71 */
+#define BDM_NUM_REGS 24
+
+#define BDM_REGMAP \
+ 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, /* r0-r7 */ \
+ 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, /* r8-r15 */ \
+ 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, /* r16-r23 */ \
+ 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, /* r24-r31 */ \
+\
+ 2080, 2082, 2084, 2086, 2088, 2090, 2092, 2094, /* fp0->fp8 */ \
+ 2096, 2098, 2100, 2102, 2104, 2106, 2108, 2110, /* fp0->fp8 */ \
+ 2112, 2114, 2116, 2118, 2120, 2122, 2124, 2126, /* fp0->fp8 */ \
+ 2128, 2130, 2132, 2134, 2136, 2138, 2140, 2142, /* fp0->fp8 */ \
+\
+ 26, /* pc (SRR0 (SPR 26)) */ \
+ 2146, /* ps (MSR) */ \
+ 2144, /* cnd (CR) */ \
+ 8, /* lr (SPR 8) */ \
+ 9, /* cnt (CTR (SPR 9)) */ \
+ 1, /* xer (SPR 1) */ \
+ 0, /* mq (SPR 0) */
+
+
+char nowatchdog[4] =
+{0xff, 0xff, 0xff, 0x88};
+
+/* Open a connection to a remote debugger.
+ NAME is the filename used for communication. */
+
+static void
+bdm_ppc_open (char *name, int from_tty)
+{
+ CORE_ADDR watchdogaddr = 0xff000004;
+
+ ocd_open (name, from_tty, OCD_TARGET_MOTO_PPC, &bdm_ppc_ops);
+
+ /* We want interrupts to drop us into debugging mode. */
+ /* Modify the DER register to accomplish this. */
+ ocd_write_bdm_register (149, 0x20024000);
+
+ /* Disable watchdog timer on the board */
+ ocd_write_bytes (watchdogaddr, nowatchdog, 4);
+}
+
+/* Wait until the remote machine stops, then return,
+ storing status in STATUS just as `wait' would.
+ Returns "pid" (though it's not clear what, if anything, that
+ means in the case of this target). */
+
+static ptid_t
+bdm_ppc_wait (ptid_t ptid, struct target_waitstatus *target_status)
+{
+ int stop_reason;
+
+ target_status->kind = TARGET_WAITKIND_STOPPED;
+
+ stop_reason = ocd_wait ();
+
+ if (stop_reason)
+ {
+ target_status->value.sig = TARGET_SIGNAL_INT;
+ return inferior_ptid;
+ }
+
+ target_status->value.sig = TARGET_SIGNAL_TRAP; /* XXX for now */
+
+#if 0
+ {
+ unsigned long ecr, der;
+
+ ecr = ocd_read_bdm_register (148); /* Read the exception cause register */
+ der = ocd_read_bdm_register (149); /* Read the debug enables register */
+ fprintf_unfiltered (gdb_stdout, "ecr = 0x%x, der = 0x%x\n", ecr, der);
+ }
+#endif
+
+ return inferior_ptid;
+}
+
+static int bdm_regmap[] =
+{BDM_REGMAP};
+
+/* Read the remote registers into regs.
+ Fetch register REGNO, or all registers if REGNO == -1
+
+ The Wiggler uses the following codes to access the registers:
+
+ 0 -> 1023 SPR 0 -> 1023
+ 0 - SPR 0 - MQ
+ 1 - SPR 1 - XER
+ 8 - SPR 8 - LR
+ 9 - SPR 9 - CTR (known as cnt in GDB)
+ 26 - SPR 26 - SRR0 - pc
+ 1024 -> 2047 DCR 0 -> DCR 1023 (IBM PPC 4xx only)
+ 2048 -> 2079 R0 -> R31
+ 2080 -> 2143 FP0 -> FP31 (64 bit regs) (IBM PPC 5xx only)
+ 2144 CR (known as cnd in GDB)
+ 2145 FPCSR
+ 2146 MSR (known as ps in GDB)
+ */
+
+static void
+bdm_ppc_fetch_registers (int regno)
+{
+ int i;
+ unsigned char *regs, *beginregs, *endregs, *almostregs;
+ unsigned char midregs[32];
+ unsigned char mqreg[1];
+ int first_regno, last_regno;
+ int first_bdm_regno, last_bdm_regno;
+ int reglen, beginreglen, endreglen;
+
+#if 1
+ for (i = 0; i < (FPLAST_REGNUM - FP0_REGNUM + 1); i++)
+ {
+ midregs[i] = -1;
+ }
+ mqreg[0] = -1;
+#endif
+
+ if (regno == -1)
+ {
+ first_regno = 0;
+ last_regno = NUM_REGS - 1;
+
+ first_bdm_regno = 0;
+ last_bdm_regno = BDM_NUM_REGS - 1;
+ }
+ else
+ {
+ first_regno = regno;
+ last_regno = regno;
+
+ first_bdm_regno = bdm_regmap[regno];
+ last_bdm_regno = bdm_regmap[regno];
+ }
+
+ if (first_bdm_regno == -1)
+ {
+ supply_register (first_regno, NULL);
+ return; /* Unsupported register */
+ }
+
+#if 1
+ /* Can't ask for floating point regs on ppc 8xx, also need to
+ avoid asking for the mq register. */
+ if (first_regno == last_regno) /* only want one reg */
+ {
+/* printf("Asking for register %d\n", first_regno); */
+
+ /* if asking for an invalid register */
+ if ((first_regno == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
+ || (first_regno == gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum)
+ || ((first_regno >= FP0_REGNUM) && (first_regno <= FPLAST_REGNUM)))
+ {
+/* printf("invalid reg request!\n"); */
+ supply_register (first_regno, NULL);
+ return; /* Unsupported register */
+ }
+ else
+ {
+ regs = ocd_read_bdm_registers (first_bdm_regno,
+ last_bdm_regno, &reglen);
+ }
+ }
+ else
+ /* want all regs */
+ {
+/* printf("Asking for registers %d to %d\n", first_regno, last_regno); */
+ beginregs = ocd_read_bdm_registers (first_bdm_regno,
+ FP0_REGNUM - 1, &beginreglen);
+ endregs = (strcat (midregs,
+ ocd_read_bdm_registers (FPLAST_REGNUM + 1,
+ last_bdm_regno - 1, &endreglen)));
+ almostregs = (strcat (beginregs, endregs));
+ regs = (strcat (almostregs, mqreg));
+ reglen = beginreglen + 32 + endreglen + 1;
+ }
+
+#endif
+#if 0
+ regs = ocd_read_bdm_registers (first_bdm_regno, last_bdm_regno, &reglen);
+#endif
+
+ for (i = first_regno; i <= last_regno; i++)
+ {
+ int bdm_regno, regoffset;
+
+ bdm_regno = bdm_regmap[i];
+ if (bdm_regno != -1)
+ {
+ regoffset = bdm_regno - first_bdm_regno;
+
+ if (regoffset >= reglen / 4)
+ continue;
+
+ supply_register (i, regs + 4 * regoffset);
+ }
+ else
+ supply_register (i, NULL); /* Unsupported register */
+ }
+}
+
+/* Store register REGNO, or all registers if REGNO == -1, from the contents
+ of REGISTERS. FIXME: ignores errors. */
+
+static void
+bdm_ppc_store_registers (int regno)
+{
+ int i;
+ int first_regno, last_regno;
+ int first_bdm_regno, last_bdm_regno;
+
+ if (regno == -1)
+ {
+ first_regno = 0;
+ last_regno = NUM_REGS - 1;
+
+ first_bdm_regno = 0;
+ last_bdm_regno = BDM_NUM_REGS - 1;
+ }
+ else
+ {
+ first_regno = regno;
+ last_regno = regno;
+
+ first_bdm_regno = bdm_regmap[regno];
+ last_bdm_regno = bdm_regmap[regno];
+ }
+
+ if (first_bdm_regno == -1)
+ return; /* Unsupported register */
+
+ for (i = first_regno; i <= last_regno; i++)
+ {
+ int bdm_regno;
+
+ bdm_regno = bdm_regmap[i];
+
+ /* only attempt to write if it's a valid ppc 8xx register */
+ /* (need to avoid FP regs and MQ reg) */
+ if ((i != gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
+ && (i != gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum)
+ && ((i < FP0_REGNUM) || (i > FPLAST_REGNUM)))
+ {
+/* printf("write valid reg %d\n", bdm_regno); */
+ ocd_write_bdm_registers (bdm_regno, registers + REGISTER_BYTE (i), 4);
+ }
+/*
+ else if (i == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
+ printf("don't write invalid reg %d (PPC_MQ_REGNUM)\n", bdm_regno);
+ else
+ printf("don't write invalid reg %d\n", bdm_regno);
+ */
+ }
+}
+
+/* Define the target subroutine names */
+
+struct target_ops bdm_ppc_ops;
+
+static void
+init_bdm_ppc_ops (void)
+{
+ bdm_ppc_ops.to_shortname = "ocd";
+ bdm_ppc_ops.to_longname = "Remote target with On-Chip Debugging";
+ bdm_ppc_ops.to_doc = "Use a remote target with On-Chip Debugging. To use a target box;\n\
+specify the serial device it is connected to (e.g. /dev/ttya). To use\n\
+a wiggler, specify wiggler and then the port it is connected to\n\
+(e.g. wiggler lpt1)."; /* to_doc */
+ bdm_ppc_ops.to_open = bdm_ppc_open;
+ bdm_ppc_ops.to_close = ocd_close;
+ bdm_ppc_ops.to_attach = NULL;
+ bdm_ppc_ops.to_post_attach = NULL;
+ bdm_ppc_ops.to_require_attach = NULL;
+ bdm_ppc_ops.to_detach = ocd_detach;
+ bdm_ppc_ops.to_require_detach = NULL;
+ bdm_ppc_ops.to_resume = ocd_resume;
+ bdm_ppc_ops.to_wait = bdm_ppc_wait;
+ bdm_ppc_ops.to_post_wait = NULL;
+ bdm_ppc_ops.to_fetch_registers = bdm_ppc_fetch_registers;
+ bdm_ppc_ops.to_store_registers = bdm_ppc_store_registers;
+ bdm_ppc_ops.to_prepare_to_store = ocd_prepare_to_store;
+ bdm_ppc_ops.to_xfer_memory = ocd_xfer_memory;
+ bdm_ppc_ops.to_files_info = ocd_files_info;
+ bdm_ppc_ops.to_insert_breakpoint = ocd_insert_breakpoint;
+ bdm_ppc_ops.to_remove_breakpoint = ocd_remove_breakpoint;
+ bdm_ppc_ops.to_terminal_init = NULL;
+ bdm_ppc_ops.to_terminal_inferior = NULL;
+ bdm_ppc_ops.to_terminal_ours_for_output = NULL;
+ bdm_ppc_ops.to_terminal_ours = NULL;
+ bdm_ppc_ops.to_terminal_info = NULL;
+ bdm_ppc_ops.to_kill = ocd_kill;
+ bdm_ppc_ops.to_load = ocd_load;
+ bdm_ppc_ops.to_lookup_symbol = NULL;
+ bdm_ppc_ops.to_create_inferior = ocd_create_inferior;
+ bdm_ppc_ops.to_post_startup_inferior = NULL;
+ bdm_ppc_ops.to_acknowledge_created_inferior = NULL;
+ bdm_ppc_ops.to_clone_and_follow_inferior = NULL;
+ bdm_ppc_ops.to_post_follow_inferior_by_clone = NULL;
+ bdm_ppc_ops.to_insert_fork_catchpoint = NULL;
+ bdm_ppc_ops.to_remove_fork_catchpoint = NULL;
+ bdm_ppc_ops.to_insert_vfork_catchpoint = NULL;
+ bdm_ppc_ops.to_remove_vfork_catchpoint = NULL;
+ bdm_ppc_ops.to_has_forked = NULL;
+ bdm_ppc_ops.to_has_vforked = NULL;
+ bdm_ppc_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ bdm_ppc_ops.to_post_follow_vfork = NULL;
+ bdm_ppc_ops.to_insert_exec_catchpoint = NULL;
+ bdm_ppc_ops.to_remove_exec_catchpoint = NULL;
+ bdm_ppc_ops.to_has_execd = NULL;
+ bdm_ppc_ops.to_reported_exec_events_per_exec_call = NULL;
+ bdm_ppc_ops.to_has_exited = NULL;
+ bdm_ppc_ops.to_mourn_inferior = ocd_mourn;
+ bdm_ppc_ops.to_can_run = 0;
+ bdm_ppc_ops.to_notice_signals = 0;
+ bdm_ppc_ops.to_thread_alive = ocd_thread_alive;
+ bdm_ppc_ops.to_stop = ocd_stop;
+ bdm_ppc_ops.to_pid_to_exec_file = NULL;
+ bdm_ppc_ops.to_stratum = process_stratum;
+ bdm_ppc_ops.DONT_USE = NULL;
+ bdm_ppc_ops.to_has_all_memory = 1;
+ bdm_ppc_ops.to_has_memory = 1;
+ bdm_ppc_ops.to_has_stack = 1;
+ bdm_ppc_ops.to_has_registers = 1;
+ bdm_ppc_ops.to_has_execution = 1;
+ bdm_ppc_ops.to_sections = NULL;
+ bdm_ppc_ops.to_sections_end = NULL;
+ bdm_ppc_ops.to_magic = OPS_MAGIC;
+} /* init_bdm_ppc_ops */
+
+void
+_initialize_bdm_ppc (void)
+{
+ init_bdm_ppc_ops ();
+ add_target (&bdm_ppc_ops);
+}
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
new file mode 100644
index 00000000000..25616c0f047
--- /dev/null
+++ b/gdb/ppc-linux-nat.c
@@ -0,0 +1,553 @@
+/* PPC GNU/Linux native support.
+ Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001, 2002
+ 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <signal.h>
+#include <sys/user.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <sys/procfs.h>
+#include <sys/ptrace.h>
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+#include "ppc-tdep.h"
+
+#ifndef PT_READ_U
+#define PT_READ_U PTRACE_PEEKUSR
+#endif
+#ifndef PT_WRITE_U
+#define PT_WRITE_U PTRACE_POKEUSR
+#endif
+
+/* Default the type of the ptrace transfer to int. */
+#ifndef PTRACE_XFER_TYPE
+#define PTRACE_XFER_TYPE int
+#endif
+
+/* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a
+ configure time check. Some older glibc's (for instance 2.2.1)
+ don't have a specific powerpc version of ptrace.h, and fall back on
+ a generic one. In such cases, sys/ptrace.h defines
+ PTRACE_GETFPXREGS and PTRACE_SETFPXREGS to the same numbers that
+ ppc kernel's asm/ptrace.h defines PTRACE_GETVRREGS and
+ PTRACE_SETVRREGS to be. This also makes a configury check pretty
+ much useless. */
+
+/* These definitions should really come from the glibc header files,
+ but Glibc doesn't know about the vrregs yet. */
+#ifndef PTRACE_GETVRREGS
+#define PTRACE_GETVRREGS 18
+#define PTRACE_SETVRREGS 19
+#endif
+
+/* This oddity is because the Linux kernel defines elf_vrregset_t as
+ an array of 33 16 bytes long elements. I.e. it leaves out vrsave.
+ However the PTRACE_GETVRREGS and PTRACE_SETVRREGS requests return
+ the vrsave as an extra 4 bytes at the end. I opted for creating a
+ flat array of chars, so that it is easier to manipulate for gdb.
+
+ There are 32 vector registers 16 bytes longs, plus a VSCR register
+ which is only 4 bytes long, but is fetched as a 16 bytes
+ quantity. Up to here we have the elf_vrregset_t structure.
+ Appended to this there is space for the VRSAVE register: 4 bytes.
+ Even though this vrsave register is not included in the regset
+ typedef, it is handled by the ptrace requests.
+
+ Note that GNU/Linux doesn't support little endian PPC hardware,
+ therefore the offset at which the real value of the VSCR register
+ is located will be always 12 bytes.
+
+ The layout is like this (where x is the actual value of the vscr reg): */
+
+/* *INDENT-OFF* */
+/*
+ |.|.|.|.|.....|.|.|.|.||.|.|.|x||.|
+ <-------> <-------><-------><->
+ VR0 VR31 VSCR VRSAVE
+*/
+/* *INDENT-ON* */
+
+#define SIZEOF_VRREGS 33*16+4
+
+typedef char gdb_vrregset_t[SIZEOF_VRREGS];
+
+/* For runtime check of ptrace support for VRREGS. */
+int have_ptrace_getvrregs = 1;
+
+int
+kernel_u_size (void)
+{
+ return (sizeof (struct user));
+}
+
+/* *INDENT-OFF* */
+/* registers layout, as presented by the ptrace interface:
+PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7,
+PT_R8, PT_R9, PT_R10, PT_R11, PT_R12, PT_R13, PT_R14, PT_R15,
+PT_R16, PT_R17, PT_R18, PT_R19, PT_R20, PT_R21, PT_R22, PT_R23,
+PT_R24, PT_R25, PT_R26, PT_R27, PT_R28, PT_R29, PT_R30, PT_R31,
+PT_FPR0, PT_FPR0 + 2, PT_FPR0 + 4, PT_FPR0 + 6, PT_FPR0 + 8, PT_FPR0 + 10, PT_FPR0 + 12, PT_FPR0 + 14,
+PT_FPR0 + 16, PT_FPR0 + 18, PT_FPR0 + 20, PT_FPR0 + 22, PT_FPR0 + 24, PT_FPR0 + 26, PT_FPR0 + 28, PT_FPR0 + 30,
+PT_FPR0 + 32, PT_FPR0 + 34, PT_FPR0 + 36, PT_FPR0 + 38, PT_FPR0 + 40, PT_FPR0 + 42, PT_FPR0 + 44, PT_FPR0 + 46,
+PT_FPR0 + 48, PT_FPR0 + 50, PT_FPR0 + 52, PT_FPR0 + 54, PT_FPR0 + 56, PT_FPR0 + 58, PT_FPR0 + 60, PT_FPR0 + 62,
+PT_NIP, PT_MSR, PT_CCR, PT_LNK, PT_CTR, PT_XER, PT_MQ */
+/* *INDENT_ON * */
+
+static int
+ppc_register_u_addr (int regno)
+{
+ int u_addr = -1;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ /* General purpose registers occupy 1 slot each in the buffer */
+ if (regno >= tdep->ppc_gp0_regnum && regno <= tdep->ppc_gplast_regnum )
+ u_addr = ((PT_R0 + regno) * 4);
+
+ /* Floating point regs: 2 slots each */
+ if (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM)
+ u_addr = ((PT_FPR0 + (regno - FP0_REGNUM) * 2) * 4);
+
+ /* UISA special purpose registers: 1 slot each */
+ if (regno == PC_REGNUM)
+ u_addr = PT_NIP * 4;
+ if (regno == tdep->ppc_lr_regnum)
+ u_addr = PT_LNK * 4;
+ if (regno == tdep->ppc_cr_regnum)
+ u_addr = PT_CCR * 4;
+ if (regno == tdep->ppc_xer_regnum)
+ u_addr = PT_XER * 4;
+ if (regno == tdep->ppc_ctr_regnum)
+ u_addr = PT_CTR * 4;
+ if (regno == tdep->ppc_mq_regnum)
+ u_addr = PT_MQ * 4;
+ if (regno == tdep->ppc_ps_regnum)
+ u_addr = PT_MSR * 4;
+ if (regno == tdep->ppc_fpscr_regnum)
+ u_addr = PT_FPSCR * 4;
+
+ return u_addr;
+}
+
+static int
+ppc_ptrace_cannot_fetch_store_register (int regno)
+{
+ return (ppc_register_u_addr (regno) == -1);
+}
+
+/* The Linux kernel ptrace interface for AltiVec registers uses the
+ registers set mechanism, as opposed to the interface for all the
+ other registers, that stores/fetches each register individually. */
+static void
+fetch_altivec_register (int tid, int regno)
+{
+ int ret;
+ int offset = 0;
+ gdb_vrregset_t regs;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ int vrregsize = REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum);
+
+ ret = ptrace (PTRACE_GETVRREGS, tid, 0, &regs);
+ if (ret < 0)
+ {
+ if (errno == EIO)
+ {
+ have_ptrace_getvrregs = 0;
+ return;
+ }
+ perror_with_name ("Unable to fetch AltiVec register");
+ }
+
+ /* VSCR is fetched as a 16 bytes quantity, but it is really 4 bytes
+ long on the hardware. We deal only with the lower 4 bytes of the
+ vector. VRSAVE is at the end of the array in a 4 bytes slot, so
+ there is no need to define an offset for it. */
+ if (regno == (tdep->ppc_vrsave_regnum - 1))
+ offset = vrregsize - REGISTER_RAW_SIZE (tdep->ppc_vrsave_regnum);
+
+ supply_register (regno,
+ regs + (regno - tdep->ppc_vr0_regnum) * vrregsize + offset);
+}
+
+static void
+fetch_register (int tid, int regno)
+{
+ /* This isn't really an address. But ptrace thinks of it as one. */
+ char mess[128]; /* For messages */
+ register int i;
+ unsigned int offset; /* Offset of registers within the u area. */
+ char *buf = alloca (MAX_REGISTER_RAW_SIZE);
+ CORE_ADDR regaddr = ppc_register_u_addr (regno);
+
+ if (altivec_register_p (regno))
+ {
+ /* If this is the first time through, or if it is not the first
+ time through, and we have comfirmed that there is kernel
+ support for such a ptrace request, then go and fetch the
+ register. */
+ if (have_ptrace_getvrregs)
+ {
+ fetch_altivec_register (tid, regno);
+ return;
+ }
+ /* If we have discovered that there is no ptrace support for
+ AltiVec registers, fall through and return zeroes, because
+ regaddr will be -1 in this case. */
+ }
+
+ if (regaddr == -1)
+ {
+ memset (buf, '\0', REGISTER_RAW_SIZE (regno)); /* Supply zeroes */
+ supply_register (regno, buf);
+ return;
+ }
+
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ *(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid,
+ (PTRACE_ARG3_TYPE) regaddr, 0);
+ regaddr += sizeof (PTRACE_XFER_TYPE);
+ if (errno != 0)
+ {
+ sprintf (mess, "reading register %s (#%d)",
+ REGISTER_NAME (regno), regno);
+ perror_with_name (mess);
+ }
+ }
+ supply_register (regno, buf);
+}
+
+static void
+supply_vrregset (gdb_vrregset_t *vrregsetp)
+{
+ int i;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
+ int vrregsize = REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum);
+ int offset = vrregsize - REGISTER_RAW_SIZE (tdep->ppc_vrsave_regnum);
+
+ for (i = 0; i < num_of_vrregs; i++)
+ {
+ /* The last 2 registers of this set are only 32 bit long, not
+ 128. However an offset is necessary only for VSCR because it
+ occupies a whole vector, while VRSAVE occupies a full 4 bytes
+ slot. */
+ if (i == (num_of_vrregs - 2))
+ supply_register (tdep->ppc_vr0_regnum + i,
+ *vrregsetp + i * vrregsize + offset);
+ else
+ supply_register (tdep->ppc_vr0_regnum + i, *vrregsetp + i * vrregsize);
+ }
+}
+
+static void
+fetch_altivec_registers (int tid)
+{
+ int ret;
+ gdb_vrregset_t regs;
+
+ ret = ptrace (PTRACE_GETVRREGS, tid, 0, &regs);
+ if (ret < 0)
+ {
+ if (errno == EIO)
+ {
+ have_ptrace_getvrregs = 0;
+ return;
+ }
+ perror_with_name ("Unable to fetch AltiVec registers");
+ }
+ supply_vrregset (&regs);
+}
+
+static void
+fetch_ppc_registers (int tid)
+{
+ int i;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ for (i = 0; i <= tdep->ppc_fpscr_regnum; i++)
+ fetch_register (tid, i);
+ if (tdep->ppc_mq_regnum != -1)
+ fetch_register (tid, tdep->ppc_mq_regnum);
+ if (have_ptrace_getvrregs)
+ if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
+ fetch_altivec_registers (tid);
+}
+
+/* Fetch registers from the child process. Fetch all registers if
+ regno == -1, otherwise fetch all general registers or all floating
+ point registers depending upon the value of regno. */
+void
+fetch_inferior_registers (int regno)
+{
+ /* Overload thread id onto process id */
+ int tid = TIDGET (inferior_ptid);
+
+ /* No thread id, just use process id */
+ if (tid == 0)
+ tid = PIDGET (inferior_ptid);
+
+ if (regno == -1)
+ fetch_ppc_registers (tid);
+ else
+ fetch_register (tid, regno);
+}
+
+/* Store one register. */
+static void
+store_altivec_register (int tid, int regno)
+{
+ int ret;
+ int offset = 0;
+ gdb_vrregset_t regs;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ int vrregsize = REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum);
+
+ ret = ptrace (PTRACE_GETVRREGS, tid, 0, &regs);
+ if (ret < 0)
+ {
+ if (errno == EIO)
+ {
+ have_ptrace_getvrregs = 0;
+ return;
+ }
+ perror_with_name ("Unable to fetch AltiVec register");
+ }
+
+ /* VSCR is fetched as a 16 bytes quantity, but it is really 4 bytes
+ long on the hardware. */
+ if (regno == (tdep->ppc_vrsave_regnum - 1))
+ offset = vrregsize - REGISTER_RAW_SIZE (tdep->ppc_vrsave_regnum);
+
+ regcache_collect (regno,
+ regs + (regno - tdep->ppc_vr0_regnum) * vrregsize + offset);
+
+ ret = ptrace (PTRACE_SETVRREGS, tid, 0, &regs);
+ if (ret < 0)
+ perror_with_name ("Unable to store AltiVec register");
+}
+
+static void
+store_register (int tid, int regno)
+{
+ /* This isn't really an address. But ptrace thinks of it as one. */
+ CORE_ADDR regaddr = ppc_register_u_addr (regno);
+ char mess[128]; /* For messages */
+ register int i;
+ unsigned int offset; /* Offset of registers within the u area. */
+ char *buf = alloca (MAX_REGISTER_RAW_SIZE);
+
+ if (altivec_register_p (regno))
+ {
+ store_altivec_register (tid, regno);
+ return;
+ }
+
+ if (regaddr == -1)
+ return;
+
+ regcache_collect (regno, buf);
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,
+ *(PTRACE_XFER_TYPE *) & buf[i]);
+ regaddr += sizeof (PTRACE_XFER_TYPE);
+
+ if (errno == EIO
+ && regno == gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum)
+ {
+ /* Some older kernel versions don't allow fpscr to be written. */
+ continue;
+ }
+
+ if (errno != 0)
+ {
+ sprintf (mess, "writing register %s (#%d)",
+ REGISTER_NAME (regno), regno);
+ perror_with_name (mess);
+ }
+ }
+}
+
+static void
+fill_vrregset (gdb_vrregset_t *vrregsetp)
+{
+ int i;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
+ int vrregsize = REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum);
+ int offset = vrregsize - REGISTER_RAW_SIZE (tdep->ppc_vrsave_regnum);
+
+ for (i = 0; i < num_of_vrregs; i++)
+ {
+ /* The last 2 registers of this set are only 32 bit long, not
+ 128, but only VSCR is fetched as a 16 bytes quantity. */
+ if (i == (num_of_vrregs - 2))
+ regcache_collect (tdep->ppc_vr0_regnum + i,
+ *vrregsetp + i * vrregsize + offset);
+ else
+ regcache_collect (tdep->ppc_vr0_regnum + i, *vrregsetp + i * vrregsize);
+ }
+}
+
+static void
+store_altivec_registers (int tid)
+{
+ int ret;
+ gdb_vrregset_t regs;
+
+ ret = ptrace (PTRACE_GETVRREGS, tid, 0, (int) &regs);
+ if (ret < 0)
+ {
+ if (errno == EIO)
+ {
+ have_ptrace_getvrregs = 0;
+ return;
+ }
+ perror_with_name ("Couldn't get AltiVec registers");
+ }
+
+ fill_vrregset (&regs);
+
+ if (ptrace (PTRACE_SETVRREGS, tid, 0, (int) &regs) < 0)
+ perror_with_name ("Couldn't write AltiVec registers");
+}
+
+static void
+store_ppc_registers (int tid)
+{
+ int i;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ for (i = 0; i <= tdep->ppc_fpscr_regnum; i++)
+ store_register (tid, i);
+ if (tdep->ppc_mq_regnum != -1)
+ store_register (tid, tdep->ppc_mq_regnum);
+ if (have_ptrace_getvrregs)
+ if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
+ store_altivec_registers (tid);
+}
+
+void
+store_inferior_registers (int regno)
+{
+ /* Overload thread id onto process id */
+ int tid = TIDGET (inferior_ptid);
+
+ /* No thread id, just use process id */
+ if (tid == 0)
+ tid = PIDGET (inferior_ptid);
+
+ if (regno >= 0)
+ store_register (tid, regno);
+ else
+ store_ppc_registers (tid);
+}
+
+void
+supply_gregset (gdb_gregset_t *gregsetp)
+{
+ int regi;
+ register elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ for (regi = 0; regi < 32; regi++)
+ supply_register (regi, (char *) (regp + regi));
+
+ supply_register (PC_REGNUM, (char *) (regp + PT_NIP));
+ supply_register (tdep->ppc_lr_regnum, (char *) (regp + PT_LNK));
+ supply_register (tdep->ppc_cr_regnum, (char *) (regp + PT_CCR));
+ supply_register (tdep->ppc_xer_regnum, (char *) (regp + PT_XER));
+ supply_register (tdep->ppc_ctr_regnum, (char *) (regp + PT_CTR));
+ if (tdep->ppc_mq_regnum != -1)
+ supply_register (tdep->ppc_mq_regnum, (char *) (regp + PT_MQ));
+ supply_register (tdep->ppc_ps_regnum, (char *) (regp + PT_MSR));
+}
+
+void
+fill_gregset (gdb_gregset_t *gregsetp, int regno)
+{
+ int regi;
+ elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ for (regi = 0; regi < 32; regi++)
+ {
+ if ((regno == -1) || regno == regi)
+ regcache_collect (regi, regp + PT_R0 + regi);
+ }
+
+ if ((regno == -1) || regno == PC_REGNUM)
+ regcache_collect (PC_REGNUM, regp + PT_NIP);
+ if ((regno == -1) || regno == tdep->ppc_lr_regnum)
+ regcache_collect (tdep->ppc_lr_regnum, regp + PT_LNK);
+ if ((regno == -1) || regno == tdep->ppc_cr_regnum)
+ regcache_collect (tdep->ppc_cr_regnum, regp + PT_CCR);
+ if ((regno == -1) || regno == tdep->ppc_xer_regnum)
+ regcache_collect (tdep->ppc_xer_regnum, regp + PT_XER);
+ if ((regno == -1) || regno == tdep->ppc_ctr_regnum)
+ regcache_collect (tdep->ppc_ctr_regnum, regp + PT_CTR);
+ if (((regno == -1) || regno == tdep->ppc_mq_regnum)
+ && (tdep->ppc_mq_regnum != -1))
+ regcache_collect (tdep->ppc_mq_regnum, regp + PT_MQ);
+ if ((regno == -1) || regno == tdep->ppc_ps_regnum)
+ regcache_collect (tdep->ppc_ps_regnum, regp + PT_MSR);
+}
+
+void
+supply_fpregset (gdb_fpregset_t * fpregsetp)
+{
+ int regi;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ for (regi = 0; regi < 32; regi++)
+ supply_register (FP0_REGNUM + regi, (char *) (*fpregsetp + regi));
+ supply_register (tdep->ppc_fpscr_regnum, (char *) (*fpregsetp + 32));
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), update the register specified by REGNO from gdb's
+ idea of the current floating point register set. If REGNO is -1,
+ update them all. */
+void
+fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
+{
+ int regi;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ for (regi = 0; regi < 32; regi++)
+ {
+ if ((regno == -1) || (regno == FP0_REGNUM + regi))
+ regcache_collect (FP0_REGNUM + regi, (char *) (*fpregsetp + regi));
+ }
+ if ((regno == -1) || regno == tdep->ppc_fpscr_regnum)
+ regcache_collect (tdep->ppc_fpscr_regnum, (char *) (*fpregsetp + regi));
+}
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
new file mode 100644
index 00000000000..f358274140b
--- /dev/null
+++ b/gdb/ppc-linux-tdep.c
@@ -0,0 +1,888 @@
+/* Target-dependent code for GDB, the GNU debugger.
+
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 2000, 2001, 2002 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "symtab.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "regcache.h"
+#include "value.h"
+
+#include "solib-svr4.h"
+#include "ppc-tdep.h"
+
+/* The following two instructions are used in the signal trampoline
+ code on GNU/Linux PPC. */
+#define INSTR_LI_R0_0x7777 0x38007777
+#define INSTR_SC 0x44000002
+
+/* Since the *-tdep.c files are platform independent (i.e, they may be
+ used to build cross platform debuggers), we can't include system
+ headers. Therefore, details concerning the sigcontext structure
+ must be painstakingly rerecorded. What's worse, if these details
+ ever change in the header files, they'll have to be changed here
+ as well. */
+
+/* __SIGNAL_FRAMESIZE from <asm/ptrace.h> */
+#define PPC_LINUX_SIGNAL_FRAMESIZE 64
+
+/* From <asm/sigcontext.h>, offsetof(struct sigcontext_struct, regs) == 0x1c */
+#define PPC_LINUX_REGS_PTR_OFFSET (PPC_LINUX_SIGNAL_FRAMESIZE + 0x1c)
+
+/* From <asm/sigcontext.h>,
+ offsetof(struct sigcontext_struct, handler) == 0x14 */
+#define PPC_LINUX_HANDLER_PTR_OFFSET (PPC_LINUX_SIGNAL_FRAMESIZE + 0x14)
+
+/* From <asm/ptrace.h>, values for PT_NIP, PT_R1, and PT_LNK */
+#define PPC_LINUX_PT_R0 0
+#define PPC_LINUX_PT_R1 1
+#define PPC_LINUX_PT_R2 2
+#define PPC_LINUX_PT_R3 3
+#define PPC_LINUX_PT_R4 4
+#define PPC_LINUX_PT_R5 5
+#define PPC_LINUX_PT_R6 6
+#define PPC_LINUX_PT_R7 7
+#define PPC_LINUX_PT_R8 8
+#define PPC_LINUX_PT_R9 9
+#define PPC_LINUX_PT_R10 10
+#define PPC_LINUX_PT_R11 11
+#define PPC_LINUX_PT_R12 12
+#define PPC_LINUX_PT_R13 13
+#define PPC_LINUX_PT_R14 14
+#define PPC_LINUX_PT_R15 15
+#define PPC_LINUX_PT_R16 16
+#define PPC_LINUX_PT_R17 17
+#define PPC_LINUX_PT_R18 18
+#define PPC_LINUX_PT_R19 19
+#define PPC_LINUX_PT_R20 20
+#define PPC_LINUX_PT_R21 21
+#define PPC_LINUX_PT_R22 22
+#define PPC_LINUX_PT_R23 23
+#define PPC_LINUX_PT_R24 24
+#define PPC_LINUX_PT_R25 25
+#define PPC_LINUX_PT_R26 26
+#define PPC_LINUX_PT_R27 27
+#define PPC_LINUX_PT_R28 28
+#define PPC_LINUX_PT_R29 29
+#define PPC_LINUX_PT_R30 30
+#define PPC_LINUX_PT_R31 31
+#define PPC_LINUX_PT_NIP 32
+#define PPC_LINUX_PT_MSR 33
+#define PPC_LINUX_PT_CTR 35
+#define PPC_LINUX_PT_LNK 36
+#define PPC_LINUX_PT_XER 37
+#define PPC_LINUX_PT_CCR 38
+#define PPC_LINUX_PT_MQ 39
+#define PPC_LINUX_PT_FPR0 48 /* each FP reg occupies 2 slots in this space */
+#define PPC_LINUX_PT_FPR31 (PPC_LINUX_PT_FPR0 + 2*31)
+#define PPC_LINUX_PT_FPSCR (PPC_LINUX_PT_FPR0 + 2*32 + 1)
+
+static int ppc_linux_at_sigtramp_return_path (CORE_ADDR pc);
+
+/* Determine if pc is in a signal trampoline...
+
+ Ha! That's not what this does at all. wait_for_inferior in
+ infrun.c calls PC_IN_SIGTRAMP in order to detect entry into a
+ signal trampoline just after delivery of a signal. But on
+ GNU/Linux, signal trampolines are used for the return path only.
+ The kernel sets things up so that the signal handler is called
+ directly.
+
+ If we use in_sigtramp2() in place of in_sigtramp() (see below)
+ we'll (often) end up with stop_pc in the trampoline and prev_pc in
+ the (now exited) handler. The code there will cause a temporary
+ breakpoint to be set on prev_pc which is not very likely to get hit
+ again.
+
+ If this is confusing, think of it this way... the code in
+ wait_for_inferior() needs to be able to detect entry into a signal
+ trampoline just after a signal is delivered, not after the handler
+ has been run.
+
+ So, we define in_sigtramp() below to return 1 if the following is
+ true:
+
+ 1) The previous frame is a real signal trampoline.
+
+ - and -
+
+ 2) pc is at the first or second instruction of the corresponding
+ handler.
+
+ Why the second instruction? It seems that wait_for_inferior()
+ never sees the first instruction when single stepping. When a
+ signal is delivered while stepping, the next instruction that
+ would've been stepped over isn't, instead a signal is delivered and
+ the first instruction of the handler is stepped over instead. That
+ puts us on the second instruction. (I added the test for the
+ first instruction long after the fact, just in case the observed
+ behavior is ever fixed.)
+
+ PC_IN_SIGTRAMP is called from blockframe.c as well in order to set
+ the signal_handler_caller flag. Because of our strange definition
+ of in_sigtramp below, we can't rely on signal_handler_caller
+ getting set correctly from within blockframe.c. This is why we
+ take pains to set it in init_extra_frame_info(). */
+
+int
+ppc_linux_in_sigtramp (CORE_ADDR pc, char *func_name)
+{
+ CORE_ADDR lr;
+ CORE_ADDR sp;
+ CORE_ADDR tramp_sp;
+ char buf[4];
+ CORE_ADDR handler;
+
+ lr = read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum);
+ if (!ppc_linux_at_sigtramp_return_path (lr))
+ return 0;
+
+ sp = read_register (SP_REGNUM);
+
+ if (target_read_memory (sp, buf, sizeof (buf)) != 0)
+ return 0;
+
+ tramp_sp = extract_unsigned_integer (buf, 4);
+
+ if (target_read_memory (tramp_sp + PPC_LINUX_HANDLER_PTR_OFFSET, buf,
+ sizeof (buf)) != 0)
+ return 0;
+
+ handler = extract_unsigned_integer (buf, 4);
+
+ return (pc == handler || pc == handler + 4);
+}
+
+/*
+ * The signal handler trampoline is on the stack and consists of exactly
+ * two instructions. The easiest and most accurate way of determining
+ * whether the pc is in one of these trampolines is by inspecting the
+ * instructions. It'd be faster though if we could find a way to do this
+ * via some simple address comparisons.
+ */
+static int
+ppc_linux_at_sigtramp_return_path (CORE_ADDR pc)
+{
+ char buf[12];
+ unsigned long pcinsn;
+ if (target_read_memory (pc - 4, buf, sizeof (buf)) != 0)
+ return 0;
+
+ /* extract the instruction at the pc */
+ pcinsn = extract_unsigned_integer (buf + 4, 4);
+
+ return (
+ (pcinsn == INSTR_LI_R0_0x7777
+ && extract_unsigned_integer (buf + 8, 4) == INSTR_SC)
+ ||
+ (pcinsn == INSTR_SC
+ && extract_unsigned_integer (buf, 4) == INSTR_LI_R0_0x7777));
+}
+
+CORE_ADDR
+ppc_linux_skip_trampoline_code (CORE_ADDR pc)
+{
+ char buf[4];
+ struct obj_section *sect;
+ struct objfile *objfile;
+ unsigned long insn;
+ CORE_ADDR plt_start = 0;
+ CORE_ADDR symtab = 0;
+ CORE_ADDR strtab = 0;
+ int num_slots = -1;
+ int reloc_index = -1;
+ CORE_ADDR plt_table;
+ CORE_ADDR reloc;
+ CORE_ADDR sym;
+ long symidx;
+ char symname[1024];
+ struct minimal_symbol *msymbol;
+
+ /* Find the section pc is in; return if not in .plt */
+ sect = find_pc_section (pc);
+ if (!sect || strcmp (sect->the_bfd_section->name, ".plt") != 0)
+ return 0;
+
+ objfile = sect->objfile;
+
+ /* Pick up the instruction at pc. It had better be of the
+ form
+ li r11, IDX
+
+ where IDX is an index into the plt_table. */
+
+ if (target_read_memory (pc, buf, 4) != 0)
+ return 0;
+ insn = extract_unsigned_integer (buf, 4);
+
+ if ((insn & 0xffff0000) != 0x39600000 /* li r11, VAL */ )
+ return 0;
+
+ reloc_index = (insn << 16) >> 16;
+
+ /* Find the objfile that pc is in and obtain the information
+ necessary for finding the symbol name. */
+ for (sect = objfile->sections; sect < objfile->sections_end; ++sect)
+ {
+ const char *secname = sect->the_bfd_section->name;
+ if (strcmp (secname, ".plt") == 0)
+ plt_start = sect->addr;
+ else if (strcmp (secname, ".rela.plt") == 0)
+ num_slots = ((int) sect->endaddr - (int) sect->addr) / 12;
+ else if (strcmp (secname, ".dynsym") == 0)
+ symtab = sect->addr;
+ else if (strcmp (secname, ".dynstr") == 0)
+ strtab = sect->addr;
+ }
+
+ /* Make sure we have all the information we need. */
+ if (plt_start == 0 || num_slots == -1 || symtab == 0 || strtab == 0)
+ return 0;
+
+ /* Compute the value of the plt table */
+ plt_table = plt_start + 72 + 8 * num_slots;
+
+ /* Get address of the relocation entry (Elf32_Rela) */
+ if (target_read_memory (plt_table + reloc_index, buf, 4) != 0)
+ return 0;
+ reloc = extract_address (buf, 4);
+
+ sect = find_pc_section (reloc);
+ if (!sect)
+ return 0;
+
+ if (strcmp (sect->the_bfd_section->name, ".text") == 0)
+ return reloc;
+
+ /* Now get the r_info field which is the relocation type and symbol
+ index. */
+ if (target_read_memory (reloc + 4, buf, 4) != 0)
+ return 0;
+ symidx = extract_unsigned_integer (buf, 4);
+
+ /* Shift out the relocation type leaving just the symbol index */
+ /* symidx = ELF32_R_SYM(symidx); */
+ symidx = symidx >> 8;
+
+ /* compute the address of the symbol */
+ sym = symtab + symidx * 4;
+
+ /* Fetch the string table index */
+ if (target_read_memory (sym, buf, 4) != 0)
+ return 0;
+ symidx = extract_unsigned_integer (buf, 4);
+
+ /* Fetch the string; we don't know how long it is. Is it possible
+ that the following will fail because we're trying to fetch too
+ much? */
+ if (target_read_memory (strtab + symidx, symname, sizeof (symname)) != 0)
+ return 0;
+
+ /* This might not work right if we have multiple symbols with the
+ same name; the only way to really get it right is to perform
+ the same sort of lookup as the dynamic linker. */
+ msymbol = lookup_minimal_symbol_text (symname, NULL, NULL);
+ if (!msymbol)
+ return 0;
+
+ return SYMBOL_VALUE_ADDRESS (msymbol);
+}
+
+/* The rs6000 version of FRAME_SAVED_PC will almost work for us. The
+ signal handler details are different, so we'll handle those here
+ and call the rs6000 version to do the rest. */
+CORE_ADDR
+ppc_linux_frame_saved_pc (struct frame_info *fi)
+{
+ if (fi->signal_handler_caller)
+ {
+ CORE_ADDR regs_addr =
+ read_memory_integer (fi->frame + PPC_LINUX_REGS_PTR_OFFSET, 4);
+ /* return the NIP in the regs array */
+ return read_memory_integer (regs_addr + 4 * PPC_LINUX_PT_NIP, 4);
+ }
+ else if (fi->next && fi->next->signal_handler_caller)
+ {
+ CORE_ADDR regs_addr =
+ read_memory_integer (fi->next->frame + PPC_LINUX_REGS_PTR_OFFSET, 4);
+ /* return LNK in the regs array */
+ return read_memory_integer (regs_addr + 4 * PPC_LINUX_PT_LNK, 4);
+ }
+ else
+ return rs6000_frame_saved_pc (fi);
+}
+
+void
+ppc_linux_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ rs6000_init_extra_frame_info (fromleaf, fi);
+
+ if (fi->next != 0)
+ {
+ /* We're called from get_prev_frame_info; check to see if
+ this is a signal frame by looking to see if the pc points
+ at trampoline code */
+ if (ppc_linux_at_sigtramp_return_path (fi->pc))
+ fi->signal_handler_caller = 1;
+ else
+ fi->signal_handler_caller = 0;
+ }
+}
+
+int
+ppc_linux_frameless_function_invocation (struct frame_info *fi)
+{
+ /* We'll find the wrong thing if we let
+ rs6000_frameless_function_invocation () search for a signal trampoline */
+ if (ppc_linux_at_sigtramp_return_path (fi->pc))
+ return 0;
+ else
+ return rs6000_frameless_function_invocation (fi);
+}
+
+void
+ppc_linux_frame_init_saved_regs (struct frame_info *fi)
+{
+ if (fi->signal_handler_caller)
+ {
+ CORE_ADDR regs_addr;
+ int i;
+ if (fi->saved_regs)
+ return;
+
+ frame_saved_regs_zalloc (fi);
+
+ regs_addr =
+ read_memory_integer (fi->frame + PPC_LINUX_REGS_PTR_OFFSET, 4);
+ fi->saved_regs[PC_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_NIP;
+ fi->saved_regs[gdbarch_tdep (current_gdbarch)->ppc_ps_regnum] =
+ regs_addr + 4 * PPC_LINUX_PT_MSR;
+ fi->saved_regs[gdbarch_tdep (current_gdbarch)->ppc_cr_regnum] =
+ regs_addr + 4 * PPC_LINUX_PT_CCR;
+ fi->saved_regs[gdbarch_tdep (current_gdbarch)->ppc_lr_regnum] =
+ regs_addr + 4 * PPC_LINUX_PT_LNK;
+ fi->saved_regs[gdbarch_tdep (current_gdbarch)->ppc_ctr_regnum] =
+ regs_addr + 4 * PPC_LINUX_PT_CTR;
+ fi->saved_regs[gdbarch_tdep (current_gdbarch)->ppc_xer_regnum] =
+ regs_addr + 4 * PPC_LINUX_PT_XER;
+ fi->saved_regs[gdbarch_tdep (current_gdbarch)->ppc_mq_regnum] =
+ regs_addr + 4 * PPC_LINUX_PT_MQ;
+ for (i = 0; i < 32; i++)
+ fi->saved_regs[gdbarch_tdep (current_gdbarch)->ppc_gp0_regnum + i] =
+ regs_addr + 4 * PPC_LINUX_PT_R0 + 4 * i;
+ for (i = 0; i < 32; i++)
+ fi->saved_regs[FP0_REGNUM + i] = regs_addr + 4 * PPC_LINUX_PT_FPR0 + 8 * i;
+ }
+ else
+ rs6000_frame_init_saved_regs (fi);
+}
+
+CORE_ADDR
+ppc_linux_frame_chain (struct frame_info *thisframe)
+{
+ /* Kernel properly constructs the frame chain for the handler */
+ if (thisframe->signal_handler_caller)
+ return read_memory_integer ((thisframe)->frame, 4);
+ else
+ return rs6000_frame_chain (thisframe);
+}
+
+/* FIXME: Move the following to rs6000-tdep.c (or some other file where
+ it may be used generically by ports which use either the SysV ABI or
+ the EABI */
+
+/* Until November 2001, gcc was not complying to the SYSV ABI for
+ returning structures less than or equal to 8 bytes in size. It was
+ returning everything in memory. When this was corrected, it wasn't
+ fixed for native platforms. */
+int
+ppc_sysv_abi_broken_use_struct_convention (int gcc_p, struct type *value_type)
+{
+ if (TYPE_LENGTH (value_type) == 16
+ && TYPE_VECTOR (value_type))
+ return 0;
+
+ return generic_use_struct_convention (gcc_p, value_type);
+}
+
+/* Structures 8 bytes or less long are returned in the r3 & r4
+ registers, according to the SYSV ABI. */
+int
+ppc_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type)
+{
+ if (TYPE_LENGTH (value_type) == 16
+ && TYPE_VECTOR (value_type))
+ return 0;
+
+ return (TYPE_LENGTH (value_type) > 8);
+}
+
+/* round2 rounds x up to the nearest multiple of s assuming that s is a
+ power of 2 */
+
+#undef round2
+#define round2(x,s) ((((long) (x) - 1) & ~(long)((s)-1)) + (s))
+
+/* Pass the arguments in either registers, or in the stack. Using the
+ ppc sysv ABI, the first eight words of the argument list (that might
+ be less than eight parameters if some parameters occupy more than one
+ word) are passed in r3..r10 registers. float and double parameters are
+ passed in fpr's, in addition to that. Rest of the parameters if any
+ are passed in user stack.
+
+ If the function is returning a structure, then the return address is passed
+ in r3, then the first 7 words of the parametes can be passed in registers,
+ starting from r4. */
+
+CORE_ADDR
+ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int argno;
+ /* Next available general register for non-float, non-vector arguments. */
+ int greg;
+ /* Next available floating point register for float arguments. */
+ int freg;
+ /* Next available vector register for vector arguments. */
+ int vreg;
+ int argstkspace;
+ int structstkspace;
+ int argoffset;
+ int structoffset;
+ struct value *arg;
+ struct type *type;
+ int len;
+ char old_sp_buf[4];
+ CORE_ADDR saved_sp;
+
+ greg = struct_return ? 4 : 3;
+ freg = 1;
+ vreg = 2;
+ argstkspace = 0;
+ structstkspace = 0;
+
+ /* Figure out how much new stack space is required for arguments
+ which don't fit in registers. Unlike the PowerOpen ABI, the
+ SysV ABI doesn't reserve any extra space for parameters which
+ are put in registers. */
+ for (argno = 0; argno < nargs; argno++)
+ {
+ arg = args[argno];
+ type = check_typedef (VALUE_TYPE (arg));
+ len = TYPE_LENGTH (type);
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
+ if (freg <= 8)
+ freg++;
+ else
+ {
+ /* SysV ABI converts floats to doubles when placed in
+ memory and requires 8 byte alignment */
+ if (argstkspace & 0x4)
+ argstkspace += 4;
+ argstkspace += 8;
+ }
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8) /* long long */
+ {
+ if (greg > 9)
+ {
+ greg = 11;
+ if (argstkspace & 0x4)
+ argstkspace += 4;
+ argstkspace += 8;
+ }
+ else
+ {
+ if ((greg & 1) == 0)
+ greg++;
+ greg += 2;
+ }
+ }
+ else if (!TYPE_VECTOR (type))
+ {
+ if (len > 4
+ || TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION)
+ {
+ /* Rounding to the nearest multiple of 8 may not be necessary,
+ but it is safe. Particularly since we don't know the
+ field types of the structure */
+ structstkspace += round2 (len, 8);
+ }
+ if (greg <= 10)
+ greg++;
+ else
+ argstkspace += 4;
+ }
+ else
+ {
+ if (len == 16
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_VECTOR (type))
+ {
+ if (vreg <= 13)
+ vreg++;
+ else
+ {
+ /* Vector arguments must be aligned to 16 bytes on
+ the stack. */
+ argstkspace += round2 (argstkspace, 16);
+ argstkspace += 16;
+ }
+ }
+ }
+ }
+
+ /* Get current SP location */
+ saved_sp = read_sp ();
+
+ sp -= argstkspace + structstkspace;
+
+ /* Allocate space for backchain and callee's saved lr */
+ sp -= 8;
+
+ /* Make sure that we maintain 16 byte alignment */
+ sp &= ~0x0f;
+
+ /* Update %sp before proceeding any further */
+ write_register (SP_REGNUM, sp);
+
+ /* write the backchain */
+ store_address (old_sp_buf, 4, saved_sp);
+ write_memory (sp, old_sp_buf, 4);
+
+ argoffset = 8;
+ structoffset = argoffset + argstkspace;
+ freg = 1;
+ greg = 3;
+ vreg = 2;
+ /* Fill in r3 with the return structure, if any */
+ if (struct_return)
+ {
+ char val_buf[4];
+ store_address (val_buf, 4, struct_addr);
+ memcpy (&registers[REGISTER_BYTE (greg)], val_buf, 4);
+ greg++;
+ }
+ /* Now fill in the registers and stack... */
+ for (argno = 0; argno < nargs; argno++)
+ {
+ arg = args[argno];
+ type = check_typedef (VALUE_TYPE (arg));
+ len = TYPE_LENGTH (type);
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
+ if (freg <= 8)
+ {
+ if (len > 8)
+ printf_unfiltered (
+ "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM + freg)],
+ VALUE_CONTENTS (arg), len);
+ freg++;
+ }
+ else
+ {
+ /* SysV ABI converts floats to doubles when placed in
+ memory and requires 8 byte alignment */
+ /* FIXME: Convert floats to doubles */
+ if (argoffset & 0x4)
+ argoffset += 4;
+ write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
+ argoffset += 8;
+ }
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8) /* long long */
+ {
+ if (greg > 9)
+ {
+ greg = 11;
+ if (argoffset & 0x4)
+ argoffset += 4;
+ write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
+ argoffset += 8;
+ }
+ else
+ {
+ if ((greg & 1) == 0)
+ greg++;
+
+ memcpy (&registers[REGISTER_BYTE (greg)],
+ VALUE_CONTENTS (arg), 4);
+ memcpy (&registers[REGISTER_BYTE (greg + 1)],
+ VALUE_CONTENTS (arg) + 4, 4);
+ greg += 2;
+ }
+ }
+ else if (!TYPE_VECTOR (type))
+ {
+ char val_buf[4];
+ if (len > 4
+ || TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION)
+ {
+ write_memory (sp + structoffset, VALUE_CONTENTS (arg), len);
+ store_address (val_buf, 4, sp + structoffset);
+ structoffset += round2 (len, 8);
+ }
+ else
+ {
+ memset (val_buf, 0, 4);
+ memcpy (val_buf, VALUE_CONTENTS (arg), len);
+ }
+ if (greg <= 10)
+ {
+ memcpy (&registers[REGISTER_BYTE (greg)], val_buf, 4);
+ greg++;
+ }
+ else
+ {
+ write_memory (sp + argoffset, val_buf, 4);
+ argoffset += 4;
+ }
+ }
+ else
+ {
+ if (len == 16
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_VECTOR (type))
+ {
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ char *v_val_buf = alloca (16);
+ memset (v_val_buf, 0, 16);
+ memcpy (v_val_buf, VALUE_CONTENTS (arg), len);
+ if (vreg <= 13)
+ {
+ memcpy (&registers[REGISTER_BYTE (tdep->ppc_vr0_regnum
+ + vreg)],
+ v_val_buf, 16);
+ vreg++;
+ }
+ else
+ {
+ write_memory (sp + argoffset, v_val_buf, 16);
+ argoffset += 16;
+ }
+ }
+ }
+ }
+
+ target_store_registers (-1);
+ return sp;
+}
+
+/* ppc_linux_memory_remove_breakpoints attempts to remove a breakpoint
+ in much the same fashion as memory_remove_breakpoint in mem-break.c,
+ but is careful not to write back the previous contents if the code
+ in question has changed in between inserting the breakpoint and
+ removing it.
+
+ Here is the problem that we're trying to solve...
+
+ Once upon a time, before introducing this function to remove
+ breakpoints from the inferior, setting a breakpoint on a shared
+ library function prior to running the program would not work
+ properly. In order to understand the problem, it is first
+ necessary to understand a little bit about dynamic linking on
+ this platform.
+
+ A call to a shared library function is accomplished via a bl
+ (branch-and-link) instruction whose branch target is an entry
+ in the procedure linkage table (PLT). The PLT in the object
+ file is uninitialized. To gdb, prior to running the program, the
+ entries in the PLT are all zeros.
+
+ Once the program starts running, the shared libraries are loaded
+ and the procedure linkage table is initialized, but the entries in
+ the table are not (necessarily) resolved. Once a function is
+ actually called, the code in the PLT is hit and the function is
+ resolved. In order to better illustrate this, an example is in
+ order; the following example is from the gdb testsuite.
+
+ We start the program shmain.
+
+ [kev@arroyo testsuite]$ ../gdb gdb.base/shmain
+ [...]
+
+ We place two breakpoints, one on shr1 and the other on main.
+
+ (gdb) b shr1
+ Breakpoint 1 at 0x100409d4
+ (gdb) b main
+ Breakpoint 2 at 0x100006a0: file gdb.base/shmain.c, line 44.
+
+ Examine the instruction (and the immediatly following instruction)
+ upon which the breakpoint was placed. Note that the PLT entry
+ for shr1 contains zeros.
+
+ (gdb) x/2i 0x100409d4
+ 0x100409d4 <shr1>: .long 0x0
+ 0x100409d8 <shr1+4>: .long 0x0
+
+ Now run 'til main.
+
+ (gdb) r
+ Starting program: gdb.base/shmain
+ Breakpoint 1 at 0xffaf790: file gdb.base/shr1.c, line 19.
+
+ Breakpoint 2, main ()
+ at gdb.base/shmain.c:44
+ 44 g = 1;
+
+ Examine the PLT again. Note that the loading of the shared
+ library has initialized the PLT to code which loads a constant
+ (which I think is an index into the GOT) into r11 and then
+ branchs a short distance to the code which actually does the
+ resolving.
+
+ (gdb) x/2i 0x100409d4
+ 0x100409d4 <shr1>: li r11,4
+ 0x100409d8 <shr1+4>: b 0x10040984 <sg+4>
+ (gdb) c
+ Continuing.
+
+ Breakpoint 1, shr1 (x=1)
+ at gdb.base/shr1.c:19
+ 19 l = 1;
+
+ Now we've hit the breakpoint at shr1. (The breakpoint was
+ reset from the PLT entry to the actual shr1 function after the
+ shared library was loaded.) Note that the PLT entry has been
+ resolved to contain a branch that takes us directly to shr1.
+ (The real one, not the PLT entry.)
+
+ (gdb) x/2i 0x100409d4
+ 0x100409d4 <shr1>: b 0xffaf76c <shr1>
+ 0x100409d8 <shr1+4>: b 0x10040984 <sg+4>
+
+ The thing to note here is that the PLT entry for shr1 has been
+ changed twice.
+
+ Now the problem should be obvious. GDB places a breakpoint (a
+ trap instruction) on the zero value of the PLT entry for shr1.
+ Later on, after the shared library had been loaded and the PLT
+ initialized, GDB gets a signal indicating this fact and attempts
+ (as it always does when it stops) to remove all the breakpoints.
+
+ The breakpoint removal was causing the former contents (a zero
+ word) to be written back to the now initialized PLT entry thus
+ destroying a portion of the initialization that had occurred only a
+ short time ago. When execution continued, the zero word would be
+ executed as an instruction an an illegal instruction trap was
+ generated instead. (0 is not a legal instruction.)
+
+ The fix for this problem was fairly straightforward. The function
+ memory_remove_breakpoint from mem-break.c was copied to this file,
+ modified slightly, and renamed to ppc_linux_memory_remove_breakpoint.
+ In tm-linux.h, MEMORY_REMOVE_BREAKPOINT is defined to call this new
+ function.
+
+ The differences between ppc_linux_memory_remove_breakpoint () and
+ memory_remove_breakpoint () are minor. All that the former does
+ that the latter does not is check to make sure that the breakpoint
+ location actually contains a breakpoint (trap instruction) prior
+ to attempting to write back the old contents. If it does contain
+ a trap instruction, we allow the old contents to be written back.
+ Otherwise, we silently do nothing.
+
+ The big question is whether memory_remove_breakpoint () should be
+ changed to have the same functionality. The downside is that more
+ traffic is generated for remote targets since we'll have an extra
+ fetch of a memory word each time a breakpoint is removed.
+
+ For the time being, we'll leave this self-modifying-code-friendly
+ version in ppc-linux-tdep.c, but it ought to be migrated somewhere
+ else in the event that some other platform has similar needs with
+ regard to removing breakpoints in some potentially self modifying
+ code. */
+int
+ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ const unsigned char *bp;
+ int val;
+ int bplen;
+ char old_contents[BREAKPOINT_MAX];
+
+ /* Determine appropriate breakpoint contents and size for this address. */
+ bp = BREAKPOINT_FROM_PC (&addr, &bplen);
+ if (bp == NULL)
+ error ("Software breakpoints not implemented for this target.");
+
+ val = target_read_memory (addr, old_contents, bplen);
+
+ /* If our breakpoint is no longer at the address, this means that the
+ program modified the code on us, so it is wrong to put back the
+ old value */
+ if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
+ val = target_write_memory (addr, contents_cache, bplen);
+
+ return val;
+}
+
+/* Fetch (and possibly build) an appropriate link_map_offsets
+ structure for GNU/Linux PPC targets using the struct offsets
+ defined in link.h (but without actual reference to that file).
+
+ This makes it possible to access GNU/Linux PPC shared libraries
+ from a GDB that was not built on an GNU/Linux PPC host (for cross
+ debugging). */
+
+struct link_map_offsets *
+ppc_linux_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_debug_size = 8; /* The actual size is 20 bytes, but
+ this is all we need. */
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 4;
+
+ lmo.link_map_size = 20; /* The actual size is 560 bytes, but
+ this is all we need. */
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 4;
+
+ lmo.l_name_offset = 4;
+ lmo.l_name_size = 4;
+
+ lmo.l_next_offset = 12;
+ lmo.l_next_size = 4;
+
+ lmo.l_prev_offset = 16;
+ lmo.l_prev_size = 4;
+ }
+
+ return lmp;
+}
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
new file mode 100644
index 00000000000..0d33683a4c4
--- /dev/null
+++ b/gdb/ppc-sysv-tdep.c
@@ -0,0 +1,312 @@
+/* Target-dependent code for PowerPC systems using the SVR4 ABI
+ for GDB, the GNU debugger.
+
+ Copyright 2000, 2001, 2002 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 "defs.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "value.h"
+
+#include "ppc-tdep.h"
+
+/* round2 rounds x up to the nearest multiple of s assuming that s is a
+ power of 2 */
+
+#undef round2
+#define round2(x,s) ((((long) (x) - 1) & ~(long)((s)-1)) + (s))
+
+/* Pass the arguments in either registers, or in the stack. Using the
+ ppc sysv ABI, the first eight words of the argument list (that might
+ be less than eight parameters if some parameters occupy more than one
+ word) are passed in r3..r10 registers. float and double parameters are
+ passed in fpr's, in addition to that. Rest of the parameters if any
+ are passed in user stack.
+
+ If the function is returning a structure, then the return address is passed
+ in r3, then the first 7 words of the parametes can be passed in registers,
+ starting from r4. */
+
+CORE_ADDR
+ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int argno;
+ /* Next available general register for non-float, non-vector arguments. */
+ int greg;
+ /* Next available floating point register for float arguments. */
+ int freg;
+ /* Next available vector register for vector arguments. */
+ int vreg;
+ int argstkspace;
+ int structstkspace;
+ int argoffset;
+ int structoffset;
+ struct value *arg;
+ struct type *type;
+ int len;
+ char old_sp_buf[4];
+ CORE_ADDR saved_sp;
+
+ greg = struct_return ? 4 : 3;
+ freg = 1;
+ vreg = 2;
+ argstkspace = 0;
+ structstkspace = 0;
+
+ /* Figure out how much new stack space is required for arguments
+ which don't fit in registers. Unlike the PowerOpen ABI, the
+ SysV ABI doesn't reserve any extra space for parameters which
+ are put in registers. */
+ for (argno = 0; argno < nargs; argno++)
+ {
+ arg = args[argno];
+ type = check_typedef (VALUE_TYPE (arg));
+ len = TYPE_LENGTH (type);
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
+ if (freg <= 8)
+ freg++;
+ else
+ {
+ /* SysV ABI converts floats to doubles when placed in
+ memory and requires 8 byte alignment */
+ if (argstkspace & 0x4)
+ argstkspace += 4;
+ argstkspace += 8;
+ }
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8) /* long long */
+ {
+ if (greg > 9)
+ {
+ greg = 11;
+ if (argstkspace & 0x4)
+ argstkspace += 4;
+ argstkspace += 8;
+ }
+ else
+ {
+ if ((greg & 1) == 0)
+ greg++;
+ greg += 2;
+ }
+ }
+ else if (!TYPE_VECTOR (type))
+ {
+ if (len > 4
+ || TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION)
+ {
+ /* Rounding to the nearest multiple of 8 may not be necessary,
+ but it is safe. Particularly since we don't know the
+ field types of the structure */
+ structstkspace += round2 (len, 8);
+ }
+ if (greg <= 10)
+ greg++;
+ else
+ argstkspace += 4;
+ }
+ else
+ {
+ if (len == 16
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_VECTOR (type))
+ {
+ if (vreg <= 13)
+ vreg++;
+ else
+ {
+ /* Vector arguments must be aligned to 16 bytes on
+ the stack. */
+ argstkspace += round2 (argstkspace, 16);
+ argstkspace += 16;
+ }
+ }
+ }
+ }
+
+ /* Get current SP location */
+ saved_sp = read_sp ();
+
+ sp -= argstkspace + structstkspace;
+
+ /* Allocate space for backchain and callee's saved lr */
+ sp -= 8;
+
+ /* Make sure that we maintain 16 byte alignment */
+ sp &= ~0x0f;
+
+ /* Update %sp before proceeding any further */
+ write_register (SP_REGNUM, sp);
+
+ /* write the backchain */
+ store_address (old_sp_buf, 4, saved_sp);
+ write_memory (sp, old_sp_buf, 4);
+
+ argoffset = 8;
+ structoffset = argoffset + argstkspace;
+ freg = 1;
+ greg = 3;
+ vreg = 2;
+ /* Fill in r3 with the return structure, if any */
+ if (struct_return)
+ {
+ char val_buf[4];
+ store_address (val_buf, 4, struct_addr);
+ memcpy (&registers[REGISTER_BYTE (greg)], val_buf, 4);
+ greg++;
+ }
+ /* Now fill in the registers and stack... */
+ for (argno = 0; argno < nargs; argno++)
+ {
+ arg = args[argno];
+ type = check_typedef (VALUE_TYPE (arg));
+ len = TYPE_LENGTH (type);
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
+ if (freg <= 8)
+ {
+ if (len > 8)
+ printf_unfiltered (
+ "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM + freg)],
+ VALUE_CONTENTS (arg), len);
+ freg++;
+ }
+ else
+ {
+ /* SysV ABI converts floats to doubles when placed in
+ memory and requires 8 byte alignment */
+ /* FIXME: Convert floats to doubles */
+ if (argoffset & 0x4)
+ argoffset += 4;
+ write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
+ argoffset += 8;
+ }
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8) /* long long */
+ {
+ if (greg > 9)
+ {
+ greg = 11;
+ if (argoffset & 0x4)
+ argoffset += 4;
+ write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
+ argoffset += 8;
+ }
+ else
+ {
+ if ((greg & 1) == 0)
+ greg++;
+
+ memcpy (&registers[REGISTER_BYTE (greg)],
+ VALUE_CONTENTS (arg), 4);
+ memcpy (&registers[REGISTER_BYTE (greg + 1)],
+ VALUE_CONTENTS (arg) + 4, 4);
+ greg += 2;
+ }
+ }
+ else if (!TYPE_VECTOR (type))
+ {
+ char val_buf[4];
+ if (len > 4
+ || TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION)
+ {
+ write_memory (sp + structoffset, VALUE_CONTENTS (arg), len);
+ store_address (val_buf, 4, sp + structoffset);
+ structoffset += round2 (len, 8);
+ }
+ else
+ {
+ memset (val_buf, 0, 4);
+ memcpy (val_buf, VALUE_CONTENTS (arg), len);
+ }
+ if (greg <= 10)
+ {
+ memcpy (&registers[REGISTER_BYTE (greg)], val_buf, 4);
+ greg++;
+ }
+ else
+ {
+ write_memory (sp + argoffset, val_buf, 4);
+ argoffset += 4;
+ }
+ }
+ else
+ {
+ if (len == 16
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_VECTOR (type))
+ {
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ char *v_val_buf = alloca (16);
+ memset (v_val_buf, 0, 16);
+ memcpy (v_val_buf, VALUE_CONTENTS (arg), len);
+ if (vreg <= 13)
+ {
+ memcpy (&registers[REGISTER_BYTE (tdep->ppc_vr0_regnum
+ + vreg)],
+ v_val_buf, 16);
+ vreg++;
+ }
+ else
+ {
+ write_memory (sp + argoffset, v_val_buf, 16);
+ argoffset += 16;
+ }
+ }
+ }
+ }
+
+ target_store_registers (-1);
+ return sp;
+}
+
+/* Until November 2001, gcc was not complying to the SYSV ABI for
+ returning structures less than or equal to 8 bytes in size. It was
+ returning everything in memory. When this was corrected, it wasn't
+ fixed for native platforms. */
+int
+ppc_sysv_abi_broken_use_struct_convention (int gcc_p, struct type *value_type)
+{
+ if (TYPE_LENGTH (value_type) == 16
+ && TYPE_VECTOR (value_type))
+ return 0;
+
+ return generic_use_struct_convention (gcc_p, value_type);
+}
+
+/* Structures 8 bytes or less long are returned in the r3 & r4
+ registers, according to the SYSV ABI. */
+int
+ppc_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type)
+{
+ if (TYPE_LENGTH (value_type) == 16
+ && TYPE_VECTOR (value_type))
+ return 0;
+
+ return (TYPE_LENGTH (value_type) > 8);
+}
diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h
new file mode 100644
index 00000000000..3da66ad1405
--- /dev/null
+++ b/gdb/ppc-tdep.h
@@ -0,0 +1,75 @@
+/* Target-dependent code for GDB, the GNU debugger.
+ Copyright 2000
+ 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. */
+
+#ifndef PPC_TDEP_H
+#define PPC_TDEP_H
+
+struct frame_info;
+struct value;
+
+/* From ppc-linux-tdep.c... */
+CORE_ADDR ppc_linux_frame_saved_pc (struct frame_info *fi);
+void ppc_linux_init_extra_frame_info (int fromleaf, struct frame_info *);
+int ppc_linux_frameless_function_invocation (struct frame_info *);
+void ppc_linux_frame_init_saved_regs (struct frame_info *);
+CORE_ADDR ppc_linux_frame_chain (struct frame_info *);
+int ppc_sysv_abi_use_struct_convention (int, struct type *);
+int ppc_sysv_abi_broken_use_struct_convention (int, struct type *);
+CORE_ADDR ppc_sysv_abi_push_arguments (int, struct value **, CORE_ADDR, int,
+ CORE_ADDR);
+int ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache);
+struct link_map_offsets *ppc_linux_svr4_fetch_link_map_offsets (void);
+
+
+/* From rs6000-tdep.c... */
+CORE_ADDR rs6000_frame_saved_pc (struct frame_info *fi);
+void rs6000_init_extra_frame_info (int fromleaf, struct frame_info *);
+int rs6000_frameless_function_invocation (struct frame_info *);
+void rs6000_frame_init_saved_regs (struct frame_info *);
+CORE_ADDR rs6000_frame_chain (struct frame_info *);
+int altivec_register_p (int regno);
+
+/* Private data that this module attaches to struct gdbarch. */
+
+struct gdbarch_tdep
+ {
+ int wordsize; /* size in bytes of fixed-point word */
+ int osabi; /* OS / ABI from ELF header */
+ int *regoff; /* byte offsets in register arrays */
+ const struct reg *regs; /* from current variant */
+ int ppc_gp0_regnum; /* GPR register 0 */
+ int ppc_gplast_regnum; /* GPR register 31 */
+ int ppc_toc_regnum; /* TOC register */
+ int ppc_ps_regnum; /* Processor (or machine) status (%msr) */
+ int ppc_cr_regnum; /* Condition register */
+ int ppc_lr_regnum; /* Link register */
+ int ppc_ctr_regnum; /* Count register */
+ int ppc_xer_regnum; /* Integer exception register */
+ int ppc_fpscr_regnum; /* Floating point status and condition
+ register */
+ int ppc_mq_regnum; /* Multiply/Divide extension register */
+ int ppc_vr0_regnum; /* First AltiVec register */
+ int ppc_vrsave_regnum; /* Last AltiVec register */
+ int lr_frame_offset; /* Offset to ABI specific location where
+ link register is saved. */
+};
+
+#endif
diff --git a/gdb/ppcbug-rom.c b/gdb/ppcbug-rom.c
new file mode 100644
index 00000000000..712af06d3ff
--- /dev/null
+++ b/gdb/ppcbug-rom.c
@@ -0,0 +1,223 @@
+/* Remote debugging interface for PPCbug (PowerPC) Rom monitor
+ for GDB, the GNU debugger.
+ Copyright 1995, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+ Written by Stu Grossman of 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 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "regcache.h"
+
+static void
+ppcbug_supply_register (char *regname, int regnamelen, char *val, int vallen)
+{
+ int regno = 0;
+
+ if (regnamelen < 2 || regnamelen > 4)
+ return;
+
+ switch (regname[0])
+ {
+ case 'R':
+ if (regname[1] < '0' || regname[1] > '9')
+ return;
+ if (regnamelen == 2)
+ regno = regname[1] - '0';
+ else if (regnamelen == 3 && regname[2] >= '0' && regname[2] <= '9')
+ regno = (regname[1] - '0') * 10 + (regname[2] - '0');
+ else
+ return;
+ break;
+ case 'F':
+ if (regname[1] != 'R' || regname[2] < '0' || regname[2] > '9')
+ return;
+ if (regnamelen == 3)
+ regno = 32 + regname[2] - '0';
+ else if (regnamelen == 4 && regname[3] >= '0' && regname[3] <= '9')
+ regno = 32 + (regname[2] - '0') * 10 + (regname[3] - '0');
+ else
+ return;
+ break;
+ case 'I':
+ if (regnamelen != 2 || regname[1] != 'P')
+ return;
+ regno = 64;
+ break;
+ case 'M':
+ if (regnamelen != 3 || regname[1] != 'S' || regname[2] != 'R')
+ return;
+ regno = 65;
+ break;
+ case 'C':
+ if (regnamelen != 2 || regname[1] != 'R')
+ return;
+ regno = 66;
+ break;
+ case 'S':
+ if (regnamelen != 4 || regname[1] != 'P' || regname[2] != 'R')
+ return;
+ else if (regname[3] == '8')
+ regno = 67;
+ else if (regname[3] == '9')
+ regno = 68;
+ else if (regname[3] == '1')
+ regno = 69;
+ else if (regname[3] == '0')
+ regno = 70;
+ else
+ return;
+ break;
+ default:
+ return;
+ }
+
+ monitor_supply_register (regno, val);
+}
+
+/*
+ * This array of registers needs to match the indexes used by GDB. The
+ * whole reason this exists is because the various ROM monitors use
+ * different names than GDB does, and don't support all the
+ * registers either. So, typing "info reg sp" becomes an "A7".
+ */
+
+static char *ppcbug_regnames[] =
+{
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+
+ "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
+ "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
+ "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
+ "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31",
+
+/* pc ps cnd lr cnt xer mq */
+ "ip", "msr", "cr", "spr8", "spr9", "spr1", "spr0"
+};
+
+/*
+ * Define the monitor command strings. Since these are passed directly
+ * through to a printf style function, we need can include formatting
+ * strings. We also need a CR or LF on the end.
+ */
+
+static struct target_ops ppcbug_ops0;
+static struct target_ops ppcbug_ops1;
+
+static char *ppcbug_inits[] =
+{"\r", NULL};
+
+static void
+init_ppc_cmds (char *LOAD_CMD,
+ struct monitor_ops *OPS,
+ struct target_ops *targops)
+{
+ OPS->flags = MO_CLR_BREAK_USES_ADDR | MO_HANDLE_NL;
+ OPS->init = ppcbug_inits; /* Init strings */
+ OPS->cont = "g\r"; /* continue command */
+ OPS->step = "t\r"; /* single step */
+ OPS->stop = NULL; /* interrupt command */
+ OPS->set_break = "br %x\r"; /* set a breakpoint */
+ OPS->clr_break = "nobr %x\r"; /* clear a breakpoint */
+ OPS->clr_all_break = "nobr\r"; /* clear all breakpoints */
+ OPS->fill = "bf %x:%x %x;b\r"; /* fill (start count val) */
+ OPS->setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */
+ OPS->setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */
+ OPS->setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */
+ OPS->setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ OPS->setmem.resp_delim = NULL; /* setreg.resp_delim */
+ OPS->setmem.term = NULL; /* setreg.term */
+ OPS->setmem.term_cmd = NULL; /* setreg.term_cmd */
+ OPS->getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */
+ OPS->getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */
+ OPS->getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */
+ OPS->getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ OPS->getmem.resp_delim = " "; /* getmem.resp_delim */
+ OPS->getmem.term = NULL; /* getmem.term */
+ OPS->getmem.term_cmd = NULL; /* getmem.term_cmd */
+ OPS->setreg.cmd = "rs %s %x\r"; /* setreg.cmd (name, value) */
+ OPS->setreg.resp_delim = NULL; /* setreg.resp_delim */
+ OPS->setreg.term = NULL; /* setreg.term */
+ OPS->setreg.term_cmd = NULL; /* setreg.term_cmd */
+ OPS->getreg.cmd = "rs %s\r"; /* getreg.cmd (name) */
+ OPS->getreg.resp_delim = "="; /* getreg.resp_delim */
+ OPS->getreg.term = NULL; /* getreg.term */
+ OPS->getreg.term_cmd = NULL; /* getreg.term_cmd */
+ OPS->register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
+ OPS->supply_register = ppcbug_supply_register; /* supply_register */
+ OPS->dump_registers = "rd\r"; /* dump all registers */
+ OPS->load_routine = NULL; /* load_routine (defaults to SRECs) */
+ OPS->load = LOAD_CMD; /* download command */
+ OPS->loadresp = NULL; /* load response */
+ OPS->prompt = "PPC1-Bug>"; /* monitor command prompt */
+ OPS->line_term = "\r"; /* end-of-line terminator */
+ OPS->cmd_end = NULL; /* optional command terminator */
+ OPS->target = targops; /* target operations */
+ OPS->stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ OPS->regnames = ppcbug_regnames; /* registers names */
+ OPS->magic = MONITOR_OPS_MAGIC; /* magic */
+}
+
+
+static struct monitor_ops ppcbug_cmds0;
+static struct monitor_ops ppcbug_cmds1;
+
+static void
+ppcbug_open0 (char *args, int from_tty)
+{
+ monitor_open (args, &ppcbug_cmds0, from_tty);
+}
+
+static void
+ppcbug_open1 (char *args, int from_tty)
+{
+ monitor_open (args, &ppcbug_cmds1, from_tty);
+}
+
+void
+_initialize_ppcbug_rom (void)
+{
+ init_ppc_cmds ("lo 0\r", &ppcbug_cmds0, &ppcbug_ops0);
+ init_ppc_cmds ("lo 1\r", &ppcbug_cmds1, &ppcbug_ops1);
+ init_monitor_ops (&ppcbug_ops0);
+
+ ppcbug_ops0.to_shortname = "ppcbug";
+ ppcbug_ops0.to_longname = "PowerPC PPCBug monitor on port 0";
+ ppcbug_ops0.to_doc = "Debug via the PowerPC PPCBug monitor using port 0.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ ppcbug_ops0.to_open = ppcbug_open0;
+
+ add_target (&ppcbug_ops0);
+
+ init_monitor_ops (&ppcbug_ops1);
+
+ ppcbug_ops1.to_shortname = "ppcbug1";
+ ppcbug_ops1.to_longname = "PowerPC PPCBug monitor on port 1";
+ ppcbug_ops1.to_doc = "Debug via the PowerPC PPCBug monitor using port 1.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ ppcbug_ops1.to_open = ppcbug_open1;
+
+ add_target (&ppcbug_ops1);
+}
diff --git a/gdb/ppcnbsd-nat.c b/gdb/ppcnbsd-nat.c
new file mode 100644
index 00000000000..2e43ce46411
--- /dev/null
+++ b/gdb/ppcnbsd-nat.c
@@ -0,0 +1,123 @@
+/* Native-dependent code for PowerPC's running NetBSD, for GDB.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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 <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "defs.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#include "ppc-tdep.h"
+#include "ppcnbsd-tdep.h"
+
+/* Returns true if PT_GETREGS fetches this register. */
+static int
+getregs_supplies (int regno)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ return ((regno >= 0 && regno <= 31)
+ || regno == tdep->ppc_lr_regnum
+ || regno == tdep->ppc_cr_regnum
+ || regno == tdep->ppc_xer_regnum
+ || regno == tdep->ppc_ctr_regnum
+ || regno == PC_REGNUM);
+}
+
+/* Like above, but for PT_GETFPREGS. */
+static int
+getfpregs_supplies (int regno)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ return ((regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31)
+ || regno == tdep->ppc_fpscr_regnum);
+}
+
+void
+fetch_inferior_registers (int regno)
+{
+ if (regno == -1 || getregs_supplies (regno))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ ppcnbsd_supply_reg ((char *) &regs, regno);
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1 || getfpregs_supplies (regno))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get FP registers");
+
+ ppcnbsd_supply_fpreg ((char *) &fpregs, regno);
+ if (regno != -1)
+ return;
+ }
+}
+
+void
+store_inferior_registers (int regno)
+{
+ if (regno == -1 || getregs_supplies (regno))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ ppcnbsd_fill_reg ((char *) &regs, regno);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't write registers");
+
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1 || getfpregs_supplies (regno))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get FP registers");
+
+ ppcnbsd_fill_fpreg ((char *) &fpregs, regno);
+
+ if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't set FP registers");
+ }
+}
diff --git a/gdb/ppcnbsd-tdep.c b/gdb/ppcnbsd-tdep.c
new file mode 100644
index 00000000000..16662fd6287
--- /dev/null
+++ b/gdb/ppcnbsd-tdep.c
@@ -0,0 +1,222 @@
+/* Target-dependent code for PowerPC systems running NetBSD.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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 "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "target.h"
+#include "breakpoint.h"
+#include "value.h"
+
+#include "ppc-tdep.h"
+#include "ppcnbsd-tdep.h"
+#include "nbsd-tdep.h"
+
+#include "solib-svr4.h"
+
+#define REG_FIXREG_OFFSET(x) ((x) * 4)
+#define REG_LR_OFFSET (32 * 4)
+#define REG_CR_OFFSET (33 * 4)
+#define REG_XER_OFFSET (34 * 4)
+#define REG_CTR_OFFSET (35 * 4)
+#define REG_PC_OFFSET (36 * 4)
+#define SIZEOF_STRUCT_REG (37 * 4)
+
+#define FPREG_FPR_OFFSET(x) ((x) * 8)
+#define FPREG_FPSCR_OFFSET (32 * 8)
+#define SIZEOF_STRUCT_FPREG (33 * 8)
+
+void
+ppcnbsd_supply_reg (char *regs, int regno)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ int i;
+
+ for (i = 0; i <= 31; i++)
+ {
+ if (regno == i || regno == -1)
+ supply_register (i, regs + REG_FIXREG_OFFSET (i));
+ }
+
+ if (regno == tdep->ppc_lr_regnum || regno == -1)
+ supply_register (tdep->ppc_lr_regnum, regs + REG_LR_OFFSET);
+
+ if (regno == tdep->ppc_cr_regnum || regno == -1)
+ supply_register (tdep->ppc_cr_regnum, regs + REG_CR_OFFSET);
+
+ if (regno == tdep->ppc_xer_regnum || regno == -1)
+ supply_register (tdep->ppc_xer_regnum, regs + REG_XER_OFFSET);
+
+ if (regno == tdep->ppc_ctr_regnum || regno == -1)
+ supply_register (tdep->ppc_ctr_regnum, regs + REG_CTR_OFFSET);
+
+ if (regno == PC_REGNUM || regno == -1)
+ supply_register (PC_REGNUM, regs + REG_PC_OFFSET);
+}
+
+void
+ppcnbsd_fill_reg (char *regs, int regno)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ int i;
+
+ for (i = 0; i <= 31; i++)
+ {
+ if (regno == i || regno == -1)
+ regcache_collect (i, regs + REG_FIXREG_OFFSET (i));
+ }
+
+ if (regno == tdep->ppc_lr_regnum || regno == -1)
+ regcache_collect (tdep->ppc_lr_regnum, regs + REG_LR_OFFSET);
+
+ if (regno == tdep->ppc_cr_regnum || regno == -1)
+ regcache_collect (tdep->ppc_cr_regnum, regs + REG_CR_OFFSET);
+
+ if (regno == tdep->ppc_xer_regnum || regno == -1)
+ regcache_collect (tdep->ppc_xer_regnum, regs + REG_XER_OFFSET);
+
+ if (regno == tdep->ppc_ctr_regnum || regno == -1)
+ regcache_collect (tdep->ppc_ctr_regnum, regs + REG_CTR_OFFSET);
+
+ if (regno == PC_REGNUM || regno == -1)
+ regcache_collect (PC_REGNUM, regs + REG_PC_OFFSET);
+}
+
+void
+ppcnbsd_supply_fpreg (char *fpregs, int regno)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ int i;
+
+ for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
+ {
+ if (regno == i || regno == -1)
+ supply_register (i, fpregs + FPREG_FPR_OFFSET (i - FP0_REGNUM));
+ }
+
+ if (regno == tdep->ppc_fpscr_regnum || regno == -1)
+ supply_register (tdep->ppc_fpscr_regnum, fpregs + FPREG_FPSCR_OFFSET);
+}
+
+void
+ppcnbsd_fill_fpreg (char *fpregs, int regno)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ int i;
+
+ for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
+ {
+ if (regno == i || regno == -1)
+ regcache_collect (i, fpregs + FPREG_FPR_OFFSET (i - FP0_REGNUM));
+ }
+
+ if (regno == tdep->ppc_fpscr_regnum || regno == -1)
+ regcache_collect (tdep->ppc_fpscr_regnum, fpregs + FPREG_FPSCR_OFFSET);
+}
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR ignore)
+{
+ char *regs, *fpregs;
+
+ /* We get everything from one section. */
+ if (which != 0)
+ return;
+
+ regs = core_reg_sect;
+ fpregs = core_reg_sect + SIZEOF_STRUCT_REG;
+
+ /* Integer registers. */
+ ppcnbsd_supply_reg (regs, -1);
+
+ /* Floating point registers. */
+ ppcnbsd_supply_fpreg (fpregs, -1);
+}
+
+static void
+fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR ignore)
+{
+ switch (which)
+ {
+ case 0: /* Integer registers. */
+ if (core_reg_size != SIZEOF_STRUCT_REG)
+ warning ("Wrong size register set in core file.");
+ else
+ ppcnbsd_supply_reg (core_reg_sect, -1);
+ break;
+
+ case 2: /* Floating point registers. */
+ if (core_reg_size != SIZEOF_STRUCT_FPREG)
+ warning ("Wrong size FP register set in core file.");
+ else
+ ppcnbsd_supply_fpreg (core_reg_sect, -1);
+ break;
+
+ default:
+ /* Don't know what kind of register request this is; just ignore it. */
+ break;
+ }
+}
+
+static struct core_fns ppcnbsd_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+static struct core_fns ppcnbsd_elfcore_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_elfcore_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+static void
+ppcnbsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ /* Until November 2001, gcc was not complying to the SYSV ABI for
+ returning structures less than or equal to 8 bytes in size. It was
+ returning everything in memory. When this was corrected, it wasn't
+ fixed for native platforms. */
+ set_gdbarch_use_struct_convention (gdbarch,
+ ppc_sysv_abi_broken_use_struct_convention);
+
+ set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ nbsd_ilp32_solib_svr4_fetch_link_map_offsets);
+}
+
+void
+_initialize_ppcnbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_powerpc, GDB_OSABI_NETBSD_ELF,
+ ppcnbsd_init_abi);
+
+ add_core_fns (&ppcnbsd_core_fns);
+ add_core_fns (&ppcnbsd_elfcore_fns);
+}
diff --git a/gdb/ppcnbsd-tdep.h b/gdb/ppcnbsd-tdep.h
new file mode 100644
index 00000000000..3eae72d819a
--- /dev/null
+++ b/gdb/ppcnbsd-tdep.h
@@ -0,0 +1,30 @@
+/* Common target dependent code for GDB on PowerPC systems running NetBSD.
+ Copyright 2002 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. */
+
+#ifndef PPCNBSD_TDEP_H
+#define PPCNBSD_TDEP_H
+
+void ppcnbsd_supply_reg (char *, int);
+void ppcnbsd_fill_reg (char *, int);
+
+void ppcnbsd_supply_fpreg (char *, int);
+void ppcnbsd_fill_fpreg (char *, int);
+
+#endif /* PPCNBSD_TDEP_H */
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
new file mode 100644
index 00000000000..de306f0b98f
--- /dev/null
+++ b/gdb/printcmd.c
@@ -0,0 +1,2567 @@
+/* Print values for GNU debugger GDB.
+
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+#include "gdb_string.h"
+#include "frame.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "value.h"
+#include "language.h"
+#include "expression.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "breakpoint.h"
+#include "demangle.h"
+#include "valprint.h"
+#include "annotate.h"
+#include "symfile.h" /* for overlay functions */
+#include "objfiles.h" /* ditto */
+#include "completer.h" /* for completion functions */
+#include "ui-out.h"
+
+extern int asm_demangle; /* Whether to demangle syms in asm printouts */
+extern int addressprint; /* Whether to print hex addresses in HLL " */
+
+struct format_data
+ {
+ int count;
+ char format;
+ char size;
+ };
+
+/* Last specified output format. */
+
+static char last_format = 'x';
+
+/* Last specified examination size. 'b', 'h', 'w' or `q'. */
+
+static char last_size = 'w';
+
+/* Default address to examine next. */
+
+static CORE_ADDR next_address;
+
+/* Default section to examine next. */
+
+static asection *next_section;
+
+/* Last address examined. */
+
+static CORE_ADDR last_examine_address;
+
+/* Contents of last address examined.
+ This is not valid past the end of the `x' command! */
+
+static struct value *last_examine_value;
+
+/* Largest offset between a symbolic value and an address, that will be
+ printed as `0x1234 <symbol+offset>'. */
+
+static unsigned int max_symbolic_offset = UINT_MAX;
+
+/* Append the source filename and linenumber of the symbol when
+ printing a symbolic value as `<symbol at filename:linenum>' if set. */
+static int print_symbol_filename = 0;
+
+/* Number of auto-display expression currently being displayed.
+ So that we can disable it if we get an error or a signal within it.
+ -1 when not doing one. */
+
+int current_display_number;
+
+/* Flag to low-level print routines that this value is being printed
+ in an epoch window. We'd like to pass this as a parameter, but
+ every routine would need to take it. Perhaps we can encapsulate
+ this in the I/O stream once we have GNU stdio. */
+
+int inspect_it = 0;
+
+struct display
+ {
+ /* Chain link to next auto-display item. */
+ struct display *next;
+ /* Expression to be evaluated and displayed. */
+ struct expression *exp;
+ /* Item number of this auto-display item. */
+ int number;
+ /* Display format specified. */
+ struct format_data format;
+ /* Innermost block required by this expression when evaluated */
+ struct block *block;
+ /* Status of this display (enabled or disabled) */
+ int enabled_p;
+ };
+
+/* Chain of expressions whose values should be displayed
+ automatically each time the program stops. */
+
+static struct display *display_chain;
+
+static int display_number;
+
+/* Prototypes for exported functions. */
+
+void output_command (char *, int);
+
+void _initialize_printcmd (void);
+
+/* Prototypes for local functions. */
+
+static void delete_display (int);
+
+static void enable_display (char *, int);
+
+static void disable_display_command (char *, int);
+
+static void disassemble_command (char *, int);
+
+static void printf_command (char *, int);
+
+static void print_frame_nameless_args (struct frame_info *, long,
+ int, int, struct ui_file *);
+
+static void display_info (char *, int);
+
+static void do_one_display (struct display *);
+
+static void undisplay_command (char *, int);
+
+static void free_display (struct display *);
+
+static void display_command (char *, int);
+
+void x_command (char *, int);
+
+static void address_info (char *, int);
+
+static void set_command (char *, int);
+
+static void call_command (char *, int);
+
+static void inspect_command (char *, int);
+
+static void print_command (char *, int);
+
+static void print_command_1 (char *, int, int);
+
+static void validate_format (struct format_data, char *);
+
+static void do_examine (struct format_data, CORE_ADDR addr,
+ asection * section);
+
+static void print_formatted (struct value *, int, int, struct ui_file *);
+
+static struct format_data decode_format (char **, int, int);
+
+static int print_insn (CORE_ADDR, struct ui_file *);
+
+static void sym_info (char *, int);
+
+
+/* Decode a format specification. *STRING_PTR should point to it.
+ OFORMAT and OSIZE are used as defaults for the format and size
+ if none are given in the format specification.
+ If OSIZE is zero, then the size field of the returned value
+ should be set only if a size is explicitly specified by the
+ user.
+ The structure returned describes all the data
+ found in the specification. In addition, *STRING_PTR is advanced
+ past the specification and past all whitespace following it. */
+
+static struct format_data
+decode_format (char **string_ptr, int oformat, int osize)
+{
+ struct format_data val;
+ register char *p = *string_ptr;
+
+ val.format = '?';
+ val.size = '?';
+ val.count = 1;
+
+ if (*p >= '0' && *p <= '9')
+ val.count = atoi (p);
+ while (*p >= '0' && *p <= '9')
+ p++;
+
+ /* Now process size or format letters that follow. */
+
+ while (1)
+ {
+ if (*p == 'b' || *p == 'h' || *p == 'w' || *p == 'g')
+ val.size = *p++;
+ else if (*p >= 'a' && *p <= 'z')
+ val.format = *p++;
+ else
+ break;
+ }
+
+ while (*p == ' ' || *p == '\t')
+ p++;
+ *string_ptr = p;
+
+ /* Set defaults for format and size if not specified. */
+ if (val.format == '?')
+ {
+ if (val.size == '?')
+ {
+ /* Neither has been specified. */
+ val.format = oformat;
+ val.size = osize;
+ }
+ else
+ /* If a size is specified, any format makes a reasonable
+ default except 'i'. */
+ val.format = oformat == 'i' ? 'x' : oformat;
+ }
+ else if (val.size == '?')
+ switch (val.format)
+ {
+ case 'a':
+ case 's':
+ /* Pick the appropriate size for an address. */
+ if (TARGET_PTR_BIT == 64)
+ val.size = osize ? 'g' : osize;
+ else if (TARGET_PTR_BIT == 32)
+ val.size = osize ? 'w' : osize;
+ else if (TARGET_PTR_BIT == 16)
+ val.size = osize ? 'h' : osize;
+ else
+ /* Bad value for TARGET_PTR_BIT */
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ break;
+ case 'f':
+ /* Floating point has to be word or giantword. */
+ if (osize == 'w' || osize == 'g')
+ val.size = osize;
+ else
+ /* Default it to giantword if the last used size is not
+ appropriate. */
+ val.size = osize ? 'g' : osize;
+ break;
+ case 'c':
+ /* Characters default to one byte. */
+ val.size = osize ? 'b' : osize;
+ break;
+ default:
+ /* The default is the size most recently specified. */
+ val.size = osize;
+ }
+
+ return val;
+}
+
+/* Print value VAL on stream according to FORMAT, a letter or 0.
+ Do not end with a newline.
+ 0 means print VAL according to its own type.
+ SIZE is the letter for the size of datum being printed.
+ This is used to pad hex numbers so they line up. */
+
+static void
+print_formatted (struct value *val, register int format, int size,
+ struct ui_file *stream)
+{
+ struct type *type = check_typedef (VALUE_TYPE (val));
+ int len = TYPE_LENGTH (type);
+
+ if (VALUE_LVAL (val) == lval_memory)
+ {
+ next_address = VALUE_ADDRESS (val) + len;
+ next_section = VALUE_BFD_SECTION (val);
+ }
+
+ switch (format)
+ {
+ case 's':
+ /* FIXME: Need to handle wchar_t's here... */
+ next_address = VALUE_ADDRESS (val)
+ + val_print_string (VALUE_ADDRESS (val), -1, 1, stream);
+ next_section = VALUE_BFD_SECTION (val);
+ break;
+
+ case 'i':
+ /* The old comment says
+ "Force output out, print_insn not using _filtered".
+ I'm not completely sure what that means, I suspect most print_insn
+ now do use _filtered, so I guess it's obsolete.
+ --Yes, it does filter now, and so this is obsolete. -JB */
+
+ /* We often wrap here if there are long symbolic names. */
+ wrap_here (" ");
+ next_address = VALUE_ADDRESS (val)
+ + print_insn (VALUE_ADDRESS (val), stream);
+ next_section = VALUE_BFD_SECTION (val);
+ break;
+
+ default:
+ if (format == 0
+ || TYPE_CODE (type) == TYPE_CODE_ARRAY
+ || TYPE_CODE (type) == TYPE_CODE_STRING
+ || TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION)
+ /* If format is 0, use the 'natural' format for
+ * that type of value. If the type is non-scalar,
+ * we have to use language rules to print it as
+ * a series of scalars.
+ */
+ value_print (val, stream, format, Val_pretty_default);
+ else
+ /* User specified format, so don't look to the
+ * the type to tell us what to do.
+ */
+ print_scalar_formatted (VALUE_CONTENTS (val), type,
+ format, size, stream);
+ }
+}
+
+/* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR,
+ according to letters FORMAT and SIZE on STREAM.
+ FORMAT may not be zero. Formats s and i are not supported at this level.
+
+ This is how the elements of an array or structure are printed
+ with a format. */
+
+void
+print_scalar_formatted (char *valaddr, struct type *type, int format, int size,
+ struct ui_file *stream)
+{
+ LONGEST val_long;
+ unsigned int len = TYPE_LENGTH (type);
+
+ if (len > sizeof (LONGEST)
+ && (format == 't'
+ || format == 'c'
+ || format == 'o'
+ || format == 'u'
+ || format == 'd'
+ || format == 'x'))
+ {
+ if (!TYPE_UNSIGNED (type)
+ || !extract_long_unsigned_integer (valaddr, len, &val_long))
+ {
+ /* We can't print it normally, but we can print it in hex.
+ Printing it in the wrong radix is more useful than saying
+ "use /x, you dummy". */
+ /* FIXME: we could also do octal or binary if that was the
+ desired format. */
+ /* FIXME: we should be using the size field to give us a
+ minimum field width to print. */
+
+ if (format == 'o')
+ print_octal_chars (stream, valaddr, len);
+ else if (format == 'd')
+ print_decimal_chars (stream, valaddr, len);
+ else if (format == 't')
+ print_binary_chars (stream, valaddr, len);
+ else
+ /* replace with call to print_hex_chars? Looks
+ like val_print_type_code_int is redoing
+ work. - edie */
+
+ val_print_type_code_int (type, valaddr, stream);
+
+ return;
+ }
+
+ /* If we get here, extract_long_unsigned_integer set val_long. */
+ }
+ else if (format != 'f')
+ val_long = unpack_long (type, valaddr);
+
+ /* If the value is a pointer, and pointers and addresses are not the
+ same, then at this point, the value's length is TARGET_ADDR_BIT, not
+ TYPE_LENGTH (type). */
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ len = TARGET_ADDR_BIT;
+
+ /* If we are printing it as unsigned, truncate it in case it is actually
+ a negative signed value (e.g. "print/u (short)-1" should print 65535
+ (if shorts are 16 bits) instead of 4294967295). */
+ if (format != 'd')
+ {
+ if (len < sizeof (LONGEST))
+ val_long &= ((LONGEST) 1 << HOST_CHAR_BIT * len) - 1;
+ }
+
+ switch (format)
+ {
+ case 'x':
+ if (!size)
+ {
+ /* no size specified, like in print. Print varying # of digits. */
+ print_longest (stream, 'x', 1, val_long);
+ }
+ else
+ switch (size)
+ {
+ case 'b':
+ case 'h':
+ case 'w':
+ case 'g':
+ print_longest (stream, size, 1, val_long);
+ break;
+ default:
+ error ("Undefined output size \"%c\".", size);
+ }
+ break;
+
+ case 'd':
+ print_longest (stream, 'd', 1, val_long);
+ break;
+
+ case 'u':
+ print_longest (stream, 'u', 0, val_long);
+ break;
+
+ case 'o':
+ if (val_long)
+ print_longest (stream, 'o', 1, val_long);
+ else
+ fprintf_filtered (stream, "0");
+ break;
+
+ case 'a':
+ {
+ CORE_ADDR addr = unpack_pointer (type, valaddr);
+ print_address (addr, stream);
+ }
+ break;
+
+ case 'c':
+ value_print (value_from_longest (builtin_type_true_char, val_long),
+ stream, 0, Val_pretty_default);
+ break;
+
+ case 'f':
+ if (len == TYPE_LENGTH (builtin_type_float))
+ type = builtin_type_float;
+ else if (len == TYPE_LENGTH (builtin_type_double))
+ type = builtin_type_double;
+ else if (len == TYPE_LENGTH (builtin_type_long_double))
+ type = builtin_type_long_double;
+ print_floating (valaddr, type, stream);
+ break;
+
+ case 0:
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+ case 't':
+ /* Binary; 't' stands for "two". */
+ {
+ char bits[8 * (sizeof val_long) + 1];
+ char buf[8 * (sizeof val_long) + 32];
+ char *cp = bits;
+ int width;
+
+ if (!size)
+ width = 8 * (sizeof val_long);
+ else
+ switch (size)
+ {
+ case 'b':
+ width = 8;
+ break;
+ case 'h':
+ width = 16;
+ break;
+ case 'w':
+ width = 32;
+ break;
+ case 'g':
+ width = 64;
+ break;
+ default:
+ error ("Undefined output size \"%c\".", size);
+ }
+
+ bits[width] = '\0';
+ while (width-- > 0)
+ {
+ bits[width] = (val_long & 1) ? '1' : '0';
+ val_long >>= 1;
+ }
+ if (!size)
+ {
+ while (*cp && *cp == '0')
+ cp++;
+ if (*cp == '\0')
+ cp--;
+ }
+ strcpy (buf, local_binary_format_prefix ());
+ strcat (buf, cp);
+ strcat (buf, local_binary_format_suffix ());
+ fprintf_filtered (stream, buf);
+ }
+ break;
+
+ default:
+ error ("Undefined output format \"%c\".", format);
+ }
+}
+
+/* Specify default address for `x' command.
+ `info lines' uses this. */
+
+void
+set_next_address (CORE_ADDR addr)
+{
+ next_address = addr;
+
+ /* Make address available to the user as $_. */
+ set_internalvar (lookup_internalvar ("_"),
+ value_from_pointer (lookup_pointer_type (builtin_type_void),
+ addr));
+}
+
+/* Optionally print address ADDR symbolically as <SYMBOL+OFFSET> on STREAM,
+ after LEADIN. Print nothing if no symbolic name is found nearby.
+ Optionally also print source file and line number, if available.
+ DO_DEMANGLE controls whether to print a symbol in its native "raw" form,
+ or to interpret it as a possible C++ name and convert it back to source
+ form. However note that DO_DEMANGLE can be overridden by the specific
+ settings of the demangle and asm_demangle variables. */
+
+void
+print_address_symbolic (CORE_ADDR addr, struct ui_file *stream, int do_demangle,
+ char *leadin)
+{
+ char *name = NULL;
+ char *filename = NULL;
+ int unmapped = 0;
+ int offset = 0;
+ int line = 0;
+
+ /* throw away both name and filename */
+ struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &name);
+ make_cleanup (free_current_contents, &filename);
+
+ if (build_address_symbolic (addr, do_demangle, &name, &offset, &filename, &line, &unmapped))
+ {
+ do_cleanups (cleanup_chain);
+ return;
+ }
+
+ fputs_filtered (leadin, stream);
+ if (unmapped)
+ fputs_filtered ("<*", stream);
+ else
+ fputs_filtered ("<", stream);
+ fputs_filtered (name, stream);
+ if (offset != 0)
+ fprintf_filtered (stream, "+%u", (unsigned int) offset);
+
+ /* Append source filename and line number if desired. Give specific
+ line # of this addr, if we have it; else line # of the nearest symbol. */
+ if (print_symbol_filename && filename != NULL)
+ {
+ if (line != -1)
+ fprintf_filtered (stream, " at %s:%d", filename, line);
+ else
+ fprintf_filtered (stream, " in %s", filename);
+ }
+ if (unmapped)
+ fputs_filtered ("*>", stream);
+ else
+ fputs_filtered (">", stream);
+
+ do_cleanups (cleanup_chain);
+}
+
+/* Given an address ADDR return all the elements needed to print the
+ address in a symbolic form. NAME can be mangled or not depending
+ on DO_DEMANGLE (and also on the asm_demangle global variable,
+ manipulated via ''set print asm-demangle''). Return 0 in case of
+ success, when all the info in the OUT paramters is valid. Return 1
+ otherwise. */
+int
+build_address_symbolic (CORE_ADDR addr, /* IN */
+ int do_demangle, /* IN */
+ char **name, /* OUT */
+ int *offset, /* OUT */
+ char **filename, /* OUT */
+ int *line, /* OUT */
+ int *unmapped) /* OUT */
+{
+ struct minimal_symbol *msymbol;
+ struct symbol *symbol;
+ struct symtab *symtab = 0;
+ CORE_ADDR name_location = 0;
+ asection *section = 0;
+ char *name_temp = "";
+
+ /* Let's say it is unmapped. */
+ *unmapped = 0;
+
+ /* Determine if the address is in an overlay, and whether it is
+ mapped. */
+ if (overlay_debugging)
+ {
+ section = find_pc_overlay (addr);
+ if (pc_in_unmapped_range (addr, section))
+ {
+ *unmapped = 1;
+ addr = overlay_mapped_address (addr, section);
+ }
+ }
+
+ /* On some targets, add in extra "flag" bits to PC for
+ disassembly. This should ensure that "rounding errors" in
+ symbol addresses that are masked for disassembly favour the
+ the correct symbol. */
+
+#ifdef GDB_TARGET_UNMASK_DISAS_PC
+ addr = GDB_TARGET_UNMASK_DISAS_PC (addr);
+#endif
+
+ /* First try to find the address in the symbol table, then
+ in the minsyms. Take the closest one. */
+
+ /* This is defective in the sense that it only finds text symbols. So
+ really this is kind of pointless--we should make sure that the
+ minimal symbols have everything we need (by changing that we could
+ save some memory, but for many debug format--ELF/DWARF or
+ anything/stabs--it would be inconvenient to eliminate those minimal
+ symbols anyway). */
+ msymbol = lookup_minimal_symbol_by_pc_section (addr, section);
+ symbol = find_pc_sect_function (addr, section);
+
+ if (symbol)
+ {
+ name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (symbol));
+ if (do_demangle)
+ name_temp = SYMBOL_SOURCE_NAME (symbol);
+ else
+ name_temp = SYMBOL_LINKAGE_NAME (symbol);
+ }
+
+ if (msymbol != NULL)
+ {
+ if (SYMBOL_VALUE_ADDRESS (msymbol) > name_location || symbol == NULL)
+ {
+ /* The msymbol is closer to the address than the symbol;
+ use the msymbol instead. */
+ symbol = 0;
+ symtab = 0;
+ name_location = SYMBOL_VALUE_ADDRESS (msymbol);
+ if (do_demangle)
+ name_temp = SYMBOL_SOURCE_NAME (msymbol);
+ else
+ name_temp = SYMBOL_LINKAGE_NAME (msymbol);
+ }
+ }
+ if (symbol == NULL && msymbol == NULL)
+ return 1;
+
+ /* On some targets, mask out extra "flag" bits from PC for handsome
+ disassembly. */
+
+#ifdef GDB_TARGET_MASK_DISAS_PC
+ name_location = GDB_TARGET_MASK_DISAS_PC (name_location);
+ addr = GDB_TARGET_MASK_DISAS_PC (addr);
+#endif
+
+ /* If the nearest symbol is too far away, don't print anything symbolic. */
+
+ /* For when CORE_ADDR is larger than unsigned int, we do math in
+ CORE_ADDR. But when we detect unsigned wraparound in the
+ CORE_ADDR math, we ignore this test and print the offset,
+ because addr+max_symbolic_offset has wrapped through the end
+ of the address space back to the beginning, giving bogus comparison. */
+ if (addr > name_location + max_symbolic_offset
+ && name_location + max_symbolic_offset > name_location)
+ return 1;
+
+ *offset = addr - name_location;
+
+ *name = xstrdup (name_temp);
+
+ if (print_symbol_filename)
+ {
+ struct symtab_and_line sal;
+
+ sal = find_pc_sect_line (addr, section, 0);
+
+ if (sal.symtab)
+ {
+ *filename = xstrdup (sal.symtab->filename);
+ *line = sal.line;
+ }
+ else if (symtab && symbol && symbol->line)
+ {
+ *filename = xstrdup (symtab->filename);
+ *line = symbol->line;
+ }
+ else if (symtab)
+ {
+ *filename = xstrdup (symtab->filename);
+ *line = -1;
+ }
+ }
+ return 0;
+}
+
+/* Print address ADDR on STREAM. USE_LOCAL means the same thing as for
+ print_longest. */
+void
+print_address_numeric (CORE_ADDR addr, int use_local, struct ui_file *stream)
+{
+ /* Truncate address to the size of a target address, avoiding shifts
+ larger or equal than the width of a CORE_ADDR. The local
+ variable ADDR_BIT stops the compiler reporting a shift overflow
+ when it won't occur. */
+ /* NOTE: This assumes that the significant address information is
+ kept in the least significant bits of ADDR - the upper bits were
+ either zero or sign extended. Should ADDRESS_TO_POINTER() or
+ some ADDRESS_TO_PRINTABLE() be used to do the conversion? */
+
+ int addr_bit = TARGET_ADDR_BIT;
+
+ if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
+ addr &= ((CORE_ADDR) 1 << addr_bit) - 1;
+ print_longest (stream, 'x', use_local, (ULONGEST) addr);
+}
+
+/* Print address ADDR symbolically on STREAM.
+ First print it as a number. Then perhaps print
+ <SYMBOL + OFFSET> after the number. */
+
+void
+print_address (CORE_ADDR addr, struct ui_file *stream)
+{
+ print_address_numeric (addr, 1, stream);
+ print_address_symbolic (addr, stream, asm_demangle, " ");
+}
+
+/* Print address ADDR symbolically on STREAM. Parameter DEMANGLE
+ controls whether to print the symbolic name "raw" or demangled.
+ Global setting "addressprint" controls whether to print hex address
+ or not. */
+
+void
+print_address_demangle (CORE_ADDR addr, struct ui_file *stream, int do_demangle)
+{
+ if (addr == 0)
+ {
+ fprintf_filtered (stream, "0");
+ }
+ else if (addressprint)
+ {
+ print_address_numeric (addr, 1, stream);
+ print_address_symbolic (addr, stream, do_demangle, " ");
+ }
+ else
+ {
+ print_address_symbolic (addr, stream, do_demangle, "");
+ }
+}
+
+
+/* These are the types that $__ will get after an examine command of one
+ of these sizes. */
+
+static struct type *examine_i_type;
+
+static struct type *examine_b_type;
+static struct type *examine_h_type;
+static struct type *examine_w_type;
+static struct type *examine_g_type;
+
+/* Examine data at address ADDR in format FMT.
+ Fetch it from memory and print on gdb_stdout. */
+
+static void
+do_examine (struct format_data fmt, CORE_ADDR addr, asection *sect)
+{
+ register char format = 0;
+ register char size;
+ register int count = 1;
+ struct type *val_type = NULL;
+ register int i;
+ register int maxelts;
+
+ format = fmt.format;
+ size = fmt.size;
+ count = fmt.count;
+ next_address = addr;
+ next_section = sect;
+
+ /* String or instruction format implies fetch single bytes
+ regardless of the specified size. */
+ if (format == 's' || format == 'i')
+ size = 'b';
+
+ if (format == 'i')
+ val_type = examine_i_type;
+ else if (size == 'b')
+ val_type = examine_b_type;
+ else if (size == 'h')
+ val_type = examine_h_type;
+ else if (size == 'w')
+ val_type = examine_w_type;
+ else if (size == 'g')
+ val_type = examine_g_type;
+
+ maxelts = 8;
+ if (size == 'w')
+ maxelts = 4;
+ if (size == 'g')
+ maxelts = 2;
+ if (format == 's' || format == 'i')
+ maxelts = 1;
+
+ /* Print as many objects as specified in COUNT, at most maxelts per line,
+ with the address of the next one at the start of each line. */
+
+ while (count > 0)
+ {
+ QUIT;
+ print_address (next_address, gdb_stdout);
+ printf_filtered (":");
+ for (i = maxelts;
+ i > 0 && count > 0;
+ i--, count--)
+ {
+ printf_filtered ("\t");
+ /* Note that print_formatted sets next_address for the next
+ object. */
+ last_examine_address = next_address;
+
+ if (last_examine_value)
+ value_free (last_examine_value);
+
+ /* The value to be displayed is not fetched greedily.
+ Instead, to avoid the posibility of a fetched value not
+ being used, its retreval is delayed until the print code
+ uses it. When examining an instruction stream, the
+ disassembler will perform its own memory fetch using just
+ the address stored in LAST_EXAMINE_VALUE. FIXME: Should
+ the disassembler be modified so that LAST_EXAMINE_VALUE
+ is left with the byte sequence from the last complete
+ instruction fetched from memory? */
+ last_examine_value = value_at_lazy (val_type, next_address, sect);
+
+ if (last_examine_value)
+ release_value (last_examine_value);
+
+ print_formatted (last_examine_value, format, size, gdb_stdout);
+ }
+ printf_filtered ("\n");
+ gdb_flush (gdb_stdout);
+ }
+}
+
+static void
+validate_format (struct format_data fmt, char *cmdname)
+{
+ if (fmt.size != 0)
+ error ("Size letters are meaningless in \"%s\" command.", cmdname);
+ if (fmt.count != 1)
+ error ("Item count other than 1 is meaningless in \"%s\" command.",
+ cmdname);
+ if (fmt.format == 'i' || fmt.format == 's')
+ error ("Format letter \"%c\" is meaningless in \"%s\" command.",
+ fmt.format, cmdname);
+}
+
+/* Evaluate string EXP as an expression in the current language and
+ print the resulting value. EXP may contain a format specifier as the
+ first argument ("/x myvar" for example, to print myvar in hex).
+ */
+
+static void
+print_command_1 (char *exp, int inspect, int voidprint)
+{
+ struct expression *expr;
+ register struct cleanup *old_chain = 0;
+ register char format = 0;
+ struct value *val;
+ struct format_data fmt;
+ int cleanup = 0;
+
+ /* Pass inspect flag to the rest of the print routines in a global (sigh). */
+ inspect_it = inspect;
+
+ if (exp && *exp == '/')
+ {
+ exp++;
+ fmt = decode_format (&exp, last_format, 0);
+ validate_format (fmt, "print");
+ last_format = format = fmt.format;
+ }
+ else
+ {
+ fmt.count = 1;
+ fmt.format = 0;
+ fmt.size = 0;
+ }
+
+ if (exp && *exp)
+ {
+ struct type *type;
+ expr = parse_expression (exp);
+ old_chain = make_cleanup (free_current_contents, &expr);
+ cleanup = 1;
+ val = evaluate_expression (expr);
+ }
+ else
+ val = access_value_history (0);
+
+ if (voidprint || (val && VALUE_TYPE (val) &&
+ TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_VOID))
+ {
+ int histindex = record_latest_value (val);
+
+ if (histindex >= 0)
+ annotate_value_history_begin (histindex, VALUE_TYPE (val));
+ else
+ annotate_value_begin (VALUE_TYPE (val));
+
+ if (inspect)
+ printf_unfiltered ("\031(gdb-makebuffer \"%s\" %d '(\"", exp, histindex);
+ else if (histindex >= 0)
+ printf_filtered ("$%d = ", histindex);
+
+ if (histindex >= 0)
+ annotate_value_history_value ();
+
+ print_formatted (val, format, fmt.size, gdb_stdout);
+ printf_filtered ("\n");
+
+ if (histindex >= 0)
+ annotate_value_history_end ();
+ else
+ annotate_value_end ();
+
+ if (inspect)
+ printf_unfiltered ("\") )\030");
+ }
+
+ if (cleanup)
+ do_cleanups (old_chain);
+ inspect_it = 0; /* Reset print routines to normal */
+}
+
+/* ARGSUSED */
+static void
+print_command (char *exp, int from_tty)
+{
+ print_command_1 (exp, 0, 1);
+}
+
+/* Same as print, except in epoch, it gets its own window */
+/* ARGSUSED */
+static void
+inspect_command (char *exp, int from_tty)
+{
+ extern int epoch_interface;
+
+ print_command_1 (exp, epoch_interface, 1);
+}
+
+/* Same as print, except it doesn't print void results. */
+/* ARGSUSED */
+static void
+call_command (char *exp, int from_tty)
+{
+ print_command_1 (exp, 0, 0);
+}
+
+/* ARGSUSED */
+void
+output_command (char *exp, int from_tty)
+{
+ struct expression *expr;
+ register struct cleanup *old_chain;
+ register char format = 0;
+ struct value *val;
+ struct format_data fmt;
+
+ if (exp && *exp == '/')
+ {
+ exp++;
+ fmt = decode_format (&exp, 0, 0);
+ validate_format (fmt, "output");
+ format = fmt.format;
+ }
+
+ expr = parse_expression (exp);
+ old_chain = make_cleanup (free_current_contents, &expr);
+
+ val = evaluate_expression (expr);
+
+ annotate_value_begin (VALUE_TYPE (val));
+
+ print_formatted (val, format, fmt.size, gdb_stdout);
+
+ annotate_value_end ();
+
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+
+ do_cleanups (old_chain);
+}
+
+/* ARGSUSED */
+static void
+set_command (char *exp, int from_tty)
+{
+ struct expression *expr = parse_expression (exp);
+ register struct cleanup *old_chain =
+ make_cleanup (free_current_contents, &expr);
+ evaluate_expression (expr);
+ do_cleanups (old_chain);
+}
+
+/* ARGSUSED */
+static void
+sym_info (char *arg, int from_tty)
+{
+ struct minimal_symbol *msymbol;
+ struct objfile *objfile;
+ struct obj_section *osect;
+ asection *sect;
+ CORE_ADDR addr, sect_addr;
+ int matches = 0;
+ unsigned int offset;
+
+ if (!arg)
+ error_no_arg ("address");
+
+ addr = parse_and_eval_address (arg);
+ ALL_OBJSECTIONS (objfile, osect)
+ {
+ sect = osect->the_bfd_section;
+ sect_addr = overlay_mapped_address (addr, sect);
+
+ if (osect->addr <= sect_addr && sect_addr < osect->endaddr &&
+ (msymbol = lookup_minimal_symbol_by_pc_section (sect_addr, sect)))
+ {
+ matches = 1;
+ offset = sect_addr - SYMBOL_VALUE_ADDRESS (msymbol);
+ if (offset)
+ printf_filtered ("%s + %u in ",
+ SYMBOL_SOURCE_NAME (msymbol), offset);
+ else
+ printf_filtered ("%s in ",
+ SYMBOL_SOURCE_NAME (msymbol));
+ if (pc_in_unmapped_range (addr, sect))
+ printf_filtered ("load address range of ");
+ if (section_is_overlay (sect))
+ printf_filtered ("%s overlay ",
+ section_is_mapped (sect) ? "mapped" : "unmapped");
+ printf_filtered ("section %s", sect->name);
+ printf_filtered ("\n");
+ }
+ }
+ if (matches == 0)
+ printf_filtered ("No symbol matches %s.\n", arg);
+}
+
+/* ARGSUSED */
+static void
+address_info (char *exp, int from_tty)
+{
+ register struct symbol *sym;
+ register struct minimal_symbol *msymbol;
+ register long val;
+ register long basereg;
+ asection *section;
+ CORE_ADDR load_addr;
+ int is_a_field_of_this; /* C++: lookup_symbol sets this to nonzero
+ if exp is a field of `this'. */
+
+ if (exp == 0)
+ error ("Argument required.");
+
+ sym = lookup_symbol (exp, get_selected_block (0), VAR_NAMESPACE,
+ &is_a_field_of_this, (struct symtab **) NULL);
+ if (sym == NULL)
+ {
+ if (is_a_field_of_this)
+ {
+ printf_filtered ("Symbol \"");
+ fprintf_symbol_filtered (gdb_stdout, exp,
+ current_language->la_language, DMGL_ANSI);
+ printf_filtered ("\" is a field of the local class variable `this'\n");
+ return;
+ }
+
+ msymbol = lookup_minimal_symbol (exp, NULL, NULL);
+
+ if (msymbol != NULL)
+ {
+ load_addr = SYMBOL_VALUE_ADDRESS (msymbol);
+
+ printf_filtered ("Symbol \"");
+ fprintf_symbol_filtered (gdb_stdout, exp,
+ current_language->la_language, DMGL_ANSI);
+ printf_filtered ("\" is at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in a file compiled without debugging");
+ section = SYMBOL_BFD_SECTION (msymbol);
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
+ printf_filtered (".\n");
+ }
+ else
+ error ("No symbol \"%s\" in current context.", exp);
+ return;
+ }
+
+ printf_filtered ("Symbol \"");
+ fprintf_symbol_filtered (gdb_stdout, SYMBOL_NAME (sym),
+ current_language->la_language, DMGL_ANSI);
+ printf_filtered ("\" is ");
+ val = SYMBOL_VALUE (sym);
+ basereg = SYMBOL_BASEREG (sym);
+ section = SYMBOL_BFD_SECTION (sym);
+
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_CONST:
+ case LOC_CONST_BYTES:
+ printf_filtered ("constant");
+ break;
+
+ case LOC_LABEL:
+ printf_filtered ("a label at address ");
+ print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
+ 1, gdb_stdout);
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
+ break;
+
+ case LOC_REGISTER:
+ printf_filtered ("a variable in register %s", REGISTER_NAME (val));
+ break;
+
+ case LOC_STATIC:
+ printf_filtered ("static storage at address ");
+ print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
+ 1, gdb_stdout);
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
+ break;
+
+ case LOC_INDIRECT:
+ printf_filtered ("external global (indirect addressing), at address *(");
+ print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
+ 1, gdb_stdout);
+ printf_filtered (")");
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
+ break;
+
+ case LOC_REGPARM:
+ printf_filtered ("an argument in register %s", REGISTER_NAME (val));
+ break;
+
+ case LOC_REGPARM_ADDR:
+ printf_filtered ("address of an argument in register %s", REGISTER_NAME (val));
+ break;
+
+ case LOC_ARG:
+ printf_filtered ("an argument at offset %ld", val);
+ break;
+
+ case LOC_LOCAL_ARG:
+ printf_filtered ("an argument at frame offset %ld", val);
+ break;
+
+ case LOC_LOCAL:
+ printf_filtered ("a local variable at frame offset %ld", val);
+ break;
+
+ case LOC_REF_ARG:
+ printf_filtered ("a reference argument at offset %ld", val);
+ break;
+
+ case LOC_BASEREG:
+ printf_filtered ("a variable at offset %ld from register %s",
+ val, REGISTER_NAME (basereg));
+ break;
+
+ case LOC_BASEREG_ARG:
+ printf_filtered ("an argument at offset %ld from register %s",
+ val, REGISTER_NAME (basereg));
+ break;
+
+ case LOC_TYPEDEF:
+ printf_filtered ("a typedef");
+ break;
+
+ case LOC_BLOCK:
+ printf_filtered ("a function at address ");
+#ifdef GDB_TARGET_MASK_DISAS_PC
+ print_address_numeric
+ (load_addr = GDB_TARGET_MASK_DISAS_PC (BLOCK_START (SYMBOL_BLOCK_VALUE (sym))),
+ 1, gdb_stdout);
+#else
+ print_address_numeric (load_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)),
+ 1, gdb_stdout);
+#endif
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
+ break;
+
+ case LOC_UNRESOLVED:
+ {
+ struct minimal_symbol *msym;
+
+ msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, NULL);
+ if (msym == NULL)
+ printf_filtered ("unresolved");
+ else
+ {
+ section = SYMBOL_BFD_SECTION (msym);
+ printf_filtered ("static storage at address ");
+ print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (msym),
+ 1, gdb_stdout);
+ if (section_is_overlay (section))
+ {
+ load_addr = overlay_unmapped_address (load_addr, section);
+ printf_filtered (",\n -- loaded at ");
+ print_address_numeric (load_addr, 1, gdb_stdout);
+ printf_filtered (" in overlay section %s", section->name);
+ }
+ }
+ }
+ break;
+
+ case LOC_THREAD_LOCAL_STATIC:
+ printf_filtered (
+ "a thread-local variable at offset %ld from the thread base register %s",
+ val, REGISTER_NAME (basereg));
+ break;
+
+ case LOC_OPTIMIZED_OUT:
+ printf_filtered ("optimized out");
+ break;
+
+ default:
+ printf_filtered ("of unknown (botched) type");
+ break;
+ }
+ printf_filtered (".\n");
+}
+
+void
+x_command (char *exp, int from_tty)
+{
+ struct expression *expr;
+ struct format_data fmt;
+ struct cleanup *old_chain;
+ struct value *val;
+
+ fmt.format = last_format;
+ fmt.size = last_size;
+ fmt.count = 1;
+
+ if (exp && *exp == '/')
+ {
+ exp++;
+ fmt = decode_format (&exp, last_format, last_size);
+ }
+
+ /* If we have an expression, evaluate it and use it as the address. */
+
+ if (exp != 0 && *exp != 0)
+ {
+ expr = parse_expression (exp);
+ /* Cause expression not to be there any more
+ if this command is repeated with Newline.
+ But don't clobber a user-defined command's definition. */
+ if (from_tty)
+ *exp = 0;
+ old_chain = make_cleanup (free_current_contents, &expr);
+ val = evaluate_expression (expr);
+ if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_REF)
+ val = value_ind (val);
+ /* In rvalue contexts, such as this, functions are coerced into
+ pointers to functions. This makes "x/i main" work. */
+ if (/* last_format == 'i' && */
+ TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC
+ && VALUE_LVAL (val) == lval_memory)
+ next_address = VALUE_ADDRESS (val);
+ else
+ next_address = value_as_address (val);
+ if (VALUE_BFD_SECTION (val))
+ next_section = VALUE_BFD_SECTION (val);
+ do_cleanups (old_chain);
+ }
+
+ do_examine (fmt, next_address, next_section);
+
+ /* If the examine succeeds, we remember its size and format for next time. */
+ last_size = fmt.size;
+ last_format = fmt.format;
+
+ /* Set a couple of internal variables if appropriate. */
+ if (last_examine_value)
+ {
+ /* Make last address examined available to the user as $_. Use
+ the correct pointer type. */
+ struct type *pointer_type
+ = lookup_pointer_type (VALUE_TYPE (last_examine_value));
+ set_internalvar (lookup_internalvar ("_"),
+ value_from_pointer (pointer_type,
+ last_examine_address));
+
+ /* Make contents of last address examined available to the user as $__. */
+ /* If the last value has not been fetched from memory then don't
+ fetch it now - instead mark it by voiding the $__ variable. */
+ if (VALUE_LAZY (last_examine_value))
+ set_internalvar (lookup_internalvar ("__"),
+ allocate_value (builtin_type_void));
+ else
+ set_internalvar (lookup_internalvar ("__"), last_examine_value);
+ }
+}
+
+
+/* Add an expression to the auto-display chain.
+ Specify the expression. */
+
+static void
+display_command (char *exp, int from_tty)
+{
+ struct format_data fmt;
+ register struct expression *expr;
+ register struct display *new;
+ int display_it = 1;
+
+#if defined(TUI)
+ if (tui_version && *exp == '$')
+ display_it = (tui_set_layout (exp) == TUI_FAILURE);
+#endif
+
+ if (display_it)
+ {
+ if (exp == 0)
+ {
+ do_displays ();
+ return;
+ }
+
+ if (*exp == '/')
+ {
+ exp++;
+ fmt = decode_format (&exp, 0, 0);
+ if (fmt.size && fmt.format == 0)
+ fmt.format = 'x';
+ if (fmt.format == 'i' || fmt.format == 's')
+ fmt.size = 'b';
+ }
+ else
+ {
+ fmt.format = 0;
+ fmt.size = 0;
+ fmt.count = 0;
+ }
+
+ innermost_block = 0;
+ expr = parse_expression (exp);
+
+ new = (struct display *) xmalloc (sizeof (struct display));
+
+ new->exp = expr;
+ new->block = innermost_block;
+ new->next = display_chain;
+ new->number = ++display_number;
+ new->format = fmt;
+ new->enabled_p = 1;
+ display_chain = new;
+
+ if (from_tty && target_has_execution)
+ do_one_display (new);
+
+ dont_repeat ();
+ }
+}
+
+static void
+free_display (struct display *d)
+{
+ xfree (d->exp);
+ xfree (d);
+}
+
+/* Clear out the display_chain.
+ Done when new symtabs are loaded, since this invalidates
+ the types stored in many expressions. */
+
+void
+clear_displays (void)
+{
+ register struct display *d;
+
+ while ((d = display_chain) != NULL)
+ {
+ xfree (d->exp);
+ display_chain = d->next;
+ xfree (d);
+ }
+}
+
+/* Delete the auto-display number NUM. */
+
+static void
+delete_display (int num)
+{
+ register struct display *d1, *d;
+
+ if (!display_chain)
+ error ("No display number %d.", num);
+
+ if (display_chain->number == num)
+ {
+ d1 = display_chain;
+ display_chain = d1->next;
+ free_display (d1);
+ }
+ else
+ for (d = display_chain;; d = d->next)
+ {
+ if (d->next == 0)
+ error ("No display number %d.", num);
+ if (d->next->number == num)
+ {
+ d1 = d->next;
+ d->next = d1->next;
+ free_display (d1);
+ break;
+ }
+ }
+}
+
+/* Delete some values from the auto-display chain.
+ Specify the element numbers. */
+
+static void
+undisplay_command (char *args, int from_tty)
+{
+ register char *p = args;
+ register char *p1;
+ register int num;
+
+ if (args == 0)
+ {
+ if (query ("Delete all auto-display expressions? "))
+ clear_displays ();
+ dont_repeat ();
+ return;
+ }
+
+ while (*p)
+ {
+ p1 = p;
+ while (*p1 >= '0' && *p1 <= '9')
+ p1++;
+ if (*p1 && *p1 != ' ' && *p1 != '\t')
+ error ("Arguments must be display numbers.");
+
+ num = atoi (p);
+
+ delete_display (num);
+
+ p = p1;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ }
+ dont_repeat ();
+}
+
+/* Display a single auto-display.
+ Do nothing if the display cannot be printed in the current context,
+ or if the display is disabled. */
+
+static void
+do_one_display (struct display *d)
+{
+ int within_current_scope;
+
+ if (d->enabled_p == 0)
+ return;
+
+ if (d->block)
+ within_current_scope = contained_in (get_selected_block (0), d->block);
+ else
+ within_current_scope = 1;
+ if (!within_current_scope)
+ return;
+
+ current_display_number = d->number;
+
+ annotate_display_begin ();
+ printf_filtered ("%d", d->number);
+ annotate_display_number_end ();
+ printf_filtered (": ");
+ if (d->format.size)
+ {
+ CORE_ADDR addr;
+ struct value *val;
+
+ annotate_display_format ();
+
+ printf_filtered ("x/");
+ if (d->format.count != 1)
+ printf_filtered ("%d", d->format.count);
+ printf_filtered ("%c", d->format.format);
+ if (d->format.format != 'i' && d->format.format != 's')
+ printf_filtered ("%c", d->format.size);
+ printf_filtered (" ");
+
+ annotate_display_expression ();
+
+ print_expression (d->exp, gdb_stdout);
+ annotate_display_expression_end ();
+
+ if (d->format.count != 1)
+ printf_filtered ("\n");
+ else
+ printf_filtered (" ");
+
+ val = evaluate_expression (d->exp);
+ addr = value_as_address (val);
+ if (d->format.format == 'i')
+ addr = ADDR_BITS_REMOVE (addr);
+
+ annotate_display_value ();
+
+ do_examine (d->format, addr, VALUE_BFD_SECTION (val));
+ }
+ else
+ {
+ annotate_display_format ();
+
+ if (d->format.format)
+ printf_filtered ("/%c ", d->format.format);
+
+ annotate_display_expression ();
+
+ print_expression (d->exp, gdb_stdout);
+ annotate_display_expression_end ();
+
+ printf_filtered (" = ");
+
+ annotate_display_expression ();
+
+ print_formatted (evaluate_expression (d->exp),
+ d->format.format, d->format.size, gdb_stdout);
+ printf_filtered ("\n");
+ }
+
+ annotate_display_end ();
+
+ gdb_flush (gdb_stdout);
+ current_display_number = -1;
+}
+
+/* Display all of the values on the auto-display chain which can be
+ evaluated in the current scope. */
+
+void
+do_displays (void)
+{
+ register struct display *d;
+
+ for (d = display_chain; d; d = d->next)
+ do_one_display (d);
+}
+
+/* Delete the auto-display which we were in the process of displaying.
+ This is done when there is an error or a signal. */
+
+void
+disable_display (int num)
+{
+ register struct display *d;
+
+ for (d = display_chain; d; d = d->next)
+ if (d->number == num)
+ {
+ d->enabled_p = 0;
+ return;
+ }
+ printf_unfiltered ("No display number %d.\n", num);
+}
+
+void
+disable_current_display (void)
+{
+ if (current_display_number >= 0)
+ {
+ disable_display (current_display_number);
+ fprintf_unfiltered (gdb_stderr, "Disabling display %d to avoid infinite recursion.\n",
+ current_display_number);
+ }
+ current_display_number = -1;
+}
+
+static void
+display_info (char *ignore, int from_tty)
+{
+ register struct display *d;
+
+ if (!display_chain)
+ printf_unfiltered ("There are no auto-display expressions now.\n");
+ else
+ printf_filtered ("Auto-display expressions now in effect:\n\
+Num Enb Expression\n");
+
+ for (d = display_chain; d; d = d->next)
+ {
+ printf_filtered ("%d: %c ", d->number, "ny"[(int) d->enabled_p]);
+ if (d->format.size)
+ printf_filtered ("/%d%c%c ", d->format.count, d->format.size,
+ d->format.format);
+ else if (d->format.format)
+ printf_filtered ("/%c ", d->format.format);
+ print_expression (d->exp, gdb_stdout);
+ if (d->block && !contained_in (get_selected_block (0), d->block))
+ printf_filtered (" (cannot be evaluated in the current context)");
+ printf_filtered ("\n");
+ gdb_flush (gdb_stdout);
+ }
+}
+
+static void
+enable_display (char *args, int from_tty)
+{
+ register char *p = args;
+ register char *p1;
+ register int num;
+ register struct display *d;
+
+ if (p == 0)
+ {
+ for (d = display_chain; d; d = d->next)
+ d->enabled_p = 1;
+ }
+ else
+ while (*p)
+ {
+ p1 = p;
+ while (*p1 >= '0' && *p1 <= '9')
+ p1++;
+ if (*p1 && *p1 != ' ' && *p1 != '\t')
+ error ("Arguments must be display numbers.");
+
+ num = atoi (p);
+
+ for (d = display_chain; d; d = d->next)
+ if (d->number == num)
+ {
+ d->enabled_p = 1;
+ goto win;
+ }
+ printf_unfiltered ("No display number %d.\n", num);
+ win:
+ p = p1;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ }
+}
+
+/* ARGSUSED */
+static void
+disable_display_command (char *args, int from_tty)
+{
+ register char *p = args;
+ register char *p1;
+ register struct display *d;
+
+ if (p == 0)
+ {
+ for (d = display_chain; d; d = d->next)
+ d->enabled_p = 0;
+ }
+ else
+ while (*p)
+ {
+ p1 = p;
+ while (*p1 >= '0' && *p1 <= '9')
+ p1++;
+ if (*p1 && *p1 != ' ' && *p1 != '\t')
+ error ("Arguments must be display numbers.");
+
+ disable_display (atoi (p));
+
+ p = p1;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ }
+}
+
+
+/* Print the value in stack frame FRAME of a variable
+ specified by a struct symbol. */
+
+void
+print_variable_value (struct symbol *var, struct frame_info *frame,
+ struct ui_file *stream)
+{
+ struct value *val = read_var_value (var, frame);
+
+ value_print (val, stream, 0, Val_pretty_default);
+}
+
+/* Print the arguments of a stack frame, given the function FUNC
+ running in that frame (as a symbol), the info on the frame,
+ and the number of args according to the stack frame (or -1 if unknown). */
+
+/* References here and elsewhere to "number of args according to the
+ stack frame" appear in all cases to refer to "number of ints of args
+ according to the stack frame". At least for VAX, i386, isi. */
+
+void
+print_frame_args (struct symbol *func, struct frame_info *fi, int num,
+ struct ui_file *stream)
+{
+ struct block *b = NULL;
+ int first = 1;
+ register int i;
+ register struct symbol *sym;
+ struct value *val;
+ /* Offset of next stack argument beyond the one we have seen that is
+ at the highest offset.
+ -1 if we haven't come to a stack argument yet. */
+ long highest_offset = -1;
+ int arg_size;
+ /* Number of ints of arguments that we have printed so far. */
+ int args_printed = 0;
+ struct cleanup *old_chain, *list_chain;
+ struct ui_stream *stb;
+
+ stb = ui_out_stream_new (uiout);
+ old_chain = make_cleanup_ui_out_stream_delete (stb);
+
+ if (func)
+ {
+ b = SYMBOL_BLOCK_VALUE (func);
+ ALL_BLOCK_SYMBOLS (b, i, sym)
+ {
+ QUIT;
+
+ /* Keep track of the highest stack argument offset seen, and
+ skip over any kinds of symbols we don't care about. */
+
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_ARG:
+ case LOC_REF_ARG:
+ {
+ long current_offset = SYMBOL_VALUE (sym);
+ arg_size = TYPE_LENGTH (SYMBOL_TYPE (sym));
+
+ /* Compute address of next argument by adding the size of
+ this argument and rounding to an int boundary. */
+ current_offset =
+ ((current_offset + arg_size + sizeof (int) - 1)
+ & ~(sizeof (int) - 1));
+
+ /* If this is the highest offset seen yet, set highest_offset. */
+ if (highest_offset == -1
+ || (current_offset > highest_offset))
+ highest_offset = current_offset;
+
+ /* Add the number of ints we're about to print to args_printed. */
+ args_printed += (arg_size + sizeof (int) - 1) / sizeof (int);
+ }
+
+ /* We care about types of symbols, but don't need to keep track of
+ stack offsets in them. */
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_LOCAL_ARG:
+ case LOC_BASEREG_ARG:
+ break;
+
+ /* Other types of symbols we just skip over. */
+ default:
+ continue;
+ }
+
+ /* We have to look up the symbol because arguments can have
+ two entries (one a parameter, one a local) and the one we
+ want is the local, which lookup_symbol will find for us.
+ This includes gcc1 (not gcc2) on the sparc when passing a
+ small structure and gcc2 when the argument type is float
+ and it is passed as a double and converted to float by
+ the prologue (in the latter case the type of the LOC_ARG
+ symbol is double and the type of the LOC_LOCAL symbol is
+ float). */
+ /* But if the parameter name is null, don't try it.
+ Null parameter names occur on the RS/6000, for traceback tables.
+ FIXME, should we even print them? */
+
+ if (*SYMBOL_NAME (sym))
+ {
+ struct symbol *nsym;
+ nsym = lookup_symbol
+ (SYMBOL_NAME (sym),
+ b, VAR_NAMESPACE, (int *) NULL, (struct symtab **) NULL);
+ if (SYMBOL_CLASS (nsym) == LOC_REGISTER)
+ {
+ /* There is a LOC_ARG/LOC_REGISTER pair. This means that
+ it was passed on the stack and loaded into a register,
+ or passed in a register and stored in a stack slot.
+ GDB 3.x used the LOC_ARG; GDB 4.0-4.11 used the LOC_REGISTER.
+
+ Reasons for using the LOC_ARG:
+ (1) because find_saved_registers may be slow for remote
+ debugging,
+ (2) because registers are often re-used and stack slots
+ rarely (never?) are. Therefore using the stack slot is
+ much less likely to print garbage.
+
+ Reasons why we might want to use the LOC_REGISTER:
+ (1) So that the backtrace prints the same value as
+ "print foo". I see no compelling reason why this needs
+ to be the case; having the backtrace print the value which
+ was passed in, and "print foo" print the value as modified
+ within the called function, makes perfect sense to me.
+
+ Additional note: It might be nice if "info args" displayed
+ both values.
+ One more note: There is a case with sparc structure passing
+ where we need to use the LOC_REGISTER, but this is dealt with
+ by creating a single LOC_REGPARM in symbol reading. */
+
+ /* Leave sym (the LOC_ARG) alone. */
+ ;
+ }
+ else
+ sym = nsym;
+ }
+
+ /* Print the current arg. */
+ if (!first)
+ ui_out_text (uiout, ", ");
+ ui_out_wrap_hint (uiout, " ");
+
+ annotate_arg_begin ();
+
+ list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+ fprintf_symbol_filtered (stb->stream, SYMBOL_SOURCE_NAME (sym),
+ SYMBOL_LANGUAGE (sym), DMGL_PARAMS | DMGL_ANSI);
+ ui_out_field_stream (uiout, "name", stb);
+ annotate_arg_name_end ();
+ ui_out_text (uiout, "=");
+
+ /* Avoid value_print because it will deref ref parameters. We just
+ want to print their addresses. Print ??? for args whose address
+ we do not know. We pass 2 as "recurse" to val_print because our
+ standard indentation here is 4 spaces, and val_print indents
+ 2 for each recurse. */
+ val = read_var_value (sym, fi);
+
+ annotate_arg_value (val == NULL ? NULL : VALUE_TYPE (val));
+
+ if (val)
+ {
+ val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), 0,
+ VALUE_ADDRESS (val),
+ stb->stream, 0, 0, 2, Val_no_prettyprint);
+ ui_out_field_stream (uiout, "value", stb);
+ }
+ else
+ ui_out_text (uiout, "???");
+
+ /* Invoke ui_out_tuple_end. */
+ do_cleanups (list_chain);
+
+ annotate_arg_end ();
+
+ first = 0;
+ }
+ }
+
+ /* Don't print nameless args in situations where we don't know
+ enough about the stack to find them. */
+ if (num != -1)
+ {
+ long start;
+
+ if (highest_offset == -1)
+ start = FRAME_ARGS_SKIP;
+ else
+ start = highest_offset;
+
+ print_frame_nameless_args (fi, start, num - args_printed,
+ first, stream);
+ }
+ do_cleanups (old_chain);
+}
+
+/* Print nameless args on STREAM.
+ FI is the frameinfo for this frame, START is the offset
+ of the first nameless arg, and NUM is the number of nameless args to
+ print. FIRST is nonzero if this is the first argument (not just
+ the first nameless arg). */
+
+static void
+print_frame_nameless_args (struct frame_info *fi, long start, int num,
+ int first, struct ui_file *stream)
+{
+ int i;
+ CORE_ADDR argsaddr;
+ long arg_value;
+
+ for (i = 0; i < num; i++)
+ {
+ QUIT;
+#ifdef NAMELESS_ARG_VALUE
+ NAMELESS_ARG_VALUE (fi, start, &arg_value);
+#else
+ argsaddr = FRAME_ARGS_ADDRESS (fi);
+ if (!argsaddr)
+ return;
+
+ arg_value = read_memory_integer (argsaddr + start, sizeof (int));
+#endif
+
+ if (!first)
+ fprintf_filtered (stream, ", ");
+
+#ifdef PRINT_NAMELESS_INTEGER
+ PRINT_NAMELESS_INTEGER (stream, arg_value);
+#else
+#ifdef PRINT_TYPELESS_INTEGER
+ PRINT_TYPELESS_INTEGER (stream, builtin_type_int, (LONGEST) arg_value);
+#else
+ fprintf_filtered (stream, "%ld", arg_value);
+#endif /* PRINT_TYPELESS_INTEGER */
+#endif /* PRINT_NAMELESS_INTEGER */
+ first = 0;
+ start += sizeof (int);
+ }
+}
+
+/* ARGSUSED */
+static void
+printf_command (char *arg, int from_tty)
+{
+ register char *f = NULL;
+ register char *s = arg;
+ char *string = NULL;
+ struct value **val_args;
+ char *substrings;
+ char *current_substring;
+ int nargs = 0;
+ int allocated_args = 20;
+ struct cleanup *old_cleanups;
+
+ val_args = (struct value **) xmalloc (allocated_args
+ * sizeof (struct value *));
+ old_cleanups = make_cleanup (free_current_contents, &val_args);
+
+ if (s == 0)
+ error_no_arg ("format-control string and values to print");
+
+ /* Skip white space before format string */
+ while (*s == ' ' || *s == '\t')
+ s++;
+
+ /* A format string should follow, enveloped in double quotes */
+ if (*s++ != '"')
+ error ("Bad format string, missing '\"'.");
+
+ /* Parse the format-control string and copy it into the string STRING,
+ processing some kinds of escape sequence. */
+
+ f = string = (char *) alloca (strlen (s) + 1);
+
+ while (*s != '"')
+ {
+ int c = *s++;
+ switch (c)
+ {
+ case '\0':
+ error ("Bad format string, non-terminated '\"'.");
+
+ case '\\':
+ switch (c = *s++)
+ {
+ case '\\':
+ *f++ = '\\';
+ break;
+ case 'a':
+ *f++ = '\a';
+ break;
+ case 'b':
+ *f++ = '\b';
+ break;
+ case 'f':
+ *f++ = '\f';
+ break;
+ case 'n':
+ *f++ = '\n';
+ break;
+ case 'r':
+ *f++ = '\r';
+ break;
+ case 't':
+ *f++ = '\t';
+ break;
+ case 'v':
+ *f++ = '\v';
+ break;
+ case '"':
+ *f++ = '"';
+ break;
+ default:
+ /* ??? TODO: handle other escape sequences */
+ error ("Unrecognized escape character \\%c in format string.",
+ c);
+ }
+ break;
+
+ default:
+ *f++ = c;
+ }
+ }
+
+ /* Skip over " and following space and comma. */
+ s++;
+ *f++ = '\0';
+ while (*s == ' ' || *s == '\t')
+ s++;
+
+ if (*s != ',' && *s != 0)
+ error ("Invalid argument syntax");
+
+ if (*s == ',')
+ s++;
+ while (*s == ' ' || *s == '\t')
+ s++;
+
+ /* Need extra space for the '\0's. Doubling the size is sufficient. */
+ substrings = alloca (strlen (string) * 2);
+ current_substring = substrings;
+
+ {
+ /* Now scan the string for %-specs and see what kinds of args they want.
+ argclass[I] classifies the %-specs so we can give printf_filtered
+ something of the right size. */
+
+ enum argclass
+ {
+ no_arg, int_arg, string_arg, double_arg, long_long_arg
+ };
+ enum argclass *argclass;
+ enum argclass this_argclass;
+ char *last_arg;
+ int nargs_wanted;
+ int lcount;
+ int i;
+
+ argclass = (enum argclass *) alloca (strlen (s) * sizeof *argclass);
+ nargs_wanted = 0;
+ f = string;
+ last_arg = string;
+ while (*f)
+ if (*f++ == '%')
+ {
+ lcount = 0;
+ while (strchr ("0123456789.hlL-+ #", *f))
+ {
+ if (*f == 'l' || *f == 'L')
+ lcount++;
+ f++;
+ }
+ switch (*f)
+ {
+ case 's':
+ this_argclass = string_arg;
+ break;
+
+ case 'e':
+ case 'f':
+ case 'g':
+ this_argclass = double_arg;
+ break;
+
+ case '*':
+ error ("`*' not supported for precision or width in printf");
+
+ case 'n':
+ error ("Format specifier `n' not supported in printf");
+
+ case '%':
+ this_argclass = no_arg;
+ break;
+
+ default:
+ if (lcount > 1)
+ this_argclass = long_long_arg;
+ else
+ this_argclass = int_arg;
+ break;
+ }
+ f++;
+ if (this_argclass != no_arg)
+ {
+ strncpy (current_substring, last_arg, f - last_arg);
+ current_substring += f - last_arg;
+ *current_substring++ = '\0';
+ last_arg = f;
+ argclass[nargs_wanted++] = this_argclass;
+ }
+ }
+
+ /* Now, parse all arguments and evaluate them.
+ Store the VALUEs in VAL_ARGS. */
+
+ while (*s != '\0')
+ {
+ char *s1;
+ if (nargs == allocated_args)
+ val_args = (struct value **) xrealloc ((char *) val_args,
+ (allocated_args *= 2)
+ * sizeof (struct value *));
+ s1 = s;
+ val_args[nargs] = parse_to_comma_and_eval (&s1);
+
+ /* If format string wants a float, unchecked-convert the value to
+ floating point of the same size */
+
+ if (argclass[nargs] == double_arg)
+ {
+ struct type *type = VALUE_TYPE (val_args[nargs]);
+ if (TYPE_LENGTH (type) == sizeof (float))
+ VALUE_TYPE (val_args[nargs]) = builtin_type_float;
+ if (TYPE_LENGTH (type) == sizeof (double))
+ VALUE_TYPE (val_args[nargs]) = builtin_type_double;
+ }
+ nargs++;
+ s = s1;
+ if (*s == ',')
+ s++;
+ }
+
+ if (nargs != nargs_wanted)
+ error ("Wrong number of arguments for specified format-string");
+
+ /* Now actually print them. */
+ current_substring = substrings;
+ for (i = 0; i < nargs; i++)
+ {
+ switch (argclass[i])
+ {
+ case string_arg:
+ {
+ char *str;
+ CORE_ADDR tem;
+ int j;
+ tem = value_as_address (val_args[i]);
+
+ /* This is a %s argument. Find the length of the string. */
+ for (j = 0;; j++)
+ {
+ char c;
+ QUIT;
+ read_memory (tem + j, &c, 1);
+ if (c == 0)
+ break;
+ }
+
+ /* Copy the string contents into a string inside GDB. */
+ str = (char *) alloca (j + 1);
+ if (j != 0)
+ read_memory (tem, str, j);
+ str[j] = 0;
+
+ printf_filtered (current_substring, str);
+ }
+ break;
+ case double_arg:
+ {
+ double val = value_as_double (val_args[i]);
+ printf_filtered (current_substring, val);
+ break;
+ }
+ case long_long_arg:
+#if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG)
+ {
+ long long val = value_as_long (val_args[i]);
+ printf_filtered (current_substring, val);
+ break;
+ }
+#else
+ error ("long long not supported in printf");
+#endif
+ case int_arg:
+ {
+ /* FIXME: there should be separate int_arg and long_arg. */
+ long val = value_as_long (val_args[i]);
+ printf_filtered (current_substring, val);
+ break;
+ }
+ default: /* purecov: deadcode */
+ error ("internal error in printf_command"); /* purecov: deadcode */
+ }
+ /* Skip to the next substring. */
+ current_substring += strlen (current_substring) + 1;
+ }
+ /* Print the portion of the format string after the last argument. */
+ printf_filtered (last_arg);
+ }
+ do_cleanups (old_cleanups);
+}
+
+/* Dump a specified section of assembly code. With no command line
+ arguments, this command will dump the assembly code for the
+ function surrounding the pc value in the selected frame. With one
+ argument, it will dump the assembly code surrounding that pc value.
+ Two arguments are interpeted as bounds within which to dump
+ assembly. */
+
+/* ARGSUSED */
+static void
+disassemble_command (char *arg, int from_tty)
+{
+ CORE_ADDR low, high;
+ char *name;
+ CORE_ADDR pc, pc_masked;
+ char *space_index;
+#if 0
+ asection *section;
+#endif
+
+ name = NULL;
+ if (!arg)
+ {
+ if (!selected_frame)
+ error ("No frame selected.\n");
+
+ pc = get_frame_pc (selected_frame);
+ if (find_pc_partial_function (pc, &name, &low, &high) == 0)
+ error ("No function contains program counter for selected frame.\n");
+#if defined(TUI)
+ else if (tui_version)
+ low = tuiGetLowDisassemblyAddress (low, pc);
+#endif
+ low += FUNCTION_START_OFFSET;
+ }
+ else if (!(space_index = (char *) strchr (arg, ' ')))
+ {
+ /* One argument. */
+ pc = parse_and_eval_address (arg);
+ if (find_pc_partial_function (pc, &name, &low, &high) == 0)
+ error ("No function contains specified address.\n");
+#if defined(TUI)
+ else if (tui_version)
+ low = tuiGetLowDisassemblyAddress (low, pc);
+#endif
+ low += FUNCTION_START_OFFSET;
+ }
+ else
+ {
+ /* Two arguments. */
+ *space_index = '\0';
+ low = parse_and_eval_address (arg);
+ high = parse_and_eval_address (space_index + 1);
+ }
+
+#if defined(TUI)
+ if (!tui_is_window_visible (DISASSEM_WIN))
+#endif
+ {
+ printf_filtered ("Dump of assembler code ");
+ if (name != NULL)
+ {
+ printf_filtered ("for function %s:\n", name);
+ }
+ else
+ {
+ printf_filtered ("from ");
+ print_address_numeric (low, 1, gdb_stdout);
+ printf_filtered (" to ");
+ print_address_numeric (high, 1, gdb_stdout);
+ printf_filtered (":\n");
+ }
+
+ /* Dump the specified range. */
+ pc = low;
+
+#ifdef GDB_TARGET_MASK_DISAS_PC
+ pc_masked = GDB_TARGET_MASK_DISAS_PC (pc);
+#else
+ pc_masked = pc;
+#endif
+
+ while (pc_masked < high)
+ {
+ QUIT;
+ print_address (pc_masked, gdb_stdout);
+ printf_filtered (":\t");
+ /* We often wrap here if there are long symbolic names. */
+ wrap_here (" ");
+ pc += print_insn (pc, gdb_stdout);
+ printf_filtered ("\n");
+
+#ifdef GDB_TARGET_MASK_DISAS_PC
+ pc_masked = GDB_TARGET_MASK_DISAS_PC (pc);
+#else
+ pc_masked = pc;
+#endif
+ }
+ printf_filtered ("End of assembler dump.\n");
+ gdb_flush (gdb_stdout);
+ }
+#if defined(TUI)
+ else
+ {
+ tui_show_assembly (low);
+ }
+#endif
+}
+
+/* Print the instruction at address MEMADDR in debugged memory,
+ on STREAM. Returns length of the instruction, in bytes. */
+
+static int
+print_insn (CORE_ADDR memaddr, struct ui_file *stream)
+{
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ TARGET_PRINT_INSN_INFO->endian = BFD_ENDIAN_BIG;
+ else
+ TARGET_PRINT_INSN_INFO->endian = BFD_ENDIAN_LITTLE;
+
+ if (TARGET_ARCHITECTURE != NULL)
+ TARGET_PRINT_INSN_INFO->mach = TARGET_ARCHITECTURE->mach;
+ /* else: should set .mach=0 but some disassemblers don't grok this */
+
+ TARGET_PRINT_INSN_INFO->stream = stream;
+
+ return TARGET_PRINT_INSN (memaddr, TARGET_PRINT_INSN_INFO);
+}
+
+
+void
+_initialize_printcmd (void)
+{
+ struct cmd_list_element *c;
+
+ current_display_number = -1;
+
+ add_info ("address", address_info,
+ "Describe where symbol SYM is stored.");
+
+ add_info ("symbol", sym_info,
+ "Describe what symbol is at location ADDR.\n\
+Only for symbols with fixed locations (global or static scope).");
+
+ add_com ("x", class_vars, x_command,
+ concat ("Examine memory: x/FMT ADDRESS.\n\
+ADDRESS is an expression for the memory address to examine.\n\
+FMT is a repeat count followed by a format letter and a size letter.\n\
+Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),\n\
+ t(binary), f(float), a(address), i(instruction), c(char) and s(string).\n",
+ "Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).\n\
+The specified number of objects of the specified size are printed\n\
+according to the format.\n\n\
+Defaults for format and size letters are those previously used.\n\
+Default count is 1. Default address is following last thing printed\n\
+with this command or \"print\".", NULL));
+
+ c = add_com ("disassemble", class_vars, disassemble_command,
+ "Disassemble a specified section of memory.\n\
+Default is the function surrounding the pc of the selected frame.\n\
+With a single argument, the function surrounding that address is dumped.\n\
+Two arguments are taken as a range of memory to dump.");
+ set_cmd_completer (c, location_completer);
+ if (xdb_commands)
+ add_com_alias ("va", "disassemble", class_xdb, 0);
+
+#if 0
+ add_com ("whereis", class_vars, whereis_command,
+ "Print line number and file of definition of variable.");
+#endif
+
+ add_info ("display", display_info,
+ "Expressions to display when program stops, with code numbers.");
+
+ add_cmd ("undisplay", class_vars, undisplay_command,
+ "Cancel some expressions to be displayed when program stops.\n\
+Arguments are the code numbers of the expressions to stop displaying.\n\
+No argument means cancel all automatic-display expressions.\n\
+\"delete display\" has the same effect as this command.\n\
+Do \"info display\" to see current list of code numbers.",
+ &cmdlist);
+
+ add_com ("display", class_vars, display_command,
+ "Print value of expression EXP each time the program stops.\n\
+/FMT may be used before EXP as in the \"print\" command.\n\
+/FMT \"i\" or \"s\" or including a size-letter is allowed,\n\
+as in the \"x\" command, and then EXP is used to get the address to examine\n\
+and examining is done as in the \"x\" command.\n\n\
+With no argument, display all currently requested auto-display expressions.\n\
+Use \"undisplay\" to cancel display requests previously made."
+ );
+
+ add_cmd ("display", class_vars, enable_display,
+ "Enable some expressions to be displayed when program stops.\n\
+Arguments are the code numbers of the expressions to resume displaying.\n\
+No argument means enable all automatic-display expressions.\n\
+Do \"info display\" to see current list of code numbers.", &enablelist);
+
+ add_cmd ("display", class_vars, disable_display_command,
+ "Disable some expressions to be displayed when program stops.\n\
+Arguments are the code numbers of the expressions to stop displaying.\n\
+No argument means disable all automatic-display expressions.\n\
+Do \"info display\" to see current list of code numbers.", &disablelist);
+
+ add_cmd ("display", class_vars, undisplay_command,
+ "Cancel some expressions to be displayed when program stops.\n\
+Arguments are the code numbers of the expressions to stop displaying.\n\
+No argument means cancel all automatic-display expressions.\n\
+Do \"info display\" to see current list of code numbers.", &deletelist);
+
+ add_com ("printf", class_vars, printf_command,
+ "printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\
+This is useful for formatted output in user-defined commands.");
+
+ add_com ("output", class_vars, output_command,
+ "Like \"print\" but don't put in value history and don't print newline.\n\
+This is useful in user-defined commands.");
+
+ add_prefix_cmd ("set", class_vars, set_command,
+ concat ("Evaluate expression EXP and assign result to variable VAR, using assignment\n\
+syntax appropriate for the current language (VAR = EXP or VAR := EXP for\n\
+example). VAR may be a debugger \"convenience\" variable (names starting\n\
+with $), a register (a few standard names starting with $), or an actual\n\
+variable in the program being debugged. EXP is any valid expression.\n",
+ "Use \"set variable\" for variables with names identical to set subcommands.\n\
+\nWith a subcommand, this command modifies parts of the gdb environment.\n\
+You can see these environment settings with the \"show\" command.", NULL),
+ &setlist, "set ", 1, &cmdlist);
+ if (dbx_commands)
+ add_com ("assign", class_vars, set_command, concat ("Evaluate expression \
+EXP and assign result to variable VAR, using assignment\n\
+syntax appropriate for the current language (VAR = EXP or VAR := EXP for\n\
+example). VAR may be a debugger \"convenience\" variable (names starting\n\
+with $), a register (a few standard names starting with $), or an actual\n\
+variable in the program being debugged. EXP is any valid expression.\n",
+ "Use \"set variable\" for variables with names identical to set subcommands.\n\
+\nWith a subcommand, this command modifies parts of the gdb environment.\n\
+You can see these environment settings with the \"show\" command.", NULL));
+
+ /* "call" is the same as "set", but handy for dbx users to call fns. */
+ c = add_com ("call", class_vars, call_command,
+ "Call a function in the program.\n\
+The argument is the function name and arguments, in the notation of the\n\
+current working language. The result is printed and saved in the value\n\
+history, if it is not void.");
+ set_cmd_completer (c, location_completer);
+
+ add_cmd ("variable", class_vars, set_command,
+ "Evaluate expression EXP and assign result to variable VAR, using assignment\n\
+syntax appropriate for the current language (VAR = EXP or VAR := EXP for\n\
+example). VAR may be a debugger \"convenience\" variable (names starting\n\
+with $), a register (a few standard names starting with $), or an actual\n\
+variable in the program being debugged. EXP is any valid expression.\n\
+This may usually be abbreviated to simply \"set\".",
+ &setlist);
+
+ c = add_com ("print", class_vars, print_command,
+ concat ("Print value of expression EXP.\n\
+Variables accessible are those of the lexical environment of the selected\n\
+stack frame, plus all those whose scope is global or an entire file.\n\
+\n\
+$NUM gets previous value number NUM. $ and $$ are the last two values.\n\
+$$NUM refers to NUM'th value back from the last one.\n\
+Names starting with $ refer to registers (with the values they would have\n",
+ "if the program were to return to the stack frame now selected, restoring\n\
+all registers saved by frames farther in) or else to debugger\n\
+\"convenience\" variables (any such name not a known register).\n\
+Use assignment expressions to give values to convenience variables.\n",
+ "\n\
+{TYPE}ADREXP refers to a datum of data type TYPE, located at address ADREXP.\n\
+@ is a binary operator for treating consecutive data objects\n\
+anywhere in memory as an array. FOO@NUM gives an array whose first\n\
+element is FOO, whose second element is stored in the space following\n\
+where FOO is stored, etc. FOO must be an expression whose value\n\
+resides in memory.\n",
+ "\n\
+EXP may be preceded with /FMT, where FMT is a format letter\n\
+but no count or size letter (see \"x\" command).", NULL));
+ set_cmd_completer (c, location_completer);
+ add_com_alias ("p", "print", class_vars, 1);
+
+ c = add_com ("inspect", class_vars, inspect_command,
+ "Same as \"print\" command, except that if you are running in the epoch\n\
+environment, the value is printed in its own window.");
+ set_cmd_completer (c, location_completer);
+
+ add_show_from_set (
+ add_set_cmd ("max-symbolic-offset", no_class, var_uinteger,
+ (char *) &max_symbolic_offset,
+ "Set the largest offset that will be printed in <symbol+1234> form.",
+ &setprintlist),
+ &showprintlist);
+ add_show_from_set (
+ add_set_cmd ("symbol-filename", no_class, var_boolean,
+ (char *) &print_symbol_filename,
+ "Set printing of source filename and line number with <symbol>.",
+ &setprintlist),
+ &showprintlist);
+
+ /* For examine/instruction a single byte quantity is specified as
+ the data. This avoids problems with value_at_lazy() requiring a
+ valid data type (and rejecting VOID). */
+ examine_i_type = init_type (TYPE_CODE_INT, 1, 0, "examine_i_type", NULL);
+
+ examine_b_type = init_type (TYPE_CODE_INT, 1, 0, "examine_b_type", NULL);
+ examine_h_type = init_type (TYPE_CODE_INT, 2, 0, "examine_h_type", NULL);
+ examine_w_type = init_type (TYPE_CODE_INT, 4, 0, "examine_w_type", NULL);
+ examine_g_type = init_type (TYPE_CODE_INT, 8, 0, "examine_g_type", NULL);
+
+}
diff --git a/gdb/proc-api.c b/gdb/proc-api.c
new file mode 100644
index 00000000000..2d3ca9ffbf2
--- /dev/null
+++ b/gdb/proc-api.c
@@ -0,0 +1,789 @@
+/* Machine independent support for SVR4 /proc (process file system) for GDB.
+ Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+ Written by Michael Snyder at Cygnus Solutions.
+ Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
+
+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. */
+
+/*
+ * Pretty-print trace of api calls to the /proc api
+ * (ioctl or read/write calls).
+ *
+ */
+
+#include "defs.h"
+#include "gdbcmd.h"
+#include "completer.h"
+
+#if defined (NEW_PROC_API)
+#define _STRUCTURED_PROC 1
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/procfs.h>
+#include <sys/proc.h> /* for struct proc */
+#ifdef HAVE_SYS_USER_H
+#include <sys/user.h> /* for struct user */
+#endif
+#include <fcntl.h> /* for O_RDWR etc. */
+#include <sys/wait.h>
+
+#include "proc-utils.h"
+
+/* Much of the information used in the /proc interface, particularly for
+ printing status information, is kept as tables of structures of the
+ following form. These tables can be used to map numeric values to
+ their symbolic names and to a string that describes their specific use. */
+
+struct trans {
+ long value; /* The numeric value */
+ char *name; /* The equivalent symbolic value */
+ char *desc; /* Short description of value */
+};
+
+static int procfs_trace = 0;
+static FILE *procfs_file = NULL;
+static char *procfs_filename = "procfs_trace";
+
+static void
+prepare_to_trace (void)
+{
+ if (procfs_trace) /* if procfs tracing turned on */
+ if (procfs_file == NULL) /* if output file not yet open */
+ if (procfs_filename != NULL) /* if output filename known */
+ procfs_file = fopen (procfs_filename, "a"); /* open output file */
+}
+
+static void
+set_procfs_trace_cmd (char *args, int from_tty, struct cmd_list_element *c)
+{
+#if 0 /* not sure what I might actually need to do here, if anything */
+ if (procfs_file)
+ fflush (procfs_file);
+#endif
+}
+
+static void
+set_procfs_file_cmd (char *args, int from_tty, struct cmd_list_element *c)
+{
+ /* Just changed the filename for procfs tracing.
+ If a file was already open, close it. */
+ if (procfs_file)
+ fclose (procfs_file);
+ procfs_file = NULL;
+}
+
+
+#ifndef NEW_PROC_API
+
+static struct trans ioctl_table[] = {
+#ifdef PIOCACINFO /* irix */
+ { PIOCACINFO, "PIOCACINFO", "get process account info" },
+#endif
+ { PIOCACTION, "PIOCACTION", "get signal action structs" },
+#ifdef PIOCARGUMENTS /* osf */
+ { PIOCARGUMENTS, "PIOCARGUMENTS", "command line args" },
+#endif
+#ifdef PIOCAUXV /* solaris aux vectors */
+ { PIOCAUXV, "PIOCAUXV", "get aux vector" },
+ { PIOCNAUXV, "PIOCNAUXV", "get number of aux vector entries" },
+#endif /* AUXV */
+ { PIOCCFAULT, "PIOCCFAULT", "clear current fault" },
+ { PIOCCRED, "PIOCCRED", "get process credentials" },
+#ifdef PIOCENEVCTRS /* irix event counters */
+ { PIOCENEVCTRS, "PIOCENEVCTRS", "acquire and start event counters" },
+ { PIOCGETEVCTRL, "PIOCGETEVCTRL", "get control info of event counters" },
+ { PIOCGETEVCTRS, "PIOCGETEVCTRS", "dump event counters" },
+ { PIOCGETPREVCTRS, "PIOCGETPREVCTRS", "dump event counters & prusage info" },
+ { PIOCRELEVCTRS, "PIOCRELEVCTRS", "release/stop event counters" },
+ { PIOCSETEVCTRL, "PIOCSETEVCTRL", "set control info of event counters" },
+ { PIOCGETPTIMER, "PIOCGETPTIMER", "get process timers" },
+#endif /* irix event counters */
+ { PIOCGENTRY, "PIOCGENTRY", "get traced syscall entry set" },
+#if defined (PIOCGETPR)
+ { PIOCGETPR, "PIOCGETPR", "read struct proc" },
+#endif
+#if defined (PIOCGETU)
+ { PIOCGETU, "PIOCGETU", "read user area" },
+#endif
+#if defined (PIOCGETUTK) && (defined(KERNEL) || defined(SHOW_UTT)) /* osf */
+ { PIOCGETUTK, "PIOCGETUTK", "get the utask struct" },
+#endif
+ { PIOCGEXIT, "PIOCGEXIT", "get traced syscall exit set" },
+ { PIOCGFAULT, "PIOCGFAULT", "get traced fault set" },
+#ifdef PIOCGFPCR /* osf */
+ { PIOCGFPCR, "PIOCGFPCR", "get FP control register" },
+ { PIOCSFPCR, "PIOCSFPCR", "set FP conrtol register" },
+#endif
+ { PIOCGFPREG, "PIOCGFPREG", "get floating point registers" },
+ { PIOCGHOLD, "PIOCGHOLD", "get held signal set" },
+ { PIOCGREG, "PIOCGREG", "get general registers" },
+ { PIOCGROUPS, "PIOCGROUPS", "get supplementary groups" },
+#ifdef PIOCGSPCACT /* osf */
+ { PIOCGSPCACT, "PIOCGSPCACT", "get special action" },
+ { PIOCSSPCACT, "PIOCSSPCACT", "set special action" },
+#endif
+ { PIOCGTRACE, "PIOCGTRACE", "get traced signal set" },
+#ifdef PIOCGWATCH /* irix watchpoints */
+ { PIOCGWATCH, "PIOCGWATCH", "get watchpoint" },
+ { PIOCSWATCH, "PIOCSWATCH", "set watchpoint" },
+ { PIOCNWATCH, "PIOCNWATCH", "get number of watchpoints" },
+#endif /* irix watchpoints */
+#ifdef PIOCGWIN /* solaris sparc */
+ { PIOCGWIN, "PIOCGWIN", "get gwindows_t" },
+#endif
+#ifdef PIOCGXREG /* solaris sparc extra regs */
+ { PIOCGXREGSIZE, "PIOCXREGSIZE", "get extra register state size" },
+ { PIOCGXREG, "PIOCGXREG", "get extra register state" },
+ { PIOCSXREG, "PIOCSXREG", "set extra register state" },
+#endif /* XREG */
+ { PIOCKILL, "PIOCKILL", "send signal" },
+#ifdef PIOCLDT /* solaris i386 */
+ { PIOCLDT, "PIOCLDT", "get LDT" },
+ { PIOCNLDT, "PIOCNLDT", "get number of LDT entries" },
+#endif
+#ifdef PIOCLSTATUS /* solaris and unixware */
+ { PIOCLSTATUS, "PIOCLSTATUS", "get status of all lwps" },
+ { PIOCLUSAGE, "PIOCLUSAGE", "get resource usage of all lwps" },
+ { PIOCOPENLWP, "PIOCOPENLWP", "get lwp file descriptor" },
+ { PIOCLWPIDS, "PIOCLWPIDS", "get lwp identifiers" },
+#endif /* LWP */
+ { PIOCMAP, "PIOCMAP", "get memory map information" },
+ { PIOCMAXSIG, "PIOCMAXSIG", "get max signal number" },
+ { PIOCNICE, "PIOCNICE", "set nice priority" },
+ { PIOCNMAP, "PIOCNMAP", "get number of memory mappings" },
+ { PIOCOPENM, "PIOCOPENM", "open mapped object for reading" },
+#ifdef PIOCOPENMOBS /* osf */
+ { PIOCOPENMOBS, "PIOCOPENMOBS", "open mapped object" },
+#endif
+#ifdef PIOCOPENPD /* solaris */
+ { PIOCOPENPD, "PIOCOPENPD", "get page data file descriptor" },
+#endif
+ { PIOCPSINFO, "PIOCPSINFO", "get ps(1) information" },
+ { PIOCRESET, "PIOCRESET", "reset process flags" },
+ { PIOCRFORK, "PIOCRFORK", "reset inherit-on-fork flag" },
+ { PIOCRRLC, "PIOCRRLC", "reset run-on-last-close flag" },
+ { PIOCRUN, "PIOCRUN", "make process runnable" },
+#ifdef PIOCSAVECCNTRS /* irix */
+ { PIOCSAVECCNTRS, "PIOCSAVECCNTRS", "parent gets child cntrs" },
+#endif
+ { PIOCSENTRY, "PIOCSENTRY", "set traced syscall entry set" },
+ { PIOCSET, "PIOCSET", "set process flags" },
+ { PIOCSEXIT, "PIOCSEXIT", "set traced syscall exit set" },
+ { PIOCSFAULT, "PIOCSFAULT", "set traced fault set" },
+ { PIOCSFORK, "PIOCSFORK", "set inherit-on-fork flag" },
+ { PIOCSFPREG, "PIOCSFPREG", "set floating point registers" },
+ { PIOCSHOLD, "PIOCSHOLD", "set held signal set" },
+ { PIOCSREG, "PIOCSREG", "set general registers" },
+ { PIOCSRLC, "PIOCSRLC", "set run-on-last-close flag" },
+ { PIOCSSIG, "PIOCSSIG", "set current signal" },
+ { PIOCSTATUS, "PIOCSTATUS", "get process status" },
+ { PIOCSTOP, "PIOCSTOP", "post stop request" },
+ { PIOCSTRACE, "PIOCSTRACE", "set traced signal set" },
+ { PIOCUNKILL, "PIOCUNKILL", "delete a signal" },
+#ifdef PIOCUSAGE /* solaris */
+ { PIOCUSAGE, "PIOCUSAGE", "get resource usage" },
+#endif
+ { PIOCWSTOP, "PIOCWSTOP", "wait for process to stop" },
+
+#ifdef PIOCNTHR /* osf threads */
+ { PIOCNTHR, "PIOCNTHR", "get thread count" },
+ { PIOCRTINH, "PIOCRTINH", "reset inherit-on-thread-creation" },
+ { PIOCSTINH, "PIOCSTINH", "set inherit-on-thread-creation" },
+ { PIOCTLIST, "PIOCTLIST", "get thread ids" },
+ { PIOCXPTH, "PIOCXPTH", "translate port to thread handle" },
+ { PIOCTRUN, "PIOCTRUN", "make thread runnable" },
+ { PIOCTSTATUS, "PIOCTSTATUS", "get thread status" },
+ { PIOCTSTOP, "PIOCTSTOP", "stop a thread" },
+ /* ... TGTRACE TSTRACE TSSIG TKILL TUNKILL TCFAULT TGFAULT TSFAULT
+ TGFPREG TSFPREG TGREG TSREG TACTION TTERM TABRUN TGENTRY TSENTRY
+ TGEXIT TSEXIT TSHOLD ... thread functions */
+#endif /* osf threads */
+ { -1, NULL, NULL }
+};
+
+int
+ioctl_with_trace (int fd, long opcode, void *ptr, char *file, int line)
+{
+ int i = 0;
+ int ret;
+ int arg1;
+
+ prepare_to_trace ();
+
+ if (procfs_trace)
+ {
+ for (i = 0; ioctl_table[i].name != NULL; i++)
+ if (ioctl_table[i].value == opcode)
+ break;
+
+ if (info_verbose)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "%s:%d -- ", file, line);
+ switch (opcode) {
+ case PIOCSET:
+ arg1 = ptr ? *(long *) ptr : 0;
+ fprintf (procfs_file ? procfs_file : stdout,
+ "ioctl (PIOCSET, %s) %s\n",
+ arg1 == PR_FORK ? "PR_FORK" :
+ arg1 == PR_RLC ? "PR_RLC" :
+#ifdef PR_ASYNC
+ arg1 == PR_ASYNC ? "PR_ASYNC" :
+#endif
+ "<unknown flag>",
+ info_verbose ? ioctl_table[i].desc : "");
+ break;
+ case PIOCRESET:
+ arg1 = ptr ? *(long *) ptr : 0;
+ fprintf (procfs_file ? procfs_file : stdout,
+ "ioctl (PIOCRESET, %s) %s\n",
+ arg1 == PR_FORK ? "PR_FORK" :
+ arg1 == PR_RLC ? "PR_RLC" :
+#ifdef PR_ASYNC
+ arg1 == PR_ASYNC ? "PR_ASYNC" :
+#endif
+ "<unknown flag>",
+ info_verbose ? ioctl_table[i].desc : "");
+ break;
+ case PIOCSTRACE:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "ioctl (PIOCSTRACE) ");
+ proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
+ (sigset_t *) ptr, 0);
+ break;
+ case PIOCSFAULT:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "ioctl (%s) ",
+ opcode == PIOCSFAULT ? "PIOCSFAULT" : "PIOCGFAULT");
+ proc_prettyfprint_faultset (procfs_file ? procfs_file : stdout,
+ (fltset_t *) ptr, 0);
+ break;
+ case PIOCSENTRY:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "ioctl (%s) ",
+ opcode == PIOCSENTRY ? "PIOCSENTRY" : "PIOCGENTRY");
+ proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
+ (sysset_t *) ptr, 0);
+ break;
+ case PIOCSEXIT:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "ioctl (%s) ",
+ opcode == PIOCSEXIT ? "PIOCSEXIT" : "PIOCGEXIT");
+ proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
+ (sysset_t *) ptr, 0);
+ break;
+ case PIOCSHOLD:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "ioctl (%s) ",
+ opcode == PIOCSHOLD ? "PIOCSHOLD" : "PIOCGHOLD");
+ proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
+ (sigset_t *) ptr, 0);
+ break;
+ case PIOCSSIG:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "ioctl (PIOCSSIG) ");
+ proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
+ ptr ? ((siginfo_t *) ptr)->si_signo : 0,
+ 0);
+ fprintf (procfs_file ? procfs_file : stdout, "\n");
+ break;
+ case PIOCRUN:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "ioctl (PIOCRUN) ");
+
+ arg1 = ptr ? *(long *) ptr : 0;
+ if (arg1 & PRCSIG)
+ fprintf (procfs_file ? procfs_file : stdout, "clearSig ");
+ if (arg1 & PRCFAULT)
+ fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
+ if (arg1 & PRSTRACE)
+ fprintf (procfs_file ? procfs_file : stdout, "setTrace ");
+ if (arg1 & PRSHOLD)
+ fprintf (procfs_file ? procfs_file : stdout, "setHold ");
+ if (arg1 & PRSFAULT)
+ fprintf (procfs_file ? procfs_file : stdout, "setFlt ");
+ if (arg1 & PRSVADDR)
+ fprintf (procfs_file ? procfs_file : stdout, "setVaddr ");
+ if (arg1 & PRSTEP)
+ fprintf (procfs_file ? procfs_file : stdout, "step ");
+ if (arg1 & PRSABORT)
+ fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
+ if (arg1 & PRSTOP)
+ fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
+
+ fprintf (procfs_file ? procfs_file : stdout, "\n");
+ break;
+ case PIOCKILL:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "ioctl (PIOCKILL) ");
+ proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
+ ptr ? *(long *) ptr : 0, 0);
+ fprintf (procfs_file ? procfs_file : stdout, "\n");
+ break;
+#ifdef PIOCSSPCACT
+ case PIOCSSPCACT:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "ioctl (PIOCSSPCACT) ");
+ arg1 = ptr ? *(long *) ptr : 0;
+ if (arg1 & PRFS_STOPFORK)
+ fprintf (procfs_file ? procfs_file : stdout, "stopFork ");
+ if (arg1 & PRFS_STOPEXEC)
+ fprintf (procfs_file ? procfs_file : stdout, "stopExec ");
+ if (arg1 & PRFS_STOPTERM)
+ fprintf (procfs_file ? procfs_file : stdout, "stopTerm ");
+ if (arg1 & PRFS_STOPTCR)
+ fprintf (procfs_file ? procfs_file : stdout, "stopThreadCreate ");
+ if (arg1 & PRFS_STOPTTERM)
+ fprintf (procfs_file ? procfs_file : stdout, "stopThreadTerm ");
+ if (arg1 & PRFS_KOLC)
+ fprintf (procfs_file ? procfs_file : stdout, "killOnLastClose ");
+ fprintf (procfs_file ? procfs_file : stdout, "\n");
+ break;
+#endif /* PIOCSSPCACT */
+ default:
+ if (ioctl_table[i].name)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "ioctl (%s) %s\n",
+ ioctl_table[i].name,
+ info_verbose ? ioctl_table[i].desc : "");
+ else
+ fprintf (procfs_file ? procfs_file : stdout,
+ "ioctl (<unknown %ld (0x%lx)) \n", opcode, opcode);
+ break;
+ }
+ if (procfs_file)
+ fflush (procfs_file);
+ }
+ errno = 0;
+ ret = ioctl (fd, opcode, ptr);
+ if (procfs_trace && ret < 0)
+ {
+ fprintf (procfs_file ? procfs_file : stdout,
+ "[ioctl (%s) FAILED! (%s)]\n",
+ ioctl_table[i].name != NULL ?
+ ioctl_table[i].name : "<unknown>",
+ safe_strerror (errno));
+ if (procfs_file)
+ fflush (procfs_file);
+ }
+
+ return ret;
+}
+
+#else /* NEW_PROC_API */
+
+static struct trans rw_table[] = {
+#ifdef PCAGENT /* solaris */
+ { PCAGENT, "PCAGENT", "create agent lwp with regs from argument" },
+#endif
+ { PCCFAULT, "PCCFAULT", "clear current fault" },
+#ifdef PCCSIG /* solaris */
+ { PCCSIG, "PCCSIG", "clear current signal" },
+#endif
+ { PCDSTOP, "PCDSTOP", "post stop request" },
+ { PCKILL, "PCKILL", "post a signal" },
+ { PCNICE, "PCNICE", "set nice priority" },
+#ifdef PCREAD /* solaris */
+ { PCREAD, "PCREAD", "read from the address space" },
+ { PCWRITE, "PCWRITE", "write to the address space" },
+#endif
+#ifdef PCRESET /* unixware */
+ { PCRESET, "PCRESET", "unset modes" },
+#endif
+ { PCRUN, "PCRUN", "make process/lwp runnable" },
+#ifdef PCSASRS /* solaris 2.7 only */
+ { PCSASRS, "PCSASRS", "set ancillary state registers" },
+#endif
+#ifdef PCSCRED /* solaris */
+ { PCSCRED, "PCSCRED", "set process credentials" },
+#endif
+ { PCSENTRY, "PCSENTRY", "set traced syscall entry set" },
+ { PCSET, "PCSET", "set modes" },
+ { PCSEXIT, "PCSEXIT", "set traced syscall exit set" },
+ { PCSFAULT, "PCSFAULT", "set traced fault set" },
+ { PCSFPREG, "PCSFPREG", "set floating point registers" },
+ { PCSHOLD, "PCSHOLD", "set signal mask" },
+ { PCSREG, "PCSREG", "set general registers" },
+ { PCSSIG, "PCSSIG", "set current signal" },
+ { PCSTOP, "PCSTOP", "post stop request and wait" },
+ { PCSTRACE, "PCSTRACE", "set traced signal set" },
+#ifdef PCSVADDR /* solaris */
+ { PCSVADDR, "PCSVADDR", "set pc virtual address" },
+#endif
+#ifdef PCSXREG /* solaris sparc only */
+ { PCSXREG, "PCSXREG", "set extra registers" },
+#endif
+#ifdef PCTWSTOP /* solaris */
+ { PCTWSTOP, "PCTWSTOP", "wait for stop, with timeout arg" },
+#endif
+ { PCUNKILL, "PCUNKILL", "delete a pending signal" },
+#ifdef PCUNSET /* solaris */
+ { PCUNSET, "PCUNSET", "unset modes" },
+#endif
+#ifdef PCWATCH /* solaris */
+ { PCWATCH, "PCWATCH", "set/unset watched memory area" },
+#endif
+ { PCWSTOP, "PCWSTOP", "wait for process/lwp to stop, no timeout" },
+ { 0, NULL, NULL }
+};
+
+static off_t lseek_offset;
+
+int
+write_with_trace (int fd, void *varg, size_t len, char *file, int line)
+{
+ int i;
+ int ret;
+ procfs_ctl_t *arg = (procfs_ctl_t *) varg;
+
+ prepare_to_trace ();
+ if (procfs_trace)
+ {
+ procfs_ctl_t opcode = arg[0];
+ for (i = 0; rw_table[i].name != NULL; i++)
+ if (rw_table[i].value == opcode)
+ break;
+
+ if (info_verbose)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "%s:%d -- ", file, line);
+ switch (opcode) {
+ case PCSET:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "write (PCSET, %s) %s\n",
+ arg[1] == PR_FORK ? "PR_FORK" :
+ arg[1] == PR_RLC ? "PR_RLC" :
+#ifdef PR_ASYNC
+ arg[1] == PR_ASYNC ? "PR_ASYNC" :
+#endif
+ "<unknown flag>",
+ info_verbose ? rw_table[i].desc : "");
+ break;
+#ifdef PCUNSET
+ case PCUNSET:
+#endif
+#ifdef PCRESET
+#if PCRESET != PCUNSET
+ case PCRESET:
+#endif
+#endif
+ fprintf (procfs_file ? procfs_file : stdout,
+ "write (PCRESET, %s) %s\n",
+ arg[1] == PR_FORK ? "PR_FORK" :
+ arg[1] == PR_RLC ? "PR_RLC" :
+#ifdef PR_ASYNC
+ arg[1] == PR_ASYNC ? "PR_ASYNC" :
+#endif
+ "<unknown flag>",
+ info_verbose ? rw_table[i].desc : "");
+ break;
+ case PCSTRACE:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "write (PCSTRACE) ");
+ proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
+ (sigset_t *) &arg[1], 0);
+ break;
+ case PCSFAULT:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "write (PCSFAULT) ");
+ proc_prettyfprint_faultset (procfs_file ? procfs_file : stdout,
+ (fltset_t *) &arg[1], 0);
+ break;
+ case PCSENTRY:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "write (PCSENTRY) ");
+ proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
+ (sysset_t *) &arg[1], 0);
+ break;
+ case PCSEXIT:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "write (PCSEXIT) ");
+ proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
+ (sysset_t *) &arg[1], 0);
+ break;
+ case PCSHOLD:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "write (PCSHOLD) ");
+ proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
+ (sigset_t *) &arg[1], 0);
+ break;
+ case PCSSIG:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "write (PCSSIG) ");
+ proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
+ arg[1] ? ((siginfo_t *) &arg[1])->si_signo
+ : 0,
+ 0);
+ fprintf (procfs_file ? procfs_file : stdout, "\n");
+ break;
+ case PCRUN:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "write (PCRUN) ");
+ if (arg[1] & PRCSIG)
+ fprintf (procfs_file ? procfs_file : stdout, "clearSig ");
+ if (arg[1] & PRCFAULT)
+ fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
+ if (arg[1] & PRSTEP)
+ fprintf (procfs_file ? procfs_file : stdout, "step ");
+ if (arg[1] & PRSABORT)
+ fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
+ if (arg[1] & PRSTOP)
+ fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
+
+ fprintf (procfs_file ? procfs_file : stdout, "\n");
+ break;
+ case PCKILL:
+ fprintf (procfs_file ? procfs_file : stdout,
+ "write (PCKILL) ");
+ proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
+ arg[1], 0);
+ fprintf (procfs_file ? procfs_file : stdout, "\n");
+ break;
+ default:
+ {
+#ifdef BREAKPOINT
+ static unsigned char break_insn[] = BREAKPOINT;
+
+ if (len == sizeof (break_insn) &&
+ memcmp (arg, &break_insn, len) == 0)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "write (<breakpoint at 0x%08lx>) \n",
+ (unsigned long) lseek_offset);
+ else
+#endif
+ if (rw_table[i].name)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "write (%s) %s\n",
+ rw_table[i].name,
+ info_verbose ? rw_table[i].desc : "");
+ else
+ {
+ if (lseek_offset != -1)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "write (<unknown>, %lud bytes at 0x%08lx) \n",
+ (unsigned long) len, (unsigned long) lseek_offset);
+ else
+ fprintf (procfs_file ? procfs_file : stdout,
+ "write (<unknown>, %lud bytes) \n",
+ (unsigned long) len);
+ }
+ break;
+ }
+ }
+ if (procfs_file)
+ fflush (procfs_file);
+ }
+ errno = 0;
+ ret = write (fd, (void *) arg, len);
+ if (procfs_trace && ret != len)
+ {
+ fprintf (procfs_file ? procfs_file : stdout,
+ "[write (%s) FAILED! (%s)]\n",
+ rw_table[i].name != NULL ?
+ rw_table[i].name : "<unknown>",
+ safe_strerror (errno));
+ if (procfs_file)
+ fflush (procfs_file);
+ }
+
+ lseek_offset = -1;
+ return ret;
+}
+
+off_t
+lseek_with_trace (int fd, off_t offset, int whence, char *file, int line)
+{
+ off_t ret;
+
+ prepare_to_trace ();
+ errno = 0;
+ ret = lseek (fd, offset, whence);
+ lseek_offset = ret;
+ if (procfs_trace && (ret == -1 || errno != 0))
+ {
+ fprintf (procfs_file ? procfs_file : stdout,
+ "[lseek (0x%08lx) FAILED! (%s)]\n",
+ (unsigned long) offset, safe_strerror (errno));
+ if (procfs_file)
+ fflush (procfs_file);
+ }
+
+ return ret;
+}
+
+#endif /* NEW_PROC_API */
+
+int
+open_with_trace (char *filename, int mode, char *file, int line)
+{
+ int ret;
+
+ prepare_to_trace ();
+ errno = 0;
+ ret = open (filename, mode);
+ if (procfs_trace)
+ {
+ if (info_verbose)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "%s:%d -- ", file, line);
+
+ if (errno)
+ {
+ fprintf (procfs_file ? procfs_file : stdout,
+ "[open FAILED! (%s) line %d]\\n",
+ safe_strerror (errno), line);
+ }
+ else
+ {
+ fprintf (procfs_file ? procfs_file : stdout,
+ "%d = open (%s, ", ret, filename);
+ if (mode == O_RDONLY)
+ fprintf (procfs_file ? procfs_file : stdout, "O_RDONLY) %d\n",
+ line);
+ else if (mode == O_WRONLY)
+ fprintf (procfs_file ? procfs_file : stdout, "O_WRONLY) %d\n",
+ line);
+ else if (mode == O_RDWR)
+ fprintf (procfs_file ? procfs_file : stdout, "O_RDWR) %d\n",
+ line);
+ }
+ if (procfs_file)
+ fflush (procfs_file);
+ }
+
+ return ret;
+}
+
+int
+close_with_trace (int fd, char *file, int line)
+{
+ int ret;
+
+ prepare_to_trace ();
+ errno = 0;
+ ret = close (fd);
+ if (procfs_trace)
+ {
+ if (info_verbose)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "%s:%d -- ", file, line);
+ if (errno)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "[close FAILED! (%s)]\n", safe_strerror (errno));
+ else
+ fprintf (procfs_file ? procfs_file : stdout,
+ "%d = close (%d)\n", ret, fd);
+ if (procfs_file)
+ fflush (procfs_file);
+ }
+
+ return ret;
+}
+
+pid_t
+wait_with_trace (int *wstat, char *file, int line)
+{
+ int ret, lstat = 0;
+
+ prepare_to_trace ();
+ if (procfs_trace)
+ {
+ if (info_verbose)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "%s:%d -- ", file, line);
+ fprintf (procfs_file ? procfs_file : stdout,
+ "wait (line %d) ", line);
+ if (procfs_file)
+ fflush (procfs_file);
+ }
+ errno = 0;
+ ret = wait (&lstat);
+ if (procfs_trace)
+ {
+ if (errno)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "[wait FAILED! (%s)]\n", safe_strerror (errno));
+ else
+ fprintf (procfs_file ? procfs_file : stdout,
+ "returned pid %d, status 0x%x\n", ret, lstat);
+ if (procfs_file)
+ fflush (procfs_file);
+ }
+ if (wstat)
+ *wstat = lstat;
+
+ return ret;
+}
+
+void
+procfs_note (char *msg, char *file, int line)
+{
+ prepare_to_trace ();
+ if (procfs_trace)
+ {
+ if (info_verbose)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "%s:%d -- ", file, line);
+ fprintf (procfs_file ? procfs_file : stdout, msg);
+ if (procfs_file)
+ fflush (procfs_file);
+ }
+}
+
+void
+proc_prettyfprint_status (long flags, int why, int what, int thread)
+{
+ prepare_to_trace ();
+ if (procfs_trace)
+ {
+ if (thread)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "Thread %d: ", thread);
+
+ proc_prettyfprint_flags (procfs_file ? procfs_file : stdout,
+ flags, 0);
+
+ if (flags & (PR_STOPPED | PR_ISTOP))
+ proc_prettyfprint_why (procfs_file ? procfs_file : stdout,
+ why, what, 0);
+ if (procfs_file)
+ fflush (procfs_file);
+ }
+}
+
+
+void
+_initialize_proc_api (void)
+{
+ struct cmd_list_element *c;
+
+ c = add_set_cmd ("procfs-trace", no_class,
+ var_boolean, (char *) &procfs_trace,
+ "Set tracing for /proc api calls.\n", &setlist);
+
+ add_show_from_set (c, &showlist);
+ set_cmd_sfunc (c, set_procfs_trace_cmd);
+ set_cmd_completer (c, filename_completer);
+
+ c = add_set_cmd ("procfs-file", no_class, var_filename,
+ (char *) &procfs_filename,
+ "Set filename for /proc tracefile.\n", &setlist);
+
+ add_show_from_set (c, &showlist);
+ set_cmd_sfunc (c, set_procfs_file_cmd);
+}
diff --git a/gdb/proc-events.c b/gdb/proc-events.c
new file mode 100644
index 00000000000..5365fefde66
--- /dev/null
+++ b/gdb/proc-events.c
@@ -0,0 +1,1777 @@
+/* Machine independent support for SVR4 /proc (process file system) for GDB.
+ Copyright 1999, 2000 Free Software Foundation, Inc.
+ Written by Michael Snyder at Cygnus Solutions.
+ Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
+
+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. */
+
+/*
+ * Pretty-print "events of interest".
+ *
+ * This module includes pretty-print routines for:
+ * faults (hardware exceptions):
+ * signals (software interrupts):
+ * syscalls
+ *
+ * FIXME: At present, the syscall translation table must be initialized,
+ * which is not true of the other translation tables.
+ */
+
+#include "defs.h"
+
+#if defined (NEW_PROC_API)
+#define _STRUCTURED_PROC 1
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/procfs.h>
+#ifdef HAVE_SYS_SYSCALL_H
+#include <sys/syscall.h>
+#endif
+#ifdef HAVE_SYS_FAULT_H
+#include <sys/fault.h>
+#endif
+
+/* Much of the information used in the /proc interface, particularly for
+ printing status information, is kept as tables of structures of the
+ following form. These tables can be used to map numeric values to
+ their symbolic names and to a string that describes their specific use. */
+
+struct trans {
+ int value; /* The numeric value */
+ char *name; /* The equivalent symbolic value */
+ char *desc; /* Short description of value */
+};
+
+/*
+ * pretty print syscalls
+ */
+
+/* Ugh -- Unixware and Solaris spell these differently! */
+
+#ifdef SYS_lwpcreate
+#define SYS_lwp_create SYS_lwpcreate
+#endif
+
+#ifdef SYS_lwpexit
+#define SYS_lwp_exit SYS_lwpexit
+#endif
+
+#ifdef SYS_lwpwait
+#define SYS_lwp_wait SYS_lwpwait
+#endif
+
+#ifdef SYS_lwpself
+#define SYS_lwp_self SYS_lwpself
+#endif
+
+#ifdef SYS_lwpinfo
+#define SYS_lwp_info SYS_lwpinfo
+#endif
+
+#ifdef SYS_lwpprivate
+#define SYS_lwp_private SYS_lwpprivate
+#endif
+
+#ifdef SYS_lwpkill
+#define SYS_lwp_kill SYS_lwpkill
+#endif
+
+#ifdef SYS_lwpsuspend
+#define SYS_lwp_suspend SYS_lwpsuspend
+#endif
+
+#ifdef SYS_lwpcontinue
+#define SYS_lwp_continue SYS_lwpcontinue
+#endif
+
+
+/* Syscall translation table. */
+
+#define MAX_SYSCALLS 262 /* pretty arbitrary */
+static char * syscall_table[MAX_SYSCALLS];
+
+void
+init_syscall_table (void)
+{
+#if defined (SYS_BSD_getime)
+ syscall_table[SYS_BSD_getime] = "BSD_getime";
+#endif
+#if defined (SYS_BSDgetpgrp)
+ syscall_table[SYS_BSDgetpgrp] = "BSDgetpgrp";
+#endif
+#if defined (SYS_BSDsetpgrp)
+ syscall_table[SYS_BSDsetpgrp] = "BSDsetpgrp";
+#endif
+#if defined (SYS_acancel)
+ syscall_table[SYS_acancel] = "acancel";
+#endif
+#if defined (SYS_accept)
+ syscall_table[SYS_accept] = "accept";
+#endif
+#if defined (SYS_access)
+ syscall_table[SYS_access] = "access";
+#endif
+#if defined (SYS_acct)
+ syscall_table[SYS_acct] = "acct";
+#endif
+#if defined (SYS_acl)
+ syscall_table[SYS_acl] = "acl";
+#endif
+#if defined (SYS_aclipc)
+ syscall_table[SYS_aclipc] = "aclipc";
+#endif
+#if defined (SYS_adjtime)
+ syscall_table[SYS_adjtime] = "adjtime";
+#endif
+#if defined (SYS_afs_syscall)
+ syscall_table[SYS_afs_syscall] = "afs_syscall";
+#endif
+#if defined (SYS_alarm)
+ syscall_table[SYS_alarm] = "alarm";
+#endif
+#if defined (SYS_alt_plock)
+ syscall_table[SYS_alt_plock] = "alt_plock";
+#endif
+#if defined (SYS_alt_sigpending)
+ syscall_table[SYS_alt_sigpending] = "alt_sigpending";
+#endif
+#if defined (SYS_async)
+ syscall_table[SYS_async] = "async";
+#endif
+#if defined (SYS_async_daemon)
+ syscall_table[SYS_async_daemon] = "async_daemon";
+#endif
+#if defined (SYS_audcntl)
+ syscall_table[SYS_audcntl] = "audcntl";
+#endif
+#if defined (SYS_audgen)
+ syscall_table[SYS_audgen] = "audgen";
+#endif
+#if defined (SYS_auditbuf)
+ syscall_table[SYS_auditbuf] = "auditbuf";
+#endif
+#if defined (SYS_auditctl)
+ syscall_table[SYS_auditctl] = "auditctl";
+#endif
+#if defined (SYS_auditdmp)
+ syscall_table[SYS_auditdmp] = "auditdmp";
+#endif
+#if defined (SYS_auditevt)
+ syscall_table[SYS_auditevt] = "auditevt";
+#endif
+#if defined (SYS_auditlog)
+ syscall_table[SYS_auditlog] = "auditlog";
+#endif
+#if defined (SYS_auditsys)
+ syscall_table[SYS_auditsys] = "auditsys";
+#endif
+#if defined (SYS_bind)
+ syscall_table[SYS_bind] = "bind";
+#endif
+#if defined (SYS_block)
+ syscall_table[SYS_block] = "block";
+#endif
+#if defined (SYS_brk)
+ syscall_table[SYS_brk] = "brk";
+#endif
+#if defined (SYS_cachectl)
+ syscall_table[SYS_cachectl] = "cachectl";
+#endif
+#if defined (SYS_cacheflush)
+ syscall_table[SYS_cacheflush] = "cacheflush";
+#endif
+#if defined (SYS_cancelblock)
+ syscall_table[SYS_cancelblock] = "cancelblock";
+#endif
+#if defined (SYS_cg_bind)
+ syscall_table[SYS_cg_bind] = "cg_bind";
+#endif
+#if defined (SYS_cg_current)
+ syscall_table[SYS_cg_current] = "cg_current";
+#endif
+#if defined (SYS_cg_ids)
+ syscall_table[SYS_cg_ids] = "cg_ids";
+#endif
+#if defined (SYS_cg_info)
+ syscall_table[SYS_cg_info] = "cg_info";
+#endif
+#if defined (SYS_cg_memloc)
+ syscall_table[SYS_cg_memloc] = "cg_memloc";
+#endif
+#if defined (SYS_cg_processors)
+ syscall_table[SYS_cg_processors] = "cg_processors";
+#endif
+#if defined (SYS_chdir)
+ syscall_table[SYS_chdir] = "chdir";
+#endif
+#if defined (SYS_chflags)
+ syscall_table[SYS_chflags] = "chflags";
+#endif
+#if defined (SYS_chmod)
+ syscall_table[SYS_chmod] = "chmod";
+#endif
+#if defined (SYS_chown)
+ syscall_table[SYS_chown] = "chown";
+#endif
+#if defined (SYS_chroot)
+ syscall_table[SYS_chroot] = "chroot";
+#endif
+#if defined (SYS_clocal)
+ syscall_table[SYS_clocal] = "clocal";
+#endif
+#if defined (SYS_clock_getres)
+ syscall_table[SYS_clock_getres] = "clock_getres";
+#endif
+#if defined (SYS_clock_gettime)
+ syscall_table[SYS_clock_gettime] = "clock_gettime";
+#endif
+#if defined (SYS_clock_settime)
+ syscall_table[SYS_clock_settime] = "clock_settime";
+#endif
+#if defined (SYS_close)
+ syscall_table[SYS_close] = "close";
+#endif
+#if defined (SYS_connect)
+ syscall_table[SYS_connect] = "connect";
+#endif
+#if defined (SYS_context)
+ syscall_table[SYS_context] = "context";
+#endif
+#if defined (SYS_creat)
+ syscall_table[SYS_creat] = "creat";
+#endif
+#if defined (SYS_creat64)
+ syscall_table[SYS_creat64] = "creat64";
+#endif
+#if defined (SYS_devstat)
+ syscall_table[SYS_devstat] = "devstat";
+#endif
+#if defined (SYS_dmi)
+ syscall_table[SYS_dmi] = "dmi";
+#endif
+#if defined (SYS_door)
+ syscall_table[SYS_door] = "door";
+#endif
+#if defined (SYS_dshmsys)
+ syscall_table[SYS_dshmsys] = "dshmsys";
+#endif
+#if defined (SYS_dup)
+ syscall_table[SYS_dup] = "dup";
+#endif
+#if defined (SYS_dup2)
+ syscall_table[SYS_dup2] = "dup2";
+#endif
+#if defined (SYS_evsys)
+ syscall_table[SYS_evsys] = "evsys";
+#endif
+#if defined (SYS_evtrapret)
+ syscall_table[SYS_evtrapret] = "evtrapret";
+#endif
+#if defined (SYS_exec)
+ syscall_table[SYS_exec] = "exec";
+#endif
+#if defined (SYS_exec_with_loader)
+ syscall_table[SYS_exec_with_loader] = "exec_with_loader";
+#endif
+#if defined (SYS_execv)
+ syscall_table[SYS_execv] = "execv";
+#endif
+#if defined (SYS_execve)
+ syscall_table[SYS_execve] = "execve";
+#endif
+#if defined (SYS_exit)
+ syscall_table[SYS_exit] = "exit";
+#endif
+#if defined (SYS_exportfs)
+ syscall_table[SYS_exportfs] = "exportfs";
+#endif
+#if defined (SYS_facl)
+ syscall_table[SYS_facl] = "facl";
+#endif
+#if defined (SYS_fchdir)
+ syscall_table[SYS_fchdir] = "fchdir";
+#endif
+#if defined (SYS_fchflags)
+ syscall_table[SYS_fchflags] = "fchflags";
+#endif
+#if defined (SYS_fchmod)
+ syscall_table[SYS_fchmod] = "fchmod";
+#endif
+#if defined (SYS_fchown)
+ syscall_table[SYS_fchown] = "fchown";
+#endif
+#if defined (SYS_fchroot)
+ syscall_table[SYS_fchroot] = "fchroot";
+#endif
+#if defined (SYS_fcntl)
+ syscall_table[SYS_fcntl] = "fcntl";
+#endif
+#if defined (SYS_fdatasync)
+ syscall_table[SYS_fdatasync] = "fdatasync";
+#endif
+#if defined (SYS_fdevstat)
+ syscall_table[SYS_fdevstat] = "fdevstat";
+#endif
+#if defined (SYS_fdsync)
+ syscall_table[SYS_fdsync] = "fdsync";
+#endif
+#if defined (SYS_filepriv)
+ syscall_table[SYS_filepriv] = "filepriv";
+#endif
+#if defined (SYS_flock)
+ syscall_table[SYS_flock] = "flock";
+#endif
+#if defined (SYS_flvlfile)
+ syscall_table[SYS_flvlfile] = "flvlfile";
+#endif
+#if defined (SYS_fork)
+ syscall_table[SYS_fork] = "fork";
+#endif
+#if defined (SYS_fork1)
+ syscall_table[SYS_fork1] = "fork1";
+#endif
+#if defined (SYS_forkall)
+ syscall_table[SYS_forkall] = "forkall";
+#endif
+#if defined (SYS_fpathconf)
+ syscall_table[SYS_fpathconf] = "fpathconf";
+#endif
+#if defined (SYS_fstat)
+ syscall_table[SYS_fstat] = "fstat";
+#endif
+#if defined (SYS_fstat64)
+ syscall_table[SYS_fstat64] = "fstat64";
+#endif
+#if defined (SYS_fstatfs)
+ syscall_table[SYS_fstatfs] = "fstatfs";
+#endif
+#if defined (SYS_fstatvfs)
+ syscall_table[SYS_fstatvfs] = "fstatvfs";
+#endif
+#if defined (SYS_fstatvfs64)
+ syscall_table[SYS_fstatvfs64] = "fstatvfs64";
+#endif
+#if defined (SYS_fsync)
+ syscall_table[SYS_fsync] = "fsync";
+#endif
+#if defined (SYS_ftruncate)
+ syscall_table[SYS_ftruncate] = "ftruncate";
+#endif
+#if defined (SYS_ftruncate64)
+ syscall_table[SYS_ftruncate64] = "ftruncate64";
+#endif
+#if defined (SYS_fuser)
+ syscall_table[SYS_fuser] = "fuser";
+#endif
+#if defined (SYS_fxstat)
+ syscall_table[SYS_fxstat] = "fxstat";
+#endif
+#if defined (SYS_get_sysinfo)
+ syscall_table[SYS_get_sysinfo] = "get_sysinfo";
+#endif
+#if defined (SYS_getaddressconf)
+ syscall_table[SYS_getaddressconf] = "getaddressconf";
+#endif
+#if defined (SYS_getcontext)
+ syscall_table[SYS_getcontext] = "getcontext";
+#endif
+#if defined (SYS_getdents)
+ syscall_table[SYS_getdents] = "getdents";
+#endif
+#if defined (SYS_getdents64)
+ syscall_table[SYS_getdents64] = "getdents64";
+#endif
+#if defined (SYS_getdirentries)
+ syscall_table[SYS_getdirentries] = "getdirentries";
+#endif
+#if defined (SYS_getdomainname)
+ syscall_table[SYS_getdomainname] = "getdomainname";
+#endif
+#if defined (SYS_getdtablesize)
+ syscall_table[SYS_getdtablesize] = "getdtablesize";
+#endif
+#if defined (SYS_getfh)
+ syscall_table[SYS_getfh] = "getfh";
+#endif
+#if defined (SYS_getfsstat)
+ syscall_table[SYS_getfsstat] = "getfsstat";
+#endif
+#if defined (SYS_getgid)
+ syscall_table[SYS_getgid] = "getgid";
+#endif
+#if defined (SYS_getgroups)
+ syscall_table[SYS_getgroups] = "getgroups";
+#endif
+#if defined (SYS_gethostid)
+ syscall_table[SYS_gethostid] = "gethostid";
+#endif
+#if defined (SYS_gethostname)
+ syscall_table[SYS_gethostname] = "gethostname";
+#endif
+#if defined (SYS_getitimer)
+ syscall_table[SYS_getitimer] = "getitimer";
+#endif
+#if defined (SYS_getksym)
+ syscall_table[SYS_getksym] = "getksym";
+#endif
+#if defined (SYS_getlogin)
+ syscall_table[SYS_getlogin] = "getlogin";
+#endif
+#if defined (SYS_getmnt)
+ syscall_table[SYS_getmnt] = "getmnt";
+#endif
+#if defined (SYS_getmsg)
+ syscall_table[SYS_getmsg] = "getmsg";
+#endif
+#if defined (SYS_getpagesize)
+ syscall_table[SYS_getpagesize] = "getpagesize";
+#endif
+#if defined (SYS_getpeername)
+ syscall_table[SYS_getpeername] = "getpeername";
+#endif
+#if defined (SYS_getpgid)
+ syscall_table[SYS_getpgid] = "getpgid";
+#endif
+#if defined (SYS_getpgrp)
+ syscall_table[SYS_getpgrp] = "getpgrp";
+#endif
+#if defined (SYS_getpid)
+ syscall_table[SYS_getpid] = "getpid";
+#endif
+#if defined (SYS_getpmsg)
+ syscall_table[SYS_getpmsg] = "getpmsg";
+#endif
+#if defined (SYS_getpriority)
+ syscall_table[SYS_getpriority] = "getpriority";
+#endif
+#if defined (SYS_getrlimit)
+ syscall_table[SYS_getrlimit] = "getrlimit";
+#endif
+#if defined (SYS_getrlimit64)
+ syscall_table[SYS_getrlimit64] = "getrlimit64";
+#endif
+#if defined (SYS_getrusage)
+ syscall_table[SYS_getrusage] = "getrusage";
+#endif
+#if defined (SYS_getsid)
+ syscall_table[SYS_getsid] = "getsid";
+#endif
+#if defined (SYS_getsockname)
+ syscall_table[SYS_getsockname] = "getsockname";
+#endif
+#if defined (SYS_getsockopt)
+ syscall_table[SYS_getsockopt] = "getsockopt";
+#endif
+#if defined (SYS_gettimeofday)
+ syscall_table[SYS_gettimeofday] = "gettimeofday";
+#endif
+#if defined (SYS_getuid)
+ syscall_table[SYS_getuid] = "getuid";
+#endif
+#if defined (SYS_gtty)
+ syscall_table[SYS_gtty] = "gtty";
+#endif
+#if defined (SYS_hrtsys)
+ syscall_table[SYS_hrtsys] = "hrtsys";
+#endif
+#if defined (SYS_inst_sync)
+ syscall_table[SYS_inst_sync] = "inst_sync";
+#endif
+#if defined (SYS_install_utrap)
+ syscall_table[SYS_install_utrap] = "install_utrap";
+#endif
+#if defined (SYS_invlpg)
+ syscall_table[SYS_invlpg] = "invlpg";
+#endif
+#if defined (SYS_ioctl)
+ syscall_table[SYS_ioctl] = "ioctl";
+#endif
+#if defined (SYS_kaio)
+ syscall_table[SYS_kaio] = "kaio";
+#endif
+#if defined (SYS_keyctl)
+ syscall_table[SYS_keyctl] = "keyctl";
+#endif
+#if defined (SYS_kill)
+ syscall_table[SYS_kill] = "kill";
+#endif
+#if defined (SYS_killpg)
+ syscall_table[SYS_killpg] = "killpg";
+#endif
+#if defined (SYS_kloadcall)
+ syscall_table[SYS_kloadcall] = "kloadcall";
+#endif
+#if defined (SYS_kmodcall)
+ syscall_table[SYS_kmodcall] = "kmodcall";
+#endif
+#if defined (SYS_ksigaction)
+ syscall_table[SYS_ksigaction] = "ksigaction";
+#endif
+#if defined (SYS_ksigprocmask)
+ syscall_table[SYS_ksigprocmask] = "ksigprocmask";
+#endif
+#if defined (SYS_ksigqueue)
+ syscall_table[SYS_ksigqueue] = "ksigqueue";
+#endif
+#if defined (SYS_lchown)
+ syscall_table[SYS_lchown] = "lchown";
+#endif
+#if defined (SYS_link)
+ syscall_table[SYS_link] = "link";
+#endif
+#if defined (SYS_listen)
+ syscall_table[SYS_listen] = "listen";
+#endif
+#if defined (SYS_llseek)
+ syscall_table[SYS_llseek] = "llseek";
+#endif
+#if defined (SYS_lseek)
+ syscall_table[SYS_lseek] = "lseek";
+#endif
+#if defined (SYS_lseek64)
+ syscall_table[SYS_lseek64] = "lseek64";
+#endif
+#if defined (SYS_lstat)
+ syscall_table[SYS_lstat] = "lstat";
+#endif
+#if defined (SYS_lstat64)
+ syscall_table[SYS_lstat64] = "lstat64";
+#endif
+#if defined (SYS_lvldom)
+ syscall_table[SYS_lvldom] = "lvldom";
+#endif
+#if defined (SYS_lvlequal)
+ syscall_table[SYS_lvlequal] = "lvlequal";
+#endif
+#if defined (SYS_lvlfile)
+ syscall_table[SYS_lvlfile] = "lvlfile";
+#endif
+#if defined (SYS_lvlipc)
+ syscall_table[SYS_lvlipc] = "lvlipc";
+#endif
+#if defined (SYS_lvlproc)
+ syscall_table[SYS_lvlproc] = "lvlproc";
+#endif
+#if defined (SYS_lvlvfs)
+ syscall_table[SYS_lvlvfs] = "lvlvfs";
+#endif
+#if defined (SYS_lwp_alarm)
+ syscall_table[SYS_lwp_alarm] = "lwp_alarm";
+#endif
+#if defined (SYS_lwp_cond_broadcast)
+ syscall_table[SYS_lwp_cond_broadcast] = "lwp_cond_broadcast";
+#endif
+#if defined (SYS_lwp_cond_signal)
+ syscall_table[SYS_lwp_cond_signal] = "lwp_cond_signal";
+#endif
+#if defined (SYS_lwp_cond_wait)
+ syscall_table[SYS_lwp_cond_wait] = "lwp_cond_wait";
+#endif
+#if defined (SYS_lwp_continue)
+ syscall_table[SYS_lwp_continue] = "lwp_continue";
+#endif
+#if defined (SYS_lwp_create)
+ syscall_table[SYS_lwp_create] = "lwp_create";
+#endif
+#if defined (SYS_lwp_exit)
+ syscall_table[SYS_lwp_exit] = "lwp_exit";
+#endif
+#if defined (SYS_lwp_getprivate)
+ syscall_table[SYS_lwp_getprivate] = "lwp_getprivate";
+#endif
+#if defined (SYS_lwp_info)
+ syscall_table[SYS_lwp_info] = "lwp_info";
+#endif
+#if defined (SYS_lwp_kill)
+ syscall_table[SYS_lwp_kill] = "lwp_kill";
+#endif
+#if defined (SYS_lwp_mutex_init)
+ syscall_table[SYS_lwp_mutex_init] = "lwp_mutex_init";
+#endif
+#if defined (SYS_lwp_mutex_lock)
+ syscall_table[SYS_lwp_mutex_lock] = "lwp_mutex_lock";
+#endif
+#if defined (SYS_lwp_mutex_trylock)
+ syscall_table[SYS_lwp_mutex_trylock] = "lwp_mutex_trylock";
+#endif
+#if defined (SYS_lwp_mutex_unlock)
+ syscall_table[SYS_lwp_mutex_unlock] = "lwp_mutex_unlock";
+#endif
+#if defined (SYS_lwp_private)
+ syscall_table[SYS_lwp_private] = "lwp_private";
+#endif
+#if defined (SYS_lwp_self)
+ syscall_table[SYS_lwp_self] = "lwp_self";
+#endif
+#if defined (SYS_lwp_sema_post)
+ syscall_table[SYS_lwp_sema_post] = "lwp_sema_post";
+#endif
+#if defined (SYS_lwp_sema_trywait)
+ syscall_table[SYS_lwp_sema_trywait] = "lwp_sema_trywait";
+#endif
+#if defined (SYS_lwp_sema_wait)
+ syscall_table[SYS_lwp_sema_wait] = "lwp_sema_wait";
+#endif
+#if defined (SYS_lwp_setprivate)
+ syscall_table[SYS_lwp_setprivate] = "lwp_setprivate";
+#endif
+#if defined (SYS_lwp_sigredirect)
+ syscall_table[SYS_lwp_sigredirect] = "lwp_sigredirect";
+#endif
+#if defined (SYS_lwp_suspend)
+ syscall_table[SYS_lwp_suspend] = "lwp_suspend";
+#endif
+#if defined (SYS_lwp_wait)
+ syscall_table[SYS_lwp_wait] = "lwp_wait";
+#endif
+#if defined (SYS_lxstat)
+ syscall_table[SYS_lxstat] = "lxstat";
+#endif
+#if defined (SYS_madvise)
+ syscall_table[SYS_madvise] = "madvise";
+#endif
+#if defined (SYS_memcntl)
+ syscall_table[SYS_memcntl] = "memcntl";
+#endif
+#if defined (SYS_mincore)
+ syscall_table[SYS_mincore] = "mincore";
+#endif
+#if defined (SYS_mincore)
+ syscall_table[SYS_mincore] = "mincore";
+#endif
+#if defined (SYS_mkdir)
+ syscall_table[SYS_mkdir] = "mkdir";
+#endif
+#if defined (SYS_mkmld)
+ syscall_table[SYS_mkmld] = "mkmld";
+#endif
+#if defined (SYS_mknod)
+ syscall_table[SYS_mknod] = "mknod";
+#endif
+#if defined (SYS_mldmode)
+ syscall_table[SYS_mldmode] = "mldmode";
+#endif
+#if defined (SYS_mmap)
+ syscall_table[SYS_mmap] = "mmap";
+#endif
+#if defined (SYS_mmap64)
+ syscall_table[SYS_mmap64] = "mmap64";
+#endif
+#if defined (SYS_modadm)
+ syscall_table[SYS_modadm] = "modadm";
+#endif
+#if defined (SYS_modctl)
+ syscall_table[SYS_modctl] = "modctl";
+#endif
+#if defined (SYS_modload)
+ syscall_table[SYS_modload] = "modload";
+#endif
+#if defined (SYS_modpath)
+ syscall_table[SYS_modpath] = "modpath";
+#endif
+#if defined (SYS_modstat)
+ syscall_table[SYS_modstat] = "modstat";
+#endif
+#if defined (SYS_moduload)
+ syscall_table[SYS_moduload] = "moduload";
+#endif
+#if defined (SYS_mount)
+ syscall_table[SYS_mount] = "mount";
+#endif
+#if defined (SYS_mprotect)
+ syscall_table[SYS_mprotect] = "mprotect";
+#endif
+#if defined (SYS_mremap)
+ syscall_table[SYS_mremap] = "mremap";
+#endif
+#if defined (SYS_msfs_syscall)
+ syscall_table[SYS_msfs_syscall] = "msfs_syscall";
+#endif
+#if defined (SYS_msgctl)
+ syscall_table[SYS_msgctl] = "msgctl";
+#endif
+#if defined (SYS_msgget)
+ syscall_table[SYS_msgget] = "msgget";
+#endif
+#if defined (SYS_msgrcv)
+ syscall_table[SYS_msgrcv] = "msgrcv";
+#endif
+#if defined (SYS_msgsnd)
+ syscall_table[SYS_msgsnd] = "msgsnd";
+#endif
+#if defined (SYS_msgsys)
+ syscall_table[SYS_msgsys] = "msgsys";
+#endif
+#if defined (SYS_msleep)
+ syscall_table[SYS_msleep] = "msleep";
+#endif
+#if defined (SYS_msync)
+ syscall_table[SYS_msync] = "msync";
+#endif
+#if defined (SYS_munmap)
+ syscall_table[SYS_munmap] = "munmap";
+#endif
+#if defined (SYS_mvalid)
+ syscall_table[SYS_mvalid] = "mvalid";
+#endif
+#if defined (SYS_mwakeup)
+ syscall_table[SYS_mwakeup] = "mwakeup";
+#endif
+#if defined (SYS_naccept)
+ syscall_table[SYS_naccept] = "naccept";
+#endif
+#if defined (SYS_nanosleep)
+ syscall_table[SYS_nanosleep] = "nanosleep";
+#endif
+#if defined (SYS_nfssvc)
+ syscall_table[SYS_nfssvc] = "nfssvc";
+#endif
+#if defined (SYS_nfssys)
+ syscall_table[SYS_nfssys] = "nfssys";
+#endif
+#if defined (SYS_ngetpeername)
+ syscall_table[SYS_ngetpeername] = "ngetpeername";
+#endif
+#if defined (SYS_ngetsockname)
+ syscall_table[SYS_ngetsockname] = "ngetsockname";
+#endif
+#if defined (SYS_nice)
+ syscall_table[SYS_nice] = "nice";
+#endif
+#if defined (SYS_nrecvfrom)
+ syscall_table[SYS_nrecvfrom] = "nrecvfrom";
+#endif
+#if defined (SYS_nrecvmsg)
+ syscall_table[SYS_nrecvmsg] = "nrecvmsg";
+#endif
+#if defined (SYS_nsendmsg)
+ syscall_table[SYS_nsendmsg] = "nsendmsg";
+#endif
+#if defined (SYS_ntp_adjtime)
+ syscall_table[SYS_ntp_adjtime] = "ntp_adjtime";
+#endif
+#if defined (SYS_ntp_gettime)
+ syscall_table[SYS_ntp_gettime] = "ntp_gettime";
+#endif
+#if defined (SYS_nuname)
+ syscall_table[SYS_nuname] = "nuname";
+#endif
+#if defined (SYS_obreak)
+ syscall_table[SYS_obreak] = "obreak";
+#endif
+#if defined (SYS_old_accept)
+ syscall_table[SYS_old_accept] = "old_accept";
+#endif
+#if defined (SYS_old_fstat)
+ syscall_table[SYS_old_fstat] = "old_fstat";
+#endif
+#if defined (SYS_old_getpeername)
+ syscall_table[SYS_old_getpeername] = "old_getpeername";
+#endif
+#if defined (SYS_old_getpgrp)
+ syscall_table[SYS_old_getpgrp] = "old_getpgrp";
+#endif
+#if defined (SYS_old_getsockname)
+ syscall_table[SYS_old_getsockname] = "old_getsockname";
+#endif
+#if defined (SYS_old_killpg)
+ syscall_table[SYS_old_killpg] = "old_killpg";
+#endif
+#if defined (SYS_old_lstat)
+ syscall_table[SYS_old_lstat] = "old_lstat";
+#endif
+#if defined (SYS_old_recv)
+ syscall_table[SYS_old_recv] = "old_recv";
+#endif
+#if defined (SYS_old_recvfrom)
+ syscall_table[SYS_old_recvfrom] = "old_recvfrom";
+#endif
+#if defined (SYS_old_recvmsg)
+ syscall_table[SYS_old_recvmsg] = "old_recvmsg";
+#endif
+#if defined (SYS_old_send)
+ syscall_table[SYS_old_send] = "old_send";
+#endif
+#if defined (SYS_old_sendmsg)
+ syscall_table[SYS_old_sendmsg] = "old_sendmsg";
+#endif
+#if defined (SYS_old_sigblock)
+ syscall_table[SYS_old_sigblock] = "old_sigblock";
+#endif
+#if defined (SYS_old_sigsetmask)
+ syscall_table[SYS_old_sigsetmask] = "old_sigsetmask";
+#endif
+#if defined (SYS_old_sigvec)
+ syscall_table[SYS_old_sigvec] = "old_sigvec";
+#endif
+#if defined (SYS_old_stat)
+ syscall_table[SYS_old_stat] = "old_stat";
+#endif
+#if defined (SYS_old_vhangup)
+ syscall_table[SYS_old_vhangup] = "old_vhangup";
+#endif
+#if defined (SYS_old_wait)
+ syscall_table[SYS_old_wait] = "old_wait";
+#endif
+#if defined (SYS_oldquota)
+ syscall_table[SYS_oldquota] = "oldquota";
+#endif
+#if defined (SYS_online)
+ syscall_table[SYS_online] = "online";
+#endif
+#if defined (SYS_open)
+ syscall_table[SYS_open] = "open";
+#endif
+#if defined (SYS_open64)
+ syscall_table[SYS_open64] = "open64";
+#endif
+#if defined (SYS_ovadvise)
+ syscall_table[SYS_ovadvise] = "ovadvise";
+#endif
+#if defined (SYS_p_online)
+ syscall_table[SYS_p_online] = "p_online";
+#endif
+#if defined (SYS_pagelock)
+ syscall_table[SYS_pagelock] = "pagelock";
+#endif
+#if defined (SYS_pathconf)
+ syscall_table[SYS_pathconf] = "pathconf";
+#endif
+#if defined (SYS_pause)
+ syscall_table[SYS_pause] = "pause";
+#endif
+#if defined (SYS_pgrpsys)
+ syscall_table[SYS_pgrpsys] = "pgrpsys";
+#endif
+#if defined (SYS_pid_block)
+ syscall_table[SYS_pid_block] = "pid_block";
+#endif
+#if defined (SYS_pid_unblock)
+ syscall_table[SYS_pid_unblock] = "pid_unblock";
+#endif
+#if defined (SYS_pipe)
+ syscall_table[SYS_pipe] = "pipe";
+#endif
+#if defined (SYS_plock)
+ syscall_table[SYS_plock] = "plock";
+#endif
+#if defined (SYS_poll)
+ syscall_table[SYS_poll] = "poll";
+#endif
+#if defined (SYS_prctl)
+ syscall_table[SYS_prctl] = "prctl";
+#endif
+#if defined (SYS_pread)
+ syscall_table[SYS_pread] = "pread";
+#endif
+#if defined (SYS_pread64)
+ syscall_table[SYS_pread64] = "pread64";
+#endif
+#if defined (SYS_pread64)
+ syscall_table[SYS_pread64] = "pread64";
+#endif
+#if defined (SYS_prepblock)
+ syscall_table[SYS_prepblock] = "prepblock";
+#endif
+#if defined (SYS_priocntl)
+ syscall_table[SYS_priocntl] = "priocntl";
+#endif
+#if defined (SYS_priocntllst)
+ syscall_table[SYS_priocntllst] = "priocntllst";
+#endif
+#if defined (SYS_priocntlset)
+ syscall_table[SYS_priocntlset] = "priocntlset";
+#endif
+#if defined (SYS_priocntlsys)
+ syscall_table[SYS_priocntlsys] = "priocntlsys";
+#endif
+#if defined (SYS_procblk)
+ syscall_table[SYS_procblk] = "procblk";
+#endif
+#if defined (SYS_processor_bind)
+ syscall_table[SYS_processor_bind] = "processor_bind";
+#endif
+#if defined (SYS_processor_exbind)
+ syscall_table[SYS_processor_exbind] = "processor_exbind";
+#endif
+#if defined (SYS_processor_info)
+ syscall_table[SYS_processor_info] = "processor_info";
+#endif
+#if defined (SYS_procpriv)
+ syscall_table[SYS_procpriv] = "procpriv";
+#endif
+#if defined (SYS_profil)
+ syscall_table[SYS_profil] = "profil";
+#endif
+#if defined (SYS_proplist_syscall)
+ syscall_table[SYS_proplist_syscall] = "proplist_syscall";
+#endif
+#if defined (SYS_pset)
+ syscall_table[SYS_pset] = "pset";
+#endif
+#if defined (SYS_ptrace)
+ syscall_table[SYS_ptrace] = "ptrace";
+#endif
+#if defined (SYS_putmsg)
+ syscall_table[SYS_putmsg] = "putmsg";
+#endif
+#if defined (SYS_putpmsg)
+ syscall_table[SYS_putpmsg] = "putpmsg";
+#endif
+#if defined (SYS_pwrite)
+ syscall_table[SYS_pwrite] = "pwrite";
+#endif
+#if defined (SYS_pwrite64)
+ syscall_table[SYS_pwrite64] = "pwrite64";
+#endif
+#if defined (SYS_quotactl)
+ syscall_table[SYS_quotactl] = "quotactl";
+#endif
+#if defined (SYS_rdblock)
+ syscall_table[SYS_rdblock] = "rdblock";
+#endif
+#if defined (SYS_read)
+ syscall_table[SYS_read] = "read";
+#endif
+#if defined (SYS_readlink)
+ syscall_table[SYS_readlink] = "readlink";
+#endif
+#if defined (SYS_readv)
+ syscall_table[SYS_readv] = "readv";
+#endif
+#if defined (SYS_reboot)
+ syscall_table[SYS_reboot] = "reboot";
+#endif
+#if defined (SYS_recv)
+ syscall_table[SYS_recv] = "recv";
+#endif
+#if defined (SYS_recvfrom)
+ syscall_table[SYS_recvfrom] = "recvfrom";
+#endif
+#if defined (SYS_recvmsg)
+ syscall_table[SYS_recvmsg] = "recvmsg";
+#endif
+#if defined (SYS_rename)
+ syscall_table[SYS_rename] = "rename";
+#endif
+#if defined (SYS_resolvepath)
+ syscall_table[SYS_resolvepath] = "resolvepath";
+#endif
+#if defined (SYS_revoke)
+ syscall_table[SYS_revoke] = "revoke";
+#endif
+#if defined (SYS_rfsys)
+ syscall_table[SYS_rfsys] = "rfsys";
+#endif
+#if defined (SYS_rmdir)
+ syscall_table[SYS_rmdir] = "rmdir";
+#endif
+#if defined (SYS_rpcsys)
+ syscall_table[SYS_rpcsys] = "rpcsys";
+#endif
+#if defined (SYS_sbrk)
+ syscall_table[SYS_sbrk] = "sbrk";
+#endif
+#if defined (SYS_schedctl)
+ syscall_table[SYS_schedctl] = "schedctl";
+#endif
+#if defined (SYS_secadvise)
+ syscall_table[SYS_secadvise] = "secadvise";
+#endif
+#if defined (SYS_secsys)
+ syscall_table[SYS_secsys] = "secsys";
+#endif
+#if defined (SYS_security)
+ syscall_table[SYS_security] = "security";
+#endif
+#if defined (SYS_select)
+ syscall_table[SYS_select] = "select";
+#endif
+#if defined (SYS_semctl)
+ syscall_table[SYS_semctl] = "semctl";
+#endif
+#if defined (SYS_semget)
+ syscall_table[SYS_semget] = "semget";
+#endif
+#if defined (SYS_semop)
+ syscall_table[SYS_semop] = "semop";
+#endif
+#if defined (SYS_semsys)
+ syscall_table[SYS_semsys] = "semsys";
+#endif
+#if defined (SYS_send)
+ syscall_table[SYS_send] = "send";
+#endif
+#if defined (SYS_sendmsg)
+ syscall_table[SYS_sendmsg] = "sendmsg";
+#endif
+#if defined (SYS_sendto)
+ syscall_table[SYS_sendto] = "sendto";
+#endif
+#if defined (SYS_set_program_attributes)
+ syscall_table[SYS_set_program_attributes] = "set_program_attributes";
+#endif
+#if defined (SYS_set_speculative)
+ syscall_table[SYS_set_speculative] = "set_speculative";
+#endif
+#if defined (SYS_set_sysinfo)
+ syscall_table[SYS_set_sysinfo] = "set_sysinfo";
+#endif
+#if defined (SYS_setcontext)
+ syscall_table[SYS_setcontext] = "setcontext";
+#endif
+#if defined (SYS_setdomainname)
+ syscall_table[SYS_setdomainname] = "setdomainname";
+#endif
+#if defined (SYS_setegid)
+ syscall_table[SYS_setegid] = "setegid";
+#endif
+#if defined (SYS_seteuid)
+ syscall_table[SYS_seteuid] = "seteuid";
+#endif
+#if defined (SYS_setgid)
+ syscall_table[SYS_setgid] = "setgid";
+#endif
+#if defined (SYS_setgroups)
+ syscall_table[SYS_setgroups] = "setgroups";
+#endif
+#if defined (SYS_sethostid)
+ syscall_table[SYS_sethostid] = "sethostid";
+#endif
+#if defined (SYS_sethostname)
+ syscall_table[SYS_sethostname] = "sethostname";
+#endif
+#if defined (SYS_setitimer)
+ syscall_table[SYS_setitimer] = "setitimer";
+#endif
+#if defined (SYS_setlogin)
+ syscall_table[SYS_setlogin] = "setlogin";
+#endif
+#if defined (SYS_setpgid)
+ syscall_table[SYS_setpgid] = "setpgid";
+#endif
+#if defined (SYS_setpgrp)
+ syscall_table[SYS_setpgrp] = "setpgrp";
+#endif
+#if defined (SYS_setpriority)
+ syscall_table[SYS_setpriority] = "setpriority";
+#endif
+#if defined (SYS_setregid)
+ syscall_table[SYS_setregid] = "setregid";
+#endif
+#if defined (SYS_setreuid)
+ syscall_table[SYS_setreuid] = "setreuid";
+#endif
+#if defined (SYS_setrlimit)
+ syscall_table[SYS_setrlimit] = "setrlimit";
+#endif
+#if defined (SYS_setrlimit64)
+ syscall_table[SYS_setrlimit64] = "setrlimit64";
+#endif
+#if defined (SYS_setsid)
+ syscall_table[SYS_setsid] = "setsid";
+#endif
+#if defined (SYS_setsockopt)
+ syscall_table[SYS_setsockopt] = "setsockopt";
+#endif
+#if defined (SYS_settimeofday)
+ syscall_table[SYS_settimeofday] = "settimeofday";
+#endif
+#if defined (SYS_setuid)
+ syscall_table[SYS_setuid] = "setuid";
+#endif
+#if defined (SYS_sgi)
+ syscall_table[SYS_sgi] = "sgi";
+#endif
+#if defined (SYS_sgifastpath)
+ syscall_table[SYS_sgifastpath] = "sgifastpath";
+#endif
+#if defined (SYS_sgikopt)
+ syscall_table[SYS_sgikopt] = "sgikopt";
+#endif
+#if defined (SYS_sginap)
+ syscall_table[SYS_sginap] = "sginap";
+#endif
+#if defined (SYS_shmat)
+ syscall_table[SYS_shmat] = "shmat";
+#endif
+#if defined (SYS_shmctl)
+ syscall_table[SYS_shmctl] = "shmctl";
+#endif
+#if defined (SYS_shmdt)
+ syscall_table[SYS_shmdt] = "shmdt";
+#endif
+#if defined (SYS_shmget)
+ syscall_table[SYS_shmget] = "shmget";
+#endif
+#if defined (SYS_shmsys)
+ syscall_table[SYS_shmsys] = "shmsys";
+#endif
+#if defined (SYS_shutdown)
+ syscall_table[SYS_shutdown] = "shutdown";
+#endif
+#if defined (SYS_sigaction)
+ syscall_table[SYS_sigaction] = "sigaction";
+#endif
+#if defined (SYS_sigaltstack)
+ syscall_table[SYS_sigaltstack] = "sigaltstack";
+#endif
+#if defined (SYS_sigaltstack)
+ syscall_table[SYS_sigaltstack] = "sigaltstack";
+#endif
+#if defined (SYS_sigblock)
+ syscall_table[SYS_sigblock] = "sigblock";
+#endif
+#if defined (SYS_signal)
+ syscall_table[SYS_signal] = "signal";
+#endif
+#if defined (SYS_signotify)
+ syscall_table[SYS_signotify] = "signotify";
+#endif
+#if defined (SYS_signotifywait)
+ syscall_table[SYS_signotifywait] = "signotifywait";
+#endif
+#if defined (SYS_sigpending)
+ syscall_table[SYS_sigpending] = "sigpending";
+#endif
+#if defined (SYS_sigpoll)
+ syscall_table[SYS_sigpoll] = "sigpoll";
+#endif
+#if defined (SYS_sigprocmask)
+ syscall_table[SYS_sigprocmask] = "sigprocmask";
+#endif
+#if defined (SYS_sigqueue)
+ syscall_table[SYS_sigqueue] = "sigqueue";
+#endif
+#if defined (SYS_sigreturn)
+ syscall_table[SYS_sigreturn] = "sigreturn";
+#endif
+#if defined (SYS_sigsendset)
+ syscall_table[SYS_sigsendset] = "sigsendset";
+#endif
+#if defined (SYS_sigsendsys)
+ syscall_table[SYS_sigsendsys] = "sigsendsys";
+#endif
+#if defined (SYS_sigsetmask)
+ syscall_table[SYS_sigsetmask] = "sigsetmask";
+#endif
+#if defined (SYS_sigstack)
+ syscall_table[SYS_sigstack] = "sigstack";
+#endif
+#if defined (SYS_sigsuspend)
+ syscall_table[SYS_sigsuspend] = "sigsuspend";
+#endif
+#if defined (SYS_sigvec)
+ syscall_table[SYS_sigvec] = "sigvec";
+#endif
+#if defined (SYS_sigwait)
+ syscall_table[SYS_sigwait] = "sigwait";
+#endif
+#if defined (SYS_sigwaitprim)
+ syscall_table[SYS_sigwaitprim] = "sigwaitprim";
+#endif
+#if defined (SYS_sleep)
+ syscall_table[SYS_sleep] = "sleep";
+#endif
+#if defined (SYS_so_socket)
+ syscall_table[SYS_so_socket] = "so_socket";
+#endif
+#if defined (SYS_so_socketpair)
+ syscall_table[SYS_so_socketpair] = "so_socketpair";
+#endif
+#if defined (SYS_sockconfig)
+ syscall_table[SYS_sockconfig] = "sockconfig";
+#endif
+#if defined (SYS_socket)
+ syscall_table[SYS_socket] = "socket";
+#endif
+#if defined (SYS_socketpair)
+ syscall_table[SYS_socketpair] = "socketpair";
+#endif
+#if defined (SYS_sproc)
+ syscall_table[SYS_sproc] = "sproc";
+#endif
+#if defined (SYS_sprocsp)
+ syscall_table[SYS_sprocsp] = "sprocsp";
+#endif
+#if defined (SYS_sstk)
+ syscall_table[SYS_sstk] = "sstk";
+#endif
+#if defined (SYS_stat)
+ syscall_table[SYS_stat] = "stat";
+#endif
+#if defined (SYS_stat64)
+ syscall_table[SYS_stat64] = "stat64";
+#endif
+#if defined (SYS_statfs)
+ syscall_table[SYS_statfs] = "statfs";
+#endif
+#if defined (SYS_statvfs)
+ syscall_table[SYS_statvfs] = "statvfs";
+#endif
+#if defined (SYS_statvfs64)
+ syscall_table[SYS_statvfs64] = "statvfs64";
+#endif
+#if defined (SYS_stime)
+ syscall_table[SYS_stime] = "stime";
+#endif
+#if defined (SYS_stty)
+ syscall_table[SYS_stty] = "stty";
+#endif
+#if defined (SYS_subsys_info)
+ syscall_table[SYS_subsys_info] = "subsys_info";
+#endif
+#if defined (SYS_swapctl)
+ syscall_table[SYS_swapctl] = "swapctl";
+#endif
+#if defined (SYS_swapon)
+ syscall_table[SYS_swapon] = "swapon";
+#endif
+#if defined (SYS_symlink)
+ syscall_table[SYS_symlink] = "symlink";
+#endif
+#if defined (SYS_sync)
+ syscall_table[SYS_sync] = "sync";
+#endif
+#if defined (SYS_sys3b)
+ syscall_table[SYS_sys3b] = "sys3b";
+#endif
+#if defined (SYS_syscall)
+ syscall_table[SYS_syscall] = "syscall";
+#endif
+#if defined (SYS_sysconfig)
+ syscall_table[SYS_sysconfig] = "sysconfig";
+#endif
+#if defined (SYS_sysfs)
+ syscall_table[SYS_sysfs] = "sysfs";
+#endif
+#if defined (SYS_sysi86)
+ syscall_table[SYS_sysi86] = "sysi86";
+#endif
+#if defined (SYS_sysinfo)
+ syscall_table[SYS_sysinfo] = "sysinfo";
+#endif
+#if defined (SYS_sysmips)
+ syscall_table[SYS_sysmips] = "sysmips";
+#endif
+#if defined (SYS_syssun)
+ syscall_table[SYS_syssun] = "syssun";
+#endif
+#if defined (SYS_systeminfo)
+ syscall_table[SYS_systeminfo] = "systeminfo";
+#endif
+#if defined (SYS_table)
+ syscall_table[SYS_table] = "table";
+#endif
+#if defined (SYS_time)
+ syscall_table[SYS_time] = "time";
+#endif
+#if defined (SYS_timedwait)
+ syscall_table[SYS_timedwait] = "timedwait";
+#endif
+#if defined (SYS_timer_create)
+ syscall_table[SYS_timer_create] = "timer_create";
+#endif
+#if defined (SYS_timer_delete)
+ syscall_table[SYS_timer_delete] = "timer_delete";
+#endif
+#if defined (SYS_timer_getoverrun)
+ syscall_table[SYS_timer_getoverrun] = "timer_getoverrun";
+#endif
+#if defined (SYS_timer_gettime)
+ syscall_table[SYS_timer_gettime] = "timer_gettime";
+#endif
+#if defined (SYS_timer_settime)
+ syscall_table[SYS_timer_settime] = "timer_settime";
+#endif
+#if defined (SYS_times)
+ syscall_table[SYS_times] = "times";
+#endif
+#if defined (SYS_truncate)
+ syscall_table[SYS_truncate] = "truncate";
+#endif
+#if defined (SYS_truncate64)
+ syscall_table[SYS_truncate64] = "truncate64";
+#endif
+#if defined (SYS_tsolsys)
+ syscall_table[SYS_tsolsys] = "tsolsys";
+#endif
+#if defined (SYS_uadmin)
+ syscall_table[SYS_uadmin] = "uadmin";
+#endif
+#if defined (SYS_ulimit)
+ syscall_table[SYS_ulimit] = "ulimit";
+#endif
+#if defined (SYS_umask)
+ syscall_table[SYS_umask] = "umask";
+#endif
+#if defined (SYS_umount)
+ syscall_table[SYS_umount] = "umount";
+#endif
+#if defined (SYS_uname)
+ syscall_table[SYS_uname] = "uname";
+#endif
+#if defined (SYS_unblock)
+ syscall_table[SYS_unblock] = "unblock";
+#endif
+#if defined (SYS_unlink)
+ syscall_table[SYS_unlink] = "unlink";
+#endif
+#if defined (SYS_unmount)
+ syscall_table[SYS_unmount] = "unmount";
+#endif
+#if defined (SYS_usleep_thread)
+ syscall_table[SYS_usleep_thread] = "usleep_thread";
+#endif
+#if defined (SYS_uswitch)
+ syscall_table[SYS_uswitch] = "uswitch";
+#endif
+#if defined (SYS_utc_adjtime)
+ syscall_table[SYS_utc_adjtime] = "utc_adjtime";
+#endif
+#if defined (SYS_utc_gettime)
+ syscall_table[SYS_utc_gettime] = "utc_gettime";
+#endif
+#if defined (SYS_utime)
+ syscall_table[SYS_utime] = "utime";
+#endif
+#if defined (SYS_utimes)
+ syscall_table[SYS_utimes] = "utimes";
+#endif
+#if defined (SYS_utssys)
+ syscall_table[SYS_utssys] = "utssys";
+#endif
+#if defined (SYS_vfork)
+ syscall_table[SYS_vfork] = "vfork";
+#endif
+#if defined (SYS_vhangup)
+ syscall_table[SYS_vhangup] = "vhangup";
+#endif
+#if defined (SYS_vtrace)
+ syscall_table[SYS_vtrace] = "vtrace";
+#endif
+#if defined (SYS_wait)
+ syscall_table[SYS_wait] = "wait";
+#endif
+#if defined (SYS_waitid)
+ syscall_table[SYS_waitid] = "waitid";
+#endif
+#if defined (SYS_waitsys)
+ syscall_table[SYS_waitsys] = "waitsys";
+#endif
+#if defined (SYS_write)
+ syscall_table[SYS_write] = "write";
+#endif
+#if defined (SYS_writev)
+ syscall_table[SYS_writev] = "writev";
+#endif
+#if defined (SYS_xenix)
+ syscall_table[SYS_xenix] = "xenix";
+#endif
+#if defined (SYS_xmknod)
+ syscall_table[SYS_xmknod] = "xmknod";
+#endif
+#if defined (SYS_xstat)
+ syscall_table[SYS_xstat] = "xstat";
+#endif
+#if defined (SYS_yield)
+ syscall_table[SYS_yield] = "yield";
+#endif
+}
+
+/*
+ * Prettyprint a single syscall by number.
+ */
+
+void
+proc_prettyfprint_syscall (FILE *file, int num, int verbose)
+{
+ if (syscall_table[num])
+ fprintf (file, "SYS_%s ", syscall_table[num]);
+ else
+ fprintf (file, "<Unknown syscall %d> ", num);
+}
+
+void
+proc_prettyprint_syscall (int num, int verbose)
+{
+ proc_prettyfprint_syscall (stdout, num, verbose);
+}
+
+/*
+ * Prettyprint all of the syscalls in a sysset_t set.
+ */
+
+void
+proc_prettyfprint_syscalls (FILE *file, sysset_t *sysset, int verbose)
+{
+ int i;
+
+ for (i = 0; i < MAX_SYSCALLS; i++)
+ if (prismember (sysset, i))
+ {
+ proc_prettyfprint_syscall (file, i, verbose);
+ }
+ fprintf (file, "\n");
+}
+
+void
+proc_prettyprint_syscalls (sysset_t *sysset, int verbose)
+{
+ proc_prettyfprint_syscalls (stdout, sysset, verbose);
+}
+
+/* FIXME: add real-time signals */
+
+static struct trans signal_table[] =
+{
+ { 0, "<no signal>", "no signal" },
+#ifdef SIGHUP
+ { SIGHUP, "SIGHUP", "Hangup" },
+#endif
+#ifdef SIGINT
+ { SIGINT, "SIGINT", "Interrupt (rubout)" },
+#endif
+#ifdef SIGQUIT
+ { SIGQUIT, "SIGQUIT", "Quit (ASCII FS)" },
+#endif
+#ifdef SIGILL
+ { SIGILL, "SIGILL", "Illegal instruction" }, /* not reset when caught */
+#endif
+#ifdef SIGTRAP
+ { SIGTRAP, "SIGTRAP", "Trace trap" }, /* not reset when caught */
+#endif
+#ifdef SIGABRT
+ { SIGABRT, "SIGABRT", "used by abort()" }, /* replaces SIGIOT */
+#endif
+#ifdef SIGIOT
+ { SIGIOT, "SIGIOT", "IOT instruction" },
+#endif
+#ifdef SIGEMT
+ { SIGEMT, "SIGEMT", "EMT instruction" },
+#endif
+#ifdef SIGFPE
+ { SIGFPE, "SIGFPE", "Floating point exception" },
+#endif
+#ifdef SIGKILL
+ { SIGKILL, "SIGKILL", "Kill" }, /* Solaris: cannot be caught/ignored */
+#endif
+#ifdef SIGBUS
+ { SIGBUS, "SIGBUS", "Bus error" },
+#endif
+#ifdef SIGSEGV
+ { SIGSEGV, "SIGSEGV", "Segmentation violation" },
+#endif
+#ifdef SIGSYS
+ { SIGSYS, "SIGSYS", "Bad argument to system call" },
+#endif
+#ifdef SIGPIPE
+ { SIGPIPE, "SIGPIPE", "Write to pipe with no one to read it" },
+#endif
+#ifdef SIGALRM
+ { SIGALRM, "SIGALRM", "Alarm clock" },
+#endif
+#ifdef SIGTERM
+ { SIGTERM, "SIGTERM", "Software termination signal from kill" },
+#endif
+#ifdef SIGUSR1
+ { SIGUSR1, "SIGUSR1", "User defined signal 1" },
+#endif
+#ifdef SIGUSR2
+ { SIGUSR2, "SIGUSR2", "User defined signal 2" },
+#endif
+#ifdef SIGCHLD
+ { SIGCHLD, "SIGCHLD", "Child status changed" }, /* Posix version */
+#endif
+#ifdef SIGCLD
+ { SIGCLD, "SIGCLD", "Child status changed" }, /* Solaris version */
+#endif
+#ifdef SIGPWR
+ { SIGPWR, "SIGPWR", "Power-fail restart" },
+#endif
+#ifdef SIGWINCH
+ { SIGWINCH, "SIGWINCH", "Window size change" },
+#endif
+#ifdef SIGURG
+ { SIGURG, "SIGURG", "Urgent socket condition" },
+#endif
+#ifdef SIGPOLL
+ { SIGPOLL, "SIGPOLL", "Pollable event" },
+#endif
+#ifdef SIGIO
+ { SIGIO, "SIGIO", "Socket I/O possible" }, /* alias for SIGPOLL */
+#endif
+#ifdef SIGSTOP
+ { SIGSTOP, "SIGSTOP", "Stop, not from tty" }, /* cannot be caught or ignored */
+#endif
+#ifdef SIGTSTP
+ { SIGTSTP, "SIGTSTP", "User stop from tty" },
+#endif
+#ifdef SIGCONT
+ { SIGCONT, "SIGCONT", "Stopped process has been continued" },
+#endif
+#ifdef SIGTTIN
+ { SIGTTIN, "SIGTTIN", "Background tty read attempted" },
+#endif
+#ifdef SIGTTOU
+ { SIGTTOU, "SIGTTOU", "Background tty write attempted" },
+#endif
+#ifdef SIGVTALRM
+ { SIGVTALRM, "SIGVTALRM", "Virtual timer expired" },
+#endif
+#ifdef SIGPROF
+ { SIGPROF, "SIGPROF", "Profiling timer expired" },
+#endif
+#ifdef SIGXCPU
+ { SIGXCPU, "SIGXCPU", "Exceeded CPU limit" },
+#endif
+#ifdef SIGXFSZ
+ { SIGXFSZ, "SIGXFSZ", "Exceeded file size limit" },
+#endif
+#ifdef SIGWAITING
+ { SIGWAITING, "SIGWAITING", "Process's LWPs are blocked" },
+#endif
+#ifdef SIGLWP
+ { SIGLWP, "SIGLWP", "Used by thread library" },
+#endif
+#ifdef SIGFREEZE
+ { SIGFREEZE, "SIGFREEZE", "Used by CPR" },
+#endif
+#ifdef SIGTHAW
+ { SIGTHAW, "SIGTHAW", "Used by CPR" },
+#endif
+#ifdef SIGCANCEL
+ { SIGCANCEL, "SIGCANCEL", "Used by libthread" },
+#endif
+#ifdef SIGLOST
+ { SIGLOST, "SIGLOST", "Resource lost" },
+#endif
+#ifdef SIG32
+ { SIG32, "SIG32", "Reserved for kernel usage (Irix)" },
+#endif
+#ifdef SIGPTINTR
+ { SIGPTINTR, "SIGPTINTR", "Posix 1003.1b" },
+#endif
+#ifdef SIGTRESCHED
+ { SIGTRESCHED, "SIGTRESCHED", "Posix 1003.1b" },
+#endif
+#ifdef SIGINFO
+ { SIGINFO, "SIGINFO", "Information request" },
+#endif
+#ifdef SIGRESV
+ { SIGRESV, "SIGRESV", "Reserved by Digital for future use" },
+#endif
+#ifdef SIGAIO
+ { SIGAIO, "SIGAIO", "Asynchronous I/O signal" },
+#endif
+};
+
+/*
+ * Prettyprint a single signal by number.
+ * Accepts a signal number and finds it in the signal table,
+ * then pretty-prints it.
+ */
+
+void
+proc_prettyfprint_signal (FILE *file, int signo, int verbose)
+{
+ int i;
+
+ for (i = 0; i < sizeof (signal_table) / sizeof (signal_table[0]); i++)
+ if (signo == signal_table[i].value)
+ {
+ fprintf (file, "%s", signal_table[i].name);
+ if (verbose)
+ fprintf (file, ": %s\n", signal_table[i].desc);
+ else
+ fprintf (file, " ");
+ return;
+ }
+ fprintf (file, "Unknown signal %d%c", signo, verbose ? '\n' : ' ');
+}
+
+void
+proc_prettyprint_signal (int signo, int verbose)
+{
+ proc_prettyfprint_signal (stdout, signo, verbose);
+}
+
+/*
+ * Prettyprint all of the signals in a sigset_t set.
+ *
+ * This function loops over all signal numbers from 0 to NSIG,
+ * uses them as indexes for prismember, and prints them pretty.
+ *
+ * It does not loop over the signal table, as is done with the
+ * fault table, because the signal table may contain aliases.
+ * If it did, both aliases would be printed.
+ */
+
+void
+proc_prettyfprint_signalset (FILE *file, sigset_t *sigset, int verbose)
+{
+ int i;
+
+ for (i = 0; i < NSIG; i++)
+ if (prismember (sigset, i))
+ proc_prettyfprint_signal (file, i, verbose);
+
+ if (!verbose)
+ fprintf (file, "\n");
+}
+
+void
+proc_prettyprint_signalset (sigset_t *sigset, int verbose)
+{
+ proc_prettyfprint_signalset (stdout, sigset, verbose);
+}
+
+/* Hardware fault translation table. */
+
+static struct trans fault_table[] =
+{
+#if defined (FLTILL)
+ { FLTILL, "FLTILL", "Illegal instruction" },
+#endif
+#if defined (FLTPRIV)
+ { FLTPRIV, "FLTPRIV", "Privileged instruction" },
+#endif
+#if defined (FLTBPT)
+ { FLTBPT, "FLTBPT", "Breakpoint trap" },
+#endif
+#if defined (FLTTRACE)
+ { FLTTRACE, "FLTTRACE", "Trace trap" },
+#endif
+#if defined (FLTACCESS)
+ { FLTACCESS, "FLTACCESS", "Memory access fault" },
+#endif
+#if defined (FLTBOUNDS)
+ { FLTBOUNDS, "FLTBOUNDS", "Memory bounds violation" },
+#endif
+#if defined (FLTIOVF)
+ { FLTIOVF, "FLTIOVF", "Integer overflow" },
+#endif
+#if defined (FLTIZDIV)
+ { FLTIZDIV, "FLTIZDIV", "Integer zero divide" },
+#endif
+#if defined (FLTFPE)
+ { FLTFPE, "FLTFPE", "Floating-point exception" },
+#endif
+#if defined (FLTSTACK)
+ { FLTSTACK, "FLTSTACK", "Unrecoverable stack fault" },
+#endif
+#if defined (FLTPAGE)
+ { FLTPAGE, "FLTPAGE", "Recoverable page fault" },
+#endif
+#if defined (FLTPCINVAL)
+ { FLTPCINVAL, "FLTPCINVAL", "Invalid PC exception" },
+#endif
+#if defined (FLTWATCH)
+ { FLTWATCH, "FLTWATCH", "User watchpoint" },
+#endif
+#if defined (FLTKWATCH)
+ { FLTKWATCH, "FLTKWATCH", "Kernel watchpoint" },
+#endif
+#if defined (FLTSCWATCH)
+ { FLTSCWATCH, "FLTSCWATCH", "Hit a store conditional on a watched page" },
+#endif
+};
+
+/*
+ * Work horse. Accepts an index into the fault table, prints it pretty.
+ */
+
+static void
+prettyfprint_faulttable_entry (FILE *file, int i, int verbose)
+{
+ fprintf (file, "%s", fault_table[i].name);
+ if (verbose)
+ fprintf (file, ": %s\n", fault_table[i].desc);
+ else
+ fprintf (file, " ");
+}
+
+/*
+ * Prettyprint a hardware fault by number.
+ */
+
+void
+proc_prettyfprint_fault (FILE *file, int faultno, int verbose)
+{
+ int i;
+
+ for (i = 0; i < sizeof (fault_table) / sizeof (fault_table[0]); i++)
+ if (faultno == fault_table[i].value)
+ {
+ prettyfprint_faulttable_entry (file, i, verbose);
+ return;
+ }
+
+ fprintf (file, "Unknown hardware fault %d%c",
+ faultno, verbose ? '\n' : ' ');
+}
+
+void
+proc_prettyprint_fault (int faultno, int verbose)
+{
+ proc_prettyfprint_fault (stdout, faultno, verbose);
+}
+
+/*
+ * Prettyprint all the faults in a fltset_t set.
+ *
+ * This function loops thru the fault table,
+ * using the value field as the index to prismember.
+ * The fault table had better not contain aliases,
+ * for if it does they will both be printed.
+ */
+
+void
+proc_prettyfprint_faultset (FILE *file, fltset_t *fltset, int verbose)
+{
+ int i;
+
+ for (i = 0; i < sizeof (fault_table) / sizeof (fault_table[0]); i++)
+ if (prismember (fltset, fault_table[i].value))
+ prettyfprint_faulttable_entry (file, i, verbose);
+
+ if (!verbose)
+ fprintf (file, "\n");
+}
+
+void
+proc_prettyprint_faultset (fltset_t *fltset, int verbose)
+{
+ proc_prettyfprint_faultset (stdout, fltset, verbose);
+}
+
+/*
+ * Todo: actions, holds...
+ */
+
+void
+proc_prettyprint_actionset (struct sigaction *actions, int verbose)
+{
+}
+
+void
+_initialize_proc_events (void)
+{
+ init_syscall_table ();
+}
diff --git a/gdb/proc-flags.c b/gdb/proc-flags.c
new file mode 100644
index 00000000000..6e737d11261
--- /dev/null
+++ b/gdb/proc-flags.c
@@ -0,0 +1,291 @@
+/* Machine independent support for SVR4 /proc (process file system) for GDB.
+ Copyright 1999, 2000 Free Software Foundation, Inc.
+ Written by Michael Snyder at Cygnus Solutions.
+ Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
+
+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. */
+
+/*
+ * Pretty-print the prstatus flags.
+ *
+ * Arguments: unsigned long flags, int verbose
+ *
+ */
+
+#include "defs.h"
+
+#if defined (NEW_PROC_API)
+#define _STRUCTURED_PROC 1
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/procfs.h>
+
+/* Much of the information used in the /proc interface, particularly for
+ printing status information, is kept as tables of structures of the
+ following form. These tables can be used to map numeric values to
+ their symbolic names and to a string that describes their specific use. */
+
+struct trans {
+ int value; /* The numeric value */
+ char *name; /* The equivalent symbolic value */
+ char *desc; /* Short description of value */
+};
+
+/* Translate bits in the pr_flags member of the prstatus structure,
+ into the names and desc information. */
+
+static struct trans pr_flag_table[] =
+{
+#if defined (PR_STOPPED)
+ /* Sol2.5: lwp is stopped
+ * Sol2.6: lwp is stopped
+ * Sol2.7: lwp is stopped
+ * IRIX6: process is stopped
+ * OSF: task/thread is stopped
+ * UW: LWP is stopped
+ */
+ { PR_STOPPED, "PR_STOPPED", "Process (LWP) is stopped" },
+#endif
+#if defined (PR_ISTOP)
+ /* Sol2.5: lwp is stopped on an event of interest
+ * Sol2.6: lwp is stopped on an event of interest
+ * Sol2.7: lwp is stopped on an event of interest
+ * IRIX6: process is stopped on event of interest
+ * OSF: task/thread stopped on event of interest
+ * UW: LWP stopped on an event of interest
+ */
+ { PR_ISTOP, "PR_ISTOP", "Stopped on an event of interest" },
+#endif
+#if defined (PR_DSTOP)
+ /* Sol2.5: lwp has a stop directive in effect
+ * Sol2.6: lwp has a stop directive in effect
+ * Sol2.7: lwp has a stop directive in effect
+ * IRIX6: process has stop directive in effect
+ * OSF: task/thread has stop directive in effect
+ * UW: A stop directive is in effect
+ */
+ { PR_DSTOP, "PR_DSTOP", "A stop directive is in effect" },
+#endif
+#if defined (PR_STEP)
+ /* Sol2.5: lwp has a single-step directive in effect
+ * Sol2.6: lwp has a single-step directive in effect
+ * Sol2.7: lwp has a single-step directive in effect
+ * IRIX6: process has single step pending
+ */
+ { PR_STEP, "PR_STEP", "A single step directive is in effect" },
+#endif
+#if defined (PR_ASLEEP)
+ /* Sol2.5: lwp is sleeping in a system call
+ * Sol2.6: lwp is sleeping in a system call
+ * Sol2.7: lwp is sleeping in a system call
+ * IRIX6: process is in an interruptible sleep
+ * OSF: task/thread is asleep within a system call
+ * UW: LWP is sleep()ing in a system call
+ */
+ { PR_ASLEEP, "PR_ASLEEP", "Sleeping in an (interruptible) system call" },
+#endif
+#if defined (PR_PCINVAL)
+ /* Sol2.5: contents of pr_instr undefined
+ * Sol2.6: contents of pr_instr undefined
+ * Sol2.7: contents of pr_instr undefined
+ * IRIX6: current pc is invalid
+ * OSF: program counter contains invalid address
+ * UW: %pc refers to an invalid virtual address
+ */
+ { PR_PCINVAL, "PR_PCINVAL", "PC (pr_instr) is invalid" },
+#endif
+#if defined (PR_ASLWP)
+ /* Sol2.5: this lwp is the aslwp
+ * Sol2.6: this lwp is the aslwp
+ * Sol2.7: this lwp is the aslwp
+ */
+ { PR_ASLWP, "PR_ASLWP", "This is the asynchronous signal LWP" },
+#endif
+#if defined (PR_AGENT)
+ /* Sol2.6: this lwp is the /proc agent lwp
+ * Sol2.7: this lwp is the /proc agent lwp
+ */
+ { PR_AGENT, "PR_AGENT", "This is the /proc agent LWP" },
+#endif
+#if defined (PR_ISSYS)
+ /* Sol2.5: system process
+ * Sol2.6: this is a system process
+ * Sol2.7: this is a system process
+ * IRIX6: process is a system process
+ * OSF: task/thread is a system task/thread
+ * UW: System process
+ */
+ { PR_ISSYS, "PR_ISSYS", "Is a system process/thread" },
+#endif
+#if defined (PR_VFORKP)
+ /* Sol2.6: process is the parent of a vfork()d child
+ * Sol2.7: process is the parent of a vfork()d child
+ */
+ { PR_VFORKP, "PR_VFORKP", "Process is the parent of a vforked child" },
+#endif
+#ifdef PR_ORPHAN
+ /* Sol2.6: process's process group is orphaned
+ * Sol2.7: process's process group is orphaned
+ */
+ { PR_ORPHAN, "PR_ORPHAN", "Process's process group is orphaned" },
+#endif
+#if defined (PR_FORK)
+ /* Sol2.5: inherit-on-fork is in effect
+ * Sol2.6: inherit-on-fork is in effect
+ * Sol2.7: inherit-on-fork is in effect
+ * IRIX6: process has inherit-on-fork flag set
+ * OSF: task/thread has inherit-on-fork flag set
+ * UW: inherit-on-fork is in effect
+ */
+ { PR_FORK, "PR_FORK", "Inherit-on-fork is in effect" },
+#endif
+#if defined (PR_RLC)
+ /* Sol2.5: run-on-last-close is in effect
+ * Sol2.6: run-on-last-close is in effect
+ * Sol2.7: run-on-last-close is in effect
+ * IRIX6: process has run-on-last-close flag set
+ * OSF: task/thread has run-on-last-close flag set
+ * UW: Run-on-last-close is in effect
+ */
+ { PR_RLC, "PR_RLC", "Run-on-last-close is in effect" },
+#endif
+#if defined (PR_KLC)
+ /* Sol2.5: kill-on-last-close is in effect
+ * Sol2.6: kill-on-last-close is in effect
+ * Sol2.7: kill-on-last-close is in effect
+ * IRIX6: process has kill-on-last-close flag set
+ * OSF: kill-on-last-close, superceeds RLC
+ * UW: kill-on-last-close is in effect
+ */
+ { PR_KLC, "PR_KLC", "Kill-on-last-close is in effect" },
+#endif
+#if defined (PR_ASYNC)
+ /* Sol2.5: asynchronous-stop is in effect
+ * Sol2.6: asynchronous-stop is in effect
+ * Sol2.7: asynchronous-stop is in effect
+ * OSF: asynchronous stop mode is in effect
+ * UW: asynchronous stop mode is in effect
+ */
+ { PR_ASYNC, "PR_ASYNC", "Asynchronous stop is in effect" },
+#endif
+#if defined (PR_MSACCT)
+ /* Sol2.5: micro-state usage accounting is in effect
+ * Sol2.6: micro-state usage accounting is in effect
+ * Sol2.7: micro-state usage accounting is in effect
+ */
+ { PR_MSACCT, "PR_MSACCT", "Microstate accounting enabled" },
+#endif
+#if defined (PR_BPTADJ)
+ /* Sol2.5: breakpoint trap pc adjustment is in effect
+ * Sol2.6: breakpoint trap pc adjustment is in effect
+ * Sol2.7: breakpoint trap pc adjustment is in effect
+ */
+ { PR_BPTADJ, "PR_BPTADJ", "Breakpoint PC adjustment in effect" },
+#endif
+#if defined (PR_PTRACE)
+ /* Note: different meanings on Solaris and Irix 6
+ * Sol2.5: obsolete, never set in SunOS5.0
+ * Sol2.6: ptrace-compatibility mode is in effect
+ * Sol2.7: ptrace-compatibility mode is in effect
+ * IRIX6: process is traced with ptrace() too
+ * OSF: task/thread is being traced by ptrace
+ * UW: Process is being controlled by ptrace(2)
+ */
+ { PR_PTRACE, "PR_PTRACE", "Process is being controlled by ptrace" },
+#endif
+#if defined (PR_PCOMPAT)
+ /* Note: PCOMPAT on Sol2.5 means same thing as PTRACE on Sol2.6
+ * Sol2.5 (only): ptrace-compatibility mode is in effect
+ */
+ { PR_PCOMPAT, "PR_PCOMPAT", "Ptrace compatibility mode in effect" },
+#endif
+#ifdef PR_MSFORK
+ /* Sol2.6: micro-state accounting inherited on fork
+ * Sol2.7: micro-state accounting inherited on fork
+ */
+ { PR_MSFORK, "PR_PCOMPAT", "Micro-state accounting inherited on fork" },
+#endif
+
+#ifdef PR_ISKTHREAD
+ /* Irix6: process is a kernel thread */
+ { PR_ISKTHREAD, "PR_KTHREAD", "Process is a kernel thread" },
+#endif
+
+#ifdef PR_ABORT
+ /* OSF (only): abort the current stop condition */
+ { PR_ABORT, "PR_ABORT", "Abort the current stop condition" },
+#endif
+
+#ifdef PR_TRACING
+ /* OSF: task is traced */
+ { PR_TRACING, "PR_TRACING", "Task is traced" },
+#endif
+
+#ifdef PR_STOPFORK
+ /* OSF: stop child on fork */
+ { PR_STOPFORK, "PR_STOPFORK", "Stop child on fork" },
+#endif
+
+#ifdef PR_STOPEXEC
+ /* OSF: stop on exec */
+ { PR_STOPEXEC, "PR_STOPEXEC", "Stop on exec" },
+#endif
+
+#ifdef PR_STOPTERM
+ /* OSF: stop on task exit */
+ { PR_STOPTERM, "PR_STOPTERM", "Stop on task exit" },
+#endif
+
+#ifdef PR_STOPTCR
+ /* OSF: stop on thread creation */
+ { PR_STOPTCR, "PR_STOPTCR", "Stop on thread creation" },
+#endif
+
+#ifdef PR_STOPTTERM
+ /* OSF: stop on thread exit */
+ { PR_STOPTTERM, "PR_STOPTTERM", "Stop on thread exit" },
+#endif
+
+#ifdef PR_USCHED
+ /* OSF: user level scheduling is in effect */
+ { PR_USCHED, "PR_USCHED", "User level scheduling is in effect" },
+#endif
+};
+
+void
+proc_prettyfprint_flags (FILE *file, unsigned long flags, int verbose)
+{
+ int i;
+
+ for (i = 0; i < sizeof (pr_flag_table) / sizeof (pr_flag_table[0]); i++)
+ if (flags & pr_flag_table[i].value)
+ {
+ fprintf (file, "%s ", pr_flag_table[i].name);
+ if (verbose)
+ fprintf (file, "%s\n", pr_flag_table[i].desc);
+ }
+ if (!verbose)
+ fprintf (file, "\n");
+}
+
+void
+proc_prettyprint_flags (unsigned long flags, int verbose)
+{
+ proc_prettyfprint_flags (stdout, flags, verbose);
+}
diff --git a/gdb/proc-service.c b/gdb/proc-service.c
new file mode 100644
index 00000000000..d7cd1aaf91b
--- /dev/null
+++ b/gdb/proc-service.c
@@ -0,0 +1,312 @@
+/* <proc_service.h> implementation.
+
+ Copyright 1999, 2000, 2002 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 "defs.h"
+
+#include "gdb_proc_service.h"
+#include <sys/procfs.h>
+
+#include "inferior.h"
+#include "symtab.h"
+#include "target.h"
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+
+/* Fix-up some broken systems. */
+
+/* The prototypes in <proc_service.h> are slightly different on older
+ systems. Compensate for the discrepancies. */
+
+#ifdef PROC_SERVICE_IS_OLD
+typedef const struct ps_prochandle *gdb_ps_prochandle_t;
+typedef char *gdb_ps_read_buf_t;
+typedef char *gdb_ps_write_buf_t;
+typedef int gdb_ps_size_t;
+#else
+typedef struct ps_prochandle *gdb_ps_prochandle_t;
+typedef void *gdb_ps_read_buf_t;
+typedef const void *gdb_ps_write_buf_t;
+typedef size_t gdb_ps_size_t;
+#endif
+
+
+/* Building process ids. */
+
+#define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
+
+
+/* Helper functions. */
+
+/* Transfer LEN bytes of memory between BUF and address ADDR in the
+ process specified by PH. If WRITE, transfer them to the process,
+ else transfer them from the process. Returns PS_OK for success,
+ PS_ERR on failure.
+
+ This is a helper function for ps_pdread, ps_pdwrite, ps_ptread and
+ ps_ptwrite. */
+
+static ps_err_e
+ps_xfer_memory (const struct ps_prochandle *ph, paddr_t addr,
+ char *buf, size_t len, int write)
+{
+ struct cleanup *old_chain = save_inferior_ptid ();
+ int ret;
+
+ inferior_ptid = pid_to_ptid (ph->pid);
+
+ if (write)
+ ret = target_write_memory (addr, buf, len);
+ else
+ ret = target_read_memory (addr, buf, len);
+
+ do_cleanups (old_chain);
+
+ return (ret == 0 ? PS_OK : PS_ERR);
+}
+
+
+/* Stop the target process PH. */
+
+ps_err_e
+ps_pstop (gdb_ps_prochandle_t ph)
+{
+ /* The process is always stopped when under control of GDB. */
+ return PS_OK;
+}
+
+/* Resume the target process PH. */
+
+ps_err_e
+ps_pcontinue (gdb_ps_prochandle_t ph)
+{
+ /* Pretend we did successfully continue the process. GDB will take
+ care of it later on. */
+ return PS_OK;
+}
+
+/* Stop the lightweight process LWPID within the target process PH. */
+
+ps_err_e
+ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
+{
+ /* All lightweight processes are stopped when under control of GDB. */
+ return PS_OK;
+}
+
+/* Resume the lightweight process (LWP) LWPID within the target
+ process PH. */
+
+ps_err_e
+ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
+{
+ /* Pretend we did successfully continue LWPID. GDB will take care
+ of it later on. */
+ return PS_OK;
+}
+
+/* Get the size of the architecture-dependent extra state registers
+ for LWP LWPID within the target process PH and return it in
+ *XREGSIZE. */
+
+ps_err_e
+ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
+{
+ /* FIXME: Not supported yet. */
+ return PS_OK;
+}
+
+/* Get the extra state registers of LWP LWPID within the target
+ process PH and store them in XREGSET. */
+
+ps_err_e
+ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
+{
+ /* FIXME: Not supported yet. */
+ return PS_OK;
+}
+
+/* Set the extra state registers of LWP LWPID within the target
+ process PH from XREGSET. */
+
+ps_err_e
+ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
+{
+ /* FIXME: Not supported yet. */
+ return PS_OK;
+}
+
+/* Log (additional) diognostic information. */
+
+void
+ps_plog (const char *fmt, ...)
+{
+ va_list args;
+
+ va_start (args, fmt);
+ vfprintf_filtered (gdb_stderr, fmt, args);
+}
+
+/* Search for the symbol named NAME within the object named OBJ within
+ the target process PH. If the symbol is found the address of the
+ symbol is stored in SYM_ADDR. */
+
+ps_err_e
+ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *obj,
+ const char *name, paddr_t *sym_addr)
+{
+ struct minimal_symbol *ms;
+
+ /* FIXME: kettenis/2000-09-03: What should we do with OBJ? */
+ ms = lookup_minimal_symbol (name, NULL, NULL);
+ if (ms == NULL)
+ return PS_NOSYM;
+
+ *sym_addr = SYMBOL_VALUE_ADDRESS (ms);
+ return PS_OK;
+}
+
+/* Read SIZE bytes from the target process PH at address ADDR and copy
+ them into BUF. */
+
+ps_err_e
+ps_pdread (gdb_ps_prochandle_t ph, paddr_t addr,
+ gdb_ps_read_buf_t buf, gdb_ps_size_t size)
+{
+ return ps_xfer_memory (ph, addr, buf, size, 0);
+}
+
+/* Write SIZE bytes from BUF into the target process PH at address ADDR. */
+
+ps_err_e
+ps_pdwrite (gdb_ps_prochandle_t ph, paddr_t addr,
+ gdb_ps_write_buf_t buf, gdb_ps_size_t size)
+{
+ return ps_xfer_memory (ph, addr, (char *) buf, size, 1);
+}
+
+/* Read SIZE bytes from the target process PH at address ADDR and copy
+ them into BUF. */
+
+ps_err_e
+ps_ptread (gdb_ps_prochandle_t ph, paddr_t addr,
+ gdb_ps_read_buf_t buf, gdb_ps_size_t size)
+{
+ return ps_xfer_memory (ph, addr, buf, size, 0);
+}
+
+/* Write SIZE bytes from BUF into the target process PH at address ADDR. */
+
+ps_err_e
+ps_ptwrite (gdb_ps_prochandle_t ph, paddr_t addr,
+ gdb_ps_write_buf_t buf, gdb_ps_size_t size)
+{
+ return ps_xfer_memory (ph, addr, (char *) buf, size, 1);
+}
+
+/* Get the general registers of LWP LWPID within the target process PH
+ and store them in GREGSET. */
+
+ps_err_e
+ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
+{
+ struct cleanup *old_chain = save_inferior_ptid ();
+
+ inferior_ptid = BUILD_LWP (lwpid, ph->pid);
+
+ target_fetch_registers (-1);
+ fill_gregset ((gdb_gregset_t *) gregset, -1);
+
+ do_cleanups (old_chain);
+ return PS_OK;
+}
+
+/* Set the general registers of LWP LWPID within the target process PH
+ from GREGSET. */
+
+ps_err_e
+ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, const prgregset_t gregset)
+{
+ struct cleanup *old_chain = save_inferior_ptid ();
+
+ inferior_ptid = BUILD_LWP (lwpid, ph->pid);
+
+ /* FIXME: We should really make supply_gregset const-correct. */
+ supply_gregset ((gdb_gregset_t *) gregset);
+ target_store_registers (-1);
+
+ do_cleanups (old_chain);
+ return PS_OK;
+}
+
+/* Get the floating-point registers of LWP LWPID within the target
+ process PH and store them in FPREGSET. */
+
+ps_err_e
+ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+ gdb_prfpregset_t *fpregset)
+{
+ struct cleanup *old_chain = save_inferior_ptid ();
+
+ inferior_ptid = BUILD_LWP (lwpid, ph->pid);
+
+ target_fetch_registers (-1);
+ fill_fpregset ((gdb_fpregset_t *) fpregset, -1);
+
+ do_cleanups (old_chain);
+ return PS_OK;
+}
+
+/* Set the floating-point registers of LWP LWPID within the target
+ process PH from FPREGSET. */
+
+ps_err_e
+ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+ const gdb_prfpregset_t *fpregset)
+{
+ struct cleanup *old_chain = save_inferior_ptid ();
+
+ inferior_ptid = BUILD_LWP (lwpid, ph->pid);
+
+ /* FIXME: We should really make supply_fpregset const-correct. */
+ supply_fpregset ((gdb_fpregset_t *) fpregset);
+ target_store_registers (-1);
+
+ do_cleanups (old_chain);
+ return PS_OK;
+}
+
+/* Return overall process id of the target PH. Special for GNU/Linux
+ -- not used on Solaris. */
+
+pid_t
+ps_getpid (gdb_ps_prochandle_t ph)
+{
+ return ph->pid;
+}
+
+void
+_initialize_proc_service (void)
+{
+ /* This function solely exists to make sure this module is linked
+ into the final binary. */
+}
diff --git a/gdb/proc-utils.h b/gdb/proc-utils.h
new file mode 100644
index 00000000000..1c419649184
--- /dev/null
+++ b/gdb/proc-utils.h
@@ -0,0 +1,102 @@
+/* Machine independent support for SVR4 /proc (process file system) for GDB.
+ Copyright 1999, 2000 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. */
+
+
+/*
+ * Pretty-print functions for /proc data
+ */
+
+extern void
+proc_prettyprint_why (unsigned long why, unsigned long what, int verbose);
+
+extern void
+proc_prettyprint_syscalls (sysset_t *sysset, int verbose);
+
+extern void
+proc_prettyprint_syscall (int num, int verbose);
+
+extern void proc_prettyprint_flags (unsigned long flags, int verbose);
+
+extern void
+proc_prettyfprint_signalset (FILE *file, sigset_t *sigset, int verbose);
+
+extern void
+proc_prettyfprint_faultset (FILE *file, fltset_t *fltset, int verbose);
+
+extern void
+proc_prettyfprint_syscall (FILE *file, int num, int verbose);
+
+extern void
+proc_prettyfprint_signal (FILE *file, int signo, int verbose);
+
+extern void
+proc_prettyfprint_flags (FILE *file, unsigned long flags, int verbose);
+
+extern void
+proc_prettyfprint_why (FILE *file, unsigned long why,
+ unsigned long what, int verbose);
+
+extern void
+proc_prettyfprint_fault (FILE *file, int faultno, int verbose);
+
+extern void
+proc_prettyfprint_syscalls (FILE *file, sysset_t *sysset, int verbose);
+
+extern void
+proc_prettyfprint_status (long, int, int, int);
+
+/*
+ * Trace functions for /proc api.
+ */
+
+extern int write_with_trace (int, void *, size_t, char *, int);
+extern off_t lseek_with_trace (int, off_t, int, char *, int);
+extern int ioctl_with_trace (int, long, void *, char *, int);
+extern pid_t wait_with_trace (int *, char *, int);
+extern int open_with_trace (char *, int, char *, int);
+extern int close_with_trace (int, char *, int);
+extern void procfs_note (char *, char *, int);
+
+#ifdef PROCFS_TRACE
+/*
+ * Debugging code:
+ *
+ * These macros allow me to trace the system calls that we make
+ * to control the child process. This is quite handy for comparing
+ * with the older version of procfs.
+ */
+
+#define write(X,Y,Z) write_with_trace (X, Y, Z, __FILE__, __LINE__)
+#define lseek(X,Y,Z) lseek_with_trace (X, Y, Z, __FILE__, __LINE__)
+#define ioctl(X,Y,Z) ioctl_with_trace (X, Y, Z, __FILE__, __LINE__)
+#define open(X,Y) open_with_trace (X, Y, __FILE__, __LINE__)
+#define close(X) close_with_trace (X, __FILE__, __LINE__)
+#define wait(X) wait_with_trace (X, __FILE__, __LINE__)
+#endif
+#define PROCFS_NOTE(X) procfs_note (X, __FILE__, __LINE__)
+#define PROC_PRETTYFPRINT_STATUS(X,Y,Z,T) \
+ proc_prettyfprint_status (X, Y, Z, T)
+
+/* Define the type (and more importantly the width) of the control
+ word used to write to the /proc/PID/ctl file. */
+#if defined (PROC_CTL_WORD_TYPE)
+typedef PROC_CTL_WORD_TYPE procfs_ctl_t;
+#else
+typedef long procfs_ctl_t;
+#endif
diff --git a/gdb/proc-why.c b/gdb/proc-why.c
new file mode 100644
index 00000000000..15af16cb171
--- /dev/null
+++ b/gdb/proc-why.c
@@ -0,0 +1,175 @@
+/* Machine independent support for SVR4 /proc (process file system) for GDB.
+ Copyright 1999, 2000 Free Software Foundation, Inc.
+ Written by Michael Snyder at Cygnus Solutions.
+ Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
+
+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. */
+
+/*
+ * Pretty-print the pr_why value.
+ *
+ * Arguments: unsigned long flags, int verbose
+ *
+ */
+
+#include "defs.h"
+
+#if defined(NEW_PROC_API)
+#define _STRUCTURED_PROC 1
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/procfs.h>
+
+#include "proc-utils.h"
+
+/* Much of the information used in the /proc interface, particularly for
+ printing status information, is kept as tables of structures of the
+ following form. These tables can be used to map numeric values to
+ their symbolic names and to a string that describes their specific use. */
+
+struct trans {
+ int value; /* The numeric value */
+ char *name; /* The equivalent symbolic value */
+ char *desc; /* Short description of value */
+};
+
+/* Translate values in the pr_why field of the prstatus struct. */
+
+static struct trans pr_why_table[] =
+{
+#if defined (PR_REQUESTED)
+ /* All platforms */
+ { PR_REQUESTED, "PR_REQUESTED",
+ "Directed to stop by debugger via P(IO)CSTOP or P(IO)CWSTOP" },
+#endif
+#if defined (PR_SIGNALLED)
+ /* All platforms */
+ { PR_SIGNALLED, "PR_SIGNALLED", "Receipt of a traced signal" },
+#endif
+#if defined (PR_SYSENTRY)
+ /* All platforms */
+ { PR_SYSENTRY, "PR_SYSENTRY", "Entry to a traced system call" },
+#endif
+#if defined (PR_SYSEXIT)
+ /* All platforms */
+ { PR_SYSEXIT, "PR_SYSEXIT", "Exit from a traced system call" },
+#endif
+#if defined (PR_JOBCONTROL)
+ /* All platforms */
+ { PR_JOBCONTROL, "PR_JOBCONTROL", "Default job control stop signal action" },
+#endif
+#if defined (PR_FAULTED)
+ /* All platforms */
+ { PR_FAULTED, "PR_FAULTED", "Incurred a traced hardware fault" },
+#endif
+#if defined (PR_SUSPENDED)
+ /* Solaris and UnixWare */
+ { PR_SUSPENDED, "PR_SUSPENDED", "Process suspended" },
+#endif
+#if defined (PR_CHECKPOINT)
+ /* Solaris only */
+ { PR_CHECKPOINT, "PR_CHECKPOINT", "Process stopped at checkpoint" },
+#endif
+#if defined (PR_FORKSTOP)
+ /* OSF only */
+ { PR_FORKSTOP, "PR_FORKSTOP", "Process stopped at end of fork call" },
+#endif
+#if defined (PR_TCRSTOP)
+ /* OSF only */
+ { PR_TCRSTOP, "PR_TCRSTOP", "Process stopped on thread creation" },
+#endif
+#if defined (PR_TTSTOP)
+ /* OSF only */
+ { PR_TTSTOP, "PR_TTSTOP", "Process stopped on thread termination" },
+#endif
+#if defined (PR_DEAD)
+ /* OSF only */
+ { PR_DEAD, "PR_DEAD", "Process stopped in exit system call" },
+#endif
+};
+
+void
+proc_prettyfprint_why (FILE *file, unsigned long why, unsigned long what,
+ int verbose)
+{
+ int i;
+
+ if (why == 0)
+ return;
+
+ for (i = 0; i < sizeof (pr_why_table) / sizeof (pr_why_table[0]); i++)
+ if (why == pr_why_table[i].value)
+ {
+ fprintf (file, "%s ", pr_why_table[i].name);
+ if (verbose)
+ fprintf (file, ": %s ", pr_why_table[i].desc);
+
+ switch (why) {
+#ifdef PR_REQUESTED
+ case PR_REQUESTED:
+ break; /* Nothing more to print. */
+#endif
+#ifdef PR_SIGNALLED
+ case PR_SIGNALLED:
+ proc_prettyfprint_signal (file, what, verbose);
+ break;
+#endif
+#ifdef PR_FAULTED
+ case PR_FAULTED:
+ proc_prettyfprint_fault (file, what, verbose);
+ break;
+#endif
+#ifdef PR_SYSENTRY
+ case PR_SYSENTRY:
+ fprintf (file, "Entry to ");
+ proc_prettyfprint_syscall (file, what, verbose);
+ break;
+#endif
+#ifdef PR_SYSEXIT
+ case PR_SYSEXIT:
+ fprintf (file, "Exit from ");
+ proc_prettyfprint_syscall (file, what, verbose);
+ break;
+#endif
+#ifdef PR_JOBCONTROL
+ case PR_JOBCONTROL:
+ proc_prettyfprint_signal (file, what, verbose);
+ break;
+#endif
+#ifdef PR_DEAD
+ case PR_DEAD:
+ fprintf (file, "Exit status: %d\n", what);
+ break;
+#endif
+ default:
+ fprintf (file, "Unknown why %ld, what %ld\n", why, what);
+ break;
+ }
+ fprintf (file, "\n");
+
+ return;
+ }
+ fprintf (file, "Unknown pr_why.\n");
+}
+
+void
+proc_prettyprint_why (unsigned long why, unsigned long what, int verbose)
+{
+ proc_prettyfprint_why (stdout, why, what, verbose);
+}
diff --git a/gdb/process_reply.defs b/gdb/process_reply.defs
new file mode 100644
index 00000000000..824b5c65c2e
--- /dev/null
+++ b/gdb/process_reply.defs
@@ -0,0 +1 @@
+#include <hurd/process_reply.defs>
diff --git a/gdb/procfs.c b/gdb/procfs.c
new file mode 100644
index 00000000000..55e0496bc78
--- /dev/null
+++ b/gdb/procfs.c
@@ -0,0 +1,5857 @@
+/* Machine independent support for SVR4 /proc (process file system) for GDB.
+ Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Written by Michael Snyder at Cygnus Solutions.
+ Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
+
+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 "defs.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "elf-bfd.h" /* for elfcore_write_* */
+#include "gdbcmd.h"
+#include "gdbthread.h"
+
+#if defined (NEW_PROC_API)
+#define _STRUCTURED_PROC 1 /* Should be done by configure script. */
+#endif
+
+#include <sys/procfs.h>
+#ifdef HAVE_SYS_FAULT_H
+#include <sys/fault.h>
+#endif
+#ifdef HAVE_SYS_SYSCALL_H
+#include <sys/syscall.h>
+#endif
+#include <sys/errno.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <ctype.h>
+
+/*
+ * PROCFS.C
+ *
+ * This module provides the interface between GDB and the
+ * /proc file system, which is used on many versions of Unix
+ * as a means for debuggers to control other processes.
+ * Examples of the systems that use this interface are:
+ * Irix
+ * Solaris
+ * OSF
+ * Unixware
+ * AIX5
+ *
+ * /proc works by imitating a file system: you open a simulated file
+ * that represents the process you wish to interact with, and
+ * perform operations on that "file" in order to examine or change
+ * the state of the other process.
+ *
+ * The most important thing to know about /proc and this module
+ * is that there are two very different interfaces to /proc:
+ * One that uses the ioctl system call, and
+ * another that uses read and write system calls.
+ * This module has to support both /proc interfaces. This means
+ * that there are two different ways of doing every basic operation.
+ *
+ * In order to keep most of the code simple and clean, I have
+ * defined an interface "layer" which hides all these system calls.
+ * An ifdef (NEW_PROC_API) determines which interface we are using,
+ * and most or all occurrances of this ifdef should be confined to
+ * this interface layer.
+ */
+
+
+/* Determine which /proc API we are using:
+ The ioctl API defines PIOCSTATUS, while
+ the read/write (multiple fd) API never does. */
+
+#ifdef NEW_PROC_API
+#include <sys/types.h>
+#include "gdb_dirent.h" /* opendir/readdir, for listing the LWP's */
+#endif
+
+#include <fcntl.h> /* for O_RDONLY */
+#include <unistd.h> /* for "X_OK" */
+#include "gdb_stat.h" /* for struct stat */
+
+/* Note: procfs-utils.h must be included after the above system header
+ files, because it redefines various system calls using macros.
+ This may be incompatible with the prototype declarations. */
+
+#include "proc-utils.h"
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* =================== TARGET_OPS "MODULE" =================== */
+
+/*
+ * This module defines the GDB target vector and its methods.
+ */
+
+static void procfs_open (char *, int);
+static void procfs_attach (char *, int);
+static void procfs_detach (char *, int);
+static void procfs_resume (ptid_t, int, enum target_signal);
+static int procfs_can_run (void);
+static void procfs_stop (void);
+static void procfs_files_info (struct target_ops *);
+static void procfs_fetch_registers (int);
+static void procfs_store_registers (int);
+static void procfs_notice_signals (ptid_t);
+static void procfs_prepare_to_store (void);
+static void procfs_kill_inferior (void);
+static void procfs_mourn_inferior (void);
+static void procfs_create_inferior (char *, char *, char **);
+static ptid_t procfs_wait (ptid_t, struct target_waitstatus *);
+static int procfs_xfer_memory (CORE_ADDR, char *, int, int,
+ struct mem_attrib *attrib,
+ struct target_ops *);
+
+static int procfs_thread_alive (ptid_t);
+
+void procfs_find_new_threads (void);
+char *procfs_pid_to_str (ptid_t);
+
+static int proc_find_memory_regions (int (*) (CORE_ADDR,
+ unsigned long,
+ int, int, int,
+ void *),
+ void *);
+
+static char * procfs_make_note_section (bfd *, int *);
+
+struct target_ops procfs_ops; /* the target vector */
+
+static void
+init_procfs_ops (void)
+{
+ procfs_ops.to_shortname = "procfs";
+ procfs_ops.to_longname = "Unix /proc child process";
+ procfs_ops.to_doc =
+ "Unix /proc child process (started by the \"run\" command).";
+ procfs_ops.to_open = procfs_open;
+ procfs_ops.to_can_run = procfs_can_run;
+ procfs_ops.to_create_inferior = procfs_create_inferior;
+ procfs_ops.to_kill = procfs_kill_inferior;
+ procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
+ procfs_ops.to_attach = procfs_attach;
+ procfs_ops.to_detach = procfs_detach;
+ procfs_ops.to_wait = procfs_wait;
+ procfs_ops.to_resume = procfs_resume;
+ procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
+ procfs_ops.to_fetch_registers = procfs_fetch_registers;
+ procfs_ops.to_store_registers = procfs_store_registers;
+ procfs_ops.to_xfer_memory = procfs_xfer_memory;
+ procfs_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ procfs_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ procfs_ops.to_notice_signals = procfs_notice_signals;
+ procfs_ops.to_files_info = procfs_files_info;
+ procfs_ops.to_stop = procfs_stop;
+
+ procfs_ops.to_terminal_init = terminal_init_inferior;
+ procfs_ops.to_terminal_inferior = terminal_inferior;
+ procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ procfs_ops.to_terminal_ours = terminal_ours;
+ procfs_ops.to_terminal_info = child_terminal_info;
+
+ procfs_ops.to_find_new_threads = procfs_find_new_threads;
+ procfs_ops.to_thread_alive = procfs_thread_alive;
+ procfs_ops.to_pid_to_str = procfs_pid_to_str;
+
+ procfs_ops.to_has_all_memory = 1;
+ procfs_ops.to_has_memory = 1;
+ procfs_ops.to_has_execution = 1;
+ procfs_ops.to_has_stack = 1;
+ procfs_ops.to_has_registers = 1;
+ procfs_ops.to_stratum = process_stratum;
+ procfs_ops.to_has_thread_control = tc_schedlock;
+ procfs_ops.to_find_memory_regions = proc_find_memory_regions;
+ procfs_ops.to_make_corefile_notes = procfs_make_note_section;
+ procfs_ops.to_magic = OPS_MAGIC;
+}
+
+/* =================== END, TARGET_OPS "MODULE" =================== */
+
+/*
+ * World Unification:
+ *
+ * Put any typedefs, defines etc. here that are required for
+ * the unification of code that handles different versions of /proc.
+ */
+
+#ifdef NEW_PROC_API /* Solaris 7 && 8 method for watchpoints */
+#ifdef WA_READ
+ enum { READ_WATCHFLAG = WA_READ,
+ WRITE_WATCHFLAG = WA_WRITE,
+ EXEC_WATCHFLAG = WA_EXEC,
+ AFTER_WATCHFLAG = WA_TRAPAFTER
+ };
+#endif
+#else /* Irix method for watchpoints */
+ enum { READ_WATCHFLAG = MA_READ,
+ WRITE_WATCHFLAG = MA_WRITE,
+ EXEC_WATCHFLAG = MA_EXEC,
+ AFTER_WATCHFLAG = 0 /* trapafter not implemented */
+ };
+#endif
+
+/* gdb_sigset_t */
+#ifdef HAVE_PR_SIGSET_T
+typedef pr_sigset_t gdb_sigset_t;
+#else
+typedef sigset_t gdb_sigset_t;
+#endif
+
+/* sigaction */
+#ifdef HAVE_PR_SIGACTION64_T
+typedef pr_sigaction64_t gdb_sigaction_t;
+#else
+typedef struct sigaction gdb_sigaction_t;
+#endif
+
+/* siginfo */
+#ifdef HAVE_PR_SIGINFO64_T
+typedef pr_siginfo64_t gdb_siginfo_t;
+#else
+typedef struct siginfo gdb_siginfo_t;
+#endif
+
+/* gdb_premptysysset */
+#ifdef premptysysset
+#define gdb_premptysysset premptysysset
+#else
+#define gdb_premptysysset premptyset
+#endif
+
+/* praddsysset */
+#ifdef praddsysset
+#define gdb_praddsysset praddsysset
+#else
+#define gdb_praddsysset praddset
+#endif
+
+/* prdelsysset */
+#ifdef prdelsysset
+#define gdb_prdelsysset prdelsysset
+#else
+#define gdb_prdelsysset prdelset
+#endif
+
+/* prissyssetmember */
+#ifdef prissyssetmember
+#define gdb_pr_issyssetmember prissyssetmember
+#else
+#define gdb_pr_issyssetmember prismember
+#endif
+
+/* As a feature test, saying ``#if HAVE_PRSYSENT_T'' everywhere isn't
+ as intuitively descriptive as it could be, so we'll define
+ DYNAMIC_SYSCALLS to mean the same thing. Anyway, at the time of
+ this writing, this feature is only found on AIX5 systems and
+ basically means that the set of syscalls is not fixed. I.e,
+ there's no nice table that one can #include to get all of the
+ syscall numbers. Instead, they're stored in /proc/PID/sysent
+ for each process. We are at least guaranteed that they won't
+ change over the lifetime of the process. But each process could
+ (in theory) have different syscall numbers.
+*/
+#ifdef HAVE_PRSYSENT_T
+#define DYNAMIC_SYSCALLS
+#endif
+
+
+
+/* =================== STRUCT PROCINFO "MODULE" =================== */
+
+ /* FIXME: this comment will soon be out of date W.R.T. threads. */
+
+/* The procinfo struct is a wrapper to hold all the state information
+ concerning a /proc process. There should be exactly one procinfo
+ for each process, and since GDB currently can debug only one
+ process at a time, that means there should be only one procinfo.
+ All of the LWP's of a process can be accessed indirectly thru the
+ single process procinfo.
+
+ However, against the day when GDB may debug more than one process,
+ this data structure is kept in a list (which for now will hold no
+ more than one member), and many functions will have a pointer to a
+ procinfo as an argument.
+
+ There will be a separate procinfo structure for use by the (not yet
+ implemented) "info proc" command, so that we can print useful
+ information about any random process without interfering with the
+ inferior's procinfo information. */
+
+#ifdef NEW_PROC_API
+/* format strings for /proc paths */
+# ifndef CTL_PROC_NAME_FMT
+# define MAIN_PROC_NAME_FMT "/proc/%d"
+# define CTL_PROC_NAME_FMT "/proc/%d/ctl"
+# define AS_PROC_NAME_FMT "/proc/%d/as"
+# define MAP_PROC_NAME_FMT "/proc/%d/map"
+# define STATUS_PROC_NAME_FMT "/proc/%d/status"
+# define MAX_PROC_NAME_SIZE sizeof("/proc/99999/lwp/8096/lstatus")
+# endif
+/* the name of the proc status struct depends on the implementation */
+typedef pstatus_t gdb_prstatus_t;
+typedef lwpstatus_t gdb_lwpstatus_t;
+#else /* ! NEW_PROC_API */
+/* format strings for /proc paths */
+# ifndef CTL_PROC_NAME_FMT
+# define MAIN_PROC_NAME_FMT "/proc/%05d"
+# define CTL_PROC_NAME_FMT "/proc/%05d"
+# define AS_PROC_NAME_FMT "/proc/%05d"
+# define MAP_PROC_NAME_FMT "/proc/%05d"
+# define STATUS_PROC_NAME_FMT "/proc/%05d"
+# define MAX_PROC_NAME_SIZE sizeof("/proc/ttttppppp")
+# endif
+/* the name of the proc status struct depends on the implementation */
+typedef prstatus_t gdb_prstatus_t;
+typedef prstatus_t gdb_lwpstatus_t;
+#endif /* NEW_PROC_API */
+
+typedef struct procinfo {
+ struct procinfo *next;
+ int pid; /* Process ID */
+ int tid; /* Thread/LWP id */
+
+ /* process state */
+ int was_stopped;
+ int ignore_next_sigstop;
+
+ /* The following four fd fields may be identical, or may contain
+ several different fd's, depending on the version of /proc
+ (old ioctl or new read/write). */
+
+ int ctl_fd; /* File descriptor for /proc control file */
+ /*
+ * The next three file descriptors are actually only needed in the
+ * read/write, multiple-file-descriptor implemenation (NEW_PROC_API).
+ * However, to avoid a bunch of #ifdefs in the code, we will use
+ * them uniformly by (in the case of the ioctl single-file-descriptor
+ * implementation) filling them with copies of the control fd.
+ */
+ int status_fd; /* File descriptor for /proc status file */
+ int as_fd; /* File descriptor for /proc as file */
+
+ char pathname[MAX_PROC_NAME_SIZE]; /* Pathname to /proc entry */
+
+ fltset_t saved_fltset; /* Saved traced hardware fault set */
+ gdb_sigset_t saved_sigset; /* Saved traced signal set */
+ gdb_sigset_t saved_sighold; /* Saved held signal set */
+ sysset_t *saved_exitset; /* Saved traced system call exit set */
+ sysset_t *saved_entryset; /* Saved traced system call entry set */
+
+ gdb_prstatus_t prstatus; /* Current process status info */
+
+#ifndef NEW_PROC_API
+ gdb_fpregset_t fpregset; /* Current floating point registers */
+#endif
+
+#ifdef DYNAMIC_SYSCALLS
+ int num_syscalls; /* Total number of syscalls */
+ char **syscall_names; /* Syscall number to name map */
+#endif
+
+ struct procinfo *thread_list;
+
+ int status_valid : 1;
+ int gregs_valid : 1;
+ int fpregs_valid : 1;
+ int threads_valid: 1;
+} procinfo;
+
+static char errmsg[128]; /* shared error msg buffer */
+
+/* Function prototypes for procinfo module: */
+
+static procinfo *find_procinfo_or_die (int pid, int tid);
+static procinfo *find_procinfo (int pid, int tid);
+static procinfo *create_procinfo (int pid, int tid);
+static void destroy_procinfo (procinfo * p);
+static void do_destroy_procinfo_cleanup (void *);
+static void dead_procinfo (procinfo * p, char *msg, int killp);
+static int open_procinfo_files (procinfo * p, int which);
+static void close_procinfo_files (procinfo * p);
+static int sysset_t_size (procinfo *p);
+static sysset_t *sysset_t_alloc (procinfo * pi);
+#ifdef DYNAMIC_SYSCALLS
+static void load_syscalls (procinfo *pi);
+static void free_syscalls (procinfo *pi);
+static int find_syscall (procinfo *pi, char *name);
+#endif /* DYNAMIC_SYSCALLS */
+
+/* The head of the procinfo list: */
+static procinfo * procinfo_list;
+
+/*
+ * Function: find_procinfo
+ *
+ * Search the procinfo list.
+ *
+ * Returns: pointer to procinfo, or NULL if not found.
+ */
+
+static procinfo *
+find_procinfo (int pid, int tid)
+{
+ procinfo *pi;
+
+ for (pi = procinfo_list; pi; pi = pi->next)
+ if (pi->pid == pid)
+ break;
+
+ if (pi)
+ if (tid)
+ {
+ /* Don't check threads_valid. If we're updating the
+ thread_list, we want to find whatever threads are already
+ here. This means that in general it is the caller's
+ responsibility to check threads_valid and update before
+ calling find_procinfo, if the caller wants to find a new
+ thread. */
+
+ for (pi = pi->thread_list; pi; pi = pi->next)
+ if (pi->tid == tid)
+ break;
+ }
+
+ return pi;
+}
+
+/*
+ * Function: find_procinfo_or_die
+ *
+ * Calls find_procinfo, but errors on failure.
+ */
+
+static procinfo *
+find_procinfo_or_die (int pid, int tid)
+{
+ procinfo *pi = find_procinfo (pid, tid);
+
+ if (pi == NULL)
+ {
+ if (tid)
+ error ("procfs: couldn't find pid %d (kernel thread %d) in procinfo list.",
+ pid, tid);
+ else
+ error ("procfs: couldn't find pid %d in procinfo list.", pid);
+ }
+ return pi;
+}
+
+/* open_with_retry() is a wrapper for open(). The appropriate
+ open() call is attempted; if unsuccessful, it will be retried as
+ many times as needed for the EAGAIN and EINTR conditions.
+
+ For other conditions, open_with_retry() will retry the open() a
+ limited number of times. In addition, a short sleep is imposed
+ prior to retrying the open(). The reason for this sleep is to give
+ the kernel a chance to catch up and create the file in question in
+ the event that GDB "wins" the race to open a file before the kernel
+ has created it. */
+
+static int
+open_with_retry (const char *pathname, int flags)
+{
+ int retries_remaining, status;
+
+ retries_remaining = 2;
+
+ while (1)
+ {
+ status = open (pathname, flags);
+
+ if (status >= 0 || retries_remaining == 0)
+ break;
+ else if (errno != EINTR && errno != EAGAIN)
+ {
+ retries_remaining--;
+ sleep (1);
+ }
+ }
+
+ return status;
+}
+
+/*
+ * Function: open_procinfo_files
+ *
+ * Open the file descriptor for the process or LWP.
+ * ifdef NEW_PROC_API, we only open the control file descriptor;
+ * the others are opened lazily as needed.
+ * else (if not NEW_PROC_API), there is only one real
+ * file descriptor, but we keep multiple copies of it so that
+ * the code that uses them does not have to be #ifdef'd.
+ *
+ * Return: file descriptor, or zero for failure.
+ */
+
+enum { FD_CTL, FD_STATUS, FD_AS };
+
+static int
+open_procinfo_files (procinfo *pi, int which)
+{
+#ifdef NEW_PROC_API
+ char tmp[MAX_PROC_NAME_SIZE];
+#endif
+ int fd;
+
+ /*
+ * This function is getting ALMOST long enough to break up into several.
+ * Here is some rationale:
+ *
+ * NEW_PROC_API (Solaris 2.6, Solaris 2.7, Unixware):
+ * There are several file descriptors that may need to be open
+ * for any given process or LWP. The ones we're intereted in are:
+ * - control (ctl) write-only change the state
+ * - status (status) read-only query the state
+ * - address space (as) read/write access memory
+ * - map (map) read-only virtual addr map
+ * Most of these are opened lazily as they are needed.
+ * The pathnames for the 'files' for an LWP look slightly
+ * different from those of a first-class process:
+ * Pathnames for a process (<proc-id>):
+ * /proc/<proc-id>/ctl
+ * /proc/<proc-id>/status
+ * /proc/<proc-id>/as
+ * /proc/<proc-id>/map
+ * Pathnames for an LWP (lwp-id):
+ * /proc/<proc-id>/lwp/<lwp-id>/lwpctl
+ * /proc/<proc-id>/lwp/<lwp-id>/lwpstatus
+ * An LWP has no map or address space file descriptor, since
+ * the memory map and address space are shared by all LWPs.
+ *
+ * Everyone else (Solaris 2.5, Irix, OSF)
+ * There is only one file descriptor for each process or LWP.
+ * For convenience, we copy the same file descriptor into all
+ * three fields of the procinfo struct (ctl_fd, status_fd, and
+ * as_fd, see NEW_PROC_API above) so that code that uses them
+ * doesn't need any #ifdef's.
+ * Pathname for all:
+ * /proc/<proc-id>
+ *
+ * Solaris 2.5 LWP's:
+ * Each LWP has an independent file descriptor, but these
+ * are not obtained via the 'open' system call like the rest:
+ * instead, they're obtained thru an ioctl call (PIOCOPENLWP)
+ * to the file descriptor of the parent process.
+ *
+ * OSF threads:
+ * These do not even have their own independent file descriptor.
+ * All operations are carried out on the file descriptor of the
+ * parent process. Therefore we just call open again for each
+ * thread, getting a new handle for the same 'file'.
+ */
+
+#ifdef NEW_PROC_API
+ /*
+ * In this case, there are several different file descriptors that
+ * we might be asked to open. The control file descriptor will be
+ * opened early, but the others will be opened lazily as they are
+ * needed.
+ */
+
+ strcpy (tmp, pi->pathname);
+ switch (which) { /* which file descriptor to open? */
+ case FD_CTL:
+ if (pi->tid)
+ strcat (tmp, "/lwpctl");
+ else
+ strcat (tmp, "/ctl");
+ fd = open_with_retry (tmp, O_WRONLY);
+ if (fd <= 0)
+ return 0; /* fail */
+ pi->ctl_fd = fd;
+ break;
+ case FD_AS:
+ if (pi->tid)
+ return 0; /* there is no 'as' file descriptor for an lwp */
+ strcat (tmp, "/as");
+ fd = open_with_retry (tmp, O_RDWR);
+ if (fd <= 0)
+ return 0; /* fail */
+ pi->as_fd = fd;
+ break;
+ case FD_STATUS:
+ if (pi->tid)
+ strcat (tmp, "/lwpstatus");
+ else
+ strcat (tmp, "/status");
+ fd = open_with_retry (tmp, O_RDONLY);
+ if (fd <= 0)
+ return 0; /* fail */
+ pi->status_fd = fd;
+ break;
+ default:
+ return 0; /* unknown file descriptor */
+ }
+#else /* not NEW_PROC_API */
+ /*
+ * In this case, there is only one file descriptor for each procinfo
+ * (ie. each process or LWP). In fact, only the file descriptor for
+ * the process can actually be opened by an 'open' system call.
+ * The ones for the LWPs have to be obtained thru an IOCTL call
+ * on the process's file descriptor.
+ *
+ * For convenience, we copy each procinfo's single file descriptor
+ * into all of the fields occupied by the several file descriptors
+ * of the NEW_PROC_API implementation. That way, the code that uses
+ * them can be written without ifdefs.
+ */
+
+
+#ifdef PIOCTSTATUS /* OSF */
+ /* Only one FD; just open it. */
+ if ((fd = open_with_retry (pi->pathname, O_RDWR)) == 0)
+ return 0;
+#else /* Sol 2.5, Irix, other? */
+ if (pi->tid == 0) /* Master procinfo for the process */
+ {
+ fd = open_with_retry (pi->pathname, O_RDWR);
+ if (fd <= 0)
+ return 0; /* fail */
+ }
+ else /* LWP thread procinfo */
+ {
+#ifdef PIOCOPENLWP /* Sol 2.5, thread/LWP */
+ procinfo *process;
+ int lwpid = pi->tid;
+
+ /* Find the procinfo for the entire process. */
+ if ((process = find_procinfo (pi->pid, 0)) == NULL)
+ return 0; /* fail */
+
+ /* Now obtain the file descriptor for the LWP. */
+ if ((fd = ioctl (process->ctl_fd, PIOCOPENLWP, &lwpid)) <= 0)
+ return 0; /* fail */
+#else /* Irix, other? */
+ return 0; /* Don't know how to open threads */
+#endif /* Sol 2.5 PIOCOPENLWP */
+ }
+#endif /* OSF PIOCTSTATUS */
+ pi->ctl_fd = pi->as_fd = pi->status_fd = fd;
+#endif /* NEW_PROC_API */
+
+ return 1; /* success */
+}
+
+/*
+ * Function: create_procinfo
+ *
+ * Allocate a data structure and link it into the procinfo list.
+ * (First tries to find a pre-existing one (FIXME: why?)
+ *
+ * Return: pointer to new procinfo struct.
+ */
+
+static procinfo *
+create_procinfo (int pid, int tid)
+{
+ procinfo *pi, *parent;
+
+ if ((pi = find_procinfo (pid, tid)))
+ return pi; /* Already exists, nothing to do. */
+
+ /* find parent before doing malloc, to save having to cleanup */
+ if (tid != 0)
+ parent = find_procinfo_or_die (pid, 0); /* FIXME: should I
+ create it if it
+ doesn't exist yet? */
+
+ pi = (procinfo *) xmalloc (sizeof (procinfo));
+ memset (pi, 0, sizeof (procinfo));
+ pi->pid = pid;
+ pi->tid = tid;
+
+#ifdef DYNAMIC_SYSCALLS
+ load_syscalls (pi);
+#endif
+
+ pi->saved_entryset = sysset_t_alloc (pi);
+ pi->saved_exitset = sysset_t_alloc (pi);
+
+ /* Chain into list. */
+ if (tid == 0)
+ {
+ sprintf (pi->pathname, MAIN_PROC_NAME_FMT, pid);
+ pi->next = procinfo_list;
+ procinfo_list = pi;
+ }
+ else
+ {
+#ifdef NEW_PROC_API
+ sprintf (pi->pathname, "/proc/%05d/lwp/%d", pid, tid);
+#else
+ sprintf (pi->pathname, MAIN_PROC_NAME_FMT, pid);
+#endif
+ pi->next = parent->thread_list;
+ parent->thread_list = pi;
+ }
+ return pi;
+}
+
+/*
+ * Function: close_procinfo_files
+ *
+ * Close all file descriptors associated with the procinfo
+ */
+
+static void
+close_procinfo_files (procinfo *pi)
+{
+ if (pi->ctl_fd > 0)
+ close (pi->ctl_fd);
+#ifdef NEW_PROC_API
+ if (pi->as_fd > 0)
+ close (pi->as_fd);
+ if (pi->status_fd > 0)
+ close (pi->status_fd);
+#endif
+ pi->ctl_fd = pi->as_fd = pi->status_fd = 0;
+}
+
+/*
+ * Function: destroy_procinfo
+ *
+ * Destructor function. Close, unlink and deallocate the object.
+ */
+
+static void
+destroy_one_procinfo (procinfo **list, procinfo *pi)
+{
+ procinfo *ptr;
+
+ /* Step one: unlink the procinfo from its list */
+ if (pi == *list)
+ *list = pi->next;
+ else
+ for (ptr = *list; ptr; ptr = ptr->next)
+ if (ptr->next == pi)
+ {
+ ptr->next = pi->next;
+ break;
+ }
+
+ /* Step two: close any open file descriptors */
+ close_procinfo_files (pi);
+
+ /* Step three: free the memory. */
+#ifdef DYNAMIC_SYSCALLS
+ free_syscalls (pi);
+#endif
+ xfree (pi->saved_entryset);
+ xfree (pi->saved_exitset);
+ xfree (pi);
+}
+
+static void
+destroy_procinfo (procinfo *pi)
+{
+ procinfo *tmp;
+
+ if (pi->tid != 0) /* destroy a thread procinfo */
+ {
+ tmp = find_procinfo (pi->pid, 0); /* find the parent process */
+ destroy_one_procinfo (&tmp->thread_list, pi);
+ }
+ else /* destroy a process procinfo and all its threads */
+ {
+ /* First destroy the children, if any; */
+ while (pi->thread_list != NULL)
+ destroy_one_procinfo (&pi->thread_list, pi->thread_list);
+ /* Then destroy the parent. Genocide!!! */
+ destroy_one_procinfo (&procinfo_list, pi);
+ }
+}
+
+static void
+do_destroy_procinfo_cleanup (void *pi)
+{
+ destroy_procinfo (pi);
+}
+
+enum { NOKILL, KILL };
+
+/*
+ * Function: dead_procinfo
+ *
+ * To be called on a non_recoverable error for a procinfo.
+ * Prints error messages, optionally sends a SIGKILL to the process,
+ * then destroys the data structure.
+ */
+
+static void
+dead_procinfo (procinfo *pi, char *msg, int kill_p)
+{
+ char procfile[80];
+
+ if (pi->pathname)
+ {
+ print_sys_errmsg (pi->pathname, errno);
+ }
+ else
+ {
+ sprintf (procfile, "process %d", pi->pid);
+ print_sys_errmsg (procfile, errno);
+ }
+ if (kill_p == KILL)
+ kill (pi->pid, SIGKILL);
+
+ destroy_procinfo (pi);
+ error (msg);
+}
+
+/*
+ * Function: sysset_t_size
+ *
+ * Returns the (complete) size of a sysset_t struct. Normally, this
+ * is just sizeof (syset_t), but in the case of Monterey/64, the actual
+ * size of sysset_t isn't known until runtime.
+ */
+
+static int
+sysset_t_size (procinfo * pi)
+{
+#ifndef DYNAMIC_SYSCALLS
+ return sizeof (sysset_t);
+#else
+ return sizeof (sysset_t) - sizeof (uint64_t)
+ + sizeof (uint64_t) * ((pi->num_syscalls + (8 * sizeof (uint64_t) - 1))
+ / (8 * sizeof (uint64_t)));
+#endif
+}
+
+/* Function: sysset_t_alloc
+
+ Allocate and (partially) initialize a sysset_t struct. */
+
+static sysset_t *
+sysset_t_alloc (procinfo * pi)
+{
+ sysset_t *ret;
+ int size = sysset_t_size (pi);
+ ret = xmalloc (size);
+#ifdef DYNAMIC_SYSCALLS
+ ret->pr_size = (pi->num_syscalls + (8 * sizeof (uint64_t) - 1))
+ / (8 * sizeof (uint64_t));
+#endif
+ return ret;
+}
+
+#ifdef DYNAMIC_SYSCALLS
+
+/* Function: load_syscalls
+
+ Extract syscall numbers and names from /proc/<pid>/sysent. Initialize
+ pi->num_syscalls with the number of syscalls and pi->syscall_names
+ with the names. (Certain numbers may be skipped in which case the
+ names for these numbers will be left as NULL.) */
+
+#define MAX_SYSCALL_NAME_LENGTH 256
+#define MAX_SYSCALLS 65536
+
+static void
+load_syscalls (procinfo *pi)
+{
+ char pathname[MAX_PROC_NAME_SIZE];
+ int sysent_fd;
+ prsysent_t header;
+ prsyscall_t *syscalls;
+ int i, size, maxcall;
+
+ pi->num_syscalls = 0;
+ pi->syscall_names = 0;
+
+ /* Open the file descriptor for the sysent file */
+ sprintf (pathname, "/proc/%d/sysent", pi->pid);
+ sysent_fd = open_with_retry (pathname, O_RDONLY);
+ if (sysent_fd < 0)
+ {
+ error ("load_syscalls: Can't open /proc/%d/sysent", pi->pid);
+ }
+
+ size = sizeof header - sizeof (prsyscall_t);
+ if (read (sysent_fd, &header, size) != size)
+ {
+ error ("load_syscalls: Error reading /proc/%d/sysent", pi->pid);
+ }
+
+ if (header.pr_nsyscalls == 0)
+ {
+ error ("load_syscalls: /proc/%d/sysent contains no syscalls!", pi->pid);
+ }
+
+ size = header.pr_nsyscalls * sizeof (prsyscall_t);
+ syscalls = xmalloc (size);
+
+ if (read (sysent_fd, syscalls, size) != size)
+ {
+ xfree (syscalls);
+ error ("load_syscalls: Error reading /proc/%d/sysent", pi->pid);
+ }
+
+ /* Find maximum syscall number. This may not be the same as
+ pr_nsyscalls since that value refers to the number of entries
+ in the table. (Also, the docs indicate that some system
+ call numbers may be skipped.) */
+
+ maxcall = syscalls[0].pr_number;
+
+ for (i = 1; i < header.pr_nsyscalls; i++)
+ if (syscalls[i].pr_number > maxcall
+ && syscalls[i].pr_nameoff > 0
+ && syscalls[i].pr_number < MAX_SYSCALLS)
+ maxcall = syscalls[i].pr_number;
+
+ pi->num_syscalls = maxcall+1;
+ pi->syscall_names = xmalloc (pi->num_syscalls * sizeof (char *));
+
+ for (i = 0; i < pi->num_syscalls; i++)
+ pi->syscall_names[i] = NULL;
+
+ /* Read the syscall names in */
+ for (i = 0; i < header.pr_nsyscalls; i++)
+ {
+ char namebuf[MAX_SYSCALL_NAME_LENGTH];
+ int nread;
+ int callnum;
+
+ if (syscalls[i].pr_number >= MAX_SYSCALLS
+ || syscalls[i].pr_number < 0
+ || syscalls[i].pr_nameoff <= 0
+ || (lseek (sysent_fd, (off_t) syscalls[i].pr_nameoff, SEEK_SET)
+ != (off_t) syscalls[i].pr_nameoff))
+ continue;
+
+ nread = read (sysent_fd, namebuf, sizeof namebuf);
+ if (nread <= 0)
+ continue;
+
+ callnum = syscalls[i].pr_number;
+
+ if (pi->syscall_names[callnum] != NULL)
+ {
+ /* FIXME: Generate warning */
+ continue;
+ }
+
+ namebuf[nread-1] = '\0';
+ size = strlen (namebuf) + 1;
+ pi->syscall_names[callnum] = xmalloc (size);
+ strncpy (pi->syscall_names[callnum], namebuf, size-1);
+ pi->syscall_names[callnum][size-1] = '\0';
+ }
+
+ close (sysent_fd);
+ xfree (syscalls);
+}
+
+/* Function: free_syscalls
+
+ Free the space allocated for the syscall names from the procinfo
+ structure. */
+
+static void
+free_syscalls (procinfo *pi)
+{
+ if (pi->syscall_names)
+ {
+ int i;
+
+ for (i = 0; i < pi->num_syscalls; i++)
+ if (pi->syscall_names[i] != NULL)
+ xfree (pi->syscall_names[i]);
+
+ xfree (pi->syscall_names);
+ pi->syscall_names = 0;
+ }
+}
+
+/* Function: find_syscall
+
+ Given a name, look up (and return) the corresponding syscall number.
+ If no match is found, return -1. */
+
+static int
+find_syscall (procinfo *pi, char *name)
+{
+ int i;
+ for (i = 0; i < pi->num_syscalls; i++)
+ {
+ if (pi->syscall_names[i] && strcmp (name, pi->syscall_names[i]) == 0)
+ return i;
+ }
+ return -1;
+}
+#endif
+
+/* =================== END, STRUCT PROCINFO "MODULE" =================== */
+
+/* =================== /proc "MODULE" =================== */
+
+/*
+ * This "module" is the interface layer between the /proc system API
+ * and the gdb target vector functions. This layer consists of
+ * access functions that encapsulate each of the basic operations
+ * that we need to use from the /proc API.
+ *
+ * The main motivation for this layer is to hide the fact that
+ * there are two very different implementations of the /proc API.
+ * Rather than have a bunch of #ifdefs all thru the gdb target vector
+ * functions, we do our best to hide them all in here.
+ */
+
+int proc_get_status (procinfo * pi);
+long proc_flags (procinfo * pi);
+int proc_why (procinfo * pi);
+int proc_what (procinfo * pi);
+int proc_set_run_on_last_close (procinfo * pi);
+int proc_unset_run_on_last_close (procinfo * pi);
+int proc_set_inherit_on_fork (procinfo * pi);
+int proc_unset_inherit_on_fork (procinfo * pi);
+int proc_set_async (procinfo * pi);
+int proc_unset_async (procinfo * pi);
+int proc_stop_process (procinfo * pi);
+int proc_trace_signal (procinfo * pi, int signo);
+int proc_ignore_signal (procinfo * pi, int signo);
+int proc_clear_current_fault (procinfo * pi);
+int proc_set_current_signal (procinfo * pi, int signo);
+int proc_clear_current_signal (procinfo * pi);
+int proc_set_gregs (procinfo * pi);
+int proc_set_fpregs (procinfo * pi);
+int proc_wait_for_stop (procinfo * pi);
+int proc_run_process (procinfo * pi, int step, int signo);
+int proc_kill (procinfo * pi, int signo);
+int proc_parent_pid (procinfo * pi);
+int proc_get_nthreads (procinfo * pi);
+int proc_get_current_thread (procinfo * pi);
+int proc_set_held_signals (procinfo * pi, gdb_sigset_t * sighold);
+int proc_set_traced_sysexit (procinfo * pi, sysset_t * sysset);
+int proc_set_traced_sysentry (procinfo * pi, sysset_t * sysset);
+int proc_set_traced_faults (procinfo * pi, fltset_t * fltset);
+int proc_set_traced_signals (procinfo * pi, gdb_sigset_t * sigset);
+
+int proc_update_threads (procinfo * pi);
+int proc_iterate_over_threads (procinfo * pi,
+ int (*func) (procinfo *, procinfo *, void *),
+ void *ptr);
+
+gdb_gregset_t *proc_get_gregs (procinfo * pi);
+gdb_fpregset_t *proc_get_fpregs (procinfo * pi);
+sysset_t *proc_get_traced_sysexit (procinfo * pi, sysset_t * save);
+sysset_t *proc_get_traced_sysentry (procinfo * pi, sysset_t * save);
+fltset_t *proc_get_traced_faults (procinfo * pi, fltset_t * save);
+gdb_sigset_t *proc_get_traced_signals (procinfo * pi, gdb_sigset_t * save);
+gdb_sigset_t *proc_get_held_signals (procinfo * pi, gdb_sigset_t * save);
+gdb_sigset_t *proc_get_pending_signals (procinfo * pi, gdb_sigset_t * save);
+gdb_sigaction_t *proc_get_signal_actions (procinfo * pi, gdb_sigaction_t *save);
+
+void proc_warn (procinfo * pi, char *func, int line);
+void proc_error (procinfo * pi, char *func, int line);
+
+void
+proc_warn (procinfo *pi, char *func, int line)
+{
+ sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname);
+ print_sys_errmsg (errmsg, errno);
+}
+
+void
+proc_error (procinfo *pi, char *func, int line)
+{
+ sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname);
+ perror_with_name (errmsg);
+}
+
+/*
+ * Function: proc_get_status
+ *
+ * Updates the status struct in the procinfo.
+ * There is a 'valid' flag, to let other functions know when
+ * this function needs to be called (so the status is only
+ * read when it is needed). The status file descriptor is
+ * also only opened when it is needed.
+ *
+ * Return: non-zero for success, zero for failure.
+ */
+
+int
+proc_get_status (procinfo *pi)
+{
+ /* Status file descriptor is opened "lazily" */
+ if (pi->status_fd == 0 &&
+ open_procinfo_files (pi, FD_STATUS) == 0)
+ {
+ pi->status_valid = 0;
+ return 0;
+ }
+
+#ifdef NEW_PROC_API
+ if (lseek (pi->status_fd, 0, SEEK_SET) < 0)
+ pi->status_valid = 0; /* fail */
+ else
+ {
+ /* Sigh... I have to read a different data structure,
+ depending on whether this is a main process or an LWP. */
+ if (pi->tid)
+ pi->status_valid = (read (pi->status_fd,
+ (char *) &pi->prstatus.pr_lwp,
+ sizeof (lwpstatus_t))
+ == sizeof (lwpstatus_t));
+ else
+ {
+ pi->status_valid = (read (pi->status_fd,
+ (char *) &pi->prstatus,
+ sizeof (gdb_prstatus_t))
+ == sizeof (gdb_prstatus_t));
+#if 0 /*def UNIXWARE*/
+ if (pi->status_valid &&
+ (pi->prstatus.pr_lwp.pr_flags & PR_ISTOP) &&
+ pi->prstatus.pr_lwp.pr_why == PR_REQUESTED)
+ /* Unixware peculiarity -- read the damn thing again! */
+ pi->status_valid = (read (pi->status_fd,
+ (char *) &pi->prstatus,
+ sizeof (gdb_prstatus_t))
+ == sizeof (gdb_prstatus_t));
+#endif /* UNIXWARE */
+ }
+ }
+#else /* ioctl method */
+#ifdef PIOCTSTATUS /* osf */
+ if (pi->tid == 0) /* main process */
+ {
+ /* Just read the danged status. Now isn't that simple? */
+ pi->status_valid =
+ (ioctl (pi->status_fd, PIOCSTATUS, &pi->prstatus) >= 0);
+ }
+ else
+ {
+ int win;
+ struct {
+ long pr_count;
+ tid_t pr_error_thread;
+ struct prstatus status;
+ } thread_status;
+
+ thread_status.pr_count = 1;
+ thread_status.status.pr_tid = pi->tid;
+ win = (ioctl (pi->status_fd, PIOCTSTATUS, &thread_status) >= 0);
+ if (win)
+ {
+ memcpy (&pi->prstatus, &thread_status.status,
+ sizeof (pi->prstatus));
+ pi->status_valid = 1;
+ }
+ }
+#else
+ /* Just read the danged status. Now isn't that simple? */
+ pi->status_valid = (ioctl (pi->status_fd, PIOCSTATUS, &pi->prstatus) >= 0);
+#endif
+#endif
+
+ if (pi->status_valid)
+ {
+ PROC_PRETTYFPRINT_STATUS (proc_flags (pi),
+ proc_why (pi),
+ proc_what (pi),
+ proc_get_current_thread (pi));
+ }
+
+ /* The status struct includes general regs, so mark them valid too */
+ pi->gregs_valid = pi->status_valid;
+#ifdef NEW_PROC_API
+ /* In the read/write multiple-fd model,
+ the status struct includes the fp regs too, so mark them valid too */
+ pi->fpregs_valid = pi->status_valid;
+#endif
+ return pi->status_valid; /* True if success, false if failure. */
+}
+
+/*
+ * Function: proc_flags
+ *
+ * returns the process flags (pr_flags field).
+ */
+
+long
+proc_flags (procinfo *pi)
+{
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return 0; /* FIXME: not a good failure value (but what is?) */
+
+#ifdef NEW_PROC_API
+# ifdef UNIXWARE
+ /* UnixWare 7.1 puts process status flags, e.g. PR_ASYNC, in
+ pstatus_t and LWP status flags, e.g. PR_STOPPED, in lwpstatus_t.
+ The two sets of flags don't overlap. */
+ return pi->prstatus.pr_flags | pi->prstatus.pr_lwp.pr_flags;
+# else
+ return pi->prstatus.pr_lwp.pr_flags;
+# endif
+#else
+ return pi->prstatus.pr_flags;
+#endif
+}
+
+/*
+ * Function: proc_why
+ *
+ * returns the pr_why field (why the process stopped).
+ */
+
+int
+proc_why (procinfo *pi)
+{
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return 0; /* FIXME: not a good failure value (but what is?) */
+
+#ifdef NEW_PROC_API
+ return pi->prstatus.pr_lwp.pr_why;
+#else
+ return pi->prstatus.pr_why;
+#endif
+}
+
+/*
+ * Function: proc_what
+ *
+ * returns the pr_what field (details of why the process stopped).
+ */
+
+int
+proc_what (procinfo *pi)
+{
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return 0; /* FIXME: not a good failure value (but what is?) */
+
+#ifdef NEW_PROC_API
+ return pi->prstatus.pr_lwp.pr_what;
+#else
+ return pi->prstatus.pr_what;
+#endif
+}
+
+#ifndef PIOCSSPCACT /* The following is not supported on OSF. */
+/*
+ * Function: proc_nsysarg
+ *
+ * returns the pr_nsysarg field (number of args to the current syscall).
+ */
+
+int
+proc_nsysarg (procinfo *pi)
+{
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return 0;
+
+#ifdef NEW_PROC_API
+ return pi->prstatus.pr_lwp.pr_nsysarg;
+#else
+ return pi->prstatus.pr_nsysarg;
+#endif
+}
+
+/*
+ * Function: proc_sysargs
+ *
+ * returns the pr_sysarg field (pointer to the arguments of current syscall).
+ */
+
+long *
+proc_sysargs (procinfo *pi)
+{
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return NULL;
+
+#ifdef NEW_PROC_API
+ return (long *) &pi->prstatus.pr_lwp.pr_sysarg;
+#else
+ return (long *) &pi->prstatus.pr_sysarg;
+#endif
+}
+
+/*
+ * Function: proc_syscall
+ *
+ * returns the pr_syscall field (id of current syscall if we are in one).
+ */
+
+int
+proc_syscall (procinfo *pi)
+{
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return 0;
+
+#ifdef NEW_PROC_API
+ return pi->prstatus.pr_lwp.pr_syscall;
+#else
+ return pi->prstatus.pr_syscall;
+#endif
+}
+#endif /* PIOCSSPCACT */
+
+/*
+ * Function: proc_cursig:
+ *
+ * returns the pr_cursig field (current signal).
+ */
+
+long
+proc_cursig (struct procinfo *pi)
+{
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return 0; /* FIXME: not a good failure value (but what is?) */
+
+#ifdef NEW_PROC_API
+ return pi->prstatus.pr_lwp.pr_cursig;
+#else
+ return pi->prstatus.pr_cursig;
+#endif
+}
+
+/*
+ * Function: proc_modify_flag
+ *
+ * === I appologize for the messiness of this function.
+ * === This is an area where the different versions of
+ * === /proc are more inconsistent than usual. MVS
+ *
+ * Set or reset any of the following process flags:
+ * PR_FORK -- forked child will inherit trace flags
+ * PR_RLC -- traced process runs when last /proc file closed.
+ * PR_KLC -- traced process is killed when last /proc file closed.
+ * PR_ASYNC -- LWP's get to run/stop independently.
+ *
+ * There are three methods for doing this function:
+ * 1) Newest: read/write [PCSET/PCRESET/PCUNSET]
+ * [Sol6, Sol7, UW]
+ * 2) Middle: PIOCSET/PIOCRESET
+ * [Irix, Sol5]
+ * 3) Oldest: PIOCSFORK/PIOCRFORK/PIOCSRLC/PIOCRRLC
+ * [OSF, Sol5]
+ *
+ * Note: Irix does not define PR_ASYNC.
+ * Note: OSF does not define PR_KLC.
+ * Note: OSF is the only one that can ONLY use the oldest method.
+ *
+ * Arguments:
+ * pi -- the procinfo
+ * flag -- one of PR_FORK, PR_RLC, or PR_ASYNC
+ * mode -- 1 for set, 0 for reset.
+ *
+ * Returns non-zero for success, zero for failure.
+ */
+
+enum { FLAG_RESET, FLAG_SET };
+
+static int
+proc_modify_flag (procinfo *pi, long flag, long mode)
+{
+ long win = 0; /* default to fail */
+
+ /*
+ * These operations affect the process as a whole, and applying
+ * them to an individual LWP has the same meaning as applying them
+ * to the main process. Therefore, if we're ever called with a
+ * pointer to an LWP's procinfo, let's substitute the process's
+ * procinfo and avoid opening the LWP's file descriptor
+ * unnecessarily.
+ */
+
+ if (pi->pid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef NEW_PROC_API /* Newest method: UnixWare and newer Solarii */
+ /* First normalize the PCUNSET/PCRESET command opcode
+ (which for no obvious reason has a different definition
+ from one operating system to the next...) */
+#ifdef PCUNSET
+#define GDBRESET PCUNSET
+#else
+#ifdef PCRESET
+#define GDBRESET PCRESET
+#endif
+#endif
+ {
+ procfs_ctl_t arg[2];
+
+ if (mode == FLAG_SET) /* Set the flag (RLC, FORK, or ASYNC) */
+ arg[0] = PCSET;
+ else /* Reset the flag */
+ arg[0] = GDBRESET;
+
+ arg[1] = flag;
+ win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
+ }
+#else
+#ifdef PIOCSET /* Irix/Sol5 method */
+ if (mode == FLAG_SET) /* Set the flag (hopefully RLC, FORK, or ASYNC) */
+ {
+ win = (ioctl (pi->ctl_fd, PIOCSET, &flag) >= 0);
+ }
+ else /* Reset the flag */
+ {
+ win = (ioctl (pi->ctl_fd, PIOCRESET, &flag) >= 0);
+ }
+
+#else
+#ifdef PIOCSRLC /* Oldest method: OSF */
+ switch (flag) {
+ case PR_RLC:
+ if (mode == FLAG_SET) /* Set run-on-last-close */
+ {
+ win = (ioctl (pi->ctl_fd, PIOCSRLC, NULL) >= 0);
+ }
+ else /* Clear run-on-last-close */
+ {
+ win = (ioctl (pi->ctl_fd, PIOCRRLC, NULL) >= 0);
+ }
+ break;
+ case PR_FORK:
+ if (mode == FLAG_SET) /* Set inherit-on-fork */
+ {
+ win = (ioctl (pi->ctl_fd, PIOCSFORK, NULL) >= 0);
+ }
+ else /* Clear inherit-on-fork */
+ {
+ win = (ioctl (pi->ctl_fd, PIOCRFORK, NULL) >= 0);
+ }
+ break;
+ default:
+ win = 0; /* fail -- unknown flag (can't do PR_ASYNC) */
+ break;
+ }
+#endif
+#endif
+#endif
+#undef GDBRESET
+ /* The above operation renders the procinfo's cached pstatus obsolete. */
+ pi->status_valid = 0;
+
+ if (!win)
+ warning ("procfs: modify_flag failed to turn %s %s",
+ flag == PR_FORK ? "PR_FORK" :
+ flag == PR_RLC ? "PR_RLC" :
+#ifdef PR_ASYNC
+ flag == PR_ASYNC ? "PR_ASYNC" :
+#endif
+#ifdef PR_KLC
+ flag == PR_KLC ? "PR_KLC" :
+#endif
+ "<unknown flag>",
+ mode == FLAG_RESET ? "off" : "on");
+
+ return win;
+}
+
+/*
+ * Function: proc_set_run_on_last_close
+ *
+ * Set the run_on_last_close flag.
+ * Process with all threads will become runnable
+ * when debugger closes all /proc fds.
+ *
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_set_run_on_last_close (procinfo *pi)
+{
+ return proc_modify_flag (pi, PR_RLC, FLAG_SET);
+}
+
+/*
+ * Function: proc_unset_run_on_last_close
+ *
+ * Reset the run_on_last_close flag.
+ * Process will NOT become runnable
+ * when debugger closes its file handles.
+ *
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_unset_run_on_last_close (procinfo *pi)
+{
+ return proc_modify_flag (pi, PR_RLC, FLAG_RESET);
+}
+
+#ifdef PR_KLC
+/*
+ * Function: proc_set_kill_on_last_close
+ *
+ * Set the kill_on_last_close flag.
+ * Process with all threads will be killed when debugger
+ * closes all /proc fds (or debugger exits or dies).
+ *
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_set_kill_on_last_close (procinfo *pi)
+{
+ return proc_modify_flag (pi, PR_KLC, FLAG_SET);
+}
+
+/*
+ * Function: proc_unset_kill_on_last_close
+ *
+ * Reset the kill_on_last_close flag.
+ * Process will NOT be killed when debugger
+ * closes its file handles (or exits or dies).
+ *
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_unset_kill_on_last_close (procinfo *pi)
+{
+ return proc_modify_flag (pi, PR_KLC, FLAG_RESET);
+}
+#endif /* PR_KLC */
+
+/*
+ * Function: proc_set_inherit_on_fork
+ *
+ * Set inherit_on_fork flag.
+ * If the process forks a child while we are registered for events
+ * in the parent, then we will also recieve events from the child.
+ *
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_set_inherit_on_fork (procinfo *pi)
+{
+ return proc_modify_flag (pi, PR_FORK, FLAG_SET);
+}
+
+/*
+ * Function: proc_unset_inherit_on_fork
+ *
+ * Reset inherit_on_fork flag.
+ * If the process forks a child while we are registered for events
+ * in the parent, then we will NOT recieve events from the child.
+ *
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_unset_inherit_on_fork (procinfo *pi)
+{
+ return proc_modify_flag (pi, PR_FORK, FLAG_RESET);
+}
+
+#ifdef PR_ASYNC
+/*
+ * Function: proc_set_async
+ *
+ * Set PR_ASYNC flag.
+ * If one LWP stops because of a debug event (signal etc.),
+ * the remaining LWPs will continue to run.
+ *
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_set_async (procinfo *pi)
+{
+ return proc_modify_flag (pi, PR_ASYNC, FLAG_SET);
+}
+
+/*
+ * Function: proc_unset_async
+ *
+ * Reset PR_ASYNC flag.
+ * If one LWP stops because of a debug event (signal etc.),
+ * then all other LWPs will stop as well.
+ *
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_unset_async (procinfo *pi)
+{
+ return proc_modify_flag (pi, PR_ASYNC, FLAG_RESET);
+}
+#endif /* PR_ASYNC */
+
+/*
+ * Function: proc_stop_process
+ *
+ * Request the process/LWP to stop. Does not wait.
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_stop_process (procinfo *pi)
+{
+ int win;
+
+ /*
+ * We might conceivably apply this operation to an LWP, and
+ * the LWP's ctl file descriptor might not be open.
+ */
+
+ if (pi->ctl_fd == 0 &&
+ open_procinfo_files (pi, FD_CTL) == 0)
+ return 0;
+ else
+ {
+#ifdef NEW_PROC_API
+ procfs_ctl_t cmd = PCSTOP;
+ win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
+#else /* ioctl method */
+ win = (ioctl (pi->ctl_fd, PIOCSTOP, &pi->prstatus) >= 0);
+ /* Note: the call also reads the prstatus. */
+ if (win)
+ {
+ pi->status_valid = 1;
+ PROC_PRETTYFPRINT_STATUS (proc_flags (pi),
+ proc_why (pi),
+ proc_what (pi),
+ proc_get_current_thread (pi));
+ }
+#endif
+ }
+
+ return win;
+}
+
+/*
+ * Function: proc_wait_for_stop
+ *
+ * Wait for the process or LWP to stop (block until it does).
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_wait_for_stop (procinfo *pi)
+{
+ int win;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef NEW_PROC_API
+ {
+ procfs_ctl_t cmd = PCWSTOP;
+ win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
+ /* We been runnin' and we stopped -- need to update status. */
+ pi->status_valid = 0;
+ }
+#else /* ioctl method */
+ win = (ioctl (pi->ctl_fd, PIOCWSTOP, &pi->prstatus) >= 0);
+ /* Above call also refreshes the prstatus. */
+ if (win)
+ {
+ pi->status_valid = 1;
+ PROC_PRETTYFPRINT_STATUS (proc_flags (pi),
+ proc_why (pi),
+ proc_what (pi),
+ proc_get_current_thread (pi));
+ }
+#endif
+
+ return win;
+}
+
+/*
+ * Function: proc_run_process
+ *
+ * Make the process or LWP runnable.
+ * Options (not all are implemented):
+ * - single-step
+ * - clear current fault
+ * - clear current signal
+ * - abort the current system call
+ * - stop as soon as finished with system call
+ * - (ioctl): set traced signal set
+ * - (ioctl): set held signal set
+ * - (ioctl): set traced fault set
+ * - (ioctl): set start pc (vaddr)
+ * Always clear the current fault.
+ * Clear the current signal if 'signo' is zero.
+ *
+ * Arguments:
+ * pi the process or LWP to operate on.
+ * step if true, set the process or LWP to trap after one instr.
+ * signo if zero, clear the current signal if any.
+ * if non-zero, set the current signal to this one.
+ *
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_run_process (procinfo *pi, int step, int signo)
+{
+ int win;
+ int runflags;
+
+ /*
+ * We will probably have to apply this operation to individual threads,
+ * so make sure the control file descriptor is open.
+ */
+
+ if (pi->ctl_fd == 0 &&
+ open_procinfo_files (pi, FD_CTL) == 0)
+ {
+ return 0;
+ }
+
+ runflags = PRCFAULT; /* always clear current fault */
+ if (step)
+ runflags |= PRSTEP;
+ if (signo == 0)
+ runflags |= PRCSIG;
+ else if (signo != -1) /* -1 means do nothing W.R.T. signals */
+ proc_set_current_signal (pi, signo);
+
+#ifdef NEW_PROC_API
+ {
+ procfs_ctl_t cmd[2];
+
+ cmd[0] = PCRUN;
+ cmd[1] = runflags;
+ win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
+ }
+#else /* ioctl method */
+ {
+ prrun_t prrun;
+
+ memset (&prrun, 0, sizeof (prrun));
+ prrun.pr_flags = runflags;
+ win = (ioctl (pi->ctl_fd, PIOCRUN, &prrun) >= 0);
+ }
+#endif
+
+ return win;
+}
+
+/*
+ * Function: proc_set_traced_signals
+ *
+ * Register to trace signals in the process or LWP.
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_set_traced_signals (procinfo *pi, gdb_sigset_t *sigset)
+{
+ int win;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef NEW_PROC_API
+ {
+ struct {
+ procfs_ctl_t cmd;
+ /* Use char array to avoid alignment issues. */
+ char sigset[sizeof (gdb_sigset_t)];
+ } arg;
+
+ arg.cmd = PCSTRACE;
+ memcpy (&arg.sigset, sigset, sizeof (gdb_sigset_t));
+
+ win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg));
+ }
+#else /* ioctl method */
+ win = (ioctl (pi->ctl_fd, PIOCSTRACE, sigset) >= 0);
+#endif
+ /* The above operation renders the procinfo's cached pstatus obsolete. */
+ pi->status_valid = 0;
+
+ if (!win)
+ warning ("procfs: set_traced_signals failed");
+ return win;
+}
+
+/*
+ * Function: proc_set_traced_faults
+ *
+ * Register to trace hardware faults in the process or LWP.
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_set_traced_faults (procinfo *pi, fltset_t *fltset)
+{
+ int win;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef NEW_PROC_API
+ {
+ struct {
+ procfs_ctl_t cmd;
+ /* Use char array to avoid alignment issues. */
+ char fltset[sizeof (fltset_t)];
+ } arg;
+
+ arg.cmd = PCSFAULT;
+ memcpy (&arg.fltset, fltset, sizeof (fltset_t));
+
+ win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg));
+ }
+#else /* ioctl method */
+ win = (ioctl (pi->ctl_fd, PIOCSFAULT, fltset) >= 0);
+#endif
+ /* The above operation renders the procinfo's cached pstatus obsolete. */
+ pi->status_valid = 0;
+
+ return win;
+}
+
+/*
+ * Function: proc_set_traced_sysentry
+ *
+ * Register to trace entry to system calls in the process or LWP.
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_set_traced_sysentry (procinfo *pi, sysset_t *sysset)
+{
+ int win;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef NEW_PROC_API
+ {
+ struct gdb_proc_ctl_pcsentry {
+ procfs_ctl_t cmd;
+ /* Use char array to avoid alignment issues. */
+ char sysset[sizeof (sysset_t)];
+ } *argp;
+ int argp_size = sizeof (struct gdb_proc_ctl_pcsentry)
+ - sizeof (sysset_t)
+ + sysset_t_size (pi);
+
+ argp = xmalloc (argp_size);
+
+ argp->cmd = PCSENTRY;
+ memcpy (&argp->sysset, sysset, sysset_t_size (pi));
+
+ win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size);
+ xfree (argp);
+ }
+#else /* ioctl method */
+ win = (ioctl (pi->ctl_fd, PIOCSENTRY, sysset) >= 0);
+#endif
+ /* The above operation renders the procinfo's cached pstatus obsolete. */
+ pi->status_valid = 0;
+
+ return win;
+}
+
+/*
+ * Function: proc_set_traced_sysexit
+ *
+ * Register to trace exit from system calls in the process or LWP.
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_set_traced_sysexit (procinfo *pi, sysset_t *sysset)
+{
+ int win;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef NEW_PROC_API
+ {
+ struct gdb_proc_ctl_pcsexit {
+ procfs_ctl_t cmd;
+ /* Use char array to avoid alignment issues. */
+ char sysset[sizeof (sysset_t)];
+ } *argp;
+ int argp_size = sizeof (struct gdb_proc_ctl_pcsexit)
+ - sizeof (sysset_t)
+ + sysset_t_size (pi);
+
+ argp = xmalloc (argp_size);
+
+ argp->cmd = PCSEXIT;
+ memcpy (&argp->sysset, sysset, sysset_t_size (pi));
+
+ win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size);
+ xfree (argp);
+ }
+#else /* ioctl method */
+ win = (ioctl (pi->ctl_fd, PIOCSEXIT, sysset) >= 0);
+#endif
+ /* The above operation renders the procinfo's cached pstatus obsolete. */
+ pi->status_valid = 0;
+
+ return win;
+}
+
+/*
+ * Function: proc_set_held_signals
+ *
+ * Specify the set of blocked / held signals in the process or LWP.
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_set_held_signals (procinfo *pi, gdb_sigset_t *sighold)
+{
+ int win;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef NEW_PROC_API
+ {
+ struct {
+ procfs_ctl_t cmd;
+ /* Use char array to avoid alignment issues. */
+ char hold[sizeof (gdb_sigset_t)];
+ } arg;
+
+ arg.cmd = PCSHOLD;
+ memcpy (&arg.hold, sighold, sizeof (gdb_sigset_t));
+ win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
+ }
+#else
+ win = (ioctl (pi->ctl_fd, PIOCSHOLD, sighold) >= 0);
+#endif
+ /* The above operation renders the procinfo's cached pstatus obsolete. */
+ pi->status_valid = 0;
+
+ return win;
+}
+
+/*
+ * Function: proc_get_pending_signals
+ *
+ * returns the set of signals that are pending in the process or LWP.
+ * Will also copy the sigset if 'save' is non-zero.
+ */
+
+gdb_sigset_t *
+proc_get_pending_signals (procinfo *pi, gdb_sigset_t *save)
+{
+ gdb_sigset_t *ret = NULL;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return NULL;
+
+#ifdef NEW_PROC_API
+ ret = &pi->prstatus.pr_lwp.pr_lwppend;
+#else
+ ret = &pi->prstatus.pr_sigpend;
+#endif
+ if (save && ret)
+ memcpy (save, ret, sizeof (gdb_sigset_t));
+
+ return ret;
+}
+
+/*
+ * Function: proc_get_signal_actions
+ *
+ * returns the set of signal actions.
+ * Will also copy the sigactionset if 'save' is non-zero.
+ */
+
+gdb_sigaction_t *
+proc_get_signal_actions (procinfo *pi, gdb_sigaction_t *save)
+{
+ gdb_sigaction_t *ret = NULL;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return NULL;
+
+#ifdef NEW_PROC_API
+ ret = &pi->prstatus.pr_lwp.pr_action;
+#else
+ ret = &pi->prstatus.pr_action;
+#endif
+ if (save && ret)
+ memcpy (save, ret, sizeof (gdb_sigaction_t));
+
+ return ret;
+}
+
+/*
+ * Function: proc_get_held_signals
+ *
+ * returns the set of signals that are held / blocked.
+ * Will also copy the sigset if 'save' is non-zero.
+ */
+
+gdb_sigset_t *
+proc_get_held_signals (procinfo *pi, gdb_sigset_t *save)
+{
+ gdb_sigset_t *ret = NULL;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef NEW_PROC_API
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return NULL;
+
+#ifdef UNIXWARE
+ ret = &pi->prstatus.pr_lwp.pr_context.uc_sigmask;
+#else
+ ret = &pi->prstatus.pr_lwp.pr_lwphold;
+#endif /* UNIXWARE */
+#else /* not NEW_PROC_API */
+ {
+ static gdb_sigset_t sigheld;
+
+ if (ioctl (pi->ctl_fd, PIOCGHOLD, &sigheld) >= 0)
+ ret = &sigheld;
+ }
+#endif /* NEW_PROC_API */
+ if (save && ret)
+ memcpy (save, ret, sizeof (gdb_sigset_t));
+
+ return ret;
+}
+
+/*
+ * Function: proc_get_traced_signals
+ *
+ * returns the set of signals that are traced / debugged.
+ * Will also copy the sigset if 'save' is non-zero.
+ */
+
+gdb_sigset_t *
+proc_get_traced_signals (procinfo *pi, gdb_sigset_t *save)
+{
+ gdb_sigset_t *ret = NULL;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef NEW_PROC_API
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return NULL;
+
+ ret = &pi->prstatus.pr_sigtrace;
+#else
+ {
+ static gdb_sigset_t sigtrace;
+
+ if (ioctl (pi->ctl_fd, PIOCGTRACE, &sigtrace) >= 0)
+ ret = &sigtrace;
+ }
+#endif
+ if (save && ret)
+ memcpy (save, ret, sizeof (gdb_sigset_t));
+
+ return ret;
+}
+
+/*
+ * Function: proc_trace_signal
+ *
+ * Add 'signo' to the set of signals that are traced.
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_trace_signal (procinfo *pi, int signo)
+{
+ gdb_sigset_t temp;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+ if (pi)
+ {
+ if (proc_get_traced_signals (pi, &temp))
+ {
+ praddset (&temp, signo);
+ return proc_set_traced_signals (pi, &temp);
+ }
+ }
+
+ return 0; /* failure */
+}
+
+/*
+ * Function: proc_ignore_signal
+ *
+ * Remove 'signo' from the set of signals that are traced.
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_ignore_signal (procinfo *pi, int signo)
+{
+ gdb_sigset_t temp;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+ if (pi)
+ {
+ if (proc_get_traced_signals (pi, &temp))
+ {
+ prdelset (&temp, signo);
+ return proc_set_traced_signals (pi, &temp);
+ }
+ }
+
+ return 0; /* failure */
+}
+
+/*
+ * Function: proc_get_traced_faults
+ *
+ * returns the set of hardware faults that are traced /debugged.
+ * Will also copy the faultset if 'save' is non-zero.
+ */
+
+fltset_t *
+proc_get_traced_faults (procinfo *pi, fltset_t *save)
+{
+ fltset_t *ret = NULL;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef NEW_PROC_API
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return NULL;
+
+ ret = &pi->prstatus.pr_flttrace;
+#else
+ {
+ static fltset_t flttrace;
+
+ if (ioctl (pi->ctl_fd, PIOCGFAULT, &flttrace) >= 0)
+ ret = &flttrace;
+ }
+#endif
+ if (save && ret)
+ memcpy (save, ret, sizeof (fltset_t));
+
+ return ret;
+}
+
+/*
+ * Function: proc_get_traced_sysentry
+ *
+ * returns the set of syscalls that are traced /debugged on entry.
+ * Will also copy the syscall set if 'save' is non-zero.
+ */
+
+sysset_t *
+proc_get_traced_sysentry (procinfo *pi, sysset_t *save)
+{
+ sysset_t *ret = NULL;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef NEW_PROC_API
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return NULL;
+
+#ifndef DYNAMIC_SYSCALLS
+ ret = &pi->prstatus.pr_sysentry;
+#else /* DYNAMIC_SYSCALLS */
+ {
+ static sysset_t *sysentry;
+ size_t size;
+
+ if (!sysentry)
+ sysentry = sysset_t_alloc (pi);
+ ret = sysentry;
+ if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0)
+ return NULL;
+ if (pi->prstatus.pr_sysentry_offset == 0)
+ {
+ gdb_premptysysset (sysentry);
+ }
+ else
+ {
+ int rsize;
+
+ if (lseek (pi->status_fd, (off_t) pi->prstatus.pr_sysentry_offset,
+ SEEK_SET)
+ != (off_t) pi->prstatus.pr_sysentry_offset)
+ return NULL;
+ size = sysset_t_size (pi);
+ gdb_premptysysset (sysentry);
+ rsize = read (pi->status_fd, sysentry, size);
+ if (rsize < 0)
+ return NULL;
+ }
+ }
+#endif /* DYNAMIC_SYSCALLS */
+#else /* !NEW_PROC_API */
+ {
+ static sysset_t sysentry;
+
+ if (ioctl (pi->ctl_fd, PIOCGENTRY, &sysentry) >= 0)
+ ret = &sysentry;
+ }
+#endif /* NEW_PROC_API */
+ if (save && ret)
+ memcpy (save, ret, sysset_t_size (pi));
+
+ return ret;
+}
+
+/*
+ * Function: proc_get_traced_sysexit
+ *
+ * returns the set of syscalls that are traced /debugged on exit.
+ * Will also copy the syscall set if 'save' is non-zero.
+ */
+
+sysset_t *
+proc_get_traced_sysexit (procinfo *pi, sysset_t *save)
+{
+ sysset_t * ret = NULL;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef NEW_PROC_API
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return NULL;
+
+#ifndef DYNAMIC_SYSCALLS
+ ret = &pi->prstatus.pr_sysexit;
+#else /* DYNAMIC_SYSCALLS */
+ {
+ static sysset_t *sysexit;
+ size_t size;
+
+ if (!sysexit)
+ sysexit = sysset_t_alloc (pi);
+ ret = sysexit;
+ if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0)
+ return NULL;
+ if (pi->prstatus.pr_sysexit_offset == 0)
+ {
+ gdb_premptysysset (sysexit);
+ }
+ else
+ {
+ int rsize;
+
+ if (lseek (pi->status_fd, (off_t) pi->prstatus.pr_sysexit_offset, SEEK_SET)
+ != (off_t) pi->prstatus.pr_sysexit_offset)
+ return NULL;
+ size = sysset_t_size (pi);
+ gdb_premptysysset (sysexit);
+ rsize = read (pi->status_fd, sysexit, size);
+ if (rsize < 0)
+ return NULL;
+ }
+ }
+#endif /* DYNAMIC_SYSCALLS */
+#else
+ {
+ static sysset_t sysexit;
+
+ if (ioctl (pi->ctl_fd, PIOCGEXIT, &sysexit) >= 0)
+ ret = &sysexit;
+ }
+#endif
+ if (save && ret)
+ memcpy (save, ret, sysset_t_size (pi));
+
+ return ret;
+}
+
+/*
+ * Function: proc_clear_current_fault
+ *
+ * The current fault (if any) is cleared; the associated signal
+ * will not be sent to the process or LWP when it resumes.
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_clear_current_fault (procinfo *pi)
+{
+ int win;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef NEW_PROC_API
+ {
+ procfs_ctl_t cmd = PCCFAULT;
+ win = (write (pi->ctl_fd, (void *) &cmd, sizeof (cmd)) == sizeof (cmd));
+ }
+#else
+ win = (ioctl (pi->ctl_fd, PIOCCFAULT, 0) >= 0);
+#endif
+
+ return win;
+}
+
+/*
+ * Function: proc_set_current_signal
+ *
+ * Set the "current signal" that will be delivered next to the process.
+ * NOTE: semantics are different from those of KILL.
+ * This signal will be delivered to the process or LWP
+ * immediately when it is resumed (even if the signal is held/blocked);
+ * it will NOT immediately cause another event of interest, and will NOT
+ * first trap back to the debugger.
+ *
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_set_current_signal (procinfo *pi, int signo)
+{
+ int win;
+ struct {
+ procfs_ctl_t cmd;
+ /* Use char array to avoid alignment issues. */
+ char sinfo[sizeof (gdb_siginfo_t)];
+ } arg;
+ gdb_siginfo_t *mysinfo;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef PROCFS_DONT_PIOCSSIG_CURSIG
+ /* With Alpha OSF/1 procfs, the kernel gets really confused if it
+ * receives a PIOCSSIG with a signal identical to the current signal,
+ * it messes up the current signal. Work around the kernel bug.
+ */
+ if (signo > 0 &&
+ signo == proc_cursig (pi))
+ return 1; /* I assume this is a success? */
+#endif
+
+ /* The pointer is just a type alias. */
+ mysinfo = (gdb_siginfo_t *) &arg.sinfo;
+ mysinfo->si_signo = signo;
+ mysinfo->si_code = 0;
+ mysinfo->si_pid = getpid (); /* ?why? */
+ mysinfo->si_uid = getuid (); /* ?why? */
+
+#ifdef NEW_PROC_API
+ arg.cmd = PCSSIG;
+ win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
+#else
+ win = (ioctl (pi->ctl_fd, PIOCSSIG, (void *) &arg.sinfo) >= 0);
+#endif
+
+ return win;
+}
+
+/*
+ * Function: proc_clear_current_signal
+ *
+ * The current signal (if any) is cleared, and
+ * is not sent to the process or LWP when it resumes.
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_clear_current_signal (procinfo *pi)
+{
+ int win;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+#ifdef NEW_PROC_API
+ {
+ struct {
+ procfs_ctl_t cmd;
+ /* Use char array to avoid alignment issues. */
+ char sinfo[sizeof (gdb_siginfo_t)];
+ } arg;
+ gdb_siginfo_t *mysinfo;
+
+ arg.cmd = PCSSIG;
+ /* The pointer is just a type alias. */
+ mysinfo = (gdb_siginfo_t *) &arg.sinfo;
+ mysinfo->si_signo = 0;
+ mysinfo->si_code = 0;
+ mysinfo->si_errno = 0;
+ mysinfo->si_pid = getpid (); /* ?why? */
+ mysinfo->si_uid = getuid (); /* ?why? */
+
+ win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
+ }
+#else
+ win = (ioctl (pi->ctl_fd, PIOCSSIG, 0) >= 0);
+#endif
+
+ return win;
+}
+
+/*
+ * Function: proc_get_gregs
+ *
+ * Get the general registers for the process or LWP.
+ * Returns non-zero for success, zero for failure.
+ */
+
+gdb_gregset_t *
+proc_get_gregs (procinfo *pi)
+{
+ if (!pi->status_valid || !pi->gregs_valid)
+ if (!proc_get_status (pi))
+ return NULL;
+
+ /*
+ * OK, sorry about the ifdef's.
+ * There's three cases instead of two, because
+ * in this instance Unixware and Solaris/RW differ.
+ */
+
+#ifdef NEW_PROC_API
+#ifdef UNIXWARE /* ugh, a true architecture dependency */
+ return &pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs;
+#else /* not Unixware */
+ return &pi->prstatus.pr_lwp.pr_reg;
+#endif /* Unixware */
+#else /* not NEW_PROC_API */
+ return &pi->prstatus.pr_reg;
+#endif /* NEW_PROC_API */
+}
+
+/*
+ * Function: proc_get_fpregs
+ *
+ * Get the floating point registers for the process or LWP.
+ * Returns non-zero for success, zero for failure.
+ */
+
+gdb_fpregset_t *
+proc_get_fpregs (procinfo *pi)
+{
+#ifdef NEW_PROC_API
+ if (!pi->status_valid || !pi->fpregs_valid)
+ if (!proc_get_status (pi))
+ return NULL;
+
+#ifdef UNIXWARE /* a true architecture dependency */
+ return &pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs;
+#else
+ return &pi->prstatus.pr_lwp.pr_fpreg;
+#endif /* Unixware */
+
+#else /* not NEW_PROC_API */
+ if (pi->fpregs_valid)
+ return &pi->fpregset; /* already got 'em */
+ else
+ {
+ if (pi->ctl_fd == 0 &&
+ open_procinfo_files (pi, FD_CTL) == 0)
+ {
+ return NULL;
+ }
+ else
+ {
+#ifdef PIOCTGFPREG
+ struct {
+ long pr_count;
+ tid_t pr_error_thread;
+ tfpregset_t thread_1;
+ } thread_fpregs;
+
+ thread_fpregs.pr_count = 1;
+ thread_fpregs.thread_1.tid = pi->tid;
+
+ if (pi->tid == 0 &&
+ ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset) >= 0)
+ {
+ pi->fpregs_valid = 1;
+ return &pi->fpregset; /* got 'em now! */
+ }
+ else if (pi->tid != 0 &&
+ ioctl (pi->ctl_fd, PIOCTGFPREG, &thread_fpregs) >= 0)
+ {
+ memcpy (&pi->fpregset, &thread_fpregs.thread_1.pr_fpregs,
+ sizeof (pi->fpregset));
+ pi->fpregs_valid = 1;
+ return &pi->fpregset; /* got 'em now! */
+ }
+ else
+ {
+ return NULL;
+ }
+#else
+ if (ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset) >= 0)
+ {
+ pi->fpregs_valid = 1;
+ return &pi->fpregset; /* got 'em now! */
+ }
+ else
+ {
+ return NULL;
+ }
+#endif
+ }
+ }
+#endif
+}
+
+/*
+ * Function: proc_set_gregs
+ *
+ * Write the general registers back to the process or LWP.
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_set_gregs (procinfo *pi)
+{
+ gdb_gregset_t *gregs;
+ int win;
+
+ if ((gregs = proc_get_gregs (pi)) == NULL)
+ return 0; /* get_regs has already warned */
+
+ if (pi->ctl_fd == 0 &&
+ open_procinfo_files (pi, FD_CTL) == 0)
+ {
+ return 0;
+ }
+ else
+ {
+#ifdef NEW_PROC_API
+ struct {
+ procfs_ctl_t cmd;
+ /* Use char array to avoid alignment issues. */
+ char gregs[sizeof (gdb_gregset_t)];
+ } arg;
+
+ arg.cmd = PCSREG;
+ memcpy (&arg.gregs, gregs, sizeof (arg.gregs));
+ win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
+#else
+ win = (ioctl (pi->ctl_fd, PIOCSREG, gregs) >= 0);
+#endif
+ }
+
+ /* Policy: writing the regs invalidates our cache. */
+ pi->gregs_valid = 0;
+ return win;
+}
+
+/*
+ * Function: proc_set_fpregs
+ *
+ * Modify the floating point register set of the process or LWP.
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_set_fpregs (procinfo *pi)
+{
+ gdb_fpregset_t *fpregs;
+ int win;
+
+ if ((fpregs = proc_get_fpregs (pi)) == NULL)
+ return 0; /* get_fpregs has already warned */
+
+ if (pi->ctl_fd == 0 &&
+ open_procinfo_files (pi, FD_CTL) == 0)
+ {
+ return 0;
+ }
+ else
+ {
+#ifdef NEW_PROC_API
+ struct {
+ procfs_ctl_t cmd;
+ /* Use char array to avoid alignment issues. */
+ char fpregs[sizeof (gdb_fpregset_t)];
+ } arg;
+
+ arg.cmd = PCSFPREG;
+ memcpy (&arg.fpregs, fpregs, sizeof (arg.fpregs));
+ win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
+#else
+#ifdef PIOCTSFPREG
+ if (pi->tid == 0)
+ win = (ioctl (pi->ctl_fd, PIOCSFPREG, fpregs) >= 0);
+ else
+ {
+ struct {
+ long pr_count;
+ tid_t pr_error_thread;
+ tfpregset_t thread_1;
+ } thread_fpregs;
+
+ thread_fpregs.pr_count = 1;
+ thread_fpregs.thread_1.tid = pi->tid;
+ memcpy (&thread_fpregs.thread_1.pr_fpregs, fpregs,
+ sizeof (*fpregs));
+ win = (ioctl (pi->ctl_fd, PIOCTSFPREG, &thread_fpregs) >= 0);
+ }
+#else
+ win = (ioctl (pi->ctl_fd, PIOCSFPREG, fpregs) >= 0);
+#endif /* osf PIOCTSFPREG */
+#endif /* NEW_PROC_API */
+ }
+
+ /* Policy: writing the regs invalidates our cache. */
+ pi->fpregs_valid = 0;
+ return win;
+}
+
+/*
+ * Function: proc_kill
+ *
+ * Send a signal to the proc or lwp with the semantics of "kill()".
+ * Returns non-zero for success, zero for failure.
+ */
+
+int
+proc_kill (procinfo *pi, int signo)
+{
+ int win;
+
+ /*
+ * We might conceivably apply this operation to an LWP, and
+ * the LWP's ctl file descriptor might not be open.
+ */
+
+ if (pi->ctl_fd == 0 &&
+ open_procinfo_files (pi, FD_CTL) == 0)
+ {
+ return 0;
+ }
+ else
+ {
+#ifdef NEW_PROC_API
+ procfs_ctl_t cmd[2];
+
+ cmd[0] = PCKILL;
+ cmd[1] = signo;
+ win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
+#else /* ioctl method */
+ /* FIXME: do I need the Alpha OSF fixups present in
+ procfs.c/unconditionally_kill_inferior? Perhaps only for SIGKILL? */
+ win = (ioctl (pi->ctl_fd, PIOCKILL, &signo) >= 0);
+#endif
+ }
+
+ return win;
+}
+
+/*
+ * Function: proc_parent_pid
+ *
+ * Find the pid of the process that started this one.
+ * Returns the parent process pid, or zero.
+ */
+
+int
+proc_parent_pid (procinfo *pi)
+{
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return 0;
+
+ return pi->prstatus.pr_ppid;
+}
+
+
+/*
+ * Function: proc_set_watchpoint
+ *
+ */
+
+int
+proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags)
+{
+#if !defined (TARGET_HAS_HARDWARE_WATCHPOINTS)
+ return 0;
+#else
+/* Horrible hack! Detect Solaris 2.5, because this doesn't work on 2.5 */
+#if defined (PIOCOPENLWP) || defined (UNIXWARE) /* Solaris 2.5: bail out */
+ return 0;
+#else
+ struct {
+ procfs_ctl_t cmd;
+ char watch[sizeof (prwatch_t)];
+ } arg;
+ prwatch_t *pwatch;
+
+ pwatch = (prwatch_t *) &arg.watch;
+#ifdef PCAGENT /* Horrible hack: only defined on Solaris 2.6+ */
+ pwatch->pr_vaddr = (uintptr_t) address_to_host_pointer (addr);
+#else
+ pwatch->pr_vaddr = (caddr_t) address_to_host_pointer (addr);
+#endif
+ pwatch->pr_size = len;
+ pwatch->pr_wflags = wflags;
+#if defined(NEW_PROC_API) && defined (PCWATCH)
+ arg.cmd = PCWATCH;
+ return (write (pi->ctl_fd, &arg, sizeof (arg)) == sizeof (arg));
+#else
+#if defined (PIOCSWATCH)
+ return (ioctl (pi->ctl_fd, PIOCSWATCH, pwatch) >= 0);
+#else
+ return 0; /* Fail */
+#endif
+#endif
+#endif
+#endif
+}
+
+#ifdef TM_I386SOL2_H /* Is it hokey to use this? */
+
+#include <sys/sysi86.h>
+
+/*
+ * Function: proc_get_LDT_entry
+ *
+ * Inputs:
+ * procinfo *pi;
+ * int key;
+ *
+ * The 'key' is actually the value of the lower 16 bits of
+ * the GS register for the LWP that we're interested in.
+ *
+ * Return: matching ssh struct (LDT entry).
+ */
+
+struct ssd *
+proc_get_LDT_entry (procinfo *pi, int key)
+{
+ static struct ssd *ldt_entry = NULL;
+#ifdef NEW_PROC_API
+ char pathname[MAX_PROC_NAME_SIZE];
+ struct cleanup *old_chain = NULL;
+ int fd;
+
+ /* Allocate space for one LDT entry.
+ This alloc must persist, because we return a pointer to it. */
+ if (ldt_entry == NULL)
+ ldt_entry = (struct ssd *) xmalloc (sizeof (struct ssd));
+
+ /* Open the file descriptor for the LDT table. */
+ sprintf (pathname, "/proc/%d/ldt", pi->pid);
+ if ((fd = open_with_retry (pathname, O_RDONLY)) < 0)
+ {
+ proc_warn (pi, "proc_get_LDT_entry (open)", __LINE__);
+ return NULL;
+ }
+ /* Make sure it gets closed again! */
+ old_chain = make_cleanup_close (fd);
+
+ /* Now 'read' thru the table, find a match and return it. */
+ while (read (fd, ldt_entry, sizeof (struct ssd)) == sizeof (struct ssd))
+ {
+ if (ldt_entry->sel == 0 &&
+ ldt_entry->bo == 0 &&
+ ldt_entry->acc1 == 0 &&
+ ldt_entry->acc2 == 0)
+ break; /* end of table */
+ /* If key matches, return this entry. */
+ if (ldt_entry->sel == key)
+ return ldt_entry;
+ }
+ /* Loop ended, match not found. */
+ return NULL;
+#else
+ int nldt, i;
+ static int nalloc = 0;
+
+ /* Get the number of LDT entries. */
+ if (ioctl (pi->ctl_fd, PIOCNLDT, &nldt) < 0)
+ {
+ proc_warn (pi, "proc_get_LDT_entry (PIOCNLDT)", __LINE__);
+ return NULL;
+ }
+
+ /* Allocate space for the number of LDT entries. */
+ /* This alloc has to persist, 'cause we return a pointer to it. */
+ if (nldt > nalloc)
+ {
+ ldt_entry = (struct ssd *)
+ xrealloc (ldt_entry, (nldt + 1) * sizeof (struct ssd));
+ nalloc = nldt;
+ }
+
+ /* Read the whole table in one gulp. */
+ if (ioctl (pi->ctl_fd, PIOCLDT, ldt_entry) < 0)
+ {
+ proc_warn (pi, "proc_get_LDT_entry (PIOCLDT)", __LINE__);
+ return NULL;
+ }
+
+ /* Search the table and return the (first) entry matching 'key'. */
+ for (i = 0; i < nldt; i++)
+ if (ldt_entry[i].sel == key)
+ return &ldt_entry[i];
+
+ /* Loop ended, match not found. */
+ return NULL;
+#endif
+}
+
+#endif /* TM_I386SOL2_H */
+
+/* =============== END, non-thread part of /proc "MODULE" =============== */
+
+/* =================== Thread "MODULE" =================== */
+
+/* NOTE: you'll see more ifdefs and duplication of functions here,
+ since there is a different way to do threads on every OS. */
+
+/*
+ * Function: proc_get_nthreads
+ *
+ * Return the number of threads for the process
+ */
+
+#if defined (PIOCNTHR) && defined (PIOCTLIST)
+/*
+ * OSF version
+ */
+int
+proc_get_nthreads (procinfo *pi)
+{
+ int nthreads = 0;
+
+ if (ioctl (pi->ctl_fd, PIOCNTHR, &nthreads) < 0)
+ proc_warn (pi, "procfs: PIOCNTHR failed", __LINE__);
+
+ return nthreads;
+}
+
+#else
+#if defined (SYS_lwpcreate) || defined (SYS_lwp_create) /* FIXME: multiple */
+/*
+ * Solaris and Unixware version
+ */
+int
+proc_get_nthreads (procinfo *pi)
+{
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return 0;
+
+ /*
+ * NEW_PROC_API: only works for the process procinfo,
+ * because the LWP procinfos do not get prstatus filled in.
+ */
+#ifdef NEW_PROC_API
+ if (pi->tid != 0) /* find the parent process procinfo */
+ pi = find_procinfo_or_die (pi->pid, 0);
+#endif
+ return pi->prstatus.pr_nlwp;
+}
+
+#else
+/*
+ * Default version
+ */
+int
+proc_get_nthreads (procinfo *pi)
+{
+ return 0;
+}
+#endif
+#endif
+
+/*
+ * Function: proc_get_current_thread (LWP version)
+ *
+ * Return the ID of the thread that had an event of interest.
+ * (ie. the one that hit a breakpoint or other traced event).
+ * All other things being equal, this should be the ID of a
+ * thread that is currently executing.
+ */
+
+#if defined (SYS_lwpcreate) || defined (SYS_lwp_create) /* FIXME: multiple */
+/*
+ * Solaris and Unixware version
+ */
+int
+proc_get_current_thread (procinfo *pi)
+{
+ /*
+ * Note: this should be applied to the root procinfo for the process,
+ * not to the procinfo for an LWP. If applied to the procinfo for
+ * an LWP, it will simply return that LWP's ID. In that case,
+ * find the parent process procinfo.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+ if (!pi->status_valid)
+ if (!proc_get_status (pi))
+ return 0;
+
+#ifdef NEW_PROC_API
+ return pi->prstatus.pr_lwp.pr_lwpid;
+#else
+ return pi->prstatus.pr_who;
+#endif
+}
+
+#else
+#if defined (PIOCNTHR) && defined (PIOCTLIST)
+/*
+ * OSF version
+ */
+int
+proc_get_current_thread (procinfo *pi)
+{
+#if 0 /* FIXME: not ready for prime time? */
+ return pi->prstatus.pr_tid;
+#else
+ return 0;
+#endif
+}
+
+#else
+/*
+ * Default version
+ */
+int
+proc_get_current_thread (procinfo *pi)
+{
+ return 0;
+}
+
+#endif
+#endif
+
+/*
+ * Function: proc_update_threads
+ *
+ * Discover the IDs of all the threads within the process, and
+ * create a procinfo for each of them (chained to the parent).
+ *
+ * This unfortunately requires a different method on every OS.
+ *
+ * Return: non-zero for success, zero for failure.
+ */
+
+int
+proc_delete_dead_threads (procinfo *parent, procinfo *thread, void *ignore)
+{
+ if (thread && parent) /* sanity */
+ {
+ thread->status_valid = 0;
+ if (!proc_get_status (thread))
+ destroy_one_procinfo (&parent->thread_list, thread);
+ }
+ return 0; /* keep iterating */
+}
+
+#if defined (PIOCLSTATUS)
+/*
+ * Solaris 2.5 (ioctl) version
+ */
+int
+proc_update_threads (procinfo *pi)
+{
+ gdb_prstatus_t *prstatus;
+ struct cleanup *old_chain = NULL;
+ procinfo *thread;
+ int nlwp, i;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+ proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL);
+
+ if ((nlwp = proc_get_nthreads (pi)) <= 1)
+ return 1; /* Process is not multi-threaded; nothing to do. */
+
+ prstatus = xmalloc (sizeof (gdb_prstatus_t) * (nlwp + 1));
+
+ old_chain = make_cleanup (xfree, prstatus);
+ if (ioctl (pi->ctl_fd, PIOCLSTATUS, prstatus) < 0)
+ proc_error (pi, "update_threads (PIOCLSTATUS)", __LINE__);
+
+ /* Skip element zero, which represents the process as a whole. */
+ for (i = 1; i < nlwp + 1; i++)
+ {
+ if ((thread = create_procinfo (pi->pid, prstatus[i].pr_who)) == NULL)
+ proc_error (pi, "update_threads, create_procinfo", __LINE__);
+
+ memcpy (&thread->prstatus, &prstatus[i], sizeof (*prstatus));
+ thread->status_valid = 1;
+ }
+ pi->threads_valid = 1;
+ do_cleanups (old_chain);
+ return 1;
+}
+#else
+#ifdef NEW_PROC_API
+/*
+ * Unixware and Solaris 6 (and later) version
+ */
+static void
+do_closedir_cleanup (void *dir)
+{
+ closedir (dir);
+}
+
+int
+proc_update_threads (procinfo *pi)
+{
+ char pathname[MAX_PROC_NAME_SIZE + 16];
+ struct dirent *direntry;
+ struct cleanup *old_chain = NULL;
+ procinfo *thread;
+ DIR *dirp;
+ int lwpid;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+ proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL);
+
+ /*
+ * Unixware
+ *
+ * Note: this brute-force method is the only way I know of
+ * to accomplish this task on Unixware. This method will
+ * also work on Solaris 2.6 and 2.7. There is a much simpler
+ * and more elegant way to do this on Solaris, but the margins
+ * of this manuscript are too small to write it here... ;-)
+ */
+
+ strcpy (pathname, pi->pathname);
+ strcat (pathname, "/lwp");
+ if ((dirp = opendir (pathname)) == NULL)
+ proc_error (pi, "update_threads, opendir", __LINE__);
+
+ old_chain = make_cleanup (do_closedir_cleanup, dirp);
+ while ((direntry = readdir (dirp)) != NULL)
+ if (direntry->d_name[0] != '.') /* skip '.' and '..' */
+ {
+ lwpid = atoi (&direntry->d_name[0]);
+ if ((thread = create_procinfo (pi->pid, lwpid)) == NULL)
+ proc_error (pi, "update_threads, create_procinfo", __LINE__);
+ }
+ pi->threads_valid = 1;
+ do_cleanups (old_chain);
+ return 1;
+}
+#else
+#ifdef PIOCTLIST
+/*
+ * OSF version
+ */
+int
+proc_update_threads (procinfo *pi)
+{
+ int nthreads, i;
+ tid_t *threads;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+ proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL);
+
+ nthreads = proc_get_nthreads (pi);
+ if (nthreads < 2)
+ return 0; /* nothing to do for 1 or fewer threads */
+
+ threads = xmalloc (nthreads * sizeof (tid_t));
+
+ if (ioctl (pi->ctl_fd, PIOCTLIST, threads) < 0)
+ proc_error (pi, "procfs: update_threads (PIOCTLIST)", __LINE__);
+
+ for (i = 0; i < nthreads; i++)
+ {
+ if (!find_procinfo (pi->pid, threads[i]))
+ if (!create_procinfo (pi->pid, threads[i]))
+ proc_error (pi, "update_threads, create_procinfo", __LINE__);
+ }
+ pi->threads_valid = 1;
+ return 1;
+}
+#else
+/*
+ * Default version
+ */
+int
+proc_update_threads (procinfo *pi)
+{
+ return 0;
+}
+#endif /* OSF PIOCTLIST */
+#endif /* NEW_PROC_API */
+#endif /* SOL 2.5 PIOCLSTATUS */
+
+/*
+ * Function: proc_iterate_over_threads
+ *
+ * Description:
+ * Given a pointer to a function, call that function once
+ * for each lwp in the procinfo list, until the function
+ * returns non-zero, in which event return the value
+ * returned by the function.
+ *
+ * Note: this function does NOT call update_threads.
+ * If you want to discover new threads first, you must
+ * call that function explicitly. This function just makes
+ * a quick pass over the currently-known procinfos.
+ *
+ * Arguments:
+ * pi - parent process procinfo
+ * func - per-thread function
+ * ptr - opaque parameter for function.
+ *
+ * Return:
+ * First non-zero return value from the callee, or zero.
+ */
+
+int
+proc_iterate_over_threads (procinfo *pi,
+ int (*func) (procinfo *, procinfo *, void *),
+ void *ptr)
+{
+ procinfo *thread, *next;
+ int retval = 0;
+
+ /*
+ * We should never have to apply this operation to any procinfo
+ * except the one for the main process. If that ever changes
+ * for any reason, then take out the following clause and
+ * replace it with one that makes sure the ctl_fd is open.
+ */
+
+ if (pi->tid != 0)
+ pi = find_procinfo_or_die (pi->pid, 0);
+
+ for (thread = pi->thread_list; thread != NULL; thread = next)
+ {
+ next = thread->next; /* in case thread is destroyed */
+ if ((retval = (*func) (pi, thread, ptr)) != 0)
+ break;
+ }
+
+ return retval;
+}
+
+/* =================== END, Thread "MODULE" =================== */
+
+/* =================== END, /proc "MODULE" =================== */
+
+/* =================== GDB "MODULE" =================== */
+
+/*
+ * Here are all of the gdb target vector functions and their friends.
+ */
+
+static ptid_t do_attach (ptid_t ptid);
+static void do_detach (int signo);
+static int register_gdb_signals (procinfo *, gdb_sigset_t *);
+
+/*
+ * Function: procfs_debug_inferior
+ *
+ * Sets up the inferior to be debugged.
+ * Registers to trace signals, hardware faults, and syscalls.
+ * Note: does not set RLC flag: caller may want to customize that.
+ *
+ * Returns: zero for success (note! unlike most functions in this module)
+ * On failure, returns the LINE NUMBER where it failed!
+ */
+
+static int
+procfs_debug_inferior (procinfo *pi)
+{
+ fltset_t traced_faults;
+ gdb_sigset_t traced_signals;
+ sysset_t *traced_syscall_entries;
+ sysset_t *traced_syscall_exits;
+ int status;
+
+#ifdef PROCFS_DONT_TRACE_FAULTS
+ /* On some systems (OSF), we don't trace hardware faults.
+ Apparently it's enough that we catch them as signals.
+ Wonder why we don't just do that in general? */
+ premptyset (&traced_faults); /* don't trace faults. */
+#else
+ /* Register to trace hardware faults in the child. */
+ prfillset (&traced_faults); /* trace all faults... */
+ prdelset (&traced_faults, FLTPAGE); /* except page fault. */
+#endif
+ if (!proc_set_traced_faults (pi, &traced_faults))
+ return __LINE__;
+
+ /* Register to trace selected signals in the child. */
+ premptyset (&traced_signals);
+ if (!register_gdb_signals (pi, &traced_signals))
+ return __LINE__;
+
+
+ /* Register to trace the 'exit' system call (on entry). */
+ traced_syscall_entries = sysset_t_alloc (pi);
+ gdb_premptysysset (traced_syscall_entries);
+#ifdef SYS_exit
+ gdb_praddsysset (traced_syscall_entries, SYS_exit);
+#endif
+#ifdef SYS_lwpexit
+ gdb_praddsysset (traced_syscall_entries, SYS_lwpexit); /* And _lwp_exit... */
+#endif
+#ifdef SYS_lwp_exit
+ gdb_praddsysset (traced_syscall_entries, SYS_lwp_exit);
+#endif
+#ifdef DYNAMIC_SYSCALLS
+ {
+ int callnum = find_syscall (pi, "_exit");
+ if (callnum >= 0)
+ gdb_praddsysset (traced_syscall_entries, callnum);
+ }
+#endif
+
+ status = proc_set_traced_sysentry (pi, traced_syscall_entries);
+ xfree (traced_syscall_entries);
+ if (!status)
+ return __LINE__;
+
+#ifdef PRFS_STOPEXEC /* defined on OSF */
+ /* OSF method for tracing exec syscalls. Quoting:
+ Under Alpha OSF/1 we have to use a PIOCSSPCACT ioctl to trace
+ exits from exec system calls because of the user level loader. */
+ /* FIXME: make nice and maybe move into an access function. */
+ {
+ int prfs_flags;
+
+ if (ioctl (pi->ctl_fd, PIOCGSPCACT, &prfs_flags) < 0)
+ return __LINE__;
+
+ prfs_flags |= PRFS_STOPEXEC;
+
+ if (ioctl (pi->ctl_fd, PIOCSSPCACT, &prfs_flags) < 0)
+ return __LINE__;
+ }
+#else /* not PRFS_STOPEXEC */
+ /* Everyone else's (except OSF) method for tracing exec syscalls */
+ /* GW: Rationale...
+ Not all systems with /proc have all the exec* syscalls with the same
+ names. On the SGI, for example, there is no SYS_exec, but there
+ *is* a SYS_execv. So, we try to account for that. */
+
+ traced_syscall_exits = sysset_t_alloc (pi);
+ gdb_premptysysset (traced_syscall_exits);
+#ifdef SYS_exec
+ gdb_praddsysset (traced_syscall_exits, SYS_exec);
+#endif
+#ifdef SYS_execve
+ gdb_praddsysset (traced_syscall_exits, SYS_execve);
+#endif
+#ifdef SYS_execv
+ gdb_praddsysset (traced_syscall_exits, SYS_execv);
+#endif
+
+#ifdef SYS_lwpcreate
+ gdb_praddsysset (traced_syscall_exits, SYS_lwpcreate);
+ gdb_praddsysset (traced_syscall_exits, SYS_lwpexit);
+#endif
+
+#ifdef SYS_lwp_create /* FIXME: once only, please */
+ gdb_praddsysset (traced_syscall_exits, SYS_lwp_create);
+ gdb_praddsysset (traced_syscall_exits, SYS_lwp_exit);
+#endif
+
+#ifdef DYNAMIC_SYSCALLS
+ {
+ int callnum = find_syscall (pi, "execve");
+ if (callnum >= 0)
+ gdb_praddsysset (traced_syscall_exits, callnum);
+ callnum = find_syscall (pi, "ra_execve");
+ if (callnum >= 0)
+ gdb_praddsysset (traced_syscall_exits, callnum);
+ }
+#endif
+
+ status = proc_set_traced_sysexit (pi, traced_syscall_exits);
+ xfree (traced_syscall_exits);
+ if (!status)
+ return __LINE__;
+
+#endif /* PRFS_STOPEXEC */
+ return 0;
+}
+
+static void
+procfs_attach (char *args, int from_tty)
+{
+ char *exec_file;
+ int pid;
+
+ if (!args)
+ error_no_arg ("process-id to attach");
+
+ pid = atoi (args);
+ if (pid == getpid ())
+ error ("Attaching GDB to itself is not a good idea...");
+
+ if (from_tty)
+ {
+ exec_file = get_exec_file (0);
+
+ if (exec_file)
+ printf_filtered ("Attaching to program `%s', %s\n",
+ exec_file, target_pid_to_str (pid_to_ptid (pid)));
+ else
+ printf_filtered ("Attaching to %s\n",
+ target_pid_to_str (pid_to_ptid (pid)));
+
+ fflush (stdout);
+ }
+ inferior_ptid = do_attach (pid_to_ptid (pid));
+ push_target (&procfs_ops);
+}
+
+static void
+procfs_detach (char *args, int from_tty)
+{
+ char *exec_file;
+ int signo = 0;
+
+ if (from_tty)
+ {
+ exec_file = get_exec_file (0);
+ if (exec_file == 0)
+ exec_file = "";
+ printf_filtered ("Detaching from program: %s %s\n",
+ exec_file, target_pid_to_str (inferior_ptid));
+ fflush (stdout);
+ }
+ if (args)
+ signo = atoi (args);
+
+ do_detach (signo);
+ inferior_ptid = null_ptid;
+ unpush_target (&procfs_ops); /* Pop out of handling an inferior */
+}
+
+static ptid_t
+do_attach (ptid_t ptid)
+{
+ procinfo *pi;
+ int fail;
+
+ if ((pi = create_procinfo (PIDGET (ptid), 0)) == NULL)
+ perror ("procfs: out of memory in 'attach'");
+
+ if (!open_procinfo_files (pi, FD_CTL))
+ {
+ fprintf_filtered (gdb_stderr, "procfs:%d -- ", __LINE__);
+ sprintf (errmsg, "do_attach: couldn't open /proc file for process %d",
+ PIDGET (ptid));
+ dead_procinfo (pi, errmsg, NOKILL);
+ }
+
+ /* Stop the process (if it isn't already stopped). */
+ if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP))
+ {
+ pi->was_stopped = 1;
+ proc_prettyprint_why (proc_why (pi), proc_what (pi), 1);
+ }
+ else
+ {
+ pi->was_stopped = 0;
+ /* Set the process to run again when we close it. */
+ if (!proc_set_run_on_last_close (pi))
+ dead_procinfo (pi, "do_attach: couldn't set RLC.", NOKILL);
+
+ /* Now stop the process. */
+ if (!proc_stop_process (pi))
+ dead_procinfo (pi, "do_attach: couldn't stop the process.", NOKILL);
+ pi->ignore_next_sigstop = 1;
+ }
+ /* Save some of the /proc state to be restored if we detach. */
+ if (!proc_get_traced_faults (pi, &pi->saved_fltset))
+ dead_procinfo (pi, "do_attach: couldn't save traced faults.", NOKILL);
+ if (!proc_get_traced_signals (pi, &pi->saved_sigset))
+ dead_procinfo (pi, "do_attach: couldn't save traced signals.", NOKILL);
+ if (!proc_get_traced_sysentry (pi, pi->saved_entryset))
+ dead_procinfo (pi, "do_attach: couldn't save traced syscall entries.",
+ NOKILL);
+ if (!proc_get_traced_sysexit (pi, pi->saved_exitset))
+ dead_procinfo (pi, "do_attach: couldn't save traced syscall exits.",
+ NOKILL);
+ if (!proc_get_held_signals (pi, &pi->saved_sighold))
+ dead_procinfo (pi, "do_attach: couldn't save held signals.", NOKILL);
+
+ if ((fail = procfs_debug_inferior (pi)) != 0)
+ dead_procinfo (pi, "do_attach: failed in procfs_debug_inferior", NOKILL);
+
+ /* Let GDB know that the inferior was attached. */
+ attach_flag = 1;
+ return MERGEPID (pi->pid, proc_get_current_thread (pi));
+}
+
+static void
+do_detach (int signo)
+{
+ procinfo *pi;
+
+ /* Find procinfo for the main process */
+ pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); /* FIXME: threads */
+ if (signo)
+ if (!proc_set_current_signal (pi, signo))
+ proc_warn (pi, "do_detach, set_current_signal", __LINE__);
+
+ if (!proc_set_traced_signals (pi, &pi->saved_sigset))
+ proc_warn (pi, "do_detach, set_traced_signal", __LINE__);
+
+ if (!proc_set_traced_faults (pi, &pi->saved_fltset))
+ proc_warn (pi, "do_detach, set_traced_faults", __LINE__);
+
+ if (!proc_set_traced_sysentry (pi, pi->saved_entryset))
+ proc_warn (pi, "do_detach, set_traced_sysentry", __LINE__);
+
+ if (!proc_set_traced_sysexit (pi, pi->saved_exitset))
+ proc_warn (pi, "do_detach, set_traced_sysexit", __LINE__);
+
+ if (!proc_set_held_signals (pi, &pi->saved_sighold))
+ proc_warn (pi, "do_detach, set_held_signals", __LINE__);
+
+ if (signo || (proc_flags (pi) & (PR_STOPPED | PR_ISTOP)))
+ if (signo || !(pi->was_stopped) ||
+ query ("Was stopped when attached, make it runnable again? "))
+ {
+ /* Clear any pending signal. */
+ if (!proc_clear_current_fault (pi))
+ proc_warn (pi, "do_detach, clear_current_fault", __LINE__);
+
+ if (!proc_set_run_on_last_close (pi))
+ proc_warn (pi, "do_detach, set_rlc", __LINE__);
+ }
+
+ attach_flag = 0;
+ destroy_procinfo (pi);
+}
+
+/*
+ * fetch_registers
+ *
+ * Since the /proc interface cannot give us individual registers,
+ * we pay no attention to the (regno) argument, and just fetch them all.
+ * This results in the possibility that we will do unnecessarily many
+ * fetches, since we may be called repeatedly for individual registers.
+ * So we cache the results, and mark the cache invalid when the process
+ * is resumed.
+ */
+
+static void
+procfs_fetch_registers (int regno)
+{
+ gdb_fpregset_t *fpregs;
+ gdb_gregset_t *gregs;
+ procinfo *pi;
+ int pid;
+ int tid;
+
+ pid = PIDGET (inferior_ptid);
+ tid = TIDGET (inferior_ptid);
+
+ /* First look up procinfo for the main process. */
+ pi = find_procinfo_or_die (pid, 0);
+
+ /* If the event thread is not the same as GDB's requested thread
+ (ie. inferior_ptid), then look up procinfo for the requested
+ thread. */
+ if ((tid != 0) &&
+ (tid != proc_get_current_thread (pi)))
+ pi = find_procinfo_or_die (pid, tid);
+
+ if (pi == NULL)
+ error ("procfs: fetch_registers failed to find procinfo for %s",
+ target_pid_to_str (inferior_ptid));
+
+ if ((gregs = proc_get_gregs (pi)) == NULL)
+ proc_error (pi, "fetch_registers, get_gregs", __LINE__);
+
+ supply_gregset (gregs);
+
+ if (FP0_REGNUM >= 0) /* need floating point? */
+ {
+ if ((regno >= 0 && regno < FP0_REGNUM) ||
+ regno == PC_REGNUM ||
+ (NPC_REGNUM >= 0 && regno == NPC_REGNUM) ||
+ regno == FP_REGNUM ||
+ regno == SP_REGNUM)
+ return; /* not a floating point register */
+
+ if ((fpregs = proc_get_fpregs (pi)) == NULL)
+ proc_error (pi, "fetch_registers, get_fpregs", __LINE__);
+
+ supply_fpregset (fpregs);
+ }
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On
+ machines which store all the registers in one fell swoop, such as
+ /proc, this makes sure that registers contains all the registers
+ from the program being debugged. */
+
+static void
+procfs_prepare_to_store (void)
+{
+#ifdef CHILD_PREPARE_TO_STORE
+ CHILD_PREPARE_TO_STORE ();
+#endif
+}
+
+/*
+ * store_registers
+ *
+ * Since the /proc interface will not read individual registers,
+ * we will cache these requests until the process is resumed, and
+ * only then write them back to the inferior process.
+ *
+ * FIXME: is that a really bad idea? Have to think about cases
+ * where writing one register might affect the value of others, etc.
+ */
+
+static void
+procfs_store_registers (int regno)
+{
+ gdb_fpregset_t *fpregs;
+ gdb_gregset_t *gregs;
+ procinfo *pi;
+ int pid;
+ int tid;
+
+ pid = PIDGET (inferior_ptid);
+ tid = TIDGET (inferior_ptid);
+
+ /* First find procinfo for main process */
+ pi = find_procinfo_or_die (pid, 0);
+
+ /* If current lwp for process is not the same as requested thread
+ (ie. inferior_ptid), then find procinfo for the requested thread. */
+
+ if ((tid != 0) &&
+ (tid != proc_get_current_thread (pi)))
+ pi = find_procinfo_or_die (pid, tid);
+
+ if (pi == NULL)
+ error ("procfs: store_registers: failed to find procinfo for %s",
+ target_pid_to_str (inferior_ptid));
+
+ if ((gregs = proc_get_gregs (pi)) == NULL)
+ proc_error (pi, "store_registers, get_gregs", __LINE__);
+
+ fill_gregset (gregs, regno);
+ if (!proc_set_gregs (pi))
+ proc_error (pi, "store_registers, set_gregs", __LINE__);
+
+ if (FP0_REGNUM >= 0) /* need floating point? */
+ {
+ if ((regno >= 0 && regno < FP0_REGNUM) ||
+ regno == PC_REGNUM ||
+ (NPC_REGNUM >= 0 && regno == NPC_REGNUM) ||
+ regno == FP_REGNUM ||
+ regno == SP_REGNUM)
+ return; /* not a floating point register */
+
+ if ((fpregs = proc_get_fpregs (pi)) == NULL)
+ proc_error (pi, "store_registers, get_fpregs", __LINE__);
+
+ fill_fpregset (fpregs, regno);
+ if (!proc_set_fpregs (pi))
+ proc_error (pi, "store_registers, set_fpregs", __LINE__);
+ }
+}
+
+static int
+syscall_is_lwp_exit (procinfo *pi, int scall)
+{
+
+#ifdef SYS_lwp_exit
+ if (scall == SYS_lwp_exit)
+ return 1;
+#endif
+#ifdef SYS_lwpexit
+ if (scall == SYS_lwpexit)
+ return 1;
+#endif
+ return 0;
+}
+
+static int
+syscall_is_exit (procinfo *pi, int scall)
+{
+#ifdef SYS_exit
+ if (scall == SYS_exit)
+ return 1;
+#endif
+#ifdef DYNAMIC_SYSCALLS
+ if (find_syscall (pi, "_exit") == scall)
+ return 1;
+#endif
+ return 0;
+}
+
+static int
+syscall_is_exec (procinfo *pi, int scall)
+{
+#ifdef SYS_exec
+ if (scall == SYS_exec)
+ return 1;
+#endif
+#ifdef SYS_execv
+ if (scall == SYS_execv)
+ return 1;
+#endif
+#ifdef SYS_execve
+ if (scall == SYS_execve)
+ return 1;
+#endif
+#ifdef DYNAMIC_SYSCALLS
+ if (find_syscall (pi, "_execve"))
+ return 1;
+ if (find_syscall (pi, "ra_execve"))
+ return 1;
+#endif
+ return 0;
+}
+
+static int
+syscall_is_lwp_create (procinfo *pi, int scall)
+{
+#ifdef SYS_lwp_create
+ if (scall == SYS_lwp_create)
+ return 1;
+#endif
+#ifdef SYS_lwpcreate
+ if (scall == SYS_lwpcreate)
+ return 1;
+#endif
+ return 0;
+}
+
+/*
+ * Function: target_wait
+ *
+ * Retrieve the next stop event from the child process.
+ * If child has not stopped yet, wait for it to stop.
+ * Translate /proc eventcodes (or possibly wait eventcodes)
+ * into gdb internal event codes.
+ *
+ * Return: id of process (and possibly thread) that incurred the event.
+ * event codes are returned thru a pointer parameter.
+ */
+
+static ptid_t
+procfs_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ /* First cut: loosely based on original version 2.1 */
+ procinfo *pi;
+ int wstat;
+ int temp_tid;
+ ptid_t retval, temp_ptid;
+ int why, what, flags;
+ int retry = 0;
+
+wait_again:
+
+ retry++;
+ wstat = 0;
+ retval = pid_to_ptid (-1);
+
+ /* Find procinfo for main process */
+ pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ if (pi)
+ {
+ /* We must assume that the status is stale now... */
+ pi->status_valid = 0;
+ pi->gregs_valid = 0;
+ pi->fpregs_valid = 0;
+
+#if 0 /* just try this out... */
+ flags = proc_flags (pi);
+ why = proc_why (pi);
+ if ((flags & PR_STOPPED) && (why == PR_REQUESTED))
+ pi->status_valid = 0; /* re-read again, IMMEDIATELY... */
+#endif
+ /* If child is not stopped, wait for it to stop. */
+ if (!(proc_flags (pi) & (PR_STOPPED | PR_ISTOP)) &&
+ !proc_wait_for_stop (pi))
+ {
+ /* wait_for_stop failed: has the child terminated? */
+ if (errno == ENOENT)
+ {
+ int wait_retval;
+
+ /* /proc file not found; presumably child has terminated. */
+ wait_retval = wait (&wstat); /* "wait" for the child's exit */
+
+ if (wait_retval != PIDGET (inferior_ptid)) /* wrong child? */
+ error ("procfs: couldn't stop process %d: wait returned %d\n",
+ PIDGET (inferior_ptid), wait_retval);
+ /* FIXME: might I not just use waitpid?
+ Or try find_procinfo to see if I know about this child? */
+ retval = pid_to_ptid (wait_retval);
+ }
+ else if (errno == EINTR)
+ goto wait_again;
+ else
+ {
+ /* Unknown error from wait_for_stop. */
+ proc_error (pi, "target_wait (wait_for_stop)", __LINE__);
+ }
+ }
+ else
+ {
+ /* This long block is reached if either:
+ a) the child was already stopped, or
+ b) we successfully waited for the child with wait_for_stop.
+ This block will analyze the /proc status, and translate it
+ into a waitstatus for GDB.
+
+ If we actually had to call wait because the /proc file
+ is gone (child terminated), then we skip this block,
+ because we already have a waitstatus. */
+
+ flags = proc_flags (pi);
+ why = proc_why (pi);
+ what = proc_what (pi);
+
+ if (flags & (PR_STOPPED | PR_ISTOP))
+ {
+#ifdef PR_ASYNC
+ /* If it's running async (for single_thread control),
+ set it back to normal again. */
+ if (flags & PR_ASYNC)
+ if (!proc_unset_async (pi))
+ proc_error (pi, "target_wait, unset_async", __LINE__);
+#endif
+
+ if (info_verbose)
+ proc_prettyprint_why (why, what, 1);
+
+ /* The 'pid' we will return to GDB is composed of
+ the process ID plus the lwp ID. */
+ retval = MERGEPID (pi->pid, proc_get_current_thread (pi));
+
+ switch (why) {
+ case PR_SIGNALLED:
+ wstat = (what << 8) | 0177;
+ break;
+ case PR_SYSENTRY:
+ if (syscall_is_lwp_exit (pi, what))
+ {
+ printf_filtered ("[%s exited]\n",
+ target_pid_to_str (retval));
+ delete_thread (retval);
+ status->kind = TARGET_WAITKIND_SPURIOUS;
+ return retval;
+ }
+ else if (syscall_is_exit (pi, what))
+ {
+ /* Handle SYS_exit call only */
+ /* Stopped at entry to SYS_exit.
+ Make it runnable, resume it, then use
+ the wait system call to get its exit code.
+ Proc_run_process always clears the current
+ fault and signal.
+ Then return its exit status. */
+ pi->status_valid = 0;
+ wstat = 0;
+ /* FIXME: what we should do is return
+ TARGET_WAITKIND_SPURIOUS. */
+ if (!proc_run_process (pi, 0, 0))
+ proc_error (pi, "target_wait, run_process", __LINE__);
+ if (attach_flag)
+ {
+ /* Don't call wait: simulate waiting for exit,
+ return a "success" exit code. Bogus: what if
+ it returns something else? */
+ wstat = 0;
+ retval = inferior_ptid; /* ? ? ? */
+ }
+ else
+ {
+ int temp = wait (&wstat);
+
+ /* FIXME: shouldn't I make sure I get the right
+ event from the right process? If (for
+ instance) I have killed an earlier inferior
+ process but failed to clean up after it
+ somehow, I could get its termination event
+ here. */
+
+ /* If wait returns -1, that's what we return to GDB. */
+ if (temp < 0)
+ retval = pid_to_ptid (temp);
+ }
+ }
+ else
+ {
+ printf_filtered ("procfs: trapped on entry to ");
+ proc_prettyprint_syscall (proc_what (pi), 0);
+ printf_filtered ("\n");
+#ifndef PIOCSSPCACT
+ {
+ long i, nsysargs, *sysargs;
+
+ if ((nsysargs = proc_nsysarg (pi)) > 0 &&
+ (sysargs = proc_sysargs (pi)) != NULL)
+ {
+ printf_filtered ("%ld syscall arguments:\n", nsysargs);
+ for (i = 0; i < nsysargs; i++)
+ printf_filtered ("#%ld: 0x%08lx\n",
+ i, sysargs[i]);
+ }
+
+ }
+#endif
+ if (status)
+ {
+ /* How to exit gracefully, returning "unknown event" */
+ status->kind = TARGET_WAITKIND_SPURIOUS;
+ return inferior_ptid;
+ }
+ else
+ {
+ /* How to keep going without returning to wfi: */
+ target_resume (ptid, 0, TARGET_SIGNAL_0);
+ goto wait_again;
+ }
+ }
+ break;
+ case PR_SYSEXIT:
+ if (syscall_is_exec (pi, what))
+ {
+ /* Hopefully this is our own "fork-child" execing
+ the real child. Hoax this event into a trap, and
+ GDB will see the child about to execute its start
+ address. */
+ wstat = (SIGTRAP << 8) | 0177;
+ }
+ else if (syscall_is_lwp_create (pi, what))
+ {
+ /*
+ * This syscall is somewhat like fork/exec.
+ * We will get the event twice: once for the parent LWP,
+ * and once for the child. We should already know about
+ * the parent LWP, but the child will be new to us. So,
+ * whenever we get this event, if it represents a new
+ * thread, simply add the thread to the list.
+ */
+
+ /* If not in procinfo list, add it. */
+ temp_tid = proc_get_current_thread (pi);
+ if (!find_procinfo (pi->pid, temp_tid))
+ create_procinfo (pi->pid, temp_tid);
+
+ temp_ptid = MERGEPID (pi->pid, temp_tid);
+ /* If not in GDB's thread list, add it. */
+ if (!in_thread_list (temp_ptid))
+ {
+ printf_filtered ("[New %s]\n",
+ target_pid_to_str (temp_ptid));
+ add_thread (temp_ptid);
+ }
+ /* Return to WFI, but tell it to immediately resume. */
+ status->kind = TARGET_WAITKIND_SPURIOUS;
+ return inferior_ptid;
+ }
+ else if (syscall_is_lwp_exit (pi, what))
+ {
+ printf_filtered ("[%s exited]\n",
+ target_pid_to_str (retval));
+ delete_thread (retval);
+ status->kind = TARGET_WAITKIND_SPURIOUS;
+ return retval;
+ }
+ else if (0)
+ {
+ /* FIXME: Do we need to handle SYS_sproc,
+ SYS_fork, or SYS_vfork here? The old procfs
+ seemed to use this event to handle threads on
+ older (non-LWP) systems, where I'm assuming
+ that threads were actually separate processes.
+ Irix, maybe? Anyway, low priority for now. */
+ }
+ else
+ {
+ printf_filtered ("procfs: trapped on exit from ");
+ proc_prettyprint_syscall (proc_what (pi), 0);
+ printf_filtered ("\n");
+#ifndef PIOCSSPCACT
+ {
+ long i, nsysargs, *sysargs;
+
+ if ((nsysargs = proc_nsysarg (pi)) > 0 &&
+ (sysargs = proc_sysargs (pi)) != NULL)
+ {
+ printf_filtered ("%ld syscall arguments:\n", nsysargs);
+ for (i = 0; i < nsysargs; i++)
+ printf_filtered ("#%ld: 0x%08lx\n",
+ i, sysargs[i]);
+ }
+ }
+#endif
+ status->kind = TARGET_WAITKIND_SPURIOUS;
+ return inferior_ptid;
+ }
+ break;
+ case PR_REQUESTED:
+#if 0 /* FIXME */
+ wstat = (SIGSTOP << 8) | 0177;
+ break;
+#else
+ if (retry < 5)
+ {
+ printf_filtered ("Retry #%d:\n", retry);
+ pi->status_valid = 0;
+ goto wait_again;
+ }
+ else
+ {
+ /* If not in procinfo list, add it. */
+ temp_tid = proc_get_current_thread (pi);
+ if (!find_procinfo (pi->pid, temp_tid))
+ create_procinfo (pi->pid, temp_tid);
+
+ /* If not in GDB's thread list, add it. */
+ temp_ptid = MERGEPID (pi->pid, temp_tid);
+ if (!in_thread_list (temp_ptid))
+ {
+ printf_filtered ("[New %s]\n",
+ target_pid_to_str (temp_ptid));
+ add_thread (temp_ptid);
+ }
+
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = 0;
+ return retval;
+ }
+#endif
+ case PR_JOBCONTROL:
+ wstat = (what << 8) | 0177;
+ break;
+ case PR_FAULTED:
+ switch (what) { /* FIXME: FAULTED_USE_SIGINFO */
+#ifdef FLTWATCH
+ case FLTWATCH:
+ wstat = (SIGTRAP << 8) | 0177;
+ break;
+#endif
+#ifdef FLTKWATCH
+ case FLTKWATCH:
+ wstat = (SIGTRAP << 8) | 0177;
+ break;
+#endif
+ /* FIXME: use si_signo where possible. */
+ case FLTPRIV:
+#if (FLTILL != FLTPRIV) /* avoid "duplicate case" error */
+ case FLTILL:
+#endif
+ wstat = (SIGILL << 8) | 0177;
+ break;
+ case FLTBPT:
+#if (FLTTRACE != FLTBPT) /* avoid "duplicate case" error */
+ case FLTTRACE:
+#endif
+ wstat = (SIGTRAP << 8) | 0177;
+ break;
+ case FLTSTACK:
+ case FLTACCESS:
+#if (FLTBOUNDS != FLTSTACK) /* avoid "duplicate case" error */
+ case FLTBOUNDS:
+#endif
+ wstat = (SIGSEGV << 8) | 0177;
+ break;
+ case FLTIOVF:
+ case FLTIZDIV:
+#if (FLTFPE != FLTIOVF) /* avoid "duplicate case" error */
+ case FLTFPE:
+#endif
+ wstat = (SIGFPE << 8) | 0177;
+ break;
+ case FLTPAGE: /* Recoverable page fault */
+ default: /* FIXME: use si_signo if possible for fault */
+ retval = pid_to_ptid (-1);
+ printf_filtered ("procfs:%d -- ", __LINE__);
+ printf_filtered ("child stopped for unknown reason:\n");
+ proc_prettyprint_why (why, what, 1);
+ error ("... giving up...");
+ break;
+ }
+ break; /* case PR_FAULTED: */
+ default: /* switch (why) unmatched */
+ printf_filtered ("procfs:%d -- ", __LINE__);
+ printf_filtered ("child stopped for unknown reason:\n");
+ proc_prettyprint_why (why, what, 1);
+ error ("... giving up...");
+ break;
+ }
+ /*
+ * Got this far without error:
+ * If retval isn't in the threads database, add it.
+ */
+ if (PIDGET (retval) > 0 &&
+ !ptid_equal (retval, inferior_ptid) &&
+ !in_thread_list (retval))
+ {
+ /*
+ * We have a new thread.
+ * We need to add it both to GDB's list and to our own.
+ * If we don't create a procinfo, resume may be unhappy
+ * later.
+ */
+ printf_filtered ("[New %s]\n", target_pid_to_str (retval));
+ add_thread (retval);
+ if (find_procinfo (PIDGET (retval), TIDGET (retval)) == NULL)
+ create_procinfo (PIDGET (retval), TIDGET (retval));
+
+ /* In addition, it's possible that this is the first
+ * new thread we've seen, in which case we may not
+ * have created entries for inferior_ptid yet.
+ */
+ if (TIDGET (inferior_ptid) != 0)
+ {
+ if (!in_thread_list (inferior_ptid))
+ add_thread (inferior_ptid);
+ if (find_procinfo (PIDGET (inferior_ptid),
+ TIDGET (inferior_ptid)) == NULL)
+ create_procinfo (PIDGET (inferior_ptid),
+ TIDGET (inferior_ptid));
+ }
+ }
+ }
+ else /* flags do not indicate STOPPED */
+ {
+ /* surely this can't happen... */
+ printf_filtered ("procfs:%d -- process not stopped.\n",
+ __LINE__);
+ proc_prettyprint_flags (flags, 1);
+ error ("procfs: ...giving up...");
+ }
+ }
+
+ if (status)
+ store_waitstatus (status, wstat);
+ }
+
+ return retval;
+}
+
+/* Transfer LEN bytes between GDB address MYADDR and target address
+ MEMADDR. If DOWRITE is non-zero, transfer them to the target,
+ otherwise transfer them from the target. TARGET is unused.
+
+ The return value is 0 if an error occurred or no bytes were
+ transferred. Otherwise, it will be a positive value which
+ indicates the number of bytes transferred between gdb and the
+ target. (Note that the interface also makes provisions for
+ negative values, but this capability isn't implemented here.) */
+
+static int
+procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
+ struct mem_attrib *attrib, struct target_ops *target)
+{
+ procinfo *pi;
+ int nbytes = 0;
+
+ /* Find procinfo for main process */
+ pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ if (pi->as_fd == 0 &&
+ open_procinfo_files (pi, FD_AS) == 0)
+ {
+ proc_warn (pi, "xfer_memory, open_proc_files", __LINE__);
+ return 0;
+ }
+
+ if (lseek (pi->as_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
+ {
+ if (dowrite)
+ {
+#ifdef NEW_PROC_API
+ PROCFS_NOTE ("write memory: ");
+#else
+ PROCFS_NOTE ("write memory: \n");
+#endif
+ nbytes = write (pi->as_fd, myaddr, len);
+ }
+ else
+ {
+ PROCFS_NOTE ("read memory: \n");
+ nbytes = read (pi->as_fd, myaddr, len);
+ }
+ if (nbytes < 0)
+ {
+ nbytes = 0;
+ }
+ }
+ return nbytes;
+}
+
+/*
+ * Function: invalidate_cache
+ *
+ * Called by target_resume before making child runnable.
+ * Mark cached registers and status's invalid.
+ * If there are "dirty" caches that need to be written back
+ * to the child process, do that.
+ *
+ * File descriptors are also cached.
+ * As they are a limited resource, we cannot hold onto them indefinitely.
+ * However, as they are expensive to open, we don't want to throw them
+ * away indescriminately either. As a compromise, we will keep the
+ * file descriptors for the parent process, but discard any file
+ * descriptors we may have accumulated for the threads.
+ *
+ * Return value:
+ * As this function is called by iterate_over_threads, it always
+ * returns zero (so that iterate_over_threads will keep iterating).
+ */
+
+
+static int
+invalidate_cache (procinfo *parent, procinfo *pi, void *ptr)
+{
+ /*
+ * About to run the child; invalidate caches and do any other cleanup.
+ */
+
+#if 0
+ if (pi->gregs_dirty)
+ if (parent == NULL ||
+ proc_get_current_thread (parent) != pi->tid)
+ if (!proc_set_gregs (pi)) /* flush gregs cache */
+ proc_warn (pi, "target_resume, set_gregs",
+ __LINE__);
+ if (FP0_REGNUM >= 0)
+ if (pi->fpregs_dirty)
+ if (parent == NULL ||
+ proc_get_current_thread (parent) != pi->tid)
+ if (!proc_set_fpregs (pi)) /* flush fpregs cache */
+ proc_warn (pi, "target_resume, set_fpregs",
+ __LINE__);
+#endif
+
+ if (parent != NULL)
+ {
+ /* The presence of a parent indicates that this is an LWP.
+ Close any file descriptors that it might have open.
+ We don't do this to the master (parent) procinfo. */
+
+ close_procinfo_files (pi);
+ }
+ pi->gregs_valid = 0;
+ pi->fpregs_valid = 0;
+#if 0
+ pi->gregs_dirty = 0;
+ pi->fpregs_dirty = 0;
+#endif
+ pi->status_valid = 0;
+ pi->threads_valid = 0;
+
+ return 0;
+}
+
+#if 0
+/*
+ * Function: make_signal_thread_runnable
+ *
+ * A callback function for iterate_over_threads.
+ * Find the asynchronous signal thread, and make it runnable.
+ * See if that helps matters any.
+ */
+
+static int
+make_signal_thread_runnable (procinfo *process, procinfo *pi, void *ptr)
+{
+#ifdef PR_ASLWP
+ if (proc_flags (pi) & PR_ASLWP)
+ {
+ if (!proc_run_process (pi, 0, -1))
+ proc_error (pi, "make_signal_thread_runnable", __LINE__);
+ return 1;
+ }
+#endif
+ return 0;
+}
+#endif
+
+/*
+ * Function: target_resume
+ *
+ * Make the child process runnable. Normally we will then call
+ * procfs_wait and wait for it to stop again (unles gdb is async).
+ *
+ * Arguments:
+ * step: if true, then arrange for the child to stop again
+ * after executing a single instruction.
+ * signo: if zero, then cancel any pending signal.
+ * If non-zero, then arrange for the indicated signal
+ * to be delivered to the child when it runs.
+ * pid: if -1, then allow any child thread to run.
+ * if non-zero, then allow only the indicated thread to run.
+ ******* (not implemented yet)
+ */
+
+static void
+procfs_resume (ptid_t ptid, int step, enum target_signal signo)
+{
+ procinfo *pi, *thread;
+ int native_signo;
+
+ /* 2.1:
+ prrun.prflags |= PRSVADDR;
+ prrun.pr_vaddr = $PC; set resume address
+ prrun.prflags |= PRSTRACE; trace signals in pr_trace (all)
+ prrun.prflags |= PRSFAULT; trace faults in pr_fault (all but PAGE)
+ prrun.prflags |= PRCFAULT; clear current fault.
+
+ PRSTRACE and PRSFAULT can be done by other means
+ (proc_trace_signals, proc_trace_faults)
+ PRSVADDR is unnecessary.
+ PRCFAULT may be replaced by a PIOCCFAULT call (proc_clear_current_fault)
+ This basically leaves PRSTEP and PRCSIG.
+ PRCSIG is like PIOCSSIG (proc_clear_current_signal).
+ So basically PR_STEP is the sole argument that must be passed
+ to proc_run_process (for use in the prrun struct by ioctl). */
+
+ /* Find procinfo for main process */
+ pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+
+ /* First cut: ignore pid argument */
+ errno = 0;
+
+ /* Convert signal to host numbering. */
+ if (signo == 0 ||
+ (signo == TARGET_SIGNAL_STOP && pi->ignore_next_sigstop))
+ native_signo = 0;
+ else
+ native_signo = target_signal_to_host (signo);
+
+ pi->ignore_next_sigstop = 0;
+
+ /* Running the process voids all cached registers and status. */
+ /* Void the threads' caches first */
+ proc_iterate_over_threads (pi, invalidate_cache, NULL);
+ /* Void the process procinfo's caches. */
+ invalidate_cache (NULL, pi, NULL);
+
+ if (PIDGET (ptid) != -1)
+ {
+ /* Resume a specific thread, presumably suppressing the others. */
+ thread = find_procinfo (PIDGET (ptid), TIDGET (ptid));
+ if (thread != NULL)
+ {
+ if (thread->tid != 0)
+ {
+ /* We're to resume a specific thread, and not the others.
+ * Set the child process's PR_ASYNC flag.
+ */
+#ifdef PR_ASYNC
+ if (!proc_set_async (pi))
+ proc_error (pi, "target_resume, set_async", __LINE__);
+#endif
+#if 0
+ proc_iterate_over_threads (pi,
+ make_signal_thread_runnable,
+ NULL);
+#endif
+ pi = thread; /* substitute the thread's procinfo for run */
+ }
+ }
+ }
+
+ if (!proc_run_process (pi, step, native_signo))
+ {
+ if (errno == EBUSY)
+ warning ("resume: target already running. Pretend to resume, and hope for the best!\n");
+ else
+ proc_error (pi, "target_resume", __LINE__);
+ }
+}
+
+/*
+ * Function: register_gdb_signals
+ *
+ * Traverse the list of signals that GDB knows about
+ * (see "handle" command), and arrange for the target
+ * to be stopped or not, according to these settings.
+ *
+ * Returns non-zero for success, zero for failure.
+ */
+
+static int
+register_gdb_signals (procinfo *pi, gdb_sigset_t *signals)
+{
+ int signo;
+
+ for (signo = 0; signo < NSIG; signo ++)
+ if (signal_stop_state (target_signal_from_host (signo)) == 0 &&
+ signal_print_state (target_signal_from_host (signo)) == 0 &&
+ signal_pass_state (target_signal_from_host (signo)) == 1)
+ prdelset (signals, signo);
+ else
+ praddset (signals, signo);
+
+ return proc_set_traced_signals (pi, signals);
+}
+
+/*
+ * Function: target_notice_signals
+ *
+ * Set up to trace signals in the child process.
+ */
+
+static void
+procfs_notice_signals (ptid_t ptid)
+{
+ gdb_sigset_t signals;
+ procinfo *pi = find_procinfo_or_die (PIDGET (ptid), 0);
+
+ if (proc_get_traced_signals (pi, &signals) &&
+ register_gdb_signals (pi, &signals))
+ return;
+ else
+ proc_error (pi, "notice_signals", __LINE__);
+}
+
+/*
+ * Function: target_files_info
+ *
+ * Print status information about the child process.
+ */
+
+static void
+procfs_files_info (struct target_ops *ignore)
+{
+ printf_filtered ("\tUsing the running image of %s %s via /proc.\n",
+ attach_flag? "attached": "child",
+ target_pid_to_str (inferior_ptid));
+}
+
+/*
+ * Function: target_open
+ *
+ * A dummy: you don't open procfs.
+ */
+
+static void
+procfs_open (char *args, int from_tty)
+{
+ error ("Use the \"run\" command to start a Unix child process.");
+}
+
+/*
+ * Function: target_can_run
+ *
+ * This tells GDB that this target vector can be invoked
+ * for "run" or "attach".
+ */
+
+int procfs_suppress_run = 0; /* Non-zero if procfs should pretend not to
+ be a runnable target. Used by targets
+ that can sit atop procfs, such as solaris
+ thread support. */
+
+
+static int
+procfs_can_run (void)
+{
+ /* This variable is controlled by modules that sit atop procfs that
+ may layer their own process structure atop that provided here.
+ sol-thread.c does this because of the Solaris two-level thread
+ model. */
+
+ /* NOTE: possibly obsolete -- use the thread_stratum approach instead. */
+
+ return !procfs_suppress_run;
+}
+
+/*
+ * Function: target_stop
+ *
+ * Stop the child process asynchronously, as when the
+ * gdb user types control-c or presses a "stop" button.
+ *
+ * Works by sending kill(SIGINT) to the child's process group.
+ */
+
+static void
+procfs_stop (void)
+{
+ extern pid_t inferior_process_group;
+
+ kill (-inferior_process_group, SIGINT);
+}
+
+/*
+ * Function: unconditionally_kill_inferior
+ *
+ * Make it die. Wait for it to die. Clean up after it.
+ * Note: this should only be applied to the real process,
+ * not to an LWP, because of the check for parent-process.
+ * If we need this to work for an LWP, it needs some more logic.
+ */
+
+static void
+unconditionally_kill_inferior (procinfo *pi)
+{
+ int parent_pid;
+
+ parent_pid = proc_parent_pid (pi);
+#ifdef PROCFS_NEED_CLEAR_CURSIG_FOR_KILL
+ /* FIXME: use access functions */
+ /* Alpha OSF/1-3.x procfs needs a clear of the current signal
+ before the PIOCKILL, otherwise it might generate a corrupted core
+ file for the inferior. */
+ if (ioctl (pi->ctl_fd, PIOCSSIG, NULL) < 0)
+ {
+ printf_filtered ("unconditionally_kill: SSIG failed!\n");
+ }
+#endif
+#ifdef PROCFS_NEED_PIOCSSIG_FOR_KILL
+ /* Alpha OSF/1-2.x procfs needs a PIOCSSIG call with a SIGKILL signal
+ to kill the inferior, otherwise it might remain stopped with a
+ pending SIGKILL.
+ We do not check the result of the PIOCSSIG, the inferior might have
+ died already. */
+ {
+ gdb_siginfo_t newsiginfo;
+
+ memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
+ newsiginfo.si_signo = SIGKILL;
+ newsiginfo.si_code = 0;
+ newsiginfo.si_errno = 0;
+ newsiginfo.si_pid = getpid ();
+ newsiginfo.si_uid = getuid ();
+ /* FIXME: use proc_set_current_signal */
+ ioctl (pi->ctl_fd, PIOCSSIG, &newsiginfo);
+ }
+#else /* PROCFS_NEED_PIOCSSIG_FOR_KILL */
+ if (!proc_kill (pi, SIGKILL))
+ proc_error (pi, "unconditionally_kill, proc_kill", __LINE__);
+#endif /* PROCFS_NEED_PIOCSSIG_FOR_KILL */
+ destroy_procinfo (pi);
+
+ /* If pi is GDB's child, wait for it to die. */
+ if (parent_pid == getpid ())
+ /* FIXME: should we use waitpid to make sure we get the right event?
+ Should we check the returned event? */
+ {
+#if 0
+ int status, ret;
+
+ ret = waitpid (pi->pid, &status, 0);
+#else
+ wait (NULL);
+#endif
+ }
+}
+
+/*
+ * Function: target_kill_inferior
+ *
+ * We're done debugging it, and we want it to go away.
+ * Then we want GDB to forget all about it.
+ */
+
+static void
+procfs_kill_inferior (void)
+{
+ if (!ptid_equal (inferior_ptid, null_ptid)) /* ? */
+ {
+ /* Find procinfo for main process */
+ procinfo *pi = find_procinfo (PIDGET (inferior_ptid), 0);
+
+ if (pi)
+ unconditionally_kill_inferior (pi);
+ target_mourn_inferior ();
+ }
+}
+
+/*
+ * Function: target_mourn_inferior
+ *
+ * Forget we ever debugged this thing!
+ */
+
+static void
+procfs_mourn_inferior (void)
+{
+ procinfo *pi;
+
+ if (!ptid_equal (inferior_ptid, null_ptid))
+ {
+ /* Find procinfo for main process */
+ pi = find_procinfo (PIDGET (inferior_ptid), 0);
+ if (pi)
+ destroy_procinfo (pi);
+ }
+ unpush_target (&procfs_ops);
+ generic_mourn_inferior ();
+}
+
+/*
+ * Function: init_inferior
+ *
+ * When GDB forks to create a runnable inferior process,
+ * this function is called on the parent side of the fork.
+ * It's job is to do whatever is necessary to make the child
+ * ready to be debugged, and then wait for the child to synchronize.
+ */
+
+static void
+procfs_init_inferior (int pid)
+{
+ procinfo *pi;
+ gdb_sigset_t signals;
+ int fail;
+
+ /* This routine called on the parent side (GDB side)
+ after GDB forks the inferior. */
+
+ push_target (&procfs_ops);
+
+ if ((pi = create_procinfo (pid, 0)) == NULL)
+ perror ("procfs: out of memory in 'init_inferior'");
+
+ if (!open_procinfo_files (pi, FD_CTL))
+ proc_error (pi, "init_inferior, open_proc_files", __LINE__);
+
+ /*
+ xmalloc // done
+ open_procinfo_files // done
+ link list // done
+ prfillset (trace)
+ procfs_notice_signals
+ prfillset (fault)
+ prdelset (FLTPAGE)
+ PIOCWSTOP
+ PIOCSFAULT
+ */
+
+ /* If not stopped yet, wait for it to stop. */
+ if (!(proc_flags (pi) & PR_STOPPED) &&
+ !(proc_wait_for_stop (pi)))
+ dead_procinfo (pi, "init_inferior: wait_for_stop failed", KILL);
+
+ /* Save some of the /proc state to be restored if we detach. */
+ /* FIXME: Why? In case another debugger was debugging it?
+ We're it's parent, for Ghu's sake! */
+ if (!proc_get_traced_signals (pi, &pi->saved_sigset))
+ proc_error (pi, "init_inferior, get_traced_signals", __LINE__);
+ if (!proc_get_held_signals (pi, &pi->saved_sighold))
+ proc_error (pi, "init_inferior, get_held_signals", __LINE__);
+ if (!proc_get_traced_faults (pi, &pi->saved_fltset))
+ proc_error (pi, "init_inferior, get_traced_faults", __LINE__);
+ if (!proc_get_traced_sysentry (pi, pi->saved_entryset))
+ proc_error (pi, "init_inferior, get_traced_sysentry", __LINE__);
+ if (!proc_get_traced_sysexit (pi, pi->saved_exitset))
+ proc_error (pi, "init_inferior, get_traced_sysexit", __LINE__);
+
+ /* Register to trace selected signals in the child. */
+ prfillset (&signals);
+ if (!register_gdb_signals (pi, &signals))
+ proc_error (pi, "init_inferior, register_signals", __LINE__);
+
+ if ((fail = procfs_debug_inferior (pi)) != 0)
+ proc_error (pi, "init_inferior (procfs_debug_inferior)", fail);
+
+ /* FIXME: logically, we should really be turning OFF run-on-last-close,
+ and possibly even turning ON kill-on-last-close at this point. But
+ I can't make that change without careful testing which I don't have
+ time to do right now... */
+ /* Turn on run-on-last-close flag so that the child
+ will die if GDB goes away for some reason. */
+ if (!proc_set_run_on_last_close (pi))
+ proc_error (pi, "init_inferior, set_RLC", __LINE__);
+
+ /* The 'process ID' we return to GDB is composed of
+ the actual process ID plus the lwp ID. */
+ inferior_ptid = MERGEPID (pi->pid, proc_get_current_thread (pi));
+
+#ifdef START_INFERIOR_TRAPS_EXPECTED
+ startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
+#else
+ /* One trap to exec the shell, one to exec the program being debugged. */
+ startup_inferior (2);
+#endif /* START_INFERIOR_TRAPS_EXPECTED */
+}
+
+/*
+ * Function: set_exec_trap
+ *
+ * When GDB forks to create a new process, this function is called
+ * on the child side of the fork before GDB exec's the user program.
+ * Its job is to make the child minimally debuggable, so that the
+ * parent GDB process can connect to the child and take over.
+ * This function should do only the minimum to make that possible,
+ * and to synchronize with the parent process. The parent process
+ * should take care of the details.
+ */
+
+static void
+procfs_set_exec_trap (void)
+{
+ /* This routine called on the child side (inferior side)
+ after GDB forks the inferior. It must use only local variables,
+ because it may be sharing data space with its parent. */
+
+ procinfo *pi;
+ sysset_t *exitset;
+
+ if ((pi = create_procinfo (getpid (), 0)) == NULL)
+ perror_with_name ("procfs: create_procinfo failed in child.");
+
+ if (open_procinfo_files (pi, FD_CTL) == 0)
+ {
+ proc_warn (pi, "set_exec_trap, open_proc_files", __LINE__);
+ gdb_flush (gdb_stderr);
+ /* no need to call "dead_procinfo", because we're going to exit. */
+ _exit (127);
+ }
+
+#ifdef PRFS_STOPEXEC /* defined on OSF */
+ /* OSF method for tracing exec syscalls. Quoting:
+ Under Alpha OSF/1 we have to use a PIOCSSPCACT ioctl to trace
+ exits from exec system calls because of the user level loader. */
+ /* FIXME: make nice and maybe move into an access function. */
+ {
+ int prfs_flags;
+
+ if (ioctl (pi->ctl_fd, PIOCGSPCACT, &prfs_flags) < 0)
+ {
+ proc_warn (pi, "set_exec_trap (PIOCGSPCACT)", __LINE__);
+ gdb_flush (gdb_stderr);
+ _exit (127);
+ }
+ prfs_flags |= PRFS_STOPEXEC;
+
+ if (ioctl (pi->ctl_fd, PIOCSSPCACT, &prfs_flags) < 0)
+ {
+ proc_warn (pi, "set_exec_trap (PIOCSSPCACT)", __LINE__);
+ gdb_flush (gdb_stderr);
+ _exit (127);
+ }
+ }
+#else /* not PRFS_STOPEXEC */
+ /* Everyone else's (except OSF) method for tracing exec syscalls */
+ /* GW: Rationale...
+ Not all systems with /proc have all the exec* syscalls with the same
+ names. On the SGI, for example, there is no SYS_exec, but there
+ *is* a SYS_execv. So, we try to account for that. */
+
+ exitset = sysset_t_alloc (pi);
+ gdb_premptysysset (exitset);
+#ifdef SYS_exec
+ gdb_praddsysset (exitset, SYS_exec);
+#endif
+#ifdef SYS_execve
+ gdb_praddsysset (exitset, SYS_execve);
+#endif
+#ifdef SYS_execv
+ gdb_praddsysset (exitset, SYS_execv);
+#endif
+#ifdef DYNAMIC_SYSCALLS
+ {
+ int callnum = find_syscall (pi, "execve");
+
+ if (callnum >= 0)
+ gdb_praddsysset (exitset, callnum);
+
+ callnum = find_syscall (pi, "ra_execve");
+ if (callnum >= 0)
+ gdb_praddsysset (exitset, callnum);
+ }
+#endif /* DYNAMIC_SYSCALLS */
+
+ if (!proc_set_traced_sysexit (pi, exitset))
+ {
+ proc_warn (pi, "set_exec_trap, set_traced_sysexit", __LINE__);
+ gdb_flush (gdb_stderr);
+ _exit (127);
+ }
+#endif /* PRFS_STOPEXEC */
+
+ /* FIXME: should this be done in the parent instead? */
+ /* Turn off inherit on fork flag so that all grand-children
+ of gdb start with tracing flags cleared. */
+ if (!proc_unset_inherit_on_fork (pi))
+ proc_warn (pi, "set_exec_trap, unset_inherit", __LINE__);
+
+ /* Turn off run on last close flag, so that the child process
+ cannot run away just because we close our handle on it.
+ We want it to wait for the parent to attach. */
+ if (!proc_unset_run_on_last_close (pi))
+ proc_warn (pi, "set_exec_trap, unset_RLC", __LINE__);
+
+ /* FIXME: No need to destroy the procinfo --
+ we have our own address space, and we're about to do an exec! */
+ /*destroy_procinfo (pi);*/
+}
+
+/*
+ * Function: create_inferior
+ *
+ * This function is called BEFORE gdb forks the inferior process.
+ * Its only real responsibility is to set things up for the fork,
+ * and tell GDB which two functions to call after the fork (one
+ * for the parent, and one for the child).
+ *
+ * This function does a complicated search for a unix shell program,
+ * which it then uses to parse arguments and environment variables
+ * to be sent to the child. I wonder whether this code could not
+ * be abstracted out and shared with other unix targets such as
+ * infptrace?
+ */
+
+static void
+procfs_create_inferior (char *exec_file, char *allargs, char **env)
+{
+ char *shell_file = getenv ("SHELL");
+ char *tryname;
+ if (shell_file != NULL && strchr (shell_file, '/') == NULL)
+ {
+
+ /* We will be looking down the PATH to find shell_file. If we
+ just do this the normal way (via execlp, which operates by
+ attempting an exec for each element of the PATH until it
+ finds one which succeeds), then there will be an exec for
+ each failed attempt, each of which will cause a PR_SYSEXIT
+ stop, and we won't know how to distinguish the PR_SYSEXIT's
+ for these failed execs with the ones for successful execs
+ (whether the exec has succeeded is stored at that time in the
+ carry bit or some such architecture-specific and
+ non-ABI-specified place).
+
+ So I can't think of anything better than to search the PATH
+ now. This has several disadvantages: (1) There is a race
+ condition; if we find a file now and it is deleted before we
+ exec it, we lose, even if the deletion leaves a valid file
+ further down in the PATH, (2) there is no way to know exactly
+ what an executable (in the sense of "capable of being
+ exec'd") file is. Using access() loses because it may lose
+ if the caller is the superuser; failing to use it loses if
+ there are ACLs or some such. */
+
+ char *p;
+ char *p1;
+ /* FIXME-maybe: might want "set path" command so user can change what
+ path is used from within GDB. */
+ char *path = getenv ("PATH");
+ int len;
+ struct stat statbuf;
+
+ if (path == NULL)
+ path = "/bin:/usr/bin";
+
+ tryname = alloca (strlen (path) + strlen (shell_file) + 2);
+ for (p = path; p != NULL; p = p1 ? p1 + 1: NULL)
+ {
+ p1 = strchr (p, ':');
+ if (p1 != NULL)
+ len = p1 - p;
+ else
+ len = strlen (p);
+ strncpy (tryname, p, len);
+ tryname[len] = '\0';
+ strcat (tryname, "/");
+ strcat (tryname, shell_file);
+ if (access (tryname, X_OK) < 0)
+ continue;
+ if (stat (tryname, &statbuf) < 0)
+ continue;
+ if (!S_ISREG (statbuf.st_mode))
+ /* We certainly need to reject directories. I'm not quite
+ as sure about FIFOs, sockets, etc., but I kind of doubt
+ that people want to exec() these things. */
+ continue;
+ break;
+ }
+ if (p == NULL)
+ /* Not found. This must be an error rather than merely passing
+ the file to execlp(), because execlp() would try all the
+ exec()s, causing GDB to get confused. */
+ error ("procfs:%d -- Can't find shell %s in PATH",
+ __LINE__, shell_file);
+
+ shell_file = tryname;
+ }
+
+ fork_inferior (exec_file, allargs, env, procfs_set_exec_trap,
+ procfs_init_inferior, NULL, shell_file);
+
+ /* We are at the first instruction we care about. */
+ /* Pedal to the metal... */
+
+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
+}
+
+/*
+ * Function: notice_thread
+ *
+ * Callback for find_new_threads.
+ * Calls "add_thread".
+ */
+
+static int
+procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr)
+{
+ ptid_t gdb_threadid = MERGEPID (pi->pid, thread->tid);
+
+ if (!in_thread_list (gdb_threadid))
+ add_thread (gdb_threadid);
+
+ return 0;
+}
+
+/*
+ * Function: target_find_new_threads
+ *
+ * Query all the threads that the target knows about,
+ * and give them back to GDB to add to its list.
+ */
+
+void
+procfs_find_new_threads (void)
+{
+ procinfo *pi;
+
+ /* Find procinfo for main process */
+ pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ proc_update_threads (pi);
+ proc_iterate_over_threads (pi, procfs_notice_thread, NULL);
+}
+
+/*
+ * Function: target_thread_alive
+ *
+ * Return true if the thread is still 'alive'.
+ *
+ * This guy doesn't really seem to be doing his job.
+ * Got to investigate how to tell when a thread is really gone.
+ */
+
+static int
+procfs_thread_alive (ptid_t ptid)
+{
+ int proc, thread;
+ procinfo *pi;
+
+ proc = PIDGET (ptid);
+ thread = TIDGET (ptid);
+ /* If I don't know it, it ain't alive! */
+ if ((pi = find_procinfo (proc, thread)) == NULL)
+ return 0;
+
+ /* If I can't get its status, it ain't alive!
+ What's more, I need to forget about it! */
+ if (!proc_get_status (pi))
+ {
+ destroy_procinfo (pi);
+ return 0;
+ }
+ /* I couldn't have got its status if it weren't alive, so it's alive. */
+ return 1;
+}
+
+/*
+ * Function: target_pid_to_str
+ *
+ * Return a string to be used to identify the thread in
+ * the "info threads" display.
+ */
+
+char *
+procfs_pid_to_str (ptid_t ptid)
+{
+ static char buf[80];
+ int proc, thread;
+ procinfo *pi;
+
+ proc = PIDGET (ptid);
+ thread = TIDGET (ptid);
+ pi = find_procinfo (proc, thread);
+
+ if (thread == 0)
+ sprintf (buf, "Process %d", proc);
+ else
+ sprintf (buf, "LWP %d", thread);
+ return &buf[0];
+}
+
+/*
+ * Function: procfs_set_watchpoint
+ * Insert a watchpoint
+ */
+
+int
+procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag,
+ int after)
+{
+#ifndef UNIXWARE
+#ifndef AIX5
+ int pflags = 0;
+ procinfo *pi;
+
+ pi = find_procinfo_or_die (PIDGET (ptid) == -1 ?
+ PIDGET (inferior_ptid) : PIDGET (ptid), 0);
+
+ /* Translate from GDB's flags to /proc's */
+ if (len > 0) /* len == 0 means delete watchpoint */
+ {
+ switch (rwflag) { /* FIXME: need an enum! */
+ case hw_write: /* default watchpoint (write) */
+ pflags = WRITE_WATCHFLAG;
+ break;
+ case hw_read: /* read watchpoint */
+ pflags = READ_WATCHFLAG;
+ break;
+ case hw_access: /* access watchpoint */
+ pflags = READ_WATCHFLAG | WRITE_WATCHFLAG;
+ break;
+ case hw_execute: /* execution HW breakpoint */
+ pflags = EXEC_WATCHFLAG;
+ break;
+ default: /* Something weird. Return error. */
+ return -1;
+ }
+ if (after) /* Stop after r/w access is completed. */
+ pflags |= AFTER_WATCHFLAG;
+ }
+
+ if (!proc_set_watchpoint (pi, addr, len, pflags))
+ {
+ if (errno == E2BIG) /* Typical error for no resources */
+ return -1; /* fail */
+ /* GDB may try to remove the same watchpoint twice.
+ If a remove request returns no match, don't error. */
+ if (errno == ESRCH && len == 0)
+ return 0; /* ignore */
+ proc_error (pi, "set_watchpoint", __LINE__);
+ }
+#endif /* AIX5 */
+#endif /* UNIXWARE */
+ return 0;
+}
+
+/*
+ * Function: stopped_by_watchpoint
+ *
+ * Returns non-zero if process is stopped on a hardware watchpoint fault,
+ * else returns zero.
+ */
+
+int
+procfs_stopped_by_watchpoint (ptid_t ptid)
+{
+ procinfo *pi;
+
+ pi = find_procinfo_or_die (PIDGET (ptid) == -1 ?
+ PIDGET (inferior_ptid) : PIDGET (ptid), 0);
+
+ if (!pi) /* If no process, then not stopped by watchpoint! */
+ return 0;
+
+ if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP))
+ {
+ if (proc_why (pi) == PR_FAULTED)
+ {
+#ifdef FLTWATCH
+ if (proc_what (pi) == FLTWATCH)
+ return 1;
+#endif
+#ifdef FLTKWATCH
+ if (proc_what (pi) == FLTKWATCH)
+ return 1;
+#endif
+ }
+ }
+ return 0;
+}
+
+#ifdef TM_I386SOL2_H
+/*
+ * Function: procfs_find_LDT_entry
+ *
+ * Input:
+ * ptid_t ptid; // The GDB-style pid-plus-LWP.
+ *
+ * Return:
+ * pointer to the corresponding LDT entry.
+ */
+
+struct ssd *
+procfs_find_LDT_entry (ptid_t ptid)
+{
+ gdb_gregset_t *gregs;
+ int key;
+ procinfo *pi;
+
+ /* Find procinfo for the lwp. */
+ if ((pi = find_procinfo (PIDGET (ptid), TIDGET (ptid))) == NULL)
+ {
+ warning ("procfs_find_LDT_entry: could not find procinfo for %d:%d.",
+ PIDGET (ptid), TIDGET (ptid));
+ return NULL;
+ }
+ /* get its general registers. */
+ if ((gregs = proc_get_gregs (pi)) == NULL)
+ {
+ warning ("procfs_find_LDT_entry: could not read gregs for %d:%d.",
+ PIDGET (ptid), TIDGET (ptid));
+ return NULL;
+ }
+ /* Now extract the GS register's lower 16 bits. */
+ key = (*gregs)[GS] & 0xffff;
+
+ /* Find the matching entry and return it. */
+ return proc_get_LDT_entry (pi, key);
+}
+#endif /* TM_I386SOL2_H */
+
+/*
+ * Memory Mappings Functions:
+ */
+
+/*
+ * Function: iterate_over_mappings
+ *
+ * Call a callback function once for each mapping, passing it the mapping,
+ * an optional secondary callback function, and some optional opaque data.
+ * Quit and return the first non-zero value returned from the callback.
+ *
+ * Arguments:
+ * pi -- procinfo struct for the process to be mapped.
+ * func -- callback function to be called by this iterator.
+ * data -- optional opaque data to be passed to the callback function.
+ * child_func -- optional secondary function pointer to be passed
+ * to the child function.
+ *
+ * Return: First non-zero return value from the callback function,
+ * or zero.
+ */
+
+static int
+iterate_over_mappings (procinfo *pi, int (*child_func) (), void *data,
+ int (*func) (struct prmap *map,
+ int (*child_func) (),
+ void *data))
+{
+ char pathname[MAX_PROC_NAME_SIZE];
+ struct prmap *prmaps;
+ struct prmap *prmap;
+ int funcstat;
+ int map_fd;
+ int nmap;
+#ifdef NEW_PROC_API
+ struct stat sbuf;
+#endif
+
+ /* Get the number of mappings, allocate space,
+ and read the mappings into prmaps. */
+#ifdef NEW_PROC_API
+ /* Open map fd. */
+ sprintf (pathname, "/proc/%d/map", pi->pid);
+ if ((map_fd = open (pathname, O_RDONLY)) < 0)
+ proc_error (pi, "iterate_over_mappings (open)", __LINE__);
+
+ /* Make sure it gets closed again. */
+ make_cleanup_close (map_fd);
+
+ /* Use stat to determine the file size, and compute
+ the number of prmap_t objects it contains. */
+ if (fstat (map_fd, &sbuf) != 0)
+ proc_error (pi, "iterate_over_mappings (fstat)", __LINE__);
+
+ nmap = sbuf.st_size / sizeof (prmap_t);
+ prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
+ if (read (map_fd, (char *) prmaps, nmap * sizeof (*prmaps))
+ != (nmap * sizeof (*prmaps)))
+ proc_error (pi, "iterate_over_mappings (read)", __LINE__);
+#else
+ /* Use ioctl command PIOCNMAP to get number of mappings. */
+ if (ioctl (pi->ctl_fd, PIOCNMAP, &nmap) != 0)
+ proc_error (pi, "iterate_over_mappings (PIOCNMAP)", __LINE__);
+
+ prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
+ if (ioctl (pi->ctl_fd, PIOCMAP, prmaps) != 0)
+ proc_error (pi, "iterate_over_mappings (PIOCMAP)", __LINE__);
+#endif
+
+ for (prmap = prmaps; nmap > 0; prmap++, nmap--)
+ if ((funcstat = (*func) (prmap, child_func, data)) != 0)
+ return funcstat;
+
+ return 0;
+}
+
+/*
+ * Function: solib_mappings_callback
+ *
+ * Calls the supplied callback function once for each mapped address
+ * space in the process. The callback function receives an open
+ * file descriptor for the file corresponding to that mapped
+ * address space (if there is one), and the base address of the
+ * mapped space. Quit when the callback function returns a
+ * nonzero value, or at teh end of the mappings.
+ *
+ * Returns: the first non-zero return value of the callback function,
+ * or zero.
+ */
+
+int solib_mappings_callback (struct prmap *map,
+ int (*func) (int, CORE_ADDR),
+ void *data)
+{
+ procinfo *pi = data;
+ int fd;
+
+#ifdef NEW_PROC_API
+ char name[MAX_PROC_NAME_SIZE + sizeof (map->pr_mapname)];
+
+ if (map->pr_vaddr == 0 && map->pr_size == 0)
+ return -1; /* sanity */
+
+ if (map->pr_mapname[0] == 0)
+ {
+ fd = -1; /* no map file */
+ }
+ else
+ {
+ sprintf (name, "/proc/%d/object/%s", pi->pid, map->pr_mapname);
+ /* Note: caller's responsibility to close this fd! */
+ fd = open_with_retry (name, O_RDONLY);
+ /* Note: we don't test the above call for failure;
+ we just pass the FD on as given. Sometimes there is
+ no file, so the open may return failure, but that's
+ not a problem. */
+ }
+#else
+ fd = ioctl (pi->ctl_fd, PIOCOPENM, &map->pr_vaddr);
+ /* Note: we don't test the above call for failure;
+ we just pass the FD on as given. Sometimes there is
+ no file, so the ioctl may return failure, but that's
+ not a problem. */
+#endif
+ return (*func) (fd, (CORE_ADDR) map->pr_vaddr);
+}
+
+/*
+ * Function: proc_iterate_over_mappings
+ *
+ * Uses the unified "iterate_over_mappings" function
+ * to implement the exported interface to solib-svr4.c.
+ *
+ * Given a pointer to a function, call that function once for every
+ * mapped address space in the process. The callback function
+ * receives an open file descriptor for the file corresponding to
+ * that mapped address space (if there is one), and the base address
+ * of the mapped space. Quit when the callback function returns a
+ * nonzero value, or at teh end of the mappings.
+ *
+ * Returns: the first non-zero return value of the callback function,
+ * or zero.
+ */
+
+int
+proc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
+{
+ procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+
+ return iterate_over_mappings (pi, func, pi, solib_mappings_callback);
+}
+
+/*
+ * Function: find_memory_regions_callback
+ *
+ * Implements the to_find_memory_regions method.
+ * Calls an external function for each memory region.
+ * External function will have the signiture:
+ *
+ * int callback (CORE_ADDR vaddr,
+ * unsigned long size,
+ * int read, int write, int execute,
+ * void *data);
+ *
+ * Returns the integer value returned by the callback.
+ */
+
+static int
+find_memory_regions_callback (struct prmap *map,
+ int (*func) (CORE_ADDR,
+ unsigned long,
+ int, int, int,
+ void *),
+ void *data)
+{
+ return (*func) ((CORE_ADDR) map->pr_vaddr,
+ map->pr_size,
+ (map->pr_mflags & MA_READ) != 0,
+ (map->pr_mflags & MA_WRITE) != 0,
+ (map->pr_mflags & MA_EXEC) != 0,
+ data);
+}
+
+/*
+ * Function: proc_find_memory_regions
+ *
+ * External interface. Calls a callback function once for each
+ * mapped memory region in the child process, passing as arguments
+ * CORE_ADDR virtual_address,
+ * unsigned long size,
+ * int read, TRUE if region is readable by the child
+ * int write, TRUE if region is writable by the child
+ * int execute TRUE if region is executable by the child.
+ *
+ * Stops iterating and returns the first non-zero value
+ * returned by the callback.
+ */
+
+static int
+proc_find_memory_regions (int (*func) (CORE_ADDR,
+ unsigned long,
+ int, int, int,
+ void *),
+ void *data)
+{
+ procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+
+ return iterate_over_mappings (pi, func, data,
+ find_memory_regions_callback);
+}
+
+/*
+ * Function: mappingflags
+ *
+ * Returns an ascii representation of a memory mapping's flags.
+ */
+
+static char *
+mappingflags (flags)
+ long flags;
+{
+ static char asciiflags[8];
+
+ strcpy (asciiflags, "-------");
+#if defined (MA_PHYS)
+ if (flags & MA_PHYS)
+ asciiflags[0] = 'd';
+#endif
+ if (flags & MA_STACK)
+ asciiflags[1] = 's';
+ if (flags & MA_BREAK)
+ asciiflags[2] = 'b';
+ if (flags & MA_SHARED)
+ asciiflags[3] = 's';
+ if (flags & MA_READ)
+ asciiflags[4] = 'r';
+ if (flags & MA_WRITE)
+ asciiflags[5] = 'w';
+ if (flags & MA_EXEC)
+ asciiflags[6] = 'x';
+ return (asciiflags);
+}
+
+/*
+ * Function: info_mappings_callback
+ *
+ * Callback function, does the actual work for 'info proc mappings'.
+ */
+
+/* ARGSUSED */
+static int
+info_mappings_callback (struct prmap *map, int (*ignore) (), void *unused)
+{
+ char *data_fmt_string;
+
+ if (TARGET_ADDR_BIT == 32)
+ data_fmt_string = "\t%#10lx %#10lx %#10x %#10x %7s\n";
+ else
+ data_fmt_string = " %#18lx %#18lx %#10x %#10x %7s\n";
+
+ printf_filtered (data_fmt_string,
+ (unsigned long) map->pr_vaddr,
+ (unsigned long) map->pr_vaddr + map->pr_size - 1,
+ map->pr_size,
+#ifdef PCAGENT /* Horrible hack: only defined on Solaris 2.6+ */
+ (unsigned int) map->pr_offset,
+#else
+ map->pr_off,
+#endif
+ mappingflags (map->pr_mflags));
+
+ return 0;
+}
+
+/*
+ * Function: info_proc_mappings
+ *
+ * Implement the "info proc mappings" subcommand.
+ */
+
+static void
+info_proc_mappings (procinfo *pi, int summary)
+{
+ char *header_fmt_string;
+
+ if (TARGET_PTR_BIT == 32)
+ header_fmt_string = "\t%10s %10s %10s %10s %7s\n";
+ else
+ header_fmt_string = " %18s %18s %10s %10s %7s\n";
+
+ if (summary)
+ return; /* No output for summary mode. */
+
+ printf_filtered ("Mapped address spaces:\n\n");
+ printf_filtered (header_fmt_string,
+ "Start Addr",
+ " End Addr",
+ " Size",
+ " Offset",
+ "Flags");
+
+ iterate_over_mappings (pi, NULL, NULL, info_mappings_callback);
+ printf_filtered ("\n");
+}
+
+/*
+ * Function: info_proc_cmd
+ *
+ * Implement the "info proc" command.
+ */
+
+static void
+info_proc_cmd (char *args, int from_tty)
+{
+ struct cleanup *old_chain;
+ procinfo *process = NULL;
+ procinfo *thread = NULL;
+ char **argv = NULL;
+ char *tmp = NULL;
+ int pid = 0;
+ int tid = 0;
+ int mappings = 0;
+
+ old_chain = make_cleanup (null_cleanup, 0);
+ if (args)
+ {
+ if ((argv = buildargv (args)) == NULL)
+ nomem (0);
+ else
+ make_cleanup_freeargv (argv);
+ }
+ while (argv != NULL && *argv != NULL)
+ {
+ if (isdigit (argv[0][0]))
+ {
+ pid = strtoul (argv[0], &tmp, 10);
+ if (*tmp == '/')
+ tid = strtoul (++tmp, NULL, 10);
+ }
+ else if (argv[0][0] == '/')
+ {
+ tid = strtoul (argv[0] + 1, NULL, 10);
+ }
+ else if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0)
+ {
+ mappings = 1;
+ }
+ else
+ {
+ /* [...] */
+ }
+ argv++;
+ }
+ if (pid == 0)
+ pid = PIDGET (inferior_ptid);
+ if (pid == 0)
+ error ("No current process: you must name one.");
+ else
+ {
+ /* Have pid, will travel.
+ First see if it's a process we're already debugging. */
+ process = find_procinfo (pid, 0);
+ if (process == NULL)
+ {
+ /* No. So open a procinfo for it, but
+ remember to close it again when finished. */
+ process = create_procinfo (pid, 0);
+ make_cleanup (do_destroy_procinfo_cleanup, process);
+ if (!open_procinfo_files (process, FD_CTL))
+ proc_error (process, "info proc, open_procinfo_files", __LINE__);
+ }
+ }
+ if (tid != 0)
+ thread = create_procinfo (pid, tid);
+
+ if (process)
+ {
+ printf_filtered ("process %d flags:\n", process->pid);
+ proc_prettyprint_flags (proc_flags (process), 1);
+ if (proc_flags (process) & (PR_STOPPED | PR_ISTOP))
+ proc_prettyprint_why (proc_why (process), proc_what (process), 1);
+ if (proc_get_nthreads (process) > 1)
+ printf_filtered ("Process has %d threads.\n",
+ proc_get_nthreads (process));
+ }
+ if (thread)
+ {
+ printf_filtered ("thread %d flags:\n", thread->tid);
+ proc_prettyprint_flags (proc_flags (thread), 1);
+ if (proc_flags (thread) & (PR_STOPPED | PR_ISTOP))
+ proc_prettyprint_why (proc_why (thread), proc_what (thread), 1);
+ }
+
+ if (mappings)
+ {
+ info_proc_mappings (process, 0);
+ }
+
+ do_cleanups (old_chain);
+}
+
+static void
+proc_trace_syscalls (char *args, int from_tty, int entry_or_exit, int mode)
+{
+ procinfo *pi;
+ sysset_t *sysset;
+ int syscallnum = 0;
+
+ if (PIDGET (inferior_ptid) <= 0)
+ error ("you must be debugging a process to use this command.");
+
+ if (args == NULL || args[0] == 0)
+ error_no_arg ("system call to trace");
+
+ pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ if (isdigit (args[0]))
+ {
+ syscallnum = atoi (args);
+ if (entry_or_exit == PR_SYSENTRY)
+ sysset = proc_get_traced_sysentry (pi, NULL);
+ else
+ sysset = proc_get_traced_sysexit (pi, NULL);
+
+ if (sysset == NULL)
+ proc_error (pi, "proc-trace, get_traced_sysset", __LINE__);
+
+ if (mode == FLAG_SET)
+ gdb_praddsysset (sysset, syscallnum);
+ else
+ gdb_prdelsysset (sysset, syscallnum);
+
+ if (entry_or_exit == PR_SYSENTRY)
+ {
+ if (!proc_set_traced_sysentry (pi, sysset))
+ proc_error (pi, "proc-trace, set_traced_sysentry", __LINE__);
+ }
+ else
+ {
+ if (!proc_set_traced_sysexit (pi, sysset))
+ proc_error (pi, "proc-trace, set_traced_sysexit", __LINE__);
+ }
+ }
+}
+
+static void
+proc_trace_sysentry_cmd (char *args, int from_tty)
+{
+ proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_SET);
+}
+
+static void
+proc_trace_sysexit_cmd (char *args, int from_tty)
+{
+ proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_SET);
+}
+
+static void
+proc_untrace_sysentry_cmd (char *args, int from_tty)
+{
+ proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_RESET);
+}
+
+static void
+proc_untrace_sysexit_cmd (char *args, int from_tty)
+{
+ proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_RESET);
+}
+
+
+void
+_initialize_procfs (void)
+{
+ init_procfs_ops ();
+ add_target (&procfs_ops);
+ add_info ("proc", info_proc_cmd,
+ "Show /proc process information about any running process.\n\
+Specify process id, or use the program being debugged by default.\n\
+Specify keyword 'mappings' for detailed info on memory mappings.");
+ add_com ("proc-trace-entry", no_class, proc_trace_sysentry_cmd,
+ "Give a trace of entries into the syscall.");
+ add_com ("proc-trace-exit", no_class, proc_trace_sysexit_cmd,
+ "Give a trace of exits from the syscall.");
+ add_com ("proc-untrace-entry", no_class, proc_untrace_sysentry_cmd,
+ "Cancel a trace of entries into the syscall.");
+ add_com ("proc-untrace-exit", no_class, proc_untrace_sysexit_cmd,
+ "Cancel a trace of exits from the syscall.");
+}
+
+/* =================== END, GDB "MODULE" =================== */
+
+
+
+/* miscellaneous stubs: */
+/* The following satisfy a few random symbols mostly created by */
+/* the solaris threads implementation, which I will chase down */
+/* later. */
+
+/*
+ * Return a pid for which we guarantee
+ * we will be able to find a 'live' procinfo.
+ */
+
+ptid_t
+procfs_first_available (void)
+{
+ return pid_to_ptid (procinfo_list ? procinfo_list->pid : -1);
+}
+
+/* =================== GCORE .NOTE "MODULE" =================== */
+#if defined (UNIXWARE) || defined (PIOCOPENLWP) || defined (PCAGENT)
+/* gcore only implemented on solaris and unixware (so far) */
+
+static char *
+procfs_do_thread_registers (bfd *obfd, ptid_t ptid,
+ char *note_data, int *note_size)
+{
+ gdb_gregset_t gregs;
+ gdb_fpregset_t fpregs;
+ unsigned long merged_pid;
+
+ merged_pid = TIDGET (ptid) << 16 | PIDGET (ptid);
+
+ fill_gregset (&gregs, -1);
+#if defined (UNIXWARE)
+ note_data = (char *) elfcore_write_lwpstatus (obfd,
+ note_data,
+ note_size,
+ merged_pid,
+ stop_signal,
+ &gregs);
+#else
+ note_data = (char *) elfcore_write_prstatus (obfd,
+ note_data,
+ note_size,
+ merged_pid,
+ stop_signal,
+ &gregs);
+#endif
+ fill_fpregset (&fpregs, -1);
+ note_data = (char *) elfcore_write_prfpreg (obfd,
+ note_data,
+ note_size,
+ &fpregs,
+ sizeof (fpregs));
+ return note_data;
+}
+
+struct procfs_corefile_thread_data {
+ bfd *obfd;
+ char *note_data;
+ int *note_size;
+};
+
+static int
+procfs_corefile_thread_callback (procinfo *pi, procinfo *thread, void *data)
+{
+ struct procfs_corefile_thread_data *args = data;
+
+ if (pi != NULL && thread->tid != 0)
+ {
+ ptid_t saved_ptid = inferior_ptid;
+ inferior_ptid = MERGEPID (pi->pid, thread->tid);
+ args->note_data = procfs_do_thread_registers (args->obfd, inferior_ptid,
+ args->note_data,
+ args->note_size);
+ inferior_ptid = saved_ptid;
+ }
+ return 0;
+}
+
+static char *
+procfs_make_note_section (bfd *obfd, int *note_size)
+{
+ struct cleanup *old_chain;
+ gdb_gregset_t gregs;
+ gdb_fpregset_t fpregs;
+ char fname[16] = {'\0'};
+ char psargs[80] = {'\0'};
+ procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ char *note_data = NULL;
+ char *inf_args;
+ struct procfs_corefile_thread_data thread_args;
+
+ if (get_exec_file (0))
+ {
+ strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname));
+ strncpy (psargs, get_exec_file (0),
+ sizeof (psargs));
+
+ inf_args = get_inferior_args ();
+ if (inf_args && *inf_args &&
+ strlen (inf_args) < ((int) sizeof (psargs) - (int) strlen (psargs)))
+ {
+ strncat (psargs, " ",
+ sizeof (psargs) - strlen (psargs));
+ strncat (psargs, inf_args,
+ sizeof (psargs) - strlen (psargs));
+ }
+ }
+
+ note_data = (char *) elfcore_write_prpsinfo (obfd,
+ note_data,
+ note_size,
+ fname,
+ psargs);
+
+#ifdef UNIXWARE
+ fill_gregset (&gregs, -1);
+ note_data = elfcore_write_pstatus (obfd, note_data, note_size,
+ PIDGET (inferior_ptid),
+ stop_signal, &gregs);
+#endif
+
+ thread_args.obfd = obfd;
+ thread_args.note_data = note_data;
+ thread_args.note_size = note_size;
+ proc_iterate_over_threads (pi, procfs_corefile_thread_callback, &thread_args);
+
+ if (thread_args.note_data == note_data)
+ {
+ /* iterate_over_threads didn't come up with any threads;
+ just use inferior_ptid. */
+ note_data = procfs_do_thread_registers (obfd, inferior_ptid,
+ note_data, note_size);
+ }
+ else
+ {
+ note_data = thread_args.note_data;
+ }
+
+ make_cleanup (xfree, note_data);
+ return note_data;
+}
+#else /* !(Solaris or Unixware) */
+static char *
+procfs_make_note_section (bfd *obfd, int *note_size)
+{
+ error ("gcore not implemented for this host.");
+ return NULL; /* lint */
+}
+#endif /* Solaris or Unixware */
+/* =================== END GCORE .NOTE "MODULE" =================== */
diff --git a/gdb/ptx4-nat.c b/gdb/ptx4-nat.c
new file mode 100644
index 00000000000..65eef9d3518
--- /dev/null
+++ b/gdb/ptx4-nat.c
@@ -0,0 +1,211 @@
+/* Native-dependent code for ptx 4.0
+ Copyright 1988, 1989, 1991, 1992, 1994, 1999, 2000, 2001
+ 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 "defs.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include <sys/procfs.h>
+#include <sys/ptrace.h>
+#include <sys/param.h>
+#include <fcntl.h>
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* Given a pointer to a general register set in /proc format (gregset_t *),
+ unpack the register contents and supply them as gdb's idea of the current
+ register values. */
+
+void
+supply_gregset (gregset_t *gregsetp)
+{
+ supply_register (EAX_REGNUM, (char *) &(*gregsetp)[EAX]);
+ supply_register (EDX_REGNUM, (char *) &(*gregsetp)[EDX]);
+ supply_register (ECX_REGNUM, (char *) &(*gregsetp)[ECX]);
+ supply_register (EBX_REGNUM, (char *) &(*gregsetp)[EBX]);
+ supply_register (ESI_REGNUM, (char *) &(*gregsetp)[ESI]);
+ supply_register (EDI_REGNUM, (char *) &(*gregsetp)[EDI]);
+ supply_register (ESP_REGNUM, (char *) &(*gregsetp)[UESP]);
+ supply_register (EBP_REGNUM, (char *) &(*gregsetp)[EBP]);
+ supply_register (EIP_REGNUM, (char *) &(*gregsetp)[EIP]);
+ supply_register (EFLAGS_REGNUM, (char *) &(*gregsetp)[EFL]);
+}
+
+void
+fill_gregset (gregset_t *gregsetp, int regno)
+{
+ int regi;
+
+ for (regi = 0; regi < NUM_REGS; regi++)
+ {
+ if ((regno == -1) || (regno == regi))
+ {
+ (*gregsetp)[regi] = *(greg_t *) & registers[REGISTER_BYTE (regi)];
+ }
+ }
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), unpack the register contents and supply them as gdb's
+ idea of the current floating point register values. */
+
+void
+supply_fpregset (fpregset_t *fpregsetp)
+{
+ supply_fpu_registers ((struct fpusave *) &fpregsetp->fp_reg_set);
+ supply_fpa_registers ((struct fpasave *) &fpregsetp->f_wregs);
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), update the register specified by REGNO from gdb's idea
+ of the current floating point register set. If REGNO is -1, update
+ them all. */
+
+void
+fill_fpregset (fpregset_t *fpregsetp, int regno)
+{
+ int regi;
+ char *to;
+ char *from;
+
+ /* FIXME: see m68k-tdep.c for an example, for the m68k. */
+}
+
+/*
+ * This doesn't quite do the same thing as the procfs.c version, but give
+ * it the same name so we don't have to put an ifdef in solib.c.
+ */
+/* this could use elf_interpreter() from elfread.c */
+int
+proc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
+{
+ vaddr_t curseg, memptr;
+ pt_vseg_t pv;
+ int rv, cmperr;
+ sec_ptr interp_sec;
+ char *interp_content;
+ int interp_fd, funcstat;
+ unsigned int size;
+ char buf1[NBPG], buf2[NBPG];
+
+ /*
+ * The following is really vile. We can get the name of the
+ * shared library from the exec_bfd, and we can get a list of
+ * each virtual memory segment, but there is no simple way to
+ * find the mapped segment from the shared library (ala
+ * procfs's PIOCOPENMEM). As a pretty nasty kludge, we
+ * compare the virtual memory segment to the contents of the
+ * .interp file. If they match, we assume that we've got the
+ * right one.
+ */
+
+ /*
+ * TODO: for attach, use XPT_OPENT to get the executable, in
+ * case we're attached without knowning the executable's
+ * filename.
+ */
+
+#ifdef VERBOSE_DEBUG
+ printf ("proc_iter\n");
+#endif
+ interp_sec = bfd_get_section_by_name (exec_bfd, ".interp");
+ if (!interp_sec)
+ {
+ return 0;
+ }
+
+ size = bfd_section_size (exec_bfd, interp_sec);
+ interp_content = alloca (size);
+ if (0 == bfd_get_section_contents (exec_bfd, interp_sec,
+ interp_content, (file_ptr) 0, size))
+ {
+ return 0;
+ }
+
+#ifdef VERBOSE_DEBUG
+ printf ("proc_iter: \"%s\"\n", interp_content);
+#endif
+ interp_fd = open (interp_content, O_RDONLY, 0);
+ if (-1 == interp_fd)
+ {
+ return 0;
+ }
+
+ curseg = 0;
+ while (1)
+ {
+ rv = ptrace (PT_NEXT_VSEG, PIDGET (inferior_ptid), &pv, curseg);
+#ifdef VERBOSE_DEBUG
+ printf ("PT_NEXT_VSEG: rv %d errno %d\n", rv, errno);
+#endif
+ if (-1 == rv)
+ break;
+ if (0 == rv)
+ break;
+#ifdef VERBOSE_DEBUG
+ printf ("pv.pv_start 0x%x pv_size 0x%x pv_prot 0x%x\n",
+ pv.pv_start, pv.pv_size, pv.pv_prot);
+#endif
+ curseg = pv.pv_start + pv.pv_size;
+
+ rv = lseek (interp_fd, 0, SEEK_SET);
+ if (-1 == rv)
+ {
+ perror ("lseek");
+ close (interp_fd);
+ return 0;
+ }
+ for (memptr = pv.pv_start; memptr < pv.pv_start + pv.pv_size;
+ memptr += NBPG)
+ {
+#ifdef VERBOSE_DEBUG
+ printf ("memptr 0x%x\n", memptr);
+#endif
+ rv = read (interp_fd, buf1, NBPG);
+ if (-1 == rv)
+ {
+ perror ("read");
+ close (interp_fd);
+ return 0;
+ }
+ rv = ptrace (PT_RDATA_PAGE, PIDGET (inferior_ptid), buf2,
+ memptr);
+ if (-1 == rv)
+ {
+ perror ("ptrace");
+ close (interp_fd);
+ return 0;
+ }
+ cmperr = memcmp (buf1, buf2, NBPG);
+ if (cmperr)
+ break;
+ }
+ if (0 == cmperr)
+ {
+ /* this is it */
+ funcstat = (*func) (interp_fd, pv.pv_start);
+ break;
+ }
+ }
+ close (interp_fd);
+ return 0;
+}
diff --git a/gdb/rdi-share/Makefile.am b/gdb/rdi-share/Makefile.am
new file mode 100644
index 00000000000..4dd71d89d0d
--- /dev/null
+++ b/gdb/rdi-share/Makefile.am
@@ -0,0 +1,19 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+noinst_LIBRARIES = libangsd.a
+
+libangsd_a_SOURCES = ardi.c angel_bytesex.c crc.c devsw.c drivers.c etherdrv.c \
+ hostchan.c hsys.c logging.c msgbuild.c params.c rx.c \
+ serdrv.c serpardr.c tx.c unixcomm.c
+
+noinst_HEADERS = adp.h adperr.h angel.h ardi.h armdbg.h buffers.h \
+ chandefs.h channels.h chanpriv.h crc.h dbg_conf.h dbg_cp.h \
+ dbg_hif.h dbg_rdi.h devclnt.h devices.h devsw.h drivers.h \
+ angel_endian.h ethernet.h host.h hostchan.h hsys.h logging.h \
+ msgbuild.h params.h rxtx.h sys.h unixcomm.h angel_bytesex.h
+
+EXTRA_DIST = README.CYGNUS
+
+INCLUDES = -DRETRANS -DARM_RELEASE='"Berkeley Licence for Cygnus"'
diff --git a/gdb/rdi-share/Makefile.in b/gdb/rdi-share/Makefile.in
new file mode 100644
index 00000000000..f4afde6ca80
--- /dev/null
+++ b/gdb/rdi-share/Makefile.in
@@ -0,0 +1,296 @@
+# Makefile.in generated automatically by automake 1.3b from Makefile.am
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+htmldir = $(prefix)/html
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+CC = @CC@
+EXEEXT = @EXEEXT@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+
+AUTOMAKE_OPTIONS = cygnus
+
+noinst_LIBRARIES = libangsd.a
+
+libangsd_a_SOURCES = ardi.c angel_bytesex.c crc.c devsw.c drivers.c etherdrv.c \
+ hostchan.c hsys.c logging.c msgbuild.c params.c rx.c \
+ serdrv.c serpardr.c tx.c unixcomm.c
+
+noinst_HEADERS = adp.h adperr.h angel.h ardi.h armdbg.h buffers.h \
+ chandefs.h channels.h chanpriv.h crc.h dbg_conf.h dbg_cp.h \
+ dbg_hif.h dbg_rdi.h devclnt.h devices.h devsw.h drivers.h \
+ angel_endian.h ethernet.h host.h hostchan.h hsys.h logging.h \
+ msgbuild.h params.h rxtx.h sys.h unixcomm.h angel_bytesex.h
+
+EXTRA_DIST = README.CYGNUS
+
+INCLUDES = -DRETRANS -DARM_RELEASE='"Berkeley Licence for Cygnus"'
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir)
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libangsd_a_LIBADD =
+libangsd_a_OBJECTS = ardi.o angel_bytesex.o crc.o devsw.o drivers.o \
+etherdrv.o hostchan.o hsys.o logging.o msgbuild.o params.o rx.o \
+serdrv.o serpardr.o tx.o unixcomm.o
+AR = ar
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LINK = $(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(noinst_HEADERS)
+
+DIST_COMMON = Makefile.am Makefile.in aclocal.m4 configure configure.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+SOURCES = $(libangsd_a_SOURCES)
+OBJECTS = $(libangsd_a_OBJECTS)
+
+all: Makefile $(LIBRARIES) $(HEADERS)
+
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: @MAINT@Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINT@ configure.in
+ cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: @MAINT@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.c.o:
+ $(COMPILE) -c $<
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+libangsd.a: $(libangsd_a_OBJECTS) $(libangsd_a_DEPENDENCIES)
+ -rm -f libangsd.a
+ $(AR) cru libangsd.a $(libangsd_a_OBJECTS) $(libangsd_a_LIBADD)
+ $(RANLIB) libangsd.a
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @echo "========================"; \
+ echo "$(distdir).tar.gz is ready for distribution"; \
+ echo "========================"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done
+info:
+dvi:
+check:
+html:
+install-html:
+installcheck:
+install-info:
+install-exec:
+ @$(NORMAL_INSTALL)
+
+install-data:
+ @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+ @:
+
+uninstall:
+
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean: mostlyclean-noinstLIBRARIES mostlyclean-compile \
+ mostlyclean-tags mostlyclean-generic
+
+clean: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
+ mostlyclean
+
+distclean: distclean-noinstLIBRARIES distclean-compile distclean-tags \
+ distclean-generic clean
+ -rm -f config.status
+
+maintainer-clean: maintainer-clean-noinstLIBRARIES \
+ maintainer-clean-compile maintainer-clean-tags \
+ maintainer-clean-generic distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ -rm -f config.status
+
+.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info dvi installcheck \
+install-info install-exec install-data install uninstall all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/gdb/rdi-share/README.CYGNUS b/gdb/rdi-share/README.CYGNUS
new file mode 100644
index 00000000000..4bf06c93c3d
--- /dev/null
+++ b/gdb/rdi-share/README.CYGNUS
@@ -0,0 +1,6 @@
+This is a version of ARM's RDI library which has been been put under a
+free software license.
+
+See ARM's Software Development Tools Reference Manual (Remote
+Debugging chapter), and the file gdb/remote-rdi.c for information
+about how to use it.
diff --git a/gdb/rdi-share/aclocal.m4 b/gdb/rdi-share/aclocal.m4
new file mode 100644
index 00000000000..bab2ccf49cb
--- /dev/null
+++ b/gdb/rdi-share/aclocal.m4
@@ -0,0 +1,202 @@
+dnl aclocal.m4 generated automatically by aclocal 1.3b
+
+dnl Copyright 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AM_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION"))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+
+# serial 1
+
+AC_DEFUN(AM_PROG_INSTALL,
+[AC_REQUIRE([AC_PROG_INSTALL])
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+AC_SUBST(INSTALL_SCRIPT)dnl
+])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT($USE_MAINTAINER_MODE)
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINT=
+ else
+ MAINT='#M#'
+ fi
+ AC_SUBST(MAINT)dnl
+]
+)
+
+# Check to see if we're running under Win32, without using
+# AC_CANONICAL_*. If so, set output variable EXEEXT to ".exe".
+# Otherwise set it to "".
+
+dnl AM_EXEEXT()
+dnl This knows we add .exe if we're building in the Cygwin
+dnl environment. But if we're not, then it compiles a test program
+dnl to see if there is a suffix for executables.
+AC_DEFUN(AM_EXEEXT,
+[AC_REQUIRE([AM_CYGWIN])
+AC_REQUIRE([AM_MINGW32])
+AC_MSG_CHECKING([for executable suffix])
+AC_CACHE_VAL(am_cv_exeext,
+[if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+am_cv_exeext=.exe
+else
+cat > am_c_test.c << 'EOF'
+int main() {
+/* Nothing needed here */
+}
+EOF
+${CC-cc} -o am_c_test $CFLAGS $CPPFLAGS $LDFLAGS am_c_test.c $LIBS 1>&5
+am_cv_exeext=
+for file in am_c_test.*; do
+ case $file in
+ *.c) ;;
+ *.o) ;;
+ *) am_cv_exeext=`echo $file | sed -e s/am_c_test//` ;;
+ esac
+done
+rm -f am_c_test*])
+test x"${am_cv_exeext}" = x && am_cv_exeext=no
+fi
+EXEEXT=""
+test x"${am_cv_exeext}" != xno && EXEEXT=${am_cv_exeext}
+AC_MSG_RESULT(${am_cv_exeext})
+AC_SUBST(EXEEXT)])
+
+# Check to see if we're running under Cygwin, without using
+# AC_CANONICAL_*. If so, set output variable CYGWIN to "yes".
+# Otherwise set it to "no".
+
+dnl AM_CYGWIN()
+AC_DEFUN(AM_CYGWIN,
+[AC_CACHE_CHECK(for Cygwin environment, am_cv_cygwin,
+[AC_TRY_COMPILE(,[return __CYGWIN32__;],
+am_cv_cygwin=yes, am_cv_cygwin=no)
+rm -f conftest*])
+CYGWIN=
+test "$am_cv_cygwin" = yes && CYGWIN=yes])
+
+
+
+# Check to see if we're running under Mingw, without using
+# AC_CANONICAL_*. If so, set output variable MINGW32 to "yes".
+# Otherwise set it to "no".
+
+dnl AM_MINGW32()
+AC_DEFUN(AM_MINGW32,
+[AC_CACHE_CHECK(for Mingw32 environment, am_cv_mingw32,
+[AC_TRY_COMPILE(,[return __MINGW32__;],
+am_cv_mingw32=yes, am_cv_mingw32=no)
+rm -f conftest*])
+MINGW32=
+test "$am_cv_mingw32" = yes && MINGW32=yes])
+
diff --git a/gdb/rdi-share/adp.h b/gdb/rdi-share/adp.h
new file mode 100644
index 00000000000..099fa4db149
--- /dev/null
+++ b/gdb/rdi-share/adp.h
@@ -0,0 +1,2528 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ *
+ * INTRODUCTION
+ * ------------
+ * The early RDP message definitions were held in an ARM Ltd "armdbg"
+ * source file. Since the relevant header files were not exported
+ * publicly as part of an ARM Ltd core tools release, it was a problem
+ * for developers manipulating the target side of the protocol.
+ *
+ * For Angel, this new (ANSI 'C' clean) header file defines the ADP
+ * protocol. The header should be useable by both host and target
+ * systems, thus avoiding problems that can arise from duplicate
+ * definitions. Care has been taken in the construction of this header
+ * file to avoid any host/target differences.
+ *
+ * MESSAGE FORMAT
+ * --------------
+ * Format of the "data" section of debug and boot agent messages. This is
+ * the standard ADP (Angel Debug Protocol) message format:
+ *
+ * unsigned32 reason - Main debug reason code.
+ * unsigned32 debugID - Information describing host debug world;
+ * - private to host and used in any target initiated
+ * messages.
+ * unsigned32 OSinfo1 \ Target OS information to identify process/thread
+ * unsigned32 OSinfo2 / memory/world, etc. These two fields are target
+ * defined.
+ * byte args[n] - Data for message "reason" code.
+ *
+ * NOTE: The message format is the same for single threaded debugging,
+ * except that the "OSinfo" fields should be -1 (0xFFFFFFFF). Even
+ * single-threaded debugging *MAY* have different host specified
+ * debugID values, so the Angel debug system will preserve the "debugID"
+ * information for replies, and the relevant asynchronous target-to-host
+ * messages. The "debugID" is defined by the host-end of the
+ * protocol, and is used by the host to ensure that messages are
+ * routed to the correct handler program/veneer.
+ *
+ * The reason there are two target specified "OSinfo" words is because
+ * thread identifiers may not be unique when processes/tasks have
+ * private virtual address spaces. It allows more flexibility when
+ * supporting multi-threaded or O/S aware debugging.
+ *
+ * NOTE: The reason that there is no "size" information, is that the
+ * message IDs themselves encode the format of any arguments. Also it
+ * would be a duplication of information used by the physical
+ * transport layer (which is distinct from this logical message
+ * layer). Any routing of messages through programs, hosts,
+ * etc. should be performed at the physical layer, or the boundaries
+ * between physical layers. i.e. packet received on socket in host,
+ * and transferred to serial packet for passing on down the line.
+ *
+ * NOTE: Pointers aren't passed in messages because they are dangerous in
+ * a multi-threaded environment.
+ *
+ * ADP REASON CODE
+ * ---------------
+ * The message reason codes contain some information that ties them to
+ * the channel and direction that the message will be used with. This
+ * will ensure that even if the message "#define name" is not
+ * completely descriptive, the message reason code is.
+ *
+ * b31 = direction. 0=Host-to-Target; 1=Target-to-Host;
+ * b30-28 = debug agent multi-threaded control (see below)
+ * b27-24 = reserved. should be zero.
+ * b23-16 = channelid. The fixed Angel channel number
+ * (see "channels.h").
+ * b15-0 = message reason code.
+ *
+ * It is unfortunate that to aid the error-checking capabilities of
+ * the Angel communications we have changed the message numbers from
+ * the original ARM Ltd RDP. However this also has benefits, in that
+ * the Angel work is meant to be a clean break.
+ *
+ * However, it isn't so bad since even though the numbers are
+ * different, the majority of the reason codes have exactly the same
+ * functionality as the original RDP messages.
+ *
+ * NOTES
+ * -----
+ * It would be ideal to use "rpcgen" (or some equivalent) to
+ * automatically maintain compatibility between the target and host
+ * ends of the protocol. However, ARM Ltd expressed that the message
+ * handling should be hand-coded, to avoid dependance on external
+ * tools.
+ *
+ * All other channels have undefined data formats and are purely
+ * application defined. The C library "_sys_" support will provide a
+ * veneer to perform message block operations as required.
+ *
+ * It is IMPLIED that all of the ADP messages will fit within the
+ * buffer DATASIZE. This has a minimum value, calculated from
+ * BUFFERMINSIZE.
+ *
+ * All messages are passed and received to the channel system in little
+ * endian order (ie. use little endian order when writing a word as
+ * a sequence of bytes within a message).
+ *
+ * A reply / acknowledgement to an ADP message is always sent and has the
+ * same reason code as the original except that the TtoH / HtoT bit is
+ * reversed. This makes it simple to check that the reply really
+ * is a reply to the message which was just sent! [Boot Channel messages
+ * also require that this protocol is used].
+ */
+
+#ifndef angel_adp_h
+#define angel_adp_h
+
+#include "chandefs.h"
+
+
+/*
+ * Buffer minimum sizes
+ */
+
+/* the minimum target internal size */
+#define ADP_BUFFER_MIN_SIZE (256)
+
+/* a word is always reserved for internal use in the target */
+#define ADP_BUFFER_MAX_INTERNAL (sizeof(word))
+
+/* the minimum available data portion */
+#define ADP_BUFFER_MIN_DATASIZE \
+ (ADP_BUFFER_MIN_SIZE - ADP_BUFFER_MAX_INTERNAL - CHAN_HEADER_SIZE)
+
+/*
+ * the space taken up by the standard ADP header
+ * (reason, debugID, OSinfo1, OSinfo2)
+ */
+#define ADP_DEFAULT_HEADER_SIZE (4*sizeof(word))
+
+
+/* 8bit ADP version identification */
+#define ADPVSN (0x03)
+/* This value can be used to identify the protocol version supported
+ * by target or host systems. This version number should only be
+ * changed if the protocol undergoes a non-backward compatible
+ * change. It should *NOT* be used to reflect extensions to the
+ * protocol. Such extensions can be added to the existing protocol
+ * version by allocating new reason codes, and by extending the
+ * ADP_Info message to identify new features.
+ */
+
+/* The following value is used in the OSinfo fields for
+ * single-threaded messages, or where the host wants to alter the
+ * global CPU state. NOTE: The "debugID" field should always be
+ * defined by the host, and returned in target initiated messages. The
+ * only exception to this rule is the ADP_Booted message at the
+ * start-of-day.
+ */
+#define ADP_HandleUnknown (-1)
+
+/******************************************************************
+ *
+ * ADP reason code subfields
+ *
+ */
+
+/* The following bits are used to describe the basic direction of
+ * messages. This allows some extra checking of message validity to be
+ * performed, as well as providing a description of the message that
+ * may not be available in the "cpp" macro:
+ */
+#define HtoT ((unsigned)0 << 31) /* Host-to-Target message */
+#define TtoH ((unsigned)1 << 31) /* Target-to-Host message */
+
+/* The following bits are used to control how the target system
+ * executes whilst processing messages. This allows for O/S specific
+ * host-based debug programs to interrogate system structures whilst
+ * ensuring that the access is atomic within the constraints imposed
+ * by the target O/S.
+ *
+ * NOTE: That only the channel is inserted into the reason code
+ * automatically. Thus both direction and multi thread control bits
+ * must be added by the host / target.
+ */
+/* Disable FIQ whilst processing message */
+#define DisableFIQ (1 << 30)
+/* Disable IRQ whilst processing message */
+#define DisableIRQ (1 << 29)
+/* Disable O/S pre-emption whilst processing message */
+#define DisablePreemption (1 << 28)
+
+/* The channel identification number is held in the reason code as a
+ * check:
+ */
+#define ADPCHANNEL(b) (((b) & 0xFF) << 16)
+
+/* The following macro constructs the reason code number, from the
+ * various fields - note that the direction is NOT inlcuded since
+ * this depends on whether the Host or Target system is including
+ * this file!
+ */
+#define ADPREASON(c,r) (ADPCHANNEL(c) | ((r) & 0xFFFF))
+
+/* This macros is used when constructing manifests for sub-reason
+ * codes. At the moment it is identical to the main reason macro. If
+ * desired we could add a new bit that explicitly identifies the value
+ * as a sub-reason code, where the corresponding bit in the main
+ * message ID would be zero.
+ */
+#define ADPSUBREASON(c,r) (ADPCHANNEL(c) | ((r) & 0xFFFF))
+
+/* All other undefined bits are reserved, and should be zero. */
+
+
+
+/*****************************************************************
+ *
+ * channel_BOOT messages
+ *
+ */
+
+/* The BOOT agent only supports a few messages. They are used purely
+ * to control the "start-of-day" connection to a host program. All
+ * Angel systems with host communications *MUST* provide the BOOT
+ * agent, even if they don't have support for either the single- or
+ * multi-threaded debug agents.
+ *
+ * The way the BOOT channel will be used on startup will be as follows:
+ *
+ * a) Target board is powered up before host debugger is invoked
+ *
+ * After switching on the target and initialisation is completed the
+ * target will send an ADP_Booted or ADP_Reset message. The debugger
+ * has not been started yet so this message will not be received. In
+ * a serial world this makes it important that any buffers on the host
+ * side are flushed during initialisation of the debugger, and in an
+ * Ethernet world it makes it important that the target can cope with the
+ * message not being received.
+ *
+ * Eventually the Debugger will be started up and will send an
+ * ADP_Reboot or ADP_Reset request. The target will respond to this with
+ * an ADP_Reboot or ADP_Reset acknowldege and will then reboot, finally
+ * sending an ADP_Rebooted when it has done all it needs to do (very little
+ * in the case of ADP_Reset, but completely rebooting in the case of
+ * ADP_Reboot). Note that it is important that an ADP_Rebooted message is
+ * sent so that the Debugger does not attempt to send any data after it has
+ * made a request to ADP_Reboot and before it receives an ADP_Rebooted, as
+ * data can be lost be the target during this time.
+ *
+ * The target and host are now ready to start a debug session.
+ *
+ * b) Target board is powered up after host debugger is invoked
+ *
+ * The debugger will send an ADP_Reboot or ADP_Reset request, but will
+ * receive no reply until the target is powered up.
+/ *
+ * When the target is powered up then it will send an ADP_Rebooted
+ * message to the debugger. The debugger should accept this message
+ * even though it has received no ADP_Reboot or ADP_Reset acknowldege message
+ * from the target.
+ *
+ * The target and host are now ready to start a debug session.
+ *
+ *
+ * If at any point during the bootup sequence and ADP messages are
+ * sent down the S_DBG channel then they should be responded to with a
+ * RDI_NotInitialised error. [This should never happen however].
+ *
+ * An ADP_Boot or ADP Rebooted message should be accepted at
+ * any point, since it is possible for a catastrophe to occur (such as
+ * disconnecteing the host and target during a debug message) which
+ * requires that one or other end be reset.
+ *
+ */
+
+/*
+ * A list of parameter types - for now just baud rate
+ */
+typedef enum ADP_Parameter {
+ AP_PARAMS_START = 0xC000,
+ AP_BAUD_RATE = AP_PARAMS_START,
+ /* extra parameters go in here */
+#ifdef TEST_PARAMS
+ AP_CAFE_MENU, /* extra just for testing */
+#endif
+ AP_PARAMS_END
+} ADP_Parameter;
+
+#define AP_NUM_PARAMS (AP_PARAMS_END - AP_PARAMS_START)
+
+/*
+ * Parameter types should have associated semantics which can be represented
+ * within one word per parameter, or an associated enum for choices.
+ *
+ * AP_BAUD_RATE: the word contains the exact baud rate, eg. 9600, 38400.
+ */
+
+/* this is not strictly necessary, but it's an example */
+typedef enum ADP_BaudRate {
+ AB_9600 = 9600,
+ AB_19200 = 19200,
+ AB_38400 = 38400,
+ AB_57600 = 57600,
+ AB_115200 = 115200
+} ADP_BaudRate;
+
+#define AB_NUM_BAUD_RATES 5 /* this is more useful, for sizing arrays */
+
+/* This must be set to the max number of options per parameter type */
+#define AP_MAX_OPTIONS (AB_NUM_BAUD_RATES)
+
+
+#define ADP_Booted ADPREASON(CI_TBOOT,0)
+/* This message is sent by the target after the Angel system has been
+ * initialised. This message also contains information describing the
+ * Angel world. The information can then be used to check that the
+ * target debug agent and source debugger are compatible.
+ *
+ * Message arguments:
+ * word Angel message default buffer size.
+ * word Angel message large buffer size (may be same as default)
+ * word Angel version ; inc. type (e.g. boot ROM) See (1)
+ * word ADP version. See (2)
+ * word ARM Architecture info See (3)
+ * word ARM CPU information ; including target endianness. See (4)
+ * word Target hardware status. See (5)
+ * word Number of bytes in banner message
+ * bytes Startup banner message (single-threaded readable
+ * descriptive text - NOT NULL terminated).
+ *
+ * Reply:
+ * word status
+ *
+ * 'status' returns RDIError_NoError for success, and otherwise
+ * indicates an error.
+ */
+
+/* Angel version word [Reference(1)] : */
+/* Angel version number is a 16bit BCD value */
+#define ADP_ANGELVSN_MASK (0x0000FFFF)
+#define ADP_ANGELVSN_SHIFT (0)
+
+/* Type of Angel system */
+#define ADP_ANGELVSN_TYPE_MASK (0x00FF0000)
+#define ADP_ANGELVSN_TYPE_SHIFT (16)
+
+typedef enum {
+ ADP_AngelType_bootROM, /* Simple ROM system providing download capability */
+ ADP_AngelType_appROM, /* ROM based application */
+ ADP_AngelType_appDLOAD,/* Downloaded Angel based application */
+ ADP_AngelType_Last /* Unknown type. This typedef can be extended */
+ /* but if the host and target vsns differ */
+ /* Then one will spot that it dies not understand */
+} ADP_Angel_Types ; /* this field and can whinge appropriately */
+
+/* First unknown ADP_AngelType */
+#define ADP_ANGELVSN_UNKTYPE_MASK (0xFF000000)
+#define ADP_ANGELVSN_UNKYPE_SHIFT (24)
+
+/* Currently only 8 bits are used in the word: */
+/* ADP protocol supported by target [Reference (2)] */
+#define ADP_ANGELVSN_ADP_MASK (0x000000FF)
+#define ADP_ANGELVSN_ADP_SHIFT (0)
+
+/* ARM Architecture info: [Reference (3)] */
+/* ARM Architecture Verson of target CPU */
+#define ADP_ARM_ARCH_VSN_MASK (0x000000FF)
+#define ADP_ARM_ARCH_VSN_SHIFT (0)
+/* Does the processor support the Thumb Instruction Set */
+#define ADP_ARM_ARCH_THUMB (0x80000000)
+/* Does the processor support Long Multiplies */
+#define ADP_ARM_ARCH_LONGMUL (0x40000000)
+/* All other flags are current undefined, and should be zero. */
+
+/* The following flags describe the feature set of the processor: */
+/* Set if cpu supports little-endian model [Reference (4)] */
+#define ADP_CPU_LE (1 << 0)
+/* Set if cpu supports big-endian model */
+#define ADP_CPU_BE (1 << 1)
+/* Set if processor has a cache */
+#define ADP_CPU_CACHE (1 << 2)
+/* Set if processor has a MMU */
+#define ADP_CPU_MMU (1 << 3)
+/* All other flags are current undefined, and should be zero. */
+
+/* The following flags reflect current Target hardware status: */
+/* [Reference (5)] */
+/* 0 = no MMU or MMU off; 1 = MMU on */
+#define ADP_CPU_MMUOn (1 << 29)
+/* 0 = no cache or cache off; 1 = cache on */
+#define ADP_CPU_CacheOn (1 << 30)
+/* 0 = little-endian; 1 = big-endian */
+#define ADP_CPU_BigEndian (1U << 31)
+/* All other flags are current undefined, and should be zero. */
+
+
+#ifdef LINK_RECOVERY
+
+#define ADP_TargetResetIndication ADPREASON(CI_TBOOT, 1)
+/*
+ * If parameter negotiation is enabled at the target, it configures itself
+ * to various likely parameter settings and sends this message at each
+ * configuration. The message describes the default settings, and after
+ * sending at each configuration the target sets itself to the defaults
+ * it has just broadcast, to await either an ack on TBOOT or a request
+ * or reset indication on HBOOT.
+ *
+ * If the host receives this message successfully, it should reset to the
+ * indicated parameters and send a reply.
+ *
+ * Message arguments:
+ * word status (always 0, makes body same as
+ * ADP_ParamNegotiate response)
+ * word n-parameters
+ * n-parameters * {
+ * word ADP_Parameter
+ * word parameter-value
+ * }
+ *
+ * Reply:
+ * - empty acknowledgement
+ */
+
+#endif /* def LINK_RECOVERY */
+
+typedef enum ADP_Boot_Ack {
+ AB_NORMAL_ACK, /* will comply, immediate booted message */
+ AB_LATE_ACK, /* will comply, late startup */
+ AB_ERROR /* cannot comply */
+} ADP_Boot_Ack;
+
+/* If the host sets neither of these in the word sent on a Reset / Reboot
+ * then it doesn;t care about the endianess of the target
+ */
+#define ADP_BootHostFeature_LittleEnd 0x80000000
+#define ADP_BootHostFeature_BigEnd 0x40000000
+
+#define ADP_Reboot ADPREASON(CI_HBOOT,2)
+/* This message is sent when the host wants the target system to be
+ * completely reset, back to the boot monitor Angel. This is the
+ * method of the host forcing a cold-reboot.
+ * Note that an acknowledgement message will be sent immediately and
+ * that this must be sent before the target can reset.
+ *
+ * The parameter to this function is a bitset of host supported
+ * features. (in fact the same as ADP_Reset below. This can be used by
+ * the target system to avoid using debug channel bandwidth raising
+ * messages that will be ignored by the host.
+ *
+ * Parameters:
+ * word host supported features (see above)
+ *
+ * Reply:
+ * word status, one of enum ADP_Boot_Ack above.
+ *
+ * Currently there are no such features defined, so the word indicating
+ * host supported features should be set to 0.
+ */
+
+
+
+#define ADP_Reset ADPREASON(CI_HBOOT,3)
+/* This message is a request from the host, which should eventually
+ * result in the "ADP_Booted" message being sent by the target.
+ * Note that an acknowledgement message will be sent immediately and
+ * that this must be sent before the target can reset.
+ * This reset message is *ALWAYS* treated as a warm boot, with the target
+ * preserving as much state as possible.
+ *
+ * The parameter to this function is a bitset of host supported
+ * features. This can be used by the target system to avoid using
+ * debug channel bandwitdth raising messages that will be ignored by
+ * the host.
+ *
+ * Parameters:
+ * word host supported features (see above)
+ *
+ * Reply:
+ * word status, one of enum ADP_Boot_Ack above.
+ *
+ * Currently there are no such features defined, so the word indicating
+ * host supported features should be set to 0.
+ */
+
+
+#ifdef LINK_RECOVERY
+
+#define ADP_HostResetIndication ADPREASON(CI_HBOOT, 4)
+/*
+ * This is as for ADP_TargetResetIndication, but is sent by the host when
+ * it first starts up in case the target is listening at a non-default
+ * setting. Having sent at various configurations, the host then listens
+ * at the defaults it has just broadcast, to await either an ack on HBOOT
+ * or a reset indication on TBOOT.
+ *
+ * For arguments and reply, see ADP_TargetResetIndication.
+ */
+
+#endif /* def LINK_RECOVERY */
+
+
+#define ADP_ParamNegotiate ADPREASON(CI_HBOOT, 5)
+/*
+ * The host sends this messages to negotiate new parameters with the target.
+ * For each parameter the host specifies a range of possibilities, starting
+ * with the most favoured. All possible combinations of parameters
+ * must be valid.
+ *
+ * If the target can operate at a combination of the offered parameters,
+ * it will reply with the parameters it is willing to use. AFTER sending
+ * the reply, the target switches to this combination. On receiving the
+ * reply, the host will switch to the new combination and send a LinkCheck
+ * message (see below).
+ *
+ * If the target cannot operate at any combination of the offered parameters,
+ * it will reply with an error status.
+ *
+ * Message arguments:
+ * word n-parameter-blocks
+ * n-parameter-blocks * {
+ * word ADP_Parameter
+ * word n-options
+ * n-options * { word parameter-value }
+ * }
+ *
+ * Reply:
+ * word status
+ * if (status == RDIError_NoError) {
+ * word n-parameters
+ * n-parameters * {
+ * word ADP_Parameter
+ * word chosen-value
+ * }
+ * }
+ */
+
+#define ADP_LinkCheck ADPREASON(CI_HBOOT, 6)
+/*
+ * This should be the first message that the host sends after a successful
+ * parameter negotiation. It is really just a 'ping'.
+ *
+ * Message arguments:
+ * - empty message
+ *
+ * Reply:
+ * - empty acknowledgement
+ */
+
+
+/********************************************************************
+ *
+ * CI_HADP messages
+ *
+ */
+
+#define ADP_HADPUnrecognised ADPREASON(CI_HADP,0)
+/* This message is unusual in that it is normally sent in reply to
+ * another message which is not understood. This is an exception
+ * to the normal protocol which says that a reply must have the
+ * same base reason code as the original. There is a single reply
+ * parameter which is the reason code which was not understood.
+ *
+ * As well as being a reply this message can also be sent and will
+ * return as if this message were unrecognised!
+ *
+ * Parameters:
+ * none
+ *
+ * Reply:
+ * word reason code which was not recognised
+ */
+
+
+#define ADP_Info ADPREASON(CI_HADP,1)
+/* This is the new ADP information message. It is used to interrogate
+ * the target debug agent. It provides information on the processor,
+ * as well as the state of the debug world. This allows the host to
+ * configure itself to the capabilities of the target.
+ *
+ * We try not to use feature bitsets, since we could quickly run out
+ * of known bits. Thus when the feature set is extended, this can be
+ * done in a couple of supported ways:
+ *
+ * If an undivided reason code is to be added (no reason subcodes)
+ * then add a new ADP_Info code which responds with a flag indicating
+ * whether that feature is supported by the target. If this has not
+ * even been implemented then the reply will be ADP_HADPUnrecognised
+ *
+ * If a reason code which is subdivided into reason subcodes is
+ * added then reason subcode 0 should be set aside to indicate
+ * whether the functionality of that reason code is supported
+ * by the target. If it is not even implemented then the reply will
+ * be ADP_Unrecognised.
+ *
+ * The first parameter to ADP_Info is a reason subcode, and subsequent
+ * parameters are defined by that subcode
+ *
+ * Parameters:
+ * word reason subcode
+ * other arguments as reason subcode determines.
+ *
+ * Reply:
+ * word reason subcode
+ * other argument as reason subcode determines
+ */
+
+/* ADP_Info reason subcodes: */
+
+
+
+#define ADP_Info_NOP ADPSUBREASON(CI_HADP,0)
+/* ADP_Info_NOP
+ * ------------
+ * Summary: This message is used to check for ADP_Info being supported.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' returns RDIError_NoError for success, non-zero indicates an error.
+ * If an error is returned then there is no handler for the ADP_Info
+ * message. The normal action will be to return an OK status.
+ */
+
+
+#define ADP_Info_Target ADPSUBREASON(CI_HADP,1)
+/* ADP_Info_Target
+ * ---------------
+ * Summary:
+ * This reason code is used to interrogate target system details.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word bitset, word model)
+ *
+ * 'status' is RDIError_NoError to indicate OK, or non-zero to indicate
+ * some sort of error.
+ * 'bitset' is described in more detail below, and is mostly compatible
+ * with the old RDI/RDP system to avoid gratuitous changes to the debugger
+ * toolbox.
+ * 'model' is the target hardware ID word, as returned by the ADP_Booted
+ * message.
+ *
+ * NOTE: The minimum and maximum protocol levels are no longer supported.
+ * It is the Angel view that debugging complexity should be shifted to the
+ * host if at all possible. This means that the host debugger should
+ * always try to configure itself to the features available in the target
+ * debug agent. This can be done by checking individual messages, rather
+ * than by a blanket version number dictating the feature set.
+ */
+
+/* 'bitset':- */
+/* Target speed in instructions per second = 10**(bits0..3). */
+#define ADP_Info_Target_LogSpeedMask (0xF)
+
+/* Target is running on [0 = emulator / 1 = hardware] */
+#define ADP_Info_Target_HW (1 << 4)
+
+/* Bits 5..10 are currently undefined and should be zero. */
+/* Other bis are kept the same as the RDP in order to */
+/* eliminate the need to change the position of some bits */
+
+/* If set then the debug agent can be reloaded. */
+#define ADP_Info_Target_CanReloadAgent (1 << 11)
+
+/* Can request AngelBufferSize information. */
+#define ADP_Info_Target_CanInquireBufferSize (1 << 12)
+
+/* Bit 13 is no longer required as it inquired whether
+ * a special RDP Interrupt code was supported
+ */
+
+/* Debug agent can perform profiling. */
+#define ADP_Info_Target_Profiling (1 << 14)
+
+/* Debug agent can support Thumb code. */
+#define ADP_Info_Target_Thumb (1 << 15)
+
+/* Bit 16 was the communications channel check.
+ * This is always available on Angel systems.
+ */
+
+#define ADP_Info_Points ADPSUBREASON(CI_HADP,2)
+/* ADP_Info_Points
+ * ---------------
+ * Summary: Returns a 32bit wide bitset of break- and watch-point
+ * features supported by the target debug agent.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word breakinfo)
+ *
+ * 'status' returns RDIError_NoError on success or non-zero to indicate
+ * some sort of error.
+ * 'breakinfo' is a 32bit wide bitset described in detail below. Note
+ * that only bits 1..12 are used.
+ */
+
+/* 'breakinfo':- */
+/* Can trap on address equality. */
+#define ADP_Info_Points_Comparison (1 << 0)
+
+/* Can trap on address range. */
+#define ADP_Info_Points_Range (1 << 1)
+
+/* Can trap on 8bit memory reads. */
+#define ADP_Info_Points_ReadByteWatch (1 << 2)
+
+/* Can trap on 16bit memory reads. */
+#define ADP_Info_Points_ReadHalfWatch (1 << 3)
+
+/* Can trap on 32bit memory reads. */
+#define ADP_Info_Points_ReadWordWatch (1 << 4)
+
+/* Can trap on 8bit write accesses. */
+#define ADP_Info_Points_WriteByteWatch (1 << 5)
+
+/* Can trap on 16bit write accesses. */
+#define ADP_Info_Points_WriteHalfWatch (1 << 6)
+
+/* Can trap on 32bit write accesses. */
+#define ADP_Info_Points_WriteWordWatch (1 << 7)
+
+/* Like range, but based on address bitmask<. */
+#define ADP_Info_Points_Mask (1 << 8)
+
+/* Multi-threaded support only - thread specific breakpoints. */
+#define ADP_Info_Points_ThreadBreak (1 << 9)
+
+/* Multi-threaded support only - thread specific watchpoints. */
+#define ADP_Info_Points_ThreadWatch (1 << 10)
+
+/* Allows conditional breakpoints. */
+#define ADP_Info_Points_Conditionals (1 << 11)
+
+/* Break- and watch-points can be interrogated */
+#define ADP_Info_Points_Status (1 << 12)
+
+
+#define ADP_Info_Step ADPSUBREASON(CI_HADP,3)
+/* ADP_Info_Step
+ * -------------
+ * Summary: Returns a 32bit wide bitmask of the single-stepping
+ * capabilities of the target debug agent.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word stepinfo)
+ *
+ * 'status' returns RDIError_NoError on success, or non-zero to indicate
+ * some kind of error.
+ * 'stepinfo' is a 32bit wide bitmask described in detail below. Note that
+ * only 3 bits are used.
+ */
+
+/* 'stepinfo':- */
+/* Single-stepping of more than one instruction is possible. */
+#define ADP_Info_Step_Multiple (1 << 0)
+
+/* Single-stepping until next direct PC change is possible. */
+#define ADP_Info_Step_PCChange (1 << 1)
+
+/* Single-stepping of a single instruction is possible. */
+#define ADP_Info_Step_Single (1 << 2)
+
+
+#define ADP_Info_MMU ADPSUBREASON(CI_HADP,4)
+/* ADP_Info_MMU
+ * ------------
+ * Summary: Returns information about the memory management system (if
+ * any).
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word meminfo)
+ *
+ * 'status' returns RDIError_NoError to indicate success or non-zero to
+ * indicate some kind of error.
+ * 'meminfo' should be a 32bit unique ID, or zero if there is no MMU
+ * support on the target.
+ */
+
+
+#define ADP_Info_SemiHosting ADPSUBREASON(CI_HADP,5)
+/* ADP_Info_SemiHosting
+ * --------------------
+ * Summary: This message is used to check whether semi-hosting info calls
+ * are available on the target.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' returns RDIError_NoError if semi-hosting info calls are available,
+ * non-zero otherwise.
+ */
+
+
+#define ADP_Info_CoPro ADPSUBREASON(CI_HADP,6)
+/* ADP_Info_CoPro
+ * --------------
+ * Summary: This message checks whether CoProcessor info calls are
+ * supported.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' returns RDIError_NoError to indicate these facilities
+ * are supported, non-zero otherwise.
+ */
+
+
+#define ADP_Info_Cycles ADPSUBREASON(CI_HADP,7)
+/* ADP_Info_Cycles
+ * ---------------
+ * Summary: Returns the number of instructions and cycles executed since
+ * the target was initialised.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word ninstr, word Scycles, word Ncycles,
+ * word Icycles, word Ccycles, word Fcycles)
+ *
+ * 'status' is RDIError_NoError to indicate success, or non-zero if there
+ * is no target support for gathering cycle count information.
+ * 'ninstr' is the number of instructions executed.
+ * 'Scycles' is the number of S-cycles executed.
+ * 'Ncycles' is the number of N-cycles executed.
+ * 'Icycles' is the number of I-cycles executed.
+ * 'Ccycles' is the number of C-cycles executed.
+ * 'Fcycles' is the number of F-cycles executed.
+ */
+
+
+#define ADP_Info_DescribeCoPro ADPSUBREASON(CI_HADP,8)
+/* ADP_Info_DescribeCoPro
+ * ----------------------
+ * Summary: Describe the registers of a coprocessor. Use only if
+ * ADP_Info_CoPro return RDIError_NoError.
+ *
+ * Arguments:
+ * Send: Arguments of the form:
+ * (byte cpno, byte rmin, byte rmax, byte nbytes, byte access,
+ * byte cprt_r_b0, byte cprt_r_b1, byte cprt_w_b0, byte cprt_w_b1)
+ * And a terminating byte = 0xff. Must be within maximum buffer size.
+ * Return: (word status)
+ *
+ * 'cpno' is the number of the coprocessor to be described.
+ * 'rmin' is the bottom of a range of registers with the same description.
+ * 'rmax' is the top of a range of registers with the same description.
+ * 'nbytes' is the size of the register.
+ * 'access' describes access to the register and is described in more detail
+ * below.
+ *
+ * If bit 2 of access is set:-
+ * 'cprt_r0' provides bits 0 to 7, and
+ * 'cprt_r1' provides bits 16 to 23 of a CPRT instruction to read the
+ * register.
+ * 'cprt_w0' provides bits 0 to 7, and
+ * 'cprt_w1' provides bits 16 to 23 of a CPRT instruction to write the
+ * register.
+ *
+ * Otherwise, 'cprt_r0' provides bits 12 to 15, and 'cprt_r1' bit 22 of CPDT
+ * instructions to read and write the register ('cprt_w0' and 'cprt_w1' are
+ * junk).
+ */
+
+/* 'access':- */
+/* Readable. */
+#define ADP_Info_DescribeCoPro_Readable (1 << 0)
+
+/* Writeable. */
+#define ADP_Info_DescribeCoPro_Writeable (1 << 1)
+
+/* Registers read or written via CPDT instructions (else CPRT) with this
+ bit set. */
+#define ADP_Info_DescribeCoPro_CPDT (1 << 2)
+
+#define ADP_Info_RequestCoProDesc ADPSUBREASON(CI_HADP,9)
+/* ADP_Info_RequestCoProDesc
+ * -------------------------
+ * Summary: Requests a description of the registers of a coprocessor. Use
+ * only if ADP_Info_CoPro return RDIError_NoError.
+ *
+ * Arguments:
+ * Send: (byte cpno)
+ * Return: Arguments of the form:-
+ * (word status, byte rmin, byte rmax, byte nbytes, byte access)
+ * Followed by a terminating byte = 0xFF. Must be within maximum
+ * buffer size.
+ * 'cpno' is the number of the coprocessor to describe.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'rmin' is the bottom of a range of registers with the same description.
+ * 'rmax' is the top of a range of registers with the same description.
+ * 'nbytes' is the size in bytes of the register(s).
+ * 'access' is as above in ADP_Info_DescribeCoPro.
+ */
+
+
+#define ADP_Info_AngelBufferSize ADPSUBREASON(CI_HADP,10)
+/* ADP_Info_AngelBufferSize
+ * ------------------------
+ * Summary: Returns the Angel buffer sizes.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word defaultsize, word maxsize)
+ *
+ * 'status' returns RDIError_NoError to indicate success or non-zero to
+ * indicate some kind of error.
+ * 'defaultsize' is the default Angel ADP buffer size in bytes. This is
+ * at least 256 bytes.
+ * 'maxsize' is the largest Angel ADP buffer size in bytes. This will be
+ * greater than or equal to defaultsize. The target will accept ADP messages
+ * of up to this length for download, etc.
+ *
+ * Was DownLoadSize in RDP/RDI world. This is the amount that the target
+ * should transmit in a single operation. This should now be the Angel
+ * buffer size. This information is also given in the ADP_Booted message.
+ *
+ * NOTE: The value returned should be the DATASIZE and *NOT* BUFFERDEFSIZE.
+ * This is needed to ensure that the transport protocol information
+ * can be wrapped around the data.
+ */
+
+#define ADP_Info_ChangeableSHSWI ADPSUBREASON(CI_HADP,11)
+/* ADP_Info_ChangeableSHSWI
+ * ------------------------
+ * Summary: This message is used to check whether it is possible to change
+ * which SWI's are used for semihosting.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' returns RDIError_NoError if semi-hosting info calls are available,
+ * non-zero otherwise.
+ */
+
+#define ADP_Info_CanTargetExecute ADPSUBREASON(CI_HADP,12)
+/* ADP_Info_CanTargetExecute
+ * -------------------------
+ * Summary: This message is used to see if the target is currently in
+ * an executable state. Typically this is called after the debugger
+ * initialises. If a non-error statis is returned then the user is
+ * allowed to 'go' immediately.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' returns RDIError_NoError if target is ready to execute.
+ * other values indicate why it cannot execute.
+ */
+
+#define ADP_Info_AgentEndianess ADPSUBREASON(CI_HADP,13)
+/* ADP_Info_AgentEndianess
+ * -------------------------
+ * Summary: This message is used to determine the endianess of the
+ * debug agent
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * status should be RDIError_LittleEndian or RDIError_BigEndian
+ * any other value indicates the target does not support this
+ * request, so the debugger will have to make a best guess, which
+ * probably means only allow little endian loadagenting.
+ */
+
+
+#define ADP_Control ADPREASON(CI_HADP,2)
+/* This message allows for the state of the debug agent to be
+ * manipulated by the host.
+ */
+
+/* The following are sub reason codes to ADP control, the first parameter
+ * is the sub reason code which defines the format of subsequent parameters.
+ *
+ * word sub reason code
+ */
+
+#define ADP_Ctrl_NOP ADPSUBREASON(CI_HADP,0)
+/* ADP_Ctrl_NOP
+ * ------------
+ * Summary: This message is used to check that ADP_Ctrl messages are
+ * supported.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate ADP_Ctrl messages are
+ * supported, non-zero otherwise.
+ */
+
+#define ADP_Ctrl_VectorCatch ADPSUBREASON(CI_HADP,1)
+/* ADP_Ctrl_VectorCatch
+ * --------------------
+ * Summary: Specifies which hardware exceptions should be reported to the
+ * debugger.
+ *
+ * Arguments:
+ * Send: (word bitmap)
+ * Return: (word status)
+ *
+ * 'bitmap' is a bit-mask of exceptions to be reported, described in more
+ * detail below. A set bit indicates that the exception should be
+ * reported to the debugger, a clear bit indicates that the corresponding
+ * exception vector should be taken.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+/* 'bitmap':- */
+/* Reset(branch through zero). */
+#define ADP_Ctrl_VectorCatch_BranchThroughZero (1 << 0)
+
+/* Undefined Instruction. */
+#define ADP_Ctrl_VectorCatch_UndefinedInstr (1 << 1)
+
+/* Software Interrupt. */
+#define ADP_Ctrl_VectorCatch_SWI (1 << 2)
+
+/* Prefetch Abort. */
+#define ADP_Ctrl_VectorCatch_PrefetchAbort (1 << 3)
+
+/* Data Abort. */
+#define ADP_Ctrl_VectorCatch_DataAbort (1 << 4)
+
+/* Address Exception. */
+#define ADP_Ctrl_VectorCatch_AddressException (1 << 5)
+
+/* Interrupt Request. */
+#define ADP_Ctrl_VectorCatch_IRQ (1 << 6)
+
+/* Fast Interrupt Request. */
+#define ADP_Ctrl_VectorCatch_FIQ (1 << 7)
+
+/* Error. */
+#define ADP_Ctrl_VectorCatch_Error (1 << 8)
+
+
+#define ADP_Ctrl_PointStatus_Watch ADPSUBREASON(CI_HADP,2)
+/* ADP_Ctrl_PointStatus_Watch
+ * --------------------------
+ * Summary: Returns the hardware resource number and the type of that
+ * resource when given a watchpoint handle. Should only be called if
+ * the value returned by ADP_Info_Points had ADP_Info_Points_Status set.
+ *
+ * Arguments:
+ * Send: (word handle)
+ * Return: (word status, word hwresource, word type)
+ *
+ * 'handle' is a handle to a watchpoint.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'hwresource' is the hardware resource number. !!!!!
+ * 'type' is the type of the resource.
+ */
+
+
+#define ADP_Ctrl_PointStatus_Break ADPSUBREASON(CI_HADP,3)
+/* ADP_Ctrl_PointStatus_Break
+ * --------------------------
+ * Summary: Returns the hardware resource number and the type of that
+ * resource when given a breakpoint handle. Should only be called if
+ * the value returned by ADP_Info_Points had ADP_Info_Points_Status set.
+ *
+ * Arguments:
+ * Send: (word handle)
+ * Return: (word status, word hwresource, word type)
+ *
+ * 'handle' is a handle to a breakpoint.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'hwresource' is the hardware resource number.
+ * 'type' is the type of the resource.
+ */
+
+#define ADP_Ctrl_SemiHosting_SetState ADPSUBREASON(CI_HADP,4)
+/* ADP_Ctrl_SemiHosting_SetState
+ * -----------------------------
+ * Summary: Sets whether or not semi-hosting is enabled.
+ *
+ * Arguments:
+ * Send: (word semihostingstate)
+ * Return: (word status)
+ *
+ * 'semihostingstate' sets semi-hosting to enabled if zero, otherwise
+ * it disables semi-hosting.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: This should only be called if ADP_Info_SemiHosting didn't return
+ * an error.
+ */
+
+
+#define ADP_Ctrl_SemiHosting_GetState ADPSUBREASON(CI_HADP,5)
+/* ADP_Ctrl_SemiHosting_GetState
+ * -----------------------------
+ * Summary: Reads whether or not semi-hosting is enabled.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word semihostingstate)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'semihostingstate' is zero if semi-hosting is enabled, non-zero otherwise.
+ *
+ * NOTE: This should only be called if ADP_Info_SemiHosting didn't return
+ * an error.
+ */
+
+
+#define ADP_Ctrl_SemiHosting_SetVector ADPSUBREASON(CI_HADP,6)
+/* ADP_Ctrl_SemiHosting_SetVector
+ * ------------------------------
+ * Summary: Sets the semi-hosting vector.
+ *
+ * Arguments:
+ * Send: (word semihostingvector)
+ * Return: (word status)
+ *
+ * 'semihostingvector' holds the value the vector is to be set to.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: This should only be called if ADP_Info_SemiHosting didn't return
+ * an error.
+ */
+
+
+#define ADP_Ctrl_SemiHosting_GetVector ADPSUBREASON(CI_HADP,7)
+/* ADP_Ctrl_SemiHosting_GetVector
+ * ------------------------------
+ * Summary: Gets the value of the semi-hosting vector.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word semihostingvector)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'semihostingvector' holds the value of the vector.
+ *
+ * NOTE: This should only be called if ADP_Info_SemiHosting didn't return
+ * an error.
+ */
+
+
+#define ADP_Ctrl_Log ADPSUBREASON(CI_HADP,8)
+/* ADP_Ctrl_Log
+ * ------------
+ * Summary: Returns the logging state.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word logsetting)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'logsetting' is a bitmap specifying the level of logging desired,
+ * described in more detail below. The bits can be ORed together
+ */
+
+/* 'logsetting':- */
+
+/* No logging. */
+#define ADP_Ctrl_Log_NoLogging (0)
+/* RDI level logging. */
+#define ADP_Ctrl_Log_RDI (1 << 0)
+/* ADP byte level logging. */
+#define ADP_Ctrl_Log_ADP (1 << 1)
+
+
+#define ADP_Ctrl_SetLog ADPSUBREASON(CI_HADP,9)
+/* ADP_Ctrl_SetLog
+ * ---------------
+ * Summary: Sets the logging state.
+ *
+ * Arguments:
+ * Send: (word logsetting)
+ * Return: (word status)
+ *
+ * 'logsetting' is the same as in ADP_Ctrl_Log above.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+#define ADP_Ctrl_SemiHosting_SetARMSWI ADPSUBREASON(CI_HADP,10)
+/* ADP_Ctrl_SemiHosting_SetARMSWI
+ * ------------------------------
+ * Summary: Sets the number of the ARM SWI used for semihosting
+ *
+ * Arguments:
+ * Send: (word ARM_SWI_number)
+ * Return: (word status)
+ *
+ * The debug agent will interpret ARM SWI's with the SWI number specified
+ * as semihosting SWI's.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: This should only be called if ADP_Info_ChangeableSHSWI didn't return
+ * an error.
+ */
+
+
+#define ADP_Ctrl_SemiHosting_GetARMSWI ADPSUBREASON(CI_HADP,11)
+/* ADP_Ctrl_SemiHosting_GetARMSWI
+ * ------------------------------
+ * Summary: Reads the number of the ARM SWI used for semihosting
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word ARM_SWI_number)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * ARM_SWI_number is the SWI number which is used for semihosting.
+ *
+ * NOTE: This should only be called if ADP_Info_SemiHosting didn't return
+ * an error.
+ */
+
+#define ADP_Ctrl_SemiHosting_SetThumbSWI ADPSUBREASON(CI_HADP,12)
+/* ADP_Ctrl_SemiHosting_SetThumbSWI
+ * --------------------------------
+ * Summary: Sets the number of the Thumb SWI used for semihosting
+ *
+ * Arguments:
+ * Send: (word Thumb_SWI_number)
+ * Return: (word status)
+ *
+ * The debug agent will interpret Thumb SWI's with the SWI number specified
+ * as semihosting SWI's.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: This should only be called if ADP_Info_ChangeableSHSWI didn't return
+ * an error.
+ */
+
+
+#define ADP_Ctrl_SemiHosting_GetThumbSWI ADPSUBREASON(CI_HADP,13)
+/* ADP_Ctrl_SemiHosting_GetThumbSWI
+ * --------------------------------
+ * Summary: Reads the number of the Thumb SWI used for semihosting
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word ARM_Thumb_number)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * Thumb_SWI_number is the SWI number which is used for semihosting.
+ *
+ * NOTE: This should only be called if ADP_Info_SemiHosting didn't return
+ * an error.
+ */
+
+
+#define ADP_Ctrl_Download_Supported ADPSUBREASON(CI_HADP,14)
+/* ADP_Ctrl_Download_Supported
+ * ---------------------------
+ * Summary: Can configuration be downloaded?
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError if the configuration can be downloaded,
+ * non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDIInfo_DownLoad.
+ */
+
+
+#define ADP_Ctrl_Download_Data ADPSUBREASON(CI_HADP,15)
+/* ADP_Ctrl_Download_Data
+ * ----------------------
+ * Summary: Loads configuration data.
+ *
+ * Arguments:
+ * Send: (word nbytes, words data)
+ * Return: (word status)
+ *
+ * 'nbytes' is the number of *bytes* being sent.
+ * 'data' is the configuration data. NOTE: data must not cause the buffer
+ * size to exceed the maximum allowed buffer size.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDP_LoadConfigData. Should only be used if
+ * ADP_ICEM_AddConfig didn't return an error.
+ */
+
+
+#define ADP_Ctrl_Download_Agent ADPSUBREASON(CI_HADP,16)
+/* ADP_Ctrl_Download_Agent
+ * -----------------------
+ * Summary: Prepares Debug Agent to receive configuration data which it
+ * should interpret as a new version of the Debug Agent code.
+ *
+ * Arguments:
+ * Send: (word loadaddress, word size)
+ * Return: (word status)
+ *
+ * 'loadaddress' is the address where the new Debug Agent code should be
+ * loaded.
+ * 'size' is the number of bytes of Debug Agent code to be loaded.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDP_LoadAgent. The data will be downloaded using
+ * ADP_Ctrl_Download_Data. The new agent is started with ADP_Ctrl_Start_Agent
+ */
+
+
+#define ADP_Ctrl_Start_Agent ADPSUBREASON(CI_HADP,17)
+/* ADP_Ctrl_Start_Agent
+ * -----------------------
+ * Summary: Instruct Debug Agent to begin execution of new agent,
+ * which has been downloaded by ADP_Ctrl_Download_Agent.
+ *
+ * Arguments:
+ * Send: (word startaddress)
+ * Return: (word status)
+ *
+ * 'startaddress' is the address where the new Debug Agent code should be
+ * entered, and must satisfy:
+ * (loadaddress <= startaddress <= (loadaddress + size))
+ * where 'loadaddress' and 'size' were specified in the
+ * ADP_Ctrl_Download_Agent message.
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+
+#define ADP_Ctrl_SetTopMem ADPSUBREASON(CI_HADP,18)
+/* ADP_Ctrl_SetTopMem
+ * ------------------
+ * Summary: Sets the top of memory for ICEman2 systems, so that the C Library
+ * can allocate the stack in the correct place on startup.
+ *
+ * Arguments:
+ * Send: (word mem_top)
+ * Return: (word status)
+ *
+ * This request should only be supported by ICEman2. Standard Angel systems
+ * should return an error (unrecognised is fine).
+ */
+
+
+#define ADP_Read ADPREASON(CI_HADP,3)
+#define ADP_ReadHeaderSize (ADP_DEFAULT_HEADER_SIZE + 2*sizeof(word))
+
+/* ADP_Read
+ * --------
+ * Summary: Request for a transer of memory contents from the target to the
+ * debugger.
+ *
+ * Arguments:
+ * Send: (word address, word nbytes)
+ * Return: (word status, word rnbytes [, bytes data])
+ *
+ * 'address' is the address from which memory transer should start.
+ * 'nbytes' is the number of bytes to transfer.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'rnbytes' holds the number of requested bytes NOT read (i.e. zero
+ * indicates success, non-zero indicates an error).
+ * 'data' is the number of bytes requested minus 'rnbytes'.
+ */
+
+
+
+#define ADP_Write ADPREASON(CI_HADP,4)
+#define ADP_WriteHeaderSize (ADP_DEFAULT_HEADER_SIZE + 2*sizeof(word))
+
+/* ADP_Write
+ * ---------
+ * Summary: Request for a transfer of memory contents from the debugger to
+ * the target.
+ *
+ * Arguments:
+ * Send: (word address, word nbytes, bytes data)
+ * Return: (word status [, word rnbytes])
+ *
+ * 'address' is the address from which memory transer should start.
+ * 'nbytes' is the number of bytes to transfer.
+ * 'data' holds the bytes to be transferred.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'rnbytes' holds the number of requested bytes NOT written (i.e. zero
+ * indicates success, non-zero indicates an error) if status indicated an
+ * error.
+ */
+
+
+
+#define ADP_CPUread ADPREASON(CI_HADP,5)
+/* ADP_CPUread
+ * -----------
+ * Summary: This is a request to read values in the CPU.
+ *
+ * Arguments:
+ * Send: (byte mode, word mask)
+ * Return: (word status, words data)
+ *
+ * 'mode' defines the processor mode from which the transfer should be made.
+ * It is described in more detail below.
+ * 'mask' indicates which registers should be transferred. Setting a bit to
+ * one will cause the designated register to be transferred. The details
+ * of mask are specified below.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'data' holds the values of the registers on successful completion,
+ * otherwise it just holds rubbish. The lowest numbered register is
+ * transferred first. NOTE: data must not cause the buffer size to exceed
+ * the maximum allowed buffer size.
+ */
+
+/* 'mode':- */
+/* The mode number is the same as the mode number used by an ARM; a value of
+ 255 indicates the current mode. */
+#define ADP_CPUmode_Current (255)
+
+/* 26bit user mode. */
+#define ADP_CPUread_26bitUser (0x0)
+
+/* 26bit FIQ mode. */
+#define ADP_CPUread_26bitFIQ (0x1)
+
+/* 26bit IRQ mode. */
+#define ADP_CPUread_26bitIRQ (0x2)
+
+/* 26bit Supervisor mode. */
+#define ADP_CPUread_26bitSVC (0x3)
+
+/* 32bit user mode. */
+#define ADP_CPUread_32bitUser (0x10)
+
+/* 32bit FIQ mode. */
+#define ADP_CPUread_32bitFIQ (0x11)
+
+/* 32bit IRQ mode. */
+#define ADP_CPUread_32bitIRQ (0x12)
+
+/* 32bit Supervisor mode. */
+#define ADP_CPUread_32bitSVC (0x13)
+
+/* 32bit Abort mode. */
+#define ADP_CPUread_32bitAbort (0x17)
+
+/* 32bit Undefined mode. */
+#define ADP_CPUread_32bitUndef (0x1B)
+
+/* #32bit System mode - Added in Architecture 4 ARMs e.g.ARM7TDMI */
+#define ADP_CPUread_32bitSystem (0x1F)
+
+/* 'mask':- */
+/* Request registers RO-R14. */
+#define ADP_CPUread_RegsMask (0x7FFF)
+
+/* Request Program Counter (including mode and flag bits in 26-bit modes. */
+#define ADP_CPUread_PCmode (1 << 15)
+
+/* Request Program Counter (without mode and flag bits in 26-bit modes. */
+#define ADP_CPUread_PCnomode (1 << 16)
+
+/* Requests the transfer of the CPSR */
+#define ADP_CPUread_CPSR (1 << 17)
+
+/* In processor modes with an SPSR(non-user modes), bit 19 requests its
+ transfer */
+#define ADP_CPUread_SPSR (1 << 18)
+
+
+
+#define ADP_CPUwrite ADPREASON(CI_HADP,6)
+/* ADP_CPUwrite
+ * ------------
+ * Summary: This is a request to write values to the CPU.
+ *
+ * Arguments:
+ * Send: (byte mode, word mask, words data)
+ * Return: (word status)
+ *
+ * 'mode' defines the processor mode to which the transfer should be made.
+ * The mode number is the same as the mode number used by ARM; a value of
+ * 255 indicates the current mode. See ADP_CPUread above for more detail.
+ * 'mask' indicates which registers should be transferred. Setting a bit to
+ * one will cause the designated register to be transferred. The details
+ * of mask are specified above in ADP_CPUread.
+ * 'data' holds the values of the registers to be transferred. The first
+ * value is written to the lowest numbered register. NOTE: data must not
+ * cause the buffer size to exceed the maximum allowed buffer size.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+
+
+#define ADP_CPread ADPREASON(CI_HADP,7)
+/* ADP_CPread
+ * ----------
+ * Summary: This message requests a co-processors internal state.
+ *
+ * Arguments:
+ * Send: (byte CPnum, word mask)
+ * Return: (word status, words data)
+ *
+ * 'CPnum' is the number of the co-processor to transfer values from.
+ * 'mask' specifies which registers to transfer and is co-processor
+ * specific.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'data' holds the registers specified in 'mask' if successful, otherwise
+ * just rubbish. The lowest numbered register is transferred first.
+ * NOTE: data must not cause the buffer size to exceed the maximum allowed
+ * buffer size.
+ */
+
+
+
+#define ADP_CPwrite ADPREASON(CI_HADP,8)
+/* ADP_CPwrite
+ * -----------
+ * Summary: This message requests a write to a co-processors internal state.
+ *
+ * Arguments:
+ * Send: (byte CPnum, word mask, words data)
+ * Return: (word status)
+ *
+ * 'CPnum' is the number of the co-processor to transfer values to.
+ * 'mask' specifies which registers to transfer and is co-processor
+ * specific.
+ * 'data' holds the values to transfer to the registers specified in 'mask'.
+ * The first value is written to the lowest numbered register.
+ * NOTE: data must not cause the buffer size to exceed the maximum allowed
+ * buffer size.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+
+
+#define ADP_SetBreak ADPREASON(CI_HADP,9)
+/* ADP_SetBreak
+ * ------------
+ * Summary: Sets a breakpoint.
+ *
+ * Arguments:
+ * Send: (word address, byte type [, word bound])
+ * Return: (word status, word pointhandle, word raddress, word rbound)
+ *
+ * 'address' is the address of the instruction to set the breakpoint on.
+ * 'type' specifies the sort of breakpoint and is described in more detail
+ * below.
+ * 'bound' is included if the least significant 4 bits of type are set to
+ * 5 or above (see below for more detail).
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'pointhandle' returns a handle to the breakpoint, it will be valid if bit
+ * 7 of 'type' is set. See below for more detail.
+ * 'raddress' is valid depending on 'type', see below for more detail.
+ * 'rbound' is valid depending on 'type', see below for more detail.
+ */
+
+/* 'type':- */
+/* The least significant 4 bits define the sort of breakpoint to set:- */
+/* Halt if the pc is equal to 'address'. */
+#define ADP_SetBreak_EqualsAddress (0)
+
+/* Halt if the pc is greater than 'address'. */
+#define ADP_SetBreak_GreaterAddress (1)
+
+/* Halt if the pc is greater than or equal to 'address'. */
+#define ADP_SetBreak_GEqualsAddress (2)
+
+/* Halt if the pc is less than 'address'. */
+#define ADP_SetBreak_LessAddress (3)
+
+/* Halt if the pc is less than or equal to 'address'. */
+#define ADP_SetBreak_LEqualsAddress (4)
+
+/* Halt if the pc is in the range from 'address' to 'bound' inclusive. */
+#define ADP_SetBreak_Range (5)
+
+/* Halt if the pc is not in the range from 'address' to 'bound' inclusive. */
+#define ADP_SetBreak_NotRange (6)
+
+/* Halt if (pc & 'bound') = 'address'. */
+#define ADP_SetBreak_AndBound (7)
+
+/* Bits 5,6 and 7 are used as follows :- */
+/* If set this indicates that the breakpoint is on a 16bit (Thumb)
+ instruction rather than a 32bit (ARM) instruction. */
+#define ADP_SetBreak_Thumb (1 << 4)
+
+/* This requests that the breakpoint should be conditional (execution halts
+ only if the breakpointed instruction is executed, not if it is
+ conditionally skipped). If bit 5 is not set, execution halts whenever
+ the breakpointed instruction is reached (whether executed or skipped). */
+#define ADP_SetBreak_Cond (1 << 5)
+
+/* This requests a dry run: the breakpoint is not set and the 'raddress', and
+ if appropriate the 'rbound', that would be used, are returned (for
+ comparison and range breakpoints the address and bound used need not be
+ exactly as requested). A RDIError_NoError 'status' byte indicates that
+ resources are currently available to set the breakpoint, non-zero
+ indicates an error. RDIError_NoMorePoints indicates that the required
+ breakpoint resources are not currently available. */
+#define ADP_SetBreak_DryRun (1 << 6)
+
+/* If the request is successful, but there are no more breakpoint registers
+ (of the requested type), then the value RDIError_NoMorePoints is
+ returned. */
+
+/* If a breakpoint is set on a location which already has a breakpoint, the
+ first breakpoint will be removed before the new breakpoint is set. */
+
+
+
+#define ADP_ClearBreak ADPREASON(CI_HADP,10)
+/* ADP_ClearBreak
+ * --------------
+ * Summary: Clears a breakpoint.
+ *
+ * Arguments:
+ * Send: (word pointhandle)
+ * Return: (word status)
+ *
+ * 'pointhandle' is a handle returned by a previous ADP_SetBreak.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+
+#define ADP_SetWatch ADPREASON(CI_HADP,11)
+/* ADP_SetWatch
+ * ------------
+ * Summary: Sets a watchpoint.
+ *
+ * Arguments:
+ * Send: (word address, byte type, byte datatype [,word bound])
+ * Return: (word status, word pointhandle, word raddress, word rbound)
+ *
+ * 'address' is the address at which to set the watchpoint.
+ * 'type' is the type of watchpoint to set and is described in detail below.
+ * 'datatype' defines the sort of data access to watch for and is described
+ * in more detail below.
+ * 'bound' is included depending on the value of type (see description of
+ * type below).
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'pointhandle' is valid depending on the value of type (see description
+ * of type below).
+ * 'raddress' is valid depending on the value of type (see description
+ * of type below).
+ * 'rbound' is valid depending on the value of type (see description
+ * of type below).
+ */
+
+/* 'type':- */
+/* The least significant 4 bits of 'type' define the sort of watchpoint to
+ set:- */
+/* Halt on a data access to the address equal to 'address'. */
+#define ADP_SetWatch_EqualsAddress (0)
+
+/* Halt on a data access to an address greater than 'address'. */
+#define ADP_SetWatch_GreaterAddress (1)
+
+/* Halt on a data access to an address greater than or equal to 'address'. */
+#define ADP_SetWatch_GEqualsAddress (2)
+
+/* Halt on a data access to an address less than 'address'. */
+#define ADP_SetWatch_LessAddress (3)
+
+/* Halt on a data access to an address less than or equal to 'address'. */
+#define ADP_SetWatch_LEqualsAddress (4)
+
+/* Halt on a data access to an address in the range from 'address' to
+ 'bound' inclusive. */
+#define ADP_SetWatch_Range (5)
+
+/* Halt on a data access to an address not in the range from 'address' to
+ 'bound' inclusive. */
+#define ADP_SetWatch_NotRange (6)
+
+/* Halt if (data-access-address & 'bound')='address'. */
+#define ADP_SetWatch_AndBound (7)
+
+/* Bits 6 and 7 of 'type' also have further significance:-
+ NOTE: they must not be simulataneously set. */
+
+/* Bit 6 of 'type' set: Requests a dry run: the watchpoint is not set and
+ the 'address' and, if appropriate, the 'bound', that would be used are
+ returned (for range and comparison watchpoints, the 'address' and 'bound'
+ used need not be exactly as requested). A RDIError_NoError status byte
+ indicates that resources are currently available to set the watchpoint;
+ RDIError_NoMorePoints indicates that the required watchpoint resources
+ are not currently available. */
+
+/* Bit 7 of 'type' set: Requests that a handle should be returned for the
+ watchpoint by which it will be identified subsequently. If bit 7 is
+ set, a handle will be returned ('pointhandle'), whether or not the
+ request succeeds or fails (but, obviously, it will only be meaningful
+ if the request succeesd). */
+
+/* 'datatype':- */
+/* The 'datatype' argument defines the sort of data access to watch for,
+ values can be summed or ORed together to halt on any set of sorts of
+ memory access. */
+
+/* Watch for byte reads. */
+#define ADP_SetWatch_ByteReads (1)
+
+/* Watch for half-word reads. */
+#define ADP_SetWatch_HalfWordReads (2)
+
+/* Watch for word reads. */
+#define ADP_SetWatch_WordReads (4)
+
+/* Watch for half-word reads. */
+#define ADP_SetWatch_ByteWrites (8)
+
+/* Watch for half-word reads. */
+#define ADP_SetWatch_HalfWordWrites (16)
+
+/* Watch for half-word reads. */
+#define ADP_SetWatch_WordWrites (32)
+
+/* On successful completion a RDIError_NoError 'status' byte is returned. On
+ unsuccessful completion, a non-zero error code byte is returned. If the
+ request is successful, but there are now no more watchpoint registers
+ (of the requested type), then the value RDIError_NoMorePoints is
+ returned. */
+
+/* If a watchpoint is set on a location which already has a watchpoint, the
+ first watchpoint will be removed before the new watchpoint is set. */
+
+
+#define ADP_ClearWatch ADPREASON(CI_HADP,12)
+/* ADP_ClearWatch
+ * --------------
+ * Summary: Clears a watchpoint.
+ *
+ * Arguments:
+ * Send: (word pointhandle)
+ * Return: (word status)
+ *
+ * 'pointhandle' is a handle to a watchpoint returned by a previous
+ * ADP_SetWatch.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+
+
+#define ADP_Execute ADPREASON(CI_HADP,13)
+/* ADP_Execute
+ * -----------
+ * Summary: This message requests that the target starts executing from
+ * the stored CPU state.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * The message will *ALWAYS* respond immediately with an ACK (unlike the
+ * old RDI definition, which allowed asynchronous message replies).
+ *
+ * Execution will stop when allowed system events occur. The host will
+ * be notified via a ADP_Stopped message (described below).
+ */
+
+
+
+#define ADP_Step ADPREASON(CI_HADP,14)
+/* ADP_Step
+ * --------
+ * Summary: Execute 'ninstr' instructions.
+ *
+ * Arguments:
+ * Send: (word ninstr)
+ * Return: (word status)
+ *
+ * 'ninstr' is the number of instructions to execute, starting at the
+ * address currently loaded into the CPU program counter. If it is zero,
+ * the target should execute instructions upto the next instruction that
+ * explicitly alters the Program Counter. i.e. a branch or ALU operation
+ * with the PC as the destination.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * The ADP_Step function (unlike the earlier RDI system) will *ALWAYS*
+ * return an ACK immediately. A subsequent ADP_Stopped message will be
+ * delivered from the target to the host when the ADP_Step operation
+ * has completed.
+ */
+
+
+
+#define ADP_InterruptRequest ADPREASON(CI_HADP,15)
+/* ADP_InterruptRequest
+ * --------------------
+ * Summary: Interrupt execution.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * On receiving this message the target should attempt to stop execution.
+ */
+
+
+
+#define ADP_HW_Emulation ADPREASON(CI_HADP,16)
+/* ADP_HW_Emulation
+ * ----------------
+ * The first parameter to ADP_HW_Emulation is a Reason Subcode, and
+ * subsequent parameters are defined by that subcode
+ *
+ * word reason subcode
+ * other arguments as reason subcode determines
+ *
+ */
+
+/* ADP__HW_Emulation sub-reason codes: */
+
+#define ADP_HW_Emul_Supported ADPSUBREASON(CI_HADP,0)
+/* ADP_HW_Emul_Supported
+ * ---------------------
+ * Summary: Enquires whether calls to the next 4 messages are available
+ * (MemoryAccess, MemoryMap, Set_CPUspeed, ReadClock).
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate the messages are available,
+ * non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDI_Info_Memory_Stats.
+ */
+
+
+#define ADP_HW_Emul_MemoryAccess ADPSUBREASON(CI_HADP,1)
+/* ADP_HW_Emul_MemoryAccess
+ * ------------------------
+ * Summary: Get memory access information for memory block with specified
+ * handle.
+ *
+ * Arguments:
+ * Send: (word handle)
+ * Return: (word status, word nreads, word nwrites, word sreads,
+ * word swrites, word ns, word s)
+ *
+ * 'handle' is a handle to a memory block.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'nreads' is the number of non-sequential reads.
+ * 'nwrites' is the number of non-sequential writes.
+ * 'sreads' is the number of sequential reads.
+ * 'swrites' is the number of sequential writes.
+ * 'ns' is time in nano seconds.
+ * 's' is time in seconds.
+ *
+ * NOTE: Equivalent to RDIMemory_Access.
+ */
+
+
+#define ADP_HW_Emul_MemoryMap ADPSUBREASON(CI_HADP,2)
+/* ADP_HW_Emul_MemoryMap
+ * ---------------------
+ * Summary: Sets memory characteristics.
+ *
+ * Arguments:
+ * Send: (word n,
+ Then 'n' sets of arguments of the form:-
+ word handle, word start, word limit, byte width,
+ byte access, word Nread_ns, word Nwrite_ns, word Sread_ns,
+ word Swrite_ns)
+ * Return: (word status)
+ *
+ * 'n' is the number of sets of arguments.
+ * 'handle' is a handle to the region.
+ * 'start' is the start of this region.
+ * 'limit' is the limit of this region.
+ * 'width' is the memory width, described in detail below.
+ * 'access' is described in detail below.
+ * 'Nread_ns' is the access time for N read cycles in nano seconds.
+ * 'Nwrite_ns' is the access time for N write cycles in nano seconds.
+ * 'Sread_ns' is the access time for S read cycles in nano seconds.
+ * 'Swrite_ns' is the access time for S write cycles in nano seconds.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * NOTE: Equivalent to RDIMemory_Map.
+ */
+
+/* 'width':- */
+/* 8 bit memory width. */
+#define ADP_HW_Emul_MemoryMap_Width8 (0)
+
+/* 16 bit memory width. */
+#define ADP_HW_Emul_MemoryMap_Width16 (1)
+
+/* 32 bit memory width. */
+#define ADP_HW_Emul_MemoryMap_Width32 (2)
+
+/* 'access':- */
+/* Bit 0 - read access. */
+#define ADP_HW_Emul_MemoryMap_Access_Read (1 << 0)
+
+/* Bit 1 - write access. */
+#define ADP_HW_Emul_MemoryMap_Access_Write (1 << 1)
+
+/* Bit 2 - latched 32 bit memory. */
+#define ADP_HW_Emul_MemoryMap_Access_Latched (1 << 2)
+
+
+#define ADP_HW_Emul_SetCPUSpeed ADPSUBREASON(CI_HADP,3)
+/* ADP_HW_Emul_SetCPUSpeed
+ * -----------------------
+ * Summary: Sets the speed of the CPU.
+ *
+ * Arguments:
+ * Send: (word speed)
+ * Return: (word status)
+ *
+ * 'speed' is the CPU speed in nano seconds.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDISet_CPUSpeed.
+ */
+
+
+#define ADP_HW_Emul_ReadClock ADPSUBREASON(CI_HADP,4)
+/* ADP_HW_Emul_ReadClock
+ * ---------------------
+ * Summary: Reads simulated time.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word ns, word s)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'ns' is time in nano seconds.
+ * 's' is time in seconds.
+ *
+ * NOTE: Equivalent to RDIRead_Clock.
+ */
+
+
+#define ADP_ICEbreakerHADP ADPREASON(CI_HADP,17)
+
+/* The first parameter to ADP_ICEbreaker is a Reason Subcode, and
+ * subsequent parameters are defined by that subcode
+ *
+ * word reason subcode
+ * other arguments as reason subcode determines
+ *
+ */
+
+/* ADP_ICEbreaker sub-reason codes: */
+
+#define ADP_ICEB_Exists ADPSUBREASON(CI_HADP,0)
+/* ADP_ICEB_Exists
+ * ---------------
+ * Summary: Is there an ICEbreaker in the system?
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate there is an ICEbreaker,
+ * non-zero otherwise.
+ */
+
+
+#define ADP_ICEB_GetLocks ADPSUBREASON(CI_HADP,1)
+/* ADP_ICEB_GetLocks
+ * -----------------
+ * Summary: Returns which ICEbreaker registers are locked.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word lockedstate)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'lockedstate' is a bitmap if the ICEbreaker registers locked against use
+ * by IceMan (because explicitly written by the user). Bit n represents
+ * hardware breakpoint n, and if set the register is locked.
+ *
+ * NOTE: Equivalent to RDIIcebreaker_GetLocks. Should only be used if
+ * ADP_ICEB_Exists didn't return an error.
+ */
+
+
+#define ADP_ICEB_SetLocks ADPSUBREASON(CI_HADP,2)
+/* ADP_ICEB_SetLocks
+ * -----------------
+ * Summary: Sets which ICEbreaker registers are locked.
+ *
+ * Arguments:
+ * Send: (word lockedstate)
+ * Return: (word status)
+ *
+ * 'lockedstate' is the same as in ADP_ICEB_GetLocks above.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDIIcebreaker_SetLocks. Should only be used if
+ * ADP_ICEB_Exists didn't return an error.
+ */
+
+
+#define ADP_ICEB_CC_Exists ADPSUBREASON(CI_HADP,3)
+/* ADP_ICEB_CC_Exists
+ * ------------------
+ * Summary: Is there an ICEbreaker Comms Channel?
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate there is a Comms Channel,
+ * non-zero otherwise.
+ *
+ * NOTE: Should only be used if ADP_ICEB_Exists didn't return an error.
+ */
+
+
+#define ADP_ICEB_CC_Connect_ToHost ADPSUBREASON(CI_HADP,4)
+/* ADP_ICEB_CC_Connect_ToHost
+ * --------------------------
+ * Summary: Connect Comms Channel in ToHost direction.
+ *
+ * Arguments:
+ * Send: (byte connect)
+ * Return: (word status)
+ *
+ * 'connect' !!!!!
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDICommsChannel_ToHost. Should only be used if
+ * ADP_ICEB_CC_Exists didn't return an error.
+ */
+
+
+#define ADP_ICEB_CC_Connect_FromHost ADPSUBREASON(CI_HADP,5)
+/* ADP_ICEB_CC_Connect_FromHost
+ * ----------------------------
+ * Summary: Connect Comms Channel in FromHost direction.
+ *
+ * Arguments:
+ * Send: (byte connect)
+ * Return: (word status)
+ *
+ * 'connect' is the same as in ADP_ICEB_CC_Connect_ToHost above.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDICommsChannel_FromHost. Should only be used if
+ * ADP_ICEB_CC_Exists didn't return an error.
+ */
+
+
+#define ADP_ICEman ADPREASON(CI_HADP,18)
+
+/* The first parameter to ADP_ICEman is a Reason Subcode, and
+ * subsequent parameters are defined by that subcode
+ *
+ * word reason subcode
+ * other arguments as reason subcode determines
+ *
+ */
+
+/* ADP_ICEman sub-reason codes: */
+
+
+#define ADP_ICEM_AddConfig ADPSUBREASON(CI_HADP,0)
+/* ADP_ICEM_AddConfig
+ * ------------------
+ * Summary: Prepares target to receive configuration data block.
+ *
+ * Arguments:
+ * Send: (word nbytes)
+ * Return: (word status)
+ *
+ * 'nbytes' is the number of bytes in the configuration block.
+ * 'status' is RDIError_NoError to indicate success, non-zero if a
+ * configuration block of this size can't be accepted.
+ *
+ * NOTE: Equivalent to RDP_AddConfig.
+ */
+
+
+#define ADP_ICEM_SelectConfig ADPSUBREASON(CI_HADP,1)
+/* ADP_ICEM_SelectConfig
+ * ---------------------
+ * Summary: Selects one of the sets of configuration data blocks and
+ * reinitialises to use the new configuration.
+ *
+ * Arguments:
+ * Send: (byte aspect, byte namelen, byte matchtype, word vsn_req,
+ bytes name)
+ * Return: (word status, word vsn_sel)
+ *
+ * 'aspect' is one of two values defined below.
+ * 'namelen' is the number of bytes in 'name'.
+ * 'matchtype' specifies how the selected version must match that specified,
+ * and takes one of the values defined below.
+ * 'vsn_req' is the requested version of the named configuration.
+ * 'name' is the name of the configuration.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'vsn_sel' is the version number of the configuration selected on success.
+ *
+ * NOTE: Equivalent to RDP_SelectConfig.
+ */
+
+/* 'aspect':- */
+#define ADP_ICEM_SelectConfig_ConfigCPU (0)
+#define ADP_ICEM_SelectConfig_ConfigSystem (1)
+
+/* 'matchtype':- */
+#define ADP_ICEM_SelectConfig_MatchAny (0)
+#define ADP_ICEM_SelectConfig_MatchExactly (1)
+#define ADP_ICEM_SelectConfig_MatchNoEarlier (2)
+
+
+#define ADP_ICEM_ConfigCount ADPSUBREASON(CI_HADP,2)
+/* ADP_ICEM_ConfigCount
+ * --------------------
+ * Summary: Return number of configurations.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status [, word count])
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'count' returns the number of configurations if status is zero.
+ *
+ * NOTE: Equivalent to RDIConfig_Count.
+ */
+
+
+#define ADP_ICEM_ConfigNth ADPSUBREASON(CI_HADP,3)
+/* ADP_ICEM_ConfigNth
+ * ------------------
+ * Summary: Gets the nth configuration details.
+ *
+ * Arguments:
+ * Send: (word confign)
+ * Return: (word status, word version, byte namelen, bytes name)
+ *
+ * 'confign' is the number of the configuration.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'version' is the configuration version number.
+ * 'namelen' is the number of bytes in 'name'.
+ * 'name' is the name of the configuration.
+ *
+ * NOTE: Equivalent to RDIConfig_Nth.
+ */
+
+
+
+#define ADP_Profile ADPREASON(CI_HADP,19)
+
+/* The first parameter to ADP_Profile is a Reason Subcode, and
+ * subsequent parameters are defined by that subcode
+ *
+ * word reason subcode
+ * other arguments as reason subcode determines
+ *
+ */
+
+/* ADP_Profile sub-reason codes: */
+
+
+#define ADP_Profile_Supported ADPSUBREASON(CI_HADP,0)
+/* ADP_Profile_Supported
+ * ---------------------
+ * Summary: Checks whether profiling is supported.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError if profiling is supported, non-zero otherwise.
+ *
+ * NOTE: Can also be determined using Info_Target.
+ */
+
+
+#define ADP_Profile_Stop ADPSUBREASON(CI_HADP,1)
+/* ADP_Profile_Stop
+ * ----------------
+ * Summary: Stops profiling.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDIProfile_Stop.
+ */
+
+
+#define ADP_Profile_Start ADPSUBREASON(CI_HADP,2)
+/* ADP_Profile_Start
+ * -----------------
+ * Summary: Starts profiling (PC sampling).
+ *
+ * Arguments:
+ * Send: (word interval)
+ * Return: (word status)
+ *
+ * 'interval' is the period of PC sampling in micro seconds.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDIProfile_Start.
+ */
+
+
+#define ADP_Profile_WriteMap ADPSUBREASON(CI_HADP,3)
+#define ADP_ProfileWriteHeaderSize (ADP_DEFAULT_HEADER_SIZE + 4*sizeof(word))
+
+/* ADP_Profile_WriteMap
+ * --------------------
+ * Summary: Downloads a map array, which describes the PC ranges for profiling.
+ *
+ * Arguments: A number of messages each of form:-
+ * Send: (word len, word size, word offset, words map_data)
+ * Return: (word status)
+ *
+ * 'len' is the number of elements in the entire map array being downloaded.
+ * 'size' is the number of words being downloaded in this message, i.e. the
+ * length of 'map_data'.
+ * 'offset' is the offset into the entire map array which this message starts
+ * from, in words.
+ * 'map_data' consists of 'size' words of map data.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDIProfile_WriteMap.
+ */
+
+
+#define ADP_Profile_ReadMap ADPSUBREASON(CI_HADP,4)
+#define ADP_ProfileReadHeaderSize (ADP_DEFAULT_HEADER_SIZE + 2*sizeof(word))
+
+/* ADP_Profile_ReadMap
+ * -------------------
+ * Summary: Uploads a set of profile counts which correspond to the current
+ * profile map.
+ *
+ * Arguments: A number of messages, each of the form:
+ * Send: (word offset, word size)
+ * Return: (word status, words counts)
+ *
+ * 'offset' is the offset in the entire array of counts that this message
+ * starts from, in words.
+ * 'size' is the number of words uploaded in this message (in counts).
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'counts' is 'size' words of profile counts.
+ *
+ * NOTE: Equivalent to RDIProfile_ReadMap.
+ */
+
+
+#define ADP_Profile_ClearCounts ADPSUBREASON(CI_HADP,5)
+/* ADP_Profile_ClearCounts
+ * -----------------------
+ * Summary: Requests that PC sample counts be set to zero.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDIProfile_ClearCounts.
+ */
+
+#define ADP_InitialiseApplication ADPREASON(CI_HADP,20)
+/* ADP_InitialiseApplication
+ * -------------------------
+ * Summary: Requests that OS setup up the thread/task so that it can be
+ * executed.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+#define ADP_End ADPREASON(CI_HADP,21)
+/* ADP_End
+ * -------
+ * Summary: Sent by the host debugger to tell angel this debugging session
+ * is is finished
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ * status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+/******************************************************************
+ *
+ * CI_TADP messages
+ *
+ */
+
+#define ADP_TADPUnrecognised ADPREASON(CI_TADP,0)
+/* This message is unusual in that it is normally sent in reply to
+ * another message which is not understood. This is an exception
+ * to the normal protocol which says that a reply must have the
+ * same base reason code as the original. There is a single reply
+ * parameter which is the reason code which was not understood.
+ *
+ * As well as being a reply this message can also be sent and will
+ * return as if this message were unrecognised!
+ *
+ * Parameters:
+ * none
+ *
+ * Reply:
+ * word reason code which was not recognised
+ */
+
+/*-------------------------------------------------------------------------*/
+
+#define ADP_Stopped ADPREASON(CI_TADP,1)
+/* ADP_Stopped
+ * -----------
+ * Summary: This message is sent to the host when the application stops,
+ * either naturally or due to an exception.
+ *
+ * Parameters:
+ * word reason subcode
+ * other arguments as reason subcode determines.
+ * Unless stated otherwise (below) there will be none.
+ *
+ * Reply:
+ * word status unless reason subcode says otherwise
+ *
+ * This message is sent to the host when execution has stopped. This
+ * can be when the end of the application has been reached, or as the
+ * result of an exception. It can also be the return from an ADP_Step
+ * process, when the requested number of instructions have been
+ * executed., or a breakpoint or watchpoint has been hit etc.
+ */
+
+/* The first set of Stopped subreason codes are for the ARM hardware
+ * vectors. These events will be raised if the
+ * ADP_Control_Vector_Catch allows, or if the target application has
+ * not provided its own handlers.
+ */
+#define ADP_Stopped_BranchThroughZero ADPSUBREASON(CI_TADP,0)
+#define ADP_Stopped_UndefinedInstr ADPSUBREASON(CI_TADP,1)
+#define ADP_Stopped_SoftwareInterrupt ADPSUBREASON(CI_TADP,2)
+#define ADP_Stopped_PrefetchAbort ADPSUBREASON(CI_TADP,3)
+#define ADP_Stopped_DataAbort ADPSUBREASON(CI_TADP,4)
+#define ADP_Stopped_AddressException ADPSUBREASON(CI_TADP,5)
+#define ADP_Stopped_IRQ ADPSUBREASON(CI_TADP,6)
+#define ADP_Stopped_FIQ ADPSUBREASON(CI_TADP,7)
+
+/* We leave the rest of what would be the bits in the VectorCatch
+ * bitmask free for future expansion.
+ */
+
+/* The following are software reasons for execution stopping: */
+#define ADP_Stopped_BreakPoint ADPSUBREASON(CI_TADP,32)
+/* Breakpoint was reached
+ * extra send parameter: word handle - indicates which breakpoint
+ */
+
+#define ADP_Stopped_WatchPoint ADPSUBREASON(CI_TADP,33)
+/* Watchpoint was triggered
+ * extra send parameter: word handle - indicates which watchpoint
+ */
+
+#define ADP_Stopped_StepComplete ADPSUBREASON(CI_TADP,34)
+/* End of ADP_Step request */
+
+#define ADP_Stopped_RunTimeErrorUnknown ADPSUBREASON(CI_TADP,35)
+/*
+ * non-specific fatal runtime support error
+ */
+
+#define ADP_Stopped_InternalError ADPSUBREASON(CI_TADP,36)
+/* extra send parameter: word error - indicates the nature of the error
+ *
+ * An Angel internal error has happened. The error number should be
+ * displayed for the user to report to his software supplier. Once
+ * this error has been received the internal state of Angel can no longer
+ * be trusted.
+ */
+
+#define ADP_Stopped_UserInterruption ADPSUBREASON(CI_TADP,37)
+/* Host requested interruption */
+
+#define ADP_Stopped_ApplicationExit ADPSUBREASON(CI_TADP,38)
+/* extra send parameter: word exitcode
+ * This indicates that the application has exited via exit(), an exitcode
+ * of zero indiactes successful termination.
+ */
+
+#define ADP_Stopped_StackOverflow ADPSUBREASON(CI_TADP, 39)
+/*
+ * Software stack overflow has occurred
+ */
+
+#define ADP_Stopped_DivisionByZero ADPSUBREASON(CI_TADP, 40)
+/*
+ * Division by zero has occurred
+ */
+
+#define ADP_Stopped_OSSpecific ADPSUBREASON(CI_TADP, 41)
+/*
+ * The OS has requested that execution stops. The OS will know
+ * why this has happened.
+ */
+
+
+
+/******************************************************************
+ *
+ * CI_TTDCC messages (Target-initiated debug comms channel)
+ *
+ */
+
+#define ADP_TDCC_ToHost ADPREASON(CI_TTDCC,0)
+/* ADP_TDCC_ToHost
+ * ------------------
+ * Summary: Send Data down Comms Channel in ToHost direction.
+ *
+ * Arguments:
+ * Send: (word nbytes, words data)
+ * Return: (word status)
+ *
+ * 'nbytes' is number of BYTES to be transferred from the target to the
+ * host via the Debug Comms channel.
+ * 'data' is (nbytes/sizeof(word)) WORDS of data to be transferred from
+ * the target to the host via the Debug Comms channel.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDP_CCToHost and RDP_CCToHostReply (just set the
+ * direction bit).
+ * NOTE II: Current implementations only support single word transfers
+ * (nbytes = 4).
+ */
+
+
+#define ADP_TDCC_FromHost ADPREASON(CI_TTDCC,1)
+/* ADP_TDCC_FromHost
+ * --------------------
+ * Summary: Send Data down Comms Channel in FromHost direction.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word nbytes, words data)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'nbytes' is number of BYTES to be transferred from the host to the
+ * target via the Debug Comms channel, or zero if the host has no data
+ * to transfer.
+ * 'data' is (nbytes/sizeof(word)) WORDS of transferred data.
+ *
+ * NOTE: Equivalent to RDP_CCFromHost and RDP_CCFromHostReply (just set the
+ * direction bit).
+ * NOTE II: Current implementations only support single word transfers
+ * (nbytes = 4).
+ */
+
+
+/*******************************************************************
+ *
+ * Error Codes
+ *
+ */
+
+#define RDIError_NoError 0
+
+#define RDIError_Reset 1
+#define RDIError_UndefinedInstruction 2
+#define RDIError_SoftwareInterrupt 3
+#define RDIError_PrefetchAbort 4
+#define RDIError_DataAbort 5
+#define RDIError_AddressException 6
+#define RDIError_IRQ 7
+#define RDIError_FIQ 8
+#define RDIError_Error 9
+#define RDIError_BranchThrough0 10
+
+#define RDIError_NotInitialised 128
+#define RDIError_UnableToInitialise 129
+#define RDIError_WrongByteSex 130
+#define RDIError_UnableToTerminate 131
+#define RDIError_BadInstruction 132
+#define RDIError_IllegalInstruction 133
+#define RDIError_BadCPUStateSetting 134
+#define RDIError_UnknownCoPro 135
+#define RDIError_UnknownCoProState 136
+#define RDIError_BadCoProState 137
+#define RDIError_BadPointType 138
+#define RDIError_UnimplementedType 139
+#define RDIError_BadPointSize 140
+#define RDIError_UnimplementedSize 141
+#define RDIError_NoMorePoints 142
+#define RDIError_BreakpointReached 143
+#define RDIError_WatchpointAccessed 144
+#define RDIError_NoSuchPoint 145
+#define RDIError_ProgramFinishedInStep 146
+#define RDIError_UserInterrupt 147
+#define RDIError_CantSetPoint 148
+#define RDIError_IncompatibleRDILevels 149
+
+#define RDIError_CantLoadConfig 150
+#define RDIError_BadConfigData 151
+#define RDIError_NoSuchConfig 152
+#define RDIError_BufferFull 153
+#define RDIError_OutOfStore 154
+#define RDIError_NotInDownload 155
+#define RDIError_PointInUse 156
+#define RDIError_BadImageFormat 157
+#define RDIError_TargetRunning 158
+#define RDIError_DeviceWouldNotOpen 159
+#define RDIError_NoSuchHandle 160
+#define RDIError_ConflictingPoint 161
+
+#define RDIError_LittleEndian 240
+#define RDIError_BigEndian 241
+#define RDIError_SoftInitialiseError 242
+
+#define RDIError_InsufficientPrivilege 253
+#define RDIError_UnimplementedMessage 254
+#define RDIError_UndefinedMessage 255
+
+
+#endif
+
+/* EOF adp_h */
diff --git a/gdb/rdi-share/adperr.h b/gdb/rdi-share/adperr.h
new file mode 100644
index 00000000000..f90f1dcc3fd
--- /dev/null
+++ b/gdb/rdi-share/adperr.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Definitions of ADP error codes
+ */
+
+#ifndef angsd_adperrs_h
+#define angsd_adperrs_h
+/*
+ * ADP failure codes start at 256 to distinguish them for debug purposes
+ */
+enum AdpErrs
+{
+ adp_ok = 0,
+ adp_failed = 256,
+ adp_malloc_failure,
+ adp_illegal_args,
+ adp_device_not_found,
+ adp_device_open_failed,
+ adp_device_already_open,
+ adp_device_not_open,
+ adp_bad_channel_id,
+ adp_callback_already_registered,
+ adp_write_busy,
+ adp_bad_packet,
+ adp_seq_high,
+ adp_seq_low,
+ adp_timeout_on_open,
+ adp_abandon_boot_wait,
+ adp_late_startup,
+ adp_new_agent_starting
+};
+
+#ifndef __cplusplus
+typedef enum AdpErrs AdpErrs;
+#endif
+
+#define AdpMess_Failed "ADP Error - unspecific failure"
+#define AdpMess_MallocFailed "ADP Error - malloc failed"
+#define AdpMess_IllegalArgs "ADP Error - illegal arguments"
+#define AdpMess_DeviceNotFound "ADP Error - invalid device specified"
+#define AdpMess_DeviceOpenFailed "ADP Error - specified device failed to open"
+#define AdpMess_DeviceAlreadyOpen "ADP Error - device already open"
+#define AdpMess_DeviceNotOpen "ADP Error - device not open"
+#define AdpMess_BadChannelId "ADP Error - bad channel Id"
+#define AdpMess_CBAlreadyRegd "ADP Error - callback already registered"
+#define AdpMess_WriteBusy "ADP Error - write busy"
+#define AdpMess_BadPacket "ADP Error - bad packet"
+#define AdpMess_SeqHigh "ADP Error - sequence number too high"
+#define AdpMess_SeqLow "ADP Error - sequence number too low"
+#define AdpMess_TimeoutOnOpen "ADP Error - target did not respond"
+#define AdpMess_AbandonBootWait "abandoned wait for late startup"
+#define AdpMess_LateStartup "Target compiled with LATE_STARTUP set.\n" \
+ "Waiting for target...\n" \
+ "Press <Ctrl-C> to abort.\n"
+#define AdpMessLen_LateStartup (3*80)
+#define AdpMess_NewAgentStarting "New Debug Agent about to start.\n"
+
+#endif /* ndef angsd_adperr_h */
+
+/* EOF adperr.h */
diff --git a/gdb/rdi-share/angel.h b/gdb/rdi-share/angel.h
new file mode 100644
index 00000000000..60a5f31720f
--- /dev/null
+++ b/gdb/rdi-share/angel.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*> angel.h <*/
+/*---------------------------------------------------------------------------*/
+/* This header file is the main holder for the declarations and
+ * prototypes for the core Angel system. Some Angel concepts are
+ * described at the start of this file to ensure that a complete view
+ * of the Angel world can be derived purely from the source.
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * NOTE: Currently the Angel source is designed to be simple,
+ * understandable and easy to port to new hardware platforms. However,
+ * this does not always yield the highest performing system. The
+ * current layered approach introduces an overhead to the performance
+ * of the system. In a true commercial target, this code should be
+ * re-designed to build a system where the Angel logical message
+ * system, device driver and hardware accesses are merged to provide
+ * the best performance.
+ */
+/*---------------------------------------------------------------------------*/
+/* Angel overview:
+
+... some comments describing Angel ...
+
+ * Angel is designed as a kit-of-parts that can be used to provide
+ * run-time support for the development of ARM applications. The main
+ * core of Angel is in providing support for the "debug" message
+ * communication with a host system. These messages do not just cover
+ * debugging ARM processes, but also the process of downloading ARM
+ * programs or attaching to executing processes on the target.
+ *
+ * A stand-alone ROM based Angel world is the basic starting point for
+ * a system, since it will allow programs to be downloaded to the
+ * target. The ROM version of Angel will provide the generic debug
+ * support, but no system specific routines. The preferred method of
+ * using Angel is as a link library. This ensures that applications
+ * carry with them the Angel routines necessary to support debugging
+ * (and also ensure that the Angel version is up-to-date, independant
+ * of the version in the target ROM). Eventually, once a program has
+ * been fully debugged, a ROMmed version of the program can be
+ * generated with the Angel code being provided in the application.
+
+.. more comments ..
+
+ * The standard Angel routines do *NOT* perform any dynamic memory
+ * allocation. To simplify the source, and aid the porting to a non C
+ * library world, memory is either pre-allocated (as build-time
+ * globals) or actually given to the particular Angel routine by the
+ * active run-time. This ensures that the interaction between Angel
+ * and the target O/S is minimised.
+ *
+ * Notes: We sub-include more header files to keep the source
+ * modular. Since Angel is a kit-of-parts alternative systems may need
+ * to change the prototypes of particular functions, whilst
+ * maintaining a fixed external interface. e.g. using the standard
+ * DEBUG messages, but with a different communications world.
+ */
+/*---------------------------------------------------------------------------*/
+
+#ifndef __angel_h
+#define __angel_h
+
+/*---------------------------------------------------------------------------*/
+/*-- Global Angel definitions and manifests ---------------------------------*/
+/*---------------------------------------------------------------------------*/
+/* When building Angel we may not include the standard library
+ * headers. However, it is useful coding using standard macro names
+ * since it makes the code easier to understand.
+ */
+
+typedef unsigned int word ;
+typedef unsigned char byte ;
+
+/* The following typedefs can be used to access I/O registers: */
+typedef volatile unsigned int vuword ;
+typedef volatile unsigned char vubyte ;
+
+/*
+ * The following typedefs are used when defining objects that may also
+ * be created on a host system, where the word size is not
+ * 32bits. This ensures that the same data values are manipulated.
+ */
+#ifdef TARGET
+typedef unsigned int unsigned32;
+typedef signed int signed32;
+typedef int int32;
+
+typedef unsigned short int unsigned16;
+typedef signed short int signed16;
+
+/*
+ * yet another solution for the bool/boolean problem, this one is
+ * copied from Scott's modifications to clx/host.h
+ */
+# ifdef IMPLEMENT_BOOL_AS_ENUM
+ enum _bool { _false, _true };
+# define _bool enum _bool
+# elif defined(IMPLEMENT_BOOL_AS_INT) || !defined(__cplusplus)
+# define _bool int
+# define _false 0
+# define _true 1
+# endif
+
+# ifdef _bool
+# define bool _bool
+# endif
+
+# ifndef true
+# define true _true
+# define false _false
+# endif
+
+# ifndef YES
+# define YES true
+# define NO false
+# endif
+
+# undef TRUE /* some OSF headers define as 1 */
+# define TRUE true
+
+# undef FALSE /* some OSF headers define as 1 */
+# define FALSE false
+
+# ifndef NULL
+# define NULL 0
+# endif
+
+#else
+
+# include "host.h"
+
+#endif
+
+#ifndef IGNORE
+# define IGNORE(x) ((x)=(x))
+#endif
+
+/* The following typedef allows us to cast between integral and
+ * function pointers. This isn't allowed by direct casting when
+ * conforming to the ANSI spec.
+ */
+typedef union ansibodge
+{
+ word w ;
+ word *wp ;
+ void *vp ;
+ byte *bp ;
+ void (*vfn)(void) ;
+ word (*wfn)(void) ;
+ int (*ifn)(void) ;
+ byte (*bfn)(void) ;
+} ansibodge ;
+
+/*---------------------------------------------------------------------------*/
+
+/* The amount setup aside by the run-time system for stack overflow
+ * handlers to execute in. This must be at least 256bytes, since that
+ * value is assumed by the current ARM Ltd compiler.
+ * This space is _only_ kept for the USR stack, not any of the privileged
+ * mode stacks, as stack overflow on these is always fatal - there is
+ * no point attemptingto recover. In addition is is important that
+ * Angel should keep privileged stack space requirements to a minimum.
+ */
+#define APCS_STACKGUARD 256
+
+#endif /* __angel_h */
+
+/* EOF angel.h */
diff --git a/gdb/rdi-share/angel_bytesex.c b/gdb/rdi-share/angel_bytesex.c
new file mode 100644
index 00000000000..054f9607ce1
--- /dev/null
+++ b/gdb/rdi-share/angel_bytesex.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * angel_bytesex.c - Code to support byte-sex independence
+ * Copyright: (C) 1991, Advanced RISC Machines Ltd., Cambridge, England.
+ */
+
+/*
+ * RCS $Revision$
+ * Checkin $Date$
+ */
+
+#include "angel_bytesex.h"
+
+static int reversing_bytes = 0;
+
+void bytesex_reverse(yes_or_no)
+int yes_or_no;
+{ reversing_bytes = yes_or_no;
+}
+
+int bytesex_reversing()
+{
+ return reversing_bytes;
+}
+
+int32 bytesex_hostval(v)
+int32 v;
+{ /* Return v with the same endian-ness as the host */
+ /* This mess generates better ARM code than the more obvious mess */
+ /* and may eventually peephole to optimal code... */
+ if (reversing_bytes)
+ { unsigned32 t;
+ /* t = v ^ (v ror 16) */
+ t = v ^ ((v << 16) | (((unsigned32)v) >> 16));
+ t &= ~0xff0000;
+ /* v = v ror 8 */
+ v = (v << 24) | (((unsigned32)v) >> 8);
+ v = v ^ (t >> 8);
+ }
+ return v;
+}
+
+int32 bytesex_hostval_16(v)
+int32 v;
+{
+ if (reversing_bytes) {
+ v = ((v >> 8) & 0xff) | ((v << 8) & 0xff00);
+ }
+ return v;
+}
diff --git a/gdb/rdi-share/angel_bytesex.h b/gdb/rdi-share/angel_bytesex.h
new file mode 100644
index 00000000000..cb86af4fdc5
--- /dev/null
+++ b/gdb/rdi-share/angel_bytesex.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ Title: Code to support byte-sex independence
+ Copyright: (C) 1991, Advanced RISC Machines Ltd., Cambridge, England.
+*/
+/*
+ * RCS $Revision$
+ * Checkin $Date$
+ */
+
+#ifndef angel_bytesex_h
+#define angel_bytesex_h
+
+#include "host.h"
+
+void bytesex_reverse(int yes_or_no);
+/*
+ * Turn sex-reversal on or off - 0 means off, non-0 means on.
+ */
+
+int bytesex_reversing(void);
+/*
+ * Return non-0 if reversing the byte sex, else 0.
+ */
+
+int32 bytesex_hostval(int32 v);
+/*
+ * Return v or byte-reversed v, according to whether sex-reversval
+ * is on or off.
+ */
+
+int32 bytesex_hostval_16(int32 v);
+/* Return v or byte-reversed v for a 16 bit value */
+
+#endif
diff --git a/gdb/rdi-share/angel_endian.h b/gdb/rdi-share/angel_endian.h
new file mode 100644
index 00000000000..4e40dcb7a9e
--- /dev/null
+++ b/gdb/rdi-share/angel_endian.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * angel_endian.h - target endianness independent read/write primitives.
+ */
+
+#ifndef angel_endian_h
+#define angel_endian_h
+
+/*
+ * The endianness of the data being processed needs to be known, but
+ * the host endianness is not required (since the data is constructed
+ * using bytes). At the moment these are provided as macros. This
+ * gives the compiler freedom in optimising individual calls. However,
+ * if space is at a premium then functions should be provided.
+ *
+ * NOTE: These macros assume that the data has been packed in the same format
+ * as the packing on the build host. If this is not the case then
+ * the wrong addresses could be used when dealing with structures.
+ *
+ */
+
+/*
+ * For all the following routines the target endianness is defined by the
+ * following boolean definitions.
+ */
+#define BE (1 == 1) /* TRUE : big-endian */
+#define LE (1 == 0) /* FALSE : little-endian */
+
+/*
+ * The following type definitions are used by the endianness converting
+ * macros.
+ */
+typedef unsigned char U8;
+typedef U8 *P_U8;
+typedef const U8 *CP_U8;
+
+typedef unsigned short U16;
+typedef U16 *P_U16;
+
+typedef unsigned int U32;
+typedef U32 *P_U32;
+
+/*
+ * If the endianness of the host and target are known (fixed) and the same
+ * then the following macro definitions can be used. These just directly copy
+ * the data.
+ *
+ * #define READ(e,a) (a)
+ * #define WRITE(e,a,v) ((a) = (v))
+ * #define PREAD(e,a) (a)
+ * #define PWRITE(e,a,v) (*(a) = (v))
+ */
+
+/*
+ * These macros assume that a byte (char) is 8bits in size, and that the
+ * endianness is not important when reading or writing bytes.
+ */
+#define PUT8(a,v) (*((P_U8)(a)) = (U8)(v))
+#define PUT16LE(a,v) (PUT8(a,((v) & 0xFF)), \
+ PUT8((((P_U8)(a)) + sizeof(char)),((v) >> 8)))
+#define PUT16BE(a,v) (PUT8(a,((v) >> 8)), \
+ PUT8((((P_U8)(a)) + sizeof(char)),((v) & 0xFF)))
+#define PUT32LE(a,v) (PUT16LE(a,v), \
+ PUT16LE((((P_U8)(a)) + sizeof(short)),((v) >> 16)))
+#define PUT32BE(a,v) (PUT16BE(a,((v) >> 16)), \
+ PUT16BE((((P_U8)(a)) + sizeof(short)),v))
+
+#define GET8(a) (*((CP_U8)(a)))
+#define GET16LE(a) (GET8(a) | (((U16)GET8(((CP_U8)(a)) + sizeof(char))) << 8))
+#define GET16BE(a) ((((U16)GET8(a)) << 8) | GET8(((CP_U8)(a)) + sizeof(char)))
+#define GET32LE(a) (GET16LE(a) | \
+ (((U32)GET16LE(((CP_U8)(a)) + sizeof(short))) << 16))
+#define GET32BE(a) ((((U32)GET16BE(a)) << 16) | \
+ GET16BE(((CP_U8)(a)) + sizeof(short)))
+
+/*
+ * These macros simplify the code in respect to reading and writing the
+ * correct size data when dealing with endianness. "e" is TRUE if we are
+ * dealing with big-endian data, FALSE if we are dealing with little-endian.
+ */
+
+/* void WRITE(int endianness, void *address, unsigned value); */
+
+#define WRITE16(e,a,v) ((e) ? PUT16BE(&(a),v) : PUT16LE(&(a),v))
+#define WRITE32(e,a,v) ((e) ? PUT32BE(&(a),v) : PUT32LE(&(a),v))
+#define WRITE(e,a,v) ((sizeof(v) == sizeof(char)) ? \
+ PUT8(&(a),v) : ((sizeof(v) == sizeof(short)) ? \
+ WRITE16(e,a,v) : WRITE32(e,a,v)))
+
+/* unsigned READ(int endianness, void *address) */
+#define READ16(e,a) ((e) ? GET16BE(&(a)) : GET16LE(&(a)))
+#define READ32(e,a) ((e) ? GET32BE(&(a)) : GET32LE(&(a)))
+#define READ(e,a) ((sizeof(a) == sizeof(char)) ? \
+ GET8((CP_U8)&(a)) : ((sizeof(a) == sizeof(short)) ? \
+ READ16(e,a) : READ32(e,a)))
+
+/* void PWRITE(int endianness, void *address, unsigned value); */
+#define PWRITE16(e,a,v) ((e) ? PUT16BE(a,v) : PUT16LE(a,v))
+#define PWRITE32(e,a,v) ((e) ? PUT32BE(a,v) : PUT32LE(a,v))
+#define PWRITE(e,a,v) ((sizeof(v) == sizeof(char)) ? \
+ PUT8(a,v) : ((sizeof(v) == sizeof(short)) ? \
+ PWRITE16(e,a,v) : PWRITE32(e,a,v)))
+
+/* unsigned PREAD(int endianness, void *address) */
+#define PREAD16(e,a) ((e) ? GET16BE(a) : GET16LE(a))
+#define PREAD32(e,a) ((e) ? GET32BE(a) : GET32LE(a))
+#define PREAD(e,a) ((sizeof(*(a)) == sizeof(char)) ? \
+ GET8((CP_U8)a) : ((sizeof(*(a)) == sizeof(short)) ? \
+ PREAD16(e,a) : PREAD32(e,a)))
+
+#endif /* !defined(angel_endian_h) */
+
+/* EOF angel_endian.h */
diff --git a/gdb/rdi-share/ardi.c b/gdb/rdi-share/ardi.c
new file mode 100644
index 00000000000..334a1fc9a60
--- /dev/null
+++ b/gdb/rdi-share/ardi.c
@@ -0,0 +1,2693 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ARDI.c
+ * Angel Remote Debug Interface
+ *
+ *
+ * $Revision$
+ * $Date$
+ *
+ * This file is based on /plg/pisd/rdi.c, but instead of using RDP it uses
+ * ADP messages.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define uint HIDE_HPs_uint
+#include <signal.h>
+#undef uint
+
+
+#include "angel_endian.h"
+#include "ardi.h"
+#include "buffers.h"
+#include "channels.h"
+#include "hostchan.h"
+#include "host.h"
+#include "angel_bytesex.h"
+#include "dbg_cp.h"
+#include "adp.h"
+#include "hsys.h"
+#include "logging.h"
+#include "msgbuild.h"
+#include "rxtx.h"
+#include "devsw.h"
+#include "params.h"
+
+#ifdef COMPILING_ON_WINDOWS
+# define IGNORE(x) (x = x) /* must go after #includes to work on Windows */
+#endif
+#define NOT(x) (!(x))
+
+#define ADP_INITIAL_TIMEOUT_PERIOD 5
+
+static volatile int executing;
+static int rdi_log = 0 ; /* debugging ? */
+
+/* we need a starting point for our first buffers, this is a safe one */
+int Armsd_BufferSize = ADP_BUFFER_MIN_SIZE;
+int Armsd_LongBufSize = ADP_BUFFER_MIN_SIZE;
+
+#ifdef WIN32
+ extern int interrupted;
+ extern int swiprocessing;
+#endif
+
+static char dummycline = 0;
+char *ardi_commandline = &dummycline ; /* exported in ardi.h */
+
+extern unsigned int heartbeat_enabled;
+
+static unsigned char *cpwords[16];
+
+typedef struct stoppedProcListElement {
+ struct stoppedProcListElement *next;
+ angel_RDI_TargetStoppedProc *fn;
+ void *arg;
+} stoppedProcListElement;
+
+static stoppedProcListElement *stopped_proc_list=NULL;
+
+const struct Dbg_HostosInterface *angel_hostif;
+static hsys_state *hstate;
+
+static void angel_DebugPrint(const char *format, ...)
+{ va_list ap;
+ va_start(ap, format);
+ angel_hostif->dbgprint(angel_hostif->dbgarg, format, ap);
+ va_end(ap);
+}
+
+#ifdef RDI_VERBOSE
+#define TracePrint(s) \
+ if (rdi_log & 2) angel_DebugPrint("\n"); \
+ if (rdi_log & 1) angel_DebugPrint s
+#else
+#define TracePrint(s)
+#endif
+
+typedef struct receive_dbgmsg_state {
+ volatile int received;
+ Packet *packet;
+} receive_dbgmsg_state;
+
+static receive_dbgmsg_state dbgmsg_state;
+
+static void receive_debug_packet(Packet *packet, void *stateptr)
+{
+ receive_dbgmsg_state *state = stateptr;
+
+ state->packet = packet;
+ state->received = 1;
+}
+
+static int register_debug_message_handler(void)
+{
+ int err;
+ dbgmsg_state.received = 0;
+
+ err = Adp_ChannelRegisterRead(CI_HADP, receive_debug_packet, &dbgmsg_state);
+#ifdef DEBUG
+ if (err!=adp_ok) angel_DebugPrint("register_debug_message_handler failed %i\n", err);
+#endif
+ return err;
+}
+
+
+static int wait_for_debug_message(int *rcode, int *debugID,
+ int *OSinfo1, int *OSinfo2,
+ int *status, Packet **packet)
+{
+ unsigned int reason;
+
+#ifdef DEBUG
+ angel_DebugPrint("wait_for_debug_message waiting for %X\n", *rcode);
+#endif
+
+ for ( ; dbgmsg_state.received == 0 ; )
+ Adp_AsynchronousProcessing(async_block_on_read);
+
+#ifdef DEBUG
+ angel_DebugPrint("wait_for_debug_message got packet\n");
+#endif
+
+ *packet = dbgmsg_state.packet;
+
+ Adp_ChannelRegisterRead(CI_HADP, NULL, NULL);
+
+ /*
+ * TODO:
+ * If ADP_Unrecognised return error.
+ * If ADP_Acknowledge - handle appropriately.
+ * If expected message read arguments and return RDIError_NoError.
+ * Note: if RDIError occurs then the data values returned are junk
+ */
+
+ unpack_message(BUFFERDATA((*packet)->pk_buffer), "%w%w%w%w%w", &reason, debugID,
+ OSinfo1, OSinfo2, status);
+ if (reason&0xffffff == ADP_HADPUnrecognised)
+ return RDIError_UnimplementedMessage;
+ if (reason != (unsigned ) *rcode) {
+ if((reason&0xffffff) == ADP_HADPUnrecognised)
+ return RDIError_UnimplementedMessage;
+ else {
+ angel_DebugPrint("ARDI ERROR: Expected reasoncode %x got reasoncode %x.\n",
+ *rcode, reason);
+ return RDIError_Error;
+ }
+ }
+ else
+ return RDIError_NoError;
+ return RDIError_Error; /* stop a pesky ANSI compiler warning */
+}
+
+
+/*
+ * Handler and registration for logging messages from target
+ */
+static void TargetLogCallback( Packet *packet, void *state )
+{
+ p_Buffer reply = BUFFERDATA(packet->pk_buffer);
+ unsigned int len = packet->pk_length;
+ IGNORE(state);
+ angel_hostif->write(angel_hostif->hostosarg,
+ (char *)reply, len - CHAN_HEADER_SIZE);
+ DevSW_FreePacket(packet);
+
+ packet = DevSW_AllocatePacket(4); /* better not ask for 0 */
+ /* the reply is the ACK - any contents are ignored */
+ if (packet != NULL)
+ Adp_ChannelWrite( CI_TLOG, packet );
+}
+
+static void TargetLogInit( void )
+{
+ AdpErrs err = Adp_ChannelRegisterRead( CI_TLOG, TargetLogCallback, NULL );
+
+#ifdef DEBUG
+ if (err != adp_ok)
+ angel_DebugPrint("CI_TLOG RegisterRead failed %d\n", err);
+#else
+ IGNORE(err);
+#endif
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_open-----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+typedef struct NegotiateState {
+ bool negotiate_resp;
+ bool negotiate_ack;
+ bool link_check_resp;
+ ParameterConfig *accepted_config;
+} NegotiateState;
+
+static void receive_negotiate(Packet *packet, void *stateptr)
+{
+ unsigned reason, debugID, OSinfo1, OSinfo2, status;
+ NegotiateState *n_state = (NegotiateState *)stateptr;
+ p_Buffer reply = BUFFERDATA(packet->pk_buffer);
+
+ unpack_message( reply, "%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2 );
+ reply += ADP_DEFAULT_HEADER_SIZE;
+
+#ifdef DEBUG
+ angel_DebugPrint( "receive_negotiate: reason %x\n", reason );
+#endif
+
+ switch ( reason )
+ {
+ case ADP_ParamNegotiate | TtoH:
+ {
+ n_state->negotiate_resp = TRUE;
+
+ status = GET32LE( reply );
+ reply += sizeof(word);
+#ifdef DEBUG
+ angel_DebugPrint( "ParamNegotiate status %u\n", status );
+#endif
+ if ( status == RDIError_NoError )
+ {
+ if ( Angel_ReadParamConfigMessage(
+ reply, n_state->accepted_config ) )
+ n_state->negotiate_ack = TRUE;
+ }
+ break;
+ }
+
+ case ADP_LinkCheck | TtoH:
+ {
+#ifdef DEBUG
+ angel_DebugPrint( "PONG!\n" );
+#endif
+ n_state->link_check_resp = TRUE;
+ break;
+ }
+
+ default:
+ {
+#ifdef DEBUG
+ angel_DebugPrint( "Unexpected!\n" );
+#endif
+ break;
+ }
+ }
+ DevSW_FreePacket( packet );
+}
+
+# include <sys/types.h>
+#ifdef __unix
+# include <sys/time.h>
+#else
+# include <time.h>
+#endif
+
+/*
+ * convert a config into a single-valued options list
+ */
+static ParameterOptions *config_to_options( const ParameterConfig *config )
+{
+ unsigned int num_params;
+ size_t size;
+ ParameterOptions *base_p;
+
+ num_params = config->num_parameters;
+ size =
+ sizeof(ParameterOptions)
+ + num_params*(sizeof(ParameterList) + sizeof(unsigned int));
+ base_p = malloc( size );
+
+ if ( base_p != NULL )
+ {
+ unsigned int u;
+ ParameterList *list_p =
+ (ParameterList *)((char *)base_p + sizeof(ParameterOptions));
+ unsigned int *option_p =
+ (unsigned int *)(list_p + num_params);
+
+ base_p->num_param_lists = num_params;
+ base_p->param_list = list_p;
+
+ for ( u = 0; u < num_params; ++u )
+ {
+ option_p[u] = config->param[u].value;
+ list_p[u].type = config->param[u].type;
+ list_p[u].num_options = 1;
+ list_p[u].option = &option_p[u];
+ }
+ }
+
+ return base_p;
+}
+
+static AdpErrs negotiate_params( const ParameterOptions *user_options )
+{
+ Packet *packet;
+ unsigned int count;
+ static Parameter params[AP_NUM_PARAMS];
+ static ParameterConfig accepted_config = { AP_NUM_PARAMS, params };
+
+ time_t t;
+
+ static volatile NegotiateState n_state;
+ n_state.negotiate_resp = FALSE;
+ n_state.negotiate_ack = FALSE;
+ n_state.link_check_resp = FALSE;
+ n_state.accepted_config = &accepted_config;
+
+#ifdef DEBUG
+ angel_DebugPrint( "negotiate_params\n" );
+#endif
+
+ Adp_ChannelRegisterRead( CI_HBOOT, receive_negotiate, (void *)&n_state );
+
+ packet = (Packet *)DevSW_AllocatePacket(Armsd_BufferSize);
+ count = msgbuild( BUFFERDATA(packet->pk_buffer), "%w%w%w%w",
+ ADP_ParamNegotiate | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown );
+ count += Angel_BuildParamOptionsMessage(
+ BUFFERDATA(packet->pk_buffer) + count, user_options );
+ packet->pk_length = count;
+ Adp_ChannelWriteAsync( CI_HBOOT, packet );
+
+#ifdef DEBUG
+ angel_DebugPrint( "sent negotiate packet\n" );
+#endif
+
+ t=time(NULL);
+
+ do {
+ Adp_AsynchronousProcessing(async_block_on_nothing);
+
+ if ((time(NULL)-t) > ADP_INITIAL_TIMEOUT_PERIOD) {
+ return adp_timeout_on_open;
+ }
+ } while ( ! n_state.negotiate_resp );
+
+ if ( n_state.negotiate_ack )
+ {
+ /* select accepted config */
+ Adp_Ioctl( DC_SET_PARAMS, (void *)n_state.accepted_config );
+
+ /*
+ * 960430 KWelton
+ *
+ * There is a race in the renegotiation protocol: the
+ * target has to have had time to load new config before
+ * we send the link check packet - insert a deliberate
+ * pause (100ms) to give the target some time
+ */
+ Adp_delay(100000);
+
+ /* do link check */
+ msgsend( CI_HBOOT, "%w%w%w%w", ADP_LinkCheck | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown );
+#ifdef DEBUG
+ angel_DebugPrint("sent link check\n");
+#endif
+
+ do {
+ Adp_AsynchronousProcessing(async_block_on_read);
+ } while ( ! n_state.link_check_resp );
+ Adp_initSeq();
+ }
+ return adp_ok;
+}
+
+static int late_booted = FALSE;
+static bool ardi_handler_installed = FALSE;
+
+#ifdef __unix
+static struct sigaction old_action;
+#else
+static void (*old_handler)();
+#endif
+
+static bool boot_interrupted = FALSE;
+static volatile bool interrupt_request = FALSE;
+static volatile bool stop_request = FALSE;
+
+static void ardi_sigint_handler(int sig) {
+#ifdef DEBUG
+ if (sig != SIGINT)
+ angel_DebugPrint("Expecting SIGINT got %d.\n", sig);
+#else
+ IGNORE(sig);
+#endif
+ boot_interrupted = TRUE;
+ interrupt_request = TRUE;
+#ifndef __unix
+ signal(SIGINT, ardi_sigint_handler);
+#endif
+}
+
+static void install_ardi_handler( void ) {
+ if (!ardi_handler_installed) {
+ /* install a new Ctrl-C handler so we can abandon waiting */
+#ifdef __unix
+ struct sigaction new_action;
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_handler = ardi_sigint_handler;
+ new_action.sa_flags = 0;
+ sigaction(SIGINT, &new_action, &old_action);
+#else
+ old_handler = signal(SIGINT, ardi_sigint_handler);
+#endif
+ ardi_handler_installed = TRUE;
+ }
+}
+
+static int angel_RDI_errmess(char *buf, int blen, int errnum);
+
+static void receive_reset_acknowledge(Packet *packet, void *stateptr) {
+ unsigned reason, debugID, OSinfo1, OSinfo2, status;
+ IGNORE(stateptr);
+
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &status);
+ if (reason==(ADP_Reset | TtoH) && status==AB_NORMAL_ACK) {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Successfully received normal reset acknowledgement\n");
+ late_booted = FALSE;
+#endif
+ } else if (reason==(ADP_Reset | TtoH) && status==AB_LATE_ACK) {
+ char late_msg[AdpMessLen_LateStartup];
+ int late_len;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Successfully received LATE reset acknowledgement\n");
+#endif
+ late_booted = TRUE;
+ install_ardi_handler();
+ late_len = angel_RDI_errmess(late_msg,
+ AdpMessLen_LateStartup, adp_late_startup);
+ angel_hostif->write(angel_hostif->hostosarg, late_msg, late_len);
+ } else {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Bad reset ack: reason=%8X, status=%8X\n", reason, status);
+#endif
+ }
+ DevSW_FreePacket(packet);
+}
+
+static int booted_not_received;
+static unsigned int angel_version;
+static unsigned int adp_version;
+static unsigned int arch_info;
+static unsigned int cpu_info;
+static unsigned int hw_status;
+
+static void receive_booted(Packet *packet, void *stateptr) {
+ unsigned reason, debugID, OSinfo1, OSinfo2, banner_length, bufsiz, longsiz;
+ unsigned i, count;
+
+ IGNORE(stateptr);
+
+ count = unpack_message(BUFFERDATA(packet->pk_buffer),
+ "%w%w%w%w%w%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2, &bufsiz, &longsiz,
+ &angel_version, &adp_version,
+ &arch_info, &cpu_info, &hw_status, &banner_length);
+ if (reason==(ADP_Booted | TtoH)) {
+#ifdef MONITOR_DOWNLOAD_PACKETS
+ angel_DebugPrint("DEBUG: Successfully received Booted\n");
+ angel_DebugPrint(" cpu_info=%8X, hw_status=%8X, bufsiz=%d, longsiz=%d\n",
+ cpu_info, hw_status, bufsiz, longsiz);
+#endif
+ /* Get the banner from the booted message */
+ for (i=0; i<banner_length; i++)
+ angel_hostif->writec(angel_hostif->hostosarg,
+ (BUFFERDATA(packet->pk_buffer)+count)[i]);
+
+ booted_not_received=0;
+#ifndef NO_HEARTBEAT
+ heartbeat_enabled = TRUE;
+#endif
+ Armsd_BufferSize = bufsiz + CHAN_HEADER_SIZE;
+ Armsd_LongBufSize = longsiz + CHAN_HEADER_SIZE;
+ } else {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Bad Booted msg: reason=%8X\n", reason);
+#endif
+ }
+ DevSW_FreePacket(packet);
+}
+
+
+/* forward declaration */
+static int angel_negotiate_defaults( void );
+
+/* Open communications. */
+int angel_RDI_open(
+ unsigned type, Dbg_ConfigBlock const *config,
+ Dbg_HostosInterface const *hostif, struct Dbg_MCState *dbg_state)
+{
+ Packet *packet;
+ int status, reasoncode, debugID, OSinfo1, OSinfo2, err;
+ ParameterOptions *user_options = NULL;
+
+ time_t t;
+
+ IGNORE( dbg_state );
+
+ if ((type & 1) == 0) {
+ /* cold start */
+ if (hostif != NULL) {
+ angel_hostif = hostif;
+ err = HostSysInit(hostif, &ardi_commandline, &hstate);
+ if (err != RDIError_NoError) {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: HostSysInit error %i\n",err);
+#endif
+ return err;
+ }
+ }
+ TargetLogInit();
+ }
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Buffer allocated in angel_RDI_open(type=%i).\n",type);
+#endif
+
+ if ((type & 1) == 0) {
+ /* cold start */
+ unsigned endian;
+ Adp_Ioctl( DC_GET_USER_PARAMS, (void *)&user_options );
+ if ( user_options != NULL ) {
+ err = negotiate_params( user_options );
+ if (err != adp_ok) return err;
+ }
+ else {
+ ParameterConfig *default_config = NULL;
+ Adp_Ioctl( DC_GET_DEFAULT_PARAMS, (void *)&default_config );
+ if ( default_config != NULL ) {
+ ParameterOptions *default_options = config_to_options(default_config);
+ err = negotiate_params( default_options );
+ if (err != adp_ok) return err;
+ }
+ }
+
+ /* Register handlers before sending any messages */
+ booted_not_received=1;
+ Adp_ChannelRegisterRead(CI_HBOOT, receive_reset_acknowledge, NULL);
+ Adp_ChannelRegisterRead(CI_TBOOT, receive_booted, NULL);
+ endian = 0;
+ if (config!=NULL) {
+ if (config->bytesex & RDISex_Little) endian |= ADP_BootHostFeature_LittleEnd;
+ if (config->bytesex & RDISex_Big) endian |= ADP_BootHostFeature_BigEnd;
+ }
+ msgsend(CI_HBOOT,"%w%w%w%w%w", ADP_Reset | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, endian);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Transmitted Reset message in angel_RDI_open.\n");
+#endif
+
+ /* We will now either get an acknowledgement for the Reset message
+ * or if the target was started after the host, we will get a
+ * rebooted message first.
+ */
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: waiting for a booted message\n");
+#endif
+
+ {
+ boot_interrupted = FALSE;
+
+ if (late_booted)
+ install_ardi_handler();
+
+ t=time(NULL);
+
+ do {
+ Adp_AsynchronousProcessing(async_block_on_nothing);
+ if ((time(NULL)-t) > ADP_INITIAL_TIMEOUT_PERIOD && !late_booted) {
+ return adp_timeout_on_open;
+ }
+ } while (booted_not_received && !boot_interrupted);
+
+ if (ardi_handler_installed)
+ {
+ /* uninstall our Ctrl-C handler */
+#ifdef __unix
+ sigaction(SIGINT, &old_action, NULL);
+#else
+ signal(SIGINT, old_handler);
+#endif
+ }
+
+ if (boot_interrupted) {
+ angel_negotiate_defaults();
+ return adp_abandon_boot_wait;
+ }
+ }
+
+ booted_not_received=1;
+ Adp_ChannelRegisterRead(CI_HBOOT, NULL, NULL);
+
+ /* Leave the booted handler installed */
+ msgsend(CI_TBOOT, "%w%w%w%w%w", ADP_Booted | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, 0);
+ Adp_initSeq();
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Transmitted ADP_Booted acknowledgement.\n");
+ angel_DebugPrint("DEBUG: Boot sequence completed, leaving angel_RDI_open.\n");
+#endif
+
+ return (hw_status & ADP_CPU_BigEndian )? RDIError_BigEndian :
+ RDIError_LittleEndian;
+ }
+ else {
+ /* warm start */
+ register_debug_message_handler();
+
+ msgsend(CI_HADP, "%w%w%w%w",
+ ADP_InitialiseApplication | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Transmitted Initialise Application\n");
+#endif
+ reasoncode=ADP_InitialiseApplication | TtoH;
+ err = wait_for_debug_message(&reasoncode, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) return err;
+ return status;
+ }
+ return -1;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_close----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+static int angel_negotiate_defaults( void ) {
+ int err = adp_ok;
+ ParameterConfig *default_config = NULL;
+ Adp_Ioctl( DC_GET_DEFAULT_PARAMS, (void *)&default_config );
+ if ( default_config != NULL ) {
+ ParameterOptions *default_options = config_to_options(default_config);
+ err = negotiate_params( default_options );
+ free( default_options );
+ }
+ return err;
+}
+
+int angel_RDI_close(void) {
+/*Angel host exit */
+ int err;
+ int status,debugID, OSinfo1,OSinfo2;
+ int reason;
+ Packet *packet = NULL;;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_Close.\n");
+#endif
+
+ register_debug_message_handler();
+
+ heartbeat_enabled = FALSE;
+
+ err = msgsend(CI_HADP,"%w%w%w%w",ADP_End | HtoT,0,
+ ADP_HandleUnknown, ADP_HandleUnknown);
+ if (err != RDIError_NoError) return err;
+ reason = ADP_End | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ DevSW_FreePacket(packet);
+ if (err != RDIError_NoError) return err;
+ if (status == RDIError_NoError) {
+ err = angel_negotiate_defaults();
+ if (err != adp_ok) return err;
+ Adp_Ioctl( DC_RESET, NULL ); /* just to be safe */
+ return HostSysExit(hstate);
+ }
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_read-----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Read memory contents from target to host: use ADP_Read */
+int angel_RDI_read(ARMword source, void *dest, unsigned *nbytes)
+{
+ Packet *packet=NULL;
+ int len; /* Integer to hold message length. */
+ unsigned int nbtogo = *nbytes, nbinpacket, nbdone=0;
+ int rnbytes = 0, status, reason, debugID, OSinfo1, OSinfo2, err;
+ unsigned int maxlen = Armsd_BufferSize-CHAN_HEADER_SIZE-ADP_ReadHeaderSize;
+
+ /* Print debug trace information, this is just copied straight from rdi.c
+ and I can see no reason why it should have to be changed. */
+ TracePrint(("angel_RDI_read: source=%.8lx dest=%p nbytes=%.8x\n",
+ (unsigned long)source, dest, *nbytes));
+ if (*nbytes == 0) return RDIError_NoError; /* Read nothing - easy! */
+ /* check the buffer size */
+ while (nbtogo >0) {
+ register_debug_message_handler();
+
+ nbinpacket = (nbtogo <= maxlen) ? nbtogo : maxlen;
+ len = msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Read | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, source+nbdone,
+ nbinpacket);
+ reason=ADP_Read | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ TracePrint(("angel_RDI_read: nbinpacket =%d status=%08x err = %d\n",
+ nbinpacket,status,err));
+ if (err != RDIError_NoError) return err; /* Was there an error? */
+ if (status == RDIError_NoError){
+ rnbytes += PREAD(LE,(unsigned int *)(BUFFERDATA(packet->pk_buffer)+20));
+ TracePrint(("angel_RDI_read: rnbytes = %d\n",rnbytes));
+ memcpy(((unsigned char *)dest)+nbdone, BUFFERDATA(packet->pk_buffer)+24,
+ nbinpacket);
+ }
+ nbdone += nbinpacket;
+ nbtogo -= nbinpacket;
+ }
+ *nbytes -= rnbytes;
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_write----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Transfer memory block from host to target. Use ADP_Write>. */
+int angel_RDI_write(const void *source, ARMword dest, unsigned *nbytes)
+{
+ Packet *packet;/* Message buffers. */
+ unsigned int len, nbtogo = *nbytes, nboffset = 0, nbinpacket;
+ int status, reason, debugID, OSinfo1, OSinfo2, err;
+ unsigned int maxlen = Armsd_LongBufSize-CHAN_HEADER_SIZE-ADP_WriteHeaderSize;
+
+ TracePrint(("angel_RDI_write: source=%p dest=%.8lx nbytes=%.8x\n",
+ source, (unsigned long)dest, *nbytes));
+
+ if (*nbytes == 0) return RDIError_NoError;
+
+ *nbytes = 0;
+ while (nbtogo > 0) {
+ packet = (Packet *) DevSW_AllocatePacket(Armsd_LongBufSize);
+ nbinpacket = (nbtogo <= maxlen) ? nbtogo : maxlen;
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w",
+ ADP_Write | HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, dest+nboffset, nbinpacket);
+ /* Copy the data into the packet. */
+
+ memcpy(BUFFERDATA(packet->pk_buffer)+len,
+ ((const unsigned char *) source)+nboffset, nbinpacket);
+ nboffset += nbinpacket;
+ packet->pk_length = nbinpacket+len;
+
+#ifdef MONITOR_DOWNLOAD_PACKETS
+ angel_DebugPrint("angel_RDI_write packet size=%i, bytes done=%i\n",
+ nbinpacket, nboffset);
+#endif
+
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason=ADP_Write | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ nbtogo -= nbinpacket;
+ if (err != RDIError_NoError) return err;
+ if (status == RDIError_NoError)
+ *nbytes += nbinpacket;
+
+ DevSW_FreePacket(packet);
+ }
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_CPUread--------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Reads the values of registers in the CPU, uses ADP_CPUwrite. */
+int angel_RDI_CPUread(unsigned mode, unsigned long mask, ARMword *buffer)
+{
+ unsigned int i, j;
+ Packet *packet = NULL;
+ int err, status, reason, debugID, OSinfo1, OSinfo2;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_CPUread.\n");
+#endif
+ for (i=0, j=0 ; i < RDINumCPURegs ; i++)
+ if (mask & (1L << i)) j++; /* Count the number of registers. */
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%c%w", ADP_CPUread | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, mode, mask);
+ reason = ADP_CPUread | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ if(status == RDIError_NoError) {
+ for (i=0; i<j; i++)
+ buffer[i] = GET32LE(BUFFERDATA(packet->pk_buffer)+20+(i*4));
+ TracePrint(("angel_RDI_CPUread: mode=%.8x mask=%.8lx", mode, mask));
+ DevSW_FreePacket(packet);
+#ifdef RDI_VERBOSE
+ if (rdi_log & 1) {
+ unsigned k;
+ for (k = 0, j = 0 ; j <= 20 ; j++)
+ if (mask & (1L << j)) {
+ angel_DebugPrint("%c%.8lx",k%4==0?'\n':' ',
+ (unsigned long)buffer[k]);
+ k++ ;
+ }
+ angel_DebugPrint("\n") ;
+ }
+#endif
+
+ }
+ return status;
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_CPUwrite-------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Write CPU registers: use ADP_CPUwrite. */
+int angel_RDI_CPUwrite(unsigned mode, unsigned long mask,
+ ARMword const *buffer){
+
+ unsigned i, j, c;
+ Packet *packet;
+ int status, reason, debugID, OSinfo1, OSinfo2, err, len;
+
+ TracePrint(("angel_RDI_CPUwrite: mode=%.8x mask=%.8lx", mode, mask));
+#ifdef RDI_VERBOSE
+ if (rdi_log & 1) {
+ for (j = 0, i = 0 ; i <= 20 ; i++)
+ if (mask & (1L << i)) {
+ angel_DebugPrint("%c%.8lx",j%4==0?'\n':' ',
+ (unsigned long)buffer[j]);
+ j++ ;
+ }
+ angel_DebugPrint("\n") ;
+ }
+#endif
+ packet = (Packet *)DevSW_AllocatePacket(Armsd_BufferSize);
+ for (i=0, j=0; i < RDINumCPURegs ; i++)
+ if (mask & (1L << i)) j++; /* count the number of registers */
+
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%b%w",
+ ADP_CPUwrite | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, mode, mask);
+ for(c=0; c<j; c++)
+ PUT32LE(BUFFERDATA(packet->pk_buffer)+len+(c*4), buffer[c]);
+ packet->pk_length = len+(j*4);
+ register_debug_message_handler();
+
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason = ADP_CPUwrite | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &status);
+ DevSW_FreePacket(packet);
+ if (err != RDIError_NoError)
+ return err; /* Was there an error? */
+ else
+ return status;
+ }
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_CPread---------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Read coprocessor's internal state. See dbg_cp.h for help.
+ * Use ADP_CPRead.
+ * It would appear that the correct behaviour at this point is to leave
+ * the unpacking to a the caller and to simply copy the stream of data
+ * words into the buffer
+ */
+
+int angel_RDI_CPread(unsigned CPnum, unsigned long mask, ARMword *buffer){
+ Packet *packet = NULL;
+ int i, j, status, reasoncode, OSinfo1, OSinfo2, err, debugID;
+ unsigned char *rmap = cpwords[CPnum];
+ int n;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_CPread.\n");
+#endif
+ if (rmap == NULL) return RDIError_UnknownCoPro;
+
+ register_debug_message_handler();
+ n = rmap[-1];
+ msgsend(CI_HADP, "%w%w%w%w%b%w", ADP_CPread | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, CPnum, mask);
+ reasoncode=ADP_CPread | TtoH;
+ err = wait_for_debug_message(&reasoncode, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ for (j=i=0; i < n ; i++) /* count the number of registers */
+ if (mask & (1L << i)) {
+ j++;
+ }
+ for (i=0; i<j; i++)
+ buffer[i] = PREAD32(LE, BUFFERDATA(packet->pk_buffer) + 20 + (i*4));
+ DevSW_FreePacket(packet);
+ TracePrint(("angel_RDI_CPread: CPnum=%.8x mask=%.8lx\n", CPnum, mask));
+#ifdef RDI_VERBOSE
+ if (rdi_log & 1) {
+ for (i = 0, j = 0; j < n ; j++) {
+ if (mask & (1L << j)) {
+ int nw = rmap[j];
+ angel_DebugPrint("%2d ", j);
+ while (--nw > 0)
+ angel_DebugPrint("%.8lx ", (unsigned long)buffer[i++]);
+ angel_DebugPrint("%.8lx\n", (unsigned long)buffer[i++]);
+ }
+ }
+ }
+#endif
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_CPwrite--------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Write coprocessor's internal state. See dbg_cp.h for help. Use
+ * ADP_CPwrite.
+ */
+
+int angel_RDI_CPwrite(unsigned CPnum, unsigned long mask,
+ ARMword const *buffer)
+{
+ Packet *packet = NULL;
+ int i, j, len, status, reason, OSinfo1, OSinfo2, err, debugID;
+ unsigned char *rmap = cpwords[CPnum];
+ int n;
+
+ if (rmap == NULL) return RDIError_UnknownCoPro;
+ n = rmap[-1];
+
+ TracePrint(("angel_RDI_CPwrite: CPnum=%d mask=%.8lx\n", CPnum, mask));
+
+#ifdef RDI_VERBOSE
+ if (rdi_log & 1) {
+ for (i = 0, j = 0; j < n ; j++)
+ if (mask & (1L << j)) {
+ int nw = rmap[j];
+ angel_DebugPrint("%2d ", j);
+ while (--nw > 0)
+ angel_DebugPrint("%.8lx ", (unsigned long)buffer[i++]);
+ angel_DebugPrint("%.8lx\n", (unsigned long)buffer[i++]);
+ }
+ }
+#endif
+
+ for (j=i=0; i < n ; i++) /* Count the number of registers. */
+ if (mask & (1L << i)) j++;
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%c%w",
+ ADP_CPwrite | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, CPnum, mask);
+ for(i=0; i<j; i++)
+ len+=msgbuild(BUFFERDATA(packet->pk_buffer) + len, "%w", buffer[i]);
+ packet->pk_length = len;
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet); /* Transmit message. */
+ reason=ADP_CPwrite | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ DevSW_FreePacket(packet);
+ if (err != RDIError_NoError)
+ return err;
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_pointinq-------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Do test calls to ADP_SetBreak/ADP_SetWatch to see if resources exist to
+ carry out request. */
+int angel_RDI_pointinq(ARMword *address, unsigned type, unsigned datatype,
+ ARMword *bound)
+{
+ Packet *packet = NULL;
+ int len, status, reason, OSinfo1, OSinfo2, err=RDIError_NoError;
+ /* stop a compiler warning */
+ int debugID, pointhandle;
+ TracePrint(
+ ("angel_RDI_pointinq: address=%.8lx type=%d datatype=%d bound=%.8lx ",
+ (unsigned long)*address, type, datatype, (unsigned long)*bound));
+ /* for a buffer. */
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%b",
+ ((datatype == 0) ? ADP_SetBreak : ADP_SetWatch) | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, address, type);
+ if (datatype == 0)
+ len += msgbuild(BUFFERDATA(packet->pk_buffer) + 21, "%w", bound);
+ else
+ len += msgbuild(BUFFERDATA(packet->pk_buffer) + 21, "%b%w", datatype, bound);
+
+ register_debug_message_handler();
+ packet->pk_length = len;
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason = ((datatype == 0) ? ADP_SetBreak : ADP_SetWatch | TtoH);
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2, &status,
+ &pointhandle, &address, &bound);
+ DevSW_FreePacket(packet);
+ return err;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_setbreak-------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Set a breakpoint: Use ADP_SetBreak */
+int angel_RDI_setbreak(ARMword address, unsigned type, ARMword bound,
+ PointHandle *handle)
+{
+ int status, reason, OSinfo1, OSinfo2, err, debugID;
+ int tmpval, tmpaddr, tmpbnd;
+ Packet *packet;
+ TracePrint(("angel_RDI_setbreak address=%.8lx type=%d bound=%.8lx \n",
+ (unsigned long)address, type, (unsigned long)bound));
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%b%w",
+ ADP_SetBreak| HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, address, type, bound);
+ reason = ADP_SetBreak |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ /* Work around varargs problem... -sts */
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2, &status,
+ &tmpval, &tmpaddr, &tmpbnd);
+ *handle = tmpval;
+ address = tmpaddr;
+ bound = tmpbnd;
+ DevSW_FreePacket(packet);
+ if (status != RDIError_NoError) return status;
+ TracePrint(("returns handle %.8lx\n", (unsigned long)*handle));
+ return RDIError_NoError;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_clearbreak-----------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Clear a breakpoint: Use ADP_ClearBreak. */
+int angel_RDI_clearbreak(PointHandle handle)
+{
+ Packet *packet = NULL;
+ int status, reason, OSinfo1, OSinfo2, err, debugID;
+
+ TracePrint(("angel_RDI_clearbreak: handle=%.8lx\n", (unsigned long)handle));
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w",
+ ADP_ClearBreak| HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, handle);
+ reason = ADP_ClearBreak|TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ angel_DebugPrint("***RECEIVE DEBUG MESSAGE RETURNED ERR = %d.\n", err);
+ return err; /* Was there an error? */
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &status);
+ DevSW_FreePacket(packet);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Clear Break completed OK.\n");
+#endif
+ return RDIError_NoError;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_setwatch-------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Set a watchpoint: use ADP_SetWatch. */
+int angel_RDI_setwatch(ARMword address, unsigned type, unsigned datatype,
+ ARMword bound, PointHandle *handle)
+{
+ Packet *packet = NULL;
+ int status, reason, OSinfo1, OSinfo2, err, debugID;
+
+ TracePrint(("angel_RDI_setwatch: address=%.8lx type=%d bound=%.8lx ",
+ (unsigned long)address, type, (unsigned long)bound));
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%b%b%w",
+ ADP_SetWatch| HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, address, type, datatype, bound);
+
+ reason = ADP_SetWatch | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2, &status,
+ handle, &address, &bound);
+ DevSW_FreePacket(packet);
+ TracePrint(("returns handle %.8lx\n", (unsigned long)*handle));
+ return RDIError_NoError;
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_clearwatch-----------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Clear a watchpoint: use ADP_ClearWatch. */
+int angel_RDI_clearwatch(PointHandle handle) {
+
+ int status, reason, OSinfo1, OSinfo2, err, debugID;
+ Packet *packet = NULL;
+
+ TracePrint(("angel_RDI_clearwatch: handle=%.8lx\n", (unsigned long)handle));
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w",
+ ADP_ClearWatch| HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, handle);
+ reason = ADP_ClearWatch|TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &status);
+ DevSW_FreePacket(packet);
+ return RDIError_NoError;
+}
+
+typedef struct {
+ unsigned stopped_reason;
+ int stopped_status;
+ int data;
+} adp_stopped_struct;
+
+
+int angel_RDI_OnTargetStopping(angel_RDI_TargetStoppedProc *fn,
+ void *arg)
+{
+ stoppedProcListElement **lptr = &stopped_proc_list;
+
+ /* Find the address of the NULL ptr at the end of the list */
+ for (; *lptr!=NULL ; lptr = &((*lptr)->next))
+ ; /* Do nothing */
+
+ *lptr = (stoppedProcListElement *) malloc(sizeof(stoppedProcListElement));
+ if (*lptr == NULL) return RDIError_OutOfStore;
+ (*lptr)->fn = fn;
+ (*lptr)->arg = arg;
+
+ return RDIError_NoError;
+}
+
+static int CallStoppedProcs(unsigned reason)
+{
+ stoppedProcListElement *p = stopped_proc_list;
+ int err=RDIError_NoError;
+
+ for (; p!=NULL ; p=p->next) {
+ int local_err = p->fn(reason, p->arg);
+ if (local_err != RDIError_NoError) err=local_err;
+ }
+
+ return err;
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_execute--------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+static int HandleStoppedMessage(Packet *packet, void *stateptr) {
+ unsigned int err, reason, debugID, OSinfo1, OSinfo2, count;
+ adp_stopped_struct *stopped_info;
+ stopped_info = (adp_stopped_struct *) stateptr;
+ IGNORE(stateptr);
+ count = unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w",
+ &reason, &debugID,
+ &OSinfo1, &OSinfo2,
+ &stopped_info->stopped_reason, &stopped_info->data);
+ DevSW_FreePacket(packet);
+
+ if (reason != (ADP_Stopped | TtoH)) {
+#ifdef DEBUG
+ angel_DebugPrint("Expecting stopped message, got %x", reason);
+#endif
+ return RDIError_Error;
+ }
+ else {
+ executing = FALSE;
+#ifdef DEBUG
+ angel_DebugPrint("Received stopped message.\n");
+#endif
+ }
+
+ err = msgsend(CI_TADP, "%w%w%w%w%w", (ADP_Stopped | HtoT), 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, RDIError_NoError);
+#ifdef DEBUG
+ angel_DebugPrint("Transmiting stopped acknowledge.\n");
+#endif
+ if (err != RDIError_NoError) angel_DebugPrint("Transmit failed.\n");
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Stopped reason : %x\n", stopped_info->stopped_reason);
+#endif
+ switch (stopped_info->stopped_reason) {
+ case ADP_Stopped_BranchThroughZero:
+ stopped_info->stopped_status = RDIError_BranchThrough0;
+ break;
+ case ADP_Stopped_UndefinedInstr:
+ stopped_info->stopped_status = RDIError_UndefinedInstruction;
+ break;
+ case ADP_Stopped_SoftwareInterrupt:
+ stopped_info->stopped_status = RDIError_SoftwareInterrupt;
+ break;
+ case ADP_Stopped_PrefetchAbort:
+ stopped_info->stopped_status = RDIError_PrefetchAbort;
+ break;
+ case ADP_Stopped_DataAbort:
+ stopped_info->stopped_status = RDIError_DataAbort;
+ break;
+ case ADP_Stopped_AddressException:
+ stopped_info->stopped_status = RDIError_AddressException;
+ break;
+ case ADP_Stopped_IRQ:
+ stopped_info->stopped_status = RDIError_IRQ;
+ break;
+ case ADP_Stopped_BreakPoint:
+ stopped_info->stopped_status = RDIError_BreakpointReached;
+ break;
+ case ADP_Stopped_WatchPoint:
+ stopped_info->stopped_status = RDIError_WatchpointAccessed;
+ break;
+ case ADP_Stopped_StepComplete:
+ stopped_info->stopped_status = RDIError_ProgramFinishedInStep;
+ break;
+ case ADP_Stopped_RunTimeErrorUnknown:
+ case ADP_Stopped_StackOverflow:
+ case ADP_Stopped_DivisionByZero:
+ stopped_info->stopped_status = RDIError_Error;
+ break;
+ case ADP_Stopped_FIQ:
+ stopped_info->stopped_status = RDIError_FIQ;
+ break;
+ case ADP_Stopped_UserInterruption:
+ case ADP_Stopped_OSSpecific:
+ stopped_info->stopped_status = RDIError_UserInterrupt;
+ break;
+ case ADP_Stopped_ApplicationExit:
+ stopped_info->stopped_status = RDIError_NoError;
+ break;
+ default:
+ stopped_info->stopped_status = RDIError_Error;
+ break;
+ }
+ return RDIError_NoError;
+}
+
+
+static void interrupt_target( void )
+{
+ Packet *packet = NULL;
+ int err;
+ int reason, debugID, OSinfo1, OSinfo2, status;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: interrupt_target.\n");
+#endif
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w", ADP_InterruptRequest | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown);
+
+ reason = ADP_InterruptRequest |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ DevSW_FreePacket(packet);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: got interrupt ack ok err = %d, status=%i\n",
+ err, status);
+#endif
+
+ return;
+}
+
+#ifdef TEST_DC_APPL
+ extern void test_dc_appl_handler( const DeviceDescr *device,
+ Packet *packet );
+#endif
+
+void angel_RDI_stop_request(void)
+{
+ stop_request = 1;
+}
+
+/* Core functionality for execute and step */
+static int angel_RDI_ExecuteOrStep(PointHandle *handle, word type,
+ unsigned ninstr)
+{
+ extern int (*ui_loop_hook) (int);
+ int err;
+ adp_stopped_struct stopped_info;
+ void* stateptr = (void *)&stopped_info;
+ ChannelCallback HandleStoppedMessageFPtr=(ChannelCallback) HandleStoppedMessage;
+ int status, reasoncode, debugID, OSinfo1, OSinfo2;
+ Packet *packet = NULL;
+
+ TracePrint(("angel_RDI_ExecuteOrStep\n"));
+
+ err = Adp_ChannelRegisterRead(CI_TADP,
+ HandleStoppedMessageFPtr, stateptr);
+ if (err != RDIError_NoError) {
+#ifdef DEBUG
+ angel_DebugPrint("TADP Register failed.\n");
+#endif
+ return err;
+ }
+ /* Set executing TRUE here, as it must be set up before the target has
+ * had any chance at all to execute, or it may send its stopped message
+ * before we get round to setting executing = TRUE !!!
+ */
+ executing = TRUE;
+
+ register_debug_message_handler();
+
+#ifdef TEST_DC_APPL
+ Adp_Install_DC_Appl_Handler( test_dc_appl_handler );
+#endif
+
+#ifdef DEBUG
+ angel_DebugPrint("Transmiting %s message.\n",
+ type == ADP_Execute ? "execute": "step");
+#endif
+
+ register_debug_message_handler();
+ /* Extra ninstr parameter for execute message will simply be ignored */
+ err = msgsend(CI_HADP,"%w%w%w%w%w", type | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, ninstr);
+#if DEBUG
+ if (err != RDIError_NoError) angel_DebugPrint("Transmit failed.\n");
+#endif
+
+ reasoncode = type | TtoH;
+ err = wait_for_debug_message( &reasoncode, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet );
+ if (err != RDIError_NoError)
+ return err;
+ else if (status != RDIError_NoError)
+ return status;
+
+#ifdef DEBUG
+ angel_DebugPrint("Waiting for program to finish...\n");
+#endif
+
+ interrupt_request = FALSE;
+ stop_request = FALSE;
+
+ signal(SIGINT, ardi_sigint_handler);
+ while( executing )
+ {
+ if (ui_loop_hook)
+ ui_loop_hook(0);
+
+ if (interrupt_request || stop_request)
+ {
+ interrupt_target();
+ interrupt_request = FALSE;
+ stop_request = FALSE;
+ }
+ Adp_AsynchronousProcessing( async_block_on_nothing );
+ }
+ signal(SIGINT, SIG_IGN);
+
+
+#ifdef TEST_DC_APPL
+ Adp_Install_DC_Appl_Handler( NULL );
+#endif
+
+ (void)Adp_ChannelRegisterRead(CI_TADP, NULL, NULL);
+
+ *handle = (PointHandle)stopped_info.data;
+
+ CallStoppedProcs(stopped_info.stopped_reason);
+
+ return stopped_info.stopped_status;
+}
+
+/* Request that the target starts executing from the stored CPU state: use
+ ADP_Execute. */
+int angel_RDI_execute(PointHandle *handle)
+{
+ return angel_RDI_ExecuteOrStep(handle, ADP_Execute, 0);
+}
+
+#ifdef __WATCOMC__
+typedef void handlertype(int);
+
+static int interrupted=0;
+
+static void myhandler(int sig) {
+ IGNORE(sig);
+ interrupted=1;
+ signal(SIGINT, myhandler);
+}
+#endif
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_step-----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Step 'ninstr' through the code: use ADP_Step. */
+int angel_RDI_step(unsigned ninstr, PointHandle *handle)
+{
+ int err = angel_RDI_ExecuteOrStep(handle, ADP_Step, ninstr);
+ if (err == RDIError_ProgramFinishedInStep)
+ return RDIError_NoError;
+ else
+ return err;
+}
+
+
+static void SetCPWords(int cpnum, struct Dbg_CoProDesc const *cpd) {
+ int i, rmax = 0;
+ for (i = 0; i < cpd->entries; i++)
+ if (cpd->regdesc[i].rmax > rmax)
+ rmax = cpd->regdesc[i].rmax;
+
+ { unsigned char *rmap = (unsigned char *)malloc(rmax + 2);
+ *rmap++ = rmax + 1;
+ for (i = 0; i < cpd->entries; i++) {
+ int r;
+ for (r = cpd->regdesc[i].rmin; r <= cpd->regdesc[i].rmax; r++)
+ rmap[r] = (cpd->regdesc[i].nbytes+3) / 4;
+ }
+/* if (cpwords[cpnum] != NULL) free(cpwords[cpnum]); */
+ cpwords[cpnum] = rmap;
+ }
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_info-----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Use ADP_Info, ADP_Ctrl and ADP_Profile calls to implement these,
+ see adp.h for more details. */
+
+static int angel_cc_exists( void )
+{
+ Packet *packet = NULL;
+ int err;
+ int reason, debugID, OSinfo1, OSinfo2, subreason, status;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_CC_Exists.\n");
+#endif
+
+ if ( angel_RDI_info( RDIInfo_Icebreaker, NULL, NULL ) == RDIError_NoError ) {
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", ADP_ICEbreakerHADP | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEB_CC_Exists );
+ reason = ADP_ICEbreakerHADP |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ if (subreason != ADP_ICEB_CC_Exists) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else
+ return status;
+ }
+ else
+ return RDIError_UnimplementedMessage;
+}
+
+typedef struct {
+ RDICCProc_ToHost *tohost; void *tohostarg;
+ RDICCProc_FromHost *fromhost; void *fromhostarg;
+ bool registered;
+} CCState;
+static CCState ccstate = { NULL, NULL, NULL, NULL, FALSE };
+
+static void HandleDCCMessage( Packet *packet, void *stateptr )
+{
+ unsigned int reason, debugID, OSinfo1, OSinfo2;
+ int count;
+ CCState *ccstate_p = (CCState *)stateptr;
+
+ count = unpack_message( BUFFERDATA(packet->pk_buffer), "%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2 );
+ switch ( reason )
+ {
+ case ADP_TDCC_ToHost | TtoH:
+ {
+ /* only handles a single word of data, for now */
+
+ unsigned int nbytes, data;
+
+ unpack_message( BUFFERDATA(packet->pk_buffer)+count, "%w%w",
+ &nbytes, &data );
+#ifdef DEBUG
+ angel_DebugPrint( "DEBUG: received CC_ToHost message: nbytes %d data %08x.\n",
+ nbytes, data );
+#endif
+ ccstate_p->tohost( ccstate_p->tohostarg, data );
+ msgsend(CI_TTDCC, "%w%w%w%w%w",
+ ADP_TDCC_ToHost | HtoT, debugID, OSinfo1, OSinfo2,
+ RDIError_NoError );
+ break;
+ }
+
+ case ADP_TDCC_FromHost | TtoH:
+ {
+ /* only handles a single word of data, for now */
+
+ int valid;
+ ARMword data;
+
+ ccstate_p->fromhost( ccstate_p->fromhostarg, &data, &valid );
+#ifdef DEBUG
+ angel_DebugPrint( "DEBUG: received CC_FromHost message, returning: %08x %s.\n",
+ data, valid ? "VALID" : "INvalid" );
+#endif
+ msgsend(CI_TTDCC, "%w%w%w%w%w%w%w",
+ ADP_TDCC_FromHost | HtoT, debugID, OSinfo1, OSinfo2,
+ RDIError_NoError, valid ? 1 : 0, data );
+ break;
+ }
+
+ default:
+#ifdef DEBUG
+ angel_DebugPrint( "Unexpected TDCC message %08x received\n", reason );
+#endif
+ break;
+ }
+ DevSW_FreePacket(packet);
+ return;
+}
+
+static void angel_check_DCC_handler( CCState *ccstate_p )
+{
+ int err;
+
+ if ( ccstate_p->tohost != NULL || ccstate_p->fromhost != NULL )
+ {
+ /* doing DCC, so need a handler */
+ if ( ! ccstate_p->registered )
+ {
+#ifdef DEBUG
+ angel_DebugPrint( "Registering handler for TTDCC channel.\n" );
+#endif
+ err = Adp_ChannelRegisterRead( CI_TTDCC, HandleDCCMessage,
+ ccstate_p );
+ if ( err == adp_ok )
+ ccstate_p->registered = TRUE;
+#ifdef DEBUG
+ else
+ angel_DebugPrint( "angel_check_DCC_handler: register failed!\n" );
+#endif
+ }
+ }
+ else
+ {
+ /* not doing DCC, so don't need a handler */
+ if ( ccstate_p->registered )
+ {
+#ifdef DEBUG
+ angel_DebugPrint( "Unregistering handler for TTDCC channel.\n" );
+#endif
+ err = Adp_ChannelRegisterRead( CI_TTDCC, NULL, NULL );
+ if ( err == adp_ok )
+ ccstate_p->registered = FALSE;
+#ifdef DEBUG
+ else
+ angel_DebugPrint( "angel_check_DCC_handler: unregister failed!\n" );
+#endif
+ }
+ }
+}
+
+
+static int CheckSubMessageReply(int reason, int subreason) {
+ Packet *packet = NULL;
+ int status, debugID, OSinfo1, OSinfo2;
+ int err = RDIError_NoError;
+ reason |= TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ status = err;
+ } else {
+ int sr;
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &sr, &status);
+ if (subreason != sr) status = RDIError_Error;
+ }
+ DevSW_FreePacket(packet);
+ return status;
+}
+
+static int SendSubMessageAndCheckReply(int reason, int subreason) {
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", reason | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ subreason);
+ return CheckSubMessageReply(reason, subreason);
+}
+
+static int SendSubMessageWordAndCheckReply(int reason, int subreason, ARMword word) {
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", reason | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ subreason, word);
+ return CheckSubMessageReply(reason, subreason);
+}
+
+static int SendSubMessageGetWordAndCheckReply(int reason, int subreason, ARMword *resp) {
+ Packet *packet = NULL;
+ int status, debugID, OSinfo1, OSinfo2;
+ int err = RDIError_NoError;
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", reason | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ subreason);
+ reason |= TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ status = err;
+ } else {
+ int sr;
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &sr, &status, resp);
+ if (subreason != sr) status = RDIError_Error;
+ }
+ DevSW_FreePacket(packet);
+ return status;
+}
+
+static int const hostsex = 1;
+
+int angel_RDI_info(unsigned type, ARMword *arg1, ARMword *arg2) {
+ Packet *packet = NULL;
+ int len, status, c, reason, subreason, debugID, OSinfo1, OSinfo2;
+ int err=RDIError_NoError, cpnum=0;
+ struct Dbg_CoProDesc *cpd;
+ int count, i;
+ unsigned char *bp;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_info.\n");
+#endif
+ switch (type) {
+ case RDIInfo_Target:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_Target.\n");
+#endif
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, ADP_Info_Target);
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status,
+ arg1, arg2);
+ DevSW_FreePacket(packet);
+
+ if (subreason != ADP_Info_Target)
+ return RDIError_Error;
+ else
+ return status;
+
+ case RDISignal_Stop:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDISignal_Stop.\n");
+ if (interrupt_request)
+ angel_DebugPrint(" STILL WAITING to send previous interrupt request\n");
+#endif
+ interrupt_request = TRUE;
+ return RDIError_NoError;
+
+ case RDIInfo_Points:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_Points.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Info, ADP_Info_Points, arg1);
+
+ case RDIInfo_Step:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_Step.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Info, ADP_Info_Step, arg1);
+
+ case RDISet_Cmdline:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDISet_Cmdline.\n");
+#endif
+ if (ardi_commandline != &dummycline)
+ free(ardi_commandline);
+ ardi_commandline = (char *)malloc(strlen((char*)arg1) + 1) ;
+ (void)strcpy(ardi_commandline, (char *)arg1) ;
+ return RDIError_NoError;
+
+ case RDIInfo_SetLog:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_SetLog.\n");
+#endif
+ rdi_log = (int) *arg1;
+ return RDIError_NoError;
+
+ case RDIInfo_Log:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_Log.\n");
+#endif
+ *arg1 = rdi_log;
+ return RDIError_NoError;
+
+
+ case RDIInfo_MMU:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_MMU.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Info, ADP_Info_MMU, arg1);
+
+ case RDIInfo_SemiHosting:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_SemiHosting.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_SemiHosting);
+
+ case RDIInfo_CoPro:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_CoPro.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_CoPro);
+
+ case RDICycles:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDICycles.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, ADP_Info_Cycles);
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if (subreason != ADP_Info_Cycles)
+ return RDIError_Error;
+ if (status != RDIError_NoError) return status;
+ for (c=0; c<12; c++)
+ arg1[c]=GET32LE(BUFFERDATA(packet->pk_buffer)+24+(c*4));
+ return status;
+
+ case RDIInfo_DescribeCoPro:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_DescribeCoPro.\n");
+#endif
+ cpnum = *(int *)arg1;
+ cpd = (struct Dbg_CoProDesc *)arg2;
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ if (angel_RDI_info(ADP_Info_CoPro, NULL, NULL) != RDIError_NoError)
+ return RDIError_Error;
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Info_DescribeCoPro);
+ len +=msgbuild(BUFFERDATA(packet->pk_buffer)+20, "%b%b%b%b%b", cpnum,
+ cpd->regdesc[cpnum].rmin, cpd->regdesc[cpnum].rmax,
+ cpd->regdesc[cpnum].nbytes, cpd->regdesc[cpnum].access);
+ if (cpd->regdesc[cpnum].access&0x3 == 0x3){
+ len += msgbuild(BUFFERDATA(packet->pk_buffer)+25, "%b%b%b%b%b",
+ cpd->regdesc[cpnum].accessinst.cprt.read_b0,
+ cpd->regdesc[cpnum].accessinst.cprt.read_b1,
+ cpd->regdesc[cpnum].accessinst.cprt.write_b0,
+ cpd->regdesc[cpnum].accessinst.cprt.write_b1, 0xff);
+ }
+ else {
+ len += msgbuild(BUFFERDATA(packet->pk_buffer)+25, "%b%b%b%b%b%",
+ cpd->regdesc[cpnum].accessinst.cpdt.rdbits,
+ cpd->regdesc[cpnum].accessinst.cpdt.nbit,0,0, 0xff);
+ }
+ register_debug_message_handler();
+ packet->pk_length = len;
+ Adp_ChannelWrite(CI_HADP, packet); /* Transmit message. */
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if (subreason != ADP_Info_DescribeCoPro)
+ return RDIError_Error;
+ else
+ return status;
+
+ case RDIInfo_RequestCoProDesc:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_RequestCoProDesc.\n");
+#endif
+ cpnum = *(int *)arg1;
+ cpd = (struct Dbg_CoProDesc *)arg2;
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Info_RequestCoProDesc);
+ len += msgbuild(BUFFERDATA(packet->pk_buffer)+20, "%b", *(int *)arg1);
+ packet->pk_length = len;
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet); /* Transmit message. */
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ count = unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ if (subreason != ADP_Info_RequestCoProDesc) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ } else if ( status != RDIError_NoError ) {
+ DevSW_FreePacket(packet);
+ return status;
+ } else {
+ bp = BUFFERDATA(packet->pk_buffer)+count;
+ for ( i = 0; *bp != 0xFF && i < cpd->entries; ++i ) {
+ cpd->regdesc[i].rmin = *bp++;
+ cpd->regdesc[i].rmax = *bp++;
+ cpd->regdesc[i].nbytes = *bp++;
+ cpd->regdesc[i].access = *bp++;
+ }
+ cpd->entries = i;
+ if ( *bp != 0xFF )
+ status = RDIError_BufferFull;
+ else
+ SetCPWords( cpnum, cpd );
+ DevSW_FreePacket(packet);
+ return status;
+ }
+
+ case RDIInfo_GetLoadSize:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Info_AngelBufferSize.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Info_AngelBufferSize);
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ if (subreason != ADP_Info_AngelBufferSize) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else {
+ word defaultsize, longsize;
+ unpack_message(BUFFERDATA(packet->pk_buffer)+24, "%w%w",
+ &defaultsize, &longsize);
+ *arg1 = longsize - ADP_WriteHeaderSize; /* space for ADP header */
+#ifdef MONITOR_DOWNLOAD_PACKETS
+ angel_DebugPrint("DEBUG: ADP_Info_AngelBufferSize: got (%d, %d), returning %d.\n",
+ defaultsize, longsize, *arg1);
+#endif
+ DevSW_FreePacket(packet);
+ return status;
+ }
+
+ case RDIVector_Catch:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_VectorCatch %lx.\n", *arg1);
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_VectorCatch, *arg1);
+
+ case RDISemiHosting_SetState:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetState %lx.\n", *arg1);
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetState, *arg1);
+
+ case RDISemiHosting_GetState:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetState.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetState, arg1);
+
+ case RDISemiHosting_SetVector:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetVector %lx.\n", *arg1);
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetVector, *arg1);
+
+ case RDISemiHosting_GetVector:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetVector.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetVector, arg1);
+
+ case RDISemiHosting_SetARMSWI:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetARMSWI.\n");
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetARMSWI, *arg1);
+
+ case RDISemiHosting_GetARMSWI:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetARMSWI.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetARMSWI, arg1);
+
+ case RDISemiHosting_SetThumbSWI:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetThumbSWI.\n");
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetThumbSWI, *arg1);
+
+ case RDISemiHosting_GetThumbSWI:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetThumbSWI.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetThumbSWI, arg1);
+
+ case RDIInfo_SetTopMem:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SetTopMem.\n");
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SetTopMem, *arg1);
+
+ case RDIPointStatus_Watch:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_PointStatus_Watch.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Control | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_PointStatus_Watch, *arg1 );
+ reason = ADP_Control |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status,
+ arg1, arg2);
+ if (subreason != ADP_Ctrl_PointStatus_Watch) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else
+ return status;
+
+ case RDIPointStatus_Break:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_PointStatus_Break.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Control | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_PointStatus_Break, *arg1 );
+ reason = ADP_Control |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status,
+ arg1, arg2);
+ if (subreason != ADP_Ctrl_PointStatus_Break) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else
+ return status;
+
+ case RDIInfo_DownLoad:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_Download_Supported.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_Control, ADP_Ctrl_Download_Supported);
+
+ case RDIConfig_Count:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEM_ConfigCount.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_ICEman, ADP_ICEM_ConfigCount, arg1);
+
+ case RDIConfig_Nth:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEM_ConfigNth.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_ICEman | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEM_ConfigNth, *arg1 );
+ reason = ADP_ICEman |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ } else {
+ RDI_ConfigDesc *cd = (RDI_ConfigDesc *)arg2;
+ unsigned char n;
+ len = unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%b",
+ &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status,
+ &cd->version, &n);
+ if (subreason != ADP_ICEM_ConfigNth) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else {
+ memcpy( cd->name, BUFFERDATA(packet->pk_buffer)+len, n+1 );
+ cd->name[n] = 0;
+ return status;
+ }
+ }
+
+ case RDIInfo_Icebreaker:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_Exists.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_ICEbreakerHADP, ADP_ICEB_Exists);
+
+ case RDIIcebreaker_GetLocks:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_GetLocks.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_ICEbreakerHADP, ADP_ICEB_GetLocks, arg1);
+
+ case RDIIcebreaker_SetLocks:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_SetLocks.\n");
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_ICEbreakerHADP, ADP_ICEB_SetLocks, *arg1);
+
+ case RDICommsChannel_ToHost:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_CC_Connect_ToHost.\n");
+#endif
+ if ( angel_cc_exists() == RDIError_NoError ) {
+
+ /*
+ * The following three lines of code have to be removed in order to get
+ * the Windows Angel Channel Viewer working with the Thumb comms channel.
+ * At the moment it allows the ARMSD command line to register a CCIN/CCOUT
+ * callback which stops the ACV working!
+ */
+#ifdef __unix
+ ccstate.tohost = (RDICCProc_ToHost *)arg1;
+ ccstate.tohostarg = arg2;
+ angel_check_DCC_handler( &ccstate );
+#endif
+#ifdef _WIN32
+
+#endif
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%b", ADP_ICEbreakerHADP | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEB_CC_Connect_ToHost, (arg1 != NULL) );
+ return CheckSubMessageReply(ADP_ICEbreakerHADP, ADP_ICEB_CC_Connect_ToHost);
+ } else {
+ return RDIError_UnimplementedMessage;
+ }
+
+ case RDICommsChannel_FromHost:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_CC_Connect_FromHost.\n");
+#endif
+ if ( angel_cc_exists() == RDIError_NoError ) {
+
+ ccstate.fromhost = (RDICCProc_FromHost *)arg1;
+ ccstate.fromhostarg = arg2;
+ angel_check_DCC_handler( &ccstate );
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%b", ADP_ICEbreakerHADP | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEB_CC_Connect_FromHost, (arg1 != NULL) );
+ return CheckSubMessageReply(ADP_ICEbreakerHADP, ADP_ICEB_CC_Connect_FromHost);
+ } else {
+ return RDIError_UnimplementedMessage;
+ }
+
+ case RDIProfile_Stop:
+ return SendSubMessageAndCheckReply(ADP_Profile, ADP_Profile_Stop);
+
+ case RDIProfile_ClearCounts:
+ return SendSubMessageAndCheckReply(ADP_Profile, ADP_Profile_ClearCounts);
+
+ case RDIProfile_Start:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Profile_Start %ld.\n", (long)*arg1);
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Profile, ADP_Profile_Start, *arg1);
+
+ case RDIProfile_WriteMap:
+ { RDI_ProfileMap *map = (RDI_ProfileMap *)arg1;
+ int32 maplen = map->len,
+ offset,
+ size;
+ int32 chunk = (Armsd_LongBufSize-CHAN_HEADER_SIZE-ADP_ProfileWriteHeaderSize) / sizeof(ARMword);
+ /* Maximum number of words sendable in one message */
+ int oldrev = bytesex_reversing();
+ int host_little = *(uint8 const *)&hostsex;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Profile_WriteMap %ld.\n", maplen);
+#endif
+ status = RDIError_NoError;
+ if (!host_little) {
+ bytesex_reverse(1);
+ for (offset = 0; offset < maplen; offset++)
+ map->map[offset] = bytesex_hostval(map->map[offset]);
+ }
+ for (offset = 0; offset < maplen; offset += size) {
+ unsigned hdrlen;
+ size = maplen - offset;
+ packet = (Packet *)DevSW_AllocatePacket(Armsd_LongBufSize);
+ if (size > chunk) size = chunk;
+ hdrlen = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
+ ADP_Profile | HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, ADP_Profile_WriteMap,
+ maplen, size, offset);
+
+ /* Copy the data into the packet. */
+ memcpy(BUFFERDATA(packet->pk_buffer)+hdrlen,
+ &map->map[offset], (size_t)size * sizeof(ARMword));
+ packet->pk_length = size * sizeof(ARMword) + hdrlen;
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason = ADP_Profile | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err == RDIError_NoError) {
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ if (subreason != ADP_Profile_WriteMap) {
+ err = RDIError_Error;
+ }
+ DevSW_FreePacket(packet);
+ }
+ if (err != RDIError_NoError) { status = err; break; }
+ }
+ if (!host_little) {
+ for (offset = 0; offset < maplen; offset++)
+ map->map[offset] = bytesex_hostval(map->map[offset]);
+ bytesex_reverse(oldrev);
+ }
+ return status;
+ }
+
+ case RDIProfile_ReadMap:
+ { int32 maplen = *(int32 *)arg1,
+ offset = 0,
+ size;
+ int32 chunk = (Armsd_BufferSize-CHAN_HEADER_SIZE-ADP_ProfileReadHeaderSize) / sizeof(ARMword);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Profile_ReadMap %ld.\n", maplen);
+#endif
+ status = RDIError_NoError;
+ for (offset = 0; offset < maplen; offset += size) {
+ size = maplen - offset;
+ if (size > chunk) size = chunk;
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w%w", ADP_Profile | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Profile_ReadMap, offset, size);
+ reason = ADP_Profile | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) return err;
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ memcpy(&arg2[offset], BUFFERDATA(packet->pk_buffer)+ADP_ProfileReadHeaderSize,
+ size * sizeof(ARMword));
+ DevSW_FreePacket(packet);
+ if (status != RDIError_NoError) break;
+ }
+ { int oldrev = bytesex_reversing();
+ int host_little = *(uint8 const *)&hostsex;
+ if (!host_little) {
+ bytesex_reverse(1);
+ for (offset = 0; offset < maplen; offset++)
+ arg2[offset] = bytesex_hostval(arg2[offset]);
+ }
+ bytesex_reverse(oldrev);
+ }
+ return status;
+ }
+
+ case RDIInfo_CanTargetExecute:
+#ifdef DEBUG
+ printf("DEBUG: RDIInfo_CanTargetExecute.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_CanTargetExecute);
+
+ case RDIInfo_AgentEndianess:
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_AgentEndianess);
+
+ default:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Fell through ADP_Info, default case taken.\n");
+ angel_DebugPrint("DEBUG: type = 0x%x.\n", type);
+#endif
+ if (type & RDIInfo_CapabilityRequest) {
+ switch (type & ~RDIInfo_CapabilityRequest) {
+ case RDISemiHosting_SetARMSWI:
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_ChangeableSHSWI);
+ default:
+#ifdef DEBUG
+ angel_DebugPrint(
+ "DEBUG: ADP_Info - Capability Request(%d) - reporting unimplemented \n",
+ type & ~RDIInfo_CapabilityRequest);
+#endif
+ break;
+ }
+ }
+ return RDIError_UnimplementedMessage;
+ }
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_AddConfig------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Add a configuration: use ADP_ICEM_AddConfig. */
+int angel_RDI_AddConfig(unsigned long nbytes) {
+ Packet *packet = NULL;
+ int status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_AddConfig.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_ICEman | HtoT,
+ 0, ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEM_AddConfig, nbytes);
+ reason=ADP_ICEman | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return -1;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_ICEM_AddConfig )
+ return RDIError_Error;
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_LoadConfigData-------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Load configuration data: use ADP_Ctrl_Download_Data. */
+int angel_RDI_LoadConfigData(unsigned long nbytes, char const *data) {
+ Packet *packet = NULL;
+ int len, status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_LoadConfigData (%d bytes)\n", nbytes);
+#endif
+#if 0
+ if (err = angel_RDI_AddConfig(nbytes) != RDIError_NoError)
+ return err;
+#endif
+ packet = DevSW_AllocatePacket(Armsd_LongBufSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w",
+ ADP_Control | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_Download_Data, nbytes);
+ memcpy(BUFFERDATA(packet->pk_buffer)+len, data, nbytes);
+ len += nbytes;
+ packet->pk_length = len;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: packet len %d.\n", len);
+#endif
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason=ADP_Control | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return -1;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_Ctrl_Download_Data )
+ return RDIError_Error;
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_SelectConfig---------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Select a configuration: use ADP_ICEM_SelecConfig.*/
+int angel_RDI_SelectConfig(RDI_ConfigAspect aspect, char const *name,
+ RDI_ConfigMatchType matchtype, unsigned versionreq,
+ unsigned *versionp)
+{
+ Packet *packet = NULL;
+ int len, status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_SelectConfig.\n");
+#endif
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%b%b%b%w",
+ ADP_ICEman | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEM_SelectConfig, aspect, strlen(name),
+ matchtype, versionreq);
+ /* copy the name into the buffer */
+ memcpy(BUFFERDATA(packet->pk_buffer)+len, name, strlen(name));
+ len += strlen(name);
+ packet->pk_length = len;
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason=ADP_ICEman | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2,
+ &subreason, &status, versionp);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_ICEM_SelectConfig )
+ return RDIError_Error;
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_LoadAgent------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Load a new debug agent: use ADP_Ctrl_Download_Agent. */
+int angel_RDI_LoadAgent(ARMword dest, unsigned long size,
+ getbufferproc *getb, void *getbarg)
+{
+ Packet *packet = NULL;
+ int status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
+ time_t t;
+
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: Entered angel_RDI_LoadAgent.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w%w", ADP_Control | HtoT,
+ 0, ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_Download_Agent, dest, size);
+ reason=ADP_Control | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return -1;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_Ctrl_Download_Agent )
+ return RDIError_Error;
+ if ( status != RDIError_NoError )
+ return status;
+
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: starting agent data download.\n");
+#endif
+ { unsigned long pos = 0, segsize;
+ for (; pos < size; pos += segsize) {
+ char *b = getb(getbarg, &segsize);
+ if (b == NULL) return RDIError_NoError;
+ err = angel_RDI_LoadConfigData( segsize, b );
+ if (err != RDIError_NoError) return err;
+ }
+ }
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: finished downloading new agent.\n");
+#endif
+
+ /* renegotiate back down */
+ err = angel_negotiate_defaults();
+ if (err != adp_ok)
+ return err;
+
+ /* Output a message to tell the user what is going on. This is vital
+ * when switching from ADP EICE to ADP over JTAG, as then the user
+ * has to reset the target board !
+ */
+ { char msg[256];
+ int len=angel_RDI_errmess(msg, 256, adp_new_agent_starting);
+ angel_hostif->write(angel_hostif->hostosarg, msg, len);
+ }
+
+ /* get new image started */
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: sending start message for new agent.\n");
+#endif
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Control | HtoT,
+ 0, ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_Start_Agent, dest);
+ reason=ADP_Control | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return -1;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_Ctrl_Start_Agent )
+ return RDIError_Error;
+ if ( status != RDIError_NoError )
+ return status;
+
+ /* wait for image to start up */
+ heartbeat_enabled = FALSE;
+ t=time(NULL);
+ do {
+ Adp_AsynchronousProcessing(async_block_on_nothing);
+ if ((time(NULL)-t) > 2) {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: no booted message from new image yet.\n");
+#endif
+ break;
+ }
+ } while (booted_not_received);
+ booted_not_received=1;
+
+ /* Give device driver a chance to do any necessary resyncing with new agent.
+ * Only used by etherdrv.c at the moment.
+ */
+ (void)Adp_Ioctl( DC_RESYNC, NULL );
+
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: reopening to new agent.\n");
+#endif
+ err = angel_RDI_open(0, NULL, NULL, NULL);
+ switch ( err )
+ {
+ case RDIError_NoError:
+ {
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint( "LoadAgent: Open returned RDIError_NoError\n" );
+#endif
+ break;
+ }
+
+ case RDIError_LittleEndian:
+ {
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint( "LoadAgent: Open returned RDIError_LittleEndian (OK)\n" );
+#endif
+ err = RDIError_NoError;
+ break;
+ }
+
+ case RDIError_BigEndian:
+ {
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint( "LoadAgent: Open returned RDIError_BigEndian (OK)\n" );
+#endif
+ err = RDIError_NoError;
+ break;
+ }
+
+ default:
+ {
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint( "LoadAgent: Open returned %d - unexpected!\n", err );
+#endif
+ break;
+ }
+ }
+#ifndef NO_HEARTBEAT
+ heartbeat_enabled = TRUE;
+#endif
+ return err;
+}
+
+static int angel_RDI_errmess(char *buf, int blen, int errnum) {
+ char *s=NULL;
+ int n;
+
+ switch (errnum) {
+ case adp_malloc_failure:
+ s=AdpMess_MallocFailed; break;
+ case adp_illegal_args:
+ s=AdpMess_IllegalArgs; break;
+ case adp_device_not_found:
+ s=AdpMess_DeviceNotFound; break;
+ case adp_device_open_failed:
+ s=AdpMess_DeviceOpenFailed; break;
+ case adp_device_already_open:
+ s=AdpMess_DeviceAlreadyOpen; break;
+ case adp_device_not_open:
+ s=AdpMess_DeviceNotOpen; break;
+ case adp_bad_channel_id:
+ s=AdpMess_BadChannelId; break;
+ case adp_callback_already_registered:
+ s=AdpMess_CBAlreadyRegd; break;
+ case adp_write_busy:
+ s=AdpMess_WriteBusy; break;
+ case adp_bad_packet:
+ s=AdpMess_BadPacket; break;
+ case adp_seq_high:
+ s=AdpMess_SeqHigh; break;
+ case adp_seq_low:
+ s=AdpMess_SeqLow; break;
+ case adp_timeout_on_open:
+ s=AdpMess_TimeoutOnOpen; break;
+ case adp_failed:
+ s=AdpMess_Failed; break;
+ case adp_abandon_boot_wait:
+ s=AdpMess_AbandonBootWait; break;
+ case adp_late_startup:
+ s=AdpMess_LateStartup; break;
+ case adp_new_agent_starting:
+ s=AdpMess_NewAgentStarting; break;
+ default: return 0;
+ }
+ n=strlen(s);
+ if (n>blen-1) n=blen-1;
+ memcpy(buf, s, n);
+ buf[n++]=0;
+ return n;
+}
+
+extern const struct RDIProcVec angel_rdi;
+const struct RDIProcVec angel_rdi = {
+ "ADP",
+ angel_RDI_open,
+ angel_RDI_close,
+ angel_RDI_read,
+ angel_RDI_write,
+ angel_RDI_CPUread,
+ angel_RDI_CPUwrite,
+ angel_RDI_CPread,
+ angel_RDI_CPwrite,
+ angel_RDI_setbreak,
+ angel_RDI_clearbreak,
+ angel_RDI_setwatch,
+ angel_RDI_clearwatch,
+ angel_RDI_execute,
+ angel_RDI_step,
+ angel_RDI_info,
+ angel_RDI_pointinq,
+
+ angel_RDI_AddConfig,
+ angel_RDI_LoadConfigData,
+ angel_RDI_SelectConfig,
+
+ 0, /*angel_RDI_drivernames,*/
+ 0, /* cpunames */
+
+ angel_RDI_errmess,
+
+ angel_RDI_LoadAgent
+};
+
+/* EOF ardi.c */
+
+/* Not strictly necessary, but allows linking this code into armsd. */
+
+struct foo {
+ char *name;
+ int (*action)();
+ char *syntax;
+ char **helpmessage;
+ int doafterend;
+ int dobeforestart;
+ int doinmidline;
+} hostappl_CmdTable[1] = {{"", NULL}};
+
+void
+hostappl_Init()
+{
+}
+
+int
+hostappl_Backstop()
+{
+ return -30;
+}
diff --git a/gdb/rdi-share/ardi.h b/gdb/rdi-share/ardi.h
new file mode 100644
index 00000000000..3b23d88bff8
--- /dev/null
+++ b/gdb/rdi-share/ardi.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ardi.h
+ * ADP RDI interfaces
+ *
+ * $Revision$
+ * $Date$
+ */
+
+#include "host.h"
+
+typedef unsigned32 ARMword;
+
+#include "dbg_rdi.h"
+#include "dbg_conf.h"
+
+extern char *commandline;
+extern ARMword last_vector_catch;
+
+/* This is the size of buffers that are asked for by standard channels
+ * Non standard channels may wish to copy this!
+ */
+extern int Armsd_BufferSize;
+
+typedef int (*host_ChannelBufferFilledFnPtr)(unsigned int ,unsigned char ** ,void *);
+
+int angel_RDI_open(
+ unsigned type, Dbg_ConfigBlock const *config,
+ Dbg_HostosInterface const *hostif, struct Dbg_MCState *dbg_state);
+int angel_RDI_close(void);
+
+int angel_RDI_read(ARMword source, void *dest, unsigned *nbytes);
+int angel_RDI_write(const void *source, ARMword dest, unsigned *nbytes);
+
+int angel_RDI_CPUread(unsigned mode, unsigned long mask, ARMword *buffer);
+int angel_RDI_CPUwrite(unsigned mode, unsigned long mask,
+ ARMword const *buffer);
+
+int angel_RDI_CPread(unsigned CPnum, unsigned long mask, ARMword *buffer);
+int angel_RDI_CPwrite(unsigned CPnum, unsigned long mask,
+ ARMword const *buffer);
+
+int angel_RDI_setbreak(ARMword address, unsigned type, ARMword bound,
+ PointHandle *handle);
+int angel_RDI_clearbreak(PointHandle handle);
+
+int angel_RDI_setwatch(ARMword address, unsigned type, unsigned datatype,
+ ARMword bound, PointHandle *handle);
+int angel_RDI_clearwatch(PointHandle handle);
+
+int angel_RDI_pointinq(ARMword *address, unsigned type, unsigned datatype,
+ ARMword *bound);
+
+int angel_RDI_execute(PointHandle *handle);
+
+void angel_RDI_stop_request(void);
+
+int angel_RDI_step(unsigned ninstr, PointHandle *handle);
+
+int angel_RDI_info(unsigned type, ARMword *arg1, ARMword *arg2);
+
+int angel_RDI_AddConfig(unsigned long nbytes);
+
+int angel_RDI_LoadConfigData(unsigned long nbytes, char const *data);
+
+int angel_RDI_SelectConfig(RDI_ConfigAspect aspect, char const *name,
+ RDI_ConfigMatchType matchtype, unsigned versionreq,
+ unsigned *versionp);
+
+RDI_NameList const *angel_RDI_drivernames(void);
+
+int angel_RDI_LoadAgent(ARMword dest, unsigned long size, getbufferproc *getb,
+ void *getbarg);
+
+extern const struct Dbg_HostosInterface *angel_hostif;
+
+typedef int angel_RDI_TargetStoppedProc(unsigned stopped_reason, void *arg);
+
+extern int angel_RDI_OnTargetStopping(angel_RDI_TargetStoppedProc *fn,
+ void *arg);
diff --git a/gdb/rdi-share/armdbg.h b/gdb/rdi-share/armdbg.h
new file mode 100644
index 00000000000..b5fae113281
--- /dev/null
+++ b/gdb/rdi-share/armdbg.h
@@ -0,0 +1,1452 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ARM symbolic debugger toolbox interface
+ */
+
+/*
+ * RCS $Revision$
+ * Checkin $Date$
+ */
+
+/* Minor points of uncertainty are indicated by a question mark in the
+ LH margin.
+
+ Wherever an interface is required to iterate over things of some class,
+ I prefer something of the form EnumerateXXs(..., XXProc *p, void *arg)
+ which results in a call of p(xx, arg) for each xx, rather than something
+ of the form
+ for (xxh = StartIterationOverXXs(); (xx = Next(xxh)) != 0; ) { ... }
+ EndIterationOverXXs(xxh);
+ Others may disagree.
+ (Each XXProc returns an Error value: if this is not Err_OK, iteration
+ stops immediately and the EnumerateXXs function returns that value).
+
+ ptrace has been retired as of insufficient utility. If such fuctionality is
+ required, it can be constructed using breakpoints.
+
+ The file form of all name fields in debug areas is in-line, with a length
+ byte and no terminator. The debugger toolbox makes an in-store translation,
+ where the strings are out of line (the namep variant in asdfmt.h) and have a
+ terminating zero byte: the pointer is to the first character of the string
+ with the length byte at ...->n.namep[-1].
+ */
+
+#ifndef armdbg__h
+#define armdbg__h
+
+#include <stddef.h>
+
+#include "host.h"
+#include "msg.h"
+
+typedef unsigned32 ARMaddress;
+typedef unsigned32 ARMword;
+typedef unsigned16 ARMhword;
+
+#include "dbg_conf.h"
+#include "dbg_rdi.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef unsigned char Dbg_Byte;
+
+typedef int Dbg_Error;
+
+typedef struct Dbg_MCState Dbg_MCState;
+/* A representation of the state of the target. The structure is not revealed.
+ A pointer to one of these is returned by Dbg_Initialise(), is passed to all
+ toolbox calls which refer to the state of the target, and is discarded
+ by Dbg_Finalise().
+ Nothing in the toolbox itself precludes there being multiple targets, each
+ with its own state.
+ */
+
+/* Most toolbox interfaces return an error status. Only a few of the status
+ values are expected to be interesting to clients and defined here; the
+ rest are private (but a textual form can be produced by ErrorToChars()).
+ */
+
+#define Error_OK 0
+
+/* Partitioning of the error code space: errors below Dbg_Error_Base are RDI
+ errors (as defined in dbg_rdi.h). Codes above Dbg_Error_Limit are
+ available to clients, who may impose some further structure.
+ */
+#define Dbg_Error_Base 0x1000
+#define Dbg_Error_Limit 0x2000
+
+#define DbgError(n) ((Dbg_Error)(Dbg_Error_Base+(n)))
+
+#define Dbg_Err_OK Error_OK
+#define Dbg_Err_Interrupted DbgError(1)
+#define Dbg_Err_Overflow DbgError(2)
+#define Dbg_Err_FileNotFound DbgError(3)
+#define Dbg_Err_ActivationNotPresent DbgError(4)
+#define Dbg_Err_OutOfHeap DbgError(5)
+#define Dbg_Err_TypeNotSimple DbgError(6)
+#define Dbg_Err_BufferFull DbgError(7)
+#define Dbg_Err_AtStackBase DbgError(8)
+#define Dbg_Err_AtStackTop DbgError(9)
+#define Dbg_Err_DbgTableFormat DbgError(10)
+#define Dbg_Err_NotVariable DbgError(11)
+#define Dbg_Err_NoSuchBreakPoint DbgError(12)
+#define Dbg_Err_NoSuchWatchPoint DbgError(13)
+#define Dbg_Err_FileLineNotFound DbgError(14)
+#define Dbg_Err_DbgTableVersion DbgError(15)
+#define Dbg_Err_NoSuchPath DbgError(16)
+#define Dbg_Err_StateChanged DbgError(17)
+#define Dbg_Err_SoftInitialiseError DbgError(18)
+#define Dbg_Err_CoProRegNotWritable DbgError(19)
+#define Dbg_Err_NotInHistory DbgError(20)
+#define Dbg_Err_ContextSyntax DbgError(21)
+#define Dbg_Err_ContextNoLine DbgError(22)
+#define Dbg_Err_ContextTwoLines DbgError(23)
+#define Dbg_Err_VarReadOnly DbgError(24)
+#define Dbg_Err_FileNewerThanImage DbgError(25)
+#define Dbg_Err_NotFound DbgError(26)
+
+ /* functions which evaluate expressions may return this value, to indicate
+ that execution became suspended within a function called in the debugee */
+
+/* Functions returning characters take a BufDesc argument, with fields buffer
+ and bufsize being input arguments describing the buffer to be filled, and
+ filled being set on return to the number of bytes written to the buffer
+ (omitting the terminating 0).
+ */
+
+typedef struct Dbg_BufDesc Dbg_BufDesc;
+
+typedef void Dbg_BufferFullProc(Dbg_BufDesc *bd);
+
+struct Dbg_BufDesc {
+ char *buffer;
+ size_t size,
+ filled;
+ Dbg_BufferFullProc *p;
+ void *arg;
+};
+
+#define Dbg_InitBufDesc(bd, buf, bytes) \
+ ((bd).buffer = (buf), (bd).size = (bytes), (bd).filled = 0,\
+ (bd).p = NULL, (bd).arg = NULL)
+
+#define Dbg_InitBufDesc_P(bd, buf, bytes, fn, a) \
+ ((bd).buffer = (buf), (bd).size = (bytes), (bd).filled = 0,\
+ (bd).p = (fn), (bd).arg = (a))
+
+Dbg_Error Dbg_StringToBuf(Dbg_BufDesc *buf, char const *s);
+Dbg_Error Dbg_BufPrintf(Dbg_BufDesc *buf, char const *form, ...);
+#ifdef NLS
+Dbg_Error Dbg_MsgToBuf(Dbg_BufDesc *buf, msg_t t);
+Dbg_Error Dbg_BufMsgPrintf(Dbg_BufDesc *buf, msg_t form, ...);
+#else
+#define Dbg_MsgToBuf Dbg_StringToBuf
+#define Dbg_BufMsgPrintf Dbg_BufPrintf
+#endif
+Dbg_Error Dbg_CharToBuf(Dbg_BufDesc *buf, int ch);
+
+int Dbg_CIStrCmp(char const *s1, char const *s2);
+/* Case-independent string comparison, interface as for strcmp */
+
+int Dbg_CIStrnCmp(char const *s1, char const *s2, size_t n);
+/* Case-independent string comparison, interface as for strncmp */
+
+void Dbg_ErrorToChars(Dbg_MCState *state, Dbg_Error err, Dbg_BufDesc *buf);
+
+typedef int Dbg_RDIResetCheckProc(int);
+/* Type of a function to be called after each RDI operation performed by the
+ toolbox, with the status from the operation as argument. The value returned
+ is treated as the status. (The intent is to allow the toolbox's client to
+ take special action to handle RDIDbg_Error_Reset).
+ */
+
+typedef struct Dbg_CoProDesc Dbg_CoProDesc;
+
+typedef Dbg_Error Dbg_CoProFoundProc(Dbg_MCState *state, int cpno, Dbg_CoProDesc const *cpd);
+/* Type of a function to be called when the shape of a coprocessor is discovered
+ by enquiry of the target or agent (via RequestCoProDesc)
+ */
+
+typedef struct RDIProcVec RDIProcVec;
+
+Dbg_Error Dbg_RequestReset(Dbg_MCState *);
+
+Dbg_Error Dbg_Initialise(
+ Dbg_ConfigBlock *config, Dbg_HostosInterface const *i,
+ Dbg_RDIResetCheckProc *checkreset, Dbg_CoProFoundProc *coprofound,
+ RDIProcVec const *rdi, Dbg_MCState **statep);
+/* values in config are updated if they call for default values */
+
+void Dbg_Finalise(Dbg_MCState *state, bool targetdead);
+
+typedef struct {
+ char name[16];
+ RDI_MemDescr md;
+ RDI_MemAccessStats a;
+} Dbg_MemStats;
+
+/*--------------------------------------------------------------------------*/
+
+/* Symbol table management.
+ The structure of a Dbg_SymTable is not revealed. It is created by
+ Dbg_ReadSymbols() or by Dbg_LoadFile(), and associated with the argument
+ Dbg_MCState.
+ Many symbol tables may be concurrently active.
+ A Dbg_SymTable is removed either explicitly (by call to Dbg_DeleteSymbols)
+ or implicitly when a symbol table for an overlapping address range is read.
+
+ There is a pre-defined symbol table containing entries for ARM registers,
+ co-processor registers and the like.
+ */
+
+typedef struct Dbg_SymTable Dbg_SymTable;
+
+typedef struct Dbg_ImageFragmentDesc {
+ ARMaddress base, limit;
+} Dbg_ImageFragmentDesc;
+
+typedef enum {
+ Dbg_Lang_None,
+ Dbg_Lang_C,
+ Dbg_Lang_Pascal,
+ Dbg_Lang_Fortran,
+ Dbg_Lang_Asm,
+ Dbg_Lang_Cpp
+} Dbg_Lang;
+
+typedef struct Dbg_ImageDesc {
+ Dbg_Lang lang;
+ int executable;
+ ARMaddress robase, rolimit, rwbase, rwlimit;
+ int nfrags;
+ Dbg_ImageFragmentDesc *fragments;
+ char *name;
+} Dbg_ImageDesc;
+
+Dbg_ImageDesc *Dbg_ImageAreas(Dbg_SymTable *st);
+
+Dbg_SymTable *Dbg_LastImage(Dbg_MCState *state);
+
+Dbg_SymTable *Dbg_NewSymTable(Dbg_MCState *state, const char *name);
+
+Dbg_Error Dbg_ReadSymbols(Dbg_MCState *state, const char *filename, Dbg_SymTable **st);
+/* Just read the symbols from the named image. <st> is set to the allocated
+ symbol table.
+? Maybe we could usefully allow other formats than AIF images to describe
+ the symbols (eg) of shared libraries
+ */
+
+typedef struct Dbg_SymInfo {
+ int isize;
+ ARMaddress addr;
+ char *name;
+} Dbg_SymInfo;
+
+Dbg_SymInfo *Dbg_AsmSym(Dbg_SymTable *st, ARMaddress addr);
+int32 Dbg_AsmAddr(Dbg_SymTable *st, int32 line);
+int32 Dbg_AsmLine(Dbg_SymTable *st, ARMaddress addr);
+int32 Dbg_AsmLinesInRange(Dbg_SymTable *st, ARMaddress start, ARMaddress end);
+
+Dbg_Error Dbg_LoadFile(Dbg_MCState *state, const char *filename, Dbg_SymTable **st);
+/* load the image into target memory, and read its symbols. <st> is set to
+ the allocated symbol table.
+ A null filename reloads the most recently loaded file (and rereads its
+ symbols).
+ Loading an image leaves breakpoints unchanged. If a client wishes
+ otherwise, it must remove the breakpoints explicitly.
+*/
+
+Dbg_Error Dbg_CallGLoadFile(Dbg_MCState *state, const char *filename, Dbg_SymTable **st);
+
+typedef void Dbg_ImageLoadProc(Dbg_MCState *, Dbg_SymTable *);
+Dbg_Error Dbg_OnImageLoad(Dbg_MCState *, Dbg_ImageLoadProc *);
+/* Register function to be called back whenever an image is loaded, or symbols
+ * for an image read. (To allow multiple toolbox clients to coexist).
+ */
+
+Dbg_Error Dbg_LoadAgent(Dbg_MCState *state, const char *filename);
+/* Load a debug agent, and start it.
+ Symbols in the image for the agent are ignored.
+*/
+
+Dbg_Error Dbg_RelocateSymbols(Dbg_SymTable *st, ARMaddress reloc);
+/* add <reloc> to the value of all symbols in <st> describing absolute memory
+ locations. The intent is to allow the symbols in a load-time relocating
+ image (for example) to be useful.
+ */
+
+Dbg_Error Dbg_DeleteSymbols(Dbg_MCState *state, Dbg_SymTable **st);
+
+typedef enum Dbg_LLSymType {
+ llst_code,
+ llst_code16,
+ llst_data,
+ llst_const,
+ llst_unknown,
+ llst_max
+} Dbg_LLSymType;
+/* Since AIF images contain no type information for low-level symbols, this
+ classification is only a guess, and some symbols describing constants will
+ incorrectly be described as code or data.
+ */
+
+typedef Dbg_Error Dbg_SymProc(
+ Dbg_MCState *state,
+ const char *symbol, Dbg_LLSymType symtype, ARMaddress value,
+ void *arg);
+
+Dbg_Error Dbg_EnumerateLowLevelSymbols(
+ Dbg_MCState *state, const char *match, Dbg_SymProc *p,
+ void *arg);
+/* Call p(name, value) for each low level symbol in the tables of <state>
+ whose name matches the regular expression <match> (a NULL <match> matches
+ any name). Symbols are enumerated in no particular order.
+ */
+
+/*--------------------------------------------------------------------------*/
+
+/* Functions are provided here to allow quick mass access to register values
+ for display. There is no comparable need for quick mass update, so writing
+ should be via Assign().
+ */
+
+typedef struct Dbg_RegSet {
+ ARMword
+ user[15],
+ pc,
+ psr,
+ fiq[7],
+ spsr_fiq,
+ irq[2],
+ spsr_irq,
+ svc[2],
+ spsr_svc,
+ abort[2],
+ spsr_abort,
+ undef[2],
+ spsr_undef;
+} Dbg_RegSet;
+
+/* bits in the modemask argument for ReadRegisters */
+
+#define Dbg_MM_User 1
+#define Dbg_MM_FIQ 2
+#define Dbg_MM_IRQ 4
+#define Dbg_MM_SVC 8
+#define Dbg_MM_Abort 0x10
+#define Dbg_MM_Undef 0x20
+#define Dbg_MM_System 0x40
+
+Dbg_Error Dbg_ReadRegisters(Dbg_MCState *state, Dbg_RegSet *regs, int modemask);
+
+Dbg_Error Dbg_WriteRegister(Dbg_MCState *state, int rno, int modemask, ARMword val);
+
+int Dbg_StringToMode(const char *name);
+
+int Dbg_ModeToModeMask(ARMword mode);
+
+/* Some implementations of the FP instruction set keep FP values loaded into
+ registers in their unconverted format, converting only when necessary.
+ Some RDI implementations deliver these values uninterpreted.
+ (For the rest, register values will always have type F_Extended).
+ */
+
+typedef enum { F_Single, F_Double, F_Extended, F_Packed, /* fpe340 values */
+ F_Internal, /* new fpe : mostly as extended */
+ F_None } Dbg_FPType;
+
+typedef struct { ARMword w[3]; } Dbg_TargetExtendedVal;
+typedef struct { ARMword w[3]; } Dbg_TargetPackedVal;
+typedef struct { ARMword w[2]; } Dbg_TargetDoubleVal;
+typedef struct { ARMword w[1]; } Dbg_TargetFloatVal;
+
+typedef union { Dbg_TargetExtendedVal e; Dbg_TargetPackedVal p;
+ Dbg_TargetDoubleVal d; Dbg_TargetFloatVal f; } Dbg_TargetFPVal;
+
+#define TargetSizeof_Extended 12
+#define TargetSizeof_Packed 12
+#define TargetSizeof_Double 8
+#define TargetSizeof_Float 4
+
+typedef struct Dbg_FPRegVal {
+ Dbg_FPType type;
+ Dbg_TargetFPVal v;
+} Dbg_FPRegVal;
+
+typedef struct Dbg_FPRegSet {
+ Dbg_FPRegVal f[8];
+ ARMword fpsr, fpcr;
+} Dbg_FPRegSet;
+
+Dbg_Error Dbg_ReadFPRegisters(Dbg_MCState *state, Dbg_FPRegSet *regs);
+
+Dbg_Error Dbg_WriteFPRegisters(Dbg_MCState *state, int32 mask, Dbg_FPRegSet *regs);
+
+Dbg_Error Dbg_FPRegToDouble(DbleBin *d, Dbg_FPRegVal const *f);
+/* Converts from a FP register value (in any format) to a double with
+ approximately the same value (or returns Dbg_Err_Overflow)
+ */
+
+void Dbg_DoubleToFPReg(Dbg_FPRegVal *f, DbleBin const *d);
+/* Converts the double <d> to a Dbg_FPRegVal with type F_Extended */
+
+/*--------------------------------------------------------------------------*/
+
+#include "dbg_cp.h"
+
+Dbg_Error Dbg_DescribeCoPro(Dbg_MCState *state, int cpnum, Dbg_CoProDesc *p);
+
+Dbg_Error Dbg_DescribeCoPro_RDI(Dbg_MCState *state, int cpnum, Dbg_CoProDesc *p);
+
+Dbg_Error Dbg_ReadCPRegisters(Dbg_MCState *state, int cpnum, ARMword *regs);
+
+Dbg_Error Dbg_WriteCPRegisters(Dbg_MCState *state, int cpnum, int32 mask, ARMword *regs);
+
+/*--------------------------------------------------------------------------*/
+
+Dbg_Error Dbg_ReadWords(
+ Dbg_MCState *state,
+ ARMword *words, ARMaddress addr, unsigned count);
+/* Reads a number of (32-bit) words from target store. The values are in host
+ byte order; if they are also to be interpreted as bytes Dbg_SwapByteOrder()
+ must be called to convert to target byte order.
+ */
+
+Dbg_Error Dbg_WriteWords(
+ Dbg_MCState *state,
+ ARMaddress addr, const ARMword *words, unsigned count);
+/* Writes a number of (32-bit) words to target store. The values are in host
+ byte order (if what is being written is actually a byte string it must be
+ converted by Dbg_SwapByteOrder()).
+ */
+
+Dbg_Error Dbg_ReadHalf(Dbg_MCState *state, ARMhword *val, ARMaddress addr);
+Dbg_Error Dbg_WriteHalf(Dbg_MCState *state, ARMaddress addr, ARMword val);
+
+Dbg_Error Dbg_ReadBytes(Dbg_MCState *state, Dbg_Byte *val, ARMaddress addr, unsigned count);
+Dbg_Error Dbg_WriteBytes(Dbg_MCState *state, ARMaddress addr, const Dbg_Byte *val, unsigned count);
+
+void Dbg_HostWords(Dbg_MCState *state, ARMword *words, unsigned wordcount);
+/* (A noop unless host and target bytesexes differ) */
+
+ARMword Dbg_HostWord(Dbg_MCState *state, ARMword v);
+
+ARMhword Dbg_HostHalf(Dbg_MCState *state, ARMword v);
+
+/*--------------------------------------------------------------------------*/
+
+/* Types describing various aspects of position within code.
+ There are rather a lot of these, in the interests of describing precisely
+ what fields must be present (rather than having a single type with many
+ fields which may or may not be valid according to context).
+ */
+
+typedef struct Dbg_LLPos {
+ Dbg_SymTable *st;
+ char *llsym;
+ ARMaddress offset;
+} Dbg_LLPos;
+
+typedef struct Dbg_File {
+ Dbg_SymTable *st;
+ char *file;
+} Dbg_File;
+
+typedef struct Dbg_Line {
+ unsigned32 line; /* linenumber in the file */
+ unsigned16 statement, /* within the line (1-based) */
+ charpos; /* ditto */
+} Dbg_Line;
+/* As an output value from toolbox functions, both statement and charpos are set
+ if the version of the debugger tables for the section concerned permits.
+ On input, <charpos> is used only if <statement> is 0 (in which case, if
+ <charpos> is non-0, Dbg_Err_DbgTableVersion is returned if the version of
+ the debugger tables concerned is too early.
+ */
+
+typedef struct Dbg_FilePos {
+ Dbg_File f;
+ Dbg_Line line;
+} Dbg_FilePos;
+
+typedef struct Dbg_ProcDesc {
+ Dbg_File f;
+ char *name;
+} Dbg_ProcDesc;
+
+typedef struct Dbg_ProcPos {
+ Dbg_ProcDesc p;
+ Dbg_Line line;
+} Dbg_ProcPos;
+
+/* Support for conversions between position representations */
+
+Dbg_Error Dbg_ProcDescToLine(Dbg_MCState *state, Dbg_ProcDesc *proc, Dbg_Line *line);
+/* If proc->f.file is null (and there is just one function proc->name), it is
+ updated to point to the name of the file containing (the start of)
+ proc->name.
+ */
+
+Dbg_Error Dbg_FilePosToProc(Dbg_MCState *state, const Dbg_FilePos *pos, char **procname);
+
+/* Conversions from position representations to and from code addresses */
+
+Dbg_Error Dbg_AddressToProcPos(
+ Dbg_MCState *state, ARMaddress addr,
+ Dbg_ProcPos *pos);
+Dbg_Error Dbg_AddressToLLPos(
+ Dbg_MCState *state, ARMaddress addr,
+ Dbg_LLPos *pos, Dbg_LLSymType *res_type, int system_names);
+
+Dbg_Error Dbg_ProcPosToAddress(
+ Dbg_MCState *state, const Dbg_ProcPos *pos,
+ ARMaddress *res);
+Dbg_Error Dbg_LLPosToAddress(
+ Dbg_MCState *state, const Dbg_LLPos *pos,
+ ARMaddress *res);
+
+typedef struct {
+ ARMaddress start, end;
+} Dbg_AddressRange;
+
+typedef Dbg_Error Dbg_AddressRangeProc(void *arg, int32 first, int32 last, Dbg_AddressRange const *range);
+
+Dbg_Error Dbg_MapAddressRangesForFileRange(
+ Dbg_MCState *state,
+ Dbg_SymTable *st, const char *f, int32 first, int32 last, Dbg_AddressRangeProc *p, void *arg);
+
+typedef struct Dbg_Environment Dbg_Environment;
+/* A Dbg_Environment describes the context required to make sense of a variable
+ name and access its value. Its format is not revealed. Dbg_Environment
+ values are allocated by Dbg_NewEnvironment() and discarded by
+ Dbg_DeleteEnvironment().
+ */
+
+Dbg_Environment *Dbg_NewEnvironment(Dbg_MCState *state);
+void Dbg_DeleteEnvironment(Dbg_MCState *state, Dbg_Environment *env);
+
+Dbg_Error Dbg_StringToEnv(
+ Dbg_MCState *state, char *str, Dbg_Environment *resenv,
+ int forcontext, Dbg_Environment const *curenv);
+
+Dbg_Error Dbg_ProcPosToEnvironment(
+ Dbg_MCState *state, const Dbg_ProcPos *pos, int activation,
+ const Dbg_Environment *current, Dbg_Environment *res);
+
+/* Conversion from a position representation to an Dbg_Environment (as required
+ to access variable values). Only a Dbg_ProcPos argument here; other
+ representations need to be converted first.
+
+ Returns <res> describing the <activation>th instance of the function
+ described by <pos>, up from the stack base if <activation> is negative,
+ else down from <current>.
+ If this function returns Dbg_Err_ActivationNotPresent, the result
+ Dbg_Environment is still valid for accessing non-auto variables.
+ */
+
+typedef struct Dbg_DeclSpec Dbg_DeclSpec;
+
+Dbg_Error Dbg_EnvToProcItem(
+ Dbg_MCState *state, Dbg_Environment const *env, Dbg_DeclSpec *proc);
+
+Dbg_Error Dbg_ContainingEnvironment(
+ Dbg_MCState *state, const Dbg_Environment *context, Dbg_Environment *res);
+/* Set <res> to describe the containing function, file if <context> is within
+ a top-level function (or error if <context> already describes a file).
+ */
+
+/*--------------------------------------------------------------------------*/
+
+/* ASD debug table pointers are not by themselves sufficient description,
+ since there's an implied section context. Hence the DeclSpec and TypeSpec
+ structures.
+ */
+
+
+#ifndef Dbg_TypeSpec_Defined
+
+struct Dbg_DeclSpec { void *a; };
+
+#ifdef CALLABLE_COMPILER
+typedef void *Dbg_TypeSpec;
+
+/* The intention here is to give an alternative definition for Dbg_BasicType
+ which follows.
+ */
+
+#define Dbg_T_Void xDbg_T_Void
+#define Dbg_T_Bool xDbg_T_Bool
+#define Dbg_T_SByte xDbg_T_SByte
+#define Dbg_T_SHalf xDbg_T_Half
+#define Dbg_T_SWord xDbg_T_SWord
+#define Dbg_T_UByte xDbg_T_UByte
+#define Dbg_T_UHalf xDbg_T_UHalf
+#define Dbg_T_UWord xDbg_T_UWord
+#define Dbg_T_Float xDbg_T_Float
+#define Dbg_T_Double xDbg_T_Double
+#define Dbg_T_LDouble xDbg_T_LDouble
+#define Dbg_T_Complex xDbg_T_Complex
+#define Dbg_T_DComplex xDbg_T_DComplex
+#define Dbg_T_String xDbg_T_String
+#define Dbg_T_Function xDbg_T_Function
+
+#define Dbg_BasicType xDbg_BaiscType
+#define Dbg_PrimitiveTypeToTypeSpec xDbg_PrimitiveTypeToTypeSpec
+
+#else
+/* We want a Dbg_TypeSpec to be a an opaque type, but of known size (so the
+ toolbox's clients can allocate the store to hold one); unfortunately, we
+ can do this only by having one definition for the toolbox's clients and
+ one (elsewhere) for the toolbox itself.
+ */
+
+typedef struct Dbg_TypeSpec Dbg_TypeSpec;
+struct Dbg_TypeSpec { void *a; int32 b; };
+#endif /* CALLABLE_COMPILER */
+
+typedef enum {
+ Dbg_T_Void,
+
+ Dbg_T_Bool,
+
+ Dbg_T_SByte,
+ Dbg_T_SHalf,
+ Dbg_T_SWord,
+
+ Dbg_T_UByte,
+ Dbg_T_UHalf,
+ Dbg_T_UWord,
+
+ Dbg_T_Float,
+ Dbg_T_Double,
+ Dbg_T_LDouble,
+
+ Dbg_T_Complex,
+ Dbg_T_DComplex,
+
+ Dbg_T_String,
+
+ Dbg_T_Function
+} Dbg_BasicType;
+
+#endif
+
+void Dbg_PrimitiveTypeToTypeSpec(Dbg_TypeSpec *ts, Dbg_BasicType t);
+
+bool Dbg_TypeIsIntegral(Dbg_TypeSpec const *ts);
+
+bool Dbg_TypeIsPointer(Dbg_TypeSpec const *ts);
+
+bool Dbg_TypeIsFunction(Dbg_TypeSpec const *ts);
+
+bool Dbg_PruneType(Dbg_TypeSpec *tsres, Dbg_TypeSpec const *ts);
+/* Return to tsres a version of ts which has been pruned by the removal of all
+ toplevel typedefs. Result is YES if the result has changed.
+ */
+
+typedef Dbg_Error Dbg_FileProc(Dbg_MCState *state, const char *name, const Dbg_DeclSpec *procdef, void *arg);
+
+Dbg_Error Dbg_EnumerateFiles(Dbg_MCState *state, Dbg_SymTable *st, Dbg_FileProc *p, void *arg);
+/* The top level for a high level enumerate. Lower levels are performed by
+ EnumerateDeclarations (below).
+ */
+
+typedef enum {
+ ds_Invalid,
+ ds_Type,
+ ds_Var,
+ ds_Proc,
+ ds_Enum,
+ ds_Function,
+ ds_Label
+} Dbg_DeclSort;
+
+Dbg_DeclSort Dbg_SortOfDeclSpec(Dbg_DeclSpec const *decl);
+
+char *Dbg_NameOfDeclSpec(Dbg_DeclSpec const *decl);
+
+Dbg_TypeSpec Dbg_TypeSpecOfDeclSpec(Dbg_DeclSpec const *decl);
+
+typedef enum {
+ cs_None,
+ cs_Extern,
+ cs_Static,
+ cs_Auto,
+ cs_Reg,
+ cs_Var,
+ cs_Farg,
+ cs_Fcarg,
+ cs_Local,
+ cs_Filtered,
+ cs_Globalreg
+} Dbg_StgClass;
+
+Dbg_StgClass Dbg_StgClassOfDeclSpec(Dbg_DeclSpec const *decl);
+
+bool Dbg_VarsAtSameAddress(Dbg_DeclSpec const *d1, Dbg_DeclSpec const *d2);
+
+bool Dbg_VarsDecribedForDeclSpec(Dbg_DeclSpec const *decl);
+
+int Dbg_ArgCountOfDeclSpec(Dbg_DeclSpec const *decl);
+
+typedef struct Dbg_DComplex { DbleBin r, i; } Dbg_DComplex;
+
+typedef union Dbg_ConstantVal {
+ int32 l;
+ unsigned32 u;
+ DbleBin d;
+ Dbg_DComplex fc;
+ ARMaddress a;
+ char *s;
+} Dbg_ConstantVal;
+
+typedef struct Dbg_Constant {
+ Dbg_TypeSpec type;
+ Dbg_ConstantVal val;
+} Dbg_Constant;
+
+typedef enum Dbg_ValueSort {
+ vs_register,
+ vs_store,
+ vs_constant,
+ vs_local,
+ vs_filtered,
+ vs_none,
+ vs_error
+} Dbg_ValueSort;
+
+/* vs_local allows the use of symbol table entries to describe entities within
+ the debugger's own address space, accessed in the same way as target
+ variables.
+ vs_filtered describes entities which may be read or written only via an
+ access function (eg r15)
+ */
+
+#define fpr_base 16
+/* There's only one register ValueSort (reflecting asd table StgClass);
+ fp register n is encoded as register n+fpr_base.
+ */
+
+typedef struct Dbg_Value Dbg_Value;
+
+typedef Dbg_Error Dbg_AccessFn(Dbg_MCState *state, int write, Dbg_Value *self, Dbg_Constant *c);
+/* <write> == 0: read a vs_filtered value, updating the value self.
+ <write> == 1: update a vs_filtered value, with the value described by c.
+ <self> allows use of the same Dbg_AccessFn for several different entities
+ (using different val.f.id fields).
+ */
+
+typedef Dbg_Error Dbg_FormatFn(int decode, char *b, ARMword *valp, void *formatarg);
+
+typedef struct { Dbg_AccessFn *f; int id; } Dbg_AccessFnRec;
+
+struct Dbg_Value {
+ Dbg_TypeSpec type;
+ Dbg_ValueSort sort;
+ Dbg_FormatFn *formatp;
+ void *formatarg;
+ int f77csize;
+ union {
+ struct { int no; ARMaddress frame; } r;
+ ARMaddress ptr;
+ Dbg_ConstantVal c;
+ void *localp;
+ Dbg_AccessFnRec f;
+ Dbg_Error err;
+ } val;
+};
+
+Dbg_Error Dbg_AddLLSymbol(Dbg_SymTable *st, char const *name, Dbg_LLSymType type, ARMword val);
+
+Dbg_Error Dbg_AddSymbol(Dbg_SymTable *st, char const *name, Dbg_Value const *val);
+
+typedef struct Dbg_DeclSpecF {
+ Dbg_DeclSpec decl;
+ Dbg_FormatFn *formatp;
+ void *formatarg;
+} Dbg_DeclSpecF;
+
+typedef Dbg_Error Dbg_DeclProc(Dbg_MCState *state, Dbg_Environment const *context,
+ Dbg_DeclSpecF const *var, Dbg_DeclSort sort, int masked,
+ void *arg);
+
+Dbg_Error Dbg_EnumerateDeclarations(Dbg_MCState *state, Dbg_Environment const *context,
+ Dbg_DeclProc *p, void *arg);
+/* call p once for every declaration local to the function described by
+ <context> (or file if <context> describes a place outside a function).
+ p's argument <masked> is true if the variable is not visible, thanks to
+ a declaration in an inner scope.
+ */
+
+Dbg_Error Dbg_ValueOfVar(Dbg_MCState *state, const Dbg_Environment *context,
+ const Dbg_DeclSpec *var, Dbg_Value *val);
+/* Different from Dbg_EvalExpr() in that the thing being evaluated is described
+ by a Dbg_DeclSpec (which must be for a variable), rather than a string
+ needing to be decoded and associated with a symbol-table item. Intended to
+ be called from a Dbg_DeclProc called from Dbg_EnumerateDeclarations.
+ */
+
+Dbg_Error Dbg_EvalExpr(Dbg_MCState *state, Dbg_Environment const *context,
+ char const *expr, int flags, Dbg_Value *val);
+
+Dbg_Error Dbg_EvalExpr_ep(Dbg_MCState *state, Dbg_Environment const *context,
+ char const *expr, char **exprend, int flags, Dbg_Value *val);
+
+/* Both Dbg_ValueOfVar and Dbg_EvalExpr mostly deliver a value still containing
+ an indirection (since it may be wanted as the lhs of an assignment)
+ */
+
+void Dbg_RealLocation(Dbg_MCState *state, Dbg_Value *val);
+/* If val describes a register, this may really be a register, or a place on
+ the stack where the register's value is saved. In the latter case, val
+ is altered to describe the save place. (In all others, it remains
+ unchanged).
+ */
+
+Dbg_Error Dbg_DereferenceValue(Dbg_MCState *state, const Dbg_Value *value, Dbg_Constant *c);
+/* This fails if <value> describes a structure or array, returning
+ Dbg_Err_TypeNotSimple
+ */
+
+typedef struct Dbg_Expr Dbg_Expr;
+/* The result of parsing an expression in an environment: its structure is not
+ revealed. (Clients may wish to parse just once an expression which may be
+ evaluated often). In support of which, the following two functions partition
+ the work of Dbg_EvalExpr().
+ */
+
+#define Dbg_exfl_heap 1 /* allocate Expr on the heap (FreeExpr must then be
+ called to discard it). Otherwise, it goes in a
+ place overwritten by the next call to ParseExpr
+ or EvalExpr
+ */
+#define Dbg_exfl_needassign 2
+#define Dbg_exfl_lowlevel 4
+
+int Dbg_SetInputRadix(Dbg_MCState *state, int radix);
+char *Dbg_SetDefaultIntFormat(Dbg_MCState *state, char *format);
+
+Dbg_Error Dbg_ParseExpr(
+ Dbg_MCState *state, Dbg_Environment const *env, char *string,
+ char **end, Dbg_Expr **res, int flags);
+/* Just parse the argument string, returning a pointer to a parsed expression
+ and a pointer to the first non-white space character in the input string
+ which is not part of the parsed expression. (If macro expansion has taken
+ place, the returned pointer will not be into the argument string at all,
+ rather into the expanded version of it).
+ */
+
+Dbg_Error Dbg_ParseExprCheckEnd(
+ Dbg_MCState *state, Dbg_Environment const *env, char *string,
+ Dbg_Expr **res, int flags);
+/* As Dbg_ParseExpr, but the parsed expression is required completely to fill
+ the argument string (apart possibly for trailing whitespace), and an error
+ is returned if it does not.
+ */
+
+Dbg_Error Dbg_ParsedExprToValue(
+ Dbg_MCState *state, const Dbg_Environment *env, Dbg_Expr *expr, Dbg_Value *v);
+
+Dbg_Error Dbg_ReadDecl(
+ Dbg_MCState *state, Dbg_Environment const *env, char *string,
+ Dbg_TypeSpec *p, char **varp, int flags);
+/* Read a variable declaration, returing a description of the type of the
+ variable to p, and a pointer to its name to varp.
+ */
+
+bool Dbg_IsCastToArrayType(Dbg_MCState *state, Dbg_Expr *expr);
+
+void Dbg_FreeExpr(Dbg_Expr *expr);
+
+Dbg_Error Dbg_CopyType(Dbg_TypeSpec *tdest, Dbg_TypeSpec const *tsource);
+Dbg_Error Dbg_FreeCopiedType(Dbg_TypeSpec *ts);
+
+Dbg_Error Dbg_TypeOfExpr(Dbg_MCState *state, Dbg_Expr *tree, Dbg_TypeSpec *restype);
+
+Dbg_Error Dbg_ExprToVar(const Dbg_Expr *expr, Dbg_DeclSpec *var, Dbg_Environment *env);
+
+Dbg_Error Dbg_Assign(Dbg_MCState *state, const Dbg_Value *lv, const Dbg_Value *rv);
+
+typedef enum Dbg_TypeSort {
+ ts_simple,
+ ts_union,
+ ts_struct,
+ ts_array
+} Dbg_TypeSort;
+
+Dbg_TypeSort Dbg_TypeSortOfValue(Dbg_MCState *state, const Dbg_Value *val, int *fieldcount);
+
+Dbg_Error Dbg_TypeToChars(const Dbg_TypeSpec *var, Dbg_BufDesc *buf);
+
+Dbg_Error Dbg_TypeSize(Dbg_MCState *state, const Dbg_TypeSpec *type, unsigned32 *res);
+
+typedef int Dbg_ValToChars_cb(Dbg_MCState *state, Dbg_Value *subval, const char *fieldname,
+ Dbg_BufDesc *buf, void *arg);
+
+Dbg_Error Dbg_ValToChars(Dbg_MCState *state, Dbg_Value *val, int base,
+ Dbg_ValToChars_cb *cb, void *arg,
+ const char *form, Dbg_BufDesc *buf);
+/*
+ <base> is used for (any size) integer values.
+ If <val> is of an array or structure type, <cb> is called for each element,
+ with <arg> as its last parameter, and <subbuf> describing the space remaining
+ in <buf>. If <cb> returns 0, conversion ceases.
+ */
+
+Dbg_Error Dbg_NthElement(
+ Dbg_MCState *state,
+ const Dbg_Value *val, unsigned32 n, char **fieldname, Dbg_Value *subval);
+
+typedef Dbg_Error Dbg_HistoryProc(void *, int, Dbg_Value *);
+
+Dbg_Error Dbg_RegisterHistoryProc(Dbg_MCState *state, Dbg_HistoryProc *p, void *arg);
+
+typedef enum {
+ ls_cpu,
+ ls_store,
+ ls_copro,
+ ls_local,
+ ls_filtered
+} Dbg_LocSort;
+
+typedef struct {
+ Dbg_LocSort sort;
+ union {
+ struct { ARMaddress addr, size; } store;
+ struct { int modemask; int r; } cpu;
+ struct { int no; int r; } cp;
+ void *localp;
+ Dbg_AccessFnRec f;
+ } loc;
+} Dbg_Loc;
+
+typedef Dbg_Error Dbg_ObjectWriteProc(Dbg_MCState *state, Dbg_Loc const *loc);
+Dbg_Error Dbg_OnObjectWrite(Dbg_MCState *state, Dbg_ObjectWriteProc *p);
+/* Register function to be called back whenever the toolbox has written to any
+ * object accessible by the debuggee (or to local variables belonging to a
+ * toolbox client). The write has already been done.
+ * (To allow multiple toolbox clients to coexist).
+ */
+
+Dbg_Error Dbg_ObjectWritten(Dbg_MCState *state, Dbg_Loc const *loc);
+
+/*--------------------------------------------------------------------------*/
+
+/* Control of target program execution.
+ Currently, only synchronous operation is provided.
+ Execution could possibly be asynchronous where the target is a seperate
+ processor, but is necessarily synchronous if the target is Armulator.
+ Unfortunately, this may require modification to the RDI implementation
+ if multitasking is required but the the host system provides it only
+ cooperatively, or if there is no system-provided way to generate SIGINT.
+ */
+
+Dbg_Error Dbg_SetCommandline(Dbg_MCState *state, const char *args);
+/* Set the argument string to the concatenation of the name of the most
+ recently loaded image and args.
+ */
+
+typedef enum Dbg_ProgramState {
+ ps_notstarted,
+ /* Normal ways of stopping */
+ ps_atbreak, ps_atwatch, ps_stepdone,
+ ps_interrupted,
+ ps_stopped,
+ /* abnormal (but unsurprising) ways of stopping */
+ ps_lostwatch,
+ ps_branchthrough0, ps_undef, ps_caughtswi, ps_prefetch,
+ ps_abort, ps_addrexcept, ps_caughtirq, ps_caughtfiq,
+ ps_error,
+ /* only as a return value from Call() */
+ ps_callfailed, ps_callreturned,
+ /* internal inconsistencies */
+ ps_broken, /* target has "broken" */
+ ps_unknownbreak,
+ ps_unknown
+} Dbg_ProgramState;
+
+int Dbg_IsCallLink(Dbg_MCState *state, ARMaddress pc);
+
+typedef struct {
+ Dbg_FPRegVal fpres;
+ ARMword intres;
+} Dbg_CallResults;
+
+Dbg_CallResults *Dbg_GetCallResults(Dbg_MCState *state);
+
+#define Dbg_S_STATEMENTS 0
+#define Dbg_S_INSTRUCTIONS 1
+#define Dbg_S_STEPINTOPROCS 2
+
+Dbg_Error Dbg_Step(Dbg_MCState *state, int32 stepcount, int stepby, Dbg_ProgramState *status);
+/* <stepby> is a combination of the Dbg_S_... values above */
+
+Dbg_Error Dbg_StepOut(Dbg_MCState *state, Dbg_ProgramState *status);
+
+bool Dbg_CanGo(Dbg_MCState *state);
+
+bool Dbg_IsExecuting(Dbg_MCState *state);
+
+Dbg_Error Dbg_Go(Dbg_MCState *state, Dbg_ProgramState *status);
+
+Dbg_Error Dbg_Stop(Dbg_MCState *state);
+/* Asynchronous Stop request, for call from SIGINT handler. On return to the
+ caller, the call of Dbg_Go, Dbg_Step or Dbg_Call which started execution
+ should return ps_interrupted.
+ */
+
+typedef void Dbg_ExecuteProc(Dbg_MCState *state, Dbg_ProgramState status);
+Dbg_Error Dbg_OnExecute(Dbg_MCState *, Dbg_ExecuteProc *);
+/* Register function to be called back whenever execution stops.
+ * (To allow multiple toolbox clients to coexist).
+ */
+
+Dbg_Error Dbg_SetReturn(Dbg_MCState *state,
+ const Dbg_Environment *context, const Dbg_Value *value);
+/* Prepare continuation by returning <value> from the function activation
+ described by <context>. (Dbg_Go() or Dbg_Step() actually perform the
+ continuation).
+ */
+
+Dbg_Error Dbg_SetExecution(Dbg_MCState *state, Dbg_Environment *context);
+/* Set the pc in a high-level fashion */
+
+Dbg_Error Dbg_ProgramStateToChars(Dbg_MCState *state, Dbg_ProgramState event, Dbg_BufDesc *buf);
+/* This is guaranteed to give a completely accurate description of <event> if
+ this was the value returned by the most recent call of Dbg_Go, Dbg_Step,
+ or Dbg_Call.
+ */
+
+/*--------------------------------------------------------------------------*/
+
+Dbg_Error Dbg_CurrentEnvironment(Dbg_MCState *state, Dbg_Environment *context);
+
+Dbg_Error Dbg_PrevFrame(Dbg_MCState *state, Dbg_Environment *context);
+/* towards the base of the stack */
+
+Dbg_Error Dbg_NextFrame(Dbg_MCState *state, Dbg_Environment *context);
+/* away from the base of the stack */
+
+typedef struct Dbg_AnyPos {
+ enum { pos_source, pos_ll, pos_none } postype;
+ ARMaddress pc;
+ union {
+ Dbg_ProcPos source;
+ Dbg_LLPos ll;
+ ARMaddress none;
+ } pos;
+} Dbg_AnyPos;
+
+Dbg_Error Dbg_EnvironmentToPos(Dbg_MCState *state, const Dbg_Environment *context, Dbg_AnyPos *pos);
+/* <pos> is set to a Dbg_ProcPos if these is one corresponding to <context>
+ else a Dbg_LLPos if there is one.
+ */
+
+/*--------------------------------------------------------------------------*/
+
+/* Source file management.
+ Pretty vestigial. Handles source path (per loaded image),
+ and translates from line-number (as given in debugger tables) to character
+ position (as required to access files)
+ */
+
+Dbg_Error Dbg_ClearPaths(Dbg_MCState *state, Dbg_SymTable *st);
+Dbg_Error Dbg_AddPath(Dbg_MCState *state, Dbg_SymTable *st, const char *path);
+Dbg_Error Dbg_DeletePath(Dbg_MCState *state, Dbg_SymTable *st, const char *path);
+
+typedef enum {
+ Dbg_PathsCleared,
+ Dbg_PathAdded,
+ Dbg_PathDeleted
+} Dbg_PathAlteration;
+
+typedef void Dbg_PathAlteredProc(
+ Dbg_MCState *state, Dbg_SymTable *st, char const *path,
+ Dbg_PathAlteration sort);
+
+Dbg_Error Dbg_OnPathAlteration(Dbg_MCState *state, Dbg_PathAlteredProc *p);
+/* Register function to be called back whenever one of the source path
+ * modification functions above is called. (To allow multiple toolbox
+ * clients to coexist).
+ */
+
+typedef struct Dbg_FileRec Dbg_FileRec;
+typedef struct {
+ unsigned32 linecount;
+ Dbg_FileRec *handle;
+ char *fullname;
+} Dbg_FileDetails;
+
+Dbg_Error Dbg_GetFileDetails(
+ Dbg_MCState *state, const Dbg_File *fname, Dbg_FileDetails *res);
+Dbg_Error Dbg_FinishedWithFile(Dbg_MCState *state, Dbg_FileRec *handle);
+
+Dbg_Error Dbg_GetFileDetails_fr(
+ Dbg_MCState *state, Dbg_FileRec *handle, Dbg_FileDetails *res);
+/* Refresh details about the file associated with <handle> (in particular,
+ * its linecount).
+ */
+
+Dbg_Error Dbg_FileLineLength(
+ Dbg_MCState *state, Dbg_FileRec *handle, int32 lineno, int32 *len);
+/* Return to <len> the length of line <lineno> of the file associated with
+ * <handle> (without necessarily reading from the file).
+ */
+
+Dbg_Error Dbg_GetFileLine_fr(
+ Dbg_MCState *state, Dbg_FileRec *handle, int32 lineno, Dbg_BufDesc *buf);
+/* Return to <buf> the contents of line <lineno> of the file associated with
+ * <handle> (including its terminating newline).
+ */
+
+Dbg_Error Dbg_StartFileAccess(Dbg_MCState *state, Dbg_FileRec *handle);
+Dbg_Error Dbg_EndFileAccess(Dbg_MCState *state, Dbg_FileRec *handle);
+/* These two calls bracket a sequence of calls to GetFileLine. Between the
+ * calls, the toolbox is permitted to retain state allowing more rapid
+ * access to text on the file associated with <handle>.
+ */
+
+Dbg_Error Dbg_ControlSourceFileAccess(
+ Dbg_MCState *state, uint32 cachesize, bool closefiles);
+/* Control details of how the toolbox manages source files.
+ * If <cachesize> is non-zero, the text from the most recently accessed
+ * source files (of total size not to exceed <cachesize>) is saved in
+ * store on first access to the file; subsequent access to the text of
+ * the file uses this copy.
+ * If <closefiles> is true, no stream is left attached to uncached source
+ * files after Dbg_EndFileAccess has been closed. Otherwise, the toolbox
+ * may retain such streams, in order to improve access.
+ */
+
+/*--------------------------------------------------------------------------*/
+
+/* disassembly */
+
+/*
+ ? More exact control is wanted here, but that requires a more complicated
+ ? disass callback interface.
+ */
+
+typedef const char *Dbg_SWI_Decode(Dbg_MCState *state, ARMword swino);
+
+Dbg_Error Dbg_InstructionAt(Dbg_MCState *state, ARMaddress addr,
+ int isize, ARMhword *inst, Dbg_SymTable *st,
+ Dbg_SWI_Decode *swi_name, Dbg_BufDesc *buf, int *length);
+/* <isize> describes the form of disassembly wanted: 2 for 16-bit, 4 for 32-bit,
+ * 0 for 16- or 32-bit depending whether addr addresses 16- or 32-bit code.
+ * <inst> is a pointer to a pair of halfwords *in target byte order*
+ * Possibly only the first halfword will be consumed: the number of bytes used
+ * is returned via <length>.
+ */
+
+/*--------------------------------------------------------------------------*/
+
+int Dbg_RDIOpen(Dbg_MCState *state, unsigned type);
+int Dbg_RDIInfo(Dbg_MCState *state, unsigned type, ARMword *arg1, ARMword *arg2);
+
+/*--------------------------------------------------------------------------*/
+
+typedef enum {
+ Dbg_Point_Toolbox,
+ Dbg_Point_RDI_Unknown,
+ Dbg_Point_RDI_SW,
+ Dbg_Point_RDI_HW
+} Dbg_PointType;
+
+/* breakpoint management
+ Associated with a breakpoint there may be any of
+ a count
+ an expression
+ a function
+ the breakpoint is activated if
+ the expression evaluates to a non-zero value (or fails to evaluate).
+ && decrementing the count reaches zero (the count is then reset to its
+ initial value).
+ && the function, called with the breakpoint address as argument, returns
+ a non-zero value.
+? (The order here may be open to debate. Note that the first two are in
+ the opposite order in armsd, but I think this order more rational)
+ */
+
+typedef enum Dbg_BreakPosType {
+ bt_procpos,
+ bt_procexit,
+ bt_address
+} Dbg_BreakPosType;
+
+typedef union {
+ Dbg_ProcPos procpos;
+ Dbg_ProcDesc procexit;
+ ARMaddress address;
+} Dbg_BreakPosPos;
+
+typedef struct Dbg_BreakPos {
+ Dbg_BreakPosType sort;
+ Dbg_BreakPosPos loc;
+} Dbg_BreakPos;
+
+typedef int Dbg_BPProc(Dbg_MCState *state, void *BPArg, Dbg_BreakPos *where);
+
+typedef struct Dbg_BreakStatus {
+ int index;
+ int initcount, countnow;
+ Dbg_BreakPos where;
+ char *expr;
+ Dbg_BPProc *p; void *p_arg;
+ int incomplete;
+ Dbg_PointType type;
+ ARMword hwresource;
+} Dbg_BreakStatus;
+
+Dbg_Error Dbg_StringToBreakPos(
+ Dbg_MCState *state, Dbg_Environment *env, char const *str, size_t len,
+ Dbg_BreakPos *bpos, char *b);
+
+Dbg_Error Dbg_SetBreakPoint(Dbg_MCState *state, Dbg_BreakPos *where,
+ int count,
+ const char *expr,
+ Dbg_BPProc *p, void *arg);
+Dbg_Error Dbg_SetBreakPoint16(Dbg_MCState *state, Dbg_BreakPos *where,
+ int count,
+ const char *expr,
+ Dbg_BPProc *p, void *arg);
+Dbg_Error Dbg_SetBreakPointNaturalSize(Dbg_MCState *state, Dbg_BreakPos *where,
+ int count,
+ const char *expr,
+ Dbg_BPProc *p, void *arg);
+/* Setting a breakpoint at the same address as a previous breakpoint
+ completely removes the previous one.
+ */
+
+Dbg_Error Dbg_DeleteBreakPoint(Dbg_MCState *state, Dbg_BreakPos *where);
+
+Dbg_Error Dbg_SuspendBreakPoint(Dbg_MCState *state, Dbg_BreakPos *where);
+/* Temporarily remove the break point (until Reinstated) but leave intact
+ its associated expr, the value its count has reached, etc.
+? The debugger toolbox itself wants this, but I'm not sure what use a client
+ could have for it. Ditto Reinstate...
+ */
+
+Dbg_Error Dbg_ReinstateBreakPoint(Dbg_MCState *state, Dbg_BreakPos *where);
+/* Undo the effect of Dbg_SuspendBreakPoint
+ */
+
+Dbg_Error Dbg_DeleteAllBreakPoints(Dbg_MCState *state);
+
+Dbg_Error Dbg_SuspendAllBreakPoints(Dbg_MCState *state);
+
+Dbg_Error Dbg_ReinstateAllBreakPoints(Dbg_MCState *state);
+
+typedef Dbg_Error Dbg_BPEnumProc(Dbg_MCState *state, Dbg_BreakStatus *status, void *arg);
+
+Dbg_Error Dbg_EnumerateBreakPoints(Dbg_MCState *state, Dbg_BPEnumProc *p, void *arg);
+
+Dbg_Error Dbg_BreakPointStatus(Dbg_MCState *state,
+ const Dbg_BreakPos *where, Dbg_BreakStatus *status);
+
+typedef void Dbg_BreakAlteredProc(Dbg_MCState *state, ARMaddress addr, bool set);
+Dbg_Error Dbg_OnBreak(Dbg_MCState *state, Dbg_BreakAlteredProc *p);
+/* Register function to be called back whenever a breakpoint is set or
+ * cleared. (To allow multiple toolbox clients to coexist).
+ */
+
+bool Dbg_StoppedAtBreakPoint(Dbg_MCState *state, const Dbg_BreakPos *where);
+/* Called after execution which resulted in ps_atbreak, to find out whether
+ the specified breakpoint was hit (could be >1, eg. exit break and another
+ high-level breakpoint at the same position).
+ Returns NO if specified breakpoint not found, or execution didn't stop
+ with ps_atbreak status.
+ */
+
+/*--------------------------------------------------------------------------*/
+
+typedef struct {
+ Dbg_Value val;
+ char *name;
+} Dbg_WatchPos;
+
+typedef int Dbg_WPProc(Dbg_MCState *state, void *WPArg, Dbg_WatchPos *where);
+
+typedef struct Dbg_WPStatus {
+ int index;
+ int initcount, countnow;
+ Dbg_WatchPos what, target;
+ char *expr;
+ Dbg_WPProc *p; void *p_arg;
+ Dbg_PointType type;
+ ARMword hwresource;
+ int skip;
+} Dbg_WPStatus;
+
+Dbg_Error Dbg_SetWatchPoint(
+ Dbg_MCState *state, Dbg_Environment *context, char const *watchee,
+ char const *target,
+ int count,
+ char const *expr,
+ Dbg_WPProc *p, void *arg);
+
+/* Cause a watchpoint event if the value of <watchee> changes to the value of
+ <target> (or changes at all if <target> is NULL). <watchee> should
+ evaluate either to an L-value (when the size of the object being watched is
+ determined by its type) or to an integer constant (when the word with this
+ address is watched).
+ */
+
+Dbg_Error Dbg_DeleteWatchPoint(Dbg_MCState *state, Dbg_Environment *context, char const *watchee);
+
+
+Dbg_Error Dbg_SetWatchPoint_V(
+ Dbg_MCState *state,
+ char const *name, Dbg_Value const *val, char const *tname, Dbg_Value const *tval,
+ int count,
+ char const *expr,
+ Dbg_WPProc *p, void *arg);
+
+Dbg_Error Dbg_DeleteWatchPoint_V(Dbg_MCState *state, Dbg_Value const *val);
+
+
+Dbg_Error Dbg_DeleteAllWatchPoints(Dbg_MCState *state);
+
+typedef Dbg_Error Dbg_WPEnumProc(Dbg_MCState *state, Dbg_WPStatus const *watchee, void *arg);
+
+Dbg_Error Dbg_EnumerateWatchPoints(Dbg_MCState *state, Dbg_WPEnumProc *p, void *arg);
+
+Dbg_Error Dbg_WatchPointStatus(Dbg_MCState *state,
+ Dbg_WatchPos const *where, Dbg_WPStatus *status);
+
+typedef void Dbg_WPRemovedProc(void *arg, Dbg_WPStatus const *wp);
+Dbg_Error Dbg_RegisterWPRemovalProc(Dbg_MCState *state, Dbg_WPRemovedProc *p, void *arg);
+/* When a watchpoint goes out of scope it is removed by the toolbox, and the
+ function registered here gets called back to adjust its view
+ */
+
+typedef void Dbg_WatchAlteredProc(Dbg_MCState *state, Dbg_Value const *where, bool set);
+Dbg_Error Dbg_OnWatch(Dbg_MCState *state, Dbg_WatchAlteredProc *p);
+/* Register function to be called back whenever a watchpoint is set or
+ * cleared. (To allow multiple toolbox clients to coexist).
+ */
+
+/*--------------------------------------------------------------------------*/
+
+Dbg_Error Dbg_ProfileLoad(Dbg_MCState *state);
+
+Dbg_Error Dbg_ProfileStart(Dbg_MCState *state, ARMword interval);
+Dbg_Error Dbg_ProfileStop(Dbg_MCState *state);
+
+Dbg_Error Dbg_ProfileClear(Dbg_MCState *state);
+
+Dbg_Error Dbg_WriteProfile(Dbg_MCState *state, char const *filename,
+ char const *toolid, char const *arg);
+
+/*--------------------------------------------------------------------------*/
+
+Dbg_Error Dbg_ConnectChannel_ToHost(Dbg_MCState *state, RDICCProc_ToHost *p, void *arg);
+Dbg_Error Dbg_ConnectChannel_FromHost(Dbg_MCState *state, RDICCProc_FromHost *p, void *arg);
+
+/*--------------------------------------------------------------------------*/
+
+/* Configuration data management */
+
+Dbg_Error Dbg_LoadConfigData(Dbg_MCState *state, char const *filename);
+
+Dbg_Error Dbg_SelectConfig(
+ Dbg_MCState *state,
+ RDI_ConfigAspect aspect, char const *name, RDI_ConfigMatchType matchtype,
+ unsigned versionreq, unsigned *versionp);
+
+Dbg_Error Dbg_ParseConfigVersion(
+ char const *s, RDI_ConfigMatchType *matchp, unsigned *versionp);
+
+typedef Dbg_Error Dbg_ConfigEnumProc(Dbg_MCState *state, RDI_ConfigDesc const *desc, void *arg);
+
+Dbg_Error Dbg_EnumerateConfigs(Dbg_MCState *state, Dbg_ConfigEnumProc *p, void *arg);
+
+/*--------------------------------------------------------------------------*/
+
+/* Angel OS support */
+
+Dbg_Error Dbg_CreateTask(Dbg_MCState **statep, Dbg_MCState *parent, bool inherit);
+/* This is called when a task is to be debugged which has not been debugged
+ before - ie. there is no existing Dbg_MCState for this task. It
+ initialises a new Dbg_MCState and returns a pointer to it.
+ <parent> is any valid previously-created MCCState. If <inherit> is TRUE,
+ the new MCState inherits certain features from it (eg. symbols).
+ Otherwise, only features which are the same across all tasks are inherited,
+ (eg. global breakpoints).
+ */
+
+Dbg_Error Dbg_DeleteTask(Dbg_MCState *state);
+/* This is called when a task dies, and frees up everything which relates to that
+ task which is controlled by armdbg.
+ */
+
+Dbg_Error Dbg_DetachTask(Dbg_MCState *state);
+
+Dbg_Error Dbg_AttachTask(Dbg_MCState *state);
+/* These are called to request a switch of the current task. First
+ Dbg_DetachTask should be called with the state of the old task.
+ Dbg_DetachTask will ensure that any cached state held by armdbg for
+ the old task is immediately written out to the target.
+
+ After Dbg_DetachTask is called and before Dbg_AttachTask is called
+ the OS channel manager should tell the target that any future
+ requests from the debugger will be fore the new task.
+
+ If the new task does not have an armdbg state structure
+ already, then Dbg_CreateTask should be called to create one (see
+ above). Then Dbg_AttachTask is called to tell armdbg to treat the
+ new armdbg state as the current task.
+ */
+
+typedef Dbg_Error Dbg_TaskSwitchProc(void *arg, Dbg_MCState *newstate);
+
+Dbg_Error Dbg_OnTaskSwitch(Dbg_MCState *state, Dbg_TaskSwitchProc *fn, void *arg);
+/* The front end may register a callback which gets called by armdbg whenever
+ Dbg_AttachTask is called. This callback tells the front end the new current
+ Dbg_MCState it should use to call armdbg.
+ [Note that this is only useful if there is one front end shared between all
+ tasks rather than one front end per task]
+ The value of <arg> passed to Dbg_OnTaskSwitch is passed to <fn>
+ when it is called.
+ */
+
+typedef Dbg_Error Dbg_RestartProc(
+ void *arg, Dbg_MCState *curstate, Dbg_MCState **newstate);
+
+Dbg_Error Dbg_OnRestart(Dbg_MCState *state, Dbg_RestartProc *fn, void *arg);
+/* This is used by the OS channels layer to register a callback which
+ will be made by the debugger toolbox early in the process of resuming
+ execution.
+
+ This callback must determine which task will be resumed when the target
+ restarts execution. If this is not already the current task then it must
+ call Dbg_DetachTask and Dbg_AttachTask as decribed above to switch to the
+ task about to be resumed and return the state for the new task in
+ <newstate>.
+
+ This will ensure that armdbg updates the correct task on execution as well
+ as ensuring that stepping over a breakpointed instruction on restarting
+ happens correctly.
+
+ The value of <arg> passed to Dbg_OnRestart is passed to <fn>
+ when it is called.
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/* End of armdbg.h */
diff --git a/gdb/rdi-share/buffers.h b/gdb/rdi-share/buffers.h
new file mode 100644
index 00000000000..78549de0097
--- /dev/null
+++ b/gdb/rdi-share/buffers.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Public interface to buffer management
+ */
+
+#ifndef angel_buffers_h
+#define angel_buffers_h
+
+#include "chandefs.h" /* CHAN_HEADER_SIZE */
+
+
+/* the handle to a buffer */
+typedef unsigned char *p_Buffer;
+
+
+/*
+ * Angel Packets are structured as a fixed size header, followed
+ * by the packet data
+ */
+#ifdef TARGET
+# define BUFFERDATA(b) (b) /* channels layer takes care of it */
+#else
+# define BUFFERDATA(b) (&((b)[CHAN_HEADER_SIZE]))
+#endif
+
+
+/*
+ * The buffer management function prototypes are only applicable
+ * when compiling target code
+ */
+#ifdef TARGET
+
+/*
+ * Function: Angel_BufferQuerySizes
+ * Purpose: Request infomation on the default and maximum buffer sizes
+ * that can be allocated
+ *
+ * Params:
+ * In/Out: default_size, max_size: pointers to place the
+ * sizes in on return
+ */
+
+void Angel_BufferQuerySizes(unsigned int *default_size,
+ unsigned int *max_size );
+
+/*
+ * Function: Angel_RxEnginBuffersLeft
+ * Purpose: return the number of free buffers
+ *
+ * Params:
+ * Returns: number of free buffers
+ */
+unsigned int Angel_BuffersLeft( void );
+
+/*
+ * Function: Angel_BufferAlloc
+ * Purpose: allocate a buffer that is at least req_size bytes long
+ *
+ * Params:
+ * Input: req_size the required size of the buffer
+ *
+ * Returns: pointer to the buffer NULL if unable to
+ * fulfil the request
+ */
+p_Buffer Angel_BufferAlloc(unsigned int req_size);
+
+/*
+ * Function: Angel_BufferRelease
+ * Purpose: release a buffer back to the free pool
+ *
+ * Params:
+ * Input: pointer to the buffer to free
+ */
+void Angel_BufferRelease(p_Buffer buffer);
+
+
+/* return values for angel_InitBuffers */
+typedef enum buf_init_error{
+ INIT_BUF_OK,
+ INIT_BUF_FAIL
+} buf_init_error;
+
+/*
+ * Function: Angel_InitBuffers
+ * Purpose: Initalised and malloc the buffer pool
+ *
+ * Params:
+ * Returns: see above
+ */
+
+buf_init_error Angel_InitBuffers(void);
+
+#endif /* def TARGET */
+
+#endif /* ndef angel_buffers_h */
+
+/* EOF buffers.h */
diff --git a/gdb/rdi-share/chandefs.h b/gdb/rdi-share/chandefs.h
new file mode 100644
index 00000000000..d97f0b5bcef
--- /dev/null
+++ b/gdb/rdi-share/chandefs.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Enumeration with all supported channels
+ */
+
+#ifndef angel_chandefs_h
+#define angel_chandefs_h
+
+enum channelIDs {
+ CI_PRIVATE = 0, /* channels protocol control messages */
+ CI_HADP, /* ADP, host originated */
+ CI_TADP, /* ADP, target originated */
+ CI_HBOOT, /* Boot, host originated */
+ CI_TBOOT, /* Boot, target originated */
+ CI_CLIB, /* Semihosting C library support */
+ CI_HUDBG, /* User debug support, host originated */
+ CI_TUDBG, /* User debug support, target originated */
+ CI_HTDCC, /* Thumb direct comms channel, host orig. */
+ CI_TTDCC, /* Thumb direct comms channel, target orig. */
+ CI_TLOG, /* Target debug/logging */
+ CI_NUM_CHANNELS
+};
+
+typedef unsigned ChannelID;
+
+
+/*
+ * Size in bytes of the channel header.
+ * This is a duplicate of XXX in chanpriv.h, but we don't want everyone
+ * to have access to all of chanpriv.h, so we'll double-check in chanpriv.h.
+ */
+#define CHAN_HEADER_SIZE (4)
+
+#endif /* ndef angel_chandefs_h */
+
+/* EOF chandefs.h */
diff --git a/gdb/rdi-share/channels.h b/gdb/rdi-share/channels.h
new file mode 100644
index 00000000000..b43ebc10a65
--- /dev/null
+++ b/gdb/rdi-share/channels.h
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: User interface to the channels layer
+ */
+
+#ifndef angel_channels_h
+#define angel_channels_h
+
+/*
+ * This provides the public interface to the channels layer read and write
+ * routines, and buffer management routines.
+ */
+
+/* Nested header files, if required */
+
+#include "devices.h"
+#include "chandefs.h"
+#include "adperr.h"
+
+/* General purpose constants, macros, enums, typedefs */
+
+/* use the default device */
+#define CH_DEFAULT_DEV ((DeviceID)-1)
+
+/* return codes */
+typedef enum ChanError {
+ CE_OKAY, /* no error */
+ CE_ABANDONED, /* abandoned due to device switch */
+ CE_DEV_ERROR, /* unexpected error from device driver */
+ CE_BUSY, /* channel in use */
+ CE_BUFF_ERROR, /* unable to get buffer */
+ CE_PRIVATE /* start of internal error codes */
+} ChanError;
+
+
+/* Publically-accessible globals */
+
+/*
+ * The following two globals are only valid after angel_InitialiseChannels()
+ * has been called.
+ */
+
+/* the default size of a channel buffer, for global use */
+extern unsigned Angel_ChanBuffSize;
+
+/* the size of a long buffer, for global use */
+extern unsigned Angel_ChanLongSize;
+
+#ifdef TARGET
+AdpErrs send_resend_msg(DeviceID devid);
+#endif
+
+/*
+ * Function: angel_InitialiseChannels
+ * Purpose: initialise the channels layer
+ *
+ * Params:
+ * Input: -
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: -
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ */
+
+void angel_InitialiseChannels( void );
+
+/*
+ * Function: adp_init_seq
+ * Purpose: initialise sequence numbers and free anyt leftover buffers
+ *
+ * Params:
+ * Input: -
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: - adp_ok if things went ok else an error code
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ */
+
+AdpErrs adp_init_seq(void);
+
+/*
+ * Function: angel_ChannelAllocBuffer
+ * Purpose: allocate a buffer that is at least req_size bytes long
+ *
+ * Params:
+ * Input: req_size the minimum size required
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: pointer to allocated buffer, or
+ * NULL if unable to allocate suitable buffer
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ */
+
+p_Buffer angel_ChannelAllocBuffer(unsigned req_size);
+
+
+/*
+ * Function: angel_ChannelReleaseBuffer
+ * Purpose: release a buffer back to the free pool
+ *
+ * Params:
+ * Input: buffer the buffer to release
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: -
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ */
+
+void angel_ChannelReleaseBuffer(p_Buffer buffer);
+
+
+/*
+ * Function: angel_ChannelSend
+ * Purpose: blocking send of a packet via a channel
+ *
+ * Params:
+ * Input: devid Device to use, or CH_DEFAULT_DEV
+ * chanid Channel to use for tx
+ * buffer Pointer to data to send
+ * len Length of data to send
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Transmission completed
+ * CE_BAD_CHAN Channel id invalid
+ * CE_ABANDONED Tx abandoned due to device switch
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ */
+
+ChanError angel_ChannelSend(DeviceID devid, ChannelID chanid,
+ const p_Buffer buffer, unsigned len);
+
+
+/*
+ * Function: angel_ChannelSendAsync
+ * Purpose: asynchronous send of a packet via a channel
+ *
+ * Params:
+ * Input: devid Device to use, or CH_DEFAULT_DEV
+ * chanid Channel to use for tx
+ * buffer Pointer to data to send
+ * len Length of data to send
+ * callback Function to call on completion
+ * callback_data Pointer to pass to callback
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Transmission underway
+ * CE_BAD_CHAN Channel id invalid
+ * CE_ABANDONED Tx abandoned due to device switch
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * register an asynchronous send on the given channel
+ * (blocks until send can be commenced)
+ */
+
+typedef void (*ChanTx_CB_Fn)(ChannelID chanid, /* which channel */
+ void *callback_data); /* as supplied... */
+
+
+ChanError angel_ChannelSendAsync( DeviceID devid,
+ ChannelID chanid,
+ const p_Buffer buffer,
+ unsigned len,
+ ChanTx_CB_Fn callback,
+ void *callback_data);
+
+
+/*
+ * Function: angel_ChannelRead
+ * Purpose: blocking read of a packet from a channel
+ *
+ * Params:
+ * Input: devid Device to use, or CH_DEFAULT_DEV
+ * chanid Channel to use for rx
+ * Output: buffer The buffer, supplied and filled
+ * len How many bytes there are in the buffer
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Reception successful
+ * CE_BAD_CHAN Channel id invalid
+ * CE_ABANDONED Tx abandoned due to device switch
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * Note that in the present version, if an asynchronous read has been
+ * registered, a blocking read will be refused with CE_BUSY.
+ */
+ChanError angel_ChannelRead(DeviceID devid,
+ ChannelID chanid,
+ p_Buffer *buffer,
+ unsigned *len);
+
+
+/*
+ * Function: angel_ChannelReadAsync
+ * Purpose: asynchronous read of a packet via a channel
+ *
+ * Params:
+ * Input: devid Device to use, or CH_DEFAULT_DEV
+ * chanid Channel to wait on
+ * callback Function to call on completion, or NULL
+ * callback_data Pointer to pass to callback
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Read request registered
+ * CE_BAD_CHAN Channel id invalid
+ * CE_BUSY Someone else is using the channel
+ * (in a single threaded world)
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * Register an asynchronous read on the given channel. There can only be one
+ * async. reader per channel, and blocking reads are not permitted whilst
+ * an async. reader is registered.
+ *
+ * Reader can unregister by specifying NULL as the callback function.
+ */
+
+typedef void (*ChanRx_CB_Fn)(DeviceID devID, /* ID of receiving device */
+ ChannelID chanID, /* ID of receiving channel */
+ p_Buffer buff, /* pointer to buffer */
+ unsigned len, /* length of data */
+ void *cb_data /* callback data */
+ );
+
+ChanError angel_ChannelReadAsync(DeviceID devid,
+ ChannelID chanid,
+ ChanRx_CB_Fn callback,
+ void *callback_data);
+
+
+/*
+ * Function: angel_ChannelReadAll
+ * Purpose: register an asynchronous read across all devices
+ *
+ * Params:
+ * Input: chanid Channel to look for (usually HBOOT)
+ * callback Function to call on completion
+ * callback_data Pointer to pass to callback
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Read request registered
+ * CE_BAD_CHAN Channel id invalid
+ * CE_BUSY Someone else is reading all devices
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * Register an asynchronous read across all devices. This is a 'fallback',
+ * which will be superseded (temporarily) by a registered reader or blocking
+ * read on a specific device.
+ */
+
+ChanError angel_ChannelReadAll( ChannelID chanid,
+ ChanRx_CB_Fn callback,
+ void *callback_data);
+
+
+
+/*
+ * Function: angel_ChannelSendThenRead
+ * Purpose: blocking write to followed by read from a channel
+ *
+ * Params:
+ * Input: devid Device to use, or CH_DEFAULT_DEV
+ * chanid Channel to use for rx
+ * In/Out: buffer On entry: the packet to be sent
+ * On return: the packet received
+ * len On entry: length of packet to be sent
+ * On return: length of packet rx'd
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Tx and Reception successful
+ * CE_BAD_CHAN Channel id invalid
+ * CE_ABANDONED Tx abandoned due to device switch
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * Note that in the present version, if an asynchronous read has been
+ * registered, this will be refused with CE_BUSY.
+ */
+ChanError angel_ChannelSendThenRead(DeviceID devid,
+ ChannelID chanid,
+ p_Buffer *buffer,
+ unsigned *len);
+
+
+/*
+ * Function: angel_ChannelSelectDevice
+ * Purpose: select the device to be used for all channel comms
+ *
+ * Params:
+ * Input: device ID of device to use as the default
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Default device selected
+ * CE_BAD_DEV Invalid device ID
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: Any channel operations in progress are
+ * abandoned.
+ *
+ * select the device for all channels comms
+ */
+
+ChanError angel_ChannelSelectDevice(DeviceID device);
+
+
+/*
+ * Function: angel_ChannelReadActiveDevice
+ * Purpose: reads the device id of the currently active device
+ *
+ * Params:
+ * Input: device address of a DeviceID variable
+ * Output: *device ID of device currently being used
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Default device selected
+ */
+
+ChanError angel_ChannelReadActiveDevice(DeviceID *device);
+
+#endif /* ndef angel_channels_h */
+
+/* EOF channels.h */
diff --git a/gdb/rdi-share/chanpriv.h b/gdb/rdi-share/chanpriv.h
new file mode 100644
index 00000000000..155e864e297
--- /dev/null
+++ b/gdb/rdi-share/chanpriv.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Private header for channels implementations
+ */
+
+#ifndef angel_chanpriv_h
+#define angel_chanpriv_h
+
+/*
+ * This describes the internal structure and flags for a channels packet.
+ */
+
+/* byte positions within channel packet */
+#define CF_CHANNEL_BYTE_POS 0
+#define CF_HOME_SEQ_BYTE_POS 1
+#define CF_OPPO_SEQ_BYTE_POS 2
+#define CF_FLAGS_BYTE_POS 3
+#define CF_DATA_BYTE_POS 4
+
+/* flags for FLAGS field */
+#define CF_RELIABLE (1 << 0) /* use reliable channels protocol */
+#define CF_RESEND (1 << 1) /* this is a renegotiation packet */
+#define CF_HEARTBEAT (1 << 2) /* heartbeat packet - prod target into sync */
+
+/* byte positions within buffer */
+#define CB_LINK_BYTE_POS 0 /* the link pointer */
+#define CB_CHAN_HEADER_BYTE_POS 4 /* the channel frame starts here */
+
+/* macro to get buffer position of packet component */
+#define CB_PACKET(x) (CB_CHAN_HEADER_BYTE_POS + (x))
+
+/* byte offset of packet data within buffer */
+#define CB_CHAN_DATA_BYTE_POS (CB_PACKET(CF_DATA_BYTE_POS))
+
+/* access the link in a buffer, where b is byte pointer to buffer */
+#define CB_LINK(b) ((p_Buffer)(&(b)[0]))
+
+#define invalidChannelID(chan) (((int)(chan)) < 0 || \
+ (chan) >= CI_NUM_CHANNELS)
+
+#endif /* ndef angel_chanpriv_h */
+
+/* EOF chanpriv.h */
diff --git a/gdb/rdi-share/configure b/gdb/rdi-share/configure
new file mode 100755
index 00000000000..e85f4f80cd4
--- /dev/null
+++ b/gdb/rdi-share/configure
@@ -0,0 +1,2115 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.2
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.2"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=adp.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:560: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ 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
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:614: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:671: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=rdi-share
+
+VERSION=1.0
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:717: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:730: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:743: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:756: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:769: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+PACKAGE=rdi-share
+VERSION=1.0
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:789: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:818: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:868: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:899: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 909 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:913: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:933: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:938: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:947: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+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
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:966: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1009: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ 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
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:1060: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1089: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1118: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1133 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1139: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1150 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1156: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1167 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1173: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1198: checking for ANSI C header files" >&5
+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 1203 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1211: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+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 1228 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+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 1246 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1267 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1278: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in fcntl.h sys/ioctl.h sys/time.h unistd.h sys/filio.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1305: checking for $ac_hdr" >&5
+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 1310 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1315: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+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 | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1343: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1348 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1397: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:1418: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1423 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:1451: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1456 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:1465: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+
+if test $ac_cv_prog_gcc = yes; then
+ echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
+echo "configure:1488: checking whether ${CC-cc} needs -traditional" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_pattern="Autoconf.*'x'"
+ cat > conftest.$ac_ext <<EOF
+#line 1494 "configure"
+#include "confdefs.h"
+#include <sgtty.h>
+Autoconf TIOCGETP
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$ac_pattern" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=yes
+else
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+ if test $ac_cv_prog_gcc_traditional = no; then
+ cat > conftest.$ac_ext <<EOF
+#line 1512 "configure"
+#include "confdefs.h"
+#include <termio.h>
+Autoconf TCGETA
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$ac_pattern" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+ fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
+ if test $ac_cv_prog_gcc_traditional = yes; then
+ CC="$CC -traditional"
+ fi
+fi
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:1534: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1539 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:1556: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_signal=void
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+echo $ac_n "checking for vprintf""... $ac_c" 1>&6
+echo "configure:1575: checking for vprintf" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1580 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char vprintf(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char vprintf();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_vprintf) || defined (__stub___vprintf)
+choke me
+#else
+vprintf();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1603: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_vprintf=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_vprintf=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_VPRINTF 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test "$ac_cv_func_vprintf" != yes; then
+echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
+echo "configure:1627: checking for _doprnt" >&5
+if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1632 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char _doprnt(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char _doprnt();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+_doprnt();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1655: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func__doprnt=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func__doprnt=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_DOPRNT 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+for ac_func in gettimeofday select socket strtod strtoul memcpy memmove
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1682: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1687 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1710: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:1736: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINT=
+ else
+ MAINT='#M#'
+ fi
+
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:1754: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'am_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1759 "configure"
+#include "confdefs.h"
+
+int main() {
+return __CYGWIN32__;
+; return 0; }
+EOF
+if { (eval echo configure:1766: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ am_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ am_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$am_cv_cygwin" 1>&6
+CYGWIN=
+test "$am_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for Mingw32 environment""... $ac_c" 1>&6
+echo "configure:1783: checking for Mingw32 environment" >&5
+if eval "test \"`echo '$''{'am_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1788 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:1795: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ am_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ am_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$am_cv_mingw32" 1>&6
+MINGW32=
+test "$am_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:1814: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'am_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+am_cv_exeext=.exe
+else
+cat > am_c_test.c << 'EOF'
+int main() {
+/* Nothing needed here */
+}
+EOF
+${CC-cc} -o am_c_test $CFLAGS $CPPFLAGS $LDFLAGS am_c_test.c $LIBS 1>&5
+am_cv_exeext=
+for file in am_c_test.*; do
+ case $file in
+ *.c) ;;
+ *.o) ;;
+ *) am_cv_exeext=`echo $file | sed -e s/am_c_test//` ;;
+ esac
+done
+rm -f am_c_test*
+fi
+
+test x"${am_cv_exeext}" = x && am_cv_exeext=no
+fi
+EXEEXT=""
+test x"${am_cv_exeext}" != xno && EXEEXT=${am_cv_exeext}
+echo "$ac_t""${am_cv_exeext}" 1>&6
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.12.2"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@CC@%$CC%g
+s%@RANLIB@%$RANLIB%g
+s%@CPP@%$CPP%g
+s%@MAINT@%$MAINT%g
+s%@EXEEXT@%$EXEEXT%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/rdi-share/configure.in b/gdb/rdi-share/configure.in
new file mode 100644
index 00000000000..bbda5ccbad0
--- /dev/null
+++ b/gdb/rdi-share/configure.in
@@ -0,0 +1,36 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.12.1)
+AC_INIT(adp.h)
+
+AM_INIT_AUTOMAKE(rdi-share, 1.0)
+
+PACKAGE=rdi-share
+VERSION=1.0
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+
+dnl Checks for libraries.
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS(fcntl.h sys/ioctl.h sys/time.h unistd.h sys/filio.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+
+dnl Checks for library functions.
+AC_PROG_GCC_TRADITIONAL
+AC_TYPE_SIGNAL
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS(gettimeofday select socket strtod strtoul memcpy memmove)
+
+AM_MAINTAINER_MODE
+AM_EXEEXT
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/rdi-share/crc.c b/gdb/rdi-share/crc.c
new file mode 100644
index 00000000000..cfa6522e8d2
--- /dev/null
+++ b/gdb/rdi-share/crc.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * crc.c - provides some "standard" CRC calculation routines.
+ *
+ */
+#include "crc.h" /* describes this code */
+
+/**********************************************************************/
+
+/*
+ * crc32 IEEE-802.3 32bit CRC
+ * ----- --------------------
+ */
+
+/* This table was generated by the "crctable" program */
+static const unsigned int crc32table[256] = {
+ /* 0x00 */ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
+ /* 0x04 */ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+ /* 0x08 */ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+ /* 0x0C */ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+ /* 0x10 */ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
+ /* 0x14 */ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ /* 0x18 */ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
+ /* 0x1C */ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+ /* 0x20 */ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+ /* 0x24 */ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ /* 0x28 */ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
+ /* 0x2C */ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+ /* 0x30 */ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
+ /* 0x34 */ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ /* 0x38 */ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+ /* 0x3C */ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+ /* 0x40 */ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
+ /* 0x44 */ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ /* 0x48 */ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
+ /* 0x4C */ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ /* 0x50 */ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+ /* 0x54 */ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+ /* 0x58 */ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
+ /* 0x5C */ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+ /* 0x60 */ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
+ /* 0x64 */ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+ /* 0x68 */ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+ /* 0x6C */ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+ /* 0x70 */ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
+ /* 0x74 */ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ /* 0x78 */ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
+ /* 0x7C */ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+ /* 0x80 */ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+ /* 0x84 */ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+ /* 0x88 */ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+ /* 0x8C */ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+ /* 0x90 */ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
+ /* 0x94 */ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+ /* 0x98 */ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+ /* 0x9C */ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ /* 0xA0 */ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
+ /* 0xA4 */ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ /* 0xA8 */ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
+ /* 0xAC */ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+ /* 0xB0 */ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+ /* 0xB4 */ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+ /* 0xB8 */ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
+ /* 0xBC */ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+ /* 0xC0 */ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
+ /* 0xC4 */ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ /* 0xC8 */ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+ /* 0xCC */ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+ /* 0xD0 */ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
+ /* 0xD4 */ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ /* 0xD8 */ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
+ /* 0xDC */ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+ /* 0xE0 */ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+ /* 0xE4 */ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+ /* 0xE8 */ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
+ /* 0xEC */ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ /* 0xF0 */ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
+ /* 0xF4 */ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+ /* 0xF8 */ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+ /* 0xFC */ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
+ };
+unsigned int crc32(unsigned char *address, unsigned int size, unsigned int crc)
+{
+#if 0
+ /* FAST, but bigger and only good for word-aligned data */
+ unsigned int *daddr = (unsigned int *)address;
+ unsigned int data = FALSE; /* little-endian by default */
+
+ /*
+ * TODO: We should really get the current processor big- or
+ * little-endian state and set "data" accordingly.
+ */
+
+ /* Perform word loop to save on memory accesses */
+ if (data)
+ /* big-endian */
+ for (; (size > 0); size -= sizeof(unsigned int))
+ {
+ data = *daddr++;
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 24) & 0xFF)) & 0xFF]);
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 16) & 0xFF)) & 0xFF]);
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 8) & 0xFF)) & 0xFF]);
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 0) & 0xFF)) & 0xFF]);
+ }
+ else
+ for (; (size > 0); size -= sizeof(unsigned int))
+ {
+ data = *daddr++;
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 0) & 0xFF)) & 0xFF]);
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 8) & 0xFF)) & 0xFF]);
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 16) & 0xFF)) & 0xFF]);
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 24) & 0xFF)) & 0xFF]);
+ }
+#else
+ for (; (size > 0); size--)
+ /* byte loop */
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ *address++) & 0x000000FF]);
+#endif
+
+ return(crc);
+}
+
+/**********************************************************************/
+
+/*
+ * crc16 16bit CRC-CCITT
+ * ----- ---------------
+ * This function provides a table driven 16bit CRC generation for byte data.
+ * This CRC is also known as the HDLC CRC.
+ */
+/*
+ * 960201 KWelton
+ *
+ *TODO: Is this correct? The compiler predefines __arm, *not* __ARM
+ */
+#ifdef __ARM
+/*
+ * To make the code quicker on the ARM, we double the table size and
+ * use integer slots rather than short slots for the table.
+ */
+static const unsigned int crctableA[16] = {
+#else
+static const unsigned short crctableA[16] = {
+#endif
+ 0x0000,
+ 0x1081,
+ 0x2102,
+ 0x3183,
+ 0x4204,
+ 0x5285,
+ 0x6306,
+ 0x7387,
+ 0x8408,
+ 0x9489,
+ 0xA50A,
+ 0xB58B,
+ 0xC60C,
+ 0xD68D,
+ 0xE70E,
+ 0xF78F
+ };
+
+#ifdef __ARM
+/* See comments above */
+static const unsigned int crctableB[16] = {
+#else
+static const unsigned short crctableB[16] = {
+#endif
+ 0x0000,
+ 0x1189,
+ 0x2312,
+ 0x329B,
+ 0x4624,
+ 0x57AD,
+ 0x6536,
+ 0x74BF,
+ 0x8C48,
+ 0x9DC1,
+ 0xAF5A,
+ 0xBED3,
+ 0xCA6C,
+ 0xDBE5,
+ 0xE97E,
+ 0xF8F7
+ };
+
+unsigned short crc16(unsigned char *address, unsigned int size,
+ unsigned short crc)
+{
+ for (; (size > 0); size--)
+ {
+ /* byte loop */
+ unsigned char data = *address++; /* fetch the next data byte */
+
+ data ^= crc; /* EOR data with current CRC value */
+ crc = ((crctableA[(data & 0xF0) >> 4] ^ crctableB[data & 0x0F]) ^
+ (crc >> 8));
+ }
+
+ return(crc);
+}
+
+/**********************************************************************/
+
+#if 0 /* not required at the moment */
+
+/*
+ * elf_hash
+ * --------
+ * This function is derived from the one on page 68 of chapter of the "Unix
+ * SVR4 Programmer's Guide". It is used to generate a hash-code from a
+ * symbol name.
+ */
+unsigned int elf_hash(const unsigned char *name)
+{
+ unsigned int h = 0;
+ unsigned int g;
+
+ /* NULL pointer returns a hash of zero */
+ while (name && (*name))
+ {
+ h = ((h << 4) + *name++);
+
+ if (g = (h & 0xF0000000))
+ h ^= (g >> 24);
+
+ h &= ~g;
+ }
+
+ return(h);
+}
+#endif
+
+/**********************************************************************/
+
+/* EOF crc.c */
diff --git a/gdb/rdi-share/crc.h b/gdb/rdi-share/crc.h
new file mode 100644
index 00000000000..77ba23e97df
--- /dev/null
+++ b/gdb/rdi-share/crc.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * crc.h - describes some "standard" CRC calculation routines.
+ */
+#ifndef angel_crc_h
+#define angel_crc_h
+
+/*
+ * manifests
+ */
+
+/*
+ * When using "crc32" or "crc16" these initial CRC values must be given to
+ * the respective function the first time it is called. The function can
+ * then be called with the return value from the last call of the function
+ * to generate a running CRC over multiple data blocks.
+ * When the last data block has been processed using the "crc32" algorithm
+ * the CRC value should be inverted to produce the final CRC value:
+ * e.g. CRC = ~CRC
+ */
+
+#define startCRC32 (0xFFFFFFFF) /* CRC initialised to all 1s */
+#define startCRC16 (0x0000) /* CRC initialised to all 0s */
+
+/*
+ * For the CRC-32 residual to be calculated correctly requires that the CRC
+ * value is in memory little-endian due to the byte read, bit-ordering
+ * nature of the algorithm.
+ */
+#define CRC32residual (0xDEBB20E3) /* good CRC-32 residual */
+
+
+/**********************************************************************/
+
+/*
+ * exported functions
+ */
+
+/*
+ * Function: crc32
+ * Purpose: Provides a table driven implementation of the IEEE-802.3
+ * 32-bit CRC algorithm for byte data.
+ *
+ * Params:
+ * Input: address pointer to the byte data
+ * size number of bytes of data to be processed
+ * crc initial CRC value to be used (can be the output
+ * from a previous call to this function).
+ * Returns:
+ * OK: 32-bit CRC value for the specified data
+ */
+extern unsigned int crc32(unsigned char *address, unsigned int size,
+ unsigned int crc);
+
+/**********************************************************************/
+
+/*
+ *
+ * Function: crc16
+ * Purpose: Generates a table driven 16-bit CRC-CCITT for byte data
+ *
+ * Params:
+ * Input: address pointer to the byte data
+ * size number of bytes of data to be processed
+ * crc initial CRC value to be used (can be the output
+ * from a previous call to this function).
+ *
+ * Returns:
+ * OK: 16-bit CRC value for the specified data
+ */
+extern unsigned short crc16(unsigned char *address, unsigned int size,
+ unsigned short crc);
+
+/**********************************************************************/
+
+#endif /* !defined(angel_crc_h) */
+
+/* EOF crc.h */
diff --git a/gdb/rdi-share/dbg_conf.h b/gdb/rdi-share/dbg_conf.h
new file mode 100644
index 00000000000..bf79958e6c5
--- /dev/null
+++ b/gdb/rdi-share/dbg_conf.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ARM symbolic debugger toolbox: dbg_conf.h
+ */
+
+/*
+ * RCS $Revision$
+ * Checkin $Date$
+ */
+
+#ifndef Dbg_Conf__h
+
+#define Dbg_Conf__h
+
+typedef struct Dbg_ConfigBlock {
+ int bytesex;
+ int fpe; /* Target should initialise FPE */
+ long memorysize;
+ unsigned long cpu_speed;/* Cpu speed (HZ) */
+ int serialport; /*) remote connection parameters */
+ int seriallinespeed; /*) (serial connection) */
+ int parallelport; /*) ditto */
+ int parallellinespeed; /*) (parallel connection) */
+ char *ethernettarget; /* name of remote ethernet target */
+ int processor; /* processor the armulator is to emulate (eg ARM60) */
+ int rditype; /* armulator / remote processor */
+ int heartbeat_on; /* angel heartbeat */
+ int drivertype; /* parallel / serial / etc */
+ char const *configtoload;
+ char const *memconfigtoload;
+ int flags;
+} Dbg_ConfigBlock;
+
+#define Dbg_ConfigFlag_Reset 1
+#define Dbg_ConfigFlag_LLSymsNeedPrefix 2
+
+typedef struct Dbg_HostosInterface Dbg_HostosInterface;
+/* This structure allows access by the (host-independent) C-library support
+ module of armulator or pisd (armos.c) to host-dependent functions for
+ which there is no host-independent interface. Its contents are unknown
+ to the debugger toolbox.
+ The assumption is that, in a windowed system, fputc(stderr) for example
+ may not achieve the desired effect of the character appearing in some
+ window.
+ */
+
+#endif
diff --git a/gdb/rdi-share/dbg_cp.h b/gdb/rdi-share/dbg_cp.h
new file mode 100644
index 00000000000..8974f836442
--- /dev/null
+++ b/gdb/rdi-share/dbg_cp.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ARM symbolic debugger toolbox: dbg_cp.h
+ */
+
+/*
+ * RCS $Revision$
+ * Checkin $Date$
+ */
+
+#ifndef Dbg_CP__h
+
+#define Dbg_CP__h
+
+#define Dbg_Access_Readable 1
+#define Dbg_Access_Writable 2
+#define Dbg_Access_CPDT 4 /* else CPRT */
+
+typedef struct {
+ unsigned short rmin, rmax;
+ /* a single description can be used for a range of registers with
+ the same properties *accessed via CPDT instructions*
+ */
+ unsigned char nbytes; /* size of register */
+ unsigned char access; /* see above (Access_xxx) */
+ union {
+ struct { /* CPDT instructions do not allow the coprocessor much freedom:
+ only bit 22 ('N') and 12-15 ('CRd') are free for the
+ coprocessor to use as it sees fit.
+ */
+ unsigned char nbit;
+ unsigned char rdbits;
+ } cpdt;
+ struct { /* CPRT instructions have much more latitude. The bits fixed
+ by the ARM are 24..31 (condition mask & opcode)
+ 20 (direction)
+ 8..15 (cpnum, arm register)
+ 4 (CPRT not CPDO)
+ leaving 14 bits free to the coprocessor (fortunately
+ falling within two bytes).
+ */
+ unsigned char read_b0, read_b1,
+ write_b0, write_b1;
+ } cprt;
+ } accessinst;
+} Dbg_CoProRegDesc;
+
+struct Dbg_CoProDesc {
+ int entries;
+ Dbg_CoProRegDesc regdesc[1/* really nentries */];
+};
+
+#define Dbg_CoProDesc_Size(n) (sizeof(struct Dbg_CoProDesc) + ((n)-1)*sizeof(Dbg_CoProRegDesc))
+
+#endif
diff --git a/gdb/rdi-share/dbg_hif.h b/gdb/rdi-share/dbg_hif.h
new file mode 100644
index 00000000000..5be21563660
--- /dev/null
+++ b/gdb/rdi-share/dbg_hif.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ARM debugger toolbox : dbg_hif.c
+ * Description of the Dbg_HostosInterface structure. This is *NOT*
+ * part of the debugger toolbox, but it is required by 2 back ends
+ * (armul & pisd) and two front ends (armsd & wdbg), so putting it
+ * in the toolbox is the only way of avoiding multiple copies.
+ */
+
+/*
+ * RCS $Revision$
+ * Checkin $Date$
+ */
+
+#ifndef dbg_hif__h
+#define dbg_hif__h
+
+#ifdef STDC_HEADERS
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+typedef void Hif_DbgPrint(void *arg, const char *format, va_list ap);
+typedef void Hif_DbgPause(void *arg);
+
+typedef void Hif_WriteC(void *arg, int c);
+typedef int Hif_ReadC(void *arg);
+typedef int Hif_Write(void *arg, char const *buffer, int len);
+typedef char *Hif_GetS(void *arg, char *buffer, int len);
+
+typedef void Hif_RDIResetProc(void *arg);
+
+struct Dbg_HostosInterface {
+ Hif_DbgPrint *dbgprint;
+ Hif_DbgPause *dbgpause;
+ void *dbgarg;
+
+ Hif_WriteC *writec;
+ Hif_ReadC *readc;
+ Hif_Write *write;
+ Hif_GetS *gets;
+ void *hostosarg;
+
+ Hif_RDIResetProc *reset;
+ void *resetarg;
+};
+
+#endif
diff --git a/gdb/rdi-share/dbg_rdi.h b/gdb/rdi-share/dbg_rdi.h
new file mode 100644
index 00000000000..efda7bd8800
--- /dev/null
+++ b/gdb/rdi-share/dbg_rdi.h
@@ -0,0 +1,511 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ARM debugger toolbox : dbg_rdi.h
+ */
+
+/*
+ * RCS $Revision$
+ * Checkin $Date$
+ */
+
+#ifndef dbg_rdi__h
+#define dbg_rdi__h
+
+/***************************************************************************\
+* Other RDI values *
+\***************************************************************************/
+
+#define RDISex_Little 0 /* the byte sex of the debuggee */
+#define RDISex_Big 1
+#define RDISex_DontCare 2
+
+#define RDIPoint_EQ 0 /* the different types of break/watchpoints */
+#define RDIPoint_GT 1
+#define RDIPoint_GE 2
+#define RDIPoint_LT 3
+#define RDIPoint_LE 4
+#define RDIPoint_IN 5
+#define RDIPoint_OUT 6
+#define RDIPoint_MASK 7
+
+#define RDIPoint_16Bit 16 /* 16-bit breakpoint */
+#define RDIPoint_Conditional 32
+
+/* ORRed with point type in extended RDP break and watch messages */
+#define RDIPoint_Inquiry 64
+#define RDIPoint_Handle 128 /* messages */
+
+#define RDIWatch_ByteRead 1 /* types of data accesses to watch for*/
+#define RDIWatch_HalfRead 2
+#define RDIWatch_WordRead 4
+#define RDIWatch_ByteWrite 8
+#define RDIWatch_HalfWrite 16
+#define RDIWatch_WordWrite 32
+
+#define RDIReg_R15 (1L << 15) /* mask values for CPU */
+#define RDIReg_PC (1L << 16)
+#define RDIReg_CPSR (1L << 17)
+#define RDIReg_SPSR (1L << 18)
+#define RDINumCPURegs 19
+
+#define RDINumCPRegs 10 /* current maximum */
+
+#define RDIMode_Curr 255
+
+/* RDI_Info subcodes */
+/* rdp in parameters are all preceded by */
+/* in byte = RDP_Info, word = info subcode */
+/* out parameters are all preceded by */
+/* out byte = RDP_Return */
+
+#define RDIInfo_Target 0
+/* rdi: out ARMword *targetflags, out ARMword *processor id */
+/* rdp: in none, out word targetflags, word processorid, byte status */
+/* the following bits are defined in targetflags */
+# define RDITarget_LogSpeed 0x0f
+# define RDITarget_HW 0x10 /* else emulator */
+# define RDITarget_AgentMaxLevel 0xe0
+# define RDITarget_AgentLevelShift 5
+# define RDITarget_DebuggerMinLevel 0x700
+# define RDITarget_DebuggerLevelShift 8
+# define RDITarget_CanReloadAgent 0x800
+# define RDITarget_CanInquireLoadSize 0x1000
+# define RDITarget_UnderstandsRDPInterrupt 0x2000
+# define RDITarget_CanProfile 0x4000
+# define RDITarget_Code16 0x8000
+# define RDITarget_HasCommsChannel 0x10000
+
+#define RDIInfo_Points 1
+/* rdi: out ARMword *pointcapabilities */
+/* rdp: in none, out word pointcapabilities, byte status */
+/* the following bits are defined in pointcapabilities */
+# define RDIPointCapability_Comparison 1
+# define RDIPointCapability_Range 2
+/* 4 to 128 are RDIWatch_xx{Read,Write} left-shifted by two */
+# define RDIPointCapability_Mask 0x100
+# define RDIPointCapability_ThreadBreak 0x200
+# define RDIPointCapability_ThreadWatch 0x400
+# define RDIPointCapability_CondBreak 0x800
+# define RDIPointCapability_Status 0x1000 /* status enquiries available */
+
+#define RDIInfo_Step 2
+/* rdi: out ARMword *stepcapabilities */
+/* rdp: in none, out word stepcapabilities, byte status */
+/* the following bits are defined in stepcapabilities */
+# define RDIStep_Multiple 1
+# define RDIStep_PCChange 2
+# define RDIStep_Single 4
+
+#define RDIInfo_MMU 3
+/* rdi: out ARMword *mmuidentity */
+/* rdp: in none, out word mmuidentity, byte status */
+
+#define RDIInfo_DownLoad 4
+/* Inquires whether configuration download and selection is available. */
+/* rdp: in none, out byte status */
+/* No argument, no return value. status == ok if available */
+
+#define RDIInfo_SemiHosting 5
+/* Inquires whether RDISemiHosting_* RDI_Info calls are available. */
+/* rdp: in none, out byte status */
+/* No argument, no return value. status == ok if available */
+
+#define RDIInfo_CoPro 6
+/* Inquires whether CoPro RDI_Info calls are available. */
+/* rdp: in none, out byte status */
+/* No argument, no return value. status == ok if available */
+
+#define RDIInfo_Icebreaker 7
+/* Inquires whether debuggee controlled by IceBreaker. */
+/* rdp: in none, out byte status */
+/* No argument, no return value. status == ok if available */
+
+#define RDIMemory_Access 8
+/* rdi: out RDI_MemAccessStats *p, in ARMword *handle */
+/* rdp: in word handle */
+/* out word nreads, word nwrites, word sreads, word swrites, */
+/* word ns, word s, byte status */
+
+/* Get memory access information for memory block with specified handle */
+
+#define RDIMemory_Map 9
+/* rdi: in RDI_MemDescr md[n], in ARMword *n */
+/* rdp: in word n, n * { */
+/* word handle, word start, word limit, */
+/* byte width, byte access */
+/* word Nread_ns, word Nwrite_ns, */
+/* word Sread_ns, word Swrite_ns} */
+/* out byte status */
+/* Sets memory characteristics. */
+
+#define RDISet_CPUSpeed 10
+/* rdi: in ARMword *speed */
+/* rdp: in word speed, out byte status */
+/* Sets CPU speed (in ns) */
+
+#define RDIRead_Clock 12
+/* rdi: out ARMword *ns, out ARMword *s */
+/* rdp: in none, out word ns, word s, byte status */
+/* Reads simulated time */
+
+#define RDIInfo_Memory_Stats 13
+/* Inquires whether RDI_Info codes 8-10 are available */
+/* rdp: in none, out byte status */
+/* No argument, no return value. status == ok if available */
+
+/* The next two are only to be used if RDIInfo_DownLoad returned no */
+/* error */
+#define RDIConfig_Count 14
+/* rdi: out ARMword *count */
+/* rdp: out byte status, word count (if status == OK) */
+
+/* In addition, the next one is only to be used if RDIConfig_Count */
+/* returned no error */
+typedef struct { unsigned32 version; char name[32]; } RDI_ConfigDesc;
+#define RDIConfig_Nth 15
+/* rdi: in ARMword *n, out RDI_ConfigDesc * */
+/* rdp: in word n */
+/* out word version, byte namelen, bytes * bytelen name, */
+/* byte status */
+
+/* Set a front-end polling function to be used from within driver poll */
+/* loops */
+typedef void RDI_PollProc(void *);
+typedef struct { RDI_PollProc *p; void *arg; } RDI_PollDesc;
+#define RDISet_PollProc 16
+/* rdi: in RDI_PollDesc const *from, RDI_PollDesc *to */
+/* if from non-NULL, sets the polling function from it */
+/* if to non-NULL, returns the previous polling function to it */
+/* No corresponding RDP operation */
+
+/* Called on debugger startup to see if the target is ready to execute */
+#define RDIInfo_CanTargetExecute 20
+/* rdi: in void
+ * out byte status (RDIError_NoError => Yes, Otherwise No)
+ */
+
+/* Called to set the top of target memory in an ICEman2 system
+ * This is then used by ICEman to tell the C Library via the INFOHEAP
+ * SWI where the stack should start.
+ * Note that only ICEman2 supports this call. Other systems eg.
+ * Demon, Angel, will simply return an error, which means that setting
+ * the top of memory in this fashion is not supported.
+ */
+#define RDIInfo_SetTopMem 21
+/* rdi: in word mem_top
+ * out byte status (RDIError_NoError => Done, Other => Not supported
+ */
+
+/* Called before performing a loadagent to determine the endianess of
+ * the debug agent, so that images of the wrong bytesex can be
+ * complained about
+ */
+#define RDIInfo_AgentEndianess 22
+/* rdi: in void
+ * out byte status
+ * status should be RDIError_LittleEndian or RDIError_BigEndian
+ * any other value indicates the target does not support this
+ * request, so the debugger will have to make a best guess, which
+ * probably means only allow little endian loadagenting.
+ */
+
+/* The next two are only to be used if the value returned by */
+/* RDIInfo_Points has RDIPointCapability_Status set. */
+#define RDIPointStatus_Watch 0x80
+#define RDIPointStatus_Break 0x81
+/* rdi: inout ARMword * (in handle, out hwresource), out ARMword *type */
+/* rdp: in word handle, out word hwresource, word type, byte status */
+
+#define RDISignal_Stop 0x100
+/* Requests that the debuggee stop */
+/* No arguments, no return value */
+/* rdp: no reply (when the debuggee stops, there will be a reply to the */
+/* step or execute request which started it) */
+
+#define RDIVector_Catch 0x180
+/* rdi: in ARMword *bitmap */
+/* rdp: int word bitmap, out byte status */
+/* bit i in bitmap set to cause vector i to cause entry to debugger */
+
+/* The next four are only to be used if RDIInfo_Semihosting returned */
+/* no error */
+#define RDISemiHosting_SetState 0x181
+/* rdi: in ARMword *semihostingstate */
+/* rdp: in word semihostingstate, out byte status */
+#define RDISemiHosting_GetState 0x182
+/* rdi: out ARMword *semihostingstate */
+/* rdp: in none, out word semihostingstate, byte status */
+#define RDISemiHosting_SetVector 0x183
+/* rdi: in ARMword *semihostingvector */
+/* rdp: in word semihostingvector, out byte status */
+#define RDISemiHosting_GetVector 0x184
+/* rdi: out ARMword *semihostingvector */
+/* rdp: in none, out word semihostingvector, byte status */
+
+/* The next two are only to be used if RDIInfo_Icebreaker returned */
+/* no error */
+#define RDIIcebreaker_GetLocks 0x185
+/* rdi: out ARMword *lockedstate */
+/* rdp: in none, out word lockedstate, byte status */
+
+#define RDIIcebreaker_SetLocks 0x186
+/* rdi: in ARMword *lockedstate */
+/* rdp: in word lockedstate, out byte status */
+
+/* lockedstate is a bitmap of the icebreaker registers locked against */
+/* use by IceMan (because explicitly written by the user) */
+
+#define RDIInfo_GetLoadSize 0x187
+/* rdi: out ARMword *maxloadsize */
+/* rdp: in none, out word maxloadsize, byte status */
+/* Inquires the maximum length of data transfer the agent is prepared */
+/* to receive */
+/* Only usable if RDIInfo_Target returned RDITarget_CanInquireLoadSize */
+/* rdi: out ARMword *size */
+
+/* Only to be used if the value returned by RDIInfo_Target had */
+/* RDITarget_HasCommsChannel set */
+typedef void RDICCProc_ToHost(void *arg, ARMword data);
+typedef void RDICCProc_FromHost(void *arg, ARMword *data, int *valid);
+
+#define RDICommsChannel_ToHost 0x188
+/* rdi: in RDICCProc_ToHost *, in void *arg */
+/* rdp: in byte connect, out byte status */
+#define RDICommsChannel_FromHost 0x189
+/* rdi: in RDICCProc_FromHost *, in void *arg */
+/* rdp: in byte connect, out byte status */
+
+/* These 4 are only to be used if RDIInfo_Semihosting returns no error */
+#define RDISemiHosting_SetARMSWI 0x190
+/* rdi: in ARMword ARM_SWI_number */
+/* rdp: in ARMword ARM_SWI_number, out byte status */
+
+#define RDISemiHosting_GetARMSWI 0x191
+/* rdi: out ARMword ARM_SWI_number */
+/* rdp: out ARMword ARM_SWI_number, byte status */
+
+#define RDISemiHosting_SetThumbSWI 0x192
+/* rdi: in ARMword Thumb_SWI_number */
+/* rdp: in ARMword Thumb_SWI_number, out byte status */
+
+#define RDISemiHosting_GetThumbSWI 0x193
+/* rdi: out ARMword ARM_Thumb_number */
+/* rdp: out ARMword ARM_Thumb_number, byte status */
+
+
+#define RDICycles 0x200
+/* rdi: out ARMword cycles[12] */
+/* rdp: in none, out 6 words cycles, byte status */
+/* the rdi result represents 6 big-endian doublewords; the rdp results */
+/* return values for the ls halves of these */
+# define RDICycles_Size 48
+
+#define RDIErrorP 0x201
+/* rdi: out ARMaddress *errorp */
+/* rdp: in none, out word errorp, byte status */
+/* Returns the error pointer associated with the last return from step */
+/* or execute with status RDIError_Error. */
+
+#define RDISet_Cmdline 0x300
+/* rdi: in char *commandline (a null-terminated string) */
+/* No corresponding RDP operation (cmdline is sent to the agent in */
+/* response to SWI_GetEnv) */
+
+#define RDISet_RDILevel 0x301
+/* rdi: in ARMword *level */
+/* rdp: in word level, out byte status */
+/* Sets the RDI/RDP protocol level to be used (must lie between the */
+/* limits returned by RDIInfo_Target). */
+
+#define RDISet_Thread 0x302
+/* rdi: in ARMword *threadhandle */
+/* rdp: in word threadhandle, out byte status */
+/* Sets the thread context for subsequent thread-sensitive operations */
+/* (null value sets no thread) */
+
+/* The next two are only to be used if RDI_read or RDI_write returned */
+/* RDIError_LittleEndian or RDIError_BigEndian, to signify that the */
+/* debugger has noticed. */
+#define RDIInfo_AckByteSex 0x303
+/* rdi: in ARMword *sex (RDISex_Little or RDISex_Big) */
+
+/* The next two are only to be used if RDIInfo_CoPro returned no error */
+#define RDIInfo_DescribeCoPro 0x400
+/* rdi: in int *cpno, Dbg_CoProDesc *cpd */
+/* rdp: in byte cpno, */
+/* cpd->entries * { */
+/* byte rmin, byte rmax, byte nbytes, byte access, */
+/* byte cprt_r_b0, cprt_r_b1, cprt_w_b0, cprt_w_b1} */
+/* byte = 255 */
+/* out byte status */
+
+#define RDIInfo_RequestCoProDesc 0x401
+/* rdi: in int *cpno, out Dbg_CoProDesc *cpd */
+/* rpd: in byte cpno */
+/* out nentries * { */
+/* byte rmin, byte rmax, byte nbytes, byte access, */
+/* } */
+/* byte = 255, byte status */
+
+#define RDIInfo_Log 0x800
+/* rdi: out ARMword *logsetting */
+/* No corresponding RDP operation */
+#define RDIInfo_SetLog 0x801
+/* rdi: in ARMword *logsetting */
+/* No corresponding RDP operation */
+
+#define RDIProfile_Stop 0x500
+/* No arguments, no return value */
+/* rdp: in none, out byte status */
+/* Requests that pc sampling stop */
+
+#define RDIProfile_Start 0x501
+/* rdi: in ARMword *interval */
+/* rdp: in word interval, out byte status */
+/* Requests that pc sampling start, with period <interval> usec */
+
+#define RDIProfile_WriteMap 0x502
+/* rdi: in ARMword map[] */
+/* map[0] is the length of the array, subsequent elements are sorted */
+/* and are the base of ranges for pc sampling (so if the sampled pc */
+/* lies between map[i] and map[i+1], count[i] is incremented). */
+/* rdp: a number of messages, each of form: */
+/* in word len, word size, word offset, <size> words map data */
+/* out status */
+/* len, size and offset are all word counts. */
+
+#define RDIProfile_ReadMap 0x503
+/* rdi: in ARMword *len, out ARMword counts[len] */
+/* Requests that the counts array be set to the accumulated pc sample */
+/* counts */
+/* rdp: a number of messages, each of form: */
+/* in word offset, word size */
+/* out <size> words, status */
+/* len, size and offset are all word counts. */
+
+#define RDIProfile_ClearCounts 0x504
+/* No arguments, no return value */
+/* rdp: in none, out byte status */
+/* Requests that pc sample counts be set to zero */
+
+#define RDIInfo_RequestReset 0x900
+/* Request reset of the target environment */
+/* No arguments, no return value */
+/* No RDP equivalent, sends an RDP reset */
+
+#define RDIInfo_CapabilityRequest 0x8000
+/* Request whether the interface supports the named capability. The */
+/* capability is specified by or'ing the RDIInfo number with this, and */
+/* sending that request */
+/* rdi: in none */
+/* rdp: in none, out byte status */
+
+typedef struct {
+ ARMword len;
+ ARMword map[1];
+} RDI_ProfileMap;
+
+typedef unsigned32 PointHandle;
+typedef unsigned32 ThreadHandle;
+#define RDINoPointHandle ((PointHandle)-1L)
+#define RDINoHandle ((ThreadHandle)-1L)
+
+struct Dbg_ConfigBlock;
+struct Dbg_HostosInterface;
+struct Dbg_MCState;
+typedef int rdi_open_proc(unsigned type, struct Dbg_ConfigBlock const *config,
+ struct Dbg_HostosInterface const *i,
+ struct Dbg_MCState *dbg_state);
+typedef int rdi_close_proc(void);
+typedef int rdi_read_proc(ARMword source, void *dest, unsigned *nbytes);
+typedef int rdi_write_proc(const void *source, ARMword dest, unsigned *nbytes);
+typedef int rdi_CPUread_proc(unsigned mode, unsigned32 mask, ARMword *state);
+typedef int rdi_CPUwrite_proc(unsigned mode, unsigned32 mask, ARMword const *state);
+typedef int rdi_CPread_proc(unsigned CPnum, unsigned32 mask, ARMword *state);
+typedef int rdi_CPwrite_proc(unsigned CPnum, unsigned32 mask, ARMword const *state);
+typedef int rdi_setbreak_proc(ARMword address, unsigned type, ARMword bound,
+ PointHandle *handle);
+typedef int rdi_clearbreak_proc(PointHandle handle);
+typedef int rdi_setwatch_proc(ARMword address, unsigned type, unsigned datatype,
+ ARMword bound, PointHandle *handle);
+typedef int rdi_clearwatch_proc(PointHandle handle);
+typedef int rdi_execute_proc(PointHandle *handle);
+typedef int rdi_step_proc(unsigned ninstr, PointHandle *handle);
+typedef int rdi_info_proc(unsigned type, ARMword *arg1, ARMword *arg2);
+typedef int rdi_pointinq_proc(ARMword *address, unsigned type,
+ unsigned datatype, ARMword *bound);
+
+typedef enum {
+ RDI_ConfigCPU,
+ RDI_ConfigSystem
+} RDI_ConfigAspect;
+
+typedef enum {
+ RDI_MatchAny,
+ RDI_MatchExactly,
+ RDI_MatchNoEarlier
+} RDI_ConfigMatchType;
+
+typedef int rdi_addconfig_proc(unsigned32 nbytes);
+typedef int rdi_loadconfigdata_proc(unsigned32 nbytes, char const *data);
+typedef int rdi_selectconfig_proc(RDI_ConfigAspect aspect, char const *name,
+ RDI_ConfigMatchType matchtype, unsigned versionreq,
+ unsigned *versionp);
+
+typedef char *getbufferproc(void *getbarg, unsigned32 *sizep);
+typedef int rdi_loadagentproc(ARMword dest, unsigned32 size, getbufferproc *getb, void *getbarg);
+typedef int rdi_targetisdead(void);
+
+typedef struct {
+ int itemmax;
+ char const * const *names;
+} RDI_NameList;
+
+typedef RDI_NameList const *rdi_namelistproc(void);
+
+typedef int rdi_errmessproc(char *buf, int buflen, int errnum);
+
+struct RDIProcVec {
+ char rditypename[12];
+
+ rdi_open_proc *open;
+ rdi_close_proc *close;
+ rdi_read_proc *read;
+ rdi_write_proc *write;
+ rdi_CPUread_proc *CPUread;
+ rdi_CPUwrite_proc *CPUwrite;
+ rdi_CPread_proc *CPread;
+ rdi_CPwrite_proc *CPwrite;
+ rdi_setbreak_proc *setbreak;
+ rdi_clearbreak_proc *clearbreak;
+ rdi_setwatch_proc *setwatch;
+ rdi_clearwatch_proc *clearwatch;
+ rdi_execute_proc *execute;
+ rdi_step_proc *step;
+ rdi_info_proc *info;
+ /* V2 RDI */
+ rdi_pointinq_proc *pointinquiry;
+
+ /* These three useable only if RDIInfo_DownLoad returns no error */
+ rdi_addconfig_proc *addconfig;
+ rdi_loadconfigdata_proc *loadconfigdata;
+ rdi_selectconfig_proc *selectconfig;
+
+ rdi_namelistproc *drivernames;
+ rdi_namelistproc *cpunames;
+
+ rdi_errmessproc *errmess;
+
+ /* Only if RDIInfo_Target returns a value with RDITarget_LoadAgent set */
+ rdi_loadagentproc *loadagent;
+ rdi_targetisdead *targetisdead;
+};
+
+#endif
diff --git a/gdb/rdi-share/devclnt.h b/gdb/rdi-share/devclnt.h
new file mode 100644
index 00000000000..cb920f66baf
--- /dev/null
+++ b/gdb/rdi-share/devclnt.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Public client interface to devices
+ */
+
+#ifndef angel_devclnt_h
+#define angel_devclnt_h
+
+/*
+ * This header exports the public interface to Angel-compliant device
+ * drivers.
+ *
+ * They are intended to be used solely by Angel, not by the User
+ * Application. See devappl.h for the User Application interface to
+ * the device drivers.
+ */
+
+#include "devices.h"
+
+/* General purpose constants, macros, enums, typedefs */
+
+/*
+ * possible channels at device level
+ *
+ * XXX
+ *
+ * these are used as array indices, so be specific about their values
+ */
+typedef enum DevChanID {
+ DC_DBUG = 0, /* reliable debug packets
+ * containing SDBG, CLIB,UDBG, etc.) */
+ DC_APPL = 1, /* application packets */
+ DC_NUM_CHANNELS
+} DevChanID;
+
+/* Publically-accessible globals */
+/* none */
+
+/* Public functions */
+
+/*
+ * Function: angel_DeviceWrite
+ * Purpose: The main entry point for asynchronous writes to a device.
+ *
+ * Params:
+ * Input: devID index of the device to write to
+ * buff data to write
+ * length how much data to write
+ * callback callback here when write finished
+ * or error
+ * cb_data data to be passed to callback
+ * chanID device channel to use
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: DE_OKAY write request is underway
+ * DE_NO_DEV no such device
+ * DE_BAD_DEV device does not support angel writes
+ * DE_BAD_CHAN no such device channel
+ * DE_BUSY device busy with another write
+ * DE_INVAL silly length
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * Commence asynchronous transmission of a buffer on a device. The
+ * callback will occur when the write completes or if there is an
+ * error.
+ *
+ * This must be called for each packet to be sent.
+ */
+
+DevError angel_DeviceWrite(DeviceID devID, p_Buffer buff,
+ unsigned length, DevWrite_CB_Fn callback,
+ void *cb_data, DevChanID chanID);
+
+
+/*
+ * Function: angel_DeviceRegisterRead
+ * Purpose: The main entry point for asynchronous reads from a device.
+ *
+ * Params:
+ * Input: devID index of the device to read from
+ * callback callback here when read finished
+ * or error
+ * cb_data data to be passed to callback
+ * get_buff callback to be used to acquire buffer
+ * for incoming packets
+ * getb_data data to be passed to get_buff
+ * chanID device channel to use
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: DE_OKAY read request is underway
+ * DE_NO_DEV no such device
+ * DE_BAD_DEV device does not support angel reads
+ * DE_BAD_CHAN no such device channel
+ * DE_BUSY device busy with another read
+ * DE_INVAL silly length
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * Register asynchronous packet read from a device. The callback will
+ * occur when the read completes or if there is an error.
+ *
+ * This is persistent: the read remains registered for all incoming
+ * packets on the device channel.
+ */
+
+DevError angel_DeviceRegisterRead(DeviceID devID,
+ DevRead_CB_Fn callback, void *cb_data,
+ DevGetBuff_Fn get_buff, void *getb_data,
+ DevChanID chanID);
+
+
+/*
+ * Function: angel_DeviceControl
+ * Purpose: Call a control function for a device
+ *
+ * Params:
+ * Input: devID index of the device to control to
+ * op operation to perform
+ * arg parameter depending on op
+ *
+ * Returns: DE_OKAY control request is underway
+ * DE_NO_DEV no such device
+ * DE_BAD_OP device does not support operation
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * Have a device perform a control operation. Extra parameters vary
+ * according to the operation requested.
+ */
+
+DevError angel_DeviceControl(DeviceID devID, DeviceControl op, void *arg);
+
+
+/*
+ * Function: angel_ReceiveMode
+ * Purpose: enable or disable reception across all devices
+ *
+ * Params:
+ * Input: mode choose enable or disable
+ *
+ * Pass the mode parameter to the receive_mode control method of each device
+ */
+
+void angel_ReceiveMode(DevRecvMode mode);
+
+
+/*
+ * Function: angel_ResetDevices
+ * Purpose: reset all devices
+ *
+ * Params: none
+ *
+ * Call the reset control method for each device
+ */
+
+void angel_ResetDevices(void);
+
+
+/*
+ * Function: angel_InitialiseDevices
+ * Purpose: initialise the device driver layer
+ *
+ * Params: none
+ *
+ * Set up the device driver layer and call the init method for each device
+ */
+
+void angel_InitialiseDevices(void);
+
+
+/*
+ * Function: angel_IsAngelDevice
+ * Purpose: Find out if a device supports Angel packets
+ *
+ * Params:
+ * Input: devID index of the device to control to
+ *
+ * Returns: TRUE supports Angel packets
+ * FALSE raw device
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ */
+
+bool angel_IsAngelDevice(DeviceID devID);
+
+
+#if !defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0
+
+/*
+ * Function: angel_ApplDeviceHandler
+ * Purpose: The entry point for User Application Device Driver requests
+ * in a full functiionality version of Angel.
+ * It will never be called directly by the User Application,
+ * but gets called indirectly, via the SWI handler.
+ *
+ * Params:
+ * Input: swi_r0 Argument to SWI indicating that
+ * angel_ApplDeviceHandler was to be called. This
+ * will not be used in this function, but is needed
+ * by the SWI handler.
+ * arg_blk pointer to block of arguments
+ * arg_blk[0] is one of
+ * angel_SWIreason_ApplDevice_{Read,Write,Yield}
+ * which indicates which angel_Device* fn is to
+ * be called. arg_blk[1] - arg_blk[n] are the
+ * arguments to the corresponding
+ * angel_ApplDevice* function.
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: whatever the specified angel_Device* function
+ * returns.
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * This has the side effects of angel_Device{Read,Write,Yield}
+ * depending upon which is operation is specified as described above.
+ */
+
+DevError angel_ApplDeviceHandler(
+ unsigned swi_r0, unsigned *arg_blk
+);
+
+#endif /* ndef MINIMAL_ANGEL */
+
+#endif /* ndef angel_devclnt_h */
+
+/* EOF devclnt.h */
diff --git a/gdb/rdi-share/devices.h b/gdb/rdi-share/devices.h
new file mode 100644
index 00000000000..eac6ee20fd7
--- /dev/null
+++ b/gdb/rdi-share/devices.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Devices header file
+ */
+
+#ifndef angel_devices_h
+#define angel_devices_h
+
+/*
+ * Provides common types for using devices, and provides access to the
+ * device table.
+ */
+
+#include "angel.h"
+#include "buffers.h"
+
+/* General purpose constants, macros, enums, typedefs */
+
+/* a non-enum holder for device IDs */
+typedef unsigned int DeviceID;
+
+/* device error codes */
+typedef enum DevError {
+ DE_OKAY, /* no error */
+ DE_NO_DEV, /* no such device */
+ DE_BAD_DEV, /* device does not support angel */
+ DE_BAD_CHAN, /* no such device channel */
+ DE_BAD_OP, /* operation not supported by this device */
+ DE_BUSY, /* device already busy */
+ DE_INVAL, /* length invalid */
+ DE_FAILED /* something else went wrong */
+} DevError;
+
+/* return codes from asynchronous calls - primarily for channels' benefit */
+typedef enum DevStatus {
+ DS_DONE, /* operation succeeded */
+ DS_OVERFLOW, /* not enough buffer space */
+ DS_BAD_PACKET, /* packet failed */
+ DS_DEV_ERROR, /* device error */
+ DS_INT_ERROR /* internal error */
+} DevStatus;
+
+/* Callback for async. writes */
+typedef void (*DevWrite_CB_Fn)(
+ void *buff, /* pointer to data -- cast to p_Buffer */
+ void *length, /* how much done -- cast to unsigned */
+ void *status, /* success code -- cast to DevStatus */
+ void *cb_data /* as supplied */
+ );
+
+/* Callback for async. reads */
+typedef void (*DevRead_CB_Fn)(
+ void *buff, /* pointer to data -- cast to p_Buffer */
+ void *length, /* how much read -- cast to unsigned */
+ void *status, /* success code -- cast to DevStatus */
+ void *cb_data /* as supplied */
+ );
+
+/* control operations */
+typedef enum DeviceControl {
+ DC_INIT, /* initialise device */
+ DC_RESET, /* reset device */
+ DC_RECEIVE_MODE, /* control reception */
+ DC_SET_PARAMS, /* set parameters of device */
+#ifndef TARGET
+ DC_GET_USER_PARAMS, /* params set by user at open */
+ DC_GET_DEFAULT_PARAMS, /* device default parameters */
+ DC_RESYNC, /* resynchronise with new agent */
+#endif
+ DC_PRIVATE /* start of private device codes */
+} DeviceControl;
+
+typedef enum DevRecvMode {
+ DR_DISABLE,
+ DR_ENABLE
+} DevRecvMode;
+
+/*
+ * callback to allow a device driver to request a buffer, to be filled
+ * with an incoming packet
+ */
+typedef p_Buffer (*DevGetBuff_Fn)(unsigned req_size, void *cb_data);
+
+
+/* Publically-accessible globals */
+/* none */
+
+#endif /* ndef angel_devices_h */
+
+/* EOF devices.h */
diff --git a/gdb/rdi-share/devsw.c b/gdb/rdi-share/devsw.c
new file mode 100644
index 00000000000..6ad0e4de91d
--- /dev/null
+++ b/gdb/rdi-share/devsw.c
@@ -0,0 +1,612 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <time.h>
+
+#include "adp.h"
+#include "sys.h"
+#include "hsys.h"
+#include "rxtx.h"
+#include "drivers.h"
+#include "buffers.h"
+#include "devclnt.h"
+#include "adperr.h"
+#include "devsw.h"
+#include "hostchan.h"
+#include "logging.h"
+
+static char *angelDebugFilename = NULL;
+static FILE *angelDebugLogFile = NULL;
+static int angelDebugLogEnable = 0;
+
+static void openLogFile ()
+{
+ time_t t;
+
+ if (angelDebugFilename == NULL || *angelDebugFilename =='\0')
+ return;
+
+ angelDebugLogFile = fopen (angelDebugFilename,"a");
+
+ if (!angelDebugLogFile)
+ {
+ fprintf (stderr,"Error opening log file '%s'\n",angelDebugFilename);
+ perror ("fopen");
+ }
+ else
+ {
+ /* The following line is equivalent to: */
+ /* setlinebuf (angelDebugLogFile); */
+ setvbuf(angelDebugLogFile, (char *)NULL, _IOLBF, 0);
+#if defined(__CYGWIN32__) || defined(__CYGWIN__)
+ setmode(fileno(angelDebugLogFile), O_TEXT);
+#endif
+ }
+
+ time (&t);
+ fprintf (angelDebugLogFile,"ADP log file opened at %s\n",asctime(localtime(&t)));
+}
+
+
+static void closeLogFile (void)
+{
+ time_t t;
+
+ if (!angelDebugLogFile)
+ return;
+
+ time (&t);
+ fprintf (angelDebugLogFile,"ADP log file closed at %s\n",asctime(localtime(&t)));
+
+ fclose (angelDebugLogFile);
+ angelDebugLogFile = NULL;
+}
+
+void DevSW_SetLogEnable (int logEnableFlag)
+{
+ if (logEnableFlag && !angelDebugLogFile)
+ openLogFile ();
+ else if (!logEnableFlag && angelDebugLogFile)
+ closeLogFile ();
+
+ angelDebugLogEnable = logEnableFlag;
+}
+
+
+void DevSW_SetLogfile (const char *filename)
+{
+ closeLogFile ();
+
+ if (angelDebugFilename)
+ {
+ free (angelDebugFilename);
+ angelDebugFilename = NULL;
+ }
+
+ if (filename && *filename)
+ {
+ angelDebugFilename = strdup (filename);
+ if (angelDebugLogEnable)
+ openLogFile ();
+ }
+}
+
+
+#define WordAt(p) ((unsigned long) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24)))
+
+static void dumpPacket(FILE *fp, char *label, struct data_packet *p)
+{
+ unsigned r;
+ int i;
+ unsigned char channel;
+
+ if (!fp)
+ return;
+
+ fprintf(fp,"%s [T=%d L=%d] ",label,p->type,p->len);
+ for (i=0; i<p->len; ++i)
+ fprintf(fp,"%02x ",p->data[i]);
+ fprintf(fp,"\n");
+
+ channel = p->data[0];
+
+ r = WordAt(p->data+4);
+
+ fprintf(fp,"R=%08x ",r);
+ fprintf(fp,"%s ", r&0x80000000 ? "H<-T" : "H->T");
+
+ switch (channel)
+ {
+ case CI_PRIVATE: fprintf(fp,"CI_PRIVATE: "); break;
+ case CI_HADP: fprintf(fp,"CI_HADP: "); break;
+ case CI_TADP: fprintf(fp,"CI_TADP: "); break;
+ case CI_HBOOT: fprintf(fp,"CI_HBOOT: "); break;
+ case CI_TBOOT: fprintf(fp,"CI_TBOOT: "); break;
+ case CI_CLIB: fprintf(fp,"CI_CLIB: "); break;
+ case CI_HUDBG: fprintf(fp,"CI_HUDBG: "); break;
+ case CI_TUDBG: fprintf(fp,"CI_TUDBG: "); break;
+ case CI_HTDCC: fprintf(fp,"CI_HTDCC: "); break;
+ case CI_TTDCC: fprintf(fp,"CI_TTDCC: "); break;
+ case CI_TLOG: fprintf(fp,"CI_TLOG: "); break;
+ default: fprintf(fp,"BadChan: "); break;
+ }
+
+ switch (r & 0xffffff)
+ {
+ case ADP_Booted: fprintf(fp," ADP_Booted "); break;
+#if defined(ADP_TargetResetIndication)
+ case ADP_TargetResetIndication: fprintf(fp," ADP_TargetResetIndication "); break;
+#endif
+ case ADP_Reboot: fprintf(fp," ADP_Reboot "); break;
+ case ADP_Reset: fprintf(fp," ADP_Reset "); break;
+#if defined(ADP_HostResetIndication)
+ case ADP_HostResetIndication: fprintf(fp," ADP_HostResetIndication "); break;
+#endif
+ case ADP_ParamNegotiate: fprintf(fp," ADP_ParamNegotiate "); break;
+ case ADP_LinkCheck: fprintf(fp," ADP_LinkCheck "); break;
+ case ADP_HADPUnrecognised: fprintf(fp," ADP_HADPUnrecognised "); break;
+ case ADP_Info: fprintf(fp," ADP_Info "); break;
+ case ADP_Control: fprintf(fp," ADP_Control "); break;
+ case ADP_Read: fprintf(fp," ADP_Read "); break;
+ case ADP_Write: fprintf(fp," ADP_Write "); break;
+ case ADP_CPUread: fprintf(fp," ADP_CPUread "); break;
+ case ADP_CPUwrite: fprintf(fp," ADP_CPUwrite "); break;
+ case ADP_CPread: fprintf(fp," ADP_CPread "); break;
+ case ADP_CPwrite: fprintf(fp," ADP_CPwrite "); break;
+ case ADP_SetBreak: fprintf(fp," ADP_SetBreak "); break;
+ case ADP_ClearBreak: fprintf(fp," ADP_ClearBreak "); break;
+ case ADP_SetWatch: fprintf(fp," ADP_SetWatch "); break;
+ case ADP_ClearWatch: fprintf(fp," ADP_ClearWatch "); break;
+ case ADP_Execute: fprintf(fp," ADP_Execute "); break;
+ case ADP_Step: fprintf(fp," ADP_Step "); break;
+ case ADP_InterruptRequest: fprintf(fp," ADP_InterruptRequest "); break;
+ case ADP_HW_Emulation: fprintf(fp," ADP_HW_Emulation "); break;
+ case ADP_ICEbreakerHADP: fprintf(fp," ADP_ICEbreakerHADP "); break;
+ case ADP_ICEman: fprintf(fp," ADP_ICEman "); break;
+ case ADP_Profile: fprintf(fp," ADP_Profile "); break;
+ case ADP_InitialiseApplication: fprintf(fp," ADP_InitialiseApplication "); break;
+ case ADP_End: fprintf(fp," ADP_End "); break;
+ case ADP_TADPUnrecognised: fprintf(fp," ADP_TADPUnrecognised "); break;
+ case ADP_Stopped: fprintf(fp," ADP_Stopped "); break;
+ case ADP_TDCC_ToHost: fprintf(fp," ADP_TDCC_ToHost "); break;
+ case ADP_TDCC_FromHost: fprintf(fp," ADP_TDCC_FromHost "); break;
+
+ case CL_Unrecognised: fprintf(fp," CL_Unrecognised "); break;
+ case CL_WriteC: fprintf(fp," CL_WriteC "); break;
+ case CL_Write0: fprintf(fp," CL_Write0 "); break;
+ case CL_ReadC: fprintf(fp," CL_ReadC "); break;
+ case CL_System: fprintf(fp," CL_System "); break;
+ case CL_GetCmdLine: fprintf(fp," CL_GetCmdLine "); break;
+ case CL_Clock: fprintf(fp," CL_Clock "); break;
+ case CL_Time: fprintf(fp," CL_Time "); break;
+ case CL_Remove: fprintf(fp," CL_Remove "); break;
+ case CL_Rename: fprintf(fp," CL_Rename "); break;
+ case CL_Open: fprintf(fp," CL_Open "); break;
+ case CL_Close: fprintf(fp," CL_Close "); break;
+ case CL_Write: fprintf(fp," CL_Write "); break;
+ case CL_WriteX: fprintf(fp," CL_WriteX "); break;
+ case CL_Read: fprintf(fp," CL_Read "); break;
+ case CL_ReadX: fprintf(fp," CL_ReadX "); break;
+ case CL_Seek: fprintf(fp," CL_Seek "); break;
+ case CL_Flen: fprintf(fp," CL_Flen "); break;
+ case CL_IsTTY: fprintf(fp," CL_IsTTY "); break;
+ case CL_TmpNam: fprintf(fp," CL_TmpNam "); break;
+
+ default: fprintf(fp," BadReason "); break;
+ }
+
+ i = 20;
+
+ if (((r & 0xffffff) == ADP_CPUread ||
+ (r & 0xffffff) == ADP_CPUwrite) && (r&0x80000000)==0)
+ {
+ fprintf(fp,"%02x ", p->data[i]);
+ ++i;
+ }
+
+ for (; i<p->len; i+=4)
+ fprintf(fp,"%08x ",WordAt(p->data+i));
+
+ fprintf(fp,"\n");
+}
+
+
+/*
+ * TODO: this should be adjustable - it could be done by defining
+ * a reason code for DevSW_Ioctl. It could even be a
+ * per-devicechannel parameter.
+ */
+static const unsigned int allocsize = ADP_BUFFER_MIN_SIZE;
+
+#define illegalDevChanID(type) ((type) >= DC_NUM_CHANNELS)
+
+/**********************************************************************/
+
+/*
+ * Function: initialise_read
+ * Purpose: Set up a read request for another packet
+ *
+ * Params:
+ * In/Out: ds State structure to be initialised
+ *
+ * Returns:
+ * OK: 0
+ * Error: -1
+ */
+static int initialise_read(DevSWState *ds)
+{
+ struct data_packet *dp;
+
+ /*
+ * try to claim the structure that will
+ * eventually hold the new packet.
+ */
+ if ((ds->ds_nextreadpacket = DevSW_AllocatePacket(allocsize)) == NULL)
+ return -1;
+
+ /*
+ * Calls into the device driver use the DriverCall structure: use
+ * the buffer we have just allocated, and declare its size. We
+ * are also obliged to clear the driver's context pointer.
+ */
+ dp = &ds->ds_activeread.dc_packet;
+ dp->buf_len = allocsize;
+ dp->data = ds->ds_nextreadpacket->pk_buffer;
+
+ ds->ds_activeread.dc_context = NULL;
+
+ return 0;
+}
+
+/*
+ * Function: initialise_write
+ * Purpose: Set up a write request for another packet
+ *
+ * Params:
+ * Input: packet The packet to be written
+ *
+ * type The type of the packet
+ *
+ * In/Out: dc The structure to be intialised
+ *
+ * Returns: Nothing
+ */
+static void initialise_write(DriverCall *dc, Packet *packet, DevChanID type)
+{
+ struct data_packet *dp = &dc->dc_packet;
+
+ dp->len = packet->pk_length;
+ dp->data = packet->pk_buffer;
+ dp->type = type;
+
+ /*
+ * we are required to clear the state structure for the driver
+ */
+ dc->dc_context = NULL;
+}
+
+/*
+ * Function: enqueue_packet
+ * Purpose: move a newly read packet onto the appropriate queue
+ * of read packets
+ *
+ * Params:
+ * In/Out: ds State structure with new packet
+ *
+ * Returns: Nothing
+ */
+static void enqueue_packet(DevSWState *ds)
+{
+ struct data_packet *dp = &ds->ds_activeread.dc_packet;
+ Packet *packet = ds->ds_nextreadpacket;
+
+ /*
+ * transfer the length
+ */
+ packet->pk_length = dp->len;
+
+ /*
+ * take this packet out of the incoming slot
+ */
+ ds->ds_nextreadpacket = NULL;
+
+ /*
+ * try to put it on the correct input queue
+ */
+ if (illegalDevChanID(dp->type))
+ {
+ /* this shouldn't happen */
+ WARN("Illegal type for Rx packet");
+ DevSW_FreePacket(packet);
+ }
+ else
+ Adp_addToQueue(&ds->ds_readqueue[dp->type], packet);
+}
+
+/*
+ * Function: flush_packet
+ * Purpose: Send a packet to the device driver
+ *
+ * Params:
+ * Input: device The device to be written to
+ *
+ * In/Out: dc Describes the packet to be sent
+ *
+ * Returns: Nothing
+ *
+ * Post-conditions: If the whole packet was accepted by the device
+ * driver, then dc->dc_packet.data will be
+ * set to NULL.
+ */
+static void flush_packet(const DeviceDescr *device, DriverCall *dc)
+{
+ if (device->DeviceWrite(dc) > 0)
+ /*
+ * the whole packet was swallowed
+ */
+ dc->dc_packet.data = NULL;
+}
+
+/**********************************************************************/
+
+/*
+ * These are the externally visible functions. They are documented in
+ * devsw.h
+ */
+Packet *DevSW_AllocatePacket(const unsigned int length)
+{
+ Packet *pk;
+
+ if ((pk = malloc(sizeof(*pk))) == NULL)
+ {
+ WARN("malloc failure");
+ return NULL;
+ }
+
+ if ((pk->pk_buffer = malloc(length+CHAN_HEADER_SIZE)) == NULL)
+ {
+ WARN("malloc failure");
+ free(pk);
+ return NULL;
+ }
+
+ return pk;
+}
+
+void DevSW_FreePacket(Packet *pk)
+{
+ free(pk->pk_buffer);
+ free(pk);
+}
+
+AdpErrs DevSW_Open(DeviceDescr *device, const char *name, const char *arg,
+ const DevChanID type)
+{
+ DevSWState *ds;
+
+ /*
+ * is this the very first open call for this driver?
+ */
+ if ((ds = (DevSWState *)(device->SwitcherState)) == NULL)
+ {
+ /*
+ * yes, it is: initialise state
+ */
+ if ((ds = malloc(sizeof(*ds))) == NULL)
+ /* give up */
+ return adp_malloc_failure;
+
+ (void)memset(ds, 0, sizeof(*ds));
+ device->SwitcherState = (void *)ds;
+ }
+
+ /*
+ * check that we haven't already been opened for this type
+ */
+ if ((ds->ds_opendevchans & (1 << type)) != 0)
+ return adp_device_already_open;
+
+ /*
+ * if no opens have been done for this device, then do it now
+ */
+ if (ds->ds_opendevchans == 0)
+ if (device->DeviceOpen(name, arg) < 0)
+ return adp_device_open_failed;
+
+ /*
+ * open has finished
+ */
+ ds->ds_opendevchans |= (1 << type);
+ return adp_ok;
+}
+
+AdpErrs DevSW_Match(const DeviceDescr *device, const char *name,
+ const char *arg)
+{
+ return (device->DeviceMatch(name, arg) == -1) ? adp_failed : adp_ok;
+}
+
+AdpErrs DevSW_Close (DeviceDescr *device, const DevChanID type)
+{
+ DevSWState *ds = (DevSWState *)(device->SwitcherState);
+ Packet *pk;
+
+ if ((ds->ds_opendevchans & (1 << type)) == 0)
+ return adp_device_not_open;
+
+ ds->ds_opendevchans &= ~(1 << type);
+
+ /*
+ * if this is the last close for this channel, then inform the driver
+ */
+ if (ds->ds_opendevchans == 0)
+ device->DeviceClose();
+
+ /*
+ * release all packets of the appropriate type
+ */
+ for (pk = Adp_removeFromQueue(&(ds->ds_readqueue[type]));
+ pk != NULL;
+ pk = Adp_removeFromQueue(&(ds->ds_readqueue[type])))
+ DevSW_FreePacket(pk);
+
+ /* Free memory */
+ free ((char *) device->SwitcherState);
+ device->SwitcherState = 0x0;
+
+ /* that's all */
+ return adp_ok;
+}
+
+AdpErrs DevSW_Read(const DeviceDescr *device, const DevChanID type,
+ Packet **packet, bool block)
+{
+ int read_err;
+ DevSWState *ds = device->SwitcherState;
+
+ /*
+ * To try to get information out of the device driver as
+ * quickly as possible, we try and read more packets, even
+ * if a completed packet is already available.
+ */
+
+ /*
+ * have we got a packet currently pending?
+ */
+ if (ds->ds_nextreadpacket == NULL)
+ /*
+ * no - set things up
+ */
+ if (initialise_read(ds) < 0) {
+ /*
+ * we failed to initialise the next packet, but can
+ * still return a packet that has already arrived.
+ */
+ *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
+ return adp_ok;
+ }
+ read_err = device->DeviceRead(&ds->ds_activeread, block);
+ switch (read_err) {
+ case 1:
+ /*
+ * driver has pulled in a complete packet, queue it up
+ */
+#ifdef RET_DEBUG
+ printf("got a complete packet\n");
+#endif
+
+ if (angelDebugLogEnable)
+ dumpPacket(angelDebugLogFile,"rx:",&ds->ds_activeread.dc_packet);
+
+ enqueue_packet(ds);
+ *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
+ return adp_ok;
+ case 0:
+ /*
+ * OK, return the head of the read queue for the given type
+ */
+ /* enqueue_packet(ds); */
+ *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
+ return adp_ok;
+ case -1:
+#ifdef RET_DEBUG
+ printf("got a bad packet\n");
+#endif
+ /* bad packet */
+ *packet = NULL;
+ return adp_bad_packet;
+ default:
+ panic("DevSW_Read: bad read status %d", read_err);
+ }
+ return 0; /* get rid of a potential compiler warning */
+}
+
+
+AdpErrs DevSW_FlushPendingWrite(const DeviceDescr *device)
+{
+ struct DriverCall *dc;
+ struct data_packet *dp;
+
+ dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite;
+ dp = &dc->dc_packet;
+
+ /*
+ * try to flush any packet that is still being written
+ */
+ if (dp->data != NULL)
+ {
+ flush_packet(device, dc);
+
+ /* see if it has gone */
+ if (dp->data != NULL)
+ return adp_write_busy;
+ else
+ return adp_ok;
+ }
+ else
+ return adp_ok;
+}
+
+
+AdpErrs DevSW_Write(const DeviceDescr *device, Packet *packet, DevChanID type)
+{
+ struct DriverCall *dc;
+ struct data_packet *dp;
+
+ dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite;
+ dp = &dc->dc_packet;
+
+ if (illegalDevChanID(type))
+ return adp_illegal_args;
+
+ /*
+ * try to flush any packet that is still being written
+ */
+ if (DevSW_FlushPendingWrite(device) != adp_ok)
+ return adp_write_busy;
+
+ /*
+ * we can take this packet - set things up, then try to get rid of it
+ */
+ initialise_write(dc, packet, type);
+
+ if (angelDebugLogEnable)
+ dumpPacket(angelDebugLogFile,"tx:",&dc->dc_packet);
+
+ flush_packet(device, dc);
+
+ return adp_ok;
+}
+
+AdpErrs DevSW_Ioctl(const DeviceDescr *device, const int opcode, void *args)
+{
+ return (device->DeviceIoctl(opcode, args) < 0) ? adp_failed : adp_ok;
+}
+
+bool DevSW_WriteFinished(const DeviceDescr *device)
+{
+ struct DriverCall *dc;
+ struct data_packet *dp;
+
+ dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite;
+ dp = &dc->dc_packet;
+
+ return (dp == NULL || dp->data == NULL);
+}
+
+/* EOF devsw.c */
diff --git a/gdb/rdi-share/devsw.h b/gdb/rdi-share/devsw.h
new file mode 100644
index 00000000000..6a2279d94fb
--- /dev/null
+++ b/gdb/rdi-share/devsw.h
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ */
+#ifndef angsd_devsw_h
+#define angsd_devsw_h
+
+#include "devclnt.h"
+#include "adperr.h"
+#include "drivers.h"
+
+#ifndef __cplusplus
+typedef struct Packet Packet;
+typedef struct DevSWState DevSWState;
+#endif
+
+/*
+ * the basic structure used for passing packets around
+ */
+struct Packet
+{
+ struct Packet *pk_next; /* XXX first field in struct */
+ unsigned int pk_length;
+ unsigned char *pk_buffer;
+};
+
+/*
+ * control structure, used for maintaining device switcher state
+ */
+struct DevSWState
+{
+ unsigned int ds_opendevchans; /* bitmap of open device channels */
+
+ /*
+ * queue of packets read for the various device channels
+ */
+ Packet *ds_readqueue[DC_NUM_CHANNELS];
+
+ /*
+ * structures for managing active read and write operations
+ */
+ Packet *ds_nextreadpacket;
+ DriverCall ds_activeread;
+ DriverCall ds_activewrite;
+};
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*
+ * Function: DevSW_AllocatePacket
+ * Purpose: Claim some memory to hold a struct Packet, and the buffer for
+ * that packet.
+ *
+ * Params:
+ * Input: length Size of the buffer in struct Packet.
+ *
+ * Returns:
+ * OK: Pointer to the newly malloc()ed Packet.
+ * Error: NULL
+ */
+Packet *DevSW_AllocatePacket(const unsigned int length);
+
+/*
+ * Function: DevSW_FreePacket
+ * Purpose: Free the memory associated with a struct Packet.
+ *
+ * Pre-conditions The structure must have been originally claimed
+ * via DevSW_AllocatePacket.
+ *
+ * Params:
+ * Input: pk The packet to be freed.
+ *
+ * Returns: Nothing
+ */
+void DevSW_FreePacket(Packet *pk);
+
+/*
+ * Function: DevSW_Open
+ * Purpose: Open the specified device driver
+ *
+ * Params:
+ * Input: name Identifies which device to open. This can either be
+ * a host specific identifier (e.g. "/dev/ttya",
+ * "COM1:"), or a number which is used to refer to
+ * `standard' interfaces, so "1" would be the first host
+ * interface, "2" the second, and so on.
+ *
+ * arg Driver specific arguments. For example, some serial
+ * drivers accept speed and control arguments such as
+ * "9600" or "19200/NO_BREAK". These arguments are
+ * completely free-form: it is the individual drivers
+ * which do the necessary interpretation.
+ *
+ * type The type of packet the caller is interested in. Only
+ * one open is allowed for each type of packet.
+ *
+ * In/Out: device The device driver to open
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_open_failed
+ * adp_device_already_open
+ * adp_malloc_failure
+ */
+AdpErrs DevSW_Open(DeviceDescr *device, const char *name, const char *arg,
+ const DevChanID type);
+
+/*
+ * Function: DevSW_Match
+ * Purpose: Minimal veneer for DeviceMatch
+ *
+ * Params:
+ * Input: device The device driver to match.
+ *
+ * name Identifies which device to open. This can either be
+ * a host specific identifier (e.g. "/dev/ttya",
+ * "COM1:"), or a number which is used to refer to
+ * `standard' interfaces, so "1" would be the first host
+ * interface, "2" the second, and so on.
+ *
+ * arg Driver specific arguments. For example, some serial
+ * drivers accept speed and control arguments such as
+ * "9600" or "19200/NO_BREAK". These arguments are
+ * completely free-form: it is the individual drivers
+ * which do the necessary interpretation.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_failed
+ */
+AdpErrs DevSW_Match(const DeviceDescr *device, const char *name,
+ const char *arg);
+
+/*
+ * Function: DevSW_Close
+ * Purpose: Close the specified device driver. All packets of the type
+ * used by the caller held within the switching layer will
+ * be discarded.
+ *
+ * Pre-conditions: Device must have been previously opened.
+ *
+ * Params:
+ * Input: device The device driver to close
+ *
+ * type The type of packet the caller was interested in.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_open
+ */
+AdpErrs DevSW_Close(DeviceDescr *device, const DevChanID type);
+
+/*
+ * Function: DevSW_Read
+ * Purpose: Read a packet of appropriate type from the device driver
+ *
+ * Params:
+ * Input: device The device driver to read packet from.
+ *
+ * type The type of packet the caller is interested in.
+ *
+ * Output: packet Pointer to new packet (if one is available)
+ * NULL (if no complete packet is available)
+ *
+ * Input: block If TRUE, read may safely block for a short period
+ * of time (say up to 20ms), to avoid high CPU load
+ * whilst waiting for a reply.
+ * If FALSE, read MUST NOT block.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_bad_packet
+ *
+ * Post-conditions: The calling function is responsible for freeing the
+ * resources used by the packet when it is no longer
+ * needed.
+ */
+AdpErrs DevSW_Read(const DeviceDescr *device, const DevChanID type,
+ Packet **packet, bool block);
+
+/*
+ * Function: DevSW_Write
+ * Purpose: Try to write a packet to the device driver. The write will
+ * be bounced if another write is still in progress.
+ *
+ * Params:
+ * Input: device The device driver to write a packet to.
+ *
+ * packet The packet to be written.
+ *
+ * type The type to be assigned to the packet.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_illegal_args
+ * adp_write_busy
+ *
+ * Post-conditions: The calling function retains "ownership" of the packet,
+ * i.e. it is responsible for freeing the resources used
+ * by the packet when it is no longer needed.
+ */
+AdpErrs DevSW_Write(const DeviceDescr *device, Packet *packet, DevChanID type);
+
+/*
+ * Function: DevSW_FlushPendingWrite
+ * Purpose: If a write is in progress, give it a chance to finish.
+ *
+ * Params:
+ * Input: device The device driver to flush.
+ *
+ * Returns:
+ * adp_ok no pending write, or write flushed completely
+ * adp_write_busy pending write not flushed completely
+ */
+AdpErrs DevSW_FlushPendingWrite(const DeviceDescr *device);
+
+/*
+ * Function: DevSW_Ioctl
+ * Purpose: Perform miscellaneous control operations. This is a minimal
+ * veneer to DeviceIoctl.
+ *
+ * Params:
+ * Input: device The device driver to control.
+ *
+ * opcode Reason code indicating the operation to perform.
+ *
+ * In/Out: args Pointer to opcode-sensitive arguments/result space.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_failed
+ */
+AdpErrs DevSW_Ioctl(const DeviceDescr *device, const int opcode, void *args);
+
+/*
+ * Function: DevSW_WriteFinished
+ * Purpose: Return TRUE if the active device has finished writing
+ * the last packet to be sent, or FALSE if a packet is still
+ * being transmitted.
+ *
+ * Params:
+ * Input: device The device driver to check.
+ *
+ * Returns:
+ * TRUE: write finished or inactive
+ * FALSE: write in progress
+ */
+bool DevSW_WriteFinished(const DeviceDescr *device);
+
+
+/*
+ * set filename and enable/disable logginf of ADP packets
+ */
+void DevSW_SetLogfile(const char *filename);
+void DevSW_SetLogEnable(int logEnableFlag);
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* ndef angsd_devsw_h */
+
+/* EOF devsw.h */
diff --git a/gdb/rdi-share/drivers.c b/gdb/rdi-share/drivers.c
new file mode 100644
index 00000000000..ba0eee50890
--- /dev/null
+++ b/gdb/rdi-share/drivers.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * drivers.c - declares a NULL terminated list of device driver
+ * descriptors supported by the host.
+ */
+#include <stdio.h>
+
+#include "drivers.h"
+
+extern DeviceDescr angel_SerialDevice;
+extern DeviceDescr angel_SerparDevice;
+extern DeviceDescr angel_EthernetDevice;
+
+DeviceDescr *devices[] =
+{
+ &angel_SerialDevice,
+ &angel_SerparDevice,
+ &angel_EthernetDevice,
+ NULL
+};
+
+/* EOF drivers.c */
diff --git a/gdb/rdi-share/drivers.h b/gdb/rdi-share/drivers.h
new file mode 100644
index 00000000000..3655c18b0a2
--- /dev/null
+++ b/gdb/rdi-share/drivers.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Definitions for device driver interface.
+ */
+#ifndef angsd_drivers_h
+#define angsd_drivers_h
+
+#include "rxtx.h"
+
+#ifndef __cplusplus
+typedef struct DeviceDescr DeviceDescr;
+typedef struct DriverCall DriverCall;
+#endif
+
+/*
+ * used to pass packets across the driver interface
+ */
+struct DriverCall
+{
+ struct data_packet dc_packet;
+ void *dc_context;
+};
+
+/*
+ * used to describe a device driver
+ */
+struct DeviceDescr
+{
+ char *DeviceName;
+ int (*DeviceOpen)(const char *name, const char *arg);
+ int (*DeviceMatch)(const char *name, const char *arg);
+ void (*DeviceClose)(void);
+ int (*DeviceRead)(DriverCall *dc, bool block);
+ int (*DeviceWrite)(DriverCall *dc);
+ int (*DeviceIoctl)(const int opcode, void *args);
+ void *SwitcherState; /* used by switcher interface */
+};
+
+/*
+ * Function: DeviceOpen
+ *
+ * Purpose: Open a communications device
+ *
+ * Pre-conditions: No previous open is still active
+ *
+ * Params:
+ * Input: name Identifies which device to open. This can either be
+ * a host specific identifier (e.g. "/dev/ttya",
+ * "COM1:"), or a number which is used to refer to
+ * `standard' interfaces, so "1" would be the first host
+ * interface, "2" the second, and so on.
+ *
+ * arg Driver specific arguments. For example, some serial
+ * drivers accept speed and control arguments such as
+ * "9600" or "19200/NO_BREAK". These arguments are
+ * completely free-form: it is the individual drivers
+ * which do the necessary interpretation.
+ *
+ * Returns:
+ * OK: 0
+ * Error: -1
+ */
+extern int DeviceOpen(const char *name, const char *arg);
+
+/*
+ * Function: DeviceMatch
+ *
+ * Purpose: Check whether parameters are OK to be passed to DeviceOpen
+ *
+ * Params:
+ * Input: name Identifies which device to open. This can either be
+ * a host specific identifier (e.g. "/dev/ttya",
+ * "COM1:"), or a number which is used to refer to
+ * `standard' interfaces, so "1" would be the first host
+ * interface, "2" the second, and so on.
+ *
+ * arg Driver specific arguments. For example, some serial
+ * drivers accept speed and control arguments such as
+ * "9600" or "19200/NO_BREAK". These arguments are
+ * completely free-form: it is the individual drivers
+ * which do the necessary interpretation.
+ *
+ * Returns:
+ * OK: 0
+ * Error: -1
+ */
+extern int DeviceMatch(const char *name, const char *arg);
+
+/*
+ * Function: DeviceClose
+ *
+ * Purpose: Close a communications device
+ *
+ * Pre-conditions: Device must have been previously opened
+ *
+ * Params: None
+ *
+ * Returns: Nothing
+ */
+extern void DeviceClose(void);
+
+/*
+ * Function: DeviceRead
+ *
+ * Purpose: Try to read a complete packet from a communications device.
+ * This read must usually be non-blocking, i.e. it should read as
+ * many data from the device as needed to complete the packet,
+ * but it should not wait if the packet is not complete, and no
+ * more data are currently available from the device.
+ * As an optimisation the read can optionally block when 'block'
+ * is TRUE, but only for a short time. It is acceptable for the
+ * 'block' parameter to be ignored in which case all reads
+ * should be non-blocking.
+ *
+ * Pre-conditions: Device has been opened via DeviceOpen()
+ *
+ * Params:
+ * In/Out: dc Describes the packet being read (dc->dc_packet);
+ * dc->dc_context is for the driver to store private
+ * context, and is guaranteed to be NULL the first
+ * time DeviceRead is called for a given packet.
+ *
+ * In: block If TRUE, read may safely block for a short period
+ * of time (say up to 20ms), to avoid high CPU load
+ * whilst waiting for a reply.
+ * If FALSE, read MUST NOT block.
+ *
+ * Returns:
+ * OK: 1 (packet is complete)
+ * 0 (packet is not yet complete)
+ * Error: -1 bad packet
+ *
+ * Post-conditions: should a calamatous error occur panic() will be called
+ */
+extern int DeviceRead(DriverCall *dc, bool block);
+
+/*
+ * Function: DeviceWrite
+ *
+ * Purpose: Try to write a packet to a communications device. This write
+ * must be non-blocking, i.e. it should write as many data to
+ * the device as is immediately possible, but should not wait
+ * for space to send any more after that.
+ *
+ * Pre-conditions: Device has been opened via DeviceOpen()
+ *
+ * Params:
+ * In/Out: dc Describes the packet being written (dc->dc_packet);
+ * dc->dc_context is for the driver to store private
+ * context, and is guaranteed to be NULL the first
+ * time DeviceWrite is called for a given packet.
+ *
+ * Returns:
+ * OK: 1 (all of the packet has been written)
+ * 0 (some of the packet remains to be written)
+ * Error: -1
+ */
+extern int DeviceWrite(DriverCall *dc);
+
+/*
+ * Function: DeviceIoctl
+ *
+ * Purpose: Perform miscellaneous driver operations
+ *
+ * Pre-conditions: Device has been open via DeviceOpen()
+ *
+ * Params:
+ * Input: opcode Reason code indicating the operation to perform
+ * In/Out: args Pointer to opcode-sensitive arguments/result space
+ *
+ * Returns:
+ * OK: 0
+ * Error: -1
+ */
+extern int DeviceIoctl(const int opcode, void *args);
+
+#endif /* !defined(angsd_drivers_h) */
+
+/* EOF drivers.h */
diff --git a/gdb/rdi-share/etherdrv.c b/gdb/rdi-share/etherdrv.c
new file mode 100644
index 00000000000..b3156b226cd
--- /dev/null
+++ b/gdb/rdi-share/etherdrv.c
@@ -0,0 +1,737 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * etherdrv.c - Ethernet Driver for Angel.
+ */
+
+#ifdef __hpux
+# define _POSIX_SOURCE 1
+# define _HPUX_SOURCE 1
+# define _XOPEN_SOURCE 1
+#endif
+
+#include <stdio.h>
+#ifdef __hpux
+# define uint hide_HPs_uint
+#endif
+#ifdef STDC_HEADERS
+# include <unistd.h>
+# ifdef __hpux
+# undef uint
+# endif
+#endif
+#include <stdlib.h>
+#include <string.h>
+#ifdef __hpux
+# define uint hide_HPs_uint
+#endif
+#include <fcntl.h>
+#ifdef __hpux
+# undef uint
+#endif
+#include <errno.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include "host.h"
+
+#ifdef COMPILING_ON_WINDOWS
+ typedef char * caddr_t;
+# undef IGNORE
+# include <winsock.h>
+# include "angeldll.h"
+#else
+# ifdef __hpux
+# define uint hide_HPs_uint
+# endif
+# include <sys/types.h>
+# include <sys/socket.h>
+# ifdef __hpux
+# undef uint
+# endif
+# include <netdb.h>
+# include <sys/time.h>
+# include <sys/ioctl.h>
+# ifdef HAVE_SYS_FILIO_H
+# include <sys/filio.h>
+# endif
+# include <netinet/in.h>
+# include <arpa/inet.h>
+#endif
+
+#include "hsys.h"
+#include "devices.h"
+#include "angel_endian.h"
+#include "buffers.h"
+#include "hostchan.h"
+#include "params.h"
+#include "logging.h"
+#include "ethernet.h"
+
+
+#if !defined(COMPILING_ON_WINDOWS) && !defined(STDC_HEADERS)
+/* These two might not work for windows. */
+extern int sys_nerr;
+extern char * sys_errlist[];
+#endif
+
+#ifndef UNUSED
+# define UNUSED(x) (x = x) /* Silence compiler warnings */
+#endif
+
+/*
+ * forward declarations of static functions
+ */
+static int EthernetOpen(const char *name, const char *arg);
+static int EthernetMatch(const char *name, const char *arg);
+static void EthernetClose(void);
+static int EthernetRead(DriverCall *dc, bool block);
+static int EthernetWrite(DriverCall *dc);
+static int EthernetIoctl(const int opcode, void *args);
+
+/*
+ * the device descriptor for Ethernet
+ */
+DeviceDescr angel_EthernetDevice =
+{
+ "Ethernet",
+ EthernetOpen,
+ EthernetMatch,
+ EthernetClose,
+ EthernetRead,
+ EthernetWrite,
+ EthernetIoctl
+};
+
+/*
+ * descriptor for the socket that we talk down
+ */
+static int sock = -1;
+
+/*
+ * address of the remote target
+ */
+static struct sockaddr_in remote, *ia = &remote;
+
+/*
+ * array of dynamic port numbers on target
+ */
+static unsigned short int ports[2];
+
+/*
+ * Function: set_address
+ * Purpose: Try to get an address into an understandable form
+ *
+ * Params:
+ * Input: addr The address to parse
+ *
+ * Output: ia Structure to hold the parsed address
+ *
+ * Returns:
+ * OK: 0
+ * Error: -1
+ */
+static int set_address(const char *const addr, struct sockaddr_in *const ia)
+{
+ ia->sin_family = AF_INET;
+
+ /*
+ * Try address as a dotted decimal
+ */
+ ia->sin_addr.s_addr = inet_addr(addr);
+
+ /*
+ * If that failed, try it as a hostname
+ */
+ if (ia->sin_addr.s_addr == (u_int)-1)
+ {
+ struct hostent *hp = gethostbyname(addr);
+
+ if (hp == NULL)
+ return -1;
+
+ (void)memcpy((caddr_t)&ia->sin_addr, hp->h_addr, hp->h_length);
+ }
+
+ return 0;
+}
+
+/*
+ * Function: open_socket
+ * Purpose: Open a non-blocking UDP socket, and bind it to a port
+ * assigned by the system.
+ *
+ * Params: None
+ *
+ * Returns:
+ * OK: socket descriptor
+ * Error: -1
+ */
+static int open_socket(void)
+{
+ int sfd;
+#if 0 /* see #if 0 just below -VVV- */
+ int yesplease = 1;
+#endif
+ struct sockaddr_in local;
+
+ /*
+ * open the socket
+ */
+#ifdef COMPILING_ON_WINDOWS
+ if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
+ return -1;
+#else
+ if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+# ifdef DEBUG
+ perror("socket");
+# endif
+ return -1;
+ }
+#endif
+
+ /*
+ * 960731 KWelton
+ *
+ * I don't believe that this should be necessary - if we
+ * use select(), then non-blocking I/O is redundant.
+ * Unfortunately, select() appears to be broken (under
+ * Solaris, with a limited amount of time available for
+ * debug), so this code stays in for the time being
+ */
+#if 0
+ /*
+ * enable non-blocking I/O
+ */
+ if (ioctlsocket(sfd, FIONBIO, &yesplease) < 0)
+ {
+# ifdef DEBUG
+ perror("ioctl(FIONBIO)");
+# endif
+ closesocket(sfd);
+
+ return -1;
+ }
+#endif /* 0/1 */
+
+ /*
+ * bind local address to a system-assigned port
+ */
+ memset((char *)&local, 0, sizeof(local));
+ local.sin_family = AF_INET;
+ local.sin_port = htons(0);
+ local.sin_addr.s_addr = INADDR_ANY;
+ if (bind(sfd, (struct sockaddr *)&local, sizeof(local)) < 0)
+ {
+#ifdef DEBUG
+ perror("bind");
+#endif
+ closesocket(sfd);
+
+ return -1;
+ }
+
+ /*
+ * all done
+ */
+ return sfd;
+}
+
+/*
+ * Function: fetch_ports
+ * Purpose: Request assigned port numbers from remote target
+ *
+ * Params: None
+ *
+ * Returns: Nothing
+ *
+ * Post-conditions: This routine will *always* return something for the
+ * port numbers. If the remote target does not
+ * respond, then it makes something up - this allows
+ * the standard error message (from ardi.c) to be
+ * generated when the target is dead for whatever
+ * reason.
+ */
+static void fetch_ports(void)
+{
+ int i;
+ char ctrlpacket[10];
+ CtrlResponse response;
+
+ memset (ctrlpacket, 0, 10);
+ strcpy (ctrlpacket, CTRL_MAGIC);
+ memset (response, 0, sizeof(CtrlResponse));
+ /*
+ * we will try 3 times to elicit a response from the target
+ */
+ for (i = 0; i < 3; ++i)
+ {
+ struct timeval tv;
+ fd_set fdset;
+
+ /*
+ * send the magic string to the control
+ * port on the remote target
+ */
+ ia->sin_port = htons(CTRL_PORT);
+#ifdef DEBUG
+ printf("CTLR_PORT=0x%04x sin_port=0x%04x\n");
+#endif
+
+ if (sendto(sock, ctrlpacket, sizeof(ctrlpacket), 0,
+ (struct sockaddr *)ia, sizeof(*ia)) < 0)
+ {
+#ifdef DEBUG
+ perror("fetch_ports: sendto");
+#endif
+ return;
+ }
+
+ FD_ZERO(&fdset);
+ FD_SET(sock, &fdset);
+ tv.tv_sec = 0;
+ tv.tv_usec = 250000;
+
+ if (select(sock + 1, &fdset, NULL, NULL, &tv) < 0)
+ {
+#ifdef DEBUG
+ perror("fetch_ports: select");
+#endif
+ return;
+ }
+
+ if (FD_ISSET(sock, &fdset))
+ {
+ /*
+ * there is something there - read it
+ */
+ if (recv(sock, (char *)&response, sizeof(response), 0) < 0)
+ {
+#ifdef COMPILING_ON_WINDOWS
+ unsigned int werrno = WSAGetLastError();
+
+ if (werrno == WSAEWOULDBLOCK || werrno == 0)
+#else
+ if (errno == EWOULDBLOCK)
+#endif
+ {
+ --i;
+ continue;
+ }
+ else
+ {
+#ifdef DEBUG
+ perror("fetch_ports: recv");
+#endif
+ return;
+ }
+ }
+ {
+ /*
+ * XXX
+ *
+ * this is *very* unpleasant - try to match the structure
+ * layout
+ */
+ unsigned short *sptr = (unsigned short *)(response + RESP_DBUG);
+
+ if (strcmp(response, ctrlpacket) == 0)
+ {
+ ports[DBUG_INDEX] = htons(*sptr);
+ sptr++;
+ ports[APPL_INDEX] = htons(*sptr);
+ }
+
+#ifdef DEBUG
+ printf("fetch_ports: got response, DBUG=%d, APPL=%d\n",
+ ports[DBUG_INDEX], ports[APPL_INDEX]);
+#endif
+ return;
+ }
+ }
+ }
+
+ /*
+ * we failed to get a response
+ */
+#ifdef DEBUG
+ printf("fetch_ports: failed to get a real answer\n");
+#endif
+}
+
+/*
+ * Function: read_packet
+ * Purpose: read a packet, and pass it back to higher levels
+ *
+ * Params:
+ * In/Out: packet Holder for the read packet
+ *
+ * Returns: 1 - Packet is complete
+ * 0 - No complete packet read
+ *
+ * Post-conditions: Will call panic() if something goes wrong with the OS
+ */
+static int read_packet(struct data_packet *const packet)
+{
+ struct sockaddr_in from;
+ int nbytes, fromlen = sizeof(from);
+ DevChanID devchan;
+
+ /*
+ * try to get the packet
+ */
+ if ((nbytes = recvfrom(sock, (char *)(packet->data), packet->buf_len, 0,
+ (struct sockaddr *)&from, &fromlen)) < 0)
+ {
+#ifdef COMPILING_ON_WINDOWS
+ if (nbytes == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
+ MessageBox(GetFocus(), "Error receiving packet\n", "Angel", MB_OK | MB_ICONSTOP);
+#else
+ if (errno != EWOULDBLOCK)
+ {
+# ifdef DEBUG
+ perror("recv");
+# endif
+ panic("ethernet recv failure");
+ }
+#endif
+ return 0;
+ }
+
+#ifdef COMPILING_ON_WINDOWS
+ if (pfnProgressCallback != NULL && nbytes != SOCKET_ERROR)
+ {
+ progressInfo.nRead += nbytes;
+ (*pfnProgressCallback)(&progressInfo);
+ }
+#endif
+
+ /*
+ * work out where the packet was from
+ */
+ if (from.sin_addr.s_addr != remote.sin_addr.s_addr)
+ {
+ /*
+ * not from our target - ignore it
+ */
+#ifdef DEBUG
+ printf("read_packet: ignoring packet from %s\n",
+ inet_ntoa(from.sin_addr));
+#endif
+
+ return 0;
+ }
+ else if (ntohs(from.sin_port) == ports[DBUG_INDEX])
+ devchan = DC_DBUG;
+ else if (ntohs(from.sin_port) == ports[APPL_INDEX])
+ devchan = DC_APPL;
+ else
+ {
+ /*
+ * unknown port number - ignore it
+ */
+#ifdef DEBUG
+ printf("read_packet: ignore packet from port %hd\n",
+ htons(from.sin_port));
+#endif
+
+ return 0;
+ }
+
+#if defined(DEBUG) && !defined(DO_TRACE)
+ printf("EthernetRead: %d bytes from %s channel\n",
+ nbytes, (devchan == DC_DBUG) ? "DBUG" : "APPL");
+#endif
+
+#ifdef DO_TRACE
+ printf("[%d on %d]\n", nbytes, devchan);
+ {
+ int i = 0;
+ unsigned char *cptr = packet->data;
+
+ while (i < nbytes)
+ {
+ printf("<%02X ", *(cptr++));
+
+ if (!(++i % 16))
+ printf("\n");
+ }
+
+ if (i % 16)
+ printf("\n");
+ }
+#endif
+
+ /*
+ * OK - fill in the details
+ */
+ packet->type = devchan;
+ packet->len = nbytes;
+ return 1;
+}
+
+/**********************************************************************/
+
+/*
+ * Function: Ethernet_Open
+ * Purpose: Open the Ethernet device. See the documentation for
+ * DeviceOpen in drivers.h
+ *
+ * Post-conditions: Will have updated struct sockaddr_in remote (*ia)
+ * with the address of the remote target.
+ */
+static int EthernetOpen(const char *name, const char *arg)
+{
+#ifdef COMPILING_ON_WINDOWS
+ WORD wVersionRequested;
+ WSADATA wsaData;
+#endif
+ /*
+ * name is passed as e=<blah>, so skip 1st two characters
+ */
+ const char *etheraddr = name + 2;
+
+#ifdef DEBUG
+ printf("EthernetOpen: name `%s'\n", name);
+#endif
+
+ /* Check that the name is a valid one */
+ if (EthernetMatch(name, arg) != 0)
+ return -1;
+
+#ifdef COMPILING_ON_WINDOWS
+ wVersionRequested = MAKEWORD(1, 1);
+ if (WSAStartup(wVersionRequested, &wsaData) != 0)
+ /*
+ * Couldn't find a useable winsock.dll.
+ */
+ return -1;
+
+ if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
+ {
+ WSACleanup();
+
+ /*
+ * Couldn't find a winsock.dll with supported version.
+ */
+ return -1;
+ }
+#endif
+
+ memset((char *)ia, 0, sizeof(*ia));
+ if (set_address(etheraddr, ia) < 0)
+ {
+#ifdef COMPILING_ON_WINDOWS
+ /*
+ * SJ - I'm not sure that this is the correct way to handle this
+ * as Fail calls remote_disable and exits, while panic just exits.
+ * However at the time of writing remote_disable does nothing!
+ */
+ /* Panic("EthernetOpen: bad name `%s'\n", etheraddr); */
+#else
+ Fail("EthernetOpen: bad name `%s'\n", etheraddr);
+#endif
+ return -1;
+ }
+
+ if ((sock = open_socket()) < 0)
+ return -1;
+
+ /*
+ * fetch the port numbers assigned by the remote target
+ * to its Debug and Application sockets
+ */
+ fetch_ports();
+
+ return 0;
+}
+
+static int EthernetMatch(const char *name, const char *arg)
+{
+ /* IGNORE arg */
+ if (0)
+ arg = arg;
+
+ if (name == NULL)
+ return -1;
+
+ if (tolower(name[0]) != 'e' || name[1] != '=')
+ return -1;
+
+ return 0;
+}
+
+static void EthernetClose(void)
+{
+ if (sock >= 0)
+ {
+ closesocket(sock);
+ sock = -1;
+ }
+
+#ifdef COMPILING_ON_WINDOWS
+ WSACleanup();
+#endif
+}
+
+static int EthernetRead(DriverCall *dc, bool block)
+{
+ fd_set fdset;
+ struct timeval tv;
+ int err;
+
+ FD_ZERO(&fdset);
+ FD_SET(sock, &fdset);
+
+#ifdef COMPILING_ON_WINDOWS
+ UNUSED(block);
+ tv.tv_sec = tv.tv_usec = 0;
+#else
+ tv.tv_sec = 0;
+ tv.tv_usec = (block ? 10000 : 0);
+#endif
+
+ err = select(sock + 1, &fdset, NULL, NULL, &tv);
+
+ if (err < 0) {
+ if (errno == EINTR) {
+ return 0;
+ }
+ panic("ethernet select failure (errno=%i)",errno);
+ return 0;
+ }
+
+ if (FD_ISSET(sock, &fdset))
+ return read_packet(&dc->dc_packet);
+ else
+ return 0;
+}
+
+static int EthernetWrite(DriverCall *dc)
+{
+ int nbytes;
+ struct data_packet *packet = &dc->dc_packet;
+
+ if (packet->type == DC_DBUG)
+ ia->sin_port = htons(ports[DBUG_INDEX]);
+ else if (packet->type == DC_APPL)
+ ia->sin_port = htons(ports[APPL_INDEX]);
+ else
+ {
+ panic("EthernetWrite: unknown devchan");
+ return 0;
+ }
+
+#if defined(DEBUG) && !defined(DO_TRACE)
+ printf("EthernetWrite: %d bytes to %s channel\n",
+ packet->len, (packet->type == DC_DBUG) ? "DBUG" : "APPL");
+#endif
+
+#ifdef DO_TRACE
+ printf("[%d on %d]\n", packet->len, packet->type);
+ {
+ int i = 0;
+ unsigned char *cptr = packet->data;
+
+ while (i < packet->len)
+ {
+ printf(">%02X ", *(cptr++));
+
+ if (!(++i % 16))
+ printf("\n");
+ }
+
+ if (i % 16)
+ printf("\n");
+ }
+#endif
+
+ if ((nbytes = sendto(sock, (char *)(packet->data), packet->len, 0,
+ (struct sockaddr *)ia, sizeof(*ia))) != packet->len)
+ {
+#ifdef COMPILING_ON_WINDOWS
+ if (nbytes == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
+#else
+ if (nbytes < 0 && errno != EWOULDBLOCK)
+#endif
+ {
+#ifdef DEBUG
+ perror("sendto");
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ panic("ethernet send failure\n");
+#else
+ /* might not work for Windows */
+ panic("ethernet send failure [%s]\n",
+#ifdef STDC_HEADERS
+ strerror(errno));
+#else
+ errno < sys_nerr ? sys_errlist[errno] : "unknown errno");
+#endif /* STDC_HEADERS */
+#endif
+ }
+#ifdef DEBUG
+ else if (nbytes >= 0)
+ fprintf(stderr, "ethernet send: asked for %d, sent %d\n", packet->len, nbytes);
+#endif
+ return 0;
+ }
+
+#ifdef COMPILING_ON_WINDOWS
+ if (pfnProgressCallback != NULL && nbytes != SOCKET_ERROR)
+ {
+ progressInfo.nWritten += nbytes;
+ (*pfnProgressCallback)(&progressInfo);
+ }
+#endif
+
+ return 1;
+}
+
+static int EthernetIoctl(const int opcode, void *args)
+{
+#ifdef DEBUG
+ printf( "EthernetIoctl: op %d arg %x\n", opcode, args );
+#endif
+
+ /*
+ * IGNORE(opcode)
+ */
+ if (0)
+ {
+ int dummy = opcode;
+ UNUSED(dummy);
+ }
+ UNUSED(args);
+
+ switch ( opcode )
+ {
+ case DC_RESYNC:
+ {
+#ifdef DEBUG
+ printf( "EthernetIoctl: resync\n" );
+#endif
+ fetch_ports();
+ return 0;
+ }
+
+ default:
+ {
+ return -1;
+ }
+ }
+}
+
+/* EOF etherdrv.c */
diff --git a/gdb/rdi-share/ethernet.h b/gdb/rdi-share/ethernet.h
new file mode 100644
index 00000000000..930acedcf57
--- /dev/null
+++ b/gdb/rdi-share/ethernet.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * ethernet.h: Angel drivers for Ethernet using Fusion UDP/IP stack
+ */
+#ifndef angel_ethernet_h
+#define angel_ethernet_h
+
+/*
+ * the UDP ports that Angel Ethernet uses
+ */
+#define CTRL_PORT 1913
+
+/*
+ * the size of the largest packet accepted on the control socket
+ */
+#define CTRL_MAXPACKET 6
+
+/*
+ * This is the "magic number" sent to the control port to
+ * request that the channel port numbers are returned
+ */
+#define CTRL_MAGIC "Angel"
+
+/*
+ * Array used for responding to a request on the control port
+ */
+typedef unsigned char CtrlResponse[10];
+#define RESP_MAGIC 0
+#define RESP_DBUG 6
+#define RESP_APPL 8
+
+/*
+ * indices for accessing the array of port numbers sent
+ * over the control socket
+ */
+#define DBUG_INDEX 0
+#define APPL_INDEX 1
+
+#ifdef TARGET
+
+# include "devdriv.h"
+
+extern const struct angel_DeviceEntry angel_EthernetDevice;
+
+/*
+ * Function: angel_EthernetPoll
+ * Purpose: Poll Fusion for newly arrived packets
+ *
+ * Pre-conditions: Called in SVC mode with the lock
+ *
+ * Params:
+ * Input: data IGNORE'd
+ *
+ * Returns: Nothing
+ *
+ * Post-conditions: Will have passed any packets received along to
+ * higher levels
+ */
+void angel_EthernetPoll(unsigned int data);
+
+void angel_EthernetNOP(unsigned int data);
+
+
+/*
+ * Function: angel_FindEthernetConfigBlock
+ * Purpose: Search the Flash for an ethernet config block and return
+ * it if found.
+ *
+ * Params: None
+ *
+ * Returns: NULL if no config block found, the address if one is found.
+ *
+ */
+extern angel_EthernetConfigBlock *angel_FindEthernetConfigBlock(void);
+
+#else /* def TARGET */
+
+# ifndef COMPILING_ON_WINDOWS
+# define ioctlsocket(x, y, z) ioctl((x), (y), (z))
+# define closesocket(x) close(x)
+# endif
+
+#endif /* def TARGET */
+
+#endif /* ndef angel_ethernet_h */
+
+/* EOF ethernet.h */
diff --git a/gdb/rdi-share/host.h b/gdb/rdi-share/host.h
new file mode 100644
index 00000000000..2fdbf5f4541
--- /dev/null
+++ b/gdb/rdi-share/host.h
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+
+#ifndef _host_LOADED
+#define _host_LOADED 1
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#ifndef SEEK_SET
+# define SEEK_SET 0
+#endif
+#ifndef SEEK_CUR
+# define SEEK_CUR 1
+#endif
+#ifndef SEEK_END
+# define SEEK_END 2
+#endif
+
+/* The following for the benefit of compiling on SunOS */
+#ifndef offsetof
+# define offsetof(T, member) ((char *)&(((T *)0)->member) - (char *)0)
+#endif
+
+/* If under Cygwin, provide backwards compatibility with older
+ Cygwin compilers that don't define the current cpp define. */
+#ifdef __CYGWIN32__
+#ifndef __CYGWIN__
+#define __CYGWIN__
+#endif
+#endif
+
+/* A temporary sop to older compilers */
+#if defined (__NetBSD__) || defined (unix)
+# ifndef __unix /* (good for long-term portability?) */
+# define __unix 1
+# endif
+#endif
+
+#if defined(__unix)
+/* Generic unix -- hopefully a split into other variants will not be */
+/* needed. However, beware the 'bsd' test above and safe_toupper etc. */
+/* which cope with backwards (pre-posix/X/open) unix compatility. */
+# define COMPILING_ON_UNIX 1
+#endif
+#if defined(_WIN32)
+# define COMPILING_ON_WIN32 1
+# if !defined(__CYGWIN32__)
+# define COMPILING_ON_WINDOWS 1
+# endif
+#endif
+#if defined(_CONSOLE)
+# define COMPILING_ON_WINDOWS_CONSOLE 1
+# define COMPILING_ON_WINDOWS 1
+#endif
+/* The '(defined(__sparc) && defined(P_tmpdir) */
+/* && !defined(__svr4__))' is to detect gcc on SunOS. */
+/* C++ compilers don't have to define __STDC__ */
+#if (defined(__sparc) && defined(P_tmpdir))
+# if defined(__svr4__)
+# define COMPILING_ON_SOLARIS
+# else
+# define COMPILING_ON_SUNOS
+# endif
+#endif
+#ifdef __hppa
+# define COMPILING_ON_HPUX
+#endif
+
+/*
+ * The following typedefs may need alteration for obscure host machines.
+ */
+#if defined(__alpha) && defined(__osf__) /* =========================== */
+/* Under OSF the alpha has 64-bit pointers and 64-bit longs. */
+typedef int int32;
+typedef unsigned int unsigned32;
+/* IPtr and UPtr are 'ints of same size as pointer'. Do not use in */
+/* new code. Currently only used within 'ncc'. */
+typedef long int IPtr;
+typedef unsigned long int UPtr;
+
+#else /* all hosts except alpha under OSF ============================= */
+
+typedef long int int32;
+typedef unsigned long int unsigned32;
+/* IPtr and UPtr are 'ints of same size as pointer'. Do not use in */
+/* new code. Currently only used within 'ncc'. */
+#define IPtr int32
+#define UPtr unsigned32
+#endif /* ============================================================= */
+
+typedef short int int16;
+typedef unsigned short int unsigned16;
+typedef signed char int8;
+typedef unsigned char unsigned8;
+
+/* The following code defines the 'bool' type to be 'int' under C */
+/* and real 'bool' under C++. It also avoids warnings such as */
+/* C++ keyword 'bool' used as identifier. It can be overridden by */
+/* defining IMPLEMENT_BOOL_AS_ENUM or IMPLEMENT_BOOL_AS_INT. */
+#undef _bool
+
+#ifdef IMPLEMENT_BOOL_AS_ENUM
+ enum _bool { _false, _true };
+# define _bool enum _bool
+#elif defined(IMPLEMENT_BOOL_AS_INT) || !defined(__cplusplus)
+# define _bool int
+# define _false 0
+# define _true 1
+#endif
+
+#ifdef _bool
+# if defined(_MFC_VER) || defined(__CC_NORCROFT) /* When using MS Visual C/C++ v4.2 */
+# define bool _bool /* avoids "'bool' is reserved word" warning */
+# else
+# ifndef bool
+ typedef _bool bool;
+# endif
+# endif
+# define true _true
+# define false _false
+#endif
+
+#define YES true
+#define NO false
+#undef TRUE /* some OSF headers define as 1 */
+#define TRUE true
+#undef FALSE /* some OSF headers define as 1 */
+#define FALSE false
+
+/* 'uint' conflicts with some Unixen sys/types.h, so we now don't define it */
+typedef unsigned8 uint8;
+typedef unsigned16 uint16;
+typedef unsigned32 uint32;
+
+typedef unsigned Uint;
+typedef unsigned8 Uint8;
+typedef unsigned16 Uint16;
+typedef unsigned32 Uint32;
+
+#ifdef ALPHA_TASO_SHORT_ON_OSF /* was __alpha && __osf. */
+/* The following sets ArgvType for 64-bit pointers so that */
+/* DEC Unix (OSF) cc can be used with the -xtaso_short compiler option */
+/* to force pointers to be 32-bit. Not currently used since most/all */
+/* ARM tools accept 32 or 64 bit pointers transparently. See IPtr. */
+#pragma pointer_size (save)
+#pragma pointer_size (long)
+typedef char *ArgvType;
+#pragma pointer_size (restore)
+#else
+typedef char *ArgvType;
+#endif
+
+/*
+ * Rotate macros
+ */
+#define ROL_32(val, n) \
+((((unsigned32)(val) << (n)) | ((unsigned32)(val) >> (32-(n)))) & 0xFFFFFFFFL)
+#define ROR_32(val, n) \
+((((unsigned32)(val) >> (n)) | ((unsigned32)(val) << (32-(n)))) & 0xFFFFFFFFL)
+
+#ifdef COMPILING_ON_UNIX
+# define FOPEN_WB "w"
+# define FOPEN_RB "r"
+# define FOPEN_RWB "r+"
+# ifndef __STDC__ /* caveat RISCiX... */
+# define remove(file) unlink(file) /* a horrid hack, but probably best? */
+# endif
+#else
+# define FOPEN_WB "wb"
+# define FOPEN_RB "rb"
+# define FOPEN_RWB "rb+"
+#endif
+
+#ifndef FILENAME_MAX
+# define FILENAME_MAX 256
+#endif
+
+#if (!defined(__STDC__) && !defined(__cplusplus)) || defined(COMPILING_ON_SUNOS)
+/* Use bcopy rather than memmove, as memmove is not available. */
+/* There does not seem to be a header for bcopy. */
+void bcopy(const char *src, char *dst, int length);
+# define memmove(d,s,l) bcopy(s,d,l)
+
+/* BSD/SUN don't have strtoul(), but then strtol() doesn't barf on */
+/* overflow as required by ANSI... This bodge is horrid. */
+# define strtoul(s, ptr, base) strtol(s, ptr, base)
+
+/* strtod is present in the C-library but is not in stdlib.h */
+extern double strtod(const char *str, char **ptr);
+#endif
+
+/* For systems that do not define EXIT_SUCCESS and EXIT_FAILURE */
+#ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+#endif
+#ifndef EXIT_FAILURE
+# define EXIT_FAILURE 1
+#endif
+
+#ifndef IGNORE
+#define IGNORE(x) (x = x) /* Silence compiler warnings for unused arguments */
+#endif
+
+/* Define endian-ness of host */
+
+#if defined(__acorn) || defined(__mvs) || defined(_WIN32) || \
+ (defined(__alpha) && defined(__osf__))
+# define HOST_ENDIAN_LITTLE
+#elif defined(__sparc) || defined(macintosh)
+# define HOST_ENDIAN_BIG
+#else
+# define HOST_ENDIAN_UNKNOWN
+#endif
+
+#endif
+
+/* end of host.h */
diff --git a/gdb/rdi-share/hostchan.c b/gdb/rdi-share/hostchan.c
new file mode 100644
index 00000000000..3114c52d2f7
--- /dev/null
+++ b/gdb/rdi-share/hostchan.c
@@ -0,0 +1,1067 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * hostchan.c - Semi Synchronous Host side channel interface for Angel.
+ */
+
+#include <stdio.h>
+
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#else
+# include "winsock.h"
+# include "time.h"
+#endif
+#include "hsys.h"
+#include "host.h"
+#include "logging.h"
+#include "chandefs.h"
+#include "chanpriv.h"
+#include "devclnt.h"
+#include "buffers.h"
+#include "drivers.h"
+#include "adperr.h"
+#include "devsw.h"
+#include "hostchan.h"
+
+#ifndef UNUSED
+#define UNUSED(x) (x = x) /* Silence compiler warnings for unused arguments */
+#endif
+
+#define HEARTRATE 5000000
+
+/*
+ * list of available drivers, declared in drivers.c
+ */
+extern DeviceDescr *devices[];
+
+static DeviceDescr *deviceToUse = NULL;
+
+static struct Channel {
+ ChannelCallback callback;
+ void *callback_state;
+} channels[CI_NUM_CHANNELS];
+
+static unsigned char HomeSeq;
+static unsigned char OppoSeq;
+
+/*
+ * Handler for DC_APPL packets
+ */
+static DC_Appl_Handler dc_appl_handler = NULL;
+
+/*
+ * slots for registered asynchronous processing callback procedures
+ */
+#define MAX_ASYNC_CALLBACKS 8
+static unsigned int num_async_callbacks = 0;
+static Adp_Async_Callback async_callbacks[MAX_ASYNC_CALLBACKS];
+
+/*
+ * writeQueueRoot is the queue of write requests pending acknowledgement
+ * writeQueueSend is the queue of pending write requests which will
+ * be a subset of the list writeQueueRoot
+ */
+static Packet *writeQueueRoot = NULL;
+static Packet *writeQueueSend = NULL;
+static Packet *resend_pkt = NULL;
+static int resending = FALSE;
+
+/* heartbeat_enabled is a flag used to indicate whether the heartbeat is
+ * currently turned on, heartbeat_enabled will be false in situations
+ * where even though a heartbeat is being used it is problematical or
+ * dis-advantageous to have it turned on, for instance during the
+ * initial stages of boot up
+ */
+unsigned int heartbeat_enabled = FALSE;
+/* heartbeat_configured is set up by the device driver to indicate whether
+ * the heartbeat is being used during this debug session. In contrast to
+ * heartbeat_enabled it must not be changed during a session. The logic for
+ * deciding whether to send a heartbeat is: Is heartbeat_configured for this
+ * session? if and only if it is then if heartbeat[is currently]_enabled and
+ * we are due to send a pulse then send it
+ */
+unsigned int heartbeat_configured = TRUE;
+
+void Adp_initSeq( void ) {
+ Packet *tmp_pkt = writeQueueSend;
+
+ HomeSeq = 0;
+ OppoSeq = 0;
+ if ( writeQueueSend != NULL) {
+ while (writeQueueSend->pk_next !=NULL) {
+ tmp_pkt = writeQueueSend;
+ writeQueueSend = tmp_pkt->pk_next;
+ DevSW_FreePacket(tmp_pkt);
+ }
+ }
+ tmp_pkt = writeQueueRoot;
+ if ( writeQueueRoot == NULL)
+ return;
+
+ while (writeQueueRoot->pk_next !=NULL) {
+ tmp_pkt = writeQueueRoot;
+ writeQueueRoot = tmp_pkt->pk_next;
+ DevSW_FreePacket(tmp_pkt);
+ }
+ return;
+}
+
+/**********************************************************************/
+
+/*
+ * Function: DummyCallback
+ * Purpose: Default callback routine to handle unexpected input
+ * on a channel
+ *
+ * Params:
+ * Input: packet The received packet
+ *
+ * state Contains nothing of significance
+ *
+ * Returns: Nothing
+ */
+static void DummyCallback(Packet *packet, void *state)
+{
+ ChannelID chan;
+ const char fmt[] = "Unexpected read on channel %u, length %d\n";
+ char fmtbuf[sizeof(fmt) + 24];
+
+ UNUSED(state);
+
+ chan = *(packet->pk_buffer);
+ sprintf(fmtbuf, fmt, chan, packet->pk_length);
+ printf(fmtbuf);
+
+ /*
+ * junk this packet
+ */
+ DevSW_FreePacket(packet);
+}
+
+/*
+ * Function: BlockingCallback
+ * Purpose: Callback routine used to implement a blocking read call
+ *
+ * Params:
+ * Input: packet The received packet.
+ *
+ * Output: state Address of higher level's pointer to the received
+ * packet.
+ *
+ * Returns: Nothing
+ */
+static void BlockingCallback(Packet *packet, void *state)
+{
+ /*
+ * Pass the packet back to the caller which requested a packet
+ * from this channel. This also flags the completion of the I/O
+ * request to the blocking read call.
+ */
+ *((Packet **)state) = packet;
+}
+
+/*
+ * Function: FireCallback
+ * Purpose: Pass received packet along to the callback routine for
+ * the appropriate channel
+ *
+ * Params:
+ * Input: packet The received packet.
+ *
+ * Returns: Nothing
+ *
+ * Post-conditions: The Target-to-Host sequence number for the channel
+ * will have been incremented.
+ */
+static void FireCallback(Packet *packet)
+{
+ ChannelID chan;
+ struct Channel *ch;
+
+ /*
+ * is this a sensible channel number?
+ */
+ chan = *(packet->pk_buffer);
+ if (invalidChannelID(chan))
+ {
+ printf("ERROR: invalid ChannelID received from target\n");
+
+ /*
+ * free the packet's resources, 'cause no-one else will
+ */
+ DevSW_FreePacket(packet);
+ return;
+ }
+
+ /*
+ * looks OK - increment sequence number, and pass packet to callback
+ */
+ ch = channels + chan;
+ (ch->callback)(packet, ch->callback_state);
+}
+
+/**********************************************************************/
+
+/*
+ * These are the externally visible functions. They are documented
+ * in hostchan.h
+ */
+void Adp_addToQueue(Packet **head, Packet *newpkt)
+{
+ /*
+ * this is a bit of a hack
+ */
+ Packet *pk;
+
+ /*
+ * make sure that the hack we are about to use will work as expected
+ */
+ ASSERT(&(((Packet *)0)->pk_next) == 0, "bad struct Packet layout");
+
+#if defined(DEBUG) && 0
+ printf("Adp_addToQueue(%p, %p)\n", head, newpkt);
+#endif
+
+ /*
+ * here's the hack - it relies upon the next
+ * pointer being at the start of Packet.
+ */
+ pk = (Packet *)(head);
+
+ /*
+ * skip to the end of the queue
+ */
+ while (pk->pk_next != NULL)
+ pk = pk->pk_next;
+
+ /*
+ * now add the new element
+ */
+ newpkt->pk_next = NULL;
+ pk->pk_next = newpkt;
+}
+
+Packet *Adp_removeFromQueue(Packet **head)
+{
+ struct Packet *pk;
+
+ pk = *head;
+
+ if (pk != NULL)
+ *head = pk->pk_next;
+
+ return pk;
+}
+
+void Adp_SetLogEnable(int logEnableFlag)
+{
+ DevSW_SetLogEnable(logEnableFlag);
+}
+
+void Adp_SetLogfile(const char *filename)
+{
+ DevSW_SetLogfile(filename);
+}
+
+AdpErrs Adp_OpenDevice(const char *name, const char *arg,
+ unsigned int heartbeat_on)
+{
+ int i;
+ AdpErrs retc;
+ ChannelID chan;
+
+#ifdef DEBUG
+ printf("Adp_OpenDevice(%s, %s)\n", name, arg ? arg : "<NULL>");
+#endif
+
+ heartbeat_configured = heartbeat_on;
+ if (deviceToUse != NULL)
+ return adp_device_already_open;
+
+ for (i = 0; (deviceToUse = devices[i]) != NULL; ++i)
+ if (DevSW_Match(deviceToUse, name, arg) == adp_ok)
+ break;
+
+ if (deviceToUse == NULL)
+ return adp_device_not_found;
+
+ /*
+ * we seem to have found a suitable device driver, so try to open it
+ */
+ if ((retc = DevSW_Open(deviceToUse, name, arg, DC_DBUG)) != adp_ok)
+ {
+ /* we don't have a device to use */
+ deviceToUse = NULL;
+ return retc;
+ }
+
+ /*
+ * there is no explicit open on channels any more, so
+ * initialise state for all channels.
+ */
+ for (chan = 0; chan < CI_NUM_CHANNELS; ++chan)
+ {
+ struct Channel *ch = channels + chan;
+
+ ch->callback = DummyCallback;
+ ch->callback_state = NULL;
+ OppoSeq = 0;
+ HomeSeq = 0;
+ }
+
+ return adp_ok;
+}
+
+AdpErrs Adp_CloseDevice(void)
+{
+ AdpErrs retc;
+
+#ifdef DEBUG
+ printf("Adp_CloseDevice\n");
+#endif
+
+ if (deviceToUse == NULL)
+ return adp_device_not_open;
+
+ heartbeat_enabled = FALSE;
+
+ retc = DevSW_Close(deviceToUse, DC_DBUG);
+
+ /*
+ * we have to clear deviceToUse, even when the lower layers
+ * faulted the close, otherwise the condition will never clear
+ */
+ if (retc != adp_ok)
+ WARN("DevSW_Close faulted the call");
+
+ deviceToUse = NULL;
+ return retc;
+}
+
+AdpErrs Adp_Ioctl(int opcode, void *args)
+{
+#ifdef DEBUG
+ printf("Adp_Ioctl\n");
+#endif
+
+ if (deviceToUse == NULL)
+ return adp_device_not_open;
+
+ return DevSW_Ioctl(deviceToUse, opcode, args);
+}
+
+AdpErrs Adp_ChannelRegisterRead(const ChannelID chan,
+ const ChannelCallback cbfunc,
+ void *cbstate)
+{
+#ifdef DEBUG
+ printf("Adp_ChannelRegisterRead(%d, %p, %x)\n", chan, cbfunc, cbstate);
+#endif
+
+ if (deviceToUse == NULL)
+ return adp_device_not_open;
+
+ if (invalidChannelID(chan))
+ return adp_bad_channel_id;
+
+ if (cbfunc == NULL)
+ {
+ channels[chan].callback = DummyCallback;
+ channels[chan].callback_state = NULL;
+ }
+ else
+ {
+ channels[chan].callback = cbfunc;
+ channels[chan].callback_state = cbstate;
+ }
+
+ return adp_ok;
+}
+
+AdpErrs Adp_ChannelRead(const ChannelID chan, Packet **packet)
+{
+ struct Channel *ch;
+
+#ifdef DEBUG
+ printf("Adp_ChannelRead(%d, %x)\n", chan, *packet);
+#endif
+
+ if (deviceToUse == NULL)
+ return adp_device_not_open;
+
+ if (invalidChannelID(chan))
+ return adp_bad_channel_id;
+
+ /*
+ * if a callback has already been registered for this
+ * channel, then we do not allow this blocking read.
+ */
+ ch = channels + chan;
+ if (ch->callback != DummyCallback)
+ return adp_callback_already_registered;
+
+ /*
+ * OK, use our own callback to wait for a packet to arrive
+ * on this channel
+ */
+ ch->callback = BlockingCallback;
+ ch->callback_state = packet;
+ *packet = NULL;
+
+ /*
+ * keep polling until a packet appears for this channel
+ */
+ while (((volatile Packet *)(*packet)) == NULL)
+ /*
+ * this call will block until a packet is read on any channel
+ */
+ Adp_AsynchronousProcessing(async_block_on_read);
+
+ /*
+ * OK, the packet has arrived: clear the callback
+ */
+ ch->callback = DummyCallback;
+ ch->callback_state = NULL;
+
+ return adp_ok;
+}
+
+static AdpErrs ChannelWrite(
+ const ChannelID chan, Packet *packet, AsyncMode mode)
+{
+ struct Channel *ch;
+ unsigned char *cptr;
+
+#ifdef DEBUG
+ printf( "Adp_ChannelWrite(%d, %x)\n", chan, packet );
+#endif
+
+ if (deviceToUse == NULL)
+ return adp_device_not_open;
+
+ if (invalidChannelID(chan))
+ return adp_bad_channel_id;
+
+ /*
+ * fill in the channels header at the start of this buffer
+ */
+ ch = channels + chan;
+ cptr = packet->pk_buffer;
+ *cptr++ = chan;
+ *cptr = 0;
+ packet->pk_length += CHAN_HEADER_SIZE;
+
+ /*
+ * OK, add this packet to the write queue, and try to flush it out
+ */
+
+ Adp_addToQueue(&writeQueueSend, packet);
+ Adp_AsynchronousProcessing(mode);
+
+ return adp_ok;
+}
+
+AdpErrs Adp_ChannelWrite(const ChannelID chan, Packet *packet) {
+ return ChannelWrite(chan, packet, async_block_on_write);
+}
+
+AdpErrs Adp_ChannelWriteAsync(const ChannelID chan, Packet *packet) {
+ return ChannelWrite(chan, packet, async_block_on_nothing);
+}
+
+static AdpErrs send_resend_msg(DeviceID devid) {
+
+ /*
+ * Send a resend message, usually in response to a bad packet or
+ * a resend request */
+ Packet * packet;
+ packet = DevSW_AllocatePacket(CF_DATA_BYTE_POS);
+ packet->pk_buffer[CF_CHANNEL_BYTE_POS] = CI_PRIVATE;
+ packet->pk_buffer[CF_HOME_SEQ_BYTE_POS] = HomeSeq;
+ packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS] = OppoSeq;
+ packet->pk_buffer[CF_FLAGS_BYTE_POS] = CF_RELIABLE | CF_RESEND;
+ packet->pk_length = CF_DATA_BYTE_POS;
+ return DevSW_Write(deviceToUse, packet, devid);
+}
+
+static AdpErrs check_seq(unsigned char msg_home, unsigned char msg_oppo) {
+ Packet *tmp_pkt;
+
+ UNUSED(msg_oppo);
+ /*
+ * check if we have got an ack for anything and if so remove it from the
+ * queue
+ */
+ if (msg_home == (unsigned char)(OppoSeq+1)) {
+ /*
+ * arrived in sequence can increment our opposing seq number and remove
+ * the relevant packet from our queue
+ * check that the packet we're going to remove really is the right one
+ */
+ tmp_pkt = writeQueueRoot;
+ while ((tmp_pkt->pk_next != NULL) &&
+ (tmp_pkt->pk_next->pk_buffer[CF_HOME_SEQ_BYTE_POS]
+ != OppoSeq)){
+ tmp_pkt = tmp_pkt->pk_next;
+ }
+ OppoSeq++;
+ if (tmp_pkt->pk_next == NULL) {
+#ifdef DEBUG
+ printf("trying to remove a non existant packet\n");
+#endif
+ return adp_bad_packet;
+ }
+ else {
+ Packet *tmp = tmp_pkt->pk_next;
+#ifdef RET_DEBUG
+ printf("removing a packet from the root queue\n");
+#endif
+ tmp_pkt->pk_next = tmp_pkt->pk_next->pk_next;
+ /* remove the appropriate packet */
+ DevSW_FreePacket(tmp);
+ return adp_ok;
+ }
+ }
+ else if (msg_home < (unsigned char) (OppoSeq+1)){
+ /* already received this message */
+#ifdef RET_DEBUG
+ printf("sequence numbers low\n");
+#endif
+ return adp_seq_low;
+ }
+ else { /* we've missed something */
+#ifdef RET_DEBUG
+ printf("sequence numbers high\n");
+#endif
+ return adp_seq_high;
+ }
+}
+
+static unsigned long tv_diff(const struct timeval *time_now,
+ const struct timeval *time_was)
+{
+ return ( ((time_now->tv_sec * 1000000) + time_now->tv_usec)
+ - ((time_was->tv_sec * 1000000) + time_was->tv_usec) );
+}
+
+#if !defined(__unix) && !defined(__CYGWIN32__)
+static void gettimeofday( struct timeval *time_now, void *dummy )
+{
+ time_t t = clock();
+ UNUSED(dummy);
+ time_now->tv_sec = t/CLOCKS_PER_SEC;
+ time_now->tv_usec = (t%CLOCKS_PER_SEC)*(1000000/CLOCKS_PER_SEC);
+}
+#endif
+
+static AdpErrs pacemaker(void)
+{
+ Packet *packet;
+
+ packet = DevSW_AllocatePacket(CF_DATA_BYTE_POS);
+ if (packet == NULL) {
+ printf("ERROR: could not allocate a packet in pacemaker()\n");
+ return adp_malloc_failure;
+ }
+ packet->pk_buffer[CF_CHANNEL_BYTE_POS] = CI_PRIVATE;
+ packet->pk_buffer[CF_HOME_SEQ_BYTE_POS] = HomeSeq;
+ packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS] = OppoSeq;
+ packet->pk_buffer[CF_FLAGS_BYTE_POS] = CF_RELIABLE | CF_HEARTBEAT;
+ packet->pk_length = CF_DATA_BYTE_POS;
+ return DevSW_Write(deviceToUse, packet, DC_DBUG);
+}
+
+#ifdef FAKE_BAD_LINE_RX
+static AdpErrs fake_bad_line_rx( const Packet *const packet, AdpErrs adp_err )
+{
+ static unsigned int bl_num = 0;
+
+ if ( (packet != NULL)
+ && (bl_num++ >= 20 )
+ && ((bl_num % FAKE_BAD_LINE_RX) == 0))
+ {
+ printf("DEBUG: faking a bad packet\n");
+ return adp_bad_packet;
+ }
+ return adp_err;
+}
+#endif /* def FAKE_BAD_LINE_RX */
+
+#ifdef FAKE_BAD_LINE_TX
+static unsigned char tmp_ch;
+
+static void fake_bad_line_tx( void )
+{
+ static unsigned int bl_num = 0;
+
+ /* give the thing a chance to boot then try corrupting stuff */
+ if ( (bl_num++ >= 20) && ((bl_num % FAKE_BAD_LINE_TX) == 0))
+ {
+ printf("DEBUG: faking a bad packet for tx\n");
+ tmp_ch = writeQueueSend->pk_buffer[CF_FLAGS_BYTE_POS];
+ writeQueueSend->pk_buffer[CF_FLAGS_BYTE_POS] = 77;
+ }
+}
+
+static void unfake_bad_line_tx( void )
+{
+ static unsigned int bl_num = 0;
+
+ /*
+ * must reset the packet so that its not corrupted when we
+ * resend it
+ */
+ if ( (bl_num >= 20) && ((bl_num % FAKE_BAD_LINE_TX) != 0))
+ {
+ writeQueueSend->pk_buffer[CF_FLAGS_BYTE_POS] = tmp_ch;
+ }
+}
+#endif /* def FAKE_BAD_LINE_TX */
+
+/*
+ * NOTE: we are assuming that a resolution of microseconds will
+ * be good enough for the purporses of the heartbeat. If this proves
+ * not to be the case then we may need a rethink, possibly using
+ * [get,set]itimer
+ */
+static struct timeval time_now;
+static struct timeval time_lastalive;
+
+static void async_process_dbug_read( const AsyncMode mode,
+ bool *const finished )
+{
+ Packet *packet;
+ unsigned int msg_home, msg_oppo;
+ AdpErrs adp_err;
+
+ adp_err = DevSW_Read(deviceToUse, DC_DBUG, &packet,
+ mode == async_block_on_read );
+
+#ifdef FAKE_BAD_LINE_RX
+ adp_err = fake_bad_line_rx( packet, adp_err );
+#endif
+
+ if (adp_err == adp_bad_packet) {
+ /* We got a bad packet, ask for a resend, send a resend message */
+#ifdef DEBUG
+ printf("received a bad packet\n");
+#endif
+ send_resend_msg(DC_DBUG);
+ }
+ else if (packet != NULL)
+ {
+ /* update the heartbeat clock */
+ gettimeofday(&time_lastalive, NULL);
+
+ /*
+ * we got a live one here - were we waiting for it?
+ */
+ if (mode == async_block_on_read)
+ /* not any more */
+ *finished = TRUE;
+#ifdef RETRANS
+
+ if (packet->pk_length < CF_DATA_BYTE_POS) {
+ /* we've got a packet with no header information! */
+ printf("ERROR: packet with no transport header\n");
+ send_resend_msg(DC_DBUG);
+ }
+ else {
+#ifdef RET_DEBUG
+ unsigned int c;
+#endif
+ /*
+ * TODO: Check to see if its acknowledgeing anything, remove
+ * those packets it is from the queue. If its a retrans add the
+ * packets to the queue
+ */
+ msg_home = packet->pk_buffer[CF_HOME_SEQ_BYTE_POS];
+ msg_oppo = packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS];
+#ifdef RET_DEBUG
+ printf("msg seq numbers are hseq 0x%x oseq 0x%x\n",
+ msg_home, msg_oppo);
+ for (c=0;c<packet->pk_length;c++)
+ printf("%02.2x", packet->pk_buffer[c]);
+ printf("\n");
+#endif
+ /* now was it a resend request? */
+ if ((packet->pk_buffer[CF_FLAGS_BYTE_POS])
+ & CF_RESEND) {
+ /* we've been asked for a resend so we had better resend */
+ /*
+ * I don't think we can use a resend as acknowledgement for
+ * anything so lets not do this for the moment
+ * check_seq(msg_home, msg_oppo);
+ */
+#ifdef RET_DEBUG
+ printf("received a resend request\n");
+#endif
+ if (HomeSeq != msg_oppo) {
+ int found = FALSE;
+ /* need to resend from msg_oppo +1 upwards */
+ DevSW_FreePacket(packet);
+ resending = TRUE;
+ /* find the correct packet to resend from */
+ packet = writeQueueRoot;
+ while (((packet->pk_next) != NULL) && !found) {
+ if ((packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS])
+ != msg_oppo+1) {
+ resend_pkt = packet;
+ found = TRUE;
+ }
+ packet = packet->pk_next;
+ }
+ if (!found) {
+ panic("trying to resend non-existent packets\n");
+ }
+ }
+ else if (OppoSeq != msg_home) {
+ /*
+ * send a resend request telling the target where we think
+ * the world is at
+ */
+ DevSW_FreePacket(packet);
+ send_resend_msg(DC_DBUG);
+ }
+ }
+ else {
+ /* not a resend request, lets check the sequence numbers */
+
+ if ((packet->pk_buffer[CF_CHANNEL_BYTE_POS] != CI_HBOOT) &&
+ (packet->pk_buffer[CF_CHANNEL_BYTE_POS] != CI_TBOOT)) {
+ adp_err = check_seq(msg_home, msg_oppo);
+ if (adp_err == adp_seq_low) {
+ /* we have already received this packet so discard */
+ DevSW_FreePacket(packet);
+ }
+ else if (adp_err == adp_seq_high) {
+ /*
+ * we must have missed a packet somewhere, discard this
+ * packet and tell the target where we are
+ */
+ DevSW_FreePacket(packet);
+ send_resend_msg(DC_DBUG);
+ }
+ else
+ /*
+ * now pass the packet to whoever is waiting for it
+ */
+ FireCallback(packet);
+ }
+ else
+ FireCallback(packet);
+ }
+ }
+#else
+ /*
+ * now pass the packet to whoever is waiting for it
+ */
+ FireCallback(packet);
+#endif
+ }
+}
+
+static void async_process_appl_read(void)
+{
+ Packet *packet;
+ AdpErrs adp_err;
+
+ /* see if there is anything for the DC_APPL channel */
+ adp_err = DevSW_Read(deviceToUse, DC_APPL, &packet, FALSE);
+
+ if (adp_err == adp_ok && packet != NULL)
+ {
+ /* got an application packet on a shared device */
+
+#ifdef DEBUG
+ printf("GOT DC_APPL PACKET: len %d\nData: ", packet->pk_length);
+ {
+ unsigned int c;
+ for ( c = 0; c < packet->pk_length; ++c )
+ printf( "%02X ", packet->pk_buffer[c] );
+ }
+ printf("\n");
+#endif
+
+ if (dc_appl_handler != NULL)
+ {
+ dc_appl_handler( deviceToUse, packet );
+ }
+ else
+ {
+ /* for now, just free it!! */
+#ifdef DEBUG
+ printf("no handler - dropping DC_APPL packet\n");
+#endif
+ DevSW_FreePacket( packet );
+ }
+ }
+}
+
+static void async_process_write( const AsyncMode mode,
+ bool *const finished )
+{
+ Packet *packet;
+
+#ifdef DEBUG
+ static unsigned int num_written = 0;
+#endif
+
+ /*
+ * NOTE: here we rely in the fact that any packet in the writeQueueSend
+ * section of the queue will need its sequence number setting up while
+ * and packet in the writeQueueRoot section will have its sequence
+ * numbers set up from when it was first sent so we can easily look
+ * up the packet numbers when(if) we want to resend the packet.
+ */
+
+#ifdef DEBUG
+ if (writeQueueSend!=NULL)
+ printf("written 0x%x\n",num_written += writeQueueSend->pk_length);
+#endif
+ /*
+ * give the switcher a chance to complete any partial writes
+ */
+ if (DevSW_FlushPendingWrite(deviceToUse) == adp_write_busy)
+ {
+ /* no point trying a new write */
+ return;
+ }
+
+ /*
+ * now see whether there is anything to write
+ */
+ packet = NULL;
+ if (resending) {
+ packet = resend_pkt;
+#ifdef RET_DEBUG
+ printf("resending hseq 0x%x oseq 0x%x\n",
+ packet->pk_buffer[CF_HOME_SEQ_BYTE_POS],
+ packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS]);
+#endif
+ }
+ else if (writeQueueSend != NULL) {
+#ifdef RETRANS
+ /* set up the sequence number on the packet */
+ packet = writeQueueSend;
+ HomeSeq++;
+ (writeQueueSend->pk_buffer[CF_OPPO_SEQ_BYTE_POS])
+ = OppoSeq;
+ (writeQueueSend->pk_buffer[CF_HOME_SEQ_BYTE_POS])
+ = HomeSeq;
+ (writeQueueSend->pk_buffer[CF_FLAGS_BYTE_POS])
+ = CF_RELIABLE;
+# ifdef RET_DEBUG
+ printf("sending packet with hseq 0x%x oseq 0x%x\n",
+ writeQueueSend->pk_buffer[CF_HOME_SEQ_BYTE_POS],
+ writeQueueSend->pk_buffer[CF_OPPO_SEQ_BYTE_POS]);
+# endif
+#endif /* RETRANS */
+ }
+
+ if (packet != NULL) {
+ AdpErrs dev_err;
+
+#ifdef FAKE_BAD_LINE_TX
+ fake_bad_line_tx();
+#endif
+
+ dev_err = DevSW_Write(deviceToUse, packet, DC_DBUG);
+ if (dev_err == adp_ok) {
+#ifdef RETRANS
+ if (resending) {
+ /* check to see if we've recovered yet */
+ if ((packet->pk_next) == NULL){
+# ifdef RET_DEBUG
+ printf("we have recovered\n");
+# endif
+ resending = FALSE;
+ }
+ else {
+ resend_pkt = resend_pkt->pk_next;
+ }
+ }
+ else {
+ /*
+ * move the packet we just sent from the send queue to the root
+ */
+ Packet *tmp_pkt, *tmp;
+
+# ifdef FAKE_BAD_LINE_TX
+ unfake_bad_line_tx();
+# endif
+
+ tmp_pkt = writeQueueSend;
+ writeQueueSend = writeQueueSend->pk_next;
+ tmp_pkt->pk_next = NULL;
+ if (writeQueueRoot == NULL)
+ writeQueueRoot = tmp_pkt;
+ else {
+ tmp = writeQueueRoot;
+ while (tmp->pk_next != NULL) {
+ tmp = tmp->pk_next;
+ }
+ tmp->pk_next = tmp_pkt;
+ }
+ }
+#else /* not RETRANS */
+ /*
+ * switcher has taken the write, so remove it from the
+ * queue, and free its resources
+ */
+ DevSW_FreePacket(Adp_removeFromQueue(&writeQueueSend));
+#endif /* if RETRANS ... else ... */
+
+ if (mode == async_block_on_write)
+ *finished = DevSW_WriteFinished(deviceToUse);
+
+ } /* endif write ok */
+ }
+ else /* packet == NULL */
+ {
+ if (mode == async_block_on_write)
+ *finished = DevSW_WriteFinished(deviceToUse);
+ }
+}
+
+static void async_process_heartbeat( void )
+{
+ /* check to see whether we need to send a heartbeat */
+ gettimeofday(&time_now, NULL);
+
+ if (tv_diff(&time_now, &time_lastalive) >= HEARTRATE)
+ {
+ /*
+ * if we've not booted then don't do send a heartrate the link
+ * must be reliable enough for us to boot without any clever stuff,
+ * if we can't do this then theres little chance of the link staying
+ * together even with the resends etc
+ */
+ if (heartbeat_enabled) {
+ gettimeofday(&time_lastalive, NULL);
+ pacemaker();
+ }
+ }
+}
+
+static void async_process_callbacks( void )
+{
+ /* call any registered asynchronous callbacks */
+ unsigned int i;
+ for ( i = 0; i < num_async_callbacks; ++i )
+ async_callbacks[i]( deviceToUse, &time_now );
+}
+
+void Adp_AsynchronousProcessing(const AsyncMode mode)
+{
+ bool finished = FALSE;
+#ifdef DEBUG
+ unsigned int wc = 0, dc = 0, ac = 0, hc = 0;
+# define INC_COUNT(x) ((x)++)
+#else
+# define INC_COUNT(x)
+#endif
+
+ if ((time_lastalive.tv_sec == 0) && (time_lastalive.tv_usec == 0)) {
+ /* first time through, needs initing */
+ gettimeofday(&time_lastalive, NULL);
+ }
+
+ /* main loop */
+ do
+ {
+ async_process_write( mode, &finished );
+ INC_COUNT(wc);
+
+ if ( ! finished && mode != async_block_on_write )
+ {
+ async_process_dbug_read( mode, &finished );
+ INC_COUNT(dc);
+ }
+
+ if ( ! finished && mode != async_block_on_write )
+ {
+ async_process_appl_read();
+ INC_COUNT(ac);
+ }
+
+ if ( ! finished )
+ {
+ if (heartbeat_configured)
+ async_process_heartbeat();
+ async_process_callbacks();
+ INC_COUNT(hc);
+ }
+
+ } while (!finished && mode != async_block_on_nothing);
+
+#ifdef DEBUG
+ if ( mode != async_block_on_nothing )
+ printf( "Async: %s - w %d, d %d, a %d, h %d\n",
+ mode == async_block_on_write ? "blk_write" : "blk_read",
+ wc, dc, ac, hc );
+#endif
+}
+
+/*
+ * install a handler for DC_APPL packets (can be NULL), returning old one.
+ */
+DC_Appl_Handler Adp_Install_DC_Appl_Handler(const DC_Appl_Handler handler)
+{
+ DC_Appl_Handler old_handler = dc_appl_handler;
+
+#ifdef DEBUG
+ printf( "Installing DC_APPL handler %x (old %x)\n", handler, old_handler );
+#endif
+
+ dc_appl_handler = handler;
+ return old_handler;
+}
+
+
+/*
+ * add an asynchronous processing callback to the list
+ * TRUE == okay, FALSE == no more async processing slots
+ */
+bool Adp_Install_Async_Callback( const Adp_Async_Callback callback_proc )
+{
+ if ( num_async_callbacks < MAX_ASYNC_CALLBACKS && callback_proc != NULL )
+ {
+ async_callbacks[num_async_callbacks] = callback_proc;
+ ++num_async_callbacks;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+/*
+ * delay for a given period (in microseconds)
+ */
+void Adp_delay(unsigned int period)
+{
+ struct timeval tv;
+
+#ifdef DEBUG
+ printf("delaying for %d microseconds\n", period);
+#endif
+ tv.tv_sec = (period / 1000000);
+ tv.tv_usec = (period % 1000000);
+
+ (void)select(0, NULL, NULL, NULL, &tv);
+}
+
+/* EOF hostchan.c */
diff --git a/gdb/rdi-share/hostchan.h b/gdb/rdi-share/hostchan.h
new file mode 100644
index 00000000000..3e6d26fd792
--- /dev/null
+++ b/gdb/rdi-share/hostchan.h
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ */
+#ifndef angsd_hostchan_h
+#define angsd_hostchan_h
+
+/* If under Cygwin, provide backwards compatibility with older
+ Cygwin compilers that don't define the current cpp define. */
+#ifdef __CYGWIN32__
+#ifndef __CYGWIN__
+#define __CYGWIN__
+#endif
+#endif
+
+/* A temporary sop to older compilers */
+#if defined (__NetBSD__) || defined (unix)
+# ifndef __unix /* (good for long-term portability?) */
+# define __unix 1
+# endif
+#endif
+
+/* struct timeval */
+#if defined(__unix) || defined(__CYGWIN32__)
+# include <sys/time.h>
+#else
+# include "winsock.h"
+# include "time.h"
+#endif
+
+#include "chandefs.h"
+#include "adperr.h"
+#include "devsw.h"
+
+/*
+ * asynchronous processing modes
+ */
+enum AsyncMode
+{
+ async_block_on_nothing,
+ async_block_on_read,
+ async_block_on_write
+};
+
+#ifndef __cplusplus
+typedef enum AsyncMode AsyncMode;
+#endif
+
+/*
+ * prototype for channels callback function
+ */
+typedef void (*ChannelCallback)(Packet *packet, void *state);
+
+/*
+ * Function: Adp_initSeq
+ * Purpose: initialise the channel protocol and sequence numbers
+ *
+ * Params: none
+ *
+ * Returns: Nothing
+ */
+extern void Adp_initSeq(void);
+
+/*
+ * Function: Adp_addToQueue
+ * Purpose: chain a Packet to the end of a linked list of such structures
+ *
+ * Params:
+ * In/Out: head Head of the linked list
+ *
+ * newpkt Packet to be chained onto the list
+ *
+ * Returns: Nothing
+ */
+extern void Adp_addToQueue(Packet **head, Packet *newpkt);
+
+/*
+ * Function: removeFromQueue
+ * Purpose: remove a Packet from the head of a linked list of such structures
+ *
+ * Params:
+ * In/Out: head Head of the linked list
+ *
+ * Returns: Old head from the linked list
+ *
+ * Post-conditions: Second element in the list will be the new head.
+ */
+
+extern Packet *Adp_removeFromQueue(Packet **head);
+
+/*
+ * Set log file and Enable/disable logging of ADP packets to file.
+ */
+
+void Adp_SetLogfile(const char *filename);
+void Adp_SetLogEnable(int logEnableFlag);
+
+/*
+ * Function: Adp_OpenDevice
+ * Purpose: Open a device to use for channels communication. This is a
+ * very thin veneer to the device drivers: what hostchan.c
+ * will do is call DeviceMatch for each device driver until it
+ * finds a driver that will accept name and arg, then call
+ * DeviceOpen for that device.
+ *
+ * Pre-conditions: No previous open is still active
+ *
+ * Params:
+ * Input: name Identifies which device to open. This can either be
+ * a host specific identifier (e.g. "/dev/ttya",
+ * "COM1:"), or a number which is used to refer to
+ * `standard' interfaces, so "1" would be the first host
+ * interface, "2" the second, and so on.
+ *
+ * arg Driver specific arguments. For example, some serial
+ * drivers accept speed and control arguments such as
+ * "9600" or "19200/NO_BREAK". These arguments are
+ * completely free-form: it is the individual drivers
+ * which do the necessary interpretation.
+ *
+ * heartbeat_on Incicates if the heartbeat is configured to be
+ * used or not, true if it is, false otherwise
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_known,
+ * adp_device_open_failed
+ * adp_device_already_open
+ */
+AdpErrs Adp_OpenDevice(const char *name, const char *arg,
+ unsigned int heartbeat_on);
+
+/*
+ * Function: Adp_CloseDevice
+ * Purpose: Close the device used for channels communication.
+ *
+ * Params: None
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_open
+ */
+AdpErrs Adp_CloseDevice(void);
+
+/*
+ * Function: Adp_Ioctl
+ * Purpose: Perform miscellaneous control operations on
+ * the device used for channels communication.
+ * This is a minimal veneer to DevSW_Ioctl.
+ *
+ * Params:
+ * Input: opcode Reason code indicating the operation to perform.
+ * In/Out: args Pointer to opcode-sensitive arguments/result space.
+ *
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_open, adp_failed
+ */
+AdpErrs Adp_Ioctl(int opcode, void *args);
+
+/*
+ * Function: Adp_ChannelRegisterRead
+ * Purpose: Register a callback function for received packets on a given
+ * channel
+ *
+ * Params:
+ * Input: chan The channel the callback function is for.
+ *
+ * cbfunc The callback function. If NULL, then the current
+ * callback is removed.
+ *
+ * cbstate State pointer to pass into the callback function
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_open
+ * adp_bad_channel_id
+ *
+ * Post-conditions: The callback function is responsible for freeing the
+ * packet that is passed to it, when that packet is
+ * no longer needed.
+ */
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+extern AdpErrs Adp_ChannelRegisterRead(const ChannelID chan,
+ const ChannelCallback cbfunc,
+ void *cbstate);
+
+#ifdef __cplusplus
+ }
+#endif
+/*
+ * Function: Adp_ChannelRead
+ * Purpose: Wait until a packet has been read for a given channel, and
+ * then return it. Callbacks for other channels are still
+ * active while this read is blocking.
+ *
+ * Pre-conditions: No callback has been already been registered for
+ * the channel.
+ *
+ * Params:
+ * Input: chan The channel to read.
+ *
+ * Output: packet The received packet.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_open
+ * adp_bad_channel_id
+ * adp_callback_already_registered
+ *
+ * Post-conditions: The calling function is responsible for freeing the
+ * received packet, when that packet is no longer
+ * needed.
+ */
+AdpErrs Adp_ChannelRead(const ChannelID chan, Packet **packet);
+
+/*
+ * Function: Adp_ChannelWrite
+ * Purpose: Write a packet to the given channel
+ *
+ * Pre-conditions: Channel must have been previously opened.
+ *
+ * Params:
+ * Input: chan The channel to write.
+ *
+ * packet The packet to write.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_open
+ * adp_bad_channel_id
+ *
+ * Post-conditions: The packet being written becomes the "property" of
+ * Adp_ChannelWrite, which is responsible for freeing
+ * the packet when it is no longer needed.
+ */
+AdpErrs Adp_ChannelWrite(const ChannelID chan, Packet *packet);
+
+/*
+ * Function: Adp_ChannelWriteAsync
+ * Purpose: Write a packet to the given channel, but don't wait
+ * for the write to complete before returning.
+ *
+ * Pre-conditions: Channel must have been previously opened.
+ *
+ * Params:
+ * Input: chan The channel to write.
+ *
+ * packet The packet to write.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_open
+ * adp_bad_channel_id
+ *
+ * Post-conditions: The packet being written becomes the "property" of
+ * Adp_ChannelWrite, which is responsible for freeing
+ * the packet when it is no longer needed.
+ */
+AdpErrs Adp_ChannelWriteAsync(const ChannelID chan, Packet *packet);
+
+/*
+ * Function: Adp_AsynchronousProcessing
+ * Purpose: This routine should be called from persistent any idle loop
+ * to give the data I/O routines a chance to poll for packet
+ * activity. Depending upon the requested mode, this routine
+ * may, or may not, block.
+ *
+ * Params:
+ * Input: mode Specifies whether to block until a complete packet
+ * has been read, all pending writes have completed,
+ * or not to block at all.
+ *
+ * Returns: Nothing.
+ */
+void Adp_AsynchronousProcessing(const AsyncMode mode);
+
+/*
+ * prototype for DC_APPL packet handler
+ */
+typedef void (*DC_Appl_Handler)(const DeviceDescr *device, Packet *packet);
+
+/*
+ * install a handler for DC_APPL packets (can be NULL), returning old one.
+ */
+DC_Appl_Handler Adp_Install_DC_Appl_Handler(const DC_Appl_Handler handler);
+
+/*
+ * prototype for asynchronous processing callback
+ */
+typedef void (*Adp_Async_Callback)(const DeviceDescr *device,
+ const struct timeval *const time_now);
+
+/*
+ * add an asynchronous processing callback to the list
+ * TRUE == okay, FALSE == no more async processing slots
+ */
+bool Adp_Install_Async_Callback( const Adp_Async_Callback callback_proc );
+
+/*
+ * delay for a given period (in microseconds)
+ */
+void Adp_delay(unsigned int period);
+
+#endif /* ndef angsd_hostchan_h */
+
+/* EOF hostchan.h */
diff --git a/gdb/rdi-share/hsys.c b/gdb/rdi-share/hsys.c
new file mode 100644
index 00000000000..1d47a85fe46
--- /dev/null
+++ b/gdb/rdi-share/hsys.c
@@ -0,0 +1,917 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * Host C Library support functions.
+ *
+ * $Revision$
+ * $Date$
+ */
+
+#ifdef DEBUG
+# include <ctype.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <time.h>
+
+#include "adp.h"
+#include "host.h"
+#include "ardi.h"
+#include "buffers.h"
+#include "channels.h" /* Channel interface. */
+#include "angel_endian.h"
+#include "logging.h" /* Angel support functions. */
+#include "msgbuild.h"
+#include "sys.h"
+#include "hsys.h" /* Function and structure declarations. */
+#include "hostchan.h"
+
+#define FILEHANDLE int
+
+/* Note: no statics allowed. All globals must be malloc()ed on the heap.
+ The state struct is used for this purpose. See 'hsys.h'. */
+/* This is the message handler function passed to the channel manager in
+ HostSysInit. It is called whenever a message is received. 'buffptr'
+ points to the message body. Functionality is provided by the debugger
+ toolkit. The routine is very loosely based on the HandleSWI routine from
+ armos.c in the armulator source. */
+/* These routines could be tested by providing a simple interface to armsd,
+ and running them in that. */
+
+
+/* taken staight from armulator source */
+#ifdef __riscos
+ extern int _fisatty(FILE *);
+# define isatty_(f) _fisatty(f)
+# define EMFILE -1
+# define EBADF -1
+ int _kernel_escape_seen(void) { return 0 ;}
+#else
+# if defined(_WINDOWS) || defined(_CONSOLE)
+# define isatty_(f) (f == stdin || f == stdout)
+# else
+# ifdef __ZTC__
+# include <io.h>
+# define isatty_(f) isatty((f)->_file)
+# else
+# ifdef macintosh
+# include <ioctl.h>
+# define isatty_(f) (~ioctl((f)->_file,FIOINTERACTIVE,NULL))
+# else
+# define isatty_(f) isatty(fileno(f))
+# endif
+# endif
+# endif
+#endif
+
+/* Set up the state block, filetable and register the C lib callback fn */
+int HostSysInit(const struct Dbg_HostosInterface *hostif, char **cmdline,
+ hsys_state **stateptr)
+{
+ ChannelCallback HandleMessageFPtr = (ChannelCallback) HandleSysMessage;
+ int i;
+ *stateptr = (hsys_state *)malloc(sizeof(hsys_state));
+
+ if (*stateptr == NULL) return RDIError_OutOfStore;
+
+ (*stateptr)->hostif=hostif;
+ (*stateptr)->last_errno=0;
+ (*stateptr)->OSptr=(OSblock *)malloc(sizeof(OSblock));
+ if ((*stateptr)->OSptr == NULL) return RDIError_OutOfStore;
+ for (i=0; i<UNIQUETEMPS; i++) (*stateptr)->OSptr->TempNames[i]=NULL;
+ for (i=0; i<HSYS_FOPEN_MAX; i++) {
+ (*stateptr)->OSptr->FileTable[i]=NULL;
+ (*stateptr)->OSptr->FileFlags[i]=0;
+ }
+ (*stateptr)->CommandLine=cmdline;
+
+ return Adp_ChannelRegisterRead(CI_CLIB, (ChannelCallback)HandleMessageFPtr,
+ *stateptr);
+}
+
+/* Shut down the Clib support, this will probably never get called though */
+int HostSysExit(hsys_state *stateptr)
+{
+ free(stateptr->OSptr);
+ free(stateptr);
+ return RDIError_NoError;
+}
+
+#ifdef DEBUG
+static void DebugCheckNullTermString(char *prefix, bool nl,
+ unsigned int len, unsigned char *strp)
+{
+ printf("%s: %d: ", prefix, len);
+ if (strp[len]=='\0')
+ printf("\"%s\"", strp);
+ else
+ printf("NOT NULL TERMINATED");
+ if (nl)
+ printf("\n");
+ else
+ {
+ printf(" ");
+ fflush(stdout);
+ }
+}
+
+#ifdef NEED_SYSERRLIST
+extern int sys_nerr;
+extern char *sys_errlist[];
+#endif
+
+static char *DebugStrError(int last_errno)
+{
+ if (last_errno < sys_nerr)
+ return sys_errlist[last_errno];
+ else
+ return "NO MSG (errno>sys_nerr)";
+}
+
+static void DebugCheckErr(char *prefix, bool nl, int err, int last_errno)
+{
+ printf("\t%s: returned ", prefix);
+ if (err == 0)
+ printf("okay");
+ else
+ printf("%d, errno = %d \"%s\"", err, last_errno,
+ DebugStrError(last_errno));
+ if (nl)
+ printf("\n");
+ else
+ {
+ printf(" ");
+ fflush(stdout);
+ }
+}
+
+static void DebugCheckNonNull(char *prefix, bool nl,
+ void *handle, int last_errno)
+{
+ printf("\t%s: returned ", prefix);
+ if (handle != NULL)
+ printf("okay [%08x]", (unsigned int)handle);
+ else
+ printf("NULL, errno = %d \"%s\"", last_errno,
+ DebugStrError(last_errno));
+ if (nl)
+ printf("\n");
+ else
+ {
+ printf(" ");
+ fflush(stdout);
+ }
+}
+
+#define DebugPrintF(c) printf c;
+
+#else
+
+#define DebugCheckNullTermString(p, n, l, s) ((void)(0))
+#define DebugCheckErr(p, n, e, l) ((void)(0))
+#define DebugCheckNonNull(p, n, h, l) ((void)(0))
+#define DebugPrintF(c) ((void)(0))
+
+#endif /* ifdef DEBUG ... else */
+
+static FILE *hsysGetRealFileHandle(hsys_state *stateptr, int fh, char *flags)
+{
+ FILE *file_p = NULL;
+
+ if (fh < 0 || fh >= HSYS_FOPEN_MAX)
+ {
+ stateptr->last_errno = EBADF;
+ DebugPrintF(("\tfh %d out-of-bounds!\n", fh));
+ return NULL;
+ }
+ else
+ {
+ file_p = stateptr->OSptr->FileTable[fh];
+ if (file_p != NULL) {
+ if (flags != NULL)
+ *flags = stateptr->OSptr->FileFlags[fh];
+ }
+ else {
+ stateptr->last_errno = EBADF;
+ DebugPrintF(("\tFileTable[%d] is NULL\n", fh));
+ }
+
+ return file_p;
+ }
+}
+
+int HandleSysMessage(Packet *packet, hsys_state *stateptr)
+{
+ unsigned int reason_code, mode, len, c, nbytes, nbtotal, nbtogo = 0;
+ long posn, fl;
+ char character;
+ int err;
+
+ /* Note: We must not free the buffer passed in as the callback handler */
+ /* expects to do this. Freeing any other buffers we have malloced */
+ /* ourselves is acceptable */
+
+ unsigned char *buffp = ((unsigned char *)BUFFERDATA(packet->pk_buffer))+16;
+ /* buffp points to the parameters*/
+ /* the invidual messages, excluding*/
+ /* standard SYS fields (debugID, */
+ /* osinfo and reasoncode) */
+ unsigned char *buffhead = (unsigned char *)(packet->pk_buffer);
+
+ int DebugID, OSInfo1, OSInfo2, count;
+
+ const char* fmode[] = {"r","rb","r+","r+b",
+ "w","wb","w+","w+b",
+ "a","ab","a+","a+b",
+ "r","r","r","r"} /* last 4 are illegal */ ;
+
+ FILEHANDLE fh; /* fh is used as an index to the real file handle
+ * in OSptr */
+ FILE *fhreal;
+ unpack_message(BUFFERDATA(buffhead), "%w%w%w%w", &reason_code,
+ &DebugID, &OSInfo1, &OSInfo2);
+ /* Extract reason code from buffer. */
+ reason_code &= 0xFFFF; /* Strip away direction bit, OSInfo and */
+ /* DebugInfo fields. Will want to do some */
+ /* sort of validation on this later. */
+
+ switch(reason_code)
+ {
+
+ case CL_WriteC: /* Write a character to the terminal. */
+ /* byte data -> word status */
+ {
+#ifdef DEBUG
+ int c = (int)(*buffp);
+ printf("CL_WriteC: [%02x]>%c<", c, isprint(c) ? c : '.');
+#endif
+ stateptr->hostif->writec(stateptr->hostif->hostosarg, (int)(*buffp));
+ DevSW_FreePacket(packet);
+ return msgsend(CI_CLIB,"%w%w%w%w%w", CL_WriteC|HtoT,
+ DebugID, OSInfo1, OSInfo2, NoError);
+ }
+
+ case CL_Write0: /* Write a null terminated string to the terminal. */
+ {
+ unpack_message(buffp, "%w", &len);
+ DebugCheckNullTermString("CL_Write0", TRUE, len, buffp+4);
+ stateptr->hostif->write(stateptr->hostif->hostosarg,
+ (char *) buffp+4, len);
+ DevSW_FreePacket(packet);
+ return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Write0|HtoT, DebugID,
+ OSInfo1, OSInfo2, NoError);
+ }
+
+ case CL_ReadC: /* Read a byte from the terminal */
+ {
+ DebugPrintF(("CL_ReadC: "));
+ DevSW_FreePacket(packet);
+
+ character = stateptr->hostif->readc(stateptr->hostif->hostosarg);
+ DebugPrintF(("\nCL_ReadC returning [%02x]>%c<\n", character,
+ isprint(character) ? character : '.'));
+
+ return msgsend(CI_CLIB, "%w%w%w%w%w%b", CL_ReadC|HtoT,
+ DebugID, OSInfo1, OSInfo2, NoError, character);
+ }
+
+ case CL_System: /* Pass NULL terminated string to the hosts command
+ * interpreter. As it is nULL terminated we dont need
+ * the length
+ */
+ {
+ unpack_message(buffp, "%w", &len);
+ DebugCheckNullTermString("CL_System", TRUE, len, buffp+4);
+
+ err = system((char *)buffp+4); /* Use the string in the buffer */
+ stateptr->last_errno = errno;
+ DebugCheckErr("system", TRUE, err, stateptr->last_errno);
+
+ err = msgsend(CI_CLIB, "%w%w%w%w%w%w", CL_System|HtoT,
+ DebugID, OSInfo1, OSInfo2, NoError, err);
+ DevSW_FreePacket(packet);
+ return err;
+ }
+
+ case CL_GetCmdLine: /* Returns the command line used to call the program */
+ {
+ /* Note: we reuse the packet here, this may not always be desirable */
+ /* /* TODO: Use long buffers if possible */
+ DebugPrintF(("CL_GetCmdLine: \"%s\"\n", *(stateptr->CommandLine)));
+
+ if (buffhead!=NULL) {
+ len = strlen(*(stateptr->CommandLine));
+ if (len > Armsd_BufferSize-24) len = Armsd_BufferSize-24;
+ packet->pk_length = len + msgbuild(BUFFERDATA(buffhead),
+ "%w%w%w%w%w%w", CL_GetCmdLine|HtoT,
+ DebugID, OSInfo1, OSInfo2,
+ NoError, len);
+ strncpy((char *) BUFFERDATA(buffhead)+24,*(stateptr->CommandLine),
+ len);
+
+ Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */
+ return 0;
+ }
+ else return -1;
+ }
+
+ case CL_Clock: /* Return the number of centiseconds since the support */
+ /* code started executing */
+ {
+ time_t retTime = time(NULL);
+ if (retTime == (time_t)-1)
+ stateptr->last_errno = errno;
+ else
+ retTime *=100;
+
+ DebugPrintF(("CL_Clock: %lu\n", retTime));
+ DebugCheckErr("time", TRUE, (retTime == (time_t)-1),
+ stateptr->last_errno);
+
+ DevSW_FreePacket(packet);
+ return msgsend(CI_CLIB, "%w%w%w%w%w%w",CL_Clock|HtoT,
+ DebugID, OSInfo1, OSInfo2, NoError, retTime);
+ }
+
+ case CL_Time: /* return time, in seconds since the start of 1970 */
+ {
+ time_t retTime = time(NULL);
+ if (retTime == (time_t)-1)
+ stateptr->last_errno = errno;
+
+ DebugPrintF(("CL_Time: %lu\n", retTime));
+ DebugCheckErr("time", TRUE, (retTime == (time_t)-1),
+ stateptr->last_errno);
+
+ DevSW_FreePacket(packet);
+ return msgsend(CI_CLIB,"%w%w%w%w%w%w",CL_Time|HtoT,
+ DebugID, OSInfo1, OSInfo2, NoError, retTime);
+ }
+
+ case CL_Remove: /* delete named in the null terminated string */
+ {
+ /* Removing an open file will cause problems but once again
+ * its not our problem, likely result is a tangled FileTable */
+ /* As the filename is passed with a null terminator we can use it
+ * straight out of the buffer without copying it.*/
+
+ unpack_message(buffp, "%w", &len);
+ DebugCheckNullTermString("CL_Remove", TRUE, len, buffp+4);
+
+ err=remove((char *)buffp+4);
+ stateptr->last_errno = errno;
+ DevSW_FreePacket(packet);
+ DebugCheckErr("remove", TRUE, err, stateptr->last_errno);
+
+ return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Remove|HtoT,
+ DebugID, OSInfo1, OSInfo2, err?-1:NoError);
+ }
+
+ case CL_Rename: /* rename file */
+ {
+ /* Rename(word nbytes, bytes oname, word nbytes, bytes nname)
+ * return(byte status)
+ */
+ unsigned int len2;
+
+ unpack_message(buffp, "%w", &len);
+ DebugCheckNullTermString("CL_Rename", FALSE, len, buffp+4);
+ unpack_message(buffp+5+len, "%w", &len2);
+ DebugCheckNullTermString("to", TRUE, len2, buffp+9+len);
+
+ /* Both names are passed with null terminators so we can use them
+ * directly from the buffer. */
+ err = rename((char *)buffp+4, (char *)buffp+9+len);
+ stateptr->last_errno = errno;
+ DebugCheckErr("rename", TRUE, err, stateptr->last_errno);
+ DevSW_FreePacket(packet);
+
+ return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Rename|HtoT,
+ DebugID, OSInfo1, OSInfo2, (err==0)? NoError : -1);
+ }
+
+ case CL_Open: /* open the file */
+ {
+ /* Open(word nbytes, bytes name, byte mode)
+ * return(word handle)
+ */
+ unpack_message(buffp, "%w", &len);
+ /* get the open mode */
+ unpack_message((buffp)+4+len+1, "%w", &mode);
+ DebugCheckNullTermString("CL_Open", FALSE, len, buffp+4);
+ DebugPrintF(("mode: %d\n", mode));
+
+ /* do some checking on the file first? */
+ /* check if its a tty */
+ if (strcmp((char *)buffp+4, ":tt")==0 && (mode==0||mode==1)) {
+ /* opening tty "r" */
+ fhreal = stdin;
+ stateptr->last_errno = errno;
+ DebugPrintF(("\tstdin "));
+ }
+ else if (strcmp((char *)buffp+4, ":tt")== 0 && (mode==4||mode==5)) {
+ /* opening tty "w" */
+ fhreal = stdout;
+ stateptr->last_errno = errno;
+ DebugPrintF(("\tstdout "));
+ }
+ else
+ {
+ fhreal = fopen((char *)buffp+4, fmode[mode&0xFF]);
+ stateptr->last_errno = errno;
+ DebugCheckNonNull("fopen", FALSE, fhreal, stateptr->last_errno);
+ }
+ DevSW_FreePacket(packet);
+
+ c = NONHANDLE;
+ if (fhreal != NULL) {
+ /* update filetable */
+ for (c=3; c < HSYS_FOPEN_MAX; c++) {
+ /* allow for stdin, stdout, stderr (!!! WHY? MJG) */
+ if (stateptr->OSptr->FileTable[c] == NULL) {
+ stateptr->OSptr->FileTable[c]= fhreal;
+ stateptr->OSptr->FileFlags[c]= mode & 1;
+ DebugPrintF(("fh: %d\n", c));
+ break;
+ }
+ else if (c == HSYS_FOPEN_MAX) {
+ /* no filehandles free */
+ DebugPrintF(("no free fh: %d\n", c));
+ stateptr->last_errno = EMFILE;
+ }
+ }
+ }
+ else {
+ /* c = NULL;*/
+ DebugPrintF(("error fh: %d\n", c));
+ }
+ (void) msgsend(CI_CLIB, "%w%w%w%w%w", CL_Open|HtoT,
+ DebugID, OSInfo1, OSInfo2, c);
+ return 0;
+ }
+
+ case CL_Close: /* close the file pointed to by the filehandle */
+ {
+ unpack_message(buffp, "%w", &fh);
+ DebugPrintF(("CL_Close: fh %d\n", fh));
+ DevSW_FreePacket(packet);
+
+ fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
+ if (fhreal == NULL)
+ err = -1;
+ else {
+ if (fhreal == stdin || fhreal == stdout || fhreal == stderr) {
+ stateptr->last_errno = errno;
+ DebugPrintF(("\tskipping close of std*\n"));
+ err = 0;
+ }
+ else {
+ err = fclose(fhreal);
+ if (err == 0)
+ stateptr->OSptr->FileTable[fh]=NULL;
+ stateptr->last_errno = errno;
+ DebugCheckErr("fclose", TRUE, err, stateptr->last_errno);
+ }
+ }
+ return msgsend(CI_CLIB,"%w%w%w%w%w", CL_Close|HtoT, DebugID,
+ OSInfo1, OSInfo2, err);
+ }
+
+ case CL_Write:
+ {
+ /* Write(word handle, word nbtotal, word nbytes, bytes data)
+ * return(word nbytes)
+ * WriteX(word nbytes, bytes data)
+ * return(word nbytes)
+ */
+ unsigned char *rwdata = NULL, *rwhead = NULL;
+ unsigned char *write_source = NULL;
+ char flags;
+ FILE *fhreal;
+ unsigned int ack_reason = CL_Write; /* first ack is for CL_Write */
+
+ err = -1; /* err == 0 is fwrite() error indication */
+ unpack_message(buffp, "%w%w%w", &fh, &nbtotal, &nbytes);
+ DebugPrintF(("CL_Write: fh %d nbtotal %u nbytes %u\n",
+ fh, nbtotal, nbytes));
+
+ fhreal = hsysGetRealFileHandle(stateptr, fh, &flags);
+ nbtogo = nbtotal;
+
+ /* deal with the file handle */
+ if (fhreal == NULL)
+ err = 0;
+ else {
+ if (flags & READOP)
+ fseek(fhreal,0,SEEK_CUR);
+ stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP;
+
+ nbtogo -= nbytes;
+
+ if (nbtogo > 0) {
+ write_source = rwdata = rwhead = (unsigned char *)malloc(nbtotal);
+ if (rwhead == NULL) {
+ fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
+ __LINE__, __FILE__);
+ return -1;
+ }
+ memcpy(rwdata, buffp+12, nbytes);
+ rwdata += nbytes;
+ }
+ else
+ write_source = buffp+12;
+ }
+
+ do {
+ /* at least once!! */
+
+ if (nbtogo == 0 && err != 0) {
+ /* Do the actual write! */
+ if (fhreal == stdout || fhreal == stderr) {
+ stateptr->hostif->write(stateptr->hostif->hostosarg,
+ (char *)write_source, nbtotal);
+ }
+ else
+ err = fwrite(write_source, 1, nbtotal, fhreal);
+ stateptr->last_errno = errno;
+ DebugCheckErr("fwrite", TRUE, (err == 0), stateptr->last_errno);
+ }
+
+ DevSW_FreePacket(packet);
+ if (msgsend(CI_CLIB,"%w%w%w%w%w%w", ack_reason|HtoT,
+ DebugID, OSInfo1, OSInfo2, (err == 0), nbtogo))
+ {
+ fprintf(stderr, "COULD NOT REPLY at line %d in %s\n",
+ __LINE__, __FILE__);
+ if (rwhead != NULL)
+ free(rwhead);
+ return -1;
+ }
+
+ if (nbtogo == 0 || err == 0) {
+ DebugPrintF(("\twrite complete - returning\n"));
+ if (rwhead != NULL)
+ free(rwhead);
+ return 0;
+ }
+ else {
+ /* await extension */
+ ack_reason = CL_WriteX;
+
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ if (packet == NULL)
+ {
+ fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
+ __LINE__, __FILE__);
+ if (rwhead != NULL)
+ free(rwhead);
+ return -1;
+ }
+ Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL);
+ Adp_ChannelRead(CI_CLIB, &packet);
+ Adp_ChannelRegisterRead(CI_CLIB,
+ (ChannelCallback)HandleSysMessage,
+ stateptr);
+
+ buffhead = packet->pk_buffer;
+ unpack_message(BUFFERDATA(buffhead), "%w%w%w%w%w", &reason_code,
+ &DebugID, &OSInfo1, &OSInfo2, &nbytes);
+ if (reason_code != (CL_WriteX|TtoH)) {
+ DevSW_FreePacket(packet);
+ free(rwhead);
+ fprintf(stderr, "EXPECTING CL_WriteX GOT %u at line %d in %s\n",
+ reason_code, __LINE__, __FILE__);
+ return -1;
+ }
+
+ DebugPrintF(("CL_WriteX: nbytes %u\n", nbytes));
+ memcpy(rwdata, BUFFERDATA(buffhead)+20, nbytes);
+ rwdata += nbytes;
+ nbtogo -= nbytes;
+ }
+
+ } while (TRUE); /* will return when done */
+ }
+
+ case CL_WriteX: /*
+ * NOTE: if we've got here something has gone wrong
+ * CL_WriteX's should all be picked up within the
+ * CL_Write loop, probably best to return an error here
+ * do this for the moment just so we do actually return
+ */
+ fprintf(stderr, "ERROR: unexpected CL_WriteX message received\n");
+ return -1;
+
+ case CL_Read:
+ {
+ /* Read(word handle, word nbtotal)
+ * return(word nbytes, word nbmore, bytes data)
+ */
+ /* ReadX()
+ * return(word nbytes, word nbmore, bytes data) */
+ unsigned char *rwdata, *rwhead;
+ int gotlen;
+ unsigned int max_data_in_buffer=Armsd_BufferSize-28;
+ char flags;
+ FILE *fhreal;
+ unsigned int nbleft = 0, reason = CL_Read;
+
+ err = NoError;
+
+ unpack_message(buffp, "%w%w", &fh, &nbtotal);
+ DebugPrintF(("CL_Read: fh %d, nbtotal %d: ", fh, nbtotal));
+
+ rwdata = rwhead = (unsigned char *)malloc(nbtotal);
+ if (rwdata == NULL) {
+ fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
+ __LINE__, __FILE__);
+ DevSW_FreePacket(packet);
+ return -1;
+ }
+
+ /* perform the actual read */
+ fhreal = hsysGetRealFileHandle(stateptr, fh, &flags);
+ if (fhreal == NULL)
+ {
+ /* bad file handle */
+ err = -1;
+ nbytes = 0;
+ gotlen = 0;
+ }
+ else
+ {
+ if (flags & WRITEOP)
+ fseek(fhreal,0,SEEK_CUR);
+ stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP;
+ if (isatty_(fhreal)) {
+ /* reading from a tty, so do some nasty stuff, reading into rwdata */
+ if (angel_hostif->gets(stateptr->hostif->hostosarg, (char *)rwdata,
+ nbtotal) != 0)
+ gotlen = strlen((char *)rwdata);
+ else
+ gotlen = 0;
+ stateptr->last_errno = errno;
+ DebugPrintF(("ttyread %d\n", gotlen));
+ }
+ else {
+ /* not a tty, reading from a real file */
+ gotlen = fread(rwdata, 1, nbtotal, fhreal);
+ stateptr->last_errno = errno;
+ DebugCheckErr("fread", FALSE, (gotlen == 0), stateptr->last_errno);
+ DebugPrintF(("(%d)\n", gotlen));
+ }
+ }
+
+ nbtogo = gotlen;
+
+ do {
+ /* at least once */
+
+ if ((unsigned int) nbtogo <= max_data_in_buffer)
+ nbytes = nbtogo;
+ else
+ nbytes = max_data_in_buffer;
+ nbtogo -= nbytes;
+
+ /* last ReadX needs subtle adjustment to returned nbtogo */
+ if (nbtogo == 0 && err == NoError && reason == CL_ReadX)
+ nbleft = nbtotal - gotlen;
+ else
+ nbleft = nbtogo;
+
+ count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w%w",
+ reason|HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, err, nbytes, nbleft);
+
+ if (err == NoError) {
+ /* copy data into buffptr */
+ memcpy(BUFFERDATA(buffhead)+28, rwdata, nbytes);
+ rwdata += nbytes;
+ count += nbytes;
+ }
+
+ DebugPrintF(("\treplying err %d, nbytes %d, nbtogo %d\n",
+ err, nbytes, nbtogo));
+
+ packet->pk_length = count;
+ Adp_ChannelWrite(CI_CLIB, packet);
+
+ if (nbtogo == 0 || err != NoError) {
+ /* done */
+ free(rwhead);
+ return 0;
+ }
+ else {
+ /* await extension */
+ reason = CL_ReadX;
+
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ if (packet == NULL) {
+ fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
+ __LINE__, __FILE__);
+ free(rwhead);
+ return -1;
+ }
+ Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL);
+ Adp_ChannelRead(CI_CLIB, &packet);
+ Adp_ChannelRegisterRead(CI_CLIB,
+ (ChannelCallback)HandleSysMessage,
+ stateptr);
+ buffhead = packet->pk_buffer;
+ unpack_message(BUFFERDATA(buffhead),"%w", &reason_code);
+ if (reason_code != (CL_ReadX|TtoH)) {
+ fprintf(stderr, "EXPECTING CL_ReadX GOT %u at line %d in %s\n",
+ reason_code, __LINE__, __FILE__);
+ DevSW_FreePacket(packet);
+ free(rwdata);
+ return -1;
+ }
+ }
+
+ } while (TRUE); /* will return above on error or when done */
+ }
+
+ case CL_ReadX: /* If we're here something has probably gone wrong */
+ fprintf(stderr, "ERROR: Got unexpected CL_ReadX message\n");
+ return -1;
+
+ case CL_Seek:
+ {
+ unpack_message(buffp, "%w%w", &fh, &posn);
+ DebugPrintF(("CL_Seek: fh %d, posn %ld\n", fh, posn));
+ DevSW_FreePacket(packet);
+
+ fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
+ if (fhreal == NULL)
+ err = -1;
+ else {
+ err = fseek(fhreal, posn, SEEK_SET);
+ stateptr->last_errno = errno;
+ DebugCheckErr("fseek", TRUE, err, stateptr->last_errno);
+ }
+
+ return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Seek|HtoT,
+ DebugID, OSInfo1, OSInfo2, err);
+ }
+
+ case CL_Flen:
+ {
+ unpack_message(buffp, "%w", &fh);
+ DebugPrintF(("CL_Flen: fh %d ", fh));
+ DevSW_FreePacket(packet);
+
+ fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
+ if (fhreal == NULL)
+ fl = -1;
+ else {
+ posn = ftell(fhreal);
+ if (fseek(fhreal, 0L, SEEK_END) < 0) {
+ fl=-1;
+ }
+ else {
+ fl = ftell(fhreal);
+ fseek(fhreal, posn, SEEK_SET);
+ }
+ stateptr->last_errno = errno;
+ }
+ DebugPrintF(("returning len %ld\n", fl));
+ return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Flen|HtoT, DebugID, OSInfo1,
+ OSInfo2, fl);
+ }
+
+ case CL_IsTTY:
+ {
+ int ttyOrNot;
+ unpack_message(buffp, "%w", &fh);
+ DebugPrintF(("CL_IsTTY: fh %d ", fh));
+ DevSW_FreePacket(packet);
+
+ fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
+ if (fhreal == NULL)
+ ttyOrNot = FALSE;
+ else {
+ ttyOrNot = isatty_(fhreal);
+ stateptr->last_errno = errno;
+ }
+ DebugPrintF(("returning %s\n", ttyOrNot ? "tty (1)" : "not (0)"));
+
+ return msgsend(CI_CLIB, "%w%w%w%w%w",CL_IsTTY|HtoT,
+ DebugID, OSInfo1, OSInfo2, ttyOrNot);
+ }
+
+ case CL_TmpNam:
+ {
+ char *name;
+ unsigned int tnamelen, TargetID;
+ unpack_message(buffp, "%w%w", &tnamelen, &TargetID);
+ DebugPrintF(("CL_TmpNam: tnamelen %d TargetID %d: ",
+ tnamelen, TargetID));
+ DevSW_FreePacket(packet);
+
+ TargetID = TargetID & 0xFF;
+ if (stateptr->OSptr->TempNames[TargetID] == NULL) {
+ if ((stateptr->OSptr->TempNames[TargetID] =
+ (char *)malloc(L_tmpnam)) == NULL)
+ {
+ fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
+ __LINE__, __FILE__);
+ return -1;
+ }
+ tmpnam(stateptr->OSptr->TempNames[TargetID]);
+ }
+ name = stateptr->OSptr->TempNames[TargetID];
+ len = strlen(name) + 1;
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ if (packet == NULL)
+ {
+ fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
+ __LINE__, __FILE__);
+ return -1;
+ }
+ buffhead = packet->pk_buffer;
+ if (len > tnamelen) {
+ DebugPrintF(("TMPNAME TOO LONG!\n"));
+ count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w",
+ CL_TmpNam|HtoT, DebugID, OSInfo1, OSInfo2, -1);
+ }
+ else {
+ DebugPrintF(("returning \"%s\"\n", name));
+ count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w", CL_TmpNam|HtoT,
+ DebugID, OSInfo1, OSInfo2, 0, len);
+ strcpy((char *)BUFFERDATA(buffhead)+count, name);
+ count +=len+1;
+ }
+ packet->pk_length = count;
+ Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */
+ return 0;
+ }
+
+ case CL_Unrecognised:
+ DebugPrintF(("CL_Unrecognised!!\n"));
+ return 0;
+
+ default:
+ fprintf(stderr, "UNRECOGNISED CL code %08x\n", reason_code);
+ break;
+/* Need some sort of error handling here. */
+/* A call to CL_Unrecognised should suffice */
+ }
+ return -1; /* Stop a potential compiler warning */
+}
+
+#ifdef COMPILING_ON_WINDOWS
+
+#include <windows.h>
+
+extern HWND hwndParent;
+
+void panic(const char *format, ...)
+{
+ char buf[2048];
+ va_list args;
+
+ Adp_CloseDevice();
+
+ va_start(args, format);
+ vsprintf(buf, format, args);
+
+ MessageBox(hwndParent, (LPCTSTR)buf, (LPCTSTR)"Fatal Error:", MB_OK);
+
+ /* SJ - Not the proper way to shutdown the app */
+ exit(EXIT_FAILURE);
+
+/*
+ if (hwndParent != NULL)
+ SendMessage(hwndParent, WM_QUIT, 0, 0);
+*/
+
+ va_end(args);
+}
+
+#else
+
+void panic(const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ fprintf(stderr, "Fatal error: ");
+ vfprintf(stderr, format, args);
+ fprintf(stderr,"\n");
+
+ exit(EXIT_FAILURE);
+}
+
+#endif
+
+/* EOF hsys.c */
diff --git a/gdb/rdi-share/hsys.h b/gdb/rdi-share/hsys.h
new file mode 100644
index 00000000000..7f63d0103d1
--- /dev/null
+++ b/gdb/rdi-share/hsys.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * Host C library support header file.
+ *
+ * $Revision$
+ * $Date$
+ *
+ */
+
+#ifndef angsd_hsys_h
+#define angsd_hsys_h
+
+#define HSYS_FOPEN_MAX 256
+#define NONHANDLE -1
+#define UNIQUETEMPS 256
+
+#include "dbg_hif.h"
+#include "hostchan.h"
+
+typedef struct {
+ FILE *FileTable[HSYS_FOPEN_MAX] ;
+ char FileFlags[HSYS_FOPEN_MAX] ;
+ char *TempNames[UNIQUETEMPS];
+} OSblock;
+
+#define NOOP 0
+#define BINARY 1
+#define READOP 2
+#define WRITEOP 4
+
+typedef struct {
+ const struct Dbg_HostosInterface *hostif; /* Interface to debug toolkit. */
+ int last_errno; /* Number of the last error. */
+ OSblock *OSptr;
+ char **CommandLine ; /* Ptr to cmd line d`string held by ardi.c */
+} hsys_state;
+
+/*
+ * Function: HostSysInit
+ * Purpose: Set up the state block, filetable and register the and C lib
+ * callback fn
+ *
+ * Params:
+ * Input: hostif, the host interface from the debug toolbox
+ * cmdline, the command line used to call the image
+ * state, the status block for the C lib
+ *
+ * Returns:
+ * OK: an RDIError_* valuee
+ */
+extern int HostSysInit(
+ const struct Dbg_HostosInterface *hostif, char **cmdline, hsys_state **state
+);
+
+/*
+ * Function: HostSysExit
+ * Purpose: Close down the host side C library support
+ *
+ * Params:
+ * Input: hstate, the status block for the C lib
+ *
+ * Returns: an RDIError_* valuee
+ */
+extern int HostSysExit(hsys_state *hstate);
+
+/*
+ * Function: HandleSysMessage
+ * Purpose: Handle an incoming C library message as a callback
+ *
+ * Params:
+ * Input: packet is the incoming data packet as described in devsw.h
+ * hstate, the status block for the C lib
+ *
+ * Returns: an RDIError_* valuee
+ */
+extern int HandleSysMessage(Packet *packet, hsys_state* stateptr);
+
+/*
+ * Function: panic
+ * Purpose: Print a fatal error message
+ *
+ * Params:
+ * Input: format printf() style message describing the problem
+ * ... extra arguments for printf().
+ *
+ * Returns: This routine does not return
+ *
+ * Post-conditions: Will have called exit(1);
+ */
+extern void panic(const char *format, ...);
+
+#endif /* ndef angsd_hsys_h */
+
+/* EOF hsys.h */
diff --git a/gdb/rdi-share/logging.c b/gdb/rdi-share/logging.c
new file mode 100644
index 00000000000..79b70ef348f
--- /dev/null
+++ b/gdb/rdi-share/logging.c
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * logging.c - methods for logging warnings, errors and trace info
+ *
+ */
+
+#include <stdarg.h> /* ANSI varargs support */
+
+#ifdef TARGET
+# include "angel.h"
+# include "devconf.h"
+#else
+# include "host.h"
+#endif
+
+#include "logging.h" /* Header file for this source code */
+
+#ifndef UNUSED
+# define UNUSED(x) ((x)=(x))
+#endif
+
+/*
+ * __rt_warning
+ * ------------
+ * This routine is provided as a standard method of generating
+ * run-time system warnings. The actual action taken by this code can
+ * be board or target application specific, e.g. internal logging,
+ * debug message, etc.
+ */
+
+#ifdef DEBUG
+
+# ifdef DEBUG_METHOD
+
+# define STRINGIFY2(x) #x
+# define STRINGIFY(x) STRINGIFY2(x)
+# define DEBUG_METHOD_HEADER STRINGIFY(DEBUG_METHOD##.h)
+
+# include DEBUG_METHOD_HEADER
+
+# define METHOD_EXPAND_2(m, p, c) m##p(c)
+# define METHOD_EXPAND(m, p, c) METHOD_EXPAND_2(m, p, c)
+
+# define CHAROUT(c) METHOD_EXPAND(DEBUG_METHOD, _PutChar, (c))
+# define PRE_DEBUG(l) METHOD_EXPAND(DEBUG_METHOD, _PreWarn, (l))
+# define POST_DEBUG(n) METHOD_EXPAND(DEBUG_METHOD, _PostWarn, (n))
+
+# else
+# error Must define DEBUG_METHOD
+# endif
+
+#endif /* def DEBUG */
+
+/*
+ * the guts of __rt_warning
+ */
+
+#pragma no_check_stack
+#ifdef DEBUG
+
+static const char hextab[] = "0123456789ABCDEF";
+
+/*
+ * If debugging, then we break va_warn into sub-functions which
+ * allow us to get an easy breakpoint on the formatted string
+ */
+static int va_warn0(char *format, va_list args)
+{
+ int len = 0;
+
+ while ((format != NULL) && (*format != '\0'))
+ {
+ if (*format == '%')
+ {
+ char fch = *(++format); /* get format character (skipping '%') */
+ int ival; /* holder for integer arguments */
+ char *string; /* holder for string arguments */
+ int width = 0; /* No field width by default */
+ int padzero = FALSE; /* By default we pad with spaces */
+
+ /*
+ * Check if the format has a width specified. NOTE: We do
+ * not use the "isdigit" function here, since it will
+ * require run-time support. The current ARM Ltd header
+ * defines "isdigit" as a macro, that uses a fixed
+ * character description table.
+ */
+ if ((fch >= '0') && (fch <= '9'))
+ {
+ if (fch == '0')
+ {
+ /* Leading zeroes padding */
+ padzero = TRUE;
+ fch = *(++format);
+ }
+
+ while ((fch >= '0') && (fch <= '9'))
+ {
+ width = ((width * 10) + (fch - '0'));
+ fch = *(++format);
+ }
+ }
+
+ if (fch == 'l')
+ /* skip 'l' in "%lx", etc. */
+ fch = *(++format);
+
+ switch (fch)
+ {
+ case 'c':
+ /* char */
+ ival = va_arg(args, int);
+ CHAROUT((char)ival);
+ len++;
+ break;
+
+ case 'x':
+ case 'X':
+ {
+ /* hexadecimal */
+ unsigned int uval = va_arg(args, unsigned int);
+ int loop;
+
+ UNUSED(uval);
+
+ if ((width == 0) || (width > 8))
+ width = 8;
+
+ for(loop = (width * 4); (loop != 0); loop -= 4)
+ {
+ CHAROUT(hextab[(uval >> (loop - 4)) & 0xF]);
+ len++;
+ }
+ }
+
+ break;
+
+ case 'd':
+ /* decimal */
+ ival = va_arg(args, int);
+
+ if (ival < 0)
+ {
+ ival = -ival;
+ CHAROUT('-');
+ len++;
+ }
+
+ if (ival == 0)
+ {
+ CHAROUT('0');
+ len++;
+ }
+ else
+ {
+ /*
+ * The simplest method of displaying numbers is
+ * to provide a small recursive routine, that
+ * nests until the most-significant digit is
+ * reached, and then falls back out displaying
+ * individual digits. However, we want to avoid
+ * using recursive code within the lo-level
+ * parts of Angel (to minimise the stack
+ * usage). The following number conversion is a
+ * non-recursive solution.
+ */
+ char buffer[16]; /* stack space used to hold number */
+ int count = 0; /* pointer into buffer */
+
+ /*
+ * Place the conversion into the buffer in
+ * reverse order:
+ */
+ while (ival != 0)
+ {
+ buffer[count++] = ('0' + ((unsigned int)ival % 10));
+ ival = ((unsigned int)ival / 10);
+ }
+
+ /*
+ * Check if we are placing the data in a
+ * fixed width field:
+ */
+ if (width != 0)
+ {
+ width -= count;
+
+ for (; (width != 0); width--)
+ {
+ CHAROUT(padzero ? '0': ' ');
+ len++;
+ }
+ }
+
+ /* then display the buffer in reverse order */
+ for (; (count != 0); count--)
+ {
+ CHAROUT(buffer[count - 1]);
+ len++;
+ }
+ }
+
+ break;
+
+ case 's':
+ /* string */
+ string = va_arg(args, char *);
+
+ /* we only need this test once */
+ if (string != NULL)
+ /* whilst we check this for every character */
+ while (*string)
+ {
+ CHAROUT(*string);
+ len++;
+ string++;
+
+ /*
+ * NOTE: We do not use "*string++" as the macro
+ * parameter, since we do not know how many times
+ *the parameter may be expanded within the macro.
+ */
+ }
+
+ break;
+
+ case '\0':
+ /*
+ * string terminated by '%' character, bodge things
+ * to prepare for default "format++" below
+ */
+ format--;
+
+ break;
+
+ default:
+ /* just display the character */
+ CHAROUT(*format);
+ len++;
+
+ break;
+ }
+
+ format++; /* step over format character */
+ }
+ else
+ {
+ CHAROUT(*format);
+ len++;
+ format++;
+ }
+ }
+ return len;
+}
+
+/*
+ * this routine is simply here as a good breakpoint for dumping msg -
+ * can be used by DEBUG_METHOD macros or functions, if required.
+ */
+# ifdef DEBUG_NEED_VA_WARN1
+static void va_warn1(int len, char *msg)
+{
+ UNUSED(len); UNUSED(msg);
+}
+# endif
+
+void va_warn(WarnLevel level, char *format, va_list args)
+{
+ int len;
+
+ if ( PRE_DEBUG( level ) )
+ {
+ len = va_warn0(format, args);
+ POST_DEBUG( len );
+ }
+}
+
+#else /* ndef DEBUG */
+
+void va_warn(WarnLevel level, char *format, va_list args)
+{
+ UNUSED(level); UNUSED(format); UNUSED(args);
+}
+
+#endif /* ... else ndef(DEBUG) ... */
+#pragma check_stack
+
+#pragma no_check_stack
+void __rt_warning(char *format, ...)
+{
+ va_list args;
+
+ /*
+ * For a multi-threaded system we should provide a lock at this point
+ * to ensure that the warning messages are sequenced properly.
+ */
+
+ va_start(args, format);
+ va_warn(WL_WARN, format, args);
+ va_end(args);
+
+ return;
+}
+#pragma check_stack
+
+#ifdef TARGET
+
+#pragma no_check_stack
+void __rt_uninterruptable_loop( void ); /* in suppasm.s */
+
+void __rt_error(char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+
+ /* Display warning message */
+ va_warn(WL_ERROR, format, args);
+
+ __rt_uninterruptable_loop();
+
+ va_end(args);
+ return;
+}
+#pragma check_stack
+
+#endif /* def TARGET */
+
+#ifdef DO_TRACE
+
+static bool trace_on = FALSE; /* must be set true in debugger if req'd */
+
+#pragma no_check_stack
+void __rt_trace(char *format, ...)
+{
+ va_list args;
+
+ /*
+ * For a multi-threaded system we should provide a lock at this point
+ * to ensure that the warning messages are sequenced properly.
+ */
+
+ if (trace_on)
+ {
+ va_start(args, format);
+ va_warn(WL_TRACE, format, args);
+ va_end(args);
+ }
+
+ return;
+}
+#pragma check_stack
+
+#endif /* def DO_TRACE */
+
+
+/* EOF logging.c */
diff --git a/gdb/rdi-share/logging.h b/gdb/rdi-share/logging.h
new file mode 100644
index 00000000000..97bf902ad1a
--- /dev/null
+++ b/gdb/rdi-share/logging.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * logging.h - methods for logging warnings, errors and trace info
+ */
+
+#ifndef angel_logging_h
+#define angel_logging_h
+
+#include <stdarg.h>
+
+/*
+ * __rt_warning
+ * ------------
+ * Provides a standard method of generating run-time system
+ * warnings. The actual action taken by this code can be board or
+ * target application specific, e.g. internal logging, debug message,
+ * etc.
+ */
+extern void __rt_warning(char *format, ...);
+
+/*---------------------------------------------------------------------------*/
+
+/*
+ * __rt_error
+ * ----------
+ * Raise an internal Angel error. The parameters are passed directly
+ * to "__rt_warning" for display, and the code then raises a debugger
+ * event and stops the target processing.
+ */
+extern void __rt_error(char *format, ...);
+
+/*
+ * Some macros for debugging and warning messages
+ */
+
+typedef enum WarnLevel {
+ WL_TRACE,
+ WL_WARN,
+ WL_ERROR
+} WarnLevel;
+
+void va_warn(WarnLevel level, char *format, va_list args);
+
+#ifdef _WINGDI_
+/* stupidity in MSVC <wingdi.h> (in <windows.h> in <winsock.h>) */
+# undef ERROR
+#endif
+
+#ifndef ERROR
+# define ERROR_FORMAT "Error \"%s\" in %s at line %d\n"
+# define ERROR(e) __rt_error(ERROR_FORMAT, (e), __FILE__, __LINE__)
+#endif
+
+#ifndef ASSERT
+# ifdef ASSERTIONS_ENABLED
+# define ASSERT(x, y) ((x) ? (void)(0) : ERROR((y)))
+# else
+# define ASSERT(x, y) ((void)(0))
+# endif
+#endif
+
+#ifndef WARN
+# ifdef ASSERTIONS_ENABLED
+# define WARN_FORMAT "Warning \"%s\" in %s at line %d\n"
+# define WARN(w) __rt_warning(WARN_FORMAT, (w), __FILE__, __LINE__)
+# else
+# define WARN(w) ((void)(0))
+# endif
+#endif
+
+
+#ifdef NO_INFO_MESSAGES
+# define __rt_info (void)
+# ifndef INFO
+# define INFO(w)
+# endif
+#else
+# define __rt_info __rt_warning
+# ifndef INFO
+# ifdef DEBUG
+# define INFO(w) __rt_warning("%s\n", (w))
+# else
+# define INFO(w) ((void)(0))
+# endif
+# endif
+#endif
+
+
+#if defined(DEBUG) && !defined(NO_IDLE_CHITCHAT)
+# ifndef DO_TRACE
+# define DO_TRACE (1)
+# endif
+#endif
+
+#ifdef DO_TRACE
+extern void __rt_trace(char *format, ...);
+#endif
+
+#ifndef TRACE
+# ifdef DO_TRACE
+# define TRACE(w) __rt_trace("%s ", (w))
+# else
+# define TRACE(w) ((void)(0))
+# endif
+#endif
+
+#endif /* ndef angel_logging_h */
+
+/* EOF logging.h */
diff --git a/gdb/rdi-share/msgbuild.c b/gdb/rdi-share/msgbuild.c
new file mode 100644
index 00000000000..63263e75676
--- /dev/null
+++ b/gdb/rdi-share/msgbuild.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * msgbuild.c - utilities for assembling and interpreting ADP messages
+ *
+ */
+
+#include <stdarg.h> /* ANSI varargs support */
+
+#ifdef TARGET
+# include "angel.h"
+# include "devconf.h"
+#else
+# include "host.h"
+# include "hostchan.h"
+#endif
+
+#include "channels.h"
+#include "buffers.h"
+#include "angel_endian.h" /* Endianness support macros */
+#include "msgbuild.h" /* Header file for this source code */
+
+#ifndef UNUSED
+# define UNUSED(x) ((x)=(x))
+#endif
+
+#ifndef TARGET
+
+extern unsigned int Armsd_BufferSize;
+
+#endif /* ndef TARGET */
+
+
+unsigned int vmsgbuild(unsigned char *buffer, const char *format, va_list args)
+{
+ unsigned int blen = 0;
+ int ch;
+
+ /* Step through the format string */
+ while ((ch = *format++) != '\0')
+ {
+ if (ch != '%')
+ {
+ if (buffer != NULL)
+ *buffer++ = (unsigned char)ch;
+
+ blen++;
+ }
+ else
+ {
+ switch (ch = *format++)
+ {
+ case 'w':
+ case 'W':
+ /* 32bit pointer */
+ case 'p':
+ case 'P':
+ {
+ /* 32bit word / 32bit pointer */
+ unsigned int na = va_arg(args, unsigned int);
+
+ if (buffer != NULL)
+ {
+ PUT32LE(buffer, na);
+ buffer += sizeof(unsigned int);
+ }
+
+ blen += sizeof(unsigned int);
+
+ break;
+ }
+
+ case 'h':
+ case 'H':
+ {
+ /* 16bit value */
+ unsigned int na = va_arg(args, unsigned int);
+
+ if (buffer != NULL)
+ {
+ PUT16LE(buffer, na);
+ buffer += sizeof(unsigned short);
+ }
+
+ blen += sizeof(unsigned short);
+
+ break;
+ }
+
+ case 'c':
+ case 'C':
+ case 'b':
+ case 'B':
+ /* 8bit character / 8bit byte */
+ ch = va_arg(args, int);
+
+ /*
+ * XXX
+ *
+ * fall through to the normal character processing
+ */
+
+ case '%':
+ default:
+ /* normal '%' character, or a different normal character */
+ if (buffer != NULL)
+ *buffer++ = (unsigned char)ch;
+
+ blen++;
+ break;
+ }
+ }
+ }
+
+ return blen;
+}
+
+/*
+ * msgbuild
+ * --------
+ * Simple routine to aid in construction of Angel messages. See the
+ * "msgbuild.h" header file for a detailed description of the operation
+ * of this routine.
+ */
+unsigned int msgbuild(unsigned char *buffer, const char *format, ...)
+{
+ va_list args;
+ unsigned int blen;
+
+ va_start(args, format);
+ blen = vmsgbuild(buffer, format, args);
+ va_end(args);
+
+ return blen;
+}
+
+#if !defined(JTAG_ADP_SUPPORTED) && !defined(MSG_UTILS_ONLY)
+/*
+ * This routine allocates a buffer, puts the data supplied as
+ * parameters into the buffer and sends the message. It does *NOT*
+ * wait for a reply.
+ */
+extern int msgsend(ChannelID chan, const char *format,...)
+{
+ unsigned int length;
+ p_Buffer buffer;
+ va_list args;
+# ifndef TARGET
+ Packet *packet;
+
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ buffer = packet->pk_buffer;
+# else
+ buffer = angel_ChannelAllocBuffer(Angel_ChanBuffSize);
+# endif
+
+ if (buffer != NULL)
+ {
+ va_start(args, format);
+
+ length = vmsgbuild(BUFFERDATA(buffer), format, args);
+
+# ifdef TARGET
+ angel_ChannelSend(CH_DEFAULT_DEV, chan, buffer, length);
+# else
+ packet->pk_length = length;
+ Adp_ChannelWrite(chan, packet);
+# endif
+
+ va_end(args);
+ return 0;
+ }
+ else
+ return -1;
+}
+
+#endif /* ndef JTAG_ADP_SUPPORTED && ndef MSG_UTILS_ONLY */
+
+/*
+ * unpack_message
+ * --------------
+ */
+extern unsigned int unpack_message(unsigned char *buffer, const char *format, ...)
+{
+ va_list args;
+ unsigned int blen = 0;
+ int ch;
+ char *chp = NULL;
+
+ va_start(args, format);
+
+ /* Step through the format string. */
+ while ((ch = *format++) != '\0')
+ {
+ if (ch != '%')
+ {
+ if (buffer != NULL)
+ ch = (unsigned char)*buffer++;
+
+ blen++;
+ }
+ else
+ {
+ switch (ch = *format++)
+ {
+ case 'w':
+ case 'W':
+ {
+ /* 32bit word. */
+ unsigned int *nap = va_arg(args, unsigned int*);
+
+ if (buffer != NULL)
+ {
+ *nap = PREAD32(LE, buffer);
+ buffer += sizeof(unsigned int);
+ }
+
+ blen += sizeof(unsigned int);
+
+ break;
+ }
+
+ case 'h':
+ case 'H':
+ {
+ /* 16bit value. */
+ unsigned int *nap = va_arg(args, unsigned int*);
+
+ if (buffer != NULL)
+ {
+ *nap = PREAD16(LE,buffer);
+ buffer += sizeof(unsigned short);
+ }
+
+ blen += sizeof(unsigned short);
+
+ break;
+ }
+
+ case 'c':
+ case 'C':
+ case 'b':
+ case 'B':
+ /* 8-bit character, or 8-bit byte */
+ chp = va_arg(args, char*);
+
+ /*
+ * XXX
+ *
+ * fall through to the normal character processing.
+ */
+
+ case '%':
+ default:
+ /* normal '%' character, or a different normal character */
+ if (buffer != NULL)
+ *chp = (unsigned char)*buffer++;
+
+ blen++;
+
+ break;
+ }
+ }
+ }
+
+ va_end(args);
+ return(blen);
+}
+
+
+/* EOF msgbuild.c */
diff --git a/gdb/rdi-share/msgbuild.h b/gdb/rdi-share/msgbuild.h
new file mode 100644
index 00000000000..ac2436c1391
--- /dev/null
+++ b/gdb/rdi-share/msgbuild.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * msgbuild.h - utilities for assembling and interpreting ADP messages
+ */
+
+#ifndef angel_msgbuild_h
+#define angel_msgbuild_h
+#include <stdarg.h>
+#include "channels.h"
+
+/*
+ * msgbuild
+ * --------
+ * We use a "varargs" function to enable a description of how the
+ * final message should look to be provided. We use a function rather
+ * than in-line macros to keep the size of Angel small.
+ *
+ * The "buffer" pointer is the starting point from where the data will
+ * be written. Note: If a NULL pointer is passed then no data will be
+ * written, but the size information will be returned. This allows
+ * code to call this routine with a NULL "buffer" pointer to ascertain
+ * whether the pointer they are passing contains enough space for the
+ * message being constructed.
+ *
+ * The "format" string should contain sequences of the following
+ * tokens:
+ * %w - insert 32bit word value
+ * %p - insert 32bit target pointer value
+ * %h - insert 16bit value
+ * %b - insert 8bit byte value
+ *
+ * The return parameter is the final byte length of the data written.
+ */
+unsigned int msgbuild(unsigned char *buffer, const char *format, ...);
+unsigned int vmsgbuild(unsigned char *buffer, const char *format,
+ va_list args);
+
+/*---------------------------------------------------------------------------*/
+
+/*
+ * msgsend
+ * -------
+ * As for msgbuild except that it allocates a buffer, formats the data as
+ * for msgbuild and transmits the packet. Returns 0 if successful non 0 if ot
+ * fails.
+ * Not for use on cooked channels e.g. debug channels only.
+ */
+extern int msgsend(ChannelID chan, const char *format, ...);
+
+/*---------------------------------------------------------------------------*/
+
+/*
+ * Unpack_message
+ * --------------
+ * This basically does the opposite of msg_build, it takes a message, and
+ * a scanf type format string (but much cut down functionality) and returns
+ * the arguments in the message.
+ */
+extern unsigned int unpack_message(unsigned char *buffer, const char *format, ...);
+
+#endif /* ndef angel_msgbuild_h */
+
+/* EOF msgbuild.h */
diff --git a/gdb/rdi-share/params.c b/gdb/rdi-share/params.c
new file mode 100644
index 00000000000..55d9eb210ef
--- /dev/null
+++ b/gdb/rdi-share/params.c
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Parameter negotiation utility functions
+ */
+
+#include "params.h"
+
+#include "angel_endian.h"
+#include "logging.h"
+
+
+/*
+ * Function: Angel_FindParam
+ * Purpose: find the value of a given parameter from a config.
+ *
+ * see params.h for details
+ */
+bool Angel_FindParam( ADP_Parameter type,
+ const ParameterConfig *config,
+ unsigned int *value )
+{
+ unsigned int i;
+
+ for ( i = 0; i < config->num_parameters; ++i )
+ if ( config->param[i].type == type )
+ {
+ *value = config->param[i].value;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+#if !defined(TARGET) || !defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0
+
+ParameterList *Angel_FindParamList( const ParameterOptions *options,
+ ADP_Parameter type )
+{
+ unsigned int i;
+
+ for ( i = 0; i < options->num_param_lists; ++i )
+ if ( options->param_list[i].type == type )
+ return &options->param_list[i];
+
+ return NULL;
+}
+
+
+#if defined(TARGET) || defined(TEST_PARAMS)
+/*
+ * Function: Angel_MatchParams
+ * Purpose: find a configuration from the requested options which is
+ * the best match from the supported options.
+ *
+ * see params.h for details
+ */
+const ParameterConfig *Angel_MatchParams( const ParameterOptions *requested,
+ const ParameterOptions *supported )
+{
+ static Parameter chosen_params[AP_NUM_PARAMS];
+ static ParameterConfig chosen_config = {
+ AP_NUM_PARAMS,
+ chosen_params
+ };
+ unsigned int i;
+
+ ASSERT( requested != NULL, "requested is NULL" );
+ ASSERT( requested != NULL, "requested is NULL" );
+ ASSERT( supported->num_param_lists <= AP_NUM_PARAMS, "supp_num too big" );
+
+ if ( requested->num_param_lists > supported->num_param_lists )
+ {
+ WARN( "req_num exceeds supp_num" );
+ return NULL;
+ }
+
+ for ( i = 0; i < requested->num_param_lists; ++i )
+ {
+ bool match;
+ unsigned int j;
+
+ const ParameterList *req_list = &requested->param_list[i];
+ ADP_Parameter req_type = req_list->type;
+ const ParameterList *sup_list = Angel_FindParamList(
+ supported, req_type );
+
+ if ( sup_list == NULL )
+ {
+#ifdef ASSERTIONS_ENABLED
+ __rt_warning( "option %x not supported\n", req_type );
+#endif
+ return NULL;
+ }
+
+ for ( j = 0, match = FALSE;
+ (j < req_list->num_options) && !match;
+ ++j
+ )
+ {
+ unsigned int k;
+
+ for ( k = 0;
+ (k < sup_list->num_options) && !match;
+ ++k
+ )
+ {
+ if ( req_list->option[j] == sup_list->option[k] )
+ {
+#ifdef DEBUG
+ __rt_info( "chose value %d for option %x\n",
+ req_list->option[j], req_type );
+#endif
+ match = TRUE;
+ chosen_config.param[i].type = req_type;
+ chosen_config.param[i].value = req_list->option[j];
+ }
+ }
+ }
+
+ if ( !match )
+ {
+#ifdef ASSERTIONS_ENABLED
+ __rt_warning( "no match found for option %x\n", req_type );
+#endif
+ return NULL;
+ }
+ }
+
+ chosen_config.num_parameters = i;
+ INFO( "match succeeded" );
+ return &chosen_config;
+}
+#endif /* defined(TARGET) || defined(TEST_PARAMS) */
+
+
+#if !defined(TARGET) || defined(TEST_PARAMS)
+/*
+ * Function: Angel_StoreParam
+ * Purpose: store the value of a given parameter to a config.
+ *
+ * see params.h for details
+ */
+bool Angel_StoreParam( ParameterConfig *config,
+ ADP_Parameter type,
+ unsigned int value )
+{
+ unsigned int i;
+
+ for ( i = 0; i < config->num_parameters; ++i )
+ if ( config->param[i].type == type )
+ {
+ config->param[i].value = value;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+#endif /* !defined(TARGET) || defined(TEST_PARAMS) */
+
+
+#if defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS)
+/*
+ * Function: Angel_BuildParamConfigMessage
+ * Purpose: write a parameter config to a buffer in ADP format.
+ *
+ * see params.h for details
+ */
+unsigned int Angel_BuildParamConfigMessage( unsigned char *buffer,
+ const ParameterConfig *config )
+{
+ unsigned char *start = buffer;
+ unsigned int i;
+
+ PUT32LE( buffer, config->num_parameters );
+ buffer += sizeof( word );
+
+ for ( i = 0; i < config->num_parameters; ++i )
+ {
+ PUT32LE( buffer, config->param[i].type );
+ buffer += sizeof( word );
+ PUT32LE( buffer, config->param[i].value );
+ buffer += sizeof( word );
+ }
+
+ return (buffer - start);
+}
+#endif /* defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS) */
+
+
+#if !defined(TARGET) || defined(TEST_PARAMS)
+/*
+ * Function: Angel_BuildParamOptionsMessage
+ * Purpose: write a parameter Options to a buffer in ADP format.
+ *
+ * see params.h for details
+ */
+unsigned int Angel_BuildParamOptionsMessage( unsigned char *buffer,
+ const ParameterOptions *options )
+{
+ unsigned char *start = buffer;
+ unsigned int i, j;
+
+ PUT32LE( buffer, options->num_param_lists );
+ buffer += sizeof( word );
+
+ for ( i = 0; i < options->num_param_lists; ++i )
+ {
+ PUT32LE( buffer, options->param_list[i].type );
+ buffer += sizeof( word );
+ PUT32LE( buffer, options->param_list[i].num_options );
+ buffer += sizeof( word );
+ for ( j = 0; j < options->param_list[i].num_options; ++j )
+ {
+ PUT32LE( buffer, options->param_list[i].option[j] );
+ buffer += sizeof( word );
+ }
+ }
+
+ return (buffer - start);
+}
+#endif /* !defined(TARGET) || defined(TEST_PARAMS) */
+
+
+#if !defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS)
+/*
+ * Function: Angel_ReadParamConfigMessage
+ * Purpose: read a parameter config from a buffer where it is in ADP format.
+ *
+ * see params.h for details
+ */
+bool Angel_ReadParamConfigMessage( const unsigned char *buffer,
+ ParameterConfig *config )
+{
+ unsigned int word;
+ unsigned int i;
+
+ word = GET32LE( buffer );
+ buffer += sizeof( word );
+ if ( word > config->num_parameters )
+ {
+ WARN( "not enough space" );
+ return FALSE;
+ }
+ config->num_parameters = word;
+
+ for ( i = 0; i < config->num_parameters; ++i )
+ {
+ config->param[i].type = (ADP_Parameter)GET32LE( buffer );
+ buffer += sizeof( word );
+ config->param[i].value = GET32LE( buffer );
+ buffer += sizeof( word );
+ }
+
+ return TRUE;
+}
+#endif /* !defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS) */
+
+
+#if defined(TARGET) || defined(TEST_PARAMS)
+/*
+ * Function: Angel_ReadParamOptionsMessage
+ * Purpose: read a parameter options block from a buffer
+ * where it is in ADP format.
+ *
+ * see params.h for details
+ */
+bool Angel_ReadParamOptionsMessage( const unsigned char *buffer,
+ ParameterOptions *options )
+{
+ unsigned int word;
+ unsigned int i, j;
+
+ word = GET32LE( buffer );
+ buffer += sizeof( word );
+ if ( word > options->num_param_lists )
+ {
+ WARN( "not enough space" );
+ return FALSE;
+ }
+ options->num_param_lists = word;
+
+ for ( i = 0; i < options->num_param_lists; ++i )
+ {
+ ParameterList *list = &options->param_list[i];
+
+ list->type = (ADP_Parameter)GET32LE( buffer );
+ buffer += sizeof( word );
+ word = GET32LE( buffer );
+ buffer += sizeof( word );
+ if ( word > list->num_options )
+ {
+ WARN( "not enough list space" );
+ return FALSE;
+ }
+ list->num_options = word;
+
+ for ( j = 0; j < list->num_options; ++j )
+ {
+ list->option[j] = GET32LE( buffer );
+ buffer += sizeof( word );
+ }
+ }
+
+ return TRUE;
+}
+#endif /* defined(TARGET) || defined(TEST_PARAMS) */
+
+#endif /* !define(TARGET) || !defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0 */
+
+/* EOF params.c */
diff --git a/gdb/rdi-share/params.h b/gdb/rdi-share/params.h
new file mode 100644
index 00000000000..5b0757bc92d
--- /dev/null
+++ b/gdb/rdi-share/params.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Parameter negotiation structures and utilities
+ */
+
+#ifndef angel_params_h
+#define angel_params_h
+
+#include "angel.h"
+#include "adp.h"
+
+#ifndef TARGET
+# include "host.h"
+#endif
+
+/* A single parameter, with tag */
+typedef struct Parameter {
+ ADP_Parameter type;
+ unsigned int value;
+} Parameter;
+
+/* A list of parameter values, with tag */
+typedef struct ParameterList {
+ ADP_Parameter type;
+ unsigned int num_options;
+ unsigned int *option; /* points to array of values */
+} ParameterList;
+
+/* A configuration of one or more parameters */
+typedef struct ParameterConfig {
+ unsigned int num_parameters;
+ Parameter *param; /* pointer to array of Parameters */
+} ParameterConfig;
+
+/* A set of parameter options */
+typedef struct ParameterOptions {
+ unsigned int num_param_lists;
+ ParameterList *param_list; /* pointer to array of ParamLists */
+} ParameterOptions;
+
+/*
+ * Function: Angel_MatchParams
+ * Purpose: find a configuration from the requested options which is
+ * the best match from the supported options.
+ *
+ * Params:
+ * Input: requested The offered set of parameters.
+ * supported The supported set of parameters.
+ *
+ * Returns: ptr to config A match has been made, ptr to result
+ * will remain valid until next call to
+ * this function.
+ * NULL Match not possible
+ */
+const ParameterConfig *Angel_MatchParams( const ParameterOptions *requested,
+ const ParameterOptions *supported );
+
+/*
+ * Function: Angel_FindParam
+ * Purpose: find the value of a given parameter from a config.
+ *
+ * Params:
+ * Input: type parameter type to find
+ * config config to search
+ * Output: value parameter value if found
+ *
+ * Returns: TRUE parameter found
+ * FALSE parameter not found
+ */
+bool Angel_FindParam( ADP_Parameter type,
+ const ParameterConfig *config,
+ unsigned int *value );
+
+/*
+ * Function: Angel_StoreParam
+ * Purpose: store the value of a given parameter in a config.
+ *
+ * Params:
+ * In/Out: config config to store in
+ * Input: type parameter type to store
+ * value parameter value if found
+ *
+ * Returns: TRUE parameter found and new value stored
+ * FALSE parameter not found
+ */
+bool Angel_StoreParam( ParameterConfig *config,
+ ADP_Parameter type,
+ unsigned int value );
+
+/*
+ * Function: Angel_FindParamList
+ * Purpose: find the parameter list of a given parameter from an options.
+ *
+ * Params:
+ * Input: type parameter type to find
+ * options options block to search
+ *
+ * Returns: pointer to list
+ * NULL parameter not found
+ */
+ParameterList *Angel_FindParamList( const ParameterOptions *options,
+ ADP_Parameter type );
+
+/*
+ * Function: Angel_BuildParamConfigMessage
+ * Purpose: write a parameter config to a buffer in ADP format.
+ *
+ * Params:
+ * Input: buffer where to write to
+ * config the parameter config to write
+ *
+ * Returns: number of characters written to buffer
+ */
+unsigned int Angel_BuildParamConfigMessage( unsigned char *buffer,
+ const ParameterConfig *config );
+
+/*
+ * Function: Angel_BuildParamOptionsMessage
+ * Purpose: write a parameter Options to a buffer in ADP format.
+ *
+ * Params:
+ * Input: buffer where to write to
+ * options the options block to write
+ *
+ * Returns: number of characters written to buffer
+ */
+unsigned int Angel_BuildParamOptionsMessage( unsigned char *buffer,
+ const ParameterOptions *options );
+
+/*
+ * Function: Angel_ReadParamConfigMessage
+ * Purpose: read a parameter config from a buffer where it is in ADP format.
+ *
+ * Params:
+ * Input: buffer where to read from
+ * In/Out: config the parameter config to read to, which must
+ * be set up on entry with a valid array, and
+ * the size of the array in num_parameters.
+ *
+ * Returns: TRUE okay
+ * FALSE not enough space in config
+ */
+bool Angel_ReadParamConfigMessage( const unsigned char *buffer,
+ ParameterConfig *config );
+
+/*
+ * Function: Angel_ReadParamOptionsMessage
+ * Purpose: read a parameter options from a buffer
+ * where it is in ADP format.
+ *
+ * Params:
+ * Input: buffer where to read from
+ * In/Out: options the parameter options block to read to,
+ * which must be set up on entry with a valid
+ * array, and the size of the array in
+ * num_parameters. Each param_list must
+ * also be set up in the same way.
+ *
+ * Returns: TRUE okay
+ * FALSE not enough space in options
+ */
+bool Angel_ReadParamOptionsMessage( const unsigned char *buffer,
+ ParameterOptions *options );
+
+#endif /* ndef angel_params_h */
+
+/* EOF params.h */
diff --git a/gdb/rdi-share/rx.c b/gdb/rdi-share/rx.c
new file mode 100644
index 00000000000..caf833ad24b
--- /dev/null
+++ b/gdb/rdi-share/rx.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*-*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Character reception engine
+ */
+
+#include <stdarg.h> /* ANSI varargs support */
+#include "angel.h" /* Angel system definitions */
+#include "angel_endian.h" /* Endian independant memory access macros */
+#include "crc.h" /* crc generation definitions and headers */
+#include "rxtx.h"
+#include "channels.h"
+#include "buffers.h"
+#ifdef TARGET
+# include "devdriv.h"
+#endif
+#include "logging.h"
+
+static re_status unexp_stx(struct re_state *rxstate);
+static re_status unexp_etx(struct re_state *rxstate);
+
+/* bitfield for the rx_engine state */
+typedef enum rx_state_flag{
+ RST_STX,
+ RST_TYP,
+ RST_LEN,
+ RST_DAT,
+ RST_CRC,
+ RST_ETX,
+ RST_ESC = (0x1 << 0x3)
+} rx_state_flag;
+
+void Angel_RxEngineInit(const struct re_config *rxconfig,
+ struct re_state *rxstate)
+{
+ rxstate->rx_state = RST_STX;
+ rxstate->field_c = 0;
+ rxstate->index = 0;
+ rxstate->crc = 0;
+ rxstate->error = RE_OKAY;
+ rxstate->config = rxconfig;
+}
+
+re_status Angel_RxEngine(unsigned char new_ch, struct data_packet *packet,
+ struct re_state *rxstate)
+{
+ /*
+ * TODO: add the flow control bits in
+ * Note: We test for the data field in a seperate case so we can
+ * completely avoid entering the switch for most chars
+ */
+
+ /* see if we're expecting a escaped char */
+ if ((rxstate->rx_state & RST_ESC) == RST_ESC)
+ {
+ /* unescape the char and unset the flag*/
+ new_ch &= ~serial_ESCAPE;
+#ifdef DO_TRACE
+ __rt_trace("rxe-echar-%2x ", new_ch);
+#endif
+ rxstate->rx_state &= ~RST_ESC;
+ }
+ else if ( (1 << new_ch) & rxstate->config->esc_set )
+ {
+ /* see if the incoming char is a special one */
+ if (new_ch == rxstate->config->esc)
+ {
+#ifdef DO_TRACE
+ __rt_trace("rxe-esc ");
+#endif
+ rxstate->rx_state |= RST_ESC;
+ return RS_IN_PKT;
+ }
+ else
+ {
+ /*
+ * must be a normal packet so do some unexpected etx/stx checking
+ * we haven't been told to escape or received an escape so unless
+ * we are expecting an stx or etx then we can take the unexpected
+ * stx/etx trap
+ */
+ if ((new_ch == (rxstate->config->stx)) && (rxstate->rx_state != RST_STX))
+ return unexp_stx(rxstate);
+ if ((new_ch == (rxstate->config->etx)) && (rxstate->rx_state != RST_ETX))
+ return unexp_etx(rxstate);
+ }
+ }
+
+ if (rxstate->rx_state == RST_DAT)
+ {
+ /*
+ * do this to speed up the common case, no real penalty for
+ * other cases
+ */
+#ifdef DO_TRACE
+ __rt_trace("rxe-dat ");
+#endif
+
+ rxstate->crc = crc32(&new_ch, 1, rxstate->crc);
+ (packet->data)[rxstate->index++] = (unsigned int)new_ch & 0xff;
+
+ if (rxstate->index == packet->len)
+ rxstate->rx_state = RST_CRC;
+
+ return RS_IN_PKT;
+ }
+
+ /*
+ * Now that the common case is out of the way we can test for everything
+ * else without worrying quite so much about the speed, changing the
+ * order to len,crc,stx,etx,typ might gain a tiny bit of speed but lets
+ * leave that for the moment
+ */
+ switch (rxstate->rx_state)
+ {
+ case RST_STX:
+ if (new_ch == rxstate->config->stx)
+ {
+ rxstate->rx_state = RST_TYP;
+ rxstate->error = RE_OKAY;
+ rxstate->crc = startCRC32;
+ rxstate->index = 0;
+ return RS_IN_PKT;
+ }
+ else
+ {
+ rxstate->error = RE_OKAY;
+ return RS_WAIT_PKT;
+ }
+
+ case RST_TYP:
+ packet->type = (DevChanID)new_ch;
+ rxstate->rx_state = RST_LEN;
+ rxstate->error = RE_OKAY;
+ rxstate->field_c = 0; /* set up here for the length that follows */
+#ifdef DO_TRACE
+ __rt_trace("rxe-type-%2x ", packet->type);
+#endif
+ rxstate->crc = crc32(&new_ch, 1, rxstate->crc);
+
+ return RS_IN_PKT;
+
+ case RST_LEN:
+ rxstate->crc = crc32(&new_ch, 1, rxstate->crc);
+
+ if (rxstate->field_c++ == 0)
+ {
+ /* first length byte */
+ packet->len = ((unsigned int)new_ch) << 8;
+ return RS_IN_PKT;
+ }
+ else
+ {
+ /* got the whole legth */
+ packet->len |= new_ch;
+#ifdef DO_TRACE
+ __rt_trace("rxe-len-%4x\n", packet->len);
+#endif
+
+ /* check that the length is ok */
+ if (packet->len == 0)
+ {
+ /* empty pkt */
+ rxstate->field_c = 0;
+ rxstate->rx_state = RST_CRC;
+ return RS_IN_PKT;
+ }
+ else
+ {
+ if (packet->data == NULL)
+ {
+ /* need to alloc the data buffer */
+ if (!rxstate->config->ba_callback(
+ packet, rxstate->config->ba_data)) {
+ rxstate->rx_state = RST_STX;
+ rxstate->error = RE_INTERNAL;
+ return RS_BAD_PKT;
+ }
+ }
+
+ if (packet->len > packet->buf_len)
+ {
+ /* pkt bigger than buffer */
+ rxstate->field_c = 0;
+ rxstate->rx_state = RST_STX;
+ rxstate->error = RE_LEN;
+ return RS_BAD_PKT;
+ }
+ else
+ {
+ /* packet ok */
+ rxstate->field_c = 0;
+ rxstate->rx_state = RST_DAT;
+ return RS_IN_PKT;
+ }
+ }
+ }
+
+ case RST_DAT:
+ /* dummy case (dealt with earlier) */
+#ifdef ASSERTIONS_ENABLED
+ __rt_warning("ERROR: hit RST_dat in switch\n");
+#endif
+ rxstate->rx_state = RST_STX;
+ rxstate->error = RE_INTERNAL;
+ return RS_BAD_PKT;
+
+ case RST_CRC:
+ if (rxstate->field_c == 0)
+ packet->crc = 0;
+
+ packet->crc |= (new_ch & 0xFF) << ((3 - rxstate->field_c) * 8);
+ rxstate->field_c++;
+
+ if (rxstate->field_c == 4)
+ {
+ /* last crc field */
+ rxstate->field_c = 0;
+ rxstate->rx_state = RST_ETX;
+#ifdef DO_TRACE
+ __rt_trace("rxe-rcrc-%8x ", packet->crc);
+#endif
+ }
+
+ return RS_IN_PKT;
+
+ case RST_ETX:
+ if (new_ch == rxstate->config->etx)
+ {
+#if defined(DEBUG) && !defined(NO_PKT_DATA)
+ {
+ int c;
+# ifdef DO_TRACE
+ __rt_trace("\n");
+# endif
+ __rt_info("RXE Data =");
+ for (c=0; c < packet->len; c++)
+ __rt_info("%02x", packet->data[c]);
+ __rt_info("\n");
+ }
+#endif
+
+ /* check crc */
+ if (rxstate->crc == packet->crc)
+ {
+ /* crc ok */
+ rxstate->rx_state = RST_STX;
+ rxstate->field_c = 0;
+ return RS_GOOD_PKT;
+ }
+ else
+ {
+#ifdef ASSERTIONS_ENABLED
+ __rt_warning("Bad crc, rx calculates it should be 0x%x\n", rxstate->crc);
+#endif
+ rxstate->rx_state = RST_STX;
+ rxstate->error = RE_CRC;
+ return RS_BAD_PKT;
+ }
+ }
+ else if (new_ch == rxstate->config->stx)
+ return unexp_stx(rxstate);
+ else
+ {
+ rxstate->rx_state = RST_STX;
+ rxstate->error = RE_NETX;
+ return RS_BAD_PKT;
+ }
+
+ default:
+#ifdef ASSERTIONS_ENABLED
+ __rt_warning("ERROR fell through rxengine\n");
+#endif
+ rxstate->rx_state = RST_STX;
+ rxstate->error = RE_INTERNAL;
+ return RS_BAD_PKT;
+ }
+}
+
+static re_status unexp_stx(struct re_state *rxstate)
+{
+#ifdef ASSERTIONS_ENABLED
+ __rt_warning("Unexpected stx\n");
+#endif
+ rxstate->crc = startCRC32;
+ rxstate->index = 0;
+ rxstate->rx_state = RST_TYP;
+ rxstate->error = RE_U_STX;
+ rxstate->field_c = 0;
+ return RS_BAD_PKT;
+}
+
+static re_status unexp_etx(struct re_state *rxstate)
+{
+#ifdef ASSERTIONS_ENABLED
+ __rt_warning("Unexpected etx, rxstate: index= 0x%2x, field_c=0x%2x, state=0x%2x\n", rxstate->index, rxstate->field_c, rxstate->rx_state);
+#endif
+ rxstate->crc = 0;
+ rxstate->index = 0;
+ rxstate->rx_state = RST_STX;
+ rxstate->error = RE_U_ETX;
+ rxstate->field_c = 0;
+ return RS_BAD_PKT;
+}
+
+/*
+ * This can be used as the buffer allocation callback for the rx engine,
+ * and makes use of angel_DD_GetBuffer() [in devdrv.h].
+ *
+ * Saves duplicating this callback function in every device driver that
+ * uses the rx engine.
+ *
+ * Note that this REQUIRES that the device id is installed as ba_data
+ * in the rx engine config structure for the driver.
+ */
+bool angel_DD_RxEng_BufferAlloc( struct data_packet *packet, void *cb_data )
+{
+#ifdef TARGET
+ DeviceID devid = (DeviceID)cb_data;
+#else
+ IGNORE(cb_data);
+#endif
+
+ if ( packet->type < DC_NUM_CHANNELS )
+ {
+ /* request a buffer down from the channels layer */
+#ifdef TARGET
+ packet->data = angel_DD_GetBuffer( devid, packet->type,
+ packet->len );
+#else
+ packet->data = malloc(packet->len);
+#endif
+ if ( packet->data == NULL )
+ return FALSE;
+ else
+ {
+ packet->buf_len = packet->len;
+ return TRUE;
+ }
+ }
+ else
+ {
+ /* bad type field */
+ return FALSE;
+ }
+}
+
+/* EOF rx.c */
diff --git a/gdb/rdi-share/rxtx.h b/gdb/rdi-share/rxtx.h
new file mode 100644
index 00000000000..204e99870fa
--- /dev/null
+++ b/gdb/rdi-share/rxtx.h
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*-*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Definitions required for the rx and tx engines
+ */
+
+#ifndef angel_rxtx_h
+#define angel_rxtx_h
+
+
+/*
+ * we need a definition for bool, which is "system" dependent
+ */
+#ifdef TARGET
+# include "angel.h"
+#else
+# include "host.h"
+#endif
+
+#include "devclnt.h"
+
+/* return status codes for the rx engine */
+typedef enum re_status {
+ RS_WAIT_PKT,
+ RS_IN_PKT,
+ RS_BAD_PKT,
+ RS_GOOD_PKT
+} re_status;
+
+/* return status codes for the tx engine */
+typedef enum te_status {
+ TS_IDLE,
+ TS_IN_PKT,
+ TS_DONE_PKT
+} te_status;
+
+
+/*
+ * required serial definitions, they should all be <32, refer to the
+ * re_config struct comments for more details
+ */
+#define serial_STX (0x1c) /* data packet start */
+#define serial_ETX (0x1d) /* packet end */
+#define serial_ESC (0x1b) /* standard escape character */
+#define serial_XON (0x11) /* software flow control - enable transmission */
+#define serial_XOFF (0x13) /* software flow control - disable transmission */
+
+/*
+ * All other characters are transmitted clean. If any of the above
+ * characters need to be transmitted as part of the serial data stream
+ * then the character will be preceded by the "serial_ESC" character,
+ * and then the required character transmitted (OR-ed with the
+ * "serial_ESCAPE" value, to ensure that the serial stream never has
+ * any of the exceptional characters generated by data transfers).
+ */
+
+#define serial_ESCAPE (0x40) /* OR-ed with escaped characters */
+
+/* bad packet error codes */
+typedef enum re_error {
+ RE_OKAY,
+ RE_U_STX,
+ RE_U_ETX,
+ RE_LEN,
+ RE_CRC,
+ RE_NETX,
+ RE_INTERNAL
+} re_error;
+
+/* a decoded packet */
+struct data_packet {
+ unsigned short buf_len; /* should be set by caller */
+ DevChanID type; /* valid when status is RS_GOOD_PKT */
+ unsigned short len; /* --"-- */
+ unsigned int crc; /* crc for the unescaped pkt */
+ unsigned char *data; /* should be set by caller */
+};
+
+/*
+ * Purpose: typedef for flow control function
+ *
+ * Params:
+ * Input: fc_char the flow control character in question
+ * In/Out: cb_data callback data as set in the fc_data
+ * field of re_config, typically device id
+ *
+ * This callback would tpyically respond to received XON and XOFF
+ * characters by controlling the transmit side of the device.
+ */
+typedef void (*fc_cb_func)(char fc_char, void *cb_data);
+
+
+/*
+ * Purpose: typedef for the function to alloc the data buffer
+ *
+ * Params:
+ * In/Out: packet the data packet: len and type will be set on
+ * entry, and buf_len and data should
+ * be set by this routine if successful.
+ * cb_data callback data as set in the ba_data
+ * field of re_config, typically device id
+ *
+ * Returns: TRUE buffer allocated okay
+ * FALSE couldn't allocate buffer of required size
+ * for given type
+ *
+ * This callback should attempt to acquire a buffer for the data portion
+ * of the packet which is currently being received, based on the len and
+ * type fields supplied in packet.
+ *
+ * angel_DD_RxEng_BufferAlloc() is supplied for use as this callback,
+ * and will be sufficient for most devices.
+ */
+typedef bool (*BufferAlloc_CB_Fn)(struct data_packet *packet, void *cb_data);
+
+
+/*
+ * The static info needed by the engine, may vary per device.
+ *
+ * fc_set and esc_set are bitmaps, e.g. bit 3 == charcode 3 == ASCII ETX.
+ * Thus any of the first 32 charcodes can be set for flow control or to
+ * be escaped.
+ *
+ * Note that esc_set should include all of fc_set, and should have bits
+ * set for stx, etx and esc, as a minimum.
+ *
+ * If character codes > 31 need to be used then fc_set and esc_set
+ * and their handling can be extended to use arrays and bit manipulation
+ * macros, potentially up to the full 256 possible chars.
+ *
+ * Note too that this could/should be shared with the tx engine.
+ */
+
+struct re_config {
+ unsigned char stx; /* the STX char for this device */
+ unsigned char etx; /* the ETX --"-- */
+ unsigned char esc; /* the ESC --"-- */
+ unsigned int fc_set; /* bitmap of flow control chars */
+ unsigned int esc_set; /* bitmap of special chars */
+ fc_cb_func fc_callback; /* flow control callback func */
+ void *fc_data; /* data to pass to fc_callback */
+ BufferAlloc_CB_Fn ba_callback; /* buffer alloc callback */
+ void *ba_data; /* data to pass to ba_calback */
+};
+
+/* the dynamic info needed by the rx engine */
+struct re_state {
+ unsigned char rx_state; /* 3 bits pkt state, 1 prepro state */
+ unsigned short field_c; /* chars left in current field */
+ unsigned short index; /* index into buffer */
+ unsigned int crc; /* crc accumulator */
+ re_error error; /* valid only if status is RS_BAD_PKT */
+ const struct re_config *config; /* pointer to static config */
+};
+
+/* dynamic state info needed by the tx engine */
+struct te_state {
+ unsigned short field_c; /* position in current field */
+ unsigned char tx_state; /* encodes n,e, and f (2+1+2=5 bits) */
+ unsigned char encoded; /* escape-encoded char for transmission */
+ const struct re_config *config; /* pointer to static config */
+ unsigned int crc; /* space for CRC (before escaping) */
+};
+
+/*
+ * Function: Angel_RxEngineInit
+ * Purpose: Initialise state (during device init) for engine.
+ *
+ * Params:
+ * Input: config static config info
+ * In/Out: state internal state
+ */
+
+void Angel_RxEngineInit(const struct re_config *config,
+ struct re_state *state);
+
+/*
+ * Function: Angel_RxEngine
+ * Purpose: Rx Engine for character-based devices
+ *
+ * Params:
+ * Input: new_ch the latest character
+ *
+ * In/Out: packet details of packet
+ * packet.buf_len and packet.data must
+ * be set on entry!
+ * state internal state, intially set by
+ * angel_RxEngineInit()
+ *
+ * Returns: re_status (see above)
+ *
+ */
+
+re_status Angel_RxEngine(unsigned char new_ch, struct data_packet *packet,
+ struct re_state *state);
+
+/*
+ * This can be used as the buffer allocation callback for the rx engine,
+ * and will make use of angel_DD_GetBuffer() [in devdrv.h].
+ *
+ * Saves duplicating this callback function in every device driver that
+ * uses the rx engine.
+ *
+ * Note that this REQUIRES that the device id is installed as ba_data
+ * in the rx engine config structure for the driver.
+ */
+bool angel_DD_RxEng_BufferAlloc( struct data_packet *packet, void *cb_data );
+
+/*
+ * Function: Angel_TxEngineInit
+ * Purpose: Set up tx engine at start of new packet, calculate CRC etc.
+ * (This should perform the actions described under
+ * "Initialisation" above)
+ *
+ * Params:
+ * Input: config static config info
+ * packet the packet to transmit
+ * In/Out: state internal state
+ */
+
+void Angel_TxEngineInit(const struct re_config *config,
+ const struct data_packet *packet,
+ struct te_state *state);
+
+/*
+ * Function: Angel_TxEngine
+ * Purpose: Tx Engine for character-based devices
+ *
+ * Params:
+ * Input: packet details of packet
+ * packet.len, packet.data and
+ * packet.type must
+ * be set on entry!
+ * In/Out: state internal state, intially set by
+ * angel_TxEngineStart()
+ * Output: tx_ch the character to be transmitted
+ * (NOT SET if return code is TS_IDLE)
+ *
+ * Returns: te_status (see above)
+ */
+
+te_status Angel_TxEngine(const struct data_packet *packet,
+ struct te_state *state,
+ unsigned char *tx_ch);
+
+
+
+#endif /* !defined(angel_rxtx_h) */
+
+/* EOF rxtx.h */
diff --git a/gdb/rdi-share/serdrv.c b/gdb/rdi-share/serdrv.c
new file mode 100644
index 00000000000..91f8f196b2f
--- /dev/null
+++ b/gdb/rdi-share/serdrv.c
@@ -0,0 +1,667 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * serdrv.c - Synchronous Serial Driver for Angel.
+ * This is nice and simple just to get something going.
+ */
+
+#ifdef __hpux
+# define _POSIX_SOURCE 1
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "crc.h"
+#include "devices.h"
+#include "buffers.h"
+#include "rxtx.h"
+#include "hostchan.h"
+#include "params.h"
+#include "logging.h"
+
+extern int baud_rate; /* From gdb/top.c */
+
+#ifdef COMPILING_ON_WINDOWS
+# undef ERROR
+# undef IGNORE
+# include <windows.h>
+# include "angeldll.h"
+# include "comb_api.h"
+#else
+# ifdef __hpux
+# define _TERMIOS_INCLUDED
+# include <sys/termio.h>
+# undef _TERMIOS_INCLUDED
+# else
+# include <termios.h>
+# endif
+# include "unixcomm.h"
+#endif
+
+#ifndef UNUSED
+# define UNUSED(x) (x = x) /* Silence compiler warnings */
+#endif
+
+#define MAXREADSIZE 512
+#define MAXWRITESIZE 512
+
+#define SERIAL_FC_SET ((1<<serial_XON)|(1<<serial_XOFF))
+#define SERIAL_CTL_SET ((1<<serial_STX)|(1<<serial_ETX)|(1<<serial_ESC))
+#define SERIAL_ESC_SET (SERIAL_FC_SET|SERIAL_CTL_SET)
+
+static const struct re_config config = {
+ serial_STX, serial_ETX, serial_ESC, /* self-explanatory? */
+ SERIAL_FC_SET, /* set of flow-control characters */
+ SERIAL_ESC_SET, /* set of characters to be escaped */
+ NULL /* serial_flow_control */, NULL , /* what to do with FC chars */
+ angel_DD_RxEng_BufferAlloc, NULL /* how to get a buffer */
+};
+
+static struct re_state rxstate;
+
+typedef struct writestate {
+ unsigned int wbindex;
+ /* static te_status testatus;*/
+ unsigned char writebuf[MAXWRITESIZE];
+ struct te_state txstate;
+} writestate;
+
+static struct writestate wstate;
+
+/*
+ * The set of parameter options supported by the device
+ */
+static unsigned int baud_options[] = {
+#if defined(B115200) || defined(__hpux)
+ 115200,
+#endif
+#if defined(B57600) || defined(__hpux)
+ 57600,
+#endif
+ 38400, 19200, 9600
+};
+
+static ParameterList param_list[] = {
+ { AP_BAUD_RATE,
+ sizeof(baud_options)/sizeof(unsigned int),
+ baud_options }
+};
+
+static const ParameterOptions serial_options = {
+ sizeof(param_list)/sizeof(ParameterList), param_list };
+
+/*
+ * The default parameter config for the device
+ */
+static Parameter param_default[] = {
+ { AP_BAUD_RATE, 9600 }
+};
+
+static ParameterConfig serial_defaults = {
+ sizeof(param_default)/sizeof(Parameter), param_default };
+
+/*
+ * The user-modified options for the device
+ */
+static unsigned int user_baud_options[sizeof(baud_options)/sizeof(unsigned)];
+
+static ParameterList param_user_list[] = {
+ { AP_BAUD_RATE,
+ sizeof(user_baud_options)/sizeof(unsigned),
+ user_baud_options }
+};
+
+static ParameterOptions user_options = {
+ sizeof(param_user_list)/sizeof(ParameterList), param_user_list };
+
+static bool user_options_set;
+
+/* forward declarations */
+static int serial_reset( void );
+static int serial_set_params( const ParameterConfig *config );
+static int SerialMatch(const char *name, const char *arg);
+
+static void process_baud_rate( unsigned int target_baud_rate )
+{
+ const ParameterList *full_list;
+ ParameterList *user_list;
+
+ /* create subset of full options */
+ full_list = Angel_FindParamList( &serial_options, AP_BAUD_RATE );
+ user_list = Angel_FindParamList( &user_options, AP_BAUD_RATE );
+
+ if ( full_list != NULL && user_list != NULL )
+ {
+ unsigned int i, j;
+ unsigned int def_baud = 0;
+
+ /* find lower or equal to */
+ for ( i = 0; i < full_list->num_options; ++i )
+ if ( target_baud_rate >= full_list->option[i] )
+ {
+ /* copy remaining */
+ for ( j = 0; j < (full_list->num_options - i); ++j )
+ user_list->option[j] = full_list->option[i+j];
+ user_list->num_options = j;
+
+ /* check this is not the default */
+ Angel_FindParam( AP_BAUD_RATE, &serial_defaults, &def_baud );
+ if ( (j == 1) && (user_list->option[0] == def_baud) )
+ {
+#ifdef DEBUG
+ printf( "user selected default\n" );
+#endif
+ }
+ else
+ {
+ user_options_set = TRUE;
+#ifdef DEBUG
+ printf( "user options are: " );
+ for ( j = 0; j < user_list->num_options; ++j )
+ printf( "%u ", user_list->option[j] );
+ printf( "\n" );
+#endif
+ }
+
+ break; /* out of i loop */
+ }
+
+#ifdef DEBUG
+ if ( i >= full_list->num_options )
+ printf( "couldn't match baud rate %u\n", target_baud_rate );
+#endif
+ }
+#ifdef DEBUG
+ else
+ printf( "failed to find lists\n" );
+#endif
+}
+
+static int SerialOpen(const char *name, const char *arg)
+{
+ const char *port_name = name;
+
+#ifdef DEBUG
+ printf("SerialOpen: name %s arg %s\n", name, arg ? arg : "<NULL>");
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ if (IsOpenSerial()) return -1;
+#else
+ if (Unix_IsSerialInUse()) return -1;
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ if (SerialMatch(name, arg) != adp_ok)
+ return adp_failed;
+#else
+ port_name = Unix_MatchValidSerialDevice(port_name);
+# ifdef DEBUG
+ printf("translated port to %s\n", port_name == 0 ? "NULL" : port_name);
+# endif
+ if (port_name == 0) return adp_failed;
+#endif
+
+ user_options_set = FALSE;
+
+ /* interpret and store the arguments */
+ if ( arg != NULL )
+ {
+ unsigned int target_baud_rate;
+ target_baud_rate = (unsigned int)strtoul(arg, NULL, 10);
+ if (target_baud_rate > 0)
+ {
+#ifdef DEBUG
+ printf( "user selected baud rate %u\n", target_baud_rate );
+#endif
+ process_baud_rate( target_baud_rate );
+ }
+#ifdef DEBUG
+ else
+ printf( "could not understand baud rate %s\n", arg );
+#endif
+ }
+ else if (baud_rate > 0)
+ {
+ /* If the user specified a baud rate on the command line "-b" or via
+ the "set remotebaud" command then try to use that one */
+ process_baud_rate( baud_rate );
+ }
+
+#ifdef COMPILING_ON_WINDOWS
+ {
+ int port = IsValidDevice(name);
+ if (OpenSerial(port, FALSE) != COM_OK)
+ return -1;
+ }
+#else
+ if (Unix_OpenSerial(port_name) < 0)
+ return -1;
+#endif
+
+ serial_reset();
+
+#if defined(__unix) || defined(__CYGWIN32__)
+ Unix_ioctlNonBlocking();
+#endif
+
+ Angel_RxEngineInit(&config, &rxstate);
+ /*
+ * DANGER!: passing in NULL as the packet is ok for now as it is just
+ * IGNOREd but this may well change
+ */
+ Angel_TxEngineInit(&config, NULL, &wstate.txstate);
+ return 0;
+}
+
+static int SerialMatch(const char *name, const char *arg)
+{
+ UNUSED(arg);
+#ifdef COMPILING_ON_WINDOWS
+ if (IsValidDevice(name) == COM_DEVICENOTVALID)
+ return -1;
+ else
+ return 0;
+#else
+ return Unix_MatchValidSerialDevice(name) == 0 ? -1 : 0;
+#endif
+}
+
+static void SerialClose(void)
+{
+#ifdef DO_TRACE
+ printf("SerialClose()\n");
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ CloseSerial();
+#else
+ Unix_CloseSerial();
+#endif
+}
+
+static int SerialRead(DriverCall *dc, bool block) {
+ static unsigned char readbuf[MAXREADSIZE];
+ static int rbindex=0;
+
+ int nread;
+ int read_errno;
+ int c=0;
+ re_status restatus;
+ int ret_code = -1; /* assume bad packet or error */
+
+ /* must not overflow buffer and must start after the existing data */
+#ifdef COMPILING_ON_WINDOWS
+ {
+ BOOL dummy = FALSE;
+ nread = BytesInRXBufferSerial();
+
+ if (nread > MAXREADSIZE - rbindex)
+ nread = MAXREADSIZE - rbindex;
+
+ if ((read_errno = ReadSerial(readbuf+rbindex, nread, &dummy)) == COM_READFAIL)
+ {
+ MessageBox(GetFocus(), "Read error\n", "Angel", MB_OK | MB_ICONSTOP);
+ return -1; /* SJ - This really needs to return a value, which is picked up in */
+ /* DevSW_Read as meaning stop debugger but don't kill. */
+ }
+ else if (pfnProgressCallback != NULL && read_errno == COM_OK)
+ {
+ progressInfo.nRead += nread;
+ (*pfnProgressCallback)(&progressInfo);
+ }
+ }
+#else
+ nread = Unix_ReadSerial(readbuf+rbindex, MAXREADSIZE-rbindex, block);
+ read_errno = errno;
+#endif
+
+ if ((nread > 0) || (rbindex > 0)) {
+
+#ifdef DO_TRACE
+ printf("[%d@%d] ", nread, rbindex);
+#endif
+
+ if (nread>0)
+ rbindex = rbindex+nread;
+
+ do {
+ restatus = Angel_RxEngine(readbuf[c], &(dc->dc_packet), &rxstate);
+#ifdef DO_TRACE
+ printf("<%02X ",readbuf[c]);
+ if (!(++c % 16))
+ printf("\n");
+#else
+ c++;
+#endif
+ } while (c<rbindex &&
+ ((restatus == RS_IN_PKT) || (restatus == RS_WAIT_PKT)));
+
+#ifdef DO_TRACE
+ if (c % 16)
+ printf("\n");
+#endif
+
+ switch(restatus) {
+
+ case RS_GOOD_PKT:
+ ret_code = 1;
+ /* fall through to: */
+
+ case RS_BAD_PKT:
+ /*
+ * We now need to shuffle any left over data down to the
+ * beginning of our private buffer ready to be used
+ *for the next packet
+ */
+#ifdef DO_TRACE
+ printf("SerialRead() processed %d, moving down %d\n", c, rbindex-c);
+#endif
+ if (c != rbindex) memmove((char *) readbuf, (char *) (readbuf+c),
+ rbindex-c);
+ rbindex -= c;
+ break;
+
+ case RS_IN_PKT:
+ case RS_WAIT_PKT:
+ rbindex = 0; /* will have processed all we had */
+ ret_code = 0;
+ break;
+
+ default:
+#ifdef DEBUG
+ printf("Bad re_status in serialRead()\n");
+#endif
+ break;
+ }
+ } else if (nread == 0)
+ ret_code = 0; /* nothing to read */
+ else if (read_errno == ERRNO_FOR_BLOCKED_IO) /* nread < 0 */
+ ret_code = 0;
+
+#ifdef DEBUG
+ if ((nread<0) && (read_errno!=ERRNO_FOR_BLOCKED_IO))
+ perror("read() error in serialRead()");
+#endif
+
+ return ret_code;
+}
+
+
+static int SerialWrite(DriverCall *dc) {
+ int nwritten = 0;
+ te_status testatus = TS_IN_PKT;
+
+ if (dc->dc_context == NULL) {
+ Angel_TxEngineInit(&config, &(dc->dc_packet), &(wstate.txstate));
+ wstate.wbindex = 0;
+ dc->dc_context = &wstate;
+ }
+
+ while ((testatus == TS_IN_PKT) && (wstate.wbindex < MAXWRITESIZE))
+ {
+ /* send the raw data through the tx engine to escape and encapsulate */
+ testatus = Angel_TxEngine(&(dc->dc_packet), &(wstate.txstate),
+ &(wstate.writebuf)[wstate.wbindex]);
+ if (testatus != TS_IDLE) wstate.wbindex++;
+ }
+
+ if (testatus == TS_IDLE) {
+#ifdef DEBUG
+ printf("SerialWrite: testatus is TS_IDLE during preprocessing\n");
+#endif
+ }
+
+#ifdef DO_TRACE
+ {
+ int i = 0;
+
+ while (i<wstate.wbindex)
+ {
+ printf(">%02X ",wstate.writebuf[i]);
+
+ if (!(++i % 16))
+ printf("\n");
+ }
+ if (i % 16)
+ printf("\n");
+ }
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ if (WriteSerial(wstate.writebuf, wstate.wbindex) == COM_OK)
+ {
+ nwritten = wstate.wbindex;
+ if (pfnProgressCallback != NULL)
+ {
+ progressInfo.nWritten += nwritten;
+ (*pfnProgressCallback)(&progressInfo);
+ }
+ }
+ else
+ {
+ MessageBox(GetFocus(), "Write error\n", "Angel", MB_OK | MB_ICONSTOP);
+ return -1; /* SJ - This really needs to return a value, which is picked up in */
+ /* DevSW_Read as meaning stop debugger but don't kill. */
+ }
+#else
+ nwritten = Unix_WriteSerial(wstate.writebuf, wstate.wbindex);
+
+ if (nwritten < 0) {
+ nwritten=0;
+ }
+#endif
+
+#ifdef DEBUG
+ if (nwritten > 0)
+ printf("Wrote %#04x bytes\n", nwritten);
+#endif
+
+ if ((unsigned) nwritten == wstate.wbindex &&
+ (testatus == TS_DONE_PKT || testatus == TS_IDLE)) {
+
+ /* finished sending the packet */
+
+#ifdef DEBUG
+ printf("SerialWrite: calling Angel_TxEngineInit after sending packet (len=%i)\n",wstate.wbindex);
+#endif
+ testatus = TS_IN_PKT;
+ wstate.wbindex = 0;
+ return 1;
+ }
+ else {
+#ifdef DEBUG
+ printf("SerialWrite: Wrote part of packet wbindex=%i, nwritten=%i\n",
+ wstate.wbindex, nwritten);
+#endif
+
+ /*
+ * still some data left to send shuffle whats left down and reset
+ * the ptr
+ */
+ memmove((char *) wstate.writebuf, (char *) (wstate.writebuf+nwritten),
+ wstate.wbindex-nwritten);
+ wstate.wbindex -= nwritten;
+ return 0;
+ }
+ return -1;
+}
+
+
+static int serial_reset( void )
+{
+#ifdef DEBUG
+ printf( "serial_reset\n" );
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ FlushSerial();
+#else
+ Unix_ResetSerial();
+#endif
+
+ return serial_set_params( &serial_defaults );
+}
+
+
+static int find_baud_rate( unsigned int *speed )
+{
+ static struct {
+ unsigned int baud;
+ int termiosValue;
+ } possibleBaudRates[] = {
+#if defined(__hpux)
+ {115200,_B115200}, {57600,_B57600},
+#else
+#ifdef B115200
+ {115200,B115200},
+#endif
+#ifdef B57600
+ {57600,B57600},
+#endif
+#endif
+#ifdef COMPILING_ON_WINDOWS
+ {38400,CBR_38400}, {19200,CBR_19200}, {9600, CBR_9600}, {0,0}
+#else
+ {38400,B38400}, {19200,B19200}, {9600, B9600}, {0,0}
+#endif
+ };
+ unsigned int i;
+
+ /* look for lower or matching -- will always terminate at 0 end marker */
+ for ( i = 0; possibleBaudRates[i].baud > *speed; ++i )
+ /* do nothing */ ;
+
+ if ( possibleBaudRates[i].baud > 0 )
+ *speed = possibleBaudRates[i].baud;
+
+ return possibleBaudRates[i].termiosValue;
+}
+
+
+static int serial_set_params( const ParameterConfig *config )
+{
+ unsigned int speed;
+ int termios_value;
+
+#ifdef DEBUG
+ printf( "serial_set_params\n" );
+#endif
+
+ if ( ! Angel_FindParam( AP_BAUD_RATE, config, &speed ) )
+ {
+#ifdef DEBUG
+ printf( "speed not found in config\n" );
+#endif
+ return DE_OKAY;
+ }
+
+ termios_value = find_baud_rate( &speed );
+ if ( termios_value == 0 )
+ {
+#ifdef DEBUG
+ printf( "speed not valid: %u\n", speed );
+#endif
+ return DE_OKAY;
+ }
+
+#ifdef DEBUG
+ printf( "setting speed to %u\n", speed );
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ SetBaudRate((WORD)termios_value);
+#else
+ Unix_SetSerialBaudRate(termios_value);
+#endif
+
+ return DE_OKAY;
+}
+
+
+static int serial_get_user_params( ParameterOptions **p_options )
+{
+#ifdef DEBUG
+ printf( "serial_get_user_params\n" );
+#endif
+
+ if ( user_options_set )
+ {
+ *p_options = &user_options;
+ }
+ else
+ {
+ *p_options = NULL;
+ }
+
+ return DE_OKAY;
+}
+
+
+static int serial_get_default_params( ParameterConfig **p_config )
+{
+#ifdef DEBUG
+ printf( "serial_get_default_params\n" );
+#endif
+
+ *p_config = (ParameterConfig *) &serial_defaults;
+ return DE_OKAY;
+}
+
+
+static int SerialIoctl(const int opcode, void *args) {
+
+ int ret_code;
+
+#ifdef DEBUG
+ printf( "SerialIoctl: op %d arg %p\n", opcode, args ? args : "<NULL>");
+#endif
+
+ switch (opcode)
+ {
+ case DC_RESET:
+ ret_code = serial_reset();
+ break;
+
+ case DC_SET_PARAMS:
+ ret_code = serial_set_params((const ParameterConfig *)args);
+ break;
+
+ case DC_GET_USER_PARAMS:
+ ret_code = serial_get_user_params((ParameterOptions **)args);
+ break;
+
+ case DC_GET_DEFAULT_PARAMS:
+ ret_code = serial_get_default_params((ParameterConfig **)args);
+ break;
+
+ default:
+ ret_code = DE_BAD_OP;
+ break;
+ }
+
+ return ret_code;
+}
+
+DeviceDescr angel_SerialDevice = {
+ "SERIAL",
+ SerialOpen,
+ SerialMatch,
+ SerialClose,
+ SerialRead,
+ SerialWrite,
+ SerialIoctl
+};
diff --git a/gdb/rdi-share/serpardr.c b/gdb/rdi-share/serpardr.c
new file mode 100644
index 00000000000..604d0480613
--- /dev/null
+++ b/gdb/rdi-share/serpardr.c
@@ -0,0 +1,730 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * serpardv.c - Serial/Parallel Driver for Angel.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "crc.h"
+#include "devices.h"
+#include "buffers.h"
+#include "rxtx.h"
+#include "hostchan.h"
+#include "params.h"
+#include "logging.h"
+#include "hsys.h"
+
+#ifdef COMPILING_ON_WINDOWS
+# undef ERROR
+# undef IGNORE
+# include <windows.h>
+# include "angeldll.h"
+# include "comb_api.h"
+#else
+# ifdef __hpux
+# define _TERMIOS_INCLUDED
+# include <sys/termio.h>
+# undef _TERMIOS_INCLUDED
+# else
+# include <termios.h>
+# endif
+# include "unixcomm.h"
+#endif
+
+#ifndef UNUSED
+# define UNUSED(x) (x = x) /* Silence compiler warnings */
+#endif
+
+#define MAXREADSIZE 512
+#define MAXWRITESIZE 512
+
+#define SERPAR_FC_SET ((1 << serial_XON) | (1 << serial_XOFF))
+#define SERPAR_CTL_SET ((1 << serial_STX) | (1 << serial_ETX) | \
+ (1 << serial_ESC))
+#define SERPAR_ESC_SET (SERPAR_FC_SET | SERPAR_CTL_SET)
+
+static const struct re_config config = {
+ serial_STX, serial_ETX, serial_ESC, /* self-explanatory? */
+ SERPAR_FC_SET, /* set of flow-control characters */
+ SERPAR_ESC_SET, /* set of characters to be escaped */
+ NULL, /* serial_flow_control */
+ NULL, /* what to do with FC chars */
+ angel_DD_RxEng_BufferAlloc, NULL /* how to get a buffer */
+};
+
+static struct re_state rxstate;
+
+/*
+ * structure used for manipulating transmit data
+ */
+typedef struct TxState
+{
+ struct te_state state;
+ unsigned int index;
+ unsigned char writebuf[MAXWRITESIZE];
+} TxState;
+
+/*
+ * The set of parameter options supported by the device
+ */
+static unsigned int baud_options[] =
+{
+#ifdef __hpux
+ 115200, 57600,
+#endif
+ 38400, 19200, 9600
+};
+
+static ParameterList param_list[] =
+{
+ {
+ AP_BAUD_RATE,
+ sizeof(baud_options) / sizeof(unsigned int),
+ baud_options
+ }
+};
+
+static const ParameterOptions serpar_options =
+{
+ sizeof(param_list) / sizeof(ParameterList),
+ param_list
+};
+
+/*
+ * The default parameter config for the device
+ */
+static Parameter param_default[] =
+{
+ { AP_BAUD_RATE, 9600 }
+};
+
+static const ParameterConfig serpar_defaults =
+{
+ sizeof(param_default)/sizeof(Parameter),
+ param_default
+};
+
+/*
+ * The user-modified options for the device
+ */
+static unsigned int user_baud_options[sizeof(baud_options) /
+ sizeof(unsigned int)];
+
+static ParameterList param_user_list[] =
+{
+ {
+ AP_BAUD_RATE,
+ sizeof(user_baud_options) / sizeof(unsigned),
+ user_baud_options
+ }
+};
+
+static ParameterOptions user_options =
+{
+ sizeof(param_user_list) / sizeof(ParameterList),
+ param_user_list
+};
+
+static bool user_options_set;
+
+/* forward declarations */
+static int serpar_reset(void);
+static int serpar_set_params(const ParameterConfig *config);
+static int SerparMatch(const char *name, const char *arg);
+
+static void process_baud_rate(unsigned int target_baud_rate)
+{
+ const ParameterList *full_list;
+ ParameterList *user_list;
+
+ /* create subset of full options */
+ full_list = Angel_FindParamList(&serpar_options, AP_BAUD_RATE);
+ user_list = Angel_FindParamList(&user_options, AP_BAUD_RATE);
+
+ if (full_list != NULL && user_list != NULL)
+ {
+ unsigned int i, j;
+ unsigned int def_baud = 0;
+
+ /* find lower or equal to */
+ for (i = 0; i < full_list->num_options; ++i)
+ if (target_baud_rate >= full_list->option[i])
+ {
+ /* copy remaining */
+ for (j = 0; j < (full_list->num_options - i); ++j)
+ user_list->option[j] = full_list->option[i+j];
+ user_list->num_options = j;
+
+ /* check this is not the default */
+ Angel_FindParam(AP_BAUD_RATE, &serpar_defaults, &def_baud);
+ if ((j == 1) && (user_list->option[0] == def_baud))
+ {
+#ifdef DEBUG
+ printf("user selected default\n");
+#endif
+ }
+ else
+ {
+ user_options_set = TRUE;
+#ifdef DEBUG
+ printf("user options are: ");
+ for (j = 0; j < user_list->num_options; ++j)
+ printf("%u ", user_list->option[j]);
+ printf("\n");
+#endif
+ }
+
+ break; /* out of i loop */
+ }
+
+#ifdef DEBUG
+ if (i >= full_list->num_options)
+ printf("couldn't match baud rate %u\n", target_baud_rate);
+#endif
+ }
+#ifdef DEBUG
+ else
+ printf("failed to find lists\n");
+#endif
+}
+
+static int SerparOpen(const char *name, const char *arg)
+{
+ char *sername = NULL;
+ char *parname = NULL;
+
+#ifdef DEBUG
+ printf("SerparOpen: name %s arg %s\n", name, arg ? arg : "<NULL>");
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ if (IsOpenSerial() || IsOpenParallel()) return -1;
+#else
+ if (Unix_IsSerialInUse() || Unix_IsParallelInUse()) return -1;
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ if (SerparMatch(name, arg) == -1)
+ return -1;
+#else
+ Unix_IsValidParallelDevice(name,&sername,&parname);
+# ifdef DEBUG
+ printf("translated %s to serial %s and parallel %s\n",
+ name==0 ? "NULL" : name,
+ sername==0 ? "NULL" : sername,
+ parname==0 ? "NULL" : parname);
+# endif
+ if (sername==NULL || parname==NULL) return -1;
+#endif
+
+ user_options_set = FALSE;
+
+ /* interpret and store the arguments */
+ if (arg != NULL)
+ {
+ unsigned int target_baud_rate;
+
+ target_baud_rate = (unsigned int)strtoul(arg, NULL, 10);
+
+ if (target_baud_rate > 0)
+ {
+#ifdef DEBUG
+ printf("user selected baud rate %u\n", target_baud_rate);
+#endif
+ process_baud_rate(target_baud_rate);
+ }
+#ifdef DEBUG
+ else
+ printf("could not understand baud rate %s\n", arg);
+#endif
+ }
+
+#ifdef COMPILING_ON_WINDOWS
+ {
+ /*
+ * The serial port number is in name[0] followed by
+ * the parallel port number in name[1]
+ */
+
+ int sport = name[0] - '0';
+ int pport = name[1] - '0';
+
+ if (OpenParallel(pport) != COM_OK)
+ return -1;
+
+ if (OpenSerial(sport, FALSE) != COM_OK)
+ {
+ CloseParallel();
+ return -1;
+ }
+ }
+#else
+ Unix_OpenParallel(parname);
+ Unix_OpenSerial(sername);
+#endif
+
+ serpar_reset();
+
+#if defined(__unix) || defined(__CYGWIN32__)
+ Unix_ioctlNonBlocking();
+#endif
+
+ Angel_RxEngineInit(&config, &rxstate);
+
+ return 0;
+}
+
+#ifdef COMPILING_ON_WINDOWS
+static int SerparMatch(const char *name, const char *arg)
+{
+ char sername[2];
+ char parname[2];
+
+ UNUSED(arg);
+
+ sername[0] = name[0];
+ parname[0] = name[1];
+ sername[1] = parname[1] = 0;
+
+ if (IsValidDevice(sername) == COM_DEVICENOTVALID ||
+ IsValidDevice(parname) == COM_DEVICENOTVALID)
+ return -1;
+ else
+ return 0;
+}
+#else
+static int SerparMatch(const char *portstring, const char *arg)
+{
+ char *sername=NULL, *parname=NULL;
+ UNUSED(arg);
+
+ Unix_IsValidParallelDevice(portstring,&sername,&parname);
+
+ /* Match failed if either sername or parname are still NULL */
+ if (sername==NULL || parname==NULL) return -1;
+ return 0;
+}
+#endif
+
+static void SerparClose(void)
+{
+#ifdef COMPILING_ON_WINDOWS
+ CloseParallel();
+ CloseSerial();
+#else
+ Unix_CloseParallel();
+ Unix_CloseSerial();
+#endif
+}
+
+static int SerparRead(DriverCall *dc, bool block)
+{
+ static unsigned char readbuf[MAXREADSIZE];
+ static int rbindex = 0;
+
+ int nread;
+ int read_errno;
+ int c = 0;
+ re_status restatus;
+ int ret_code = -1; /* assume bad packet or error */
+
+ /*
+ * we must not overflow buffer, and must start after
+ * the existing data
+ */
+#ifdef COMPILING_ON_WINDOWS
+ {
+ BOOL dummy = FALSE;
+ nread = BytesInRXBufferSerial();
+
+ if (nread > MAXREADSIZE - rbindex)
+ nread = MAXREADSIZE - rbindex;
+ read_errno = ReadSerial(readbuf+rbindex, nread, &dummy);
+ if (pfnProgressCallback != NULL && read_errno == COM_OK)
+ {
+ progressInfo.nRead += nread;
+ (*pfnProgressCallback)(&progressInfo);
+ }
+ }
+#else
+ nread = Unix_ReadSerial(readbuf+rbindex, MAXREADSIZE-rbindex, block);
+ read_errno = errno;
+#endif
+
+ if ((nread > 0) || (rbindex > 0))
+ {
+#ifdef DO_TRACE
+ printf("[%d@%d] ", nread, rbindex);
+#endif
+
+ if (nread > 0)
+ rbindex = rbindex + nread;
+
+ do
+ {
+ restatus = Angel_RxEngine(readbuf[c], &(dc->dc_packet), &rxstate);
+
+#ifdef DO_TRACE
+ printf("<%02X ",readbuf[c]);
+#endif
+ c++;
+ } while (c < rbindex &&
+ ((restatus == RS_IN_PKT) || (restatus == RS_WAIT_PKT)));
+
+#ifdef DO_TRACE
+ printf("\n");
+#endif
+
+ switch(restatus)
+ {
+ case RS_GOOD_PKT:
+ ret_code = 1;
+ /* fall through to: */
+
+ case RS_BAD_PKT:
+ /*
+ * We now need to shuffle any left over data down to the
+ * beginning of our private buffer ready to be used
+ *for the next packet
+ */
+#ifdef DO_TRACE
+ printf("SerparRead() processed %d, moving down %d\n",
+ c, rbindex - c);
+#endif
+
+ if (c != rbindex)
+ memmove((char *) readbuf, (char *) (readbuf + c), rbindex - c);
+
+ rbindex -= c;
+
+ break;
+
+ case RS_IN_PKT:
+ case RS_WAIT_PKT:
+ rbindex = 0; /* will have processed all we had */
+ ret_code = 0;
+ break;
+
+ default:
+#ifdef DEBUG
+ printf("Bad re_status in SerparRead()\n");
+#endif
+ break;
+ }
+ }
+ else if (nread == 0)
+ /* nothing to read */
+ ret_code = 0;
+ else if (read_errno == ERRNO_FOR_BLOCKED_IO) /* nread < 0 */
+ ret_code = 0;
+
+#ifdef DEBUG
+ if ((nread < 0) && (read_errno != ERRNO_FOR_BLOCKED_IO))
+ perror("read() error in SerparRead()");
+#endif
+
+ return ret_code;
+}
+
+/*
+ * Function: send_packet
+ * Purpose: Send a stream of bytes to Angel through the parallel port
+ *
+ * Algorithm: We need to present the data in a form that all boards can
+ * swallow. With the PID board, this is a problem: for reasons
+ * described in the driver (angel/pid/st16c552.c), data are
+ * sent a nybble at a time on D0-D2 and D4; D3 is wired to ACK,
+ * which generates an interrupt when it goes low. This routine
+ * fills in an array of nybbles, with ACK clear in all but the
+ * last one. If, for whatever reason, the write fails, then
+ * ACK is forced high (thereby enabling the next write a chance
+ * to be noticed when the falling edge of ACK generates an
+ * interrupt (hopefully).
+ *
+ * Params:
+ * Input: txstate Contains the packet to be sent
+ *
+ * Returns: Number of *complete* bytes written
+ */
+
+static int SerparWrite(DriverCall *dc)
+{
+ te_status status;
+ int nwritten = 0;
+ static TxState txstate;
+
+ /*
+ * is this a new packet?
+ */
+ if (dc->dc_context == NULL)
+ {
+ /*
+ * yes - initialise TxEngine
+ */
+ Angel_TxEngineInit(&config, &dc->dc_packet, &txstate.state);
+
+ txstate.index = 0;
+ dc->dc_context = &txstate;
+ }
+
+ /*
+ * fill the buffer using the Tx Engine
+ */
+ do
+ {
+ status = Angel_TxEngine(&dc->dc_packet, &txstate.state,
+ &txstate.writebuf[txstate.index]);
+ if (status != TS_IDLE) txstate.index++;
+
+ } while (status == TS_IN_PKT && txstate.index < MAXWRITESIZE);
+
+#ifdef DO_TRACE
+ {
+ unsigned int i = 0;
+
+ while (i < txstate.index)
+ {
+ printf(">%02X ", txstate.writebuf[i]);
+
+ if (!(++i % 16))
+ putc('\n', stdout);
+ }
+
+ if (i % 16)
+ putc('\n', stdout);
+ }
+#endif
+
+ /*
+ * the data are ready, all we need now is to send them out
+ * in a form that Angel can swallow.
+ */
+#ifdef COMPILING_ON_WINDOWS
+ if (WriteParallel(txstate.writebuf, txstate.index) == COM_OK)
+ {
+ nwritten = txstate.index;
+ if (pfnProgressCallback != NULL)
+ {
+ progressInfo.nWritten += nwritten;
+ (*pfnProgressCallback)(&progressInfo);
+ }
+ }
+ else
+ {
+ MessageBox(GetFocus(), "Write error\n", "Angel", MB_OK | MB_ICONSTOP);
+ return -1; /* SJ - This really needs to return a value, which is picked up in */
+ /* DevSW_Read as meaning stop debugger but don't kill. */
+ }
+#else
+ nwritten = Unix_WriteParallel(txstate.writebuf, txstate.index);
+#endif
+
+ if (nwritten < 0) nwritten = 0;
+
+#ifdef DO_TRACE
+ printf("SerparWrite: wrote %d out of %d bytes\n",
+ nwritten, txstate.index);
+#endif
+
+ /*
+ * has the whole packet gone?
+ */
+ if (nwritten == (int)txstate.index &&
+ (status == TS_DONE_PKT || status == TS_IDLE))
+ /*
+ * yes it has
+ */
+ return 1;
+ else
+ {
+ /*
+ * if some data are left, shuffle them
+ * to the start of the buffer
+ */
+ if (nwritten != (int)txstate.index && nwritten != 0)
+ {
+ txstate.index -= nwritten;
+ (void)memmove((char *) txstate.writebuf,
+ (char *) (txstate.writebuf + nwritten),
+ txstate.index);
+ }
+ else if (nwritten == (int)txstate.index)
+ txstate.index = 0;
+
+ return 0;
+ }
+}
+
+static int serpar_reset(void)
+{
+#ifdef COMPILING_ON_WINDOWS
+ FlushParallel();
+ FlushSerial();
+#else
+ Unix_ResetParallel();
+ Unix_ResetSerial();
+#endif
+
+ return serpar_set_params(&serpar_defaults);
+}
+
+static int find_baud_rate(unsigned int *speed)
+{
+ static struct
+ {
+ unsigned int baud;
+ int termiosValue;
+ } possibleBaudRates[] =
+ {
+#if defined(__hpux)
+ {115200, _B115200}, {57600, _B57600},
+#endif
+#ifdef COMPILING_ON_WINDOWS
+ {38400, CBR_38400}, {19200, CBR_19200}, {9600, CBR_9600}, {0, 0}
+#else
+ {38400, B38400}, {19200, B19200}, {9600, B9600}, {0, 0}
+#endif
+ };
+ unsigned int i;
+
+ /* look for lower or matching -- will always terminate at 0 end marker */
+ for (i = 0; possibleBaudRates[i].baud > *speed; ++i)
+ /* do nothing */
+ ;
+
+ if (possibleBaudRates[i].baud > 0)
+ *speed = possibleBaudRates[i].baud;
+
+ return possibleBaudRates[i].termiosValue;
+}
+
+static int serpar_set_params(const ParameterConfig *config)
+{
+ unsigned int speed;
+ int termios_value;
+
+#ifdef DEBUG
+ printf("serpar_set_params\n");
+#endif
+
+ if (!Angel_FindParam(AP_BAUD_RATE, config, &speed))
+ {
+#ifdef DEBUG
+ printf("speed not found in config\n");
+#endif
+ return DE_OKAY;
+ }
+
+ termios_value = find_baud_rate(&speed);
+ if (termios_value == 0)
+ {
+#ifdef DEBUG
+ printf("speed not valid: %u\n", speed);
+#endif
+ return DE_OKAY;
+ }
+
+#ifdef DEBUG
+ printf("setting speed to %u\n", speed);
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ SetBaudRate((WORD)termios_value);
+#else
+ Unix_SetSerialBaudRate(termios_value);
+#endif
+
+ return DE_OKAY;
+}
+
+
+static int serpar_get_user_params(ParameterOptions **p_options)
+{
+#ifdef DEBUG
+ printf("serpar_get_user_params\n");
+#endif
+
+ if (user_options_set)
+ {
+ *p_options = &user_options;
+ }
+ else
+ {
+ *p_options = NULL;
+ }
+
+ return DE_OKAY;
+}
+
+
+static int serial_get_default_params( const ParameterConfig **p_config )
+{
+#ifdef DEBUG
+ printf( "serial_get_default_params\n" );
+#endif
+
+ *p_config = &serpar_defaults;
+ return DE_OKAY;
+}
+
+
+static int SerparIoctl(const int opcode, void *args)
+{
+ int ret_code;
+
+#ifdef DEBUG
+ printf("SerparIoctl: op %d arg %p\n", opcode, args ? args : "<NULL>");
+#endif
+
+ switch (opcode)
+ {
+ case DC_RESET:
+ ret_code = serpar_reset();
+ break;
+
+ case DC_SET_PARAMS:
+ ret_code = serpar_set_params((const ParameterConfig *)args);
+ break;
+
+ case DC_GET_USER_PARAMS:
+ ret_code = serpar_get_user_params((ParameterOptions **)args);
+ break;
+
+ case DC_GET_DEFAULT_PARAMS:
+ ret_code =
+ serial_get_default_params((const ParameterConfig **)args);
+ break;
+
+ default:
+ ret_code = DE_BAD_OP;
+ break;
+ }
+
+ return ret_code;
+}
+
+DeviceDescr angel_SerparDevice =
+{
+ "SERPAR",
+ SerparOpen,
+ SerparMatch,
+ SerparClose,
+ SerparRead,
+ SerparWrite,
+ SerparIoctl
+};
+
+/* EOF serpardr.c */
diff --git a/gdb/rdi-share/sys.h b/gdb/rdi-share/sys.h
new file mode 100644
index 00000000000..b68ac785cd6
--- /dev/null
+++ b/gdb/rdi-share/sys.h
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* sys.h
+ ***********************************************************************
+ * Angel C Libary support channel protocol definitions
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ *
+ *
+ * MESSAGE FORMAT
+ * --------------
+ * Format of the "data" section of C Lib Support Channel Messages.
+ * You will notice that the format is much the same as the format
+ * of ADP messages - this is so that multi-threaded C Libraries can
+ * be supported.
+ *
+ * unsigned32 reason - Main C Library reason code.
+ * unsigned32 debugID - Info. describing host debug world;
+ * private to host and used in any target
+ * initiated messages.
+ * unsigned32 OSinfo1 \ Target OS information to identify process/thread
+ * unsigned32 OSinfo2 / world, etc. These two fields are target defined.
+ * byte args[n] - Data for message "reason" code.
+ *
+ * The "debugID" is defined by the host-end of the protocol, and is used
+ * by the host to ensure that messages are routed to the correct handler
+ * program/veneer (eg. imagine several threads having opened stdout and
+ * each writing to a different window in a windowed debugger).
+ *
+ * NOTE: The reason that there is no "size" information, is that the
+ * message IDs themselves encode the format of any arguments.
+ *
+ * For further discussion of the format see adp.h
+ *
+ * N.B. All streams are little endian.
+ *
+ * CLIB REASON CODE
+ * ----------------
+ * The message reason codes contain some information that ties them to
+ * the channel and direction that the message will be used with. This
+ * will ensure that even if the message "#define name" is not
+ * completely descriptive, the message reason code is.
+ *
+ * b31 = direction. 0=Host-to-Target; 1=Target-to-Host;
+ * b30-16 = reserved. should be zero
+ * b15-0 = message reason code.
+ *
+ * Note that typically a request will be initiated by the target side, and
+ * that the host will then respond with either an acknowledgement or some
+ * data. In either case the same reason code will be used, but the direction
+ * bit will be reveresed.
+ */
+
+#ifndef __sys_h
+#define __sys_h
+
+#ifndef HtoT
+#define HtoT ((unsigned)0 << 31) /* Host-to-Target message */
+#define TtoH ((unsigned)1 << 31) /* Target-to-Host message */
+#endif
+
+/*
+ * The following are error codes used in the status field returned on
+ * sending a message. 0 represents no error having occurred, non-zero
+ * represents a general error. More codes should be added as required.
+ */
+
+#ifndef ErrCode
+#define NoError 0x0
+#endif
+
+/*************************************************************************/
+/* The following are direct conversions of the DeMon SWI's */
+/* NB: nbytes is the number of bytes INCLUDING THE NULL character where */
+/* applicable. */
+
+/* This message is used as a response to a packet whose message
+ * was not understood. The return parameter, code is the reason
+ * code which was not understood. Although intended for use as a
+ * default case on a received message switch it can also be used
+ * as a proper message*/
+#define CL_Unrecognised 0x00
+ /* Unrecognised()
+ * return(word code)
+ */
+
+/* Write a character to the terminal.
+ */
+#define CL_WriteC 0x01
+ /* WriteC(byte data)
+ * return(word status)
+ */
+
+/* Write a NULL terminated string of characters to the terminal. The length
+ * of the string excluding the NULL terminating character is passed in
+ * 'nbytes'.
+ */
+#define CL_Write0 0x02
+ /* Write0(word nbytes, bytes data)
+ * return(word status)
+ */
+
+/* Read a character from the terminal - probably the keyboard.
+ */
+#define CL_ReadC 0x04
+ /* ReadC(void)
+ * return(word status, byte data)
+ */
+
+/* Perform system call, pass NULL terminated string to host's command
+ * line interpreter(NOT AVAILABLE IN PC/DOS RELEASE). The data byte
+ * returned holds the return code from the system call.
+ */
+#define CL_System 0x05
+ /* CLI(word nbytes, bytes data)
+ * return(word status, word data)
+ */
+
+/* It returns the address of the null terminated command line string used to
+ * invoke the program. status will be set to NoError if the command line
+ * can be returned. Other status values will be treated as error conditions.
+ */
+#define CL_GetCmdLine 0x10
+ /* GetCmdLine(void)
+ * return(word status, word nbytes, bytes argline)
+ */
+
+/* Return the number of centi-seconds since the support code began
+ * execution. Only the difference between successive calls can be
+ * meaningful.
+ */
+#define CL_Clock 0x61
+ /* Clock(void)
+ * return(word status, word clks)
+ */
+
+/* Return the number of seconds since the beginning of 1970.
+ */
+#define CL_Time 0x63
+ /* Time(void)
+ * return(word status, word time)
+ */
+
+/* Delete(remove, un-link, wipe, destroy) the file named by the
+ * NULL-terminated string 'name'.
+ */
+#define CL_Remove 0x64
+ /* Remove(word nbytes, bytes name)
+ * return(word status)
+ */
+
+/* Rename the file specified by the NULL-terminated string 'oname'
+ * to 'nname'.
+ */
+#define CL_Rename 0x65
+ /* Rename(word nbytes, bytes oname, word nbytes, bytes nname)
+ * return(word status)
+ */
+
+/* 'name' specifies a NULL-terminated string containing a file name or a
+ * device name. Opens the file/device and returns a non-zero handle on
+ * success that can be quoted to CL_Close, CL_Read, CL_Write, CL_Seek,
+ * CL_Flen or CL_IsTTY. The mode is an integer in the range 0-11:-
+ *
+ * Mode: 0 1 2 3 4 5 6 7 8 9 10 11
+ * ANSI C fopen mode: r rb r+ r+b w wb w+ w+b a ab a+ a+b
+ *
+ * Values 12-15 are illegal. If 'name' is ":tt" the stdin/stdout is
+ * opened depending on whether 'mode' is read or write.
+ */
+#define CL_Open 0x66
+ /* Open(word nbytes, bytes name, word mode)
+ * return(word handle)
+ */
+
+/* 'handle' is a file handle previously returned by CL_Open. CL_Close
+ * closes the file.
+ */
+#define CL_Close 0x68
+ /* Close(word handle)
+ * return(word status)
+ */
+
+/* Writes data of length nbytes to the file/device specified by
+ * handle. nbtotal represents the total number of bytes to be
+ * written, whereas nbytes is the number of bytes in this packet
+ *
+ * If nbtotal is <= DATASIZE - CL_Write message header size in the
+ * packet then nbytes = nbtotal and the number of bytes not written
+ * is returned. If nbtotal is > the packet size then the CL_Write
+ * must be followed by a number of CL_WriteX's to complete the write,
+ * the nbytes returned by CL_Write can be ignored
+ * If the status word returned is non zero, an error has occurred and
+ * the write request has been aborted.
+ *
+ */
+#define CL_Write 0x69
+ /* Write(word handle, word nbtotal, word nbytes, bytes data)
+ * return(word status, word nbytes)
+ */
+
+/* Write Extension is a reads a continuation of data from a CL_Write
+ * which was too big to fit in a single packet.
+ * nbytes is the number of bytes of data in this packet, the
+ * returned value of nbytes can be ignored except if it is the
+ * last packet, in which case it is the number of bytes that were NOT
+ * written
+ */
+#define CL_WriteX 0x6A
+ /* WriteX(word nbytes, bytes data)
+ * return(word status, word nbytes)
+ */
+
+/* Reads 'nbytes' from the file/device specified by 'handle'.
+ *
+ * If nbytes <= DATASIZE then the read will occur in a single packet
+ * and the returned value of nbytes will be the number of bytes actually
+ * read and nbmore will be 0. If nbytes> DATASIZE then multiple packets
+ * will have to be used ie CL_Read followed by 1 or more CL_ReadX
+ * packets. In this case CL_Read will return nbytes read in the current
+ * packet and nbmore representing how many more bytes are expected to be
+ * read
+ * If the status word is non zero then the request has completed with an
+ * error. If the status word is 0xFFFFFFFF (-1) then an EOF condition
+ * has been reached.
+ */
+#define CL_Read 0x6B
+ /* Read(word handle, word nbytes)
+ * return(word status, word nbytes, word nbmore, bytes data)
+ */
+
+/* Read eXtension returns a continuation of the data that was opened for
+ * read in the earlier CL_Read. The return value nbytes is the number of
+ * data bytes in the packet, nbmore is the number of bytes more that are
+ * expected to be read in subsequent packets.
+ */
+#define CL_ReadX 0x6C
+ /* ReadX()
+ * return(word status, word nbytes, word nbmore, bytes data)
+ */
+
+/* Seeks to byte position 'posn' in the file/device specified by 'handle'.
+ */
+#define CL_Seek 0x6D
+ /* Seek(word handle, word posn)
+ * return(word status)
+ */
+
+/* Returns the current length of the file specified by 'handle' in 'len'.
+ * If an error occurs 'len' is set to -1.
+ */
+#define CL_Flen 0x6E
+ /* Flen(word handle)
+ * return(word len)
+ */
+
+/* Returns NoError if 'handle' specifies an interactive device, otherwise
+ * returns GenError
+ */
+#define CL_IsTTY 0x6F
+ /* IsTTY(word handle)
+ * return(word status)
+ */
+
+/* Returns a temporary host file name. The maximum length of a file name
+ * is passed to the host. The TargetID is some identifier from the target
+ * for this particular temporary filename. This value is could be used
+ * directly in the generation of the filename.
+ *
+ * If the host cannot create a suitable name or the generated name is too
+ * long then status is non zero. status will be NoError if the host can create
+ * a name.
+ */
+#define CL_TmpNam 0x70
+ /* TmpNam(word maxlength, word TargetID)
+ * return(word status, word nbytes, bytes fname)
+ */
+
+/* Note there is no message for Exit, EnterOS, InstallHandler or
+ * GenerateError as these will be supported entirely at the host end,
+ * or by the underlying Operating system.
+ */
+
+#define CL_UnknownReason (-1)
+
+extern unsigned int GetRaiseHandler( void );
+extern unsigned int SysLibraryHandler(unsigned int sysCode, unsigned int *args);
+extern void angel_SysLibraryInit(void);
+
+/*
+ * Function: Angel_IsSysHandlerRunning
+ * Purpose: return whether or not SysLibraryHandler is running
+ *
+ * No paramaters
+ *
+ * Returns 1 if SysLibraryHandler is running
+ * 0 otherwise
+ */
+extern int Angel_IsSysHandlerRunning(void);
+
+#ifdef ICEMAN2
+/* This function exists in an ICEman2 system only, and can be called by
+ * debug support code when the debugger tells it how much memory the
+ * target has. This will then be used to deal with the HEAPINFO SWI
+ */
+extern void angel_SetTopMem(unsigned addr);
+#endif
+
+#endif
+
diff --git a/gdb/rdi-share/tx.c b/gdb/rdi-share/tx.c
new file mode 100644
index 00000000000..7d8d154e484
--- /dev/null
+++ b/gdb/rdi-share/tx.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*-*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ * Project: ANGEL
+ *
+ * Title: Character based packet transmission engine
+ */
+
+#include <stdarg.h> /* ANSI varargs support */
+#include "angel.h" /* Angel system definitions */
+#include "angel_endian.h" /* Endian independant memory access macros */
+#include "crc.h" /* crc generation definitions and headers */
+#include "rxtx.h"
+#include "channels.h"
+#include "buffers.h"
+#include "logging.h"
+
+/* definitions to describe the engines state */
+#define N_STX 0x0 /* first 2 bits for N_ */
+#define N_BODY 0x1
+#define N_ETX 0x2
+#define N_IDLE 0x3
+#define N_MASK 0x3 /* mask for the Encapsulator state */
+
+#define E_PLAIN (0x0 << 2) /* 3rd bit for E_ */
+#define E_ESC (0x1 << 2) /* 3rd bit for E_ */
+#define E_MASK (0x1 << 2) /* mask for the Escaper state */
+
+#define F_HEAD (0x0 << 3) /* 4th and 5th bits for F_ */
+#define F_DATA (0x1 << 3)
+#define F_CRC (0x1 << 4)
+#define F_MASK (0x3 << 3) /* mask for the Escaper state */
+
+static unsigned char escape(unsigned char ch_in, struct te_state *txstate);
+
+void Angel_TxEngineInit(const struct re_config *txconfig,
+ const struct data_packet *packet,
+ struct te_state *txstate){
+ IGNORE(packet);
+ txstate->tx_state = N_STX | E_PLAIN | F_HEAD;
+ txstate->field_c = 0;
+ txstate->encoded = 0;
+ txstate->config = txconfig;
+ txstate->crc = 0;
+}
+
+te_status Angel_TxEngine(const struct data_packet *packet,
+ struct te_state *txstate,
+ unsigned char *tx_ch){
+ /* TODO: gaurd on long/bad packets */
+ /*
+ * encapsulate the packet, framing has been moved from a seperate
+ * function into the encapsulation routine as it needed too much
+ * inherited state for it to be sensibly located elsewhere
+ */
+ switch ((txstate->tx_state) & N_MASK){
+ case N_STX:
+#ifdef DO_TRACE
+ __rt_trace("txe-stx ");
+#endif
+ txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_BODY;
+ *tx_ch = txstate->config->stx;
+ txstate->field_c = 3; /* set up for the header */
+ txstate->crc = startCRC32; /* set up basic crc */
+ return TS_IN_PKT;
+ case N_BODY:{
+ switch (txstate->tx_state & F_MASK) {
+ case F_HEAD:
+#ifdef DO_TRACE
+ __rt_trace("txe-head ");
+#endif
+ if (txstate->field_c == 3) {
+ /* send type */
+ *tx_ch = escape(packet->type, txstate);
+ return TS_IN_PKT;
+ }
+ else {
+ *tx_ch = escape((packet->len >> (txstate->field_c - 1) * 8) & 0xff,
+ txstate);
+ if (txstate->field_c == 0) {
+ /* move on to the next state */
+ txstate->tx_state = (txstate->tx_state & ~F_MASK) | F_DATA;
+ txstate->field_c = packet->len;
+ }
+ return TS_IN_PKT;
+ }
+ case F_DATA:
+#ifdef DO_TRACE
+ __rt_trace("txe-data ");
+#endif
+ *tx_ch = escape(packet->data[packet->len - txstate->field_c], txstate);
+ if (txstate->field_c == 0) {
+ /* move on to the next state */
+ txstate->tx_state = (txstate->tx_state & ~F_MASK) | F_CRC;
+ txstate->field_c = 4;
+ }
+ return TS_IN_PKT;
+ case F_CRC:
+#ifdef DO_TRACE
+ __rt_trace("txe-crc ");
+#endif
+ *tx_ch = escape((txstate->crc >> ((txstate->field_c - 1) * 8)) & 0xff,
+ txstate);
+
+ if (txstate->field_c == 0) {
+#ifdef DO_TRACE
+ __rt_trace("txe crc = 0x%x\n", txstate->crc);
+#endif
+ /* move on to the next state */
+ txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_ETX;
+ }
+ return TS_IN_PKT;
+ }
+ }
+ case N_ETX:
+#ifdef DO_TRACE
+ __rt_trace("txe-etx\n");
+#endif
+ txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_IDLE;
+ *tx_ch = txstate->config->etx;
+ return TS_DONE_PKT;
+ default:
+#ifdef DEBUG
+ __rt_info("tx default\n");
+#endif
+ txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_IDLE;
+ return TS_IDLE;
+ }
+ /* stop a silly -Wall warning */
+ return (te_status)-1;
+}
+
+/*
+ * crc generation occurs in the escape function because it is the only
+ * place where we know that we're putting a real char into the buffer
+ * rather than an escaped one.
+ * We must be careful here not to update the crc when we're sending it
+ */
+static unsigned char escape(unsigned char ch_in, struct te_state *txstate) {
+ if (((txstate->tx_state) & E_MASK) == E_ESC) {
+ /* char has been escaped so send the real char */
+#ifdef DO_TRACE
+ __rt_trace("txe-echar ");
+#endif
+ txstate->tx_state = (txstate->tx_state & ~E_MASK) | E_PLAIN;
+ txstate->field_c--;
+ if ((txstate->tx_state & F_MASK) != F_CRC)
+ txstate->crc = crc32( &ch_in, 1, txstate->crc);
+ return ch_in | serial_ESCAPE;
+ }
+ if ((ch_in < 32) && ((txstate->config->esc_set & (1 << ch_in)) != 0)) {
+ /* char needs escaping */
+#ifdef DO_TRACE
+ __rt_trace("txe-esc ");
+#endif
+ txstate->tx_state = (txstate->tx_state & ~E_MASK) | E_ESC;
+ return txstate->config->esc;
+ }
+ /* must be a char that can be sent plain */
+ txstate->field_c--;
+ if ((txstate->tx_state & F_MASK) != F_CRC)
+ txstate->crc = crc32(&ch_in, 1, txstate->crc);
+ return ch_in;
+}
+
+/* EOF tx.c */
diff --git a/gdb/rdi-share/unixcomm.c b/gdb/rdi-share/unixcomm.c
new file mode 100644
index 00000000000..0abd4115a29
--- /dev/null
+++ b/gdb/rdi-share/unixcomm.c
@@ -0,0 +1,563 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ */
+
+#ifdef __hpux
+# define _POSIX_SOURCE 1
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#ifdef __hpux
+# define _TERMIOS_INCLUDED
+# include <sys/termio.h>
+# undef _TERMIOS_INCLUDED
+#else
+# include <termios.h>
+#endif
+
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (bsdi)
+#undef BSD
+#include <sys/ioctl.h>
+#endif
+
+#ifdef sun
+# include <sys/ioccom.h>
+# ifdef __svr4__
+# include <sys/bpp_io.h>
+# else
+# include <sbusdev/bpp_io.h>
+# endif
+#endif
+
+#ifdef BSD
+# ifdef sun
+# include <sys/ttydev.h>
+# endif
+# ifdef __alpha
+# include <sys/ioctl.h>
+# else
+# include <sys/filio.h>
+# endif
+#endif
+
+#ifdef __hpux
+# define _INCLUDE_HPUX_SOURCE
+# include <sys/ioctl.h>
+# undef _INCLUDE_HPUX_SOURCE
+#endif
+
+#include "host.h"
+#include "unixcomm.h"
+
+#define PP_TIMEOUT 1 /* seconds */
+
+#ifdef sun
+#define SERIAL_PREFIX "/dev/tty"
+#define SERPORT1 "/dev/ttya"
+#define SERPORT2 "/dev/ttyb"
+#define PARPORT1 "/dev/bpp0"
+#define PARPORT2 "/dev/bpp1"
+#endif
+
+#ifdef __hpux
+#define SERIAL_PREFIX "/dev/tty"
+#define SERPORT1 "/dev/tty00"
+#define SERPORT2 "/dev/tty01"
+#define PARPORT1 "/dev/ptr_parallel"
+#define PARPORT2 "/dev/ptr_parallel"
+#endif
+
+#ifdef __linux__
+#define SERIAL_PREFIX "/dev/ttyS"
+#define SERPORT1 "/dev/ttyS0"
+#define SERPORT2 "/dev/ttyS1"
+#define PARPORT1 "/dev/par0"
+#define PARPORT2 "/dev/par1"
+#endif
+
+#if defined(_WIN32) || defined (__CYGWIN32__)
+#define SERIAL_PREFIX "com"
+#define SERPORT1 "com1"
+#define SERPORT2 "com2"
+#define PARPORT1 "lpt1"
+#define PARPORT2 "lpt2"
+#endif
+
+#if !defined (SERIAL_PREFIX)
+#define SERIAL_PREFIX "/dev/cuaa"
+#define SERPORT1 "/dev/cuaa0"
+#define SERPORT2 "/dev/cuaa1"
+#define PARPORT1 "/dev/lpt0"
+#define PARPORT2 "/dev/lpt1"
+#endif
+
+
+
+
+/*
+ * Parallel port output pins, used for signalling to target
+ */
+
+#ifdef sun
+struct bpp_pins bp;
+#endif
+
+static int serpfd = -1;
+static int parpfd = -1;
+
+extern const char *Unix_MatchValidSerialDevice(const char *name)
+{
+ int i=0;
+ char *sername=NULL;
+
+ /* Accept no name as the default serial port */
+ if (name == NULL) {
+ return SERPORT1;
+ }
+
+ /* Look for the simple cases - 1,2,s,S,/dev/... first, and
+ * afterwards look for S=... clauses, which need parsing properly.
+ */
+
+ /* Accept /dev/tty* where * is limited */
+ if (strlen(name) == strlen(SERPORT1)
+ && strncmp(name, SERIAL_PREFIX, strlen (SERIAL_PREFIX)) == 0)
+ {
+ return name;
+ }
+
+ /* Accept "1" or "2" or "S" - S is equivalent to "1" */
+ if (strcmp(name, "1") == 0 ||
+ strcmp(name, "S") == 0 || strcmp(name, "s") == 0) {
+ return SERPORT1;
+ }
+ if (strcmp(name, "2") == 0) return SERPORT2;
+
+ /* It wasn't one of the simple cases, so now we have to parse it
+ * properly
+ */
+
+ do {
+ switch (name[i]) {
+ case ',':
+ /* Skip over commas */
+ i++;
+ break;
+
+ default:
+ return 0;
+ /* Unexpected character => error - not matched */
+
+ case 0:
+ /* End of string means return whatever we have matched */
+ return sername;
+
+ case 's':
+ case 'S':
+ case 'h':
+ case 'H': {
+ char ch = tolower(name[i]);
+ int j, continue_from, len;
+
+ /* If the next character is a comma or a NULL then this is
+ * a request for the default Serial port
+ */
+ if (name[++i] == 0 || name[i] == ',') {
+ if (ch=='s')
+ sername=SERPORT1;
+ break;
+ }
+
+ /* Next character must be an = */
+ if (name[i] != '=') return 0;
+ /* Search for the end of the port spec. (ends in NULL or ,) */
+ for (j= ++i; name[j] != 0 && name[j] != ','; j++)
+ ; /* Do nothing */
+ /* Notice whether this is the last thing to parse or not
+ * and also calaculate the length of the string
+ */
+ if (name[j] == '0') continue_from = -1;
+ else continue_from = j;
+ len=(j-i);
+
+ /* And now try to match the serial / parallel port */
+ switch (ch) {
+ case 's': {
+ /* Match serial port */
+ if (len==1) {
+ if (name[i]=='1')
+ sername=SERPORT1;
+ else if (name[i]=='2')
+ sername=SERPORT2;
+ } else if (len==strlen(SERPORT1)) {
+ if (strncmp(name+i,SERPORT1,strlen(SERPORT1)) == 0)
+ sername=SERPORT1;
+ else if (strncmp(name+i,SERPORT2,strlen(SERPORT2)) == 0)
+ sername=SERPORT2;
+ }
+
+ break;
+ }
+
+ case 'h':
+ /* We don't actually deal with the H case here, we just
+ * match it and allow it through.
+ */
+ break;
+ }
+
+ if (continue_from == -1) return sername;
+ i = continue_from;
+ break;
+ }
+ }
+ } while (1);
+
+ return 0;
+}
+
+
+extern int Unix_IsSerialInUse(void)
+{
+ if (serpfd >= 0)
+ return -1;
+
+ return 0;
+}
+
+extern int Unix_OpenSerial(const char *name)
+{
+#if defined(BSD) || defined(__CYGWIN32__)
+ serpfd = open(name, O_RDWR);
+#else
+ serpfd = open(name, O_RDWR | O_NONBLOCK);
+#endif
+
+ if (serpfd < 0) {
+ perror("open");
+ return -1;
+ }
+#ifdef TIOCEXCL
+ if (ioctl(serpfd, TIOCEXCL) < 0) {
+ close(serpfd);
+ perror("ioctl: TIOCEXCL");
+ return -1;
+ }
+#endif
+
+ return 0;
+}
+
+extern void Unix_CloseSerial(void)
+{
+ if (serpfd >= 0)
+ {
+ (void)close(serpfd);
+ serpfd = -1;
+ }
+}
+
+extern int Unix_ReadSerial(unsigned char *buf, int n, bool block)
+{
+ fd_set fdset;
+ struct timeval tv;
+ int err;
+
+ FD_ZERO(&fdset);
+ FD_SET(serpfd, &fdset);
+
+ tv.tv_sec = 0;
+ tv.tv_usec = (block ? 10000 : 0);
+
+ err = select(serpfd + 1, &fdset, NULL, NULL, &tv);
+
+ if (err < 0 && errno != EINTR)
+ {
+#ifdef DEBUG
+ perror("select");
+#endif
+ panic("select failure");
+ return -1;
+ }
+ else if (err > 0 && FD_ISSET(serpfd, &fdset))
+ {
+ int s;
+
+ s = read(serpfd, buf, n);
+ if (s < 0)
+ perror("read:");
+ return s;
+ }
+ else /* err == 0 || FD_CLR(serpfd, &fdset) */
+ {
+ errno = ERRNO_FOR_BLOCKED_IO;
+ return -1;
+ }
+}
+
+extern int Unix_WriteSerial(unsigned char *buf, int n)
+{
+ return write(serpfd, buf, n);
+}
+
+extern void Unix_ResetSerial(void)
+{
+ struct termios terminfo;
+
+ tcgetattr(serpfd, &terminfo);
+ terminfo.c_lflag &= ~(ICANON | ISIG | ECHO | IEXTEN);
+ terminfo.c_iflag &= ~(IGNCR | INPCK | ISTRIP | ICRNL | BRKINT);
+ terminfo.c_iflag |= (IXON | IXOFF | IGNBRK);
+ terminfo.c_cflag = (terminfo.c_cflag & ~CSIZE) | CS8 | CREAD;
+ terminfo.c_cflag &= ~PARENB;
+ terminfo.c_cc[VMIN] = 1;
+ terminfo.c_cc[VTIME] = 0;
+ terminfo.c_oflag &= ~OPOST;
+ tcsetattr(serpfd, TCSAFLUSH, &terminfo);
+}
+
+extern void Unix_SetSerialBaudRate(int baudrate)
+{
+ struct termios terminfo;
+
+ tcgetattr(serpfd, &terminfo);
+ cfsetospeed(&terminfo, baudrate);
+ cfsetispeed(&terminfo, baudrate);
+ tcsetattr(serpfd, TCSAFLUSH, &terminfo);
+}
+
+extern void Unix_ioctlNonBlocking(void)
+{
+#if defined(BSD)
+ int nonblockingIO = 1;
+ (void)ioctl(serpfd, FIONBIO, &nonblockingIO);
+
+ if (parpfd != -1)
+ (void)ioctl(parpfd, FIONBIO, &nonblockingIO);
+#endif
+}
+
+extern void Unix_IsValidParallelDevice(
+ const char *portstring, char **sername, char **parname)
+{
+ int i=0;
+ *sername=NULL;
+ *parname=NULL;
+
+ /* Do not recognise a NULL portstring */
+ if (portstring==NULL) return;
+
+ do {
+ switch (portstring[i]) {
+ case ',':
+ /* Skip over commas */
+ i++;
+ break;
+
+ default:
+ case 0:
+ /* End of string or bad characcter means we have finished */
+ return;
+
+ case 's':
+ case 'S':
+ case 'p':
+ case 'P':
+ case 'h':
+ case 'H': {
+ char ch = tolower(portstring[i]);
+ int j, continue_from, len;
+
+ /* If the next character is a comma or a NULL then this is
+ * a request for the default Serial or Parallel port
+ */
+ if (portstring[++i] == 0 || portstring[i] == ',') {
+ if (ch=='s') *sername=SERPORT1;
+ else if (ch=='p') *parname=PARPORT1;
+ break;
+ }
+
+ /* Next character must be an = */
+ if (portstring[i] != '=') return;
+ /* Search for the end of the port spec. (ends in NULL or ,) */
+ for (j= ++i; portstring[j] != 0 && portstring[j] != ','; j++)
+ ; /* Do nothing */
+ /* Notice whether this is the last thing to parse or not
+ * and also calaculate the length of the string
+ */
+ if (portstring[j] == '0') continue_from = -1;
+ else continue_from = j;
+ len=(j-i);
+
+ /* And now try to match the serial / parallel port */
+ switch (ch) {
+ case 's': {
+ /* Match serial port */
+ if (len==1) {
+ if (portstring[i]=='1') *sername=SERPORT1;
+ else if (portstring[i]=='2') *sername=SERPORT2;
+ } else if (len==strlen(SERPORT1)) {
+ if (strncmp(portstring+i,SERPORT1,strlen(SERPORT1)) == 0)
+ *sername=SERPORT1;
+ else if (strncmp(portstring+i,SERPORT2,strlen(SERPORT2)) == 0)
+ *sername=SERPORT2;
+ }
+ break;
+ }
+
+ case 'p': {
+ /* Match parallel port */
+ if (len==1) {
+ if (portstring[i]=='1') *parname=PARPORT1;
+ else if (portstring[i]=='2') *parname=PARPORT2;
+ } else if (len==strlen(PARPORT1)) {
+ if (strncmp(portstring+i,PARPORT1,strlen(PARPORT1)) == 0)
+ *parname=PARPORT1;
+ else if (strncmp(portstring+i,PARPORT2,strlen(PARPORT2)) == 0)
+ *parname=PARPORT2;
+ }
+ break;
+ }
+
+ case 'h':
+ /* We don't actually deal with the H case here, we just
+ * match it and allow it through.
+ */
+ break;
+ }
+
+ if (continue_from == -1) return;
+ i = continue_from;
+ break;
+ }
+ }
+ } while (1);
+ return; /* Will never get here */
+}
+
+extern int Unix_IsParallelInUse(void)
+{
+ if (parpfd >= 0)
+ return -1;
+
+ return 0;
+}
+
+extern int Unix_OpenParallel(const char *name)
+{
+#if defined(BSD)
+ parpfd = open(name, O_RDWR);
+#else
+ parpfd = open(name, O_RDWR | O_NONBLOCK);
+#endif
+
+ if (parpfd < 0)
+ {
+ char errbuf[256];
+
+ sprintf(errbuf, "open %s", name);
+ perror(errbuf);
+
+ return -1;
+ }
+
+ return 0;
+}
+
+extern void Unix_CloseParallel(void)
+{
+ if (parpfd >= 0)
+ {
+ (void)close(parpfd);
+ parpfd = -1;
+ }
+}
+
+
+extern unsigned int Unix_WriteParallel(unsigned char *buf, int n)
+{
+ int ngone;
+
+ if ((ngone = write(parpfd, buf, n)) < 0)
+ {
+ /*
+ * we ignore errors (except for debug purposes)
+ */
+#ifdef DEBUG
+ char errbuf[256];
+
+ sprintf(errbuf, "send_packet: write");
+ perror(errbuf);
+#endif
+ ngone = 0;
+ }
+
+ /* finished */
+ return (unsigned int)ngone;
+}
+
+
+#ifdef sun
+extern void Unix_ResetParallel(void)
+{
+ struct bpp_transfer_parms tp;
+
+#ifdef DEBUG
+ printf("serpar_reset\n");
+#endif
+
+ /*
+ * we need to set the parallel port up for BUSY handshaking,
+ * and select the timeout
+ */
+ if (ioctl(parpfd, BPPIOC_GETPARMS, &tp) < 0)
+ {
+#ifdef DEBUG
+ perror("ioctl(BPPIOCGETPARMS)");
+#endif
+ panic("serpar_reset: cannot get BPP parameters");
+ }
+
+ tp.write_handshake = BPP_BUSY_HS;
+ tp.write_timeout = PP_TIMEOUT;
+
+ if (ioctl(parpfd, BPPIOC_SETPARMS, &tp) < 0)
+ {
+#ifdef DEBUG
+ perror("ioctl(BPPIOC_SETPARMS)");
+#endif
+ panic("serpar_reset: cannot set BPP parameters");
+ }
+}
+
+#else
+
+/* Parallel not supported on HP */
+
+extern void Unix_ResetParallel(void)
+{
+}
+
+#endif
+
diff --git a/gdb/rdi-share/unixcomm.h b/gdb/rdi-share/unixcomm.h
new file mode 100644
index 00000000000..baa65520392
--- /dev/null
+++ b/gdb/rdi-share/unixcomm.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ */
+#ifndef angsd_unixcomm_h
+#define angsd_unixcomm_h
+
+#include <errno.h>
+
+#if defined(BSD)
+# define ERRNO_FOR_BLOCKED_IO EWOULDBLOCK
+#else
+# define ERRNO_FOR_BLOCKED_IO EAGAIN
+#endif
+
+/*
+ * Function: Unix_MatchValidSerialDevice
+ * Purpose: check that the serial driver/port name is valid
+ * and return the actual device name if it is.
+ *
+ * Params:
+ * Input: name Name of device going to be used
+ *
+ * Returns:
+ * OK: Pointer to name of the device matched
+ * Error or unrecognised deivce: 0
+ */
+extern const char *Unix_MatchValidSerialDevice(const char *name);
+
+/*
+ * Function: Unix_IsSerialInUse
+ * Purpose: check whether the serial port is in use
+ *
+ * Params:
+ * Input: Nothing
+ *
+ * Returns:
+ * OK: 0 Serial device not in use
+ * Error: -1 Serial device in use
+ */
+extern int Unix_IsSerialInUse(void);
+
+/*
+ * Function: Unix_OpenSerial
+ * Purpose: open the serial port
+ *
+ * Params:
+ * Input: name Name of device to open
+ *
+ * Returns: Unix 'open' returns
+ */
+extern int Unix_OpenSerial(const char *name);
+
+/*
+ * Function: Unix_CloseSerial
+ * Purpose: close the serial port
+ *
+ * Params:
+ * Input: Nothing
+ *
+ * Returns: Nothing
+ */
+extern void Unix_CloseSerial(void);
+
+/*
+ * Function: Unix_ReadSerial
+ * Purpose: reads a specified number of bytes (or less) from the serial port
+ *
+ * Params:
+ * Input: buf Buffer to store read bytes
+ * n Maximum number of bytes to read
+ *
+ * Returns: Unix 'read' returns
+ */
+extern int Unix_ReadSerial(unsigned char *buf, int n, bool block);
+
+/*
+ * Function: Unix_WriteSerial
+ * Purpose: writes a specified number of bytes (or less) to the serial port
+ *
+ * Params:
+ * Input: buf Buffer to write bytes from
+ * n Maximum number of bytes to write
+ *
+ * Returns: Unix 'write' returns
+ */
+extern int Unix_WriteSerial(unsigned char *buf, int n);
+
+/*
+ * Function: Unix_ResetSerial
+ * Purpose: resets the serial port for another operation
+ *
+ * Params:
+ * Input: Nothing
+ *
+ * Returns: Nothing
+ */
+extern void Unix_ResetSerial(void);
+
+/*
+ * Function: Unix_SetSerialBaudRate
+ * Purpose: check that the serial driver/port name is valid
+ *
+ * Params:
+ * Input: baudrate termios value for baud rate
+ *
+ * Returns: Nothing
+ */
+extern void Unix_SetSerialBaudRate(int baudrate);
+
+/*
+ * Function: Unix_ioctlNonBlocking
+ * Purpose: sets the serial port to non-blocking IO
+ *
+ * Params:
+ * Input: Nothing
+ *
+ * Returns: Nothing
+ */
+extern void Unix_ioctlNonBlocking(void);
+
+/*
+ * Function: Unix_IsValidParallelDevice
+ * Purpose: check whether the combined serial and parallel device specification
+ * is ok, and return the ports selected
+ *
+ * Params:
+ * Input: portstring - is a string which specifies which serial
+ * and parallel ports are to be used. Can
+ * include s=<val> and p=<val> separated by a
+ * comma.
+ *
+ * Returns:
+ * Output: *sername - returns the device name of the chosen serial port
+ * *parname - returns the device name of the chosen parallel port
+ * If either of these is NULL on return then the match failed.
+ */
+extern void Unix_IsValidParallelDevice(
+ const char *portstring, char **sername, char **parname
+);
+
+/*
+ * Function: Unix_IsParallelInUse
+ * Purpose: check whether the parallel port is in use
+ *
+ * Params:
+ * Input: Nothing
+ *
+ * Returns:
+ * OK: 0 Parallel device not in use
+ * Error: -1 Parallel device in use
+ */
+extern int Unix_IsParallelInUse(void);
+
+/*
+ * Function: Unix_OpenParallel
+ * Purpose: open the parallel port
+ *
+ * Params:
+ * Input: name Name of device to open
+ *
+ * Returns: Unix 'open' returns
+ */
+extern int Unix_OpenParallel(const char *name);
+
+/*
+ * Function: Unix_CloseParallel
+ * Purpose: close the parallel port
+ *
+ * Params:
+ * Input: Nothing
+ *
+ * Returns: Nothing
+ */
+extern void Unix_CloseParallel(void);
+
+/*
+ * Function: Unix_WriteParallel
+ * Purpose: writes a specified number of bytes (or less) to the parallel port
+ *
+ * Params:
+ * Input: buf Buffer to write bytes from
+ * n Maximum number of bytes to write
+ *
+ * Returns: Unix 'write' returns
+ */
+extern unsigned int Unix_WriteParallel(unsigned char *buf, int n);
+
+/*
+ * Function: Unix_ResetParallel
+ * Purpose: resets the parallel port for another operation
+ *
+ * Params:
+ * Input: Nothing
+ *
+ * Returns: Nothing
+ */
+extern void Unix_ResetParallel(void);
+
+#endif /* ndef angsd_unixcomm_h */
+
+/* EOF unixcomm.h */
diff --git a/gdb/regcache.c b/gdb/regcache.c
new file mode 100644
index 00000000000..11ed8c4f70d
--- /dev/null
+++ b/gdb/regcache.c
@@ -0,0 +1,799 @@
+/* Cache and manage the values of registers for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, 2001
+ 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 "defs.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbarch.h"
+#include "gdbcmd.h"
+#include "regcache.h"
+#include "gdb_assert.h"
+
+/*
+ * DATA STRUCTURE
+ *
+ * Here is the actual register cache.
+ */
+
+/* NOTE: this is a write-through cache. There is no "dirty" bit for
+ recording if the register values have been changed (eg. by the
+ user). Therefore all registers must be written back to the
+ target when appropriate. */
+
+/* REGISTERS contains the cached register values (in target byte order). */
+
+char *registers;
+
+/* REGISTER_VALID is 0 if the register needs to be fetched,
+ 1 if it has been fetched, and
+ -1 if the register value was not available.
+
+ "Not available" indicates that the target is not not able to supply
+ the register at this state. The register may become available at a
+ later time (after the next resume). This often occures when GDB is
+ manipulating a target that contains only a snapshot of the entire
+ system being debugged - some of the registers in such a system may
+ not have been saved. */
+
+signed char *register_valid;
+
+/* The thread/process associated with the current set of registers. */
+
+static ptid_t registers_ptid;
+
+/*
+ * FUNCTIONS:
+ */
+
+/* REGISTER_CACHED()
+
+ Returns 0 if the value is not in the cache (needs fetch).
+ >0 if the value is in the cache.
+ <0 if the value is permanently unavailable (don't ask again). */
+
+int
+register_cached (int regnum)
+{
+ return register_valid[regnum];
+}
+
+/* Record that REGNUM's value is cached if STATE is >0, uncached but
+ fetchable if STATE is 0, and uncached and unfetchable if STATE is <0. */
+
+void
+set_register_cached (int regnum, int state)
+{
+ register_valid[regnum] = state;
+}
+
+/* REGISTER_CHANGED
+
+ invalidate a single register REGNUM in the cache */
+void
+register_changed (int regnum)
+{
+ set_register_cached (regnum, 0);
+}
+
+/* If REGNUM >= 0, return a pointer to register REGNUM's cache buffer area,
+ else return a pointer to the start of the cache buffer. */
+
+static char *
+register_buffer (int regnum)
+{
+ gdb_assert (regnum >= 0 && regnum < (NUM_REGS + NUM_PSEUDO_REGS));
+ return &registers[REGISTER_BYTE (regnum)];
+}
+
+/* Return whether register REGNUM is a real register. */
+
+static int
+real_register (int regnum)
+{
+ return regnum >= 0 && regnum < NUM_REGS;
+}
+
+/* Return whether register REGNUM is a pseudo register. */
+
+static int
+pseudo_register (int regnum)
+{
+ return regnum >= NUM_REGS && regnum < NUM_REGS + NUM_PSEUDO_REGS;
+}
+
+/* Fetch register REGNUM into the cache. */
+
+static void
+fetch_register (int regnum)
+{
+ /* NOTE: cagney/2001-12-04: Legacy targets were using fetch/store
+ pseudo-register as a way of handling registers that needed to be
+ constructed from one or more raw registers. New targets instead
+ use gdbarch register read/write. */
+ if (FETCH_PSEUDO_REGISTER_P ()
+ && pseudo_register (regnum))
+ FETCH_PSEUDO_REGISTER (regnum);
+ else
+ target_fetch_registers (regnum);
+}
+
+/* Write register REGNUM cached value to the target. */
+
+static void
+store_register (int regnum)
+{
+ /* NOTE: cagney/2001-12-04: Legacy targets were using fetch/store
+ pseudo-register as a way of handling registers that needed to be
+ constructed from one or more raw registers. New targets instead
+ use gdbarch register read/write. */
+ if (STORE_PSEUDO_REGISTER_P ()
+ && pseudo_register (regnum))
+ STORE_PSEUDO_REGISTER (regnum);
+ else
+ target_store_registers (regnum);
+}
+
+/* Low level examining and depositing of registers.
+
+ The caller is responsible for making sure that the inferior is
+ stopped before calling the fetching routines, or it will get
+ garbage. (a change from GDB version 3, in which the caller got the
+ value from the last stop). */
+
+/* REGISTERS_CHANGED ()
+
+ Indicate that registers may have changed, so invalidate the cache. */
+
+void
+registers_changed (void)
+{
+ int i;
+
+ registers_ptid = pid_to_ptid (-1);
+
+ /* Force cleanup of any alloca areas if using C alloca instead of
+ a builtin alloca. This particular call is used to clean up
+ areas allocated by low level target code which may build up
+ during lengthy interactions between gdb and the target before
+ gdb gives control to the user (ie watchpoints). */
+ alloca (0);
+
+ for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+ set_register_cached (i, 0);
+
+ if (registers_changed_hook)
+ registers_changed_hook ();
+}
+
+/* REGISTERS_FETCHED ()
+
+ Indicate that all registers have been fetched, so mark them all valid. */
+
+/* NOTE: cagney/2001-12-04: This function does not set valid on the
+ pseudo-register range since pseudo registers are always supplied
+ using supply_register(). */
+/* FIXME: cagney/2001-12-04: This function is DEPRECATED. The target
+ code was blatting the registers[] array and then calling this.
+ Since targets should only be using supply_register() the need for
+ this function/hack is eliminated. */
+
+void
+registers_fetched (void)
+{
+ int i;
+
+ for (i = 0; i < NUM_REGS; i++)
+ set_register_cached (i, 1);
+ /* Do not assume that the pseudo-regs have also been fetched.
+ Fetching all real regs NEVER accounts for pseudo-regs. */
+}
+
+/* read_register_bytes and write_register_bytes are generally a *BAD*
+ idea. They are inefficient because they need to check for partial
+ updates, which can only be done by scanning through all of the
+ registers and seeing if the bytes that are being read/written fall
+ inside of an invalid register. [The main reason this is necessary
+ is that register sizes can vary, so a simple index won't suffice.]
+ It is far better to call read_register_gen and write_register_gen
+ if you want to get at the raw register contents, as it only takes a
+ regnum as an argument, and therefore can't do a partial register
+ update.
+
+ Prior to the recent fixes to check for partial updates, both read
+ and write_register_bytes always checked to see if any registers
+ were stale, and then called target_fetch_registers (-1) to update
+ the whole set. This caused really slowed things down for remote
+ targets. */
+
+/* Copy INLEN bytes of consecutive data from registers
+ starting with the INREGBYTE'th byte of register data
+ into memory at MYADDR. */
+
+void
+read_register_bytes (int in_start, char *in_buf, int in_len)
+{
+ int in_end = in_start + in_len;
+ int regnum;
+ char *reg_buf = alloca (MAX_REGISTER_RAW_SIZE);
+
+ /* See if we are trying to read bytes from out-of-date registers. If so,
+ update just those registers. */
+
+ for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+ {
+ int reg_start;
+ int reg_end;
+ int reg_len;
+ int start;
+ int end;
+ int byte;
+
+ reg_start = REGISTER_BYTE (regnum);
+ reg_len = REGISTER_RAW_SIZE (regnum);
+ reg_end = reg_start + reg_len;
+
+ if (reg_end <= in_start || in_end <= reg_start)
+ /* The range the user wants to read doesn't overlap with regnum. */
+ continue;
+
+ if (REGISTER_NAME (regnum) != NULL && *REGISTER_NAME (regnum) != '\0')
+ /* Force the cache to fetch the entire register. */
+ read_register_gen (regnum, reg_buf);
+ else
+ /* Legacy note: even though this register is ``invalid'' we
+ still need to return something. It would appear that some
+ code relies on apparent gaps in the register array also
+ being returned. */
+ /* FIXME: cagney/2001-08-18: This is just silly. It defeats
+ the entire register read/write flow of control. Must
+ resist temptation to return 0xdeadbeef. */
+ memcpy (reg_buf, registers + reg_start, reg_len);
+
+ /* Legacy note: This function, for some reason, allows a NULL
+ input buffer. If the buffer is NULL, the registers are still
+ fetched, just the final transfer is skipped. */
+ if (in_buf == NULL)
+ continue;
+
+ /* start = max (reg_start, in_start) */
+ if (reg_start > in_start)
+ start = reg_start;
+ else
+ start = in_start;
+
+ /* end = min (reg_end, in_end) */
+ if (reg_end < in_end)
+ end = reg_end;
+ else
+ end = in_end;
+
+ /* Transfer just the bytes common to both IN_BUF and REG_BUF */
+ for (byte = start; byte < end; byte++)
+ {
+ in_buf[byte - in_start] = reg_buf[byte - reg_start];
+ }
+ }
+}
+
+/* Read register REGNUM into memory at MYADDR, which must be large
+ enough for REGISTER_RAW_BYTES (REGNUM). Target byte-order. If the
+ register is known to be the size of a CORE_ADDR or smaller,
+ read_register can be used instead. */
+
+static void
+legacy_read_register_gen (int regnum, char *myaddr)
+{
+ gdb_assert (regnum >= 0 && regnum < (NUM_REGS + NUM_PSEUDO_REGS));
+ if (! ptid_equal (registers_ptid, inferior_ptid))
+ {
+ registers_changed ();
+ registers_ptid = inferior_ptid;
+ }
+
+ if (!register_cached (regnum))
+ fetch_register (regnum);
+
+ memcpy (myaddr, register_buffer (regnum),
+ REGISTER_RAW_SIZE (regnum));
+}
+
+void
+regcache_read (int rawnum, char *buf)
+{
+ gdb_assert (rawnum >= 0 && rawnum < (NUM_REGS + NUM_PSEUDO_REGS));
+ /* For moment, just use underlying legacy code. Ulgh!!! */
+ legacy_read_register_gen (rawnum, buf);
+}
+
+void
+read_register_gen (int regnum, char *buf)
+{
+ if (! gdbarch_register_read_p (current_gdbarch))
+ {
+ legacy_read_register_gen (regnum, buf);
+ return;
+ }
+ gdbarch_register_read (current_gdbarch, regnum, buf);
+}
+
+
+/* Write register REGNUM at MYADDR to the target. MYADDR points at
+ REGISTER_RAW_BYTES(REGNUM), which must be in target byte-order. */
+
+static void
+legacy_write_register_gen (int regnum, char *myaddr)
+{
+ int size;
+ gdb_assert (regnum >= 0 && regnum < (NUM_REGS + NUM_PSEUDO_REGS));
+
+ /* On the sparc, writing %g0 is a no-op, so we don't even want to
+ change the registers array if something writes to this register. */
+ if (CANNOT_STORE_REGISTER (regnum))
+ return;
+
+ if (! ptid_equal (registers_ptid, inferior_ptid))
+ {
+ registers_changed ();
+ registers_ptid = inferior_ptid;
+ }
+
+ size = REGISTER_RAW_SIZE (regnum);
+
+ if (real_register (regnum))
+ {
+ /* If we have a valid copy of the register, and new value == old
+ value, then don't bother doing the actual store. */
+ if (register_cached (regnum)
+ && memcmp (register_buffer (regnum), myaddr, size) == 0)
+ return;
+ else
+ target_prepare_to_store ();
+ }
+
+ memcpy (register_buffer (regnum), myaddr, size);
+
+ set_register_cached (regnum, 1);
+ store_register (regnum);
+}
+
+void
+regcache_write (int rawnum, char *buf)
+{
+ gdb_assert (rawnum >= 0 && rawnum < (NUM_REGS + NUM_PSEUDO_REGS));
+ /* For moment, just use underlying legacy code. Ulgh!!! */
+ legacy_write_register_gen (rawnum, buf);
+}
+
+void
+write_register_gen (int regnum, char *buf)
+{
+ if (! gdbarch_register_write_p (current_gdbarch))
+ {
+ legacy_write_register_gen (regnum, buf);
+ return;
+ }
+ gdbarch_register_write (current_gdbarch, regnum, buf);
+}
+
+/* Copy INLEN bytes of consecutive data from memory at MYADDR
+ into registers starting with the MYREGSTART'th byte of register data. */
+
+void
+write_register_bytes (int myregstart, char *myaddr, int inlen)
+{
+ int myregend = myregstart + inlen;
+ int regnum;
+
+ target_prepare_to_store ();
+
+ /* Scan through the registers updating any that are covered by the
+ range myregstart<=>myregend using write_register_gen, which does
+ nice things like handling threads, and avoiding updates when the
+ new and old contents are the same. */
+
+ for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+ {
+ int regstart, regend;
+
+ regstart = REGISTER_BYTE (regnum);
+ regend = regstart + REGISTER_RAW_SIZE (regnum);
+
+ /* Is this register completely outside the range the user is writing? */
+ if (myregend <= regstart || regend <= myregstart)
+ /* do nothing */ ;
+
+ /* Is this register completely within the range the user is writing? */
+ else if (myregstart <= regstart && regend <= myregend)
+ write_register_gen (regnum, myaddr + (regstart - myregstart));
+
+ /* The register partially overlaps the range being written. */
+ else
+ {
+ char *regbuf = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ /* What's the overlap between this register's bytes and
+ those the caller wants to write? */
+ int overlapstart = max (regstart, myregstart);
+ int overlapend = min (regend, myregend);
+
+ /* We may be doing a partial update of an invalid register.
+ Update it from the target before scribbling on it. */
+ read_register_gen (regnum, regbuf);
+
+ memcpy (registers + overlapstart,
+ myaddr + (overlapstart - myregstart),
+ overlapend - overlapstart);
+
+ store_register (regnum);
+ }
+ }
+}
+
+
+/* Return the contents of register REGNUM as an unsigned integer. */
+
+ULONGEST
+read_register (int regnum)
+{
+ char *buf = alloca (REGISTER_RAW_SIZE (regnum));
+ read_register_gen (regnum, buf);
+ return (extract_unsigned_integer (buf, REGISTER_RAW_SIZE (regnum)));
+}
+
+ULONGEST
+read_register_pid (int regnum, ptid_t ptid)
+{
+ ptid_t save_ptid;
+ int save_pid;
+ CORE_ADDR retval;
+
+ if (ptid_equal (ptid, inferior_ptid))
+ return read_register (regnum);
+
+ save_ptid = inferior_ptid;
+
+ inferior_ptid = ptid;
+
+ retval = read_register (regnum);
+
+ inferior_ptid = save_ptid;
+
+ return retval;
+}
+
+/* Return the contents of register REGNUM as a signed integer. */
+
+LONGEST
+read_signed_register (int regnum)
+{
+ void *buf = alloca (REGISTER_RAW_SIZE (regnum));
+ read_register_gen (regnum, buf);
+ return (extract_signed_integer (buf, REGISTER_RAW_SIZE (regnum)));
+}
+
+LONGEST
+read_signed_register_pid (int regnum, ptid_t ptid)
+{
+ ptid_t save_ptid;
+ LONGEST retval;
+
+ if (ptid_equal (ptid, inferior_ptid))
+ return read_signed_register (regnum);
+
+ save_ptid = inferior_ptid;
+
+ inferior_ptid = ptid;
+
+ retval = read_signed_register (regnum);
+
+ inferior_ptid = save_ptid;
+
+ return retval;
+}
+
+/* Store VALUE into the raw contents of register number REGNUM. */
+
+void
+write_register (int regnum, LONGEST val)
+{
+ void *buf;
+ int size;
+ size = REGISTER_RAW_SIZE (regnum);
+ buf = alloca (size);
+ store_signed_integer (buf, size, (LONGEST) val);
+ write_register_gen (regnum, buf);
+}
+
+void
+write_register_pid (int regnum, CORE_ADDR val, ptid_t ptid)
+{
+ ptid_t save_ptid;
+
+ if (ptid_equal (ptid, inferior_ptid))
+ {
+ write_register (regnum, val);
+ return;
+ }
+
+ save_ptid = inferior_ptid;
+
+ inferior_ptid = ptid;
+
+ write_register (regnum, val);
+
+ inferior_ptid = save_ptid;
+}
+
+/* SUPPLY_REGISTER()
+
+ Record that register REGNUM contains VAL. This is used when the
+ value is obtained from the inferior or core dump, so there is no
+ need to store the value there.
+
+ If VAL is a NULL pointer, then it's probably an unsupported register.
+ We just set its value to all zeros. We might want to record this
+ fact, and report it to the users of read_register and friends. */
+
+void
+supply_register (int regnum, char *val)
+{
+#if 1
+ if (! ptid_equal (registers_ptid, inferior_ptid))
+ {
+ registers_changed ();
+ registers_ptid = inferior_ptid;
+ }
+#endif
+
+ set_register_cached (regnum, 1);
+ if (val)
+ memcpy (register_buffer (regnum), val,
+ REGISTER_RAW_SIZE (regnum));
+ else
+ memset (register_buffer (regnum), '\000',
+ REGISTER_RAW_SIZE (regnum));
+
+ /* On some architectures, e.g. HPPA, there are a few stray bits in
+ some registers, that the rest of the code would like to ignore. */
+
+ /* NOTE: cagney/2001-03-16: The macro CLEAN_UP_REGISTER_VALUE is
+ going to be deprecated. Instead architectures will leave the raw
+ register value as is and instead clean things up as they pass
+ through the method gdbarch_register_read() clean up the
+ values. */
+
+#ifdef DEPRECATED_CLEAN_UP_REGISTER_VALUE
+ DEPRECATED_CLEAN_UP_REGISTER_VALUE (regnum, register_buffer (regnum));
+#endif
+}
+
+void
+regcache_collect (int regnum, void *buf)
+{
+ memcpy (buf, register_buffer (regnum), REGISTER_RAW_SIZE (regnum));
+}
+
+
+/* read_pc, write_pc, read_sp, write_sp, read_fp, etc. Special
+ handling for registers PC, SP, and FP. */
+
+/* NOTE: cagney/2001-02-18: The functions generic_target_read_pc(),
+ read_pc_pid(), read_pc(), generic_target_write_pc(),
+ write_pc_pid(), write_pc(), generic_target_read_sp(), read_sp(),
+ generic_target_write_sp(), write_sp(), generic_target_read_fp() and
+ read_fp(), will eventually be moved out of the reg-cache into
+ either frame.[hc] or to the multi-arch framework. The are not part
+ of the raw register cache. */
+
+/* This routine is getting awfully cluttered with #if's. It's probably
+ time to turn this into READ_PC and define it in the tm.h file.
+ Ditto for write_pc.
+
+ 1999-06-08: The following were re-written so that it assumes the
+ existence of a TARGET_READ_PC et.al. macro. A default generic
+ version of that macro is made available where needed.
+
+ Since the ``TARGET_READ_PC'' et.al. macro is going to be controlled
+ by the multi-arch framework, it will eventually be possible to
+ eliminate the intermediate read_pc_pid(). The client would call
+ TARGET_READ_PC directly. (cagney). */
+
+CORE_ADDR
+generic_target_read_pc (ptid_t ptid)
+{
+#ifdef PC_REGNUM
+ if (PC_REGNUM >= 0)
+ {
+ CORE_ADDR pc_val = ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, ptid));
+ return pc_val;
+ }
+#endif
+ internal_error (__FILE__, __LINE__,
+ "generic_target_read_pc");
+ return 0;
+}
+
+CORE_ADDR
+read_pc_pid (ptid_t ptid)
+{
+ ptid_t saved_inferior_ptid;
+ CORE_ADDR pc_val;
+
+ /* In case ptid != inferior_ptid. */
+ saved_inferior_ptid = inferior_ptid;
+ inferior_ptid = ptid;
+
+ pc_val = TARGET_READ_PC (ptid);
+
+ inferior_ptid = saved_inferior_ptid;
+ return pc_val;
+}
+
+CORE_ADDR
+read_pc (void)
+{
+ return read_pc_pid (inferior_ptid);
+}
+
+void
+generic_target_write_pc (CORE_ADDR pc, ptid_t ptid)
+{
+#ifdef PC_REGNUM
+ if (PC_REGNUM >= 0)
+ write_register_pid (PC_REGNUM, pc, ptid);
+ if (NPC_REGNUM >= 0)
+ write_register_pid (NPC_REGNUM, pc + 4, ptid);
+#else
+ internal_error (__FILE__, __LINE__,
+ "generic_target_write_pc");
+#endif
+}
+
+void
+write_pc_pid (CORE_ADDR pc, ptid_t ptid)
+{
+ ptid_t saved_inferior_ptid;
+
+ /* In case ptid != inferior_ptid. */
+ saved_inferior_ptid = inferior_ptid;
+ inferior_ptid = ptid;
+
+ TARGET_WRITE_PC (pc, ptid);
+
+ inferior_ptid = saved_inferior_ptid;
+}
+
+void
+write_pc (CORE_ADDR pc)
+{
+ write_pc_pid (pc, inferior_ptid);
+}
+
+/* Cope with strage ways of getting to the stack and frame pointers */
+
+CORE_ADDR
+generic_target_read_sp (void)
+{
+#ifdef SP_REGNUM
+ if (SP_REGNUM >= 0)
+ return read_register (SP_REGNUM);
+#endif
+ internal_error (__FILE__, __LINE__,
+ "generic_target_read_sp");
+}
+
+CORE_ADDR
+read_sp (void)
+{
+ return TARGET_READ_SP ();
+}
+
+void
+generic_target_write_sp (CORE_ADDR val)
+{
+#ifdef SP_REGNUM
+ if (SP_REGNUM >= 0)
+ {
+ write_register (SP_REGNUM, val);
+ return;
+ }
+#endif
+ internal_error (__FILE__, __LINE__,
+ "generic_target_write_sp");
+}
+
+void
+write_sp (CORE_ADDR val)
+{
+ TARGET_WRITE_SP (val);
+}
+
+CORE_ADDR
+generic_target_read_fp (void)
+{
+#ifdef FP_REGNUM
+ if (FP_REGNUM >= 0)
+ return read_register (FP_REGNUM);
+#endif
+ internal_error (__FILE__, __LINE__,
+ "generic_target_read_fp");
+}
+
+CORE_ADDR
+read_fp (void)
+{
+ return TARGET_READ_FP ();
+}
+
+/* ARGSUSED */
+static void
+reg_flush_command (char *command, int from_tty)
+{
+ /* Force-flush the register cache. */
+ registers_changed ();
+ if (from_tty)
+ printf_filtered ("Register cache flushed.\n");
+}
+
+static void
+build_regcache (void)
+{
+ int i;
+ int sizeof_register_valid;
+ /* Come up with the real size of the registers buffer. */
+ int sizeof_registers = REGISTER_BYTES; /* OK use. */
+ for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+ {
+ long regend;
+ /* Keep extending the buffer so that there is always enough
+ space for all registers. The comparison is necessary since
+ legacy code is free to put registers in random places in the
+ buffer separated by holes. Once REGISTER_BYTE() is killed
+ this can be greatly simplified. */
+ /* FIXME: cagney/2001-12-04: This code shouldn't need to use
+ REGISTER_BYTE(). Unfortunatly, legacy code likes to lay the
+ buffer out so that certain registers just happen to overlap.
+ Ulgh! New targets use gdbarch's register read/write and
+ entirely avoid this uglyness. */
+ regend = REGISTER_BYTE (i) + REGISTER_RAW_SIZE (i);
+ if (sizeof_registers < regend)
+ sizeof_registers = regend;
+ }
+ registers = xmalloc (sizeof_registers);
+ sizeof_register_valid = ((NUM_REGS + NUM_PSEUDO_REGS)
+ * sizeof (*register_valid));
+ register_valid = xmalloc (sizeof_register_valid);
+ memset (register_valid, 0, sizeof_register_valid);
+}
+
+void
+_initialize_regcache (void)
+{
+ register_gdbarch_swap (&registers, sizeof (registers), NULL);
+ register_gdbarch_swap (&register_valid, sizeof (register_valid), NULL);
+ register_gdbarch_swap (NULL, 0, build_regcache);
+
+ add_com ("flushregs", class_maintenance, reg_flush_command,
+ "Force gdb to flush its register cache (maintainer command)");
+
+ /* Initialize the thread/process associated with the current set of
+ registers. For now, -1 is special, and means `no current process'. */
+ registers_ptid = pid_to_ptid (-1);
+}
diff --git a/gdb/regcache.h b/gdb/regcache.h
new file mode 100644
index 00000000000..4e854d31667
--- /dev/null
+++ b/gdb/regcache.h
@@ -0,0 +1,82 @@
+/* Cache and manage the values of registers for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, 2001
+ 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. */
+
+#ifndef REGCACHE_H
+#define REGCACHE_H
+
+/* Transfer a raw register [0..NUM_REGS) between core-gdb and the
+ regcache. */
+
+void regcache_read (int rawnum, char *buf);
+void regcache_write (int rawnum, char *buf);
+
+/* Transfer a raw register [0..NUM_REGS) between the regcache and the
+ target. These functions are called by the target in response to a
+ target_fetch_registers() or target_store_registers(). */
+
+extern void supply_register (int regnum, char *val);
+extern void regcache_collect (int regnum, void *buf);
+
+
+/* DEPRECATED: Character array containing an image of the inferior
+ programs' registers for the most recently referenced thread. */
+
+extern char *registers;
+
+/* DEPRECATED: Character array containing the current state of each
+ register (unavailable<0, invalid=0, valid>0) for the most recently
+ referenced thread. */
+
+extern signed char *register_valid;
+
+extern int register_cached (int regnum);
+
+extern void set_register_cached (int regnum, int state);
+
+extern void register_changed (int regnum);
+
+extern void registers_changed (void);
+
+extern void registers_fetched (void);
+
+extern void read_register_bytes (int regbyte, char *myaddr, int len);
+
+extern void read_register_gen (int regnum, char *myaddr);
+
+extern void write_register_gen (int regnum, char *myaddr);
+
+extern void write_register_bytes (int regbyte, char *myaddr, int len);
+
+/* Rename to read_unsigned_register()? */
+extern ULONGEST read_register (int regnum);
+
+/* Rename to read_unsigned_register_pid()? */
+extern ULONGEST read_register_pid (int regnum, ptid_t ptid);
+
+extern LONGEST read_signed_register (int regnum);
+
+extern LONGEST read_signed_register_pid (int regnum, ptid_t ptid);
+
+extern void write_register (int regnum, LONGEST val);
+
+extern void write_register_pid (int regnum, CORE_ADDR val, ptid_t ptid);
+
+#endif /* REGCACHE_H */
diff --git a/gdb/regformats/reg-arm.dat b/gdb/regformats/reg-arm.dat
new file mode 100644
index 00000000000..5a600258239
--- /dev/null
+++ b/gdb/regformats/reg-arm.dat
@@ -0,0 +1,28 @@
+name:arm
+expedite:r11,sp,pc
+32:r0
+32:r1
+32:r2
+32:r3
+32:r4
+32:r5
+32:r6
+32:r7
+32:r8
+32:r9
+32:r10
+32:r11
+32:r12
+32:sp
+32:lr
+32:pc
+96:f0
+96:f1
+96:f2
+96:f3
+96:f4
+96:f5
+96:f6
+96:f7
+32:fps
+32:cpsr
diff --git a/gdb/regformats/reg-i386-linux.dat b/gdb/regformats/reg-i386-linux.dat
new file mode 100644
index 00000000000..91baa8fc80b
--- /dev/null
+++ b/gdb/regformats/reg-i386-linux.dat
@@ -0,0 +1,44 @@
+name:i386_linux
+expedite:ebp,esp,eip
+32:eax
+32:ecx
+32:edx
+32:ebx
+32:esp
+32:ebp
+32:esi
+32:edi
+32:eip
+32:eflags
+32:cs
+32:ss
+32:ds
+32:es
+32:fs
+32:gs
+80:st0
+80:st1
+80:st2
+80:st3
+80:st4
+80:st5
+80:st6
+80:st7
+32:fctrl
+32:fstat
+32:ftag
+32:fiseg
+32:fioff
+32:foseg
+32:fooff
+32:fop
+128:xmm0
+128:xmm1
+128:xmm2
+128:xmm3
+128:xmm4
+128:xmm5
+128:xmm6
+128:xmm7
+32:mxcsr
+32:orig_eax
diff --git a/gdb/regformats/reg-i386.dat b/gdb/regformats/reg-i386.dat
new file mode 100644
index 00000000000..69c2d90f1fd
--- /dev/null
+++ b/gdb/regformats/reg-i386.dat
@@ -0,0 +1,43 @@
+name:i386
+expedite:ebp,esp,eip
+32:eax
+32:ecx
+32:edx
+32:ebx
+32:esp
+32:ebp
+32:esi
+32:edi
+32:eip
+32:eflags
+32:cs
+32:ss
+32:ds
+32:es
+32:fs
+32:gs
+80:st0
+80:st1
+80:st2
+80:st3
+80:st4
+80:st5
+80:st6
+80:st7
+32:fctrl
+32:fstat
+32:ftag
+32:fiseg
+32:fioff
+32:foseg
+32:fooff
+32:fop
+128:xmm0
+128:xmm1
+128:xmm2
+128:xmm3
+128:xmm4
+128:xmm5
+128:xmm6
+128:xmm7
+32:mxcsr
diff --git a/gdb/regformats/reg-ia64.dat b/gdb/regformats/reg-ia64.dat
new file mode 100644
index 00000000000..125902dfe8d
--- /dev/null
+++ b/gdb/regformats/reg-ia64.dat
@@ -0,0 +1,603 @@
+name:ia64
+expedite:ip,psr,r12,bsp,cfm
+64:r0
+64:r1
+64:r2
+64:r3
+64:r4
+64:r5
+64:r6
+64:r7
+64:r8
+64:r9
+64:r10
+64:r11
+64:r12
+64:r13
+64:r14
+64:r15
+64:r16
+64:r17
+64:r18
+64:r19
+64:r20
+64:r21
+64:r22
+64:r23
+64:r24
+64:r25
+64:r26
+64:r27
+64:r28
+64:r29
+64:r30
+64:r31
+64:r32
+64:r33
+64:r34
+64:r35
+64:r36
+64:r37
+64:r38
+64:r39
+64:r40
+64:r41
+64:r42
+64:r43
+64:r44
+64:r45
+64:r46
+64:r47
+64:r48
+64:r49
+64:r50
+64:r51
+64:r52
+64:r53
+64:r54
+64:r55
+64:r56
+64:r57
+64:r58
+64:r59
+64:r60
+64:r61
+64:r62
+64:r63
+64:r64
+64:r65
+64:r66
+64:r67
+64:r68
+64:r69
+64:r70
+64:r71
+64:r72
+64:r73
+64:r74
+64:r75
+64:r76
+64:r77
+64:r78
+64:r79
+64:r80
+64:r81
+64:r82
+64:r83
+64:r84
+64:r85
+64:r86
+64:r87
+64:r88
+64:r89
+64:r90
+64:r91
+64:r92
+64:r93
+64:r94
+64:r95
+64:r96
+64:r97
+64:r98
+64:r99
+64:r100
+64:r101
+64:r102
+64:r103
+64:r104
+64:r105
+64:r106
+64:r107
+64:r108
+64:r109
+64:r110
+64:r111
+64:r112
+64:r113
+64:r114
+64:r115
+64:r116
+64:r117
+64:r118
+64:r119
+64:r120
+64:r121
+64:r122
+64:r123
+64:r124
+64:r125
+64:r126
+64:r127
+
+128:f0
+128:f1
+128:f2
+128:f3
+128:f4
+128:f5
+128:f6
+128:f7
+128:f8
+128:f9
+128:f10
+128:f11
+128:f12
+128:f13
+128:f14
+128:f15
+128:f16
+128:f17
+128:f18
+128:f19
+128:f20
+128:f21
+128:f22
+128:f23
+128:f24
+128:f25
+128:f26
+128:f27
+128:f28
+128:f29
+128:f30
+128:f31
+128:f32
+128:f33
+128:f34
+128:f35
+128:f36
+128:f37
+128:f38
+128:f39
+128:f40
+128:f41
+128:f42
+128:f43
+128:f44
+128:f45
+128:f46
+128:f47
+128:f48
+128:f49
+128:f50
+128:f51
+128:f52
+128:f53
+128:f54
+128:f55
+128:f56
+128:f57
+128:f58
+128:f59
+128:f60
+128:f61
+128:f62
+128:f63
+128:f64
+128:f65
+128:f66
+128:f67
+128:f68
+128:f69
+128:f70
+128:f71
+128:f72
+128:f73
+128:f74
+128:f75
+128:f76
+128:f77
+128:f78
+128:f79
+128:f80
+128:f81
+128:f82
+128:f83
+128:f84
+128:f85
+128:f86
+128:f87
+128:f88
+128:f89
+128:f90
+128:f91
+128:f92
+128:f93
+128:f94
+128:f95
+128:f96
+128:f97
+128:f98
+128:f99
+128:f100
+128:f101
+128:f102
+128:f103
+128:f104
+128:f105
+128:f106
+128:f107
+128:f108
+128:f109
+128:f110
+128:f111
+128:f112
+128:f113
+128:f114
+128:f115
+128:f116
+128:f117
+128:f118
+128:f119
+128:f120
+128:f121
+128:f122
+128:f123
+128:f124
+128:f125
+128:f126
+128:f127
+
+64:p0
+64:p1
+64:p2
+64:p3
+64:p4
+64:p5
+64:p6
+64:p7
+64:p8
+64:p9
+64:p10
+64:p11
+64:p12
+64:p13
+64:p14
+64:p15
+64:p16
+64:p17
+64:p18
+64:p19
+64:p20
+64:p21
+64:p22
+64:p23
+64:p24
+64:p25
+64:p26
+64:p27
+64:p28
+64:p29
+64:p30
+64:p31
+64:p32
+64:p33
+64:p34
+64:p35
+64:p36
+64:p37
+64:p38
+64:p39
+64:p40
+64:p41
+64:p42
+64:p43
+64:p44
+64:p45
+64:p46
+64:p47
+64:p48
+64:p49
+64:p50
+64:p51
+64:p52
+64:p53
+64:p54
+64:p55
+64:p56
+64:p57
+64:p58
+64:p59
+64:p60
+64:p61
+64:p62
+64:p63
+
+64:b0
+64:b1
+64:b2
+64:b3
+64:b4
+64:b5
+64:b6
+64:b7
+
+64:vfp
+64:vrap
+
+64:pr
+64:ip
+64:psr
+64:cfm
+
+64:kr0
+64:kr1
+64:kr2
+64:kr3
+64:kr4
+64:kr5
+64:kr6
+64:kr7
+
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+
+64:rsc
+64:bsp
+64:bspstore
+64:rnat
+
+64:
+64:fcr
+64:
+64:
+
+64:eflag
+64:csd
+64:ssd
+64:cflg
+64:fsr
+64:fir
+64:fdr
+64:
+64:ccv
+64:
+64:
+64:
+64:unat
+64:
+64:
+64:
+64:fpsr
+64:
+64:
+64:
+64:itc
+
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:pfs
+64:lc
+64:ec
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:
+64:nat0
+64:nat1
+64:nat2
+64:nat3
+64:nat4
+64:nat5
+64:nat6
+64:nat7
+64:nat8
+64:nat9
+64:nat10
+64:nat11
+64:nat12
+64:nat13
+64:nat14
+64:nat15
+64:nat16
+64:nat17
+64:nat18
+64:nat19
+64:nat20
+64:nat21
+64:nat22
+64:nat23
+64:nat24
+64:nat25
+64:nat26
+64:nat27
+64:nat28
+64:nat29
+64:nat30
+64:nat31
+64:nat32
+64:nat33
+64:nat34
+64:nat35
+64:nat36
+64:nat37
+64:nat38
+64:nat39
+64:nat40
+64:nat41
+64:nat42
+64:nat43
+64:nat44
+64:nat45
+64:nat46
+64:nat47
+64:nat48
+64:nat49
+64:nat50
+64:nat51
+64:nat52
+64:nat53
+64:nat54
+64:nat55
+64:nat56
+64:nat57
+64:nat58
+64:nat59
+64:nat60
+64:nat61
+64:nat62
+64:nat63
+64:nat64
+64:nat65
+64:nat66
+64:nat67
+64:nat68
+64:nat69
+64:nat70
+64:nat71
+64:nat72
+64:nat73
+64:nat74
+64:nat75
+64:nat76
+64:nat77
+64:nat78
+64:nat79
+64:nat80
+64:nat81
+64:nat82
+64:nat83
+64:nat84
+64:nat85
+64:nat86
+64:nat87
+64:nat88
+64:nat89
+64:nat90
+64:nat91
+64:nat92
+64:nat93
+64:nat94
+64:nat95
+64:nat96
+64:nat97
+64:nat98
+64:nat99
+64:nat100
+64:nat101
+64:nat102
+64:nat103
+64:nat104
+64:nat105
+64:nat106
+64:nat107
+64:nat108
+64:nat109
+64:nat110
+64:nat111
+64:nat112
+64:nat113
+64:nat114
+64:nat115
+64:nat116
+64:nat117
+64:nat118
+64:nat119
+64:nat120
+64:nat121
+64:nat122
+64:nat123
+64:nat124
+64:nat125
+64:nat126
+64:nat127
diff --git a/gdb/regformats/reg-m68k.dat b/gdb/regformats/reg-m68k.dat
new file mode 100644
index 00000000000..1f0b078dd3c
--- /dev/null
+++ b/gdb/regformats/reg-m68k.dat
@@ -0,0 +1,35 @@
+name:m68k
+expedite:sp,fp,pc
+32:d0
+32:d1
+32:d2
+32:d3
+32:d4
+32:d5
+32:d6
+32:d7
+32:a0
+32:a1
+32:a2
+32:a3
+32:a4
+32:a5
+32:fp
+32:sp
+32:ps
+32:pc
+
+96:fp0
+96:fp1
+96:fp2
+96:fp3
+96:fp4
+96:fp5
+96:fp6
+96:fp7
+
+32:fpcontrol
+32:fpstatus
+32:fpiaddr
+32:fpcode
+32:fpflags
diff --git a/gdb/regformats/reg-mips.dat b/gdb/regformats/reg-mips.dat
new file mode 100644
index 00000000000..7a7c8086e94
--- /dev/null
+++ b/gdb/regformats/reg-mips.dat
@@ -0,0 +1,112 @@
+name:mips
+expedite:pc,sp
+32:zero
+32:at
+32:v0
+32:v1
+
+32:a0
+32:a1
+32:a2
+32:a3
+
+32:t0
+32:t1
+32:t2
+32:t3
+
+32:t4
+32:t5
+32:t6
+32:t7
+
+32:s0
+32:s1
+32:s2
+32:s3
+
+32:s4
+32:s5
+32:s6
+32:s7
+
+32:t8
+32:t9
+32:k0
+32:k1
+
+32:gp
+32:sp
+32:s8
+32:ra
+
+32:sr
+32:lo
+32:hi
+32:bad
+
+32:cause
+32:pc
+
+32:f0
+32:f1
+32:f2
+32:f3
+
+32:f4
+32:f5
+32:f6
+32:f7
+
+32:f8
+32:f9
+32:f10
+32:f11
+
+32:f12
+32:f13
+32:f14
+32:f15
+
+32:f16
+32:f17
+32:f18
+32:f19
+
+32:f20
+32:f21
+32:f22
+32:f23
+
+32:f24
+32:f25
+32:f26
+32:f27
+
+32:f28
+32:f29
+32:f30
+32:f31
+
+32:fsr
+32:fir
+
+32:fp
+32:
+
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
diff --git a/gdb/regformats/reg-ppc.dat b/gdb/regformats/reg-ppc.dat
new file mode 100644
index 00000000000..d7f9b88c355
--- /dev/null
+++ b/gdb/regformats/reg-ppc.dat
@@ -0,0 +1,76 @@
+name:ppc
+expedite:r1,pc
+32:r0
+32:r1
+32:r2
+32:r3
+32:r4
+32:r5
+32:r6
+32:r7
+32:r8
+32:r9
+32:r10
+32:r11
+32:r12
+32:r13
+32:r14
+32:r15
+32:r16
+32:r17
+32:r18
+32:r19
+32:r20
+32:r21
+32:r22
+32:r23
+32:r24
+32:r25
+32:r26
+32:r27
+32:r28
+32:r29
+32:r30
+32:r31
+
+64:f0
+64:f1
+64:f2
+64:f3
+64:f4
+64:f5
+64:f6
+64:f7
+64:f8
+64:f9
+64:f10
+64:f11
+64:f12
+64:f13
+64:f14
+64:f15
+64:f16
+64:f17
+64:f18
+64:f19
+64:f20
+64:f21
+64:f22
+64:f23
+64:f24
+64:f25
+64:f26
+64:f27
+64:f28
+64:f29
+64:f30
+64:f31
+
+32:pc
+32:ps
+
+32:cr
+32:lr
+32:ctr
+32:xer
+32:fpscr
diff --git a/gdb/regformats/reg-s390.dat b/gdb/regformats/reg-s390.dat
new file mode 100644
index 00000000000..c533a489459
--- /dev/null
+++ b/gdb/regformats/reg-s390.dat
@@ -0,0 +1,69 @@
+name:s390
+expedite:r14,r15,pswa
+32:pswm
+32:pswa
+32:r0
+32:r1
+32:r2
+32:r3
+32:r4
+32:r5
+32:r6
+32:r7
+32:r8
+32:r9
+32:r10
+32:r11
+32:r12
+32:r13
+32:r14
+32:r15
+32:acr0
+32:acr1
+32:acr2
+32:acr3
+32:acr4
+32:acr5
+32:acr6
+32:acr7
+32:acr8
+32:acr9
+32:acr10
+32:acr11
+32:acr12
+32:acr13
+32:acr14
+32:acr15
+32:cr0
+32:cr1
+32:cr2
+32:cr3
+32:cr4
+32:cr5
+32:cr6
+32:cr7
+32:cr8
+32:cr9
+32:cr10
+32:cr11
+32:cr12
+32:cr13
+32:cr14
+32:cr15
+32:fpc
+64:f0
+64:f1
+64:f2
+64:f3
+64:f4
+64:f5
+64:f6
+64:f7
+64:f8
+64:f9
+64:f10
+64:f11
+64:f12
+64:f13
+64:f14
+64:f15
diff --git a/gdb/regformats/reg-s390x.dat b/gdb/regformats/reg-s390x.dat
new file mode 100644
index 00000000000..25bef05645a
--- /dev/null
+++ b/gdb/regformats/reg-s390x.dat
@@ -0,0 +1,69 @@
+name:s390
+expedite:r14,r15,pswa
+64:pswm
+64:pswa
+64:r0
+64:r1
+64:r2
+64:r3
+64:r4
+64:r5
+64:r6
+64:r7
+64:r8
+64:r9
+64:r10
+64:r11
+64:r12
+64:r13
+64:r14
+64:r15
+32:acr0
+32:acr1
+32:acr2
+32:acr3
+32:acr4
+32:acr5
+32:acr6
+32:acr7
+32:acr8
+32:acr9
+32:acr10
+32:acr11
+32:acr12
+32:acr13
+32:acr14
+32:acr15
+64:cr0
+64:cr1
+64:cr2
+64:cr3
+64:cr4
+64:cr5
+64:cr6
+64:cr7
+64:cr8
+64:cr9
+64:cr10
+64:cr11
+64:cr12
+64:cr13
+64:cr14
+64:cr15
+32:fpc
+64:f0
+64:f1
+64:f2
+64:f3
+64:f4
+64:f5
+64:f6
+64:f7
+64:f8
+64:f9
+64:f10
+64:f11
+64:f12
+64:f13
+64:f14
+64:f15
diff --git a/gdb/regformats/reg-sh.dat b/gdb/regformats/reg-sh.dat
new file mode 100644
index 00000000000..d670b46765b
--- /dev/null
+++ b/gdb/regformats/reg-sh.dat
@@ -0,0 +1,62 @@
+name:sh
+expedite:pc,r14,r15
+32:r0
+32:r1
+32:r2
+32:r3
+32:r4
+32:r5
+32:r6
+32:r7
+32:r8
+32:r9
+32:r10
+32:r11
+32:r12
+32:r13
+32:r14
+32:r15
+32:pc
+32:pr
+32:gbr
+32:vbr
+32:mach
+32:macl
+32:sr
+32:fpul
+32:fpscr
+32:fr0
+32:fr1
+32:fr2
+32:fr3
+32:fr4
+32:fr5
+32:fr6
+32:fr7
+32:fr8
+32:fr9
+32:fr10
+32:fr11
+32:fr12
+32:fr13
+32:fr14
+32:fr15
+
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
diff --git a/gdb/regformats/reg-x86-64.dat b/gdb/regformats/reg-x86-64.dat
new file mode 100644
index 00000000000..59ebbf5267e
--- /dev/null
+++ b/gdb/regformats/reg-x86-64.dat
@@ -0,0 +1,57 @@
+name:x86_64
+expedite:rbp,rsp,rip
+64:rax
+64:rbx
+64:rcx
+64:rdx
+64:rsi
+64:rdi
+64:rbp
+64:rsp
+64:r8
+64:r9
+64:r10
+64:r11
+64:r12
+64:r13
+64:r14
+64:r15
+64:rip
+32:eflags
+32:ds
+32:es
+32:fs
+32:gs
+80:st0
+80:st1
+80:st2
+80:st3
+80:st4
+80:st5
+80:st6
+80:st7
+32:fctrl
+32:fstat
+32:ftag
+32:fiseg
+32:fioff
+32:foseg
+32:fooff
+32:fop
+128:xmm0
+128:xmm1
+128:xmm2
+128:xmm3
+128:xmm4
+128:xmm5
+128:xmm6
+128:xmm7
+128:xmm8
+128:xmm9
+128:xmm10
+128:xmm11
+128:xmm12
+128:xmm13
+128:xmm14
+128:xmm15
+32:mxcsr
diff --git a/gdb/regformats/regdat.sh b/gdb/regformats/regdat.sh
new file mode 100755
index 00000000000..9035b3dc90d
--- /dev/null
+++ b/gdb/regformats/regdat.sh
@@ -0,0 +1,169 @@
+#!/bin/sh -u
+
+# Register protocol definitions for GDB, the GNU debugger.
+# Copyright 2001, 2002 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.
+
+move_if_change ()
+{
+ file=$1
+ if test -r ${file} && cmp -s "${file}" new-"${file}"
+ then
+ echo "${file} unchanged." 1>&2
+ else
+ mv new-"${file}" "${file}"
+ echo "${file} updated." 1>&2
+ fi
+}
+
+# Format of the input files
+read="type entry"
+
+do_read ()
+{
+ type=""
+ entry=""
+ while read line
+ do
+ if test "${line}" = ""
+ then
+ continue
+ elif test "${line}" = "#" -a "${comment}" = ""
+ then
+ continue
+ elif expr "${line}" : "#" > /dev/null
+ then
+ comment="${comment}
+${line}"
+ else
+
+ # The semantics of IFS varies between different SH's. Some
+ # treat ``::' as three fields while some treat it as just too.
+ # Work around this by eliminating ``::'' ....
+ line="`echo "${line}" | sed -e 's/::/: :/g' -e 's/::/: :/g'`"
+
+ OFS="${IFS}" ; IFS="[:]"
+ eval read ${read} <<EOF
+${line}
+EOF
+ IFS="${OFS}"
+
+ # .... and then going back through each field and strip out those
+ # that ended up with just that space character.
+ for r in ${read}
+ do
+ if eval test \"\${${r}}\" = \"\ \"
+ then
+ eval ${r}=""
+ fi
+ done
+
+ break
+ fi
+ done
+ if [ -n "${type}" ]
+ then
+ true
+ else
+ false
+ fi
+}
+
+if test ! -r $1; then
+ echo "$0: Could not open $1." 1>&2
+ exit 1
+fi
+
+copyright ()
+{
+cat <<EOF
+/* *INDENT-OFF* */ /* THIS FILE IS GENERATED */
+
+/* A register protocol for GDB, the GNU debugger.
+ Copyright 2001, 2002 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. */
+
+/* This file was created with the aid of \`\`regdat.sh'' and \`\`$1''. */
+
+EOF
+}
+
+
+exec > new-$2
+copyright $1
+echo '#include "regdef.h"'
+echo '#include "regcache.h"'
+echo
+offset=0
+i=0
+name=x
+expedite=x
+exec < $1
+while do_read
+do
+ if test "${type}" = "name"; then
+ name="${entry}"
+ echo "struct reg regs_${name}[] = {"
+ continue
+ elif test "${type}" = "expedite"; then
+ expedite="${entry}"
+ continue
+ elif test "${name}" = x; then
+ echo "$0: $1 does not specify \`\`name''." 1>&2
+ exit 1
+ else
+ echo " { \"${entry}\", ${offset}, ${type} },"
+ offset=`expr ${offset} + ${type}`
+ i=`expr $i + 1`
+ fi
+done
+
+echo "};"
+echo
+echo "const char *expedite_regs_${name}[] = { \"`echo ${expedite} | sed 's/,/", "/g'`\", 0 };"
+echo
+
+cat <<EOF
+void
+init_registers ()
+{
+ set_register_cache (regs_${name},
+ sizeof (regs_${name}) / sizeof (regs_${name}[0]));
+ gdbserver_expedite_regs = expedite_regs_${name};
+}
+EOF
+
+# close things off
+exec 1>&2
+move_if_change $2
diff --git a/gdb/regformats/regdef.h b/gdb/regformats/regdef.h
new file mode 100644
index 00000000000..c1f862cc356
--- /dev/null
+++ b/gdb/regformats/regdef.h
@@ -0,0 +1,46 @@
+/* Register protocol definition structures for the GNU Debugger
+ Copyright 2001, 2002 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. */
+
+#ifndef REGDEF_H
+#define REGDEF_H
+
+struct reg
+{
+ /* The name of this register - NULL for pad entries. */
+ const char *name;
+
+ /* At the moment, both of the following bit counts must be divisible
+ by eight (to match the representation as two hex digits) and divisible
+ by the size of a byte (to match the layout of each register in
+ memory). */
+
+ /* The offset (in bits) of the value of this register in the buffer. */
+ int offset;
+
+ /* The size (in bits) of the value of this register, as transmitted. */
+ int size;
+};
+
+/* Set the current remote protocol and register cache according to the array
+ ``regs'', with ``n'' elements. */
+
+void set_register_cache (struct reg *regs, int n);
+
+#endif /* REGDEF_H */
diff --git a/gdb/remote-array.c b/gdb/remote-array.c
new file mode 100644
index 00000000000..ed0c40e4436
--- /dev/null
+++ b/gdb/remote-array.c
@@ -0,0 +1,1460 @@
+/* Remote debugging interface for Array Tech RAID controller..
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
+
+ This module talks to a debug monitor called 'MONITOR', which
+ We communicate with MONITOR via either a direct serial line, or a TCP
+ (or possibly TELNET) stream to a terminal multiplexor,
+ which in turn talks to the target board.
+
+ 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include <ctype.h>
+#include <sys/types.h>
+#include "gdb_string.h"
+#include "command.h"
+#include "serial.h"
+#include "monitor.h"
+#include "remote-utils.h"
+#include "inferior.h"
+#include "version.h"
+#include "regcache.h"
+
+extern int baud_rate;
+
+#define ARRAY_PROMPT ">> "
+
+static void debuglogs (int, char *, ...);
+static void array_open ();
+static void array_close ();
+static void array_detach ();
+static void array_attach ();
+static void array_resume (ptid_t ptid, int step, enum target_signal sig);
+static void array_fetch_register ();
+static void array_store_register ();
+static void array_fetch_registers ();
+static void array_store_registers ();
+static void array_prepare_to_store ();
+static void array_files_info ();
+static void array_kill ();
+static void array_create_inferior ();
+static void array_mourn_inferior ();
+static void make_gdb_packet ();
+static int array_xfer_memory ();
+static ptid_t array_wait (ptid_t ptid,
+ struct target_waitstatus *status);
+static int array_insert_breakpoint ();
+static int array_remove_breakpoint ();
+static int tohex ();
+static int to_hex ();
+static int from_hex ();
+static int array_send_packet ();
+static int array_get_packet ();
+static unsigned long ascii2hexword ();
+static void hexword2ascii ();
+
+#define LOG_FILE "monitor.log"
+#if defined (LOG_FILE)
+FILE *log_file;
+#endif
+
+static int timeout = 30;
+/* Having this larger than 400 causes us to be incompatible with m68k-stub.c
+ and i386-stub.c. Normally, no one would notice because it only matters
+ for writing large chunks of memory (e.g. in downloads). Also, this needs
+ to be more than 400 if required to hold the registers (see below, where
+ we round it up based on REGISTER_BYTES). */
+#define PBUFSIZ 400
+
+/*
+ * Descriptor for I/O to remote machine. Initialize it to NULL so that
+ * array_open knows that we don't have a file open when the program starts.
+ */
+struct serial *array_desc = NULL;
+
+/*
+ * this array of registers need to match the indexes used by GDB. The
+ * whole reason this exists is cause the various ROM monitors use
+ * different strings than GDB does, and doesn't support all the
+ * registers either. So, typing "info reg sp" becomes a "r30".
+ */
+extern char *tmp_mips_processor_type;
+extern int mips_set_processor_type ();
+
+static struct target_ops array_ops;
+
+static void
+init_array_ops (void)
+{
+ array_ops.to_shortname = "array";
+ array_ops.to_longname =
+ "Debug using the standard GDB remote protocol for the Array Tech target.",
+ array_ops.to_doc =
+ "Debug using the standard GDB remote protocol for the Array Tech target.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ array_ops.to_open = array_open;
+ array_ops.to_close = array_close;
+ array_ops.to_attach = NULL;
+ array_ops.to_post_attach = NULL;
+ array_ops.to_require_attach = NULL;
+ array_ops.to_detach = array_detach;
+ array_ops.to_require_detach = NULL;
+ array_ops.to_resume = array_resume;
+ array_ops.to_wait = array_wait;
+ array_ops.to_post_wait = NULL;
+ array_ops.to_fetch_registers = array_fetch_registers;
+ array_ops.to_store_registers = array_store_registers;
+ array_ops.to_prepare_to_store = array_prepare_to_store;
+ array_ops.to_xfer_memory = array_xfer_memory;
+ array_ops.to_files_info = array_files_info;
+ array_ops.to_insert_breakpoint = array_insert_breakpoint;
+ array_ops.to_remove_breakpoint = array_remove_breakpoint;
+ array_ops.to_terminal_init = 0;
+ array_ops.to_terminal_inferior = 0;
+ array_ops.to_terminal_ours_for_output = 0;
+ array_ops.to_terminal_ours = 0;
+ array_ops.to_terminal_info = 0;
+ array_ops.to_kill = array_kill;
+ array_ops.to_load = 0;
+ array_ops.to_lookup_symbol = 0;
+ array_ops.to_create_inferior = array_create_inferior;
+ array_ops.to_post_startup_inferior = NULL;
+ array_ops.to_acknowledge_created_inferior = NULL;
+ array_ops.to_clone_and_follow_inferior = NULL;
+ array_ops.to_post_follow_inferior_by_clone = NULL;
+ array_ops.to_insert_fork_catchpoint = NULL;
+ array_ops.to_remove_fork_catchpoint = NULL;
+ array_ops.to_insert_vfork_catchpoint = NULL;
+ array_ops.to_remove_vfork_catchpoint = NULL;
+ array_ops.to_has_forked = NULL;
+ array_ops.to_has_vforked = NULL;
+ array_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ array_ops.to_post_follow_vfork = NULL;
+ array_ops.to_insert_exec_catchpoint = NULL;
+ array_ops.to_remove_exec_catchpoint = NULL;
+ array_ops.to_has_execd = NULL;
+ array_ops.to_reported_exec_events_per_exec_call = NULL;
+ array_ops.to_has_exited = NULL;
+ array_ops.to_mourn_inferior = array_mourn_inferior;
+ array_ops.to_can_run = 0;
+ array_ops.to_notice_signals = 0;
+ array_ops.to_thread_alive = 0;
+ array_ops.to_stop = 0;
+ array_ops.to_pid_to_exec_file = NULL;
+ array_ops.to_stratum = process_stratum;
+ array_ops.DONT_USE = 0;
+ array_ops.to_has_all_memory = 1;
+ array_ops.to_has_memory = 1;
+ array_ops.to_has_stack = 1;
+ array_ops.to_has_registers = 1;
+ array_ops.to_has_execution = 1;
+ array_ops.to_sections = 0;
+ array_ops.to_sections_end = 0;
+ array_ops.to_magic = OPS_MAGIC;
+};
+
+/*
+ * printf_monitor -- send data to monitor. Works just like printf.
+ */
+static void
+printf_monitor (char *pattern,...)
+{
+ va_list args;
+ char buf[PBUFSIZ];
+ int i;
+
+ va_start (args, pattern);
+
+ vsprintf (buf, pattern, args);
+
+ debuglogs (1, "printf_monitor(), Sending: \"%s\".", buf);
+
+ if (strlen (buf) > PBUFSIZ)
+ error ("printf_monitor(): string too long");
+ if (serial_write (array_desc, buf, strlen (buf)))
+ fprintf_unfiltered (gdb_stderr, "serial_write failed: %s\n",
+ safe_strerror (errno));
+}
+/*
+ * write_monitor -- send raw data to monitor.
+ */
+static void
+write_monitor (char data[], int len)
+{
+ if (serial_write (array_desc, data, len))
+ fprintf_unfiltered (gdb_stderr, "serial_write failed: %s\n",
+ safe_strerror (errno));
+
+ *(data + len + 1) = '\0';
+ debuglogs (1, "write_monitor(), Sending: \"%s\".", data);
+
+}
+
+/*
+ * debuglogs -- deal with debugging info to multiple sources. This takes
+ * two real args, the first one is the level to be compared against
+ * the sr_get_debug() value, the second arg is a printf buffer and args
+ * to be formatted and printed. A CR is added after each string is printed.
+ */
+static void
+debuglogs (int level, char *pattern,...)
+{
+ va_list args;
+ char *p;
+ unsigned char buf[PBUFSIZ];
+ char newbuf[PBUFSIZ];
+ int i;
+
+ va_start (args, pattern);
+
+ if ((level < 0) || (level > 100))
+ {
+ error ("Bad argument passed to debuglogs(), needs debug level");
+ return;
+ }
+
+ vsprintf (buf, pattern, args); /* format the string */
+
+ /* convert some characters so it'll look right in the log */
+ p = newbuf;
+ for (i = 0; buf[i] != '\0'; i++)
+ {
+ if (i > PBUFSIZ)
+ error ("Debug message too long");
+ switch (buf[i])
+ {
+ case '\n': /* newlines */
+ *p++ = '\\';
+ *p++ = 'n';
+ continue;
+ case '\r': /* carriage returns */
+ *p++ = '\\';
+ *p++ = 'r';
+ continue;
+ case '\033': /* escape */
+ *p++ = '\\';
+ *p++ = 'e';
+ continue;
+ case '\t': /* tab */
+ *p++ = '\\';
+ *p++ = 't';
+ continue;
+ case '\b': /* backspace */
+ *p++ = '\\';
+ *p++ = 'b';
+ continue;
+ default: /* no change */
+ *p++ = buf[i];
+ }
+
+ if (buf[i] < 26)
+ { /* modify control characters */
+ *p++ = '^';
+ *p++ = buf[i] + 'A';
+ continue;
+ }
+ if (buf[i] >= 128)
+ { /* modify control characters */
+ *p++ = '!';
+ *p++ = buf[i] + 'A';
+ continue;
+ }
+ }
+ *p = '\0'; /* terminate the string */
+
+ if (sr_get_debug () > level)
+ printf_unfiltered ("%s\n", newbuf);
+
+#ifdef LOG_FILE /* write to the monitor log */
+ if (log_file != 0x0)
+ {
+ fputs (newbuf, log_file);
+ fputc ('\n', log_file);
+ fflush (log_file);
+ }
+#endif
+}
+
+/* readchar -- read a character from the remote system, doing all the fancy
+ * timeout stuff.
+ */
+static int
+readchar (int timeout)
+{
+ int c;
+
+ c = serial_readchar (array_desc, abs (timeout));
+
+ if (sr_get_debug () > 5)
+ {
+ putchar (c & 0x7f);
+ debuglogs (5, "readchar: timeout = %d\n", timeout);
+ }
+
+#ifdef LOG_FILE
+ if (isascii (c))
+ putc (c & 0x7f, log_file);
+#endif
+
+ if (c >= 0)
+ return c & 0x7f;
+
+ if (c == SERIAL_TIMEOUT)
+ {
+ if (timeout <= 0)
+ return c; /* Polls shouldn't generate timeout errors */
+ error ("Timeout reading from remote system.");
+#ifdef LOG_FILE
+ fputs ("ERROR: Timeout reading from remote system", log_file);
+#endif
+ }
+ perror_with_name ("readchar");
+}
+
+/*
+ * expect -- scan input from the remote system, until STRING is found.
+ * If DISCARD is non-zero, then discard non-matching input, else print
+ * it out. Let the user break out immediately.
+ */
+static void
+expect (char *string, int discard)
+{
+ char *p = string;
+ int c;
+
+
+ debuglogs (1, "Expecting \"%s\".", string);
+
+ immediate_quit++;
+ while (1)
+ {
+ c = readchar (timeout);
+ if (!isascii (c))
+ continue;
+ if (c == *p++)
+ {
+ if (*p == '\0')
+ {
+ immediate_quit--;
+ debuglogs (4, "Matched");
+ return;
+ }
+ }
+ else
+ {
+ if (!discard)
+ {
+ fputc_unfiltered (c, gdb_stdout);
+ }
+ p = string;
+ }
+ }
+}
+
+/* Keep discarding input until we see the MONITOR array_cmds->prompt.
+
+ The convention for dealing with the expect_prompt is that you
+ o give your command
+ o *then* wait for the expect_prompt.
+
+ Thus the last thing that a procedure does with the serial line
+ will be an expect_prompt(). Exception: array_resume does not
+ wait for the expect_prompt, because the terminal is being handed over
+ to the inferior. However, the next thing which happens after that
+ is a array_wait which does wait for the expect_prompt.
+ Note that this includes abnormal exit, e.g. error(). This is
+ necessary to prevent getting into states from which we can't
+ recover. */
+static void
+expect_prompt (int discard)
+{
+ expect (ARRAY_PROMPT, discard);
+}
+
+/*
+ * junk -- ignore junk characters. Returns a 1 if junk, 0 otherwise
+ */
+static int
+junk (char ch)
+{
+ switch (ch)
+ {
+ case '\0':
+ case ' ':
+ case '-':
+ case '\t':
+ case '\r':
+ case '\n':
+ if (sr_get_debug () > 5)
+ debuglogs (5, "Ignoring \'%c\'.", ch);
+ return 1;
+ default:
+ if (sr_get_debug () > 5)
+ debuglogs (5, "Accepting \'%c\'.", ch);
+ return 0;
+ }
+}
+
+/*
+ * get_hex_digit -- Get a hex digit from the remote system & return its value.
+ * If ignore is nonzero, ignore spaces, newline & tabs.
+ */
+static int
+get_hex_digit (int ignore)
+{
+ static int ch;
+ while (1)
+ {
+ ch = readchar (timeout);
+ if (junk (ch))
+ continue;
+ if (sr_get_debug () > 4)
+ {
+ debuglogs (4, "get_hex_digit() got a 0x%x(%c)", ch, ch);
+ }
+ else
+ {
+#ifdef LOG_FILE /* write to the monitor log */
+ if (log_file != 0x0)
+ {
+ fputs ("get_hex_digit() got a 0x", log_file);
+ fputc (ch, log_file);
+ fputc ('\n', log_file);
+ fflush (log_file);
+ }
+#endif
+ }
+
+ if (ch >= '0' && ch <= '9')
+ return ch - '0';
+ else if (ch >= 'A' && ch <= 'F')
+ return ch - 'A' + 10;
+ else if (ch >= 'a' && ch <= 'f')
+ return ch - 'a' + 10;
+ else if (ch == ' ' && ignore)
+ ;
+ else
+ {
+ expect_prompt (1);
+ debuglogs (4, "Invalid hex digit from remote system. (0x%x)", ch);
+ error ("Invalid hex digit from remote system. (0x%x)", ch);
+ }
+ }
+}
+
+/* get_hex_byte -- Get a byte from monitor and put it in *BYT.
+ * Accept any number leading spaces.
+ */
+static void
+get_hex_byte (char *byt)
+{
+ int val;
+
+ val = get_hex_digit (1) << 4;
+ debuglogs (4, "get_hex_byte() -- Read first nibble 0x%x", val);
+
+ val |= get_hex_digit (0);
+ debuglogs (4, "get_hex_byte() -- Read second nibble 0x%x", val);
+ *byt = val;
+
+ debuglogs (4, "get_hex_byte() -- Read a 0x%x", val);
+}
+
+/*
+ * get_hex_word -- Get N 32-bit words from remote, each preceded by a space,
+ * and put them in registers starting at REGNO.
+ */
+static int
+get_hex_word (void)
+{
+ long val, newval;
+ int i;
+
+ val = 0;
+
+ for (i = 0; i < 8; i++)
+ val = (val << 4) + get_hex_digit (i == 0);
+
+ debuglogs (4, "get_hex_word() got a 0x%x.", val);
+
+ return val;
+}
+
+/* This is called not only when we first attach, but also when the
+ user types "run" after having attached. */
+static void
+array_create_inferior (char *execfile, char *args, char **env)
+{
+ int entry_pt;
+
+ if (args && *args)
+ error ("Can't pass arguments to remote MONITOR process");
+
+ if (execfile == 0 || exec_bfd == 0)
+ error ("No executable file specified");
+
+ entry_pt = (int) bfd_get_start_address (exec_bfd);
+
+/* The "process" (board) is already stopped awaiting our commands, and
+ the program is already downloaded. We just set its PC and go. */
+
+ clear_proceed_status ();
+
+ /* Tell wait_for_inferior that we've started a new process. */
+ init_wait_for_inferior ();
+
+ /* Set up the "saved terminal modes" of the inferior
+ based on what modes we are starting it with. */
+ target_terminal_init ();
+
+ /* Install inferior's terminal modes. */
+ target_terminal_inferior ();
+
+ /* insert_step_breakpoint (); FIXME, do we need this? */
+
+ /* Let 'er rip... */
+ proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0);
+}
+
+/*
+ * array_open -- open a connection to a remote debugger.
+ * NAME is the filename used for communication.
+ */
+static int baudrate = 9600;
+static char dev_name[100];
+
+static void
+array_open (char *args, char *name, int from_tty)
+{
+ char packet[PBUFSIZ];
+
+ if (args == NULL)
+ error ("Use `target %s DEVICE-NAME' to use a serial port, or \n\
+`target %s HOST-NAME:PORT-NUMBER' to use a network connection.", name, name);
+
+/* if (is_open) */
+ array_close (0);
+
+ target_preopen (from_tty);
+ unpush_target (&array_ops);
+
+ tmp_mips_processor_type = "lsi33k"; /* change the default from r3051 */
+ mips_set_processor_type_command ("lsi33k", 0);
+
+ strcpy (dev_name, args);
+ array_desc = serial_open (dev_name);
+
+ if (array_desc == NULL)
+ perror_with_name (dev_name);
+
+ if (baud_rate != -1)
+ {
+ if (serial_setbaudrate (array_desc, baud_rate))
+ {
+ serial_close (array_desc);
+ perror_with_name (name);
+ }
+ }
+
+ serial_raw (array_desc);
+
+#if defined (LOG_FILE)
+ log_file = fopen (LOG_FILE, "w");
+ if (log_file == NULL)
+ perror_with_name (LOG_FILE);
+ fprintf (log_file, "GDB %s (%s", version, host_name);
+ fprintf (log_file, " --target %s)\n", array_ops.to_shortname);
+ fprintf (log_file, "Remote target %s connected to %s\n\n", array_ops.to_shortname, dev_name);
+#endif
+
+ /* see if the target is alive. For a ROM monitor, we can just try to force the
+ expect_prompt to print a few times. For the GDB remote protocol, the application
+ being debugged is sitting at a breakpoint and waiting for GDB to initialize
+ the connection. We force it to give us an empty packet to see if it's alive.
+ */
+ debuglogs (3, "Trying to ACK the target's debug stub");
+ /* unless your are on the new hardware, the old board won't initialize
+ because the '@' doesn't flush output like it does on the new ROMS.
+ */
+ printf_monitor ("@"); /* ask for the last signal */
+ expect_prompt (1); /* See if we get a expect_prompt */
+#ifdef TEST_ARRAY /* skip packet for testing */
+ make_gdb_packet (packet, "?"); /* ask for a bogus packet */
+ if (array_send_packet (packet) == 0)
+ error ("Couldn't transmit packet\n");
+ printf_monitor ("@\n"); /* force it to flush stdout */
+ expect_prompt (1); /* See if we get a expect_prompt */
+#endif
+ push_target (&array_ops);
+ if (from_tty)
+ printf ("Remote target %s connected to %s\n", array_ops.to_shortname, dev_name);
+}
+
+/*
+ * array_close -- Close out all files and local state before this
+ * target loses control.
+ */
+
+static void
+array_close (int quitting)
+{
+ serial_close (array_desc);
+ array_desc = NULL;
+
+ debuglogs (1, "array_close (quitting=%d)", quitting);
+
+#if defined (LOG_FILE)
+ if (log_file)
+ {
+ if (ferror (log_file))
+ printf_filtered ("Error writing log file.\n");
+ if (fclose (log_file) != 0)
+ printf_filtered ("Error closing log file.\n");
+ }
+#endif
+}
+
+/*
+ * array_detach -- terminate the open connection to the remote
+ * debugger. Use this when you want to detach and do something
+ * else with your gdb.
+ */
+static void
+array_detach (int from_tty)
+{
+
+ debuglogs (1, "array_detach ()");
+
+ pop_target (); /* calls array_close to do the real work */
+ if (from_tty)
+ printf ("Ending remote %s debugging\n", target_shortname);
+}
+
+/*
+ * array_attach -- attach GDB to the target.
+ */
+static void
+array_attach (char *args, int from_tty)
+{
+ if (from_tty)
+ printf ("Starting remote %s debugging\n", target_shortname);
+
+ debuglogs (1, "array_attach (args=%s)", args);
+
+ printf_monitor ("go %x\n");
+ /* swallow the echo. */
+ expect ("go %x\n", 1);
+}
+
+/*
+ * array_resume -- Tell the remote machine to resume.
+ */
+static void
+array_resume (ptid_t ptid, int step, enum target_signal sig)
+{
+ debuglogs (1, "array_resume (step=%d, sig=%d)", step, sig);
+
+ if (step)
+ {
+ printf_monitor ("s\n");
+ }
+ else
+ {
+ printf_monitor ("go\n");
+ }
+}
+
+#define TMPBUFSIZ 5
+
+/*
+ * array_wait -- Wait until the remote machine stops, then return,
+ * storing status in status just as `wait' would.
+ */
+static ptid_t
+array_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ int old_timeout = timeout;
+ int result, i;
+ char c;
+ struct serial *tty_desc;
+ serial_ttystate ttystate;
+
+ debuglogs (1, "array_wait (), printing extraneous text.");
+
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = 0;
+
+ timeout = 0; /* Don't time out -- user program is running. */
+
+#if !defined(__GO32__) && !defined(__MSDOS__) && !defined(_WIN32)
+ tty_desc = serial_fdopen (0);
+ ttystate = serial_get_tty_state (tty_desc);
+ serial_raw (tty_desc);
+
+ i = 0;
+ /* poll on the serial port and the keyboard. */
+ while (1)
+ {
+ c = readchar (timeout);
+ if (c > 0)
+ {
+ if (c == *(ARRAY_PROMPT + i))
+ {
+ if (++i >= strlen (ARRAY_PROMPT))
+ { /* matched the prompt */
+ debuglogs (4, "array_wait(), got the expect_prompt.");
+ break;
+ }
+ }
+ else
+ { /* not the prompt */
+ i = 0;
+ }
+ fputc_unfiltered (c, gdb_stdout);
+ gdb_flush (gdb_stdout);
+ }
+ c = serial_readchar (tty_desc, timeout);
+ if (c > 0)
+ {
+ serial_write (array_desc, &c, 1);
+ /* do this so it looks like there's keyboard echo */
+ if (c == 3) /* exit on Control-C */
+ break;
+#if 0
+ fputc_unfiltered (c, gdb_stdout);
+ gdb_flush (gdb_stdout);
+#endif
+ }
+ }
+ serial_set_tty_state (tty_desc, ttystate);
+#else
+ expect_prompt (1);
+ debuglogs (4, "array_wait(), got the expect_prompt.");
+#endif
+
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+
+ timeout = old_timeout;
+
+ return inferior_ptid;
+}
+
+/*
+ * array_fetch_registers -- read the remote registers into the
+ * block regs.
+ */
+static void
+array_fetch_registers (int ignored)
+{
+ char *reg = alloca (MAX_REGISTER_RAW_SIZE);
+ int regno;
+ char *p;
+ char *packet = alloca (PBUFSIZ);
+
+ debuglogs (1, "array_fetch_registers (ignored=%d)\n", ignored);
+
+ memset (packet, 0, PBUFSIZ);
+ make_gdb_packet (packet, "g");
+ if (array_send_packet (packet) == 0)
+ error ("Couldn't transmit packet\n");
+ if (array_get_packet (packet) == 0)
+ error ("Couldn't receive packet\n");
+ /* FIXME: read bytes from packet */
+ debuglogs (4, "array_fetch_registers: Got a \"%s\" back\n", packet);
+ for (regno = 0; regno <= PC_REGNUM + 4; regno++)
+ {
+ /* supply register stores in target byte order, so swap here */
+ /* FIXME: convert from ASCII hex to raw bytes */
+ LONGEST i = ascii2hexword (packet + (regno * 8));
+ debuglogs (5, "Adding register %d = %x\n", regno, i);
+ store_unsigned_integer (&reg, REGISTER_RAW_SIZE (regno), i);
+ supply_register (regno, (char *) &reg);
+ }
+}
+
+/*
+ * This is unused by targets like this one that use a
+ * protocol based on GDB's remote protocol.
+ */
+static void
+array_fetch_register (int ignored)
+{
+ array_fetch_registers (0 /* ignored */);
+}
+
+/*
+ * Get all the registers from the targets. They come back in a large array.
+ */
+static void
+array_store_registers (int ignored)
+{
+ int regno;
+ unsigned long i;
+ char packet[PBUFSIZ];
+ char buf[PBUFSIZ];
+ char num[9];
+
+ debuglogs (1, "array_store_registers()");
+
+ memset (packet, 0, PBUFSIZ);
+ memset (buf, 0, PBUFSIZ);
+ buf[0] = 'G';
+
+ /* Unimplemented registers read as all bits zero. */
+ /* FIXME: read bytes from packet */
+ for (regno = 0; regno < 41; regno++)
+ { /* FIXME */
+ /* supply register stores in target byte order, so swap here */
+ /* FIXME: convert from ASCII hex to raw bytes */
+ i = (unsigned long) read_register (regno);
+ hexword2ascii (num, i);
+ strcpy (buf + (regno * 8) + 1, num);
+ }
+ *(buf + (regno * 8) + 2) = 0;
+ make_gdb_packet (packet, buf);
+ if (array_send_packet (packet) == 0)
+ error ("Couldn't transmit packet\n");
+ if (array_get_packet (packet) == 0)
+ error ("Couldn't receive packet\n");
+
+ registers_changed ();
+}
+
+/*
+ * This is unused by targets like this one that use a
+ * protocol based on GDB's remote protocol.
+ */
+static void
+array_store_register (int ignored)
+{
+ array_store_registers (0 /* ignored */);
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+static void
+array_prepare_to_store (void)
+{
+ /* Do nothing, since we can store individual regs */
+}
+
+static void
+array_files_info (void)
+{
+ printf ("\tAttached to %s at %d baud.\n",
+ dev_name, baudrate);
+}
+
+/*
+ * array_write_inferior_memory -- Copy LEN bytes of data from debugger
+ * memory at MYADDR to inferior's memory at MEMADDR. Returns length moved.
+ */
+static int
+array_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
+{
+ unsigned long i;
+ int j;
+ char packet[PBUFSIZ];
+ char buf[PBUFSIZ];
+ char num[9];
+ char *p;
+
+ debuglogs (1, "array_write_inferior_memory (memaddr=0x%x, myaddr=0x%x, len=%d)", memaddr, myaddr, len);
+ memset (buf, '\0', PBUFSIZ); /* this also sets the string terminator */
+ p = buf;
+
+ *p++ = 'M'; /* The command to write memory */
+ hexword2ascii (num, memaddr); /* convert the address */
+ strcpy (p, num); /* copy the address */
+ p += 8;
+ *p++ = ','; /* add comma delimeter */
+ hexword2ascii (num, len); /* Get the length as a 4 digit number */
+ *p++ = num[4];
+ *p++ = num[5];
+ *p++ = num[6];
+ *p++ = num[7];
+ *p++ = ':'; /* add the colon delimeter */
+ for (j = 0; j < len; j++)
+ { /* copy the data in after converting it */
+ *p++ = tohex ((myaddr[j] >> 4) & 0xf);
+ *p++ = tohex (myaddr[j] & 0xf);
+ }
+
+ make_gdb_packet (packet, buf);
+ if (array_send_packet (packet) == 0)
+ error ("Couldn't transmit packet\n");
+ if (array_get_packet (packet) == 0)
+ error ("Couldn't receive packet\n");
+
+ return len;
+}
+
+/*
+ * array_read_inferior_memory -- read LEN bytes from inferior memory
+ * at MEMADDR. Put the result at debugger address MYADDR. Returns
+ * length moved.
+ */
+static int
+array_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ int j;
+ char buf[20];
+ char packet[PBUFSIZ];
+ int count; /* Number of bytes read so far. */
+ unsigned long startaddr; /* Starting address of this pass. */
+ int len_this_pass; /* Number of bytes to read in this pass. */
+
+ debuglogs (1, "array_read_inferior_memory (memaddr=0x%x, myaddr=0x%x, len=%d)", memaddr, myaddr, len);
+
+ /* Note that this code works correctly if startaddr is just less
+ than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
+ thing). That is, something like
+ array_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
+ works--it never adds len To memaddr and gets 0. */
+ /* However, something like
+ array_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
+ doesn't need to work. Detect it and give up if there's an attempt
+ to do that. */
+ if (((memaddr - 1) + len) < memaddr)
+ {
+ errno = EIO;
+ return 0;
+ }
+
+ for (count = 0, startaddr = memaddr; count < len; startaddr += len_this_pass)
+ {
+ /* Try to align to 16 byte boundry (why?) */
+ len_this_pass = 16;
+ if ((startaddr % 16) != 0)
+ {
+ len_this_pass -= startaddr % 16;
+ }
+ /* Only transfer bytes we need */
+ if (len_this_pass > (len - count))
+ {
+ len_this_pass = (len - count);
+ }
+ /* Fetch the bytes */
+ debuglogs (3, "read %d bytes from inferior address %x", len_this_pass,
+ startaddr);
+ sprintf (buf, "m%08lx,%04x", startaddr, len_this_pass);
+ make_gdb_packet (packet, buf);
+ if (array_send_packet (packet) == 0)
+ {
+ error ("Couldn't transmit packet\n");
+ }
+ if (array_get_packet (packet) == 0)
+ {
+ error ("Couldn't receive packet\n");
+ }
+ if (*packet == 0)
+ {
+ error ("Got no data in the GDB packet\n");
+ }
+ /* Pick packet apart and xfer bytes to myaddr */
+ debuglogs (4, "array_read_inferior_memory: Got a \"%s\" back\n", packet);
+ for (j = 0; j < len_this_pass; j++)
+ {
+ /* extract the byte values */
+ myaddr[count++] = from_hex (*(packet + (j * 2))) * 16 + from_hex (*(packet + (j * 2) + 1));
+ debuglogs (5, "myaddr[%d] set to %x\n", count - 1, myaddr[count - 1]);
+ }
+ }
+ return (count);
+}
+
+/* Transfer LEN bytes between GDB address MYADDR and target address
+ MEMADDR. If WRITE is non-zero, transfer them to the target,
+ otherwise transfer them from the target. TARGET is unused.
+
+ Returns the number of bytes transferred. */
+
+static int
+array_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib, struct target_ops *target)
+{
+ if (write)
+ return array_write_inferior_memory (memaddr, myaddr, len);
+ else
+ return array_read_inferior_memory (memaddr, myaddr, len);
+}
+
+static void
+array_kill (char *args, int from_tty)
+{
+ return; /* ignore attempts to kill target system */
+}
+
+/* Clean up when a program exits.
+ The program actually lives on in the remote processor's RAM, and may be
+ run again without a download. Don't leave it full of breakpoint
+ instructions. */
+
+static void
+array_mourn_inferior (void)
+{
+ remove_breakpoints ();
+ generic_mourn_inferior (); /* Do all the proper things now */
+}
+
+#define MAX_ARRAY_BREAKPOINTS 16
+
+static CORE_ADDR breakaddr[MAX_ARRAY_BREAKPOINTS] =
+{0};
+
+/*
+ * array_insert_breakpoint -- add a breakpoint
+ */
+static int
+array_insert_breakpoint (CORE_ADDR addr, char *shadow)
+{
+ int i;
+ int bp_size = 0;
+ CORE_ADDR bp_addr = addr;
+
+ debuglogs (1, "array_insert_breakpoint() addr = 0x%x", addr);
+ BREAKPOINT_FROM_PC (&bp_addr, &bp_size);
+
+ for (i = 0; i <= MAX_ARRAY_BREAKPOINTS; i++)
+ {
+ if (breakaddr[i] == 0)
+ {
+ breakaddr[i] = addr;
+ if (sr_get_debug () > 4)
+ printf ("Breakpoint at %s\n", paddr_nz (addr));
+ array_read_inferior_memory (bp_addr, shadow, bp_size);
+ printf_monitor ("b 0x%x\n", addr);
+ expect_prompt (1);
+ return 0;
+ }
+ }
+
+ fprintf_unfiltered (gdb_stderr, "Too many breakpoints (> 16) for monitor\n");
+ return 1;
+}
+
+/*
+ * _remove_breakpoint -- Tell the monitor to remove a breakpoint
+ */
+static int
+array_remove_breakpoint (CORE_ADDR addr, char *shadow)
+{
+ int i;
+
+ debuglogs (1, "array_remove_breakpoint() addr = 0x%x", addr);
+
+ for (i = 0; i < MAX_ARRAY_BREAKPOINTS; i++)
+ {
+ if (breakaddr[i] == addr)
+ {
+ breakaddr[i] = 0;
+ /* some monitors remove breakpoints based on the address */
+ printf_monitor ("bd %x\n", i);
+ expect_prompt (1);
+ return 0;
+ }
+ }
+ fprintf_unfiltered (gdb_stderr,
+ "Can't find breakpoint associated with 0x%s\n",
+ paddr_nz (addr));
+ return 1;
+}
+
+static void
+array_stop (void)
+{
+ debuglogs (1, "array_stop()");
+ printf_monitor ("\003");
+ expect_prompt (1);
+}
+
+/*
+ * array_command -- put a command string, in args, out to MONITOR.
+ * Output from MONITOR is placed on the users terminal until the
+ * expect_prompt is seen. FIXME
+ */
+static void
+monitor_command (char *args, int fromtty)
+{
+ debuglogs (1, "monitor_command (args=%s)", args);
+
+ if (array_desc == NULL)
+ error ("monitor target not open.");
+
+ if (!args)
+ error ("Missing command.");
+
+ printf_monitor ("%s\n", args);
+ expect_prompt (0);
+}
+
+/*
+ * make_gdb_packet -- make a GDB packet. The data is always ASCII.
+ * A debug packet whose contents are <data>
+ * is encapsulated for transmission in the form:
+ *
+ * $ <data> # CSUM1 CSUM2
+ *
+ * <data> must be ASCII alphanumeric and cannot include characters
+ * '$' or '#'. If <data> starts with two characters followed by
+ * ':', then the existing stubs interpret this as a sequence number.
+ *
+ * CSUM1 and CSUM2 are ascii hex representation of an 8-bit
+ * checksum of <data>, the most significant nibble is sent first.
+ * the hex digits 0-9,a-f are used.
+ *
+ */
+static void
+make_gdb_packet (char *buf, char *data)
+{
+ int i;
+ unsigned char csum = 0;
+ int cnt;
+ char *p;
+
+ debuglogs (3, "make_gdb_packet(%s)\n", data);
+ cnt = strlen (data);
+ if (cnt > PBUFSIZ)
+ error ("make_gdb_packet(): to much data\n");
+
+ /* start with the packet header */
+ p = buf;
+ *p++ = '$';
+
+ /* calculate the checksum */
+ for (i = 0; i < cnt; i++)
+ {
+ csum += data[i];
+ *p++ = data[i];
+ }
+
+ /* terminate the data with a '#' */
+ *p++ = '#';
+
+ /* add the checksum as two ascii digits */
+ *p++ = tohex ((csum >> 4) & 0xf);
+ *p++ = tohex (csum & 0xf);
+ *p = 0x0; /* Null terminator on string */
+}
+
+/*
+ * array_send_packet -- send a GDB packet to the target with error handling. We
+ * get a '+' (ACK) back if the packet is received and the checksum
+ * matches. Otherwise a '-' (NAK) is returned. It returns a 1 for a
+ * successful transmition, or a 0 for a failure.
+ */
+static int
+array_send_packet (char *packet)
+{
+ int c, retries, i;
+ char junk[PBUFSIZ];
+
+ retries = 0;
+
+#if 0
+ /* scan the packet to make sure it only contains valid characters.
+ this may sound silly, but sometimes a garbled packet will hang
+ the target board. We scan the whole thing, then print the error
+ message.
+ */
+ for (i = 0; i < strlen (packet); i++)
+ {
+ debuglogs (5, "array_send_packet(): Scanning \'%c\'\n", packet[i]);
+ /* legit hex numbers or command */
+ if ((isxdigit (packet[i])) || (isalpha (packet[i])))
+ continue;
+ switch (packet[i])
+ {
+ case '+': /* ACK */
+ case '-': /* NAK */
+ case '#': /* end of packet */
+ case '$': /* start of packet */
+ continue;
+ default: /* bogus character */
+ retries++;
+ debuglogs (4, "array_send_packet(): Found a non-ascii digit \'%c\' in the packet.\n", packet[i]);
+ }
+ }
+#endif
+
+ if (retries > 0)
+ error ("Can't send packet, found %d non-ascii characters", retries);
+
+ /* ok, try to send the packet */
+ retries = 0;
+ while (retries++ <= 10)
+ {
+ printf_monitor ("%s", packet);
+
+ /* read until either a timeout occurs (-2) or '+' is read */
+ while (retries <= 10)
+ {
+ c = readchar (-timeout);
+ debuglogs (3, "Reading a GDB protocol packet... Got a '%c'\n", c);
+ switch (c)
+ {
+ case '+':
+ debuglogs (3, "Got Ack\n");
+ return 1;
+ case SERIAL_TIMEOUT:
+ debuglogs (3, "Timed out reading serial port\n");
+ printf_monitor ("@"); /* resync with the monitor */
+ expect_prompt (1); /* See if we get a expect_prompt */
+ break; /* Retransmit buffer */
+ case '-':
+ debuglogs (3, "Got NAK\n");
+ printf_monitor ("@"); /* resync with the monitor */
+ expect_prompt (1); /* See if we get a expect_prompt */
+ break;
+ case '$':
+ /* it's probably an old response, or the echo of our command.
+ * just gobble up the packet and ignore it.
+ */
+ debuglogs (3, "Got a junk packet\n");
+ i = 0;
+ do
+ {
+ c = readchar (timeout);
+ junk[i++] = c;
+ }
+ while (c != '#');
+ c = readchar (timeout);
+ junk[i++] = c;
+ c = readchar (timeout);
+ junk[i++] = c;
+ junk[i++] = '\0';
+ debuglogs (3, "Reading a junk packet, got a \"%s\"\n", junk);
+ continue; /* Now, go look for next packet */
+ default:
+ continue;
+ }
+ retries++;
+ debuglogs (3, "Retransmitting packet \"%s\"\n", packet);
+ break; /* Here to retransmit */
+ }
+ } /* outer while */
+ return 0;
+}
+
+/*
+ * array_get_packet -- get a GDB packet from the target. Basically we read till we
+ * see a '#', then check the checksum. It returns a 1 if it's gotten a
+ * packet, or a 0 it the packet wasn't transmitted correctly.
+ */
+static int
+array_get_packet (char *packet)
+{
+ int c;
+ int retries;
+ unsigned char csum;
+ unsigned char pktcsum;
+ char *bp;
+
+ csum = 0;
+ bp = packet;
+
+ memset (packet, 1, PBUFSIZ);
+ retries = 0;
+ while (retries <= 10)
+ {
+ do
+ {
+ c = readchar (timeout);
+ if (c == SERIAL_TIMEOUT)
+ {
+ debuglogs (3, "array_get_packet: got time out from serial port.\n");
+ }
+ debuglogs (3, "Waiting for a '$', got a %c\n", c);
+ }
+ while (c != '$');
+
+ retries = 0;
+ while (retries <= 10)
+ {
+ c = readchar (timeout);
+ debuglogs (3, "array_get_packet: got a '%c'\n", c);
+ switch (c)
+ {
+ case SERIAL_TIMEOUT:
+ debuglogs (3, "Timeout in mid-packet, retrying\n");
+ return 0;
+ case '$':
+ debuglogs (3, "Saw new packet start in middle of old one\n");
+ return 0; /* Start a new packet, count retries */
+ case '#':
+ *bp = '\0';
+ pktcsum = from_hex (readchar (timeout)) << 4;
+ pktcsum |= from_hex (readchar (timeout));
+ if (csum == 0)
+ debuglogs (3, "\nGDB packet checksum zero, must be a bogus packet\n");
+ if (csum == pktcsum)
+ {
+ debuglogs (3, "\nGDB packet checksum correct, packet data is \"%s\",\n", packet);
+ printf_monitor ("@");
+ expect_prompt (1);
+ return 1;
+ }
+ debuglogs (3, "Bad checksum, sentsum=0x%x, csum=0x%x\n", pktcsum, csum);
+ return 0;
+ case '*': /* Run length encoding */
+ debuglogs (5, "Run length encoding in packet\n");
+ csum += c;
+ c = readchar (timeout);
+ csum += c;
+ c = c - ' ' + 3; /* Compute repeat count */
+
+ if (c > 0 && c < 255 && bp + c - 1 < packet + PBUFSIZ - 1)
+ {
+ memset (bp, *(bp - 1), c);
+ bp += c;
+ continue;
+ }
+ *bp = '\0';
+ printf_filtered ("Repeat count %d too large for buffer.\n", c);
+ return 0;
+
+ default:
+ if ((!isxdigit (c)) && (!ispunct (c)))
+ debuglogs (4, "Got a non-ascii digit \'%c\'.\\n", c);
+ if (bp < packet + PBUFSIZ - 1)
+ {
+ *bp++ = c;
+ csum += c;
+ continue;
+ }
+
+ *bp = '\0';
+ puts_filtered ("Remote packet too long.\n");
+ return 0;
+ }
+ }
+ }
+ return 0; /* exceeded retries */
+}
+
+/*
+ * ascii2hexword -- convert an ascii number represented by 8 digits to a hex value.
+ */
+static unsigned long
+ascii2hexword (unsigned char *mem)
+{
+ unsigned long val;
+ int i;
+ char buf[9];
+
+ val = 0;
+ for (i = 0; i < 8; i++)
+ {
+ val <<= 4;
+ if (mem[i] >= 'A' && mem[i] <= 'F')
+ val = val + mem[i] - 'A' + 10;
+ if (mem[i] >= 'a' && mem[i] <= 'f')
+ val = val + mem[i] - 'a' + 10;
+ if (mem[i] >= '0' && mem[i] <= '9')
+ val = val + mem[i] - '0';
+ buf[i] = mem[i];
+ }
+ buf[8] = '\0';
+ debuglogs (4, "ascii2hexword() got a 0x%x from %s(%x).\n", val, buf, mem);
+ return val;
+}
+
+/*
+ * ascii2hexword -- convert a hex value to an ascii number represented by 8
+ * digits.
+ */
+static void
+hexword2ascii (unsigned char *mem, unsigned long num)
+{
+ int i;
+ unsigned char ch;
+
+ debuglogs (4, "hexword2ascii() converting %x ", num);
+ for (i = 7; i >= 0; i--)
+ {
+ mem[i] = tohex ((num >> 4) & 0xf);
+ mem[i] = tohex (num & 0xf);
+ num = num >> 4;
+ }
+ mem[8] = '\0';
+ debuglogs (4, "\tto a %s", mem);
+}
+
+/* Convert hex digit A to a number. */
+static int
+from_hex (int a)
+{
+ if (a == 0)
+ return 0;
+
+ debuglogs (4, "from_hex got a 0x%x(%c)\n", a, a);
+ if (a >= '0' && a <= '9')
+ return a - '0';
+ if (a >= 'a' && a <= 'f')
+ return a - 'a' + 10;
+ if (a >= 'A' && a <= 'F')
+ return a - 'A' + 10;
+ else
+ {
+ error ("Reply contains invalid hex digit 0x%x", a);
+ }
+}
+
+/* Convert number NIB to a hex digit. */
+static int
+tohex (int nib)
+{
+ if (nib < 10)
+ return '0' + nib;
+ else
+ return 'a' + nib - 10;
+}
+
+/*
+ * _initialize_remote_monitors -- setup a few addtitional commands that
+ * are usually only used by monitors.
+ */
+void
+_initialize_remote_monitors (void)
+{
+ /* generic monitor command */
+ add_com ("monitor", class_obscure, monitor_command,
+ "Send a command to the debug monitor.");
+
+}
+
+/*
+ * _initialize_array -- do any special init stuff for the target.
+ */
+void
+_initialize_array (void)
+{
+ init_array_ops ();
+ add_target (&array_ops);
+}
diff --git a/gdb/remote-bug.c b/gdb/remote-bug.c
new file mode 100644
index 00000000000..f74ce9768e2
--- /dev/null
+++ b/gdb/remote-bug.c
@@ -0,0 +1,1027 @@
+/* Remote debugging interface for Motorola's MVME187BUG monitor, an embedded
+ monitor for the m88k.
+
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+ 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Support. Written by K. Richard Pixley.
+
+ 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 "defs.h"
+#include "inferior.h"
+#include "gdb_string.h"
+#include "regcache.h"
+#include <ctype.h>
+#include <fcntl.h>
+#include <setjmp.h>
+#include <errno.h>
+
+#include "terminal.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+
+#include "serial.h"
+#include "remote-utils.h"
+
+/* External data declarations */
+extern int stop_soon_quietly; /* for wait_for_inferior */
+
+/* Forward data declarations */
+extern struct target_ops bug_ops; /* Forward declaration */
+
+/* Forward function declarations */
+static int bug_clear_breakpoints (void);
+
+static int bug_read_memory (CORE_ADDR memaddr,
+ unsigned char *myaddr, int len);
+
+static int bug_write_memory (CORE_ADDR memaddr,
+ unsigned char *myaddr, int len);
+
+/* This variable is somewhat arbitrary. It's here so that it can be
+ set from within a running gdb. */
+
+static int srec_max_retries = 3;
+
+/* Each S-record download to the target consists of an S0 header
+ record, some number of S3 data records, and one S7 termination
+ record. I call this download a "frame". Srec_frame says how many
+ bytes will be represented in each frame. */
+
+#define SREC_SIZE 160
+static int srec_frame = SREC_SIZE;
+
+/* This variable determines how many bytes will be represented in each
+ S3 s-record. */
+
+static int srec_bytes = 40;
+
+/* At one point it appeared to me as though the bug monitor could not
+ really be expected to receive two sequential characters at 9600
+ baud reliably. Echo-pacing is an attempt to force data across the
+ line even in this condition. Specifically, in echo-pace mode, each
+ character is sent one at a time and we look for the echo before
+ sending the next. This is excruciatingly slow. */
+
+static int srec_echo_pace = 0;
+
+/* How long to wait after an srec for a possible error message.
+ Similar to the above, I tried sleeping after sending each S3 record
+ in hopes that I might actually see error messages from the bug
+ monitor. This might actually work if we were to use sleep
+ intervals smaller than 1 second. */
+
+static int srec_sleep = 0;
+
+/* Every srec_noise records, flub the checksum. This is a debugging
+ feature. Set the variable to something other than 1 in order to
+ inject *deliberate* checksum errors. One might do this if one
+ wanted to test error handling and recovery. */
+
+static int srec_noise = 0;
+
+/* Called when SIGALRM signal sent due to alarm() timeout. */
+
+/* Number of SIGTRAPs we need to simulate. That is, the next
+ NEED_ARTIFICIAL_TRAP calls to bug_wait should just return
+ SIGTRAP without actually waiting for anything. */
+
+static int need_artificial_trap = 0;
+
+/*
+ * Download a file specified in 'args', to the bug.
+ */
+
+static void
+bug_load (char *args, int fromtty)
+{
+ bfd *abfd;
+ asection *s;
+ char buffer[1024];
+
+ sr_check_open ();
+
+ inferior_ptid = null_ptid;
+ abfd = bfd_openr (args, 0);
+ if (!abfd)
+ {
+ printf_filtered ("Unable to open file %s\n", args);
+ return;
+ }
+
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ {
+ printf_filtered ("File is not an object file\n");
+ return;
+ }
+
+ s = abfd->sections;
+ while (s != (asection *) NULL)
+ {
+ srec_frame = SREC_SIZE;
+ if (s->flags & SEC_LOAD)
+ {
+ int i;
+
+ char *buffer = xmalloc (srec_frame);
+
+ printf_filtered ("%s\t: 0x%4lx .. 0x%4lx ", s->name, s->vma, s->vma + s->_raw_size);
+ gdb_flush (gdb_stdout);
+ for (i = 0; i < s->_raw_size; i += srec_frame)
+ {
+ if (srec_frame > s->_raw_size - i)
+ srec_frame = s->_raw_size - i;
+
+ bfd_get_section_contents (abfd, s, buffer, i, srec_frame);
+ bug_write_memory (s->vma + i, buffer, srec_frame);
+ printf_filtered ("*");
+ gdb_flush (gdb_stdout);
+ }
+ printf_filtered ("\n");
+ xfree (buffer);
+ }
+ s = s->next;
+ }
+ sprintf (buffer, "rs ip %lx", (unsigned long) abfd->start_address);
+ sr_write_cr (buffer);
+ gr_expect_prompt ();
+}
+
+#if 0
+static char *
+get_word (char **p)
+{
+ char *s = *p;
+ char *word;
+ char *copy;
+ size_t len;
+
+ while (isspace (*s))
+ s++;
+
+ word = s;
+
+ len = 0;
+
+ while (*s && !isspace (*s))
+ {
+ s++;
+ len++;
+
+ }
+ copy = xmalloc (len + 1);
+ memcpy (copy, word, len);
+ copy[len] = 0;
+ *p = s;
+ return copy;
+}
+#endif
+
+static struct gr_settings bug_settings =
+{
+ "Bug>", /* prompt */
+ &bug_ops, /* ops */
+ bug_clear_breakpoints, /* clear_all_breakpoints */
+ gr_generic_checkin, /* checkin */
+};
+
+static char *cpu_check_strings[] =
+{
+ "=",
+ "Invalid Register",
+};
+
+static void
+bug_open (char *args, int from_tty)
+{
+ if (args == NULL)
+ args = "";
+
+ gr_open (args, from_tty, &bug_settings);
+ /* decide *now* whether we are on an 88100 or an 88110 */
+ sr_write_cr ("rs cr06");
+ sr_expect ("rs cr06");
+
+ switch (gr_multi_scan (cpu_check_strings, 0))
+ {
+ case 0: /* this is an m88100 */
+ target_is_m88110 = 0;
+ break;
+ case 1: /* this is an m88110 */
+ target_is_m88110 = 1;
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+}
+
+/* Tell the remote machine to resume. */
+
+void
+bug_resume (ptid_t ptid, int step, enum target_signal sig)
+{
+ if (step)
+ {
+ sr_write_cr ("t");
+
+ /* Force the next bug_wait to return a trap. Not doing anything
+ about I/O from the target means that the user has to type
+ "continue" to see any. FIXME, this should be fixed. */
+ need_artificial_trap = 1;
+ }
+ else
+ sr_write_cr ("g");
+
+ return;
+}
+
+/* Wait until the remote machine stops, then return,
+ storing status in STATUS just as `wait' would. */
+
+static char *wait_strings[] =
+{
+ "At Breakpoint",
+ "Exception: Data Access Fault (Local Bus Timeout)",
+ "\r8??\?-Bug>", /* The '\?' avoids creating a trigraph */
+ "\r197-Bug>",
+ NULL,
+};
+
+ptid_t
+bug_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ int old_timeout = sr_get_timeout ();
+ int old_immediate_quit = immediate_quit;
+
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = 0;
+
+ /* read off leftovers from resume so that the rest can be passed
+ back out as stdout. */
+ if (need_artificial_trap == 0)
+ {
+ sr_expect ("Effective address: ");
+ (void) sr_get_hex_word ();
+ sr_expect ("\r\n");
+ }
+
+ sr_set_timeout (-1); /* Don't time out -- user program is running. */
+ immediate_quit = 1; /* Helps ability to QUIT */
+
+ switch (gr_multi_scan (wait_strings, need_artificial_trap == 0))
+ {
+ case 0: /* breakpoint case */
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ /* user output from the target can be discarded here. (?) */
+ gr_expect_prompt ();
+ break;
+
+ case 1: /* bus error */
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_BUS;
+ /* user output from the target can be discarded here. (?) */
+ gr_expect_prompt ();
+ break;
+
+ case 2: /* normal case */
+ case 3:
+ if (need_artificial_trap != 0)
+ {
+ /* stepping */
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ need_artificial_trap--;
+ break;
+ }
+ else
+ {
+ /* exit case */
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = 0;
+ break;
+ }
+
+ case -1: /* trouble */
+ default:
+ fprintf_filtered (gdb_stderr,
+ "Trouble reading target during wait\n");
+ break;
+ }
+
+ sr_set_timeout (old_timeout);
+ immediate_quit = old_immediate_quit;
+ return inferior_ptid;
+}
+
+/* Return the name of register number REGNO
+ in the form input and output by bug.
+
+ Returns a pointer to a static buffer containing the answer. */
+static char *
+get_reg_name (int regno)
+{
+ static char *rn[] =
+ {
+ "r00", "r01", "r02", "r03", "r04", "r05", "r06", "r07",
+ "r08", "r09", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+
+ /* these get confusing because we omit a few and switch some ordering around. */
+
+ "cr01", /* 32 = psr */
+ "fcr62", /* 33 = fpsr */
+ "fcr63", /* 34 = fpcr */
+ "ip", /* this is something of a cheat. */
+ /* 35 = sxip */
+ "cr05", /* 36 = snip */
+ "cr06", /* 37 = sfip */
+
+ "x00", "x01", "x02", "x03", "x04", "x05", "x06", "x07",
+ "x08", "x09", "x10", "x11", "x12", "x13", "x14", "x15",
+ "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
+ "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31",
+ };
+
+ return rn[regno];
+}
+
+#if 0 /* not currently used */
+/* Read from remote while the input matches STRING. Return zero on
+ success, -1 on failure. */
+
+static int
+bug_scan (char *s)
+{
+ int c;
+
+ while (*s)
+ {
+ c = sr_readchar ();
+ if (c != *s++)
+ {
+ fflush (stdout);
+ printf ("\nNext character is '%c' - %d and s is \"%s\".\n", c, c, --s);
+ return (-1);
+ }
+ }
+
+ return (0);
+}
+#endif /* never */
+
+static int
+bug_srec_write_cr (char *s)
+{
+ char *p = s;
+
+ if (srec_echo_pace)
+ for (p = s; *p; ++p)
+ {
+ if (sr_get_debug () > 0)
+ printf ("%c", *p);
+
+ do
+ serial_write (sr_get_desc (), p, 1);
+ while (sr_pollchar () != *p);
+ }
+ else
+ {
+ sr_write_cr (s);
+/* return(bug_scan (s) || bug_scan ("\n")); */
+ }
+
+ return (0);
+}
+
+/* Store register REGNO, or all if REGNO == -1. */
+
+static void
+bug_fetch_register (int regno)
+{
+ sr_check_open ();
+
+ if (regno == -1)
+ {
+ int i;
+
+ for (i = 0; i < NUM_REGS; ++i)
+ bug_fetch_register (i);
+ }
+ else if (target_is_m88110 && regno == SFIP_REGNUM)
+ {
+ /* m88110 has no sfip. */
+ long l = 0;
+ supply_register (regno, (char *) &l);
+ }
+ else if (regno < XFP_REGNUM)
+ {
+ char buffer[MAX_REGISTER_RAW_SIZE];
+
+ sr_write ("rs ", 3);
+ sr_write_cr (get_reg_name (regno));
+ sr_expect ("=");
+ store_unsigned_integer (buffer, REGISTER_RAW_SIZE (regno),
+ sr_get_hex_word ());
+ gr_expect_prompt ();
+ supply_register (regno, buffer);
+ }
+ else
+ {
+ /* Float register so we need to parse a strange data format. */
+ long p;
+ unsigned char fpreg_buf[10];
+
+ sr_write ("rs ", 3);
+ sr_write (get_reg_name (regno), strlen (get_reg_name (regno)));
+ sr_write_cr (";d");
+ sr_expect ("rs");
+ sr_expect (get_reg_name (regno));
+ sr_expect (";d");
+ sr_expect ("=");
+
+ /* sign */
+ p = sr_get_hex_digit (1);
+ fpreg_buf[0] = p << 7;
+
+ /* exponent */
+ sr_expect ("_");
+ p = sr_get_hex_digit (1);
+ fpreg_buf[0] += (p << 4);
+ fpreg_buf[0] += sr_get_hex_digit (1);
+
+ fpreg_buf[1] = sr_get_hex_digit (1) << 4;
+
+ /* fraction */
+ sr_expect ("_");
+ fpreg_buf[1] += sr_get_hex_digit (1);
+
+ fpreg_buf[2] = (sr_get_hex_digit (1) << 4) + sr_get_hex_digit (1);
+ fpreg_buf[3] = (sr_get_hex_digit (1) << 4) + sr_get_hex_digit (1);
+ fpreg_buf[4] = (sr_get_hex_digit (1) << 4) + sr_get_hex_digit (1);
+ fpreg_buf[5] = (sr_get_hex_digit (1) << 4) + sr_get_hex_digit (1);
+ fpreg_buf[6] = (sr_get_hex_digit (1) << 4) + sr_get_hex_digit (1);
+ fpreg_buf[7] = (sr_get_hex_digit (1) << 4) + sr_get_hex_digit (1);
+ fpreg_buf[8] = 0;
+ fpreg_buf[9] = 0;
+
+ gr_expect_prompt ();
+ supply_register (regno, fpreg_buf);
+ }
+
+ return;
+}
+
+/* Store register REGNO, or all if REGNO == -1. */
+
+static void
+bug_store_register (int regno)
+{
+ char buffer[1024];
+ sr_check_open ();
+
+ if (regno == -1)
+ {
+ int i;
+
+ for (i = 0; i < NUM_REGS; ++i)
+ bug_store_register (i);
+ }
+ else
+ {
+ char *regname;
+
+ regname = get_reg_name (regno);
+
+ if (target_is_m88110 && regno == SFIP_REGNUM)
+ return;
+ else if (regno < XFP_REGNUM)
+ sprintf (buffer, "rs %s %08lx",
+ regname,
+ (long) read_register (regno));
+ else
+ {
+ unsigned char *fpreg_buf =
+ (unsigned char *) &registers[REGISTER_BYTE (regno)];
+
+ sprintf (buffer, "rs %s %1x_%02x%1x_%1x%02x%02x%02x%02x%02x%02x;d",
+ regname,
+ /* sign */
+ (fpreg_buf[0] >> 7) & 0xf,
+ /* exponent */
+ fpreg_buf[0] & 0x7f,
+ (fpreg_buf[1] >> 8) & 0xf,
+ /* fraction */
+ fpreg_buf[1] & 0xf,
+ fpreg_buf[2],
+ fpreg_buf[3],
+ fpreg_buf[4],
+ fpreg_buf[5],
+ fpreg_buf[6],
+ fpreg_buf[7]);
+ }
+
+ sr_write_cr (buffer);
+ gr_expect_prompt ();
+ }
+
+ return;
+}
+
+/* Transfer LEN bytes between GDB address MYADDR and target address
+ MEMADDR. If WRITE is non-zero, transfer them to the target,
+ otherwise transfer them from the target. TARGET is unused.
+
+ Returns the number of bytes transferred. */
+
+int
+bug_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib, struct target_ops *target)
+{
+ int res;
+
+ if (len <= 0)
+ return 0;
+
+ if (write)
+ res = bug_write_memory (memaddr, myaddr, len);
+ else
+ res = bug_read_memory (memaddr, myaddr, len);
+
+ return res;
+}
+
+static void
+start_load (void)
+{
+ char *command;
+
+ command = (srec_echo_pace ? "lo 0 ;x" : "lo 0");
+
+ sr_write_cr (command);
+ sr_expect (command);
+ sr_expect ("\r\n");
+ bug_srec_write_cr ("S0030000FC");
+ return;
+}
+
+/* This is an extremely vulnerable and fragile function. I've made
+ considerable attempts to make this deterministic, but I've
+ certainly forgotten something. The trouble is that S-records are
+ only a partial file format, not a protocol. Worse, apparently the
+ m88k bug monitor does not run in real time while receiving
+ S-records. Hence, we must pay excruciating attention to when and
+ where error messages are returned, and what has actually been sent.
+
+ Each call represents a chunk of memory to be sent to the target.
+ We break that chunk into an S0 header record, some number of S3
+ data records each containing srec_bytes, and an S7 termination
+ record. */
+
+static char *srecord_strings[] =
+{
+ "S-RECORD",
+ "-Bug>",
+ NULL,
+};
+
+static int
+bug_write_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
+{
+ int done;
+ int checksum;
+ int x;
+ int retries;
+ char *buffer = alloca ((srec_bytes + 8) << 1);
+
+ retries = 0;
+
+ do
+ {
+ done = 0;
+
+ if (retries > srec_max_retries)
+ return (-1);
+
+ if (retries > 0)
+ {
+ if (sr_get_debug () > 0)
+ printf ("\n<retrying...>\n");
+
+ /* This gr_expect_prompt call is extremely important. Without
+ it, we will tend to resend our packet so fast that it
+ will arrive before the bug monitor is ready to receive
+ it. This would lead to a very ugly resend loop. */
+
+ gr_expect_prompt ();
+ }
+
+ start_load ();
+
+ while (done < len)
+ {
+ int thisgo;
+ int idx;
+ char *buf = buffer;
+ CORE_ADDR address;
+
+ checksum = 0;
+ thisgo = len - done;
+ if (thisgo > srec_bytes)
+ thisgo = srec_bytes;
+
+ address = memaddr + done;
+ sprintf (buf, "S3%02X%08lX", thisgo + 4 + 1, (long) address);
+ buf += 12;
+
+ checksum += (thisgo + 4 + 1
+ + (address & 0xff)
+ + ((address >> 8) & 0xff)
+ + ((address >> 16) & 0xff)
+ + ((address >> 24) & 0xff));
+
+ for (idx = 0; idx < thisgo; idx++)
+ {
+ sprintf (buf, "%02X", myaddr[idx + done]);
+ checksum += myaddr[idx + done];
+ buf += 2;
+ }
+
+ if (srec_noise > 0)
+ {
+ /* FIXME-NOW: insert a deliberate error every now and then.
+ This is intended for testing/debugging the error handling
+ stuff. */
+ static int counter = 0;
+ if (++counter > srec_noise)
+ {
+ counter = 0;
+ ++checksum;
+ }
+ }
+
+ sprintf (buf, "%02X", ~checksum & 0xff);
+ bug_srec_write_cr (buffer);
+
+ if (srec_sleep != 0)
+ sleep (srec_sleep);
+
+ /* This pollchar is probably redundant to the gr_multi_scan
+ below. Trouble is, we can't be sure when or where an
+ error message will appear. Apparently, when running at
+ full speed from a typical sun4, error messages tend to
+ appear to arrive only *after* the s7 record. */
+
+ if ((x = sr_pollchar ()) != 0)
+ {
+ if (sr_get_debug () > 0)
+ printf ("\n<retrying...>\n");
+
+ ++retries;
+
+ /* flush any remaining input and verify that we are back
+ at the prompt level. */
+ gr_expect_prompt ();
+ /* start all over again. */
+ start_load ();
+ done = 0;
+ continue;
+ }
+
+ done += thisgo;
+ }
+
+ bug_srec_write_cr ("S7060000000000F9");
+ ++retries;
+
+ /* Having finished the load, we need to figure out whether we
+ had any errors. */
+ }
+ while (gr_multi_scan (srecord_strings, 0) == 0);;
+
+ return (0);
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+ to inferior's memory at MEMADDR. Returns errno value.
+ * sb/sh instructions don't work on unaligned addresses, when TU=1.
+ */
+
+/* Read LEN bytes from inferior memory at MEMADDR. Put the result
+ at debugger address MYADDR. Returns errno value. */
+static int
+bug_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
+{
+ char request[100];
+ char *buffer;
+ char *p;
+ char type;
+ char size;
+ unsigned char c;
+ unsigned int inaddr;
+ unsigned int checksum;
+
+ sprintf (request, "du 0 %lx:&%d", (long) memaddr, len);
+ sr_write_cr (request);
+
+ p = buffer = alloca (len);
+
+ /* scan up through the header */
+ sr_expect ("S0030000FC");
+
+ while (p < buffer + len)
+ {
+ /* scan off any white space. */
+ while (sr_readchar () != 'S');;
+
+ /* what kind of s-rec? */
+ type = sr_readchar ();
+
+ /* scan record size */
+ sr_get_hex_byte (&size);
+ checksum = size;
+ --size;
+ inaddr = 0;
+
+ switch (type)
+ {
+ case '7':
+ case '8':
+ case '9':
+ goto done;
+
+ case '3':
+ sr_get_hex_byte (&c);
+ inaddr = (inaddr << 8) + c;
+ checksum += c;
+ --size;
+ /* intentional fall through */
+ case '2':
+ sr_get_hex_byte (&c);
+ inaddr = (inaddr << 8) + c;
+ checksum += c;
+ --size;
+ /* intentional fall through */
+ case '1':
+ sr_get_hex_byte (&c);
+ inaddr = (inaddr << 8) + c;
+ checksum += c;
+ --size;
+ sr_get_hex_byte (&c);
+ inaddr = (inaddr << 8) + c;
+ checksum += c;
+ --size;
+ break;
+
+ default:
+ /* bonk */
+ error ("reading s-records.");
+ }
+
+ if (inaddr < memaddr
+ || (memaddr + len) < (inaddr + size))
+ error ("srec out of memory range.");
+
+ if (p != buffer + inaddr - memaddr)
+ error ("srec out of sequence.");
+
+ for (; size; --size, ++p)
+ {
+ sr_get_hex_byte (p);
+ checksum += *p;
+ }
+
+ sr_get_hex_byte (&c);
+ if (c != (~checksum & 0xff))
+ error ("bad s-rec checksum");
+ }
+
+done:
+ gr_expect_prompt ();
+ if (p != buffer + len)
+ return (1);
+
+ memcpy (myaddr, buffer, len);
+ return (0);
+}
+
+#define MAX_BREAKS 16
+static int num_brkpts = 0;
+
+/* Insert a breakpoint at ADDR. SAVE is normally the address of the
+ pattern buffer where the instruction that the breakpoint overwrites
+ is saved. It is unused here since the bug is responsible for
+ saving/restoring the original instruction. */
+
+static int
+bug_insert_breakpoint (CORE_ADDR addr, char *save)
+{
+ sr_check_open ();
+
+ if (num_brkpts < MAX_BREAKS)
+ {
+ char buffer[100];
+
+ num_brkpts++;
+ sprintf (buffer, "br %lx", (long) addr);
+ sr_write_cr (buffer);
+ gr_expect_prompt ();
+ return (0);
+ }
+ else
+ {
+ fprintf_filtered (gdb_stderr,
+ "Too many break points, break point not installed\n");
+ return (1);
+ }
+
+}
+
+/* Remove a breakpoint at ADDR. SAVE is normally the previously
+ saved pattern, but is unused here since the bug is responsible
+ for saving/restoring instructions. */
+
+static int
+bug_remove_breakpoint (CORE_ADDR addr, char *save)
+{
+ if (num_brkpts > 0)
+ {
+ char buffer[100];
+
+ num_brkpts--;
+ sprintf (buffer, "nobr %lx", (long) addr);
+ sr_write_cr (buffer);
+ gr_expect_prompt ();
+
+ }
+ return (0);
+}
+
+/* Clear the bugs notion of what the break points are */
+static int
+bug_clear_breakpoints (void)
+{
+
+ if (sr_is_open ())
+ {
+ sr_write_cr ("nobr");
+ sr_expect ("nobr");
+ gr_expect_prompt ();
+ }
+ num_brkpts = 0;
+ return (0);
+}
+
+struct target_ops bug_ops;
+
+static void
+init_bug_ops (void)
+{
+ bug_ops.to_shortname = "bug";
+ "Remote BUG monitor",
+ bug_ops.to_longname = "Use the mvme187 board running the BUG monitor connected by a serial line.";
+ bug_ops.to_doc = " ";
+ bug_ops.to_open = bug_open;
+ bug_ops.to_close = gr_close;
+ bug_ops.to_attach = 0;
+ bug_ops.to_post_attach = NULL;
+ bug_ops.to_require_attach = NULL;
+ bug_ops.to_detach = gr_detach;
+ bug_ops.to_require_detach = NULL;
+ bug_ops.to_resume = bug_resume;
+ bug_ops.to_wait = bug_wait;
+ bug_ops.to_post_wait = NULL;
+ bug_ops.to_fetch_registers = bug_fetch_register;
+ bug_ops.to_store_registers = bug_store_register;
+ bug_ops.to_prepare_to_store = gr_prepare_to_store;
+ bug_ops.to_xfer_memory = bug_xfer_memory;
+ bug_ops.to_files_info = gr_files_info;
+ bug_ops.to_insert_breakpoint = bug_insert_breakpoint;
+ bug_ops.to_remove_breakpoint = bug_remove_breakpoint;
+ bug_ops.to_terminal_init = 0;
+ bug_ops.to_terminal_inferior = 0;
+ bug_ops.to_terminal_ours_for_output = 0;
+ bug_ops.to_terminal_ours = 0;
+ bug_ops.to_terminal_info = 0;
+ bug_ops.to_kill = gr_kill;
+ bug_ops.to_load = bug_load;
+ bug_ops.to_lookup_symbol = 0;
+ bug_ops.to_create_inferior = gr_create_inferior;
+ bug_ops.to_post_startup_inferior = NULL;
+ bug_ops.to_acknowledge_created_inferior = NULL;
+ bug_ops.to_clone_and_follow_inferior = NULL;
+ bug_ops.to_post_follow_inferior_by_clone = NULL;
+ bug_ops.to_insert_fork_catchpoint = NULL;
+ bug_ops.to_remove_fork_catchpoint = NULL;
+ bug_ops.to_insert_vfork_catchpoint = NULL;
+ bug_ops.to_remove_vfork_catchpoint = NULL;
+ bug_ops.to_has_forked = NULL;
+ bug_ops.to_has_vforked = NULL;
+ bug_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ bug_ops.to_post_follow_vfork = NULL;
+ bug_ops.to_insert_exec_catchpoint = NULL;
+ bug_ops.to_remove_exec_catchpoint = NULL;
+ bug_ops.to_has_execd = NULL;
+ bug_ops.to_reported_exec_events_per_exec_call = NULL;
+ bug_ops.to_has_exited = NULL;
+ bug_ops.to_mourn_inferior = gr_mourn;
+ bug_ops.to_can_run = 0;
+ bug_ops.to_notice_signals = 0;
+ bug_ops.to_thread_alive = 0;
+ bug_ops.to_stop = 0;
+ bug_ops.to_pid_to_exec_file = NULL;
+ bug_ops.to_stratum = process_stratum;
+ bug_ops.DONT_USE = 0;
+ bug_ops.to_has_all_memory = 1;
+ bug_ops.to_has_memory = 1;
+ bug_ops.to_has_stack = 1;
+ bug_ops.to_has_registers = 0;
+ bug_ops.to_has_execution = 0;
+ bug_ops.to_sections = 0;
+ bug_ops.to_sections_end = 0;
+ bug_ops.to_magic = OPS_MAGIC; /* Always the last thing */
+} /* init_bug_ops */
+
+void
+_initialize_remote_bug (void)
+{
+ init_bug_ops ();
+ add_target (&bug_ops);
+
+ add_show_from_set
+ (add_set_cmd ("srec-bytes", class_support, var_uinteger,
+ (char *) &srec_bytes,
+ "\
+Set the number of bytes represented in each S-record.\n\
+This affects the communication protocol with the remote target.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("srec-max-retries", class_support, var_uinteger,
+ (char *) &srec_max_retries,
+ "\
+Set the number of retries for shipping S-records.\n\
+This affects the communication protocol with the remote target.",
+ &setlist),
+ &showlist);
+
+#if 0
+ /* This needs to set SREC_SIZE, not srec_frame which gets changed at the
+ end of a download. But do we need the option at all? */
+ add_show_from_set
+ (add_set_cmd ("srec-frame", class_support, var_uinteger,
+ (char *) &srec_frame,
+ "\
+Set the number of bytes in an S-record frame.\n\
+This affects the communication protocol with the remote target.",
+ &setlist),
+ &showlist);
+#endif /* 0 */
+
+ add_show_from_set
+ (add_set_cmd ("srec-noise", class_support, var_zinteger,
+ (char *) &srec_noise,
+ "\
+Set number of S-record to send before deliberately flubbing a checksum.\n\
+Zero means flub none at all. This affects the communication protocol\n\
+with the remote target.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("srec-sleep", class_support, var_zinteger,
+ (char *) &srec_sleep,
+ "\
+Set number of seconds to sleep after an S-record for a possible error message to arrive.\n\
+This affects the communication protocol with the remote target.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("srec-echo-pace", class_support, var_boolean,
+ (char *) &srec_echo_pace,
+ "\
+Set echo-verification.\n\
+When on, use verification by echo when downloading S-records. This is\n\
+much slower, but generally more reliable.",
+ &setlist),
+ &showlist);
+}
diff --git a/gdb/remote-e7000.c b/gdb/remote-e7000.c
new file mode 100644
index 00000000000..d9cf5e8bba9
--- /dev/null
+++ b/gdb/remote-e7000.c
@@ -0,0 +1,2227 @@
+/* Remote debugging interface for Hitachi E7000 ICE, for GDB
+
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Support.
+
+ Written by Steve Chamberlain for 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 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. */
+
+/* The E7000 is an in-circuit emulator for the Hitachi H8/300-H and
+ Hitachi-SH processor. It has serial port and a lan port.
+
+ The monitor command set makes it difficult to load large ammounts of
+ data over the lan without using ftp - so try not to issue load
+ commands when communicating over ethernet; use the ftpload command.
+
+ The monitor pauses for a second when dumping srecords to the serial
+ line too, so we use a slower per byte mechanism but without the
+ startup overhead. Even so, it's pretty slow... */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "gdbarch.h"
+#include "inferior.h"
+#include "target.h"
+#include "value.h"
+#include "command.h"
+#include "gdb_string.h"
+#include "gdbcmd.h"
+#include <sys/types.h>
+#include "serial.h"
+#include "remote-utils.h"
+#include "symfile.h"
+#include "regcache.h"
+#include <time.h>
+#include <ctype.h>
+
+
+#if 1
+#define HARD_BREAKPOINTS /* Now handled by set option. */
+#define BC_BREAKPOINTS use_hard_breakpoints
+#endif
+
+#define CTRLC 0x03
+#define ENQ 0x05
+#define ACK 0x06
+#define CTRLZ 0x1a
+
+/* This file is used by 2 different targets, sh-elf and h8300. The
+ h8300 is not multiarched and doesn't use the registers defined in
+ tm-sh.h. To avoid using a macro GDB_TARGET_IS_SH, we do runtime check
+ of the target, which requires that these namse below are always
+ defined also in the h8300 case. */
+
+#if !defined (PR_REGNUM)
+#define PR_REGNUM -1
+#endif
+#if !defined (GBR_REGNUM)
+#define GBR_REGNUM -1
+#endif
+#if !defined (VBR_REGNUM)
+#define VBR_REGNUM -1
+#endif
+#if !defined (MACH_REGNUM)
+#define MACH_REGNUM -1
+#endif
+#if !defined (MACL_REGNUM)
+#define MACL_REGNUM -1
+#endif
+#if !defined (SR_REGNUM)
+#define SR_REGNUM -1
+#endif
+
+extern void report_transfer_performance (unsigned long, time_t, time_t);
+
+extern char *sh_processor_type;
+
+/* Local function declarations. */
+
+static void e7000_close (int);
+
+static void e7000_fetch_register (int);
+
+static void e7000_store_register (int);
+
+static void e7000_command (char *, int);
+
+static void e7000_login_command (char *, int);
+
+static void e7000_ftp_command (char *, int);
+
+static void e7000_drain_command (char *, int);
+
+static void expect (char *);
+
+static void expect_full_prompt (void);
+
+static void expect_prompt (void);
+
+static int e7000_parse_device (char *args, char *dev_name, int baudrate);
+/* Variables. */
+
+static struct serial *e7000_desc;
+
+/* Allow user to chose between using hardware breakpoints or memory. */
+static int use_hard_breakpoints = 0; /* use sw breakpoints by default */
+
+/* Nonzero if using the tcp serial driver. */
+
+static int using_tcp; /* direct tcp connection to target */
+static int using_tcp_remote; /* indirect connection to target
+ via tcp to controller */
+
+/* Nonzero if using the pc isa card. */
+
+static int using_pc;
+
+extern struct target_ops e7000_ops; /* Forward declaration */
+
+char *ENQSTRING = "\005";
+
+/* Nonzero if some routine (as opposed to the user) wants echoing.
+ FIXME: Do this reentrantly with an extra parameter. */
+
+static int echo;
+
+static int ctrl_c;
+
+static int timeout = 20;
+
+/* Send data to e7000debug. */
+
+static void
+puts_e7000debug (char *buf)
+{
+ if (!e7000_desc)
+ error ("Use \"target e7000 ...\" first.");
+
+ if (remote_debug)
+ printf_unfiltered ("Sending %s\n", buf);
+
+ if (serial_write (e7000_desc, buf, strlen (buf)))
+ fprintf_unfiltered (gdb_stderr, "serial_write failed: %s\n", safe_strerror (errno));
+
+ /* And expect to see it echoed, unless using the pc interface */
+#if 0
+ if (!using_pc)
+#endif
+ expect (buf);
+}
+
+static void
+putchar_e7000 (int x)
+{
+ char b[1];
+
+ b[0] = x;
+ serial_write (e7000_desc, b, 1);
+}
+
+static void
+write_e7000 (char *s)
+{
+ serial_write (e7000_desc, s, strlen (s));
+}
+
+static int
+normal (int x)
+{
+ if (x == '\n')
+ return '\r';
+ return x;
+}
+
+/* Read a character from the remote system, doing all the fancy timeout
+ stuff. Handles serial errors and EOF. If TIMEOUT == 0, and no chars,
+ returns -1, else returns next char. Discards chars > 127. */
+
+static int
+readchar (int timeout)
+{
+ int c;
+
+ do
+ {
+ c = serial_readchar (e7000_desc, timeout);
+ }
+ while (c > 127);
+
+ if (c == SERIAL_TIMEOUT)
+ {
+ if (timeout == 0)
+ return -1;
+ echo = 0;
+ error ("Timeout reading from remote system.");
+ }
+ else if (c < 0)
+ error ("Serial communication error");
+
+ if (remote_debug)
+ {
+ putchar_unfiltered (c);
+ gdb_flush (gdb_stdout);
+ }
+
+ return normal (c);
+}
+
+#if 0
+char *
+tl (int x)
+{
+ static char b[8][10];
+ static int p;
+
+ p++;
+ p &= 7;
+ if (x >= ' ')
+ {
+ b[p][0] = x;
+ b[p][1] = 0;
+ }
+ else
+ {
+ sprintf (b[p], "<%d>", x);
+ }
+
+ return b[p];
+}
+#endif
+
+/* Scan input from the remote system, until STRING is found. If
+ DISCARD is non-zero, then discard non-matching input, else print it
+ out. Let the user break out immediately. */
+
+static void
+expect (char *string)
+{
+ char *p = string;
+ int c;
+ int nl = 0;
+
+ while (1)
+ {
+ c = readchar (timeout);
+
+ if (echo)
+ {
+ if (c == '\r' || c == '\n')
+ {
+ if (!nl)
+ putchar_unfiltered ('\n');
+ nl = 1;
+ }
+ else
+ {
+ nl = 0;
+ putchar_unfiltered (c);
+ }
+ gdb_flush (gdb_stdout);
+ }
+ if (normal (c) == normal (*p++))
+ {
+ if (*p == '\0')
+ return;
+ }
+ else
+ {
+ p = string;
+
+ if (normal (c) == normal (string[0]))
+ p++;
+ }
+ }
+}
+
+/* Keep discarding input until we see the e7000 prompt.
+
+ The convention for dealing with the prompt is that you
+ o give your command
+ o *then* wait for the prompt.
+
+ Thus the last thing that a procedure does with the serial line will
+ be an expect_prompt(). Exception: e7000_resume does not wait for
+ the prompt, because the terminal is being handed over to the
+ inferior. However, the next thing which happens after that is a
+ e7000_wait which does wait for the prompt. Note that this includes
+ abnormal exit, e.g. error(). This is necessary to prevent getting
+ into states from which we can't recover. */
+
+static void
+expect_prompt (void)
+{
+ expect (":");
+}
+
+static void
+expect_full_prompt (void)
+{
+ expect ("\r:");
+}
+
+static int
+convert_hex_digit (int ch)
+{
+ if (ch >= '0' && ch <= '9')
+ return ch - '0';
+ else if (ch >= 'A' && ch <= 'F')
+ return ch - 'A' + 10;
+ else if (ch >= 'a' && ch <= 'f')
+ return ch - 'a' + 10;
+ return -1;
+}
+
+static int
+get_hex (int *start)
+{
+ int value = convert_hex_digit (*start);
+ int try;
+
+ *start = readchar (timeout);
+ while ((try = convert_hex_digit (*start)) >= 0)
+ {
+ value <<= 4;
+ value += try;
+ *start = readchar (timeout);
+ }
+ return value;
+}
+
+#if 0
+/* Get N 32-bit words from remote, each preceded by a space, and put
+ them in registers starting at REGNO. */
+
+static void
+get_hex_regs (int n, int regno)
+{
+ long val;
+ int i;
+
+ for (i = 0; i < n; i++)
+ {
+ int j;
+
+ val = 0;
+ for (j = 0; j < 8; j++)
+ val = (val << 4) + get_hex_digit (j == 0);
+ supply_register (regno++, (char *) &val);
+ }
+}
+#endif
+
+/* This is called not only when we first attach, but also when the
+ user types "run" after having attached. */
+
+static void
+e7000_create_inferior (char *execfile, char *args, char **env)
+{
+ int entry_pt;
+
+ if (args && *args)
+ error ("Can't pass arguments to remote E7000DEBUG process");
+
+ if (execfile == 0 || exec_bfd == 0)
+ error ("No executable file specified");
+
+ entry_pt = (int) bfd_get_start_address (exec_bfd);
+
+#ifdef CREATE_INFERIOR_HOOK
+ CREATE_INFERIOR_HOOK (0); /* No process-ID */
+#endif
+
+ /* The "process" (board) is already stopped awaiting our commands, and
+ the program is already downloaded. We just set its PC and go. */
+
+ clear_proceed_status ();
+
+ /* Tell wait_for_inferior that we've started a new process. */
+ init_wait_for_inferior ();
+
+ /* Set up the "saved terminal modes" of the inferior
+ based on what modes we are starting it with. */
+ target_terminal_init ();
+
+ /* Install inferior's terminal modes. */
+ target_terminal_inferior ();
+
+ /* insert_step_breakpoint (); FIXME, do we need this? */
+ proceed ((CORE_ADDR) entry_pt, -1, 0); /* Let 'er rip... */
+}
+
+/* Open a connection to a remote debugger. NAME is the filename used
+ for communication. */
+
+static int baudrate = 9600;
+static char dev_name[100];
+
+static char *machine = "";
+static char *user = "";
+static char *passwd = "";
+static char *dir = "";
+
+/* Grab the next token and buy some space for it */
+
+static char *
+next (char **ptr)
+{
+ char *p = *ptr;
+ char *s;
+ char *r;
+ int l = 0;
+
+ while (*p && *p == ' ')
+ p++;
+ s = p;
+ while (*p && (*p != ' ' && *p != '\t'))
+ {
+ l++;
+ p++;
+ }
+ r = xmalloc (l + 1);
+ memcpy (r, s, l);
+ r[l] = 0;
+ *ptr = p;
+ return r;
+}
+
+static void
+e7000_login_command (char *args, int from_tty)
+{
+ if (args)
+ {
+ machine = next (&args);
+ user = next (&args);
+ passwd = next (&args);
+ dir = next (&args);
+ if (from_tty)
+ {
+ printf_unfiltered ("Set info to %s %s %s %s\n", machine, user, passwd, dir);
+ }
+ }
+ else
+ {
+ error ("Syntax is ftplogin <machine> <user> <passwd> <directory>");
+ }
+}
+
+/* Start an ftp transfer from the E7000 to a host */
+
+static void
+e7000_ftp_command (char *args, int from_tty)
+{
+ /* FIXME: arbitrary limit on machine names and such. */
+ char buf[200];
+
+ int oldtimeout = timeout;
+ timeout = remote_timeout;
+
+ sprintf (buf, "ftp %s\r", machine);
+ puts_e7000debug (buf);
+ expect (" Username : ");
+ sprintf (buf, "%s\r", user);
+ puts_e7000debug (buf);
+ expect (" Password : ");
+ write_e7000 (passwd);
+ write_e7000 ("\r");
+ expect ("success\r");
+ expect ("FTP>");
+ sprintf (buf, "cd %s\r", dir);
+ puts_e7000debug (buf);
+ expect ("FTP>");
+ sprintf (buf, "ll 0;s:%s\r", args);
+ puts_e7000debug (buf);
+ expect ("FTP>");
+ puts_e7000debug ("bye\r");
+ expect (":");
+ timeout = oldtimeout;
+}
+
+static int
+e7000_parse_device (char *args, char *dev_name, int baudrate)
+{
+ char junk[128];
+ int n = 0;
+ if (args && strcasecmp (args, "pc") == 0)
+ {
+ strcpy (dev_name, args);
+ using_pc = 1;
+ }
+ else
+ {
+ /* FIXME! temp hack to allow use with port master -
+ target tcp_remote <device> */
+ if (args && strncmp (args, "tcp", 10) == 0)
+ {
+ char com_type[128];
+ n = sscanf (args, " %s %s %d %s", com_type, dev_name, &baudrate, junk);
+ using_tcp_remote = 1;
+ n--;
+ }
+ else if (args)
+ {
+ n = sscanf (args, " %s %d %s", dev_name, &baudrate, junk);
+ }
+
+ if (n != 1 && n != 2)
+ {
+ error ("Bad arguments. Usage:\ttarget e7000 <device> <speed>\n\
+or \t\ttarget e7000 <host>[:<port>]\n\
+or \t\ttarget e7000 tcp_remote <host>[:<port>]\n\
+or \t\ttarget e7000 pc\n");
+ }
+
+#if !defined(__GO32__) && !defined(_WIN32) && !defined(__CYGWIN__)
+ /* FIXME! test for ':' is ambiguous */
+ if (n == 1 && strchr (dev_name, ':') == 0)
+ {
+ /* Default to normal telnet port */
+ /* serial_open will use this to determine tcp communication */
+ strcat (dev_name, ":23");
+ }
+#endif
+ if (!using_tcp_remote && strchr (dev_name, ':'))
+ using_tcp = 1;
+ }
+
+ return n;
+}
+
+/* Stub for catch_errors. */
+
+static int
+e7000_start_remote (void *dummy)
+{
+ int loop;
+ int sync;
+ int try;
+ int quit_trying;
+
+ immediate_quit++; /* Allow user to interrupt it */
+
+ /* Hello? Are you there? */
+ sync = 0;
+ loop = 0;
+ try = 0;
+ quit_trying = 20;
+ putchar_e7000 (CTRLC);
+ while (!sync && ++try <= quit_trying)
+ {
+ int c;
+
+ printf_unfiltered ("[waiting for e7000...]\n");
+
+ write_e7000 ("\r");
+ c = readchar (1);
+
+ /* FIXME! this didn't seem right-> while (c != SERIAL_TIMEOUT)
+ * we get stuck in this loop ...
+ * We may never timeout, and never sync up :-(
+ */
+ while (!sync && c != -1)
+ {
+ /* Dont echo cr's */
+ if (c != '\r')
+ {
+ putchar_unfiltered (c);
+ gdb_flush (gdb_stdout);
+ }
+ /* Shouldn't we either break here, or check for sync in inner loop? */
+ if (c == ':')
+ sync = 1;
+
+ if (loop++ == 20)
+ {
+ putchar_e7000 (CTRLC);
+ loop = 0;
+ }
+
+ QUIT;
+
+ if (quit_flag)
+ {
+ putchar_e7000 (CTRLC);
+ /* Was-> quit_flag = 0; */
+ c = -1;
+ quit_trying = try + 1; /* we don't want to try anymore */
+ }
+ else
+ {
+ c = readchar (1);
+ }
+ }
+ }
+
+ if (!sync)
+ {
+ fprintf_unfiltered (gdb_stderr, "Giving up after %d tries...\n", try);
+ error ("Unable to synchronize with target.\n");
+ }
+
+ puts_e7000debug ("\r");
+ expect_prompt ();
+ puts_e7000debug ("b -\r"); /* Clear breakpoints */
+ expect_prompt ();
+
+ immediate_quit--;
+
+/* This is really the job of start_remote however, that makes an assumption
+ that the target is about to print out a status message of some sort. That
+ doesn't happen here. */
+
+ flush_cached_frames ();
+ registers_changed ();
+ stop_pc = read_pc ();
+ set_current_frame (create_new_frame (read_fp (), stop_pc));
+ select_frame (get_current_frame ());
+ print_stack_frame (selected_frame, -1, 1);
+
+ return 1;
+}
+
+static void
+e7000_open (char *args, int from_tty)
+{
+ int n;
+
+ target_preopen (from_tty);
+
+ n = e7000_parse_device (args, dev_name, baudrate);
+
+ push_target (&e7000_ops);
+
+ e7000_desc = serial_open (dev_name);
+
+ if (!e7000_desc)
+ perror_with_name (dev_name);
+
+ if (serial_setbaudrate (e7000_desc, baudrate))
+ {
+ serial_close (e7000_desc);
+ perror_with_name (dev_name);
+ }
+ serial_raw (e7000_desc);
+
+#ifdef GDB_TARGET_IS_H8300
+ h8300hmode = 1;
+#endif
+
+ /* Start the remote connection; if error (0), discard this target.
+ In particular, if the user quits, be sure to discard it
+ (we'd be in an inconsistent state otherwise). */
+ if (!catch_errors (e7000_start_remote, (char *) 0,
+ "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
+ if (from_tty)
+ printf_filtered ("Remote target %s connected to %s\n", target_shortname,
+ dev_name);
+}
+
+/* Close out all files and local state before this target loses control. */
+
+static void
+e7000_close (int quitting)
+{
+ if (e7000_desc)
+ {
+ serial_close (e7000_desc);
+ e7000_desc = 0;
+ }
+}
+
+/* Terminate the open connection to the remote debugger. Use this
+ when you want to detach and do something else with your gdb. */
+
+static void
+e7000_detach (char *arg, int from_tty)
+{
+ pop_target (); /* calls e7000_close to do the real work */
+ if (from_tty)
+ printf_unfiltered ("Ending remote %s debugging\n", target_shortname);
+}
+
+/* Tell the remote machine to resume. */
+
+static void
+e7000_resume (ptid_t ptid, int step, enum target_signal sigal)
+{
+ if (step)
+ puts_e7000debug ("S\r");
+ else
+ puts_e7000debug ("G\r");
+}
+
+/* Read the remote registers into the block REGS.
+
+ For the H8/300 a register dump looks like:
+
+ PC=00021A CCR=80:I*******
+ ER0 - ER3 0000000A 0000002E 0000002E 00000000
+ ER4 - ER7 00000000 00000000 00000000 00FFEFF6
+ 000218 MOV.B R1L,R2L
+ STEP NORMAL END or
+ BREAK POINT
+ */
+
+char *want_h8300h = "PC=%p CCR=%c\n\
+ ER0 - ER3 %0 %1 %2 %3\n\
+ ER4 - ER7 %4 %5 %6 %7\n";
+
+char *want_nopc_h8300h = "%p CCR=%c\n\
+ ER0 - ER3 %0 %1 %2 %3\n\
+ ER4 - ER7 %4 %5 %6 %7";
+
+char *want_h8300s = "PC=%p CCR=%c\n\
+ MACH=\n\
+ ER0 - ER3 %0 %1 %2 %3\n\
+ ER4 - ER7 %4 %5 %6 %7\n";
+
+char *want_nopc_h8300s = "%p CCR=%c EXR=%9\n\
+ ER0 - ER3 %0 %1 %2 %3\n\
+ ER4 - ER7 %4 %5 %6 %7";
+
+char *want_sh = "PC=%16 SR=%22\n\
+PR=%17 GBR=%18 VBR=%19\n\
+MACH=%20 MACL=%21\n\
+R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\
+R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n";
+
+char *want_nopc_sh = "%16 SR=%22\n\
+ PR=%17 GBR=%18 VBR=%19\n\
+ MACH=%20 MACL=%21\n\
+ R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\
+ R8-15 %8 %9 %10 %11 %12 %13 %14 %15";
+
+char *want_sh3 = "PC=%16 SR=%22\n\
+PR=%17 GBR=%18 VBR=%19\n\
+MACH=%20 MACL=%21 SSR=%23 SPC=%24\n\
+R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\
+R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\
+R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\
+R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\
+R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\
+R4_BANK1-R7_BANK1 %37 %38 %39 %40";
+
+char *want_nopc_sh3 = "%16 SR=%22\n\
+ PR=%17 GBR=%18 VBR=%19\n\
+ MACH=%20 MACL=%21 SSR=%22 SPC=%23\n\
+ R0-7 %0 %1 %2 %3 %4 %5 %6 %7\n\
+ R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\
+ R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\
+ R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\
+ R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\
+ R4_BANK1-R7_BANK1 %37 %38 %39 %40";
+
+static int
+gch (void)
+{
+ return readchar (timeout);
+}
+
+static unsigned int
+gbyte (void)
+{
+ int high = convert_hex_digit (gch ());
+ int low = convert_hex_digit (gch ());
+
+ return (high << 4) + low;
+}
+
+void
+fetch_regs_from_dump (int (*nextchar) (), char *want)
+{
+ int regno;
+ char buf[MAX_REGISTER_RAW_SIZE];
+
+ int thischar = nextchar ();
+
+ if (want == NULL)
+ internal_error (__FILE__, __LINE__, "Register set not selected.");
+
+ while (*want)
+ {
+ switch (*want)
+ {
+ case '\n':
+ /* Skip to end of line and then eat all new line type stuff */
+ while (thischar != '\n' && thischar != '\r')
+ thischar = nextchar ();
+ while (thischar == '\n' || thischar == '\r')
+ thischar = nextchar ();
+ want++;
+ break;
+
+ case ' ':
+ while (thischar == ' '
+ || thischar == '\t'
+ || thischar == '\r'
+ || thischar == '\n')
+ thischar = nextchar ();
+ want++;
+ break;
+
+ default:
+ if (*want == thischar)
+ {
+ want++;
+ if (*want)
+ thischar = nextchar ();
+
+ }
+ else if (thischar == ' ' || thischar == '\n' || thischar == '\r')
+ {
+ thischar = nextchar ();
+ }
+ else
+ {
+ error ("out of sync in fetch registers wanted <%s>, got <%c 0x%x>",
+ want, thischar, thischar);
+ }
+
+ break;
+ case '%':
+ /* Got a register command */
+ want++;
+ switch (*want)
+ {
+#ifdef PC_REGNUM
+ case 'p':
+ regno = PC_REGNUM;
+ want++;
+ break;
+#endif
+#ifdef CCR_REGNUM
+ case 'c':
+ regno = CCR_REGNUM;
+ want++;
+ break;
+#endif
+#ifdef SP_REGNUM
+ case 's':
+ regno = SP_REGNUM;
+ want++;
+ break;
+#endif
+#ifdef FP_REGNUM
+ case 'f':
+ regno = FP_REGNUM;
+ want++;
+ break;
+#endif
+
+ default:
+ if (isdigit (want[0]))
+ {
+ if (isdigit (want[1]))
+ {
+ regno = (want[0] - '0') * 10 + want[1] - '0';
+ want += 2;
+ }
+ else
+ {
+ regno = want[0] - '0';
+ want++;
+ }
+ }
+
+ else
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+ store_signed_integer (buf,
+ REGISTER_RAW_SIZE (regno),
+ (LONGEST) get_hex (&thischar));
+ supply_register (regno, buf);
+ break;
+ }
+ }
+}
+
+static void
+e7000_fetch_registers (void)
+{
+ int regno;
+ char *wanted = NULL;
+
+ puts_e7000debug ("R\r");
+
+ if (TARGET_ARCHITECTURE->arch == bfd_arch_sh)
+ {
+ wanted = want_sh;
+ switch (TARGET_ARCHITECTURE->mach)
+ {
+ case bfd_mach_sh3:
+ case bfd_mach_sh3e:
+ case bfd_mach_sh4:
+ wanted = want_sh3;
+ }
+ }
+#ifdef GDB_TARGET_IS_H8300
+ if (TARGET_ARCHITECTURE->arch == bfd_arch_h8300)
+ {
+ if (h8300smode)
+ wanted = want_h8300s;
+ else
+ wanted = want_h8300h;
+ }
+#endif
+
+ fetch_regs_from_dump (gch, wanted);
+
+ /* And supply the extra ones the simulator uses */
+ for (regno = NUM_REALREGS; regno < NUM_REGS; regno++)
+ {
+ int buf = 0;
+
+ supply_register (regno, (char *) (&buf));
+ }
+}
+
+/* Fetch register REGNO, or all registers if REGNO is -1. Returns
+ errno value. */
+
+static void
+e7000_fetch_register (int regno)
+{
+ e7000_fetch_registers ();
+}
+
+/* Store the remote registers from the contents of the block REGS. */
+
+static void
+e7000_store_registers (void)
+{
+ int regno;
+
+ for (regno = 0; regno < NUM_REALREGS; regno++)
+ e7000_store_register (regno);
+
+ registers_changed ();
+}
+
+/* Store register REGNO, or all if REGNO == 0. Return errno value. */
+
+static void
+e7000_store_register (int regno)
+{
+ char buf[200];
+
+ if (regno == -1)
+ {
+ e7000_store_registers ();
+ return;
+ }
+
+ if (TARGET_ARCHITECTURE->arch == bfd_arch_h8300)
+ {
+ if (regno <= 7)
+ {
+ sprintf (buf, ".ER%d %s\r", regno, phex_nz (read_register (regno), 0));
+ puts_e7000debug (buf);
+ }
+ else if (regno == PC_REGNUM)
+ {
+ sprintf (buf, ".PC %s\r", phex_nz (read_register (regno), 0));
+ puts_e7000debug (buf);
+ }
+#ifdef CCR_REGNUM
+ else if (regno == CCR_REGNUM)
+ {
+ sprintf (buf, ".CCR %s\r", phex_nz (read_register (regno), 0));
+ puts_e7000debug (buf);
+ }
+#endif
+ }
+
+ else if (TARGET_ARCHITECTURE->arch == bfd_arch_sh)
+ {
+ if (regno == PC_REGNUM)
+ {
+ sprintf (buf, ".PC %s\r", phex_nz (read_register (regno), 0));
+ puts_e7000debug (buf);
+ }
+
+ else if (regno == SR_REGNUM)
+ {
+ sprintf (buf, ".SR %s\r", phex_nz (read_register (regno), 0));
+ puts_e7000debug (buf);
+ }
+
+ else if (regno == PR_REGNUM)
+ {
+ sprintf (buf, ".PR %s\r", phex_nz (read_register (regno), 0));
+ puts_e7000debug (buf);
+ }
+
+ else if (regno == GBR_REGNUM)
+ {
+ sprintf (buf, ".GBR %s\r", phex_nz (read_register (regno), 0));
+ puts_e7000debug (buf);
+ }
+
+ else if (regno == VBR_REGNUM)
+ {
+ sprintf (buf, ".VBR %s\r", phex_nz (read_register (regno), 0));
+ puts_e7000debug (buf);
+ }
+
+ else if (regno == MACH_REGNUM)
+ {
+ sprintf (buf, ".MACH %s\r", phex_nz (read_register (regno), 0));
+ puts_e7000debug (buf);
+ }
+
+ else if (regno == MACL_REGNUM)
+ {
+ sprintf (buf, ".MACL %s\r", phex_nz (read_register (regno), 0));
+ puts_e7000debug (buf);
+ }
+ else
+ {
+ sprintf (buf, ".R%d %s\r", regno, phex_nz (read_register (regno), 0));
+ puts_e7000debug (buf);
+ }
+ }
+
+ expect_prompt ();
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+static void
+e7000_prepare_to_store (void)
+{
+ /* Do nothing, since we can store individual regs */
+}
+
+static void
+e7000_files_info (struct target_ops *ops)
+{
+ printf_unfiltered ("\tAttached to %s at %d baud.\n", dev_name, baudrate);
+}
+
+static int
+stickbyte (char *where, unsigned int what)
+{
+ static CONST char digs[] = "0123456789ABCDEF";
+
+ where[0] = digs[(what >> 4) & 0xf];
+ where[1] = digs[(what & 0xf) & 0xf];
+
+ return what;
+}
+
+/* Write a small ammount of memory. */
+
+static int
+write_small (CORE_ADDR memaddr, unsigned char *myaddr, int len)
+{
+ int i;
+ char buf[200];
+
+ for (i = 0; i < len; i++)
+ {
+ if (((memaddr + i) & 3) == 0 && (i + 3 < len))
+ {
+ /* Can be done with a long word */
+ sprintf (buf, "m %s %x%02x%02x%02x;l\r",
+ paddr_nz (memaddr + i),
+ myaddr[i], myaddr[i + 1], myaddr[i + 2], myaddr[i + 3]);
+ puts_e7000debug (buf);
+ i += 3;
+ }
+ else
+ {
+ sprintf (buf, "m %s %x\r", paddr_nz (memaddr + i), myaddr[i]);
+ puts_e7000debug (buf);
+ }
+ }
+
+ expect_prompt ();
+
+ return len;
+}
+
+/* Write a large ammount of memory, this only works with the serial
+ mode enabled. Command is sent as
+
+ il ;s:s\r ->
+ <- il ;s:s\r
+ <- ENQ
+ ACK ->
+ <- LO s\r
+ Srecords...
+ ^Z ->
+ <- ENQ
+ ACK ->
+ <- :
+ */
+
+static int
+write_large (CORE_ADDR memaddr, unsigned char *myaddr, int len)
+{
+ int i;
+#define maxstride 128
+ int stride;
+
+ puts_e7000debug ("IL ;S:FK\r");
+ expect (ENQSTRING);
+ putchar_e7000 (ACK);
+ expect ("LO FK\r");
+
+ for (i = 0; i < len; i += stride)
+ {
+ char compose[maxstride * 2 + 50];
+ int address = i + memaddr;
+ int j;
+ int check_sum;
+ int where = 0;
+ int alen;
+
+ stride = len - i;
+ if (stride > maxstride)
+ stride = maxstride;
+
+ compose[where++] = 'S';
+ check_sum = 0;
+ if (address >= 0xffffff)
+ alen = 4;
+ else if (address >= 0xffff)
+ alen = 3;
+ else
+ alen = 2;
+ /* Insert type. */
+ compose[where++] = alen - 1 + '0';
+ /* Insert length. */
+ check_sum += stickbyte (compose + where, alen + stride + 1);
+ where += 2;
+ while (alen > 0)
+ {
+ alen--;
+ check_sum += stickbyte (compose + where, address >> (8 * (alen)));
+ where += 2;
+ }
+
+ for (j = 0; j < stride; j++)
+ {
+ check_sum += stickbyte (compose + where, myaddr[i + j]);
+ where += 2;
+ }
+ stickbyte (compose + where, ~check_sum);
+ where += 2;
+ compose[where++] = '\r';
+ compose[where++] = '\n';
+ compose[where++] = 0;
+
+ serial_write (e7000_desc, compose, where);
+ j = readchar (0);
+ if (j == -1)
+ {
+ /* This is ok - nothing there */
+ }
+ else if (j == ENQ)
+ {
+ /* Hmm, it's trying to tell us something */
+ expect (":");
+ error ("Error writing memory");
+ }
+ else
+ {
+ printf_unfiltered ("@%d}@", j);
+ while ((j = readchar (0)) > 0)
+ {
+ printf_unfiltered ("@{%d}@", j);
+ }
+ }
+ }
+
+ /* Send the trailer record */
+ write_e7000 ("S70500000000FA\r");
+ putchar_e7000 (CTRLZ);
+ expect (ENQSTRING);
+ putchar_e7000 (ACK);
+ expect (":");
+
+ return len;
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's
+ memory at MEMADDR. Returns length moved.
+
+ Can't use the Srecord load over ethernet, so don't use fast method
+ then. */
+
+static int
+e7000_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
+{
+ if (len < 16 || using_tcp || using_pc)
+ return write_small (memaddr, myaddr, len);
+ else
+ return write_large (memaddr, myaddr, len);
+}
+
+/* Read LEN bytes from inferior memory at MEMADDR. Put the result
+ at debugger address MYADDR. Returns length moved.
+
+ Small transactions we send
+ m <addr>;l
+ and receive
+ 00000000 12345678 ?
+ */
+
+static int
+e7000_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
+{
+ int count;
+ int c;
+ int i;
+ char buf[200];
+ /* Starting address of this pass. */
+
+/* printf("READ INF %x %x %d\n", memaddr, myaddr, len); */
+ if (((memaddr - 1) + len) < memaddr)
+ {
+ errno = EIO;
+ return 0;
+ }
+
+ sprintf (buf, "m %s;l\r", paddr_nz (memaddr));
+ puts_e7000debug (buf);
+
+ for (count = 0; count < len; count += 4)
+ {
+ /* Suck away the address */
+ c = gch ();
+ while (c != ' ')
+ c = gch ();
+ c = gch ();
+ if (c == '*')
+ { /* Some kind of error */
+ puts_e7000debug (".\r"); /* Some errors leave us in memory input mode */
+ expect_full_prompt ();
+ return -1;
+ }
+ while (c != ' ')
+ c = gch ();
+
+ /* Now read in the data */
+ for (i = 0; i < 4; i++)
+ {
+ int b = gbyte ();
+ if (count + i < len)
+ {
+ myaddr[count + i] = b;
+ }
+ }
+
+ /* Skip the trailing ? and send a . to end and a cr for more */
+ gch ();
+ gch ();
+ if (count + 4 >= len)
+ puts_e7000debug (".\r");
+ else
+ puts_e7000debug ("\r");
+
+ }
+ expect_prompt ();
+ return len;
+}
+
+
+
+/*
+ For large transfers we used to send
+
+
+ d <addr> <endaddr>\r
+
+ and receive
+ <ADDRESS> < D A T A > < ASCII CODE >
+ 00000000 5F FD FD FF DF 7F DF FF 01 00 01 00 02 00 08 04 "_..............."
+ 00000010 FF D7 FF 7F D7 F1 7F FF 00 05 00 00 08 00 40 00 "..............@."
+ 00000020 7F FD FF F7 7F FF FF F7 00 00 00 00 00 00 00 00 "................"
+
+ A cost in chars for each transaction of 80 + 5*n-bytes.
+
+ Large transactions could be done with the srecord load code, but
+ there is a pause for a second before dumping starts, which slows the
+ average rate down!
+ */
+
+static int
+e7000_read_inferior_memory_large (CORE_ADDR memaddr, unsigned char *myaddr,
+ int len)
+{
+ int count;
+ int c;
+ char buf[200];
+
+ /* Starting address of this pass. */
+
+ if (((memaddr - 1) + len) < memaddr)
+ {
+ errno = EIO;
+ return 0;
+ }
+
+ sprintf (buf, "d %s %s\r", paddr_nz (memaddr), paddr_nz (memaddr + len - 1));
+ puts_e7000debug (buf);
+
+ count = 0;
+ c = gch ();
+
+ /* skip down to the first ">" */
+ while (c != '>')
+ c = gch ();
+ /* now skip to the end of that line */
+ while (c != '\r')
+ c = gch ();
+ c = gch ();
+
+ while (count < len)
+ {
+ /* get rid of any white space before the address */
+ while (c <= ' ')
+ c = gch ();
+
+ /* Skip the address */
+ get_hex (&c);
+
+ /* read in the bytes on the line */
+ while (c != '"' && count < len)
+ {
+ if (c == ' ')
+ c = gch ();
+ else
+ {
+ myaddr[count++] = get_hex (&c);
+ }
+ }
+ /* throw out the rest of the line */
+ while (c != '\r')
+ c = gch ();
+ }
+
+ /* wait for the ":" prompt */
+ while (c != ':')
+ c = gch ();
+
+ return len;
+}
+
+#if 0
+
+static int
+fast_but_for_the_pause_e7000_read_inferior_memory (CORE_ADDR memaddr,
+ char *myaddr, int len)
+{
+ int loop;
+ int c;
+ char buf[200];
+
+ if (((memaddr - 1) + len) < memaddr)
+ {
+ errno = EIO;
+ return 0;
+ }
+
+ sprintf (buf, "is %x@%x:s\r", memaddr, len);
+ puts_e7000debug (buf);
+ gch ();
+ c = gch ();
+ if (c != ENQ)
+ {
+ /* Got an error */
+ error ("Memory read error");
+ }
+ putchar_e7000 (ACK);
+ expect ("SV s");
+ loop = 1;
+ while (loop)
+ {
+ int type;
+ int length;
+ int addr;
+ int i;
+
+ c = gch ();
+ switch (c)
+ {
+ case ENQ: /* ENQ, at the end */
+ loop = 0;
+ break;
+ case 'S':
+ /* Start of an Srecord */
+ type = gch ();
+ length = gbyte ();
+ switch (type)
+ {
+ case '7': /* Termination record, ignore */
+ case '0':
+ case '8':
+ case '9':
+ /* Header record - ignore it */
+ while (length--)
+ {
+ gbyte ();
+ }
+ break;
+ case '1':
+ case '2':
+ case '3':
+ {
+ int alen;
+
+ alen = type - '0' + 1;
+ addr = 0;
+ while (alen--)
+ {
+ addr = (addr << 8) + gbyte ();
+ length--;
+ }
+
+ for (i = 0; i < length - 1; i++)
+ myaddr[i + addr - memaddr] = gbyte ();
+
+ gbyte (); /* Ignore checksum */
+ }
+ }
+ }
+ }
+
+ putchar_e7000 (ACK);
+ expect ("TOP ADDRESS =");
+ expect ("END ADDRESS =");
+ expect (":");
+
+ return len;
+}
+
+#endif
+
+/* Transfer LEN bytes between GDB address MYADDR and target address
+ MEMADDR. If WRITE is non-zero, transfer them to the target,
+ otherwise transfer them from the target. TARGET is unused.
+
+ Returns the number of bytes transferred. */
+
+static int
+e7000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int write, struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ if (write)
+ return e7000_write_inferior_memory (memaddr, myaddr, len);
+ else if (len < 16)
+ return e7000_read_inferior_memory (memaddr, myaddr, len);
+ else
+ return e7000_read_inferior_memory_large (memaddr, myaddr, len);
+}
+
+static void
+e7000_kill (void)
+{
+}
+
+static void
+e7000_load (char *args, int from_tty)
+{
+ struct cleanup *old_chain;
+ asection *section;
+ bfd *pbfd;
+ bfd_vma entry;
+#define WRITESIZE 0x1000
+ char buf[2 + 4 + 4 + WRITESIZE]; /* `DT' + <addr> + <len> + <data> */
+ char *filename;
+ int quiet;
+ int nostart;
+ time_t start_time, end_time; /* Start and end times of download */
+ unsigned long data_count; /* Number of bytes transferred to memory */
+ int oldtimeout = timeout;
+
+ timeout = remote_timeout;
+
+
+ /* FIXME! change test to test for type of download */
+ if (!using_tcp)
+ {
+ generic_load (args, from_tty);
+ return;
+ }
+
+ /* for direct tcp connections, we can do a fast binary download */
+ buf[0] = 'D';
+ buf[1] = 'T';
+ quiet = 0;
+ nostart = 0;
+ filename = NULL;
+
+ while (*args != '\000')
+ {
+ char *arg;
+
+ while (isspace (*args))
+ args++;
+
+ arg = args;
+
+ while ((*args != '\000') && !isspace (*args))
+ args++;
+
+ if (*args != '\000')
+ *args++ = '\000';
+
+ if (*arg != '-')
+ filename = arg;
+ else if (strncmp (arg, "-quiet", strlen (arg)) == 0)
+ quiet = 1;
+ else if (strncmp (arg, "-nostart", strlen (arg)) == 0)
+ nostart = 1;
+ else
+ error ("unknown option `%s'", arg);
+ }
+
+ if (!filename)
+ filename = get_exec_file (1);
+
+ pbfd = bfd_openr (filename, gnutarget);
+ if (pbfd == NULL)
+ {
+ perror_with_name (filename);
+ return;
+ }
+ old_chain = make_cleanup_bfd_close (pbfd);
+
+ if (!bfd_check_format (pbfd, bfd_object))
+ error ("\"%s\" is not an object file: %s", filename,
+ bfd_errmsg (bfd_get_error ()));
+
+ start_time = time (NULL);
+ data_count = 0;
+
+ puts_e7000debug ("mw\r");
+
+ expect ("\nOK");
+
+ for (section = pbfd->sections; section; section = section->next)
+ {
+ if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
+ {
+ bfd_vma section_address;
+ bfd_size_type section_size;
+ file_ptr fptr;
+
+ section_address = bfd_get_section_vma (pbfd, section);
+ section_size = bfd_get_section_size_before_reloc (section);
+
+ if (!quiet)
+ printf_filtered ("[Loading section %s at 0x%s (%s bytes)]\n",
+ bfd_get_section_name (pbfd, section),
+ paddr_nz (section_address),
+ paddr_u (section_size));
+
+ fptr = 0;
+
+ data_count += section_size;
+
+ while (section_size > 0)
+ {
+ int count;
+ static char inds[] = "|/-\\";
+ static int k = 0;
+
+ QUIT;
+
+ count = min (section_size, WRITESIZE);
+
+ buf[2] = section_address >> 24;
+ buf[3] = section_address >> 16;
+ buf[4] = section_address >> 8;
+ buf[5] = section_address;
+
+ buf[6] = count >> 24;
+ buf[7] = count >> 16;
+ buf[8] = count >> 8;
+ buf[9] = count;
+
+ bfd_get_section_contents (pbfd, section, buf + 10, fptr, count);
+
+ if (serial_write (e7000_desc, buf, count + 10))
+ fprintf_unfiltered (gdb_stderr,
+ "e7000_load: serial_write failed: %s\n",
+ safe_strerror (errno));
+
+ expect ("OK");
+
+ if (!quiet)
+ {
+ printf_unfiltered ("\r%c", inds[k++ % 4]);
+ gdb_flush (gdb_stdout);
+ }
+
+ section_address += count;
+ fptr += count;
+ section_size -= count;
+ }
+ }
+ }
+
+ write_e7000 ("ED");
+
+ expect_prompt ();
+
+ end_time = time (NULL);
+
+/* Finally, make the PC point at the start address */
+
+ if (exec_bfd)
+ write_pc (bfd_get_start_address (exec_bfd));
+
+ inferior_ptid = null_ptid; /* No process now */
+
+/* This is necessary because many things were based on the PC at the time that
+ we attached to the monitor, which is no longer valid now that we have loaded
+ new code (and just changed the PC). Another way to do this might be to call
+ normal_stop, except that the stack may not be valid, and things would get
+ horribly confused... */
+
+ clear_symtab_users ();
+
+ if (!nostart)
+ {
+ entry = bfd_get_start_address (pbfd);
+
+ if (!quiet)
+ printf_unfiltered ("[Starting %s at 0x%s]\n", filename, paddr_nz (entry));
+
+/* start_routine (entry); */
+ }
+
+ report_transfer_performance (data_count, start_time, end_time);
+
+ do_cleanups (old_chain);
+ timeout = oldtimeout;
+}
+
+/* Clean up when a program exits.
+
+ The program actually lives on in the remote processor's RAM, and may be
+ run again without a download. Don't leave it full of breakpoint
+ instructions. */
+
+static void
+e7000_mourn_inferior (void)
+{
+ remove_breakpoints ();
+ unpush_target (&e7000_ops);
+ generic_mourn_inferior (); /* Do all the proper things now */
+}
+
+#define MAX_BREAKPOINTS 200
+#ifdef HARD_BREAKPOINTS
+#define MAX_E7000DEBUG_BREAKPOINTS (BC_BREAKPOINTS ? 5 : MAX_BREAKPOINTS)
+#else
+#define MAX_E7000DEBUG_BREAKPOINTS MAX_BREAKPOINTS
+#endif
+
+/* Since we can change to soft breakpoints dynamically, we must define
+ more than enough. Was breakaddr[MAX_E7000DEBUG_BREAKPOINTS]. */
+static CORE_ADDR breakaddr[MAX_BREAKPOINTS] =
+{0};
+
+static int
+e7000_insert_breakpoint (CORE_ADDR addr, char *shadow)
+{
+ int i;
+ char buf[200];
+#if 0
+ static char nop[2] = NOP;
+#endif
+
+ for (i = 0; i <= MAX_E7000DEBUG_BREAKPOINTS; i++)
+ if (breakaddr[i] == 0)
+ {
+ breakaddr[i] = addr;
+ /* Save old contents, and insert a nop in the space */
+#ifdef HARD_BREAKPOINTS
+ if (BC_BREAKPOINTS)
+ {
+ sprintf (buf, "BC%d A=%s\r", i + 1, paddr_nz (addr));
+ puts_e7000debug (buf);
+ }
+ else
+ {
+ sprintf (buf, "B %s\r", paddr_nz (addr));
+ puts_e7000debug (buf);
+ }
+#else
+#if 0
+ e7000_read_inferior_memory (addr, shadow, 2);
+ e7000_write_inferior_memory (addr, nop, 2);
+#endif
+
+ sprintf (buf, "B %x\r", addr);
+ puts_e7000debug (buf);
+#endif
+ expect_prompt ();
+ return 0;
+ }
+
+ error ("Too many breakpoints ( > %d) for the E7000\n",
+ MAX_E7000DEBUG_BREAKPOINTS);
+ return 1;
+}
+
+static int
+e7000_remove_breakpoint (CORE_ADDR addr, char *shadow)
+{
+ int i;
+ char buf[200];
+
+ for (i = 0; i < MAX_E7000DEBUG_BREAKPOINTS; i++)
+ if (breakaddr[i] == addr)
+ {
+ breakaddr[i] = 0;
+#ifdef HARD_BREAKPOINTS
+ if (BC_BREAKPOINTS)
+ {
+ sprintf (buf, "BC%d - \r", i + 1);
+ puts_e7000debug (buf);
+ }
+ else
+ {
+ sprintf (buf, "B - %s\r", paddr_nz (addr));
+ puts_e7000debug (buf);
+ }
+ expect_prompt ();
+#else
+ sprintf (buf, "B - %s\r", paddr_nz (addr));
+ puts_e7000debug (buf);
+ expect_prompt ();
+
+#if 0
+ /* Replace the insn under the break */
+ e7000_write_inferior_memory (addr, shadow, 2);
+#endif
+#endif
+
+ return 0;
+ }
+
+ warning ("Can't find breakpoint associated with 0x%s\n", paddr_nz (addr));
+ return 1;
+}
+
+/* Put a command string, in args, out to STDBUG. Output from STDBUG
+ is placed on the users terminal until the prompt is seen. */
+
+static void
+e7000_command (char *args, int fromtty)
+{
+ /* FIXME: arbitrary limit on length of args. */
+ char buf[200];
+
+ echo = 0;
+
+ if (!e7000_desc)
+ error ("e7000 target not open.");
+ if (!args)
+ {
+ puts_e7000debug ("\r");
+ }
+ else
+ {
+ sprintf (buf, "%s\r", args);
+ puts_e7000debug (buf);
+ }
+
+ echo++;
+ ctrl_c = 2;
+ expect_full_prompt ();
+ echo--;
+ ctrl_c = 0;
+ printf_unfiltered ("\n");
+
+ /* Who knows what the command did... */
+ registers_changed ();
+}
+
+
+static void
+e7000_drain_command (char *args, int fromtty)
+{
+ int c;
+
+ puts_e7000debug ("end\r");
+ putchar_e7000 (CTRLC);
+
+ while ((c = readchar (1) != -1))
+ {
+ if (quit_flag)
+ {
+ putchar_e7000 (CTRLC);
+ quit_flag = 0;
+ }
+ if (c > ' ' && c < 127)
+ printf_unfiltered ("%c", c & 0xff);
+ else
+ printf_unfiltered ("<%x>", c & 0xff);
+ }
+}
+
+#define NITEMS 7
+
+static int
+why_stop (void)
+{
+ static char *strings[NITEMS] =
+ {
+ "STEP NORMAL",
+ "BREAK POINT",
+ "BREAK KEY",
+ "BREAK CONDI",
+ "CYCLE ACCESS",
+ "ILLEGAL INSTRUCTION",
+ "WRITE PROTECT",
+ };
+ char *p[NITEMS];
+ int c;
+ int i;
+
+ for (i = 0; i < NITEMS; ++i)
+ p[i] = strings[i];
+
+ c = gch ();
+ while (1)
+ {
+ for (i = 0; i < NITEMS; i++)
+ {
+ if (c == *(p[i]))
+ {
+ p[i]++;
+ if (*(p[i]) == 0)
+ {
+ /* found one of the choices */
+ return i;
+ }
+ }
+ else
+ p[i] = strings[i];
+ }
+
+ c = gch ();
+ }
+}
+
+/* Suck characters, if a string match, then return the strings index
+ otherwise echo them. */
+
+int
+expect_n (char **strings)
+{
+ char *(ptr[10]);
+ int n;
+ int c;
+ char saveaway[100];
+ char *buffer = saveaway;
+ /* Count number of expect strings */
+
+ for (n = 0; strings[n]; n++)
+ {
+ ptr[n] = strings[n];
+ }
+
+ while (1)
+ {
+ int i;
+ int gotone = 0;
+
+ c = readchar (1);
+ if (c == -1)
+ {
+ printf_unfiltered ("[waiting for e7000...]\n");
+ }
+#ifdef __GO32__
+ if (kbhit ())
+ {
+ int k = getkey ();
+
+ if (k == 1)
+ quit_flag = 1;
+ }
+#endif
+ if (quit_flag)
+ {
+ putchar_e7000 (CTRLC); /* interrupt the running program */
+ quit_flag = 0;
+ }
+
+ for (i = 0; i < n; i++)
+ {
+ if (c == ptr[i][0])
+ {
+ ptr[i]++;
+ if (ptr[i][0] == 0)
+ {
+ /* Gone all the way */
+ return i;
+ }
+ gotone = 1;
+ }
+ else
+ {
+ ptr[i] = strings[i];
+ }
+ }
+
+ if (gotone)
+ {
+ /* Save it up incase we find that there was no match */
+ *buffer++ = c;
+ }
+ else
+ {
+ if (buffer != saveaway)
+ {
+ *buffer++ = 0;
+ printf_unfiltered ("%s", buffer);
+ buffer = saveaway;
+ }
+ if (c != -1)
+ {
+ putchar_unfiltered (c);
+ gdb_flush (gdb_stdout);
+ }
+ }
+ }
+}
+
+/* We subtract two from the pc here rather than use
+ DECR_PC_AFTER_BREAK since the e7000 doesn't always add two to the
+ pc, and the simulators never do. */
+
+static void
+sub2_from_pc (void)
+{
+ char buf[4];
+ char buf2[200];
+
+ store_signed_integer (buf,
+ REGISTER_RAW_SIZE (PC_REGNUM),
+ read_register (PC_REGNUM) - 2);
+ supply_register (PC_REGNUM, buf);
+ sprintf (buf2, ".PC %s\r", phex_nz (read_register (PC_REGNUM), 0));
+ puts_e7000debug (buf2);
+}
+
+#define WAS_SLEEP 0
+#define WAS_INT 1
+#define WAS_RUNNING 2
+#define WAS_OTHER 3
+
+static char *estrings[] =
+{
+ "** SLEEP",
+ "BREAK !",
+ "** PC",
+ "PC",
+ NULL
+};
+
+/* Wait until the remote machine stops, then return, storing status in
+ STATUS just as `wait' would. */
+
+static ptid_t
+e7000_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ int stop_reason;
+ int regno;
+ int running_count = 0;
+ int had_sleep = 0;
+ int loop = 1;
+ char *wanted_nopc = NULL;
+
+ /* Then echo chars until PC= string seen */
+ gch (); /* Drop cr */
+ gch (); /* and space */
+
+ while (loop)
+ {
+ switch (expect_n (estrings))
+ {
+ case WAS_OTHER:
+ /* how did this happen ? */
+ loop = 0;
+ break;
+ case WAS_SLEEP:
+ had_sleep = 1;
+ putchar_e7000 (CTRLC);
+ loop = 0;
+ break;
+ case WAS_INT:
+ loop = 0;
+ break;
+ case WAS_RUNNING:
+ running_count++;
+ if (running_count == 20)
+ {
+ printf_unfiltered ("[running...]\n");
+ running_count = 0;
+ }
+ break;
+ default:
+ /* error? */
+ break;
+ }
+ }
+
+ /* Skip till the PC= */
+ expect ("=");
+
+ if (TARGET_ARCHITECTURE->arch == bfd_arch_sh)
+ {
+ wanted_nopc = want_nopc_sh;
+ switch (TARGET_ARCHITECTURE->mach)
+ {
+ case bfd_mach_sh3:
+ case bfd_mach_sh3e:
+ case bfd_mach_sh4:
+ wanted_nopc = want_nopc_sh3;
+ }
+ }
+#ifdef GDB_TARGET_IS_H8300
+ if (TARGET_ARCHITECTURE->arch == bfd_arch_h8300)
+ {
+ if (h8300smode)
+ wanted_nopc = want_nopc_h8300s;
+ else
+ wanted_nopc = want_nopc_h8300h;
+ }
+#endif
+ fetch_regs_from_dump (gch, wanted_nopc);
+
+ /* And supply the extra ones the simulator uses */
+ for (regno = NUM_REALREGS; regno < NUM_REGS; regno++)
+ {
+ int buf = 0;
+ supply_register (regno, (char *) &buf);
+ }
+
+ stop_reason = why_stop ();
+ expect_full_prompt ();
+
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+
+ switch (stop_reason)
+ {
+ case 1: /* Breakpoint */
+ write_pc (read_pc ()); /* PC is always off by 2 for breakpoints */
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ break;
+ case 0: /* Single step */
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ break;
+ case 2: /* Interrupt */
+ if (had_sleep)
+ {
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ sub2_from_pc ();
+ }
+ else
+ {
+ status->value.sig = TARGET_SIGNAL_INT;
+ }
+ break;
+ case 3:
+ break;
+ case 4:
+ printf_unfiltered ("a cycle address error?\n");
+ status->value.sig = TARGET_SIGNAL_UNKNOWN;
+ break;
+ case 5:
+ status->value.sig = TARGET_SIGNAL_ILL;
+ break;
+ case 6:
+ status->value.sig = TARGET_SIGNAL_SEGV;
+ break;
+ case 7: /* Anything else (NITEMS + 1) */
+ printf_unfiltered ("a write protect error?\n");
+ status->value.sig = TARGET_SIGNAL_UNKNOWN;
+ break;
+ default:
+ /* Get the user's attention - this should never happen. */
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+
+ return inferior_ptid;
+}
+
+/* Stop the running program. */
+
+static void
+e7000_stop (void)
+{
+ /* Sending a ^C is supposed to stop the running program. */
+ putchar_e7000 (CTRLC);
+}
+
+/* Define the target subroutine names. */
+
+struct target_ops e7000_ops;
+
+static void
+init_e7000_ops (void)
+{
+ e7000_ops.to_shortname = "e7000";
+ e7000_ops.to_longname = "Remote Hitachi e7000 target";
+ e7000_ops.to_doc = "Use a remote Hitachi e7000 ICE connected by a serial line;\n\
+or a network connection.\n\
+Arguments are the name of the device for the serial line,\n\
+the speed to connect at in bits per second.\n\
+eg\n\
+target e7000 /dev/ttya 9600\n\
+target e7000 foobar";
+ e7000_ops.to_open = e7000_open;
+ e7000_ops.to_close = e7000_close;
+ e7000_ops.to_attach = 0;
+ e7000_ops.to_post_attach = NULL;
+ e7000_ops.to_require_attach = NULL;
+ e7000_ops.to_detach = e7000_detach;
+ e7000_ops.to_require_detach = NULL;
+ e7000_ops.to_resume = e7000_resume;
+ e7000_ops.to_wait = e7000_wait;
+ e7000_ops.to_post_wait = NULL;
+ e7000_ops.to_fetch_registers = e7000_fetch_register;
+ e7000_ops.to_store_registers = e7000_store_register;
+ e7000_ops.to_prepare_to_store = e7000_prepare_to_store;
+ e7000_ops.to_xfer_memory = e7000_xfer_inferior_memory;
+ e7000_ops.to_files_info = e7000_files_info;
+ e7000_ops.to_insert_breakpoint = e7000_insert_breakpoint;
+ e7000_ops.to_remove_breakpoint = e7000_remove_breakpoint;
+ e7000_ops.to_terminal_init = 0;
+ e7000_ops.to_terminal_inferior = 0;
+ e7000_ops.to_terminal_ours_for_output = 0;
+ e7000_ops.to_terminal_ours = 0;
+ e7000_ops.to_terminal_info = 0;
+ e7000_ops.to_kill = e7000_kill;
+ e7000_ops.to_load = e7000_load;
+ e7000_ops.to_lookup_symbol = 0;
+ e7000_ops.to_create_inferior = e7000_create_inferior;
+ e7000_ops.to_post_startup_inferior = NULL;
+ e7000_ops.to_acknowledge_created_inferior = NULL;
+ e7000_ops.to_clone_and_follow_inferior = NULL;
+ e7000_ops.to_post_follow_inferior_by_clone = NULL;
+ e7000_ops.to_insert_fork_catchpoint = NULL;
+ e7000_ops.to_remove_fork_catchpoint = NULL;
+ e7000_ops.to_insert_vfork_catchpoint = NULL;
+ e7000_ops.to_remove_vfork_catchpoint = NULL;
+ e7000_ops.to_has_forked = NULL;
+ e7000_ops.to_has_vforked = NULL;
+ e7000_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ e7000_ops.to_post_follow_vfork = NULL;
+ e7000_ops.to_insert_exec_catchpoint = NULL;
+ e7000_ops.to_remove_exec_catchpoint = NULL;
+ e7000_ops.to_has_execd = NULL;
+ e7000_ops.to_reported_exec_events_per_exec_call = NULL;
+ e7000_ops.to_has_exited = NULL;
+ e7000_ops.to_mourn_inferior = e7000_mourn_inferior;
+ e7000_ops.to_can_run = 0;
+ e7000_ops.to_notice_signals = 0;
+ e7000_ops.to_thread_alive = 0;
+ e7000_ops.to_stop = e7000_stop;
+ e7000_ops.to_pid_to_exec_file = NULL;
+ e7000_ops.to_stratum = process_stratum;
+ e7000_ops.DONT_USE = 0;
+ e7000_ops.to_has_all_memory = 1;
+ e7000_ops.to_has_memory = 1;
+ e7000_ops.to_has_stack = 1;
+ e7000_ops.to_has_registers = 1;
+ e7000_ops.to_has_execution = 1;
+ e7000_ops.to_sections = 0;
+ e7000_ops.to_sections_end = 0;
+ e7000_ops.to_magic = OPS_MAGIC;
+};
+
+void
+_initialize_remote_e7000 (void)
+{
+ init_e7000_ops ();
+ add_target (&e7000_ops);
+
+ add_com ("e7000", class_obscure, e7000_command,
+ "Send a command to the e7000 monitor.");
+
+ add_com ("ftplogin", class_obscure, e7000_login_command,
+ "Login to machine and change to directory.");
+
+ add_com ("ftpload", class_obscure, e7000_ftp_command,
+ "Fetch and load a file from previously described place.");
+
+ add_com ("drain", class_obscure, e7000_drain_command,
+ "Drain pending e7000 text buffers.");
+
+ add_show_from_set (add_set_cmd ("usehardbreakpoints", no_class,
+ var_integer, (char *) &use_hard_breakpoints,
+ "Set use of hardware breakpoints for all breakpoints.\n", &setlist),
+ &showlist);
+}
diff --git a/gdb/remote-es.c b/gdb/remote-es.c
new file mode 100644
index 00000000000..e489254bcc0
--- /dev/null
+++ b/gdb/remote-es.c
@@ -0,0 +1,2127 @@
+/* Memory-access and commands for remote es1800 processes, for GDB.
+
+ Copyright 1988, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
+ 2001, 2002 Free Software Foundation, Inc.
+
+ This file is added to GDB to make it possible to do debugging via an
+ ES-1800 emulator. The code was originally written by Johan Holmberg
+ TT/SJ Ericsson Telecom AB and later modified by Johan Henriksson
+ TT/SJ. It was modified for gdb 4.0 by TX/DK Jan Nordenand by TX/DKG
+ Harald Johansen.
+
+ This file is part of GDB.
+
+ GDB 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 1, or (at your option)
+ any later version.
+
+ GDB 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. */
+
+
+/* Emulator communication protocol.
+ All values are encoded in ascii hex digits.
+
+ Request
+ Command
+ Reply
+ read registers:
+ DR<cr>
+ - 0 - - 1 - - 2 - - 3 - - 4 - - 5 - -- 6 - - 7 -
+ D = XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
+ A = XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
+ PC = XXXXXX SSP = XXXXXX USP = XXXXXX SR = XXXXXXXX
+ >
+ Each byte of register data is described by two hex digits.
+
+ write regs
+ D0=XXXXXXXX<cr>
+ >D1=XXXXXXXX<cr>
+ >D2=XXXXXXXX<cr>
+ >D3=XXXXXXXX<cr>
+ >D4=XXXXXXXX<cr>
+ >D5=XXXXXXXX<cr>
+ >D6=XXXXXXXX<cr>
+ >D7=XXXXXXXX<cr>
+ >A0=XXXXXXXX<cr>
+ >A1=XXXXXXXX<cr>
+ >A2=XXXXXXXX<cr>
+ >A3=XXXXXXXX<cr>
+ >A4=XXXXXXXX<cr>
+ >A5=XXXXXXXX<cr>
+ >A6=XXXXXXXX<cr>
+ >A7=XXXXXXXX<cr>
+ >SR=XXXXXXXX<cr>
+ >PC=XXXXXX<cr>
+ >
+ Each byte of register data is described by two hex digits.
+
+ read mem
+ @.BAA..AA
+ $FFFFFFXX
+ >
+ AA..AA is address, XXXXXXX is the contents
+
+ write mem
+ @.BAA..AA=$XXXXXXXX
+ >
+ AA..AA is address, XXXXXXXX is data
+
+ cont
+ PC=$AA..AA
+ >RBK
+ R>
+ AA..AA is address to resume. If AA..AA is omitted, resume at same address.
+
+ step
+ PC=$AA..AA
+ >STP
+ R>
+ AA..AA is address to resume. If AA..AA is omitted, resume at same address.
+
+ kill req
+ STP
+ >
+ */
+
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include <errno.h>
+#include <ctype.h>
+#include <setjmp.h>
+#include <fcntl.h>
+#include "defs.h"
+#include "gdb_string.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "command.h"
+#include "symfile.h"
+#include "remote-utils.h"
+#include "gdbcore.h"
+#include "serial.h"
+#include "regcache.h"
+#include "value.h"
+
+/* Prototypes for local functions */
+
+static void es1800_child_detach (char *, int);
+
+static void es1800_child_open (char *, int);
+
+static void es1800_transparent (char *, int);
+
+static void es1800_create_inferior (char *, char *, char **);
+
+static void es1800_load (char *, int);
+
+static void es1800_kill (void);
+
+static int verify_break (int);
+
+static int es1800_remove_breakpoint (CORE_ADDR, char *);
+
+static int es1800_insert_breakpoint (CORE_ADDR, char *);
+
+static void es1800_files_info (struct target_ops *);
+
+static int
+es1800_xfer_inferior_memory (CORE_ADDR, char *, int, int,
+ struct mem_attrib *, struct target_ops *);
+
+static void es1800_prepare_to_store (void);
+
+static ptid_t es1800_wait (ptid_t, struct target_waitstatus *);
+
+static void es1800_resume (ptid_t, int, enum target_signal);
+
+static void es1800_detach (char *, int);
+
+static void es1800_attach (char *, int);
+
+static int damn_b (char *);
+
+static void es1800_open (char *, int);
+
+static void es1800_timer (void);
+
+static void es1800_reset (char *);
+
+static void es1800_request_quit (void);
+
+static int readchar (void);
+
+static void expect (char *, int);
+
+static void expect_prompt (void);
+
+static void download (FILE *, int, int);
+
+#if 0
+static void bfd_copy (bfd *, bfd *);
+#endif
+
+static void get_break_addr (int, CORE_ADDR *);
+
+static int fromhex (int);
+
+static int tohex (int);
+
+static void es1800_close (int);
+
+static void es1800_fetch_registers (void);
+
+static void es1800_fetch_register (int);
+
+static void es1800_store_register (int);
+
+static void es1800_read_bytes (CORE_ADDR, char *, int);
+
+static void es1800_write_bytes (CORE_ADDR, char *, int);
+
+static void send_with_reply (char *, char *, int);
+
+static void send_command (char *);
+
+static void send (char *);
+
+static void getmessage (char *, int);
+
+static void es1800_mourn_inferior (void);
+
+static void es1800_create_break_insn (char *, int);
+
+static void es1800_init_break (char *, int);
+
+/* Local variables */
+
+/* FIXME: Convert this to use "set remotedebug" instead. */
+#define LOG_FILE "es1800.log"
+#if defined (LOG_FILE)
+static FILE *log_file;
+#endif
+
+extern struct target_ops es1800_ops; /* Forward decl */
+extern struct target_ops es1800_child_ops; /* Forward decl */
+
+static int kiodebug;
+static int timeout = 100;
+static char *savename; /* Name of i/o device used */
+static serial_ttystate es1800_saved_ttystate;
+static int es1800_fc_save; /* Save fcntl state */
+
+/* indicates that the emulator uses 32-bit data-adress (68020-mode)
+ instead of 24-bit (68000 -mode) */
+
+static int m68020;
+
+#define MODE (m68020 ? "M68020" : "M68000" )
+#define ES1800_BREAK_VEC (0xf)
+
+/* Descriptor for I/O to remote machine. Initialize it to NULL so that
+ es1800_open knows that we don't have a file open when the program
+ starts. */
+
+static struct serial *es1800_desc = NULL;
+
+#define PBUFSIZ 1000
+#define HDRLEN sizeof("@.BAAAAAAAA=$VV\r")
+
+/* Maximum number of bytes to read/write at once. The value here
+ is chosen to fill up a packet. */
+
+#define MAXBUFBYTES ((PBUFSIZ-150)*16/75 )
+
+static int es1800_break_vec = 0;
+static char es1800_break_insn[2];
+static long es1800_break_address;
+static void (*old_sigint) (); /* Old signal-handler for sigint */
+static jmp_buf interrupt;
+
+/* Local signalhandler to allow breaking tranfers or program run.
+ Rely on global variables: old_sigint(), interrupt */
+
+static void
+es1800_request_quit (void)
+{
+ /* restore original signalhandler */
+ signal (SIGINT, old_sigint);
+ longjmp (interrupt, 1);
+}
+
+
+/* Reset emulator.
+ Sending reset character(octal 32) to emulator.
+ quit - return to '(esgdb)' prompt or continue */
+
+static void
+es1800_reset (char *quit)
+{
+ char buf[80];
+
+ if (quit)
+ {
+ printf ("\nResetting emulator... ");
+ }
+ strcpy (buf, "\032");
+ send (buf);
+ expect_prompt ();
+ if (quit)
+ {
+ error ("done\n");
+ }
+}
+
+
+/* Open a connection to a remote debugger and push the new target
+ onto the stack. Check if the emulator is responding and find out
+ what kind of processor the emulator is connected to.
+ Initiate the breakpoint handling in the emulator.
+
+ name - the filename used for communication (ex. '/dev/tta')
+ from_tty - says whether to be verbose or not */
+
+static void
+es1800_open (char *name, int from_tty)
+{
+ char buf[PBUFSIZ];
+ char *p;
+ int i, fcflag;
+
+ m68020 = 0;
+
+ if (!name) /* no device name given in target command */
+ {
+ error_no_arg ("serial port device name");
+ }
+
+ target_preopen (from_tty);
+ es1800_close (0);
+
+ /* open the device and configure it for communication */
+
+#ifndef DEBUG_STDIN
+
+ es1800_desc = serial_open (name);
+ if (es1800_desc == NULL)
+ {
+ perror_with_name (name);
+ }
+ savename = savestring (name, strlen (name));
+
+ es1800_saved_ttystate = serial_get_tty_state (es1800_desc);
+
+ if ((fcflag = fcntl (deprecated_serial_fd (es1800_desc), F_GETFL, 0)) == -1)
+ {
+ perror_with_name ("fcntl serial");
+ }
+ es1800_fc_save = fcflag;
+
+ fcflag = (fcflag & (FREAD | FWRITE)); /* mask out any funny stuff */
+ if (fcntl (deprecated_serial_fd (es1800_desc), F_SETFL, fcflag) == -1)
+ {
+ perror_with_name ("fcntl serial");
+ }
+
+ if (baud_rate != -1)
+ {
+ if (serial_setbaudrate (es1800_desc, baud_rate))
+ {
+ serial_close (es1800_desc);
+ perror_with_name (name);
+ }
+ }
+
+ serial_raw (es1800_desc);
+
+ /* If there is something sitting in the buffer we might take it as a
+ response to a command, which would be bad. */
+ serial_flush_input (es1800_desc);
+
+#endif /* DEBUG_STDIN */
+
+ push_target (&es1800_ops); /* Switch to using remote target now */
+ if (from_tty)
+ {
+ printf ("Remote ES1800 debugging using %s\n", name);
+ }
+
+#if defined (LOG_FILE)
+
+ log_file = fopen (LOG_FILE, "w");
+ if (log_file == NULL)
+ {
+ perror_with_name (LOG_FILE);
+ }
+
+#endif /* LOG_FILE */
+
+ /* Hello? Are you there?, also check mode */
+
+ /* send_with_reply( "DB 0 TO 1", buf, sizeof(buf)); */
+ /* for (p = buf, i = 0; *p++ =='0';) *//* count the number of zeros */
+ /* i++; */
+
+ send ("\032");
+ getmessage (buf, sizeof (buf)); /* send reset character */
+
+ if (from_tty)
+ {
+ printf ("Checking mode.... ");
+ }
+ /* m68020 = (i==8); *//* if eight zeros then we are in m68020 mode */
+
+ /* What kind of processor am i talking to ? */
+ p = buf;
+ while (*p++ != '\n')
+ {;
+ }
+ while (*p++ != '\n')
+ {;
+ }
+ while (*p++ != '\n')
+ {;
+ }
+ for (i = 0; i < 20; i++, p++)
+ {;
+ }
+ m68020 = !strncmp (p, "68020", 5);
+ if (from_tty)
+ {
+ printf ("You are in %s(%c%c%c%c%c)-mode\n", MODE, p[0], p[1], p[2],
+ p[3], p[4]);
+ }
+
+ /* if no init_break statement is present in .gdb file we have to check
+ whether to download a breakpoint routine or not */
+
+#if 0
+ if ((es1800_break_vec == 0) || (verify_break (es1800_break_vec) != 0)
+ && query ("No breakpoint routine in ES 1800 emulator!\nDownload a breakpoint routine to the emulator? "))
+ {
+ CORE_ADDR memaddress;
+ printf ("Give the start address of the breakpoint routine: ");
+ scanf ("%li", &memaddress);
+ es1800_init_break ((es1800_break_vec ? es1800_break_vec :
+ ES1800_BREAK_VEC), memaddress);
+ }
+#endif
+
+}
+
+/* Close out all files and local state before this target loses control.
+ quitting - are we quitting gdb now? */
+
+static void
+es1800_close (int quitting)
+{
+ if (es1800_desc != NULL)
+ {
+ printf ("\nClosing connection to emulator...\n");
+ if (serial_set_tty_state (es1800_desc, es1800_saved_ttystate) < 0)
+ print_sys_errmsg ("warning: unable to restore tty state", errno);
+ fcntl (deprecated_serial_fd (es1800_desc), F_SETFL, es1800_fc_save);
+ serial_close (es1800_desc);
+ es1800_desc = NULL;
+ }
+ if (savename != NULL)
+ {
+ xfree (savename);
+ }
+ savename = NULL;
+
+#if defined (LOG_FILE)
+
+ if (log_file != NULL)
+ {
+ if (ferror (log_file))
+ {
+ printf ("Error writing log file.\n");
+ }
+ if (fclose (log_file) != 0)
+ {
+ printf ("Error closing log file.\n");
+ }
+ log_file = NULL;
+ }
+
+#endif /* LOG_FILE */
+
+}
+
+/* Attaches to a process on the target side
+ proc_id - the id of the process to be attached.
+ from_tty - says whether to be verbose or not */
+
+static void
+es1800_attach (char *args, int from_tty)
+{
+ error ("Cannot attach to pid %s, this feature is not implemented yet.",
+ args);
+}
+
+
+/* Takes a program previously attached to and detaches it.
+ We better not have left any breakpoints
+ in the program or it'll die when it hits one.
+ Close the open connection to the remote debugger.
+ Use this when you want to detach and do something else
+ with your gdb.
+
+ args - arguments given to the 'detach' command
+ from_tty - says whether to be verbose or not */
+
+static void
+es1800_detach (char *args, int from_tty)
+{
+ if (args)
+ {
+ error ("Argument given to \"detach\" when remotely debugging.");
+ }
+ pop_target ();
+ if (from_tty)
+ {
+ printf ("Ending es1800 remote debugging.\n");
+ }
+}
+
+
+/* Tell the remote machine to resume.
+ step - single-step or run free
+ siggnal - the signal value to be given to the target (0 = no signal) */
+
+static void
+es1800_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ char buf[PBUFSIZ];
+
+ if (siggnal)
+ {
+ error ("Can't send signals to a remote system.");
+ }
+ if (step)
+ {
+ strcpy (buf, "STP\r");
+ send (buf);
+ }
+ else
+ {
+ send_command ("RBK");
+ }
+}
+
+/* Wait until the remote machine stops, then return,
+ storing status in STATUS just as `wait' would.
+ status - */
+
+static ptid_t
+es1800_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ unsigned char buf[PBUFSIZ];
+ int old_timeout = timeout;
+
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = 0;
+
+ timeout = 0; /* Don't time out -- user program is running. */
+ if (!setjmp (interrupt))
+ {
+ old_sigint = signal (SIGINT, es1800_request_quit);
+ while (1)
+ {
+ getmessage (buf, sizeof (buf));
+ if (strncmp (buf, "\r\n* BREAK *", 11) == 0)
+ {
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ send_command ("STP"); /* Restore stack and PC and such */
+ if (m68020)
+ {
+ send_command ("STP");
+ }
+ break;
+ }
+ if (strncmp (buf, "STP\r\n ", 6) == 0)
+ {
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ break;
+ }
+ if (buf[strlen (buf) - 2] == 'R')
+ {
+ printf ("Unexpected emulator reply: \n%s\n", buf);
+ }
+ else
+ {
+ printf ("Unexpected stop: \n%s\n", buf);
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_QUIT;
+ break;
+ }
+ }
+ }
+ else
+ {
+ fflush (stdin);
+ printf ("\nStopping emulator...");
+ if (!setjmp (interrupt))
+ {
+ old_sigint = signal (SIGINT, es1800_request_quit);
+ send_command ("STP");
+ printf (" emulator stopped\n");
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_INT;
+ }
+ else
+ {
+ fflush (stdin);
+ es1800_reset ((char *) 1);
+ }
+ }
+ signal (SIGINT, old_sigint);
+ timeout = old_timeout;
+ return inferior_ptid;
+}
+
+
+/* Fetch register values from remote machine.
+ regno - the register to be fetched (fetch all registers if -1) */
+
+static void
+es1800_fetch_register (int regno)
+{
+ char buf[PBUFSIZ];
+ int k;
+ int r;
+ char *p;
+ static char regtab[18][4] =
+ {
+ "D0 ", "D1 ", "D2 ", "D3 ", "D4 ", "D5 ", "D6 ", "D7 ",
+ "A0 ", "A1 ", "A2 ", "A3 ", "A4 ", "A5 ", "A6 ", "SSP",
+ "SR ", "PC "
+ };
+
+ if ((regno < 15) || (regno == 16) || (regno == 17))
+ {
+ r = regno * 4;
+ send_with_reply (regtab[regno], buf, sizeof (buf));
+ p = buf;
+ for (k = 0; k < 4; k++)
+ {
+ if ((p[k * 2 + 1] == 0) || (p[k * 2 + 2] == 0))
+ {
+ error ("Emulator reply is too short: %s", buf);
+ }
+ registers[r++] = (fromhex (p[k * 2 + 1]) * 16) + fromhex (p[k * 2 + 2]);
+ }
+ }
+ else
+ {
+ es1800_fetch_registers ();
+ }
+}
+
+/* Read the remote registers into REGISTERS.
+ Always fetches all registers. */
+
+static void
+es1800_fetch_registers (void)
+{
+ char buf[PBUFSIZ];
+ char SR_buf[PBUFSIZ];
+ int i;
+ int k;
+ int r;
+ char *p;
+
+ send_with_reply ("DR", buf, sizeof (buf));
+
+ /* Reply is edited to a string that describes registers byte by byte,
+ each byte encoded as two hex characters. */
+
+ p = buf;
+ r = 0;
+
+ /* parsing row one - D0-D7-registers */
+
+ while (*p++ != '\n')
+ {;
+ }
+ for (i = 4; i < 70; i += (i == 39 ? 3 : 1))
+ {
+ for (k = 0; k < 4; k++)
+ {
+ if (p[i + 0] == 0 || p[i + 1] == 0)
+ {
+ error ("Emulator reply is too short: %s", buf);
+ }
+ registers[r++] = (fromhex (p[i + 0]) * 16) + fromhex (p[i + 1]);
+ i += 2;
+ }
+ }
+ p += i;
+
+ /* parsing row two - A0-A6-registers */
+
+ while (*p++ != '\n')
+ {;
+ }
+ for (i = 4; i < 61; i += (i == 39 ? 3 : 1))
+ {
+ for (k = 0; k < 4; k++)
+ {
+ if (p[i + 0] == 0 || p[i + 1] == 0)
+ {
+ error ("Emulator reply is too short: %s", buf);
+ }
+ registers[r++] = (fromhex (p[i + 0])) * 16 + fromhex (p[i + 1]);
+ i += 2;
+ }
+ }
+ p += i;
+
+ while (*p++ != '\n')
+ {;
+ }
+
+ /* fetch SSP-, SR- and PC-registers */
+
+ /* first - check STATUS-word and decide which stackpointer to use */
+
+ send_with_reply ("SR", SR_buf, sizeof (SR_buf));
+ p = SR_buf;
+ p += 5;
+
+ if (m68020)
+ {
+ if (*p == '3') /* use masterstackpointer MSP */
+ {
+ send_with_reply ("MSP", buf, sizeof (buf));
+ }
+ else if (*p == '2') /* use interruptstackpointer ISP */
+ {
+ send_with_reply ("ISP", buf, sizeof (buf));
+ }
+ else
+ /* use userstackpointer USP */
+ {
+ send_with_reply ("USP", buf, sizeof (buf));
+ }
+ p = buf;
+ for (k = 0; k < 4; k++)
+ {
+ if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0)
+ {
+ error ("Emulator reply is too short: %s", buf);
+ }
+ registers[r++] = fromhex (buf[k * 2 + 1]) * 16 + fromhex (buf[k * 2 + 2]);
+ }
+
+ p = SR_buf;
+ for (k = 0; k < 4; k++)
+ {
+ if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0)
+ {
+ error ("Emulator reply is too short: %s", buf);
+ }
+ registers[r++] =
+ fromhex (SR_buf[k * 2 + 1]) * 16 + fromhex (SR_buf[k * 2 + 2]);
+ }
+ send_with_reply ("PC", buf, sizeof (buf));
+ p = buf;
+ for (k = 0; k < 4; k++)
+ {
+ if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0)
+ {
+ error ("Emulator reply is too short: %s", buf);
+ }
+ registers[r++] = fromhex (buf[k * 2 + 1]) * 16 + fromhex (buf[k * 2 + 2]);
+ }
+ }
+ else
+ /* 68000-mode */
+ {
+ if (*p == '2') /* use supervisorstackpointer SSP */
+ {
+ send_with_reply ("SSP", buf, sizeof (buf));
+ }
+ else
+ /* use userstackpointer USP */
+ {
+ send_with_reply ("USP", buf, sizeof (buf));
+ }
+
+ /* fetch STACKPOINTER */
+
+ p = buf;
+ for (k = 0; k < 4; k++)
+ {
+ if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0)
+ {
+ error ("Emulator reply is too short: %s", buf);
+ }
+ registers[r++] = fromhex (buf[k * 2 + 1]) * 16 + fromhex (buf[k * 2 + 2]);
+ }
+
+ /* fetch STATUS */
+
+ p = SR_buf;
+ for (k = 0; k < 4; k++)
+ {
+ if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0)
+ {
+ error ("Emulator reply is too short: %s", buf);
+ }
+ registers[r++] =
+ fromhex (SR_buf[k * 2 + 1]) * 16 + fromhex (SR_buf[k * 2 + 2]);
+ }
+
+ /* fetch PC */
+
+ send_with_reply ("PC", buf, sizeof (buf));
+ p = buf;
+ for (k = 0; k < 4; k++)
+ {
+ if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0)
+ {
+ error ("Emulator reply is too short: %s", buf);
+ }
+ registers[r++] = fromhex (buf[k * 2 + 1]) * 16 + fromhex (buf[k * 2 + 2]);
+ }
+ }
+}
+
+/* Store register value, located in REGISTER, on the target processor.
+ regno - the register-number of the register to store
+ (-1 means store them all)
+ FIXME: Return errno value. */
+
+static void
+es1800_store_register (int regno)
+{
+
+ static char regtab[18][4] =
+ {
+ "D0 ", "D1 ", "D2 ", "D3 ", "D4 ", "D5 ", "D6 ", "D7 ",
+ "A0 ", "A1 ", "A2 ", "A3 ", "A4 ", "A5 ", "A6 ", "SSP",
+ "SR ", "PC "
+ };
+
+ char buf[PBUFSIZ];
+ char SR_buf[PBUFSIZ];
+ char stack_pointer[4];
+ char *p;
+ int i;
+ int j;
+ int k;
+ unsigned char *r;
+
+ r = (unsigned char *) registers;
+
+ if (regno == -1) /* write all registers */
+ {
+ j = 0;
+ k = 18;
+ }
+ else
+ /* write one register */
+ {
+ j = regno;
+ k = regno + 1;
+ r += regno * 4;
+ }
+
+ if ((regno == -1) || (regno == 15))
+ {
+ /* fetch current status */
+ send_with_reply ("SR", SR_buf, sizeof (SR_buf));
+ p = SR_buf;
+ p += 5;
+ if (m68020)
+ {
+ if (*p == '3') /* use masterstackpointer MSP */
+ {
+ strcpy (stack_pointer, "MSP");
+ }
+ else
+ {
+ if (*p == '2') /* use interruptstackpointer ISP */
+ {
+ strcpy (stack_pointer, "ISP");
+ }
+ else
+ {
+ strcpy (stack_pointer, "USP"); /* use userstackpointer USP */
+ }
+ }
+ }
+ else
+ /* 68000-mode */
+ {
+ if (*p == '2') /* use supervisorstackpointer SSP */
+ {
+ strcpy (stack_pointer, "SSP");
+ }
+ else
+ {
+ strcpy (stack_pointer, "USP"); /* use userstackpointer USP */
+ }
+ }
+ strcpy (regtab[15], stack_pointer);
+ }
+
+ for (i = j; i < k; i++)
+ {
+ buf[0] = regtab[i][0];
+ buf[1] = regtab[i][1];
+ buf[2] = regtab[i][2];
+ buf[3] = '=';
+ buf[4] = '$';
+ buf[5] = tohex ((*r >> 4) & 0x0f);
+ buf[6] = tohex (*r++ & 0x0f);
+ buf[7] = tohex ((*r >> 4) & 0x0f);
+ buf[8] = tohex (*r++ & 0x0f);
+ buf[9] = tohex ((*r >> 4) & 0x0f);
+ buf[10] = tohex (*r++ & 0x0f);
+ buf[11] = tohex ((*r >> 4) & 0x0f);
+ buf[12] = tohex (*r++ & 0x0f);
+ buf[13] = 0;
+
+ send_with_reply (buf, buf, sizeof (buf)); /* FIXME, reply not used? */
+ }
+}
+
+
+/* Prepare to store registers. */
+
+static void
+es1800_prepare_to_store (void)
+{
+ /* Do nothing, since we can store individual regs */
+}
+
+/* Convert hex digit A to a number. */
+
+static int
+fromhex (int a)
+{
+ if (a >= '0' && a <= '9')
+ {
+ return a - '0';
+ }
+ else if (a >= 'a' && a <= 'f')
+ {
+ return a - 'a' + 10;
+ }
+ else if (a >= 'A' && a <= 'F')
+ {
+ return a - 'A' + 10;
+ }
+ else
+ {
+ error ("Reply contains invalid hex digit");
+ }
+ return (-1);
+}
+
+
+/* Convert number NIB to a hex digit. */
+
+static int
+tohex (int nib)
+{
+ if (nib < 10)
+ {
+ return ('0' + nib);
+ }
+ else
+ {
+ return ('A' + nib - 10);
+ }
+}
+
+/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
+ to or from debugger address MYADDR. Write to inferior if WRITE is
+ nonzero. Returns length of data written or read; 0 for error.
+
+ memaddr - the target's address
+ myaddr - gdb's address
+ len - number of bytes
+ write - write if != 0 otherwise read
+ tops - unused */
+
+static int
+es1800_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int write, struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ int origlen = len;
+ int xfersize;
+
+ while (len > 0)
+ {
+ xfersize = len > MAXBUFBYTES ? MAXBUFBYTES : len;
+ if (write)
+ {
+ es1800_write_bytes (memaddr, myaddr, xfersize);
+ }
+ else
+ {
+ es1800_read_bytes (memaddr, myaddr, xfersize);
+ }
+ memaddr += xfersize;
+ myaddr += xfersize;
+ len -= xfersize;
+ }
+ return (origlen); /* no error possible */
+}
+
+
+/* Write memory data directly to the emulator.
+ This does not inform the data cache; the data cache uses this.
+ MEMADDR is the address in the remote memory space.
+ MYADDR is the address of the buffer in our space.
+ LEN is the number of bytes.
+
+ memaddr - the target's address
+ myaddr - gdb's address
+ len - number of bytes */
+
+static void
+es1800_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ char buf[PBUFSIZ];
+ int i;
+ char *p;
+
+ p = myaddr;
+ for (i = 0; i < len; i++)
+ {
+ sprintf (buf, "@.B$%x=$%x", memaddr + i, (*p++) & 0xff);
+ send_with_reply (buf, buf, sizeof (buf)); /* FIXME send_command? */
+ }
+}
+
+
+/* Read memory data directly from the emulator.
+ This does not use the data cache; the data cache uses this.
+
+ memaddr - the target's address
+ myaddr - gdb's address
+ len - number of bytes */
+
+static void
+es1800_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ static int DB_tab[16] =
+ {8, 11, 14, 17, 20, 23, 26, 29, 34, 37, 40, 43, 46, 49, 52, 55};
+ char buf[PBUFSIZ];
+ int i;
+ int low_addr;
+ char *p;
+ char *b;
+
+ if (len > PBUFSIZ / 2 - 1)
+ {
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+
+ if (len == 1) /* The emulator does not like expressions like: */
+ {
+ len = 2; /* DB.B $20018 TO $20018 */
+ }
+
+ /* Reply describes registers byte by byte, each byte encoded as two hex
+ characters. */
+
+ sprintf (buf, "DB.B $%x TO $%x", memaddr, memaddr + len - 1);
+ send_with_reply (buf, buf, sizeof (buf));
+ b = buf;
+ low_addr = memaddr & 0x0f;
+ for (i = low_addr; i < low_addr + len; i++)
+ {
+ if ((!(i % 16)) && i)
+ { /* if (i = 16,32,48) */
+ while (*p++ != '\n')
+ {;
+ }
+ b = p;
+ }
+ p = b + DB_tab[i % 16] + (m68020 ? 2 : 0);
+ if (p[0] == 32 || p[1] == 32)
+ {
+ error ("Emulator reply is too short: %s", buf);
+ }
+ myaddr[i - low_addr] = fromhex (p[0]) * 16 + fromhex (p[1]);
+ }
+}
+
+/* Display information about the current target. TOPS is unused. */
+
+static void
+es1800_files_info (struct target_ops *tops)
+{
+ printf ("ES1800 Attached to %s at %d baud in %s mode\n", savename, 19200,
+ MODE);
+}
+
+
+/* We read the contents of the target location and stash it,
+ then overwrite it with a breakpoint instruction.
+
+ addr - is the target location in the target machine.
+ contents_cache - is a pointer to memory allocated for saving the target contents.
+ It is guaranteed by the caller to be long enough to save sizeof
+ BREAKPOINT bytes.
+
+ FIXME: This size is target_arch dependent and should be available in
+ the target_arch transfer vector, if we ever have one... */
+
+static int
+es1800_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ int val;
+
+ val = target_read_memory (addr, contents_cache, sizeof (es1800_break_insn));
+
+ if (val == 0)
+ {
+ val = target_write_memory (addr, es1800_break_insn,
+ sizeof (es1800_break_insn));
+ }
+
+ return (val);
+}
+
+
+/* Write back the stashed instruction
+
+ addr - is the target location in the target machine.
+ contents_cache - is a pointer to memory allocated for saving the target contents.
+ It is guaranteed by the caller to be long enough to save sizeof
+ BREAKPOINT bytes. */
+
+static int
+es1800_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+
+ return (target_write_memory (addr, contents_cache,
+ sizeof (es1800_break_insn)));
+}
+
+/* create_break_insn ()
+ Primitive datastructures containing the es1800 breakpoint instruction */
+
+static void
+es1800_create_break_insn (char *ins, int vec)
+{
+ if (vec == 15)
+ {
+ ins[0] = 0x4e;
+ ins[1] = 0x4f;
+ }
+}
+
+
+/* verify_break ()
+ Seach for breakpoint routine in emulator memory.
+ returns non-zero on failure
+ vec - trap vector used for breakpoints */
+
+static int
+verify_break (int vec)
+{
+ CORE_ADDR memaddress;
+ char buf[8];
+ char *instr = "NqNqNqNs"; /* breakpoint routine */
+ int status;
+
+ get_break_addr (vec, &memaddress);
+
+ if (memaddress)
+ {
+ status = target_read_memory (memaddress, buf, 8);
+ if (status != 0)
+ {
+ memory_error (status, memaddress);
+ }
+ return (strcmp (instr, buf));
+ }
+ return (-1);
+}
+
+
+/* get_break_addr ()
+ find address of breakpoint routine
+ vec - trap vector used for breakpoints
+ addrp - store the address here */
+
+static void
+get_break_addr (int vec, CORE_ADDR *addrp)
+{
+ CORE_ADDR memaddress = 0;
+ int status;
+ int k;
+ char buf[PBUFSIZ];
+ char base_addr[4];
+ char *p;
+
+ if (m68020)
+ {
+ send_with_reply ("VBR ", buf, sizeof (buf));
+ p = buf;
+ for (k = 0; k < 4; k++)
+ {
+ if ((p[k * 2 + 1] == 0) || (p[k * 2 + 2] == 0))
+ {
+ error ("Emulator reply is too short: %s", buf);
+ }
+ base_addr[k] = (fromhex (p[k * 2 + 1]) * 16) + fromhex (p[k * 2 + 2]);
+ }
+ /* base addr of exception vector table */
+ memaddress = *((CORE_ADDR *) base_addr);
+ }
+
+ memaddress += (vec + 32) * 4; /* address of trap vector */
+ status = target_read_memory (memaddress, (char *) addrp, 4);
+ if (status != 0)
+ {
+ memory_error (status, memaddress);
+ }
+}
+
+
+/* Kill an inferior process */
+
+static void
+es1800_kill (void)
+{
+ if (!ptid_equal (inferior_ptid, null_ptid))
+ {
+ inferior_ptid = null_ptid;
+ es1800_mourn_inferior ();
+ }
+}
+
+
+/* Load a file to the ES1800 emulator.
+ Converts the file from a.out format into Extended Tekhex format
+ before the file is loaded.
+ Also loads the trap routine, and sets the ES1800 breakpoint on it
+ filename - the a.out to be loaded
+ from_tty - says whether to be verbose or not
+ FIXME Uses emulator overlay memory for trap routine */
+
+static void
+es1800_load (char *filename, int from_tty)
+{
+
+ FILE *instream;
+ char loadname[15];
+ char buf[160];
+ struct cleanup *old_chain;
+ int es1800_load_format = 5;
+
+ if (es1800_desc == NULL)
+ {
+ printf ("No emulator attached, type emulator-command first\n");
+ return;
+ }
+
+ filename = tilde_expand (filename);
+ make_cleanup (xfree, filename);
+
+ switch (es1800_load_format)
+ {
+ case 2: /* Extended Tekhex */
+ if (from_tty)
+ {
+ printf ("Converting \"%s\" to Extended Tekhex Format\n", filename);
+ }
+ sprintf (buf, "tekhex %s", filename);
+ system (buf);
+ sprintf (loadname, "out.hex");
+ break;
+
+ case 5: /* Motorola S-rec */
+ if (from_tty)
+ {
+ printf ("Converting \"%s\" to Motorola S-record format\n",
+ filename);
+ }
+ /* in the future the source code in copy (part of binutils-1.93) will
+ be included in this file */
+ sprintf (buf,
+ "copy -s \"a.out-sunos-big\" -d \"srec\" %s /tmp/out.hex",
+ filename);
+ system (buf);
+ sprintf (loadname, "/tmp/out.hex");
+ break;
+
+ default:
+ error ("Downloading format not defined\n");
+ }
+
+ breakpoint_init_inferior ();
+ inferior_ptid = null_ptid;
+ if (from_tty)
+ {
+ printf ("Downloading \"%s\" to the ES 1800\n", filename);
+ }
+ if ((instream = fopen (loadname, "r")) == NULL)
+ {
+ perror_with_name ("fopen:");
+ }
+
+ old_chain = make_cleanup (fclose, instream);
+ immediate_quit++;
+
+ es1800_reset (0);
+
+ download (instream, from_tty, es1800_load_format);
+
+ /* if breakpoint routine is not present anymore we have to check
+ whether to download a new breakpoint routine or not */
+
+ if ((verify_break (es1800_break_vec) != 0)
+ && query ("No breakpoint routine in ES 1800 emulator!\nDownload a breakpoint routine to the emulator? "))
+ {
+ char buf[128];
+ printf ("Using break vector 0x%x\n", es1800_break_vec);
+ sprintf (buf, "0x%x ", es1800_break_vec);
+ printf ("Give the start address of the breakpoint routine: ");
+ fgets (buf + strlen (buf), sizeof (buf) - strlen (buf), stdin);
+ es1800_init_break (buf, 0);
+ }
+
+ do_cleanups (old_chain);
+ expect_prompt ();
+ readchar (); /* FIXME I am getting a ^G = 7 after the prompt */
+ printf ("\n");
+
+ if (fclose (instream) == EOF)
+ {
+ ;
+ }
+
+ if (es1800_load_format != 2)
+ {
+ sprintf (buf, "/usr/bin/rm %s", loadname);
+ system (buf);
+ }
+
+ symbol_file_add_main (filename, from_tty); /* reading symbol table */
+ immediate_quit--;
+}
+
+#if 0
+
+#define NUMCPYBYTES 20
+
+static void
+bfd_copy (bfd *from_bfd, bfd *to_bfd)
+{
+ asection *p, *new;
+ int i;
+ char buf[NUMCPYBYTES];
+
+ for (p = from_bfd->sections; p != NULL; p = p->next)
+ {
+ printf (" Copying section %s. Size = %x.\n", p->name, p->_cooked_size);
+ printf (" vma = %x, offset = %x, output_sec = %x\n",
+ p->vma, p->output_offset, p->output_section);
+ new = bfd_make_section (to_bfd, p->name);
+ if (p->_cooked_size &&
+ !bfd_set_section_size (to_bfd, new, p->_cooked_size))
+ {
+ error ("Wrong BFD size!\n");
+ }
+ if (!bfd_set_section_flags (to_bfd, new, p->flags))
+ {
+ error ("bfd_set_section_flags");
+ }
+ new->vma = p->vma;
+
+ for (i = 0; (i + NUMCPYBYTES) < p->_cooked_size; i += NUMCPYBYTES)
+ {
+ if (!bfd_get_section_contents (from_bfd, p, (PTR) buf, (file_ptr) i,
+ (bfd_size_type) NUMCPYBYTES))
+ {
+ error ("bfd_get_section_contents\n");
+ }
+ if (!bfd_set_section_contents (to_bfd, new, (PTR) buf, (file_ptr) i,
+ (bfd_size_type) NUMCPYBYTES))
+ {
+ error ("bfd_set_section_contents\n");
+ }
+ }
+ bfd_get_section_contents (from_bfd, p, (PTR) buf, (file_ptr) i,
+ (bfd_size_type) (p->_cooked_size - i));
+ bfd_set_section_contents (to_bfd, new, (PTR) buf, (file_ptr) i,
+ (bfd_size_type) (p->_cooked_size - i));
+ }
+}
+
+#endif
+
+/* Start an process on the es1800 and set inferior_ptid to the new
+ process' pid.
+ execfile - the file to run
+ args - arguments passed to the program
+ env - the environment vector to pass */
+
+static void
+es1800_create_inferior (char *execfile, char *args, char **env)
+{
+ int entry_pt;
+ int pid;
+#if 0
+ struct expression *expr;
+ register struct cleanup *old_chain = 0;
+ register value val;
+#endif
+
+ if (args && *args)
+ {
+ error ("Can't pass arguments to remote ES1800 process");
+ }
+
+#if 0
+ if (query ("Use 'start' as entry point? "))
+ {
+ expr = parse_c_expression ("start");
+ old_chain = make_cleanup (free_current_contents, &expr);
+ val = evaluate_expression (expr);
+ entry_pt = (val->location).address;
+ }
+ else
+ {
+ printf ("Enter the program's entry point (in hexadecimal): ");
+ scanf ("%x", &entry_pt);
+ }
+#endif
+
+ if (execfile == 0 || exec_bfd == 0)
+ {
+ error ("No executable file specified");
+ }
+
+ entry_pt = (int) bfd_get_start_address (exec_bfd);
+
+ pid = 42;
+
+ /* Now that we have a child process, make it our target. */
+
+ push_target (&es1800_child_ops);
+
+ /* The "process" (board) is already stopped awaiting our commands, and
+ the program is already downloaded. We just set its PC and go. */
+
+ inferior_ptid = pid_to_ptid (pid); /* Needed for wait_for_inferior below */
+
+ clear_proceed_status ();
+
+ /* Tell wait_for_inferior that we've started a new process. */
+
+ init_wait_for_inferior ();
+
+ /* Set up the "saved terminal modes" of the inferior
+ based on what modes we are starting it with. */
+
+ target_terminal_init ();
+
+ /* Install inferior's terminal modes. */
+
+ target_terminal_inferior ();
+
+ /* remote_start (args); */
+ /* trap_expected = 0; */
+ /* insert_step_breakpoint (); FIXME, do we need this? */
+
+ /* Let 'er rip... */
+ proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0);
+
+}
+
+
+/* The process has died, clean up. */
+
+static void
+es1800_mourn_inferior (void)
+{
+ remove_breakpoints ();
+ unpush_target (&es1800_child_ops);
+ generic_mourn_inferior (); /* Do all the proper things now */
+}
+
+/* ES1800-protocol specific routines */
+
+/* Keep discarding input from the remote system, until STRING is found.
+ Let the user break out immediately.
+ string - the string to expect
+ nowait - break out if string not the emulator's first respond otherwise
+ read until string is found (== 0) */
+
+static void
+expect (char *string, int nowait)
+{
+ char c;
+ char *p = string;
+
+ immediate_quit++;
+ while (1)
+ {
+ c = readchar ();
+ if (isalpha (c))
+ {
+ c = toupper (c);
+ }
+ if (c == toupper (*p))
+ {
+ p++;
+ if (*p == '\0')
+ {
+ immediate_quit--;
+ return;
+ }
+ }
+ else if (!nowait)
+ {
+ p = string;
+ }
+ else
+ {
+ printf ("\'%s\' expected\n", string);
+ printf ("char %d is %d", p - string, c);
+ error ("\n");
+ }
+ }
+}
+
+/* Keep discarding input until we see the prompt. */
+
+static void
+expect_prompt (void)
+{
+ expect (">", 0);
+}
+
+
+/* Read one character */
+
+#ifdef DEBUG_STDIN
+
+/* read from stdin */
+
+static int
+readchar (void)
+{
+ char buf[1];
+
+ buf[0] = '\0';
+ printf ("readchar, give one character\n");
+ read (0, buf, 1);
+
+#if defined (LOG_FILE)
+ putc (buf[0] & 0x7f, log_file);
+#endif
+
+ return (buf[0] & 0x7f);
+}
+
+#else /* !DEBUG_STDIN */
+
+/* Read a character from the remote system, doing all the fancy
+ timeout stuff. */
+
+static int
+readchar (void)
+{
+ int ch;
+
+ ch = serial_readchar (es1800_desc, timeout);
+
+ /* FIXME: doing an error() here will probably cause trouble, at least if from
+ es1800_wait. */
+ if (ch == SERIAL_TIMEOUT)
+ error ("Timeout reading from remote system.");
+ else if (ch == SERIAL_ERROR)
+ perror_with_name ("remote read");
+
+#if defined (LOG_FILE)
+ putc (ch & 0x7f, log_file);
+ fflush (log_file);
+#endif
+
+ return (ch);
+}
+
+#endif /* DEBUG_STDIN */
+
+
+/* Send a command to the emulator and save the reply.
+ Report an error if we get an error reply.
+ string - the es1800 command
+ buf - containing the emulator reply on return
+ len - size of buf */
+
+static void
+send_with_reply (char *string, char *buf, int len)
+{
+ send (string);
+ serial_write (es1800_desc, "\r", 1);
+
+#ifndef DEBUG_STDIN
+ expect (string, 1);
+ expect ("\r\n", 0);
+#endif
+
+ getmessage (buf, len);
+}
+
+
+/* Send the command in STR to the emulator adding \r. check
+ the echo for consistency.
+ string - the es1800 command */
+
+static void
+send_command (char *string)
+{
+ send (string);
+ serial_write (es1800_desc, "\r", 1);
+
+#ifndef DEBUG_STDIN
+ expect (string, 0);
+ expect_prompt ();
+#endif
+
+}
+
+/* Send a string
+ string - the es1800 command */
+
+static void
+send (char *string)
+{
+ if (kiodebug)
+ {
+ fprintf_unfiltered (gdb_stderr, "Sending: %s\n", string);
+ }
+ serial_write (es1800_desc, string, strlen (string));
+}
+
+
+/* Read a message from the emulator and store it in BUF.
+ buf - containing the emulator reply on return
+ len - size of buf */
+
+static void
+getmessage (char *buf, int len)
+{
+ char *bp;
+ int c;
+ int prompt_found = 0;
+ extern kiodebug;
+
+#if defined (LOG_FILE)
+ /* This is a convenient place to do this. The idea is to do it often
+ enough that we never lose much data if we terminate abnormally. */
+ fflush (log_file);
+#endif
+
+ bp = buf;
+ c = readchar ();
+ do
+ {
+ if (c)
+ {
+ if (len-- < 2) /* char and terminaling NULL */
+ {
+ error ("input buffer overrun\n");
+ }
+ *bp++ = c;
+ }
+ c = readchar ();
+ if ((c == '>') && (*(bp - 1) == ' '))
+ {
+ prompt_found = 1;
+ }
+ }
+ while (!prompt_found);
+ *bp = 0;
+
+ if (kiodebug)
+ {
+ fprintf_unfiltered (gdb_stderr, "message received :%s\n", buf);
+ }
+}
+
+static void
+download (FILE *instream, int from_tty, int format)
+{
+ char c;
+ char buf[160];
+ int i = 0;
+
+ send_command ("SET #2,$1A"); /* reset char = ^Z */
+ send_command ("SET #3,$11,$13"); /* XON XOFF */
+ if (format == 2)
+ {
+ send_command ("SET #26,#2");
+ }
+ else
+ {
+ send_command ("SET #26,#5"); /* Format=Extended Tekhex */
+ }
+ send_command ("DFB = $10");
+ send_command ("PUR");
+ send_command ("CES");
+ send ("DNL\r");
+ expect ("DNL", 1);
+ if (from_tty)
+ {
+ printf (" 0 records loaded...\r");
+ }
+ while (fgets (buf, 160, instream))
+ {
+ send (buf);
+ if (from_tty)
+ {
+ printf ("%5d\b\b\b\b\b", ++i);
+ fflush (stdout);
+ }
+ if ((c = readchar ()) != 006)
+ {
+ error ("expected ACK");
+ }
+ }
+ if (from_tty)
+ {
+ printf ("- All");
+ }
+}
+
+/* Additional commands */
+
+#if defined (TIOCGETP) && defined (FNDELAY) && defined (EWOULDBLOCK)
+#define PROVIDE_TRANSPARENT
+#endif
+
+#ifdef PROVIDE_TRANSPARENT
+/* Talk directly to the emulator
+ FIXME, uses busy wait, and is SUNOS (or at least BSD) specific */
+
+/*ARGSUSED */
+static void
+es1800_transparent (char *args, int from_tty)
+{
+ int console;
+ struct sgttyb modebl;
+ int fcflag;
+ int cc;
+ struct sgttyb console_mode_save;
+ int console_fc_save;
+ int es1800_fc_save;
+ int inputcnt = 80;
+ char inputbuf[80];
+ int consolecnt = 0;
+ char consolebuf[80];
+ int es1800_cnt = 0;
+ char es1800_buf[80];
+ int i;
+
+ dont_repeat ();
+ if (es1800_desc == NULL)
+ {
+ printf ("No emulator attached, type emulator-command first\n");
+ return;
+ }
+
+ printf ("\n");
+ printf ("You are now communicating directly with the ES 1800 emulator.\n");
+ printf ("To leave this mode (transparent mode), press ^E.\n");
+ printf ("\n");
+ printf (" >");
+ fflush (stdout);
+
+ if ((console = open ("/dev/tty", O_RDWR)) == -1)
+ {
+ perror_with_name ("/dev/tty:");
+ }
+
+ if ((fcflag = fcntl (console, F_GETFL, 0)) == -1)
+ {
+ perror_with_name ("fcntl console");
+ }
+
+ console_fc_save = fcflag;
+ fcflag = fcflag | FNDELAY;
+
+ if (fcntl (console, F_SETFL, fcflag) == -1)
+ {
+ perror_with_name ("fcntl console");
+ }
+
+ if (ioctl (console, TIOCGETP, &modebl))
+ {
+ perror_with_name ("ioctl console");
+ }
+
+ console_mode_save = modebl;
+ modebl.sg_flags = RAW;
+
+ if (ioctl (console, TIOCSETP, &modebl))
+ {
+ perror_with_name ("ioctl console");
+ }
+
+ if ((fcflag = fcntl (deprecated_serial_fd (es1800_desc), F_GETFL, 0)) == -1)
+ {
+ perror_with_name ("fcntl serial");
+ }
+
+ es1800_fc_save = fcflag;
+ fcflag = fcflag | FNDELAY;
+
+ if (fcntl (deprecated_serial_fd (es1800_desc), F_SETFL, fcflag) == -1)
+ {
+ perror_with_name ("fcntl serial");
+ }
+
+ while (1)
+ {
+ cc = read (console, inputbuf, inputcnt);
+ if (cc != -1)
+ {
+ if ((*inputbuf & 0x7f) == 0x05)
+ {
+ break;
+ }
+ for (i = 0; i < cc;)
+ {
+ es1800_buf[es1800_cnt++] = inputbuf[i++];
+ }
+ if ((cc = serial_write (es1800_desc, es1800_buf, es1800_cnt)) == -1)
+ {
+ perror_with_name ("FEL! write:");
+ }
+ es1800_cnt -= cc;
+ if (es1800_cnt && cc)
+ {
+ for (i = 0; i < es1800_cnt; i++)
+ {
+ es1800_buf[i] = es1800_buf[cc + i];
+ }
+ }
+ }
+ else if (errno != EWOULDBLOCK)
+ {
+ perror_with_name ("FEL! read:");
+ }
+
+ cc = read (deprecated_serial_fd (es1800_desc), inputbuf, inputcnt);
+ if (cc != -1)
+ {
+ for (i = 0; i < cc;)
+ {
+ consolebuf[consolecnt++] = inputbuf[i++];
+ }
+ if ((cc = write (console, consolebuf, consolecnt)) == -1)
+ {
+ perror_with_name ("FEL! write:");
+ }
+ consolecnt -= cc;
+ if (consolecnt && cc)
+ {
+ for (i = 0; i < consolecnt; i++)
+ {
+ consolebuf[i] = consolebuf[cc + i];
+ }
+ }
+ }
+ else if (errno != EWOULDBLOCK)
+ {
+ perror_with_name ("FEL! read:");
+ }
+ }
+
+ console_fc_save = console_fc_save & !FNDELAY;
+ if (fcntl (console, F_SETFL, console_fc_save) == -1)
+ {
+ perror_with_name ("FEL! fcntl");
+ }
+
+ if (ioctl (console, TIOCSETP, &console_mode_save))
+ {
+ perror_with_name ("FEL! ioctl");
+ }
+
+ close (console);
+
+ if (fcntl (deprecated_serial_fd (es1800_desc), F_SETFL, es1800_fc_save) == -1)
+ {
+ perror_with_name ("FEL! fcntl");
+ }
+
+ printf ("\n");
+
+}
+#endif /* PROVIDE_TRANSPARENT */
+
+static void
+es1800_init_break (char *args, int from_tty)
+{
+ CORE_ADDR memaddress = 0;
+ char buf[PBUFSIZ];
+ char base_addr[4];
+ char *space_index;
+ char *p;
+ int k;
+
+ if (args == NULL)
+ {
+ error_no_arg ("a trap vector");
+ }
+
+ if (!(space_index = strchr (args, ' ')))
+ {
+ error ("Two arguments needed (trap vector and address of break routine).\n");
+ }
+
+ *space_index = '\0';
+
+ es1800_break_vec = strtol (args, (char **) NULL, 0);
+ es1800_break_address = parse_and_eval_address (space_index + 1);
+
+ es1800_create_break_insn (es1800_break_insn, es1800_break_vec);
+
+ if (m68020)
+ {
+ send_with_reply ("VBR ", buf, sizeof (buf));
+ p = buf;
+ for (k = 0; k < 4; k++)
+ {
+ if ((p[k * 2 + 1] == 0) || (p[k * 2 + 2] == 0))
+ {
+ error ("Emulator reply is too short: %s", buf);
+ }
+ base_addr[k] = (fromhex (p[k * 2 + 1]) * 16) + fromhex (p[k * 2 + 2]);
+ }
+ /* base addr of exception vector table */
+ memaddress = *((CORE_ADDR *) base_addr);
+ }
+
+ memaddress += (es1800_break_vec + 32) * 4; /* address of trap vector */
+
+ sprintf (buf, "@.L%lx=$%lx", memaddress, es1800_break_address);
+ send_command (buf); /* set the address of the break routine in the */
+ /* trap vector */
+
+ sprintf (buf, "@.L%lx=$4E714E71", es1800_break_address); /* NOP; NOP */
+ send_command (buf);
+ sprintf (buf, "@.L%lx=$4E714E73", es1800_break_address + 4); /* NOP; RTE */
+ send_command (buf);
+
+ sprintf (buf, "AC2=$%lx", es1800_break_address + 4);
+ /* breakpoint at es1800-break_address */
+ send_command (buf);
+ send_command ("WHEN AC2 THEN BRK"); /* ie in exception routine */
+
+ if (from_tty)
+ {
+ printf ("Breakpoint (trap $%x) routine at address: %lx\n",
+ es1800_break_vec, es1800_break_address);
+ }
+}
+
+static void
+es1800_child_open (char *arg, int from_tty)
+{
+ error ("Use the \"run\" command to start a child process.");
+}
+
+static void
+es1800_child_detach (char *args, int from_tty)
+{
+ if (args)
+ {
+ error ("Argument given to \"detach\" when remotely debugging.");
+ }
+
+ pop_target ();
+ if (from_tty)
+ {
+ printf ("Ending debugging the process %d.\n", PIDGET (inferior_ptid));
+ }
+}
+
+
+/* Define the target subroutine names */
+
+struct target_ops es1800_ops;
+
+static void
+init_es1800_ops (void)
+{
+ es1800_ops.to_shortname = "es1800";
+ es1800_ops.to_longname = "Remote serial target in ES1800-emulator protocol";
+ es1800_ops.to_doc = "Remote debugging on the es1800 emulator via a serial line.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ es1800_ops.to_open = es1800_open;
+ es1800_ops.to_close = es1800_close;
+ es1800_ops.to_attach = es1800_attach;
+ es1800_ops.to_post_attach = NULL;
+ es1800_ops.to_require_attach = NULL;
+ es1800_ops.to_detach = es1800_detach;
+ es1800_ops.to_require_detach = NULL;
+ es1800_ops.to_resume = es1800_resume;
+ es1800_ops.to_wait = NULL;
+ es1800_ops.to_post_wait = NULL;
+ es1800_ops.to_fetch_registers = NULL;
+ es1800_ops.to_store_registers = NULL;
+ es1800_ops.to_prepare_to_store = es1800_prepare_to_store;
+ es1800_ops.to_xfer_memory = es1800_xfer_inferior_memory;
+ es1800_ops.to_files_info = es1800_files_info;
+ es1800_ops.to_insert_breakpoint = es1800_insert_breakpoint;
+ es1800_ops.to_remove_breakpoint = es1800_remove_breakpoint;
+ es1800_ops.to_terminal_init = NULL;
+ es1800_ops.to_terminal_inferior = NULL;
+ es1800_ops.to_terminal_ours_for_output = NULL;
+ es1800_ops.to_terminal_ours = NULL;
+ es1800_ops.to_terminal_info = NULL;
+ es1800_ops.to_kill = NULL;
+ es1800_ops.to_load = es1800_load;
+ es1800_ops.to_lookup_symbol = NULL;
+ es1800_ops.to_create_inferior = es1800_create_inferior;
+ es1800_ops.to_post_startup_inferior = NULL;
+ es1800_ops.to_acknowledge_created_inferior = NULL;
+ es1800_ops.to_clone_and_follow_inferior = NULL;
+ es1800_ops.to_post_follow_inferior_by_clone = NULL;
+ es1800_ops.to_insert_fork_catchpoint = NULL;
+ es1800_ops.to_remove_fork_catchpoint = NULL;
+ es1800_ops.to_insert_vfork_catchpoint = NULL;
+ es1800_ops.to_remove_vfork_catchpoint = NULL;
+ es1800_ops.to_has_forked = NULL;
+ es1800_ops.to_has_vforked = NULL;
+ es1800_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ es1800_ops.to_post_follow_vfork = NULL;
+ es1800_ops.to_insert_exec_catchpoint = NULL;
+ es1800_ops.to_remove_exec_catchpoint = NULL;
+ es1800_ops.to_has_execd = NULL;
+ es1800_ops.to_reported_exec_events_per_exec_call = NULL;
+ es1800_ops.to_has_exited = NULL;
+ es1800_ops.to_mourn_inferior = NULL;
+ es1800_ops.to_can_run = 0;
+ es1800_ops.to_notice_signals = 0;
+ es1800_ops.to_thread_alive = 0;
+ es1800_ops.to_stop = 0;
+ es1800_ops.to_pid_to_exec_file = NULL;
+ es1800_ops.to_stratum = core_stratum;
+ es1800_ops.DONT_USE = 0;
+ es1800_ops.to_has_all_memory = 0;
+ es1800_ops.to_has_memory = 1;
+ es1800_ops.to_has_stack = 0;
+ es1800_ops.to_has_registers = 0;
+ es1800_ops.to_has_execution = 0;
+ es1800_ops.to_sections = NULL;
+ es1800_ops.to_sections_end = NULL;
+ es1800_ops.to_magic = OPS_MAGIC;
+}
+
+/* Define the target subroutine names */
+
+struct target_ops es1800_child_ops;
+
+static void
+init_es1800_child_ops (void)
+{
+ es1800_child_ops.to_shortname = "es1800_process";
+ es1800_child_ops.to_longname = "Remote serial target in ES1800-emulator protocol";
+ es1800_child_ops.to_doc = "Remote debugging on the es1800 emulator via a serial line.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ es1800_child_ops.to_open = es1800_child_open;
+ es1800_child_ops.to_close = NULL;
+ es1800_child_ops.to_attach = es1800_attach;
+ es1800_child_ops.to_post_attach = NULL;
+ es1800_child_ops.to_require_attach = NULL;
+ es1800_child_ops.to_detach = es1800_child_detach;
+ es1800_child_ops.to_require_detach = NULL;
+ es1800_child_ops.to_resume = es1800_resume;
+ es1800_child_ops.to_wait = es1800_wait;
+ es1800_child_ops.to_post_wait = NULL;
+ es1800_child_ops.to_fetch_registers = es1800_fetch_register;
+ es1800_child_ops.to_store_registers = es1800_store_register;
+ es1800_child_ops.to_prepare_to_store = es1800_prepare_to_store;
+ es1800_child_ops.to_xfer_memory = es1800_xfer_inferior_memory;
+ es1800_child_ops.to_files_info = es1800_files_info;
+ es1800_child_ops.to_insert_breakpoint = es1800_insert_breakpoint;
+ es1800_child_ops.to_remove_breakpoint = es1800_remove_breakpoint;
+ es1800_child_ops.to_terminal_init = NULL;
+ es1800_child_ops.to_terminal_inferior = NULL;
+ es1800_child_ops.to_terminal_ours_for_output = NULL;
+ es1800_child_ops.to_terminal_ours = NULL;
+ es1800_child_ops.to_terminal_info = NULL;
+ es1800_child_ops.to_kill = es1800_kill;
+ es1800_child_ops.to_load = es1800_load;
+ es1800_child_ops.to_lookup_symbol = NULL;
+ es1800_child_ops.to_create_inferior = es1800_create_inferior;
+ es1800_child_ops.to_post_startup_inferior = NULL;
+ es1800_child_ops.to_acknowledge_created_inferior = NULL;
+ es1800_child_ops.to_clone_and_follow_inferior = NULL;
+ es1800_child_ops.to_post_follow_inferior_by_clone = NULL;
+ es1800_child_ops.to_insert_fork_catchpoint = NULL;
+ es1800_child_ops.to_remove_fork_catchpoint = NULL;
+ es1800_child_ops.to_insert_vfork_catchpoint = NULL;
+ es1800_child_ops.to_remove_vfork_catchpoint = NULL;
+ es1800_child_ops.to_has_forked = NULL;
+ es1800_child_ops.to_has_vforked = NULL;
+ es1800_child_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ es1800_child_ops.to_post_follow_vfork = NULL;
+ es1800_child_ops.to_insert_exec_catchpoint = NULL;
+ es1800_child_ops.to_remove_exec_catchpoint = NULL;
+ es1800_child_ops.to_has_execd = NULL;
+ es1800_child_ops.to_reported_exec_events_per_exec_call = NULL;
+ es1800_child_ops.to_has_exited = NULL;
+ es1800_child_ops.to_mourn_inferior = es1800_mourn_inferior;
+ es1800_child_ops.to_can_run = 0;
+ es1800_child_ops.to_notice_signals = 0;
+ es1800_child_ops.to_thread_alive = 0;
+ es1800_child_ops.to_stop = 0;
+ es1800_child_ops.to_pid_to_exec_file = NULL;
+ es1800_child_ops.to_stratum = process_stratum;
+ es1800_child_ops.DONT_USE = 0;
+ es1800_child_ops.to_has_all_memory = 1;
+ es1800_child_ops.to_has_memory = 1;
+ es1800_child_ops.to_has_stack = 1;
+ es1800_child_ops.to_has_registers = 1;
+ es1800_child_ops.to_has_execution = 1;
+ es1800_child_ops.to_sections = NULL;
+ es1800_child_ops.to_sections_end = NULL;
+ es1800_child_ops.to_magic = OPS_MAGIC;
+}
+
+void
+_initialize_es1800 (void)
+{
+ init_es1800_ops ();
+ init_es1800_child_ops ();
+ add_target (&es1800_ops);
+ add_target (&es1800_child_ops);
+#ifdef PROVIDE_TRANSPARENT
+ add_com ("transparent", class_support, es1800_transparent,
+ "Start transparent communication with the ES 1800 emulator.");
+#endif /* PROVIDE_TRANSPARENT */
+ add_com ("init_break", class_support, es1800_init_break,
+ "Download break routine and initialize break facility on ES 1800");
+}
diff --git a/gdb/remote-est.c b/gdb/remote-est.c
new file mode 100644
index 00000000000..e045a8951cd
--- /dev/null
+++ b/gdb/remote-est.c
@@ -0,0 +1,169 @@
+/* Remote debugging interface for EST-300 ICE, for GDB
+ Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+
+ Written by Steve Chamberlain for Cygnus Support.
+ Re-written by Stu Grossman of 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 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "regcache.h"
+
+static void est_open (char *args, int from_tty);
+
+static void
+est_supply_register (char *regname, int regnamelen, char *val, int vallen)
+{
+ int regno;
+
+ if (regnamelen != 2)
+ return;
+
+ switch (regname[0])
+ {
+ case 'S':
+ if (regname[1] != 'R')
+ return;
+ regno = PS_REGNUM;
+ break;
+ case 'P':
+ if (regname[1] != 'C')
+ return;
+ regno = PC_REGNUM;
+ break;
+ case 'D':
+ if (regname[1] < '0' || regname[1] > '7')
+ return;
+ regno = regname[1] - '0' + D0_REGNUM;
+ break;
+ case 'A':
+ if (regname[1] < '0' || regname[1] > '7')
+ return;
+ regno = regname[1] - '0' + A0_REGNUM;
+ break;
+ default:
+ return;
+ }
+
+ monitor_supply_register (regno, val);
+}
+
+/*
+ * This array of registers needs to match the indexes used by GDB. The
+ * whole reason this exists is because the various ROM monitors use
+ * different names than GDB does, and don't support all the
+ * registers either. So, typing "info reg sp" becomes a "r30".
+ */
+
+static char *est_regnames[NUM_REGS] =
+{
+ "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
+ "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
+ "SR", "PC",
+};
+
+/*
+ * Define the monitor command strings. Since these are passed directly
+ * through to a printf style function, we need can include formatting
+ * strings. We also need a CR or LF on the end.
+ */
+
+static struct target_ops est_ops;
+
+static char *est_inits[] =
+{"he\r", /* Resets the prompt, and clears repeated cmds */
+ NULL};
+
+static struct monitor_ops est_cmds;
+
+static void
+init_est_cmds (void)
+{
+ est_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_NEED_REGDUMP_AFTER_CONT |
+ MO_SREC_ACK | MO_SREC_ACK_PLUS;
+ est_cmds.init = est_inits; /* Init strings */
+ est_cmds.cont = "go\r"; /* continue command */
+ est_cmds.step = "sidr\r"; /* single step */
+ est_cmds.stop = "\003"; /* ^C interrupts the program */
+ est_cmds.set_break = "sb %x\r"; /* set a breakpoint */
+ est_cmds.clr_break = "rb %x\r"; /* clear a breakpoint */
+ est_cmds.clr_all_break = "rb\r"; /* clear all breakpoints */
+ est_cmds.fill = "bfb %x %x %x\r"; /* fill (start end val) */
+ est_cmds.setmem.cmdb = "smb %x %x\r"; /* setmem.cmdb (addr, value) */
+ est_cmds.setmem.cmdw = "smw %x %x\r"; /* setmem.cmdw (addr, value) */
+ est_cmds.setmem.cmdl = "sml %x %x\r"; /* setmem.cmdl (addr, value) */
+ est_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ est_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
+ est_cmds.setmem.term = NULL; /* setreg.term */
+ est_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
+ est_cmds.getmem.cmdb = "dmb %x %x\r"; /* getmem.cmdb (addr, len) */
+ est_cmds.getmem.cmdw = "dmw %x %x\r"; /* getmem.cmdw (addr, len) */
+ est_cmds.getmem.cmdl = "dml %x %x\r"; /* getmem.cmdl (addr, len) */
+ est_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ est_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
+ est_cmds.getmem.term = NULL; /* getmem.term */
+ est_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
+ est_cmds.setreg.cmd = "sr %s %x\r"; /* setreg.cmd (name, value) */
+ est_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ est_cmds.setreg.term = NULL; /* setreg.term */
+ est_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
+ est_cmds.getreg.cmd = "dr %s\r"; /* getreg.cmd (name) */
+ est_cmds.getreg.resp_delim = " = "; /* getreg.resp_delim */
+ est_cmds.getreg.term = NULL; /* getreg.term */
+ est_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
+ est_cmds.dump_registers = "dr\r"; /* dump_registers */
+ est_cmds.register_pattern = "\\(\\w+\\) = \\([0-9a-fA-F]+\\)"; /* register_pattern */
+ est_cmds.supply_register = est_supply_register; /* supply_register */
+ est_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ est_cmds.load = "dl\r"; /* download command */
+ est_cmds.loadresp = "+"; /* load response */
+ est_cmds.prompt = ">BKM>"; /* monitor command prompt */
+ est_cmds.line_term = "\r"; /* end-of-line terminator */
+ est_cmds.cmd_end = NULL; /* optional command terminator */
+ est_cmds.target = &est_ops; /* target operations */
+ est_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ est_cmds.regnames = est_regnames; /* registers names */
+ est_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+} /* init_est_cmds */
+
+static void
+est_open (char *args, int from_tty)
+{
+ monitor_open (args, &est_cmds, from_tty);
+}
+
+void
+_initialize_est (void)
+{
+ init_est_cmds ();
+ init_monitor_ops (&est_ops);
+
+ est_ops.to_shortname = "est";
+ est_ops.to_longname = "EST background debug monitor";
+ est_ops.to_doc = "Debug via the EST BDM.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ est_ops.to_open = est_open;
+
+ add_target (&est_ops);
+}
diff --git a/gdb/remote-hms.c b/gdb/remote-hms.c
new file mode 100644
index 00000000000..4a2b088c508
--- /dev/null
+++ b/gdb/remote-hms.c
@@ -0,0 +1,157 @@
+/* Remote debugging interface for Hitachi HMS Monitor Version 1.0
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support. Written by Steve Chamberlain
+ (sac@cygnus.com).
+
+ 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "regcache.h"
+
+static void hms_open (char *args, int from_tty);
+static void
+hms_supply_register (char *regname, int regnamelen, char *val, int vallen)
+{
+ int regno;
+
+ if (regnamelen != 2)
+ return;
+ if (regname[0] != 'P')
+ return;
+ /* We scan off all the registers in one go */
+
+ val = monitor_supply_register (PC_REGNUM, val);
+ /* Skip the ccr string */
+ while (*val != '=' && *val)
+ val++;
+
+ val = monitor_supply_register (CCR_REGNUM, val + 1);
+
+ /* Skip up to rest of regs */
+ while (*val != '=' && *val)
+ val++;
+
+ for (regno = 0; regno < 7; regno++)
+ {
+ val = monitor_supply_register (regno, val + 1);
+ }
+}
+
+/*
+ * This array of registers needs to match the indexes used by GDB. The
+ * whole reason this exists is because the various ROM monitors use
+ * different names than GDB does, and don't support all the
+ * registers either. So, typing "info reg sp" becomes a "r30".
+ */
+
+static char *hms_regnames[NUM_REGS] =
+{
+ "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "CCR", "PC"
+};
+
+/*
+ * Define the monitor command strings. Since these are passed directly
+ * through to a printf style function, we need can include formatting
+ * strings. We also need a CR or LF on the end.
+ */
+
+static struct target_ops hms_ops;
+
+static char *hms_inits[] =
+{"\003", /* Resets the prompt, and clears repeated cmds */
+ NULL};
+
+static struct monitor_ops hms_cmds;
+
+static void
+init_hms_cmds (void)
+{
+ hms_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_GETMEM_NEEDS_RANGE;
+ hms_cmds.init = hms_inits; /* Init strings */
+ hms_cmds.cont = "g\r"; /* continue command */
+ hms_cmds.step = "s\r"; /* single step */
+ hms_cmds.stop = "\003"; /* ^C interrupts the program */
+ hms_cmds.set_break = "b %x\r"; /* set a breakpoint */
+ hms_cmds.clr_break = "b - %x\r"; /* clear a breakpoint */
+ hms_cmds.clr_all_break = "b -\r"; /* clear all breakpoints */
+ hms_cmds.fill = "f %x %x %x\r"; /* fill (start end val) */
+ hms_cmds.setmem.cmdb = "m.b %x=%x\r"; /* setmem.cmdb (addr, value) */
+ hms_cmds.setmem.cmdw = "m.w %x=%x\r"; /* setmem.cmdw (addr, value) */
+ hms_cmds.setmem.cmdl = NULL; /* setmem.cmdl (addr, value) */
+ hms_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ hms_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
+ hms_cmds.setmem.term = NULL; /* setreg.term */
+ hms_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
+ hms_cmds.getmem.cmdb = "m.b %x %x\r"; /* getmem.cmdb (addr, addr) */
+ hms_cmds.getmem.cmdw = "m.w %x %x\r"; /* getmem.cmdw (addr, addr) */
+ hms_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, addr) */
+ hms_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, addr) */
+ hms_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
+ hms_cmds.getmem.term = ">"; /* getmem.term */
+ hms_cmds.getmem.term_cmd = "\003"; /* getmem.term_cmd */
+ hms_cmds.setreg.cmd = "r %s=%x\r"; /* setreg.cmd (name, value) */
+ hms_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ hms_cmds.setreg.term = NULL; /* setreg.term */
+ hms_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
+ hms_cmds.getreg.cmd = "r %s\r"; /* getreg.cmd (name) */
+ hms_cmds.getreg.resp_delim = " ("; /* getreg.resp_delim */
+ hms_cmds.getreg.term = ":"; /* getreg.term */
+ hms_cmds.getreg.term_cmd = "\003"; /* getreg.term_cmd */
+ hms_cmds.dump_registers = "r\r"; /* dump_registers */
+ hms_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */
+ hms_cmds.supply_register = hms_supply_register; /* supply_register */
+ hms_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
+ hms_cmds.load = "tl\r"; /* download command */
+ hms_cmds.loadresp = NULL; /* load response */
+ hms_cmds.prompt = ">"; /* monitor command prompt */
+ hms_cmds.line_term = "\r"; /* end-of-command delimitor */
+ hms_cmds.cmd_end = NULL; /* optional command terminator */
+ hms_cmds.target = &hms_ops; /* target operations */
+ hms_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ hms_cmds.regnames = hms_regnames; /* registers names */
+ hms_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+} /* init_hms-cmds */
+
+static void
+hms_open (char *args, int from_tty)
+{
+ monitor_open (args, &hms_cmds, from_tty);
+}
+
+int write_dos_tick_delay;
+
+void
+_initialize_remote_hms (void)
+{
+ init_hms_cmds ();
+ init_monitor_ops (&hms_ops);
+
+ hms_ops.to_shortname = "hms";
+ hms_ops.to_longname = "Hitachi Microsystems H8/300 debug monitor";
+ hms_ops.to_doc = "Debug via the HMS monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ hms_ops.to_open = hms_open;
+ /* By trial and error I've found that this delay doesn't break things */
+ write_dos_tick_delay = 1;
+ add_target (&hms_ops);
+}
diff --git a/gdb/remote-mips.c b/gdb/remote-mips.c
new file mode 100644
index 00000000000..a1df0eb94e9
--- /dev/null
+++ b/gdb/remote-mips.c
@@ -0,0 +1,3599 @@
+/* Remote debugging interface for MIPS remote debugging protocol.
+
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Support. Written by Ian Lance Taylor
+ <ian@cygnus.com>.
+
+ 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 "defs.h"
+#include "inferior.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "serial.h"
+#include "target.h"
+#include "remote-utils.h"
+#include "gdb_string.h"
+#include "gdb_stat.h"
+#include "regcache.h"
+#include <ctype.h>
+
+
+/* Breakpoint types. Values 0, 1, and 2 must agree with the watch
+ types passed by breakpoint.c to target_insert_watchpoint.
+ Value 3 is our own invention, and is used for ordinary instruction
+ breakpoints. Value 4 is used to mark an unused watchpoint in tables. */
+enum break_type
+ {
+ BREAK_WRITE, /* 0 */
+ BREAK_READ, /* 1 */
+ BREAK_ACCESS, /* 2 */
+ BREAK_FETCH, /* 3 */
+ BREAK_UNUSED /* 4 */
+ };
+
+/* Prototypes for local functions. */
+
+static int mips_readchar (int timeout);
+
+static int mips_receive_header (unsigned char *hdr, int *pgarbage,
+ int ch, int timeout);
+
+static int mips_receive_trailer (unsigned char *trlr, int *pgarbage,
+ int *pch, int timeout);
+
+static int mips_cksum (const unsigned char *hdr,
+ const unsigned char *data, int len);
+
+static void mips_send_packet (const char *s, int get_ack);
+
+static void mips_send_command (const char *cmd, int prompt);
+
+static int mips_receive_packet (char *buff, int throw_error, int timeout);
+
+static ULONGEST mips_request (int cmd, ULONGEST addr, ULONGEST data,
+ int *perr, int timeout, char *buff);
+
+static void mips_initialize (void);
+
+static void mips_open (char *name, int from_tty);
+
+static void pmon_open (char *name, int from_tty);
+
+static void ddb_open (char *name, int from_tty);
+
+static void lsi_open (char *name, int from_tty);
+
+static void mips_close (int quitting);
+
+static void mips_detach (char *args, int from_tty);
+
+static void mips_resume (ptid_t ptid, int step,
+ enum target_signal siggnal);
+
+static ptid_t mips_wait (ptid_t ptid,
+ struct target_waitstatus *status);
+
+static int mips_map_regno (int regno);
+
+static void mips_fetch_registers (int regno);
+
+static void mips_prepare_to_store (void);
+
+static void mips_store_registers (int regno);
+
+static unsigned int mips_fetch_word (CORE_ADDR addr);
+
+static int mips_store_word (CORE_ADDR addr, unsigned int value,
+ char *old_contents);
+
+static int mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int write,
+ struct mem_attrib *attrib,
+ struct target_ops *target);
+
+static void mips_files_info (struct target_ops *ignore);
+
+static void mips_create_inferior (char *execfile, char *args, char **env);
+
+static void mips_mourn_inferior (void);
+
+static int pmon_makeb64 (unsigned long v, char *p, int n, int *chksum);
+
+static int pmon_zeroset (int recsize, char **buff, int *amount,
+ unsigned int *chksum);
+
+static int pmon_checkset (int recsize, char **buff, int *value);
+
+static void pmon_make_fastrec (char **outbuf, unsigned char *inbuf,
+ int *inptr, int inamount, int *recsize,
+ unsigned int *csum, unsigned int *zerofill);
+
+static int pmon_check_ack (char *mesg);
+
+static void pmon_start_download (void);
+
+static void pmon_end_download (int final, int bintotal);
+
+static void pmon_download (char *buffer, int length);
+
+static void pmon_load_fast (char *file);
+
+static void mips_load (char *file, int from_tty);
+
+static int mips_make_srec (char *buffer, int type, CORE_ADDR memaddr,
+ unsigned char *myaddr, int len);
+
+static int set_breakpoint (CORE_ADDR addr, int len, enum break_type type);
+
+static int clear_breakpoint (CORE_ADDR addr, int len, enum break_type type);
+
+static int common_breakpoint (int set, CORE_ADDR addr, int len,
+ enum break_type type);
+
+/* Forward declarations. */
+extern struct target_ops mips_ops;
+extern struct target_ops pmon_ops;
+extern struct target_ops ddb_ops;
+ /* *INDENT-OFF* */
+/* The MIPS remote debugging interface is built on top of a simple
+ packet protocol. Each packet is organized as follows:
+
+ SYN The first character is always a SYN (ASCII 026, or ^V). SYN
+ may not appear anywhere else in the packet. Any time a SYN is
+ seen, a new packet should be assumed to have begun.
+
+ TYPE_LEN
+ This byte contains the upper five bits of the logical length
+ of the data section, plus a single bit indicating whether this
+ is a data packet or an acknowledgement. The documentation
+ indicates that this bit is 1 for a data packet, but the actual
+ board uses 1 for an acknowledgement. The value of the byte is
+ 0x40 + (ack ? 0x20 : 0) + (len >> 6)
+ (we always have 0 <= len < 1024). Acknowledgement packets do
+ not carry data, and must have a data length of 0.
+
+ LEN1 This byte contains the lower six bits of the logical length of
+ the data section. The value is
+ 0x40 + (len & 0x3f)
+
+ SEQ This byte contains the six bit sequence number of the packet.
+ The value is
+ 0x40 + seq
+ An acknowlegment packet contains the sequence number of the
+ packet being acknowledged plus 1 modulo 64. Data packets are
+ transmitted in sequence. There may only be one outstanding
+ unacknowledged data packet at a time. The sequence numbers
+ are independent in each direction. If an acknowledgement for
+ the previous packet is received (i.e., an acknowledgement with
+ the sequence number of the packet just sent) the packet just
+ sent should be retransmitted. If no acknowledgement is
+ received within a timeout period, the packet should be
+ retransmitted. This has an unfortunate failure condition on a
+ high-latency line, as a delayed acknowledgement may lead to an
+ endless series of duplicate packets.
+
+ DATA The actual data bytes follow. The following characters are
+ escaped inline with DLE (ASCII 020, or ^P):
+ SYN (026) DLE S
+ DLE (020) DLE D
+ ^C (003) DLE C
+ ^S (023) DLE s
+ ^Q (021) DLE q
+ The additional DLE characters are not counted in the logical
+ length stored in the TYPE_LEN and LEN1 bytes.
+
+ CSUM1
+ CSUM2
+ CSUM3
+ These bytes contain an 18 bit checksum of the complete
+ contents of the packet excluding the SEQ byte and the
+ CSUM[123] bytes. The checksum is simply the twos complement
+ addition of all the bytes treated as unsigned characters. The
+ values of the checksum bytes are:
+ CSUM1: 0x40 + ((cksum >> 12) & 0x3f)
+ CSUM2: 0x40 + ((cksum >> 6) & 0x3f)
+ CSUM3: 0x40 + (cksum & 0x3f)
+
+ It happens that the MIPS remote debugging protocol always
+ communicates with ASCII strings. Because of this, this
+ implementation doesn't bother to handle the DLE quoting mechanism,
+ since it will never be required. */
+/* *INDENT-ON* */
+
+
+/* The SYN character which starts each packet. */
+#define SYN '\026'
+
+/* The 0x40 used to offset each packet (this value ensures that all of
+ the header and trailer bytes, other than SYN, are printable ASCII
+ characters). */
+#define HDR_OFFSET 0x40
+
+/* The indices of the bytes in the packet header. */
+#define HDR_INDX_SYN 0
+#define HDR_INDX_TYPE_LEN 1
+#define HDR_INDX_LEN1 2
+#define HDR_INDX_SEQ 3
+#define HDR_LENGTH 4
+
+/* The data/ack bit in the TYPE_LEN header byte. */
+#define TYPE_LEN_DA_BIT 0x20
+#define TYPE_LEN_DATA 0
+#define TYPE_LEN_ACK TYPE_LEN_DA_BIT
+
+/* How to compute the header bytes. */
+#define HDR_SET_SYN(data, len, seq) (SYN)
+#define HDR_SET_TYPE_LEN(data, len, seq) \
+ (HDR_OFFSET \
+ + ((data) ? TYPE_LEN_DATA : TYPE_LEN_ACK) \
+ + (((len) >> 6) & 0x1f))
+#define HDR_SET_LEN1(data, len, seq) (HDR_OFFSET + ((len) & 0x3f))
+#define HDR_SET_SEQ(data, len, seq) (HDR_OFFSET + (seq))
+
+/* Check that a header byte is reasonable. */
+#define HDR_CHECK(ch) (((ch) & HDR_OFFSET) == HDR_OFFSET)
+
+/* Get data from the header. These macros evaluate their argument
+ multiple times. */
+#define HDR_IS_DATA(hdr) \
+ (((hdr)[HDR_INDX_TYPE_LEN] & TYPE_LEN_DA_BIT) == TYPE_LEN_DATA)
+#define HDR_GET_LEN(hdr) \
+ ((((hdr)[HDR_INDX_TYPE_LEN] & 0x1f) << 6) + (((hdr)[HDR_INDX_LEN1] & 0x3f)))
+#define HDR_GET_SEQ(hdr) ((unsigned int)(hdr)[HDR_INDX_SEQ] & 0x3f)
+
+/* The maximum data length. */
+#define DATA_MAXLEN 1023
+
+/* The trailer offset. */
+#define TRLR_OFFSET HDR_OFFSET
+
+/* The indices of the bytes in the packet trailer. */
+#define TRLR_INDX_CSUM1 0
+#define TRLR_INDX_CSUM2 1
+#define TRLR_INDX_CSUM3 2
+#define TRLR_LENGTH 3
+
+/* How to compute the trailer bytes. */
+#define TRLR_SET_CSUM1(cksum) (TRLR_OFFSET + (((cksum) >> 12) & 0x3f))
+#define TRLR_SET_CSUM2(cksum) (TRLR_OFFSET + (((cksum) >> 6) & 0x3f))
+#define TRLR_SET_CSUM3(cksum) (TRLR_OFFSET + (((cksum) ) & 0x3f))
+
+/* Check that a trailer byte is reasonable. */
+#define TRLR_CHECK(ch) (((ch) & TRLR_OFFSET) == TRLR_OFFSET)
+
+/* Get data from the trailer. This evaluates its argument multiple
+ times. */
+#define TRLR_GET_CKSUM(trlr) \
+ ((((trlr)[TRLR_INDX_CSUM1] & 0x3f) << 12) \
+ + (((trlr)[TRLR_INDX_CSUM2] & 0x3f) << 6) \
+ + ((trlr)[TRLR_INDX_CSUM3] & 0x3f))
+
+/* The sequence number modulos. */
+#define SEQ_MODULOS (64)
+
+/* PMON commands to load from the serial port or UDP socket. */
+#define LOAD_CMD "load -b -s tty0\r"
+#define LOAD_CMD_UDP "load -b -s udp\r"
+
+/* The target vectors for the four different remote MIPS targets.
+ These are initialized with code in _initialize_remote_mips instead
+ of static initializers, to make it easier to extend the target_ops
+ vector later. */
+struct target_ops mips_ops, pmon_ops, ddb_ops, lsi_ops;
+
+enum mips_monitor_type
+ {
+ /* IDT/SIM monitor being used: */
+ MON_IDT,
+ /* PMON monitor being used: */
+ MON_PMON, /* 3.0.83 [COGENT,EB,FP,NET] Algorithmics Ltd. Nov 9 1995 17:19:50 */
+ MON_DDB, /* 2.7.473 [DDBVR4300,EL,FP,NET] Risq Modular Systems, Thu Jun 6 09:28:40 PDT 1996 */
+ MON_LSI, /* 4.3.12 [EB,FP], LSI LOGIC Corp. Tue Feb 25 13:22:14 1997 */
+ /* Last and unused value, for sizing vectors, etc. */
+ MON_LAST
+ };
+static enum mips_monitor_type mips_monitor = MON_LAST;
+
+/* The monitor prompt text. If the user sets the PMON prompt
+ to some new value, the GDB `set monitor-prompt' command must also
+ be used to inform GDB about the expected prompt. Otherwise, GDB
+ will not be able to connect to PMON in mips_initialize().
+ If the `set monitor-prompt' command is not used, the expected
+ default prompt will be set according the target:
+ target prompt
+ ----- -----
+ pmon PMON>
+ ddb NEC010>
+ lsi PMON>
+ */
+static char *mips_monitor_prompt;
+
+/* Set to 1 if the target is open. */
+static int mips_is_open;
+
+/* Currently active target description (if mips_is_open == 1) */
+static struct target_ops *current_ops;
+
+/* Set to 1 while the connection is being initialized. */
+static int mips_initializing;
+
+/* Set to 1 while the connection is being brought down. */
+static int mips_exiting;
+
+/* The next sequence number to send. */
+static unsigned int mips_send_seq;
+
+/* The next sequence number we expect to receive. */
+static unsigned int mips_receive_seq;
+
+/* The time to wait before retransmitting a packet, in seconds. */
+static int mips_retransmit_wait = 3;
+
+/* The number of times to try retransmitting a packet before giving up. */
+static int mips_send_retries = 10;
+
+/* The number of garbage characters to accept when looking for an
+ SYN for the next packet. */
+static int mips_syn_garbage = 10;
+
+/* The time to wait for a packet, in seconds. */
+static int mips_receive_wait = 5;
+
+/* Set if we have sent a packet to the board but have not yet received
+ a reply. */
+static int mips_need_reply = 0;
+
+/* Handle used to access serial I/O stream. */
+static struct serial *mips_desc;
+
+/* UDP handle used to download files to target. */
+static struct serial *udp_desc;
+static int udp_in_use;
+
+/* TFTP filename used to download files to DDB board, in the form
+ host:filename. */
+static char *tftp_name; /* host:filename */
+static char *tftp_localname; /* filename portion of above */
+static int tftp_in_use;
+static FILE *tftp_file;
+
+/* Counts the number of times the user tried to interrupt the target (usually
+ via ^C. */
+static int interrupt_count;
+
+/* If non-zero, means that the target is running. */
+static int mips_wait_flag = 0;
+
+/* If non-zero, monitor supports breakpoint commands. */
+static int monitor_supports_breakpoints = 0;
+
+/* Data cache header. */
+
+#if 0 /* not used (yet?) */
+static DCACHE *mips_dcache;
+#endif
+
+/* Non-zero means that we've just hit a read or write watchpoint */
+static int hit_watchpoint;
+
+/* Table of breakpoints/watchpoints (used only on LSI PMON target).
+ The table is indexed by a breakpoint number, which is an integer
+ from 0 to 255 returned by the LSI PMON when a breakpoint is set.
+ */
+#define MAX_LSI_BREAKPOINTS 256
+struct lsi_breakpoint_info
+ {
+ enum break_type type; /* type of breakpoint */
+ CORE_ADDR addr; /* address of breakpoint */
+ int len; /* length of region being watched */
+ unsigned long value; /* value to watch */
+ }
+lsi_breakpoints[MAX_LSI_BREAKPOINTS];
+
+/* Error/warning codes returned by LSI PMON for breakpoint commands.
+ Warning values may be ORed together; error values may not. */
+#define W_WARN 0x100 /* This bit is set if the error code is a warning */
+#define W_MSK 0x101 /* warning: Range feature is supported via mask */
+#define W_VAL 0x102 /* warning: Value check is not supported in hardware */
+#define W_QAL 0x104 /* warning: Requested qualifiers are not supported in hardware */
+
+#define E_ERR 0x200 /* This bit is set if the error code is an error */
+#define E_BPT 0x200 /* error: No such breakpoint number */
+#define E_RGE 0x201 /* error: Range is not supported */
+#define E_QAL 0x202 /* error: The requested qualifiers can not be used */
+#define E_OUT 0x203 /* error: Out of hardware resources */
+#define E_NON 0x204 /* error: Hardware breakpoint not supported */
+
+struct lsi_error
+ {
+ int code; /* error code */
+ char *string; /* string associated with this code */
+ };
+
+struct lsi_error lsi_warning_table[] =
+{
+ {W_MSK, "Range feature is supported via mask"},
+ {W_VAL, "Value check is not supported in hardware"},
+ {W_QAL, "Requested qualifiers are not supported in hardware"},
+ {0, NULL}
+};
+
+struct lsi_error lsi_error_table[] =
+{
+ {E_BPT, "No such breakpoint number"},
+ {E_RGE, "Range is not supported"},
+ {E_QAL, "The requested qualifiers can not be used"},
+ {E_OUT, "Out of hardware resources"},
+ {E_NON, "Hardware breakpoint not supported"},
+ {0, NULL}
+};
+
+/* Set to 1 with the 'set monitor-warnings' command to enable printing
+ of warnings returned by PMON when hardware breakpoints are used. */
+static int monitor_warnings;
+
+
+static void
+close_ports (void)
+{
+ mips_is_open = 0;
+ serial_close (mips_desc);
+
+ if (udp_in_use)
+ {
+ serial_close (udp_desc);
+ udp_in_use = 0;
+ }
+ tftp_in_use = 0;
+}
+
+/* Handle low-level error that we can't recover from. Note that just
+ error()ing out from target_wait or some such low-level place will cause
+ all hell to break loose--the rest of GDB will tend to get left in an
+ inconsistent state. */
+
+static NORETURN void
+mips_error (char *string,...)
+{
+ va_list args;
+
+ va_start (args, string);
+
+ target_terminal_ours ();
+ wrap_here (""); /* Force out any buffered output */
+ gdb_flush (gdb_stdout);
+ if (error_pre_print)
+ fprintf_filtered (gdb_stderr, error_pre_print);
+ vfprintf_filtered (gdb_stderr, string, args);
+ fprintf_filtered (gdb_stderr, "\n");
+ va_end (args);
+ gdb_flush (gdb_stderr);
+
+ /* Clean up in such a way that mips_close won't try to talk to the
+ board (it almost surely won't work since we weren't able to talk to
+ it). */
+ close_ports ();
+
+ printf_unfiltered ("Ending remote MIPS debugging.\n");
+ target_mourn_inferior ();
+
+ throw_exception (RETURN_ERROR);
+}
+
+/* putc_readable - print a character, displaying non-printable chars in
+ ^x notation or in hex. */
+
+static void
+fputc_readable (int ch, struct ui_file *file)
+{
+ if (ch == '\n')
+ fputc_unfiltered ('\n', file);
+ else if (ch == '\r')
+ fprintf_unfiltered (file, "\\r");
+ else if (ch < 0x20) /* ASCII control character */
+ fprintf_unfiltered (file, "^%c", ch + '@');
+ else if (ch >= 0x7f) /* non-ASCII characters (rubout or greater) */
+ fprintf_unfiltered (file, "[%02x]", ch & 0xff);
+ else
+ fputc_unfiltered (ch, file);
+}
+
+
+/* puts_readable - print a string, displaying non-printable chars in
+ ^x notation or in hex. */
+
+static void
+fputs_readable (const char *string, struct ui_file *file)
+{
+ int c;
+
+ while ((c = *string++) != '\0')
+ fputc_readable (c, file);
+}
+
+
+/* Wait until STRING shows up in mips_desc. Returns 1 if successful, else 0 if
+ timed out. TIMEOUT specifies timeout value in seconds.
+ */
+
+int
+mips_expect_timeout (const char *string, int timeout)
+{
+ const char *p = string;
+
+ if (remote_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Expected \"");
+ fputs_readable (string, gdb_stdlog);
+ fprintf_unfiltered (gdb_stdlog, "\", got \"");
+ }
+
+ immediate_quit++;
+ while (1)
+ {
+ int c;
+
+ /* Must use serial_readchar() here cuz mips_readchar would get
+ confused if we were waiting for the mips_monitor_prompt... */
+
+ c = serial_readchar (mips_desc, timeout);
+
+ if (c == SERIAL_TIMEOUT)
+ {
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "\": FAIL\n");
+ return 0;
+ }
+
+ if (remote_debug)
+ fputc_readable (c, gdb_stdlog);
+
+ if (c == *p++)
+ {
+ if (*p == '\0')
+ {
+ immediate_quit--;
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "\": OK\n");
+ return 1;
+ }
+ }
+ else
+ {
+ p = string;
+ if (c == *p)
+ p++;
+ }
+ }
+}
+
+/* Wait until STRING shows up in mips_desc. Returns 1 if successful, else 0 if
+ timed out. The timeout value is hard-coded to 2 seconds. Use
+ mips_expect_timeout if a different timeout value is needed.
+ */
+
+int
+mips_expect (const char *string)
+{
+ return mips_expect_timeout (string, remote_timeout);
+}
+
+/* Read the required number of characters into the given buffer (which
+ is assumed to be large enough). The only failure is a timeout. */
+int
+mips_getstring (char *string, int n)
+{
+ char *p = string;
+ int c;
+
+ immediate_quit++;
+ while (n > 0)
+ {
+ c = serial_readchar (mips_desc, remote_timeout);
+
+ if (c == SERIAL_TIMEOUT)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "Failed to read %d characters from target (TIMEOUT)\n", n);
+ immediate_quit--;
+ return 0;
+ }
+
+ *p++ = c;
+ n--;
+ }
+
+ immediate_quit--;
+ return 1;
+}
+
+/* Read a character from the remote, aborting on error. Returns
+ SERIAL_TIMEOUT on timeout (since that's what serial_readchar()
+ returns). FIXME: If we see the string mips_monitor_prompt from the
+ board, then we are debugging on the main console port, and we have
+ somehow dropped out of remote debugging mode. In this case, we
+ automatically go back in to remote debugging mode. This is a hack,
+ put in because I can't find any way for a program running on the
+ remote board to terminate without also ending remote debugging
+ mode. I assume users won't have any trouble with this; for one
+ thing, the IDT documentation generally assumes that the remote
+ debugging port is not the console port. This is, however, very
+ convenient for DejaGnu when you only have one connected serial
+ port. */
+
+static int
+mips_readchar (int timeout)
+{
+ int ch;
+ static int state = 0;
+ int mips_monitor_prompt_len = strlen (mips_monitor_prompt);
+
+ {
+ int i;
+
+ i = timeout;
+ if (i == -1 && watchdog > 0)
+ i = watchdog;
+ }
+
+ if (state == mips_monitor_prompt_len)
+ timeout = 1;
+ ch = serial_readchar (mips_desc, timeout);
+
+ if (ch == SERIAL_TIMEOUT && timeout == -1) /* Watchdog went off */
+ {
+ target_mourn_inferior ();
+ error ("Watchdog has expired. Target detached.\n");
+ }
+
+ if (ch == SERIAL_EOF)
+ mips_error ("End of file from remote");
+ if (ch == SERIAL_ERROR)
+ mips_error ("Error reading from remote: %s", safe_strerror (errno));
+ if (remote_debug > 1)
+ {
+ /* Don't use _filtered; we can't deal with a QUIT out of
+ target_wait, and I think this might be called from there. */
+ if (ch != SERIAL_TIMEOUT)
+ fprintf_unfiltered (gdb_stdlog, "Read '%c' %d 0x%x\n", ch, ch, ch);
+ else
+ fprintf_unfiltered (gdb_stdlog, "Timed out in read\n");
+ }
+
+ /* If we have seen mips_monitor_prompt and we either time out, or
+ we see a @ (which was echoed from a packet we sent), reset the
+ board as described above. The first character in a packet after
+ the SYN (which is not echoed) is always an @ unless the packet is
+ more than 64 characters long, which ours never are. */
+ if ((ch == SERIAL_TIMEOUT || ch == '@')
+ && state == mips_monitor_prompt_len
+ && !mips_initializing
+ && !mips_exiting)
+ {
+ if (remote_debug > 0)
+ /* Don't use _filtered; we can't deal with a QUIT out of
+ target_wait, and I think this might be called from there. */
+ fprintf_unfiltered (gdb_stdlog, "Reinitializing MIPS debugging mode\n");
+
+ mips_need_reply = 0;
+ mips_initialize ();
+
+ state = 0;
+
+ /* At this point, about the only thing we can do is abort the command
+ in progress and get back to command level as quickly as possible. */
+
+ error ("Remote board reset, debug protocol re-initialized.");
+ }
+
+ if (ch == mips_monitor_prompt[state])
+ ++state;
+ else
+ state = 0;
+
+ return ch;
+}
+
+/* Get a packet header, putting the data in the supplied buffer.
+ PGARBAGE is a pointer to the number of garbage characters received
+ so far. CH is the last character received. Returns 0 for success,
+ or -1 for timeout. */
+
+static int
+mips_receive_header (unsigned char *hdr, int *pgarbage, int ch, int timeout)
+{
+ int i;
+
+ while (1)
+ {
+ /* Wait for a SYN. mips_syn_garbage is intended to prevent
+ sitting here indefinitely if the board sends us one garbage
+ character per second. ch may already have a value from the
+ last time through the loop. */
+ while (ch != SYN)
+ {
+ ch = mips_readchar (timeout);
+ if (ch == SERIAL_TIMEOUT)
+ return -1;
+ if (ch != SYN)
+ {
+ /* Printing the character here lets the user of gdb see
+ what the program is outputting, if the debugging is
+ being done on the console port. Don't use _filtered:
+ we can't deal with a QUIT out of target_wait and
+ buffered target output confuses the user. */
+ if (!mips_initializing || remote_debug > 0)
+ {
+ if (isprint (ch) || isspace (ch))
+ {
+ fputc_unfiltered (ch, gdb_stdtarg);
+ }
+ else
+ {
+ fputc_readable (ch, gdb_stdtarg);
+ }
+ gdb_flush (gdb_stdtarg);
+ }
+
+ /* Only count unprintable characters. */
+ if (! (isprint (ch) || isspace (ch)))
+ (*pgarbage) += 1;
+
+ if (mips_syn_garbage > 0
+ && *pgarbage > mips_syn_garbage)
+ mips_error ("Debug protocol failure: more than %d characters before a sync.",
+ mips_syn_garbage);
+ }
+ }
+
+ /* Get the packet header following the SYN. */
+ for (i = 1; i < HDR_LENGTH; i++)
+ {
+ ch = mips_readchar (timeout);
+ if (ch == SERIAL_TIMEOUT)
+ return -1;
+ /* Make sure this is a header byte. */
+ if (ch == SYN || !HDR_CHECK (ch))
+ break;
+
+ hdr[i] = ch;
+ }
+
+ /* If we got the complete header, we can return. Otherwise we
+ loop around and keep looking for SYN. */
+ if (i >= HDR_LENGTH)
+ return 0;
+ }
+}
+
+/* Get a packet header, putting the data in the supplied buffer.
+ PGARBAGE is a pointer to the number of garbage characters received
+ so far. The last character read is returned in *PCH. Returns 0
+ for success, -1 for timeout, -2 for error. */
+
+static int
+mips_receive_trailer (unsigned char *trlr, int *pgarbage, int *pch, int timeout)
+{
+ int i;
+ int ch;
+
+ for (i = 0; i < TRLR_LENGTH; i++)
+ {
+ ch = mips_readchar (timeout);
+ *pch = ch;
+ if (ch == SERIAL_TIMEOUT)
+ return -1;
+ if (!TRLR_CHECK (ch))
+ return -2;
+ trlr[i] = ch;
+ }
+ return 0;
+}
+
+/* Get the checksum of a packet. HDR points to the packet header.
+ DATA points to the packet data. LEN is the length of DATA. */
+
+static int
+mips_cksum (const unsigned char *hdr, const unsigned char *data, int len)
+{
+ register const unsigned char *p;
+ register int c;
+ register int cksum;
+
+ cksum = 0;
+
+ /* The initial SYN is not included in the checksum. */
+ c = HDR_LENGTH - 1;
+ p = hdr + 1;
+ while (c-- != 0)
+ cksum += *p++;
+
+ c = len;
+ p = data;
+ while (c-- != 0)
+ cksum += *p++;
+
+ return cksum;
+}
+
+/* Send a packet containing the given ASCII string. */
+
+static void
+mips_send_packet (const char *s, int get_ack)
+{
+ /* unsigned */ int len;
+ unsigned char *packet;
+ register int cksum;
+ int try;
+
+ len = strlen (s);
+ if (len > DATA_MAXLEN)
+ mips_error ("MIPS protocol data packet too long: %s", s);
+
+ packet = (unsigned char *) alloca (HDR_LENGTH + len + TRLR_LENGTH + 1);
+
+ packet[HDR_INDX_SYN] = HDR_SET_SYN (1, len, mips_send_seq);
+ packet[HDR_INDX_TYPE_LEN] = HDR_SET_TYPE_LEN (1, len, mips_send_seq);
+ packet[HDR_INDX_LEN1] = HDR_SET_LEN1 (1, len, mips_send_seq);
+ packet[HDR_INDX_SEQ] = HDR_SET_SEQ (1, len, mips_send_seq);
+
+ memcpy (packet + HDR_LENGTH, s, len);
+
+ cksum = mips_cksum (packet, packet + HDR_LENGTH, len);
+ packet[HDR_LENGTH + len + TRLR_INDX_CSUM1] = TRLR_SET_CSUM1 (cksum);
+ packet[HDR_LENGTH + len + TRLR_INDX_CSUM2] = TRLR_SET_CSUM2 (cksum);
+ packet[HDR_LENGTH + len + TRLR_INDX_CSUM3] = TRLR_SET_CSUM3 (cksum);
+
+ /* Increment the sequence number. This will set mips_send_seq to
+ the sequence number we expect in the acknowledgement. */
+ mips_send_seq = (mips_send_seq + 1) % SEQ_MODULOS;
+
+ /* We can only have one outstanding data packet, so we just wait for
+ the acknowledgement here. Keep retransmitting the packet until
+ we get one, or until we've tried too many times. */
+ for (try = 0; try < mips_send_retries; try++)
+ {
+ int garbage;
+ int ch;
+
+ if (remote_debug > 0)
+ {
+ /* Don't use _filtered; we can't deal with a QUIT out of
+ target_wait, and I think this might be called from there. */
+ packet[HDR_LENGTH + len + TRLR_LENGTH] = '\0';
+ fprintf_unfiltered (gdb_stdlog, "Writing \"%s\"\n", packet + 1);
+ }
+
+ if (serial_write (mips_desc, packet,
+ HDR_LENGTH + len + TRLR_LENGTH) != 0)
+ mips_error ("write to target failed: %s", safe_strerror (errno));
+
+ if (!get_ack)
+ return;
+
+ garbage = 0;
+ ch = 0;
+ while (1)
+ {
+ unsigned char hdr[HDR_LENGTH + 1];
+ unsigned char trlr[TRLR_LENGTH + 1];
+ int err;
+ unsigned int seq;
+
+ /* Get the packet header. If we time out, resend the data
+ packet. */
+ err = mips_receive_header (hdr, &garbage, ch, mips_retransmit_wait);
+ if (err != 0)
+ break;
+
+ ch = 0;
+
+ /* If we get a data packet, assume it is a duplicate and
+ ignore it. FIXME: If the acknowledgement is lost, this
+ data packet may be the packet the remote sends after the
+ acknowledgement. */
+ if (HDR_IS_DATA (hdr))
+ {
+ int i;
+
+ /* Ignore any errors raised whilst attempting to ignore
+ packet. */
+
+ len = HDR_GET_LEN (hdr);
+
+ for (i = 0; i < len; i++)
+ {
+ int rch;
+
+ rch = mips_readchar (remote_timeout);
+ if (rch == SYN)
+ {
+ ch = SYN;
+ break;
+ }
+ if (rch == SERIAL_TIMEOUT)
+ break;
+ /* ignore the character */
+ }
+
+ if (i == len)
+ (void) mips_receive_trailer (trlr, &garbage, &ch,
+ remote_timeout);
+
+ /* We don't bother checking the checksum, or providing an
+ ACK to the packet. */
+ continue;
+ }
+
+ /* If the length is not 0, this is a garbled packet. */
+ if (HDR_GET_LEN (hdr) != 0)
+ continue;
+
+ /* Get the packet trailer. */
+ err = mips_receive_trailer (trlr, &garbage, &ch,
+ mips_retransmit_wait);
+
+ /* If we timed out, resend the data packet. */
+ if (err == -1)
+ break;
+
+ /* If we got a bad character, reread the header. */
+ if (err != 0)
+ continue;
+
+ /* If the checksum does not match the trailer checksum, this
+ is a bad packet; ignore it. */
+ if (mips_cksum (hdr, (unsigned char *) NULL, 0)
+ != TRLR_GET_CKSUM (trlr))
+ continue;
+
+ if (remote_debug > 0)
+ {
+ hdr[HDR_LENGTH] = '\0';
+ trlr[TRLR_LENGTH] = '\0';
+ /* Don't use _filtered; we can't deal with a QUIT out of
+ target_wait, and I think this might be called from there. */
+ fprintf_unfiltered (gdb_stdlog, "Got ack %d \"%s%s\"\n",
+ HDR_GET_SEQ (hdr), hdr + 1, trlr);
+ }
+
+ /* If this ack is for the current packet, we're done. */
+ seq = HDR_GET_SEQ (hdr);
+ if (seq == mips_send_seq)
+ return;
+
+ /* If this ack is for the last packet, resend the current
+ packet. */
+ if ((seq + 1) % SEQ_MODULOS == mips_send_seq)
+ break;
+
+ /* Otherwise this is a bad ack; ignore it. Increment the
+ garbage count to ensure that we do not stay in this loop
+ forever. */
+ ++garbage;
+ }
+ }
+
+ mips_error ("Remote did not acknowledge packet");
+}
+
+/* Receive and acknowledge a packet, returning the data in BUFF (which
+ should be DATA_MAXLEN + 1 bytes). The protocol documentation
+ implies that only the sender retransmits packets, so this code just
+ waits silently for a packet. It returns the length of the received
+ packet. If THROW_ERROR is nonzero, call error() on errors. If not,
+ don't print an error message and return -1. */
+
+static int
+mips_receive_packet (char *buff, int throw_error, int timeout)
+{
+ int ch;
+ int garbage;
+ int len;
+ unsigned char ack[HDR_LENGTH + TRLR_LENGTH + 1];
+ int cksum;
+
+ ch = 0;
+ garbage = 0;
+ while (1)
+ {
+ unsigned char hdr[HDR_LENGTH];
+ unsigned char trlr[TRLR_LENGTH];
+ int i;
+ int err;
+
+ if (mips_receive_header (hdr, &garbage, ch, timeout) != 0)
+ {
+ if (throw_error)
+ mips_error ("Timed out waiting for remote packet");
+ else
+ return -1;
+ }
+
+ ch = 0;
+
+ /* An acknowledgement is probably a duplicate; ignore it. */
+ if (!HDR_IS_DATA (hdr))
+ {
+ len = HDR_GET_LEN (hdr);
+ /* Check if the length is valid for an ACK, we may aswell
+ try and read the remainder of the packet: */
+ if (len == 0)
+ {
+ /* Ignore the error condition, since we are going to
+ ignore the packet anyway. */
+ (void) mips_receive_trailer (trlr, &garbage, &ch, timeout);
+ }
+ /* Don't use _filtered; we can't deal with a QUIT out of
+ target_wait, and I think this might be called from there. */
+ if (remote_debug > 0)
+ fprintf_unfiltered (gdb_stdlog, "Ignoring unexpected ACK\n");
+ continue;
+ }
+
+ len = HDR_GET_LEN (hdr);
+ for (i = 0; i < len; i++)
+ {
+ int rch;
+
+ rch = mips_readchar (timeout);
+ if (rch == SYN)
+ {
+ ch = SYN;
+ break;
+ }
+ if (rch == SERIAL_TIMEOUT)
+ {
+ if (throw_error)
+ mips_error ("Timed out waiting for remote packet");
+ else
+ return -1;
+ }
+ buff[i] = rch;
+ }
+
+ if (i < len)
+ {
+ /* Don't use _filtered; we can't deal with a QUIT out of
+ target_wait, and I think this might be called from there. */
+ if (remote_debug > 0)
+ fprintf_unfiltered (gdb_stdlog,
+ "Got new SYN after %d chars (wanted %d)\n",
+ i, len);
+ continue;
+ }
+
+ err = mips_receive_trailer (trlr, &garbage, &ch, timeout);
+ if (err == -1)
+ {
+ if (throw_error)
+ mips_error ("Timed out waiting for packet");
+ else
+ return -1;
+ }
+ if (err == -2)
+ {
+ /* Don't use _filtered; we can't deal with a QUIT out of
+ target_wait, and I think this might be called from there. */
+ if (remote_debug > 0)
+ fprintf_unfiltered (gdb_stdlog, "Got SYN when wanted trailer\n");
+ continue;
+ }
+
+ /* If this is the wrong sequence number, ignore it. */
+ if (HDR_GET_SEQ (hdr) != mips_receive_seq)
+ {
+ /* Don't use _filtered; we can't deal with a QUIT out of
+ target_wait, and I think this might be called from there. */
+ if (remote_debug > 0)
+ fprintf_unfiltered (gdb_stdlog,
+ "Ignoring sequence number %d (want %d)\n",
+ HDR_GET_SEQ (hdr), mips_receive_seq);
+ continue;
+ }
+
+ if (mips_cksum (hdr, buff, len) == TRLR_GET_CKSUM (trlr))
+ break;
+
+ if (remote_debug > 0)
+ /* Don't use _filtered; we can't deal with a QUIT out of
+ target_wait, and I think this might be called from there. */
+ printf_unfiltered ("Bad checksum; data %d, trailer %d\n",
+ mips_cksum (hdr, buff, len),
+ TRLR_GET_CKSUM (trlr));
+
+ /* The checksum failed. Send an acknowledgement for the
+ previous packet to tell the remote to resend the packet. */
+ ack[HDR_INDX_SYN] = HDR_SET_SYN (0, 0, mips_receive_seq);
+ ack[HDR_INDX_TYPE_LEN] = HDR_SET_TYPE_LEN (0, 0, mips_receive_seq);
+ ack[HDR_INDX_LEN1] = HDR_SET_LEN1 (0, 0, mips_receive_seq);
+ ack[HDR_INDX_SEQ] = HDR_SET_SEQ (0, 0, mips_receive_seq);
+
+ cksum = mips_cksum (ack, (unsigned char *) NULL, 0);
+
+ ack[HDR_LENGTH + TRLR_INDX_CSUM1] = TRLR_SET_CSUM1 (cksum);
+ ack[HDR_LENGTH + TRLR_INDX_CSUM2] = TRLR_SET_CSUM2 (cksum);
+ ack[HDR_LENGTH + TRLR_INDX_CSUM3] = TRLR_SET_CSUM3 (cksum);
+
+ if (remote_debug > 0)
+ {
+ ack[HDR_LENGTH + TRLR_LENGTH] = '\0';
+ /* Don't use _filtered; we can't deal with a QUIT out of
+ target_wait, and I think this might be called from there. */
+ printf_unfiltered ("Writing ack %d \"%s\"\n", mips_receive_seq,
+ ack + 1);
+ }
+
+ if (serial_write (mips_desc, ack, HDR_LENGTH + TRLR_LENGTH) != 0)
+ {
+ if (throw_error)
+ mips_error ("write to target failed: %s", safe_strerror (errno));
+ else
+ return -1;
+ }
+ }
+
+ if (remote_debug > 0)
+ {
+ buff[len] = '\0';
+ /* Don't use _filtered; we can't deal with a QUIT out of
+ target_wait, and I think this might be called from there. */
+ printf_unfiltered ("Got packet \"%s\"\n", buff);
+ }
+
+ /* We got the packet. Send an acknowledgement. */
+ mips_receive_seq = (mips_receive_seq + 1) % SEQ_MODULOS;
+
+ ack[HDR_INDX_SYN] = HDR_SET_SYN (0, 0, mips_receive_seq);
+ ack[HDR_INDX_TYPE_LEN] = HDR_SET_TYPE_LEN (0, 0, mips_receive_seq);
+ ack[HDR_INDX_LEN1] = HDR_SET_LEN1 (0, 0, mips_receive_seq);
+ ack[HDR_INDX_SEQ] = HDR_SET_SEQ (0, 0, mips_receive_seq);
+
+ cksum = mips_cksum (ack, (unsigned char *) NULL, 0);
+
+ ack[HDR_LENGTH + TRLR_INDX_CSUM1] = TRLR_SET_CSUM1 (cksum);
+ ack[HDR_LENGTH + TRLR_INDX_CSUM2] = TRLR_SET_CSUM2 (cksum);
+ ack[HDR_LENGTH + TRLR_INDX_CSUM3] = TRLR_SET_CSUM3 (cksum);
+
+ if (remote_debug > 0)
+ {
+ ack[HDR_LENGTH + TRLR_LENGTH] = '\0';
+ /* Don't use _filtered; we can't deal with a QUIT out of
+ target_wait, and I think this might be called from there. */
+ printf_unfiltered ("Writing ack %d \"%s\"\n", mips_receive_seq,
+ ack + 1);
+ }
+
+ if (serial_write (mips_desc, ack, HDR_LENGTH + TRLR_LENGTH) != 0)
+ {
+ if (throw_error)
+ mips_error ("write to target failed: %s", safe_strerror (errno));
+ else
+ return -1;
+ }
+
+ return len;
+}
+
+/* Optionally send a request to the remote system and optionally wait
+ for the reply. This implements the remote debugging protocol,
+ which is built on top of the packet protocol defined above. Each
+ request has an ADDR argument and a DATA argument. The following
+ requests are defined:
+
+ \0 don't send a request; just wait for a reply
+ i read word from instruction space at ADDR
+ d read word from data space at ADDR
+ I write DATA to instruction space at ADDR
+ D write DATA to data space at ADDR
+ r read register number ADDR
+ R set register number ADDR to value DATA
+ c continue execution (if ADDR != 1, set pc to ADDR)
+ s single step (if ADDR != 1, set pc to ADDR)
+
+ The read requests return the value requested. The write requests
+ return the previous value in the changed location. The execution
+ requests return a UNIX wait value (the approximate signal which
+ caused execution to stop is in the upper eight bits).
+
+ If PERR is not NULL, this function waits for a reply. If an error
+ occurs, it sets *PERR to 1 and sets errno according to what the
+ target board reports. */
+
+static ULONGEST
+mips_request (int cmd,
+ ULONGEST addr,
+ ULONGEST data,
+ int *perr,
+ int timeout,
+ char *buff)
+{
+ char myBuff[DATA_MAXLEN + 1];
+ int len;
+ int rpid;
+ char rcmd;
+ int rerrflg;
+ unsigned long rresponse;
+
+ if (buff == (char *) NULL)
+ buff = myBuff;
+
+ if (cmd != '\0')
+ {
+ if (mips_need_reply)
+ internal_error (__FILE__, __LINE__,
+ "mips_request: Trying to send command before reply");
+ sprintf (buff, "0x0 %c 0x%s 0x%s", cmd, paddr_nz (addr), paddr_nz (data));
+ mips_send_packet (buff, 1);
+ mips_need_reply = 1;
+ }
+
+ if (perr == (int *) NULL)
+ return 0;
+
+ if (!mips_need_reply)
+ internal_error (__FILE__, __LINE__,
+ "mips_request: Trying to get reply before command");
+
+ mips_need_reply = 0;
+
+ len = mips_receive_packet (buff, 1, timeout);
+ buff[len] = '\0';
+
+ if (sscanf (buff, "0x%x %c 0x%x 0x%lx",
+ &rpid, &rcmd, &rerrflg, &rresponse) != 4
+ || (cmd != '\0' && rcmd != cmd))
+ mips_error ("Bad response from remote board");
+
+ if (rerrflg != 0)
+ {
+ *perr = 1;
+
+ /* FIXME: This will returns MIPS errno numbers, which may or may
+ not be the same as errno values used on other systems. If
+ they stick to common errno values, they will be the same, but
+ if they don't, they must be translated. */
+ errno = rresponse;
+
+ return 0;
+ }
+
+ *perr = 0;
+ return rresponse;
+}
+
+static void
+mips_initialize_cleanups (PTR arg)
+{
+ mips_initializing = 0;
+}
+
+static void
+mips_exit_cleanups (PTR arg)
+{
+ mips_exiting = 0;
+}
+
+static void
+mips_send_command (const char *cmd, int prompt)
+{
+ serial_write (mips_desc, cmd, strlen (cmd));
+ mips_expect (cmd);
+ mips_expect ("\n");
+ if (prompt)
+ mips_expect (mips_monitor_prompt);
+}
+
+/* Enter remote (dbx) debug mode: */
+static void
+mips_enter_debug (void)
+{
+ /* Reset the sequence numbers, ready for the new debug sequence: */
+ mips_send_seq = 0;
+ mips_receive_seq = 0;
+
+ if (mips_monitor != MON_IDT)
+ mips_send_command ("debug\r", 0);
+ else /* assume IDT monitor by default */
+ mips_send_command ("db tty0\r", 0);
+
+ sleep (1);
+ serial_write (mips_desc, "\r", sizeof "\r" - 1);
+
+ /* We don't need to absorb any spurious characters here, since the
+ mips_receive_header will eat up a reasonable number of characters
+ whilst looking for the SYN, however this avoids the "garbage"
+ being displayed to the user. */
+ if (mips_monitor != MON_IDT)
+ mips_expect ("\r");
+
+ {
+ char buff[DATA_MAXLEN + 1];
+ if (mips_receive_packet (buff, 1, 3) < 0)
+ mips_error ("Failed to initialize (didn't receive packet).");
+ }
+}
+
+/* Exit remote (dbx) debug mode, returning to the monitor prompt: */
+static int
+mips_exit_debug (void)
+{
+ int err;
+ struct cleanup *old_cleanups = make_cleanup (mips_exit_cleanups, NULL);
+
+ mips_exiting = 1;
+
+ if (mips_monitor != MON_IDT)
+ {
+ /* The DDB (NEC) and MiniRISC (LSI) versions of PMON exit immediately,
+ so we do not get a reply to this command: */
+ mips_request ('x', 0, 0, NULL, mips_receive_wait, NULL);
+ mips_need_reply = 0;
+ if (!mips_expect (" break!"))
+ return -1;
+ }
+ else
+ mips_request ('x', 0, 0, &err, mips_receive_wait, NULL);
+
+ if (!mips_expect (mips_monitor_prompt))
+ return -1;
+
+ do_cleanups (old_cleanups);
+
+ return 0;
+}
+
+/* Initialize a new connection to the MIPS board, and make sure we are
+ really connected. */
+
+static void
+mips_initialize (void)
+{
+ int err;
+ struct cleanup *old_cleanups = make_cleanup (mips_initialize_cleanups, NULL);
+ int j;
+
+ /* What is this code doing here? I don't see any way it can happen, and
+ it might mean mips_initializing didn't get cleared properly.
+ So I'll make it a warning. */
+
+ if (mips_initializing)
+ {
+ warning ("internal error: mips_initialize called twice");
+ return;
+ }
+
+ mips_wait_flag = 0;
+ mips_initializing = 1;
+
+ /* At this point, the packit protocol isn't responding. We'll try getting
+ into the monitor, and restarting the protocol. */
+
+ /* Force the system into the monitor. After this we *should* be at
+ the mips_monitor_prompt. */
+ if (mips_monitor != MON_IDT)
+ j = 0; /* start by checking if we are already at the prompt */
+ else
+ j = 1; /* start by sending a break */
+ for (; j <= 4; j++)
+ {
+ switch (j)
+ {
+ case 0: /* First, try sending a CR */
+ serial_flush_input (mips_desc);
+ serial_write (mips_desc, "\r", 1);
+ break;
+ case 1: /* First, try sending a break */
+ serial_send_break (mips_desc);
+ break;
+ case 2: /* Then, try a ^C */
+ serial_write (mips_desc, "\003", 1);
+ break;
+ case 3: /* Then, try escaping from download */
+ {
+ if (mips_monitor != MON_IDT)
+ {
+ char tbuff[7];
+
+ /* We shouldn't need to send multiple termination
+ sequences, since the target performs line (or
+ block) reads, and then processes those
+ packets. In-case we were downloading a large packet
+ we flush the output buffer before inserting a
+ termination sequence. */
+ serial_flush_output (mips_desc);
+ sprintf (tbuff, "\r/E/E\r");
+ serial_write (mips_desc, tbuff, 6);
+ }
+ else
+ {
+ char srec[10];
+ int i;
+
+ /* We are possibly in binary download mode, having
+ aborted in the middle of an S-record. ^C won't
+ work because of binary mode. The only reliable way
+ out is to send enough termination packets (8 bytes)
+ to fill up and then overflow the largest size
+ S-record (255 bytes in this case). This amounts to
+ 256/8 + 1 packets.
+ */
+
+ mips_make_srec (srec, '7', 0, NULL, 0);
+
+ for (i = 1; i <= 33; i++)
+ {
+ serial_write (mips_desc, srec, 8);
+
+ if (serial_readchar (mips_desc, 0) >= 0)
+ break; /* Break immediatly if we get something from
+ the board. */
+ }
+ }
+ }
+ break;
+ case 4:
+ mips_error ("Failed to initialize.");
+ }
+
+ if (mips_expect (mips_monitor_prompt))
+ break;
+ }
+
+ if (mips_monitor != MON_IDT)
+ {
+ /* Sometimes PMON ignores the first few characters in the first
+ command sent after a load. Sending a blank command gets
+ around that. */
+ mips_send_command ("\r", -1);
+
+ /* Ensure the correct target state: */
+ if (mips_monitor != MON_LSI)
+ mips_send_command ("set regsize 64\r", -1);
+ mips_send_command ("set hostport tty0\r", -1);
+ mips_send_command ("set brkcmd \"\"\r", -1);
+ /* Delete all the current breakpoints: */
+ mips_send_command ("db *\r", -1);
+ /* NOTE: PMON does not have breakpoint support through the
+ "debug" mode, only at the monitor command-line. */
+ }
+
+ mips_enter_debug ();
+
+ /* Clear all breakpoints: */
+ if ((mips_monitor == MON_IDT
+ && clear_breakpoint (-1, 0, BREAK_UNUSED) == 0)
+ || mips_monitor == MON_LSI)
+ monitor_supports_breakpoints = 1;
+ else
+ monitor_supports_breakpoints = 0;
+
+ do_cleanups (old_cleanups);
+
+ /* If this doesn't call error, we have connected; we don't care if
+ the request itself succeeds or fails. */
+
+ mips_request ('r', 0, 0, &err, mips_receive_wait, NULL);
+ set_current_frame (create_new_frame (read_fp (), read_pc ()));
+ select_frame (get_current_frame ());
+}
+
+/* Open a connection to the remote board. */
+static void
+common_open (struct target_ops *ops, char *name, int from_tty,
+ enum mips_monitor_type new_monitor,
+ const char *new_monitor_prompt)
+{
+ char *ptype;
+ char *serial_port_name;
+ char *remote_name = 0;
+ char *local_name = 0;
+ char **argv;
+
+ if (name == 0)
+ error (
+ "To open a MIPS remote debugging connection, you need to specify what serial\n\
+device is attached to the target board (e.g., /dev/ttya).\n"
+ "If you want to use TFTP to download to the board, specify the name of a\n"
+ "temporary file to be used by GDB for downloads as the second argument.\n"
+ "This filename must be in the form host:filename, where host is the name\n"
+ "of the host running the TFTP server, and the file must be readable by the\n"
+ "world. If the local name of the temporary file differs from the name as\n"
+ "seen from the board via TFTP, specify that name as the third parameter.\n");
+
+ /* Parse the serial port name, the optional TFTP name, and the
+ optional local TFTP name. */
+ if ((argv = buildargv (name)) == NULL)
+ nomem (0);
+ make_cleanup_freeargv (argv);
+
+ serial_port_name = xstrdup (argv[0]);
+ if (argv[1]) /* remote TFTP name specified? */
+ {
+ remote_name = argv[1];
+ if (argv[2]) /* local TFTP filename specified? */
+ local_name = argv[2];
+ }
+
+ target_preopen (from_tty);
+
+ if (mips_is_open)
+ unpush_target (current_ops);
+
+ /* Open and initialize the serial port. */
+ mips_desc = serial_open (serial_port_name);
+ if (mips_desc == NULL)
+ perror_with_name (serial_port_name);
+
+ if (baud_rate != -1)
+ {
+ if (serial_setbaudrate (mips_desc, baud_rate))
+ {
+ serial_close (mips_desc);
+ perror_with_name (serial_port_name);
+ }
+ }
+
+ serial_raw (mips_desc);
+
+ /* Open and initialize the optional download port. If it is in the form
+ hostname#portnumber, it's a UDP socket. If it is in the form
+ hostname:filename, assume it's the TFTP filename that must be
+ passed to the DDB board to tell it where to get the load file. */
+ if (remote_name)
+ {
+ if (strchr (remote_name, '#'))
+ {
+ udp_desc = serial_open (remote_name);
+ if (!udp_desc)
+ perror_with_name ("Unable to open UDP port");
+ udp_in_use = 1;
+ }
+ else
+ {
+ /* Save the remote and local names of the TFTP temp file. If
+ the user didn't specify a local name, assume it's the same
+ as the part of the remote name after the "host:". */
+ if (tftp_name)
+ xfree (tftp_name);
+ if (tftp_localname)
+ xfree (tftp_localname);
+ if (local_name == NULL)
+ if ((local_name = strchr (remote_name, ':')) != NULL)
+ local_name++; /* skip over the colon */
+ if (local_name == NULL)
+ local_name = remote_name; /* local name same as remote name */
+ tftp_name = xstrdup (remote_name);
+ tftp_localname = xstrdup (local_name);
+ tftp_in_use = 1;
+ }
+ }
+
+ current_ops = ops;
+ mips_is_open = 1;
+
+ /* Reset the expected monitor prompt if it's never been set before. */
+ if (mips_monitor_prompt == NULL)
+ mips_monitor_prompt = xstrdup (new_monitor_prompt);
+ mips_monitor = new_monitor;
+
+ mips_initialize ();
+
+ if (from_tty)
+ printf_unfiltered ("Remote MIPS debugging using %s\n", serial_port_name);
+
+ /* Switch to using remote target now. */
+ push_target (ops);
+
+ /* FIXME: Should we call start_remote here? */
+
+ /* Try to figure out the processor model if possible. */
+ ptype = mips_read_processor_type ();
+ if (ptype)
+ mips_set_processor_type_command (xstrdup (ptype), 0);
+
+/* This is really the job of start_remote however, that makes an assumption
+ that the target is about to print out a status message of some sort. That
+ doesn't happen here (in fact, it may not be possible to get the monitor to
+ send the appropriate packet). */
+
+ flush_cached_frames ();
+ registers_changed ();
+ stop_pc = read_pc ();
+ set_current_frame (create_new_frame (read_fp (), stop_pc));
+ select_frame (get_current_frame ());
+ print_stack_frame (selected_frame, -1, 1);
+ xfree (serial_port_name);
+}
+
+static void
+mips_open (char *name, int from_tty)
+{
+ const char *monitor_prompt = NULL;
+ if (TARGET_ARCHITECTURE != NULL
+ && TARGET_ARCHITECTURE->arch == bfd_arch_mips)
+ {
+ switch (TARGET_ARCHITECTURE->mach)
+ {
+ case bfd_mach_mips4100:
+ case bfd_mach_mips4300:
+ case bfd_mach_mips4600:
+ case bfd_mach_mips4650:
+ case bfd_mach_mips5000:
+ monitor_prompt = "<RISQ> ";
+ break;
+ }
+ }
+ if (monitor_prompt == NULL)
+ monitor_prompt = "<IDT>";
+ common_open (&mips_ops, name, from_tty, MON_IDT, monitor_prompt);
+}
+
+static void
+pmon_open (char *name, int from_tty)
+{
+ common_open (&pmon_ops, name, from_tty, MON_PMON, "PMON> ");
+}
+
+static void
+ddb_open (char *name, int from_tty)
+{
+ common_open (&ddb_ops, name, from_tty, MON_DDB, "NEC010>");
+}
+
+static void
+lsi_open (char *name, int from_tty)
+{
+ int i;
+
+ /* Clear the LSI breakpoint table. */
+ for (i = 0; i < MAX_LSI_BREAKPOINTS; i++)
+ lsi_breakpoints[i].type = BREAK_UNUSED;
+
+ common_open (&lsi_ops, name, from_tty, MON_LSI, "PMON> ");
+}
+
+/* Close a connection to the remote board. */
+
+static void
+mips_close (int quitting)
+{
+ if (mips_is_open)
+ {
+ /* Get the board out of remote debugging mode. */
+ (void) mips_exit_debug ();
+
+ close_ports ();
+ }
+}
+
+/* Detach from the remote board. */
+
+static void
+mips_detach (char *args, int from_tty)
+{
+ if (args)
+ error ("Argument given to \"detach\" when remotely debugging.");
+
+ pop_target ();
+
+ mips_close (1);
+
+ if (from_tty)
+ printf_unfiltered ("Ending remote MIPS debugging.\n");
+}
+
+/* Tell the target board to resume. This does not wait for a reply
+ from the board, except in the case of single-stepping on LSI boards,
+ where PMON does return a reply. */
+
+static void
+mips_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ int err;
+
+ /* LSI PMON requires returns a reply packet "0x1 s 0x0 0x57f" after
+ a single step, so we wait for that. */
+ mips_request (step ? 's' : 'c', 1, siggnal,
+ mips_monitor == MON_LSI && step ? &err : (int *) NULL,
+ mips_receive_wait, NULL);
+}
+
+/* Return the signal corresponding to SIG, where SIG is the number which
+ the MIPS protocol uses for the signal. */
+enum target_signal
+mips_signal_from_protocol (int sig)
+{
+ /* We allow a few more signals than the IDT board actually returns, on
+ the theory that there is at least *some* hope that perhaps the numbering
+ for these signals is widely agreed upon. */
+ if (sig <= 0
+ || sig > 31)
+ return TARGET_SIGNAL_UNKNOWN;
+
+ /* Don't want to use target_signal_from_host because we are converting
+ from MIPS signal numbers, not host ones. Our internal numbers
+ match the MIPS numbers for the signals the board can return, which
+ are: SIGINT, SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP. */
+ return (enum target_signal) sig;
+}
+
+/* Wait until the remote stops, and return a wait status. */
+
+static ptid_t
+mips_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ int rstatus;
+ int err;
+ char buff[DATA_MAXLEN];
+ int rpc, rfp, rsp;
+ char flags[20];
+ int nfields;
+ int i;
+
+ interrupt_count = 0;
+ hit_watchpoint = 0;
+
+ /* If we have not sent a single step or continue command, then the
+ board is waiting for us to do something. Return a status
+ indicating that it is stopped. */
+ if (!mips_need_reply)
+ {
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ return inferior_ptid;
+ }
+
+ /* No timeout; we sit here as long as the program continues to execute. */
+ mips_wait_flag = 1;
+ rstatus = mips_request ('\000', 0, 0, &err, -1, buff);
+ mips_wait_flag = 0;
+ if (err)
+ mips_error ("Remote failure: %s", safe_strerror (errno));
+
+ /* On returning from a continue, the PMON monitor seems to start
+ echoing back the messages we send prior to sending back the
+ ACK. The code can cope with this, but to try and avoid the
+ unnecessary serial traffic, and "spurious" characters displayed
+ to the user, we cheat and reset the debug protocol. The problems
+ seems to be caused by a check on the number of arguments, and the
+ command length, within the monitor causing it to echo the command
+ as a bad packet. */
+ if (mips_monitor == MON_PMON)
+ {
+ mips_exit_debug ();
+ mips_enter_debug ();
+ }
+
+ /* See if we got back extended status. If so, pick out the pc, fp, sp, etc... */
+
+ nfields = sscanf (buff, "0x%*x %*c 0x%*x 0x%*x 0x%x 0x%x 0x%x 0x%*x %s",
+ &rpc, &rfp, &rsp, flags);
+ if (nfields >= 3)
+ {
+ char buf[MAX_REGISTER_RAW_SIZE];
+
+ store_unsigned_integer (buf, REGISTER_RAW_SIZE (PC_REGNUM), rpc);
+ supply_register (PC_REGNUM, buf);
+
+ store_unsigned_integer (buf, REGISTER_RAW_SIZE (PC_REGNUM), rfp);
+ supply_register (30, buf); /* This register they are avoiding and so it is unnamed */
+
+ store_unsigned_integer (buf, REGISTER_RAW_SIZE (SP_REGNUM), rsp);
+ supply_register (SP_REGNUM, buf);
+
+ store_unsigned_integer (buf, REGISTER_RAW_SIZE (FP_REGNUM), 0);
+ supply_register (FP_REGNUM, buf);
+
+ if (nfields == 9)
+ {
+ int i;
+
+ for (i = 0; i <= 2; i++)
+ if (flags[i] == 'r' || flags[i] == 'w')
+ hit_watchpoint = 1;
+ else if (flags[i] == '\000')
+ break;
+ }
+ }
+
+ if (strcmp (target_shortname, "lsi") == 0)
+ {
+#if 0
+ /* If this is an LSI PMON target, see if we just hit a hardrdware watchpoint.
+ Right now, PMON doesn't give us enough information to determine which
+ breakpoint we hit. So we have to look up the PC in our own table
+ of breakpoints, and if found, assume it's just a normal instruction
+ fetch breakpoint, not a data watchpoint. FIXME when PMON
+ provides some way to tell us what type of breakpoint it is. */
+ int i;
+ CORE_ADDR pc = read_pc ();
+
+ hit_watchpoint = 1;
+ for (i = 0; i < MAX_LSI_BREAKPOINTS; i++)
+ {
+ if (lsi_breakpoints[i].addr == pc
+ && lsi_breakpoints[i].type == BREAK_FETCH)
+ {
+ hit_watchpoint = 0;
+ break;
+ }
+ }
+#else
+ /* If a data breakpoint was hit, PMON returns the following packet:
+ 0x1 c 0x0 0x57f 0x1
+ The return packet from an ordinary breakpoint doesn't have the
+ extra 0x01 field tacked onto the end. */
+ if (nfields == 1 && rpc == 1)
+ hit_watchpoint = 1;
+#endif
+ }
+
+ /* NOTE: The following (sig) numbers are defined by PMON:
+ SPP_SIGTRAP 5 breakpoint
+ SPP_SIGINT 2
+ SPP_SIGSEGV 11
+ SPP_SIGBUS 10
+ SPP_SIGILL 4
+ SPP_SIGFPE 8
+ SPP_SIGTERM 15 */
+
+ /* Translate a MIPS waitstatus. We use constants here rather than WTERMSIG
+ and so on, because the constants we want here are determined by the
+ MIPS protocol and have nothing to do with what host we are running on. */
+ if ((rstatus & 0xff) == 0)
+ {
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = (((rstatus) >> 8) & 0xff);
+ }
+ else if ((rstatus & 0xff) == 0x7f)
+ {
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = mips_signal_from_protocol (((rstatus) >> 8) & 0xff);
+
+ /* If the stop PC is in the _exit function, assume
+ we hit the 'break 0x3ff' instruction in _exit, so this
+ is not a normal breakpoint. */
+ if (strcmp (target_shortname, "lsi") == 0)
+ {
+ char *func_name;
+ CORE_ADDR func_start;
+ CORE_ADDR pc = read_pc ();
+
+ find_pc_partial_function (pc, &func_name, &func_start, NULL);
+ if (func_name != NULL && strcmp (func_name, "_exit") == 0
+ && func_start == pc)
+ status->kind = TARGET_WAITKIND_EXITED;
+ }
+ }
+ else
+ {
+ status->kind = TARGET_WAITKIND_SIGNALLED;
+ status->value.sig = mips_signal_from_protocol (rstatus & 0x7f);
+ }
+
+ return inferior_ptid;
+}
+
+/* We have to map between the register numbers used by gdb and the
+ register numbers used by the debugging protocol. This function
+ assumes that we are using tm-mips.h. */
+
+#define REGNO_OFFSET 96
+
+static int
+mips_map_regno (int regno)
+{
+ if (regno < 32)
+ return regno;
+ if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
+ return regno - FP0_REGNUM + 32;
+ switch (regno)
+ {
+ case PC_REGNUM:
+ return REGNO_OFFSET + 0;
+ case CAUSE_REGNUM:
+ return REGNO_OFFSET + 1;
+ case HI_REGNUM:
+ return REGNO_OFFSET + 2;
+ case LO_REGNUM:
+ return REGNO_OFFSET + 3;
+ case FCRCS_REGNUM:
+ return REGNO_OFFSET + 4;
+ case FCRIR_REGNUM:
+ return REGNO_OFFSET + 5;
+ default:
+ /* FIXME: Is there a way to get the status register? */
+ return 0;
+ }
+}
+
+/* Fetch the remote registers. */
+
+static void
+mips_fetch_registers (int regno)
+{
+ unsigned LONGEST val;
+ int err;
+
+ if (regno == -1)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ mips_fetch_registers (regno);
+ return;
+ }
+
+ if (regno == FP_REGNUM || regno == ZERO_REGNUM)
+ /* FP_REGNUM on the mips is a hack which is just supposed to read
+ zero (see also mips-nat.c). */
+ val = 0;
+ else
+ {
+ /* If PMON doesn't support this register, don't waste serial
+ bandwidth trying to read it. */
+ int pmon_reg = mips_map_regno (regno);
+ if (regno != 0 && pmon_reg == 0)
+ val = 0;
+ else
+ {
+ /* Unfortunately the PMON version in the Vr4300 board has been
+ compiled without the 64bit register access commands. This
+ means we cannot get hold of the full register width. */
+ if (mips_monitor == MON_DDB)
+ val = (unsigned) mips_request ('t', pmon_reg, 0,
+ &err, mips_receive_wait, NULL);
+ else
+ val = mips_request ('r', pmon_reg, 0,
+ &err, mips_receive_wait, NULL);
+ if (err)
+ mips_error ("Can't read register %d: %s", regno,
+ safe_strerror (errno));
+ }
+ }
+
+ {
+ char buf[MAX_REGISTER_RAW_SIZE];
+
+ /* We got the number the register holds, but gdb expects to see a
+ value in the target byte ordering. */
+ store_unsigned_integer (buf, REGISTER_RAW_SIZE (regno), val);
+ supply_register (regno, buf);
+ }
+}
+
+/* Prepare to store registers. The MIPS protocol can store individual
+ registers, so this function doesn't have to do anything. */
+
+static void
+mips_prepare_to_store (void)
+{
+}
+
+/* Store remote register(s). */
+
+static void
+mips_store_registers (int regno)
+{
+ int err;
+
+ if (regno == -1)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ mips_store_registers (regno);
+ return;
+ }
+
+ mips_request ('R', mips_map_regno (regno),
+ read_register (regno),
+ &err, mips_receive_wait, NULL);
+ if (err)
+ mips_error ("Can't write register %d: %s", regno, safe_strerror (errno));
+}
+
+/* Fetch a word from the target board. */
+
+static unsigned int
+mips_fetch_word (CORE_ADDR addr)
+{
+ unsigned int val;
+ int err;
+
+ val = mips_request ('d', addr, 0, &err, mips_receive_wait, NULL);
+ if (err)
+ {
+ /* Data space failed; try instruction space. */
+ val = mips_request ('i', addr, 0, &err,
+ mips_receive_wait, NULL);
+ if (err)
+ mips_error ("Can't read address 0x%s: %s",
+ paddr_nz (addr), safe_strerror (errno));
+ }
+ return val;
+}
+
+/* Store a word to the target board. Returns errno code or zero for
+ success. If OLD_CONTENTS is non-NULL, put the old contents of that
+ memory location there. */
+
+/* FIXME! make sure only 32-bit quantities get stored! */
+static int
+mips_store_word (CORE_ADDR addr, unsigned int val, char *old_contents)
+{
+ int err;
+ unsigned int oldcontents;
+
+ oldcontents = mips_request ('D', addr, val, &err,
+ mips_receive_wait, NULL);
+ if (err)
+ {
+ /* Data space failed; try instruction space. */
+ oldcontents = mips_request ('I', addr, val, &err,
+ mips_receive_wait, NULL);
+ if (err)
+ return errno;
+ }
+ if (old_contents != NULL)
+ store_unsigned_integer (old_contents, 4, oldcontents);
+ return 0;
+}
+
+/* Read or write LEN bytes from inferior memory at MEMADDR,
+ transferring to or from debugger address MYADDR. Write to inferior
+ if SHOULD_WRITE is nonzero. Returns length of data written or
+ read; 0 for error. Note that protocol gives us the correct value
+ for a longword, since it transfers values in ASCII. We want the
+ byte values, so we have to swap the longword values. */
+
+static int mask_address_p = 1;
+
+static int
+mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib, struct target_ops *target)
+{
+ int i;
+ CORE_ADDR addr;
+ int count;
+ char *buffer;
+ int status;
+
+ /* PMON targets do not cope well with 64 bit addresses. Mask the
+ value down to 32 bits. */
+ if (mask_address_p)
+ memaddr &= (CORE_ADDR) 0xffffffff;
+
+ /* Round starting address down to longword boundary. */
+ addr = memaddr & ~3;
+ /* Round ending address up; get number of longwords that makes. */
+ count = (((memaddr + len) - addr) + 3) / 4;
+ /* Allocate buffer of that many longwords. */
+ buffer = alloca (count * 4);
+
+ if (write)
+ {
+ /* Fill start and end extra bytes of buffer with existing data. */
+ if (addr != memaddr || len < 4)
+ {
+ /* Need part of initial word -- fetch it. */
+ store_unsigned_integer (&buffer[0], 4, mips_fetch_word (addr));
+ }
+
+ if (count > 1)
+ {
+ /* Need part of last word -- fetch it. FIXME: we do this even
+ if we don't need it. */
+ store_unsigned_integer (&buffer[(count - 1) * 4], 4,
+ mips_fetch_word (addr + (count - 1) * 4));
+ }
+
+ /* Copy data to be written over corresponding part of buffer */
+
+ memcpy ((char *) buffer + (memaddr & 3), myaddr, len);
+
+ /* Write the entire buffer. */
+
+ for (i = 0; i < count; i++, addr += 4)
+ {
+ status = mips_store_word (addr,
+ extract_unsigned_integer (&buffer[i * 4], 4),
+ NULL);
+ /* Report each kilobyte (we download 32-bit words at a time) */
+ if (i % 256 == 255)
+ {
+ printf_unfiltered ("*");
+ gdb_flush (gdb_stdout);
+ }
+ if (status)
+ {
+ errno = status;
+ return 0;
+ }
+ /* FIXME: Do we want a QUIT here? */
+ }
+ if (count >= 256)
+ printf_unfiltered ("\n");
+ }
+ else
+ {
+ /* Read all the longwords */
+ for (i = 0; i < count; i++, addr += 4)
+ {
+ store_unsigned_integer (&buffer[i * 4], 4, mips_fetch_word (addr));
+ QUIT;
+ }
+
+ /* Copy appropriate bytes out of the buffer. */
+ memcpy (myaddr, buffer + (memaddr & 3), len);
+ }
+ return len;
+}
+
+/* Print info on this target. */
+
+static void
+mips_files_info (struct target_ops *ignore)
+{
+ printf_unfiltered ("Debugging a MIPS board over a serial line.\n");
+}
+
+/* Kill the process running on the board. This will actually only
+ work if we are doing remote debugging over the console input. I
+ think that if IDT/sim had the remote debug interrupt enabled on the
+ right port, we could interrupt the process with a break signal. */
+
+static void
+mips_kill (void)
+{
+ if (!mips_wait_flag)
+ return;
+
+ interrupt_count++;
+
+ if (interrupt_count >= 2)
+ {
+ interrupt_count = 0;
+
+ target_terminal_ours ();
+
+ if (query ("Interrupted while waiting for the program.\n\
+Give up (and stop debugging it)? "))
+ {
+ /* Clean up in such a way that mips_close won't try to talk to the
+ board (it almost surely won't work since we weren't able to talk to
+ it). */
+ mips_wait_flag = 0;
+ close_ports ();
+
+ printf_unfiltered ("Ending remote MIPS debugging.\n");
+ target_mourn_inferior ();
+
+ throw_exception (RETURN_QUIT);
+ }
+
+ target_terminal_inferior ();
+ }
+
+ if (remote_debug > 0)
+ printf_unfiltered ("Sending break\n");
+
+ serial_send_break (mips_desc);
+
+#if 0
+ if (mips_is_open)
+ {
+ char cc;
+
+ /* Send a ^C. */
+ cc = '\003';
+ serial_write (mips_desc, &cc, 1);
+ sleep (1);
+ target_mourn_inferior ();
+ }
+#endif
+}
+
+/* Start running on the target board. */
+
+static void
+mips_create_inferior (char *execfile, char *args, char **env)
+{
+ CORE_ADDR entry_pt;
+
+ if (args && *args)
+ {
+ warning ("\
+Can't pass arguments to remote MIPS board; arguments ignored.");
+ /* And don't try to use them on the next "run" command. */
+ execute_command ("set args", 0);
+ }
+
+ if (execfile == 0 || exec_bfd == 0)
+ error ("No executable file specified");
+
+ entry_pt = (CORE_ADDR) bfd_get_start_address (exec_bfd);
+
+ init_wait_for_inferior ();
+
+ /* FIXME: Should we set inferior_ptid here? */
+
+ proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
+}
+
+/* Clean up after a process. Actually nothing to do. */
+
+static void
+mips_mourn_inferior (void)
+{
+ if (current_ops != NULL)
+ unpush_target (current_ops);
+ generic_mourn_inferior ();
+}
+
+/* We can write a breakpoint and read the shadow contents in one
+ operation. */
+
+/* Insert a breakpoint. On targets that don't have built-in breakpoint
+ support, we read the contents of the target location and stash it,
+ then overwrite it with a breakpoint instruction. ADDR is the target
+ location in the target machine. CONTENTS_CACHE is a pointer to
+ memory allocated for saving the target contents. It is guaranteed
+ by the caller to be long enough to save sizeof BREAKPOINT bytes (this
+ is accomplished via BREAKPOINT_MAX). */
+
+static int
+mips_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ if (monitor_supports_breakpoints)
+ return set_breakpoint (addr, MIPS_INSTLEN, BREAK_FETCH);
+ else
+ return memory_insert_breakpoint (addr, contents_cache);
+}
+
+static int
+mips_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ if (monitor_supports_breakpoints)
+ return clear_breakpoint (addr, MIPS_INSTLEN, BREAK_FETCH);
+ else
+ return memory_remove_breakpoint (addr, contents_cache);
+}
+
+#if 0 /* currently not used */
+/* PMON does not currently provide support for the debug mode 'b'
+ commands to manipulate breakpoints. However, if we wanted to use
+ the monitor breakpoints (rather than the GDB BREAK_INSN version)
+ then this code performs the work needed to leave debug mode,
+ set/clear the breakpoint, and then return to debug mode. */
+
+#define PMON_MAX_BP (33) /* 32 SW, 1 HW */
+static CORE_ADDR mips_pmon_bp_info[PMON_MAX_BP];
+/* NOTE: The code relies on this vector being zero-initialised by the system */
+
+static int
+pmon_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ int status;
+
+ if (monitor_supports_breakpoints)
+ {
+ char tbuff[12]; /* space for breakpoint command */
+ int bpnum;
+ CORE_ADDR bpaddr;
+
+ /* PMON does not support debug level breakpoint set/remove: */
+ if (mips_exit_debug ())
+ mips_error ("Failed to exit debug mode");
+
+ sprintf (tbuff, "b %08x\r", addr);
+ mips_send_command (tbuff, 0);
+
+ mips_expect ("Bpt ");
+
+ if (!mips_getstring (tbuff, remote_timeout))
+ return 1;
+ tbuff[2] = '\0'; /* terminate the string */
+ if (sscanf (tbuff, "%d", &bpnum) != 1)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "Invalid decimal breakpoint number from target: %s\n", tbuff);
+ return 1;
+ }
+
+ mips_expect (" = ");
+
+ /* Lead in the hex number we are expecting: */
+ tbuff[0] = '0';
+ tbuff[1] = 'x';
+
+ /* FIXME!! only 8 bytes! need to expand for Bfd64;
+ which targets return 64-bit addresses? PMON returns only 32! */
+ if (!mips_getstring (&tbuff[2], 8))
+ return 1;
+ tbuff[10] = '\0'; /* terminate the string */
+
+ if (sscanf (tbuff, "0x%08x", &bpaddr) != 1)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "Invalid hex address from target: %s\n", tbuff);
+ return 1;
+ }
+
+ if (bpnum >= PMON_MAX_BP)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "Error: Returned breakpoint number %d outside acceptable range (0..%d)\n",
+ bpnum, PMON_MAX_BP - 1);
+ return 1;
+ }
+
+ if (bpaddr != addr)
+ fprintf_unfiltered (gdb_stderr, "Warning: Breakpoint addresses do not match: 0x%x != 0x%x\n", addr, bpaddr);
+
+ mips_pmon_bp_info[bpnum] = bpaddr;
+
+ mips_expect ("\r\n");
+ mips_expect (mips_monitor_prompt);
+
+ mips_enter_debug ();
+
+ return 0;
+ }
+
+ return mips_store_word (addr, BREAK_INSN, contents_cache);
+}
+
+static int
+pmon_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ if (monitor_supports_breakpoints)
+ {
+ int bpnum;
+ char tbuff[7]; /* enough for delete breakpoint command */
+
+ for (bpnum = 0; bpnum < PMON_MAX_BP; bpnum++)
+ if (mips_pmon_bp_info[bpnum] == addr)
+ break;
+
+ if (bpnum >= PMON_MAX_BP)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "pmon_remove_breakpoint: Failed to find breakpoint at address 0x%s\n",
+ paddr_nz (addr));
+ return 1;
+ }
+
+ if (mips_exit_debug ())
+ mips_error ("Failed to exit debug mode");
+
+ sprintf (tbuff, "db %02d\r", bpnum);
+
+ mips_send_command (tbuff, -1);
+ /* NOTE: If the breakpoint does not exist then a "Bpt <dd> not
+ set" message will be returned. */
+
+ mips_enter_debug ();
+
+ return 0;
+ }
+
+ return target_write_memory (addr, contents_cache, BREAK_INSN_SIZE);
+}
+#endif
+
+
+/* Tell whether this target can support a hardware breakpoint. CNT
+ is the number of hardware breakpoints already installed. This
+ implements the TARGET_CAN_USE_HARDWARE_WATCHPOINT macro. */
+
+int
+remote_mips_can_use_hardware_watchpoint (int cnt)
+{
+ return cnt < MAX_LSI_BREAKPOINTS && strcmp (target_shortname, "lsi") == 0;
+}
+
+
+/* Compute a don't care mask for the region bounding ADDR and ADDR + LEN - 1.
+ This is used for memory ref breakpoints. */
+
+static unsigned long
+calculate_mask (CORE_ADDR addr, int len)
+{
+ unsigned long mask;
+ int i;
+
+ mask = addr ^ (addr + len - 1);
+
+ for (i = 32; i >= 0; i--)
+ if (mask == 0)
+ break;
+ else
+ mask >>= 1;
+
+ mask = (unsigned long) 0xffffffff >> i;
+
+ return mask;
+}
+
+
+/* Insert a hardware breakpoint. This works only on LSI targets, which
+ implement ordinary breakpoints using hardware facilities. */
+
+int
+remote_mips_insert_hw_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ if (strcmp (target_shortname, "lsi") == 0)
+ return mips_insert_breakpoint (addr, contents_cache);
+ else
+ return -1;
+}
+
+
+/* Remove a hardware breakpoint. This works only on LSI targets, which
+ implement ordinary breakpoints using hardware facilities. */
+
+int
+remote_mips_remove_hw_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ if (strcmp (target_shortname, "lsi") == 0)
+ return mips_remove_breakpoint (addr, contents_cache);
+ else
+ return -1;
+}
+
+/* Set a data watchpoint. ADDR and LEN should be obvious. TYPE is 0
+ for a write watchpoint, 1 for a read watchpoint, or 2 for a read/write
+ watchpoint. */
+
+int
+remote_mips_set_watchpoint (CORE_ADDR addr, int len, int type)
+{
+ if (set_breakpoint (addr, len, type))
+ return -1;
+
+ return 0;
+}
+
+int
+remote_mips_remove_watchpoint (CORE_ADDR addr, int len, int type)
+{
+ if (clear_breakpoint (addr, len, type))
+ return -1;
+
+ return 0;
+}
+
+int
+remote_mips_stopped_by_watchpoint (void)
+{
+ return hit_watchpoint;
+}
+
+
+/* Insert a breakpoint. */
+
+static int
+set_breakpoint (CORE_ADDR addr, int len, enum break_type type)
+{
+ return common_breakpoint (1, addr, len, type);
+}
+
+
+/* Clear a breakpoint. */
+
+static int
+clear_breakpoint (CORE_ADDR addr, int len, enum break_type type)
+{
+ return common_breakpoint (0, addr, len, type);
+}
+
+
+/* Check the error code from the return packet for an LSI breakpoint
+ command. If there's no error, just return 0. If it's a warning,
+ print the warning text and return 0. If it's an error, print
+ the error text and return 1. <ADDR> is the address of the breakpoint
+ that was being set. <RERRFLG> is the error code returned by PMON.
+ This is a helper function for common_breakpoint. */
+
+static int
+check_lsi_error (CORE_ADDR addr, int rerrflg)
+{
+ struct lsi_error *err;
+ char *saddr = paddr_nz (addr); /* printable address string */
+
+ if (rerrflg == 0) /* no error */
+ return 0;
+
+ /* Warnings can be ORed together, so check them all. */
+ if (rerrflg & W_WARN)
+ {
+ if (monitor_warnings)
+ {
+ int found = 0;
+ for (err = lsi_warning_table; err->code != 0; err++)
+ {
+ if ((err->code & rerrflg) == err->code)
+ {
+ found = 1;
+ fprintf_unfiltered (gdb_stderr,
+ "common_breakpoint (0x%s): Warning: %s\n",
+ saddr,
+ err->string);
+ }
+ }
+ if (!found)
+ fprintf_unfiltered (gdb_stderr,
+ "common_breakpoint (0x%s): Unknown warning: 0x%x\n",
+ saddr,
+ rerrflg);
+ }
+ return 0;
+ }
+
+ /* Errors are unique, i.e. can't be ORed together. */
+ for (err = lsi_error_table; err->code != 0; err++)
+ {
+ if ((err->code & rerrflg) == err->code)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "common_breakpoint (0x%s): Error: %s\n",
+ saddr,
+ err->string);
+ return 1;
+ }
+ }
+ fprintf_unfiltered (gdb_stderr,
+ "common_breakpoint (0x%s): Unknown error: 0x%x\n",
+ saddr,
+ rerrflg);
+ return 1;
+}
+
+
+/* This routine sends a breakpoint command to the remote target.
+
+ <SET> is 1 if setting a breakpoint, or 0 if clearing a breakpoint.
+ <ADDR> is the address of the breakpoint.
+ <LEN> the length of the region to break on.
+ <TYPE> is the type of breakpoint:
+ 0 = write (BREAK_WRITE)
+ 1 = read (BREAK_READ)
+ 2 = read/write (BREAK_ACCESS)
+ 3 = instruction fetch (BREAK_FETCH)
+
+ Return 0 if successful; otherwise 1. */
+
+static int
+common_breakpoint (int set, CORE_ADDR addr, int len, enum break_type type)
+{
+ char buf[DATA_MAXLEN + 1];
+ char cmd, rcmd;
+ int rpid, rerrflg, rresponse, rlen;
+ int nfields;
+
+ addr = ADDR_BITS_REMOVE (addr);
+
+ if (mips_monitor == MON_LSI)
+ {
+ if (set == 0) /* clear breakpoint */
+ {
+ /* The LSI PMON "clear breakpoint" has this form:
+ <pid> 'b' <bptn> 0x0
+ reply:
+ <pid> 'b' 0x0 <code>
+
+ <bptn> is a breakpoint number returned by an earlier 'B' command.
+ Possible return codes: OK, E_BPT. */
+
+ int i;
+
+ /* Search for the breakpoint in the table. */
+ for (i = 0; i < MAX_LSI_BREAKPOINTS; i++)
+ if (lsi_breakpoints[i].type == type
+ && lsi_breakpoints[i].addr == addr
+ && lsi_breakpoints[i].len == len)
+ break;
+
+ /* Clear the table entry and tell PMON to clear the breakpoint. */
+ if (i == MAX_LSI_BREAKPOINTS)
+ {
+ warning ("common_breakpoint: Attempt to clear bogus breakpoint at %s\n",
+ paddr_nz (addr));
+ return 1;
+ }
+
+ lsi_breakpoints[i].type = BREAK_UNUSED;
+ sprintf (buf, "0x0 b 0x%x 0x0", i);
+ mips_send_packet (buf, 1);
+
+ rlen = mips_receive_packet (buf, 1, mips_receive_wait);
+ buf[rlen] = '\0';
+
+ nfields = sscanf (buf, "0x%x b 0x0 0x%x", &rpid, &rerrflg);
+ if (nfields != 2)
+ mips_error ("common_breakpoint: Bad response from remote board: %s", buf);
+
+ return (check_lsi_error (addr, rerrflg));
+ }
+ else
+ /* set a breakpoint */
+ {
+ /* The LSI PMON "set breakpoint" command has this form:
+ <pid> 'B' <addr> 0x0
+ reply:
+ <pid> 'B' <bptn> <code>
+
+ The "set data breakpoint" command has this form:
+
+ <pid> 'A' <addr1> <type> [<addr2> [<value>]]
+
+ where: type= "0x1" = read
+ "0x2" = write
+ "0x3" = access (read or write)
+
+ The reply returns two values:
+ bptn - a breakpoint number, which is a small integer with
+ possible values of zero through 255.
+ code - an error return code, a value of zero indicates a
+ succesful completion, other values indicate various
+ errors and warnings.
+
+ Possible return codes: OK, W_QAL, E_QAL, E_OUT, E_NON.
+
+ */
+
+ if (type == BREAK_FETCH) /* instruction breakpoint */
+ {
+ cmd = 'B';
+ sprintf (buf, "0x0 B 0x%s 0x0", paddr_nz (addr));
+ }
+ else
+ /* watchpoint */
+ {
+ cmd = 'A';
+ sprintf (buf, "0x0 A 0x%s 0x%x 0x%s", paddr_nz (addr),
+ type == BREAK_READ ? 1 : (type == BREAK_WRITE ? 2 : 3),
+ paddr_nz (addr + len - 1));
+ }
+ mips_send_packet (buf, 1);
+
+ rlen = mips_receive_packet (buf, 1, mips_receive_wait);
+ buf[rlen] = '\0';
+
+ nfields = sscanf (buf, "0x%x %c 0x%x 0x%x",
+ &rpid, &rcmd, &rresponse, &rerrflg);
+ if (nfields != 4 || rcmd != cmd || rresponse > 255)
+ mips_error ("common_breakpoint: Bad response from remote board: %s", buf);
+
+ if (rerrflg != 0)
+ if (check_lsi_error (addr, rerrflg))
+ return 1;
+
+ /* rresponse contains PMON's breakpoint number. Record the
+ information for this breakpoint so we can clear it later. */
+ lsi_breakpoints[rresponse].type = type;
+ lsi_breakpoints[rresponse].addr = addr;
+ lsi_breakpoints[rresponse].len = len;
+
+ return 0;
+ }
+ }
+ else
+ {
+ /* On non-LSI targets, the breakpoint command has this form:
+ 0x0 <CMD> <ADDR> <MASK> <FLAGS>
+ <MASK> is a don't care mask for addresses.
+ <FLAGS> is any combination of `r', `w', or `f' for read/write/fetch.
+ */
+ unsigned long mask;
+
+ mask = calculate_mask (addr, len);
+ addr &= ~mask;
+
+ if (set) /* set a breakpoint */
+ {
+ char *flags;
+ switch (type)
+ {
+ case BREAK_WRITE: /* write */
+ flags = "w";
+ break;
+ case BREAK_READ: /* read */
+ flags = "r";
+ break;
+ case BREAK_ACCESS: /* read/write */
+ flags = "rw";
+ break;
+ case BREAK_FETCH: /* fetch */
+ flags = "f";
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+
+ cmd = 'B';
+ sprintf (buf, "0x0 B 0x%s 0x%s %s", paddr_nz (addr),
+ paddr_nz (mask), flags);
+ }
+ else
+ {
+ cmd = 'b';
+ sprintf (buf, "0x0 b 0x%s", paddr_nz (addr));
+ }
+
+ mips_send_packet (buf, 1);
+
+ rlen = mips_receive_packet (buf, 1, mips_receive_wait);
+ buf[rlen] = '\0';
+
+ nfields = sscanf (buf, "0x%x %c 0x%x 0x%x",
+ &rpid, &rcmd, &rerrflg, &rresponse);
+
+ if (nfields != 4 || rcmd != cmd)
+ mips_error ("common_breakpoint: Bad response from remote board: %s",
+ buf);
+
+ if (rerrflg != 0)
+ {
+ /* Ddb returns "0x0 b 0x16 0x0\000", whereas
+ Cogent returns "0x0 b 0xffffffff 0x16\000": */
+ if (mips_monitor == MON_DDB)
+ rresponse = rerrflg;
+ if (rresponse != 22) /* invalid argument */
+ fprintf_unfiltered (gdb_stderr,
+ "common_breakpoint (0x%s): Got error: 0x%x\n",
+ paddr_nz (addr), rresponse);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void
+send_srec (char *srec, int len, CORE_ADDR addr)
+{
+ while (1)
+ {
+ int ch;
+
+ serial_write (mips_desc, srec, len);
+
+ ch = mips_readchar (remote_timeout);
+
+ switch (ch)
+ {
+ case SERIAL_TIMEOUT:
+ error ("Timeout during download.");
+ break;
+ case 0x6: /* ACK */
+ return;
+ case 0x15: /* NACK */
+ fprintf_unfiltered (gdb_stderr, "Download got a NACK at byte %s! Retrying.\n", paddr_u (addr));
+ continue;
+ default:
+ error ("Download got unexpected ack char: 0x%x, retrying.\n", ch);
+ }
+ }
+}
+
+/* Download a binary file by converting it to S records. */
+
+static void
+mips_load_srec (char *args)
+{
+ bfd *abfd;
+ asection *s;
+ char *buffer, srec[1024];
+ unsigned int i;
+ unsigned int srec_frame = 200;
+ int reclen;
+ static int hashmark = 1;
+
+ buffer = alloca (srec_frame * 2 + 256);
+
+ abfd = bfd_openr (args, 0);
+ if (!abfd)
+ {
+ printf_filtered ("Unable to open file %s\n", args);
+ return;
+ }
+
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ {
+ printf_filtered ("File is not an object file\n");
+ return;
+ }
+
+/* This actually causes a download in the IDT binary format: */
+ mips_send_command (LOAD_CMD, 0);
+
+ for (s = abfd->sections; s; s = s->next)
+ {
+ if (s->flags & SEC_LOAD)
+ {
+ unsigned int numbytes;
+
+ /* FIXME! vma too small????? */
+ printf_filtered ("%s\t: 0x%4lx .. 0x%4lx ", s->name,
+ (long) s->vma,
+ (long) (s->vma + s->_raw_size));
+ gdb_flush (gdb_stdout);
+
+ for (i = 0; i < s->_raw_size; i += numbytes)
+ {
+ numbytes = min (srec_frame, s->_raw_size - i);
+
+ bfd_get_section_contents (abfd, s, buffer, i, numbytes);
+
+ reclen = mips_make_srec (srec, '3', s->vma + i, buffer, numbytes);
+ send_srec (srec, reclen, s->vma + i);
+
+ if (ui_load_progress_hook)
+ ui_load_progress_hook (s->name, i);
+
+ if (hashmark)
+ {
+ putchar_unfiltered ('#');
+ gdb_flush (gdb_stdout);
+ }
+
+ } /* Per-packet (or S-record) loop */
+
+ putchar_unfiltered ('\n');
+ } /* Loadable sections */
+ }
+ if (hashmark)
+ putchar_unfiltered ('\n');
+
+ /* Write a type 7 terminator record. no data for a type 7, and there
+ is no data, so len is 0. */
+
+ reclen = mips_make_srec (srec, '7', abfd->start_address, NULL, 0);
+
+ send_srec (srec, reclen, abfd->start_address);
+
+ serial_flush_input (mips_desc);
+}
+
+/*
+ * mips_make_srec -- make an srecord. This writes each line, one at a
+ * time, each with it's own header and trailer line.
+ * An srecord looks like this:
+ *
+ * byte count-+ address
+ * start ---+ | | data +- checksum
+ * | | | |
+ * S01000006F6B692D746573742E73726563E4
+ * S315000448600000000000000000FC00005900000000E9
+ * S31A0004000023C1400037DE00F023604000377B009020825000348D
+ * S30B0004485A0000000000004E
+ * S70500040000F6
+ *
+ * S<type><length><address><data><checksum>
+ *
+ * Where
+ * - length
+ * is the number of bytes following upto the checksum. Note that
+ * this is not the number of chars following, since it takes two
+ * chars to represent a byte.
+ * - type
+ * is one of:
+ * 0) header record
+ * 1) two byte address data record
+ * 2) three byte address data record
+ * 3) four byte address data record
+ * 7) four byte address termination record
+ * 8) three byte address termination record
+ * 9) two byte address termination record
+ *
+ * - address
+ * is the start address of the data following, or in the case of
+ * a termination record, the start address of the image
+ * - data
+ * is the data.
+ * - checksum
+ * is the sum of all the raw byte data in the record, from the length
+ * upwards, modulo 256 and subtracted from 255.
+ *
+ * This routine returns the length of the S-record.
+ *
+ */
+
+static int
+mips_make_srec (char *buf, int type, CORE_ADDR memaddr, unsigned char *myaddr,
+ int len)
+{
+ unsigned char checksum;
+ int i;
+
+ /* Create the header for the srec. addr_size is the number of bytes in the address,
+ and 1 is the number of bytes in the count. */
+
+ /* FIXME!! bigger buf required for 64-bit! */
+ buf[0] = 'S';
+ buf[1] = type;
+ buf[2] = len + 4 + 1; /* len + 4 byte address + 1 byte checksum */
+ /* This assumes S3 style downloads (4byte addresses). There should
+ probably be a check, or the code changed to make it more
+ explicit. */
+ buf[3] = memaddr >> 24;
+ buf[4] = memaddr >> 16;
+ buf[5] = memaddr >> 8;
+ buf[6] = memaddr;
+ memcpy (&buf[7], myaddr, len);
+
+ /* Note that the checksum is calculated on the raw data, not the
+ hexified data. It includes the length, address and the data
+ portions of the packet. */
+ checksum = 0;
+ buf += 2; /* Point at length byte */
+ for (i = 0; i < len + 4 + 1; i++)
+ checksum += *buf++;
+
+ *buf = ~checksum;
+
+ return len + 8;
+}
+
+/* The following manifest controls whether we enable the simple flow
+ control support provided by the monitor. If enabled the code will
+ wait for an affirmative ACK between transmitting packets. */
+#define DOETXACK (1)
+
+/* The PMON fast-download uses an encoded packet format constructed of
+ 3byte data packets (encoded as 4 printable ASCII characters), and
+ escape sequences (preceded by a '/'):
+
+ 'K' clear checksum
+ 'C' compare checksum (12bit value, not included in checksum calculation)
+ 'S' define symbol name (for addr) terminated with "," and padded to 4char boundary
+ 'Z' zero fill multiple of 3bytes
+ 'B' byte (12bit encoded value, of 8bit data)
+ 'A' address (36bit encoded value)
+ 'E' define entry as original address, and exit load
+
+ The packets are processed in 4 character chunks, so the escape
+ sequences that do not have any data (or variable length data)
+ should be padded to a 4 character boundary. The decoder will give
+ an error if the complete message block size is not a multiple of
+ 4bytes (size of record).
+
+ The encoding of numbers is done in 6bit fields. The 6bit value is
+ used to index into this string to get the specific character
+ encoding for the value: */
+static char encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,.";
+
+/* Convert the number of bits required into an encoded number, 6bits
+ at a time (range 0..63). Keep a checksum if required (passed
+ pointer non-NULL). The function returns the number of encoded
+ characters written into the buffer. */
+static int
+pmon_makeb64 (unsigned long v, char *p, int n, int *chksum)
+{
+ int count = (n / 6);
+
+ if ((n % 12) != 0)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "Fast encoding bitcount must be a multiple of 12bits: %dbit%s\n", n, (n == 1) ? "" : "s");
+ return (0);
+ }
+ if (n > 36)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "Fast encoding cannot process more than 36bits at the moment: %dbits\n", n);
+ return (0);
+ }
+
+ /* Deal with the checksum: */
+ if (chksum != NULL)
+ {
+ switch (n)
+ {
+ case 36:
+ *chksum += ((v >> 24) & 0xFFF);
+ case 24:
+ *chksum += ((v >> 12) & 0xFFF);
+ case 12:
+ *chksum += ((v >> 0) & 0xFFF);
+ }
+ }
+
+ do
+ {
+ n -= 6;
+ *p++ = encoding[(v >> n) & 0x3F];
+ }
+ while (n > 0);
+
+ return (count);
+}
+
+/* Shorthand function (that could be in-lined) to output the zero-fill
+ escape sequence into the data stream. */
+static int
+pmon_zeroset (int recsize, char **buff, int *amount, unsigned int *chksum)
+{
+ int count;
+
+ sprintf (*buff, "/Z");
+ count = pmon_makeb64 (*amount, (*buff + 2), 12, chksum);
+ *buff += (count + 2);
+ *amount = 0;
+ return (recsize + count + 2);
+}
+
+static int
+pmon_checkset (int recsize, char **buff, int *value)
+{
+ int count;
+
+ /* Add the checksum (without updating the value): */
+ sprintf (*buff, "/C");
+ count = pmon_makeb64 (*value, (*buff + 2), 12, NULL);
+ *buff += (count + 2);
+ sprintf (*buff, "\n");
+ *buff += 2; /* include zero terminator */
+ /* Forcing a checksum validation clears the sum: */
+ *value = 0;
+ return (recsize + count + 3);
+}
+
+/* Amount of padding we leave after at the end of the output buffer,
+ for the checksum and line termination characters: */
+#define CHECKSIZE (4 + 4 + 4 + 2)
+/* zero-fill, checksum, transfer end and line termination space. */
+
+/* The amount of binary data loaded from the object file in a single
+ operation: */
+#define BINCHUNK (1024)
+
+/* Maximum line of data accepted by the monitor: */
+#define MAXRECSIZE (550)
+/* NOTE: This constant depends on the monitor being used. This value
+ is for PMON 5.x on the Cogent Vr4300 board. */
+
+static void
+pmon_make_fastrec (char **outbuf, unsigned char *inbuf, int *inptr,
+ int inamount, int *recsize, unsigned int *csum,
+ unsigned int *zerofill)
+{
+ int count = 0;
+ char *p = *outbuf;
+
+ /* This is a simple check to ensure that our data will fit within
+ the maximum allowable record size. Each record output is 4bytes
+ in length. We must allow space for a pending zero fill command,
+ the record, and a checksum record. */
+ while ((*recsize < (MAXRECSIZE - CHECKSIZE)) && ((inamount - *inptr) > 0))
+ {
+ /* Process the binary data: */
+ if ((inamount - *inptr) < 3)
+ {
+ if (*zerofill != 0)
+ *recsize = pmon_zeroset (*recsize, &p, zerofill, csum);
+ sprintf (p, "/B");
+ count = pmon_makeb64 (inbuf[*inptr], &p[2], 12, csum);
+ p += (2 + count);
+ *recsize += (2 + count);
+ (*inptr)++;
+ }
+ else
+ {
+ unsigned int value = ((inbuf[*inptr + 0] << 16) | (inbuf[*inptr + 1] << 8) | inbuf[*inptr + 2]);
+ /* Simple check for zero data. TODO: A better check would be
+ to check the last, and then the middle byte for being zero
+ (if the first byte is not). We could then check for
+ following runs of zeros, and if above a certain size it is
+ worth the 4 or 8 character hit of the byte insertions used
+ to pad to the start of the zeroes. NOTE: This also depends
+ on the alignment at the end of the zero run. */
+ if (value == 0x00000000)
+ {
+ (*zerofill)++;
+ if (*zerofill == 0xFFF) /* 12bit counter */
+ *recsize = pmon_zeroset (*recsize, &p, zerofill, csum);
+ }
+ else
+ {
+ if (*zerofill != 0)
+ *recsize = pmon_zeroset (*recsize, &p, zerofill, csum);
+ count = pmon_makeb64 (value, p, 24, csum);
+ p += count;
+ *recsize += count;
+ }
+ *inptr += 3;
+ }
+ }
+
+ *outbuf = p;
+ return;
+}
+
+static int
+pmon_check_ack (char *mesg)
+{
+#if defined(DOETXACK)
+ int c;
+
+ if (!tftp_in_use)
+ {
+ c = serial_readchar (udp_in_use ? udp_desc : mips_desc,
+ remote_timeout);
+ if ((c == SERIAL_TIMEOUT) || (c != 0x06))
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "Failed to receive valid ACK for %s\n", mesg);
+ return (-1); /* terminate the download */
+ }
+ }
+#endif /* DOETXACK */
+ return (0);
+}
+
+/* pmon_download - Send a sequence of characters to the PMON download port,
+ which is either a serial port or a UDP socket. */
+
+static void
+pmon_start_download (void)
+{
+ if (tftp_in_use)
+ {
+ /* Create the temporary download file. */
+ if ((tftp_file = fopen (tftp_localname, "w")) == NULL)
+ perror_with_name (tftp_localname);
+ }
+ else
+ {
+ mips_send_command (udp_in_use ? LOAD_CMD_UDP : LOAD_CMD, 0);
+ mips_expect ("Downloading from ");
+ mips_expect (udp_in_use ? "udp" : "tty0");
+ mips_expect (", ^C to abort\r\n");
+ }
+}
+
+static int
+mips_expect_download (char *string)
+{
+ if (!mips_expect (string))
+ {
+ fprintf_unfiltered (gdb_stderr, "Load did not complete successfully.\n");
+ if (tftp_in_use)
+ remove (tftp_localname); /* Remove temporary file */
+ return 0;
+ }
+ else
+ return 1;
+}
+
+static void
+pmon_check_entry_address (char *entry_address, int final)
+{
+ char hexnumber[9]; /* includes '\0' space */
+ mips_expect_timeout (entry_address, tftp_in_use ? 15 : remote_timeout);
+ sprintf (hexnumber, "%x", final);
+ mips_expect (hexnumber);
+ mips_expect ("\r\n");
+}
+
+static int
+pmon_check_total (int bintotal)
+{
+ char hexnumber[9]; /* includes '\0' space */
+ mips_expect ("\r\ntotal = 0x");
+ sprintf (hexnumber, "%x", bintotal);
+ mips_expect (hexnumber);
+ return mips_expect_download (" bytes\r\n");
+}
+
+static void
+pmon_end_download (int final, int bintotal)
+{
+ char hexnumber[9]; /* includes '\0' space */
+
+ if (tftp_in_use)
+ {
+ static char *load_cmd_prefix = "load -b -s ";
+ char *cmd;
+ struct stat stbuf;
+
+ /* Close off the temporary file containing the load data. */
+ fclose (tftp_file);
+ tftp_file = NULL;
+
+ /* Make the temporary file readable by the world. */
+ if (stat (tftp_localname, &stbuf) == 0)
+ chmod (tftp_localname, stbuf.st_mode | S_IROTH);
+
+ /* Must reinitialize the board to prevent PMON from crashing. */
+ mips_send_command ("initEther\r", -1);
+
+ /* Send the load command. */
+ cmd = xmalloc (strlen (load_cmd_prefix) + strlen (tftp_name) + 2);
+ strcpy (cmd, load_cmd_prefix);
+ strcat (cmd, tftp_name);
+ strcat (cmd, "\r");
+ mips_send_command (cmd, 0);
+ xfree (cmd);
+ if (!mips_expect_download ("Downloading from "))
+ return;
+ if (!mips_expect_download (tftp_name))
+ return;
+ if (!mips_expect_download (", ^C to abort\r\n"))
+ return;
+ }
+
+ /* Wait for the stuff that PMON prints after the load has completed.
+ The timeout value for use in the tftp case (15 seconds) was picked
+ arbitrarily but might be too small for really large downloads. FIXME. */
+ switch (mips_monitor)
+ {
+ case MON_LSI:
+ pmon_check_ack ("termination");
+ pmon_check_entry_address ("Entry address is ", final);
+ if (!pmon_check_total (bintotal))
+ return;
+ break;
+ default:
+ pmon_check_entry_address ("Entry Address = ", final);
+ pmon_check_ack ("termination");
+ if (!pmon_check_total (bintotal))
+ return;
+ break;
+ }
+
+ if (tftp_in_use)
+ remove (tftp_localname); /* Remove temporary file */
+}
+
+static void
+pmon_download (char *buffer, int length)
+{
+ if (tftp_in_use)
+ fwrite (buffer, 1, length, tftp_file);
+ else
+ serial_write (udp_in_use ? udp_desc : mips_desc, buffer, length);
+}
+
+static void
+pmon_load_fast (char *file)
+{
+ bfd *abfd;
+ asection *s;
+ unsigned char *binbuf;
+ char *buffer;
+ int reclen;
+ unsigned int csum = 0;
+ int hashmark = !tftp_in_use;
+ int bintotal = 0;
+ int final = 0;
+ int finished = 0;
+
+ buffer = (char *) xmalloc (MAXRECSIZE + 1);
+ binbuf = (unsigned char *) xmalloc (BINCHUNK);
+
+ abfd = bfd_openr (file, 0);
+ if (!abfd)
+ {
+ printf_filtered ("Unable to open file %s\n", file);
+ return;
+ }
+
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ {
+ printf_filtered ("File is not an object file\n");
+ return;
+ }
+
+ /* Setup the required download state: */
+ mips_send_command ("set dlproto etxack\r", -1);
+ mips_send_command ("set dlecho off\r", -1);
+ /* NOTE: We get a "cannot set variable" message if the variable is
+ already defined to have the argument we give. The code doesn't
+ care, since it just scans to the next prompt anyway. */
+ /* Start the download: */
+ pmon_start_download ();
+
+ /* Zero the checksum */
+ sprintf (buffer, "/Kxx\n");
+ reclen = strlen (buffer);
+ pmon_download (buffer, reclen);
+ finished = pmon_check_ack ("/Kxx");
+
+ for (s = abfd->sections; s && !finished; s = s->next)
+ if (s->flags & SEC_LOAD) /* only deal with loadable sections */
+ {
+ bintotal += s->_raw_size;
+ final = (s->vma + s->_raw_size);
+
+ printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, (unsigned int) s->vma,
+ (unsigned int) (s->vma + s->_raw_size));
+ gdb_flush (gdb_stdout);
+
+ /* Output the starting address */
+ sprintf (buffer, "/A");
+ reclen = pmon_makeb64 (s->vma, &buffer[2], 36, &csum);
+ buffer[2 + reclen] = '\n';
+ buffer[3 + reclen] = '\0';
+ reclen += 3; /* for the initial escape code and carriage return */
+ pmon_download (buffer, reclen);
+ finished = pmon_check_ack ("/A");
+
+ if (!finished)
+ {
+ unsigned int binamount;
+ unsigned int zerofill = 0;
+ char *bp = buffer;
+ unsigned int i;
+
+ reclen = 0;
+
+ for (i = 0; ((i < s->_raw_size) && !finished); i += binamount)
+ {
+ int binptr = 0;
+
+ binamount = min (BINCHUNK, s->_raw_size - i);
+
+ bfd_get_section_contents (abfd, s, binbuf, i, binamount);
+
+ /* This keeps a rolling checksum, until we decide to output
+ the line: */
+ for (; ((binamount - binptr) > 0);)
+ {
+ pmon_make_fastrec (&bp, binbuf, &binptr, binamount, &reclen, &csum, &zerofill);
+ if (reclen >= (MAXRECSIZE - CHECKSIZE))
+ {
+ reclen = pmon_checkset (reclen, &bp, &csum);
+ pmon_download (buffer, reclen);
+ finished = pmon_check_ack ("data record");
+ if (finished)
+ {
+ zerofill = 0; /* do not transmit pending zerofills */
+ break;
+ }
+
+ if (ui_load_progress_hook)
+ ui_load_progress_hook (s->name, i);
+
+ if (hashmark)
+ {
+ putchar_unfiltered ('#');
+ gdb_flush (gdb_stdout);
+ }
+
+ bp = buffer;
+ reclen = 0; /* buffer processed */
+ }
+ }
+ }
+
+ /* Ensure no out-standing zerofill requests: */
+ if (zerofill != 0)
+ reclen = pmon_zeroset (reclen, &bp, &zerofill, &csum);
+
+ /* and then flush the line: */
+ if (reclen > 0)
+ {
+ reclen = pmon_checkset (reclen, &bp, &csum);
+ /* Currently pmon_checkset outputs the line terminator by
+ default, so we write out the buffer so far: */
+ pmon_download (buffer, reclen);
+ finished = pmon_check_ack ("record remnant");
+ }
+ }
+
+ putchar_unfiltered ('\n');
+ }
+
+ /* Terminate the transfer. We know that we have an empty output
+ buffer at this point. */
+ sprintf (buffer, "/E/E\n"); /* include dummy padding characters */
+ reclen = strlen (buffer);
+ pmon_download (buffer, reclen);
+
+ if (finished)
+ { /* Ignore the termination message: */
+ serial_flush_input (udp_in_use ? udp_desc : mips_desc);
+ }
+ else
+ { /* Deal with termination message: */
+ pmon_end_download (final, bintotal);
+ }
+
+ return;
+}
+
+/* mips_load -- download a file. */
+
+static void
+mips_load (char *file, int from_tty)
+{
+ /* Get the board out of remote debugging mode. */
+ if (mips_exit_debug ())
+ error ("mips_load: Couldn't get into monitor mode.");
+
+ if (mips_monitor != MON_IDT)
+ pmon_load_fast (file);
+ else
+ mips_load_srec (file);
+
+ mips_initialize ();
+
+ /* Finally, make the PC point at the start address */
+ if (mips_monitor != MON_IDT)
+ {
+ /* Work around problem where PMON monitor updates the PC after a load
+ to a different value than GDB thinks it has. The following ensures
+ that the write_pc() WILL update the PC value: */
+ register_valid[PC_REGNUM] = 0;
+ }
+ if (exec_bfd)
+ write_pc (bfd_get_start_address (exec_bfd));
+
+ inferior_ptid = null_ptid; /* No process now */
+
+/* This is necessary because many things were based on the PC at the time that
+ we attached to the monitor, which is no longer valid now that we have loaded
+ new code (and just changed the PC). Another way to do this might be to call
+ normal_stop, except that the stack may not be valid, and things would get
+ horribly confused... */
+
+ clear_symtab_users ();
+}
+
+
+/* Pass the command argument as a packet to PMON verbatim. */
+
+static void
+pmon_command (char *args, int from_tty)
+{
+ char buf[DATA_MAXLEN + 1];
+ int rlen;
+
+ sprintf (buf, "0x0 %s", args);
+ mips_send_packet (buf, 1);
+ printf_filtered ("Send packet: %s\n", buf);
+
+ rlen = mips_receive_packet (buf, 1, mips_receive_wait);
+ buf[rlen] = '\0';
+ printf_filtered ("Received packet: %s\n", buf);
+}
+
+void
+_initialize_remote_mips (void)
+{
+ /* Initialize the fields in mips_ops that are common to all four targets. */
+ mips_ops.to_longname = "Remote MIPS debugging over serial line";
+ mips_ops.to_close = mips_close;
+ mips_ops.to_detach = mips_detach;
+ mips_ops.to_resume = mips_resume;
+ mips_ops.to_fetch_registers = mips_fetch_registers;
+ mips_ops.to_store_registers = mips_store_registers;
+ mips_ops.to_prepare_to_store = mips_prepare_to_store;
+ mips_ops.to_xfer_memory = mips_xfer_memory;
+ mips_ops.to_files_info = mips_files_info;
+ mips_ops.to_insert_breakpoint = mips_insert_breakpoint;
+ mips_ops.to_remove_breakpoint = mips_remove_breakpoint;
+ mips_ops.to_kill = mips_kill;
+ mips_ops.to_load = mips_load;
+ mips_ops.to_create_inferior = mips_create_inferior;
+ mips_ops.to_mourn_inferior = mips_mourn_inferior;
+ mips_ops.to_stratum = process_stratum;
+ mips_ops.to_has_all_memory = 1;
+ mips_ops.to_has_memory = 1;
+ mips_ops.to_has_stack = 1;
+ mips_ops.to_has_registers = 1;
+ mips_ops.to_has_execution = 1;
+ mips_ops.to_magic = OPS_MAGIC;
+
+ /* Copy the common fields to all four target vectors. */
+ pmon_ops = ddb_ops = lsi_ops = mips_ops;
+
+ /* Initialize target-specific fields in the target vectors. */
+ mips_ops.to_shortname = "mips";
+ mips_ops.to_doc = "\
+Debug a board using the MIPS remote debugging protocol over a serial line.\n\
+The argument is the device it is connected to or, if it contains a colon,\n\
+HOST:PORT to access a board over a network";
+ mips_ops.to_open = mips_open;
+ mips_ops.to_wait = mips_wait;
+
+ pmon_ops.to_shortname = "pmon";
+ pmon_ops.to_doc = "\
+Debug a board using the PMON MIPS remote debugging protocol over a serial\n\
+line. The argument is the device it is connected to or, if it contains a\n\
+colon, HOST:PORT to access a board over a network";
+ pmon_ops.to_open = pmon_open;
+ pmon_ops.to_wait = mips_wait;
+
+ ddb_ops.to_shortname = "ddb";
+ ddb_ops.to_doc = "\
+Debug a board using the PMON MIPS remote debugging protocol over a serial\n\
+line. The first argument is the device it is connected to or, if it contains\n\
+a colon, HOST:PORT to access a board over a network. The optional second\n\
+parameter is the temporary file in the form HOST:FILENAME to be used for\n\
+TFTP downloads to the board. The optional third parameter is the local name\n\
+of the TFTP temporary file, if it differs from the filename seen by the board.";
+ ddb_ops.to_open = ddb_open;
+ ddb_ops.to_wait = mips_wait;
+
+ lsi_ops.to_shortname = "lsi";
+ lsi_ops.to_doc = pmon_ops.to_doc;
+ lsi_ops.to_open = lsi_open;
+ lsi_ops.to_wait = mips_wait;
+
+ /* Add the targets. */
+ add_target (&mips_ops);
+ add_target (&pmon_ops);
+ add_target (&ddb_ops);
+ add_target (&lsi_ops);
+
+ add_show_from_set (
+ add_set_cmd ("timeout", no_class, var_zinteger,
+ (char *) &mips_receive_wait,
+ "Set timeout in seconds for remote MIPS serial I/O.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("retransmit-timeout", no_class, var_zinteger,
+ (char *) &mips_retransmit_wait,
+ "Set retransmit timeout in seconds for remote MIPS serial I/O.\n\
+This is the number of seconds to wait for an acknowledgement to a packet\n\
+before resending the packet.", &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("syn-garbage-limit", no_class, var_zinteger,
+ (char *) &mips_syn_garbage,
+ "Set the maximum number of characters to ignore when scanning for a SYN.\n\
+This is the maximum number of characters GDB will ignore when trying to\n\
+synchronize with the remote system. A value of -1 means that there is no limit\n\
+(Note that these characters are printed out even though they are ignored.)",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("monitor-prompt", class_obscure, var_string,
+ (char *) &mips_monitor_prompt,
+ "Set the prompt that GDB expects from the monitor.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("monitor-warnings", class_obscure, var_zinteger,
+ (char *) &monitor_warnings,
+ "Set printing of monitor warnings.\n"
+ "When enabled, monitor warnings about hardware breakpoints "
+ "will be displayed.",
+ &setlist),
+ &showlist);
+
+ add_com ("pmon <command>", class_obscure, pmon_command,
+ "Send a packet to PMON (must be in debug mode).");
+
+ add_show_from_set (add_set_cmd ("mask-address", no_class,
+ var_boolean, &mask_address_p,
+ "Set zeroing of upper 32 bits of 64-bit addresses when talking to PMON targets.\n\
+Use \"on\" to enable the masking and \"off\" to disable it.\n",
+ &setlist),
+ &showlist);
+}
diff --git a/gdb/remote-nindy.c b/gdb/remote-nindy.c
new file mode 100644
index 00000000000..679dfad919e
--- /dev/null
+++ b/gdb/remote-nindy.c
@@ -0,0 +1,762 @@
+/* Memory-access and commands for remote NINDY process, for GDB.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
+ 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Intel Corporation. Modified from remote.c by Chris Benenati.
+
+ GDB is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY. No author or distributor accepts responsibility to anyone
+ for the consequences of using it or for whether it serves any
+ particular purpose or works at all, unless he says so in writing.
+ Refer to the GDB General Public License for full details.
+
+ Everyone is granted permission to copy, modify and redistribute GDB,
+ but only under the conditions described in the GDB General Public
+ License. A copy of this license is supposed to have been given to you
+ along with GDB so you can know your rights and responsibilities. It
+ should be in a file named COPYING. Among other things, the copyright
+ notice and this notice must be preserved on all copies.
+
+ In other words, go ahead and share GDB, but don't try to stop
+ anyone else from sharing it farther. Help stamp out software hoarding! */
+
+/*
+ Except for the data cache routines, this file bears little resemblence
+ to remote.c. A new (although similar) protocol has been specified, and
+ portions of the code are entirely dependent on having an i80960 with a
+ NINDY ROM monitor at the other end of the line.
+ */
+
+/*****************************************************************************
+ *
+ * REMOTE COMMUNICATION PROTOCOL BETWEEN GDB960 AND THE NINDY ROM MONITOR.
+ *
+ *
+ * MODES OF OPERATION
+ * ----- -- ---------
+ *
+ * As far as NINDY is concerned, GDB is always in one of two modes: command
+ * mode or passthrough mode.
+ *
+ * In command mode (the default) pre-defined packets containing requests
+ * are sent by GDB to NINDY. NINDY never talks except in reponse to a request.
+ *
+ * Once the the user program is started, GDB enters passthrough mode, to give
+ * the user program access to the terminal. GDB remains in this mode until
+ * NINDY indicates that the program has stopped.
+ *
+ *
+ * PASSTHROUGH MODE
+ * ----------- ----
+ *
+ * GDB writes all input received from the keyboard directly to NINDY, and writes
+ * all characters received from NINDY directly to the monitor.
+ *
+ * Keyboard input is neither buffered nor echoed to the monitor.
+ *
+ * GDB remains in passthrough mode until NINDY sends a single ^P character,
+ * to indicate that the user process has stopped.
+ *
+ * Note:
+ * GDB assumes NINDY performs a 'flushreg' when the user program stops.
+ *
+ *
+ * COMMAND MODE
+ * ------- ----
+ *
+ * All info (except for message ack and nak) is transferred between gdb
+ * and the remote processor in messages of the following format:
+ *
+ * <info>#<checksum>
+ *
+ * where
+ * # is a literal character
+ *
+ * <info> ASCII information; all numeric information is in the
+ * form of hex digits ('0'-'9' and lowercase 'a'-'f').
+ *
+ * <checksum>
+ * is a pair of ASCII hex digits representing an 8-bit
+ * checksum formed by adding together each of the
+ * characters in <info>.
+ *
+ * The receiver of a message always sends a single character to the sender
+ * to indicate that the checksum was good ('+') or bad ('-'); the sender
+ * re-transmits the entire message over until a '+' is received.
+ *
+ * In response to a command NINDY always sends back either data or
+ * a result code of the form "Xnn", where "nn" are hex digits and "X00"
+ * means no errors. (Exceptions: the "s" and "c" commands don't respond.)
+ *
+ * SEE THE HEADER OF THE FILE "gdb.c" IN THE NINDY MONITOR SOURCE CODE FOR A
+ * FULL DESCRIPTION OF LEGAL COMMANDS.
+ *
+ * SEE THE FILE "stop.h" IN THE NINDY MONITOR SOURCE CODE FOR A LIST
+ * OF STOP CODES.
+ *
+ ***************************************************************************/
+
+#include "defs.h"
+#include <signal.h>
+#include <sys/types.h>
+#include <setjmp.h>
+
+#include "frame.h"
+#include "inferior.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "floatformat.h"
+#include "regcache.h"
+
+#include <sys/file.h>
+#include <ctype.h>
+#include "serial.h"
+#include "nindy-share/env.h"
+#include "nindy-share/stop.h"
+#include "remote-utils.h"
+
+extern int unlink ();
+extern char *getenv ();
+extern char *mktemp ();
+
+extern void generic_mourn_inferior ();
+
+extern struct target_ops nindy_ops;
+extern FILE *instream;
+
+extern char ninStopWhy ();
+extern int ninMemGet ();
+extern int ninMemPut ();
+
+int nindy_initial_brk; /* nonzero if want to send an initial BREAK to nindy */
+int nindy_old_protocol; /* nonzero if want to use old protocol */
+char *nindy_ttyname; /* name of tty to talk to nindy on, or null */
+
+#define DLE '\020' /* Character NINDY sends to indicate user program has
+ * halted. */
+#define TRUE 1
+#define FALSE 0
+
+/* From nindy-share/nindy.c. */
+extern struct serial *nindy_serial;
+
+static int have_regs = 0; /* 1 iff regs read since i960 last halted */
+static int regs_changed = 0; /* 1 iff regs were modified since last read */
+
+extern char *exists ();
+
+static void nindy_fetch_registers (int);
+
+static void nindy_store_registers (int);
+
+static char *savename;
+
+static void
+nindy_close (int quitting)
+{
+ if (nindy_serial != NULL)
+ serial_close (nindy_serial);
+ nindy_serial = NULL;
+
+ if (savename)
+ xfree (savename);
+ savename = 0;
+}
+
+/* Open a connection to a remote debugger.
+ FIXME, there should be "set" commands for the options that are
+ now specified with gdb command-line options (old_protocol,
+ and initial_brk). */
+void
+nindy_open (char *name, /* "/dev/ttyXX", "ttyXX", or "XX": tty to be opened */
+ int from_tty)
+{
+ char baudrate[1024];
+
+ if (!name)
+ error_no_arg ("serial port device name");
+
+ target_preopen (from_tty);
+
+ nindy_close (0);
+
+ have_regs = regs_changed = 0;
+
+ /* Allow user to interrupt the following -- we could hang if there's
+ no NINDY at the other end of the remote tty. */
+ immediate_quit++;
+ /* If baud_rate is -1, then ninConnect will not recognize the baud rate
+ and will deal with the situation in a (more or less) reasonable
+ fashion. */
+ sprintf (baudrate, "%d", baud_rate);
+ ninConnect (name, baudrate,
+ nindy_initial_brk, !from_tty, nindy_old_protocol);
+ immediate_quit--;
+
+ if (nindy_serial == NULL)
+ {
+ perror_with_name (name);
+ }
+
+ savename = savestring (name, strlen (name));
+ push_target (&nindy_ops);
+
+ target_fetch_registers (-1);
+
+ init_thread_list ();
+ init_wait_for_inferior ();
+ clear_proceed_status ();
+ normal_stop ();
+}
+
+/* User-initiated quit of nindy operations. */
+
+static void
+nindy_detach (char *name, int from_tty)
+{
+ if (name)
+ error ("Too many arguments");
+ pop_target ();
+}
+
+static void
+nindy_files_info (void)
+{
+ /* FIXME: this lies about the baud rate if we autobauded. */
+ printf_unfiltered ("\tAttached to %s at %d bits per second%s%s.\n", savename,
+ baud_rate,
+ nindy_old_protocol ? " in old protocol" : "",
+ nindy_initial_brk ? " with initial break" : "");
+}
+
+/* Return the number of characters in the buffer BUF before
+ the first DLE character. N is maximum number of characters to
+ consider. */
+
+static
+int
+non_dle (char *buf, int n)
+{
+ int i;
+
+ for (i = 0; i < n; i++)
+ {
+ if (buf[i] == DLE)
+ {
+ break;
+ }
+ }
+ return i;
+}
+
+/* Tell the remote machine to resume. */
+
+void
+nindy_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ if (siggnal != TARGET_SIGNAL_0 && siggnal != stop_signal)
+ warning ("Can't send signals to remote NINDY targets.");
+
+ if (regs_changed)
+ {
+ nindy_store_registers (-1);
+ regs_changed = 0;
+ }
+ have_regs = 0;
+ ninGo (step);
+}
+
+/* FIXME, we can probably use the normal terminal_inferior stuff here.
+ We have to do terminal_inferior and then set up the passthrough
+ settings initially. Thereafter, terminal_ours and terminal_inferior
+ will automatically swap the settings around for us. */
+
+struct clean_up_tty_args
+{
+ serial_ttystate state;
+ struct serial *serial;
+};
+static struct clean_up_tty_args tty_args;
+
+static void
+clean_up_tty (PTR ptrarg)
+{
+ struct clean_up_tty_args *args = (struct clean_up_tty_args *) ptrarg;
+ serial_set_tty_state (args->serial, args->state);
+ xfree (args->state);
+ warning ("\n\nYou may need to reset the 80960 and/or reload your program.\n");
+}
+
+/* Recover from ^Z or ^C while remote process is running */
+static void (*old_ctrlc) ();
+#ifdef SIGTSTP
+static void (*old_ctrlz) ();
+#endif
+
+static void
+clean_up_int (void)
+{
+ serial_set_tty_state (tty_args.serial, tty_args.state);
+ xfree (tty_args.state);
+
+ signal (SIGINT, old_ctrlc);
+#ifdef SIGTSTP
+ signal (SIGTSTP, old_ctrlz);
+#endif
+ error ("\n\nYou may need to reset the 80960 and/or reload your program.\n");
+}
+
+/* Wait until the remote machine stops. While waiting, operate in passthrough
+ * mode; i.e., pass everything NINDY sends to gdb_stdout, and everything from
+ * stdin to NINDY.
+ *
+ * Return to caller, storing status in 'status' just as `wait' would.
+ */
+
+static ptid_t
+nindy_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ fd_set fds;
+ int c;
+ char buf[2];
+ int i, n;
+ unsigned char stop_exit;
+ unsigned char stop_code;
+ struct cleanup *old_cleanups;
+ long ip_value, fp_value, sp_value; /* Reg values from stop */
+
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = 0;
+
+ /* OPERATE IN PASSTHROUGH MODE UNTIL NINDY SENDS A DLE CHARACTER */
+
+ /* Save current tty attributes, and restore them when done. */
+ tty_args.serial = serial_fdopen (0);
+ tty_args.state = serial_get_tty_state (tty_args.serial);
+ old_ctrlc = signal (SIGINT, clean_up_int);
+#ifdef SIGTSTP
+ old_ctrlz = signal (SIGTSTP, clean_up_int);
+#endif
+
+ old_cleanups = make_cleanup (clean_up_tty, &tty_args);
+
+ /* Pass input from keyboard to NINDY as it arrives. NINDY will interpret
+ <CR> and perform echo. */
+ /* This used to set CBREAK and clear ECHO and CRMOD. I hope this is close
+ enough. */
+ serial_raw (tty_args.serial);
+
+ while (1)
+ {
+ /* Input on remote */
+ c = serial_readchar (nindy_serial, -1);
+ if (c == SERIAL_ERROR)
+ {
+ error ("Cannot read from serial line");
+ }
+ else if (c == 0x1b) /* ESC */
+ {
+ c = serial_readchar (nindy_serial, -1);
+ c &= ~0x40;
+ }
+ else if (c != 0x10) /* DLE */
+ /* Write out any characters preceding DLE */
+ {
+ buf[0] = (char) c;
+ write (1, buf, 1);
+ }
+ else
+ {
+ stop_exit = ninStopWhy (&stop_code,
+ &ip_value, &fp_value, &sp_value);
+ if (!stop_exit && (stop_code == STOP_SRQ))
+ {
+ immediate_quit++;
+ ninSrq ();
+ immediate_quit--;
+ }
+ else
+ {
+ /* Get out of loop */
+ supply_register (IP_REGNUM,
+ (char *) &ip_value);
+ supply_register (FP_REGNUM,
+ (char *) &fp_value);
+ supply_register (SP_REGNUM,
+ (char *) &sp_value);
+ break;
+ }
+ }
+ }
+
+ serial_set_tty_state (tty_args.serial, tty_args.state);
+ xfree (tty_args.state);
+ discard_cleanups (old_cleanups);
+
+ if (stop_exit)
+ {
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = stop_code;
+ }
+ else
+ {
+ /* nindy has some special stop code need to be handled */
+ if (stop_code == STOP_GDB_BPT)
+ stop_code = TRACE_STEP;
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = i960_fault_to_signal (stop_code);
+ }
+ return inferior_ptid;
+}
+
+/* Read the remote registers into the block REGS. */
+
+/* This is the block that ninRegsGet and ninRegsPut handles. */
+struct nindy_regs
+{
+ char local_regs[16 * 4];
+ char global_regs[16 * 4];
+ char pcw_acw[2 * 4];
+ char ip[4];
+ char tcw[4];
+ char fp_as_double[4 * 8];
+};
+
+static void
+nindy_fetch_registers (int regno)
+{
+ struct nindy_regs nindy_regs;
+ int regnum;
+
+ immediate_quit++;
+ ninRegsGet ((char *) &nindy_regs);
+ immediate_quit--;
+
+ memcpy (&registers[REGISTER_BYTE (R0_REGNUM)], nindy_regs.local_regs, 16 * 4);
+ memcpy (&registers[REGISTER_BYTE (G0_REGNUM)], nindy_regs.global_regs, 16 * 4);
+ memcpy (&registers[REGISTER_BYTE (PCW_REGNUM)], nindy_regs.pcw_acw, 2 * 4);
+ memcpy (&registers[REGISTER_BYTE (IP_REGNUM)], nindy_regs.ip, 1 * 4);
+ memcpy (&registers[REGISTER_BYTE (TCW_REGNUM)], nindy_regs.tcw, 1 * 4);
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], nindy_regs.fp_as_double, 4 * 8);
+
+ registers_fetched ();
+}
+
+static void
+nindy_prepare_to_store (void)
+{
+ /* Fetch all regs if they aren't already here. */
+ read_register_bytes (0, NULL, REGISTER_BYTES);
+}
+
+static void
+nindy_store_registers (int regno)
+{
+ struct nindy_regs nindy_regs;
+ int regnum;
+
+ memcpy (nindy_regs.local_regs, &registers[REGISTER_BYTE (R0_REGNUM)], 16 * 4);
+ memcpy (nindy_regs.global_regs, &registers[REGISTER_BYTE (G0_REGNUM)], 16 * 4);
+ memcpy (nindy_regs.pcw_acw, &registers[REGISTER_BYTE (PCW_REGNUM)], 2 * 4);
+ memcpy (nindy_regs.ip, &registers[REGISTER_BYTE (IP_REGNUM)], 1 * 4);
+ memcpy (nindy_regs.tcw, &registers[REGISTER_BYTE (TCW_REGNUM)], 1 * 4);
+ memcpy (nindy_regs.fp_as_double, &registers[REGISTER_BYTE (FP0_REGNUM)], 8 * 4);
+
+ immediate_quit++;
+ ninRegsPut ((char *) &nindy_regs);
+ immediate_quit--;
+}
+
+/* Copy LEN bytes to or from inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. Copy to inferior if
+ SHOULD_WRITE is nonzero. Returns the length copied. TARGET is
+ unused. */
+
+int
+nindy_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int should_write, struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ int res;
+
+ if (len <= 0)
+ return 0;
+
+ if (should_write)
+ res = ninMemPut (memaddr, myaddr, len);
+ else
+ res = ninMemGet (memaddr, myaddr, len);
+
+ return res;
+}
+
+static void
+nindy_create_inferior (char *execfile, char *args, char **env)
+{
+ int entry_pt;
+ int pid;
+
+ if (args && *args)
+ error ("Can't pass arguments to remote NINDY process");
+
+ if (execfile == 0 || exec_bfd == 0)
+ error ("No executable file specified");
+
+ entry_pt = (int) bfd_get_start_address (exec_bfd);
+
+ pid = 42;
+
+ /* The "process" (board) is already stopped awaiting our commands, and
+ the program is already downloaded. We just set its PC and go. */
+
+ inferior_ptid = pid_to_ptid (pid); /* Needed for wait_for_inferior below */
+
+ clear_proceed_status ();
+
+ /* Tell wait_for_inferior that we've started a new process. */
+ init_wait_for_inferior ();
+
+ /* Set up the "saved terminal modes" of the inferior
+ based on what modes we are starting it with. */
+ target_terminal_init ();
+
+ /* Install inferior's terminal modes. */
+ target_terminal_inferior ();
+
+ /* insert_step_breakpoint (); FIXME, do we need this? */
+ /* Let 'er rip... */
+ proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0);
+}
+
+static void
+reset_command (char *args, int from_tty)
+{
+ if (nindy_serial == NULL)
+ {
+ error ("No target system to reset -- use 'target nindy' command.");
+ }
+ if (query ("Really reset the target system?", 0, 0))
+ {
+ serial_send_break (nindy_serial);
+ tty_flush (nindy_serial);
+ }
+}
+
+void
+nindy_kill (char *args, int from_tty)
+{
+ return; /* Ignore attempts to kill target system */
+}
+
+/* Clean up when a program exits.
+
+ The program actually lives on in the remote processor's RAM, and may be
+ run again without a download. Don't leave it full of breakpoint
+ instructions. */
+
+void
+nindy_mourn_inferior (void)
+{
+ remove_breakpoints ();
+ unpush_target (&nindy_ops);
+ generic_mourn_inferior (); /* Do all the proper things now */
+}
+
+/* Pass the args the way catch_errors wants them. */
+static int
+nindy_open_stub (char *arg)
+{
+ nindy_open (arg, 1);
+ return 1;
+}
+
+static void
+nindy_load (char *filename, int from_tty)
+{
+ asection *s;
+ /* Can't do unix style forking on a VMS system, so we'll use bfd to do
+ all the work for us
+ */
+
+ bfd *file = bfd_openr (filename, 0);
+ if (!file)
+ {
+ perror_with_name (filename);
+ return;
+ }
+
+ if (!bfd_check_format (file, bfd_object))
+ {
+ error ("can't prove it's an object file\n");
+ return;
+ }
+
+ for (s = file->sections; s; s = s->next)
+ {
+ if (s->flags & SEC_LOAD)
+ {
+ char *buffer = xmalloc (s->_raw_size);
+ bfd_get_section_contents (file, s, buffer, 0, s->_raw_size);
+ printf ("Loading section %s, size %x vma %x\n",
+ s->name,
+ s->_raw_size,
+ s->vma);
+ ninMemPut (s->vma, buffer, s->_raw_size);
+ xfree (buffer);
+ }
+ }
+ bfd_close (file);
+}
+
+static int
+load_stub (char *arg)
+{
+ target_load (arg, 1);
+ return 1;
+}
+
+/* This routine is run as a hook, just before the main command loop is
+ entered. If gdb is configured for the i960, but has not had its
+ nindy target specified yet, this will loop prompting the user to do so.
+
+ Unlike the loop provided by Intel, we actually let the user get out
+ of this with a RETURN. This is useful when e.g. simply examining
+ an i960 object file on the host system. */
+
+void
+nindy_before_main_loop (void)
+{
+ char ttyname[100];
+ char *p, *p2;
+
+ while (target_stack->target_ops != &nindy_ops) /* What is this crap??? */
+ { /* remote tty not specified yet */
+ if (instream == stdin)
+ {
+ printf_unfiltered ("\nAttach /dev/ttyNN -- specify NN, or \"quit\" to quit: ");
+ gdb_flush (gdb_stdout);
+ }
+ fgets (ttyname, sizeof (ttyname) - 1, stdin);
+
+ /* Strip leading and trailing whitespace */
+ for (p = ttyname; isspace (*p); p++)
+ {
+ ;
+ }
+ if (*p == '\0')
+ {
+ return; /* User just hit spaces or return, wants out */
+ }
+ for (p2 = p; !isspace (*p2) && (*p2 != '\0'); p2++)
+ {
+ ;
+ }
+ *p2 = '\0';
+ if (STREQ ("quit", p))
+ {
+ exit (1);
+ }
+
+ if (catch_errors (nindy_open_stub, p, "", RETURN_MASK_ALL))
+ {
+ /* Now that we have a tty open for talking to the remote machine,
+ download the executable file if one was specified. */
+ if (exec_bfd)
+ {
+ catch_errors (load_stub, bfd_get_filename (exec_bfd), "",
+ RETURN_MASK_ALL);
+ }
+ }
+ }
+}
+
+/* Define the target subroutine names */
+
+struct target_ops nindy_ops;
+
+static void
+init_nindy_ops (void)
+{
+ nindy_ops.to_shortname = "nindy";
+ "Remote serial target in i960 NINDY-specific protocol",
+ nindy_ops.to_longname = "Use a remote i960 system running NINDY connected by a serial line.\n\
+Specify the name of the device the serial line is connected to.\n\
+The speed (baud rate), whether to use the old NINDY protocol,\n\
+and whether to send a break on startup, are controlled by options\n\
+specified when you started GDB.";
+ nindy_ops.to_doc = "";
+ nindy_ops.to_open = nindy_open;
+ nindy_ops.to_close = nindy_close;
+ nindy_ops.to_attach = 0;
+ nindy_ops.to_post_attach = NULL;
+ nindy_ops.to_require_attach = NULL;
+ nindy_ops.to_detach = nindy_detach;
+ nindy_ops.to_require_detach = NULL;
+ nindy_ops.to_resume = nindy_resume;
+ nindy_ops.to_wait = nindy_wait;
+ nindy_ops.to_post_wait = NULL;
+ nindy_ops.to_fetch_registers = nindy_fetch_registers;
+ nindy_ops.to_store_registers = nindy_store_registers;
+ nindy_ops.to_prepare_to_store = nindy_prepare_to_store;
+ nindy_ops.to_xfer_memory = nindy_xfer_inferior_memory;
+ nindy_ops.to_files_info = nindy_files_info;
+ nindy_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ nindy_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ nindy_ops.to_terminal_init = 0;
+ nindy_ops.to_terminal_inferior = 0;
+ nindy_ops.to_terminal_ours_for_output = 0;
+ nindy_ops.to_terminal_ours = 0;
+ nindy_ops.to_terminal_info = 0; /* Terminal crud */
+ nindy_ops.to_kill = nindy_kill;
+ nindy_ops.to_load = nindy_load;
+ nindy_ops.to_lookup_symbol = 0; /* lookup_symbol */
+ nindy_ops.to_create_inferior = nindy_create_inferior;
+ nindy_ops.to_post_startup_inferior = NULL;
+ nindy_ops.to_acknowledge_created_inferior = NULL;
+ nindy_ops.to_clone_and_follow_inferior = NULL;
+ nindy_ops.to_post_follow_inferior_by_clone = NULL;
+ nindy_ops.to_insert_fork_catchpoint = NULL;
+ nindy_ops.to_remove_fork_catchpoint = NULL;
+ nindy_ops.to_insert_vfork_catchpoint = NULL;
+ nindy_ops.to_remove_vfork_catchpoint = NULL;
+ nindy_ops.to_has_forked = NULL;
+ nindy_ops.to_has_vforked = NULL;
+ nindy_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ nindy_ops.to_post_follow_vfork = NULL;
+ nindy_ops.to_insert_exec_catchpoint = NULL;
+ nindy_ops.to_remove_exec_catchpoint = NULL;
+ nindy_ops.to_has_execd = NULL;
+ nindy_ops.to_reported_exec_events_per_exec_call = NULL;
+ nindy_ops.to_has_exited = NULL;
+ nindy_ops.to_mourn_inferior = nindy_mourn_inferior;
+ nindy_ops.to_can_run = 0; /* can_run */
+ nindy_ops.to_notice_signals = 0; /* notice_signals */
+ nindy_ops.to_thread_alive = 0; /* to_thread_alive */
+ nindy_ops.to_stop = 0; /* to_stop */
+ nindy_ops.to_pid_to_exec_file = NULL;
+ nindy_ops.to_stratum = process_stratum;
+ nindy_ops.DONT_USE = 0; /* next */
+ nindy_ops.to_has_all_memory = 1;
+ nindy_ops.to_has_memory = 1;
+ nindy_ops.to_has_stack = 1;
+ nindy_ops.to_has_registers = 1;
+ nindy_ops.to_has_execution = 1; /* all mem, mem, stack, regs, exec */
+ nindy_ops.to_sections = 0;
+ nindy_ops.to_sections_end = 0; /* Section pointers */
+ nindy_ops.to_magic = OPS_MAGIC; /* Always the last thing */
+}
+
+void
+_initialize_nindy (void)
+{
+ init_nindy_ops ();
+ add_target (&nindy_ops);
+ add_com ("reset", class_obscure, reset_command,
+ "Send a 'break' to the remote target system.\n\
+Only useful if the target has been equipped with a circuit\n\
+to perform a hard reset when a break is detected.");
+}
diff --git a/gdb/remote-nrom.c b/gdb/remote-nrom.c
new file mode 100644
index 00000000000..436c3d272a6
--- /dev/null
+++ b/gdb/remote-nrom.c
@@ -0,0 +1,351 @@
+/* Remote debugging with the XLNT Designs, Inc (XDI) NetROM.
+ Copyright 1990, 1991, 1992, 1995, 1998, 1999, 2000
+ Free Software Foundation, Inc.
+ Contributed by:
+ Roger Moyers
+ XLNT Designs, Inc.
+ 15050 Avenue of Science, Suite 106
+ San Diego, CA 92128
+ (619)487-9320
+ roger@xlnt.com
+ Adapted from work done at Cygnus Support in remote-nindy.c,
+ later merged in by Stan Shebs at Cygnus.
+
+ 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 "defs.h"
+#include "gdbcmd.h"
+#include "serial.h"
+#include "target.h"
+
+/* Default ports used to talk with the NetROM. */
+
+#define DEFAULT_NETROM_LOAD_PORT 1236
+#define DEFAULT_NETROM_CONTROL_PORT 1237
+
+static void nrom_close (int quitting);
+
+/* New commands. */
+
+static void nrom_passthru (char *, int);
+
+/* We talk to the NetROM over these sockets. */
+
+static struct serial *load_desc = NULL;
+static struct serial *ctrl_desc = NULL;
+
+static int load_port = DEFAULT_NETROM_LOAD_PORT;
+static int control_port = DEFAULT_NETROM_CONTROL_PORT;
+
+static char nrom_hostname[100];
+
+/* Forward data declaration. */
+
+extern struct target_ops nrom_ops;
+
+/* Scan input from the remote system, until STRING is found. Print chars that
+ don't match. */
+
+static int
+expect (char *string)
+{
+ char *p = string;
+ int c;
+
+ immediate_quit++;
+
+ while (1)
+ {
+ c = serial_readchar (ctrl_desc, 5);
+
+ if (c == *p++)
+ {
+ if (*p == '\0')
+ {
+ immediate_quit--;
+ return 0;
+ }
+ }
+ else
+ {
+ fputc_unfiltered (c, gdb_stdout);
+ p = string;
+ if (c == *p)
+ p++;
+ }
+ }
+}
+
+static void
+nrom_kill (void)
+{
+ nrom_close (0);
+}
+
+static struct serial *
+open_socket (char *name, int port)
+{
+ char sockname[100];
+ struct serial *desc;
+
+ sprintf (sockname, "%s:%d", name, port);
+ desc = serial_open (sockname);
+ if (!desc)
+ perror_with_name (sockname);
+
+ return desc;
+}
+
+static void
+load_cleanup (void)
+{
+ serial_close (load_desc);
+ load_desc = NULL;
+}
+
+/* Download a file specified in ARGS to the netROM. */
+
+static void
+nrom_load (char *args, int fromtty)
+{
+ int fd, rd_amt, fsize;
+ bfd *pbfd;
+ asection *section;
+ char *downloadstring = "download 0\n";
+ struct cleanup *old_chain;
+
+ /* Tell the netrom to get ready to download. */
+ if (serial_write (ctrl_desc, downloadstring, strlen (downloadstring)))
+ error ("nrom_load: control_send() of `%s' failed", downloadstring);
+
+ expect ("Waiting for a connection...\n");
+
+ load_desc = open_socket (nrom_hostname, load_port);
+
+ old_chain = make_cleanup (load_cleanup, 0);
+
+ pbfd = bfd_openr (args, 0);
+
+ if (pbfd)
+ {
+ make_cleanup (bfd_close, pbfd);
+
+ if (!bfd_check_format (pbfd, bfd_object))
+ error ("\"%s\": not in executable format: %s",
+ args, bfd_errmsg (bfd_get_error ()));
+
+ for (section = pbfd->sections; section; section = section->next)
+ {
+ if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
+ {
+ bfd_vma section_address;
+ unsigned long section_size;
+ const char *section_name;
+
+ section_name = bfd_get_section_name (pbfd, section);
+ section_address = bfd_get_section_vma (pbfd, section);
+ section_size = bfd_section_size (pbfd, section);
+
+ if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
+ {
+ file_ptr fptr;
+
+ printf_filtered ("[Loading section %s at %x (%d bytes)]\n",
+ section_name, section_address,
+ section_size);
+
+ fptr = 0;
+
+ while (section_size > 0)
+ {
+ char buffer[1024];
+ int count;
+
+ count = min (section_size, 1024);
+
+ bfd_get_section_contents (pbfd, section, buffer, fptr,
+ count);
+
+ serial_write (load_desc, buffer, count);
+ section_address += count;
+ fptr += count;
+ section_size -= count;
+ }
+ }
+ else
+ /* BSS and such */
+ {
+ printf_filtered ("[section %s: not loading]\n",
+ section_name);
+ }
+ }
+ }
+ }
+ else
+ error ("\"%s\": Could not open", args);
+
+ do_cleanups (old_chain);
+}
+
+/* Open a connection to the remote NetROM devices. */
+
+static void
+nrom_open (char *name, int from_tty)
+{
+ int errn;
+
+ if (!name || strchr (name, '/') || strchr (name, ':'))
+ error (
+ "To open a NetROM connection, you must specify the hostname\n\
+or IP address of the NetROM device you wish to use.");
+
+ strcpy (nrom_hostname, name);
+
+ target_preopen (from_tty);
+
+ unpush_target (&nrom_ops);
+
+ ctrl_desc = open_socket (nrom_hostname, control_port);
+
+ push_target (&nrom_ops);
+
+ if (from_tty)
+ printf_filtered ("Connected to NetROM device \"%s\"\n", nrom_hostname);
+}
+
+/* Close out all files and local state before this target loses control. */
+
+static void
+nrom_close (int quitting)
+{
+ if (load_desc)
+ serial_close (load_desc);
+ if (ctrl_desc)
+ serial_close (ctrl_desc);
+}
+
+/* Pass arguments directly to the NetROM. */
+
+static void
+nrom_passthru (char *args, int fromtty)
+{
+ char buf[1024];
+
+ sprintf (buf, "%s\n", args);
+ if (serial_write (ctrl_desc, buf, strlen (buf)))
+ error ("nrom_reset: control_send() of `%s'failed", args);
+}
+
+static void
+nrom_mourn (void)
+{
+ unpush_target (&nrom_ops);
+ generic_mourn_inferior ();
+}
+
+/* Define the target vector. */
+
+struct target_ops nrom_ops;
+
+static void
+init_nrom_ops (void)
+{
+ nrom_ops.to_shortname = "nrom";
+ nrom_ops.to_longname = "Remote XDI `NetROM' target";
+ nrom_ops.to_doc = "Remote debug using a NetROM over Ethernet";
+ nrom_ops.to_open = nrom_open;
+ nrom_ops.to_close = nrom_close;
+ nrom_ops.to_attach = NULL;
+ nrom_ops.to_post_attach = NULL;
+ nrom_ops.to_require_attach = NULL;
+ nrom_ops.to_detach = NULL;
+ nrom_ops.to_require_detach = NULL;
+ nrom_ops.to_resume = NULL;
+ nrom_ops.to_wait = NULL;
+ nrom_ops.to_post_wait = NULL;
+ nrom_ops.to_fetch_registers = NULL;
+ nrom_ops.to_store_registers = NULL;
+ nrom_ops.to_prepare_to_store = NULL;
+ nrom_ops.to_xfer_memory = NULL;
+ nrom_ops.to_files_info = NULL;
+ nrom_ops.to_insert_breakpoint = NULL;
+ nrom_ops.to_remove_breakpoint = NULL;
+ nrom_ops.to_terminal_init = NULL;
+ nrom_ops.to_terminal_inferior = NULL;
+ nrom_ops.to_terminal_ours_for_output = NULL;
+ nrom_ops.to_terminal_ours = NULL;
+ nrom_ops.to_terminal_info = NULL;
+ nrom_ops.to_kill = nrom_kill;
+ nrom_ops.to_load = nrom_load;
+ nrom_ops.to_lookup_symbol = NULL;
+ nrom_ops.to_create_inferior = NULL;
+ nrom_ops.to_post_startup_inferior = NULL;
+ nrom_ops.to_acknowledge_created_inferior = NULL;
+ nrom_ops.to_clone_and_follow_inferior = NULL;
+ nrom_ops.to_post_follow_inferior_by_clone = NULL;
+ nrom_ops.to_insert_fork_catchpoint = NULL;
+ nrom_ops.to_remove_fork_catchpoint = NULL;
+ nrom_ops.to_insert_vfork_catchpoint = NULL;
+ nrom_ops.to_remove_vfork_catchpoint = NULL;
+ nrom_ops.to_has_forked = NULL;
+ nrom_ops.to_has_vforked = NULL;
+ nrom_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ nrom_ops.to_post_follow_vfork = NULL;
+ nrom_ops.to_insert_exec_catchpoint = NULL;
+ nrom_ops.to_remove_exec_catchpoint = NULL;
+ nrom_ops.to_has_execd = NULL;
+ nrom_ops.to_reported_exec_events_per_exec_call = NULL;
+ nrom_ops.to_has_exited = NULL;
+ nrom_ops.to_mourn_inferior = nrom_mourn;
+ nrom_ops.to_can_run = NULL;
+ nrom_ops.to_notice_signals = 0;
+ nrom_ops.to_thread_alive = 0;
+ nrom_ops.to_stop = 0;
+ nrom_ops.to_pid_to_exec_file = NULL;
+ nrom_ops.to_stratum = download_stratum;
+ nrom_ops.DONT_USE = NULL;
+ nrom_ops.to_has_all_memory = 1;
+ nrom_ops.to_has_memory = 1;
+ nrom_ops.to_has_stack = 1;
+ nrom_ops.to_has_registers = 1;
+ nrom_ops.to_has_execution = 0;
+ nrom_ops.to_sections = NULL;
+ nrom_ops.to_sections_end = NULL;
+ nrom_ops.to_magic = OPS_MAGIC;
+}
+
+void
+_initialize_remote_nrom (void)
+{
+ init_nrom_ops ();
+ add_target (&nrom_ops);
+
+ add_show_from_set (
+ add_set_cmd ("nrom_load_port", no_class, var_zinteger, (char *) &load_port,
+ "Set the port to use for NetROM downloads\n", &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("nrom_control_port", no_class, var_zinteger, (char *) &control_port,
+ "Set the port to use for NetROM debugger services\n", &setlist),
+ &showlist);
+
+ add_cmd ("nrom", no_class, nrom_passthru,
+ "Pass arguments as command to NetROM",
+ &cmdlist);
+}
diff --git a/gdb/remote-os9k.c b/gdb/remote-os9k.c
new file mode 100644
index 00000000000..0a703ebd3a5
--- /dev/null
+++ b/gdb/remote-os9k.c
@@ -0,0 +1,1234 @@
+/* Remote debugging interface for boot monitors, for GDB.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
+ 2000, 2001, 2002 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. */
+
+/* This file was derived from remote-eb.c, which did a similar job, but for
+ an AMD-29K running EBMON. That file was in turn derived from remote.c
+ as mentioned in the following comment (left in for comic relief):
+
+ "This is like remote.c but is for a different situation--
+ having a PC running os9000 hook up with a unix machine with
+ a serial line, and running ctty com2 on the PC. os9000 has a debug
+ monitor called ROMBUG running. Not to mention that the PC
+ has PC/NFS, so it can access the same executables that gdb can,
+ over the net in real time."
+
+ In reality, this module talks to a debug monitor called 'ROMBUG', which
+ We communicate with ROMBUG via a direct serial line, the network version
+ of ROMBUG is not available yet.
+ */
+
+/* FIXME This file needs to be rewritten if it's to work again, either
+ to self-contained or to use the new monitor interface. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "gdb_string.h"
+#include <sys/types.h>
+#include "command.h"
+#include "serial.h"
+#include "monitor.h"
+#include "remote-utils.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include "regcache.h"
+
+struct cmd_list_element *showlist;
+extern struct target_ops rombug_ops; /* Forward declaration */
+extern struct monitor_ops rombug_cmds; /* Forward declaration */
+extern struct cmd_list_element *setlist;
+extern struct cmd_list_element *unsetlist;
+extern int attach_flag;
+
+static void rombug_close ();
+static void rombug_fetch_register ();
+static void rombug_fetch_registers ();
+static void rombug_store_register ();
+#if 0
+static int sr_get_debug (); /* flag set by "set remotedebug" */
+#endif
+static int hashmark; /* flag set by "set hash" */
+static int rombug_is_open = 0;
+
+/* FIXME: Replace with sr_get_debug (). */
+#define LOG_FILE "monitor.log"
+FILE *log_file;
+static int monitor_log = 0;
+static int tty_xon = 0;
+static int tty_xoff = 0;
+
+static int timeout = 10;
+static int is_trace_mode = 0;
+/* Descriptor for I/O to remote machine. Initialize it to NULL */
+static struct serial *monitor_desc = NULL;
+
+static CORE_ADDR bufaddr = 0;
+static int buflen = 0;
+static char readbuf[16];
+
+/* Send data to monitor. Works just like printf. */
+static void
+printf_monitor (char *pattern,...)
+{
+ va_list args;
+ char buf[200];
+ int i;
+
+ va_start (args, pattern);
+
+ vsprintf (buf, pattern, args);
+ va_end (args);
+
+ if (serial_write (monitor_desc, buf, strlen (buf)))
+ fprintf_unfiltered (gdb_stderr, "serial_write failed: %s\n",
+ safe_strerror (errno));
+}
+
+/* Read a character from the remote system, doing all the fancy timeout stuff */
+static int
+readchar (int timeout)
+{
+ int c;
+
+ c = serial_readchar (monitor_desc, timeout);
+
+ if (sr_get_debug ())
+ putchar (c & 0x7f);
+
+ if (monitor_log && isascii (c))
+ putc (c & 0x7f, log_file);
+
+ if (c >= 0)
+ return c & 0x7f;
+
+ if (c == SERIAL_TIMEOUT)
+ {
+ if (timeout == 0)
+ return c; /* Polls shouldn't generate timeout errors */
+
+ error ("Timeout reading from remote system.");
+ }
+
+ perror_with_name ("remote-monitor");
+}
+
+/* Scan input from the remote system, until STRING is found. If DISCARD is
+ non-zero, then discard non-matching input, else print it out.
+ Let the user break out immediately. */
+static void
+expect (char *string, int discard)
+{
+ char *p = string;
+ int c;
+
+ if (sr_get_debug ())
+ printf ("Expecting \"%s\"\n", string);
+
+ immediate_quit++;
+ while (1)
+ {
+ c = readchar (timeout);
+ if (!isascii (c))
+ continue;
+ if (c == *p++)
+ {
+ if (*p == '\0')
+ {
+ immediate_quit--;
+ if (sr_get_debug ())
+ printf ("\nMatched\n");
+ return;
+ }
+ }
+ else
+ {
+ if (!discard)
+ {
+ fwrite (string, 1, (p - 1) - string, stdout);
+ putchar ((char) c);
+ fflush (stdout);
+ }
+ p = string;
+ }
+ }
+}
+
+/* Keep discarding input until we see the ROMBUG prompt.
+
+ The convention for dealing with the prompt is that you
+ o give your command
+ o *then* wait for the prompt.
+
+ Thus the last thing that a procedure does with the serial line
+ will be an expect_prompt(). Exception: rombug_resume does not
+ wait for the prompt, because the terminal is being handed over
+ to the inferior. However, the next thing which happens after that
+ is a rombug_wait which does wait for the prompt.
+ Note that this includes abnormal exit, e.g. error(). This is
+ necessary to prevent getting into states from which we can't
+ recover. */
+static void
+expect_prompt (int discard)
+{
+ if (monitor_log)
+ /* This is a convenient place to do this. The idea is to do it often
+ enough that we never lose much data if we terminate abnormally. */
+ fflush (log_file);
+
+ if (is_trace_mode)
+ {
+ expect ("trace", discard);
+ }
+ else
+ {
+ expect (PROMPT, discard);
+ }
+}
+
+/* Get a hex digit from the remote system & return its value.
+ If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
+static int
+get_hex_digit (int ignore_space)
+{
+ int ch;
+ while (1)
+ {
+ ch = readchar (timeout);
+ if (ch >= '0' && ch <= '9')
+ return ch - '0';
+ else if (ch >= 'A' && ch <= 'F')
+ return ch - 'A' + 10;
+ else if (ch >= 'a' && ch <= 'f')
+ return ch - 'a' + 10;
+ else if (ch == ' ' && ignore_space)
+ ;
+ else
+ {
+ expect_prompt (1);
+ error ("Invalid hex digit from remote system.");
+ }
+ }
+}
+
+/* Get a byte from monitor and put it in *BYT. Accept any number
+ leading spaces. */
+static void
+get_hex_byte (char *byt)
+{
+ int val;
+
+ val = get_hex_digit (1) << 4;
+ val |= get_hex_digit (0);
+ *byt = val;
+}
+
+/* Get N 32-bit words from remote, each preceded by a space,
+ and put them in registers starting at REGNO. */
+static void
+get_hex_regs (int n, int regno)
+{
+ long val;
+ int i;
+ unsigned char b;
+
+ for (i = 0; i < n; i++)
+ {
+ int j;
+
+ val = 0;
+ for (j = 0; j < 4; j++)
+ {
+ get_hex_byte (&b);
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ val = (val << 8) + b;
+ else
+ val = val + (b << (j * 8));
+ }
+ supply_register (regno++, (char *) &val);
+ }
+}
+
+/* This is called not only when we first attach, but also when the
+ user types "run" after having attached. */
+static void
+rombug_create_inferior (char *execfile, char *args, char **env)
+{
+ int entry_pt;
+
+ if (args && *args)
+ error ("Can't pass arguments to remote ROMBUG process");
+
+ if (execfile == 0 || exec_bfd == 0)
+ error ("No executable file specified");
+
+ entry_pt = (int) bfd_get_start_address (exec_bfd);
+
+ if (monitor_log)
+ fputs ("\nIn Create_inferior()", log_file);
+
+
+/* The "process" (board) is already stopped awaiting our commands, and
+ the program is already downloaded. We just set its PC and go. */
+
+ init_wait_for_inferior ();
+ proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0);
+}
+
+/* Open a connection to a remote debugger.
+ NAME is the filename used for communication. */
+
+static char dev_name[100];
+
+static void
+rombug_open (char *args, int from_tty)
+{
+ if (args == NULL)
+ error ("Use `target RomBug DEVICE-NAME' to use a serial port, or \n\
+`target RomBug HOST-NAME:PORT-NUMBER' to use a network connection.");
+
+ target_preopen (from_tty);
+
+ if (rombug_is_open)
+ unpush_target (&rombug_ops);
+
+ strcpy (dev_name, args);
+ monitor_desc = serial_open (dev_name);
+ if (monitor_desc == NULL)
+ perror_with_name (dev_name);
+
+ /* if baud rate is set by 'set remotebaud' */
+ if (serial_setbaudrate (monitor_desc, sr_get_baud_rate ()))
+ {
+ serial_close (monitor_desc);
+ perror_with_name ("RomBug");
+ }
+ serial_raw (monitor_desc);
+ if (tty_xon || tty_xoff)
+ {
+ struct hardware_ttystate
+ {
+ struct termios t;
+ }
+ *tty_s;
+
+ tty_s = (struct hardware_ttystate *) serial_get_tty_state (monitor_desc);
+ if (tty_xon)
+ tty_s->t.c_iflag |= IXON;
+ if (tty_xoff)
+ tty_s->t.c_iflag |= IXOFF;
+ serial_set_tty_state (monitor_desc, (serial_ttystate) tty_s);
+ }
+
+ rombug_is_open = 1;
+
+ log_file = fopen (LOG_FILE, "w");
+ if (log_file == NULL)
+ perror_with_name (LOG_FILE);
+
+ push_monitor (&rombug_cmds);
+ printf_monitor ("\r"); /* CR wakes up monitor */
+ expect_prompt (1);
+ push_target (&rombug_ops);
+ attach_flag = 1;
+
+ if (from_tty)
+ printf ("Remote %s connected to %s\n", target_shortname,
+ dev_name);
+
+ rombug_fetch_registers ();
+
+ printf_monitor ("ov e \r");
+ expect_prompt (1);
+ bufaddr = 0;
+ buflen = 0;
+}
+
+/*
+ * Close out all files and local state before this target loses control.
+ */
+
+static void
+rombug_close (int quitting)
+{
+ if (rombug_is_open)
+ {
+ serial_close (monitor_desc);
+ monitor_desc = NULL;
+ rombug_is_open = 0;
+ }
+
+ if (log_file)
+ {
+ if (ferror (log_file))
+ fprintf_unfiltered (gdb_stderr, "Error writing log file.\n");
+ if (fclose (log_file) != 0)
+ fprintf_unfiltered (gdb_stderr, "Error closing log file.\n");
+ log_file = 0;
+ }
+}
+
+int
+rombug_link (char *mod_name, CORE_ADDR *text_reloc)
+{
+ int i, j;
+ unsigned long val;
+ unsigned char b;
+
+ printf_monitor ("l %s \r", mod_name);
+ expect_prompt (1);
+ printf_monitor (".r \r");
+ expect (REG_DELIM, 1);
+ for (i = 0; i <= 7; i++)
+ {
+ val = 0;
+ for (j = 0; j < 4; j++)
+ {
+ get_hex_byte (&b);
+ val = (val << 8) + b;
+ }
+ }
+ expect_prompt (1);
+ *text_reloc = val;
+ return 1;
+}
+
+/* Terminate the open connection to the remote debugger.
+ Use this when you want to detach and do something else
+ with your gdb. */
+static void
+rombug_detach (int from_tty)
+{
+ if (attach_flag)
+ {
+ printf_monitor (GO_CMD);
+ attach_flag = 0;
+ }
+ pop_target (); /* calls rombug_close to do the real work */
+ if (from_tty)
+ printf ("Ending remote %s debugging\n", target_shortname);
+}
+
+/*
+ * Tell the remote machine to resume.
+ */
+static void
+rombug_resume (ptid_t ptid, int step, enum target_signal sig)
+{
+ if (monitor_log)
+ fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig);
+
+ if (step)
+ {
+ is_trace_mode = 1;
+ printf_monitor (STEP_CMD);
+ /* wait for the echo. **
+ expect (STEP_CMD, 1);
+ */
+ }
+ else
+ {
+ printf_monitor (GO_CMD);
+ /* swallow the echo. **
+ expect (GO_CMD, 1);
+ */
+ }
+ bufaddr = 0;
+ buflen = 0;
+}
+
+/*
+ * Wait until the remote machine stops, then return,
+ * storing status in status just as `wait' would.
+ */
+
+static ptid *
+rombug_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ int old_timeout = timeout;
+ struct section_offsets *offs;
+ CORE_ADDR addr, pc;
+ struct obj_section *obj_sec;
+
+ if (monitor_log)
+ fputs ("\nIn wait ()", log_file);
+
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = 0;
+
+ timeout = -1; /* Don't time out -- user program is running. */
+ expect ("eax:", 0); /* output any message before register display */
+ expect_prompt (1); /* Wait for prompt, outputting extraneous text */
+
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ timeout = old_timeout;
+ rombug_fetch_registers ();
+ bufaddr = 0;
+ buflen = 0;
+ pc = read_register (PC_REGNUM);
+ addr = read_register (DATABASE_REG);
+ obj_sec = find_pc_section (pc);
+ if (obj_sec != NULL)
+ {
+ if (obj_sec->objfile != symfile_objfile)
+ new_symfile_objfile (obj_sec->objfile, 1, 0);
+ offs = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
+ memcpy (offs, symfile_objfile->section_offsets, SIZEOF_SECTION_OFFSETS);
+ offs->offsets[SECT_OFF_DATA (symfile_objfile)] = addr;
+ offs->offsets[SECT_OFF_BSS (symfile_objfile)] = addr;
+
+ objfile_relocate (symfile_objfile, offs);
+ }
+
+ return inferior_ptid;
+}
+
+/* Return the name of register number regno in the form input and output by
+ monitor. Currently, register_names just happens to contain exactly what
+ monitor wants. Lets take advantage of that just as long as possible! */
+
+static char *
+get_reg_name (int regno)
+{
+ static char buf[50];
+ char *p;
+ char *b;
+
+ b = buf;
+
+ if (regno < 0)
+ return ("");
+/*
+ for (p = REGISTER_NAME (regno); *p; p++)
+ *b++ = toupper(*p);
+ *b = '\000';
+ */
+ p = (char *) REGISTER_NAME (regno);
+ return p;
+/*
+ return buf;
+ */
+}
+
+/* read the remote registers into the block regs. */
+
+static void
+rombug_fetch_registers (void)
+{
+ int regno, j, i;
+ long val;
+ unsigned char b;
+
+ printf_monitor (GET_REG);
+ expect ("eax:", 1);
+ expect ("\n", 1);
+ get_hex_regs (1, 0);
+ get_hex_regs (1, 3);
+ get_hex_regs (1, 1);
+ get_hex_regs (1, 2);
+ get_hex_regs (1, 6);
+ get_hex_regs (1, 7);
+ get_hex_regs (1, 5);
+ get_hex_regs (1, 4);
+ for (regno = 8; regno <= 15; regno++)
+ {
+ expect (REG_DELIM, 1);
+ if (regno >= 8 && regno <= 13)
+ {
+ val = 0;
+ for (j = 0; j < 2; j++)
+ {
+ get_hex_byte (&b);
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ val = (val << 8) + b;
+ else
+ val = val + (b << (j * 8));
+ }
+
+ if (regno == 8)
+ i = 10;
+ if (regno >= 9 && regno <= 12)
+ i = regno + 3;
+ if (regno == 13)
+ i = 11;
+ supply_register (i, (char *) &val);
+ }
+ else if (regno == 14)
+ {
+ get_hex_regs (1, PC_REGNUM);
+ }
+ else if (regno == 15)
+ {
+ get_hex_regs (1, 9);
+ }
+ else
+ {
+ val = 0;
+ supply_register (regno, (char *) &val);
+ }
+ }
+ is_trace_mode = 0;
+ expect_prompt (1);
+}
+
+/* Fetch register REGNO, or all registers if REGNO is -1.
+ Returns errno value. */
+static void
+rombug_fetch_register (int regno)
+{
+ int val, j;
+ unsigned char b;
+
+ if (monitor_log)
+ {
+ fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
+ fflush (log_file);
+ }
+
+ if (regno < 0)
+ {
+ rombug_fetch_registers ();
+ }
+ else
+ {
+ char *name = get_reg_name (regno);
+ printf_monitor (GET_REG);
+ if (regno >= 10 && regno <= 15)
+ {
+ expect ("\n", 1);
+ expect ("\n", 1);
+ expect (name, 1);
+ expect (REG_DELIM, 1);
+ val = 0;
+ for (j = 0; j < 2; j++)
+ {
+ get_hex_byte (&b);
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ val = (val << 8) + b;
+ else
+ val = val + (b << (j * 8));
+ }
+ supply_register (regno, (char *) &val);
+ }
+ else if (regno == 8 || regno == 9)
+ {
+ expect ("\n", 1);
+ expect ("\n", 1);
+ expect ("\n", 1);
+ expect (name, 1);
+ expect (REG_DELIM, 1);
+ get_hex_regs (1, regno);
+ }
+ else
+ {
+ expect (name, 1);
+ expect (REG_DELIM, 1);
+ expect ("\n", 1);
+ get_hex_regs (1, 0);
+ get_hex_regs (1, 3);
+ get_hex_regs (1, 1);
+ get_hex_regs (1, 2);
+ get_hex_regs (1, 6);
+ get_hex_regs (1, 7);
+ get_hex_regs (1, 5);
+ get_hex_regs (1, 4);
+ }
+ expect_prompt (1);
+ }
+ return;
+}
+
+/* Store the remote registers from the contents of the block REGS. */
+
+static void
+rombug_store_registers (void)
+{
+ int regno;
+
+ for (regno = 0; regno <= PC_REGNUM; regno++)
+ rombug_store_register (regno);
+
+ registers_changed ();
+}
+
+/* Store register REGNO, or all if REGNO == 0.
+ return errno value. */
+static void
+rombug_store_register (int regno)
+{
+ char *name;
+
+ if (monitor_log)
+ fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
+
+ if (regno == -1)
+ rombug_store_registers ();
+ else
+ {
+ if (sr_get_debug ())
+ printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
+
+ name = get_reg_name (regno);
+ if (name == 0)
+ return;
+ printf_monitor (SET_REG, name, read_register (regno));
+
+ is_trace_mode = 0;
+ expect_prompt (1);
+ }
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+static void
+rombug_prepare_to_store (void)
+{
+ /* Do nothing, since we can store individual regs */
+}
+
+static void
+rombug_files_info (void)
+{
+ printf ("\tAttached to %s at %d baud.\n",
+ dev_name, sr_get_baud_rate ());
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+ to inferior's memory at MEMADDR. Returns length moved. */
+static int
+rombug_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
+{
+ int i;
+ char buf[10];
+
+ if (monitor_log)
+ fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
+
+ printf_monitor (MEM_SET_CMD, memaddr);
+ for (i = 0; i < len; i++)
+ {
+ expect (CMD_DELIM, 1);
+ printf_monitor ("%x \r", myaddr[i]);
+ if (sr_get_debug ())
+ printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
+ }
+ expect (CMD_DELIM, 1);
+ if (CMD_END)
+ printf_monitor (CMD_END);
+ is_trace_mode = 0;
+ expect_prompt (1);
+
+ bufaddr = 0;
+ buflen = 0;
+ return len;
+}
+
+/* Read LEN bytes from inferior memory at MEMADDR. Put the result
+ at debugger address MYADDR. Returns length moved. */
+static int
+rombug_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ int i, j;
+
+ /* Number of bytes read so far. */
+ int count;
+
+ /* Starting address of this pass. */
+ unsigned long startaddr;
+
+ /* Number of bytes to read in this pass. */
+ int len_this_pass;
+
+ if (monitor_log)
+ fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
+
+ /* Note that this code works correctly if startaddr is just less
+ than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
+ thing). That is, something like
+ rombug_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
+ works--it never adds len To memaddr and gets 0. */
+ /* However, something like
+ rombug_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
+ doesn't need to work. Detect it and give up if there's an attempt
+ to do that. */
+ if (((memaddr - 1) + len) < memaddr)
+ {
+ errno = EIO;
+ return 0;
+ }
+ if (bufaddr <= memaddr && (memaddr + len) <= (bufaddr + buflen))
+ {
+ memcpy (myaddr, &readbuf[memaddr - bufaddr], len);
+ return len;
+ }
+
+ startaddr = memaddr;
+ count = 0;
+ while (count < len)
+ {
+ len_this_pass = 16;
+ if ((startaddr % 16) != 0)
+ len_this_pass -= startaddr % 16;
+ if (len_this_pass > (len - count))
+ len_this_pass = (len - count);
+ if (sr_get_debug ())
+ printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
+
+ printf_monitor (MEM_DIS_CMD, startaddr, 8);
+ expect ("- ", 1);
+ for (i = 0; i < 16; i++)
+ {
+ get_hex_byte (&readbuf[i]);
+ }
+ bufaddr = startaddr;
+ buflen = 16;
+ memcpy (&myaddr[count], readbuf, len_this_pass);
+ count += len_this_pass;
+ startaddr += len_this_pass;
+ expect (CMD_DELIM, 1);
+ }
+ if (CMD_END)
+ printf_monitor (CMD_END);
+ is_trace_mode = 0;
+ expect_prompt (1);
+
+ return len;
+}
+
+/* Transfer LEN bytes between GDB address MYADDR and target address
+ MEMADDR. If WRITE is non-zero, transfer them to the target,
+ otherwise transfer them from the target. TARGET is unused.
+
+ Returns the number of bytes transferred. */
+
+static int
+rombug_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int write, struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ if (write)
+ return rombug_write_inferior_memory (memaddr, myaddr, len);
+ else
+ return rombug_read_inferior_memory (memaddr, myaddr, len);
+}
+
+static void
+rombug_kill (char *args, int from_tty)
+{
+ return; /* ignore attempts to kill target system */
+}
+
+/* Clean up when a program exits.
+ The program actually lives on in the remote processor's RAM, and may be
+ run again without a download. Don't leave it full of breakpoint
+ instructions. */
+
+static void
+rombug_mourn_inferior (void)
+{
+ remove_breakpoints ();
+ generic_mourn_inferior (); /* Do all the proper things now */
+}
+
+#define MAX_MONITOR_BREAKPOINTS 16
+
+static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] =
+{0};
+
+static int
+rombug_insert_breakpoint (CORE_ADDR addr, char *shadow)
+{
+ int i;
+ CORE_ADDR bp_addr = addr;
+ int bp_size = 0;
+
+ if (monitor_log)
+ fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
+ BREAKPOINT_FROM_PC (&bp_addr, &bp_size);
+
+ for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
+ if (breakaddr[i] == 0)
+ {
+ breakaddr[i] = addr;
+ if (sr_get_debug ())
+ printf ("Breakpoint at %x\n", addr);
+ rombug_read_inferior_memory (bp_addr, shadow, bp_size);
+ printf_monitor (SET_BREAK_CMD, addr);
+ is_trace_mode = 0;
+ expect_prompt (1);
+ return 0;
+ }
+
+ fprintf_unfiltered (gdb_stderr, "Too many breakpoints (> 16) for monitor\n");
+ return 1;
+}
+
+/*
+ * _remove_breakpoint -- Tell the monitor to remove a breakpoint
+ */
+static int
+rombug_remove_breakpoint (CORE_ADDR addr, char *shadow)
+{
+ int i;
+
+ if (monitor_log)
+ fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
+
+ for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
+ if (breakaddr[i] == addr)
+ {
+ breakaddr[i] = 0;
+ printf_monitor (CLR_BREAK_CMD, addr);
+ is_trace_mode = 0;
+ expect_prompt (1);
+ return 0;
+ }
+
+ fprintf_unfiltered (gdb_stderr,
+ "Can't find breakpoint associated with 0x%x\n", addr);
+ return 1;
+}
+
+/* Load a file. This is usually an srecord, which is ascii. No
+ protocol, just sent line by line. */
+
+#define DOWNLOAD_LINE_SIZE 100
+static void
+rombug_load (char *arg)
+{
+/* this part comment out for os9* */
+#if 0
+ FILE *download;
+ char buf[DOWNLOAD_LINE_SIZE];
+ int i, bytes_read;
+
+ if (sr_get_debug ())
+ printf ("Loading %s to monitor\n", arg);
+
+ download = fopen (arg, "r");
+ if (download == NULL)
+ {
+ error (sprintf (buf, "%s Does not exist", arg));
+ return;
+ }
+
+ printf_monitor (LOAD_CMD);
+/* expect ("Waiting for S-records from host... ", 1); */
+
+ while (!feof (download))
+ {
+ bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
+ if (hashmark)
+ {
+ putchar ('.');
+ fflush (stdout);
+ }
+
+ if (serial_write (monitor_desc, buf, bytes_read))
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "serial_write failed: (while downloading) %s\n",
+ safe_strerror (errno));
+ break;
+ }
+ i = 0;
+ while (i++ <= 200000)
+ {
+ }; /* Ugly HACK, probably needs flow control */
+ if (bytes_read < DOWNLOAD_LINE_SIZE)
+ {
+ if (!feof (download))
+ error ("Only read %d bytes\n", bytes_read);
+ break;
+ }
+ }
+
+ if (hashmark)
+ {
+ putchar ('\n');
+ }
+ if (!feof (download))
+ error ("Never got EOF while downloading");
+ fclose (download);
+#endif /* 0 */
+}
+
+/* Put a command string, in args, out to MONITOR.
+ Output from MONITOR is placed on the users terminal until the prompt
+ is seen. */
+
+static void
+rombug_command (char *args, int fromtty)
+{
+ if (monitor_desc == NULL)
+ error ("monitor target not open.");
+
+ if (monitor_log)
+ fprintf (log_file, "\nIn command (args=%s)\n", args);
+
+ if (!args)
+ error ("Missing command.");
+
+ printf_monitor ("%s\r", args);
+ expect_prompt (0);
+}
+
+#if 0
+/* Connect the user directly to MONITOR. This command acts just like the
+ 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
+
+static struct ttystate ttystate;
+
+static void
+cleanup_tty (void)
+{
+ printf ("\r\n[Exiting connect mode]\r\n");
+ /*serial_restore(0, &ttystate); */
+}
+
+static void
+connect_command (char *args, int fromtty)
+{
+ fd_set readfds;
+ int numfds;
+ int c;
+ char cur_esc = 0;
+
+ dont_repeat ();
+
+ if (monitor_desc == NULL)
+ error ("monitor target not open.");
+
+ if (args)
+ fprintf ("This command takes no args. They have been ignored.\n");
+
+ printf ("[Entering connect mode. Use ~. or ~^D to escape]\n");
+
+ serial_raw (0, &ttystate);
+
+ make_cleanup (cleanup_tty, 0);
+
+ FD_ZERO (&readfds);
+
+ while (1)
+ {
+ do
+ {
+ FD_SET (0, &readfds);
+ FD_SET (deprecated_serial_fd (monitor_desc), &readfds);
+ numfds = select (sizeof (readfds) * 8, &readfds, 0, 0, 0);
+ }
+ while (numfds == 0);
+
+ if (numfds < 0)
+ perror_with_name ("select");
+
+ if (FD_ISSET (0, &readfds))
+ { /* tty input, send to monitor */
+ c = getchar ();
+ if (c < 0)
+ perror_with_name ("connect");
+
+ printf_monitor ("%c", c);
+ switch (cur_esc)
+ {
+ case 0:
+ if (c == '\r')
+ cur_esc = c;
+ break;
+ case '\r':
+ if (c == '~')
+ cur_esc = c;
+ else
+ cur_esc = 0;
+ break;
+ case '~':
+ if (c == '.' || c == '\004')
+ return;
+ else
+ cur_esc = 0;
+ }
+ }
+
+ if (FD_ISSET (deprecated_serial_fd (monitor_desc), &readfds))
+ {
+ while (1)
+ {
+ c = readchar (0);
+ if (c < 0)
+ break;
+ putchar (c);
+ }
+ fflush (stdout);
+ }
+ }
+}
+#endif
+
+/*
+ * Define the monitor command strings. Since these are passed directly
+ * through to a printf style function, we need can include formatting
+ * strings. We also need a CR or LF on the end.
+ */
+#warning FIXME: monitor interface pattern strings, stale struct decl
+struct monitor_ops rombug_cmds =
+{
+ "g \r", /* execute or usually GO command */
+ "g \r", /* continue command */
+ "t \r", /* single step */
+ "b %x\r", /* set a breakpoint */
+ "k %x\r", /* clear a breakpoint */
+ "c %x\r", /* set memory to a value */
+ "d %x %d\r", /* display memory */
+ "$%08X", /* prompt memory commands use */
+ ".%s %x\r", /* set a register */
+ ":", /* delimiter between registers */
+ ". \r", /* read a register */
+ "mf \r", /* download command */
+ "RomBug: ", /* monitor command prompt */
+ ": ", /* end-of-command delimitor */
+ ".\r" /* optional command terminator */
+};
+
+struct target_ops rombug_ops;
+
+static void
+init_rombug_ops (void)
+{
+ rombug_ops.to_shortname = "rombug";
+ rombug_ops.to_longname = "Microware's ROMBUG debug monitor";
+ rombug_ops.to_doc = "Use a remote computer running the ROMBUG debug monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).",
+ rombug_ops.to_open = rombug_open;
+ rombug_ops.to_close = rombug_close;
+ rombug_ops.to_attach = 0;
+ rombug_ops.to_post_attach = NULL;
+ rombug_ops.to_require_attach = NULL;
+ rombug_ops.to_detach = rombug_detach;
+ rombug_ops.to_require_detach = NULL;
+ rombug_ops.to_resume = rombug_resume;
+ rombug_ops.to_wait = rombug_wait;
+ rombug_ops.to_post_wait = NULL;
+ rombug_ops.to_fetch_registers = rombug_fetch_register;
+ rombug_ops.to_store_registers = rombug_store_register;
+ rombug_ops.to_prepare_to_store = rombug_prepare_to_store;
+ rombug_ops.to_xfer_memory = rombug_xfer_inferior_memory;
+ rombug_ops.to_files_info = rombug_files_info;
+ rombug_ops.to_insert_breakpoint = rombug_insert_breakpoint;
+ rombug_ops.to_remove_breakpoint = rombug_remove_breakpoint; /* Breakpoints */
+ rombug_ops.to_terminal_init = 0;
+ rombug_ops.to_terminal_inferior = 0;
+ rombug_ops.to_terminal_ours_for_output = 0;
+ rombug_ops.to_terminal_ours = 0;
+ rombug_ops.to_terminal_info = 0; /* Terminal handling */
+ rombug_ops.to_kill = rombug_kill;
+ rombug_ops.to_load = rombug_load; /* load */
+ rombug_ops.to_lookup_symbol = rombug_link; /* lookup_symbol */
+ rombug_ops.to_create_inferior = rombug_create_inferior;
+ rombug_ops.to_post_startup_inferior = NULL;
+ rombug_ops.to_acknowledge_created_inferior = NULL;
+ rombug_ops.to_clone_and_follow_inferior = NULL;
+ rombug_ops.to_post_follow_inferior_by_clone = NULL;
+ rombug_ops.to_insert_fork_catchpoint = NULL;
+ rombug_ops.to_remove_fork_catchpoint = NULL;
+ rombug_ops.to_insert_vfork_catchpoint = NULL;
+ rombug_ops.to_remove_vfork_catchpoint = NULL;
+ rombug_ops.to_has_forked = NULL;
+ rombug_ops.to_has_vforked = NULL;
+ rombug_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ rombug_ops.to_post_follow_vfork = NULL;
+ rombug_ops.to_insert_exec_catchpoint = NULL;
+ rombug_ops.to_remove_exec_catchpoint = NULL;
+ rombug_ops.to_has_execd = NULL;
+ rombug_ops.to_reported_exec_events_per_exec_call = NULL;
+ rombug_ops.to_has_exited = NULL;
+ rombug_ops.to_mourn_inferior = rombug_mourn_inferior;
+ rombug_ops.to_can_run = 0; /* can_run */
+ rombug_ops.to_notice_signals = 0; /* notice_signals */
+ rombug_ops.to_thread_alive = 0;
+ rombug_ops.to_stop = 0; /* to_stop */
+ rombug_ops.to_pid_to_exec_file = NULL;
+ rombug_ops.to_stratum = process_stratum;
+ rombug_ops.DONT_USE = 0; /* next */
+ rombug_ops.to_has_all_memory = 1;
+ rombug_ops.to_has_memory = 1;
+ rombug_ops.to_has_stack = 1;
+ rombug_ops.to_has_registers = 1;
+ rombug_ops.to_has_execution = 1; /* has execution */
+ rombug_ops.to_sections = 0;
+ rombug_ops.to_sections_end = 0; /* Section pointers */
+ rombug_ops.to_magic = OPS_MAGIC; /* Always the last thing */
+}
+
+void
+_initialize_remote_os9k (void)
+{
+ init_rombug_ops ();
+ add_target (&rombug_ops);
+
+ add_show_from_set (
+ add_set_cmd ("hash", no_class, var_boolean, (char *) &hashmark,
+ "Set display of activity while downloading a file.\nWhen enabled, a period \'.\' is displayed.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("timeout", no_class, var_zinteger,
+ (char *) &timeout,
+ "Set timeout in seconds for remote MIPS serial I/O.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("remotelog", no_class, var_zinteger,
+ (char *) &monitor_log,
+ "Set monitor activity log on(=1) or off(=0).",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("remotexon", no_class, var_zinteger,
+ (char *) &tty_xon,
+ "Set remote tty line XON control",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("remotexoff", no_class, var_zinteger,
+ (char *) &tty_xoff,
+ "Set remote tty line XOFF control",
+ &setlist),
+ &showlist);
+
+ add_com ("rombug <command>", class_obscure, rombug_command,
+ "Send a command to the debug monitor.");
+#if 0
+ add_com ("connect", class_obscure, connect_command,
+ "Connect the terminal directly up to a serial based command monitor.\nUse <CR>~. or <CR>~^D to break out.");
+#endif
+}
diff --git a/gdb/remote-rdi.c b/gdb/remote-rdi.c
new file mode 100644
index 00000000000..5243f9bd28f
--- /dev/null
+++ b/gdb/remote-rdi.c
@@ -0,0 +1,1070 @@
+/* GDB interface to ARM RDI library.
+
+ Copyright 1997, 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+#include "gdb_string.h"
+#include <fcntl.h>
+#include "frame.h"
+#include "inferior.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "target.h"
+#include "gdbcmd.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include "gdbthread.h"
+#include "gdbcore.h"
+#include "breakpoint.h"
+#include "completer.h"
+#include "regcache.h"
+#include "arm-tdep.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <signal.h>
+
+#include "rdi-share/ardi.h"
+#include "rdi-share/adp.h"
+#include "rdi-share/hsys.h"
+
+extern int isascii (int);
+
+/* Prototypes for local functions */
+
+static void arm_rdi_files_info (struct target_ops *ignore);
+
+static int arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr,
+ int len, int should_write,
+ struct mem_attrib *attrib,
+ struct target_ops *target);
+
+static void arm_rdi_prepare_to_store (void);
+
+static void arm_rdi_fetch_registers (int regno);
+
+static void arm_rdi_resume (ptid_t pid, int step,
+ enum target_signal siggnal);
+
+static int arm_rdi_start_remote (char *dummy);
+
+static void arm_rdi_open (char *name, int from_tty);
+
+static void arm_rdi_create_inferior (char *exec_file, char *args, char **env);
+
+static void arm_rdi_close (int quitting);
+
+static void arm_rdi_store_registers (int regno);
+
+static void arm_rdi_mourn (void);
+
+static void arm_rdi_send (char *buf);
+
+static ptid_t arm_rdi_wait (ptid_t ptid, struct target_waitstatus *status);
+
+static void arm_rdi_kill (void);
+
+static void arm_rdi_detach (char *args, int from_tty);
+
+static void arm_rdi_interrupt (int signo);
+
+static void arm_rdi_interrupt_twice (int signo);
+
+static void interrupt_query (void);
+
+static int arm_rdi_insert_breakpoint (CORE_ADDR, char *);
+
+static int arm_rdi_remove_breakpoint (CORE_ADDR, char *);
+
+static char *rdi_error_message (int err);
+
+static enum target_signal rdi_error_signal (int err);
+
+/* Global variables. */
+
+struct target_ops arm_rdi_ops;
+
+static struct Dbg_ConfigBlock gdb_config;
+
+static struct Dbg_HostosInterface gdb_hostif;
+
+static int max_load_size;
+
+static int execute_status;
+
+/* Send heatbeat packets? */
+static int rdi_heartbeat = 0;
+
+/* Target has ROM at address 0. */
+static int rom_at_zero = 0;
+
+/* Enable logging? */
+static int log_enable = 0;
+
+/* Name of the log file. Default is "rdi.log". */
+static char *log_filename;
+
+/* A little list of breakpoints that have been set. */
+
+static struct local_bp_list_entry
+ {
+ CORE_ADDR addr;
+ PointHandle point;
+ struct local_bp_list_entry *next;
+ }
+ *local_bp_list;
+
+
+/* Stub for catch_errors. */
+
+static int
+arm_rdi_start_remote (char *dummy)
+{
+ return 1;
+}
+
+/* Helper callbacks for the "host interface" structure. RDI functions call
+ these to forward output from the target system and so forth. */
+
+void
+voiddummy (void *dummy)
+{
+ fprintf_unfiltered (gdb_stdout, "void dummy\n");
+}
+
+static void
+myprint (void *arg, const char *format, va_list ap)
+{
+ vfprintf_unfiltered (gdb_stdout, format, ap);
+}
+
+static void
+mywritec (void *arg, int c)
+{
+ if (isascii (c))
+ fputc_unfiltered (c, gdb_stdout);
+}
+
+static int
+mywrite (void *arg, char const *buffer, int len)
+{
+ int i;
+ char *e;
+
+ e = (char *) buffer;
+ for (i = 0; i < len; i++)
+ {
+ if (isascii ((int) *e))
+ {
+ fputc_unfiltered ((int) *e, gdb_stdout);
+ e++;
+ }
+ }
+
+ return len;
+}
+
+static void
+mypause (void *arg)
+{
+}
+
+/* These last two are tricky as we have to handle the special case of
+ being interrupted more carefully */
+
+static int
+myreadc (void *arg)
+{
+ return fgetc (stdin);
+}
+
+static char *
+mygets (void *arg, char *buffer, int len)
+{
+ return fgets (buffer, len, stdin);
+}
+
+/* Prevent multiple calls to angel_RDI_close(). */
+static int closed_already = 1;
+
+/* Open a connection to a remote debugger. NAME is the filename used
+ for communication. */
+
+static void
+arm_rdi_open (char *name, int from_tty)
+{
+ int rslt, i;
+ unsigned long arg1, arg2;
+ char *openArgs = NULL;
+ char *devName = NULL;
+ char *p;
+
+ if (name == NULL)
+ error ("To open an RDI connection, you need to specify what serial\n\
+device is attached to the remote system (e.g. /dev/ttya).");
+
+ /* split name after whitespace, pass tail as arg to open command */
+
+ devName = xstrdup (name);
+ p = strchr (devName, ' ');
+ if (p)
+ {
+ *p = '\0';
+ ++p;
+
+ while (*p == ' ')
+ ++p;
+
+ openArgs = p;
+ }
+
+ /* Make the basic low-level connection. */
+
+ arm_rdi_close (0);
+ rslt = Adp_OpenDevice (devName, openArgs, rdi_heartbeat);
+
+ if (rslt != adp_ok)
+ error ("Could not open device \"%s\"", name);
+
+ gdb_config.bytesex = 2 | (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 1 : 0);
+ gdb_config.fpe = 1;
+ gdb_config.rditype = 2;
+ gdb_config.heartbeat_on = 1;
+ gdb_config.flags = 2;
+
+ gdb_hostif.dbgprint = myprint;
+ gdb_hostif.dbgpause = mypause;
+ gdb_hostif.dbgarg = NULL;
+ gdb_hostif.writec = mywritec;
+ gdb_hostif.readc = myreadc;
+ gdb_hostif.write = mywrite;
+ gdb_hostif.gets = mygets;
+ gdb_hostif.hostosarg = NULL;
+ gdb_hostif.reset = voiddummy;
+
+ rslt = angel_RDI_open (10, &gdb_config, &gdb_hostif, NULL);
+ if (rslt == RDIError_BigEndian || rslt == RDIError_LittleEndian)
+ ; /* do nothing, this is the expected return */
+ else if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
+ Adp_CloseDevice ();
+ error ("RDI_open failed\n");
+ }
+
+ rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ rslt = angel_RDI_info (RDIInfo_Points, &arg1, &arg2);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ rslt = angel_RDI_info (RDIInfo_CoPro, &arg1, &arg2);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ rslt = angel_RDI_info (RDIInfo_SemiHosting, &arg1, &arg2);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+
+ rslt = angel_RDI_info (RDIInfo_GetLoadSize, &arg1, &arg2);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ max_load_size = arg1;
+
+ push_target (&arm_rdi_ops);
+
+ target_fetch_registers (-1);
+
+ rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
+ }
+
+ arg1 = rom_at_zero ? 0x0 : 0x13b;
+
+ rslt = angel_RDI_info (RDIVector_Catch, &arg1, &arg2);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+
+ arg1 = (unsigned long) "";
+ rslt = angel_RDI_info (RDISet_Cmdline, &arg1, &arg2);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+
+ /* Clear out any existing records of breakpoints. */
+ {
+ struct local_bp_list_entry *entry, *preventry = NULL;
+
+ for (entry = local_bp_list; entry != NULL; entry = entry->next)
+ {
+ if (preventry)
+ xfree (preventry);
+ }
+ }
+
+ printf_filtered ("Connected to ARM RDI target.\n");
+ closed_already = 0;
+ inferior_ptid = pid_to_ptid (42);
+}
+
+/* Start an inferior process and set inferior_ptid to its pid.
+ EXEC_FILE is the file to run.
+ ARGS is a string containing the arguments to the program.
+ ENV is the environment vector to pass. Errors reported with error().
+ On VxWorks and various standalone systems, we ignore exec_file. */
+/* This is called not only when we first attach, but also when the
+ user types "run" after having attached. */
+
+static void
+arm_rdi_create_inferior (char *exec_file, char *args, char **env)
+{
+ int len, rslt;
+ unsigned long arg1, arg2;
+ char *arg_buf;
+ CORE_ADDR entry_point;
+
+ if (exec_file == 0 || exec_bfd == 0)
+ error ("No executable file specified.");
+
+ entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
+
+ arm_rdi_kill ();
+ remove_breakpoints ();
+ init_wait_for_inferior ();
+
+ len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10;
+ arg_buf = (char *) alloca (len);
+ arg_buf[0] = '\0';
+ strcat (arg_buf, exec_file);
+ strcat (arg_buf, " ");
+ strcat (arg_buf, args);
+
+ inferior_ptid = pid_to_ptid (42);
+ insert_breakpoints (); /* Needed to get correct instruction in cache */
+
+ if (env != NULL)
+ {
+ while (*env)
+ {
+ if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
+ {
+ unsigned long top_of_memory;
+ char *end_of_num;
+
+ /* Set up memory limit */
+ top_of_memory = strtoul (*env + sizeof ("MEMSIZE=") - 1,
+ &end_of_num, 0);
+ printf_filtered ("Setting top-of-memory to 0x%lx\n",
+ top_of_memory);
+
+ rslt = angel_RDI_info (RDIInfo_SetTopMem, &top_of_memory, &arg2);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ }
+ env++;
+ }
+ }
+
+ arg1 = (unsigned long) arg_buf;
+ rslt = angel_RDI_info (RDISet_Cmdline, /* &arg1 */ (unsigned long *) arg_buf, &arg2);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+
+ proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
+}
+
+/* This takes a program previously attached to and detaches it. After
+ this is done, GDB can be used to debug some other program. We
+ better not have left any breakpoints in the target program or it'll
+ die when it hits one. */
+
+static void
+arm_rdi_detach (char *args, int from_tty)
+{
+ pop_target ();
+}
+
+/* Clean up connection to a remote debugger. */
+
+static void
+arm_rdi_close (int quitting)
+{
+ int rslt;
+
+ if (!closed_already)
+ {
+ rslt = angel_RDI_close ();
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_close: %s\n", rdi_error_message (rslt));
+ }
+ closed_already = 1;
+ inferior_ptid = null_ptid;
+ Adp_CloseDevice ();
+ generic_mourn_inferior ();
+ }
+}
+
+/* Tell the remote machine to resume. */
+
+static void
+arm_rdi_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ int rslt;
+ PointHandle point;
+
+ if (0 /* turn on when hardware supports single-stepping */ )
+ {
+ rslt = angel_RDI_step (1, &point);
+ if (rslt != RDIError_NoError)
+ printf_filtered ("RDI_step: %s\n", rdi_error_message (rslt));
+ }
+ else
+ {
+ char handle[4];
+ CORE_ADDR pc = 0;
+
+ if (step)
+ {
+ pc = read_register (ARM_PC_REGNUM);
+ pc = arm_get_next_pc (pc);
+ arm_rdi_insert_breakpoint (pc, handle);
+ }
+
+ execute_status = rslt = angel_RDI_execute (&point);
+ if (rslt != RDIError_NoError && rslt != RDIError_BreakpointReached)
+ printf_filtered ("RDI_execute: %s\n", rdi_error_message (rslt));
+
+ if (step)
+ arm_rdi_remove_breakpoint (pc, handle);
+ }
+}
+
+/* Send ^C to target to halt it. Target will respond, and send us a
+ packet. */
+
+static void
+arm_rdi_interrupt (int signo)
+{
+}
+
+static void (*ofunc) ();
+
+/* The user typed ^C twice. */
+static void
+arm_rdi_interrupt_twice (int signo)
+{
+}
+
+/* Ask the user what to do when an interrupt is received. */
+
+static void
+interrupt_query (void)
+{
+}
+
+/* Wait until the remote machine stops, then return, storing status in
+ STATUS just as `wait' would. Returns "pid" (though it's not clear
+ what, if anything, that means in the case of this target). */
+
+static ptid_t
+arm_rdi_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ status->kind = (execute_status == RDIError_NoError ?
+ TARGET_WAITKIND_EXITED : TARGET_WAITKIND_STOPPED);
+
+ /* convert stopped code from target into right signal */
+ status->value.sig = rdi_error_signal (execute_status);
+
+ return inferior_ptid;
+}
+
+/* Read the remote registers into the block REGS. */
+
+/* ARGSUSED */
+static void
+arm_rdi_fetch_registers (int regno)
+{
+ int rslt, rdi_regmask;
+ unsigned long rawreg, rawregs[32];
+ char cookedreg[4];
+
+ if (regno == -1)
+ {
+ rslt = angel_RDI_CPUread (255, 0x27fff, rawregs);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt));
+ }
+
+ for (regno = 0; regno < 15; regno++)
+ {
+ store_unsigned_integer (cookedreg, 4, rawregs[regno]);
+ supply_register (regno, (char *) cookedreg);
+ }
+ store_unsigned_integer (cookedreg, 4, rawregs[15]);
+ supply_register (ARM_PS_REGNUM, (char *) cookedreg);
+ arm_rdi_fetch_registers (ARM_PC_REGNUM);
+ }
+ else
+ {
+ if (regno == ARM_PC_REGNUM)
+ rdi_regmask = RDIReg_PC;
+ else if (regno == ARM_PS_REGNUM)
+ rdi_regmask = RDIReg_CPSR;
+ else if (regno < 0 || regno > 15)
+ {
+ rawreg = 0;
+ supply_register (regno, (char *) &rawreg);
+ return;
+ }
+ else
+ rdi_regmask = 1 << regno;
+
+ rslt = angel_RDI_CPUread (255, rdi_regmask, &rawreg);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt));
+ }
+ store_unsigned_integer (cookedreg, 4, rawreg);
+ supply_register (regno, (char *) cookedreg);
+ }
+}
+
+static void
+arm_rdi_prepare_to_store (void)
+{
+ /* Nothing to do. */
+}
+
+/* Store register REGNO, or all registers if REGNO == -1, from the contents
+ of REGISTERS. FIXME: ignores errors. */
+
+static void
+arm_rdi_store_registers (int regno)
+{
+ int rslt, rdi_regmask;
+
+ /* These need to be able to take 'floating point register' contents */
+ unsigned long rawreg[3], rawerreg[3];
+
+ if (regno == -1)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ arm_rdi_store_registers (regno);
+ }
+ else
+ {
+ read_register_gen (regno, (char *) rawreg);
+ /* RDI manipulates data in host byte order, so convert now. */
+ store_unsigned_integer (rawerreg, 4, rawreg[0]);
+
+ if (regno == ARM_PC_REGNUM)
+ rdi_regmask = RDIReg_PC;
+ else if (regno == ARM_PS_REGNUM)
+ rdi_regmask = RDIReg_CPSR;
+ else if (regno < 0 || regno > 15)
+ return;
+ else
+ rdi_regmask = 1 << regno;
+
+ rslt = angel_RDI_CPUwrite (255, rdi_regmask, rawerreg);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_CPUwrite: %s\n", rdi_error_message (rslt));
+ }
+ }
+}
+
+/* Read or write LEN bytes from inferior memory at MEMADDR,
+ transferring to or from debugger address MYADDR. Write to inferior
+ if SHOULD_WRITE is nonzero. Returns length of data written or
+ read; 0 for error. TARGET is unused. */
+
+/* ARGSUSED */
+static int
+arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int should_write, struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ int rslt, i;
+
+ if (should_write)
+ {
+ rslt = angel_RDI_write (myaddr, memaddr, &len);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_write: %s\n", rdi_error_message (rslt));
+ }
+ }
+ else
+ {
+ rslt = angel_RDI_read (memaddr, myaddr, &len);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_read: %s\n", rdi_error_message (rslt));
+ len = 0;
+ }
+ }
+ return len;
+}
+
+/* Display random info collected from the target. */
+
+static void
+arm_rdi_files_info (struct target_ops *ignore)
+{
+ char *file = "nothing";
+ int rslt;
+ unsigned long arg1, arg2;
+
+ rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ if (arg1 & (1 << 15))
+ printf_filtered ("Target supports Thumb code.\n");
+ if (arg1 & (1 << 14))
+ printf_filtered ("Target can do profiling.\n");
+ if (arg1 & (1 << 4))
+ printf_filtered ("Target is real hardware.\n");
+
+ rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ printf_filtered ("Target can%s single-step.\n", (arg1 & 0x4 ? "" : "not"));
+
+ rslt = angel_RDI_info (RDIInfo_Icebreaker, &arg1, &arg2);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
+ }
+ else
+ printf_filtered ("Target includes an EmbeddedICE.\n");
+}
+
+static void
+arm_rdi_kill (void)
+{
+ int rslt;
+
+ rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
+ }
+}
+
+static void
+arm_rdi_mourn_inferior (void)
+{
+ /* We remove the inserted breakpoints in case the user wants to
+ issue another target and load commands to rerun his application;
+ This is something that wouldn't work on a native target, for instance,
+ as the process goes away when the inferior exits, but it works with
+ some remote targets like this one. That is why this is done here. */
+ remove_breakpoints();
+ unpush_target (&arm_rdi_ops);
+ generic_mourn_inferior ();
+}
+
+/* While the RDI library keeps track of its own breakpoints, we need
+ to remember "handles" so that we can delete them later. Since
+ breakpoints get used for stepping, be careful not to leak memory
+ here. */
+
+static int
+arm_rdi_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ int rslt;
+ PointHandle point;
+ struct local_bp_list_entry *entry;
+ int type = RDIPoint_EQ;
+
+ if (arm_pc_is_thumb (addr) || arm_pc_is_thumb_dummy (addr))
+ type |= RDIPoint_16Bit;
+ rslt = angel_RDI_setbreak (addr, type, 0, &point);
+ if (rslt != RDIError_NoError)
+ {
+ printf_filtered ("RDI_setbreak: %s\n", rdi_error_message (rslt));
+ }
+ entry =
+ (struct local_bp_list_entry *) xmalloc (sizeof (struct local_bp_list_entry));
+ entry->addr = addr;
+ entry->point = point;
+ entry->next = local_bp_list;
+ local_bp_list = entry;
+ return rslt;
+}
+
+static int
+arm_rdi_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ int rslt;
+ PointHandle point;
+ struct local_bp_list_entry **entryp, *dead;
+
+ for (entryp = &local_bp_list; *entryp != NULL; entryp = &(*entryp)->next)
+ if ((*entryp)->addr == addr)
+ break;
+
+ if (*entryp)
+ {
+ dead = *entryp;
+ rslt = angel_RDI_clearbreak (dead->point);
+ if (rslt != RDIError_NoError)
+ printf_filtered ("RDI_clearbreak: %s\n", rdi_error_message (rslt));
+
+ /* Delete the breakpoint entry locally. */
+ *entryp = dead->next;
+ xfree (dead);
+ }
+
+ return 0;
+}
+
+
+static char *
+rdi_error_message (int err)
+{
+ switch (err)
+ {
+ case RDIError_NoError:
+ return "no error";
+ case RDIError_Reset:
+ return "debuggee reset";
+ case RDIError_UndefinedInstruction:
+ return "undefined instruction";
+ case RDIError_SoftwareInterrupt:
+ return "SWI trapped";
+ case RDIError_PrefetchAbort:
+ return "prefetch abort, execution ran into unmapped memory?";
+ case RDIError_DataAbort:
+ return "data abort, no memory at specified address?";
+ case RDIError_AddressException:
+ return "address exception, access >26bit in 26bit mode";
+ case RDIError_IRQ:
+ return "IRQ, interrupt trapped";
+ case RDIError_FIQ:
+ return "FIQ, fast interrupt trapped";
+ case RDIError_Error:
+ return "a miscellaneous type of error";
+ case RDIError_BranchThrough0:
+ return "branch through location 0";
+ case RDIError_NotInitialised:
+ return "internal error, RDI_open not called first";
+ case RDIError_UnableToInitialise:
+ return "internal error, target world is broken";
+ case RDIError_WrongByteSex:
+ return "See Operator: WrongByteSex";
+ case RDIError_UnableToTerminate:
+ return "See Operator: Unable to Terminate";
+ case RDIError_BadInstruction:
+ return "bad instruction, illegal to execute this instruction";
+ case RDIError_IllegalInstruction:
+ return "illegal instruction, the effect of executing it is undefined";
+ case RDIError_BadCPUStateSetting:
+ return "internal error, tried to set SPSR of user mode";
+ case RDIError_UnknownCoPro:
+ return "unknown co-processor";
+ case RDIError_UnknownCoProState:
+ return "cannot execute co-processor request";
+ case RDIError_BadCoProState:
+ return "recognizably broken co-processor request";
+ case RDIError_BadPointType:
+ return "internal error, bad point yype";
+ case RDIError_UnimplementedType:
+ return "internal error, unimplemented type";
+ case RDIError_BadPointSize:
+ return "internal error, bad point size";
+ case RDIError_UnimplementedSize:
+ return "internal error, unimplemented size";
+ case RDIError_NoMorePoints:
+ return "last break/watch point was used";
+ case RDIError_BreakpointReached:
+ return "breakpoint reached";
+ case RDIError_WatchpointAccessed:
+ return "watchpoint accessed";
+ case RDIError_NoSuchPoint:
+ return "attempted to clear non-existent break/watch point";
+ case RDIError_ProgramFinishedInStep:
+ return "end of the program reached while stepping";
+ case RDIError_UserInterrupt:
+ return "you pressed Escape";
+ case RDIError_CantSetPoint:
+ return "no more break/watch points available";
+ case RDIError_IncompatibleRDILevels:
+ return "incompatible RDI levels";
+ case RDIError_LittleEndian:
+ return "debuggee is little endian";
+ case RDIError_BigEndian:
+ return "debuggee is big endian";
+ case RDIError_SoftInitialiseError:
+ return "recoverable error in RDI initialization";
+ case RDIError_InsufficientPrivilege:
+ return "internal error, supervisor state not accessible to monitor";
+ case RDIError_UnimplementedMessage:
+ return "internal error, unimplemented message";
+ case RDIError_UndefinedMessage:
+ return "internal error, undefined message";
+ default:
+ return "undefined error message, should reset target";
+ }
+}
+
+/* Convert the ARM error messages to signals that GDB knows about. */
+
+static enum target_signal
+rdi_error_signal (int err)
+{
+ switch (err)
+ {
+ case RDIError_NoError:
+ return 0;
+ case RDIError_Reset:
+ return TARGET_SIGNAL_TERM; /* ??? */
+ case RDIError_UndefinedInstruction:
+ return TARGET_SIGNAL_ILL;
+ case RDIError_SoftwareInterrupt:
+ case RDIError_PrefetchAbort:
+ case RDIError_DataAbort:
+ return TARGET_SIGNAL_TRAP;
+ case RDIError_AddressException:
+ return TARGET_SIGNAL_SEGV;
+ case RDIError_IRQ:
+ case RDIError_FIQ:
+ return TARGET_SIGNAL_TRAP;
+ case RDIError_Error:
+ return TARGET_SIGNAL_TERM;
+ case RDIError_BranchThrough0:
+ return TARGET_SIGNAL_TRAP;
+ case RDIError_NotInitialised:
+ case RDIError_UnableToInitialise:
+ case RDIError_WrongByteSex:
+ case RDIError_UnableToTerminate:
+ return TARGET_SIGNAL_UNKNOWN;
+ case RDIError_BadInstruction:
+ case RDIError_IllegalInstruction:
+ return TARGET_SIGNAL_ILL;
+ case RDIError_BadCPUStateSetting:
+ case RDIError_UnknownCoPro:
+ case RDIError_UnknownCoProState:
+ case RDIError_BadCoProState:
+ case RDIError_BadPointType:
+ case RDIError_UnimplementedType:
+ case RDIError_BadPointSize:
+ case RDIError_UnimplementedSize:
+ case RDIError_NoMorePoints:
+ return TARGET_SIGNAL_UNKNOWN;
+ case RDIError_BreakpointReached:
+ case RDIError_WatchpointAccessed:
+ return TARGET_SIGNAL_TRAP;
+ case RDIError_NoSuchPoint:
+ case RDIError_ProgramFinishedInStep:
+ return TARGET_SIGNAL_UNKNOWN;
+ case RDIError_UserInterrupt:
+ return TARGET_SIGNAL_INT;
+ case RDIError_IncompatibleRDILevels:
+ case RDIError_LittleEndian:
+ case RDIError_BigEndian:
+ case RDIError_SoftInitialiseError:
+ case RDIError_InsufficientPrivilege:
+ case RDIError_UnimplementedMessage:
+ case RDIError_UndefinedMessage:
+ default:
+ return TARGET_SIGNAL_UNKNOWN;
+ }
+}
+
+static void
+arm_rdi_stop(void)
+{
+ angel_RDI_stop_request();
+}
+
+
+/* Define the target operations structure. */
+
+static void
+init_rdi_ops (void)
+{
+ arm_rdi_ops.to_shortname = "rdi";
+ arm_rdi_ops.to_longname = "ARM RDI";
+ arm_rdi_ops.to_doc = "Use a remote ARM-based computer; via the RDI library.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ arm_rdi_ops.to_open = arm_rdi_open;
+ arm_rdi_ops.to_close = arm_rdi_close;
+ arm_rdi_ops.to_detach = arm_rdi_detach;
+ arm_rdi_ops.to_resume = arm_rdi_resume;
+ arm_rdi_ops.to_wait = arm_rdi_wait;
+ arm_rdi_ops.to_stop = arm_rdi_stop;
+ arm_rdi_ops.to_fetch_registers = arm_rdi_fetch_registers;
+ arm_rdi_ops.to_store_registers = arm_rdi_store_registers;
+ arm_rdi_ops.to_prepare_to_store = arm_rdi_prepare_to_store;
+ arm_rdi_ops.to_xfer_memory = arm_rdi_xfer_memory;
+ arm_rdi_ops.to_files_info = arm_rdi_files_info;
+ arm_rdi_ops.to_insert_breakpoint = arm_rdi_insert_breakpoint;
+ arm_rdi_ops.to_remove_breakpoint = arm_rdi_remove_breakpoint;
+ arm_rdi_ops.to_kill = arm_rdi_kill;
+ arm_rdi_ops.to_load = generic_load;
+ arm_rdi_ops.to_create_inferior = arm_rdi_create_inferior;
+ arm_rdi_ops.to_mourn_inferior = arm_rdi_mourn_inferior;
+ arm_rdi_ops.to_stratum = process_stratum;
+ arm_rdi_ops.to_has_all_memory = 1;
+ arm_rdi_ops.to_has_memory = 1;
+ arm_rdi_ops.to_has_stack = 1;
+ arm_rdi_ops.to_has_registers = 1;
+ arm_rdi_ops.to_has_execution = 1;
+ arm_rdi_ops.to_magic = OPS_MAGIC;
+}
+
+static void
+rdilogfile_command (char *arg, int from_tty)
+{
+ if (!arg || strlen (arg) == 0)
+ {
+ printf_filtered ("rdi log file is '%s'\n", log_filename);
+ return;
+ }
+
+ if (log_filename)
+ xfree (log_filename);
+
+ log_filename = xstrdup (arg);
+
+ Adp_SetLogfile (log_filename);
+}
+
+static void
+rdilogenable_command (char *args, int from_tty)
+{
+ if (!args || strlen (args) == 0)
+ {
+ printf_filtered ("rdi log is %s\n", log_enable ? "enabled" : "disabled");
+ return;
+ }
+
+ if (!strcasecmp (args, "1") ||
+ !strcasecmp (args, "y") ||
+ !strcasecmp (args, "yes") ||
+ !strcasecmp (args, "on") ||
+ !strcasecmp (args, "t") ||
+ !strcasecmp (args, "true"))
+ Adp_SetLogEnable (log_enable = 1);
+ else if (!strcasecmp (args, "0") ||
+ !strcasecmp (args, "n") ||
+ !strcasecmp (args, "no") ||
+ !strcasecmp (args, "off") ||
+ !strcasecmp (args, "f") ||
+ !strcasecmp (args, "false"))
+ Adp_SetLogEnable (log_enable = 0);
+ else
+ printf_filtered ("rdilogenable: unrecognized argument '%s'\n"
+ " try y or n\n", args);
+}
+
+void
+_initialize_remote_rdi (void)
+{
+ struct cmd_list_element *c;
+
+ init_rdi_ops ();
+ add_target (&arm_rdi_ops);
+
+ log_filename = xstrdup ("rdi.log");
+ Adp_SetLogfile (log_filename);
+ Adp_SetLogEnable (log_enable);
+
+ c = add_cmd ("rdilogfile", class_maintenance,
+ rdilogfile_command,
+ "Set filename for ADP packet log.\n"
+ "This file is used to log Angel Debugger Protocol packets.\n"
+ "With a single argument, sets the logfile name to that value.\n"
+ "Without an argument, shows the current logfile name.\n"
+ "See also: rdilogenable\n",
+ &maintenancelist);
+ set_cmd_completer (c, filename_completer);
+
+ add_cmd ("rdilogenable", class_maintenance,
+ rdilogenable_command,
+ "Set enable logging of ADP packets.\n"
+ "This will log ADP packets exchanged between gdb and the\n"
+ "rdi target device.\n"
+ "An argument of 1, t, true, y or yes will enable.\n"
+ "An argument of 0, f, false, n or no will disabled.\n"
+ "Withough an argument, it will display current state.\n",
+ &maintenancelist);
+
+ add_show_from_set
+ (add_set_boolean_cmd
+ ("rdiromatzero", no_class, &rom_at_zero,
+ "Set target has ROM at addr 0.\n"
+ "A true value disables vector catching, false enables vector catching.\n"
+ "This is evaluated at the time the 'target rdi' command is executed\n",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_boolean_cmd
+ ("rdiheartbeat", no_class, &rdi_heartbeat,
+ "Set enable for ADP heartbeat packets.\n"
+ "I don't know why you would want this. If you enable them,\n"
+ "it will confuse ARM and EPI JTAG interface boxes as well\n"
+ "as the Angel Monitor.\n",
+ &setlist),
+ &showlist);
+}
+
+/* A little dummy to make linking with the library succeed. */
+
+int
+Fail (void)
+{
+ return 0;
+}
diff --git a/gdb/remote-rdp.c b/gdb/remote-rdp.c
new file mode 100644
index 00000000000..280e79cdad4
--- /dev/null
+++ b/gdb/remote-rdp.c
@@ -0,0 +1,1449 @@
+/* Remote debugging for the ARM RDP interface.
+
+ Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002 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.
+
+
+ */
+
+
+/*
+ Much of this file (in particular the SWI stuff) is based on code by
+ David Taylor (djt1000@uk.ac.cam.hermes).
+
+ I hacked on and simplified it by removing a lot of sexy features he
+ had added, and some of the (unix specific) workarounds he'd done
+ for other GDB problems - which if they still exist should be fixed
+ in GDB, not in a remote-foo thing . I also made it conform more to
+ the doc I have; which may be wrong.
+
+ Steve Chamberlain (sac@cygnus.com).
+ */
+
+
+#include "defs.h"
+#include "inferior.h"
+#include "value.h"
+#include "callback.h"
+#include "command.h"
+#include <ctype.h>
+#include <fcntl.h>
+#include "symfile.h"
+#include "remote-utils.h"
+#include "gdb_string.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "serial.h"
+
+#include "arm-tdep.h"
+
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+extern struct target_ops remote_rdp_ops;
+static struct serial *io;
+static host_callback *callback = &default_callback;
+
+struct
+ {
+ int step_info;
+ int break_info;
+ int model_info;
+ int target_info;
+ int can_step;
+ char command_line[10];
+ int rdi_level;
+ int rdi_stopped_status;
+ }
+ds;
+
+
+
+/* Definitions for the RDP protocol. */
+
+#define RDP_MOUTHFULL (1<<6)
+#define FPU_COPRO_NUMBER 1
+
+#define RDP_OPEN 0
+#define RDP_OPEN_TYPE_COLD 0
+#define RDP_OPEN_TYPE_WARM 1
+#define RDP_OPEN_TYPE_BAUDRATE 2
+
+#define RDP_OPEN_BAUDRATE_9600 1
+#define RDP_OPEN_BAUDRATE_19200 2
+#define RDP_OPEN_BAUDRATE_38400 3
+
+#define RDP_OPEN_TYPE_RETURN_SEX (1<<3)
+
+#define RDP_CLOSE 1
+
+#define RDP_MEM_READ 2
+
+#define RDP_MEM_WRITE 3
+
+#define RDP_CPU_READ 4
+#define RDP_CPU_WRITE 5
+#define RDP_CPU_READWRITE_MODE_CURRENT 255
+#define RDP_CPU_READWRITE_MASK_PC (1<<16)
+#define RDP_CPU_READWRITE_MASK_CPSR (1<<17)
+#define RDP_CPU_READWRITE_MASK_SPSR (1<<18)
+
+#define RDP_COPRO_READ 6
+#define RDP_COPRO_WRITE 7
+#define RDP_FPU_READWRITE_MASK_FPS (1<<8)
+
+#define RDP_SET_BREAK 0xa
+#define RDP_SET_BREAK_TYPE_PC_EQUAL 0
+#define RDP_SET_BREAK_TYPE_GET_HANDLE (0x10)
+
+#define RDP_CLEAR_BREAK 0xb
+
+#define RDP_EXEC 0x10
+#define RDP_EXEC_TYPE_SYNC 0
+
+#define RDP_STEP 0x11
+
+#define RDP_INFO 0x12
+#define RDP_INFO_ABOUT_STEP 2
+#define RDP_INFO_ABOUT_STEP_GT_1 1
+#define RDP_INFO_ABOUT_STEP_TO_JMP 2
+#define RDP_INFO_ABOUT_STEP_1 4
+#define RDP_INFO_ABOUT_TARGET 0
+#define RDP_INFO_ABOUT_BREAK 1
+#define RDP_INFO_ABOUT_BREAK_COMP 1
+#define RDP_INFO_ABOUT_BREAK_RANGE 2
+#define RDP_INFO_ABOUT_BREAK_BYTE_READ 4
+#define RDP_INFO_ABOUT_BREAK_HALFWORD_READ 8
+#define RDP_INFO_ABOUT_BREAK_WORD_READ (1<<4)
+#define RDP_INFO_ABOUT_BREAK_BYTE_WRITE (1<<5)
+#define RDP_INFO_ABOUT_BREAK_HALFWORD_WRITE (1<<6)
+#define RDP_INFO_ABOUT_BREAK_WORD_WRITE (1<<7)
+#define RDP_INFO_ABOUT_BREAK_MASK (1<<8)
+#define RDP_INFO_ABOUT_BREAK_THREAD_BREAK (1<<9)
+#define RDP_INFO_ABOUT_BREAK_THREAD_WATCH (1<<10)
+#define RDP_INFO_ABOUT_BREAK_COND (1<<11)
+#define RDP_INFO_VECTOR_CATCH (0x180)
+#define RDP_INFO_ICEBREAKER (7)
+#define RDP_INFO_SET_CMDLINE (0x300)
+
+#define RDP_SELECT_CONFIG (0x16)
+#define RDI_ConfigCPU 0
+#define RDI_ConfigSystem 1
+#define RDI_MatchAny 0
+#define RDI_MatchExactly 1
+#define RDI_MatchNoEarlier 2
+
+#define RDP_RESET 0x7f
+
+/* Returns from RDP */
+#define RDP_RES_STOPPED 0x20
+#define RDP_RES_SWI 0x21
+#define RDP_RES_FATAL 0x5e
+#define RDP_RES_VALUE 0x5f
+#define RDP_RES_VALUE_LITTLE_ENDIAN 240
+#define RDP_RES_VALUE_BIG_ENDIAN 241
+#define RDP_RES_RESET 0x7f
+#define RDP_RES_AT_BREAKPOINT 143
+#define RDP_RES_IDUNNO 0xe6
+#define RDP_OSOpReply 0x13
+#define RDP_OSOpWord 2
+#define RDP_OSOpNothing 0
+
+static int timeout = 2;
+
+static char *commandline = NULL;
+
+static int
+remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int write,
+ struct mem_attrib *attrib,
+ struct target_ops *target);
+
+
+/* Stuff for talking to the serial layer. */
+
+static unsigned char
+get_byte (void)
+{
+ int c = serial_readchar (io, timeout);
+
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "[%02x]\n", c);
+
+ if (c == SERIAL_TIMEOUT)
+ {
+ if (timeout == 0)
+ return (unsigned char) c;
+
+ error ("Timeout reading from remote_system");
+ }
+
+ return c;
+}
+
+/* Note that the target always speaks little-endian to us,
+ even if it's a big endian machine. */
+static unsigned int
+get_word (void)
+{
+ unsigned int val = 0;
+ unsigned int c;
+ int n;
+ for (n = 0; n < 4; n++)
+ {
+ c = get_byte ();
+ val |= c << (n * 8);
+ }
+ return val;
+}
+
+static void
+put_byte (char val)
+{
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "(%02x)\n", val);
+ serial_write (io, &val, 1);
+}
+
+static void
+put_word (int val)
+{
+ /* We always send in little endian */
+ unsigned char b[4];
+ b[0] = val;
+ b[1] = val >> 8;
+ b[2] = val >> 16;
+ b[3] = val >> 24;
+
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "(%04x)", val);
+
+ serial_write (io, b, 4);
+}
+
+
+
+/* Stuff for talking to the RDP layer. */
+
+/* This is a bit more fancy that need be so that it syncs even in nasty cases.
+
+ I'be been unable to make it reliably sync up with the change
+ baudrate open command. It likes to sit and say it's been reset,
+ with no more action. So I took all that code out. I'd rather sync
+ reliably at 9600 than wait forever for a possible 19200 connection.
+
+ */
+static void
+rdp_init (int cold, int tty)
+{
+ int sync = 0;
+ int type = cold ? RDP_OPEN_TYPE_COLD : RDP_OPEN_TYPE_WARM;
+ int baudtry = 9600;
+
+ time_t now = time (0);
+ time_t stop_time = now + 10; /* Try and sync for 10 seconds, then give up */
+
+
+ while (time (0) < stop_time && !sync)
+ {
+ int restype;
+ QUIT;
+
+ serial_flush_input (io);
+ serial_flush_output (io);
+
+ if (tty)
+ printf_unfiltered ("Trying to connect at %d baud.\n", baudtry);
+
+ /*
+ ** It seems necessary to reset an EmbeddedICE to get it going.
+ ** This has the side benefit of displaying the startup banner.
+ */
+ if (cold)
+ {
+ put_byte (RDP_RESET);
+ while ((restype = serial_readchar (io, 1)) > 0)
+ {
+ switch (restype)
+ {
+ case SERIAL_TIMEOUT:
+ break;
+ case RDP_RESET:
+ /* Sent at start of reset process: ignore */
+ break;
+ default:
+ printf_unfiltered ("%c", isgraph (restype) ? restype : ' ');
+ break;
+ }
+ }
+
+ if (restype == 0)
+ {
+ /* Got end-of-banner mark */
+ printf_filtered ("\n");
+ }
+ }
+
+ put_byte (RDP_OPEN);
+
+ put_byte (type | RDP_OPEN_TYPE_RETURN_SEX);
+ put_word (0);
+
+ while (!sync && (restype = serial_readchar (io, 1)) > 0)
+ {
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "[%02x]\n", restype);
+
+ switch (restype)
+ {
+ case SERIAL_TIMEOUT:
+ break;
+
+ case RDP_RESET:
+ while ((restype = serial_readchar (io, 1)) == RDP_RESET)
+ ;
+ do
+ {
+ printf_unfiltered ("%c", isgraph (restype) ? restype : ' ');
+ }
+ while ((restype = serial_readchar (io, 1)) > 0);
+
+ if (tty)
+ {
+ printf_unfiltered ("\nThe board has sent notification that it was reset.\n");
+ printf_unfiltered ("Waiting for it to settle down...\n");
+ }
+ sleep (3);
+ if (tty)
+ printf_unfiltered ("\nTrying again.\n");
+ cold = 0;
+ break;
+
+ default:
+ break;
+
+ case RDP_RES_VALUE:
+ {
+ int resval = serial_readchar (io, 1);
+
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "[%02x]\n", resval);
+
+ switch (resval)
+ {
+ case SERIAL_TIMEOUT:
+ break;
+ case RDP_RES_VALUE_LITTLE_ENDIAN:
+ target_byte_order = BFD_ENDIAN_LITTLE;
+ sync = 1;
+ break;
+ case RDP_RES_VALUE_BIG_ENDIAN:
+ target_byte_order = BFD_ENDIAN_BIG;
+ sync = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (!sync)
+ {
+ error ("Couldn't reset the board, try pressing the reset button");
+ }
+}
+
+
+void
+send_rdp (char *template,...)
+{
+ char buf[200];
+ char *dst = buf;
+ va_list alist;
+ va_start (alist, template);
+
+ while (*template)
+ {
+ unsigned int val;
+ int *pi;
+ int *pstat;
+ char *pc;
+ int i;
+ switch (*template++)
+ {
+ case 'b':
+ val = va_arg (alist, int);
+ *dst++ = val;
+ break;
+ case 'w':
+ val = va_arg (alist, int);
+ *dst++ = val;
+ *dst++ = val >> 8;
+ *dst++ = val >> 16;
+ *dst++ = val >> 24;
+ break;
+ case 'S':
+ val = get_byte ();
+ if (val != RDP_RES_VALUE)
+ {
+ printf_unfiltered ("got bad res value of %d, %x\n", val, val);
+ }
+ break;
+ case 'V':
+ pstat = va_arg (alist, int *);
+ pi = va_arg (alist, int *);
+
+ *pstat = get_byte ();
+ /* Check the result was zero, if not read the syndrome */
+ if (*pstat)
+ {
+ *pi = get_word ();
+ }
+ break;
+ case 'Z':
+ /* Check the result code */
+ switch (get_byte ())
+ {
+ case 0:
+ /* Success */
+ break;
+ case 253:
+ /* Target can't do it; never mind */
+ printf_unfiltered ("RDP: Insufficient privilege\n");
+ return;
+ case 254:
+ /* Target can't do it; never mind */
+ printf_unfiltered ("RDP: Unimplemented message\n");
+ return;
+ case 255:
+ error ("Command garbled");
+ break;
+ default:
+ error ("Corrupt reply from target");
+ break;
+ }
+ break;
+ case 'W':
+ /* Read a word from the target */
+ pi = va_arg (alist, int *);
+ *pi = get_word ();
+ break;
+ case 'P':
+ /* Read in some bytes from the target. */
+ pc = va_arg (alist, char *);
+ val = va_arg (alist, int);
+ for (i = 0; i < val; i++)
+ {
+ pc[i] = get_byte ();
+ }
+ break;
+ case 'p':
+ /* send what's being pointed at */
+ pc = va_arg (alist, char *);
+ val = va_arg (alist, int);
+ dst = buf;
+ serial_write (io, pc, val);
+ break;
+ case '-':
+ /* Send whats in the queue */
+ if (dst != buf)
+ {
+ serial_write (io, buf, dst - buf);
+ dst = buf;
+ }
+ break;
+ case 'B':
+ pi = va_arg (alist, int *);
+ *pi = get_byte ();
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+ }
+ va_end (alist);
+
+ if (dst != buf)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+}
+
+
+static int
+rdp_write (CORE_ADDR memaddr, char *buf, int len)
+{
+ int res;
+ int val;
+
+ send_rdp ("bww-p-SV", RDP_MEM_WRITE, memaddr, len, buf, len, &res, &val);
+
+ if (res)
+ {
+ return val;
+ }
+ return len;
+}
+
+
+static int
+rdp_read (CORE_ADDR memaddr, char *buf, int len)
+{
+ int res;
+ int val;
+ send_rdp ("bww-S-P-V",
+ RDP_MEM_READ, memaddr, len,
+ buf, len,
+ &res, &val);
+ if (res)
+ {
+ return val;
+ }
+ return len;
+}
+
+static void
+rdp_fetch_one_register (int mask, char *buf)
+{
+ int val;
+ send_rdp ("bbw-SWZ", RDP_CPU_READ, RDP_CPU_READWRITE_MODE_CURRENT, mask, &val);
+ store_signed_integer (buf, 4, val);
+}
+
+static void
+rdp_fetch_one_fpu_register (int mask, char *buf)
+{
+#if 0
+ /* !!! Since the PIE board doesn't work as documented,
+ and it doesn't have FPU hardware anyway and since it
+ slows everything down, I've disabled this. */
+ int val;
+ if (mask == RDP_FPU_READWRITE_MASK_FPS)
+ {
+ /* this guy is only a word */
+ send_rdp ("bbw-SWZ", RDP_COPRO_READ, FPU_COPRO_NUMBER, mask, &val);
+ store_signed_integer (buf, 4, val);
+ }
+ else
+ {
+ /* There are 12 bytes long
+ !! fixme about endianness
+ */
+ int dummy; /* I've seen these come back as four words !! */
+ send_rdp ("bbw-SWWWWZ", RDP_COPRO_READ, FPU_COPRO_NUMBER, mask, buf + 0, buf + 4, buf + 8, &dummy);
+ }
+#endif
+ memset (buf, 0, MAX_REGISTER_RAW_SIZE);
+}
+
+
+static void
+rdp_store_one_register (int mask, char *buf)
+{
+ int val = extract_unsigned_integer (buf, 4);
+
+ send_rdp ("bbww-SZ",
+ RDP_CPU_WRITE, RDP_CPU_READWRITE_MODE_CURRENT, mask, val);
+}
+
+
+static void
+rdp_store_one_fpu_register (int mask, char *buf)
+{
+#if 0
+ /* See comment in fetch_one_fpu_register */
+ if (mask == RDP_FPU_READWRITE_MASK_FPS)
+ {
+ int val = extract_unsigned_integer (buf, 4);
+ /* this guy is only a word */
+ send_rdp ("bbww-SZ", RDP_COPRO_WRITE,
+ FPU_COPRO_NUMBER,
+ mask, val);
+ }
+ else
+ {
+ /* There are 12 bytes long
+ !! fixme about endianness
+ */
+ int dummy = 0;
+ /* I've seen these come as four words, not the three advertized !! */
+ printf ("Sending mask %x\n", mask);
+ send_rdp ("bbwwwww-SZ",
+ RDP_COPRO_WRITE,
+ FPU_COPRO_NUMBER,
+ mask,
+ *(int *) (buf + 0),
+ *(int *) (buf + 4),
+ *(int *) (buf + 8),
+ 0);
+
+ printf ("done mask %x\n", mask);
+ }
+#endif
+}
+
+
+/* Convert between GDB requests and the RDP layer. */
+
+static void
+remote_rdp_fetch_register (int regno)
+{
+ if (regno == -1)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ remote_rdp_fetch_register (regno);
+ }
+ else
+ {
+ char buf[ARM_MAX_REGISTER_RAW_SIZE];
+ if (regno < 15)
+ rdp_fetch_one_register (1 << regno, buf);
+ else if (regno == ARM_PC_REGNUM)
+ rdp_fetch_one_register (RDP_CPU_READWRITE_MASK_PC, buf);
+ else if (regno == ARM_PS_REGNUM)
+ rdp_fetch_one_register (RDP_CPU_READWRITE_MASK_CPSR, buf);
+ else if (regno == ARM_FPS_REGNUM)
+ rdp_fetch_one_fpu_register (RDP_FPU_READWRITE_MASK_FPS, buf);
+ else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
+ rdp_fetch_one_fpu_register (1 << (regno - ARM_F0_REGNUM), buf);
+ else
+ {
+ printf ("Help me with fetch reg %d\n", regno);
+ }
+ supply_register (regno, buf);
+ }
+}
+
+
+static void
+remote_rdp_store_register (int regno)
+{
+ if (regno == -1)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ remote_rdp_store_register (regno);
+ }
+ else
+ {
+ char tmp[ARM_MAX_REGISTER_RAW_SIZE];
+ read_register_gen (regno, tmp);
+ if (regno < 15)
+ rdp_store_one_register (1 << regno, tmp);
+ else if (regno == ARM_PC_REGNUM)
+ rdp_store_one_register (RDP_CPU_READWRITE_MASK_PC, tmp);
+ else if (regno == ARM_PS_REGNUM)
+ rdp_store_one_register (RDP_CPU_READWRITE_MASK_CPSR, tmp);
+ else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
+ rdp_store_one_fpu_register (1 << (regno - ARM_F0_REGNUM), tmp);
+ else
+ {
+ printf ("Help me with reg %d\n", regno);
+ }
+ }
+}
+
+static void
+remote_rdp_kill (void)
+{
+ callback->shutdown (callback);
+}
+
+
+static void
+rdp_info (void)
+{
+ send_rdp ("bw-S-W-Z", RDP_INFO, RDP_INFO_ABOUT_STEP,
+ &ds.step_info);
+ send_rdp ("bw-S-W-Z", RDP_INFO, RDP_INFO_ABOUT_BREAK,
+ &ds.break_info);
+ send_rdp ("bw-S-WW-Z", RDP_INFO, RDP_INFO_ABOUT_TARGET,
+ &ds.target_info,
+ &ds.model_info);
+
+ ds.can_step = ds.step_info & RDP_INFO_ABOUT_STEP_1;
+
+ ds.rdi_level = (ds.target_info >> 5) & 3;
+}
+
+
+static void
+rdp_execute_start (void)
+{
+ /* Start it off, but don't wait for it */
+ send_rdp ("bb-", RDP_EXEC, RDP_EXEC_TYPE_SYNC);
+}
+
+
+static void
+rdp_set_command_line (char *command, char *args)
+{
+ /*
+ ** We could use RDP_INFO_SET_CMDLINE to send this, but EmbeddedICE systems
+ ** don't implement that, and get all confused at the unexpected text.
+ ** Instead, just keep a copy, and send it when the target does a SWI_GetEnv
+ */
+
+ if (commandline != NULL)
+ xfree (commandline);
+
+ xasprintf (&commandline, "%s %s", command, args);
+}
+
+static void
+rdp_catch_vectors (void)
+{
+ /*
+ ** We want the target monitor to intercept the abort vectors
+ ** i.e. stop the program if any of these are used.
+ */
+ send_rdp ("bww-SZ", RDP_INFO, RDP_INFO_VECTOR_CATCH,
+ /*
+ ** Specify a bitmask including
+ ** the reset vector
+ ** the undefined instruction vector
+ ** the prefetch abort vector
+ ** the data abort vector
+ ** the address exception vector
+ */
+ (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5)
+ );
+}
+
+
+
+#define a_byte 1
+#define a_word 2
+#define a_string 3
+
+
+typedef struct
+{
+ CORE_ADDR n;
+ const char *s;
+}
+argsin;
+
+#define ABYTE 1
+#define AWORD 2
+#define ASTRING 3
+#define ADDRLEN 4
+
+#define SWI_WriteC 0x0
+#define SWI_Write0 0x2
+#define SWI_ReadC 0x4
+#define SWI_CLI 0x5
+#define SWI_GetEnv 0x10
+#define SWI_Exit 0x11
+#define SWI_EnterOS 0x16
+
+#define SWI_GetErrno 0x60
+#define SWI_Clock 0x61
+
+#define SWI_Time 0x63
+#define SWI_Remove 0x64
+#define SWI_Rename 0x65
+#define SWI_Open 0x66
+
+#define SWI_Close 0x68
+#define SWI_Write 0x69
+#define SWI_Read 0x6a
+#define SWI_Seek 0x6b
+#define SWI_Flen 0x6c
+
+#define SWI_IsTTY 0x6e
+#define SWI_TmpNam 0x6f
+#define SWI_InstallHandler 0x70
+#define SWI_GenerateError 0x71
+
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+static int translate_open_mode[] =
+{
+ O_RDONLY, /* "r" */
+ O_RDONLY + O_BINARY, /* "rb" */
+ O_RDWR, /* "r+" */
+ O_RDWR + O_BINARY, /* "r+b" */
+ O_WRONLY + O_CREAT + O_TRUNC, /* "w" */
+ O_WRONLY + O_BINARY + O_CREAT + O_TRUNC, /* "wb" */
+ O_RDWR + O_CREAT + O_TRUNC, /* "w+" */
+ O_RDWR + O_BINARY + O_CREAT + O_TRUNC, /* "w+b" */
+ O_WRONLY + O_APPEND + O_CREAT, /* "a" */
+ O_WRONLY + O_BINARY + O_APPEND + O_CREAT, /* "ab" */
+ O_RDWR + O_APPEND + O_CREAT, /* "a+" */
+ O_RDWR + O_BINARY + O_APPEND + O_CREAT /* "a+b" */
+};
+
+static int
+exec_swi (int swi, argsin *args)
+{
+ int i;
+ char c;
+ switch (swi)
+ {
+ case SWI_WriteC:
+ callback->write_stdout (callback, &c, 1);
+ return 0;
+ case SWI_Write0:
+ for (i = 0; i < args->n; i++)
+ callback->write_stdout (callback, args->s, strlen (args->s));
+ return 0;
+ case SWI_ReadC:
+ callback->read_stdin (callback, &c, 1);
+ args->n = c;
+ return 1;
+ case SWI_CLI:
+ args->n = callback->system (callback, args->s);
+ return 1;
+ case SWI_GetErrno:
+ args->n = callback->get_errno (callback);
+ return 1;
+ case SWI_Time:
+ args->n = callback->time (callback, NULL);
+ return 1;
+
+ case SWI_Clock:
+ /* return number of centi-seconds... */
+ args->n =
+#ifdef CLOCKS_PER_SEC
+ (CLOCKS_PER_SEC >= 100)
+ ? (clock () / (CLOCKS_PER_SEC / 100))
+ : ((clock () * 100) / CLOCKS_PER_SEC);
+#else
+ /* presume unix... clock() returns microseconds */
+ clock () / 10000;
+#endif
+ return 1;
+
+ case SWI_Remove:
+ args->n = callback->unlink (callback, args->s);
+ return 1;
+ case SWI_Rename:
+ args->n = callback->rename (callback, args[0].s, args[1].s);
+ return 1;
+
+ case SWI_Open:
+ /* Now we need to decode the Demon open mode */
+ i = translate_open_mode[args[1].n];
+
+ /* Filename ":tt" is special: it denotes stdin/out */
+ if (strcmp (args->s, ":tt") == 0)
+ {
+ if (i == O_RDONLY) /* opening tty "r" */
+ args->n = 0 /* stdin */ ;
+ else
+ args->n = 1 /* stdout */ ;
+ }
+ else
+ args->n = callback->open (callback, args->s, i);
+ return 1;
+
+ case SWI_Close:
+ args->n = callback->close (callback, args->n);
+ return 1;
+
+ case SWI_Write:
+ /* Return the number of bytes *not* written */
+ args->n = args[1].n -
+ callback->write (callback, args[0].n, args[1].s, args[1].n);
+ return 1;
+
+ case SWI_Read:
+ {
+ char *copy = alloca (args[2].n);
+ int done = callback->read (callback, args[0].n, copy, args[2].n);
+ if (done > 0)
+ remote_rdp_xfer_inferior_memory (args[1].n, copy, done, 1, 0, 0);
+ args->n = args[2].n - done;
+ return 1;
+ }
+
+ case SWI_Seek:
+ /* Return non-zero on failure */
+ args->n = callback->lseek (callback, args[0].n, args[1].n, 0) < 0;
+ return 1;
+
+ case SWI_Flen:
+ {
+ long old = callback->lseek (callback, args->n, 0, SEEK_CUR);
+ args->n = callback->lseek (callback, args->n, 0, SEEK_END);
+ callback->lseek (callback, args->n, old, 0);
+ return 1;
+ }
+
+ case SWI_IsTTY:
+ args->n = callback->isatty (callback, args->n);
+ return 1;
+
+ case SWI_GetEnv:
+ if (commandline != NULL)
+ {
+ int len = strlen (commandline);
+ if (len > 255)
+ {
+ len = 255;
+ commandline[255] = '\0';
+ }
+ remote_rdp_xfer_inferior_memory (args[0].n,
+ commandline, len + 1, 1, 0, 0);
+ }
+ else
+ remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0, 0);
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+
+static void
+handle_swi (void)
+{
+ argsin args[3];
+ char *buf;
+ int len;
+ int count = 0;
+
+ int swino = get_word ();
+ int type = get_byte ();
+ while (type != 0)
+ {
+ switch (type & 0x3)
+ {
+ case ABYTE:
+ args[count].n = get_byte ();
+ break;
+
+ case AWORD:
+ args[count].n = get_word ();
+ break;
+
+ case ASTRING:
+ /* If the word is under 32 bytes it will be sent otherwise
+ an address to it is passed. Also: Special case of 255 */
+
+ len = get_byte ();
+ if (len > 32)
+ {
+ if (len == 255)
+ {
+ len = get_word ();
+ }
+ buf = alloca (len);
+ remote_rdp_xfer_inferior_memory (get_word (),
+ buf,
+ len,
+ 0,
+ 0,
+ 0);
+ }
+ else
+ {
+ int i;
+ buf = alloca (len + 1);
+ for (i = 0; i < len; i++)
+ buf[i] = get_byte ();
+ buf[i] = 0;
+ }
+ args[count].n = len;
+ args[count].s = buf;
+ break;
+
+ default:
+ error ("Unimplemented SWI argument");
+ }
+
+ type = type >> 2;
+ count++;
+ }
+
+ if (exec_swi (swino, args))
+ {
+ /* We have two options here reply with either a byte or a word
+ which is stored in args[0].n. There is no harm in replying with
+ a word all the time, so thats what I do! */
+ send_rdp ("bbw-", RDP_OSOpReply, RDP_OSOpWord, args[0].n);
+ }
+ else
+ {
+ send_rdp ("bb-", RDP_OSOpReply, RDP_OSOpNothing);
+ }
+}
+
+static void
+rdp_execute_finish (void)
+{
+ int running = 1;
+
+ while (running)
+ {
+ int res;
+ res = serial_readchar (io, 1);
+ while (res == SERIAL_TIMEOUT)
+ {
+ QUIT;
+ printf_filtered ("Waiting for target..\n");
+ res = serial_readchar (io, 1);
+ }
+
+ switch (res)
+ {
+ case RDP_RES_SWI:
+ handle_swi ();
+ break;
+ case RDP_RES_VALUE:
+ send_rdp ("B", &ds.rdi_stopped_status);
+ running = 0;
+ break;
+ case RDP_RESET:
+ printf_filtered ("Target reset\n");
+ running = 0;
+ break;
+ default:
+ printf_filtered ("Ignoring %x\n", res);
+ break;
+ }
+ }
+}
+
+
+static void
+rdp_execute (void)
+{
+ rdp_execute_start ();
+ rdp_execute_finish ();
+}
+
+static int
+remote_rdp_insert_breakpoint (CORE_ADDR addr, char *save)
+{
+ int res;
+ if (ds.rdi_level > 0)
+ {
+ send_rdp ("bwb-SWB",
+ RDP_SET_BREAK,
+ addr,
+ RDP_SET_BREAK_TYPE_PC_EQUAL | RDP_SET_BREAK_TYPE_GET_HANDLE,
+ save,
+ &res);
+ }
+ else
+ {
+ send_rdp ("bwb-SB",
+ RDP_SET_BREAK,
+ addr,
+ RDP_SET_BREAK_TYPE_PC_EQUAL,
+ &res);
+ }
+ return res;
+}
+
+static int
+remote_rdp_remove_breakpoint (CORE_ADDR addr, char *save)
+{
+ int res;
+ if (ds.rdi_level > 0)
+ {
+ send_rdp ("b-p-S-B",
+ RDP_CLEAR_BREAK,
+ save, 4,
+ &res);
+ }
+ else
+ {
+ send_rdp ("bw-S-B",
+ RDP_CLEAR_BREAK,
+ addr,
+ &res);
+ }
+ return res;
+}
+
+static void
+rdp_step (void)
+{
+ if (ds.can_step && 0)
+ {
+ /* The pie board can't do steps so I can't test this, and
+ the other code will always work. */
+ int status;
+ send_rdp ("bbw-S-B",
+ RDP_STEP, 0, 1,
+ &status);
+ }
+ else
+ {
+ char handle[4];
+ CORE_ADDR pc = read_register (ARM_PC_REGNUM);
+ pc = arm_get_next_pc (pc);
+ remote_rdp_insert_breakpoint (pc, handle);
+ rdp_execute ();
+ remote_rdp_remove_breakpoint (pc, handle);
+ }
+}
+
+static void
+remote_rdp_open (char *args, int from_tty)
+{
+ int not_icebreaker;
+
+ if (!args)
+ error_no_arg ("serial port device name");
+
+ baud_rate = 9600;
+
+ target_preopen (from_tty);
+
+ io = serial_open (args);
+
+ if (!io)
+ perror_with_name (args);
+
+ serial_raw (io);
+
+ rdp_init (1, from_tty);
+
+
+ if (from_tty)
+ {
+ printf_unfiltered ("Remote RDP debugging using %s at %d baud\n", args, baud_rate);
+ }
+
+ rdp_info ();
+
+ /* Need to set up the vector interception state */
+ rdp_catch_vectors ();
+
+ /*
+ ** If it's an EmbeddedICE, we need to set the processor config.
+ ** Assume we can always have ARM7TDI...
+ */
+ send_rdp ("bw-SB", RDP_INFO, RDP_INFO_ICEBREAKER, &not_icebreaker);
+ if (!not_icebreaker)
+ {
+ const char *CPU = "ARM7TDI";
+ int ICEversion;
+ int len = strlen (CPU);
+
+ send_rdp ("bbbbw-p-SWZ",
+ RDP_SELECT_CONFIG,
+ RDI_ConfigCPU, /* Aspect: set the CPU */
+ len, /* The number of bytes in the name */
+ RDI_MatchAny, /* We'll take whatever we get */
+ 0, /* We'll take whatever version's there */
+ CPU, len,
+ &ICEversion);
+ }
+
+ /* command line initialised on 'run' */
+
+ push_target (&remote_rdp_ops);
+
+ callback->init (callback);
+ flush_cached_frames ();
+ registers_changed ();
+ stop_pc = read_pc ();
+ set_current_frame (create_new_frame (read_fp (), stop_pc));
+ select_frame (get_current_frame ());
+ print_stack_frame (selected_frame, -1, 1);
+}
+
+
+
+/* Close out all files and local state before this target loses control. */
+
+static void
+remote_rdp_close (int quitting)
+{
+ callback->shutdown (callback);
+ if (io)
+ serial_close (io);
+ io = 0;
+}
+
+
+/* Resume execution of the target process. STEP says whether to single-step
+ or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given
+ to the target, or zero for no signal. */
+
+static void
+remote_rdp_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ if (step)
+ rdp_step ();
+ else
+ rdp_execute ();
+}
+
+/* Wait for inferior process to do something. Return pid of child,
+ or -1 in case of error; store status through argument pointer STATUS,
+ just as `wait' would. */
+
+static ptid_t
+remote_rdp_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ switch (ds.rdi_stopped_status)
+ {
+ default:
+ case RDP_RES_RESET:
+ case RDP_RES_SWI:
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = read_register (0);
+ break;
+ case RDP_RES_AT_BREAKPOINT:
+ status->kind = TARGET_WAITKIND_STOPPED;
+ /* The signal in sigrc is a host signal. That probably
+ should be fixed. */
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ break;
+#if 0
+ case rdp_signalled:
+ status->kind = TARGET_WAITKIND_SIGNALLED;
+ /* The signal in sigrc is a host signal. That probably
+ should be fixed. */
+ status->value.sig = target_signal_from_host (sigrc);
+ break;
+#endif
+ }
+
+ return inferior_ptid;
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+static void
+remote_rdp_prepare_to_store (void)
+{
+ /* Do nothing, since we can store individual regs */
+}
+
+/* Transfer LEN bytes between GDB address MYADDR and target address
+ MEMADDR. If WRITE is non-zero, transfer them to the target,
+ otherwise transfer them from the target. TARGET is unused.
+
+ Returns the number of bytes transferred. */
+
+static int
+remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int write, struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ /* I infer from D Taylor's code that there's a limit on the amount
+ we can transfer in one chunk.. */
+ int done = 0;
+ while (done < len)
+ {
+ int justdone;
+ int thisbite = len - done;
+ if (thisbite > RDP_MOUTHFULL)
+ thisbite = RDP_MOUTHFULL;
+
+ QUIT;
+
+ if (write)
+ {
+ justdone = rdp_write (memaddr + done, myaddr + done, thisbite);
+ }
+ else
+ {
+ justdone = rdp_read (memaddr + done, myaddr + done, thisbite);
+ }
+
+ done += justdone;
+
+ if (justdone != thisbite)
+ break;
+ }
+ return done;
+}
+
+
+
+struct yn
+{
+ const char *name;
+ int bit;
+};
+static struct yn stepinfo[] =
+{
+ {"Step more than one instruction", RDP_INFO_ABOUT_STEP_GT_1},
+ {"Step to jump", RDP_INFO_ABOUT_STEP_TO_JMP},
+ {"Step one instruction", RDP_INFO_ABOUT_STEP_1},
+ {0}
+};
+
+static struct yn breakinfo[] =
+{
+ {"comparison breakpoints supported", RDP_INFO_ABOUT_BREAK_COMP},
+ {"range breakpoints supported", RDP_INFO_ABOUT_BREAK_RANGE},
+ {"watchpoints for byte reads supported", RDP_INFO_ABOUT_BREAK_BYTE_READ},
+ {"watchpoints for half-word reads supported", RDP_INFO_ABOUT_BREAK_HALFWORD_READ},
+ {"watchpoints for word reads supported", RDP_INFO_ABOUT_BREAK_WORD_READ},
+ {"watchpoints for byte writes supported", RDP_INFO_ABOUT_BREAK_BYTE_WRITE},
+ {"watchpoints for half-word writes supported", RDP_INFO_ABOUT_BREAK_HALFWORD_WRITE},
+ {"watchpoints for word writes supported", RDP_INFO_ABOUT_BREAK_WORD_WRITE},
+ {"mask break/watch-points supported", RDP_INFO_ABOUT_BREAK_MASK},
+{"thread-specific breakpoints supported", RDP_INFO_ABOUT_BREAK_THREAD_BREAK},
+{"thread-specific watchpoints supported", RDP_INFO_ABOUT_BREAK_THREAD_WATCH},
+ {"conditional breakpoints supported", RDP_INFO_ABOUT_BREAK_COND},
+ {0}
+};
+
+
+static void
+dump_bits (struct yn *t, int info)
+{
+ while (t->name)
+ {
+ printf_unfiltered (" %-45s : %s\n", t->name, (info & t->bit) ? "Yes" : "No");
+ t++;
+ }
+}
+
+static void
+remote_rdp_files_info (struct target_ops *target)
+{
+ printf_filtered ("Target capabilities:\n");
+ dump_bits (stepinfo, ds.step_info);
+ dump_bits (breakinfo, ds.break_info);
+ printf_unfiltered ("target level RDI %x\n", (ds.target_info >> 5) & 3);
+}
+
+
+static void
+remote_rdp_create_inferior (char *exec_file, char *allargs, char **env)
+{
+ CORE_ADDR entry_point;
+
+ if (exec_file == 0 || exec_bfd == 0)
+ error ("No executable file specified.");
+
+ entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
+
+ remote_rdp_kill ();
+ remove_breakpoints ();
+ init_wait_for_inferior ();
+
+ /* This gives us a chance to set up the command line */
+ rdp_set_command_line (exec_file, allargs);
+
+ inferior_ptid = pid_to_ptid (42);
+ insert_breakpoints (); /* Needed to get correct instruction in cache */
+
+ /*
+ ** RDP targets don't provide any facility to set the top of memory,
+ ** so we don't bother to look for MEMSIZE in the environment.
+ */
+
+ /* Let's go! */
+ proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
+}
+
+/* Attach doesn't need to do anything */
+static void
+remote_rdp_attach (char *args, int from_tty)
+{
+ return;
+}
+
+/* Define the target subroutine names */
+
+struct target_ops remote_rdp_ops;
+
+static void
+init_remote_rdp_ops (void)
+{
+ remote_rdp_ops.to_shortname = "rdp";
+ remote_rdp_ops.to_longname = "Remote Target using the RDProtocol";
+ remote_rdp_ops.to_doc = "Use a remote ARM system which uses the ARM Remote Debugging Protocol";
+ remote_rdp_ops.to_open = remote_rdp_open;
+ remote_rdp_ops.to_close = remote_rdp_close;
+ remote_rdp_ops.to_attach = remote_rdp_attach;
+ remote_rdp_ops.to_post_attach = NULL;
+ remote_rdp_ops.to_require_attach = NULL;
+ remote_rdp_ops.to_detach = NULL;
+ remote_rdp_ops.to_require_detach = NULL;
+ remote_rdp_ops.to_resume = remote_rdp_resume;
+ remote_rdp_ops.to_wait = remote_rdp_wait;
+ remote_rdp_ops.to_post_wait = NULL;
+ remote_rdp_ops.to_fetch_registers = remote_rdp_fetch_register;
+ remote_rdp_ops.to_store_registers = remote_rdp_store_register;
+ remote_rdp_ops.to_prepare_to_store = remote_rdp_prepare_to_store;
+ remote_rdp_ops.to_xfer_memory = remote_rdp_xfer_inferior_memory;
+ remote_rdp_ops.to_files_info = remote_rdp_files_info;
+ remote_rdp_ops.to_insert_breakpoint = remote_rdp_insert_breakpoint;
+ remote_rdp_ops.to_remove_breakpoint = remote_rdp_remove_breakpoint;
+ remote_rdp_ops.to_terminal_init = NULL;
+ remote_rdp_ops.to_terminal_inferior = NULL;
+ remote_rdp_ops.to_terminal_ours_for_output = NULL;
+ remote_rdp_ops.to_terminal_ours = NULL;
+ remote_rdp_ops.to_terminal_info = NULL;
+ remote_rdp_ops.to_kill = remote_rdp_kill;
+ remote_rdp_ops.to_load = generic_load;
+ remote_rdp_ops.to_lookup_symbol = NULL;
+ remote_rdp_ops.to_create_inferior = remote_rdp_create_inferior;
+ remote_rdp_ops.to_post_startup_inferior = NULL;
+ remote_rdp_ops.to_acknowledge_created_inferior = NULL;
+ remote_rdp_ops.to_clone_and_follow_inferior = NULL;
+ remote_rdp_ops.to_post_follow_inferior_by_clone = NULL;
+ remote_rdp_ops.to_insert_fork_catchpoint = NULL;
+ remote_rdp_ops.to_remove_fork_catchpoint = NULL;
+ remote_rdp_ops.to_insert_vfork_catchpoint = NULL;
+ remote_rdp_ops.to_remove_vfork_catchpoint = NULL;
+ remote_rdp_ops.to_has_forked = NULL;
+ remote_rdp_ops.to_has_vforked = NULL;
+ remote_rdp_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ remote_rdp_ops.to_post_follow_vfork = NULL;
+ remote_rdp_ops.to_insert_exec_catchpoint = NULL;
+ remote_rdp_ops.to_remove_exec_catchpoint = NULL;
+ remote_rdp_ops.to_has_execd = NULL;
+ remote_rdp_ops.to_reported_exec_events_per_exec_call = NULL;
+ remote_rdp_ops.to_has_exited = NULL;
+ remote_rdp_ops.to_mourn_inferior = generic_mourn_inferior;
+ remote_rdp_ops.to_can_run = NULL;
+ remote_rdp_ops.to_notice_signals = 0;
+ remote_rdp_ops.to_thread_alive = 0;
+ remote_rdp_ops.to_stop = 0;
+ remote_rdp_ops.to_pid_to_exec_file = NULL;
+ remote_rdp_ops.to_stratum = process_stratum;
+ remote_rdp_ops.DONT_USE = NULL;
+ remote_rdp_ops.to_has_all_memory = 1;
+ remote_rdp_ops.to_has_memory = 1;
+ remote_rdp_ops.to_has_stack = 1;
+ remote_rdp_ops.to_has_registers = 1;
+ remote_rdp_ops.to_has_execution = 1;
+ remote_rdp_ops.to_sections = NULL;
+ remote_rdp_ops.to_sections_end = NULL;
+ remote_rdp_ops.to_magic = OPS_MAGIC;
+}
+
+void
+_initialize_remote_rdp (void)
+{
+ init_remote_rdp_ops ();
+ add_target (&remote_rdp_ops);
+}
diff --git a/gdb/remote-sds.c b/gdb/remote-sds.c
new file mode 100644
index 00000000000..507ac5be208
--- /dev/null
+++ b/gdb/remote-sds.c
@@ -0,0 +1,1145 @@
+/* Remote target communications for serial-line targets using SDS' protocol.
+
+ Copyright 1997, 1998, 1999, 2000, 2001, 2002 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. */
+
+/* This interface was written by studying the behavior of the SDS
+ monitor on an ADS 821/860 board, and by consulting the
+ documentation of the monitor that is available on Motorola's web
+ site. -sts 8/13/97 */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include <fcntl.h>
+#include "frame.h"
+#include "inferior.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "target.h"
+#include "gdbcmd.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include "gdbthread.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <signal.h>
+#include "serial.h"
+
+extern void _initialize_remote_sds (void);
+
+/* Declarations of local functions. */
+
+static int sds_write_bytes (CORE_ADDR, char *, int);
+
+static int sds_read_bytes (CORE_ADDR, char *, int);
+
+static void sds_files_info (struct target_ops *ignore);
+
+static int sds_xfer_memory (CORE_ADDR, char *, int, int,
+ struct mem_attrib *, struct target_ops *);
+
+static void sds_prepare_to_store (void);
+
+static void sds_fetch_registers (int);
+
+static void sds_resume (ptid_t, int, enum target_signal);
+
+static int sds_start_remote (PTR);
+
+static void sds_open (char *, int);
+
+static void sds_close (int);
+
+static void sds_store_registers (int);
+
+static void sds_mourn (void);
+
+static void sds_create_inferior (char *, char *, char **);
+
+static void sds_load (char *, int);
+
+static int getmessage (unsigned char *, int);
+
+static int putmessage (unsigned char *, int);
+
+static int sds_send (unsigned char *, int);
+
+static int readchar (int);
+
+static ptid_t sds_wait (ptid_t, struct target_waitstatus *);
+
+static void sds_kill (void);
+
+static int tohex (int);
+
+static int fromhex (int);
+
+static void sds_detach (char *, int);
+
+static void sds_interrupt (int);
+
+static void sds_interrupt_twice (int);
+
+static void interrupt_query (void);
+
+static int read_frame (char *);
+
+static int sds_insert_breakpoint (CORE_ADDR, char *);
+
+static int sds_remove_breakpoint (CORE_ADDR, char *);
+
+static void init_sds_ops (void);
+
+static void sds_command (char *args, int from_tty);
+
+/* Define the target operations vector. */
+
+static struct target_ops sds_ops;
+
+/* This was 5 seconds, which is a long time to sit and wait.
+ Unless this is going though some terminal server or multiplexer or
+ other form of hairy serial connection, I would think 2 seconds would
+ be plenty. */
+
+static int sds_timeout = 2;
+
+/* Descriptor for I/O to remote machine. Initialize it to NULL so
+ that sds_open knows that we don't have a file open when the program
+ starts. */
+
+static struct serial *sds_desc = NULL;
+
+/* This limit comes from the monitor. */
+
+#define PBUFSIZ 250
+
+/* Maximum number of bytes to read/write at once. The value here
+ is chosen to fill up a packet (the headers account for the 32). */
+#define MAXBUFBYTES ((PBUFSIZ-32)/2)
+
+static int next_msg_id;
+
+static int just_started;
+
+static int message_pending;
+
+
+/* Clean up connection to a remote debugger. */
+
+/* ARGSUSED */
+static void
+sds_close (int quitting)
+{
+ if (sds_desc)
+ serial_close (sds_desc);
+ sds_desc = NULL;
+}
+
+/* Stub for catch_errors. */
+
+static int
+sds_start_remote (PTR dummy)
+{
+ int c;
+ unsigned char buf[200];
+
+ immediate_quit++; /* Allow user to interrupt it */
+
+ /* Ack any packet which the remote side has already sent. */
+ serial_write (sds_desc, "{#*\r\n", 5);
+ serial_write (sds_desc, "{#}\r\n", 5);
+
+ while ((c = readchar (1)) >= 0)
+ printf_unfiltered ("%c", c);
+ printf_unfiltered ("\n");
+
+ next_msg_id = 251;
+
+ buf[0] = 26;
+ sds_send (buf, 1);
+
+ buf[0] = 0;
+ sds_send (buf, 1);
+
+ immediate_quit--;
+
+ start_remote (); /* Initialize gdb process mechanisms */
+ return 1;
+}
+
+/* Open a connection to a remote debugger.
+ NAME is the filename used for communication. */
+
+static void
+sds_open (char *name, int from_tty)
+{
+ if (name == 0)
+ error ("To open a remote debug connection, you need to specify what serial\n\
+device is attached to the remote system (e.g. /dev/ttya).");
+
+ target_preopen (from_tty);
+
+ unpush_target (&sds_ops);
+
+ sds_desc = serial_open (name);
+ if (!sds_desc)
+ perror_with_name (name);
+
+ if (baud_rate != -1)
+ {
+ if (serial_setbaudrate (sds_desc, baud_rate))
+ {
+ serial_close (sds_desc);
+ perror_with_name (name);
+ }
+ }
+
+
+ serial_raw (sds_desc);
+
+ /* If there is something sitting in the buffer we might take it as a
+ response to a command, which would be bad. */
+ serial_flush_input (sds_desc);
+
+ if (from_tty)
+ {
+ puts_filtered ("Remote debugging using ");
+ puts_filtered (name);
+ puts_filtered ("\n");
+ }
+ push_target (&sds_ops); /* Switch to using remote target now */
+
+ just_started = 1;
+
+ /* Start the remote connection; if error (0), discard this target.
+ In particular, if the user quits, be sure to discard it (we'd be
+ in an inconsistent state otherwise). */
+ if (!catch_errors (sds_start_remote, NULL,
+ "Couldn't establish connection to remote target\n",
+ RETURN_MASK_ALL))
+ pop_target ();
+}
+
+/* This takes a program previously attached to and detaches it. After
+ this is done, GDB can be used to debug some other program. We
+ better not have left any breakpoints in the target program or it'll
+ die when it hits one. */
+
+static void
+sds_detach (char *args, int from_tty)
+{
+ char buf[PBUFSIZ];
+
+ if (args)
+ error ("Argument given to \"detach\" when remotely debugging.");
+
+#if 0
+ /* Tell the remote target to detach. */
+ strcpy (buf, "D");
+ sds_send (buf, 1);
+#endif
+
+ pop_target ();
+ if (from_tty)
+ puts_filtered ("Ending remote debugging.\n");
+}
+
+/* Convert hex digit A to a number. */
+
+static int
+fromhex (int a)
+{
+ if (a >= '0' && a <= '9')
+ return a - '0';
+ else if (a >= 'a' && a <= 'f')
+ return a - 'a' + 10;
+ else
+ error ("Reply contains invalid hex digit %d", a);
+}
+
+/* Convert number NIB to a hex digit. */
+
+static int
+tohex (int nib)
+{
+ if (nib < 10)
+ return '0' + nib;
+ else
+ return 'a' + nib - 10;
+}
+
+static int
+tob64 (unsigned char *inbuf, char *outbuf, int len)
+{
+ int i, sum;
+ char *p;
+
+ if (len % 3 != 0)
+ error ("bad length");
+
+ p = outbuf;
+ for (i = 0; i < len; i += 3)
+ {
+ /* Collect the next three bytes into a number. */
+ sum = ((long) *inbuf++) << 16;
+ sum |= ((long) *inbuf++) << 8;
+ sum |= ((long) *inbuf++);
+
+ /* Spit out 4 6-bit encodings. */
+ *p++ = ((sum >> 18) & 0x3f) + '0';
+ *p++ = ((sum >> 12) & 0x3f) + '0';
+ *p++ = ((sum >> 6) & 0x3f) + '0';
+ *p++ = (sum & 0x3f) + '0';
+ }
+ return (p - outbuf);
+}
+
+static int
+fromb64 (char *inbuf, char *outbuf, int len)
+{
+ int i, sum;
+
+ if (len % 4 != 0)
+ error ("bad length");
+
+ for (i = 0; i < len; i += 4)
+ {
+ /* Collect 4 6-bit digits. */
+ sum = (*inbuf++ - '0') << 18;
+ sum |= (*inbuf++ - '0') << 12;
+ sum |= (*inbuf++ - '0') << 6;
+ sum |= (*inbuf++ - '0');
+
+ /* Now take the resulting 24-bit number and get three bytes out
+ of it. */
+ *outbuf++ = (sum >> 16) & 0xff;
+ *outbuf++ = (sum >> 8) & 0xff;
+ *outbuf++ = sum & 0xff;
+ }
+
+ return (len / 4) * 3;
+}
+
+
+/* Tell the remote machine to resume. */
+
+static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
+int last_sent_step;
+
+static void
+sds_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ unsigned char buf[PBUFSIZ];
+
+ last_sent_signal = siggnal;
+ last_sent_step = step;
+
+ buf[0] = (step ? 21 : 20);
+ buf[1] = 0; /* (should be signal?) */
+
+ sds_send (buf, 2);
+}
+
+/* Send a message to target to halt it. Target will respond, and send
+ us a message pending notice. */
+
+static void
+sds_interrupt (int signo)
+{
+ unsigned char buf[PBUFSIZ];
+
+ /* If this doesn't work, try more severe steps. */
+ signal (signo, sds_interrupt_twice);
+
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "sds_interrupt called\n");
+
+ buf[0] = 25;
+ sds_send (buf, 1);
+}
+
+static void (*ofunc) ();
+
+/* The user typed ^C twice. */
+
+static void
+sds_interrupt_twice (int signo)
+{
+ signal (signo, ofunc);
+
+ interrupt_query ();
+
+ signal (signo, sds_interrupt);
+}
+
+/* Ask the user what to do when an interrupt is received. */
+
+static void
+interrupt_query (void)
+{
+ target_terminal_ours ();
+
+ if (query ("Interrupted while waiting for the program.\n\
+Give up (and stop debugging it)? "))
+ {
+ target_mourn_inferior ();
+ throw_exception (RETURN_QUIT);
+ }
+
+ target_terminal_inferior ();
+}
+
+/* If nonzero, ignore the next kill. */
+int kill_kludge;
+
+/* Wait until the remote machine stops, then return, storing status in
+ STATUS just as `wait' would. Returns "pid" (though it's not clear
+ what, if anything, that means in the case of this target). */
+
+static ptid_t
+sds_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ unsigned char buf[PBUFSIZ];
+ int retlen;
+
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = 0;
+
+ ofunc = (void (*)()) signal (SIGINT, sds_interrupt);
+
+ signal (SIGINT, ofunc);
+
+ if (just_started)
+ {
+ just_started = 0;
+ status->kind = TARGET_WAITKIND_STOPPED;
+ return inferior_ptid;
+ }
+
+ while (1)
+ {
+ getmessage (buf, 1);
+
+ if (message_pending)
+ {
+ buf[0] = 26;
+ retlen = sds_send (buf, 1);
+ if (remote_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Signals: %02x%02x %02x %02x\n",
+ buf[0], buf[1],
+ buf[2], buf[3]);
+ }
+ message_pending = 0;
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ goto got_status;
+ }
+ }
+got_status:
+ return inferior_ptid;
+}
+
+static unsigned char sprs[16];
+
+/* Read the remote registers into the block REGS. */
+/* Currently we just read all the registers, so we don't use regno. */
+
+/* ARGSUSED */
+static void
+sds_fetch_registers (int regno)
+{
+ unsigned char buf[PBUFSIZ];
+ int i, retlen;
+ char regs[REGISTER_BYTES];
+
+ /* Unimplemented registers read as all bits zero. */
+ memset (regs, 0, REGISTER_BYTES);
+
+ buf[0] = 18;
+ buf[1] = 1;
+ buf[2] = 0;
+ retlen = sds_send (buf, 3);
+
+ for (i = 0; i < 4 * 6; ++i)
+ regs[i + 4 * 32 + 8 * 32] = buf[i];
+ for (i = 0; i < 4 * 4; ++i)
+ sprs[i] = buf[i + 4 * 7];
+
+ buf[0] = 18;
+ buf[1] = 2;
+ buf[2] = 0;
+ retlen = sds_send (buf, 3);
+
+ for (i = 0; i < retlen; i++)
+ regs[i] = buf[i];
+
+ /* (should warn about reply too short) */
+
+ for (i = 0; i < NUM_REGS; i++)
+ supply_register (i, &regs[REGISTER_BYTE (i)]);
+}
+
+/* Prepare to store registers. Since we may send them all, we have to
+ read out the ones we don't want to change first. */
+
+static void
+sds_prepare_to_store (void)
+{
+ /* Make sure the entire registers array is valid. */
+ read_register_bytes (0, (char *) NULL, REGISTER_BYTES);
+}
+
+/* Store register REGNO, or all registers if REGNO == -1, from the contents
+ of REGISTERS. FIXME: ignores errors. */
+
+static void
+sds_store_registers (int regno)
+{
+ unsigned char *p, buf[PBUFSIZ];
+ int i;
+
+ /* Store all the special-purpose registers. */
+ p = buf;
+ *p++ = 19;
+ *p++ = 1;
+ *p++ = 0;
+ *p++ = 0;
+ for (i = 0; i < 4 * 6; i++)
+ *p++ = registers[i + 4 * 32 + 8 * 32];
+ for (i = 0; i < 4 * 1; i++)
+ *p++ = 0;
+ for (i = 0; i < 4 * 4; i++)
+ *p++ = sprs[i];
+
+ sds_send (buf, p - buf);
+
+ /* Store all the general-purpose registers. */
+ p = buf;
+ *p++ = 19;
+ *p++ = 2;
+ *p++ = 0;
+ *p++ = 0;
+ for (i = 0; i < 4 * 32; i++)
+ *p++ = registers[i];
+
+ sds_send (buf, p - buf);
+
+}
+
+/* Write memory data directly to the remote machine. This does not
+ inform the data cache; the data cache uses this. MEMADDR is the
+ address in the remote memory space. MYADDR is the address of the
+ buffer in our space. LEN is the number of bytes.
+
+ Returns number of bytes transferred, or 0 for error. */
+
+static int
+sds_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ int max_buf_size; /* Max size of packet output buffer */
+ int origlen;
+ unsigned char buf[PBUFSIZ];
+ int todo;
+ int i;
+
+ /* Chop the transfer down if necessary */
+
+ max_buf_size = 150;
+
+ origlen = len;
+ while (len > 0)
+ {
+ todo = min (len, max_buf_size);
+
+ buf[0] = 13;
+ buf[1] = 0;
+ buf[2] = (int) (memaddr >> 24) & 0xff;
+ buf[3] = (int) (memaddr >> 16) & 0xff;
+ buf[4] = (int) (memaddr >> 8) & 0xff;
+ buf[5] = (int) (memaddr) & 0xff;
+ buf[6] = 1;
+ buf[7] = 0;
+
+ for (i = 0; i < todo; i++)
+ buf[i + 8] = myaddr[i];
+
+ sds_send (buf, 8 + todo);
+
+ /* (should look at result) */
+
+ myaddr += todo;
+ memaddr += todo;
+ len -= todo;
+ }
+ return origlen;
+}
+
+/* Read memory data directly from the remote machine. This does not
+ use the data cache; the data cache uses this. MEMADDR is the
+ address in the remote memory space. MYADDR is the address of the
+ buffer in our space. LEN is the number of bytes.
+
+ Returns number of bytes transferred, or 0 for error. */
+
+static int
+sds_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ int max_buf_size; /* Max size of packet output buffer */
+ int origlen, retlen;
+ unsigned char buf[PBUFSIZ];
+ int todo;
+ int i;
+
+ /* Chop the transfer down if necessary */
+
+ max_buf_size = 150;
+
+ origlen = len;
+ while (len > 0)
+ {
+ todo = min (len, max_buf_size);
+
+ buf[0] = 12;
+ buf[1] = 0;
+ buf[2] = (int) (memaddr >> 24) & 0xff;
+ buf[3] = (int) (memaddr >> 16) & 0xff;
+ buf[4] = (int) (memaddr >> 8) & 0xff;
+ buf[5] = (int) (memaddr) & 0xff;
+ buf[6] = (int) (todo >> 8) & 0xff;
+ buf[7] = (int) (todo) & 0xff;
+ buf[8] = 1;
+
+ retlen = sds_send (buf, 9);
+
+ if (retlen - 2 != todo)
+ {
+ return 0;
+ }
+
+ /* Reply describes memory byte by byte. */
+
+ for (i = 0; i < todo; i++)
+ myaddr[i] = buf[i + 2];
+
+ myaddr += todo;
+ memaddr += todo;
+ len -= todo;
+ }
+
+ return origlen;
+}
+
+/* Read or write LEN bytes from inferior memory at MEMADDR,
+ transferring to or from debugger address MYADDR. Write to inferior
+ if SHOULD_WRITE is nonzero. Returns length of data written or
+ read; 0 for error. TARGET is unused. */
+
+/* ARGSUSED */
+static int
+sds_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write,
+ struct mem_attrib *attrib, struct target_ops *target)
+{
+ int res;
+
+ if (should_write)
+ res = sds_write_bytes (memaddr, myaddr, len);
+ else
+ res = sds_read_bytes (memaddr, myaddr, len);
+
+ return res;
+}
+
+
+static void
+sds_files_info (struct target_ops *ignore)
+{
+ puts_filtered ("Debugging over a serial connection, using SDS protocol.\n");
+}
+
+/* Stuff for dealing with the packets which are part of this protocol.
+ See comment at top of file for details. */
+
+/* Read a single character from the remote end, masking it down to 7 bits. */
+
+static int
+readchar (int timeout)
+{
+ int ch;
+
+ ch = serial_readchar (sds_desc, timeout);
+
+ if (remote_debug > 1 && ch >= 0)
+ fprintf_unfiltered (gdb_stdlog, "%c(%x)", ch, ch);
+
+ switch (ch)
+ {
+ case SERIAL_EOF:
+ error ("Remote connection closed");
+ case SERIAL_ERROR:
+ perror_with_name ("Remote communication error");
+ case SERIAL_TIMEOUT:
+ return ch;
+ default:
+ return ch & 0x7f;
+ }
+}
+
+/* An SDS-style checksum is a sum of the bytes modulo 253. (Presumably
+ because 253, 254, and 255 are special flags in the protocol.) */
+
+static int
+compute_checksum (int csum, char *buf, int len)
+{
+ int i;
+
+ for (i = 0; i < len; ++i)
+ csum += (unsigned char) buf[i];
+
+ csum %= 253;
+ return csum;
+}
+
+/* Send the command in BUF to the remote machine, and read the reply
+ into BUF also. */
+
+static int
+sds_send (unsigned char *buf, int len)
+{
+ putmessage (buf, len);
+
+ return getmessage (buf, 0);
+}
+
+/* Send a message to the remote machine. */
+
+static int
+putmessage (unsigned char *buf, int len)
+{
+ int i, enclen;
+ unsigned char csum = 0;
+ char buf2[PBUFSIZ], buf3[PBUFSIZ];
+ unsigned char header[3];
+ char *p;
+
+ /* Copy the packet into buffer BUF2, encapsulating it
+ and giving it a checksum. */
+
+ if (len > 170) /* Prosanity check */
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+ if (remote_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Message to send: \"");
+ for (i = 0; i < len; ++i)
+ fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
+ fprintf_unfiltered (gdb_stdlog, "\"\n");
+ }
+
+ p = buf2;
+ *p++ = '$';
+
+ if (len % 3 != 0)
+ {
+ buf[len] = '\0';
+ buf[len + 1] = '\0';
+ }
+
+ header[1] = next_msg_id;
+
+ header[2] = len;
+
+ csum = compute_checksum (csum, buf, len);
+ csum = compute_checksum (csum, header + 1, 2);
+
+ header[0] = csum;
+
+ tob64 (header, p, 3);
+ p += 4;
+ enclen = tob64 (buf, buf3, ((len + 2) / 3) * 3);
+
+ for (i = 0; i < enclen; ++i)
+ *p++ = buf3[i];
+ *p++ = '\r';
+ *p++ = '\n';
+
+ next_msg_id = (next_msg_id + 3) % 245;
+
+ /* Send it over and over until we get a positive ack. */
+
+ while (1)
+ {
+ if (remote_debug)
+ {
+ *p = '\0';
+ fprintf_unfiltered (gdb_stdlog, "Sending encoded: \"%s\"", buf2);
+ fprintf_unfiltered (gdb_stdlog,
+ " (Checksum %d, id %d, length %d)\n",
+ header[0], header[1], header[2]);
+ gdb_flush (gdb_stdlog);
+ }
+ if (serial_write (sds_desc, buf2, p - buf2))
+ perror_with_name ("putmessage: write failed");
+
+ return 1;
+ }
+}
+
+/* Come here after finding the start of the frame. Collect the rest
+ into BUF. Returns 0 on any error, 1 on success. */
+
+static int
+read_frame (char *buf)
+{
+ char *bp;
+ int c;
+
+ bp = buf;
+
+ while (1)
+ {
+ c = readchar (sds_timeout);
+
+ switch (c)
+ {
+ case SERIAL_TIMEOUT:
+ if (remote_debug)
+ fputs_filtered ("Timeout in mid-message, retrying\n", gdb_stdlog);
+ return 0;
+ case '$':
+ if (remote_debug)
+ fputs_filtered ("Saw new packet start in middle of old one\n",
+ gdb_stdlog);
+ return 0; /* Start a new packet, count retries */
+ case '\r':
+ break;
+
+ case '\n':
+ {
+ *bp = '\000';
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "Received encoded: \"%s\"\n",
+ buf);
+ return 1;
+ }
+
+ default:
+ if (bp < buf + PBUFSIZ - 1)
+ {
+ *bp++ = c;
+ continue;
+ }
+
+ *bp = '\0';
+ puts_filtered ("Message too long: ");
+ puts_filtered (buf);
+ puts_filtered ("\n");
+
+ return 0;
+ }
+ }
+}
+
+/* Read a packet from the remote machine, with error checking,
+ and store it in BUF. BUF is expected to be of size PBUFSIZ.
+ If FOREVER, wait forever rather than timing out; this is used
+ while the target is executing user code. */
+
+static int
+getmessage (unsigned char *buf, int forever)
+{
+ int c, c2, c3;
+ int tries;
+ int timeout;
+ int val, i, len, csum;
+ unsigned char header[3];
+ unsigned char inbuf[500];
+
+ strcpy (buf, "timeout");
+
+ if (forever)
+ {
+ timeout = watchdog > 0 ? watchdog : -1;
+ }
+
+ else
+ timeout = sds_timeout;
+
+#define MAX_TRIES 3
+
+ for (tries = 1; tries <= MAX_TRIES; tries++)
+ {
+ /* This can loop forever if the remote side sends us characters
+ continuously, but if it pauses, we'll get a zero from readchar
+ because of timeout. Then we'll count that as a retry. */
+
+ /* Note that we will only wait forever prior to the start of a packet.
+ After that, we expect characters to arrive at a brisk pace. They
+ should show up within sds_timeout intervals. */
+
+ do
+ {
+ c = readchar (timeout);
+
+ if (c == SERIAL_TIMEOUT)
+ {
+ if (forever) /* Watchdog went off. Kill the target. */
+ {
+ target_mourn_inferior ();
+ error ("Watchdog has expired. Target detached.\n");
+ }
+ if (remote_debug)
+ fputs_filtered ("Timed out.\n", gdb_stdlog);
+ goto retry;
+ }
+ }
+ while (c != '$' && c != '{');
+
+ /* We might have seen a "trigraph", a sequence of three characters
+ that indicate various sorts of communication state. */
+
+ if (c == '{')
+ {
+ /* Read the other two chars of the trigraph. */
+ c2 = readchar (timeout);
+ c3 = readchar (timeout);
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "Trigraph %c%c%c received\n",
+ c, c2, c3);
+ if (c3 == '+')
+ {
+ message_pending = 1;
+ return 0; /*???? */
+ }
+ continue;
+ }
+
+ val = read_frame (inbuf);
+
+ if (val == 1)
+ {
+ fromb64 (inbuf, header, 4);
+ /* (should check out other bits) */
+ fromb64 (inbuf + 4, buf, strlen (inbuf) - 4);
+
+ len = header[2];
+
+ csum = 0;
+ csum = compute_checksum (csum, buf, len);
+ csum = compute_checksum (csum, header + 1, 2);
+
+ if (csum != header[0])
+ fprintf_unfiltered (gdb_stderr,
+ "Checksum mismatch: computed %d, received %d\n",
+ csum, header[0]);
+
+ if (header[2] == 0xff)
+ fprintf_unfiltered (gdb_stderr, "Requesting resend...\n");
+
+ if (remote_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "... (Got checksum %d, id %d, length %d)\n",
+ header[0], header[1], header[2]);
+ fprintf_unfiltered (gdb_stdlog, "Message received: \"");
+ for (i = 0; i < len; ++i)
+ {
+ fprintf_unfiltered (gdb_stdlog, "%02x", (unsigned char) buf[i]);
+ }
+ fprintf_unfiltered (gdb_stdlog, "\"\n");
+ }
+
+ /* no ack required? */
+ return len;
+ }
+
+ /* Try the whole thing again. */
+ retry:
+ /* need to do something here */
+ }
+
+ /* We have tried hard enough, and just can't receive the packet. Give up. */
+
+ printf_unfiltered ("Ignoring packet error, continuing...\n");
+ return 0;
+}
+
+static void
+sds_kill (void)
+{
+ /* Don't try to do anything to the target. */
+}
+
+static void
+sds_mourn (void)
+{
+ unpush_target (&sds_ops);
+ generic_mourn_inferior ();
+}
+
+static void
+sds_create_inferior (char *exec_file, char *args, char **env)
+{
+ inferior_ptid = pid_to_ptid (42000);
+
+ /* Clean up from the last time we were running. */
+ clear_proceed_status ();
+
+ /* Let the remote process run. */
+ proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
+}
+
+static void
+sds_load (char *filename, int from_tty)
+{
+ generic_load (filename, from_tty);
+
+ inferior_ptid = null_ptid;
+}
+
+/* The SDS monitor has commands for breakpoint insertion, although it
+ it doesn't actually manage the breakpoints, it just returns the
+ replaced instruction back to the debugger. */
+
+static int
+sds_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ int i, retlen;
+ unsigned char *p, buf[PBUFSIZ];
+
+ p = buf;
+ *p++ = 16;
+ *p++ = 0;
+ *p++ = (int) (addr >> 24) & 0xff;
+ *p++ = (int) (addr >> 16) & 0xff;
+ *p++ = (int) (addr >> 8) & 0xff;
+ *p++ = (int) (addr) & 0xff;
+
+ retlen = sds_send (buf, p - buf);
+
+ for (i = 0; i < 4; ++i)
+ contents_cache[i] = buf[i + 2];
+
+ return 0;
+}
+
+static int
+sds_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ int i, retlen;
+ unsigned char *p, buf[PBUFSIZ];
+
+ p = buf;
+ *p++ = 17;
+ *p++ = 0;
+ *p++ = (int) (addr >> 24) & 0xff;
+ *p++ = (int) (addr >> 16) & 0xff;
+ *p++ = (int) (addr >> 8) & 0xff;
+ *p++ = (int) (addr) & 0xff;
+ for (i = 0; i < 4; ++i)
+ *p++ = contents_cache[i];
+
+ retlen = sds_send (buf, p - buf);
+
+ return 0;
+}
+
+static void
+init_sds_ops (void)
+{
+ sds_ops.to_shortname = "sds";
+ sds_ops.to_longname = "Remote serial target with SDS protocol";
+ sds_ops.to_doc = "Use a remote computer via a serial line; using the SDS protocol.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ sds_ops.to_open = sds_open;
+ sds_ops.to_close = sds_close;
+ sds_ops.to_detach = sds_detach;
+ sds_ops.to_resume = sds_resume;
+ sds_ops.to_wait = sds_wait;
+ sds_ops.to_fetch_registers = sds_fetch_registers;
+ sds_ops.to_store_registers = sds_store_registers;
+ sds_ops.to_prepare_to_store = sds_prepare_to_store;
+ sds_ops.to_xfer_memory = sds_xfer_memory;
+ sds_ops.to_files_info = sds_files_info;
+ sds_ops.to_insert_breakpoint = sds_insert_breakpoint;
+ sds_ops.to_remove_breakpoint = sds_remove_breakpoint;
+ sds_ops.to_kill = sds_kill;
+ sds_ops.to_load = sds_load;
+ sds_ops.to_create_inferior = sds_create_inferior;
+ sds_ops.to_mourn_inferior = sds_mourn;
+ sds_ops.to_stratum = process_stratum;
+ sds_ops.to_has_all_memory = 1;
+ sds_ops.to_has_memory = 1;
+ sds_ops.to_has_stack = 1;
+ sds_ops.to_has_registers = 1;
+ sds_ops.to_has_execution = 1;
+ sds_ops.to_magic = OPS_MAGIC;
+}
+
+/* Put a command string, in args, out to the monitor and display the
+ reply message. */
+
+static void
+sds_command (char *args, int from_tty)
+{
+ char *p;
+ int i, len, retlen;
+ unsigned char buf[1000];
+
+ /* Convert hexadecimal chars into a byte buffer. */
+ p = args;
+ len = 0;
+ while (*p != '\0')
+ {
+ buf[len++] = fromhex (p[0]) * 16 + fromhex (p[1]);
+ if (p[1] == '\0')
+ break;
+ p += 2;
+ }
+
+ retlen = sds_send (buf, len);
+
+ printf_filtered ("Reply is ");
+ for (i = 0; i < retlen; ++i)
+ {
+ printf_filtered ("%02x", buf[i]);
+ }
+ printf_filtered ("\n");
+}
+
+void
+_initialize_remote_sds (void)
+{
+ init_sds_ops ();
+ add_target (&sds_ops);
+
+ add_show_from_set (add_set_cmd ("sdstimeout", no_class,
+ var_integer, (char *) &sds_timeout,
+ "Set timeout value for sds read.\n", &setlist),
+ &showlist);
+
+ add_com ("sds", class_obscure, sds_command,
+ "Send a command to the SDS monitor.");
+}
diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
new file mode 100644
index 00000000000..1d037c8fa79
--- /dev/null
+++ b/gdb/remote-sim.c
@@ -0,0 +1,941 @@
+/* Generic remote debugging interface for simulators.
+
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Support.
+ Steve Chamberlain (sac@cygnus.com).
+
+ 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 "defs.h"
+#include "inferior.h"
+#include "value.h"
+#include "gdb_string.h"
+#include <ctype.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <errno.h>
+#include "terminal.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "callback.h"
+#include "remote-sim.h"
+#include "remote-utils.h"
+#include "command.h"
+#include "regcache.h"
+
+/* Prototypes */
+
+extern void _initialize_remote_sim (void);
+
+extern int (*ui_loop_hook) (int signo);
+
+static void dump_mem (char *buf, int len);
+
+static void init_callbacks (void);
+
+static void end_callbacks (void);
+
+static int gdb_os_write_stdout (host_callback *, const char *, int);
+
+static void gdb_os_flush_stdout (host_callback *);
+
+static int gdb_os_write_stderr (host_callback *, const char *, int);
+
+static void gdb_os_flush_stderr (host_callback *);
+
+static int gdb_os_poll_quit (host_callback *);
+
+/* printf_filtered is depreciated */
+static void gdb_os_printf_filtered (host_callback *, const char *, ...);
+
+static void gdb_os_vprintf_filtered (host_callback *, const char *, va_list);
+
+static void gdb_os_evprintf_filtered (host_callback *, const char *, va_list);
+
+static void gdb_os_error (host_callback *, const char *, ...);
+
+static void gdbsim_fetch_register (int regno);
+
+static void gdbsim_store_register (int regno);
+
+static void gdbsim_kill (void);
+
+static void gdbsim_load (char *prog, int fromtty);
+
+static void gdbsim_create_inferior (char *exec_file, char *args, char **env);
+
+static void gdbsim_open (char *args, int from_tty);
+
+static void gdbsim_close (int quitting);
+
+static void gdbsim_detach (char *args, int from_tty);
+
+static void gdbsim_resume (ptid_t ptid, int step, enum target_signal siggnal);
+
+static ptid_t gdbsim_wait (ptid_t ptid, struct target_waitstatus *status);
+
+static void gdbsim_prepare_to_store (void);
+
+static int gdbsim_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr,
+ int len, int write,
+ struct mem_attrib *attrib,
+ struct target_ops *target);
+
+static void gdbsim_files_info (struct target_ops *target);
+
+static void gdbsim_mourn_inferior (void);
+
+static void gdbsim_stop (void);
+
+void simulator_command (char *args, int from_tty);
+
+/* Naming convention:
+
+ sim_* are the interface to the simulator (see remote-sim.h).
+ gdbsim_* are stuff which is internal to gdb. */
+
+/* Forward data declarations */
+extern struct target_ops gdbsim_ops;
+
+static int program_loaded = 0;
+
+/* We must keep track of whether the simulator has been opened or not because
+ GDB can call a target's close routine twice, but sim_close doesn't allow
+ this. We also need to record the result of sim_open so we can pass it
+ back to the other sim_foo routines. */
+static SIM_DESC gdbsim_desc = 0;
+
+static void
+dump_mem (char *buf, int len)
+{
+ if (len <= 8)
+ {
+ if (len == 8 || len == 4)
+ {
+ long l[2];
+ memcpy (l, buf, len);
+ printf_filtered ("\t0x%lx", l[0]);
+ if (len == 8)
+ printf_filtered (" 0x%lx", l[1]);
+ printf_filtered ("\n");
+ }
+ else
+ {
+ int i;
+ printf_filtered ("\t");
+ for (i = 0; i < len; i++)
+ printf_filtered ("0x%x ", buf[i]);
+ printf_filtered ("\n");
+ }
+ }
+}
+
+static host_callback gdb_callback;
+static int callbacks_initialized = 0;
+
+/* Initialize gdb_callback. */
+
+static void
+init_callbacks (void)
+{
+ if (!callbacks_initialized)
+ {
+ gdb_callback = default_callback;
+ gdb_callback.init (&gdb_callback);
+ gdb_callback.write_stdout = gdb_os_write_stdout;
+ gdb_callback.flush_stdout = gdb_os_flush_stdout;
+ gdb_callback.write_stderr = gdb_os_write_stderr;
+ gdb_callback.flush_stderr = gdb_os_flush_stderr;
+ gdb_callback.printf_filtered = gdb_os_printf_filtered;
+ gdb_callback.vprintf_filtered = gdb_os_vprintf_filtered;
+ gdb_callback.evprintf_filtered = gdb_os_evprintf_filtered;
+ gdb_callback.error = gdb_os_error;
+ gdb_callback.poll_quit = gdb_os_poll_quit;
+ gdb_callback.magic = HOST_CALLBACK_MAGIC;
+ callbacks_initialized = 1;
+ }
+}
+
+/* Release callbacks (free resources used by them). */
+
+static void
+end_callbacks (void)
+{
+ if (callbacks_initialized)
+ {
+ gdb_callback.shutdown (&gdb_callback);
+ callbacks_initialized = 0;
+ }
+}
+
+/* GDB version of os_write_stdout callback. */
+
+static int
+gdb_os_write_stdout (host_callback *p, const char *buf, int len)
+{
+ int i;
+ char b[2];
+
+ ui_file_write (gdb_stdtarg, buf, len);
+ return len;
+}
+
+/* GDB version of os_flush_stdout callback. */
+
+static void
+gdb_os_flush_stdout (host_callback *p)
+{
+ gdb_flush (gdb_stdtarg);
+}
+
+/* GDB version of os_write_stderr callback. */
+
+static int
+gdb_os_write_stderr (host_callback *p, const char *buf, int len)
+{
+ int i;
+ char b[2];
+
+ for (i = 0; i < len; i++)
+ {
+ b[0] = buf[i];
+ b[1] = 0;
+ fputs_unfiltered (b, gdb_stdtarg);
+ }
+ return len;
+}
+
+/* GDB version of os_flush_stderr callback. */
+
+static void
+gdb_os_flush_stderr (host_callback *p)
+{
+ gdb_flush (gdb_stderr);
+}
+
+/* GDB version of printf_filtered callback. */
+
+static void
+gdb_os_printf_filtered (host_callback * p, const char *format,...)
+{
+ va_list args;
+ va_start (args, format);
+
+ vfprintf_filtered (gdb_stdout, format, args);
+
+ va_end (args);
+}
+
+/* GDB version of error vprintf_filtered. */
+
+static void
+gdb_os_vprintf_filtered (host_callback * p, const char *format, va_list ap)
+{
+ vfprintf_filtered (gdb_stdout, format, ap);
+}
+
+/* GDB version of error evprintf_filtered. */
+
+static void
+gdb_os_evprintf_filtered (host_callback * p, const char *format, va_list ap)
+{
+ vfprintf_filtered (gdb_stderr, format, ap);
+}
+
+/* GDB version of error callback. */
+
+static void
+gdb_os_error (host_callback * p, const char *format,...)
+{
+ if (error_hook)
+ (*error_hook) ();
+ else
+ {
+ va_list args;
+ va_start (args, format);
+ verror (format, args);
+ va_end (args);
+ }
+}
+
+static void
+gdbsim_fetch_register (int regno)
+{
+ static int warn_user = 1;
+ if (regno == -1)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ gdbsim_fetch_register (regno);
+ }
+ else if (REGISTER_NAME (regno) != NULL
+ && *REGISTER_NAME (regno) != '\0')
+ {
+ char buf[MAX_REGISTER_RAW_SIZE];
+ int nr_bytes;
+ if (REGISTER_SIM_REGNO (regno) >= 0)
+ nr_bytes = sim_fetch_register (gdbsim_desc,
+ REGISTER_SIM_REGNO (regno),
+ buf, REGISTER_RAW_SIZE (regno));
+ else
+ nr_bytes = 0;
+ if (nr_bytes == 0)
+ /* register not applicable, supply zero's */
+ memset (buf, 0, MAX_REGISTER_RAW_SIZE);
+ else if (nr_bytes > 0 && nr_bytes != REGISTER_RAW_SIZE (regno)
+ && warn_user)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "Size of register %s (%d/%d) incorrect (%d instead of %d))",
+ REGISTER_NAME (regno),
+ regno, REGISTER_SIM_REGNO (regno),
+ nr_bytes, REGISTER_RAW_SIZE (regno));
+ warn_user = 0;
+ }
+ supply_register (regno, buf);
+ if (sr_get_debug ())
+ {
+ printf_filtered ("gdbsim_fetch_register: %d", regno);
+ /* FIXME: We could print something more intelligible. */
+ dump_mem (buf, REGISTER_RAW_SIZE (regno));
+ }
+ }
+}
+
+
+static void
+gdbsim_store_register (int regno)
+{
+ if (regno == -1)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ gdbsim_store_register (regno);
+ }
+ else if (REGISTER_NAME (regno) != NULL
+ && *REGISTER_NAME (regno) != '\0'
+ && REGISTER_SIM_REGNO (regno) >= 0)
+ {
+ char tmp[MAX_REGISTER_RAW_SIZE];
+ int nr_bytes;
+ read_register_gen (regno, tmp);
+ nr_bytes = sim_store_register (gdbsim_desc,
+ REGISTER_SIM_REGNO (regno),
+ tmp, REGISTER_RAW_SIZE (regno));
+ if (nr_bytes > 0 && nr_bytes != REGISTER_RAW_SIZE (regno))
+ internal_error (__FILE__, __LINE__,
+ "Register size different to expected");
+ if (sr_get_debug ())
+ {
+ printf_filtered ("gdbsim_store_register: %d", regno);
+ /* FIXME: We could print something more intelligible. */
+ dump_mem (tmp, REGISTER_RAW_SIZE (regno));
+ }
+ }
+}
+
+/* Kill the running program. This may involve closing any open files
+ and releasing other resources acquired by the simulated program. */
+
+static void
+gdbsim_kill (void)
+{
+ if (sr_get_debug ())
+ printf_filtered ("gdbsim_kill\n");
+
+ /* There is no need to `kill' running simulator - the simulator is
+ not running */
+ inferior_ptid = null_ptid;
+}
+
+/* Load an executable file into the target process. This is expected to
+ not only bring new code into the target process, but also to update
+ GDB's symbol tables to match. */
+
+static void
+gdbsim_load (char *prog, int fromtty)
+{
+ if (sr_get_debug ())
+ printf_filtered ("gdbsim_load: prog \"%s\"\n", prog);
+
+ inferior_ptid = null_ptid;
+
+ /* FIXME: We will print two messages on error.
+ Need error to either not print anything if passed NULL or need
+ another routine that doesn't take any arguments. */
+ if (sim_load (gdbsim_desc, prog, NULL, fromtty) == SIM_RC_FAIL)
+ error ("unable to load program");
+
+ /* FIXME: If a load command should reset the targets registers then
+ a call to sim_create_inferior() should go here. */
+
+ program_loaded = 1;
+}
+
+
+/* Start an inferior process and set inferior_ptid to its pid.
+ EXEC_FILE is the file to run.
+ ARGS is a string containing the arguments to the program.
+ ENV is the environment vector to pass. Errors reported with error().
+ On VxWorks and various standalone systems, we ignore exec_file. */
+/* This is called not only when we first attach, but also when the
+ user types "run" after having attached. */
+
+static void
+gdbsim_create_inferior (char *exec_file, char *args, char **env)
+{
+ int len;
+ char *arg_buf, **argv;
+
+ if (exec_file == 0 || exec_bfd == 0)
+ warning ("No executable file specified.");
+ if (!program_loaded)
+ warning ("No program loaded.");
+
+ if (sr_get_debug ())
+ printf_filtered ("gdbsim_create_inferior: exec_file \"%s\", args \"%s\"\n",
+ (exec_file ? exec_file : "(NULL)"),
+ args);
+
+ gdbsim_kill ();
+ remove_breakpoints ();
+ init_wait_for_inferior ();
+
+ if (exec_file != NULL)
+ {
+ len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10;
+ arg_buf = (char *) alloca (len);
+ arg_buf[0] = '\0';
+ strcat (arg_buf, exec_file);
+ strcat (arg_buf, " ");
+ strcat (arg_buf, args);
+ argv = buildargv (arg_buf);
+ make_cleanup_freeargv (argv);
+ }
+ else
+ argv = NULL;
+ sim_create_inferior (gdbsim_desc, exec_bfd, argv, env);
+
+ inferior_ptid = pid_to_ptid (42);
+ insert_breakpoints (); /* Needed to get correct instruction in cache */
+
+ clear_proceed_status ();
+
+ /* NB: Entry point already set by sim_create_inferior. */
+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+}
+
+/* The open routine takes the rest of the parameters from the command,
+ and (if successful) pushes a new target onto the stack.
+ Targets should supply this routine, if only to provide an error message. */
+/* Called when selecting the simulator. EG: (gdb) target sim name. */
+
+static void
+gdbsim_open (char *args, int from_tty)
+{
+ int len;
+ char *arg_buf;
+ char **argv;
+
+ if (sr_get_debug ())
+ printf_filtered ("gdbsim_open: args \"%s\"\n", args ? args : "(null)");
+
+ /* Remove current simulator if one exists. Only do this if the simulator
+ has been opened because sim_close requires it.
+ This is important because the call to push_target below will cause
+ sim_close to be called if the simulator is already open, but push_target
+ is called after sim_open! We can't move the call to push_target before
+ the call to sim_open because sim_open may invoke `error'. */
+ if (gdbsim_desc != NULL)
+ unpush_target (&gdbsim_ops);
+
+ len = (7 + 1 /* gdbsim */
+ + strlen (" -E little")
+ + strlen (" --architecture=xxxxxxxxxx")
+ + (args ? strlen (args) : 0)
+ + 50) /* slack */ ;
+ arg_buf = (char *) alloca (len);
+ strcpy (arg_buf, "gdbsim"); /* 7 */
+ /* Specify the byte order for the target when it is both selectable
+ and explicitly specified by the user (not auto detected). */
+ if (!TARGET_BYTE_ORDER_AUTO)
+ {
+ switch (TARGET_BYTE_ORDER)
+ {
+ case BFD_ENDIAN_BIG:
+ strcat (arg_buf, " -E big");
+ break;
+ case BFD_ENDIAN_LITTLE:
+ strcat (arg_buf, " -E little");
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "Value of TARGET_BYTE_ORDER unknown");
+ }
+ }
+ /* Specify the architecture of the target when it has been
+ explicitly specified */
+ if (!TARGET_ARCHITECTURE_AUTO)
+ {
+ strcat (arg_buf, " --architecture=");
+ strcat (arg_buf, TARGET_ARCHITECTURE->printable_name);
+ }
+ /* finally, any explicit args */
+ if (args)
+ {
+ strcat (arg_buf, " "); /* 1 */
+ strcat (arg_buf, args);
+ }
+ argv = buildargv (arg_buf);
+ if (argv == NULL)
+ error ("Insufficient memory available to allocate simulator arg list.");
+ make_cleanup_freeargv (argv);
+
+ init_callbacks ();
+ gdbsim_desc = sim_open (SIM_OPEN_DEBUG, &gdb_callback, exec_bfd, argv);
+
+ if (gdbsim_desc == 0)
+ error ("unable to create simulator instance");
+
+ push_target (&gdbsim_ops);
+ target_fetch_registers (-1);
+ printf_filtered ("Connected to the simulator.\n");
+}
+
+/* Does whatever cleanup is required for a target that we are no longer
+ going to be calling. Argument says whether we are quitting gdb and
+ should not get hung in case of errors, or whether we want a clean
+ termination even if it takes a while. This routine is automatically
+ always called just before a routine is popped off the target stack.
+ Closing file descriptors and freeing memory are typical things it should
+ do. */
+/* Close out all files and local state before this target loses control. */
+
+static void
+gdbsim_close (int quitting)
+{
+ if (sr_get_debug ())
+ printf_filtered ("gdbsim_close: quitting %d\n", quitting);
+
+ program_loaded = 0;
+
+ if (gdbsim_desc != NULL)
+ {
+ sim_close (gdbsim_desc, quitting);
+ gdbsim_desc = NULL;
+ }
+
+ end_callbacks ();
+ generic_mourn_inferior ();
+}
+
+/* Takes a program previously attached to and detaches it.
+ The program may resume execution (some targets do, some don't) and will
+ no longer stop on signals, etc. We better not have left any breakpoints
+ in the program or it'll die when it hits one. ARGS is arguments
+ typed by the user (e.g. a signal to send the process). FROM_TTY
+ says whether to be verbose or not. */
+/* Terminate the open connection to the remote debugger.
+ Use this when you want to detach and do something else with your gdb. */
+
+static void
+gdbsim_detach (char *args, int from_tty)
+{
+ if (sr_get_debug ())
+ printf_filtered ("gdbsim_detach: args \"%s\"\n", args);
+
+ pop_target (); /* calls gdbsim_close to do the real work */
+ if (from_tty)
+ printf_filtered ("Ending simulator %s debugging\n", target_shortname);
+}
+
+/* Resume execution of the target process. STEP says whether to single-step
+ or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given
+ to the target, or zero for no signal. */
+
+static enum target_signal resume_siggnal;
+static int resume_step;
+
+static void
+gdbsim_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ if (PIDGET (inferior_ptid) != 42)
+ error ("The program is not being run.");
+
+ if (sr_get_debug ())
+ printf_filtered ("gdbsim_resume: step %d, signal %d\n", step, siggnal);
+
+ resume_siggnal = siggnal;
+ resume_step = step;
+}
+
+/* Notify the simulator of an asynchronous request to stop.
+
+ The simulator shall ensure that the stop request is eventually
+ delivered to the simulator. If the call is made while the
+ simulator is not running then the stop request is processed when
+ the simulator is next resumed.
+
+ For simulators that do not support this operation, just abort */
+
+static void
+gdbsim_stop (void)
+{
+ if (!sim_stop (gdbsim_desc))
+ {
+ quit ();
+ }
+}
+
+/* GDB version of os_poll_quit callback.
+ Taken from gdb/util.c - should be in a library */
+
+static int
+gdb_os_poll_quit (host_callback *p)
+{
+ if (ui_loop_hook != NULL)
+ ui_loop_hook (0);
+
+ if (quit_flag) /* gdb's idea of quit */
+ {
+ quit_flag = 0; /* we've stolen it */
+ return 1;
+ }
+ else if (immediate_quit)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/* Wait for inferior process to do something. Return pid of child,
+ or -1 in case of error; store status through argument pointer STATUS,
+ just as `wait' would. */
+
+static void
+gdbsim_cntrl_c (int signo)
+{
+ gdbsim_stop ();
+}
+
+static ptid_t
+gdbsim_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ static RETSIGTYPE (*prev_sigint) ();
+ int sigrc = 0;
+ enum sim_stop reason = sim_running;
+
+ if (sr_get_debug ())
+ printf_filtered ("gdbsim_wait\n");
+
+#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
+ {
+ struct sigaction sa, osa;
+ sa.sa_handler = gdbsim_cntrl_c;
+ sigemptyset (&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction (SIGINT, &sa, &osa);
+ prev_sigint = osa.sa_handler;
+ }
+#else
+ prev_sigint = signal (SIGINT, gdbsim_cntrl_c);
+#endif
+ sim_resume (gdbsim_desc, resume_step,
+ target_signal_to_host (resume_siggnal));
+ signal (SIGINT, prev_sigint);
+ resume_step = 0;
+
+ sim_stop_reason (gdbsim_desc, &reason, &sigrc);
+
+ switch (reason)
+ {
+ case sim_exited:
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = sigrc;
+ break;
+ case sim_stopped:
+ switch (sigrc)
+ {
+ case SIGABRT:
+ quit ();
+ break;
+ case SIGINT:
+ case SIGTRAP:
+ default:
+ status->kind = TARGET_WAITKIND_STOPPED;
+ /* The signal in sigrc is a host signal. That probably
+ should be fixed. */
+ status->value.sig = target_signal_from_host (sigrc);
+ break;
+ }
+ break;
+ case sim_signalled:
+ status->kind = TARGET_WAITKIND_SIGNALLED;
+ /* The signal in sigrc is a host signal. That probably
+ should be fixed. */
+ status->value.sig = target_signal_from_host (sigrc);
+ break;
+ case sim_running:
+ case sim_polling:
+ /* FIXME: Is this correct? */
+ break;
+ }
+
+ return inferior_ptid;
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+static void
+gdbsim_prepare_to_store (void)
+{
+ /* Do nothing, since we can store individual regs */
+}
+
+/* Transfer LEN bytes between GDB address MYADDR and target address
+ MEMADDR. If WRITE is non-zero, transfer them to the target,
+ otherwise transfer them from the target. TARGET is unused.
+
+ Returns the number of bytes transferred. */
+
+static int
+gdbsim_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int write, struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ if (!program_loaded)
+ error ("No program loaded.");
+
+ if (sr_get_debug ())
+ {
+ /* FIXME: Send to something other than STDOUT? */
+ printf_filtered ("gdbsim_xfer_inferior_memory: myaddr 0x");
+ gdb_print_host_address (myaddr, gdb_stdout);
+ printf_filtered (", memaddr 0x%s, len %d, write %d\n",
+ paddr_nz (memaddr), len, write);
+ if (sr_get_debug () && write)
+ dump_mem (myaddr, len);
+ }
+
+ if (write)
+ {
+ len = sim_write (gdbsim_desc, memaddr, myaddr, len);
+ }
+ else
+ {
+ len = sim_read (gdbsim_desc, memaddr, myaddr, len);
+ if (sr_get_debug () && len > 0)
+ dump_mem (myaddr, len);
+ }
+ return len;
+}
+
+static void
+gdbsim_files_info (struct target_ops *target)
+{
+ char *file = "nothing";
+
+ if (exec_bfd)
+ file = bfd_get_filename (exec_bfd);
+
+ if (sr_get_debug ())
+ printf_filtered ("gdbsim_files_info: file \"%s\"\n", file);
+
+ if (exec_bfd)
+ {
+ printf_filtered ("\tAttached to %s running program %s\n",
+ target_shortname, file);
+ sim_info (gdbsim_desc, 0);
+ }
+}
+
+/* Clear the simulator's notion of what the break points are. */
+
+static void
+gdbsim_mourn_inferior (void)
+{
+ if (sr_get_debug ())
+ printf_filtered ("gdbsim_mourn_inferior:\n");
+
+ remove_breakpoints ();
+ generic_mourn_inferior ();
+}
+
+static int
+gdbsim_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+#ifdef SIM_HAS_BREAKPOINTS
+ SIM_RC retcode;
+
+ retcode = sim_set_breakpoint (gdbsim_desc, addr);
+
+ switch (retcode)
+ {
+ case SIM_RC_OK:
+ return 0;
+ case SIM_RC_INSUFFICIENT_RESOURCES:
+ return ENOMEM;
+ default:
+ return EIO;
+ }
+#else
+ return memory_insert_breakpoint (addr, contents_cache);
+#endif
+}
+
+static int
+gdbsim_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+#ifdef SIM_HAS_BREAKPOINTS
+ SIM_RC retcode;
+
+ retcode = sim_clear_breakpoint (gdbsim_desc, addr);
+
+ switch (retcode)
+ {
+ case SIM_RC_OK:
+ case SIM_RC_UNKNOWN_BREAKPOINT:
+ return 0;
+ case SIM_RC_INSUFFICIENT_RESOURCES:
+ return ENOMEM;
+ default:
+ return EIO;
+ }
+#else
+ return memory_remove_breakpoint (addr, contents_cache);
+#endif
+}
+
+/* Pass the command argument through to the simulator verbatim. The
+ simulator must do any command interpretation work. */
+
+void
+simulator_command (char *args, int from_tty)
+{
+ if (gdbsim_desc == NULL)
+ {
+
+ /* PREVIOUSLY: The user may give a command before the simulator
+ is opened. [...] (??? assuming of course one wishes to
+ continue to allow commands to be sent to unopened simulators,
+ which isn't entirely unreasonable). */
+
+ /* The simulator is a builtin abstraction of a remote target.
+ Consistent with that model, access to the simulator, via sim
+ commands, is restricted to the period when the channel to the
+ simulator is open. */
+
+ error ("Not connected to the simulator target");
+ }
+
+ sim_do_command (gdbsim_desc, args);
+
+ /* Invalidate the register cache, in case the simulator command does
+ something funny. */
+ registers_changed ();
+}
+
+/* Define the target subroutine names */
+
+struct target_ops gdbsim_ops;
+
+static void
+init_gdbsim_ops (void)
+{
+ gdbsim_ops.to_shortname = "sim";
+ gdbsim_ops.to_longname = "simulator";
+ gdbsim_ops.to_doc = "Use the compiled-in simulator.";
+ gdbsim_ops.to_open = gdbsim_open;
+ gdbsim_ops.to_close = gdbsim_close;
+ gdbsim_ops.to_attach = NULL;
+ gdbsim_ops.to_post_attach = NULL;
+ gdbsim_ops.to_require_attach = NULL;
+ gdbsim_ops.to_detach = gdbsim_detach;
+ gdbsim_ops.to_require_detach = NULL;
+ gdbsim_ops.to_resume = gdbsim_resume;
+ gdbsim_ops.to_wait = gdbsim_wait;
+ gdbsim_ops.to_post_wait = NULL;
+ gdbsim_ops.to_fetch_registers = gdbsim_fetch_register;
+ gdbsim_ops.to_store_registers = gdbsim_store_register;
+ gdbsim_ops.to_prepare_to_store = gdbsim_prepare_to_store;
+ gdbsim_ops.to_xfer_memory = gdbsim_xfer_inferior_memory;
+ gdbsim_ops.to_files_info = gdbsim_files_info;
+ gdbsim_ops.to_insert_breakpoint = gdbsim_insert_breakpoint;
+ gdbsim_ops.to_remove_breakpoint = gdbsim_remove_breakpoint;
+ gdbsim_ops.to_terminal_init = NULL;
+ gdbsim_ops.to_terminal_inferior = NULL;
+ gdbsim_ops.to_terminal_ours_for_output = NULL;
+ gdbsim_ops.to_terminal_ours = NULL;
+ gdbsim_ops.to_terminal_info = NULL;
+ gdbsim_ops.to_kill = gdbsim_kill;
+ gdbsim_ops.to_load = gdbsim_load;
+ gdbsim_ops.to_lookup_symbol = NULL;
+ gdbsim_ops.to_create_inferior = gdbsim_create_inferior;
+ gdbsim_ops.to_post_startup_inferior = NULL;
+ gdbsim_ops.to_acknowledge_created_inferior = NULL;
+ gdbsim_ops.to_clone_and_follow_inferior = NULL;
+ gdbsim_ops.to_post_follow_inferior_by_clone = NULL;
+ gdbsim_ops.to_insert_fork_catchpoint = NULL;
+ gdbsim_ops.to_remove_fork_catchpoint = NULL;
+ gdbsim_ops.to_insert_vfork_catchpoint = NULL;
+ gdbsim_ops.to_remove_vfork_catchpoint = NULL;
+ gdbsim_ops.to_has_forked = NULL;
+ gdbsim_ops.to_has_vforked = NULL;
+ gdbsim_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ gdbsim_ops.to_post_follow_vfork = NULL;
+ gdbsim_ops.to_insert_exec_catchpoint = NULL;
+ gdbsim_ops.to_remove_exec_catchpoint = NULL;
+ gdbsim_ops.to_has_execd = NULL;
+ gdbsim_ops.to_reported_exec_events_per_exec_call = NULL;
+ gdbsim_ops.to_has_exited = NULL;
+ gdbsim_ops.to_mourn_inferior = gdbsim_mourn_inferior;
+ gdbsim_ops.to_can_run = 0;
+ gdbsim_ops.to_notice_signals = 0;
+ gdbsim_ops.to_thread_alive = 0;
+ gdbsim_ops.to_stop = gdbsim_stop;
+ gdbsim_ops.to_pid_to_exec_file = NULL;
+ gdbsim_ops.to_stratum = process_stratum;
+ gdbsim_ops.DONT_USE = NULL;
+ gdbsim_ops.to_has_all_memory = 1;
+ gdbsim_ops.to_has_memory = 1;
+ gdbsim_ops.to_has_stack = 1;
+ gdbsim_ops.to_has_registers = 1;
+ gdbsim_ops.to_has_execution = 1;
+ gdbsim_ops.to_sections = NULL;
+ gdbsim_ops.to_sections_end = NULL;
+ gdbsim_ops.to_magic = OPS_MAGIC;
+
+#ifdef TARGET_REDEFINE_DEFAULT_OPS
+ TARGET_REDEFINE_DEFAULT_OPS (&gdbsim_ops);
+#endif
+}
+
+void
+_initialize_remote_sim (void)
+{
+ init_gdbsim_ops ();
+ add_target (&gdbsim_ops);
+
+ add_com ("sim <command>", class_obscure, simulator_command,
+ "Send a command to the simulator.");
+}
diff --git a/gdb/remote-st.c b/gdb/remote-st.c
new file mode 100644
index 00000000000..c27ddebbf3b
--- /dev/null
+++ b/gdb/remote-st.c
@@ -0,0 +1,839 @@
+/* Remote debugging interface for Tandem ST2000 phone switch, for GDB.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000,
+ 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Support. Written by Jim Kingdon for Cygnus.
+
+ 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. */
+
+/* This file was derived from remote-eb.c, which did a similar job, but for
+ an AMD-29K running EBMON. That file was in turn derived from remote.c
+ as mentioned in the following comment (left in for comic relief):
+
+ "This is like remote.c but is for an esoteric situation--
+ having an a29k board in a PC hooked up to a unix machine with
+ a serial line, and running ctty com1 on the PC, through which
+ the unix machine can run ebmon. Not to mention that the PC
+ has PC/NFS, so it can access the same executables that gdb can,
+ over the net in real time."
+
+ In reality, this module talks to a debug monitor called 'STDEBUG', which
+ runs in a phone switch. We communicate with STDEBUG via either a direct
+ serial line, or a TCP (or possibly TELNET) stream to a terminal multiplexor,
+ which in turn talks to the phone switch. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "gdb_string.h"
+#include <sys/types.h>
+#include "serial.h"
+#include "regcache.h"
+
+extern struct target_ops st2000_ops; /* Forward declaration */
+
+static void st2000_close ();
+static void st2000_fetch_register ();
+static void st2000_store_register ();
+
+#define LOG_FILE "st2000.log"
+#if defined (LOG_FILE)
+FILE *log_file;
+#endif
+
+static int timeout = 24;
+
+/* Descriptor for I/O to remote machine. Initialize it to -1 so that
+ st2000_open knows that we don't have a file open when the program
+ starts. */
+
+static struct serial *st2000_desc;
+
+/* Send data to stdebug. Works just like printf. */
+
+static void
+printf_stdebug (char *pattern,...)
+{
+ va_list args;
+ char buf[200];
+
+ va_start (args, pattern);
+
+ vsprintf (buf, pattern, args);
+ va_end (args);
+
+ if (serial_write (st2000_desc, buf, strlen (buf)))
+ fprintf_unfiltered (gdb_stderr, "serial_write failed: %s\n",
+ safe_strerror (errno));
+}
+
+/* Read a character from the remote system, doing all the fancy timeout
+ stuff. */
+
+static int
+readchar (int timeout)
+{
+ int c;
+
+ c = serial_readchar (st2000_desc, timeout);
+
+#ifdef LOG_FILE
+ putc (c & 0x7f, log_file);
+#endif
+
+ if (c >= 0)
+ return c & 0x7f;
+
+ if (c == SERIAL_TIMEOUT)
+ {
+ if (timeout == 0)
+ return c; /* Polls shouldn't generate timeout errors */
+
+ error ("Timeout reading from remote system.");
+ }
+
+ perror_with_name ("remote-st2000");
+}
+
+/* Scan input from the remote system, until STRING is found. If DISCARD is
+ non-zero, then discard non-matching input, else print it out.
+ Let the user break out immediately. */
+static void
+expect (char *string, int discard)
+{
+ char *p = string;
+ int c;
+
+ immediate_quit++;
+ while (1)
+ {
+ c = readchar (timeout);
+ if (c == *p++)
+ {
+ if (*p == '\0')
+ {
+ immediate_quit--;
+ return;
+ }
+ }
+ else
+ {
+ if (!discard)
+ {
+ fwrite (string, 1, (p - 1) - string, stdout);
+ putchar ((char) c);
+ fflush (stdout);
+ }
+ p = string;
+ }
+ }
+}
+
+/* Keep discarding input until we see the STDEBUG prompt.
+
+ The convention for dealing with the prompt is that you
+ o give your command
+ o *then* wait for the prompt.
+
+ Thus the last thing that a procedure does with the serial line
+ will be an expect_prompt(). Exception: st2000_resume does not
+ wait for the prompt, because the terminal is being handed over
+ to the inferior. However, the next thing which happens after that
+ is a st2000_wait which does wait for the prompt.
+ Note that this includes abnormal exit, e.g. error(). This is
+ necessary to prevent getting into states from which we can't
+ recover. */
+static void
+expect_prompt (int discard)
+{
+#if defined (LOG_FILE)
+ /* This is a convenient place to do this. The idea is to do it often
+ enough that we never lose much data if we terminate abnormally. */
+ fflush (log_file);
+#endif
+ expect ("dbug> ", discard);
+}
+
+/* Get a hex digit from the remote system & return its value.
+ If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
+static int
+get_hex_digit (int ignore_space)
+{
+ int ch;
+ while (1)
+ {
+ ch = readchar (timeout);
+ if (ch >= '0' && ch <= '9')
+ return ch - '0';
+ else if (ch >= 'A' && ch <= 'F')
+ return ch - 'A' + 10;
+ else if (ch >= 'a' && ch <= 'f')
+ return ch - 'a' + 10;
+ else if (ch == ' ' && ignore_space)
+ ;
+ else
+ {
+ expect_prompt (1);
+ error ("Invalid hex digit from remote system.");
+ }
+ }
+}
+
+/* Get a byte from stdebug and put it in *BYT. Accept any number
+ leading spaces. */
+static void
+get_hex_byte (char *byt)
+{
+ int val;
+
+ val = get_hex_digit (1) << 4;
+ val |= get_hex_digit (0);
+ *byt = val;
+}
+
+/* Get N 32-bit words from remote, each preceded by a space,
+ and put them in registers starting at REGNO. */
+static void
+get_hex_regs (int n, int regno)
+{
+ long val;
+ int i;
+
+ for (i = 0; i < n; i++)
+ {
+ int j;
+
+ val = 0;
+ for (j = 0; j < 8; j++)
+ val = (val << 4) + get_hex_digit (j == 0);
+ supply_register (regno++, (char *) &val);
+ }
+}
+
+/* This is called not only when we first attach, but also when the
+ user types "run" after having attached. */
+static void
+st2000_create_inferior (char *execfile, char *args, char **env)
+{
+ int entry_pt;
+
+ if (args && *args)
+ error ("Can't pass arguments to remote STDEBUG process");
+
+ if (execfile == 0 || exec_bfd == 0)
+ error ("No executable file specified");
+
+ entry_pt = (int) bfd_get_start_address (exec_bfd);
+
+/* The "process" (board) is already stopped awaiting our commands, and
+ the program is already downloaded. We just set its PC and go. */
+
+ clear_proceed_status ();
+
+ /* Tell wait_for_inferior that we've started a new process. */
+ init_wait_for_inferior ();
+
+ /* Set up the "saved terminal modes" of the inferior
+ based on what modes we are starting it with. */
+ target_terminal_init ();
+
+ /* Install inferior's terminal modes. */
+ target_terminal_inferior ();
+
+ /* insert_step_breakpoint (); FIXME, do we need this? */
+ /* Let 'er rip... */
+ proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0);
+}
+
+/* Open a connection to a remote debugger.
+ NAME is the filename used for communication. */
+
+static int baudrate = 9600;
+static char dev_name[100];
+
+static void
+st2000_open (char *args, int from_tty)
+{
+ int n;
+ char junk[100];
+
+ target_preopen (from_tty);
+
+ n = sscanf (args, " %s %d %s", dev_name, &baudrate, junk);
+
+ if (n != 2)
+ error ("Bad arguments. Usage: target st2000 <device> <speed>\n\
+or target st2000 <host> <port>\n");
+
+ st2000_close (0);
+
+ st2000_desc = serial_open (dev_name);
+
+ if (!st2000_desc)
+ perror_with_name (dev_name);
+
+ if (serial_setbaudrate (st2000_desc, baudrate))
+ {
+ serial_close (dev_name);
+ perror_with_name (dev_name);
+ }
+
+ serial_raw (st2000_desc);
+
+ push_target (&st2000_ops);
+
+#if defined (LOG_FILE)
+ log_file = fopen (LOG_FILE, "w");
+ if (log_file == NULL)
+ perror_with_name (LOG_FILE);
+#endif
+
+ /* Hello? Are you there? */
+ printf_stdebug ("\003"); /* ^C wakes up dbug */
+
+ expect_prompt (1);
+
+ if (from_tty)
+ printf ("Remote %s connected to %s\n", target_shortname,
+ dev_name);
+}
+
+/* Close out all files and local state before this target loses control. */
+
+static void
+st2000_close (int quitting)
+{
+ serial_close (st2000_desc);
+
+#if defined (LOG_FILE)
+ if (log_file)
+ {
+ if (ferror (log_file))
+ fprintf_unfiltered (gdb_stderr, "Error writing log file.\n");
+ if (fclose (log_file) != 0)
+ fprintf_unfiltered (gdb_stderr, "Error closing log file.\n");
+ }
+#endif
+}
+
+/* Terminate the open connection to the remote debugger.
+ Use this when you want to detach and do something else
+ with your gdb. */
+static void
+st2000_detach (int from_tty)
+{
+ pop_target (); /* calls st2000_close to do the real work */
+ if (from_tty)
+ printf ("Ending remote %s debugging\n", target_shortname);
+}
+
+/* Tell the remote machine to resume. */
+
+static void
+st2000_resume (ptid_t ptid, int step, enum target_signal sig)
+{
+ if (step)
+ {
+ printf_stdebug ("ST\r");
+ /* Wait for the echo. */
+ expect ("ST\r", 1);
+ }
+ else
+ {
+ printf_stdebug ("GO\r");
+ /* Swallow the echo. */
+ expect ("GO\r", 1);
+ }
+}
+
+/* Wait until the remote machine stops, then return,
+ storing status in STATUS just as `wait' would. */
+
+static ptid_t
+st2000_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ int old_timeout = timeout;
+
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = 0;
+
+ timeout = 0; /* Don't time out -- user program is running. */
+
+ expect_prompt (0); /* Wait for prompt, outputting extraneous text */
+
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+
+ timeout = old_timeout;
+
+ return inferior_ptid;
+}
+
+/* Return the name of register number REGNO in the form input and output by
+ STDEBUG. Currently, REGISTER_NAMES just happens to contain exactly what
+ STDEBUG wants. Lets take advantage of that just as long as possible! */
+
+static char *
+get_reg_name (int regno)
+{
+ static char buf[50];
+ const char *p;
+ char *b;
+
+ b = buf;
+
+ for (p = REGISTER_NAME (regno); *p; p++)
+ *b++ = toupper (*p);
+ *b = '\000';
+
+ return buf;
+}
+
+/* Read the remote registers into the block REGS. */
+
+static void
+st2000_fetch_registers (void)
+{
+ int regno;
+
+ /* Yeah yeah, I know this is horribly inefficient. But it isn't done
+ very often... I'll clean it up later. */
+
+ for (regno = 0; regno <= PC_REGNUM; regno++)
+ st2000_fetch_register (regno);
+}
+
+/* Fetch register REGNO, or all registers if REGNO is -1.
+ Returns errno value. */
+static void
+st2000_fetch_register (int regno)
+{
+ if (regno == -1)
+ st2000_fetch_registers ();
+ else
+ {
+ char *name = get_reg_name (regno);
+ printf_stdebug ("DR %s\r", name);
+ expect (name, 1);
+ expect (" : ", 1);
+ get_hex_regs (1, regno);
+ expect_prompt (1);
+ }
+ return;
+}
+
+/* Store the remote registers from the contents of the block REGS. */
+
+static void
+st2000_store_registers (void)
+{
+ int regno;
+
+ for (regno = 0; regno <= PC_REGNUM; regno++)
+ st2000_store_register (regno);
+
+ registers_changed ();
+}
+
+/* Store register REGNO, or all if REGNO == 0.
+ Return errno value. */
+static void
+st2000_store_register (int regno)
+{
+ if (regno == -1)
+ st2000_store_registers ();
+ else
+ {
+ printf_stdebug ("PR %s %x\r", get_reg_name (regno),
+ read_register (regno));
+
+ expect_prompt (1);
+ }
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+static void
+st2000_prepare_to_store (void)
+{
+ /* Do nothing, since we can store individual regs */
+}
+
+static void
+st2000_files_info (void)
+{
+ printf ("\tAttached to %s at %d baud.\n",
+ dev_name, baudrate);
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+ to inferior's memory at MEMADDR. Returns length moved. */
+static int
+st2000_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ printf_stdebug ("PM.B %x %x\r", memaddr + i, myaddr[i]);
+ expect_prompt (1);
+ }
+ return len;
+}
+
+/* Read LEN bytes from inferior memory at MEMADDR. Put the result
+ at debugger address MYADDR. Returns length moved. */
+static int
+st2000_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ int i;
+
+ /* Number of bytes read so far. */
+ int count;
+
+ /* Starting address of this pass. */
+ unsigned long startaddr;
+
+ /* Number of bytes to read in this pass. */
+ int len_this_pass;
+
+ /* Note that this code works correctly if startaddr is just less
+ than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
+ thing). That is, something like
+ st2000_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
+ works--it never adds len to memaddr and gets 0. */
+ /* However, something like
+ st2000_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
+ doesn't need to work. Detect it and give up if there's an attempt
+ to do that. */
+ if (((memaddr - 1) + len) < memaddr)
+ {
+ errno = EIO;
+ return 0;
+ }
+
+ startaddr = memaddr;
+ count = 0;
+ while (count < len)
+ {
+ len_this_pass = 16;
+ if ((startaddr % 16) != 0)
+ len_this_pass -= startaddr % 16;
+ if (len_this_pass > (len - count))
+ len_this_pass = (len - count);
+
+ printf_stdebug ("DI.L %x %x\r", startaddr, len_this_pass);
+ expect (": ", 1);
+
+ for (i = 0; i < len_this_pass; i++)
+ get_hex_byte (&myaddr[count++]);
+
+ expect_prompt (1);
+
+ startaddr += len_this_pass;
+ }
+ return len;
+}
+
+/* Transfer LEN bytes between GDB address MYADDR and target address
+ MEMADDR. If WRITE is non-zero, transfer them to the target,
+ otherwise transfer them from the target. TARGET is unused.
+
+ Returns the number of bytes transferred. */
+
+static int
+st2000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int write, struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ if (write)
+ return st2000_write_inferior_memory (memaddr, myaddr, len);
+ else
+ return st2000_read_inferior_memory (memaddr, myaddr, len);
+}
+
+static void
+st2000_kill (char *args, int from_tty)
+{
+ return; /* Ignore attempts to kill target system */
+}
+
+/* Clean up when a program exits.
+
+ The program actually lives on in the remote processor's RAM, and may be
+ run again without a download. Don't leave it full of breakpoint
+ instructions. */
+
+static void
+st2000_mourn_inferior (void)
+{
+ remove_breakpoints ();
+ unpush_target (&st2000_ops);
+ generic_mourn_inferior (); /* Do all the proper things now */
+}
+
+#define MAX_STDEBUG_BREAKPOINTS 16
+
+static CORE_ADDR breakaddr[MAX_STDEBUG_BREAKPOINTS] =
+{0};
+
+static int
+st2000_insert_breakpoint (CORE_ADDR addr, char *shadow)
+{
+ int i;
+ CORE_ADDR bp_addr = addr;
+ int bp_size = 0;
+
+ BREAKPOINT_FROM_PC (&bp_addr, &bp_size);
+
+ for (i = 0; i <= MAX_STDEBUG_BREAKPOINTS; i++)
+ if (breakaddr[i] == 0)
+ {
+ breakaddr[i] = addr;
+
+ st2000_read_inferior_memory (bp_addr, shadow, bp_size);
+ printf_stdebug ("BR %x H\r", addr);
+ expect_prompt (1);
+ return 0;
+ }
+
+ fprintf_unfiltered (gdb_stderr, "Too many breakpoints (> 16) for STDBUG\n");
+ return 1;
+}
+
+static int
+st2000_remove_breakpoint (CORE_ADDR addr, char *shadow)
+{
+ int i;
+
+ for (i = 0; i < MAX_STDEBUG_BREAKPOINTS; i++)
+ if (breakaddr[i] == addr)
+ {
+ breakaddr[i] = 0;
+
+ printf_stdebug ("CB %d\r", i);
+ expect_prompt (1);
+ return 0;
+ }
+
+ fprintf_unfiltered (gdb_stderr,
+ "Can't find breakpoint associated with 0x%x\n", addr);
+ return 1;
+}
+
+
+/* Put a command string, in args, out to STDBUG. Output from STDBUG is placed
+ on the users terminal until the prompt is seen. */
+
+static void
+st2000_command (char *args, int fromtty)
+{
+ if (!st2000_desc)
+ error ("st2000 target not open.");
+
+ if (!args)
+ error ("Missing command.");
+
+ printf_stdebug ("%s\r", args);
+ expect_prompt (0);
+}
+
+/* Connect the user directly to STDBUG. This command acts just like the
+ 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
+
+/*static struct ttystate ttystate; */
+
+static void
+cleanup_tty (void)
+{
+ printf ("\r\n[Exiting connect mode]\r\n");
+/* serial_restore(0, &ttystate); */
+}
+
+#if 0
+/* This all should now be in serial.c */
+
+static void
+connect_command (char *args, int fromtty)
+{
+ fd_set readfds;
+ int numfds;
+ int c;
+ char cur_esc = 0;
+
+ dont_repeat ();
+
+ if (st2000_desc < 0)
+ error ("st2000 target not open.");
+
+ if (args)
+ fprintf ("This command takes no args. They have been ignored.\n");
+
+ printf ("[Entering connect mode. Use ~. or ~^D to escape]\n");
+
+ serial_raw (0, &ttystate);
+
+ make_cleanup (cleanup_tty, 0);
+
+ FD_ZERO (&readfds);
+
+ while (1)
+ {
+ do
+ {
+ FD_SET (0, &readfds);
+ FD_SET (deprecated_serial_fd (st2000_desc), &readfds);
+ numfds = select (sizeof (readfds) * 8, &readfds, 0, 0, 0);
+ }
+ while (numfds == 0);
+
+ if (numfds < 0)
+ perror_with_name ("select");
+
+ if (FD_ISSET (0, &readfds))
+ { /* tty input, send to stdebug */
+ c = getchar ();
+ if (c < 0)
+ perror_with_name ("connect");
+
+ printf_stdebug ("%c", c);
+ switch (cur_esc)
+ {
+ case 0:
+ if (c == '\r')
+ cur_esc = c;
+ break;
+ case '\r':
+ if (c == '~')
+ cur_esc = c;
+ else
+ cur_esc = 0;
+ break;
+ case '~':
+ if (c == '.' || c == '\004')
+ return;
+ else
+ cur_esc = 0;
+ }
+ }
+
+ if (FD_ISSET (deprecated_serial_fd (st2000_desc), &readfds))
+ {
+ while (1)
+ {
+ c = readchar (0);
+ if (c < 0)
+ break;
+ putchar (c);
+ }
+ fflush (stdout);
+ }
+ }
+}
+#endif /* 0 */
+
+/* Define the target subroutine names */
+
+struct target_ops st2000_ops;
+
+static void
+init_st2000_ops (void)
+{
+ st2000_ops.to_shortname = "st2000";
+ st2000_ops.to_longname = "Remote serial Tandem ST2000 target";
+ st2000_ops.to_doc = "Use a remote computer running STDEBUG connected by a serial line;\n\
+or a network connection.\n\
+Arguments are the name of the device for the serial line,\n\
+the speed to connect at in bits per second.";
+ st2000_ops.to_open = st2000_open;
+ st2000_ops.to_close = st2000_close;
+ st2000_ops.to_attach = 0;
+ st2000_run_ops.to_post_attach = NULL;
+ st2000_ops.to_require_attach = NULL;
+ st2000_ops.to_detach = st2000_detach;
+ st2000_ops.to_require_detach = NULL;
+ st2000_ops.to_resume = st2000_resume;
+ st2000_ops.to_wait = st2000_wait;
+ st2000_ops.to_post_wait = NULL;
+ st2000_ops.to_fetch_registers = st2000_fetch_register;
+ st2000_ops.to_store_registers = st2000_store_register;
+ st2000_ops.to_prepare_to_store = st2000_prepare_to_store;
+ st2000_ops.to_xfer_memory = st2000_xfer_inferior_memory;
+ st2000_ops.to_files_info = st2000_files_info;
+ st2000_ops.to_insert_breakpoint = st2000_insert_breakpoint;
+ st2000_ops.to_remove_breakpoint = st2000_remove_breakpoint; /* Breakpoints */
+ st2000_ops.to_terminal_init = 0;
+ st2000_ops.to_terminal_inferior = 0;
+ st2000_ops.to_terminal_ours_for_output = 0;
+ st2000_ops.to_terminal_ours = 0;
+ st2000_ops.to_terminal_info = 0; /* Terminal handling */
+ st2000_ops.to_kill = st2000_kill;
+ st2000_ops.to_load = 0; /* load */
+ st2000_ops.to_lookup_symbol = 0; /* lookup_symbol */
+ st2000_ops.to_create_inferior = st2000_create_inferior;
+ st2000_ops.to_post_startup_inferior = NULL;
+ st2000_ops.to_acknowledge_created_inferior = NULL;
+ st2000_ops.to_clone_and_follow_inferior = NULL;
+ st2000_ops.to_post_follow_inferior_by_clone = NULL;
+ st2000_run_ops.to_insert_fork_catchpoint = NULL;
+ st2000_run_ops.to_remove_fork_catchpoint = NULL;
+ st2000_run_ops.to_insert_vfork_catchpoint = NULL;
+ st2000_run_ops.to_remove_vfork_catchpoint = NULL;
+ st2000_ops.to_has_forked = NULL;
+ st2000_ops.to_has_vforked = NULL;
+ st2000_run_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ st2000_ops.to_post_follow_vfork = NULL;
+ st2000_run_ops.to_insert_exec_catchpoint = NULL;
+ st2000_run_ops.to_remove_exec_catchpoint = NULL;
+ st2000_run_ops.to_has_execd = NULL;
+ st2000_run_ops.to_reported_exec_events_per_exec_call = NULL;
+ st2000_run_ops.to_has_exited = NULL;
+ st2000_ops.to_mourn_inferior = st2000_mourn_inferior;
+ st2000_ops.to_can_run = 0; /* can_run */
+ st2000_ops.to_notice_signals = 0; /* notice_signals */
+ st2000_ops.to_thread_alive = 0; /* thread alive */
+ st2000_ops.to_stop = 0; /* to_stop */
+ st2000_ops.to_pid_to_exec_file = NULL;
+ st2000_ops.to_stratum = process_stratum;
+ st2000_ops.DONT_USE = 0; /* next */
+ st2000_ops.to_has_all_memory = 1;
+ st2000_ops.to_has_memory = 1;
+ st2000_ops.to_has_stack = 1;
+ st2000_ops.to_has_registers = 1;
+ st2000_ops.to_has_execution = 1; /* all mem, mem, stack, regs, exec */
+ st2000_ops.to_sections = 0;
+ st2000_ops.to_sections_end = 0; /* Section pointers */
+ st2000_ops.to_magic = OPS_MAGIC; /* Always the last thing */
+};
+
+void
+_initialize_remote_st2000 (void)
+{
+ init_st2000_ops ();
+ add_target (&st2000_ops);
+ add_com ("st2000 <command>", class_obscure, st2000_command,
+ "Send a command to the STDBUG monitor.");
+ add_com ("connect", class_obscure, connect_command,
+ "Connect the terminal directly up to the STDBUG command monitor.\n\
+Use <CR>~. or <CR>~^D to break out.");
+}
diff --git a/gdb/remote-utils.c b/gdb/remote-utils.c
new file mode 100644
index 00000000000..ba150e34d5d
--- /dev/null
+++ b/gdb/remote-utils.c
@@ -0,0 +1,609 @@
+/* Generic support for remote debugging interfaces.
+
+ Copyright 1993, 1994, 1995, 1996, 1998, 2000, 2001
+ 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. */
+
+/* This file actually contains two distinct logical "packages". They
+ are packaged together in this one file because they are typically
+ used together.
+
+ The first package is an addition to the serial package. The
+ addition provides reading and writing with debugging output and
+ timeouts based on user settable variables. These routines are
+ intended to support serial port based remote backends. These
+ functions are prefixed with sr_.
+
+ The second package is a collection of more or less generic
+ functions for use by remote backends. They support user settable
+ variables for debugging, retries, and the like.
+
+ Todo:
+
+ * a pass through mode a la kermit or telnet.
+ * autobaud.
+ * ask remote to change his baud rate.
+ */
+
+#include <ctype.h>
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "serial.h"
+#include "gdbcore.h" /* for exec_bfd */
+#include "inferior.h" /* for generic_mourn_inferior */
+#include "remote-utils.h"
+#include "regcache.h"
+
+
+void _initialize_sr_support (void);
+
+struct _sr_settings sr_settings =
+{
+ 4, /* timeout:
+ remote-hms.c had 2
+ remote-bug.c had "with a timeout of 2, we time out waiting for
+ the prompt after an s-record dump."
+
+ remote.c had (2): This was 5 seconds, which is a long time to
+ sit and wait. Unless this is going though some terminal server
+ or multiplexer or other form of hairy serial connection, I
+ would think 2 seconds would be plenty.
+ */
+
+ 10, /* retries */
+ NULL, /* device */
+ NULL, /* descriptor */
+};
+
+struct gr_settings *gr_settings = NULL;
+
+static void usage (char *, char *);
+static void sr_com (char *, int);
+
+static void
+usage (char *proto, char *junk)
+{
+ if (junk != NULL)
+ fprintf_unfiltered (gdb_stderr, "Unrecognized arguments: `%s'.\n", junk);
+
+ error ("Usage: target %s [DEVICE [SPEED [DEBUG]]]\n\
+where DEVICE is the name of a device or HOST:PORT", proto);
+
+ return;
+}
+
+#define CHECKDONE(p, q) \
+{ \
+ if (q == p) \
+ { \
+ if (*p == '\0') \
+ return; \
+ else \
+ usage(proto, p); \
+ } \
+}
+
+void
+sr_scan_args (char *proto, char *args)
+{
+ int n;
+ char *p, *q;
+
+ /* if no args, then nothing to do. */
+ if (args == NULL || *args == '\0')
+ return;
+
+ /* scan off white space. */
+ for (p = args; isspace (*p); ++p);;
+
+ /* find end of device name. */
+ for (q = p; *q != '\0' && !isspace (*q); ++q);;
+
+ /* check for missing or empty device name. */
+ CHECKDONE (p, q);
+ sr_set_device (savestring (p, q - p));
+
+ /* look for baud rate. */
+ n = strtol (q, &p, 10);
+
+ /* check for missing or empty baud rate. */
+ CHECKDONE (p, q);
+ baud_rate = n;
+
+ /* look for debug value. */
+ n = strtol (p, &q, 10);
+
+ /* check for missing or empty debug value. */
+ CHECKDONE (p, q);
+ sr_set_debug (n);
+
+ /* scan off remaining white space. */
+ for (p = q; isspace (*p); ++p);;
+
+ /* if not end of string, then there's unrecognized junk. */
+ if (*p != '\0')
+ usage (proto, p);
+
+ return;
+}
+
+void
+gr_generic_checkin (void)
+{
+ sr_write_cr ("");
+ gr_expect_prompt ();
+}
+
+void
+gr_open (char *args, int from_tty, struct gr_settings *gr)
+{
+ target_preopen (from_tty);
+ sr_scan_args (gr->ops->to_shortname, args);
+ unpush_target (gr->ops);
+
+ gr_settings = gr;
+
+ if (sr_get_desc () != NULL)
+ gr_close (0);
+
+ /* If no args are specified, then we use the device specified by a
+ previous command or "set remotedevice". But if there is no
+ device, better stop now, not dump core. */
+
+ if (sr_get_device () == NULL)
+ usage (gr->ops->to_shortname, NULL);
+
+ sr_set_desc (serial_open (sr_get_device ()));
+ if (!sr_get_desc ())
+ perror_with_name ((char *) sr_get_device ());
+
+ if (baud_rate != -1)
+ {
+ if (serial_setbaudrate (sr_get_desc (), baud_rate) != 0)
+ {
+ serial_close (sr_get_desc ());
+ perror_with_name (sr_get_device ());
+ }
+ }
+
+ serial_raw (sr_get_desc ());
+
+ /* If there is something sitting in the buffer we might take it as a
+ response to a command, which would be bad. */
+ serial_flush_input (sr_get_desc ());
+
+ /* default retries */
+ if (sr_get_retries () == 0)
+ sr_set_retries (1);
+
+ /* default clear breakpoint function */
+ if (gr_settings->clear_all_breakpoints == NULL)
+ gr_settings->clear_all_breakpoints = remove_breakpoints;
+
+ if (from_tty)
+ {
+ printf_filtered ("Remote debugging using `%s'", sr_get_device ());
+ if (baud_rate != -1)
+ printf_filtered (" at baud rate of %d",
+ baud_rate);
+ printf_filtered ("\n");
+ }
+
+ push_target (gr->ops);
+ gr_checkin ();
+ gr_clear_all_breakpoints ();
+ return;
+}
+
+/* Read a character from the remote system masking it down to 7 bits
+ and doing all the fancy timeout stuff. */
+
+int
+sr_readchar (void)
+{
+ int buf;
+
+ buf = serial_readchar (sr_get_desc (), sr_get_timeout ());
+
+ if (buf == SERIAL_TIMEOUT)
+ error ("Timeout reading from remote system.");
+
+ if (sr_get_debug () > 0)
+ printf_unfiltered ("%c", buf);
+
+ return buf & 0x7f;
+}
+
+int
+sr_pollchar (void)
+{
+ int buf;
+
+ buf = serial_readchar (sr_get_desc (), 0);
+ if (buf == SERIAL_TIMEOUT)
+ buf = 0;
+ if (sr_get_debug () > 0)
+ {
+ if (buf)
+ printf_unfiltered ("%c", buf);
+ else
+ printf_unfiltered ("<empty character poll>");
+ }
+
+ return buf & 0x7f;
+}
+
+/* Keep discarding input from the remote system, until STRING is found.
+ Let the user break out immediately. */
+void
+sr_expect (char *string)
+{
+ char *p = string;
+
+ immediate_quit++;
+ while (1)
+ {
+ if (sr_readchar () == *p)
+ {
+ p++;
+ if (*p == '\0')
+ {
+ immediate_quit--;
+ return;
+ }
+ }
+ else
+ p = string;
+ }
+}
+
+void
+sr_write (char *a, int l)
+{
+ int i;
+
+ if (serial_write (sr_get_desc (), a, l) != 0)
+ perror_with_name ("sr_write: Error writing to remote");
+
+ if (sr_get_debug () > 0)
+ for (i = 0; i < l; i++)
+ printf_unfiltered ("%c", a[i]);
+
+ return;
+}
+
+void
+sr_write_cr (char *s)
+{
+ sr_write (s, strlen (s));
+ sr_write ("\r", 1);
+ return;
+}
+
+int
+sr_timed_read (char *buf, int n)
+{
+ int i;
+ char c;
+
+ i = 0;
+ while (i < n)
+ {
+ c = sr_readchar ();
+
+ if (c == 0)
+ return i;
+ buf[i] = c;
+ i++;
+
+ }
+ return i;
+}
+
+/* Get a hex digit from the remote system & return its value. If
+ ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
+
+int
+sr_get_hex_digit (int ignore_space)
+{
+ int ch;
+
+ while (1)
+ {
+ ch = sr_readchar ();
+ if (ch >= '0' && ch <= '9')
+ return ch - '0';
+ else if (ch >= 'A' && ch <= 'F')
+ return ch - 'A' + 10;
+ else if (ch >= 'a' && ch <= 'f')
+ return ch - 'a' + 10;
+ else if (ch != ' ' || !ignore_space)
+ {
+ gr_expect_prompt ();
+ error ("Invalid hex digit from remote system.");
+ }
+ }
+}
+
+/* Get a byte from the remote and put it in *BYT. Accept any number
+ leading spaces. */
+void
+sr_get_hex_byte (char *byt)
+{
+ int val;
+
+ val = sr_get_hex_digit (1) << 4;
+ val |= sr_get_hex_digit (0);
+ *byt = val;
+}
+
+/* Read a 32-bit hex word from the remote, preceded by a space */
+long
+sr_get_hex_word (void)
+{
+ long val;
+ int j;
+
+ val = 0;
+ for (j = 0; j < 8; j++)
+ val = (val << 4) + sr_get_hex_digit (j == 0);
+ return val;
+}
+
+/* Put a command string, in args, out to the remote. The remote is assumed to
+ be in raw mode, all writing/reading done through desc.
+ Ouput from the remote is placed on the users terminal until the
+ prompt from the remote is seen.
+ FIXME: Can't handle commands that take input. */
+
+static void
+sr_com (char *args, int fromtty)
+{
+ sr_check_open ();
+
+ if (!args)
+ return;
+
+ /* Clear all input so only command relative output is displayed */
+
+ sr_write_cr (args);
+ sr_write ("\030", 1);
+ registers_changed ();
+ gr_expect_prompt ();
+}
+
+void
+gr_close (int quitting)
+{
+ gr_clear_all_breakpoints ();
+
+ if (sr_is_open ())
+ {
+ serial_close (sr_get_desc ());
+ sr_set_desc (NULL);
+ }
+
+ return;
+}
+
+/* gr_detach()
+ takes a program previously attached to and detaches it.
+ We better not have left any breakpoints
+ in the program or it'll die when it hits one.
+ Close the open connection to the remote debugger.
+ Use this when you want to detach and do something else
+ with your gdb. */
+
+void
+gr_detach (char *args, int from_tty)
+{
+ if (args)
+ error ("Argument given to \"detach\" when remotely debugging.");
+
+ if (sr_is_open ())
+ gr_clear_all_breakpoints ();
+
+ pop_target ();
+ if (from_tty)
+ puts_filtered ("Ending remote debugging.\n");
+
+ return;
+}
+
+void
+gr_files_info (struct target_ops *ops)
+{
+#ifdef __GO32__
+ printf_filtered ("\tAttached to DOS asynctsr\n");
+#else
+ printf_filtered ("\tAttached to %s", sr_get_device ());
+ if (baud_rate != -1)
+ printf_filtered ("at %d baud", baud_rate);
+ printf_filtered ("\n");
+#endif
+
+ if (exec_bfd)
+ {
+ printf_filtered ("\tand running program %s\n",
+ bfd_get_filename (exec_bfd));
+ }
+ printf_filtered ("\tusing the %s protocol.\n", ops->to_shortname);
+}
+
+void
+gr_mourn (void)
+{
+ gr_clear_all_breakpoints ();
+ unpush_target (gr_get_ops ());
+ generic_mourn_inferior ();
+}
+
+void
+gr_kill (void)
+{
+ return;
+}
+
+/* This is called not only when we first attach, but also when the
+ user types "run" after having attached. */
+void
+gr_create_inferior (char *execfile, char *args, char **env)
+{
+ int entry_pt;
+
+ if (args && *args)
+ error ("Can't pass arguments to remote process.");
+
+ if (execfile == 0 || exec_bfd == 0)
+ error ("No executable file specified");
+
+ entry_pt = (int) bfd_get_start_address (exec_bfd);
+ sr_check_open ();
+
+ gr_kill ();
+ gr_clear_all_breakpoints ();
+
+ init_wait_for_inferior ();
+ gr_checkin ();
+
+ insert_breakpoints (); /* Needed to get correct instruction in cache */
+ proceed (entry_pt, -1, 0);
+}
+
+/* Given a null terminated list of strings LIST, read the input until we find one of
+ them. Return the index of the string found or -1 on error. '?' means match
+ any single character. Note that with the algorithm we use, the initial
+ character of the string cannot recur in the string, or we will not find some
+ cases of the string in the input. If PASSTHROUGH is non-zero, then
+ pass non-matching data on. */
+
+int
+gr_multi_scan (char *list[], int passthrough)
+{
+ char *swallowed = NULL; /* holding area */
+ char *swallowed_p = swallowed; /* Current position in swallowed. */
+ int ch;
+ int ch_handled;
+ int i;
+ int string_count;
+ int max_length;
+ char **plist;
+
+ /* Look through the strings. Count them. Find the largest one so we can
+ allocate a holding area. */
+
+ for (max_length = string_count = i = 0;
+ list[i] != NULL;
+ ++i, ++string_count)
+ {
+ int length = strlen (list[i]);
+
+ if (length > max_length)
+ max_length = length;
+ }
+
+ /* if we have no strings, then something is wrong. */
+ if (string_count == 0)
+ return (-1);
+
+ /* otherwise, we will need a holding area big enough to hold almost two
+ copies of our largest string. */
+ swallowed_p = swallowed = alloca (max_length << 1);
+
+ /* and a list of pointers to current scan points. */
+ plist = (char **) alloca (string_count * sizeof (*plist));
+
+ /* and initialize */
+ for (i = 0; i < string_count; ++i)
+ plist[i] = list[i];
+
+ for (ch = sr_readchar (); /* loop forever */ ; ch = sr_readchar ())
+ {
+ QUIT; /* Let user quit and leave process running */
+ ch_handled = 0;
+
+ for (i = 0; i < string_count; ++i)
+ {
+ if (ch == *plist[i] || *plist[i] == '?')
+ {
+ ++plist[i];
+ if (*plist[i] == '\0')
+ return (i);
+
+ if (!ch_handled)
+ *swallowed_p++ = ch;
+
+ ch_handled = 1;
+ }
+ else
+ plist[i] = list[i];
+ }
+
+ if (!ch_handled)
+ {
+ char *p;
+
+ /* Print out any characters which have been swallowed. */
+ if (passthrough)
+ {
+ for (p = swallowed; p < swallowed_p; ++p)
+ fputc_unfiltered (*p, gdb_stdout);
+
+ fputc_unfiltered (ch, gdb_stdout);
+ }
+
+ swallowed_p = swallowed;
+ }
+ }
+#if 0
+ /* Never reached. */
+ return (-1);
+#endif
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+void
+gr_prepare_to_store (void)
+{
+ /* Do nothing, since we assume we can store individual regs */
+}
+
+void
+_initialize_sr_support (void)
+{
+/* FIXME-now: if target is open... */
+ add_show_from_set (add_set_cmd ("remotedevice", no_class,
+ var_filename, (char *) &sr_settings.device,
+ "Set device for remote serial I/O.\n\
+This device is used as the serial port when debugging using remote\n\
+targets.", &setlist),
+ &showlist);
+
+ add_com ("remote <command>", class_obscure, sr_com,
+ "Send a command to the remote monitor.");
+
+}
diff --git a/gdb/remote-utils.h b/gdb/remote-utils.h
new file mode 100644
index 00000000000..3ca3bb4dcce
--- /dev/null
+++ b/gdb/remote-utils.h
@@ -0,0 +1,133 @@
+/* Generic support for remote debugging interfaces.
+
+ Copyright 1993, 1994, 2000, 2001 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. */
+
+#ifndef REMOTE_UTILS_H
+#define REMOTE_UTILS_H
+
+#include "target.h"
+struct serial;
+
+/* Stuff that should be shared (and handled consistently) among the various
+ remote targets. */
+
+struct _sr_settings
+ {
+ unsigned int timeout;
+
+ int retries;
+
+ char *device;
+ struct serial *desc;
+
+ };
+
+extern struct _sr_settings sr_settings;
+
+/* get and set debug value. */
+#define sr_get_debug() (remote_debug)
+#define sr_set_debug(newval) (remote_debug = (newval))
+
+/* get and set timeout. */
+#define sr_get_timeout() (sr_settings.timeout)
+#define sr_set_timeout(newval) (sr_settings.timeout = (newval))
+
+/* get and set device. */
+#define sr_get_device() (sr_settings.device)
+#define sr_set_device(newval) \
+{ \
+ if (sr_settings.device) xfree (sr_settings.device); \
+ sr_settings.device = (newval); \
+}
+
+/* get and set descriptor value. */
+#define sr_get_desc() (sr_settings.desc)
+#define sr_set_desc(newval) (sr_settings.desc = (newval))
+
+/* get and set retries. */
+#define sr_get_retries() (sr_settings.retries)
+#define sr_set_retries(newval) (sr_settings.retries = (newval))
+
+#define sr_is_open() (sr_settings.desc != NULL)
+
+#define sr_check_open() { if (!sr_is_open()) \
+ error ("Remote device not open"); }
+
+struct gr_settings
+ {
+ char *prompt;
+ struct target_ops *ops;
+ int (*clear_all_breakpoints) (void);
+ void (*checkin) (void);
+ };
+
+extern struct gr_settings *gr_settings;
+
+/* get and set prompt. */
+#define gr_get_prompt() (gr_settings->prompt)
+#define gr_set_prompt(newval) (gr_settings->prompt = (newval))
+
+/* get and set ops. */
+#define gr_get_ops() (gr_settings->ops)
+#define gr_set_ops(newval) (gr_settings->ops = (newval))
+
+#define gr_clear_all_breakpoints() ((gr_settings->clear_all_breakpoints)())
+#define gr_checkin() ((gr_settings->checkin)())
+
+/* Keep discarding input until we see the prompt.
+
+ The convention for dealing with the prompt is that you
+ o give your command
+ o *then* wait for the prompt.
+
+ Thus the last thing that a procedure does with the serial line
+ will be an gr_expect_prompt(). Exception: resume does not
+ wait for the prompt, because the terminal is being handed over
+ to the inferior. However, the next thing which happens after that
+ is a bug_wait which does wait for the prompt.
+ Note that this includes abnormal exit, e.g. error(). This is
+ necessary to prevent getting into states from which we can't
+ recover. */
+
+#define gr_expect_prompt() sr_expect(gr_get_prompt())
+
+int gr_multi_scan (char *list[], int passthrough);
+int sr_get_hex_digit (int ignore_space);
+int sr_pollchar (void);
+int sr_readchar (void);
+int sr_timed_read (char *buf, int n);
+long sr_get_hex_word (void);
+void gr_close (int quitting);
+void gr_create_inferior (char *execfile, char *args, char **env);
+void gr_detach (char *args, int from_tty);
+void gr_files_info (struct target_ops *ops);
+void gr_generic_checkin (void);
+void gr_kill (void);
+void gr_mourn (void);
+void gr_prepare_to_store (void);
+void sr_expect (char *string);
+void sr_get_hex_byte (char *byt);
+void sr_scan_args (char *proto, char *args);
+void sr_write (char *a, int l);
+void sr_write_cr (char *s);
+
+void gr_open (char *args, int from_tty, struct gr_settings *gr_settings);
+void gr_load_image (char *, int from_tty);
+#endif /* REMOTE_UTILS_H */
diff --git a/gdb/remote-vx.c b/gdb/remote-vx.c
new file mode 100644
index 00000000000..5ec4df42fd7
--- /dev/null
+++ b/gdb/remote-vx.c
@@ -0,0 +1,1410 @@
+/* Memory-access and commands for remote VxWorks processes, for GDB.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999,
+ 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Wind River Systems and 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 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "symtab.h"
+#include "complaints.h"
+#include "gdbcmd.h"
+#include "bfd.h" /* Required by objfiles.h. */
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include "regcache.h"
+
+#include "gdb_string.h"
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#define malloc bogon_malloc /* Sun claims "char *malloc()" not void * */
+#define free bogon_free /* Sun claims "int free()" not void */
+#define realloc bogon_realloc /* Sun claims "char *realloc()", not void * */
+#include <rpc/rpc.h>
+#undef malloc
+#undef free
+#undef realloc
+#include <sys/time.h> /* UTek's <rpc/rpc.h> doesn't #incl this */
+#include <netdb.h>
+#include "vx-share/ptrace.h"
+#include "vx-share/xdr_ptrace.h"
+#include "vx-share/xdr_ld.h"
+#include "vx-share/xdr_rdb.h"
+#include "vx-share/dbgRpcLib.h"
+
+#include <symtab.h>
+
+/* Maximum number of bytes to transfer in a single
+ PTRACE_{READ,WRITE}DATA request. */
+#define VX_MEMXFER_MAX 4096
+
+extern void vx_read_register ();
+extern void vx_write_register ();
+extern void symbol_file_command ();
+extern int stop_soon_quietly; /* for wait_for_inferior */
+
+static int net_step ();
+static int net_ptrace_clnt_call (); /* Forward decl */
+static enum clnt_stat net_clnt_call (); /* Forward decl */
+
+/* Target ops structure for accessing memory and such over the net */
+
+static struct target_ops vx_ops;
+
+/* Target ops structure for accessing VxWorks child processes over the net */
+
+static struct target_ops vx_run_ops;
+
+/* Saved name of target host and called function for "info files".
+ Both malloc'd. */
+
+static char *vx_host;
+static char *vx_running; /* Called function */
+
+/* Nonzero means target that is being debugged remotely has a floating
+ point processor. */
+
+int target_has_fp;
+
+/* Default error message when the network is forking up. */
+
+static const char rpcerr[] = "network target debugging: rpc error";
+
+CLIENT *pClient; /* client used in net debugging */
+static int ptraceSock = RPC_ANYSOCK;
+
+enum clnt_stat net_clnt_call ();
+static void parse_args ();
+
+static struct timeval rpcTimeout =
+{10, 0};
+
+static char *skip_white_space ();
+static char *find_white_space ();
+
+/* Tell the VxWorks target system to download a file.
+ The load addresses of the text, data, and bss segments are
+ stored in *pTextAddr, *pDataAddr, and *pBssAddr (respectively).
+ Returns 0 for success, -1 for failure. */
+
+static int
+net_load (char *filename, CORE_ADDR *pTextAddr, CORE_ADDR *pDataAddr,
+ CORE_ADDR *pBssAddr)
+{
+ enum clnt_stat status;
+ struct ldfile ldstruct;
+ struct timeval load_timeout;
+
+ memset ((char *) &ldstruct, '\0', sizeof (ldstruct));
+
+ /* We invoke clnt_call () here directly, instead of through
+ net_clnt_call (), because we need to set a large timeout value.
+ The load on the target side can take quite a while, easily
+ more than 10 seconds. The user can kill this call by typing
+ CTRL-C if there really is a problem with the load.
+
+ Do not change the tv_sec value without checking -- select() imposes
+ a limit of 10**8 on it for no good reason that I can see... */
+
+ load_timeout.tv_sec = 99999999; /* A large number, effectively inf. */
+ load_timeout.tv_usec = 0;
+
+ status = clnt_call (pClient, VX_LOAD, xdr_wrapstring, &filename, xdr_ldfile,
+ &ldstruct, load_timeout);
+
+ if (status == RPC_SUCCESS)
+ {
+ if (*ldstruct.name == 0) /* load failed on VxWorks side */
+ return -1;
+ *pTextAddr = ldstruct.txt_addr;
+ *pDataAddr = ldstruct.data_addr;
+ *pBssAddr = ldstruct.bss_addr;
+ return 0;
+ }
+ else
+ return -1;
+}
+
+/* returns 0 if successful, errno if RPC failed or VxWorks complains. */
+
+static int
+net_break (int addr, u_long procnum)
+{
+ enum clnt_stat status;
+ int break_status;
+ Rptrace ptrace_in; /* XXX This is stupid. It doesn't need to be a ptrace
+ structure. How about something smaller? */
+
+ memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+ break_status = 0;
+
+ ptrace_in.addr = addr;
+ ptrace_in.pid = PIDGET (inferior_ptid);
+
+ status = net_clnt_call (procnum, xdr_rptrace, &ptrace_in, xdr_int,
+ &break_status);
+
+ if (status != RPC_SUCCESS)
+ return errno;
+
+ if (break_status == -1)
+ return ENOMEM;
+ return break_status; /* probably (FIXME) zero */
+}
+
+/* returns 0 if successful, errno otherwise */
+
+static int
+vx_insert_breakpoint (int addr)
+{
+ return net_break (addr, VX_BREAK_ADD);
+}
+
+/* returns 0 if successful, errno otherwise */
+
+static int
+vx_remove_breakpoint (int addr)
+{
+ return net_break (addr, VX_BREAK_DELETE);
+}
+
+/* Start an inferior process and sets inferior_ptid 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.
+ Returns process id. Errors reported with error().
+ On VxWorks, we ignore exec_file. */
+
+static void
+vx_create_inferior (char *exec_file, char *args, char **env)
+{
+ enum clnt_stat status;
+ arg_array passArgs;
+ TASK_START taskStart;
+
+ memset ((char *) &passArgs, '\0', sizeof (passArgs));
+ memset ((char *) &taskStart, '\0', sizeof (taskStart));
+
+ /* parse arguments, put them in passArgs */
+
+ parse_args (args, &passArgs);
+
+ if (passArgs.arg_array_len == 0)
+ error ("You must specify a function name to run, and arguments if any");
+
+ status = net_clnt_call (PROCESS_START, xdr_arg_array, &passArgs,
+ xdr_TASK_START, &taskStart);
+
+ if ((status != RPC_SUCCESS) || (taskStart.status == -1))
+ error ("Can't create process on remote target machine");
+
+ /* Save the name of the running function */
+ vx_running = savestring (passArgs.arg_array_val[0],
+ strlen (passArgs.arg_array_val[0]));
+
+ push_target (&vx_run_ops);
+ inferior_ptid = pid_to_ptid (taskStart.pid);
+
+ /* We will get a trace trap after one instruction.
+ Insert breakpoints and continue. */
+
+ init_wait_for_inferior ();
+
+ /* Set up the "saved terminal modes" of the inferior
+ based on what modes we are starting it with. */
+ target_terminal_init ();
+
+ /* Install inferior's terminal modes. */
+ target_terminal_inferior ();
+
+ stop_soon_quietly = 1;
+ wait_for_inferior (); /* Get the task spawn event */
+ stop_soon_quietly = 0;
+
+ /* insert_step_breakpoint (); FIXME, do we need this? */
+ proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
+}
+
+/* Fill ARGSTRUCT in argc/argv form with the arguments from the
+ argument string ARGSTRING. */
+
+static void
+parse_args (register char *arg_string, arg_array *arg_struct)
+{
+ register int arg_count = 0; /* number of arguments */
+ register int arg_index = 0;
+ register char *p0;
+
+ memset ((char *) arg_struct, '\0', sizeof (arg_array));
+
+ /* first count how many arguments there are */
+
+ p0 = arg_string;
+ while (*p0 != '\0')
+ {
+ if (*(p0 = skip_white_space (p0)) == '\0')
+ break;
+ p0 = find_white_space (p0);
+ arg_count++;
+ }
+
+ arg_struct->arg_array_len = arg_count;
+ arg_struct->arg_array_val = (char **) xmalloc ((arg_count + 1)
+ * sizeof (char *));
+
+ /* now copy argument strings into arg_struct. */
+
+ while (*(arg_string = skip_white_space (arg_string)))
+ {
+ p0 = find_white_space (arg_string);
+ arg_struct->arg_array_val[arg_index++] = savestring (arg_string,
+ p0 - arg_string);
+ arg_string = p0;
+ }
+
+ arg_struct->arg_array_val[arg_count] = NULL;
+}
+
+/* Advance a string pointer across whitespace and return a pointer
+ to the first non-white character. */
+
+static char *
+skip_white_space (register char *p)
+{
+ while (*p == ' ' || *p == '\t')
+ p++;
+ return p;
+}
+
+/* Search for the first unquoted whitespace character in a string.
+ Returns a pointer to the character, or to the null terminator
+ if no whitespace is found. */
+
+static char *
+find_white_space (register char *p)
+{
+ register int c;
+
+ while ((c = *p) != ' ' && c != '\t' && c)
+ {
+ if (c == '\'' || c == '"')
+ {
+ while (*++p != c && *p)
+ {
+ if (*p == '\\')
+ p++;
+ }
+ if (!*p)
+ break;
+ }
+ p++;
+ }
+ return p;
+}
+
+/* Poll the VxWorks target system for an event related
+ to the debugged task.
+ Returns -1 if remote wait failed, task status otherwise. */
+
+static int
+net_wait (RDB_EVENT *pEvent)
+{
+ int pid;
+ enum clnt_stat status;
+
+ memset ((char *) pEvent, '\0', sizeof (RDB_EVENT));
+
+ pid = PIDGET (inferior_ptid);
+ status = net_clnt_call (PROCESS_WAIT, xdr_int, &pid, xdr_RDB_EVENT,
+ pEvent);
+
+ /* return (status == RPC_SUCCESS)? pEvent->status: -1; */
+ if (status == RPC_SUCCESS)
+ return ((pEvent->status) ? 1 : 0);
+ else if (status == RPC_TIMEDOUT)
+ return (1);
+ else
+ return (-1);
+}
+
+/* Suspend the remote task.
+ Returns -1 if suspend fails on target system, 0 otherwise. */
+
+static int
+net_quit (void)
+{
+ int pid;
+ int quit_status;
+ enum clnt_stat status;
+
+ quit_status = 0;
+
+ /* don't let rdbTask suspend itself by passing a pid of 0 */
+
+ if ((pid = PIDGET (inferior_ptid)) == 0)
+ return -1;
+
+ status = net_clnt_call (VX_TASK_SUSPEND, xdr_int, &pid, xdr_int,
+ &quit_status);
+
+ return (status == RPC_SUCCESS) ? quit_status : -1;
+}
+
+/* Read a register or registers from the remote system. */
+
+void
+net_read_registers (char *reg_buf, int len, u_long procnum)
+{
+ int status;
+ Rptrace ptrace_in;
+ Ptrace_return ptrace_out;
+ C_bytes out_data;
+ char message[100];
+
+ memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+ memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
+
+ /* Initialize RPC input argument structure. */
+
+ ptrace_in.pid = PIDGET (inferior_ptid);
+ ptrace_in.info.ttype = NOINFO;
+
+ /* Initialize RPC return value structure. */
+
+ out_data.bytes = reg_buf;
+ out_data.len = len;
+ ptrace_out.info.more_data = (caddr_t) & out_data;
+
+ /* Call RPC; take an error exit if appropriate. */
+
+ status = net_ptrace_clnt_call (procnum, &ptrace_in, &ptrace_out);
+ if (status)
+ error (rpcerr);
+ if (ptrace_out.status == -1)
+ {
+ errno = ptrace_out.errno_num;
+ sprintf (message, "reading %s registers", (procnum == PTRACE_GETREGS)
+ ? "general-purpose"
+ : "floating-point");
+ perror_with_name (message);
+ }
+}
+
+/* Write register values to a VxWorks target. REG_BUF points to a buffer
+ containing the raw register values, LEN is the length of REG_BUF in
+ bytes, and PROCNUM is the RPC procedure number (PTRACE_SETREGS or
+ PTRACE_SETFPREGS). An error exit is taken if the RPC call fails or
+ if an error status is returned by the remote debug server. This is
+ a utility routine used by vx_write_register (). */
+
+void
+net_write_registers (char *reg_buf, int len, u_long procnum)
+{
+ int status;
+ Rptrace ptrace_in;
+ Ptrace_return ptrace_out;
+ C_bytes in_data;
+ char message[100];
+
+ memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+ memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
+
+ /* Initialize RPC input argument structure. */
+
+ in_data.bytes = reg_buf;
+ in_data.len = len;
+
+ ptrace_in.pid = PIDGET (inferior_ptid);
+ ptrace_in.info.ttype = DATA;
+ ptrace_in.info.more_data = (caddr_t) & in_data;
+
+ /* Call RPC; take an error exit if appropriate. */
+
+ status = net_ptrace_clnt_call (procnum, &ptrace_in, &ptrace_out);
+ if (status)
+ error (rpcerr);
+ if (ptrace_out.status == -1)
+ {
+ errno = ptrace_out.errno_num;
+ sprintf (message, "writing %s registers", (procnum == PTRACE_SETREGS)
+ ? "general-purpose"
+ : "floating-point");
+ perror_with_name (message);
+ }
+}
+
+/* Prepare to store registers. Since we will store all of them,
+ read out their current values now. */
+
+static void
+vx_prepare_to_store (void)
+{
+ /* Fetch all registers, if any of them are not yet fetched. */
+ read_register_bytes (0, NULL, REGISTER_BYTES);
+}
+
+/* Copy LEN bytes to or from remote inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. WRITE is true if writing to the
+ inferior. TARGET is unused.
+ Result is the number of bytes written or read (zero if error). The
+ protocol allows us to return a negative count, indicating that we can't
+ handle the current address but can handle one N bytes further, but
+ vxworks doesn't give us that information. */
+
+static int
+vx_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib, struct target_ops *target)
+{
+ int status;
+ Rptrace ptrace_in;
+ Ptrace_return ptrace_out;
+ C_bytes data;
+ enum ptracereq request;
+ int nleft, nxfer;
+
+ memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+ memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
+
+ ptrace_in.pid = PIDGET (inferior_ptid); /* XXX pid unnecessary for READDATA */
+ ptrace_in.addr = (int) memaddr; /* Where from */
+ ptrace_in.data = len; /* How many bytes */
+
+ if (write)
+ {
+ ptrace_in.info.ttype = DATA;
+ ptrace_in.info.more_data = (caddr_t) & data;
+
+ data.bytes = (caddr_t) myaddr; /* Where from */
+ data.len = len; /* How many bytes (again, for XDR) */
+ request = PTRACE_WRITEDATA;
+ }
+ else
+ {
+ ptrace_out.info.more_data = (caddr_t) & data;
+ request = PTRACE_READDATA;
+ }
+ /* Loop until the entire request has been satisfied, transferring
+ at most VX_MEMXFER_MAX bytes per iteration. Break from the loop
+ if an error status is returned by the remote debug server. */
+
+ nleft = len;
+ status = 0;
+
+ while (nleft > 0 && status == 0)
+ {
+ nxfer = min (nleft, VX_MEMXFER_MAX);
+
+ ptrace_in.addr = (int) memaddr;
+ ptrace_in.data = nxfer;
+ data.bytes = (caddr_t) myaddr;
+ data.len = nxfer;
+
+ /* Request a block from the remote debug server; if RPC fails,
+ report an error and return to debugger command level. */
+
+ if (net_ptrace_clnt_call (request, &ptrace_in, &ptrace_out))
+ error (rpcerr);
+
+ status = ptrace_out.status;
+ if (status == 0)
+ {
+ memaddr += nxfer;
+ myaddr += nxfer;
+ nleft -= nxfer;
+ }
+ else
+ {
+ /* A target-side error has ocurred. Set errno to the error
+ code chosen by the target so that a later perror () will
+ say something meaningful. */
+
+ errno = ptrace_out.errno_num;
+ }
+ }
+
+ /* Return the number of bytes transferred. */
+
+ return (len - nleft);
+}
+
+static void
+vx_files_info (void)
+{
+ printf_unfiltered ("\tAttached to host `%s'", vx_host);
+ printf_unfiltered (", which has %sfloating point", target_has_fp ? "" : "no ");
+ printf_unfiltered (".\n");
+}
+
+static void
+vx_run_files_info (void)
+{
+ printf_unfiltered ("\tRunning %s VxWorks process %s",
+ vx_running ? "child" : "attached",
+ local_hex_string (PIDGET (inferior_ptid)));
+ if (vx_running)
+ printf_unfiltered (", function `%s'", vx_running);
+ printf_unfiltered (".\n");
+}
+
+static void
+vx_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ int status;
+ Rptrace ptrace_in;
+ Ptrace_return ptrace_out;
+ CORE_ADDR cont_addr;
+
+ if (ptid_equal (ptid, minus_one_ptid))
+ ptid = inferior_ptid;
+
+ if (siggnal != 0 && siggnal != stop_signal)
+ error ("Cannot send signals to VxWorks processes");
+
+ /* Set CONT_ADDR to the address at which we are continuing,
+ or to 1 if we are continuing from where the program stopped.
+ This conforms to traditional ptrace () usage, but at the same
+ time has special meaning for the VxWorks remote debug server.
+ If the address is not 1, the server knows that the target
+ program is jumping to a new address, which requires special
+ handling if there is a breakpoint at the new address. */
+
+ cont_addr = read_register (PC_REGNUM);
+ if (cont_addr == stop_pc)
+ cont_addr = 1;
+
+ memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+ memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
+
+ ptrace_in.pid = PIDGET (ptid);
+ ptrace_in.addr = cont_addr; /* Target side insists on this, or it panics. */
+
+ if (step)
+ status = net_step ();
+ else
+ status = net_ptrace_clnt_call (PTRACE_CONT, &ptrace_in, &ptrace_out);
+
+ if (status)
+ error (rpcerr);
+ if (ptrace_out.status == -1)
+ {
+ errno = ptrace_out.errno_num;
+ perror_with_name ("Resuming remote process");
+ }
+}
+
+static void
+vx_mourn_inferior (void)
+{
+ pop_target (); /* Pop back to no-child state */
+ generic_mourn_inferior ();
+}
+
+
+static void vx_add_symbols (char *, int, CORE_ADDR, CORE_ADDR, CORE_ADDR);
+
+struct find_sect_args
+ {
+ CORE_ADDR text_start;
+ CORE_ADDR data_start;
+ CORE_ADDR bss_start;
+ };
+
+static void find_sect (bfd *, asection *, void *);
+
+static void
+find_sect (bfd *abfd, asection *sect, PTR obj)
+{
+ struct find_sect_args *args = (struct find_sect_args *) obj;
+
+ if (bfd_get_section_flags (abfd, sect) & (SEC_CODE & SEC_READONLY))
+ args->text_start = bfd_get_section_vma (abfd, sect);
+ else if (bfd_get_section_flags (abfd, sect) & SEC_ALLOC)
+ {
+ if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
+ {
+ /* Exclude .ctor and .dtor sections which have SEC_CODE set but not
+ SEC_DATA. */
+ if (bfd_get_section_flags (abfd, sect) & SEC_DATA)
+ args->data_start = bfd_get_section_vma (abfd, sect);
+ }
+ else
+ args->bss_start = bfd_get_section_vma (abfd, sect);
+ }
+}
+
+static void
+vx_add_symbols (char *name, int from_tty, CORE_ADDR text_addr,
+ CORE_ADDR data_addr, CORE_ADDR bss_addr)
+{
+ struct section_offsets *offs;
+ struct objfile *objfile;
+ struct find_sect_args ss;
+
+ /* It might be nice to suppress the breakpoint_re_set which happens here
+ because we are going to do one again after the objfile_relocate. */
+ objfile = symbol_file_add (name, from_tty, NULL, 0, 0);
+
+ /* This is a (slightly cheesy) way of superceding the old symbols. A less
+ cheesy way would be to find the objfile with the same name and
+ free_objfile it. */
+ objfile_to_front (objfile);
+
+ offs = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
+ memcpy (offs, objfile->section_offsets, SIZEOF_SECTION_OFFSETS);
+
+ ss.text_start = 0;
+ ss.data_start = 0;
+ ss.bss_start = 0;
+ bfd_map_over_sections (objfile->obfd, find_sect, &ss);
+
+ /* Both COFF and b.out frontends use these SECT_OFF_* values. */
+ offs->offsets[SECT_OFF_TEXT (objfile)] = text_addr - ss.text_start;
+ offs->offsets[SECT_OFF_DATA (objfile)] = data_addr - ss.data_start;
+ offs->offsets[SECT_OFF_BSS (objfile)] = bss_addr - ss.bss_start;
+ objfile_relocate (objfile, offs);
+}
+
+/* This function allows the addition of incrementally linked object files. */
+
+static void
+vx_load_command (char *arg_string, int from_tty)
+{
+ CORE_ADDR text_addr;
+ CORE_ADDR data_addr;
+ CORE_ADDR bss_addr;
+
+ if (arg_string == 0)
+ error ("The load command takes a file name");
+
+ arg_string = tilde_expand (arg_string);
+ make_cleanup (xfree, arg_string);
+
+ dont_repeat ();
+
+ /* Refuse to load the module if a debugged task is running. Doing so
+ can have a number of unpleasant consequences to the running task. */
+
+ if (PIDGET (inferior_ptid) != 0 && target_has_execution)
+ {
+ if (query ("You may not load a module while the target task is running.\n\
+Kill the target task? "))
+ target_kill ();
+ else
+ error ("Load canceled.");
+ }
+
+ QUIT;
+ immediate_quit++;
+ if (net_load (arg_string, &text_addr, &data_addr, &bss_addr) == -1)
+ error ("Load failed on target machine");
+ immediate_quit--;
+
+ vx_add_symbols (arg_string, from_tty, text_addr, data_addr, bss_addr);
+
+ /* Getting new symbols may change our opinion about what is
+ frameless. */
+ reinit_frame_cache ();
+}
+
+/* Single step the target program at the source or machine level.
+ Takes an error exit if rpc fails.
+ Returns -1 if remote single-step operation fails, else 0. */
+
+static int
+net_step (void)
+{
+ enum clnt_stat status;
+ int step_status;
+ SOURCE_STEP source_step;
+
+ source_step.taskId = PIDGET (inferior_ptid);
+
+ if (step_range_end)
+ {
+ source_step.startAddr = step_range_start;
+ source_step.endAddr = step_range_end;
+ }
+ else
+ {
+ source_step.startAddr = 0;
+ source_step.endAddr = 0;
+ }
+
+ status = net_clnt_call (VX_SOURCE_STEP, xdr_SOURCE_STEP, &source_step,
+ xdr_int, &step_status);
+
+ if (status == RPC_SUCCESS)
+ return step_status;
+ else
+ error (rpcerr);
+}
+
+/* Emulate ptrace using RPC calls to the VxWorks target system.
+ Returns nonzero (-1) if RPC status to VxWorks is bad, 0 otherwise. */
+
+static int
+net_ptrace_clnt_call (enum ptracereq request, Rptrace *pPtraceIn,
+ Ptrace_return *pPtraceOut)
+{
+ enum clnt_stat status;
+
+ status = net_clnt_call (request, xdr_rptrace, pPtraceIn, xdr_ptrace_return,
+ pPtraceOut);
+
+ if (status != RPC_SUCCESS)
+ return -1;
+
+ return 0;
+}
+
+/* Query the target for the name of the file from which VxWorks was
+ booted. pBootFile is the address of a pointer to the buffer to
+ receive the file name; if the pointer pointed to by pBootFile is
+ NULL, memory for the buffer will be allocated by XDR.
+ Returns -1 if rpc failed, 0 otherwise. */
+
+static int
+net_get_boot_file (char **pBootFile)
+{
+ enum clnt_stat status;
+
+ status = net_clnt_call (VX_BOOT_FILE_INQ, xdr_void, (char *) 0,
+ xdr_wrapstring, pBootFile);
+ return (status == RPC_SUCCESS) ? 0 : -1;
+}
+
+/* Fetch a list of loaded object modules from the VxWorks target
+ and store in PLOADTABLE.
+ Returns -1 if rpc failed, 0 otherwise
+ There's no way to check if the returned loadTable is correct.
+ VxWorks doesn't check it. */
+
+static int
+net_get_symbols (ldtabl *pLoadTable)
+{
+ enum clnt_stat status;
+
+ memset ((char *) pLoadTable, '\0', sizeof (struct ldtabl));
+
+ status = net_clnt_call (VX_STATE_INQ, xdr_void, 0, xdr_ldtabl, pLoadTable);
+ return (status == RPC_SUCCESS) ? 0 : -1;
+}
+
+/* Look up a symbol in the VxWorks target's symbol table.
+ Returns status of symbol read on target side (0=success, -1=fail)
+ Returns -1 and complain()s if rpc fails. */
+
+struct complaint cant_contact_target =
+{"Lost contact with VxWorks target", 0, 0};
+
+static int
+vx_lookup_symbol (char *name, /* symbol name */
+ CORE_ADDR *pAddr)
+{
+ enum clnt_stat status;
+ SYMBOL_ADDR symbolAddr;
+
+ *pAddr = 0;
+ memset ((char *) &symbolAddr, '\0', sizeof (symbolAddr));
+
+ status = net_clnt_call (VX_SYMBOL_INQ, xdr_wrapstring, &name,
+ xdr_SYMBOL_ADDR, &symbolAddr);
+ if (status != RPC_SUCCESS)
+ {
+ complain (&cant_contact_target);
+ return -1;
+ }
+
+ *pAddr = symbolAddr.addr;
+ return symbolAddr.status;
+}
+
+/* Check to see if the VxWorks target has a floating point coprocessor.
+ Returns 1 if target has floating point processor, 0 otherwise.
+ Calls error() if rpc fails. */
+
+static int
+net_check_for_fp (void)
+{
+ enum clnt_stat status;
+ bool_t fp = 0; /* true if fp processor is present on target board */
+
+ status = net_clnt_call (VX_FP_INQUIRE, xdr_void, 0, xdr_bool, &fp);
+ if (status != RPC_SUCCESS)
+ error (rpcerr);
+
+ return (int) fp;
+}
+
+/* Establish an RPC connection with the VxWorks target system.
+ Calls error () if unable to establish connection. */
+
+static void
+net_connect (char *host)
+{
+ struct sockaddr_in destAddr;
+ struct hostent *destHost;
+ unsigned long addr;
+
+ /* Get the internet address for the given host. Allow a numeric
+ IP address or a hostname. */
+
+ addr = inet_addr (host);
+ if (addr == -1)
+ {
+ destHost = (struct hostent *) gethostbyname (host);
+ if (destHost == NULL)
+ /* FIXME: Probably should include hostname here in quotes.
+ For example if the user types "target vxworks vx960 " it should
+ say "Invalid host `vx960 '." not just "Invalid hostname". */
+ error ("Invalid hostname. Couldn't find remote host address.");
+ addr = *(unsigned long *) destHost->h_addr;
+ }
+
+ memset (&destAddr, '\0', sizeof (destAddr));
+
+ destAddr.sin_addr.s_addr = addr;
+ destAddr.sin_family = AF_INET;
+ destAddr.sin_port = 0; /* set to actual port that remote
+ ptrace is listening on. */
+
+ /* Create a tcp client transport on which to issue
+ calls to the remote ptrace server. */
+
+ ptraceSock = RPC_ANYSOCK;
+ pClient = clnttcp_create (&destAddr, RDBPROG, RDBVERS, &ptraceSock, 0, 0);
+ /* FIXME, here is where we deal with different version numbers of the
+ proto */
+
+ if (pClient == NULL)
+ {
+ clnt_pcreateerror ("\tnet_connect");
+ error ("Couldn't connect to remote target.");
+ }
+}
+
+/* Sleep for the specified number of milliseconds
+ * (assumed to be less than 1000).
+ * If select () is interrupted, returns immediately;
+ * takes an error exit if select () fails for some other reason.
+ */
+
+static void
+sleep_ms (long ms)
+{
+ struct timeval select_timeout;
+ int status;
+
+ select_timeout.tv_sec = 0;
+ select_timeout.tv_usec = ms * 1000;
+
+ status = select (0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0,
+ &select_timeout);
+
+ if (status < 0 && errno != EINTR)
+ perror_with_name ("select");
+}
+
+static ptid_t
+vx_wait (ptid_t ptid_to_wait_for, struct target_waitstatus *status)
+{
+ register int pid;
+ RDB_EVENT rdbEvent;
+ int quit_failed;
+
+ do
+ {
+ /* If CTRL-C is hit during this loop,
+ suspend the inferior process. */
+
+ quit_failed = 0;
+ if (quit_flag)
+ {
+ quit_failed = (net_quit () == -1);
+ quit_flag = 0;
+ }
+
+ /* If a net_quit () or net_wait () call has failed,
+ allow the user to break the connection with the target.
+ We can't simply error () out of this loop, since the
+ data structures representing the state of the inferior
+ are in an inconsistent state. */
+
+ if (quit_failed || net_wait (&rdbEvent) == -1)
+ {
+ terminal_ours ();
+ if (query ("Can't %s. Disconnect from target system? ",
+ (quit_failed) ? "suspend remote task"
+ : "get status of remote task"))
+ {
+ target_mourn_inferior ();
+ error ("Use the \"target\" command to reconnect.");
+ }
+ else
+ {
+ terminal_inferior ();
+ continue;
+ }
+ }
+
+ pid = rdbEvent.taskId;
+ if (pid == 0)
+ {
+ sleep_ms (200); /* FIXME Don't kill the network too badly */
+ }
+ else if (pid != PIDGET (inferior_ptid))
+ internal_error (__FILE__, __LINE__,
+ "Bad pid for debugged task: %s\n",
+ local_hex_string ((unsigned long) pid));
+ }
+ while (pid == 0);
+
+ /* The mostly likely kind. */
+ status->kind = TARGET_WAITKIND_STOPPED;
+
+ switch (rdbEvent.eventType)
+ {
+ case EVENT_EXIT:
+ status->kind = TARGET_WAITKIND_EXITED;
+ /* FIXME is it possible to distinguish between a
+ normal vs abnormal exit in VxWorks? */
+ status->value.integer = 0;
+ break;
+
+ case EVENT_START:
+ /* Task was just started. */
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ break;
+
+ case EVENT_STOP:
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ /* XXX was it stopped by a signal? act accordingly */
+ break;
+
+ case EVENT_BREAK: /* Breakpoint was hit. */
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ break;
+
+ case EVENT_SUSPEND: /* Task was suspended, probably by ^C. */
+ status->value.sig = TARGET_SIGNAL_INT;
+ break;
+
+ case EVENT_BUS_ERR: /* Task made evil nasty reference. */
+ status->value.sig = TARGET_SIGNAL_BUS;
+ break;
+
+ case EVENT_ZERO_DIV: /* Division by zero */
+ status->value.sig = TARGET_SIGNAL_FPE;
+ break;
+
+ case EVENT_SIGNAL:
+#ifdef I80960
+ status->value.sig = i960_fault_to_signal (rdbEvent.sigType);
+#else
+ /* Back in the old days, before enum target_signal, this code used
+ to add NSIG to the signal number and claim that PRINT_RANDOM_SIGNAL
+ would take care of it. But PRINT_RANDOM_SIGNAL has never been
+ defined except on the i960, so I don't really know what we are
+ supposed to do on other architectures. */
+ status->value.sig = TARGET_SIGNAL_UNKNOWN;
+#endif
+ break;
+ } /* switch */
+ return pid_to_ptid (pid);
+}
+
+static int
+symbol_stub (char *arg)
+{
+ symbol_file_add_main (arg, 0);
+ return 1;
+}
+
+static int
+add_symbol_stub (char *arg)
+{
+ struct ldfile *pLoadFile = (struct ldfile *) arg;
+
+ printf_unfiltered ("\t%s: ", pLoadFile->name);
+ vx_add_symbols (pLoadFile->name, 0, pLoadFile->txt_addr,
+ pLoadFile->data_addr, pLoadFile->bss_addr);
+ printf_unfiltered ("ok\n");
+ return 1;
+}
+/* Target command for VxWorks target systems.
+
+ Used in vxgdb. Takes the name of a remote target machine
+ running vxWorks and connects to it to initialize remote network
+ debugging. */
+
+static void
+vx_open (char *args, int from_tty)
+{
+ extern int close ();
+ char *bootFile;
+ extern char *source_path;
+ struct ldtabl loadTable;
+ struct ldfile *pLoadFile;
+ int i;
+ extern CLIENT *pClient;
+ int symbols_added = 0;
+
+ if (!args)
+ error_no_arg ("target machine name");
+
+ target_preopen (from_tty);
+
+ unpush_target (&vx_ops);
+ printf_unfiltered ("Attaching remote machine across net...\n");
+ gdb_flush (gdb_stdout);
+
+ /* Allow the user to kill the connect attempt by typing ^C.
+ Wait until the call to target_has_fp () completes before
+ disallowing an immediate quit, since even if net_connect ()
+ is successful, the remote debug server might be hung. */
+
+ immediate_quit++;
+
+ net_connect (args);
+ target_has_fp = net_check_for_fp ();
+ printf_filtered ("Connected to %s.\n", args);
+
+ immediate_quit--;
+
+ push_target (&vx_ops);
+
+ /* Save a copy of the target host's name. */
+ vx_host = savestring (args, strlen (args));
+
+ /* Find out the name of the file from which the target was booted
+ and load its symbol table. */
+
+ printf_filtered ("Looking in Unix path for all loaded modules:\n");
+ bootFile = NULL;
+ if (!net_get_boot_file (&bootFile))
+ {
+ if (*bootFile)
+ {
+ printf_filtered ("\t%s: ", bootFile);
+ /* This assumes that the kernel is never relocated. Hope that is an
+ accurate assumption. */
+ if (catch_errors
+ (symbol_stub,
+ bootFile,
+ "Error while reading symbols from boot file:\n",
+ RETURN_MASK_ALL))
+ puts_filtered ("ok\n");
+ }
+ else if (from_tty)
+ printf_unfiltered ("VxWorks kernel symbols not loaded.\n");
+ }
+ else
+ error ("Can't retrieve boot file name from target machine.");
+
+ clnt_freeres (pClient, xdr_wrapstring, &bootFile);
+
+ if (net_get_symbols (&loadTable) != 0)
+ error ("Can't read loaded modules from target machine");
+
+ i = 0 - 1;
+ while (++i < loadTable.tbl_size)
+ {
+ QUIT; /* FIXME, avoids clnt_freeres below: mem leak */
+ pLoadFile = &loadTable.tbl_ent[i];
+#ifdef WRS_ORIG
+ {
+ register int desc;
+ struct cleanup *old_chain;
+ char *fullname = NULL;
+
+ desc = openp (source_path, 0, pLoadFile->name, O_RDONLY, 0, &fullname);
+ if (desc < 0)
+ perror_with_name (pLoadFile->name);
+ old_chain = make_cleanup (close, desc);
+ add_file_at_addr (fullname, desc, pLoadFile->txt_addr, pLoadFile->data_addr,
+ pLoadFile->bss_addr);
+ do_cleanups (old_chain);
+ }
+#else
+ /* FIXME: Is there something better to search than the PATH? (probably
+ not the source path, since source might be in different directories
+ than objects. */
+
+ if (catch_errors (add_symbol_stub, (char *) pLoadFile, (char *) 0,
+ RETURN_MASK_ALL))
+ symbols_added = 1;
+#endif
+ }
+ printf_filtered ("Done.\n");
+
+ clnt_freeres (pClient, xdr_ldtabl, &loadTable);
+
+ /* Getting new symbols may change our opinion about what is
+ frameless. */
+ if (symbols_added)
+ reinit_frame_cache ();
+}
+
+/* Takes a task started up outside of gdb and ``attaches'' to it.
+ This stops it cold in its tracks and allows us to start tracing it. */
+
+static void
+vx_attach (char *args, int from_tty)
+{
+ unsigned long pid;
+ char *cptr = 0;
+ Rptrace ptrace_in;
+ Ptrace_return ptrace_out;
+ int status;
+
+ if (!args)
+ error_no_arg ("process-id to attach");
+
+ pid = strtoul (args, &cptr, 0);
+ if ((cptr == args) || (*cptr != '\0'))
+ error ("Invalid process-id -- give a single number in decimal or 0xhex");
+
+ if (from_tty)
+ printf_unfiltered ("Attaching pid %s.\n",
+ local_hex_string ((unsigned long) pid));
+
+ memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+ memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
+ ptrace_in.pid = pid;
+
+ status = net_ptrace_clnt_call (PTRACE_ATTACH, &ptrace_in, &ptrace_out);
+ if (status == -1)
+ error (rpcerr);
+ if (ptrace_out.status == -1)
+ {
+ errno = ptrace_out.errno_num;
+ perror_with_name ("Attaching remote process");
+ }
+
+ /* It worked... */
+
+ inferior_ptid = pid_to_ptid (pid);
+ push_target (&vx_run_ops);
+
+ if (vx_running)
+ xfree (vx_running);
+ vx_running = 0;
+}
+
+/* detach_command --
+ takes a program previously attached to and detaches it.
+ The program resumes execution and will no longer stop
+ on signals, etc. We better not have left any breakpoints
+ in the program or it'll die when it hits one. For this
+ to work, it may be necessary for the process to have been
+ previously attached. It *might* work if the program was
+ started via the normal ptrace (PTRACE_TRACEME). */
+
+static void
+vx_detach (char *args, int from_tty)
+{
+ Rptrace ptrace_in;
+ Ptrace_return ptrace_out;
+ int signal = 0;
+ int status;
+
+ if (args)
+ error ("Argument given to VxWorks \"detach\".");
+
+ if (from_tty)
+ printf_unfiltered ("Detaching pid %s.\n",
+ local_hex_string (
+ (unsigned long) PIDGET (inferior_ptid)));
+
+ if (args) /* FIXME, should be possible to leave suspended */
+ signal = atoi (args);
+
+ memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+ memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
+ ptrace_in.pid = PIDGET (inferior_ptid);
+
+ status = net_ptrace_clnt_call (PTRACE_DETACH, &ptrace_in, &ptrace_out);
+ if (status == -1)
+ error (rpcerr);
+ if (ptrace_out.status == -1)
+ {
+ errno = ptrace_out.errno_num;
+ perror_with_name ("Detaching VxWorks process");
+ }
+
+ inferior_ptid = null_ptid;
+ pop_target (); /* go back to non-executing VxWorks connection */
+}
+
+/* vx_kill -- takes a running task and wipes it out. */
+
+static void
+vx_kill (void)
+{
+ Rptrace ptrace_in;
+ Ptrace_return ptrace_out;
+ int status;
+
+ printf_unfiltered ("Killing pid %s.\n", local_hex_string ((unsigned long) PIDGET (inferior_ptid)));
+
+ memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in));
+ memset ((char *) &ptrace_out, '\0', sizeof (ptrace_out));
+ ptrace_in.pid = PIDGET (inferior_ptid);
+
+ status = net_ptrace_clnt_call (PTRACE_KILL, &ptrace_in, &ptrace_out);
+ if (status == -1)
+ warning (rpcerr);
+ else if (ptrace_out.status == -1)
+ {
+ errno = ptrace_out.errno_num;
+ perror_with_name ("Killing VxWorks process");
+ }
+
+ /* If it gives good status, the process is *gone*, no events remain.
+ If the kill failed, assume the process is gone anyhow. */
+ inferior_ptid = null_ptid;
+ pop_target (); /* go back to non-executing VxWorks connection */
+}
+
+/* Clean up from the VxWorks process target as it goes away. */
+
+static void
+vx_proc_close (int quitting)
+{
+ inferior_ptid = null_ptid; /* No longer have a process. */
+ if (vx_running)
+ xfree (vx_running);
+ vx_running = 0;
+}
+
+/* Make an RPC call to the VxWorks target.
+ Returns RPC status. */
+
+static enum clnt_stat
+net_clnt_call (enum ptracereq procNum, xdrproc_t inProc, char *in,
+ xdrproc_t outProc, char *out)
+{
+ enum clnt_stat status;
+
+ status = clnt_call (pClient, procNum, inProc, in, outProc, out, rpcTimeout);
+
+ if (status != RPC_SUCCESS)
+ clnt_perrno (status);
+
+ return status;
+}
+
+/* Clean up before losing control. */
+
+static void
+vx_close (int quitting)
+{
+ if (pClient)
+ clnt_destroy (pClient); /* The net connection */
+ pClient = 0;
+
+ if (vx_host)
+ xfree (vx_host); /* The hostname */
+ vx_host = 0;
+}
+
+/* A vxprocess target should be started via "run" not "target". */
+/*ARGSUSED */
+static void
+vx_proc_open (char *name, int from_tty)
+{
+ error ("Use the \"run\" command to start a VxWorks process.");
+}
+
+static void
+init_vx_ops (void)
+{
+ vx_ops.to_shortname = "vxworks";
+ vx_ops.to_longname = "VxWorks target memory via RPC over TCP/IP";
+ vx_ops.to_doc = "Use VxWorks target memory. \n\
+Specify the name of the machine to connect to.";
+ vx_ops.to_open = vx_open;
+ vx_ops.to_close = vx_close;
+ vx_ops.to_attach = vx_attach;
+ vx_ops.to_xfer_memory = vx_xfer_memory;
+ vx_ops.to_files_info = vx_files_info;
+ vx_ops.to_load = vx_load_command;
+ vx_ops.to_lookup_symbol = vx_lookup_symbol;
+ vx_ops.to_create_inferior = vx_create_inferior;
+ vx_ops.to_stratum = core_stratum;
+ vx_ops.to_has_all_memory = 1;
+ vx_ops.to_has_memory = 1;
+ vx_ops.to_magic = OPS_MAGIC; /* Always the last thing */
+};
+
+static void
+init_vx_run_ops (void)
+{
+ vx_run_ops.to_shortname = "vxprocess";
+ vx_run_ops.to_longname = "VxWorks process";
+ vx_run_ops.to_doc = "VxWorks process; started by the \"run\" command.";
+ vx_run_ops.to_open = vx_proc_open;
+ vx_run_ops.to_close = vx_proc_close;
+ vx_run_ops.to_detach = vx_detach;
+ vx_run_ops.to_resume = vx_resume;
+ vx_run_ops.to_wait = vx_wait;
+ vx_run_ops.to_fetch_registers = vx_read_register;
+ vx_run_ops.to_store_registers = vx_write_register;
+ vx_run_ops.to_prepare_to_store = vx_prepare_to_store;
+ vx_run_ops.to_xfer_memory = vx_xfer_memory;
+ vx_run_ops.to_files_info = vx_run_files_info;
+ vx_run_ops.to_insert_breakpoint = vx_insert_breakpoint;
+ vx_run_ops.to_remove_breakpoint = vx_remove_breakpoint;
+ vx_run_ops.to_kill = vx_kill;
+ vx_run_ops.to_load = vx_load_command;
+ vx_run_ops.to_lookup_symbol = vx_lookup_symbol;
+ vx_run_ops.to_mourn_inferior = vx_mourn_inferior;
+ vx_run_ops.to_stratum = process_stratum;
+ vx_run_ops.to_has_memory = 1;
+ vx_run_ops.to_has_stack = 1;
+ vx_run_ops.to_has_registers = 1;
+ vx_run_ops.to_has_execution = 1;
+ vx_run_ops.to_magic = OPS_MAGIC;
+}
+
+void
+_initialize_vx (void)
+{
+ init_vx_ops ();
+ add_target (&vx_ops);
+ init_vx_run_ops ();
+ add_target (&vx_run_ops);
+
+ add_show_from_set
+ (add_set_cmd ("vxworks-timeout", class_support, var_uinteger,
+ (char *) &rpcTimeout.tv_sec,
+ "Set seconds to wait for rpc calls to return.\n\
+Set the number of seconds to wait for rpc calls to return.", &setlist),
+ &showlist);
+}
diff --git a/gdb/remote-vx29k.c b/gdb/remote-vx29k.c
new file mode 100644
index 00000000000..798cd088396
--- /dev/null
+++ b/gdb/remote-vx29k.c
@@ -0,0 +1,182 @@
+/* Am29k-dependent portions of the RPC protocol
+
+ Contributed by Wind River Systems.
+
+ 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 <stdio.h>
+#include "defs.h"
+
+#include "vx-share/regPacket.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "symtab.h"
+#include "symfile.h" /* for struct complaint */
+#include "regcache.h"
+
+#include "gdb_string.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#ifdef _AIX /* IBM claims "void *malloc()" not char * */
+#define malloc bogon_malloc
+#endif
+
+#include <rpc/rpc.h>
+#include <sys/time.h> /* UTek's <rpc/rpc.h> doesn't #incl this */
+#include <netdb.h>
+#include "vx-share/ptrace.h"
+#include "vx-share/xdr_ptrace.h"
+#include "vx-share/xdr_ld.h"
+#include "vx-share/xdr_rdb.h"
+#include "vx-share/dbgRpcLib.h"
+
+/* get rid of value.h if possible */
+#include <value.h>
+#include <symtab.h>
+
+/* Flag set if target has fpu */
+
+extern int target_has_fp;
+
+/* Generic register read/write routines in remote-vx.c. */
+
+extern void net_read_registers ();
+extern void net_write_registers ();
+
+/* Read a register or registers from the VxWorks target.
+ REGNO is the register to read, or -1 for all; currently,
+ it is ignored. FIXME look at regno to improve efficiency. */
+
+void
+vx_read_register (int regno)
+{
+ char am29k_greg_packet[AM29K_GREG_PLEN];
+ char am29k_fpreg_packet[AM29K_FPREG_PLEN];
+
+ /* Get general-purpose registers. When copying values into
+ registers [], don't assume that a location in registers []
+ is properly aligned for the target data type. */
+
+ net_read_registers (am29k_greg_packet, AM29K_GREG_PLEN, PTRACE_GETREGS);
+
+ /* Now copy the register values into registers[].
+ Note that this code depends on the ordering of the REGNUMs
+ as defined in "tm-29k.h". */
+
+ bcopy (&am29k_greg_packet[AM29K_R_GR96],
+ &registers[REGISTER_BYTE (GR96_REGNUM)], 160 * AM29K_GREG_SIZE);
+ bcopy (&am29k_greg_packet[AM29K_R_VAB],
+ &registers[REGISTER_BYTE (VAB_REGNUM)], 15 * AM29K_GREG_SIZE);
+ registers[REGISTER_BYTE (INTE_REGNUM)] = am29k_greg_packet[AM29K_R_INTE];
+ bcopy (&am29k_greg_packet[AM29K_R_RSP],
+ &registers[REGISTER_BYTE (GR1_REGNUM)], 5 * AM29K_GREG_SIZE);
+
+ /* PAD For now, don't care about exop register */
+
+ memset (&registers[REGISTER_BYTE (EXO_REGNUM)], '\0', AM29K_GREG_SIZE);
+
+ /* If the target has floating point registers, fetch them.
+ Otherwise, zero the floating point register values in
+ registers[] for good measure, even though we might not
+ need to. */
+
+ if (target_has_fp)
+ {
+ net_read_registers (am29k_fpreg_packet, AM29K_FPREG_PLEN,
+ PTRACE_GETFPREGS);
+ registers[REGISTER_BYTE (FPE_REGNUM)] = am29k_fpreg_packet[AM29K_R_FPE];
+ registers[REGISTER_BYTE (FPS_REGNUM)] = am29k_fpreg_packet[AM29K_R_FPS];
+
+ /* PAD For now, don't care about registers (?) AI0 to q */
+
+ memset (&registers[REGISTER_BYTE (161)], '\0', 21 * AM29K_FPREG_SIZE);
+ }
+ else
+ {
+ memset (&registers[REGISTER_BYTE (FPE_REGNUM)], '\0', AM29K_FPREG_SIZE);
+ memset (&registers[REGISTER_BYTE (FPS_REGNUM)], '\0', AM29K_FPREG_SIZE);
+
+ /* PAD For now, don't care about registers (?) AI0 to q */
+
+ memset (&registers[REGISTER_BYTE (161)], '\0', 21 * AM29K_FPREG_SIZE);
+ }
+
+ /* Mark the register cache valid. */
+
+ registers_fetched ();
+}
+
+/* Store a register or registers into the VxWorks target.
+ REGNO is the register to store, or -1 for all; currently,
+ it is ignored. FIXME look at regno to improve efficiency. */
+
+void
+vx_write_register (int regno)
+{
+ char am29k_greg_packet[AM29K_GREG_PLEN];
+ char am29k_fpreg_packet[AM29K_FPREG_PLEN];
+
+ /* Store general purpose registers. When copying values from
+ registers [], don't assume that a location in registers []
+ is properly aligned for the target data type. */
+
+ bcopy (&registers[REGISTER_BYTE (GR96_REGNUM)],
+ &am29k_greg_packet[AM29K_R_GR96], 160 * AM29K_GREG_SIZE);
+ bcopy (&registers[REGISTER_BYTE (VAB_REGNUM)],
+ &am29k_greg_packet[AM29K_R_VAB], 15 * AM29K_GREG_SIZE);
+ am29k_greg_packet[AM29K_R_INTE] = registers[REGISTER_BYTE (INTE_REGNUM)];
+ bcopy (&registers[REGISTER_BYTE (GR1_REGNUM)],
+ &am29k_greg_packet[AM29K_R_RSP], 5 * AM29K_GREG_SIZE);
+
+ net_write_registers (am29k_greg_packet, AM29K_GREG_PLEN, PTRACE_SETREGS);
+
+ /* Store floating point registers if the target has them. */
+
+ if (target_has_fp)
+ {
+ am29k_fpreg_packet[AM29K_R_FPE] = registers[REGISTER_BYTE (FPE_REGNUM)];
+ am29k_fpreg_packet[AM29K_R_FPS] = registers[REGISTER_BYTE (FPS_REGNUM)];
+
+ net_write_registers (am29k_fpreg_packet, AM29K_FPREG_PLEN,
+ PTRACE_SETFPREGS);
+ }
+}
+
+/* VxWorks zeroes fp when the task is initialized; we use this
+ to terminate the frame chain. Chain means here the nominal address of
+ a frame, that is, the return address (lr0) address in the stack. To
+ obtain the frame pointer (lr1) contents, we must add 4 bytes.
+ Note : may be we should modify init_frame_info() to get the frame pointer
+ and store it into the frame_info struct rather than reading its
+ contents when FRAME_CHAIN_VALID is invoked. THISFRAME is unused. */
+
+int
+vx29k_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
+{
+ int fp_contents;
+
+ read_memory ((CORE_ADDR) (chain + 4), (char *) &fp_contents, 4);
+ return (fp_contents != 0);
+}
diff --git a/gdb/remote-vx68.c b/gdb/remote-vx68.c
new file mode 100644
index 00000000000..2ebaa633f77
--- /dev/null
+++ b/gdb/remote-vx68.c
@@ -0,0 +1,156 @@
+/* 68k-dependent portions of the RPC protocol
+ used with a VxWorks target
+
+ Contributed by Wind River Systems.
+
+ 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 <stdio.h>
+#include "defs.h"
+
+#include "vx-share/regPacket.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "symtab.h"
+#include "symfile.h" /* for struct complaint */
+#include "regcache.h"
+
+#include "gdb_string.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#ifdef _AIX /* IBM claims "void *malloc()" not char * */
+#define malloc bogon_malloc
+#endif
+
+#include <rpc/rpc.h>
+
+#ifdef _AIX
+#undef malloc
+#endif
+
+#include <sys/time.h> /* UTek's <rpc/rpc.h> doesn't #incl this */
+#include <netdb.h>
+#include "vx-share/ptrace.h"
+#include "vx-share/xdr_ptrace.h"
+#include "vx-share/xdr_ld.h"
+#include "vx-share/xdr_rdb.h"
+#include "vx-share/dbgRpcLib.h"
+
+/* get rid of value.h if possible */
+#include <value.h>
+#include <symtab.h>
+
+/* Flag set if target has fpu */
+
+extern int target_has_fp;
+
+/* Generic register read/write routines in remote-vx.c. */
+
+extern void net_read_registers ();
+extern void net_write_registers ();
+
+/* Read a register or registers from the VxWorks target.
+ REGNO is the register to read, or -1 for all; currently,
+ it is ignored. FIXME look at regno to improve efficiency. */
+
+void
+vx_read_register (int regno)
+{
+ char mc68k_greg_packet[MC68K_GREG_PLEN];
+ char mc68k_fpreg_packet[MC68K_FPREG_PLEN];
+
+ /* Get general-purpose registers. */
+
+ net_read_registers (mc68k_greg_packet, MC68K_GREG_PLEN, PTRACE_GETREGS);
+
+ bcopy (&mc68k_greg_packet[MC68K_R_D0], registers, 16 * MC68K_GREG_SIZE);
+ bcopy (&mc68k_greg_packet[MC68K_R_SR], &registers[REGISTER_BYTE (PS_REGNUM)],
+ MC68K_GREG_SIZE);
+ bcopy (&mc68k_greg_packet[MC68K_R_PC], &registers[REGISTER_BYTE (PC_REGNUM)],
+ MC68K_GREG_SIZE);
+
+ /* Get floating-point registers, if the target system has them.
+ Otherwise, zero them. */
+
+ if (target_has_fp)
+ {
+ net_read_registers (mc68k_fpreg_packet, MC68K_FPREG_PLEN,
+ PTRACE_GETFPREGS);
+
+ bcopy (&mc68k_fpreg_packet[MC68K_R_FP0],
+ &registers[REGISTER_BYTE (FP0_REGNUM)],
+ MC68K_FPREG_SIZE * 8);
+ bcopy (&mc68k_fpreg_packet[MC68K_R_FPCR],
+ &registers[REGISTER_BYTE (FPC_REGNUM)],
+ MC68K_FPREG_PLEN - (MC68K_FPREG_SIZE * 8));
+ }
+ else
+ {
+ bzero (&registers[REGISTER_BYTE (FP0_REGNUM)],
+ MC68K_FPREG_SIZE * 8);
+ bzero (&registers[REGISTER_BYTE (FPC_REGNUM)],
+ MC68K_FPREG_PLEN - (MC68K_FPREG_SIZE * 8));
+ }
+
+ /* Mark the register cache valid. */
+
+ registers_fetched ();
+}
+
+/* Store a register or registers into the VxWorks target.
+ REGNO is the register to store, or -1 for all; currently,
+ it is ignored. FIXME look at regno to improve efficiency. */
+
+void
+vx_write_register (int regno)
+{
+ char mc68k_greg_packet[MC68K_GREG_PLEN];
+ char mc68k_fpreg_packet[MC68K_FPREG_PLEN];
+
+ /* Store general-purpose registers. */
+
+ bcopy (registers, &mc68k_greg_packet[MC68K_R_D0], 16 * MC68K_GREG_SIZE);
+ bcopy (&registers[REGISTER_BYTE (PS_REGNUM)],
+ &mc68k_greg_packet[MC68K_R_SR], MC68K_GREG_SIZE);
+ bcopy (&registers[REGISTER_BYTE (PC_REGNUM)],
+ &mc68k_greg_packet[MC68K_R_PC], MC68K_GREG_SIZE);
+
+ net_write_registers (mc68k_greg_packet, MC68K_GREG_PLEN, PTRACE_SETREGS);
+
+ /* Store floating point registers if the target has them. */
+
+ if (target_has_fp)
+ {
+ bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)],
+ &mc68k_fpreg_packet[MC68K_R_FP0],
+ MC68K_FPREG_SIZE * 8);
+ bcopy (&registers[REGISTER_BYTE (FPC_REGNUM)],
+ &mc68k_fpreg_packet[MC68K_R_FPCR],
+ MC68K_FPREG_PLEN - (MC68K_FPREG_SIZE * 8));
+
+ net_write_registers (mc68k_fpreg_packet, MC68K_FPREG_PLEN,
+ PTRACE_SETFPREGS);
+ }
+}
diff --git a/gdb/remote-vx960.c b/gdb/remote-vx960.c
new file mode 100644
index 00000000000..08568bc4ca6
--- /dev/null
+++ b/gdb/remote-vx960.c
@@ -0,0 +1,160 @@
+/* i80960-dependent portions of the RPC protocol
+ used with a VxWorks target
+
+ Contributed by Wind River Systems.
+
+ 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 <stdio.h>
+#include "defs.h"
+
+#include "vx-share/regPacket.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "symtab.h"
+#include "symfile.h" /* for struct complaint */
+#include "regcache.h"
+
+#include "gdb_string.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#ifdef _AIX /* IBM claims "void *malloc()" not char * */
+#define malloc bogon_malloc
+#endif
+
+#include <rpc/rpc.h>
+#include <sys/time.h> /* UTek's <rpc/rpc.h> doesn't #incl this */
+#include <netdb.h>
+#include "vx-share/ptrace.h"
+#include "vx-share/xdr_ptrace.h"
+#include "vx-share/xdr_ld.h"
+#include "vx-share/xdr_rdb.h"
+#include "vx-share/dbgRpcLib.h"
+
+/* get rid of value.h if possible */
+#include <value.h>
+#include <symtab.h>
+
+/* Flag set if target has fpu */
+
+extern int target_has_fp;
+
+/* 960 floating point format descriptor, from "i960-tdep.c." */
+
+extern struct ext_format ext_format_i960;
+
+/* Generic register read/write routines in remote-vx.c. */
+
+extern void net_read_registers ();
+extern void net_write_registers ();
+
+/* Read a register or registers from the VxWorks target.
+ REGNO is the register to read, or -1 for all; currently,
+ it is ignored. FIXME look at regno to improve efficiency. */
+
+void
+vx_read_register (int regno)
+{
+ char i960_greg_packet[I960_GREG_PLEN];
+ char i960_fpreg_packet[I960_FPREG_PLEN];
+
+ /* Get general-purpose registers. When copying values into
+ registers [], don't assume that a location in registers []
+ is properly aligned for the target data type. */
+
+ net_read_registers (i960_greg_packet, I960_GREG_PLEN, PTRACE_GETREGS);
+
+ bcopy (&i960_greg_packet[I960_R_R0],
+ &registers[REGISTER_BYTE (R0_REGNUM)], 16 * I960_GREG_SIZE);
+ bcopy (&i960_greg_packet[I960_R_G0],
+ &registers[REGISTER_BYTE (G0_REGNUM)], 16 * I960_GREG_SIZE);
+ bcopy (&i960_greg_packet[I960_R_PCW],
+ &registers[REGISTER_BYTE (PCW_REGNUM)], sizeof (int));
+ bcopy (&i960_greg_packet[I960_R_ACW],
+ &registers[REGISTER_BYTE (ACW_REGNUM)], sizeof (int));
+ bcopy (&i960_greg_packet[I960_R_TCW],
+ &registers[REGISTER_BYTE (TCW_REGNUM)], sizeof (int));
+
+ /* If the target has floating point registers, fetch them.
+ Otherwise, zero the floating point register values in
+ registers[] for good measure, even though we might not
+ need to. */
+
+ if (target_has_fp)
+ {
+ net_read_registers (i960_fpreg_packet, I960_FPREG_PLEN,
+ PTRACE_GETFPREGS);
+ bcopy (&i960_fpreg_packet[I960_R_FP0],
+ &registers[REGISTER_BYTE (FP0_REGNUM)],
+ REGISTER_RAW_SIZE (FP0_REGNUM) * 4);
+ }
+ else
+ bzero (&registers[REGISTER_BYTE (FP0_REGNUM)],
+ REGISTER_RAW_SIZE (FP0_REGNUM) * 4);
+
+ /* Mark the register cache valid. */
+
+ registers_fetched ();
+}
+
+/* Store a register or registers into the VxWorks target.
+ REGNO is the register to store, or -1 for all; currently,
+ it is ignored. FIXME look at regno to improve efficiency. */
+
+void
+vx_write_register (int regno)
+{
+ char i960_greg_packet[I960_GREG_PLEN];
+ char i960_fpreg_packet[I960_FPREG_PLEN];
+
+ /* Store floating-point registers. When copying values from
+ registers [], don't assume that a location in registers []
+ is properly aligned for the target data type. */
+
+ bcopy (&registers[REGISTER_BYTE (R0_REGNUM)],
+ &i960_greg_packet[I960_R_R0], 16 * I960_GREG_SIZE);
+ bcopy (&registers[REGISTER_BYTE (G0_REGNUM)],
+ &i960_greg_packet[I960_R_G0], 16 * I960_GREG_SIZE);
+ bcopy (&registers[REGISTER_BYTE (PCW_REGNUM)],
+ &i960_greg_packet[I960_R_PCW], sizeof (int));
+ bcopy (&registers[REGISTER_BYTE (ACW_REGNUM)],
+ &i960_greg_packet[I960_R_ACW], sizeof (int));
+ bcopy (&registers[REGISTER_BYTE (TCW_REGNUM)],
+ &i960_greg_packet[I960_R_TCW], sizeof (int));
+
+ net_write_registers (i960_greg_packet, I960_GREG_PLEN, PTRACE_SETREGS);
+
+ /* Store floating point registers if the target has them. */
+
+ if (target_has_fp)
+ {
+ bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)],
+ &i960_fpreg_packet[I960_R_FP0],
+ REGISTER_RAW_SIZE (FP0_REGNUM) * 4);
+
+ net_write_registers (i960_fpreg_packet, I960_FPREG_PLEN,
+ PTRACE_SETFPREGS);
+ }
+}
diff --git a/gdb/remote-vxmips.c b/gdb/remote-vxmips.c
new file mode 100644
index 00000000000..8be4a2f9464
--- /dev/null
+++ b/gdb/remote-vxmips.c
@@ -0,0 +1,199 @@
+/* MIPS-dependent portions of the RPC protocol
+ used with a VxWorks target
+
+ Contributed by Wind River Systems.
+
+ 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 <stdio.h>
+#include "defs.h"
+
+#include "vx-share/regPacket.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "symtab.h"
+#include "symfile.h" /* for struct complaint */
+#include "regcache.h"
+
+#include "gdb_string.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <rpc/rpc.h>
+#include <sys/time.h> /* UTek's <rpc/rpc.h> doesn't #incl this */
+#include <netdb.h>
+#include "vx-share/ptrace.h"
+#include "vx-share/xdr_ptrace.h"
+#include "vx-share/xdr_ld.h"
+#include "vx-share/xdr_rdb.h"
+#include "vx-share/dbgRpcLib.h"
+
+/* get rid of value.h if possible */
+#include <value.h>
+#include <symtab.h>
+
+/* Flag set if target has fpu */
+
+extern int target_has_fp;
+
+/* Generic register read/write routines in remote-vx.c. */
+
+extern void net_read_registers ();
+extern void net_write_registers ();
+
+/* Read a register or registers from the VxWorks target.
+ REGNO is the register to read, or -1 for all; currently,
+ it is ignored. FIXME look at regno to improve efficiency. */
+
+void
+vx_read_register (int regno)
+{
+ char mips_greg_packet[MIPS_GREG_PLEN];
+ char mips_fpreg_packet[MIPS_FPREG_PLEN];
+
+ /* Get general-purpose registers. */
+
+ net_read_registers (mips_greg_packet, MIPS_GREG_PLEN, PTRACE_GETREGS);
+
+ /* this code copies the registers obtained by RPC
+ stored in a structure(s) like this :
+
+ Register(s) Offset(s)
+ gp 0-31 0x00
+ hi 0x80
+ lo 0x84
+ sr 0x88
+ pc 0x8c
+
+ into a stucture like this:
+
+ 0x00 GP 0-31
+ 0x80 SR
+ 0x84 LO
+ 0x88 HI
+ 0x8C BAD --- Not available currently
+ 0x90 CAUSE --- Not available currently
+ 0x94 PC
+ 0x98 FP 0-31
+ 0x118 FCSR
+ 0x11C FIR --- Not available currently
+ 0x120 FP --- Not available currently
+
+ structure is 0x124 (292) bytes in length */
+
+ /* Copy the general registers. */
+
+ bcopy (&mips_greg_packet[MIPS_R_GP0], &registers[0], 32 * MIPS_GREG_SIZE);
+
+ /* Copy SR, LO, HI, and PC. */
+
+ bcopy (&mips_greg_packet[MIPS_R_SR],
+ &registers[REGISTER_BYTE (PS_REGNUM)], MIPS_GREG_SIZE);
+ bcopy (&mips_greg_packet[MIPS_R_LO],
+ &registers[REGISTER_BYTE (LO_REGNUM)], MIPS_GREG_SIZE);
+ bcopy (&mips_greg_packet[MIPS_R_HI],
+ &registers[REGISTER_BYTE (HI_REGNUM)], MIPS_GREG_SIZE);
+ bcopy (&mips_greg_packet[MIPS_R_PC],
+ &registers[REGISTER_BYTE (PC_REGNUM)], MIPS_GREG_SIZE);
+
+ /* If the target has floating point registers, fetch them.
+ Otherwise, zero the floating point register values in
+ registers[] for good measure, even though we might not
+ need to. */
+
+ if (target_has_fp)
+ {
+ net_read_registers (mips_fpreg_packet, MIPS_FPREG_PLEN,
+ PTRACE_GETFPREGS);
+
+ /* Copy the floating point registers. */
+
+ bcopy (&mips_fpreg_packet[MIPS_R_FP0],
+ &registers[REGISTER_BYTE (FP0_REGNUM)],
+ REGISTER_RAW_SIZE (FP0_REGNUM) * 32);
+
+ /* Copy the floating point control/status register (fpcsr). */
+
+ bcopy (&mips_fpreg_packet[MIPS_R_FPCSR],
+ &registers[REGISTER_BYTE (FCRCS_REGNUM)],
+ REGISTER_RAW_SIZE (FCRCS_REGNUM));
+ }
+ else
+ {
+ bzero ((char *) &registers[REGISTER_BYTE (FP0_REGNUM)],
+ REGISTER_RAW_SIZE (FP0_REGNUM) * 32);
+ bzero ((char *) &registers[REGISTER_BYTE (FCRCS_REGNUM)],
+ REGISTER_RAW_SIZE (FCRCS_REGNUM));
+ }
+
+ /* Mark the register cache valid. */
+
+ registers_fetched ();
+}
+
+/* Store a register or registers into the VxWorks target.
+ REGNO is the register to store, or -1 for all; currently,
+ it is ignored. FIXME look at regno to improve efficiency. */
+
+vx_write_register (int regno)
+{
+ char mips_greg_packet[MIPS_GREG_PLEN];
+ char mips_fpreg_packet[MIPS_FPREG_PLEN];
+
+ /* Store general registers. */
+
+ bcopy (&registers[0], &mips_greg_packet[MIPS_R_GP0], 32 * MIPS_GREG_SIZE);
+
+ /* Copy SR, LO, HI, and PC. */
+
+ bcopy (&registers[REGISTER_BYTE (PS_REGNUM)],
+ &mips_greg_packet[MIPS_R_SR], MIPS_GREG_SIZE);
+ bcopy (&registers[REGISTER_BYTE (LO_REGNUM)],
+ &mips_greg_packet[MIPS_R_LO], MIPS_GREG_SIZE);
+ bcopy (&registers[REGISTER_BYTE (HI_REGNUM)],
+ &mips_greg_packet[MIPS_R_HI], MIPS_GREG_SIZE);
+ bcopy (&registers[REGISTER_BYTE (PC_REGNUM)],
+ &mips_greg_packet[MIPS_R_PC], MIPS_GREG_SIZE);
+
+ net_write_registers (mips_greg_packet, MIPS_GREG_PLEN, PTRACE_SETREGS);
+
+ /* Store floating point registers if the target has them. */
+
+ if (target_has_fp)
+ {
+ /* Copy the floating point data registers. */
+
+ bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)],
+ &mips_fpreg_packet[MIPS_R_FP0],
+ REGISTER_RAW_SIZE (FP0_REGNUM) * 32);
+
+ /* Copy the floating point control/status register (fpcsr). */
+
+ bcopy (&registers[REGISTER_BYTE (FCRCS_REGNUM)],
+ &mips_fpreg_packet[MIPS_R_FPCSR],
+ REGISTER_RAW_SIZE (FCRCS_REGNUM));
+
+ net_write_registers (mips_fpreg_packet, MIPS_FPREG_PLEN,
+ PTRACE_SETFPREGS);
+ }
+}
diff --git a/gdb/remote-vxsparc.c b/gdb/remote-vxsparc.c
new file mode 100644
index 00000000000..294e940f500
--- /dev/null
+++ b/gdb/remote-vxsparc.c
@@ -0,0 +1,194 @@
+/* sparc-dependent portions of the RPC protocol
+ used with a VxWorks target
+
+ Contributed by Wind River Systems.
+
+ 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 <stdio.h>
+#include "defs.h"
+
+#include "vx-share/regPacket.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "symtab.h"
+#include "symfile.h" /* for struct complaint */
+#include "regcache.h"
+
+#include "gdb_string.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#ifdef _AIX /* IBM claims "void *malloc()" not char * */
+#define malloc bogon_malloc
+#endif
+
+#include <rpc/rpc.h>
+#include <sys/time.h> /* UTek's <rpc/rpc.h> doesn't #incl this */
+#include <netdb.h>
+#include "vx-share/ptrace.h"
+#include "vx-share/xdr_ptrace.h"
+#include "vx-share/xdr_ld.h"
+#include "vx-share/xdr_rdb.h"
+#include "vx-share/dbgRpcLib.h"
+
+/* get rid of value.h if possible */
+#include <value.h>
+#include <symtab.h>
+
+/* Flag set if target has fpu */
+
+extern int target_has_fp;
+
+/* sparc floating point format descriptor, from "sparc-tdep.c." */
+
+extern struct ext_format ext_format_sparc;
+
+/* Generic register read/write routines in remote-vx.c. */
+
+extern void net_read_registers ();
+extern void net_write_registers ();
+
+/* Read a register or registers from the VxWorks target.
+ REGNO is the register to read, or -1 for all; currently,
+ it is ignored. FIXME look at regno to improve efficiency. */
+
+void
+vx_read_register (int regno)
+{
+ char sparc_greg_packet[SPARC_GREG_PLEN];
+ char sparc_fpreg_packet[SPARC_FPREG_PLEN];
+ CORE_ADDR sp;
+
+ /* Get general-purpose registers. When copying values into
+ registers [], don't assume that a location in registers []
+ is properly aligned for the target data type. */
+
+ net_read_registers (sparc_greg_packet, SPARC_GREG_PLEN, PTRACE_GETREGS);
+
+ /* Now copy the register values into registers[].
+ Note that this code depends on the ordering of the REGNUMs
+ as defined in "tm-sparc.h". */
+
+ bcopy (&sparc_greg_packet[SPARC_R_G0],
+ &registers[REGISTER_BYTE (G0_REGNUM)], 32 * SPARC_GREG_SIZE);
+ bcopy (&sparc_greg_packet[SPARC_R_Y],
+ &registers[REGISTER_BYTE (Y_REGNUM)], 6 * SPARC_GREG_SIZE);
+
+ /* Now write the local and in registers to the register window
+ spill area in the frame. VxWorks does not do this for the
+ active frame automatically; it greatly simplifies debugging
+ (FRAME_FIND_SAVED_REGS, in particular, depends on this). */
+
+ sp = extract_address (&registers[REGISTER_BYTE (SP_REGNUM)],
+ REGISTER_RAW_SIZE (SP_REGNUM));
+ write_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
+ 16 * REGISTER_RAW_SIZE (L0_REGNUM));
+
+ /* If the target has floating point registers, fetch them.
+ Otherwise, zero the floating point register values in
+ registers[] for good measure, even though we might not
+ need to. */
+
+ if (target_has_fp)
+ {
+ net_read_registers (sparc_fpreg_packet, SPARC_FPREG_PLEN,
+ PTRACE_GETFPREGS);
+ bcopy (&sparc_fpreg_packet[SPARC_R_FP0],
+ &registers[REGISTER_BYTE (FP0_REGNUM)], 32 * SPARC_FPREG_SIZE);
+ bcopy (&sparc_fpreg_packet[SPARC_R_FSR],
+ &registers[REGISTER_BYTE (FPS_REGNUM)], 1 * SPARC_FPREG_SIZE);
+ }
+ else
+ {
+ bzero (&registers[REGISTER_BYTE (FP0_REGNUM)], 32 * SPARC_FPREG_SIZE);
+ bzero (&registers[REGISTER_BYTE (FPS_REGNUM)], 1 * SPARC_FPREG_SIZE);
+ }
+
+ /* Mark the register cache valid. */
+
+ registers_fetched ();
+}
+
+/* Store a register or registers into the VxWorks target.
+ REGNO is the register to store, or -1 for all; currently,
+ it is ignored. FIXME look at regno to improve efficiency. */
+
+void
+vx_write_register (int regno)
+{
+ char sparc_greg_packet[SPARC_GREG_PLEN];
+ char sparc_fpreg_packet[SPARC_FPREG_PLEN];
+ int in_gp_regs;
+ int in_fp_regs;
+ CORE_ADDR sp;
+
+ /* Store general purpose registers. When copying values from
+ registers [], don't assume that a location in registers []
+ is properly aligned for the target data type. */
+
+ in_gp_regs = 1;
+ in_fp_regs = 1;
+ if (regno >= 0)
+ {
+ if ((G0_REGNUM <= regno && regno <= I7_REGNUM)
+ || (Y_REGNUM <= regno && regno <= NPC_REGNUM))
+ in_fp_regs = 0;
+ else
+ in_gp_regs = 0;
+ }
+ if (in_gp_regs)
+ {
+ bcopy (&registers[REGISTER_BYTE (G0_REGNUM)],
+ &sparc_greg_packet[SPARC_R_G0], 32 * SPARC_GREG_SIZE);
+ bcopy (&registers[REGISTER_BYTE (Y_REGNUM)],
+ &sparc_greg_packet[SPARC_R_Y], 6 * SPARC_GREG_SIZE);
+
+ net_write_registers (sparc_greg_packet, SPARC_GREG_PLEN, PTRACE_SETREGS);
+
+ /* If this is a local or in register, or we're storing all
+ registers, update the register window spill area. */
+
+ if (regno < 0 || (L0_REGNUM <= regno && regno <= I7_REGNUM))
+ {
+ sp = extract_address (&registers[REGISTER_BYTE (SP_REGNUM)],
+ REGISTER_RAW_SIZE (SP_REGNUM));
+ write_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
+ 16 * REGISTER_RAW_SIZE (L0_REGNUM));
+ }
+ }
+
+ /* Store floating point registers if the target has them. */
+
+ if (in_fp_regs && target_has_fp)
+ {
+ bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)],
+ &sparc_fpreg_packet[SPARC_R_FP0], 32 * SPARC_FPREG_SIZE);
+ bcopy (&registers[REGISTER_BYTE (FPS_REGNUM)],
+ &sparc_fpreg_packet[SPARC_R_FSR], 1 * SPARC_FPREG_SIZE);
+
+ net_write_registers (sparc_fpreg_packet, SPARC_FPREG_PLEN,
+ PTRACE_SETFPREGS);
+ }
+}
diff --git a/gdb/remote.c b/gdb/remote.c
new file mode 100644
index 00000000000..a1b90b7a5a4
--- /dev/null
+++ b/gdb/remote.c
@@ -0,0 +1,6218 @@
+/* Remote target communications for serial-line targets in custom GDB protocol
+
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001, 2002 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. */
+
+/* See the GDB User Guide for details of the GDB remote protocol. */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include <ctype.h>
+#include <fcntl.h>
+#include "inferior.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "target.h"
+/*#include "terminal.h" */
+#include "gdbcmd.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include "gdbthread.h"
+#include "remote.h"
+#include "regcache.h"
+#include "value.h"
+#include "gdb_assert.h"
+
+#include <ctype.h>
+#include <sys/time.h>
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include "event-loop.h"
+#include "event-top.h"
+#include "inf-loop.h"
+
+#include <signal.h>
+#include "serial.h"
+
+#include "gdbcore.h" /* for exec_bfd */
+
+/* Prototypes for local functions */
+static void cleanup_sigint_signal_handler (void *dummy);
+static void initialize_sigint_signal_handler (void);
+static int getpkt_sane (char *buf, long sizeof_buf, int forever);
+
+static void handle_remote_sigint (int);
+static void handle_remote_sigint_twice (int);
+static void async_remote_interrupt (gdb_client_data);
+void async_remote_interrupt_twice (gdb_client_data);
+
+static void build_remote_gdbarch_data (void);
+
+static int remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len);
+
+static int remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len);
+
+static void remote_files_info (struct target_ops *ignore);
+
+static int remote_xfer_memory (CORE_ADDR memaddr, char *myaddr,
+ int len, int should_write,
+ struct mem_attrib *attrib,
+ struct target_ops *target);
+
+static void remote_prepare_to_store (void);
+
+static void remote_fetch_registers (int regno);
+
+static void remote_resume (ptid_t ptid, int step,
+ enum target_signal siggnal);
+static void remote_async_resume (ptid_t ptid, int step,
+ enum target_signal siggnal);
+static int remote_start_remote (struct ui_out *uiout, void *dummy);
+
+static void remote_open (char *name, int from_tty);
+static void remote_async_open (char *name, int from_tty);
+
+static void extended_remote_open (char *name, int from_tty);
+static void extended_remote_async_open (char *name, int from_tty);
+
+static void remote_open_1 (char *, int, struct target_ops *, int extended_p);
+static void remote_async_open_1 (char *, int, struct target_ops *,
+ int extended_p);
+
+static void remote_close (int quitting);
+
+static void remote_store_registers (int regno);
+
+static void remote_mourn (void);
+static void remote_async_mourn (void);
+
+static void extended_remote_restart (void);
+
+static void extended_remote_mourn (void);
+
+static void extended_remote_create_inferior (char *, char *, char **);
+static void extended_remote_async_create_inferior (char *, char *, char **);
+
+static void remote_mourn_1 (struct target_ops *);
+
+static void remote_send (char *buf, long sizeof_buf);
+
+static int readchar (int timeout);
+
+static ptid_t remote_wait (ptid_t ptid,
+ struct target_waitstatus *status);
+static ptid_t remote_async_wait (ptid_t ptid,
+ struct target_waitstatus *status);
+
+static void remote_kill (void);
+static void remote_async_kill (void);
+
+static int tohex (int nib);
+
+static void remote_detach (char *args, int from_tty);
+static void remote_async_detach (char *args, int from_tty);
+
+static void remote_interrupt (int signo);
+
+static void remote_interrupt_twice (int signo);
+
+static void interrupt_query (void);
+
+static void set_thread (int, int);
+
+static int remote_thread_alive (ptid_t);
+
+static void get_offsets (void);
+
+static long read_frame (char *buf, long sizeof_buf);
+
+static int remote_insert_breakpoint (CORE_ADDR, char *);
+
+static int remote_remove_breakpoint (CORE_ADDR, char *);
+
+static int hexnumlen (ULONGEST num);
+
+static void init_remote_ops (void);
+
+static void init_extended_remote_ops (void);
+
+static void init_remote_cisco_ops (void);
+
+static struct target_ops remote_cisco_ops;
+
+static void remote_stop (void);
+
+static int ishex (int ch, int *val);
+
+static int stubhex (int ch);
+
+static int remote_query (int /*char */ , char *, char *, int *);
+
+static int hexnumstr (char *, ULONGEST);
+
+static int hexnumnstr (char *, ULONGEST, int);
+
+static CORE_ADDR remote_address_masked (CORE_ADDR);
+
+static void print_packet (char *);
+
+static unsigned long crc32 (unsigned char *, int, unsigned int);
+
+static void compare_sections_command (char *, int);
+
+static void packet_command (char *, int);
+
+static int stub_unpack_int (char *buff, int fieldlength);
+
+static ptid_t remote_current_thread (ptid_t oldptid);
+
+static void remote_find_new_threads (void);
+
+static void record_currthread (int currthread);
+
+static int fromhex (int a);
+
+static int hex2bin (const char *hex, char *bin, int count);
+
+static int bin2hex (const char *bin, char *hex, int count);
+
+static int putpkt_binary (char *buf, int cnt);
+
+static void check_binary_download (CORE_ADDR addr);
+
+struct packet_config;
+
+static void show_packet_config_cmd (struct packet_config *config);
+
+static void update_packet_config (struct packet_config *config);
+
+/* Define the target subroutine names */
+
+void open_remote_target (char *, int, struct target_ops *, int);
+
+void _initialize_remote (void);
+
+/* Description of the remote protocol. Strictly speaking, when the
+ target is open()ed, remote.c should create a per-target description
+ of the remote protocol using that target's architecture.
+ Unfortunatly, the target stack doesn't include local state. For
+ the moment keep the information in the target's architecture
+ object. Sigh.. */
+
+struct packet_reg
+{
+ long offset; /* Offset into G packet. */
+ long regnum; /* GDB's internal register number. */
+ LONGEST pnum; /* Remote protocol register number. */
+ int in_g_packet; /* Always part of G packet. */
+ /* long size in bytes; == REGISTER_RAW_SIZE (regnum); at present. */
+ /* char *name; == REGISTER_NAME (regnum); at present. */
+};
+
+struct remote_state
+{
+ /* Description of the remote protocol registers. */
+ long sizeof_g_packet;
+
+ /* Description of the remote protocol registers indexed by REGNUM
+ (making an array of NUM_REGS + NUM_PSEUDO_REGS in size). */
+ struct packet_reg *regs;
+
+ /* This is the size (in chars) of the first response to the ``g''
+ packet. It is used as a heuristic when determining the maximum
+ size of memory-read and memory-write packets. A target will
+ typically only reserve a buffer large enough to hold the ``g''
+ packet. The size does not include packet overhead (headers and
+ trailers). */
+ long actual_register_packet_size;
+
+ /* This is the maximum size (in chars) of a non read/write packet.
+ It is also used as a cap on the size of read/write packets. */
+ long remote_packet_size;
+};
+
+/* Handle for retreving the remote protocol data from gdbarch. */
+static struct gdbarch_data *remote_gdbarch_data_handle;
+
+static struct remote_state *
+get_remote_state ()
+{
+ return gdbarch_data (current_gdbarch, remote_gdbarch_data_handle);
+}
+
+static void *
+init_remote_state (struct gdbarch *gdbarch)
+{
+ int regnum;
+ struct remote_state *rs = xmalloc (sizeof (struct remote_state));
+
+ /* Start out by having the remote protocol mimic the existing
+ behavour - just copy in the description of the register cache. */
+ rs->sizeof_g_packet = REGISTER_BYTES; /* OK use. */
+
+ /* Assume a 1:1 regnum<->pnum table. */
+ rs->regs = xcalloc (NUM_REGS + NUM_PSEUDO_REGS, sizeof (struct packet_reg));
+ for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+ {
+ struct packet_reg *r = &rs->regs[regnum];
+ r->pnum = regnum;
+ r->regnum = regnum;
+ r->offset = REGISTER_BYTE (regnum);
+ r->in_g_packet = (regnum < NUM_REGS);
+ /* ...size = REGISTER_RAW_SIZE (regnum); */
+ /* ...name = REGISTER_NAME (regnum); */
+ }
+
+ /* Default maximum number of characters in a packet body. Many
+ remote stubs have a hardwired buffer size of 400 bytes
+ (c.f. BUFMAX in m68k-stub.c and i386-stub.c). BUFMAX-1 is used
+ as the maximum packet-size to ensure that the packet and an extra
+ NUL character can always fit in the buffer. This stops GDB
+ trashing stubs that try to squeeze an extra NUL into what is
+ already a full buffer (As of 1999-12-04 that was most stubs. */
+ rs->remote_packet_size = 400 - 1;
+
+ /* Should rs->sizeof_g_packet needs more space than the
+ default, adjust the size accordingly. Remember that each byte is
+ encoded as two characters. 32 is the overhead for the packet
+ header / footer. NOTE: cagney/1999-10-26: I suspect that 8
+ (``$NN:G...#NN'') is a better guess, the below has been padded a
+ little. */
+ if (rs->sizeof_g_packet > ((rs->remote_packet_size - 32) / 2))
+ rs->remote_packet_size = (rs->sizeof_g_packet * 2 + 32);
+
+ /* This one is filled in when a ``g'' packet is received. */
+ rs->actual_register_packet_size = 0;
+
+ return rs;
+}
+
+static void
+free_remote_state (struct gdbarch *gdbarch, void *pointer)
+{
+ struct remote_state *data = pointer;
+ xfree (data->regs);
+ xfree (data);
+}
+
+static struct packet_reg *
+packet_reg_from_regnum (struct remote_state *rs, long regnum)
+{
+ if (regnum < 0 && regnum >= NUM_REGS + NUM_PSEUDO_REGS)
+ return NULL;
+ else
+ {
+ struct packet_reg *r = &rs->regs[regnum];
+ gdb_assert (r->regnum == regnum);
+ return r;
+ }
+}
+
+static struct packet_reg *
+packet_reg_from_pnum (struct remote_state *rs, LONGEST pnum)
+{
+ int i;
+ for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+ {
+ struct packet_reg *r = &rs->regs[i];
+ if (r->pnum == pnum)
+ return r;
+ }
+ return NULL;
+}
+
+/* */
+
+static struct target_ops remote_ops;
+
+static struct target_ops extended_remote_ops;
+
+/* Temporary target ops. Just like the remote_ops and
+ extended_remote_ops, but with asynchronous support. */
+static struct target_ops remote_async_ops;
+
+static struct target_ops extended_async_remote_ops;
+
+/* FIXME: cagney/1999-09-23: Even though getpkt was called with
+ ``forever'' still use the normal timeout mechanism. This is
+ currently used by the ASYNC code to guarentee that target reads
+ during the initial connect always time-out. Once getpkt has been
+ modified to return a timeout indication and, in turn
+ remote_wait()/wait_for_inferior() have gained a timeout parameter
+ this can go away. */
+static int wait_forever_enabled_p = 1;
+
+
+/* This variable chooses whether to send a ^C or a break when the user
+ requests program interruption. Although ^C is usually what remote
+ systems expect, and that is the default here, sometimes a break is
+ preferable instead. */
+
+static int remote_break;
+
+/* Descriptor for I/O to remote machine. Initialize it to NULL so that
+ remote_open knows that we don't have a file open when the program
+ starts. */
+static struct serial *remote_desc = NULL;
+
+/* This is set by the target (thru the 'S' message)
+ to denote that the target is in kernel mode. */
+static int cisco_kernel_mode = 0;
+
+/* This variable sets the number of bits in an address that are to be
+ sent in a memory ("M" or "m") packet. Normally, after stripping
+ leading zeros, the entire address would be sent. This variable
+ restricts the address to REMOTE_ADDRESS_SIZE bits. HISTORY: The
+ initial implementation of remote.c restricted the address sent in
+ memory packets to ``host::sizeof long'' bytes - (typically 32
+ bits). Consequently, for 64 bit targets, the upper 32 bits of an
+ address was never sent. Since fixing this bug may cause a break in
+ some remote targets this variable is principly provided to
+ facilitate backward compatibility. */
+
+static int remote_address_size;
+
+/* Tempoary to track who currently owns the terminal. See
+ target_async_terminal_* for more details. */
+
+static int remote_async_terminal_ours_p;
+
+
+/* User configurable variables for the number of characters in a
+ memory read/write packet. MIN ((rs->remote_packet_size),
+ rs->sizeof_g_packet) is the default. Some targets need smaller
+ values (fifo overruns, et.al.) and some users need larger values
+ (speed up transfers). The variables ``preferred_*'' (the user
+ request), ``current_*'' (what was actually set) and ``forced_*''
+ (Positive - a soft limit, negative - a hard limit). */
+
+struct memory_packet_config
+{
+ char *name;
+ long size;
+ int fixed_p;
+};
+
+/* Compute the current size of a read/write packet. Since this makes
+ use of ``actual_register_packet_size'' the computation is dynamic. */
+
+static long
+get_memory_packet_size (struct memory_packet_config *config)
+{
+ struct remote_state *rs = get_remote_state ();
+ /* NOTE: The somewhat arbitrary 16k comes from the knowledge (folk
+ law?) that some hosts don't cope very well with large alloca()
+ calls. Eventually the alloca() code will be replaced by calls to
+ xmalloc() and make_cleanups() allowing this restriction to either
+ be lifted or removed. */
+#ifndef MAX_REMOTE_PACKET_SIZE
+#define MAX_REMOTE_PACKET_SIZE 16384
+#endif
+ /* NOTE: 16 is just chosen at random. */
+#ifndef MIN_REMOTE_PACKET_SIZE
+#define MIN_REMOTE_PACKET_SIZE 16
+#endif
+ long what_they_get;
+ if (config->fixed_p)
+ {
+ if (config->size <= 0)
+ what_they_get = MAX_REMOTE_PACKET_SIZE;
+ else
+ what_they_get = config->size;
+ }
+ else
+ {
+ what_they_get = (rs->remote_packet_size);
+ /* Limit the packet to the size specified by the user. */
+ if (config->size > 0
+ && what_they_get > config->size)
+ what_they_get = config->size;
+ /* Limit it to the size of the targets ``g'' response. */
+ if ((rs->actual_register_packet_size) > 0
+ && what_they_get > (rs->actual_register_packet_size))
+ what_they_get = (rs->actual_register_packet_size);
+ }
+ if (what_they_get > MAX_REMOTE_PACKET_SIZE)
+ what_they_get = MAX_REMOTE_PACKET_SIZE;
+ if (what_they_get < MIN_REMOTE_PACKET_SIZE)
+ what_they_get = MIN_REMOTE_PACKET_SIZE;
+ return what_they_get;
+}
+
+/* Update the size of a read/write packet. If they user wants
+ something really big then do a sanity check. */
+
+static void
+set_memory_packet_size (char *args, struct memory_packet_config *config)
+{
+ int fixed_p = config->fixed_p;
+ long size = config->size;
+ if (args == NULL)
+ error ("Argument required (integer, `fixed' or `limited').");
+ else if (strcmp (args, "hard") == 0
+ || strcmp (args, "fixed") == 0)
+ fixed_p = 1;
+ else if (strcmp (args, "soft") == 0
+ || strcmp (args, "limit") == 0)
+ fixed_p = 0;
+ else
+ {
+ char *end;
+ size = strtoul (args, &end, 0);
+ if (args == end)
+ error ("Invalid %s (bad syntax).", config->name);
+#if 0
+ /* Instead of explicitly capping the size of a packet to
+ MAX_REMOTE_PACKET_SIZE or dissallowing it, the user is
+ instead allowed to set the size to something arbitrarily
+ large. */
+ if (size > MAX_REMOTE_PACKET_SIZE)
+ error ("Invalid %s (too large).", config->name);
+#endif
+ }
+ /* Extra checks? */
+ if (fixed_p && !config->fixed_p)
+ {
+ if (! query ("The target may not be able to correctly handle a %s\n"
+ "of %ld bytes. Change the packet size? ",
+ config->name, size))
+ error ("Packet size not changed.");
+ }
+ /* Update the config. */
+ config->fixed_p = fixed_p;
+ config->size = size;
+}
+
+static void
+show_memory_packet_size (struct memory_packet_config *config)
+{
+ printf_filtered ("The %s is %ld. ", config->name, config->size);
+ if (config->fixed_p)
+ printf_filtered ("Packets are fixed at %ld bytes.\n",
+ get_memory_packet_size (config));
+ else
+ printf_filtered ("Packets are limited to %ld bytes.\n",
+ get_memory_packet_size (config));
+}
+
+static struct memory_packet_config memory_write_packet_config =
+{
+ "memory-write-packet-size",
+};
+
+static void
+set_memory_write_packet_size (char *args, int from_tty)
+{
+ set_memory_packet_size (args, &memory_write_packet_config);
+}
+
+static void
+show_memory_write_packet_size (char *args, int from_tty)
+{
+ show_memory_packet_size (&memory_write_packet_config);
+}
+
+static long
+get_memory_write_packet_size (void)
+{
+ return get_memory_packet_size (&memory_write_packet_config);
+}
+
+static struct memory_packet_config memory_read_packet_config =
+{
+ "memory-read-packet-size",
+};
+
+static void
+set_memory_read_packet_size (char *args, int from_tty)
+{
+ set_memory_packet_size (args, &memory_read_packet_config);
+}
+
+static void
+show_memory_read_packet_size (char *args, int from_tty)
+{
+ show_memory_packet_size (&memory_read_packet_config);
+}
+
+static long
+get_memory_read_packet_size (void)
+{
+ struct remote_state *rs = get_remote_state ();
+ long size = get_memory_packet_size (&memory_read_packet_config);
+ /* FIXME: cagney/1999-11-07: Functions like getpkt() need to get an
+ extra buffer size argument before the memory read size can be
+ increased beyond (rs->remote_packet_size). */
+ if (size > (rs->remote_packet_size))
+ size = (rs->remote_packet_size);
+ return size;
+}
+
+
+/* Generic configuration support for packets the stub optionally
+ supports. Allows the user to specify the use of the packet as well
+ as allowing GDB to auto-detect support in the remote stub. */
+
+enum packet_support
+ {
+ PACKET_SUPPORT_UNKNOWN = 0,
+ PACKET_ENABLE,
+ PACKET_DISABLE
+ };
+
+struct packet_config
+ {
+ char *name;
+ char *title;
+ enum cmd_auto_boolean detect;
+ enum packet_support support;
+ };
+
+/* Analyze a packet's return value and update the packet config
+ accordingly. */
+
+enum packet_result
+{
+ PACKET_ERROR,
+ PACKET_OK,
+ PACKET_UNKNOWN
+};
+
+static void
+update_packet_config (struct packet_config *config)
+{
+ switch (config->detect)
+ {
+ case CMD_AUTO_BOOLEAN_TRUE:
+ config->support = PACKET_ENABLE;
+ break;
+ case CMD_AUTO_BOOLEAN_FALSE:
+ config->support = PACKET_DISABLE;
+ break;
+ case CMD_AUTO_BOOLEAN_AUTO:
+ config->support = PACKET_SUPPORT_UNKNOWN;
+ break;
+ }
+}
+
+static void
+show_packet_config_cmd (struct packet_config *config)
+{
+ char *support = "internal-error";
+ switch (config->support)
+ {
+ case PACKET_ENABLE:
+ support = "enabled";
+ break;
+ case PACKET_DISABLE:
+ support = "disabled";
+ break;
+ case PACKET_SUPPORT_UNKNOWN:
+ support = "unknown";
+ break;
+ }
+ switch (config->detect)
+ {
+ case CMD_AUTO_BOOLEAN_AUTO:
+ printf_filtered ("Support for remote protocol `%s' (%s) packet is auto-detected, currently %s.\n",
+ config->name, config->title, support);
+ break;
+ case CMD_AUTO_BOOLEAN_TRUE:
+ case CMD_AUTO_BOOLEAN_FALSE:
+ printf_filtered ("Support for remote protocol `%s' (%s) packet is currently %s.\n",
+ config->name, config->title, support);
+ break;
+ }
+}
+
+static void
+add_packet_config_cmd (struct packet_config *config,
+ char *name,
+ char *title,
+ void (*set_func) (char *args, int from_tty,
+ struct cmd_list_element *
+ c),
+ void (*show_func) (char *name,
+ int from_tty),
+ struct cmd_list_element **set_remote_list,
+ struct cmd_list_element **show_remote_list,
+ int legacy)
+{
+ struct cmd_list_element *set_cmd;
+ struct cmd_list_element *show_cmd;
+ char *set_doc;
+ char *show_doc;
+ char *cmd_name;
+ config->name = name;
+ config->title = title;
+ config->detect = CMD_AUTO_BOOLEAN_AUTO;
+ config->support = PACKET_SUPPORT_UNKNOWN;
+ xasprintf (&set_doc, "Set use of remote protocol `%s' (%s) packet",
+ name, title);
+ xasprintf (&show_doc, "Show current use of remote protocol `%s' (%s) packet",
+ name, title);
+ /* set/show TITLE-packet {auto,on,off} */
+ xasprintf (&cmd_name, "%s-packet", title);
+ set_cmd = add_set_auto_boolean_cmd (cmd_name, class_obscure,
+ &config->detect, set_doc,
+ set_remote_list);
+ set_cmd_sfunc (set_cmd, set_func);
+ show_cmd = add_cmd (cmd_name, class_obscure, show_func, show_doc,
+ show_remote_list);
+ /* set/show remote NAME-packet {auto,on,off} -- legacy */
+ if (legacy)
+ {
+ char *legacy_name;
+ xasprintf (&legacy_name, "%s-packet", name);
+ add_alias_cmd (legacy_name, cmd_name, class_obscure, 0,
+ set_remote_list);
+ add_alias_cmd (legacy_name, cmd_name, class_obscure, 0,
+ show_remote_list);
+ }
+}
+
+static enum packet_result
+packet_ok (const char *buf, struct packet_config *config)
+{
+ if (buf[0] != '\0')
+ {
+ /* The stub recognized the packet request. Check that the
+ operation succeeded. */
+ switch (config->support)
+ {
+ case PACKET_SUPPORT_UNKNOWN:
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "Packet %s (%s) is supported\n",
+ config->name, config->title);
+ config->support = PACKET_ENABLE;
+ break;
+ case PACKET_DISABLE:
+ internal_error (__FILE__, __LINE__,
+ "packet_ok: attempt to use a disabled packet");
+ break;
+ case PACKET_ENABLE:
+ break;
+ }
+ if (buf[0] == 'O' && buf[1] == 'K' && buf[2] == '\0')
+ /* "OK" - definitly OK. */
+ return PACKET_OK;
+ if (buf[0] == 'E'
+ && isxdigit (buf[1]) && isxdigit (buf[2])
+ && buf[3] == '\0')
+ /* "Enn" - definitly an error. */
+ return PACKET_ERROR;
+ /* The packet may or may not be OK. Just assume it is */
+ return PACKET_OK;
+ }
+ else
+ {
+ /* The stub does not support the packet. */
+ switch (config->support)
+ {
+ case PACKET_ENABLE:
+ if (config->detect == CMD_AUTO_BOOLEAN_AUTO)
+ /* If the stub previously indicated that the packet was
+ supported then there is a protocol error.. */
+ error ("Protocol error: %s (%s) conflicting enabled responses.",
+ config->name, config->title);
+ else
+ /* The user set it wrong. */
+ error ("Enabled packet %s (%s) not recognized by stub",
+ config->name, config->title);
+ break;
+ case PACKET_SUPPORT_UNKNOWN:
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "Packet %s (%s) is NOT supported\n",
+ config->name, config->title);
+ config->support = PACKET_DISABLE;
+ break;
+ case PACKET_DISABLE:
+ break;
+ }
+ return PACKET_UNKNOWN;
+ }
+}
+
+/* Should we try the 'qSymbol' (target symbol lookup service) request? */
+static struct packet_config remote_protocol_qSymbol;
+
+static void
+set_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_qSymbol);
+}
+
+static void
+show_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty)
+{
+ show_packet_config_cmd (&remote_protocol_qSymbol);
+}
+
+/* Should we try the 'e' (step over range) request? */
+static struct packet_config remote_protocol_e;
+
+static void
+set_remote_protocol_e_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_e);
+}
+
+static void
+show_remote_protocol_e_packet_cmd (char *args, int from_tty)
+{
+ show_packet_config_cmd (&remote_protocol_e);
+}
+
+
+/* Should we try the 'E' (step over range / w signal #) request? */
+static struct packet_config remote_protocol_E;
+
+static void
+set_remote_protocol_E_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_E);
+}
+
+static void
+show_remote_protocol_E_packet_cmd (char *args, int from_tty)
+{
+ show_packet_config_cmd (&remote_protocol_E);
+}
+
+
+/* Should we try the 'P' (set register) request? */
+
+static struct packet_config remote_protocol_P;
+
+static void
+set_remote_protocol_P_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_P);
+}
+
+static void
+show_remote_protocol_P_packet_cmd (char *args, int from_tty)
+{
+ show_packet_config_cmd (&remote_protocol_P);
+}
+
+/* Should we try one of the 'Z' requests? */
+
+enum Z_packet_type
+{
+ Z_PACKET_SOFTWARE_BP,
+ Z_PACKET_HARDWARE_BP,
+ Z_PACKET_WRITE_WP,
+ Z_PACKET_READ_WP,
+ Z_PACKET_ACCESS_WP,
+ NR_Z_PACKET_TYPES
+};
+
+static struct packet_config remote_protocol_Z[NR_Z_PACKET_TYPES];
+
+/* FIXME: Instead of having all these boiler plate functions, the
+ command callback should include a context argument. */
+
+static void
+set_remote_protocol_Z_software_bp_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_Z[Z_PACKET_SOFTWARE_BP]);
+}
+
+static void
+show_remote_protocol_Z_software_bp_packet_cmd (char *args, int from_tty)
+{
+ show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_SOFTWARE_BP]);
+}
+
+static void
+set_remote_protocol_Z_hardware_bp_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_Z[Z_PACKET_HARDWARE_BP]);
+}
+
+static void
+show_remote_protocol_Z_hardware_bp_packet_cmd (char *args, int from_tty)
+{
+ show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_HARDWARE_BP]);
+}
+
+static void
+set_remote_protocol_Z_write_wp_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_Z[Z_PACKET_WRITE_WP]);
+}
+
+static void
+show_remote_protocol_Z_write_wp_packet_cmd (char *args, int from_tty)
+{
+ show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_WRITE_WP]);
+}
+
+static void
+set_remote_protocol_Z_read_wp_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_Z[Z_PACKET_READ_WP]);
+}
+
+static void
+show_remote_protocol_Z_read_wp_packet_cmd (char *args, int from_tty)
+{
+ show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_READ_WP]);
+}
+
+static void
+set_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_Z[Z_PACKET_ACCESS_WP]);
+}
+
+static void
+show_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty)
+{
+ show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_ACCESS_WP]);
+}
+
+/* For compatibility with older distributions. Provide a ``set remote
+ Z-packet ...'' command that updates all the Z packet types. */
+
+static enum cmd_auto_boolean remote_Z_packet_detect;
+
+static void
+set_remote_protocol_Z_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ int i;
+ for (i = 0; i < NR_Z_PACKET_TYPES; i++)
+ {
+ remote_protocol_Z[i].detect = remote_Z_packet_detect;
+ update_packet_config (&remote_protocol_Z[i]);
+ }
+}
+
+static void
+show_remote_protocol_Z_packet_cmd (char *args, int from_tty)
+{
+ int i;
+ for (i = 0; i < NR_Z_PACKET_TYPES; i++)
+ {
+ show_packet_config_cmd (&remote_protocol_Z[i]);
+ }
+}
+
+/* Should we try the 'X' (remote binary download) packet?
+
+ This variable (available to the user via "set remote X-packet")
+ dictates whether downloads are sent in binary (via the 'X' packet).
+ We assume that the stub can, and attempt to do it. This will be
+ cleared if the stub does not understand it. This switch is still
+ needed, though in cases when the packet is supported in the stub,
+ but the connection does not allow it (i.e., 7-bit serial connection
+ only). */
+
+static struct packet_config remote_protocol_binary_download;
+
+/* Should we try the 'ThreadInfo' query packet?
+
+ This variable (NOT available to the user: auto-detect only!)
+ determines whether GDB will use the new, simpler "ThreadInfo"
+ query or the older, more complex syntax for thread queries.
+ This is an auto-detect variable (set to true at each connect,
+ and set to false when the target fails to recognize it). */
+
+static int use_threadinfo_query;
+static int use_threadextra_query;
+
+static void
+set_remote_protocol_binary_download_cmd (char *args,
+ int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_binary_download);
+}
+
+static void
+show_remote_protocol_binary_download_cmd (char *args,
+ int from_tty)
+{
+ show_packet_config_cmd (&remote_protocol_binary_download);
+}
+
+
+/* Tokens for use by the asynchronous signal handlers for SIGINT */
+static void *sigint_remote_twice_token;
+static void *sigint_remote_token;
+
+/* These are pointers to hook functions that may be set in order to
+ modify resume/wait behavior for a particular architecture. */
+
+void (*target_resume_hook) (void);
+void (*target_wait_loop_hook) (void);
+
+
+
+/* These are the threads which we last sent to the remote system.
+ -1 for all or -2 for not sent yet. */
+static int general_thread;
+static int continue_thread;
+
+/* Call this function as a result of
+ 1) A halt indication (T packet) containing a thread id
+ 2) A direct query of currthread
+ 3) Successful execution of set thread
+ */
+
+static void
+record_currthread (int currthread)
+{
+ general_thread = currthread;
+
+ /* If this is a new thread, add it to GDB's thread list.
+ If we leave it up to WFI to do this, bad things will happen. */
+ if (!in_thread_list (pid_to_ptid (currthread)))
+ {
+ add_thread (pid_to_ptid (currthread));
+ ui_out_text (uiout, "[New ");
+ ui_out_text (uiout, target_pid_to_str (pid_to_ptid (currthread)));
+ ui_out_text (uiout, "]\n");
+ }
+}
+
+#define MAGIC_NULL_PID 42000
+
+static void
+set_thread (int th, int gen)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+ int state = gen ? general_thread : continue_thread;
+
+ if (state == th)
+ return;
+
+ buf[0] = 'H';
+ buf[1] = gen ? 'g' : 'c';
+ if (th == MAGIC_NULL_PID)
+ {
+ buf[2] = '0';
+ buf[3] = '\0';
+ }
+ else if (th < 0)
+ sprintf (&buf[2], "-%x", -th);
+ else
+ sprintf (&buf[2], "%x", th);
+ putpkt (buf);
+ getpkt (buf, (rs->remote_packet_size), 0);
+ if (gen)
+ general_thread = th;
+ else
+ continue_thread = th;
+}
+
+/* Return nonzero if the thread TH is still alive on the remote system. */
+
+static int
+remote_thread_alive (ptid_t ptid)
+{
+ int tid = PIDGET (ptid);
+ char buf[16];
+
+ if (tid < 0)
+ sprintf (buf, "T-%08x", -tid);
+ else
+ sprintf (buf, "T%08x", tid);
+ putpkt (buf);
+ getpkt (buf, sizeof (buf), 0);
+ return (buf[0] == 'O' && buf[1] == 'K');
+}
+
+/* About these extended threadlist and threadinfo packets. They are
+ variable length packets but, the fields within them are often fixed
+ length. They are redundent enough to send over UDP as is the
+ remote protocol in general. There is a matching unit test module
+ in libstub. */
+
+#define OPAQUETHREADBYTES 8
+
+/* a 64 bit opaque identifier */
+typedef unsigned char threadref[OPAQUETHREADBYTES];
+
+/* WARNING: This threadref data structure comes from the remote O.S., libstub
+ protocol encoding, and remote.c. it is not particularly changable */
+
+/* Right now, the internal structure is int. We want it to be bigger.
+ Plan to fix this.
+ */
+
+typedef int gdb_threadref; /* internal GDB thread reference */
+
+/* gdb_ext_thread_info is an internal GDB data structure which is
+ equivalint to the reply of the remote threadinfo packet */
+
+struct gdb_ext_thread_info
+ {
+ threadref threadid; /* External form of thread reference */
+ int active; /* Has state interesting to GDB? , regs, stack */
+ char display[256]; /* Brief state display, name, blocked/syspended */
+ char shortname[32]; /* To be used to name threads */
+ char more_display[256]; /* Long info, statistics, queue depth, whatever */
+ };
+
+/* The volume of remote transfers can be limited by submitting
+ a mask containing bits specifying the desired information.
+ Use a union of these values as the 'selection' parameter to
+ get_thread_info. FIXME: Make these TAG names more thread specific.
+ */
+
+#define TAG_THREADID 1
+#define TAG_EXISTS 2
+#define TAG_DISPLAY 4
+#define TAG_THREADNAME 8
+#define TAG_MOREDISPLAY 16
+
+#define BUF_THREAD_ID_SIZE (OPAQUETHREADBYTES*2)
+
+char *unpack_varlen_hex (char *buff, int *result);
+
+static char *unpack_nibble (char *buf, int *val);
+
+static char *pack_nibble (char *buf, int nibble);
+
+static char *pack_hex_byte (char *pkt, int /*unsigned char */ byte);
+
+static char *unpack_byte (char *buf, int *value);
+
+static char *pack_int (char *buf, int value);
+
+static char *unpack_int (char *buf, int *value);
+
+static char *unpack_string (char *src, char *dest, int length);
+
+static char *pack_threadid (char *pkt, threadref * id);
+
+static char *unpack_threadid (char *inbuf, threadref * id);
+
+void int_to_threadref (threadref * id, int value);
+
+static int threadref_to_int (threadref * ref);
+
+static void copy_threadref (threadref * dest, threadref * src);
+
+static int threadmatch (threadref * dest, threadref * src);
+
+static char *pack_threadinfo_request (char *pkt, int mode, threadref * id);
+
+static int remote_unpack_thread_info_response (char *pkt,
+ threadref * expectedref,
+ struct gdb_ext_thread_info
+ *info);
+
+
+static int remote_get_threadinfo (threadref * threadid, int fieldset, /*TAG mask */
+ struct gdb_ext_thread_info *info);
+
+static int adapt_remote_get_threadinfo (gdb_threadref * ref,
+ int selection,
+ struct gdb_ext_thread_info *info);
+
+static char *pack_threadlist_request (char *pkt, int startflag,
+ int threadcount,
+ threadref * nextthread);
+
+static int parse_threadlist_response (char *pkt,
+ int result_limit,
+ threadref * original_echo,
+ threadref * resultlist, int *doneflag);
+
+static int remote_get_threadlist (int startflag,
+ threadref * nextthread,
+ int result_limit,
+ int *done,
+ int *result_count, threadref * threadlist);
+
+typedef int (*rmt_thread_action) (threadref * ref, void *context);
+
+static int remote_threadlist_iterator (rmt_thread_action stepfunction,
+ void *context, int looplimit);
+
+static int remote_newthread_step (threadref * ref, void *context);
+
+/* encode 64 bits in 16 chars of hex */
+
+static const char hexchars[] = "0123456789abcdef";
+
+static int
+ishex (int ch, int *val)
+{
+ if ((ch >= 'a') && (ch <= 'f'))
+ {
+ *val = ch - 'a' + 10;
+ return 1;
+ }
+ if ((ch >= 'A') && (ch <= 'F'))
+ {
+ *val = ch - 'A' + 10;
+ return 1;
+ }
+ if ((ch >= '0') && (ch <= '9'))
+ {
+ *val = ch - '0';
+ return 1;
+ }
+ return 0;
+}
+
+static int
+stubhex (int ch)
+{
+ if (ch >= 'a' && ch <= 'f')
+ return ch - 'a' + 10;
+ if (ch >= '0' && ch <= '9')
+ return ch - '0';
+ if (ch >= 'A' && ch <= 'F')
+ return ch - 'A' + 10;
+ return -1;
+}
+
+static int
+stub_unpack_int (char *buff, int fieldlength)
+{
+ int nibble;
+ int retval = 0;
+
+ while (fieldlength)
+ {
+ nibble = stubhex (*buff++);
+ retval |= nibble;
+ fieldlength--;
+ if (fieldlength)
+ retval = retval << 4;
+ }
+ return retval;
+}
+
+char *
+unpack_varlen_hex (char *buff, /* packet to parse */
+ int *result)
+{
+ int nibble;
+ int retval = 0;
+
+ while (ishex (*buff, &nibble))
+ {
+ buff++;
+ retval = retval << 4;
+ retval |= nibble & 0x0f;
+ }
+ *result = retval;
+ return buff;
+}
+
+static char *
+unpack_nibble (char *buf, int *val)
+{
+ ishex (*buf++, val);
+ return buf;
+}
+
+static char *
+pack_nibble (char *buf, int nibble)
+{
+ *buf++ = hexchars[(nibble & 0x0f)];
+ return buf;
+}
+
+static char *
+pack_hex_byte (char *pkt, int byte)
+{
+ *pkt++ = hexchars[(byte >> 4) & 0xf];
+ *pkt++ = hexchars[(byte & 0xf)];
+ return pkt;
+}
+
+static char *
+unpack_byte (char *buf, int *value)
+{
+ *value = stub_unpack_int (buf, 2);
+ return buf + 2;
+}
+
+static char *
+pack_int (char *buf, int value)
+{
+ buf = pack_hex_byte (buf, (value >> 24) & 0xff);
+ buf = pack_hex_byte (buf, (value >> 16) & 0xff);
+ buf = pack_hex_byte (buf, (value >> 8) & 0x0ff);
+ buf = pack_hex_byte (buf, (value & 0xff));
+ return buf;
+}
+
+static char *
+unpack_int (char *buf, int *value)
+{
+ *value = stub_unpack_int (buf, 8);
+ return buf + 8;
+}
+
+#if 0 /* currently unused, uncomment when needed */
+static char *pack_string (char *pkt, char *string);
+
+static char *
+pack_string (char *pkt, char *string)
+{
+ char ch;
+ int len;
+
+ len = strlen (string);
+ if (len > 200)
+ len = 200; /* Bigger than most GDB packets, junk??? */
+ pkt = pack_hex_byte (pkt, len);
+ while (len-- > 0)
+ {
+ ch = *string++;
+ if ((ch == '\0') || (ch == '#'))
+ ch = '*'; /* Protect encapsulation */
+ *pkt++ = ch;
+ }
+ return pkt;
+}
+#endif /* 0 (unused) */
+
+static char *
+unpack_string (char *src, char *dest, int length)
+{
+ while (length--)
+ *dest++ = *src++;
+ *dest = '\0';
+ return src;
+}
+
+static char *
+pack_threadid (char *pkt, threadref *id)
+{
+ char *limit;
+ unsigned char *altid;
+
+ altid = (unsigned char *) id;
+ limit = pkt + BUF_THREAD_ID_SIZE;
+ while (pkt < limit)
+ pkt = pack_hex_byte (pkt, *altid++);
+ return pkt;
+}
+
+
+static char *
+unpack_threadid (char *inbuf, threadref *id)
+{
+ char *altref;
+ char *limit = inbuf + BUF_THREAD_ID_SIZE;
+ int x, y;
+
+ altref = (char *) id;
+
+ while (inbuf < limit)
+ {
+ x = stubhex (*inbuf++);
+ y = stubhex (*inbuf++);
+ *altref++ = (x << 4) | y;
+ }
+ return inbuf;
+}
+
+/* Externally, threadrefs are 64 bits but internally, they are still
+ ints. This is due to a mismatch of specifications. We would like
+ to use 64bit thread references internally. This is an adapter
+ function. */
+
+void
+int_to_threadref (threadref *id, int value)
+{
+ unsigned char *scan;
+
+ scan = (unsigned char *) id;
+ {
+ int i = 4;
+ while (i--)
+ *scan++ = 0;
+ }
+ *scan++ = (value >> 24) & 0xff;
+ *scan++ = (value >> 16) & 0xff;
+ *scan++ = (value >> 8) & 0xff;
+ *scan++ = (value & 0xff);
+}
+
+static int
+threadref_to_int (threadref *ref)
+{
+ int i, value = 0;
+ unsigned char *scan;
+
+ scan = (char *) ref;
+ scan += 4;
+ i = 4;
+ while (i-- > 0)
+ value = (value << 8) | ((*scan++) & 0xff);
+ return value;
+}
+
+static void
+copy_threadref (threadref *dest, threadref *src)
+{
+ int i;
+ unsigned char *csrc, *cdest;
+
+ csrc = (unsigned char *) src;
+ cdest = (unsigned char *) dest;
+ i = 8;
+ while (i--)
+ *cdest++ = *csrc++;
+}
+
+static int
+threadmatch (threadref *dest, threadref *src)
+{
+ /* things are broken right now, so just assume we got a match */
+#if 0
+ unsigned char *srcp, *destp;
+ int i, result;
+ srcp = (char *) src;
+ destp = (char *) dest;
+
+ result = 1;
+ while (i-- > 0)
+ result &= (*srcp++ == *destp++) ? 1 : 0;
+ return result;
+#endif
+ return 1;
+}
+
+/*
+ threadid:1, # always request threadid
+ context_exists:2,
+ display:4,
+ unique_name:8,
+ more_display:16
+ */
+
+/* Encoding: 'Q':8,'P':8,mask:32,threadid:64 */
+
+static char *
+pack_threadinfo_request (char *pkt, int mode, threadref *id)
+{
+ *pkt++ = 'q'; /* Info Query */
+ *pkt++ = 'P'; /* process or thread info */
+ pkt = pack_int (pkt, mode); /* mode */
+ pkt = pack_threadid (pkt, id); /* threadid */
+ *pkt = '\0'; /* terminate */
+ return pkt;
+}
+
+/* These values tag the fields in a thread info response packet */
+/* Tagging the fields allows us to request specific fields and to
+ add more fields as time goes by */
+
+#define TAG_THREADID 1 /* Echo the thread identifier */
+#define TAG_EXISTS 2 /* Is this process defined enough to
+ fetch registers and its stack */
+#define TAG_DISPLAY 4 /* A short thing maybe to put on a window */
+#define TAG_THREADNAME 8 /* string, maps 1-to-1 with a thread is */
+#define TAG_MOREDISPLAY 16 /* Whatever the kernel wants to say about
+ the process */
+
+static int
+remote_unpack_thread_info_response (char *pkt, threadref *expectedref,
+ struct gdb_ext_thread_info *info)
+{
+ struct remote_state *rs = get_remote_state ();
+ int mask, length;
+ unsigned int tag;
+ threadref ref;
+ char *limit = pkt + (rs->remote_packet_size); /* plausable parsing limit */
+ int retval = 1;
+
+ /* info->threadid = 0; FIXME: implement zero_threadref */
+ info->active = 0;
+ info->display[0] = '\0';
+ info->shortname[0] = '\0';
+ info->more_display[0] = '\0';
+
+ /* Assume the characters indicating the packet type have been stripped */
+ pkt = unpack_int (pkt, &mask); /* arg mask */
+ pkt = unpack_threadid (pkt, &ref);
+
+ if (mask == 0)
+ warning ("Incomplete response to threadinfo request\n");
+ if (!threadmatch (&ref, expectedref))
+ { /* This is an answer to a different request */
+ warning ("ERROR RMT Thread info mismatch\n");
+ return 0;
+ }
+ copy_threadref (&info->threadid, &ref);
+
+ /* Loop on tagged fields , try to bail if somthing goes wrong */
+
+ while ((pkt < limit) && mask && *pkt) /* packets are terminated with nulls */
+ {
+ pkt = unpack_int (pkt, &tag); /* tag */
+ pkt = unpack_byte (pkt, &length); /* length */
+ if (!(tag & mask)) /* tags out of synch with mask */
+ {
+ warning ("ERROR RMT: threadinfo tag mismatch\n");
+ retval = 0;
+ break;
+ }
+ if (tag == TAG_THREADID)
+ {
+ if (length != 16)
+ {
+ warning ("ERROR RMT: length of threadid is not 16\n");
+ retval = 0;
+ break;
+ }
+ pkt = unpack_threadid (pkt, &ref);
+ mask = mask & ~TAG_THREADID;
+ continue;
+ }
+ if (tag == TAG_EXISTS)
+ {
+ info->active = stub_unpack_int (pkt, length);
+ pkt += length;
+ mask = mask & ~(TAG_EXISTS);
+ if (length > 8)
+ {
+ warning ("ERROR RMT: 'exists' length too long\n");
+ retval = 0;
+ break;
+ }
+ continue;
+ }
+ if (tag == TAG_THREADNAME)
+ {
+ pkt = unpack_string (pkt, &info->shortname[0], length);
+ mask = mask & ~TAG_THREADNAME;
+ continue;
+ }
+ if (tag == TAG_DISPLAY)
+ {
+ pkt = unpack_string (pkt, &info->display[0], length);
+ mask = mask & ~TAG_DISPLAY;
+ continue;
+ }
+ if (tag == TAG_MOREDISPLAY)
+ {
+ pkt = unpack_string (pkt, &info->more_display[0], length);
+ mask = mask & ~TAG_MOREDISPLAY;
+ continue;
+ }
+ warning ("ERROR RMT: unknown thread info tag\n");
+ break; /* Not a tag we know about */
+ }
+ return retval;
+}
+
+static int
+remote_get_threadinfo (threadref *threadid, int fieldset, /* TAG mask */
+ struct gdb_ext_thread_info *info)
+{
+ struct remote_state *rs = get_remote_state ();
+ int result;
+ char *threadinfo_pkt = alloca (rs->remote_packet_size);
+
+ pack_threadinfo_request (threadinfo_pkt, fieldset, threadid);
+ putpkt (threadinfo_pkt);
+ getpkt (threadinfo_pkt, (rs->remote_packet_size), 0);
+ result = remote_unpack_thread_info_response (threadinfo_pkt + 2, threadid,
+ info);
+ return result;
+}
+
+/* Unfortunately, 61 bit thread-ids are bigger than the internal
+ representation of a threadid. */
+
+static int
+adapt_remote_get_threadinfo (gdb_threadref *ref, int selection,
+ struct gdb_ext_thread_info *info)
+{
+ threadref lclref;
+
+ int_to_threadref (&lclref, *ref);
+ return remote_get_threadinfo (&lclref, selection, info);
+}
+
+/* Format: i'Q':8,i"L":8,initflag:8,batchsize:16,lastthreadid:32 */
+
+static char *
+pack_threadlist_request (char *pkt, int startflag, int threadcount,
+ threadref *nextthread)
+{
+ *pkt++ = 'q'; /* info query packet */
+ *pkt++ = 'L'; /* Process LIST or threadLIST request */
+ pkt = pack_nibble (pkt, startflag); /* initflag 1 bytes */
+ pkt = pack_hex_byte (pkt, threadcount); /* threadcount 2 bytes */
+ pkt = pack_threadid (pkt, nextthread); /* 64 bit thread identifier */
+ *pkt = '\0';
+ return pkt;
+}
+
+/* Encoding: 'q':8,'M':8,count:16,done:8,argthreadid:64,(threadid:64)* */
+
+static int
+parse_threadlist_response (char *pkt, int result_limit,
+ threadref *original_echo, threadref *resultlist,
+ int *doneflag)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *limit;
+ int count, resultcount, done;
+
+ resultcount = 0;
+ /* Assume the 'q' and 'M chars have been stripped. */
+ limit = pkt + ((rs->remote_packet_size) - BUF_THREAD_ID_SIZE); /* done parse past here */
+ pkt = unpack_byte (pkt, &count); /* count field */
+ pkt = unpack_nibble (pkt, &done);
+ /* The first threadid is the argument threadid. */
+ pkt = unpack_threadid (pkt, original_echo); /* should match query packet */
+ while ((count-- > 0) && (pkt < limit))
+ {
+ pkt = unpack_threadid (pkt, resultlist++);
+ if (resultcount++ >= result_limit)
+ break;
+ }
+ if (doneflag)
+ *doneflag = done;
+ return resultcount;
+}
+
+static int
+remote_get_threadlist (int startflag, threadref *nextthread, int result_limit,
+ int *done, int *result_count, threadref *threadlist)
+{
+ struct remote_state *rs = get_remote_state ();
+ static threadref echo_nextthread;
+ char *threadlist_packet = alloca (rs->remote_packet_size);
+ char *t_response = alloca (rs->remote_packet_size);
+ int result = 1;
+
+ /* Trancate result limit to be smaller than the packet size */
+ if ((((result_limit + 1) * BUF_THREAD_ID_SIZE) + 10) >= (rs->remote_packet_size))
+ result_limit = ((rs->remote_packet_size) / BUF_THREAD_ID_SIZE) - 2;
+
+ pack_threadlist_request (threadlist_packet,
+ startflag, result_limit, nextthread);
+ putpkt (threadlist_packet);
+ getpkt (t_response, (rs->remote_packet_size), 0);
+
+ *result_count =
+ parse_threadlist_response (t_response + 2, result_limit, &echo_nextthread,
+ threadlist, done);
+
+ if (!threadmatch (&echo_nextthread, nextthread))
+ {
+ /* FIXME: This is a good reason to drop the packet */
+ /* Possably, there is a duplicate response */
+ /* Possabilities :
+ retransmit immediatly - race conditions
+ retransmit after timeout - yes
+ exit
+ wait for packet, then exit
+ */
+ warning ("HMM: threadlist did not echo arg thread, dropping it\n");
+ return 0; /* I choose simply exiting */
+ }
+ if (*result_count <= 0)
+ {
+ if (*done != 1)
+ {
+ warning ("RMT ERROR : failed to get remote thread list\n");
+ result = 0;
+ }
+ return result; /* break; */
+ }
+ if (*result_count > result_limit)
+ {
+ *result_count = 0;
+ warning ("RMT ERROR: threadlist response longer than requested\n");
+ return 0;
+ }
+ return result;
+}
+
+/* This is the interface between remote and threads, remotes upper interface */
+
+/* remote_find_new_threads retrieves the thread list and for each
+ thread in the list, looks up the thread in GDB's internal list,
+ ading the thread if it does not already exist. This involves
+ getting partial thread lists from the remote target so, polling the
+ quit_flag is required. */
+
+
+/* About this many threadisds fit in a packet. */
+
+#define MAXTHREADLISTRESULTS 32
+
+static int
+remote_threadlist_iterator (rmt_thread_action stepfunction, void *context,
+ int looplimit)
+{
+ int done, i, result_count;
+ int startflag = 1;
+ int result = 1;
+ int loopcount = 0;
+ static threadref nextthread;
+ static threadref resultthreadlist[MAXTHREADLISTRESULTS];
+
+ done = 0;
+ while (!done)
+ {
+ if (loopcount++ > looplimit)
+ {
+ result = 0;
+ warning ("Remote fetch threadlist -infinite loop-\n");
+ break;
+ }
+ if (!remote_get_threadlist (startflag, &nextthread, MAXTHREADLISTRESULTS,
+ &done, &result_count, resultthreadlist))
+ {
+ result = 0;
+ break;
+ }
+ /* clear for later iterations */
+ startflag = 0;
+ /* Setup to resume next batch of thread references, set nextthread. */
+ if (result_count >= 1)
+ copy_threadref (&nextthread, &resultthreadlist[result_count - 1]);
+ i = 0;
+ while (result_count--)
+ if (!(result = (*stepfunction) (&resultthreadlist[i++], context)))
+ break;
+ }
+ return result;
+}
+
+static int
+remote_newthread_step (threadref *ref, void *context)
+{
+ ptid_t ptid;
+
+ ptid = pid_to_ptid (threadref_to_int (ref));
+
+ if (!in_thread_list (ptid))
+ add_thread (ptid);
+ return 1; /* continue iterator */
+}
+
+#define CRAZY_MAX_THREADS 1000
+
+static ptid_t
+remote_current_thread (ptid_t oldpid)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+
+ putpkt ("qC");
+ getpkt (buf, (rs->remote_packet_size), 0);
+ if (buf[0] == 'Q' && buf[1] == 'C')
+ return pid_to_ptid (strtol (&buf[2], NULL, 16));
+ else
+ return oldpid;
+}
+
+/* Find new threads for info threads command.
+ * Original version, using John Metzler's thread protocol.
+ */
+
+static void
+remote_find_new_threads (void)
+{
+ remote_threadlist_iterator (remote_newthread_step, 0,
+ CRAZY_MAX_THREADS);
+ if (PIDGET (inferior_ptid) == MAGIC_NULL_PID) /* ack ack ack */
+ inferior_ptid = remote_current_thread (inferior_ptid);
+}
+
+/*
+ * Find all threads for info threads command.
+ * Uses new thread protocol contributed by Cisco.
+ * Falls back and attempts to use the older method (above)
+ * if the target doesn't respond to the new method.
+ */
+
+static void
+remote_threads_info (void)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+ char *bufp;
+ int tid;
+
+ if (remote_desc == 0) /* paranoia */
+ error ("Command can only be used when connected to the remote target.");
+
+ if (use_threadinfo_query)
+ {
+ putpkt ("qfThreadInfo");
+ bufp = buf;
+ getpkt (bufp, (rs->remote_packet_size), 0);
+ if (bufp[0] != '\0') /* q packet recognized */
+ {
+ while (*bufp++ == 'm') /* reply contains one or more TID */
+ {
+ do
+ {
+ tid = strtol (bufp, &bufp, 16);
+ if (tid != 0 && !in_thread_list (pid_to_ptid (tid)))
+ add_thread (pid_to_ptid (tid));
+ }
+ while (*bufp++ == ','); /* comma-separated list */
+ putpkt ("qsThreadInfo");
+ bufp = buf;
+ getpkt (bufp, (rs->remote_packet_size), 0);
+ }
+ return; /* done */
+ }
+ }
+
+ /* Else fall back to old method based on jmetzler protocol. */
+ use_threadinfo_query = 0;
+ remote_find_new_threads ();
+ return;
+}
+
+/*
+ * Collect a descriptive string about the given thread.
+ * The target may say anything it wants to about the thread
+ * (typically info about its blocked / runnable state, name, etc.).
+ * This string will appear in the info threads display.
+ *
+ * Optional: targets are not required to implement this function.
+ */
+
+static char *
+remote_threads_extra_info (struct thread_info *tp)
+{
+ struct remote_state *rs = get_remote_state ();
+ int result;
+ int set;
+ threadref id;
+ struct gdb_ext_thread_info threadinfo;
+ static char display_buf[100]; /* arbitrary... */
+ char *bufp = alloca (rs->remote_packet_size);
+ int n = 0; /* position in display_buf */
+
+ if (remote_desc == 0) /* paranoia */
+ internal_error (__FILE__, __LINE__,
+ "remote_threads_extra_info");
+
+ if (use_threadextra_query)
+ {
+ sprintf (bufp, "qThreadExtraInfo,%x", PIDGET (tp->ptid));
+ putpkt (bufp);
+ getpkt (bufp, (rs->remote_packet_size), 0);
+ if (bufp[0] != 0)
+ {
+ n = min (strlen (bufp) / 2, sizeof (display_buf));
+ result = hex2bin (bufp, display_buf, n);
+ display_buf [result] = '\0';
+ return display_buf;
+ }
+ }
+
+ /* If the above query fails, fall back to the old method. */
+ use_threadextra_query = 0;
+ set = TAG_THREADID | TAG_EXISTS | TAG_THREADNAME
+ | TAG_MOREDISPLAY | TAG_DISPLAY;
+ int_to_threadref (&id, PIDGET (tp->ptid));
+ if (remote_get_threadinfo (&id, set, &threadinfo))
+ if (threadinfo.active)
+ {
+ if (*threadinfo.shortname)
+ n += sprintf(&display_buf[0], " Name: %s,", threadinfo.shortname);
+ if (*threadinfo.display)
+ n += sprintf(&display_buf[n], " State: %s,", threadinfo.display);
+ if (*threadinfo.more_display)
+ n += sprintf(&display_buf[n], " Priority: %s",
+ threadinfo.more_display);
+
+ if (n > 0)
+ {
+ /* for purely cosmetic reasons, clear up trailing commas */
+ if (',' == display_buf[n-1])
+ display_buf[n-1] = ' ';
+ return display_buf;
+ }
+ }
+ return NULL;
+}
+
+
+
+/* Restart the remote side; this is an extended protocol operation. */
+
+static void
+extended_remote_restart (void)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+
+ /* Send the restart command; for reasons I don't understand the
+ remote side really expects a number after the "R". */
+ buf[0] = 'R';
+ sprintf (&buf[1], "%x", 0);
+ putpkt (buf);
+
+ /* Now query for status so this looks just like we restarted
+ gdbserver from scratch. */
+ putpkt ("?");
+ getpkt (buf, (rs->remote_packet_size), 0);
+}
+
+/* Clean up connection to a remote debugger. */
+
+/* ARGSUSED */
+static void
+remote_close (int quitting)
+{
+ if (remote_desc)
+ serial_close (remote_desc);
+ remote_desc = NULL;
+}
+
+/* Query the remote side for the text, data and bss offsets. */
+
+static void
+get_offsets (void)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+ char *ptr;
+ int lose;
+ CORE_ADDR text_addr, data_addr, bss_addr;
+ struct section_offsets *offs;
+
+ putpkt ("qOffsets");
+
+ getpkt (buf, (rs->remote_packet_size), 0);
+
+ if (buf[0] == '\000')
+ return; /* Return silently. Stub doesn't support
+ this command. */
+ if (buf[0] == 'E')
+ {
+ warning ("Remote failure reply: %s", buf);
+ return;
+ }
+
+ /* Pick up each field in turn. This used to be done with scanf, but
+ scanf will make trouble if CORE_ADDR size doesn't match
+ conversion directives correctly. The following code will work
+ with any size of CORE_ADDR. */
+ text_addr = data_addr = bss_addr = 0;
+ ptr = buf;
+ lose = 0;
+
+ if (strncmp (ptr, "Text=", 5) == 0)
+ {
+ ptr += 5;
+ /* Don't use strtol, could lose on big values. */
+ while (*ptr && *ptr != ';')
+ text_addr = (text_addr << 4) + fromhex (*ptr++);
+ }
+ else
+ lose = 1;
+
+ if (!lose && strncmp (ptr, ";Data=", 6) == 0)
+ {
+ ptr += 6;
+ while (*ptr && *ptr != ';')
+ data_addr = (data_addr << 4) + fromhex (*ptr++);
+ }
+ else
+ lose = 1;
+
+ if (!lose && strncmp (ptr, ";Bss=", 5) == 0)
+ {
+ ptr += 5;
+ while (*ptr && *ptr != ';')
+ bss_addr = (bss_addr << 4) + fromhex (*ptr++);
+ }
+ else
+ lose = 1;
+
+ if (lose)
+ error ("Malformed response to offset query, %s", buf);
+
+ if (symfile_objfile == NULL)
+ return;
+
+ offs = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
+ memcpy (offs, symfile_objfile->section_offsets, SIZEOF_SECTION_OFFSETS);
+
+ offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_addr;
+
+ /* This is a temporary kludge to force data and bss to use the same offsets
+ because that's what nlmconv does now. The real solution requires changes
+ to the stub and remote.c that I don't have time to do right now. */
+
+ offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_addr;
+ offs->offsets[SECT_OFF_BSS (symfile_objfile)] = data_addr;
+
+ objfile_relocate (symfile_objfile, offs);
+}
+
+/*
+ * Cisco version of section offsets:
+ *
+ * Instead of having GDB query the target for the section offsets,
+ * Cisco lets the target volunteer the information! It's also in
+ * a different format, so here are the functions that will decode
+ * a section offset packet from a Cisco target.
+ */
+
+/*
+ * Function: remote_cisco_section_offsets
+ *
+ * Returns: zero for success, non-zero for failure
+ */
+
+static int
+remote_cisco_section_offsets (bfd_vma text_addr,
+ bfd_vma data_addr,
+ bfd_vma bss_addr,
+ bfd_signed_vma *text_offs,
+ bfd_signed_vma *data_offs,
+ bfd_signed_vma *bss_offs)
+{
+ bfd_vma text_base, data_base, bss_base;
+ struct minimal_symbol *start;
+ asection *sect;
+ bfd *abfd;
+ int len;
+
+ if (symfile_objfile == NULL)
+ return -1; /* no can do nothin' */
+
+ start = lookup_minimal_symbol ("_start", NULL, NULL);
+ if (start == NULL)
+ return -1; /* Can't find "_start" symbol */
+
+ data_base = bss_base = 0;
+ text_base = SYMBOL_VALUE_ADDRESS (start);
+
+ abfd = symfile_objfile->obfd;
+ for (sect = abfd->sections;
+ sect != 0;
+ sect = sect->next)
+ {
+ const char *p = bfd_get_section_name (abfd, sect);
+ len = strlen (p);
+ if (strcmp (p + len - 4, "data") == 0) /* ends in "data" */
+ if (data_base == 0 ||
+ data_base > bfd_get_section_vma (abfd, sect))
+ data_base = bfd_get_section_vma (abfd, sect);
+ if (strcmp (p + len - 3, "bss") == 0) /* ends in "bss" */
+ if (bss_base == 0 ||
+ bss_base > bfd_get_section_vma (abfd, sect))
+ bss_base = bfd_get_section_vma (abfd, sect);
+ }
+ *text_offs = text_addr - text_base;
+ *data_offs = data_addr - data_base;
+ *bss_offs = bss_addr - bss_base;
+ if (remote_debug)
+ {
+ char tmp[128];
+
+ sprintf (tmp, "VMA: text = 0x");
+ sprintf_vma (tmp + strlen (tmp), text_addr);
+ sprintf (tmp + strlen (tmp), " data = 0x");
+ sprintf_vma (tmp + strlen (tmp), data_addr);
+ sprintf (tmp + strlen (tmp), " bss = 0x");
+ sprintf_vma (tmp + strlen (tmp), bss_addr);
+ fprintf_filtered (gdb_stdlog, tmp);
+ fprintf_filtered (gdb_stdlog,
+ "Reloc offset: text = 0x%s data = 0x%s bss = 0x%s\n",
+ paddr_nz (*text_offs),
+ paddr_nz (*data_offs),
+ paddr_nz (*bss_offs));
+ }
+
+ return 0;
+}
+
+/*
+ * Function: remote_cisco_objfile_relocate
+ *
+ * Relocate the symbol file for a remote target.
+ */
+
+void
+remote_cisco_objfile_relocate (bfd_signed_vma text_off, bfd_signed_vma data_off,
+ bfd_signed_vma bss_off)
+{
+ struct section_offsets *offs;
+
+ if (text_off != 0 || data_off != 0 || bss_off != 0)
+ {
+ /* FIXME: This code assumes gdb-stabs.h is being used; it's
+ broken for xcoff, dwarf, sdb-coff, etc. But there is no
+ simple canonical representation for this stuff. */
+
+ offs = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
+ memcpy (offs, symfile_objfile->section_offsets, SIZEOF_SECTION_OFFSETS);
+
+ offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_off;
+ offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_off;
+ offs->offsets[SECT_OFF_BSS (symfile_objfile)] = bss_off;
+
+ /* First call the standard objfile_relocate. */
+ objfile_relocate (symfile_objfile, offs);
+
+ /* Now we need to fix up the section entries already attached to
+ the exec target. These entries will control memory transfers
+ from the exec file. */
+
+ exec_set_section_offsets (text_off, data_off, bss_off);
+ }
+}
+
+/* Stub for catch_errors. */
+
+static int
+remote_start_remote_dummy (struct ui_out *uiout, void *dummy)
+{
+ start_remote (); /* Initialize gdb process mechanisms */
+ /* NOTE: Return something >=0. A -ve value is reserved for
+ catch_exceptions. */
+ return 1;
+}
+
+static int
+remote_start_remote (struct ui_out *uiout, void *dummy)
+{
+ immediate_quit++; /* Allow user to interrupt it */
+
+ /* Ack any packet which the remote side has already sent. */
+ serial_write (remote_desc, "+", 1);
+
+ /* Let the stub know that we want it to return the thread. */
+ set_thread (-1, 0);
+
+ inferior_ptid = remote_current_thread (inferior_ptid);
+
+ get_offsets (); /* Get text, data & bss offsets */
+
+ putpkt ("?"); /* initiate a query from remote machine */
+ immediate_quit--;
+
+ /* NOTE: See comment above in remote_start_remote_dummy(). This
+ function returns something >=0. */
+ return remote_start_remote_dummy (uiout, dummy);
+}
+
+/* Open a connection to a remote debugger.
+ NAME is the filename used for communication. */
+
+static void
+remote_open (char *name, int from_tty)
+{
+ remote_open_1 (name, from_tty, &remote_ops, 0);
+}
+
+/* Just like remote_open, but with asynchronous support. */
+static void
+remote_async_open (char *name, int from_tty)
+{
+ remote_async_open_1 (name, from_tty, &remote_async_ops, 0);
+}
+
+/* Open a connection to a remote debugger using the extended
+ remote gdb protocol. NAME is the filename used for communication. */
+
+static void
+extended_remote_open (char *name, int from_tty)
+{
+ remote_open_1 (name, from_tty, &extended_remote_ops, 1 /*extended_p */ );
+}
+
+/* Just like extended_remote_open, but with asynchronous support. */
+static void
+extended_remote_async_open (char *name, int from_tty)
+{
+ remote_async_open_1 (name, from_tty, &extended_async_remote_ops, 1 /*extended_p */ );
+}
+
+/* Generic code for opening a connection to a remote target. */
+
+static void
+init_all_packet_configs (void)
+{
+ int i;
+ update_packet_config (&remote_protocol_e);
+ update_packet_config (&remote_protocol_E);
+ update_packet_config (&remote_protocol_P);
+ update_packet_config (&remote_protocol_qSymbol);
+ for (i = 0; i < NR_Z_PACKET_TYPES; i++)
+ update_packet_config (&remote_protocol_Z[i]);
+ /* Force remote_write_bytes to check whether target supports binary
+ downloading. */
+ update_packet_config (&remote_protocol_binary_download);
+}
+
+/* Symbol look-up. */
+
+static void
+remote_check_symbols (struct objfile *objfile)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *msg, *reply, *tmp;
+ struct minimal_symbol *sym;
+ int end;
+
+ if (remote_protocol_qSymbol.support == PACKET_DISABLE)
+ return;
+
+ msg = alloca (rs->remote_packet_size);
+ reply = alloca (rs->remote_packet_size);
+
+ /* Invite target to request symbol lookups. */
+
+ putpkt ("qSymbol::");
+ getpkt (reply, (rs->remote_packet_size), 0);
+ packet_ok (reply, &remote_protocol_qSymbol);
+
+ while (strncmp (reply, "qSymbol:", 8) == 0)
+ {
+ tmp = &reply[8];
+ end = hex2bin (tmp, msg, strlen (tmp) / 2);
+ msg[end] = '\0';
+ sym = lookup_minimal_symbol (msg, NULL, NULL);
+ if (sym == NULL)
+ sprintf (msg, "qSymbol::%s", &reply[8]);
+ else
+ sprintf (msg, "qSymbol:%s:%s",
+ paddr_nz (SYMBOL_VALUE_ADDRESS (sym)),
+ &reply[8]);
+ putpkt (msg);
+ getpkt (reply, (rs->remote_packet_size), 0);
+ }
+}
+
+static struct serial *
+remote_serial_open (char *name)
+{
+ static int udp_warning = 0;
+
+ /* FIXME: Parsing NAME here is a hack. But we want to warn here instead
+ of in ser-tcp.c, because it is the remote protocol assuming that the
+ serial connection is reliable and not the serial connection promising
+ to be. */
+ if (!udp_warning && strncmp (name, "udp:", 4) == 0)
+ {
+ warning ("The remote protocol may be unreliable over UDP.");
+ warning ("Some events may be lost, rendering further debugging "
+ "impossible.");
+ udp_warning = 1;
+ }
+
+ return serial_open (name);
+}
+
+static void
+remote_open_1 (char *name, int from_tty, struct target_ops *target,
+ int extended_p)
+{
+ int ex;
+ struct remote_state *rs = get_remote_state ();
+ if (name == 0)
+ error ("To open a remote debug connection, you need to specify what\n"
+ "serial device is attached to the remote system\n"
+ "(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
+
+ /* See FIXME above */
+ wait_forever_enabled_p = 1;
+
+ target_preopen (from_tty);
+
+ unpush_target (target);
+
+ remote_desc = remote_serial_open (name);
+ if (!remote_desc)
+ perror_with_name (name);
+
+ if (baud_rate != -1)
+ {
+ if (serial_setbaudrate (remote_desc, baud_rate))
+ {
+ serial_close (remote_desc);
+ perror_with_name (name);
+ }
+ }
+
+ serial_raw (remote_desc);
+
+ /* If there is something sitting in the buffer we might take it as a
+ response to a command, which would be bad. */
+ serial_flush_input (remote_desc);
+
+ if (from_tty)
+ {
+ puts_filtered ("Remote debugging using ");
+ puts_filtered (name);
+ puts_filtered ("\n");
+ }
+ push_target (target); /* Switch to using remote target now */
+
+ init_all_packet_configs ();
+
+ general_thread = -2;
+ continue_thread = -2;
+
+ /* Probe for ability to use "ThreadInfo" query, as required. */
+ use_threadinfo_query = 1;
+ use_threadextra_query = 1;
+
+ /* Without this, some commands which require an active target (such
+ as kill) won't work. This variable serves (at least) double duty
+ as both the pid of the target process (if it has such), and as a
+ flag indicating that a target is active. These functions should
+ be split out into seperate variables, especially since GDB will
+ someday have a notion of debugging several processes. */
+
+ inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+ /* First delete any symbols previously loaded from shared libraries. */
+ no_shared_libraries (NULL, 0);
+#endif
+
+ /* Start the remote connection. If error() or QUIT, discard this
+ target (we'd otherwise be in an inconsistent state) and then
+ propogate the error on up the exception chain. This ensures that
+ the caller doesn't stumble along blindly assuming that the
+ function succeeded. The CLI doesn't have this problem but other
+ UI's, such as MI do.
+
+ FIXME: cagney/2002-05-19: Instead of re-throwing the exception,
+ this function should return an error indication letting the
+ caller restore the previous state. Unfortunatly the command
+ ``target remote'' is directly wired to this function making that
+ impossible. On a positive note, the CLI side of this problem has
+ been fixed - the function set_cmd_context() makes it possible for
+ all the ``target ....'' commands to share a common callback
+ function. See cli-dump.c. */
+ ex = catch_exceptions (uiout,
+ remote_start_remote, NULL,
+ "Couldn't establish connection to remote"
+ " target\n",
+ RETURN_MASK_ALL);
+ if (ex < 0)
+ {
+ pop_target ();
+ throw_exception (ex);
+ }
+
+ if (extended_p)
+ {
+ /* Tell the remote that we are using the extended protocol. */
+ char *buf = alloca (rs->remote_packet_size);
+ putpkt ("!");
+ getpkt (buf, (rs->remote_packet_size), 0);
+ }
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+ /* FIXME: need a master target_open vector from which all
+ remote_opens can be called, so that stuff like this can
+ go there. Failing that, the following code must be copied
+ to the open function for any remote target that wants to
+ support svr4 shared libraries. */
+
+ /* Set up to detect and load shared libraries. */
+ if (exec_bfd) /* No use without an exec file. */
+ {
+ SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
+ remote_check_symbols (symfile_objfile);
+ }
+#endif
+}
+
+/* Just like remote_open but with asynchronous support. */
+static void
+remote_async_open_1 (char *name, int from_tty, struct target_ops *target,
+ int extended_p)
+{
+ int ex;
+ struct remote_state *rs = get_remote_state ();
+ if (name == 0)
+ error ("To open a remote debug connection, you need to specify what\n"
+ "serial device is attached to the remote system\n"
+ "(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
+
+ target_preopen (from_tty);
+
+ unpush_target (target);
+
+ remote_desc = remote_serial_open (name);
+ if (!remote_desc)
+ perror_with_name (name);
+
+ if (baud_rate != -1)
+ {
+ if (serial_setbaudrate (remote_desc, baud_rate))
+ {
+ serial_close (remote_desc);
+ perror_with_name (name);
+ }
+ }
+
+ serial_raw (remote_desc);
+
+ /* If there is something sitting in the buffer we might take it as a
+ response to a command, which would be bad. */
+ serial_flush_input (remote_desc);
+
+ if (from_tty)
+ {
+ puts_filtered ("Remote debugging using ");
+ puts_filtered (name);
+ puts_filtered ("\n");
+ }
+
+ push_target (target); /* Switch to using remote target now */
+
+ init_all_packet_configs ();
+
+ general_thread = -2;
+ continue_thread = -2;
+
+ /* Probe for ability to use "ThreadInfo" query, as required. */
+ use_threadinfo_query = 1;
+ use_threadextra_query = 1;
+
+ /* Without this, some commands which require an active target (such
+ as kill) won't work. This variable serves (at least) double duty
+ as both the pid of the target process (if it has such), and as a
+ flag indicating that a target is active. These functions should
+ be split out into seperate variables, especially since GDB will
+ someday have a notion of debugging several processes. */
+ inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
+
+ /* With this target we start out by owning the terminal. */
+ remote_async_terminal_ours_p = 1;
+
+ /* FIXME: cagney/1999-09-23: During the initial connection it is
+ assumed that the target is already ready and able to respond to
+ requests. Unfortunately remote_start_remote() eventually calls
+ wait_for_inferior() with no timeout. wait_forever_enabled_p gets
+ around this. Eventually a mechanism that allows
+ wait_for_inferior() to expect/get timeouts will be
+ implemented. */
+ wait_forever_enabled_p = 0;
+
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+ /* First delete any symbols previously loaded from shared libraries. */
+ no_shared_libraries (NULL, 0);
+#endif
+
+ /* Start the remote connection; if error, discard this target. See
+ the comments in remote_open_1() for further details such as the
+ need to re-throw the exception. */
+ ex = catch_exceptions (uiout,
+ remote_start_remote, NULL,
+ "Couldn't establish connection to remote"
+ " target\n",
+ RETURN_MASK_ALL);
+ if (ex < 0)
+ {
+ pop_target ();
+ wait_forever_enabled_p = 1;
+ throw_exception (ex);
+ }
+
+ wait_forever_enabled_p = 1;
+
+ if (extended_p)
+ {
+ /* Tell the remote that we are using the extended protocol. */
+ char *buf = alloca (rs->remote_packet_size);
+ putpkt ("!");
+ getpkt (buf, (rs->remote_packet_size), 0);
+ }
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+ /* FIXME: need a master target_open vector from which all
+ remote_opens can be called, so that stuff like this can
+ go there. Failing that, the following code must be copied
+ to the open function for any remote target that wants to
+ support svr4 shared libraries. */
+
+ /* Set up to detect and load shared libraries. */
+ if (exec_bfd) /* No use without an exec file. */
+ {
+ SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
+ remote_check_symbols (symfile_objfile);
+ }
+#endif
+}
+
+/* This takes a program previously attached to and detaches it. After
+ this is done, GDB can be used to debug some other program. We
+ better not have left any breakpoints in the target program or it'll
+ die when it hits one. */
+
+static void
+remote_detach (char *args, int from_tty)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+
+ if (args)
+ error ("Argument given to \"detach\" when remotely debugging.");
+
+ /* Tell the remote target to detach. */
+ strcpy (buf, "D");
+ remote_send (buf, (rs->remote_packet_size));
+
+ target_mourn_inferior ();
+ if (from_tty)
+ puts_filtered ("Ending remote debugging.\n");
+
+}
+
+/* Same as remote_detach, but with async support. */
+static void
+remote_async_detach (char *args, int from_tty)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+
+ if (args)
+ error ("Argument given to \"detach\" when remotely debugging.");
+
+ /* Tell the remote target to detach. */
+ strcpy (buf, "D");
+ remote_send (buf, (rs->remote_packet_size));
+
+ /* Unregister the file descriptor from the event loop. */
+ if (target_is_async_p ())
+ serial_async (remote_desc, NULL, 0);
+
+ target_mourn_inferior ();
+ if (from_tty)
+ puts_filtered ("Ending remote debugging.\n");
+}
+
+/* Convert hex digit A to a number. */
+
+static int
+fromhex (int a)
+{
+ if (a >= '0' && a <= '9')
+ return a - '0';
+ else if (a >= 'a' && a <= 'f')
+ return a - 'a' + 10;
+ else if (a >= 'A' && a <= 'F')
+ return a - 'A' + 10;
+ else
+ error ("Reply contains invalid hex digit %d", a);
+}
+
+static int
+hex2bin (const char *hex, char *bin, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ if (hex[0] == 0 || hex[1] == 0)
+ {
+ /* Hex string is short, or of uneven length.
+ Return the count that has been converted so far. */
+ return i;
+ }
+ *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
+ hex += 2;
+ }
+ return i;
+}
+
+/* Convert number NIB to a hex digit. */
+
+static int
+tohex (int nib)
+{
+ if (nib < 10)
+ return '0' + nib;
+ else
+ return 'a' + nib - 10;
+}
+
+static int
+bin2hex (const char *bin, char *hex, int count)
+{
+ int i;
+ /* May use a length, or a nul-terminated string as input. */
+ if (count == 0)
+ count = strlen (bin);
+
+ for (i = 0; i < count; i++)
+ {
+ *hex++ = tohex ((*bin >> 4) & 0xf);
+ *hex++ = tohex (*bin++ & 0xf);
+ }
+ *hex = 0;
+ return i;
+}
+
+/* Tell the remote machine to resume. */
+
+static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
+
+static int last_sent_step;
+
+static void
+remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+ int pid = PIDGET (ptid);
+ char *p;
+
+ if (pid == -1)
+ set_thread (0, 0); /* run any thread */
+ else
+ set_thread (pid, 0); /* run this thread */
+
+ last_sent_signal = siggnal;
+ last_sent_step = step;
+
+ /* A hook for when we need to do something at the last moment before
+ resumption. */
+ if (target_resume_hook)
+ (*target_resume_hook) ();
+
+
+ /* The s/S/c/C packets do not return status. So if the target does
+ not support the S or C packets, the debug agent returns an empty
+ string which is detected in remote_wait(). This protocol defect
+ is fixed in the e/E packets. */
+
+ if (step && step_range_end)
+ {
+ /* If the target does not support the 'E' packet, we try the 'S'
+ packet. Ideally we would fall back to the 'e' packet if that
+ too is not supported. But that would require another copy of
+ the code to issue the 'e' packet (and fall back to 's' if not
+ supported) in remote_wait(). */
+
+ if (siggnal != TARGET_SIGNAL_0)
+ {
+ if (remote_protocol_E.support != PACKET_DISABLE)
+ {
+ p = buf;
+ *p++ = 'E';
+ *p++ = tohex (((int) siggnal >> 4) & 0xf);
+ *p++ = tohex (((int) siggnal) & 0xf);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) step_range_start);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) step_range_end);
+ *p++ = 0;
+
+ putpkt (buf);
+ getpkt (buf, (rs->remote_packet_size), 0);
+
+ if (packet_ok (buf, &remote_protocol_E) == PACKET_OK)
+ return;
+ }
+ }
+ else
+ {
+ if (remote_protocol_e.support != PACKET_DISABLE)
+ {
+ p = buf;
+ *p++ = 'e';
+ p += hexnumstr (p, (ULONGEST) step_range_start);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) step_range_end);
+ *p++ = 0;
+
+ putpkt (buf);
+ getpkt (buf, (rs->remote_packet_size), 0);
+
+ if (packet_ok (buf, &remote_protocol_e) == PACKET_OK)
+ return;
+ }
+ }
+ }
+
+ if (siggnal != TARGET_SIGNAL_0)
+ {
+ buf[0] = step ? 'S' : 'C';
+ buf[1] = tohex (((int) siggnal >> 4) & 0xf);
+ buf[2] = tohex (((int) siggnal) & 0xf);
+ buf[3] = '\0';
+ }
+ else
+ strcpy (buf, step ? "s" : "c");
+
+ putpkt (buf);
+}
+
+/* Same as remote_resume, but with async support. */
+static void
+remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+ int pid = PIDGET (ptid);
+ char *p;
+
+ if (pid == -1)
+ set_thread (0, 0); /* run any thread */
+ else
+ set_thread (pid, 0); /* run this thread */
+
+ last_sent_signal = siggnal;
+ last_sent_step = step;
+
+ /* A hook for when we need to do something at the last moment before
+ resumption. */
+ if (target_resume_hook)
+ (*target_resume_hook) ();
+
+ /* The s/S/c/C packets do not return status. So if the target does
+ not support the S or C packets, the debug agent returns an empty
+ string which is detected in remote_wait(). This protocol defect
+ is fixed in the e/E packets. */
+
+ if (step && step_range_end)
+ {
+ /* If the target does not support the 'E' packet, we try the 'S'
+ packet. Ideally we would fall back to the 'e' packet if that
+ too is not supported. But that would require another copy of
+ the code to issue the 'e' packet (and fall back to 's' if not
+ supported) in remote_wait(). */
+
+ if (siggnal != TARGET_SIGNAL_0)
+ {
+ if (remote_protocol_E.support != PACKET_DISABLE)
+ {
+ p = buf;
+ *p++ = 'E';
+ *p++ = tohex (((int) siggnal >> 4) & 0xf);
+ *p++ = tohex (((int) siggnal) & 0xf);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) step_range_start);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) step_range_end);
+ *p++ = 0;
+
+ putpkt (buf);
+ getpkt (buf, (rs->remote_packet_size), 0);
+
+ if (packet_ok (buf, &remote_protocol_E) == PACKET_OK)
+ goto register_event_loop;
+ }
+ }
+ else
+ {
+ if (remote_protocol_e.support != PACKET_DISABLE)
+ {
+ p = buf;
+ *p++ = 'e';
+ p += hexnumstr (p, (ULONGEST) step_range_start);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) step_range_end);
+ *p++ = 0;
+
+ putpkt (buf);
+ getpkt (buf, (rs->remote_packet_size), 0);
+
+ if (packet_ok (buf, &remote_protocol_e) == PACKET_OK)
+ goto register_event_loop;
+ }
+ }
+ }
+
+ if (siggnal != TARGET_SIGNAL_0)
+ {
+ buf[0] = step ? 'S' : 'C';
+ buf[1] = tohex (((int) siggnal >> 4) & 0xf);
+ buf[2] = tohex ((int) siggnal & 0xf);
+ buf[3] = '\0';
+ }
+ else
+ strcpy (buf, step ? "s" : "c");
+
+ putpkt (buf);
+
+register_event_loop:
+ /* We are about to start executing the inferior, let's register it
+ with the event loop. NOTE: this is the one place where all the
+ execution commands end up. We could alternatively do this in each
+ of the execution commands in infcmd.c.*/
+ /* FIXME: ezannoni 1999-09-28: We may need to move this out of here
+ into infcmd.c in order to allow inferior function calls to work
+ NOT asynchronously. */
+ if (event_loop_p && target_can_async_p ())
+ target_async (inferior_event_handler, 0);
+ /* Tell the world that the target is now executing. */
+ /* FIXME: cagney/1999-09-23: Is it the targets responsibility to set
+ this? Instead, should the client of target just assume (for
+ async targets) that the target is going to start executing? Is
+ this information already found in the continuation block? */
+ if (target_is_async_p ())
+ target_executing = 1;
+}
+
+
+/* Set up the signal handler for SIGINT, while the target is
+ executing, ovewriting the 'regular' SIGINT signal handler. */
+static void
+initialize_sigint_signal_handler (void)
+{
+ sigint_remote_token =
+ create_async_signal_handler (async_remote_interrupt, NULL);
+ signal (SIGINT, handle_remote_sigint);
+}
+
+/* Signal handler for SIGINT, while the target is executing. */
+static void
+handle_remote_sigint (int sig)
+{
+ signal (sig, handle_remote_sigint_twice);
+ sigint_remote_twice_token =
+ create_async_signal_handler (async_remote_interrupt_twice, NULL);
+ mark_async_signal_handler_wrapper (sigint_remote_token);
+}
+
+/* Signal handler for SIGINT, installed after SIGINT has already been
+ sent once. It will take effect the second time that the user sends
+ a ^C. */
+static void
+handle_remote_sigint_twice (int sig)
+{
+ signal (sig, handle_sigint);
+ sigint_remote_twice_token =
+ create_async_signal_handler (inferior_event_handler_wrapper, NULL);
+ mark_async_signal_handler_wrapper (sigint_remote_twice_token);
+}
+
+/* Perform the real interruption of the target execution, in response
+ to a ^C. */
+static void
+async_remote_interrupt (gdb_client_data arg)
+{
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
+
+ target_stop ();
+}
+
+/* Perform interrupt, if the first attempt did not succeed. Just give
+ up on the target alltogether. */
+void
+async_remote_interrupt_twice (gdb_client_data arg)
+{
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "remote_interrupt_twice called\n");
+ /* Do something only if the target was not killed by the previous
+ cntl-C. */
+ if (target_executing)
+ {
+ interrupt_query ();
+ signal (SIGINT, handle_remote_sigint);
+ }
+}
+
+/* Reinstall the usual SIGINT handlers, after the target has
+ stopped. */
+static void
+cleanup_sigint_signal_handler (void *dummy)
+{
+ signal (SIGINT, handle_sigint);
+ if (sigint_remote_twice_token)
+ delete_async_signal_handler ((struct async_signal_handler **) & sigint_remote_twice_token);
+ if (sigint_remote_token)
+ delete_async_signal_handler ((struct async_signal_handler **) & sigint_remote_token);
+}
+
+/* Send ^C to target to halt it. Target will respond, and send us a
+ packet. */
+static void (*ofunc) (int);
+
+/* The command line interface's stop routine. This function is installed
+ as a signal handler for SIGINT. The first time a user requests a
+ stop, we call remote_stop to send a break or ^C. If there is no
+ response from the target (it didn't stop when the user requested it),
+ we ask the user if he'd like to detach from the target. */
+static void
+remote_interrupt (int signo)
+{
+ /* If this doesn't work, try more severe steps. */
+ signal (signo, remote_interrupt_twice);
+
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
+
+ target_stop ();
+}
+
+/* The user typed ^C twice. */
+
+static void
+remote_interrupt_twice (int signo)
+{
+ signal (signo, ofunc);
+ interrupt_query ();
+ signal (signo, remote_interrupt);
+}
+
+/* This is the generic stop called via the target vector. When a target
+ interrupt is requested, either by the command line or the GUI, we
+ will eventually end up here. */
+static void
+remote_stop (void)
+{
+ /* Send a break or a ^C, depending on user preference. */
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "remote_stop called\n");
+
+ if (remote_break)
+ serial_send_break (remote_desc);
+ else
+ serial_write (remote_desc, "\003", 1);
+}
+
+/* Ask the user what to do when an interrupt is received. */
+
+static void
+interrupt_query (void)
+{
+ target_terminal_ours ();
+
+ if (query ("Interrupted while waiting for the program.\n\
+Give up (and stop debugging it)? "))
+ {
+ target_mourn_inferior ();
+ throw_exception (RETURN_QUIT);
+ }
+
+ target_terminal_inferior ();
+}
+
+/* Enable/disable target terminal ownership. Most targets can use
+ terminal groups to control terminal ownership. Remote targets are
+ different in that explicit transfer of ownership to/from GDB/target
+ is required. */
+
+static void
+remote_async_terminal_inferior (void)
+{
+ /* FIXME: cagney/1999-09-27: Shouldn't need to test for
+ sync_execution here. This function should only be called when
+ GDB is resuming the inferior in the forground. A background
+ resume (``run&'') should leave GDB in control of the terminal and
+ consequently should not call this code. */
+ if (!sync_execution)
+ return;
+ /* FIXME: cagney/1999-09-27: Closely related to the above. Make
+ calls target_terminal_*() idenpotent. The event-loop GDB talking
+ to an asynchronous target with a synchronous command calls this
+ function from both event-top.c and infrun.c/infcmd.c. Once GDB
+ stops trying to transfer the terminal to the target when it
+ shouldn't this guard can go away. */
+ if (!remote_async_terminal_ours_p)
+ return;
+ delete_file_handler (input_fd);
+ remote_async_terminal_ours_p = 0;
+ initialize_sigint_signal_handler ();
+ /* NOTE: At this point we could also register our selves as the
+ recipient of all input. Any characters typed could then be
+ passed on down to the target. */
+}
+
+static void
+remote_async_terminal_ours (void)
+{
+ /* See FIXME in remote_async_terminal_inferior. */
+ if (!sync_execution)
+ return;
+ /* See FIXME in remote_async_terminal_inferior. */
+ if (remote_async_terminal_ours_p)
+ return;
+ cleanup_sigint_signal_handler (NULL);
+ add_file_handler (input_fd, stdin_event_handler, 0);
+ remote_async_terminal_ours_p = 1;
+}
+
+/* If nonzero, ignore the next kill. */
+
+int kill_kludge;
+
+void
+remote_console_output (char *msg)
+{
+ char *p;
+
+ for (p = msg; p[0] && p[1]; p += 2)
+ {
+ char tb[2];
+ char c = fromhex (p[0]) * 16 + fromhex (p[1]);
+ tb[0] = c;
+ tb[1] = 0;
+ fputs_unfiltered (tb, gdb_stdtarg);
+ }
+ gdb_flush (gdb_stdtarg);
+}
+
+/* Wait until the remote machine stops, then return,
+ storing status in STATUS just as `wait' would.
+ Returns "pid", which in the case of a multi-threaded
+ remote OS, is the thread-id. */
+
+static ptid_t
+remote_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ struct remote_state *rs = get_remote_state ();
+ unsigned char *buf = alloca (rs->remote_packet_size);
+ int thread_num = -1;
+
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = 0;
+
+ while (1)
+ {
+ unsigned char *p;
+
+ ofunc = signal (SIGINT, remote_interrupt);
+ getpkt (buf, (rs->remote_packet_size), 1);
+ signal (SIGINT, ofunc);
+
+ /* This is a hook for when we need to do something (perhaps the
+ collection of trace data) every time the target stops. */
+ if (target_wait_loop_hook)
+ (*target_wait_loop_hook) ();
+
+ switch (buf[0])
+ {
+ case 'E': /* Error of some sort */
+ warning ("Remote failure reply: %s", buf);
+ continue;
+ case 'T': /* Status with PC, SP, FP, ... */
+ {
+ int i;
+ char* regs = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+
+ /* Expedited reply, containing Signal, {regno, reg} repeat */
+ /* format is: 'Tssn...:r...;n...:r...;n...:r...;#cc', where
+ ss = signal number
+ n... = register number
+ r... = register contents
+ */
+ p = &buf[3]; /* after Txx */
+
+ while (*p)
+ {
+ unsigned char *p1;
+ char *p_temp;
+ int fieldsize;
+
+ /* Read the ``P'' register number. */
+ LONGEST pnum = strtol ((const char *) p, &p_temp, 16);
+ p1 = (unsigned char *) p_temp;
+
+ if (p1 == p) /* No register number present here */
+ {
+ p1 = (unsigned char *) strchr ((const char *) p, ':');
+ if (p1 == NULL)
+ warning ("Malformed packet(a) (missing colon): %s\n\
+Packet: '%s'\n",
+ p, buf);
+ if (strncmp ((const char *) p, "thread", p1 - p) == 0)
+ {
+ p_temp = unpack_varlen_hex (++p1, &thread_num);
+ record_currthread (thread_num);
+ p = (unsigned char *) p_temp;
+ }
+ }
+ else
+ {
+ struct packet_reg *reg = packet_reg_from_pnum (rs, pnum);
+ p = p1;
+
+ if (*p++ != ':')
+ warning ("Malformed packet(b) (missing colon): %s\n\
+Packet: '%s'\n",
+ p, buf);
+
+ if (reg == NULL)
+ warning ("Remote sent bad register number %s: %s\n\
+Packet: '%s'\n",
+ phex_nz (pnum, 0), p, buf);
+
+ fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (reg->regnum));
+ p += 2 * fieldsize;
+ if (fieldsize < REGISTER_RAW_SIZE (reg->regnum))
+ warning ("Remote reply is too short: %s", buf);
+ supply_register (reg->regnum, regs);
+ }
+
+ if (*p++ != ';')
+ {
+ warning ("Remote register badly formatted: %s", buf);
+ warning (" here: %s", p);
+ }
+ }
+ }
+ /* fall through */
+ case 'S': /* Old style status, just signal only */
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = (enum target_signal)
+ (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+
+ if (buf[3] == 'p')
+ {
+ /* Export Cisco kernel mode as a convenience variable
+ (so that it can be used in the GDB prompt if desired). */
+
+ if (cisco_kernel_mode == 1)
+ set_internalvar (lookup_internalvar ("cisco_kernel_mode"),
+ value_from_string ("PDEBUG-"));
+ cisco_kernel_mode = 0;
+ thread_num = strtol ((const char *) &buf[4], NULL, 16);
+ record_currthread (thread_num);
+ }
+ else if (buf[3] == 'k')
+ {
+ /* Export Cisco kernel mode as a convenience variable
+ (so that it can be used in the GDB prompt if desired). */
+
+ if (cisco_kernel_mode == 1)
+ set_internalvar (lookup_internalvar ("cisco_kernel_mode"),
+ value_from_string ("KDEBUG-"));
+ cisco_kernel_mode = 1;
+ }
+ goto got_status;
+ case 'N': /* Cisco special: status and offsets */
+ {
+ bfd_vma text_addr, data_addr, bss_addr;
+ bfd_signed_vma text_off, data_off, bss_off;
+ unsigned char *p1;
+
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = (enum target_signal)
+ (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+
+ if (symfile_objfile == NULL)
+ {
+ warning ("Relocation packet received with no symbol file. \
+Packet Dropped");
+ goto got_status;
+ }
+
+ /* Relocate object file. Buffer format is NAATT;DD;BB
+ * where AA is the signal number, TT is the new text
+ * address, DD * is the new data address, and BB is the
+ * new bss address. */
+
+ p = &buf[3];
+ text_addr = strtoul (p, (char **) &p1, 16);
+ if (p1 == p || *p1 != ';')
+ warning ("Malformed relocation packet: Packet '%s'", buf);
+ p = p1 + 1;
+ data_addr = strtoul (p, (char **) &p1, 16);
+ if (p1 == p || *p1 != ';')
+ warning ("Malformed relocation packet: Packet '%s'", buf);
+ p = p1 + 1;
+ bss_addr = strtoul (p, (char **) &p1, 16);
+ if (p1 == p)
+ warning ("Malformed relocation packet: Packet '%s'", buf);
+
+ if (remote_cisco_section_offsets (text_addr, data_addr, bss_addr,
+ &text_off, &data_off, &bss_off)
+ == 0)
+ if (text_off != 0 || data_off != 0 || bss_off != 0)
+ remote_cisco_objfile_relocate (text_off, data_off, bss_off);
+
+ goto got_status;
+ }
+ case 'W': /* Target exited */
+ {
+ /* The remote process exited. */
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = (fromhex (buf[1]) << 4) + fromhex (buf[2]);
+ goto got_status;
+ }
+ case 'X':
+ status->kind = TARGET_WAITKIND_SIGNALLED;
+ status->value.sig = (enum target_signal)
+ (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+ kill_kludge = 1;
+
+ goto got_status;
+ case 'O': /* Console output */
+ remote_console_output (buf + 1);
+ continue;
+ case '\0':
+ if (last_sent_signal != TARGET_SIGNAL_0)
+ {
+ /* Zero length reply means that we tried 'S' or 'C' and
+ the remote system doesn't support it. */
+ target_terminal_ours_for_output ();
+ printf_filtered
+ ("Can't send signals to this remote system. %s not sent.\n",
+ target_signal_to_name (last_sent_signal));
+ last_sent_signal = TARGET_SIGNAL_0;
+ target_terminal_inferior ();
+
+ strcpy ((char *) buf, last_sent_step ? "s" : "c");
+ putpkt ((char *) buf);
+ continue;
+ }
+ /* else fallthrough */
+ default:
+ warning ("Invalid remote reply: %s", buf);
+ continue;
+ }
+ }
+got_status:
+ if (thread_num != -1)
+ {
+ return pid_to_ptid (thread_num);
+ }
+ return inferior_ptid;
+}
+
+/* Async version of remote_wait. */
+static ptid_t
+remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ struct remote_state *rs = get_remote_state ();
+ unsigned char *buf = alloca (rs->remote_packet_size);
+ int thread_num = -1;
+
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = 0;
+
+ while (1)
+ {
+ unsigned char *p;
+
+ if (!target_is_async_p ())
+ ofunc = signal (SIGINT, remote_interrupt);
+ /* FIXME: cagney/1999-09-27: If we're in async mode we should
+ _never_ wait for ever -> test on target_is_async_p().
+ However, before we do that we need to ensure that the caller
+ knows how to take the target into/out of async mode. */
+ getpkt (buf, (rs->remote_packet_size), wait_forever_enabled_p);
+ if (!target_is_async_p ())
+ signal (SIGINT, ofunc);
+
+ /* This is a hook for when we need to do something (perhaps the
+ collection of trace data) every time the target stops. */
+ if (target_wait_loop_hook)
+ (*target_wait_loop_hook) ();
+
+ switch (buf[0])
+ {
+ case 'E': /* Error of some sort */
+ warning ("Remote failure reply: %s", buf);
+ continue;
+ case 'T': /* Status with PC, SP, FP, ... */
+ {
+ int i;
+ char* regs = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+
+ /* Expedited reply, containing Signal, {regno, reg} repeat */
+ /* format is: 'Tssn...:r...;n...:r...;n...:r...;#cc', where
+ ss = signal number
+ n... = register number
+ r... = register contents
+ */
+ p = &buf[3]; /* after Txx */
+
+ while (*p)
+ {
+ unsigned char *p1;
+ char *p_temp;
+ int fieldsize;
+
+ /* Read the register number */
+ long pnum = strtol ((const char *) p, &p_temp, 16);
+ p1 = (unsigned char *) p_temp;
+
+ if (p1 == p) /* No register number present here */
+ {
+ p1 = (unsigned char *) strchr ((const char *) p, ':');
+ if (p1 == NULL)
+ warning ("Malformed packet(a) (missing colon): %s\n\
+Packet: '%s'\n",
+ p, buf);
+ if (strncmp ((const char *) p, "thread", p1 - p) == 0)
+ {
+ p_temp = unpack_varlen_hex (++p1, &thread_num);
+ record_currthread (thread_num);
+ p = (unsigned char *) p_temp;
+ }
+ }
+ else
+ {
+ struct packet_reg *reg = packet_reg_from_pnum (rs, pnum);
+ p = p1;
+ if (*p++ != ':')
+ warning ("Malformed packet(b) (missing colon): %s\n\
+Packet: '%s'\n",
+ p, buf);
+
+ if (reg == NULL)
+ warning ("Remote sent bad register number %ld: %s\n\
+Packet: '%s'\n",
+ pnum, p, buf);
+
+ fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (reg->regnum));
+ p += 2 * fieldsize;
+ if (fieldsize < REGISTER_RAW_SIZE (reg->regnum))
+ warning ("Remote reply is too short: %s", buf);
+ supply_register (reg->regnum, regs);
+ }
+
+ if (*p++ != ';')
+ {
+ warning ("Remote register badly formatted: %s", buf);
+ warning (" here: %s", p);
+ }
+ }
+ }
+ /* fall through */
+ case 'S': /* Old style status, just signal only */
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = (enum target_signal)
+ (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+
+ if (buf[3] == 'p')
+ {
+ /* Export Cisco kernel mode as a convenience variable
+ (so that it can be used in the GDB prompt if desired). */
+
+ if (cisco_kernel_mode == 1)
+ set_internalvar (lookup_internalvar ("cisco_kernel_mode"),
+ value_from_string ("PDEBUG-"));
+ cisco_kernel_mode = 0;
+ thread_num = strtol ((const char *) &buf[4], NULL, 16);
+ record_currthread (thread_num);
+ }
+ else if (buf[3] == 'k')
+ {
+ /* Export Cisco kernel mode as a convenience variable
+ (so that it can be used in the GDB prompt if desired). */
+
+ if (cisco_kernel_mode == 1)
+ set_internalvar (lookup_internalvar ("cisco_kernel_mode"),
+ value_from_string ("KDEBUG-"));
+ cisco_kernel_mode = 1;
+ }
+ goto got_status;
+ case 'N': /* Cisco special: status and offsets */
+ {
+ bfd_vma text_addr, data_addr, bss_addr;
+ bfd_signed_vma text_off, data_off, bss_off;
+ unsigned char *p1;
+
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = (enum target_signal)
+ (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+
+ if (symfile_objfile == NULL)
+ {
+ warning ("Relocation packet recieved with no symbol file. \
+Packet Dropped");
+ goto got_status;
+ }
+
+ /* Relocate object file. Buffer format is NAATT;DD;BB
+ * where AA is the signal number, TT is the new text
+ * address, DD * is the new data address, and BB is the
+ * new bss address. */
+
+ p = &buf[3];
+ text_addr = strtoul (p, (char **) &p1, 16);
+ if (p1 == p || *p1 != ';')
+ warning ("Malformed relocation packet: Packet '%s'", buf);
+ p = p1 + 1;
+ data_addr = strtoul (p, (char **) &p1, 16);
+ if (p1 == p || *p1 != ';')
+ warning ("Malformed relocation packet: Packet '%s'", buf);
+ p = p1 + 1;
+ bss_addr = strtoul (p, (char **) &p1, 16);
+ if (p1 == p)
+ warning ("Malformed relocation packet: Packet '%s'", buf);
+
+ if (remote_cisco_section_offsets (text_addr, data_addr, bss_addr,
+ &text_off, &data_off, &bss_off)
+ == 0)
+ if (text_off != 0 || data_off != 0 || bss_off != 0)
+ remote_cisco_objfile_relocate (text_off, data_off, bss_off);
+
+ goto got_status;
+ }
+ case 'W': /* Target exited */
+ {
+ /* The remote process exited. */
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = (fromhex (buf[1]) << 4) + fromhex (buf[2]);
+ goto got_status;
+ }
+ case 'X':
+ status->kind = TARGET_WAITKIND_SIGNALLED;
+ status->value.sig = (enum target_signal)
+ (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+ kill_kludge = 1;
+
+ goto got_status;
+ case 'O': /* Console output */
+ remote_console_output (buf + 1);
+ /* Return immediately to the event loop. The event loop will
+ still be waiting on the inferior afterwards. */
+ status->kind = TARGET_WAITKIND_IGNORE;
+ goto got_status;
+ case '\0':
+ if (last_sent_signal != TARGET_SIGNAL_0)
+ {
+ /* Zero length reply means that we tried 'S' or 'C' and
+ the remote system doesn't support it. */
+ target_terminal_ours_for_output ();
+ printf_filtered
+ ("Can't send signals to this remote system. %s not sent.\n",
+ target_signal_to_name (last_sent_signal));
+ last_sent_signal = TARGET_SIGNAL_0;
+ target_terminal_inferior ();
+
+ strcpy ((char *) buf, last_sent_step ? "s" : "c");
+ putpkt ((char *) buf);
+ continue;
+ }
+ /* else fallthrough */
+ default:
+ warning ("Invalid remote reply: %s", buf);
+ continue;
+ }
+ }
+got_status:
+ if (thread_num != -1)
+ {
+ return pid_to_ptid (thread_num);
+ }
+ return inferior_ptid;
+}
+
+/* Number of bytes of registers this stub implements. */
+
+static int register_bytes_found;
+
+/* Read the remote registers into the block REGS. */
+/* Currently we just read all the registers, so we don't use regnum. */
+
+/* ARGSUSED */
+static void
+remote_fetch_registers (int regnum)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+ int i;
+ char *p;
+ char *regs = alloca (rs->sizeof_g_packet);
+
+ set_thread (PIDGET (inferior_ptid), 1);
+
+ if (regnum >= 0)
+ {
+ struct packet_reg *reg = packet_reg_from_regnum (rs, regnum);
+ gdb_assert (reg != NULL);
+ if (!reg->in_g_packet)
+ internal_error (__FILE__, __LINE__,
+ "Attempt to fetch a non G-packet register when this "
+ "remote.c does not support the p-packet.");
+ }
+
+ sprintf (buf, "g");
+ remote_send (buf, (rs->remote_packet_size));
+
+ /* Save the size of the packet sent to us by the target. Its used
+ as a heuristic when determining the max size of packets that the
+ target can safely receive. */
+ if ((rs->actual_register_packet_size) == 0)
+ (rs->actual_register_packet_size) = strlen (buf);
+
+ /* Unimplemented registers read as all bits zero. */
+ memset (regs, 0, rs->sizeof_g_packet);
+
+ /* We can get out of synch in various cases. If the first character
+ in the buffer is not a hex character, assume that has happened
+ and try to fetch another packet to read. */
+ while ((buf[0] < '0' || buf[0] > '9')
+ && (buf[0] < 'a' || buf[0] > 'f')
+ && buf[0] != 'x') /* New: unavailable register value */
+ {
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "Bad register packet; fetching a new packet\n");
+ getpkt (buf, (rs->remote_packet_size), 0);
+ }
+
+ /* Reply describes registers byte by byte, each byte encoded as two
+ hex characters. Suck them all up, then supply them to the
+ register cacheing/storage mechanism. */
+
+ p = buf;
+ for (i = 0; i < rs->sizeof_g_packet; i++)
+ {
+ if (p[0] == 0)
+ break;
+ if (p[1] == 0)
+ {
+ warning ("Remote reply is of odd length: %s", buf);
+ /* Don't change register_bytes_found in this case, and don't
+ print a second warning. */
+ goto supply_them;
+ }
+ if (p[0] == 'x' && p[1] == 'x')
+ regs[i] = 0; /* 'x' */
+ else
+ regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
+ p += 2;
+ }
+
+ if (i != register_bytes_found)
+ {
+ register_bytes_found = i;
+ if (REGISTER_BYTES_OK_P ()
+ && !REGISTER_BYTES_OK (i))
+ warning ("Remote reply is too short: %s", buf);
+ }
+
+ supply_them:
+ {
+ int i;
+ for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+ {
+ struct packet_reg *r = &rs->regs[i];
+ if (r->in_g_packet)
+ {
+ supply_register (r->regnum, regs + r->offset);
+ if (buf[r->offset * 2] == 'x')
+ set_register_cached (i, -1);
+ }
+ }
+ }
+}
+
+/* Prepare to store registers. Since we may send them all (using a
+ 'G' request), we have to read out the ones we don't want to change
+ first. */
+
+static void
+remote_prepare_to_store (void)
+{
+ /* Make sure the entire registers array is valid. */
+ switch (remote_protocol_P.support)
+ {
+ case PACKET_DISABLE:
+ case PACKET_SUPPORT_UNKNOWN:
+ /* NOTE: This isn't rs->sizeof_g_packet because here, we are
+ forcing the register cache to read its and not the target
+ registers. */
+ read_register_bytes (0, (char *) NULL, REGISTER_BYTES); /* OK use. */
+ break;
+ case PACKET_ENABLE:
+ break;
+ }
+}
+
+/* Helper: Attempt to store REGNUM using the P packet. Return fail IFF
+ packet was not recognized. */
+
+static int
+store_register_using_P (int regnum)
+{
+ struct remote_state *rs = get_remote_state ();
+ struct packet_reg *reg = packet_reg_from_regnum (rs, regnum);
+ /* Try storing a single register. */
+ char *buf = alloca (rs->remote_packet_size);
+ char *regp = alloca (MAX_REGISTER_RAW_SIZE);
+ char *p;
+ int i;
+
+ sprintf (buf, "P%s=", phex_nz (reg->pnum, 0));
+ p = buf + strlen (buf);
+ regcache_collect (reg->regnum, regp);
+ bin2hex (regp, p, REGISTER_RAW_SIZE (reg->regnum));
+ remote_send (buf, rs->remote_packet_size);
+
+ return buf[0] != '\0';
+}
+
+
+/* Store register REGNUM, or all registers if REGNUM == -1, from the contents
+ of the register cache buffer. FIXME: ignores errors. */
+
+static void
+remote_store_registers (int regnum)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf;
+ char *regs;
+ int i;
+ char *p;
+
+ set_thread (PIDGET (inferior_ptid), 1);
+
+ if (regnum >= 0)
+ {
+ switch (remote_protocol_P.support)
+ {
+ case PACKET_DISABLE:
+ break;
+ case PACKET_ENABLE:
+ if (store_register_using_P (regnum))
+ return;
+ else
+ error ("Protocol error: P packet not recognized by stub");
+ case PACKET_SUPPORT_UNKNOWN:
+ if (store_register_using_P (regnum))
+ {
+ /* The stub recognized the 'P' packet. Remember this. */
+ remote_protocol_P.support = PACKET_ENABLE;
+ return;
+ }
+ else
+ {
+ /* The stub does not support the 'P' packet. Use 'G'
+ instead, and don't try using 'P' in the future (it
+ will just waste our time). */
+ remote_protocol_P.support = PACKET_DISABLE;
+ break;
+ }
+ }
+ }
+
+ /* Extract all the registers in the regcache copying them into a
+ local buffer. */
+ {
+ int i;
+ regs = alloca (rs->sizeof_g_packet);
+ memset (regs, rs->sizeof_g_packet, 0);
+ for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+ {
+ struct packet_reg *r = &rs->regs[i];
+ if (r->in_g_packet)
+ regcache_collect (r->regnum, regs + r->offset);
+ }
+ }
+
+ /* Command describes registers byte by byte,
+ each byte encoded as two hex characters. */
+ buf = alloca (rs->remote_packet_size);
+ p = buf;
+ *p++ = 'G';
+ /* remote_prepare_to_store insures that register_bytes_found gets set. */
+ bin2hex (regs, p, register_bytes_found);
+ remote_send (buf, (rs->remote_packet_size));
+}
+
+
+/* Return the number of hex digits in num. */
+
+static int
+hexnumlen (ULONGEST num)
+{
+ int i;
+
+ for (i = 0; num != 0; i++)
+ num >>= 4;
+
+ return max (i, 1);
+}
+
+/* Set BUF to the minimum number of hex digits representing NUM. */
+
+static int
+hexnumstr (char *buf, ULONGEST num)
+{
+ int len = hexnumlen (num);
+ return hexnumnstr (buf, num, len);
+}
+
+
+/* Set BUF to the hex digits representing NUM, padded to WIDTH characters. */
+
+static int
+hexnumnstr (char *buf, ULONGEST num, int width)
+{
+ int i;
+
+ buf[width] = '\0';
+
+ for (i = width - 1; i >= 0; i--)
+ {
+ buf[i] = "0123456789abcdef"[(num & 0xf)];
+ num >>= 4;
+ }
+
+ return width;
+}
+
+/* Mask all but the least significant REMOTE_ADDRESS_SIZE bits. */
+
+static CORE_ADDR
+remote_address_masked (CORE_ADDR addr)
+{
+ if (remote_address_size > 0
+ && remote_address_size < (sizeof (ULONGEST) * 8))
+ {
+ /* Only create a mask when that mask can safely be constructed
+ in a ULONGEST variable. */
+ ULONGEST mask = 1;
+ mask = (mask << remote_address_size) - 1;
+ addr &= mask;
+ }
+ return addr;
+}
+
+/* Determine whether the remote target supports binary downloading.
+ This is accomplished by sending a no-op memory write of zero length
+ to the target at the specified address. It does not suffice to send
+ the whole packet, since many stubs strip the eighth bit and subsequently
+ compute a wrong checksum, which causes real havoc with remote_write_bytes.
+
+ NOTE: This can still lose if the serial line is not eight-bit
+ clean. In cases like this, the user should clear "remote
+ X-packet". */
+
+static void
+check_binary_download (CORE_ADDR addr)
+{
+ struct remote_state *rs = get_remote_state ();
+ switch (remote_protocol_binary_download.support)
+ {
+ case PACKET_DISABLE:
+ break;
+ case PACKET_ENABLE:
+ break;
+ case PACKET_SUPPORT_UNKNOWN:
+ {
+ char *buf = alloca (rs->remote_packet_size);
+ char *p;
+
+ p = buf;
+ *p++ = 'X';
+ p += hexnumstr (p, (ULONGEST) addr);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) 0);
+ *p++ = ':';
+ *p = '\0';
+
+ putpkt_binary (buf, (int) (p - buf));
+ getpkt (buf, (rs->remote_packet_size), 0);
+
+ if (buf[0] == '\0')
+ {
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "binary downloading NOT suppported by target\n");
+ remote_protocol_binary_download.support = PACKET_DISABLE;
+ }
+ else
+ {
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "binary downloading suppported by target\n");
+ remote_protocol_binary_download.support = PACKET_ENABLE;
+ }
+ break;
+ }
+ }
+}
+
+/* Write memory data directly to the remote machine.
+ This does not inform the data cache; the data cache uses this.
+ MEMADDR is the address in the remote memory space.
+ MYADDR is the address of the buffer in our space.
+ LEN is the number of bytes.
+
+ Returns number of bytes transferred, or 0 (setting errno) for
+ error. Only transfer a single packet. */
+
+static int
+remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ unsigned char *buf;
+ int max_buf_size; /* Max size of packet output buffer */
+ unsigned char *p;
+ unsigned char *plen;
+ long sizeof_buf;
+ int plenlen;
+ int todo;
+ int nr_bytes;
+
+ /* Verify that the target can support a binary download */
+ check_binary_download (memaddr);
+
+ /* Determine the max packet size. */
+ max_buf_size = get_memory_write_packet_size ();
+ sizeof_buf = max_buf_size + 1; /* Space for trailing NUL */
+ buf = alloca (sizeof_buf);
+
+ /* Subtract header overhead from max payload size - $M<memaddr>,<len>:#nn */
+ max_buf_size -= 2 + hexnumlen (memaddr + len - 1) + 1 + hexnumlen (len) + 4;
+
+ /* construct "M"<memaddr>","<len>":" */
+ /* sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo); */
+ p = buf;
+
+ /* Append [XM]. Compute a best guess of the number of bytes
+ actually transfered. */
+ switch (remote_protocol_binary_download.support)
+ {
+ case PACKET_ENABLE:
+ *p++ = 'X';
+ /* Best guess at number of bytes that will fit. */
+ todo = min (len, max_buf_size);
+ break;
+ case PACKET_DISABLE:
+ *p++ = 'M';
+ /* num bytes that will fit */
+ todo = min (len, max_buf_size / 2);
+ break;
+ case PACKET_SUPPORT_UNKNOWN:
+ internal_error (__FILE__, __LINE__,
+ "remote_write_bytes: bad internal state");
+ default:
+ internal_error (__FILE__, __LINE__, "bad switch");
+ }
+
+ /* Append <memaddr> */
+ memaddr = remote_address_masked (memaddr);
+ p += hexnumstr (p, (ULONGEST) memaddr);
+ *p++ = ',';
+
+ /* Append <len>. Retain the location/size of <len>. It may
+ need to be adjusted once the packet body has been created. */
+ plen = p;
+ plenlen = hexnumstr (p, (ULONGEST) todo);
+ p += plenlen;
+ *p++ = ':';
+ *p = '\0';
+
+ /* Append the packet body. */
+ switch (remote_protocol_binary_download.support)
+ {
+ case PACKET_ENABLE:
+ /* Binary mode. Send target system values byte by byte, in
+ increasing byte addresses. Only escape certain critical
+ characters. */
+ for (nr_bytes = 0;
+ (nr_bytes < todo) && (p - buf) < (max_buf_size - 2);
+ nr_bytes++)
+ {
+ switch (myaddr[nr_bytes] & 0xff)
+ {
+ case '$':
+ case '#':
+ case 0x7d:
+ /* These must be escaped */
+ *p++ = 0x7d;
+ *p++ = (myaddr[nr_bytes] & 0xff) ^ 0x20;
+ break;
+ default:
+ *p++ = myaddr[nr_bytes] & 0xff;
+ break;
+ }
+ }
+ if (nr_bytes < todo)
+ {
+ /* Escape chars have filled up the buffer prematurely,
+ and we have actually sent fewer bytes than planned.
+ Fix-up the length field of the packet. Use the same
+ number of characters as before. */
+
+ plen += hexnumnstr (plen, (ULONGEST) nr_bytes, plenlen);
+ *plen = ':'; /* overwrite \0 from hexnumnstr() */
+ }
+ break;
+ case PACKET_DISABLE:
+ /* Normal mode: Send target system values byte by byte, in
+ increasing byte addresses. Each byte is encoded as a two hex
+ value. */
+ nr_bytes = bin2hex (myaddr, p, todo);
+ p += 2 * nr_bytes;
+ break;
+ case PACKET_SUPPORT_UNKNOWN:
+ internal_error (__FILE__, __LINE__,
+ "remote_write_bytes: bad internal state");
+ default:
+ internal_error (__FILE__, __LINE__, "bad switch");
+ }
+
+ putpkt_binary (buf, (int) (p - buf));
+ getpkt (buf, sizeof_buf, 0);
+
+ if (buf[0] == 'E')
+ {
+ /* There is no correspondance between what the remote protocol
+ uses for errors and errno codes. We would like a cleaner way
+ of representing errors (big enough to include errno codes,
+ bfd_error codes, and others). But for now just return EIO. */
+ errno = EIO;
+ return 0;
+ }
+
+ /* Return NR_BYTES, not TODO, in case escape chars caused us to send fewer
+ bytes than we'd planned. */
+ return nr_bytes;
+}
+
+/* Read memory data directly from the remote machine.
+ This does not use the data cache; the data cache uses this.
+ MEMADDR is the address in the remote memory space.
+ MYADDR is the address of the buffer in our space.
+ LEN is the number of bytes.
+
+ Returns number of bytes transferred, or 0 for error. */
+
+/* NOTE: cagney/1999-10-18: This function (and its siblings in other
+ remote targets) shouldn't attempt to read the entire buffer.
+ Instead it should read a single packet worth of data and then
+ return the byte size of that packet to the caller. The caller (its
+ caller and its callers caller ;-) already contains code for
+ handling partial reads. */
+
+static int
+remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ char *buf;
+ int max_buf_size; /* Max size of packet output buffer */
+ long sizeof_buf;
+ int origlen;
+
+ /* Create a buffer big enough for this packet. */
+ max_buf_size = get_memory_read_packet_size ();
+ sizeof_buf = max_buf_size + 1; /* Space for trailing NUL */
+ buf = alloca (sizeof_buf);
+
+ origlen = len;
+ while (len > 0)
+ {
+ char *p;
+ int todo;
+ int i;
+
+ todo = min (len, max_buf_size / 2); /* num bytes that will fit */
+
+ /* construct "m"<memaddr>","<len>" */
+ /* sprintf (buf, "m%lx,%x", (unsigned long) memaddr, todo); */
+ memaddr = remote_address_masked (memaddr);
+ p = buf;
+ *p++ = 'm';
+ p += hexnumstr (p, (ULONGEST) memaddr);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) todo);
+ *p = '\0';
+
+ putpkt (buf);
+ getpkt (buf, sizeof_buf, 0);
+
+ if (buf[0] == 'E')
+ {
+ /* There is no correspondance between what the remote protocol uses
+ for errors and errno codes. We would like a cleaner way of
+ representing errors (big enough to include errno codes, bfd_error
+ codes, and others). But for now just return EIO. */
+ errno = EIO;
+ return 0;
+ }
+
+ /* Reply describes memory byte by byte,
+ each byte encoded as two hex characters. */
+
+ p = buf;
+ if ((i = hex2bin (p, myaddr, todo)) < todo)
+ {
+ /* Reply is short. This means that we were able to read
+ only part of what we wanted to. */
+ return i + (origlen - len);
+ }
+ myaddr += todo;
+ memaddr += todo;
+ len -= todo;
+ }
+ return origlen;
+}
+
+/* Read or write LEN bytes from inferior memory at MEMADDR,
+ transferring to or from debugger address BUFFER. Write to inferior if
+ SHOULD_WRITE is nonzero. Returns length of data written or read; 0
+ for error. TARGET is unused. */
+
+/* ARGSUSED */
+static int
+remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len,
+ int should_write, struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ CORE_ADDR targ_addr;
+ int targ_len;
+ int res;
+
+ REMOTE_TRANSLATE_XFER_ADDRESS (mem_addr, mem_len, &targ_addr, &targ_len);
+ if (targ_len <= 0)
+ return 0;
+
+ if (should_write)
+ res = remote_write_bytes (targ_addr, buffer, targ_len);
+ else
+ res = remote_read_bytes (targ_addr, buffer, targ_len);
+
+ return res;
+}
+
+
+#if 0
+/* Enable after 4.12. */
+
+void
+remote_search (int len, char *data, char *mask, CORE_ADDR startaddr,
+ int increment, CORE_ADDR lorange, CORE_ADDR hirange,
+ CORE_ADDR *addr_found, char *data_found)
+{
+ if (increment == -4 && len == 4)
+ {
+ long mask_long, data_long;
+ long data_found_long;
+ CORE_ADDR addr_we_found;
+ char *buf = alloca (rs->remote_packet_size);
+ long returned_long[2];
+ char *p;
+
+ mask_long = extract_unsigned_integer (mask, len);
+ data_long = extract_unsigned_integer (data, len);
+ sprintf (buf, "t%x:%x,%x", startaddr, data_long, mask_long);
+ putpkt (buf);
+ getpkt (buf, (rs->remote_packet_size), 0);
+ if (buf[0] == '\0')
+ {
+ /* The stub doesn't support the 't' request. We might want to
+ remember this fact, but on the other hand the stub could be
+ switched on us. Maybe we should remember it only until
+ the next "target remote". */
+ generic_search (len, data, mask, startaddr, increment, lorange,
+ hirange, addr_found, data_found);
+ return;
+ }
+
+ if (buf[0] == 'E')
+ /* There is no correspondance between what the remote protocol uses
+ for errors and errno codes. We would like a cleaner way of
+ representing errors (big enough to include errno codes, bfd_error
+ codes, and others). But for now just use EIO. */
+ memory_error (EIO, startaddr);
+ p = buf;
+ addr_we_found = 0;
+ while (*p != '\0' && *p != ',')
+ addr_we_found = (addr_we_found << 4) + fromhex (*p++);
+ if (*p == '\0')
+ error ("Protocol error: short return for search");
+
+ data_found_long = 0;
+ while (*p != '\0' && *p != ',')
+ data_found_long = (data_found_long << 4) + fromhex (*p++);
+ /* Ignore anything after this comma, for future extensions. */
+
+ if (addr_we_found < lorange || addr_we_found >= hirange)
+ {
+ *addr_found = 0;
+ return;
+ }
+
+ *addr_found = addr_we_found;
+ *data_found = store_unsigned_integer (data_we_found, len);
+ return;
+ }
+ generic_search (len, data, mask, startaddr, increment, lorange,
+ hirange, addr_found, data_found);
+}
+#endif /* 0 */
+
+static void
+remote_files_info (struct target_ops *ignore)
+{
+ puts_filtered ("Debugging a target over a serial line.\n");
+}
+
+/* Stuff for dealing with the packets which are part of this protocol.
+ See comment at top of file for details. */
+
+/* Read a single character from the remote end, masking it down to 7 bits. */
+
+static int
+readchar (int timeout)
+{
+ int ch;
+
+ ch = serial_readchar (remote_desc, timeout);
+
+ if (ch >= 0)
+ return (ch & 0x7f);
+
+ switch ((enum serial_rc) ch)
+ {
+ case SERIAL_EOF:
+ target_mourn_inferior ();
+ error ("Remote connection closed");
+ /* no return */
+ case SERIAL_ERROR:
+ perror_with_name ("Remote communication error");
+ /* no return */
+ case SERIAL_TIMEOUT:
+ break;
+ }
+ return ch;
+}
+
+/* Send the command in BUF to the remote machine, and read the reply
+ into BUF. Report an error if we get an error reply. */
+
+static void
+remote_send (char *buf,
+ long sizeof_buf)
+{
+ putpkt (buf);
+ getpkt (buf, sizeof_buf, 0);
+
+ if (buf[0] == 'E')
+ error ("Remote failure reply: %s", buf);
+}
+
+/* Display a null-terminated packet on stdout, for debugging, using C
+ string notation. */
+
+static void
+print_packet (char *buf)
+{
+ puts_filtered ("\"");
+ fputstr_filtered (buf, '"', gdb_stdout);
+ puts_filtered ("\"");
+}
+
+int
+putpkt (char *buf)
+{
+ return putpkt_binary (buf, strlen (buf));
+}
+
+/* Send a packet to the remote machine, with error checking. The data
+ of the packet is in BUF. The string in BUF can be at most (rs->remote_packet_size) - 5
+ to account for the $, # and checksum, and for a possible /0 if we are
+ debugging (remote_debug) and want to print the sent packet as a string */
+
+static int
+putpkt_binary (char *buf, int cnt)
+{
+ struct remote_state *rs = get_remote_state ();
+ int i;
+ unsigned char csum = 0;
+ char *buf2 = alloca (cnt + 6);
+ long sizeof_junkbuf = (rs->remote_packet_size);
+ char *junkbuf = alloca (sizeof_junkbuf);
+
+ int ch;
+ int tcount = 0;
+ char *p;
+
+ /* Copy the packet into buffer BUF2, encapsulating it
+ and giving it a checksum. */
+
+ p = buf2;
+ *p++ = '$';
+
+ for (i = 0; i < cnt; i++)
+ {
+ csum += buf[i];
+ *p++ = buf[i];
+ }
+ *p++ = '#';
+ *p++ = tohex ((csum >> 4) & 0xf);
+ *p++ = tohex (csum & 0xf);
+
+ /* Send it over and over until we get a positive ack. */
+
+ while (1)
+ {
+ int started_error_output = 0;
+
+ if (remote_debug)
+ {
+ *p = '\0';
+ fprintf_unfiltered (gdb_stdlog, "Sending packet: ");
+ fputstrn_unfiltered (buf2, p - buf2, 0, gdb_stdlog);
+ fprintf_unfiltered (gdb_stdlog, "...");
+ gdb_flush (gdb_stdlog);
+ }
+ if (serial_write (remote_desc, buf2, p - buf2))
+ perror_with_name ("putpkt: write failed");
+
+ /* read until either a timeout occurs (-2) or '+' is read */
+ while (1)
+ {
+ ch = readchar (remote_timeout);
+
+ if (remote_debug)
+ {
+ switch (ch)
+ {
+ case '+':
+ case '-':
+ case SERIAL_TIMEOUT:
+ case '$':
+ if (started_error_output)
+ {
+ putchar_unfiltered ('\n');
+ started_error_output = 0;
+ }
+ }
+ }
+
+ switch (ch)
+ {
+ case '+':
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "Ack\n");
+ return 1;
+ case '-':
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "Nak\n");
+ case SERIAL_TIMEOUT:
+ tcount++;
+ if (tcount > 3)
+ return 0;
+ break; /* Retransmit buffer */
+ case '$':
+ {
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "Packet instead of Ack, ignoring it\n");
+ /* It's probably an old response, and we're out of sync.
+ Just gobble up the packet and ignore it. */
+ read_frame (junkbuf, sizeof_junkbuf);
+ continue; /* Now, go look for + */
+ }
+ default:
+ if (remote_debug)
+ {
+ if (!started_error_output)
+ {
+ started_error_output = 1;
+ fprintf_unfiltered (gdb_stdlog, "putpkt: Junk: ");
+ }
+ fputc_unfiltered (ch & 0177, gdb_stdlog);
+ }
+ continue;
+ }
+ break; /* Here to retransmit */
+ }
+
+#if 0
+ /* This is wrong. If doing a long backtrace, the user should be
+ able to get out next time we call QUIT, without anything as
+ violent as interrupt_query. If we want to provide a way out of
+ here without getting to the next QUIT, it should be based on
+ hitting ^C twice as in remote_wait. */
+ if (quit_flag)
+ {
+ quit_flag = 0;
+ interrupt_query ();
+ }
+#endif
+ }
+}
+
+static int remote_cisco_mode;
+
+/* Come here after finding the start of the frame. Collect the rest
+ into BUF, verifying the checksum, length, and handling run-length
+ compression. No more than sizeof_buf-1 characters are read so that
+ the buffer can be NUL terminated.
+
+ Returns -1 on error, number of characters in buffer (ignoring the
+ trailing NULL) on success. (could be extended to return one of the
+ SERIAL status indications). */
+
+static long
+read_frame (char *buf,
+ long sizeof_buf)
+{
+ unsigned char csum;
+ long bc;
+ int c;
+
+ csum = 0;
+ bc = 0;
+
+ while (1)
+ {
+ /* ASSERT (bc < sizeof_buf - 1) - space for trailing NUL */
+ c = readchar (remote_timeout);
+ switch (c)
+ {
+ case SERIAL_TIMEOUT:
+ if (remote_debug)
+ fputs_filtered ("Timeout in mid-packet, retrying\n", gdb_stdlog);
+ return -1;
+ case '$':
+ if (remote_debug)
+ fputs_filtered ("Saw new packet start in middle of old one\n",
+ gdb_stdlog);
+ return -1; /* Start a new packet, count retries */
+ case '#':
+ {
+ unsigned char pktcsum;
+ int check_0 = 0;
+ int check_1 = 0;
+
+ buf[bc] = '\0';
+
+ check_0 = readchar (remote_timeout);
+ if (check_0 >= 0)
+ check_1 = readchar (remote_timeout);
+
+ if (check_0 == SERIAL_TIMEOUT || check_1 == SERIAL_TIMEOUT)
+ {
+ if (remote_debug)
+ fputs_filtered ("Timeout in checksum, retrying\n", gdb_stdlog);
+ return -1;
+ }
+ else if (check_0 < 0 || check_1 < 0)
+ {
+ if (remote_debug)
+ fputs_filtered ("Communication error in checksum\n", gdb_stdlog);
+ return -1;
+ }
+
+ pktcsum = (fromhex (check_0) << 4) | fromhex (check_1);
+ if (csum == pktcsum)
+ return bc;
+
+ if (remote_debug)
+ {
+ fprintf_filtered (gdb_stdlog,
+ "Bad checksum, sentsum=0x%x, csum=0x%x, buf=",
+ pktcsum, csum);
+ fputs_filtered (buf, gdb_stdlog);
+ fputs_filtered ("\n", gdb_stdlog);
+ }
+ /* Number of characters in buffer ignoring trailing
+ NUL. */
+ return -1;
+ }
+ case '*': /* Run length encoding */
+ {
+ int repeat;
+ csum += c;
+
+ if (remote_cisco_mode == 0)
+ {
+ c = readchar (remote_timeout);
+ csum += c;
+ repeat = c - ' ' + 3; /* Compute repeat count */
+ }
+ else
+ {
+ /* Cisco's run-length encoding variant uses two
+ hex chars to represent the repeat count. */
+
+ c = readchar (remote_timeout);
+ csum += c;
+ repeat = fromhex (c) << 4;
+ c = readchar (remote_timeout);
+ csum += c;
+ repeat += fromhex (c);
+ }
+
+ /* The character before ``*'' is repeated. */
+
+ if (repeat > 0 && repeat <= 255
+ && bc > 0
+ && bc + repeat - 1 < sizeof_buf - 1)
+ {
+ memset (&buf[bc], buf[bc - 1], repeat);
+ bc += repeat;
+ continue;
+ }
+
+ buf[bc] = '\0';
+ printf_filtered ("Repeat count %d too large for buffer: ", repeat);
+ puts_filtered (buf);
+ puts_filtered ("\n");
+ return -1;
+ }
+ default:
+ if (bc < sizeof_buf - 1)
+ {
+ buf[bc++] = c;
+ csum += c;
+ continue;
+ }
+
+ buf[bc] = '\0';
+ puts_filtered ("Remote packet too long: ");
+ puts_filtered (buf);
+ puts_filtered ("\n");
+
+ return -1;
+ }
+ }
+}
+
+/* Read a packet from the remote machine, with error checking, and
+ store it in BUF. If FOREVER, wait forever rather than timing out;
+ this is used (in synchronous mode) to wait for a target that is is
+ executing user code to stop. */
+/* FIXME: ezannoni 2000-02-01 this wrapper is necessary so that we
+ don't have to change all the calls to getpkt to deal with the
+ return value, because at the moment I don't know what the right
+ thing to do it for those. */
+void
+getpkt (char *buf,
+ long sizeof_buf,
+ int forever)
+{
+ int timed_out;
+
+ timed_out = getpkt_sane (buf, sizeof_buf, forever);
+}
+
+
+/* Read a packet from the remote machine, with error checking, and
+ store it in BUF. If FOREVER, wait forever rather than timing out;
+ this is used (in synchronous mode) to wait for a target that is is
+ executing user code to stop. If FOREVER == 0, this function is
+ allowed to time out gracefully and return an indication of this to
+ the caller. */
+static int
+getpkt_sane (char *buf,
+ long sizeof_buf,
+ int forever)
+{
+ int c;
+ int tries;
+ int timeout;
+ int val;
+
+ strcpy (buf, "timeout");
+
+ if (forever)
+ {
+ timeout = watchdog > 0 ? watchdog : -1;
+ }
+
+ else
+ timeout = remote_timeout;
+
+#define MAX_TRIES 3
+
+ for (tries = 1; tries <= MAX_TRIES; tries++)
+ {
+ /* This can loop forever if the remote side sends us characters
+ continuously, but if it pauses, we'll get a zero from readchar
+ because of timeout. Then we'll count that as a retry. */
+
+ /* Note that we will only wait forever prior to the start of a packet.
+ After that, we expect characters to arrive at a brisk pace. They
+ should show up within remote_timeout intervals. */
+
+ do
+ {
+ c = readchar (timeout);
+
+ if (c == SERIAL_TIMEOUT)
+ {
+ if (forever) /* Watchdog went off? Kill the target. */
+ {
+ QUIT;
+ target_mourn_inferior ();
+ error ("Watchdog has expired. Target detached.\n");
+ }
+ if (remote_debug)
+ fputs_filtered ("Timed out.\n", gdb_stdlog);
+ goto retry;
+ }
+ }
+ while (c != '$');
+
+ /* We've found the start of a packet, now collect the data. */
+
+ val = read_frame (buf, sizeof_buf);
+
+ if (val >= 0)
+ {
+ if (remote_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Packet received: ");
+ fputstr_unfiltered (buf, 0, gdb_stdlog);
+ fprintf_unfiltered (gdb_stdlog, "\n");
+ }
+ serial_write (remote_desc, "+", 1);
+ return 0;
+ }
+
+ /* Try the whole thing again. */
+ retry:
+ serial_write (remote_desc, "-", 1);
+ }
+
+ /* We have tried hard enough, and just can't receive the packet. Give up. */
+
+ printf_unfiltered ("Ignoring packet error, continuing...\n");
+ serial_write (remote_desc, "+", 1);
+ return 1;
+}
+
+static void
+remote_kill (void)
+{
+ /* For some mysterious reason, wait_for_inferior calls kill instead of
+ mourn after it gets TARGET_WAITKIND_SIGNALLED. Work around it. */
+ if (kill_kludge)
+ {
+ kill_kludge = 0;
+ target_mourn_inferior ();
+ return;
+ }
+
+ /* Use catch_errors so the user can quit from gdb even when we aren't on
+ speaking terms with the remote system. */
+ catch_errors ((catch_errors_ftype *) putpkt, "k", "", RETURN_MASK_ERROR);
+
+ /* Don't wait for it to die. I'm not really sure it matters whether
+ we do or not. For the existing stubs, kill is a noop. */
+ target_mourn_inferior ();
+}
+
+/* Async version of remote_kill. */
+static void
+remote_async_kill (void)
+{
+ /* Unregister the file descriptor from the event loop. */
+ if (target_is_async_p ())
+ serial_async (remote_desc, NULL, 0);
+
+ /* For some mysterious reason, wait_for_inferior calls kill instead of
+ mourn after it gets TARGET_WAITKIND_SIGNALLED. Work around it. */
+ if (kill_kludge)
+ {
+ kill_kludge = 0;
+ target_mourn_inferior ();
+ return;
+ }
+
+ /* Use catch_errors so the user can quit from gdb even when we aren't on
+ speaking terms with the remote system. */
+ catch_errors ((catch_errors_ftype *) putpkt, "k", "", RETURN_MASK_ERROR);
+
+ /* Don't wait for it to die. I'm not really sure it matters whether
+ we do or not. For the existing stubs, kill is a noop. */
+ target_mourn_inferior ();
+}
+
+static void
+remote_mourn (void)
+{
+ remote_mourn_1 (&remote_ops);
+}
+
+static void
+remote_async_mourn (void)
+{
+ remote_mourn_1 (&remote_async_ops);
+}
+
+static void
+extended_remote_mourn (void)
+{
+ /* We do _not_ want to mourn the target like this; this will
+ remove the extended remote target from the target stack,
+ and the next time the user says "run" it'll fail.
+
+ FIXME: What is the right thing to do here? */
+#if 0
+ remote_mourn_1 (&extended_remote_ops);
+#endif
+}
+
+/* Worker function for remote_mourn. */
+static void
+remote_mourn_1 (struct target_ops *target)
+{
+ unpush_target (target);
+ generic_mourn_inferior ();
+}
+
+/* In the extended protocol we want to be able to do things like
+ "run" and have them basically work as expected. So we need
+ a special create_inferior function.
+
+ FIXME: One day add support for changing the exec file
+ we're debugging, arguments and an environment. */
+
+static void
+extended_remote_create_inferior (char *exec_file, char *args, char **env)
+{
+ /* Rip out the breakpoints; we'll reinsert them after restarting
+ the remote server. */
+ remove_breakpoints ();
+
+ /* Now restart the remote server. */
+ extended_remote_restart ();
+
+ /* Now put the breakpoints back in. This way we're safe if the
+ restart function works via a unix fork on the remote side. */
+ insert_breakpoints ();
+
+ /* Clean up from the last time we were running. */
+ clear_proceed_status ();
+
+ /* Let the remote process run. */
+ proceed (-1, TARGET_SIGNAL_0, 0);
+}
+
+/* Async version of extended_remote_create_inferior. */
+static void
+extended_remote_async_create_inferior (char *exec_file, char *args, char **env)
+{
+ /* Rip out the breakpoints; we'll reinsert them after restarting
+ the remote server. */
+ remove_breakpoints ();
+
+ /* If running asynchronously, register the target file descriptor
+ with the event loop. */
+ if (event_loop_p && target_can_async_p ())
+ target_async (inferior_event_handler, 0);
+
+ /* Now restart the remote server. */
+ extended_remote_restart ();
+
+ /* Now put the breakpoints back in. This way we're safe if the
+ restart function works via a unix fork on the remote side. */
+ insert_breakpoints ();
+
+ /* Clean up from the last time we were running. */
+ clear_proceed_status ();
+
+ /* Let the remote process run. */
+ proceed (-1, TARGET_SIGNAL_0, 0);
+}
+
+
+/* On some machines, e.g. 68k, we may use a different breakpoint instruction
+ than other targets; in those use REMOTE_BREAKPOINT instead of just
+ BREAKPOINT. Also, bi-endian targets may define LITTLE_REMOTE_BREAKPOINT
+ and BIG_REMOTE_BREAKPOINT. If none of these are defined, we just call
+ the standard routines that are in mem-break.c. */
+
+/* FIXME, these ought to be done in a more dynamic fashion. For instance,
+ the choice of breakpoint instruction affects target program design and
+ vice versa, and by making it user-tweakable, the special code here
+ goes away and we need fewer special GDB configurations. */
+
+#if defined (LITTLE_REMOTE_BREAKPOINT) && defined (BIG_REMOTE_BREAKPOINT) && !defined(REMOTE_BREAKPOINT)
+#define REMOTE_BREAKPOINT
+#endif
+
+#ifdef REMOTE_BREAKPOINT
+
+/* If the target isn't bi-endian, just pretend it is. */
+#if !defined (LITTLE_REMOTE_BREAKPOINT) && !defined (BIG_REMOTE_BREAKPOINT)
+#define LITTLE_REMOTE_BREAKPOINT REMOTE_BREAKPOINT
+#define BIG_REMOTE_BREAKPOINT REMOTE_BREAKPOINT
+#endif
+
+static unsigned char big_break_insn[] = BIG_REMOTE_BREAKPOINT;
+static unsigned char little_break_insn[] = LITTLE_REMOTE_BREAKPOINT;
+
+#endif /* REMOTE_BREAKPOINT */
+
+/* Insert a breakpoint on targets that don't have any better breakpoint
+ support. We read the contents of the target location and stash it,
+ then overwrite it with a breakpoint instruction. ADDR is the target
+ location in the target machine. CONTENTS_CACHE is a pointer to
+ memory allocated for saving the target contents. It is guaranteed
+ by the caller to be long enough to save sizeof BREAKPOINT bytes (this
+ is accomplished via BREAKPOINT_MAX). */
+
+static int
+remote_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ struct remote_state *rs = get_remote_state ();
+#ifdef REMOTE_BREAKPOINT
+ int val;
+#endif
+ int bp_size;
+
+ /* Try the "Z" s/w breakpoint packet if it is not already disabled.
+ If it succeeds, then set the support to PACKET_ENABLE. If it
+ fails, and the user has explicitly requested the Z support then
+ report an error, otherwise, mark it disabled and go on. */
+
+ if (remote_protocol_Z[Z_PACKET_SOFTWARE_BP].support != PACKET_DISABLE)
+ {
+ char *buf = alloca (rs->remote_packet_size);
+ char *p = buf;
+
+ addr = remote_address_masked (addr);
+ *(p++) = 'Z';
+ *(p++) = '0';
+ *(p++) = ',';
+ p += hexnumstr (p, (ULONGEST) addr);
+ BREAKPOINT_FROM_PC (&addr, &bp_size);
+ sprintf (p, ",%d", bp_size);
+
+ putpkt (buf);
+ getpkt (buf, (rs->remote_packet_size), 0);
+
+ switch (packet_ok (buf, &remote_protocol_Z[Z_PACKET_SOFTWARE_BP]))
+ {
+ case PACKET_ERROR:
+ return -1;
+ case PACKET_OK:
+ return 0;
+ case PACKET_UNKNOWN:
+ break;
+ }
+ }
+
+#ifdef REMOTE_BREAKPOINT
+ val = target_read_memory (addr, contents_cache, sizeof big_break_insn);
+
+ if (val == 0)
+ {
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ val = target_write_memory (addr, (char *) big_break_insn,
+ sizeof big_break_insn);
+ else
+ val = target_write_memory (addr, (char *) little_break_insn,
+ sizeof little_break_insn);
+ }
+
+ return val;
+#else
+ return memory_insert_breakpoint (addr, contents_cache);
+#endif /* REMOTE_BREAKPOINT */
+}
+
+static int
+remote_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ struct remote_state *rs = get_remote_state ();
+ int bp_size;
+
+ if (remote_protocol_Z[Z_PACKET_SOFTWARE_BP].support != PACKET_DISABLE)
+ {
+ char *buf = alloca (rs->remote_packet_size);
+ char *p = buf;
+
+ *(p++) = 'z';
+ *(p++) = '0';
+ *(p++) = ',';
+
+ addr = remote_address_masked (addr);
+ p += hexnumstr (p, (ULONGEST) addr);
+ BREAKPOINT_FROM_PC (&addr, &bp_size);
+ sprintf (p, ",%d", bp_size);
+
+ putpkt (buf);
+ getpkt (buf, (rs->remote_packet_size), 0);
+
+ return (buf[0] == 'E');
+ }
+
+#ifdef REMOTE_BREAKPOINT
+ return target_write_memory (addr, contents_cache, sizeof big_break_insn);
+#else
+ return memory_remove_breakpoint (addr, contents_cache);
+#endif /* REMOTE_BREAKPOINT */
+}
+
+static int
+watchpoint_to_Z_packet (int type)
+{
+ switch (type)
+ {
+ case hw_write:
+ return 2;
+ break;
+ case hw_read:
+ return 3;
+ break;
+ case hw_access:
+ return 4;
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "hw_bp_to_z: bad watchpoint type %d", type);
+ }
+}
+
+/* FIXME: This function should be static and a member of the remote
+ target vector. */
+
+int
+remote_insert_watchpoint (CORE_ADDR addr, int len, int type)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+ char *p;
+ enum Z_packet_type packet = watchpoint_to_Z_packet (type);
+
+ if (remote_protocol_Z[packet].support == PACKET_DISABLE)
+ error ("Can't set hardware watchpoints without the '%s' (%s) packet\n",
+ remote_protocol_Z[packet].name,
+ remote_protocol_Z[packet].title);
+
+ sprintf (buf, "Z%x,", packet);
+ p = strchr (buf, '\0');
+ addr = remote_address_masked (addr);
+ p += hexnumstr (p, (ULONGEST) addr);
+ sprintf (p, ",%x", len);
+
+ putpkt (buf);
+ getpkt (buf, (rs->remote_packet_size), 0);
+
+ switch (packet_ok (buf, &remote_protocol_Z[packet]))
+ {
+ case PACKET_ERROR:
+ case PACKET_UNKNOWN:
+ return -1;
+ case PACKET_OK:
+ return 0;
+ }
+ internal_error (__FILE__, __LINE__,
+ "remote_insert_watchpoint: reached end of function");
+}
+
+/* FIXME: This function should be static and a member of the remote
+ target vector. */
+
+int
+remote_remove_watchpoint (CORE_ADDR addr, int len, int type)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+ char *p;
+ enum Z_packet_type packet = watchpoint_to_Z_packet (type);
+
+ if (remote_protocol_Z[packet].support == PACKET_DISABLE)
+ error ("Can't clear hardware watchpoints without the '%s' (%s) packet\n",
+ remote_protocol_Z[packet].name,
+ remote_protocol_Z[packet].title);
+
+ sprintf (buf, "z%x,", packet);
+ p = strchr (buf, '\0');
+ addr = remote_address_masked (addr);
+ p += hexnumstr (p, (ULONGEST) addr);
+ sprintf (p, ",%x", len);
+ putpkt (buf);
+ getpkt (buf, (rs->remote_packet_size), 0);
+
+ switch (packet_ok (buf, &remote_protocol_Z[packet]))
+ {
+ case PACKET_ERROR:
+ case PACKET_UNKNOWN:
+ return -1;
+ case PACKET_OK:
+ return 0;
+ }
+ internal_error (__FILE__, __LINE__,
+ "remote_remove_watchpoint: reached end of function");
+}
+
+/* FIXME: This function should be static and a member of the remote
+ target vector. */
+
+int
+remote_insert_hw_breakpoint (CORE_ADDR addr, int len)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+ char *p = buf;
+
+ if (remote_protocol_Z[Z_PACKET_HARDWARE_BP].support == PACKET_DISABLE)
+ error ("Can't set hardware breakpoint without the '%s' (%s) packet\n",
+ remote_protocol_Z[Z_PACKET_HARDWARE_BP].name,
+ remote_protocol_Z[Z_PACKET_HARDWARE_BP].title);
+
+ *(p++) = 'Z';
+ *(p++) = '1';
+ *(p++) = ',';
+
+ addr = remote_address_masked (addr);
+ p += hexnumstr (p, (ULONGEST) addr);
+ sprintf (p, ",%x", len);
+
+ putpkt (buf);
+ getpkt (buf, (rs->remote_packet_size), 0);
+
+ switch (packet_ok (buf, &remote_protocol_Z[Z_PACKET_HARDWARE_BP]))
+ {
+ case PACKET_ERROR:
+ case PACKET_UNKNOWN:
+ return -1;
+ case PACKET_OK:
+ return 0;
+ }
+ internal_error (__FILE__, __LINE__,
+ "remote_remove_watchpoint: reached end of function");
+}
+
+/* FIXME: This function should be static and a member of the remote
+ target vector. */
+
+int
+remote_remove_hw_breakpoint (CORE_ADDR addr, int len)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+ char *p = buf;
+
+ if (remote_protocol_Z[Z_PACKET_HARDWARE_BP].support == PACKET_DISABLE)
+ error ("Can't clear hardware breakpoint without the '%s' (%s) packet\n",
+ remote_protocol_Z[Z_PACKET_HARDWARE_BP].name,
+ remote_protocol_Z[Z_PACKET_HARDWARE_BP].title);
+
+ *(p++) = 'z';
+ *(p++) = '1';
+ *(p++) = ',';
+
+ addr = remote_address_masked (addr);
+ p += hexnumstr (p, (ULONGEST) addr);
+ sprintf (p, ",%x", len);
+
+ putpkt(buf);
+ getpkt (buf, (rs->remote_packet_size), 0);
+
+ switch (packet_ok (buf, &remote_protocol_Z[Z_PACKET_HARDWARE_BP]))
+ {
+ case PACKET_ERROR:
+ case PACKET_UNKNOWN:
+ return -1;
+ case PACKET_OK:
+ return 0;
+ }
+ internal_error (__FILE__, __LINE__,
+ "remote_remove_watchpoint: reached end of function");
+}
+
+/* Some targets are only capable of doing downloads, and afterwards
+ they switch to the remote serial protocol. This function provides
+ a clean way to get from the download target to the remote target.
+ It's basically just a wrapper so that we don't have to expose any
+ of the internal workings of remote.c.
+
+ Prior to calling this routine, you should shutdown the current
+ target code, else you will get the "A program is being debugged
+ already..." message. Usually a call to pop_target() suffices. */
+
+void
+push_remote_target (char *name, int from_tty)
+{
+ printf_filtered ("Switching to remote protocol\n");
+ remote_open (name, from_tty);
+}
+
+/* Other targets want to use the entire remote serial module but with
+ certain remote_ops overridden. */
+
+void
+open_remote_target (char *name, int from_tty, struct target_ops *target,
+ int extended_p)
+{
+ printf_filtered ("Selecting the %sremote protocol\n",
+ (extended_p ? "extended-" : ""));
+ remote_open_1 (name, from_tty, target, extended_p);
+}
+
+/* Table used by the crc32 function to calcuate the checksum. */
+
+static unsigned long crc32_table[256] =
+{0, 0};
+
+static unsigned long
+crc32 (unsigned char *buf, int len, unsigned int crc)
+{
+ if (!crc32_table[1])
+ {
+ /* Initialize the CRC table and the decoding table. */
+ int i, j;
+ unsigned int c;
+
+ for (i = 0; i < 256; i++)
+ {
+ for (c = i << 24, j = 8; j > 0; --j)
+ c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
+ crc32_table[i] = c;
+ }
+ }
+
+ while (len--)
+ {
+ crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
+ buf++;
+ }
+ return crc;
+}
+
+/* compare-sections command
+
+ With no arguments, compares each loadable section in the exec bfd
+ with the same memory range on the target, and reports mismatches.
+ Useful for verifying the image on the target against the exec file.
+ Depends on the target understanding the new "qCRC:" request. */
+
+/* FIXME: cagney/1999-10-26: This command should be broken down into a
+ target method (target verify memory) and generic version of the
+ actual command. This will allow other high-level code (especially
+ generic_load()) to make use of this target functionality. */
+
+static void
+compare_sections_command (char *args, int from_tty)
+{
+ struct remote_state *rs = get_remote_state ();
+ asection *s;
+ unsigned long host_crc, target_crc;
+ extern bfd *exec_bfd;
+ struct cleanup *old_chain;
+ char *tmp;
+ char *sectdata;
+ const char *sectname;
+ char *buf = alloca (rs->remote_packet_size);
+ bfd_size_type size;
+ bfd_vma lma;
+ int matched = 0;
+ int mismatched = 0;
+
+ if (!exec_bfd)
+ error ("command cannot be used without an exec file");
+ if (!current_target.to_shortname ||
+ strcmp (current_target.to_shortname, "remote") != 0)
+ error ("command can only be used with remote target");
+
+ for (s = exec_bfd->sections; s; s = s->next)
+ {
+ if (!(s->flags & SEC_LOAD))
+ continue; /* skip non-loadable section */
+
+ size = bfd_get_section_size_before_reloc (s);
+ if (size == 0)
+ continue; /* skip zero-length section */
+
+ sectname = bfd_get_section_name (exec_bfd, s);
+ if (args && strcmp (args, sectname) != 0)
+ continue; /* not the section selected by user */
+
+ matched = 1; /* do this section */
+ lma = s->lma;
+ /* FIXME: assumes lma can fit into long */
+ sprintf (buf, "qCRC:%lx,%lx", (long) lma, (long) size);
+ putpkt (buf);
+
+ /* be clever; compute the host_crc before waiting for target reply */
+ sectdata = xmalloc (size);
+ old_chain = make_cleanup (xfree, sectdata);
+ bfd_get_section_contents (exec_bfd, s, sectdata, 0, size);
+ host_crc = crc32 ((unsigned char *) sectdata, size, 0xffffffff);
+
+ getpkt (buf, (rs->remote_packet_size), 0);
+ if (buf[0] == 'E')
+ error ("target memory fault, section %s, range 0x%s -- 0x%s",
+ sectname, paddr (lma), paddr (lma + size));
+ if (buf[0] != 'C')
+ error ("remote target does not support this operation");
+
+ for (target_crc = 0, tmp = &buf[1]; *tmp; tmp++)
+ target_crc = target_crc * 16 + fromhex (*tmp);
+
+ printf_filtered ("Section %s, range 0x%s -- 0x%s: ",
+ sectname, paddr (lma), paddr (lma + size));
+ if (host_crc == target_crc)
+ printf_filtered ("matched.\n");
+ else
+ {
+ printf_filtered ("MIS-MATCHED!\n");
+ mismatched++;
+ }
+
+ do_cleanups (old_chain);
+ }
+ if (mismatched > 0)
+ warning ("One or more sections of the remote executable does not match\n\
+the loaded file\n");
+ if (args && !matched)
+ printf_filtered ("No loaded section named '%s'.\n", args);
+}
+
+static int
+remote_query (int query_type, char *buf, char *outbuf, int *bufsiz)
+{
+ struct remote_state *rs = get_remote_state ();
+ int i;
+ char *buf2 = alloca (rs->remote_packet_size);
+ char *p2 = &buf2[0];
+
+ if (!bufsiz)
+ error ("null pointer to remote bufer size specified");
+
+ /* minimum outbuf size is (rs->remote_packet_size) - if bufsiz is not large enough let
+ the caller know and return what the minimum size is */
+ /* Note: a zero bufsiz can be used to query the minimum buffer size */
+ if (*bufsiz < (rs->remote_packet_size))
+ {
+ *bufsiz = (rs->remote_packet_size);
+ return -1;
+ }
+
+ /* except for querying the minimum buffer size, target must be open */
+ if (!remote_desc)
+ error ("remote query is only available after target open");
+
+ /* we only take uppercase letters as query types, at least for now */
+ if ((query_type < 'A') || (query_type > 'Z'))
+ error ("invalid remote query type");
+
+ if (!buf)
+ error ("null remote query specified");
+
+ if (!outbuf)
+ error ("remote query requires a buffer to receive data");
+
+ outbuf[0] = '\0';
+
+ *p2++ = 'q';
+ *p2++ = query_type;
+
+ /* we used one buffer char for the remote protocol q command and another
+ for the query type. As the remote protocol encapsulation uses 4 chars
+ plus one extra in case we are debugging (remote_debug),
+ we have PBUFZIZ - 7 left to pack the query string */
+ i = 0;
+ while (buf[i] && (i < ((rs->remote_packet_size) - 8)))
+ {
+ /* bad caller may have sent forbidden characters */
+ if ((!isprint (buf[i])) || (buf[i] == '$') || (buf[i] == '#'))
+ error ("illegal characters in query string");
+
+ *p2++ = buf[i];
+ i++;
+ }
+ *p2 = buf[i];
+
+ if (buf[i])
+ error ("query larger than available buffer");
+
+ i = putpkt (buf2);
+ if (i < 0)
+ return i;
+
+ getpkt (outbuf, *bufsiz, 0);
+
+ return 0;
+}
+
+static void
+remote_rcmd (char *command,
+ struct ui_file *outbuf)
+{
+ struct remote_state *rs = get_remote_state ();
+ int i;
+ char *buf = alloca (rs->remote_packet_size);
+ char *p = buf;
+
+ if (!remote_desc)
+ error ("remote rcmd is only available after target open");
+
+ /* Send a NULL command across as an empty command */
+ if (command == NULL)
+ command = "";
+
+ /* The query prefix */
+ strcpy (buf, "qRcmd,");
+ p = strchr (buf, '\0');
+
+ if ((strlen (buf) + strlen (command) * 2 + 8/*misc*/) > (rs->remote_packet_size))
+ error ("\"monitor\" command ``%s'' is too long\n", command);
+
+ /* Encode the actual command */
+ bin2hex (command, p, 0);
+
+ if (putpkt (buf) < 0)
+ error ("Communication problem with target\n");
+
+ /* get/display the response */
+ while (1)
+ {
+ /* XXX - see also tracepoint.c:remote_get_noisy_reply() */
+ buf[0] = '\0';
+ getpkt (buf, (rs->remote_packet_size), 0);
+ if (buf[0] == '\0')
+ error ("Target does not support this command\n");
+ if (buf[0] == 'O' && buf[1] != 'K')
+ {
+ remote_console_output (buf + 1); /* 'O' message from stub */
+ continue;
+ }
+ if (strcmp (buf, "OK") == 0)
+ break;
+ if (strlen (buf) == 3 && buf[0] == 'E'
+ && isdigit (buf[1]) && isdigit (buf[2]))
+ {
+ error ("Protocol error with Rcmd");
+ }
+ for (p = buf; p[0] != '\0' && p[1] != '\0'; p += 2)
+ {
+ char c = (fromhex (p[0]) << 4) + fromhex (p[1]);
+ fputc_unfiltered (c, outbuf);
+ }
+ break;
+ }
+}
+
+static void
+packet_command (char *args, int from_tty)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+
+ if (!remote_desc)
+ error ("command can only be used with remote target");
+
+ if (!args)
+ error ("remote-packet command requires packet text as argument");
+
+ puts_filtered ("sending: ");
+ print_packet (args);
+ puts_filtered ("\n");
+ putpkt (args);
+
+ getpkt (buf, (rs->remote_packet_size), 0);
+ puts_filtered ("received: ");
+ print_packet (buf);
+ puts_filtered ("\n");
+}
+
+#if 0
+/* --------- UNIT_TEST for THREAD oriented PACKETS ------------------------- */
+
+static void display_thread_info (struct gdb_ext_thread_info *info);
+
+static void threadset_test_cmd (char *cmd, int tty);
+
+static void threadalive_test (char *cmd, int tty);
+
+static void threadlist_test_cmd (char *cmd, int tty);
+
+int get_and_display_threadinfo (threadref * ref);
+
+static void threadinfo_test_cmd (char *cmd, int tty);
+
+static int thread_display_step (threadref * ref, void *context);
+
+static void threadlist_update_test_cmd (char *cmd, int tty);
+
+static void init_remote_threadtests (void);
+
+#define SAMPLE_THREAD 0x05060708 /* Truncated 64 bit threadid */
+
+static void
+threadset_test_cmd (char *cmd, int tty)
+{
+ int sample_thread = SAMPLE_THREAD;
+
+ printf_filtered ("Remote threadset test\n");
+ set_thread (sample_thread, 1);
+}
+
+
+static void
+threadalive_test (char *cmd, int tty)
+{
+ int sample_thread = SAMPLE_THREAD;
+
+ if (remote_thread_alive (pid_to_ptid (sample_thread)))
+ printf_filtered ("PASS: Thread alive test\n");
+ else
+ printf_filtered ("FAIL: Thread alive test\n");
+}
+
+void output_threadid (char *title, threadref * ref);
+
+void
+output_threadid (char *title, threadref *ref)
+{
+ char hexid[20];
+
+ pack_threadid (&hexid[0], ref); /* Convert threead id into hex */
+ hexid[16] = 0;
+ printf_filtered ("%s %s\n", title, (&hexid[0]));
+}
+
+static void
+threadlist_test_cmd (char *cmd, int tty)
+{
+ int startflag = 1;
+ threadref nextthread;
+ int done, result_count;
+ threadref threadlist[3];
+
+ printf_filtered ("Remote Threadlist test\n");
+ if (!remote_get_threadlist (startflag, &nextthread, 3, &done,
+ &result_count, &threadlist[0]))
+ printf_filtered ("FAIL: threadlist test\n");
+ else
+ {
+ threadref *scan = threadlist;
+ threadref *limit = scan + result_count;
+
+ while (scan < limit)
+ output_threadid (" thread ", scan++);
+ }
+}
+
+void
+display_thread_info (struct gdb_ext_thread_info *info)
+{
+ output_threadid ("Threadid: ", &info->threadid);
+ printf_filtered ("Name: %s\n ", info->shortname);
+ printf_filtered ("State: %s\n", info->display);
+ printf_filtered ("other: %s\n\n", info->more_display);
+}
+
+int
+get_and_display_threadinfo (threadref *ref)
+{
+ int result;
+ int set;
+ struct gdb_ext_thread_info threadinfo;
+
+ set = TAG_THREADID | TAG_EXISTS | TAG_THREADNAME
+ | TAG_MOREDISPLAY | TAG_DISPLAY;
+ if (0 != (result = remote_get_threadinfo (ref, set, &threadinfo)))
+ display_thread_info (&threadinfo);
+ return result;
+}
+
+static void
+threadinfo_test_cmd (char *cmd, int tty)
+{
+ int athread = SAMPLE_THREAD;
+ threadref thread;
+ int set;
+
+ int_to_threadref (&thread, athread);
+ printf_filtered ("Remote Threadinfo test\n");
+ if (!get_and_display_threadinfo (&thread))
+ printf_filtered ("FAIL cannot get thread info\n");
+}
+
+static int
+thread_display_step (threadref *ref, void *context)
+{
+ /* output_threadid(" threadstep ",ref); *//* simple test */
+ return get_and_display_threadinfo (ref);
+}
+
+static void
+threadlist_update_test_cmd (char *cmd, int tty)
+{
+ printf_filtered ("Remote Threadlist update test\n");
+ remote_threadlist_iterator (thread_display_step, 0, CRAZY_MAX_THREADS);
+}
+
+static void
+init_remote_threadtests (void)
+{
+ add_com ("tlist", class_obscure, threadlist_test_cmd,
+ "Fetch and print the remote list of thread identifiers, one pkt only");
+ add_com ("tinfo", class_obscure, threadinfo_test_cmd,
+ "Fetch and display info about one thread");
+ add_com ("tset", class_obscure, threadset_test_cmd,
+ "Test setting to a different thread");
+ add_com ("tupd", class_obscure, threadlist_update_test_cmd,
+ "Iterate through updating all remote thread info");
+ add_com ("talive", class_obscure, threadalive_test,
+ " Remote thread alive test ");
+}
+
+#endif /* 0 */
+
+/* Convert a thread ID to a string. Returns the string in a static
+ buffer. */
+
+static char *
+remote_pid_to_str (ptid_t ptid)
+{
+ static char buf[30];
+
+ sprintf (buf, "Thread %d", PIDGET (ptid));
+ return buf;
+}
+
+static void
+init_remote_ops (void)
+{
+ remote_ops.to_shortname = "remote";
+ remote_ops.to_longname = "Remote serial target in gdb-specific protocol";
+ remote_ops.to_doc =
+ "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
+Specify the serial device it is connected to\n\
+(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).";
+ remote_ops.to_open = remote_open;
+ remote_ops.to_close = remote_close;
+ remote_ops.to_detach = remote_detach;
+ remote_ops.to_resume = remote_resume;
+ remote_ops.to_wait = remote_wait;
+ remote_ops.to_fetch_registers = remote_fetch_registers;
+ remote_ops.to_store_registers = remote_store_registers;
+ remote_ops.to_prepare_to_store = remote_prepare_to_store;
+ remote_ops.to_xfer_memory = remote_xfer_memory;
+ remote_ops.to_files_info = remote_files_info;
+ remote_ops.to_insert_breakpoint = remote_insert_breakpoint;
+ remote_ops.to_remove_breakpoint = remote_remove_breakpoint;
+ remote_ops.to_kill = remote_kill;
+ remote_ops.to_load = generic_load;
+ remote_ops.to_mourn_inferior = remote_mourn;
+ remote_ops.to_thread_alive = remote_thread_alive;
+ remote_ops.to_find_new_threads = remote_threads_info;
+ remote_ops.to_pid_to_str = remote_pid_to_str;
+ remote_ops.to_extra_thread_info = remote_threads_extra_info;
+ remote_ops.to_stop = remote_stop;
+ remote_ops.to_query = remote_query;
+ remote_ops.to_rcmd = remote_rcmd;
+ remote_ops.to_stratum = process_stratum;
+ remote_ops.to_has_all_memory = 1;
+ remote_ops.to_has_memory = 1;
+ remote_ops.to_has_stack = 1;
+ remote_ops.to_has_registers = 1;
+ remote_ops.to_has_execution = 1;
+ remote_ops.to_has_thread_control = tc_schedlock; /* can lock scheduler */
+ remote_ops.to_magic = OPS_MAGIC;
+}
+
+/* Set up the extended remote vector by making a copy of the standard
+ remote vector and adding to it. */
+
+static void
+init_extended_remote_ops (void)
+{
+ extended_remote_ops = remote_ops;
+
+ extended_remote_ops.to_shortname = "extended-remote";
+ extended_remote_ops.to_longname =
+ "Extended remote serial target in gdb-specific protocol";
+ extended_remote_ops.to_doc =
+ "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).",
+ extended_remote_ops.to_open = extended_remote_open;
+ extended_remote_ops.to_create_inferior = extended_remote_create_inferior;
+ extended_remote_ops.to_mourn_inferior = extended_remote_mourn;
+}
+
+/*
+ * Command: info remote-process
+ *
+ * This implements Cisco's version of the "info proc" command.
+ *
+ * This query allows the target stub to return an arbitrary string
+ * (or strings) giving arbitrary information about the target process.
+ * This is optional; the target stub isn't required to implement it.
+ *
+ * Syntax: qfProcessInfo request first string
+ * qsProcessInfo request subsequent string
+ * reply: 'O'<hex-encoded-string>
+ * 'l' last reply (empty)
+ */
+
+static void
+remote_info_process (char *args, int from_tty)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *buf = alloca (rs->remote_packet_size);
+
+ if (remote_desc == 0)
+ error ("Command can only be used when connected to the remote target.");
+
+ putpkt ("qfProcessInfo");
+ getpkt (buf, (rs->remote_packet_size), 0);
+ if (buf[0] == 0)
+ return; /* Silently: target does not support this feature. */
+
+ if (buf[0] == 'E')
+ error ("info proc: target error.");
+
+ while (buf[0] == 'O') /* Capitol-O packet */
+ {
+ remote_console_output (&buf[1]);
+ putpkt ("qsProcessInfo");
+ getpkt (buf, (rs->remote_packet_size), 0);
+ }
+}
+
+/*
+ * Target Cisco
+ */
+
+static void
+remote_cisco_open (char *name, int from_tty)
+{
+ int ex;
+ if (name == 0)
+ error ("To open a remote debug connection, you need to specify what \n"
+ "device is attached to the remote system (e.g. host:port).");
+
+ /* See FIXME above */
+ wait_forever_enabled_p = 1;
+
+ target_preopen (from_tty);
+
+ unpush_target (&remote_cisco_ops);
+
+ remote_desc = remote_serial_open (name);
+ if (!remote_desc)
+ perror_with_name (name);
+
+ /*
+ * If a baud rate was specified on the gdb command line it will
+ * be greater than the initial value of -1. If it is, use it otherwise
+ * default to 9600
+ */
+
+ baud_rate = (baud_rate > 0) ? baud_rate : 9600;
+ if (serial_setbaudrate (remote_desc, baud_rate))
+ {
+ serial_close (remote_desc);
+ perror_with_name (name);
+ }
+
+ serial_raw (remote_desc);
+
+ /* If there is something sitting in the buffer we might take it as a
+ response to a command, which would be bad. */
+ serial_flush_input (remote_desc);
+
+ if (from_tty)
+ {
+ puts_filtered ("Remote debugging using ");
+ puts_filtered (name);
+ puts_filtered ("\n");
+ }
+
+ remote_cisco_mode = 1;
+
+ push_target (&remote_cisco_ops); /* Switch to using cisco target now */
+
+ init_all_packet_configs ();
+
+ general_thread = -2;
+ continue_thread = -2;
+
+ /* Probe for ability to use "ThreadInfo" query, as required. */
+ use_threadinfo_query = 1;
+ use_threadextra_query = 1;
+
+ /* Without this, some commands which require an active target (such
+ as kill) won't work. This variable serves (at least) double duty
+ as both the pid of the target process (if it has such), and as a
+ flag indicating that a target is active. These functions should
+ be split out into seperate variables, especially since GDB will
+ someday have a notion of debugging several processes. */
+ inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
+
+ /* Start the remote connection; if error, discard this target. See
+ the comments in remote_open_1() for further details such as the
+ need to re-throw the exception. */
+ ex = catch_exceptions (uiout,
+ remote_start_remote_dummy, NULL,
+ "Couldn't establish connection to remote"
+ " target\n",
+ RETURN_MASK_ALL);
+ if (ex < 0)
+ {
+ pop_target ();
+ throw_exception (ex);
+ }
+}
+
+static void
+remote_cisco_close (int quitting)
+{
+ remote_cisco_mode = 0;
+ remote_close (quitting);
+}
+
+static void
+remote_cisco_mourn (void)
+{
+ remote_mourn_1 (&remote_cisco_ops);
+}
+
+enum
+{
+ READ_MORE,
+ FATAL_ERROR,
+ ENTER_DEBUG,
+ DISCONNECT_TELNET
+}
+minitelnet_return;
+
+/* Shared between readsocket() and readtty(). The size is arbitrary,
+ however all targets are known to support a 400 character packet. */
+static char tty_input[400];
+
+static int escape_count;
+static int echo_check;
+extern int quit_flag;
+
+static int
+readsocket (void)
+{
+ int data;
+
+ /* Loop until the socket doesn't have any more data */
+
+ while ((data = readchar (0)) >= 0)
+ {
+ /* Check for the escape sequence */
+ if (data == '|')
+ {
+ /* If this is the fourth escape, get out */
+ if (++escape_count == 4)
+ {
+ return ENTER_DEBUG;
+ }
+ else
+ { /* This is a '|', but not the fourth in a row.
+ Continue without echoing it. If it isn't actually
+ one of four in a row, it'll be echoed later. */
+ continue;
+ }
+ }
+ else
+ /* Not a '|' */
+ {
+ /* Ensure any pending '|'s are flushed. */
+
+ for (; escape_count > 0; escape_count--)
+ putchar ('|');
+ }
+
+ if (data == '\r') /* If this is a return character, */
+ continue; /* - just supress it. */
+
+ if (echo_check != -1) /* Check for echo of user input. */
+ {
+ if (tty_input[echo_check] == data)
+ {
+ gdb_assert (echo_check <= sizeof (tty_input));
+ echo_check++; /* Character matched user input: */
+ continue; /* Continue without echoing it. */
+ }
+ else if ((data == '\n') && (tty_input[echo_check] == '\r'))
+ { /* End of the line (and of echo checking). */
+ echo_check = -1; /* No more echo supression */
+ continue; /* Continue without echoing. */
+ }
+ else
+ { /* Failed check for echo of user input.
+ We now have some suppressed output to flush! */
+ int j;
+
+ for (j = 0; j < echo_check; j++)
+ putchar (tty_input[j]);
+ echo_check = -1;
+ }
+ }
+ putchar (data); /* Default case: output the char. */
+ }
+
+ if (data == SERIAL_TIMEOUT) /* Timeout returned from readchar. */
+ return READ_MORE; /* Try to read some more */
+ else
+ return FATAL_ERROR; /* Trouble, bail out */
+}
+
+static int
+readtty (void)
+{
+ int tty_bytecount;
+
+ /* First, read a buffer full from the terminal */
+ tty_bytecount = read (fileno (stdin), tty_input, sizeof (tty_input) - 1);
+ if (tty_bytecount == -1)
+ {
+ perror ("readtty: read failed");
+ return FATAL_ERROR;
+ }
+
+ /* Remove a quoted newline. */
+ if (tty_input[tty_bytecount - 1] == '\n' &&
+ tty_input[tty_bytecount - 2] == '\\') /* line ending in backslash */
+ {
+ tty_input[--tty_bytecount] = 0; /* remove newline */
+ tty_input[--tty_bytecount] = 0; /* remove backslash */
+ }
+
+ /* Turn trailing newlines into returns */
+ if (tty_input[tty_bytecount - 1] == '\n')
+ tty_input[tty_bytecount - 1] = '\r';
+
+ /* If the line consists of a ~, enter debugging mode. */
+ if ((tty_input[0] == '~') && (tty_bytecount == 2))
+ return ENTER_DEBUG;
+
+ /* Make this a zero terminated string and write it out */
+ tty_input[tty_bytecount] = 0;
+ if (serial_write (remote_desc, tty_input, tty_bytecount))
+ {
+ perror_with_name ("readtty: write failed");
+ return FATAL_ERROR;
+ }
+
+ return READ_MORE;
+}
+
+static int
+minitelnet (void)
+{
+ fd_set input; /* file descriptors for select */
+ int tablesize; /* max number of FDs for select */
+ int status;
+ int quit_count = 0;
+
+ extern int escape_count; /* global shared by readsocket */
+ extern int echo_check; /* ditto */
+
+ escape_count = 0;
+ echo_check = -1;
+
+ tablesize = 8 * sizeof (input);
+
+ for (;;)
+ {
+ /* Check for anything from our socket - doesn't block. Note that
+ this must be done *before* the select as there may be
+ buffered I/O waiting to be processed. */
+
+ if ((status = readsocket ()) == FATAL_ERROR)
+ {
+ error ("Debugging terminated by communications error");
+ }
+ else if (status != READ_MORE)
+ {
+ return (status);
+ }
+
+ fflush (stdout); /* Flush output before blocking */
+
+ /* Now block on more socket input or TTY input */
+
+ FD_ZERO (&input);
+ FD_SET (fileno (stdin), &input);
+ FD_SET (deprecated_serial_fd (remote_desc), &input);
+
+ status = select (tablesize, &input, 0, 0, 0);
+ if ((status == -1) && (errno != EINTR))
+ {
+ error ("Communications error on select %d", errno);
+ }
+
+ /* Handle Control-C typed */
+
+ if (quit_flag)
+ {
+ if ((++quit_count) == 2)
+ {
+ if (query ("Interrupt GDB? "))
+ {
+ printf_filtered ("Interrupted by user.\n");
+ throw_exception (RETURN_QUIT);
+ }
+ quit_count = 0;
+ }
+ quit_flag = 0;
+
+ if (remote_break)
+ serial_send_break (remote_desc);
+ else
+ serial_write (remote_desc, "\003", 1);
+
+ continue;
+ }
+
+ /* Handle console input */
+
+ if (FD_ISSET (fileno (stdin), &input))
+ {
+ quit_count = 0;
+ echo_check = 0;
+ status = readtty ();
+ if (status == READ_MORE)
+ continue;
+
+ return status; /* telnet session ended */
+ }
+ }
+}
+
+static ptid_t
+remote_cisco_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ if (minitelnet () != ENTER_DEBUG)
+ {
+ error ("Debugging session terminated by protocol error");
+ }
+ putpkt ("?");
+ return remote_wait (ptid, status);
+}
+
+static void
+init_remote_cisco_ops (void)
+{
+ remote_cisco_ops.to_shortname = "cisco";
+ remote_cisco_ops.to_longname = "Remote serial target in cisco-specific protocol";
+ remote_cisco_ops.to_doc =
+ "Use a remote machine via TCP, using a cisco-specific protocol.\n\
+Specify the serial device it is connected to (e.g. host:2020).";
+ remote_cisco_ops.to_open = remote_cisco_open;
+ remote_cisco_ops.to_close = remote_cisco_close;
+ remote_cisco_ops.to_detach = remote_detach;
+ remote_cisco_ops.to_resume = remote_resume;
+ remote_cisco_ops.to_wait = remote_cisco_wait;
+ remote_cisco_ops.to_fetch_registers = remote_fetch_registers;
+ remote_cisco_ops.to_store_registers = remote_store_registers;
+ remote_cisco_ops.to_prepare_to_store = remote_prepare_to_store;
+ remote_cisco_ops.to_xfer_memory = remote_xfer_memory;
+ remote_cisco_ops.to_files_info = remote_files_info;
+ remote_cisco_ops.to_insert_breakpoint = remote_insert_breakpoint;
+ remote_cisco_ops.to_remove_breakpoint = remote_remove_breakpoint;
+ remote_cisco_ops.to_kill = remote_kill;
+ remote_cisco_ops.to_load = generic_load;
+ remote_cisco_ops.to_mourn_inferior = remote_cisco_mourn;
+ remote_cisco_ops.to_thread_alive = remote_thread_alive;
+ remote_cisco_ops.to_find_new_threads = remote_threads_info;
+ remote_cisco_ops.to_pid_to_str = remote_pid_to_str;
+ remote_cisco_ops.to_extra_thread_info = remote_threads_extra_info;
+ remote_cisco_ops.to_stratum = process_stratum;
+ remote_cisco_ops.to_has_all_memory = 1;
+ remote_cisco_ops.to_has_memory = 1;
+ remote_cisco_ops.to_has_stack = 1;
+ remote_cisco_ops.to_has_registers = 1;
+ remote_cisco_ops.to_has_execution = 1;
+ remote_cisco_ops.to_magic = OPS_MAGIC;
+}
+
+static int
+remote_can_async_p (void)
+{
+ /* We're async whenever the serial device is. */
+ return (current_target.to_async_mask_value) && serial_can_async_p (remote_desc);
+}
+
+static int
+remote_is_async_p (void)
+{
+ /* We're async whenever the serial device is. */
+ return (current_target.to_async_mask_value) && serial_is_async_p (remote_desc);
+}
+
+/* Pass the SERIAL event on and up to the client. One day this code
+ will be able to delay notifying the client of an event until the
+ point where an entire packet has been received. */
+
+static void (*async_client_callback) (enum inferior_event_type event_type, void *context);
+static void *async_client_context;
+static serial_event_ftype remote_async_serial_handler;
+
+static void
+remote_async_serial_handler (struct serial *scb, void *context)
+{
+ /* Don't propogate error information up to the client. Instead let
+ the client find out about the error by querying the target. */
+ async_client_callback (INF_REG_EVENT, async_client_context);
+}
+
+static void
+remote_async (void (*callback) (enum inferior_event_type event_type, void *context), void *context)
+{
+ if (current_target.to_async_mask_value == 0)
+ internal_error (__FILE__, __LINE__,
+ "Calling remote_async when async is masked");
+
+ if (callback != NULL)
+ {
+ serial_async (remote_desc, remote_async_serial_handler, NULL);
+ async_client_callback = callback;
+ async_client_context = context;
+ }
+ else
+ serial_async (remote_desc, NULL, NULL);
+}
+
+/* Target async and target extended-async.
+
+ This are temporary targets, until it is all tested. Eventually
+ async support will be incorporated int the usual 'remote'
+ target. */
+
+static void
+init_remote_async_ops (void)
+{
+ remote_async_ops.to_shortname = "async";
+ remote_async_ops.to_longname = "Remote serial target in async version of the gdb-specific protocol";
+ remote_async_ops.to_doc =
+ "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ remote_async_ops.to_open = remote_async_open;
+ remote_async_ops.to_close = remote_close;
+ remote_async_ops.to_detach = remote_async_detach;
+ remote_async_ops.to_resume = remote_async_resume;
+ remote_async_ops.to_wait = remote_async_wait;
+ remote_async_ops.to_fetch_registers = remote_fetch_registers;
+ remote_async_ops.to_store_registers = remote_store_registers;
+ remote_async_ops.to_prepare_to_store = remote_prepare_to_store;
+ remote_async_ops.to_xfer_memory = remote_xfer_memory;
+ remote_async_ops.to_files_info = remote_files_info;
+ remote_async_ops.to_insert_breakpoint = remote_insert_breakpoint;
+ remote_async_ops.to_remove_breakpoint = remote_remove_breakpoint;
+ remote_async_ops.to_terminal_inferior = remote_async_terminal_inferior;
+ remote_async_ops.to_terminal_ours = remote_async_terminal_ours;
+ remote_async_ops.to_kill = remote_async_kill;
+ remote_async_ops.to_load = generic_load;
+ remote_async_ops.to_mourn_inferior = remote_async_mourn;
+ remote_async_ops.to_thread_alive = remote_thread_alive;
+ remote_async_ops.to_find_new_threads = remote_threads_info;
+ remote_async_ops.to_pid_to_str = remote_pid_to_str;
+ remote_async_ops.to_extra_thread_info = remote_threads_extra_info;
+ remote_async_ops.to_stop = remote_stop;
+ remote_async_ops.to_query = remote_query;
+ remote_async_ops.to_rcmd = remote_rcmd;
+ remote_async_ops.to_stratum = process_stratum;
+ remote_async_ops.to_has_all_memory = 1;
+ remote_async_ops.to_has_memory = 1;
+ remote_async_ops.to_has_stack = 1;
+ remote_async_ops.to_has_registers = 1;
+ remote_async_ops.to_has_execution = 1;
+ remote_async_ops.to_has_thread_control = tc_schedlock; /* can lock scheduler */
+ remote_async_ops.to_can_async_p = remote_can_async_p;
+ remote_async_ops.to_is_async_p = remote_is_async_p;
+ remote_async_ops.to_async = remote_async;
+ remote_async_ops.to_async_mask_value = 1;
+ remote_async_ops.to_magic = OPS_MAGIC;
+}
+
+/* Set up the async extended remote vector by making a copy of the standard
+ remote vector and adding to it. */
+
+static void
+init_extended_async_remote_ops (void)
+{
+ extended_async_remote_ops = remote_async_ops;
+
+ extended_async_remote_ops.to_shortname = "extended-async";
+ extended_async_remote_ops.to_longname =
+ "Extended remote serial target in async gdb-specific protocol";
+ extended_async_remote_ops.to_doc =
+ "Use a remote computer via a serial line, using an async gdb-specific protocol.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).",
+ extended_async_remote_ops.to_open = extended_remote_async_open;
+ extended_async_remote_ops.to_create_inferior = extended_remote_async_create_inferior;
+ extended_async_remote_ops.to_mourn_inferior = extended_remote_mourn;
+}
+
+static void
+set_remote_cmd (char *args, int from_tty)
+{
+}
+
+static void
+show_remote_cmd (char *args, int from_tty)
+{
+
+ show_remote_protocol_Z_packet_cmd (args, from_tty);
+ show_remote_protocol_e_packet_cmd (args, from_tty);
+ show_remote_protocol_E_packet_cmd (args, from_tty);
+ show_remote_protocol_P_packet_cmd (args, from_tty);
+ show_remote_protocol_qSymbol_packet_cmd (args, from_tty);
+ show_remote_protocol_binary_download_cmd (args, from_tty);
+}
+
+static void
+build_remote_gdbarch_data (void)
+{
+ remote_address_size = TARGET_ADDR_BIT;
+}
+
+/* Saved pointer to previous owner of the new_objfile event. */
+static void (*remote_new_objfile_chain) (struct objfile *);
+
+/* Function to be called whenever a new objfile (shlib) is detected. */
+static void
+remote_new_objfile (struct objfile *objfile)
+{
+ if (remote_desc != 0) /* Have a remote connection */
+ {
+ remote_check_symbols (objfile);
+ }
+ /* Call predecessor on chain, if any. */
+ if (remote_new_objfile_chain != 0 &&
+ remote_desc == 0)
+ remote_new_objfile_chain (objfile);
+}
+
+void
+_initialize_remote (void)
+{
+ static struct cmd_list_element *remote_set_cmdlist;
+ static struct cmd_list_element *remote_show_cmdlist;
+ struct cmd_list_element *tmpcmd;
+
+ /* architecture specific data */
+ remote_gdbarch_data_handle = register_gdbarch_data (init_remote_state,
+ free_remote_state);
+
+ /* Old tacky stuff. NOTE: This comes after the remote protocol so
+ that the remote protocol has been initialized. */
+ register_gdbarch_swap (&remote_address_size,
+ sizeof (&remote_address_size), NULL);
+ register_gdbarch_swap (NULL, 0, build_remote_gdbarch_data);
+
+ init_remote_ops ();
+ add_target (&remote_ops);
+
+ init_extended_remote_ops ();
+ add_target (&extended_remote_ops);
+
+ init_remote_async_ops ();
+ add_target (&remote_async_ops);
+
+ init_extended_async_remote_ops ();
+ add_target (&extended_async_remote_ops);
+
+ init_remote_cisco_ops ();
+ add_target (&remote_cisco_ops);
+
+ /* Hook into new objfile notification. */
+ remote_new_objfile_chain = target_new_objfile_hook;
+ target_new_objfile_hook = remote_new_objfile;
+
+#if 0
+ init_remote_threadtests ();
+#endif
+
+ /* set/show remote ... */
+
+ add_prefix_cmd ("remote", class_maintenance, set_remote_cmd, "\
+Remote protocol specific variables\n\
+Configure various remote-protocol specific variables such as\n\
+the packets being used",
+ &remote_set_cmdlist, "set remote ",
+ 0/*allow-unknown*/, &setlist);
+ add_prefix_cmd ("remote", class_maintenance, show_remote_cmd, "\
+Remote protocol specific variables\n\
+Configure various remote-protocol specific variables such as\n\
+the packets being used",
+ &remote_show_cmdlist, "show remote ",
+ 0/*allow-unknown*/, &showlist);
+
+ add_cmd ("compare-sections", class_obscure, compare_sections_command,
+ "Compare section data on target to the exec file.\n\
+Argument is a single section name (default: all loaded sections).",
+ &cmdlist);
+
+ add_cmd ("packet", class_maintenance, packet_command,
+ "Send an arbitrary packet to a remote target.\n\
+ maintenance packet TEXT\n\
+If GDB is talking to an inferior via the GDB serial protocol, then\n\
+this command sends the string TEXT to the inferior, and displays the\n\
+response packet. GDB supplies the initial `$' character, and the\n\
+terminating `#' character and checksum.",
+ &maintenancelist);
+
+ add_show_from_set
+ (add_set_boolean_cmd ("remotebreak", no_class, &remote_break,
+ "Set whether to send break if interrupted.\n",
+ &setlist),
+ &showlist);
+
+ /* Install commands for configuring memory read/write packets. */
+
+ add_cmd ("remotewritesize", no_class, set_memory_write_packet_size,
+ "Set the maximum number of bytes per memory write packet (deprecated).\n",
+ &setlist);
+ add_cmd ("remotewritesize", no_class, show_memory_write_packet_size,
+ "Show the maximum number of bytes per memory write packet (deprecated).\n",
+ &showlist);
+ add_cmd ("memory-write-packet-size", no_class,
+ set_memory_write_packet_size,
+ "Set the maximum number of bytes per memory-write packet.\n"
+ "Specify the number of bytes in a packet or 0 (zero) for the\n"
+ "default packet size. The actual limit is further reduced\n"
+ "dependent on the target. Specify ``fixed'' to disable the\n"
+ "further restriction and ``limit'' to enable that restriction\n",
+ &remote_set_cmdlist);
+ add_cmd ("memory-read-packet-size", no_class,
+ set_memory_read_packet_size,
+ "Set the maximum number of bytes per memory-read packet.\n"
+ "Specify the number of bytes in a packet or 0 (zero) for the\n"
+ "default packet size. The actual limit is further reduced\n"
+ "dependent on the target. Specify ``fixed'' to disable the\n"
+ "further restriction and ``limit'' to enable that restriction\n",
+ &remote_set_cmdlist);
+ add_cmd ("memory-write-packet-size", no_class,
+ show_memory_write_packet_size,
+ "Show the maximum number of bytes per memory-write packet.\n",
+ &remote_show_cmdlist);
+ add_cmd ("memory-read-packet-size", no_class,
+ show_memory_read_packet_size,
+ "Show the maximum number of bytes per memory-read packet.\n",
+ &remote_show_cmdlist);
+
+ add_show_from_set
+ (add_set_cmd ("remoteaddresssize", class_obscure,
+ var_integer, (char *) &remote_address_size,
+ "Set the maximum size of the address (in bits) \
+in a memory packet.\n",
+ &setlist),
+ &showlist);
+
+ add_packet_config_cmd (&remote_protocol_binary_download,
+ "X", "binary-download",
+ set_remote_protocol_binary_download_cmd,
+ show_remote_protocol_binary_download_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 1);
+#if 0
+ /* XXXX - should ``set remotebinarydownload'' be retained for
+ compatibility. */
+ add_show_from_set
+ (add_set_cmd ("remotebinarydownload", no_class,
+ var_boolean, (char *) &remote_binary_download,
+ "Set binary downloads.\n", &setlist),
+ &showlist);
+#endif
+
+ add_info ("remote-process", remote_info_process,
+ "Query the remote system for process info.");
+
+ add_packet_config_cmd (&remote_protocol_qSymbol,
+ "qSymbol", "symbol-lookup",
+ set_remote_protocol_qSymbol_packet_cmd,
+ show_remote_protocol_qSymbol_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+
+ add_packet_config_cmd (&remote_protocol_e,
+ "e", "step-over-range",
+ set_remote_protocol_e_packet_cmd,
+ show_remote_protocol_e_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+ /* Disable by default. The ``e'' packet has nasty interactions with
+ the threading code - it relies on global state. */
+ remote_protocol_e.detect = CMD_AUTO_BOOLEAN_FALSE;
+ update_packet_config (&remote_protocol_e);
+
+ add_packet_config_cmd (&remote_protocol_E,
+ "E", "step-over-range-w-signal",
+ set_remote_protocol_E_packet_cmd,
+ show_remote_protocol_E_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+ /* Disable by default. The ``e'' packet has nasty interactions with
+ the threading code - it relies on global state. */
+ remote_protocol_E.detect = CMD_AUTO_BOOLEAN_FALSE;
+ update_packet_config (&remote_protocol_E);
+
+ add_packet_config_cmd (&remote_protocol_P,
+ "P", "set-register",
+ set_remote_protocol_P_packet_cmd,
+ show_remote_protocol_P_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 1);
+
+ add_packet_config_cmd (&remote_protocol_Z[Z_PACKET_SOFTWARE_BP],
+ "Z0", "software-breakpoint",
+ set_remote_protocol_Z_software_bp_packet_cmd,
+ show_remote_protocol_Z_software_bp_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+
+ add_packet_config_cmd (&remote_protocol_Z[Z_PACKET_HARDWARE_BP],
+ "Z1", "hardware-breakpoint",
+ set_remote_protocol_Z_hardware_bp_packet_cmd,
+ show_remote_protocol_Z_hardware_bp_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+
+ add_packet_config_cmd (&remote_protocol_Z[Z_PACKET_WRITE_WP],
+ "Z2", "write-watchpoint",
+ set_remote_protocol_Z_write_wp_packet_cmd,
+ show_remote_protocol_Z_write_wp_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+
+ add_packet_config_cmd (&remote_protocol_Z[Z_PACKET_READ_WP],
+ "Z3", "read-watchpoint",
+ set_remote_protocol_Z_read_wp_packet_cmd,
+ show_remote_protocol_Z_read_wp_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+
+ add_packet_config_cmd (&remote_protocol_Z[Z_PACKET_ACCESS_WP],
+ "Z4", "access-watchpoint",
+ set_remote_protocol_Z_access_wp_packet_cmd,
+ show_remote_protocol_Z_access_wp_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+
+ /* Keep the old ``set remote Z-packet ...'' working. */
+ tmpcmd = add_set_auto_boolean_cmd ("Z-packet", class_obscure,
+ &remote_Z_packet_detect,
+ "\
+Set use of remote protocol `Z' packets", &remote_set_cmdlist);
+ set_cmd_sfunc (tmpcmd, set_remote_protocol_Z_packet_cmd);
+ add_cmd ("Z-packet", class_obscure, show_remote_protocol_Z_packet_cmd,
+ "Show use of remote protocol `Z' packets ",
+ &remote_show_cmdlist);
+}
diff --git a/gdb/remote.h b/gdb/remote.h
new file mode 100644
index 00000000000..e2171b27efd
--- /dev/null
+++ b/gdb/remote.h
@@ -0,0 +1,57 @@
+/* Remote target communications for serial-line targets in custom GDB protocol
+ Copyright 1999 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. */
+
+#ifndef REMOTE_H
+#define REMOTE_H
+
+/* FIXME?: move this interface down to tgt vector) */
+
+/* Read a packet from the remote machine, with error checking, and
+ store it in BUF. BUF is expected to be of size PBUFSIZ. If
+ FOREVER, wait forever rather than timing out; this is used while
+ the target is executing user code. */
+
+extern void getpkt (char *buf, long sizeof_buf, int forever);
+
+/* Send a packet to the remote machine, with error checking. The data
+ of the packet is in BUF. The string in BUF can be at most PBUFSIZ
+ - 5 to account for the $, # and checksum, and for a possible /0 if
+ we are debugging (remote_debug) and want to print the sent packet
+ as a string */
+
+extern int putpkt (char *buf);
+
+/* Send HEX encoded string to the target console. (gdb_stdtarg) */
+
+extern void remote_console_output (char *);
+
+
+/* FIXME: cagney/1999-09-20: The remote cisco stuff in remote.c needs
+ to be broken out into a separate file (remote-cisco.[hc]?). Before
+ that can happen, a remote protocol stack framework needs to be
+ implemented. */
+
+extern void remote_cisco_objfile_relocate (bfd_signed_vma text_off,
+ bfd_signed_vma data_off,
+ bfd_signed_vma bss_off);
+
+extern void async_remote_interrupt_twice (void *arg);
+
+#endif
diff --git a/gdb/reply_mig_hack.awk b/gdb/reply_mig_hack.awk
new file mode 100644
index 00000000000..85c935d81fe
--- /dev/null
+++ b/gdb/reply_mig_hack.awk
@@ -0,0 +1,123 @@
+# Reply server mig-output massager
+#
+# Copyright 1995, 1996, 1999 Free Software Foundation, Inc.
+#
+# Written by Miles Bader <miles@gnu.ai.mit.edu>
+#
+# 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, 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.
+#
+# This awk script hacks the output of mig-generated reply server code
+# so that it allows replies with just the error-code in them (as this is
+# how mig returns errors).
+#
+# It is highly, highly, dependent on the exact format of mig output. Ick.
+#
+
+BEGIN { parse_phase = 0; }
+
+/^}/ { parse_phase = 0; }
+
+parse_phase == 0 && /^mig_internal void _X[a-zA-Z0-9_]*_reply/ {
+ # The start of a mig server routine. Reset everything. Note that we only
+ # mess with rpcs that have the suffix `_reply'.
+ num_args = 0;
+ num_checks = 0;
+ parse_phase = 1;
+ print; next;
+}
+
+parse_phase == 1 && /^[\t ]*typedef struct/ {
+ # The first structure in the server routine should describe the arguments
+ parse_phase = 2;
+ print; next;
+}
+
+parse_phase == 2 {
+ # The message header field in the args structure, which skip.
+ parse_phase = 3;
+ print; next;
+}
+
+parse_phase == 3 && /}/ {
+ # The args structure is over.
+ if (num_args > 1)
+ parse_phase = 5;
+ else
+ # There's no extra args that could screw up the normal mechanism for
+ # error returns, so we don't have to insert any new code.
+ parse_phase = 0;
+ print; next;
+}
+
+parse_phase == 3 {
+ # The type field for an argument.
+ arg_type_code_name[num_args] = $2;
+ sub (/;$/, "", arg_type_code_name[num_args]) # Get rid of the semi-colon
+ parse_phase = 4;
+ print; next;
+}
+
+parse_phase == 4 {
+ # The value field for an argument.
+ arg_name[num_args] = $2;
+ sub (/;$/, "", arg_name[num_args]) # Get rid of the semi-colon
+ arg_type[num_args] = $1;
+ num_args++;
+ parse_phase = 3;
+ print; next;
+}
+
+parse_phase == 5 && /^[ \t]*static const mach_msg_type_t/ {
+ # The type check structure for an argument.
+ arg_check_name[num_checks] = $4;
+ num_checks++;
+ print; next;
+}
+
+parse_phase == 5 && /^[ \t]*mig_external kern_return_t/ {
+ # The declaration of the user server function for this rpc.
+ user_function_name = $3;
+ print; next;
+}
+
+parse_phase == 5 && /^#if[ \t]TypeCheck/ {
+ # The first args type checking statement; we need to insert our chunk of
+ # code that bypasses all the type checks if this is an error return, after
+ # which we're done until we get to the next function. Handily, the size
+ # of mig's Reply structure is also the size of the alternate Request
+ # structure that we want to check for.
+ print "\tif (In0P->Head.msgh_size == sizeof (Reply)";
+ print "\t && ! (In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)";
+ print "\t && *(int *)&In0P->" arg_type_code_name[0] " == *(int *)&" arg_check_name[0];
+ print "\t && In0P->" arg_name[0] " != 0)";
+ print "\t /* Error return, only the error code argument is passed. */";
+ print "\t {";
+ # Force the function into a type that only takes the first two args, via
+ # the temp variable SFUN (is there another way to correctly do this cast?).
+ # This is possibly bogus, but easier than supplying bogus values for all
+ # the other args (we can't just pass 0 for them, as they might not be scalar).
+ printf ("\t kern_return_t (*sfun)(mach_port_t");
+ for (i = 0; i < num_args; i++)
+ printf (", %s", arg_type[i]);
+ printf (") = %s;\n", user_function_name);
+ print "\t OutP->RetCode = (*(kern_return_t (*)(mach_port_t, kern_return_t))sfun) (In0P->Head.msgh_request_port, In0P->" arg_name[0] ");";
+ print "\t return;";
+ print "\t }";
+ print "";
+ parse_phase = 0;
+ print; next;
+}
+
+{ print; }
diff --git a/gdb/rom68k-rom.c b/gdb/rom68k-rom.c
new file mode 100644
index 00000000000..ec49f5d7177
--- /dev/null
+++ b/gdb/rom68k-rom.c
@@ -0,0 +1,246 @@
+/* Remote target glue for the ROM68K ROM monitor.
+ Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "regcache.h"
+#include "value.h"
+
+static void rom68k_open (char *args, int from_tty);
+
+/* Return true if C is a hex digit.
+ We can't use isxdigit here: that is affected by the current locale;
+ ROM68K is not. */
+static int
+is_hex_digit (int c)
+{
+ return (('0' <= c && c <= '9')
+ || ('a' <= c && c <= 'f')
+ || ('A' <= c && c <= 'F'));
+}
+
+
+/* Convert hex digit A to a number. */
+static int
+hex_digit_value (int a)
+{
+ if (a >= '0' && a <= '9')
+ return a - '0';
+ else if (a >= 'a' && a <= 'f')
+ return a - 'a' + 10;
+ else if (a >= 'A' && a <= 'F')
+ return a - 'A' + 10;
+ else
+ error ("Invalid hex digit %d", a);
+}
+
+
+/* Return true iff C is a whitespace character.
+ We can't use isspace here: that is affected by the current locale;
+ ROM68K is not. */
+static int
+is_whitespace (int c)
+{
+ return (c == ' '
+ || c == '\r'
+ || c == '\n'
+ || c == '\t'
+ || c == '\f');
+}
+
+
+/* Parse a string of hex digits starting at HEX, supply them as the
+ value of register REGNO, skip any whitespace, and return a pointer
+ to the next character.
+
+ There is a function in monitor.c, monitor_supply_register, which is
+ supposed to do this job. However, there is some rather odd stuff
+ in there (whitespace characters don't terminate numbers, for
+ example) that is incorrect for ROM68k. It's basically impossible
+ to safely tweak monitor_supply_register --- it's used by a zillion
+ other monitors; who knows what behaviors they're depending on. So
+ instead, we'll just use our own function, which can behave exactly
+ the way we want it to. */
+static char *
+rom68k_supply_one_register (int regno, unsigned char *hex)
+{
+ ULONGEST value;
+ unsigned char regbuf[MAX_REGISTER_RAW_SIZE];
+
+ value = 0;
+ while (*hex != '\0')
+ if (is_hex_digit (*hex))
+ value = (value * 16) + hex_digit_value (*hex++);
+ else
+ break;
+
+ /* Skip any whitespace. */
+ while (is_whitespace (*hex))
+ hex++;
+
+ store_unsigned_integer (regbuf, REGISTER_RAW_SIZE (regno), value);
+ supply_register (regno, regbuf);
+
+ return hex;
+}
+
+
+static void
+rom68k_supply_register (char *regname, int regnamelen, char *val, int vallen)
+{
+ int numregs;
+ int regno;
+
+ numregs = 1;
+ regno = -1;
+
+ if (regnamelen == 2)
+ switch (regname[0])
+ {
+ case 'S':
+ if (regname[1] == 'R')
+ regno = PS_REGNUM;
+ break;
+ case 'P':
+ if (regname[1] == 'C')
+ regno = PC_REGNUM;
+ break;
+ case 'D':
+ if (regname[1] != 'R')
+ break;
+ regno = D0_REGNUM;
+ numregs = 8;
+ break;
+ case 'A':
+ if (regname[1] != 'R')
+ break;
+ regno = A0_REGNUM;
+ numregs = 7;
+ break;
+ }
+ else if (regnamelen == 3)
+ switch (regname[0])
+ {
+ case 'I':
+ if (regname[1] == 'S' && regname[2] == 'P')
+ regno = SP_REGNUM;
+ }
+
+ if (regno >= 0)
+ while (numregs-- > 0)
+ val = rom68k_supply_one_register (regno++, val);
+}
+
+/* This array of registers need to match the indexes used by GDB.
+ This exists because the various ROM monitors use different strings
+ than does GDB, and don't necessarily support all the registers
+ either. So, typing "info reg sp" becomes a "r30". */
+
+static char *rom68k_regnames[NUM_REGS] =
+{
+ "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
+ "A0", "A1", "A2", "A3", "A4", "A5", "A6", "ISP",
+ "SR", "PC"};
+
+/* Define the monitor command strings. Since these are passed directly
+ through to a printf style function, we may include formatting
+ strings. We also need a CR or LF on the end. */
+
+static struct target_ops rom68k_ops;
+
+static char *rom68k_inits[] =
+{".\r\r", NULL}; /* Exits pm/pr & download cmds */
+
+static struct monitor_ops rom68k_cmds;
+
+static void
+init_rom68k_cmds (void)
+{
+ rom68k_cmds.flags = MO_PRINT_PROGRAM_OUTPUT;
+ rom68k_cmds.init = rom68k_inits; /* monitor init string */
+ rom68k_cmds.cont = "go\r";
+ rom68k_cmds.step = "st\r";
+ rom68k_cmds.stop = NULL;
+ rom68k_cmds.set_break = "db %x\r";
+ rom68k_cmds.clr_break = "cb %x\r";
+ rom68k_cmds.clr_all_break = "cb *\r";
+ rom68k_cmds.fill = "fm %x %x %x\r";
+ rom68k_cmds.setmem.cmdb = "pm %x %x\r";
+ rom68k_cmds.setmem.cmdw = "pm.w %x %x\r";
+ rom68k_cmds.setmem.cmdl = "pm.l %x %x\r";
+ rom68k_cmds.setmem.cmdll = NULL;
+ rom68k_cmds.setmem.resp_delim = NULL;
+ rom68k_cmds.setmem.term = NULL;
+ rom68k_cmds.setmem.term_cmd = NULL;
+ rom68k_cmds.getmem.cmdb = "dm %x %x\r";
+ rom68k_cmds.getmem.cmdw = "dm.w %x %x\r";
+ rom68k_cmds.getmem.cmdl = "dm.l %x %x\r";
+ rom68k_cmds.getmem.cmdll = NULL;
+ rom68k_cmds.getmem.resp_delim = " ";
+ rom68k_cmds.getmem.term = NULL;
+ rom68k_cmds.getmem.term_cmd = NULL;
+ rom68k_cmds.setreg.cmd = "pr %s %x\r";
+ rom68k_cmds.setreg.resp_delim = NULL;
+ rom68k_cmds.setreg.term = NULL;
+ rom68k_cmds.setreg.term_cmd = NULL;
+ rom68k_cmds.getreg.cmd = "pr %s\r";
+ rom68k_cmds.getreg.resp_delim = ": ";
+ rom68k_cmds.getreg.term = "= ";
+ rom68k_cmds.getreg.term_cmd = ".\r";
+ rom68k_cmds.dump_registers = "dr\r";
+ rom68k_cmds.register_pattern =
+ "\\(\\w+\\)=\\([0-9a-fA-F]+\\( +[0-9a-fA-F]+\\b\\)*\\)";
+ rom68k_cmds.supply_register = rom68k_supply_register;
+ rom68k_cmds.load_routine = NULL;
+ rom68k_cmds.load = "dc\r";
+ rom68k_cmds.loadresp = "Waiting for S-records from host... ";
+ rom68k_cmds.prompt = "ROM68K :-> ";
+ rom68k_cmds.line_term = "\r";
+ rom68k_cmds.cmd_end = ".\r";
+ rom68k_cmds.target = &rom68k_ops;
+ rom68k_cmds.stopbits = SERIAL_1_STOPBITS;
+ rom68k_cmds.regnames = rom68k_regnames;
+ rom68k_cmds.magic = MONITOR_OPS_MAGIC;
+} /* init_rom68k_cmds */
+
+static void
+rom68k_open (char *args, int from_tty)
+{
+ monitor_open (args, &rom68k_cmds, from_tty);
+}
+
+void
+_initialize_rom68k (void)
+{
+ init_rom68k_cmds ();
+ init_monitor_ops (&rom68k_ops);
+
+ rom68k_ops.to_shortname = "rom68k";
+ rom68k_ops.to_longname = "Rom68k debug monitor for the IDP Eval board";
+ rom68k_ops.to_doc = "Debug on a Motorola IDP eval board running the ROM68K monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ rom68k_ops.to_open = rom68k_open;
+
+ add_target (&rom68k_ops);
+}
diff --git a/gdb/rs6000-nat.c b/gdb/rs6000-nat.c
new file mode 100644
index 00000000000..8fb2fecf91f
--- /dev/null
+++ b/gdb/rs6000-nat.c
@@ -0,0 +1,1172 @@
+/* IBM RS/6000 native-dependent code for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001, 2002
+ 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 "defs.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "xcoffsolib.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "libbfd.h" /* For bfd_cache_lookup (FIXME) */
+#include "bfd.h"
+#include "gdb-stabs.h"
+#include "regcache.h"
+#include "arch-utils.h"
+
+#include <sys/ptrace.h>
+#include <sys/reg.h>
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <a.out.h>
+#include <sys/file.h>
+#include "gdb_stat.h"
+#include <sys/core.h>
+#define __LDINFO_PTRACE32__ /* for __ld_info32 */
+#define __LDINFO_PTRACE64__ /* for __ld_info64 */
+#include <sys/ldr.h>
+#include <sys/systemcfg.h>
+
+/* On AIX4.3+, sys/ldr.h provides different versions of struct ld_info for
+ debugging 32-bit and 64-bit processes. Define a typedef and macros for
+ accessing fields in the appropriate structures. */
+
+/* In 32-bit compilation mode (which is the only mode from which ptrace()
+ works on 4.3), __ld_info32 is #defined as equivalent to ld_info. */
+
+#ifdef __ld_info32
+# define ARCH3264
+#endif
+
+/* Return whether the current architecture is 64-bit. */
+
+#ifndef ARCH3264
+# define ARCH64() 0
+#else
+# define ARCH64() (REGISTER_RAW_SIZE (0) == 8)
+#endif
+
+/* Union of 32-bit and 64-bit ".reg" core file sections. */
+
+typedef union {
+#ifdef ARCH3264
+ struct __context64 r64;
+#else
+ struct mstsave r64;
+#endif
+ struct mstsave r32;
+} CoreRegs;
+
+/* Union of 32-bit and 64-bit versions of ld_info. */
+
+typedef union {
+#ifndef ARCH3264
+ struct ld_info l32;
+ struct ld_info l64;
+#else
+ struct __ld_info32 l32;
+ struct __ld_info64 l64;
+#endif
+} LdInfo;
+
+/* If compiling with 32-bit and 64-bit debugging capability (e.g. AIX 4.x),
+ declare and initialize a variable named VAR suitable for use as the arch64
+ parameter to the various LDI_*() macros. */
+
+#ifndef ARCH3264
+# define ARCH64_DECL(var)
+#else
+# define ARCH64_DECL(var) int var = ARCH64 ()
+#endif
+
+/* Return LDI's FIELD for a 64-bit process if ARCH64 and for a 32-bit process
+ otherwise. This technique only works for FIELDs with the same data type in
+ 32-bit and 64-bit versions of ld_info. */
+
+#ifndef ARCH3264
+# define LDI_FIELD(ldi, arch64, field) (ldi)->l32.ldinfo_##field
+#else
+# define LDI_FIELD(ldi, arch64, field) \
+ (arch64 ? (ldi)->l64.ldinfo_##field : (ldi)->l32.ldinfo_##field)
+#endif
+
+/* Return various LDI fields for a 64-bit process if ARCH64 and for a 32-bit
+ process otherwise. */
+
+#define LDI_NEXT(ldi, arch64) LDI_FIELD(ldi, arch64, next)
+#define LDI_FD(ldi, arch64) LDI_FIELD(ldi, arch64, fd)
+#define LDI_FILENAME(ldi, arch64) LDI_FIELD(ldi, arch64, filename)
+
+extern struct vmap *map_vmap (bfd * bf, bfd * arch);
+
+extern struct target_ops exec_ops;
+
+static void vmap_exec (void);
+
+static void vmap_ldinfo (LdInfo *);
+
+static struct vmap *add_vmap (LdInfo *);
+
+static int objfile_symbol_add (void *);
+
+static void vmap_symtab (struct vmap *);
+
+static void fetch_core_registers (char *, unsigned int, int, CORE_ADDR);
+
+static void exec_one_dummy_insn (void);
+
+extern void
+fixup_breakpoints (CORE_ADDR low, CORE_ADDR high, CORE_ADDR delta);
+
+/* Conversion from gdb-to-system special purpose register numbers. */
+
+static int special_regs[] =
+{
+ IAR, /* PC_REGNUM */
+ MSR, /* PS_REGNUM */
+ CR, /* CR_REGNUM */
+ LR, /* LR_REGNUM */
+ CTR, /* CTR_REGNUM */
+ XER, /* XER_REGNUM */
+ MQ /* MQ_REGNUM */
+};
+
+/* Call ptrace(REQ, ID, ADDR, DATA, BUF). */
+
+static int
+rs6000_ptrace32 (int req, int id, int *addr, int data, int *buf)
+{
+ int ret = ptrace (req, id, (int *)addr, data, buf);
+#if 0
+ printf ("rs6000_ptrace32 (%d, %d, 0x%x, %08x, 0x%x) = 0x%x\n",
+ req, id, (unsigned int)addr, data, (unsigned int)buf, ret);
+#endif
+ return ret;
+}
+
+/* Call ptracex(REQ, ID, ADDR, DATA, BUF). */
+
+static int
+rs6000_ptrace64 (int req, int id, long long addr, int data, int *buf)
+{
+#ifdef ARCH3264
+ int ret = ptracex (req, id, addr, data, buf);
+#else
+ int ret = 0;
+#endif
+#if 0
+ printf ("rs6000_ptrace64 (%d, %d, 0x%llx, %08x, 0x%x) = 0x%x\n",
+ req, id, addr, data, (unsigned int)buf, ret);
+#endif
+ return ret;
+}
+
+/* Fetch register REGNO from the inferior. */
+
+static void
+fetch_register (int regno)
+{
+ int *addr = (int *) &registers[REGISTER_BYTE (regno)];
+ int nr;
+
+ /* Retrieved values may be -1, so infer errors from errno. */
+ errno = 0;
+
+ /* Floating-point registers. */
+ if (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM)
+ {
+ nr = regno - FP0_REGNUM + FPR0;
+ rs6000_ptrace32 (PT_READ_FPR, PIDGET (inferior_ptid), addr, nr, 0);
+ }
+
+ /* Bogus register number. */
+ else if (regno > LAST_UISA_SP_REGNUM)
+ {
+ if (regno >= NUM_REGS)
+ fprintf_unfiltered (gdb_stderr,
+ "gdb error: register no %d not implemented.\n",
+ regno);
+ }
+
+ /* Fixed-point registers. */
+ else
+ {
+ if (regno >= FIRST_UISA_SP_REGNUM)
+ nr = special_regs[regno - FIRST_UISA_SP_REGNUM];
+ else
+ nr = regno;
+
+ if (!ARCH64 ())
+ *addr = rs6000_ptrace32 (PT_READ_GPR, PIDGET (inferior_ptid), (int *)nr, 0, 0);
+ else
+ {
+ /* PT_READ_GPR requires the buffer parameter to point to long long,
+ even if the register is really only 32 bits. */
+ long long buf;
+ rs6000_ptrace64 (PT_READ_GPR, PIDGET (inferior_ptid), nr, 0, (int *)&buf);
+ if (REGISTER_RAW_SIZE (regno) == 8)
+ memcpy (addr, &buf, 8);
+ else
+ *addr = buf;
+ }
+ }
+
+ if (!errno)
+ register_valid[regno] = 1;
+ else
+ {
+#if 0
+ /* FIXME: this happens 3 times at the start of each 64-bit program. */
+ perror ("ptrace read");
+#endif
+ errno = 0;
+ }
+}
+
+/* Store register REGNO back into the inferior. */
+
+static void
+store_register (int regno)
+{
+ int *addr = (int *) &registers[REGISTER_BYTE (regno)];
+ int nr;
+
+ /* -1 can be a successful return value, so infer errors from errno. */
+ errno = 0;
+
+ /* Floating-point registers. */
+ if (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM)
+ {
+ nr = regno - FP0_REGNUM + FPR0;
+ rs6000_ptrace32 (PT_WRITE_FPR, PIDGET (inferior_ptid), addr, nr, 0);
+ }
+
+ /* Bogus register number. */
+ else if (regno > LAST_UISA_SP_REGNUM)
+ {
+ if (regno >= NUM_REGS)
+ fprintf_unfiltered (gdb_stderr,
+ "gdb error: register no %d not implemented.\n",
+ regno);
+ }
+
+ /* Fixed-point registers. */
+ else
+ {
+ if (regno == SP_REGNUM)
+ /* Execute one dummy instruction (which is a breakpoint) in inferior
+ process to give kernel a chance to do internal housekeeping.
+ Otherwise the following ptrace(2) calls will mess up user stack
+ since kernel will get confused about the bottom of the stack
+ (%sp). */
+ exec_one_dummy_insn ();
+
+ if (regno >= FIRST_UISA_SP_REGNUM)
+ nr = special_regs[regno - FIRST_UISA_SP_REGNUM];
+ else
+ nr = regno;
+
+ if (!ARCH64 ())
+ rs6000_ptrace32 (PT_WRITE_GPR, PIDGET (inferior_ptid), (int *)nr, *addr, 0);
+ else
+ {
+ /* PT_WRITE_GPR requires the buffer parameter to point to an 8-byte
+ area, even if the register is really only 32 bits. */
+ long long buf;
+ if (REGISTER_RAW_SIZE (regno) == 8)
+ memcpy (&buf, addr, 8);
+ else
+ buf = *addr;
+ rs6000_ptrace64 (PT_WRITE_GPR, PIDGET (inferior_ptid), nr, 0, (int *)&buf);
+ }
+ }
+
+ if (errno)
+ {
+ perror ("ptrace write");
+ errno = 0;
+ }
+}
+
+/* Read from the inferior all registers if REGNO == -1 and just register
+ REGNO otherwise. */
+
+void
+fetch_inferior_registers (int regno)
+{
+ if (regno != -1)
+ fetch_register (regno);
+
+ else
+ {
+ /* read 32 general purpose registers. */
+ for (regno = 0; regno < 32; regno++)
+ fetch_register (regno);
+
+ /* read general purpose floating point registers. */
+ for (regno = FP0_REGNUM; regno <= FPLAST_REGNUM; regno++)
+ fetch_register (regno);
+
+ /* read special registers. */
+ for (regno = FIRST_UISA_SP_REGNUM; regno <= LAST_UISA_SP_REGNUM; regno++)
+ fetch_register (regno);
+ }
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ if (regno != -1)
+ store_register (regno);
+
+ else
+ {
+ /* write general purpose registers first! */
+ for (regno = GPR0; regno <= GPR31; regno++)
+ store_register (regno);
+
+ /* write floating point registers now. */
+ for (regno = FP0_REGNUM; regno <= FPLAST_REGNUM; regno++)
+ store_register (regno);
+
+ /* write special registers. */
+
+ for (regno = FIRST_UISA_SP_REGNUM; regno <= LAST_UISA_SP_REGNUM; regno++)
+ store_register (regno);
+ }
+}
+
+/* Store in *TO the 32-bit word at 32-bit-aligned ADDR in the child
+ process, which is 64-bit if ARCH64 and 32-bit otherwise. Return
+ success. */
+
+static int
+read_word (CORE_ADDR from, int *to, int arch64)
+{
+ /* Retrieved values may be -1, so infer errors from errno. */
+ errno = 0;
+
+ if (arch64)
+ *to = rs6000_ptrace64 (PT_READ_I, PIDGET (inferior_ptid), from, 0, NULL);
+ else
+ *to = rs6000_ptrace32 (PT_READ_I, PIDGET (inferior_ptid), (int *)(long) from,
+ 0, NULL);
+
+ return !errno;
+}
+
+/* Copy LEN bytes to or from inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. Copy to inferior if
+ WRITE is nonzero.
+
+ Returns the length copied, which is either the LEN argument or zero.
+ This xfer function does not do partial moves, since child_ops
+ doesn't allow memory operations to cross below us in the target stack
+ anyway. */
+
+int
+child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int write, struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ /* Round starting address down to 32-bit word boundary. */
+ int mask = sizeof (int) - 1;
+ CORE_ADDR addr = memaddr & ~(CORE_ADDR)mask;
+
+ /* Round ending address up to 32-bit word boundary. */
+ int count = ((memaddr + len - addr + mask) & ~(CORE_ADDR)mask)
+ / sizeof (int);
+
+ /* Allocate word transfer buffer. */
+ /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe
+ because it uses alloca to allocate a buffer of arbitrary size.
+ For very large xfers, this could crash GDB's stack. */
+ int *buf = (int *) alloca (count * sizeof (int));
+
+ int arch64 = ARCH64 ();
+ int i;
+
+ if (!write)
+ {
+ /* Retrieve memory a word at a time. */
+ for (i = 0; i < count; i++, addr += sizeof (int))
+ {
+ if (!read_word (addr, buf + i, arch64))
+ return 0;
+ QUIT;
+ }
+
+ /* Copy memory to supplied buffer. */
+ addr -= count * sizeof (int);
+ memcpy (myaddr, (char *)buf + (memaddr - addr), len);
+ }
+ else
+ {
+ /* Fetch leading memory needed for alignment. */
+ if (addr < memaddr)
+ if (!read_word (addr, buf, arch64))
+ return 0;
+
+ /* Fetch trailing memory needed for alignment. */
+ if (addr + count * sizeof (int) > memaddr + len)
+ if (!read_word (addr, buf + count - 1, arch64))
+ return 0;
+
+ /* Copy supplied data into memory buffer. */
+ memcpy ((char *)buf + (memaddr - addr), myaddr, len);
+
+ /* Store memory one word at a time. */
+ for (i = 0, errno = 0; i < count; i++, addr += sizeof (int))
+ {
+ if (arch64)
+ rs6000_ptrace64 (PT_WRITE_D, PIDGET (inferior_ptid), addr, buf[i], NULL);
+ else
+ rs6000_ptrace32 (PT_WRITE_D, PIDGET (inferior_ptid), (int *)(long) addr,
+ buf[i], NULL);
+
+ if (errno)
+ return 0;
+ QUIT;
+ }
+ }
+
+ return len;
+}
+
+/* Execute one dummy breakpoint instruction. This way we give the kernel
+ a chance to do some housekeeping and update inferior's internal data,
+ including u_area. */
+
+static void
+exec_one_dummy_insn (void)
+{
+#define DUMMY_INSN_ADDR (TEXT_SEGMENT_BASE)+0x200
+
+ char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */
+ int ret, status, pid;
+ CORE_ADDR prev_pc;
+
+ /* We plant one dummy breakpoint into DUMMY_INSN_ADDR address. We
+ assume that this address will never be executed again by the real
+ code. */
+
+ target_insert_breakpoint (DUMMY_INSN_ADDR, shadow_contents);
+
+ /* You might think this could be done with a single ptrace call, and
+ you'd be correct for just about every platform I've ever worked
+ on. However, rs6000-ibm-aix4.1.3 seems to have screwed this up --
+ the inferior never hits the breakpoint (it's also worth noting
+ powerpc-ibm-aix4.1.3 works correctly). */
+ prev_pc = read_pc ();
+ write_pc (DUMMY_INSN_ADDR);
+ if (ARCH64 ())
+ ret = rs6000_ptrace64 (PT_CONTINUE, PIDGET (inferior_ptid), 1, 0, NULL);
+ else
+ ret = rs6000_ptrace32 (PT_CONTINUE, PIDGET (inferior_ptid), (int *)1, 0, NULL);
+
+ if (ret != 0)
+ perror ("pt_continue");
+
+ do
+ {
+ pid = wait (&status);
+ }
+ while (pid != PIDGET (inferior_ptid));
+
+ write_pc (prev_pc);
+ target_remove_breakpoint (DUMMY_INSN_ADDR, shadow_contents);
+}
+
+/* Fetch registers from the register section in core bfd. */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+ CoreRegs *regs;
+ double *fprs;
+ int arch64, i, size;
+ void *gprs, *sprs[7];
+
+ if (which != 0)
+ {
+ fprintf_unfiltered
+ (gdb_stderr,
+ "Gdb error: unknown parameter to fetch_core_registers().\n");
+ return;
+ }
+
+ arch64 = ARCH64 ();
+ regs = (CoreRegs *) core_reg_sect;
+
+ /* Retrieve register pointers. */
+
+ if (arch64)
+ {
+ gprs = regs->r64.gpr;
+ fprs = regs->r64.fpr;
+ sprs[0] = &regs->r64.iar;
+ sprs[1] = &regs->r64.msr;
+ sprs[2] = &regs->r64.cr;
+ sprs[3] = &regs->r64.lr;
+ sprs[4] = &regs->r64.ctr;
+ sprs[5] = &regs->r64.xer;
+ }
+ else
+ {
+ gprs = regs->r32.gpr;
+ fprs = regs->r32.fpr;
+ sprs[0] = &regs->r32.iar;
+ sprs[1] = &regs->r32.msr;
+ sprs[2] = &regs->r32.cr;
+ sprs[3] = &regs->r32.lr;
+ sprs[4] = &regs->r32.ctr;
+ sprs[5] = &regs->r32.xer;
+ sprs[6] = &regs->r32.mq;
+ }
+
+ /* Copy from pointers to registers[]. */
+
+ memcpy (registers, gprs, 32 * (arch64 ? 8 : 4));
+ memcpy (registers + REGISTER_BYTE (FP0_REGNUM), fprs, 32 * 8);
+ for (i = FIRST_UISA_SP_REGNUM; i <= LAST_UISA_SP_REGNUM; i++)
+ {
+ size = REGISTER_RAW_SIZE (i);
+ if (size)
+ memcpy (registers + REGISTER_BYTE (i),
+ sprs[i - FIRST_UISA_SP_REGNUM], size);
+ }
+}
+
+
+/* Copy information about text and data sections from LDI to VP for a 64-bit
+ process if ARCH64 and for a 32-bit process otherwise. */
+
+static void
+vmap_secs (struct vmap *vp, LdInfo *ldi, int arch64)
+{
+ if (arch64)
+ {
+ vp->tstart = (CORE_ADDR) ldi->l64.ldinfo_textorg;
+ vp->tend = vp->tstart + ldi->l64.ldinfo_textsize;
+ vp->dstart = (CORE_ADDR) ldi->l64.ldinfo_dataorg;
+ vp->dend = vp->dstart + ldi->l64.ldinfo_datasize;
+ }
+ else
+ {
+ vp->tstart = (unsigned long) ldi->l32.ldinfo_textorg;
+ vp->tend = vp->tstart + ldi->l32.ldinfo_textsize;
+ vp->dstart = (unsigned long) ldi->l32.ldinfo_dataorg;
+ vp->dend = vp->dstart + ldi->l32.ldinfo_datasize;
+ }
+
+ /* The run time loader maps the file header in addition to the text
+ section and returns a pointer to the header in ldinfo_textorg.
+ Adjust the text start address to point to the real start address
+ of the text section. */
+ vp->tstart += vp->toffs;
+}
+
+/* handle symbol translation on vmapping */
+
+static void
+vmap_symtab (struct vmap *vp)
+{
+ register struct objfile *objfile;
+ struct section_offsets *new_offsets;
+ int i;
+
+ objfile = vp->objfile;
+ if (objfile == NULL)
+ {
+ /* OK, it's not an objfile we opened ourselves.
+ Currently, that can only happen with the exec file, so
+ relocate the symbols for the symfile. */
+ if (symfile_objfile == NULL)
+ return;
+ objfile = symfile_objfile;
+ }
+ else if (!vp->loaded)
+ /* If symbols are not yet loaded, offsets are not yet valid. */
+ return;
+
+ new_offsets = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
+
+ for (i = 0; i < objfile->num_sections; ++i)
+ new_offsets->offsets[i] = ANOFFSET (objfile->section_offsets, i);
+
+ /* The symbols in the object file are linked to the VMA of the section,
+ relocate them VMA relative. */
+ new_offsets->offsets[SECT_OFF_TEXT (objfile)] = vp->tstart - vp->tvma;
+ new_offsets->offsets[SECT_OFF_DATA (objfile)] = vp->dstart - vp->dvma;
+ new_offsets->offsets[SECT_OFF_BSS (objfile)] = vp->dstart - vp->dvma;
+
+ objfile_relocate (objfile, new_offsets);
+}
+
+/* Add symbols for an objfile. */
+
+static int
+objfile_symbol_add (void *arg)
+{
+ struct objfile *obj = (struct objfile *) arg;
+
+ syms_from_objfile (obj, NULL, 0, 0);
+ new_symfile_objfile (obj, 0, 0);
+ return 1;
+}
+
+/* Add symbols for a vmap. Return zero upon error. */
+
+int
+vmap_add_symbols (struct vmap *vp)
+{
+ if (catch_errors (objfile_symbol_add, vp->objfile,
+ "Error while reading shared library symbols:\n",
+ RETURN_MASK_ALL))
+ {
+ /* Note this is only done if symbol reading was successful. */
+ vp->loaded = 1;
+ vmap_symtab (vp);
+ return 1;
+ }
+ return 0;
+}
+
+/* Add a new vmap entry based on ldinfo() information.
+
+ If ldi->ldinfo_fd is not valid (e.g. this struct ld_info is from a
+ core file), the caller should set it to -1, and we will open the file.
+
+ Return the vmap new entry. */
+
+static struct vmap *
+add_vmap (LdInfo *ldi)
+{
+ bfd *abfd, *last;
+ register char *mem, *objname, *filename;
+ struct objfile *obj;
+ struct vmap *vp;
+ int fd;
+ ARCH64_DECL (arch64);
+
+ /* This ldi structure was allocated using alloca() in
+ xcoff_relocate_symtab(). Now we need to have persistent object
+ and member names, so we should save them. */
+
+ filename = LDI_FILENAME (ldi, arch64);
+ mem = filename + strlen (filename) + 1;
+ mem = savestring (mem, strlen (mem));
+ objname = savestring (filename, strlen (filename));
+
+ fd = LDI_FD (ldi, arch64);
+ if (fd < 0)
+ /* Note that this opens it once for every member; a possible
+ enhancement would be to only open it once for every object. */
+ abfd = bfd_openr (objname, gnutarget);
+ else
+ abfd = bfd_fdopenr (objname, gnutarget, fd);
+ if (!abfd)
+ {
+ warning ("Could not open `%s' as an executable file: %s",
+ objname, bfd_errmsg (bfd_get_error ()));
+ return NULL;
+ }
+
+ /* make sure we have an object file */
+
+ if (bfd_check_format (abfd, bfd_object))
+ vp = map_vmap (abfd, 0);
+
+ else if (bfd_check_format (abfd, bfd_archive))
+ {
+ last = 0;
+ /* FIXME??? am I tossing BFDs? bfd? */
+ while ((last = bfd_openr_next_archived_file (abfd, last)))
+ if (STREQ (mem, last->filename))
+ break;
+
+ if (!last)
+ {
+ warning ("\"%s\": member \"%s\" missing.", objname, mem);
+ bfd_close (abfd);
+ return NULL;
+ }
+
+ if (!bfd_check_format (last, bfd_object))
+ {
+ warning ("\"%s\": member \"%s\" not in executable format: %s.",
+ objname, mem, bfd_errmsg (bfd_get_error ()));
+ bfd_close (last);
+ bfd_close (abfd);
+ return NULL;
+ }
+
+ vp = map_vmap (last, abfd);
+ }
+ else
+ {
+ warning ("\"%s\": not in executable format: %s.",
+ objname, bfd_errmsg (bfd_get_error ()));
+ bfd_close (abfd);
+ return NULL;
+ }
+ obj = allocate_objfile (vp->bfd, 0);
+ vp->objfile = obj;
+
+ /* Always add symbols for the main objfile. */
+ if (vp == vmap || auto_solib_add)
+ vmap_add_symbols (vp);
+ return vp;
+}
+
+/* update VMAP info with ldinfo() information
+ Input is ptr to ldinfo() results. */
+
+static void
+vmap_ldinfo (LdInfo *ldi)
+{
+ struct stat ii, vi;
+ register struct vmap *vp;
+ int got_one, retried;
+ int got_exec_file = 0;
+ uint next;
+ int arch64 = ARCH64 ();
+
+ /* For each *ldi, see if we have a corresponding *vp.
+ If so, update the mapping, and symbol table.
+ If not, add an entry and symbol table. */
+
+ do
+ {
+ char *name = LDI_FILENAME (ldi, arch64);
+ char *memb = name + strlen (name) + 1;
+ int fd = LDI_FD (ldi, arch64);
+
+ retried = 0;
+
+ if (fstat (fd, &ii) < 0)
+ {
+ /* The kernel sets ld_info to -1, if the process is still using the
+ object, and the object is removed. Keep the symbol info for the
+ removed object and issue a warning. */
+ warning ("%s (fd=%d) has disappeared, keeping its symbols",
+ name, fd);
+ continue;
+ }
+ retry:
+ for (got_one = 0, vp = vmap; vp; vp = vp->nxt)
+ {
+ struct objfile *objfile;
+
+ /* First try to find a `vp', which is the same as in ldinfo.
+ If not the same, just continue and grep the next `vp'. If same,
+ relocate its tstart, tend, dstart, dend values. If no such `vp'
+ found, get out of this for loop, add this ldi entry as a new vmap
+ (add_vmap) and come back, find its `vp' and so on... */
+
+ /* The filenames are not always sufficient to match on. */
+
+ if ((name[0] == '/' && !STREQ (name, vp->name))
+ || (memb[0] && !STREQ (memb, vp->member)))
+ continue;
+
+ /* See if we are referring to the same file.
+ We have to check objfile->obfd, symfile.c:reread_symbols might
+ have updated the obfd after a change. */
+ objfile = vp->objfile == NULL ? symfile_objfile : vp->objfile;
+ if (objfile == NULL
+ || objfile->obfd == NULL
+ || bfd_stat (objfile->obfd, &vi) < 0)
+ {
+ warning ("Unable to stat %s, keeping its symbols", name);
+ continue;
+ }
+
+ if (ii.st_dev != vi.st_dev || ii.st_ino != vi.st_ino)
+ continue;
+
+ if (!retried)
+ close (fd);
+
+ ++got_one;
+
+ /* Found a corresponding VMAP. Remap! */
+
+ vmap_secs (vp, ldi, arch64);
+
+ /* The objfile is only NULL for the exec file. */
+ if (vp->objfile == NULL)
+ got_exec_file = 1;
+
+ /* relocate symbol table(s). */
+ vmap_symtab (vp);
+
+ /* There may be more, so we don't break out of the loop. */
+ }
+
+ /* if there was no matching *vp, we must perforce create the sucker(s) */
+ if (!got_one && !retried)
+ {
+ add_vmap (ldi);
+ ++retried;
+ goto retry;
+ }
+ }
+ while ((next = LDI_NEXT (ldi, arch64))
+ && (ldi = (void *) (next + (char *) ldi)));
+
+ /* If we don't find the symfile_objfile anywhere in the ldinfo, it
+ is unlikely that the symbol file is relocated to the proper
+ address. And we might have attached to a process which is
+ running a different copy of the same executable. */
+ if (symfile_objfile != NULL && !got_exec_file)
+ {
+ warning ("Symbol file %s\nis not mapped; discarding it.\n\
+If in fact that file has symbols which the mapped files listed by\n\
+\"info files\" lack, you can load symbols with the \"symbol-file\" or\n\
+\"add-symbol-file\" commands (note that you must take care of relocating\n\
+symbols to the proper address).",
+ symfile_objfile->name);
+ free_objfile (symfile_objfile);
+ symfile_objfile = NULL;
+ }
+ breakpoint_re_set ();
+}
+
+/* As well as symbol tables, exec_sections need relocation. After
+ the inferior process' termination, there will be a relocated symbol
+ table exist with no corresponding inferior process. At that time, we
+ need to use `exec' bfd, rather than the inferior process's memory space
+ to look up symbols.
+
+ `exec_sections' need to be relocated only once, as long as the exec
+ file remains unchanged.
+ */
+
+static void
+vmap_exec (void)
+{
+ static bfd *execbfd;
+ int i;
+
+ if (execbfd == exec_bfd)
+ return;
+
+ execbfd = exec_bfd;
+
+ if (!vmap || !exec_ops.to_sections)
+ error ("vmap_exec: vmap or exec_ops.to_sections == 0\n");
+
+ for (i = 0; &exec_ops.to_sections[i] < exec_ops.to_sections_end; i++)
+ {
+ if (STREQ (".text", exec_ops.to_sections[i].the_bfd_section->name))
+ {
+ exec_ops.to_sections[i].addr += vmap->tstart - vmap->tvma;
+ exec_ops.to_sections[i].endaddr += vmap->tstart - vmap->tvma;
+ }
+ else if (STREQ (".data", exec_ops.to_sections[i].the_bfd_section->name))
+ {
+ exec_ops.to_sections[i].addr += vmap->dstart - vmap->dvma;
+ exec_ops.to_sections[i].endaddr += vmap->dstart - vmap->dvma;
+ }
+ else if (STREQ (".bss", exec_ops.to_sections[i].the_bfd_section->name))
+ {
+ exec_ops.to_sections[i].addr += vmap->dstart - vmap->dvma;
+ exec_ops.to_sections[i].endaddr += vmap->dstart - vmap->dvma;
+ }
+ }
+}
+
+/* Set the current architecture from the host running GDB. Called when
+ starting a child process. */
+
+static void
+set_host_arch (int pid)
+{
+ enum bfd_architecture arch;
+ unsigned long mach;
+ bfd abfd;
+ struct gdbarch_info info;
+
+ if (__power_rs ())
+ {
+ arch = bfd_arch_rs6000;
+ mach = bfd_mach_rs6k;
+ }
+ else
+ {
+ arch = bfd_arch_powerpc;
+ mach = bfd_mach_ppc;
+ }
+
+ /* FIXME: schauer/2002-02-25:
+ We don't know if we are executing a 32 or 64 bit executable,
+ and have no way to pass the proper word size to rs6000_gdbarch_init.
+ So we have to avoid switching to a new architecture, if the architecture
+ matches already.
+ Blindly calling rs6000_gdbarch_init used to work in older versions of
+ GDB, as rs6000_gdbarch_init incorrectly used the previous tdep to
+ determine the wordsize. */
+ if (exec_bfd)
+ {
+ const struct bfd_arch_info *exec_bfd_arch_info;
+
+ exec_bfd_arch_info = bfd_get_arch_info (exec_bfd);
+ if (arch == exec_bfd_arch_info->arch)
+ return;
+ }
+
+ bfd_default_set_arch_mach (&abfd, arch, mach);
+
+ gdbarch_info_init (&info);
+ info.bfd_arch_info = bfd_get_arch_info (&abfd);
+
+ if (!gdbarch_update_p (info))
+ {
+ internal_error (__FILE__, __LINE__,
+ "set_host_arch: failed to select architecture");
+ }
+}
+
+
+/* xcoff_relocate_symtab - hook for symbol table relocation.
+ also reads shared libraries.. */
+
+void
+xcoff_relocate_symtab (unsigned int pid)
+{
+ int load_segs = 64; /* number of load segments */
+ int rc;
+ LdInfo *ldi = NULL;
+ int arch64 = ARCH64 ();
+ int ldisize = arch64 ? sizeof (ldi->l64) : sizeof (ldi->l32);
+ int size;
+
+ do
+ {
+ size = load_segs * ldisize;
+ ldi = (void *) xrealloc (ldi, size);
+
+#if 0
+ /* According to my humble theory, AIX has some timing problems and
+ when the user stack grows, kernel doesn't update stack info in time
+ and ptrace calls step on user stack. That is why we sleep here a
+ little, and give kernel to update its internals. */
+ usleep (36000);
+#endif
+
+ if (arch64)
+ rc = rs6000_ptrace64 (PT_LDINFO, pid, (unsigned long) ldi, size, NULL);
+ else
+ rc = rs6000_ptrace32 (PT_LDINFO, pid, (int *) ldi, size, NULL);
+
+ if (rc == -1)
+ {
+ if (errno == ENOMEM)
+ load_segs *= 2;
+ else
+ perror_with_name ("ptrace ldinfo");
+ }
+ else
+ {
+ vmap_ldinfo (ldi);
+ vmap_exec (); /* relocate the exec and core sections as well. */
+ }
+ } while (rc == -1);
+ if (ldi)
+ xfree (ldi);
+}
+
+/* Core file stuff. */
+
+/* Relocate symtabs and read in shared library info, based on symbols
+ from the core file. */
+
+void
+xcoff_relocate_core (struct target_ops *target)
+{
+ sec_ptr ldinfo_sec;
+ int offset = 0;
+ LdInfo *ldi;
+ struct vmap *vp;
+ int arch64 = ARCH64 ();
+
+ /* Size of a struct ld_info except for the variable-length filename. */
+ int nonfilesz = (int)LDI_FILENAME ((LdInfo *)0, arch64);
+
+ /* Allocated size of buffer. */
+ int buffer_size = nonfilesz;
+ char *buffer = xmalloc (buffer_size);
+ struct cleanup *old = make_cleanup (free_current_contents, &buffer);
+
+ ldinfo_sec = bfd_get_section_by_name (core_bfd, ".ldinfo");
+ if (ldinfo_sec == NULL)
+ {
+ bfd_err:
+ fprintf_filtered (gdb_stderr, "Couldn't get ldinfo from core file: %s\n",
+ bfd_errmsg (bfd_get_error ()));
+ do_cleanups (old);
+ return;
+ }
+ do
+ {
+ int i;
+ int names_found = 0;
+
+ /* Read in everything but the name. */
+ if (bfd_get_section_contents (core_bfd, ldinfo_sec, buffer,
+ offset, nonfilesz) == 0)
+ goto bfd_err;
+
+ /* Now the name. */
+ i = nonfilesz;
+ do
+ {
+ if (i == buffer_size)
+ {
+ buffer_size *= 2;
+ buffer = xrealloc (buffer, buffer_size);
+ }
+ if (bfd_get_section_contents (core_bfd, ldinfo_sec, &buffer[i],
+ offset + i, 1) == 0)
+ goto bfd_err;
+ if (buffer[i++] == '\0')
+ ++names_found;
+ }
+ while (names_found < 2);
+
+ ldi = (LdInfo *) buffer;
+
+ /* Can't use a file descriptor from the core file; need to open it. */
+ if (arch64)
+ ldi->l64.ldinfo_fd = -1;
+ else
+ ldi->l32.ldinfo_fd = -1;
+
+ /* The first ldinfo is for the exec file, allocated elsewhere. */
+ if (offset == 0 && vmap != NULL)
+ vp = vmap;
+ else
+ vp = add_vmap (ldi);
+
+ /* Process next shared library upon error. */
+ offset += LDI_NEXT (ldi, arch64);
+ if (vp == NULL)
+ continue;
+
+ vmap_secs (vp, ldi, arch64);
+
+ /* Unless this is the exec file,
+ add our sections to the section table for the core target. */
+ if (vp != vmap)
+ {
+ struct section_table *stp;
+
+ target_resize_to_sections (target, 2);
+ stp = target->to_sections_end - 2;
+
+ stp->bfd = vp->bfd;
+ stp->the_bfd_section = bfd_get_section_by_name (stp->bfd, ".text");
+ stp->addr = vp->tstart;
+ stp->endaddr = vp->tend;
+ stp++;
+
+ stp->bfd = vp->bfd;
+ stp->the_bfd_section = bfd_get_section_by_name (stp->bfd, ".data");
+ stp->addr = vp->dstart;
+ stp->endaddr = vp->dend;
+ }
+
+ vmap_symtab (vp);
+ }
+ while (LDI_NEXT (ldi, arch64) != 0);
+ vmap_exec ();
+ breakpoint_re_set ();
+ do_cleanups (old);
+}
+
+int
+kernel_u_size (void)
+{
+ return (sizeof (struct user));
+}
+
+/* Under AIX, we have to pass the correct TOC pointer to a function
+ when calling functions in the inferior.
+ We try to find the relative toc offset of the objfile containing PC
+ and add the current load address of the data segment from the vmap. */
+
+static CORE_ADDR
+find_toc_address (CORE_ADDR pc)
+{
+ struct vmap *vp;
+ extern CORE_ADDR get_toc_offset (struct objfile *); /* xcoffread.c */
+
+ for (vp = vmap; vp; vp = vp->nxt)
+ {
+ if (pc >= vp->tstart && pc < vp->tend)
+ {
+ /* vp->objfile is only NULL for the exec file. */
+ return vp->dstart + get_toc_offset (vp->objfile == NULL
+ ? symfile_objfile
+ : vp->objfile);
+ }
+ }
+ error ("Unable to find TOC entry for pc 0x%x\n", pc);
+}
+
+/* Register that we are able to handle rs6000 core file formats. */
+
+static struct core_fns rs6000_core_fns =
+{
+ bfd_target_xcoff_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_rs6000 (void)
+{
+ /* Initialize hook in rs6000-tdep.c for determining the TOC address when
+ calling functions in the inferior. */
+ rs6000_find_toc_address_hook = find_toc_address;
+
+ /* Initialize hook in rs6000-tdep.c to set the current architecture when
+ starting a child process. */
+ rs6000_set_host_arch_hook = set_host_arch;
+
+ add_core_fns (&rs6000_core_fns);
+}
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
new file mode 100644
index 00000000000..2ba81ea2aba
--- /dev/null
+++ b/gdb/rs6000-tdep.c
@@ -0,0 +1,2823 @@
+/* Target-dependent code for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001, 2002
+ 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "symtab.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "arch-utils.h"
+#include "regcache.h"
+#include "doublest.h"
+#include "value.h"
+#include "parser-defs.h"
+
+#include "libbfd.h" /* for bfd_default_set_arch_mach */
+#include "coff/internal.h" /* for libcoff.h */
+#include "libcoff.h" /* for xcoff_data */
+#include "coff/xcoff.h"
+#include "libxcoff.h"
+
+#include "elf-bfd.h"
+
+#include "solib-svr4.h"
+#include "ppc-tdep.h"
+
+/* If the kernel has to deliver a signal, it pushes a sigcontext
+ structure on the stack and then calls the signal handler, passing
+ the address of the sigcontext in an argument register. Usually
+ the signal handler doesn't save this register, so we have to
+ access the sigcontext structure via an offset from the signal handler
+ frame.
+ The following constants were determined by experimentation on AIX 3.2. */
+#define SIG_FRAME_PC_OFFSET 96
+#define SIG_FRAME_LR_OFFSET 108
+#define SIG_FRAME_FP_OFFSET 284
+
+/* To be used by skip_prologue. */
+
+struct rs6000_framedata
+ {
+ int offset; /* total size of frame --- the distance
+ by which we decrement sp to allocate
+ the frame */
+ int saved_gpr; /* smallest # of saved gpr */
+ int saved_fpr; /* smallest # of saved fpr */
+ int saved_vr; /* smallest # of saved vr */
+ int alloca_reg; /* alloca register number (frame ptr) */
+ char frameless; /* true if frameless functions. */
+ char nosavedpc; /* true if pc not saved. */
+ int gpr_offset; /* offset of saved gprs from prev sp */
+ int fpr_offset; /* offset of saved fprs from prev sp */
+ int vr_offset; /* offset of saved vrs from prev sp */
+ int lr_offset; /* offset of saved lr */
+ int cr_offset; /* offset of saved cr */
+ int vrsave_offset; /* offset of saved vrsave register */
+ };
+
+/* Description of a single register. */
+
+struct reg
+ {
+ char *name; /* name of register */
+ unsigned char sz32; /* size on 32-bit arch, 0 if nonextant */
+ unsigned char sz64; /* size on 64-bit arch, 0 if nonextant */
+ unsigned char fpr; /* whether register is floating-point */
+ };
+
+/* Return the current architecture's gdbarch_tdep structure. */
+
+#define TDEP gdbarch_tdep (current_gdbarch)
+
+/* Breakpoint shadows for the single step instructions will be kept here. */
+
+static struct sstep_breaks
+ {
+ /* Address, or 0 if this is not in use. */
+ CORE_ADDR address;
+ /* Shadow contents. */
+ char data[4];
+ }
+stepBreaks[2];
+
+/* Hook for determining the TOC address when calling functions in the
+ inferior under AIX. The initialization code in rs6000-nat.c sets
+ this hook to point to find_toc_address. */
+
+CORE_ADDR (*rs6000_find_toc_address_hook) (CORE_ADDR) = NULL;
+
+/* Hook to set the current architecture when starting a child process.
+ rs6000-nat.c sets this. */
+
+void (*rs6000_set_host_arch_hook) (int) = NULL;
+
+/* Static function prototypes */
+
+static CORE_ADDR branch_dest (int opcode, int instr, CORE_ADDR pc,
+ CORE_ADDR safety);
+static CORE_ADDR skip_prologue (CORE_ADDR, CORE_ADDR,
+ struct rs6000_framedata *);
+static void frame_get_saved_regs (struct frame_info * fi,
+ struct rs6000_framedata * fdatap);
+static CORE_ADDR frame_initial_stack_address (struct frame_info *);
+
+/* Read a LEN-byte address from debugged memory address MEMADDR. */
+
+static CORE_ADDR
+read_memory_addr (CORE_ADDR memaddr, int len)
+{
+ return read_memory_unsigned_integer (memaddr, len);
+}
+
+static CORE_ADDR
+rs6000_skip_prologue (CORE_ADDR pc)
+{
+ struct rs6000_framedata frame;
+ pc = skip_prologue (pc, 0, &frame);
+ return pc;
+}
+
+
+/* Fill in fi->saved_regs */
+
+struct frame_extra_info
+{
+ /* Functions calling alloca() change the value of the stack
+ pointer. We need to use initial stack pointer (which is saved in
+ r31 by gcc) in such cases. If a compiler emits traceback table,
+ then we should use the alloca register specified in traceback
+ table. FIXME. */
+ CORE_ADDR initial_sp; /* initial stack pointer. */
+};
+
+void
+rs6000_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ fi->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+ fi->extra_info->initial_sp = 0;
+ if (fi->next != (CORE_ADDR) 0
+ && fi->pc < TEXT_SEGMENT_BASE)
+ /* We're in get_prev_frame */
+ /* and this is a special signal frame. */
+ /* (fi->pc will be some low address in the kernel, */
+ /* to which the signal handler returns). */
+ fi->signal_handler_caller = 1;
+}
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame. */
+
+/* In this implementation for RS/6000, we do *not* save sp. I am
+ not sure if it will be needed. The following function takes care of gpr's
+ and fpr's only. */
+
+void
+rs6000_frame_init_saved_regs (struct frame_info *fi)
+{
+ frame_get_saved_regs (fi, NULL);
+}
+
+static CORE_ADDR
+rs6000_frame_args_address (struct frame_info *fi)
+{
+ if (fi->extra_info->initial_sp != 0)
+ return fi->extra_info->initial_sp;
+ else
+ return frame_initial_stack_address (fi);
+}
+
+/* Immediately after a function call, return the saved pc.
+ Can't go through the frames for this because on some machines
+ the new frame is not set up until the new function executes
+ some instructions. */
+
+static CORE_ADDR
+rs6000_saved_pc_after_call (struct frame_info *fi)
+{
+ return read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum);
+}
+
+/* Calculate the destination of a branch/jump. Return -1 if not a branch. */
+
+static CORE_ADDR
+branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety)
+{
+ CORE_ADDR dest;
+ int immediate;
+ int absolute;
+ int ext_op;
+
+ absolute = (int) ((instr >> 1) & 1);
+
+ switch (opcode)
+ {
+ case 18:
+ immediate = ((instr & ~3) << 6) >> 6; /* br unconditional */
+ if (absolute)
+ dest = immediate;
+ else
+ dest = pc + immediate;
+ break;
+
+ case 16:
+ immediate = ((instr & ~3) << 16) >> 16; /* br conditional */
+ if (absolute)
+ dest = immediate;
+ else
+ dest = pc + immediate;
+ break;
+
+ case 19:
+ ext_op = (instr >> 1) & 0x3ff;
+
+ if (ext_op == 16) /* br conditional register */
+ {
+ dest = read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum) & ~3;
+
+ /* If we are about to return from a signal handler, dest is
+ something like 0x3c90. The current frame is a signal handler
+ caller frame, upon completion of the sigreturn system call
+ execution will return to the saved PC in the frame. */
+ if (dest < TEXT_SEGMENT_BASE)
+ {
+ struct frame_info *fi;
+
+ fi = get_current_frame ();
+ if (fi != NULL)
+ dest = read_memory_addr (fi->frame + SIG_FRAME_PC_OFFSET,
+ TDEP->wordsize);
+ }
+ }
+
+ else if (ext_op == 528) /* br cond to count reg */
+ {
+ dest = read_register (gdbarch_tdep (current_gdbarch)->ppc_ctr_regnum) & ~3;
+
+ /* If we are about to execute a system call, dest is something
+ like 0x22fc or 0x3b00. Upon completion the system call
+ will return to the address in the link register. */
+ if (dest < TEXT_SEGMENT_BASE)
+ dest = read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum) & ~3;
+ }
+ else
+ return -1;
+ break;
+
+ default:
+ return -1;
+ }
+ return (dest < TEXT_SEGMENT_BASE) ? safety : dest;
+}
+
+
+/* Sequence of bytes for breakpoint instruction. */
+
+#define BIG_BREAKPOINT { 0x7d, 0x82, 0x10, 0x08 }
+#define LITTLE_BREAKPOINT { 0x08, 0x10, 0x82, 0x7d }
+
+const static unsigned char *
+rs6000_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size)
+{
+ static unsigned char big_breakpoint[] = BIG_BREAKPOINT;
+ static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT;
+ *bp_size = 4;
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ return big_breakpoint;
+ else
+ return little_breakpoint;
+}
+
+
+/* AIX does not support PT_STEP. Simulate it. */
+
+void
+rs6000_software_single_step (enum target_signal signal,
+ int insert_breakpoints_p)
+{
+ CORE_ADDR dummy;
+ int breakp_sz;
+ const char *breakp = rs6000_breakpoint_from_pc (&dummy, &breakp_sz);
+ int ii, insn;
+ CORE_ADDR loc;
+ CORE_ADDR breaks[2];
+ int opcode;
+
+ if (insert_breakpoints_p)
+ {
+
+ loc = read_pc ();
+
+ insn = read_memory_integer (loc, 4);
+
+ breaks[0] = loc + breakp_sz;
+ opcode = insn >> 26;
+ breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
+
+ /* Don't put two breakpoints on the same address. */
+ if (breaks[1] == breaks[0])
+ breaks[1] = -1;
+
+ stepBreaks[1].address = 0;
+
+ for (ii = 0; ii < 2; ++ii)
+ {
+
+ /* ignore invalid breakpoint. */
+ if (breaks[ii] == -1)
+ continue;
+ target_insert_breakpoint (breaks[ii], stepBreaks[ii].data);
+ stepBreaks[ii].address = breaks[ii];
+ }
+
+ }
+ else
+ {
+
+ /* remove step breakpoints. */
+ for (ii = 0; ii < 2; ++ii)
+ if (stepBreaks[ii].address != 0)
+ target_remove_breakpoint (stepBreaks[ii].address,
+ stepBreaks[ii].data);
+ }
+ errno = 0; /* FIXME, don't ignore errors! */
+ /* What errors? {read,write}_memory call error(). */
+}
+
+
+/* return pc value after skipping a function prologue and also return
+ information about a function frame.
+
+ in struct rs6000_framedata fdata:
+ - frameless is TRUE, if function does not have a frame.
+ - nosavedpc is TRUE, if function does not save %pc value in its frame.
+ - offset is the initial size of this stack frame --- the amount by
+ which we decrement the sp to allocate the frame.
+ - saved_gpr is the number of the first saved gpr.
+ - saved_fpr is the number of the first saved fpr.
+ - saved_vr is the number of the first saved vr.
+ - alloca_reg is the number of the register used for alloca() handling.
+ Otherwise -1.
+ - gpr_offset is the offset of the first saved gpr from the previous frame.
+ - fpr_offset is the offset of the first saved fpr from the previous frame.
+ - vr_offset is the offset of the first saved vr from the previous frame.
+ - lr_offset is the offset of the saved lr
+ - cr_offset is the offset of the saved cr
+ - vrsave_offset is the offset of the saved vrsave register
+ */
+
+#define SIGNED_SHORT(x) \
+ ((sizeof (short) == 2) \
+ ? ((int)(short)(x)) \
+ : ((int)((((x) & 0xffff) ^ 0x8000) - 0x8000)))
+
+#define GET_SRC_REG(x) (((x) >> 21) & 0x1f)
+
+/* Limit the number of skipped non-prologue instructions, as the examining
+ of the prologue is expensive. */
+static int max_skip_non_prologue_insns = 10;
+
+/* Given PC representing the starting address of a function, and
+ LIM_PC which is the (sloppy) limit to which to scan when looking
+ for a prologue, attempt to further refine this limit by using
+ the line data in the symbol table. If successful, a better guess
+ on where the prologue ends is returned, otherwise the previous
+ value of lim_pc is returned. */
+static CORE_ADDR
+refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc)
+{
+ struct symtab_and_line prologue_sal;
+
+ prologue_sal = find_pc_line (pc, 0);
+ if (prologue_sal.line != 0)
+ {
+ int i;
+ CORE_ADDR addr = prologue_sal.end;
+
+ /* Handle the case in which compiler's optimizer/scheduler
+ has moved instructions into the prologue. We scan ahead
+ in the function looking for address ranges whose corresponding
+ line number is less than or equal to the first one that we
+ found for the function. (It can be less than when the
+ scheduler puts a body instruction before the first prologue
+ instruction.) */
+ for (i = 2 * max_skip_non_prologue_insns;
+ i > 0 && (lim_pc == 0 || addr < lim_pc);
+ i--)
+ {
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (addr, 0);
+ if (sal.line == 0)
+ break;
+ if (sal.line <= prologue_sal.line
+ && sal.symtab == prologue_sal.symtab)
+ {
+ prologue_sal = sal;
+ }
+ addr = sal.end;
+ }
+
+ if (lim_pc == 0 || prologue_sal.end < lim_pc)
+ lim_pc = prologue_sal.end;
+ }
+ return lim_pc;
+}
+
+
+static CORE_ADDR
+skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
+{
+ CORE_ADDR orig_pc = pc;
+ CORE_ADDR last_prologue_pc = pc;
+ CORE_ADDR li_found_pc = 0;
+ char buf[4];
+ unsigned long op;
+ long offset = 0;
+ long vr_saved_offset = 0;
+ int lr_reg = -1;
+ int cr_reg = -1;
+ int vr_reg = -1;
+ int vrsave_reg = -1;
+ int reg;
+ int framep = 0;
+ int minimal_toc_loaded = 0;
+ int prev_insn_was_prologue_insn = 1;
+ int num_skip_non_prologue_insns = 0;
+
+ /* Attempt to find the end of the prologue when no limit is specified.
+ Note that refine_prologue_limit() has been written so that it may
+ be used to "refine" the limits of non-zero PC values too, but this
+ is only safe if we 1) trust the line information provided by the
+ compiler and 2) iterate enough to actually find the end of the
+ prologue.
+
+ It may become a good idea at some point (for both performance and
+ accuracy) to unconditionally call refine_prologue_limit(). But,
+ until we can make a clear determination that this is beneficial,
+ we'll play it safe and only use it to obtain a limit when none
+ has been specified. */
+ if (lim_pc == 0)
+ lim_pc = refine_prologue_limit (pc, lim_pc);
+
+ memset (fdata, 0, sizeof (struct rs6000_framedata));
+ fdata->saved_gpr = -1;
+ fdata->saved_fpr = -1;
+ fdata->saved_vr = -1;
+ fdata->alloca_reg = -1;
+ fdata->frameless = 1;
+ fdata->nosavedpc = 1;
+
+ for (;; pc += 4)
+ {
+ /* Sometimes it isn't clear if an instruction is a prologue
+ instruction or not. When we encounter one of these ambiguous
+ cases, we'll set prev_insn_was_prologue_insn to 0 (false).
+ Otherwise, we'll assume that it really is a prologue instruction. */
+ if (prev_insn_was_prologue_insn)
+ last_prologue_pc = pc;
+
+ /* Stop scanning if we've hit the limit. */
+ if (lim_pc != 0 && pc >= lim_pc)
+ break;
+
+ prev_insn_was_prologue_insn = 1;
+
+ /* Fetch the instruction and convert it to an integer. */
+ if (target_read_memory (pc, buf, 4))
+ break;
+ op = extract_signed_integer (buf, 4);
+
+ if ((op & 0xfc1fffff) == 0x7c0802a6)
+ { /* mflr Rx */
+ lr_reg = (op & 0x03e00000) | 0x90010000;
+ continue;
+
+ }
+ else if ((op & 0xfc1fffff) == 0x7c000026)
+ { /* mfcr Rx */
+ cr_reg = (op & 0x03e00000) | 0x90010000;
+ continue;
+
+ }
+ else if ((op & 0xfc1f0000) == 0xd8010000)
+ { /* stfd Rx,NUM(r1) */
+ reg = GET_SRC_REG (op);
+ if (fdata->saved_fpr == -1 || fdata->saved_fpr > reg)
+ {
+ fdata->saved_fpr = reg;
+ fdata->fpr_offset = SIGNED_SHORT (op) + offset;
+ }
+ continue;
+
+ }
+ else if (((op & 0xfc1f0000) == 0xbc010000) || /* stm Rx, NUM(r1) */
+ (((op & 0xfc1f0000) == 0x90010000 || /* st rx,NUM(r1) */
+ (op & 0xfc1f0003) == 0xf8010000) && /* std rx,NUM(r1) */
+ (op & 0x03e00000) >= 0x01a00000)) /* rx >= r13 */
+ {
+
+ reg = GET_SRC_REG (op);
+ if (fdata->saved_gpr == -1 || fdata->saved_gpr > reg)
+ {
+ fdata->saved_gpr = reg;
+ if ((op & 0xfc1f0003) == 0xf8010000)
+ op = (op >> 1) << 1;
+ fdata->gpr_offset = SIGNED_SHORT (op) + offset;
+ }
+ continue;
+
+ }
+ else if ((op & 0xffff0000) == 0x60000000)
+ {
+ /* nop */
+ /* Allow nops in the prologue, but do not consider them to
+ be part of the prologue unless followed by other prologue
+ instructions. */
+ prev_insn_was_prologue_insn = 0;
+ continue;
+
+ }
+ else if ((op & 0xffff0000) == 0x3c000000)
+ { /* addis 0,0,NUM, used
+ for >= 32k frames */
+ fdata->offset = (op & 0x0000ffff) << 16;
+ fdata->frameless = 0;
+ continue;
+
+ }
+ else if ((op & 0xffff0000) == 0x60000000)
+ { /* ori 0,0,NUM, 2nd ha
+ lf of >= 32k frames */
+ fdata->offset |= (op & 0x0000ffff);
+ fdata->frameless = 0;
+ continue;
+
+ }
+ else if (lr_reg != -1 && (op & 0xffff0000) == lr_reg)
+ { /* st Rx,NUM(r1)
+ where Rx == lr */
+ fdata->lr_offset = SIGNED_SHORT (op) + offset;
+ fdata->nosavedpc = 0;
+ lr_reg = 0;
+ continue;
+
+ }
+ else if (cr_reg != -1 && (op & 0xffff0000) == cr_reg)
+ { /* st Rx,NUM(r1)
+ where Rx == cr */
+ fdata->cr_offset = SIGNED_SHORT (op) + offset;
+ cr_reg = 0;
+ continue;
+
+ }
+ else if (op == 0x48000005)
+ { /* bl .+4 used in
+ -mrelocatable */
+ continue;
+
+ }
+ else if (op == 0x48000004)
+ { /* b .+4 (xlc) */
+ break;
+
+ }
+ else if ((op & 0xffff0000) == 0x3fc00000 || /* addis 30,0,foo@ha, used
+ in V.4 -mminimal-toc */
+ (op & 0xffff0000) == 0x3bde0000)
+ { /* addi 30,30,foo@l */
+ continue;
+
+ }
+ else if ((op & 0xfc000001) == 0x48000001)
+ { /* bl foo,
+ to save fprs??? */
+
+ fdata->frameless = 0;
+ /* Don't skip over the subroutine call if it is not within
+ the first three instructions of the prologue. */
+ if ((pc - orig_pc) > 8)
+ break;
+
+ op = read_memory_integer (pc + 4, 4);
+
+ /* At this point, make sure this is not a trampoline
+ function (a function that simply calls another functions,
+ and nothing else). If the next is not a nop, this branch
+ was part of the function prologue. */
+
+ if (op == 0x4def7b82 || op == 0) /* crorc 15, 15, 15 */
+ break; /* don't skip over
+ this branch */
+ continue;
+
+ /* update stack pointer */
+ }
+ else if ((op & 0xffff0000) == 0x94210000 || /* stu r1,NUM(r1) */
+ (op & 0xffff0003) == 0xf8210001) /* stdu r1,NUM(r1) */
+ {
+ fdata->frameless = 0;
+ if ((op & 0xffff0003) == 0xf8210001)
+ op = (op >> 1) << 1;
+ fdata->offset = SIGNED_SHORT (op);
+ offset = fdata->offset;
+ continue;
+
+ }
+ else if (op == 0x7c21016e)
+ { /* stwux 1,1,0 */
+ fdata->frameless = 0;
+ offset = fdata->offset;
+ continue;
+
+ /* Load up minimal toc pointer */
+ }
+ else if ((op >> 22) == 0x20f
+ && !minimal_toc_loaded)
+ { /* l r31,... or l r30,... */
+ minimal_toc_loaded = 1;
+ continue;
+
+ /* move parameters from argument registers to local variable
+ registers */
+ }
+ else if ((op & 0xfc0007fe) == 0x7c000378 && /* mr(.) Rx,Ry */
+ (((op >> 21) & 31) >= 3) && /* R3 >= Ry >= R10 */
+ (((op >> 21) & 31) <= 10) &&
+ (((op >> 16) & 31) >= fdata->saved_gpr)) /* Rx: local var reg */
+ {
+ continue;
+
+ /* store parameters in stack */
+ }
+ else if ((op & 0xfc1f0003) == 0xf8010000 || /* std rx,NUM(r1) */
+ (op & 0xfc1f0000) == 0xd8010000 || /* stfd Rx,NUM(r1) */
+ (op & 0xfc1f0000) == 0xfc010000) /* frsp, fp?,NUM(r1) */
+ {
+ continue;
+
+ /* store parameters in stack via frame pointer */
+ }
+ else if (framep &&
+ ((op & 0xfc1f0000) == 0x901f0000 || /* st rx,NUM(r1) */
+ (op & 0xfc1f0000) == 0xd81f0000 || /* stfd Rx,NUM(r1) */
+ (op & 0xfc1f0000) == 0xfc1f0000))
+ { /* frsp, fp?,NUM(r1) */
+ continue;
+
+ /* Set up frame pointer */
+ }
+ else if (op == 0x603f0000 /* oril r31, r1, 0x0 */
+ || op == 0x7c3f0b78)
+ { /* mr r31, r1 */
+ fdata->frameless = 0;
+ framep = 1;
+ fdata->alloca_reg = 31;
+ continue;
+
+ /* Another way to set up the frame pointer. */
+ }
+ else if ((op & 0xfc1fffff) == 0x38010000)
+ { /* addi rX, r1, 0x0 */
+ fdata->frameless = 0;
+ framep = 1;
+ fdata->alloca_reg = (op & ~0x38010000) >> 21;
+ continue;
+ }
+ /* AltiVec related instructions. */
+ /* Store the vrsave register (spr 256) in another register for
+ later manipulation, or load a register into the vrsave
+ register. 2 instructions are used: mfvrsave and
+ mtvrsave. They are shorthand notation for mfspr Rn, SPR256
+ and mtspr SPR256, Rn. */
+ /* mfspr Rn SPR256 == 011111 nnnnn 0000001000 01010100110
+ mtspr SPR256 Rn == 011111 nnnnn 0000001000 01110100110 */
+ else if ((op & 0xfc1fffff) == 0x7c0042a6) /* mfvrsave Rn */
+ {
+ vrsave_reg = GET_SRC_REG (op);
+ continue;
+ }
+ else if ((op & 0xfc1fffff) == 0x7c0043a6) /* mtvrsave Rn */
+ {
+ continue;
+ }
+ /* Store the register where vrsave was saved to onto the stack:
+ rS is the register where vrsave was stored in a previous
+ instruction. */
+ /* 100100 sssss 00001 dddddddd dddddddd */
+ else if ((op & 0xfc1f0000) == 0x90010000) /* stw rS, d(r1) */
+ {
+ if (vrsave_reg == GET_SRC_REG (op))
+ {
+ fdata->vrsave_offset = SIGNED_SHORT (op) + offset;
+ vrsave_reg = -1;
+ }
+ continue;
+ }
+ /* Compute the new value of vrsave, by modifying the register
+ where vrsave was saved to. */
+ else if (((op & 0xfc000000) == 0x64000000) /* oris Ra, Rs, UIMM */
+ || ((op & 0xfc000000) == 0x60000000))/* ori Ra, Rs, UIMM */
+ {
+ continue;
+ }
+ /* li r0, SIMM (short for addi r0, 0, SIMM). This is the first
+ in a pair of insns to save the vector registers on the
+ stack. */
+ /* 001110 00000 00000 iiii iiii iiii iiii */
+ else if ((op & 0xffff0000) == 0x38000000) /* li r0, SIMM */
+ {
+ li_found_pc = pc;
+ vr_saved_offset = SIGNED_SHORT (op);
+ }
+ /* Store vector register S at (r31+r0) aligned to 16 bytes. */
+ /* 011111 sssss 11111 00000 00111001110 */
+ else if ((op & 0xfc1fffff) == 0x7c1f01ce) /* stvx Vs, R31, R0 */
+ {
+ if (pc == (li_found_pc + 4))
+ {
+ vr_reg = GET_SRC_REG (op);
+ /* If this is the first vector reg to be saved, or if
+ it has a lower number than others previously seen,
+ reupdate the frame info. */
+ if (fdata->saved_vr == -1 || fdata->saved_vr > vr_reg)
+ {
+ fdata->saved_vr = vr_reg;
+ fdata->vr_offset = vr_saved_offset + offset;
+ }
+ vr_saved_offset = -1;
+ vr_reg = -1;
+ li_found_pc = 0;
+ }
+ }
+ /* End AltiVec related instructions. */
+ else
+ {
+ /* Not a recognized prologue instruction.
+ Handle optimizer code motions into the prologue by continuing
+ the search if we have no valid frame yet or if the return
+ address is not yet saved in the frame. */
+ if (fdata->frameless == 0
+ && (lr_reg == -1 || fdata->nosavedpc == 0))
+ break;
+
+ if (op == 0x4e800020 /* blr */
+ || op == 0x4e800420) /* bctr */
+ /* Do not scan past epilogue in frameless functions or
+ trampolines. */
+ break;
+ if ((op & 0xf4000000) == 0x40000000) /* bxx */
+ /* Never skip branches. */
+ break;
+
+ if (num_skip_non_prologue_insns++ > max_skip_non_prologue_insns)
+ /* Do not scan too many insns, scanning insns is expensive with
+ remote targets. */
+ break;
+
+ /* Continue scanning. */
+ prev_insn_was_prologue_insn = 0;
+ continue;
+ }
+ }
+
+#if 0
+/* I have problems with skipping over __main() that I need to address
+ * sometime. Previously, I used to use misc_function_vector which
+ * didn't work as well as I wanted to be. -MGO */
+
+ /* If the first thing after skipping a prolog is a branch to a function,
+ this might be a call to an initializer in main(), introduced by gcc2.
+ We'd like to skip over it as well. Fortunately, xlc does some extra
+ work before calling a function right after a prologue, thus we can
+ single out such gcc2 behaviour. */
+
+
+ if ((op & 0xfc000001) == 0x48000001)
+ { /* bl foo, an initializer function? */
+ op = read_memory_integer (pc + 4, 4);
+
+ if (op == 0x4def7b82)
+ { /* cror 0xf, 0xf, 0xf (nop) */
+
+ /* check and see if we are in main. If so, skip over this initializer
+ function as well. */
+
+ tmp = find_pc_misc_function (pc);
+ if (tmp >= 0 && STREQ (misc_function_vector[tmp].name, main_name ()))
+ return pc + 8;
+ }
+ }
+#endif /* 0 */
+
+ fdata->offset = -fdata->offset;
+ return last_prologue_pc;
+}
+
+
+/*************************************************************************
+ Support for creating pushing a dummy frame into the stack, and popping
+ frames, etc.
+*************************************************************************/
+
+
+/* Pop the innermost frame, go back to the caller. */
+
+static void
+rs6000_pop_frame (void)
+{
+ CORE_ADDR pc, lr, sp, prev_sp, addr; /* %pc, %lr, %sp */
+ struct rs6000_framedata fdata;
+ struct frame_info *frame = get_current_frame ();
+ int ii, wordsize;
+
+ pc = read_pc ();
+ sp = FRAME_FP (frame);
+
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ {
+ generic_pop_dummy_frame ();
+ flush_cached_frames ();
+ return;
+ }
+
+ /* Make sure that all registers are valid. */
+ read_register_bytes (0, NULL, REGISTER_BYTES);
+
+ /* figure out previous %pc value. If the function is frameless, it is
+ still in the link register, otherwise walk the frames and retrieve the
+ saved %pc value in the previous frame. */
+
+ addr = get_pc_function_start (frame->pc);
+ (void) skip_prologue (addr, frame->pc, &fdata);
+
+ wordsize = TDEP->wordsize;
+ if (fdata.frameless)
+ prev_sp = sp;
+ else
+ prev_sp = read_memory_addr (sp, wordsize);
+ if (fdata.lr_offset == 0)
+ lr = read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum);
+ else
+ lr = read_memory_addr (prev_sp + fdata.lr_offset, wordsize);
+
+ /* reset %pc value. */
+ write_register (PC_REGNUM, lr);
+
+ /* reset register values if any was saved earlier. */
+
+ if (fdata.saved_gpr != -1)
+ {
+ addr = prev_sp + fdata.gpr_offset;
+ for (ii = fdata.saved_gpr; ii <= 31; ++ii)
+ {
+ read_memory (addr, &registers[REGISTER_BYTE (ii)], wordsize);
+ addr += wordsize;
+ }
+ }
+
+ if (fdata.saved_fpr != -1)
+ {
+ addr = prev_sp + fdata.fpr_offset;
+ for (ii = fdata.saved_fpr; ii <= 31; ++ii)
+ {
+ read_memory (addr, &registers[REGISTER_BYTE (ii + FP0_REGNUM)], 8);
+ addr += 8;
+ }
+ }
+
+ write_register (SP_REGNUM, prev_sp);
+ target_store_registers (-1);
+ flush_cached_frames ();
+}
+
+/* Fixup the call sequence of a dummy function, with the real function
+ address. Its arguments will be passed by gdb. */
+
+static void
+rs6000_fix_call_dummy (char *dummyname, CORE_ADDR pc, CORE_ADDR fun,
+ int nargs, struct value **args, struct type *type,
+ int gcc_p)
+{
+ int ii;
+ CORE_ADDR target_addr;
+
+ if (rs6000_find_toc_address_hook != NULL)
+ {
+ CORE_ADDR tocvalue = (*rs6000_find_toc_address_hook) (fun);
+ write_register (gdbarch_tdep (current_gdbarch)->ppc_toc_regnum,
+ tocvalue);
+ }
+}
+
+/* Pass the arguments in either registers, or in the stack. In RS/6000,
+ the first eight words of the argument list (that might be less than
+ eight parameters if some parameters occupy more than one word) are
+ passed in r3..r10 registers. float and double parameters are
+ passed in fpr's, in addition to that. Rest of the parameters if any
+ are passed in user stack. There might be cases in which half of the
+ parameter is copied into registers, the other half is pushed into
+ stack.
+
+ Stack must be aligned on 64-bit boundaries when synthesizing
+ function calls.
+
+ If the function is returning a structure, then the return address is passed
+ in r3, then the first 7 words of the parameters can be passed in registers,
+ starting from r4. */
+
+static CORE_ADDR
+rs6000_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int ii;
+ int len = 0;
+ int argno; /* current argument number */
+ int argbytes; /* current argument byte */
+ char tmp_buffer[50];
+ int f_argno = 0; /* current floating point argno */
+ int wordsize = TDEP->wordsize;
+
+ struct value *arg = 0;
+ struct type *type;
+
+ CORE_ADDR saved_sp;
+
+ /* The first eight words of ther arguments are passed in registers. Copy
+ them appropriately.
+
+ If the function is returning a `struct', then the first word (which
+ will be passed in r3) is used for struct return address. In that
+ case we should advance one word and start from r4 register to copy
+ parameters. */
+
+ ii = struct_return ? 1 : 0;
+
+/*
+ effectively indirect call... gcc does...
+
+ return_val example( float, int);
+
+ eabi:
+ float in fp0, int in r3
+ offset of stack on overflow 8/16
+ for varargs, must go by type.
+ power open:
+ float in r3&r4, int in r5
+ offset of stack on overflow different
+ both:
+ return in r3 or f0. If no float, must study how gcc emulates floats;
+ pay attention to arg promotion.
+ User may have to cast\args to handle promotion correctly
+ since gdb won't know if prototype supplied or not.
+ */
+
+ for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii)
+ {
+ int reg_size = REGISTER_RAW_SIZE (ii + 3);
+
+ arg = args[argno];
+ type = check_typedef (VALUE_TYPE (arg));
+ len = TYPE_LENGTH (type);
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
+
+ /* floating point arguments are passed in fpr's, as well as gpr's.
+ There are 13 fpr's reserved for passing parameters. At this point
+ there is no way we would run out of them. */
+
+ if (len > 8)
+ printf_unfiltered (
+ "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
+
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM + 1 + f_argno)],
+ VALUE_CONTENTS (arg),
+ len);
+ ++f_argno;
+ }
+
+ if (len > reg_size)
+ {
+
+ /* Argument takes more than one register. */
+ while (argbytes < len)
+ {
+ memset (&registers[REGISTER_BYTE (ii + 3)], 0, reg_size);
+ memcpy (&registers[REGISTER_BYTE (ii + 3)],
+ ((char *) VALUE_CONTENTS (arg)) + argbytes,
+ (len - argbytes) > reg_size
+ ? reg_size : len - argbytes);
+ ++ii, argbytes += reg_size;
+
+ if (ii >= 8)
+ goto ran_out_of_registers_for_arguments;
+ }
+ argbytes = 0;
+ --ii;
+ }
+ else
+ { /* Argument can fit in one register. No problem. */
+ int adj = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? reg_size - len : 0;
+ memset (&registers[REGISTER_BYTE (ii + 3)], 0, reg_size);
+ memcpy ((char *)&registers[REGISTER_BYTE (ii + 3)] + adj,
+ VALUE_CONTENTS (arg), len);
+ }
+ ++argno;
+ }
+
+ran_out_of_registers_for_arguments:
+
+ saved_sp = read_sp ();
+
+ /* location for 8 parameters are always reserved. */
+ sp -= wordsize * 8;
+
+ /* another six words for back chain, TOC register, link register, etc. */
+ sp -= wordsize * 6;
+
+ /* stack pointer must be quadword aligned */
+ sp &= -16;
+
+ /* if there are more arguments, allocate space for them in
+ the stack, then push them starting from the ninth one. */
+
+ if ((argno < nargs) || argbytes)
+ {
+ int space = 0, jj;
+
+ if (argbytes)
+ {
+ space += ((len - argbytes + 3) & -4);
+ jj = argno + 1;
+ }
+ else
+ jj = argno;
+
+ for (; jj < nargs; ++jj)
+ {
+ struct value *val = args[jj];
+ space += ((TYPE_LENGTH (VALUE_TYPE (val))) + 3) & -4;
+ }
+
+ /* add location required for the rest of the parameters */
+ space = (space + 15) & -16;
+ sp -= space;
+
+ /* This is another instance we need to be concerned about securing our
+ stack space. If we write anything underneath %sp (r1), we might conflict
+ with the kernel who thinks he is free to use this area. So, update %sp
+ first before doing anything else. */
+
+ write_register (SP_REGNUM, sp);
+
+ /* if the last argument copied into the registers didn't fit there
+ completely, push the rest of it into stack. */
+
+ if (argbytes)
+ {
+ write_memory (sp + 24 + (ii * 4),
+ ((char *) VALUE_CONTENTS (arg)) + argbytes,
+ len - argbytes);
+ ++argno;
+ ii += ((len - argbytes + 3) & -4) / 4;
+ }
+
+ /* push the rest of the arguments into stack. */
+ for (; argno < nargs; ++argno)
+ {
+
+ arg = args[argno];
+ type = check_typedef (VALUE_TYPE (arg));
+ len = TYPE_LENGTH (type);
+
+
+ /* float types should be passed in fpr's, as well as in the stack. */
+ if (TYPE_CODE (type) == TYPE_CODE_FLT && f_argno < 13)
+ {
+
+ if (len > 8)
+ printf_unfiltered (
+ "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
+
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM + 1 + f_argno)],
+ VALUE_CONTENTS (arg),
+ len);
+ ++f_argno;
+ }
+
+ write_memory (sp + 24 + (ii * 4), (char *) VALUE_CONTENTS (arg), len);
+ ii += ((len + 3) & -4) / 4;
+ }
+ }
+ else
+ /* Secure stack areas first, before doing anything else. */
+ write_register (SP_REGNUM, sp);
+
+ /* set back chain properly */
+ store_address (tmp_buffer, 4, saved_sp);
+ write_memory (sp, tmp_buffer, 4);
+
+ target_store_registers (-1);
+ return sp;
+}
+
+/* Function: ppc_push_return_address (pc, sp)
+ Set up the return address for the inferior function call. */
+
+static CORE_ADDR
+ppc_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ write_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum,
+ CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+/* Extract a function return value of type TYPE from raw register array
+ REGBUF, and copy that return value into VALBUF in virtual format. */
+
+static void
+rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
+{
+ int offset = 0;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
+ {
+
+ double dd;
+ float ff;
+ /* floats and doubles are returned in fpr1. fpr's have a size of 8 bytes.
+ We need to truncate the return value into float size (4 byte) if
+ necessary. */
+
+ if (TYPE_LENGTH (valtype) > 4) /* this is a double */
+ memcpy (valbuf,
+ &regbuf[REGISTER_BYTE (FP0_REGNUM + 1)],
+ TYPE_LENGTH (valtype));
+ else
+ { /* float */
+ memcpy (&dd, &regbuf[REGISTER_BYTE (FP0_REGNUM + 1)], 8);
+ ff = (float) dd;
+ memcpy (valbuf, &ff, sizeof (float));
+ }
+ }
+ else if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY
+ && TYPE_LENGTH (valtype) == 16
+ && TYPE_VECTOR (valtype))
+ {
+ memcpy (valbuf, regbuf + REGISTER_BYTE (tdep->ppc_vr0_regnum + 2),
+ TYPE_LENGTH (valtype));
+ }
+ else
+ {
+ /* return value is copied starting from r3. */
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ && TYPE_LENGTH (valtype) < REGISTER_RAW_SIZE (3))
+ offset = REGISTER_RAW_SIZE (3) - TYPE_LENGTH (valtype);
+
+ memcpy (valbuf,
+ regbuf + REGISTER_BYTE (3) + offset,
+ TYPE_LENGTH (valtype));
+ }
+}
+
+/* Keep structure return address in this variable.
+ FIXME: This is a horrid kludge which should not be allowed to continue
+ living. This only allows a single nested call to a structure-returning
+ function. Come on, guys! -- gnu@cygnus.com, Aug 92 */
+
+static CORE_ADDR rs6000_struct_return_address;
+
+/* Return whether handle_inferior_event() should proceed through code
+ starting at PC in function NAME when stepping.
+
+ The AIX -bbigtoc linker option generates functions @FIX0, @FIX1, etc. to
+ handle memory references that are too distant to fit in instructions
+ generated by the compiler. For example, if 'foo' in the following
+ instruction:
+
+ lwz r9,foo(r2)
+
+ is greater than 32767, the linker might replace the lwz with a branch to
+ somewhere in @FIX1 that does the load in 2 instructions and then branches
+ back to where execution should continue.
+
+ GDB should silently step over @FIX code, just like AIX dbx does.
+ Unfortunately, the linker uses the "b" instruction for the branches,
+ meaning that the link register doesn't get set. Therefore, GDB's usual
+ step_over_function() mechanism won't work.
+
+ Instead, use the IN_SOLIB_RETURN_TRAMPOLINE and SKIP_TRAMPOLINE_CODE hooks
+ in handle_inferior_event() to skip past @FIX code. */
+
+int
+rs6000_in_solib_return_trampoline (CORE_ADDR pc, char *name)
+{
+ return name && !strncmp (name, "@FIX", 4);
+}
+
+/* Skip code that the user doesn't want to see when stepping:
+
+ 1. Indirect function calls use a piece of trampoline code to do context
+ switching, i.e. to set the new TOC table. Skip such code if we are on
+ its first instruction (as when we have single-stepped to here).
+
+ 2. Skip shared library trampoline code (which is different from
+ indirect function call trampolines).
+
+ 3. Skip bigtoc fixup code.
+
+ Result is desired PC to step until, or NULL if we are not in
+ code that should be skipped. */
+
+CORE_ADDR
+rs6000_skip_trampoline_code (CORE_ADDR pc)
+{
+ register unsigned int ii, op;
+ int rel;
+ CORE_ADDR solib_target_pc;
+ struct minimal_symbol *msymbol;
+
+ static unsigned trampoline_code[] =
+ {
+ 0x800b0000, /* l r0,0x0(r11) */
+ 0x90410014, /* st r2,0x14(r1) */
+ 0x7c0903a6, /* mtctr r0 */
+ 0x804b0004, /* l r2,0x4(r11) */
+ 0x816b0008, /* l r11,0x8(r11) */
+ 0x4e800420, /* bctr */
+ 0x4e800020, /* br */
+ 0
+ };
+
+ /* Check for bigtoc fixup code. */
+ msymbol = lookup_minimal_symbol_by_pc (pc);
+ if (msymbol && rs6000_in_solib_return_trampoline (pc, SYMBOL_NAME (msymbol)))
+ {
+ /* Double-check that the third instruction from PC is relative "b". */
+ op = read_memory_integer (pc + 8, 4);
+ if ((op & 0xfc000003) == 0x48000000)
+ {
+ /* Extract bits 6-29 as a signed 24-bit relative word address and
+ add it to the containing PC. */
+ rel = ((int)(op << 6) >> 6);
+ return pc + 8 + rel;
+ }
+ }
+
+ /* If pc is in a shared library trampoline, return its target. */
+ solib_target_pc = find_solib_trampoline_target (pc);
+ if (solib_target_pc)
+ return solib_target_pc;
+
+ for (ii = 0; trampoline_code[ii]; ++ii)
+ {
+ op = read_memory_integer (pc + (ii * 4), 4);
+ if (op != trampoline_code[ii])
+ return 0;
+ }
+ ii = read_register (11); /* r11 holds destination addr */
+ pc = read_memory_addr (ii, TDEP->wordsize); /* (r11) value */
+ return pc;
+}
+
+/* Determines whether the function FI has a frame on the stack or not. */
+
+int
+rs6000_frameless_function_invocation (struct frame_info *fi)
+{
+ CORE_ADDR func_start;
+ struct rs6000_framedata fdata;
+
+ /* Don't even think about framelessness except on the innermost frame
+ or if the function was interrupted by a signal. */
+ if (fi->next != NULL && !fi->next->signal_handler_caller)
+ return 0;
+
+ func_start = get_pc_function_start (fi->pc);
+
+ /* If we failed to find the start of the function, it is a mistake
+ to inspect the instructions. */
+
+ if (!func_start)
+ {
+ /* A frame with a zero PC is usually created by dereferencing a NULL
+ function pointer, normally causing an immediate core dump of the
+ inferior. Mark function as frameless, as the inferior has no chance
+ of setting up a stack frame. */
+ if (fi->pc == 0)
+ return 1;
+ else
+ return 0;
+ }
+
+ (void) skip_prologue (func_start, fi->pc, &fdata);
+ return fdata.frameless;
+}
+
+/* Return the PC saved in a frame */
+
+CORE_ADDR
+rs6000_frame_saved_pc (struct frame_info *fi)
+{
+ CORE_ADDR func_start;
+ struct rs6000_framedata fdata;
+ struct gdbarch_tdep *tdep = TDEP;
+ int wordsize = tdep->wordsize;
+
+ if (fi->signal_handler_caller)
+ return read_memory_addr (fi->frame + SIG_FRAME_PC_OFFSET, wordsize);
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
+
+ func_start = get_pc_function_start (fi->pc);
+
+ /* If we failed to find the start of the function, it is a mistake
+ to inspect the instructions. */
+ if (!func_start)
+ return 0;
+
+ (void) skip_prologue (func_start, fi->pc, &fdata);
+
+ if (fdata.lr_offset == 0 && fi->next != NULL)
+ {
+ if (fi->next->signal_handler_caller)
+ return read_memory_addr (fi->next->frame + SIG_FRAME_LR_OFFSET,
+ wordsize);
+ else
+ return read_memory_addr (FRAME_CHAIN (fi) + tdep->lr_frame_offset,
+ wordsize);
+ }
+
+ if (fdata.lr_offset == 0)
+ return read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum);
+
+ return read_memory_addr (FRAME_CHAIN (fi) + fdata.lr_offset, wordsize);
+}
+
+/* If saved registers of frame FI are not known yet, read and cache them.
+ &FDATAP contains rs6000_framedata; TDATAP can be NULL,
+ in which case the framedata are read. */
+
+static void
+frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap)
+{
+ CORE_ADDR frame_addr;
+ struct rs6000_framedata work_fdata;
+ struct gdbarch_tdep * tdep = gdbarch_tdep (current_gdbarch);
+ int wordsize = tdep->wordsize;
+
+ if (fi->saved_regs)
+ return;
+
+ if (fdatap == NULL)
+ {
+ fdatap = &work_fdata;
+ (void) skip_prologue (get_pc_function_start (fi->pc), fi->pc, fdatap);
+ }
+
+ frame_saved_regs_zalloc (fi);
+
+ /* If there were any saved registers, figure out parent's stack
+ pointer. */
+ /* The following is true only if the frame doesn't have a call to
+ alloca(), FIXME. */
+
+ if (fdatap->saved_fpr == 0
+ && fdatap->saved_gpr == 0
+ && fdatap->saved_vr == 0
+ && fdatap->lr_offset == 0
+ && fdatap->cr_offset == 0
+ && fdatap->vr_offset == 0)
+ frame_addr = 0;
+ else
+ /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most
+ address of the current frame. Things might be easier if the
+ ->frame pointed to the outer-most address of the frame. In the
+ mean time, the address of the prev frame is used as the base
+ address of this frame. */
+ frame_addr = FRAME_CHAIN (fi);
+
+ /* if != -1, fdatap->saved_fpr is the smallest number of saved_fpr.
+ All fpr's from saved_fpr to fp31 are saved. */
+
+ if (fdatap->saved_fpr >= 0)
+ {
+ int i;
+ CORE_ADDR fpr_addr = frame_addr + fdatap->fpr_offset;
+ for (i = fdatap->saved_fpr; i < 32; i++)
+ {
+ fi->saved_regs[FP0_REGNUM + i] = fpr_addr;
+ fpr_addr += 8;
+ }
+ }
+
+ /* if != -1, fdatap->saved_gpr is the smallest number of saved_gpr.
+ All gpr's from saved_gpr to gpr31 are saved. */
+
+ if (fdatap->saved_gpr >= 0)
+ {
+ int i;
+ CORE_ADDR gpr_addr = frame_addr + fdatap->gpr_offset;
+ for (i = fdatap->saved_gpr; i < 32; i++)
+ {
+ fi->saved_regs[i] = gpr_addr;
+ gpr_addr += wordsize;
+ }
+ }
+
+ /* if != -1, fdatap->saved_vr is the smallest number of saved_vr.
+ All vr's from saved_vr to vr31 are saved. */
+ if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
+ {
+ if (fdatap->saved_vr >= 0)
+ {
+ int i;
+ CORE_ADDR vr_addr = frame_addr + fdatap->vr_offset;
+ for (i = fdatap->saved_vr; i < 32; i++)
+ {
+ fi->saved_regs[tdep->ppc_vr0_regnum + i] = vr_addr;
+ vr_addr += REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum);
+ }
+ }
+ }
+
+ /* If != 0, fdatap->cr_offset is the offset from the frame that holds
+ the CR. */
+ if (fdatap->cr_offset != 0)
+ fi->saved_regs[tdep->ppc_cr_regnum] = frame_addr + fdatap->cr_offset;
+
+ /* If != 0, fdatap->lr_offset is the offset from the frame that holds
+ the LR. */
+ if (fdatap->lr_offset != 0)
+ fi->saved_regs[tdep->ppc_lr_regnum] = frame_addr + fdatap->lr_offset;
+
+ /* If != 0, fdatap->vrsave_offset is the offset from the frame that holds
+ the VRSAVE. */
+ if (fdatap->vrsave_offset != 0)
+ fi->saved_regs[tdep->ppc_vrsave_regnum] = frame_addr + fdatap->vrsave_offset;
+}
+
+/* Return the address of a frame. This is the inital %sp value when the frame
+ was first allocated. For functions calling alloca(), it might be saved in
+ an alloca register. */
+
+static CORE_ADDR
+frame_initial_stack_address (struct frame_info *fi)
+{
+ CORE_ADDR tmpaddr;
+ struct rs6000_framedata fdata;
+ struct frame_info *callee_fi;
+
+ /* if the initial stack pointer (frame address) of this frame is known,
+ just return it. */
+
+ if (fi->extra_info->initial_sp)
+ return fi->extra_info->initial_sp;
+
+ /* find out if this function is using an alloca register.. */
+
+ (void) skip_prologue (get_pc_function_start (fi->pc), fi->pc, &fdata);
+
+ /* if saved registers of this frame are not known yet, read and cache them. */
+
+ if (!fi->saved_regs)
+ frame_get_saved_regs (fi, &fdata);
+
+ /* If no alloca register used, then fi->frame is the value of the %sp for
+ this frame, and it is good enough. */
+
+ if (fdata.alloca_reg < 0)
+ {
+ fi->extra_info->initial_sp = fi->frame;
+ return fi->extra_info->initial_sp;
+ }
+
+ /* There is an alloca register, use its value, in the current frame,
+ as the initial stack pointer. */
+ {
+ char *tmpbuf = alloca (MAX_REGISTER_RAW_SIZE);
+ if (frame_register_read (fi, fdata.alloca_reg, tmpbuf))
+ {
+ fi->extra_info->initial_sp
+ = extract_unsigned_integer (tmpbuf,
+ REGISTER_RAW_SIZE (fdata.alloca_reg));
+ }
+ else
+ /* NOTE: cagney/2002-04-17: At present the only time
+ frame_register_read will fail is when the register isn't
+ available. If that does happen, use the frame. */
+ fi->extra_info->initial_sp = fi->frame;
+ }
+ return fi->extra_info->initial_sp;
+}
+
+/* Describe the pointer in each stack frame to the previous stack frame
+ (its caller). */
+
+/* FRAME_CHAIN takes a frame's nominal address
+ and produces the frame's chain-pointer. */
+
+/* In the case of the RS/6000, the frame's nominal address
+ is the address of a 4-byte word containing the calling frame's address. */
+
+CORE_ADDR
+rs6000_frame_chain (struct frame_info *thisframe)
+{
+ CORE_ADDR fp, fpp, lr;
+ int wordsize = TDEP->wordsize;
+
+ if (PC_IN_CALL_DUMMY (thisframe->pc, thisframe->frame, thisframe->frame))
+ return thisframe->frame; /* dummy frame same as caller's frame */
+
+ if (inside_entry_file (thisframe->pc) ||
+ thisframe->pc == entry_point_address ())
+ return 0;
+
+ if (thisframe->signal_handler_caller)
+ fp = read_memory_addr (thisframe->frame + SIG_FRAME_FP_OFFSET,
+ wordsize);
+ else if (thisframe->next != NULL
+ && thisframe->next->signal_handler_caller
+ && FRAMELESS_FUNCTION_INVOCATION (thisframe))
+ /* A frameless function interrupted by a signal did not change the
+ frame pointer. */
+ fp = FRAME_FP (thisframe);
+ else
+ fp = read_memory_addr ((thisframe)->frame, wordsize);
+
+ lr = read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum);
+ if (lr == entry_point_address ())
+ if (fp != 0 && (fpp = read_memory_addr (fp, wordsize)) != 0)
+ if (PC_IN_CALL_DUMMY (lr, fpp, fpp))
+ return fpp;
+
+ return fp;
+}
+
+/* Return the size of register REG when words are WORDSIZE bytes long. If REG
+ isn't available with that word size, return 0. */
+
+static int
+regsize (const struct reg *reg, int wordsize)
+{
+ return wordsize == 8 ? reg->sz64 : reg->sz32;
+}
+
+/* Return the name of register number N, or null if no such register exists
+ in the current architecture. */
+
+static char *
+rs6000_register_name (int n)
+{
+ struct gdbarch_tdep *tdep = TDEP;
+ const struct reg *reg = tdep->regs + n;
+
+ if (!regsize (reg, tdep->wordsize))
+ return NULL;
+ return reg->name;
+}
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+static int
+rs6000_register_byte (int n)
+{
+ return TDEP->regoff[n];
+}
+
+/* Return the number of bytes of storage in the actual machine representation
+ for register N if that register is available, else return 0. */
+
+static int
+rs6000_register_raw_size (int n)
+{
+ struct gdbarch_tdep *tdep = TDEP;
+ const struct reg *reg = tdep->regs + n;
+ return regsize (reg, tdep->wordsize);
+}
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+static struct type *
+rs6000_register_virtual_type (int n)
+{
+ struct gdbarch_tdep *tdep = TDEP;
+ const struct reg *reg = tdep->regs + n;
+
+ if (reg->fpr)
+ return builtin_type_double;
+ else
+ {
+ int size = regsize (reg, tdep->wordsize);
+ switch (size)
+ {
+ case 8:
+ return builtin_type_int64;
+ break;
+ case 16:
+ return builtin_type_vec128;
+ break;
+ default:
+ return builtin_type_int32;
+ break;
+ }
+ }
+}
+
+/* For the PowerPC, it appears that the debug info marks float parameters as
+ floats regardless of whether the function is prototyped, but the actual
+ values are always passed in as doubles. Tell gdb to always assume that
+ floats are passed as doubles and then converted in the callee. */
+
+static int
+rs6000_coerce_float_to_double (struct type *formal, struct type *actual)
+{
+ return 1;
+}
+
+/* Return whether register N requires conversion when moving from raw format
+ to virtual format.
+
+ The register format for RS/6000 floating point registers is always
+ double, we need a conversion if the memory format is float. */
+
+static int
+rs6000_register_convertible (int n)
+{
+ const struct reg *reg = TDEP->regs + n;
+ return reg->fpr;
+}
+
+/* Convert data from raw format for register N in buffer FROM
+ to virtual format with type TYPE in buffer TO. */
+
+static void
+rs6000_register_convert_to_virtual (int n, struct type *type,
+ char *from, char *to)
+{
+ if (TYPE_LENGTH (type) != REGISTER_RAW_SIZE (n))
+ {
+ double val = extract_floating (from, REGISTER_RAW_SIZE (n));
+ store_floating (to, TYPE_LENGTH (type), val);
+ }
+ else
+ memcpy (to, from, REGISTER_RAW_SIZE (n));
+}
+
+/* Convert data from virtual format with type TYPE in buffer FROM
+ to raw format for register N in buffer TO. */
+
+static void
+rs6000_register_convert_to_raw (struct type *type, int n,
+ char *from, char *to)
+{
+ if (TYPE_LENGTH (type) != REGISTER_RAW_SIZE (n))
+ {
+ double val = extract_floating (from, TYPE_LENGTH (type));
+ store_floating (to, REGISTER_RAW_SIZE (n), val);
+ }
+ else
+ memcpy (to, from, REGISTER_RAW_SIZE (n));
+}
+
+int
+altivec_register_p (int regno)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ if (tdep->ppc_vr0_regnum < 0 || tdep->ppc_vrsave_regnum < 0)
+ return 0;
+ else
+ return (regno >= tdep->ppc_vr0_regnum && regno <= tdep->ppc_vrsave_regnum);
+}
+
+static void
+rs6000_do_altivec_registers (int regnum)
+{
+ int i;
+ char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ char *virtual_buffer = (char*) alloca (MAX_REGISTER_VIRTUAL_SIZE);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ for (i = tdep->ppc_vr0_regnum; i <= tdep->ppc_vrsave_regnum; i++)
+ {
+ /* If we want just one reg, check that this is the one we want. */
+ if (regnum != -1 && i != regnum)
+ continue;
+
+ /* If the register name is empty, it is undefined for this
+ processor, so don't display anything. */
+ if (REGISTER_NAME (i) == NULL || *(REGISTER_NAME (i)) == '\0')
+ continue;
+
+ fputs_filtered (REGISTER_NAME (i), gdb_stdout);
+ print_spaces_filtered (15 - strlen (REGISTER_NAME (i)), gdb_stdout);
+
+ /* Get the data in raw format. */
+ if (!frame_register_read (selected_frame, i, raw_buffer))
+ {
+ printf_filtered ("*value not available*\n");
+ continue;
+ }
+
+ /* Convert raw data to virtual format if necessary. */
+ if (REGISTER_CONVERTIBLE (i))
+ REGISTER_CONVERT_TO_VIRTUAL (i, REGISTER_VIRTUAL_TYPE (i),
+ raw_buffer, virtual_buffer);
+ else
+ memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (i));
+
+ /* Print as integer in hex only. */
+ val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
+ gdb_stdout, 'x', 1, 0, Val_pretty_default);
+ printf_filtered ("\n");
+ }
+}
+
+static void
+rs6000_altivec_registers_info (char *addr_exp, int from_tty)
+{
+ int regnum, numregs;
+ register char *end;
+
+ if (!target_has_registers)
+ error ("The program has no registers now.");
+ if (selected_frame == NULL)
+ error ("No selected frame.");
+
+ if (!addr_exp)
+ {
+ rs6000_do_altivec_registers (-1);
+ return;
+ }
+
+ numregs = NUM_REGS + NUM_PSEUDO_REGS;
+ do
+ {
+ if (addr_exp[0] == '$')
+ addr_exp++;
+ end = addr_exp;
+ while (*end != '\0' && *end != ' ' && *end != '\t')
+ ++end;
+
+ regnum = target_map_name_to_register (addr_exp, end - addr_exp);
+ if (regnum < 0)
+ {
+ regnum = numregs;
+ if (*addr_exp >= '0' && *addr_exp <= '9')
+ regnum = atoi (addr_exp); /* Take a number */
+ if (regnum >= numregs) /* Bad name, or bad number */
+ error ("%.*s: invalid register", end - addr_exp, addr_exp);
+ }
+
+ rs6000_do_altivec_registers (regnum);
+
+ addr_exp = end;
+ while (*addr_exp == ' ' || *addr_exp == '\t')
+ ++addr_exp;
+ }
+ while (*addr_exp != '\0');
+}
+
+static void
+rs6000_do_registers_info (int regnum, int fpregs)
+{
+ register int i;
+ int numregs = NUM_REGS + NUM_PSEUDO_REGS;
+ char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ char *virtual_buffer = (char*) alloca (MAX_REGISTER_VIRTUAL_SIZE);
+
+ for (i = 0; i < numregs; i++)
+ {
+ /* Decide between printing all regs, nonfloat regs, or specific reg. */
+ if (regnum == -1)
+ {
+ if ((TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT && !fpregs)
+ || (altivec_register_p (i) && !fpregs))
+ continue;
+ }
+ else
+ {
+ if (i != regnum)
+ continue;
+ }
+
+ /* If the register name is empty, it is undefined for this
+ processor, so don't display anything. */
+ if (REGISTER_NAME (i) == NULL || *(REGISTER_NAME (i)) == '\0')
+ continue;
+
+ fputs_filtered (REGISTER_NAME (i), gdb_stdout);
+ print_spaces_filtered (15 - strlen (REGISTER_NAME (i)), gdb_stdout);
+
+ /* Get the data in raw format. */
+ if (!frame_register_read (selected_frame, i, raw_buffer))
+ {
+ printf_filtered ("*value not available*\n");
+ continue;
+ }
+
+ /* Convert raw data to virtual format if necessary. */
+ if (REGISTER_CONVERTIBLE (i))
+ REGISTER_CONVERT_TO_VIRTUAL (i, REGISTER_VIRTUAL_TYPE (i),
+ raw_buffer, virtual_buffer);
+ else
+ memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (i));
+
+ /* If virtual format is floating, print it that way, and in raw hex. */
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
+ {
+ register int j;
+
+ val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
+ gdb_stdout, 0, 1, 0, Val_pretty_default);
+
+ printf_filtered ("\t(raw 0x");
+ for (j = 0; j < REGISTER_RAW_SIZE (i); j++)
+ {
+ register int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j
+ : REGISTER_RAW_SIZE (i) - 1 - j;
+ printf_filtered ("%02x", (unsigned char) raw_buffer[idx]);
+ }
+ printf_filtered (")");
+ }
+ else
+ {
+ /* Print the register in hex. */
+ val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
+ gdb_stdout, 'x', 1, 0, Val_pretty_default);
+ /* If not a vector register, print it also in decimal. */
+ if (!altivec_register_p (i))
+ {
+ printf_filtered ("\t");
+ val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
+ gdb_stdout, 0, 1, 0, Val_pretty_default);
+ }
+ }
+ printf_filtered ("\n");
+ }
+}
+
+/* Convert a dbx stab register number (from `r' declaration) to a gdb
+ REGNUM. */
+static int
+rs6000_stab_reg_to_regnum (int num)
+{
+ int regnum;
+ switch (num)
+ {
+ case 64:
+ regnum = gdbarch_tdep (current_gdbarch)->ppc_mq_regnum;
+ break;
+ case 65:
+ regnum = gdbarch_tdep (current_gdbarch)->ppc_lr_regnum;
+ break;
+ case 66:
+ regnum = gdbarch_tdep (current_gdbarch)->ppc_ctr_regnum;
+ break;
+ case 76:
+ regnum = gdbarch_tdep (current_gdbarch)->ppc_xer_regnum;
+ break;
+ default:
+ regnum = num;
+ break;
+ }
+ return regnum;
+}
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function.
+
+ In RS/6000, struct return addresses are passed as an extra parameter in r3.
+ In function return, callee is not responsible of returning this address
+ back. Since gdb needs to find it, we will store in a designated variable
+ `rs6000_struct_return_address'. */
+
+static void
+rs6000_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ write_register (3, addr);
+ rs6000_struct_return_address = addr;
+}
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format. */
+
+static void
+rs6000_store_return_value (struct type *type, char *valbuf)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+
+ /* Floating point values are returned starting from FPR1 and up.
+ Say a double_double_double type could be returned in
+ FPR1/FPR2/FPR3 triple. */
+
+ write_register_bytes (REGISTER_BYTE (FP0_REGNUM + 1), valbuf,
+ TYPE_LENGTH (type));
+ else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ if (TYPE_LENGTH (type) == 16
+ && TYPE_VECTOR (type))
+ write_register_bytes (REGISTER_BYTE (tdep->ppc_vr0_regnum + 2),
+ valbuf, TYPE_LENGTH (type));
+ }
+ else
+ /* Everything else is returned in GPR3 and up. */
+ write_register_bytes (REGISTER_BYTE (gdbarch_tdep (current_gdbarch)->ppc_gp0_regnum + 3),
+ valbuf, TYPE_LENGTH (type));
+}
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+
+static CORE_ADDR
+rs6000_extract_struct_value_address (char *regbuf)
+{
+ return rs6000_struct_return_address;
+}
+
+/* Return whether PC is in a dummy function call.
+
+ FIXME: This just checks for the end of the stack, which is broken
+ for things like stepping through gcc nested function stubs. */
+
+static int
+rs6000_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR fp)
+{
+ return sp < pc && pc < fp;
+}
+
+/* Hook called when a new child process is started. */
+
+void
+rs6000_create_inferior (int pid)
+{
+ if (rs6000_set_host_arch_hook)
+ rs6000_set_host_arch_hook (pid);
+}
+
+/* Support for CONVERT_FROM_FUNC_PTR_ADDR(ADDR).
+
+ Usually a function pointer's representation is simply the address
+ of the function. On the RS/6000 however, a function pointer is
+ represented by a pointer to a TOC entry. This TOC entry contains
+ three words, the first word is the address of the function, the
+ second word is the TOC pointer (r2), and the third word is the
+ static chain value. Throughout GDB it is currently assumed that a
+ function pointer contains the address of the function, which is not
+ easy to fix. In addition, the conversion of a function address to
+ a function pointer would require allocation of a TOC entry in the
+ inferior's memory space, with all its drawbacks. To be able to
+ call C++ virtual methods in the inferior (which are called via
+ function pointers), find_function_addr uses this function to get the
+ function address from a function pointer. */
+
+/* Return real function address if ADDR (a function pointer) is in the data
+ space and is therefore a special function pointer. */
+
+CORE_ADDR
+rs6000_convert_from_func_ptr_addr (CORE_ADDR addr)
+{
+ struct obj_section *s;
+
+ s = find_pc_section (addr);
+ if (s && s->the_bfd_section->flags & SEC_CODE)
+ return addr;
+
+ /* ADDR is in the data space, so it's a special function pointer. */
+ return read_memory_addr (addr, TDEP->wordsize);
+}
+
+
+/* Handling the various POWER/PowerPC variants. */
+
+
+/* The arrays here called registers_MUMBLE hold information about available
+ registers.
+
+ For each family of PPC variants, I've tried to isolate out the
+ common registers and put them up front, so that as long as you get
+ the general family right, GDB will correctly identify the registers
+ common to that family. The common register sets are:
+
+ For the 60x family: hid0 hid1 iabr dabr pir
+
+ For the 505 and 860 family: eie eid nri
+
+ For the 403 and 403GC: icdbdr esr dear evpr cdbcr tsr tcr pit tbhi
+ tblo srr2 srr3 dbsr dbcr iac1 iac2 dac1 dac2 dccr iccr pbl1
+ pbu1 pbl2 pbu2
+
+ Most of these register groups aren't anything formal. I arrived at
+ them by looking at the registers that occurred in more than one
+ processor.
+
+ Note: kevinb/2002-04-30: Support for the fpscr register was added
+ during April, 2002. Slot 70 is being used for PowerPC and slot 71
+ for Power. For PowerPC, slot 70 was unused and was already in the
+ PPC_UISA_SPRS which is ideally where fpscr should go. For Power,
+ slot 70 was being used for "mq", so the next available slot (71)
+ was chosen. It would have been nice to be able to make the
+ register numbers the same across processor cores, but this wasn't
+ possible without either 1) renumbering some registers for some
+ processors or 2) assigning fpscr to a really high slot that's
+ larger than any current register number. Doing (1) is bad because
+ existing stubs would break. Doing (2) is undesirable because it
+ would introduce a really large gap between fpscr and the rest of
+ the registers for most processors. */
+
+/* Convenience macros for populating register arrays. */
+
+/* Within another macro, convert S to a string. */
+
+#define STR(s) #s
+
+/* Return a struct reg defining register NAME that's 32 bits on 32-bit systems
+ and 64 bits on 64-bit systems. */
+#define R(name) { STR(name), 4, 8, 0 }
+
+/* Return a struct reg defining register NAME that's 32 bits on all
+ systems. */
+#define R4(name) { STR(name), 4, 4, 0 }
+
+/* Return a struct reg defining register NAME that's 64 bits on all
+ systems. */
+#define R8(name) { STR(name), 8, 8, 0 }
+
+/* Return a struct reg defining register NAME that's 128 bits on all
+ systems. */
+#define R16(name) { STR(name), 16, 16, 0 }
+
+/* Return a struct reg defining floating-point register NAME. */
+#define F(name) { STR(name), 8, 8, 1 }
+
+/* Return a struct reg defining register NAME that's 32 bits on 32-bit
+ systems and that doesn't exist on 64-bit systems. */
+#define R32(name) { STR(name), 4, 0, 0 }
+
+/* Return a struct reg defining register NAME that's 64 bits on 64-bit
+ systems and that doesn't exist on 32-bit systems. */
+#define R64(name) { STR(name), 0, 8, 0 }
+
+/* Return a struct reg placeholder for a register that doesn't exist. */
+#define R0 { 0, 0, 0, 0 }
+
+/* UISA registers common across all architectures, including POWER. */
+
+#define COMMON_UISA_REGS \
+ /* 0 */ R(r0), R(r1), R(r2), R(r3), R(r4), R(r5), R(r6), R(r7), \
+ /* 8 */ R(r8), R(r9), R(r10),R(r11),R(r12),R(r13),R(r14),R(r15), \
+ /* 16 */ R(r16),R(r17),R(r18),R(r19),R(r20),R(r21),R(r22),R(r23), \
+ /* 24 */ R(r24),R(r25),R(r26),R(r27),R(r28),R(r29),R(r30),R(r31), \
+ /* 32 */ F(f0), F(f1), F(f2), F(f3), F(f4), F(f5), F(f6), F(f7), \
+ /* 40 */ F(f8), F(f9), F(f10),F(f11),F(f12),F(f13),F(f14),F(f15), \
+ /* 48 */ F(f16),F(f17),F(f18),F(f19),F(f20),F(f21),F(f22),F(f23), \
+ /* 56 */ F(f24),F(f25),F(f26),F(f27),F(f28),F(f29),F(f30),F(f31), \
+ /* 64 */ R(pc), R(ps)
+
+#define COMMON_UISA_NOFP_REGS \
+ /* 0 */ R(r0), R(r1), R(r2), R(r3), R(r4), R(r5), R(r6), R(r7), \
+ /* 8 */ R(r8), R(r9), R(r10),R(r11),R(r12),R(r13),R(r14),R(r15), \
+ /* 16 */ R(r16),R(r17),R(r18),R(r19),R(r20),R(r21),R(r22),R(r23), \
+ /* 24 */ R(r24),R(r25),R(r26),R(r27),R(r28),R(r29),R(r30),R(r31), \
+ /* 32 */ R0, R0, R0, R0, R0, R0, R0, R0, \
+ /* 40 */ R0, R0, R0, R0, R0, R0, R0, R0, \
+ /* 48 */ R0, R0, R0, R0, R0, R0, R0, R0, \
+ /* 56 */ R0, R0, R0, R0, R0, R0, R0, R0, \
+ /* 64 */ R(pc), R(ps)
+
+/* UISA-level SPRs for PowerPC. */
+#define PPC_UISA_SPRS \
+ /* 66 */ R4(cr), R(lr), R(ctr), R4(xer), R4(fpscr)
+
+/* Segment registers, for PowerPC. */
+#define PPC_SEGMENT_REGS \
+ /* 71 */ R32(sr0), R32(sr1), R32(sr2), R32(sr3), \
+ /* 75 */ R32(sr4), R32(sr5), R32(sr6), R32(sr7), \
+ /* 79 */ R32(sr8), R32(sr9), R32(sr10), R32(sr11), \
+ /* 83 */ R32(sr12), R32(sr13), R32(sr14), R32(sr15)
+
+/* OEA SPRs for PowerPC. */
+#define PPC_OEA_SPRS \
+ /* 87 */ R4(pvr), \
+ /* 88 */ R(ibat0u), R(ibat0l), R(ibat1u), R(ibat1l), \
+ /* 92 */ R(ibat2u), R(ibat2l), R(ibat3u), R(ibat3l), \
+ /* 96 */ R(dbat0u), R(dbat0l), R(dbat1u), R(dbat1l), \
+ /* 100 */ R(dbat2u), R(dbat2l), R(dbat3u), R(dbat3l), \
+ /* 104 */ R(sdr1), R64(asr), R(dar), R4(dsisr), \
+ /* 108 */ R(sprg0), R(sprg1), R(sprg2), R(sprg3), \
+ /* 112 */ R(srr0), R(srr1), R(tbl), R(tbu), \
+ /* 116 */ R4(dec), R(dabr), R4(ear)
+
+/* AltiVec registers */
+#define PPC_ALTIVEC_REGS \
+ /*119*/R16(vr0), R16(vr1), R16(vr2), R16(vr3), R16(vr4), R16(vr5), R16(vr6), R16(vr7), \
+ /*127*/R16(vr8), R16(vr9), R16(vr10),R16(vr11),R16(vr12),R16(vr13),R16(vr14),R16(vr15), \
+ /*135*/R16(vr16),R16(vr17),R16(vr18),R16(vr19),R16(vr20),R16(vr21),R16(vr22),R16(vr23), \
+ /*143*/R16(vr24),R16(vr25),R16(vr26),R16(vr27),R16(vr28),R16(vr29),R16(vr30),R16(vr31), \
+ /*151*/R4(vscr), R4(vrsave)
+
+/* IBM POWER (pre-PowerPC) architecture, user-level view. We only cover
+ user-level SPR's. */
+static const struct reg registers_power[] =
+{
+ COMMON_UISA_REGS,
+ /* 66 */ R4(cnd), R(lr), R(cnt), R4(xer), R4(mq),
+ /* 71 */ R4(fpscr)
+};
+
+/* PowerPC UISA - a PPC processor as viewed by user-level code. A UISA-only
+ view of the PowerPC. */
+static const struct reg registers_powerpc[] =
+{
+ COMMON_UISA_REGS,
+ PPC_UISA_SPRS,
+ PPC_ALTIVEC_REGS
+};
+
+/* PowerPC UISA - a PPC processor as viewed by user-level
+ code, but without floating point registers. */
+static const struct reg registers_powerpc_nofp[] =
+{
+ COMMON_UISA_NOFP_REGS,
+ PPC_UISA_SPRS
+};
+
+/* IBM PowerPC 403. */
+static const struct reg registers_403[] =
+{
+ COMMON_UISA_REGS,
+ PPC_UISA_SPRS,
+ PPC_SEGMENT_REGS,
+ PPC_OEA_SPRS,
+ /* 119 */ R(icdbdr), R(esr), R(dear), R(evpr),
+ /* 123 */ R(cdbcr), R(tsr), R(tcr), R(pit),
+ /* 127 */ R(tbhi), R(tblo), R(srr2), R(srr3),
+ /* 131 */ R(dbsr), R(dbcr), R(iac1), R(iac2),
+ /* 135 */ R(dac1), R(dac2), R(dccr), R(iccr),
+ /* 139 */ R(pbl1), R(pbu1), R(pbl2), R(pbu2)
+};
+
+/* IBM PowerPC 403GC. */
+static const struct reg registers_403GC[] =
+{
+ COMMON_UISA_REGS,
+ PPC_UISA_SPRS,
+ PPC_SEGMENT_REGS,
+ PPC_OEA_SPRS,
+ /* 119 */ R(icdbdr), R(esr), R(dear), R(evpr),
+ /* 123 */ R(cdbcr), R(tsr), R(tcr), R(pit),
+ /* 127 */ R(tbhi), R(tblo), R(srr2), R(srr3),
+ /* 131 */ R(dbsr), R(dbcr), R(iac1), R(iac2),
+ /* 135 */ R(dac1), R(dac2), R(dccr), R(iccr),
+ /* 139 */ R(pbl1), R(pbu1), R(pbl2), R(pbu2),
+ /* 143 */ R(zpr), R(pid), R(sgr), R(dcwr),
+ /* 147 */ R(tbhu), R(tblu)
+};
+
+/* Motorola PowerPC 505. */
+static const struct reg registers_505[] =
+{
+ COMMON_UISA_REGS,
+ PPC_UISA_SPRS,
+ PPC_SEGMENT_REGS,
+ PPC_OEA_SPRS,
+ /* 119 */ R(eie), R(eid), R(nri)
+};
+
+/* Motorola PowerPC 860 or 850. */
+static const struct reg registers_860[] =
+{
+ COMMON_UISA_REGS,
+ PPC_UISA_SPRS,
+ PPC_SEGMENT_REGS,
+ PPC_OEA_SPRS,
+ /* 119 */ R(eie), R(eid), R(nri), R(cmpa),
+ /* 123 */ R(cmpb), R(cmpc), R(cmpd), R(icr),
+ /* 127 */ R(der), R(counta), R(countb), R(cmpe),
+ /* 131 */ R(cmpf), R(cmpg), R(cmph), R(lctrl1),
+ /* 135 */ R(lctrl2), R(ictrl), R(bar), R(ic_cst),
+ /* 139 */ R(ic_adr), R(ic_dat), R(dc_cst), R(dc_adr),
+ /* 143 */ R(dc_dat), R(dpdr), R(dpir), R(immr),
+ /* 147 */ R(mi_ctr), R(mi_ap), R(mi_epn), R(mi_twc),
+ /* 151 */ R(mi_rpn), R(md_ctr), R(m_casid), R(md_ap),
+ /* 155 */ R(md_epn), R(md_twb), R(md_twc), R(md_rpn),
+ /* 159 */ R(m_tw), R(mi_dbcam), R(mi_dbram0), R(mi_dbram1),
+ /* 163 */ R(md_dbcam), R(md_dbram0), R(md_dbram1)
+};
+
+/* Motorola PowerPC 601. Note that the 601 has different register numbers
+ for reading and writing RTCU and RTCL. However, how one reads and writes a
+ register is the stub's problem. */
+static const struct reg registers_601[] =
+{
+ COMMON_UISA_REGS,
+ PPC_UISA_SPRS,
+ PPC_SEGMENT_REGS,
+ PPC_OEA_SPRS,
+ /* 119 */ R(hid0), R(hid1), R(iabr), R(dabr),
+ /* 123 */ R(pir), R(mq), R(rtcu), R(rtcl)
+};
+
+/* Motorola PowerPC 602. */
+static const struct reg registers_602[] =
+{
+ COMMON_UISA_REGS,
+ PPC_UISA_SPRS,
+ PPC_SEGMENT_REGS,
+ PPC_OEA_SPRS,
+ /* 119 */ R(hid0), R(hid1), R(iabr), R0,
+ /* 123 */ R0, R(tcr), R(ibr), R(esassr),
+ /* 127 */ R(sebr), R(ser), R(sp), R(lt)
+};
+
+/* Motorola/IBM PowerPC 603 or 603e. */
+static const struct reg registers_603[] =
+{
+ COMMON_UISA_REGS,
+ PPC_UISA_SPRS,
+ PPC_SEGMENT_REGS,
+ PPC_OEA_SPRS,
+ /* 119 */ R(hid0), R(hid1), R(iabr), R0,
+ /* 123 */ R0, R(dmiss), R(dcmp), R(hash1),
+ /* 127 */ R(hash2), R(imiss), R(icmp), R(rpa)
+};
+
+/* Motorola PowerPC 604 or 604e. */
+static const struct reg registers_604[] =
+{
+ COMMON_UISA_REGS,
+ PPC_UISA_SPRS,
+ PPC_SEGMENT_REGS,
+ PPC_OEA_SPRS,
+ /* 119 */ R(hid0), R(hid1), R(iabr), R(dabr),
+ /* 123 */ R(pir), R(mmcr0), R(pmc1), R(pmc2),
+ /* 127 */ R(sia), R(sda)
+};
+
+/* Motorola/IBM PowerPC 750 or 740. */
+static const struct reg registers_750[] =
+{
+ COMMON_UISA_REGS,
+ PPC_UISA_SPRS,
+ PPC_SEGMENT_REGS,
+ PPC_OEA_SPRS,
+ /* 119 */ R(hid0), R(hid1), R(iabr), R(dabr),
+ /* 123 */ R0, R(ummcr0), R(upmc1), R(upmc2),
+ /* 127 */ R(usia), R(ummcr1), R(upmc3), R(upmc4),
+ /* 131 */ R(mmcr0), R(pmc1), R(pmc2), R(sia),
+ /* 135 */ R(mmcr1), R(pmc3), R(pmc4), R(l2cr),
+ /* 139 */ R(ictc), R(thrm1), R(thrm2), R(thrm3)
+};
+
+
+/* Motorola PowerPC 7400. */
+static const struct reg registers_7400[] =
+{
+ /* gpr0-gpr31, fpr0-fpr31 */
+ COMMON_UISA_REGS,
+ /* ctr, xre, lr, cr */
+ PPC_UISA_SPRS,
+ /* sr0-sr15 */
+ PPC_SEGMENT_REGS,
+ PPC_OEA_SPRS,
+ /* vr0-vr31, vrsave, vscr */
+ PPC_ALTIVEC_REGS
+ /* FIXME? Add more registers? */
+};
+
+/* Information about a particular processor variant. */
+
+struct variant
+ {
+ /* Name of this variant. */
+ char *name;
+
+ /* English description of the variant. */
+ char *description;
+
+ /* bfd_arch_info.arch corresponding to variant. */
+ enum bfd_architecture arch;
+
+ /* bfd_arch_info.mach corresponding to variant. */
+ unsigned long mach;
+
+ /* Table of register names; registers[R] is the name of the register
+ number R. */
+ int nregs;
+ const struct reg *regs;
+ };
+
+#define num_registers(list) (sizeof (list) / sizeof((list)[0]))
+
+
+/* Information in this table comes from the following web sites:
+ IBM: http://www.chips.ibm.com:80/products/embedded/
+ Motorola: http://www.mot.com/SPS/PowerPC/
+
+ I'm sure I've got some of the variant descriptions not quite right.
+ Please report any inaccuracies you find to GDB's maintainer.
+
+ If you add entries to this table, please be sure to allow the new
+ value as an argument to the --with-cpu flag, in configure.in. */
+
+static const struct variant variants[] =
+{
+ {"powerpc", "PowerPC user-level", bfd_arch_powerpc,
+ bfd_mach_ppc, num_registers (registers_powerpc), registers_powerpc},
+ {"power", "POWER user-level", bfd_arch_rs6000,
+ bfd_mach_rs6k, num_registers (registers_power), registers_power},
+ {"403", "IBM PowerPC 403", bfd_arch_powerpc,
+ bfd_mach_ppc_403, num_registers (registers_403), registers_403},
+ {"601", "Motorola PowerPC 601", bfd_arch_powerpc,
+ bfd_mach_ppc_601, num_registers (registers_601), registers_601},
+ {"602", "Motorola PowerPC 602", bfd_arch_powerpc,
+ bfd_mach_ppc_602, num_registers (registers_602), registers_602},
+ {"603", "Motorola/IBM PowerPC 603 or 603e", bfd_arch_powerpc,
+ bfd_mach_ppc_603, num_registers (registers_603), registers_603},
+ {"604", "Motorola PowerPC 604 or 604e", bfd_arch_powerpc,
+ 604, num_registers (registers_604), registers_604},
+ {"403GC", "IBM PowerPC 403GC", bfd_arch_powerpc,
+ bfd_mach_ppc_403gc, num_registers (registers_403GC), registers_403GC},
+ {"505", "Motorola PowerPC 505", bfd_arch_powerpc,
+ bfd_mach_ppc_505, num_registers (registers_505), registers_505},
+ {"860", "Motorola PowerPC 860 or 850", bfd_arch_powerpc,
+ bfd_mach_ppc_860, num_registers (registers_860), registers_860},
+ {"750", "Motorola/IBM PowerPC 750 or 740", bfd_arch_powerpc,
+ bfd_mach_ppc_750, num_registers (registers_750), registers_750},
+ {"7400", "Motorola/IBM PowerPC 7400 (G4)", bfd_arch_powerpc,
+ bfd_mach_ppc_7400, num_registers (registers_7400), registers_7400},
+
+ /* 64-bit */
+ {"powerpc64", "PowerPC 64-bit user-level", bfd_arch_powerpc,
+ bfd_mach_ppc64, num_registers (registers_powerpc), registers_powerpc},
+ {"620", "Motorola PowerPC 620", bfd_arch_powerpc,
+ bfd_mach_ppc_620, num_registers (registers_powerpc), registers_powerpc},
+ {"630", "Motorola PowerPC 630", bfd_arch_powerpc,
+ bfd_mach_ppc_630, num_registers (registers_powerpc), registers_powerpc},
+ {"a35", "PowerPC A35", bfd_arch_powerpc,
+ bfd_mach_ppc_a35, num_registers (registers_powerpc), registers_powerpc},
+ {"rs64ii", "PowerPC rs64ii", bfd_arch_powerpc,
+ bfd_mach_ppc_rs64ii, num_registers (registers_powerpc), registers_powerpc},
+ {"rs64iii", "PowerPC rs64iii", bfd_arch_powerpc,
+ bfd_mach_ppc_rs64iii, num_registers (registers_powerpc), registers_powerpc},
+
+ /* FIXME: I haven't checked the register sets of the following. */
+ {"rs1", "IBM POWER RS1", bfd_arch_rs6000,
+ bfd_mach_rs6k_rs1, num_registers (registers_power), registers_power},
+ {"rsc", "IBM POWER RSC", bfd_arch_rs6000,
+ bfd_mach_rs6k_rsc, num_registers (registers_power), registers_power},
+ {"rs2", "IBM POWER RS2", bfd_arch_rs6000,
+ bfd_mach_rs6k_rs2, num_registers (registers_power), registers_power},
+
+ {0, 0, 0, 0}
+};
+
+#undef num_registers
+
+/* Return the variant corresponding to architecture ARCH and machine number
+ MACH. If no such variant exists, return null. */
+
+static const struct variant *
+find_variant_by_arch (enum bfd_architecture arch, unsigned long mach)
+{
+ const struct variant *v;
+
+ for (v = variants; v->name; v++)
+ if (arch == v->arch && mach == v->mach)
+ return v;
+
+ return NULL;
+}
+
+
+
+
+static void
+process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
+{
+ int *os_ident_ptr = obj;
+ const char *name;
+ unsigned int sectsize;
+
+ name = bfd_get_section_name (abfd, sect);
+ sectsize = bfd_section_size (abfd, sect);
+ if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
+ {
+ unsigned int name_length, data_length, note_type;
+ char *note = alloca (sectsize);
+
+ bfd_get_section_contents (abfd, sect, note,
+ (file_ptr) 0, (bfd_size_type) sectsize);
+
+ name_length = bfd_h_get_32 (abfd, note);
+ data_length = bfd_h_get_32 (abfd, note + 4);
+ note_type = bfd_h_get_32 (abfd, note + 8);
+
+ if (name_length == 4 && data_length == 16 && note_type == 1
+ && strcmp (note + 12, "GNU") == 0)
+ {
+ int os_number = bfd_h_get_32 (abfd, note + 16);
+
+ /* The case numbers are from abi-tags in glibc */
+ switch (os_number)
+ {
+ case 0 :
+ *os_ident_ptr = ELFOSABI_LINUX;
+ break;
+ case 1 :
+ *os_ident_ptr = ELFOSABI_HURD;
+ break;
+ case 2 :
+ *os_ident_ptr = ELFOSABI_SOLARIS;
+ break;
+ default :
+ internal_error (__FILE__, __LINE__,
+ "process_note_abi_sections: unknown OS number %d",
+ os_number);
+ break;
+ }
+ }
+ }
+}
+
+/* Return one of the ELFOSABI_ constants for BFDs representing ELF
+ executables. If it's not an ELF executable or if the OS/ABI couldn't
+ be determined, simply return -1. */
+
+static int
+get_elfosabi (bfd *abfd)
+{
+ int elfosabi = -1;
+
+ if (abfd != NULL && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+ {
+ elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
+
+ /* When elfosabi is 0 (ELFOSABI_NONE), this is supposed to indicate
+ that we're on a SYSV system. However, GNU/Linux uses a note section
+ to record OS/ABI info, but leaves e_ident[EI_OSABI] zero. So we
+ have to check the note sections too. */
+ if (elfosabi == 0)
+ {
+ bfd_map_over_sections (abfd,
+ process_note_abi_tag_sections,
+ &elfosabi);
+ }
+ }
+
+ return elfosabi;
+}
+
+
+
+/* Initialize the current architecture based on INFO. If possible, re-use an
+ architecture from ARCHES, which is a list of architectures already created
+ during this debugging session.
+
+ Called e.g. at program startup, when reading a core file, and when reading
+ a binary file. */
+
+static struct gdbarch *
+rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch *gdbarch;
+ struct gdbarch_tdep *tdep;
+ int wordsize, from_xcoff_exec, from_elf_exec, power, i, off;
+ struct reg *regs;
+ const struct variant *v;
+ enum bfd_architecture arch;
+ unsigned long mach;
+ bfd abfd;
+ int osabi, sysv_abi;
+ gdbarch_print_insn_ftype *print_insn;
+
+ from_xcoff_exec = info.abfd && info.abfd->format == bfd_object &&
+ bfd_get_flavour (info.abfd) == bfd_target_xcoff_flavour;
+
+ from_elf_exec = info.abfd && info.abfd->format == bfd_object &&
+ bfd_get_flavour (info.abfd) == bfd_target_elf_flavour;
+
+ sysv_abi = info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour;
+
+ osabi = get_elfosabi (info.abfd);
+
+ /* Check word size. If INFO is from a binary file, infer it from
+ that, else choose a likely default. */
+ if (from_xcoff_exec)
+ {
+ if (bfd_xcoff_is_xcoff64 (info.abfd))
+ wordsize = 8;
+ else
+ wordsize = 4;
+ }
+ else if (from_elf_exec)
+ {
+ if (elf_elfheader (info.abfd)->e_ident[EI_CLASS] == ELFCLASS64)
+ wordsize = 8;
+ else
+ wordsize = 4;
+ }
+ else
+ {
+ if (info.bfd_arch_info != NULL && info.bfd_arch_info->bits_per_word != 0)
+ wordsize = info.bfd_arch_info->bits_per_word /
+ info.bfd_arch_info->bits_per_byte;
+ else
+ wordsize = 4;
+ }
+
+ /* Find a candidate among extant architectures. */
+ for (arches = gdbarch_list_lookup_by_info (arches, &info);
+ arches != NULL;
+ arches = gdbarch_list_lookup_by_info (arches->next, &info))
+ {
+ /* Word size in the various PowerPC bfd_arch_info structs isn't
+ meaningful, because 64-bit CPUs can run in 32-bit mode. So, perform
+ separate word size check. */
+ tdep = gdbarch_tdep (arches->gdbarch);
+ if (tdep && tdep->wordsize == wordsize && tdep->osabi == osabi)
+ return arches->gdbarch;
+ }
+
+ /* None found, create a new architecture from INFO, whose bfd_arch_info
+ validity depends on the source:
+ - executable useless
+ - rs6000_host_arch() good
+ - core file good
+ - "set arch" trust blindly
+ - GDB startup useless but harmless */
+
+ if (!from_xcoff_exec)
+ {
+ arch = info.bfd_arch_info->arch;
+ mach = info.bfd_arch_info->mach;
+ }
+ else
+ {
+ arch = bfd_arch_powerpc;
+ mach = 0;
+ bfd_default_set_arch_mach (&abfd, arch, mach);
+ info.bfd_arch_info = bfd_get_arch_info (&abfd);
+ }
+ tdep = xmalloc (sizeof (struct gdbarch_tdep));
+ tdep->wordsize = wordsize;
+ tdep->osabi = osabi;
+ gdbarch = gdbarch_alloc (&info, tdep);
+ power = arch == bfd_arch_rs6000;
+
+ /* Choose variant. */
+ v = find_variant_by_arch (arch, mach);
+ if (!v)
+ return NULL;
+
+ tdep->regs = v->regs;
+
+ tdep->ppc_gp0_regnum = 0;
+ tdep->ppc_gplast_regnum = 31;
+ tdep->ppc_toc_regnum = 2;
+ tdep->ppc_ps_regnum = 65;
+ tdep->ppc_cr_regnum = 66;
+ tdep->ppc_lr_regnum = 67;
+ tdep->ppc_ctr_regnum = 68;
+ tdep->ppc_xer_regnum = 69;
+ if (v->mach == bfd_mach_ppc_601)
+ tdep->ppc_mq_regnum = 124;
+ else if (power)
+ tdep->ppc_mq_regnum = 70;
+ else
+ tdep->ppc_mq_regnum = -1;
+ tdep->ppc_fpscr_regnum = power ? 71 : 70;
+
+ if (v->arch == bfd_arch_powerpc)
+ switch (v->mach)
+ {
+ case bfd_mach_ppc:
+ tdep->ppc_vr0_regnum = 71;
+ tdep->ppc_vrsave_regnum = 104;
+ break;
+ case bfd_mach_ppc_7400:
+ tdep->ppc_vr0_regnum = 119;
+ tdep->ppc_vrsave_regnum = 153;
+ break;
+ default:
+ tdep->ppc_vr0_regnum = -1;
+ tdep->ppc_vrsave_regnum = -1;
+ break;
+ }
+
+ /* Set lr_frame_offset. */
+ if (wordsize == 8)
+ tdep->lr_frame_offset = 16;
+ else if (sysv_abi)
+ tdep->lr_frame_offset = 4;
+ else
+ tdep->lr_frame_offset = 8;
+
+ /* Calculate byte offsets in raw register array. */
+ tdep->regoff = xmalloc (v->nregs * sizeof (int));
+ for (i = off = 0; i < v->nregs; i++)
+ {
+ tdep->regoff[i] = off;
+ off += regsize (v->regs + i, wordsize);
+ }
+
+ /* Select instruction printer. */
+ if (arch == power)
+ print_insn = print_insn_rs6000;
+ else if (info.byte_order == BFD_ENDIAN_BIG)
+ print_insn = print_insn_big_powerpc;
+ else
+ print_insn = print_insn_little_powerpc;
+ set_gdbarch_print_insn (gdbarch, print_insn);
+
+ set_gdbarch_read_pc (gdbarch, generic_target_read_pc);
+ set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
+ set_gdbarch_read_fp (gdbarch, generic_target_read_fp);
+ set_gdbarch_read_sp (gdbarch, generic_target_read_sp);
+ set_gdbarch_write_sp (gdbarch, generic_target_write_sp);
+
+ set_gdbarch_num_regs (gdbarch, v->nregs);
+ set_gdbarch_sp_regnum (gdbarch, 1);
+ set_gdbarch_fp_regnum (gdbarch, 1);
+ set_gdbarch_pc_regnum (gdbarch, 64);
+ set_gdbarch_register_name (gdbarch, rs6000_register_name);
+ set_gdbarch_register_size (gdbarch, wordsize);
+ set_gdbarch_register_bytes (gdbarch, off);
+ set_gdbarch_register_byte (gdbarch, rs6000_register_byte);
+ set_gdbarch_register_raw_size (gdbarch, rs6000_register_raw_size);
+ set_gdbarch_max_register_raw_size (gdbarch, 16);
+ set_gdbarch_register_virtual_size (gdbarch, generic_register_size);
+ set_gdbarch_max_register_virtual_size (gdbarch, 16);
+ set_gdbarch_register_virtual_type (gdbarch, rs6000_register_virtual_type);
+ set_gdbarch_do_registers_info (gdbarch, rs6000_do_registers_info);
+
+ set_gdbarch_ptr_bit (gdbarch, wordsize * TARGET_CHAR_BIT);
+ set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_long_bit (gdbarch, wordsize * TARGET_CHAR_BIT);
+ set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+ set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+ set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+ set_gdbarch_char_signed (gdbarch, 0);
+
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+ set_gdbarch_fix_call_dummy (gdbarch, rs6000_fix_call_dummy);
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+ set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
+ set_gdbarch_push_return_address (gdbarch, ppc_push_return_address);
+ set_gdbarch_believe_pcc_promotion (gdbarch, 1);
+ set_gdbarch_coerce_float_to_double (gdbarch, rs6000_coerce_float_to_double);
+
+ set_gdbarch_register_convertible (gdbarch, rs6000_register_convertible);
+ set_gdbarch_register_convert_to_virtual (gdbarch, rs6000_register_convert_to_virtual);
+ set_gdbarch_register_convert_to_raw (gdbarch, rs6000_register_convert_to_raw);
+ set_gdbarch_stab_reg_to_regnum (gdbarch, rs6000_stab_reg_to_regnum);
+
+ set_gdbarch_extract_return_value (gdbarch, rs6000_extract_return_value);
+
+ /* Note: kevinb/2002-04-12: I'm not convinced that rs6000_push_arguments()
+ is correct for the SysV ABI when the wordsize is 8, but I'm also
+ fairly certain that ppc_sysv_abi_push_arguments() will give even
+ worse results since it only works for 32-bit code. So, for the moment,
+ we're better off calling rs6000_push_arguments() since it works for
+ 64-bit code. At some point in the future, this matter needs to be
+ revisited. */
+ if (sysv_abi && wordsize == 4)
+ set_gdbarch_push_arguments (gdbarch, ppc_sysv_abi_push_arguments);
+ else
+ set_gdbarch_push_arguments (gdbarch, rs6000_push_arguments);
+
+ set_gdbarch_store_struct_return (gdbarch, rs6000_store_struct_return);
+ set_gdbarch_store_return_value (gdbarch, rs6000_store_return_value);
+ set_gdbarch_extract_struct_value_address (gdbarch, rs6000_extract_struct_value_address);
+ set_gdbarch_pop_frame (gdbarch, rs6000_pop_frame);
+
+ set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue);
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+ set_gdbarch_function_start_offset (gdbarch, 0);
+ set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
+
+ /* Not sure on this. FIXMEmgo */
+ set_gdbarch_frame_args_skip (gdbarch, 8);
+
+ /* Until November 2001, gcc was not complying to the SYSV ABI for
+ returning structures less than or equal to 8 bytes in size. It was
+ returning everything in memory. When this was corrected, it wasn't
+ fixed for native platforms. */
+ if (sysv_abi)
+ {
+ if (osabi == ELFOSABI_LINUX
+ || osabi == ELFOSABI_NETBSD
+ || osabi == ELFOSABI_FREEBSD)
+ set_gdbarch_use_struct_convention (gdbarch,
+ ppc_sysv_abi_broken_use_struct_convention);
+ else
+ set_gdbarch_use_struct_convention (gdbarch,
+ ppc_sysv_abi_use_struct_convention);
+ }
+ else
+ {
+ set_gdbarch_use_struct_convention (gdbarch,
+ generic_use_struct_convention);
+ }
+
+ set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
+ /* Note: kevinb/2002-04-12: See note above regarding *_push_arguments().
+ The same remarks hold for the methods below. */
+ if (osabi == ELFOSABI_LINUX && wordsize == 4)
+ {
+ set_gdbarch_frameless_function_invocation (gdbarch,
+ ppc_linux_frameless_function_invocation);
+ set_gdbarch_frame_chain (gdbarch, ppc_linux_frame_chain);
+ set_gdbarch_frame_saved_pc (gdbarch, ppc_linux_frame_saved_pc);
+
+ set_gdbarch_frame_init_saved_regs (gdbarch,
+ ppc_linux_frame_init_saved_regs);
+ set_gdbarch_init_extra_frame_info (gdbarch,
+ ppc_linux_init_extra_frame_info);
+
+ set_gdbarch_memory_remove_breakpoint (gdbarch,
+ ppc_linux_memory_remove_breakpoint);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, ppc_linux_svr4_fetch_link_map_offsets);
+ }
+ else
+ {
+ set_gdbarch_frameless_function_invocation (gdbarch,
+ rs6000_frameless_function_invocation);
+ set_gdbarch_frame_chain (gdbarch, rs6000_frame_chain);
+ set_gdbarch_frame_saved_pc (gdbarch, rs6000_frame_saved_pc);
+
+ set_gdbarch_frame_init_saved_regs (gdbarch, rs6000_frame_init_saved_regs);
+ set_gdbarch_init_extra_frame_info (gdbarch, rs6000_init_extra_frame_info);
+ }
+ if (!sysv_abi)
+ {
+ /* Handle RS/6000 function pointers (which are really function
+ descriptors). */
+ set_gdbarch_convert_from_func_ptr_addr (gdbarch,
+ rs6000_convert_from_func_ptr_addr);
+ }
+ set_gdbarch_frame_args_address (gdbarch, rs6000_frame_args_address);
+ set_gdbarch_frame_locals_address (gdbarch, rs6000_frame_args_address);
+ set_gdbarch_saved_pc_after_call (gdbarch, rs6000_saved_pc_after_call);
+
+ /* We can't tell how many args there are
+ now that the C compiler delays popping them. */
+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+
+ return gdbarch;
+}
+
+static struct cmd_list_element *info_powerpc_cmdlist = NULL;
+
+static void
+rs6000_info_powerpc_command (char *args, int from_tty)
+{
+ help_list (info_powerpc_cmdlist, "info powerpc ", class_info, gdb_stdout);
+}
+
+/* Initialization code. */
+
+void
+_initialize_rs6000_tdep (void)
+{
+ register_gdbarch_init (bfd_arch_rs6000, rs6000_gdbarch_init);
+ register_gdbarch_init (bfd_arch_powerpc, rs6000_gdbarch_init);
+
+ /* Add root prefix command for "info powerpc" commands */
+ add_prefix_cmd ("powerpc", class_info, rs6000_info_powerpc_command,
+ "Various POWERPC info specific commands.",
+ &info_powerpc_cmdlist, "info powerpc ", 0, &infolist);
+
+ add_cmd ("altivec", class_info, rs6000_altivec_registers_info,
+ "Display the contents of the AltiVec registers.",
+ &info_powerpc_cmdlist);
+
+}
diff --git a/gdb/s390-nat.c b/gdb/s390-nat.c
new file mode 100644
index 00000000000..19e89238374
--- /dev/null
+++ b/gdb/s390-nat.c
@@ -0,0 +1,310 @@
+/* S390 native-dependent code for GDB, the GNU debugger.
+ Copyright 2001 Free Software Foundation, Inc
+ Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ for IBM Deutschland Entwicklung GmbH, IBM Corporation.
+ 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 "defs.h"
+#include "tm.h"
+#include "regcache.h"
+#include <asm/ptrace.h>
+#include <sys/ptrace.h>
+#include <asm/processor.h>
+#include <sys/procfs.h>
+#include <sys/user.h>
+#include <value.h>
+#include <sys/ucontext.h>
+#ifndef offsetof
+#define offsetof(type,member) ((size_t) &((type *)0)->member)
+#endif
+
+
+int
+s390_register_u_addr (int blockend, int regnum)
+{
+ int retval;
+
+ if (regnum >= S390_GP0_REGNUM && regnum <= S390_GP_LAST_REGNUM)
+ retval = PT_GPR0 + ((regnum - S390_GP0_REGNUM) * S390_GPR_SIZE);
+ else if (regnum >= S390_PSWM_REGNUM && regnum <= S390_PC_REGNUM)
+ retval = PT_PSWMASK + ((regnum - S390_PSWM_REGNUM) * S390_PSW_MASK_SIZE);
+ else if (regnum == S390_FPC_REGNUM)
+ retval = PT_FPC;
+ else if (regnum >= S390_FP0_REGNUM && regnum <= S390_FPLAST_REGNUM)
+ retval =
+#if CONFIG_ARCH_S390X
+ PT_FPR0
+#else
+ PT_FPR0_HI
+#endif
+ + ((regnum - S390_FP0_REGNUM) * S390_FPR_SIZE);
+ else if (regnum >= S390_FIRST_ACR && regnum <= S390_LAST_ACR)
+ retval = PT_ACR0 + ((regnum - S390_FIRST_ACR) * S390_ACR_SIZE);
+ else if (regnum >= (S390_FIRST_CR + 9) && regnum <= (S390_FIRST_CR + 11))
+ retval = PT_CR_9 + ((regnum - (S390_FIRST_CR + 9)) * S390_CR_SIZE);
+ else
+ {
+#ifdef GDBSERVER
+ error ("s390_register_u_addr invalid regnum %s %d regnum=%d",
+ __FILE__, (int) __LINE__, regnum);
+#else
+ internal_error (__FILE__, __LINE__,
+ "s390_register_u_addr invalid regnum regnum=%d",
+ regnum);
+#endif
+ retval = 0;
+ }
+ return retval + blockend;
+}
+
+#ifndef GDBSERVER
+/* watch_areas are required if you put 2 or more watchpoints on the same
+ address or overlapping areas gdb will call us to delete the watchpoint
+ more than once when we try to delete them.
+ attempted reference counting to reduce the number of areas unfortunately
+ they didn't shrink when areas had to be split overlapping occurs. */
+struct watch_area;
+typedef struct watch_area watch_area;
+struct watch_area
+{
+ watch_area *next;
+ CORE_ADDR lo_addr;
+ CORE_ADDR hi_addr;
+};
+
+static watch_area *watch_base = NULL;
+int watch_area_cnt = 0;
+static CORE_ADDR watch_lo_addr = 0, watch_hi_addr = 0;
+
+
+
+CORE_ADDR
+s390_stopped_by_watchpoint (int pid)
+{
+ per_lowcore_bits per_lowcore;
+ ptrace_area parea;
+
+ parea.len = sizeof (per_lowcore);
+ parea.process_addr = (addr_t) & per_lowcore;
+ parea.kernel_addr = offsetof (struct user_regs_struct, per_info.lowcore);
+ ptrace (PTRACE_PEEKUSR_AREA, pid, &parea);
+ return ((per_lowcore.perc_storage_alteration == 1) &&
+ (per_lowcore.perc_store_real_address == 0));
+}
+
+
+void
+s390_fix_watch_points (int pid)
+{
+ per_struct per_info;
+ ptrace_area parea;
+
+ parea.len = sizeof (per_info);
+ parea.process_addr = (addr_t) & per_info;
+ parea.kernel_addr = PT_CR_9;
+ ptrace (PTRACE_PEEKUSR_AREA, pid, &parea);
+ /* The kernel automatically sets the psw for per depending */
+ /* on whether the per control registers are set for event recording */
+ /* & sets cr9 & cr10 appropriately also */
+ if (watch_area_cnt)
+ {
+ per_info.control_regs.bits.em_storage_alteration = 1;
+ per_info.control_regs.bits.storage_alt_space_ctl = 1;
+ }
+ else
+ {
+ per_info.control_regs.bits.em_storage_alteration = 0;
+ per_info.control_regs.bits.storage_alt_space_ctl = 0;
+ }
+ per_info.starting_addr = watch_lo_addr;
+ per_info.ending_addr = watch_hi_addr;
+ ptrace (PTRACE_POKEUSR_AREA, pid, &parea);
+}
+
+int
+s390_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw)
+{
+ CORE_ADDR hi_addr = addr + len - 1;
+ watch_area *newarea = (watch_area *) xmalloc (sizeof (watch_area));
+
+
+ if (newarea)
+ {
+ newarea->next = watch_base;
+ watch_base = newarea;
+ watch_lo_addr = min (watch_lo_addr, addr);
+ watch_hi_addr = max (watch_hi_addr, hi_addr);
+ newarea->lo_addr = addr;
+ newarea->hi_addr = hi_addr;
+ if (watch_area_cnt == 0)
+ {
+ watch_lo_addr = newarea->lo_addr;
+ watch_hi_addr = newarea->hi_addr;
+ }
+ watch_area_cnt++;
+ s390_fix_watch_points (pid);
+ }
+ return newarea ? 0 : -1;
+}
+
+
+int
+s390_remove_watchpoint (int pid, CORE_ADDR addr, int len)
+{
+ watch_area *curr = watch_base, *prev, *matchCurr;
+ CORE_ADDR hi_addr = addr + len - 1;
+ CORE_ADDR watch_second_lo_addr = 0xffffffffUL, watch_second_hi_addr = 0;
+ int lo_addr_ref_cnt, hi_addr_ref_cnt;
+ prev = matchCurr = NULL;
+ lo_addr_ref_cnt = (addr == watch_lo_addr);
+ hi_addr_ref_cnt = (addr == watch_hi_addr);
+ while (curr)
+ {
+ if (matchCurr == NULL)
+ {
+ if (curr->lo_addr == addr && curr->hi_addr == hi_addr)
+ {
+ matchCurr = curr;
+ if (prev)
+ prev->next = curr->next;
+ else
+ watch_base = curr->next;
+ }
+ prev = curr;
+ }
+ if (lo_addr_ref_cnt)
+ {
+ if (watch_lo_addr == curr->lo_addr)
+ lo_addr_ref_cnt++;
+ if (curr->lo_addr > watch_lo_addr &&
+ curr->lo_addr < watch_second_lo_addr)
+ watch_second_lo_addr = curr->lo_addr;
+ }
+ if (hi_addr_ref_cnt)
+ {
+ if (watch_hi_addr == curr->hi_addr)
+ hi_addr_ref_cnt++;
+ if (curr->hi_addr < watch_hi_addr &&
+ curr->hi_addr > watch_second_hi_addr)
+ watch_second_hi_addr = curr->hi_addr;
+ }
+ curr = curr->next;
+ }
+ if (matchCurr)
+ {
+ xfree (matchCurr);
+ watch_area_cnt--;
+ if (watch_area_cnt)
+ {
+ if (lo_addr_ref_cnt == 2)
+ watch_lo_addr = watch_second_lo_addr;
+ if (hi_addr_ref_cnt == 2)
+ watch_hi_addr = watch_second_hi_addr;
+ }
+ else
+ {
+ watch_lo_addr = watch_hi_addr = 0;
+ }
+ s390_fix_watch_points (pid);
+ return 0;
+ }
+ else
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "Attempt to remove nonexistent watchpoint in s390_remove_watchpoint\n");
+ return -1;
+ }
+}
+
+int
+kernel_u_size (void)
+{
+ return sizeof (struct user);
+}
+
+
+#if (defined (S390_FP0_REGNUM) && defined (HAVE_FPREGSET_T) && defined(HAVE_SYS_PROCFS_H) && defined (HAVE_GREGSET_T))
+void
+supply_gregset (gregset_t * gregsetp)
+{
+ int regi;
+ greg_t *gregp = (greg_t *) gregsetp;
+
+ supply_register (S390_PSWM_REGNUM, (char *) &gregp[S390_PSWM_REGNUM]);
+ supply_register (S390_PC_REGNUM, (char *) &gregp[S390_PC_REGNUM]);
+ for (regi = 0; regi < S390_NUM_GPRS; regi++)
+ supply_register (S390_GP0_REGNUM + regi,
+ (char *) &gregp[S390_GP0_REGNUM + regi]);
+ for (regi = 0; regi < S390_NUM_ACRS; regi++)
+ supply_register (S390_FIRST_ACR + regi,
+ (char *) &gregp[S390_FIRST_ACR + regi]);
+ /* unfortunately this isn't in gregsetp */
+ for (regi = 0; regi < S390_NUM_CRS; regi++)
+ supply_register (S390_FIRST_CR + regi, NULL);
+}
+
+
+void
+supply_fpregset (fpregset_t * fpregsetp)
+{
+ int regi;
+
+ supply_register (S390_FPC_REGNUM, (char *) &fpregsetp->fpc);
+ for (regi = 0; regi < S390_NUM_FPRS; regi++)
+ supply_register (S390_FP0_REGNUM + regi, (char *) &fpregsetp->fprs[regi]);
+
+}
+
+void
+fill_gregset (gregset_t * gregsetp, int regno)
+{
+ greg_t *gregp = (greg_t *) gregsetp;
+
+ if (regno >= S390_FIRST_CR && regno <= S390_LAST_CR)
+ supply_register (regno, NULL);
+ else if (regno != -1)
+ supply_register (regno, (char *) &gregp[regno]);
+ else
+ supply_gregset (gregsetp);
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), update the register specified by REGNO from gdb's idea
+ of the current floating point register set. If REGNO is -1, update
+ them all. */
+
+void
+fill_fpregset (fpregset_t * fpregsetp, int regno)
+{
+ if (regno == -1)
+ supply_fpregset (fpregsetp);
+ else
+ supply_register (regno,
+ &((char *) fpregsetp)[REGISTER_BYTE (regno) -
+ REGISTER_BYTE (S390_FPC_REGNUM)]);
+}
+
+
+#else
+#error "There are a few possibilities here"
+#error "1) You aren't compiling for linux & don't need a core dumps to work."
+#error "2) The header files sys/elf.h sys/user.h sys/ptrace.h & sys/procfs.h"
+#error "libc files are inconsistent with linux/include/asm-s390/"
+#error "3) you didn't do a completely clean build & delete config.cache."
+#endif
+#endif /* GDBSERVER */
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
new file mode 100644
index 00000000000..c69aca69fa3
--- /dev/null
+++ b/gdb/s390-tdep.c
@@ -0,0 +1,1886 @@
+/* Target-dependent code for GDB, the GNU debugger.
+
+ Copyright 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ for IBM Deutschland Entwicklung GmbH, IBM Corporation.
+
+ 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. */
+
+#define S390_TDEP /* for special macros in tm-s390.h */
+#include <defs.h>
+#include "arch-utils.h"
+#include "frame.h"
+#include "inferior.h"
+#include "symtab.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "tm.h"
+#include "../bfd/bfd.h"
+#include "floatformat.h"
+#include "regcache.h"
+#include "value.h"
+#include "gdb_assert.h"
+
+
+
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. */
+int
+s390_register_raw_size (int reg_nr)
+{
+ if (S390_FP0_REGNUM <= reg_nr
+ && reg_nr < S390_FP0_REGNUM + S390_NUM_FPRS)
+ return S390_FPR_SIZE;
+ else
+ return 4;
+}
+
+int
+s390x_register_raw_size (int reg_nr)
+{
+ return (reg_nr == S390_FPC_REGNUM)
+ || (reg_nr >= S390_FIRST_ACR && reg_nr <= S390_LAST_ACR) ? 4 : 8;
+}
+
+int
+s390_cannot_fetch_register (int regno)
+{
+ return (regno >= S390_FIRST_CR && regno < (S390_FIRST_CR + 9)) ||
+ (regno >= (S390_FIRST_CR + 12) && regno <= S390_LAST_CR);
+}
+
+int
+s390_register_byte (int reg_nr)
+{
+ if (reg_nr <= S390_GP_LAST_REGNUM)
+ return reg_nr * S390_GPR_SIZE;
+ if (reg_nr <= S390_LAST_ACR)
+ return S390_ACR0_OFFSET + (((reg_nr) - S390_FIRST_ACR) * S390_ACR_SIZE);
+ if (reg_nr <= S390_LAST_CR)
+ return S390_CR0_OFFSET + (((reg_nr) - S390_FIRST_CR) * S390_CR_SIZE);
+ if (reg_nr == S390_FPC_REGNUM)
+ return S390_FPC_OFFSET;
+ else
+ return S390_FP0_OFFSET + (((reg_nr) - S390_FP0_REGNUM) * S390_FPR_SIZE);
+}
+
+#ifndef GDBSERVER
+#define S390_MAX_INSTR_SIZE (6)
+#define S390_SYSCALL_OPCODE (0x0a)
+#define S390_SYSCALL_SIZE (2)
+#define S390_SIGCONTEXT_SREGS_OFFSET (8)
+#define S390X_SIGCONTEXT_SREGS_OFFSET (8)
+#define S390_SIGREGS_FP0_OFFSET (144)
+#define S390X_SIGREGS_FP0_OFFSET (216)
+#define S390_UC_MCONTEXT_OFFSET (256)
+#define S390X_UC_MCONTEXT_OFFSET (344)
+#define S390_STACK_FRAME_OVERHEAD (GDB_TARGET_IS_ESAME ? 160:96)
+#define S390_SIGNAL_FRAMESIZE (GDB_TARGET_IS_ESAME ? 160:96)
+#define s390_NR_sigreturn 119
+#define s390_NR_rt_sigreturn 173
+
+
+
+struct frame_extra_info
+{
+ int initialised;
+ int good_prologue;
+ CORE_ADDR function_start;
+ CORE_ADDR skip_prologue_function_start;
+ CORE_ADDR saved_pc_valid;
+ CORE_ADDR saved_pc;
+ CORE_ADDR sig_fixed_saved_pc_valid;
+ CORE_ADDR sig_fixed_saved_pc;
+ CORE_ADDR frame_pointer_saved_pc; /* frame pointer needed for alloca */
+ CORE_ADDR stack_bought; /* amount we decrement the stack pointer by */
+ CORE_ADDR sigcontext;
+};
+
+
+static CORE_ADDR s390_frame_saved_pc_nofix (struct frame_info *fi);
+
+int
+s390_readinstruction (bfd_byte instr[], CORE_ADDR at,
+ struct disassemble_info *info)
+{
+ int instrlen;
+
+ static int s390_instrlen[] = {
+ 2,
+ 4,
+ 4,
+ 6
+ };
+ if ((*info->read_memory_func) (at, &instr[0], 2, info))
+ return -1;
+ instrlen = s390_instrlen[instr[0] >> 6];
+ if (instrlen > 2)
+ {
+ if ((*info->read_memory_func) (at + 2, &instr[2], instrlen - 2, info))
+ return -1;
+ }
+ return instrlen;
+}
+
+static void
+s390_memset_extra_info (struct frame_extra_info *fextra_info)
+{
+ memset (fextra_info, 0, sizeof (struct frame_extra_info));
+}
+
+
+
+char *
+s390_register_name (int reg_nr)
+{
+ static char *register_names[] = {
+ "pswm", "pswa",
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "acr0", "acr1", "acr2", "acr3", "acr4", "acr5", "acr6", "acr7",
+ "acr8", "acr9", "acr10", "acr11", "acr12", "acr13", "acr14", "acr15",
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
+ "cr8", "cr9", "cr10", "cr11", "cr12", "cr13", "cr14", "cr15",
+ "fpc",
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15"
+ };
+
+ if (reg_nr <= S390_LAST_REGNUM)
+ return register_names[reg_nr];
+ else
+ return NULL;
+}
+
+
+
+
+int
+s390_stab_reg_to_regnum (int regno)
+{
+ return regno >= 64 ? S390_PSWM_REGNUM - 64 :
+ regno >= 48 ? S390_FIRST_ACR - 48 :
+ regno >= 32 ? S390_FIRST_CR - 32 :
+ regno <= 15 ? (regno + 2) :
+ S390_FP0_REGNUM + ((regno - 16) & 8) + (((regno - 16) & 3) << 1) +
+ (((regno - 16) & 4) >> 2);
+}
+
+
+/* Return true if REGIDX is the number of a register used to pass
+ arguments, false otherwise. */
+static int
+is_arg_reg (int regidx)
+{
+ return 2 <= regidx && regidx <= 6;
+}
+
+
+/* s390_get_frame_info based on Hartmuts
+ prologue definition in
+ gcc-2.8.1/config/l390/linux.c
+
+ It reads one instruction at a time & based on whether
+ it looks like prologue code or not it makes a decision on
+ whether the prologue is over, there are various state machines
+ in the code to determine if the prologue code is possilby valid.
+
+ This is done to hopefully allow the code survive minor revs of
+ calling conventions.
+
+ */
+
+int
+s390_get_frame_info (CORE_ADDR pc, struct frame_extra_info *fextra_info,
+ struct frame_info *fi, int init_extra_info)
+{
+#define CONST_POOL_REGIDX 13
+#define GOT_REGIDX 12
+ bfd_byte instr[S390_MAX_INSTR_SIZE];
+ CORE_ADDR test_pc = pc, test_pc2;
+ CORE_ADDR orig_sp = 0, save_reg_addr = 0, *saved_regs = NULL;
+ int valid_prologue, good_prologue = 0;
+ int gprs_saved[S390_NUM_GPRS];
+ int fprs_saved[S390_NUM_FPRS];
+ int regidx, instrlen;
+ int const_pool_state;
+ int varargs_state;
+ int loop_cnt, gdb_gpr_store, gdb_fpr_store;
+ int offset, expected_offset;
+ int err = 0;
+ disassemble_info info;
+
+ /* Have we seen an instruction initializing the frame pointer yet?
+ If we've seen an `lr %r11, %r15', then frame_pointer_found is
+ non-zero, and frame_pointer_regidx == 11. Otherwise,
+ frame_pointer_found is zero and frame_pointer_regidx is 15,
+ indicating that we're using the stack pointer as our frame
+ pointer. */
+ int frame_pointer_found = 0;
+ int frame_pointer_regidx = 0xf;
+
+ /* What we've seen so far regarding saving the back chain link:
+ 0 -- nothing yet; sp still has the same value it had at the entry
+ point. Since not all functions allocate frames, this is a
+ valid state for the prologue to finish in.
+ 1 -- We've saved the original sp in some register other than the
+ frame pointer (hard-coded to be %r11, yuck).
+ save_link_regidx is the register we saved it in.
+ 2 -- We've seen the initial `bras' instruction of the sequence for
+ reserving more than 32k of stack:
+ bras %rX, .+8
+ .long N
+ s %r15, 0(%rX)
+ where %rX is not the constant pool register.
+ subtract_sp_regidx is %rX, and fextra_info->stack_bought is N.
+ 3 -- We've reserved space for a new stack frame. This means we
+ either saw a simple `ahi %r15,-N' in state 1, or the final
+ `s %r15, ...' in state 2.
+ 4 -- The frame and link are now fully initialized. We've
+ reserved space for the new stack frame, and stored the old
+ stack pointer captured in the back chain pointer field. */
+ int save_link_state = 0;
+ int save_link_regidx, subtract_sp_regidx;
+
+ /* What we've seen so far regarding r12 --- the GOT (Global Offset
+ Table) pointer. We expect to see `l %r12, N(%r13)', which loads
+ r12 with the offset from the constant pool to the GOT, and then
+ an `ar %r12, %r13', which adds the constant pool address,
+ yielding the GOT's address. Here's what got_state means:
+ 0 -- seen nothing
+ 1 -- seen `l %r12, N(%r13)', but no `ar'
+ 2 -- seen load and add, so GOT pointer is totally initialized
+ When got_state is 1, then got_load_addr is the address of the
+ load instruction, and got_load_len is the length of that
+ instruction. */
+ int got_state= 0;
+ CORE_ADDR got_load_addr = 0, got_load_len = 0;
+
+ const_pool_state = varargs_state = 0;
+
+ memset (gprs_saved, 0, sizeof (gprs_saved));
+ memset (fprs_saved, 0, sizeof (fprs_saved));
+ info.read_memory_func = dis_asm_read_memory;
+
+ save_link_regidx = subtract_sp_regidx = 0;
+ if (fextra_info)
+ {
+ if (fi && fi->frame)
+ {
+ orig_sp = fi->frame;
+ if (! init_extra_info && fextra_info->initialised)
+ orig_sp += fextra_info->stack_bought;
+ saved_regs = fi->saved_regs;
+ }
+ if (init_extra_info || !fextra_info->initialised)
+ {
+ s390_memset_extra_info (fextra_info);
+ fextra_info->function_start = pc;
+ fextra_info->initialised = 1;
+ }
+ }
+ instrlen = 0;
+ do
+ {
+ valid_prologue = 0;
+ test_pc += instrlen;
+ /* add the previous instruction len */
+ instrlen = s390_readinstruction (instr, test_pc, &info);
+ if (instrlen < 0)
+ {
+ good_prologue = 0;
+ err = -1;
+ break;
+ }
+ /* We probably are in a glibc syscall */
+ if (instr[0] == S390_SYSCALL_OPCODE && test_pc == pc)
+ {
+ good_prologue = 1;
+ if (saved_regs && fextra_info && fi->next && fi->next->extra_info
+ && fi->next->extra_info->sigcontext)
+ {
+ /* We are backtracing from a signal handler */
+ save_reg_addr = fi->next->extra_info->sigcontext +
+ REGISTER_BYTE (S390_GP0_REGNUM);
+ for (regidx = 0; regidx < S390_NUM_GPRS; regidx++)
+ {
+ saved_regs[S390_GP0_REGNUM + regidx] = save_reg_addr;
+ save_reg_addr += S390_GPR_SIZE;
+ }
+ save_reg_addr = fi->next->extra_info->sigcontext +
+ (GDB_TARGET_IS_ESAME ? S390X_SIGREGS_FP0_OFFSET :
+ S390_SIGREGS_FP0_OFFSET);
+ for (regidx = 0; regidx < S390_NUM_FPRS; regidx++)
+ {
+ saved_regs[S390_FP0_REGNUM + regidx] = save_reg_addr;
+ save_reg_addr += S390_FPR_SIZE;
+ }
+ }
+ break;
+ }
+ if (save_link_state == 0)
+ {
+ /* check for a stack relative STMG or STM */
+ if (((GDB_TARGET_IS_ESAME &&
+ ((instr[0] == 0xeb) && (instr[5] == 0x24))) ||
+ (instr[0] == 0x90)) && ((instr[2] >> 4) == 0xf))
+ {
+ regidx = (instr[1] >> 4);
+ if (regidx < 6)
+ varargs_state = 1;
+ offset = ((instr[2] & 0xf) << 8) + instr[3];
+ expected_offset =
+ S390_GPR6_STACK_OFFSET + (S390_GPR_SIZE * (regidx - 6));
+ if (offset != expected_offset)
+ {
+ good_prologue = 0;
+ break;
+ }
+ if (saved_regs)
+ save_reg_addr = orig_sp + offset;
+ for (; regidx <= (instr[1] & 0xf); regidx++)
+ {
+ if (gprs_saved[regidx])
+ {
+ good_prologue = 0;
+ break;
+ }
+ good_prologue = 1;
+ gprs_saved[regidx] = 1;
+ if (saved_regs)
+ {
+ saved_regs[S390_GP0_REGNUM + regidx] = save_reg_addr;
+ save_reg_addr += S390_GPR_SIZE;
+ }
+ }
+ valid_prologue = 1;
+ continue;
+ }
+ }
+ /* check for a stack relative STG or ST */
+ if ((save_link_state == 0 || save_link_state == 3) &&
+ ((GDB_TARGET_IS_ESAME &&
+ ((instr[0] == 0xe3) && (instr[5] == 0x24))) ||
+ (instr[0] == 0x50)) && ((instr[2] >> 4) == 0xf))
+ {
+ regidx = instr[1] >> 4;
+ offset = ((instr[2] & 0xf) << 8) + instr[3];
+ if (offset == 0)
+ {
+ if (save_link_state == 3 && regidx == save_link_regidx)
+ {
+ save_link_state = 4;
+ valid_prologue = 1;
+ continue;
+ }
+ else
+ break;
+ }
+ if (regidx < 6)
+ varargs_state = 1;
+ expected_offset =
+ S390_GPR6_STACK_OFFSET + (S390_GPR_SIZE * (regidx - 6));
+ if (offset != expected_offset)
+ {
+ good_prologue = 0;
+ break;
+ }
+ if (gprs_saved[regidx])
+ {
+ good_prologue = 0;
+ break;
+ }
+ good_prologue = 1;
+ gprs_saved[regidx] = 1;
+ if (saved_regs)
+ {
+ save_reg_addr = orig_sp + offset;
+ saved_regs[S390_GP0_REGNUM + regidx] = save_reg_addr;
+ }
+ valid_prologue = 1;
+ continue;
+ }
+
+ /* Check for an fp-relative STG, ST, or STM. This is probably
+ spilling an argument from a register out into a stack slot.
+ This could be a user instruction, but if we haven't included
+ any other suspicious instructions in the prologue, this
+ could only be an initializing store, which isn't too bad to
+ skip. The consequences of not including arg-to-stack spills
+ are more serious, though --- you don't see the proper values
+ of the arguments. */
+ if ((save_link_state == 3 || save_link_state == 4)
+ && ((instr[0] == 0x50 /* st %rA, D(%rX,%rB) */
+ && (instr[1] & 0xf) == 0 /* %rX is zero, no index reg */
+ && is_arg_reg ((instr[1] >> 4) & 0xf)
+ && ((instr[2] >> 4) & 0xf) == frame_pointer_regidx)
+ || (instr[0] == 0x90 /* stm %rA, %rB, D(%rC) */
+ && is_arg_reg ((instr[1] >> 4) & 0xf)
+ && is_arg_reg (instr[1] & 0xf)
+ && ((instr[2] >> 4) & 0xf) == frame_pointer_regidx)))
+ {
+ valid_prologue = 1;
+ continue;
+ }
+
+ /* check for STD */
+ if (instr[0] == 0x60 && (instr[2] >> 4) == 0xf)
+ {
+ regidx = instr[1] >> 4;
+ if (regidx == 0 || regidx == 2)
+ varargs_state = 1;
+ if (fprs_saved[regidx])
+ {
+ good_prologue = 0;
+ break;
+ }
+ fprs_saved[regidx] = 1;
+ if (saved_regs)
+ {
+ save_reg_addr = orig_sp + (((instr[2] & 0xf) << 8) + instr[3]);
+ saved_regs[S390_FP0_REGNUM + regidx] = save_reg_addr;
+ }
+ valid_prologue = 1;
+ continue;
+ }
+
+
+ if (const_pool_state == 0)
+ {
+
+ if (GDB_TARGET_IS_ESAME)
+ {
+ /* Check for larl CONST_POOL_REGIDX,offset on ESAME */
+ if ((instr[0] == 0xc0)
+ && (instr[1] == (CONST_POOL_REGIDX << 4)))
+ {
+ const_pool_state = 2;
+ valid_prologue = 1;
+ continue;
+ }
+ }
+ else
+ {
+ /* Check for BASR gpr13,gpr0 used to load constant pool pointer to r13 in old compiler */
+ if (instr[0] == 0xd && (instr[1] & 0xf) == 0
+ && ((instr[1] >> 4) == CONST_POOL_REGIDX))
+ {
+ const_pool_state = 1;
+ valid_prologue = 1;
+ continue;
+ }
+ }
+ /* Check for new fangled bras %r13,newpc to load new constant pool */
+ /* embedded in code, older pre abi compilers also emitted this stuff. */
+ if ((instr[0] == 0xa7) && ((instr[1] & 0xf) == 0x5) &&
+ ((instr[1] >> 4) == CONST_POOL_REGIDX)
+ && ((instr[2] & 0x80) == 0))
+ {
+ const_pool_state = 2;
+ test_pc +=
+ (((((instr[2] & 0xf) << 8) + instr[3]) << 1) - instrlen);
+ valid_prologue = 1;
+ continue;
+ }
+ }
+ /* Check for AGHI or AHI CONST_POOL_REGIDX,val */
+ if (const_pool_state == 1 && (instr[0] == 0xa7) &&
+ ((GDB_TARGET_IS_ESAME &&
+ (instr[1] == ((CONST_POOL_REGIDX << 4) | 0xb))) ||
+ (instr[1] == ((CONST_POOL_REGIDX << 4) | 0xa))))
+ {
+ const_pool_state = 2;
+ valid_prologue = 1;
+ continue;
+ }
+ /* Check for LGR or LR gprx,15 */
+ if ((GDB_TARGET_IS_ESAME &&
+ instr[0] == 0xb9 && instr[1] == 0x04 && (instr[3] & 0xf) == 0xf) ||
+ (instr[0] == 0x18 && (instr[1] & 0xf) == 0xf))
+ {
+ if (GDB_TARGET_IS_ESAME)
+ regidx = instr[3] >> 4;
+ else
+ regidx = instr[1] >> 4;
+ if (save_link_state == 0 && regidx != 0xb)
+ {
+ /* Almost defintely code for
+ decrementing the stack pointer
+ ( i.e. a non leaf function
+ or else leaf with locals ) */
+ save_link_regidx = regidx;
+ save_link_state = 1;
+ valid_prologue = 1;
+ continue;
+ }
+ /* We use this frame pointer for alloca
+ unfortunately we need to assume its gpr11
+ otherwise we would need a smarter prologue
+ walker. */
+ if (!frame_pointer_found && regidx == 0xb)
+ {
+ frame_pointer_regidx = 0xb;
+ frame_pointer_found = 1;
+ if (fextra_info)
+ fextra_info->frame_pointer_saved_pc = test_pc;
+ valid_prologue = 1;
+ continue;
+ }
+ }
+ /* Check for AHI or AGHI gpr15,val */
+ if (save_link_state == 1 && (instr[0] == 0xa7) &&
+ ((GDB_TARGET_IS_ESAME && (instr[1] == 0xfb)) || (instr[1] == 0xfa)))
+ {
+ if (fextra_info)
+ fextra_info->stack_bought =
+ -extract_signed_integer (&instr[2], 2);
+ save_link_state = 3;
+ valid_prologue = 1;
+ continue;
+ }
+ /* Alternatively check for the complex construction for
+ buying more than 32k of stack
+ BRAS gprx,.+8
+ long val
+ s %r15,0(%gprx) gprx currently r1 */
+ if ((save_link_state == 1) && (instr[0] == 0xa7)
+ && ((instr[1] & 0xf) == 0x5) && (instr[2] == 0)
+ && (instr[3] == 0x4) && ((instr[1] >> 4) != CONST_POOL_REGIDX))
+ {
+ subtract_sp_regidx = instr[1] >> 4;
+ save_link_state = 2;
+ if (fextra_info)
+ target_read_memory (test_pc + instrlen,
+ (char *) &fextra_info->stack_bought,
+ sizeof (fextra_info->stack_bought));
+ test_pc += 4;
+ valid_prologue = 1;
+ continue;
+ }
+ if (save_link_state == 2 && instr[0] == 0x5b
+ && instr[1] == 0xf0 &&
+ instr[2] == (subtract_sp_regidx << 4) && instr[3] == 0)
+ {
+ save_link_state = 3;
+ valid_prologue = 1;
+ continue;
+ }
+ /* check for LA gprx,offset(15) used for varargs */
+ if ((instr[0] == 0x41) && ((instr[2] >> 4) == 0xf) &&
+ ((instr[1] & 0xf) == 0))
+ {
+ /* some code uses gpr7 to point to outgoing args */
+ if (((instr[1] >> 4) == 7) && (save_link_state == 0) &&
+ ((instr[2] & 0xf) == 0)
+ && (instr[3] == S390_STACK_FRAME_OVERHEAD))
+ {
+ valid_prologue = 1;
+ continue;
+ }
+ if (varargs_state == 1)
+ {
+ varargs_state = 2;
+ valid_prologue = 1;
+ continue;
+ }
+ }
+ /* Check for a GOT load */
+
+ if (GDB_TARGET_IS_ESAME)
+ {
+ /* Check for larl GOT_REGIDX, on ESAME */
+ if ((got_state == 0) && (instr[0] == 0xc0)
+ && (instr[1] == (GOT_REGIDX << 4)))
+ {
+ got_state = 2;
+ valid_prologue = 1;
+ continue;
+ }
+ }
+ else
+ {
+ /* check for l GOT_REGIDX,x(CONST_POOL_REGIDX) */
+ if (got_state == 0 && const_pool_state == 2 && instr[0] == 0x58
+ && (instr[2] == (CONST_POOL_REGIDX << 4))
+ && ((instr[1] >> 4) == GOT_REGIDX))
+ {
+ got_state = 1;
+ got_load_addr = test_pc;
+ got_load_len = instrlen;
+ valid_prologue = 1;
+ continue;
+ }
+ /* Check for subsequent ar got_regidx,basr_regidx */
+ if (got_state == 1 && instr[0] == 0x1a &&
+ instr[1] == ((GOT_REGIDX << 4) | CONST_POOL_REGIDX))
+ {
+ got_state = 2;
+ valid_prologue = 1;
+ continue;
+ }
+ }
+ }
+ while (valid_prologue && good_prologue);
+ if (good_prologue)
+ {
+ /* If this function doesn't reference the global offset table,
+ then the compiler may use r12 for other things. If the last
+ instruction we saw was a load of r12 from the constant pool,
+ with no subsequent add to make the address PC-relative, then
+ the load was probably a genuine body instruction; don't treat
+ it as part of the prologue. */
+ if (got_state == 1
+ && got_load_addr + got_load_len == test_pc)
+ {
+ test_pc = got_load_addr;
+ instrlen = got_load_len;
+ }
+
+ good_prologue = (((const_pool_state == 0) || (const_pool_state == 2)) &&
+ ((save_link_state == 0) || (save_link_state == 4)) &&
+ ((varargs_state == 0) || (varargs_state == 2)));
+ }
+ if (fextra_info)
+ {
+ fextra_info->good_prologue = good_prologue;
+ fextra_info->skip_prologue_function_start =
+ (good_prologue ? test_pc : pc);
+ }
+ if (saved_regs)
+ /* The SP's element of the saved_regs array holds the old SP,
+ not the address at which it is saved. */
+ saved_regs[S390_SP_REGNUM] = orig_sp;
+ return err;
+}
+
+
+int
+s390_check_function_end (CORE_ADDR pc)
+{
+ bfd_byte instr[S390_MAX_INSTR_SIZE];
+ disassemble_info info;
+ int regidx, instrlen;
+
+ info.read_memory_func = dis_asm_read_memory;
+ instrlen = s390_readinstruction (instr, pc, &info);
+ if (instrlen < 0)
+ return -1;
+ /* check for BR */
+ if (instrlen != 2 || instr[0] != 07 || (instr[1] >> 4) != 0xf)
+ return 0;
+ regidx = instr[1] & 0xf;
+ /* Check for LMG or LG */
+ instrlen =
+ s390_readinstruction (instr, pc - (GDB_TARGET_IS_ESAME ? 6 : 4), &info);
+ if (instrlen < 0)
+ return -1;
+ if (GDB_TARGET_IS_ESAME)
+ {
+
+ if (instrlen != 6 || instr[0] != 0xeb || instr[5] != 0x4)
+ return 0;
+ }
+ else if (instrlen != 4 || instr[0] != 0x98)
+ {
+ return 0;
+ }
+ if ((instr[2] >> 4) != 0xf)
+ return 0;
+ if (regidx == 14)
+ return 1;
+ instrlen = s390_readinstruction (instr, pc - (GDB_TARGET_IS_ESAME ? 12 : 8),
+ &info);
+ if (instrlen < 0)
+ return -1;
+ if (GDB_TARGET_IS_ESAME)
+ {
+ /* Check for LG */
+ if (instrlen != 6 || instr[0] != 0xe3 || instr[5] != 0x4)
+ return 0;
+ }
+ else
+ {
+ /* Check for L */
+ if (instrlen != 4 || instr[0] != 0x58)
+ return 0;
+ }
+ if (instr[2] >> 4 != 0xf)
+ return 0;
+ if (instr[1] >> 4 != regidx)
+ return 0;
+ return 1;
+}
+
+static CORE_ADDR
+s390_sniff_pc_function_start (CORE_ADDR pc, struct frame_info *fi)
+{
+ CORE_ADDR function_start, test_function_start;
+ int loop_cnt, err, function_end;
+ struct frame_extra_info fextra_info;
+ function_start = get_pc_function_start (pc);
+
+ if (function_start == 0)
+ {
+ test_function_start = pc;
+ if (test_function_start & 1)
+ return 0; /* This has to be bogus */
+ loop_cnt = 0;
+ do
+ {
+
+ err =
+ s390_get_frame_info (test_function_start, &fextra_info, fi, 1);
+ loop_cnt++;
+ test_function_start -= 2;
+ function_end = s390_check_function_end (test_function_start);
+ }
+ while (!(function_end == 1 || err || loop_cnt >= 4096 ||
+ (fextra_info.good_prologue)));
+ if (fextra_info.good_prologue)
+ function_start = fextra_info.function_start;
+ else if (function_end == 1)
+ function_start = test_function_start;
+ }
+ return function_start;
+}
+
+
+
+CORE_ADDR
+s390_function_start (struct frame_info *fi)
+{
+ CORE_ADDR function_start = 0;
+
+ if (fi->extra_info && fi->extra_info->initialised)
+ function_start = fi->extra_info->function_start;
+ else if (fi->pc)
+ function_start = get_pc_function_start (fi->pc);
+ return function_start;
+}
+
+
+
+
+int
+s390_frameless_function_invocation (struct frame_info *fi)
+{
+ struct frame_extra_info fextra_info, *fextra_info_ptr;
+ int frameless = 0;
+
+ if (fi->next == NULL) /* no may be frameless */
+ {
+ if (fi->extra_info)
+ fextra_info_ptr = fi->extra_info;
+ else
+ {
+ fextra_info_ptr = &fextra_info;
+ s390_get_frame_info (s390_sniff_pc_function_start (fi->pc, fi),
+ fextra_info_ptr, fi, 1);
+ }
+ frameless = ((fextra_info_ptr->stack_bought == 0));
+ }
+ return frameless;
+
+}
+
+
+static int
+s390_is_sigreturn (CORE_ADDR pc, struct frame_info *sighandler_fi,
+ CORE_ADDR *sregs, CORE_ADDR *sigcaller_pc)
+{
+ bfd_byte instr[S390_MAX_INSTR_SIZE];
+ disassemble_info info;
+ int instrlen;
+ CORE_ADDR scontext;
+ int retval = 0;
+ CORE_ADDR orig_sp;
+ CORE_ADDR temp_sregs;
+
+ scontext = temp_sregs = 0;
+
+ info.read_memory_func = dis_asm_read_memory;
+ instrlen = s390_readinstruction (instr, pc, &info);
+ if (sigcaller_pc)
+ *sigcaller_pc = 0;
+ if (((instrlen == S390_SYSCALL_SIZE) &&
+ (instr[0] == S390_SYSCALL_OPCODE)) &&
+ ((instr[1] == s390_NR_sigreturn) || (instr[1] == s390_NR_rt_sigreturn)))
+ {
+ if (sighandler_fi)
+ {
+ if (s390_frameless_function_invocation (sighandler_fi))
+ orig_sp = sighandler_fi->frame;
+ else
+ orig_sp = ADDR_BITS_REMOVE ((CORE_ADDR)
+ read_memory_integer (sighandler_fi->
+ frame,
+ S390_GPR_SIZE));
+ if (orig_sp && sigcaller_pc)
+ {
+ scontext = orig_sp + S390_SIGNAL_FRAMESIZE;
+ if (pc == scontext && instr[1] == s390_NR_rt_sigreturn)
+ {
+ /* We got a new style rt_signal */
+ /* get address of read ucontext->uc_mcontext */
+ temp_sregs = orig_sp + (GDB_TARGET_IS_ESAME ?
+ S390X_UC_MCONTEXT_OFFSET :
+ S390_UC_MCONTEXT_OFFSET);
+ }
+ else
+ {
+ /* read sigcontext->sregs */
+ temp_sregs = ADDR_BITS_REMOVE ((CORE_ADDR)
+ read_memory_integer (scontext
+ +
+ (GDB_TARGET_IS_ESAME
+ ?
+ S390X_SIGCONTEXT_SREGS_OFFSET
+ :
+ S390_SIGCONTEXT_SREGS_OFFSET),
+ S390_GPR_SIZE));
+
+ }
+ /* read sigregs->psw.addr */
+ *sigcaller_pc =
+ ADDR_BITS_REMOVE ((CORE_ADDR)
+ read_memory_integer (temp_sregs +
+ REGISTER_BYTE
+ (S390_PC_REGNUM),
+ S390_PSW_ADDR_SIZE));
+ }
+ }
+ retval = 1;
+ }
+ if (sregs)
+ *sregs = temp_sregs;
+ return retval;
+}
+
+/*
+ We need to do something better here but this will keep us out of trouble
+ for the moment.
+ For some reason the blockframe.c calls us with fi->next->fromleaf
+ so this seems of little use to us. */
+void
+s390_init_frame_pc_first (int next_fromleaf, struct frame_info *fi)
+{
+ CORE_ADDR sigcaller_pc;
+
+ fi->pc = 0;
+ if (next_fromleaf)
+ {
+ fi->pc = ADDR_BITS_REMOVE (read_register (S390_RETADDR_REGNUM));
+ /* fix signal handlers */
+ }
+ else if (fi->next && fi->next->pc)
+ fi->pc = s390_frame_saved_pc_nofix (fi->next);
+ if (fi->pc && fi->next && fi->next->frame &&
+ s390_is_sigreturn (fi->pc, fi->next, NULL, &sigcaller_pc))
+ {
+ fi->pc = sigcaller_pc;
+ }
+
+}
+
+void
+s390_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ fi->extra_info = frame_obstack_alloc (sizeof (struct frame_extra_info));
+ if (fi->pc)
+ s390_get_frame_info (s390_sniff_pc_function_start (fi->pc, fi),
+ fi->extra_info, fi, 1);
+ else
+ s390_memset_extra_info (fi->extra_info);
+}
+
+/* If saved registers of frame FI are not known yet, read and cache them.
+ &FEXTRA_INFOP contains struct frame_extra_info; TDATAP can be NULL,
+ in which case the framedata are read. */
+
+void
+s390_frame_init_saved_regs (struct frame_info *fi)
+{
+
+ int quick;
+
+ if (fi->saved_regs == NULL)
+ {
+ /* zalloc memsets the saved regs */
+ frame_saved_regs_zalloc (fi);
+ if (fi->pc)
+ {
+ quick = (fi->extra_info && fi->extra_info->initialised
+ && fi->extra_info->good_prologue);
+ s390_get_frame_info (quick ? fi->extra_info->function_start :
+ s390_sniff_pc_function_start (fi->pc, fi),
+ fi->extra_info, fi, !quick);
+ }
+ }
+}
+
+
+
+CORE_ADDR
+s390_frame_args_address (struct frame_info *fi)
+{
+
+ /* Apparently gdb already knows gdb_args_offset itself */
+ return fi->frame;
+}
+
+
+static CORE_ADDR
+s390_frame_saved_pc_nofix (struct frame_info *fi)
+{
+ if (fi->extra_info && fi->extra_info->saved_pc_valid)
+ return fi->extra_info->saved_pc;
+
+ if (generic_find_dummy_frame (fi->pc, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, S390_PC_REGNUM);
+
+ s390_frame_init_saved_regs (fi);
+ if (fi->extra_info)
+ {
+ fi->extra_info->saved_pc_valid = 1;
+ if (fi->extra_info->good_prologue
+ && fi->saved_regs[S390_RETADDR_REGNUM])
+ fi->extra_info->saved_pc
+ = ADDR_BITS_REMOVE (read_memory_integer
+ (fi->saved_regs[S390_RETADDR_REGNUM],
+ S390_GPR_SIZE));
+ else
+ fi->extra_info->saved_pc
+ = ADDR_BITS_REMOVE (read_register (S390_RETADDR_REGNUM));
+ return fi->extra_info->saved_pc;
+ }
+ return 0;
+}
+
+CORE_ADDR
+s390_frame_saved_pc (struct frame_info *fi)
+{
+ CORE_ADDR saved_pc = 0, sig_pc;
+
+ if (fi->extra_info && fi->extra_info->sig_fixed_saved_pc_valid)
+ return fi->extra_info->sig_fixed_saved_pc;
+ saved_pc = s390_frame_saved_pc_nofix (fi);
+
+ if (fi->extra_info)
+ {
+ fi->extra_info->sig_fixed_saved_pc_valid = 1;
+ if (saved_pc)
+ {
+ if (s390_is_sigreturn (saved_pc, fi, NULL, &sig_pc))
+ saved_pc = sig_pc;
+ }
+ fi->extra_info->sig_fixed_saved_pc = saved_pc;
+ }
+ return saved_pc;
+}
+
+
+
+
+/* We want backtraces out of signal handlers so we don't
+ set thisframe->signal_handler_caller to 1 */
+
+CORE_ADDR
+s390_frame_chain (struct frame_info *thisframe)
+{
+ CORE_ADDR prev_fp = 0;
+
+ if (generic_find_dummy_frame (thisframe->pc, thisframe->frame))
+ return generic_read_register_dummy (thisframe->pc, thisframe->frame,
+ S390_SP_REGNUM);
+ else
+ {
+ int sigreturn = 0;
+ CORE_ADDR sregs = 0;
+ struct frame_extra_info prev_fextra_info;
+
+ memset (&prev_fextra_info, 0, sizeof (prev_fextra_info));
+ if (thisframe->pc)
+ {
+ CORE_ADDR saved_pc, sig_pc;
+
+ saved_pc = s390_frame_saved_pc_nofix (thisframe);
+ if (saved_pc)
+ {
+ if ((sigreturn =
+ s390_is_sigreturn (saved_pc, thisframe, &sregs, &sig_pc)))
+ saved_pc = sig_pc;
+ s390_get_frame_info (s390_sniff_pc_function_start
+ (saved_pc, NULL), &prev_fextra_info, NULL,
+ 1);
+ }
+ }
+ if (sigreturn)
+ {
+ /* read sigregs,regs.gprs[11 or 15] */
+ prev_fp = read_memory_integer (sregs +
+ REGISTER_BYTE (S390_GP0_REGNUM +
+ (prev_fextra_info.
+ frame_pointer_saved_pc
+ ? 11 : 15)),
+ S390_GPR_SIZE);
+ thisframe->extra_info->sigcontext = sregs;
+ }
+ else
+ {
+ if (thisframe->saved_regs)
+ {
+ int regno;
+
+ if (prev_fextra_info.frame_pointer_saved_pc
+ && thisframe->saved_regs[S390_FRAME_REGNUM])
+ regno = S390_FRAME_REGNUM;
+ else
+ regno = S390_SP_REGNUM;
+
+ if (thisframe->saved_regs[regno])
+ {
+ /* The SP's entry of `saved_regs' is special. */
+ if (regno == S390_SP_REGNUM)
+ prev_fp = thisframe->saved_regs[regno];
+ else
+ prev_fp =
+ read_memory_integer (thisframe->saved_regs[regno],
+ S390_GPR_SIZE);
+ }
+ }
+ }
+ }
+ return ADDR_BITS_REMOVE (prev_fp);
+}
+
+/*
+ Whether struct frame_extra_info is actually needed I'll have to figure
+ out as our frames are similar to rs6000 there is a possibility
+ i386 dosen't need it. */
+
+
+
+/* a given return value in `regbuf' with a type `valtype', extract and copy its
+ value into `valbuf' */
+void
+s390_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
+{
+ /* floats and doubles are returned in fpr0. fpr's have a size of 8 bytes.
+ We need to truncate the return value into float size (4 byte) if
+ necessary. */
+ int len = TYPE_LENGTH (valtype);
+
+ if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
+ memcpy (valbuf, &regbuf[REGISTER_BYTE (S390_FP0_REGNUM)], len);
+ else
+ {
+ int offset = 0;
+ /* return value is copied starting from r2. */
+ if (TYPE_LENGTH (valtype) < S390_GPR_SIZE)
+ offset = S390_GPR_SIZE - TYPE_LENGTH (valtype);
+ memcpy (valbuf,
+ regbuf + REGISTER_BYTE (S390_GP0_REGNUM + 2) + offset,
+ TYPE_LENGTH (valtype));
+ }
+}
+
+
+static char *
+s390_promote_integer_argument (struct type *valtype, char *valbuf,
+ char *reg_buff, int *arglen)
+{
+ char *value = valbuf;
+ int len = TYPE_LENGTH (valtype);
+
+ if (len < S390_GPR_SIZE)
+ {
+ /* We need to upgrade this value to a register to pass it correctly */
+ int idx, diff = S390_GPR_SIZE - len, negative =
+ (!TYPE_UNSIGNED (valtype) && value[0] & 0x80);
+ for (idx = 0; idx < S390_GPR_SIZE; idx++)
+ {
+ reg_buff[idx] = (idx < diff ? (negative ? 0xff : 0x0) :
+ value[idx - diff]);
+ }
+ value = reg_buff;
+ *arglen = S390_GPR_SIZE;
+ }
+ else
+ {
+ if (len & (S390_GPR_SIZE - 1))
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "s390_promote_integer_argument detected an argument not "
+ "a multiple of S390_GPR_SIZE & greater than S390_GPR_SIZE "
+ "we might not deal with this correctly.\n");
+ }
+ *arglen = len;
+ }
+
+ return (value);
+}
+
+void
+s390_store_return_value (struct type *valtype, char *valbuf)
+{
+ int arglen;
+ char *reg_buff = alloca (max (S390_FPR_SIZE, REGISTER_SIZE)), *value;
+
+ if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
+ {
+ if (TYPE_LENGTH (valtype) == 4
+ || TYPE_LENGTH (valtype) == 8)
+ write_register_bytes (REGISTER_BYTE (S390_FP0_REGNUM), valbuf,
+ TYPE_LENGTH (valtype));
+ else
+ error ("GDB is unable to return `long double' values "
+ "on this architecture.");
+ }
+ else
+ {
+ value =
+ s390_promote_integer_argument (valtype, valbuf, reg_buff, &arglen);
+ /* Everything else is returned in GPR2 and up. */
+ write_register_bytes (REGISTER_BYTE (S390_GP0_REGNUM + 2), value,
+ arglen);
+ }
+}
+static int
+gdb_print_insn_s390 (bfd_vma memaddr, disassemble_info * info)
+{
+ bfd_byte instrbuff[S390_MAX_INSTR_SIZE];
+ int instrlen, cnt;
+
+ instrlen = s390_readinstruction (instrbuff, (CORE_ADDR) memaddr, info);
+ if (instrlen < 0)
+ {
+ (*info->memory_error_func) (instrlen, memaddr, info);
+ return -1;
+ }
+ for (cnt = 0; cnt < instrlen; cnt++)
+ info->fprintf_func (info->stream, "%02X ", instrbuff[cnt]);
+ for (cnt = instrlen; cnt < S390_MAX_INSTR_SIZE; cnt++)
+ info->fprintf_func (info->stream, " ");
+ instrlen = print_insn_s390 (memaddr, info);
+ return instrlen;
+}
+
+
+
+/* Not the most efficent code in the world */
+int
+s390_fp_regnum ()
+{
+ int regno = S390_SP_REGNUM;
+ struct frame_extra_info fextra_info;
+
+ CORE_ADDR pc = ADDR_BITS_REMOVE (read_register (S390_PC_REGNUM));
+
+ s390_get_frame_info (s390_sniff_pc_function_start (pc, NULL), &fextra_info,
+ NULL, 1);
+ if (fextra_info.frame_pointer_saved_pc)
+ regno = S390_FRAME_REGNUM;
+ return regno;
+}
+
+CORE_ADDR
+s390_read_fp ()
+{
+ return read_register (s390_fp_regnum ());
+}
+
+
+static void
+s390_pop_frame_regular (struct frame_info *frame)
+{
+ int regnum;
+
+ write_register (S390_PC_REGNUM, FRAME_SAVED_PC (frame));
+
+ /* Restore any saved registers. */
+ if (frame->saved_regs)
+ {
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ if (frame->saved_regs[regnum] != 0)
+ {
+ ULONGEST value;
+
+ value = read_memory_unsigned_integer (frame->saved_regs[regnum],
+ REGISTER_RAW_SIZE (regnum));
+ write_register (regnum, value);
+ }
+
+ /* Actually cut back the stack. Remember that the SP's element of
+ saved_regs is the old SP itself, not the address at which it is
+ saved. */
+ write_register (S390_SP_REGNUM, frame->saved_regs[S390_SP_REGNUM]);
+ }
+
+ /* Throw away any cached frame information. */
+ flush_cached_frames ();
+}
+
+
+/* Destroy the innermost (Top-Of-Stack) stack frame, restoring the
+ machine state that was in effect before the frame was created.
+ Used in the contexts of the "return" command, and of
+ target function calls from the debugger. */
+void
+s390_pop_frame ()
+{
+ /* This function checks for and handles generic dummy frames, and
+ calls back to our function for ordinary frames. */
+ generic_pop_current_frame (s390_pop_frame_regular);
+}
+
+
+/* Return non-zero if TYPE is an integer-like type, zero otherwise.
+ "Integer-like" types are those that should be passed the way
+ integers are: integers, enums, ranges, characters, and booleans. */
+static int
+is_integer_like (struct type *type)
+{
+ enum type_code code = TYPE_CODE (type);
+
+ return (code == TYPE_CODE_INT
+ || code == TYPE_CODE_ENUM
+ || code == TYPE_CODE_RANGE
+ || code == TYPE_CODE_CHAR
+ || code == TYPE_CODE_BOOL);
+}
+
+
+/* Return non-zero if TYPE is a pointer-like type, zero otherwise.
+ "Pointer-like" types are those that should be passed the way
+ pointers are: pointers and references. */
+static int
+is_pointer_like (struct type *type)
+{
+ enum type_code code = TYPE_CODE (type);
+
+ return (code == TYPE_CODE_PTR
+ || code == TYPE_CODE_REF);
+}
+
+
+/* Return non-zero if TYPE is a `float singleton' or `double
+ singleton', zero otherwise.
+
+ A `T singleton' is a struct type with one member, whose type is
+ either T or a `T singleton'. So, the following are all float
+ singletons:
+
+ struct { float x };
+ struct { struct { float x; } x; };
+ struct { struct { struct { float x; } x; } x; };
+
+ ... and so on.
+
+ WHY THE HECK DO WE CARE ABOUT THIS??? Well, it turns out that GCC
+ passes all float singletons and double singletons as if they were
+ simply floats or doubles. This is *not* what the ABI says it
+ should do. */
+static int
+is_float_singleton (struct type *type)
+{
+ return (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ && TYPE_NFIELDS (type) == 1
+ && (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_FLT
+ || is_float_singleton (TYPE_FIELD_TYPE (type, 0))));
+}
+
+
+/* Return non-zero if TYPE is a struct-like type, zero otherwise.
+ "Struct-like" types are those that should be passed as structs are:
+ structs and unions.
+
+ As an odd quirk, not mentioned in the ABI, GCC passes float and
+ double singletons as if they were a plain float, double, etc. (The
+ corresponding union types are handled normally.) So we exclude
+ those types here. *shrug* */
+static int
+is_struct_like (struct type *type)
+{
+ enum type_code code = TYPE_CODE (type);
+
+ return (code == TYPE_CODE_UNION
+ || (code == TYPE_CODE_STRUCT && ! is_float_singleton (type)));
+}
+
+
+/* Return non-zero if TYPE is a float-like type, zero otherwise.
+ "Float-like" types are those that should be passed as
+ floating-point values are.
+
+ You'd think this would just be floats, doubles, long doubles, etc.
+ But as an odd quirk, not mentioned in the ABI, GCC passes float and
+ double singletons as if they were a plain float, double, etc. (The
+ corresponding union types are handled normally.) So we exclude
+ those types here. *shrug* */
+static int
+is_float_like (struct type *type)
+{
+ return (TYPE_CODE (type) == TYPE_CODE_FLT
+ || is_float_singleton (type));
+}
+
+
+/* Return non-zero if TYPE is considered a `DOUBLE_OR_FLOAT', as
+ defined by the parameter passing conventions described in the
+ "GNU/Linux for S/390 ELF Application Binary Interface Supplement".
+ Otherwise, return zero. */
+static int
+is_double_or_float (struct type *type)
+{
+ return (is_float_like (type)
+ && (TYPE_LENGTH (type) == 4
+ || TYPE_LENGTH (type) == 8));
+}
+
+
+/* Return non-zero if TYPE is considered a `SIMPLE_ARG', as defined by
+ the parameter passing conventions described in the "GNU/Linux for
+ S/390 ELF Application Binary Interface Supplement". Return zero
+ otherwise. */
+static int
+is_simple_arg (struct type *type)
+{
+ unsigned length = TYPE_LENGTH (type);
+
+ /* This is almost a direct translation of the ABI's language, except
+ that we have to exclude 8-byte structs; those are DOUBLE_ARGs. */
+ return ((is_integer_like (type) && length <= 4)
+ || is_pointer_like (type)
+ || (is_struct_like (type) && length != 8)
+ || (is_float_like (type) && length == 16));
+}
+
+
+/* Return non-zero if TYPE should be passed as a pointer to a copy,
+ zero otherwise. TYPE must be a SIMPLE_ARG, as recognized by
+ `is_simple_arg'. */
+static int
+pass_by_copy_ref (struct type *type)
+{
+ unsigned length = TYPE_LENGTH (type);
+
+ return ((is_struct_like (type) && length != 1 && length != 2 && length != 4)
+ || (is_float_like (type) && length == 16));
+}
+
+
+/* Return ARG, a `SIMPLE_ARG', sign-extended or zero-extended to a full
+ word as required for the ABI. */
+static LONGEST
+extend_simple_arg (struct value *arg)
+{
+ struct type *type = VALUE_TYPE (arg);
+
+ /* Even structs get passed in the least significant bits of the
+ register / memory word. It's not really right to extract them as
+ an integer, but it does take care of the extension. */
+ if (TYPE_UNSIGNED (type))
+ return extract_unsigned_integer (VALUE_CONTENTS (arg),
+ TYPE_LENGTH (type));
+ else
+ return extract_signed_integer (VALUE_CONTENTS (arg),
+ TYPE_LENGTH (type));
+}
+
+
+/* Return non-zero if TYPE is a `DOUBLE_ARG', as defined by the
+ parameter passing conventions described in the "GNU/Linux for S/390
+ ELF Application Binary Interface Supplement". Return zero
+ otherwise. */
+static int
+is_double_arg (struct type *type)
+{
+ unsigned length = TYPE_LENGTH (type);
+
+ return ((is_integer_like (type)
+ || is_struct_like (type))
+ && length == 8);
+}
+
+
+/* Round ADDR up to the next N-byte boundary. N must be a power of
+ two. */
+static CORE_ADDR
+round_up (CORE_ADDR addr, int n)
+{
+ /* Check that N is really a power of two. */
+ gdb_assert (n && (n & (n-1)) == 0);
+ return ((addr + n - 1) & -n);
+}
+
+
+/* Round ADDR down to the next N-byte boundary. N must be a power of
+ two. */
+static CORE_ADDR
+round_down (CORE_ADDR addr, int n)
+{
+ /* Check that N is really a power of two. */
+ gdb_assert (n && (n & (n-1)) == 0);
+ return (addr & -n);
+}
+
+
+/* Return the alignment required by TYPE. */
+static int
+alignment_of (struct type *type)
+{
+ int alignment;
+
+ if (is_integer_like (type)
+ || is_pointer_like (type)
+ || TYPE_CODE (type) == TYPE_CODE_FLT)
+ alignment = TYPE_LENGTH (type);
+ else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION)
+ {
+ int i;
+
+ alignment = 1;
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
+ {
+ int field_alignment = alignment_of (TYPE_FIELD_TYPE (type, i));
+
+ if (field_alignment > alignment)
+ alignment = field_alignment;
+ }
+ }
+ else
+ alignment = 1;
+
+ /* Check that everything we ever return is a power of two. Lots of
+ code doesn't want to deal with aligning things to arbitrary
+ boundaries. */
+ gdb_assert ((alignment & (alignment - 1)) == 0);
+
+ return alignment;
+}
+
+
+/* Put the actual parameter values pointed to by ARGS[0..NARGS-1] in
+ place to be passed to a function, as specified by the "GNU/Linux
+ for S/390 ELF Application Binary Interface Supplement".
+
+ SP is the current stack pointer. We must put arguments, links,
+ padding, etc. whereever they belong, and return the new stack
+ pointer value.
+
+ If STRUCT_RETURN is non-zero, then the function we're calling is
+ going to return a structure by value; STRUCT_ADDR is the address of
+ a block we've allocated for it on the stack.
+
+ Our caller has taken care of any type promotions needed to satisfy
+ prototypes or the old K&R argument-passing rules. */
+CORE_ADDR
+s390_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int i;
+ int pointer_size = (TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ /* The number of arguments passed by reference-to-copy. */
+ int num_copies;
+
+ /* If the i'th argument is passed as a reference to a copy, then
+ copy_addr[i] is the address of the copy we made. */
+ CORE_ADDR *copy_addr = alloca (nargs * sizeof (CORE_ADDR));
+
+ /* Build the reference-to-copy area. */
+ num_copies = 0;
+ for (i = 0; i < nargs; i++)
+ {
+ struct value *arg = args[i];
+ struct type *type = VALUE_TYPE (arg);
+ unsigned length = TYPE_LENGTH (type);
+
+ if (is_simple_arg (type)
+ && pass_by_copy_ref (type))
+ {
+ sp -= length;
+ sp = round_down (sp, alignment_of (type));
+ write_memory (sp, VALUE_CONTENTS (arg), length);
+ copy_addr[i] = sp;
+ num_copies++;
+ }
+ }
+
+ /* Reserve space for the parameter area. As a conservative
+ simplification, we assume that everything will be passed on the
+ stack. */
+ {
+ int i;
+
+ for (i = 0; i < nargs; i++)
+ {
+ struct value *arg = args[i];
+ struct type *type = VALUE_TYPE (arg);
+ int length = TYPE_LENGTH (type);
+
+ sp = round_down (sp, alignment_of (type));
+
+ /* SIMPLE_ARG values get extended to 32 bits. Assume every
+ argument is. */
+ if (length < 4) length = 4;
+ sp -= length;
+ }
+ }
+
+ /* Include space for any reference-to-copy pointers. */
+ sp = round_down (sp, pointer_size);
+ sp -= num_copies * pointer_size;
+
+ /* After all that, make sure it's still aligned on an eight-byte
+ boundary. */
+ sp = round_down (sp, 8);
+
+ /* Finally, place the actual parameters, working from SP towards
+ higher addresses. The code above is supposed to reserve enough
+ space for this. */
+ {
+ int fr = 0;
+ int gr = 2;
+ CORE_ADDR starg = sp;
+
+ for (i = 0; i < nargs; i++)
+ {
+ struct value *arg = args[i];
+ struct type *type = VALUE_TYPE (arg);
+
+ if (is_double_or_float (type)
+ && fr <= 2)
+ {
+ /* When we store a single-precision value in an FP register,
+ it occupies the leftmost bits. */
+ write_register_bytes (REGISTER_BYTE (S390_FP0_REGNUM + fr),
+ VALUE_CONTENTS (arg),
+ TYPE_LENGTH (type));
+ fr += 2;
+ }
+ else if (is_simple_arg (type)
+ && gr <= 6)
+ {
+ /* Do we need to pass a pointer to our copy of this
+ argument? */
+ if (pass_by_copy_ref (type))
+ write_register (S390_GP0_REGNUM + gr, copy_addr[i]);
+ else
+ write_register (S390_GP0_REGNUM + gr, extend_simple_arg (arg));
+
+ gr++;
+ }
+ else if (is_double_arg (type)
+ && gr <= 5)
+ {
+ write_register_gen (S390_GP0_REGNUM + gr,
+ VALUE_CONTENTS (arg));
+ write_register_gen (S390_GP0_REGNUM + gr + 1,
+ VALUE_CONTENTS (arg) + 4);
+ gr += 2;
+ }
+ else
+ {
+ /* The `OTHER' case. */
+ enum type_code code = TYPE_CODE (type);
+ unsigned length = TYPE_LENGTH (type);
+
+ /* If we skipped r6 because we couldn't fit a DOUBLE_ARG
+ in it, then don't go back and use it again later. */
+ if (is_double_arg (type) && gr == 6)
+ gr = 7;
+
+ if (is_simple_arg (type))
+ {
+ /* Simple args are always either extended to 32 bits,
+ or pointers. */
+ starg = round_up (starg, 4);
+
+ /* Do we need to pass a pointer to our copy of this
+ argument? */
+ if (pass_by_copy_ref (type))
+ write_memory_signed_integer (starg, pointer_size,
+ copy_addr[i]);
+ else
+ /* Simple args are always extended to 32 bits. */
+ write_memory_signed_integer (starg, 4,
+ extend_simple_arg (arg));
+ starg += 4;
+ }
+ else
+ {
+ /* You'd think we should say:
+ starg = round_up (starg, alignment_of (type));
+ Unfortunately, GCC seems to simply align the stack on
+ a four-byte boundary, even when passing doubles. */
+ starg = round_up (starg, 4);
+ write_memory (starg, VALUE_CONTENTS (arg), length);
+ starg += length;
+ }
+ }
+ }
+ }
+
+ /* Allocate the standard frame areas: the register save area, the
+ word reserved for the compiler (which seems kind of meaningless),
+ and the back chain pointer. */
+ sp -= 96;
+
+ /* Write the back chain pointer into the first word of the stack
+ frame. This will help us get backtraces from within functions
+ called from GDB. */
+ write_memory_unsigned_integer (sp, (TARGET_PTR_BIT / TARGET_CHAR_BIT),
+ read_fp ());
+
+ return sp;
+}
+
+
+static int
+s390_use_struct_convention (int gcc_p, struct type *value_type)
+{
+ enum type_code code = TYPE_CODE (value_type);
+
+ return (code == TYPE_CODE_STRUCT
+ || code == TYPE_CODE_UNION);
+}
+
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+struct type *
+s390_register_virtual_type (int regno)
+{
+ if (S390_FP0_REGNUM <= regno && regno < S390_FP0_REGNUM + S390_NUM_FPRS)
+ return builtin_type_double;
+ else
+ return builtin_type_int;
+}
+
+
+struct type *
+s390x_register_virtual_type (int regno)
+{
+ return (regno == S390_FPC_REGNUM) ||
+ (regno >= S390_FIRST_ACR && regno <= S390_LAST_ACR) ? builtin_type_int :
+ (regno >= S390_FP0_REGNUM) ? builtin_type_double : builtin_type_long;
+}
+
+
+
+void
+s390_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ write_register (S390_GP0_REGNUM + 2, addr);
+}
+
+
+
+const static unsigned char *
+s390_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+ static unsigned char breakpoint[] = { 0x0, 0x1 };
+
+ *lenptr = sizeof (breakpoint);
+ return breakpoint;
+}
+
+/* Advance PC across any function entry prologue instructions to reach some
+ "real" code. */
+CORE_ADDR
+s390_skip_prologue (CORE_ADDR pc)
+{
+ struct frame_extra_info fextra_info;
+
+ s390_get_frame_info (pc, &fextra_info, NULL, 1);
+ return fextra_info.skip_prologue_function_start;
+}
+
+/* Immediately after a function call, return the saved pc.
+ Can't go through the frames for this because on some machines
+ the new frame is not set up until the new function executes
+ some instructions. */
+CORE_ADDR
+s390_saved_pc_after_call (struct frame_info *frame)
+{
+ return ADDR_BITS_REMOVE (read_register (S390_RETADDR_REGNUM));
+}
+
+static CORE_ADDR
+s390_addr_bits_remove (CORE_ADDR addr)
+{
+ return (addr) & 0x7fffffff;
+}
+
+
+static CORE_ADDR
+s390_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ write_register (S390_RETADDR_REGNUM, CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+struct gdbarch *
+s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ static LONGEST s390_call_dummy_words[] = { 0 };
+ struct gdbarch *gdbarch;
+ struct gdbarch_tdep *tdep;
+ int elf_flags;
+
+ /* First see if there is already a gdbarch that can satisfy the request. */
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+ if (arches != NULL)
+ return arches->gdbarch;
+
+ /* None found: is the request for a s390 architecture? */
+ if (info.bfd_arch_info->arch != bfd_arch_s390)
+ return NULL; /* No; then it's not for us. */
+
+ /* Yes: create a new gdbarch for the specified machine type. */
+ gdbarch = gdbarch_alloc (&info, NULL);
+
+ set_gdbarch_believe_pcc_promotion (gdbarch, 0);
+ set_gdbarch_char_signed (gdbarch, 0);
+
+ set_gdbarch_frame_args_skip (gdbarch, 0);
+ set_gdbarch_frame_args_address (gdbarch, s390_frame_args_address);
+ set_gdbarch_frame_chain (gdbarch, s390_frame_chain);
+ set_gdbarch_frame_init_saved_regs (gdbarch, s390_frame_init_saved_regs);
+ set_gdbarch_frame_locals_address (gdbarch, s390_frame_args_address);
+ /* We can't do this */
+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+ set_gdbarch_store_struct_return (gdbarch, s390_store_struct_return);
+ set_gdbarch_extract_return_value (gdbarch, s390_extract_return_value);
+ set_gdbarch_store_return_value (gdbarch, s390_store_return_value);
+ /* Amount PC must be decremented by after a breakpoint.
+ This is often the number of bytes in BREAKPOINT
+ but not always. */
+ set_gdbarch_decr_pc_after_break (gdbarch, 2);
+ set_gdbarch_pop_frame (gdbarch, s390_pop_frame);
+ /* Stack grows downward. */
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+ /* Offset from address of function to start of its code.
+ Zero on most machines. */
+ set_gdbarch_function_start_offset (gdbarch, 0);
+ set_gdbarch_max_register_raw_size (gdbarch, 8);
+ set_gdbarch_max_register_virtual_size (gdbarch, 8);
+ set_gdbarch_breakpoint_from_pc (gdbarch, s390_breakpoint_from_pc);
+ set_gdbarch_skip_prologue (gdbarch, s390_skip_prologue);
+ set_gdbarch_init_extra_frame_info (gdbarch, s390_init_extra_frame_info);
+ set_gdbarch_init_frame_pc_first (gdbarch, s390_init_frame_pc_first);
+ set_gdbarch_read_fp (gdbarch, s390_read_fp);
+ /* This function that tells us whether the function invocation represented
+ by FI does not have a frame on the stack associated with it. If it
+ does not, FRAMELESS is set to 1, else 0. */
+ set_gdbarch_frameless_function_invocation (gdbarch,
+ s390_frameless_function_invocation);
+ /* Return saved PC from a frame */
+ set_gdbarch_frame_saved_pc (gdbarch, s390_frame_saved_pc);
+ /* FRAME_CHAIN takes a frame's nominal address
+ and produces the frame's chain-pointer. */
+ set_gdbarch_frame_chain (gdbarch, s390_frame_chain);
+ set_gdbarch_saved_pc_after_call (gdbarch, s390_saved_pc_after_call);
+ set_gdbarch_register_byte (gdbarch, s390_register_byte);
+ set_gdbarch_pc_regnum (gdbarch, S390_PC_REGNUM);
+ set_gdbarch_sp_regnum (gdbarch, S390_SP_REGNUM);
+ set_gdbarch_fp_regnum (gdbarch, S390_FP_REGNUM);
+ set_gdbarch_fp0_regnum (gdbarch, S390_FP0_REGNUM);
+ set_gdbarch_num_regs (gdbarch, S390_NUM_REGS);
+ set_gdbarch_cannot_fetch_register (gdbarch, s390_cannot_fetch_register);
+ set_gdbarch_cannot_store_register (gdbarch, s390_cannot_fetch_register);
+ set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+ set_gdbarch_use_struct_convention (gdbarch, s390_use_struct_convention);
+ set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
+ set_gdbarch_register_name (gdbarch, s390_register_name);
+ set_gdbarch_stab_reg_to_regnum (gdbarch, s390_stab_reg_to_regnum);
+ set_gdbarch_dwarf_reg_to_regnum (gdbarch, s390_stab_reg_to_regnum);
+ set_gdbarch_dwarf2_reg_to_regnum (gdbarch, s390_stab_reg_to_regnum);
+ set_gdbarch_extract_struct_value_address
+ (gdbarch, generic_cannot_extract_struct_value_address);
+
+ /* Parameters for inferior function calls. */
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+ set_gdbarch_push_arguments (gdbarch, s390_push_arguments);
+ set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
+ set_gdbarch_push_return_address (gdbarch, s390_push_return_address);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch,
+ sizeof (s390_call_dummy_words));
+ set_gdbarch_call_dummy_words (gdbarch, s390_call_dummy_words);
+ set_gdbarch_coerce_float_to_double (gdbarch,
+ standard_coerce_float_to_double);
+
+ switch (info.bfd_arch_info->mach)
+ {
+ case bfd_mach_s390_31:
+ set_gdbarch_register_size (gdbarch, 4);
+ set_gdbarch_register_raw_size (gdbarch, s390_register_raw_size);
+ set_gdbarch_register_virtual_size (gdbarch, s390_register_raw_size);
+ set_gdbarch_register_virtual_type (gdbarch, s390_register_virtual_type);
+
+ set_gdbarch_addr_bits_remove (gdbarch, s390_addr_bits_remove);
+ set_gdbarch_register_bytes (gdbarch, S390_REGISTER_BYTES);
+ break;
+ case bfd_mach_s390_64:
+ set_gdbarch_register_size (gdbarch, 8);
+ set_gdbarch_register_raw_size (gdbarch, s390x_register_raw_size);
+ set_gdbarch_register_virtual_size (gdbarch, s390x_register_raw_size);
+ set_gdbarch_register_virtual_type (gdbarch,
+ s390x_register_virtual_type);
+
+ set_gdbarch_long_bit (gdbarch, 64);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+ set_gdbarch_ptr_bit (gdbarch, 64);
+ set_gdbarch_register_bytes (gdbarch, S390X_REGISTER_BYTES);
+ break;
+ }
+
+ return gdbarch;
+}
+
+
+
+void
+_initialize_s390_tdep ()
+{
+
+ /* Hook us into the gdbarch mechanism. */
+ register_gdbarch_init (bfd_arch_s390, s390_gdbarch_init);
+ if (!tm_print_insn) /* Someone may have already set it */
+ tm_print_insn = gdb_print_insn_s390;
+}
+
+#endif /* GDBSERVER */
diff --git a/gdb/saber.suppress b/gdb/saber.suppress
new file mode 100644
index 00000000000..6dda1c5f2da
--- /dev/null
+++ b/gdb/saber.suppress
@@ -0,0 +1,451 @@
+
+
+/* Options for project */
+unsetopt ansi
+setopt auto_compile
+unsetopt auto_reload
+setopt auto_replace
+unsetopt batch_load
+unsetopt batch_run
+unsetopt cc_prog
+setopt ccargs -g
+unsetopt create_file
+unsetopt debug_child
+unsetopt echo
+setopt edit_jobs 5
+unsetopt eight_bit
+setopt line_edit
+setopt line_meta
+setopt lint_load 2
+setopt lint_run 2
+setopt list_action
+setopt load_flags -I. -g -I.. -I../vx-share
+unsetopt long_not_int
+unsetopt make_args
+setopt make_hfiles
+unsetopt make_offset
+unsetopt make_prog
+setopt make_symbol #
+setopt mem_config 16384
+unsetopt mem_trace
+setopt num_proc 1
+unsetopt page_cmds
+setopt page_list 19
+unsetopt page_load
+unsetopt path
+setopt proto_path . /s2/saber_dir30/sun4-40/proto /s2/saber_dir30/sun4-40/../common/proto
+unsetopt preprocessor
+setopt program_name a.out
+unsetopt print_custom
+setopt print_pointer
+setopt print_string 20
+unsetopt save_memory
+setopt sbrk_size 1048576
+setopt src_err 3
+setopt src_step 1
+setopt src_stop 3
+setopt sys_load_flags -L/lib -L/usr/lib -L/usr/local/lib -I/usr/include -Dunix -Dsun -Dsparc
+unsetopt tab_stop
+unsetopt terse_suppress
+unsetopt terse_where
+setopt unset_value 191
+unsetopt win_fork_nodup
+setopt win_no_raise
+unsetopt win_message_list
+unsetopt win_project_list
+/* Suppressions for project */
+suppress 6 in read_huge_number
+/* Over/underflow <plus> */
+suppress 8 in read_huge_number
+/* Over/underflow <multiply> */
+suppress 22
+/* Pointer subtraction */
+suppress 22 in free_all_psymtabs
+/* Pointer subtraction */
+suppress 22 in free_all_symtabs
+/* Pointer subtraction */
+suppress 56 in print_string
+/* Information lost <function> */
+suppress 65 "../bfd/bfd.c":379
+/* Too many function arguments */
+suppress 65 on printf_filtered
+/* Too many function arguments */
+suppress 65 on fprintf_filtered
+/* Too many function arguments */
+suppress 65 on vfprintf_filtered
+/* Too many function arguments */
+suppress 65 on query
+/* Too many function arguments */
+suppress 65 on fatal_dump_core
+/* Too many function arguments */
+suppress 65 on fatal
+/* Too many function arguments */
+suppress 65 on error
+/* Too many function arguments */
+suppress 65 on noprocess
+/* Too many function arguments */
+suppress 65
+/* Too many function arguments */
+suppress 66 on say
+/* Too few function arguments */
+suppress 66 on printf_filtered
+/* Too few function arguments */
+suppress 66 on fprintf_filtered
+/* Too few function arguments */
+suppress 66 on vfprintf_filtered
+/* Too few function arguments */
+suppress 66 on query
+/* Too few function arguments */
+suppress 66 on fatal_dump_core
+/* Too few function arguments */
+suppress 66 on fatal
+/* Too few function arguments */
+suppress 66 on error
+/* Too few function arguments */
+suppress 67 on printf_filtered
+/* Signed/unsigned argument mismatch */
+suppress 67 on fprintf_filtered
+/* Signed/unsigned argument mismatch */
+suppress 67 on vfprintf_filtered
+/* Signed/unsigned argument mismatch */
+suppress 67 on query
+/* Signed/unsigned argument mismatch */
+suppress 67 on fatal_dump_core
+/* Signed/unsigned argument mismatch */
+suppress 67 on fatal
+/* Signed/unsigned argument mismatch */
+suppress 67 on error
+/* Signed/unsigned argument mismatch */
+suppress 67
+/* Signed/unsigned argument mismatch */
+suppress 68 on bfd_get_section_contents
+/* Benign argument mismatch */
+suppress 68 on _do_getblong
+/* Benign argument mismatch */
+suppress 68 on supply_register
+/* Benign argument mismatch */
+suppress 68 on target_write_memory
+/* Benign argument mismatch */
+suppress 68 on write_register_bytes
+/* Benign argument mismatch */
+suppress 68 on read_register_bytes
+/* Benign argument mismatch */
+suppress 68 on read_memory
+/* Benign argument mismatch */
+suppress 68 on say
+/* Benign argument mismatch */
+suppress 68 on printf_filtered
+/* Benign argument mismatch */
+suppress 68 on fprintf_filtered
+/* Benign argument mismatch */
+suppress 68 on vfprintf_filtered
+/* Benign argument mismatch */
+suppress 68 on query
+/* Benign argument mismatch */
+suppress 68 on fatal_dump_core
+/* Benign argument mismatch */
+suppress 68 on fatal
+/* Benign argument mismatch */
+suppress 68 on error
+/* Benign argument mismatch */
+suppress 68 in find_solib
+/* Benign argument mismatch */
+suppress 68 on child_wait
+/* Benign argument mismatch */
+suppress 68 on xrealloc
+/* Benign argument mismatch */
+suppress 68 on myread
+/* Benign argument mismatch */
+suppress 68 in do_cleanups
+/* Benign argument mismatch */
+suppress 68 on make_cleanup
+/* Benign argument mismatch */
+suppress 68 on target_read_memory
+/* Benign argument mismatch */
+suppress 69 on printf_filtered
+/* Serious argument mismatch */
+suppress 69 on fprintf_filtered
+/* Serious argument mismatch */
+suppress 69 on vfprintf_filtered
+/* Serious argument mismatch */
+suppress 69 on query
+/* Serious argument mismatch */
+suppress 69 on fatal_dump_core
+/* Serious argument mismatch */
+suppress 69 on fatal
+/* Serious argument mismatch */
+suppress 69 on error
+/* Serious argument mismatch */
+suppress 70 on printf_filtered
+/* Passing illegal enumeration value */
+suppress 70 on fprintf_filtered
+/* Passing illegal enumeration value */
+suppress 70 on vfprintf_filtered
+/* Passing illegal enumeration value */
+suppress 70 on query
+/* Passing illegal enumeration value */
+suppress 70 on fatal_dump_core
+/* Passing illegal enumeration value */
+suppress 70 on fatal
+/* Passing illegal enumeration value */
+suppress 70 on error
+/* Passing illegal enumeration value */
+suppress 80 on first_link_map_member
+/* Returning invalid pointer */
+suppress 110 in printf_filtered
+/* Signed/unsigned memory retrieval */
+suppress 110 in fprintf_filtered
+/* Signed/unsigned memory retrieval */
+suppress 110 in vfprintf_filtered
+/* Signed/unsigned memory retrieval */
+suppress 110 in query
+/* Signed/unsigned memory retrieval */
+suppress 110 in fatal_dump_core
+/* Signed/unsigned memory retrieval */
+suppress 110 in fatal
+/* Signed/unsigned memory retrieval */
+suppress 110 in error
+/* Signed/unsigned memory retrieval */
+suppress 112 in printf_filtered
+/* Memory retrieval */
+suppress 112 in fprintf_filtered
+/* Memory retrieval */
+suppress 112 in vfprintf_filtered
+/* Memory retrieval */
+suppress 112 in query
+/* Memory retrieval */
+suppress 112 in fatal_dump_core
+/* Memory retrieval */
+suppress 112 in fatal
+/* Memory retrieval */
+suppress 112 in error
+/* Memory retrieval */
+suppress 112
+/* Memory retrieval */
+suppress 112 ../symtab.c
+/* Memory retrieval */
+suppress 112 in child_xfer_memory
+/* Memory retrieval */
+suppress 165 in frame_saved_pc
+/* Dereference */
+suppress 165 in get_prev_frame_info
+/* Dereference */
+suppress 167 in get_prev_frame_info
+/* Selection */
+suppress 167 in frame_saved_pc
+/* Selection */
+suppress 442 in try_baudrate
+/* Escape has null value */
+suppress 529 in read_range_type
+/* Statement not reached */
+suppress 529 in process_one_symbol
+/* Statement not reached */
+suppress 529 in unpack_double
+/* Statement not reached */
+suppress 529 in wait_for_inferior
+/* Statement not reached */
+suppress 529 in do_registers_info
+/* Statement not reached */
+suppress 529 in value_from_register
+/* Statement not reached */
+suppress 529 in solib_create_inferior_hook
+/* Constant in conditional */
+suppress 530
+/* Empty body of statement */
+suppress 546 in net_quit
+/* Function exits through bottom */
+suppress 546 in net_wait
+/* Function exits through bottom */
+suppress 546 in vx_remove_breakpoint
+/* Function exits through bottom */
+suppress 546 in vx_insert_breakpoint
+/* Function exits through bottom */
+suppress 546 in value_less
+/* Function exits through bottom */
+suppress 546 in value_equal
+/* Function exits through bottom */
+suppress 546 in unpack_long
+/* Function exits through bottom */
+suppress 558 in solib_create_inferior_hook
+/* Constant in conditional */
+suppress 558 in read_range_type
+/* Constant in conditional */
+suppress 558 in process_one_symbol
+/* Constant in conditional */
+suppress 558 in read_dbx_symtab
+/* Constant in conditional */
+suppress 558 in vx_write_register
+/* Constant in conditional */
+suppress 558 in vx_read_register
+/* Constant in conditional */
+suppress 558 in unpack_double
+/* Constant in conditional */
+suppress 558 in wait_for_inferior
+/* Constant in conditional */
+suppress 558 in do_registers_info
+/* Constant in conditional */
+suppress 558 in value_from_register
+/* Constant in conditional */
+suppress 558 in add_enum_psymbol
+/* Constant in conditional */
+suppress 558 in add_partial_symbol
+/* Constant in conditional */
+suppress 558 mfree.c
+/* Constant in conditional */
+suppress 558 mmalloc.c
+/* Constant in conditional */
+suppress 558 mrealloc.c
+/* Constant in conditional */
+suppress 560 in solib_address
+/* Assignment within conditional */
+suppress 560 in solib_info
+/* Assignment within conditional */
+suppress 560 in solib_add
+/* Assignment within conditional */
+suppress 560 in read_type
+/* Assignment within conditional */
+suppress 560 in type_print_base
+/* Assignment within conditional */
+suppress 560 in type_print_derivation_info
+/* Assignment within conditional */
+suppress 560 in block_depth
+/* Assignment within conditional */
+suppress 560 in select_source_symtab
+/* Assignment within conditional */
+suppress 560 in clear_value_history
+/* Assignment within conditional */
+suppress 560 in clear_displays
+/* Assignment within conditional */
+suppress 560 in initialize_main
+/* Assignment within conditional */
+suppress 560 in echo_command
+/* Assignment within conditional */
+suppress 560 in unset_in_environ
+/* Assignment within conditional */
+suppress 560 in set_in_environ
+/* Assignment within conditional */
+suppress 560 in get_in_environ
+/* Assignment within conditional */
+suppress 560 in do_setshow_command
+/* Assignment within conditional */
+suppress 560 in breakpoint_1
+/* Assignment within conditional */
+suppress 590 on sig
+/* Unused formal parameter */
+suppress 590 in nindy_create_inferior
+/* Unused formal parameter */
+suppress 590 in add_to_section_table
+/* Unused formal parameter */
+suppress 590 in vx_create_inferior
+/* Unused formal parameter */
+suppress 590 in host_convert_from_virtual
+/* Unused formal parameter */
+suppress 590 in host_convert_to_virtual
+/* Unused formal parameter */
+suppress 590 on siggnal
+/* Unused formal parameter */
+suppress 590 in init_sig
+/* Unused formal parameter */
+suppress 590 in nindy_resume
+/* Unused formal parameter */
+suppress 590 in set_history_size_command
+/* Unused formal parameter */
+suppress 590 in not_just_help_class_command
+/* Unused formal parameter */
+suppress 590 on regno
+/* Unused formal parameter */
+suppress 590 on from_tty
+/* Unused formal parameter */
+suppress 590 on args
+/* Unused formal parameter */
+suppress 590 in process_symbol_pair
+/* Unused formal parameter */
+suppress 591 in print_scalar_formatted
+/* Unused automatic variable */
+suppress 592 on rcsid
+/* Unused static */
+suppress 594 in call_function_by_hand
+/* Set but not used */
+suppress 594 in record_latest_value
+/* Set but not used */
+suppress 594 in bpstat_stop_status
+/* Set but not used */
+suppress 595 in coffstrip
+/* Used before set */
+suppress 652 ../include/bfd.h
+/* Declaration has no effect */
+suppress 652 /usr/include/machine/reg.h
+/* Declaration has no effect */
+suppress 652 /usr/include/sun4/reg.h
+/* Declaration has no effect */
+suppress 68 on complain
+/* Benign type mismatch */
+suppress 3 in read_range_type
+/* Over/underflow unary minus */
+suppress 442 ../bfd/archive.c
+/* \0 in string */
+suppress 558 ../bfd/b.out.c
+/* Conditional if always true */
+suppress 558 ../bfd/coffswap.c
+/* Conditional if always true -- bfd_h_put_x */
+suppress 529 ../bfd/coffswap.c
+/* Stmt unreach -- bfd_h_put_x */
+suppress 590 ../bfd/ecoff.c
+/* Formal parameter not used */
+suppress 590 on ignore
+/* Formal param not used */
+suppress 590 on ignore_exec_bfd
+/* Formal param not used */
+suppress 590 on ignore_core_bfd
+/* Formal param not used */
+suppress 590 on ignore_input_section
+/* Formal param not used */
+suppress 590 on ignore_newsect
+/* Formal param not used */
+suppress 590 on ignore_abfd
+/* Formal param not used */
+suppress 590 on ignore_symbol
+/* Formal param not used */
+suppress 590 on ignore_symbols
+/* Formal param not used */
+suppress 590 on signo
+/* Formal param not used */
+suppress 652
+/* The declaration has no effect */
+suppress 442 in ../bfd/archive.c
+/* Escape sequence in string literal has null value */
+
+/* Signals caught and ignored */
+catch HUP
+catch QUIT
+catch ILL
+catch TRAP
+catch IOT
+catch EMT
+catch FPE
+catch KILL
+catch BUS
+catch SEGV
+catch SYS
+catch PIPE
+catch TERM
+catch URG
+catch STOP
+catch TSTP
+catch TTIN
+catch TTOU
+catch IO
+catch XCPU
+catch XFSZ
+catch VTALRM
+catch PROF
+catch LOST
+catch USR1
+catch USR2
+ignore INT
+ignore ALRM
+ignore CONT
+ignore CHLD
+ignore WINCH
+
+/* Status of project */
diff --git a/gdb/scm-exp.c b/gdb/scm-exp.c
new file mode 100644
index 00000000000..7464ecfc6bf
--- /dev/null
+++ b/gdb/scm-exp.c
@@ -0,0 +1,495 @@
+/* Scheme/Guile language support routines for GDB, the GNU debugger.
+ Copyright 1995, 1996, 2000 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "value.h"
+#include "c-lang.h"
+#include "scm-lang.h"
+#include "scm-tags.h"
+
+#define USE_EXPRSTRING 0
+
+static void scm_lreadparen (int);
+static int scm_skip_ws (void);
+static void scm_read_token (int, int);
+static LONGEST scm_istring2number (char *, int, int);
+static LONGEST scm_istr2int (char *, int, int);
+static void scm_lreadr (int);
+
+static LONGEST
+scm_istr2int (char *str, int len, int radix)
+{
+ int i = 0;
+ LONGEST inum = 0;
+ int c;
+ int sign = 0;
+
+ if (0 >= len)
+ return SCM_BOOL_F; /* zero scm_length */
+ switch (str[0])
+ { /* leading sign */
+ case '-':
+ case '+':
+ sign = str[0];
+ if (++i == len)
+ return SCM_BOOL_F; /* bad if lone `+' or `-' */
+ }
+ do
+ {
+ switch (c = str[i++])
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ c = c - '0';
+ goto accumulate;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ c = c - 'A' + 10;
+ goto accumulate;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ c = c - 'a' + 10;
+ accumulate:
+ if (c >= radix)
+ return SCM_BOOL_F; /* bad digit for radix */
+ inum *= radix;
+ inum += c;
+ break;
+ default:
+ return SCM_BOOL_F; /* not a digit */
+ }
+ }
+ while (i < len);
+ if (sign == '-')
+ inum = -inum;
+ return SCM_MAKINUM (inum);
+}
+
+static LONGEST
+scm_istring2number (char *str, int len, int radix)
+{
+ int i = 0;
+ char ex = 0;
+ char ex_p = 0, rx_p = 0; /* Only allow 1 exactness and 1 radix prefix */
+#if 0
+ SCM res;
+#endif
+ if (len == 1)
+ if (*str == '+' || *str == '-') /* Catches lone `+' and `-' for speed */
+ return SCM_BOOL_F;
+
+ while ((len - i) >= 2 && str[i] == '#' && ++i)
+ switch (str[i++])
+ {
+ case 'b':
+ case 'B':
+ if (rx_p++)
+ return SCM_BOOL_F;
+ radix = 2;
+ break;
+ case 'o':
+ case 'O':
+ if (rx_p++)
+ return SCM_BOOL_F;
+ radix = 8;
+ break;
+ case 'd':
+ case 'D':
+ if (rx_p++)
+ return SCM_BOOL_F;
+ radix = 10;
+ break;
+ case 'x':
+ case 'X':
+ if (rx_p++)
+ return SCM_BOOL_F;
+ radix = 16;
+ break;
+ case 'i':
+ case 'I':
+ if (ex_p++)
+ return SCM_BOOL_F;
+ ex = 2;
+ break;
+ case 'e':
+ case 'E':
+ if (ex_p++)
+ return SCM_BOOL_F;
+ ex = 1;
+ break;
+ default:
+ return SCM_BOOL_F;
+ }
+
+ switch (ex)
+ {
+ case 1:
+ return scm_istr2int (&str[i], len - i, radix);
+ case 0:
+ return scm_istr2int (&str[i], len - i, radix);
+#if 0
+ if NFALSEP
+ (res) return res;
+#ifdef FLOATS
+ case 2:
+ return scm_istr2flo (&str[i], len - i, radix);
+#endif
+#endif
+ }
+ return SCM_BOOL_F;
+}
+
+static void
+scm_read_token (int c, int weird)
+{
+ while (1)
+ {
+ c = *lexptr++;
+ switch (c)
+ {
+ case '[':
+ case ']':
+ case '(':
+ case ')':
+ case '\"':
+ case ';':
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\f':
+ case '\n':
+ if (weird)
+ goto default_case;
+ case '\0': /* End of line */
+ eof_case:
+ --lexptr;
+ return;
+ case '\\':
+ if (!weird)
+ goto default_case;
+ else
+ {
+ c = *lexptr++;
+ if (c == '\0')
+ goto eof_case;
+ else
+ goto default_case;
+ }
+ case '}':
+ if (!weird)
+ goto default_case;
+
+ c = *lexptr++;
+ if (c == '#')
+ return;
+ else
+ {
+ --lexptr;
+ c = '}';
+ goto default_case;
+ }
+
+ default:
+ default_case:
+ ;
+ }
+ }
+}
+
+static int
+scm_skip_ws (void)
+{
+ register int c;
+ while (1)
+ switch ((c = *lexptr++))
+ {
+ case '\0':
+ goteof:
+ return c;
+ case ';':
+ lp:
+ switch ((c = *lexptr++))
+ {
+ case '\0':
+ goto goteof;
+ default:
+ goto lp;
+ case '\n':
+ break;
+ }
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\f':
+ case '\n':
+ break;
+ default:
+ return c;
+ }
+}
+
+static void
+scm_lreadparen (int skipping)
+{
+ for (;;)
+ {
+ int c = scm_skip_ws ();
+ if (')' == c || ']' == c)
+ return;
+ --lexptr;
+ if (c == '\0')
+ error ("missing close paren");
+ scm_lreadr (skipping);
+ }
+}
+
+static void
+scm_lreadr (int skipping)
+{
+ int c, j;
+ struct stoken str;
+ LONGEST svalue = 0;
+tryagain:
+ c = *lexptr++;
+ switch (c)
+ {
+ case '\0':
+ lexptr--;
+ return;
+ case '[':
+ case '(':
+ scm_lreadparen (skipping);
+ return;
+ case ']':
+ case ')':
+ error ("unexpected #\\%c", c);
+ goto tryagain;
+ case '\'':
+ case '`':
+ str.ptr = lexptr - 1;
+ scm_lreadr (skipping);
+ if (!skipping)
+ {
+ struct value *val = scm_evaluate_string (str.ptr, lexptr - str.ptr);
+ if (!is_scmvalue_type (VALUE_TYPE (val)))
+ error ("quoted scm form yields non-SCM value");
+ svalue = extract_signed_integer (VALUE_CONTENTS (val),
+ TYPE_LENGTH (VALUE_TYPE (val)));
+ goto handle_immediate;
+ }
+ return;
+ case ',':
+ c = *lexptr++;
+ if ('@' != c)
+ lexptr--;
+ scm_lreadr (skipping);
+ return;
+ case '#':
+ c = *lexptr++;
+ switch (c)
+ {
+ case '[':
+ case '(':
+ scm_lreadparen (skipping);
+ return;
+ case 't':
+ case 'T':
+ svalue = SCM_BOOL_T;
+ goto handle_immediate;
+ case 'f':
+ case 'F':
+ svalue = SCM_BOOL_F;
+ goto handle_immediate;
+ case 'b':
+ case 'B':
+ case 'o':
+ case 'O':
+ case 'd':
+ case 'D':
+ case 'x':
+ case 'X':
+ case 'i':
+ case 'I':
+ case 'e':
+ case 'E':
+ lexptr--;
+ c = '#';
+ goto num;
+ case '*': /* bitvector */
+ scm_read_token (c, 0);
+ return;
+ case '{':
+ scm_read_token (c, 1);
+ return;
+ case '\\': /* character */
+ c = *lexptr++;
+ scm_read_token (c, 0);
+ return;
+ case '|':
+ j = 1; /* here j is the comment nesting depth */
+ lp:
+ c = *lexptr++;
+ lpc:
+ switch (c)
+ {
+ case '\0':
+ error ("unbalanced comment");
+ default:
+ goto lp;
+ case '|':
+ if ('#' != (c = *lexptr++))
+ goto lpc;
+ if (--j)
+ goto lp;
+ break;
+ case '#':
+ if ('|' != (c = *lexptr++))
+ goto lpc;
+ ++j;
+ goto lp;
+ }
+ goto tryagain;
+ case '.':
+ default:
+#if 0
+ callshrp:
+#endif
+ scm_lreadr (skipping);
+ return;
+ }
+ case '\"':
+ while ('\"' != (c = *lexptr++))
+ {
+ if (c == '\\')
+ switch (c = *lexptr++)
+ {
+ case '\0':
+ error ("non-terminated string literal");
+ case '\n':
+ continue;
+ case '0':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
+ case 'a':
+ case 'v':
+ break;
+ }
+ }
+ return;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '.':
+ case '-':
+ case '+':
+ num:
+ {
+ str.ptr = lexptr - 1;
+ scm_read_token (c, 0);
+ if (!skipping)
+ {
+ svalue = scm_istring2number (str.ptr, lexptr - str.ptr, 10);
+ if (svalue != SCM_BOOL_F)
+ goto handle_immediate;
+ goto tok;
+ }
+ }
+ return;
+ case ':':
+ scm_read_token ('-', 0);
+ return;
+#if 0
+ do_symbol:
+#endif
+ default:
+ str.ptr = lexptr - 1;
+ scm_read_token (c, 0);
+ tok:
+ if (!skipping)
+ {
+ str.length = lexptr - str.ptr;
+ if (str.ptr[0] == '$')
+ {
+ write_dollar_variable (str);
+ return;
+ }
+ write_exp_elt_opcode (OP_NAME);
+ write_exp_string (str);
+ write_exp_elt_opcode (OP_NAME);
+ }
+ return;
+ }
+handle_immediate:
+ if (!skipping)
+ {
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_scm);
+ write_exp_elt_longcst (svalue);
+ write_exp_elt_opcode (OP_LONG);
+ }
+}
+
+int
+scm_parse (void)
+{
+ char *start;
+ while (*lexptr == ' ')
+ lexptr++;
+ start = lexptr;
+ scm_lreadr (USE_EXPRSTRING);
+#if USE_EXPRSTRING
+ str.length = lexptr - start;
+ str.ptr = start;
+ write_exp_elt_opcode (OP_EXPRSTRING);
+ write_exp_string (str);
+ write_exp_elt_opcode (OP_EXPRSTRING);
+#endif
+ return 0;
+}
diff --git a/gdb/scm-lang.c b/gdb/scm-lang.c
new file mode 100644
index 00000000000..00d679730cd
--- /dev/null
+++ b/gdb/scm-lang.c
@@ -0,0 +1,267 @@
+/* Scheme/Guile language support routines for GDB, the GNU debugger.
+ Copyright 1995, 1996, 1998, 2000, 2001, 2002
+ 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "value.h"
+#include "c-lang.h"
+#include "scm-lang.h"
+#include "scm-tags.h"
+#include "gdb_string.h"
+#include "gdbcore.h"
+
+extern void _initialize_scheme_language (void);
+static struct value *evaluate_subexp_scm (struct type *, struct expression *,
+ int *, enum noside);
+static struct value *scm_lookup_name (char *);
+static int in_eval_c (void);
+static void scm_printstr (struct ui_file * stream, char *string,
+ unsigned int length, int width,
+ int force_ellipses);
+
+extern struct type **const (c_builtin_types[]);
+
+struct type *builtin_type_scm;
+
+void
+scm_printchar (int c, struct ui_file *stream)
+{
+ fprintf_filtered (stream, "#\\%c", c);
+}
+
+static void
+scm_printstr (struct ui_file *stream, char *string, unsigned int length,
+ int width, int force_ellipses)
+{
+ fprintf_filtered (stream, "\"%s\"", string);
+}
+
+int
+is_scmvalue_type (struct type *type)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_INT
+ && TYPE_NAME (type) && strcmp (TYPE_NAME (type), "SCM") == 0)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/* Get the INDEX'th SCM value, assuming SVALUE is the address
+ of the 0'th one. */
+
+LONGEST
+scm_get_field (LONGEST svalue, int index)
+{
+ char buffer[20];
+ read_memory (SCM2PTR (svalue) + index * TYPE_LENGTH (builtin_type_scm),
+ buffer, TYPE_LENGTH (builtin_type_scm));
+ return extract_signed_integer (buffer, TYPE_LENGTH (builtin_type_scm));
+}
+
+/* Unpack a value of type TYPE in buffer VALADDR as an integer
+ (if CONTEXT == TYPE_CODE_IN), a pointer (CONTEXT == TYPE_CODE_PTR),
+ or Boolean (CONTEXT == TYPE_CODE_BOOL). */
+
+LONGEST
+scm_unpack (struct type *type, char *valaddr, enum type_code context)
+{
+ if (is_scmvalue_type (type))
+ {
+ LONGEST svalue = extract_signed_integer (valaddr, TYPE_LENGTH (type));
+ if (context == TYPE_CODE_BOOL)
+ {
+ if (svalue == SCM_BOOL_F)
+ return 0;
+ else
+ return 1;
+ }
+ switch (7 & (int) svalue)
+ {
+ case 2:
+ case 6: /* fixnum */
+ return svalue >> 2;
+ case 4: /* other immediate value */
+ if (SCM_ICHRP (svalue)) /* character */
+ return SCM_ICHR (svalue);
+ else if (SCM_IFLAGP (svalue))
+ {
+ switch ((int) svalue)
+ {
+#ifndef SICP
+ case SCM_EOL:
+#endif
+ case SCM_BOOL_F:
+ return 0;
+ case SCM_BOOL_T:
+ return 1;
+ }
+ }
+ error ("Value can't be converted to integer.");
+ default:
+ return svalue;
+ }
+ }
+ else
+ return unpack_long (type, valaddr);
+}
+
+/* True if we're correctly in Guile's eval.c (the evaluator and apply). */
+
+static int
+in_eval_c (void)
+{
+ if (current_source_symtab && current_source_symtab->filename)
+ {
+ char *filename = current_source_symtab->filename;
+ int len = strlen (filename);
+ if (len >= 6 && strcmp (filename + len - 6, "eval.c") == 0)
+ return 1;
+ }
+ return 0;
+}
+
+/* Lookup a value for the variable named STR.
+ First lookup in Scheme context (using the scm_lookup_cstr inferior
+ function), then try lookup_symbol for compiled variables. */
+
+static struct value *
+scm_lookup_name (char *str)
+{
+ struct value *args[3];
+ int len = strlen (str);
+ struct value *func;
+ struct value *val;
+ struct symbol *sym;
+ args[0] = value_allocate_space_in_inferior (len);
+ args[1] = value_from_longest (builtin_type_int, len);
+ write_memory (value_as_long (args[0]), str, len);
+
+ if (in_eval_c ()
+ && (sym = lookup_symbol ("env",
+ expression_context_block,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL)) != NULL)
+ args[2] = value_of_variable (sym, expression_context_block);
+ else
+ /* FIXME in this case, we should try lookup_symbol first */
+ args[2] = value_from_longest (builtin_type_scm, SCM_EOL);
+
+ func = find_function_in_inferior ("scm_lookup_cstr");
+ val = call_function_by_hand (func, 3, args);
+ if (!value_logical_not (val))
+ return value_ind (val);
+
+ sym = lookup_symbol (str,
+ expression_context_block,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ if (sym)
+ return value_of_variable (sym, NULL);
+ error ("No symbol \"%s\" in current context.", str);
+}
+
+struct value *
+scm_evaluate_string (char *str, int len)
+{
+ struct value *func;
+ struct value *addr = value_allocate_space_in_inferior (len + 1);
+ LONGEST iaddr = value_as_long (addr);
+ write_memory (iaddr, str, len);
+ /* FIXME - should find and pass env */
+ write_memory (iaddr + len, "", 1);
+ func = find_function_in_inferior ("scm_evstr");
+ return call_function_by_hand (func, 1, &addr);
+}
+
+static struct value *
+evaluate_subexp_scm (struct type *expect_type, register struct expression *exp,
+ register int *pos, enum noside noside)
+{
+ enum exp_opcode op = exp->elts[*pos].opcode;
+ int len, pc;
+ char *str;
+ switch (op)
+ {
+ case OP_NAME:
+ pc = (*pos)++;
+ len = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (len + 1);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ str = &exp->elts[pc + 2].string;
+ return scm_lookup_name (str);
+ case OP_EXPRSTRING:
+ pc = (*pos)++;
+ len = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (len + 1);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ str = &exp->elts[pc + 2].string;
+ return scm_evaluate_string (str, len);
+ default:;
+ }
+ return evaluate_subexp_standard (expect_type, exp, pos, noside);
+nosideret:
+ return value_from_longest (builtin_type_long, (LONGEST) 1);
+}
+
+const struct language_defn scm_language_defn =
+{
+ "scheme", /* Language name */
+ language_scm,
+ c_builtin_types,
+ range_check_off,
+ type_check_off,
+ case_sensitive_off,
+ scm_parse,
+ c_error,
+ evaluate_subexp_scm,
+ scm_printchar, /* Print a character constant */
+ scm_printstr, /* Function to print string constant */
+ NULL, /* Function to print a single character */
+ NULL, /* Create fundamental type in this language */
+ c_print_type, /* Print a type using appropriate syntax */
+ scm_val_print, /* Print a value using appropriate syntax */
+ scm_value_print, /* Print a top-level value */
+ {"", "", "", ""}, /* Binary format info */
+ {"#o%lo", "#o", "o", ""}, /* Octal format info */
+ {"%ld", "", "d", ""}, /* Decimal format info */
+ {"#x%lX", "#X", "X", ""}, /* Hex format info */
+ NULL, /* expression operators for printing */
+ 1, /* c-style arrays */
+ 0, /* String lower bound */
+ &builtin_type_char, /* Type of string elements */
+ LANG_MAGIC
+};
+
+void
+_initialize_scheme_language (void)
+{
+ add_language (&scm_language_defn);
+ builtin_type_scm = init_type (TYPE_CODE_INT,
+ TARGET_LONG_BIT / TARGET_CHAR_BIT,
+ 0, "SCM", (struct objfile *) NULL);
+}
diff --git a/gdb/scm-lang.h b/gdb/scm-lang.h
new file mode 100644
index 00000000000..713b0309028
--- /dev/null
+++ b/gdb/scm-lang.h
@@ -0,0 +1,70 @@
+/* Scheme/Guile language support routines for GDB, the GNU debugger.
+ Copyright 1995, 1996, 1998, 1999, 2000 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. */
+
+#define SICP
+#include "scm-tags.h"
+#undef SCM_NCELLP
+#define SCM_NCELLP(x) ((SCM_SIZE-1) & (int)(x))
+#define SCM_ITAG8_DATA(X) ((X)>>8)
+#define SCM_ICHR(x) ((unsigned char)SCM_ITAG8_DATA(x))
+#define SCM_ICHRP(x) (SCM_ITAG8(x) == scm_tc8_char)
+#define scm_tc8_char 0xf4
+#define SCM_IFLAGP(n) ((0x87 & (int)(n))==4)
+#define SCM_ISYMNUM(n) ((int)((n)>>9))
+#define SCM_ISYMCHARS(n) (scm_isymnames[SCM_ISYMNUM(n)])
+#define SCM_ILOCP(n) ((0xff & (int)(n))==0xfc)
+#define SCM_ITAG8(X) ((int)(X) & 0xff)
+#define SCM_TYP7(x) (0x7f & (int)SCM_CAR(x))
+#define SCM_LENGTH(x) (((unsigned long)SCM_CAR(x))>>8)
+#define SCM_NCONSP(x) (1 & (int)SCM_CAR(x))
+#define SCM_NECONSP(x) (SCM_NCONSP(x) && (1 != SCM_TYP3(x)))
+#define SCM_CAR(x) scm_get_field (x, 0)
+#define SCM_CDR(x) scm_get_field (x, 1)
+#define SCM_VELTS(x) ((SCM *)SCM_CDR(x))
+#define SCM_CLOSCAR(x) (SCM_CAR(x)-scm_tc3_closure)
+#define SCM_CODE(x) SCM_CAR(SCM_CLOSCAR (x))
+#define SCM_MAKINUM(x) (((x)<<2)+2L)
+
+/* Forward decls for prototypes */
+struct value;
+
+extern int scm_value_print (struct value *, struct ui_file *,
+ int, enum val_prettyprint);
+
+extern int scm_val_print (struct type *, char *, int, CORE_ADDR,
+ struct ui_file *, int, int, int,
+ enum val_prettyprint);
+
+extern LONGEST scm_get_field (LONGEST, int);
+
+extern void scm_scmval_print (LONGEST, struct ui_file *, int, int, int,
+ enum val_prettyprint);
+
+extern int is_scmvalue_type (struct type *);
+
+extern void scm_printchar (int, struct ui_file *);
+
+extern struct value *scm_evaluate_string (char *, int);
+
+extern struct type *builtin_type_scm;
+
+extern int scm_parse (void);
+
+extern LONGEST scm_unpack (struct type *, char *, enum type_code);
diff --git a/gdb/scm-tags.h b/gdb/scm-tags.h
new file mode 100644
index 00000000000..4fa5ce2d16d
--- /dev/null
+++ b/gdb/scm-tags.h
@@ -0,0 +1,379 @@
+/* This is a minimally edited version of Guile's tags.h. */
+/* classes: h_files */
+
+#ifndef TAGSH
+#define TAGSH
+/* Copyright 1995, 1999 Free Software Foundation, Inc.
+
+ * 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, 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.
+ *
+ * As a special exception, the Free Software Foundation gives permission
+ * for additional uses of the text contained in its release of GUILE.
+ *
+ * The exception is that, if you link the GUILE library with other files
+ * to produce an executable, this does not by itself cause the
+ * resulting executable to be covered by the GNU General Public License.
+ * Your use of that executable is in no way restricted on account of
+ * linking the GUILE library code into it.
+ *
+ * This exception does not however invalidate any other reasons why
+ * the executable file might be covered by the GNU General Public License.
+ *
+ * This exception applies only to the code released by the
+ * Free Software Foundation under the name GUILE. If you copy
+ * code from other Free Software Foundation releases into a copy of
+ * GUILE, as the General Public License permits, the exception does
+ * not apply to the code that you add in this way. To avoid misleading
+ * anyone as to the status of such modified files, you must delete
+ * this exception notice from them.
+ *
+ * If you write modifications of your own for GUILE, it is your choice
+ * whether to permit this exception to apply to your modifications.
+ * If you do not wish that, delete this exception notice.
+ */
+
+
+/** This file defines the format of SCM values and cons pairs.
+ ** It is here that tag bits are assigned for various purposes.
+ **/
+
+
+/* Three Bit Tags
+
+ * 000 -- a non-immediate value. Points into the pair heap.
+ *
+ * 001 -- a gloc (i.e., a resolved global variable in a CAR in a code graph)
+ * or the CAR of an object handle (i.e., the tagged pointer to the
+ * vtable part of a user-defined object).
+ *
+ * If X has this tag, the value at CDAR(X - 1) distinguishes
+ * glocs from object handles. The distinction only needs
+ * to be made in a few places. Only a few parts of the code know
+ * about glocs. In most cases, when a value in the CAR of a pair
+ * has the tag 001, it means that the pair is an object handle.
+ *
+ * 010 -- the tag for immediate, exact integers.
+ *
+ * 011 -- in the CAR of a pair, this tag indicates that the pair is a closure.
+ * The remaining bits of the CAR are a pointer into the pair heap
+ * to the code graph for the closure.
+ *
+ * 1xy -- an extension tag which means that there is a five or six bit
+ * tag to the left of the low three bits. See the nice diagrams
+ * in ../doc/code.doc if you want to know what the bits mean.
+ */
+
+
+
+
+
+#define scm_tc3_cons 0
+#define scm_tc3_cons_gloc 1
+#define scm_tc3_closure 3
+
+#define scm_tc7_ssymbol 5
+#define scm_tc7_msymbol 7
+#define scm_tc7_string 13
+#define scm_tc7_bvect 15
+#define scm_tc7_vector 21
+#define scm_tc7_lvector 23
+#define scm_tc7_ivect 29
+#define scm_tc7_uvect 31
+/* spare 37 39 */
+#define scm_tc7_fvect 45
+#define scm_tc7_dvect 47
+#define scm_tc7_cvect 53
+#define scm_tc7_port 55
+#define scm_tc7_contin 61
+#define scm_tc7_cclo 63
+/* spare 69 71 77 79 */
+#define scm_tc7_subr_0 85
+#define scm_tc7_subr_1 87
+#define scm_tc7_cxr 93
+#define scm_tc7_subr_3 95
+#define scm_tc7_subr_2 101
+#define scm_tc7_asubr 103
+#define scm_tc7_subr_1o 109
+#define scm_tc7_subr_2o 111
+#define scm_tc7_lsubr_2 117
+#define scm_tc7_lsubr 119
+#define scm_tc7_rpsubr 125
+
+#define scm_tc7_smob 127
+#define scm_tc_free_cell 127
+
+#define scm_tc16_flo 0x017f
+#define scm_tc_flo 0x017fL
+
+#define SCM_REAL_PART (1L<<16)
+#define SCM_IMAG_PART (2L<<16)
+#define scm_tc_dblr (scm_tc16_flo|REAL_PART)
+#define scm_tc_dblc (scm_tc16_flo|REAL_PART|IMAG_PART)
+
+#define scm_tc16_bigpos 0x027f
+#define scm_tc16_bigneg 0x037f
+
+#define scm_tc16_fport (scm_tc7_port + 0*256L)
+#define scm_tc16_pipe (scm_tc7_port + 1*256L)
+#define scm_tc16_strport (scm_tc7_port + 2*256L)
+#define scm_tc16_sfport (scm_tc7_port + 3*256L)
+
+
+
+/* For cons pairs with immediate values in the CAR */
+#define scm_tcs_cons_imcar 2:case 4:case 6:case 10:\
+ case 12:case 14:case 18:case 20:\
+ case 22:case 26:case 28:case 30:\
+ case 34:case 36:case 38:case 42:\
+ case 44:case 46:case 50:case 52:\
+ case 54:case 58:case 60:case 62:\
+ case 66:case 68:case 70:case 74:\
+ case 76:case 78:case 82:case 84:\
+ case 86:case 90:case 92:case 94:\
+ case 98:case 100:case 102:case 106:\
+ case 108:case 110:case 114:case 116:\
+ case 118:case 122:case 124:case 126
+
+/* For cons pairs with non-immediate values in the CAR */
+#define scm_tcs_cons_nimcar 0:case 8:case 16:case 24:\
+ case 32:case 40:case 48:case 56:\
+ case 64:case 72:case 80:case 88:\
+ case 96:case 104:case 112:case 120
+
+/* A CONS_GLOC occurs in code. It's CAR is a pointer to the
+ * CDR of a variable. The low order bits of the CAR are 001.
+ * The CDR of the gloc is the code continuation.
+ */
+#define scm_tcs_cons_gloc 1:case 9:case 17:case 25:\
+ case 33:case 41:case 49:case 57:\
+ case 65:case 73:case 81:case 89:\
+ case 97:case 105:case 113:case 121
+
+#define scm_tcs_closures 3:case 11:case 19:case 27:\
+ case 35:case 43:case 51:case 59:\
+ case 67:case 75:case 83:case 91:\
+ case 99:case 107:case 115:case 123
+
+#define scm_tcs_subrs scm_tc7_asubr:case scm_tc7_subr_0:case scm_tc7_subr_1:case scm_tc7_cxr:\
+ case scm_tc7_subr_3:case scm_tc7_subr_2:case scm_tc7_rpsubr:case scm_tc7_subr_1o:\
+ case scm_tc7_subr_2o:case scm_tc7_lsubr_2:case scm_tc7_lsubr
+
+#define scm_tcs_symbols scm_tc7_ssymbol:case scm_tc7_msymbol
+
+#define scm_tcs_bignums tc16_bigpos:case tc16_bigneg
+
+
+
+/* References to objects are of type SCM. Values may be non-immediate
+ * (pointers) or immediate (encoded, immutable, scalar values that fit
+ * in an SCM variable).
+ */
+
+typedef long SCM;
+
+/* Cray machines have pointers that are incremented once for each word,
+ * rather than each byte, the 3 most significant bits encode the byte
+ * within the word. The following macros deal with this by storing the
+ * native Cray pointers like the ones that looks like scm expects. This
+ * is done for any pointers that might appear in the car of a scm_cell, pointers
+ * to scm_vector elts, functions, &c are not munged.
+ */
+#ifdef _UNICOS
+#define SCM2PTR(x) ((int)(x) >> 3)
+#define PTR2SCM(x) (((SCM)(x)) << 3)
+#define SCM_POINTERS_MUNGED
+#else
+#define SCM2PTR(x) (x)
+#define PTR2SCM(x) ((SCM)(x))
+#endif /* def _UNICOS */
+
+
+
+/* Immediate? Predicates
+ */
+#define SCM_IMP(x) (6 & (int)(x))
+#define SCM_NIMP(x) (!SCM_IMP(x))
+
+
+
+enum scm_tags
+ {
+ scm_tc8_char = 0xf4
+ };
+
+#define SCM_ITAG8(X) ((int)(X) & 0xff)
+#define SCM_MAKE_ITAG8(X, TAG) (((X)<<8) + TAG)
+#define SCM_ITAG8_DATA(X) ((X)>>8)
+
+
+
+/* Local Environment Structure
+ */
+#define SCM_ILOCP(n) ((0xff & (int)(n))==0xfc)
+#define SCM_ILOC00 (0x000000fcL)
+#define SCM_IDINC (0x00100000L)
+#define SCM_ICDR (0x00080000L)
+#define SCM_IFRINC (0x00000100L)
+#define SCM_IDSTMSK (-SCM_IDINC)
+#define SCM_IFRAME(n) ((int)((SCM_ICDR-SCM_IFRINC)>>8) & ((int)(n)>>8))
+#define SCM_IDIST(n) (((unsigned long)(n))>>20)
+#define SCM_ICDRP(n) (SCM_ICDR & (n))
+
+
+/* Immediate Symbols, Special Symbols, Flags (various constants).
+ */
+
+/* ISYMP tests for ISPCSYM and ISYM */
+#define SCM_ISYMP(n) ((0x187 & (int)(n))==4)
+
+/* IFLAGP tests for ISPCSYM, ISYM and IFLAG */
+#define SCM_IFLAGP(n) ((0x87 & (int)(n))==4)
+#define SCM_ISYMNUM(n) ((int)((n)>>9))
+#define SCM_ISYMCHARS(n) (scm_isymnames[SCM_ISYMNUM(n)])
+#define SCM_MAKSPCSYM(n) (((n)<<9)+((n)<<3)+4L)
+#define SCM_MAKISYM(n) (((n)<<9)+0x74L)
+#define SCM_MAKIFLAG(n) (((n)<<9)+0x174L)
+
+/* This table must agree with the declarations
+ * in repl.c: {Names of immediate symbols}.
+ *
+ * These are used only in eval but their values
+ * have to be allocated here.
+ *
+ */
+
+#define SCM_IM_AND SCM_MAKSPCSYM(0)
+#define SCM_IM_BEGIN SCM_MAKSPCSYM(1)
+#define SCM_IM_CASE SCM_MAKSPCSYM(2)
+#define SCM_IM_COND SCM_MAKSPCSYM(3)
+#define SCM_IM_DO SCM_MAKSPCSYM(4)
+#define SCM_IM_IF SCM_MAKSPCSYM(5)
+#define SCM_IM_LAMBDA SCM_MAKSPCSYM(6)
+#define SCM_IM_LET SCM_MAKSPCSYM(7)
+#define SCM_IM_LETSTAR SCM_MAKSPCSYM(8)
+#define SCM_IM_LETREC SCM_MAKSPCSYM(9)
+#define SCM_IM_OR SCM_MAKSPCSYM(10)
+#define SCM_IM_QUOTE SCM_MAKSPCSYM(11)
+#define SCM_IM_SET SCM_MAKSPCSYM(12)
+#define SCM_IM_DEFINE SCM_MAKSPCSYM(13)
+#define SCM_IM_APPLY SCM_MAKISYM(14)
+#define SCM_IM_CONT SCM_MAKISYM(15)
+#define SCM_NUM_ISYMS 16
+
+/* Important immediates
+ */
+
+#define SCM_BOOL_F SCM_MAKIFLAG(SCM_NUM_ISYMS+0)
+#define SCM_BOOL_T SCM_MAKIFLAG(SCM_NUM_ISYMS+1)
+#define SCM_UNDEFINED SCM_MAKIFLAG(SCM_NUM_ISYMS+2)
+#define SCM_EOF_VAL SCM_MAKIFLAG(SCM_NUM_ISYMS+3)
+
+#ifdef SICP
+#define SCM_EOL SCM_BOOL_F
+#else
+#define SCM_EOL SCM_MAKIFLAG(SCM_NUM_ISYMS+4)
+#endif
+
+#define SCM_UNSPECIFIED SCM_MAKIFLAG(SCM_NUM_ISYMS+5)
+
+
+
+/* Heap Pairs and the Empty List Predicates
+ */
+#define SCM_NULLP(x) (SCM_EOL == (x))
+#define SCM_NNULLP(x) (SCM_EOL != (x))
+#define SCM_CELLP(x) (!SCM_NCELLP(x))
+#define SCM_NCELLP(x) ((sizeof(scm_cell)-1) & (int)(x))
+
+
+
+#define SCM_UNBNDP(x) (SCM_UNDEFINED==(x))
+
+
+
+/* Testing and Changing GC Marks in Various Standard Positions
+ */
+#define SCM_GCMARKP(x) (1 & (int)SCM_CDR(x))
+#define SCM_GC8MARKP(x) (0x80 & (int)SCM_CAR(x))
+#define SCM_SETGCMARK(x) (SCM_CDR(x) |= 1)
+#define SCM_CLRGCMARK(x) (SCM_CDR(x) &= ~1L)
+#define SCM_SETGC8MARK(x) (SCM_CAR(x) |= 0x80)
+#define SCM_CLRGC8MARK(x) (SCM_CAR(x) &= ~0x80L)
+
+
+/* Extracting Tag Bits, With or Without GC Safety and Optional Bits
+ */
+#define SCM_TYP3(x) (7 & (int)SCM_CAR(x))
+#define SCM_TYP7(x) (0x7f & (int)SCM_CAR(x))
+#define SCM_TYP7S(x) (0x7d & (int)SCM_CAR(x))
+#define SCM_TYP16(x) (0xffff & (int)SCM_CAR(x))
+#define SCM_TYP16S(x) (0xfeff & (int)SCM_CAR(x))
+#define SCM_GCTYP16(x) (0xff7f & (int)SCM_CAR(x))
+
+
+/* Two slightly extensible types: smobs and ptobs.
+
+ */
+#define SCM_SMOBNUM(x) (0x0ff & (CAR(x)>>8));
+#define SCM_PTOBNUM(x) (0x0ff & (CAR(x)>>8));
+
+
+
+
+#define SCM_DIRP(x) (SCM_NIMP(x) && (TYP16(x)==(scm_tc16_dir)))
+#define SCM_OPDIRP(x) (SCM_NIMP(x) && (CAR(x)==(scm_tc16_dir | OPN)))
+
+
+
+/* Lvectors
+ */
+#define SCM_LVECTORP(x) (TYP7(x)==tc7_lvector)
+
+
+#if 0
+
+/* Sockets
+ */
+#define tc_socket (tc7_port | OPN)
+#define SCM_SOCKP(x) (((0x7f | OPN | RDNG | WRTNG) & CAR(x))==(tc_socket))
+#define SCM_SOCKTYP(x) (CAR(x)>>24)
+
+
+
+extern int scm_tc16_key_vector;
+#define SCM_KEYVECP(X) (scm_tc16_key_vector == TYP16 (X))
+#define SCM_KEYVECLEN(OBJ) (((unsigned long)CAR (obj)) >> 16)
+
+
+#define SCM_MALLOCDATA(obj) ((char *)CDR(obj))
+#define SCM_MALLOCLEN(obj) (((unsigned long)CAR (obj)) >> 16)
+#define SCM_WORDDATA(obj) (CDR (obj))
+
+
+#define SCM_BYTECODEP(X) ((TYP7 (X) == tc7_cclo) && (CCLO_SUBR (X) == rb_proc))
+#define SCM_BYTECODE_CONSTANTS(X) (VELTS(X)[1])
+#define SCM_BYTECODE_CODE(X) (VELTS(X)[2])
+#define SCM_BYTECODE_NAME(X) (VELTS(X)[3])
+#define SCM_BYTECODE_BCODE(X) (VELTS(X)[4])
+#define SCM_BYTECODE_ELTS 5
+
+
+#define SCM_FREEP(x) (CAR(x)==tc_free_cell)
+#define SCM_NFREEP(x) (!FREEP(x))
+
+#endif /* 0 */
+
+
+#endif /* TAGSH */
diff --git a/gdb/scm-valprint.c b/gdb/scm-valprint.c
new file mode 100644
index 00000000000..737bafab01f
--- /dev/null
+++ b/gdb/scm-valprint.c
@@ -0,0 +1,395 @@
+/* Scheme/Guile language support routines for GDB, the GNU debugger.
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "value.h"
+#include "scm-lang.h"
+#include "valprint.h"
+#include "gdbcore.h"
+
+/* FIXME: Should be in a header file that we import. */
+extern int c_val_print (struct type *, char *, int, CORE_ADDR,
+ struct ui_file *, int, int, int,
+ enum val_prettyprint);
+
+static void scm_ipruk (char *, LONGEST, struct ui_file *);
+static void scm_scmlist_print (LONGEST, struct ui_file *, int, int,
+ int, enum val_prettyprint);
+static int scm_inferior_print (LONGEST, struct ui_file *, int, int,
+ int, enum val_prettyprint);
+
+/* Prints the SCM value VALUE by invoking the inferior, if appropraite.
+ Returns >= 0 on succes; retunr -1 if the inferior cannot/should not
+ print VALUE. */
+
+static int
+scm_inferior_print (LONGEST value, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
+{
+ return -1;
+}
+
+/* {Names of immediate symbols}
+ * This table must agree with the declarations in scm.h: {Immediate Symbols}.*/
+
+static char *scm_isymnames[] =
+{
+ /* This table must agree with the declarations */
+ "and",
+ "begin",
+ "case",
+ "cond",
+ "do",
+ "if",
+ "lambda",
+ "let",
+ "let*",
+ "letrec",
+ "or",
+ "quote",
+ "set!",
+ "define",
+#if 0
+ "literal-variable-ref",
+ "literal-variable-set!",
+#endif
+ "apply",
+ "call-with-current-continuation",
+
+ /* user visible ISYMS */
+ /* other keywords */
+ /* Flags */
+
+ "#f",
+ "#t",
+ "#<undefined>",
+ "#<eof>",
+ "()",
+ "#<unspecified>"
+};
+
+static void
+scm_scmlist_print (LONGEST svalue, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
+{
+ unsigned int more = print_max;
+ if (recurse > 6)
+ {
+ fputs_filtered ("...", stream);
+ return;
+ }
+ scm_scmval_print (SCM_CAR (svalue), stream, format,
+ deref_ref, recurse + 1, pretty);
+ svalue = SCM_CDR (svalue);
+ for (; SCM_NIMP (svalue); svalue = SCM_CDR (svalue))
+ {
+ if (SCM_NECONSP (svalue))
+ break;
+ fputs_filtered (" ", stream);
+ if (--more == 0)
+ {
+ fputs_filtered ("...", stream);
+ return;
+ }
+ scm_scmval_print (SCM_CAR (svalue), stream, format,
+ deref_ref, recurse + 1, pretty);
+ }
+ if (SCM_NNULLP (svalue))
+ {
+ fputs_filtered (" . ", stream);
+ scm_scmval_print (svalue, stream, format,
+ deref_ref, recurse + 1, pretty);
+ }
+}
+
+static void
+scm_ipruk (char *hdr, LONGEST ptr, struct ui_file *stream)
+{
+ fprintf_filtered (stream, "#<unknown-%s", hdr);
+#define SCM_SIZE TYPE_LENGTH (builtin_type_scm)
+ if (SCM_CELLP (ptr))
+ fprintf_filtered (stream, " (0x%lx . 0x%lx) @",
+ (long) SCM_CAR (ptr), (long) SCM_CDR (ptr));
+ fprintf_filtered (stream, " 0x%s>", paddr_nz (ptr));
+}
+
+void
+scm_scmval_print (LONGEST svalue, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
+{
+taloop:
+ switch (7 & (int) svalue)
+ {
+ case 2:
+ case 6:
+ print_longest (stream, format ? format : 'd', 1, svalue >> 2);
+ break;
+ case 4:
+ if (SCM_ICHRP (svalue))
+ {
+ svalue = SCM_ICHR (svalue);
+ scm_printchar (svalue, stream);
+ break;
+ }
+ else if (SCM_IFLAGP (svalue)
+ && (SCM_ISYMNUM (svalue)
+ < (sizeof scm_isymnames / sizeof (char *))))
+ {
+ fputs_filtered (SCM_ISYMCHARS (svalue), stream);
+ break;
+ }
+ else if (SCM_ILOCP (svalue))
+ {
+ fprintf_filtered (stream, "#@%ld%c%ld",
+ (long) SCM_IFRAME (svalue),
+ SCM_ICDRP (svalue) ? '-' : '+',
+ (long) SCM_IDIST (svalue));
+ break;
+ }
+ else
+ goto idef;
+ break;
+ case 1:
+ /* gloc */
+ svalue = SCM_CAR (svalue - 1);
+ goto taloop;
+ default:
+ idef:
+ scm_ipruk ("immediate", svalue, stream);
+ break;
+ case 0:
+
+ switch (SCM_TYP7 (svalue))
+ {
+ case scm_tcs_cons_gloc:
+ if (SCM_CDR (SCM_CAR (svalue) - 1L) == 0)
+ {
+#if 0
+ SCM name;
+#endif
+ fputs_filtered ("#<latte ", stream);
+#if 1
+ fputs_filtered ("???", stream);
+#else
+ name = ((SCM n *) (STRUCT_TYPE (exp)))[struct_i_name];
+ scm_lfwrite (CHARS (name),
+ (sizet) sizeof (char),
+ (sizet) LENGTH (name),
+ port);
+#endif
+ fprintf_filtered (stream, " #X%s>", paddr_nz (svalue));
+ break;
+ }
+ case scm_tcs_cons_imcar:
+ case scm_tcs_cons_nimcar:
+ fputs_filtered ("(", stream);
+ scm_scmlist_print (svalue, stream, format,
+ deref_ref, recurse + 1, pretty);
+ fputs_filtered (")", stream);
+ break;
+ case scm_tcs_closures:
+ fputs_filtered ("#<CLOSURE ", stream);
+ scm_scmlist_print (SCM_CODE (svalue), stream, format,
+ deref_ref, recurse + 1, pretty);
+ fputs_filtered (">", stream);
+ break;
+ case scm_tc7_string:
+ {
+ int len = SCM_LENGTH (svalue);
+ CORE_ADDR addr = (CORE_ADDR) SCM_CDR (svalue);
+ int i;
+ int done = 0;
+ int buf_size;
+ char buffer[64];
+ int truncate = print_max && len > (int) print_max;
+ if (truncate)
+ len = print_max;
+ fputs_filtered ("\"", stream);
+ for (; done < len; done += buf_size)
+ {
+ buf_size = min (len - done, 64);
+ read_memory (addr + done, buffer, buf_size);
+
+ for (i = 0; i < buf_size; ++i)
+ switch (buffer[i])
+ {
+ case '\"':
+ case '\\':
+ fputs_filtered ("\\", stream);
+ default:
+ fprintf_filtered (stream, "%c", buffer[i]);
+ }
+ }
+ fputs_filtered (truncate ? "...\"" : "\"", stream);
+ break;
+ }
+ break;
+ case scm_tcs_symbols:
+ {
+ int len = SCM_LENGTH (svalue);
+
+ char *str = (char *) alloca (len);
+ read_memory (SCM_CDR (svalue), str, len + 1);
+ /* Should handle weird characters FIXME */
+ str[len] = '\0';
+ fputs_filtered (str, stream);
+ break;
+ }
+ case scm_tc7_vector:
+ {
+ int len = SCM_LENGTH (svalue);
+ int i;
+ LONGEST elements = SCM_CDR (svalue);
+ fputs_filtered ("#(", stream);
+ for (i = 0; i < len; ++i)
+ {
+ if (i > 0)
+ fputs_filtered (" ", stream);
+ scm_scmval_print (scm_get_field (elements, i), stream, format,
+ deref_ref, recurse + 1, pretty);
+ }
+ fputs_filtered (")", stream);
+ }
+ break;
+#if 0
+ case tc7_lvector:
+ {
+ SCM result;
+ SCM hook;
+ hook = scm_get_lvector_hook (exp, LV_PRINT_FN);
+ if (hook == BOOL_F)
+ {
+ scm_puts ("#<locked-vector ", port);
+ scm_intprint (CDR (exp), 16, port);
+ scm_puts (">", port);
+ }
+ else
+ {
+ result
+ = scm_apply (hook,
+ scm_listify (exp, port, (writing ? BOOL_T : BOOL_F),
+ SCM_UNDEFINED),
+ EOL);
+ if (result == BOOL_F)
+ goto punk;
+ }
+ break;
+ }
+ break;
+ case tc7_bvect:
+ case tc7_ivect:
+ case tc7_uvect:
+ case tc7_fvect:
+ case tc7_dvect:
+ case tc7_cvect:
+ scm_raprin1 (exp, port, writing);
+ break;
+#endif
+ case scm_tcs_subrs:
+ {
+ int index = SCM_CAR (svalue) >> 8;
+#if 1
+ char str[20];
+ sprintf (str, "#%d", index);
+#else
+ char *str = index ? SCM_CHARS (scm_heap_org + index) : "";
+#define SCM_CHARS(x) ((char *)(SCM_CDR(x)))
+ char *str = CHARS (SNAME (exp));
+#endif
+ fprintf_filtered (stream, "#<primitive-procedure %s>",
+ str);
+ }
+ break;
+#if 0
+#ifdef CCLO
+ case tc7_cclo:
+ scm_puts ("#<compiled-closure ", port);
+ scm_iprin1 (CCLO_SUBR (exp), port, writing);
+ scm_putc ('>', port);
+ break;
+#endif
+ case tc7_contin:
+ fprintf_filtered (stream, "#<continuation %d @ #X%lx >",
+ LENGTH (svalue),
+ (long) CHARS (svalue));
+ break;
+ case tc7_port:
+ i = PTOBNUM (exp);
+ if (i < scm_numptob && scm_ptobs[i].print && (scm_ptobs[i].print) (exp, port, writing))
+ break;
+ goto punk;
+ case tc7_smob:
+ i = SMOBNUM (exp);
+ if (i < scm_numsmob && scm_smobs[i].print
+ && (scm_smobs[i].print) (exp, port, writing))
+ break;
+ goto punk;
+#endif
+ default:
+#if 0
+ punk:
+#endif
+ scm_ipruk ("type", svalue, stream);
+ }
+ break;
+ }
+}
+
+int
+scm_val_print (struct type *type, char *valaddr, int embedded_offset,
+ CORE_ADDR address, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
+{
+ if (is_scmvalue_type (type))
+ {
+ LONGEST svalue = extract_signed_integer (valaddr, TYPE_LENGTH (type));
+ if (scm_inferior_print (svalue, stream, format,
+ deref_ref, recurse, pretty) >= 0)
+ {
+ }
+ else
+ {
+ scm_scmval_print (svalue, stream, format,
+ deref_ref, recurse, pretty);
+ }
+
+ gdb_flush (stream);
+ return (0);
+ }
+ else
+ {
+ return c_val_print (type, valaddr, 0, address, stream, format,
+ deref_ref, recurse, pretty);
+ }
+}
+
+int
+scm_value_print (struct value *val, struct ui_file *stream, int format,
+ enum val_prettyprint pretty)
+{
+ return (val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), 0,
+ VALUE_ADDRESS (val), stream, format, 1, 0, pretty));
+}
diff --git a/gdb/ser-e7kpc.c b/gdb/ser-e7kpc.c
new file mode 100644
index 00000000000..49b2c89c324
--- /dev/null
+++ b/gdb/ser-e7kpc.c
@@ -0,0 +1,438 @@
+/* Remote serial interface using Hitachi E7000 PC ISA card in a PC
+ Copyright 1994, 1996, 1997, 1998, 1999, 2000
+ 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. */
+
+#if defined __GO32__ || defined _WIN32
+#include "defs.h"
+#include "serial.h"
+#include "gdb_string.h"
+
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#ifdef __GO32__
+#include <sys/dos.h>
+#endif
+
+static int e7000pc_open (struct serial *scb, const char *name);
+static void e7000pc_raw (struct serial *scb);
+static int e7000pc_readchar (struct serial *scb, int timeout);
+static int e7000pc_setbaudrate (struct serial *scb, int rate);
+static int e7000pc_write (struct serial *scb, const char *str, int len);
+static void e7000pc_close (struct serial *scb);
+static serial_ttystate e7000pc_get_tty_state (struct serial *scb);
+static int e7000pc_set_tty_state (struct serial *scb, serial_ttystate state);
+
+#define OFF_DPD 0x0000
+#define OFF_DDP 0x1000
+#define OFF_CPD 0x2000
+#define OFF_CDP 0x2400
+#define OFF_FA 0x3000
+#define OFF_FB 0x3002
+#define OFF_FC 0x3004
+#define OFF_IRQTOD 0x3008
+#define OFF_IRQTOP 0x300a
+#define OFF_READY 0x300c
+#define OFF_PON 0x300e
+
+#define IDLE 0x0000
+#define CMD_CI 0x4349
+#define CMD_CO 0x434f
+#define CMD_LO 0x4c4f
+#define CMD_LS 0x4c53
+#define CMD_SV 0x5356
+#define CMD_SS 0x5353
+#define CMD_OK 0x4f4b
+#define CMD_ER 0x4552
+#define CMD_NF 0x4e46
+#define CMD_AB 0x4142
+#define CMD_ED 0x4544
+#define CMD_CE 0x4345
+
+static unsigned long fa;
+static unsigned long irqtod;
+static unsigned long ready;
+static unsigned long fb;
+static unsigned long cpd;
+static unsigned long cdp;
+static unsigned long ready;
+static unsigned long pon;
+static unsigned long irqtop;
+static unsigned long board_at;
+
+#ifdef __GO32__
+
+#define SET_BYTE(x,y) { char _buf = y;dosmemput(&_buf,1, x);}
+#define SET_WORD(x,y) { short _buf = y;dosmemput(&_buf,2, x);}
+#define GET_BYTE(x) ( dosmemget(x,1,&bb), bb)
+#define GET_WORD(x) ( dosmemget(x,2,&sb), sb)
+static unsigned char bb;
+static unsigned short sb;
+
+#else /* win32 */
+
+#define SET_BYTE(x,y) *(volatile unsigned char *)(x) = (y)
+#define SET_WORD(x,y) *(volatile unsigned short *)(x) = (y)
+#define GET_BYTE(x) (*(volatile unsigned char *)(x))
+#define GET_WORD(x) (*(volatile unsigned short *)(x))
+#define dosmemget(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN))
+#define dosmemput(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN))
+#endif
+
+static struct sw
+ {
+ int sw;
+ int addr;
+ }
+sigs[] =
+{
+ {
+ 0x14, 0xd0000
+ }
+ ,
+ {
+ 0x15, 0xd4000
+ }
+ ,
+ {
+ 0x16, 0xd8000
+ }
+ ,
+ {
+ 0x17, 0xdc000
+ }
+ ,
+ 0
+};
+
+#define get_ds_base() 0
+
+static int
+e7000pc_init (void)
+{
+ int try;
+ unsigned long dsbase;
+
+ dsbase = get_ds_base ();
+
+ /* Look around in memory for the board's signature */
+
+ for (try = 0; sigs[try].sw; try++)
+ {
+ int val;
+ board_at = sigs[try].addr - dsbase;
+ fa = board_at + OFF_FA;
+ fb = board_at + OFF_FB;
+ cpd = board_at + OFF_CPD;
+ cdp = board_at + OFF_CDP;
+ ready = board_at + OFF_READY;
+ pon = board_at + OFF_PON;
+ irqtop = board_at + OFF_IRQTOP;
+ irqtod = board_at + OFF_IRQTOD;
+
+ val = GET_WORD (ready);
+
+ if (val == (0xaaa0 | sigs[try].sw))
+ {
+ if (GET_WORD (pon) & 0xf)
+ {
+ SET_WORD (fa, 0);
+ SET_WORD (fb, 0);
+
+ SET_WORD (irqtop, 1); /* Disable interrupts from e7000 */
+ SET_WORD (ready, 1);
+ printf_filtered ("\nConnected to the E7000PC at address 0x%x\n",
+ sigs[try].addr);
+ return 1;
+ }
+ error ("The E7000 PC board is working, but the E7000 is turned off.\n");
+ return 0;
+ }
+ }
+
+ error ("GDB cannot connect to the E7000 PC board, check that it is installed\n\
+and that the switch settings are correct. Some other DOS programs can \n\
+stop the board from working. Try starting from a very minimal boot, \n\
+perhaps you need to disable EMM386 over the region where the board has\n\
+its I/O space, remove other unneeded cards, etc etc\n");
+ return 0;
+
+}
+
+static int pbuf_size;
+static int pbuf_index;
+
+/* Return next byte from cdp. If no more, then return -1. */
+
+static int
+e7000_get (void)
+{
+ static char pbuf[1000];
+ char tmp[1000];
+ int x;
+
+ if (pbuf_index < pbuf_size)
+ {
+ x = pbuf[pbuf_index++];
+ }
+ else if ((GET_WORD (fb) & 1))
+ {
+ int i;
+ pbuf_size = GET_WORD (cdp + 2);
+
+ dosmemget (cdp + 8, pbuf_size + 1, tmp);
+
+ /* Tell the E7000 we've eaten */
+ SET_WORD (fb, 0);
+ /* Swap it around */
+ for (i = 0; i < pbuf_size; i++)
+ {
+ pbuf[i] = tmp[i ^ 1];
+ }
+ pbuf_index = 0;
+ x = pbuf[pbuf_index++];
+ }
+ else
+ {
+ x = -1;
+ }
+ return x;
+}
+
+/* Works just like read(), except that it takes a TIMEOUT in seconds. Note
+ that TIMEOUT == 0 is a poll, and TIMEOUT == -1 means wait forever. */
+
+static int
+dosasync_read (int fd, char *buf, int len, int timeout)
+{
+ long now;
+ long then;
+ int i = 0;
+
+ /* Then look for some more if we're still hungry */
+ time (&now);
+ then = now + timeout;
+ while (i < len)
+ {
+ int ch = e7000_get ();
+
+ /* While there's room in the buffer, and we've already
+ read the stuff in, suck it over */
+ if (ch != -1)
+ {
+ buf[i++] = ch;
+ while (i < len && pbuf_index < pbuf_size)
+ {
+ ch = e7000_get ();
+ if (ch == -1)
+ break;
+ buf[i++] = ch;
+ }
+ }
+
+ time (&now);
+
+ if (timeout == 0)
+ return i;
+ if (now >= then && timeout > 0)
+ {
+ return i;
+ }
+ }
+ return len;
+}
+
+
+static int
+dosasync_write (int fd, const char *buf, int len)
+{
+ int i;
+ char dummy[1000];
+
+ /* Construct copy locally */
+ ((short *) dummy)[0] = CMD_CI;
+ ((short *) dummy)[1] = len;
+ ((short *) dummy)[2] = 0;
+ ((short *) dummy)[3] = 0;
+ for (i = 0; i < len; i++)
+ {
+ dummy[(8 + i) ^ 1] = buf[i];
+ }
+
+ /* Wait for the card to get ready */
+ while (GET_WORD (fa) & 1);
+
+ /* Blast onto the ISA card */
+ dosmemput (dummy, 8 + len + 1, cpd);
+
+ SET_WORD (fa, 1);
+ SET_WORD (irqtod, 1); /* Interrupt the E7000 */
+
+ return len;
+}
+
+static int
+e7000pc_open (struct serial *scb, const char *name)
+{
+ if (strncasecmp (name, "pc", 2) != 0)
+ {
+ errno = ENOENT;
+ return -1;
+ }
+
+ scb->fd = e7000pc_init ();
+
+ if (!scb->fd)
+ return -1;
+
+ return 0;
+}
+
+static int
+e7000pc_noop (struct serial *scb)
+{
+ return 0;
+}
+
+static void
+e7000pc_raw (struct serial *scb)
+{
+ /* Always in raw mode */
+}
+
+static int
+e7000pc_readchar (struct serial *scb, int timeout)
+{
+ char buf;
+
+top:
+
+ if (dosasync_read (scb->fd, &buf, 1, timeout))
+ {
+ if (buf == 0)
+ goto top;
+ return buf;
+ }
+ else
+ return SERIAL_TIMEOUT;
+}
+
+struct e7000pc_ttystate
+{
+ int dummy;
+};
+
+/* e7000pc_{get set}_tty_state() are both dummys to fill out the function
+ vector. Someday, they may do something real... */
+
+static serial_ttystate
+e7000pc_get_tty_state (struct serial *scb)
+{
+ struct e7000pc_ttystate *state;
+
+ state = (struct e7000pc_ttystate *) xmalloc (sizeof *state);
+
+ return (serial_ttystate) state;
+}
+
+static int
+e7000pc_set_tty_state (struct serial *scb, serial_ttystate ttystate)
+{
+ return 0;
+}
+
+static int
+e7000pc_noflush_set_tty_state (struct serial *scb,
+ serial_ttystate new_ttystate,
+ serial_ttystate old_ttystate)
+{
+ return 0;
+}
+
+static void
+e7000pc_print_tty_state (struct serial *scb,
+ serial_ttystate ttystate,
+ struct ui_file *stream)
+{
+ /* Nothing to print. */
+ return;
+}
+
+static int
+e7000pc_setbaudrate (struct serial *scb, int rate)
+{
+ return 0;
+}
+
+static int
+e7000pc_setstopbits (struct serial *scb, int rate)
+{
+ return 0;
+}
+
+static int
+e7000pc_write (struct serial *scb, const char *str, int len)
+{
+ dosasync_write (scb->fd, str, len);
+
+ return 0;
+}
+
+static void
+e7000pc_close (struct serial *scb)
+{
+}
+
+static struct serial_ops e7000pc_ops =
+{
+ "pc",
+ 0,
+ e7000pc_open,
+ e7000pc_close,
+ e7000pc_readchar,
+ e7000pc_write,
+ e7000pc_noop, /* flush output */
+ e7000pc_noop, /* flush input */
+ e7000pc_noop, /* send break -- currently used only for nindy */
+ e7000pc_raw,
+ e7000pc_get_tty_state,
+ e7000pc_set_tty_state,
+ e7000pc_print_tty_state,
+ e7000pc_noflush_set_tty_state,
+ e7000pc_setbaudrate,
+ e7000pc_setstopbits,
+ e7000pc_noop, /* wait for output to drain */
+};
+
+void
+_initialize_ser_e7000pc (void)
+{
+ serial_add_interface (&e7000pc_ops);
+}
+#else
+
+void
+_initialize_ser_e7000pc (void)
+{
+
+}
+#endif
diff --git a/gdb/ser-go32.c b/gdb/ser-go32.c
new file mode 100644
index 00000000000..0642b5aa4bd
--- /dev/null
+++ b/gdb/ser-go32.c
@@ -0,0 +1,964 @@
+/* Remote serial interface for local (hardwired) serial ports for GO32.
+ Copyright 1992, 1993, 2000, 2001 Free Software Foundation, Inc.
+
+ Contributed by Nigel Stephens, Algorithmics Ltd. (nigel@algor.co.uk).
+
+ This version uses DPMI interrupts to handle buffered i/o
+ without the separate "asynctsr" program.
+
+ 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 "defs.h"
+#include "gdbcmd.h"
+#include "serial.h"
+#include "gdb_string.h"
+
+
+/*
+ * NS16550 UART registers
+ */
+
+#define COM1ADDR 0x3f8
+#define COM2ADDR 0x2f8
+#define COM3ADDR 0x3e8
+#define COM4ADDR 0x3e0
+
+#define com_data 0 /* data register (R/W) */
+#define com_dlbl 0 /* divisor latch low (W) */
+#define com_ier 1 /* interrupt enable (W) */
+#define com_dlbh 1 /* divisor latch high (W) */
+#define com_iir 2 /* interrupt identification (R) */
+#define com_fifo 2 /* FIFO control (W) */
+#define com_lctl 3 /* line control register (R/W) */
+#define com_cfcr 3 /* line control register (R/W) */
+#define com_mcr 4 /* modem control register (R/W) */
+#define com_lsr 5 /* line status register (R/W) */
+#define com_msr 6 /* modem status register (R/W) */
+
+/*
+ * Constants for computing 16 bit baud rate divisor (lower byte
+ * in com_dlbl, upper in com_dlbh) from 1.8432MHz crystal. Divisor is
+ * 1.8432 MHz / (16 * X) for X bps. If the baud rate can't be set
+ * to within +- (desired_rate*SPEED_TOLERANCE/1000) bps, we fail.
+ */
+#define COMTICK (1843200/16)
+#define SPEED_TOLERANCE 30 /* thousandths; real == desired +- 3.0% */
+
+/* interrupt enable register */
+#define IER_ERXRDY 0x1 /* int on rx ready */
+#define IER_ETXRDY 0x2 /* int on tx ready */
+#define IER_ERLS 0x4 /* int on line status change */
+#define IER_EMSC 0x8 /* int on modem status change */
+
+/* interrupt identification register */
+#define IIR_FIFO_MASK 0xc0 /* set if FIFOs are enabled */
+#define IIR_IMASK 0xf /* interrupt cause mask */
+#define IIR_NOPEND 0x1 /* nothing pending */
+#define IIR_RLS 0x6 /* receive line status */
+#define IIR_RXRDY 0x4 /* receive ready */
+#define IIR_RXTOUT 0xc /* receive timeout */
+#define IIR_TXRDY 0x2 /* transmit ready */
+#define IIR_MLSC 0x0 /* modem status */
+
+
+/* fifo control register */
+#define FIFO_ENABLE 0x01 /* enable fifo */
+#define FIFO_RCV_RST 0x02 /* reset receive fifo */
+#define FIFO_XMT_RST 0x04 /* reset transmit fifo */
+#define FIFO_DMA_MODE 0x08 /* enable dma mode */
+#define FIFO_TRIGGER_1 0x00 /* trigger at 1 char */
+#define FIFO_TRIGGER_4 0x40 /* trigger at 4 chars */
+#define FIFO_TRIGGER_8 0x80 /* trigger at 8 chars */
+#define FIFO_TRIGGER_14 0xc0 /* trigger at 14 chars */
+
+/* character format control register */
+#define CFCR_DLAB 0x80 /* divisor latch */
+#define CFCR_SBREAK 0x40 /* send break */
+#define CFCR_PZERO 0x30 /* zero parity */
+#define CFCR_PONE 0x20 /* one parity */
+#define CFCR_PEVEN 0x10 /* even parity */
+#define CFCR_PODD 0x00 /* odd parity */
+#define CFCR_PENAB 0x08 /* parity enable */
+#define CFCR_STOPB 0x04 /* 2 stop bits */
+#define CFCR_8BITS 0x03 /* 8 data bits */
+#define CFCR_7BITS 0x02 /* 7 data bits */
+#define CFCR_6BITS 0x01 /* 6 data bits */
+#define CFCR_5BITS 0x00 /* 5 data bits */
+
+/* modem control register */
+#define MCR_LOOPBACK 0x10 /* loopback */
+#define MCR_IENABLE 0x08 /* output 2 = int enable */
+#define MCR_DRS 0x04 /* output 1 = xxx */
+#define MCR_RTS 0x02 /* enable RTS */
+#define MCR_DTR 0x01 /* enable DTR */
+
+/* line status register */
+#define LSR_RCV_FIFO 0x80 /* error in receive fifo */
+#define LSR_TSRE 0x40 /* transmitter empty */
+#define LSR_TXRDY 0x20 /* transmitter ready */
+#define LSR_BI 0x10 /* break detected */
+#define LSR_FE 0x08 /* framing error */
+#define LSR_PE 0x04 /* parity error */
+#define LSR_OE 0x02 /* overrun error */
+#define LSR_RXRDY 0x01 /* receiver ready */
+#define LSR_RCV_MASK 0x1f
+
+/* modem status register */
+#define MSR_DCD 0x80
+#define MSR_RI 0x40
+#define MSR_DSR 0x20
+#define MSR_CTS 0x10
+#define MSR_DDCD 0x08
+#define MSR_TERI 0x04
+#define MSR_DDSR 0x02
+#define MSR_DCTS 0x01
+
+#include <time.h>
+#include <dos.h>
+#include <go32.h>
+#include <dpmi.h>
+typedef unsigned long u_long;
+
+/* 16550 rx fifo trigger point */
+#define FIFO_TRIGGER FIFO_TRIGGER_4
+
+/* input buffer size */
+#define CBSIZE 4096
+
+#define RAWHZ 18
+
+#ifdef DOS_STATS
+#define CNT_RX 16
+#define CNT_TX 17
+#define CNT_STRAY 18
+#define CNT_ORUN 19
+#define NCNT 20
+
+static int intrcnt;
+static int cnts[NCNT];
+static char *cntnames[NCNT] =
+{
+ /* h/w interrupt counts. */
+ "mlsc", "nopend", "txrdy", "?3",
+ "rxrdy", "?5", "rls", "?7",
+ "?8", "?9", "?a", "?b",
+ "rxtout", "?d", "?e", "?f",
+ /* s/w counts. */
+ "rxcnt", "txcnt", "stray", "swoflo"
+};
+
+#define COUNT(x) cnts[x]++
+#else
+#define COUNT(x)
+#endif
+
+/* Main interrupt controller port addresses. */
+#define ICU_BASE 0x20
+#define ICU_OCW2 (ICU_BASE + 0)
+#define ICU_MASK (ICU_BASE + 1)
+
+/* Original interrupt controller mask register. */
+unsigned char icu_oldmask;
+
+/* Maximum of 8 interrupts (we don't handle the slave icu yet). */
+#define NINTR 8
+
+static struct intrupt
+ {
+ char inuse;
+ struct dos_ttystate *port;
+ _go32_dpmi_seginfo old_rmhandler;
+ _go32_dpmi_seginfo old_pmhandler;
+ _go32_dpmi_seginfo new_rmhandler;
+ _go32_dpmi_seginfo new_pmhandler;
+ _go32_dpmi_registers regs;
+ }
+intrupts[NINTR];
+
+
+static struct dos_ttystate
+ {
+ int base;
+ int irq;
+ int refcnt;
+ struct intrupt *intrupt;
+ int fifo;
+ int baudrate;
+ unsigned char cbuf[CBSIZE];
+ unsigned int first;
+ unsigned int count;
+ int txbusy;
+ unsigned char old_mcr;
+ int ferr;
+ int perr;
+ int oflo;
+ int msr;
+ }
+ports[4] =
+{
+ {
+ COM1ADDR, 4, 0, NULL, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, 0
+ }
+ ,
+ {
+ COM2ADDR, 3, 0, NULL, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, 0
+ }
+ ,
+ {
+ COM3ADDR, 4, 0, NULL, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, 0
+ }
+ ,
+ {
+ COM4ADDR, 3, 0, NULL, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, 0
+ }
+};
+
+static int dos_open (struct serial *scb, const char *name);
+static void dos_raw (struct serial *scb);
+static int dos_readchar (struct serial *scb, int timeout);
+static int dos_setbaudrate (struct serial *scb, int rate);
+static int dos_write (struct serial *scb, const char *str, int len);
+static void dos_close (struct serial *scb);
+static serial_ttystate dos_get_tty_state (struct serial *scb);
+static int dos_set_tty_state (struct serial *scb, serial_ttystate state);
+static int dos_baudconv (int rate);
+
+#define inb(p,a) inportb((p)->base + (a))
+#define outb(p,a,v) outportb((p)->base + (a), (v))
+#define disable() asm volatile ("cli");
+#define enable() asm volatile ("sti");
+
+
+static int
+dos_getc (volatile struct dos_ttystate *port)
+{
+ int c;
+
+ if (port->count == 0)
+ return -1;
+
+ c = port->cbuf[port->first];
+ disable ();
+ port->first = (port->first + 1) & (CBSIZE - 1);
+ port->count--;
+ enable ();
+ return c;
+}
+
+
+static int
+dos_putc (int c, struct dos_ttystate *port)
+{
+ if (port->count >= CBSIZE - 1)
+ return -1;
+ port->cbuf[(port->first + port->count) & (CBSIZE - 1)] = c;
+ port->count++;
+ return 0;
+}
+
+
+
+static void
+dos_comisr (int irq)
+{
+ struct dos_ttystate *port;
+ unsigned char iir, lsr, c;
+
+ disable (); /* Paranoia */
+ outportb (ICU_OCW2, 0x20); /* End-Of-Interrupt */
+#ifdef DOS_STATS
+ ++intrcnt;
+#endif
+
+ port = intrupts[irq].port;
+ if (!port)
+ {
+ COUNT (CNT_STRAY);
+ return; /* not open */
+ }
+
+ while (1)
+ {
+ iir = inb (port, com_iir) & IIR_IMASK;
+ switch (iir)
+ {
+
+ case IIR_RLS:
+ lsr = inb (port, com_lsr);
+ goto rx;
+
+ case IIR_RXTOUT:
+ case IIR_RXRDY:
+ lsr = 0;
+
+ rx:
+ do
+ {
+ c = inb (port, com_data);
+ if (lsr & (LSR_BI | LSR_FE | LSR_PE | LSR_OE))
+ {
+ if (lsr & (LSR_BI | LSR_FE))
+ port->ferr++;
+ else if (lsr & LSR_PE)
+ port->perr++;
+ if (lsr & LSR_OE)
+ port->oflo++;
+ }
+
+ if (dos_putc (c, port) < 0)
+ {
+ COUNT (CNT_ORUN);
+ }
+ else
+ {
+ COUNT (CNT_RX);
+ }
+ }
+ while ((lsr = inb (port, com_lsr)) & LSR_RXRDY);
+ break;
+
+ case IIR_MLSC:
+ /* could be used to flowcontrol Tx */
+ port->msr = inb (port, com_msr);
+ break;
+
+ case IIR_TXRDY:
+ port->txbusy = 0;
+ break;
+
+ case IIR_NOPEND:
+ /* no more pending interrupts, all done */
+ return;
+
+ default:
+ /* unexpected interrupt, ignore */
+ break;
+ }
+ COUNT (iir);
+ }
+}
+
+#define ISRNAME(x) dos_comisr##x
+#define ISR(x) static void ISRNAME(x)(void) {dos_comisr(x);}
+
+ISR (0) ISR (1) ISR (2) ISR (3)
+ISR (4) ISR (5) ISR (6) ISR (7)
+
+typedef void (*isr_t) (void);
+
+static isr_t isrs[NINTR] =
+ {
+ ISRNAME (0), ISRNAME (1), ISRNAME (2), ISRNAME (3),
+ ISRNAME (4), ISRNAME (5), ISRNAME (6), ISRNAME (7)
+ };
+
+
+
+static struct intrupt *
+dos_hookirq (unsigned int irq)
+{
+ struct intrupt *intr;
+ unsigned int vec;
+ isr_t isr;
+
+ if (irq >= NINTR)
+ return 0;
+
+ intr = &intrupts[irq];
+ if (intr->inuse)
+ return 0;
+
+ vec = 0x08 + irq;
+ isr = isrs[irq];
+
+ /* setup real mode handler */
+ _go32_dpmi_get_real_mode_interrupt_vector (vec, &intr->old_rmhandler);
+
+ intr->new_rmhandler.pm_selector = _go32_my_cs ();
+ intr->new_rmhandler.pm_offset = (u_long) isr;
+ if (_go32_dpmi_allocate_real_mode_callback_iret (&intr->new_rmhandler,
+ &intr->regs))
+ {
+ return 0;
+ }
+
+ if (_go32_dpmi_set_real_mode_interrupt_vector (vec, &intr->new_rmhandler))
+ {
+ return 0;
+ }
+
+ /* setup protected mode handler */
+ _go32_dpmi_get_protected_mode_interrupt_vector (vec, &intr->old_pmhandler);
+
+ intr->new_pmhandler.pm_selector = _go32_my_cs ();
+ intr->new_pmhandler.pm_offset = (u_long) isr;
+ _go32_dpmi_allocate_iret_wrapper (&intr->new_pmhandler);
+
+ if (_go32_dpmi_set_protected_mode_interrupt_vector (vec,
+ &intr->new_pmhandler))
+ {
+ return 0;
+ }
+
+ /* setup interrupt controller mask */
+ disable ();
+ outportb (ICU_MASK, inportb (ICU_MASK) & ~(1 << irq));
+ enable ();
+
+ intr->inuse = 1;
+ return intr;
+}
+
+
+static void
+dos_unhookirq (struct intrupt *intr)
+{
+ unsigned int irq, vec;
+ unsigned char mask;
+
+ irq = intr - intrupts;
+ vec = 0x08 + irq;
+
+ /* restore old interrupt mask bit */
+ mask = 1 << irq;
+ disable ();
+ outportb (ICU_MASK, inportb (ICU_MASK) | (mask & icu_oldmask));
+ enable ();
+
+ /* remove real mode handler */
+ _go32_dpmi_set_real_mode_interrupt_vector (vec, &intr->old_rmhandler);
+ _go32_dpmi_free_real_mode_callback (&intr->new_rmhandler);
+
+ /* remove protected mode handler */
+ _go32_dpmi_set_protected_mode_interrupt_vector (vec, &intr->old_pmhandler);
+ _go32_dpmi_free_iret_wrapper (&intr->new_pmhandler);
+ intr->inuse = 0;
+}
+
+
+
+static int
+dos_open (struct serial *scb, const char *name)
+{
+ struct dos_ttystate *port;
+ int fd, i;
+
+ if (strncasecmp (name, "/dev/", 5) == 0)
+ name += 5;
+ else if (strncasecmp (name, "\\dev\\", 5) == 0)
+ name += 5;
+
+ if (strlen (name) != 4 || strncasecmp (name, "com", 3) != 0)
+ {
+ errno = ENOENT;
+ return -1;
+ }
+
+ if (name[3] < '1' || name[3] > '4')
+ {
+ errno = ENOENT;
+ return -1;
+ }
+
+ /* FIXME: this is a Bad Idea (tm)! One should *never* invent file
+ handles, since they might be already used by other files/devices.
+ The Right Way to do this is to create a real handle by dup()'ing
+ some existing one. */
+ fd = name[3] - '1';
+ port = &ports[fd];
+ if (port->refcnt++ > 0)
+ {
+ /* Device already opened another user. Just point at it. */
+ scb->fd = fd;
+ return 0;
+ }
+
+ /* force access to ID reg */
+ outb (port, com_cfcr, 0);
+ outb (port, com_iir, 0);
+ for (i = 0; i < 17; i++)
+ {
+ if ((inb (port, com_iir) & 0x38) == 0)
+ goto ok;
+ (void) inb (port, com_data); /* clear recv */
+ }
+ errno = ENODEV;
+ return -1;
+
+ok:
+ /* disable all interrupts in chip */
+ outb (port, com_ier, 0);
+
+ /* tentatively enable 16550 fifo, and see if it responds */
+ outb (port, com_fifo,
+ FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER);
+ sleep (1);
+ port->fifo = ((inb (port, com_iir) & IIR_FIFO_MASK) == IIR_FIFO_MASK);
+
+ /* clear pending status reports. */
+ (void) inb (port, com_lsr);
+ (void) inb (port, com_msr);
+
+ /* enable external interrupt gate (to avoid floating IRQ) */
+ outb (port, com_mcr, MCR_IENABLE);
+
+ /* hook up interrupt handler and initialise icu */
+ port->intrupt = dos_hookirq (port->irq);
+ if (!port->intrupt)
+ {
+ outb (port, com_mcr, 0);
+ outb (port, com_fifo, 0);
+ errno = ENODEV;
+ return -1;
+ }
+
+ disable ();
+
+ /* record port */
+ port->intrupt->port = port;
+ scb->fd = fd;
+
+ /* clear rx buffer, tx busy flag and overflow count */
+ port->first = port->count = 0;
+ port->txbusy = 0;
+ port->oflo = 0;
+
+ /* set default baud rate and mode: 9600,8,n,1 */
+ i = dos_baudconv (port->baudrate = 9600);
+ outb (port, com_cfcr, CFCR_DLAB);
+ outb (port, com_dlbl, i & 0xff);
+ outb (port, com_dlbh, i >> 8);
+ outb (port, com_cfcr, CFCR_8BITS);
+
+ /* enable all interrupts */
+ outb (port, com_ier, IER_ETXRDY | IER_ERXRDY | IER_ERLS | IER_EMSC);
+
+ /* enable DTR & RTS */
+ outb (port, com_mcr, MCR_DTR | MCR_RTS | MCR_IENABLE);
+
+ enable ();
+
+ return 0;
+}
+
+
+static void
+dos_close (struct serial *scb)
+{
+ struct dos_ttystate *port;
+ struct intrupt *intrupt;
+
+ if (!scb)
+ return;
+
+ port = &ports[scb->fd];
+
+ if (port->refcnt-- > 1)
+ return;
+
+ if (!(intrupt = port->intrupt))
+ return;
+
+ /* disable interrupts, fifo, flow control */
+ disable ();
+ port->intrupt = 0;
+ intrupt->port = 0;
+ outb (port, com_fifo, 0);
+ outb (port, com_ier, 0);
+ enable ();
+
+ /* unhook handler, and disable interrupt gate */
+ dos_unhookirq (intrupt);
+ outb (port, com_mcr, 0);
+
+ /* Check for overflow errors */
+ if (port->oflo)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "Serial input overruns occurred.\n");
+ fprintf_unfiltered (gdb_stderr, "This system %s handle %d baud.\n",
+ port->fifo ? "cannot" : "needs a 16550 to",
+ port->baudrate);
+ }
+}
+
+
+
+static int
+dos_noop (struct serial *scb)
+{
+ return 0;
+}
+
+static void
+dos_raw (struct serial *scb)
+{
+ /* Always in raw mode */
+}
+
+static int
+dos_readchar (struct serial *scb, int timeout)
+{
+ struct dos_ttystate *port = &ports[scb->fd];
+ long then;
+ int c;
+
+ then = rawclock () + (timeout * RAWHZ);
+ while ((c = dos_getc (port)) < 0)
+ {
+ if (timeout >= 0 && (rawclock () - then) >= 0)
+ return SERIAL_TIMEOUT;
+ }
+
+ return c;
+}
+
+
+static serial_ttystate
+dos_get_tty_state (struct serial *scb)
+{
+ struct dos_ttystate *port = &ports[scb->fd];
+ struct dos_ttystate *state;
+
+ /* Are they asking about a port we opened? */
+ if (port->refcnt <= 0)
+ {
+ /* We've never heard about this port. We should fail this call,
+ unless they are asking about one of the 3 standard handles,
+ in which case we pretend the handle was open by us if it is
+ connected to a terminal device. This is beacuse Unix
+ terminals use the serial interface, so GDB expects the
+ standard handles to go through here. */
+ if (scb->fd >= 3 || !isatty (scb->fd))
+ return NULL;
+ }
+
+ state = (struct dos_ttystate *) xmalloc (sizeof *state);
+ *state = *port;
+ return (serial_ttystate) state;
+}
+
+static int
+dos_set_tty_state (struct serial *scb, serial_ttystate ttystate)
+{
+ struct dos_ttystate *state;
+
+ state = (struct dos_ttystate *) ttystate;
+ dos_setbaudrate (scb, state->baudrate);
+ return 0;
+}
+
+static int
+dos_noflush_set_tty_state (struct serial *scb, serial_ttystate new_ttystate,
+ serial_ttystate old_ttystate)
+{
+ struct dos_ttystate *state;
+
+ state = (struct dos_ttystate *) new_ttystate;
+ dos_setbaudrate (scb, state->baudrate);
+ return 0;
+}
+
+static int
+dos_flush_input (struct serial *scb)
+{
+ struct dos_ttystate *port = &ports[scb->fd];
+ disable ();
+ port->first = port->count = 0;
+ if (port->fifo)
+ outb (port, com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_TRIGGER);
+ enable ();
+ return 0;
+}
+
+static void
+dos_print_tty_state (struct serial *scb, serial_ttystate ttystate,
+ struct ui_file *stream)
+{
+ /* Nothing to print */
+ return;
+}
+
+static int
+dos_baudconv (int rate)
+{
+ long x, err;
+
+ if (rate <= 0)
+ return -1;
+
+#define divrnd(n, q) (((n) * 2 / (q) + 1) / 2) /* divide and round off */
+ x = divrnd (COMTICK, rate);
+ if (x <= 0)
+ return -1;
+
+ err = divrnd (1000 * COMTICK, x * rate) - 1000;
+ if (err < 0)
+ err = -err;
+ if (err > SPEED_TOLERANCE)
+ return -1;
+#undef divrnd
+ return x;
+}
+
+
+static int
+dos_setbaudrate (struct serial *scb, int rate)
+{
+ struct dos_ttystate *port = &ports[scb->fd];
+
+ if (port->baudrate != rate)
+ {
+ int x;
+ unsigned char cfcr;
+
+ x = dos_baudconv (rate);
+ if (x <= 0)
+ {
+ fprintf_unfiltered (gdb_stderr, "%d: impossible baudrate\n", rate);
+ errno = EINVAL;
+ return -1;
+ }
+
+ disable ();
+ cfcr = inb (port, com_cfcr);
+
+ outb (port, com_cfcr, CFCR_DLAB);
+ outb (port, com_dlbl, x & 0xff);
+ outb (port, com_dlbh, x >> 8);
+ outb (port, com_cfcr, cfcr);
+ port->baudrate = rate;
+ enable ();
+ }
+
+ return 0;
+}
+
+static int
+dos_setstopbits (struct serial *scb, int num)
+{
+ struct dos_ttystate *port = &ports[scb->fd];
+ unsigned char cfcr;
+
+ disable ();
+ cfcr = inb (port, com_cfcr);
+
+ switch (num)
+ {
+ case SERIAL_1_STOPBITS:
+ outb (port, com_cfcr, cfcr & ~CFCR_STOPB);
+ break;
+ case SERIAL_1_AND_A_HALF_STOPBITS:
+ case SERIAL_2_STOPBITS:
+ outb (port, com_cfcr, cfcr | CFCR_STOPB);
+ break;
+ default:
+ enable ();
+ return 1;
+ }
+ enable ();
+
+ return 0;
+}
+
+static int
+dos_write (struct serial *scb, const char *str, int len)
+{
+ volatile struct dos_ttystate *port = &ports[scb->fd];
+ int fifosize = port->fifo ? 16 : 1;
+ long then;
+ int cnt;
+
+ while (len > 0)
+ {
+ /* send the data, fifosize bytes at a time */
+ cnt = fifosize > len ? len : fifosize;
+ port->txbusy = 1;
+ /* Francisco Pastor <fpastor.etra-id@etra.es> says OUTSB messes
+ up the communications with UARTs with FIFOs. */
+#ifdef UART_FIFO_WORKS
+ outportsb (port->base + com_data, str, cnt);
+ str += cnt;
+ len -= cnt;
+#else
+ for ( ; cnt > 0; cnt--, len--)
+ outportb (port->base + com_data, *str++);
+#endif
+#ifdef DOS_STATS
+ cnts[CNT_TX] += cnt;
+#endif
+ /* wait for transmission to complete (max 1 sec) */
+ then = rawclock () + RAWHZ;
+ while (port->txbusy)
+ {
+ if ((rawclock () - then) >= 0)
+ {
+ errno = EIO;
+ return SERIAL_ERROR;
+ }
+ }
+ }
+ return 0;
+}
+
+
+static int
+dos_sendbreak (struct serial *scb)
+{
+ volatile struct dos_ttystate *port = &ports[scb->fd];
+ unsigned char cfcr;
+ long then;
+
+ cfcr = inb (port, com_cfcr);
+ outb (port, com_cfcr, cfcr | CFCR_SBREAK);
+
+ /* 0.25 sec delay */
+ then = rawclock () + RAWHZ / 4;
+ while ((rawclock () - then) < 0)
+ continue;
+
+ outb (port, com_cfcr, cfcr);
+ return 0;
+}
+
+
+static struct serial_ops dos_ops =
+{
+ "hardwire",
+ 0,
+ dos_open,
+ dos_close,
+ dos_readchar,
+ dos_write,
+ dos_noop, /* flush output */
+ dos_flush_input,
+ dos_sendbreak,
+ dos_raw,
+ dos_get_tty_state,
+ dos_set_tty_state,
+ dos_print_tty_state,
+ dos_noflush_set_tty_state,
+ dos_setbaudrate,
+ dos_setstopbits,
+ dos_noop, /* wait for output to drain */
+ (void (*)(struct serial *, int))NULL /* change into async mode */
+};
+
+
+static void
+dos_info (char *arg, int from_tty)
+{
+ struct dos_ttystate *port;
+#ifdef DOS_STATS
+ int i;
+#endif
+
+ for (port = ports; port < &ports[4]; port++)
+ {
+ if (port->baudrate == 0)
+ continue;
+ printf_filtered ("Port:\tCOM%ld (%sactive)\n", (long)(port - ports) + 1,
+ port->intrupt ? "" : "not ");
+ printf_filtered ("Addr:\t0x%03x (irq %d)\n", port->base, port->irq);
+ printf_filtered ("16550:\t%s\n", port->fifo ? "yes" : "no");
+ printf_filtered ("Speed:\t%d baud\n", port->baudrate);
+ printf_filtered ("Errs:\tframing %d parity %d overflow %d\n\n",
+ port->ferr, port->perr, port->oflo);
+ }
+
+#ifdef DOS_STATS
+ printf_filtered ("\nTotal interrupts: %d\n", intrcnt);
+ for (i = 0; i < NCNT; i++)
+ if (cnts[i])
+ printf_filtered ("%s:\t%d\n", cntnames[i], cnts[i]);
+#endif
+}
+
+
+void
+_initialize_ser_dos (void)
+{
+ serial_add_interface (&dos_ops);
+
+ /* Save original interrupt mask register. */
+ icu_oldmask = inportb (ICU_MASK);
+
+ /* Mark fixed motherboard irqs as inuse. */
+ intrupts[0].inuse = /* timer tick */
+ intrupts[1].inuse = /* keyboard */
+ intrupts[2].inuse = 1; /* slave icu */
+
+ add_show_from_set (
+ add_set_cmd ("com1base", class_obscure, var_zinteger,
+ (char *) &ports[0].base,
+ "Set COM1 base i/o port address.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("com1irq", class_obscure, var_zinteger,
+ (char *) &ports[0].irq,
+ "Set COM1 interrupt request.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("com2base", class_obscure, var_zinteger,
+ (char *) &ports[1].base,
+ "Set COM2 base i/o port address.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("com2irq", class_obscure, var_zinteger,
+ (char *) &ports[1].irq,
+ "Set COM2 interrupt request.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("com3base", class_obscure, var_zinteger,
+ (char *) &ports[2].base,
+ "Set COM3 base i/o port address.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("com3irq", class_obscure, var_zinteger,
+ (char *) &ports[2].irq,
+ "Set COM3 interrupt request.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("com4base", class_obscure, var_zinteger,
+ (char *) &ports[3].base,
+ "Set COM4 base i/o port address.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("com4irq", class_obscure, var_zinteger,
+ (char *) &ports[3].irq,
+ "Set COM4 interrupt request.",
+ &setlist),
+ &showlist);
+
+ add_info ("serial", dos_info,
+ "Print DOS serial port status.");
+}
diff --git a/gdb/ser-pipe.c b/gdb/ser-pipe.c
new file mode 100644
index 00000000000..bca0e54e4ba
--- /dev/null
+++ b/gdb/ser-pipe.c
@@ -0,0 +1,161 @@
+/* Serial interface for a pipe to a separate program
+ Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Solutions.
+
+ 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 "defs.h"
+#include "serial.h"
+#include "ser-unix.h"
+
+#include "gdb_vfork.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include "gdb_string.h"
+
+#include <signal.h>
+
+static int pipe_open (struct serial *scb, const char *name);
+static void pipe_close (struct serial *scb);
+
+extern void _initialize_ser_pipe (void);
+
+struct pipe_state
+ {
+ int pid;
+ };
+
+/* Open up a raw pipe */
+
+static int
+pipe_open (struct serial *scb, const char *name)
+{
+#if !HAVE_SOCKETPAIR
+ return -1;
+#else
+ struct pipe_state *state;
+ /* This chunk: */
+ /* Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software written by Ken Arnold and
+ * published in UNIX Review, Vol. 6, No. 8.
+ */
+ int pdes[2];
+ int pid;
+ if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
+ return -1;
+
+ /* Create the child process to run the command in. Note that the
+ apparent call to vfork() below *might* actually be a call to
+ fork() due to the fact that autoconf will ``#define vfork fork''
+ on certain platforms. */
+ pid = vfork ();
+
+ /* Error. */
+ if (pid == -1)
+ {
+ close (pdes[0]);
+ close (pdes[1]);
+ return -1;
+ }
+
+ /* Child. */
+ if (pid == 0)
+ {
+ /* re-wire pdes[1] to stdin/stdout */
+ close (pdes[0]);
+ if (pdes[1] != STDOUT_FILENO)
+ {
+ dup2 (pdes[1], STDOUT_FILENO);
+ close (pdes[1]);
+ }
+ dup2 (STDOUT_FILENO, STDIN_FILENO);
+#if 0
+ /* close any stray FD's - FIXME - how? */
+ /* POSIX.2 B.3.2.2 "popen() shall ensure that any streams
+ from previous popen() calls that remain open in the
+ parent process are closed in the new child process. */
+ for (old = pidlist; old; old = old->next)
+ close (fileno (old->fp)); /* don't allow a flush */
+#endif
+ execl ("/bin/sh", "sh", "-c", name, NULL);
+ _exit (127);
+ }
+
+ /* Parent. */
+ close (pdes[1]);
+ /* :end chunk */
+ state = XMALLOC (struct pipe_state);
+ state->pid = pid;
+ scb->fd = pdes[0];
+ scb->state = state;
+
+ /* If we don't do this, GDB simply exits when the remote side dies. */
+ signal (SIGPIPE, SIG_IGN);
+ return 0;
+#endif
+}
+
+static void
+pipe_close (struct serial *scb)
+{
+ struct pipe_state *state = scb->state;
+ if (state != NULL)
+ {
+ int pid = state->pid;
+ close (scb->fd);
+ scb->fd = -1;
+ xfree (state);
+ scb->state = NULL;
+ kill (pid, SIGTERM);
+ /* Might be useful to check that the child does die. */
+ }
+}
+
+static struct serial_ops pipe_ops;
+
+void
+_initialize_ser_pipe (void)
+{
+ struct serial_ops *ops = XMALLOC (struct serial_ops);
+ memset (ops, sizeof (struct serial_ops), 0);
+ ops->name = "pipe";
+ ops->next = 0;
+ ops->open = pipe_open;
+ ops->close = pipe_close;
+ ops->readchar = ser_unix_readchar;
+ ops->write = ser_unix_write;
+ ops->flush_output = ser_unix_nop_flush_output;
+ ops->flush_input = ser_unix_flush_input;
+ ops->send_break = ser_unix_nop_send_break;
+ ops->go_raw = ser_unix_nop_raw;
+ ops->get_tty_state = ser_unix_nop_get_tty_state;
+ ops->set_tty_state = ser_unix_nop_set_tty_state;
+ ops->print_tty_state = ser_unix_nop_print_tty_state;
+ ops->noflush_set_tty_state = ser_unix_nop_noflush_set_tty_state;
+ ops->setbaudrate = ser_unix_nop_setbaudrate;
+ ops->setstopbits = ser_unix_nop_setstopbits;
+ ops->drain_output = ser_unix_nop_drain_output;
+ ops->async = ser_unix_async;
+ serial_add_interface (ops);
+}
diff --git a/gdb/ser-tcp.c b/gdb/ser-tcp.c
new file mode 100644
index 00000000000..c6ae19dab02
--- /dev/null
+++ b/gdb/ser-tcp.c
@@ -0,0 +1,231 @@
+/* Serial interface for raw TCP connections on Un*x like systems
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001
+ 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 "defs.h"
+#include "serial.h"
+#include "ser-unix.h"
+
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h> /* For FIONBIO. */
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h> /* For FIONBIO. */
+#endif
+
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+
+#include <signal.h>
+#include "gdb_string.h"
+
+static int net_open (struct serial *scb, const char *name);
+static void net_close (struct serial *scb);
+extern int (*ui_loop_hook) (int);
+void _initialize_ser_tcp (void);
+
+/* seconds to wait for connect */
+#define TIMEOUT 15
+/* how many times per second to poll ui_loop_hook */
+#define POLL_INTERVAL 2
+
+/* Open a tcp socket */
+
+static int
+net_open (struct serial *scb, const char *name)
+{
+ char *port_str, hostname[100];
+ int n, port, tmp;
+ int use_udp;
+ struct hostent *hostent;
+ struct sockaddr_in sockaddr;
+
+ use_udp = 0;
+ if (strncmp (name, "udp:", 4) == 0)
+ {
+ use_udp = 1;
+ name = name + 4;
+ }
+ else if (strncmp (name, "tcp:", 4) == 0)
+ name = name + 4;
+
+ port_str = strchr (name, ':');
+
+ if (!port_str)
+ error ("net_open: No colon in host name!"); /* Shouldn't ever happen */
+
+ tmp = min (port_str - name, (int) sizeof hostname - 1);
+ strncpy (hostname, name, tmp); /* Don't want colon */
+ hostname[tmp] = '\000'; /* Tie off host name */
+ port = atoi (port_str + 1);
+
+ /* default hostname is localhost */
+ if (!hostname[0])
+ strcpy (hostname, "localhost");
+
+ hostent = gethostbyname (hostname);
+ if (!hostent)
+ {
+ fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
+ errno = ENOENT;
+ return -1;
+ }
+
+ if (use_udp)
+ scb->fd = socket (PF_INET, SOCK_DGRAM, 0);
+ else
+ scb->fd = socket (PF_INET, SOCK_STREAM, 0);
+
+ if (scb->fd < 0)
+ return -1;
+
+ sockaddr.sin_family = PF_INET;
+ sockaddr.sin_port = htons (port);
+ memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
+ sizeof (struct in_addr));
+
+ /* set socket nonblocking */
+ tmp = 1;
+ ioctl (scb->fd, FIONBIO, &tmp);
+
+ /* Use Non-blocking connect. connect() will return 0 if connected already. */
+ n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
+
+ if (n < 0 && errno != EINPROGRESS)
+ {
+ net_close (scb);
+ return -1;
+ }
+
+ if (n)
+ {
+ /* looks like we need to wait for the connect */
+ struct timeval t;
+ fd_set rset, wset;
+ int polls = 0;
+ FD_ZERO (&rset);
+
+ do
+ {
+ /* While we wait for the connect to complete
+ poll the UI so it can update or the user can
+ interrupt. */
+ if (ui_loop_hook)
+ {
+ if (ui_loop_hook (0))
+ {
+ errno = EINTR;
+ net_close (scb);
+ return -1;
+ }
+ }
+
+ FD_SET (scb->fd, &rset);
+ wset = rset;
+ t.tv_sec = 0;
+ t.tv_usec = 1000000 / POLL_INTERVAL;
+
+ n = select (scb->fd + 1, &rset, &wset, NULL, &t);
+ polls++;
+ }
+ while (n == 0 && polls <= TIMEOUT * POLL_INTERVAL);
+ if (n < 0 || polls > TIMEOUT * POLL_INTERVAL)
+ {
+ if (polls > TIMEOUT * POLL_INTERVAL)
+ errno = ETIMEDOUT;
+ net_close (scb);
+ return -1;
+ }
+ }
+
+ /* Got something. Is it an error? */
+ {
+ int res, err, len;
+ len = sizeof(err);
+ res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, &err, &len);
+ if (res < 0 || err)
+ {
+ if (err)
+ errno = err;
+ net_close (scb);
+ return -1;
+ }
+ }
+
+ /* turn off nonblocking */
+ tmp = 0;
+ ioctl (scb->fd, FIONBIO, &tmp);
+
+ if (use_udp == 0)
+ {
+ /* Disable Nagle algorithm. Needed in some cases. */
+ tmp = 1;
+ setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY,
+ (char *)&tmp, sizeof (tmp));
+ }
+
+ /* If we don't do this, then GDB simply exits
+ when the remote side dies. */
+ signal (SIGPIPE, SIG_IGN);
+
+ return 0;
+}
+
+static void
+net_close (struct serial *scb)
+{
+ if (scb->fd < 0)
+ return;
+
+ close (scb->fd);
+ scb->fd = -1;
+}
+
+void
+_initialize_ser_tcp (void)
+{
+ struct serial_ops *ops = XMALLOC (struct serial_ops);
+ memset (ops, sizeof (struct serial_ops), 0);
+ ops->name = "tcp";
+ ops->next = 0;
+ ops->open = net_open;
+ ops->close = net_close;
+ ops->readchar = ser_unix_readchar;
+ ops->write = ser_unix_write;
+ ops->flush_output = ser_unix_nop_flush_output;
+ ops->flush_input = ser_unix_flush_input;
+ ops->send_break = ser_unix_nop_send_break;
+ ops->go_raw = ser_unix_nop_raw;
+ ops->get_tty_state = ser_unix_nop_get_tty_state;
+ ops->set_tty_state = ser_unix_nop_set_tty_state;
+ ops->print_tty_state = ser_unix_nop_print_tty_state;
+ ops->noflush_set_tty_state = ser_unix_nop_noflush_set_tty_state;
+ ops->setbaudrate = ser_unix_nop_setbaudrate;
+ ops->setstopbits = ser_unix_nop_setstopbits;
+ ops->drain_output = ser_unix_nop_drain_output;
+ ops->async = ser_unix_async;
+ serial_add_interface (ops);
+}
diff --git a/gdb/ser-unix.c b/gdb/ser-unix.c
new file mode 100644
index 00000000000..f7ab28ae750
--- /dev/null
+++ b/gdb/ser-unix.c
@@ -0,0 +1,1363 @@
+/* Serial interface for local (hardwired) serial ports on Un*x like systems
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "serial.h"
+#include "ser-unix.h"
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include "terminal.h"
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include "gdb_string.h"
+#include "event-loop.h"
+
+#ifdef HAVE_TERMIOS
+
+struct hardwire_ttystate
+ {
+ struct termios termios;
+ };
+#endif /* termios */
+
+#ifdef HAVE_TERMIO
+
+/* It is believed that all systems which have added job control to SVR3
+ (e.g. sco) have also added termios. Even if not, trying to figure out
+ all the variations (TIOCGPGRP vs. TCGETPGRP, etc.) would be pretty
+ bewildering. So we don't attempt it. */
+
+struct hardwire_ttystate
+ {
+ struct termio termio;
+ };
+#endif /* termio */
+
+#ifdef HAVE_SGTTY
+struct hardwire_ttystate
+ {
+ struct sgttyb sgttyb;
+ struct tchars tc;
+ struct ltchars ltc;
+ /* Line discipline flags. */
+ int lmode;
+ };
+#endif /* sgtty */
+
+static int hardwire_open (struct serial *scb, const char *name);
+static void hardwire_raw (struct serial *scb);
+static int wait_for (struct serial *scb, int timeout);
+static int hardwire_readchar (struct serial *scb, int timeout);
+static int do_hardwire_readchar (struct serial *scb, int timeout);
+static int generic_readchar (struct serial *scb, int timeout,
+ int (*do_readchar) (struct serial *scb,
+ int timeout));
+static int rate_to_code (int rate);
+static int hardwire_setbaudrate (struct serial *scb, int rate);
+static void hardwire_close (struct serial *scb);
+static int get_tty_state (struct serial *scb,
+ struct hardwire_ttystate * state);
+static int set_tty_state (struct serial *scb,
+ struct hardwire_ttystate * state);
+static serial_ttystate hardwire_get_tty_state (struct serial *scb);
+static int hardwire_set_tty_state (struct serial *scb, serial_ttystate state);
+static int hardwire_noflush_set_tty_state (struct serial *, serial_ttystate,
+ serial_ttystate);
+static void hardwire_print_tty_state (struct serial *, serial_ttystate,
+ struct ui_file *);
+static int hardwire_drain_output (struct serial *);
+static int hardwire_flush_output (struct serial *);
+static int hardwire_flush_input (struct serial *);
+static int hardwire_send_break (struct serial *);
+static int hardwire_setstopbits (struct serial *, int);
+
+static int do_unix_readchar (struct serial *scb, int timeout);
+static timer_handler_func push_event;
+static handler_func fd_event;
+static void reschedule (struct serial *scb);
+
+void _initialize_ser_hardwire (void);
+
+extern int (*ui_loop_hook) (int);
+
+/* Open up a real live device for serial I/O */
+
+static int
+hardwire_open (struct serial *scb, const char *name)
+{
+ scb->fd = open (name, O_RDWR);
+ if (scb->fd < 0)
+ return -1;
+
+ return 0;
+}
+
+static int
+get_tty_state (struct serial *scb, struct hardwire_ttystate *state)
+{
+#ifdef HAVE_TERMIOS
+ if (tcgetattr (scb->fd, &state->termios) < 0)
+ return -1;
+
+ return 0;
+#endif
+
+#ifdef HAVE_TERMIO
+ if (ioctl (scb->fd, TCGETA, &state->termio) < 0)
+ return -1;
+ return 0;
+#endif
+
+#ifdef HAVE_SGTTY
+ if (ioctl (scb->fd, TIOCGETP, &state->sgttyb) < 0)
+ return -1;
+ if (ioctl (scb->fd, TIOCGETC, &state->tc) < 0)
+ return -1;
+ if (ioctl (scb->fd, TIOCGLTC, &state->ltc) < 0)
+ return -1;
+ if (ioctl (scb->fd, TIOCLGET, &state->lmode) < 0)
+ return -1;
+
+ return 0;
+#endif
+}
+
+static int
+set_tty_state (struct serial *scb, struct hardwire_ttystate *state)
+{
+#ifdef HAVE_TERMIOS
+ if (tcsetattr (scb->fd, TCSANOW, &state->termios) < 0)
+ return -1;
+
+ return 0;
+#endif
+
+#ifdef HAVE_TERMIO
+ if (ioctl (scb->fd, TCSETA, &state->termio) < 0)
+ return -1;
+ return 0;
+#endif
+
+#ifdef HAVE_SGTTY
+ if (ioctl (scb->fd, TIOCSETN, &state->sgttyb) < 0)
+ return -1;
+ if (ioctl (scb->fd, TIOCSETC, &state->tc) < 0)
+ return -1;
+ if (ioctl (scb->fd, TIOCSLTC, &state->ltc) < 0)
+ return -1;
+ if (ioctl (scb->fd, TIOCLSET, &state->lmode) < 0)
+ return -1;
+
+ return 0;
+#endif
+}
+
+static serial_ttystate
+hardwire_get_tty_state (struct serial *scb)
+{
+ struct hardwire_ttystate *state;
+
+ state = (struct hardwire_ttystate *) xmalloc (sizeof *state);
+
+ if (get_tty_state (scb, state))
+ return NULL;
+
+ return (serial_ttystate) state;
+}
+
+static int
+hardwire_set_tty_state (struct serial *scb, serial_ttystate ttystate)
+{
+ struct hardwire_ttystate *state;
+
+ state = (struct hardwire_ttystate *) ttystate;
+
+ return set_tty_state (scb, state);
+}
+
+static int
+hardwire_noflush_set_tty_state (struct serial *scb,
+ serial_ttystate new_ttystate,
+ serial_ttystate old_ttystate)
+{
+ struct hardwire_ttystate new_state;
+#ifdef HAVE_SGTTY
+ struct hardwire_ttystate *state = (struct hardwire_ttystate *) old_ttystate;
+#endif
+
+ new_state = *(struct hardwire_ttystate *) new_ttystate;
+
+ /* Don't change in or out of raw mode; we don't want to flush input.
+ termio and termios have no such restriction; for them flushing input
+ is separate from setting the attributes. */
+
+#ifdef HAVE_SGTTY
+ if (state->sgttyb.sg_flags & RAW)
+ new_state.sgttyb.sg_flags |= RAW;
+ else
+ new_state.sgttyb.sg_flags &= ~RAW;
+
+ /* I'm not sure whether this is necessary; the manpage just mentions
+ RAW not CBREAK. */
+ if (state->sgttyb.sg_flags & CBREAK)
+ new_state.sgttyb.sg_flags |= CBREAK;
+ else
+ new_state.sgttyb.sg_flags &= ~CBREAK;
+#endif
+
+ return set_tty_state (scb, &new_state);
+}
+
+static void
+hardwire_print_tty_state (struct serial *scb,
+ serial_ttystate ttystate,
+ struct ui_file *stream)
+{
+ struct hardwire_ttystate *state = (struct hardwire_ttystate *) ttystate;
+ int i;
+
+#ifdef HAVE_TERMIOS
+ fprintf_filtered (stream, "c_iflag = 0x%x, c_oflag = 0x%x,\n",
+ (int) state->termios.c_iflag,
+ (int) state->termios.c_oflag);
+ fprintf_filtered (stream, "c_cflag = 0x%x, c_lflag = 0x%x\n",
+ (int) state->termios.c_cflag,
+ (int) state->termios.c_lflag);
+#if 0
+ /* This not in POSIX, and is not really documented by those systems
+ which have it (at least not Sun). */
+ fprintf_filtered (stream, "c_line = 0x%x.\n", state->termios.c_line);
+#endif
+ fprintf_filtered (stream, "c_cc: ");
+ for (i = 0; i < NCCS; i += 1)
+ fprintf_filtered (stream, "0x%x ", state->termios.c_cc[i]);
+ fprintf_filtered (stream, "\n");
+#endif
+
+#ifdef HAVE_TERMIO
+ fprintf_filtered (stream, "c_iflag = 0x%x, c_oflag = 0x%x,\n",
+ state->termio.c_iflag, state->termio.c_oflag);
+ fprintf_filtered (stream, "c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
+ state->termio.c_cflag, state->termio.c_lflag,
+ state->termio.c_line);
+ fprintf_filtered (stream, "c_cc: ");
+ for (i = 0; i < NCC; i += 1)
+ fprintf_filtered (stream, "0x%x ", state->termio.c_cc[i]);
+ fprintf_filtered (stream, "\n");
+#endif
+
+#ifdef HAVE_SGTTY
+ fprintf_filtered (stream, "sgttyb.sg_flags = 0x%x.\n",
+ state->sgttyb.sg_flags);
+
+ fprintf_filtered (stream, "tchars: ");
+ for (i = 0; i < (int) sizeof (struct tchars); i++)
+ fprintf_filtered (stream, "0x%x ", ((unsigned char *) &state->tc)[i]);
+ fprintf_filtered (stream, "\n");
+
+ fprintf_filtered (stream, "ltchars: ");
+ for (i = 0; i < (int) sizeof (struct ltchars); i++)
+ fprintf_filtered (stream, "0x%x ", ((unsigned char *) &state->ltc)[i]);
+ fprintf_filtered (stream, "\n");
+
+ fprintf_filtered (stream, "lmode: 0x%x\n", state->lmode);
+#endif
+}
+
+/* Wait for the output to drain away, as opposed to flushing (discarding) it */
+
+static int
+hardwire_drain_output (struct serial *scb)
+{
+#ifdef HAVE_TERMIOS
+ return tcdrain (scb->fd);
+#endif
+
+#ifdef HAVE_TERMIO
+ return ioctl (scb->fd, TCSBRK, 1);
+#endif
+
+#ifdef HAVE_SGTTY
+ /* Get the current state and then restore it using TIOCSETP,
+ which should cause the output to drain and pending input
+ to be discarded. */
+ {
+ struct hardwire_ttystate state;
+ if (get_tty_state (scb, &state))
+ {
+ return (-1);
+ }
+ else
+ {
+ return (ioctl (scb->fd, TIOCSETP, &state.sgttyb));
+ }
+ }
+#endif
+}
+
+static int
+hardwire_flush_output (struct serial *scb)
+{
+#ifdef HAVE_TERMIOS
+ return tcflush (scb->fd, TCOFLUSH);
+#endif
+
+#ifdef HAVE_TERMIO
+ return ioctl (scb->fd, TCFLSH, 1);
+#endif
+
+#ifdef HAVE_SGTTY
+ /* This flushes both input and output, but we can't do better. */
+ return ioctl (scb->fd, TIOCFLUSH, 0);
+#endif
+}
+
+static int
+hardwire_flush_input (struct serial *scb)
+{
+ ser_unix_flush_input (scb);
+
+#ifdef HAVE_TERMIOS
+ return tcflush (scb->fd, TCIFLUSH);
+#endif
+
+#ifdef HAVE_TERMIO
+ return ioctl (scb->fd, TCFLSH, 0);
+#endif
+
+#ifdef HAVE_SGTTY
+ /* This flushes both input and output, but we can't do better. */
+ return ioctl (scb->fd, TIOCFLUSH, 0);
+#endif
+}
+
+static int
+hardwire_send_break (struct serial *scb)
+{
+#ifdef HAVE_TERMIOS
+ return tcsendbreak (scb->fd, 0);
+#endif
+
+#ifdef HAVE_TERMIO
+ return ioctl (scb->fd, TCSBRK, 0);
+#endif
+
+#ifdef HAVE_SGTTY
+ {
+ int status;
+ struct timeval timeout;
+
+ status = ioctl (scb->fd, TIOCSBRK, 0);
+
+ /* Can't use usleep; it doesn't exist in BSD 4.2. */
+ /* Note that if this select() is interrupted by a signal it will not wait
+ the full length of time. I think that is OK. */
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 250000;
+ select (0, 0, 0, 0, &timeout);
+ status = ioctl (scb->fd, TIOCCBRK, 0);
+ return status;
+ }
+#endif
+}
+
+static void
+hardwire_raw (struct serial *scb)
+{
+ struct hardwire_ttystate state;
+
+ if (get_tty_state (scb, &state))
+ fprintf_unfiltered (gdb_stderr, "get_tty_state failed: %s\n", safe_strerror (errno));
+
+#ifdef HAVE_TERMIOS
+ state.termios.c_iflag = 0;
+ state.termios.c_oflag = 0;
+ state.termios.c_lflag = 0;
+ state.termios.c_cflag &= ~(CSIZE | PARENB);
+ state.termios.c_cflag |= CLOCAL | CS8;
+ state.termios.c_cc[VMIN] = 0;
+ state.termios.c_cc[VTIME] = 0;
+#endif
+
+#ifdef HAVE_TERMIO
+ state.termio.c_iflag = 0;
+ state.termio.c_oflag = 0;
+ state.termio.c_lflag = 0;
+ state.termio.c_cflag &= ~(CSIZE | PARENB);
+ state.termio.c_cflag |= CLOCAL | CS8;
+ state.termio.c_cc[VMIN] = 0;
+ state.termio.c_cc[VTIME] = 0;
+#endif
+
+#ifdef HAVE_SGTTY
+ state.sgttyb.sg_flags |= RAW | ANYP;
+ state.sgttyb.sg_flags &= ~(CBREAK | ECHO);
+#endif
+
+ scb->current_timeout = 0;
+
+ if (set_tty_state (scb, &state))
+ fprintf_unfiltered (gdb_stderr, "set_tty_state failed: %s\n", safe_strerror (errno));
+}
+
+/* Wait for input on scb, with timeout seconds. Returns 0 on success,
+ otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
+
+ For termio{s}, we actually just setup VTIME if necessary, and let the
+ timeout occur in the read() in hardwire_read().
+ */
+
+/* FIXME: cagney/1999-09-16: Don't replace this with the equivalent
+ ser_unix*() until the old TERMIOS/SGTTY/... timer code has been
+ flushed. . */
+
+/* NOTE: cagney/1999-09-30: Much of the code below is dead. The only
+ possible values of the TIMEOUT parameter are ONE and ZERO.
+ Consequently all the code that tries to handle the possability of
+ an overflowed timer is unnecessary. */
+
+static int
+wait_for (struct serial *scb, int timeout)
+{
+#ifdef HAVE_SGTTY
+ while (1)
+ {
+ struct timeval tv;
+ fd_set readfds;
+ int numfds;
+
+ /* NOTE: Some OS's can scramble the READFDS when the select()
+ call fails (ex the kernel with Red Hat 5.2). Initialize all
+ arguments before each call. */
+
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+
+ FD_ZERO (&readfds);
+ FD_SET (scb->fd, &readfds);
+
+ if (timeout >= 0)
+ numfds = select (scb->fd + 1, &readfds, 0, 0, &tv);
+ else
+ numfds = select (scb->fd + 1, &readfds, 0, 0, 0);
+
+ if (numfds <= 0)
+ if (numfds == 0)
+ return SERIAL_TIMEOUT;
+ else if (errno == EINTR)
+ continue;
+ else
+ return SERIAL_ERROR; /* Got an error from select or poll */
+
+ return 0;
+ }
+#endif /* HAVE_SGTTY */
+
+#if defined HAVE_TERMIO || defined HAVE_TERMIOS
+ if (timeout == scb->current_timeout)
+ return 0;
+
+ scb->current_timeout = timeout;
+
+ {
+ struct hardwire_ttystate state;
+
+ if (get_tty_state (scb, &state))
+ fprintf_unfiltered (gdb_stderr, "get_tty_state failed: %s\n", safe_strerror (errno));
+
+#ifdef HAVE_TERMIOS
+ if (timeout < 0)
+ {
+ /* No timeout. */
+ state.termios.c_cc[VTIME] = 0;
+ state.termios.c_cc[VMIN] = 1;
+ }
+ else
+ {
+ state.termios.c_cc[VMIN] = 0;
+ state.termios.c_cc[VTIME] = timeout * 10;
+ if (state.termios.c_cc[VTIME] != timeout * 10)
+ {
+
+ /* If c_cc is an 8-bit signed character, we can't go
+ bigger than this. If it is always unsigned, we could use
+ 25. */
+
+ scb->current_timeout = 12;
+ state.termios.c_cc[VTIME] = scb->current_timeout * 10;
+ scb->timeout_remaining = timeout - scb->current_timeout;
+ }
+ }
+#endif
+
+#ifdef HAVE_TERMIO
+ if (timeout < 0)
+ {
+ /* No timeout. */
+ state.termio.c_cc[VTIME] = 0;
+ state.termio.c_cc[VMIN] = 1;
+ }
+ else
+ {
+ state.termio.c_cc[VMIN] = 0;
+ state.termio.c_cc[VTIME] = timeout * 10;
+ if (state.termio.c_cc[VTIME] != timeout * 10)
+ {
+ /* If c_cc is an 8-bit signed character, we can't go
+ bigger than this. If it is always unsigned, we could use
+ 25. */
+
+ scb->current_timeout = 12;
+ state.termio.c_cc[VTIME] = scb->current_timeout * 10;
+ scb->timeout_remaining = timeout - scb->current_timeout;
+ }
+ }
+#endif
+
+ if (set_tty_state (scb, &state))
+ fprintf_unfiltered (gdb_stderr, "set_tty_state failed: %s\n", safe_strerror (errno));
+
+ return 0;
+ }
+#endif /* HAVE_TERMIO || HAVE_TERMIOS */
+}
+
+/* Read a character with user-specified timeout. TIMEOUT is number of seconds
+ to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
+ char if successful. Returns SERIAL_TIMEOUT if timeout expired, EOF if line
+ dropped dead, or SERIAL_ERROR for any other error (see errno in that case). */
+
+/* FIXME: cagney/1999-09-16: Don't replace this with the equivalent
+ ser_unix*() until the old TERMIOS/SGTTY/... timer code has been
+ flushed. */
+
+/* NOTE: cagney/1999-09-16: This function is not identical to
+ ser_unix_readchar() as part of replacing it with ser_unix*()
+ merging will be required - this code handles the case where read()
+ times out due to no data while ser_unix_readchar() doesn't expect
+ that. */
+
+static int
+do_hardwire_readchar (struct serial *scb, int timeout)
+{
+ int status, delta;
+ int detach = 0;
+
+ if (timeout > 0)
+ timeout++;
+
+ /* We have to be able to keep the GUI alive here, so we break the original
+ timeout into steps of 1 second, running the "keep the GUI alive" hook
+ each time through the loop.
+ Also, timeout = 0 means to poll, so we just set the delta to 0, so we
+ will only go through the loop once. */
+
+ delta = (timeout == 0 ? 0 : 1);
+ while (1)
+ {
+
+ /* N.B. The UI may destroy our world (for instance by calling
+ remote_stop,) in which case we want to get out of here as
+ quickly as possible. It is not safe to touch scb, since
+ someone else might have freed it. The ui_loop_hook signals that
+ we should exit by returning 1. */
+
+ if (ui_loop_hook)
+ detach = ui_loop_hook (0);
+
+ if (detach)
+ return SERIAL_TIMEOUT;
+
+ scb->timeout_remaining = (timeout < 0 ? timeout : timeout - delta);
+ status = wait_for (scb, delta);
+
+ if (status < 0)
+ return status;
+
+ status = read (scb->fd, scb->buf, BUFSIZ);
+
+ if (status <= 0)
+ {
+ if (status == 0)
+ {
+ /* Zero characters means timeout (it could also be EOF, but
+ we don't (yet at least) distinguish). */
+ if (scb->timeout_remaining > 0)
+ {
+ timeout = scb->timeout_remaining;
+ continue;
+ }
+ else if (scb->timeout_remaining < 0)
+ continue;
+ else
+ return SERIAL_TIMEOUT;
+ }
+ else if (errno == EINTR)
+ continue;
+ else
+ return SERIAL_ERROR; /* Got an error from read */
+ }
+
+ scb->bufcnt = status;
+ scb->bufcnt--;
+ scb->bufp = scb->buf;
+ return *scb->bufp++;
+ }
+}
+
+static int
+hardwire_readchar (struct serial *scb, int timeout)
+{
+ return generic_readchar (scb, timeout, do_hardwire_readchar);
+}
+
+
+#ifndef B19200
+#define B19200 EXTA
+#endif
+
+#ifndef B38400
+#define B38400 EXTB
+#endif
+
+/* Translate baud rates from integers to damn B_codes. Unix should
+ have outgrown this crap years ago, but even POSIX wouldn't buck it. */
+
+static struct
+{
+ int rate;
+ int code;
+}
+baudtab[] =
+{
+ {
+ 50, B50
+ }
+ ,
+ {
+ 75, B75
+ }
+ ,
+ {
+ 110, B110
+ }
+ ,
+ {
+ 134, B134
+ }
+ ,
+ {
+ 150, B150
+ }
+ ,
+ {
+ 200, B200
+ }
+ ,
+ {
+ 300, B300
+ }
+ ,
+ {
+ 600, B600
+ }
+ ,
+ {
+ 1200, B1200
+ }
+ ,
+ {
+ 1800, B1800
+ }
+ ,
+ {
+ 2400, B2400
+ }
+ ,
+ {
+ 4800, B4800
+ }
+ ,
+ {
+ 9600, B9600
+ }
+ ,
+ {
+ 19200, B19200
+ }
+ ,
+ {
+ 38400, B38400
+ }
+ ,
+#ifdef B57600
+ {
+ 57600, B57600
+ }
+ ,
+#endif
+#ifdef B115200
+ {
+ 115200, B115200
+ }
+ ,
+#endif
+#ifdef B230400
+ {
+ 230400, B230400
+ }
+ ,
+#endif
+#ifdef B460800
+ {
+ 460800, B460800
+ }
+ ,
+#endif
+ {
+ -1, -1
+ }
+ ,
+};
+
+static int
+rate_to_code (int rate)
+{
+ int i;
+
+ for (i = 0; baudtab[i].rate != -1; i++)
+ {
+ /* test for perfect macth. */
+ if (rate == baudtab[i].rate)
+ return baudtab[i].code;
+ else
+ {
+ /* check if it is in between valid values. */
+ if (rate < baudtab[i].rate)
+ {
+ if (i)
+ {
+ warning ("Invalid baud rate %d. Closest values are %d and %d.",
+ rate, baudtab[i - 1].rate, baudtab[i].rate);
+ }
+ else
+ {
+ warning ("Invalid baud rate %d. Minimum value is %d.",
+ rate, baudtab[0].rate);
+ }
+ return -1;
+ }
+ }
+ }
+
+ /* The requested speed was too large. */
+ warning ("Invalid baud rate %d. Maximum value is %d.",
+ rate, baudtab[i - 1].rate);
+ return -1;
+}
+
+static int
+hardwire_setbaudrate (struct serial *scb, int rate)
+{
+ struct hardwire_ttystate state;
+ int baud_code = rate_to_code (rate);
+
+ if (baud_code < 0)
+ {
+ /* The baud rate was not valid.
+ A warning has already been issued. */
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (get_tty_state (scb, &state))
+ return -1;
+
+#ifdef HAVE_TERMIOS
+ cfsetospeed (&state.termios, baud_code);
+ cfsetispeed (&state.termios, baud_code);
+#endif
+
+#ifdef HAVE_TERMIO
+#ifndef CIBAUD
+#define CIBAUD CBAUD
+#endif
+
+ state.termio.c_cflag &= ~(CBAUD | CIBAUD);
+ state.termio.c_cflag |= baud_code;
+#endif
+
+#ifdef HAVE_SGTTY
+ state.sgttyb.sg_ispeed = baud_code;
+ state.sgttyb.sg_ospeed = baud_code;
+#endif
+
+ return set_tty_state (scb, &state);
+}
+
+static int
+hardwire_setstopbits (struct serial *scb, int num)
+{
+ struct hardwire_ttystate state;
+ int newbit;
+
+ if (get_tty_state (scb, &state))
+ return -1;
+
+ switch (num)
+ {
+ case SERIAL_1_STOPBITS:
+ newbit = 0;
+ break;
+ case SERIAL_1_AND_A_HALF_STOPBITS:
+ case SERIAL_2_STOPBITS:
+ newbit = 1;
+ break;
+ default:
+ return 1;
+ }
+
+#ifdef HAVE_TERMIOS
+ if (!newbit)
+ state.termios.c_cflag &= ~CSTOPB;
+ else
+ state.termios.c_cflag |= CSTOPB; /* two bits */
+#endif
+
+#ifdef HAVE_TERMIO
+ if (!newbit)
+ state.termio.c_cflag &= ~CSTOPB;
+ else
+ state.termio.c_cflag |= CSTOPB; /* two bits */
+#endif
+
+#ifdef HAVE_SGTTY
+ return 0; /* sgtty doesn't support this */
+#endif
+
+ return set_tty_state (scb, &state);
+}
+
+static void
+hardwire_close (struct serial *scb)
+{
+ if (scb->fd < 0)
+ return;
+
+ close (scb->fd);
+ scb->fd = -1;
+}
+
+
+/* Generic operations used by all UNIX/FD based serial interfaces. */
+
+serial_ttystate
+ser_unix_nop_get_tty_state (struct serial *scb)
+{
+ /* allocate a dummy */
+ return (serial_ttystate) XMALLOC (int);
+}
+
+int
+ser_unix_nop_set_tty_state (struct serial *scb, serial_ttystate ttystate)
+{
+ return 0;
+}
+
+void
+ser_unix_nop_raw (struct serial *scb)
+{
+ return; /* Always in raw mode */
+}
+
+/* Wait for input on scb, with timeout seconds. Returns 0 on success,
+ otherwise SERIAL_TIMEOUT or SERIAL_ERROR. */
+
+int
+ser_unix_wait_for (struct serial *scb, int timeout)
+{
+ while (1)
+ {
+ int numfds;
+ struct timeval tv;
+ fd_set readfds, exceptfds;
+
+ /* NOTE: Some OS's can scramble the READFDS when the select()
+ call fails (ex the kernel with Red Hat 5.2). Initialize all
+ arguments before each call. */
+
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+
+ FD_ZERO (&readfds);
+ FD_ZERO (&exceptfds);
+ FD_SET (scb->fd, &readfds);
+ FD_SET (scb->fd, &exceptfds);
+
+ if (timeout >= 0)
+ numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
+ else
+ numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
+
+ if (numfds <= 0)
+ {
+ if (numfds == 0)
+ return SERIAL_TIMEOUT;
+ else if (errno == EINTR)
+ continue;
+ else
+ return SERIAL_ERROR; /* Got an error from select or poll */
+ }
+
+ return 0;
+ }
+}
+
+/* Read a character with user-specified timeout. TIMEOUT is number of seconds
+ to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
+ char if successful. Returns -2 if timeout expired, EOF if line dropped
+ dead, or -3 for any other error (see errno in that case). */
+
+static int
+do_unix_readchar (struct serial *scb, int timeout)
+{
+ int status;
+ int delta;
+
+ /* We have to be able to keep the GUI alive here, so we break the original
+ timeout into steps of 1 second, running the "keep the GUI alive" hook
+ each time through the loop.
+
+ Also, timeout = 0 means to poll, so we just set the delta to 0, so we
+ will only go through the loop once. */
+
+ delta = (timeout == 0 ? 0 : 1);
+ while (1)
+ {
+
+ /* N.B. The UI may destroy our world (for instance by calling
+ remote_stop,) in which case we want to get out of here as
+ quickly as possible. It is not safe to touch scb, since
+ someone else might have freed it. The ui_loop_hook signals that
+ we should exit by returning 1. */
+
+ if (ui_loop_hook)
+ {
+ if (ui_loop_hook (0))
+ return SERIAL_TIMEOUT;
+ }
+
+ status = ser_unix_wait_for (scb, delta);
+ if (timeout > 0)
+ timeout -= delta;
+
+ /* If we got a character or an error back from wait_for, then we can
+ break from the loop before the timeout is completed. */
+
+ if (status != SERIAL_TIMEOUT)
+ {
+ break;
+ }
+
+ /* If we have exhausted the original timeout, then generate
+ a SERIAL_TIMEOUT, and pass it out of the loop. */
+
+ else if (timeout == 0)
+ {
+ status = SERIAL_TIMEOUT;
+ break;
+ }
+ }
+
+ if (status < 0)
+ return status;
+
+ while (1)
+ {
+ status = read (scb->fd, scb->buf, BUFSIZ);
+ if (status != -1 || errno != EINTR)
+ break;
+ }
+
+ if (status <= 0)
+ {
+ if (status == 0)
+ return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
+ distinguish between EOF & timeouts
+ someday] */
+ else
+ return SERIAL_ERROR; /* Got an error from read */
+ }
+
+ scb->bufcnt = status;
+ scb->bufcnt--;
+ scb->bufp = scb->buf;
+ return *scb->bufp++;
+}
+
+/* Perform operations common to both old and new readchar. */
+
+/* Return the next character from the input FIFO. If the FIFO is
+ empty, call the SERIAL specific routine to try and read in more
+ characters.
+
+ Initially data from the input FIFO is returned (fd_event()
+ pre-reads the input into that FIFO. Once that has been emptied,
+ further data is obtained by polling the input FD using the device
+ specific readchar() function. Note: reschedule() is called after
+ every read. This is because there is no guarentee that the lower
+ level fd_event() poll_event() code (which also calls reschedule())
+ will be called. */
+
+static int
+generic_readchar (struct serial *scb, int timeout,
+ int (do_readchar) (struct serial *scb, int timeout))
+{
+ int ch;
+ if (scb->bufcnt > 0)
+ {
+ ch = *scb->bufp;
+ scb->bufcnt--;
+ scb->bufp++;
+ }
+ else if (scb->bufcnt < 0)
+ {
+ /* Some errors/eof are are sticky. */
+ ch = scb->bufcnt;
+ }
+ else
+ {
+ ch = do_readchar (scb, timeout);
+ if (ch < 0)
+ {
+ switch ((enum serial_rc) ch)
+ {
+ case SERIAL_EOF:
+ case SERIAL_ERROR:
+ /* Make the error/eof stick. */
+ scb->bufcnt = ch;
+ break;
+ case SERIAL_TIMEOUT:
+ scb->bufcnt = 0;
+ break;
+ }
+ }
+ }
+ reschedule (scb);
+ return ch;
+}
+
+int
+ser_unix_readchar (struct serial *scb, int timeout)
+{
+ return generic_readchar (scb, timeout, do_unix_readchar);
+}
+
+int
+ser_unix_nop_noflush_set_tty_state (struct serial *scb,
+ serial_ttystate new_ttystate,
+ serial_ttystate old_ttystate)
+{
+ return 0;
+}
+
+void
+ser_unix_nop_print_tty_state (struct serial *scb,
+ serial_ttystate ttystate,
+ struct ui_file *stream)
+{
+ /* Nothing to print. */
+ return;
+}
+
+int
+ser_unix_nop_setbaudrate (struct serial *scb, int rate)
+{
+ return 0; /* Never fails! */
+}
+
+int
+ser_unix_nop_setstopbits (struct serial *scb, int num)
+{
+ return 0; /* Never fails! */
+}
+
+int
+ser_unix_write (struct serial *scb, const char *str, int len)
+{
+ int cc;
+
+ while (len > 0)
+ {
+ cc = write (scb->fd, str, len);
+
+ if (cc < 0)
+ return 1;
+ len -= cc;
+ str += cc;
+ }
+ return 0;
+}
+
+int
+ser_unix_nop_flush_output (struct serial *scb)
+{
+ return 0;
+}
+
+int
+ser_unix_flush_input (struct serial *scb)
+{
+ if (scb->bufcnt >= 0)
+ {
+ scb->bufcnt = 0;
+ scb->bufp = scb->buf;
+ return 0;
+ }
+ else
+ return SERIAL_ERROR;
+}
+
+int
+ser_unix_nop_send_break (struct serial *scb)
+{
+ return 0;
+}
+
+int
+ser_unix_nop_drain_output (struct serial *scb)
+{
+ return 0;
+}
+
+
+
+/* Event handling for ASYNC serial code.
+
+ At any time the SERIAL device either: has an empty FIFO and is
+ waiting on a FD event; or has a non-empty FIFO/error condition and
+ is constantly scheduling timer events.
+
+ ASYNC only stops pestering its client when it is de-async'ed or it
+ is told to go away. */
+
+/* Value of scb->async_state: */
+enum {
+ /* >= 0 (TIMER_SCHEDULED) */
+ /* The ID of the currently scheduled timer event. This state is
+ rarely encountered. Timer events are one-off so as soon as the
+ event is delivered the state is shanged to NOTHING_SCHEDULED. */
+ FD_SCHEDULED = -1,
+ /* The fd_event() handler is scheduled. It is called when ever the
+ file descriptor becomes ready. */
+ NOTHING_SCHEDULED = -2
+ /* Either no task is scheduled (just going into ASYNC mode) or a
+ timer event has just gone off and the current state has been
+ forced into nothing scheduled. */
+};
+
+/* Identify and schedule the next ASYNC task based on scb->async_state
+ and scb->buf* (the input FIFO). A state machine is used to avoid
+ the need to make redundant calls into the event-loop - the next
+ scheduled task is only changed when needed. */
+
+static void
+reschedule (struct serial *scb)
+{
+ if (serial_is_async_p (scb))
+ {
+ int next_state;
+ switch (scb->async_state)
+ {
+ case FD_SCHEDULED:
+ if (scb->bufcnt == 0)
+ next_state = FD_SCHEDULED;
+ else
+ {
+ delete_file_handler (scb->fd);
+ next_state = create_timer (0, push_event, scb);
+ }
+ break;
+ case NOTHING_SCHEDULED:
+ if (scb->bufcnt == 0)
+ {
+ add_file_handler (scb->fd, fd_event, scb);
+ next_state = FD_SCHEDULED;
+ }
+ else
+ {
+ next_state = create_timer (0, push_event, scb);
+ }
+ break;
+ default: /* TIMER SCHEDULED */
+ if (scb->bufcnt == 0)
+ {
+ delete_timer (scb->async_state);
+ add_file_handler (scb->fd, fd_event, scb);
+ next_state = FD_SCHEDULED;
+ }
+ else
+ next_state = scb->async_state;
+ break;
+ }
+ if (serial_debug_p (scb))
+ {
+ switch (next_state)
+ {
+ case FD_SCHEDULED:
+ if (scb->async_state != FD_SCHEDULED)
+ fprintf_unfiltered (gdb_stdlog, "[fd%d->fd-scheduled]\n",
+ scb->fd);
+ break;
+ default: /* TIMER SCHEDULED */
+ if (scb->async_state == FD_SCHEDULED)
+ fprintf_unfiltered (gdb_stdlog, "[fd%d->timer-scheduled]\n",
+ scb->fd);
+ break;
+ }
+ }
+ scb->async_state = next_state;
+ }
+}
+
+/* FD_EVENT: This is scheduled when the input FIFO is empty (and there
+ is no pending error). As soon as data arrives, it is read into the
+ input FIFO and the client notified. The client should then drain
+ the FIFO using readchar(). If the FIFO isn't immediatly emptied,
+ push_event() is used to nag the client until it is. */
+
+static void
+fd_event (int error, void *context)
+{
+ struct serial *scb = context;
+ if (error != 0)
+ {
+ scb->bufcnt = SERIAL_ERROR;
+ }
+ else if (scb->bufcnt == 0)
+ {
+ /* Prime the input FIFO. The readchar() function is used to
+ pull characters out of the buffer. See also
+ generic_readchar(). */
+ int nr;
+ do
+ {
+ nr = read (scb->fd, scb->buf, BUFSIZ);
+ }
+ while (nr == -1 && errno == EINTR);
+ if (nr == 0)
+ {
+ scb->bufcnt = SERIAL_EOF;
+ }
+ else if (nr > 0)
+ {
+ scb->bufcnt = nr;
+ scb->bufp = scb->buf;
+ }
+ else
+ {
+ scb->bufcnt = SERIAL_ERROR;
+ }
+ }
+ scb->async_handler (scb, scb->async_context);
+ reschedule (scb);
+}
+
+/* PUSH_EVENT: The input FIFO is non-empty (or there is a pending
+ error). Nag the client until all the data has been read. In the
+ case of errors, the client will need to close or de-async the
+ device before naging stops. */
+
+static void
+push_event (void *context)
+{
+ struct serial *scb = context;
+ scb->async_state = NOTHING_SCHEDULED; /* Timers are one-off */
+ scb->async_handler (scb, scb->async_context);
+ /* re-schedule */
+ reschedule (scb);
+}
+
+/* Put the SERIAL device into/out-of ASYNC mode. */
+
+void
+ser_unix_async (struct serial *scb,
+ int async_p)
+{
+ if (async_p)
+ {
+ /* Force a re-schedule. */
+ scb->async_state = NOTHING_SCHEDULED;
+ if (serial_debug_p (scb))
+ fprintf_unfiltered (gdb_stdlog, "[fd%d->asynchronous]\n",
+ scb->fd);
+ reschedule (scb);
+ }
+ else
+ {
+ if (serial_debug_p (scb))
+ fprintf_unfiltered (gdb_stdlog, "[fd%d->synchronous]\n",
+ scb->fd);
+ /* De-schedule whatever tasks are currently scheduled. */
+ switch (scb->async_state)
+ {
+ case FD_SCHEDULED:
+ delete_file_handler (scb->fd);
+ break;
+ NOTHING_SCHEDULED:
+ break;
+ default: /* TIMER SCHEDULED */
+ delete_timer (scb->async_state);
+ break;
+ }
+ }
+}
+
+void
+_initialize_ser_hardwire (void)
+{
+ struct serial_ops *ops = XMALLOC (struct serial_ops);
+ memset (ops, sizeof (struct serial_ops), 0);
+ ops->name = "hardwire";
+ ops->next = 0;
+ ops->open = hardwire_open;
+ ops->close = hardwire_close;
+ /* FIXME: Don't replace this with the equivalent ser_unix*() until
+ the old TERMIOS/SGTTY/... timer code has been flushed. cagney
+ 1999-09-16. */
+ ops->readchar = hardwire_readchar;
+ ops->write = ser_unix_write;
+ ops->flush_output = hardwire_flush_output;
+ ops->flush_input = hardwire_flush_input;
+ ops->send_break = hardwire_send_break;
+ ops->go_raw = hardwire_raw;
+ ops->get_tty_state = hardwire_get_tty_state;
+ ops->set_tty_state = hardwire_set_tty_state;
+ ops->print_tty_state = hardwire_print_tty_state;
+ ops->noflush_set_tty_state = hardwire_noflush_set_tty_state;
+ ops->setbaudrate = hardwire_setbaudrate;
+ ops->setstopbits = hardwire_setstopbits;
+ ops->drain_output = hardwire_drain_output;
+ ops->async = ser_unix_async;
+ serial_add_interface (ops);
+}
diff --git a/gdb/ser-unix.h b/gdb/ser-unix.h
new file mode 100644
index 00000000000..f7be059b28a
--- /dev/null
+++ b/gdb/ser-unix.h
@@ -0,0 +1,51 @@
+/* Serial interface for UN*X file-descriptor based connection.
+
+ Copyright 1999, 2000, 2002 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. */
+
+#ifndef SER_UNIX_H
+#define SER_UNIX_H
+
+/* Generic UNIX/FD functions */
+
+extern int ser_unix_nop_flush_output (struct serial *scb);
+extern int ser_unix_flush_input (struct serial *scb);
+extern int ser_unix_nop_send_break (struct serial *scb);
+extern void ser_unix_nop_raw (struct serial *scb);
+extern serial_ttystate ser_unix_nop_get_tty_state (struct serial *scb);
+extern int ser_unix_nop_set_tty_state (struct serial *scb,
+ serial_ttystate ttystate);
+extern void ser_unix_nop_print_tty_state (struct serial *scb,
+ serial_ttystate ttystate,
+ struct ui_file *stream);
+extern int ser_unix_nop_noflush_set_tty_state (struct serial *scb,
+ serial_ttystate new_ttystate,
+ serial_ttystate old_ttystate);
+extern int ser_unix_nop_setbaudrate (struct serial *scb, int rate);
+extern int ser_unix_nop_setstopbits (struct serial *scb, int rate);
+extern int ser_unix_nop_drain_output (struct serial *scb);
+
+extern int ser_unix_wait_for (struct serial *scb, int timeout);
+extern int ser_unix_readchar (struct serial *scb, int timeout);
+
+extern int ser_unix_write (struct serial *scb, const char *str, int len);
+
+extern void ser_unix_async (struct serial *scb, int async_p);
+
+#endif
diff --git a/gdb/serial.c b/gdb/serial.c
new file mode 100644
index 00000000000..ada5631dce9
--- /dev/null
+++ b/gdb/serial.c
@@ -0,0 +1,712 @@
+/* Generic serial interface routines
+
+ Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002 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 "defs.h"
+#include <ctype.h>
+#include "serial.h"
+#include "gdb_string.h"
+#include "gdbcmd.h"
+
+extern void _initialize_serial (void);
+
+/* Is serial being debugged? */
+
+static int global_serial_debug_p;
+
+/* Linked list of serial I/O handlers */
+
+static struct serial_ops *serial_ops_list = NULL;
+
+/* This is the last serial stream opened. Used by connect command. */
+
+static struct serial *last_serial_opened = NULL;
+
+/* Pointer to list of scb's. */
+
+static struct serial *scb_base;
+
+/* Non-NULL gives filename which contains a recording of the remote session,
+ suitable for playback by gdbserver. */
+
+static char *serial_logfile = NULL;
+static struct ui_file *serial_logfp = NULL;
+
+static struct serial_ops *serial_interface_lookup (char *);
+static void serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout);
+static const char logbase_hex[] = "hex";
+static const char logbase_octal[] = "octal";
+static const char logbase_ascii[] = "ascii";
+static const char *logbase_enums[] =
+{logbase_hex, logbase_octal, logbase_ascii, NULL};
+static const char *serial_logbase = logbase_ascii;
+
+
+static int serial_current_type = 0;
+
+/* Log char CH of type CHTYPE, with TIMEOUT */
+
+/* Define bogus char to represent a BREAK. Should be careful to choose a value
+ that can't be confused with a normal char, or an error code. */
+#define SERIAL_BREAK 1235
+
+static void
+serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout)
+{
+ if (ch_type != serial_current_type)
+ {
+ fprintf_unfiltered (stream, "\n%c ", ch_type);
+ serial_current_type = ch_type;
+ }
+
+ if (serial_logbase != logbase_ascii)
+ fputc_unfiltered (' ', stream);
+
+ switch (ch)
+ {
+ case SERIAL_TIMEOUT:
+ fprintf_unfiltered (stream, "<Timeout: %d seconds>", timeout);
+ return;
+ case SERIAL_ERROR:
+ fprintf_unfiltered (stream, "<Error: %s>", safe_strerror (errno));
+ return;
+ case SERIAL_EOF:
+ fputs_unfiltered ("<Eof>", stream);
+ return;
+ case SERIAL_BREAK:
+ fputs_unfiltered ("<Break>", stream);
+ return;
+ default:
+ if (serial_logbase == logbase_hex)
+ fprintf_unfiltered (stream, "%02x", ch & 0xff);
+ else if (serial_logbase == logbase_octal)
+ fprintf_unfiltered (stream, "%03o", ch & 0xff);
+ else
+ switch (ch)
+ {
+ case '\\':
+ fputs_unfiltered ("\\\\", stream);
+ break;
+ case '\b':
+ fputs_unfiltered ("\\b", stream);
+ break;
+ case '\f':
+ fputs_unfiltered ("\\f", stream);
+ break;
+ case '\n':
+ fputs_unfiltered ("\\n", stream);
+ break;
+ case '\r':
+ fputs_unfiltered ("\\r", stream);
+ break;
+ case '\t':
+ fputs_unfiltered ("\\t", stream);
+ break;
+ case '\v':
+ fputs_unfiltered ("\\v", stream);
+ break;
+ default:
+ fprintf_unfiltered (stream, isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF);
+ break;
+ }
+ }
+}
+
+void
+serial_log_command (const char *cmd)
+{
+ if (!serial_logfp)
+ return;
+
+ serial_current_type = 'c';
+
+ fputs_unfiltered ("\nc ", serial_logfp);
+ fputs_unfiltered (cmd, serial_logfp);
+
+ /* Make sure that the log file is as up-to-date as possible,
+ in case we are getting ready to dump core or something. */
+ gdb_flush (serial_logfp);
+}
+
+
+static struct serial_ops *
+serial_interface_lookup (char *name)
+{
+ struct serial_ops *ops;
+
+ for (ops = serial_ops_list; ops; ops = ops->next)
+ if (strcmp (name, ops->name) == 0)
+ return ops;
+
+ return NULL;
+}
+
+void
+serial_add_interface (struct serial_ops *optable)
+{
+ optable->next = serial_ops_list;
+ serial_ops_list = optable;
+}
+
+/* Open up a device or a network socket, depending upon the syntax of NAME. */
+
+struct serial *
+serial_open (const char *name)
+{
+ struct serial *scb;
+ struct serial_ops *ops;
+ const char *open_name = name;
+
+ for (scb = scb_base; scb; scb = scb->next)
+ if (scb->name && strcmp (scb->name, name) == 0)
+ {
+ scb->refcnt++;
+ return scb;
+ }
+
+ if (strcmp (name, "pc") == 0)
+ ops = serial_interface_lookup ("pc");
+ else if (strchr (name, ':'))
+ ops = serial_interface_lookup ("tcp");
+ else if (strncmp (name, "lpt", 3) == 0)
+ ops = serial_interface_lookup ("parallel");
+ else if (strncmp (name, "|", 1) == 0)
+ {
+ ops = serial_interface_lookup ("pipe");
+ open_name = name + 1; /* discard ``|'' */
+ }
+ else
+ ops = serial_interface_lookup ("hardwire");
+
+ if (!ops)
+ return NULL;
+
+ scb = XMALLOC (struct serial);
+
+ scb->ops = ops;
+
+ scb->bufcnt = 0;
+ scb->bufp = scb->buf;
+
+ if (scb->ops->open (scb, open_name))
+ {
+ xfree (scb);
+ return NULL;
+ }
+
+ scb->name = xstrdup (name);
+ scb->next = scb_base;
+ scb->refcnt = 1;
+ scb->debug_p = 0;
+ scb->async_state = 0;
+ scb->async_handler = NULL;
+ scb->async_context = NULL;
+ scb_base = scb;
+
+ last_serial_opened = scb;
+
+ if (serial_logfile != NULL)
+ {
+ serial_logfp = gdb_fopen (serial_logfile, "w");
+ if (serial_logfp == NULL)
+ perror_with_name (serial_logfile);
+ }
+
+ return scb;
+}
+
+struct serial *
+serial_fdopen (const int fd)
+{
+ struct serial *scb;
+ struct serial_ops *ops;
+
+ for (scb = scb_base; scb; scb = scb->next)
+ if (scb->fd == fd)
+ {
+ scb->refcnt++;
+ return scb;
+ }
+
+ ops = serial_interface_lookup ("hardwire");
+
+ if (!ops)
+ return NULL;
+
+ scb = XMALLOC (struct serial);
+
+ scb->ops = ops;
+
+ scb->bufcnt = 0;
+ scb->bufp = scb->buf;
+
+ scb->fd = fd;
+
+ scb->name = NULL;
+ scb->next = scb_base;
+ scb->refcnt = 1;
+ scb->debug_p = 0;
+ scb->async_state = 0;
+ scb->async_handler = NULL;
+ scb->async_context = NULL;
+ scb_base = scb;
+
+ last_serial_opened = scb;
+
+ return scb;
+}
+
+static void
+do_serial_close (struct serial *scb, int really_close)
+{
+ struct serial *tmp_scb;
+
+ last_serial_opened = NULL;
+
+ if (serial_logfp)
+ {
+ fputs_unfiltered ("\nEnd of log\n", serial_logfp);
+ serial_current_type = 0;
+
+ /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
+ ui_file_delete (serial_logfp);
+ serial_logfp = NULL;
+ }
+
+/* This is bogus. It's not our fault if you pass us a bad scb...! Rob, you
+ should fix your code instead. */
+
+ if (!scb)
+ return;
+
+ scb->refcnt--;
+ if (scb->refcnt > 0)
+ return;
+
+ /* ensure that the FD has been taken out of async mode */
+ if (scb->async_handler != NULL)
+ serial_async (scb, NULL, NULL);
+
+ if (really_close)
+ scb->ops->close (scb);
+
+ if (scb->name)
+ xfree (scb->name);
+
+ if (scb_base == scb)
+ scb_base = scb_base->next;
+ else
+ for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
+ {
+ if (tmp_scb->next != scb)
+ continue;
+
+ tmp_scb->next = tmp_scb->next->next;
+ break;
+ }
+
+ xfree (scb);
+}
+
+void
+serial_close (struct serial *scb)
+{
+ do_serial_close (scb, 1);
+}
+
+void
+serial_un_fdopen (struct serial *scb)
+{
+ do_serial_close (scb, 0);
+}
+
+int
+serial_readchar (struct serial *scb, int timeout)
+{
+ int ch;
+
+ /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
+ code is finished. */
+ if (0 && serial_is_async_p (scb) && timeout < 0)
+ internal_error (__FILE__, __LINE__,
+ "serial_readchar: blocking read in async mode");
+
+ ch = scb->ops->readchar (scb, timeout);
+ if (serial_logfp != NULL)
+ {
+ serial_logchar (serial_logfp, 'r', ch, timeout);
+
+ /* Make sure that the log file is as up-to-date as possible,
+ in case we are getting ready to dump core or something. */
+ gdb_flush (serial_logfp);
+ }
+ if (serial_debug_p (scb))
+ {
+ fprintf_unfiltered (gdb_stdlog, "[");
+ serial_logchar (gdb_stdlog, 'r', ch, timeout);
+ fprintf_unfiltered (gdb_stdlog, "]");
+ gdb_flush (gdb_stdlog);
+ }
+
+ return (ch);
+}
+
+int
+serial_write (struct serial *scb, const char *str, int len)
+{
+ if (serial_logfp != NULL)
+ {
+ int count;
+
+ for (count = 0; count < len; count++)
+ serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0);
+
+ /* Make sure that the log file is as up-to-date as possible,
+ in case we are getting ready to dump core or something. */
+ gdb_flush (serial_logfp);
+ }
+
+ return (scb->ops->write (scb, str, len));
+}
+
+void
+serial_printf (struct serial *desc, const char *format,...)
+{
+ va_list args;
+ char *buf;
+ va_start (args, format);
+
+ xvasprintf (&buf, format, args);
+ serial_write (desc, buf, strlen (buf));
+
+ xfree (buf);
+ va_end (args);
+}
+
+int
+serial_drain_output (struct serial *scb)
+{
+ return scb->ops->drain_output (scb);
+}
+
+int
+serial_flush_output (struct serial *scb)
+{
+ return scb->ops->flush_output (scb);
+}
+
+int
+serial_flush_input (struct serial *scb)
+{
+ return scb->ops->flush_input (scb);
+}
+
+int
+serial_send_break (struct serial *scb)
+{
+ if (serial_logfp != NULL)
+ serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
+
+ return (scb->ops->send_break (scb));
+}
+
+void
+serial_raw (struct serial *scb)
+{
+ scb->ops->go_raw (scb);
+}
+
+serial_ttystate
+serial_get_tty_state (struct serial *scb)
+{
+ return scb->ops->get_tty_state (scb);
+}
+
+int
+serial_set_tty_state (struct serial *scb, serial_ttystate ttystate)
+{
+ return scb->ops->set_tty_state (scb, ttystate);
+}
+
+void
+serial_print_tty_state (struct serial *scb,
+ serial_ttystate ttystate,
+ struct ui_file *stream)
+{
+ scb->ops->print_tty_state (scb, ttystate, stream);
+}
+
+int
+serial_noflush_set_tty_state (struct serial *scb,
+ serial_ttystate new_ttystate,
+ serial_ttystate old_ttystate)
+{
+ return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
+}
+
+int
+serial_setbaudrate (struct serial *scb, int rate)
+{
+ return scb->ops->setbaudrate (scb, rate);
+}
+
+int
+serial_setstopbits (struct serial *scb, int num)
+{
+ return scb->ops->setstopbits (scb, num);
+}
+
+int
+serial_can_async_p (struct serial *scb)
+{
+ return (scb->ops->async != NULL);
+}
+
+int
+serial_is_async_p (struct serial *scb)
+{
+ return (scb->ops->async != NULL) && (scb->async_handler != NULL);
+}
+
+void
+serial_async (struct serial *scb,
+ serial_event_ftype *handler,
+ void *context)
+{
+ /* Only change mode if there is a need. */
+ if ((scb->async_handler == NULL)
+ != (handler == NULL))
+ scb->ops->async (scb, handler != NULL);
+ scb->async_handler = handler;
+ scb->async_context = context;
+}
+
+int
+deprecated_serial_fd (struct serial *scb)
+{
+ /* FIXME: should this output a warning that deprecated code is being
+ called? */
+ if (scb->fd < 0)
+ {
+ internal_error (__FILE__, __LINE__,
+ "serial: FD not valid");
+ }
+ return scb->fd; /* sigh */
+}
+
+void
+serial_debug (struct serial *scb, int debug_p)
+{
+ scb->debug_p = debug_p;
+}
+
+int
+serial_debug_p (struct serial *scb)
+{
+ return scb->debug_p || global_serial_debug_p;
+}
+
+
+#if 0
+/* The connect command is #if 0 because I hadn't thought of an elegant
+ way to wait for I/O on two `struct serial *'s simultaneously. Two
+ solutions came to mind:
+
+ 1) Fork, and have have one fork handle the to user direction,
+ and have the other hand the to target direction. This
+ obviously won't cut it for MSDOS.
+
+ 2) Use something like select. This assumes that stdin and
+ the target side can both be waited on via the same
+ mechanism. This may not be true for DOS, if GDB is
+ talking to the target via a TCP socket.
+ -grossman, 8 Jun 93 */
+
+/* Connect the user directly to the remote system. This command acts just like
+ the 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
+
+static struct serial *tty_desc; /* Controlling terminal */
+
+static void
+cleanup_tty (serial_ttystate ttystate)
+{
+ printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
+ serial_set_tty_state (tty_desc, ttystate);
+ xfree (ttystate);
+ serial_close (tty_desc);
+}
+
+static void
+connect_command (char *args, int fromtty)
+{
+ int c;
+ char cur_esc = 0;
+ serial_ttystate ttystate;
+ struct serial *port_desc; /* TTY port */
+
+ dont_repeat ();
+
+ if (args)
+ fprintf_unfiltered (gdb_stderr, "This command takes no args. They have been ignored.\n");
+
+ printf_unfiltered ("[Entering connect mode. Use ~. or ~^D to escape]\n");
+
+ tty_desc = serial_fdopen (0);
+ port_desc = last_serial_opened;
+
+ ttystate = serial_get_tty_state (tty_desc);
+
+ serial_raw (tty_desc);
+ serial_raw (port_desc);
+
+ make_cleanup (cleanup_tty, ttystate);
+
+ while (1)
+ {
+ int mask;
+
+ mask = serial_wait_2 (tty_desc, port_desc, -1);
+
+ if (mask & 2)
+ { /* tty input */
+ char cx;
+
+ while (1)
+ {
+ c = serial_readchar (tty_desc, 0);
+
+ if (c == SERIAL_TIMEOUT)
+ break;
+
+ if (c < 0)
+ perror_with_name ("connect");
+
+ cx = c;
+ serial_write (port_desc, &cx, 1);
+
+ switch (cur_esc)
+ {
+ case 0:
+ if (c == '\r')
+ cur_esc = c;
+ break;
+ case '\r':
+ if (c == '~')
+ cur_esc = c;
+ else
+ cur_esc = 0;
+ break;
+ case '~':
+ if (c == '.' || c == '\004')
+ return;
+ else
+ cur_esc = 0;
+ }
+ }
+ }
+
+ if (mask & 1)
+ { /* Port input */
+ char cx;
+
+ while (1)
+ {
+ c = serial_readchar (port_desc, 0);
+
+ if (c == SERIAL_TIMEOUT)
+ break;
+
+ if (c < 0)
+ perror_with_name ("connect");
+
+ cx = c;
+
+ serial_write (tty_desc, &cx, 1);
+ }
+ }
+ }
+}
+#endif /* 0 */
+
+/* Serial set/show framework. */
+
+static struct cmd_list_element *serial_set_cmdlist;
+static struct cmd_list_element *serial_show_cmdlist;
+
+static void
+serial_set_cmd (char *args, int from_tty)
+{
+ printf_unfiltered ("\"set serial\" must be followed by the name of a command.\n");
+ help_list (serial_set_cmdlist, "set serial ", -1, gdb_stdout);
+}
+
+static void
+serial_show_cmd (char *args, int from_tty)
+{
+ cmd_show_list (serial_show_cmdlist, from_tty, "");
+}
+
+
+void
+_initialize_serial (void)
+{
+#if 0
+ add_com ("connect", class_obscure, connect_command,
+ "Connect the terminal directly up to the command monitor.\n\
+Use <CR>~. or <CR>~^D to break out.");
+#endif /* 0 */
+
+ add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, "\
+Set default serial/parallel port configuration.",
+ &serial_set_cmdlist, "set serial ",
+ 0/*allow-unknown*/,
+ &setlist);
+
+ add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, "\
+Show default serial/parallel port configuration.",
+ &serial_show_cmdlist, "show serial ",
+ 0/*allow-unknown*/,
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("remotelogfile", no_class,
+ var_filename, (char *) &serial_logfile,
+ "Set filename for remote session recording.\n\
+This file is used to record the remote session for future playback\n\
+by gdbserver.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_enum_cmd ("remotelogbase", no_class,
+ logbase_enums, &serial_logbase,
+ "Set numerical base for remote session logging",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (add_set_cmd ("serial",
+ class_maintenance,
+ var_zinteger,
+ (char *)&global_serial_debug_p,
+ "Set serial debugging.\n\
+When non-zero, serial port debugging is enabled.", &setdebuglist),
+ &showdebuglist);
+}
diff --git a/gdb/serial.h b/gdb/serial.h
new file mode 100644
index 00000000000..97d68f32a04
--- /dev/null
+++ b/gdb/serial.h
@@ -0,0 +1,241 @@
+/* Remote serial support interface definitions for GDB, the GNU Debugger.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000
+ 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. */
+
+#ifndef SERIAL_H
+#define SERIAL_H
+
+/* For most routines, if a failure is indicated, then errno should be
+ examined. */
+
+/* Terminal state pointer. This is specific to each type of
+ interface. */
+
+typedef void *serial_ttystate;
+struct serial;
+
+/* Try to open NAME. Returns a new `struct serial *' on success, NULL
+ on failure. Note that some open calls can block and, if possible,
+ should be written to be non-blocking, with calls to ui_look_hook
+ so they can be cancelled. An async interface for open could be
+ added to GDB if necessary. */
+
+extern struct serial *serial_open (const char *name);
+
+/* Open a new serial stream using a file handle. */
+
+extern struct serial *serial_fdopen (const int fd);
+
+/* Push out all buffers, close the device and destroy SCB. */
+
+extern void serial_close (struct serial *scb);
+
+/* Push out all buffers and destroy SCB without closing the device. */
+
+extern void serial_un_fdopen (struct serial *scb);
+
+/* Read one char from the serial device with TIMEOUT seconds to wait
+ or -1 to wait forever. Use timeout of 0 to effect a poll.
+ Infinite waits are not permitted. Returns unsigned char if ok, else
+ one of the following codes. Note that all error return-codes are
+ guaranteed to be < 0. */
+
+enum serial_rc {
+ SERIAL_ERROR = -1, /* General error. */
+ SERIAL_TIMEOUT = -2, /* Timeout or data-not-ready during read.
+ Unfortunately, through ui_loop_hook(), this
+ can also be a QUIT indication. */
+ SERIAL_EOF = -3 /* General end-of-file or remote target
+ connection closed, indication. Includes
+ things like the line dropping dead. */
+};
+
+extern int serial_readchar (struct serial *scb, int timeout);
+
+/* Write LEN chars from STRING to the port SCB. Returns 0 for
+ success, non-zero for failure. */
+
+extern int serial_write (struct serial *scb, const char *str, int len);
+
+/* Write a printf style string onto the serial port. */
+
+extern void serial_printf (struct serial *desc, const char *,...) ATTR_FORMAT (printf, 2, 3);
+
+/* Allow pending output to drain. */
+
+extern int serial_drain_output (struct serial *);
+
+/* Flush (discard) pending output. Might also flush input (if this
+ system can't flush only output). */
+
+extern int serial_flush_output (struct serial *);
+
+/* Flush pending input. Might also flush output (if this system can't
+ flush only input). */
+
+extern int serial_flush_input (struct serial *);
+
+/* Send a break between 0.25 and 0.5 seconds long. */
+
+extern int serial_send_break (struct serial *scb);
+
+/* Turn the port into raw mode. */
+
+extern void serial_raw (struct serial *scb);
+
+/* Return a pointer to a newly malloc'd ttystate containing the state
+ of the tty. */
+
+extern serial_ttystate serial_get_tty_state (struct serial *scb);
+
+/* Set the state of the tty to TTYSTATE. The change is immediate.
+ When changing to or from raw mode, input might be discarded.
+ Returns 0 for success, negative value for error (in which case
+ errno contains the error). */
+
+extern int serial_set_tty_state (struct serial *scb, serial_ttystate ttystate);
+
+/* printf_filtered a user-comprehensible description of ttystate on
+ the specified STREAM. FIXME: At present this sends output to the
+ default stream - GDB_STDOUT. */
+
+extern void serial_print_tty_state (struct serial *scb, serial_ttystate ttystate, struct ui_file *);
+
+/* Set the tty state to NEW_TTYSTATE, where OLD_TTYSTATE is the
+ current state (generally obtained from a recent call to
+ serial_get_tty_state()), but be careful not to discard any input.
+ This means that we never switch in or out of raw mode, even if
+ NEW_TTYSTATE specifies a switch. */
+
+extern int serial_noflush_set_tty_state (struct serial *scb, serial_ttystate new_ttystate, serial_ttystate old_ttystate);
+
+/* Set the baudrate to the decimal value supplied. Returns 0 for
+ success, -1 for failure. */
+
+extern int serial_setbaudrate (struct serial *scb, int rate);
+
+/* Set the number of stop bits to the value specified. Returns 0 for
+ success, -1 for failure. */
+
+#define SERIAL_1_STOPBITS 1
+#define SERIAL_1_AND_A_HALF_STOPBITS 2 /* 1.5 bits, snicker... */
+#define SERIAL_2_STOPBITS 3
+
+extern int serial_setstopbits (struct serial *scb, int num);
+
+/* Asynchronous serial interface: */
+
+/* Can the serial device support asynchronous mode? */
+
+extern int serial_can_async_p (struct serial *scb);
+
+/* Has the serial device been put in asynchronous mode? */
+
+extern int serial_is_async_p (struct serial *scb);
+
+/* For ASYNC enabled devices, register a callback and enable
+ asynchronous mode. To disable asynchronous mode, register a NULL
+ callback. */
+
+typedef void (serial_event_ftype) (struct serial *scb, void *context);
+extern void serial_async (struct serial *scb, serial_event_ftype *handler, void *context);
+
+/* Provide direct access to the underlying FD (if any) used to
+ implement the serial device. This interface is clearly
+ deprecated. Will call internal_error() if the operation isn't
+ applicable to the current serial device. */
+
+extern int deprecated_serial_fd (struct serial *scb);
+
+/* Trace/debug mechanism.
+
+ serial_debug() enables/disables internal debugging.
+ serial_debug_p() indicates the current debug state. */
+
+extern void serial_debug (struct serial *scb, int debug_p);
+
+extern int serial_debug_p (struct serial *scb);
+
+
+/* Details of an instance of a serial object */
+
+struct serial
+ {
+ int fd; /* File descriptor */
+ struct serial_ops *ops; /* Function vector */
+ void *state; /* Local context info for open FD */
+ serial_ttystate ttystate; /* Not used (yet) */
+ int bufcnt; /* Amount of data remaining in receive
+ buffer. -ve for sticky errors. */
+ unsigned char *bufp; /* Current byte */
+ unsigned char buf[BUFSIZ]; /* Da buffer itself */
+ int current_timeout; /* (ser-unix.c termio{,s} only), last
+ value of VTIME */
+ int timeout_remaining; /* (ser-unix.c termio{,s} only), we
+ still need to wait for this many
+ more seconds. */
+ char *name; /* The name of the device or host */
+ struct serial *next; /* Pointer to the next `struct serial *' */
+ int refcnt; /* Number of pointers to this block */
+ int debug_p; /* Trace this serial devices operation. */
+ int async_state; /* Async internal state. */
+ void *async_context; /* Async event thread's context */
+ serial_event_ftype *async_handler;/* Async event handler */
+ };
+
+struct serial_ops
+ {
+ char *name;
+ struct serial_ops *next;
+ int (*open) (struct serial *, const char *name);
+ void (*close) (struct serial *);
+ int (*readchar) (struct serial *, int timeout);
+ int (*write) (struct serial *, const char *str, int len);
+ /* Discard pending output */
+ int (*flush_output) (struct serial *);
+ /* Discard pending input */
+ int (*flush_input) (struct serial *);
+ int (*send_break) (struct serial *);
+ void (*go_raw) (struct serial *);
+ serial_ttystate (*get_tty_state) (struct serial *);
+ int (*set_tty_state) (struct serial *, serial_ttystate);
+ void (*print_tty_state) (struct serial *, serial_ttystate,
+ struct ui_file *);
+ int (*noflush_set_tty_state) (struct serial *, serial_ttystate,
+ serial_ttystate);
+ int (*setbaudrate) (struct serial *, int rate);
+ int (*setstopbits) (struct serial *, int num);
+ /* Wait for output to drain */
+ int (*drain_output) (struct serial *);
+ /* Change the serial device into/out of asynchronous mode, call
+ the specified function when ever there is something
+ interesting. */
+ void (*async) (struct serial *scb, int async_p);
+ };
+
+/* Add a new serial interface to the interface list */
+
+extern void serial_add_interface (struct serial_ops * optable);
+
+/* File in which to record the remote debugging session */
+
+extern void serial_log_command (const char *);
+
+#endif /* SERIAL_H */
diff --git a/gdb/sh-stub.c b/gdb/sh-stub.c
new file mode 100644
index 00000000000..b6be51f2ab2
--- /dev/null
+++ b/gdb/sh-stub.c
@@ -0,0 +1,1583 @@
+/* sh-stub.c -- debugging stub for the Hitachi-SH.
+
+ NOTE!! This code has to be compiled with optimization, otherwise the
+ function inlining which generates the exception handlers won't work.
+
+*/
+
+/* This is originally based on an m68k software stub written by Glenn
+ Engel at HP, but has changed quite a bit.
+
+ Modifications for the SH by Ben Lee and Steve Chamberlain
+
+*/
+
+/****************************************************************************
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ HP offers the following for use in the public domain. HP makes no
+ warranty with regard to the software or it's performance and the
+ user accepts the software "AS IS" with all faults.
+
+ HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+ TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+
+/* Remote communication protocol.
+
+ A debug packet whose contents are <data>
+ is encapsulated for transmission in the form:
+
+ $ <data> # CSUM1 CSUM2
+
+ <data> must be ASCII alphanumeric and cannot include characters
+ '$' or '#'. If <data> starts with two characters followed by
+ ':', then the existing stubs interpret this as a sequence number.
+
+ CSUM1 and CSUM2 are ascii hex representation of an 8-bit
+ checksum of <data>, the most significant nibble is sent first.
+ the hex digits 0-9,a-f are used.
+
+ Receiver responds with:
+
+ + - if CSUM is correct and ready for next packet
+ - - if CSUM is incorrect
+
+ <data> is as follows:
+ All values are encoded in ascii hex digits.
+
+ Request Packet
+
+ read registers g
+ reply XX....X Each byte of register data
+ is described by two hex digits.
+ Registers are in the internal order
+ for GDB, and the bytes in a register
+ are in the same order the machine uses.
+ or ENN for an error.
+
+ write regs GXX..XX Each byte of register data
+ is described by two hex digits.
+ reply OK for success
+ ENN for an error
+
+ write reg Pn...=r... Write register n... with value r...,
+ which contains two hex digits for each
+ byte in the register (target byte
+ order).
+ reply OK for success
+ ENN for an error
+ (not supported by all stubs).
+
+ read mem mAA..AA,LLLL AA..AA is address, LLLL is length.
+ reply XX..XX XX..XX is mem contents
+ Can be fewer bytes than requested
+ if able to read only part of the data.
+ or ENN NN is errno
+
+ write mem MAA..AA,LLLL:XX..XX
+ AA..AA is address,
+ LLLL is number of bytes,
+ XX..XX is data
+ reply OK for success
+ ENN for an error (this includes the case
+ where only part of the data was
+ written).
+
+ cont cAA..AA AA..AA is address to resume
+ If AA..AA is omitted,
+ resume at same address.
+
+ step sAA..AA AA..AA is address to resume
+ If AA..AA is omitted,
+ resume at same address.
+
+ last signal ? Reply the current reason for stopping.
+ This is the same reply as is generated
+ for step or cont : SAA where AA is the
+ signal number.
+
+ There is no immediate reply to step or cont.
+ The reply comes when the machine stops.
+ It is SAA AA is the "signal number"
+
+ or... TAAn...:r...;n:r...;n...:r...;
+ AA = signal number
+ n... = register number
+ r... = register contents
+ or... WAA The process exited, and AA is
+ the exit status. This is only
+ applicable for certains sorts of
+ targets.
+ kill request k
+
+ toggle debug d toggle debug flag (see 386 & 68k stubs)
+ reset r reset -- see sparc stub.
+ reserved <other> On other requests, the stub should
+ ignore the request and send an empty
+ response ($#<checksum>). This way
+ we can extend the protocol and GDB
+ can tell whether the stub it is
+ talking to uses the old or the new.
+ search tAA:PP,MM Search backwards starting at address
+ AA for a match with pattern PP and
+ mask MM. PP and MM are 4 bytes.
+ Not supported by all stubs.
+
+ general query qXXXX Request info about XXXX.
+ general set QXXXX=yyyy Set value of XXXX to yyyy.
+ query sect offs qOffsets Get section offsets. Reply is
+ Text=xxx;Data=yyy;Bss=zzz
+ console output Otext Send text to stdout. Only comes from
+ remote target.
+
+ Responses can be run-length encoded to save space. A '*' means that
+ the next character is an ASCII encoding giving a repeat count which
+ stands for that many repititions of the character preceding the '*'.
+ The encoding is n+29, yielding a printable character where n >=3
+ (which is where rle starts to win). Don't use an n > 126.
+
+ So
+ "0* " means the same as "0000". */
+
+#include <string.h>
+#include <setjmp.h>
+
+/* Hitachi SH architecture instruction encoding masks */
+
+#define COND_BR_MASK 0xff00
+#define UCOND_DBR_MASK 0xe000
+#define UCOND_RBR_MASK 0xf0df
+#define TRAPA_MASK 0xff00
+
+#define COND_DISP 0x00ff
+#define UCOND_DISP 0x0fff
+#define UCOND_REG 0x0f00
+
+/* Hitachi SH instruction opcodes */
+
+#define BF_INSTR 0x8b00
+#define BT_INSTR 0x8900
+#define BRA_INSTR 0xa000
+#define BSR_INSTR 0xb000
+#define JMP_INSTR 0x402b
+#define JSR_INSTR 0x400b
+#define RTS_INSTR 0x000b
+#define RTE_INSTR 0x002b
+#define TRAPA_INSTR 0xc300
+#define SSTEP_INSTR 0xc3ff
+
+/* Hitachi SH processor register masks */
+
+#define T_BIT_MASK 0x0001
+
+/*
+ * BUFMAX defines the maximum number of characters in inbound/outbound
+ * buffers. At least NUMREGBYTES*2 are needed for register packets.
+ */
+#define BUFMAX 1024
+
+/*
+ * Number of bytes for registers
+ */
+#define NUMREGBYTES 112 /* 92 */
+
+/*
+ * typedef
+ */
+typedef void (*Function) ();
+
+/*
+ * Forward declarations
+ */
+
+static int hex (char);
+static char *mem2hex (char *, char *, int);
+static char *hex2mem (char *, char *, int);
+static int hexToInt (char **, int *);
+static unsigned char *getpacket (void);
+static void putpacket (char *);
+static void handle_buserror (void);
+static int computeSignal (int exceptionVector);
+static void handle_exception (int exceptionVector);
+void init_serial();
+
+void putDebugChar (char);
+char getDebugChar (void);
+
+/* These are in the file but in asm statements so the compiler can't see them */
+void catch_exception_4 (void);
+void catch_exception_6 (void);
+void catch_exception_9 (void);
+void catch_exception_10 (void);
+void catch_exception_11 (void);
+void catch_exception_32 (void);
+void catch_exception_33 (void);
+void catch_exception_255 (void);
+
+
+
+#define catch_exception_random catch_exception_255 /* Treat all odd ones like 255 */
+
+void breakpoint (void);
+
+
+#define init_stack_size 8*1024 /* if you change this you should also modify BINIT */
+#define stub_stack_size 8*1024
+
+int init_stack[init_stack_size] __attribute__ ((section ("stack"))) = {0};
+int stub_stack[stub_stack_size] __attribute__ ((section ("stack"))) = {0};
+
+
+void INIT ();
+void BINIT ();
+
+#define CPU_BUS_ERROR_VEC 9
+#define DMA_BUS_ERROR_VEC 10
+#define NMI_VEC 11
+#define INVALID_INSN_VEC 4
+#define INVALID_SLOT_VEC 6
+#define TRAP_VEC 32
+#define IO_VEC 33
+#define USER_VEC 255
+
+
+
+char in_nmi; /* Set when handling an NMI, so we don't reenter */
+int dofault; /* Non zero, bus errors will raise exception */
+
+int *stub_sp;
+
+/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
+int remote_debug;
+
+/* jump buffer used for setjmp/longjmp */
+jmp_buf remcomEnv;
+
+enum regnames
+ {
+ R0, R1, R2, R3, R4, R5, R6, R7,
+ R8, R9, R10, R11, R12, R13, R14,
+ R15, PC, PR, GBR, VBR, MACH, MACL, SR,
+ TICKS, STALLS, CYCLES, INSTS, PLR
+ };
+
+typedef struct
+ {
+ short *memAddr;
+ short oldInstr;
+ }
+stepData;
+
+int registers[NUMREGBYTES / 4];
+stepData instrBuffer;
+char stepped;
+static const char hexchars[] = "0123456789abcdef";
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+char highhex(int x)
+{
+ return hexchars[(x >> 4) & 0xf];
+}
+
+char lowhex(int x)
+{
+ return hexchars[x & 0xf];
+}
+
+/*
+ * Assembly macros
+ */
+
+#define BREAKPOINT() asm("trapa #0x20"::);
+
+
+/*
+ * Routines to handle hex data
+ */
+
+static int
+hex (char ch)
+{
+ if ((ch >= 'a') && (ch <= 'f'))
+ return (ch - 'a' + 10);
+ if ((ch >= '0') && (ch <= '9'))
+ return (ch - '0');
+ if ((ch >= 'A') && (ch <= 'F'))
+ return (ch - 'A' + 10);
+ return (-1);
+}
+
+/* convert the memory, pointed to by mem into hex, placing result in buf */
+/* return a pointer to the last char put in buf (null) */
+static char *
+mem2hex (char *mem, char *buf, int count)
+{
+ int i;
+ int ch;
+ for (i = 0; i < count; i++)
+ {
+ ch = *mem++;
+ *buf++ = highhex (ch);
+ *buf++ = lowhex (ch);
+ }
+ *buf = 0;
+ return (buf);
+}
+
+/* convert the hex array pointed to by buf into binary, to be placed in mem */
+/* return a pointer to the character after the last byte written */
+
+static char *
+hex2mem (char *buf, char *mem, int count)
+{
+ int i;
+ unsigned char ch;
+ for (i = 0; i < count; i++)
+ {
+ ch = hex (*buf++) << 4;
+ ch = ch + hex (*buf++);
+ *mem++ = ch;
+ }
+ return (mem);
+}
+
+/**********************************************/
+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
+/* RETURN NUMBER OF CHARS PROCESSED */
+/**********************************************/
+static int
+hexToInt (char **ptr, int *intValue)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+
+ while (**ptr)
+ {
+ hexValue = hex (**ptr);
+ if (hexValue >= 0)
+ {
+ *intValue = (*intValue << 4) | hexValue;
+ numChars++;
+ }
+ else
+ break;
+
+ (*ptr)++;
+ }
+
+ return (numChars);
+}
+
+/*
+ * Routines to get and put packets
+ */
+
+/* scan for the sequence $<data>#<checksum> */
+
+char *
+getpacket (void)
+{
+ unsigned char *buffer = &remcomInBuffer[0];
+ unsigned char checksum;
+ unsigned char xmitcsum;
+ int count;
+ char ch;
+
+ while (1)
+ {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = getDebugChar ()) != '$')
+ ;
+
+retry:
+ checksum = 0;
+ xmitcsum = -1;
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX)
+ {
+ ch = getDebugChar ();
+ if (ch == '$')
+ goto retry;
+ if (ch == '#')
+ break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+ buffer[count] = 0;
+
+ if (ch == '#')
+ {
+ ch = getDebugChar ();
+ xmitcsum = hex (ch) << 4;
+ ch = getDebugChar ();
+ xmitcsum += hex (ch);
+
+ if (checksum != xmitcsum)
+ {
+ putDebugChar ('-'); /* failed checksum */
+ }
+ else
+ {
+ putDebugChar ('+'); /* successful transfer */
+
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':')
+ {
+ putDebugChar (buffer[0]);
+ putDebugChar (buffer[1]);
+
+ return &buffer[3];
+ }
+
+ return &buffer[0];
+ }
+ }
+ }
+}
+
+
+/* send the packet in buffer. */
+
+static void
+putpacket (register char *buffer)
+{
+ register int checksum;
+ register int count;
+
+ /* $<packet info>#<checksum>. */
+ do
+ {
+ char *src = buffer;
+ putDebugChar ('$');
+ checksum = 0;
+
+ while (*src)
+ {
+ int runlen;
+
+ /* Do run length encoding */
+ for (runlen = 0; runlen < 100; runlen ++)
+ {
+ if (src[0] != src[runlen])
+ {
+ if (runlen > 3)
+ {
+ int encode;
+ /* Got a useful amount */
+ putDebugChar (*src);
+ checksum += *src;
+ putDebugChar ('*');
+ checksum += '*';
+ checksum += (encode = runlen + ' ' - 4);
+ putDebugChar (encode);
+ src += runlen;
+ }
+ else
+ {
+ putDebugChar (*src);
+ checksum += *src;
+ src++;
+ }
+ break;
+ }
+ }
+ }
+
+
+ putDebugChar ('#');
+ putDebugChar (highhex(checksum));
+ putDebugChar (lowhex(checksum));
+ }
+ while (getDebugChar() != '+');
+}
+
+
+/* a bus error has occurred, perform a longjmp
+ to return execution and allow handling of the error */
+
+void
+handle_buserror (void)
+{
+ longjmp (remcomEnv, 1);
+}
+
+/*
+ * this function takes the SH-1 exception number and attempts to
+ * translate this number into a unix compatible signal value
+ */
+static int
+computeSignal (int exceptionVector)
+{
+ int sigval;
+ switch (exceptionVector)
+ {
+ case INVALID_INSN_VEC:
+ sigval = 4;
+ break;
+ case INVALID_SLOT_VEC:
+ sigval = 4;
+ break;
+ case CPU_BUS_ERROR_VEC:
+ sigval = 10;
+ break;
+ case DMA_BUS_ERROR_VEC:
+ sigval = 10;
+ break;
+ case NMI_VEC:
+ sigval = 2;
+ break;
+
+ case TRAP_VEC:
+ case USER_VEC:
+ sigval = 5;
+ break;
+
+ default:
+ sigval = 7; /* "software generated"*/
+ break;
+ }
+ return (sigval);
+}
+
+void
+doSStep (void)
+{
+ short *instrMem;
+ int displacement;
+ int reg;
+ unsigned short opcode;
+
+ instrMem = (short *) registers[PC];
+
+ opcode = *instrMem;
+ stepped = 1;
+
+ if ((opcode & COND_BR_MASK) == BT_INSTR)
+ {
+ if (registers[SR] & T_BIT_MASK)
+ {
+ displacement = (opcode & COND_DISP) << 1;
+ if (displacement & 0x80)
+ displacement |= 0xffffff00;
+ /*
+ * Remember PC points to second instr.
+ * after PC of branch ... so add 4
+ */
+ instrMem = (short *) (registers[PC] + displacement + 4);
+ }
+ else
+ instrMem += 1;
+ }
+ else if ((opcode & COND_BR_MASK) == BF_INSTR)
+ {
+ if (registers[SR] & T_BIT_MASK)
+ instrMem += 1;
+ else
+ {
+ displacement = (opcode & COND_DISP) << 1;
+ if (displacement & 0x80)
+ displacement |= 0xffffff00;
+ /*
+ * Remember PC points to second instr.
+ * after PC of branch ... so add 4
+ */
+ instrMem = (short *) (registers[PC] + displacement + 4);
+ }
+ }
+ else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
+ {
+ displacement = (opcode & UCOND_DISP) << 1;
+ if (displacement & 0x0800)
+ displacement |= 0xfffff000;
+
+ /*
+ * Remember PC points to second instr.
+ * after PC of branch ... so add 4
+ */
+ instrMem = (short *) (registers[PC] + displacement + 4);
+ }
+ else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
+ {
+ reg = (char) ((opcode & UCOND_REG) >> 8);
+
+ instrMem = (short *) registers[reg];
+ }
+ else if (opcode == RTS_INSTR)
+ instrMem = (short *) registers[PR];
+ else if (opcode == RTE_INSTR)
+ instrMem = (short *) registers[15];
+ else if ((opcode & TRAPA_MASK) == TRAPA_INSTR)
+ instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2);
+ else
+ instrMem += 1;
+
+ instrBuffer.memAddr = instrMem;
+ instrBuffer.oldInstr = *instrMem;
+ *instrMem = SSTEP_INSTR;
+}
+
+
+/* Undo the effect of a previous doSStep. If we single stepped,
+ restore the old instruction. */
+
+void
+undoSStep (void)
+{
+ if (stepped)
+ { short *instrMem;
+ instrMem = instrBuffer.memAddr;
+ *instrMem = instrBuffer.oldInstr;
+ }
+ stepped = 0;
+}
+
+/*
+This function does all exception handling. It only does two things -
+it figures out why it was called and tells gdb, and then it reacts
+to gdb's requests.
+
+When in the monitor mode we talk a human on the serial line rather than gdb.
+
+*/
+
+
+void
+gdb_handle_exception (int exceptionVector)
+{
+ int sigval, stepping;
+ int addr, length;
+ char *ptr;
+
+ /* reply to host that an exception has occurred */
+ sigval = computeSignal (exceptionVector);
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = highhex(sigval);
+ remcomOutBuffer[2] = lowhex (sigval);
+ remcomOutBuffer[3] = 0;
+
+ putpacket (remcomOutBuffer);
+
+ /*
+ * exception 255 indicates a software trap
+ * inserted in place of code ... so back up
+ * PC by one instruction, since this instruction
+ * will later be replaced by its original one!
+ */
+ if (exceptionVector == 0xff
+ || exceptionVector == 0x20)
+ registers[PC] -= 2;
+
+ /*
+ * Do the thangs needed to undo
+ * any stepping we may have done!
+ */
+ undoSStep ();
+
+ stepping = 0;
+
+ while (1)
+ {
+ remcomOutBuffer[0] = 0;
+ ptr = getpacket ();
+
+ switch (*ptr++)
+ {
+ case '?':
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = highhex (sigval);
+ remcomOutBuffer[2] = lowhex (sigval);
+ remcomOutBuffer[3] = 0;
+ break;
+ case 'd':
+ remote_debug = !(remote_debug); /* toggle debug flag */
+ break;
+ case 'g': /* return the value of the CPU registers */
+ mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES);
+ break;
+ case 'G': /* set the value of the CPU registers - return OK */
+ hex2mem (ptr, (char *) registers, NUMREGBYTES);
+ strcpy (remcomOutBuffer, "OK");
+ break;
+
+ /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ case 'm':
+ if (setjmp (remcomEnv) == 0)
+ {
+ dofault = 0;
+ /* TRY, TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
+ if (hexToInt (&ptr, &addr))
+ if (*(ptr++) == ',')
+ if (hexToInt (&ptr, &length))
+ {
+ ptr = 0;
+ mem2hex ((char *) addr, remcomOutBuffer, length);
+ }
+ if (ptr)
+ strcpy (remcomOutBuffer, "E01");
+ }
+ else
+ strcpy (remcomOutBuffer, "E03");
+
+ /* restore handler for bus error */
+ dofault = 1;
+ break;
+
+ /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ case 'M':
+ if (setjmp (remcomEnv) == 0)
+ {
+ dofault = 0;
+
+ /* TRY, TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
+ if (hexToInt (&ptr, &addr))
+ if (*(ptr++) == ',')
+ if (hexToInt (&ptr, &length))
+ if (*(ptr++) == ':')
+ {
+ hex2mem (ptr, (char *) addr, length);
+ ptr = 0;
+ strcpy (remcomOutBuffer, "OK");
+ }
+ if (ptr)
+ strcpy (remcomOutBuffer, "E02");
+ }
+ else
+ strcpy (remcomOutBuffer, "E03");
+
+ /* restore handler for bus error */
+ dofault = 1;
+ break;
+
+ /* cAA..AA Continue at address AA..AA(optional) */
+ /* sAA..AA Step one instruction from AA..AA(optional) */
+ case 's':
+ stepping = 1;
+ case 'c':
+ {
+ /* tRY, to read optional parameter, pc unchanged if no parm */
+ if (hexToInt (&ptr, &addr))
+ registers[PC] = addr;
+
+ if (stepping)
+ doSStep ();
+ }
+ return;
+ break;
+
+ /* kill the program */
+ case 'k': /* do nothing */
+ break;
+ } /* switch */
+
+ /* reply to the request */
+ putpacket (remcomOutBuffer);
+ }
+}
+
+
+#define GDBCOOKIE 0x5ac
+static int ingdbmode;
+/* We've had an exception - choose to go into the monitor or
+ the gdb stub */
+void handle_exception(int exceptionVector)
+{
+#ifdef MONITOR
+ if (ingdbmode != GDBCOOKIE)
+ monitor_handle_exception (exceptionVector);
+ else
+#endif
+ gdb_handle_exception (exceptionVector);
+
+}
+
+void
+gdb_mode (void)
+{
+ ingdbmode = GDBCOOKIE;
+ breakpoint();
+}
+/* This function will generate a breakpoint exception. It is used at the
+ beginning of a program to sync up with a debugger and can be used
+ otherwise as a quick means to stop program execution and "break" into
+ the debugger. */
+
+void
+breakpoint (void)
+{
+ BREAKPOINT ();
+}
+
+/**** Processor-specific routines start here ****/
+/**** Processor-specific routines start here ****/
+/**** Processor-specific routines start here ****/
+
+/* Note:
+
+ The Hitachi SH family uses two exception architectures:
+
+ SH1 & SH2:
+
+ These processors utilize an exception vector table.
+ Exceptions are vectored to the address stored at VBR + (exception_num * 4)
+
+ SH3, SH3E, & SH4:
+
+ These processors have fixed entry points relative to the VBR for
+ various exception classes.
+*/
+
+#if defined(__sh1__) || defined(__sh2__)
+
+/* SH1/SH2 exception vector table format */
+
+typedef struct
+ {
+ void (*func_cold) ();
+ int *stack_cold;
+ void (*func_warm) ();
+ int *stack_warm;
+ void (*(handler[256 - 4])) ();
+ }
+vec_type;
+
+/* vectable is the SH1/SH2 vector table. It must be at address 0
+ or wherever your vbr points. */
+
+const vec_type vectable =
+{
+ &BINIT, /* 0: Power-on reset PC */
+ init_stack + init_stack_size, /* 1: Power-on reset SP */
+ &BINIT, /* 2: Manual reset PC */
+ init_stack + init_stack_size, /* 3: Manual reset SP */
+{
+ &catch_exception_4, /* 4: General invalid instruction */
+ &catch_exception_random, /* 5: Reserved for system */
+ &catch_exception_6, /* 6: Invalid slot instruction */
+ &catch_exception_random, /* 7: Reserved for system */
+ &catch_exception_random, /* 8: Reserved for system */
+ &catch_exception_9, /* 9: CPU bus error */
+ &catch_exception_10, /* 10: DMA bus error */
+ &catch_exception_11, /* 11: NMI */
+ &catch_exception_random, /* 12: User break */
+ &catch_exception_random, /* 13: Reserved for system */
+ &catch_exception_random, /* 14: Reserved for system */
+ &catch_exception_random, /* 15: Reserved for system */
+ &catch_exception_random, /* 16: Reserved for system */
+ &catch_exception_random, /* 17: Reserved for system */
+ &catch_exception_random, /* 18: Reserved for system */
+ &catch_exception_random, /* 19: Reserved for system */
+ &catch_exception_random, /* 20: Reserved for system */
+ &catch_exception_random, /* 21: Reserved for system */
+ &catch_exception_random, /* 22: Reserved for system */
+ &catch_exception_random, /* 23: Reserved for system */
+ &catch_exception_random, /* 24: Reserved for system */
+ &catch_exception_random, /* 25: Reserved for system */
+ &catch_exception_random, /* 26: Reserved for system */
+ &catch_exception_random, /* 27: Reserved for system */
+ &catch_exception_random, /* 28: Reserved for system */
+ &catch_exception_random, /* 29: Reserved for system */
+ &catch_exception_random, /* 30: Reserved for system */
+ &catch_exception_random, /* 31: Reserved for system */
+ &catch_exception_32, /* 32: Trap instr (user vectors) */
+ &catch_exception_33, /* 33: Trap instr (user vectors) */
+ &catch_exception_random, /* 34: Trap instr (user vectors) */
+ &catch_exception_random, /* 35: Trap instr (user vectors) */
+ &catch_exception_random, /* 36: Trap instr (user vectors) */
+ &catch_exception_random, /* 37: Trap instr (user vectors) */
+ &catch_exception_random, /* 38: Trap instr (user vectors) */
+ &catch_exception_random, /* 39: Trap instr (user vectors) */
+ &catch_exception_random, /* 40: Trap instr (user vectors) */
+ &catch_exception_random, /* 41: Trap instr (user vectors) */
+ &catch_exception_random, /* 42: Trap instr (user vectors) */
+ &catch_exception_random, /* 43: Trap instr (user vectors) */
+ &catch_exception_random, /* 44: Trap instr (user vectors) */
+ &catch_exception_random, /* 45: Trap instr (user vectors) */
+ &catch_exception_random, /* 46: Trap instr (user vectors) */
+ &catch_exception_random, /* 47: Trap instr (user vectors) */
+ &catch_exception_random, /* 48: Trap instr (user vectors) */
+ &catch_exception_random, /* 49: Trap instr (user vectors) */
+ &catch_exception_random, /* 50: Trap instr (user vectors) */
+ &catch_exception_random, /* 51: Trap instr (user vectors) */
+ &catch_exception_random, /* 52: Trap instr (user vectors) */
+ &catch_exception_random, /* 53: Trap instr (user vectors) */
+ &catch_exception_random, /* 54: Trap instr (user vectors) */
+ &catch_exception_random, /* 55: Trap instr (user vectors) */
+ &catch_exception_random, /* 56: Trap instr (user vectors) */
+ &catch_exception_random, /* 57: Trap instr (user vectors) */
+ &catch_exception_random, /* 58: Trap instr (user vectors) */
+ &catch_exception_random, /* 59: Trap instr (user vectors) */
+ &catch_exception_random, /* 60: Trap instr (user vectors) */
+ &catch_exception_random, /* 61: Trap instr (user vectors) */
+ &catch_exception_random, /* 62: Trap instr (user vectors) */
+ &catch_exception_random, /* 63: Trap instr (user vectors) */
+ &catch_exception_random, /* 64: IRQ0 */
+ &catch_exception_random, /* 65: IRQ1 */
+ &catch_exception_random, /* 66: IRQ2 */
+ &catch_exception_random, /* 67: IRQ3 */
+ &catch_exception_random, /* 68: IRQ4 */
+ &catch_exception_random, /* 69: IRQ5 */
+ &catch_exception_random, /* 70: IRQ6 */
+ &catch_exception_random, /* 71: IRQ7 */
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_random,
+ &catch_exception_255}};
+
+#define BCR (*(volatile short *)(0x05FFFFA0)) /* Bus control register */
+#define BAS (0x800) /* Byte access select */
+#define WCR1 (*(volatile short *)(0x05ffffA2)) /* Wait state control register */
+
+asm ("_BINIT: mov.l L1,r15");
+asm ("bra _INIT");
+asm ("nop");
+asm ("L1: .long _init_stack + 8*1024*4");
+void
+INIT (void)
+{
+ /* First turn on the ram */
+ WCR1 = 0; /* Never sample wait */
+ BCR = BAS; /* use lowbyte/high byte */
+
+ init_serial();
+
+#ifdef MONITOR
+ reset_hook ();
+#endif
+
+
+ in_nmi = 0;
+ dofault = 1;
+ stepped = 0;
+
+ stub_sp = stub_stack + stub_stack_size;
+ breakpoint ();
+
+ while (1)
+ ;
+}
+
+
+static void sr()
+{
+
+
+ /* Calling Reset does the same as pressing the button */
+ asm (".global _Reset
+ .global _WarmReset
+_Reset:
+_WarmReset:
+ mov.l L_sp,r15
+ bra _INIT
+ nop
+ .align 2
+L_sp: .long _init_stack + 8000");
+
+ asm("saveRegisters:
+ mov.l @(L_reg, pc), r0
+ mov.l @r15+, r1 ! pop R0
+ mov.l r2, @(0x08, r0) ! save R2
+ mov.l r1, @r0 ! save R0
+ mov.l @r15+, r1 ! pop R1
+ mov.l r3, @(0x0c, r0) ! save R3
+ mov.l r1, @(0x04, r0) ! save R1
+ mov.l r4, @(0x10, r0) ! save R4
+ mov.l r5, @(0x14, r0) ! save R5
+ mov.l r6, @(0x18, r0) ! save R6
+ mov.l r7, @(0x1c, r0) ! save R7
+ mov.l r8, @(0x20, r0) ! save R8
+ mov.l r9, @(0x24, r0) ! save R9
+ mov.l r10, @(0x28, r0) ! save R10
+ mov.l r11, @(0x2c, r0) ! save R11
+ mov.l r12, @(0x30, r0) ! save R12
+ mov.l r13, @(0x34, r0) ! save R13
+ mov.l r14, @(0x38, r0) ! save R14
+ mov.l @r15+, r4 ! save arg to handleException
+ add #8, r15 ! hide PC/SR values on stack
+ mov.l r15, @(0x3c, r0) ! save R15
+ add #-8, r15 ! save still needs old SP value
+ add #92, r0 ! readjust register pointer
+ mov r15, r2
+ add #4, r2
+ mov.l @r2, r2 ! R2 has SR
+ mov.l @r15, r1 ! R1 has PC
+ mov.l r2, @-r0 ! save SR
+ sts.l macl, @-r0 ! save MACL
+ sts.l mach, @-r0 ! save MACH
+ stc.l vbr, @-r0 ! save VBR
+ stc.l gbr, @-r0 ! save GBR
+ sts.l pr, @-r0 ! save PR
+ mov.l @(L_stubstack, pc), r2
+ mov.l @(L_hdl_except, pc), r3
+ mov.l @r2, r15
+ jsr @r3
+ mov.l r1, @-r0 ! save PC
+ mov.l @(L_stubstack, pc), r0
+ mov.l @(L_reg, pc), r1
+ bra restoreRegisters
+ mov.l r15, @r0 ! save __stub_stack
+
+ .align 2
+L_reg:
+ .long _registers
+L_stubstack:
+ .long _stub_sp
+L_hdl_except:
+ .long _handle_exception");
+
+}
+
+static void rr()
+{
+asm("
+ .align 2
+ .global _resume
+_resume:
+ mov r4,r1
+restoreRegisters:
+ add #8, r1 ! skip to R2
+ mov.l @r1+, r2 ! restore R2
+ mov.l @r1+, r3 ! restore R3
+ mov.l @r1+, r4 ! restore R4
+ mov.l @r1+, r5 ! restore R5
+ mov.l @r1+, r6 ! restore R6
+ mov.l @r1+, r7 ! restore R7
+ mov.l @r1+, r8 ! restore R8
+ mov.l @r1+, r9 ! restore R9
+ mov.l @r1+, r10 ! restore R10
+ mov.l @r1+, r11 ! restore R11
+ mov.l @r1+, r12 ! restore R12
+ mov.l @r1+, r13 ! restore R13
+ mov.l @r1+, r14 ! restore R14
+ mov.l @r1+, r15 ! restore programs stack
+ mov.l @r1+, r0
+ add #-8, r15 ! uncover PC/SR on stack
+ mov.l r0, @r15 ! restore PC onto stack
+ lds.l @r1+, pr ! restore PR
+ ldc.l @r1+, gbr ! restore GBR
+ ldc.l @r1+, vbr ! restore VBR
+ lds.l @r1+, mach ! restore MACH
+ lds.l @r1+, macl ! restore MACL
+ mov.l @r1, r0
+ add #-88, r1 ! readjust reg pointer to R1
+ mov.l r0, @(4, r15) ! restore SR onto stack+4
+ mov.l r2, @-r15
+ mov.l L_in_nmi, r0
+ mov #0, r2
+ mov.b r2, @r0
+ mov.l @r15+, r2
+ mov.l @r1+, r0 ! restore R0
+ rte
+ mov.l @r1, r1 ! restore R1
+
+");
+}
+
+
+static __inline__ void code_for_catch_exception(int n)
+{
+ asm(" .globl _catch_exception_%O0" : : "i" (n) );
+ asm(" _catch_exception_%O0:" :: "i" (n) );
+
+ asm(" add #-4, r15 ! reserve spot on stack ");
+ asm(" mov.l r1, @-r15 ! push R1 ");
+
+ if (n == NMI_VEC)
+ {
+ /* Special case for NMI - make sure that they don't nest */
+ asm(" mov.l r0, @-r15 ! push R0");
+ asm(" mov.l L_in_nmi, r0");
+ asm(" tas.b @r0 ! Fend off against addtnl NMIs");
+ asm(" bt noNMI");
+ asm(" mov.l @r15+, r0");
+ asm(" mov.l @r15+, r1");
+ asm(" add #4, r15");
+ asm(" rte");
+ asm(" nop");
+ asm(".align 2");
+ asm("L_in_nmi: .long _in_nmi");
+ asm("noNMI:");
+ }
+ else
+ {
+
+ if (n == CPU_BUS_ERROR_VEC)
+ {
+ /* Exception 9 (bus errors) are disasbleable - so that you
+ can probe memory and get zero instead of a fault.
+ Because the vector table may be in ROM we don't revector
+ the interrupt like all the other stubs, we check in here
+ */
+ asm("mov.l L_dofault,r1");
+ asm("mov.l @r1,r1");
+ asm("tst r1,r1");
+ asm("bf faultaway");
+ asm("bsr _handle_buserror");
+ asm(".align 2");
+ asm("L_dofault: .long _dofault");
+ asm("faultaway:");
+ }
+ asm(" mov #15<<4, r1 ");
+ asm(" ldc r1, sr ! disable interrupts ");
+ asm(" mov.l r0, @-r15 ! push R0 ");
+ }
+
+ /* Prepare for saving context, we've already pushed r0 and r1, stick exception number
+ into the frame */
+ asm(" mov r15, r0 ");
+ asm(" add #8, r0 ");
+ asm(" mov %0,r1" :: "i" (n) );
+ asm(" extu.b r1,r1 ");
+ asm(" bra saveRegisters ! save register values ");
+ asm(" mov.l r1, @r0 ! save exception # ");
+}
+
+
+static void
+exceptions (void)
+{
+ code_for_catch_exception (CPU_BUS_ERROR_VEC);
+ code_for_catch_exception (DMA_BUS_ERROR_VEC);
+ code_for_catch_exception (INVALID_INSN_VEC);
+ code_for_catch_exception (INVALID_SLOT_VEC);
+ code_for_catch_exception (NMI_VEC);
+ code_for_catch_exception (TRAP_VEC);
+ code_for_catch_exception (USER_VEC);
+ code_for_catch_exception (IO_VEC);
+}
+
+
+
+
+
+
+/* Support for Serial I/O using on chip uart */
+
+#define SMR0 (*(volatile char *)(0x05FFFEC0)) /* Channel 0 serial mode register */
+#define BRR0 (*(volatile char *)(0x05FFFEC1)) /* Channel 0 bit rate register */
+#define SCR0 (*(volatile char *)(0x05FFFEC2)) /* Channel 0 serial control register */
+#define TDR0 (*(volatile char *)(0x05FFFEC3)) /* Channel 0 transmit data register */
+#define SSR0 (*(volatile char *)(0x05FFFEC4)) /* Channel 0 serial status register */
+#define RDR0 (*(volatile char *)(0x05FFFEC5)) /* Channel 0 receive data register */
+
+#define SMR1 (*(volatile char *)(0x05FFFEC8)) /* Channel 1 serial mode register */
+#define BRR1 (*(volatile char *)(0x05FFFEC9)) /* Channel 1 bit rate register */
+#define SCR1 (*(volatile char *)(0x05FFFECA)) /* Channel 1 serial control register */
+#define TDR1 (*(volatile char *)(0x05FFFECB)) /* Channel 1 transmit data register */
+#define SSR1 (*(volatile char *)(0x05FFFECC)) /* Channel 1 serial status register */
+#define RDR1 (*(volatile char *)(0x05FFFECD)) /* Channel 1 receive data register */
+
+/*
+ * Serial mode register bits
+ */
+
+#define SYNC_MODE 0x80
+#define SEVEN_BIT_DATA 0x40
+#define PARITY_ON 0x20
+#define ODD_PARITY 0x10
+#define STOP_BITS_2 0x08
+#define ENABLE_MULTIP 0x04
+#define PHI_64 0x03
+#define PHI_16 0x02
+#define PHI_4 0x01
+
+/*
+ * Serial control register bits
+ */
+#define SCI_TIE 0x80 /* Transmit interrupt enable */
+#define SCI_RIE 0x40 /* Receive interrupt enable */
+#define SCI_TE 0x20 /* Transmit enable */
+#define SCI_RE 0x10 /* Receive enable */
+#define SCI_MPIE 0x08 /* Multiprocessor interrupt enable */
+#define SCI_TEIE 0x04 /* Transmit end interrupt enable */
+#define SCI_CKE1 0x02 /* Clock enable 1 */
+#define SCI_CKE0 0x01 /* Clock enable 0 */
+
+/*
+ * Serial status register bits
+ */
+#define SCI_TDRE 0x80 /* Transmit data register empty */
+#define SCI_RDRF 0x40 /* Receive data register full */
+#define SCI_ORER 0x20 /* Overrun error */
+#define SCI_FER 0x10 /* Framing error */
+#define SCI_PER 0x08 /* Parity error */
+#define SCI_TEND 0x04 /* Transmit end */
+#define SCI_MPB 0x02 /* Multiprocessor bit */
+#define SCI_MPBT 0x01 /* Multiprocessor bit transfer */
+
+
+/*
+ * Port B IO Register (PBIOR)
+ */
+#define PBIOR (*(volatile char *)(0x05FFFFC6))
+#define PB15IOR 0x8000
+#define PB14IOR 0x4000
+#define PB13IOR 0x2000
+#define PB12IOR 0x1000
+#define PB11IOR 0x0800
+#define PB10IOR 0x0400
+#define PB9IOR 0x0200
+#define PB8IOR 0x0100
+#define PB7IOR 0x0080
+#define PB6IOR 0x0040
+#define PB5IOR 0x0020
+#define PB4IOR 0x0010
+#define PB3IOR 0x0008
+#define PB2IOR 0x0004
+#define PB1IOR 0x0002
+#define PB0IOR 0x0001
+
+/*
+ * Port B Control Register (PBCR1)
+ */
+#define PBCR1 (*(volatile short *)(0x05FFFFCC))
+#define PB15MD1 0x8000
+#define PB15MD0 0x4000
+#define PB14MD1 0x2000
+#define PB14MD0 0x1000
+#define PB13MD1 0x0800
+#define PB13MD0 0x0400
+#define PB12MD1 0x0200
+#define PB12MD0 0x0100
+#define PB11MD1 0x0080
+#define PB11MD0 0x0040
+#define PB10MD1 0x0020
+#define PB10MD0 0x0010
+#define PB9MD1 0x0008
+#define PB9MD0 0x0004
+#define PB8MD1 0x0002
+#define PB8MD0 0x0001
+
+#define PB15MD PB15MD1|PB14MD0
+#define PB14MD PB14MD1|PB14MD0
+#define PB13MD PB13MD1|PB13MD0
+#define PB12MD PB12MD1|PB12MD0
+#define PB11MD PB11MD1|PB11MD0
+#define PB10MD PB10MD1|PB10MD0
+#define PB9MD PB9MD1|PB9MD0
+#define PB8MD PB8MD1|PB8MD0
+
+#define PB_TXD1 PB11MD1
+#define PB_RXD1 PB10MD1
+#define PB_TXD0 PB9MD1
+#define PB_RXD0 PB8MD1
+
+/*
+ * Port B Control Register (PBCR2)
+ */
+#define PBCR2 0x05FFFFCE
+#define PB7MD1 0x8000
+#define PB7MD0 0x4000
+#define PB6MD1 0x2000
+#define PB6MD0 0x1000
+#define PB5MD1 0x0800
+#define PB5MD0 0x0400
+#define PB4MD1 0x0200
+#define PB4MD0 0x0100
+#define PB3MD1 0x0080
+#define PB3MD0 0x0040
+#define PB2MD1 0x0020
+#define PB2MD0 0x0010
+#define PB1MD1 0x0008
+#define PB1MD0 0x0004
+#define PB0MD1 0x0002
+#define PB0MD0 0x0001
+
+#define PB7MD PB7MD1|PB7MD0
+#define PB6MD PB6MD1|PB6MD0
+#define PB5MD PB5MD1|PB5MD0
+#define PB4MD PB4MD1|PB4MD0
+#define PB3MD PB3MD1|PB3MD0
+#define PB2MD PB2MD1|PB2MD0
+#define PB1MD PB1MD1|PB1MD0
+#define PB0MD PB0MD1|PB0MD0
+
+
+#ifdef MHZ
+#define BPS 32 * 9600 * MHZ / ( BAUD * 10)
+#else
+#define BPS 32 /* 9600 for 10 Mhz */
+#endif
+
+void handleError (char theSSR);
+
+void
+nop (void)
+{
+
+}
+void
+init_serial (void)
+{
+ int i;
+
+ /* Clear TE and RE in Channel 1's SCR */
+ SCR1 &= ~(SCI_TE | SCI_RE);
+
+ /* Set communication to be async, 8-bit data, no parity, 1 stop bit and use internal clock */
+
+ SMR1 = 0;
+ BRR1 = BPS;
+
+ SCR1 &= ~(SCI_CKE1 | SCI_CKE0);
+
+ /* let the hardware settle */
+
+ for (i = 0; i < 1000; i++)
+ nop ();
+
+ /* Turn on in and out */
+ SCR1 |= SCI_RE | SCI_TE;
+
+ /* Set the PFC to make RXD1 (pin PB8) an input pin and TXD1 (pin PB9) an output pin */
+ PBCR1 &= ~(PB_TXD1 | PB_RXD1);
+ PBCR1 |= PB_TXD1 | PB_RXD1;
+}
+
+
+int
+getDebugCharReady (void)
+{
+ char mySSR;
+ mySSR = SSR1 & ( SCI_PER | SCI_FER | SCI_ORER );
+ if ( mySSR )
+ handleError ( mySSR );
+ return SSR1 & SCI_RDRF ;
+}
+
+char
+getDebugChar (void)
+{
+ char ch;
+ char mySSR;
+
+ while ( ! getDebugCharReady())
+ ;
+
+ ch = RDR1;
+ SSR1 &= ~SCI_RDRF;
+
+ mySSR = SSR1 & (SCI_PER | SCI_FER | SCI_ORER);
+
+ if (mySSR)
+ handleError (mySSR);
+
+ return ch;
+}
+
+int
+putDebugCharReady (void)
+{
+ return (SSR1 & SCI_TDRE);
+}
+
+void
+putDebugChar (char ch)
+{
+ while (!putDebugCharReady())
+ ;
+
+ /*
+ * Write data into TDR and clear TDRE
+ */
+ TDR1 = ch;
+ SSR1 &= ~SCI_TDRE;
+}
+
+void
+handleError (char theSSR)
+{
+ SSR1 &= ~(SCI_ORER | SCI_PER | SCI_FER);
+}
+
+#endif
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
new file mode 100644
index 00000000000..924b675a276
--- /dev/null
+++ b/gdb/sh-tdep.c
@@ -0,0 +1,4600 @@
+/* Target-dependent code for Hitachi Super-H, for GDB.
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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. */
+
+/*
+ Contributed by Steve Chamberlain
+ sac@cygnus.com
+ */
+
+#include "defs.h"
+#include "frame.h"
+#include "obstack.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "gdbtypes.h"
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "value.h"
+#include "dis-asm.h"
+#include "inferior.h" /* for BEFORE_TEXT_END etc. */
+#include "gdb_string.h"
+#include "arch-utils.h"
+#include "floatformat.h"
+#include "regcache.h"
+#include "doublest.h"
+
+#include "sh-tdep.h"
+
+#include "elf-bfd.h"
+#include "solib-svr4.h"
+
+/* sh64 flags */
+#include "elf/sh.h"
+/* registers numbers shared with the simulator */
+#include "gdb/sim-sh.h"
+
+void (*sh_show_regs) (void);
+CORE_ADDR (*skip_prologue_hard_way) (CORE_ADDR);
+void (*do_pseudo_register) (int);
+
+#define SH_DEFAULT_NUM_REGS 59
+
+/* Define other aspects of the stack frame.
+ we keep a copy of the worked out return pc lying around, since it
+ is a useful bit of info */
+
+struct frame_extra_info
+{
+ CORE_ADDR return_pc;
+ int leaf_function;
+ int f_offset;
+};
+
+static char *
+sh_generic_register_name (int reg_nr)
+{
+ static char *register_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
+ "fpul", "fpscr",
+ "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
+ "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
+ "ssr", "spc",
+ "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
+ "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1",
+ };
+ if (reg_nr < 0)
+ return NULL;
+ if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
+ return NULL;
+ return register_names[reg_nr];
+}
+
+static char *
+sh_sh_register_name (int reg_nr)
+{
+ static char *register_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
+ "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ };
+ if (reg_nr < 0)
+ return NULL;
+ if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
+ return NULL;
+ return register_names[reg_nr];
+}
+
+static char *
+sh_sh3_register_name (int reg_nr)
+{
+ static char *register_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
+ "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "ssr", "spc",
+ "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
+ "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1"
+ };
+ if (reg_nr < 0)
+ return NULL;
+ if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
+ return NULL;
+ return register_names[reg_nr];
+}
+
+static char *
+sh_sh3e_register_name (int reg_nr)
+{
+ static char *register_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
+ "fpul", "fpscr",
+ "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
+ "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
+ "ssr", "spc",
+ "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
+ "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1",
+ };
+ if (reg_nr < 0)
+ return NULL;
+ if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
+ return NULL;
+ return register_names[reg_nr];
+}
+
+static char *
+sh_sh_dsp_register_name (int reg_nr)
+{
+ static char *register_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
+ "", "dsr",
+ "a0g", "a0", "a1g", "a1", "m0", "m1", "x0", "x1",
+ "y0", "y1", "", "", "", "", "", "mod",
+ "", "",
+ "rs", "re", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ };
+ if (reg_nr < 0)
+ return NULL;
+ if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
+ return NULL;
+ return register_names[reg_nr];
+}
+
+static char *
+sh_sh3_dsp_register_name (int reg_nr)
+{
+ static char *register_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
+ "", "dsr",
+ "a0g", "a0", "a1g", "a1", "m0", "m1", "x0", "x1",
+ "y0", "y1", "", "", "", "", "", "mod",
+ "ssr", "spc",
+ "rs", "re", "", "", "", "", "", "",
+ "r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b"
+ "", "", "", "", "", "", "", "",
+ };
+ if (reg_nr < 0)
+ return NULL;
+ if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
+ return NULL;
+ return register_names[reg_nr];
+}
+
+static char *
+sh_sh4_register_name (int reg_nr)
+{
+ static char *register_names[] =
+ {
+ /* general registers 0-15 */
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ /* 16 - 22 */
+ "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
+ /* 23, 24 */
+ "fpul", "fpscr",
+ /* floating point registers 25 - 40 */
+ "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
+ "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
+ /* 41, 42 */
+ "ssr", "spc",
+ /* bank 0 43 - 50 */
+ "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
+ /* bank 1 51 - 58 */
+ "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1",
+ /* double precision (pseudo) 59 - 66 */
+ "dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14",
+ /* vectors (pseudo) 67 - 70 */
+ "fv0", "fv4", "fv8", "fv12",
+ /* FIXME: missing XF 71 - 86 */
+ /* FIXME: missing XD 87 - 94 */
+ };
+ if (reg_nr < 0)
+ return NULL;
+ if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
+ return NULL;
+ return register_names[reg_nr];
+}
+
+static char *
+sh_sh64_register_name (int reg_nr)
+{
+ static char *register_names[] =
+ {
+ /* SH MEDIA MODE (ISA 32) */
+ /* general registers (64-bit) 0-63 */
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
+ "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
+ "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
+ "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63",
+
+ /* pc (64-bit) 64 */
+ "pc",
+
+ /* status reg., saved status reg., saved pc reg. (64-bit) 65-67 */
+ "sr", "ssr", "spc",
+
+ /* target registers (64-bit) 68-75*/
+ "tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7",
+
+ /* floating point state control register (32-bit) 76 */
+ "fpscr",
+
+ /* single precision floating point registers (32-bit) 77-140*/
+ "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
+ "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
+ "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
+ "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31",
+ "fr32", "fr33", "fr34", "fr35", "fr36", "fr37", "fr38", "fr39",
+ "fr40", "fr41", "fr42", "fr43", "fr44", "fr45", "fr46", "fr47",
+ "fr48", "fr49", "fr50", "fr51", "fr52", "fr53", "fr54", "fr55",
+ "fr56", "fr57", "fr58", "fr59", "fr60", "fr61", "fr62", "fr63",
+
+ /* double precision registers (pseudo) 141-172 */
+ "dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14",
+ "dr16", "dr18", "dr20", "dr22", "dr24", "dr26", "dr28", "dr30",
+ "dr32", "dr34", "dr36", "dr38", "dr40", "dr42", "dr44", "dr46",
+ "dr48", "dr50", "dr52", "dr54", "dr56", "dr58", "dr60", "dr62",
+
+ /* floating point pairs (pseudo) 173-204*/
+ "fp0", "fp2", "fp4", "fp6", "fp8", "fp10", "fp12", "fp14",
+ "fp16", "fp18", "fp20", "fp22", "fp24", "fp26", "fp28", "fp30",
+ "fp32", "fp34", "fp36", "fp38", "fp40", "fp42", "fp44", "fp46",
+ "fp48", "fp50", "fp52", "fp54", "fp56", "fp58", "fp60", "fp62",
+
+ /* floating point vectors (4 floating point regs) (pseudo) 205-220*/
+ "fv0", "fv4", "fv8", "fv12", "fv16", "fv20", "fv24", "fv28",
+ "fv32", "fv36", "fv40", "fv44", "fv48", "fv52", "fv56", "fv60",
+
+ /* SH COMPACT MODE (ISA 16) (all pseudo) 221-272*/
+ "r0_c", "r1_c", "r2_c", "r3_c", "r4_c", "r5_c", "r6_c", "r7_c",
+ "r8_c", "r9_c", "r10_c", "r11_c", "r12_c", "r13_c", "r14_c", "r15_c",
+ "pc_c",
+ "gbr_c", "mach_c", "macl_c", "pr_c", "t_c",
+ "fpscr_c", "fpul_c",
+ "fr0_c", "fr1_c", "fr2_c", "fr3_c", "fr4_c", "fr5_c", "fr6_c", "fr7_c",
+ "fr8_c", "fr9_c", "fr10_c", "fr11_c", "fr12_c", "fr13_c", "fr14_c", "fr15_c",
+ "dr0_c", "dr2_c", "dr4_c", "dr6_c", "dr8_c", "dr10_c", "dr12_c", "dr14_c",
+ "fv0_c", "fv4_c", "fv8_c", "fv12_c",
+ /* FIXME!!!! XF0 XF15, XD0 XD14 ?????*/
+ };
+
+ if (reg_nr < 0)
+ return NULL;
+ if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
+ return NULL;
+ return register_names[reg_nr];
+}
+
+#define NUM_PSEUDO_REGS_SH_MEDIA 80
+#define NUM_PSEUDO_REGS_SH_COMPACT 51
+
+static const unsigned char *
+sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+ /* 0xc3c3 is trapa #c3, and it works in big and little endian modes */
+ static unsigned char breakpoint[] = {0xc3, 0xc3};
+
+ *lenptr = sizeof (breakpoint);
+ return breakpoint;
+}
+
+/* Macros and functions for setting and testing a bit in a minimal
+ symbol that marks it as 32-bit function. The MSB of the minimal
+ symbol's "info" field is used for this purpose. This field is
+ already being used to store the symbol size, so the assumption is
+ that the symbol size cannot exceed 2^31.
+
+ ELF_MAKE_MSYMBOL_SPECIAL
+ tests whether an ELF symbol is "special", i.e. refers
+ to a 32-bit function, and sets a "special" bit in a
+ minimal symbol to mark it as a 32-bit function
+ MSYMBOL_IS_SPECIAL tests the "special" bit in a minimal symbol
+ MSYMBOL_SIZE returns the size of the minimal symbol, i.e.
+ the "info" field with the "special" bit masked out */
+
+#define MSYMBOL_IS_SPECIAL(msym) \
+ (((long) MSYMBOL_INFO (msym) & 0x80000000) != 0)
+
+void
+sh64_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
+{
+ if (msym == NULL)
+ return;
+
+ if (((elf_symbol_type *)(sym))->internal_elf_sym.st_other == STO_SH5_ISA32)
+ {
+ MSYMBOL_INFO (msym) = (char *) (((long) MSYMBOL_INFO (msym)) | 0x80000000);
+ SYMBOL_VALUE_ADDRESS (msym) |= 1;
+ }
+}
+
+/* ISA32 (shmedia) function addresses are odd (bit 0 is set). Here
+ are some macros to test, set, or clear bit 0 of addresses. */
+#define IS_ISA32_ADDR(addr) ((addr) & 1)
+#define MAKE_ISA32_ADDR(addr) ((addr) | 1)
+#define UNMAKE_ISA32_ADDR(addr) ((addr) & ~1)
+
+static int
+pc_is_isa32 (bfd_vma memaddr)
+{
+ struct minimal_symbol *sym;
+
+ /* If bit 0 of the address is set, assume this is a
+ ISA32 (shmedia) address. */
+ if (IS_ISA32_ADDR (memaddr))
+ return 1;
+
+ /* A flag indicating that this is a ISA32 function is stored by elfread.c in
+ the high bit of the info field. Use this to decide if the function is
+ ISA16 or ISA32. */
+ sym = lookup_minimal_symbol_by_pc (memaddr);
+ if (sym)
+ return MSYMBOL_IS_SPECIAL (sym);
+ else
+ return 0;
+}
+
+static const unsigned char *
+sh_sh64_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+ /* The BRK instruction for shmedia is
+ 01101111 11110101 11111111 11110000
+ which translates in big endian mode to 0x6f, 0xf5, 0xff, 0xf0
+ and in little endian mode to 0xf0, 0xff, 0xf5, 0x6f */
+
+ /* The BRK instruction for shcompact is
+ 00000000 00111011
+ which translates in big endian mode to 0x0, 0x3b
+ and in little endian mode to 0x3b, 0x0*/
+
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ if (pc_is_isa32 (*pcptr))
+ {
+ static unsigned char big_breakpoint_media[] = {0x6f, 0xf5, 0xff, 0xf0};
+ *pcptr = UNMAKE_ISA32_ADDR (*pcptr);
+ *lenptr = sizeof (big_breakpoint_media);
+ return big_breakpoint_media;
+ }
+ else
+ {
+ static unsigned char big_breakpoint_compact[] = {0x0, 0x3b};
+ *lenptr = sizeof (big_breakpoint_compact);
+ return big_breakpoint_compact;
+ }
+ }
+ else
+ {
+ if (pc_is_isa32 (*pcptr))
+ {
+ static unsigned char little_breakpoint_media[] = {0xf0, 0xff, 0xf5, 0x6f};
+ *pcptr = UNMAKE_ISA32_ADDR (*pcptr);
+ *lenptr = sizeof (little_breakpoint_media);
+ return little_breakpoint_media;
+ }
+ else
+ {
+ static unsigned char little_breakpoint_compact[] = {0x3b, 0x0};
+ *lenptr = sizeof (little_breakpoint_compact);
+ return little_breakpoint_compact;
+ }
+ }
+}
+
+/* Prologue looks like
+ [mov.l <regs>,@-r15]...
+ [sts.l pr,@-r15]
+ [mov.l r14,@-r15]
+ [mov r15,r14]
+
+ Actually it can be more complicated than this. For instance, with
+ newer gcc's:
+
+ mov.l r14,@-r15
+ add #-12,r15
+ mov r15,r14
+ mov r4,r1
+ mov r5,r2
+ mov.l r6,@(4,r14)
+ mov.l r7,@(8,r14)
+ mov.b r1,@r14
+ mov r14,r1
+ mov r14,r1
+ add #2,r1
+ mov.w r2,@r1
+
+ */
+
+/* PTABS/L Rn, TRa 0110101111110001nnnnnnl00aaa0000
+ with l=1 and n = 18 0110101111110001010010100aaa0000 */
+#define IS_PTABSL_R18(x) (((x) & 0xffffff8f) == 0x6bf14a00)
+
+/* STS.L PR,@-r0 0100000000100010
+ r0-4-->r0, PR-->(r0) */
+#define IS_STS_R0(x) ((x) == 0x4022)
+
+/* STS PR, Rm 0000mmmm00101010
+ PR-->Rm */
+#define IS_STS_PR(x) (((x) & 0xf0ff) == 0x2a)
+
+/* MOV.L Rm,@(disp,r15) 00011111mmmmdddd
+ Rm-->(dispx4+r15) */
+#define IS_MOV_TO_R15(x) (((x) & 0xff00) == 0x1f00)
+
+/* MOV.L R14,@(disp,r15) 000111111110dddd
+ R14-->(dispx4+r15) */
+#define IS_MOV_R14(x) (((x) & 0xfff0) == 0x1fe0)
+
+/* ST.Q R14, disp, R18 101011001110dddddddddd0100100000
+ R18-->(dispx8+R14) */
+#define IS_STQ_R18_R14(x) (((x) & 0xfff003ff) == 0xace00120)
+
+/* ST.Q R15, disp, R18 101011001111dddddddddd0100100000
+ R18-->(dispx8+R15) */
+#define IS_STQ_R18_R15(x) (((x) & 0xfff003ff) == 0xacf00120)
+
+/* ST.L R15, disp, R18 101010001111dddddddddd0100100000
+ R18-->(dispx4+R15) */
+#define IS_STL_R18_R15(x) (((x) & 0xfff003ff) == 0xa8f00120)
+
+/* ST.Q R15, disp, R14 1010 1100 1111 dddd dddd dd00 1110 0000
+ R14-->(dispx8+R15) */
+#define IS_STQ_R14_R15(x) (((x) & 0xfff003ff) == 0xacf000e0)
+
+/* ST.L R15, disp, R14 1010 1000 1111 dddd dddd dd00 1110 0000
+ R14-->(dispx4+R15) */
+#define IS_STL_R14_R15(x) (((x) & 0xfff003ff) == 0xa8f000e0)
+
+/* ADDI.L R15,imm,R15 1101 0100 1111 ssss ssss ss00 1111 0000
+ R15 + imm --> R15 */
+#define IS_ADDIL_SP_MEDIA(x) (((x) & 0xfff003ff) == 0xd4f000f0)
+
+/* ADDI R15,imm,R15 1101 0000 1111 ssss ssss ss00 1111 0000
+ R15 + imm --> R15 */
+#define IS_ADDI_SP_MEDIA(x) (((x) & 0xfff003ff) == 0xd0f000f0)
+
+/* ADD.L R15,R63,R14 0000 0000 1111 1000 1111 1100 1110 0000
+ R15 + R63 --> R14 */
+#define IS_ADDL_SP_FP_MEDIA(x) ((x) == 0x00f8fce0)
+
+/* ADD R15,R63,R14 0000 0000 1111 1001 1111 1100 1110 0000
+ R15 + R63 --> R14 */
+#define IS_ADD_SP_FP_MEDIA(x) ((x) == 0x00f9fce0)
+
+#define IS_MOV_SP_FP_MEDIA(x) (IS_ADDL_SP_FP_MEDIA(x) || IS_ADD_SP_FP_MEDIA(x))
+
+/* MOV #imm, R0 1110 0000 ssss ssss
+ #imm-->R0 */
+#define IS_MOV_R0(x) (((x) & 0xff00) == 0xe000)
+
+/* MOV.L @(disp,PC), R0 1101 0000 iiii iiii */
+#define IS_MOVL_R0(x) (((x) & 0xff00) == 0xd000)
+
+/* ADD r15,r0 0011 0000 1111 1100
+ r15+r0-->r0 */
+#define IS_ADD_SP_R0(x) ((x) == 0x30fc)
+
+/* MOV.L R14 @-R0 0010 0000 1110 0110
+ R14-->(R0-4), R0-4-->R0 */
+#define IS_MOV_R14_R0(x) ((x) == 0x20e6)
+
+/* ADD Rm,R63,Rn Rm+R63-->Rn 0000 00mm mmmm 1001 1111 11nn nnnn 0000
+ where Rm is one of r2-r9 which are the argument registers. */
+/* FIXME: Recognize the float and double register moves too! */
+#define IS_MEDIA_IND_ARG_MOV(x) \
+((((x) & 0xfc0ffc0f) == 0x0009fc00) && (((x) & 0x03f00000) >= 0x00200000 && ((x) & 0x03f00000) <= 0x00900000))
+
+/* ST.Q Rn,0,Rm Rm-->Rn+0 1010 11nn nnnn 0000 0000 00mm mmmm 0000
+ or ST.L Rn,0,Rm Rm-->Rn+0 1010 10nn nnnn 0000 0000 00mm mmmm 0000
+ where Rm is one of r2-r9 which are the argument registers. */
+#define IS_MEDIA_ARG_MOV(x) \
+(((((x) & 0xfc0ffc0f) == 0xac000000) || (((x) & 0xfc0ffc0f) == 0xa8000000)) \
+ && (((x) & 0x000003f0) >= 0x00000020 && ((x) & 0x000003f0) <= 0x00000090))
+
+/* ST.B R14,0,Rn Rn-->(R14+0) 1010 0000 1110 0000 0000 00nn nnnn 0000*/
+/* ST.W R14,0,Rn Rn-->(R14+0) 1010 0100 1110 0000 0000 00nn nnnn 0000*/
+/* ST.L R14,0,Rn Rn-->(R14+0) 1010 1000 1110 0000 0000 00nn nnnn 0000*/
+/* FST.S R14,0,FRn Rn-->(R14+0) 1011 0100 1110 0000 0000 00nn nnnn 0000*/
+/* FST.D R14,0,DRn Rn-->(R14+0) 1011 1100 1110 0000 0000 00nn nnnn 0000*/
+#define IS_MEDIA_MOV_TO_R14(x) \
+((((x) & 0xfffffc0f) == 0xa0e00000) \
+|| (((x) & 0xfffffc0f) == 0xa4e00000) \
+|| (((x) & 0xfffffc0f) == 0xa8e00000) \
+|| (((x) & 0xfffffc0f) == 0xb4e00000) \
+|| (((x) & 0xfffffc0f) == 0xbce00000))
+
+/* MOV Rm, Rn Rm-->Rn 0110 nnnn mmmm 0011
+ where Rm is r2-r9 */
+#define IS_COMPACT_IND_ARG_MOV(x) \
+((((x) & 0xf00f) == 0x6003) && (((x) & 0x00f0) >= 0x0020) && (((x) & 0x00f0) <= 0x0090))
+
+/* compact direct arg move!
+ MOV.L Rn, @r14 0010 1110 mmmm 0010 */
+#define IS_COMPACT_ARG_MOV(x) \
+(((((x) & 0xff0f) == 0x2e02) && (((x) & 0x00f0) >= 0x0020) && ((x) & 0x00f0) <= 0x0090))
+
+/* MOV.B Rm, @R14 0010 1110 mmmm 0000
+ MOV.W Rm, @R14 0010 1110 mmmm 0001 */
+#define IS_COMPACT_MOV_TO_R14(x) \
+((((x) & 0xff0f) == 0x2e00) || (((x) & 0xff0f) == 0x2e01))
+
+#define IS_JSR_R0(x) ((x) == 0x400b)
+#define IS_NOP(x) ((x) == 0x0009)
+
+
+/* STS.L PR,@-r15 0100111100100010
+ r15-4-->r15, PR-->(r15) */
+#define IS_STS(x) ((x) == 0x4f22)
+
+/* MOV.L Rm,@-r15 00101111mmmm0110
+ r15-4-->r15, Rm-->(R15) */
+#define IS_PUSH(x) (((x) & 0xff0f) == 0x2f06)
+
+#define GET_PUSHED_REG(x) (((x) >> 4) & 0xf)
+
+/* MOV r15,r14 0110111011110011
+ r15-->r14 */
+#define IS_MOV_SP_FP(x) ((x) == 0x6ef3)
+
+/* ADD #imm,r15 01111111iiiiiiii
+ r15+imm-->r15 */
+#define IS_ADD_SP(x) (((x) & 0xff00) == 0x7f00)
+
+#define IS_MOV_R3(x) (((x) & 0xff00) == 0x1a00)
+#define IS_SHLL_R3(x) ((x) == 0x4300)
+
+/* ADD r3,r15 0011111100111100
+ r15+r3-->r15 */
+#define IS_ADD_R3SP(x) ((x) == 0x3f3c)
+
+/* FMOV.S FRm,@-Rn Rn-4-->Rn, FRm-->(Rn) 1111nnnnmmmm1011
+ FMOV DRm,@-Rn Rn-8-->Rn, DRm-->(Rn) 1111nnnnmmm01011
+ FMOV XDm,@-Rn Rn-8-->Rn, XDm-->(Rn) 1111nnnnmmm11011 */
+#define IS_FMOV(x) (((x) & 0xf00f) == 0xf00b)
+
+/* MOV Rm,Rn Rm-->Rn 0110nnnnmmmm0011
+ MOV.L Rm,@(disp,Rn) Rm-->(dispx4+Rn) 0001nnnnmmmmdddd
+ MOV.L Rm,@Rn Rm-->(Rn) 0010nnnnmmmm0010
+ where Rm is one of r4,r5,r6,r7 which are the argument registers. */
+#define IS_ARG_MOV(x) \
+(((((x) & 0xf00f) == 0x6003) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070)) \
+ || ((((x) & 0xf000) == 0x1000) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070)) \
+ || ((((x) & 0xf00f) == 0x2002) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070)))
+
+/* MOV.L Rm,@(disp,r14) 00011110mmmmdddd
+ Rm-->(dispx4+r14) where Rm is one of r4,r5,r6,r7 */
+#define IS_MOV_TO_R14(x) \
+ ((((x) & 0xff00) == 0x1e) && (((x) & 0x00f0) >= 0x0040 && ((x) & 0x00f0) <= 0x0070))
+
+#define FPSCR_SZ (1 << 20)
+
+/* Skip any prologue before the guts of a function */
+
+/* Skip the prologue using the debug information. If this fails we'll
+ fall back on the 'guess' method below. */
+static CORE_ADDR
+after_prologue (CORE_ADDR pc)
+{
+ struct symtab_and_line sal;
+ CORE_ADDR func_addr, func_end;
+
+ /* If we can not find the symbol in the partial symbol table, then
+ there is no hope we can determine the function's start address
+ with this code. */
+ if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ return 0;
+
+ /* Get the line associated with FUNC_ADDR. */
+ sal = find_pc_line (func_addr, 0);
+
+ /* There are only two cases to consider. First, the end of the source line
+ is within the function bounds. In that case we return the end of the
+ source line. Second is the end of the source line extends beyond the
+ bounds of the current function. We need to use the slow code to
+ examine instructions in that case. */
+ if (sal.end < func_end)
+ return sal.end;
+ else
+ return 0;
+}
+
+/* Here we look at each instruction in the function, and try to guess
+ where the prologue ends. Unfortunately this is not always
+ accurate. */
+static CORE_ADDR
+sh_skip_prologue_hard_way (CORE_ADDR start_pc)
+{
+ CORE_ADDR here, end;
+ int updated_fp = 0;
+
+ if (!start_pc)
+ return 0;
+
+ for (here = start_pc, end = start_pc + (2 * 28); here < end;)
+ {
+ int w = read_memory_integer (here, 2);
+ here += 2;
+ if (IS_FMOV (w) || IS_PUSH (w) || IS_STS (w) || IS_MOV_R3 (w)
+ || IS_ADD_R3SP (w) || IS_ADD_SP (w) || IS_SHLL_R3 (w)
+ || IS_ARG_MOV (w) || IS_MOV_TO_R14 (w))
+ {
+ start_pc = here;
+ }
+ else if (IS_MOV_SP_FP (w))
+ {
+ start_pc = here;
+ updated_fp = 1;
+ }
+ else
+ /* Don't bail out yet, if we are before the copy of sp. */
+ if (updated_fp)
+ break;
+ }
+
+ return start_pc;
+}
+
+static CORE_ADDR
+look_for_args_moves (CORE_ADDR start_pc, int media_mode)
+{
+ CORE_ADDR here, end;
+ int w;
+ int insn_size = (media_mode ? 4 : 2);
+
+ for (here = start_pc, end = start_pc + (insn_size * 28); here < end;)
+ {
+ if (media_mode)
+ {
+ w = read_memory_integer (UNMAKE_ISA32_ADDR (here), insn_size);
+ here += insn_size;
+ if (IS_MEDIA_IND_ARG_MOV (w))
+ {
+ /* This must be followed by a store to r14, so the argument
+ is where the debug info says it is. This can happen after
+ the SP has been saved, unfortunately. */
+
+ int next_insn = read_memory_integer (UNMAKE_ISA32_ADDR (here),
+ insn_size);
+ here += insn_size;
+ if (IS_MEDIA_MOV_TO_R14 (next_insn))
+ start_pc = here;
+ }
+ else if (IS_MEDIA_ARG_MOV (w))
+ {
+ /* These instructions store directly the argument in r14. */
+ start_pc = here;
+ }
+ else
+ break;
+ }
+ else
+ {
+ w = read_memory_integer (here, insn_size);
+ w = w & 0xffff;
+ here += insn_size;
+ if (IS_COMPACT_IND_ARG_MOV (w))
+ {
+ /* This must be followed by a store to r14, so the argument
+ is where the debug info says it is. This can happen after
+ the SP has been saved, unfortunately. */
+
+ int next_insn = 0xffff & read_memory_integer (here, insn_size);
+ here += insn_size;
+ if (IS_COMPACT_MOV_TO_R14 (next_insn))
+ start_pc = here;
+ }
+ else if (IS_COMPACT_ARG_MOV (w))
+ {
+ /* These instructions store directly the argument in r14. */
+ start_pc = here;
+ }
+ else if (IS_MOVL_R0 (w))
+ {
+ /* There is a function that gcc calls to get the arguments
+ passed correctly to the function. Only after this
+ function call the arguments will be found at the place
+ where they are supposed to be. This happens in case the
+ argument has to be stored into a 64-bit register (for
+ instance doubles, long longs). SHcompact doesn't have
+ access to the full 64-bits, so we store the register in
+ stack slot and store the address of the stack slot in
+ the register, then do a call through a wrapper that
+ loads the memory value into the register. A SHcompact
+ callee calls an argument decoder
+ (GCC_shcompact_incoming_args) that stores the 64-bit
+ value in a stack slot and stores the address of the
+ stack slot in the register. GCC thinks the argument is
+ just passed by transparent reference, but this is only
+ true after the argument decoder is called. Such a call
+ needs to be considered part of the prologue. */
+
+ /* This must be followed by a JSR @r0 instruction and by
+ a NOP instruction. After these, the prologue is over! */
+
+ int next_insn = 0xffff & read_memory_integer (here, insn_size);
+ here += insn_size;
+ if (IS_JSR_R0 (next_insn))
+ {
+ next_insn = 0xffff & read_memory_integer (here, insn_size);
+ here += insn_size;
+
+ if (IS_NOP (next_insn))
+ start_pc = here;
+ }
+ }
+ else
+ break;
+ }
+ }
+
+ return start_pc;
+}
+
+static CORE_ADDR
+sh64_skip_prologue_hard_way (CORE_ADDR start_pc)
+{
+ CORE_ADDR here, end;
+ int updated_fp = 0;
+ int insn_size = 4;
+ int media_mode = 1;
+
+ if (!start_pc)
+ return 0;
+
+ if (pc_is_isa32 (start_pc) == 0)
+ {
+ insn_size = 2;
+ media_mode = 0;
+ }
+
+ for (here = start_pc, end = start_pc + (insn_size * 28); here < end;)
+ {
+
+ if (media_mode)
+ {
+ int w = read_memory_integer (UNMAKE_ISA32_ADDR (here), insn_size);
+ here += insn_size;
+ if (IS_STQ_R18_R14 (w) || IS_STQ_R18_R15 (w) || IS_STQ_R14_R15 (w)
+ || IS_STL_R14_R15 (w) || IS_STL_R18_R15 (w)
+ || IS_ADDIL_SP_MEDIA (w) || IS_ADDI_SP_MEDIA (w) || IS_PTABSL_R18 (w))
+ {
+ start_pc = here;
+ }
+ else if (IS_MOV_SP_FP (w) || IS_MOV_SP_FP_MEDIA(w))
+ {
+ start_pc = here;
+ updated_fp = 1;
+ }
+ else
+ if (updated_fp)
+ {
+ /* Don't bail out yet, we may have arguments stored in
+ registers here, according to the debug info, so that
+ gdb can print the frames correctly. */
+ start_pc = look_for_args_moves (here - insn_size, media_mode);
+ break;
+ }
+ }
+ else
+ {
+ int w = 0xffff & read_memory_integer (here, insn_size);
+ here += insn_size;
+
+ if (IS_STS_R0 (w) || IS_STS_PR (w)
+ || IS_MOV_TO_R15 (w) || IS_MOV_R14 (w)
+ || IS_MOV_R0 (w) || IS_ADD_SP_R0 (w) || IS_MOV_R14_R0 (w))
+ {
+ start_pc = here;
+ }
+ else if (IS_MOV_SP_FP (w))
+ {
+ start_pc = here;
+ updated_fp = 1;
+ }
+ else
+ if (updated_fp)
+ {
+ /* Don't bail out yet, we may have arguments stored in
+ registers here, according to the debug info, so that
+ gdb can print the frames correctly. */
+ start_pc = look_for_args_moves (here - insn_size, media_mode);
+ break;
+ }
+ }
+ }
+
+ return start_pc;
+}
+
+static CORE_ADDR
+sh_skip_prologue (CORE_ADDR pc)
+{
+ CORE_ADDR post_prologue_pc;
+
+ /* See if we can determine the end of the prologue via the symbol table.
+ If so, then return either PC, or the PC after the prologue, whichever
+ is greater. */
+ post_prologue_pc = after_prologue (pc);
+
+ /* If after_prologue returned a useful address, then use it. Else
+ fall back on the instruction skipping code. */
+ if (post_prologue_pc != 0)
+ return max (pc, post_prologue_pc);
+ else
+ return (skip_prologue_hard_way (pc));
+}
+
+/* Immediately after a function call, return the saved pc.
+ Can't always go through the frames for this because on some machines
+ the new frame is not set up until the new function executes
+ some instructions.
+
+ The return address is the value saved in the PR register + 4 */
+static CORE_ADDR
+sh_saved_pc_after_call (struct frame_info *frame)
+{
+ return (ADDR_BITS_REMOVE (read_register (gdbarch_tdep (current_gdbarch)->PR_REGNUM)));
+}
+
+/* Should call_function allocate stack space for a struct return? */
+static int
+sh_use_struct_convention (int gcc_p, struct type *type)
+{
+ return (TYPE_LENGTH (type) > 1);
+}
+
+static int
+sh64_use_struct_convention (int gcc_p, struct type *type)
+{
+ return (TYPE_LENGTH (type) > 8);
+}
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function.
+
+ We store structs through a pointer passed in R2 */
+static void
+sh_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ write_register (STRUCT_RETURN_REGNUM, (addr));
+}
+
+/* Disassemble an instruction. */
+static int
+gdb_print_insn_sh (bfd_vma memaddr, disassemble_info *info)
+{
+ info->endian = TARGET_BYTE_ORDER;
+ return print_insn_sh (memaddr, info);
+}
+
+/* Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+
+ For us, the frame address is its stack pointer value, so we look up
+ the function prologue to determine the caller's sp value, and return it. */
+static CORE_ADDR
+sh_frame_chain (struct frame_info *frame)
+{
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ return frame->frame; /* dummy frame same as caller's frame */
+ if (frame->pc && !inside_entry_file (frame->pc))
+ return read_memory_integer (FRAME_FP (frame) + frame->extra_info->f_offset, 4);
+ else
+ return 0;
+}
+
+/* Given a register number RN as it appears in an assembly
+ instruction, find the corresponding register number in the GDB
+ scheme. */
+static int
+translate_insn_rn (int rn, int media_mode)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ /* FIXME: this assumes that the number rn is for a not pseudo
+ register only. */
+ if (media_mode)
+ return rn;
+ else
+ {
+ /* These registers don't have a corresponding compact one. */
+ /* FIXME: This is probably not enough. */
+#if 0
+ if ((rn >= 16 && rn <= 63) || (rn >= 93 && rn <= 140))
+ return rn;
+#endif
+ if (rn >= 0 && rn <= tdep->R0_C_REGNUM)
+ return tdep->R0_C_REGNUM + rn;
+ else
+ return rn;
+ }
+}
+
+static CORE_ADDR
+sh64_frame_chain (struct frame_info *frame)
+{
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ return frame->frame; /* dummy frame same as caller's frame */
+ if (frame->pc && !inside_entry_file (frame->pc))
+ {
+ int media_mode = pc_is_isa32 (frame->pc);
+ int size;
+ if (gdbarch_tdep (current_gdbarch)->sh_abi == SH_ABI_32)
+ size = 4;
+ else
+ size = REGISTER_RAW_SIZE (translate_insn_rn (FP_REGNUM, media_mode));
+ return read_memory_integer (FRAME_FP (frame) + frame->extra_info->f_offset, size);
+ }
+ else
+ return 0;
+}
+
+/* Find REGNUM on the stack. Otherwise, it's in an active register. One thing
+ we might want to do here is to check REGNUM against the clobber mask, and
+ somehow flag it as invalid if it isn't saved on the stack somewhere. This
+ would provide a graceful failure mode when trying to get the value of
+ caller-saves registers for an inner frame. */
+static CORE_ADDR
+sh_find_callers_reg (struct frame_info *fi, int regnum)
+{
+ for (; fi; fi = fi->next)
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ /* When the caller requests PR from the dummy frame, we return PC because
+ that's where the previous routine appears to have done a call from. */
+ return generic_read_register_dummy (fi->pc, fi->frame, regnum);
+ else
+ {
+ FRAME_INIT_SAVED_REGS (fi);
+ if (!fi->pc)
+ return 0;
+ if (fi->saved_regs[regnum] != 0)
+ return read_memory_integer (fi->saved_regs[regnum],
+ REGISTER_RAW_SIZE (regnum));
+ }
+ return read_register (regnum);
+}
+
+static CORE_ADDR
+sh64_get_saved_pr (struct frame_info *fi, int pr_regnum)
+{
+ int media_mode = 0;
+
+ for (; fi; fi = fi->next)
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ /* When the caller requests PR from the dummy frame, we return PC because
+ that's where the previous routine appears to have done a call from. */
+ return generic_read_register_dummy (fi->pc, fi->frame, pr_regnum);
+ else
+ {
+ FRAME_INIT_SAVED_REGS (fi);
+ if (!fi->pc)
+ return 0;
+
+ media_mode = pc_is_isa32 (fi->pc);
+
+ if (fi->saved_regs[pr_regnum] != 0)
+ {
+ int gdb_reg_num = translate_insn_rn (pr_regnum, media_mode);
+ int size = ((gdbarch_tdep (current_gdbarch)->sh_abi == SH_ABI_32)
+ ? 4
+ : REGISTER_RAW_SIZE (gdb_reg_num));
+ return read_memory_integer (fi->saved_regs[pr_regnum], size);
+ }
+ }
+ return read_register (pr_regnum);
+}
+
+/* Put here the code to store, into a struct frame_saved_regs, the
+ addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special: the address we
+ return for it IS the sp for the next frame. */
+static void
+sh_nofp_frame_init_saved_regs (struct frame_info *fi)
+{
+ int *where = (int *) alloca ((NUM_REGS + NUM_PSEUDO_REGS) * sizeof(int));
+ int rn;
+ int have_fp = 0;
+ int depth;
+ int pc;
+ int opc;
+ int insn;
+ int r3_val = 0;
+ char *dummy_regs = generic_find_dummy_frame (fi->pc, fi->frame);
+
+ if (fi->saved_regs == NULL)
+ frame_saved_regs_zalloc (fi);
+ else
+ memset (fi->saved_regs, 0, SIZEOF_FRAME_SAVED_REGS);
+
+ if (dummy_regs)
+ {
+ /* DANGER! This is ONLY going to work if the char buffer format of
+ the saved registers is byte-for-byte identical to the
+ CORE_ADDR regs[NUM_REGS] format used by struct frame_saved_regs! */
+ memcpy (fi->saved_regs, dummy_regs, sizeof (fi->saved_regs));
+ return;
+ }
+
+ fi->extra_info->leaf_function = 1;
+ fi->extra_info->f_offset = 0;
+
+ for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
+ where[rn] = -1;
+
+ depth = 0;
+
+ /* Loop around examining the prologue insns until we find something
+ that does not appear to be part of the prologue. But give up
+ after 20 of them, since we're getting silly then. */
+
+ pc = get_pc_function_start (fi->pc);
+ if (!pc)
+ {
+ fi->pc = 0;
+ return;
+ }
+
+ for (opc = pc + (2 * 28); pc < opc; pc += 2)
+ {
+ insn = read_memory_integer (pc, 2);
+ /* See where the registers will be saved to */
+ if (IS_PUSH (insn))
+ {
+ rn = GET_PUSHED_REG (insn);
+ where[rn] = depth;
+ depth += 4;
+ }
+ else if (IS_STS (insn))
+ {
+ where[gdbarch_tdep (current_gdbarch)->PR_REGNUM] = depth;
+ /* If we're storing the pr then this isn't a leaf */
+ fi->extra_info->leaf_function = 0;
+ depth += 4;
+ }
+ else if (IS_MOV_R3 (insn))
+ {
+ r3_val = ((insn & 0xff) ^ 0x80) - 0x80;
+ }
+ else if (IS_SHLL_R3 (insn))
+ {
+ r3_val <<= 1;
+ }
+ else if (IS_ADD_R3SP (insn))
+ {
+ depth += -r3_val;
+ }
+ else if (IS_ADD_SP (insn))
+ {
+ depth -= ((insn & 0xff) ^ 0x80) - 0x80;
+ }
+ else if (IS_MOV_SP_FP (insn))
+ break;
+#if 0 /* This used to just stop when it found an instruction that
+ was not considered part of the prologue. Now, we just
+ keep going looking for likely instructions. */
+ else
+ break;
+#endif
+ }
+
+ /* Now we know how deep things are, we can work out their addresses */
+
+ for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
+ {
+ if (where[rn] >= 0)
+ {
+ if (rn == FP_REGNUM)
+ have_fp = 1;
+
+ fi->saved_regs[rn] = fi->frame - where[rn] + depth - 4;
+ }
+ else
+ {
+ fi->saved_regs[rn] = 0;
+ }
+ }
+
+ if (have_fp)
+ {
+ fi->saved_regs[SP_REGNUM] = read_memory_integer (fi->saved_regs[FP_REGNUM], 4);
+ }
+ else
+ {
+ fi->saved_regs[SP_REGNUM] = fi->frame - 4;
+ }
+
+ fi->extra_info->f_offset = depth - where[FP_REGNUM] - 4;
+ /* Work out the return pc - either from the saved pr or the pr
+ value */
+}
+
+/* For vectors of 4 floating point registers. */
+static int
+fv_reg_base_num (int fv_regnum)
+{
+ int fp_regnum;
+
+ fp_regnum = FP0_REGNUM +
+ (fv_regnum - gdbarch_tdep (current_gdbarch)->FV0_REGNUM) * 4;
+ return fp_regnum;
+}
+
+/* For double precision floating point registers, i.e 2 fp regs.*/
+static int
+dr_reg_base_num (int dr_regnum)
+{
+ int fp_regnum;
+
+ fp_regnum = FP0_REGNUM +
+ (dr_regnum - gdbarch_tdep (current_gdbarch)->DR0_REGNUM) * 2;
+ return fp_regnum;
+}
+
+/* For pairs of floating point registers */
+static int
+fpp_reg_base_num (int fpp_regnum)
+{
+ int fp_regnum;
+
+ fp_regnum = FP0_REGNUM +
+ (fpp_regnum - gdbarch_tdep (current_gdbarch)->FPP0_REGNUM) * 2;
+ return fp_regnum;
+}
+
+static int
+is_media_pseudo (int rn)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ return (rn >= tdep->DR0_REGNUM
+ && rn <= tdep->FV_LAST_REGNUM);
+}
+
+int
+sh64_get_gdb_regnum (int gcc_regnum, CORE_ADDR pc)
+{
+ return translate_insn_rn (gcc_regnum, pc_is_isa32 (pc));
+}
+
+static int
+sh64_media_reg_base_num (int reg_nr)
+{
+ int base_regnum = -1;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (reg_nr >= tdep->DR0_REGNUM
+ && reg_nr <= tdep->DR_LAST_REGNUM)
+ base_regnum = dr_reg_base_num (reg_nr);
+
+ else if (reg_nr >= tdep->FPP0_REGNUM
+ && reg_nr <= tdep->FPP_LAST_REGNUM)
+ base_regnum = fpp_reg_base_num (reg_nr);
+
+ else if (reg_nr >= tdep->FV0_REGNUM
+ && reg_nr <= tdep->FV_LAST_REGNUM)
+ base_regnum = fv_reg_base_num (reg_nr);
+
+ return base_regnum;
+}
+
+/* *INDENT-OFF* */
+/*
+ SH COMPACT MODE (ISA 16) (all pseudo) 221-272
+ GDB_REGNUM BASE_REGNUM
+ r0_c 221 0
+ r1_c 222 1
+ r2_c 223 2
+ r3_c 224 3
+ r4_c 225 4
+ r5_c 226 5
+ r6_c 227 6
+ r7_c 228 7
+ r8_c 229 8
+ r9_c 230 9
+ r10_c 231 10
+ r11_c 232 11
+ r12_c 233 12
+ r13_c 234 13
+ r14_c 235 14
+ r15_c 236 15
+
+ pc_c 237 64
+ gbr_c 238 16
+ mach_c 239 17
+ macl_c 240 17
+ pr_c 241 18
+ t_c 242 19
+ fpscr_c 243 76
+ fpul_c 244 109
+
+ fr0_c 245 77
+ fr1_c 246 78
+ fr2_c 247 79
+ fr3_c 248 80
+ fr4_c 249 81
+ fr5_c 250 82
+ fr6_c 251 83
+ fr7_c 252 84
+ fr8_c 253 85
+ fr9_c 254 86
+ fr10_c 255 87
+ fr11_c 256 88
+ fr12_c 257 89
+ fr13_c 258 90
+ fr14_c 259 91
+ fr15_c 260 92
+
+ dr0_c 261 77
+ dr2_c 262 79
+ dr4_c 263 81
+ dr6_c 264 83
+ dr8_c 265 85
+ dr10_c 266 87
+ dr12_c 267 89
+ dr14_c 268 91
+
+ fv0_c 269 77
+ fv4_c 270 81
+ fv8_c 271 85
+ fv12_c 272 91
+*/
+/* *INDENT-ON* */
+static int
+sh64_compact_reg_base_num (int reg_nr)
+{
+ int base_regnum = -1;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ /* general register N maps to general register N */
+ if (reg_nr >= tdep->R0_C_REGNUM
+ && reg_nr <= tdep->R_LAST_C_REGNUM)
+ base_regnum = reg_nr - tdep->R0_C_REGNUM;
+
+ /* floating point register N maps to floating point register N */
+ else if (reg_nr >= tdep->FP0_C_REGNUM
+ && reg_nr <= tdep->FP_LAST_C_REGNUM)
+ base_regnum = reg_nr - tdep->FP0_C_REGNUM + FP0_REGNUM;
+
+ /* double prec register N maps to base regnum for double prec register N */
+ else if (reg_nr >= tdep->DR0_C_REGNUM
+ && reg_nr <= tdep->DR_LAST_C_REGNUM)
+ base_regnum = dr_reg_base_num (tdep->DR0_REGNUM
+ + reg_nr - tdep->DR0_C_REGNUM);
+
+ /* vector N maps to base regnum for vector register N */
+ else if (reg_nr >= tdep->FV0_C_REGNUM
+ && reg_nr <= tdep->FV_LAST_C_REGNUM)
+ base_regnum = fv_reg_base_num (tdep->FV0_REGNUM
+ + reg_nr - tdep->FV0_C_REGNUM);
+
+ else if (reg_nr == tdep->PC_C_REGNUM)
+ base_regnum = PC_REGNUM;
+
+ else if (reg_nr == tdep->GBR_C_REGNUM)
+ base_regnum = 16;
+
+ else if (reg_nr == tdep->MACH_C_REGNUM
+ || reg_nr == tdep->MACL_C_REGNUM)
+ base_regnum = 17;
+
+ else if (reg_nr == tdep->PR_C_REGNUM)
+ base_regnum = 18;
+
+ else if (reg_nr == tdep->T_C_REGNUM)
+ base_regnum = 19;
+
+ else if (reg_nr == tdep->FPSCR_C_REGNUM)
+ base_regnum = tdep->FPSCR_REGNUM; /*???? this register is a mess. */
+
+ else if (reg_nr == tdep->FPUL_C_REGNUM)
+ base_regnum = FP0_REGNUM + 32;
+
+ return base_regnum;
+}
+
+/* Given a register number RN (according to the gdb scheme) , return
+ its corresponding architectural register. In media mode, only a
+ subset of the registers is pseudo registers. For compact mode, all
+ the registers are pseudo. */
+static int
+translate_rn_to_arch_reg_num (int rn, int media_mode)
+{
+
+ if (media_mode)
+ {
+ if (!is_media_pseudo (rn))
+ return rn;
+ else
+ return sh64_media_reg_base_num (rn);
+ }
+ else
+ /* All compact registers are pseudo. */
+ return sh64_compact_reg_base_num (rn);
+}
+
+static int
+sign_extend (int value, int bits)
+{
+ value = value & ((1 << bits) - 1);
+ return (value & (1 << (bits - 1))
+ ? value | (~((1 << bits) - 1))
+ : value);
+}
+
+static void
+sh64_nofp_frame_init_saved_regs (struct frame_info *fi)
+{
+ int *where = (int *) alloca ((NUM_REGS + NUM_PSEUDO_REGS) * sizeof (int));
+ int rn;
+ int have_fp = 0;
+ int fp_regnum;
+ int sp_regnum;
+ int depth;
+ int pc;
+ int opc;
+ int insn;
+ int r0_val = 0;
+ int media_mode = 0;
+ int insn_size;
+ int gdb_register_number;
+ int register_number;
+ char *dummy_regs = generic_find_dummy_frame (fi->pc, fi->frame);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (fi->saved_regs == NULL)
+ frame_saved_regs_zalloc (fi);
+ else
+ memset (fi->saved_regs, 0, SIZEOF_FRAME_SAVED_REGS);
+
+ if (dummy_regs)
+ {
+ /* DANGER! This is ONLY going to work if the char buffer format of
+ the saved registers is byte-for-byte identical to the
+ CORE_ADDR regs[NUM_REGS] format used by struct frame_saved_regs! */
+ memcpy (fi->saved_regs, dummy_regs, sizeof (fi->saved_regs));
+ return;
+ }
+
+ fi->extra_info->leaf_function = 1;
+ fi->extra_info->f_offset = 0;
+
+ for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
+ where[rn] = -1;
+
+ depth = 0;
+
+ /* Loop around examining the prologue insns until we find something
+ that does not appear to be part of the prologue. But give up
+ after 20 of them, since we're getting silly then. */
+
+ pc = get_pc_function_start (fi->pc);
+ if (!pc)
+ {
+ fi->pc = 0;
+ return;
+ }
+
+ if (pc_is_isa32 (pc))
+ {
+ media_mode = 1;
+ insn_size = 4;
+ }
+ else
+ {
+ media_mode = 0;
+ insn_size = 2;
+ }
+
+ /* The frame pointer register is general register 14 in shmedia and
+ shcompact modes. In sh compact it is a pseudo register. Same goes
+ for the stack pointer register, which is register 15. */
+ fp_regnum = translate_insn_rn (FP_REGNUM, media_mode);
+ sp_regnum = translate_insn_rn (SP_REGNUM, media_mode);
+
+ for (opc = pc + (insn_size * 28); pc < opc; pc += insn_size)
+ {
+ insn = read_memory_integer (media_mode ? UNMAKE_ISA32_ADDR (pc) : pc,
+ insn_size);
+
+ if (media_mode == 0)
+ {
+ if (IS_STS_PR (insn))
+ {
+ int next_insn = read_memory_integer (pc + insn_size, insn_size);
+ if (IS_MOV_TO_R15 (next_insn))
+ {
+ int reg_nr = tdep->PR_C_REGNUM;
+
+ where[reg_nr] = depth - ((((next_insn & 0xf) ^ 0x8) - 0x8) << 2);
+ fi->extra_info->leaf_function = 0;
+ pc += insn_size;
+ }
+ }
+ else if (IS_MOV_R14 (insn))
+ {
+ where[fp_regnum] = depth - ((((insn & 0xf) ^ 0x8) - 0x8) << 2);
+ }
+
+ else if (IS_MOV_R0 (insn))
+ {
+ /* Put in R0 the offset from SP at which to store some
+ registers. We are interested in this value, because it
+ will tell us where the given registers are stored within
+ the frame. */
+ r0_val = ((insn & 0xff) ^ 0x80) - 0x80;
+ }
+ else if (IS_ADD_SP_R0 (insn))
+ {
+ /* This instruction still prepares r0, but we don't care.
+ We already have the offset in r0_val. */
+ }
+ else if (IS_STS_R0 (insn))
+ {
+ /* Store PR at r0_val-4 from SP. Decrement r0 by 4*/
+ int reg_nr = tdep->PR_C_REGNUM;
+ where[reg_nr] = depth - (r0_val - 4);
+ r0_val -= 4;
+ fi->extra_info->leaf_function = 0;
+ }
+ else if (IS_MOV_R14_R0 (insn))
+ {
+ /* Store R14 at r0_val-4 from SP. Decrement r0 by 4 */
+ where[fp_regnum] = depth - (r0_val - 4);
+ r0_val -= 4;
+ }
+
+ else if (IS_ADD_SP (insn))
+ {
+ depth -= ((insn & 0xff) ^ 0x80) - 0x80;
+ }
+ else if (IS_MOV_SP_FP (insn))
+ break;
+ }
+ else
+ {
+ if (IS_ADDIL_SP_MEDIA (insn)
+ || IS_ADDI_SP_MEDIA (insn))
+ {
+ depth -= sign_extend ((((insn & 0xffc00) ^ 0x80000) - 0x80000) >> 10, 9);
+ }
+
+ else if (IS_STQ_R18_R15 (insn))
+ {
+ where[tdep->PR_REGNUM] =
+ depth - (sign_extend ((insn & 0xffc00) >> 10, 9) << 3);
+ fi->extra_info->leaf_function = 0;
+ }
+
+ else if (IS_STL_R18_R15 (insn))
+ {
+ where[tdep->PR_REGNUM] =
+ depth - (sign_extend ((insn & 0xffc00) >> 10, 9) << 2);
+ fi->extra_info->leaf_function = 0;
+ }
+
+ else if (IS_STQ_R14_R15 (insn))
+ {
+ where[fp_regnum] = depth - (sign_extend ((insn & 0xffc00) >> 10, 9) << 3);
+ }
+
+ else if (IS_STL_R14_R15 (insn))
+ {
+ where[fp_regnum] = depth - (sign_extend ((insn & 0xffc00) >> 10, 9) << 2);
+ }
+
+ else if (IS_MOV_SP_FP_MEDIA (insn))
+ break;
+ }
+ }
+
+ /* Now we know how deep things are, we can work out their addresses. */
+ for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
+ {
+ register_number = translate_rn_to_arch_reg_num (rn, media_mode);
+
+ if (where[rn] >= 0)
+ {
+ if (rn == fp_regnum)
+ have_fp = 1;
+
+ /* Watch out! saved_regs is only for the real registers, and
+ doesn't include space for the pseudo registers. */
+ fi->saved_regs[register_number]= fi->frame - where[rn] + depth;
+
+ }
+ else
+ fi->saved_regs[register_number] = 0;
+ }
+
+ if (have_fp)
+ {
+ /* SP_REGNUM is 15. For shmedia 15 is the real register. For
+ shcompact 15 is the arch register corresponding to the pseudo
+ register r15 which still is the SP register. */
+ /* The place on the stack where fp is stored contains the sp of
+ the caller. */
+ /* Again, saved_registers contains only space for the real registers,
+ so we store in FP_REGNUM position. */
+ int size;
+ if (tdep->sh_abi == SH_ABI_32)
+ size = 4;
+ else
+ size = REGISTER_RAW_SIZE (fp_regnum);
+ fi->saved_regs[sp_regnum] = read_memory_integer (fi->saved_regs[fp_regnum], size);
+ }
+ else
+ fi->saved_regs[sp_regnum] = fi->frame;
+
+ fi->extra_info->f_offset = depth - where[fp_regnum];
+}
+
+static void
+sh_fp_frame_init_saved_regs (struct frame_info *fi)
+{
+ int *where = (int *) alloca ((NUM_REGS + NUM_PSEUDO_REGS) * sizeof (int));
+ int rn;
+ int have_fp = 0;
+ int depth;
+ int pc;
+ int opc;
+ int insn;
+ int r3_val = 0;
+ char *dummy_regs = generic_find_dummy_frame (fi->pc, fi->frame);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (fi->saved_regs == NULL)
+ frame_saved_regs_zalloc (fi);
+ else
+ memset (fi->saved_regs, 0, SIZEOF_FRAME_SAVED_REGS);
+
+ if (dummy_regs)
+ {
+ /* DANGER! This is ONLY going to work if the char buffer format of
+ the saved registers is byte-for-byte identical to the
+ CORE_ADDR regs[NUM_REGS] format used by struct frame_saved_regs! */
+ memcpy (fi->saved_regs, dummy_regs, sizeof (fi->saved_regs));
+ return;
+ }
+
+ fi->extra_info->leaf_function = 1;
+ fi->extra_info->f_offset = 0;
+
+ for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
+ where[rn] = -1;
+
+ depth = 0;
+
+ /* Loop around examining the prologue insns until we find something
+ that does not appear to be part of the prologue. But give up
+ after 20 of them, since we're getting silly then. */
+
+ pc = get_pc_function_start (fi->pc);
+ if (!pc)
+ {
+ fi->pc = 0;
+ return;
+ }
+
+ for (opc = pc + (2 * 28); pc < opc; pc += 2)
+ {
+ insn = read_memory_integer (pc, 2);
+ /* See where the registers will be saved to */
+ if (IS_PUSH (insn))
+ {
+ rn = GET_PUSHED_REG (insn);
+ where[rn] = depth;
+ depth += 4;
+ }
+ else if (IS_STS (insn))
+ {
+ where[tdep->PR_REGNUM] = depth;
+ /* If we're storing the pr then this isn't a leaf */
+ fi->extra_info->leaf_function = 0;
+ depth += 4;
+ }
+ else if (IS_MOV_R3 (insn))
+ {
+ r3_val = ((insn & 0xff) ^ 0x80) - 0x80;
+ }
+ else if (IS_SHLL_R3 (insn))
+ {
+ r3_val <<= 1;
+ }
+ else if (IS_ADD_R3SP (insn))
+ {
+ depth += -r3_val;
+ }
+ else if (IS_ADD_SP (insn))
+ {
+ depth -= ((insn & 0xff) ^ 0x80) - 0x80;
+ }
+ else if (IS_FMOV (insn))
+ {
+ if (read_register (tdep->FPSCR_REGNUM) & FPSCR_SZ)
+ {
+ depth += 8;
+ }
+ else
+ {
+ depth += 4;
+ }
+ }
+ else if (IS_MOV_SP_FP (insn))
+ break;
+#if 0 /* This used to just stop when it found an instruction that
+ was not considered part of the prologue. Now, we just
+ keep going looking for likely instructions. */
+ else
+ break;
+#endif
+ }
+
+ /* Now we know how deep things are, we can work out their addresses */
+
+ for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
+ {
+ if (where[rn] >= 0)
+ {
+ if (rn == FP_REGNUM)
+ have_fp = 1;
+
+ fi->saved_regs[rn] = fi->frame - where[rn] + depth - 4;
+ }
+ else
+ {
+ fi->saved_regs[rn] = 0;
+ }
+ }
+
+ if (have_fp)
+ {
+ fi->saved_regs[SP_REGNUM] =
+ read_memory_integer (fi->saved_regs[FP_REGNUM], 4);
+ }
+ else
+ {
+ fi->saved_regs[SP_REGNUM] = fi->frame - 4;
+ }
+
+ fi->extra_info->f_offset = depth - where[FP_REGNUM] - 4;
+ /* Work out the return pc - either from the saved pr or the pr
+ value */
+}
+
+/* Initialize the extra info saved in a FRAME */
+static void
+sh_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+
+ fi->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ /* We need to setup fi->frame here because run_stack_dummy gets it wrong
+ by assuming it's always FP. */
+ fi->frame = generic_read_register_dummy (fi->pc, fi->frame,
+ SP_REGNUM);
+ fi->extra_info->return_pc = generic_read_register_dummy (fi->pc,
+ fi->frame,
+ PC_REGNUM);
+ fi->extra_info->f_offset = -(CALL_DUMMY_LENGTH + 4);
+ fi->extra_info->leaf_function = 0;
+ return;
+ }
+ else
+ {
+ FRAME_INIT_SAVED_REGS (fi);
+ fi->extra_info->return_pc =
+ sh_find_callers_reg (fi, gdbarch_tdep (current_gdbarch)->PR_REGNUM);
+ }
+}
+
+static void
+sh64_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ int media_mode = pc_is_isa32 (fi->pc);
+
+ fi->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ /* We need to setup fi->frame here because run_stack_dummy gets it wrong
+ by assuming it's always FP. */
+ fi->frame = generic_read_register_dummy (fi->pc, fi->frame,
+ SP_REGNUM);
+ fi->extra_info->return_pc =
+ generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
+ fi->extra_info->f_offset = -(CALL_DUMMY_LENGTH + 4);
+ fi->extra_info->leaf_function = 0;
+ return;
+ }
+ else
+ {
+ FRAME_INIT_SAVED_REGS (fi);
+ fi->extra_info->return_pc =
+ sh64_get_saved_pr (fi, gdbarch_tdep (current_gdbarch)->PR_REGNUM);
+ }
+}
+
+void
+sh64_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp,
+ struct frame_info *frame, int regnum,
+ enum lval_type *lval)
+{
+ int media_mode;
+ int live_regnum = regnum;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (!target_has_registers)
+ error ("No registers.");
+
+ /* Normal systems don't optimize out things with register numbers. */
+ if (optimized != NULL)
+ *optimized = 0;
+
+ if (addrp) /* default assumption: not found in memory */
+ *addrp = 0;
+
+ if (raw_buffer)
+ memset (raw_buffer, 0, sizeof (raw_buffer));
+
+ /* We must do this here, before the following while loop changes
+ frame, and makes it NULL. If this is a media register number,
+ but we are in compact mode, it will become the corresponding
+ compact pseudo register. If there is no corresponding compact
+ pseudo-register what do we do?*/
+ media_mode = pc_is_isa32 (frame->pc);
+ live_regnum = translate_insn_rn (regnum, media_mode);
+
+ /* Note: since the current frame's registers could only have been
+ saved by frames INTERIOR TO the current frame, we skip examining
+ the current frame itself: otherwise, we would be getting the
+ previous frame's registers which were saved by the current frame. */
+
+ while (frame && ((frame = frame->next) != NULL))
+ {
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ {
+ if (lval) /* found it in a CALL_DUMMY frame */
+ *lval = not_lval;
+ if (raw_buffer)
+ memcpy (raw_buffer,
+ generic_find_dummy_frame (frame->pc, frame->frame) +
+ REGISTER_BYTE (regnum),
+ REGISTER_RAW_SIZE (regnum));
+ return;
+ }
+
+ FRAME_INIT_SAVED_REGS (frame);
+ if (frame->saved_regs != NULL
+ && frame->saved_regs[regnum] != 0)
+ {
+ if (lval) /* found it saved on the stack */
+ *lval = lval_memory;
+ if (regnum == SP_REGNUM)
+ {
+ if (raw_buffer) /* SP register treated specially */
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
+ frame->saved_regs[regnum]);
+ }
+ else
+ { /* any other register */
+
+ if (addrp)
+ *addrp = frame->saved_regs[regnum];
+ if (raw_buffer)
+ {
+ int size;
+ if (tdep->sh_abi == SH_ABI_32
+ && (live_regnum == FP_REGNUM
+ || live_regnum == tdep->PR_REGNUM))
+ size = 4;
+ else
+ size = REGISTER_RAW_SIZE (live_regnum);
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
+ read_memory (frame->saved_regs[regnum], raw_buffer, size);
+ else
+ read_memory (frame->saved_regs[regnum],
+ raw_buffer
+ + REGISTER_RAW_SIZE (live_regnum)
+ - size,
+ size);
+ }
+ }
+ return;
+ }
+ }
+
+ /* If we get thru the loop to this point, it means the register was
+ not saved in any frame. Return the actual live-register value. */
+
+ if (lval) /* found it in a live register */
+ *lval = lval_register;
+ if (addrp)
+ *addrp = REGISTER_BYTE (live_regnum);
+ if (raw_buffer)
+ read_register_gen (live_regnum, raw_buffer);
+}
+
+/* Extract from an array REGBUF containing the (raw) register state
+ the address in which a function should return its structure value,
+ as a CORE_ADDR (or an expression that can be used as one). */
+static CORE_ADDR
+sh_extract_struct_value_address (char *regbuf)
+{
+ return (extract_address ((regbuf), REGISTER_RAW_SIZE (0)));
+}
+
+static CORE_ADDR
+sh64_extract_struct_value_address (char *regbuf)
+{
+ return (extract_address ((regbuf + REGISTER_BYTE (STRUCT_RETURN_REGNUM)),
+ REGISTER_RAW_SIZE (STRUCT_RETURN_REGNUM)));
+}
+
+static CORE_ADDR
+sh_frame_saved_pc (struct frame_info *frame)
+{
+ return ((frame)->extra_info->return_pc);
+}
+
+/* Discard from the stack the innermost frame,
+ restoring all saved registers. */
+static void
+sh_pop_frame (void)
+{
+ register struct frame_info *frame = get_current_frame ();
+ register CORE_ADDR fp;
+ register int regnum;
+
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ generic_pop_dummy_frame ();
+ else
+ {
+ fp = FRAME_FP (frame);
+ FRAME_INIT_SAVED_REGS (frame);
+
+ /* Copy regs from where they were saved in the frame */
+ for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+ if (frame->saved_regs[regnum])
+ write_register (regnum,
+ read_memory_integer (frame->saved_regs[regnum], 4));
+
+ write_register (PC_REGNUM, frame->extra_info->return_pc);
+ write_register (SP_REGNUM, fp + 4);
+ }
+ flush_cached_frames ();
+}
+
+/* Used in the 'return' command. */
+static void
+sh64_pop_frame (void)
+{
+ register struct frame_info *frame = get_current_frame ();
+ register CORE_ADDR fp;
+ register int regnum;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ int media_mode = pc_is_isa32 (frame->pc);
+
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ generic_pop_dummy_frame ();
+ else
+ {
+ fp = FRAME_FP (frame);
+ FRAME_INIT_SAVED_REGS (frame);
+
+ /* Copy regs from where they were saved in the frame */
+ for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+ if (frame->saved_regs[regnum])
+ {
+ int size;
+ if (tdep->sh_abi == SH_ABI_32
+ && (regnum == FP_REGNUM
+ || regnum == tdep->PR_REGNUM))
+ size = 4;
+ else
+ size = REGISTER_RAW_SIZE (translate_insn_rn (regnum,
+ media_mode));
+ write_register (regnum,
+ read_memory_integer (frame->saved_regs[regnum],
+ size));
+ }
+
+ write_register (PC_REGNUM, frame->extra_info->return_pc);
+ write_register (SP_REGNUM, fp + 8);
+ }
+ flush_cached_frames ();
+}
+
+/* Function: push_arguments
+ Setup the function arguments for calling a function in the inferior.
+
+ On the Hitachi SH architecture, there are four registers (R4 to R7)
+ which are dedicated for passing function arguments. Up to the first
+ four arguments (depending on size) may go into these registers.
+ The rest go on the stack.
+
+ Arguments that are smaller than 4 bytes will still take up a whole
+ register or a whole 32-bit word on the stack, and will be
+ right-justified in the register or the stack word. This includes
+ chars, shorts, and small aggregate types.
+
+ Arguments that are larger than 4 bytes may be split between two or
+ more registers. If there are not enough registers free, an argument
+ may be passed partly in a register (or registers), and partly on the
+ stack. This includes doubles, long longs, and larger aggregates.
+ As far as I know, there is no upper limit to the size of aggregates
+ that will be passed in this way; in other words, the convention of
+ passing a pointer to a large aggregate instead of a copy is not used.
+
+ An exceptional case exists for struct arguments (and possibly other
+ aggregates such as arrays) if the size is larger than 4 bytes but
+ not a multiple of 4 bytes. In this case the argument is never split
+ between the registers and the stack, but instead is copied in its
+ entirety onto the stack, AND also copied into as many registers as
+ there is room for. In other words, space in registers permitting,
+ two copies of the same argument are passed in. As far as I can tell,
+ only the one on the stack is used, although that may be a function
+ of the level of compiler optimization. I suspect this is a compiler
+ bug. Arguments of these odd sizes are left-justified within the
+ word (as opposed to arguments smaller than 4 bytes, which are
+ right-justified).
+
+ If the function is to return an aggregate type such as a struct, it
+ is either returned in the normal return value register R0 (if its
+ size is no greater than one byte), or else the caller must allocate
+ space into which the callee will copy the return value (if the size
+ is greater than one byte). In this case, a pointer to the return
+ value location is passed into the callee in register R2, which does
+ not displace any of the other arguments passed in via registers R4
+ to R7. */
+
+static CORE_ADDR
+sh_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int stack_offset, stack_alloc;
+ int argreg;
+ int argnum;
+ struct type *type;
+ CORE_ADDR regval;
+ char *val;
+ char valbuf[4];
+ int len;
+ int odd_sized_struct;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ /* first force sp to a 4-byte alignment */
+ sp = sp & ~3;
+
+ /* The "struct return pointer" pseudo-argument has its own dedicated
+ register */
+ if (struct_return)
+ write_register (STRUCT_RETURN_REGNUM, struct_addr);
+
+ /* Now make sure there's space on the stack */
+ for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
+ stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3);
+ sp -= stack_alloc; /* make room on stack for args */
+
+ /* Now load as many as possible of the first arguments into
+ registers, and push the rest onto the stack. There are 16 bytes
+ in four registers available. Loop thru args from first to last. */
+
+ argreg = tdep->ARG0_REGNUM;
+ for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
+ {
+ type = VALUE_TYPE (args[argnum]);
+ len = TYPE_LENGTH (type);
+ memset (valbuf, 0, sizeof (valbuf));
+ if (len < 4)
+ {
+ /* value gets right-justified in the register or stack word */
+ memcpy (valbuf + (4 - len),
+ (char *) VALUE_CONTENTS (args[argnum]), len);
+ val = valbuf;
+ }
+ else
+ val = (char *) VALUE_CONTENTS (args[argnum]);
+
+ if (len > 4 && (len & 3) != 0)
+ odd_sized_struct = 1; /* such structs go entirely on stack */
+ else
+ odd_sized_struct = 0;
+ while (len > 0)
+ {
+ if (argreg > tdep->ARGLAST_REGNUM
+ || odd_sized_struct)
+ {
+ /* must go on the stack */
+ write_memory (sp + stack_offset, val, 4);
+ stack_offset += 4;
+ }
+ /* NOTE WELL!!!!! This is not an "else if" clause!!!
+ That's because some *&^%$ things get passed on the stack
+ AND in the registers! */
+ if (argreg <= tdep->ARGLAST_REGNUM)
+ {
+ /* there's room in a register */
+ regval = extract_address (val, REGISTER_RAW_SIZE (argreg));
+ write_register (argreg++, regval);
+ }
+ /* Store the value 4 bytes at a time. This means that things
+ larger than 4 bytes may go partly in registers and partly
+ on the stack. */
+ len -= REGISTER_RAW_SIZE (argreg);
+ val += REGISTER_RAW_SIZE (argreg);
+ }
+ }
+ return sp;
+}
+
+/* R2-R9 for integer types and integer equivalent (char, pointers) and
+ non-scalar (struct, union) elements (even if the elements are
+ floats).
+ FR0-FR11 for single precision floating point (float)
+ DR0-DR10 for double precision floating point (double)
+
+ If a float is argument number 3 (for instance) and arguments number
+ 1,2, and 4 are integer, the mapping will be:
+ arg1 -->R2, arg2 --> R3, arg3 -->FR0, arg4 --> R5. I.e. R4 is not used.
+
+ If a float is argument number 10 (for instance) and arguments number
+ 1 through 10 are integer, the mapping will be:
+ arg1->R2, arg2->R3, arg3->R4, arg4->R5, arg5->R6, arg6->R7, arg7->R8,
+ arg8->R9, arg9->(0,SP)stack(8-byte aligned), arg10->FR0, arg11->stack(16,SP).
+ I.e. there is hole in the stack.
+
+ Different rules apply for variable arguments functions, and for functions
+ for which the prototype is not known. */
+
+static CORE_ADDR
+sh64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int stack_offset, stack_alloc;
+ int int_argreg;
+ int float_argreg;
+ int double_argreg;
+ int float_arg_index = 0;
+ int double_arg_index = 0;
+ int argnum;
+ struct type *type;
+ CORE_ADDR regval;
+ char *val;
+ char valbuf[8];
+ char valbuf_tmp[8];
+ int len;
+ int argreg_size;
+ int fp_args[12];
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ memset (fp_args, 0, sizeof (fp_args));
+
+ /* first force sp to a 8-byte alignment */
+ sp = sp & ~7;
+
+ /* The "struct return pointer" pseudo-argument has its own dedicated
+ register */
+
+ if (struct_return)
+ write_register (STRUCT_RETURN_REGNUM, struct_addr);
+
+ /* Now make sure there's space on the stack */
+ for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
+ stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 7) & ~7);
+ sp -= stack_alloc; /* make room on stack for args */
+
+ /* Now load as many as possible of the first arguments into
+ registers, and push the rest onto the stack. There are 64 bytes
+ in eight registers available. Loop thru args from first to last. */
+
+ int_argreg = tdep->ARG0_REGNUM;
+ float_argreg = FP0_REGNUM;
+ double_argreg = tdep->DR0_REGNUM;
+
+ for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
+ {
+ type = VALUE_TYPE (args[argnum]);
+ len = TYPE_LENGTH (type);
+ memset (valbuf, 0, sizeof (valbuf));
+
+ if (TYPE_CODE (type) != TYPE_CODE_FLT)
+ {
+ argreg_size = REGISTER_RAW_SIZE (int_argreg);
+
+ if (len < argreg_size)
+ {
+ /* value gets right-justified in the register or stack word */
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ memcpy (valbuf + argreg_size - len,
+ (char *) VALUE_CONTENTS (args[argnum]), len);
+ else
+ memcpy (valbuf, (char *) VALUE_CONTENTS (args[argnum]), len);
+
+ val = valbuf;
+ }
+ else
+ val = (char *) VALUE_CONTENTS (args[argnum]);
+
+ while (len > 0)
+ {
+ if (int_argreg > tdep->ARGLAST_REGNUM)
+ {
+ /* must go on the stack */
+ write_memory (sp + stack_offset, val, argreg_size);
+ stack_offset += 8;/*argreg_size;*/
+ }
+ /* NOTE WELL!!!!! This is not an "else if" clause!!!
+ That's because some *&^%$ things get passed on the stack
+ AND in the registers! */
+ if (int_argreg <= tdep->ARGLAST_REGNUM)
+ {
+ /* there's room in a register */
+ regval = extract_address (val, argreg_size);
+ write_register (int_argreg, regval);
+ }
+ /* Store the value 8 bytes at a time. This means that
+ things larger than 8 bytes may go partly in registers
+ and partly on the stack. FIXME: argreg is incremented
+ before we use its size. */
+ len -= argreg_size;
+ val += argreg_size;
+ int_argreg++;
+ }
+ }
+ else
+ {
+ val = (char *) VALUE_CONTENTS (args[argnum]);
+ if (len == 4)
+ {
+ /* Where is it going to be stored? */
+ while (fp_args[float_arg_index])
+ float_arg_index ++;
+
+ /* Now float_argreg points to the register where it
+ should be stored. Are we still within the allowed
+ register set? */
+ if (float_arg_index <= tdep->FLOAT_ARGLAST_REGNUM)
+ {
+ /* Goes in FR0...FR11 */
+ write_register_gen (FP0_REGNUM + float_arg_index, val);
+ fp_args[float_arg_index] = 1;
+ /* Skip the corresponding general argument register. */
+ int_argreg ++;
+ }
+ else
+ ;
+ /* Store it as the integers, 8 bytes at the time, if
+ necessary spilling on the stack. */
+
+ }
+ else if (len == 8)
+ {
+ /* Where is it going to be stored? */
+ while (fp_args[double_arg_index])
+ double_arg_index += 2;
+ /* Now double_argreg points to the register
+ where it should be stored.
+ Are we still within the allowed register set? */
+ if (double_arg_index < tdep->FLOAT_ARGLAST_REGNUM)
+ {
+ /* Goes in DR0...DR10 */
+ /* The numbering of the DRi registers is consecutive,
+ i.e. includes odd numbers. */
+ int double_register_offset = double_arg_index / 2;
+ int regnum = tdep->DR0_REGNUM +
+ double_register_offset;
+#if 0
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
+ {
+ memset (valbuf_tmp, 0, sizeof (valbuf_tmp));
+ REGISTER_CONVERT_TO_VIRTUAL (regnum,
+ type, val, valbuf_tmp);
+ val = valbuf_tmp;
+ }
+#endif
+ /* Note: must use write_register_gen here instead
+ of regcache_write, because regcache_write works
+ only for real registers, not pseudo.
+ write_register_gen will call the gdbarch
+ function to do register writes, and that will
+ properly know how to deal with pseudoregs. */
+ write_register_gen (regnum, val);
+ fp_args[double_arg_index] = 1;
+ fp_args[double_arg_index + 1] = 1;
+ /* Skip the corresponding general argument register. */
+ int_argreg ++;
+ }
+ else
+ ;
+ /* Store it as the integers, 8 bytes at the time, if
+ necessary spilling on the stack. */
+ }
+ }
+ }
+ return sp;
+}
+
+/* Function: push_return_address (pc)
+ Set up the return address for the inferior function call.
+ Needed for targets where we don't actually execute a JSR/BSR instruction */
+
+static CORE_ADDR
+sh_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ write_register (gdbarch_tdep (current_gdbarch)->PR_REGNUM,
+ CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+/* Function: fix_call_dummy
+ Poke the callee function's address into the destination part of
+ the CALL_DUMMY. The address is actually stored in a data word
+ following the actualy CALL_DUMMY instructions, which will load
+ it into a register using PC-relative addressing. This function
+ expects the CALL_DUMMY to look like this:
+
+ mov.w @(2,PC), R8
+ jsr @R8
+ nop
+ trap
+ <destination>
+ */
+
+#if 0
+void
+sh_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+ struct value **args, struct type *type, int gcc_p)
+{
+ *(unsigned long *) (dummy + 8) = fun;
+}
+#endif
+
+static int
+sh_coerce_float_to_double (struct type *formal, struct type *actual)
+{
+ return 1;
+}
+
+/* Find a function's return value in the appropriate registers (in
+ regbuf), and copy it into valbuf. Extract from an array REGBUF
+ containing the (raw) register state a function return value of type
+ TYPE, and copy that, in virtual format, into VALBUF. */
+static void
+sh_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ int len = TYPE_LENGTH (type);
+ int return_register = R0_REGNUM;
+ int offset;
+
+ if (len <= 4)
+ {
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ offset = REGISTER_BYTE (return_register) + 4 - len;
+ else
+ offset = REGISTER_BYTE (return_register);
+ memcpy (valbuf, regbuf + offset, len);
+ }
+ else if (len <= 8)
+ {
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ offset = REGISTER_BYTE (return_register) + 8 - len;
+ else
+ offset = REGISTER_BYTE (return_register);
+ memcpy (valbuf, regbuf + offset, len);
+ }
+ else
+ error ("bad size for return value");
+}
+
+static void
+sh3e_sh4_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ int return_register;
+ int offset;
+ int len = TYPE_LENGTH (type);
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ return_register = FP0_REGNUM;
+ else
+ return_register = R0_REGNUM;
+
+ if (len == 8 && TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
+ DOUBLEST val;
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
+ floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword,
+ (char *) regbuf + REGISTER_BYTE (return_register),
+ &val);
+ else
+ floatformat_to_doublest (&floatformat_ieee_double_big,
+ (char *) regbuf + REGISTER_BYTE (return_register),
+ &val);
+ store_floating (valbuf, len, val);
+ }
+ else if (len <= 4)
+ {
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ offset = REGISTER_BYTE (return_register) + 4 - len;
+ else
+ offset = REGISTER_BYTE (return_register);
+ memcpy (valbuf, regbuf + offset, len);
+ }
+ else if (len <= 8)
+ {
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ offset = REGISTER_BYTE (return_register) + 8 - len;
+ else
+ offset = REGISTER_BYTE (return_register);
+ memcpy (valbuf, regbuf + offset, len);
+ }
+ else
+ error ("bad size for return value");
+}
+
+static void
+sh64_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ int offset;
+ int return_register;
+ int len = TYPE_LENGTH (type);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
+ if (len == 4)
+ {
+ /* Return value stored in FP0_REGNUM */
+ return_register = FP0_REGNUM;
+ offset = REGISTER_BYTE (return_register);
+ memcpy (valbuf, (char *) regbuf + offset, len);
+ }
+ else if (len == 8)
+ {
+ /* return value stored in DR0_REGNUM */
+ DOUBLEST val;
+
+ return_register = tdep->DR0_REGNUM;
+ offset = REGISTER_BYTE (return_register);
+
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
+ floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword,
+ (char *) regbuf + offset, &val);
+ else
+ floatformat_to_doublest (&floatformat_ieee_double_big,
+ (char *) regbuf + offset, &val);
+ store_floating (valbuf, len, val);
+ }
+ }
+ else
+ {
+ if (len <= 8)
+ {
+ /* Result is in register 2. If smaller than 8 bytes, it is padded
+ at the most significant end. */
+ return_register = tdep->RETURN_REGNUM;
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ offset = REGISTER_BYTE (return_register) +
+ REGISTER_RAW_SIZE (return_register) - len;
+ else
+ offset = REGISTER_BYTE (return_register);
+ memcpy (valbuf, (char *) regbuf + offset, len);
+ }
+ else
+ error ("bad size for return value");
+ }
+}
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format.
+ If the architecture is sh4 or sh3e, store a function's return value
+ in the R0 general register or in the FP0 floating point register,
+ depending on the type of the return value. In all the other cases
+ the result is stored in r0, left-justified. */
+static void
+sh_default_store_return_value (struct type *type, char *valbuf)
+{
+ char buf[32]; /* more than enough... */
+
+ if (TYPE_LENGTH (type) < REGISTER_RAW_SIZE (R0_REGNUM))
+ {
+ /* Add leading zeros to the value. */
+ memset (buf, 0, REGISTER_RAW_SIZE (R0_REGNUM));
+ memcpy (buf + REGISTER_RAW_SIZE (R0_REGNUM) - TYPE_LENGTH (type),
+ valbuf, TYPE_LENGTH (type));
+ write_register_bytes (REGISTER_BYTE (R0_REGNUM), buf,
+ REGISTER_RAW_SIZE (R0_REGNUM));
+ }
+ else
+ write_register_bytes (REGISTER_BYTE (R0_REGNUM), valbuf,
+ TYPE_LENGTH (type));
+}
+
+static void
+sh3e_sh4_store_return_value (struct type *type, char *valbuf)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ write_register_bytes (REGISTER_BYTE (FP0_REGNUM),
+ valbuf, TYPE_LENGTH (type));
+ else
+ sh_default_store_return_value (type, valbuf);
+}
+
+static void
+sh64_store_return_value (struct type *type, char *valbuf)
+{
+ char buf[64]; /* more than enough... */
+ int len = TYPE_LENGTH (type);
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
+ if (len == 4)
+ {
+ /* Return value stored in FP0_REGNUM */
+ write_register_gen (FP0_REGNUM, valbuf);
+ }
+ if (len == 8)
+ {
+ /* return value stored in DR0_REGNUM */
+ /* FIXME: Implement */
+ }
+ }
+ else
+ {
+ int return_register = gdbarch_tdep (current_gdbarch)->RETURN_REGNUM;
+ int offset = 0;
+
+ if (len <= REGISTER_RAW_SIZE (return_register))
+ {
+ /* Pad with zeros. */
+ memset (buf, 0, REGISTER_RAW_SIZE (return_register));
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
+ offset = 0; /*REGISTER_RAW_SIZE (return_register) - len;*/
+ else
+ offset = REGISTER_RAW_SIZE (return_register) - len;
+
+ memcpy (buf + offset, valbuf, len);
+ write_register_gen (return_register, buf);
+ }
+ else
+ write_register_gen (return_register, valbuf);
+ }
+}
+
+/* Print the registers in a form similar to the E7000 */
+
+static void
+sh_generic_show_regs (void)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
+ paddr (read_register (PC_REGNUM)),
+ (long) read_register (tdep->SR_REGNUM),
+ (long) read_register (tdep->PR_REGNUM),
+ (long) read_register (MACH_REGNUM),
+ (long) read_register (MACL_REGNUM));
+
+ printf_filtered ("GBR=%08lx VBR=%08lx",
+ (long) read_register (GBR_REGNUM),
+ (long) read_register (VBR_REGNUM));
+
+ printf_filtered ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (long) read_register (0),
+ (long) read_register (1),
+ (long) read_register (2),
+ (long) read_register (3),
+ (long) read_register (4),
+ (long) read_register (5),
+ (long) read_register (6),
+ (long) read_register (7));
+ printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (long) read_register (8),
+ (long) read_register (9),
+ (long) read_register (10),
+ (long) read_register (11),
+ (long) read_register (12),
+ (long) read_register (13),
+ (long) read_register (14),
+ (long) read_register (15));
+}
+
+static void
+sh3_show_regs (void)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
+ paddr (read_register (PC_REGNUM)),
+ (long) read_register (tdep->SR_REGNUM),
+ (long) read_register (tdep->PR_REGNUM),
+ (long) read_register (MACH_REGNUM),
+ (long) read_register (MACL_REGNUM));
+
+ printf_filtered ("GBR=%08lx VBR=%08lx",
+ (long) read_register (GBR_REGNUM),
+ (long) read_register (VBR_REGNUM));
+ printf_filtered (" SSR=%08lx SPC=%08lx",
+ (long) read_register (tdep->SSR_REGNUM),
+ (long) read_register (tdep->SPC_REGNUM));
+
+ printf_filtered ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (long) read_register (0),
+ (long) read_register (1),
+ (long) read_register (2),
+ (long) read_register (3),
+ (long) read_register (4),
+ (long) read_register (5),
+ (long) read_register (6),
+ (long) read_register (7));
+ printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (long) read_register (8),
+ (long) read_register (9),
+ (long) read_register (10),
+ (long) read_register (11),
+ (long) read_register (12),
+ (long) read_register (13),
+ (long) read_register (14),
+ (long) read_register (15));
+}
+
+
+static void
+sh3e_show_regs (void)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
+ paddr (read_register (PC_REGNUM)),
+ (long) read_register (tdep->SR_REGNUM),
+ (long) read_register (tdep->PR_REGNUM),
+ (long) read_register (MACH_REGNUM),
+ (long) read_register (MACL_REGNUM));
+
+ printf_filtered ("GBR=%08lx VBR=%08lx",
+ (long) read_register (GBR_REGNUM),
+ (long) read_register (VBR_REGNUM));
+ printf_filtered (" SSR=%08lx SPC=%08lx",
+ (long) read_register (tdep->SSR_REGNUM),
+ (long) read_register (tdep->SPC_REGNUM));
+ printf_filtered (" FPUL=%08lx FPSCR=%08lx",
+ (long) read_register (tdep->FPUL_REGNUM),
+ (long) read_register (tdep->FPSCR_REGNUM));
+
+ printf_filtered ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (long) read_register (0),
+ (long) read_register (1),
+ (long) read_register (2),
+ (long) read_register (3),
+ (long) read_register (4),
+ (long) read_register (5),
+ (long) read_register (6),
+ (long) read_register (7));
+ printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (long) read_register (8),
+ (long) read_register (9),
+ (long) read_register (10),
+ (long) read_register (11),
+ (long) read_register (12),
+ (long) read_register (13),
+ (long) read_register (14),
+ (long) read_register (15));
+
+ printf_filtered (("FP0-FP7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"),
+ (long) read_register (FP0_REGNUM + 0),
+ (long) read_register (FP0_REGNUM + 1),
+ (long) read_register (FP0_REGNUM + 2),
+ (long) read_register (FP0_REGNUM + 3),
+ (long) read_register (FP0_REGNUM + 4),
+ (long) read_register (FP0_REGNUM + 5),
+ (long) read_register (FP0_REGNUM + 6),
+ (long) read_register (FP0_REGNUM + 7));
+ printf_filtered (("FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"),
+ (long) read_register (FP0_REGNUM + 8),
+ (long) read_register (FP0_REGNUM + 9),
+ (long) read_register (FP0_REGNUM + 10),
+ (long) read_register (FP0_REGNUM + 11),
+ (long) read_register (FP0_REGNUM + 12),
+ (long) read_register (FP0_REGNUM + 13),
+ (long) read_register (FP0_REGNUM + 14),
+ (long) read_register (FP0_REGNUM + 15));
+}
+
+static void
+sh3_dsp_show_regs (void)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
+ paddr (read_register (PC_REGNUM)),
+ (long) read_register (tdep->SR_REGNUM),
+ (long) read_register (tdep->PR_REGNUM),
+ (long) read_register (MACH_REGNUM),
+ (long) read_register (MACL_REGNUM));
+
+ printf_filtered ("GBR=%08lx VBR=%08lx",
+ (long) read_register (GBR_REGNUM),
+ (long) read_register (VBR_REGNUM));
+
+ printf_filtered (" SSR=%08lx SPC=%08lx",
+ (long) read_register (tdep->SSR_REGNUM),
+ (long) read_register (tdep->SPC_REGNUM));
+
+ printf_filtered (" DSR=%08lx",
+ (long) read_register (tdep->DSR_REGNUM));
+
+ printf_filtered ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (long) read_register (0),
+ (long) read_register (1),
+ (long) read_register (2),
+ (long) read_register (3),
+ (long) read_register (4),
+ (long) read_register (5),
+ (long) read_register (6),
+ (long) read_register (7));
+ printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (long) read_register (8),
+ (long) read_register (9),
+ (long) read_register (10),
+ (long) read_register (11),
+ (long) read_register (12),
+ (long) read_register (13),
+ (long) read_register (14),
+ (long) read_register (15));
+
+ printf_filtered ("A0G=%02lx A0=%08lx M0=%08lx X0=%08lx Y0=%08lx RS=%08lx MOD=%08lx\n",
+ (long) read_register (tdep->A0G_REGNUM) & 0xff,
+ (long) read_register (tdep->A0_REGNUM),
+ (long) read_register (tdep->M0_REGNUM),
+ (long) read_register (tdep->X0_REGNUM),
+ (long) read_register (tdep->Y0_REGNUM),
+ (long) read_register (tdep->RS_REGNUM),
+ (long) read_register (tdep->MOD_REGNUM));
+ printf_filtered ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n",
+ (long) read_register (tdep->A1G_REGNUM) & 0xff,
+ (long) read_register (tdep->A1_REGNUM),
+ (long) read_register (tdep->M1_REGNUM),
+ (long) read_register (tdep->X1_REGNUM),
+ (long) read_register (tdep->Y1_REGNUM),
+ (long) read_register (tdep->RE_REGNUM));
+}
+
+static void
+sh4_show_regs (void)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ int pr = read_register (tdep->FPSCR_REGNUM) & 0x80000;
+ printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
+ paddr (read_register (PC_REGNUM)),
+ (long) read_register (tdep->SR_REGNUM),
+ (long) read_register (tdep->PR_REGNUM),
+ (long) read_register (MACH_REGNUM),
+ (long) read_register (MACL_REGNUM));
+
+ printf_filtered ("GBR=%08lx VBR=%08lx",
+ (long) read_register (GBR_REGNUM),
+ (long) read_register (VBR_REGNUM));
+ printf_filtered (" SSR=%08lx SPC=%08lx",
+ (long) read_register (tdep->SSR_REGNUM),
+ (long) read_register (tdep->SPC_REGNUM));
+ printf_filtered (" FPUL=%08lx FPSCR=%08lx",
+ (long) read_register (tdep->FPUL_REGNUM),
+ (long) read_register (tdep->FPSCR_REGNUM));
+
+ printf_filtered ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (long) read_register (0),
+ (long) read_register (1),
+ (long) read_register (2),
+ (long) read_register (3),
+ (long) read_register (4),
+ (long) read_register (5),
+ (long) read_register (6),
+ (long) read_register (7));
+ printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (long) read_register (8),
+ (long) read_register (9),
+ (long) read_register (10),
+ (long) read_register (11),
+ (long) read_register (12),
+ (long) read_register (13),
+ (long) read_register (14),
+ (long) read_register (15));
+
+ printf_filtered ((pr
+ ? "DR0-DR6 %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n"
+ : "FP0-FP7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"),
+ (long) read_register (FP0_REGNUM + 0),
+ (long) read_register (FP0_REGNUM + 1),
+ (long) read_register (FP0_REGNUM + 2),
+ (long) read_register (FP0_REGNUM + 3),
+ (long) read_register (FP0_REGNUM + 4),
+ (long) read_register (FP0_REGNUM + 5),
+ (long) read_register (FP0_REGNUM + 6),
+ (long) read_register (FP0_REGNUM + 7));
+ printf_filtered ((pr
+ ? "DR8-DR14 %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n"
+ : "FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"),
+ (long) read_register (FP0_REGNUM + 8),
+ (long) read_register (FP0_REGNUM + 9),
+ (long) read_register (FP0_REGNUM + 10),
+ (long) read_register (FP0_REGNUM + 11),
+ (long) read_register (FP0_REGNUM + 12),
+ (long) read_register (FP0_REGNUM + 13),
+ (long) read_register (FP0_REGNUM + 14),
+ (long) read_register (FP0_REGNUM + 15));
+}
+
+static void
+sh_dsp_show_regs (void)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
+ paddr (read_register (PC_REGNUM)),
+ (long) read_register (tdep->SR_REGNUM),
+ (long) read_register (tdep->PR_REGNUM),
+ (long) read_register (MACH_REGNUM),
+ (long) read_register (MACL_REGNUM));
+
+ printf_filtered ("GBR=%08lx VBR=%08lx",
+ (long) read_register (GBR_REGNUM),
+ (long) read_register (VBR_REGNUM));
+
+ printf_filtered (" DSR=%08lx",
+ (long) read_register (tdep->DSR_REGNUM));
+
+ printf_filtered ("\nR0-R7 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (long) read_register (0),
+ (long) read_register (1),
+ (long) read_register (2),
+ (long) read_register (3),
+ (long) read_register (4),
+ (long) read_register (5),
+ (long) read_register (6),
+ (long) read_register (7));
+ printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (long) read_register (8),
+ (long) read_register (9),
+ (long) read_register (10),
+ (long) read_register (11),
+ (long) read_register (12),
+ (long) read_register (13),
+ (long) read_register (14),
+ (long) read_register (15));
+
+ printf_filtered ("A0G=%02lx A0=%08lx M0=%08lx X0=%08lx Y0=%08lx RS=%08lx MOD=%08lx\n",
+ (long) read_register (tdep->A0G_REGNUM) & 0xff,
+ (long) read_register (tdep->A0_REGNUM),
+ (long) read_register (tdep->M0_REGNUM),
+ (long) read_register (tdep->X0_REGNUM),
+ (long) read_register (tdep->Y0_REGNUM),
+ (long) read_register (tdep->RS_REGNUM),
+ (long) read_register (tdep->MOD_REGNUM));
+ printf_filtered ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n",
+ (long) read_register (tdep->A1G_REGNUM) & 0xff,
+ (long) read_register (tdep->A1_REGNUM),
+ (long) read_register (tdep->M1_REGNUM),
+ (long) read_register (tdep->X1_REGNUM),
+ (long) read_register (tdep->Y1_REGNUM),
+ (long) read_register (tdep->RE_REGNUM));
+}
+
+static void
+sh64_show_media_regs (void)
+{
+ int i;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ printf_filtered ("PC=%s SR=%016llx \n",
+ paddr (read_register (PC_REGNUM)),
+ (long long) read_register (tdep->SR_REGNUM));
+
+ printf_filtered ("SSR=%016llx SPC=%016llx \n",
+ (long long) read_register (tdep->SSR_REGNUM),
+ (long long) read_register (tdep->SPC_REGNUM));
+ printf_filtered ("FPSCR=%016lx\n ",
+ (long) read_register (tdep->FPSCR_REGNUM));
+
+ for (i = 0; i < 64; i = i + 4)
+ printf_filtered ("\nR%d-R%d %016llx %016llx %016llx %016llx\n",
+ i, i + 3,
+ (long long) read_register (i + 0),
+ (long long) read_register (i + 1),
+ (long long) read_register (i + 2),
+ (long long) read_register (i + 3));
+
+ printf_filtered ("\n");
+
+ for (i = 0; i < 64; i = i + 8)
+ printf_filtered ("FR%d-FR%d %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ i, i + 7,
+ (long) read_register (FP0_REGNUM + i + 0),
+ (long) read_register (FP0_REGNUM + i + 1),
+ (long) read_register (FP0_REGNUM + i + 2),
+ (long) read_register (FP0_REGNUM + i + 3),
+ (long) read_register (FP0_REGNUM + i + 4),
+ (long) read_register (FP0_REGNUM + i + 5),
+ (long) read_register (FP0_REGNUM + i + 6),
+ (long) read_register (FP0_REGNUM + i + 7));
+}
+
+static void
+sh64_show_compact_regs (void)
+{
+ int i;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ printf_filtered ("PC=%s \n",
+ paddr (read_register (tdep->PC_C_REGNUM)));
+
+ printf_filtered ("GBR=%08lx MACH=%08lx MACL=%08lx PR=%08lx T=%08lx\n",
+ (long) read_register (tdep->GBR_C_REGNUM),
+ (long) read_register (tdep->MACH_C_REGNUM),
+ (long) read_register (tdep->MACL_C_REGNUM),
+ (long) read_register (tdep->PR_C_REGNUM),
+ (long) read_register (tdep->T_C_REGNUM));
+ printf_filtered ("FPSCR=%08lx FPUL=%08lx\n",
+ (long) read_register (tdep->FPSCR_REGNUM),
+ (long) read_register (tdep->FPUL_REGNUM));
+
+ for (i = 0; i < 16; i = i + 4)
+ printf_filtered ("\nR%d-R%d %08lx %08lx %08lx %08lx\n",
+ i, i + 3,
+ (long) read_register (i + 0),
+ (long) read_register (i + 1),
+ (long) read_register (i + 2),
+ (long) read_register (i + 3));
+
+ printf_filtered ("\n");
+
+ for (i = 0; i < 16; i = i + 8)
+ printf_filtered ("FR%d-FR%d %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ i, i + 7,
+ (long) read_register (FP0_REGNUM + i + 0),
+ (long) read_register (FP0_REGNUM + i + 1),
+ (long) read_register (FP0_REGNUM + i + 2),
+ (long) read_register (FP0_REGNUM + i + 3),
+ (long) read_register (FP0_REGNUM + i + 4),
+ (long) read_register (FP0_REGNUM + i + 5),
+ (long) read_register (FP0_REGNUM + i + 6),
+ (long) read_register (FP0_REGNUM + i + 7));
+}
+
+/*FIXME!!! This only shows the registers for shmedia, excluding the
+ pseudo registers. */
+static void
+sh64_show_regs (void)
+{
+ if (pc_is_isa32 (selected_frame->pc))
+ sh64_show_media_regs ();
+ else
+ sh64_show_compact_regs ();
+}
+
+void sh_show_regs_command (char *args, int from_tty)
+{
+ if (sh_show_regs)
+ (*sh_show_regs)();
+}
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+static int
+sh_default_register_byte (int reg_nr)
+{
+ return (reg_nr * 4);
+}
+
+static int
+sh_sh4_register_byte (int reg_nr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (reg_nr >= tdep->DR0_REGNUM
+ && reg_nr <= tdep->DR_LAST_REGNUM)
+ return (dr_reg_base_num (reg_nr) * 4);
+ else if (reg_nr >= tdep->FV0_REGNUM
+ && reg_nr <= tdep->FV_LAST_REGNUM)
+ return (fv_reg_base_num (reg_nr) * 4);
+ else
+ return (reg_nr * 4);
+}
+
+/* *INDENT-OFF* */
+/*
+ SH MEDIA MODE (ISA 32)
+ general registers (64-bit) 0-63
+0 r0, r1, r2, r3, r4, r5, r6, r7,
+64 r8, r9, r10, r11, r12, r13, r14, r15,
+128 r16, r17, r18, r19, r20, r21, r22, r23,
+192 r24, r25, r26, r27, r28, r29, r30, r31,
+256 r32, r33, r34, r35, r36, r37, r38, r39,
+320 r40, r41, r42, r43, r44, r45, r46, r47,
+384 r48, r49, r50, r51, r52, r53, r54, r55,
+448 r56, r57, r58, r59, r60, r61, r62, r63,
+
+ pc (64-bit) 64
+512 pc,
+
+ status reg., saved status reg., saved pc reg. (64-bit) 65-67
+520 sr, ssr, spc,
+
+ target registers (64-bit) 68-75
+544 tr0, tr1, tr2, tr3, tr4, tr5, tr6, tr7,
+
+ floating point state control register (32-bit) 76
+608 fpscr,
+
+ single precision floating point registers (32-bit) 77-140
+612 fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7,
+644 fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15,
+676 fr16, fr17, fr18, fr19, fr20, fr21, fr22, fr23,
+708 fr24, fr25, fr26, fr27, fr28, fr29, fr30, fr31,
+740 fr32, fr33, fr34, fr35, fr36, fr37, fr38, fr39,
+772 fr40, fr41, fr42, fr43, fr44, fr45, fr46, fr47,
+804 fr48, fr49, fr50, fr51, fr52, fr53, fr54, fr55,
+836 fr56, fr57, fr58, fr59, fr60, fr61, fr62, fr63,
+
+TOTAL SPACE FOR REGISTERS: 868 bytes
+
+From here on they are all pseudo registers: no memory allocated.
+REGISTER_BYTE returns the register byte for the base register.
+
+ double precision registers (pseudo) 141-172
+ dr0, dr2, dr4, dr6, dr8, dr10, dr12, dr14,
+ dr16, dr18, dr20, dr22, dr24, dr26, dr28, dr30,
+ dr32, dr34, dr36, dr38, dr40, dr42, dr44, dr46,
+ dr48, dr50, dr52, dr54, dr56, dr58, dr60, dr62,
+
+ floating point pairs (pseudo) 173-204
+ fp0, fp2, fp4, fp6, fp8, fp10, fp12, fp14,
+ fp16, fp18, fp20, fp22, fp24, fp26, fp28, fp30,
+ fp32, fp34, fp36, fp38, fp40, fp42, fp44, fp46,
+ fp48, fp50, fp52, fp54, fp56, fp58, fp60, fp62,
+
+ floating point vectors (4 floating point regs) (pseudo) 205-220
+ fv0, fv4, fv8, fv12, fv16, fv20, fv24, fv28,
+ fv32, fv36, fv40, fv44, fv48, fv52, fv56, fv60,
+
+ SH COMPACT MODE (ISA 16) (all pseudo) 221-272
+ r0_c, r1_c, r2_c, r3_c, r4_c, r5_c, r6_c, r7_c,
+ r8_c, r9_c, r10_c, r11_c, r12_c, r13_c, r14_c, r15_c,
+ pc_c,
+ gbr_c, mach_c, macl_c, pr_c, t_c,
+ fpscr_c, fpul_c,
+ fr0_c, fr1_c, fr2_c, fr3_c, fr4_c, fr5_c, fr6_c, fr7_c,
+ fr8_c, fr9_c, fr10_c, fr11_c, fr12_c, fr13_c, fr14_c, fr15_c
+ dr0_c, dr2_c, dr4_c, dr6_c, dr8_c, dr10_c, dr12_c, dr14_c
+ fv0_c, fv4_c, fv8_c, fv12_c
+*/
+/* *INDENT-ON* */
+static int
+sh_sh64_register_byte (int reg_nr)
+{
+ int base_regnum = -1;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ /* If it is a pseudo register, get the number of the first floating
+ point register that is part of it. */
+ if (reg_nr >= tdep->DR0_REGNUM
+ && reg_nr <= tdep->DR_LAST_REGNUM)
+ base_regnum = dr_reg_base_num (reg_nr);
+
+ else if (reg_nr >= tdep->FPP0_REGNUM
+ && reg_nr <= tdep->FPP_LAST_REGNUM)
+ base_regnum = fpp_reg_base_num (reg_nr);
+
+ else if (reg_nr >= tdep->FV0_REGNUM
+ && reg_nr <= tdep->FV_LAST_REGNUM)
+ base_regnum = fv_reg_base_num (reg_nr);
+
+ /* sh compact pseudo register. FPSCR is a pathological case, need to
+ treat it as special. */
+ else if ((reg_nr >= tdep->R0_C_REGNUM
+ && reg_nr <= tdep->FV_LAST_C_REGNUM)
+ && reg_nr != tdep->FPSCR_C_REGNUM)
+ base_regnum = sh64_compact_reg_base_num (reg_nr);
+
+ /* Now return the offset in bytes within the register cache. */
+ /* sh media pseudo register, i.e. any of DR, FFP, FV registers. */
+ if (reg_nr >= tdep->DR0_REGNUM
+ && reg_nr <= tdep->FV_LAST_REGNUM)
+ return (base_regnum - FP0_REGNUM + 1) * 4
+ + (tdep->TR7_REGNUM + 1) * 8;
+
+ /* sh compact pseudo register: general register */
+ if ((reg_nr >= tdep->R0_C_REGNUM
+ && reg_nr <= tdep->R_LAST_C_REGNUM))
+ return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ ? base_regnum * 8 + 4
+ : base_regnum * 8);
+
+ /* sh compact pseudo register: */
+ if (reg_nr == tdep->PC_C_REGNUM
+ || reg_nr == tdep->GBR_C_REGNUM
+ || reg_nr == tdep->MACL_C_REGNUM
+ || reg_nr == tdep->PR_C_REGNUM)
+ return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ ? base_regnum * 8 + 4
+ : base_regnum * 8);
+
+ if (reg_nr == tdep->MACH_C_REGNUM)
+ return base_regnum * 8;
+
+ if (reg_nr == tdep->T_C_REGNUM)
+ return base_regnum * 8; /* FIXME??? how do we get bit 0? Do we have to? */
+
+ /* sh compact pseudo register: floating point register */
+ else if (reg_nr >=tdep->FP0_C_REGNUM
+ && reg_nr <= tdep->FV_LAST_C_REGNUM)
+ return (base_regnum - FP0_REGNUM) * 4
+ + (tdep->TR7_REGNUM + 1) * 8 + 4;
+
+ else if (reg_nr == tdep->FPSCR_C_REGNUM)
+ /* This is complicated, for now return the beginning of the
+ architectural FPSCR register. */
+ return (tdep->TR7_REGNUM + 1) * 8;
+
+ else if (reg_nr == tdep->FPUL_C_REGNUM)
+ return ((base_regnum - FP0_REGNUM) * 4 +
+ (tdep->TR7_REGNUM + 1) * 8 + 4);
+
+ /* It is not a pseudo register. */
+ /* It is a 64 bit register. */
+ else if (reg_nr <= tdep->TR7_REGNUM)
+ return reg_nr * 8;
+
+ /* It is a 32 bit register. */
+ else
+ if (reg_nr == tdep->FPSCR_REGNUM)
+ return (tdep->FPSCR_REGNUM * 8);
+
+ /* It is floating point 32-bit register */
+ else
+ return ((tdep->TR7_REGNUM + 1) * 8
+ + (reg_nr - FP0_REGNUM + 1) * 4);
+}
+
+/* Number of bytes of storage in the actual machine representation for
+ register REG_NR. */
+static int
+sh_default_register_raw_size (int reg_nr)
+{
+ return 4;
+}
+
+static int
+sh_sh4_register_raw_size (int reg_nr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (reg_nr >= tdep->DR0_REGNUM
+ && reg_nr <= tdep->DR_LAST_REGNUM)
+ return 8;
+ else if (reg_nr >= tdep->FV0_REGNUM
+ && reg_nr <= tdep->FV_LAST_REGNUM)
+ return 16;
+ else
+ return 4;
+}
+
+static int
+sh_sh64_register_raw_size (int reg_nr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if ((reg_nr >= tdep->DR0_REGNUM
+ && reg_nr <= tdep->DR_LAST_REGNUM)
+ || (reg_nr >= tdep->FPP0_REGNUM
+ && reg_nr <= tdep->FPP_LAST_REGNUM)
+ || (reg_nr >= tdep->DR0_C_REGNUM
+ && reg_nr <= tdep->DR_LAST_C_REGNUM)
+ || (reg_nr <= tdep->TR7_REGNUM))
+ return 8;
+
+ else if ((reg_nr >= tdep->FV0_REGNUM
+ && reg_nr <= tdep->FV_LAST_REGNUM)
+ || (reg_nr >= tdep->FV0_C_REGNUM
+ && reg_nr <= tdep->FV_LAST_C_REGNUM))
+ return 16;
+
+ else /* this covers also the 32-bit SH compact registers. */
+ return 4;
+}
+
+/* Number of bytes of storage in the program's representation
+ for register N. */
+static int
+sh_register_virtual_size (int reg_nr)
+{
+ return 4;
+}
+
+/* ??????? FIXME */
+static int
+sh_sh64_register_virtual_size (int reg_nr)
+{
+ if (reg_nr >= FP0_REGNUM
+ && reg_nr <= gdbarch_tdep (current_gdbarch)->FP_LAST_REGNUM)
+ return 4;
+ else
+ return 8;
+}
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+static struct type *
+sh_sh3e_register_virtual_type (int reg_nr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if ((reg_nr >= FP0_REGNUM
+ && (reg_nr <= tdep->FP_LAST_REGNUM))
+ || (reg_nr == tdep->FPUL_REGNUM))
+ return builtin_type_float;
+ else
+ return builtin_type_int;
+}
+
+static struct type *
+sh_sh4_build_float_register_type (int high)
+{
+ struct type *temp;
+
+ temp = create_range_type (NULL, builtin_type_int, 0, high);
+ return create_array_type (NULL, builtin_type_float, temp);
+}
+
+static struct type *
+sh_sh4_register_virtual_type (int reg_nr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if ((reg_nr >= FP0_REGNUM
+ && (reg_nr <= tdep->FP_LAST_REGNUM))
+ || (reg_nr == tdep->FPUL_REGNUM))
+ return builtin_type_float;
+ else if (reg_nr >= tdep->DR0_REGNUM
+ && reg_nr <= tdep->DR_LAST_REGNUM)
+ return builtin_type_double;
+ else if (reg_nr >= tdep->FV0_REGNUM
+ && reg_nr <= tdep->FV_LAST_REGNUM)
+ return sh_sh4_build_float_register_type (3);
+ else
+ return builtin_type_int;
+}
+
+static struct type *
+sh_sh64_register_virtual_type (int reg_nr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if ((reg_nr >= FP0_REGNUM
+ && reg_nr <= tdep->FP_LAST_REGNUM)
+ || (reg_nr >= tdep->FP0_C_REGNUM
+ && reg_nr <= tdep->FP_LAST_C_REGNUM))
+ return builtin_type_float;
+ else if ((reg_nr >= tdep->DR0_REGNUM
+ && reg_nr <= tdep->DR_LAST_REGNUM)
+ || (reg_nr >= tdep->DR0_C_REGNUM
+ && reg_nr <= tdep->DR_LAST_C_REGNUM))
+ return builtin_type_double;
+ else if (reg_nr >= tdep->FPP0_REGNUM
+ && reg_nr <= tdep->FPP_LAST_REGNUM)
+ return sh_sh4_build_float_register_type (1);
+ else if ((reg_nr >= tdep->FV0_REGNUM
+ && reg_nr <= tdep->FV_LAST_REGNUM)
+ ||(reg_nr >= tdep->FV0_C_REGNUM
+ && reg_nr <= tdep->FV_LAST_C_REGNUM))
+ return sh_sh4_build_float_register_type (3);
+ else if (reg_nr == tdep->FPSCR_REGNUM)
+ return builtin_type_int;
+ else if (reg_nr >= tdep->R0_C_REGNUM
+ && reg_nr < tdep->FP0_C_REGNUM)
+ return builtin_type_int;
+ else
+ return builtin_type_long_long;
+}
+
+static struct type *
+sh_default_register_virtual_type (int reg_nr)
+{
+ return builtin_type_int;
+}
+
+/* On the sh4, the DRi pseudo registers are problematic if the target
+ is little endian. When the user writes one of those registers, for
+ instance with 'ser var $dr0=1', we want the double to be stored
+ like this:
+ fr0 = 0x00 0x00 0x00 0x00 0x00 0xf0 0x3f
+ fr1 = 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+
+ This corresponds to little endian byte order & big endian word
+ order. However if we let gdb write the register w/o conversion, it
+ will write fr0 and fr1 this way:
+ fr0 = 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ fr1 = 0x00 0x00 0x00 0x00 0x00 0xf0 0x3f
+ because it will consider fr0 and fr1 as a single LE stretch of memory.
+
+ To achieve what we want we must force gdb to store things in
+ floatformat_ieee_double_littlebyte_bigword (which is defined in
+ include/floatformat.h and libiberty/floatformat.c.
+
+ In case the target is big endian, there is no problem, the
+ raw bytes will look like:
+ fr0 = 0x3f 0xf0 0x00 0x00 0x00 0x00 0x00
+ fr1 = 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+
+ The other pseudo registers (the FVs) also don't pose a problem
+ because they are stored as 4 individual FP elements. */
+
+static void
+sh_sh4_register_convert_to_virtual (int regnum, struct type *type,
+ char *from, char *to)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (regnum >= tdep->DR0_REGNUM
+ && regnum <= tdep->DR_LAST_REGNUM)
+ {
+ DOUBLEST val;
+ floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword, from, &val);
+ store_floating (to, TYPE_LENGTH (type), val);
+ }
+ else
+ error ("sh_register_convert_to_virtual called with non DR register number");
+}
+
+void
+sh_sh64_register_convert_to_virtual (int regnum, struct type *type,
+ char *from, char *to)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (TARGET_BYTE_ORDER != BFD_ENDIAN_LITTLE)
+ {
+ /* It is a no-op. */
+ memcpy (to, from, REGISTER_RAW_SIZE (regnum));
+ return;
+ }
+
+ if ((regnum >= tdep->DR0_REGNUM
+ && regnum <= tdep->DR_LAST_REGNUM)
+ || (regnum >= tdep->DR0_C_REGNUM
+ && regnum <= tdep->DR_LAST_C_REGNUM))
+ {
+ DOUBLEST val;
+ floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword, from, &val);
+ store_floating(to, TYPE_LENGTH(type), val);
+ }
+ else
+ error("sh_register_convert_to_virtual called with non DR register number");
+}
+
+static void
+sh_sh4_register_convert_to_raw (struct type *type, int regnum,
+ char *from, char *to)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (regnum >= tdep->DR0_REGNUM
+ && regnum <= tdep->DR_LAST_REGNUM)
+ {
+ DOUBLEST val = extract_floating (from, TYPE_LENGTH(type));
+ floatformat_from_doublest (&floatformat_ieee_double_littlebyte_bigword, &val, to);
+ }
+ else
+ error("sh_register_convert_to_raw called with non DR register number");
+}
+
+void
+sh_sh64_register_convert_to_raw (struct type *type, int regnum,
+ char *from, char *to)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (TARGET_BYTE_ORDER != BFD_ENDIAN_LITTLE)
+ {
+ /* It is a no-op. */
+ memcpy (to, from, REGISTER_RAW_SIZE (regnum));
+ return;
+ }
+
+ if ((regnum >= tdep->DR0_REGNUM
+ && regnum <= tdep->DR_LAST_REGNUM)
+ || (regnum >= tdep->DR0_C_REGNUM
+ && regnum <= tdep->DR_LAST_C_REGNUM))
+ {
+ DOUBLEST val = extract_floating (from, TYPE_LENGTH(type));
+ floatformat_from_doublest (&floatformat_ieee_double_littlebyte_bigword, &val, to);
+ }
+ else
+ error("sh_register_convert_to_raw called with non DR register number");
+}
+
+void
+sh_pseudo_register_read (int reg_nr, char *buffer)
+{
+ int base_regnum, portion;
+ char *temp_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (reg_nr >= tdep->DR0_REGNUM
+ && reg_nr <= tdep->DR_LAST_REGNUM)
+ {
+ base_regnum = dr_reg_base_num (reg_nr);
+
+ /* Build the value in the provided buffer. */
+ /* Read the real regs for which this one is an alias. */
+ for (portion = 0; portion < 2; portion++)
+ regcache_read (base_regnum + portion,
+ temp_buffer
+ + REGISTER_RAW_SIZE (base_regnum) * portion);
+ /* We must pay attention to the endiannes. */
+ sh_sh4_register_convert_to_virtual (reg_nr,
+ REGISTER_VIRTUAL_TYPE (reg_nr),
+ temp_buffer, buffer);
+ }
+ else if (reg_nr >= tdep->FV0_REGNUM
+ && reg_nr <= tdep->FV_LAST_REGNUM)
+ {
+ base_regnum = fv_reg_base_num (reg_nr);
+
+ /* Read the real regs for which this one is an alias. */
+ for (portion = 0; portion < 4; portion++)
+ regcache_read (base_regnum + portion,
+ buffer + REGISTER_RAW_SIZE (base_regnum) * portion);
+ }
+}
+
+static void
+sh4_register_read (struct gdbarch *gdbarch, int reg_nr, char *buffer)
+{
+ if (reg_nr >= 0 && reg_nr < gdbarch_tdep (current_gdbarch)->DR0_REGNUM)
+ /* It is a regular register. */
+ regcache_read (reg_nr, buffer);
+ else
+ /* It is a pseudo register and we need to construct its value */
+ sh_pseudo_register_read (reg_nr, buffer);
+}
+
+static void
+sh64_pseudo_register_read (int reg_nr, char *buffer)
+{
+ int base_regnum;
+ int portion;
+ int offset = 0;
+ char *temp_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (reg_nr >= tdep->DR0_REGNUM
+ && reg_nr <= tdep->DR_LAST_REGNUM)
+ {
+ base_regnum = dr_reg_base_num (reg_nr);
+
+ /* Build the value in the provided buffer. */
+ /* DR regs are double precision registers obtained by
+ concatenating 2 single precision floating point registers. */
+ for (portion = 0; portion < 2; portion++)
+ regcache_read (base_regnum + portion,
+ temp_buffer
+ + REGISTER_RAW_SIZE (base_regnum) * portion);
+
+ /* We must pay attention to the endiannes. */
+ sh_sh64_register_convert_to_virtual (reg_nr, REGISTER_VIRTUAL_TYPE (reg_nr),
+ temp_buffer, buffer);
+
+ }
+
+ else if (reg_nr >= tdep->FPP0_REGNUM
+ && reg_nr <= tdep->FPP_LAST_REGNUM)
+ {
+ base_regnum = fpp_reg_base_num (reg_nr);
+
+ /* Build the value in the provided buffer. */
+ /* FPP regs are pairs of single precision registers obtained by
+ concatenating 2 single precision floating point registers. */
+ for (portion = 0; portion < 2; portion++)
+ regcache_read (base_regnum + portion,
+ buffer + REGISTER_RAW_SIZE (base_regnum) * portion);
+ }
+
+ else if (reg_nr >= tdep->FV0_REGNUM
+ && reg_nr <= tdep->FV_LAST_REGNUM)
+ {
+ base_regnum = fv_reg_base_num (reg_nr);
+
+ /* Build the value in the provided buffer. */
+ /* FV regs are vectors of single precision registers obtained by
+ concatenating 4 single precision floating point registers. */
+ for (portion = 0; portion < 4; portion++)
+ regcache_read (base_regnum + portion,
+ buffer + REGISTER_RAW_SIZE (base_regnum) * portion);
+ }
+
+ /* sh compact pseudo registers. 1-to-1 with a shmedia register */
+ else if (reg_nr >= tdep->R0_C_REGNUM
+ && reg_nr <= tdep->T_C_REGNUM)
+ {
+ base_regnum = sh64_compact_reg_base_num (reg_nr);
+
+ /* Build the value in the provided buffer. */
+ regcache_read (base_regnum, temp_buffer);
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ offset = 4;
+ memcpy (buffer, temp_buffer + offset, 4); /* get LOWER 32 bits only????*/
+ }
+
+ else if (reg_nr >= tdep->FP0_C_REGNUM
+ && reg_nr <= tdep->FP_LAST_C_REGNUM)
+ {
+ base_regnum = sh64_compact_reg_base_num (reg_nr);
+
+ /* Build the value in the provided buffer. */
+ /* Floating point registers map 1-1 to the media fp regs,
+ they have the same size and endienness. */
+ regcache_read (base_regnum, buffer);
+ }
+
+ else if (reg_nr >= tdep->DR0_C_REGNUM
+ && reg_nr <= tdep->DR_LAST_C_REGNUM)
+ {
+ base_regnum = sh64_compact_reg_base_num (reg_nr);
+
+ /* DR_C regs are double precision registers obtained by
+ concatenating 2 single precision floating point registers. */
+ for (portion = 0; portion < 2; portion++)
+ regcache_read (base_regnum + portion,
+ temp_buffer
+ + REGISTER_RAW_SIZE (base_regnum) * portion);
+
+ /* We must pay attention to the endiannes. */
+ sh_sh64_register_convert_to_virtual (reg_nr, REGISTER_VIRTUAL_TYPE (reg_nr),
+ temp_buffer, buffer);
+ }
+
+ else if (reg_nr >= tdep->FV0_C_REGNUM
+ && reg_nr <= tdep->FV_LAST_C_REGNUM)
+ {
+ base_regnum = sh64_compact_reg_base_num (reg_nr);
+
+ /* Build the value in the provided buffer. */
+ /* FV_C regs are vectors of single precision registers obtained by
+ concatenating 4 single precision floating point registers. */
+ for (portion = 0; portion < 4; portion++)
+ regcache_read (base_regnum + portion,
+ buffer + REGISTER_RAW_SIZE (base_regnum) * portion);
+ }
+
+ else if (reg_nr == tdep->FPSCR_C_REGNUM)
+ {
+ int fpscr_base_regnum;
+ int sr_base_regnum;
+ unsigned int fpscr_value;
+ unsigned int sr_value;
+ unsigned int fpscr_c_value;
+ unsigned int fpscr_c_part1_value;
+ unsigned int fpscr_c_part2_value;
+
+ fpscr_base_regnum = tdep->FPSCR_REGNUM;
+ sr_base_regnum = tdep->SR_REGNUM;
+
+ /* Build the value in the provided buffer. */
+ /* FPSCR_C is a very weird register that contains sparse bits
+ from the FPSCR and the SR architectural registers.
+ Specifically: */
+ /* *INDENT-OFF* */
+ /*
+ FPSRC_C bit
+ 0 Bit 0 of FPSCR
+ 1 reserved
+ 2-17 Bit 2-18 of FPSCR
+ 18-20 Bits 12,13,14 of SR
+ 21-31 reserved
+ */
+ /* *INDENT-ON* */
+ /* Get FPSCR into a local buffer */
+ regcache_read (fpscr_base_regnum, temp_buffer);
+ /* Get value as an int. */
+ fpscr_value = extract_unsigned_integer (temp_buffer, 4);
+ /* Get SR into a local buffer */
+ regcache_read (sr_base_regnum, temp_buffer);
+ /* Get value as an int. */
+ sr_value = extract_unsigned_integer (temp_buffer, 4);
+ /* Build the new value. */
+ fpscr_c_part1_value = fpscr_value & 0x3fffd;
+ fpscr_c_part2_value = (sr_value & 0x7000) << 6;
+ fpscr_c_value = fpscr_c_part1_value | fpscr_c_part2_value;
+ /* Store that in out buffer!!! */
+ store_unsigned_integer (buffer, 4, fpscr_c_value);
+ /* FIXME There is surely an endianness gotcha here. */
+ }
+
+ else if (reg_nr == tdep->FPUL_C_REGNUM)
+ {
+ base_regnum = sh64_compact_reg_base_num (reg_nr);
+
+ /* FPUL_C register is floating point register 32,
+ same size, same endianness. */
+ regcache_read (base_regnum, buffer);
+ }
+}
+
+static void
+sh64_register_read (struct gdbarch *gdbarch, int reg_nr, char *buffer)
+{
+
+ if (reg_nr >= 0 && reg_nr < gdbarch_tdep (current_gdbarch)->DR0_REGNUM)
+ /* It is a regular register. */
+ regcache_read (reg_nr, buffer);
+ else
+ /* It is a pseudo register and we need to construct its value */
+ sh64_pseudo_register_read (reg_nr, buffer);
+}
+
+void
+sh_pseudo_register_write (int reg_nr, char *buffer)
+{
+ int base_regnum, portion;
+ char *temp_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (reg_nr >= tdep->DR0_REGNUM
+ && reg_nr <= tdep->DR_LAST_REGNUM)
+ {
+ base_regnum = dr_reg_base_num (reg_nr);
+
+ /* We must pay attention to the endiannes. */
+ sh_sh4_register_convert_to_raw (REGISTER_VIRTUAL_TYPE (reg_nr), reg_nr,
+ buffer, temp_buffer);
+
+ /* Write the real regs for which this one is an alias. */
+ for (portion = 0; portion < 2; portion++)
+ regcache_write (base_regnum + portion,
+ temp_buffer + REGISTER_RAW_SIZE (base_regnum) * portion);
+ }
+ else if (reg_nr >= tdep->FV0_REGNUM
+ && reg_nr <= tdep->FV_LAST_REGNUM)
+ {
+ base_regnum = fv_reg_base_num (reg_nr);
+
+ /* Write the real regs for which this one is an alias. */
+ for (portion = 0; portion < 4; portion++)
+ regcache_write (base_regnum + portion,
+ buffer + REGISTER_RAW_SIZE (base_regnum) * portion);
+ }
+}
+
+static void
+sh4_register_write (struct gdbarch *gdbarch, int reg_nr, char *buffer)
+{
+ if (reg_nr >= 0 && reg_nr < gdbarch_tdep (current_gdbarch)->DR0_REGNUM)
+ /* It is a regular register. */
+ regcache_write (reg_nr, buffer);
+ else
+ /* It is a pseudo register and we need to construct its value */
+ sh_pseudo_register_write (reg_nr, buffer);
+}
+
+void
+sh64_pseudo_register_write (int reg_nr, char *buffer)
+{
+ int base_regnum, portion;
+ int offset;
+ char *temp_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (reg_nr >= tdep->DR0_REGNUM
+ && reg_nr <= tdep->DR_LAST_REGNUM)
+ {
+ base_regnum = dr_reg_base_num (reg_nr);
+ /* We must pay attention to the endiannes. */
+ sh_sh64_register_convert_to_raw (REGISTER_VIRTUAL_TYPE (reg_nr), reg_nr,
+ buffer, temp_buffer);
+
+
+ /* Write the real regs for which this one is an alias. */
+ for (portion = 0; portion < 2; portion++)
+ regcache_write (base_regnum + portion,
+ temp_buffer + REGISTER_RAW_SIZE (base_regnum) * portion);
+ }
+
+ else if (reg_nr >= tdep->FPP0_REGNUM
+ && reg_nr <= tdep->FPP_LAST_REGNUM)
+ {
+ base_regnum = fpp_reg_base_num (reg_nr);
+
+ /* Write the real regs for which this one is an alias. */
+ for (portion = 0; portion < 2; portion++)
+ regcache_write (base_regnum + portion,
+ buffer + REGISTER_RAW_SIZE (base_regnum) * portion);
+ }
+
+ else if (reg_nr >= tdep->FV0_REGNUM
+ && reg_nr <= tdep->FV_LAST_REGNUM)
+ {
+ base_regnum = fv_reg_base_num (reg_nr);
+
+ /* Write the real regs for which this one is an alias. */
+ for (portion = 0; portion < 4; portion++)
+ regcache_write (base_regnum + portion,
+ buffer + REGISTER_RAW_SIZE (base_regnum) * portion);
+ }
+
+ /* sh compact general pseudo registers. 1-to-1 with a shmedia
+ register but only 4 bytes of it. */
+ else if (reg_nr >= tdep->R0_C_REGNUM
+ && reg_nr <= tdep->T_C_REGNUM)
+ {
+ base_regnum = sh64_compact_reg_base_num (reg_nr);
+ /* reg_nr is 32 bit here, and base_regnum is 64 bits. */
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ offset = 4;
+ else
+ offset = 0;
+ /* Let's read the value of the base register into a temporary
+ buffer, so that overwriting the last four bytes with the new
+ value of the pseudo will leave the upper 4 bytes unchanged. */
+ regcache_read (base_regnum, temp_buffer);
+ /* Write as an 8 byte quantity */
+ memcpy (temp_buffer + offset, buffer, 4);
+ regcache_write (base_regnum, temp_buffer);
+ }
+
+ /* sh floating point compact pseudo registers. 1-to-1 with a shmedia
+ registers. Both are 4 bytes. */
+ else if (reg_nr >= tdep->FP0_C_REGNUM
+ && reg_nr <= tdep->FP_LAST_C_REGNUM)
+ {
+ base_regnum = sh64_compact_reg_base_num (reg_nr);
+ regcache_write (base_regnum, buffer);
+ }
+
+ else if (reg_nr >= tdep->DR0_C_REGNUM
+ && reg_nr <= tdep->DR_LAST_C_REGNUM)
+ {
+ base_regnum = sh64_compact_reg_base_num (reg_nr);
+ for (portion = 0; portion < 2; portion++)
+ {
+ /* We must pay attention to the endiannes. */
+ sh_sh64_register_convert_to_raw (REGISTER_VIRTUAL_TYPE (reg_nr), reg_nr,
+ buffer, temp_buffer);
+
+ regcache_write (base_regnum + portion,
+ temp_buffer + REGISTER_RAW_SIZE (base_regnum) * portion);
+ }
+ }
+
+ else if (reg_nr >= tdep->FV0_C_REGNUM
+ && reg_nr <= tdep->FV_LAST_C_REGNUM)
+ {
+ base_regnum = sh64_compact_reg_base_num (reg_nr);
+
+ for (portion = 0; portion < 4; portion++)
+ {
+ regcache_write (base_regnum + portion,
+ buffer + REGISTER_RAW_SIZE (base_regnum) * portion);
+ }
+ }
+
+ else if (reg_nr == tdep->FPSCR_C_REGNUM)
+ {
+ int fpscr_base_regnum;
+ int sr_base_regnum;
+ unsigned int fpscr_value;
+ unsigned int sr_value;
+ unsigned int old_fpscr_value;
+ unsigned int old_sr_value;
+ unsigned int fpscr_c_value;
+ unsigned int fpscr_mask;
+ unsigned int sr_mask;
+
+ fpscr_base_regnum = tdep->FPSCR_REGNUM;
+ sr_base_regnum = tdep->SR_REGNUM;
+
+ /* FPSCR_C is a very weird register that contains sparse bits
+ from the FPSCR and the SR architectural registers.
+ Specifically: */
+ /* *INDENT-OFF* */
+ /*
+ FPSRC_C bit
+ 0 Bit 0 of FPSCR
+ 1 reserved
+ 2-17 Bit 2-18 of FPSCR
+ 18-20 Bits 12,13,14 of SR
+ 21-31 reserved
+ */
+ /* *INDENT-ON* */
+ /* Get value as an int. */
+ fpscr_c_value = extract_unsigned_integer (buffer, 4);
+
+ /* Build the new values. */
+ fpscr_mask = 0x0003fffd;
+ sr_mask = 0x001c0000;
+
+ fpscr_value = fpscr_c_value & fpscr_mask;
+ sr_value = (fpscr_value & sr_mask) >> 6;
+
+ regcache_read (fpscr_base_regnum, temp_buffer);
+ old_fpscr_value = extract_unsigned_integer (temp_buffer, 4);
+ old_fpscr_value &= 0xfffc0002;
+ fpscr_value |= old_fpscr_value;
+ store_unsigned_integer (temp_buffer, 4, fpscr_value);
+ regcache_write (fpscr_base_regnum, temp_buffer);
+
+ regcache_read (sr_base_regnum, temp_buffer);
+ old_sr_value = extract_unsigned_integer (temp_buffer, 4);
+ old_sr_value &= 0xffff8fff;
+ sr_value |= old_sr_value;
+ store_unsigned_integer (temp_buffer, 4, sr_value);
+ regcache_write (sr_base_regnum, temp_buffer);
+ }
+
+ else if (reg_nr == tdep->FPUL_C_REGNUM)
+ {
+ base_regnum = sh64_compact_reg_base_num (reg_nr);
+ regcache_write (base_regnum, buffer);
+ }
+}
+
+static void
+sh64_register_write (struct gdbarch *gdbarch, int reg_nr, char *buffer)
+{
+ if (reg_nr >= 0 && reg_nr < gdbarch_tdep (current_gdbarch)->DR0_REGNUM)
+ /* It is a regular register. */
+ regcache_write (reg_nr, buffer);
+ else
+ /* It is a pseudo register and we need to construct its value */
+ sh64_pseudo_register_write (reg_nr, buffer);
+}
+
+/* Floating point vector of 4 float registers. */
+static void
+do_fv_register_info (int fv_regnum)
+{
+ int first_fp_reg_num = fv_reg_base_num (fv_regnum);
+ printf_filtered ("fv%d\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n",
+ fv_regnum - gdbarch_tdep (current_gdbarch)->FV0_REGNUM,
+ (int) read_register (first_fp_reg_num),
+ (int) read_register (first_fp_reg_num + 1),
+ (int) read_register (first_fp_reg_num + 2),
+ (int) read_register (first_fp_reg_num + 3));
+}
+
+/* Floating point vector of 4 float registers, compact mode. */
+static void
+do_fv_c_register_info (int fv_regnum)
+{
+ int first_fp_reg_num = sh64_compact_reg_base_num (fv_regnum);
+ printf_filtered ("fv%d_c\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n",
+ fv_regnum - gdbarch_tdep (current_gdbarch)->FV0_C_REGNUM,
+ (int) read_register (first_fp_reg_num),
+ (int) read_register (first_fp_reg_num + 1),
+ (int) read_register (first_fp_reg_num + 2),
+ (int) read_register (first_fp_reg_num + 3));
+}
+
+/* Pairs of single regs. The DR are instead double precision
+ registers. */
+static void
+do_fpp_register_info (int fpp_regnum)
+{
+ int first_fp_reg_num = fpp_reg_base_num (fpp_regnum);
+
+ printf_filtered ("fpp%d\t0x%08x\t0x%08x\n",
+ fpp_regnum - gdbarch_tdep (current_gdbarch)->FPP0_REGNUM,
+ (int) read_register (first_fp_reg_num),
+ (int) read_register (first_fp_reg_num + 1));
+}
+
+/* Double precision registers. */
+static void
+do_dr_register_info (int dr_regnum)
+{
+ int first_fp_reg_num = dr_reg_base_num (dr_regnum);
+
+ printf_filtered ("dr%d\t0x%08x%08x\n",
+ dr_regnum - gdbarch_tdep (current_gdbarch)->DR0_REGNUM,
+ (int) read_register (first_fp_reg_num),
+ (int) read_register (first_fp_reg_num + 1));
+}
+
+/* Double precision registers, compact mode. */
+static void
+do_dr_c_register_info (int dr_regnum)
+{
+ int first_fp_reg_num = sh64_compact_reg_base_num (dr_regnum);
+
+ printf_filtered ("dr%d_c\t0x%08x%08x\n",
+ dr_regnum - gdbarch_tdep (current_gdbarch)->DR0_C_REGNUM,
+ (int) read_register (first_fp_reg_num),
+ (int) read_register (first_fp_reg_num +1));
+}
+
+/* General register in compact mode. */
+static void
+do_r_c_register_info (int r_c_regnum)
+{
+ int regnum = sh64_compact_reg_base_num (r_c_regnum);
+
+ printf_filtered ("r%d_c\t0x%08x\n",
+ r_c_regnum - gdbarch_tdep (current_gdbarch)->R0_C_REGNUM,
+ /*FIXME!!!*/ (int) read_register (regnum));
+}
+
+/* FIXME:!! THIS SHOULD TAKE CARE OF GETTING THE RIGHT PORTION OF THE
+ shmedia REGISTERS. */
+/* Control registers, compact mode. */
+static void
+do_cr_c_register_info (int cr_c_regnum)
+{
+ switch (cr_c_regnum)
+ {
+ case 237: printf_filtered ("pc_c\t0x%08x\n", (int) read_register (cr_c_regnum));
+ break;
+ case 238: printf_filtered ("gbr_c\t0x%08x\n", (int) read_register (cr_c_regnum));
+ break;
+ case 239: printf_filtered ("mach_c\t0x%08x\n", (int) read_register (cr_c_regnum));
+ break;
+ case 240: printf_filtered ("macl_c\t0x%08x\n", (int) read_register (cr_c_regnum));
+ break;
+ case 241: printf_filtered ("pr_c\t0x%08x\n", (int) read_register (cr_c_regnum));
+ break;
+ case 242: printf_filtered ("t_c\t0x%08x\n", (int) read_register (cr_c_regnum));
+ break;
+ case 243: printf_filtered ("fpscr_c\t0x%08x\n", (int) read_register (cr_c_regnum));
+ break;
+ case 244: printf_filtered ("fpul_c\t0x%08x\n", (int)read_register (cr_c_regnum));
+ break;
+ }
+}
+
+static void
+sh_do_pseudo_register (int regnum)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (regnum < NUM_REGS || regnum >= NUM_REGS + NUM_PSEUDO_REGS)
+ internal_error (__FILE__, __LINE__,
+ "Invalid pseudo register number %d\n", regnum);
+ else if (regnum >= tdep->DR0_REGNUM
+ && regnum < tdep->DR_LAST_REGNUM)
+ do_dr_register_info (regnum);
+ else if (regnum >= tdep->FV0_REGNUM
+ && regnum <= tdep->FV_LAST_REGNUM)
+ do_fv_register_info (regnum);
+}
+
+static void
+sh_do_fp_register (int regnum)
+{ /* do values for FP (float) regs */
+ char *raw_buffer;
+ double flt; /* double extracted from raw hex data */
+ int inv;
+ int j;
+
+ /* Allocate space for the float. */
+ raw_buffer = (char *) alloca (REGISTER_RAW_SIZE (FP0_REGNUM));
+
+ /* Get the data in raw format. */
+ if (!frame_register_read (selected_frame, regnum, raw_buffer))
+ error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
+
+ /* Get the register as a number */
+ flt = unpack_double (builtin_type_float, raw_buffer, &inv);
+
+ /* Print the name and some spaces. */
+ fputs_filtered (REGISTER_NAME (regnum), gdb_stdout);
+ print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), gdb_stdout);
+
+ /* Print the value. */
+ if (inv)
+ printf_filtered ("<invalid float>");
+ else
+ printf_filtered ("%-10.9g", flt);
+
+ /* Print the fp register as hex. */
+ printf_filtered ("\t(raw 0x");
+ for (j = 0; j < REGISTER_RAW_SIZE (regnum); j++)
+ {
+ register int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j
+ : REGISTER_RAW_SIZE (regnum) - 1 - j;
+ printf_filtered ("%02x", (unsigned char) raw_buffer[idx]);
+ }
+ printf_filtered (")");
+ printf_filtered ("\n");
+}
+
+static void
+sh64_do_pseudo_register (int regnum)
+{
+ /* All the sh64-compact mode registers are pseudo registers. */
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (regnum < NUM_REGS
+ || regnum >= NUM_REGS + NUM_PSEUDO_REGS_SH_MEDIA + NUM_PSEUDO_REGS_SH_COMPACT)
+ internal_error (__FILE__, __LINE__,
+ "Invalid pseudo register number %d\n", regnum);
+
+ else if ((regnum >= tdep->DR0_REGNUM
+ && regnum <= tdep->DR_LAST_REGNUM))
+ do_dr_register_info (regnum);
+
+ else if ((regnum >= tdep->DR0_C_REGNUM
+ && regnum <= tdep->DR_LAST_C_REGNUM))
+ do_dr_c_register_info (regnum);
+
+ else if ((regnum >= tdep->FV0_REGNUM
+ && regnum <= tdep->FV_LAST_REGNUM))
+ do_fv_register_info (regnum);
+
+ else if ((regnum >= tdep->FV0_C_REGNUM
+ && regnum <= tdep->FV_LAST_C_REGNUM))
+ do_fv_c_register_info (regnum);
+
+ else if (regnum >= tdep->FPP0_REGNUM
+ && regnum <= tdep->FPP_LAST_REGNUM)
+ do_fpp_register_info (regnum);
+
+ else if (regnum >= tdep->R0_C_REGNUM
+ && regnum <= tdep->R_LAST_C_REGNUM)
+ do_r_c_register_info (regnum); /* FIXME, this function will not print the right format */
+
+ else if (regnum >= tdep->FP0_C_REGNUM
+ && regnum <= tdep->FP_LAST_C_REGNUM)
+ sh_do_fp_register (regnum); /* this should work also for pseudoregs */
+
+ else if (regnum >= tdep->PC_C_REGNUM
+ && regnum <= tdep->FPUL_C_REGNUM)
+ do_cr_c_register_info (regnum);
+
+}
+
+static void
+sh_do_register (int regnum)
+{
+ char raw_buffer[MAX_REGISTER_RAW_SIZE];
+
+ fputs_filtered (REGISTER_NAME (regnum), gdb_stdout);
+ print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), gdb_stdout);
+
+ /* Get the data in raw format. */
+ if (!frame_register_read (selected_frame, regnum, raw_buffer))
+ printf_filtered ("*value not available*\n");
+
+ val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0, 0,
+ gdb_stdout, 'x', 1, 0, Val_pretty_default);
+ printf_filtered ("\t");
+ val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0, 0,
+ gdb_stdout, 0, 1, 0, Val_pretty_default);
+ printf_filtered ("\n");
+}
+
+static void
+sh_print_register (int regnum)
+{
+ if (regnum < 0 || regnum >= NUM_REGS + NUM_PSEUDO_REGS)
+ internal_error (__FILE__, __LINE__,
+ "Invalid register number %d\n", regnum);
+
+ else if (regnum >= 0 && regnum < NUM_REGS)
+ {
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
+ sh_do_fp_register (regnum); /* FP regs */
+ else
+ sh_do_register (regnum); /* All other regs */
+ }
+
+ else if (regnum < NUM_REGS + NUM_PSEUDO_REGS)
+ do_pseudo_register (regnum);
+}
+
+void
+sh_do_registers_info (int regnum, int fpregs)
+{
+ if (regnum != -1) /* do one specified register */
+ {
+ if (*(REGISTER_NAME (regnum)) == '\0')
+ error ("Not a valid register for the current processor type");
+
+ sh_print_register (regnum);
+ }
+ else
+ /* do all (or most) registers */
+ {
+ regnum = 0;
+ while (regnum < NUM_REGS)
+ {
+ /* If the register name is empty, it is undefined for this
+ processor, so don't display anything. */
+ if (REGISTER_NAME (regnum) == NULL
+ || *(REGISTER_NAME (regnum)) == '\0')
+ {
+ regnum++;
+ continue;
+ }
+
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
+ {
+ if (fpregs)
+ {
+ /* true for "INFO ALL-REGISTERS" command */
+ sh_do_fp_register (regnum); /* FP regs */
+ regnum ++;
+ }
+ else
+ regnum += (gdbarch_tdep (current_gdbarch)->FP_LAST_REGNUM - FP0_REGNUM); /* skip FP regs */
+ }
+ else
+ {
+ sh_do_register (regnum); /* All other regs */
+ regnum++;
+ }
+ }
+
+ if (fpregs)
+ while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
+ {
+ do_pseudo_register (regnum);
+ regnum++;
+ }
+ }
+}
+
+void
+sh_compact_do_registers_info (int regnum, int fpregs)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ if (regnum != -1) /* do one specified register */
+ {
+ if (*(REGISTER_NAME (regnum)) == '\0')
+ error ("Not a valid register for the current processor type");
+
+ if (regnum >= 0 && regnum < tdep->R0_C_REGNUM)
+ error ("Not a valid register for the current processor mode.");
+
+ sh_print_register (regnum);
+ }
+ else
+ /* do all compact registers */
+ {
+ regnum = tdep->R0_C_REGNUM;
+ while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
+ {
+ do_pseudo_register (regnum);
+ regnum++;
+ }
+ }
+}
+
+void
+sh64_do_registers_info (int regnum, int fpregs)
+{
+ if (pc_is_isa32 (selected_frame->pc))
+ sh_do_registers_info (regnum, fpregs);
+ else
+ sh_compact_do_registers_info (regnum, fpregs);
+}
+
+#ifdef SVR4_SHARED_LIBS
+
+/* Fetch (and possibly build) an appropriate link_map_offsets structure
+ for native i386 linux targets using the struct offsets defined in
+ link.h (but without actual reference to that file).
+
+ This makes it possible to access i386-linux shared libraries from
+ a gdb that was not built on an i386-linux host (for cross debugging).
+ */
+
+struct link_map_offsets *
+sh_linux_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = 0;
+
+ if (lmp == 0)
+ {
+ lmp = &lmo;
+
+ lmo.r_debug_size = 8; /* 20 not actual size but all we need */
+
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 4;
+
+ lmo.link_map_size = 20; /* 552 not actual size but all we need */
+
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 4;
+
+ lmo.l_name_offset = 4;
+ lmo.l_name_size = 4;
+
+ lmo.l_next_offset = 12;
+ lmo.l_next_size = 4;
+
+ lmo.l_prev_offset = 16;
+ lmo.l_prev_size = 4;
+ }
+
+ return lmp;
+}
+#endif /* SVR4_SHARED_LIBS */
+
+
+static gdbarch_init_ftype sh_gdbarch_init;
+
+static struct gdbarch *
+sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ static LONGEST sh_call_dummy_words[] = {0};
+ struct gdbarch *gdbarch;
+ struct gdbarch_tdep *tdep;
+ gdbarch_register_name_ftype *sh_register_name;
+ gdbarch_store_return_value_ftype *sh_store_return_value;
+ gdbarch_register_virtual_type_ftype *sh_register_virtual_type;
+ enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
+
+ /* Try to determine the ABI of the object we are loading. */
+
+ if (info.abfd != NULL)
+ {
+ osabi = gdbarch_lookup_osabi (info.abfd);
+ /* If we get "unknown" back, just leave it that way. */
+ }
+
+ /* Find a candidate among the list of pre-declared architectures. */
+ for (arches = gdbarch_list_lookup_by_info (arches, &info);
+ arches != NULL;
+ arches = gdbarch_list_lookup_by_info (arches->next, &info))
+ {
+ /* Make sure the ABI selection matches. */
+ tdep = gdbarch_tdep (arches->gdbarch);
+ if (tdep && tdep->osabi == osabi)
+ return arches->gdbarch;
+ }
+
+ /* None found, create a new architecture from the information
+ provided. */
+ tdep = XMALLOC (struct gdbarch_tdep);
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ tdep->osabi = osabi;
+
+ /* Initialize the register numbers that are not common to all the
+ variants to -1, if necessary thse will be overwritten in the case
+ statement below. */
+ tdep->FPUL_REGNUM = -1;
+ tdep->FPSCR_REGNUM = -1;
+ tdep->PR_REGNUM = 17;
+ tdep->SR_REGNUM = 22;
+ tdep->DSR_REGNUM = -1;
+ tdep->FP_LAST_REGNUM = -1;
+ tdep->A0G_REGNUM = -1;
+ tdep->A0_REGNUM = -1;
+ tdep->A1G_REGNUM = -1;
+ tdep->A1_REGNUM = -1;
+ tdep->M0_REGNUM = -1;
+ tdep->M1_REGNUM = -1;
+ tdep->X0_REGNUM = -1;
+ tdep->X1_REGNUM = -1;
+ tdep->Y0_REGNUM = -1;
+ tdep->Y1_REGNUM = -1;
+ tdep->MOD_REGNUM = -1;
+ tdep->RS_REGNUM = -1;
+ tdep->RE_REGNUM = -1;
+ tdep->SSR_REGNUM = -1;
+ tdep->SPC_REGNUM = -1;
+ tdep->DR0_REGNUM = -1;
+ tdep->DR_LAST_REGNUM = -1;
+ tdep->FV0_REGNUM = -1;
+ tdep->FV_LAST_REGNUM = -1;
+ tdep->ARG0_REGNUM = 4;
+ tdep->ARGLAST_REGNUM = 7;
+ tdep->RETURN_REGNUM = 0;
+ tdep->FLOAT_ARGLAST_REGNUM = -1;
+
+ tdep->sh_abi = SH_ABI_UNKNOWN;
+
+ set_gdbarch_fp0_regnum (gdbarch, -1);
+ set_gdbarch_num_pseudo_regs (gdbarch, 0);
+ set_gdbarch_max_register_raw_size (gdbarch, 4);
+ set_gdbarch_max_register_virtual_size (gdbarch, 4);
+ set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_num_regs (gdbarch, SH_DEFAULT_NUM_REGS);
+ set_gdbarch_sp_regnum (gdbarch, 15);
+ set_gdbarch_fp_regnum (gdbarch, 14);
+ set_gdbarch_pc_regnum (gdbarch, 16);
+ set_gdbarch_register_size (gdbarch, 4);
+ set_gdbarch_register_bytes (gdbarch, SH_DEFAULT_NUM_REGS * 4);
+ set_gdbarch_do_registers_info (gdbarch, sh_do_registers_info);
+ set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc);
+ set_gdbarch_frame_chain (gdbarch, sh_frame_chain);
+ set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+ set_gdbarch_init_extra_frame_info (gdbarch, sh_init_extra_frame_info);
+ set_gdbarch_extract_return_value (gdbarch, sh_extract_return_value);
+ set_gdbarch_push_arguments (gdbarch, sh_push_arguments);
+ set_gdbarch_store_struct_return (gdbarch, sh_store_struct_return);
+ set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention);
+ set_gdbarch_extract_struct_value_address (gdbarch, sh_extract_struct_value_address);
+ set_gdbarch_pop_frame (gdbarch, sh_pop_frame);
+ set_gdbarch_print_insn (gdbarch, gdb_print_insn_sh);
+ skip_prologue_hard_way = sh_skip_prologue_hard_way;
+ do_pseudo_register = sh_do_pseudo_register;
+
+ switch (info.bfd_arch_info->mach)
+ {
+ case bfd_mach_sh:
+ sh_register_name = sh_sh_register_name;
+ sh_show_regs = sh_generic_show_regs;
+ sh_store_return_value = sh_default_store_return_value;
+ sh_register_virtual_type = sh_default_register_virtual_type;
+ set_gdbarch_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
+ set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
+ set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
+ set_gdbarch_register_byte (gdbarch, sh_default_register_byte);
+ break;
+ case bfd_mach_sh2:
+ sh_register_name = sh_sh_register_name;
+ sh_show_regs = sh_generic_show_regs;
+ sh_store_return_value = sh_default_store_return_value;
+ sh_register_virtual_type = sh_default_register_virtual_type;
+ set_gdbarch_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
+ set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
+ set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
+ set_gdbarch_register_byte (gdbarch, sh_default_register_byte);
+ break;
+ case bfd_mach_sh_dsp:
+ sh_register_name = sh_sh_dsp_register_name;
+ sh_show_regs = sh_dsp_show_regs;
+ sh_store_return_value = sh_default_store_return_value;
+ sh_register_virtual_type = sh_default_register_virtual_type;
+ set_gdbarch_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
+ set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
+ set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
+ set_gdbarch_register_byte (gdbarch, sh_default_register_byte);
+ tdep->DSR_REGNUM = 24;
+ tdep->A0G_REGNUM = 25;
+ tdep->A0_REGNUM = 26;
+ tdep->A1G_REGNUM = 27;
+ tdep->A1_REGNUM = 28;
+ tdep->M0_REGNUM = 29;
+ tdep->M1_REGNUM = 30;
+ tdep->X0_REGNUM = 31;
+ tdep->X1_REGNUM = 32;
+ tdep->Y0_REGNUM = 33;
+ tdep->Y1_REGNUM = 34;
+ tdep->MOD_REGNUM = 40;
+ tdep->RS_REGNUM = 43;
+ tdep->RE_REGNUM = 44;
+ break;
+ case bfd_mach_sh3:
+ sh_register_name = sh_sh3_register_name;
+ sh_show_regs = sh3_show_regs;
+ sh_store_return_value = sh_default_store_return_value;
+ sh_register_virtual_type = sh_default_register_virtual_type;
+ set_gdbarch_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
+ set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
+ set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
+ set_gdbarch_register_byte (gdbarch, sh_default_register_byte);
+ tdep->SSR_REGNUM = 41;
+ tdep->SPC_REGNUM = 42;
+ break;
+ case bfd_mach_sh3e:
+ sh_register_name = sh_sh3e_register_name;
+ sh_show_regs = sh3e_show_regs;
+ sh_store_return_value = sh3e_sh4_store_return_value;
+ sh_register_virtual_type = sh_sh3e_register_virtual_type;
+ set_gdbarch_frame_init_saved_regs (gdbarch, sh_fp_frame_init_saved_regs);
+ set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
+ set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
+ set_gdbarch_register_byte (gdbarch, sh_default_register_byte);
+ set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
+ set_gdbarch_fp0_regnum (gdbarch, 25);
+ tdep->FPUL_REGNUM = 23;
+ tdep->FPSCR_REGNUM = 24;
+ tdep->FP_LAST_REGNUM = 40;
+ tdep->SSR_REGNUM = 41;
+ tdep->SPC_REGNUM = 42;
+ break;
+ case bfd_mach_sh3_dsp:
+ sh_register_name = sh_sh3_dsp_register_name;
+ sh_show_regs = sh3_dsp_show_regs;
+ sh_store_return_value = sh_default_store_return_value;
+ sh_register_virtual_type = sh_default_register_virtual_type;
+ set_gdbarch_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
+ set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
+ set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
+ set_gdbarch_register_byte (gdbarch, sh_default_register_byte);
+ tdep->DSR_REGNUM = 24;
+ tdep->A0G_REGNUM = 25;
+ tdep->A0_REGNUM = 26;
+ tdep->A1G_REGNUM = 27;
+ tdep->A1_REGNUM = 28;
+ tdep->M0_REGNUM = 29;
+ tdep->M1_REGNUM = 30;
+ tdep->X0_REGNUM = 31;
+ tdep->X1_REGNUM = 32;
+ tdep->Y0_REGNUM = 33;
+ tdep->Y1_REGNUM = 34;
+ tdep->MOD_REGNUM = 40;
+ tdep->RS_REGNUM = 43;
+ tdep->RE_REGNUM = 44;
+ tdep->SSR_REGNUM = 41;
+ tdep->SPC_REGNUM = 42;
+ break;
+ case bfd_mach_sh4:
+ sh_register_name = sh_sh4_register_name;
+ sh_show_regs = sh4_show_regs;
+ sh_store_return_value = sh3e_sh4_store_return_value;
+ sh_register_virtual_type = sh_sh4_register_virtual_type;
+ set_gdbarch_frame_init_saved_regs (gdbarch, sh_fp_frame_init_saved_regs);
+ set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
+ set_gdbarch_fp0_regnum (gdbarch, 25);
+ set_gdbarch_register_raw_size (gdbarch, sh_sh4_register_raw_size);
+ set_gdbarch_register_virtual_size (gdbarch, sh_sh4_register_raw_size);
+ set_gdbarch_register_byte (gdbarch, sh_sh4_register_byte);
+ set_gdbarch_num_pseudo_regs (gdbarch, 12);
+ set_gdbarch_max_register_raw_size (gdbarch, 4 * 4);
+ set_gdbarch_max_register_virtual_size (gdbarch, 4 * 4);
+ set_gdbarch_register_read (gdbarch, sh4_register_read);
+ set_gdbarch_register_write (gdbarch, sh4_register_write);
+ tdep->FPUL_REGNUM = 23;
+ tdep->FPSCR_REGNUM = 24;
+ tdep->FP_LAST_REGNUM = 40;
+ tdep->SSR_REGNUM = 41;
+ tdep->SPC_REGNUM = 42;
+ tdep->DR0_REGNUM = 59;
+ tdep->DR_LAST_REGNUM = 66;
+ tdep->FV0_REGNUM = 67;
+ tdep->FV_LAST_REGNUM = 70;
+ break;
+ case bfd_mach_sh5:
+ tdep->PR_REGNUM = 18;
+ tdep->SR_REGNUM = 65;
+ tdep->FPSCR_REGNUM = SIM_SH64_FPCSR_REGNUM;
+ tdep->FP_LAST_REGNUM = SIM_SH64_FR0_REGNUM + SIM_SH64_NR_FP_REGS - 1;
+ tdep->SSR_REGNUM = SIM_SH64_SSR_REGNUM;
+ tdep->SPC_REGNUM = SIM_SH64_SPC_REGNUM;
+ tdep->TR7_REGNUM = SIM_SH64_TR0_REGNUM + 7;
+ tdep->FPP0_REGNUM = 173;
+ tdep->FPP_LAST_REGNUM = 204;
+ tdep->DR0_REGNUM = 141;
+ tdep->DR_LAST_REGNUM = 172;
+ tdep->FV0_REGNUM = 205;
+ tdep->FV_LAST_REGNUM = 220;
+ tdep->R0_C_REGNUM = 221;
+ tdep->R_LAST_C_REGNUM = 236;
+ tdep->PC_C_REGNUM = 237;
+ tdep->GBR_C_REGNUM = 238;
+ tdep->MACH_C_REGNUM = 239;
+ tdep->MACL_C_REGNUM = 240;
+ tdep->PR_C_REGNUM = 241;
+ tdep->T_C_REGNUM = 242;
+ tdep->FPSCR_C_REGNUM = 243;
+ tdep->FPUL_C_REGNUM = 244;
+ tdep->FP0_C_REGNUM = 245;
+ tdep->FP_LAST_C_REGNUM = 260;
+ tdep->DR0_C_REGNUM = 261;
+ tdep->DR_LAST_C_REGNUM = 268;
+ tdep->FV0_C_REGNUM = 269;
+ tdep->FV_LAST_C_REGNUM = 272;
+ tdep->ARG0_REGNUM = 2;
+ tdep->ARGLAST_REGNUM = 9;
+ tdep->RETURN_REGNUM = 2;
+ tdep->FLOAT_ARGLAST_REGNUM = 11;
+
+ set_gdbarch_num_pseudo_regs (gdbarch, NUM_PSEUDO_REGS_SH_MEDIA + NUM_PSEUDO_REGS_SH_COMPACT);
+ set_gdbarch_fp0_regnum (gdbarch, SIM_SH64_FR0_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, 64);
+
+ /* Determine the ABI */
+ if (bfd_get_arch_size (info.abfd) == 64)
+ {
+ /* If the ABI is the 64-bit one, it can only be sh-media. */
+ tdep->sh_abi = SH_ABI_64;
+ set_gdbarch_ptr_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+ set_gdbarch_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+ }
+ else
+ {
+ /* If the ABI is the 32-bit one it could be either media or
+ compact. */
+ tdep->sh_abi = SH_ABI_32;
+ set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ }
+
+ /* the number of real registers is the same whether we are in
+ ISA16(compact) or ISA32(media). */
+ set_gdbarch_num_regs (gdbarch, SIM_SH64_NR_REGS);
+ set_gdbarch_register_size (gdbarch, 8); /*????*/
+ set_gdbarch_register_bytes (gdbarch,
+ ((SIM_SH64_NR_FP_REGS + 1) * 4)
+ + (SIM_SH64_NR_REGS - SIM_SH64_NR_FP_REGS -1) * 8);
+
+ sh_register_name = sh_sh64_register_name;
+ sh_show_regs = sh64_show_regs;
+ sh_register_virtual_type = sh_sh64_register_virtual_type;
+ sh_store_return_value = sh64_store_return_value;
+ skip_prologue_hard_way = sh64_skip_prologue_hard_way;
+ do_pseudo_register = sh64_do_pseudo_register;
+ set_gdbarch_register_raw_size (gdbarch, sh_sh64_register_raw_size);
+ set_gdbarch_register_virtual_size (gdbarch, sh_sh64_register_raw_size);
+ set_gdbarch_register_byte (gdbarch, sh_sh64_register_byte);
+ /* This seems awfully wrong!*/
+ /*set_gdbarch_max_register_raw_size (gdbarch, 8);*/
+ /* should include the size of the pseudo regs. */
+ set_gdbarch_max_register_raw_size (gdbarch, 4 * 4);
+ /* Or should that go in the virtual_size? */
+ /*set_gdbarch_max_register_virtual_size (gdbarch, 8);*/
+ set_gdbarch_max_register_virtual_size (gdbarch, 4 * 4);
+ set_gdbarch_register_read (gdbarch, sh64_register_read);
+ set_gdbarch_register_write (gdbarch, sh64_register_write);
+
+ set_gdbarch_do_registers_info (gdbarch, sh64_do_registers_info);
+ set_gdbarch_frame_init_saved_regs (gdbarch, sh64_nofp_frame_init_saved_regs);
+ set_gdbarch_breakpoint_from_pc (gdbarch, sh_sh64_breakpoint_from_pc);
+ set_gdbarch_init_extra_frame_info (gdbarch, sh64_init_extra_frame_info);
+ set_gdbarch_frame_chain (gdbarch, sh64_frame_chain);
+ set_gdbarch_get_saved_register (gdbarch, sh64_get_saved_register);
+ set_gdbarch_extract_return_value (gdbarch, sh64_extract_return_value);
+ set_gdbarch_push_arguments (gdbarch, sh64_push_arguments);
+ /*set_gdbarch_store_struct_return (gdbarch, sh64_store_struct_return);*/
+ set_gdbarch_extract_struct_value_address (gdbarch, sh64_extract_struct_value_address);
+ set_gdbarch_use_struct_convention (gdbarch, sh64_use_struct_convention);
+ set_gdbarch_pop_frame (gdbarch, sh64_pop_frame);
+ set_gdbarch_elf_make_msymbol_special (gdbarch,
+ sh64_elf_make_msymbol_special);
+ break;
+ default:
+ sh_register_name = sh_generic_register_name;
+ sh_show_regs = sh_generic_show_regs;
+ sh_store_return_value = sh_default_store_return_value;
+ sh_register_virtual_type = sh_default_register_virtual_type;
+ set_gdbarch_frame_init_saved_regs (gdbarch, sh_nofp_frame_init_saved_regs);
+ set_gdbarch_register_raw_size (gdbarch, sh_default_register_raw_size);
+ set_gdbarch_register_virtual_size (gdbarch, sh_default_register_raw_size);
+ set_gdbarch_register_byte (gdbarch, sh_default_register_byte);
+ break;
+ }
+
+ set_gdbarch_read_pc (gdbarch, generic_target_read_pc);
+ set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
+ set_gdbarch_read_fp (gdbarch, generic_target_read_fp);
+ set_gdbarch_read_sp (gdbarch, generic_target_read_sp);
+ set_gdbarch_write_sp (gdbarch, generic_target_write_sp);
+
+ set_gdbarch_register_name (gdbarch, sh_register_name);
+ set_gdbarch_register_virtual_type (gdbarch, sh_register_virtual_type);
+
+ set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+ set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+ set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT);/*??should be 8?*/
+
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1); /*???*/
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
+ set_gdbarch_call_dummy_words (gdbarch, sh_call_dummy_words);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (sh_call_dummy_words));
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
+ set_gdbarch_coerce_float_to_double (gdbarch,
+ sh_coerce_float_to_double);
+
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+ set_gdbarch_push_return_address (gdbarch, sh_push_return_address);
+
+ set_gdbarch_store_return_value (gdbarch, sh_store_return_value);
+ set_gdbarch_skip_prologue (gdbarch, sh_skip_prologue);
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+ set_gdbarch_function_start_offset (gdbarch, 0);
+
+ set_gdbarch_frame_args_skip (gdbarch, 0);
+ set_gdbarch_frameless_function_invocation (gdbarch, frameless_look_for_prologue);
+ set_gdbarch_frame_chain_valid (gdbarch, generic_file_frame_chain_valid);
+ set_gdbarch_frame_saved_pc (gdbarch, sh_frame_saved_pc);
+ set_gdbarch_frame_args_address (gdbarch, default_frame_address);
+ set_gdbarch_frame_locals_address (gdbarch, default_frame_address);
+ set_gdbarch_saved_pc_after_call (gdbarch, sh_saved_pc_after_call);
+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+ set_gdbarch_believe_pcc_promotion (gdbarch, 1);
+
+ /* Hook in ABI-specific overrides, if they have been registered.
+
+ FIXME: if the ABI is unknown, this is probably an embedded target,
+ so we should not warn about this situation. */
+ gdbarch_init_osabi (info, gdbarch, osabi);
+
+ return gdbarch;
+}
+
+static void
+sh_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (tdep == NULL)
+ return;
+
+ fprintf_unfiltered (file, "sh_dump_tdep: OS ABI = %s\n",
+ gdbarch_osabi_name (tdep->osabi));
+}
+
+void
+_initialize_sh_tdep (void)
+{
+ struct cmd_list_element *c;
+
+ gdbarch_register (bfd_arch_sh, sh_gdbarch_init, sh_dump_tdep);
+
+ add_com ("regs", class_vars, sh_show_regs_command, "Print all registers");
+}
diff --git a/gdb/sh-tdep.h b/gdb/sh-tdep.h
new file mode 100644
index 00000000000..cd7f35a8324
--- /dev/null
+++ b/gdb/sh-tdep.h
@@ -0,0 +1,111 @@
+/* Target-specific definition for a Hitachi Super-H.
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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. */
+
+#ifndef SH_TDEP_H
+#define SH_TDEP_H
+
+#include "osabi.h"
+
+/* Contributed by Steve Chamberlain sac@cygnus.com */
+
+/* Information that is dependent on the processor variant. */
+
+enum sh_abi
+ {
+ SH_ABI_UNKNOWN,
+ SH_ABI_32,
+ SH_ABI_64
+ };
+
+struct gdbarch_tdep
+ {
+ int PR_REGNUM;
+ int FPUL_REGNUM; /* sh3e, sh4 */
+ int FPSCR_REGNUM; /* sh3e, sh4 */
+ int SR_REGNUM; /* sh-dsp, sh3, sh3-dsp, sh3e, sh4 */
+ int DSR_REGNUM; /* sh-dsp, sh3-dsp */
+ int FP_LAST_REGNUM; /* sh3e, sh4 */
+ int A0G_REGNUM; /* sh-dsp, sh3-dsp */
+ int A0_REGNUM; /* sh-dsp, sh3-dsp */
+ int A1G_REGNUM; /* sh-dsp, sh3-dsp */
+ int A1_REGNUM; /* sh-dsp, sh3-dsp */
+ int M0_REGNUM; /* sh-dsp, sh3-dsp */
+ int M1_REGNUM; /* sh-dsp, sh3-dsp */
+ int X0_REGNUM; /* sh-dsp, sh3-dsp */
+ int X1_REGNUM; /* sh-dsp, sh3-dsp */
+ int Y0_REGNUM; /* sh-dsp, sh3-dsp */
+ int Y1_REGNUM; /* sh-dsp, sh3-dsp */
+ int MOD_REGNUM; /* sh-dsp, sh3-dsp */
+ int SSR_REGNUM; /* sh3, sh3-dsp, sh3e, sh4 */
+ int SPC_REGNUM; /* sh3, sh3-dsp, sh3e, sh4 */
+ int RS_REGNUM; /* sh-dsp, sh3-dsp */
+ int RE_REGNUM; /* sh-dsp, sh3-dsp */
+ int DR0_REGNUM; /* sh4 */
+ int DR_LAST_REGNUM; /* sh4 */
+ int FV0_REGNUM; /* sh4 */
+ int FV_LAST_REGNUM; /* sh4 */
+ /* FPP stands for Floating Point Pair, to avoid confusion with
+ GDB's FP0_REGNUM, which is the number of the first Floating
+ point register. Unfortunately on the sh5, the floating point
+ registers are called FR, and the floating point pairs are called FP. */
+ int TR7_REGNUM; /* sh5-media*/
+ int FPP0_REGNUM; /* sh5-media*/
+ int FPP_LAST_REGNUM; /* sh5-media*/
+ int R0_C_REGNUM; /* sh5-compact*/
+ int R_LAST_C_REGNUM; /* sh5-compact*/
+ int PC_C_REGNUM; /* sh5-compact*/
+ int GBR_C_REGNUM; /* sh5-compact*/
+ int MACH_C_REGNUM; /* sh5-compact*/
+ int MACL_C_REGNUM; /* sh5-compact*/
+ int PR_C_REGNUM; /* sh5-compact*/
+ int T_C_REGNUM; /* sh5-compact*/
+ int FPSCR_C_REGNUM; /* sh5-compact*/
+ int FPUL_C_REGNUM; /* sh5-compact*/
+ int FP0_C_REGNUM; /* sh5-compact*/
+ int FP_LAST_C_REGNUM; /* sh5-compact*/
+ int DR0_C_REGNUM; /* sh5-compact*/
+ int DR_LAST_C_REGNUM; /* sh5-compact*/
+ int FV0_C_REGNUM; /* sh5-compact*/
+ int FV_LAST_C_REGNUM; /* sh5-compact*/
+ int ARG0_REGNUM;
+ int ARGLAST_REGNUM;
+ int FLOAT_ARGLAST_REGNUM;
+ int RETURN_REGNUM;
+ enum gdb_osabi osabi; /* OS/ABI of the inferior */
+ enum sh_abi sh_abi;
+ };
+
+/* Registers common to all the SH variants. */
+enum
+ {
+ R0_REGNUM = 0,
+ STRUCT_RETURN_REGNUM = 2,
+ ARG0_REGNUM = 4, /* Used in h8300-tdep.c */
+ ARGLAST_REGNUM = 7, /* Used in h8300-tdep.c */
+ PR_REGNUM = 17, /* used in sh3-rom.c */
+ GBR_REGNUM = 18,
+ VBR_REGNUM = 19,
+ MACH_REGNUM = 20,
+ MACL_REGNUM = 21,
+ SR_REGNUM = 22
+ };
+
+#endif /* SH_TDEP_H */
diff --git a/gdb/sh3-rom.c b/gdb/sh3-rom.c
new file mode 100644
index 00000000000..f450ac9d5fc
--- /dev/null
+++ b/gdb/sh3-rom.c
@@ -0,0 +1,384 @@
+/* Remote target glue for the Hitachi SH-3 ROM monitor.
+ Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "srec.h"
+#include "arch-utils.h"
+#include "regcache.h"
+
+#include "sh-tdep.h"
+
+static struct serial *parallel;
+static int parallel_in_use;
+
+static void sh3_open (char *args, int from_tty);
+
+static void
+sh3_supply_register (char *regname, int regnamelen, char *val, int vallen)
+{
+ int numregs;
+ int regno;
+
+ numregs = 1;
+ regno = -1;
+
+ if (regnamelen == 2)
+ {
+ switch (regname[0])
+ {
+ case 'S':
+ if (regname[1] == 'R')
+ regno = SR_REGNUM;
+ break;
+ case 'P':
+ if (regname[1] == 'C')
+ regno = PC_REGNUM;
+ else if (regname[1] == 'R')
+ regno = PR_REGNUM;
+ break;
+ }
+ }
+ else if (regnamelen == 3)
+ {
+ switch (regname[0])
+ {
+ case 'G':
+ case 'V':
+ if (regname[1] == 'B' && regname[2] == 'R')
+ {
+ if (regname[0] == 'G')
+ regno = VBR_REGNUM;
+ else
+ regno = GBR_REGNUM;
+ }
+ break;
+ case 'S':
+ if (regname[1] == 'S' && regname[2] == 'R')
+ regno = gdbarch_tdep (current_gdbarch)->SSR_REGNUM;
+ else if (regname[1] == 'P' && regname[2] == 'C')
+ regno = gdbarch_tdep (current_gdbarch)->SPC_REGNUM;
+ break;
+ }
+ }
+ else if (regnamelen == 4)
+ {
+ switch (regname[0])
+ {
+ case 'M':
+ if (regname[1] == 'A' && regname[2] == 'C')
+ {
+ if (regname[3] == 'H')
+ regno = MACH_REGNUM;
+ else if (regname[3] == 'L')
+ regno = MACL_REGNUM;
+ }
+ break;
+ case 'R':
+ if (regname[1] == '0' && regname[2] == '-' && regname[3] == '7')
+ {
+ regno = R0_REGNUM;
+ numregs = 8;
+ }
+ }
+ }
+ else if (regnamelen == 5)
+ {
+ if (regname[1] == '8' && regname[2] == '-' && regname[3] == '1'
+ && regname[4] == '5')
+ {
+ regno = R0_REGNUM + 8;
+ numregs = 8;
+ }
+ }
+ else if (regnamelen == 17)
+ {
+ }
+
+ if (regno >= 0)
+ while (numregs-- > 0)
+ val = monitor_supply_register (regno++, val);
+}
+
+static void
+sh3_load (struct serial *desc, char *file, int hashmark)
+{
+ if (parallel_in_use)
+ {
+ monitor_printf ("pl;s\r");
+ load_srec (parallel, file, 0, 80, SREC_ALL, hashmark, NULL);
+ monitor_expect_prompt (NULL, 0);
+ }
+ else
+ {
+ monitor_printf ("il;s:x\r");
+ monitor_expect ("\005", NULL, 0); /* Look for ENQ */
+ serial_write (desc, "\006", 1); /* Send ACK */
+ monitor_expect ("LO x\r", NULL, 0); /* Look for filename */
+
+ load_srec (desc, file, 0, 80, SREC_ALL, hashmark, NULL);
+
+ monitor_expect ("\005", NULL, 0); /* Look for ENQ */
+ serial_write (desc, "\006", 1); /* Send ACK */
+ monitor_expect_prompt (NULL, 0);
+ }
+}
+
+/* This array of registers need to match the indexes used by GDB.
+ This exists because the various ROM monitors use different strings
+ than does GDB, and don't necessarily support all the registers
+ either. So, typing "info reg sp" becomes a "r30". */
+
+static char *sh3_regnames[] =
+{
+ "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
+ "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
+ "PC", "PR", "GBR", "VBR", "MACH", "MACL", "SR",
+ NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "SSR", "SPC",
+ "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
+ "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
+ "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
+ "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
+};
+
+static char *sh3e_regnames[] =
+{
+ "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
+ "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
+ "PC", "PR", "GBR", "VBR", "MACH", "MACL", "SR",
+ "FPUL", "FPSCR",
+ "FR0", "FR1", "FR2", "FR3", "FR4", "FR5", "FR6", "FR7",
+ "FR8", "FR9", "FR10", "FR11", "FR12", "FR13", "FR14", "FR15",
+ "SSR", "SPC",
+ "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
+ "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
+ "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
+ "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
+};
+
+/* Define the monitor command strings. Since these are passed directly
+ through to a printf style function, we may include formatting
+ strings. We also need a CR or LF on the end. */
+
+static struct target_ops sh3_ops, sh3e_ops;
+
+static char *sh3_inits[] =
+{"\003", NULL}; /* Exits sub-command mode & download cmds */
+
+static struct monitor_ops sh3_cmds;
+
+static void
+init_sh3_cmds (void)
+{
+ sh3_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_GETMEM_READ_SINGLE; /* flags */
+ sh3_cmds.init = sh3_inits; /* monitor init string */
+ sh3_cmds.cont = "g\r"; /* continue command */
+ sh3_cmds.step = "s\r"; /* single step */
+ sh3_cmds.stop = "\003"; /* Interrupt program */
+ sh3_cmds.set_break = "b %x\r"; /* set a breakpoint */
+ sh3_cmds.clr_break = "b -%x\r"; /* clear a breakpoint */
+ sh3_cmds.clr_all_break = "b -\r"; /* clear all breakpoints */
+ sh3_cmds.fill = "f %x @%x %x\r"; /* fill (start len val) */
+ sh3_cmds.setmem.cmdb = "m %x %x\r"; /* setmem.cmdb (addr, value) */
+ sh3_cmds.setmem.cmdw = "m %x %x;w\r"; /* setmem.cmdw (addr, value) */
+ sh3_cmds.setmem.cmdl = "m %x %x;l\r"; /* setmem.cmdl (addr, value) */
+ sh3_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ sh3_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
+ sh3_cmds.setmem.term = NULL; /* setreg.term */
+ sh3_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
+ sh3_cmds.getmem.cmdb = "m %x\r"; /* getmem.cmdb (addr, len) */
+ sh3_cmds.getmem.cmdw = "m %x;w\r"; /* getmem.cmdw (addr, len) */
+ sh3_cmds.getmem.cmdl = "m %x;l\r"; /* getmem.cmdl (addr, len) */
+ sh3_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
+ sh3_cmds.getmem.resp_delim = "^ [0-9A-F]+ "; /* getmem.resp_delim */
+ sh3_cmds.getmem.term = "? "; /* getmem.term */
+ sh3_cmds.getmem.term_cmd = ".\r"; /* getmem.term_cmd */
+ sh3_cmds.setreg.cmd = ".%s %x\r"; /* setreg.cmd (name, value) */
+ sh3_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ sh3_cmds.setreg.term = NULL; /* setreg.term */
+ sh3_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
+ sh3_cmds.getreg.cmd = ".%s\r"; /* getreg.cmd (name) */
+ sh3_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */
+ sh3_cmds.getreg.term = "? "; /* getreg.term */
+ sh3_cmds.getreg.term_cmd = ".\r"; /* getreg.term_cmd */
+ sh3_cmds.dump_registers = "r\r"; /* dump_registers */
+ sh3_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\( +[0-9a-fA-F]+\\b\\)*\\)";
+ sh3_cmds.supply_register = sh3_supply_register; /* supply_register */
+ sh3_cmds.load_routine = sh3_load; /* load_routine */
+ sh3_cmds.load = NULL; /* download command */
+ sh3_cmds.loadresp = NULL; /* Load response */
+ sh3_cmds.prompt = "\n:"; /* monitor command prompt */
+ sh3_cmds.line_term = "\r"; /* end-of-line terminator */
+ sh3_cmds.cmd_end = ".\r"; /* optional command terminator */
+ sh3_cmds.target = &sh3_ops; /* target operations */
+ sh3_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ sh3_cmds.regnames = sh3_regnames; /* registers names */
+ sh3_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+} /* init_sh3_cmds */
+
+/* This monitor structure is identical except for a couple slots, so
+ we will fill it in from the base structure when needed. */
+
+static struct monitor_ops sh3e_cmds;
+
+static void
+sh3_open (char *args, int from_tty)
+{
+ char *serial_port_name = args;
+ char *parallel_port_name = 0;
+
+ if (args)
+ {
+ char *cursor = serial_port_name = xstrdup (args);
+
+ while (*cursor && *cursor != ' ')
+ cursor++;
+
+ if (*cursor)
+ *cursor++ = 0;
+
+ while (*cursor == ' ')
+ cursor++;
+
+ if (*cursor)
+ parallel_port_name = cursor;
+ }
+
+ monitor_open (serial_port_name, &sh3_cmds, from_tty);
+
+ if (parallel_port_name)
+ {
+ parallel = serial_open (parallel_port_name);
+
+ if (!parallel)
+ perror_with_name ("Unable to open parallel port.");
+
+ parallel_in_use = 1;
+ }
+
+ /* If we connected successfully, we know the processor is an SH3. */
+ set_architecture_from_arch_mach (bfd_arch_sh, bfd_mach_sh3);
+}
+
+
+static void
+sh3e_open (char *args, int from_tty)
+{
+ char *serial_port_name = args;
+ char *parallel_port_name = 0;
+
+ if (args)
+ {
+ char *cursor = serial_port_name = xstrdup (args);
+
+ while (*cursor && *cursor != ' ')
+ cursor++;
+
+ if (*cursor)
+ *cursor++ = 0;
+
+ while (*cursor == ' ')
+ cursor++;
+
+ if (*cursor)
+ parallel_port_name = cursor;
+ }
+
+ /* Set up the SH-3E monitor commands structure. */
+
+ memcpy (&sh3e_cmds, &sh3_cmds, sizeof (struct monitor_ops));
+
+ sh3e_cmds.target = &sh3e_ops;
+ sh3e_cmds.regnames = sh3e_regnames;
+
+ monitor_open (serial_port_name, &sh3e_cmds, from_tty);
+
+ if (parallel_port_name)
+ {
+ parallel = serial_open (parallel_port_name);
+
+ if (!parallel)
+ perror_with_name ("Unable to open parallel port.");
+
+ parallel_in_use = 1;
+ }
+
+ /* If we connected successfully, we know the processor is an SH3E. */
+ set_architecture_from_arch_mach (bfd_arch_sh, bfd_mach_sh3);
+}
+
+static void
+sh3_close (int quitting)
+{
+ monitor_close (quitting);
+ if (parallel_in_use)
+ {
+ serial_close (parallel);
+ parallel_in_use = 0;
+ }
+}
+
+void
+_initialize_sh3_rom (void)
+{
+ init_sh3_cmds ();
+ init_monitor_ops (&sh3_ops);
+
+ sh3_ops.to_shortname = "sh3";
+ sh3_ops.to_longname = "Hitachi SH-3 rom monitor";
+
+ sh3_ops.to_doc =
+ /* We can download through the parallel port too. */
+ "Debug on a Hitachi eval board running the SH-3E rom monitor.\n"
+ "Specify the serial device it is connected to.\n"
+ "If you want to use the parallel port to download to it, specify that\n"
+ "as an additional second argument.";
+
+ sh3_ops.to_open = sh3_open;
+ sh3_ops.to_close = sh3_close;
+
+ add_target (&sh3_ops);
+
+ /* Setup the SH3e, which has float registers. */
+
+ init_monitor_ops (&sh3e_ops);
+
+ sh3e_ops.to_shortname = "sh3e";
+ sh3e_ops.to_longname = "Hitachi SH-3E rom monitor";
+
+ sh3e_ops.to_doc =
+ /* We can download through the parallel port too. */
+ "Debug on a Hitachi eval board running the SH-3E rom monitor.\n"
+ "Specify the serial device it is connected to.\n"
+ "If you want to use the parallel port to download to it, specify that\n"
+ "as an additional second argument.";
+
+ sh3e_ops.to_open = sh3e_open;
+ sh3e_ops.to_close = sh3_close;
+
+ add_target (&sh3e_ops);
+}
diff --git a/gdb/shnbsd-nat.c b/gdb/shnbsd-nat.c
new file mode 100644
index 00000000000..e1b56e66405
--- /dev/null
+++ b/gdb/shnbsd-nat.c
@@ -0,0 +1,76 @@
+/* Native-dependent code for SuperH running NetBSD, for GDB.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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 <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "defs.h"
+#include "inferior.h"
+
+#include "shnbsd-tdep.h"
+
+/* Determine if PT_GETREGS fetches this register. */
+#define GETREGS_SUPPLIES(regno) \
+ (((regno) >= R0_REGNUM && (regno) <= (R0_REGNUM + 15)) \
+|| (regno) == PC_REGNUM || (regno) == PR_REGNUM \
+|| (regno) == MACH_REGNUM || (regno) == MACL_REGNUM \
+|| (regno) == SR_REGNUM)
+
+void
+fetch_inferior_registers (int regno)
+{
+ if (regno == -1 || GETREGS_SUPPLIES (regno))
+ {
+ struct reg inferior_registers;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &inferior_registers, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ shnbsd_supply_reg ((char *) &inferior_registers, regno);
+
+ if (regno != -1)
+ return;
+ }
+}
+
+void
+store_inferior_registers (int regno)
+{
+ if (regno == -1 || GETREGS_SUPPLIES (regno))
+ {
+ struct reg inferior_registers;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &inferior_registers, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ shnbsd_fill_reg ((char *) &inferior_registers, regno);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &inferior_registers, 0) == -1)
+ perror_with_name ("Couldn't set registers");
+
+ if (regno != -1)
+ return;
+ }
+}
diff --git a/gdb/shnbsd-tdep.c b/gdb/shnbsd-tdep.c
new file mode 100644
index 00000000000..02982267ba2
--- /dev/null
+++ b/gdb/shnbsd-tdep.c
@@ -0,0 +1,183 @@
+/* Target-dependent code for SuperH running NetBSD, for GDB.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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 "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "value.h"
+
+#include "solib-svr4.h"
+
+#include "nbsd-tdep.h"
+#include "sh-tdep.h"
+#include "shnbsd-tdep.h"
+
+/* Convert an r0-r15 register number into an offset into a ptrace
+ register structure. */
+static const int regmap[] =
+{
+ (20 * 4), /* r0 */
+ (19 * 4), /* r1 */
+ (18 * 4), /* r2 */
+ (17 * 4), /* r3 */
+ (16 * 4), /* r4 */
+ (15 * 4), /* r5 */
+ (14 * 4), /* r6 */
+ (13 * 4), /* r7 */
+ (12 * 4), /* r8 */
+ (11 * 4), /* r9 */
+ (10 * 4), /* r10 */
+ ( 9 * 4), /* r11 */
+ ( 8 * 4), /* r12 */
+ ( 7 * 4), /* r13 */
+ ( 6 * 4), /* r14 */
+ ( 5 * 4), /* r15 */
+};
+
+#define SIZEOF_STRUCT_REG (21 * 4)
+
+void
+shnbsd_supply_reg (char *regs, int regno)
+{
+ int i;
+
+ if (regno == PC_REGNUM || regno == -1)
+ supply_register (PC_REGNUM, regs + (0 * 4));
+
+ if (regno == SR_REGNUM || regno == -1)
+ supply_register (SR_REGNUM, regs + (1 * 4));
+
+ if (regno == PR_REGNUM || regno == -1)
+ supply_register (PR_REGNUM, regs + (2 * 4));
+
+ if (regno == MACH_REGNUM || regno == -1)
+ supply_register (MACH_REGNUM, regs + (3 * 4));
+
+ if (regno == MACL_REGNUM || regno == -1)
+ supply_register (MACL_REGNUM, regs + (4 * 4));
+
+ if ((regno >= R0_REGNUM && regno <= (R0_REGNUM + 15)) || regno == -1)
+ {
+ for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++)
+ if (regno == i || regno == -1)
+ supply_register (i, regs + regmap[i - R0_REGNUM]);
+ }
+}
+
+void
+shnbsd_fill_reg (char *regs, int regno)
+{
+ int i;
+
+ if (regno == PC_REGNUM || regno == -1)
+ regcache_collect (PC_REGNUM, regs + (0 * 4));
+
+ if (regno == SR_REGNUM || regno == -1)
+ regcache_collect (SR_REGNUM, regs + (1 * 4));
+
+ if (regno == PR_REGNUM || regno == -1)
+ regcache_collect (PR_REGNUM, regs + (2 * 4));
+
+ if (regno == MACH_REGNUM || regno == -1)
+ regcache_collect (MACH_REGNUM, regs + (3 * 4));
+
+ if (regno == MACL_REGNUM || regno == -1)
+ regcache_collect (MACL_REGNUM, regs + (4 * 4));
+
+ if ((regno >= R0_REGNUM && regno <= (R0_REGNUM + 15)) || regno == -1)
+ {
+ for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++)
+ if (regno == i || regno == -1)
+ regcache_collect (i, regs + regmap[i - R0_REGNUM]);
+ }
+}
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR ignore)
+{
+ /* We get everything from the .reg section. */
+ if (which != 0)
+ return;
+
+ if (core_reg_size < SIZEOF_STRUCT_REG)
+ {
+ warning ("Wrong size register set in core file.");
+ return;
+ }
+
+ /* Integer registers. */
+ shnbsd_supply_reg (core_reg_sect, -1);
+}
+
+static void
+fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR ignore)
+{
+ switch (which)
+ {
+ case 0: /* Integer registers. */
+ if (core_reg_size != SIZEOF_STRUCT_REG)
+ warning ("Wrong size register set in core file.");
+ else
+ shnbsd_supply_reg (core_reg_sect, -1);
+ break;
+
+ default:
+ /* Don't know what kind of register request this is; just ignore it. */
+ break;
+ }
+}
+
+static struct core_fns shnbsd_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+static struct core_fns shnbsd_elfcore_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_elfcore_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+static void
+shnbsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ nbsd_ilp32_solib_svr4_fetch_link_map_offsets);
+}
+
+void
+_initialize_shnbsd_tdep (void)
+{
+ add_core_fns (&shnbsd_core_fns);
+ add_core_fns (&shnbsd_elfcore_fns);
+
+ gdbarch_register_osabi (bfd_arch_sh, GDB_OSABI_NETBSD_ELF, shnbsd_init_abi);
+}
diff --git a/gdb/shnbsd-tdep.h b/gdb/shnbsd-tdep.h
new file mode 100644
index 00000000000..7364756bf56
--- /dev/null
+++ b/gdb/shnbsd-tdep.h
@@ -0,0 +1,28 @@
+/* Target-dependent definitions for SuperH running NetBSD, for GDB.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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. */
+
+#ifndef SH_NBSD_TDEP_H
+#define SH_NBSD_TDEP_H
+
+void shnbsd_supply_reg (char *, int);
+void shnbsd_fill_reg (char *, int);
+
+#endif /* SH_NBSD_TDEP_H */
diff --git a/gdb/signals/signals.c b/gdb/signals/signals.c
new file mode 100644
index 00000000000..643e450fbbe
--- /dev/null
+++ b/gdb/signals/signals.c
@@ -0,0 +1,844 @@
+/* Target signal translation functions for GDB.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002 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 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. */
+
+#ifdef GDBSERVER
+#include "server.h"
+#else
+#include "defs.h"
+#include "target.h"
+#endif
+
+#include <signal.h>
+
+/* This table must match in order and size the signals in enum target_signal
+ in target.h. */
+/* *INDENT-OFF* */
+static struct {
+ char *name;
+ char *string;
+ } signals [] =
+{
+ {"0", "Signal 0"},
+ {"SIGHUP", "Hangup"},
+ {"SIGINT", "Interrupt"},
+ {"SIGQUIT", "Quit"},
+ {"SIGILL", "Illegal instruction"},
+ {"SIGTRAP", "Trace/breakpoint trap"},
+ {"SIGABRT", "Aborted"},
+ {"SIGEMT", "Emulation trap"},
+ {"SIGFPE", "Arithmetic exception"},
+ {"SIGKILL", "Killed"},
+ {"SIGBUS", "Bus error"},
+ {"SIGSEGV", "Segmentation fault"},
+ {"SIGSYS", "Bad system call"},
+ {"SIGPIPE", "Broken pipe"},
+ {"SIGALRM", "Alarm clock"},
+ {"SIGTERM", "Terminated"},
+ {"SIGURG", "Urgent I/O condition"},
+ {"SIGSTOP", "Stopped (signal)"},
+ {"SIGTSTP", "Stopped (user)"},
+ {"SIGCONT", "Continued"},
+ {"SIGCHLD", "Child status changed"},
+ {"SIGTTIN", "Stopped (tty input)"},
+ {"SIGTTOU", "Stopped (tty output)"},
+ {"SIGIO", "I/O possible"},
+ {"SIGXCPU", "CPU time limit exceeded"},
+ {"SIGXFSZ", "File size limit exceeded"},
+ {"SIGVTALRM", "Virtual timer expired"},
+ {"SIGPROF", "Profiling timer expired"},
+ {"SIGWINCH", "Window size changed"},
+ {"SIGLOST", "Resource lost"},
+ {"SIGUSR1", "User defined signal 1"},
+ {"SIGUSR2", "User defined signal 2"},
+ {"SIGPWR", "Power fail/restart"},
+ {"SIGPOLL", "Pollable event occurred"},
+ {"SIGWIND", "SIGWIND"},
+ {"SIGPHONE", "SIGPHONE"},
+ {"SIGWAITING", "Process's LWPs are blocked"},
+ {"SIGLWP", "Signal LWP"},
+ {"SIGDANGER", "Swap space dangerously low"},
+ {"SIGGRANT", "Monitor mode granted"},
+ {"SIGRETRACT", "Need to relinquish monitor mode"},
+ {"SIGMSG", "Monitor mode data available"},
+ {"SIGSOUND", "Sound completed"},
+ {"SIGSAK", "Secure attention"},
+ {"SIGPRIO", "SIGPRIO"},
+ {"SIG33", "Real-time event 33"},
+ {"SIG34", "Real-time event 34"},
+ {"SIG35", "Real-time event 35"},
+ {"SIG36", "Real-time event 36"},
+ {"SIG37", "Real-time event 37"},
+ {"SIG38", "Real-time event 38"},
+ {"SIG39", "Real-time event 39"},
+ {"SIG40", "Real-time event 40"},
+ {"SIG41", "Real-time event 41"},
+ {"SIG42", "Real-time event 42"},
+ {"SIG43", "Real-time event 43"},
+ {"SIG44", "Real-time event 44"},
+ {"SIG45", "Real-time event 45"},
+ {"SIG46", "Real-time event 46"},
+ {"SIG47", "Real-time event 47"},
+ {"SIG48", "Real-time event 48"},
+ {"SIG49", "Real-time event 49"},
+ {"SIG50", "Real-time event 50"},
+ {"SIG51", "Real-time event 51"},
+ {"SIG52", "Real-time event 52"},
+ {"SIG53", "Real-time event 53"},
+ {"SIG54", "Real-time event 54"},
+ {"SIG55", "Real-time event 55"},
+ {"SIG56", "Real-time event 56"},
+ {"SIG57", "Real-time event 57"},
+ {"SIG58", "Real-time event 58"},
+ {"SIG59", "Real-time event 59"},
+ {"SIG60", "Real-time event 60"},
+ {"SIG61", "Real-time event 61"},
+ {"SIG62", "Real-time event 62"},
+ {"SIG63", "Real-time event 63"},
+ {"SIGCANCEL", "LWP internal signal"},
+ {"SIG32", "Real-time event 32"},
+ {"SIG64", "Real-time event 64"},
+ {"SIG65", "Real-time event 65"},
+ {"SIG66", "Real-time event 66"},
+ {"SIG67", "Real-time event 67"},
+ {"SIG68", "Real-time event 68"},
+ {"SIG69", "Real-time event 69"},
+ {"SIG70", "Real-time event 70"},
+ {"SIG71", "Real-time event 71"},
+ {"SIG72", "Real-time event 72"},
+ {"SIG73", "Real-time event 73"},
+ {"SIG74", "Real-time event 74"},
+ {"SIG75", "Real-time event 75"},
+ {"SIG76", "Real-time event 76"},
+ {"SIG77", "Real-time event 77"},
+ {"SIG78", "Real-time event 78"},
+ {"SIG79", "Real-time event 79"},
+ {"SIG80", "Real-time event 80"},
+ {"SIG81", "Real-time event 81"},
+ {"SIG82", "Real-time event 82"},
+ {"SIG83", "Real-time event 83"},
+ {"SIG84", "Real-time event 84"},
+ {"SIG85", "Real-time event 85"},
+ {"SIG86", "Real-time event 86"},
+ {"SIG87", "Real-time event 87"},
+ {"SIG88", "Real-time event 88"},
+ {"SIG89", "Real-time event 89"},
+ {"SIG90", "Real-time event 90"},
+ {"SIG91", "Real-time event 91"},
+ {"SIG92", "Real-time event 92"},
+ {"SIG93", "Real-time event 93"},
+ {"SIG94", "Real-time event 94"},
+ {"SIG95", "Real-time event 95"},
+ {"SIG96", "Real-time event 96"},
+ {"SIG97", "Real-time event 97"},
+ {"SIG98", "Real-time event 98"},
+ {"SIG99", "Real-time event 99"},
+ {"SIG100", "Real-time event 100"},
+ {"SIG101", "Real-time event 101"},
+ {"SIG102", "Real-time event 102"},
+ {"SIG103", "Real-time event 103"},
+ {"SIG104", "Real-time event 104"},
+ {"SIG105", "Real-time event 105"},
+ {"SIG106", "Real-time event 106"},
+ {"SIG107", "Real-time event 107"},
+ {"SIG108", "Real-time event 108"},
+ {"SIG109", "Real-time event 109"},
+ {"SIG110", "Real-time event 110"},
+ {"SIG111", "Real-time event 111"},
+ {"SIG112", "Real-time event 112"},
+ {"SIG113", "Real-time event 113"},
+ {"SIG114", "Real-time event 114"},
+ {"SIG115", "Real-time event 115"},
+ {"SIG116", "Real-time event 116"},
+ {"SIG117", "Real-time event 117"},
+ {"SIG118", "Real-time event 118"},
+ {"SIG119", "Real-time event 119"},
+ {"SIG120", "Real-time event 120"},
+ {"SIG121", "Real-time event 121"},
+ {"SIG122", "Real-time event 122"},
+ {"SIG123", "Real-time event 123"},
+ {"SIG124", "Real-time event 124"},
+ {"SIG125", "Real-time event 125"},
+ {"SIG126", "Real-time event 126"},
+ {"SIG127", "Real-time event 127"},
+
+ {"SIGINFO", "Information request"},
+
+ {NULL, "Unknown signal"},
+ {NULL, "Internal error: printing TARGET_SIGNAL_DEFAULT"},
+
+ /* Mach exceptions */
+ {"EXC_BAD_ACCESS", "Could not access memory"},
+ {"EXC_BAD_INSTRUCTION", "Illegal instruction/operand"},
+ {"EXC_ARITHMETIC", "Arithmetic exception"},
+ {"EXC_EMULATION", "Emulation instruction"},
+ {"EXC_SOFTWARE", "Software generated exception"},
+ {"EXC_BREAKPOINT", "Breakpoint"},
+
+ /* Last entry, used to check whether the table is the right size. */
+ {NULL, "TARGET_SIGNAL_MAGIC"}
+};
+/* *INDENT-ON* */
+
+
+
+/* Return the string for a signal. */
+char *
+target_signal_to_string (enum target_signal sig)
+{
+ if ((sig >= TARGET_SIGNAL_FIRST) && (sig <= TARGET_SIGNAL_LAST))
+ return signals[sig].string;
+ else
+ return signals[TARGET_SIGNAL_UNKNOWN].string;
+}
+
+/* Return the name for a signal. */
+char *
+target_signal_to_name (enum target_signal sig)
+{
+ if ((sig >= TARGET_SIGNAL_FIRST) && (sig <= TARGET_SIGNAL_LAST)
+ && signals[sig].name != NULL)
+ return signals[sig].name;
+ else
+ /* I think the code which prints this will always print it along
+ with the string, so no need to be verbose (very old comment). */
+ return "?";
+}
+
+/* Given a name, return its signal. */
+enum target_signal
+target_signal_from_name (char *name)
+{
+ enum target_signal sig;
+
+ /* It's possible we also should allow "SIGCLD" as well as "SIGCHLD"
+ for TARGET_SIGNAL_SIGCHLD. SIGIOT, on the other hand, is more
+ questionable; seems like by now people should call it SIGABRT
+ instead. */
+
+ /* This ugly cast brought to you by the native VAX compiler. */
+ for (sig = TARGET_SIGNAL_HUP;
+ sig < TARGET_SIGNAL_LAST;
+ sig = (enum target_signal) ((int) sig + 1))
+ if (signals[sig].name != NULL
+ && strcmp (name, signals[sig].name) == 0)
+ return sig;
+ return TARGET_SIGNAL_UNKNOWN;
+}
+
+/* The following functions are to help certain targets deal
+ with the signal/waitstatus stuff. They could just as well be in
+ a file called native-utils.c or unixwaitstatus-utils.c or whatever. */
+
+/* Convert host signal to our signals. */
+enum target_signal
+target_signal_from_host (int hostsig)
+{
+ /* A switch statement would make sense but would require special kludges
+ to deal with the cases where more than one signal has the same number. */
+
+ if (hostsig == 0)
+ return TARGET_SIGNAL_0;
+
+#if defined (SIGHUP)
+ if (hostsig == SIGHUP)
+ return TARGET_SIGNAL_HUP;
+#endif
+#if defined (SIGINT)
+ if (hostsig == SIGINT)
+ return TARGET_SIGNAL_INT;
+#endif
+#if defined (SIGQUIT)
+ if (hostsig == SIGQUIT)
+ return TARGET_SIGNAL_QUIT;
+#endif
+#if defined (SIGILL)
+ if (hostsig == SIGILL)
+ return TARGET_SIGNAL_ILL;
+#endif
+#if defined (SIGTRAP)
+ if (hostsig == SIGTRAP)
+ return TARGET_SIGNAL_TRAP;
+#endif
+#if defined (SIGABRT)
+ if (hostsig == SIGABRT)
+ return TARGET_SIGNAL_ABRT;
+#endif
+#if defined (SIGEMT)
+ if (hostsig == SIGEMT)
+ return TARGET_SIGNAL_EMT;
+#endif
+#if defined (SIGFPE)
+ if (hostsig == SIGFPE)
+ return TARGET_SIGNAL_FPE;
+#endif
+#if defined (SIGKILL)
+ if (hostsig == SIGKILL)
+ return TARGET_SIGNAL_KILL;
+#endif
+#if defined (SIGBUS)
+ if (hostsig == SIGBUS)
+ return TARGET_SIGNAL_BUS;
+#endif
+#if defined (SIGSEGV)
+ if (hostsig == SIGSEGV)
+ return TARGET_SIGNAL_SEGV;
+#endif
+#if defined (SIGSYS)
+ if (hostsig == SIGSYS)
+ return TARGET_SIGNAL_SYS;
+#endif
+#if defined (SIGPIPE)
+ if (hostsig == SIGPIPE)
+ return TARGET_SIGNAL_PIPE;
+#endif
+#if defined (SIGALRM)
+ if (hostsig == SIGALRM)
+ return TARGET_SIGNAL_ALRM;
+#endif
+#if defined (SIGTERM)
+ if (hostsig == SIGTERM)
+ return TARGET_SIGNAL_TERM;
+#endif
+#if defined (SIGUSR1)
+ if (hostsig == SIGUSR1)
+ return TARGET_SIGNAL_USR1;
+#endif
+#if defined (SIGUSR2)
+ if (hostsig == SIGUSR2)
+ return TARGET_SIGNAL_USR2;
+#endif
+#if defined (SIGCLD)
+ if (hostsig == SIGCLD)
+ return TARGET_SIGNAL_CHLD;
+#endif
+#if defined (SIGCHLD)
+ if (hostsig == SIGCHLD)
+ return TARGET_SIGNAL_CHLD;
+#endif
+#if defined (SIGPWR)
+ if (hostsig == SIGPWR)
+ return TARGET_SIGNAL_PWR;
+#endif
+#if defined (SIGWINCH)
+ if (hostsig == SIGWINCH)
+ return TARGET_SIGNAL_WINCH;
+#endif
+#if defined (SIGURG)
+ if (hostsig == SIGURG)
+ return TARGET_SIGNAL_URG;
+#endif
+#if defined (SIGIO)
+ if (hostsig == SIGIO)
+ return TARGET_SIGNAL_IO;
+#endif
+#if defined (SIGPOLL)
+ if (hostsig == SIGPOLL)
+ return TARGET_SIGNAL_POLL;
+#endif
+#if defined (SIGSTOP)
+ if (hostsig == SIGSTOP)
+ return TARGET_SIGNAL_STOP;
+#endif
+#if defined (SIGTSTP)
+ if (hostsig == SIGTSTP)
+ return TARGET_SIGNAL_TSTP;
+#endif
+#if defined (SIGCONT)
+ if (hostsig == SIGCONT)
+ return TARGET_SIGNAL_CONT;
+#endif
+#if defined (SIGTTIN)
+ if (hostsig == SIGTTIN)
+ return TARGET_SIGNAL_TTIN;
+#endif
+#if defined (SIGTTOU)
+ if (hostsig == SIGTTOU)
+ return TARGET_SIGNAL_TTOU;
+#endif
+#if defined (SIGVTALRM)
+ if (hostsig == SIGVTALRM)
+ return TARGET_SIGNAL_VTALRM;
+#endif
+#if defined (SIGPROF)
+ if (hostsig == SIGPROF)
+ return TARGET_SIGNAL_PROF;
+#endif
+#if defined (SIGXCPU)
+ if (hostsig == SIGXCPU)
+ return TARGET_SIGNAL_XCPU;
+#endif
+#if defined (SIGXFSZ)
+ if (hostsig == SIGXFSZ)
+ return TARGET_SIGNAL_XFSZ;
+#endif
+#if defined (SIGWIND)
+ if (hostsig == SIGWIND)
+ return TARGET_SIGNAL_WIND;
+#endif
+#if defined (SIGPHONE)
+ if (hostsig == SIGPHONE)
+ return TARGET_SIGNAL_PHONE;
+#endif
+#if defined (SIGLOST)
+ if (hostsig == SIGLOST)
+ return TARGET_SIGNAL_LOST;
+#endif
+#if defined (SIGWAITING)
+ if (hostsig == SIGWAITING)
+ return TARGET_SIGNAL_WAITING;
+#endif
+#if defined (SIGCANCEL)
+ if (hostsig == SIGCANCEL)
+ return TARGET_SIGNAL_CANCEL;
+#endif
+#if defined (SIGLWP)
+ if (hostsig == SIGLWP)
+ return TARGET_SIGNAL_LWP;
+#endif
+#if defined (SIGDANGER)
+ if (hostsig == SIGDANGER)
+ return TARGET_SIGNAL_DANGER;
+#endif
+#if defined (SIGGRANT)
+ if (hostsig == SIGGRANT)
+ return TARGET_SIGNAL_GRANT;
+#endif
+#if defined (SIGRETRACT)
+ if (hostsig == SIGRETRACT)
+ return TARGET_SIGNAL_RETRACT;
+#endif
+#if defined (SIGMSG)
+ if (hostsig == SIGMSG)
+ return TARGET_SIGNAL_MSG;
+#endif
+#if defined (SIGSOUND)
+ if (hostsig == SIGSOUND)
+ return TARGET_SIGNAL_SOUND;
+#endif
+#if defined (SIGSAK)
+ if (hostsig == SIGSAK)
+ return TARGET_SIGNAL_SAK;
+#endif
+#if defined (SIGPRIO)
+ if (hostsig == SIGPRIO)
+ return TARGET_SIGNAL_PRIO;
+#endif
+
+ /* Mach exceptions. Assumes that the values for EXC_ are positive! */
+#if defined (EXC_BAD_ACCESS) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_BAD_ACCESS)
+ return TARGET_EXC_BAD_ACCESS;
+#endif
+#if defined (EXC_BAD_INSTRUCTION) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_BAD_INSTRUCTION)
+ return TARGET_EXC_BAD_INSTRUCTION;
+#endif
+#if defined (EXC_ARITHMETIC) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_ARITHMETIC)
+ return TARGET_EXC_ARITHMETIC;
+#endif
+#if defined (EXC_EMULATION) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_EMULATION)
+ return TARGET_EXC_EMULATION;
+#endif
+#if defined (EXC_SOFTWARE) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_SOFTWARE)
+ return TARGET_EXC_SOFTWARE;
+#endif
+#if defined (EXC_BREAKPOINT) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_BREAKPOINT)
+ return TARGET_EXC_BREAKPOINT;
+#endif
+
+#if defined (SIGINFO)
+ if (hostsig == SIGINFO)
+ return TARGET_SIGNAL_INFO;
+#endif
+
+#if defined (REALTIME_LO)
+ if (hostsig >= REALTIME_LO && hostsig < REALTIME_HI)
+ {
+ /* This block of TARGET_SIGNAL_REALTIME value is in order. */
+ if (33 <= hostsig && hostsig <= 63)
+ return (enum target_signal)
+ (hostsig - 33 + (int) TARGET_SIGNAL_REALTIME_33);
+ else if (hostsig == 32)
+ return TARGET_SIGNAL_REALTIME_32;
+ else if (64 <= hostsig && hostsig <= 127)
+ return (enum target_signal)
+ (hostsig - 64 + (int) TARGET_SIGNAL_REALTIME_64);
+ else
+ error ("GDB bug: target.c (target_signal_from_host): unrecognized real-time signal");
+ }
+#endif
+
+#if defined (SIGRTMIN)
+ if (hostsig >= SIGRTMIN && hostsig <= SIGRTMAX)
+ {
+ /* This block of TARGET_SIGNAL_REALTIME value is in order. */
+ if (33 <= hostsig && hostsig <= 63)
+ return (enum target_signal)
+ (hostsig - 33 + (int) TARGET_SIGNAL_REALTIME_33);
+ else if (hostsig == 64)
+ return TARGET_SIGNAL_REALTIME_64;
+ else
+ error ("GDB bug: target.c (target_signal_from_host): unrecognized real-time signal");
+ }
+#endif
+ return TARGET_SIGNAL_UNKNOWN;
+}
+
+/* Convert a OURSIG (an enum target_signal) to the form used by the
+ target operating system (refered to as the ``host'') or zero if the
+ equivalent host signal is not available. Set/clear OURSIG_OK
+ accordingly. */
+
+static int
+do_target_signal_to_host (enum target_signal oursig,
+ int *oursig_ok)
+{
+ *oursig_ok = 1;
+ switch (oursig)
+ {
+ case TARGET_SIGNAL_0:
+ return 0;
+
+#if defined (SIGHUP)
+ case TARGET_SIGNAL_HUP:
+ return SIGHUP;
+#endif
+#if defined (SIGINT)
+ case TARGET_SIGNAL_INT:
+ return SIGINT;
+#endif
+#if defined (SIGQUIT)
+ case TARGET_SIGNAL_QUIT:
+ return SIGQUIT;
+#endif
+#if defined (SIGILL)
+ case TARGET_SIGNAL_ILL:
+ return SIGILL;
+#endif
+#if defined (SIGTRAP)
+ case TARGET_SIGNAL_TRAP:
+ return SIGTRAP;
+#endif
+#if defined (SIGABRT)
+ case TARGET_SIGNAL_ABRT:
+ return SIGABRT;
+#endif
+#if defined (SIGEMT)
+ case TARGET_SIGNAL_EMT:
+ return SIGEMT;
+#endif
+#if defined (SIGFPE)
+ case TARGET_SIGNAL_FPE:
+ return SIGFPE;
+#endif
+#if defined (SIGKILL)
+ case TARGET_SIGNAL_KILL:
+ return SIGKILL;
+#endif
+#if defined (SIGBUS)
+ case TARGET_SIGNAL_BUS:
+ return SIGBUS;
+#endif
+#if defined (SIGSEGV)
+ case TARGET_SIGNAL_SEGV:
+ return SIGSEGV;
+#endif
+#if defined (SIGSYS)
+ case TARGET_SIGNAL_SYS:
+ return SIGSYS;
+#endif
+#if defined (SIGPIPE)
+ case TARGET_SIGNAL_PIPE:
+ return SIGPIPE;
+#endif
+#if defined (SIGALRM)
+ case TARGET_SIGNAL_ALRM:
+ return SIGALRM;
+#endif
+#if defined (SIGTERM)
+ case TARGET_SIGNAL_TERM:
+ return SIGTERM;
+#endif
+#if defined (SIGUSR1)
+ case TARGET_SIGNAL_USR1:
+ return SIGUSR1;
+#endif
+#if defined (SIGUSR2)
+ case TARGET_SIGNAL_USR2:
+ return SIGUSR2;
+#endif
+#if defined (SIGCHLD) || defined (SIGCLD)
+ case TARGET_SIGNAL_CHLD:
+#if defined (SIGCHLD)
+ return SIGCHLD;
+#else
+ return SIGCLD;
+#endif
+#endif /* SIGCLD or SIGCHLD */
+#if defined (SIGPWR)
+ case TARGET_SIGNAL_PWR:
+ return SIGPWR;
+#endif
+#if defined (SIGWINCH)
+ case TARGET_SIGNAL_WINCH:
+ return SIGWINCH;
+#endif
+#if defined (SIGURG)
+ case TARGET_SIGNAL_URG:
+ return SIGURG;
+#endif
+#if defined (SIGIO)
+ case TARGET_SIGNAL_IO:
+ return SIGIO;
+#endif
+#if defined (SIGPOLL)
+ case TARGET_SIGNAL_POLL:
+ return SIGPOLL;
+#endif
+#if defined (SIGSTOP)
+ case TARGET_SIGNAL_STOP:
+ return SIGSTOP;
+#endif
+#if defined (SIGTSTP)
+ case TARGET_SIGNAL_TSTP:
+ return SIGTSTP;
+#endif
+#if defined (SIGCONT)
+ case TARGET_SIGNAL_CONT:
+ return SIGCONT;
+#endif
+#if defined (SIGTTIN)
+ case TARGET_SIGNAL_TTIN:
+ return SIGTTIN;
+#endif
+#if defined (SIGTTOU)
+ case TARGET_SIGNAL_TTOU:
+ return SIGTTOU;
+#endif
+#if defined (SIGVTALRM)
+ case TARGET_SIGNAL_VTALRM:
+ return SIGVTALRM;
+#endif
+#if defined (SIGPROF)
+ case TARGET_SIGNAL_PROF:
+ return SIGPROF;
+#endif
+#if defined (SIGXCPU)
+ case TARGET_SIGNAL_XCPU:
+ return SIGXCPU;
+#endif
+#if defined (SIGXFSZ)
+ case TARGET_SIGNAL_XFSZ:
+ return SIGXFSZ;
+#endif
+#if defined (SIGWIND)
+ case TARGET_SIGNAL_WIND:
+ return SIGWIND;
+#endif
+#if defined (SIGPHONE)
+ case TARGET_SIGNAL_PHONE:
+ return SIGPHONE;
+#endif
+#if defined (SIGLOST)
+ case TARGET_SIGNAL_LOST:
+ return SIGLOST;
+#endif
+#if defined (SIGWAITING)
+ case TARGET_SIGNAL_WAITING:
+ return SIGWAITING;
+#endif
+#if defined (SIGCANCEL)
+ case TARGET_SIGNAL_CANCEL:
+ return SIGCANCEL;
+#endif
+#if defined (SIGLWP)
+ case TARGET_SIGNAL_LWP:
+ return SIGLWP;
+#endif
+#if defined (SIGDANGER)
+ case TARGET_SIGNAL_DANGER:
+ return SIGDANGER;
+#endif
+#if defined (SIGGRANT)
+ case TARGET_SIGNAL_GRANT:
+ return SIGGRANT;
+#endif
+#if defined (SIGRETRACT)
+ case TARGET_SIGNAL_RETRACT:
+ return SIGRETRACT;
+#endif
+#if defined (SIGMSG)
+ case TARGET_SIGNAL_MSG:
+ return SIGMSG;
+#endif
+#if defined (SIGSOUND)
+ case TARGET_SIGNAL_SOUND:
+ return SIGSOUND;
+#endif
+#if defined (SIGSAK)
+ case TARGET_SIGNAL_SAK:
+ return SIGSAK;
+#endif
+#if defined (SIGPRIO)
+ case TARGET_SIGNAL_PRIO:
+ return SIGPRIO;
+#endif
+
+ /* Mach exceptions. Assumes that the values for EXC_ are positive! */
+#if defined (EXC_BAD_ACCESS) && defined (_NSIG)
+ case TARGET_EXC_BAD_ACCESS:
+ return _NSIG + EXC_BAD_ACCESS;
+#endif
+#if defined (EXC_BAD_INSTRUCTION) && defined (_NSIG)
+ case TARGET_EXC_BAD_INSTRUCTION:
+ return _NSIG + EXC_BAD_INSTRUCTION;
+#endif
+#if defined (EXC_ARITHMETIC) && defined (_NSIG)
+ case TARGET_EXC_ARITHMETIC:
+ return _NSIG + EXC_ARITHMETIC;
+#endif
+#if defined (EXC_EMULATION) && defined (_NSIG)
+ case TARGET_EXC_EMULATION:
+ return _NSIG + EXC_EMULATION;
+#endif
+#if defined (EXC_SOFTWARE) && defined (_NSIG)
+ case TARGET_EXC_SOFTWARE:
+ return _NSIG + EXC_SOFTWARE;
+#endif
+#if defined (EXC_BREAKPOINT) && defined (_NSIG)
+ case TARGET_EXC_BREAKPOINT:
+ return _NSIG + EXC_BREAKPOINT;
+#endif
+
+#if defined (SIGINFO)
+ case TARGET_SIGNAL_INFO:
+ return SIGINFO;
+#endif
+
+ default:
+#if defined (REALTIME_LO)
+ if (oursig >= TARGET_SIGNAL_REALTIME_33
+ && oursig <= TARGET_SIGNAL_REALTIME_63)
+ {
+ /* This block of signals is continuous, and
+ TARGET_SIGNAL_REALTIME_33 is 33 by definition. */
+ int retsig =
+ (int) oursig - (int) TARGET_SIGNAL_REALTIME_33 + 33;
+ if (retsig >= REALTIME_LO && retsig < REALTIME_HI)
+ return retsig;
+ }
+#if (REALTIME_LO < 33)
+ else if (oursig == TARGET_SIGNAL_REALTIME_32)
+ {
+ /* TARGET_SIGNAL_REALTIME_32 isn't contiguous with
+ TARGET_SIGNAL_REALTIME_33. It is 32 by definition. */
+ return 32;
+ }
+#endif
+#if (REALTIME_HI > 64)
+ if (oursig >= TARGET_SIGNAL_REALTIME_64
+ && oursig <= TARGET_SIGNAL_REALTIME_127)
+ {
+ /* This block of signals is continuous, and
+ TARGET_SIGNAL_REALTIME_64 is 64 by definition. */
+ int retsig =
+ (int) oursig - (int) TARGET_SIGNAL_REALTIME_64 + 64;
+ if (retsig >= REALTIME_LO && retsig < REALTIME_HI)
+ return retsig;
+ }
+
+#endif
+#endif
+
+#if defined (SIGRTMIN)
+ if (oursig >= TARGET_SIGNAL_REALTIME_33
+ && oursig <= TARGET_SIGNAL_REALTIME_63)
+ {
+ /* This block of signals is continuous, and
+ TARGET_SIGNAL_REALTIME_33 is 33 by definition. */
+ int retsig =
+ (int) oursig - (int) TARGET_SIGNAL_REALTIME_33 + 33;
+ if (retsig >= SIGRTMIN && retsig <= SIGRTMAX)
+ return retsig;
+ }
+ else if (oursig == TARGET_SIGNAL_REALTIME_64)
+ return 64;
+#endif
+ *oursig_ok = 0;
+ return 0;
+ }
+}
+
+int
+target_signal_to_host_p (enum target_signal oursig)
+{
+ int oursig_ok;
+ do_target_signal_to_host (oursig, &oursig_ok);
+ return oursig_ok;
+}
+
+int
+target_signal_to_host (enum target_signal oursig)
+{
+ int oursig_ok;
+ int targ_signo = do_target_signal_to_host (oursig, &oursig_ok);
+ if (!oursig_ok)
+ {
+ /* The user might be trying to do "signal SIGSAK" where this system
+ doesn't have SIGSAK. */
+ warning ("Signal %s does not exist on this system.\n",
+ target_signal_to_name (oursig));
+ return 0;
+ }
+ else
+ return targ_signo;
+}
+
+/* In some circumstances we allow a command to specify a numeric
+ signal. The idea is to keep these circumstances limited so that
+ users (and scripts) develop portable habits. For comparison,
+ POSIX.2 `kill' requires that 1,2,3,6,9,14, and 15 work (and using a
+ numeric signal at all is obsolescent. We are slightly more
+ lenient and allow 1-15 which should match host signal numbers on
+ most systems. Use of symbolic signal names is strongly encouraged. */
+
+enum target_signal
+target_signal_from_command (int num)
+{
+ if (num >= 1 && num <= 15)
+ return (enum target_signal) num;
+ error ("Only signals 1-15 are valid as numeric signals.\n\
+Use \"info signals\" for a list of symbolic signals.");
+}
+
+#ifndef GDBSERVER
+void
+_initialize_signals (void)
+{
+ if (strcmp (signals[TARGET_SIGNAL_LAST].string, "TARGET_SIGNAL_MAGIC") != 0)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+}
+#endif
diff --git a/gdb/sim-regno.h b/gdb/sim-regno.h
new file mode 100644
index 00000000000..5a7057b6b04
--- /dev/null
+++ b/gdb/sim-regno.h
@@ -0,0 +1,45 @@
+/* Generic remote debugging interface for simulators.
+
+ Copyright 2002 Free Software Foundation, Inc.
+
+ Contributed by Red Hat, 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. */
+
+#ifndef SIM_REGNO_H
+#define SIM_REGNO_H
+
+/* The REGISTER_SIM_REGNO(REGNUM) method, when there is a
+ corresponding simulator register, returns that register number as a
+ cardinal. When there is no corresponding register, it returns a
+ negative value. */
+
+enum sim_regno {
+ /* Normal sane architecture. The simulator is known to not model
+ this register. */
+ SIM_REGNO_DOES_NOT_EXIST = -1,
+ /* For possible backward compatibility. The register cache doesn't
+ have a corresponding name. Skip the register entirely. */
+ LEGACY_SIM_REGNO_IGNORE = -2
+};
+
+/* Treat all raw registers as valid. */
+
+extern int one2one_register_sim_regno (int regnum);
+
+#endif
diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c
new file mode 100644
index 00000000000..50caed39d99
--- /dev/null
+++ b/gdb/sol-thread.c
@@ -0,0 +1,1706 @@
+/* Low level interface for debugging Solaris threads for GDB, the GNU debugger.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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. */
+
+/* This module implements a sort of half target that sits between the
+ machine-independent parts of GDB and the /proc interface (procfs.c) to
+ provide access to the Solaris user-mode thread implementation.
+
+ Solaris threads are true user-mode threads, which are invoked via the thr_*
+ and pthread_* (native and Posix respectivly) interfaces. These are mostly
+ implemented in user-space, with all thread context kept in various
+ structures that live in the user's heap. These should not be confused with
+ lightweight processes (LWPs), which are implemented by the kernel, and
+ scheduled without explicit intervention by the process.
+
+ Just to confuse things a little, Solaris threads (both native and Posix) are
+ actually implemented using LWPs. In general, there are going to be more
+ threads than LWPs. There is no fixed correspondence between a thread and an
+ LWP. When a thread wants to run, it gets scheduled onto the first available
+ LWP and can therefore migrate from one LWP to another as time goes on. A
+ sleeping thread may not be associated with an LWP at all!
+
+ To make it possible to mess with threads, Sun provides a library called
+ libthread_db.so.1 (not to be confused with libthread_db.so.0, which doesn't
+ have a published interface). This interface has an upper part, which it
+ provides, and a lower part which I provide. The upper part consists of the
+ td_* routines, which allow me to find all the threads, query their state,
+ etc... The lower part consists of all of the ps_*, which are used by the
+ td_* routines to read/write memory, manipulate LWPs, lookup symbols, etc...
+ The ps_* routines actually do most of their work by calling functions in
+ procfs.c. */
+
+#include "defs.h"
+#include <thread.h>
+#include <proc_service.h>
+#include <thread_db.h>
+#include "gdbthread.h"
+#include "target.h"
+#include "inferior.h"
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <dlfcn.h>
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "symfile.h"
+
+extern struct target_ops sol_thread_ops; /* Forward declaration */
+extern struct target_ops sol_core_ops; /* Forward declaration */
+
+/* place to store core_ops before we overwrite it */
+static struct target_ops orig_core_ops;
+
+struct target_ops sol_thread_ops;
+struct target_ops sol_core_ops;
+
+extern int procfs_suppress_run;
+extern struct target_ops procfs_ops; /* target vector for procfs.c */
+extern struct target_ops core_ops; /* target vector for corelow.c */
+extern char *procfs_pid_to_str (ptid_t ptid);
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* This struct is defined by us, but mainly used for the proc_service interface.
+ We don't have much use for it, except as a handy place to get a real pid
+ for memory accesses. */
+
+struct ps_prochandle
+ {
+ ptid_t ptid;
+ };
+
+struct string_map
+ {
+ int num;
+ char *str;
+ };
+
+static struct ps_prochandle main_ph;
+static td_thragent_t *main_ta;
+static int sol_thread_active = 0;
+
+static char *td_err_string (td_err_e errcode);
+static char *td_state_string (td_thr_state_e statecode);
+static ptid_t thread_to_lwp (ptid_t thread_id, int default_lwp);
+static void sol_thread_resume (ptid_t ptid, int step, enum target_signal signo);
+static ptid_t lwp_to_thread (ptid_t lwp);
+static int sol_thread_alive (ptid_t ptid);
+static void sol_core_close (int quitting);
+
+static void init_sol_thread_ops (void);
+static void init_sol_core_ops (void);
+
+/* Default definitions: These must be defined in tm.h
+ if they are to be shared with a process module such as procfs. */
+
+#define GET_PID(ptid) ptid_get_pid (ptid)
+#define GET_LWP(ptid) ptid_get_lwp (ptid)
+#define GET_THREAD(ptid) ptid_get_tid (ptid)
+
+#define is_lwp(ptid) (GET_LWP (ptid) != 0)
+#define is_thread(ptid) (GET_THREAD (ptid) != 0)
+
+#define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
+#define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid)
+
+/* Pointers to routines from lithread_db resolved by dlopen() */
+
+static void (*p_td_log) (const int on_off);
+static td_err_e (*p_td_ta_new) (const struct ps_prochandle * ph_p,
+ td_thragent_t ** ta_pp);
+static td_err_e (*p_td_ta_delete) (td_thragent_t * ta_p);
+static td_err_e (*p_td_init) (void);
+static td_err_e (*p_td_ta_get_ph) (const td_thragent_t * ta_p,
+ struct ps_prochandle ** ph_pp);
+static td_err_e (*p_td_ta_get_nthreads) (const td_thragent_t * ta_p,
+ int *nthread_p);
+static td_err_e (*p_td_ta_tsd_iter) (const td_thragent_t * ta_p,
+ td_key_iter_f * cb,
+ void *cbdata_p);
+static td_err_e (*p_td_ta_thr_iter) (const td_thragent_t * ta_p,
+ td_thr_iter_f * cb,
+ void *cbdata_p,
+ td_thr_state_e state,
+ int ti_pri,
+ sigset_t * ti_sigmask_p,
+ unsigned ti_user_flags);
+static td_err_e (*p_td_thr_validate) (const td_thrhandle_t * th_p);
+static td_err_e (*p_td_thr_tsd) (const td_thrhandle_t * th_p,
+ const thread_key_t key,
+ void **data_pp);
+static td_err_e (*p_td_thr_get_info) (const td_thrhandle_t * th_p,
+ td_thrinfo_t * ti_p);
+static td_err_e (*p_td_thr_getfpregs) (const td_thrhandle_t * th_p,
+ prfpregset_t * fpregset);
+static td_err_e (*p_td_thr_getxregsize) (const td_thrhandle_t * th_p,
+ int *xregsize);
+static td_err_e (*p_td_thr_getxregs) (const td_thrhandle_t * th_p,
+ const caddr_t xregset);
+static td_err_e (*p_td_thr_sigsetmask) (const td_thrhandle_t * th_p,
+ const sigset_t ti_sigmask);
+static td_err_e (*p_td_thr_setprio) (const td_thrhandle_t * th_p,
+ const int ti_pri);
+static td_err_e (*p_td_thr_setsigpending) (const td_thrhandle_t * th_p,
+ const uchar_t ti_pending_flag,
+ const sigset_t ti_pending);
+static td_err_e (*p_td_thr_setfpregs) (const td_thrhandle_t * th_p,
+ const prfpregset_t * fpregset);
+static td_err_e (*p_td_thr_setxregs) (const td_thrhandle_t * th_p,
+ const caddr_t xregset);
+static td_err_e (*p_td_ta_map_id2thr) (const td_thragent_t * ta_p,
+ thread_t tid,
+ td_thrhandle_t * th_p);
+static td_err_e (*p_td_ta_map_lwp2thr) (const td_thragent_t * ta_p,
+ lwpid_t lwpid,
+ td_thrhandle_t * th_p);
+static td_err_e (*p_td_thr_getgregs) (const td_thrhandle_t * th_p,
+ prgregset_t regset);
+static td_err_e (*p_td_thr_setgregs) (const td_thrhandle_t * th_p,
+ const prgregset_t regset);
+
+/*
+
+ LOCAL FUNCTION
+
+ td_err_string - Convert a thread_db error code to a string
+
+ SYNOPSIS
+
+ char * td_err_string (errcode)
+
+ DESCRIPTION
+
+ Return the thread_db error string associated with errcode. If errcode
+ is unknown, then return a message.
+
+ */
+
+static char *
+td_err_string (td_err_e errcode)
+{
+ static struct string_map
+ td_err_table[] =
+ {
+ {TD_OK, "generic \"call succeeded\""},
+ {TD_ERR, "generic error."},
+ {TD_NOTHR, "no thread can be found to satisfy query"},
+ {TD_NOSV, "no synch. variable can be found to satisfy query"},
+ {TD_NOLWP, "no lwp can be found to satisfy query"},
+ {TD_BADPH, "invalid process handle"},
+ {TD_BADTH, "invalid thread handle"},
+ {TD_BADSH, "invalid synchronization handle"},
+ {TD_BADTA, "invalid thread agent"},
+ {TD_BADKEY, "invalid key"},
+ {TD_NOMSG, "td_thr_event_getmsg() called when there was no message"},
+ {TD_NOFPREGS, "FPU register set not available for given thread"},
+ {TD_NOLIBTHREAD, "application not linked with libthread"},
+ {TD_NOEVENT, "requested event is not supported"},
+ {TD_NOCAPAB, "capability not available"},
+ {TD_DBERR, "Debugger service failed"},
+ {TD_NOAPLIC, "Operation not applicable to"},
+ {TD_NOTSD, "No thread specific data for this thread"},
+ {TD_MALLOC, "Malloc failed"},
+ {TD_PARTIALREG, "Only part of register set was written/read"},
+ {TD_NOXREGS, "X register set not available for given thread"}
+ };
+ const int td_err_size = sizeof td_err_table / sizeof (struct string_map);
+ int i;
+ static char buf[50];
+
+ for (i = 0; i < td_err_size; i++)
+ if (td_err_table[i].num == errcode)
+ return td_err_table[i].str;
+
+ sprintf (buf, "Unknown thread_db error code: %d", errcode);
+
+ return buf;
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ td_state_string - Convert a thread_db state code to a string
+
+ SYNOPSIS
+
+ char * td_state_string (statecode)
+
+ DESCRIPTION
+
+ Return the thread_db state string associated with statecode. If
+ statecode is unknown, then return a message.
+
+ */
+
+static char *
+td_state_string (td_thr_state_e statecode)
+{
+ static struct string_map
+ td_thr_state_table[] =
+ {
+ {TD_THR_ANY_STATE, "any state"},
+ {TD_THR_UNKNOWN, "unknown"},
+ {TD_THR_STOPPED, "stopped"},
+ {TD_THR_RUN, "run"},
+ {TD_THR_ACTIVE, "active"},
+ {TD_THR_ZOMBIE, "zombie"},
+ {TD_THR_SLEEP, "sleep"},
+ {TD_THR_STOPPED_ASLEEP, "stopped asleep"}
+ };
+ const int td_thr_state_table_size = sizeof td_thr_state_table / sizeof (struct string_map);
+ int i;
+ static char buf[50];
+
+ for (i = 0; i < td_thr_state_table_size; i++)
+ if (td_thr_state_table[i].num == statecode)
+ return td_thr_state_table[i].str;
+
+ sprintf (buf, "Unknown thread_db state code: %d", statecode);
+
+ return buf;
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ thread_to_lwp - Convert a Posix or Solaris thread id to a LWP id.
+
+ SYNOPSIS
+
+ tpid_t thread_to_lwp (thread_id, default_lwp)
+
+ DESCRIPTION
+
+ This function converts a Posix or Solaris thread id to a lightweight
+ process id. If thread_id is non-existent, that's an error. If it's
+ an inactive thread, then we return default_lwp.
+
+ NOTES
+
+ This function probably shouldn't call error()...
+
+ */
+
+static ptid_t
+thread_to_lwp (ptid_t thread_id, int default_lwp)
+{
+ td_thrinfo_t ti;
+ td_thrhandle_t th;
+ td_err_e val;
+
+ if (is_lwp (thread_id))
+ return thread_id; /* It's already an LWP id */
+
+ /* It's a thread. Convert to lwp */
+
+ val = p_td_ta_map_id2thr (main_ta, GET_THREAD (thread_id), &th);
+ if (val == TD_NOTHR)
+ return pid_to_ptid (-1); /* thread must have terminated */
+ else if (val != TD_OK)
+ error ("thread_to_lwp: td_ta_map_id2thr %s", td_err_string (val));
+
+ val = p_td_thr_get_info (&th, &ti);
+ if (val == TD_NOTHR)
+ return pid_to_ptid (-1); /* thread must have terminated */
+ else if (val != TD_OK)
+ error ("thread_to_lwp: td_thr_get_info: %s", td_err_string (val));
+
+ if (ti.ti_state != TD_THR_ACTIVE)
+ {
+ if (default_lwp != -1)
+ return pid_to_ptid (default_lwp);
+ error ("thread_to_lwp: thread state not active: %s",
+ td_state_string (ti.ti_state));
+ }
+
+ return BUILD_LWP (ti.ti_lid, PIDGET (thread_id));
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ lwp_to_thread - Convert a LWP id to a Posix or Solaris thread id.
+
+ SYNOPSIS
+
+ int lwp_to_thread (lwp_id)
+
+ DESCRIPTION
+
+ This function converts a lightweight process id to a Posix or Solaris
+ thread id. If thread_id is non-existent, that's an error.
+
+ NOTES
+
+ This function probably shouldn't call error()...
+
+ */
+
+static ptid_t
+lwp_to_thread (ptid_t lwp)
+{
+ td_thrinfo_t ti;
+ td_thrhandle_t th;
+ td_err_e val;
+
+ if (is_thread (lwp))
+ return lwp; /* It's already a thread id */
+
+ /* It's an lwp. Convert it to a thread id. */
+
+ if (!sol_thread_alive (lwp))
+ return pid_to_ptid (-1); /* defunct lwp */
+
+ val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th);
+ if (val == TD_NOTHR)
+ return pid_to_ptid (-1); /* thread must have terminated */
+ else if (val != TD_OK)
+ error ("lwp_to_thread: td_ta_map_lwp2thr: %s.", td_err_string (val));
+
+ val = p_td_thr_validate (&th);
+ if (val == TD_NOTHR)
+ return lwp; /* libthread doesn't know about it;
+ just return lwp */
+ else if (val != TD_OK)
+ error ("lwp_to_thread: td_thr_validate: %s.", td_err_string (val));
+
+ val = p_td_thr_get_info (&th, &ti);
+ if (val == TD_NOTHR)
+ return pid_to_ptid (-1); /* thread must have terminated */
+ else if (val != TD_OK)
+ error ("lwp_to_thread: td_thr_get_info: %s.", td_err_string (val));
+
+ return BUILD_THREAD (ti.ti_tid, PIDGET (lwp));
+}
+
+
+/* Most target vector functions from here on actually just pass through to
+ procfs.c, as they don't need to do anything specific for threads. */
+
+
+/* ARGSUSED */
+static void
+sol_thread_open (char *arg, int from_tty)
+{
+ procfs_ops.to_open (arg, from_tty);
+}
+
+/* Attach to process PID, then initialize for debugging it
+ and wait for the trace-trap that results from attaching. */
+
+static void
+sol_thread_attach (char *args, int from_tty)
+{
+ procfs_ops.to_attach (args, from_tty);
+
+ /* Must get symbols from solibs before libthread_db can run! */
+ SOLIB_ADD ((char *) 0, from_tty, (struct target_ops *) 0, auto_solib_add);
+
+ if (sol_thread_active)
+ {
+ printf_filtered ("sol-thread active.\n");
+ main_ph.ptid = inferior_ptid; /* Save for xfer_memory */
+ push_target (&sol_thread_ops);
+ inferior_ptid = lwp_to_thread (inferior_ptid);
+ if (PIDGET (inferior_ptid) == -1)
+ inferior_ptid = main_ph.ptid;
+ else
+ add_thread (inferior_ptid);
+ }
+ /* XXX - might want to iterate over all the threads and register them. */
+}
+
+/* Take a program previously attached to and detaches it.
+ The program resumes execution and will no longer stop
+ on signals, etc. We'd better not have left any breakpoints
+ in the program or it'll die when it hits one. For this
+ to work, it may be necessary for the process to have been
+ previously attached. It *might* work if the program was
+ started via the normal ptrace (PTRACE_TRACEME). */
+
+static void
+sol_thread_detach (char *args, int from_tty)
+{
+ inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
+ unpush_target (&sol_thread_ops);
+ procfs_ops.to_detach (args, from_tty);
+}
+
+/* Resume execution of process PID. If STEP is nozero, then
+ just single step it. If SIGNAL is nonzero, restart it with that
+ signal activated. We may have to convert pid from a thread-id to an LWP id
+ for procfs. */
+
+static void
+sol_thread_resume (ptid_t ptid, int step, enum target_signal signo)
+{
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_ptid ();
+
+ inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
+ if (PIDGET (inferior_ptid) == -1)
+ inferior_ptid = procfs_first_available ();
+
+ if (PIDGET (ptid) != -1)
+ {
+ ptid_t save_ptid = ptid;
+
+ ptid = thread_to_lwp (ptid, -2);
+ if (PIDGET (ptid) == -2) /* Inactive thread */
+ error ("This version of Solaris can't start inactive threads.");
+ if (info_verbose && PIDGET (ptid) == -1)
+ warning ("Specified thread %ld seems to have terminated",
+ GET_THREAD (save_ptid));
+ }
+
+ procfs_ops.to_resume (ptid, step, signo);
+
+ do_cleanups (old_chain);
+}
+
+/* Wait for any threads to stop. We may have to convert PID from a thread id
+ to a LWP id, and vice versa on the way out. */
+
+static ptid_t
+sol_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+{
+ ptid_t rtnval;
+ ptid_t save_ptid;
+ struct cleanup *old_chain;
+
+ save_ptid = inferior_ptid;
+ old_chain = save_inferior_ptid ();
+
+ inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
+ if (PIDGET (inferior_ptid) == -1)
+ inferior_ptid = procfs_first_available ();
+
+ if (PIDGET (ptid) != -1)
+ {
+ ptid_t save_ptid = ptid;
+
+ ptid = thread_to_lwp (ptid, -2);
+ if (PIDGET (ptid) == -2) /* Inactive thread */
+ error ("This version of Solaris can't start inactive threads.");
+ if (info_verbose && PIDGET (ptid) == -1)
+ warning ("Specified thread %ld seems to have terminated",
+ GET_THREAD (save_ptid));
+ }
+
+ rtnval = procfs_ops.to_wait (ptid, ourstatus);
+
+ if (ourstatus->kind != TARGET_WAITKIND_EXITED)
+ {
+ /* Map the LWP of interest back to the appropriate thread ID */
+ rtnval = lwp_to_thread (rtnval);
+ if (PIDGET (rtnval) == -1)
+ rtnval = save_ptid;
+
+ /* See if we have a new thread */
+ if (is_thread (rtnval)
+ && !ptid_equal (rtnval, save_ptid)
+ && !in_thread_list (rtnval))
+ {
+ printf_filtered ("[New %s]\n", target_pid_to_str (rtnval));
+ add_thread (rtnval);
+ }
+ }
+
+ /* During process initialization, we may get here without the thread package
+ being initialized, since that can only happen after we've found the shared
+ libs. */
+
+ do_cleanups (old_chain);
+
+ return rtnval;
+}
+
+static void
+sol_thread_fetch_registers (int regno)
+{
+ thread_t thread;
+ td_thrhandle_t thandle;
+ td_err_e val;
+ prgregset_t gregset;
+ prfpregset_t fpregset;
+#if 0
+ int xregsize;
+ caddr_t xregset;
+#endif
+
+ if (!is_thread (inferior_ptid))
+ { /* LWP: pass the request on to procfs.c */
+ if (target_has_execution)
+ procfs_ops.to_fetch_registers (regno);
+ else
+ orig_core_ops.to_fetch_registers (regno);
+ return;
+ }
+
+ /* Solaris thread: convert inferior_ptid into a td_thrhandle_t */
+
+ thread = GET_THREAD (inferior_ptid);
+
+ if (thread == 0)
+ error ("sol_thread_fetch_registers: thread == 0");
+
+ val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
+ if (val != TD_OK)
+ error ("sol_thread_fetch_registers: td_ta_map_id2thr: %s",
+ td_err_string (val));
+
+ /* Get the integer regs */
+
+ val = p_td_thr_getgregs (&thandle, gregset);
+ if (val != TD_OK
+ && val != TD_PARTIALREG)
+ error ("sol_thread_fetch_registers: td_thr_getgregs %s",
+ td_err_string (val));
+
+ /* For the sparc, TD_PARTIALREG means that only i0->i7, l0->l7, pc and sp
+ are saved (by a thread context switch). */
+
+ /* And, now the fp regs */
+
+ val = p_td_thr_getfpregs (&thandle, &fpregset);
+ if (val != TD_OK
+ && val != TD_NOFPREGS)
+ error ("sol_thread_fetch_registers: td_thr_getfpregs %s",
+ td_err_string (val));
+
+/* Note that we must call supply_{g fp}regset *after* calling the td routines
+ because the td routines call ps_lget* which affect the values stored in the
+ registers array. */
+
+ supply_gregset ((gdb_gregset_t *) &gregset);
+ supply_fpregset ((gdb_fpregset_t *) &fpregset);
+
+#if 0
+/* thread_db doesn't seem to handle this right */
+ val = td_thr_getxregsize (&thandle, &xregsize);
+ if (val != TD_OK && val != TD_NOXREGS)
+ error ("sol_thread_fetch_registers: td_thr_getxregsize %s",
+ td_err_string (val));
+
+ if (val == TD_OK)
+ {
+ xregset = alloca (xregsize);
+ val = td_thr_getxregs (&thandle, xregset);
+ if (val != TD_OK)
+ error ("sol_thread_fetch_registers: td_thr_getxregs %s",
+ td_err_string (val));
+ }
+#endif
+}
+
+static void
+sol_thread_store_registers (int regno)
+{
+ thread_t thread;
+ td_thrhandle_t thandle;
+ td_err_e val;
+ prgregset_t gregset;
+ prfpregset_t fpregset;
+#if 0
+ int xregsize;
+ caddr_t xregset;
+#endif
+
+ if (!is_thread (inferior_ptid))
+ { /* LWP: pass the request on to procfs.c */
+ procfs_ops.to_store_registers (regno);
+ return;
+ }
+
+ /* Solaris thread: convert inferior_ptid into a td_thrhandle_t */
+
+ thread = GET_THREAD (inferior_ptid);
+
+ val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
+ if (val != TD_OK)
+ error ("sol_thread_store_registers: td_ta_map_id2thr %s",
+ td_err_string (val));
+
+ if (regno != -1)
+ { /* Not writing all the regs */
+ /* save new register value */
+ char* old_value = (char*) alloca (REGISTER_SIZE);
+ memcpy (old_value, &registers[REGISTER_BYTE (regno)], REGISTER_SIZE);
+
+ val = p_td_thr_getgregs (&thandle, gregset);
+ if (val != TD_OK)
+ error ("sol_thread_store_registers: td_thr_getgregs %s",
+ td_err_string (val));
+ val = p_td_thr_getfpregs (&thandle, &fpregset);
+ if (val != TD_OK)
+ error ("sol_thread_store_registers: td_thr_getfpregs %s",
+ td_err_string (val));
+
+ /* restore new register value */
+ memcpy (&registers[REGISTER_BYTE (regno)], old_value, REGISTER_SIZE);
+
+#if 0
+/* thread_db doesn't seem to handle this right */
+ val = td_thr_getxregsize (&thandle, &xregsize);
+ if (val != TD_OK && val != TD_NOXREGS)
+ error ("sol_thread_store_registers: td_thr_getxregsize %s",
+ td_err_string (val));
+
+ if (val == TD_OK)
+ {
+ xregset = alloca (xregsize);
+ val = td_thr_getxregs (&thandle, xregset);
+ if (val != TD_OK)
+ error ("sol_thread_store_registers: td_thr_getxregs %s",
+ td_err_string (val));
+ }
+#endif
+ }
+
+ fill_gregset ((gdb_gregset_t *) &gregset, regno);
+ fill_fpregset ((gdb_fpregset_t *) &fpregset, regno);
+
+ val = p_td_thr_setgregs (&thandle, gregset);
+ if (val != TD_OK)
+ error ("sol_thread_store_registers: td_thr_setgregs %s",
+ td_err_string (val));
+ val = p_td_thr_setfpregs (&thandle, &fpregset);
+ if (val != TD_OK)
+ error ("sol_thread_store_registers: td_thr_setfpregs %s",
+ td_err_string (val));
+
+#if 0
+/* thread_db doesn't seem to handle this right */
+ val = td_thr_getxregsize (&thandle, &xregsize);
+ if (val != TD_OK && val != TD_NOXREGS)
+ error ("sol_thread_store_registers: td_thr_getxregsize %s",
+ td_err_string (val));
+
+ /* Should probably do something about writing the xregs here, but what are
+ they? */
+#endif
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+static void
+sol_thread_prepare_to_store (void)
+{
+ procfs_ops.to_prepare_to_store ();
+}
+
+/* Transfer LEN bytes between GDB address MYADDR and target address
+ MEMADDR. If DOWRITE is non-zero, transfer them to the target,
+ otherwise transfer them from the target. TARGET is unused.
+
+ Returns the number of bytes transferred. */
+
+static int
+sol_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
+ struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ int retval;
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_ptid ();
+
+ if (is_thread (inferior_ptid) || /* A thread */
+ !target_thread_alive (inferior_ptid)) /* An lwp, but not alive */
+ inferior_ptid = procfs_first_available (); /* Find any live lwp. */
+ /* Note: don't need to call switch_to_thread; we're just reading memory. */
+
+ if (target_has_execution)
+ retval = procfs_ops.to_xfer_memory (memaddr, myaddr, len,
+ dowrite, attrib, target);
+ else
+ retval = orig_core_ops.to_xfer_memory (memaddr, myaddr, len,
+ dowrite, attrib, target);
+
+ do_cleanups (old_chain);
+
+ return retval;
+}
+
+/* Print status information about what we're accessing. */
+
+static void
+sol_thread_files_info (struct target_ops *ignore)
+{
+ procfs_ops.to_files_info (ignore);
+}
+
+static void
+sol_thread_kill_inferior (void)
+{
+ procfs_ops.to_kill ();
+}
+
+static void
+sol_thread_notice_signals (ptid_t ptid)
+{
+ procfs_ops.to_notice_signals (pid_to_ptid (PIDGET (ptid)));
+}
+
+/* Fork an inferior process, and start debugging it with /proc. */
+
+static void
+sol_thread_create_inferior (char *exec_file, char *allargs, char **env)
+{
+ procfs_ops.to_create_inferior (exec_file, allargs, env);
+
+ if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid))
+ {
+ main_ph.ptid = inferior_ptid; /* Save for xfer_memory */
+
+ push_target (&sol_thread_ops);
+
+ inferior_ptid = lwp_to_thread (inferior_ptid);
+ if (PIDGET (inferior_ptid) == -1)
+ inferior_ptid = main_ph.ptid;
+
+ if (!in_thread_list (inferior_ptid))
+ add_thread (inferior_ptid);
+ }
+}
+
+/* This routine is called whenever a new symbol table is read in, or when all
+ symbol tables are removed. libthread_db can only be initialized when it
+ finds the right variables in libthread.so. Since it's a shared library,
+ those variables don't show up until the library gets mapped and the symbol
+ table is read in. */
+
+/* This new_objfile event is now managed by a chained function pointer.
+ * It is the callee's responsability to call the next client on the chain.
+ */
+
+/* Saved pointer to previous owner of the new_objfile event. */
+static void (*target_new_objfile_chain) (struct objfile *);
+
+void
+sol_thread_new_objfile (struct objfile *objfile)
+{
+ td_err_e val;
+
+ if (!objfile)
+ {
+ sol_thread_active = 0;
+ goto quit;
+ }
+
+ /* don't do anything if init failed to resolve the libthread_db library */
+ if (!procfs_suppress_run)
+ goto quit;
+
+ /* Now, initialize the thread debugging library. This needs to be done after
+ the shared libraries are located because it needs information from the
+ user's thread library. */
+
+ val = p_td_init ();
+ if (val != TD_OK)
+ {
+ warning ("sol_thread_new_objfile: td_init: %s", td_err_string (val));
+ goto quit;
+ }
+
+ val = p_td_ta_new (&main_ph, &main_ta);
+ if (val == TD_NOLIBTHREAD)
+ goto quit;
+ else if (val != TD_OK)
+ {
+ warning ("sol_thread_new_objfile: td_ta_new: %s", td_err_string (val));
+ goto quit;
+ }
+
+ sol_thread_active = 1;
+quit:
+ /* Call predecessor on chain, if any. */
+ if (target_new_objfile_chain)
+ target_new_objfile_chain (objfile);
+}
+
+/* Clean up after the inferior dies. */
+
+static void
+sol_thread_mourn_inferior (void)
+{
+ unpush_target (&sol_thread_ops);
+ procfs_ops.to_mourn_inferior ();
+}
+
+/* Mark our target-struct as eligible for stray "run" and "attach" commands. */
+
+static int
+sol_thread_can_run (void)
+{
+ return procfs_suppress_run;
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ sol_thread_alive - test thread for "aliveness"
+
+ SYNOPSIS
+
+ static bool sol_thread_alive (ptid_t ptid);
+
+ DESCRIPTION
+
+ returns true if thread still active in inferior.
+
+ */
+
+static int
+sol_thread_alive (ptid_t ptid)
+{
+ if (is_thread (ptid)) /* non-kernel thread */
+ {
+ td_err_e val;
+ td_thrhandle_t th;
+ int pid;
+
+ pid = GET_THREAD (ptid);
+ if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
+ return 0; /* thread not found */
+ if ((val = p_td_thr_validate (&th)) != TD_OK)
+ return 0; /* thread not valid */
+ return 1; /* known thread: return true */
+ }
+ else
+ /* kernel thread (LWP): let procfs test it */
+ {
+ if (target_has_execution)
+ return procfs_ops.to_thread_alive (ptid);
+ else
+ return orig_core_ops.to_thread_alive (ptid);
+ }
+}
+
+static void
+sol_thread_stop (void)
+{
+ procfs_ops.to_stop ();
+}
+
+/* These routines implement the lower half of the thread_db interface. Ie: the
+ ps_* routines. */
+
+/* Various versions of <proc_service.h> have slightly
+ different function prototypes. In particular, we have
+
+ NEWER OLDER
+ struct ps_prochandle * const struct ps_prochandle *
+ void* char*
+ const void* char*
+ int size_t
+
+ Which one you have depends on solaris version and what
+ patches you've applied. On the theory that there are
+ only two major variants, we have configure check the
+ prototype of ps_pdwrite (), and use that info to make
+ appropriate typedefs here. */
+
+#ifdef PROC_SERVICE_IS_OLD
+typedef const struct ps_prochandle *gdb_ps_prochandle_t;
+typedef char *gdb_ps_read_buf_t;
+typedef char *gdb_ps_write_buf_t;
+typedef int gdb_ps_size_t;
+typedef paddr_t gdb_ps_addr_t;
+#else
+typedef struct ps_prochandle *gdb_ps_prochandle_t;
+typedef void *gdb_ps_read_buf_t;
+typedef const void *gdb_ps_write_buf_t;
+typedef size_t gdb_ps_size_t;
+typedef psaddr_t gdb_ps_addr_t;
+#endif
+
+
+/* The next four routines are called by thread_db to tell us to stop and stop
+ a particular process or lwp. Since GDB ensures that these are all stopped
+ by the time we call anything in thread_db, these routines need to do
+ nothing. */
+
+/* Process stop */
+
+ps_err_e
+ps_pstop (gdb_ps_prochandle_t ph)
+{
+ return PS_OK;
+}
+
+/* Process continue */
+
+ps_err_e
+ps_pcontinue (gdb_ps_prochandle_t ph)
+{
+ return PS_OK;
+}
+
+/* LWP stop */
+
+ps_err_e
+ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
+{
+ return PS_OK;
+}
+
+/* LWP continue */
+
+ps_err_e
+ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
+{
+ return PS_OK;
+}
+
+/* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
+
+ps_err_e
+ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
+ const char *ld_symbol_name, gdb_ps_addr_t * ld_symbol_addr)
+{
+ struct minimal_symbol *ms;
+
+ ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
+
+ if (!ms)
+ return PS_NOSYM;
+
+ *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
+
+ return PS_OK;
+}
+
+/* Common routine for reading and writing memory. */
+
+static ps_err_e
+rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
+ char *buf, int size)
+{
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_ptid ();
+
+ if (is_thread (inferior_ptid) || /* A thread */
+ !target_thread_alive (inferior_ptid)) /* An lwp, but not alive */
+ inferior_ptid = procfs_first_available (); /* Find any live lwp. */
+ /* Note: don't need to call switch_to_thread; we're just reading memory. */
+
+#if defined (__sparcv9)
+ /* For Sparc64 cross Sparc32, make sure the address has not been
+ accidentally sign-extended (or whatever) to beyond 32 bits. */
+ if (bfd_get_arch_size (exec_bfd) == 32)
+ addr &= 0xffffffff;
+#endif
+
+ while (size > 0)
+ {
+ int cc;
+
+ /* FIXME: passing 0 as attrib argument. */
+ if (target_has_execution)
+ cc = procfs_ops.to_xfer_memory (addr, buf, size,
+ dowrite, 0, &procfs_ops);
+ else
+ cc = orig_core_ops.to_xfer_memory (addr, buf, size,
+ dowrite, 0, &core_ops);
+
+ if (cc < 0)
+ {
+ if (dowrite == 0)
+ print_sys_errmsg ("rw_common (): read", errno);
+ else
+ print_sys_errmsg ("rw_common (): write", errno);
+
+ do_cleanups (old_chain);
+
+ return PS_ERR;
+ }
+ else if (cc == 0)
+ {
+ if (dowrite == 0)
+ warning ("rw_common (): unable to read at addr 0x%lx",
+ (long) addr);
+ else
+ warning ("rw_common (): unable to write at addr 0x%lx",
+ (long) addr);
+
+ do_cleanups (old_chain);
+
+ return PS_ERR;
+ }
+
+ size -= cc;
+ buf += cc;
+ }
+
+ do_cleanups (old_chain);
+
+ return PS_OK;
+}
+
+/* Copies SIZE bytes from target process .data segment to debugger memory. */
+
+ps_err_e
+ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
+ gdb_ps_read_buf_t buf, gdb_ps_size_t size)
+{
+ return rw_common (0, ph, addr, buf, size);
+}
+
+/* Copies SIZE bytes from debugger memory .data segment to target process. */
+
+ps_err_e
+ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
+ gdb_ps_write_buf_t buf, gdb_ps_size_t size)
+{
+ return rw_common (1, ph, addr, (char *) buf, size);
+}
+
+/* Copies SIZE bytes from target process .text segment to debugger memory. */
+
+ps_err_e
+ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
+ gdb_ps_read_buf_t buf, gdb_ps_size_t size)
+{
+ return rw_common (0, ph, addr, buf, size);
+}
+
+/* Copies SIZE bytes from debugger memory .text segment to target process. */
+
+ps_err_e
+ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
+ gdb_ps_write_buf_t buf, gdb_ps_size_t size)
+{
+ return rw_common (1, ph, addr, (char *) buf, size);
+}
+
+/* Get integer regs for LWP */
+
+ps_err_e
+ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+ prgregset_t gregset)
+{
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_ptid ();
+
+ inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
+
+ if (target_has_execution)
+ procfs_ops.to_fetch_registers (-1);
+ else
+ orig_core_ops.to_fetch_registers (-1);
+ fill_gregset ((gdb_gregset_t *) gregset, -1);
+
+ do_cleanups (old_chain);
+
+ return PS_OK;
+}
+
+/* Set integer regs for LWP */
+
+ps_err_e
+ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+ const prgregset_t gregset)
+{
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_ptid ();
+
+ inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
+
+ supply_gregset ((gdb_gregset_t *) gregset);
+ if (target_has_execution)
+ procfs_ops.to_store_registers (-1);
+ else
+ orig_core_ops.to_store_registers (-1);
+
+ do_cleanups (old_chain);
+
+ return PS_OK;
+}
+
+/* Log a message (sends to gdb_stderr). */
+
+void
+ps_plog (const char *fmt,...)
+{
+ va_list args;
+
+ va_start (args, fmt);
+
+ vfprintf_filtered (gdb_stderr, fmt, args);
+}
+
+/* Get size of extra register set. Currently a noop. */
+
+ps_err_e
+ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
+{
+#if 0
+ int lwp_fd;
+ int regsize;
+ ps_err_e val;
+
+ val = get_lwp_fd (ph, lwpid, &lwp_fd);
+ if (val != PS_OK)
+ return val;
+
+ if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
+ {
+ if (errno == EINVAL)
+ return PS_NOFREGS; /* XXX Wrong code, but this is the closest
+ thing in proc_service.h */
+
+ print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
+ return PS_ERR;
+ }
+#endif
+
+ return PS_OK;
+}
+
+/* Get extra register set. Currently a noop. */
+
+ps_err_e
+ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
+{
+#if 0
+ int lwp_fd;
+ ps_err_e val;
+
+ val = get_lwp_fd (ph, lwpid, &lwp_fd);
+ if (val != PS_OK)
+ return val;
+
+ if (ioctl (lwp_fd, PIOCGXREG, xregset))
+ {
+ print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
+ return PS_ERR;
+ }
+#endif
+
+ return PS_OK;
+}
+
+/* Set extra register set. Currently a noop. */
+
+ps_err_e
+ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
+{
+#if 0
+ int lwp_fd;
+ ps_err_e val;
+
+ val = get_lwp_fd (ph, lwpid, &lwp_fd);
+ if (val != PS_OK)
+ return val;
+
+ if (ioctl (lwp_fd, PIOCSXREG, xregset))
+ {
+ print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
+ return PS_ERR;
+ }
+#endif
+
+ return PS_OK;
+}
+
+/* Get floating-point regs for LWP */
+
+ps_err_e
+ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+ prfpregset_t * fpregset)
+{
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_ptid ();
+
+ inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
+
+ if (target_has_execution)
+ procfs_ops.to_fetch_registers (-1);
+ else
+ orig_core_ops.to_fetch_registers (-1);
+ fill_fpregset ((gdb_fpregset_t *) fpregset, -1);
+
+ do_cleanups (old_chain);
+
+ return PS_OK;
+}
+
+/* Set floating-point regs for LWP */
+
+ps_err_e
+ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+ const prfpregset_t * fpregset)
+{
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_ptid ();
+
+ inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
+
+ supply_fpregset ((gdb_fpregset_t *) fpregset);
+ if (target_has_execution)
+ procfs_ops.to_store_registers (-1);
+ else
+ orig_core_ops.to_store_registers (-1);
+
+ do_cleanups (old_chain);
+
+ return PS_OK;
+}
+
+#ifdef PR_MODEL_LP64
+/* Identify process as 32-bit or 64-bit.
+ At the moment I'm using bfd to do this.
+ There might be a more solaris-specific (eg. procfs) method,
+ but this ought to work. */
+
+ps_err_e
+ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
+{
+ if (exec_bfd == 0)
+ *data_model = PR_MODEL_UNKNOWN;
+ else if (bfd_get_arch_size (exec_bfd) == 32)
+ *data_model = PR_MODEL_ILP32;
+ else
+ *data_model = PR_MODEL_LP64;
+
+ return PS_OK;
+}
+#endif /* PR_MODEL_LP64 */
+
+#ifdef TM_I386SOL2_H
+
+/* Reads the local descriptor table of a LWP. */
+
+ps_err_e
+ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
+ struct ssd *pldt)
+{
+ /* NOTE: only used on Solaris, therefore OK to refer to procfs.c */
+ extern struct ssd *procfs_find_LDT_entry (ptid_t);
+ struct ssd *ret;
+
+ /* FIXME: can't I get the process ID from the prochandle or something?
+ */
+
+ if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
+ return PS_BADLID;
+
+ ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
+ if (ret)
+ {
+ memcpy (pldt, ret, sizeof (struct ssd));
+ return PS_OK;
+ }
+ else /* LDT not found. */
+ return PS_ERR;
+}
+#endif /* TM_I386SOL2_H */
+
+/* Convert a pid to printable form. */
+
+char *
+solaris_pid_to_str (ptid_t ptid)
+{
+ static char buf[100];
+
+ /* in case init failed to resolve the libthread_db library */
+ if (!procfs_suppress_run)
+ return procfs_pid_to_str (ptid);
+
+ if (is_thread (ptid))
+ {
+ ptid_t lwp;
+
+ lwp = thread_to_lwp (ptid, -2);
+
+ if (PIDGET (lwp) == -1)
+ sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid));
+ else if (PIDGET (lwp) != -2)
+ sprintf (buf, "Thread %ld (LWP %ld)", GET_THREAD (ptid), GET_LWP (lwp));
+ else
+ sprintf (buf, "Thread %ld ", GET_THREAD (ptid));
+ }
+ else if (GET_LWP (ptid) != 0)
+ sprintf (buf, "LWP %ld ", GET_LWP (ptid));
+ else
+ sprintf (buf, "process %d ", PIDGET (ptid));
+
+ return buf;
+}
+
+
+/* Worker bee for find_new_threads
+ Callback function that gets called once per USER thread (i.e., not
+ kernel) thread. */
+
+static int
+sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
+{
+ td_err_e retval;
+ td_thrinfo_t ti;
+ ptid_t ptid;
+
+ if ((retval = p_td_thr_get_info (th, &ti)) != TD_OK)
+ {
+ return -1;
+ }
+ ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
+ if (!in_thread_list (ptid))
+ add_thread (ptid);
+
+ return 0;
+}
+
+static void
+sol_find_new_threads (void)
+{
+ /* don't do anything if init failed to resolve the libthread_db library */
+ if (!procfs_suppress_run)
+ return;
+
+ if (PIDGET (inferior_ptid) == -1)
+ {
+ printf_filtered ("No process.\n");
+ return;
+ }
+ procfs_ops.to_find_new_threads (); /* first find new kernel threads */
+ p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
+ TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
+ TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
+}
+
+static void
+sol_core_open (char *filename, int from_tty)
+{
+ orig_core_ops.to_open (filename, from_tty);
+}
+
+static void
+sol_core_close (int quitting)
+{
+ orig_core_ops.to_close (quitting);
+}
+
+static void
+sol_core_detach (char *args, int from_tty)
+{
+ unpush_target (&core_ops);
+ orig_core_ops.to_detach (args, from_tty);
+}
+
+static void
+sol_core_files_info (struct target_ops *t)
+{
+ orig_core_ops.to_files_info (t);
+}
+
+/* Worker bee for info sol-thread command. This is a callback function that
+ gets called once for each Solaris thread (ie. not kernel thread) in the
+ inferior. Print anything interesting that we can think of. */
+
+static int
+info_cb (const td_thrhandle_t *th, void *s)
+{
+ td_err_e ret;
+ td_thrinfo_t ti;
+
+ if ((ret = p_td_thr_get_info (th, &ti)) == TD_OK)
+ {
+ printf_filtered ("%s thread #%d, lwp %d, ",
+ ti.ti_type == TD_THR_SYSTEM ? "system" : "user ",
+ ti.ti_tid, ti.ti_lid);
+ switch (ti.ti_state)
+ {
+ default:
+ case TD_THR_UNKNOWN:
+ printf_filtered ("<unknown state>");
+ break;
+ case TD_THR_STOPPED:
+ printf_filtered ("(stopped)");
+ break;
+ case TD_THR_RUN:
+ printf_filtered ("(run) ");
+ break;
+ case TD_THR_ACTIVE:
+ printf_filtered ("(active) ");
+ break;
+ case TD_THR_ZOMBIE:
+ printf_filtered ("(zombie) ");
+ break;
+ case TD_THR_SLEEP:
+ printf_filtered ("(asleep) ");
+ break;
+ case TD_THR_STOPPED_ASLEEP:
+ printf_filtered ("(stopped asleep)");
+ break;
+ }
+ /* Print thr_create start function: */
+ if (ti.ti_startfunc != 0)
+ {
+ struct minimal_symbol *msym;
+ msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
+ if (msym)
+ printf_filtered (" startfunc: %s\n", SYMBOL_NAME (msym));
+ else
+ printf_filtered (" startfunc: 0x%s\n", paddr (ti.ti_startfunc));
+ }
+
+ /* If thread is asleep, print function that went to sleep: */
+ if (ti.ti_state == TD_THR_SLEEP)
+ {
+ struct minimal_symbol *msym;
+ msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
+ if (msym)
+ printf_filtered (" - Sleep func: %s\n", SYMBOL_NAME (msym));
+ else
+ printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc));
+ }
+
+ /* Wrap up line, if necessary */
+ if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
+ printf_filtered ("\n"); /* don't you hate counting newlines? */
+ }
+ else
+ warning ("info sol-thread: failed to get info for thread.");
+
+ return 0;
+}
+
+/* List some state about each Solaris user thread in the inferior. */
+
+static void
+info_solthreads (char *args, int from_tty)
+{
+ p_td_ta_thr_iter (main_ta, info_cb, args,
+ TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
+ TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
+}
+
+static int
+sol_find_memory_regions (int (*func) (CORE_ADDR,
+ unsigned long,
+ int, int, int,
+ void *),
+ void *data)
+{
+ return procfs_ops.to_find_memory_regions (func, data);
+}
+
+static char *
+sol_make_note_section (bfd *obfd, int *note_size)
+{
+ return procfs_ops.to_make_corefile_notes (obfd, note_size);
+}
+
+static int
+ignore (CORE_ADDR addr, char *contents)
+{
+ return 0;
+}
+
+
+static void
+init_sol_thread_ops (void)
+{
+ sol_thread_ops.to_shortname = "solaris-threads";
+ sol_thread_ops.to_longname = "Solaris threads and pthread.";
+ sol_thread_ops.to_doc = "Solaris threads and pthread support.";
+ sol_thread_ops.to_open = sol_thread_open;
+ sol_thread_ops.to_close = 0;
+ sol_thread_ops.to_attach = sol_thread_attach;
+ sol_thread_ops.to_detach = sol_thread_detach;
+ sol_thread_ops.to_resume = sol_thread_resume;
+ sol_thread_ops.to_wait = sol_thread_wait;
+ sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
+ sol_thread_ops.to_store_registers = sol_thread_store_registers;
+ sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
+ sol_thread_ops.to_xfer_memory = sol_thread_xfer_memory;
+ sol_thread_ops.to_files_info = sol_thread_files_info;
+ sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ sol_thread_ops.to_terminal_init = terminal_init_inferior;
+ sol_thread_ops.to_terminal_inferior = terminal_inferior;
+ sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ sol_thread_ops.to_terminal_ours = terminal_ours;
+ sol_thread_ops.to_terminal_info = child_terminal_info;
+ sol_thread_ops.to_kill = sol_thread_kill_inferior;
+ sol_thread_ops.to_load = 0;
+ sol_thread_ops.to_lookup_symbol = 0;
+ sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
+ sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
+ sol_thread_ops.to_can_run = sol_thread_can_run;
+ sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
+ sol_thread_ops.to_thread_alive = sol_thread_alive;
+ sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
+ sol_thread_ops.to_find_new_threads = sol_find_new_threads;
+ sol_thread_ops.to_stop = sol_thread_stop;
+ sol_thread_ops.to_stratum = process_stratum;
+ sol_thread_ops.to_has_all_memory = 1;
+ sol_thread_ops.to_has_memory = 1;
+ sol_thread_ops.to_has_stack = 1;
+ sol_thread_ops.to_has_registers = 1;
+ sol_thread_ops.to_has_execution = 1;
+ sol_thread_ops.to_has_thread_control = tc_none;
+ sol_thread_ops.to_sections = 0;
+ sol_thread_ops.to_sections_end = 0;
+ sol_thread_ops.to_find_memory_regions = sol_find_memory_regions;
+ sol_thread_ops.to_make_corefile_notes = sol_make_note_section;
+ sol_thread_ops.to_magic = OPS_MAGIC;
+}
+
+
+static void
+init_sol_core_ops (void)
+{
+ sol_core_ops.to_shortname = "solaris-core";
+ sol_core_ops.to_longname = "Solaris core threads and pthread.";
+ sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
+ sol_core_ops.to_open = sol_core_open;
+ sol_core_ops.to_close = sol_core_close;
+ sol_core_ops.to_attach = sol_thread_attach;
+ sol_core_ops.to_detach = sol_core_detach;
+ /* sol_core_ops.to_resume = 0; */
+ /* sol_core_ops.to_wait = 0; */
+ sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
+ /* sol_core_ops.to_store_registers = 0; */
+ /* sol_core_ops.to_prepare_to_store = 0; */
+ sol_core_ops.to_xfer_memory = sol_thread_xfer_memory;
+ sol_core_ops.to_files_info = sol_core_files_info;
+ sol_core_ops.to_insert_breakpoint = ignore;
+ sol_core_ops.to_remove_breakpoint = ignore;
+ /* sol_core_ops.to_terminal_init = 0; */
+ /* sol_core_ops.to_terminal_inferior = 0; */
+ /* sol_core_ops.to_terminal_ours_for_output = 0; */
+ /* sol_core_ops.to_terminal_ours = 0; */
+ /* sol_core_ops.to_terminal_info = 0; */
+ /* sol_core_ops.to_kill = 0; */
+ /* sol_core_ops.to_load = 0; */
+ /* sol_core_ops.to_lookup_symbol = 0; */
+ sol_core_ops.to_create_inferior = sol_thread_create_inferior;
+ sol_core_ops.to_stratum = core_stratum;
+ sol_core_ops.to_has_all_memory = 0;
+ sol_core_ops.to_has_memory = 1;
+ sol_core_ops.to_has_stack = 1;
+ sol_core_ops.to_has_registers = 1;
+ sol_core_ops.to_has_execution = 0;
+ sol_core_ops.to_has_thread_control = tc_none;
+ sol_core_ops.to_thread_alive = sol_thread_alive;
+ sol_core_ops.to_pid_to_str = solaris_pid_to_str;
+ /* On Solaris/x86, when debugging a threaded core file from process <n>,
+ the following causes "info threads" to produce "procfs: couldn't find pid
+ <n> in procinfo list" where <n> is the pid of the process that produced
+ the core file. Disable it for now. */
+ /* sol_core_ops.to_find_new_threads = sol_find_new_threads; */
+ sol_core_ops.to_sections = 0;
+ sol_core_ops.to_sections_end = 0;
+ sol_core_ops.to_magic = OPS_MAGIC;
+}
+
+/* we suppress the call to add_target of core_ops in corelow because
+ if there are two targets in the stratum core_stratum, find_core_target
+ won't know which one to return. see corelow.c for an additonal
+ comment on coreops_suppress_target. */
+int coreops_suppress_target = 1;
+
+void
+_initialize_sol_thread (void)
+{
+ void *dlhandle;
+
+ init_sol_thread_ops ();
+ init_sol_core_ops ();
+
+ dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
+ if (!dlhandle)
+ goto die;
+
+#define resolve(X) \
+ if (!(p_##X = dlsym (dlhandle, #X))) \
+ goto die;
+
+ resolve (td_log);
+ resolve (td_ta_new);
+ resolve (td_ta_delete);
+ resolve (td_init);
+ resolve (td_ta_get_ph);
+ resolve (td_ta_get_nthreads);
+ resolve (td_ta_tsd_iter);
+ resolve (td_ta_thr_iter);
+ resolve (td_thr_validate);
+ resolve (td_thr_tsd);
+ resolve (td_thr_get_info);
+ resolve (td_thr_getfpregs);
+ resolve (td_thr_getxregsize);
+ resolve (td_thr_getxregs);
+ resolve (td_thr_sigsetmask);
+ resolve (td_thr_setprio);
+ resolve (td_thr_setsigpending);
+ resolve (td_thr_setfpregs);
+ resolve (td_thr_setxregs);
+ resolve (td_ta_map_id2thr);
+ resolve (td_ta_map_lwp2thr);
+ resolve (td_thr_getgregs);
+ resolve (td_thr_setgregs);
+
+ add_target (&sol_thread_ops);
+
+ procfs_suppress_run = 1;
+
+ add_cmd ("sol-threads", class_maintenance, info_solthreads,
+ "Show info on Solaris user threads.\n", &maintenanceinfolist);
+
+ memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
+ memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
+ add_target (&core_ops);
+
+ /* Hook into new_objfile notification. */
+ target_new_objfile_chain = target_new_objfile_hook;
+ target_new_objfile_hook = sol_thread_new_objfile;
+ return;
+
+die:
+
+ fprintf_unfiltered (gdb_stderr, "[GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
+
+ if (dlhandle)
+ dlclose (dlhandle);
+
+ /* allow the user to debug non-threaded core files */
+ add_target (&core_ops);
+
+ return;
+}
diff --git a/gdb/solib-aix5.c b/gdb/solib-aix5.c
new file mode 100644
index 00000000000..1a8c9dfeea9
--- /dev/null
+++ b/gdb/solib-aix5.c
@@ -0,0 +1,958 @@
+/* Handle AIX5 shared libraries for GDB, the GNU Debugger.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
+ 2001
+ 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 "defs.h"
+
+#include <sys/types.h>
+#include <signal.h>
+#include "gdb_string.h"
+#include <sys/param.h>
+#include <fcntl.h>
+#include <sys/procfs.h>
+
+#include "elf/external.h"
+
+#include "symtab.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "target.h"
+#include "frame.h"
+#include "gdb_regex.h"
+#include "inferior.h"
+#include "environ.h"
+#include "language.h"
+#include "gdbcmd.h"
+
+#include "solist.h"
+
+/* Link map info to include in an allocated so_list entry */
+
+struct lm_info
+ {
+ int nmappings; /* number of mappings */
+ struct lm_mapping
+ {
+ CORE_ADDR addr; /* base address */
+ CORE_ADDR size; /* size of mapped object */
+ CORE_ADDR offset; /* offset into mapped object */
+ long flags; /* MA_ protection and attribute flags */
+ CORE_ADDR gp; /* global pointer value */
+ } *mapping;
+ char *mapname; /* name in /proc/pid/object */
+ char *pathname; /* full pathname to object */
+ char *membername; /* member name in archive file */
+ };
+
+/* List of symbols in the dynamic linker where GDB can try to place
+ a breakpoint to monitor shared library events. */
+
+static char *solib_break_names[] =
+{
+ "_r_debug_state",
+ NULL
+};
+
+static void aix5_relocate_main_executable (void);
+
+/*
+
+ LOCAL FUNCTION
+
+ bfd_lookup_symbol -- lookup the value for a specific symbol
+
+ SYNOPSIS
+
+ CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname)
+
+ DESCRIPTION
+
+ An expensive way to lookup the value of a single symbol for
+ bfd's that are only temporary anyway. This is used by the
+ shared library support to find the address of the debugger
+ interface structures in the shared library.
+
+ Note that 0 is specifically allowed as an error return (no
+ such symbol).
+ */
+
+static CORE_ADDR
+bfd_lookup_symbol (bfd *abfd, char *symname)
+{
+ long storage_needed;
+ asymbol *sym;
+ asymbol **symbol_table;
+ unsigned int number_of_symbols;
+ unsigned int i;
+ struct cleanup *back_to;
+ CORE_ADDR symaddr = 0;
+
+ storage_needed = bfd_get_symtab_upper_bound (abfd);
+
+ if (storage_needed > 0)
+ {
+ symbol_table = (asymbol **) xmalloc (storage_needed);
+ back_to = make_cleanup (xfree, symbol_table);
+ number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
+
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ sym = *symbol_table++;
+ if (strcmp (sym->name, symname) == 0)
+ {
+ /* Bfd symbols are section relative. */
+ symaddr = sym->value + sym->section->vma;
+ break;
+ }
+ }
+ do_cleanups (back_to);
+ }
+
+ if (symaddr)
+ return symaddr;
+
+ /* Look for the symbol in the dynamic string table too. */
+
+ storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);
+
+ if (storage_needed > 0)
+ {
+ symbol_table = (asymbol **) xmalloc (storage_needed);
+ back_to = make_cleanup (xfree, symbol_table);
+ number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table);
+
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ sym = *symbol_table++;
+ if (strcmp (sym->name, symname) == 0)
+ {
+ /* Bfd symbols are section relative. */
+ symaddr = sym->value + sym->section->vma;
+ break;
+ }
+ }
+ do_cleanups (back_to);
+ }
+
+ return symaddr;
+}
+
+
+/* Read /proc/PID/map and build a list of shared objects such that
+ the pr_mflags value AND'd with MATCH_MASK is equal to MATCH_VAL.
+ This gives us a convenient way to find all of the mappings that
+ don't belong to the main executable or vice versa. Here are
+ some of the possibilities:
+
+ - Fetch all mappings:
+ MATCH_MASK: 0
+ MATCH_VAL: 0
+ - Fetch all mappings except for main executable:
+ MATCH_MASK: MA_MAINEXEC
+ MATCH_VAL: 0
+ - Fetch only main executable:
+ MATCH_MASK: MA_MAINEXEC
+ MATCH_VAL: MA_MAINEXEC
+
+ A cleanup chain for the list allocations done by this function should
+ be established prior to calling build_so_list_from_mapfile(). */
+
+static struct so_list *
+build_so_list_from_mapfile (int pid, long match_mask, long match_val)
+{
+ char *mapbuf = NULL;
+ struct prmap *prmap;
+ int mapbuf_size;
+ struct so_list *sos = NULL;
+
+ {
+ int mapbuf_allocation_size = 8192;
+ char *map_pathname;
+ int map_fd;
+
+ /* Open the map file */
+
+ xasprintf (&map_pathname, "/proc/%d/map", pid);
+ map_fd = open (map_pathname, O_RDONLY);
+ xfree (map_pathname);
+ if (map_fd < 0)
+ return 0;
+
+ /* Read the entire map file in */
+ do
+ {
+ if (mapbuf)
+ {
+ xfree (mapbuf);
+ mapbuf_allocation_size *= 2;
+ lseek (map_fd, 0, SEEK_SET);
+ }
+ mapbuf = xmalloc (mapbuf_allocation_size);
+ mapbuf_size = read (map_fd, mapbuf, mapbuf_allocation_size);
+ if (mapbuf_size < 0)
+ {
+ xfree (mapbuf);
+ /* FIXME: This warrants an error or a warning of some sort */
+ return 0;
+ }
+ } while (mapbuf_size == mapbuf_allocation_size);
+
+ close (map_fd);
+ }
+
+ for (prmap = (struct prmap *) mapbuf;
+ (char *) prmap < mapbuf + mapbuf_size;
+ prmap++)
+ {
+ char *mapname, *pathname, *membername;
+ struct so_list *sop;
+ int mapidx;
+
+ if (prmap->pr_size == 0)
+ break;
+
+ /* Skip to the next entry if there's no path associated with the
+ map, unless we're looking for the kernel text region, in which
+ case it's okay if there's no path. */
+ if ((prmap->pr_pathoff == 0 || prmap->pr_pathoff >= mapbuf_size)
+ && ((match_mask & MA_KERNTEXT) == 0))
+ continue;
+
+ /* Skip to the next entry if our match conditions don't hold. */
+ if ((prmap->pr_mflags & match_mask) != match_val)
+ continue;
+
+ mapname = prmap->pr_mapname;
+ if (prmap->pr_pathoff == 0)
+ {
+ pathname = "";
+ membername = "";
+ }
+ else
+ {
+ pathname = mapbuf + prmap->pr_pathoff;
+ membername = pathname + strlen (pathname) + 1;
+ }
+
+ for (sop = sos; sop != NULL; sop = sop->next)
+ if (strcmp (pathname, sop->lm_info->pathname) == 0
+ && strcmp (membername, sop->lm_info->membername) == 0)
+ break;
+
+ if (sop == NULL)
+ {
+ sop = xcalloc (1, sizeof (struct so_list));
+ make_cleanup (xfree, sop);
+ sop->lm_info = xcalloc (1, sizeof (struct lm_info));
+ make_cleanup (xfree, sop->lm_info);
+ sop->lm_info->mapname = xstrdup (mapname);
+ make_cleanup (xfree, sop->lm_info->mapname);
+ /* FIXME: Eliminate the pathname field once length restriction
+ is lifted on so_name and so_original_name. */
+ sop->lm_info->pathname = xstrdup (pathname);
+ make_cleanup (xfree, sop->lm_info->pathname);
+ sop->lm_info->membername = xstrdup (membername);
+ make_cleanup (xfree, sop->lm_info->membername);
+
+ strncpy (sop->so_name, pathname, SO_NAME_MAX_PATH_SIZE - 1);
+ sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
+ strcpy (sop->so_original_name, sop->so_name);
+
+ sop->next = sos;
+ sos = sop;
+ }
+
+ mapidx = sop->lm_info->nmappings;
+ sop->lm_info->nmappings += 1;
+ sop->lm_info->mapping
+ = xrealloc (sop->lm_info->mapping,
+ sop->lm_info->nmappings * sizeof (struct lm_mapping));
+ sop->lm_info->mapping[mapidx].addr = (CORE_ADDR) prmap->pr_vaddr;
+ sop->lm_info->mapping[mapidx].size = prmap->pr_size;
+ sop->lm_info->mapping[mapidx].offset = prmap->pr_off;
+ sop->lm_info->mapping[mapidx].flags = prmap->pr_mflags;
+ sop->lm_info->mapping[mapidx].gp = (CORE_ADDR) prmap->pr_gp;
+ }
+
+ xfree (mapbuf);
+ return sos;
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ open_symbol_file_object
+
+ SYNOPSIS
+
+ void open_symbol_file_object (void *from_tty)
+
+ DESCRIPTION
+
+ If no open symbol file, attempt to locate and open the main symbol
+ file.
+
+ If FROM_TTYP dereferences to a non-zero integer, allow messages to
+ be printed. This parameter is a pointer rather than an int because
+ open_symbol_file_object() is called via catch_errors() and
+ catch_errors() requires a pointer argument. */
+
+static int
+open_symbol_file_object (void *from_ttyp)
+{
+ CORE_ADDR lm, l_name;
+ char *filename;
+ int errcode;
+ int from_tty = *(int *)from_ttyp;
+ struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
+ struct so_list *sos;
+
+ sos = build_so_list_from_mapfile (PIDGET (inferior_ptid),
+ MA_MAINEXEC, MA_MAINEXEC);
+
+
+ if (sos == NULL)
+ {
+ warning ("Could not find name of main executable in map file");
+ return 0;
+ }
+
+ symbol_file_command (sos->lm_info->pathname, from_tty);
+
+ do_cleanups (old_chain);
+
+ aix5_relocate_main_executable ();
+
+ return 1;
+}
+
+/* LOCAL FUNCTION
+
+ aix5_current_sos -- build a list of currently loaded shared objects
+
+ SYNOPSIS
+
+ struct so_list *aix5_current_sos ()
+
+ DESCRIPTION
+
+ Build a list of `struct so_list' objects describing the shared
+ objects currently loaded in the inferior. This list does not
+ include an entry for the main executable file.
+
+ Note that we only gather information directly available from the
+ inferior --- we don't examine any of the shared library files
+ themselves. The declaration of `struct so_list' says which fields
+ we provide values for. */
+
+static struct so_list *
+aix5_current_sos (void)
+{
+ struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
+ struct so_list *sos;
+
+ /* Fetch the list of mappings, excluding the main executable. */
+ sos = build_so_list_from_mapfile (PIDGET (inferior_ptid), MA_MAINEXEC, 0);
+
+ /* Reverse the list; it looks nicer when we print it if the mappings
+ are in the same order as in the map file. */
+ if (sos)
+ {
+ struct so_list *next = sos->next;
+
+ sos->next = 0;
+ while (next)
+ {
+ struct so_list *prev = sos;
+
+ sos = next;
+ next = next->next;
+ sos->next = prev;
+ }
+ }
+ discard_cleanups (old_chain);
+ return sos;
+}
+
+
+/* Return 1 if PC lies in the dynamic symbol resolution code of the
+ run time loader. */
+
+static CORE_ADDR interp_text_sect_low;
+static CORE_ADDR interp_text_sect_high;
+static CORE_ADDR interp_plt_sect_low;
+static CORE_ADDR interp_plt_sect_high;
+
+static int
+aix5_in_dynsym_resolve_code (CORE_ADDR pc)
+{
+ return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
+ || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
+ || in_plt_section (pc, NULL));
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ enable_break -- arrange for dynamic linker to hit breakpoint
+
+ SYNOPSIS
+
+ int enable_break (void)
+
+ DESCRIPTION
+
+ The dynamic linkers has, as part of its debugger interface, support
+ for arranging for the inferior to hit a breakpoint after mapping in
+ the shared libraries. This function enables that breakpoint.
+
+ */
+
+static int
+enable_break (void)
+{
+ int success = 0;
+
+ struct minimal_symbol *msymbol;
+ char **bkpt_namep;
+ asection *interp_sect;
+
+ /* First, remove all the solib event breakpoints. Their addresses
+ may have changed since the last time we ran the program. */
+ remove_solib_event_breakpoints ();
+
+ interp_text_sect_low = interp_text_sect_high = 0;
+ interp_plt_sect_low = interp_plt_sect_high = 0;
+
+ /* Find the .interp section; if not found, warn the user and drop
+ into the old breakpoint at symbol code. */
+ interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
+ if (interp_sect)
+ {
+ unsigned int interp_sect_size;
+ char *buf;
+ CORE_ADDR load_addr;
+ bfd *tmp_bfd;
+ CORE_ADDR sym_addr = 0;
+
+ /* Read the contents of the .interp section into a local buffer;
+ the contents specify the dynamic linker this program uses. */
+ interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
+ buf = alloca (interp_sect_size);
+ bfd_get_section_contents (exec_bfd, interp_sect,
+ buf, 0, interp_sect_size);
+
+ /* Now we need to figure out where the dynamic linker was
+ loaded so that we can load its symbols and place a breakpoint
+ in the dynamic linker itself.
+
+ This address is stored on the stack. However, I've been unable
+ to find any magic formula to find it for Solaris (appears to
+ be trivial on GNU/Linux). Therefore, we have to try an alternate
+ mechanism to find the dynamic linker's base address. */
+ tmp_bfd = bfd_openr (buf, gnutarget);
+ if (tmp_bfd == NULL)
+ goto bkpt_at_symbol;
+
+ /* Make sure the dynamic linker's really a useful object. */
+ if (!bfd_check_format (tmp_bfd, bfd_object))
+ {
+ warning ("Unable to grok dynamic linker %s as an object file", buf);
+ bfd_close (tmp_bfd);
+ goto bkpt_at_symbol;
+ }
+
+ /* We find the dynamic linker's base address by examining the
+ current pc (which point at the entry point for the dynamic
+ linker) and subtracting the offset of the entry point. */
+ load_addr = read_pc () - tmp_bfd->start_address;
+
+ /* Record the relocated start and end address of the dynamic linker
+ text and plt section for aix5_in_dynsym_resolve_code. */
+ interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
+ if (interp_sect)
+ {
+ interp_text_sect_low =
+ bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+ interp_text_sect_high =
+ interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+ }
+ interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
+ if (interp_sect)
+ {
+ interp_plt_sect_low =
+ bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+ interp_plt_sect_high =
+ interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+ }
+
+ /* Now try to set a breakpoint in the dynamic linker. */
+ for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++)
+ {
+ sym_addr = bfd_lookup_symbol (tmp_bfd, *bkpt_namep);
+ if (sym_addr != 0)
+ break;
+ }
+
+ /* We're done with the temporary bfd. */
+ bfd_close (tmp_bfd);
+
+ if (sym_addr != 0)
+ {
+ create_solib_event_breakpoint (load_addr + sym_addr);
+ return 1;
+ }
+
+ /* For whatever reason we couldn't set a breakpoint in the dynamic
+ linker. Warn and drop into the old code. */
+ bkpt_at_symbol:
+ warning ("Unable to find dynamic linker breakpoint function.\nGDB will be unable to debug shared library initializers\nand track explicitly loaded dynamic code.");
+ }
+
+ /* Nothing good happened. */
+ success = 0;
+
+ return (success);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ special_symbol_handling -- additional shared library symbol handling
+
+ SYNOPSIS
+
+ void special_symbol_handling ()
+
+ DESCRIPTION
+
+ Once the symbols from a shared object have been loaded in the usual
+ way, we are called to do any system specific symbol handling that
+ is needed.
+
+ */
+
+static void
+aix5_special_symbol_handling (void)
+{
+ /* Nothing needed (yet) for AIX5. */
+}
+
+/* On AIX5, the /proc/PID/map information is used to determine
+ the relocation offsets needed for relocating the main executable.
+ There is no problem determining which map entries correspond
+ to the main executable, because these will have the MA_MAINEXEC
+ flag set. The tricky part is determining which sections correspond
+ to which map entries. To date, the following approaches have
+ been tried:
+
+ - Use the MA_WRITE attribute of pr_mflags to distinguish the read-only
+ mapping from the read/write mapping. (This assumes that there are
+ only two mappings for the main executable.) All writable sections
+ are associated with the read/write mapping and all non-writable
+ sections are associated with the read-only mapping.
+
+ This approach worked quite well until we came across executables
+ which didn't have a read-only mapping. Both mappings had the
+ same attributes represented in pr_mflags and it was impossible
+ to tell them apart.
+
+ - Use the pr_off field (which represents the offset into the
+ executable) to determine the section-to-mapping relationship.
+ Unfortunately, this approach doesn't work either, because the
+ offset value contained in the mapping is rounded down by some
+ moderately large power-of-2 value (4096 is a typical value).
+ A small (e.g. "Hello World") program will appear to have all
+ of its sections belonging to both mappings.
+
+ Also, the following approach has been considered, but dismissed:
+
+ - The section vma values typically look (something) like
+ 0x00000001xxxxxxxx or 0x00000002xxxxxxxx. Furthermore, the
+ 0x00000001xxxxxxxx values always belong to one mapping and
+ the 0x00000002xxxxxxxx values always belong to the other.
+ Thus it seems conceivable that GDB could use the bit patterns
+ in the upper portion (for some definition of "upper") in a
+ section's vma to help determine the section-to-mapping
+ relationship.
+
+ This approach was dismissed because there is nothing to prevent
+ the linker from lumping the section vmas together in one large
+ contiguous space and still expecting the dynamic linker to
+ separate them and relocate them independently. Also, different
+ linkers have been observed to use different patterns for the
+ upper portions of the vma addresses and it isn't clear what the
+ mask ought to be for distinguishing these patterns.
+
+ The current (admittedly inelegant) approach uses a lookup
+ table which associates section names with the map index that
+ they're permitted to be in. This is inelegant because we are
+ making the following assumptions:
+
+ 1) There will only be two mappings.
+ 2) The relevant (i.e. main executable) mappings will always appear
+ in the same order in the map file.
+ 3) The sections named in the table will always belong to the
+ indicated mapping.
+ 4) The table completely enumerates all possible section names.
+
+ IMO, any of these deficiencies alone will normally be sufficient
+ to disqualify this approach, but I haven't been able to think of
+ a better way to do it.
+
+ map_index_vs_section_name_okay() is a predicate which returns
+ true iff the section name NAME is associated with the map index
+ IDX in its builtin table. Of course, there's no guarantee that
+ this association is actually valid... */
+
+static int
+map_index_vs_section_name_okay (int idx, const char *name)
+{
+ static struct
+ {
+ char *name;
+ int idx;
+ } okay[] =
+ {
+ { ".interp", 0 },
+ { ".hash", 0 },
+ { ".dynsym", 0 },
+ { ".dynstr", 0 },
+ { ".rela.text", 0 },
+ { ".rela.rodata", 0 },
+ { ".rela.data", 0 },
+ { ".rela.ctors", 0 },
+ { ".rela.dtors", 0 },
+ { ".rela.got", 0 },
+ { ".rela.sdata", 0 },
+ { ".rela.IA_64.pltoff", 0 },
+ { ".rel.data", 0 },
+ { ".rel.sdata", 0 },
+ { ".rel.got", 0 },
+ { ".rel.AIX.pfdesc", 0 },
+ { ".rel.IA_64.pltoff", 0 },
+ { ".dynamic", 0 },
+ { ".init", 0 },
+ { ".plt", 0 },
+ { ".text", 0 },
+ { ".fini", 0 },
+ { ".rodata", 0 },
+ { ".IA_64.unwind_info", 0 },
+ { ".IA_64.unwind", 0 },
+ { ".AIX.mustrel", 0 },
+
+ { ".data", 1 },
+ { ".ctors", 1 },
+ { ".dtors", 1 },
+ { ".got", 1 },
+ { ".dynamic", 1},
+ { ".sdata", 1 },
+ { ".IA_64.pltoff", 1 },
+ { ".sbss", 1 },
+ { ".bss", 1 },
+ { ".AIX.pfdesc", 1 }
+ };
+ int i;
+
+ for (i = 0; i < sizeof (okay) / sizeof (okay[0]); i++)
+ {
+ if (strcmp (name, okay[i].name) == 0)
+ return idx == okay[i].idx;
+ }
+
+ warning ("solib-aix5.c: Ignoring section %s when relocating the executable\n",
+ name);
+ return 0;
+}
+
+#define SECTMAPMASK (~ (CORE_ADDR) 0x03ffffff)
+
+static void
+aix5_relocate_main_executable (void)
+{
+ struct so_list *so;
+ struct section_offsets *new_offsets;
+ int i;
+ int changed = 0;
+ struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
+
+ /* Fetch the mappings for the main executable from the map file. */
+ so = build_so_list_from_mapfile (PIDGET (inferior_ptid),
+ MA_MAINEXEC, MA_MAINEXEC);
+
+ /* Make sure we actually have some mappings to work with. */
+ if (so == NULL)
+ {
+ warning ("Could not find main executable in map file");
+ do_cleanups (old_chain);
+ return;
+ }
+
+ /* Allocate the data structure which'll contain the new offsets to
+ relocate by. Initialize it so it contains the current offsets. */
+ new_offsets = xcalloc (symfile_objfile->num_sections,
+ sizeof (struct section_offsets));
+ make_cleanup (xfree, new_offsets);
+ for (i = 0; i < symfile_objfile->num_sections; i++)
+ new_offsets->offsets[i] = ANOFFSET (symfile_objfile->section_offsets, i);
+
+ /* Iterate over the mappings in the main executable and compute
+ the new offset value as appropriate. */
+ for (i = 0; i < so->lm_info->nmappings; i++)
+ {
+ CORE_ADDR increment = 0;
+ struct obj_section *sect;
+ bfd *obfd = symfile_objfile->obfd;
+ struct lm_mapping *mapping = &so->lm_info->mapping[i];
+
+ ALL_OBJFILE_OSECTIONS (symfile_objfile, sect)
+ {
+ int flags = bfd_get_section_flags (obfd, sect->the_bfd_section);
+ if (flags & SEC_ALLOC)
+ {
+ file_ptr filepos = sect->the_bfd_section->filepos;
+ if (map_index_vs_section_name_okay (i,
+ bfd_get_section_name (obfd, sect->the_bfd_section)))
+ {
+ int idx = sect->the_bfd_section->index;
+
+ if (increment == 0)
+ increment = mapping->addr
+ - (bfd_section_vma (obfd, sect->the_bfd_section)
+ & SECTMAPMASK);
+
+ if (increment != ANOFFSET (new_offsets, idx))
+ {
+ new_offsets->offsets[idx] = increment;
+ changed = 1;
+ }
+ }
+ }
+ }
+ }
+
+ /* If any of the offsets have changed, then relocate the objfile. */
+ if (changed)
+ objfile_relocate (symfile_objfile, new_offsets);
+
+ /* Free up all the space we've allocated. */
+ do_cleanups (old_chain);
+}
+
+/*
+
+ GLOBAL FUNCTION
+
+ aix5_solib_create_inferior_hook -- shared library startup support
+
+ SYNOPSIS
+
+ void aix5_solib_create_inferior_hook()
+
+ DESCRIPTION
+
+ When gdb starts up the inferior, it nurses it along (through the
+ shell) until it is ready to execute it's first instruction. At this
+ point, this function gets called via expansion of the macro
+ SOLIB_CREATE_INFERIOR_HOOK.
+
+ For AIX5 executables, this first instruction is the first
+ instruction in the dynamic linker (for dynamically linked
+ executables) or the instruction at "start" for statically linked
+ executables. For dynamically linked executables, the system
+ first exec's libc.so.N, which contains the dynamic linker,
+ and starts it running. The dynamic linker maps in any needed
+ shared libraries, maps in the actual user executable, and then
+ jumps to "start" in the user executable.
+
+ */
+
+static void
+aix5_solib_create_inferior_hook (void)
+{
+ aix5_relocate_main_executable ();
+
+ if (!enable_break ())
+ {
+ warning ("shared library handler failed to enable breakpoint");
+ return;
+ }
+}
+
+static void
+aix5_clear_solib (void)
+{
+}
+
+static void
+aix5_free_so (struct so_list *so)
+{
+ xfree (so->lm_info->mapname);
+ xfree (so->lm_info->pathname);
+ xfree (so->lm_info->membername);
+ xfree (so->lm_info);
+}
+
+static void
+aix5_relocate_section_addresses (struct so_list *so,
+ struct section_table *sec)
+{
+ int flags = bfd_get_section_flags (sec->bfd, sec->the_bfd_section);
+ file_ptr filepos = sec->the_bfd_section->filepos;
+
+ if (flags & SEC_ALLOC)
+ {
+ int idx;
+ CORE_ADDR addr;
+
+ for (idx = 0; idx < so->lm_info->nmappings; idx++)
+ {
+ struct lm_mapping *mapping = &so->lm_info->mapping[idx];
+ if (mapping->offset <= filepos
+ && filepos <= mapping->offset + mapping->size)
+ break;
+ }
+
+ if (idx >= so->lm_info->nmappings)
+ internal_error (__FILE__, __LINE__,
+ "aix_relocate_section_addresses: Can't find mapping for section %s",
+ bfd_get_section_name (sec->bfd, sec->the_bfd_section));
+
+ addr = so->lm_info->mapping[idx].addr;
+
+ sec->addr += addr;
+ sec->endaddr += addr;
+ }
+}
+
+/* Find the global pointer for the given function address ADDR. */
+
+static CORE_ADDR
+aix5_find_global_pointer (CORE_ADDR addr)
+{
+ struct so_list *sos, *so;
+ CORE_ADDR global_pointer = 0;
+ struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
+
+ sos = build_so_list_from_mapfile (PIDGET (inferior_ptid), 0, 0);
+
+ for (so = sos; so != NULL; so = so->next)
+ {
+ int idx;
+ for (idx = 0; idx < so->lm_info->nmappings; idx++)
+ if (so->lm_info->mapping[idx].addr <= addr
+ && addr <= so->lm_info->mapping[idx].addr
+ + so->lm_info->mapping[idx].size)
+ {
+ break;
+ }
+
+ if (idx < so->lm_info->nmappings)
+ {
+ /* Look for a non-zero global pointer in the current set of
+ mappings. */
+ for (idx = 0; idx < so->lm_info->nmappings; idx++)
+ if (so->lm_info->mapping[idx].gp != 0)
+ {
+ global_pointer = so->lm_info->mapping[idx].gp;
+ break;
+ }
+ /* Get out regardless of whether we found one or not. Mappings
+ don't overlap, so it would be pointless to continue. */
+ break;
+ }
+ }
+
+ do_cleanups (old_chain);
+
+ return global_pointer;
+}
+
+/* Find the execute-only kernel region known as the gate page. This
+ page is where the signal trampoline lives. It may be found by
+ querying the map file and looking for the MA_KERNTEXT flag. */
+static void
+aix5_find_gate_addresses (CORE_ADDR *start, CORE_ADDR *end)
+{
+ struct so_list *so;
+ struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
+
+ /* Fetch the mappings for the main executable from the map file. */
+ so = build_so_list_from_mapfile (PIDGET (inferior_ptid),
+ MA_KERNTEXT, MA_KERNTEXT);
+
+ /* Make sure we actually have some mappings to work with. */
+ if (so == NULL)
+ {
+ warning ("Could not find gate page in map file");
+ *start = 0;
+ *end = 0;
+ do_cleanups (old_chain);
+ return;
+ }
+
+ /* There should only be on kernel mapping for the gate page and
+ it'll be in the read-only (even though it's execute-only)
+ mapping in the lm_info struct. */
+
+ *start = so->lm_info->mapping[0].addr;
+ *end = *start + so->lm_info->mapping[0].size;
+
+ /* Free up all the space we've allocated. */
+ do_cleanups (old_chain);
+}
+
+/* From ia64-tdep.c. FIXME: If we end up using this for rs6000 too,
+ we'll need to make the names match. */
+extern CORE_ADDR (*native_find_global_pointer) (CORE_ADDR);
+
+/* From ia64-aix-tdep.c. Hook for finding the starting and
+ ending gate page addresses. The only reason that this hook
+ is in this file is because this is where the map file reading
+ code is located. */
+extern void (*aix5_find_gate_addresses_hook) (CORE_ADDR *, CORE_ADDR *);
+
+static struct target_so_ops aix5_so_ops;
+
+void
+_initialize_aix5_solib (void)
+{
+ aix5_so_ops.relocate_section_addresses = aix5_relocate_section_addresses;
+ aix5_so_ops.free_so = aix5_free_so;
+ aix5_so_ops.clear_solib = aix5_clear_solib;
+ aix5_so_ops.solib_create_inferior_hook = aix5_solib_create_inferior_hook;
+ aix5_so_ops.special_symbol_handling = aix5_special_symbol_handling;
+ aix5_so_ops.current_sos = aix5_current_sos;
+ aix5_so_ops.open_symbol_file_object = open_symbol_file_object;
+ aix5_so_ops.in_dynsym_resolve_code = aix5_in_dynsym_resolve_code;
+
+ native_find_global_pointer = aix5_find_global_pointer;
+ aix5_find_gate_addresses_hook = aix5_find_gate_addresses;
+
+ /* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */
+ current_target_so_ops = &aix5_so_ops;
+}
diff --git a/gdb/solib-legacy.c b/gdb/solib-legacy.c
new file mode 100644
index 00000000000..2dd9fa5fd02
--- /dev/null
+++ b/gdb/solib-legacy.c
@@ -0,0 +1,151 @@
+/* Provide legacy r_debug and link_map support for SVR4-like native targets.
+ Copyright 2000, 2001
+ 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 "defs.h"
+#include "gdbcore.h"
+#include "solib-svr4.h"
+
+#ifdef HAVE_LINK_H
+
+#ifdef HAVE_NLIST_H
+/* nlist.h needs to be included before link.h on some older *BSD systems. */
+#include <nlist.h>
+#endif
+
+#include <link.h>
+
+/* Fetch (and possibly build) an appropriate link_map_offsets structure
+ for native targets using struct definitions from link.h. */
+
+static struct link_map_offsets *
+legacy_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = 0;
+#if defined (HAVE_STRUCT_LINK_MAP32)
+ static struct link_map_offsets lmo32;
+ static struct link_map_offsets *lmp32 = 0;
+#endif
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+#endif
+#define fieldsize(TYPE, MEMBER) (sizeof (((TYPE *)0)->MEMBER))
+
+ if (lmp == 0)
+ {
+ lmp = &lmo;
+
+#ifdef HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS
+ lmo.r_debug_size = sizeof (struct r_debug);
+
+ lmo.r_map_offset = offsetof (struct r_debug, r_map);
+ lmo.r_map_size = fieldsize (struct r_debug, r_map);
+
+ lmo.link_map_size = sizeof (struct link_map);
+
+ lmo.l_addr_offset = offsetof (struct link_map, l_addr);
+ lmo.l_addr_size = fieldsize (struct link_map, l_addr);
+
+ lmo.l_next_offset = offsetof (struct link_map, l_next);
+ lmo.l_next_size = fieldsize (struct link_map, l_next);
+
+ lmo.l_prev_offset = offsetof (struct link_map, l_prev);
+ lmo.l_prev_size = fieldsize (struct link_map, l_prev);
+
+ lmo.l_name_offset = offsetof (struct link_map, l_name);
+ lmo.l_name_size = fieldsize (struct link_map, l_name);
+#else /* !defined(HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS) */
+#ifdef HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS
+ lmo.link_map_size = sizeof (struct link_map);
+
+ lmo.l_addr_offset = offsetof (struct link_map, lm_addr);
+ lmo.l_addr_size = fieldsize (struct link_map, lm_addr);
+
+ lmo.l_next_offset = offsetof (struct link_map, lm_next);
+ lmo.l_next_size = fieldsize (struct link_map, lm_next);
+
+ lmo.l_name_offset = offsetof (struct link_map, lm_name);
+ lmo.l_name_size = fieldsize (struct link_map, lm_name);
+#else /* !defined(HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS) */
+#if HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS
+ lmo.link_map_size = sizeof (struct so_map);
+
+ lmo.l_addr_offset = offsetof (struct so_map, som_addr);
+ lmo.l_addr_size = fieldsize (struct so_map, som_addr);
+
+ lmo.l_next_offset = offsetof (struct so_map, som_next);
+ lmo.l_next_size = fieldsize (struct so_map, som_next);
+
+ lmo.l_name_offset = offsetof (struct so_map, som_path);
+ lmo.l_name_size = fieldsize (struct so_map, som_path);
+#endif /* HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS */
+#endif /* HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS */
+#endif /* HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS */
+ }
+
+#if defined (HAVE_STRUCT_LINK_MAP32)
+ if (lmp32 == 0)
+ {
+ lmp32 = &lmo32;
+
+ lmo32.r_debug_size = sizeof (struct r_debug32);
+
+ lmo32.r_map_offset = offsetof (struct r_debug32, r_map);
+ lmo32.r_map_size = fieldsize (struct r_debug32, r_map);
+
+ lmo32.link_map_size = sizeof (struct link_map32);
+
+ lmo32.l_addr_offset = offsetof (struct link_map32, l_addr);
+ lmo32.l_addr_size = fieldsize (struct link_map32, l_addr);
+
+ lmo32.l_next_offset = offsetof (struct link_map32, l_next);
+ lmo32.l_next_size = fieldsize (struct link_map32, l_next);
+
+ lmo32.l_prev_offset = offsetof (struct link_map32, l_prev);
+ lmo32.l_prev_size = fieldsize (struct link_map32, l_prev);
+
+ lmo32.l_name_offset = offsetof (struct link_map32, l_name);
+ lmo32.l_name_size = fieldsize (struct link_map32, l_name);
+ }
+#endif /* defined (HAVE_STRUCT_LINK_MAP32) */
+
+#if defined (HAVE_STRUCT_LINK_MAP32)
+ if (exec_bfd != NULL)
+ {
+ if (bfd_get_arch_size (exec_bfd) == 32)
+ return lmp32;
+ }
+ if (TARGET_PTR_BIT == 32)
+ return lmp32;
+#endif
+ return lmp;
+}
+
+#endif /* HAVE_LINK_H */
+
+void
+_initialize_svr4_lm (void)
+{
+#ifdef HAVE_LINK_H
+ legacy_svr4_fetch_link_map_offsets_hook = legacy_svr4_fetch_link_map_offsets;
+#endif /* HAVE_LINK_H */
+}
diff --git a/gdb/solib-osf.c b/gdb/solib-osf.c
new file mode 100644
index 00000000000..a00e488ee04
--- /dev/null
+++ b/gdb/solib-osf.c
@@ -0,0 +1,616 @@
+/* Handle OSF/1, Digital UNIX, and Tru64 shared libraries
+ for GDB, the GNU Debugger.
+ Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+ 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. */
+
+/* When handling shared libraries, GDB has to find out the pathnames
+ of all shared libraries that are currently loaded (to read in their
+ symbols) and where the shared libraries are loaded in memory
+ (to relocate them properly from their prelinked addresses to the
+ current load address).
+
+ Under OSF/1 there are two possibilities to get at this information:
+
+ 1) Peek around in the runtime loader structures.
+ These are not documented, and they are not defined in the system
+ header files. The definitions below were obtained by experimentation,
+ but they seem stable enough.
+
+ 2) Use the libxproc.a library, which contains the equivalent ldr_*
+ routines. The library is documented in Tru64 5.x, but as of 5.1, it
+ only allows a process to examine itself. On earlier versions, it
+ may require that the GDB executable be dynamically linked and that
+ NAT_CLIBS include -lxproc -Wl,-expect_unresolved,ldr_process_context
+ for GDB and all applications that are using libgdb.
+
+ We will use the peeking approach until libxproc.a works for other
+ processes. */
+
+#include "defs.h"
+
+#include <sys/types.h>
+#include <signal.h>
+#include "gdb_string.h"
+
+#include "bfd.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "target.h"
+#include "inferior.h"
+#include "solist.h"
+
+#ifdef USE_LDR_ROUTINES
+# include <loader.h>
+#endif
+
+#ifndef USE_LDR_ROUTINES
+/* Definition of runtime loader structures, found by experimentation. */
+#define RLD_CONTEXT_ADDRESS 0x3ffc0000000
+
+/* Per-module information structure referenced by ldr_context_t.head. */
+
+typedef struct
+ {
+ CORE_ADDR next;
+ CORE_ADDR previous;
+ CORE_ADDR unknown1;
+ CORE_ADDR module_name;
+ CORE_ADDR modinfo_addr; /* used by next_link_map_member() to detect
+ the end of the shared module list */
+ long module_id;
+ CORE_ADDR unknown2;
+ CORE_ADDR unknown3;
+ long region_count;
+ CORE_ADDR regioninfo_addr;
+ }
+ldr_module_info_t;
+
+/* Per-region structure referenced by ldr_module_info_t.regioninfo_addr. */
+
+typedef struct
+ {
+ long unknown1;
+ CORE_ADDR regionname_addr;
+ long protection;
+ CORE_ADDR vaddr;
+ CORE_ADDR mapaddr;
+ long size;
+ long unknown2[5];
+ }
+ldr_region_info_t;
+
+/* Structure at RLD_CONTEXT_ADDRESS specifying the start and finish addresses
+ of the shared module list. */
+
+typedef struct
+ {
+ CORE_ADDR unknown1;
+ CORE_ADDR unknown2;
+ CORE_ADDR head;
+ CORE_ADDR tail;
+ }
+ldr_context_t;
+#endif /* !USE_LDR_ROUTINES */
+
+/* Per-section information, stored in struct lm_info.secs. */
+
+struct lm_sec
+ {
+ CORE_ADDR offset; /* difference between default and actual
+ virtual addresses of section .name */
+ CORE_ADDR nameaddr; /* address in inferior of section name */
+ const char *name; /* name of section, null if not fetched */
+ };
+
+/* Per-module information, stored in struct so_list.lm_info. */
+
+struct lm_info
+ {
+ int isloader; /* whether the module is /sbin/loader */
+ int nsecs; /* length of .secs */
+ struct lm_sec secs[1]; /* variable-length array of sections, sorted
+ by name */
+ };
+
+/* Context for iterating through the inferior's shared module list. */
+
+struct read_map_ctxt
+ {
+#ifdef USE_LDR_ROUTINES
+ ldr_process_t proc;
+ ldr_module_t next;
+#else
+ CORE_ADDR next; /* next element in module list */
+ CORE_ADDR tail; /* last element in module list */
+#endif
+ };
+
+/* Forward declaration for this module's autoinit function. */
+
+extern void _initialize_osf_solib (void);
+
+#ifdef USE_LDR_ROUTINES
+# if 0
+/* This routine is intended to be called by ldr_* routines to read memory from
+ the current target. Usage:
+
+ ldr_process = ldr_core_process ();
+ ldr_set_core_reader (ldr_read_memory);
+ ldr_xdetach (ldr_process);
+ ldr_xattach (ldr_process);
+
+ ldr_core_process() and ldr_read_memory() are neither documented nor
+ declared in system header files. They work with OSF/1 2.x, and they might
+ work with later versions as well. */
+
+static int
+ldr_read_memory (CORE_ADDR memaddr, char *myaddr, int len, int readstring)
+{
+ int result;
+ char *buffer;
+
+ if (readstring)
+ {
+ target_read_string (memaddr, &buffer, len, &result);
+ if (result == 0)
+ strcpy (myaddr, buffer);
+ xfree (buffer);
+ }
+ else
+ result = target_read_memory (memaddr, myaddr, len);
+
+ if (result != 0)
+ result = -result;
+ return result;
+}
+# endif /* 0 */
+#endif /* USE_LDR_ROUTINES */
+
+/* Comparison for qsort() and bsearch(): return -1, 0, or 1 according to
+ whether lm_sec *P1's name is lexically less than, equal to, or greater
+ than that of *P2. */
+
+static int
+lm_sec_cmp (const void *p1, const void *p2)
+{
+ const struct lm_sec *lms1 = p1, *lms2 = p2;
+ return strcmp (lms1->name, lms2->name);
+}
+
+/* Sort LMI->secs so that osf_relocate_section_addresses() can binary-search
+ it. */
+
+static void
+lm_secs_sort (struct lm_info *lmi)
+{
+ qsort (lmi->secs, lmi->nsecs, sizeof *lmi->secs, lm_sec_cmp);
+}
+
+/* Populate name fields of LMI->secs. */
+
+static void
+fetch_sec_names (struct lm_info *lmi)
+{
+#ifndef USE_LDR_ROUTINES
+ int i, errcode;
+ struct lm_sec *lms;
+ char *name;
+
+ for (i = 0; i < lmi->nsecs; i++)
+ {
+ lms = lmi->secs + i;
+ target_read_string (lms->nameaddr, &name, PATH_MAX, &errcode);
+ if (errcode != 0)
+ {
+ warning ("unable to read shared sec name at 0x%lx", lms->nameaddr);
+ name = xstrdup ("");
+ }
+ lms->name = name;
+ }
+ lm_secs_sort (lmi);
+#endif
+}
+
+/* target_so_ops callback. Adjust SEC's addresses after it's been mapped into
+ the process. */
+
+static void
+osf_relocate_section_addresses (struct so_list *so,
+ struct section_table *sec)
+{
+ struct lm_info *lmi;
+ struct lm_sec lms_key, *lms;
+
+ /* Fetch SO's section names if we haven't done so already. */
+ lmi = so->lm_info;
+ if (lmi->nsecs && !lmi->secs[0].name)
+ fetch_sec_names (lmi);
+
+ /* Binary-search for offset information corresponding to SEC. */
+ lms_key.name = sec->the_bfd_section->name;
+ lms = bsearch (&lms_key, lmi->secs, lmi->nsecs, sizeof *lms, lm_sec_cmp);
+ if (lms)
+ {
+ sec->addr += lms->offset;
+ sec->endaddr += lms->offset;
+ }
+}
+
+/* target_so_ops callback. Free parts of SO allocated by this file. */
+
+static void
+osf_free_so (struct so_list *so)
+{
+ int i;
+ const char *name;
+
+ for (i = 0; i < so->lm_info->nsecs; i++)
+ {
+ name = so->lm_info->secs[i].name;
+ if (name)
+ xfree ((void *) name);
+ }
+ xfree (so->lm_info);
+}
+
+/* target_so_ops callback. Discard information accumulated by this file and
+ not freed by osf_free_so(). */
+
+static void
+osf_clear_solib (void)
+{
+ return;
+}
+
+/* target_so_ops callback. Prepare to handle shared libraries after the
+ inferior process has been created but before it's executed any
+ instructions.
+
+ For a statically bound executable, the inferior's first instruction is the
+ one at "_start", or a similar text label. No further processing is needed
+ in that case.
+
+ For a dynamically bound executable, this first instruction is somewhere
+ in the rld, and the actual user executable is not yet mapped in.
+ We continue the inferior again, rld then maps in the actual user
+ executable and any needed shared libraries and then sends
+ itself a SIGTRAP.
+
+ At that point we discover the names of all shared libraries and
+ read their symbols in.
+
+ FIXME
+
+ This code does not properly handle hitting breakpoints which the
+ user might have set in the rld itself. Proper handling would have
+ to check if the SIGTRAP happened due to a kill call.
+
+ Also, what if child has exit()ed? Must exit loop somehow. */
+
+static void
+osf_solib_create_inferior_hook (void)
+{
+ /* Nothing to do for statically bound executables. */
+
+ if (symfile_objfile == NULL
+ || symfile_objfile->obfd == NULL
+ || ((bfd_get_file_flags (symfile_objfile->obfd) & DYNAMIC) == 0))
+ return;
+
+ /* Now run the target. It will eventually get a SIGTRAP, at
+ which point all of the libraries will have been mapped in and we
+ can go groveling around in the rld structures to find
+ out what we need to know about them. */
+
+ clear_proceed_status ();
+ stop_soon_quietly = 1;
+ stop_signal = TARGET_SIGNAL_0;
+ do
+ {
+ target_resume (minus_one_ptid, 0, stop_signal);
+ wait_for_inferior ();
+ }
+ while (stop_signal != TARGET_SIGNAL_TRAP);
+
+ /* solib_add will call reinit_frame_cache.
+ But we are stopped in the runtime loader and we do not have symbols
+ for the runtime loader. So heuristic_proc_start will be called
+ and will put out an annoying warning.
+ Delaying the resetting of stop_soon_quietly until after symbol loading
+ suppresses the warning. */
+ solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
+ stop_soon_quietly = 0;
+
+ /* Enable breakpoints disabled (unnecessarily) by clear_solib(). */
+ re_enable_breakpoints_in_shlibs ();
+}
+
+/* target_so_ops callback. Do additional symbol handling, lookup, etc. after
+ symbols for a shared object have been loaded. */
+
+static void
+osf_special_symbol_handling (void)
+{
+ return;
+}
+
+/* Initialize CTXT in preparation for iterating through the inferior's module
+ list using read_map(). Return success. */
+
+static int
+open_map (struct read_map_ctxt *ctxt)
+{
+#ifdef USE_LDR_ROUTINES
+ ctxt->proc = ldr_my_process ();
+ if (ldr_xattach (ctxt->proc) != 0)
+ return 0;
+ ctxt->next = LDR_NULL_MODULE;
+#else
+ CORE_ADDR ldr_context_addr, prev, next;
+ ldr_context_t ldr_context;
+
+ if (target_read_memory ((CORE_ADDR) RLD_CONTEXT_ADDRESS,
+ (char *) &ldr_context_addr,
+ sizeof (CORE_ADDR)) != 0)
+ return 0;
+ if (target_read_memory (ldr_context_addr,
+ (char *) &ldr_context,
+ sizeof (ldr_context_t)) != 0)
+ return 0;
+ ctxt->next = ldr_context.head;
+ ctxt->tail = ldr_context.tail;
+#endif
+ return 1;
+}
+
+/* Initialize SO to have module NAME, /sbin/loader indicator ISLOADR, and
+ space for NSECS sections. */
+
+static void
+init_so (struct so_list *so, char *name, int isloader, int nsecs)
+{
+ int namelen, i;
+
+ /* solib.c requires various fields to be initialized to 0. */
+ memset (so, 0, sizeof *so);
+
+ /* Copy the name. */
+ namelen = strlen (name);
+ if (namelen >= SO_NAME_MAX_PATH_SIZE)
+ namelen = SO_NAME_MAX_PATH_SIZE - 1;
+
+ memcpy (so->so_original_name, name, namelen);
+ so->so_original_name[namelen] = '\0';
+ memcpy (so->so_name, so->so_original_name, namelen + 1);
+
+ /* Allocate section space. */
+ so->lm_info = xmalloc ((unsigned) &(((struct lm_info *)0)->secs) +
+ nsecs * sizeof *so->lm_info);
+ so->lm_info->isloader = isloader;
+ so->lm_info->nsecs = nsecs;
+ for (i = 0; i < nsecs; i++)
+ so->lm_info->secs[i].name = NULL;
+}
+
+/* Initialize SO's section SECIDX with name address NAMEADDR, name string
+ NAME, default virtual address VADDR, and actual virtual address
+ MAPADDR. */
+
+static void
+init_sec (struct so_list *so, int secidx, CORE_ADDR nameaddr,
+ const char *name, CORE_ADDR vaddr, CORE_ADDR mapaddr)
+{
+ struct lm_sec *lms;
+
+ lms = so->lm_info->secs + secidx;
+ lms->nameaddr = nameaddr;
+ lms->name = name;
+ lms->offset = mapaddr - vaddr;
+}
+
+/* If there are more elements starting at CTXT in inferior's module list,
+ store the next element in SO, advance CTXT to the next element, and return
+ 1, else return 0. */
+
+static int
+read_map (struct read_map_ctxt *ctxt, struct so_list *so)
+{
+ ldr_module_info_t minf;
+ ldr_region_info_t rinf;
+
+#ifdef USE_LDR_ROUTINES
+ size_t size;
+ ldr_region_t i;
+
+ /* Retrieve the next element. */
+ if (ldr_next_module (ctxt->proc, &ctxt->next) != 0)
+ return 0;
+ if (ctxt->next == LDR_NULL_MODULE)
+ return 0;
+ if (ldr_inq_module (ctxt->proc, ctxt->next, &minf, sizeof minf, &size) != 0)
+ return 0;
+
+ /* Initialize the module name and section count. */
+ init_so (so, minf.lmi_name, 0, minf.lmi_nregion);
+
+ /* Retrieve section names and offsets. */
+ for (i = 0; i < minf.lmi_nregion; i++)
+ {
+ if (ldr_inq_region (ctxt->proc, ctxt->next, i, &rinf,
+ sizeof rinf, &size) != 0)
+ goto err;
+ init_sec (so, (int) i, 0, xstrdup (rinf.lri_name),
+ (CORE_ADDR) rinf.lri_vaddr, (CORE_ADDR) rinf.lri_mapaddr);
+ }
+ lm_secs_sort (so->lm_info);
+#else
+ char *name;
+ int errcode, i;
+
+ /* Retrieve the next element. */
+ if (!ctxt->next)
+ return 0;
+ if (target_read_memory (ctxt->next, (char *) &minf, sizeof minf) != 0)
+ return 0;
+ if (ctxt->next == ctxt->tail)
+ ctxt->next = 0;
+ else
+ ctxt->next = minf.next;
+
+ /* Initialize the module name and section count. */
+ target_read_string (minf.module_name, &name, PATH_MAX, &errcode);
+ if (errcode != 0)
+ return 0;
+ init_so (so, name, !minf.modinfo_addr, minf.region_count);
+ xfree (name);
+
+ /* Retrieve section names and offsets. */
+ for (i = 0; i < minf.region_count; i++)
+ {
+ if (target_read_memory (minf.regioninfo_addr + i * sizeof rinf,
+ (char *) &rinf, sizeof rinf) != 0)
+ goto err;
+ init_sec (so, i, rinf.regionname_addr, NULL, rinf.vaddr, rinf.mapaddr);
+ }
+#endif /* !USE_LDR_ROUTINES */
+ return 1;
+
+ err:
+ osf_free_so (so);
+ return 0;
+}
+
+/* Free resources allocated by open_map (CTXT). */
+
+static void
+close_map (struct read_map_ctxt *ctxt)
+{
+#ifdef USE_LDR_ROUTINES
+ ldr_xdetach (ctxt->proc);
+#endif
+}
+
+/* target_so_ops callback. Return a list of shared objects currently loaded
+ in the inferior. */
+
+static struct so_list *
+osf_current_sos (void)
+{
+ struct so_list *head = NULL, *tail, *newtail, so;
+ struct read_map_ctxt ctxt;
+ int skipped_main;
+
+ if (!open_map (&ctxt))
+ return NULL;
+
+ /* Read subsequent elements. */
+ for (skipped_main = 0;;)
+ {
+ if (!read_map (&ctxt, &so))
+ break;
+
+ /* Skip the main program module, which is first in the list after
+ /sbin/loader. */
+ if (!so.lm_info->isloader && !skipped_main)
+ {
+ osf_free_so (&so);
+ skipped_main = 1;
+ continue;
+ }
+
+ newtail = xmalloc (sizeof *newtail);
+ if (!head)
+ head = newtail;
+ else
+ tail->next = newtail;
+ tail = newtail;
+
+ memcpy (tail, &so, sizeof so);
+ tail->next = NULL;
+ }
+
+ done:
+ close_map (&ctxt);
+ return head;
+}
+
+/* target_so_ops callback. Attempt to locate and open the main symbol
+ file. */
+
+static int
+osf_open_symbol_file_object (void *from_ttyp)
+{
+ struct read_map_ctxt ctxt;
+ struct so_list so;
+ int found;
+
+ if (symfile_objfile)
+ if (!query ("Attempt to reload symbols from process? "))
+ return 0;
+
+ /* The first module after /sbin/loader is the main program. */
+ if (!open_map (&ctxt))
+ return 0;
+ for (found = 0; !found;)
+ {
+ if (!read_map (&ctxt, &so))
+ break;
+ found = !so.lm_info->isloader;
+ osf_free_so (&so);
+ }
+ close_map (&ctxt);
+
+ if (found)
+ symbol_file_add_main (so.so_name, *(int *) from_ttyp);
+ return found;
+}
+
+/* target_so_ops callback. Return whether PC is in the dynamic linker. */
+
+static int
+osf_in_dynsym_resolve_code (CORE_ADDR pc)
+{
+ /* This function currently always return False. This is a temporary
+ solution which only consequence is to introduce a minor incovenience
+ for the user: When stepping inside a subprogram located in a shared
+ library, gdb might stop inside the dynamic loader code instead of
+ inside the subprogram itself. See the explanations in infrun.c about
+ the IN_SOLIB_DYNSYM_RESOLVE_CODE macro for more details. */
+ return 0;
+}
+
+static struct target_so_ops osf_so_ops;
+
+void
+_initialize_osf_solib (void)
+{
+ osf_so_ops.relocate_section_addresses = osf_relocate_section_addresses;
+ osf_so_ops.free_so = osf_free_so;
+ osf_so_ops.clear_solib = osf_clear_solib;
+ osf_so_ops.solib_create_inferior_hook = osf_solib_create_inferior_hook;
+ osf_so_ops.special_symbol_handling = osf_special_symbol_handling;
+ osf_so_ops.current_sos = osf_current_sos;
+ osf_so_ops.open_symbol_file_object = osf_open_symbol_file_object;
+ osf_so_ops.in_dynsym_resolve_code = osf_in_dynsym_resolve_code;
+
+ /* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */
+ current_target_so_ops = &osf_so_ops;
+}
diff --git a/gdb/solib-sunos.c b/gdb/solib-sunos.c
new file mode 100644
index 00000000000..374ec253a01
--- /dev/null
+++ b/gdb/solib-sunos.c
@@ -0,0 +1,897 @@
+/* Handle SunOS shared libraries for GDB, the GNU Debugger.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
+ 2001
+ 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 "defs.h"
+
+#include <sys/types.h>
+#include <signal.h>
+#include "gdb_string.h"
+#include <sys/param.h>
+#include <fcntl.h>
+
+ /* SunOS shared libs need the nlist structure. */
+#include <a.out.h>
+#include <link.h>
+
+#include "symtab.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "solist.h"
+
+/* Link map info to include in an allocated so_list entry */
+
+struct lm_info
+ {
+ /* Pointer to copy of link map from inferior. The type is char *
+ rather than void *, so that we may use byte offsets to find the
+ various fields without the need for a cast. */
+ char *lm;
+ };
+
+
+/* Symbols which are used to locate the base of the link map structures. */
+
+static char *debug_base_symbols[] =
+{
+ "_DYNAMIC",
+ "_DYNAMIC__MGC",
+ NULL
+};
+
+static char *main_name_list[] =
+{
+ "main_$main",
+ NULL
+};
+
+/* Macro to extract an address from a solib structure.
+ When GDB is configured for some 32-bit targets (e.g. Solaris 2.7
+ sparc), BFD is configured to handle 64-bit targets, so CORE_ADDR is
+ 64 bits. We have to extract only the significant bits of addresses
+ to get the right address when accessing the core file BFD. */
+
+#define SOLIB_EXTRACT_ADDRESS(MEMBER) \
+ extract_address (&(MEMBER), sizeof (MEMBER))
+
+/* local data declarations */
+
+static struct link_dynamic dynamic_copy;
+static struct link_dynamic_2 ld_2_copy;
+static struct ld_debug debug_copy;
+static CORE_ADDR debug_addr;
+static CORE_ADDR flag_addr;
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+#endif
+#define fieldsize(TYPE, MEMBER) (sizeof (((TYPE *)0)->MEMBER))
+
+/* link map access functions */
+
+static CORE_ADDR
+LM_ADDR (struct so_list *so)
+{
+ int lm_addr_offset = offsetof (struct link_map, lm_addr);
+ int lm_addr_size = fieldsize (struct link_map, lm_addr);
+
+ return (CORE_ADDR) extract_signed_integer (so->lm_info->lm + lm_addr_offset,
+ lm_addr_size);
+}
+
+static CORE_ADDR
+LM_NEXT (struct so_list *so)
+{
+ int lm_next_offset = offsetof (struct link_map, lm_next);
+ int lm_next_size = fieldsize (struct link_map, lm_next);
+
+ return extract_address (so->lm_info->lm + lm_next_offset, lm_next_size);
+}
+
+static CORE_ADDR
+LM_NAME (struct so_list *so)
+{
+ int lm_name_offset = offsetof (struct link_map, lm_name);
+ int lm_name_size = fieldsize (struct link_map, lm_name);
+
+ return extract_address (so->lm_info->lm + lm_name_offset, lm_name_size);
+}
+
+static CORE_ADDR debug_base; /* Base of dynamic linker structures */
+
+/* Local function prototypes */
+
+static int match_main (char *);
+
+/* Allocate the runtime common object file. */
+
+static void
+allocate_rt_common_objfile (void)
+{
+ struct objfile *objfile;
+ struct objfile *last_one;
+
+ objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
+ memset (objfile, 0, sizeof (struct objfile));
+ objfile->md = NULL;
+ obstack_specify_allocation (&objfile->psymbol_cache.cache, 0, 0,
+ xmalloc, xfree);
+ obstack_specify_allocation (&objfile->macro_cache.cache, 0, 0,
+ xmalloc, xfree);
+ obstack_specify_allocation (&objfile->psymbol_obstack, 0, 0, xmalloc,
+ xfree);
+ obstack_specify_allocation (&objfile->symbol_obstack, 0, 0, xmalloc,
+ xfree);
+ obstack_specify_allocation (&objfile->type_obstack, 0, 0, xmalloc,
+ xfree);
+ objfile->name = mstrsave (objfile->md, "rt_common");
+
+ /* Add this file onto the tail of the linked list of other such files. */
+
+ objfile->next = NULL;
+ if (object_files == NULL)
+ object_files = objfile;
+ else
+ {
+ for (last_one = object_files;
+ last_one->next;
+ last_one = last_one->next);
+ last_one->next = objfile;
+ }
+
+ rt_common_objfile = objfile;
+}
+
+/* Read all dynamically loaded common symbol definitions from the inferior
+ and put them into the minimal symbol table for the runtime common
+ objfile. */
+
+static void
+solib_add_common_symbols (CORE_ADDR rtc_symp)
+{
+ struct rtc_symb inferior_rtc_symb;
+ struct nlist inferior_rtc_nlist;
+ int len;
+ char *name;
+
+ /* Remove any runtime common symbols from previous runs. */
+
+ if (rt_common_objfile != NULL && rt_common_objfile->minimal_symbol_count)
+ {
+ obstack_free (&rt_common_objfile->symbol_obstack, 0);
+ obstack_specify_allocation (&rt_common_objfile->symbol_obstack, 0, 0,
+ xmalloc, xfree);
+ rt_common_objfile->minimal_symbol_count = 0;
+ rt_common_objfile->msymbols = NULL;
+ }
+
+ init_minimal_symbol_collection ();
+ make_cleanup_discard_minimal_symbols ();
+
+ while (rtc_symp)
+ {
+ read_memory (rtc_symp,
+ (char *) &inferior_rtc_symb,
+ sizeof (inferior_rtc_symb));
+ read_memory (SOLIB_EXTRACT_ADDRESS (inferior_rtc_symb.rtc_sp),
+ (char *) &inferior_rtc_nlist,
+ sizeof (inferior_rtc_nlist));
+ if (inferior_rtc_nlist.n_type == N_COMM)
+ {
+ /* FIXME: The length of the symbol name is not available, but in the
+ current implementation the common symbol is allocated immediately
+ behind the name of the symbol. */
+ len = inferior_rtc_nlist.n_value - inferior_rtc_nlist.n_un.n_strx;
+
+ name = xmalloc (len);
+ read_memory (SOLIB_EXTRACT_ADDRESS (inferior_rtc_nlist.n_un.n_name),
+ name, len);
+
+ /* Allocate the runtime common objfile if necessary. */
+ if (rt_common_objfile == NULL)
+ allocate_rt_common_objfile ();
+
+ prim_record_minimal_symbol (name, inferior_rtc_nlist.n_value,
+ mst_bss, rt_common_objfile);
+ xfree (name);
+ }
+ rtc_symp = SOLIB_EXTRACT_ADDRESS (inferior_rtc_symb.rtc_next);
+ }
+
+ /* Install any minimal symbols that have been collected as the current
+ minimal symbols for the runtime common objfile. */
+
+ install_minimal_symbols (rt_common_objfile);
+}
+
+
+/*
+
+ LOCAL FUNCTION
+
+ locate_base -- locate the base address of dynamic linker structs
+
+ SYNOPSIS
+
+ CORE_ADDR locate_base (void)
+
+ DESCRIPTION
+
+ For both the SunOS and SVR4 shared library implementations, if the
+ inferior executable has been linked dynamically, there is a single
+ address somewhere in the inferior's data space which is the key to
+ locating all of the dynamic linker's runtime structures. This
+ address is the value of the debug base symbol. The job of this
+ function is to find and return that address, or to return 0 if there
+ is no such address (the executable is statically linked for example).
+
+ For SunOS, the job is almost trivial, since the dynamic linker and
+ all of it's structures are statically linked to the executable at
+ link time. Thus the symbol for the address we are looking for has
+ already been added to the minimal symbol table for the executable's
+ objfile at the time the symbol file's symbols were read, and all we
+ have to do is look it up there. Note that we explicitly do NOT want
+ to find the copies in the shared library.
+
+ The SVR4 version is a bit more complicated because the address
+ is contained somewhere in the dynamic info section. We have to go
+ to a lot more work to discover the address of the debug base symbol.
+ Because of this complexity, we cache the value we find and return that
+ value on subsequent invocations. Note there is no copy in the
+ executable symbol tables.
+
+ */
+
+static CORE_ADDR
+locate_base (void)
+{
+ struct minimal_symbol *msymbol;
+ CORE_ADDR address = 0;
+ char **symbolp;
+
+ /* For SunOS, we want to limit the search for the debug base symbol to the
+ executable being debugged, since there is a duplicate named symbol in the
+ shared library. We don't want the shared library versions. */
+
+ for (symbolp = debug_base_symbols; *symbolp != NULL; symbolp++)
+ {
+ msymbol = lookup_minimal_symbol (*symbolp, NULL, symfile_objfile);
+ if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
+ {
+ address = SYMBOL_VALUE_ADDRESS (msymbol);
+ return (address);
+ }
+ }
+ return (0);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ first_link_map_member -- locate first member in dynamic linker's map
+
+ SYNOPSIS
+
+ static CORE_ADDR first_link_map_member (void)
+
+ DESCRIPTION
+
+ Find the first element in the inferior's dynamic link map, and
+ return its address in the inferior. This function doesn't copy the
+ link map entry itself into our address space; current_sos actually
+ does the reading. */
+
+static CORE_ADDR
+first_link_map_member (void)
+{
+ CORE_ADDR lm = 0;
+
+ read_memory (debug_base, (char *) &dynamic_copy, sizeof (dynamic_copy));
+ if (dynamic_copy.ld_version >= 2)
+ {
+ /* It is a version that we can deal with, so read in the secondary
+ structure and find the address of the link map list from it. */
+ read_memory (SOLIB_EXTRACT_ADDRESS (dynamic_copy.ld_un.ld_2),
+ (char *) &ld_2_copy, sizeof (struct link_dynamic_2));
+ lm = SOLIB_EXTRACT_ADDRESS (ld_2_copy.ld_loaded);
+ }
+ return (lm);
+}
+
+static int
+open_symbol_file_object (void *from_ttyp)
+{
+ return 1;
+}
+
+
+/* LOCAL FUNCTION
+
+ current_sos -- build a list of currently loaded shared objects
+
+ SYNOPSIS
+
+ struct so_list *current_sos ()
+
+ DESCRIPTION
+
+ Build a list of `struct so_list' objects describing the shared
+ objects currently loaded in the inferior. This list does not
+ include an entry for the main executable file.
+
+ Note that we only gather information directly available from the
+ inferior --- we don't examine any of the shared library files
+ themselves. The declaration of `struct so_list' says which fields
+ we provide values for. */
+
+static struct so_list *
+sunos_current_sos (void)
+{
+ CORE_ADDR lm;
+ struct so_list *head = 0;
+ struct so_list **link_ptr = &head;
+ int errcode;
+ char *buffer;
+
+ /* Make sure we've looked up the inferior's dynamic linker's base
+ structure. */
+ if (! debug_base)
+ {
+ debug_base = locate_base ();
+
+ /* If we can't find the dynamic linker's base structure, this
+ must not be a dynamically linked executable. Hmm. */
+ if (! debug_base)
+ return 0;
+ }
+
+ /* Walk the inferior's link map list, and build our list of
+ `struct so_list' nodes. */
+ lm = first_link_map_member ();
+ while (lm)
+ {
+ struct so_list *new
+ = (struct so_list *) xmalloc (sizeof (struct so_list));
+ struct cleanup *old_chain = make_cleanup (xfree, new);
+
+ memset (new, 0, sizeof (*new));
+
+ new->lm_info = xmalloc (sizeof (struct lm_info));
+ make_cleanup (xfree, new->lm_info);
+
+ new->lm_info->lm = xmalloc (sizeof (struct link_map));
+ make_cleanup (xfree, new->lm_info->lm);
+ memset (new->lm_info->lm, 0, sizeof (struct link_map));
+
+ read_memory (lm, new->lm_info->lm, sizeof (struct link_map));
+
+ lm = LM_NEXT (new);
+
+ /* Extract this shared object's name. */
+ target_read_string (LM_NAME (new), &buffer,
+ SO_NAME_MAX_PATH_SIZE - 1, &errcode);
+ if (errcode != 0)
+ {
+ warning ("current_sos: Can't read pathname for load map: %s\n",
+ safe_strerror (errcode));
+ }
+ else
+ {
+ strncpy (new->so_name, buffer, SO_NAME_MAX_PATH_SIZE - 1);
+ new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
+ xfree (buffer);
+ strcpy (new->so_original_name, new->so_name);
+ }
+
+ /* If this entry has no name, or its name matches the name
+ for the main executable, don't include it in the list. */
+ if (! new->so_name[0]
+ || match_main (new->so_name))
+ free_so (new);
+ else
+ {
+ new->next = 0;
+ *link_ptr = new;
+ link_ptr = &new->next;
+ }
+
+ discard_cleanups (old_chain);
+ }
+
+ return head;
+}
+
+
+/* On some systems, the only way to recognize the link map entry for
+ the main executable file is by looking at its name. Return
+ non-zero iff SONAME matches one of the known main executable names. */
+
+static int
+match_main (char *soname)
+{
+ char **mainp;
+
+ for (mainp = main_name_list; *mainp != NULL; mainp++)
+ {
+ if (strcmp (soname, *mainp) == 0)
+ return (1);
+ }
+
+ return (0);
+}
+
+
+static int
+sunos_in_dynsym_resolve_code (CORE_ADDR pc)
+{
+ return 0;
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ disable_break -- remove the "mapping changed" breakpoint
+
+ SYNOPSIS
+
+ static int disable_break ()
+
+ DESCRIPTION
+
+ Removes the breakpoint that gets hit when the dynamic linker
+ completes a mapping change.
+
+ */
+
+static int
+disable_break (void)
+{
+ CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */
+
+ int in_debugger = 0;
+
+ /* Read the debugger structure from the inferior to retrieve the
+ address of the breakpoint and the original contents of the
+ breakpoint address. Remove the breakpoint by writing the original
+ contents back. */
+
+ read_memory (debug_addr, (char *) &debug_copy, sizeof (debug_copy));
+
+ /* Set `in_debugger' to zero now. */
+
+ write_memory (flag_addr, (char *) &in_debugger, sizeof (in_debugger));
+
+ breakpoint_addr = SOLIB_EXTRACT_ADDRESS (debug_copy.ldd_bp_addr);
+ write_memory (breakpoint_addr, (char *) &debug_copy.ldd_bp_inst,
+ sizeof (debug_copy.ldd_bp_inst));
+
+ /* For the SVR4 version, we always know the breakpoint address. For the
+ SunOS version we don't know it until the above code is executed.
+ Grumble if we are stopped anywhere besides the breakpoint address. */
+
+ if (stop_pc != breakpoint_addr)
+ {
+ warning ("stopped at unknown breakpoint while handling shared libraries");
+ }
+
+ return 1;
+}
+
+
+/*
+
+ LOCAL FUNCTION
+
+ enable_break -- arrange for dynamic linker to hit breakpoint
+
+ SYNOPSIS
+
+ int enable_break (void)
+
+ DESCRIPTION
+
+ Both the SunOS and the SVR4 dynamic linkers have, as part of their
+ debugger interface, support for arranging for the inferior to hit
+ a breakpoint after mapping in the shared libraries. This function
+ enables that breakpoint.
+
+ For SunOS, there is a special flag location (in_debugger) which we
+ set to 1. When the dynamic linker sees this flag set, it will set
+ a breakpoint at a location known only to itself, after saving the
+ original contents of that place and the breakpoint address itself,
+ in it's own internal structures. When we resume the inferior, it
+ will eventually take a SIGTRAP when it runs into the breakpoint.
+ We handle this (in a different place) by restoring the contents of
+ the breakpointed location (which is only known after it stops),
+ chasing around to locate the shared libraries that have been
+ loaded, then resuming.
+
+ For SVR4, the debugger interface structure contains a member (r_brk)
+ which is statically initialized at the time the shared library is
+ built, to the offset of a function (_r_debug_state) which is guaran-
+ teed to be called once before mapping in a library, and again when
+ the mapping is complete. At the time we are examining this member,
+ it contains only the unrelocated offset of the function, so we have
+ to do our own relocation. Later, when the dynamic linker actually
+ runs, it relocates r_brk to be the actual address of _r_debug_state().
+
+ The debugger interface structure also contains an enumeration which
+ is set to either RT_ADD or RT_DELETE prior to changing the mapping,
+ depending upon whether or not the library is being mapped or unmapped,
+ and then set to RT_CONSISTENT after the library is mapped/unmapped.
+ */
+
+static int
+enable_break (void)
+{
+ int success = 0;
+ int j;
+ int in_debugger;
+
+ /* Get link_dynamic structure */
+
+ j = target_read_memory (debug_base, (char *) &dynamic_copy,
+ sizeof (dynamic_copy));
+ if (j)
+ {
+ /* unreadable */
+ return (0);
+ }
+
+ /* Calc address of debugger interface structure */
+
+ debug_addr = SOLIB_EXTRACT_ADDRESS (dynamic_copy.ldd);
+
+ /* Calc address of `in_debugger' member of debugger interface structure */
+
+ flag_addr = debug_addr + (CORE_ADDR) ((char *) &debug_copy.ldd_in_debugger -
+ (char *) &debug_copy);
+
+ /* Write a value of 1 to this member. */
+
+ in_debugger = 1;
+ write_memory (flag_addr, (char *) &in_debugger, sizeof (in_debugger));
+ success = 1;
+
+ return (success);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ special_symbol_handling -- additional shared library symbol handling
+
+ SYNOPSIS
+
+ void special_symbol_handling ()
+
+ DESCRIPTION
+
+ Once the symbols from a shared object have been loaded in the usual
+ way, we are called to do any system specific symbol handling that
+ is needed.
+
+ For SunOS4, this consists of grunging around in the dynamic
+ linkers structures to find symbol definitions for "common" symbols
+ and adding them to the minimal symbol table for the runtime common
+ objfile.
+
+ */
+
+static void
+sunos_special_symbol_handling (void)
+{
+ int j;
+
+ if (debug_addr == 0)
+ {
+ /* Get link_dynamic structure */
+
+ j = target_read_memory (debug_base, (char *) &dynamic_copy,
+ sizeof (dynamic_copy));
+ if (j)
+ {
+ /* unreadable */
+ return;
+ }
+
+ /* Calc address of debugger interface structure */
+ /* FIXME, this needs work for cross-debugging of core files
+ (byteorder, size, alignment, etc). */
+
+ debug_addr = SOLIB_EXTRACT_ADDRESS (dynamic_copy.ldd);
+ }
+
+ /* Read the debugger structure from the inferior, just to make sure
+ we have a current copy. */
+
+ j = target_read_memory (debug_addr, (char *) &debug_copy,
+ sizeof (debug_copy));
+ if (j)
+ return; /* unreadable */
+
+ /* Get common symbol definitions for the loaded object. */
+
+ if (debug_copy.ldd_cp)
+ {
+ solib_add_common_symbols (SOLIB_EXTRACT_ADDRESS (debug_copy.ldd_cp));
+ }
+}
+
+/* Relocate the main executable. This function should be called upon
+ stopping the inferior process at the entry point to the program.
+ The entry point from BFD is compared to the PC and if they are
+ different, the main executable is relocated by the proper amount.
+
+ As written it will only attempt to relocate executables which
+ lack interpreter sections. It seems likely that only dynamic
+ linker executables will get relocated, though it should work
+ properly for a position-independent static executable as well. */
+
+static void
+sunos_relocate_main_executable (void)
+{
+ asection *interp_sect;
+ CORE_ADDR pc = read_pc ();
+
+ /* Decide if the objfile needs to be relocated. As indicated above,
+ we will only be here when execution is stopped at the beginning
+ of the program. Relocation is necessary if the address at which
+ we are presently stopped differs from the start address stored in
+ the executable AND there's no interpreter section. The condition
+ regarding the interpreter section is very important because if
+ there *is* an interpreter section, execution will begin there
+ instead. When there is an interpreter section, the start address
+ is (presumably) used by the interpreter at some point to start
+ execution of the program.
+
+ If there is an interpreter, it is normal for it to be set to an
+ arbitrary address at the outset. The job of finding it is
+ handled in enable_break().
+
+ So, to summarize, relocations are necessary when there is no
+ interpreter section and the start address obtained from the
+ executable is different from the address at which GDB is
+ currently stopped.
+
+ [ The astute reader will note that we also test to make sure that
+ the executable in question has the DYNAMIC flag set. It is my
+ opinion that this test is unnecessary (undesirable even). It
+ was added to avoid inadvertent relocation of an executable
+ whose e_type member in the ELF header is not ET_DYN. There may
+ be a time in the future when it is desirable to do relocations
+ on other types of files as well in which case this condition
+ should either be removed or modified to accomodate the new file
+ type. (E.g, an ET_EXEC executable which has been built to be
+ position-independent could safely be relocated by the OS if
+ desired. It is true that this violates the ABI, but the ABI
+ has been known to be bent from time to time.) - Kevin, Nov 2000. ]
+ */
+
+ interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
+ if (interp_sect == NULL
+ && (bfd_get_file_flags (exec_bfd) & DYNAMIC) != 0
+ && bfd_get_start_address (exec_bfd) != pc)
+ {
+ struct cleanup *old_chain;
+ struct section_offsets *new_offsets;
+ int i, changed;
+ CORE_ADDR displacement;
+
+ /* It is necessary to relocate the objfile. The amount to
+ relocate by is simply the address at which we are stopped
+ minus the starting address from the executable.
+
+ We relocate all of the sections by the same amount. This
+ behavior is mandated by recent editions of the System V ABI.
+ According to the System V Application Binary Interface,
+ Edition 4.1, page 5-5:
+
+ ... Though the system chooses virtual addresses for
+ individual processes, it maintains the segments' relative
+ positions. Because position-independent code uses relative
+ addressesing between segments, the difference between
+ virtual addresses in memory must match the difference
+ between virtual addresses in the file. The difference
+ between the virtual address of any segment in memory and
+ the corresponding virtual address in the file is thus a
+ single constant value for any one executable or shared
+ object in a given process. This difference is the base
+ address. One use of the base address is to relocate the
+ memory image of the program during dynamic linking.
+
+ The same language also appears in Edition 4.0 of the System V
+ ABI and is left unspecified in some of the earlier editions. */
+
+ displacement = pc - bfd_get_start_address (exec_bfd);
+ changed = 0;
+
+ new_offsets = xcalloc (symfile_objfile->num_sections,
+ sizeof (struct section_offsets));
+ old_chain = make_cleanup (xfree, new_offsets);
+
+ for (i = 0; i < symfile_objfile->num_sections; i++)
+ {
+ if (displacement != ANOFFSET (symfile_objfile->section_offsets, i))
+ changed = 1;
+ new_offsets->offsets[i] = displacement;
+ }
+
+ if (changed)
+ objfile_relocate (symfile_objfile, new_offsets);
+
+ do_cleanups (old_chain);
+ }
+}
+
+/*
+
+ GLOBAL FUNCTION
+
+ sunos_solib_create_inferior_hook -- shared library startup support
+
+ SYNOPSIS
+
+ void sunos_solib_create_inferior_hook()
+
+ DESCRIPTION
+
+ When gdb starts up the inferior, it nurses it along (through the
+ shell) until it is ready to execute it's first instruction. At this
+ point, this function gets called via expansion of the macro
+ SOLIB_CREATE_INFERIOR_HOOK.
+
+ For SunOS executables, this first instruction is typically the
+ one at "_start", or a similar text label, regardless of whether
+ the executable is statically or dynamically linked. The runtime
+ startup code takes care of dynamically linking in any shared
+ libraries, once gdb allows the inferior to continue.
+
+ For SVR4 executables, this first instruction is either the first
+ instruction in the dynamic linker (for dynamically linked
+ executables) or the instruction at "start" for statically linked
+ executables. For dynamically linked executables, the system
+ first exec's /lib/libc.so.N, which contains the dynamic linker,
+ and starts it running. The dynamic linker maps in any needed
+ shared libraries, maps in the actual user executable, and then
+ jumps to "start" in the user executable.
+
+ For both SunOS shared libraries, and SVR4 shared libraries, we
+ can arrange to cooperate with the dynamic linker to discover the
+ names of shared libraries that are dynamically linked, and the
+ base addresses to which they are linked.
+
+ This function is responsible for discovering those names and
+ addresses, and saving sufficient information about them to allow
+ their symbols to be read at a later time.
+
+ FIXME
+
+ Between enable_break() and disable_break(), this code does not
+ properly handle hitting breakpoints which the user might have
+ set in the startup code or in the dynamic linker itself. Proper
+ handling will probably have to wait until the implementation is
+ changed to use the "breakpoint handler function" method.
+
+ Also, what if child has exit()ed? Must exit loop somehow.
+ */
+
+static void
+sunos_solib_create_inferior_hook (void)
+{
+ /* Relocate the main executable if necessary. */
+ sunos_relocate_main_executable ();
+
+ if ((debug_base = locate_base ()) == 0)
+ {
+ /* Can't find the symbol or the executable is statically linked. */
+ return;
+ }
+
+ if (!enable_break ())
+ {
+ warning ("shared library handler failed to enable breakpoint");
+ return;
+ }
+
+ /* SCO and SunOS need the loop below, other systems should be using the
+ special shared library breakpoints and the shared library breakpoint
+ service routine.
+
+ Now run the target. It will eventually hit the breakpoint, at
+ which point all of the libraries will have been mapped in and we
+ can go groveling around in the dynamic linker structures to find
+ out what we need to know about them. */
+
+ clear_proceed_status ();
+ stop_soon_quietly = 1;
+ stop_signal = TARGET_SIGNAL_0;
+ do
+ {
+ target_resume (pid_to_ptid (-1), 0, stop_signal);
+ wait_for_inferior ();
+ }
+ while (stop_signal != TARGET_SIGNAL_TRAP);
+ stop_soon_quietly = 0;
+
+ /* We are now either at the "mapping complete" breakpoint (or somewhere
+ else, a condition we aren't prepared to deal with anyway), so adjust
+ the PC as necessary after a breakpoint, disable the breakpoint, and
+ add any shared libraries that were mapped in. */
+
+ if (DECR_PC_AFTER_BREAK)
+ {
+ stop_pc -= DECR_PC_AFTER_BREAK;
+ write_register (PC_REGNUM, stop_pc);
+ }
+
+ if (!disable_break ())
+ {
+ warning ("shared library handler failed to disable breakpoint");
+ }
+
+ solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
+}
+
+static void
+sunos_clear_solib (void)
+{
+ debug_base = 0;
+}
+
+static void
+sunos_free_so (struct so_list *so)
+{
+ xfree (so->lm_info->lm);
+ xfree (so->lm_info);
+}
+
+static void
+sunos_relocate_section_addresses (struct so_list *so,
+ struct section_table *sec)
+{
+ sec->addr += LM_ADDR (so);
+ sec->endaddr += LM_ADDR (so);
+}
+
+static struct target_so_ops sunos_so_ops;
+
+void
+_initialize_sunos_solib (void)
+{
+ sunos_so_ops.relocate_section_addresses = sunos_relocate_section_addresses;
+ sunos_so_ops.free_so = sunos_free_so;
+ sunos_so_ops.clear_solib = sunos_clear_solib;
+ sunos_so_ops.solib_create_inferior_hook = sunos_solib_create_inferior_hook;
+ sunos_so_ops.special_symbol_handling = sunos_special_symbol_handling;
+ sunos_so_ops.current_sos = sunos_current_sos;
+ sunos_so_ops.open_symbol_file_object = open_symbol_file_object;
+ sunos_so_ops.in_dynsym_resolve_code = sunos_in_dynsym_resolve_code;
+
+ /* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */
+ current_target_so_ops = &sunos_so_ops;
+}
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
new file mode 100644
index 00000000000..2d71097c091
--- /dev/null
+++ b/gdb/solib-svr4.c
@@ -0,0 +1,1360 @@
+/* Handle SVR4 shared libraries for GDB, the GNU Debugger.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
+ 2001
+ 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 "defs.h"
+
+#include "elf/external.h"
+#include "elf/common.h"
+#include "elf/mips.h"
+
+#include "symtab.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "inferior.h"
+
+#include "solist.h"
+#include "solib-svr4.h"
+
+#ifndef SVR4_FETCH_LINK_MAP_OFFSETS
+#define SVR4_FETCH_LINK_MAP_OFFSETS() svr4_fetch_link_map_offsets ()
+#endif
+
+static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
+static struct link_map_offsets *legacy_fetch_link_map_offsets (void);
+
+/* fetch_link_map_offsets_gdbarch_data is a handle used to obtain the
+ architecture specific link map offsets fetching function. */
+
+static struct gdbarch_data *fetch_link_map_offsets_gdbarch_data;
+
+/* legacy_svr4_fetch_link_map_offsets_hook is a pointer to a function
+ which is used to fetch link map offsets. It will only be set
+ by solib-legacy.c, if at all. */
+
+struct link_map_offsets *(*legacy_svr4_fetch_link_map_offsets_hook)(void) = 0;
+
+/* Link map info to include in an allocated so_list entry */
+
+struct lm_info
+ {
+ /* Pointer to copy of link map from inferior. The type is char *
+ rather than void *, so that we may use byte offsets to find the
+ various fields without the need for a cast. */
+ char *lm;
+ };
+
+/* On SVR4 systems, a list of symbols in the dynamic linker where
+ GDB can try to place a breakpoint to monitor shared library
+ events.
+
+ If none of these symbols are found, or other errors occur, then
+ SVR4 systems will fall back to using a symbol as the "startup
+ mapping complete" breakpoint address. */
+
+static char *solib_break_names[] =
+{
+ "r_debug_state",
+ "_r_debug_state",
+ "_dl_debug_state",
+ "rtld_db_dlactivity",
+ "_rtld_debug_state",
+ NULL
+};
+
+#define BKPT_AT_SYMBOL 1
+
+#if defined (BKPT_AT_SYMBOL)
+static char *bkpt_names[] =
+{
+#ifdef SOLIB_BKPT_NAME
+ SOLIB_BKPT_NAME, /* Prefer configured name if it exists. */
+#endif
+ "_start",
+ "__start",
+ "main",
+ NULL
+};
+#endif
+
+static char *main_name_list[] =
+{
+ "main_$main",
+ NULL
+};
+
+/* Macro to extract an address from a solib structure.
+ When GDB is configured for some 32-bit targets (e.g. Solaris 2.7
+ sparc), BFD is configured to handle 64-bit targets, so CORE_ADDR is
+ 64 bits. We have to extract only the significant bits of addresses
+ to get the right address when accessing the core file BFD. */
+
+#define SOLIB_EXTRACT_ADDRESS(MEMBER) \
+ extract_address (&(MEMBER), sizeof (MEMBER))
+
+/* local data declarations */
+
+/* link map access functions */
+
+static CORE_ADDR
+LM_ADDR (struct so_list *so)
+{
+ struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS ();
+
+ return (CORE_ADDR) extract_signed_integer (so->lm_info->lm + lmo->l_addr_offset,
+ lmo->l_addr_size);
+}
+
+static CORE_ADDR
+LM_NEXT (struct so_list *so)
+{
+ struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS ();
+
+ return extract_address (so->lm_info->lm + lmo->l_next_offset, lmo->l_next_size);
+}
+
+static CORE_ADDR
+LM_NAME (struct so_list *so)
+{
+ struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS ();
+
+ return extract_address (so->lm_info->lm + lmo->l_name_offset, lmo->l_name_size);
+}
+
+static int
+IGNORE_FIRST_LINK_MAP_ENTRY (struct so_list *so)
+{
+ struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS ();
+
+ return extract_address (so->lm_info->lm + lmo->l_prev_offset,
+ lmo->l_prev_size) == 0;
+}
+
+static CORE_ADDR debug_base; /* Base of dynamic linker structures */
+static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */
+
+/* Local function prototypes */
+
+static int match_main (char *);
+
+static CORE_ADDR bfd_lookup_symbol (bfd *, char *);
+
+/*
+
+ LOCAL FUNCTION
+
+ bfd_lookup_symbol -- lookup the value for a specific symbol
+
+ SYNOPSIS
+
+ CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname)
+
+ DESCRIPTION
+
+ An expensive way to lookup the value of a single symbol for
+ bfd's that are only temporary anyway. This is used by the
+ shared library support to find the address of the debugger
+ interface structures in the shared library.
+
+ Note that 0 is specifically allowed as an error return (no
+ such symbol).
+ */
+
+static CORE_ADDR
+bfd_lookup_symbol (bfd *abfd, char *symname)
+{
+ long storage_needed;
+ asymbol *sym;
+ asymbol **symbol_table;
+ unsigned int number_of_symbols;
+ unsigned int i;
+ struct cleanup *back_to;
+ CORE_ADDR symaddr = 0;
+
+ storage_needed = bfd_get_symtab_upper_bound (abfd);
+
+ if (storage_needed > 0)
+ {
+ symbol_table = (asymbol **) xmalloc (storage_needed);
+ back_to = make_cleanup (xfree, (PTR) symbol_table);
+ number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
+
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ sym = *symbol_table++;
+ if (STREQ (sym->name, symname))
+ {
+ /* Bfd symbols are section relative. */
+ symaddr = sym->value + sym->section->vma;
+ break;
+ }
+ }
+ do_cleanups (back_to);
+ }
+
+ if (symaddr)
+ return symaddr;
+
+ /* On FreeBSD, the dynamic linker is stripped by default. So we'll
+ have to check the dynamic string table too. */
+
+ storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);
+
+ if (storage_needed > 0)
+ {
+ symbol_table = (asymbol **) xmalloc (storage_needed);
+ back_to = make_cleanup (xfree, (PTR) symbol_table);
+ number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table);
+
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ sym = *symbol_table++;
+ if (STREQ (sym->name, symname))
+ {
+ /* Bfd symbols are section relative. */
+ symaddr = sym->value + sym->section->vma;
+ break;
+ }
+ }
+ do_cleanups (back_to);
+ }
+
+ return symaddr;
+}
+
+#ifdef HANDLE_SVR4_EXEC_EMULATORS
+
+/*
+ Solaris BCP (the part of Solaris which allows it to run SunOS4
+ a.out files) throws in another wrinkle. Solaris does not fill
+ in the usual a.out link map structures when running BCP programs,
+ the only way to get at them is via groping around in the dynamic
+ linker.
+ The dynamic linker and it's structures are located in the shared
+ C library, which gets run as the executable's "interpreter" by
+ the kernel.
+
+ Note that we can assume nothing about the process state at the time
+ we need to find these structures. We may be stopped on the first
+ instruction of the interpreter (C shared library), the first
+ instruction of the executable itself, or somewhere else entirely
+ (if we attached to the process for example).
+ */
+
+static char *debug_base_symbols[] =
+{
+ "r_debug", /* Solaris 2.3 */
+ "_r_debug", /* Solaris 2.1, 2.2 */
+ NULL
+};
+
+static int look_for_base (int, CORE_ADDR);
+
+/*
+
+ LOCAL FUNCTION
+
+ look_for_base -- examine file for each mapped address segment
+
+ SYNOPSYS
+
+ static int look_for_base (int fd, CORE_ADDR baseaddr)
+
+ DESCRIPTION
+
+ This function is passed to proc_iterate_over_mappings, which
+ causes it to get called once for each mapped address space, with
+ an open file descriptor for the file mapped to that space, and the
+ base address of that mapped space.
+
+ Our job is to find the debug base symbol in the file that this
+ fd is open on, if it exists, and if so, initialize the dynamic
+ linker structure base address debug_base.
+
+ Note that this is a computationally expensive proposition, since
+ we basically have to open a bfd on every call, so we specifically
+ avoid opening the exec file.
+ */
+
+static int
+look_for_base (int fd, CORE_ADDR baseaddr)
+{
+ bfd *interp_bfd;
+ CORE_ADDR address = 0;
+ char **symbolp;
+
+ /* If the fd is -1, then there is no file that corresponds to this
+ mapped memory segment, so skip it. Also, if the fd corresponds
+ to the exec file, skip it as well. */
+
+ if (fd == -1
+ || (exec_bfd != NULL
+ && fdmatch (fileno ((FILE *) (exec_bfd->iostream)), fd)))
+ {
+ return (0);
+ }
+
+ /* Try to open whatever random file this fd corresponds to. Note that
+ we have no way currently to find the filename. Don't gripe about
+ any problems we might have, just fail. */
+
+ if ((interp_bfd = bfd_fdopenr ("unnamed", gnutarget, fd)) == NULL)
+ {
+ return (0);
+ }
+ if (!bfd_check_format (interp_bfd, bfd_object))
+ {
+ /* FIXME-leak: on failure, might not free all memory associated with
+ interp_bfd. */
+ bfd_close (interp_bfd);
+ return (0);
+ }
+
+ /* Now try to find our debug base symbol in this file, which we at
+ least know to be a valid ELF executable or shared library. */
+
+ for (symbolp = debug_base_symbols; *symbolp != NULL; symbolp++)
+ {
+ address = bfd_lookup_symbol (interp_bfd, *symbolp);
+ if (address != 0)
+ {
+ break;
+ }
+ }
+ if (address == 0)
+ {
+ /* FIXME-leak: on failure, might not free all memory associated with
+ interp_bfd. */
+ bfd_close (interp_bfd);
+ return (0);
+ }
+
+ /* Eureka! We found the symbol. But now we may need to relocate it
+ by the base address. If the symbol's value is less than the base
+ address of the shared library, then it hasn't yet been relocated
+ by the dynamic linker, and we have to do it ourself. FIXME: Note
+ that we make the assumption that the first segment that corresponds
+ to the shared library has the base address to which the library
+ was relocated. */
+
+ if (address < baseaddr)
+ {
+ address += baseaddr;
+ }
+ debug_base = address;
+ /* FIXME-leak: on failure, might not free all memory associated with
+ interp_bfd. */
+ bfd_close (interp_bfd);
+ return (1);
+}
+#endif /* HANDLE_SVR4_EXEC_EMULATORS */
+
+/*
+
+ LOCAL FUNCTION
+
+ elf_locate_base -- locate the base address of dynamic linker structs
+ for SVR4 elf targets.
+
+ SYNOPSIS
+
+ CORE_ADDR elf_locate_base (void)
+
+ DESCRIPTION
+
+ For SVR4 elf targets the address of the dynamic linker's runtime
+ structure is contained within the dynamic info section in the
+ executable file. The dynamic section is also mapped into the
+ inferior address space. Because the runtime loader fills in the
+ real address before starting the inferior, we have to read in the
+ dynamic info section from the inferior address space.
+ If there are any errors while trying to find the address, we
+ silently return 0, otherwise the found address is returned.
+
+ */
+
+static CORE_ADDR
+elf_locate_base (void)
+{
+ sec_ptr dyninfo_sect;
+ int dyninfo_sect_size;
+ CORE_ADDR dyninfo_addr;
+ char *buf;
+ char *bufend;
+ int arch_size;
+
+ /* Find the start address of the .dynamic section. */
+ dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic");
+ if (dyninfo_sect == NULL)
+ return 0;
+ dyninfo_addr = bfd_section_vma (exec_bfd, dyninfo_sect);
+
+ /* Read in .dynamic section, silently ignore errors. */
+ dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect);
+ buf = alloca (dyninfo_sect_size);
+ if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size))
+ return 0;
+
+ /* Find the DT_DEBUG entry in the the .dynamic section.
+ For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has
+ no DT_DEBUG entries. */
+
+ arch_size = bfd_get_arch_size (exec_bfd);
+ if (arch_size == -1) /* failure */
+ return 0;
+
+ if (arch_size == 32)
+ { /* 32-bit elf */
+ for (bufend = buf + dyninfo_sect_size;
+ buf < bufend;
+ buf += sizeof (Elf32_External_Dyn))
+ {
+ Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf;
+ long dyn_tag;
+ CORE_ADDR dyn_ptr;
+
+ dyn_tag = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
+ if (dyn_tag == DT_NULL)
+ break;
+ else if (dyn_tag == DT_DEBUG)
+ {
+ dyn_ptr = bfd_h_get_32 (exec_bfd,
+ (bfd_byte *) x_dynp->d_un.d_ptr);
+ return dyn_ptr;
+ }
+ else if (dyn_tag == DT_MIPS_RLD_MAP)
+ {
+ char *pbuf;
+
+ pbuf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT);
+ /* DT_MIPS_RLD_MAP contains a pointer to the address
+ of the dynamic link structure. */
+ dyn_ptr = bfd_h_get_32 (exec_bfd,
+ (bfd_byte *) x_dynp->d_un.d_ptr);
+ if (target_read_memory (dyn_ptr, pbuf, sizeof (pbuf)))
+ return 0;
+ return extract_unsigned_integer (pbuf, sizeof (pbuf));
+ }
+ }
+ }
+ else /* 64-bit elf */
+ {
+ for (bufend = buf + dyninfo_sect_size;
+ buf < bufend;
+ buf += sizeof (Elf64_External_Dyn))
+ {
+ Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf;
+ long dyn_tag;
+ CORE_ADDR dyn_ptr;
+
+ dyn_tag = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
+ if (dyn_tag == DT_NULL)
+ break;
+ else if (dyn_tag == DT_DEBUG)
+ {
+ dyn_ptr = bfd_h_get_64 (exec_bfd,
+ (bfd_byte *) x_dynp->d_un.d_ptr);
+ return dyn_ptr;
+ }
+ }
+ }
+
+ /* DT_DEBUG entry not found. */
+ return 0;
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ locate_base -- locate the base address of dynamic linker structs
+
+ SYNOPSIS
+
+ CORE_ADDR locate_base (void)
+
+ DESCRIPTION
+
+ For both the SunOS and SVR4 shared library implementations, if the
+ inferior executable has been linked dynamically, there is a single
+ address somewhere in the inferior's data space which is the key to
+ locating all of the dynamic linker's runtime structures. This
+ address is the value of the debug base symbol. The job of this
+ function is to find and return that address, or to return 0 if there
+ is no such address (the executable is statically linked for example).
+
+ For SunOS, the job is almost trivial, since the dynamic linker and
+ all of it's structures are statically linked to the executable at
+ link time. Thus the symbol for the address we are looking for has
+ already been added to the minimal symbol table for the executable's
+ objfile at the time the symbol file's symbols were read, and all we
+ have to do is look it up there. Note that we explicitly do NOT want
+ to find the copies in the shared library.
+
+ The SVR4 version is a bit more complicated because the address
+ is contained somewhere in the dynamic info section. We have to go
+ to a lot more work to discover the address of the debug base symbol.
+ Because of this complexity, we cache the value we find and return that
+ value on subsequent invocations. Note there is no copy in the
+ executable symbol tables.
+
+ */
+
+static CORE_ADDR
+locate_base (void)
+{
+ /* Check to see if we have a currently valid address, and if so, avoid
+ doing all this work again and just return the cached address. If
+ we have no cached address, try to locate it in the dynamic info
+ section for ELF executables. */
+
+ if (debug_base == 0)
+ {
+ if (exec_bfd != NULL
+ && bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour)
+ debug_base = elf_locate_base ();
+#ifdef HANDLE_SVR4_EXEC_EMULATORS
+ /* Try it the hard way for emulated executables. */
+ else if (!ptid_equal (inferior_ptid, null_ptid) && target_has_execution)
+ proc_iterate_over_mappings (look_for_base);
+#endif
+ }
+ return (debug_base);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ first_link_map_member -- locate first member in dynamic linker's map
+
+ SYNOPSIS
+
+ static CORE_ADDR first_link_map_member (void)
+
+ DESCRIPTION
+
+ Find the first element in the inferior's dynamic link map, and
+ return its address in the inferior. This function doesn't copy the
+ link map entry itself into our address space; current_sos actually
+ does the reading. */
+
+static CORE_ADDR
+first_link_map_member (void)
+{
+ CORE_ADDR lm = 0;
+ struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS ();
+ char *r_map_buf = xmalloc (lmo->r_map_size);
+ struct cleanup *cleanups = make_cleanup (xfree, r_map_buf);
+
+ read_memory (debug_base + lmo->r_map_offset, r_map_buf, lmo->r_map_size);
+
+ lm = extract_address (r_map_buf, lmo->r_map_size);
+
+ /* FIXME: Perhaps we should validate the info somehow, perhaps by
+ checking r_version for a known version number, or r_state for
+ RT_CONSISTENT. */
+
+ do_cleanups (cleanups);
+
+ return (lm);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ open_symbol_file_object
+
+ SYNOPSIS
+
+ void open_symbol_file_object (void *from_tty)
+
+ DESCRIPTION
+
+ If no open symbol file, attempt to locate and open the main symbol
+ file. On SVR4 systems, this is the first link map entry. If its
+ name is here, we can open it. Useful when attaching to a process
+ without first loading its symbol file.
+
+ If FROM_TTYP dereferences to a non-zero integer, allow messages to
+ be printed. This parameter is a pointer rather than an int because
+ open_symbol_file_object() is called via catch_errors() and
+ catch_errors() requires a pointer argument. */
+
+static int
+open_symbol_file_object (void *from_ttyp)
+{
+ CORE_ADDR lm, l_name;
+ char *filename;
+ int errcode;
+ int from_tty = *(int *)from_ttyp;
+ struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS ();
+ char *l_name_buf = xmalloc (lmo->l_name_size);
+ struct cleanup *cleanups = make_cleanup (xfree, l_name_buf);
+
+ if (symfile_objfile)
+ if (!query ("Attempt to reload symbols from process? "))
+ return 0;
+
+ if ((debug_base = locate_base ()) == 0)
+ return 0; /* failed somehow... */
+
+ /* First link map member should be the executable. */
+ if ((lm = first_link_map_member ()) == 0)
+ return 0; /* failed somehow... */
+
+ /* Read address of name from target memory to GDB. */
+ read_memory (lm + lmo->l_name_offset, l_name_buf, lmo->l_name_size);
+
+ /* Convert the address to host format. */
+ l_name = extract_address (l_name_buf, lmo->l_name_size);
+
+ /* Free l_name_buf. */
+ do_cleanups (cleanups);
+
+ if (l_name == 0)
+ return 0; /* No filename. */
+
+ /* Now fetch the filename from target memory. */
+ target_read_string (l_name, &filename, SO_NAME_MAX_PATH_SIZE - 1, &errcode);
+
+ if (errcode)
+ {
+ warning ("failed to read exec filename from attached file: %s",
+ safe_strerror (errcode));
+ return 0;
+ }
+
+ make_cleanup (xfree, filename);
+ /* Have a pathname: read the symbol file. */
+ symbol_file_add_main (filename, from_tty);
+
+ return 1;
+}
+
+/* LOCAL FUNCTION
+
+ current_sos -- build a list of currently loaded shared objects
+
+ SYNOPSIS
+
+ struct so_list *current_sos ()
+
+ DESCRIPTION
+
+ Build a list of `struct so_list' objects describing the shared
+ objects currently loaded in the inferior. This list does not
+ include an entry for the main executable file.
+
+ Note that we only gather information directly available from the
+ inferior --- we don't examine any of the shared library files
+ themselves. The declaration of `struct so_list' says which fields
+ we provide values for. */
+
+static struct so_list *
+svr4_current_sos (void)
+{
+ CORE_ADDR lm;
+ struct so_list *head = 0;
+ struct so_list **link_ptr = &head;
+
+ /* Make sure we've looked up the inferior's dynamic linker's base
+ structure. */
+ if (! debug_base)
+ {
+ debug_base = locate_base ();
+
+ /* If we can't find the dynamic linker's base structure, this
+ must not be a dynamically linked executable. Hmm. */
+ if (! debug_base)
+ return 0;
+ }
+
+ /* Walk the inferior's link map list, and build our list of
+ `struct so_list' nodes. */
+ lm = first_link_map_member ();
+ while (lm)
+ {
+ struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS ();
+ struct so_list *new
+ = (struct so_list *) xmalloc (sizeof (struct so_list));
+ struct cleanup *old_chain = make_cleanup (xfree, new);
+
+ memset (new, 0, sizeof (*new));
+
+ new->lm_info = xmalloc (sizeof (struct lm_info));
+ make_cleanup (xfree, new->lm_info);
+
+ new->lm_info->lm = xmalloc (lmo->link_map_size);
+ make_cleanup (xfree, new->lm_info->lm);
+ memset (new->lm_info->lm, 0, lmo->link_map_size);
+
+ read_memory (lm, new->lm_info->lm, lmo->link_map_size);
+
+ lm = LM_NEXT (new);
+
+ /* For SVR4 versions, the first entry in the link map is for the
+ inferior executable, so we must ignore it. For some versions of
+ SVR4, it has no name. For others (Solaris 2.3 for example), it
+ does have a name, so we can no longer use a missing name to
+ decide when to ignore it. */
+ if (IGNORE_FIRST_LINK_MAP_ENTRY (new))
+ free_so (new);
+ else
+ {
+ int errcode;
+ char *buffer;
+
+ /* Extract this shared object's name. */
+ target_read_string (LM_NAME (new), &buffer,
+ SO_NAME_MAX_PATH_SIZE - 1, &errcode);
+ if (errcode != 0)
+ {
+ warning ("current_sos: Can't read pathname for load map: %s\n",
+ safe_strerror (errcode));
+ }
+ else
+ {
+ strncpy (new->so_name, buffer, SO_NAME_MAX_PATH_SIZE - 1);
+ new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
+ xfree (buffer);
+ strcpy (new->so_original_name, new->so_name);
+ }
+
+ /* If this entry has no name, or its name matches the name
+ for the main executable, don't include it in the list. */
+ if (! new->so_name[0]
+ || match_main (new->so_name))
+ free_so (new);
+ else
+ {
+ new->next = 0;
+ *link_ptr = new;
+ link_ptr = &new->next;
+ }
+ }
+
+ discard_cleanups (old_chain);
+ }
+
+ return head;
+}
+
+
+/* On some systems, the only way to recognize the link map entry for
+ the main executable file is by looking at its name. Return
+ non-zero iff SONAME matches one of the known main executable names. */
+
+static int
+match_main (char *soname)
+{
+ char **mainp;
+
+ for (mainp = main_name_list; *mainp != NULL; mainp++)
+ {
+ if (strcmp (soname, *mainp) == 0)
+ return (1);
+ }
+
+ return (0);
+}
+
+/* Return 1 if PC lies in the dynamic symbol resolution code of the
+ SVR4 run time loader. */
+static CORE_ADDR interp_text_sect_low;
+static CORE_ADDR interp_text_sect_high;
+static CORE_ADDR interp_plt_sect_low;
+static CORE_ADDR interp_plt_sect_high;
+
+static int
+svr4_in_dynsym_resolve_code (CORE_ADDR pc)
+{
+ return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
+ || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
+ || in_plt_section (pc, NULL));
+}
+
+
+/*
+
+ LOCAL FUNCTION
+
+ enable_break -- arrange for dynamic linker to hit breakpoint
+
+ SYNOPSIS
+
+ int enable_break (void)
+
+ DESCRIPTION
+
+ Both the SunOS and the SVR4 dynamic linkers have, as part of their
+ debugger interface, support for arranging for the inferior to hit
+ a breakpoint after mapping in the shared libraries. This function
+ enables that breakpoint.
+
+ For SunOS, there is a special flag location (in_debugger) which we
+ set to 1. When the dynamic linker sees this flag set, it will set
+ a breakpoint at a location known only to itself, after saving the
+ original contents of that place and the breakpoint address itself,
+ in it's own internal structures. When we resume the inferior, it
+ will eventually take a SIGTRAP when it runs into the breakpoint.
+ We handle this (in a different place) by restoring the contents of
+ the breakpointed location (which is only known after it stops),
+ chasing around to locate the shared libraries that have been
+ loaded, then resuming.
+
+ For SVR4, the debugger interface structure contains a member (r_brk)
+ which is statically initialized at the time the shared library is
+ built, to the offset of a function (_r_debug_state) which is guaran-
+ teed to be called once before mapping in a library, and again when
+ the mapping is complete. At the time we are examining this member,
+ it contains only the unrelocated offset of the function, so we have
+ to do our own relocation. Later, when the dynamic linker actually
+ runs, it relocates r_brk to be the actual address of _r_debug_state().
+
+ The debugger interface structure also contains an enumeration which
+ is set to either RT_ADD or RT_DELETE prior to changing the mapping,
+ depending upon whether or not the library is being mapped or unmapped,
+ and then set to RT_CONSISTENT after the library is mapped/unmapped.
+ */
+
+static int
+enable_break (void)
+{
+ int success = 0;
+
+#ifdef BKPT_AT_SYMBOL
+
+ struct minimal_symbol *msymbol;
+ char **bkpt_namep;
+ asection *interp_sect;
+
+ /* First, remove all the solib event breakpoints. Their addresses
+ may have changed since the last time we ran the program. */
+ remove_solib_event_breakpoints ();
+
+ interp_text_sect_low = interp_text_sect_high = 0;
+ interp_plt_sect_low = interp_plt_sect_high = 0;
+
+ /* Find the .interp section; if not found, warn the user and drop
+ into the old breakpoint at symbol code. */
+ interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
+ if (interp_sect)
+ {
+ unsigned int interp_sect_size;
+ char *buf;
+ CORE_ADDR load_addr = 0;
+ int load_addr_found = 0;
+ struct so_list *inferior_sos;
+ bfd *tmp_bfd = NULL;
+ int tmp_fd = -1;
+ char *tmp_pathname = NULL;
+ CORE_ADDR sym_addr = 0;
+
+ /* Read the contents of the .interp section into a local buffer;
+ the contents specify the dynamic linker this program uses. */
+ interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
+ buf = alloca (interp_sect_size);
+ bfd_get_section_contents (exec_bfd, interp_sect,
+ buf, 0, interp_sect_size);
+
+ /* Now we need to figure out where the dynamic linker was
+ loaded so that we can load its symbols and place a breakpoint
+ in the dynamic linker itself.
+
+ This address is stored on the stack. However, I've been unable
+ to find any magic formula to find it for Solaris (appears to
+ be trivial on GNU/Linux). Therefore, we have to try an alternate
+ mechanism to find the dynamic linker's base address. */
+
+ tmp_fd = solib_open (buf, &tmp_pathname);
+ if (tmp_fd >= 0)
+ tmp_bfd = bfd_fdopenr (tmp_pathname, gnutarget, tmp_fd);
+
+ if (tmp_bfd == NULL)
+ goto bkpt_at_symbol;
+
+ /* Make sure the dynamic linker's really a useful object. */
+ if (!bfd_check_format (tmp_bfd, bfd_object))
+ {
+ warning ("Unable to grok dynamic linker %s as an object file", buf);
+ bfd_close (tmp_bfd);
+ goto bkpt_at_symbol;
+ }
+
+ /* If the entry in _DYNAMIC for the dynamic linker has already
+ been filled in, we can read its base address from there. */
+ inferior_sos = svr4_current_sos ();
+ if (inferior_sos)
+ {
+ /* Connected to a running target. Update our shared library table. */
+ solib_add (NULL, 0, NULL, auto_solib_add);
+ }
+ while (inferior_sos)
+ {
+ if (strcmp (buf, inferior_sos->so_original_name) == 0)
+ {
+ load_addr_found = 1;
+ load_addr = LM_ADDR (inferior_sos);
+ break;
+ }
+ inferior_sos = inferior_sos->next;
+ }
+
+ /* Otherwise we find the dynamic linker's base address by examining
+ the current pc (which should point at the entry point for the
+ dynamic linker) and subtracting the offset of the entry point. */
+ if (!load_addr_found)
+ load_addr = read_pc () - tmp_bfd->start_address;
+
+ /* Record the relocated start and end address of the dynamic linker
+ text and plt section for svr4_in_dynsym_resolve_code. */
+ interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
+ if (interp_sect)
+ {
+ interp_text_sect_low =
+ bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+ interp_text_sect_high =
+ interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+ }
+ interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
+ if (interp_sect)
+ {
+ interp_plt_sect_low =
+ bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+ interp_plt_sect_high =
+ interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+ }
+
+ /* Now try to set a breakpoint in the dynamic linker. */
+ for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++)
+ {
+ sym_addr = bfd_lookup_symbol (tmp_bfd, *bkpt_namep);
+ if (sym_addr != 0)
+ break;
+ }
+
+ /* We're done with the temporary bfd. */
+ bfd_close (tmp_bfd);
+
+ if (sym_addr != 0)
+ {
+ create_solib_event_breakpoint (load_addr + sym_addr);
+ return 1;
+ }
+
+ /* For whatever reason we couldn't set a breakpoint in the dynamic
+ linker. Warn and drop into the old code. */
+ bkpt_at_symbol:
+ warning ("Unable to find dynamic linker breakpoint function.\nGDB will be unable to debug shared library initializers\nand track explicitly loaded dynamic code.");
+ }
+
+ /* Scan through the list of symbols, trying to look up the symbol and
+ set a breakpoint there. Terminate loop when we/if we succeed. */
+
+ breakpoint_addr = 0;
+ for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++)
+ {
+ msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile);
+ if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
+ {
+ create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol));
+ return 1;
+ }
+ }
+
+ /* Nothing good happened. */
+ success = 0;
+
+#endif /* BKPT_AT_SYMBOL */
+
+ return (success);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ special_symbol_handling -- additional shared library symbol handling
+
+ SYNOPSIS
+
+ void special_symbol_handling ()
+
+ DESCRIPTION
+
+ Once the symbols from a shared object have been loaded in the usual
+ way, we are called to do any system specific symbol handling that
+ is needed.
+
+ For SunOS4, this consisted of grunging around in the dynamic
+ linkers structures to find symbol definitions for "common" symbols
+ and adding them to the minimal symbol table for the runtime common
+ objfile.
+
+ However, for SVR4, there's nothing to do.
+
+ */
+
+static void
+svr4_special_symbol_handling (void)
+{
+}
+
+/* Relocate the main executable. This function should be called upon
+ stopping the inferior process at the entry point to the program.
+ The entry point from BFD is compared to the PC and if they are
+ different, the main executable is relocated by the proper amount.
+
+ As written it will only attempt to relocate executables which
+ lack interpreter sections. It seems likely that only dynamic
+ linker executables will get relocated, though it should work
+ properly for a position-independent static executable as well. */
+
+static void
+svr4_relocate_main_executable (void)
+{
+ asection *interp_sect;
+ CORE_ADDR pc = read_pc ();
+
+ /* Decide if the objfile needs to be relocated. As indicated above,
+ we will only be here when execution is stopped at the beginning
+ of the program. Relocation is necessary if the address at which
+ we are presently stopped differs from the start address stored in
+ the executable AND there's no interpreter section. The condition
+ regarding the interpreter section is very important because if
+ there *is* an interpreter section, execution will begin there
+ instead. When there is an interpreter section, the start address
+ is (presumably) used by the interpreter at some point to start
+ execution of the program.
+
+ If there is an interpreter, it is normal for it to be set to an
+ arbitrary address at the outset. The job of finding it is
+ handled in enable_break().
+
+ So, to summarize, relocations are necessary when there is no
+ interpreter section and the start address obtained from the
+ executable is different from the address at which GDB is
+ currently stopped.
+
+ [ The astute reader will note that we also test to make sure that
+ the executable in question has the DYNAMIC flag set. It is my
+ opinion that this test is unnecessary (undesirable even). It
+ was added to avoid inadvertent relocation of an executable
+ whose e_type member in the ELF header is not ET_DYN. There may
+ be a time in the future when it is desirable to do relocations
+ on other types of files as well in which case this condition
+ should either be removed or modified to accomodate the new file
+ type. (E.g, an ET_EXEC executable which has been built to be
+ position-independent could safely be relocated by the OS if
+ desired. It is true that this violates the ABI, but the ABI
+ has been known to be bent from time to time.) - Kevin, Nov 2000. ]
+ */
+
+ interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
+ if (interp_sect == NULL
+ && (bfd_get_file_flags (exec_bfd) & DYNAMIC) != 0
+ && bfd_get_start_address (exec_bfd) != pc)
+ {
+ struct cleanup *old_chain;
+ struct section_offsets *new_offsets;
+ int i, changed;
+ CORE_ADDR displacement;
+
+ /* It is necessary to relocate the objfile. The amount to
+ relocate by is simply the address at which we are stopped
+ minus the starting address from the executable.
+
+ We relocate all of the sections by the same amount. This
+ behavior is mandated by recent editions of the System V ABI.
+ According to the System V Application Binary Interface,
+ Edition 4.1, page 5-5:
+
+ ... Though the system chooses virtual addresses for
+ individual processes, it maintains the segments' relative
+ positions. Because position-independent code uses relative
+ addressesing between segments, the difference between
+ virtual addresses in memory must match the difference
+ between virtual addresses in the file. The difference
+ between the virtual address of any segment in memory and
+ the corresponding virtual address in the file is thus a
+ single constant value for any one executable or shared
+ object in a given process. This difference is the base
+ address. One use of the base address is to relocate the
+ memory image of the program during dynamic linking.
+
+ The same language also appears in Edition 4.0 of the System V
+ ABI and is left unspecified in some of the earlier editions. */
+
+ displacement = pc - bfd_get_start_address (exec_bfd);
+ changed = 0;
+
+ new_offsets = xcalloc (symfile_objfile->num_sections,
+ sizeof (struct section_offsets));
+ old_chain = make_cleanup (xfree, new_offsets);
+
+ for (i = 0; i < symfile_objfile->num_sections; i++)
+ {
+ if (displacement != ANOFFSET (symfile_objfile->section_offsets, i))
+ changed = 1;
+ new_offsets->offsets[i] = displacement;
+ }
+
+ if (changed)
+ objfile_relocate (symfile_objfile, new_offsets);
+
+ do_cleanups (old_chain);
+ }
+}
+
+/*
+
+ GLOBAL FUNCTION
+
+ svr4_solib_create_inferior_hook -- shared library startup support
+
+ SYNOPSIS
+
+ void svr4_solib_create_inferior_hook()
+
+ DESCRIPTION
+
+ When gdb starts up the inferior, it nurses it along (through the
+ shell) until it is ready to execute it's first instruction. At this
+ point, this function gets called via expansion of the macro
+ SOLIB_CREATE_INFERIOR_HOOK.
+
+ For SunOS executables, this first instruction is typically the
+ one at "_start", or a similar text label, regardless of whether
+ the executable is statically or dynamically linked. The runtime
+ startup code takes care of dynamically linking in any shared
+ libraries, once gdb allows the inferior to continue.
+
+ For SVR4 executables, this first instruction is either the first
+ instruction in the dynamic linker (for dynamically linked
+ executables) or the instruction at "start" for statically linked
+ executables. For dynamically linked executables, the system
+ first exec's /lib/libc.so.N, which contains the dynamic linker,
+ and starts it running. The dynamic linker maps in any needed
+ shared libraries, maps in the actual user executable, and then
+ jumps to "start" in the user executable.
+
+ For both SunOS shared libraries, and SVR4 shared libraries, we
+ can arrange to cooperate with the dynamic linker to discover the
+ names of shared libraries that are dynamically linked, and the
+ base addresses to which they are linked.
+
+ This function is responsible for discovering those names and
+ addresses, and saving sufficient information about them to allow
+ their symbols to be read at a later time.
+
+ FIXME
+
+ Between enable_break() and disable_break(), this code does not
+ properly handle hitting breakpoints which the user might have
+ set in the startup code or in the dynamic linker itself. Proper
+ handling will probably have to wait until the implementation is
+ changed to use the "breakpoint handler function" method.
+
+ Also, what if child has exit()ed? Must exit loop somehow.
+ */
+
+static void
+svr4_solib_create_inferior_hook (void)
+{
+ /* Relocate the main executable if necessary. */
+ svr4_relocate_main_executable ();
+
+ if (!enable_break ())
+ {
+ warning ("shared library handler failed to enable breakpoint");
+ return;
+ }
+
+#if defined(_SCO_DS)
+ /* SCO needs the loop below, other systems should be using the
+ special shared library breakpoints and the shared library breakpoint
+ service routine.
+
+ Now run the target. It will eventually hit the breakpoint, at
+ which point all of the libraries will have been mapped in and we
+ can go groveling around in the dynamic linker structures to find
+ out what we need to know about them. */
+
+ clear_proceed_status ();
+ stop_soon_quietly = 1;
+ stop_signal = TARGET_SIGNAL_0;
+ do
+ {
+ target_resume (pid_to_ptid (-1), 0, stop_signal);
+ wait_for_inferior ();
+ }
+ while (stop_signal != TARGET_SIGNAL_TRAP);
+ stop_soon_quietly = 0;
+#endif /* defined(_SCO_DS) */
+}
+
+static void
+svr4_clear_solib (void)
+{
+ debug_base = 0;
+}
+
+static void
+svr4_free_so (struct so_list *so)
+{
+ xfree (so->lm_info->lm);
+ xfree (so->lm_info);
+}
+
+
+/* Clear any bits of ADDR that wouldn't fit in a target-format
+ data pointer. "Data pointer" here refers to whatever sort of
+ address the dynamic linker uses to manage its sections. At the
+ moment, we don't support shared libraries on any processors where
+ code and data pointers are different sizes.
+
+ This isn't really the right solution. What we really need here is
+ a way to do arithmetic on CORE_ADDR values that respects the
+ natural pointer/address correspondence. (For example, on the MIPS,
+ converting a 32-bit pointer to a 64-bit CORE_ADDR requires you to
+ sign-extend the value. There, simply truncating the bits above
+ TARGET_PTR_BIT, as we do below, is no good.) This should probably
+ be a new gdbarch method or something. */
+static CORE_ADDR
+svr4_truncate_ptr (CORE_ADDR addr)
+{
+ if (TARGET_PTR_BIT == sizeof (CORE_ADDR) * 8)
+ /* We don't need to truncate anything, and the bit twiddling below
+ will fail due to overflow problems. */
+ return addr;
+ else
+ return addr & (((CORE_ADDR) 1 << TARGET_PTR_BIT) - 1);
+}
+
+
+static void
+svr4_relocate_section_addresses (struct so_list *so,
+ struct section_table *sec)
+{
+ sec->addr = svr4_truncate_ptr (sec->addr + LM_ADDR (so));
+ sec->endaddr = svr4_truncate_ptr (sec->endaddr + LM_ADDR (so));
+}
+
+
+/* Fetch a link_map_offsets structure for native targets using struct
+ definitions from link.h. See solib-legacy.c for the function
+ which does the actual work.
+
+ Note: For non-native targets (i.e. cross-debugging situations),
+ a target specific fetch_link_map_offsets() function should be
+ defined and registered via set_solib_svr4_fetch_link_map_offsets(). */
+
+static struct link_map_offsets *
+legacy_fetch_link_map_offsets (void)
+{
+ if (legacy_svr4_fetch_link_map_offsets_hook)
+ return legacy_svr4_fetch_link_map_offsets_hook ();
+ else
+ {
+ internal_error (__FILE__, __LINE__,
+ "legacy_fetch_link_map_offsets called without legacy "
+ "link_map support enabled.");
+ return 0;
+ }
+}
+
+/* Fetch a link_map_offsets structure using the method registered in the
+ architecture vector. */
+
+static struct link_map_offsets *
+svr4_fetch_link_map_offsets (void)
+{
+ struct link_map_offsets *(*flmo)(void) =
+ gdbarch_data (current_gdbarch, fetch_link_map_offsets_gdbarch_data);
+
+ if (flmo == NULL)
+ {
+ internal_error (__FILE__, __LINE__,
+ "svr4_fetch_link_map_offsets: fetch_link_map_offsets "
+ "method not defined for this architecture.");
+ return 0;
+ }
+ else
+ return (flmo ());
+}
+
+/* set_solib_svr4_fetch_link_map_offsets() is intended to be called by
+ a <arch>_gdbarch_init() function. It is used to establish an
+ architecture specific link_map_offsets fetcher for the architecture
+ being defined. */
+
+void
+set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch,
+ struct link_map_offsets *(*flmo) (void))
+{
+ set_gdbarch_data (gdbarch, fetch_link_map_offsets_gdbarch_data, flmo);
+}
+
+/* Initialize the architecture specific link_map_offsets fetcher.
+ This is called after <arch>_gdbarch_init() has set up its struct
+ gdbarch for the new architecture, so care must be taken to use the
+ value set by set_solib_svr4_fetch_link_map_offsets(), above. We
+ do, however, attempt to provide a reasonable alternative (for
+ native targets anyway) if the <arch>_gdbarch_init() fails to call
+ set_solib_svr4_fetch_link_map_offsets(). */
+
+static void *
+init_fetch_link_map_offsets (struct gdbarch *gdbarch)
+{
+ struct link_map_offsets *(*flmo) =
+ gdbarch_data (gdbarch, fetch_link_map_offsets_gdbarch_data);
+
+ if (flmo == NULL)
+ return legacy_fetch_link_map_offsets;
+ else
+ return flmo;
+}
+
+static struct target_so_ops svr4_so_ops;
+
+void
+_initialize_svr4_solib (void)
+{
+ fetch_link_map_offsets_gdbarch_data =
+ register_gdbarch_data (init_fetch_link_map_offsets, 0);
+
+ svr4_so_ops.relocate_section_addresses = svr4_relocate_section_addresses;
+ svr4_so_ops.free_so = svr4_free_so;
+ svr4_so_ops.clear_solib = svr4_clear_solib;
+ svr4_so_ops.solib_create_inferior_hook = svr4_solib_create_inferior_hook;
+ svr4_so_ops.special_symbol_handling = svr4_special_symbol_handling;
+ svr4_so_ops.current_sos = svr4_current_sos;
+ svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
+ svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
+
+ /* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */
+ current_target_so_ops = &svr4_so_ops;
+}
diff --git a/gdb/solib-svr4.h b/gdb/solib-svr4.h
new file mode 100644
index 00000000000..8611dff8e6e
--- /dev/null
+++ b/gdb/solib-svr4.h
@@ -0,0 +1,78 @@
+/* Handle shared libraries for GDB, the GNU Debugger.
+ Copyright 2000
+ 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. */
+
+/* Critical offsets and sizes which describe struct r_debug and
+ struct link_map on SVR4-like targets. All offsets and sizes are
+ in bytes unless otherwise specified. */
+
+struct link_map_offsets
+ {
+ /* Size of struct r_debug (or equivalent), or at least enough of it to
+ be able to obtain the r_map field. */
+ int r_debug_size;
+
+ /* Offset to the r_map field in struct r_debug. */
+ int r_map_offset;
+
+ /* Size of the r_map field in struct r_debug. */
+ int r_map_size;
+
+ /* Size of struct link_map (or equivalent), or at least enough of it
+ to be able to obtain the fields below. */
+ int link_map_size;
+
+ /* Offset to l_addr field in struct link_map. */
+ int l_addr_offset;
+
+ /* Size of l_addr field in struct link_map. */
+ int l_addr_size;
+
+ /* Offset to l_next field in struct link_map. */
+ int l_next_offset;
+
+ /* Size of l_next field in struct link_map. */
+ int l_next_size;
+
+ /* Offset to l_prev field in struct link_map. */
+ int l_prev_offset;
+
+ /* Size of l_prev field in struct link_map. */
+ int l_prev_size;
+
+ /* Offset to l_name field in struct link_map. */
+ int l_name_offset;
+
+ /* Size of l_name field in struct link_map. */
+ int l_name_size;
+ };
+
+/* set_solib_svr4_fetch_link_map_offsets() is intended to be called by
+ a <arch>_gdbarch_init() function. It is used to establish an
+ architecture specific link_map_offsets fetcher for the architecture
+ being defined. */
+
+extern void set_solib_svr4_fetch_link_map_offsets
+ (struct gdbarch *gdbarch, struct link_map_offsets *(*func) (void));
+
+/* legacy_svr4_fetch_link_map_offsets_hook is a pointer to a function
+ which is used to fetch link map offsets. It will only be set
+ by solib-legacy.c, if at all. */
+extern struct link_map_offsets *(*legacy_svr4_fetch_link_map_offsets_hook)(void);
diff --git a/gdb/solib.c b/gdb/solib.c
new file mode 100644
index 00000000000..d4876c15e7a
--- /dev/null
+++ b/gdb/solib.c
@@ -0,0 +1,884 @@
+/* Handle shared libraries for GDB, the GNU Debugger.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002 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 "defs.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "gdb_string.h"
+#include "symtab.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "target.h"
+#include "frame.h"
+#include "gdb_regex.h"
+#include "inferior.h"
+#include "environ.h"
+#include "language.h"
+#include "gdbcmd.h"
+#include "completer.h"
+#include "filenames.h" /* for DOSish file names */
+
+#include "solist.h"
+
+/* external data declarations */
+
+/* FIXME: gdbarch needs to control this variable */
+struct target_so_ops *current_target_so_ops;
+
+/* local data declarations */
+
+static struct so_list *so_list_head; /* List of known shared objects */
+
+static int solib_cleanup_queued = 0; /* make_run_cleanup called */
+
+/* Local function prototypes */
+
+static void do_clear_solib (PTR);
+
+/* If non-zero, this is a prefix that will be added to the front of the name
+ shared libraries with an absolute filename for loading. */
+static char *solib_absolute_prefix = NULL;
+
+/* If non-empty, this is a search path for loading non-absolute shared library
+ symbol files. This takes precedence over the environment variables PATH
+ and LD_LIBRARY_PATH. */
+static char *solib_search_path = NULL;
+
+/*
+
+ GLOBAL FUNCTION
+
+ solib_open -- Find a shared library file and open it.
+
+ SYNOPSIS
+
+ int solib_open (char *in_patname, char **found_pathname);
+
+ DESCRIPTION
+
+ Global variable SOLIB_ABSOLUTE_PREFIX is used as a prefix directory
+ to search for shared libraries if they have an absolute path.
+
+ Global variable SOLIB_SEARCH_PATH is used as a prefix directory
+ (or set of directories, as in LD_LIBRARY_PATH) to search for all
+ shared libraries if not found in SOLIB_ABSOLUTE_PREFIX.
+
+ Search order:
+ * If path is absolute, look in SOLIB_ABSOLUTE_PREFIX.
+ * If path is absolute or relative, look for it literally (unmodified).
+ * Look in SOLIB_SEARCH_PATH.
+ * Look in inferior's $PATH.
+ * Look in inferior's $LD_LIBRARY_PATH.
+
+ RETURNS
+
+ file handle for opened solib, or -1 for failure. */
+
+int
+solib_open (char *in_pathname, char **found_pathname)
+{
+ int found_file = -1;
+ char *temp_pathname = NULL;
+ char *p = in_pathname;
+
+ while (*p && !IS_DIR_SEPARATOR (*p))
+ p++;
+
+ if (*p)
+ {
+ if (! IS_ABSOLUTE_PATH (in_pathname) || solib_absolute_prefix == NULL)
+ temp_pathname = in_pathname;
+ else
+ {
+ int prefix_len = strlen (solib_absolute_prefix);
+
+ /* Remove trailing slashes from absolute prefix. */
+ while (prefix_len > 0
+ && IS_DIR_SEPARATOR (solib_absolute_prefix[prefix_len - 1]))
+ prefix_len--;
+
+ /* Cat the prefixed pathname together. */
+ temp_pathname = alloca (prefix_len + strlen (in_pathname) + 1);
+ strncpy (temp_pathname, solib_absolute_prefix, prefix_len);
+ temp_pathname[prefix_len] = '\0';
+ strcat (temp_pathname, in_pathname);
+ }
+
+ /* Now see if we can open it. */
+ found_file = open (temp_pathname, O_RDONLY, 0);
+ }
+
+ /* If the search in solib_absolute_prefix failed, and the path name is
+ absolute at this point, make it relative. (openp will try and open the
+ file according to its absolute path otherwise, which is not what we want.)
+ Affects subsequent searches for this solib. */
+ if (found_file < 0 && IS_ABSOLUTE_PATH (in_pathname))
+ {
+ /* First, get rid of any drive letters etc. */
+ while (!IS_DIR_SEPARATOR (*in_pathname))
+ in_pathname++;
+
+ /* Next, get rid of all leading dir separators. */
+ while (IS_DIR_SEPARATOR (*in_pathname))
+ in_pathname++;
+ }
+
+ /* If not found, next search the solib_search_path (if any). */
+ if (found_file < 0 && solib_search_path != NULL)
+ found_file = openp (solib_search_path,
+ 1, in_pathname, O_RDONLY, 0, &temp_pathname);
+
+ /* If not found, next search the solib_search_path (if any) for the basename
+ only (ignoring the path). This is to allow reading solibs from a path
+ that differs from the opened path. */
+ if (found_file < 0 && solib_search_path != NULL)
+ found_file = openp (solib_search_path,
+ 1, lbasename (in_pathname), O_RDONLY, 0,
+ &temp_pathname);
+
+ /* If not found, next search the inferior's $PATH environment variable. */
+ if (found_file < 0 && solib_search_path != NULL)
+ found_file = openp (get_in_environ (inferior_environ, "PATH"),
+ 1, in_pathname, O_RDONLY, 0, &temp_pathname);
+
+ /* If not found, next search the inferior's $LD_LIBRARY_PATH
+ environment variable. */
+ if (found_file < 0 && solib_search_path != NULL)
+ found_file = openp (get_in_environ (inferior_environ, "LD_LIBRARY_PATH"),
+ 1, in_pathname, O_RDONLY, 0, &temp_pathname);
+
+ /* Done. If not found, tough luck. Return found_file and
+ (optionally) found_pathname. */
+ if (found_pathname != NULL && temp_pathname != NULL)
+ *found_pathname = xstrdup (temp_pathname);
+ return found_file;
+}
+
+
+/*
+
+ LOCAL FUNCTION
+
+ solib_map_sections -- open bfd and build sections for shared lib
+
+ SYNOPSIS
+
+ static int solib_map_sections (struct so_list *so)
+
+ DESCRIPTION
+
+ Given a pointer to one of the shared objects in our list
+ of mapped objects, use the recorded name to open a bfd
+ descriptor for the object, build a section table, and then
+ relocate all the section addresses by the base address at
+ which the shared object was mapped.
+
+ FIXMES
+
+ In most (all?) cases the shared object file name recorded in the
+ dynamic linkage tables will be a fully qualified pathname. For
+ cases where it isn't, do we really mimic the systems search
+ mechanism correctly in the below code (particularly the tilde
+ expansion stuff?).
+ */
+
+static int
+solib_map_sections (PTR arg)
+{
+ struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
+ char *filename;
+ char *scratch_pathname;
+ int scratch_chan;
+ struct section_table *p;
+ struct cleanup *old_chain;
+ bfd *abfd;
+
+ filename = tilde_expand (so->so_name);
+
+ old_chain = make_cleanup (xfree, filename);
+ scratch_chan = solib_open (filename, &scratch_pathname);
+
+ if (scratch_chan < 0)
+ {
+ perror_with_name (filename);
+ }
+
+ /* Leave scratch_pathname allocated. abfd->name will point to it. */
+ abfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan);
+ if (!abfd)
+ {
+ close (scratch_chan);
+ error ("Could not open `%s' as an executable file: %s",
+ scratch_pathname, bfd_errmsg (bfd_get_error ()));
+ }
+
+ /* Leave bfd open, core_xfer_memory and "info files" need it. */
+ so->abfd = abfd;
+ abfd->cacheable = 1;
+
+ /* copy full path name into so_name, so that later symbol_file_add
+ can find it */
+ if (strlen (scratch_pathname) >= SO_NAME_MAX_PATH_SIZE)
+ error ("Full path name length of shared library exceeds SO_NAME_MAX_PATH_SIZE in so_list structure.");
+ strcpy (so->so_name, scratch_pathname);
+
+ if (!bfd_check_format (abfd, bfd_object))
+ {
+ error ("\"%s\": not in executable format: %s.",
+ scratch_pathname, bfd_errmsg (bfd_get_error ()));
+ }
+ if (build_section_table (abfd, &so->sections, &so->sections_end))
+ {
+ error ("Can't find the file sections in `%s': %s",
+ bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
+ }
+
+ for (p = so->sections; p < so->sections_end; p++)
+ {
+ /* Relocate the section binding addresses as recorded in the shared
+ object's file by the base address to which the object was actually
+ mapped. */
+ TARGET_SO_RELOCATE_SECTION_ADDRESSES (so, p);
+ if (STREQ (p->the_bfd_section->name, ".text"))
+ {
+ so->textsection = p;
+ }
+ }
+
+ /* Free the file names, close the file now. */
+ do_cleanups (old_chain);
+
+ return (1);
+}
+
+/* LOCAL FUNCTION
+
+ free_so --- free a `struct so_list' object
+
+ SYNOPSIS
+
+ void free_so (struct so_list *so)
+
+ DESCRIPTION
+
+ Free the storage associated with the `struct so_list' object SO.
+ If we have opened a BFD for SO, close it.
+
+ The caller is responsible for removing SO from whatever list it is
+ a member of. If we have placed SO's sections in some target's
+ section table, the caller is responsible for removing them.
+
+ This function doesn't mess with objfiles at all. If there is an
+ objfile associated with SO that needs to be removed, the caller is
+ responsible for taking care of that. */
+
+void
+free_so (struct so_list *so)
+{
+ char *bfd_filename = 0;
+
+ if (so->sections)
+ xfree (so->sections);
+
+ if (so->abfd)
+ {
+ bfd_filename = bfd_get_filename (so->abfd);
+ if (! bfd_close (so->abfd))
+ warning ("cannot close \"%s\": %s",
+ bfd_filename, bfd_errmsg (bfd_get_error ()));
+ }
+
+ if (bfd_filename)
+ xfree (bfd_filename);
+
+ TARGET_SO_FREE_SO (so);
+
+ xfree (so);
+}
+
+
+/* A small stub to get us past the arg-passing pinhole of catch_errors. */
+
+static int
+symbol_add_stub (PTR arg)
+{
+ register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
+ struct section_addr_info *sap;
+
+ /* Have we already loaded this shared object? */
+ ALL_OBJFILES (so->objfile)
+ {
+ if (strcmp (so->objfile->name, so->so_name) == 0)
+ return 1;
+ }
+
+ sap = build_section_addr_info_from_section_table (so->sections,
+ so->sections_end);
+
+ so->objfile = symbol_file_add (so->so_name, so->from_tty,
+ sap, 0, OBJF_SHARED);
+ free_section_addr_info (sap);
+
+ return (1);
+}
+
+
+/* LOCAL FUNCTION
+
+ update_solib_list --- synchronize GDB's shared object list with inferior's
+
+ SYNOPSIS
+
+ void update_solib_list (int from_tty, struct target_ops *TARGET)
+
+ Extract the list of currently loaded shared objects from the
+ inferior, and compare it with the list of shared objects currently
+ in GDB's so_list_head list. Edit so_list_head to bring it in sync
+ with the inferior's new list.
+
+ If we notice that the inferior has unloaded some shared objects,
+ free any symbolic info GDB had read about those shared objects.
+
+ Don't load symbolic info for any new shared objects; just add them
+ to the list, and leave their symbols_loaded flag clear.
+
+ If FROM_TTY is non-null, feel free to print messages about what
+ we're doing.
+
+ If TARGET is non-null, add the sections of all new shared objects
+ to TARGET's section table. Note that this doesn't remove any
+ sections for shared objects that have been unloaded, and it
+ doesn't check to see if the new shared objects are already present in
+ the section table. But we only use this for core files and
+ processes we've just attached to, so that's okay. */
+
+void
+update_solib_list (int from_tty, struct target_ops *target)
+{
+ struct so_list *inferior = TARGET_SO_CURRENT_SOS ();
+ struct so_list *gdb, **gdb_link;
+
+ /* If we are attaching to a running process for which we
+ have not opened a symbol file, we may be able to get its
+ symbols now! */
+ if (attach_flag &&
+ symfile_objfile == NULL)
+ catch_errors (TARGET_SO_OPEN_SYMBOL_FILE_OBJECT, (PTR) &from_tty,
+ "Error reading attached process's symbol file.\n",
+ RETURN_MASK_ALL);
+
+ /* Since this function might actually add some elements to the
+ so_list_head list, arrange for it to be cleaned up when
+ appropriate. */
+ if (!solib_cleanup_queued)
+ {
+ make_run_cleanup (do_clear_solib, NULL);
+ solib_cleanup_queued = 1;
+ }
+
+ /* GDB and the inferior's dynamic linker each maintain their own
+ list of currently loaded shared objects; we want to bring the
+ former in sync with the latter. Scan both lists, seeing which
+ shared objects appear where. There are three cases:
+
+ - A shared object appears on both lists. This means that GDB
+ knows about it already, and it's still loaded in the inferior.
+ Nothing needs to happen.
+
+ - A shared object appears only on GDB's list. This means that
+ the inferior has unloaded it. We should remove the shared
+ object from GDB's tables.
+
+ - A shared object appears only on the inferior's list. This
+ means that it's just been loaded. We should add it to GDB's
+ tables.
+
+ So we walk GDB's list, checking each entry to see if it appears
+ in the inferior's list too. If it does, no action is needed, and
+ we remove it from the inferior's list. If it doesn't, the
+ inferior has unloaded it, and we remove it from GDB's list. By
+ the time we're done walking GDB's list, the inferior's list
+ contains only the new shared objects, which we then add. */
+
+ gdb = so_list_head;
+ gdb_link = &so_list_head;
+ while (gdb)
+ {
+ struct so_list *i = inferior;
+ struct so_list **i_link = &inferior;
+
+ /* Check to see whether the shared object *gdb also appears in
+ the inferior's current list. */
+ while (i)
+ {
+ if (! strcmp (gdb->so_original_name, i->so_original_name))
+ break;
+
+ i_link = &i->next;
+ i = *i_link;
+ }
+
+ /* If the shared object appears on the inferior's list too, then
+ it's still loaded, so we don't need to do anything. Delete
+ it from the inferior's list, and leave it on GDB's list. */
+ if (i)
+ {
+ *i_link = i->next;
+ free_so (i);
+ gdb_link = &gdb->next;
+ gdb = *gdb_link;
+ }
+
+ /* If it's not on the inferior's list, remove it from GDB's tables. */
+ else
+ {
+ *gdb_link = gdb->next;
+
+ /* Unless the user loaded it explicitly, free SO's objfile. */
+ if (gdb->objfile && ! (gdb->objfile->flags & OBJF_USERLOADED))
+ free_objfile (gdb->objfile);
+
+ /* Some targets' section tables might be referring to
+ sections from so->abfd; remove them. */
+ remove_target_sections (gdb->abfd);
+
+ free_so (gdb);
+ gdb = *gdb_link;
+ }
+ }
+
+ /* Now the inferior's list contains only shared objects that don't
+ appear in GDB's list --- those that are newly loaded. Add them
+ to GDB's shared object list. */
+ if (inferior)
+ {
+ struct so_list *i;
+
+ /* Add the new shared objects to GDB's list. */
+ *gdb_link = inferior;
+
+ /* Fill in the rest of each of the `struct so_list' nodes. */
+ for (i = inferior; i; i = i->next)
+ {
+ i->from_tty = from_tty;
+
+ /* Fill in the rest of the `struct so_list' node. */
+ catch_errors (solib_map_sections, i,
+ "Error while mapping shared library sections:\n",
+ RETURN_MASK_ALL);
+
+ /* If requested, add the shared object's sections to the TARGET's
+ section table. Do this immediately after mapping the object so
+ that later nodes in the list can query this object, as is needed
+ in solib-osf.c. */
+ if (target)
+ {
+ int count = (i->sections_end - i->sections);
+ if (count > 0)
+ {
+ int space = target_resize_to_sections (target, count);
+ memcpy (target->to_sections + space,
+ i->sections,
+ count * sizeof (i->sections[0]));
+ }
+ }
+ }
+ }
+}
+
+
+/* GLOBAL FUNCTION
+
+ solib_add -- read in symbol info for newly added shared libraries
+
+ SYNOPSIS
+
+ void solib_add (char *pattern, int from_tty, struct target_ops
+ *TARGET, int readsyms)
+
+ DESCRIPTION
+
+ Read in symbolic information for any shared objects whose names
+ match PATTERN. (If we've already read a shared object's symbol
+ info, leave it alone.) If PATTERN is zero, read them all.
+
+ If READSYMS is 0, defer reading symbolic information until later
+ but still do any needed low level processing.
+
+ FROM_TTY and TARGET are as described for update_solib_list, above. */
+
+void
+solib_add (char *pattern, int from_tty, struct target_ops *target, int readsyms)
+{
+ struct so_list *gdb;
+
+ if (pattern)
+ {
+ char *re_err = re_comp (pattern);
+
+ if (re_err)
+ error ("Invalid regexp: %s", re_err);
+ }
+
+ update_solib_list (from_tty, target);
+
+ /* Walk the list of currently loaded shared libraries, and read
+ symbols for any that match the pattern --- or any whose symbols
+ aren't already loaded, if no pattern was given. */
+ {
+ int any_matches = 0;
+ int loaded_any_symbols = 0;
+
+ for (gdb = so_list_head; gdb; gdb = gdb->next)
+ if (! pattern || re_exec (gdb->so_name))
+ {
+ any_matches = 1;
+
+ if (gdb->symbols_loaded)
+ {
+ if (from_tty)
+ printf_unfiltered ("Symbols already loaded for %s\n",
+ gdb->so_name);
+ }
+ else if (readsyms)
+ {
+ if (catch_errors
+ (symbol_add_stub, gdb,
+ "Error while reading shared library symbols:\n",
+ RETURN_MASK_ALL))
+ {
+ if (from_tty)
+ printf_unfiltered ("Loaded symbols for %s\n",
+ gdb->so_name);
+ gdb->symbols_loaded = 1;
+ loaded_any_symbols = 1;
+ }
+ }
+ }
+
+ if (from_tty && pattern && ! any_matches)
+ printf_unfiltered
+ ("No loaded shared libraries match the pattern `%s'.\n", pattern);
+
+ if (loaded_any_symbols)
+ {
+ /* Getting new symbols may change our opinion about what is
+ frameless. */
+ reinit_frame_cache ();
+
+ TARGET_SO_SPECIAL_SYMBOL_HANDLING ();
+ }
+ }
+}
+
+
+/*
+
+ LOCAL FUNCTION
+
+ info_sharedlibrary_command -- code for "info sharedlibrary"
+
+ SYNOPSIS
+
+ static void info_sharedlibrary_command ()
+
+ DESCRIPTION
+
+ Walk through the shared library list and print information
+ about each attached library.
+ */
+
+static void
+info_sharedlibrary_command (char *ignore, int from_tty)
+{
+ register struct so_list *so = NULL; /* link map state variable */
+ int header_done = 0;
+ int addr_width;
+ char *addr_fmt;
+
+ if (TARGET_PTR_BIT == 32)
+ {
+ addr_width = 8 + 4;
+ addr_fmt = "08l";
+ }
+ else if (TARGET_PTR_BIT == 64)
+ {
+ addr_width = 16 + 4;
+ addr_fmt = "016l";
+ }
+ else
+ {
+ internal_error (__FILE__, __LINE__,
+ "TARGET_PTR_BIT returned unknown size %d",
+ TARGET_PTR_BIT);
+ }
+
+ update_solib_list (from_tty, 0);
+
+ for (so = so_list_head; so; so = so->next)
+ {
+ if (so->so_name[0])
+ {
+ if (!header_done)
+ {
+ printf_unfiltered ("%-*s%-*s%-12s%s\n", addr_width, "From",
+ addr_width, "To", "Syms Read",
+ "Shared Object Library");
+ header_done++;
+ }
+
+ printf_unfiltered ("%-*s", addr_width,
+ so->textsection != NULL
+ ? local_hex_string_custom (
+ (LONGEST) so->textsection->addr,
+ addr_fmt)
+ : "");
+ printf_unfiltered ("%-*s", addr_width,
+ so->textsection != NULL
+ ? local_hex_string_custom (
+ (LONGEST) so->textsection->endaddr,
+ addr_fmt)
+ : "");
+ printf_unfiltered ("%-12s", so->symbols_loaded ? "Yes" : "No");
+ printf_unfiltered ("%s\n", so->so_name);
+ }
+ }
+ if (so_list_head == NULL)
+ {
+ printf_unfiltered ("No shared libraries loaded at this time.\n");
+ }
+}
+
+/*
+
+ GLOBAL FUNCTION
+
+ solib_address -- check to see if an address is in a shared lib
+
+ SYNOPSIS
+
+ char * solib_address (CORE_ADDR address)
+
+ DESCRIPTION
+
+ Provides a hook for other gdb routines to discover whether or
+ not a particular address is within the mapped address space of
+ a shared library.
+
+ For example, this routine is called at one point to disable
+ breakpoints which are in shared libraries that are not currently
+ mapped in.
+ */
+
+char *
+solib_address (CORE_ADDR address)
+{
+ register struct so_list *so = 0; /* link map state variable */
+
+ for (so = so_list_head; so; so = so->next)
+ {
+ struct section_table *p;
+
+ for (p = so->sections; p < so->sections_end; p++)
+ {
+ if (p->addr <= address && address < p->endaddr)
+ return (so->so_name);
+ }
+ }
+
+ return (0);
+}
+
+/* Called by free_all_symtabs */
+
+void
+clear_solib (void)
+{
+ /* This function is expected to handle ELF shared libraries. It is
+ also used on Solaris, which can run either ELF or a.out binaries
+ (for compatibility with SunOS 4), both of which can use shared
+ libraries. So we don't know whether we have an ELF executable or
+ an a.out executable until the user chooses an executable file.
+
+ ELF shared libraries don't get mapped into the address space
+ until after the program starts, so we'd better not try to insert
+ breakpoints in them immediately. We have to wait until the
+ dynamic linker has loaded them; we'll hit a bp_shlib_event
+ breakpoint (look for calls to create_solib_event_breakpoint) when
+ it's ready.
+
+ SunOS shared libraries seem to be different --- they're present
+ as soon as the process begins execution, so there's no need to
+ put off inserting breakpoints. There's also nowhere to put a
+ bp_shlib_event breakpoint, so if we put it off, we'll never get
+ around to it.
+
+ So: disable breakpoints only if we're using ELF shared libs. */
+ if (exec_bfd != NULL
+ && bfd_get_flavour (exec_bfd) != bfd_target_aout_flavour)
+ disable_breakpoints_in_shlibs (1);
+
+ while (so_list_head)
+ {
+ struct so_list *so = so_list_head;
+ so_list_head = so->next;
+ if (so->abfd)
+ remove_target_sections (so->abfd);
+ free_so (so);
+ }
+
+ TARGET_SO_CLEAR_SOLIB ();
+}
+
+static void
+do_clear_solib (PTR dummy)
+{
+ solib_cleanup_queued = 0;
+ clear_solib ();
+}
+
+/* GLOBAL FUNCTION
+
+ solib_create_inferior_hook -- shared library startup support
+
+ SYNOPSIS
+
+ void solib_create_inferior_hook()
+
+ DESCRIPTION
+
+ When gdb starts up the inferior, it nurses it along (through the
+ shell) until it is ready to execute it's first instruction. At this
+ point, this function gets called via expansion of the macro
+ SOLIB_CREATE_INFERIOR_HOOK. */
+
+void
+solib_create_inferior_hook (void)
+{
+ TARGET_SO_SOLIB_CREATE_INFERIOR_HOOK ();
+}
+
+/* GLOBAL FUNCTION
+
+ in_solib_dynsym_resolve_code -- check to see if an address is in
+ dynamic loader's dynamic symbol
+ resolution code
+
+ SYNOPSIS
+
+ int in_solib_dynsym_resolve_code (CORE_ADDR pc)
+
+ DESCRIPTION
+
+ Determine if PC is in the dynamic linker's symbol resolution
+ code. Return 1 if so, 0 otherwise.
+*/
+
+int
+in_solib_dynsym_resolve_code (CORE_ADDR pc)
+{
+ return TARGET_SO_IN_DYNSYM_RESOLVE_CODE (pc);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ sharedlibrary_command -- handle command to explicitly add library
+
+ SYNOPSIS
+
+ static void sharedlibrary_command (char *args, int from_tty)
+
+ DESCRIPTION
+
+ */
+
+static void
+sharedlibrary_command (char *args, int from_tty)
+{
+ dont_repeat ();
+ solib_add (args, from_tty, (struct target_ops *) 0, 1);
+}
+
+/* LOCAL FUNCTION
+
+ no_shared_libraries -- handle command to explicitly discard symbols
+ from shared libraries.
+
+ DESCRIPTION
+
+ Implements the command "nosharedlibrary", which discards symbols
+ that have been auto-loaded from shared libraries. Symbols from
+ shared libraries that were added by explicit request of the user
+ are not discarded. Also called from remote.c. */
+
+void
+no_shared_libraries (char *ignored, int from_tty)
+{
+ objfile_purge_solibs ();
+ do_clear_solib (NULL);
+}
+
+void
+_initialize_solib (void)
+{
+ struct cmd_list_element *c;
+
+ add_com ("sharedlibrary", class_files, sharedlibrary_command,
+ "Load shared object library symbols for files matching REGEXP.");
+ add_info ("sharedlibrary", info_sharedlibrary_command,
+ "Status of loaded shared object libraries.");
+ add_com ("nosharedlibrary", class_files, no_shared_libraries,
+ "Unload all shared object library symbols.");
+
+ add_show_from_set
+ (add_set_cmd ("auto-solib-add", class_support, var_boolean,
+ (char *) &auto_solib_add,
+ "Set autoloading of shared library symbols.\n\
+If \"on\", symbols from all shared object libraries will be loaded\n\
+automatically when the inferior begins execution, when the dynamic linker\n\
+informs gdb that a new library has been loaded, or when attaching to the\n\
+inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.",
+ &setlist),
+ &showlist);
+
+ c = add_set_cmd ("solib-absolute-prefix", class_support, var_filename,
+ (char *) &solib_absolute_prefix,
+ "Set prefix for loading absolute shared library symbol files.\n\
+For other (relative) files, you can add values using `set solib-search-path'.",
+ &setlist);
+ add_show_from_set (c, &showlist);
+ set_cmd_completer (c, filename_completer);
+
+ c = add_set_cmd ("solib-search-path", class_support, var_string,
+ (char *) &solib_search_path,
+ "Set the search path for loading non-absolute shared library symbol files.\n\
+This takes precedence over the environment variables PATH and LD_LIBRARY_PATH.",
+ &setlist);
+ add_show_from_set (c, &showlist);
+ set_cmd_completer (c, filename_completer);
+}
diff --git a/gdb/solib.h b/gdb/solib.h
new file mode 100644
index 00000000000..04be72da465
--- /dev/null
+++ b/gdb/solib.h
@@ -0,0 +1,204 @@
+/* Shared library declarations for GDB, the GNU Debugger.
+ Copyright 1992, 1993, 1995, 1998, 1999, 2000, 2001
+ 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. */
+
+#ifndef SOLIB_H
+#define SOLIB_H
+
+/* Forward decl's for prototypes */
+struct target_ops;
+
+/* Called when we free all symtabs, to free the shared library information
+ as well. */
+
+#define CLEAR_SOLIB clear_solib
+
+extern void clear_solib (void);
+
+/* Called to add symbols from a shared library to gdb's symbol table. */
+
+#define SOLIB_ADD(filename, from_tty, targ, readsyms) \
+ solib_add (filename, from_tty, targ, readsyms)
+
+extern void solib_add (char *, int, struct target_ops *, int);
+
+/* Function to be called when the inferior starts up, to discover the names
+ of shared libraries that are dynamically linked, the base addresses to
+ which they are linked, and sufficient information to read in their symbols
+ at a later time. */
+
+#define SOLIB_CREATE_INFERIOR_HOOK(PID) solib_create_inferior_hook()
+
+/* Function to be called to remove the connection between debugger and
+ dynamic linker that was established by SOLIB_CREATE_INFERIOR_HOOK.
+ (This operation does not remove shared library information from
+ the debugger, as CLEAR_SOLIB does.)
+
+ This functionality is presently not implemented for this target.
+ */
+#define SOLIB_REMOVE_INFERIOR_HOOK(PID) (0)
+
+extern void solib_create_inferior_hook (void); /* solib.c */
+
+/* This function is called by the "catch load" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is loaded.
+
+ Presently, this functionality is not implemented.
+ */
+#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag,filename,cond_string) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+
+/* This function is called by the "catch unload" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is unloaded.
+
+ Presently, this functionality is not implemented.
+ */
+#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename,cond_string) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+
+/* This function returns TRUE if the dynamic linker has just reported
+ a load of a library.
+
+ This function must be used only when the inferior has stopped in
+ the dynamic linker hook, or undefined results are guaranteed.
+
+ Presently, this functionality is not implemented.
+ */
+
+/*
+ #define SOLIB_HAVE_LOAD_EVENT(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+ */
+
+#define SOLIB_HAVE_LOAD_EVENT(pid) \
+(0)
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been loaded.
+
+ This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the inferior
+ has stopped in the dynamic linker hook, and becomes invalid as soon
+ as the inferior is continued. Clients should make a copy of this
+ string if they wish to continue the inferior and then access the string.
+
+ Presently, this functionality is not implemented.
+ */
+
+/*
+ #define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+ */
+
+#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \
+(0)
+
+/* This function returns TRUE if the dynamic linker has just reported
+ an unload of a library.
+
+ This function must be used only when the inferior has stopped in
+ the dynamic linker hook, or undefined results are guaranteed.
+
+ Presently, this functionality is not implemented.
+ */
+/*
+ #define SOLIB_HAVE_UNLOAD_EVENT(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+ */
+
+#define SOLIB_HAVE_UNLOAD_EVENT(pid) \
+(0)
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been unloaded.
+
+ This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the inferior
+ has stopped in the dynamic linker hook, and becomes invalid as soon
+ as the inferior is continued. Clients should make a copy of this
+ string if they wish to continue the inferior and then access the string.
+
+ Presently, this functionality is not implemented.
+ */
+/*
+ #define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+ */
+
+#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \
+(0)
+
+/* This function returns TRUE if pc is the address of an instruction that
+ lies within the dynamic linker (such as the event hook, or the dld
+ itself).
+
+ This function must be used only when a dynamic linker event has been
+ caught, and the inferior is being stepped out of the hook, or undefined
+ results are guaranteed.
+
+ Presently, this functionality is not implemented.
+ */
+
+/*
+ #define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \
+ error("catch of library loads/unloads not yet implemented on this platform")
+ */
+
+#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \
+(0)
+
+/* This function must be called when the inferior is killed, and the program
+ restarted. This is not the same as CLEAR_SOLIB, in that it doesn't discard
+ any symbol tables.
+
+ Presently, this functionality is not implemented.
+ */
+#define SOLIB_RESTART() \
+ (0)
+
+/* If we can't set a breakpoint, and it's in a shared library, just
+ disable it. */
+
+#define DISABLE_UNSETTABLE_BREAK(addr) (solib_address(addr) != NULL)
+
+extern char *solib_address (CORE_ADDR); /* solib.c */
+
+/* If ADDR lies in a shared library, return its name. */
+
+#define PC_SOLIB(addr) solib_address (addr)
+
+/* Return 1 if PC lies in the dynamic symbol resolution code of the
+ run time loader. */
+
+#define IN_SOLIB_DYNSYM_RESOLVE_CODE(pc) in_solib_dynsym_resolve_code (pc)
+
+extern int in_solib_dynsym_resolve_code (CORE_ADDR); /* solib.c */
+
+/* Discard symbols that were auto-loaded from shared libraries. */
+
+extern void no_shared_libraries (char *ignored, int from_tty);
+
+#endif /* SOLIB_H */
diff --git a/gdb/solist.h b/gdb/solist.h
new file mode 100644
index 00000000000..dd1100c31cf
--- /dev/null
+++ b/gdb/solist.h
@@ -0,0 +1,126 @@
+/* Shared library declarations for GDB, the GNU Debugger.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
+ 2001
+ 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. */
+
+#ifndef SOLIST_H
+#define SOLIST_H
+
+#define SO_NAME_MAX_PATH_SIZE 512 /* FIXME: Should be dynamic */
+
+/* Forward declaration for target specific link map information. This
+ struct is opaque to all but the target specific file. */
+struct lm_info;
+
+struct so_list
+ {
+ /* The following fields of the structure come directly from the
+ dynamic linker's tables in the inferior, and are initialized by
+ current_sos. */
+
+ struct so_list *next; /* next structure in linked list */
+
+ /* A pointer to target specific link map information. Often this
+ will be a copy of struct link_map from the user process, but
+ it need not be; it can be any collection of data needed to
+ traverse the dynamic linker's data structures. */
+ struct lm_info *lm_info;
+
+ /* Shared object file name, exactly as it appears in the
+ inferior's link map. This may be a relative path, or something
+ which needs to be looked up in LD_LIBRARY_PATH, etc. We use it
+ to tell which entries in the inferior's dynamic linker's link
+ map we've already loaded. */
+ char so_original_name[SO_NAME_MAX_PATH_SIZE];
+
+ /* shared object file name, expanded to something GDB can open */
+ char so_name[SO_NAME_MAX_PATH_SIZE];
+
+ /* The following fields of the structure are built from
+ information gathered from the shared object file itself, and
+ are set when we actually add it to our symbol tables.
+
+ current_sos must initialize these fields to 0. */
+
+ bfd *abfd;
+ char symbols_loaded; /* flag: symbols read in yet? */
+ char from_tty; /* flag: print msgs? */
+ struct objfile *objfile; /* objfile for loaded lib */
+ struct section_table *sections;
+ struct section_table *sections_end;
+ struct section_table *textsection;
+ };
+
+struct target_so_ops
+ {
+ /* Adjust the section binding addresses by the base address at
+ which the object was actually mapped. */
+ void (*relocate_section_addresses) (struct so_list *so,
+ struct section_table *);
+
+ /* Free the the link map info and any other private data
+ structures associated with a so_list entry. */
+ void (*free_so) (struct so_list *so);
+
+ /* Reset or free private data structures not associated with
+ so_list entries. */
+ void (*clear_solib) (void);
+
+ /* Target dependent code to run after child process fork. */
+ void (*solib_create_inferior_hook) (void);
+
+ /* Do additional symbol handling, lookup, etc. after symbols
+ for a shared object have been loaded. */
+ void (*special_symbol_handling) (void);
+
+ /* Construct a list of the currently loaded shared objects. */
+ struct so_list *(*current_sos) (void);
+
+ /* Find, open, and read the symbols for the main executable. */
+ int (*open_symbol_file_object) (void *from_ttyp);
+
+ /* Determine if PC lies in the dynamic symbol resolution code of
+ the run time loader */
+ int (*in_dynsym_resolve_code) (CORE_ADDR pc);
+ };
+
+void free_so (struct so_list *so);
+
+/* Find solib binary file and open it. */
+extern int solib_open (char *in_pathname, char **found_pathname);
+
+/* FIXME: gdbarch needs to control this variable */
+extern struct target_so_ops *current_target_so_ops;
+
+#define TARGET_SO_RELOCATE_SECTION_ADDRESSES \
+ (current_target_so_ops->relocate_section_addresses)
+#define TARGET_SO_FREE_SO (current_target_so_ops->free_so)
+#define TARGET_SO_CLEAR_SOLIB (current_target_so_ops->clear_solib)
+#define TARGET_SO_SOLIB_CREATE_INFERIOR_HOOK \
+ (current_target_so_ops->solib_create_inferior_hook)
+#define TARGET_SO_SPECIAL_SYMBOL_HANDLING \
+ (current_target_so_ops->special_symbol_handling)
+#define TARGET_SO_CURRENT_SOS (current_target_so_ops->current_sos)
+#define TARGET_SO_OPEN_SYMBOL_FILE_OBJECT \
+ (current_target_so_ops->open_symbol_file_object)
+#define TARGET_SO_IN_DYNSYM_RESOLVE_CODE \
+ (current_target_so_ops->in_dynsym_resolve_code)
+
+#endif
diff --git a/gdb/somread.c b/gdb/somread.c
new file mode 100644
index 00000000000..38e35b2e7bb
--- /dev/null
+++ b/gdb/somread.c
@@ -0,0 +1,734 @@
+/* Read HP PA/Risc object files for GDB.
+ Copyright 1991, 1992, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ Written by Fred Fish at 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 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 "defs.h"
+#include "bfd.h"
+#include <syms.h>
+#include "symtab.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "stabsread.h"
+#include "gdb-stabs.h"
+#include "complaints.h"
+#include "gdb_string.h"
+#include "demangle.h"
+#include "som.h"
+#include "libhppa.h"
+
+/* Various things we might complain about... */
+
+static void som_symfile_init (struct objfile *);
+
+static void som_new_init (struct objfile *);
+
+static void som_symfile_read (struct objfile *, int);
+
+static void som_symfile_finish (struct objfile *);
+
+static void
+som_symtab_read (bfd *, struct objfile *, struct section_offsets *);
+
+static void
+som_symfile_offsets (struct objfile *, struct section_addr_info *);
+
+/* FIXME: These should really be in a common header somewhere */
+
+extern void hpread_build_psymtabs (struct objfile *, int);
+
+extern void hpread_symfile_finish (struct objfile *);
+
+extern void hpread_symfile_init (struct objfile *);
+
+extern void do_pxdb (bfd *);
+
+/*
+
+ LOCAL FUNCTION
+
+ som_symtab_read -- read the symbol table of a SOM file
+
+ SYNOPSIS
+
+ void som_symtab_read (bfd *abfd, struct objfile *objfile,
+ struct section_offsets *section_offsets)
+
+ DESCRIPTION
+
+ Given an open bfd, a base address to relocate symbols to, and a
+ flag that specifies whether or not this bfd is for an executable
+ or not (may be shared library for example), add all the global
+ function and data symbols to the minimal symbol table.
+ */
+
+static void
+som_symtab_read (bfd *abfd, struct objfile *objfile,
+ struct section_offsets *section_offsets)
+{
+ unsigned int number_of_symbols;
+ int val, dynamic;
+ char *stringtab;
+ asection *shlib_info;
+ struct symbol_dictionary_record *buf, *bufp, *endbufp;
+ char *symname;
+ CONST int symsize = sizeof (struct symbol_dictionary_record);
+ CORE_ADDR text_offset, data_offset;
+
+
+ text_offset = ANOFFSET (section_offsets, 0);
+ data_offset = ANOFFSET (section_offsets, 1);
+
+ number_of_symbols = bfd_get_symcount (abfd);
+
+ /* FIXME (alloca): could be quite large. */
+ buf = alloca (symsize * number_of_symbols);
+ bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET);
+ val = bfd_bread (buf, symsize * number_of_symbols, abfd);
+ if (val != symsize * number_of_symbols)
+ error ("Couldn't read symbol dictionary!");
+
+ /* FIXME (alloca): could be quite large. */
+ stringtab = alloca (obj_som_stringtab_size (abfd));
+ bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET);
+ val = bfd_bread (stringtab, obj_som_stringtab_size (abfd), abfd);
+ if (val != obj_som_stringtab_size (abfd))
+ error ("Can't read in HP string table.");
+
+ /* We need to determine if objfile is a dynamic executable (so we
+ can do the right thing for ST_ENTRY vs ST_CODE symbols).
+
+ There's nothing in the header which easily allows us to do
+ this.
+
+ This code used to rely upon the existence of a $SHLIB_INFO$
+ section to make this determination. HP claims that it is
+ more accurate to check for a nonzero text offset, but they
+ have not provided any information about why that test is
+ more accurate. */
+ dynamic = (text_offset != 0);
+
+ endbufp = buf + number_of_symbols;
+ for (bufp = buf; bufp < endbufp; ++bufp)
+ {
+ enum minimal_symbol_type ms_type;
+
+ QUIT;
+
+ switch (bufp->symbol_scope)
+ {
+ case SS_UNIVERSAL:
+ case SS_EXTERNAL:
+ switch (bufp->symbol_type)
+ {
+ case ST_SYM_EXT:
+ case ST_ARG_EXT:
+ continue;
+
+ case ST_CODE:
+ case ST_PRI_PROG:
+ case ST_SEC_PROG:
+ case ST_MILLICODE:
+ symname = bufp->name.n_strx + stringtab;
+ ms_type = mst_text;
+ bufp->symbol_value += text_offset;
+ bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
+ break;
+
+ case ST_ENTRY:
+ symname = bufp->name.n_strx + stringtab;
+ /* For a dynamic executable, ST_ENTRY symbols are
+ the stubs, while the ST_CODE symbol is the real
+ function. */
+ if (dynamic)
+ ms_type = mst_solib_trampoline;
+ else
+ ms_type = mst_text;
+ bufp->symbol_value += text_offset;
+ bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
+ break;
+
+ case ST_STUB:
+ symname = bufp->name.n_strx + stringtab;
+ ms_type = mst_solib_trampoline;
+ bufp->symbol_value += text_offset;
+ bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
+ break;
+
+ case ST_DATA:
+ symname = bufp->name.n_strx + stringtab;
+ bufp->symbol_value += data_offset;
+ ms_type = mst_data;
+ break;
+ default:
+ continue;
+ }
+ break;
+
+#if 0
+ /* SS_GLOBAL and SS_LOCAL are two names for the same thing (!). */
+ case SS_GLOBAL:
+#endif
+ case SS_LOCAL:
+ switch (bufp->symbol_type)
+ {
+ case ST_SYM_EXT:
+ case ST_ARG_EXT:
+ continue;
+
+ case ST_CODE:
+ symname = bufp->name.n_strx + stringtab;
+ ms_type = mst_file_text;
+ bufp->symbol_value += text_offset;
+ bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
+
+ check_strange_names:
+ /* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local
+ label prefixes for stabs, constant data, etc. So we need
+ only filter out L$ symbols which are left in due to
+ limitations in how GAS generates SOM relocations.
+
+ When linking in the HPUX C-library the HP linker has
+ the nasty habit of placing section symbols from the literal
+ subspaces in the middle of the program's text. Filter
+ those out as best we can. Check for first and last character
+ being '$'.
+
+ And finally, the newer HP compilers emit crud like $PIC_foo$N
+ in some circumstance (PIC code I guess). It's also claimed
+ that they emit D$ symbols too. What stupidity. */
+ if ((symname[0] == 'L' && symname[1] == '$')
+ || (symname[0] == '$' && symname[strlen (symname) - 1] == '$')
+ || (symname[0] == 'D' && symname[1] == '$')
+ || (strncmp (symname, "$PIC", 4) == 0))
+ continue;
+ break;
+
+ case ST_PRI_PROG:
+ case ST_SEC_PROG:
+ case ST_MILLICODE:
+ symname = bufp->name.n_strx + stringtab;
+ ms_type = mst_file_text;
+ bufp->symbol_value += text_offset;
+ bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
+ break;
+
+ case ST_ENTRY:
+ symname = bufp->name.n_strx + stringtab;
+ /* SS_LOCAL symbols in a shared library do not have
+ export stubs, so we do not have to worry about
+ using mst_file_text vs mst_solib_trampoline here like
+ we do for SS_UNIVERSAL and SS_EXTERNAL symbols above. */
+ ms_type = mst_file_text;
+ bufp->symbol_value += text_offset;
+ bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
+ break;
+
+ case ST_STUB:
+ symname = bufp->name.n_strx + stringtab;
+ ms_type = mst_solib_trampoline;
+ bufp->symbol_value += text_offset;
+ bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
+ break;
+
+
+ case ST_DATA:
+ symname = bufp->name.n_strx + stringtab;
+ bufp->symbol_value += data_offset;
+ ms_type = mst_file_data;
+ goto check_strange_names;
+
+ default:
+ continue;
+ }
+ break;
+
+ /* This can happen for common symbols when -E is passed to the
+ final link. No idea _why_ that would make the linker force
+ common symbols to have an SS_UNSAT scope, but it does.
+
+ This also happens for weak symbols, but their type is
+ ST_DATA. */
+ case SS_UNSAT:
+ switch (bufp->symbol_type)
+ {
+ case ST_STORAGE:
+ case ST_DATA:
+ symname = bufp->name.n_strx + stringtab;
+ bufp->symbol_value += data_offset;
+ ms_type = mst_data;
+ break;
+
+ default:
+ continue;
+ }
+ break;
+
+ default:
+ continue;
+ }
+
+ if (bufp->name.n_strx > obj_som_stringtab_size (abfd))
+ error ("Invalid symbol data; bad HP string table offset: %d",
+ bufp->name.n_strx);
+
+ prim_record_minimal_symbol (symname, bufp->symbol_value, ms_type,
+ objfile);
+ }
+}
+
+/* Scan and build partial symbols for a symbol file.
+ We have been initialized by a call to som_symfile_init, which
+ currently does nothing.
+
+ SECTION_OFFSETS is a set of offsets to apply to relocate the symbols
+ in each section. This is ignored, as it isn't needed for SOM.
+
+ MAINLINE is true if we are reading the main symbol
+ table (as opposed to a shared lib or dynamically loaded file).
+
+ This function only does the minimum work necessary for letting the
+ user "name" things symbolically; it does not read the entire symtab.
+ Instead, it reads the external and static symbols and puts them in partial
+ symbol tables. When more extensive information is requested of a
+ file, the corresponding partial symbol table is mutated into a full
+ fledged symbol table by going back and reading the symbols
+ for real.
+
+ We look for sections with specific names, to tell us what debug
+ format to look for: FIXME!!!
+
+ somstab_build_psymtabs() handles STABS symbols.
+
+ Note that SOM files have a "minimal" symbol table, which is vaguely
+ reminiscent of a COFF symbol table, but has only the minimal information
+ necessary for linking. We process this also, and use the information to
+ build gdb's minimal symbol table. This gives us some minimal debugging
+ capability even for files compiled without -g. */
+
+static void
+som_symfile_read (struct objfile *objfile, int mainline)
+{
+ bfd *abfd = objfile->obfd;
+ struct cleanup *back_to;
+
+ do_pxdb (symfile_bfd_open (objfile->name));
+
+ init_minimal_symbol_collection ();
+ back_to = make_cleanup_discard_minimal_symbols ();
+
+ /* Read in the import list and the export list. Currently
+ the export list isn't used; the import list is used in
+ hp-symtab-read.c to handle static vars declared in other
+ shared libraries. */
+ init_import_symbols (objfile);
+#if 0 /* Export symbols not used today 1997-08-05 */
+ init_export_symbols (objfile);
+#else
+ objfile->export_list = NULL;
+ objfile->export_list_size = 0;
+#endif
+
+ /* Process the normal SOM symbol table first.
+ This reads in the DNTT and string table, but doesn't
+ actually scan the DNTT. It does scan the linker symbol
+ table and thus build up a "minimal symbol table". */
+
+ som_symtab_read (abfd, objfile, objfile->section_offsets);
+
+ /* Now read information from the stabs debug sections.
+ This is a no-op for SOM.
+ Perhaps it is intended for some kind of mixed STABS/SOM
+ situation? */
+ stabsect_build_psymtabs (objfile, mainline,
+ "$GDB_SYMBOLS$", "$GDB_STRINGS$", "$TEXT$");
+
+ /* Now read the native debug information.
+ This builds the psymtab. This used to be done via a scan of
+ the DNTT, but is now done via the PXDB-built quick-lookup tables
+ together with a scan of the GNTT. See hp-psymtab-read.c. */
+ hpread_build_psymtabs (objfile, mainline);
+
+ /* Install any minimal symbols that have been collected as the current
+ minimal symbols for this objfile.
+ Further symbol-reading is done incrementally, file-by-file,
+ in a step known as "psymtab-to-symtab" expansion. hp-symtab-read.c
+ contains the code to do the actual DNTT scanning and symtab building. */
+ install_minimal_symbols (objfile);
+
+ /* Force hppa-tdep.c to re-read the unwind descriptors. */
+ objfile->obj_private = NULL;
+ do_cleanups (back_to);
+}
+
+/* Initialize anything that needs initializing when a completely new symbol
+ file is specified (not just adding some symbols from another file, e.g. a
+ shared library).
+
+ We reinitialize buildsym, since we may be reading stabs from a SOM file. */
+
+static void
+som_new_init (struct objfile *ignore)
+{
+ stabsread_new_init ();
+ buildsym_new_init ();
+}
+
+/* Perform any local cleanups required when we are done with a particular
+ objfile. I.E, we are in the process of discarding all symbol information
+ for an objfile, freeing up all memory held for it, and unlinking the
+ objfile struct from the global list of known objfiles. */
+
+static void
+som_symfile_finish (struct objfile *objfile)
+{
+ if (objfile->sym_stab_info != NULL)
+ {
+ xmfree (objfile->md, objfile->sym_stab_info);
+ }
+ hpread_symfile_finish (objfile);
+}
+
+/* SOM specific initialization routine for reading symbols. */
+
+static void
+som_symfile_init (struct objfile *objfile)
+{
+ /* SOM objects may be reordered, so set OBJF_REORDERED. If we
+ find this causes a significant slowdown in gdb then we could
+ set it in the debug symbol readers only when necessary. */
+ objfile->flags |= OBJF_REORDERED;
+ hpread_symfile_init (objfile);
+}
+
+/* SOM specific parsing routine for section offsets.
+
+ Plain and simple for now. */
+
+static void
+som_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs)
+{
+ int i;
+ CORE_ADDR text_addr;
+
+ objfile->num_sections = SECT_OFF_MAX;
+ objfile->section_offsets = (struct section_offsets *)
+ obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
+
+ /* FIXME: ezannoni 2000-04-20 The section names in SOM are not
+ .text, .data, etc, but $TEXT$, $DATA$,... We should initialize
+ SET_OFF_* from bfd. (See default_symfile_offsets()). But I don't
+ know the correspondence between SOM sections and GDB's idea of
+ section names. So for now we default to what is was before these
+ changes.*/
+ objfile->sect_index_text = 0;
+ objfile->sect_index_data = 1;
+ objfile->sect_index_bss = 2;
+ objfile->sect_index_rodata = 3;
+
+ /* First see if we're a shared library. If so, get the section
+ offsets from the library, else get them from addrs. */
+ if (!som_solib_section_offsets (objfile, objfile->section_offsets))
+ {
+ /* Note: Here is OK to compare with ".text" because this is the
+ name that gdb itself gives to that section, not the SOM
+ name. */
+ for (i = 0; i < SECT_OFF_MAX && addrs->other[i].name; i++)
+ if (strcmp (addrs->other[i].name, ".text") == 0)
+ break;
+ text_addr = addrs->other[i].addr;
+
+ for (i = 0; i < SECT_OFF_MAX; i++)
+ (objfile->section_offsets)->offsets[i] = text_addr;
+ }
+}
+
+/* Read in and initialize the SOM import list which is present
+ for all executables and shared libraries. The import list
+ consists of the symbols that are referenced in OBJFILE but
+ not defined there. (Variables that are imported are dealt
+ with as "loc_indirect" vars.)
+ Return value = number of import symbols read in. */
+int
+init_import_symbols (struct objfile *objfile)
+{
+ unsigned int import_list;
+ unsigned int import_list_size;
+ unsigned int string_table;
+ unsigned int string_table_size;
+ char *string_buffer;
+ register int i;
+ register int j;
+ register int k;
+ asection *text_section; /* section handle */
+ unsigned int dl_header[12]; /* SOM executable header */
+
+ /* A struct for an entry in the SOM import list */
+ typedef struct
+ {
+ int name; /* index into the string table */
+ short dont_care1; /* we don't use this */
+ unsigned char type; /* 0 = NULL, 2 = Data, 3 = Code, 7 = Storage, 13 = Plabel */
+ unsigned int reserved2:8; /* not used */
+ }
+ SomImportEntry;
+
+ /* We read 100 entries in at a time from the disk file. */
+#define SOM_READ_IMPORTS_NUM 100
+#define SOM_READ_IMPORTS_CHUNK_SIZE (sizeof (SomImportEntry) * SOM_READ_IMPORTS_NUM)
+ SomImportEntry buffer[SOM_READ_IMPORTS_NUM];
+
+ /* Initialize in case we error out */
+ objfile->import_list = NULL;
+ objfile->import_list_size = 0;
+
+ /* It doesn't work, for some reason, to read in space $TEXT$;
+ the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */
+ text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
+ if (!text_section)
+ return 0;
+ /* Get the SOM executable header */
+ bfd_get_section_contents (objfile->obfd, text_section, dl_header, 0, 12 * sizeof (int));
+
+ /* Check header version number for 10.x HP-UX */
+ /* Currently we deal only with 10.x systems; on 9.x the version # is 89060912.
+ FIXME: Change for future HP-UX releases and mods to the SOM executable format */
+ if (dl_header[0] != 93092112)
+ return 0;
+
+ import_list = dl_header[4];
+ import_list_size = dl_header[5];
+ if (!import_list_size)
+ return 0;
+ string_table = dl_header[10];
+ string_table_size = dl_header[11];
+ if (!string_table_size)
+ return 0;
+
+ /* Suck in SOM string table */
+ string_buffer = (char *) xmalloc (string_table_size);
+ bfd_get_section_contents (objfile->obfd, text_section, string_buffer,
+ string_table, string_table_size);
+
+ /* Allocate import list in the psymbol obstack; this has nothing
+ to do with psymbols, just a matter of convenience. We want the
+ import list to be freed when the objfile is deallocated */
+ objfile->import_list
+ = (ImportEntry *) obstack_alloc (&objfile->psymbol_obstack,
+ import_list_size * sizeof (ImportEntry));
+
+ /* Read in the import entries, a bunch at a time */
+ for (j = 0, k = 0;
+ j < (import_list_size / SOM_READ_IMPORTS_NUM);
+ j++)
+ {
+ bfd_get_section_contents (objfile->obfd, text_section, buffer,
+ import_list + j * SOM_READ_IMPORTS_CHUNK_SIZE,
+ SOM_READ_IMPORTS_CHUNK_SIZE);
+ for (i = 0; i < SOM_READ_IMPORTS_NUM; i++, k++)
+ {
+ if (buffer[i].type != (unsigned char) 0)
+ {
+ objfile->import_list[k]
+ = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1);
+ strcpy (objfile->import_list[k], string_buffer + buffer[i].name);
+ /* Some day we might want to record the type and other information too */
+ }
+ else /* null type */
+ objfile->import_list[k] = NULL;
+
+ }
+ }
+
+ /* Get the leftovers */
+ if (k < import_list_size)
+ bfd_get_section_contents (objfile->obfd, text_section, buffer,
+ import_list + k * sizeof (SomImportEntry),
+ (import_list_size - k) * sizeof (SomImportEntry));
+ for (i = 0; k < import_list_size; i++, k++)
+ {
+ if (buffer[i].type != (unsigned char) 0)
+ {
+ objfile->import_list[k]
+ = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1);
+ strcpy (objfile->import_list[k], string_buffer + buffer[i].name);
+ /* Some day we might want to record the type and other information too */
+ }
+ else
+ objfile->import_list[k] = NULL;
+ }
+
+ objfile->import_list_size = import_list_size;
+ xfree (string_buffer);
+ return import_list_size;
+}
+
+/* Read in and initialize the SOM export list which is present
+ for all executables and shared libraries. The import list
+ consists of the symbols that are referenced in OBJFILE but
+ not defined there. (Variables that are imported are dealt
+ with as "loc_indirect" vars.)
+ Return value = number of import symbols read in. */
+int
+init_export_symbols (struct objfile *objfile)
+{
+ unsigned int export_list;
+ unsigned int export_list_size;
+ unsigned int string_table;
+ unsigned int string_table_size;
+ char *string_buffer;
+ register int i;
+ register int j;
+ register int k;
+ asection *text_section; /* section handle */
+ unsigned int dl_header[12]; /* SOM executable header */
+
+ /* A struct for an entry in the SOM export list */
+ typedef struct
+ {
+ int next; /* for hash table use -- we don't use this */
+ int name; /* index into string table */
+ int value; /* offset or plabel */
+ int dont_care1; /* not used */
+ unsigned char type; /* 0 = NULL, 2 = Data, 3 = Code, 7 = Storage, 13 = Plabel */
+ char dont_care2; /* not used */
+ short dont_care3; /* not used */
+ }
+ SomExportEntry;
+
+ /* We read 100 entries in at a time from the disk file. */
+#define SOM_READ_EXPORTS_NUM 100
+#define SOM_READ_EXPORTS_CHUNK_SIZE (sizeof (SomExportEntry) * SOM_READ_EXPORTS_NUM)
+ SomExportEntry buffer[SOM_READ_EXPORTS_NUM];
+
+ /* Initialize in case we error out */
+ objfile->export_list = NULL;
+ objfile->export_list_size = 0;
+
+ /* It doesn't work, for some reason, to read in space $TEXT$;
+ the subspace $SHLIB_INFO$ has to be used. Some BFD quirk? pai/1997-08-05 */
+ text_section = bfd_get_section_by_name (objfile->obfd, "$SHLIB_INFO$");
+ if (!text_section)
+ return 0;
+ /* Get the SOM executable header */
+ bfd_get_section_contents (objfile->obfd, text_section, dl_header, 0, 12 * sizeof (int));
+
+ /* Check header version number for 10.x HP-UX */
+ /* Currently we deal only with 10.x systems; on 9.x the version # is 89060912.
+ FIXME: Change for future HP-UX releases and mods to the SOM executable format */
+ if (dl_header[0] != 93092112)
+ return 0;
+
+ export_list = dl_header[8];
+ export_list_size = dl_header[9];
+ if (!export_list_size)
+ return 0;
+ string_table = dl_header[10];
+ string_table_size = dl_header[11];
+ if (!string_table_size)
+ return 0;
+
+ /* Suck in SOM string table */
+ string_buffer = (char *) xmalloc (string_table_size);
+ bfd_get_section_contents (objfile->obfd, text_section, string_buffer,
+ string_table, string_table_size);
+
+ /* Allocate export list in the psymbol obstack; this has nothing
+ to do with psymbols, just a matter of convenience. We want the
+ export list to be freed when the objfile is deallocated */
+ objfile->export_list
+ = (ExportEntry *) obstack_alloc (&objfile->psymbol_obstack,
+ export_list_size * sizeof (ExportEntry));
+
+ /* Read in the export entries, a bunch at a time */
+ for (j = 0, k = 0;
+ j < (export_list_size / SOM_READ_EXPORTS_NUM);
+ j++)
+ {
+ bfd_get_section_contents (objfile->obfd, text_section, buffer,
+ export_list + j * SOM_READ_EXPORTS_CHUNK_SIZE,
+ SOM_READ_EXPORTS_CHUNK_SIZE);
+ for (i = 0; i < SOM_READ_EXPORTS_NUM; i++, k++)
+ {
+ if (buffer[i].type != (unsigned char) 0)
+ {
+ objfile->export_list[k].name
+ = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1);
+ strcpy (objfile->export_list[k].name, string_buffer + buffer[i].name);
+ objfile->export_list[k].address = buffer[i].value;
+ /* Some day we might want to record the type and other information too */
+ }
+ else
+ /* null type */
+ {
+ objfile->export_list[k].name = NULL;
+ objfile->export_list[k].address = 0;
+ }
+ }
+ }
+
+ /* Get the leftovers */
+ if (k < export_list_size)
+ bfd_get_section_contents (objfile->obfd, text_section, buffer,
+ export_list + k * sizeof (SomExportEntry),
+ (export_list_size - k) * sizeof (SomExportEntry));
+ for (i = 0; k < export_list_size; i++, k++)
+ {
+ if (buffer[i].type != (unsigned char) 0)
+ {
+ objfile->export_list[k].name
+ = (char *) obstack_alloc (&objfile->psymbol_obstack, strlen (string_buffer + buffer[i].name) + 1);
+ strcpy (objfile->export_list[k].name, string_buffer + buffer[i].name);
+ /* Some day we might want to record the type and other information too */
+ objfile->export_list[k].address = buffer[i].value;
+ }
+ else
+ {
+ objfile->export_list[k].name = NULL;
+ objfile->export_list[k].address = 0;
+ }
+ }
+
+ objfile->export_list_size = export_list_size;
+ xfree (string_buffer);
+ return export_list_size;
+}
+
+
+
+/* Register that we are able to handle SOM object file formats. */
+
+static struct sym_fns som_sym_fns =
+{
+ bfd_target_som_flavour,
+ som_new_init, /* sym_new_init: init anything gbl to entire symtab */
+ som_symfile_init, /* sym_init: read initial info, setup for sym_read() */
+ som_symfile_read, /* sym_read: read a symbol file into symtab */
+ som_symfile_finish, /* sym_finish: finished with file, cleanup */
+ som_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */
+ NULL /* next: pointer to next struct sym_fns */
+};
+
+void
+_initialize_somread (void)
+{
+ add_symtab_fns (&som_sym_fns);
+}
diff --git a/gdb/somsolib.c b/gdb/somsolib.c
new file mode 100644
index 00000000000..d623e4b76db
--- /dev/null
+++ b/gdb/somsolib.c
@@ -0,0 +1,1616 @@
+/* Handle HP SOM shared libraries for GDB, the GNU Debugger.
+ Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+ 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.
+
+ Written by the Center for Software Science at the Univerity of Utah
+ and by Cygnus Support. */
+
+
+#include "defs.h"
+
+#include "frame.h"
+#include "bfd.h"
+#include "som.h"
+#include "libhppa.h"
+#include "gdbcore.h"
+#include "symtab.h"
+#include "breakpoint.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "inferior.h"
+#include "gdb-stabs.h"
+#include "gdb_stat.h"
+#include "gdbcmd.h"
+#include "assert.h"
+#include "language.h"
+#include "regcache.h"
+
+#include <fcntl.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/* Uncomment this to turn on some debugging output.
+ */
+
+/* #define SOLIB_DEBUG
+ */
+
+/* Defined in exec.c; used to prevent dangling pointer bug.
+ */
+extern struct target_ops exec_ops;
+
+/* This lives in hppa-tdep.c. */
+extern struct unwind_table_entry *find_unwind_entry (CORE_ADDR pc);
+
+/* These ought to be defined in some public interface, but aren't. They
+ define the meaning of the various bits in the distinguished __dld_flags
+ variable that is declared in every debuggable a.out on HP-UX, and that
+ is shared between the debugger and the dynamic linker.
+ */
+#define DLD_FLAGS_MAPPRIVATE 0x1
+#define DLD_FLAGS_HOOKVALID 0x2
+#define DLD_FLAGS_LISTVALID 0x4
+#define DLD_FLAGS_BOR_ENABLE 0x8
+
+/* TODO:
+
+ * Most of this code should work for hp300 shared libraries. Does
+ anyone care enough to weed out any SOM-isms.
+
+ * Support for hpux8 dynamic linker. */
+
+/* The basic structure which describes a dynamically loaded object. This
+ data structure is private to the dynamic linker and isn't found in
+ any HPUX include file. */
+
+struct som_solib_mapped_entry
+ {
+ /* The name of the library. */
+ char *name;
+
+ /* Version of this structure (it is expected to change again in hpux10). */
+ unsigned char struct_version;
+
+ /* Binding mode for this library. */
+ unsigned char bind_mode;
+
+ /* Version of this library. */
+ short library_version;
+
+ /* Start of text address,
+ * link-time text location (length of text area),
+ * end of text address. */
+ CORE_ADDR text_addr;
+ CORE_ADDR text_link_addr;
+ CORE_ADDR text_end;
+
+ /* Start of data, start of bss and end of data. */
+ CORE_ADDR data_start;
+ CORE_ADDR bss_start;
+ CORE_ADDR data_end;
+
+ /* Value of linkage pointer (%r19). */
+ CORE_ADDR got_value;
+
+ /* Next entry. */
+ struct som_solib_mapped_entry *next;
+
+ /* There are other fields, but I don't have information as to what is
+ contained in them. */
+
+ /* For versions from HPUX-10.30 and up */
+
+ /* Address in target of offset from thread-local register of
+ * start of this thread's data. I.e., the first thread-local
+ * variable in this shared library starts at *(tsd_start_addr)
+ * from that area pointed to by cr27 (mpsfu_hi).
+ *
+ * We do the indirection as soon as we read it, so from then
+ * on it's the offset itself.
+ */
+ CORE_ADDR tsd_start_addr;
+
+ /* Following this are longwords holding:
+
+ * ?, ?, ?, ptr to -1, ptr to-1, ptr to lib name (leaf name),
+ * ptr to __data_start, ptr to __data_end
+ */
+
+
+ };
+
+/* A structure to keep track of all the known shared objects. */
+struct so_list
+ {
+ struct som_solib_mapped_entry som_solib;
+ struct objfile *objfile;
+ bfd *abfd;
+ struct section_table *sections;
+ struct section_table *sections_end;
+/* elz: added this field to store the address in target space (in the
+ library) of the library descriptor (handle) which we read into
+ som_solib_mapped_entry structure */
+ CORE_ADDR solib_addr;
+ struct so_list *next;
+
+ };
+
+static struct so_list *so_list_head;
+
+
+/* This is the cumulative size in bytes of the symbol tables of all
+ shared objects on the so_list_head list. (When we say size, here
+ we mean of the information before it is brought into memory and
+ potentially expanded by GDB.) When adding a new shlib, this value
+ is compared against the threshold size, held by auto_solib_limit
+ (in megabytes). If adding symbols for the new shlib would cause
+ the total size to exceed the threshold, then the new shlib's
+ symbols are not loaded. */
+static LONGEST som_solib_total_st_size;
+
+/* When the threshold is reached for any shlib, we refuse to add
+ symbols for subsequent shlibs, even if those shlibs' symbols would
+ be small enough to fit under the threshold. (Although this may
+ result in one, early large shlib preventing the loading of later,
+ smalller shlibs' symbols, it allows us to issue one informational
+ message. The alternative, to issue a message for each shlib whose
+ symbols aren't loaded, could be a big annoyance where the threshold
+ is exceeded due to a very large number of shlibs.)
+ */
+static int som_solib_st_size_threshold_exceeded;
+
+/* These addresses should be filled in by som_solib_create_inferior_hook.
+ They are also used elsewhere in this module.
+ */
+typedef struct
+ {
+ CORE_ADDR address;
+ struct unwind_table_entry *unwind;
+ }
+addr_and_unwind_t;
+
+/* When adding fields, be sure to clear them in _initialize_som_solib. */
+static struct
+ {
+ boolean is_valid;
+ addr_and_unwind_t hook;
+ addr_and_unwind_t hook_stub;
+ addr_and_unwind_t load;
+ addr_and_unwind_t load_stub;
+ addr_and_unwind_t unload;
+ addr_and_unwind_t unload2;
+ addr_and_unwind_t unload_stub;
+ }
+dld_cache;
+
+
+
+static void som_sharedlibrary_info_command (char *, int);
+
+static void som_solib_sharedlibrary_command (char *, int);
+
+static LONGEST
+som_solib_sizeof_symbol_table (char *filename)
+{
+ bfd *abfd;
+ int desc;
+ char *absolute_name;
+ LONGEST st_size = (LONGEST) 0;
+ asection *sect;
+
+ /* We believe that filename was handed to us by the dynamic linker, and
+ is therefore always an absolute path.
+ */
+ desc = openp (getenv ("PATH"), 1, filename, O_RDONLY | O_BINARY, 0, &absolute_name);
+ if (desc < 0)
+ {
+ perror_with_name (filename);
+ }
+ filename = absolute_name;
+
+ abfd = bfd_fdopenr (filename, gnutarget, desc);
+ if (!abfd)
+ {
+ close (desc);
+ make_cleanup (xfree, filename);
+ error ("\"%s\": can't open to read symbols: %s.", filename,
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+ if (!bfd_check_format (abfd, bfd_object)) /* Reads in section info */
+ {
+ bfd_close (abfd); /* This also closes desc */
+ make_cleanup (xfree, filename);
+ error ("\"%s\": can't read symbols: %s.", filename,
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+ /* Sum the sizes of the various sections that compose debug info. */
+
+ /* This contains non-DOC information. */
+ sect = bfd_get_section_by_name (abfd, "$DEBUG$");
+ if (sect)
+ st_size += (LONGEST) bfd_section_size (abfd, sect);
+
+ /* This contains DOC information. */
+ sect = bfd_get_section_by_name (abfd, "$PINFO$");
+ if (sect)
+ st_size += (LONGEST) bfd_section_size (abfd, sect);
+
+ bfd_close (abfd); /* This also closes desc */
+ xfree (filename);
+
+ /* Unfortunately, just summing the sizes of various debug info
+ sections isn't a very accurate measurement of how much heap
+ space the debugger will need to hold them. It also doesn't
+ account for space needed by linker (aka "minimal") symbols.
+
+ Anecdotal evidence suggests that just summing the sizes of
+ debug-info-related sections understates the heap space needed
+ to represent it internally by about an order of magnitude.
+
+ Since it's not exactly brain surgery we're doing here, rather
+ than attempt to more accurately measure the size of a shlib's
+ symbol table in GDB's heap, we'll just apply a 10x fudge-
+ factor to the debug info sections' size-sum. No, this doesn't
+ account for minimal symbols in non-debuggable shlibs. But it
+ all roughly washes out in the end.
+ */
+ return st_size * (LONGEST) 10;
+}
+
+
+static void
+som_solib_add_solib_objfile (struct so_list *so, char *name, int from_tty,
+ CORE_ADDR text_addr)
+{
+ obj_private_data_t *obj_private;
+ struct obj_section *s;
+
+ so->objfile = symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED);
+ so->abfd = so->objfile->obfd;
+
+ /* syms_from_objfile has bizarre section offset code,
+ so I do my own right here. */
+ for (s = so->objfile->sections; s < so->objfile->sections_end; s++)
+ {
+ flagword aflag = bfd_get_section_flags(so->abfd, s->the_bfd_section);
+ if (aflag & SEC_CODE)
+ {
+ s->addr += so->som_solib.text_addr - so->som_solib.text_link_addr;
+ s->endaddr += so->som_solib.text_addr - so->som_solib.text_link_addr;
+ }
+ else if (aflag & SEC_DATA)
+ {
+ s->addr += so->som_solib.data_start;
+ s->endaddr += so->som_solib.data_start;
+ }
+ else
+ ;
+ }
+
+ /* Mark this as a shared library and save private data.
+ */
+ so->objfile->flags |= OBJF_SHARED;
+
+ if (so->objfile->obj_private == NULL)
+ {
+ obj_private = (obj_private_data_t *)
+ obstack_alloc (&so->objfile->psymbol_obstack,
+ sizeof (obj_private_data_t));
+ obj_private->unwind_info = NULL;
+ obj_private->so_info = NULL;
+ so->objfile->obj_private = (PTR) obj_private;
+ }
+
+ obj_private = (obj_private_data_t *) so->objfile->obj_private;
+ obj_private->so_info = so;
+
+ if (!bfd_check_format (so->abfd, bfd_object))
+ {
+ error ("\"%s\": not in executable format: %s.",
+ name, bfd_errmsg (bfd_get_error ()));
+ }
+}
+
+
+static void
+som_solib_load_symbols (struct so_list *so, char *name, int from_tty,
+ CORE_ADDR text_addr, struct target_ops *target)
+{
+ struct section_table *p;
+ int status;
+ char buf[4];
+ CORE_ADDR presumed_data_start;
+
+#ifdef SOLIB_DEBUG
+ printf ("--Adding symbols for shared library \"%s\"\n", name);
+#endif
+
+ som_solib_add_solib_objfile (so, name, from_tty, text_addr);
+
+ /* Now we need to build a section table for this library since
+ we might be debugging a core file from a dynamically linked
+ executable in which the libraries were not privately mapped. */
+ if (build_section_table (so->abfd,
+ &so->sections,
+ &so->sections_end))
+ {
+ error ("Unable to build section table for shared library\n.");
+ return;
+ }
+
+ /* Relocate all the sections based on where they got loaded. */
+ for (p = so->sections; p < so->sections_end; p++)
+ {
+ if (p->the_bfd_section->flags & SEC_CODE)
+ {
+ p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
+ p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
+ }
+ else if (p->the_bfd_section->flags & SEC_DATA)
+ {
+ p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
+ p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
+ }
+ }
+
+ /* Now see if we need to map in the text and data for this shared
+ library (for example debugging a core file which does not use
+ private shared libraries.).
+
+ Carefully peek at the first text address in the library. If the
+ read succeeds, then the libraries were privately mapped and were
+ included in the core dump file.
+
+ If the peek failed, then the libraries were not privately mapped
+ and are not in the core file, we'll have to read them in ourselves. */
+ status = target_read_memory (text_addr, buf, 4);
+ if (status != 0)
+ {
+ int old, new;
+
+ new = so->sections_end - so->sections;
+
+ old = target_resize_to_sections (target, new);
+
+ /* Copy over the old data before it gets clobbered. */
+ memcpy ((char *) (target->to_sections + old),
+ so->sections,
+ ((sizeof (struct section_table)) * new));
+ }
+}
+
+
+/* Add symbols from shared libraries into the symtab list, unless the
+ size threshold specified by auto_solib_limit (in megabytes) would
+ be exceeded. */
+
+void
+som_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms)
+{
+ struct minimal_symbol *msymbol;
+ struct so_list *so_list_tail;
+ CORE_ADDR addr;
+ asection *shlib_info;
+ int status;
+ unsigned int dld_flags;
+ char buf[4], *re_err;
+ int threshold_warning_given = 0;
+
+ /* First validate our arguments. */
+ if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)
+ {
+ error ("Invalid regexp: %s", re_err);
+ }
+
+ /* If we're debugging a core file, or have attached to a running
+ process, then som_solib_create_inferior_hook will not have been
+ called.
+
+ We need to first determine if we're dealing with a dynamically
+ linked executable. If not, then return without an error or warning.
+
+ We also need to examine __dld_flags to determine if the shared library
+ list is valid and to determine if the libraries have been privately
+ mapped. */
+ if (symfile_objfile == NULL)
+ return;
+
+ /* First see if the objfile was dynamically linked. */
+ shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
+ if (!shlib_info)
+ return;
+
+ /* It's got a $SHLIB_INFO$ section, make sure it's not empty. */
+ if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
+ return;
+
+ msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
+ if (msymbol == NULL)
+ {
+ error ("Unable to find __dld_flags symbol in object file.\n");
+ return;
+ }
+
+ addr = SYMBOL_VALUE_ADDRESS (msymbol);
+ /* Read the current contents. */
+ status = target_read_memory (addr, buf, 4);
+ if (status != 0)
+ {
+ error ("Unable to read __dld_flags\n");
+ return;
+ }
+ dld_flags = extract_unsigned_integer (buf, 4);
+
+ /* __dld_list may not be valid. If not, then we punt, warning the user if
+ we were called as a result of the add-symfile command.
+ */
+ if ((dld_flags & DLD_FLAGS_LISTVALID) == 0)
+ {
+ if (from_tty)
+ error ("__dld_list is not valid according to __dld_flags.\n");
+ return;
+ }
+
+ /* If the libraries were not mapped private, warn the user. */
+ if ((dld_flags & DLD_FLAGS_MAPPRIVATE) == 0)
+ warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n");
+
+ msymbol = lookup_minimal_symbol ("__dld_list", NULL, NULL);
+ if (!msymbol)
+ {
+ /* Older crt0.o files (hpux8) don't have __dld_list as a symbol,
+ but the data is still available if you know where to look. */
+ msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
+ if (!msymbol)
+ {
+ error ("Unable to find dynamic library list.\n");
+ return;
+ }
+ addr = SYMBOL_VALUE_ADDRESS (msymbol) - 8;
+ }
+ else
+ addr = SYMBOL_VALUE_ADDRESS (msymbol);
+
+ status = target_read_memory (addr, buf, 4);
+ if (status != 0)
+ {
+ error ("Unable to find dynamic library list.\n");
+ return;
+ }
+
+ addr = extract_unsigned_integer (buf, 4);
+
+ /* If addr is zero, then we're using an old dynamic loader which
+ doesn't maintain __dld_list. We'll have to use a completely
+ different approach to get shared library information. */
+ if (addr == 0)
+ goto old_dld;
+
+ /* Using the information in __dld_list is the preferred method
+ to get at shared library information. It doesn't depend on
+ any functions in /opt/langtools/lib/end.o and has a chance of working
+ with hpux10 when it is released. */
+ status = target_read_memory (addr, buf, 4);
+ if (status != 0)
+ {
+ error ("Unable to find dynamic library list.\n");
+ return;
+ }
+
+ /* addr now holds the address of the first entry in the dynamic
+ library list. */
+ addr = extract_unsigned_integer (buf, 4);
+
+ /* Now that we have a pointer to the dynamic library list, walk
+ through it and add the symbols for each library. */
+
+ so_list_tail = so_list_head;
+ /* Find the end of the list of shared objects. */
+ while (so_list_tail && so_list_tail->next)
+ so_list_tail = so_list_tail->next;
+
+#ifdef SOLIB_DEBUG
+ printf ("--About to read shared library list data\n");
+#endif
+
+ /* "addr" will always point to the base of the
+ * current data entry describing the current
+ * shared library.
+ */
+ while (1)
+ {
+ CORE_ADDR name_addr, text_addr;
+ unsigned int name_len;
+ char *name;
+ struct so_list *new_so;
+ struct so_list *so_list = so_list_head;
+ struct stat statbuf;
+ LONGEST st_size;
+ int is_main_program;
+
+ if (addr == 0)
+ break;
+
+ /* Get a pointer to the name of this library. */
+ status = target_read_memory (addr, buf, 4);
+ if (status != 0)
+ goto err;
+
+ name_addr = extract_unsigned_integer (buf, 4);
+ name_len = 0;
+ while (1)
+ {
+ target_read_memory (name_addr + name_len, buf, 1);
+ if (status != 0)
+ goto err;
+
+ name_len++;
+ if (*buf == '\0')
+ break;
+ }
+ name = alloca (name_len);
+ status = target_read_memory (name_addr, name, name_len);
+ if (status != 0)
+ goto err;
+
+ /* See if we've already loaded something with this name. */
+ while (so_list)
+ {
+ if (!strcmp (so_list->som_solib.name, name))
+ break;
+ so_list = so_list->next;
+ }
+
+ /* See if the file exists. If not, give a warning, but don't
+ die. */
+ status = stat (name, &statbuf);
+ if (status == -1)
+ {
+ warning ("Can't find file %s referenced in dld_list.", name);
+
+ status = target_read_memory (addr + 36, buf, 4);
+ if (status != 0)
+ goto err;
+
+ addr = (CORE_ADDR) extract_unsigned_integer (buf, 4);
+ continue;
+ }
+
+ /* If we've already loaded this one or it's the main program, skip it. */
+ is_main_program = (strcmp (name, symfile_objfile->name) == 0);
+ if (so_list || is_main_program)
+ {
+ /* This is the "next" pointer in the strcuture.
+ */
+ status = target_read_memory (addr + 36, buf, 4);
+ if (status != 0)
+ goto err;
+
+ addr = (CORE_ADDR) extract_unsigned_integer (buf, 4);
+
+ /* Record the main program's symbol table size. */
+ if (is_main_program && !so_list)
+ {
+ st_size = som_solib_sizeof_symbol_table (name);
+ som_solib_total_st_size += st_size;
+ }
+
+ /* Was this a shlib that we noted but didn't load the symbols for?
+ If so, were we invoked this time from the command-line, via
+ a 'sharedlibrary' or 'add-symbol-file' command? If yes to
+ both, we'd better load the symbols this time.
+ */
+ if (from_tty && so_list && !is_main_program && (so_list->objfile == NULL))
+ som_solib_load_symbols (so_list,
+ name,
+ from_tty,
+ so_list->som_solib.text_addr,
+ target);
+
+ continue;
+ }
+
+ name = obsavestring (name, name_len - 1,
+ &symfile_objfile->symbol_obstack);
+
+ status = target_read_memory (addr + 8, buf, 4);
+ if (status != 0)
+ goto err;
+
+ text_addr = extract_unsigned_integer (buf, 4);
+
+ new_so = (struct so_list *) xmalloc (sizeof (struct so_list));
+ memset ((char *) new_so, 0, sizeof (struct so_list));
+ if (so_list_head == NULL)
+ {
+ so_list_head = new_so;
+ so_list_tail = new_so;
+ }
+ else
+ {
+ so_list_tail->next = new_so;
+ so_list_tail = new_so;
+ }
+
+ /* Fill in all the entries in GDB's shared library list.
+ */
+
+ new_so->solib_addr = addr;
+ new_so->som_solib.name = name;
+ status = target_read_memory (addr + 4, buf, 4);
+ if (status != 0)
+ goto err;
+
+ new_so->som_solib.struct_version = extract_unsigned_integer (buf + 3, 1);
+ new_so->som_solib.bind_mode = extract_unsigned_integer (buf + 2, 1);
+ /* Following is "high water mark", highest version number
+ * seen, rather than plain version number.
+ */
+ new_so->som_solib.library_version = extract_unsigned_integer (buf, 2);
+ new_so->som_solib.text_addr = text_addr;
+
+ /* Q: What about longword at "addr + 8"?
+ * A: It's read above, out of order, into "text_addr".
+ */
+
+ status = target_read_memory (addr + 12, buf, 4);
+ if (status != 0)
+ goto err;
+
+ new_so->som_solib.text_link_addr = extract_unsigned_integer (buf, 4);
+
+ status = target_read_memory (addr + 16, buf, 4);
+ if (status != 0)
+ goto err;
+
+ new_so->som_solib.text_end = extract_unsigned_integer (buf, 4);
+
+ status = target_read_memory (addr + 20, buf, 4);
+ if (status != 0)
+ goto err;
+
+ new_so->som_solib.data_start = extract_unsigned_integer (buf, 4);
+
+ status = target_read_memory (addr + 24, buf, 4);
+ if (status != 0)
+ goto err;
+
+ new_so->som_solib.bss_start = extract_unsigned_integer (buf, 4);
+
+ status = target_read_memory (addr + 28, buf, 4);
+ if (status != 0)
+ goto err;
+
+ new_so->som_solib.data_end = extract_unsigned_integer (buf, 4);
+
+ status = target_read_memory (addr + 32, buf, 4);
+ if (status != 0)
+ goto err;
+
+ new_so->som_solib.got_value = extract_unsigned_integer (buf, 4);
+
+ status = target_read_memory (addr + 36, buf, 4);
+ if (status != 0)
+ goto err;
+
+ new_so->som_solib.next =
+ address_to_host_pointer (extract_unsigned_integer (buf, 4));
+
+ /* Note that we don't re-set "addr" to the next pointer
+ * until after we've read the trailing data.
+ */
+
+ status = target_read_memory (addr + 40, buf, 4);
+ new_so->som_solib.tsd_start_addr = extract_unsigned_integer (buf, 4);
+ if (status != 0)
+ goto err;
+
+ /* Now indirect via that value!
+ */
+ status = target_read_memory (new_so->som_solib.tsd_start_addr, buf, 4);
+ new_so->som_solib.tsd_start_addr = extract_unsigned_integer (buf, 4);
+ if (status != 0)
+ goto err;
+#ifdef SOLIB_DEBUG
+ printf ("\n+ library \"%s\" is described at 0x%x\n", name, addr);
+ printf (" 'version' is %d\n", new_so->som_solib.struct_version);
+ printf (" 'bind_mode' is %d\n", new_so->som_solib.bind_mode);
+ printf (" 'library_version' is %d\n", new_so->som_solib.library_version);
+ printf (" 'text_addr' is 0x%x\n", new_so->som_solib.text_addr);
+ printf (" 'text_link_addr' is 0x%x\n", new_so->som_solib.text_link_addr);
+ printf (" 'text_end' is 0x%x\n", new_so->som_solib.text_end);
+ printf (" 'data_start' is 0x%x\n", new_so->som_solib.data_start);
+ printf (" 'bss_start' is 0x%x\n", new_so->som_solib.bss_start);
+ printf (" 'data_end' is 0x%x\n", new_so->som_solib.data_end);
+ printf (" 'got_value' is %x\n", new_so->som_solib.got_value);
+ printf (" 'next' is 0x%x\n", new_so->som_solib.next);
+ printf (" 'tsd_start_addr' is 0x%x\n", new_so->som_solib.tsd_start_addr);
+#endif
+
+ /* Go on to the next shared library descriptor.
+ */
+ addr = (CORE_ADDR) new_so->som_solib.next;
+
+
+
+ /* At this point, we have essentially hooked the shlib into the
+ "info share" command. However, we haven't yet loaded its
+ symbol table. We must now decide whether we ought to, i.e.,
+ whether doing so would exceed the symbol table size threshold.
+
+ If the threshold has just now been exceeded, then we'll issue
+ a warning message (which explains how to load symbols manually,
+ if the user so desires).
+
+ If the threshold has just now or previously been exceeded,
+ we'll just add the shlib to the list of object files, but won't
+ actually load its symbols. (This is more useful than it might
+ sound, for it allows us to e.g., still load and use the shlibs'
+ unwind information for stack tracebacks.)
+ */
+
+ /* Note that we DON'T want to preclude the user from using the
+ add-symbol-file command! Thus, we only worry about the threshold
+ when we're invoked for other reasons.
+ */
+ st_size = som_solib_sizeof_symbol_table (name);
+ som_solib_st_size_threshold_exceeded =
+ !from_tty &&
+ auto_solib_limit > 0 &&
+ readsyms &&
+ ((st_size + som_solib_total_st_size) > (auto_solib_limit * (LONGEST) (1024 * 1024)));
+
+ if (som_solib_st_size_threshold_exceeded)
+ {
+ if (!threshold_warning_given)
+ warning ("Symbols for some libraries have not been loaded, because\ndoing so would exceed the size threshold specified by auto-solib-limit.\nTo manually load symbols, use the 'sharedlibrary' command.\nTo raise the threshold, set auto-solib-limit to a larger value and rerun\nthe program.\n");
+ threshold_warning_given = 1;
+
+ /* We'll still make note of this shlib, even if we don't
+ read its symbols. This allows us to use its unwind
+ information well enough to know how to e.g., correctly
+ do a traceback from a PC within the shlib, even if we
+ can't symbolize those PCs...
+ */
+ som_solib_add_solib_objfile (new_so, name, from_tty, text_addr);
+ continue;
+ }
+
+ som_solib_total_st_size += st_size;
+
+ /* This fills in new_so->objfile, among others. */
+ som_solib_load_symbols (new_so, name, from_tty, text_addr, target);
+ }
+
+#ifdef SOLIB_DEBUG
+ printf ("--Done reading shared library data\n");
+#endif
+
+ /* Getting new symbols may change our opinion about what is
+ frameless. */
+ reinit_frame_cache ();
+ return;
+
+old_dld:
+ error ("Debugging dynamic executables loaded via the hpux8 dld.sl is not supported.\n");
+ return;
+
+err:
+ error ("Error while reading dynamic library list.\n");
+ return;
+}
+
+
+/* This hook gets called just before the first instruction in the
+ inferior process is executed.
+
+ This is our opportunity to set magic flags in the inferior so
+ that GDB can be notified when a shared library is mapped in and
+ to tell the dynamic linker that a private copy of the library is
+ needed (so GDB can set breakpoints in the library).
+
+ __dld_flags is the location of the magic flags; as of this implementation
+ there are 3 flags of interest:
+
+ bit 0 when set indicates that private copies of the libraries are needed
+ bit 1 when set indicates that the callback hook routine is valid
+ bit 2 when set indicates that the dynamic linker should maintain the
+ __dld_list structure when loading/unloading libraries.
+
+ Note that shared libraries are not mapped in at this time, so we have
+ run the inferior until the libraries are mapped in. Typically this
+ means running until the "_start" is called. */
+
+void
+som_solib_create_inferior_hook (void)
+{
+ struct minimal_symbol *msymbol;
+ unsigned int dld_flags, status, have_endo;
+ asection *shlib_info;
+ char buf[4];
+ struct objfile *objfile;
+ CORE_ADDR anaddr;
+
+ /* First, remove all the solib event breakpoints. Their addresses
+ may have changed since the last time we ran the program. */
+ remove_solib_event_breakpoints ();
+
+ if (symfile_objfile == NULL)
+ return;
+
+ /* First see if the objfile was dynamically linked. */
+ shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
+ if (!shlib_info)
+ return;
+
+ /* It's got a $SHLIB_INFO$ section, make sure it's not empty. */
+ if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
+ return;
+
+ have_endo = 0;
+ /* Slam the pid of the process into __d_pid.
+
+ We used to warn when this failed, but that warning is only useful
+ on very old HP systems (hpux9 and older). The warnings are an
+ annoyance to users of modern systems and foul up the testsuite as
+ well. As a result, the warnings have been disabled. */
+ msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile);
+ if (msymbol == NULL)
+ goto keep_going;
+
+ anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+ store_unsigned_integer (buf, 4, PIDGET (inferior_ptid));
+ status = target_write_memory (anaddr, buf, 4);
+ if (status != 0)
+ {
+ warning ("Unable to write __d_pid");
+ warning ("Suggest linking with /opt/langtools/lib/end.o.");
+ warning ("GDB will be unable to track shl_load/shl_unload calls");
+ goto keep_going;
+ }
+
+ /* Get the value of _DLD_HOOK (an export stub) and put it in __dld_hook;
+ This will force the dynamic linker to call __d_trap when significant
+ events occur.
+
+ Note that the above is the pre-HP-UX 9.0 behaviour. At 9.0 and above,
+ the dld provides an export stub named "__d_trap" as well as the
+ function named "__d_trap" itself, but doesn't provide "_DLD_HOOK".
+ We'll look first for the old flavor and then the new.
+ */
+ msymbol = lookup_minimal_symbol ("_DLD_HOOK", NULL, symfile_objfile);
+ if (msymbol == NULL)
+ msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
+ if (msymbol == NULL)
+ {
+ warning ("Unable to find _DLD_HOOK symbol in object file.");
+ warning ("Suggest linking with /opt/langtools/lib/end.o.");
+ warning ("GDB will be unable to track shl_load/shl_unload calls");
+ goto keep_going;
+ }
+ anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+ dld_cache.hook.address = anaddr;
+
+ /* Grrr, this might not be an export symbol! We have to find the
+ export stub. */
+ ALL_OBJFILES (objfile)
+ {
+ struct unwind_table_entry *u;
+ struct minimal_symbol *msymbol2;
+
+ /* What a crock. */
+ msymbol2 = lookup_minimal_symbol_solib_trampoline (SYMBOL_NAME (msymbol),
+ NULL, objfile);
+ /* Found a symbol with the right name. */
+ if (msymbol2)
+ {
+ struct unwind_table_entry *u;
+ /* It must be a shared library trampoline. */
+ if (SYMBOL_TYPE (msymbol2) != mst_solib_trampoline)
+ continue;
+
+ /* It must also be an export stub. */
+ u = find_unwind_entry (SYMBOL_VALUE (msymbol2));
+ if (!u || u->stub_unwind.stub_type != EXPORT)
+ continue;
+
+ /* OK. Looks like the correct import stub. */
+ anaddr = SYMBOL_VALUE (msymbol2);
+ dld_cache.hook_stub.address = anaddr;
+ }
+ }
+ store_unsigned_integer (buf, 4, anaddr);
+
+ msymbol = lookup_minimal_symbol ("__dld_hook", NULL, symfile_objfile);
+ if (msymbol == NULL)
+ {
+ warning ("Unable to find __dld_hook symbol in object file.");
+ warning ("Suggest linking with /opt/langtools/lib/end.o.");
+ warning ("GDB will be unable to track shl_load/shl_unload calls");
+ goto keep_going;
+ }
+ anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+ status = target_write_memory (anaddr, buf, 4);
+
+ /* Now set a shlib_event breakpoint at __d_trap so we can track
+ significant shared library events. */
+ msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
+ if (msymbol == NULL)
+ {
+ warning ("Unable to find __dld_d_trap symbol in object file.");
+ warning ("Suggest linking with /opt/langtools/lib/end.o.");
+ warning ("GDB will be unable to track shl_load/shl_unload calls");
+ goto keep_going;
+ }
+ create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol));
+
+ /* We have all the support usually found in end.o, so we can track
+ shl_load and shl_unload calls. */
+ have_endo = 1;
+
+keep_going:
+
+ /* Get the address of __dld_flags, if no such symbol exists, then we can
+ not debug the shared code. */
+ msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
+ if (msymbol == NULL)
+ {
+ error ("Unable to find __dld_flags symbol in object file.\n");
+ }
+
+ anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+
+ /* Read the current contents. */
+ status = target_read_memory (anaddr, buf, 4);
+ if (status != 0)
+ {
+ error ("Unable to read __dld_flags\n");
+ }
+ dld_flags = extract_unsigned_integer (buf, 4);
+
+ /* Turn on the flags we care about. */
+ dld_flags |= DLD_FLAGS_MAPPRIVATE;
+ if (have_endo)
+ dld_flags |= DLD_FLAGS_HOOKVALID;
+ store_unsigned_integer (buf, 4, dld_flags);
+ status = target_write_memory (anaddr, buf, 4);
+ if (status != 0)
+ {
+ error ("Unable to write __dld_flags\n");
+ }
+
+ /* Now find the address of _start and set a breakpoint there.
+ We still need this code for two reasons:
+
+ * Not all sites have /opt/langtools/lib/end.o, so it's not always
+ possible to track the dynamic linker's events.
+
+ * At this time no events are triggered for shared libraries
+ loaded at startup time (what a crock). */
+
+ msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
+ if (msymbol == NULL)
+ {
+ error ("Unable to find _start symbol in object file.\n");
+ }
+
+ anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
+
+ /* Make the breakpoint at "_start" a shared library event breakpoint. */
+ create_solib_event_breakpoint (anaddr);
+
+ /* Wipe out all knowledge of old shared libraries since their
+ mapping can change from one exec to another! */
+ while (so_list_head)
+ {
+ struct so_list *temp;
+
+ temp = so_list_head;
+ xfree (so_list_head);
+ so_list_head = temp->next;
+ }
+ clear_symtab_users ();
+}
+
+/* This operation removes the "hook" between GDB and the dynamic linker,
+ which causes the dld to notify GDB of shared library events.
+
+ After this operation completes, the dld will no longer notify GDB of
+ shared library events. To resume notifications, GDB must call
+ som_solib_create_inferior_hook.
+
+ This operation does not remove any knowledge of shared libraries which
+ GDB may already have been notified of.
+ */
+void
+som_solib_remove_inferior_hook (int pid)
+{
+ CORE_ADDR addr;
+ struct minimal_symbol *msymbol;
+ int status;
+ char dld_flags_buffer[TARGET_INT_BIT / TARGET_CHAR_BIT];
+ unsigned int dld_flags_value;
+ struct cleanup *old_cleanups = save_inferior_ptid ();
+
+ /* Ensure that we're really operating on the specified process. */
+ inferior_ptid = pid_to_ptid (pid);
+
+ /* We won't bother to remove the solib breakpoints from this process.
+
+ In fact, on PA64 the breakpoint is hard-coded into the dld callback,
+ and thus we're not supposed to remove it.
+
+ Rather, we'll merely clear the dld_flags bit that enables callbacks.
+ */
+ msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
+
+ addr = SYMBOL_VALUE_ADDRESS (msymbol);
+ status = target_read_memory (addr, dld_flags_buffer, TARGET_INT_BIT / TARGET_CHAR_BIT);
+
+ dld_flags_value = extract_unsigned_integer (dld_flags_buffer,
+ sizeof (dld_flags_value));
+
+ dld_flags_value &= ~DLD_FLAGS_HOOKVALID;
+ store_unsigned_integer (dld_flags_buffer,
+ sizeof (dld_flags_value),
+ dld_flags_value);
+ status = target_write_memory (addr, dld_flags_buffer, TARGET_INT_BIT / TARGET_CHAR_BIT);
+
+ do_cleanups (old_cleanups);
+}
+
+
+/* This function creates a breakpoint on the dynamic linker hook, which
+ is called when e.g., a shl_load or shl_unload call is made. This
+ breakpoint will only trigger when a shl_load call is made.
+
+ If filename is NULL, then loads of any dll will be caught. Else,
+ only loads of the file whose pathname is the string contained by
+ filename will be caught.
+
+ Undefined behaviour is guaranteed if this function is called before
+ som_solib_create_inferior_hook.
+ */
+void
+som_solib_create_catch_load_hook (int pid, int tempflag, char *filename,
+ char *cond_string)
+{
+ create_solib_load_event_breakpoint ("__d_trap", tempflag, filename, cond_string);
+}
+
+/* This function creates a breakpoint on the dynamic linker hook, which
+ is called when e.g., a shl_load or shl_unload call is made. This
+ breakpoint will only trigger when a shl_unload call is made.
+
+ If filename is NULL, then unloads of any dll will be caught. Else,
+ only unloads of the file whose pathname is the string contained by
+ filename will be caught.
+
+ Undefined behaviour is guaranteed if this function is called before
+ som_solib_create_inferior_hook.
+ */
+void
+som_solib_create_catch_unload_hook (int pid, int tempflag, char *filename,
+ char *cond_string)
+{
+ create_solib_unload_event_breakpoint ("__d_trap", tempflag, filename, cond_string);
+}
+
+int
+som_solib_have_load_event (int pid)
+{
+ CORE_ADDR event_kind;
+
+ event_kind = read_register (ARG0_REGNUM);
+ return (event_kind == SHL_LOAD);
+}
+
+int
+som_solib_have_unload_event (int pid)
+{
+ CORE_ADDR event_kind;
+
+ event_kind = read_register (ARG0_REGNUM);
+ return (event_kind == SHL_UNLOAD);
+}
+
+static char *
+som_solib_library_pathname (int pid)
+{
+ CORE_ADDR dll_handle_address;
+ CORE_ADDR dll_pathname_address;
+ struct som_solib_mapped_entry dll_descriptor;
+ char *p;
+ static char dll_pathname[1024];
+
+ /* Read the descriptor of this newly-loaded library. */
+ dll_handle_address = read_register (ARG1_REGNUM);
+ read_memory (dll_handle_address, (char *) &dll_descriptor, sizeof (dll_descriptor));
+
+ /* We can find a pointer to the dll's pathname within the descriptor. */
+ dll_pathname_address = (CORE_ADDR) dll_descriptor.name;
+
+ /* Read the pathname, one byte at a time. */
+ p = dll_pathname;
+ for (;;)
+ {
+ char b;
+ read_memory (dll_pathname_address++, (char *) &b, 1);
+ *p++ = b;
+ if (b == '\0')
+ break;
+ }
+
+ return dll_pathname;
+}
+
+char *
+som_solib_loaded_library_pathname (int pid)
+{
+ if (!som_solib_have_load_event (pid))
+ error ("Must have a load event to use this query");
+
+ return som_solib_library_pathname (pid);
+}
+
+char *
+som_solib_unloaded_library_pathname (int pid)
+{
+ if (!som_solib_have_unload_event (pid))
+ error ("Must have an unload event to use this query");
+
+ return som_solib_library_pathname (pid);
+}
+
+static void
+som_solib_desire_dynamic_linker_symbols (void)
+{
+ struct objfile *objfile;
+ struct unwind_table_entry *u;
+ struct minimal_symbol *dld_msymbol;
+
+ /* Do we already know the value of these symbols? If so, then
+ we've no work to do.
+
+ (If you add clauses to this test, be sure to likewise update the
+ test within the loop.)
+ */
+ if (dld_cache.is_valid)
+ return;
+
+ ALL_OBJFILES (objfile)
+ {
+ dld_msymbol = lookup_minimal_symbol ("shl_load", NULL, objfile);
+ if (dld_msymbol != NULL)
+ {
+ dld_cache.load.address = SYMBOL_VALUE (dld_msymbol);
+ dld_cache.load.unwind = find_unwind_entry (dld_cache.load.address);
+ }
+
+ dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_load",
+ NULL,
+ objfile);
+ if (dld_msymbol != NULL)
+ {
+ if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline)
+ {
+ u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol));
+ if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
+ {
+ dld_cache.load_stub.address = SYMBOL_VALUE (dld_msymbol);
+ dld_cache.load_stub.unwind = u;
+ }
+ }
+ }
+
+ dld_msymbol = lookup_minimal_symbol ("shl_unload", NULL, objfile);
+ if (dld_msymbol != NULL)
+ {
+ dld_cache.unload.address = SYMBOL_VALUE (dld_msymbol);
+ dld_cache.unload.unwind = find_unwind_entry (dld_cache.unload.address);
+
+ /* ??rehrauer: I'm not sure exactly what this is, but it appears
+ that on some HPUX 10.x versions, there's two unwind regions to
+ cover the body of "shl_unload", the second being 4 bytes past
+ the end of the first. This is a large hack to handle that
+ case, but since I don't seem to have any legitimate way to
+ look for this thing via the symbol table...
+ */
+ if (dld_cache.unload.unwind != NULL)
+ {
+ u = find_unwind_entry (dld_cache.unload.unwind->region_end + 4);
+ if (u != NULL)
+ {
+ dld_cache.unload2.address = u->region_start;
+ dld_cache.unload2.unwind = u;
+ }
+ }
+ }
+
+ dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_unload",
+ NULL,
+ objfile);
+ if (dld_msymbol != NULL)
+ {
+ if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline)
+ {
+ u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol));
+ if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
+ {
+ dld_cache.unload_stub.address = SYMBOL_VALUE (dld_msymbol);
+ dld_cache.unload_stub.unwind = u;
+ }
+ }
+ }
+
+ /* Did we find everything we were looking for? If so, stop. */
+ if ((dld_cache.load.address != 0)
+ && (dld_cache.load_stub.address != 0)
+ && (dld_cache.unload.address != 0)
+ && (dld_cache.unload_stub.address != 0))
+ {
+ dld_cache.is_valid = 1;
+ break;
+ }
+ }
+
+ dld_cache.hook.unwind = find_unwind_entry (dld_cache.hook.address);
+ dld_cache.hook_stub.unwind = find_unwind_entry (dld_cache.hook_stub.address);
+
+ /* We're prepared not to find some of these symbols, which is why
+ this function is a "desire" operation, and not a "require".
+ */
+}
+
+int
+som_solib_in_dynamic_linker (int pid, CORE_ADDR pc)
+{
+ struct unwind_table_entry *u_pc;
+
+ /* Are we in the dld itself?
+
+ ??rehrauer: Large hack -- We'll assume that any address in a
+ shared text region is the dld's text. This would obviously
+ fall down if the user attached to a process, whose shlibs
+ weren't mapped to a (writeable) private region. However, in
+ that case the debugger probably isn't able to set the fundamental
+ breakpoint in the dld callback anyways, so this hack should be
+ safe.
+ */
+ if ((pc & (CORE_ADDR) 0xc0000000) == (CORE_ADDR) 0xc0000000)
+ return 1;
+
+ /* Cache the address of some symbols that are part of the dynamic
+ linker, if not already known.
+ */
+ som_solib_desire_dynamic_linker_symbols ();
+
+ /* Are we in the dld callback? Or its export stub? */
+ u_pc = find_unwind_entry (pc);
+ if (u_pc == NULL)
+ return 0;
+
+ if ((u_pc == dld_cache.hook.unwind) || (u_pc == dld_cache.hook_stub.unwind))
+ return 1;
+
+ /* Or the interface of the dld (i.e., "shl_load" or friends)? */
+ if ((u_pc == dld_cache.load.unwind)
+ || (u_pc == dld_cache.unload.unwind)
+ || (u_pc == dld_cache.unload2.unwind)
+ || (u_pc == dld_cache.load_stub.unwind)
+ || (u_pc == dld_cache.unload_stub.unwind))
+ return 1;
+
+ /* Apparently this address isn't part of the dld's text. */
+ return 0;
+}
+
+
+/* Return the GOT value for the shared library in which ADDR belongs. If
+ ADDR isn't in any known shared library, return zero. */
+
+CORE_ADDR
+som_solib_get_got_by_pc (CORE_ADDR addr)
+{
+ struct so_list *so_list = so_list_head;
+ CORE_ADDR got_value = 0;
+
+ while (so_list)
+ {
+ if (so_list->som_solib.text_addr <= addr
+ && so_list->som_solib.text_end > addr)
+ {
+ got_value = so_list->som_solib.got_value;
+ break;
+ }
+ so_list = so_list->next;
+ }
+ return got_value;
+}
+
+/* elz:
+ Return the address of the handle of the shared library
+ in which ADDR belongs. If
+ ADDR isn't in any known shared library, return zero. */
+/* this function is used in hppa_fix_call_dummy in hppa-tdep.c */
+
+CORE_ADDR
+som_solib_get_solib_by_pc (CORE_ADDR addr)
+{
+ struct so_list *so_list = so_list_head;
+
+ while (so_list)
+ {
+ if (so_list->som_solib.text_addr <= addr
+ && so_list->som_solib.text_end > addr)
+ {
+ break;
+ }
+ so_list = so_list->next;
+ }
+ if (so_list)
+ return so_list->solib_addr;
+ else
+ return 0;
+}
+
+
+int
+som_solib_section_offsets (struct objfile *objfile,
+ struct section_offsets *offsets)
+{
+ struct so_list *so_list = so_list_head;
+
+ while (so_list)
+ {
+ /* Oh what a pain! We need the offsets before so_list->objfile
+ is valid. The BFDs will never match. Make a best guess. */
+ if (strstr (objfile->name, so_list->som_solib.name))
+ {
+ asection *private_section;
+
+ /* The text offset is easy. */
+ offsets->offsets[SECT_OFF_TEXT (objfile)]
+ = (so_list->som_solib.text_addr
+ - so_list->som_solib.text_link_addr);
+ offsets->offsets[SECT_OFF_RODATA (objfile)]
+ = ANOFFSET (offsets, SECT_OFF_TEXT (objfile));
+
+ /* We should look at presumed_dp in the SOM header, but
+ that's not easily available. This should be OK though. */
+ private_section = bfd_get_section_by_name (objfile->obfd,
+ "$PRIVATE$");
+ if (!private_section)
+ {
+ warning ("Unable to find $PRIVATE$ in shared library!");
+ offsets->offsets[SECT_OFF_DATA (objfile)] = 0;
+ offsets->offsets[SECT_OFF_BSS (objfile)] = 0;
+ return 1;
+ }
+ offsets->offsets[SECT_OFF_DATA (objfile)]
+ = (so_list->som_solib.data_start - private_section->vma);
+ offsets->offsets[SECT_OFF_BSS (objfile)]
+ = ANOFFSET (offsets, SECT_OFF_DATA (objfile));
+ return 1;
+ }
+ so_list = so_list->next;
+ }
+ return 0;
+}
+
+/* Dump information about all the currently loaded shared libraries. */
+
+static void
+som_sharedlibrary_info_command (char *ignore, int from_tty)
+{
+ struct so_list *so_list = so_list_head;
+
+ if (exec_bfd == NULL)
+ {
+ printf_unfiltered ("No executable file.\n");
+ return;
+ }
+
+ if (so_list == NULL)
+ {
+ printf_unfiltered ("No shared libraries loaded at this time.\n");
+ return;
+ }
+
+ printf_unfiltered ("Shared Object Libraries\n");
+ printf_unfiltered (" %-12s%-12s%-12s%-12s%-12s%-12s\n",
+ " flags", " tstart", " tend", " dstart", " dend", " dlt");
+ while (so_list)
+ {
+ unsigned int flags;
+
+ flags = so_list->som_solib.struct_version << 24;
+ flags |= so_list->som_solib.bind_mode << 16;
+ flags |= so_list->som_solib.library_version;
+ printf_unfiltered ("%s", so_list->som_solib.name);
+ if (so_list->objfile == NULL)
+ printf_unfiltered (" (symbols not loaded)");
+ printf_unfiltered ("\n");
+ printf_unfiltered (" %-12s", local_hex_string_custom (flags, "08l"));
+ printf_unfiltered ("%-12s",
+ local_hex_string_custom (so_list->som_solib.text_addr, "08l"));
+ printf_unfiltered ("%-12s",
+ local_hex_string_custom (so_list->som_solib.text_end, "08l"));
+ printf_unfiltered ("%-12s",
+ local_hex_string_custom (so_list->som_solib.data_start, "08l"));
+ printf_unfiltered ("%-12s",
+ local_hex_string_custom (so_list->som_solib.data_end, "08l"));
+ printf_unfiltered ("%-12s\n",
+ local_hex_string_custom (so_list->som_solib.got_value, "08l"));
+ so_list = so_list->next;
+ }
+}
+
+static void
+som_solib_sharedlibrary_command (char *args, int from_tty)
+{
+ dont_repeat ();
+ som_solib_add (args, from_tty, (struct target_ops *) 0, 1);
+}
+
+
+
+char *
+som_solib_address (CORE_ADDR addr)
+{
+ struct so_list *so = so_list_head;
+
+ while (so)
+ {
+ /* Is this address within this shlib's text range? If so,
+ return the shlib's name.
+ */
+ if ((addr >= so->som_solib.text_addr) && (addr <= so->som_solib.text_end))
+ return so->som_solib.name;
+
+ /* Nope, keep looking... */
+ so = so->next;
+ }
+
+ /* No, we couldn't prove that the address is within a shlib. */
+ return NULL;
+}
+
+
+void
+som_solib_restart (void)
+{
+ struct so_list *sl = so_list_head;
+
+ /* Before the shlib info vanishes, use it to disable any breakpoints
+ that may still be active in those shlibs.
+ */
+ disable_breakpoints_in_shlibs (0);
+
+ /* Discard all the shlib descriptors.
+ */
+ while (sl)
+ {
+ struct so_list *next_sl = sl->next;
+ xfree (sl);
+ sl = next_sl;
+ }
+ so_list_head = NULL;
+
+ som_solib_total_st_size = (LONGEST) 0;
+ som_solib_st_size_threshold_exceeded = 0;
+
+ dld_cache.is_valid = 0;
+
+ dld_cache.hook.address = 0;
+ dld_cache.hook.unwind = NULL;
+
+ dld_cache.hook_stub.address = 0;
+ dld_cache.hook_stub.unwind = NULL;
+
+ dld_cache.load.address = 0;
+ dld_cache.load.unwind = NULL;
+
+ dld_cache.load_stub.address = 0;
+ dld_cache.load_stub.unwind = NULL;
+
+ dld_cache.unload.address = 0;
+ dld_cache.unload.unwind = NULL;
+
+ dld_cache.unload2.address = 0;
+ dld_cache.unload2.unwind = NULL;
+
+ dld_cache.unload_stub.address = 0;
+ dld_cache.unload_stub.unwind = NULL;
+}
+
+
+/* LOCAL FUNCTION
+
+ no_shared_libraries -- handle command to explicitly discard symbols
+ from shared libraries.
+
+ DESCRIPTION
+
+ Implements the command "nosharedlibrary", which discards symbols
+ that have been auto-loaded from shared libraries. Symbols from
+ shared libraries that were added by explicit request of the user
+ are not discarded. Also called from remote.c. */
+
+void
+no_shared_libraries (char *ignored, int from_tty)
+{
+ /* FIXME */
+}
+
+
+void
+_initialize_som_solib (void)
+{
+ add_com ("sharedlibrary", class_files, som_solib_sharedlibrary_command,
+ "Load shared object library symbols for files matching REGEXP.");
+ add_info ("sharedlibrary", som_sharedlibrary_info_command,
+ "Status of loaded shared object libraries.");
+
+ add_show_from_set
+ (add_set_cmd ("auto-solib-add", class_support, var_boolean,
+ (char *) &auto_solib_add,
+ "Set autoloading of shared library symbols.\n\
+If \"on\", symbols from all shared object libraries will be loaded\n\
+automatically when the inferior begins execution, when the dynamic linker\n\
+informs gdb that a new library has been loaded, or when attaching to the\n\
+inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("auto-solib-limit", class_support, var_zinteger,
+ (char *) &auto_solib_limit,
+ "Set threshold (in Mb) for autoloading shared library symbols.\n\
+When shared library autoloading is enabled, new libraries will be loaded\n\
+only until the total size of shared library symbols exceeds this\n\
+threshold in megabytes. Is ignored when using `sharedlibrary'.",
+ &setlist),
+ &showlist);
+
+ /* ??rehrauer: On HP-UX, the kernel parameter MAXDSIZ limits how
+ much data space a process can use. We ought to be reading
+ MAXDSIZ and setting auto_solib_limit to some large fraction of
+ that value. If not that, we maybe ought to be setting it smaller
+ than the default for MAXDSIZ (that being 64Mb, I believe).
+ However, [1] this threshold is only crudely approximated rather
+ than actually measured, and [2] 50 Mbytes is too small for
+ debugging gdb itself. Thus, the arbitrary 100 figure. */
+ auto_solib_limit = 100; /* Megabytes */
+
+ som_solib_restart ();
+}
+
+/* Get some HPUX-specific data from a shared lib.
+ */
+CORE_ADDR
+so_lib_thread_start_addr (struct so_list *so)
+{
+ return so->som_solib.tsd_start_addr;
+}
diff --git a/gdb/somsolib.h b/gdb/somsolib.h
new file mode 100644
index 00000000000..4b23760199c
--- /dev/null
+++ b/gdb/somsolib.h
@@ -0,0 +1,165 @@
+/* HP SOM Shared library declarations for GDB, the GNU Debugger.
+ Copyright 1992, 1994, 1995, 1998, 1999, 2000
+ 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.
+
+ Written by the Center for Software Science at the Univerity of Utah
+ and by Cygnus Support. */
+
+/* Forward decl's for prototypes */
+struct target_ops;
+struct objfile;
+struct section_offsets;
+
+/* Called to add symbols from a shared library to gdb's symbol table. */
+
+#define SOLIB_ADD(filename, from_tty, targ, readsyms) \
+ som_solib_add (filename, from_tty, targ, readsyms)
+
+extern void som_solib_add (char *, int, struct target_ops *, int);
+
+extern CORE_ADDR som_solib_get_got_by_pc (CORE_ADDR);
+
+extern int
+som_solib_section_offsets (struct objfile *, struct section_offsets *);
+
+/* Function to be called when the inferior starts up, to discover the names
+ of shared libraries that are dynamically linked, the base addresses to
+ which they are linked, and sufficient information to read in their symbols
+ at a later time. */
+
+#define SOLIB_CREATE_INFERIOR_HOOK(PID) som_solib_create_inferior_hook()
+
+extern void som_solib_create_inferior_hook (void);
+
+/* Function to be called to remove the connection between debugger and
+ dynamic linker that was established by SOLIB_CREATE_INFERIOR_HOOK.
+ (This operation does not remove shared library information from
+ the debugger, as CLEAR_SOLIB does.)
+ */
+#define SOLIB_REMOVE_INFERIOR_HOOK(PID) som_solib_remove_inferior_hook(PID)
+
+extern void som_solib_remove_inferior_hook (int);
+
+/* This function is called by the "catch load" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is loaded.
+ */
+#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag, filename,cond_string) \
+ som_solib_create_catch_load_hook (pid, tempflag, filename, cond_string)
+
+extern void som_solib_create_catch_load_hook (int, int, char *, char *);
+
+/* This function is called by the "catch unload" command. It allows
+ the debugger to be notified by the dynamic linker when a specified
+ library file (or any library file, if filename is NULL) is unloaded.
+ */
+#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename, cond_string) \
+ som_solib_create_catch_unload_hook (pid, tempflag, filename, cond_string)
+
+extern void som_solib_create_catch_unload_hook (int, int, char *, char *);
+
+/* This function returns TRUE if the dynamic linker has just reported
+ a load of a library.
+
+ This function must be used only when the inferior has stopped in
+ the dynamic linker hook, or undefined results are guaranteed.
+ */
+#define SOLIB_HAVE_LOAD_EVENT(pid) \
+ som_solib_have_load_event (pid)
+
+extern int som_solib_have_load_event (int);
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been loaded.
+
+ This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the inferior
+ has stopped in the dynamic linker hook, and becomes invalid as soon
+ as the inferior is continued. Clients should make a copy of this
+ string if they wish to continue the inferior and then access the string.
+ */
+#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \
+ som_solib_loaded_library_pathname (pid)
+
+extern char *som_solib_loaded_library_pathname (int);
+
+/* This function returns TRUE if the dynamic linker has just reported
+ an unload of a library.
+
+ This function must be used only when the inferior has stopped in
+ the dynamic linker hook, or undefined results are guaranteed.
+ */
+#define SOLIB_HAVE_UNLOAD_EVENT(pid) \
+ som_solib_have_unload_event (pid)
+
+extern int som_solib_have_unload_event (int);
+
+/* This function returns a pointer to the string representation of the
+ pathname of the dynamically-linked library that has just been unloaded.
+
+ This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE,
+ or undefined results are guaranteed.
+
+ This string's contents are only valid immediately after the inferior
+ has stopped in the dynamic linker hook, and becomes invalid as soon
+ as the inferior is continued. Clients should make a copy of this
+ string if they wish to continue the inferior and then access the string.
+ */
+#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \
+ som_solib_unloaded_library_pathname (pid)
+
+extern char *som_solib_unloaded_library_pathname (int);
+
+/* This function returns TRUE if pc is the address of an instruction that
+ lies within the dynamic linker (such as the event hook, or the dld
+ itself).
+
+ This function must be used only when a dynamic linker event has been
+ caught, and the inferior is being stepped out of the hook, or undefined
+ results are guaranteed.
+ */
+#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \
+ som_solib_in_dynamic_linker (pid, pc)
+
+extern int som_solib_in_dynamic_linker (int, CORE_ADDR);
+
+/* This function must be called when the inferior is killed, and the program
+ restarted. This is not the same as CLEAR_SOLIB, in that it doesn't discard
+ any symbol tables.
+
+ Presently, this functionality is not implemented.
+ */
+#define SOLIB_RESTART() \
+ som_solib_restart ()
+
+extern void som_solib_restart (void);
+
+/* If we can't set a breakpoint, and it's in a shared library, just
+ disable it. */
+
+#define DISABLE_UNSETTABLE_BREAK(addr) (som_solib_address(addr) != NULL)
+
+extern char *som_solib_address (CORE_ADDR); /* somsolib.c */
+
+/* If ADDR lies in a shared library, return its name. */
+
+#define PC_SOLIB(addr) som_solib_address (addr)
diff --git a/gdb/source.c b/gdb/source.c
new file mode 100644
index 00000000000..ac743724058
--- /dev/null
+++ b/gdb/source.c
@@ -0,0 +1,1692 @@
+/* List lines of source files for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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 "defs.h"
+#include "symtab.h"
+#include "expression.h"
+#include "language.h"
+#include "command.h"
+#include "source.h"
+#include "gdbcmd.h"
+#include "frame.h"
+#include "value.h"
+
+#include <sys/types.h>
+#include "gdb_string.h"
+#include "gdb_stat.h"
+#include <fcntl.h>
+#include "gdbcore.h"
+#include "gdb_regex.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "annotate.h"
+#include "gdbtypes.h"
+#include "linespec.h"
+#include "filenames.h" /* for DOSish file names */
+#include "completer.h"
+#include "ui-out.h"
+
+#ifdef CRLF_SOURCE_FILES
+
+/* Define CRLF_SOURCE_FILES in an xm-*.h file if source files on the
+ host use \r\n rather than just \n. Defining CRLF_SOURCE_FILES is
+ much faster than defining LSEEK_NOT_LINEAR. */
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#define OPEN_MODE (O_RDONLY | O_BINARY)
+#define FDOPEN_MODE FOPEN_RB
+
+#else /* ! defined (CRLF_SOURCE_FILES) */
+
+#define OPEN_MODE O_RDONLY
+#define FDOPEN_MODE FOPEN_RT
+
+#endif /* ! defined (CRLF_SOURCE_FILES) */
+
+/* Prototypes for exported functions. */
+
+void _initialize_source (void);
+
+/* Prototypes for local functions. */
+
+static int get_filename_and_charpos (struct symtab *, char **);
+
+static void reverse_search_command (char *, int);
+
+static void forward_search_command (char *, int);
+
+static void line_info (char *, int);
+
+static void list_command (char *, int);
+
+static void ambiguous_line_spec (struct symtabs_and_lines *);
+
+static void source_info (char *, int);
+
+static void show_directories (char *, int);
+
+/* Path of directories to search for source files.
+ Same format as the PATH environment variable's value. */
+
+char *source_path;
+
+/* Symtab of default file for listing lines of. */
+
+struct symtab *current_source_symtab;
+
+/* Default next line to list. */
+
+int current_source_line;
+
+/* Default number of lines to print with commands like "list".
+ This is based on guessing how many long (i.e. more than chars_per_line
+ characters) lines there will be. To be completely correct, "list"
+ and friends should be rewritten to count characters and see where
+ things are wrapping, but that would be a fair amount of work. */
+
+int lines_to_list = 10;
+
+/* Line number of last line printed. Default for various commands.
+ current_source_line is usually, but not always, the same as this. */
+
+static int last_line_listed;
+
+/* First line number listed by last listing command. */
+
+static int first_line_listed;
+
+/* Saves the name of the last source file visited and a possible error code.
+ Used to prevent repeating annoying "No such file or directories" msgs */
+
+static struct symtab *last_source_visited = NULL;
+static int last_source_error = 0;
+
+
+/* Set the source file default for the "list" command to be S.
+
+ If S is NULL, and we don't have a default, find one. This
+ should only be called when the user actually tries to use the
+ default, since we produce an error if we can't find a reasonable
+ default. Also, since this can cause symbols to be read, doing it
+ before we need to would make things slower than necessary. */
+
+void
+select_source_symtab (register struct symtab *s)
+{
+ struct symtabs_and_lines sals;
+ struct symtab_and_line sal;
+ struct partial_symtab *ps;
+ struct partial_symtab *cs_pst = 0;
+ struct objfile *ofp;
+
+ if (s)
+ {
+ current_source_symtab = s;
+ current_source_line = 1;
+ return;
+ }
+
+ if (current_source_symtab)
+ return;
+
+ /* Make the default place to list be the function `main'
+ if one exists. */
+ if (lookup_symbol (main_name (), 0, VAR_NAMESPACE, 0, NULL))
+ {
+ sals = decode_line_spec (main_name (), 1);
+ sal = sals.sals[0];
+ xfree (sals.sals);
+ current_source_symtab = sal.symtab;
+ current_source_line = max (sal.line - (lines_to_list - 1), 1);
+ if (current_source_symtab)
+ return;
+ }
+
+ /* All right; find the last file in the symtab list (ignoring .h's). */
+
+ current_source_line = 1;
+
+ for (ofp = object_files; ofp != NULL; ofp = ofp->next)
+ {
+ for (s = ofp->symtabs; s; s = s->next)
+ {
+ char *name = s->filename;
+ int len = strlen (name);
+ if (!(len > 2 && (STREQ (&name[len - 2], ".h"))))
+ {
+ current_source_symtab = s;
+ }
+ }
+ }
+ if (current_source_symtab)
+ return;
+
+ /* Howabout the partial symbol tables? */
+
+ for (ofp = object_files; ofp != NULL; ofp = ofp->next)
+ {
+ for (ps = ofp->psymtabs; ps != NULL; ps = ps->next)
+ {
+ char *name = ps->filename;
+ int len = strlen (name);
+ if (!(len > 2 && (STREQ (&name[len - 2], ".h"))))
+ {
+ cs_pst = ps;
+ }
+ }
+ }
+ if (cs_pst)
+ {
+ if (cs_pst->readin)
+ {
+ internal_error (__FILE__, __LINE__,
+ "select_source_symtab: "
+ "readin pst found and no symtabs.");
+ }
+ else
+ {
+ current_source_symtab = PSYMTAB_TO_SYMTAB (cs_pst);
+ }
+ }
+ if (current_source_symtab)
+ return;
+
+ error ("Can't find a default source file");
+}
+
+static void
+show_directories (char *ignore, int from_tty)
+{
+ puts_filtered ("Source directories searched: ");
+ puts_filtered (source_path);
+ puts_filtered ("\n");
+}
+
+/* Forget what we learned about line positions in source files, and
+ which directories contain them; must check again now since files
+ may be found in a different directory now. */
+
+void
+forget_cached_source_info (void)
+{
+ register struct symtab *s;
+ register struct objfile *objfile;
+ struct partial_symtab *pst;
+
+ for (objfile = object_files; objfile != NULL; objfile = objfile->next)
+ {
+ for (s = objfile->symtabs; s != NULL; s = s->next)
+ {
+ if (s->line_charpos != NULL)
+ {
+ xmfree (objfile->md, s->line_charpos);
+ s->line_charpos = NULL;
+ }
+ if (s->fullname != NULL)
+ {
+ xmfree (objfile->md, s->fullname);
+ s->fullname = NULL;
+ }
+ }
+
+ ALL_OBJFILE_PSYMTABS (objfile, pst)
+ {
+ if (pst->fullname != NULL)
+ {
+ xfree (pst->fullname);
+ pst->fullname = NULL;
+ }
+ }
+ }
+}
+
+void
+init_source_path (void)
+{
+ char buf[20];
+
+ sprintf (buf, "$cdir%c$cwd", DIRNAME_SEPARATOR);
+ source_path = xstrdup (buf);
+ forget_cached_source_info ();
+}
+
+/* Add zero or more directories to the front of the source path. */
+
+void
+directory_command (char *dirname, int from_tty)
+{
+ dont_repeat ();
+ /* FIXME, this goes to "delete dir"... */
+ if (dirname == 0)
+ {
+ if (from_tty && query ("Reinitialize source path to empty? "))
+ {
+ xfree (source_path);
+ init_source_path ();
+ }
+ }
+ else
+ {
+ mod_path (dirname, &source_path);
+ last_source_visited = NULL;
+ }
+ if (from_tty)
+ show_directories ((char *) 0, from_tty);
+ forget_cached_source_info ();
+}
+
+/* Add zero or more directories to the front of an arbitrary path. */
+
+void
+mod_path (char *dirname, char **which_path)
+{
+ char *old = *which_path;
+ int prefix = 0;
+
+ if (dirname == 0)
+ return;
+
+ dirname = xstrdup (dirname);
+ make_cleanup (xfree, dirname);
+
+ do
+ {
+ char *name = dirname;
+ register char *p;
+ struct stat st;
+
+ {
+ char *separator = strchr (name, DIRNAME_SEPARATOR);
+ char *space = strchr (name, ' ');
+ char *tab = strchr (name, '\t');
+
+ if (separator == 0 && space == 0 && tab == 0)
+ p = dirname = name + strlen (name);
+ else
+ {
+ p = 0;
+ if (separator != 0 && (p == 0 || separator < p))
+ p = separator;
+ if (space != 0 && (p == 0 || space < p))
+ p = space;
+ if (tab != 0 && (p == 0 || tab < p))
+ p = tab;
+ dirname = p + 1;
+ while (*dirname == DIRNAME_SEPARATOR
+ || *dirname == ' '
+ || *dirname == '\t')
+ ++dirname;
+ }
+ }
+
+ if (!(IS_DIR_SEPARATOR (*name) && p <= name + 1) /* "/" */
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ /* On MS-DOS and MS-Windows, h:\ is different from h: */
+ && !(p == name + 3 && name[1] == ':') /* "d:/" */
+#endif
+ && IS_DIR_SEPARATOR (p[-1]))
+ /* Sigh. "foo/" => "foo" */
+ --p;
+ *p = '\0';
+
+ while (p > name && p[-1] == '.')
+ {
+ if (p - name == 1)
+ {
+ /* "." => getwd (). */
+ name = current_directory;
+ goto append;
+ }
+ else if (p > name + 1 && IS_DIR_SEPARATOR (p[-2]))
+ {
+ if (p - name == 2)
+ {
+ /* "/." => "/". */
+ *--p = '\0';
+ goto append;
+ }
+ else
+ {
+ /* "...foo/." => "...foo". */
+ p -= 2;
+ *p = '\0';
+ continue;
+ }
+ }
+ else
+ break;
+ }
+
+ if (name[0] == '~')
+ name = tilde_expand (name);
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ else if (IS_ABSOLUTE_PATH (name) && p == name + 2) /* "d:" => "d:." */
+ name = concat (name, ".", NULL);
+#endif
+ else if (!IS_ABSOLUTE_PATH (name) && name[0] != '$')
+ name = concat (current_directory, SLASH_STRING, name, NULL);
+ else
+ name = savestring (name, p - name);
+ make_cleanup (xfree, name);
+
+ /* Unless it's a variable, check existence. */
+ if (name[0] != '$')
+ {
+ /* These are warnings, not errors, since we don't want a
+ non-existent directory in a .gdbinit file to stop processing
+ of the .gdbinit file.
+
+ Whether they get added to the path is more debatable. Current
+ answer is yes, in case the user wants to go make the directory
+ or whatever. If the directory continues to not exist/not be
+ a directory/etc, then having them in the path should be
+ harmless. */
+ if (stat (name, &st) < 0)
+ {
+ int save_errno = errno;
+ fprintf_unfiltered (gdb_stderr, "Warning: ");
+ print_sys_errmsg (name, save_errno);
+ }
+ else if ((st.st_mode & S_IFMT) != S_IFDIR)
+ warning ("%s is not a directory.", name);
+ }
+
+ append:
+ {
+ register unsigned int len = strlen (name);
+
+ p = *which_path;
+ while (1)
+ {
+ /* FIXME: strncmp loses in interesting ways on MS-DOS and
+ MS-Windows because of case-insensitivity and two different
+ but functionally identical slash characters. We need a
+ special filesystem-dependent file-name comparison function.
+
+ Actually, even on Unix I would use realpath() or its work-
+ alike before comparing. Then all the code above which
+ removes excess slashes and dots could simply go away. */
+ if (!strncmp (p, name, len)
+ && (p[len] == '\0' || p[len] == DIRNAME_SEPARATOR))
+ {
+ /* Found it in the search path, remove old copy */
+ if (p > *which_path)
+ p--; /* Back over leading separator */
+ if (prefix > p - *which_path)
+ goto skip_dup; /* Same dir twice in one cmd */
+ strcpy (p, &p[len + 1]); /* Copy from next \0 or : */
+ }
+ p = strchr (p, DIRNAME_SEPARATOR);
+ if (p != 0)
+ ++p;
+ else
+ break;
+ }
+ if (p == 0)
+ {
+ char tinybuf[2];
+
+ tinybuf[0] = DIRNAME_SEPARATOR;
+ tinybuf[1] = '\0';
+
+ /* If we have already tacked on a name(s) in this command, be sure they stay on the front as we tack on some more. */
+ if (prefix)
+ {
+ char *temp, c;
+
+ c = old[prefix];
+ old[prefix] = '\0';
+ temp = concat (old, tinybuf, name, NULL);
+ old[prefix] = c;
+ *which_path = concat (temp, "", &old[prefix], NULL);
+ prefix = strlen (temp);
+ xfree (temp);
+ }
+ else
+ {
+ *which_path = concat (name, (old[0] ? tinybuf : old), old, NULL);
+ prefix = strlen (name);
+ }
+ xfree (old);
+ old = *which_path;
+ }
+ }
+ skip_dup:;
+ }
+ while (*dirname != '\0');
+}
+
+
+static void
+source_info (char *ignore, int from_tty)
+{
+ register struct symtab *s = current_source_symtab;
+
+ if (!s)
+ {
+ printf_filtered ("No current source file.\n");
+ return;
+ }
+ printf_filtered ("Current source file is %s\n", s->filename);
+ if (s->dirname)
+ printf_filtered ("Compilation directory is %s\n", s->dirname);
+ if (s->fullname)
+ printf_filtered ("Located in %s\n", s->fullname);
+ if (s->nlines)
+ printf_filtered ("Contains %d line%s.\n", s->nlines,
+ s->nlines == 1 ? "" : "s");
+
+ printf_filtered ("Source language is %s.\n", language_str (s->language));
+ printf_filtered ("Compiled with %s debugging format.\n", s->debugformat);
+}
+
+
+/* Return True if the file NAME exists and is a regular file */
+static int
+is_regular_file (const char *name)
+{
+ struct stat st;
+ const int status = stat (name, &st);
+
+ /* Stat should never fail except when the file does not exist.
+ If stat fails, analyze the source of error and return True
+ unless the file does not exist, to avoid returning false results
+ on obscure systems where stat does not work as expected.
+ */
+ if (status != 0)
+ return (errno != ENOENT);
+
+ return S_ISREG (st.st_mode);
+}
+
+/* Open a file named STRING, searching path PATH (dir names sep by some char)
+ using mode MODE and protection bits PROT in the calls to open.
+
+ If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
+ (ie pretend the first element of PATH is "."). This also indicates
+ that a slash in STRING disables searching of the path (this is
+ so that "exec-file ./foo" or "symbol-file ./foo" insures that you
+ get that particular version of foo or an error message).
+
+ If FILENAME_OPENED is non-null, set it to a newly allocated string naming
+ the actual file opened (this string will always start with a "/"). We
+ have to take special pains to avoid doubling the "/" between the directory
+ and the file, sigh! Emacs gets confuzzed by this when we print the
+ source file name!!!
+
+ If a file is found, return the descriptor.
+ Otherwise, return -1, with errno set for the last name we tried to open. */
+
+/* >>>> This should only allow files of certain types,
+ >>>> eg executable, non-directory */
+int
+openp (const char *path, int try_cwd_first, const char *string,
+ int mode, int prot,
+ char **filename_opened)
+{
+ register int fd;
+ register char *filename;
+ const char *p;
+ const char *p1;
+ register int len;
+ int alloclen;
+
+ if (!path)
+ path = ".";
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+ mode |= O_BINARY;
+#endif
+
+ if ((try_cwd_first || IS_ABSOLUTE_PATH (string)) && is_regular_file (string))
+ {
+ int i;
+ filename = alloca (strlen (string) + 1);
+ strcpy (filename, string);
+ fd = open (filename, mode, prot);
+ if (fd >= 0)
+ goto done;
+ for (i = 0; string[i]; i++)
+ if (IS_DIR_SEPARATOR (string[i]))
+ goto done;
+ }
+
+ /* ./foo => foo */
+ while (string[0] == '.' && IS_DIR_SEPARATOR (string[1]))
+ string += 2;
+
+ alloclen = strlen (path) + strlen (string) + 2;
+ filename = alloca (alloclen);
+ fd = -1;
+ for (p = path; p; p = p1 ? p1 + 1 : 0)
+ {
+ p1 = strchr (p, DIRNAME_SEPARATOR);
+ if (p1)
+ len = p1 - p;
+ else
+ len = strlen (p);
+
+ if (len == 4 && p[0] == '$' && p[1] == 'c'
+ && p[2] == 'w' && p[3] == 'd')
+ {
+ /* Name is $cwd -- insert current directory name instead. */
+ int newlen;
+
+ /* First, realloc the filename buffer if too short. */
+ len = strlen (current_directory);
+ newlen = len + strlen (string) + 2;
+ if (newlen > alloclen)
+ {
+ alloclen = newlen;
+ filename = alloca (alloclen);
+ }
+ strcpy (filename, current_directory);
+ }
+ else
+ {
+ /* Normal file name in path -- just use it. */
+ strncpy (filename, p, len);
+ filename[len] = 0;
+ }
+
+ /* Remove trailing slashes */
+ while (len > 0 && IS_DIR_SEPARATOR (filename[len - 1]))
+ filename[--len] = 0;
+
+ strcat (filename + len, SLASH_STRING);
+ strcat (filename, string);
+
+ if (is_regular_file (filename))
+ {
+ fd = open (filename, mode);
+ if (fd >= 0)
+ break;
+ }
+ }
+
+done:
+ if (filename_opened)
+ {
+ /* If a file was opened, canonicalize its filename. Use xfullpath
+ rather than gdb_realpath to avoid resolving the basename part
+ of filenames when the associated file is a symbolic link. This
+ fixes a potential inconsistency between the filenames known to
+ GDB and the filenames it prints in the annotations. */
+ if (fd < 0)
+ *filename_opened = NULL;
+ else if (IS_ABSOLUTE_PATH (filename))
+ *filename_opened = xfullpath (filename);
+ else
+ {
+ /* Beware the // my son, the Emacs barfs, the botch that catch... */
+
+ char *f = concat (current_directory,
+ IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
+ ? "" : SLASH_STRING,
+ filename, NULL);
+ *filename_opened = xfullpath (f);
+ xfree (f);
+ }
+ }
+
+ return fd;
+}
+
+
+/* This is essentially a convenience, for clients that want the behaviour
+ of openp, using source_path, but that really don't want the file to be
+ opened but want instead just to know what the full pathname is (as
+ qualified against source_path).
+
+ The current working directory is searched first.
+
+ If the file was found, this function returns 1, and FULL_PATHNAME is
+ set to the fully-qualified pathname.
+
+ Else, this functions returns 0, and FULL_PATHNAME is set to NULL.
+ */
+int
+source_full_path_of (char *filename, char **full_pathname)
+{
+ int fd;
+
+ fd = openp (source_path, 1, filename, O_RDONLY, 0, full_pathname);
+ if (fd < 0)
+ {
+ *full_pathname = NULL;
+ return 0;
+ }
+
+ close (fd);
+ return 1;
+}
+
+
+/* Open a source file given a symtab S. Returns a file descriptor or
+ negative number for error. */
+
+int
+open_source_file (struct symtab *s)
+{
+ char *path = source_path;
+ const char *p;
+ int result;
+ char *fullname;
+
+ /* Quick way out if we already know its full name */
+ if (s->fullname)
+ {
+ result = open (s->fullname, OPEN_MODE);
+ if (result >= 0)
+ return result;
+ /* Didn't work -- free old one, try again. */
+ xmfree (s->objfile->md, s->fullname);
+ s->fullname = NULL;
+ }
+
+ if (s->dirname != NULL)
+ {
+ /* Replace a path entry of $cdir with the compilation directory name */
+#define cdir_len 5
+ /* We cast strstr's result in case an ANSIhole has made it const,
+ which produces a "required warning" when assigned to a nonconst. */
+ p = (char *) strstr (source_path, "$cdir");
+ if (p && (p == path || p[-1] == DIRNAME_SEPARATOR)
+ && (p[cdir_len] == DIRNAME_SEPARATOR || p[cdir_len] == '\0'))
+ {
+ int len;
+
+ path = (char *)
+ alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1);
+ len = p - source_path;
+ strncpy (path, source_path, len); /* Before $cdir */
+ strcpy (path + len, s->dirname); /* new stuff */
+ strcat (path + len, source_path + len + cdir_len); /* After $cdir */
+ }
+ }
+
+ result = openp (path, 0, s->filename, OPEN_MODE, 0, &s->fullname);
+ if (result < 0)
+ {
+ /* Didn't work. Try using just the basename. */
+ p = lbasename (s->filename);
+ if (p != s->filename)
+ result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname);
+ }
+
+ if (result >= 0)
+ {
+ fullname = s->fullname;
+ s->fullname = mstrsave (s->objfile->md, s->fullname);
+ xfree (fullname);
+ }
+ return result;
+}
+
+/* Return the path to the source file associated with symtab. Returns NULL
+ if no symtab. */
+
+char *
+symtab_to_filename (struct symtab *s)
+{
+ int fd;
+
+ if (!s)
+ return NULL;
+
+ /* If we've seen the file before, just return fullname. */
+
+ if (s->fullname)
+ return s->fullname;
+
+ /* Try opening the file to setup fullname */
+
+ fd = open_source_file (s);
+ if (fd < 0)
+ return s->filename; /* File not found. Just use short name */
+
+ /* Found the file. Cleanup and return the full name */
+
+ close (fd);
+ return s->fullname;
+}
+
+
+/* Create and initialize the table S->line_charpos that records
+ the positions of the lines in the source file, which is assumed
+ to be open on descriptor DESC.
+ All set S->nlines to the number of such lines. */
+
+void
+find_source_lines (struct symtab *s, int desc)
+{
+ struct stat st;
+ register char *data, *p, *end;
+ int nlines = 0;
+ int lines_allocated = 1000;
+ int *line_charpos;
+ long mtime = 0;
+ int size;
+
+ line_charpos = (int *) xmmalloc (s->objfile->md,
+ lines_allocated * sizeof (int));
+ if (fstat (desc, &st) < 0)
+ perror_with_name (s->filename);
+
+ if (s && s->objfile && s->objfile->obfd)
+ mtime = bfd_get_mtime (s->objfile->obfd);
+ else if (exec_bfd)
+ mtime = bfd_get_mtime (exec_bfd);
+
+ if (mtime && mtime < st.st_mtime)
+ {
+ warning ("Source file is more recent than executable.\n");
+ }
+
+#ifdef LSEEK_NOT_LINEAR
+ {
+ char c;
+
+ /* Have to read it byte by byte to find out where the chars live */
+
+ line_charpos[0] = lseek (desc, 0, SEEK_CUR);
+ nlines = 1;
+ while (myread (desc, &c, 1) > 0)
+ {
+ if (c == '\n')
+ {
+ if (nlines == lines_allocated)
+ {
+ lines_allocated *= 2;
+ line_charpos =
+ (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
+ sizeof (int) * lines_allocated);
+ }
+ line_charpos[nlines++] = lseek (desc, 0, SEEK_CUR);
+ }
+ }
+ }
+#else /* lseek linear. */
+ {
+ struct cleanup *old_cleanups;
+
+ /* st_size might be a large type, but we only support source files whose
+ size fits in an int. */
+ size = (int) st.st_size;
+
+ /* Use malloc, not alloca, because this may be pretty large, and we may
+ run into various kinds of limits on stack size. */
+ data = (char *) xmalloc (size);
+ old_cleanups = make_cleanup (xfree, data);
+
+ /* Reassign `size' to result of read for systems where \r\n -> \n. */
+ size = myread (desc, data, size);
+ if (size < 0)
+ perror_with_name (s->filename);
+ end = data + size;
+ p = data;
+ line_charpos[0] = 0;
+ nlines = 1;
+ while (p != end)
+ {
+ if (*p++ == '\n'
+ /* A newline at the end does not start a new line. */
+ && p != end)
+ {
+ if (nlines == lines_allocated)
+ {
+ lines_allocated *= 2;
+ line_charpos =
+ (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
+ sizeof (int) * lines_allocated);
+ }
+ line_charpos[nlines++] = p - data;
+ }
+ }
+ do_cleanups (old_cleanups);
+ }
+#endif /* lseek linear. */
+ s->nlines = nlines;
+ s->line_charpos =
+ (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
+ nlines * sizeof (int));
+
+}
+
+/* Return the character position of a line LINE in symtab S.
+ Return 0 if anything is invalid. */
+
+#if 0 /* Currently unused */
+
+int
+source_line_charpos (struct symtab *s, int line)
+{
+ if (!s)
+ return 0;
+ if (!s->line_charpos || line <= 0)
+ return 0;
+ if (line > s->nlines)
+ line = s->nlines;
+ return s->line_charpos[line - 1];
+}
+
+/* Return the line number of character position POS in symtab S. */
+
+int
+source_charpos_line (register struct symtab *s, register int chr)
+{
+ register int line = 0;
+ register int *lnp;
+
+ if (s == 0 || s->line_charpos == 0)
+ return 0;
+ lnp = s->line_charpos;
+ /* Files are usually short, so sequential search is Ok */
+ while (line < s->nlines && *lnp <= chr)
+ {
+ line++;
+ lnp++;
+ }
+ if (line >= s->nlines)
+ line = s->nlines;
+ return line;
+}
+
+#endif /* 0 */
+
+
+/* Get full pathname and line number positions for a symtab.
+ Return nonzero if line numbers may have changed.
+ Set *FULLNAME to actual name of the file as found by `openp',
+ or to 0 if the file is not found. */
+
+static int
+get_filename_and_charpos (struct symtab *s, char **fullname)
+{
+ register int desc, linenums_changed = 0;
+
+ desc = open_source_file (s);
+ if (desc < 0)
+ {
+ if (fullname)
+ *fullname = NULL;
+ return 0;
+ }
+ if (fullname)
+ *fullname = s->fullname;
+ if (s->line_charpos == 0)
+ linenums_changed = 1;
+ if (linenums_changed)
+ find_source_lines (s, desc);
+ close (desc);
+ return linenums_changed;
+}
+
+/* Print text describing the full name of the source file S
+ and the line number LINE and its corresponding character position.
+ The text starts with two Ctrl-z so that the Emacs-GDB interface
+ can easily find it.
+
+ MID_STATEMENT is nonzero if the PC is not at the beginning of that line.
+
+ Return 1 if successful, 0 if could not find the file. */
+
+int
+identify_source_line (struct symtab *s, int line, int mid_statement,
+ CORE_ADDR pc)
+{
+ if (s->line_charpos == 0)
+ get_filename_and_charpos (s, (char **) NULL);
+ if (s->fullname == 0)
+ return 0;
+ if (line > s->nlines)
+ /* Don't index off the end of the line_charpos array. */
+ return 0;
+ annotate_source (s->fullname, line, s->line_charpos[line - 1],
+ mid_statement, pc);
+
+ current_source_line = line;
+ first_line_listed = line;
+ last_line_listed = line;
+ current_source_symtab = s;
+ return 1;
+}
+
+
+/* Print source lines from the file of symtab S,
+ starting with line number LINE and stopping before line number STOPLINE. */
+
+static void print_source_lines_base (struct symtab *s, int line, int stopline,
+ int noerror);
+static void
+print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
+{
+ register int c;
+ register int desc;
+ register FILE *stream;
+ int nlines = stopline - line;
+
+ /* Regardless of whether we can open the file, set current_source_symtab. */
+ current_source_symtab = s;
+ current_source_line = line;
+ first_line_listed = line;
+
+ /* If printing of source lines is disabled, just print file and line number */
+ if (ui_out_test_flags (uiout, ui_source_list))
+ {
+ /* Only prints "No such file or directory" once */
+ if ((s != last_source_visited) || (!last_source_error))
+ {
+ last_source_visited = s;
+ desc = open_source_file (s);
+ }
+ else
+ {
+ desc = last_source_error;
+ noerror = 1;
+ }
+ }
+ else
+ {
+ desc = -1;
+ noerror = 1;
+ }
+
+ if (desc < 0)
+ {
+ last_source_error = desc;
+
+ if (!noerror)
+ {
+ char *name = alloca (strlen (s->filename) + 100);
+ sprintf (name, "%d\t%s", line, s->filename);
+ print_sys_errmsg (name, errno);
+ }
+ else
+ ui_out_field_int (uiout, "line", line);
+ ui_out_text (uiout, "\tin ");
+ ui_out_field_string (uiout, "file", s->filename);
+ ui_out_text (uiout, "\n");
+
+ return;
+ }
+
+ last_source_error = 0;
+
+ if (s->line_charpos == 0)
+ find_source_lines (s, desc);
+
+ if (line < 1 || line > s->nlines)
+ {
+ close (desc);
+ error ("Line number %d out of range; %s has %d lines.",
+ line, s->filename, s->nlines);
+ }
+
+ if (lseek (desc, s->line_charpos[line - 1], 0) < 0)
+ {
+ close (desc);
+ perror_with_name (s->filename);
+ }
+
+ stream = fdopen (desc, FDOPEN_MODE);
+ clearerr (stream);
+
+ while (nlines-- > 0)
+ {
+ char buf[20];
+
+ c = fgetc (stream);
+ if (c == EOF)
+ break;
+ last_line_listed = current_source_line;
+ sprintf (buf, "%d\t", current_source_line++);
+ ui_out_text (uiout, buf);
+ do
+ {
+ if (c < 040 && c != '\t' && c != '\n' && c != '\r')
+ {
+ sprintf (buf, "^%c", c + 0100);
+ ui_out_text (uiout, buf);
+ }
+ else if (c == 0177)
+ ui_out_text (uiout, "^?");
+#ifdef CRLF_SOURCE_FILES
+ else if (c == '\r')
+ {
+ /* Skip a \r character, but only before a \n. */
+ int c1 = fgetc (stream);
+
+ if (c1 != '\n')
+ printf_filtered ("^%c", c + 0100);
+ if (c1 != EOF)
+ ungetc (c1, stream);
+ }
+#endif
+ else
+ {
+ sprintf (buf, "%c", c);
+ ui_out_text (uiout, buf);
+ }
+ }
+ while (c != '\n' && (c = fgetc (stream)) >= 0);
+ }
+
+ fclose (stream);
+}
+
+/* Show source lines from the file of symtab S, starting with line
+ number LINE and stopping before line number STOPLINE. If this is the
+ not the command line version, then the source is shown in the source
+ window otherwise it is simply printed */
+
+void
+print_source_lines (struct symtab *s, int line, int stopline, int noerror)
+{
+ print_source_lines_base (s, line, stopline, noerror);
+}
+
+
+
+/* Print a list of files and line numbers which a user may choose from
+ in order to list a function which was specified ambiguously (as with
+ `list classname::overloadedfuncname', for example). The vector in
+ SALS provides the filenames and line numbers. */
+
+static void
+ambiguous_line_spec (struct symtabs_and_lines *sals)
+{
+ int i;
+
+ for (i = 0; i < sals->nelts; ++i)
+ printf_filtered ("file: \"%s\", line number: %d\n",
+ sals->sals[i].symtab->filename, sals->sals[i].line);
+}
+
+static void
+list_command (char *arg, int from_tty)
+{
+ struct symtabs_and_lines sals, sals_end;
+ struct symtab_and_line sal, sal_end;
+ struct symbol *sym;
+ char *arg1;
+ int no_end = 1;
+ int dummy_end = 0;
+ int dummy_beg = 0;
+ int linenum_beg = 0;
+ char *p;
+
+ if (!have_full_symbols () && !have_partial_symbols ())
+ error ("No symbol table is loaded. Use the \"file\" command.");
+
+ /* Pull in a current source symtab if necessary */
+ if (current_source_symtab == 0 &&
+ (arg == 0 || arg[0] == '+' || arg[0] == '-'))
+ select_source_symtab (0);
+
+ /* "l" or "l +" lists next ten lines. */
+
+ if (arg == 0 || STREQ (arg, "+"))
+ {
+ if (current_source_symtab == 0)
+ error ("No default source file yet. Do \"help list\".");
+ print_source_lines (current_source_symtab, current_source_line,
+ current_source_line + lines_to_list, 0);
+ return;
+ }
+
+ /* "l -" lists previous ten lines, the ones before the ten just listed. */
+ if (STREQ (arg, "-"))
+ {
+ if (current_source_symtab == 0)
+ error ("No default source file yet. Do \"help list\".");
+ print_source_lines (current_source_symtab,
+ max (first_line_listed - lines_to_list, 1),
+ first_line_listed, 0);
+ return;
+ }
+
+ /* Now if there is only one argument, decode it in SAL
+ and set NO_END.
+ If there are two arguments, decode them in SAL and SAL_END
+ and clear NO_END; however, if one of the arguments is blank,
+ set DUMMY_BEG or DUMMY_END to record that fact. */
+
+ arg1 = arg;
+ if (*arg1 == ',')
+ dummy_beg = 1;
+ else
+ {
+ sals = decode_line_1 (&arg1, 0, 0, 0, 0);
+
+ if (!sals.nelts)
+ return; /* C++ */
+ if (sals.nelts > 1)
+ {
+ ambiguous_line_spec (&sals);
+ xfree (sals.sals);
+ return;
+ }
+
+ sal = sals.sals[0];
+ xfree (sals.sals);
+ }
+
+ /* Record whether the BEG arg is all digits. */
+
+ for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++);
+ linenum_beg = (p == arg1);
+
+ while (*arg1 == ' ' || *arg1 == '\t')
+ arg1++;
+ if (*arg1 == ',')
+ {
+ no_end = 0;
+ arg1++;
+ while (*arg1 == ' ' || *arg1 == '\t')
+ arg1++;
+ if (*arg1 == 0)
+ dummy_end = 1;
+ else
+ {
+ if (dummy_beg)
+ sals_end = decode_line_1 (&arg1, 0, 0, 0, 0);
+ else
+ sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line, 0);
+ if (sals_end.nelts == 0)
+ return;
+ if (sals_end.nelts > 1)
+ {
+ ambiguous_line_spec (&sals_end);
+ xfree (sals_end.sals);
+ return;
+ }
+ sal_end = sals_end.sals[0];
+ xfree (sals_end.sals);
+ }
+ }
+
+ if (*arg1)
+ error ("Junk at end of line specification.");
+
+ if (!no_end && !dummy_beg && !dummy_end
+ && sal.symtab != sal_end.symtab)
+ error ("Specified start and end are in different files.");
+ if (dummy_beg && dummy_end)
+ error ("Two empty args do not say what lines to list.");
+
+ /* if line was specified by address,
+ first print exactly which line, and which file.
+ In this case, sal.symtab == 0 means address is outside
+ of all known source files, not that user failed to give a filename. */
+ if (*arg == '*')
+ {
+ if (sal.symtab == 0)
+ /* FIXME-32x64--assumes sal.pc fits in long. */
+ error ("No source file for address %s.",
+ local_hex_string ((unsigned long) sal.pc));
+ sym = find_pc_function (sal.pc);
+ if (sym)
+ {
+ print_address_numeric (sal.pc, 1, gdb_stdout);
+ printf_filtered (" is in ");
+ fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
+ printf_filtered (" (%s:%d).\n", sal.symtab->filename, sal.line);
+ }
+ else
+ {
+ print_address_numeric (sal.pc, 1, gdb_stdout);
+ printf_filtered (" is at %s:%d.\n",
+ sal.symtab->filename, sal.line);
+ }
+ }
+
+ /* If line was not specified by just a line number,
+ and it does not imply a symtab, it must be an undebuggable symbol
+ which means no source code. */
+
+ if (!linenum_beg && sal.symtab == 0)
+ error ("No line number known for %s.", arg);
+
+ /* If this command is repeated with RET,
+ turn it into the no-arg variant. */
+
+ if (from_tty)
+ *arg = 0;
+
+ if (dummy_beg && sal_end.symtab == 0)
+ error ("No default source file yet. Do \"help list\".");
+ if (dummy_beg)
+ print_source_lines (sal_end.symtab,
+ max (sal_end.line - (lines_to_list - 1), 1),
+ sal_end.line + 1, 0);
+ else if (sal.symtab == 0)
+ error ("No default source file yet. Do \"help list\".");
+ else if (no_end)
+ {
+ int first_line = sal.line - lines_to_list / 2;
+
+ if (first_line < 1) first_line = 1;
+
+ print_source_lines (sal.symtab, first_line, first_line + lines_to_list,
+ 0);
+ }
+ else
+ print_source_lines (sal.symtab, sal.line,
+ (dummy_end
+ ? sal.line + lines_to_list
+ : sal_end.line + 1),
+ 0);
+}
+
+/* Print info on range of pc's in a specified line. */
+
+static void
+line_info (char *arg, int from_tty)
+{
+ struct symtabs_and_lines sals;
+ struct symtab_and_line sal;
+ CORE_ADDR start_pc, end_pc;
+ int i;
+
+ INIT_SAL (&sal); /* initialize to zeroes */
+
+ if (arg == 0)
+ {
+ sal.symtab = current_source_symtab;
+ sal.line = last_line_listed;
+ sals.nelts = 1;
+ sals.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ sals.sals[0] = sal;
+ }
+ else
+ {
+ sals = decode_line_spec_1 (arg, 0);
+
+ dont_repeat ();
+ }
+
+ /* C++ More than one line may have been specified, as when the user
+ specifies an overloaded function name. Print info on them all. */
+ for (i = 0; i < sals.nelts; i++)
+ {
+ sal = sals.sals[i];
+
+ if (sal.symtab == 0)
+ {
+ printf_filtered ("No line number information available");
+ if (sal.pc != 0)
+ {
+ /* This is useful for "info line *0x7f34". If we can't tell the
+ user about a source line, at least let them have the symbolic
+ address. */
+ printf_filtered (" for address ");
+ wrap_here (" ");
+ print_address (sal.pc, gdb_stdout);
+ }
+ else
+ printf_filtered (".");
+ printf_filtered ("\n");
+ }
+ else if (sal.line > 0
+ && find_line_pc_range (sal, &start_pc, &end_pc))
+ {
+ if (start_pc == end_pc)
+ {
+ printf_filtered ("Line %d of \"%s\"",
+ sal.line, sal.symtab->filename);
+ wrap_here (" ");
+ printf_filtered (" is at address ");
+ print_address (start_pc, gdb_stdout);
+ wrap_here (" ");
+ printf_filtered (" but contains no code.\n");
+ }
+ else
+ {
+ printf_filtered ("Line %d of \"%s\"",
+ sal.line, sal.symtab->filename);
+ wrap_here (" ");
+ printf_filtered (" starts at address ");
+ print_address (start_pc, gdb_stdout);
+ wrap_here (" ");
+ printf_filtered (" and ends at ");
+ print_address (end_pc, gdb_stdout);
+ printf_filtered (".\n");
+ }
+
+ /* x/i should display this line's code. */
+ set_next_address (start_pc);
+
+ /* Repeating "info line" should do the following line. */
+ last_line_listed = sal.line + 1;
+
+ /* If this is the only line, show the source code. If it could
+ not find the file, don't do anything special. */
+ if (annotation_level && sals.nelts == 1)
+ identify_source_line (sal.symtab, sal.line, 0, start_pc);
+ }
+ else
+ /* Is there any case in which we get here, and have an address
+ which the user would want to see? If we have debugging symbols
+ and no line numbers? */
+ printf_filtered ("Line number %d is out of range for \"%s\".\n",
+ sal.line, sal.symtab->filename);
+ }
+ xfree (sals.sals);
+}
+
+/* Commands to search the source file for a regexp. */
+
+/* ARGSUSED */
+static void
+forward_search_command (char *regex, int from_tty)
+{
+ register int c;
+ register int desc;
+ register FILE *stream;
+ int line;
+ char *msg;
+
+ line = last_line_listed + 1;
+
+ msg = (char *) re_comp (regex);
+ if (msg)
+ error (msg);
+
+ if (current_source_symtab == 0)
+ select_source_symtab (0);
+
+ desc = open_source_file (current_source_symtab);
+ if (desc < 0)
+ perror_with_name (current_source_symtab->filename);
+
+ if (current_source_symtab->line_charpos == 0)
+ find_source_lines (current_source_symtab, desc);
+
+ if (line < 1 || line > current_source_symtab->nlines)
+ {
+ close (desc);
+ error ("Expression not found");
+ }
+
+ if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
+ {
+ close (desc);
+ perror_with_name (current_source_symtab->filename);
+ }
+
+ stream = fdopen (desc, FDOPEN_MODE);
+ clearerr (stream);
+ while (1)
+ {
+ static char *buf = NULL;
+ register char *p;
+ int cursize, newsize;
+
+ cursize = 256;
+ buf = xmalloc (cursize);
+ p = buf;
+
+ c = getc (stream);
+ if (c == EOF)
+ break;
+ do
+ {
+ *p++ = c;
+ if (p - buf == cursize)
+ {
+ newsize = cursize + cursize / 2;
+ buf = xrealloc (buf, newsize);
+ p = buf + cursize;
+ cursize = newsize;
+ }
+ }
+ while (c != '\n' && (c = getc (stream)) >= 0);
+
+#ifdef CRLF_SOURCE_FILES
+ /* Remove the \r, if any, at the end of the line, otherwise
+ regular expressions that end with $ or \n won't work. */
+ if (p - buf > 1 && p[-2] == '\r')
+ {
+ p--;
+ p[-1] = '\n';
+ }
+#endif
+
+ /* we now have a source line in buf, null terminate and match */
+ *p = 0;
+ if (re_exec (buf) > 0)
+ {
+ /* Match! */
+ fclose (stream);
+ print_source_lines (current_source_symtab, line, line + 1, 0);
+ set_internalvar (lookup_internalvar ("_"),
+ value_from_longest (builtin_type_int,
+ (LONGEST) line));
+ current_source_line = max (line - lines_to_list / 2, 1);
+ return;
+ }
+ line++;
+ }
+
+ printf_filtered ("Expression not found\n");
+ fclose (stream);
+}
+
+/* ARGSUSED */
+static void
+reverse_search_command (char *regex, int from_tty)
+{
+ register int c;
+ register int desc;
+ register FILE *stream;
+ int line;
+ char *msg;
+
+ line = last_line_listed - 1;
+
+ msg = (char *) re_comp (regex);
+ if (msg)
+ error (msg);
+
+ if (current_source_symtab == 0)
+ select_source_symtab (0);
+
+ desc = open_source_file (current_source_symtab);
+ if (desc < 0)
+ perror_with_name (current_source_symtab->filename);
+
+ if (current_source_symtab->line_charpos == 0)
+ find_source_lines (current_source_symtab, desc);
+
+ if (line < 1 || line > current_source_symtab->nlines)
+ {
+ close (desc);
+ error ("Expression not found");
+ }
+
+ if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
+ {
+ close (desc);
+ perror_with_name (current_source_symtab->filename);
+ }
+
+ stream = fdopen (desc, FDOPEN_MODE);
+ clearerr (stream);
+ while (line > 1)
+ {
+/* FIXME!!! We walk right off the end of buf if we get a long line!!! */
+ char buf[4096]; /* Should be reasonable??? */
+ register char *p = buf;
+
+ c = getc (stream);
+ if (c == EOF)
+ break;
+ do
+ {
+ *p++ = c;
+ }
+ while (c != '\n' && (c = getc (stream)) >= 0);
+
+#ifdef CRLF_SOURCE_FILES
+ /* Remove the \r, if any, at the end of the line, otherwise
+ regular expressions that end with $ or \n won't work. */
+ if (p - buf > 1 && p[-2] == '\r')
+ {
+ p--;
+ p[-1] = '\n';
+ }
+#endif
+
+ /* We now have a source line in buf; null terminate and match. */
+ *p = 0;
+ if (re_exec (buf) > 0)
+ {
+ /* Match! */
+ fclose (stream);
+ print_source_lines (current_source_symtab, line, line + 1, 0);
+ set_internalvar (lookup_internalvar ("_"),
+ value_from_longest (builtin_type_int,
+ (LONGEST) line));
+ current_source_line = max (line - lines_to_list / 2, 1);
+ return;
+ }
+ line--;
+ if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0)
+ {
+ fclose (stream);
+ perror_with_name (current_source_symtab->filename);
+ }
+ }
+
+ printf_filtered ("Expression not found\n");
+ fclose (stream);
+ return;
+}
+
+void
+_initialize_source (void)
+{
+ struct cmd_list_element *c;
+ current_source_symtab = 0;
+ init_source_path ();
+
+ /* The intention is to use POSIX Basic Regular Expressions.
+ Always use the GNU regex routine for consistency across all hosts.
+ Our current GNU regex.c does not have all the POSIX features, so this is
+ just an approximation. */
+ re_set_syntax (RE_SYNTAX_GREP);
+
+ c = add_cmd ("directory", class_files, directory_command,
+ "Add directory DIR to beginning of search path for source files.\n\
+Forget cached info on source file locations and line positions.\n\
+DIR can also be $cwd for the current working directory, or $cdir for the\n\
+directory in which the source file was compiled into object code.\n\
+With no argument, reset the search path to $cdir:$cwd, the default.",
+ &cmdlist);
+
+ if (dbx_commands)
+ add_com_alias ("use", "directory", class_files, 0);
+
+ set_cmd_completer (c, filename_completer);
+
+ add_cmd ("directories", no_class, show_directories,
+ "Current search path for finding source files.\n\
+$cwd in the path means the current working directory.\n\
+$cdir in the path means the compilation directory of the source file.",
+ &showlist);
+
+ if (xdb_commands)
+ {
+ add_com_alias ("D", "directory", class_files, 0);
+ add_cmd ("ld", no_class, show_directories,
+ "Current search path for finding source files.\n\
+$cwd in the path means the current working directory.\n\
+$cdir in the path means the compilation directory of the source file.",
+ &cmdlist);
+ }
+
+ add_info ("source", source_info,
+ "Information about the current source file.");
+
+ add_info ("line", line_info,
+ concat ("Core addresses of the code for a source line.\n\
+Line can be specified as\n\
+ LINENUM, to list around that line in current file,\n\
+ FILE:LINENUM, to list around that line in that file,\n\
+ FUNCTION, to list around beginning of that function,\n\
+ FILE:FUNCTION, to distinguish among like-named static functions.\n\
+", "\
+Default is to describe the last source line that was listed.\n\n\
+This sets the default address for \"x\" to the line's first instruction\n\
+so that \"x/i\" suffices to start examining the machine code.\n\
+The address is also stored as the value of \"$_\".", NULL));
+
+ add_com ("forward-search", class_files, forward_search_command,
+ "Search for regular expression (see regex(3)) from last line listed.\n\
+The matching line number is also stored as the value of \"$_\".");
+ add_com_alias ("search", "forward-search", class_files, 0);
+
+ add_com ("reverse-search", class_files, reverse_search_command,
+ "Search backward for regular expression (see regex(3)) from last line listed.\n\
+The matching line number is also stored as the value of \"$_\".");
+
+ if (xdb_commands)
+ {
+ add_com_alias ("/", "forward-search", class_files, 0);
+ add_com_alias ("?", "reverse-search", class_files, 0);
+ }
+
+ add_com ("list", class_files, list_command,
+ concat ("List specified function or line.\n\
+With no argument, lists ten more lines after or around previous listing.\n\
+\"list -\" lists the ten lines before a previous ten-line listing.\n\
+One argument specifies a line, and ten lines are listed around that line.\n\
+Two arguments with comma between specify starting and ending lines to list.\n\
+", "\
+Lines can be specified in these ways:\n\
+ LINENUM, to list around that line in current file,\n\
+ FILE:LINENUM, to list around that line in that file,\n\
+ FUNCTION, to list around beginning of that function,\n\
+ FILE:FUNCTION, to distinguish among like-named static functions.\n\
+ *ADDRESS, to list around the line containing that address.\n\
+With two args if one is empty it stands for ten lines away from the other arg.", NULL));
+
+ if (!xdb_commands)
+ add_com_alias ("l", "list", class_files, 1);
+ else
+ add_com_alias ("v", "list", class_files, 1);
+
+ if (dbx_commands)
+ add_com_alias ("file", "list", class_files, 1);
+
+ add_show_from_set
+ (add_set_cmd ("listsize", class_support, var_uinteger,
+ (char *) &lines_to_list,
+ "Set number of source lines gdb will list by default.",
+ &setlist),
+ &showlist);
+}
diff --git a/gdb/source.h b/gdb/source.h
new file mode 100644
index 00000000000..8dbf8517056
--- /dev/null
+++ b/gdb/source.h
@@ -0,0 +1,34 @@
+/* List lines of source files for GDB, the GNU debugger.
+ Copyright 1999 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. */
+
+#ifndef SOURCE_H
+#define SOURCE_H
+
+/* Open a source file given a symtab S. Returns a file descriptor or
+ negative number for error. */
+extern int open_source_file (struct symtab *s);
+
+/* Create and initialize the table S->line_charpos that records the
+ positions of the lines in the source file, which is assumed to be
+ open on descriptor DESC. All set S->nlines to the number of such
+ lines. */
+extern void find_source_lines (struct symtab *s, int desc);
+
+#endif
diff --git a/gdb/sparc-linux-nat.c b/gdb/sparc-linux-nat.c
new file mode 100644
index 00000000000..ba418b637db
--- /dev/null
+++ b/gdb/sparc-linux-nat.c
@@ -0,0 +1,100 @@
+/* Native-dependent code for GNU/Linux SPARC.
+
+ Copyright 2001, 2002 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 "defs.h"
+#include "regcache.h"
+
+#include <sys/procfs.h>
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+void
+supply_gregset (elf_gregset_t *gregsetp)
+{
+ elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ int i;
+
+ for (i = G0_REGNUM; i <= I7_REGNUM; i++)
+ supply_register (i, (char *) (regp + (i - G0_REGNUM)));
+
+ supply_register (PS_REGNUM, (char *) (regp + 32));
+
+ supply_register (PC_REGNUM, (char *) (regp + 33));
+ supply_register (NPC_REGNUM, (char *) (regp + 34));
+ supply_register (Y_REGNUM, (char *) (regp + 35));
+
+ supply_register (WIM_REGNUM, (char *) (regp + 36));
+ supply_register (TBR_REGNUM, (char *) (regp + 37));
+
+ /* Fill inaccessible registers with zero. */
+ supply_register (CPS_REGNUM, NULL);
+}
+
+void
+fill_gregset (elf_gregset_t *gregsetp, int regno)
+{
+ elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ int i;
+
+ for (i = G0_REGNUM; i <= I7_REGNUM; i++)
+ if (regno == -1 || regno == i)
+ regcache_collect (i, regp + (i - G0_REGNUM));
+
+ if (regno == -1 || regno == PS_REGNUM)
+ regcache_collect (PS_REGNUM, regp + 32);
+
+ if (regno == -1 || regno == PC_REGNUM)
+ regcache_collect (PC_REGNUM, regp + 33);
+ if (regno == -1 || regno == NPC_REGNUM)
+ regcache_collect (NPC_REGNUM, regp + 34);
+ if (regno == -1 || regno == Y_REGNUM)
+ regcache_collect (Y_REGNUM, regp + 35);
+
+ if (regno == -1 || regno == WIM_REGNUM)
+ regcache_collect (WIM_REGNUM, regp + 36);
+ if (regno == -1 || regno == TBR_REGNUM)
+ regcache_collect (TBR_REGNUM, regp + 37);
+}
+
+void
+supply_fpregset (elf_fpregset_t *fpregsetp)
+{
+ int i;
+
+ for (i = FP0_REGNUM; i < FP0_REGNUM + 32; i++)
+ supply_register (i, (char *) &fpregsetp->pr_fr.pr_regs[i - FP0_REGNUM]);
+
+ supply_register (FPS_REGNUM, (char *) &fpregsetp->pr_fsr);
+}
+
+void
+fill_fpregset (elf_fpregset_t *fpregsetp, int regno)
+{
+ int i;
+
+ for (i = FP0_REGNUM; i < FP0_REGNUM + 32; i++)
+ if (regno == -1 || regno == i)
+ regcache_collect (i, &fpregsetp->pr_fr.pr_regs[i - FP0_REGNUM]);
+
+ if (regno == -1 || regno == FPS_REGNUM)
+ regcache_collect (FPS_REGNUM, &fpregsetp->pr_fsr);
+}
diff --git a/gdb/sparc-nat.c b/gdb/sparc-nat.c
new file mode 100644
index 00000000000..e892fe8fbda
--- /dev/null
+++ b/gdb/sparc-nat.c
@@ -0,0 +1,349 @@
+/* Functions specific to running gdb native on a SPARC running SunOS4.
+ Copyright 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <signal.h>
+#include <sys/ptrace.h>
+#include <sys/wait.h>
+#ifdef __linux__
+#include <asm/reg.h>
+#else
+#include <machine/reg.h>
+#endif
+#include <sys/user.h>
+
+/* We don't store all registers immediately when requested, since they
+ get sent over in large chunks anyway. Instead, we accumulate most
+ of the changes and send them over once. "deferred_stores" keeps
+ track of which sets of registers we have locally-changed copies of,
+ so we only need send the groups that have changed. */
+
+#define INT_REGS 1
+#define STACK_REGS 2
+#define FP_REGS 4
+
+/* Fetch one or more registers from the inferior. REGNO == -1 to get
+ them all. We actually fetch more than requested, when convenient,
+ marking them as valid so we won't fetch them again. */
+
+void
+fetch_inferior_registers (int regno)
+{
+ struct regs inferior_registers;
+ struct fp_status inferior_fp_registers;
+ int i;
+
+ /* We should never be called with deferred stores, because a prerequisite
+ for writing regs is to have fetched them all (PREPARE_TO_STORE), sigh. */
+ if (deferred_stores)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+ DO_DEFERRED_STORES;
+
+ /* Global and Out regs are fetched directly, as well as the control
+ registers. If we're getting one of the in or local regs,
+ and the stack pointer has not yet been fetched,
+ we have to do that first, since they're found in memory relative
+ to the stack pointer. */
+ if (regno < O7_REGNUM /* including -1 */
+ || regno >= Y_REGNUM
+ || (!register_valid[SP_REGNUM] && regno < I7_REGNUM))
+ {
+ if (0 != ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0))
+ perror ("ptrace_getregs");
+
+ registers[REGISTER_BYTE (0)] = 0;
+ memcpy (&registers[REGISTER_BYTE (1)], &inferior_registers.r_g1,
+ 15 * REGISTER_RAW_SIZE (G0_REGNUM));
+ *(int *) &registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
+ *(int *) &registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
+ *(int *) &registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
+ *(int *) &registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
+
+ for (i = G0_REGNUM; i <= O7_REGNUM; i++)
+ register_valid[i] = 1;
+ register_valid[Y_REGNUM] = 1;
+ register_valid[PS_REGNUM] = 1;
+ register_valid[PC_REGNUM] = 1;
+ register_valid[NPC_REGNUM] = 1;
+ /* If we don't set these valid, read_register_bytes() rereads
+ all the regs every time it is called! FIXME. */
+ register_valid[WIM_REGNUM] = 1; /* Not true yet, FIXME */
+ register_valid[TBR_REGNUM] = 1; /* Not true yet, FIXME */
+ register_valid[CPS_REGNUM] = 1; /* Not true yet, FIXME */
+ }
+
+ /* Floating point registers */
+ if (regno == -1 ||
+ regno == FPS_REGNUM ||
+ (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31))
+ {
+ if (0 != ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers,
+ 0))
+ perror ("ptrace_getfpregs");
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
+ sizeof inferior_fp_registers.fpu_fr);
+ memcpy (&registers[REGISTER_BYTE (FPS_REGNUM)],
+ &inferior_fp_registers.Fpu_fsr,
+ sizeof (FPU_FSR_TYPE));
+ for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
+ register_valid[i] = 1;
+ register_valid[FPS_REGNUM] = 1;
+ }
+
+ /* These regs are saved on the stack by the kernel. Only read them
+ all (16 ptrace calls!) if we really need them. */
+ if (regno == -1)
+ {
+ CORE_ADDR sp = *(unsigned int *) & registers[REGISTER_BYTE (SP_REGNUM)];
+ target_read_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
+ 16 * REGISTER_RAW_SIZE (L0_REGNUM));
+ for (i = L0_REGNUM; i <= I7_REGNUM; i++)
+ register_valid[i] = 1;
+ }
+ else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
+ {
+ CORE_ADDR sp = *(unsigned int *) & registers[REGISTER_BYTE (SP_REGNUM)];
+ i = REGISTER_BYTE (regno);
+ if (register_valid[regno])
+ printf_unfiltered ("register %d valid and read\n", regno);
+ target_read_memory (sp + i - REGISTER_BYTE (L0_REGNUM),
+ &registers[i], REGISTER_RAW_SIZE (regno));
+ register_valid[regno] = 1;
+ }
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ struct regs inferior_registers;
+ struct fp_status inferior_fp_registers;
+ int wanna_store = INT_REGS + STACK_REGS + FP_REGS;
+
+ /* First decide which pieces of machine-state we need to modify.
+ Default for regno == -1 case is all pieces. */
+ if (regno >= 0)
+ {
+ if (FP0_REGNUM <= regno && regno < FP0_REGNUM + 32)
+ {
+ wanna_store = FP_REGS;
+ }
+ else
+ {
+ if (regno == SP_REGNUM)
+ wanna_store = INT_REGS + STACK_REGS;
+ else if (regno < L0_REGNUM || regno > I7_REGNUM)
+ wanna_store = INT_REGS;
+ else if (regno == FPS_REGNUM)
+ wanna_store = FP_REGS;
+ else
+ wanna_store = STACK_REGS;
+ }
+ }
+
+ /* See if we're forcing the stores to happen now, or deferring. */
+ if (regno == -2)
+ {
+ wanna_store = deferred_stores;
+ deferred_stores = 0;
+ }
+ else
+ {
+ if (wanna_store == STACK_REGS)
+ {
+ /* Fall through and just store one stack reg. If we deferred
+ it, we'd have to store them all, or remember more info. */
+ }
+ else
+ {
+ deferred_stores |= wanna_store;
+ return;
+ }
+ }
+
+ if (wanna_store & STACK_REGS)
+ {
+ CORE_ADDR sp = *(unsigned int *) & registers[REGISTER_BYTE (SP_REGNUM)];
+
+ if (regno < 0 || regno == SP_REGNUM)
+ {
+ if (!register_valid[L0_REGNUM + 5])
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ target_write_memory (sp,
+ &registers[REGISTER_BYTE (L0_REGNUM)],
+ 16 * REGISTER_RAW_SIZE (L0_REGNUM));
+ }
+ else
+ {
+ if (!register_valid[regno])
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ target_write_memory (sp + REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM),
+ &registers[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE (regno));
+ }
+
+ }
+
+ if (wanna_store & INT_REGS)
+ {
+ if (!register_valid[G1_REGNUM])
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+ memcpy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (G1_REGNUM)],
+ 15 * REGISTER_RAW_SIZE (G1_REGNUM));
+
+ inferior_registers.r_ps =
+ *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
+ inferior_registers.r_pc =
+ *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
+ inferior_registers.r_npc =
+ *(int *) &registers[REGISTER_BYTE (NPC_REGNUM)];
+ inferior_registers.r_y =
+ *(int *) &registers[REGISTER_BYTE (Y_REGNUM)];
+
+ if (0 != ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers, 0))
+ perror ("ptrace_setregs");
+ }
+
+ if (wanna_store & FP_REGS)
+ {
+ if (!register_valid[FP0_REGNUM + 9])
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
+ sizeof inferior_fp_registers.fpu_fr);
+ memcpy (&inferior_fp_registers.Fpu_fsr,
+ &registers[REGISTER_BYTE (FPS_REGNUM)], sizeof (FPU_FSR_TYPE));
+ if (0 !=
+ ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0))
+ perror ("ptrace_setfpregs");
+ }
+}
+
+/* Provide registers to GDB from a core file.
+
+ CORE_REG_SECT points to an array of bytes, which are the contents
+ of a `note' from a core file which BFD thinks might contain
+ register contents. CORE_REG_SIZE is its size.
+
+ WHICH says which register set corelow suspects this is:
+ 0 --- the general-purpose register set
+ 2 --- the floating-point register set
+
+ IGNORE is unused. */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR ignore)
+{
+
+ if (which == 0)
+ {
+
+ /* Integer registers */
+
+#define gregs ((struct regs *)core_reg_sect)
+ /* G0 *always* holds 0. */
+ *(int *) &registers[REGISTER_BYTE (0)] = 0;
+
+ /* The globals and output registers. */
+ memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &gregs->r_g1,
+ 15 * REGISTER_RAW_SIZE (G1_REGNUM));
+ *(int *) &registers[REGISTER_BYTE (PS_REGNUM)] = gregs->r_ps;
+ *(int *) &registers[REGISTER_BYTE (PC_REGNUM)] = gregs->r_pc;
+ *(int *) &registers[REGISTER_BYTE (NPC_REGNUM)] = gregs->r_npc;
+ *(int *) &registers[REGISTER_BYTE (Y_REGNUM)] = gregs->r_y;
+
+ /* My best guess at where to get the locals and input
+ registers is exactly where they usually are, right above
+ the stack pointer. If the core dump was caused by a bus error
+ from blowing away the stack pointer (as is possible) then this
+ won't work, but it's worth the try. */
+ {
+ int sp;
+
+ sp = *(int *) &registers[REGISTER_BYTE (SP_REGNUM)];
+ if (0 != target_read_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
+ 16 * REGISTER_RAW_SIZE (L0_REGNUM)))
+ {
+ /* fprintf_unfiltered so user can still use gdb */
+ fprintf_unfiltered (gdb_stderr,
+ "Couldn't read input and local registers from core file\n");
+ }
+ }
+ }
+ else if (which == 2)
+ {
+
+ /* Floating point registers */
+
+#define fpuregs ((struct fpu *) core_reg_sect)
+ if (core_reg_size >= sizeof (struct fpu))
+ {
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], fpuregs->fpu_regs,
+ sizeof (fpuregs->fpu_regs));
+ memcpy (&registers[REGISTER_BYTE (FPS_REGNUM)], &fpuregs->fpu_fsr,
+ sizeof (FPU_FSR_TYPE));
+ }
+ else
+ fprintf_unfiltered (gdb_stderr, "Couldn't read float regs from core file\n");
+ }
+}
+
+int
+kernel_u_size (void)
+{
+ return (sizeof (struct user));
+}
+
+
+/* Register that we are able to handle sparc core file formats.
+ FIXME: is this really bfd_target_unknown_flavour? */
+
+static struct core_fns sparc_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_sparc (void)
+{
+ add_core_fns (&sparc_core_fns);
+}
diff --git a/gdb/sparc-stub.c b/gdb/sparc-stub.c
new file mode 100644
index 00000000000..1e6298a179e
--- /dev/null
+++ b/gdb/sparc-stub.c
@@ -0,0 +1,778 @@
+/****************************************************************************
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ HP offers the following for use in the public domain. HP makes no
+ warranty with regard to the software or it's performance and the
+ user accepts the software "AS IS" with all faults.
+
+ HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+ TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ * Module name: remcom.c $
+ * Revision: 1.34 $
+ * Date: 91/03/09 12:29:49 $
+ * Contributor: Lake Stevens Instrument Division$
+ *
+ * Description: low level support for gdb debugger. $
+ *
+ * Considerations: only works on target hardware $
+ *
+ * Written by: Glenn Engel $
+ * ModuleState: Experimental $
+ *
+ * NOTES: See Below $
+ *
+ * Modified for SPARC by Stu Grossman, Cygnus Support.
+ *
+ * This code has been extensively tested on the Fujitsu SPARClite demo board.
+ *
+ * To enable debugger support, two things need to happen. One, a
+ * call to set_debug_traps() is necessary in order to allow any breakpoints
+ * or error conditions to be properly intercepted and reported to gdb.
+ * Two, a breakpoint needs to be generated to begin communication. This
+ * is most easily accomplished by a call to breakpoint(). Breakpoint()
+ * simulates a breakpoint by executing a trap #1.
+ *
+ *************
+ *
+ * The following gdb commands are supported:
+ *
+ * command function Return value
+ *
+ * g return the value of the CPU registers hex data or ENN
+ * G set the value of the CPU registers OK or ENN
+ *
+ * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
+ * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
+ *
+ * c Resume at current address SNN ( signal NN)
+ * cAA..AA Continue at address AA..AA SNN
+ *
+ * s Step one instruction SNN
+ * sAA..AA Step one instruction from AA..AA SNN
+ *
+ * k kill
+ *
+ * ? What was the last sigval ? SNN (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum. A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer. '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host: Reply:
+ * $m0,10#2a +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <signal.h>
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+
+extern void putDebugChar(); /* write a single character */
+extern int getDebugChar(); /* read and return a single char */
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 2048
+
+static int initialized = 0; /* !0 means we've been initialized */
+
+static void set_mem_fault_trap();
+
+static const char hexchars[]="0123456789abcdef";
+
+#define NUMREGS 72
+
+/* Number of bytes of registers. */
+#define NUMREGBYTES (NUMREGS * 4)
+enum regnames {G0, G1, G2, G3, G4, G5, G6, G7,
+ O0, O1, O2, O3, O4, O5, SP, O7,
+ L0, L1, L2, L3, L4, L5, L6, L7,
+ I0, I1, I2, I3, I4, I5, FP, I7,
+
+ F0, F1, F2, F3, F4, F5, F6, F7,
+ F8, F9, F10, F11, F12, F13, F14, F15,
+ F16, F17, F18, F19, F20, F21, F22, F23,
+ F24, F25, F26, F27, F28, F29, F30, F31,
+ Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR };
+
+/*************************** ASSEMBLY CODE MACROS *************************/
+/* */
+
+extern void trap_low();
+
+asm("
+ .reserve trapstack, 1000 * 4, \"bss\", 8
+
+ .data
+ .align 4
+
+in_trap_handler:
+ .word 0
+
+ .text
+ .align 4
+
+! This function is called when any SPARC trap (except window overflow or
+! underflow) occurs. It makes sure that the invalid register window is still
+! available before jumping into C code. It will also restore the world if you
+! return from handle_exception.
+
+ .globl _trap_low
+_trap_low:
+ mov %psr, %l0
+ mov %wim, %l3
+
+ srl %l3, %l0, %l4 ! wim >> cwp
+ cmp %l4, 1
+ bne window_fine ! Branch if not in the invalid window
+ nop
+
+! Handle window overflow
+
+ mov %g1, %l4 ! Save g1, we use it to hold the wim
+ srl %l3, 1, %g1 ! Rotate wim right
+ tst %g1
+ bg good_wim ! Branch if new wim is non-zero
+ nop
+
+! At this point, we need to bring a 1 into the high order bit of the wim.
+! Since we don't want to make any assumptions about the number of register
+! windows, we figure it out dynamically so as to setup the wim correctly.
+
+ not %g1 ! Fill g1 with ones
+ mov %g1, %wim ! Fill the wim with ones
+ nop
+ nop
+ nop
+ mov %wim, %g1 ! Read back the wim
+ inc %g1 ! Now g1 has 1 just to left of wim
+ srl %g1, 1, %g1 ! Now put 1 at top of wim
+ mov %g0, %wim ! Clear wim so that subsequent save
+ nop ! won't trap
+ nop
+ nop
+
+good_wim:
+ save %g0, %g0, %g0 ! Slip into next window
+ mov %g1, %wim ! Install the new wim
+
+ std %l0, [%sp + 0 * 4] ! save L & I registers
+ std %l2, [%sp + 2 * 4]
+ std %l4, [%sp + 4 * 4]
+ std %l6, [%sp + 6 * 4]
+
+ std %i0, [%sp + 8 * 4]
+ std %i2, [%sp + 10 * 4]
+ std %i4, [%sp + 12 * 4]
+ std %i6, [%sp + 14 * 4]
+
+ restore ! Go back to trap window.
+ mov %l4, %g1 ! Restore %g1
+
+window_fine:
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ tst %l5
+ bg recursive_trap
+ inc %l5
+
+ set trapstack+1000*4, %sp ! Switch to trap stack
+
+recursive_trap:
+ st %l5, [%lo(in_trap_handler) + %l4]
+ sub %sp,(16+1+6+1+72)*4,%sp ! Make room for input & locals
+ ! + hidden arg + arg spill
+ ! + doubleword alignment
+ ! + registers[72] local var
+
+ std %g0, [%sp + (24 + 0) * 4] ! registers[Gx]
+ std %g2, [%sp + (24 + 2) * 4]
+ std %g4, [%sp + (24 + 4) * 4]
+ std %g6, [%sp + (24 + 6) * 4]
+
+ std %i0, [%sp + (24 + 8) * 4] ! registers[Ox]
+ std %i2, [%sp + (24 + 10) * 4]
+ std %i4, [%sp + (24 + 12) * 4]
+ std %i6, [%sp + (24 + 14) * 4]
+ ! F0->F31 not implemented
+ mov %y, %l4
+ mov %tbr, %l5
+ st %l4, [%sp + (24 + 64) * 4] ! Y
+ st %l0, [%sp + (24 + 65) * 4] ! PSR
+ st %l3, [%sp + (24 + 66) * 4] ! WIM
+ st %l5, [%sp + (24 + 67) * 4] ! TBR
+ st %l1, [%sp + (24 + 68) * 4] ! PC
+ st %l2, [%sp + (24 + 69) * 4] ! NPC
+
+ ! CPSR and FPSR not impl
+
+ or %l0, 0xf20, %l4
+ mov %l4, %psr ! Turn on traps, disable interrupts
+
+ call _handle_exception
+ add %sp, 24 * 4, %o0 ! Pass address of registers
+
+! Reload all of the registers that aren't on the stack
+
+ ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx]
+ ldd [%sp + (24 + 2) * 4], %g2
+ ldd [%sp + (24 + 4) * 4], %g4
+ ldd [%sp + (24 + 6) * 4], %g6
+
+ ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox]
+ ldd [%sp + (24 + 10) * 4], %i2
+ ldd [%sp + (24 + 12) * 4], %i4
+ ldd [%sp + (24 + 14) * 4], %i6
+
+ ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR
+ ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC
+
+ restore ! Ensure that previous window is valid
+ save %g0, %g0, %g0 ! by causing a window_underflow trap
+
+ mov %l0, %y
+ mov %l1, %psr ! Make sure that traps are disabled
+ ! for rett
+
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ dec %l5
+ st %l5, [%lo(in_trap_handler) + %l4]
+
+ jmpl %l2, %g0 ! Restore old PC
+ rett %l3 ! Restore old nPC
+");
+
+/* Convert ch from a hex digit to an int */
+
+static int
+hex (unsigned char ch)
+{
+ if (ch >= 'a' && ch <= 'f')
+ return ch-'a'+10;
+ if (ch >= '0' && ch <= '9')
+ return ch-'0';
+ if (ch >= 'A' && ch <= 'F')
+ return ch-'A'+10;
+ return -1;
+}
+
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+/* scan for the sequence $<data>#<checksum> */
+
+unsigned char *
+getpacket (void)
+{
+ unsigned char *buffer = &remcomInBuffer[0];
+ unsigned char checksum;
+ unsigned char xmitcsum;
+ int count;
+ char ch;
+
+ while (1)
+ {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = getDebugChar ()) != '$')
+ ;
+
+retry:
+ checksum = 0;
+ xmitcsum = -1;
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX)
+ {
+ ch = getDebugChar ();
+ if (ch == '$')
+ goto retry;
+ if (ch == '#')
+ break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+ buffer[count] = 0;
+
+ if (ch == '#')
+ {
+ ch = getDebugChar ();
+ xmitcsum = hex (ch) << 4;
+ ch = getDebugChar ();
+ xmitcsum += hex (ch);
+
+ if (checksum != xmitcsum)
+ {
+ putDebugChar ('-'); /* failed checksum */
+ }
+ else
+ {
+ putDebugChar ('+'); /* successful transfer */
+
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':')
+ {
+ putDebugChar (buffer[0]);
+ putDebugChar (buffer[1]);
+
+ return &buffer[3];
+ }
+
+ return &buffer[0];
+ }
+ }
+ }
+}
+
+/* send the packet in buffer. */
+
+static void
+putpacket (unsigned char *buffer)
+{
+ unsigned char checksum;
+ int count;
+ unsigned char ch;
+
+ /* $<packet info>#<checksum>. */
+ do
+ {
+ putDebugChar('$');
+ checksum = 0;
+ count = 0;
+
+ while (ch = buffer[count])
+ {
+ putDebugChar(ch);
+ checksum += ch;
+ count += 1;
+ }
+
+ putDebugChar('#');
+ putDebugChar(hexchars[checksum >> 4]);
+ putDebugChar(hexchars[checksum & 0xf]);
+
+ }
+ while (getDebugChar() != '+');
+}
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an
+ error. */
+static volatile int mem_err = 0;
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+ * Return a pointer to the last char put in buf (null), in case of mem fault,
+ * return 0.
+ * If MAY_FAULT is non-zero, then we will handle memory faults by returning
+ * a 0, else treat a fault like any other fault in the stub.
+ */
+
+static unsigned char *
+mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault)
+{
+ unsigned char ch;
+
+ set_mem_fault_trap(may_fault);
+
+ while (count-- > 0)
+ {
+ ch = *mem++;
+ if (mem_err)
+ return 0;
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch & 0xf];
+ }
+
+ *buf = 0;
+
+ set_mem_fault_trap(0);
+
+ return buf;
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem
+ * return a pointer to the character AFTER the last byte written */
+
+static char *
+hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
+{
+ int i;
+ unsigned char ch;
+
+ set_mem_fault_trap(may_fault);
+
+ for (i=0; i<count; i++)
+ {
+ ch = hex(*buf++) << 4;
+ ch |= hex(*buf++);
+ *mem++ = ch;
+ if (mem_err)
+ return 0;
+ }
+
+ set_mem_fault_trap(0);
+
+ return mem;
+}
+
+/* This table contains the mapping between SPARC hardware trap types, and
+ signals, which are primarily what GDB understands. It also indicates
+ which hardware traps we need to commandeer when initializing the stub. */
+
+static struct hard_trap_info
+{
+ unsigned char tt; /* Trap type code for SPARClite */
+ unsigned char signo; /* Signal that we map this trap into */
+} hard_trap_info[] = {
+ {1, SIGSEGV}, /* instruction access error */
+ {2, SIGILL}, /* privileged instruction */
+ {3, SIGILL}, /* illegal instruction */
+ {4, SIGEMT}, /* fp disabled */
+ {36, SIGEMT}, /* cp disabled */
+ {7, SIGBUS}, /* mem address not aligned */
+ {9, SIGSEGV}, /* data access exception */
+ {10, SIGEMT}, /* tag overflow */
+ {128+1, SIGTRAP}, /* ta 1 - normal breakpoint instruction */
+ {0, 0} /* Must be last */
+};
+
+/* Set up exception handlers for tracing and breakpoints */
+
+void
+set_debug_traps (void)
+{
+ struct hard_trap_info *ht;
+
+ for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+ exceptionHandler(ht->tt, trap_low);
+
+ initialized = 1;
+}
+
+asm ("
+! Trap handler for memory errors. This just sets mem_err to be non-zero. It
+! assumes that %l1 is non-zero. This should be safe, as it is doubtful that
+! 0 would ever contain code that could mem fault. This routine will skip
+! past the faulting instruction after setting mem_err.
+
+ .text
+ .align 4
+
+_fltr_set_mem_err:
+ sethi %hi(_mem_err), %l0
+ st %l1, [%l0 + %lo(_mem_err)]
+ jmpl %l2, %g0
+ rett %l2+4
+");
+
+static void
+set_mem_fault_trap (int enable)
+{
+ extern void fltr_set_mem_err();
+ mem_err = 0;
+
+ if (enable)
+ exceptionHandler(9, fltr_set_mem_err);
+ else
+ exceptionHandler(9, trap_low);
+}
+
+/* Convert the SPARC hardware trap type code to a unix signal number. */
+
+static int
+computeSignal (int tt)
+{
+ struct hard_trap_info *ht;
+
+ for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+ if (ht->tt == tt)
+ return ht->signo;
+
+ return SIGHUP; /* default for things we don't know about */
+}
+
+/*
+ * While we find nice hex chars, build an int.
+ * Return number of chars processed.
+ */
+
+static int
+hexToInt(char **ptr, int *intValue)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+
+ while (**ptr)
+ {
+ hexValue = hex(**ptr);
+ if (hexValue < 0)
+ break;
+
+ *intValue = (*intValue << 4) | hexValue;
+ numChars ++;
+
+ (*ptr)++;
+ }
+
+ return (numChars);
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb. It
+ * returns 1 if you should skip the instruction at the trap address, 0
+ * otherwise.
+ */
+
+extern void breakinst();
+
+static void
+handle_exception (unsigned long *registers)
+{
+ int tt; /* Trap type */
+ int sigval;
+ int addr;
+ int length;
+ char *ptr;
+ unsigned long *sp;
+
+/* First, we must force all of the windows to be spilled out */
+
+ asm(" save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+");
+
+ if (registers[PC] == (unsigned long)breakinst)
+ {
+ registers[PC] = registers[NPC];
+ registers[NPC] += 4;
+ }
+
+ sp = (unsigned long *)registers[SP];
+
+ tt = (registers[TBR] >> 4) & 0xff;
+
+ /* reply to host that an exception has occurred */
+ sigval = computeSignal(tt);
+ ptr = remcomOutBuffer;
+
+ *ptr++ = 'T';
+ *ptr++ = hexchars[sigval >> 4];
+ *ptr++ = hexchars[sigval & 0xf];
+
+ *ptr++ = hexchars[PC >> 4];
+ *ptr++ = hexchars[PC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[PC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[FP >> 4];
+ *ptr++ = hexchars[FP & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[SP >> 4];
+ *ptr++ = hexchars[SP & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&sp, ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[NPC >> 4];
+ *ptr++ = hexchars[NPC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[NPC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[O7 >> 4];
+ *ptr++ = hexchars[O7 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[O7], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = 0;
+
+ putpacket(remcomOutBuffer);
+
+ while (1)
+ {
+ remcomOutBuffer[0] = 0;
+
+ ptr = getpacket();
+ switch (*ptr++)
+ {
+ case '?':
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval & 0xf];
+ remcomOutBuffer[3] = 0;
+ break;
+
+ case 'd': /* toggle debug flag */
+ break;
+
+ case 'g': /* return the value of the CPU registers */
+ {
+ ptr = remcomOutBuffer;
+ ptr = mem2hex((char *)registers, ptr, 16 * 4, 0); /* G & O regs */
+ ptr = mem2hex(sp + 0, ptr, 16 * 4, 0); /* L & I regs */
+ memset(ptr, '0', 32 * 8); /* Floating point */
+ mem2hex((char *)&registers[Y],
+ ptr + 32 * 4 * 2,
+ 8 * 4,
+ 0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+ }
+ break;
+
+ case 'G': /* set the value of the CPU registers - return OK */
+ {
+ unsigned long *newsp, psr;
+
+ psr = registers[PSR];
+
+ hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */
+ hex2mem(ptr + 16 * 4 * 2, sp + 0, 16 * 4, 0); /* L & I regs */
+ hex2mem(ptr + 64 * 4 * 2, (char *)&registers[Y],
+ 8 * 4, 0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+
+ /* See if the stack pointer has moved. If so, then copy the saved
+ locals and ins to the new location. This keeps the window
+ overflow and underflow routines happy. */
+
+ newsp = (unsigned long *)registers[SP];
+ if (sp != newsp)
+ sp = memcpy(newsp, sp, 16 * 4);
+
+ /* Don't allow CWP to be modified. */
+
+ if (psr != registers[PSR])
+ registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
+
+ strcpy(remcomOutBuffer,"OK");
+ }
+ break;
+
+ case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ /* Try to read %x,%x. */
+
+ if (hexToInt(&ptr, &addr)
+ && *ptr++ == ','
+ && hexToInt(&ptr, &length))
+ {
+ if (mem2hex((char *)addr, remcomOutBuffer, length, 1))
+ break;
+
+ strcpy (remcomOutBuffer, "E03");
+ }
+ else
+ strcpy(remcomOutBuffer,"E01");
+ break;
+
+ case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ /* Try to read '%x,%x:'. */
+
+ if (hexToInt(&ptr, &addr)
+ && *ptr++ == ','
+ && hexToInt(&ptr, &length)
+ && *ptr++ == ':')
+ {
+ if (hex2mem(ptr, (char *)addr, length, 1))
+ strcpy(remcomOutBuffer, "OK");
+ else
+ strcpy(remcomOutBuffer, "E03");
+ }
+ else
+ strcpy(remcomOutBuffer, "E02");
+ break;
+
+ case 'c': /* cAA..AA Continue at address AA..AA(optional) */
+ /* try to read optional parameter, pc unchanged if no parm */
+
+ if (hexToInt(&ptr, &addr))
+ {
+ registers[PC] = addr;
+ registers[NPC] = addr + 4;
+ }
+
+/* Need to flush the instruction cache here, as we may have deposited a
+ breakpoint, and the icache probably has no way of knowing that a data ref to
+ some location may have changed something that is in the instruction cache.
+ */
+
+ flush_i_cache();
+ return;
+
+ /* kill the program */
+ case 'k' : /* do nothing */
+ break;
+#if 0
+ case 't': /* Test feature */
+ asm (" std %f30,[%sp]");
+ break;
+#endif
+ case 'r': /* Reset */
+ asm ("call 0
+ nop ");
+ break;
+ } /* switch */
+
+ /* reply to the request */
+ putpacket(remcomOutBuffer);
+ }
+}
+
+/* This function will generate a breakpoint exception. It is used at the
+ beginning of a program to sync up with a debugger and can be used
+ otherwise as a quick means to stop program execution and "break" into
+ the debugger. */
+
+void
+breakpoint (void)
+{
+ if (!initialized)
+ return;
+
+ asm(" .globl _breakinst
+
+ _breakinst: ta 1
+ ");
+}
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
new file mode 100644
index 00000000000..6461ca088f6
--- /dev/null
+++ b/gdb/sparc-tdep.c
@@ -0,0 +1,3286 @@
+/* Target-dependent code for the SPARC for GDB, the GNU debugger.
+
+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002 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. */
+
+/* ??? Support for calling functions from gdb in sparc64 is unfinished. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "frame.h"
+#include "inferior.h"
+#include "obstack.h"
+#include "target.h"
+#include "value.h"
+#include "bfd.h"
+#include "gdb_string.h"
+#include "regcache.h"
+
+#ifdef USE_PROC_FS
+#include <sys/procfs.h>
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+#endif
+
+#include "gdbcore.h"
+
+#include "symfile.h" /* for 'entry_point_address' */
+
+/*
+ * Some local macros that have multi-arch and non-multi-arch versions:
+ */
+
+#if (GDB_MULTI_ARCH > 0)
+
+/* Does the target have Floating Point registers? */
+#define SPARC_HAS_FPU (gdbarch_tdep (current_gdbarch)->has_fpu)
+/* Number of bytes devoted to Floating Point registers: */
+#define FP_REGISTER_BYTES (gdbarch_tdep (current_gdbarch)->fp_register_bytes)
+/* Highest numbered Floating Point register. */
+#define FP_MAX_REGNUM (gdbarch_tdep (current_gdbarch)->fp_max_regnum)
+/* Size of a general (integer) register: */
+#define SPARC_INTREG_SIZE (gdbarch_tdep (current_gdbarch)->intreg_size)
+/* Offset within the call dummy stack of the saved registers. */
+#define DUMMY_REG_SAVE_OFFSET (gdbarch_tdep (current_gdbarch)->reg_save_offset)
+
+#else /* non-multi-arch */
+
+
+/* Does the target have Floating Point registers? */
+#if defined(TARGET_SPARCLET) || defined(TARGET_SPARCLITE)
+#define SPARC_HAS_FPU 0
+#else
+#define SPARC_HAS_FPU 1
+#endif
+
+/* Number of bytes devoted to Floating Point registers: */
+#if (GDB_TARGET_IS_SPARC64)
+#define FP_REGISTER_BYTES (64 * 4)
+#else
+#if (SPARC_HAS_FPU)
+#define FP_REGISTER_BYTES (32 * 4)
+#else
+#define FP_REGISTER_BYTES 0
+#endif
+#endif
+
+/* Highest numbered Floating Point register. */
+#if (GDB_TARGET_IS_SPARC64)
+#define FP_MAX_REGNUM (FP0_REGNUM + 48)
+#else
+#define FP_MAX_REGNUM (FP0_REGNUM + 32)
+#endif
+
+/* Size of a general (integer) register: */
+#define SPARC_INTREG_SIZE (REGISTER_RAW_SIZE (G0_REGNUM))
+
+/* Offset within the call dummy stack of the saved registers. */
+#if (GDB_TARGET_IS_SPARC64)
+#define DUMMY_REG_SAVE_OFFSET (128 + 16)
+#else
+#define DUMMY_REG_SAVE_OFFSET 0x60
+#endif
+
+#endif /* GDB_MULTI_ARCH */
+
+struct gdbarch_tdep
+ {
+ int has_fpu;
+ int fp_register_bytes;
+ int y_regnum;
+ int fp_max_regnum;
+ int intreg_size;
+ int reg_save_offset;
+ int call_dummy_call_offset;
+ int print_insn_mach;
+ };
+
+/* Now make GDB_TARGET_IS_SPARC64 a runtime test. */
+/* FIXME MVS: or try testing bfd_arch_info.arch and bfd_arch_info.mach ...
+ * define GDB_TARGET_IS_SPARC64 \
+ * (TARGET_ARCHITECTURE->arch == bfd_arch_sparc && \
+ * (TARGET_ARCHITECTURE->mach == bfd_mach_sparc_v9 || \
+ * TARGET_ARCHITECTURE->mach == bfd_mach_sparc_v9a))
+ */
+
+/* From infrun.c */
+extern int stop_after_trap;
+
+/* We don't store all registers immediately when requested, since they
+ get sent over in large chunks anyway. Instead, we accumulate most
+ of the changes and send them over once. "deferred_stores" keeps
+ track of which sets of registers we have locally-changed copies of,
+ so we only need send the groups that have changed. */
+
+int deferred_stores = 0; /* Accumulated stores we want to do eventually. */
+
+
+/* Some machines, such as Fujitsu SPARClite 86x, have a bi-endian mode
+ where instructions are big-endian and data are little-endian.
+ This flag is set when we detect that the target is of this type. */
+
+int bi_endian = 0;
+
+
+/* Fetch a single instruction. Even on bi-endian machines
+ such as sparc86x, instructions are always big-endian. */
+
+static unsigned long
+fetch_instruction (CORE_ADDR pc)
+{
+ unsigned long retval;
+ int i;
+ unsigned char buf[4];
+
+ read_memory (pc, buf, sizeof (buf));
+
+ /* Start at the most significant end of the integer, and work towards
+ the least significant. */
+ retval = 0;
+ for (i = 0; i < sizeof (buf); ++i)
+ retval = (retval << 8) | buf[i];
+ return retval;
+}
+
+
+/* Branches with prediction are treated like their non-predicting cousins. */
+/* FIXME: What about floating point branches? */
+
+/* Macros to extract fields from sparc instructions. */
+#define X_OP(i) (((i) >> 30) & 0x3)
+#define X_RD(i) (((i) >> 25) & 0x1f)
+#define X_A(i) (((i) >> 29) & 1)
+#define X_COND(i) (((i) >> 25) & 0xf)
+#define X_OP2(i) (((i) >> 22) & 0x7)
+#define X_IMM22(i) ((i) & 0x3fffff)
+#define X_OP3(i) (((i) >> 19) & 0x3f)
+#define X_RS1(i) (((i) >> 14) & 0x1f)
+#define X_I(i) (((i) >> 13) & 1)
+#define X_IMM13(i) ((i) & 0x1fff)
+/* Sign extension macros. */
+#define X_SIMM13(i) ((X_IMM13 (i) ^ 0x1000) - 0x1000)
+#define X_DISP22(i) ((X_IMM22 (i) ^ 0x200000) - 0x200000)
+#define X_CC(i) (((i) >> 20) & 3)
+#define X_P(i) (((i) >> 19) & 1)
+#define X_DISP19(i) ((((i) & 0x7ffff) ^ 0x40000) - 0x40000)
+#define X_RCOND(i) (((i) >> 25) & 7)
+#define X_DISP16(i) ((((((i) >> 6) && 0xc000) | ((i) & 0x3fff)) ^ 0x8000) - 0x8000)
+#define X_FCN(i) (((i) >> 25) & 31)
+
+typedef enum
+{
+ Error, not_branch, bicc, bicca, ba, baa, ticc, ta, done_retry
+} branch_type;
+
+/* Simulate single-step ptrace call for sun4. Code written by Gary
+ Beihl (beihl@mcc.com). */
+
+/* npc4 and next_pc describe the situation at the time that the
+ step-breakpoint was set, not necessary the current value of NPC_REGNUM. */
+static CORE_ADDR next_pc, npc4, target;
+static int brknpc4, brktrg;
+typedef char binsn_quantum[BREAKPOINT_MAX];
+static binsn_quantum break_mem[3];
+
+static branch_type isbranch (long, CORE_ADDR, CORE_ADDR *);
+
+/* single_step() is called just before we want to resume the inferior,
+ if we want to single-step it but there is no hardware or kernel single-step
+ support (as on all SPARCs). We find all the possible targets of the
+ coming instruction and breakpoint them.
+
+ single_step is also called just after the inferior stops. If we had
+ set up a simulated single-step, we undo our damage. */
+
+void
+sparc_software_single_step (enum target_signal ignore, /* pid, but we don't need it */
+ int insert_breakpoints_p)
+{
+ branch_type br;
+ CORE_ADDR pc;
+ long pc_instruction;
+
+ if (insert_breakpoints_p)
+ {
+ /* Always set breakpoint for NPC. */
+ next_pc = read_register (NPC_REGNUM);
+ npc4 = next_pc + 4; /* branch not taken */
+
+ target_insert_breakpoint (next_pc, break_mem[0]);
+ /* printf_unfiltered ("set break at %x\n",next_pc); */
+
+ pc = read_register (PC_REGNUM);
+ pc_instruction = fetch_instruction (pc);
+ br = isbranch (pc_instruction, pc, &target);
+ brknpc4 = brktrg = 0;
+
+ if (br == bicca)
+ {
+ /* Conditional annulled branch will either end up at
+ npc (if taken) or at npc+4 (if not taken).
+ Trap npc+4. */
+ brknpc4 = 1;
+ target_insert_breakpoint (npc4, break_mem[1]);
+ }
+ else if (br == baa && target != next_pc)
+ {
+ /* Unconditional annulled branch will always end up at
+ the target. */
+ brktrg = 1;
+ target_insert_breakpoint (target, break_mem[2]);
+ }
+ else if (GDB_TARGET_IS_SPARC64 && br == done_retry)
+ {
+ brktrg = 1;
+ target_insert_breakpoint (target, break_mem[2]);
+ }
+ }
+ else
+ {
+ /* Remove breakpoints */
+ target_remove_breakpoint (next_pc, break_mem[0]);
+
+ if (brknpc4)
+ target_remove_breakpoint (npc4, break_mem[1]);
+
+ if (brktrg)
+ target_remove_breakpoint (target, break_mem[2]);
+ }
+}
+
+struct frame_extra_info
+{
+ CORE_ADDR bottom;
+ int in_prologue;
+ int flat;
+ /* Following fields only relevant for flat frames. */
+ CORE_ADDR pc_addr;
+ CORE_ADDR fp_addr;
+ /* Add this to ->frame to get the value of the stack pointer at the
+ time of the register saves. */
+ int sp_offset;
+};
+
+/* Call this for each newly created frame. For SPARC, we need to
+ calculate the bottom of the frame, and do some extra work if the
+ prologue has been generated via the -mflat option to GCC. In
+ particular, we need to know where the previous fp and the pc have
+ been stashed, since their exact position within the frame may vary. */
+
+void
+sparc_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ char *name;
+ CORE_ADDR prologue_start, prologue_end;
+ int insn;
+
+ fi->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+ frame_saved_regs_zalloc (fi);
+
+ fi->extra_info->bottom =
+ (fi->next ?
+ (fi->frame == fi->next->frame ? fi->next->extra_info->bottom :
+ fi->next->frame) : read_sp ());
+
+ /* If fi->next is NULL, then we already set ->frame by passing read_fp()
+ to create_new_frame. */
+ if (fi->next)
+ {
+ char *buf;
+
+ buf = alloca (MAX_REGISTER_RAW_SIZE);
+
+ /* Compute ->frame as if not flat. If it is flat, we'll change
+ it later. */
+ if (fi->next->next != NULL
+ && (fi->next->next->signal_handler_caller
+ || frame_in_dummy (fi->next->next))
+ && frameless_look_for_prologue (fi->next))
+ {
+ /* A frameless function interrupted by a signal did not change
+ the frame pointer, fix up frame pointer accordingly. */
+ fi->frame = FRAME_FP (fi->next);
+ fi->extra_info->bottom = fi->next->extra_info->bottom;
+ }
+ else
+ {
+ /* Should we adjust for stack bias here? */
+ get_saved_register (buf, 0, 0, fi, FP_REGNUM, 0);
+ fi->frame = extract_address (buf, REGISTER_RAW_SIZE (FP_REGNUM));
+
+ if (GDB_TARGET_IS_SPARC64 && (fi->frame & 1))
+ fi->frame += 2047;
+ }
+ }
+
+ /* Decide whether this is a function with a ``flat register window''
+ frame. For such functions, the frame pointer is actually in %i7. */
+ fi->extra_info->flat = 0;
+ fi->extra_info->in_prologue = 0;
+ if (find_pc_partial_function (fi->pc, &name, &prologue_start, &prologue_end))
+ {
+ /* See if the function starts with an add (which will be of a
+ negative number if a flat frame) to the sp. FIXME: Does not
+ handle large frames which will need more than one instruction
+ to adjust the sp. */
+ insn = fetch_instruction (prologue_start);
+ if (X_OP (insn) == 2 && X_RD (insn) == 14 && X_OP3 (insn) == 0
+ && X_I (insn) && X_SIMM13 (insn) < 0)
+ {
+ int offset = X_SIMM13 (insn);
+
+ /* Then look for a save of %i7 into the frame. */
+ insn = fetch_instruction (prologue_start + 4);
+ if (X_OP (insn) == 3
+ && X_RD (insn) == 31
+ && X_OP3 (insn) == 4
+ && X_RS1 (insn) == 14)
+ {
+ char *buf;
+
+ buf = alloca (MAX_REGISTER_RAW_SIZE);
+
+ /* We definitely have a flat frame now. */
+ fi->extra_info->flat = 1;
+
+ fi->extra_info->sp_offset = offset;
+
+ /* Overwrite the frame's address with the value in %i7. */
+ get_saved_register (buf, 0, 0, fi, I7_REGNUM, 0);
+ fi->frame = extract_address (buf, REGISTER_RAW_SIZE (I7_REGNUM));
+
+ if (GDB_TARGET_IS_SPARC64 && (fi->frame & 1))
+ fi->frame += 2047;
+
+ /* Record where the fp got saved. */
+ fi->extra_info->fp_addr =
+ fi->frame + fi->extra_info->sp_offset + X_SIMM13 (insn);
+
+ /* Also try to collect where the pc got saved to. */
+ fi->extra_info->pc_addr = 0;
+ insn = fetch_instruction (prologue_start + 12);
+ if (X_OP (insn) == 3
+ && X_RD (insn) == 15
+ && X_OP3 (insn) == 4
+ && X_RS1 (insn) == 14)
+ fi->extra_info->pc_addr =
+ fi->frame + fi->extra_info->sp_offset + X_SIMM13 (insn);
+ }
+ }
+ else
+ {
+ /* Check if the PC is in the function prologue before a SAVE
+ instruction has been executed yet. If so, set the frame
+ to the current value of the stack pointer and set
+ the in_prologue flag. */
+ CORE_ADDR addr;
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (prologue_start, 0);
+ if (sal.line == 0) /* no line info, use PC */
+ prologue_end = fi->pc;
+ else if (sal.end < prologue_end)
+ prologue_end = sal.end;
+ if (fi->pc < prologue_end)
+ {
+ for (addr = prologue_start; addr < fi->pc; addr += 4)
+ {
+ insn = read_memory_integer (addr, 4);
+ if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3c)
+ break; /* SAVE seen, stop searching */
+ }
+ if (addr >= fi->pc)
+ {
+ fi->extra_info->in_prologue = 1;
+ fi->frame = read_register (SP_REGNUM);
+ }
+ }
+ }
+ }
+ if (fi->next && fi->frame == 0)
+ {
+ /* Kludge to cause init_prev_frame_info to destroy the new frame. */
+ fi->frame = fi->next->frame;
+ fi->pc = fi->next->pc;
+ }
+}
+
+CORE_ADDR
+sparc_frame_chain (struct frame_info *frame)
+{
+ /* Value that will cause FRAME_CHAIN_VALID to not worry about the chain
+ value. If it really is zero, we detect it later in
+ sparc_init_prev_frame. */
+ return (CORE_ADDR) 1;
+}
+
+CORE_ADDR
+sparc_extract_struct_value_address (char *regbuf)
+{
+ return extract_address (regbuf + REGISTER_BYTE (O0_REGNUM),
+ REGISTER_RAW_SIZE (O0_REGNUM));
+}
+
+/* Find the pc saved in frame FRAME. */
+
+CORE_ADDR
+sparc_frame_saved_pc (struct frame_info *frame)
+{
+ char *buf;
+ CORE_ADDR addr;
+
+ buf = alloca (MAX_REGISTER_RAW_SIZE);
+ if (frame->signal_handler_caller)
+ {
+ /* This is the signal trampoline frame.
+ Get the saved PC from the sigcontext structure. */
+
+#ifndef SIGCONTEXT_PC_OFFSET
+#define SIGCONTEXT_PC_OFFSET 12
+#endif
+
+ CORE_ADDR sigcontext_addr;
+ char *scbuf;
+ int saved_pc_offset = SIGCONTEXT_PC_OFFSET;
+ char *name = NULL;
+
+ scbuf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT);
+
+ /* Solaris2 ucbsigvechandler passes a pointer to a sigcontext
+ as the third parameter. The offset to the saved pc is 12. */
+ find_pc_partial_function (frame->pc, &name,
+ (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
+ if (name && STREQ (name, "ucbsigvechandler"))
+ saved_pc_offset = 12;
+
+ /* The sigcontext address is contained in register O2. */
+ get_saved_register (buf, (int *) NULL, (CORE_ADDR *) NULL,
+ frame, O0_REGNUM + 2, (enum lval_type *) NULL);
+ sigcontext_addr = extract_address (buf, REGISTER_RAW_SIZE (O0_REGNUM + 2));
+
+ /* Don't cause a memory_error when accessing sigcontext in case the
+ stack layout has changed or the stack is corrupt. */
+ target_read_memory (sigcontext_addr + saved_pc_offset,
+ scbuf, sizeof (scbuf));
+ return extract_address (scbuf, sizeof (scbuf));
+ }
+ else if (frame->extra_info->in_prologue ||
+ (frame->next != NULL &&
+ (frame->next->signal_handler_caller ||
+ frame_in_dummy (frame->next)) &&
+ frameless_look_for_prologue (frame)))
+ {
+ /* A frameless function interrupted by a signal did not save
+ the PC, it is still in %o7. */
+ get_saved_register (buf, (int *) NULL, (CORE_ADDR *) NULL,
+ frame, O7_REGNUM, (enum lval_type *) NULL);
+ return PC_ADJUST (extract_address (buf, SPARC_INTREG_SIZE));
+ }
+ if (frame->extra_info->flat)
+ addr = frame->extra_info->pc_addr;
+ else
+ addr = frame->extra_info->bottom + FRAME_SAVED_I0 +
+ SPARC_INTREG_SIZE * (I7_REGNUM - I0_REGNUM);
+
+ if (addr == 0)
+ /* A flat frame leaf function might not save the PC anywhere,
+ just leave it in %o7. */
+ return PC_ADJUST (read_register (O7_REGNUM));
+
+ read_memory (addr, buf, SPARC_INTREG_SIZE);
+ return PC_ADJUST (extract_address (buf, SPARC_INTREG_SIZE));
+}
+
+/* Since an individual frame in the frame cache is defined by two
+ arguments (a frame pointer and a stack pointer), we need two
+ arguments to get info for an arbitrary stack frame. This routine
+ takes two arguments and makes the cached frames look as if these
+ two arguments defined a frame on the cache. This allows the rest
+ of info frame to extract the important arguments without
+ difficulty. */
+
+struct frame_info *
+setup_arbitrary_frame (int argc, CORE_ADDR *argv)
+{
+ struct frame_info *frame;
+
+ if (argc != 2)
+ error ("Sparc frame specifications require two arguments: fp and sp");
+
+ frame = create_new_frame (argv[0], 0);
+
+ if (!frame)
+ internal_error (__FILE__, __LINE__,
+ "create_new_frame returned invalid frame");
+
+ frame->extra_info->bottom = argv[1];
+ frame->pc = FRAME_SAVED_PC (frame);
+ return frame;
+}
+
+/* Given a pc value, skip it forward past the function prologue by
+ disassembling instructions that appear to be a prologue.
+
+ If FRAMELESS_P is set, we are only testing to see if the function
+ is frameless. This allows a quicker answer.
+
+ This routine should be more specific in its actions; making sure
+ that it uses the same register in the initial prologue section. */
+
+static CORE_ADDR examine_prologue (CORE_ADDR, int, struct frame_info *,
+ CORE_ADDR *);
+
+static CORE_ADDR
+examine_prologue (CORE_ADDR start_pc, int frameless_p, struct frame_info *fi,
+ CORE_ADDR *saved_regs)
+{
+ int insn;
+ int dest = -1;
+ CORE_ADDR pc = start_pc;
+ int is_flat = 0;
+
+ insn = fetch_instruction (pc);
+
+ /* Recognize the `sethi' insn and record its destination. */
+ if (X_OP (insn) == 0 && X_OP2 (insn) == 4)
+ {
+ dest = X_RD (insn);
+ pc += 4;
+ insn = fetch_instruction (pc);
+ }
+
+ /* Recognize an add immediate value to register to either %g1 or
+ the destination register recorded above. Actually, this might
+ well recognize several different arithmetic operations.
+ It doesn't check that rs1 == rd because in theory "sub %g0, 5, %g1"
+ followed by "save %sp, %g1, %sp" is a valid prologue (Not that
+ I imagine any compiler really does that, however). */
+ if (X_OP (insn) == 2
+ && X_I (insn)
+ && (X_RD (insn) == 1 || X_RD (insn) == dest))
+ {
+ pc += 4;
+ insn = fetch_instruction (pc);
+ }
+
+ /* Recognize any SAVE insn. */
+ if (X_OP (insn) == 2 && X_OP3 (insn) == 60)
+ {
+ pc += 4;
+ if (frameless_p) /* If the save is all we care about, */
+ return pc; /* return before doing more work */
+ insn = fetch_instruction (pc);
+ }
+ /* Recognize add to %sp. */
+ else if (X_OP (insn) == 2 && X_RD (insn) == 14 && X_OP3 (insn) == 0)
+ {
+ pc += 4;
+ if (frameless_p) /* If the add is all we care about, */
+ return pc; /* return before doing more work */
+ is_flat = 1;
+ insn = fetch_instruction (pc);
+ /* Recognize store of frame pointer (i7). */
+ if (X_OP (insn) == 3
+ && X_RD (insn) == 31
+ && X_OP3 (insn) == 4
+ && X_RS1 (insn) == 14)
+ {
+ pc += 4;
+ insn = fetch_instruction (pc);
+
+ /* Recognize sub %sp, <anything>, %i7. */
+ if (X_OP (insn) == 2
+ && X_OP3 (insn) == 4
+ && X_RS1 (insn) == 14
+ && X_RD (insn) == 31)
+ {
+ pc += 4;
+ insn = fetch_instruction (pc);
+ }
+ else
+ return pc;
+ }
+ else
+ return pc;
+ }
+ else
+ /* Without a save or add instruction, it's not a prologue. */
+ return start_pc;
+
+ while (1)
+ {
+ /* Recognize stores into the frame from the input registers.
+ This recognizes all non alternate stores of an input register,
+ into a location offset from the frame pointer between
+ +68 and +92. */
+
+ /* The above will fail for arguments that are promoted
+ (eg. shorts to ints or floats to doubles), because the compiler
+ will pass them in positive-offset frame space, but the prologue
+ will save them (after conversion) in negative frame space at an
+ unpredictable offset. Therefore I am going to remove the
+ restriction on the target-address of the save, on the theory
+ that any unbroken sequence of saves from input registers must
+ be part of the prologue. In un-optimized code (at least), I'm
+ fairly sure that the compiler would emit SOME other instruction
+ (eg. a move or add) before emitting another save that is actually
+ a part of the function body.
+
+ Besides, the reserved stack space is different for SPARC64 anyway.
+
+ MVS 4/23/2000 */
+
+ if (X_OP (insn) == 3
+ && (X_OP3 (insn) & 0x3c) == 4 /* Store, non-alternate. */
+ && (X_RD (insn) & 0x18) == 0x18 /* Input register. */
+ && X_I (insn) /* Immediate mode. */
+ && X_RS1 (insn) == 30) /* Off of frame pointer. */
+ ; /* empty statement -- fall thru to end of loop */
+ else if (GDB_TARGET_IS_SPARC64
+ && X_OP (insn) == 3
+ && (X_OP3 (insn) & 0x3c) == 12 /* store, extended (64-bit) */
+ && (X_RD (insn) & 0x18) == 0x18 /* input register */
+ && X_I (insn) /* immediate mode */
+ && X_RS1 (insn) == 30) /* off of frame pointer */
+ ; /* empty statement -- fall thru to end of loop */
+ else if (X_OP (insn) == 3
+ && (X_OP3 (insn) & 0x3c) == 36 /* store, floating-point */
+ && X_I (insn) /* immediate mode */
+ && X_RS1 (insn) == 30) /* off of frame pointer */
+ ; /* empty statement -- fall thru to end of loop */
+ else if (is_flat
+ && X_OP (insn) == 3
+ && X_OP3 (insn) == 4 /* store? */
+ && X_RS1 (insn) == 14) /* off of frame pointer */
+ {
+ if (saved_regs && X_I (insn))
+ saved_regs[X_RD (insn)] =
+ fi->frame + fi->extra_info->sp_offset + X_SIMM13 (insn);
+ }
+ else
+ break;
+ pc += 4;
+ insn = fetch_instruction (pc);
+ }
+
+ return pc;
+}
+
+/* Advance PC across any function entry prologue instructions to reach
+ some "real" code. */
+
+CORE_ADDR
+sparc_skip_prologue (CORE_ADDR start_pc)
+{
+ struct symtab_and_line sal;
+ CORE_ADDR func_start, func_end;
+
+ /* This is the preferred method, find the end of the prologue by
+ using the debugging information. */
+ if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
+ {
+ sal = find_pc_line (func_start, 0);
+
+ if (sal.end < func_end
+ && start_pc <= sal.end)
+ return sal.end;
+ }
+
+ /* Oh well, examine the code by hand. */
+ return examine_prologue (start_pc, 0, NULL, NULL);
+}
+
+/* Is the prologue at IP frameless? */
+
+int
+sparc_prologue_frameless_p (CORE_ADDR ip)
+{
+ return ip == examine_prologue (ip, 1, NULL, NULL);
+}
+
+/* Check instruction at ADDR to see if it is a branch.
+ All non-annulled instructions will go to NPC or will trap.
+ Set *TARGET if we find a candidate branch; set to zero if not.
+
+ This isn't static as it's used by remote-sa.sparc.c. */
+
+static branch_type
+isbranch (long instruction, CORE_ADDR addr, CORE_ADDR *target)
+{
+ branch_type val = not_branch;
+ long int offset = 0; /* Must be signed for sign-extend. */
+
+ *target = 0;
+
+ if (X_OP (instruction) == 0
+ && (X_OP2 (instruction) == 2
+ || X_OP2 (instruction) == 6
+ || X_OP2 (instruction) == 1
+ || X_OP2 (instruction) == 3
+ || X_OP2 (instruction) == 5
+ || (GDB_TARGET_IS_SPARC64 && X_OP2 (instruction) == 7)))
+ {
+ if (X_COND (instruction) == 8)
+ val = X_A (instruction) ? baa : ba;
+ else
+ val = X_A (instruction) ? bicca : bicc;
+ switch (X_OP2 (instruction))
+ {
+ case 7:
+ if (!GDB_TARGET_IS_SPARC64)
+ break;
+ /* else fall thru */
+ case 2:
+ case 6:
+ offset = 4 * X_DISP22 (instruction);
+ break;
+ case 1:
+ case 5:
+ offset = 4 * X_DISP19 (instruction);
+ break;
+ case 3:
+ offset = 4 * X_DISP16 (instruction);
+ break;
+ }
+ *target = addr + offset;
+ }
+ else if (GDB_TARGET_IS_SPARC64
+ && X_OP (instruction) == 2
+ && X_OP3 (instruction) == 62)
+ {
+ if (X_FCN (instruction) == 0)
+ {
+ /* done */
+ *target = read_register (TNPC_REGNUM);
+ val = done_retry;
+ }
+ else if (X_FCN (instruction) == 1)
+ {
+ /* retry */
+ *target = read_register (TPC_REGNUM);
+ val = done_retry;
+ }
+ }
+
+ return val;
+}
+
+/* Find register number REGNUM relative to FRAME and put its
+ (raw) contents in *RAW_BUFFER. Set *OPTIMIZED if the variable
+ was optimized out (and thus can't be fetched). If the variable
+ was fetched from memory, set *ADDRP to where it was fetched from,
+ otherwise it was fetched from a register.
+
+ The argument RAW_BUFFER must point to aligned memory. */
+
+void
+sparc_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp,
+ struct frame_info *frame, int regnum,
+ enum lval_type *lval)
+{
+ struct frame_info *frame1;
+ CORE_ADDR addr;
+
+ if (!target_has_registers)
+ error ("No registers.");
+
+ if (optimized)
+ *optimized = 0;
+
+ addr = 0;
+
+ /* FIXME This code extracted from infcmd.c; should put elsewhere! */
+ if (frame == NULL)
+ {
+ /* error ("No selected frame."); */
+ if (!target_has_registers)
+ error ("The program has no registers now.");
+ if (selected_frame == NULL)
+ error ("No selected frame.");
+ /* Try to use selected frame */
+ frame = get_prev_frame (selected_frame);
+ if (frame == 0)
+ error ("Cmd not meaningful in the outermost frame.");
+ }
+
+
+ frame1 = frame->next;
+
+ /* Get saved PC from the frame info if not in innermost frame. */
+ if (regnum == PC_REGNUM && frame1 != NULL)
+ {
+ if (lval != NULL)
+ *lval = not_lval;
+ if (raw_buffer != NULL)
+ {
+ /* Put it back in target format. */
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), frame->pc);
+ }
+ if (addrp != NULL)
+ *addrp = 0;
+ return;
+ }
+
+ while (frame1 != NULL)
+ {
+ /* FIXME MVS: wrong test for dummy frame at entry. */
+
+ if (frame1->pc >= (frame1->extra_info->bottom ?
+ frame1->extra_info->bottom : read_sp ())
+ && frame1->pc <= FRAME_FP (frame1))
+ {
+ /* Dummy frame. All but the window regs are in there somewhere.
+ The window registers are saved on the stack, just like in a
+ normal frame. */
+ if (regnum >= G1_REGNUM && regnum < G1_REGNUM + 7)
+ addr = frame1->frame + (regnum - G0_REGNUM) * SPARC_INTREG_SIZE
+ - (FP_REGISTER_BYTES + 8 * SPARC_INTREG_SIZE);
+ else if (regnum >= I0_REGNUM && regnum < I0_REGNUM + 8)
+ /* NOTE: cagney/2002-05-04: The call to get_prev_frame()
+ is safe/cheap - there will always be a prev frame.
+ This is because frame1 is initialized to frame->next
+ (frame1->prev == frame) and is then advanced towards
+ the innermost (next) frame. */
+ addr = (get_prev_frame (frame1)->extra_info->bottom
+ + (regnum - I0_REGNUM) * SPARC_INTREG_SIZE
+ + FRAME_SAVED_I0);
+ else if (regnum >= L0_REGNUM && regnum < L0_REGNUM + 8)
+ /* NOTE: cagney/2002-05-04: The call to get_prev_frame()
+ is safe/cheap - there will always be a prev frame.
+ This is because frame1 is initialized to frame->next
+ (frame1->prev == frame) and is then advanced towards
+ the innermost (next) frame. */
+ addr = (get_prev_frame (frame1)->extra_info->bottom
+ + (regnum - L0_REGNUM) * SPARC_INTREG_SIZE
+ + FRAME_SAVED_L0);
+ else if (regnum >= O0_REGNUM && regnum < O0_REGNUM + 8)
+ addr = frame1->frame + (regnum - O0_REGNUM) * SPARC_INTREG_SIZE
+ - (FP_REGISTER_BYTES + 16 * SPARC_INTREG_SIZE);
+ else if (SPARC_HAS_FPU &&
+ regnum >= FP0_REGNUM && regnum < FP0_REGNUM + 32)
+ addr = frame1->frame + (regnum - FP0_REGNUM) * 4
+ - (FP_REGISTER_BYTES);
+ else if (GDB_TARGET_IS_SPARC64 && SPARC_HAS_FPU &&
+ regnum >= FP0_REGNUM + 32 && regnum < FP_MAX_REGNUM)
+ addr = frame1->frame + 32 * 4 + (regnum - FP0_REGNUM - 32) * 8
+ - (FP_REGISTER_BYTES);
+ else if (regnum >= Y_REGNUM && regnum < NUM_REGS)
+ addr = frame1->frame + (regnum - Y_REGNUM) * SPARC_INTREG_SIZE
+ - (FP_REGISTER_BYTES + 24 * SPARC_INTREG_SIZE);
+ }
+ else if (frame1->extra_info->flat)
+ {
+
+ if (regnum == RP_REGNUM)
+ addr = frame1->extra_info->pc_addr;
+ else if (regnum == I7_REGNUM)
+ addr = frame1->extra_info->fp_addr;
+ else
+ {
+ CORE_ADDR func_start;
+ CORE_ADDR *regs;
+
+ regs = alloca (NUM_REGS * sizeof (CORE_ADDR));
+ memset (regs, 0, NUM_REGS * sizeof (CORE_ADDR));
+
+ find_pc_partial_function (frame1->pc, NULL, &func_start, NULL);
+ examine_prologue (func_start, 0, frame1, regs);
+ addr = regs[regnum];
+ }
+ }
+ else
+ {
+ /* Normal frame. Local and In registers are saved on stack. */
+ if (regnum >= I0_REGNUM && regnum < I0_REGNUM + 8)
+ addr = (get_prev_frame (frame1)->extra_info->bottom
+ + (regnum - I0_REGNUM) * SPARC_INTREG_SIZE
+ + FRAME_SAVED_I0);
+ else if (regnum >= L0_REGNUM && regnum < L0_REGNUM + 8)
+ addr = (get_prev_frame (frame1)->extra_info->bottom
+ + (regnum - L0_REGNUM) * SPARC_INTREG_SIZE
+ + FRAME_SAVED_L0);
+ else if (regnum >= O0_REGNUM && regnum < O0_REGNUM + 8)
+ {
+ /* Outs become ins. */
+ get_saved_register (raw_buffer, optimized, addrp, frame1,
+ (regnum - O0_REGNUM + I0_REGNUM), lval);
+ return;
+ }
+ }
+ if (addr != 0)
+ break;
+ frame1 = frame1->next;
+ }
+ if (addr != 0)
+ {
+ if (lval != NULL)
+ *lval = lval_memory;
+ if (regnum == SP_REGNUM)
+ {
+ if (raw_buffer != NULL)
+ {
+ /* Put it back in target format. */
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), addr);
+ }
+ if (addrp != NULL)
+ *addrp = 0;
+ return;
+ }
+ if (raw_buffer != NULL)
+ read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum));
+ }
+ else
+ {
+ if (lval != NULL)
+ *lval = lval_register;
+ addr = REGISTER_BYTE (regnum);
+ if (raw_buffer != NULL)
+ read_register_gen (regnum, raw_buffer);
+ }
+ if (addrp != NULL)
+ *addrp = addr;
+}
+
+/* Push an empty stack frame, and record in it the current PC, regs, etc.
+
+ We save the non-windowed registers and the ins. The locals and outs
+ are new; they don't need to be saved. The i's and l's of
+ the last frame were already saved on the stack. */
+
+/* Definitely see tm-sparc.h for more doc of the frame format here. */
+
+/* See tm-sparc.h for how this is calculated. */
+
+#define DUMMY_STACK_REG_BUF_SIZE \
+ (((8+8+8) * SPARC_INTREG_SIZE) + FP_REGISTER_BYTES)
+#define DUMMY_STACK_SIZE \
+ (DUMMY_STACK_REG_BUF_SIZE + DUMMY_REG_SAVE_OFFSET)
+
+void
+sparc_push_dummy_frame (void)
+{
+ CORE_ADDR sp, old_sp;
+ char *register_temp;
+
+ register_temp = alloca (DUMMY_STACK_SIZE);
+
+ old_sp = sp = read_sp ();
+
+ if (GDB_TARGET_IS_SPARC64)
+ {
+ /* PC, NPC, CCR, FSR, FPRS, Y, ASI */
+ read_register_bytes (REGISTER_BYTE (PC_REGNUM), &register_temp[0],
+ REGISTER_RAW_SIZE (PC_REGNUM) * 7);
+ read_register_bytes (REGISTER_BYTE (PSTATE_REGNUM),
+ &register_temp[7 * SPARC_INTREG_SIZE],
+ REGISTER_RAW_SIZE (PSTATE_REGNUM));
+ /* FIXME: not sure what needs to be saved here. */
+ }
+ else
+ {
+ /* Y, PS, WIM, TBR, PC, NPC, FPS, CPS regs */
+ read_register_bytes (REGISTER_BYTE (Y_REGNUM), &register_temp[0],
+ REGISTER_RAW_SIZE (Y_REGNUM) * 8);
+ }
+
+ read_register_bytes (REGISTER_BYTE (O0_REGNUM),
+ &register_temp[8 * SPARC_INTREG_SIZE],
+ SPARC_INTREG_SIZE * 8);
+
+ read_register_bytes (REGISTER_BYTE (G0_REGNUM),
+ &register_temp[16 * SPARC_INTREG_SIZE],
+ SPARC_INTREG_SIZE * 8);
+
+ if (SPARC_HAS_FPU)
+ read_register_bytes (REGISTER_BYTE (FP0_REGNUM),
+ &register_temp[24 * SPARC_INTREG_SIZE],
+ FP_REGISTER_BYTES);
+
+ sp -= DUMMY_STACK_SIZE;
+
+ write_sp (sp);
+
+ write_memory (sp + DUMMY_REG_SAVE_OFFSET, &register_temp[0],
+ DUMMY_STACK_REG_BUF_SIZE);
+
+ if (strcmp (target_shortname, "sim") != 0)
+ {
+ /* NOTE: cagney/2002-04-04: The code below originally contained
+ GDB's _only_ call to write_fp(). That call was eliminated by
+ inlining the corresponding code. For the 64 bit case, the
+ old function (sparc64_write_fp) did the below although I'm
+ not clear why. The same goes for why this is only done when
+ the underlying target is a simulator. */
+ if (GDB_TARGET_IS_SPARC64)
+ {
+ /* Target is a 64 bit SPARC. */
+ CORE_ADDR oldfp = read_register (FP_REGNUM);
+ if (oldfp & 1)
+ write_register (FP_REGNUM, old_sp - 2047);
+ else
+ write_register (FP_REGNUM, old_sp);
+ }
+ else
+ {
+ /* Target is a 32 bit SPARC. */
+ write_register (FP_REGNUM, old_sp);
+ }
+ /* Set return address register for the call dummy to the current PC. */
+ write_register (I7_REGNUM, read_pc () - 8);
+ }
+ else
+ {
+ /* The call dummy will write this value to FP before executing
+ the 'save'. This ensures that register window flushes work
+ correctly in the simulator. */
+ write_register (G0_REGNUM + 1, read_register (FP_REGNUM));
+
+ /* The call dummy will write this value to FP after executing
+ the 'save'. */
+ write_register (G0_REGNUM + 2, old_sp);
+
+ /* The call dummy will write this value to the return address (%i7) after
+ executing the 'save'. */
+ write_register (G0_REGNUM + 3, read_pc () - 8);
+
+ /* Set the FP that the call dummy will be using after the 'save'.
+ This makes backtraces from an inferior function call work properly. */
+ write_register (FP_REGNUM, old_sp);
+ }
+}
+
+/* sparc_frame_find_saved_regs (). This function is here only because
+ pop_frame uses it. Note there is an interesting corner case which
+ I think few ports of GDB get right--if you are popping a frame
+ which does not save some register that *is* saved by a more inner
+ frame (such a frame will never be a dummy frame because dummy
+ frames save all registers). Rewriting pop_frame to use
+ get_saved_register would solve this problem and also get rid of the
+ ugly duplication between sparc_frame_find_saved_regs and
+ get_saved_register.
+
+ Stores, into an array of CORE_ADDR,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame.
+
+ Note that on register window machines, we are currently making the
+ assumption that window registers are being saved somewhere in the
+ frame in which they are being used. If they are stored in an
+ inferior frame, find_saved_register will break.
+
+ On the Sun 4, the only time all registers are saved is when
+ a dummy frame is involved. Otherwise, the only saved registers
+ are the LOCAL and IN registers which are saved as a result
+ of the "save/restore" opcodes. This condition is determined
+ by address rather than by value.
+
+ The "pc" is not stored in a frame on the SPARC. (What is stored
+ is a return address minus 8.) sparc_pop_frame knows how to
+ deal with that. Other routines might or might not.
+
+ See tm-sparc.h (PUSH_DUMMY_FRAME and friends) for CRITICAL information
+ about how this works. */
+
+static void sparc_frame_find_saved_regs (struct frame_info *, CORE_ADDR *);
+
+static void
+sparc_frame_find_saved_regs (struct frame_info *fi, CORE_ADDR *saved_regs_addr)
+{
+ register int regnum;
+ CORE_ADDR frame_addr = FRAME_FP (fi);
+
+ if (!fi)
+ internal_error (__FILE__, __LINE__,
+ "Bad frame info struct in FRAME_FIND_SAVED_REGS");
+
+ memset (saved_regs_addr, 0, NUM_REGS * sizeof (CORE_ADDR));
+
+ if (fi->pc >= (fi->extra_info->bottom ?
+ fi->extra_info->bottom : read_sp ())
+ && fi->pc <= FRAME_FP (fi))
+ {
+ /* Dummy frame. All but the window regs are in there somewhere. */
+ for (regnum = G1_REGNUM; regnum < G1_REGNUM + 7; regnum++)
+ saved_regs_addr[regnum] =
+ frame_addr + (regnum - G0_REGNUM) * SPARC_INTREG_SIZE
+ - DUMMY_STACK_REG_BUF_SIZE + 16 * SPARC_INTREG_SIZE;
+
+ for (regnum = I0_REGNUM; regnum < I0_REGNUM + 8; regnum++)
+ saved_regs_addr[regnum] =
+ frame_addr + (regnum - I0_REGNUM) * SPARC_INTREG_SIZE
+ - DUMMY_STACK_REG_BUF_SIZE + 8 * SPARC_INTREG_SIZE;
+
+ if (SPARC_HAS_FPU)
+ for (regnum = FP0_REGNUM; regnum < FP_MAX_REGNUM; regnum++)
+ saved_regs_addr[regnum] = frame_addr + (regnum - FP0_REGNUM) * 4
+ - DUMMY_STACK_REG_BUF_SIZE + 24 * SPARC_INTREG_SIZE;
+
+ if (GDB_TARGET_IS_SPARC64)
+ {
+ for (regnum = PC_REGNUM; regnum < PC_REGNUM + 7; regnum++)
+ {
+ saved_regs_addr[regnum] =
+ frame_addr + (regnum - PC_REGNUM) * SPARC_INTREG_SIZE
+ - DUMMY_STACK_REG_BUF_SIZE;
+ }
+ saved_regs_addr[PSTATE_REGNUM] =
+ frame_addr + 8 * SPARC_INTREG_SIZE - DUMMY_STACK_REG_BUF_SIZE;
+ }
+ else
+ for (regnum = Y_REGNUM; regnum < NUM_REGS; regnum++)
+ saved_regs_addr[regnum] =
+ frame_addr + (regnum - Y_REGNUM) * SPARC_INTREG_SIZE
+ - DUMMY_STACK_REG_BUF_SIZE;
+
+ frame_addr = fi->extra_info->bottom ?
+ fi->extra_info->bottom : read_sp ();
+ }
+ else if (fi->extra_info->flat)
+ {
+ CORE_ADDR func_start;
+ find_pc_partial_function (fi->pc, NULL, &func_start, NULL);
+ examine_prologue (func_start, 0, fi, saved_regs_addr);
+
+ /* Flat register window frame. */
+ saved_regs_addr[RP_REGNUM] = fi->extra_info->pc_addr;
+ saved_regs_addr[I7_REGNUM] = fi->extra_info->fp_addr;
+ }
+ else
+ {
+ /* Normal frame. Just Local and In registers */
+ frame_addr = fi->extra_info->bottom ?
+ fi->extra_info->bottom : read_sp ();
+ for (regnum = L0_REGNUM; regnum < L0_REGNUM + 8; regnum++)
+ saved_regs_addr[regnum] =
+ (frame_addr + (regnum - L0_REGNUM) * SPARC_INTREG_SIZE
+ + FRAME_SAVED_L0);
+ for (regnum = I0_REGNUM; regnum < I0_REGNUM + 8; regnum++)
+ saved_regs_addr[regnum] =
+ (frame_addr + (regnum - I0_REGNUM) * SPARC_INTREG_SIZE
+ + FRAME_SAVED_I0);
+ }
+ if (fi->next)
+ {
+ if (fi->extra_info->flat)
+ {
+ saved_regs_addr[O7_REGNUM] = fi->extra_info->pc_addr;
+ }
+ else
+ {
+ /* Pull off either the next frame pointer or the stack pointer */
+ CORE_ADDR next_next_frame_addr =
+ (fi->next->extra_info->bottom ?
+ fi->next->extra_info->bottom : read_sp ());
+ for (regnum = O0_REGNUM; regnum < O0_REGNUM + 8; regnum++)
+ saved_regs_addr[regnum] =
+ (next_next_frame_addr
+ + (regnum - O0_REGNUM) * SPARC_INTREG_SIZE
+ + FRAME_SAVED_I0);
+ }
+ }
+ /* Otherwise, whatever we would get from ptrace(GETREGS) is accurate */
+ /* FIXME -- should this adjust for the sparc64 offset? */
+ saved_regs_addr[SP_REGNUM] = FRAME_FP (fi);
+}
+
+/* Discard from the stack the innermost frame, restoring all saved registers.
+
+ Note that the values stored in fsr by get_frame_saved_regs are *in
+ the context of the called frame*. What this means is that the i
+ regs of fsr must be restored into the o regs of the (calling) frame that
+ we pop into. We don't care about the output regs of the calling frame,
+ since unless it's a dummy frame, it won't have any output regs in it.
+
+ We never have to bother with %l (local) regs, since the called routine's
+ locals get tossed, and the calling routine's locals are already saved
+ on its stack. */
+
+/* Definitely see tm-sparc.h for more doc of the frame format here. */
+
+void
+sparc_pop_frame (void)
+{
+ register struct frame_info *frame = get_current_frame ();
+ register CORE_ADDR pc;
+ CORE_ADDR *fsr;
+ char *raw_buffer;
+ int regnum;
+
+ fsr = alloca (NUM_REGS * sizeof (CORE_ADDR));
+ raw_buffer = alloca (REGISTER_BYTES);
+ sparc_frame_find_saved_regs (frame, &fsr[0]);
+ if (SPARC_HAS_FPU)
+ {
+ if (fsr[FP0_REGNUM])
+ {
+ read_memory (fsr[FP0_REGNUM], raw_buffer, FP_REGISTER_BYTES);
+ write_register_bytes (REGISTER_BYTE (FP0_REGNUM),
+ raw_buffer, FP_REGISTER_BYTES);
+ }
+ if (!(GDB_TARGET_IS_SPARC64))
+ {
+ if (fsr[FPS_REGNUM])
+ {
+ read_memory (fsr[FPS_REGNUM], raw_buffer, SPARC_INTREG_SIZE);
+ write_register_gen (FPS_REGNUM, raw_buffer);
+ }
+ if (fsr[CPS_REGNUM])
+ {
+ read_memory (fsr[CPS_REGNUM], raw_buffer, SPARC_INTREG_SIZE);
+ write_register_gen (CPS_REGNUM, raw_buffer);
+ }
+ }
+ }
+ if (fsr[G1_REGNUM])
+ {
+ read_memory (fsr[G1_REGNUM], raw_buffer, 7 * SPARC_INTREG_SIZE);
+ write_register_bytes (REGISTER_BYTE (G1_REGNUM), raw_buffer,
+ 7 * SPARC_INTREG_SIZE);
+ }
+
+ if (frame->extra_info->flat)
+ {
+ /* Each register might or might not have been saved, need to test
+ individually. */
+ for (regnum = L0_REGNUM; regnum < L0_REGNUM + 8; ++regnum)
+ if (fsr[regnum])
+ write_register (regnum, read_memory_integer (fsr[regnum],
+ SPARC_INTREG_SIZE));
+ for (regnum = I0_REGNUM; regnum < I0_REGNUM + 8; ++regnum)
+ if (fsr[regnum])
+ write_register (regnum, read_memory_integer (fsr[regnum],
+ SPARC_INTREG_SIZE));
+
+ /* Handle all outs except stack pointer (o0-o5; o7). */
+ for (regnum = O0_REGNUM; regnum < O0_REGNUM + 6; ++regnum)
+ if (fsr[regnum])
+ write_register (regnum, read_memory_integer (fsr[regnum],
+ SPARC_INTREG_SIZE));
+ if (fsr[O0_REGNUM + 7])
+ write_register (O0_REGNUM + 7,
+ read_memory_integer (fsr[O0_REGNUM + 7],
+ SPARC_INTREG_SIZE));
+
+ write_sp (frame->frame);
+ }
+ else if (fsr[I0_REGNUM])
+ {
+ CORE_ADDR sp;
+
+ char *reg_temp;
+
+ reg_temp = alloca (SPARC_INTREG_SIZE * 16);
+
+ read_memory (fsr[I0_REGNUM], raw_buffer, 8 * SPARC_INTREG_SIZE);
+
+ /* Get the ins and locals which we are about to restore. Just
+ moving the stack pointer is all that is really needed, except
+ store_inferior_registers is then going to write the ins and
+ locals from the registers array, so we need to muck with the
+ registers array. */
+ sp = fsr[SP_REGNUM];
+
+ if (GDB_TARGET_IS_SPARC64 && (sp & 1))
+ sp += 2047;
+
+ read_memory (sp, reg_temp, SPARC_INTREG_SIZE * 16);
+
+ /* Restore the out registers.
+ Among other things this writes the new stack pointer. */
+ write_register_bytes (REGISTER_BYTE (O0_REGNUM), raw_buffer,
+ SPARC_INTREG_SIZE * 8);
+
+ write_register_bytes (REGISTER_BYTE (L0_REGNUM), reg_temp,
+ SPARC_INTREG_SIZE * 16);
+ }
+
+ if (!(GDB_TARGET_IS_SPARC64))
+ if (fsr[PS_REGNUM])
+ write_register (PS_REGNUM,
+ read_memory_integer (fsr[PS_REGNUM],
+ REGISTER_RAW_SIZE (PS_REGNUM)));
+
+ if (fsr[Y_REGNUM])
+ write_register (Y_REGNUM,
+ read_memory_integer (fsr[Y_REGNUM],
+ REGISTER_RAW_SIZE (Y_REGNUM)));
+ if (fsr[PC_REGNUM])
+ {
+ /* Explicitly specified PC (and maybe NPC) -- just restore them. */
+ write_register (PC_REGNUM,
+ read_memory_integer (fsr[PC_REGNUM],
+ REGISTER_RAW_SIZE (PC_REGNUM)));
+ if (fsr[NPC_REGNUM])
+ write_register (NPC_REGNUM,
+ read_memory_integer (fsr[NPC_REGNUM],
+ REGISTER_RAW_SIZE (NPC_REGNUM)));
+ }
+ else if (frame->extra_info->flat)
+ {
+ if (frame->extra_info->pc_addr)
+ pc = PC_ADJUST ((CORE_ADDR)
+ read_memory_integer (frame->extra_info->pc_addr,
+ REGISTER_RAW_SIZE (PC_REGNUM)));
+ else
+ {
+ /* I think this happens only in the innermost frame, if so then
+ it is a complicated way of saying
+ "pc = read_register (O7_REGNUM);". */
+ char *buf;
+
+ buf = alloca (MAX_REGISTER_RAW_SIZE);
+ get_saved_register (buf, 0, 0, frame, O7_REGNUM, 0);
+ pc = PC_ADJUST (extract_address
+ (buf, REGISTER_RAW_SIZE (O7_REGNUM)));
+ }
+
+ write_register (PC_REGNUM, pc);
+ write_register (NPC_REGNUM, pc + 4);
+ }
+ else if (fsr[I7_REGNUM])
+ {
+ /* Return address in %i7 -- adjust it, then restore PC and NPC from it */
+ pc = PC_ADJUST ((CORE_ADDR) read_memory_integer (fsr[I7_REGNUM],
+ SPARC_INTREG_SIZE));
+ write_register (PC_REGNUM, pc);
+ write_register (NPC_REGNUM, pc + 4);
+ }
+ flush_cached_frames ();
+}
+
+/* On the Sun 4 under SunOS, the compile will leave a fake insn which
+ encodes the structure size being returned. If we detect such
+ a fake insn, step past it. */
+
+CORE_ADDR
+sparc_pc_adjust (CORE_ADDR pc)
+{
+ unsigned long insn;
+ char buf[4];
+ int err;
+
+ err = target_read_memory (pc + 8, buf, 4);
+ insn = extract_unsigned_integer (buf, 4);
+ if ((err == 0) && (insn & 0xffc00000) == 0)
+ return pc + 12;
+ else
+ return pc + 8;
+}
+
+/* If pc is in a shared library trampoline, return its target.
+ The SunOs 4.x linker rewrites the jump table entries for PIC
+ compiled modules in the main executable to bypass the dynamic linker
+ with jumps of the form
+ sethi %hi(addr),%g1
+ jmp %g1+%lo(addr)
+ and removes the corresponding jump table relocation entry in the
+ dynamic relocations.
+ find_solib_trampoline_target relies on the presence of the jump
+ table relocation entry, so we have to detect these jump instructions
+ by hand. */
+
+CORE_ADDR
+sunos4_skip_trampoline_code (CORE_ADDR pc)
+{
+ unsigned long insn1;
+ char buf[4];
+ int err;
+
+ err = target_read_memory (pc, buf, 4);
+ insn1 = extract_unsigned_integer (buf, 4);
+ if (err == 0 && (insn1 & 0xffc00000) == 0x03000000)
+ {
+ unsigned long insn2;
+
+ err = target_read_memory (pc + 4, buf, 4);
+ insn2 = extract_unsigned_integer (buf, 4);
+ if (err == 0 && (insn2 & 0xffffe000) == 0x81c06000)
+ {
+ CORE_ADDR target_pc = (insn1 & 0x3fffff) << 10;
+ int delta = insn2 & 0x1fff;
+
+ /* Sign extend the displacement. */
+ if (delta & 0x1000)
+ delta |= ~0x1fff;
+ return target_pc + delta;
+ }
+ }
+ return find_solib_trampoline_target (pc);
+}
+
+#ifdef USE_PROC_FS /* Target dependent support for /proc */
+/* *INDENT-OFF* */
+/* The /proc interface divides the target machine's register set up into
+ two different sets, the general register set (gregset) and the floating
+ point register set (fpregset). For each set, there is an ioctl to get
+ the current register set and another ioctl to set the current values.
+
+ The actual structure passed through the ioctl interface is, of course,
+ naturally machine dependent, and is different for each set of registers.
+ For the sparc for example, the general register set is typically defined
+ by:
+
+ typedef int gregset_t[38];
+
+ #define R_G0 0
+ ...
+ #define R_TBR 37
+
+ and the floating point set by:
+
+ typedef struct prfpregset {
+ union {
+ u_long pr_regs[32];
+ double pr_dregs[16];
+ } pr_fr;
+ void * pr_filler;
+ u_long pr_fsr;
+ u_char pr_qcnt;
+ u_char pr_q_entrysize;
+ u_char pr_en;
+ u_long pr_q[64];
+ } prfpregset_t;
+
+ These routines provide the packing and unpacking of gregset_t and
+ fpregset_t formatted data.
+
+ */
+/* *INDENT-ON* */
+
+/* Given a pointer to a general register set in /proc format (gregset_t *),
+ unpack the register contents and supply them as gdb's idea of the current
+ register values. */
+
+void
+supply_gregset (gdb_gregset_t *gregsetp)
+{
+ prgreg_t *regp = (prgreg_t *) gregsetp;
+ int regi, offset = 0;
+
+ /* If the host is 64-bit sparc, but the target is 32-bit sparc,
+ then the gregset may contain 64-bit ints while supply_register
+ is expecting 32-bit ints. Compensate. */
+ if (sizeof (regp[0]) == 8 && SPARC_INTREG_SIZE == 4)
+ offset = 4;
+
+ /* GDB register numbers for Gn, On, Ln, In all match /proc reg numbers. */
+ /* FIXME MVS: assumes the order of the first 32 elements... */
+ for (regi = G0_REGNUM; regi <= I7_REGNUM; regi++)
+ {
+ supply_register (regi, ((char *) (regp + regi)) + offset);
+ }
+
+ /* These require a bit more care. */
+ supply_register (PC_REGNUM, ((char *) (regp + R_PC)) + offset);
+ supply_register (NPC_REGNUM, ((char *) (regp + R_nPC)) + offset);
+ supply_register (Y_REGNUM, ((char *) (regp + R_Y)) + offset);
+
+ if (GDB_TARGET_IS_SPARC64)
+ {
+#ifdef R_CCR
+ supply_register (CCR_REGNUM, ((char *) (regp + R_CCR)) + offset);
+#else
+ supply_register (CCR_REGNUM, NULL);
+#endif
+#ifdef R_FPRS
+ supply_register (FPRS_REGNUM, ((char *) (regp + R_FPRS)) + offset);
+#else
+ supply_register (FPRS_REGNUM, NULL);
+#endif
+#ifdef R_ASI
+ supply_register (ASI_REGNUM, ((char *) (regp + R_ASI)) + offset);
+#else
+ supply_register (ASI_REGNUM, NULL);
+#endif
+ }
+ else /* sparc32 */
+ {
+#ifdef R_PS
+ supply_register (PS_REGNUM, ((char *) (regp + R_PS)) + offset);
+#else
+ supply_register (PS_REGNUM, NULL);
+#endif
+
+ /* For 64-bit hosts, R_WIM and R_TBR may not be defined.
+ Steal R_ASI and R_FPRS, and hope for the best! */
+
+#if !defined (R_WIM) && defined (R_ASI)
+#define R_WIM R_ASI
+#endif
+
+#if !defined (R_TBR) && defined (R_FPRS)
+#define R_TBR R_FPRS
+#endif
+
+#if defined (R_WIM)
+ supply_register (WIM_REGNUM, ((char *) (regp + R_WIM)) + offset);
+#else
+ supply_register (WIM_REGNUM, NULL);
+#endif
+
+#if defined (R_TBR)
+ supply_register (TBR_REGNUM, ((char *) (regp + R_TBR)) + offset);
+#else
+ supply_register (TBR_REGNUM, NULL);
+#endif
+ }
+
+ /* Fill inaccessible registers with zero. */
+ if (GDB_TARGET_IS_SPARC64)
+ {
+ /*
+ * don't know how to get value of any of the following:
+ */
+ supply_register (VER_REGNUM, NULL);
+ supply_register (TICK_REGNUM, NULL);
+ supply_register (PIL_REGNUM, NULL);
+ supply_register (PSTATE_REGNUM, NULL);
+ supply_register (TSTATE_REGNUM, NULL);
+ supply_register (TBA_REGNUM, NULL);
+ supply_register (TL_REGNUM, NULL);
+ supply_register (TT_REGNUM, NULL);
+ supply_register (TPC_REGNUM, NULL);
+ supply_register (TNPC_REGNUM, NULL);
+ supply_register (WSTATE_REGNUM, NULL);
+ supply_register (CWP_REGNUM, NULL);
+ supply_register (CANSAVE_REGNUM, NULL);
+ supply_register (CANRESTORE_REGNUM, NULL);
+ supply_register (CLEANWIN_REGNUM, NULL);
+ supply_register (OTHERWIN_REGNUM, NULL);
+ supply_register (ASR16_REGNUM, NULL);
+ supply_register (ASR17_REGNUM, NULL);
+ supply_register (ASR18_REGNUM, NULL);
+ supply_register (ASR19_REGNUM, NULL);
+ supply_register (ASR20_REGNUM, NULL);
+ supply_register (ASR21_REGNUM, NULL);
+ supply_register (ASR22_REGNUM, NULL);
+ supply_register (ASR23_REGNUM, NULL);
+ supply_register (ASR24_REGNUM, NULL);
+ supply_register (ASR25_REGNUM, NULL);
+ supply_register (ASR26_REGNUM, NULL);
+ supply_register (ASR27_REGNUM, NULL);
+ supply_register (ASR28_REGNUM, NULL);
+ supply_register (ASR29_REGNUM, NULL);
+ supply_register (ASR30_REGNUM, NULL);
+ supply_register (ASR31_REGNUM, NULL);
+ supply_register (ICC_REGNUM, NULL);
+ supply_register (XCC_REGNUM, NULL);
+ }
+ else
+ {
+ supply_register (CPS_REGNUM, NULL);
+ }
+}
+
+void
+fill_gregset (gdb_gregset_t *gregsetp, int regno)
+{
+ prgreg_t *regp = (prgreg_t *) gregsetp;
+ int regi, offset = 0;
+
+ /* If the host is 64-bit sparc, but the target is 32-bit sparc,
+ then the gregset may contain 64-bit ints while supply_register
+ is expecting 32-bit ints. Compensate. */
+ if (sizeof (regp[0]) == 8 && SPARC_INTREG_SIZE == 4)
+ offset = 4;
+
+ for (regi = 0; regi <= R_I7; regi++)
+ if ((regno == -1) || (regno == regi))
+ read_register_gen (regi, (char *) (regp + regi) + offset);
+
+ if ((regno == -1) || (regno == PC_REGNUM))
+ read_register_gen (PC_REGNUM, (char *) (regp + R_PC) + offset);
+
+ if ((regno == -1) || (regno == NPC_REGNUM))
+ read_register_gen (NPC_REGNUM, (char *) (regp + R_nPC) + offset);
+
+ if ((regno == -1) || (regno == Y_REGNUM))
+ read_register_gen (Y_REGNUM, (char *) (regp + R_Y) + offset);
+
+ if (GDB_TARGET_IS_SPARC64)
+ {
+#ifdef R_CCR
+ if (regno == -1 || regno == CCR_REGNUM)
+ read_register_gen (CCR_REGNUM, ((char *) (regp + R_CCR)) + offset);
+#endif
+#ifdef R_FPRS
+ if (regno == -1 || regno == FPRS_REGNUM)
+ read_register_gen (FPRS_REGNUM, ((char *) (regp + R_FPRS)) + offset);
+#endif
+#ifdef R_ASI
+ if (regno == -1 || regno == ASI_REGNUM)
+ read_register_gen (ASI_REGNUM, ((char *) (regp + R_ASI)) + offset);
+#endif
+ }
+ else /* sparc32 */
+ {
+#ifdef R_PS
+ if (regno == -1 || regno == PS_REGNUM)
+ read_register_gen (PS_REGNUM, ((char *) (regp + R_PS)) + offset);
+#endif
+
+ /* For 64-bit hosts, R_WIM and R_TBR may not be defined.
+ Steal R_ASI and R_FPRS, and hope for the best! */
+
+#if !defined (R_WIM) && defined (R_ASI)
+#define R_WIM R_ASI
+#endif
+
+#if !defined (R_TBR) && defined (R_FPRS)
+#define R_TBR R_FPRS
+#endif
+
+#if defined (R_WIM)
+ if (regno == -1 || regno == WIM_REGNUM)
+ read_register_gen (WIM_REGNUM, ((char *) (regp + R_WIM)) + offset);
+#else
+ if (regno == -1 || regno == WIM_REGNUM)
+ read_register_gen (WIM_REGNUM, NULL);
+#endif
+
+#if defined (R_TBR)
+ if (regno == -1 || regno == TBR_REGNUM)
+ read_register_gen (TBR_REGNUM, ((char *) (regp + R_TBR)) + offset);
+#else
+ if (regno == -1 || regno == TBR_REGNUM)
+ read_register_gen (TBR_REGNUM, NULL);
+#endif
+ }
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), unpack the register contents and supply them as gdb's
+ idea of the current floating point register values. */
+
+void
+supply_fpregset (gdb_fpregset_t *fpregsetp)
+{
+ register int regi;
+ char *from;
+
+ if (!SPARC_HAS_FPU)
+ return;
+
+ for (regi = FP0_REGNUM; regi < FP_MAX_REGNUM; regi++)
+ {
+ from = (char *) &fpregsetp->pr_fr.pr_regs[regi - FP0_REGNUM];
+ supply_register (regi, from);
+ }
+
+ if (GDB_TARGET_IS_SPARC64)
+ {
+ /*
+ * don't know how to get value of the following.
+ */
+ supply_register (FSR_REGNUM, NULL); /* zero it out for now */
+ supply_register (FCC0_REGNUM, NULL);
+ supply_register (FCC1_REGNUM, NULL); /* don't know how to get value */
+ supply_register (FCC2_REGNUM, NULL); /* don't know how to get value */
+ supply_register (FCC3_REGNUM, NULL); /* don't know how to get value */
+ }
+ else
+ {
+ supply_register (FPS_REGNUM, (char *) &(fpregsetp->pr_fsr));
+ }
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), update the register specified by REGNO from gdb's idea
+ of the current floating point register set. If REGNO is -1, update
+ them all. */
+/* This will probably need some changes for sparc64. */
+
+void
+fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
+{
+ int regi;
+ char *to;
+ char *from;
+
+ if (!SPARC_HAS_FPU)
+ return;
+
+ for (regi = FP0_REGNUM; regi < FP_MAX_REGNUM; regi++)
+ {
+ if ((regno == -1) || (regno == regi))
+ {
+ from = (char *) &registers[REGISTER_BYTE (regi)];
+ to = (char *) &fpregsetp->pr_fr.pr_regs[regi - FP0_REGNUM];
+ memcpy (to, from, REGISTER_RAW_SIZE (regi));
+ }
+ }
+
+ if (!(GDB_TARGET_IS_SPARC64)) /* FIXME: does Sparc64 have this register? */
+ if ((regno == -1) || (regno == FPS_REGNUM))
+ {
+ from = (char *)&registers[REGISTER_BYTE (FPS_REGNUM)];
+ to = (char *) &fpregsetp->pr_fsr;
+ memcpy (to, from, REGISTER_RAW_SIZE (FPS_REGNUM));
+ }
+}
+
+#endif /* USE_PROC_FS */
+
+/* Because of Multi-arch, GET_LONGJMP_TARGET is always defined. So test
+ for a definition of JB_PC. */
+#ifdef JB_PC
+
+/* Figure out where the longjmp will land. We expect that we have just entered
+ longjmp and haven't yet setup the stack frame, so the args are still in the
+ output regs. %o0 (O0_REGNUM) points at the jmp_buf structure from which we
+ extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+int
+get_longjmp_target (CORE_ADDR *pc)
+{
+ CORE_ADDR jb_addr;
+#define LONGJMP_TARGET_SIZE 4
+ char buf[LONGJMP_TARGET_SIZE];
+
+ jb_addr = read_register (O0_REGNUM);
+
+ if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
+ LONGJMP_TARGET_SIZE))
+ return 0;
+
+ *pc = extract_address (buf, LONGJMP_TARGET_SIZE);
+
+ return 1;
+}
+#endif /* GET_LONGJMP_TARGET */
+
+#ifdef STATIC_TRANSFORM_NAME
+/* SunPRO (3.0 at least), encodes the static variables. This is not
+ related to C++ mangling, it is done for C too. */
+
+char *
+sunpro_static_transform_name (char *name)
+{
+ char *p;
+ if (name[0] == '$')
+ {
+ /* For file-local statics there will be a dollar sign, a bunch
+ of junk (the contents of which match a string given in the
+ N_OPT), a period and the name. For function-local statics
+ there will be a bunch of junk (which seems to change the
+ second character from 'A' to 'B'), a period, the name of the
+ function, and the name. So just skip everything before the
+ last period. */
+ p = strrchr (name, '.');
+ if (p != NULL)
+ name = p + 1;
+ }
+ return name;
+}
+#endif /* STATIC_TRANSFORM_NAME */
+
+
+/* Utilities for printing registers.
+ Page numbers refer to the SPARC Architecture Manual. */
+
+static void dump_ccreg (char *, int);
+
+static void
+dump_ccreg (char *reg, int val)
+{
+ /* page 41 */
+ printf_unfiltered ("%s:%s,%s,%s,%s", reg,
+ val & 8 ? "N" : "NN",
+ val & 4 ? "Z" : "NZ",
+ val & 2 ? "O" : "NO",
+ val & 1 ? "C" : "NC");
+}
+
+static char *
+decode_asi (int val)
+{
+ /* page 72 */
+ switch (val)
+ {
+ case 4:
+ return "ASI_NUCLEUS";
+ case 0x0c:
+ return "ASI_NUCLEUS_LITTLE";
+ case 0x10:
+ return "ASI_AS_IF_USER_PRIMARY";
+ case 0x11:
+ return "ASI_AS_IF_USER_SECONDARY";
+ case 0x18:
+ return "ASI_AS_IF_USER_PRIMARY_LITTLE";
+ case 0x19:
+ return "ASI_AS_IF_USER_SECONDARY_LITTLE";
+ case 0x80:
+ return "ASI_PRIMARY";
+ case 0x81:
+ return "ASI_SECONDARY";
+ case 0x82:
+ return "ASI_PRIMARY_NOFAULT";
+ case 0x83:
+ return "ASI_SECONDARY_NOFAULT";
+ case 0x88:
+ return "ASI_PRIMARY_LITTLE";
+ case 0x89:
+ return "ASI_SECONDARY_LITTLE";
+ case 0x8a:
+ return "ASI_PRIMARY_NOFAULT_LITTLE";
+ case 0x8b:
+ return "ASI_SECONDARY_NOFAULT_LITTLE";
+ default:
+ return NULL;
+ }
+}
+
+/* PRINT_REGISTER_HOOK routine.
+ Pretty print various registers. */
+/* FIXME: Would be nice if this did some fancy things for 32 bit sparc. */
+
+void
+sparc_print_register_hook (int regno)
+{
+ ULONGEST val;
+
+ /* Handle double/quad versions of lower 32 fp regs. */
+ if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32
+ && (regno & 1) == 0)
+ {
+ char value[16];
+
+ if (frame_register_read (selected_frame, regno, value)
+ && frame_register_read (selected_frame, regno + 1, value + 4))
+ {
+ printf_unfiltered ("\t");
+ print_floating (value, builtin_type_double, gdb_stdout);
+ }
+#if 0 /* FIXME: gdb doesn't handle long doubles */
+ if ((regno & 3) == 0)
+ {
+ if (frame_register_read (selected_frame, regno + 2, value + 8)
+ && frame_register_read (selected_frame, regno + 3, value + 12))
+ {
+ printf_unfiltered ("\t");
+ print_floating (value, builtin_type_long_double, gdb_stdout);
+ }
+ }
+#endif
+ return;
+ }
+
+#if 0 /* FIXME: gdb doesn't handle long doubles */
+ /* Print upper fp regs as long double if appropriate. */
+ if (regno >= FP0_REGNUM + 32 && regno < FP_MAX_REGNUM
+ /* We test for even numbered regs and not a multiple of 4 because
+ the upper fp regs are recorded as doubles. */
+ && (regno & 1) == 0)
+ {
+ char value[16];
+
+ if (frame_register_read (selected_frame, regno, value)
+ && frame_register_read (selected_frame, regno + 1, value + 8))
+ {
+ printf_unfiltered ("\t");
+ print_floating (value, builtin_type_long_double, gdb_stdout);
+ }
+ return;
+ }
+#endif
+
+ /* FIXME: Some of these are priviledged registers.
+ Not sure how they should be handled. */
+
+#define BITS(n, mask) ((int) (((val) >> (n)) & (mask)))
+
+ val = read_register (regno);
+
+ /* pages 40 - 60 */
+ if (GDB_TARGET_IS_SPARC64)
+ switch (regno)
+ {
+ case CCR_REGNUM:
+ printf_unfiltered ("\t");
+ dump_ccreg ("xcc", val >> 4);
+ printf_unfiltered (", ");
+ dump_ccreg ("icc", val & 15);
+ break;
+ case FPRS_REGNUM:
+ printf ("\tfef:%d, du:%d, dl:%d",
+ BITS (2, 1), BITS (1, 1), BITS (0, 1));
+ break;
+ case FSR_REGNUM:
+ {
+ static char *fcc[4] =
+ {"=", "<", ">", "?"};
+ static char *rd[4] =
+ {"N", "0", "+", "-"};
+ /* Long, but I'd rather leave it as is and use a wide screen. */
+ printf_filtered ("\t0:%s, 1:%s, 2:%s, 3:%s, rd:%s, tem:%d, ",
+ fcc[BITS (10, 3)], fcc[BITS (32, 3)],
+ fcc[BITS (34, 3)], fcc[BITS (36, 3)],
+ rd[BITS (30, 3)], BITS (23, 31));
+ printf_filtered ("ns:%d, ver:%d, ftt:%d, qne:%d, aexc:%d, cexc:%d",
+ BITS (22, 1), BITS (17, 7), BITS (14, 7),
+ BITS (13, 1), BITS (5, 31), BITS (0, 31));
+ break;
+ }
+ case ASI_REGNUM:
+ {
+ char *asi = decode_asi (val);
+ if (asi != NULL)
+ printf ("\t%s", asi);
+ break;
+ }
+ case VER_REGNUM:
+ printf ("\tmanuf:%d, impl:%d, mask:%d, maxtl:%d, maxwin:%d",
+ BITS (48, 0xffff), BITS (32, 0xffff),
+ BITS (24, 0xff), BITS (8, 0xff), BITS (0, 31));
+ break;
+ case PSTATE_REGNUM:
+ {
+ static char *mm[4] =
+ {"tso", "pso", "rso", "?"};
+ printf_filtered ("\tcle:%d, tle:%d, mm:%s, red:%d, ",
+ BITS (9, 1), BITS (8, 1),
+ mm[BITS (6, 3)], BITS (5, 1));
+ printf_filtered ("pef:%d, am:%d, priv:%d, ie:%d, ag:%d",
+ BITS (4, 1), BITS (3, 1), BITS (2, 1),
+ BITS (1, 1), BITS (0, 1));
+ break;
+ }
+ case TSTATE_REGNUM:
+ /* FIXME: print all 4? */
+ break;
+ case TT_REGNUM:
+ /* FIXME: print all 4? */
+ break;
+ case TPC_REGNUM:
+ /* FIXME: print all 4? */
+ break;
+ case TNPC_REGNUM:
+ /* FIXME: print all 4? */
+ break;
+ case WSTATE_REGNUM:
+ printf ("\tother:%d, normal:%d", BITS (3, 7), BITS (0, 7));
+ break;
+ case CWP_REGNUM:
+ printf ("\t%d", BITS (0, 31));
+ break;
+ case CANSAVE_REGNUM:
+ printf ("\t%-2d before spill", BITS (0, 31));
+ break;
+ case CANRESTORE_REGNUM:
+ printf ("\t%-2d before fill", BITS (0, 31));
+ break;
+ case CLEANWIN_REGNUM:
+ printf ("\t%-2d before clean", BITS (0, 31));
+ break;
+ case OTHERWIN_REGNUM:
+ printf ("\t%d", BITS (0, 31));
+ break;
+ }
+ else /* Sparc32 */
+ switch (regno)
+ {
+ case PS_REGNUM:
+ printf ("\ticc:%c%c%c%c, pil:%d, s:%d, ps:%d, et:%d, cwp:%d",
+ BITS (23, 1) ? 'N' : '-', BITS (22, 1) ? 'Z' : '-',
+ BITS (21, 1) ? 'V' : '-', BITS (20, 1) ? 'C' : '-',
+ BITS (8, 15), BITS (7, 1), BITS (6, 1), BITS (5, 1),
+ BITS (0, 31));
+ break;
+ case FPS_REGNUM:
+ {
+ static char *fcc[4] =
+ {"=", "<", ">", "?"};
+ static char *rd[4] =
+ {"N", "0", "+", "-"};
+ /* Long, but I'd rather leave it as is and use a wide screen. */
+ printf ("\trd:%s, tem:%d, ns:%d, ver:%d, ftt:%d, qne:%d, "
+ "fcc:%s, aexc:%d, cexc:%d",
+ rd[BITS (30, 3)], BITS (23, 31), BITS (22, 1), BITS (17, 7),
+ BITS (14, 7), BITS (13, 1), fcc[BITS (10, 3)], BITS (5, 31),
+ BITS (0, 31));
+ break;
+ }
+ }
+
+#undef BITS
+}
+
+int
+gdb_print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
+{
+ /* It's necessary to override mach again because print_insn messes it up. */
+ info->mach = TARGET_ARCHITECTURE->mach;
+ return print_insn_sparc (memaddr, info);
+}
+
+/* The SPARC passes the arguments on the stack; arguments smaller
+ than an int are promoted to an int. The first 6 words worth of
+ args are also passed in registers o0 - o5. */
+
+CORE_ADDR
+sparc32_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int i, j, oregnum;
+ int accumulate_size = 0;
+ struct sparc_arg
+ {
+ char *contents;
+ int len;
+ int offset;
+ };
+ struct sparc_arg *sparc_args =
+ (struct sparc_arg *) alloca (nargs * sizeof (struct sparc_arg));
+ struct sparc_arg *m_arg;
+
+ /* Promote arguments if necessary, and calculate their stack offsets
+ and sizes. */
+ for (i = 0, m_arg = sparc_args; i < nargs; i++, m_arg++)
+ {
+ struct value *arg = args[i];
+ struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+ /* Cast argument to long if necessary as the compiler does it too. */
+ switch (TYPE_CODE (arg_type))
+ {
+ case TYPE_CODE_INT:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_ENUM:
+ if (TYPE_LENGTH (arg_type) < TYPE_LENGTH (builtin_type_long))
+ {
+ arg_type = builtin_type_long;
+ arg = value_cast (arg_type, arg);
+ }
+ break;
+ default:
+ break;
+ }
+ m_arg->len = TYPE_LENGTH (arg_type);
+ m_arg->offset = accumulate_size;
+ accumulate_size = (accumulate_size + m_arg->len + 3) & ~3;
+ m_arg->contents = VALUE_CONTENTS (arg);
+ }
+
+ /* Make room for the arguments on the stack. */
+ accumulate_size += CALL_DUMMY_STACK_ADJUST;
+ sp = ((sp - accumulate_size) & ~7) + CALL_DUMMY_STACK_ADJUST;
+
+ /* `Push' arguments on the stack. */
+ for (i = 0, oregnum = 0, m_arg = sparc_args;
+ i < nargs;
+ i++, m_arg++)
+ {
+ write_memory (sp + m_arg->offset, m_arg->contents, m_arg->len);
+ for (j = 0;
+ j < m_arg->len && oregnum < 6;
+ j += SPARC_INTREG_SIZE, oregnum++)
+ write_register_gen (O0_REGNUM + oregnum, m_arg->contents + j);
+ }
+
+ return sp;
+}
+
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. */
+
+void
+sparc32_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ int typelen = TYPE_LENGTH (type);
+ int regsize = REGISTER_RAW_SIZE (O0_REGNUM);
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT && SPARC_HAS_FPU)
+ memcpy (valbuf, &regbuf[REGISTER_BYTE (FP0_REGNUM)], typelen);
+ else
+ memcpy (valbuf,
+ &regbuf[O0_REGNUM * regsize +
+ (typelen >= regsize
+ || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE ? 0
+ : regsize - typelen)],
+ typelen);
+}
+
+
+/* Write into appropriate registers a function return value
+ of type TYPE, given in virtual format. On SPARCs with FPUs,
+ float values are returned in %f0 (and %f1). In all other cases,
+ values are returned in register %o0. */
+
+void
+sparc_store_return_value (struct type *type, char *valbuf)
+{
+ int regno;
+ char *buffer;
+
+ buffer = alloca (MAX_REGISTER_RAW_SIZE);
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT && SPARC_HAS_FPU)
+ /* Floating-point values are returned in the register pair */
+ /* formed by %f0 and %f1 (doubles are, anyway). */
+ regno = FP0_REGNUM;
+ else
+ /* Other values are returned in register %o0. */
+ regno = O0_REGNUM;
+
+ /* Add leading zeros to the value. */
+ if (TYPE_LENGTH (type) < REGISTER_RAW_SIZE (regno))
+ {
+ memset (buffer, 0, REGISTER_RAW_SIZE (regno));
+ memcpy (buffer + REGISTER_RAW_SIZE (regno) - TYPE_LENGTH (type), valbuf,
+ TYPE_LENGTH (type));
+ write_register_gen (regno, buffer);
+ }
+ else
+ write_register_bytes (REGISTER_BYTE (regno), valbuf, TYPE_LENGTH (type));
+}
+
+extern void
+sparclet_store_return_value (struct type *type, char *valbuf)
+{
+ /* Other values are returned in register %o0. */
+ write_register_bytes (REGISTER_BYTE (O0_REGNUM), valbuf,
+ TYPE_LENGTH (type));
+}
+
+
+#ifndef CALL_DUMMY_CALL_OFFSET
+#define CALL_DUMMY_CALL_OFFSET \
+ (gdbarch_tdep (current_gdbarch)->call_dummy_call_offset)
+#endif /* CALL_DUMMY_CALL_OFFSET */
+
+/* Insert the function address into a call dummy instruction sequence
+ stored at DUMMY.
+
+ For structs and unions, if the function was compiled with Sun cc,
+ it expects 'unimp' after the call. But gcc doesn't use that
+ (twisted) convention. So leave a nop there for gcc (FIX_CALL_DUMMY
+ can assume it is operating on a pristine CALL_DUMMY, not one that
+ has already been customized for a different function). */
+
+void
+sparc_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun,
+ struct type *value_type, int using_gcc)
+{
+ int i;
+
+ /* Store the relative adddress of the target function into the
+ 'call' instruction. */
+ store_unsigned_integer (dummy + CALL_DUMMY_CALL_OFFSET, 4,
+ (0x40000000
+ | (((fun - (pc + CALL_DUMMY_CALL_OFFSET)) >> 2)
+ & 0x3fffffff)));
+
+ /* If the called function returns an aggregate value, fill in the UNIMP
+ instruction containing the size of the returned aggregate return value,
+ which follows the call instruction.
+ For details see the SPARC Architecture Manual Version 8, Appendix D.3.
+
+ Adjust the call_dummy_breakpoint_offset for the bp_call_dummy breakpoint
+ to the proper address in the call dummy, so that `finish' after a stop
+ in a call dummy works.
+ Tweeking current_gdbarch is not an optimal solution, but the call to
+ sparc_fix_call_dummy is immediately followed by a call to run_stack_dummy,
+ which is the only function where dummy_breakpoint_offset is actually
+ used, if it is non-zero. */
+ if (TYPE_CODE (value_type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (value_type) == TYPE_CODE_UNION)
+ {
+ store_unsigned_integer (dummy + CALL_DUMMY_CALL_OFFSET + 8, 4,
+ TYPE_LENGTH (value_type) & 0x1fff);
+ set_gdbarch_call_dummy_breakpoint_offset (current_gdbarch, 0x30);
+ }
+ else
+ set_gdbarch_call_dummy_breakpoint_offset (current_gdbarch, 0x2c);
+
+ if (!(GDB_TARGET_IS_SPARC64))
+ {
+ /* If this is not a simulator target, change the first four
+ instructions of the call dummy to NOPs. Those instructions
+ include a 'save' instruction and are designed to work around
+ problems with register window flushing in the simulator. */
+
+ if (strcmp (target_shortname, "sim") != 0)
+ {
+ for (i = 0; i < 4; i++)
+ store_unsigned_integer (dummy + (i * 4), 4, 0x01000000);
+ }
+ }
+
+ /* If this is a bi-endian target, GDB has written the call dummy
+ in little-endian order. We must byte-swap it back to big-endian. */
+ if (bi_endian)
+ {
+ for (i = 0; i < CALL_DUMMY_LENGTH; i += 4)
+ {
+ char tmp = dummy[i];
+ dummy[i] = dummy[i + 3];
+ dummy[i + 3] = tmp;
+ tmp = dummy[i + 1];
+ dummy[i + 1] = dummy[i + 2];
+ dummy[i + 2] = tmp;
+ }
+ }
+}
+
+
+/* Set target byte order based on machine type. */
+
+static int
+sparc_target_architecture_hook (const bfd_arch_info_type *ap)
+{
+ int i, j;
+
+ if (ap->mach == bfd_mach_sparc_sparclite_le)
+ {
+ target_byte_order = BFD_ENDIAN_LITTLE;
+ bi_endian = 1;
+ }
+ else
+ bi_endian = 0;
+ return 1;
+}
+
+
+/*
+ * Module "constructor" function.
+ */
+
+static struct gdbarch * sparc_gdbarch_init (struct gdbarch_info info,
+ struct gdbarch_list *arches);
+
+void
+_initialize_sparc_tdep (void)
+{
+ /* Hook us into the gdbarch mechanism. */
+ register_gdbarch_init (bfd_arch_sparc, sparc_gdbarch_init);
+
+ tm_print_insn = gdb_print_insn_sparc;
+ tm_print_insn_info.mach = TM_PRINT_INSN_MACH; /* Selects sparc/sparclite */
+ target_architecture_hook = sparc_target_architecture_hook;
+}
+
+/* Compensate for stack bias. Note that we currently don't handle
+ mixed 32/64 bit code. */
+
+CORE_ADDR
+sparc64_read_sp (void)
+{
+ CORE_ADDR sp = read_register (SP_REGNUM);
+
+ if (sp & 1)
+ sp += 2047;
+ return sp;
+}
+
+CORE_ADDR
+sparc64_read_fp (void)
+{
+ CORE_ADDR fp = read_register (FP_REGNUM);
+
+ if (fp & 1)
+ fp += 2047;
+ return fp;
+}
+
+void
+sparc64_write_sp (CORE_ADDR val)
+{
+ CORE_ADDR oldsp = read_register (SP_REGNUM);
+ if (oldsp & 1)
+ write_register (SP_REGNUM, val - 2047);
+ else
+ write_register (SP_REGNUM, val);
+}
+
+/* The SPARC 64 ABI passes floating-point arguments in FP0 to FP31,
+ and all other arguments in O0 to O5. They are also copied onto
+ the stack in the correct places. Apparently (empirically),
+ structs of less than 16 bytes are passed member-by-member in
+ separate registers, but I am unable to figure out the algorithm.
+ Some members go in floating point regs, but I don't know which.
+
+ FIXME: Handle small structs (less than 16 bytes containing floats).
+
+ The counting regimen for using both integer and FP registers
+ for argument passing is rather odd -- a single counter is used
+ for both; this means that if the arguments alternate between
+ int and float, we will waste every other register of both types. */
+
+CORE_ADDR
+sparc64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_retaddr)
+{
+ int i, j, register_counter = 0;
+ CORE_ADDR tempsp;
+ struct type *sparc_intreg_type =
+ TYPE_LENGTH (builtin_type_long) == SPARC_INTREG_SIZE ?
+ builtin_type_long : builtin_type_long_long;
+
+ sp = (sp & ~(((unsigned long) SPARC_INTREG_SIZE) - 1UL));
+
+ /* Figure out how much space we'll need. */
+ for (i = nargs - 1; i >= 0; i--)
+ {
+ int len = TYPE_LENGTH (check_typedef (VALUE_TYPE (args[i])));
+ struct value *copyarg = args[i];
+ int copylen = len;
+
+ if (copylen < SPARC_INTREG_SIZE)
+ {
+ copyarg = value_cast (sparc_intreg_type, copyarg);
+ copylen = SPARC_INTREG_SIZE;
+ }
+ sp -= copylen;
+ }
+
+ /* Round down. */
+ sp = sp & ~7;
+ tempsp = sp;
+
+ /* if STRUCT_RETURN, then first argument is the struct return location. */
+ if (struct_return)
+ write_register (O0_REGNUM + register_counter++, struct_retaddr);
+
+ /* Now write the arguments onto the stack, while writing FP
+ arguments into the FP registers, and other arguments into the
+ first six 'O' registers. */
+
+ for (i = 0; i < nargs; i++)
+ {
+ int len = TYPE_LENGTH (check_typedef (VALUE_TYPE (args[i])));
+ struct value *copyarg = args[i];
+ enum type_code typecode = TYPE_CODE (VALUE_TYPE (args[i]));
+ int copylen = len;
+
+ if (typecode == TYPE_CODE_INT ||
+ typecode == TYPE_CODE_BOOL ||
+ typecode == TYPE_CODE_CHAR ||
+ typecode == TYPE_CODE_RANGE ||
+ typecode == TYPE_CODE_ENUM)
+ if (len < SPARC_INTREG_SIZE)
+ {
+ /* Small ints will all take up the size of one intreg on
+ the stack. */
+ copyarg = value_cast (sparc_intreg_type, copyarg);
+ copylen = SPARC_INTREG_SIZE;
+ }
+
+ write_memory (tempsp, VALUE_CONTENTS (copyarg), copylen);
+ tempsp += copylen;
+
+ /* Corner case: Structs consisting of a single float member are floats.
+ * FIXME! I don't know about structs containing multiple floats!
+ * Structs containing mixed floats and ints are even more weird.
+ */
+
+
+
+ /* Separate float args from all other args. */
+ if (typecode == TYPE_CODE_FLT && SPARC_HAS_FPU)
+ {
+ if (register_counter < 16)
+ {
+ /* This arg gets copied into a FP register. */
+ int fpreg;
+
+ switch (len) {
+ case 4: /* Single-precision (float) */
+ fpreg = FP0_REGNUM + 2 * register_counter + 1;
+ register_counter += 1;
+ break;
+ case 8: /* Double-precision (double) */
+ fpreg = FP0_REGNUM + 2 * register_counter;
+ register_counter += 1;
+ break;
+ case 16: /* Quad-precision (long double) */
+ fpreg = FP0_REGNUM + 2 * register_counter;
+ register_counter += 2;
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "bad switch");
+ }
+ write_register_bytes (REGISTER_BYTE (fpreg),
+ VALUE_CONTENTS (args[i]),
+ len);
+ }
+ }
+ else /* all other args go into the first six 'o' registers */
+ {
+ for (j = 0;
+ j < len && register_counter < 6;
+ j += SPARC_INTREG_SIZE)
+ {
+ int oreg = O0_REGNUM + register_counter;
+
+ write_register_gen (oreg, VALUE_CONTENTS (copyarg) + j);
+ register_counter += 1;
+ }
+ }
+ }
+ return sp;
+}
+
+/* Values <= 32 bytes are returned in o0-o3 (floating-point values are
+ returned in f0-f3). */
+
+void
+sp64_extract_return_value (struct type *type, char *regbuf, char *valbuf,
+ int bitoffset)
+{
+ int typelen = TYPE_LENGTH (type);
+ int regsize = REGISTER_RAW_SIZE (O0_REGNUM);
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT && SPARC_HAS_FPU)
+ {
+ memcpy (valbuf, &regbuf[REGISTER_BYTE (FP0_REGNUM)], typelen);
+ return;
+ }
+
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+ || (TYPE_LENGTH (type) > 32))
+ {
+ memcpy (valbuf,
+ &regbuf[O0_REGNUM * regsize +
+ (typelen >= regsize ? 0 : regsize - typelen)],
+ typelen);
+ return;
+ }
+ else
+ {
+ char *o0 = &regbuf[O0_REGNUM * regsize];
+ char *f0 = &regbuf[FP0_REGNUM * regsize];
+ int x;
+
+ for (x = 0; x < TYPE_NFIELDS (type); x++)
+ {
+ struct field *f = &TYPE_FIELDS (type)[x];
+ /* FIXME: We may need to handle static fields here. */
+ int whichreg = (f->loc.bitpos + bitoffset) / 32;
+ int remainder = ((f->loc.bitpos + bitoffset) % 32) / 8;
+ int where = (f->loc.bitpos + bitoffset) / 8;
+ int size = TYPE_LENGTH (f->type);
+ int typecode = TYPE_CODE (f->type);
+
+ if (typecode == TYPE_CODE_STRUCT)
+ {
+ sp64_extract_return_value (f->type,
+ regbuf,
+ valbuf,
+ bitoffset + f->loc.bitpos);
+ }
+ else if (typecode == TYPE_CODE_FLT && SPARC_HAS_FPU)
+ {
+ memcpy (valbuf + where, &f0[whichreg * 4] + remainder, size);
+ }
+ else
+ {
+ memcpy (valbuf + where, &o0[whichreg * 4] + remainder, size);
+ }
+ }
+ }
+}
+
+extern void
+sparc64_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ sp64_extract_return_value (type, regbuf, valbuf, 0);
+}
+
+extern void
+sparclet_extract_return_value (struct type *type,
+ char *regbuf,
+ char *valbuf)
+{
+ regbuf += REGISTER_RAW_SIZE (O0_REGNUM) * 8;
+ if (TYPE_LENGTH (type) < REGISTER_RAW_SIZE (O0_REGNUM))
+ regbuf += REGISTER_RAW_SIZE (O0_REGNUM) - TYPE_LENGTH (type);
+
+ memcpy ((void *) valbuf, regbuf, TYPE_LENGTH (type));
+}
+
+
+extern CORE_ADDR
+sparc32_stack_align (CORE_ADDR addr)
+{
+ return ((addr + 7) & -8);
+}
+
+extern CORE_ADDR
+sparc64_stack_align (CORE_ADDR addr)
+{
+ return ((addr + 15) & -16);
+}
+
+extern void
+sparc_print_extra_frame_info (struct frame_info *fi)
+{
+ if (fi && fi->extra_info && fi->extra_info->flat)
+ printf_filtered (" flat, pc saved at 0x%s, fp saved at 0x%s\n",
+ paddr_nz (fi->extra_info->pc_addr),
+ paddr_nz (fi->extra_info->fp_addr));
+}
+
+/* MULTI_ARCH support */
+
+static char *
+sparc32_register_name (int regno)
+{
+ static char *register_names[] =
+ { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+ "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
+
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+
+ "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
+ };
+
+ if (regno < 0 ||
+ regno >= (sizeof (register_names) / sizeof (register_names[0])))
+ return NULL;
+ else
+ return register_names[regno];
+}
+
+static char *
+sparc64_register_name (int regno)
+{
+ static char *register_names[] =
+ { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+ "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
+
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+ "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46",
+ "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62",
+
+ "pc", "npc", "ccr", "fsr", "fprs", "y", "asi", "ver",
+ "tick", "pil", "pstate", "tstate", "tba", "tl", "tt", "tpc",
+ "tnpc", "wstate", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
+ "asr16", "asr17", "asr18", "asr19", "asr20", "asr21", "asr22", "asr23",
+ "asr24", "asr25", "asr26", "asr27", "asr28", "asr29", "asr30", "asr31",
+ /* These are here at the end to simplify removing them if we have to. */
+ "icc", "xcc", "fcc0", "fcc1", "fcc2", "fcc3"
+ };
+
+ if (regno < 0 ||
+ regno >= (sizeof (register_names) / sizeof (register_names[0])))
+ return NULL;
+ else
+ return register_names[regno];
+}
+
+static char *
+sparclite_register_name (int regno)
+{
+ static char *register_names[] =
+ { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+ "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
+
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+
+ "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr",
+ "dia1", "dia2", "dda1", "dda2", "ddv1", "ddv2", "dcr", "dsr"
+ };
+
+ if (regno < 0 ||
+ regno >= (sizeof (register_names) / sizeof (register_names[0])))
+ return NULL;
+ else
+ return register_names[regno];
+}
+
+static char *
+sparclet_register_name (int regno)
+{
+ static char *register_names[] =
+ { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+ "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
+
+ "", "", "", "", "", "", "", "", /* no floating point registers */
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+
+ "y", "psr", "wim", "tbr", "pc", "npc", "", "", /* no FPSR or CPSR */
+ "ccsr", "ccpr", "cccrcr", "ccor", "ccobr", "ccibr", "ccir", "",
+
+ /* ASR15 ASR19 (don't display them) */
+ "asr1", "", "asr17", "asr18", "", "asr20", "asr21", "asr22"
+ /* None of the rest get displayed */
+#if 0
+ "awr0", "awr1", "awr2", "awr3", "awr4", "awr5", "awr6", "awr7",
+ "awr8", "awr9", "awr10", "awr11", "awr12", "awr13", "awr14", "awr15",
+ "awr16", "awr17", "awr18", "awr19", "awr20", "awr21", "awr22", "awr23",
+ "awr24", "awr25", "awr26", "awr27", "awr28", "awr29", "awr30", "awr31",
+ "apsr"
+#endif /* 0 */
+ };
+
+ if (regno < 0 ||
+ regno >= (sizeof (register_names) / sizeof (register_names[0])))
+ return NULL;
+ else
+ return register_names[regno];
+}
+
+CORE_ADDR
+sparc_push_return_address (CORE_ADDR pc_unused, CORE_ADDR sp)
+{
+ if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
+ {
+ /* The return PC of the dummy_frame is the former 'current' PC
+ (where we were before we made the target function call).
+ This is saved in %i7 by push_dummy_frame.
+
+ We will save the 'call dummy location' (ie. the address
+ to which the target function will return) in %o7.
+ This address will actually be the program's entry point.
+ There will be a special call_dummy breakpoint there. */
+
+ write_register (O7_REGNUM,
+ CALL_DUMMY_ADDRESS () - 8);
+ }
+
+ return sp;
+}
+
+/* Should call_function allocate stack space for a struct return? */
+
+static int
+sparc64_use_struct_convention (int gcc_p, struct type *type)
+{
+ return (TYPE_LENGTH (type) > 32);
+}
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function_by_hand.
+ The ultimate mystery is, tho, what is the value "16"?
+
+ MVS: That's the offset from where the sp is now, to where the
+ subroutine is gonna expect to find the struct return address. */
+
+static void
+sparc32_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ char *val;
+ CORE_ADDR o7;
+
+ val = alloca (SPARC_INTREG_SIZE);
+ store_unsigned_integer (val, SPARC_INTREG_SIZE, addr);
+ write_memory (sp + (16 * SPARC_INTREG_SIZE), val, SPARC_INTREG_SIZE);
+
+ if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
+ {
+ /* Now adjust the value of the link register, which was previously
+ stored by push_return_address. Functions that return structs are
+ peculiar in that they return to link register + 12, rather than
+ link register + 8. */
+
+ o7 = read_register (O7_REGNUM);
+ write_register (O7_REGNUM, o7 - 4);
+ }
+}
+
+static void
+sparc64_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ /* FIXME: V9 uses %o0 for this. */
+ /* FIXME MVS: Only for small enough structs!!! */
+
+ target_write_memory (sp + (16 * SPARC_INTREG_SIZE),
+ (char *) &addr, SPARC_INTREG_SIZE);
+#if 0
+ if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
+ {
+ /* Now adjust the value of the link register, which was previously
+ stored by push_return_address. Functions that return structs are
+ peculiar in that they return to link register + 12, rather than
+ link register + 8. */
+
+ write_register (O7_REGNUM, read_register (O7_REGNUM) - 4);
+ }
+#endif
+}
+
+/* Default target data type for register REGNO. */
+
+static struct type *
+sparc32_register_virtual_type (int regno)
+{
+ if (regno == PC_REGNUM ||
+ regno == FP_REGNUM ||
+ regno == SP_REGNUM)
+ return builtin_type_unsigned_int;
+ if (regno < 32)
+ return builtin_type_int;
+ if (regno < 64)
+ return builtin_type_float;
+ return builtin_type_int;
+}
+
+static struct type *
+sparc64_register_virtual_type (int regno)
+{
+ if (regno == PC_REGNUM ||
+ regno == FP_REGNUM ||
+ regno == SP_REGNUM)
+ return builtin_type_unsigned_long_long;
+ if (regno < 32)
+ return builtin_type_long_long;
+ if (regno < 64)
+ return builtin_type_float;
+ if (regno < 80)
+ return builtin_type_double;
+ return builtin_type_long_long;
+}
+
+/* Number of bytes of storage in the actual machine representation for
+ register REGNO. */
+
+static int
+sparc32_register_size (int regno)
+{
+ return 4;
+}
+
+static int
+sparc64_register_size (int regno)
+{
+ return (regno < 32 ? 8 : regno < 64 ? 4 : 8);
+}
+
+/* Index within the `registers' buffer of the first byte of the space
+ for register REGNO. */
+
+static int
+sparc32_register_byte (int regno)
+{
+ return (regno * 4);
+}
+
+static int
+sparc64_register_byte (int regno)
+{
+ if (regno < 32)
+ return regno * 8;
+ else if (regno < 64)
+ return 32 * 8 + (regno - 32) * 4;
+ else if (regno < 80)
+ return 32 * 8 + 32 * 4 + (regno - 64) * 8;
+ else
+ return 64 * 8 + (regno - 80) * 8;
+}
+
+/* Immediately after a function call, return the saved pc.
+ Can't go through the frames for this because on some machines
+ the new frame is not set up until the new function executes
+ some instructions. */
+
+static CORE_ADDR
+sparc_saved_pc_after_call (struct frame_info *fi)
+{
+ return sparc_pc_adjust (read_register (RP_REGNUM));
+}
+
+/* Convert registers between 'raw' and 'virtual' formats.
+ They are the same on sparc, so there's nothing to do. */
+
+static void
+sparc_convert_to_virtual (int regnum, struct type *type, char *from, char *to)
+{ /* do nothing (should never be called) */
+}
+
+static void
+sparc_convert_to_raw (struct type *type, int regnum, char *from, char *to)
+{ /* do nothing (should never be called) */
+}
+
+/* Init saved regs: nothing to do, just a place-holder function. */
+
+static void
+sparc_frame_init_saved_regs (struct frame_info *fi_ignored)
+{ /* no-op */
+}
+
+/* gdbarch fix call dummy:
+ All this function does is rearrange the arguments before calling
+ sparc_fix_call_dummy (which does the real work). */
+
+static void
+sparc_gdbarch_fix_call_dummy (char *dummy,
+ CORE_ADDR pc,
+ CORE_ADDR fun,
+ int nargs,
+ struct value **args,
+ struct type *type,
+ int gcc_p)
+{
+ if (CALL_DUMMY_LOCATION == ON_STACK)
+ sparc_fix_call_dummy (dummy, pc, fun, type, gcc_p);
+}
+
+/* Coerce float to double: a no-op. */
+
+static int
+sparc_coerce_float_to_double (struct type *formal, struct type *actual)
+{
+ return 1;
+}
+
+/* CALL_DUMMY_ADDRESS: fetch the breakpoint address for a call dummy. */
+
+static CORE_ADDR
+sparc_call_dummy_address (void)
+{
+ return (CALL_DUMMY_START_OFFSET) + CALL_DUMMY_BREAKPOINT_OFFSET;
+}
+
+/* Supply the Y register number to those that need it. */
+
+int
+sparc_y_regnum (void)
+{
+ return gdbarch_tdep (current_gdbarch)->y_regnum;
+}
+
+int
+sparc_reg_struct_has_addr (int gcc_p, struct type *type)
+{
+ if (GDB_TARGET_IS_SPARC64)
+ return (TYPE_LENGTH (type) > 32);
+ else
+ return (gcc_p != 1);
+}
+
+int
+sparc_intreg_size (void)
+{
+ return SPARC_INTREG_SIZE;
+}
+
+static int
+sparc_return_value_on_stack (struct type *type)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_FLT &&
+ TYPE_LENGTH (type) > 8)
+ return 1;
+ else
+ return 0;
+}
+
+/*
+ * Gdbarch "constructor" function.
+ */
+
+#define SPARC32_CALL_DUMMY_ON_STACK
+
+#define SPARC_SP_REGNUM 14
+#define SPARC_FP_REGNUM 30
+#define SPARC_FP0_REGNUM 32
+#define SPARC32_NPC_REGNUM 69
+#define SPARC32_PC_REGNUM 68
+#define SPARC32_Y_REGNUM 64
+#define SPARC64_PC_REGNUM 80
+#define SPARC64_NPC_REGNUM 81
+#define SPARC64_Y_REGNUM 85
+
+static struct gdbarch *
+sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch *gdbarch;
+ struct gdbarch_tdep *tdep;
+
+ static LONGEST call_dummy_32[] =
+ { 0xbc100001, 0x9de38000, 0xbc100002, 0xbe100003,
+ 0xda03a058, 0xd803a054, 0xd603a050, 0xd403a04c,
+ 0xd203a048, 0x40000000, 0xd003a044, 0x01000000,
+ 0x91d02001, 0x01000000
+ };
+ static LONGEST call_dummy_64[] =
+ { 0x9de3bec0fd3fa7f7LL, 0xf93fa7eff53fa7e7LL,
+ 0xf13fa7dfed3fa7d7LL, 0xe93fa7cfe53fa7c7LL,
+ 0xe13fa7bfdd3fa7b7LL, 0xd93fa7afd53fa7a7LL,
+ 0xd13fa79fcd3fa797LL, 0xc93fa78fc53fa787LL,
+ 0xc13fa77fcc3fa777LL, 0xc83fa76fc43fa767LL,
+ 0xc03fa75ffc3fa757LL, 0xf83fa74ff43fa747LL,
+ 0xf03fa73f01000000LL, 0x0100000001000000LL,
+ 0x0100000091580000LL, 0xd027a72b93500000LL,
+ 0xd027a72791480000LL, 0xd027a72391400000LL,
+ 0xd027a71fda5ba8a7LL, 0xd85ba89fd65ba897LL,
+ 0xd45ba88fd25ba887LL, 0x9fc02000d05ba87fLL,
+ 0x0100000091d02001LL, 0x0100000001000000LL
+ };
+ static LONGEST call_dummy_nil[] = {0};
+
+ /* First see if there is already a gdbarch that can satisfy the request. */
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+ if (arches != NULL)
+ return arches->gdbarch;
+
+ /* None found: is the request for a sparc architecture? */
+ if (info.bfd_arch_info->arch != bfd_arch_sparc)
+ return NULL; /* No; then it's not for us. */
+
+ /* Yes: create a new gdbarch for the specified machine type. */
+ tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ /* First set settings that are common for all sparc architectures. */
+ set_gdbarch_believe_pcc_promotion (gdbarch, 1);
+ set_gdbarch_breakpoint_from_pc (gdbarch, memory_breakpoint_from_pc);
+ set_gdbarch_coerce_float_to_double (gdbarch,
+ sparc_coerce_float_to_double);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 1);
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+ set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+ set_gdbarch_extract_struct_value_address (gdbarch,
+ sparc_extract_struct_value_address);
+ set_gdbarch_fix_call_dummy (gdbarch, sparc_gdbarch_fix_call_dummy);
+ set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_fp_regnum (gdbarch, SPARC_FP_REGNUM);
+ set_gdbarch_fp0_regnum (gdbarch, SPARC_FP0_REGNUM);
+ set_gdbarch_frame_args_address (gdbarch, default_frame_address);
+ set_gdbarch_frame_chain (gdbarch, sparc_frame_chain);
+ set_gdbarch_frame_init_saved_regs (gdbarch, sparc_frame_init_saved_regs);
+ set_gdbarch_frame_locals_address (gdbarch, default_frame_address);
+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+ set_gdbarch_frame_saved_pc (gdbarch, sparc_frame_saved_pc);
+ set_gdbarch_frameless_function_invocation (gdbarch,
+ frameless_look_for_prologue);
+ set_gdbarch_get_saved_register (gdbarch, sparc_get_saved_register);
+ set_gdbarch_init_extra_frame_info (gdbarch, sparc_init_extra_frame_info);
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+ set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT);
+ set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+ set_gdbarch_max_register_raw_size (gdbarch, 8);
+ set_gdbarch_max_register_virtual_size (gdbarch, 8);
+ set_gdbarch_pop_frame (gdbarch, sparc_pop_frame);
+ set_gdbarch_push_return_address (gdbarch, sparc_push_return_address);
+ set_gdbarch_push_dummy_frame (gdbarch, sparc_push_dummy_frame);
+ set_gdbarch_read_pc (gdbarch, generic_target_read_pc);
+ set_gdbarch_register_convert_to_raw (gdbarch, sparc_convert_to_raw);
+ set_gdbarch_register_convert_to_virtual (gdbarch,
+ sparc_convert_to_virtual);
+ set_gdbarch_register_convertible (gdbarch,
+ generic_register_convertible_not);
+ set_gdbarch_reg_struct_has_addr (gdbarch, sparc_reg_struct_has_addr);
+ set_gdbarch_return_value_on_stack (gdbarch, sparc_return_value_on_stack);
+ set_gdbarch_saved_pc_after_call (gdbarch, sparc_saved_pc_after_call);
+ set_gdbarch_prologue_frameless_p (gdbarch, sparc_prologue_frameless_p);
+ set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_skip_prologue (gdbarch, sparc_skip_prologue);
+ set_gdbarch_sp_regnum (gdbarch, SPARC_SP_REGNUM);
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
+ set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
+
+ /*
+ * Settings that depend only on 32/64 bit word size
+ */
+
+ switch (info.bfd_arch_info->mach)
+ {
+ case bfd_mach_sparc:
+ case bfd_mach_sparc_sparclet:
+ case bfd_mach_sparc_sparclite:
+ case bfd_mach_sparc_v8plus:
+ case bfd_mach_sparc_v8plusa:
+ case bfd_mach_sparc_sparclite_le:
+ /* 32-bit machine types: */
+
+#ifdef SPARC32_CALL_DUMMY_ON_STACK
+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
+ set_gdbarch_call_dummy_address (gdbarch, sparc_call_dummy_address);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0x30);
+ set_gdbarch_call_dummy_length (gdbarch, 0x38);
+
+ /* NOTE: cagney/2002-04-26: Based from info posted by Peter
+ Schauer around Oct '99. Briefly, due to aspects of the SPARC
+ ABI, it isn't possible to use ON_STACK with a strictly
+ compliant compiler.
+
+ Peter Schauer writes ...
+
+ No, any call from GDB to a user function returning a
+ struct/union will fail miserably. Try this:
+
+ *NOINDENT*
+ struct x
+ {
+ int a[4];
+ };
+
+ struct x gx;
+
+ struct x
+ sret ()
+ {
+ return gx;
+ }
+
+ main ()
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ gx.a[i] = i + 1;
+ gx = sret ();
+ }
+ *INDENT*
+
+ Set a breakpoint at the gx = sret () statement, run to it and
+ issue a `print sret()'. It will not succed with your
+ approach, and I doubt that continuing the program will work
+ as well.
+
+ For details of the ABI see the Sparc Architecture Manual. I
+ have Version 8 (Prentice Hall ISBN 0-13-825001-4) and the
+ calling conventions for functions returning aggregate values
+ are explained in Appendix D.3. */
+
+ set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
+ set_gdbarch_call_dummy_words (gdbarch, call_dummy_32);
+#else
+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
+ set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_words (gdbarch, call_dummy_nil);
+#endif
+ set_gdbarch_call_dummy_stack_adjust (gdbarch, 68);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_frame_args_skip (gdbarch, 68);
+ set_gdbarch_function_start_offset (gdbarch, 0);
+ set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_npc_regnum (gdbarch, SPARC32_NPC_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, SPARC32_PC_REGNUM);
+ set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_push_arguments (gdbarch, sparc32_push_arguments);
+ set_gdbarch_read_fp (gdbarch, generic_target_read_fp);
+ set_gdbarch_read_sp (gdbarch, generic_target_read_sp);
+
+ set_gdbarch_register_byte (gdbarch, sparc32_register_byte);
+ set_gdbarch_register_raw_size (gdbarch, sparc32_register_size);
+ set_gdbarch_register_size (gdbarch, 4);
+ set_gdbarch_register_virtual_size (gdbarch, sparc32_register_size);
+ set_gdbarch_register_virtual_type (gdbarch,
+ sparc32_register_virtual_type);
+#ifdef SPARC32_CALL_DUMMY_ON_STACK
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (call_dummy_32));
+#else
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
+#endif
+ set_gdbarch_stack_align (gdbarch, sparc32_stack_align);
+ set_gdbarch_store_struct_return (gdbarch, sparc32_store_struct_return);
+ set_gdbarch_use_struct_convention (gdbarch,
+ generic_use_struct_convention);
+ set_gdbarch_write_sp (gdbarch, generic_target_write_sp);
+ tdep->y_regnum = SPARC32_Y_REGNUM;
+ tdep->fp_max_regnum = SPARC_FP0_REGNUM + 32;
+ tdep->intreg_size = 4;
+ tdep->reg_save_offset = 0x60;
+ tdep->call_dummy_call_offset = 0x24;
+ break;
+
+ case bfd_mach_sparc_v9:
+ case bfd_mach_sparc_v9a:
+ /* 64-bit machine types: */
+ default: /* Any new machine type is likely to be 64-bit. */
+
+#ifdef SPARC64_CALL_DUMMY_ON_STACK
+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
+ set_gdbarch_call_dummy_address (gdbarch, sparc_call_dummy_address);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 8 * 4);
+ set_gdbarch_call_dummy_length (gdbarch, 192);
+ set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 148);
+ set_gdbarch_call_dummy_words (gdbarch, call_dummy_64);
+#else
+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
+ set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_words (gdbarch, call_dummy_nil);
+#endif
+ set_gdbarch_call_dummy_stack_adjust (gdbarch, 128);
+ set_gdbarch_frame_args_skip (gdbarch, 136);
+ set_gdbarch_function_start_offset (gdbarch, 0);
+ set_gdbarch_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+ set_gdbarch_npc_regnum (gdbarch, SPARC64_NPC_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, SPARC64_PC_REGNUM);
+ set_gdbarch_ptr_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+ set_gdbarch_push_arguments (gdbarch, sparc64_push_arguments);
+ /* NOTE different for at_entry */
+ set_gdbarch_read_fp (gdbarch, sparc64_read_fp);
+ set_gdbarch_read_sp (gdbarch, sparc64_read_sp);
+ /* Some of the registers aren't 64 bits, but it's a lot simpler just
+ to assume they all are (since most of them are). */
+ set_gdbarch_register_byte (gdbarch, sparc64_register_byte);
+ set_gdbarch_register_raw_size (gdbarch, sparc64_register_size);
+ set_gdbarch_register_size (gdbarch, 8);
+ set_gdbarch_register_virtual_size (gdbarch, sparc64_register_size);
+ set_gdbarch_register_virtual_type (gdbarch,
+ sparc64_register_virtual_type);
+#ifdef SPARC64_CALL_DUMMY_ON_STACK
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (call_dummy_64));
+#else
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
+#endif
+ set_gdbarch_stack_align (gdbarch, sparc64_stack_align);
+ set_gdbarch_store_struct_return (gdbarch, sparc64_store_struct_return);
+ set_gdbarch_use_struct_convention (gdbarch,
+ sparc64_use_struct_convention);
+ set_gdbarch_write_sp (gdbarch, sparc64_write_sp);
+ tdep->y_regnum = SPARC64_Y_REGNUM;
+ tdep->fp_max_regnum = SPARC_FP0_REGNUM + 48;
+ tdep->intreg_size = 8;
+ tdep->reg_save_offset = 0x90;
+ tdep->call_dummy_call_offset = 148 + 4 * 5;
+ break;
+ }
+
+ /*
+ * Settings that vary per-architecture:
+ */
+
+ switch (info.bfd_arch_info->mach)
+ {
+ case bfd_mach_sparc:
+ set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
+ set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
+ set_gdbarch_num_regs (gdbarch, 72);
+ set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4);
+ set_gdbarch_register_name (gdbarch, sparc32_register_name);
+ set_gdbarch_store_return_value (gdbarch, sparc_store_return_value);
+ tdep->has_fpu = 1; /* (all but sparclet and sparclite) */
+ tdep->fp_register_bytes = 32 * 4;
+ tdep->print_insn_mach = bfd_mach_sparc;
+ break;
+ case bfd_mach_sparc_sparclet:
+ set_gdbarch_extract_return_value (gdbarch,
+ sparclet_extract_return_value);
+ set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
+ set_gdbarch_num_regs (gdbarch, 32 + 32 + 8 + 8 + 8);
+ set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4 + 8*4);
+ set_gdbarch_register_name (gdbarch, sparclet_register_name);
+ set_gdbarch_store_return_value (gdbarch, sparclet_store_return_value);
+ tdep->has_fpu = 0; /* (all but sparclet and sparclite) */
+ tdep->fp_register_bytes = 0;
+ tdep->print_insn_mach = bfd_mach_sparc_sparclet;
+ break;
+ case bfd_mach_sparc_sparclite:
+ set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
+ set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
+ set_gdbarch_num_regs (gdbarch, 80);
+ set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4);
+ set_gdbarch_register_name (gdbarch, sparclite_register_name);
+ set_gdbarch_store_return_value (gdbarch, sparc_store_return_value);
+ tdep->has_fpu = 0; /* (all but sparclet and sparclite) */
+ tdep->fp_register_bytes = 0;
+ tdep->print_insn_mach = bfd_mach_sparc_sparclite;
+ break;
+ case bfd_mach_sparc_v8plus:
+ set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
+ set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
+ set_gdbarch_num_regs (gdbarch, 72);
+ set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4);
+ set_gdbarch_register_name (gdbarch, sparc32_register_name);
+ set_gdbarch_store_return_value (gdbarch, sparc_store_return_value);
+ tdep->print_insn_mach = bfd_mach_sparc;
+ tdep->fp_register_bytes = 32 * 4;
+ tdep->has_fpu = 1; /* (all but sparclet and sparclite) */
+ break;
+ case bfd_mach_sparc_v8plusa:
+ set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
+ set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
+ set_gdbarch_num_regs (gdbarch, 72);
+ set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4);
+ set_gdbarch_register_name (gdbarch, sparc32_register_name);
+ set_gdbarch_store_return_value (gdbarch, sparc_store_return_value);
+ tdep->has_fpu = 1; /* (all but sparclet and sparclite) */
+ tdep->fp_register_bytes = 32 * 4;
+ tdep->print_insn_mach = bfd_mach_sparc;
+ break;
+ case bfd_mach_sparc_sparclite_le:
+ set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
+ set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
+ set_gdbarch_num_regs (gdbarch, 80);
+ set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4);
+ set_gdbarch_register_name (gdbarch, sparclite_register_name);
+ set_gdbarch_store_return_value (gdbarch, sparc_store_return_value);
+ tdep->has_fpu = 0; /* (all but sparclet and sparclite) */
+ tdep->fp_register_bytes = 0;
+ tdep->print_insn_mach = bfd_mach_sparc_sparclite;
+ break;
+ case bfd_mach_sparc_v9:
+ set_gdbarch_extract_return_value (gdbarch, sparc64_extract_return_value);
+ set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
+ set_gdbarch_num_regs (gdbarch, 125);
+ set_gdbarch_register_bytes (gdbarch, 32*8 + 32*8 + 45*8);
+ set_gdbarch_register_name (gdbarch, sparc64_register_name);
+ set_gdbarch_store_return_value (gdbarch, sparc_store_return_value);
+ tdep->has_fpu = 1; /* (all but sparclet and sparclite) */
+ tdep->fp_register_bytes = 64 * 4;
+ tdep->print_insn_mach = bfd_mach_sparc_v9a;
+ break;
+ case bfd_mach_sparc_v9a:
+ set_gdbarch_extract_return_value (gdbarch, sparc64_extract_return_value);
+ set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
+ set_gdbarch_num_regs (gdbarch, 125);
+ set_gdbarch_register_bytes (gdbarch, 32*8 + 32*8 + 45*8);
+ set_gdbarch_register_name (gdbarch, sparc64_register_name);
+ set_gdbarch_store_return_value (gdbarch, sparc_store_return_value);
+ tdep->has_fpu = 1; /* (all but sparclet and sparclite) */
+ tdep->fp_register_bytes = 64 * 4;
+ tdep->print_insn_mach = bfd_mach_sparc_v9a;
+ break;
+ }
+
+ return gdbarch;
+}
+
diff --git a/gdb/sparc64nbsd-nat.c b/gdb/sparc64nbsd-nat.c
new file mode 100644
index 00000000000..a991d0ef2a4
--- /dev/null
+++ b/gdb/sparc64nbsd-nat.c
@@ -0,0 +1,207 @@
+/* Native-dependent code for UltraSPARC systems running NetBSD.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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 "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include "sparcnbsd-tdep.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+/* NOTE: We don't bother with any of the deferred_store nonsense; it
+ makes things a lot more complicated than they need to be. */
+
+/* Determine if PT_GETREGS fetches this register. */
+static int
+getregs_supplies (int regno)
+{
+ /* FIXME: PS_REGNUM for 32-bit code. */
+ return (regno == TSTATE_REGNUM
+ || regno == PC_REGNUM
+ || regno == NPC_REGNUM
+ || regno == Y_REGNUM
+ || (regno >= G0_REGNUM && regno <= G7_REGNUM)
+ || (regno >= O0_REGNUM && regno <= O7_REGNUM)
+ /* stack regs (handled by sparcnbsd_supply_reg) */
+ || (regno >= L0_REGNUM && regno <= I7_REGNUM));
+}
+
+/* Determine if PT_GETFPREGS fetches this register. */
+static int
+getfpregs_supplies (int regno)
+{
+ return ((regno >= FP0_REGNUM && regno <= (FP0_REGNUM + 47))
+ || regno == FPS_REGNUM);
+}
+
+void
+fetch_inferior_registers (int regno)
+{
+ /* We don't use deferred stores. */
+ if (deferred_stores)
+ internal_error (__FILE__, __LINE__,
+ "fetch_inferior_registers: deferred stores pending");
+
+ if (regno == -1 || getregs_supplies (regno))
+ {
+ union {
+ struct reg32 regs32;
+ struct reg64 regs64;
+ } regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ if (gdbarch_ptr_bit (current_gdbarch) == 32)
+ sparcnbsd_supply_reg32 ((char *) &regs.regs32, regno);
+ else
+ sparcnbsd_supply_reg64 ((char *) &regs.regs64, regno);
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1 || getfpregs_supplies (regno))
+ {
+ union {
+ struct fpreg32 fpregs32;
+ struct fpreg64 fpregs64;
+ } fpregs;
+
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point registers");
+
+ if (gdbarch_ptr_bit (current_gdbarch) == 32)
+ sparcnbsd_supply_fpreg32 ((char *) &fpregs.fpregs32, regno);
+ else
+ sparcnbsd_supply_fpreg64 ((char *) &fpregs.fpregs64, regno);
+ if (regno != -1)
+ return;
+ }
+}
+
+void
+store_inferior_registers (int regno)
+{
+ /* We don't use deferred stores. */
+ if (deferred_stores)
+ internal_error (__FILE__, __LINE__,
+ "store_inferior_registers: deferred stores pending");
+
+ if (regno == -1 || getregs_supplies (regno))
+ {
+ union {
+ struct reg32 regs32;
+ struct reg64 regs64;
+ } regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ if (gdbarch_ptr_bit (current_gdbarch) == 32)
+ sparcnbsd_fill_reg32 ((char *) &regs.regs32, regno);
+ else
+ sparcnbsd_fill_reg64 ((char *) &regs.regs64, regno);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't write registers");
+
+ /* Deal with the stack regs. */
+ if (regno == -1 || regno == SP_REGNUM
+ || (regno >= L0_REGNUM && regno <= I7_REGNUM))
+ {
+ CORE_ADDR sp = read_register (SP_REGNUM);
+ int i;
+ char buf[8];
+
+ if (sp & 1)
+ {
+ /* Registers are 64-bit. */
+ sp += 2047;
+
+ for (i = L0_REGNUM; i <= I7_REGNUM; i++)
+ {
+ if (regno == -1 || regno == SP_REGNUM || regno == i)
+ {
+ regcache_collect (i, buf);
+ target_write_memory (sp + ((i - L0_REGNUM) * 8),
+ buf, sizeof (buf));
+ }
+ }
+ }
+ else
+ {
+ /* Registers are 32-bit. Toss any sign-extension of the stack
+ pointer.
+
+ FIXME: We don't currently handle 32-bit code in a binary
+ that indicated LP64. Do we have to care about that? */
+ if (gdbarch_ptr_bit (current_gdbarch) != 32)
+ internal_error
+ (__FILE__, __LINE__,
+ "store_inferior_registers: 32-bit code in 64-bit inferior");
+
+ sp &= 0xffffffffUL;
+ for (i = L0_REGNUM; i <= I7_REGNUM; i++)
+ {
+ if (regno == -1 || regno == SP_REGNUM || regno == i)
+ {
+ regcache_collect (i, buf);
+ target_write_memory (sp + ((i - L0_REGNUM) * 4), buf, 4);
+ }
+ }
+ }
+ }
+
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1 || getfpregs_supplies (regno))
+ {
+ union {
+ struct fpreg32 fpregs32;
+ struct fpreg64 fpregs64;
+ } fpregs;
+
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point registers");
+
+ if (gdbarch_ptr_bit (current_gdbarch) == 32)
+ sparcnbsd_fill_fpreg32 ((char *) &fpregs.fpregs32, regno);
+ else
+ sparcnbsd_fill_fpreg64 ((char *) &fpregs.fpregs64, regno);
+
+ if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't write floating point registers");
+
+ if (regno != -1)
+ return;
+ }
+}
diff --git a/gdb/sparcl-stub.c b/gdb/sparcl-stub.c
new file mode 100644
index 00000000000..3fcdc0ad7c1
--- /dev/null
+++ b/gdb/sparcl-stub.c
@@ -0,0 +1,946 @@
+/****************************************************************************
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ HP offers the following for use in the public domain. HP makes no
+ warranty with regard to the software or it's performance and the
+ user accepts the software "AS IS" with all faults.
+
+ HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+ TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ * Module name: remcom.c $
+ * Revision: 1.34 $
+ * Date: 91/03/09 12:29:49 $
+ * Contributor: Lake Stevens Instrument Division$
+ *
+ * Description: low level support for gdb debugger. $
+ *
+ * Considerations: only works on target hardware $
+ *
+ * Written by: Glenn Engel $
+ * ModuleState: Experimental $
+ *
+ * NOTES: See Below $
+ *
+ * Modified for SPARC by Stu Grossman, Cygnus Support.
+ * Based on sparc-stub.c, it's modified for SPARClite Debug Unit hardware
+ * breakpoint support to create sparclite-stub.c, by Kung Hsu, Cygnus Support.
+ *
+ * This code has been extensively tested on the Fujitsu SPARClite demo board.
+ *
+ * To enable debugger support, two things need to happen. One, a
+ * call to set_debug_traps() is necessary in order to allow any breakpoints
+ * or error conditions to be properly intercepted and reported to gdb.
+ * Two, a breakpoint needs to be generated to begin communication. This
+ * is most easily accomplished by a call to breakpoint(). Breakpoint()
+ * simulates a breakpoint by executing a trap #1.
+ *
+ *************
+ *
+ * The following gdb commands are supported:
+ *
+ * command function Return value
+ *
+ * g return the value of the CPU registers hex data or ENN
+ * G set the value of the CPU registers OK or ENN
+ * P set the value of a single CPU register OK or ENN
+ *
+ * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
+ * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
+ *
+ * c Resume at current address SNN ( signal NN)
+ * cAA..AA Continue at address AA..AA SNN
+ *
+ * s Step one instruction SNN
+ * sAA..AA Step one instruction from AA..AA SNN
+ *
+ * k kill
+ *
+ * ? What was the last sigval ? SNN (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum. A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer. '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host: Reply:
+ * $m0,10#2a +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <signal.h>
+#include <sparclite.h>
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+
+extern void putDebugChar (int c); /* write a single character */
+extern int getDebugChar (void); /* read and return a single char */
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 2048
+
+static int initialized = 0; /* !0 means we've been initialized */
+
+extern void breakinst ();
+static void set_mem_fault_trap (int enable);
+static void get_in_break_mode (void);
+
+static const char hexchars[]="0123456789abcdef";
+
+#define NUMREGS 80
+
+/* Number of bytes of registers. */
+#define NUMREGBYTES (NUMREGS * 4)
+enum regnames {G0, G1, G2, G3, G4, G5, G6, G7,
+ O0, O1, O2, O3, O4, O5, SP, O7,
+ L0, L1, L2, L3, L4, L5, L6, L7,
+ I0, I1, I2, I3, I4, I5, FP, I7,
+
+ F0, F1, F2, F3, F4, F5, F6, F7,
+ F8, F9, F10, F11, F12, F13, F14, F15,
+ F16, F17, F18, F19, F20, F21, F22, F23,
+ F24, F25, F26, F27, F28, F29, F30, F31,
+ Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR,
+ DIA1, DIA2, DDA1, DDA2, DDV1, DDV2, DCR, DSR };
+
+/*************************** ASSEMBLY CODE MACROS *************************/
+/* */
+
+extern void trap_low();
+
+/* Create private copies of common functions used by the stub. This prevents
+ nasty interactions between app code and the stub (for instance if user steps
+ into strlen, etc..) */
+
+static char *
+strcpy (char *dst, const char *src)
+{
+ char *retval = dst;
+
+ while ((*dst++ = *src++) != '\000');
+
+ return retval;
+}
+
+static void *
+memcpy (void *vdst, const void *vsrc, int n)
+{
+ char *dst = vdst;
+ const char *src = vsrc;
+ char *retval = dst;
+
+ while (n-- > 0)
+ *dst++ = *src++;
+
+ return retval;
+}
+
+asm("
+ .reserve trapstack, 1000 * 4, \"bss\", 8
+
+ .data
+ .align 4
+
+in_trap_handler:
+ .word 0
+
+ .text
+ .align 4
+
+! This function is called when any SPARC trap (except window overflow or
+! underflow) occurs. It makes sure that the invalid register window is still
+! available before jumping into C code. It will also restore the world if you
+! return from handle_exception.
+!
+! On entry, trap_low expects l1 and l2 to contain pc and npc respectivly.
+! Register usage throughout the routine is as follows:
+!
+! l0 - psr
+! l1 - pc
+! l2 - npc
+! l3 - wim
+! l4 - scratch and y reg
+! l5 - scratch and tbr
+! l6 - unused
+! l7 - unused
+
+ .globl _trap_low
+_trap_low:
+ mov %psr, %l0
+ mov %wim, %l3
+
+ srl %l3, %l0, %l4 ! wim >> cwp
+ cmp %l4, 1
+ bne window_fine ! Branch if not in the invalid window
+ nop
+
+! Handle window overflow
+
+ mov %g1, %l4 ! Save g1, we use it to hold the wim
+ srl %l3, 1, %g1 ! Rotate wim right
+ tst %g1
+ bg good_wim ! Branch if new wim is non-zero
+ nop
+
+! At this point, we need to bring a 1 into the high order bit of the wim.
+! Since we don't want to make any assumptions about the number of register
+! windows, we figure it out dynamically so as to setup the wim correctly.
+
+ not %g1 ! Fill g1 with ones
+ mov %g1, %wim ! Fill the wim with ones
+ nop
+ nop
+ nop
+ mov %wim, %g1 ! Read back the wim
+ inc %g1 ! Now g1 has 1 just to left of wim
+ srl %g1, 1, %g1 ! Now put 1 at top of wim
+ mov %g0, %wim ! Clear wim so that subsequent save
+ nop ! won't trap
+ nop
+ nop
+
+good_wim:
+ save %g0, %g0, %g0 ! Slip into next window
+ mov %g1, %wim ! Install the new wim
+
+ std %l0, [%sp + 0 * 4] ! save L & I registers
+ std %l2, [%sp + 2 * 4]
+ std %l4, [%sp + 4 * 4]
+ std %l6, [%sp + 6 * 4]
+
+ std %i0, [%sp + 8 * 4]
+ std %i2, [%sp + 10 * 4]
+ std %i4, [%sp + 12 * 4]
+ std %i6, [%sp + 14 * 4]
+
+ restore ! Go back to trap window.
+ mov %l4, %g1 ! Restore %g1
+
+window_fine:
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ tst %l5
+ bg recursive_trap
+ inc %l5
+
+ set trapstack+1000*4, %sp ! Switch to trap stack
+
+recursive_trap:
+ st %l5, [%lo(in_trap_handler) + %l4]
+ sub %sp,(16+1+6+1+80)*4,%sp ! Make room for input & locals
+ ! + hidden arg + arg spill
+ ! + doubleword alignment
+ ! + registers[72] local var
+
+ std %g0, [%sp + (24 + 0) * 4] ! registers[Gx]
+ std %g2, [%sp + (24 + 2) * 4]
+ std %g4, [%sp + (24 + 4) * 4]
+ std %g6, [%sp + (24 + 6) * 4]
+
+ std %i0, [%sp + (24 + 8) * 4] ! registers[Ox]
+ std %i2, [%sp + (24 + 10) * 4]
+ std %i4, [%sp + (24 + 12) * 4]
+ std %i6, [%sp + (24 + 14) * 4]
+
+ mov %y, %l4
+ mov %tbr, %l5
+ st %l4, [%sp + (24 + 64) * 4] ! Y
+ st %l0, [%sp + (24 + 65) * 4] ! PSR
+ st %l3, [%sp + (24 + 66) * 4] ! WIM
+ st %l5, [%sp + (24 + 67) * 4] ! TBR
+ st %l1, [%sp + (24 + 68) * 4] ! PC
+ st %l2, [%sp + (24 + 69) * 4] ! NPC
+
+ or %l0, 0xf20, %l4
+ mov %l4, %psr ! Turn on traps, disable interrupts
+
+ set 0x1000, %l1
+ btst %l1, %l0 ! FP enabled?
+ be no_fpstore
+ nop
+
+! Must save fsr first, to flush the FQ. This may cause a deferred fp trap, so
+! traps must be enabled to allow the trap handler to clean things up.
+
+ st %fsr, [%sp + (24 + 70) * 4]
+
+ std %f0, [%sp + (24 + 32) * 4]
+ std %f2, [%sp + (24 + 34) * 4]
+ std %f4, [%sp + (24 + 36) * 4]
+ std %f6, [%sp + (24 + 38) * 4]
+ std %f8, [%sp + (24 + 40) * 4]
+ std %f10, [%sp + (24 + 42) * 4]
+ std %f12, [%sp + (24 + 44) * 4]
+ std %f14, [%sp + (24 + 46) * 4]
+ std %f16, [%sp + (24 + 48) * 4]
+ std %f18, [%sp + (24 + 50) * 4]
+ std %f20, [%sp + (24 + 52) * 4]
+ std %f22, [%sp + (24 + 54) * 4]
+ std %f24, [%sp + (24 + 56) * 4]
+ std %f26, [%sp + (24 + 58) * 4]
+ std %f28, [%sp + (24 + 60) * 4]
+ std %f30, [%sp + (24 + 62) * 4]
+no_fpstore:
+
+ call _handle_exception
+ add %sp, 24 * 4, %o0 ! Pass address of registers
+
+! Reload all of the registers that aren't on the stack
+
+ ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx]
+ ldd [%sp + (24 + 2) * 4], %g2
+ ldd [%sp + (24 + 4) * 4], %g4
+ ldd [%sp + (24 + 6) * 4], %g6
+
+ ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox]
+ ldd [%sp + (24 + 10) * 4], %i2
+ ldd [%sp + (24 + 12) * 4], %i4
+ ldd [%sp + (24 + 14) * 4], %i6
+
+
+ ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR
+ ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC
+
+ set 0x1000, %l5
+ btst %l5, %l1 ! FP enabled?
+ be no_fpreload
+ nop
+
+ ldd [%sp + (24 + 32) * 4], %f0
+ ldd [%sp + (24 + 34) * 4], %f2
+ ldd [%sp + (24 + 36) * 4], %f4
+ ldd [%sp + (24 + 38) * 4], %f6
+ ldd [%sp + (24 + 40) * 4], %f8
+ ldd [%sp + (24 + 42) * 4], %f10
+ ldd [%sp + (24 + 44) * 4], %f12
+ ldd [%sp + (24 + 46) * 4], %f14
+ ldd [%sp + (24 + 48) * 4], %f16
+ ldd [%sp + (24 + 50) * 4], %f18
+ ldd [%sp + (24 + 52) * 4], %f20
+ ldd [%sp + (24 + 54) * 4], %f22
+ ldd [%sp + (24 + 56) * 4], %f24
+ ldd [%sp + (24 + 58) * 4], %f26
+ ldd [%sp + (24 + 60) * 4], %f28
+ ldd [%sp + (24 + 62) * 4], %f30
+
+ ld [%sp + (24 + 70) * 4], %fsr
+no_fpreload:
+
+ restore ! Ensure that previous window is valid
+ save %g0, %g0, %g0 ! by causing a window_underflow trap
+
+ mov %l0, %y
+ mov %l1, %psr ! Make sure that traps are disabled
+ ! for rett
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ dec %l5
+ st %l5, [%lo(in_trap_handler) + %l4]
+
+ jmpl %l2, %g0 ! Restore old PC
+ rett %l3 ! Restore old nPC
+");
+
+/* Convert ch from a hex digit to an int */
+
+static int
+hex (unsigned char ch)
+{
+ if (ch >= 'a' && ch <= 'f')
+ return ch-'a'+10;
+ if (ch >= '0' && ch <= '9')
+ return ch-'0';
+ if (ch >= 'A' && ch <= 'F')
+ return ch-'A'+10;
+ return -1;
+}
+
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+/* scan for the sequence $<data>#<checksum> */
+
+unsigned char *
+getpacket (void)
+{
+ unsigned char *buffer = &remcomInBuffer[0];
+ unsigned char checksum;
+ unsigned char xmitcsum;
+ int count;
+ char ch;
+
+ while (1)
+ {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = getDebugChar ()) != '$')
+ ;
+
+retry:
+ checksum = 0;
+ xmitcsum = -1;
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX)
+ {
+ ch = getDebugChar ();
+ if (ch == '$')
+ goto retry;
+ if (ch == '#')
+ break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+ buffer[count] = 0;
+
+ if (ch == '#')
+ {
+ ch = getDebugChar ();
+ xmitcsum = hex (ch) << 4;
+ ch = getDebugChar ();
+ xmitcsum += hex (ch);
+
+ if (checksum != xmitcsum)
+ {
+ putDebugChar ('-'); /* failed checksum */
+ }
+ else
+ {
+ putDebugChar ('+'); /* successful transfer */
+
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':')
+ {
+ putDebugChar (buffer[0]);
+ putDebugChar (buffer[1]);
+
+ return &buffer[3];
+ }
+
+ return &buffer[0];
+ }
+ }
+ }
+}
+
+/* send the packet in buffer. */
+
+static void
+putpacket (unsigned char *buffer)
+{
+ unsigned char checksum;
+ int count;
+ unsigned char ch;
+
+ /* $<packet info>#<checksum>. */
+ do
+ {
+ putDebugChar('$');
+ checksum = 0;
+ count = 0;
+
+ while (ch = buffer[count])
+ {
+ putDebugChar (ch);
+ checksum += ch;
+ count += 1;
+ }
+
+ putDebugChar('#');
+ putDebugChar(hexchars[checksum >> 4]);
+ putDebugChar(hexchars[checksum & 0xf]);
+
+ }
+ while (getDebugChar() != '+');
+}
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an
+ error. */
+static volatile int mem_err = 0;
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+ * Return a pointer to the last char put in buf (null), in case of mem fault,
+ * return 0.
+ * If MAY_FAULT is non-zero, then we will handle memory faults by returning
+ * a 0, else treat a fault like any other fault in the stub.
+ */
+
+static unsigned char *
+mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault)
+{
+ unsigned char ch;
+
+ set_mem_fault_trap(may_fault);
+
+ while (count-- > 0)
+ {
+ ch = *mem++;
+ if (mem_err)
+ return 0;
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch & 0xf];
+ }
+
+ *buf = 0;
+
+ set_mem_fault_trap(0);
+
+ return buf;
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem
+ * return a pointer to the character AFTER the last byte written */
+
+static char *
+hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
+{
+ int i;
+ unsigned char ch;
+
+ set_mem_fault_trap(may_fault);
+
+ for (i=0; i<count; i++)
+ {
+ ch = hex(*buf++) << 4;
+ ch |= hex(*buf++);
+ *mem++ = ch;
+ if (mem_err)
+ return 0;
+ }
+
+ set_mem_fault_trap(0);
+
+ return mem;
+}
+
+/* This table contains the mapping between SPARC hardware trap types, and
+ signals, which are primarily what GDB understands. It also indicates
+ which hardware traps we need to commandeer when initializing the stub. */
+
+static struct hard_trap_info
+{
+ unsigned char tt; /* Trap type code for SPARClite */
+ unsigned char signo; /* Signal that we map this trap into */
+} hard_trap_info[] = {
+ {0x01, SIGSEGV}, /* instruction access error */
+ {0x02, SIGILL}, /* privileged instruction */
+ {0x03, SIGILL}, /* illegal instruction */
+ {0x04, SIGEMT}, /* fp disabled */
+ {0x07, SIGBUS}, /* mem address not aligned */
+ {0x09, SIGSEGV}, /* data access exception */
+ {0x0a, SIGEMT}, /* tag overflow */
+ {0x20, SIGBUS}, /* r register access error */
+ {0x21, SIGBUS}, /* instruction access error */
+ {0x24, SIGEMT}, /* cp disabled */
+ {0x29, SIGBUS}, /* data access error */
+ {0x2a, SIGFPE}, /* divide by zero */
+ {0x2b, SIGBUS}, /* data store error */
+ {0x80+1, SIGTRAP}, /* ta 1 - normal breakpoint instruction */
+ {0xff, SIGTRAP}, /* hardware breakpoint */
+ {0, 0} /* Must be last */
+};
+
+/* Set up exception handlers for tracing and breakpoints */
+
+void
+set_debug_traps (void)
+{
+ struct hard_trap_info *ht;
+
+/* Only setup fp traps if the FP is disabled. */
+
+ for (ht = hard_trap_info;
+ ht->tt != 0 && ht->signo != 0;
+ ht++)
+ if (ht->tt != 4 || ! (read_psr () & 0x1000))
+ exceptionHandler(ht->tt, trap_low);
+
+ initialized = 1;
+}
+
+asm ("
+! Trap handler for memory errors. This just sets mem_err to be non-zero. It
+! assumes that %l1 is non-zero. This should be safe, as it is doubtful that
+! 0 would ever contain code that could mem fault. This routine will skip
+! past the faulting instruction after setting mem_err.
+
+ .text
+ .align 4
+
+_fltr_set_mem_err:
+ sethi %hi(_mem_err), %l0
+ st %l1, [%l0 + %lo(_mem_err)]
+ jmpl %l2, %g0
+ rett %l2+4
+");
+
+static void
+set_mem_fault_trap (int enable)
+{
+ extern void fltr_set_mem_err();
+ mem_err = 0;
+
+ if (enable)
+ exceptionHandler(9, fltr_set_mem_err);
+ else
+ exceptionHandler(9, trap_low);
+}
+
+asm ("
+ .text
+ .align 4
+
+_dummy_hw_breakpoint:
+ jmpl %l2, %g0
+ rett %l2+4
+ nop
+ nop
+");
+
+static void
+get_in_break_mode (void)
+{
+ extern void dummy_hw_breakpoint();
+
+ exceptionHandler (255, dummy_hw_breakpoint);
+
+ asm ("ta 255");
+
+ exceptionHandler (255, trap_low);
+}
+
+/* Convert the SPARC hardware trap type code to a unix signal number. */
+
+static int
+computeSignal (int tt)
+{
+ struct hard_trap_info *ht;
+
+ for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+ if (ht->tt == tt)
+ return ht->signo;
+
+ return SIGHUP; /* default for things we don't know about */
+}
+
+/*
+ * While we find nice hex chars, build an int.
+ * Return number of chars processed.
+ */
+
+static int
+hexToInt(char **ptr, int *intValue)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+
+ while (**ptr)
+ {
+ hexValue = hex(**ptr);
+ if (hexValue < 0)
+ break;
+
+ *intValue = (*intValue << 4) | hexValue;
+ numChars ++;
+
+ (*ptr)++;
+ }
+
+ return (numChars);
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb. It
+ * returns 1 if you should skip the instruction at the trap address, 0
+ * otherwise.
+ */
+
+static void
+handle_exception (unsigned long *registers)
+{
+ int tt; /* Trap type */
+ int sigval;
+ int addr;
+ int length;
+ char *ptr;
+ unsigned long *sp;
+ unsigned long dsr;
+
+/* First, we must force all of the windows to be spilled out */
+
+ asm(" save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+");
+
+ get_in_break_mode (); /* Enable DSU register writes */
+
+ registers[DIA1] = read_asi (1, 0xff00);
+ registers[DIA2] = read_asi (1, 0xff04);
+ registers[DDA1] = read_asi (1, 0xff08);
+ registers[DDA2] = read_asi (1, 0xff0c);
+ registers[DDV1] = read_asi (1, 0xff10);
+ registers[DDV2] = read_asi (1, 0xff14);
+ registers[DCR] = read_asi (1, 0xff18);
+ registers[DSR] = read_asi (1, 0xff1c);
+
+ if (registers[PC] == (unsigned long)breakinst)
+ {
+ registers[PC] = registers[NPC];
+ registers[NPC] += 4;
+ }
+ sp = (unsigned long *)registers[SP];
+
+ dsr = (unsigned long)registers[DSR];
+ if (dsr & 0x3c)
+ tt = 255;
+ else
+ tt = (registers[TBR] >> 4) & 0xff;
+
+ /* reply to host that an exception has occurred */
+ sigval = computeSignal(tt);
+ ptr = remcomOutBuffer;
+
+ *ptr++ = 'T';
+ *ptr++ = hexchars[sigval >> 4];
+ *ptr++ = hexchars[sigval & 0xf];
+
+ *ptr++ = hexchars[PC >> 4];
+ *ptr++ = hexchars[PC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[PC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[FP >> 4];
+ *ptr++ = hexchars[FP & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[SP >> 4];
+ *ptr++ = hexchars[SP & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&sp, ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[NPC >> 4];
+ *ptr++ = hexchars[NPC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[NPC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[O7 >> 4];
+ *ptr++ = hexchars[O7 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[O7], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = 0;
+
+ putpacket(remcomOutBuffer);
+
+ while (1)
+ {
+ remcomOutBuffer[0] = 0;
+
+ ptr = getpacket();
+ switch (*ptr++)
+ {
+ case '?':
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval & 0xf];
+ remcomOutBuffer[3] = 0;
+ break;
+
+ case 'd':
+ /* toggle debug flag */
+ break;
+
+ case 'g': /* return the value of the CPU registers */
+ memcpy (&registers[L0], sp, 16 * 4); /* Copy L & I regs from stack */
+ mem2hex ((char *)registers, remcomOutBuffer, NUMREGBYTES, 0);
+ break;
+
+ case 'G': /* Set the value of all registers */
+ case 'P': /* Set the value of one register */
+ {
+ unsigned long *newsp, psr;
+
+ psr = registers[PSR];
+
+ if (ptr[-1] == 'P')
+ {
+ int regno;
+
+ if (hexToInt (&ptr, &regno)
+ && *ptr++ == '=')
+ if (regno >= L0 && regno <= I7)
+ hex2mem (ptr, sp + regno - L0, 4, 0);
+ else
+ hex2mem (ptr, (char *)&registers[regno], 4, 0);
+ else
+ {
+ strcpy (remcomOutBuffer, "E01");
+ break;
+ }
+ }
+ else
+ {
+ hex2mem (ptr, (char *)registers, NUMREGBYTES, 0);
+ memcpy (sp, &registers[L0], 16 * 4); /* Copy L & I regs to stack */
+ }
+
+ /* See if the stack pointer has moved. If so, then copy the saved
+ locals and ins to the new location. This keeps the window
+ overflow and underflow routines happy. */
+
+ newsp = (unsigned long *)registers[SP];
+ if (sp != newsp)
+ sp = memcpy(newsp, sp, 16 * 4);
+
+ /* Don't allow CWP to be modified. */
+
+ if (psr != registers[PSR])
+ registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
+
+ strcpy(remcomOutBuffer,"OK");
+ }
+ break;
+
+ case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ /* Try to read %x,%x. */
+
+ if (hexToInt(&ptr, &addr)
+ && *ptr++ == ','
+ && hexToInt(&ptr, &length))
+ {
+ if (mem2hex((char *)addr, remcomOutBuffer, length, 1))
+ break;
+
+ strcpy (remcomOutBuffer, "E03");
+ }
+ else
+ strcpy(remcomOutBuffer,"E01");
+ break;
+
+ case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ /* Try to read '%x,%x:'. */
+
+ if (hexToInt(&ptr, &addr)
+ && *ptr++ == ','
+ && hexToInt(&ptr, &length)
+ && *ptr++ == ':')
+ {
+ if (hex2mem(ptr, (char *)addr, length, 1))
+ strcpy(remcomOutBuffer, "OK");
+ else
+ strcpy(remcomOutBuffer, "E03");
+ }
+ else
+ strcpy(remcomOutBuffer, "E02");
+ break;
+
+ case 'c': /* cAA..AA Continue at address AA..AA(optional) */
+ /* try to read optional parameter, pc unchanged if no parm */
+ if (hexToInt(&ptr, &addr))
+ {
+ registers[PC] = addr;
+ registers[NPC] = addr + 4;
+ }
+
+/* Need to flush the instruction cache here, as we may have deposited a
+ breakpoint, and the icache probably has no way of knowing that a data ref to
+ some location may have changed something that is in the instruction cache.
+ */
+
+ flush_i_cache ();
+
+ if (!(registers[DSR] & 0x1) /* DSU enabled? */
+ && !(registers[DCR] & 0x200)) /* Are we in break state? */
+ { /* Yes, set the DSU regs */
+ write_asi (1, 0xff00, registers[DIA1]);
+ write_asi (1, 0xff04, registers[DIA2]);
+ write_asi (1, 0xff08, registers[DDA1]);
+ write_asi (1, 0xff0c, registers[DDA2]);
+ write_asi (1, 0xff10, registers[DDV1]);
+ write_asi (1, 0xff14, registers[DDV2]);
+ write_asi (1, 0xff1c, registers[DSR]);
+ write_asi (1, 0xff18, registers[DCR] | 0x200); /* Clear break */
+ }
+
+ return;
+
+ /* kill the program */
+ case 'k' : /* do nothing */
+ break;
+#if 0
+ case 't': /* Test feature */
+ asm (" std %f30,[%sp]");
+ break;
+#endif
+ case 'r': /* Reset */
+ asm ("call 0
+ nop ");
+ break;
+ } /* switch */
+
+ /* reply to the request */
+ putpacket(remcomOutBuffer);
+ }
+}
+
+/* This function will generate a breakpoint exception. It is used at the
+ beginning of a program to sync up with a debugger and can be used
+ otherwise as a quick means to stop program execution and "break" into
+ the debugger. */
+
+void
+breakpoint (void)
+{
+ if (!initialized)
+ return;
+
+ asm(" .globl _breakinst
+
+ _breakinst: ta 1
+ ");
+}
diff --git a/gdb/sparcl-tdep.c b/gdb/sparcl-tdep.c
new file mode 100644
index 00000000000..87351f11c13
--- /dev/null
+++ b/gdb/sparcl-tdep.c
@@ -0,0 +1,869 @@
+/* Target dependent code for the Fujitsu SPARClite for GDB, the GNU debugger.
+ Copyright 1994, 1995, 1996, 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "gdbcore.h"
+#include "breakpoint.h"
+#include "target.h"
+#include "serial.h"
+#include "regcache.h"
+#include <sys/types.h>
+
+#if (!defined(__GO32__) && !defined(_WIN32)) || defined(__CYGWIN32__)
+#define HAVE_SOCKETS
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#endif
+
+static struct target_ops sparclite_ops;
+
+static char *remote_target_name = NULL;
+static struct serial *remote_desc = NULL;
+static int serial_flag;
+#ifdef HAVE_SOCKETS
+static int udp_fd = -1;
+#endif
+
+static struct serial *open_tty (char *name);
+static int send_resp (struct serial *desc, char c);
+static void close_tty (void * ignore);
+#ifdef HAVE_SOCKETS
+static int recv_udp_buf (int fd, unsigned char *buf, int len, int timeout);
+static int send_udp_buf (int fd, unsigned char *buf, int len);
+#endif
+static void sparclite_open (char *name, int from_tty);
+static void sparclite_close (int quitting);
+static void download (char *target_name, char *args, int from_tty,
+ void (*write_routine) (bfd * from_bfd,
+ asection * from_sec,
+ file_ptr from_addr,
+ bfd_vma to_addr, int len),
+ void (*start_routine) (bfd_vma entry));
+static void sparclite_serial_start (bfd_vma entry);
+static void sparclite_serial_write (bfd * from_bfd, asection * from_sec,
+ file_ptr from_addr,
+ bfd_vma to_addr, int len);
+#ifdef HAVE_SOCKETS
+static unsigned short calc_checksum (unsigned char *buffer, int count);
+static void sparclite_udp_start (bfd_vma entry);
+static void sparclite_udp_write (bfd * from_bfd, asection * from_sec,
+ file_ptr from_addr, bfd_vma to_addr,
+ int len);
+#endif
+static void sparclite_download (char *filename, int from_tty);
+
+#define DDA2_SUP_ASI 0xb000000
+#define DDA1_SUP_ASI 0xb0000
+
+#define DDA2_ASI_MASK 0xff000000
+#define DDA1_ASI_MASK 0xff0000
+#define DIA2_SUP_MODE 0x8000
+#define DIA1_SUP_MODE 0x4000
+#define DDA2_ENABLE 0x100
+#define DDA1_ENABLE 0x80
+#define DIA2_ENABLE 0x40
+#define DIA1_ENABLE 0x20
+#define DSINGLE_STEP 0x10 /* not used */
+#define DDV_TYPE_MASK 0xc
+#define DDV_TYPE_LOAD 0x0
+#define DDV_TYPE_STORE 0x4
+#define DDV_TYPE_ACCESS 0x8
+#define DDV_TYPE_ALWAYS 0xc
+#define DDV_COND 0x2
+#define DDV_MASK 0x1
+
+int
+sparclite_insert_watchpoint (CORE_ADDR addr, int len, int type)
+{
+ CORE_ADDR dcr;
+
+ dcr = read_register (DCR_REGNUM);
+
+ if (!(dcr & DDA1_ENABLE))
+ {
+ write_register (DDA1_REGNUM, addr);
+ dcr &= ~(DDA1_ASI_MASK | DDV_TYPE_MASK);
+ dcr |= (DDA1_SUP_ASI | DDA1_ENABLE);
+ if (type == 1)
+ {
+ write_register (DDV1_REGNUM, 0);
+ write_register (DDV2_REGNUM, 0xffffffff);
+ dcr |= (DDV_TYPE_LOAD & (~DDV_COND & ~DDV_MASK));
+ }
+ else if (type == 0)
+ {
+ write_register (DDV1_REGNUM, 0);
+ write_register (DDV2_REGNUM, 0xffffffff);
+ dcr |= (DDV_TYPE_STORE & (~DDV_COND & ~DDV_MASK));
+ }
+ else
+ {
+ write_register (DDV1_REGNUM, 0);
+ write_register (DDV2_REGNUM, 0xffffffff);
+ dcr |= (DDV_TYPE_ACCESS);
+ }
+ write_register (DCR_REGNUM, dcr);
+ }
+ else if (!(dcr & DDA2_ENABLE))
+ {
+ write_register (DDA2_REGNUM, addr);
+ dcr &= ~(DDA2_ASI_MASK & DDV_TYPE_MASK);
+ dcr |= (DDA2_SUP_ASI | DDA2_ENABLE);
+ if (type == 1)
+ {
+ write_register (DDV1_REGNUM, 0);
+ write_register (DDV2_REGNUM, 0xffffffff);
+ dcr |= (DDV_TYPE_LOAD & ~DDV_COND & ~DDV_MASK);
+ }
+ else if (type == 0)
+ {
+ write_register (DDV1_REGNUM, 0);
+ write_register (DDV2_REGNUM, 0xffffffff);
+ dcr |= (DDV_TYPE_STORE & ~DDV_COND & ~DDV_MASK);
+ }
+ else
+ {
+ write_register (DDV1_REGNUM, 0);
+ write_register (DDV2_REGNUM, 0xffffffff);
+ dcr |= (DDV_TYPE_ACCESS);
+ }
+ write_register (DCR_REGNUM, dcr);
+ }
+ else
+ return -1;
+
+ return 0;
+}
+
+int
+sparclite_remove_watchpoint (CORE_ADDR addr, int len, int type)
+{
+ CORE_ADDR dcr, dda1, dda2;
+
+ dcr = read_register (DCR_REGNUM);
+ dda1 = read_register (DDA1_REGNUM);
+ dda2 = read_register (DDA2_REGNUM);
+
+ if ((dcr & DDA1_ENABLE) && addr == dda1)
+ write_register (DCR_REGNUM, (dcr & ~DDA1_ENABLE));
+ else if ((dcr & DDA2_ENABLE) && addr == dda2)
+ write_register (DCR_REGNUM, (dcr & ~DDA2_ENABLE));
+ else
+ return -1;
+
+ return 0;
+}
+
+int
+sparclite_insert_hw_breakpoint (CORE_ADDR addr, int len)
+{
+ CORE_ADDR dcr;
+
+ dcr = read_register (DCR_REGNUM);
+
+ if (!(dcr & DIA1_ENABLE))
+ {
+ write_register (DIA1_REGNUM, addr);
+ write_register (DCR_REGNUM, (dcr | DIA1_ENABLE | DIA1_SUP_MODE));
+ }
+ else if (!(dcr & DIA2_ENABLE))
+ {
+ write_register (DIA2_REGNUM, addr);
+ write_register (DCR_REGNUM, (dcr | DIA2_ENABLE | DIA2_SUP_MODE));
+ }
+ else
+ return -1;
+
+ return 0;
+}
+
+int
+sparclite_remove_hw_breakpoint (CORE_ADDR addr, int shadow)
+{
+ CORE_ADDR dcr, dia1, dia2;
+
+ dcr = read_register (DCR_REGNUM);
+ dia1 = read_register (DIA1_REGNUM);
+ dia2 = read_register (DIA2_REGNUM);
+
+ if ((dcr & DIA1_ENABLE) && addr == dia1)
+ write_register (DCR_REGNUM, (dcr & ~DIA1_ENABLE));
+ else if ((dcr & DIA2_ENABLE) && addr == dia2)
+ write_register (DCR_REGNUM, (dcr & ~DIA2_ENABLE));
+ else
+ return -1;
+
+ return 0;
+}
+
+int
+sparclite_check_watch_resources (int type, int cnt, int ot)
+{
+ /* Watchpoints not supported on simulator. */
+ if (strcmp (target_shortname, "sim") == 0)
+ return 0;
+
+ if (type == bp_hardware_breakpoint)
+ {
+ if (TARGET_HW_BREAK_LIMIT == 0)
+ return 0;
+ else if (cnt <= TARGET_HW_BREAK_LIMIT)
+ return 1;
+ }
+ else
+ {
+ if (TARGET_HW_WATCH_LIMIT == 0)
+ return 0;
+ else if (ot)
+ return -1;
+ else if (cnt <= TARGET_HW_WATCH_LIMIT)
+ return 1;
+ }
+ return -1;
+}
+
+CORE_ADDR
+sparclite_stopped_data_address (void)
+{
+ CORE_ADDR dsr, dda1, dda2;
+
+ dsr = read_register (DSR_REGNUM);
+ dda1 = read_register (DDA1_REGNUM);
+ dda2 = read_register (DDA2_REGNUM);
+
+ if (dsr & 0x10)
+ return dda1;
+ else if (dsr & 0x20)
+ return dda2;
+ else
+ return 0;
+}
+
+static struct serial *
+open_tty (char *name)
+{
+ struct serial *desc;
+
+ desc = serial_open (name);
+ if (!desc)
+ perror_with_name (name);
+
+ if (baud_rate != -1)
+ {
+ if (serial_setbaudrate (desc, baud_rate))
+ {
+ serial_close (desc);
+ perror_with_name (name);
+ }
+ }
+
+ serial_raw (desc);
+
+ serial_flush_input (desc);
+
+ return desc;
+}
+
+/* Read a single character from the remote end, masking it down to 7 bits. */
+
+static int
+readchar (struct serial *desc, int timeout)
+{
+ int ch;
+ char s[10];
+
+ ch = serial_readchar (desc, timeout);
+
+ switch (ch)
+ {
+ case SERIAL_EOF:
+ error ("SPARClite remote connection closed");
+ case SERIAL_ERROR:
+ perror_with_name ("SPARClite communication error");
+ case SERIAL_TIMEOUT:
+ error ("SPARClite remote timeout");
+ default:
+ if (remote_debug > 0)
+ {
+ sprintf (s, "[%02x]", ch & 0xff);
+ puts_debug ("read -->", s, "<--");
+ }
+ return ch;
+ }
+}
+
+static void
+debug_serial_write (struct serial *desc, char *buf, int len)
+{
+ char s[10];
+
+ serial_write (desc, buf, len);
+ if (remote_debug > 0)
+ {
+ while (len-- > 0)
+ {
+ sprintf (s, "[%02x]", *buf & 0xff);
+ puts_debug ("Sent -->", s, "<--");
+ buf++;
+ }
+ }
+}
+
+
+static int
+send_resp (struct serial *desc, char c)
+{
+ debug_serial_write (desc, &c, 1);
+ return readchar (desc, remote_timeout);
+}
+
+static void
+close_tty (void *ignore)
+{
+ if (!remote_desc)
+ return;
+
+ serial_close (remote_desc);
+
+ remote_desc = NULL;
+}
+
+#ifdef HAVE_SOCKETS
+static int
+recv_udp_buf (int fd, unsigned char *buf, int len, int timeout)
+{
+ int cc;
+ fd_set readfds;
+
+ FD_ZERO (&readfds);
+ FD_SET (fd, &readfds);
+
+ if (timeout >= 0)
+ {
+ struct timeval timebuf;
+
+ timebuf.tv_sec = timeout;
+ timebuf.tv_usec = 0;
+ cc = select (fd + 1, &readfds, 0, 0, &timebuf);
+ }
+ else
+ cc = select (fd + 1, &readfds, 0, 0, 0);
+
+ if (cc == 0)
+ return 0;
+
+ if (cc != 1)
+ perror_with_name ("recv_udp_buf: Bad return value from select:");
+
+ cc = recv (fd, buf, len, 0);
+
+ if (cc < 0)
+ perror_with_name ("Got an error from recv: ");
+}
+
+static int
+send_udp_buf (int fd, unsigned char *buf, int len)
+{
+ int cc;
+
+ cc = send (fd, buf, len, 0);
+
+ if (cc == len)
+ return;
+
+ if (cc < 0)
+ perror_with_name ("Got an error from send: ");
+
+ error ("Short count in send: tried %d, sent %d\n", len, cc);
+}
+#endif /* HAVE_SOCKETS */
+
+static void
+sparclite_open (char *name, int from_tty)
+{
+ struct cleanup *old_chain;
+ int c;
+ char *p;
+
+ if (!name)
+ error ("You need to specify what device or hostname is associated with the SparcLite board.");
+
+ target_preopen (from_tty);
+
+ unpush_target (&sparclite_ops);
+
+ if (remote_target_name)
+ xfree (remote_target_name);
+
+ remote_target_name = xstrdup (name);
+
+ /* We need a 'serial' or 'udp' keyword to disambiguate host:port, which can
+ mean either a serial port on a terminal server, or the IP address of a
+ SPARClite demo board. If there's no colon, then it pretty much has to be
+ a local device (except for DOS... grrmble) */
+
+ p = strchr (name, ' ');
+
+ if (p)
+ {
+ *p++ = '\000';
+ while ((*p != '\000') && isspace (*p))
+ p++;
+
+ if (strncmp (name, "serial", strlen (name)) == 0)
+ serial_flag = 1;
+ else if (strncmp (name, "udp", strlen (name)) == 0)
+ serial_flag = 0;
+ else
+ error ("Must specify either `serial' or `udp'.");
+ }
+ else
+ {
+ p = name;
+
+ if (!strchr (name, ':'))
+ serial_flag = 1; /* No colon is unambiguous (local device) */
+ else
+ error ("Usage: target sparclite serial /dev/ttyb\n\
+or: target sparclite udp host");
+ }
+
+ if (serial_flag)
+ {
+ remote_desc = open_tty (p);
+
+ old_chain = make_cleanup (close_tty, 0 /*ignore*/);
+
+ c = send_resp (remote_desc, 0x00);
+
+ if (c != 0xaa)
+ error ("Unknown response (0x%x) from SparcLite. Try resetting the board.",
+ c);
+
+ c = send_resp (remote_desc, 0x55);
+
+ if (c != 0x55)
+ error ("Sparclite appears to be ill.");
+ }
+ else
+ {
+#ifdef HAVE_SOCKETS
+ struct hostent *he;
+ struct sockaddr_in sockaddr;
+ unsigned char buffer[100];
+ int cc;
+
+ /* Setup the socket. Must be raw UDP. */
+
+ he = gethostbyname (p);
+
+ if (!he)
+ error ("No such host %s.", p);
+
+ udp_fd = socket (PF_INET, SOCK_DGRAM, 0);
+
+ old_chain = make_cleanup (close, udp_fd);
+
+ sockaddr.sin_family = PF_INET;
+ sockaddr.sin_port = htons (7000);
+ memcpy (&sockaddr.sin_addr.s_addr, he->h_addr, sizeof (struct in_addr));
+
+ if (connect (udp_fd, &sockaddr, sizeof (sockaddr)))
+ perror_with_name ("Connect failed");
+
+ buffer[0] = 0x5;
+ buffer[1] = 0;
+
+ send_udp_buf (udp_fd, buffer, 2); /* Request version */
+ cc = recv_udp_buf (udp_fd, buffer, sizeof (buffer), 5); /* Get response */
+ if (cc == 0)
+ error ("SPARClite isn't responding.");
+
+ if (cc < 3)
+ error ("SPARClite appears to be ill.");
+#else
+ error ("UDP downloading is not supported for DOS hosts.");
+#endif /* HAVE_SOCKETS */
+ }
+
+ printf_unfiltered ("[SPARClite appears to be alive]\n");
+
+ push_target (&sparclite_ops);
+
+ discard_cleanups (old_chain);
+
+ return;
+}
+
+static void
+sparclite_close (int quitting)
+{
+ if (serial_flag)
+ close_tty (0);
+#ifdef HAVE_SOCKETS
+ else if (udp_fd != -1)
+ close (udp_fd);
+#endif
+}
+
+#define LOAD_ADDRESS 0x40000000
+
+static void
+download (char *target_name, char *args, int from_tty,
+ void (*write_routine) (bfd *from_bfd, asection *from_sec,
+ file_ptr from_addr, bfd_vma to_addr, int len),
+ void (*start_routine) (bfd_vma entry))
+{
+ struct cleanup *old_chain;
+ asection *section;
+ bfd *pbfd;
+ bfd_vma entry;
+ int i;
+#define WRITESIZE 1024
+ char *filename;
+ int quiet;
+ int nostart;
+
+ quiet = 0;
+ nostart = 0;
+ filename = NULL;
+
+ while (*args != '\000')
+ {
+ char *arg;
+
+ while (isspace (*args))
+ args++;
+
+ arg = args;
+
+ while ((*args != '\000') && !isspace (*args))
+ args++;
+
+ if (*args != '\000')
+ *args++ = '\000';
+
+ if (*arg != '-')
+ filename = arg;
+ else if (strncmp (arg, "-quiet", strlen (arg)) == 0)
+ quiet = 1;
+ else if (strncmp (arg, "-nostart", strlen (arg)) == 0)
+ nostart = 1;
+ else
+ error ("unknown option `%s'", arg);
+ }
+
+ if (!filename)
+ filename = get_exec_file (1);
+
+ pbfd = bfd_openr (filename, gnutarget);
+ if (pbfd == NULL)
+ {
+ perror_with_name (filename);
+ return;
+ }
+ old_chain = make_cleanup_bfd_close (pbfd);
+
+ if (!bfd_check_format (pbfd, bfd_object))
+ error ("\"%s\" is not an object file: %s", filename,
+ bfd_errmsg (bfd_get_error ()));
+
+ for (section = pbfd->sections; section; section = section->next)
+ {
+ if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
+ {
+ bfd_vma section_address;
+ bfd_size_type section_size;
+ file_ptr fptr;
+ const char *section_name;
+
+ section_name = bfd_get_section_name (pbfd, section);
+
+ section_address = bfd_get_section_vma (pbfd, section);
+
+ /* Adjust sections from a.out files, since they don't
+ carry their addresses with. */
+ if (bfd_get_flavour (pbfd) == bfd_target_aout_flavour)
+ {
+ if (strcmp (section_name, ".text") == 0)
+ section_address = bfd_get_start_address (pbfd);
+ else if (strcmp (section_name, ".data") == 0)
+ {
+ /* Read the first 8 bytes of the data section.
+ There should be the string 'DaTa' followed by
+ a word containing the actual section address. */
+ struct data_marker
+ {
+ char signature[4]; /* 'DaTa' */
+ unsigned char sdata[4]; /* &sdata */
+ }
+ marker;
+ bfd_get_section_contents (pbfd, section, &marker, 0,
+ sizeof (marker));
+ if (strncmp (marker.signature, "DaTa", 4) == 0)
+ {
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ section_address = bfd_getb32 (marker.sdata);
+ else
+ section_address = bfd_getl32 (marker.sdata);
+ }
+ }
+ }
+
+ section_size = bfd_get_section_size_before_reloc (section);
+
+ if (!quiet)
+ printf_filtered ("[Loading section %s at 0x%x (%d bytes)]\n",
+ bfd_get_section_name (pbfd, section),
+ section_address,
+ section_size);
+
+ fptr = 0;
+ while (section_size > 0)
+ {
+ int count;
+ static char inds[] = "|/-\\";
+ static int k = 0;
+
+ QUIT;
+
+ count = min (section_size, WRITESIZE);
+
+ write_routine (pbfd, section, fptr, section_address, count);
+
+ if (!quiet)
+ {
+ printf_unfiltered ("\r%c", inds[k++ % 4]);
+ gdb_flush (gdb_stdout);
+ }
+
+ section_address += count;
+ fptr += count;
+ section_size -= count;
+ }
+ }
+ }
+
+ if (!nostart)
+ {
+ entry = bfd_get_start_address (pbfd);
+
+ if (!quiet)
+ printf_unfiltered ("[Starting %s at 0x%x]\n", filename, entry);
+
+ start_routine (entry);
+ }
+
+ do_cleanups (old_chain);
+}
+
+static void
+sparclite_serial_start (bfd_vma entry)
+{
+ char buffer[5];
+ int i;
+
+ buffer[0] = 0x03;
+ store_unsigned_integer (buffer + 1, 4, entry);
+
+ debug_serial_write (remote_desc, buffer, 1 + 4);
+ i = readchar (remote_desc, remote_timeout);
+ if (i != 0x55)
+ error ("Can't start SparcLite. Error code %d\n", i);
+}
+
+static void
+sparclite_serial_write (bfd *from_bfd, asection *from_sec, file_ptr from_addr,
+ bfd_vma to_addr, int len)
+{
+ char buffer[4 + 4 + WRITESIZE]; /* addr + len + data */
+ unsigned char checksum;
+ int i;
+
+ store_unsigned_integer (buffer, 4, to_addr); /* Address */
+ store_unsigned_integer (buffer + 4, 4, len); /* Length */
+
+ bfd_get_section_contents (from_bfd, from_sec, buffer + 8, from_addr, len);
+
+ checksum = 0;
+ for (i = 0; i < len; i++)
+ checksum += buffer[8 + i];
+
+ i = send_resp (remote_desc, 0x01);
+
+ if (i != 0x5a)
+ error ("Bad response from load command (0x%x)", i);
+
+ debug_serial_write (remote_desc, buffer, 4 + 4 + len);
+ i = readchar (remote_desc, remote_timeout);
+
+ if (i != checksum)
+ error ("Bad checksum from load command (0x%x)", i);
+}
+
+#ifdef HAVE_SOCKETS
+
+static unsigned short
+calc_checksum (unsigned char *buffer, int count)
+{
+ unsigned short checksum;
+
+ checksum = 0;
+ for (; count > 0; count -= 2, buffer += 2)
+ checksum += (*buffer << 8) | *(buffer + 1);
+
+ if (count != 0)
+ checksum += *buffer << 8;
+
+ return checksum;
+}
+
+static void
+sparclite_udp_start (bfd_vma entry)
+{
+ unsigned char buffer[6];
+ int i;
+
+ buffer[0] = 0x3;
+ buffer[1] = 0;
+ buffer[2] = entry >> 24;
+ buffer[3] = entry >> 16;
+ buffer[4] = entry >> 8;
+ buffer[5] = entry;
+
+ send_udp_buf (udp_fd, buffer, 6); /* Send start addr */
+ i = recv_udp_buf (udp_fd, buffer, sizeof (buffer), -1); /* Get response */
+
+ if (i < 1 || buffer[0] != 0x55)
+ error ("Failed to take start address.");
+}
+
+static void
+sparclite_udp_write (bfd *from_bfd, asection *from_sec, file_ptr from_addr,
+ bfd_vma to_addr, int len)
+{
+ unsigned char buffer[2000];
+ unsigned short checksum;
+ static int pkt_num = 0;
+ static unsigned long old_addr = -1;
+ int i;
+
+ while (1)
+ {
+ if (to_addr != old_addr)
+ {
+ buffer[0] = 0x1; /* Load command */
+ buffer[1] = 0x1; /* Loading address */
+ buffer[2] = to_addr >> 24;
+ buffer[3] = to_addr >> 16;
+ buffer[4] = to_addr >> 8;
+ buffer[5] = to_addr;
+
+ checksum = 0;
+ for (i = 0; i < 6; i++)
+ checksum += buffer[i];
+ checksum &= 0xff;
+
+ send_udp_buf (udp_fd, buffer, 6);
+ i = recv_udp_buf (udp_fd, buffer, sizeof buffer, -1);
+
+ if (i < 1)
+ error ("Got back short checksum for load addr.");
+
+ if (checksum != buffer[0])
+ error ("Got back bad checksum for load addr.");
+
+ pkt_num = 0; /* Load addr resets packet seq # */
+ old_addr = to_addr;
+ }
+
+ bfd_get_section_contents (from_bfd, from_sec, buffer + 6, from_addr,
+ len);
+
+ checksum = calc_checksum (buffer + 6, len);
+
+ buffer[0] = 0x1; /* Load command */
+ buffer[1] = 0x2; /* Loading data */
+ buffer[2] = pkt_num >> 8;
+ buffer[3] = pkt_num;
+ buffer[4] = checksum >> 8;
+ buffer[5] = checksum;
+
+ send_udp_buf (udp_fd, buffer, len + 6);
+ i = recv_udp_buf (udp_fd, buffer, sizeof buffer, 3);
+
+ if (i == 0)
+ {
+ fprintf_unfiltered (gdb_stderr, "send_data: timeout sending %d bytes to address 0x%x retrying\n", len, to_addr);
+ continue;
+ }
+
+ if (buffer[0] != 0xff)
+ error ("Got back bad response for load data.");
+
+ old_addr += len;
+ pkt_num++;
+
+ return;
+ }
+}
+
+#endif /* HAVE_SOCKETS */
+
+static void
+sparclite_download (char *filename, int from_tty)
+{
+ if (!serial_flag)
+#ifdef HAVE_SOCKETS
+ download (remote_target_name, filename, from_tty, sparclite_udp_write,
+ sparclite_udp_start);
+#else
+ internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* sparclite_open should prevent this! */
+#endif
+ else
+ download (remote_target_name, filename, from_tty, sparclite_serial_write,
+ sparclite_serial_start);
+}
+
+/* Set up the sparclite target vector. */
+
+static void
+init_sparclite_ops (void)
+{
+ sparclite_ops.to_shortname = "sparclite";
+ sparclite_ops.to_longname = "SPARClite download target";
+ sparclite_ops.to_doc = "Download to a remote SPARClite target board via serial of UDP.\n\
+Specify the device it is connected to (e.g. /dev/ttya).";
+ sparclite_ops.to_open = sparclite_open;
+ sparclite_ops.to_close = sparclite_close;
+ sparclite_ops.to_load = sparclite_download;
+ sparclite_ops.to_stratum = download_stratum;
+ sparclite_ops.to_magic = OPS_MAGIC;
+}
+
+void
+_initialize_sparcl_tdep (void)
+{
+ init_sparclite_ops ();
+ add_target (&sparclite_ops);
+}
diff --git a/gdb/sparclet-rom.c b/gdb/sparclet-rom.c
new file mode 100644
index 00000000000..fa2ca1ef53a
--- /dev/null
+++ b/gdb/sparclet-rom.c
@@ -0,0 +1,316 @@
+/* Remote target glue for the SPARC Sparclet ROM monitor.
+
+ Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "srec.h"
+#include "symtab.h"
+#include "symfile.h" /* for generic_load */
+#include "regcache.h"
+#include <time.h>
+
+extern void report_transfer_performance (unsigned long, time_t, time_t);
+
+static struct target_ops sparclet_ops;
+
+static void sparclet_open (char *args, int from_tty);
+
+/* This array of registers need to match the indexes used by GDB.
+ This exists because the various ROM monitors use different strings
+ than does GDB, and don't necessarily support all the registers
+ either. So, typing "info reg sp" becomes a "r30". */
+
+/*PSR 0x00000080 impl ver icc AW LE EE EC EF PIL S PS ET CWP WIM
+ 0x0 0x0 0x0 0 0 0 0 0 0x0 1 0 0 0x00 0x2
+ 0000010
+ INS LOCALS OUTS GLOBALS
+ 0 0x00000000 0x00000000 0x00000000 0x00000000
+ 1 0x00000000 0x00000000 0x00000000 0x00000000
+ 2 0x00000000 0x00000000 0x00000000 0x00000000
+ 3 0x00000000 0x00000000 0x00000000 0x00000000
+ 4 0x00000000 0x00000000 0x00000000 0x00000000
+ 5 0x00000000 0x00001000 0x00000000 0x00000000
+ 6 0x00000000 0x00000000 0x123f0000 0x00000000
+ 7 0x00000000 0x00000000 0x00000000 0x00000000
+ pc: 0x12010000 0x00000000 unimp
+ npc: 0x12010004 0x00001000 unimp 0x1000
+ tbr: 0x00000000
+ y: 0x00000000
+ */
+/* these correspond to the offsets from tm-* files from config directories */
+
+/* is wim part of psr?? */
+/* monitor wants lower case */
+static char *sparclet_regnames[] = {
+ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+ "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
+
+ "", "", "", "", "", "", "", "", /* no FPU regs */
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ /* no CPSR, FPSR */
+ "y", "psr", "wim", "tbr", "pc", "npc", "", "",
+
+ "ccsr", "ccpr", "cccrcr", "ccor", "ccobr", "ccibr", "ccir", "",
+
+ /* ASR15 ASR19 (don't display them) */
+ "asr1", "", "asr17", "asr18", "", "asr20", "asr21", "asr22",
+/*
+ "awr0", "awr1", "awr2", "awr3", "awr4", "awr5", "awr6", "awr7",
+ "awr8", "awr9", "awr10", "awr11", "awr12", "awr13", "awr14", "awr15",
+ "awr16", "awr17", "awr18", "awr19", "awr20", "awr21", "awr22", "awr23",
+ "awr24", "awr25", "awr26", "awr27", "awr28", "awr29", "awr30", "awr31",
+ "apsr",
+ */
+};
+
+
+
+/* Function: sparclet_supply_register
+ Just returns with no action.
+ This function is required, because parse_register_dump (monitor.c)
+ expects to be able to call it. If we don't supply something, it will
+ call a null pointer and core-dump. Since this function does not
+ actually do anything, GDB will request the registers individually. */
+
+static void
+sparclet_supply_register (char *regname, int regnamelen, char *val, int vallen)
+{
+ return;
+}
+
+static void
+sparclet_load (struct serial *desc, char *file, int hashmark)
+{
+ bfd *abfd;
+ asection *s;
+ int i;
+ CORE_ADDR load_offset;
+ time_t start_time, end_time;
+ unsigned long data_count = 0;
+
+ /* enable user to specify address for downloading as 2nd arg to load */
+
+ i = sscanf (file, "%*s 0x%lx", &load_offset);
+ if (i >= 1)
+ {
+ char *p;
+
+ for (p = file; *p != '\000' && !isspace (*p); p++);
+
+ *p = '\000';
+ }
+ else
+ load_offset = 0;
+
+ abfd = bfd_openr (file, 0);
+ if (!abfd)
+ {
+ printf_filtered ("Unable to open file %s\n", file);
+ return;
+ }
+
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ {
+ printf_filtered ("File is not an object file\n");
+ return;
+ }
+
+ start_time = time (NULL);
+
+ for (s = abfd->sections; s; s = s->next)
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_size_type section_size;
+ bfd_vma vma;
+
+ vma = bfd_get_section_vma (abfd, s) + load_offset;
+ section_size = bfd_section_size (abfd, s);
+
+ data_count += section_size;
+
+ printf_filtered ("%s\t: 0x%4x .. 0x%4x ",
+ bfd_get_section_name (abfd, s), vma,
+ vma + section_size);
+ gdb_flush (gdb_stdout);
+
+ monitor_printf ("load c r %x %x\r", vma, section_size);
+
+ monitor_expect ("load: loading ", NULL, 0);
+ monitor_expect ("\r", NULL, 0);
+
+ for (i = 0; i < section_size; i += 2048)
+ {
+ int numbytes;
+ char buf[2048];
+
+ numbytes = min (sizeof buf, section_size - i);
+
+ bfd_get_section_contents (abfd, s, buf, i, numbytes);
+
+ serial_write (desc, buf, numbytes);
+
+ if (hashmark)
+ {
+ putchar_unfiltered ('#');
+ gdb_flush (gdb_stdout);
+ }
+ } /* Per-packet (or S-record) loop */
+
+ monitor_expect_prompt (NULL, 0);
+
+ putchar_unfiltered ('\n');
+ } /* Loadable sections */
+
+ monitor_printf ("reg pc %x\r", bfd_get_start_address (abfd));
+ monitor_expect_prompt (NULL, 0);
+ monitor_printf ("reg npc %x\r", bfd_get_start_address (abfd) + 4);
+ monitor_expect_prompt (NULL, 0);
+
+ monitor_printf ("run\r");
+
+ end_time = time (NULL);
+
+ if (hashmark)
+ putchar_unfiltered ('\n');
+
+ report_transfer_performance (data_count, start_time, end_time);
+
+ pop_target ();
+ push_remote_target (monitor_get_dev_name (), 1);
+
+ throw_exception (RETURN_QUIT);
+}
+
+/* Define the monitor command strings. Since these are passed directly
+ through to a printf style function, we may include formatting
+ strings. We also need a CR or LF on the end. */
+
+/* need to pause the monitor for timing reasons, so slow it down */
+
+static char *sparclet_inits[] =
+{"\n\r\r\n", NULL};
+
+static struct monitor_ops sparclet_cmds;
+
+static void
+init_sparclet_cmds (void)
+{
+ sparclet_cmds.flags = MO_CLR_BREAK_USES_ADDR |
+ MO_HEX_PREFIX |
+ MO_NO_ECHO_ON_OPEN |
+ MO_NO_ECHO_ON_SETMEM |
+ MO_RUN_FIRST_TIME |
+ MO_GETMEM_READ_SINGLE; /* flags */
+ sparclet_cmds.init = sparclet_inits; /* Init strings */
+ sparclet_cmds.cont = "cont\r"; /* continue command */
+ sparclet_cmds.step = "step\r"; /* single step */
+ sparclet_cmds.stop = "\r"; /* break interrupts the program */
+ sparclet_cmds.set_break = "+bp %x\r"; /* set a breakpoint */
+ sparclet_cmds.clr_break = "-bp %x\r"; /* can't use "br" because only 2 hw bps are supported */
+ sparclet_cmds.clr_all_break = "-bp %x\r"; /* clear a breakpoint */
+ "-bp\r"; /* clear all breakpoints */
+ sparclet_cmds.fill = "fill %x -n %x -v %x -b\r"; /* fill (start length val) */
+ /* can't use "fi" because it takes words, not bytes */
+ /* ex [addr] [-n count] [-b|-s|-l] default: ex cur -n 1 -b */
+ sparclet_cmds.setmem.cmdb = "ex %x -b\r%x\rq\r"; /* setmem.cmdb (addr, value) */
+ sparclet_cmds.setmem.cmdw = "ex %x -s\r%x\rq\r"; /* setmem.cmdw (addr, value) */
+ sparclet_cmds.setmem.cmdl = "ex %x -l\r%x\rq\r"; /* setmem.cmdl (addr, value) */
+ sparclet_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ sparclet_cmds.setmem.resp_delim = NULL; /*": " *//* setmem.resp_delim */
+ sparclet_cmds.setmem.term = NULL; /*"? " *//* setmem.term */
+ sparclet_cmds.setmem.term_cmd = NULL; /*"q\r" *//* setmem.term_cmd */
+ /* since the parsing of multiple bytes is difficult due to
+ interspersed addresses, we'll only read 1 value at a time,
+ even tho these can handle a count */
+ /* we can use -n to set count to read, but may have to parse? */
+ sparclet_cmds.getmem.cmdb = "ex %x -n 1 -b\r"; /* getmem.cmdb (addr, #bytes) */
+ sparclet_cmds.getmem.cmdw = "ex %x -n 1 -s\r"; /* getmem.cmdw (addr, #swords) */
+ sparclet_cmds.getmem.cmdl = "ex %x -n 1 -l\r"; /* getmem.cmdl (addr, #words) */
+ sparclet_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, #dwords) */
+ sparclet_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
+ sparclet_cmds.getmem.term = NULL; /* getmem.term */
+ sparclet_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
+ sparclet_cmds.setreg.cmd = "reg %s 0x%x\r"; /* setreg.cmd (name, value) */
+ sparclet_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ sparclet_cmds.setreg.term = NULL; /* setreg.term */
+ sparclet_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
+ sparclet_cmds.getreg.cmd = "reg %s\r"; /* getreg.cmd (name) */
+ sparclet_cmds.getreg.resp_delim = " "; /* getreg.resp_delim */
+ sparclet_cmds.getreg.term = NULL; /* getreg.term */
+ sparclet_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
+ sparclet_cmds.dump_registers = "reg\r"; /* dump_registers */
+ sparclet_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */
+ sparclet_cmds.supply_register = sparclet_supply_register; /* supply_register */
+ sparclet_cmds.load_routine = sparclet_load; /* load_routine */
+ sparclet_cmds.load = NULL; /* download command (srecs on console) */
+ sparclet_cmds.loadresp = NULL; /* load response */
+ sparclet_cmds.prompt = "monitor>"; /* monitor command prompt */
+ /* yikes! gdb core dumps without this delimitor!! */
+ sparclet_cmds.line_term = "\r"; /* end-of-command delimitor */
+ sparclet_cmds.cmd_end = NULL; /* optional command terminator */
+ sparclet_cmds.target = &sparclet_ops; /* target operations */
+ sparclet_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ sparclet_cmds.regnames = sparclet_regnames; /* registers names */
+ sparclet_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+};
+
+static void
+sparclet_open (char *args, int from_tty)
+{
+ monitor_open (args, &sparclet_cmds, from_tty);
+}
+
+void
+_initialize_sparclet (void)
+{
+ int i;
+ init_sparclet_cmds ();
+
+ for (i = 0; i < NUM_REGS; i++)
+ if (sparclet_regnames[i][0] == 'c' ||
+ sparclet_regnames[i][0] == 'a')
+ sparclet_regnames[i] = 0; /* mon can't report c* or a* regs */
+
+ sparclet_regnames[0] = 0; /* mon won't report %G0 */
+
+ init_monitor_ops (&sparclet_ops);
+ sparclet_ops.to_shortname = "sparclet"; /* for the target command */
+ sparclet_ops.to_longname = "SPARC Sparclet monitor";
+ /* use SW breaks; target only supports 2 HW breakpoints */
+ sparclet_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ sparclet_ops.to_remove_breakpoint = memory_remove_breakpoint;
+
+ sparclet_ops.to_doc =
+ "Use a board running the Sparclet debug monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+
+ sparclet_ops.to_open = sparclet_open;
+ add_target (&sparclet_ops);
+}
diff --git a/gdb/sparclet-stub.c b/gdb/sparclet-stub.c
new file mode 100644
index 00000000000..f593df7f7e3
--- /dev/null
+++ b/gdb/sparclet-stub.c
@@ -0,0 +1,1167 @@
+/****************************************************************************
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ HP offers the following for use in the public domain. HP makes no
+ warranty with regard to the software or it's performance and the
+ user accepts the software "AS IS" with all faults.
+
+ HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+ TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ * Module name: remcom.c $
+ * Revision: 1.34 $
+ * Date: 91/03/09 12:29:49 $
+ * Contributor: Lake Stevens Instrument Division$
+ *
+ * Description: low level support for gdb debugger. $
+ *
+ * Considerations: only works on target hardware $
+ *
+ * Written by: Glenn Engel $
+ * ModuleState: Experimental $
+ *
+ * NOTES: See Below $
+ *
+ * Modified for SPARC by Stu Grossman, Cygnus Support.
+ * Based on sparc-stub.c, it's modified for SPARClite Debug Unit hardware
+ * breakpoint support to create sparclite-stub.c, by Kung Hsu, Cygnus Support.
+ *
+ * This code has been extensively tested on the Fujitsu SPARClite demo board.
+ *
+ * To enable debugger support, two things need to happen. One, a
+ * call to set_debug_traps() is necessary in order to allow any breakpoints
+ * or error conditions to be properly intercepted and reported to gdb.
+ * Two, a breakpoint needs to be generated to begin communication. This
+ * is most easily accomplished by a call to breakpoint(). Breakpoint()
+ * simulates a breakpoint by executing a trap #1.
+ *
+ *************
+ *
+ * The following gdb commands are supported:
+ *
+ * command function Return value
+ *
+ * g return the value of the CPU registers hex data or ENN
+ * G set the value of the CPU registers OK or ENN
+ * P set the value of a single CPU register OK or ENN
+ *
+ * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
+ * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
+ *
+ * c Resume at current address SNN ( signal NN)
+ * cAA..AA Continue at address AA..AA SNN
+ *
+ * s Step one instruction SNN
+ * sAA..AA Step one instruction from AA..AA SNN
+ *
+ * k kill
+ *
+ * ? What was the last sigval ? SNN (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum. A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum> :: <two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer. '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host: Reply:
+ * $m0,10#2a +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <signal.h>
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+
+extern void putDebugChar(); /* write a single character */
+extern int getDebugChar(); /* read and return a single char */
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 2048
+
+static int initialized = 0; /* !0 means we've been initialized */
+static int remote_debug = 0; /* turn on verbose debugging */
+
+extern void breakinst();
+void _cprint();
+static void hw_breakpoint();
+static void set_mem_fault_trap();
+static void get_in_break_mode();
+static unsigned char *mem2hex();
+
+static const char hexchars[]="0123456789abcdef";
+
+#define NUMREGS 121
+
+static unsigned long saved_stack_pointer;
+
+/* Number of bytes of registers. */
+#define NUMREGBYTES (NUMREGS * 4)
+enum regnames { G0, G1, G2, G3, G4, G5, G6, G7,
+ O0, O1, O2, O3, O4, O5, SP, O7,
+ L0, L1, L2, L3, L4, L5, L6, L7,
+ I0, I1, I2, I3, I4, I5, FP, I7,
+
+ F0, F1, F2, F3, F4, F5, F6, F7,
+ F8, F9, F10, F11, F12, F13, F14, F15,
+ F16, F17, F18, F19, F20, F21, F22, F23,
+ F24, F25, F26, F27, F28, F29, F30, F31,
+
+ Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR,
+ CCSR, CCPR, CCCRCR, CCOR, CCOBR, CCIBR, CCIR, UNUSED1,
+
+ ASR1, ASR15, ASR17, ASR18, ASR19, ASR20, ASR21, ASR22,
+ /* the following not actually implemented */
+ AWR0, AWR1, AWR2, AWR3, AWR4, AWR5, AWR6, AWR7,
+ AWR8, AWR9, AWR10, AWR11, AWR12, AWR13, AWR14, AWR15,
+ AWR16, AWR17, AWR18, AWR19, AWR20, AWR21, AWR22, AWR23,
+ AWR24, AWR25, AWR26, AWR27, AWR28, AWR29, AWR30, AWR31,
+ APSR
+};
+
+/*************************** ASSEMBLY CODE MACROS *************************/
+/* */
+
+extern void trap_low();
+
+asm("
+ .reserve trapstack, 1000 * 4, \"bss\", 8
+
+ .data
+ .align 4
+
+in_trap_handler:
+ .word 0
+
+ .text
+ .align 4
+
+! This function is called when any SPARC trap (except window overflow or
+! underflow) occurs. It makes sure that the invalid register window is still
+! available before jumping into C code. It will also restore the world if you
+! return from handle_exception.
+!
+! On entry, trap_low expects l1 and l2 to contain pc and npc respectivly.
+
+ .globl _trap_low
+_trap_low:
+ mov %psr, %l0
+ mov %wim, %l3
+
+ srl %l3, %l0, %l4 ! wim >> cwp
+ and %l4, 0xff, %l4 ! Mask off windows 28, 29
+ cmp %l4, 1
+ bne window_fine ! Branch if not in the invalid window
+ nop
+
+! Handle window overflow
+
+ mov %g1, %l4 ! Save g1, we use it to hold the wim
+ srl %l3, 1, %g1 ! Rotate wim right
+ and %g1, 0xff, %g1 ! Mask off windows 28, 29
+ tst %g1
+ bg good_wim ! Branch if new wim is non-zero
+ nop
+
+! At this point, we need to bring a 1 into the high order bit of the wim.
+! Since we don't want to make any assumptions about the number of register
+! windows, we figure it out dynamically so as to setup the wim correctly.
+
+ ! The normal way doesn't work on the sparclet as register windows
+ ! 28 and 29 are special purpose windows.
+ !not %g1 ! Fill g1 with ones
+ !mov %g1, %wim ! Fill the wim with ones
+ !nop
+ !nop
+ !nop
+ !mov %wim, %g1 ! Read back the wim
+ !inc %g1 ! Now g1 has 1 just to left of wim
+ !srl %g1, 1, %g1 ! Now put 1 at top of wim
+
+ mov 0x80, %g1 ! Hack for sparclet
+
+ ! This doesn't work on the sparclet.
+ !mov %g0, %wim ! Clear wim so that subsequent save
+ ! won't trap
+ andn %l3, 0xff, %l5 ! Clear wim but not windows 28, 29
+ mov %l5, %wim
+ nop
+ nop
+ nop
+
+good_wim:
+ save %g0, %g0, %g0 ! Slip into next window
+ mov %g1, %wim ! Install the new wim
+
+ std %l0, [%sp + 0 * 4] ! save L & I registers
+ std %l2, [%sp + 2 * 4]
+ std %l4, [%sp + 4 * 4]
+ std %l6, [%sp + 6 * 4]
+
+ std %i0, [%sp + 8 * 4]
+ std %i2, [%sp + 10 * 4]
+ std %i4, [%sp + 12 * 4]
+ std %i6, [%sp + 14 * 4]
+
+ restore ! Go back to trap window.
+ mov %l4, %g1 ! Restore %g1
+
+window_fine:
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ tst %l5
+ bg recursive_trap
+ inc %l5
+
+ set trapstack+1000*4, %sp ! Switch to trap stack
+
+recursive_trap:
+ st %l5, [%lo(in_trap_handler) + %l4]
+ sub %sp,(16+1+6+1+88)*4,%sp ! Make room for input & locals
+ ! + hidden arg + arg spill
+ ! + doubleword alignment
+ ! + registers[121]
+
+ std %g0, [%sp + (24 + 0) * 4] ! registers[Gx]
+ std %g2, [%sp + (24 + 2) * 4]
+ std %g4, [%sp + (24 + 4) * 4]
+ std %g6, [%sp + (24 + 6) * 4]
+
+ std %i0, [%sp + (24 + 8) * 4] ! registers[Ox]
+ std %i2, [%sp + (24 + 10) * 4]
+ std %i4, [%sp + (24 + 12) * 4]
+ std %i6, [%sp + (24 + 14) * 4]
+
+ ! FP regs (sparclet doesn't have fpu)
+
+ mov %y, %l4
+ mov %tbr, %l5
+ st %l4, [%sp + (24 + 64) * 4] ! Y
+ st %l0, [%sp + (24 + 65) * 4] ! PSR
+ st %l3, [%sp + (24 + 66) * 4] ! WIM
+ st %l5, [%sp + (24 + 67) * 4] ! TBR
+ st %l1, [%sp + (24 + 68) * 4] ! PC
+ st %l2, [%sp + (24 + 69) * 4] ! NPC
+ ! CPSR and FPSR not impl
+ or %l0, 0xf20, %l4
+ mov %l4, %psr ! Turn on traps, disable interrupts
+ nop
+ nop
+ nop
+
+! Save coprocessor state.
+! See SK/demo/hdlc_demo/ldc_swap_context.S.
+
+ mov %psr, %l0
+ sethi %hi(0x2000), %l5 ! EC bit in PSR
+ or %l5, %l0, %l5
+ mov %l5, %psr ! enable coprocessor
+ nop ! 3 nops after write to %psr (needed?)
+ nop
+ nop
+ crdcxt %ccsr, %l1 ! capture CCSR
+ mov 0x6, %l2
+ cwrcxt %l2, %ccsr ! set CCP state machine for CCFR
+ crdcxt %ccfr, %l2 ! capture CCOR
+ cwrcxt %l2, %ccfr ! tickle CCFR
+ crdcxt %ccfr, %l3 ! capture CCOBR
+ cwrcxt %l3, %ccfr ! tickle CCFR
+ crdcxt %ccfr, %l4 ! capture CCIBR
+ cwrcxt %l4, %ccfr ! tickle CCFR
+ crdcxt %ccfr, %l5 ! capture CCIR
+ cwrcxt %l5, %ccfr ! tickle CCFR
+ crdcxt %ccpr, %l6 ! capture CCPR
+ crdcxt %cccrcr, %l7 ! capture CCCRCR
+ st %l1, [%sp + (24 + 72) * 4] ! save CCSR
+ st %l2, [%sp + (24 + 75) * 4] ! save CCOR
+ st %l3, [%sp + (24 + 76) * 4] ! save CCOBR
+ st %l4, [%sp + (24 + 77) * 4] ! save CCIBR
+ st %l5, [%sp + (24 + 78) * 4] ! save CCIR
+ st %l6, [%sp + (24 + 73) * 4] ! save CCPR
+ st %l7, [%sp + (24 + 74) * 4] ! save CCCRCR
+ mov %l0, %psr ! restore original PSR
+ nop ! 3 nops after write to %psr (needed?)
+ nop
+ nop
+
+! End of saving coprocessor state.
+! Save asr regs
+
+! Part of this is silly -- we should not display ASR15 or ASR19 at all.
+
+ sethi %hi(0x01000000), %l6
+ st %l6, [%sp + (24 + 81) * 4] ! ASR15 == NOP
+ sethi %hi(0xdeadc0de), %l6
+ or %l6, %lo(0xdeadc0de), %l6
+ st %l6, [%sp + (24 + 84) * 4] ! ASR19 == DEADC0DE
+
+ rd %asr1, %l4
+ st %l4, [%sp + (24 + 80) * 4]
+! rd %asr15, %l4 ! must not read ASR15
+! st %l4, [%sp + (24 + 81) * 4] ! (illegal instr trap)
+ rd %asr17, %l4
+ st %l4, [%sp + (24 + 82) * 4]
+ rd %asr18, %l4
+ st %l4, [%sp + (24 + 83) * 4]
+! rd %asr19, %l4 ! must not read asr19
+! st %l4, [%sp + (24 + 84) * 4] ! (halts the CPU)
+ rd %asr20, %l4
+ st %l4, [%sp + (24 + 85) * 4]
+ rd %asr21, %l4
+ st %l4, [%sp + (24 + 86) * 4]
+ rd %asr22, %l4
+ st %l4, [%sp + (24 + 87) * 4]
+
+! End of saving asr regs
+
+ call _handle_exception
+ add %sp, 24 * 4, %o0 ! Pass address of registers
+
+! Reload all of the registers that aren't on the stack
+
+ ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx]
+ ldd [%sp + (24 + 2) * 4], %g2
+ ldd [%sp + (24 + 4) * 4], %g4
+ ldd [%sp + (24 + 6) * 4], %g6
+
+ ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox]
+ ldd [%sp + (24 + 10) * 4], %i2
+ ldd [%sp + (24 + 12) * 4], %i4
+ ldd [%sp + (24 + 14) * 4], %i6
+
+ ! FP regs (sparclet doesn't have fpu)
+
+! Update the coprocessor registers.
+! See SK/demo/hdlc_demo/ldc_swap_context.S.
+
+ mov %psr, %l0
+ sethi %hi(0x2000), %l5 ! EC bit in PSR
+ or %l5, %l0, %l5
+ mov %l5, %psr ! enable coprocessor
+ nop ! 3 nops after write to %psr (needed?)
+ nop
+ nop
+
+ mov 0x6, %l2
+ cwrcxt %l2, %ccsr ! set CCP state machine for CCFR
+
+ ld [%sp + (24 + 72) * 4], %l1 ! saved CCSR
+ ld [%sp + (24 + 75) * 4], %l2 ! saved CCOR
+ ld [%sp + (24 + 76) * 4], %l3 ! saved CCOBR
+ ld [%sp + (24 + 77) * 4], %l4 ! saved CCIBR
+ ld [%sp + (24 + 78) * 4], %l5 ! saved CCIR
+ ld [%sp + (24 + 73) * 4], %l6 ! saved CCPR
+ ld [%sp + (24 + 74) * 4], %l7 ! saved CCCRCR
+
+ cwrcxt %l2, %ccfr ! restore CCOR
+ cwrcxt %l3, %ccfr ! restore CCOBR
+ cwrcxt %l4, %ccfr ! restore CCIBR
+ cwrcxt %l5, %ccfr ! restore CCIR
+ cwrcxt %l6, %ccpr ! restore CCPR
+ cwrcxt %l7, %cccrcr ! restore CCCRCR
+ cwrcxt %l1, %ccsr ! restore CCSR
+
+ mov %l0, %psr ! restore PSR
+ nop ! 3 nops after write to %psr (needed?)
+ nop
+ nop
+
+! End of coprocessor handling stuff.
+! Update asr regs
+
+ ld [%sp + (24 + 80) * 4], %l4
+ wr %l4, %asr1
+! ld [%sp + (24 + 81) * 4], %l4 ! can't write asr15
+! wr %l4, %asr15
+ ld [%sp + (24 + 82) * 4], %l4
+ wr %l4, %asr17
+ ld [%sp + (24 + 83) * 4], %l4
+ wr %l4, %asr18
+! ld [%sp + (24 + 84) * 4], %l4 ! can't write asr19
+! wr %l4, %asr19
+! ld [%sp + (24 + 85) * 4], %l4 ! can't write asr20
+! wr %l4, %asr20
+! ld [%sp + (24 + 86) * 4], %l4 ! can't write asr21
+! wr %l4, %asr21
+ ld [%sp + (24 + 87) * 4], %l4
+ wr %l4, %asr22
+
+! End of restoring asr regs
+
+
+ ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR
+ ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC
+
+ restore ! Ensure that previous window is valid
+ save %g0, %g0, %g0 ! by causing a window_underflow trap
+
+ mov %l0, %y
+ mov %l1, %psr ! Make sure that traps are disabled
+ ! for rett
+ nop ! 3 nops after write to %psr (needed?)
+ nop
+ nop
+
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ dec %l5
+ st %l5, [%lo(in_trap_handler) + %l4]
+
+ jmpl %l2, %g0 ! Restore old PC
+ rett %l3 ! Restore old nPC
+");
+
+/* Convert ch from a hex digit to an int */
+
+static int
+hex (unsigned char ch)
+{
+ if (ch >= 'a' && ch <= 'f')
+ return ch-'a'+10;
+ if (ch >= '0' && ch <= '9')
+ return ch-'0';
+ if (ch >= 'A' && ch <= 'F')
+ return ch-'A'+10;
+ return -1;
+}
+
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+/* scan for the sequence $<data>#<checksum> */
+
+unsigned char *
+getpacket (void)
+{
+ unsigned char *buffer = &remcomInBuffer[0];
+ unsigned char checksum;
+ unsigned char xmitcsum;
+ int count;
+ char ch;
+
+ while (1)
+ {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = getDebugChar ()) != '$')
+ ;
+
+retry:
+ checksum = 0;
+ xmitcsum = -1;
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX)
+ {
+ ch = getDebugChar ();
+ if (ch == '$')
+ goto retry;
+ if (ch == '#')
+ break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+ buffer[count] = 0;
+
+ if (ch == '#')
+ {
+ ch = getDebugChar ();
+ xmitcsum = hex (ch) << 4;
+ ch = getDebugChar ();
+ xmitcsum += hex (ch);
+
+ if (checksum != xmitcsum)
+ {
+ putDebugChar ('-'); /* failed checksum */
+ }
+ else
+ {
+ putDebugChar ('+'); /* successful transfer */
+
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':')
+ {
+ putDebugChar (buffer[0]);
+ putDebugChar (buffer[1]);
+
+ return &buffer[3];
+ }
+
+ return &buffer[0];
+ }
+ }
+ }
+}
+
+/* send the packet in buffer. */
+
+static void
+putpacket (unsigned char *buffer)
+{
+ unsigned char checksum;
+ int count;
+ unsigned char ch;
+
+ /* $<packet info>#<checksum>. */
+ do
+ {
+ putDebugChar('$');
+ checksum = 0;
+ count = 0;
+
+ while (ch = buffer[count])
+ {
+ putDebugChar(ch);
+ checksum += ch;
+ count += 1;
+ }
+
+ putDebugChar('#');
+ putDebugChar(hexchars[checksum >> 4]);
+ putDebugChar(hexchars[checksum & 0xf]);
+
+ }
+ while (getDebugChar() != '+');
+}
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an
+ error. */
+static volatile int mem_err = 0;
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+ * Return a pointer to the last char put in buf (null), in case of mem fault,
+ * return 0.
+ * If MAY_FAULT is non-zero, then we will handle memory faults by returning
+ * a 0, else treat a fault like any other fault in the stub.
+ */
+
+static unsigned char *
+mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault)
+{
+ unsigned char ch;
+
+ set_mem_fault_trap(may_fault);
+
+ while (count-- > 0)
+ {
+ ch = *mem++;
+ if (mem_err)
+ return 0;
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch & 0xf];
+ }
+
+ *buf = 0;
+
+ set_mem_fault_trap(0);
+
+ return buf;
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem
+ * return a pointer to the character AFTER the last byte written */
+
+static char *
+hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
+{
+ int i;
+ unsigned char ch;
+
+ set_mem_fault_trap(may_fault);
+
+ for (i=0; i<count; i++)
+ {
+ ch = hex(*buf++) << 4;
+ ch |= hex(*buf++);
+ *mem++ = ch;
+ if (mem_err)
+ return 0;
+ }
+
+ set_mem_fault_trap(0);
+
+ return mem;
+}
+
+/* This table contains the mapping between SPARC hardware trap types, and
+ signals, which are primarily what GDB understands. It also indicates
+ which hardware traps we need to commandeer when initializing the stub. */
+
+static struct hard_trap_info
+{
+ unsigned char tt; /* Trap type code for SPARClite */
+ unsigned char signo; /* Signal that we map this trap into */
+} hard_trap_info[] = {
+ {1, SIGSEGV}, /* instruction access exception */
+ {0x3b, SIGSEGV}, /* instruction access error */
+ {2, SIGILL}, /* illegal instruction */
+ {3, SIGILL}, /* privileged instruction */
+ {4, SIGEMT}, /* fp disabled */
+ {0x24, SIGEMT}, /* cp disabled */
+ {7, SIGBUS}, /* mem address not aligned */
+ {0x29, SIGSEGV}, /* data access exception */
+ {10, SIGEMT}, /* tag overflow */
+ {128+1, SIGTRAP}, /* ta 1 - normal breakpoint instruction */
+ {0, 0} /* Must be last */
+};
+
+/* Set up exception handlers for tracing and breakpoints */
+
+void
+set_debug_traps (void)
+{
+ struct hard_trap_info *ht;
+
+ for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+ exceptionHandler(ht->tt, trap_low);
+
+ initialized = 1;
+}
+
+asm ("
+! Trap handler for memory errors. This just sets mem_err to be non-zero. It
+! assumes that %l1 is non-zero. This should be safe, as it is doubtful that
+! 0 would ever contain code that could mem fault. This routine will skip
+! past the faulting instruction after setting mem_err.
+
+ .text
+ .align 4
+
+_fltr_set_mem_err:
+ sethi %hi(_mem_err), %l0
+ st %l1, [%l0 + %lo(_mem_err)]
+ jmpl %l2, %g0
+ rett %l2+4
+");
+
+static void
+set_mem_fault_trap (int enable)
+{
+ extern void fltr_set_mem_err();
+ mem_err = 0;
+
+ if (enable)
+ exceptionHandler(0x29, fltr_set_mem_err);
+ else
+ exceptionHandler(0x29, trap_low);
+}
+
+asm ("
+ .text
+ .align 4
+
+_dummy_hw_breakpoint:
+ jmpl %l2, %g0
+ rett %l2+4
+ nop
+ nop
+");
+
+static void
+set_hw_breakpoint_trap (int enable)
+{
+ extern void dummy_hw_breakpoint();
+
+ if (enable)
+ exceptionHandler(255, dummy_hw_breakpoint);
+ else
+ exceptionHandler(255, trap_low);
+}
+
+static void
+get_in_break_mode (void)
+{
+#if 0
+ int x;
+ mesg("get_in_break_mode, sp = ");
+ phex(&x);
+#endif
+ set_hw_breakpoint_trap(1);
+
+ asm("
+ sethi %hi(0xff10), %l4
+ or %l4, %lo(0xff10), %l4
+ sta %g0, [%l4]0x1
+ nop
+ nop
+ nop
+ ");
+
+ set_hw_breakpoint_trap(0);
+}
+
+/* Convert the SPARC hardware trap type code to a unix signal number. */
+
+static int
+computeSignal (int tt)
+{
+ struct hard_trap_info *ht;
+
+ for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+ if (ht->tt == tt)
+ return ht->signo;
+
+ return SIGHUP; /* default for things we don't know about */
+}
+
+/*
+ * While we find nice hex chars, build an int.
+ * Return number of chars processed.
+ */
+
+static int
+hexToInt(char **ptr, int *intValue)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+
+ while (**ptr)
+ {
+ hexValue = hex(**ptr);
+ if (hexValue < 0)
+ break;
+
+ *intValue = (*intValue << 4) | hexValue;
+ numChars ++;
+
+ (*ptr)++;
+ }
+
+ return (numChars);
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb. It
+ * returns 1 if you should skip the instruction at the trap address, 0
+ * otherwise.
+ */
+
+static void
+handle_exception (unsigned long *registers)
+{
+ int tt; /* Trap type */
+ int sigval;
+ int addr;
+ int length;
+ char *ptr;
+ unsigned long *sp;
+ unsigned long dsr;
+
+/* First, we must force all of the windows to be spilled out */
+
+ asm("
+ ! Ugh. sparclet has broken save
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+");
+
+ if (registers[PC] == (unsigned long)breakinst)
+ {
+ registers[PC] = registers[NPC];
+ registers[NPC] += 4;
+ }
+ sp = (unsigned long *)registers[SP];
+
+ tt = (registers[TBR] >> 4) & 0xff;
+
+ /* reply to host that an exception has occurred */
+ sigval = computeSignal(tt);
+ ptr = remcomOutBuffer;
+
+ *ptr++ = 'T';
+ *ptr++ = hexchars[sigval >> 4];
+ *ptr++ = hexchars[sigval & 0xf];
+
+ *ptr++ = hexchars[PC >> 4];
+ *ptr++ = hexchars[PC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[PC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[FP >> 4];
+ *ptr++ = hexchars[FP & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[SP >> 4];
+ *ptr++ = hexchars[SP & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&sp, ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[NPC >> 4];
+ *ptr++ = hexchars[NPC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[NPC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[O7 >> 4];
+ *ptr++ = hexchars[O7 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[O7], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = 0;
+
+ putpacket(remcomOutBuffer);
+
+ while (1)
+ {
+ remcomOutBuffer[0] = 0;
+
+ ptr = getpacket();
+ switch (*ptr++)
+ {
+ case '?':
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval & 0xf];
+ remcomOutBuffer[3] = 0;
+ break;
+
+ case 'd':
+ remote_debug = !(remote_debug); /* toggle debug flag */
+ break;
+
+ case 'g': /* return the value of the CPU registers */
+ {
+ ptr = remcomOutBuffer;
+ ptr = mem2hex((char *)registers, ptr, 16 * 4, 0); /* G & O regs */
+ ptr = mem2hex(sp + 0, ptr, 16 * 4, 0); /* L & I regs */
+ memset(ptr, '0', 32 * 8); /* Floating point */
+ ptr = mem2hex((char *)&registers[Y],
+ ptr + 32 * 4 * 2,
+ 8 * 4,
+ 0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+ ptr = mem2hex((char *)&registers[CCSR],
+ ptr,
+ 8 * 4,
+ 0); /* CCSR, CCPR, CCCRCR, CCOR, CCOBR, CCIBR, CCIR */
+ ptr = mem2hex((char *)&registers[ASR1],
+ ptr,
+ 8 * 4,
+ 0); /* ASR1,ASR15,ASR17,ASR18,ASR19,ASR20,ASR21,ASR22 */
+#if 0 /* not implemented */
+ ptr = mem2hex((char *) &registers[AWR0],
+ ptr,
+ 32 * 4,
+ 0); /* Alternate Window Registers */
+#endif
+ }
+ break;
+
+ case 'G': /* set value of all the CPU registers - return OK */
+ case 'P': /* set value of one CPU register - return OK */
+ {
+ unsigned long *newsp, psr;
+
+ psr = registers[PSR];
+
+ if (ptr[-1] == 'P') /* do a single register */
+ {
+ int regno;
+
+ if (hexToInt (&ptr, &regno)
+ && *ptr++ == '=')
+ if (regno >= L0 && regno <= I7)
+ hex2mem (ptr, sp + regno - L0, 4, 0);
+ else
+ hex2mem (ptr, (char *)&registers[regno], 4, 0);
+ else
+ {
+ strcpy (remcomOutBuffer, "E01");
+ break;
+ }
+ }
+ else
+ {
+ hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */
+ hex2mem(ptr + 16 * 4 * 2, sp + 0, 16 * 4, 0); /* L & I regs */
+ hex2mem(ptr + 64 * 4 * 2, (char *)&registers[Y],
+ 8 * 4, 0); /* Y,PSR,WIM,TBR,PC,NPC,FPSR,CPSR */
+ hex2mem(ptr + 72 * 4 * 2, (char *)&registers[CCSR],
+ 8 * 4, 0); /* CCSR,CCPR,CCCRCR,CCOR,CCOBR,CCIBR,CCIR */
+ hex2mem(ptr + 80 * 4 * 2, (char *)&registers[ASR1],
+ 8 * 4, 0); /* ASR1 ... ASR22 */
+#if 0 /* not implemented */
+ hex2mem(ptr + 88 * 4 * 2, (char *)&registers[AWR0],
+ 8 * 4, 0); /* Alternate Window Registers */
+#endif
+ }
+ /* See if the stack pointer has moved. If so, then copy the saved
+ locals and ins to the new location. This keeps the window
+ overflow and underflow routines happy. */
+
+ newsp = (unsigned long *)registers[SP];
+ if (sp != newsp)
+ sp = memcpy(newsp, sp, 16 * 4);
+
+ /* Don't allow CWP to be modified. */
+
+ if (psr != registers[PSR])
+ registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
+
+ strcpy(remcomOutBuffer,"OK");
+ }
+ break;
+
+ case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ /* Try to read %x,%x. */
+
+ if (hexToInt(&ptr, &addr)
+ && *ptr++ == ','
+ && hexToInt(&ptr, &length))
+ {
+ if (mem2hex((char *)addr, remcomOutBuffer, length, 1))
+ break;
+
+ strcpy (remcomOutBuffer, "E03");
+ }
+ else
+ strcpy(remcomOutBuffer,"E01");
+ break;
+
+ case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ /* Try to read '%x,%x:'. */
+
+ if (hexToInt(&ptr, &addr)
+ && *ptr++ == ','
+ && hexToInt(&ptr, &length)
+ && *ptr++ == ':')
+ {
+ if (hex2mem(ptr, (char *)addr, length, 1))
+ strcpy(remcomOutBuffer, "OK");
+ else
+ strcpy(remcomOutBuffer, "E03");
+ }
+ else
+ strcpy(remcomOutBuffer, "E02");
+ break;
+
+ case 'c': /* cAA..AA Continue at address AA..AA(optional) */
+ /* try to read optional parameter, pc unchanged if no parm */
+
+ if (hexToInt(&ptr, &addr))
+ {
+ registers[PC] = addr;
+ registers[NPC] = addr + 4;
+ }
+
+/* Need to flush the instruction cache here, as we may have deposited a
+ breakpoint, and the icache probably has no way of knowing that a data ref to
+ some location may have changed something that is in the instruction cache.
+ */
+
+ flush_i_cache();
+ return;
+
+ /* kill the program */
+ case 'k' : /* do nothing */
+ break;
+#if 0
+ case 't': /* Test feature */
+ asm (" std %f30,[%sp]");
+ break;
+#endif
+ case 'r': /* Reset */
+ asm ("call 0
+ nop ");
+ break;
+ } /* switch */
+
+ /* reply to the request */
+ putpacket(remcomOutBuffer);
+ }
+}
+
+/* This function will generate a breakpoint exception. It is used at the
+ beginning of a program to sync up with a debugger and can be used
+ otherwise as a quick means to stop program execution and "break" into
+ the debugger. */
+
+void
+breakpoint (void)
+{
+ if (!initialized)
+ return;
+
+ asm(" .globl _breakinst
+
+ _breakinst: ta 1
+ ");
+}
+
+static void
+hw_breakpoint (void)
+{
+ asm("
+ ta 127
+ ");
+}
+
+#if 0 /* experimental and never finished, left here for reference */
+static void
+splet_temp(void)
+{
+ asm(" sub %sp,(16+1+6+1+121)*4,%sp ! Make room for input & locals
+ ! + hidden arg + arg spill
+ ! + doubleword alignment
+ ! + registers[121]
+
+! Leave a trail of breadcrumbs! (save register save area for debugging)
+ mov %sp, %l0
+ add %l0, 24*4, %l0
+ sethi %hi(_debug_registers), %l1
+ st %l0, [%lo(_debug_registers) + %l1]
+
+! Save the Alternate Register Set: (not implemented yet)
+! To save the Alternate Register set, we must:
+! 1) Save the current SP in some global location.
+! 2) Swap the register sets.
+! 3) Save the Alternate SP in the Y register
+! 4) Fetch the SP that we saved in step 1.
+! 5) Use that to save the rest of the regs (not forgetting ASP in Y)
+! 6) Restore the Alternate SP from Y
+! 7) Swap the registers back.
+
+! 1) Copy the current stack pointer to global _SAVED_STACK_POINTER:
+ sethi %hi(_saved_stack_pointer), %l0
+ st %sp, [%lo(_saved_stack_pointer) + %l0]
+
+! 2) Swap the register sets:
+ mov %psr, %l1
+ sethi %hi(0x10000), %l2
+ xor %l1, %l2, %l1
+ mov %l1, %psr
+ nop ! 3 nops after write to %psr (needed?)
+ nop
+ nop
+
+! 3) Save Alternate L0 in Y
+ wr %l0, 0, %y
+
+! 4) Load former SP into alternate SP, using L0
+ sethi %hi(_saved_stack_pointer), %l0
+ or %lo(_saved_stack_pointer), %l0, %l0
+ swap [%l0], %sp
+
+! 4.5) Restore alternate L0
+ rd %y, %l0
+
+! 5) Save the Alternate Window Registers
+ st %r0, [%sp + (24 + 88) * 4] ! AWR0
+ st %r1, [%sp + (24 + 89) * 4] ! AWR1
+ st %r2, [%sp + (24 + 90) * 4] ! AWR2
+ st %r3, [%sp + (24 + 91) * 4] ! AWR3
+ st %r4, [%sp + (24 + 92) * 4] ! AWR4
+ st %r5, [%sp + (24 + 93) * 4] ! AWR5
+ st %r6, [%sp + (24 + 94) * 4] ! AWR6
+ st %r7, [%sp + (24 + 95) * 4] ! AWR7
+ st %r8, [%sp + (24 + 96) * 4] ! AWR8
+ st %r9, [%sp + (24 + 97) * 4] ! AWR9
+ st %r10, [%sp + (24 + 98) * 4] ! AWR10
+ st %r11, [%sp + (24 + 99) * 4] ! AWR11
+ st %r12, [%sp + (24 + 100) * 4] ! AWR12
+ st %r13, [%sp + (24 + 101) * 4] ! AWR13
+! st %r14, [%sp + (24 + 102) * 4] ! AWR14 (SP)
+ st %r15, [%sp + (24 + 103) * 4] ! AWR15
+ st %r16, [%sp + (24 + 104) * 4] ! AWR16
+ st %r17, [%sp + (24 + 105) * 4] ! AWR17
+ st %r18, [%sp + (24 + 106) * 4] ! AWR18
+ st %r19, [%sp + (24 + 107) * 4] ! AWR19
+ st %r20, [%sp + (24 + 108) * 4] ! AWR20
+ st %r21, [%sp + (24 + 109) * 4] ! AWR21
+ st %r22, [%sp + (24 + 110) * 4] ! AWR22
+ st %r23, [%sp + (24 + 111) * 4] ! AWR23
+ st %r24, [%sp + (24 + 112) * 4] ! AWR24
+ st %r25, [%sp + (24 + 113) * 4] ! AWR25
+ st %r26, [%sp + (24 + 114) * 4] ! AWR26
+ st %r27, [%sp + (24 + 115) * 4] ! AWR27
+ st %r28, [%sp + (24 + 116) * 4] ! AWR28
+ st %r29, [%sp + (24 + 117) * 4] ! AWR29
+ st %r30, [%sp + (24 + 118) * 4] ! AWR30
+ st %r31, [%sp + (24 + 119) * 4] ! AWR21
+
+! Get the Alternate PSR (I hope...)
+
+ rd %psr, %l2
+ st %l2, [%sp + (24 + 120) * 4] ! APSR
+
+! Don't forget the alternate stack pointer
+
+ rd %y, %l3
+ st %l3, [%sp + (24 + 102) * 4] ! AWR14 (SP)
+
+! 6) Restore the Alternate SP (saved in Y)
+
+ rd %y, %o6
+
+
+! 7) Swap the registers back:
+
+ mov %psr, %l1
+ sethi %hi(0x10000), %l2
+ xor %l1, %l2, %l1
+ mov %l1, %psr
+ nop ! 3 nops after write to %psr (needed?)
+ nop
+ nop
+");
+}
+
+#endif
diff --git a/gdb/sparcnbsd-nat.c b/gdb/sparcnbsd-nat.c
new file mode 100644
index 00000000000..ce5d44dc6b4
--- /dev/null
+++ b/gdb/sparcnbsd-nat.c
@@ -0,0 +1,154 @@
+/* Native-dependent code for SPARC systems running NetBSD.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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 "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include "sparcnbsd-tdep.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+/* NOTE: We don't bother with any of the deferred_store nonsense; it
+ makes things a lot more complicated than they need to be. */
+
+/* Determine if PT_GETREGS fetches this register. */
+static int
+getregs_supplies (int regno)
+{
+ return (regno == PS_REGNUM
+ || regno == PC_REGNUM
+ || regno == NPC_REGNUM
+ || regno == Y_REGNUM
+ || (regno >= G0_REGNUM && regno <= G7_REGNUM)
+ || (regno >= O0_REGNUM && regno <= O7_REGNUM)
+ /* stack regs (handled by sparcnbsd_supply_reg) */
+ || (regno >= L0_REGNUM && regno <= I7_REGNUM));
+}
+
+/* Determine if PT_GETFPREGS fetches this register. */
+static int
+getfpregs_supplies (int regno)
+{
+ return ((regno >= FP0_REGNUM && regno <= (FP0_REGNUM + 31))
+ || regno == FPS_REGNUM);
+}
+
+void
+fetch_inferior_registers (int regno)
+{
+ /* We don't use deferred stores. */
+ if (deferred_stores)
+ internal_error (__FILE__, __LINE__,
+ "fetch_inferior_registers: deferred stores pending");
+
+ if (regno == -1 || getregs_supplies (regno))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ sparcnbsd_supply_reg32 ((char *) &regs, regno);
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1 || getfpregs_supplies (regno))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point registers");
+
+ sparcnbsd_supply_fpreg32 ((char *) &fpregs, regno);
+ if (regno != -1)
+ return;
+ }
+}
+
+void
+store_inferior_registers (int regno)
+{
+ /* We don't use deferred stores. */
+ if (deferred_stores)
+ internal_error (__FILE__, __LINE__,
+ "store_inferior_registers: deferred stores pending");
+
+ if (regno == -1 || getregs_supplies (regno))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ sparcnbsd_fill_reg32 ((char *) &regs, regno);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't write registers");
+
+ /* Deal with the stack regs. */
+ if (regno == -1 || regno == SP_REGNUM
+ || (regno >= L0_REGNUM && regno <= I7_REGNUM))
+ {
+ CORE_ADDR sp = read_register (SP_REGNUM);
+ int i;
+ char buf[4];
+
+ for (i = L0_REGNUM; i <= I7_REGNUM; i++)
+ {
+ if (regno == -1 || regno == SP_REGNUM || regno == i)
+ {
+ regcache_collect (i, buf);
+ target_write_memory (sp + ((i - L0_REGNUM) * 4),
+ buf, sizeof (buf));
+ }
+ }
+ }
+
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1 || getfpregs_supplies (regno))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point registers");
+
+ sparcnbsd_fill_fpreg32 ((char *) &fpregs, regno);
+
+ if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't write floating point registers");
+
+ if (regno != -1)
+ return;
+ }
+}
diff --git a/gdb/sparcnbsd-tdep.c b/gdb/sparcnbsd-tdep.c
new file mode 100644
index 00000000000..ea70e517b6d
--- /dev/null
+++ b/gdb/sparcnbsd-tdep.c
@@ -0,0 +1,531 @@
+/* Target-dependent code for SPARC systems running NetBSD.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, 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 "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "target.h"
+#include "value.h"
+#include "osabi.h"
+
+#include "sparcnbsd-tdep.h"
+#include "nbsd-tdep.h"
+
+#include "solib-svr4.h"
+
+#define REG32_OFFSET_PSR (0 * 4)
+#define REG32_OFFSET_PC (1 * 4)
+#define REG32_OFFSET_NPC (2 * 4)
+#define REG32_OFFSET_Y (3 * 4)
+#define REG32_OFFSET_GLOBAL (4 * 4)
+#define REG32_OFFSET_OUT (12 * 4)
+
+#define REG64_OFFSET_TSTATE (0 * 8)
+#define REG64_OFFSET_PC (1 * 8)
+#define REG64_OFFSET_NPC (2 * 8)
+#define REG64_OFFSET_Y (3 * 8)
+#define REG64_OFFSET_GLOBAL (4 * 8)
+#define REG64_OFFSET_OUT (12 * 8)
+
+void
+sparcnbsd_supply_reg32 (char *regs, int regno)
+{
+ int i;
+
+ if (regno == PS_REGNUM || regno == -1)
+ supply_register (PS_REGNUM, regs + REG32_OFFSET_PSR);
+
+ if (regno == PC_REGNUM || regno == -1)
+ supply_register (PC_REGNUM, regs + REG32_OFFSET_PC);
+
+ if (regno == NPC_REGNUM || regno == -1)
+ supply_register (NPC_REGNUM, regs + REG32_OFFSET_NPC);
+
+ if (regno == Y_REGNUM || regno == -1)
+ supply_register (Y_REGNUM, regs + REG32_OFFSET_Y);
+
+ if ((regno >= G0_REGNUM && regno <= G7_REGNUM) || regno == -1)
+ {
+ if (regno == G0_REGNUM || regno == -1)
+ supply_register (G0_REGNUM, NULL); /* %g0 is always zero */
+ for (i = G1_REGNUM; i <= G7_REGNUM; i++)
+ {
+ if (regno == i || regno == -1)
+ supply_register (i, regs + REG32_OFFSET_GLOBAL +
+ ((i - G0_REGNUM) * 4));
+ }
+ }
+
+ if ((regno >= O0_REGNUM && regno <= O7_REGNUM) || regno == -1)
+ {
+ for (i = O0_REGNUM; i <= O7_REGNUM; i++)
+ {
+ if (regno == i || regno == -1)
+ supply_register (i, regs + REG32_OFFSET_OUT +
+ ((i - O0_REGNUM) * 4));
+ }
+ }
+
+ /* Inputs and Locals are stored onto the stack by by the kernel. */
+ if ((regno >= L0_REGNUM && regno <= I7_REGNUM) || regno == -1)
+ {
+ CORE_ADDR sp = read_register (SP_REGNUM);
+ char buf[4];
+
+ for (i = L0_REGNUM; i <= I7_REGNUM; i++)
+ {
+ if (regno == i || regno == -1)
+ {
+ target_read_memory (sp + ((i - L0_REGNUM) * 4),
+ buf, sizeof (buf));
+ supply_register (i, buf);
+ }
+ }
+ }
+
+ /* FIXME: If we don't set these valid, read_register_bytes() rereads
+ all the regs every time it is called! */
+ if (regno == WIM_REGNUM || regno == -1)
+ supply_register (WIM_REGNUM, NULL);
+ if (regno == TBR_REGNUM || regno == -1)
+ supply_register (TBR_REGNUM, NULL);
+ if (regno == CPS_REGNUM || regno == -1)
+ supply_register (CPS_REGNUM, NULL);
+}
+
+void
+sparcnbsd_supply_reg64 (char *regs, int regno)
+{
+ int i;
+ char buf[8];
+
+ if (regno == TSTATE_REGNUM || regno == -1)
+ supply_register (PS_REGNUM, regs + REG64_OFFSET_TSTATE);
+
+ if (regno == PC_REGNUM || regno == -1)
+ supply_register (PC_REGNUM, regs + REG64_OFFSET_PC);
+
+ if (regno == NPC_REGNUM || regno == -1)
+ supply_register (NPC_REGNUM, regs + REG64_OFFSET_NPC);
+
+ if (regno == Y_REGNUM || regno == -1)
+ {
+ memset (buf, 0, sizeof (buf));
+ memcpy (&buf[4], regs + REG64_OFFSET_Y, 4);
+ supply_register (Y_REGNUM, buf);
+ }
+
+ if ((regno >= G0_REGNUM && regno <= G7_REGNUM) || regno == -1)
+ {
+ if (regno == G0_REGNUM || regno == -1)
+ supply_register (G0_REGNUM, NULL); /* %g0 is always zero */
+ for (i = G1_REGNUM; i <= G7_REGNUM; i++)
+ {
+ if (regno == i || regno == -1)
+ supply_register (i, regs + REG64_OFFSET_GLOBAL +
+ ((i - G0_REGNUM) * 8));
+ }
+ }
+
+ if ((regno >= O0_REGNUM && regno <= O7_REGNUM) || regno == -1)
+ {
+ for (i = O0_REGNUM; i <= O7_REGNUM; i++)
+ {
+ if (regno == i || regno == -1)
+ supply_register (i, regs + REG64_OFFSET_OUT +
+ ((i - O0_REGNUM) * 8));
+ }
+ }
+
+ /* Inputs and Locals are stored onto the stack by by the kernel. */
+ if ((regno >= L0_REGNUM && regno <= I7_REGNUM) || regno == -1)
+ {
+ CORE_ADDR sp = read_register (SP_REGNUM);
+ char buf[8];
+
+ if (sp & 1)
+ {
+ /* Registers are 64-bit. */
+ sp += 2047;
+
+ for (i = L0_REGNUM; i <= I7_REGNUM; i++)
+ {
+ if (regno == i || regno == -1)
+ {
+ target_read_memory (sp + ((i - L0_REGNUM) * 8),
+ buf, sizeof (buf));
+ supply_register (i, buf);
+ }
+ }
+ }
+ else
+ {
+ /* Registers are 32-bit. Toss any sign-extension of the stack
+ pointer, clear out the top half of the temporary buffer, and
+ put the register value in the bottom half. */
+
+ sp &= 0xffffffffUL;
+ memset (buf, 0, sizeof (buf));
+ for (i = L0_REGNUM; i <= I7_REGNUM; i++)
+ {
+ if (regno == i || regno == -1)
+ {
+ target_read_memory (sp + ((i - L0_REGNUM) * 4),
+ &buf[4], sizeof (buf));
+ supply_register (i, buf);
+ }
+ }
+ }
+ }
+
+ /* FIXME: If we don't set these valid, read_register_bytes() rereads
+ all the regs every time it is called! */
+ if (regno == WIM_REGNUM || regno == -1)
+ supply_register (WIM_REGNUM, NULL);
+ if (regno == TBR_REGNUM || regno == -1)
+ supply_register (TBR_REGNUM, NULL);
+ if (regno == CPS_REGNUM || regno == -1)
+ supply_register (CPS_REGNUM, NULL);
+}
+
+void
+sparcnbsd_fill_reg32 (char *regs, int regno)
+{
+ int i;
+
+ if (regno == PS_REGNUM || regno == -1)
+ regcache_collect (PS_REGNUM, regs + REG32_OFFSET_PSR);
+
+ if (regno == PC_REGNUM || regno == -1)
+ regcache_collect (PC_REGNUM, regs + REG32_OFFSET_PC);
+
+ if (regno == NPC_REGNUM || regno == -1)
+ regcache_collect (NPC_REGNUM, regs + REG32_OFFSET_NPC);
+
+ if (regno == Y_REGNUM || regno == -1)
+ regcache_collect (Y_REGNUM, regs + REG32_OFFSET_Y);
+
+ if ((regno >= G0_REGNUM && regno <= G7_REGNUM) || regno == -1)
+ {
+ /* %g0 is always zero */
+ for (i = G1_REGNUM; i <= G7_REGNUM; i++)
+ {
+ if (regno == i || regno == -1)
+ regcache_collect (i, regs + REG32_OFFSET_GLOBAL +
+ ((i - G0_REGNUM) * 4));
+ }
+ }
+
+ if ((regno >= O0_REGNUM && regno <= O7_REGNUM) || regno == -1)
+ {
+ for (i = O0_REGNUM; i <= O7_REGNUM; i++)
+ {
+ if (regno == i || regno == -1)
+ regcache_collect (i, regs + REG32_OFFSET_OUT +
+ ((i - O0_REGNUM) * 4));
+ }
+ }
+
+ /* Responsibility for the stack regs is pushed off onto the caller. */
+}
+
+void
+sparcnbsd_fill_reg64 (char *regs, int regno)
+{
+ int i;
+
+ if (regno == TSTATE_REGNUM || regno == -1)
+ regcache_collect (TSTATE_REGNUM, regs + REG64_OFFSET_TSTATE);
+
+ if (regno == PC_REGNUM || regno == -1)
+ regcache_collect (PC_REGNUM, regs + REG64_OFFSET_PC);
+
+ if (regno == NPC_REGNUM || regno == -1)
+ regcache_collect (NPC_REGNUM, regs + REG64_OFFSET_NPC);
+
+ if (regno == Y_REGNUM || regno == -1)
+ regcache_collect (Y_REGNUM, regs + REG64_OFFSET_Y);
+
+ if ((regno >= G0_REGNUM && regno <= G7_REGNUM) || regno == -1)
+ {
+ /* %g0 is always zero */
+ for (i = G1_REGNUM; i <= G7_REGNUM; i++)
+ {
+ if (regno == i || regno == -1)
+ regcache_collect (i, regs + REG64_OFFSET_GLOBAL +
+ ((i - G0_REGNUM) * 4));
+ }
+ }
+
+ if ((regno >= O0_REGNUM && regno <= O7_REGNUM) || regno == -1)
+ {
+ for (i = O0_REGNUM; i <= O7_REGNUM; i++)
+ {
+ if (regno == i || regno == -1)
+ regcache_collect (i, regs + REG64_OFFSET_OUT +
+ ((i - O0_REGNUM) * 4));
+ }
+ }
+
+ /* Responsibility for the stack regs is pushed off onto the caller. */
+}
+
+void
+sparcnbsd_supply_fpreg32 (char *fpregs, int regno)
+{
+ int i;
+
+ for (i = 0; i <= 31; i++)
+ {
+ if (regno == (FP0_REGNUM + i) || regno == -1)
+ supply_register (FP0_REGNUM + i, fpregs + (i * 4));
+ }
+
+ if (regno == FPS_REGNUM || regno == -1)
+ supply_register (FPS_REGNUM, fpregs + (32 * 4));
+}
+
+void
+sparcnbsd_supply_fpreg64 (char *fpregs, int regno)
+{
+ int i;
+
+ for (i = 0; i <= 31; i++)
+ {
+ if (regno == (FP0_REGNUM + i) || regno == -1)
+ supply_register (FP0_REGNUM + i, fpregs + (i * 4));
+ }
+
+ for (; i <= 47; i++)
+ {
+ if (regno == (FP0_REGNUM + i) || regno == -1)
+ supply_register (FP0_REGNUM + i, fpregs + (32 * 4) + (i * 8));
+ }
+
+ if (regno == FPS_REGNUM || regno == -1)
+ supply_register (FPS_REGNUM, fpregs + (32 * 4) + (16 * 8));
+
+ /* XXX %gsr */
+}
+
+void
+sparcnbsd_fill_fpreg32 (char *fpregs, int regno)
+{
+ int i;
+
+ for (i = 0; i <= 31; i++)
+ {
+ if (regno == (FP0_REGNUM + i) || regno == -1)
+ regcache_collect (FP0_REGNUM + i, fpregs + (i * 4));
+ }
+
+ if (regno == FPS_REGNUM || regno == -1)
+ regcache_collect (FPS_REGNUM, fpregs + (32 * 4));
+}
+
+void
+sparcnbsd_fill_fpreg64 (char *fpregs, int regno)
+{
+ int i;
+
+ for (i = 0; i <= 31; i++)
+ {
+ if (regno == (FP0_REGNUM + i) || regno == -1)
+ regcache_collect (FP0_REGNUM + i, fpregs + (i * 4));
+ }
+
+ for (; i <= 47; i++)
+ {
+ if (regno == (FP0_REGNUM + i) || regno == -1)
+ regcache_collect (FP0_REGNUM + i, fpregs + (32 * 4) + (i * 8));
+ }
+
+ if (regno == FPS_REGNUM || regno == -1)
+ regcache_collect (FPS_REGNUM, fpregs + (32 * 4) + (16 * 8));
+
+ /* XXX %gsr */
+}
+
+/* Unlike other NetBSD implementations, the SPARC port historically used
+ .reg and .reg2 (see bfd/netbsd-core.c), and as such, we can share one
+ routine for a.out and ELF core files. */
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR ignore)
+{
+ int reg_size, fpreg_size;
+
+ if (gdbarch_ptr_bit (current_gdbarch) == 32)
+ {
+ reg_size = (20 * 4);
+ fpreg_size = (33 * 4);
+ }
+ else
+ {
+ reg_size = (20 * 8);
+ fpreg_size = (64 * 4)
+ + 8 /* fsr */
+ + 4 /* gsr */
+ + 4; /* pad */
+ }
+
+ switch (which)
+ {
+ case 0: /* Integer registers */
+ if (core_reg_size != reg_size)
+ warning ("Wrong size register set in core file.");
+ else if (gdbarch_ptr_bit (current_gdbarch) == 32)
+ sparcnbsd_supply_reg32 (core_reg_sect, -1);
+ else
+ sparcnbsd_supply_reg64 (core_reg_sect, -1);
+ break;
+
+ case 2: /* Floating pointer registers */
+ if (core_reg_size != fpreg_size)
+ warning ("Wrong size FP register set in core file.");
+ else if (gdbarch_ptr_bit (current_gdbarch) == 32)
+ sparcnbsd_supply_fpreg32 (core_reg_sect, -1);
+ else
+ sparcnbsd_supply_fpreg64 (core_reg_sect, -1);
+ break;
+
+ default:
+ /* Don't know what kind of register request this is; just ignore it. */
+ break;
+ }
+}
+
+static struct core_fns sparcnbsd_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL
+};
+
+static struct core_fns sparcnbsd_elfcore_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL
+};
+
+/* FIXME: Need PC_IN_SIGTRAMP() support, but NetBSD/sparc signal trampolines
+ aren't easily identified. */
+
+static int
+sparcnbsd_get_longjmp_target_32 (CORE_ADDR *pc)
+{
+ CORE_ADDR jb_addr;
+ char buf[4];
+
+ jb_addr = read_register (O0_REGNUM);
+
+ if (target_read_memory (jb_addr + 12, buf, sizeof (buf)))
+ return 0;
+
+ *pc = extract_address (buf, sizeof (buf));
+
+ return 1;
+}
+
+static int
+sparcnbsd_get_longjmp_target_64 (CORE_ADDR *pc)
+{
+ CORE_ADDR jb_addr;
+ char buf[8];
+
+ jb_addr = read_register (O0_REGNUM);
+
+ if (target_read_memory (jb_addr + 16, buf, sizeof (buf)))
+ return 0;
+
+ *pc = extract_address (buf, sizeof (buf));
+
+ return 1;
+}
+
+static int
+sparcnbsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+ if (strcmp (name, "_DYNAMIC") == 0)
+ return 1;
+
+ return 0;
+}
+
+static void
+sparcnbsd_init_abi_common (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ set_gdbarch_get_longjmp_target (gdbarch, gdbarch_ptr_bit (gdbarch) == 32 ?
+ sparcnbsd_get_longjmp_target_32 :
+ sparcnbsd_get_longjmp_target_64);
+}
+
+static void
+sparcnbsd_init_abi_aout (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ sparcnbsd_init_abi_common (info, gdbarch);
+
+ set_gdbarch_in_solib_call_trampoline (gdbarch,
+ sparcnbsd_aout_in_solib_call_trampoline);
+}
+
+static void
+sparcnbsd_init_abi_elf (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ sparcnbsd_init_abi_common (info, gdbarch);
+
+ set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ gdbarch_ptr_bit (gdbarch) == 32 ?
+ nbsd_ilp32_solib_svr4_fetch_link_map_offsets :
+ nbsd_lp64_solib_svr4_fetch_link_map_offsets);
+}
+
+static enum gdb_osabi
+sparcnbsd_aout_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "a.out-sparc-netbsd") == 0)
+ return GDB_OSABI_NETBSD_AOUT;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+void
+_initialize_sparnbsd_tdep (void)
+{
+ gdbarch_register_osabi_sniffer (bfd_arch_sparc, bfd_target_aout_flavour,
+ sparcnbsd_aout_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_sparc, GDB_OSABI_NETBSD_AOUT,
+ sparcnbsd_init_abi_aout);
+ gdbarch_register_osabi (bfd_arch_sparc, GDB_OSABI_NETBSD_ELF,
+ sparcnbsd_init_abi_elf);
+
+ add_core_fns (&sparcnbsd_core_fns);
+ add_core_fns (&sparcnbsd_elfcore_fns);
+}
diff --git a/gdb/sparcnbsd-tdep.h b/gdb/sparcnbsd-tdep.h
new file mode 100644
index 00000000000..bad2d653c8e
--- /dev/null
+++ b/gdb/sparcnbsd-tdep.h
@@ -0,0 +1,34 @@
+/* Common target dependent code for GDB on SPARC systems running NetBSD.
+ Copyright 2002 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. */
+
+#ifndef SPARCNBSD_TDEP_H
+#define SPARCNBSD_TDEP_H
+
+void sparcnbsd_supply_reg32 (char *, int);
+void sparcnbsd_supply_reg64 (char *, int);
+void sparcnbsd_fill_reg32 (char *, int);
+void sparcnbsd_fill_reg64 (char *, int);
+
+void sparcnbsd_supply_fpreg32 (char *, int);
+void sparcnbsd_supply_fpreg64 (char *, int);
+void sparcnbsd_fill_fpreg32 (char *, int);
+void sparcnbsd_fill_fpreg64 (char *, int);
+
+#endif /* SPARCNBSD_TDEP_H */
diff --git a/gdb/srec.h b/gdb/srec.h
new file mode 100644
index 00000000000..d2d9876da4c
--- /dev/null
+++ b/gdb/srec.h
@@ -0,0 +1,37 @@
+/* S-record download support for GDB, the GNU debugger.
+ Copyright 1995, 1996, 2000 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. */
+
+void load_srec (struct serial *desc, const char *file, bfd_vma load_offset,
+ int maxrecsize, int flags, int hashmark,
+ int (*waitack) (void));
+
+/* S-record capability flags */
+
+/* Which record types are supported */
+#define SREC_2_BYTE_ADDR 0x00000001
+#define SREC_3_BYTE_ADDR 0x00000002
+#define SREC_4_BYTE_ADDR 0x00000004
+#define SREC_TERM_SHIFT 3
+
+#define SREC_ALL (SREC_2_BYTE_ADDR | SREC_3_BYTE_ADDR | SREC_4_BYTE_ADDR \
+ | ((SREC_2_BYTE_ADDR | SREC_3_BYTE_ADDR | SREC_4_BYTE_ADDR) \
+ << SREC_TERM_SHIFT))
+
+#define SREC_BINARY 0x00000040 /* Supports binary form of S-records */
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
new file mode 100644
index 00000000000..56b78495938
--- /dev/null
+++ b/gdb/stabsread.c
@@ -0,0 +1,5403 @@
+/* Support routines for decoding "stabs" debugging information format.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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. */
+
+/* Support routines for reading and decoding debugging information in
+ the "stabs" format. This format is used with many systems that use
+ the a.out object file format, as well as some systems that use
+ COFF or ELF where the stabs data is placed in a special section.
+ Avoid placing any object file format specific code in this file. */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "bfd.h"
+#include "obstack.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "aout/stab_gnu.h" /* We always use GNU stabs, not native */
+#include "libaout.h"
+#include "aout/aout64.h"
+#include "gdb-stabs.h"
+#include "buildsym.h"
+#include "complaints.h"
+#include "demangle.h"
+#include "language.h"
+#include "doublest.h"
+
+#include <ctype.h>
+
+/* Ask stabsread.h to define the vars it normally declares `extern'. */
+#define EXTERN
+/**/
+#include "stabsread.h" /* Our own declarations */
+#undef EXTERN
+
+extern void _initialize_stabsread (void);
+
+/* The routines that read and process a complete stabs for a C struct or
+ C++ class pass lists of data member fields and lists of member function
+ fields in an instance of a field_info structure, as defined below.
+ This is part of some reorganization of low level C++ support and is
+ expected to eventually go away... (FIXME) */
+
+struct field_info
+ {
+ struct nextfield
+ {
+ struct nextfield *next;
+
+ /* This is the raw visibility from the stab. It is not checked
+ for being one of the visibilities we recognize, so code which
+ examines this field better be able to deal. */
+ int visibility;
+
+ struct field field;
+ }
+ *list;
+ struct next_fnfieldlist
+ {
+ struct next_fnfieldlist *next;
+ struct fn_fieldlist fn_fieldlist;
+ }
+ *fnlist;
+ };
+
+static void
+read_one_struct_field (struct field_info *, char **, char *,
+ struct type *, struct objfile *);
+
+static char *get_substring (char **, int);
+
+static struct type *dbx_alloc_type (int[2], struct objfile *);
+
+static long read_huge_number (char **, int, int *);
+
+static struct type *error_type (char **, struct objfile *);
+
+static void
+patch_block_stabs (struct pending *, struct pending_stabs *,
+ struct objfile *);
+
+static void fix_common_block (struct symbol *, int);
+
+static int read_type_number (char **, int *);
+
+static struct type *read_range_type (char **, int[2], struct objfile *);
+
+static struct type *read_sun_builtin_type (char **, int[2], struct objfile *);
+
+static struct type *read_sun_floating_type (char **, int[2],
+ struct objfile *);
+
+static struct type *read_enum_type (char **, struct type *, struct objfile *);
+
+static struct type *rs6000_builtin_type (int);
+
+static int
+read_member_functions (struct field_info *, char **, struct type *,
+ struct objfile *);
+
+static int
+read_struct_fields (struct field_info *, char **, struct type *,
+ struct objfile *);
+
+static int
+read_baseclasses (struct field_info *, char **, struct type *,
+ struct objfile *);
+
+static int
+read_tilde_fields (struct field_info *, char **, struct type *,
+ struct objfile *);
+
+static int attach_fn_fields_to_type (struct field_info *, struct type *);
+
+static int
+attach_fields_to_type (struct field_info *, struct type *, struct objfile *);
+
+static struct type *read_struct_type (char **, struct type *,
+ enum type_code,
+ struct objfile *);
+
+static struct type *read_array_type (char **, struct type *,
+ struct objfile *);
+
+static struct type **read_args (char **, int, struct objfile *);
+
+static int
+read_cpp_abbrev (struct field_info *, char **, struct type *,
+ struct objfile *);
+
+/* new functions added for cfront support */
+
+static int
+copy_cfront_struct_fields (struct field_info *, struct type *,
+ struct objfile *);
+
+static char *get_cfront_method_physname (char *);
+
+static int
+read_cfront_baseclasses (struct field_info *, char **,
+ struct type *, struct objfile *);
+
+static int
+read_cfront_static_fields (struct field_info *, char **,
+ struct type *, struct objfile *);
+static int
+read_cfront_member_functions (struct field_info *, char **,
+ struct type *, struct objfile *);
+
+/* end new functions added for cfront support */
+
+static void
+add_live_range (struct objfile *, struct symbol *, CORE_ADDR, CORE_ADDR);
+
+static int resolve_live_range (struct objfile *, struct symbol *, char *);
+
+static int process_reference (char **string);
+
+static CORE_ADDR ref_search_value (int refnum);
+
+static int
+resolve_symbol_reference (struct objfile *, struct symbol *, char *);
+
+void stabsread_clear_cache (void);
+
+static const char vptr_name[] =
+{'_', 'v', 'p', 't', 'r', CPLUS_MARKER, '\0'};
+static const char vb_name[] =
+{'_', 'v', 'b', CPLUS_MARKER, '\0'};
+
+/* Define this as 1 if a pcc declaration of a char or short argument
+ gives the correct address. Otherwise assume pcc gives the
+ address of the corresponding int, which is not the same on a
+ big-endian machine. */
+
+#if !defined (BELIEVE_PCC_PROMOTION)
+#define BELIEVE_PCC_PROMOTION 0
+#endif
+#if !defined (BELIEVE_PCC_PROMOTION_TYPE)
+#define BELIEVE_PCC_PROMOTION_TYPE 0
+#endif
+
+static struct complaint invalid_cpp_abbrev_complaint =
+{"invalid C++ abbreviation `%s'", 0, 0};
+
+static struct complaint invalid_cpp_type_complaint =
+{"C++ abbreviated type name unknown at symtab pos %d", 0, 0};
+
+static struct complaint member_fn_complaint =
+{"member function type missing, got '%c'", 0, 0};
+
+static struct complaint const_vol_complaint =
+{"const/volatile indicator missing, got '%c'", 0, 0};
+
+static struct complaint error_type_complaint =
+{"couldn't parse type; debugger out of date?", 0, 0};
+
+static struct complaint invalid_member_complaint =
+{"invalid (minimal) member type data format at symtab pos %d.", 0, 0};
+
+static struct complaint range_type_base_complaint =
+{"base type %d of range type is not defined", 0, 0};
+
+static struct complaint reg_value_complaint =
+{"register number %d too large (max %d) in symbol %s", 0, 0};
+
+static struct complaint vtbl_notfound_complaint =
+{"virtual function table pointer not found when defining class `%s'", 0, 0};
+
+static struct complaint unrecognized_cplus_name_complaint =
+{"Unknown C++ symbol name `%s'", 0, 0};
+
+static struct complaint rs6000_builtin_complaint =
+{"Unknown builtin type %d", 0, 0};
+
+static struct complaint unresolved_sym_chain_complaint =
+{"%s: common block `%s' from global_sym_chain unresolved", 0, 0};
+
+static struct complaint stabs_general_complaint =
+{"%s", 0, 0};
+
+static struct complaint lrs_general_complaint =
+{"%s", 0, 0};
+
+/* Make a list of forward references which haven't been defined. */
+
+static struct type **undef_types;
+static int undef_types_allocated;
+static int undef_types_length;
+static struct symbol *current_symbol = NULL;
+
+/* Check for and handle cretinous stabs symbol name continuation! */
+#define STABS_CONTINUE(pp,objfile) \
+ do { \
+ if (**(pp) == '\\' || (**(pp) == '?' && (*(pp))[1] == '\0')) \
+ *(pp) = next_symbol_text (objfile); \
+ } while (0)
+
+/* FIXME: These probably should be our own types (like rs6000_builtin_type
+ has its own types) rather than builtin_type_*. */
+static struct type **os9k_type_vector[] =
+{
+ 0,
+ &builtin_type_int,
+ &builtin_type_char,
+ &builtin_type_long,
+ &builtin_type_short,
+ &builtin_type_unsigned_char,
+ &builtin_type_unsigned_short,
+ &builtin_type_unsigned_long,
+ &builtin_type_unsigned_int,
+ &builtin_type_float,
+ &builtin_type_double,
+ &builtin_type_void,
+ &builtin_type_long_double
+};
+
+static void os9k_init_type_vector (struct type **);
+
+static void
+os9k_init_type_vector (struct type **tv)
+{
+ unsigned int i;
+ for (i = 0; i < sizeof (os9k_type_vector) / sizeof (struct type **); i++)
+ tv[i] = (os9k_type_vector[i] == 0 ? 0 : *(os9k_type_vector[i]));
+}
+
+/* Look up a dbx type-number pair. Return the address of the slot
+ where the type for that number-pair is stored.
+ The number-pair is in TYPENUMS.
+
+ This can be used for finding the type associated with that pair
+ or for associating a new type with the pair. */
+
+struct type **
+dbx_lookup_type (int typenums[2])
+{
+ register int filenum = typenums[0];
+ register int index = typenums[1];
+ unsigned old_len;
+ register int real_filenum;
+ register struct header_file *f;
+ int f_orig_length;
+
+ if (filenum == -1) /* -1,-1 is for temporary types. */
+ return 0;
+
+ if (filenum < 0 || filenum >= n_this_object_header_files)
+ {
+ static struct complaint msg =
+ {"\
+Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.",
+ 0, 0};
+ complain (&msg, filenum, index, symnum);
+ goto error_return;
+ }
+
+ if (filenum == 0)
+ {
+ if (index < 0)
+ {
+ /* Caller wants address of address of type. We think
+ that negative (rs6k builtin) types will never appear as
+ "lvalues", (nor should they), so we stuff the real type
+ pointer into a temp, and return its address. If referenced,
+ this will do the right thing. */
+ static struct type *temp_type;
+
+ temp_type = rs6000_builtin_type (index);
+ return &temp_type;
+ }
+
+ /* Type is defined outside of header files.
+ Find it in this object file's type vector. */
+ if (index >= type_vector_length)
+ {
+ old_len = type_vector_length;
+ if (old_len == 0)
+ {
+ type_vector_length = INITIAL_TYPE_VECTOR_LENGTH;
+ type_vector = (struct type **)
+ xmalloc (type_vector_length * sizeof (struct type *));
+ }
+ while (index >= type_vector_length)
+ {
+ type_vector_length *= 2;
+ }
+ type_vector = (struct type **)
+ xrealloc ((char *) type_vector,
+ (type_vector_length * sizeof (struct type *)));
+ memset (&type_vector[old_len], 0,
+ (type_vector_length - old_len) * sizeof (struct type *));
+
+ if (os9k_stabs)
+ /* Deal with OS9000 fundamental types. */
+ os9k_init_type_vector (type_vector);
+ }
+ return (&type_vector[index]);
+ }
+ else
+ {
+ real_filenum = this_object_header_files[filenum];
+
+ if (real_filenum >= N_HEADER_FILES (current_objfile))
+ {
+ struct type *temp_type;
+ struct type **temp_type_p;
+
+ warning ("GDB internal error: bad real_filenum");
+
+ error_return:
+ temp_type = init_type (TYPE_CODE_ERROR, 0, 0, NULL, NULL);
+ temp_type_p = (struct type **) xmalloc (sizeof (struct type *));
+ *temp_type_p = temp_type;
+ return temp_type_p;
+ }
+
+ f = HEADER_FILES (current_objfile) + real_filenum;
+
+ f_orig_length = f->length;
+ if (index >= f_orig_length)
+ {
+ while (index >= f->length)
+ {
+ f->length *= 2;
+ }
+ f->vector = (struct type **)
+ xrealloc ((char *) f->vector, f->length * sizeof (struct type *));
+ memset (&f->vector[f_orig_length], 0,
+ (f->length - f_orig_length) * sizeof (struct type *));
+ }
+ return (&f->vector[index]);
+ }
+}
+
+/* Make sure there is a type allocated for type numbers TYPENUMS
+ and return the type object.
+ This can create an empty (zeroed) type object.
+ TYPENUMS may be (-1, -1) to return a new type object that is not
+ put into the type vector, and so may not be referred to by number. */
+
+static struct type *
+dbx_alloc_type (int typenums[2], struct objfile *objfile)
+{
+ register struct type **type_addr;
+
+ if (typenums[0] == -1)
+ {
+ return (alloc_type (objfile));
+ }
+
+ type_addr = dbx_lookup_type (typenums);
+
+ /* If we are referring to a type not known at all yet,
+ allocate an empty type for it.
+ We will fill it in later if we find out how. */
+ if (*type_addr == 0)
+ {
+ *type_addr = alloc_type (objfile);
+ }
+
+ return (*type_addr);
+}
+
+/* for all the stabs in a given stab vector, build appropriate types
+ and fix their symbols in given symbol vector. */
+
+static void
+patch_block_stabs (struct pending *symbols, struct pending_stabs *stabs,
+ struct objfile *objfile)
+{
+ int ii;
+ char *name;
+ char *pp;
+ struct symbol *sym;
+
+ if (stabs)
+ {
+
+ /* for all the stab entries, find their corresponding symbols and
+ patch their types! */
+
+ for (ii = 0; ii < stabs->count; ++ii)
+ {
+ name = stabs->stab[ii];
+ pp = (char *) strchr (name, ':');
+ while (pp[1] == ':')
+ {
+ pp += 2;
+ pp = (char *) strchr (pp, ':');
+ }
+ sym = find_symbol_in_list (symbols, name, pp - name);
+ if (!sym)
+ {
+ /* FIXME-maybe: it would be nice if we noticed whether
+ the variable was defined *anywhere*, not just whether
+ it is defined in this compilation unit. But neither
+ xlc or GCC seem to need such a definition, and until
+ we do psymtabs (so that the minimal symbols from all
+ compilation units are available now), I'm not sure
+ how to get the information. */
+
+ /* On xcoff, if a global is defined and never referenced,
+ ld will remove it from the executable. There is then
+ a N_GSYM stab for it, but no regular (C_EXT) symbol. */
+ sym = (struct symbol *)
+ obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+ SYMBOL_NAME (sym) =
+ obsavestring (name, pp - name, &objfile->symbol_obstack);
+ pp += 2;
+ if (*(pp - 1) == 'F' || *(pp - 1) == 'f')
+ {
+ /* I don't think the linker does this with functions,
+ so as far as I know this is never executed.
+ But it doesn't hurt to check. */
+ SYMBOL_TYPE (sym) =
+ lookup_function_type (read_type (&pp, objfile));
+ }
+ else
+ {
+ SYMBOL_TYPE (sym) = read_type (&pp, objfile);
+ }
+ add_symbol_to_list (sym, &global_symbols);
+ }
+ else
+ {
+ pp += 2;
+ if (*(pp - 1) == 'F' || *(pp - 1) == 'f')
+ {
+ SYMBOL_TYPE (sym) =
+ lookup_function_type (read_type (&pp, objfile));
+ }
+ else
+ {
+ SYMBOL_TYPE (sym) = read_type (&pp, objfile);
+ }
+ }
+ }
+ }
+}
+
+
+/* Read a number by which a type is referred to in dbx data,
+ or perhaps read a pair (FILENUM, TYPENUM) in parentheses.
+ Just a single number N is equivalent to (0,N).
+ Return the two numbers by storing them in the vector TYPENUMS.
+ TYPENUMS will then be used as an argument to dbx_lookup_type.
+
+ Returns 0 for success, -1 for error. */
+
+static int
+read_type_number (register char **pp, register int *typenums)
+{
+ int nbits;
+ if (**pp == '(')
+ {
+ (*pp)++;
+ typenums[0] = read_huge_number (pp, ',', &nbits);
+ if (nbits != 0)
+ return -1;
+ typenums[1] = read_huge_number (pp, ')', &nbits);
+ if (nbits != 0)
+ return -1;
+ }
+ else
+ {
+ typenums[0] = 0;
+ typenums[1] = read_huge_number (pp, 0, &nbits);
+ if (nbits != 0)
+ return -1;
+ }
+ return 0;
+}
+
+
+#define VISIBILITY_PRIVATE '0' /* Stabs character for private field */
+#define VISIBILITY_PROTECTED '1' /* Stabs character for protected fld */
+#define VISIBILITY_PUBLIC '2' /* Stabs character for public field */
+#define VISIBILITY_IGNORE '9' /* Optimized out or zero length */
+
+#define CFRONT_VISIBILITY_PRIVATE '2' /* Stabs character for private field */
+#define CFRONT_VISIBILITY_PUBLIC '1' /* Stabs character for public field */
+
+/* This code added to support parsing of ARM/Cfront stabs strings */
+
+/* Get substring from string up to char c, advance string pointer past
+ suibstring. */
+
+static char *
+get_substring (char **p, int c)
+{
+ char *str;
+ str = *p;
+ *p = strchr (*p, c);
+ if (*p)
+ {
+ **p = 0;
+ (*p)++;
+ }
+ else
+ str = 0;
+ return str;
+}
+
+/* Physname gets strcat'd onto sname in order to recreate the mangled
+ name (see funtion gdb_mangle_name in gdbtypes.c). For cfront, make
+ the physname look like that of g++ - take out the initial mangling
+ eg: for sname="a" and fname="foo__1aFPFs_i" return "FPFs_i" */
+
+static char *
+get_cfront_method_physname (char *fname)
+{
+ int len = 0;
+ /* FIXME would like to make this generic for g++ too, but
+ that is already handled in read_member_funcctions */
+ char *p = fname;
+
+ /* search ahead to find the start of the mangled suffix */
+ if (*p == '_' && *(p + 1) == '_') /* compiler generated; probably a ctor/dtor */
+ p += 2;
+ while (p && (unsigned) ((p + 1) - fname) < strlen (fname) && *(p + 1) != '_')
+ p = strchr (p, '_');
+ if (!(p && *p == '_' && *(p + 1) == '_'))
+ error ("Invalid mangled function name %s", fname);
+ p += 2; /* advance past '__' */
+
+ /* struct name length and name of type should come next; advance past it */
+ while (isdigit (*p))
+ {
+ len = len * 10 + (*p - '0');
+ p++;
+ }
+ p += len;
+
+ return p;
+}
+
+/* Read base classes within cfront class definition.
+ eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;;
+ ^^^^^^^^^^^^^^^^^^
+
+ A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;;
+ ^
+ */
+
+static int
+read_cfront_baseclasses (struct field_info *fip, char **pp, struct type *type,
+ struct objfile *objfile)
+{
+ static struct complaint msg_unknown =
+ {"\
+ Unsupported token in stabs string %s.\n",
+ 0, 0};
+ static struct complaint msg_notfound =
+ {"\
+ Unable to find base type for %s.\n",
+ 0, 0};
+ int bnum = 0;
+ char *p;
+ int i;
+ struct nextfield *new;
+
+ if (**pp == ';') /* no base classes; return */
+ {
+ ++(*pp);
+ return 1;
+ }
+
+ /* first count base classes so we can allocate space before parsing */
+ for (p = *pp; p && *p && *p != ';'; p++)
+ {
+ if (*p == ' ')
+ bnum++;
+ }
+ bnum++; /* add one more for last one */
+
+ /* now parse the base classes until we get to the start of the methods
+ (code extracted and munged from read_baseclasses) */
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ TYPE_N_BASECLASSES (type) = bnum;
+
+ /* allocate space */
+ {
+ int num_bytes = B_BYTES (TYPE_N_BASECLASSES (type));
+ char *pointer;
+
+ pointer = (char *) TYPE_ALLOC (type, num_bytes);
+ TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer;
+ }
+ B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type));
+
+ for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
+ {
+ new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+ make_cleanup (xfree, new);
+ memset (new, 0, sizeof (struct nextfield));
+ new->next = fip->list;
+ fip->list = new;
+ FIELD_BITSIZE (new->field) = 0; /* this should be an unpacked field! */
+
+ STABS_CONTINUE (pp, objfile);
+
+ /* virtual? eg: v2@Bvir */
+ if (**pp == 'v')
+ {
+ SET_TYPE_FIELD_VIRTUAL (type, i);
+ ++(*pp);
+ }
+
+ /* access? eg: 2@Bvir */
+ /* Note: protected inheritance not supported in cfront */
+ switch (*(*pp)++)
+ {
+ case CFRONT_VISIBILITY_PRIVATE:
+ new->visibility = VISIBILITY_PRIVATE;
+ break;
+ case CFRONT_VISIBILITY_PUBLIC:
+ new->visibility = VISIBILITY_PUBLIC;
+ break;
+ default:
+ /* Bad visibility format. Complain and treat it as
+ public. */
+ {
+ static struct complaint msg =
+ {
+ "Unknown visibility `%c' for baseclass", 0, 0};
+ complain (&msg, new->visibility);
+ new->visibility = VISIBILITY_PUBLIC;
+ }
+ }
+
+ /* "@" comes next - eg: @Bvir */
+ if (**pp != '@')
+ {
+ complain (&msg_unknown, *pp);
+ return 1;
+ }
+ ++(*pp);
+
+
+ /* Set the bit offset of the portion of the object corresponding
+ to this baseclass. Always zero in the absence of
+ multiple inheritance. */
+ /* Unable to read bit position from stabs;
+ Assuming no multiple inheritance for now FIXME! */
+ /* We may have read this in the structure definition;
+ now we should fixup the members to be the actual base classes */
+ FIELD_BITPOS (new->field) = 0;
+
+ /* Get the base class name and type */
+ {
+ char *bname; /* base class name */
+ struct symbol *bsym; /* base class */
+ char *p1, *p2;
+ p1 = strchr (*pp, ' ');
+ p2 = strchr (*pp, ';');
+ if (p1 < p2)
+ bname = get_substring (pp, ' ');
+ else
+ bname = get_substring (pp, ';');
+ if (!bname || !*bname)
+ {
+ complain (&msg_unknown, *pp);
+ return 1;
+ }
+ /* FIXME! attach base info to type */
+ bsym = lookup_symbol (bname, 0, STRUCT_NAMESPACE, 0, 0); /*demangled_name */
+ if (bsym)
+ {
+ new->field.type = SYMBOL_TYPE (bsym);
+ new->field.name = type_name_no_tag (new->field.type);
+ }
+ else
+ {
+ complain (&msg_notfound, *pp);
+ return 1;
+ }
+ }
+
+ /* If more base classes to parse, loop again.
+ We ate the last ' ' or ';' in get_substring,
+ so on exit we will have skipped the trailing ';' */
+ /* if invalid, return 0; add code to detect - FIXME! */
+ }
+ return 1;
+}
+
+/* read cfront member functions.
+ pp points to string starting with list of functions
+ eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;;
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ */
+
+static int
+read_cfront_member_functions (struct field_info *fip, char **pp,
+ struct type *type, struct objfile *objfile)
+{
+ /* This code extracted from read_member_functions
+ so as to do the similar thing for our funcs */
+
+ int nfn_fields = 0;
+ int length = 0;
+ /* Total number of member functions defined in this class. If the class
+ defines two `f' functions, and one `g' function, then this will have
+ the value 3. */
+ int total_length = 0;
+ int i;
+ struct next_fnfield
+ {
+ struct next_fnfield *next;
+ struct fn_field fn_field;
+ }
+ *sublist;
+ struct type *look_ahead_type;
+ struct next_fnfieldlist *new_fnlist;
+ struct next_fnfield *new_sublist;
+ char *main_fn_name;
+ char *fname;
+ struct symbol *ref_func = 0;
+
+ /* Process each list until we find the end of the member functions.
+ eg: p = "__ct__1AFv foo__1AFv ;;;" */
+
+ STABS_CONTINUE (pp, objfile); /* handle \\ */
+
+ while (**pp != ';' && (fname = get_substring (pp, ' '), fname))
+ {
+ int is_static = 0;
+ int sublist_count = 0;
+ char *pname;
+ if (fname[0] == '*') /* static member */
+ {
+ is_static = 1;
+ sublist_count++;
+ fname++;
+ }
+ ref_func = lookup_symbol (fname, 0, VAR_NAMESPACE, 0, 0); /* demangled name */
+ if (!ref_func)
+ {
+ static struct complaint msg =
+ {"\
+ Unable to find function symbol for %s\n",
+ 0, 0};
+ complain (&msg, fname);
+ continue;
+ }
+ sublist = NULL;
+ look_ahead_type = NULL;
+ length = 0;
+
+ new_fnlist = (struct next_fnfieldlist *)
+ xmalloc (sizeof (struct next_fnfieldlist));
+ make_cleanup (xfree, new_fnlist);
+ memset (new_fnlist, 0, sizeof (struct next_fnfieldlist));
+
+ /* The following is code to work around cfront generated stabs.
+ The stabs contains full mangled name for each field.
+ We try to demangle the name and extract the field name out of it. */
+ {
+ char *dem, *dem_p, *dem_args;
+ int dem_len;
+ dem = cplus_demangle (fname, DMGL_ANSI | DMGL_PARAMS);
+ if (dem != NULL)
+ {
+ dem_p = strrchr (dem, ':');
+ if (dem_p != 0 && *(dem_p - 1) == ':')
+ dem_p++;
+ /* get rid of args */
+ dem_args = strchr (dem_p, '(');
+ if (dem_args == NULL)
+ dem_len = strlen (dem_p);
+ else
+ dem_len = dem_args - dem_p;
+ main_fn_name =
+ obsavestring (dem_p, dem_len, &objfile->type_obstack);
+ }
+ else
+ {
+ main_fn_name =
+ obsavestring (fname, strlen (fname), &objfile->type_obstack);
+ }
+ } /* end of code for cfront work around */
+
+ new_fnlist->fn_fieldlist.name = main_fn_name;
+
+/*-------------------------------------------------*/
+ /* Set up the sublists
+ Sublists are stuff like args, static, visibility, etc.
+ so in ARM, we have to set that info some other way.
+ Multiple sublists happen if overloading
+ eg: foo::26=##1;:;2A.;
+ In g++, we'd loop here thru all the sublists... */
+
+ new_sublist =
+ (struct next_fnfield *) xmalloc (sizeof (struct next_fnfield));
+ make_cleanup (xfree, new_sublist);
+ memset (new_sublist, 0, sizeof (struct next_fnfield));
+
+ /* eat 1; from :;2A.; */
+ new_sublist->fn_field.type = SYMBOL_TYPE (ref_func); /* normally takes a read_type */
+ /* Make this type look like a method stub for gdb */
+ TYPE_FLAGS (new_sublist->fn_field.type) |= TYPE_FLAG_STUB;
+ TYPE_CODE (new_sublist->fn_field.type) = TYPE_CODE_METHOD;
+
+ /* If this is just a stub, then we don't have the real name here. */
+ if (TYPE_STUB (new_sublist->fn_field.type))
+ {
+ if (!TYPE_DOMAIN_TYPE (new_sublist->fn_field.type))
+ TYPE_DOMAIN_TYPE (new_sublist->fn_field.type) = type;
+ new_sublist->fn_field.is_stub = 1;
+ }
+
+ /* physname used later in mangling; eg PFs_i,5 for foo__1aFPFs_i
+ physname gets strcat'd in order to recreate the onto mangled name */
+ pname = get_cfront_method_physname (fname);
+ new_sublist->fn_field.physname = savestring (pname, strlen (pname));
+
+
+ /* Set this member function's visibility fields.
+ Unable to distinguish access from stabs definition!
+ Assuming public for now. FIXME!
+ (for private, set new_sublist->fn_field.is_private = 1,
+ for public, set new_sublist->fn_field.is_protected = 1) */
+
+ /* Unable to distinguish const/volatile from stabs definition!
+ Assuming normal for now. FIXME! */
+
+ new_sublist->fn_field.is_const = 0;
+ new_sublist->fn_field.is_volatile = 0; /* volatile not implemented in cfront */
+
+ /* Set virtual/static function info
+ How to get vtable offsets ?
+ Assuming normal for now FIXME!!
+ For vtables, figure out from whence this virtual function came.
+ It may belong to virtual function table of
+ one of its baseclasses.
+ set:
+ new_sublist -> fn_field.voffset = vtable offset,
+ new_sublist -> fn_field.fcontext = look_ahead_type;
+ where look_ahead_type is type of baseclass */
+ if (is_static)
+ new_sublist->fn_field.voffset = VOFFSET_STATIC;
+ else /* normal member function. */
+ new_sublist->fn_field.voffset = 0;
+ new_sublist->fn_field.fcontext = 0;
+
+
+ /* Prepare new sublist */
+ new_sublist->next = sublist;
+ sublist = new_sublist;
+ length++;
+
+ /* In g++, we loop thu sublists - now we set from functions. */
+ new_fnlist->fn_fieldlist.fn_fields = (struct fn_field *)
+ obstack_alloc (&objfile->type_obstack,
+ sizeof (struct fn_field) * length);
+ memset (new_fnlist->fn_fieldlist.fn_fields, 0,
+ sizeof (struct fn_field) * length);
+ for (i = length; (i--, sublist); sublist = sublist->next)
+ {
+ new_fnlist->fn_fieldlist.fn_fields[i] = sublist->fn_field;
+ }
+
+ new_fnlist->fn_fieldlist.length = length;
+ new_fnlist->next = fip->fnlist;
+ fip->fnlist = new_fnlist;
+ nfn_fields++;
+ total_length += length;
+ STABS_CONTINUE (pp, objfile); /* handle \\ */
+ } /* end of loop */
+
+ if (nfn_fields)
+ {
+ /* type should already have space */
+ TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
+ TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * nfn_fields);
+ memset (TYPE_FN_FIELDLISTS (type), 0,
+ sizeof (struct fn_fieldlist) * nfn_fields);
+ TYPE_NFN_FIELDS (type) = nfn_fields;
+ TYPE_NFN_FIELDS_TOTAL (type) = total_length;
+ }
+
+ /* end of scope for reading member func */
+
+ /* eg: ";;" */
+
+ /* Skip trailing ';' and bump count of number of fields seen */
+ if (**pp == ';')
+ (*pp)++;
+ else
+ return 0;
+ return 1;
+}
+
+/* This routine fixes up partial cfront types that were created
+ while parsing the stabs. The main need for this function is
+ to add information such as methods to classes.
+ Examples of "p": "sA;;__ct__1AFv foo__1AFv ;;;" */
+int
+resolve_cfront_continuation (struct objfile *objfile, struct symbol *sym,
+ char *p)
+{
+ struct symbol *ref_sym = 0;
+ char *sname;
+ /* snarfed from read_struct_type */
+ struct field_info fi;
+ struct type *type;
+ struct cleanup *back_to;
+
+ /* Need to make sure that fi isn't gunna conflict with struct
+ in case struct already had some fnfs */
+ fi.list = NULL;
+ fi.fnlist = NULL;
+ back_to = make_cleanup (null_cleanup, 0);
+
+ /* We only accept structs, classes and unions at the moment.
+ Other continuation types include t (typedef), r (long dbl), ...
+ We may want to add support for them as well;
+ right now they are handled by duplicating the symbol information
+ into the type information (see define_symbol) */
+ if (*p != 's' /* structs */
+ && *p != 'c' /* class */
+ && *p != 'u') /* union */
+ return 0; /* only handle C++ types */
+ p++;
+
+ /* Get symbol typs name and validate
+ eg: p = "A;;__ct__1AFv foo__1AFv ;;;" */
+ sname = get_substring (&p, ';');
+ if (!sname || strcmp (sname, SYMBOL_NAME (sym)))
+ error ("Internal error: base symbol type name does not match\n");
+
+ /* Find symbol's internal gdb reference using demangled_name.
+ This is the real sym that we want;
+ sym was a temp hack to make debugger happy */
+ ref_sym = lookup_symbol (SYMBOL_NAME (sym), 0, STRUCT_NAMESPACE, 0, 0);
+ type = SYMBOL_TYPE (ref_sym);
+
+
+ /* Now read the baseclasses, if any, read the regular C struct or C++
+ class member fields, attach the fields to the type, read the C++
+ member functions, attach them to the type, and then read any tilde
+ field (baseclass specifier for the class holding the main vtable). */
+
+ if (!read_cfront_baseclasses (&fi, &p, type, objfile)
+ /* g++ does this next, but cfront already did this:
+ || !read_struct_fields (&fi, &p, type, objfile) */
+ || !copy_cfront_struct_fields (&fi, type, objfile)
+ || !read_cfront_member_functions (&fi, &p, type, objfile)
+ || !read_cfront_static_fields (&fi, &p, type, objfile)
+ || !attach_fields_to_type (&fi, type, objfile)
+ || !attach_fn_fields_to_type (&fi, type)
+ /* g++ does this next, but cfront doesn't seem to have this:
+ || !read_tilde_fields (&fi, &p, type, objfile) */
+ )
+ {
+ type = error_type (&p, objfile);
+ }
+
+ do_cleanups (back_to);
+ return 0;
+}
+/* End of code added to support parsing of ARM/Cfront stabs strings */
+
+
+/* This routine fixes up symbol references/aliases to point to the original
+ symbol definition. Returns 0 on failure, non-zero on success. */
+
+static int
+resolve_symbol_reference (struct objfile *objfile, struct symbol *sym, char *p)
+{
+ int refnum;
+ struct symbol *ref_sym = 0;
+ struct alias_list *alias;
+
+ /* If this is not a symbol reference return now. */
+ if (*p != '#')
+ return 0;
+
+ /* Use "#<num>" as the name; we'll fix the name later.
+ We stored the original symbol name as "#<id>=<name>"
+ so we can now search for "#<id>" to resolving the reference.
+ We'll fix the names later by removing the "#<id>" or "#<id>=" */
+
+/*---------------------------------------------------------*/
+ /* Get the reference id number, and
+ advance p past the names so we can parse the rest.
+ eg: id=2 for p : "2=", "2=z:r(0,1)" "2:r(0,1);l(#5,#6),l(#7,#4)" */
+/*---------------------------------------------------------*/
+
+ /* This gets reference name from string. sym may not have a name. */
+
+ /* Get the reference number associated with the reference id in the
+ gdb stab string. From that reference number, get the main/primary
+ symbol for this alias. */
+ refnum = process_reference (&p);
+ ref_sym = ref_search (refnum);
+ if (!ref_sym)
+ {
+ complain (&lrs_general_complaint, "symbol for reference not found");
+ return 0;
+ }
+
+ /* Parse the stab of the referencing symbol
+ now that we have the referenced symbol.
+ Add it as a new symbol and a link back to the referenced symbol.
+ eg: p : "=", "=z:r(0,1)" ":r(0,1);l(#5,#6),l(#7,#4)" */
+
+
+ /* If the stab symbol table and string contain:
+ RSYM 0 5 00000000 868 #15=z:r(0,1)
+ LBRAC 0 0 00000000 899 #5=
+ SLINE 0 16 00000003 923 #6=
+ Then the same symbols can be later referenced by:
+ RSYM 0 5 00000000 927 #15:r(0,1);l(#5,#6)
+ This is used in live range splitting to:
+ 1) specify that a symbol (#15) is actually just a new storage
+ class for a symbol (#15=z) which was previously defined.
+ 2) specify that the beginning and ending ranges for a symbol
+ (#15) are the values of the beginning (#5) and ending (#6)
+ symbols. */
+
+ /* Read number as reference id.
+ eg: p : "=", "=z:r(0,1)" ":r(0,1);l(#5,#6),l(#7,#4)" */
+ /* FIXME! Might I want to use SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+ in case of "l(0,0)"? */
+
+/*--------------------------------------------------*/
+ /* Add this symbol to the reference list. */
+/*--------------------------------------------------*/
+
+ alias = (struct alias_list *) obstack_alloc (&objfile->type_obstack,
+ sizeof (struct alias_list));
+ if (!alias)
+ {
+ complain (&lrs_general_complaint, "Unable to allocate alias list memory");
+ return 0;
+ }
+
+ alias->next = 0;
+ alias->sym = sym;
+
+ if (!SYMBOL_ALIASES (ref_sym))
+ {
+ SYMBOL_ALIASES (ref_sym) = alias;
+ }
+ else
+ {
+ struct alias_list *temp;
+
+ /* Get to the end of the list. */
+ for (temp = SYMBOL_ALIASES (ref_sym);
+ temp->next;
+ temp = temp->next)
+ ;
+ temp->next = alias;
+ }
+
+ /* Want to fix up name so that other functions (eg. valops)
+ will correctly print the name.
+ Don't add_symbol_to_list so that lookup_symbol won't find it.
+ nope... needed for fixups. */
+ SYMBOL_NAME (sym) = SYMBOL_NAME (ref_sym);
+
+ /* Done! */
+ return 1;
+}
+
+/* Structure for storing pointers to reference definitions for fast lookup
+ during "process_later". */
+
+struct ref_map
+{
+ char *stabs;
+ CORE_ADDR value;
+ struct symbol *sym;
+};
+
+#define MAX_CHUNK_REFS 100
+#define REF_CHUNK_SIZE (MAX_CHUNK_REFS * sizeof (struct ref_map))
+#define REF_MAP_SIZE(ref_chunk) ((ref_chunk) * REF_CHUNK_SIZE)
+
+static struct ref_map *ref_map;
+
+/* Ptr to free cell in chunk's linked list. */
+static int ref_count = 0;
+
+/* Number of chunks malloced. */
+static int ref_chunk = 0;
+
+/* This file maintains a cache of stabs aliases found in the symbol
+ table. If the symbol table changes, this cache must be cleared
+ or we are left holding onto data in invalid obstacks. */
+void
+stabsread_clear_cache (void)
+{
+ ref_count = 0;
+ ref_chunk = 0;
+}
+
+/* Create array of pointers mapping refids to symbols and stab strings.
+ Add pointers to reference definition symbols and/or their values as we
+ find them, using their reference numbers as our index.
+ These will be used later when we resolve references. */
+void
+ref_add (int refnum, struct symbol *sym, char *stabs, CORE_ADDR value)
+{
+ if (ref_count == 0)
+ ref_chunk = 0;
+ if (refnum >= ref_count)
+ ref_count = refnum + 1;
+ if (ref_count > ref_chunk * MAX_CHUNK_REFS)
+ {
+ int new_slots = ref_count - ref_chunk * MAX_CHUNK_REFS;
+ int new_chunks = new_slots / MAX_CHUNK_REFS + 1;
+ ref_map = (struct ref_map *)
+ xrealloc (ref_map, REF_MAP_SIZE (ref_chunk + new_chunks));
+ memset (ref_map + ref_chunk * MAX_CHUNK_REFS, 0, new_chunks * REF_CHUNK_SIZE);
+ ref_chunk += new_chunks;
+ }
+ ref_map[refnum].stabs = stabs;
+ ref_map[refnum].sym = sym;
+ ref_map[refnum].value = value;
+}
+
+/* Return defined sym for the reference REFNUM. */
+struct symbol *
+ref_search (int refnum)
+{
+ if (refnum < 0 || refnum > ref_count)
+ return 0;
+ return ref_map[refnum].sym;
+}
+
+/* Return value for the reference REFNUM. */
+
+static CORE_ADDR
+ref_search_value (int refnum)
+{
+ if (refnum < 0 || refnum > ref_count)
+ return 0;
+ return ref_map[refnum].value;
+}
+
+/* Parse a reference id in STRING and return the resulting
+ reference number. Move STRING beyond the reference id. */
+
+static int
+process_reference (char **string)
+{
+ char *p;
+ int refnum = 0;
+
+ if (**string != '#')
+ return 0;
+
+ /* Advance beyond the initial '#'. */
+ p = *string + 1;
+
+ /* Read number as reference id. */
+ while (*p && isdigit (*p))
+ {
+ refnum = refnum * 10 + *p - '0';
+ p++;
+ }
+ *string = p;
+ return refnum;
+}
+
+/* If STRING defines a reference, store away a pointer to the reference
+ definition for later use. Return the reference number. */
+
+int
+symbol_reference_defined (char **string)
+{
+ char *p = *string;
+ int refnum = 0;
+
+ refnum = process_reference (&p);
+
+ /* Defining symbols end in '=' */
+ if (*p == '=')
+ {
+ /* Symbol is being defined here. */
+ *string = p + 1;
+ return refnum;
+ }
+ else
+ {
+ /* Must be a reference. Either the symbol has already been defined,
+ or this is a forward reference to it. */
+ *string = p;
+ return -1;
+ }
+}
+
+/* ARGSUSED */
+struct symbol *
+define_symbol (CORE_ADDR valu, char *string, int desc, int type,
+ struct objfile *objfile)
+{
+ register struct symbol *sym;
+ char *p = (char *) strchr (string, ':');
+ int deftype;
+ int synonym = 0;
+ register int i;
+
+ /* We would like to eliminate nameless symbols, but keep their types.
+ E.g. stab entry ":t10=*2" should produce a type 10, which is a pointer
+ to type 2, but, should not create a symbol to address that type. Since
+ the symbol will be nameless, there is no way any user can refer to it. */
+
+ int nameless;
+
+ /* Ignore syms with empty names. */
+ if (string[0] == 0)
+ return 0;
+
+ /* Ignore old-style symbols from cc -go */
+ if (p == 0)
+ return 0;
+
+ while (p[1] == ':')
+ {
+ p += 2;
+ p = strchr (p, ':');
+ }
+
+ /* If a nameless stab entry, all we need is the type, not the symbol.
+ e.g. ":t10=*2" or a nameless enum like " :T16=ered:0,green:1,blue:2,;" */
+ nameless = (p == string || ((string[0] == ' ') && (string[1] == ':')));
+
+ current_symbol = sym = (struct symbol *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
+
+ switch (type & N_TYPE)
+ {
+ case N_TEXT:
+ SYMBOL_SECTION (sym) = SECT_OFF_TEXT (objfile);
+ break;
+ case N_DATA:
+ SYMBOL_SECTION (sym) = SECT_OFF_DATA (objfile);
+ break;
+ case N_BSS:
+ SYMBOL_SECTION (sym) = SECT_OFF_BSS (objfile);
+ break;
+ }
+
+ if (processing_gcc_compilation)
+ {
+ /* GCC 2.x puts the line number in desc. SunOS apparently puts in the
+ number of bytes occupied by a type or object, which we ignore. */
+ SYMBOL_LINE (sym) = desc;
+ }
+ else
+ {
+ SYMBOL_LINE (sym) = 0; /* unknown */
+ }
+
+ if (is_cplus_marker (string[0]))
+ {
+ /* Special GNU C++ names. */
+ switch (string[1])
+ {
+ case 't':
+ SYMBOL_NAME (sym) = obsavestring ("this", strlen ("this"),
+ &objfile->symbol_obstack);
+ break;
+
+ case 'v': /* $vtbl_ptr_type */
+ /* Was: SYMBOL_NAME (sym) = "vptr"; */
+ goto normal;
+
+ case 'e':
+ SYMBOL_NAME (sym) = obsavestring ("eh_throw", strlen ("eh_throw"),
+ &objfile->symbol_obstack);
+ break;
+
+ case '_':
+ /* This was an anonymous type that was never fixed up. */
+ goto normal;
+
+#ifdef STATIC_TRANSFORM_NAME
+ case 'X':
+ /* SunPRO (3.0 at least) static variable encoding. */
+ goto normal;
+#endif
+
+ default:
+ complain (&unrecognized_cplus_name_complaint, string);
+ goto normal; /* Do *something* with it */
+ }
+ }
+ else if (string[0] == '#')
+ {
+ /* Special GNU C extension for referencing symbols. */
+ char *s;
+ int refnum, nlen;
+
+ /* If STRING defines a new reference id, then add it to the
+ reference map. Else it must be referring to a previously
+ defined symbol, so add it to the alias list of the previously
+ defined symbol. */
+ s = string;
+ refnum = symbol_reference_defined (&s);
+ if (refnum >= 0)
+ ref_add (refnum, sym, string, SYMBOL_VALUE (sym));
+ else if (!resolve_symbol_reference (objfile, sym, string))
+ return NULL;
+
+ /* S..P contains the name of the symbol. We need to store
+ the correct name into SYMBOL_NAME. */
+ nlen = p - s;
+ if (refnum >= 0)
+ {
+ if (nlen > 0)
+ {
+ SYMBOL_NAME (sym) = (char *)
+ obstack_alloc (&objfile->symbol_obstack, nlen);
+ strncpy (SYMBOL_NAME (sym), s, nlen);
+ SYMBOL_NAME (sym)[nlen] = '\0';
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+ }
+ else
+ /* FIXME! Want SYMBOL_NAME (sym) = 0;
+ Get error if leave name 0. So give it something. */
+ {
+ nlen = p - string;
+ SYMBOL_NAME (sym) = (char *)
+ obstack_alloc (&objfile->symbol_obstack, nlen);
+ strncpy (SYMBOL_NAME (sym), string, nlen);
+ SYMBOL_NAME (sym)[nlen] = '\0';
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+ }
+ }
+ /* Advance STRING beyond the reference id. */
+ string = s;
+ }
+ else
+ {
+ normal:
+ SYMBOL_LANGUAGE (sym) = current_subfile->language;
+ SYMBOL_NAME (sym) = (char *)
+ obstack_alloc (&objfile->symbol_obstack, ((p - string) + 1));
+ /* Open-coded memcpy--saves function call time. */
+ /* FIXME: Does it really? Try replacing with simple strcpy and
+ try it on an executable with a large symbol table. */
+ /* FIXME: considering that gcc can open code memcpy anyway, I
+ doubt it. xoxorich. */
+ {
+ register char *p1 = string;
+ register char *p2 = SYMBOL_NAME (sym);
+ while (p1 != p)
+ {
+ *p2++ = *p1++;
+ }
+ *p2++ = '\0';
+ }
+
+ /* If this symbol is from a C++ compilation, then attempt to cache the
+ demangled form for future reference. This is a typical time versus
+ space tradeoff, that was decided in favor of time because it sped up
+ C++ symbol lookups by a factor of about 20. */
+
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+ }
+ p++;
+
+ /* Determine the type of name being defined. */
+#if 0
+ /* Getting GDB to correctly skip the symbol on an undefined symbol
+ descriptor and not ever dump core is a very dodgy proposition if
+ we do things this way. I say the acorn RISC machine can just
+ fix their compiler. */
+ /* The Acorn RISC machine's compiler can put out locals that don't
+ start with "234=" or "(3,4)=", so assume anything other than the
+ deftypes we know how to handle is a local. */
+ if (!strchr ("cfFGpPrStTvVXCR", *p))
+#else
+ if (isdigit (*p) || *p == '(' || *p == '-')
+#endif
+ deftype = 'l';
+ else
+ deftype = *p++;
+
+ switch (deftype)
+ {
+ case 'c':
+ /* c is a special case, not followed by a type-number.
+ SYMBOL:c=iVALUE for an integer constant symbol.
+ SYMBOL:c=rVALUE for a floating constant symbol.
+ SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol.
+ e.g. "b:c=e6,0" for "const b = blob1"
+ (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
+ if (*p != '=')
+ {
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ SYMBOL_TYPE (sym) = error_type (&p, objfile);
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, &file_symbols);
+ return sym;
+ }
+ ++p;
+ switch (*p++)
+ {
+ case 'r':
+ {
+ double d = atof (p);
+ char *dbl_valu;
+
+ /* FIXME-if-picky-about-floating-accuracy: Should be using
+ target arithmetic to get the value. real.c in GCC
+ probably has the necessary code. */
+
+ /* FIXME: lookup_fundamental_type is a hack. We should be
+ creating a type especially for the type of float constants.
+ Problem is, what type should it be?
+
+ Also, what should the name of this type be? Should we
+ be using 'S' constants (see stabs.texinfo) instead? */
+
+ SYMBOL_TYPE (sym) = lookup_fundamental_type (objfile,
+ FT_DBL_PREC_FLOAT);
+ dbl_valu = (char *)
+ obstack_alloc (&objfile->symbol_obstack,
+ TYPE_LENGTH (SYMBOL_TYPE (sym)));
+ store_typed_floating (dbl_valu, SYMBOL_TYPE (sym), d);
+ SYMBOL_VALUE_BYTES (sym) = dbl_valu;
+ SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+ }
+ break;
+ case 'i':
+ {
+ /* Defining integer constants this way is kind of silly,
+ since 'e' constants allows the compiler to give not
+ only the value, but the type as well. C has at least
+ int, long, unsigned int, and long long as constant
+ types; other languages probably should have at least
+ unsigned as well as signed constants. */
+
+ /* We just need one int constant type for all objfiles.
+ It doesn't depend on languages or anything (arguably its
+ name should be a language-specific name for a type of
+ that size, but I'm inclined to say that if the compiler
+ wants a nice name for the type, it can use 'e'). */
+ static struct type *int_const_type;
+
+ /* Yes, this is as long as a *host* int. That is because we
+ use atoi. */
+ if (int_const_type == NULL)
+ int_const_type =
+ init_type (TYPE_CODE_INT,
+ sizeof (int) * HOST_CHAR_BIT / TARGET_CHAR_BIT, 0,
+ "integer constant",
+ (struct objfile *) NULL);
+ SYMBOL_TYPE (sym) = int_const_type;
+ SYMBOL_VALUE (sym) = atoi (p);
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ }
+ break;
+ case 'e':
+ /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value
+ can be represented as integral.
+ e.g. "b:c=e6,0" for "const b = blob1"
+ (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
+ {
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+
+ if (*p != ',')
+ {
+ SYMBOL_TYPE (sym) = error_type (&p, objfile);
+ break;
+ }
+ ++p;
+
+ /* If the value is too big to fit in an int (perhaps because
+ it is unsigned), or something like that, we silently get
+ a bogus value. The type and everything else about it is
+ correct. Ideally, we should be using whatever we have
+ available for parsing unsigned and long long values,
+ however. */
+ SYMBOL_VALUE (sym) = atoi (p);
+ }
+ break;
+ default:
+ {
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ SYMBOL_TYPE (sym) = error_type (&p, objfile);
+ }
+ }
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, &file_symbols);
+ return sym;
+
+ case 'C':
+ /* The name of a caught exception. */
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+ SYMBOL_CLASS (sym) = LOC_LABEL;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_VALUE_ADDRESS (sym) = valu;
+ add_symbol_to_list (sym, &local_symbols);
+ break;
+
+ case 'f':
+ /* A static function definition. */
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, &file_symbols);
+ /* fall into process_function_types. */
+
+ process_function_types:
+ /* Function result types are described as the result type in stabs.
+ We need to convert this to the function-returning-type-X type
+ in GDB. E.g. "int" is converted to "function returning int". */
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_FUNC)
+ SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));
+
+ /* All functions in C++ have prototypes. */
+ if (SYMBOL_LANGUAGE (sym) == language_cplus)
+ TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED;
+
+ /* fall into process_prototype_types */
+
+ process_prototype_types:
+ /* Sun acc puts declared types of arguments here. */
+ if (*p == ';')
+ {
+ struct type *ftype = SYMBOL_TYPE (sym);
+ int nsemi = 0;
+ int nparams = 0;
+ char *p1 = p;
+
+ /* Obtain a worst case guess for the number of arguments
+ by counting the semicolons. */
+ while (*p1)
+ {
+ if (*p1++ == ';')
+ nsemi++;
+ }
+
+ /* Allocate parameter information fields and fill them in. */
+ TYPE_FIELDS (ftype) = (struct field *)
+ TYPE_ALLOC (ftype, nsemi * sizeof (struct field));
+ while (*p++ == ';')
+ {
+ struct type *ptype;
+
+ /* A type number of zero indicates the start of varargs.
+ FIXME: GDB currently ignores vararg functions. */
+ if (p[0] == '0' && p[1] == '\0')
+ break;
+ ptype = read_type (&p, objfile);
+
+ /* The Sun compilers mark integer arguments, which should
+ be promoted to the width of the calling conventions, with
+ a type which references itself. This type is turned into
+ a TYPE_CODE_VOID type by read_type, and we have to turn
+ it back into builtin_type_int here.
+ FIXME: Do we need a new builtin_type_promoted_int_arg ? */
+ if (TYPE_CODE (ptype) == TYPE_CODE_VOID)
+ ptype = builtin_type_int;
+ TYPE_FIELD_TYPE (ftype, nparams) = ptype;
+ TYPE_FIELD_ARTIFICIAL (ftype, nparams++) = 0;
+ }
+ TYPE_NFIELDS (ftype) = nparams;
+ TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
+ }
+ break;
+
+ case 'F':
+ /* A global function definition. */
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, &global_symbols);
+ goto process_function_types;
+
+ case 'G':
+ /* For a class G (global) symbol, it appears that the
+ value is not correct. It is necessary to search for the
+ corresponding linker definition to find the value.
+ These definitions appear at the end of the namelist. */
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ /* Don't add symbol references to global_sym_chain.
+ Symbol references don't have valid names and wont't match up with
+ minimal symbols when the global_sym_chain is relocated.
+ We'll fixup symbol references when we fixup the defining symbol. */
+ if (SYMBOL_NAME (sym) && SYMBOL_NAME (sym)[0] != '#')
+ {
+ i = hashname (SYMBOL_NAME (sym));
+ SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i];
+ global_sym_chain[i] = sym;
+ }
+ add_symbol_to_list (sym, &global_symbols);
+ break;
+
+ /* This case is faked by a conditional above,
+ when there is no code letter in the dbx data.
+ Dbx data never actually contains 'l'. */
+ case 's':
+ case 'l':
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+ SYMBOL_CLASS (sym) = LOC_LOCAL;
+ SYMBOL_VALUE (sym) = valu;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, &local_symbols);
+ break;
+
+ case 'p':
+ if (*p == 'F')
+ /* pF is a two-letter code that means a function parameter in Fortran.
+ The type-number specifies the type of the return value.
+ Translate it into a pointer-to-function type. */
+ {
+ p++;
+ SYMBOL_TYPE (sym)
+ = lookup_pointer_type
+ (lookup_function_type (read_type (&p, objfile)));
+ }
+ else
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+
+ /* Normally this is a parameter, a LOC_ARG. On the i960, it
+ can also be a LOC_LOCAL_ARG depending on symbol type. */
+#ifndef DBX_PARM_SYMBOL_CLASS
+#define DBX_PARM_SYMBOL_CLASS(type) LOC_ARG
+#endif
+
+ SYMBOL_CLASS (sym) = DBX_PARM_SYMBOL_CLASS (type);
+ SYMBOL_VALUE (sym) = valu;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, &local_symbols);
+
+ if (TARGET_BYTE_ORDER != BFD_ENDIAN_BIG)
+ {
+ /* On little-endian machines, this crud is never necessary,
+ and, if the extra bytes contain garbage, is harmful. */
+ break;
+ }
+
+ /* If it's gcc-compiled, if it says `short', believe it. */
+ if (processing_gcc_compilation || BELIEVE_PCC_PROMOTION)
+ break;
+
+ if (!BELIEVE_PCC_PROMOTION)
+ {
+ /* This is the signed type which arguments get promoted to. */
+ static struct type *pcc_promotion_type;
+ /* This is the unsigned type which arguments get promoted to. */
+ static struct type *pcc_unsigned_promotion_type;
+
+ /* Call it "int" because this is mainly C lossage. */
+ if (pcc_promotion_type == NULL)
+ pcc_promotion_type =
+ init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "int", NULL);
+
+ if (pcc_unsigned_promotion_type == NULL)
+ pcc_unsigned_promotion_type =
+ init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, "unsigned int", NULL);
+
+ if (BELIEVE_PCC_PROMOTION_TYPE)
+ {
+ /* This is defined on machines (e.g. sparc) where we
+ should believe the type of a PCC 'short' argument,
+ but shouldn't believe the address (the address is the
+ address of the corresponding int).
+
+ My guess is that this correction, as opposed to
+ changing the parameter to an 'int' (as done below,
+ for PCC on most machines), is the right thing to do
+ on all machines, but I don't want to risk breaking
+ something that already works. On most PCC machines,
+ the sparc problem doesn't come up because the calling
+ function has to zero the top bytes (not knowing
+ whether the called function wants an int or a short),
+ so there is little practical difference between an
+ int and a short (except perhaps what happens when the
+ GDB user types "print short_arg = 0x10000;").
+
+ Hacked for SunOS 4.1 by gnu@cygnus.com. In 4.1, the
+ compiler actually produces the correct address (we
+ don't need to fix it up). I made this code adapt so
+ that it will offset the symbol if it was pointing at
+ an int-aligned location and not otherwise. This way
+ you can use the same gdb for 4.0.x and 4.1 systems.
+
+ If the parameter is shorter than an int, and is
+ integral (e.g. char, short, or unsigned equivalent),
+ and is claimed to be passed on an integer boundary,
+ don't believe it! Offset the parameter's address to
+ the tail-end of that integer. */
+
+ if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (pcc_promotion_type)
+ && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT
+ && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (pcc_promotion_type))
+ {
+ SYMBOL_VALUE (sym) += TYPE_LENGTH (pcc_promotion_type)
+ - TYPE_LENGTH (SYMBOL_TYPE (sym));
+ }
+ break;
+ }
+ else
+ {
+ /* If PCC says a parameter is a short or a char,
+ it is really an int. */
+ if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (pcc_promotion_type)
+ && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)
+ {
+ SYMBOL_TYPE (sym) =
+ TYPE_UNSIGNED (SYMBOL_TYPE (sym))
+ ? pcc_unsigned_promotion_type
+ : pcc_promotion_type;
+ }
+ break;
+ }
+ }
+
+ case 'P':
+ /* acc seems to use P to declare the prototypes of functions that
+ are referenced by this file. gdb is not prepared to deal
+ with this extra information. FIXME, it ought to. */
+ if (type == N_FUN)
+ {
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+ goto process_prototype_types;
+ }
+ /*FALLTHROUGH */
+
+ case 'R':
+ /* Parameter which is in a register. */
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+ SYMBOL_CLASS (sym) = LOC_REGPARM;
+ SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu);
+ if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS)
+ {
+ complain (&reg_value_complaint, SYMBOL_VALUE (sym),
+ NUM_REGS + NUM_PSEUDO_REGS,
+ SYMBOL_SOURCE_NAME (sym));
+ SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */
+ }
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, &local_symbols);
+ break;
+
+ case 'r':
+ /* Register variable (either global or local). */
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+ SYMBOL_CLASS (sym) = LOC_REGISTER;
+ SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu);
+ if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS)
+ {
+ complain (&reg_value_complaint, SYMBOL_VALUE (sym),
+ NUM_REGS + NUM_PSEUDO_REGS,
+ SYMBOL_SOURCE_NAME (sym));
+ SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */
+ }
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ if (within_function)
+ {
+ /* Sun cc uses a pair of symbols, one 'p' and one 'r' with the same
+ name to represent an argument passed in a register.
+ GCC uses 'P' for the same case. So if we find such a symbol pair
+ we combine it into one 'P' symbol. For Sun cc we need to do this
+ regardless of REG_STRUCT_HAS_ADDR, because the compiler puts out
+ the 'p' symbol even if it never saves the argument onto the stack.
+
+ On most machines, we want to preserve both symbols, so that
+ we can still get information about what is going on with the
+ stack (VAX for computing args_printed, using stack slots instead
+ of saved registers in backtraces, etc.).
+
+ Note that this code illegally combines
+ main(argc) struct foo argc; { register struct foo argc; }
+ but this case is considered pathological and causes a warning
+ from a decent compiler. */
+
+ if (local_symbols
+ && local_symbols->nsyms > 0
+#ifndef USE_REGISTER_NOT_ARG
+ && REG_STRUCT_HAS_ADDR_P ()
+ && REG_STRUCT_HAS_ADDR (processing_gcc_compilation,
+ SYMBOL_TYPE (sym))
+ && (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT
+ || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION
+ || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_SET
+ || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_BITSTRING)
+#endif
+ )
+ {
+ struct symbol *prev_sym;
+ prev_sym = local_symbols->symbol[local_symbols->nsyms - 1];
+ if ((SYMBOL_CLASS (prev_sym) == LOC_REF_ARG
+ || SYMBOL_CLASS (prev_sym) == LOC_ARG)
+ && STREQ (SYMBOL_NAME (prev_sym), SYMBOL_NAME (sym)))
+ {
+ SYMBOL_CLASS (prev_sym) = LOC_REGPARM;
+ /* Use the type from the LOC_REGISTER; that is the type
+ that is actually in that register. */
+ SYMBOL_TYPE (prev_sym) = SYMBOL_TYPE (sym);
+ SYMBOL_VALUE (prev_sym) = SYMBOL_VALUE (sym);
+ sym = prev_sym;
+ break;
+ }
+ }
+ add_symbol_to_list (sym, &local_symbols);
+ }
+ else
+ add_symbol_to_list (sym, &file_symbols);
+ break;
+
+ case 'S':
+ /* Static symbol at top level of file */
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ SYMBOL_VALUE_ADDRESS (sym) = valu;
+#ifdef STATIC_TRANSFORM_NAME
+ if (IS_STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym)))
+ {
+ struct minimal_symbol *msym;
+ msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile);
+ if (msym != NULL)
+ {
+ SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym));
+ SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msym);
+ }
+ }
+#endif
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, &file_symbols);
+ break;
+
+ case 't':
+ /* Typedef */
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+
+ /* For a nameless type, we don't want a create a symbol, thus we
+ did not use `sym'. Return without further processing. */
+ if (nameless)
+ return NULL;
+
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_VALUE (sym) = valu;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ /* C++ vagaries: we may have a type which is derived from
+ a base type which did not have its name defined when the
+ derived class was output. We fill in the derived class's
+ base part member's name here in that case. */
+ if (TYPE_NAME (SYMBOL_TYPE (sym)) != NULL)
+ if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT
+ || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION)
+ && TYPE_N_BASECLASSES (SYMBOL_TYPE (sym)))
+ {
+ int j;
+ for (j = TYPE_N_BASECLASSES (SYMBOL_TYPE (sym)) - 1; j >= 0; j--)
+ if (TYPE_BASECLASS_NAME (SYMBOL_TYPE (sym), j) == 0)
+ TYPE_BASECLASS_NAME (SYMBOL_TYPE (sym), j) =
+ type_name_no_tag (TYPE_BASECLASS (SYMBOL_TYPE (sym), j));
+ }
+
+ if (TYPE_NAME (SYMBOL_TYPE (sym)) == NULL)
+ {
+ /* gcc-2.6 or later (when using -fvtable-thunks)
+ emits a unique named type for a vtable entry.
+ Some gdb code depends on that specific name. */
+ extern const char vtbl_ptr_name[];
+
+ if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
+ && strcmp (SYMBOL_NAME (sym), vtbl_ptr_name))
+ || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC)
+ {
+ /* If we are giving a name to a type such as "pointer to
+ foo" or "function returning foo", we better not set
+ the TYPE_NAME. If the program contains "typedef char
+ *caddr_t;", we don't want all variables of type char
+ * to print as caddr_t. This is not just a
+ consequence of GDB's type management; PCC and GCC (at
+ least through version 2.4) both output variables of
+ either type char * or caddr_t with the type number
+ defined in the 't' symbol for caddr_t. If a future
+ compiler cleans this up it GDB is not ready for it
+ yet, but if it becomes ready we somehow need to
+ disable this check (without breaking the PCC/GCC2.4
+ case).
+
+ Sigh.
+
+ Fortunately, this check seems not to be necessary
+ for anything except pointers or functions. */
+ /* ezannoni: 2000-10-26. This seems to apply for
+ versions of gcc older than 2.8. This was the original
+ problem: with the following code gdb would tell that
+ the type for name1 is caddr_t, and func is char()
+ typedef char *caddr_t;
+ char *name2;
+ struct x
+ {
+ char *name1;
+ } xx;
+ char *func()
+ {
+ }
+ main () {}
+ */
+
+ /* Pascal accepts names for pointer types. */
+ if (current_subfile->language == language_pascal)
+ {
+ TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_NAME (sym);
+ }
+ }
+ else
+ TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_NAME (sym);
+ }
+
+ add_symbol_to_list (sym, &file_symbols);
+ break;
+
+ case 'T':
+ /* Struct, union, or enum tag. For GNU C++, this can be be followed
+ by 't' which means we are typedef'ing it as well. */
+ synonym = *p == 't';
+
+ if (synonym)
+ p++;
+ /* The semantics of C++ state that "struct foo { ... }" also defines
+ a typedef for "foo". Unfortunately, cfront never makes the typedef
+ when translating C++ into C. We make the typedef here so that
+ "ptype foo" works as expected for cfront translated code. */
+ else if (current_subfile->language == language_cplus)
+ synonym = 1;
+
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+
+ /* For a nameless type, we don't want a create a symbol, thus we
+ did not use `sym'. Return without further processing. */
+ if (nameless)
+ return NULL;
+
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_VALUE (sym) = valu;
+ SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+ if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
+ TYPE_TAG_NAME (SYMBOL_TYPE (sym))
+ = obconcat (&objfile->type_obstack, "", "", SYMBOL_NAME (sym));
+ add_symbol_to_list (sym, &file_symbols);
+
+ if (synonym)
+ {
+ /* Clone the sym and then modify it. */
+ register struct symbol *typedef_sym = (struct symbol *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
+ *typedef_sym = *sym;
+ SYMBOL_CLASS (typedef_sym) = LOC_TYPEDEF;
+ SYMBOL_VALUE (typedef_sym) = valu;
+ SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE;
+ if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
+ TYPE_NAME (SYMBOL_TYPE (sym))
+ = obconcat (&objfile->type_obstack, "", "", SYMBOL_NAME (sym));
+ add_symbol_to_list (typedef_sym, &file_symbols);
+ }
+ break;
+
+ case 'V':
+ /* Static symbol of local scope */
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ SYMBOL_VALUE_ADDRESS (sym) = valu;
+#ifdef STATIC_TRANSFORM_NAME
+ if (IS_STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym)))
+ {
+ struct minimal_symbol *msym;
+ msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile);
+ if (msym != NULL)
+ {
+ SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym));
+ SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msym);
+ }
+ }
+#endif
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ if (os9k_stabs)
+ add_symbol_to_list (sym, &global_symbols);
+ else
+ add_symbol_to_list (sym, &local_symbols);
+ break;
+
+ case 'v':
+ /* Reference parameter */
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+ SYMBOL_CLASS (sym) = LOC_REF_ARG;
+ SYMBOL_VALUE (sym) = valu;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, &local_symbols);
+ break;
+
+ case 'a':
+ /* Reference parameter which is in a register. */
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+ SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+ SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu);
+ if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS)
+ {
+ complain (&reg_value_complaint, SYMBOL_VALUE (sym),
+ NUM_REGS + NUM_PSEUDO_REGS,
+ SYMBOL_SOURCE_NAME (sym));
+ SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */
+ }
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, &local_symbols);
+ break;
+
+ case 'X':
+ /* This is used by Sun FORTRAN for "function result value".
+ Sun claims ("dbx and dbxtool interfaces", 2nd ed)
+ that Pascal uses it too, but when I tried it Pascal used
+ "x:3" (local symbol) instead. */
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+ SYMBOL_CLASS (sym) = LOC_LOCAL;
+ SYMBOL_VALUE (sym) = valu;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, &local_symbols);
+ break;
+
+ /* New code added to support cfront stabs strings.
+ Note: case 'P' already handled above */
+ case 'Z':
+ /* Cfront type continuation coming up!
+ Find the original definition and add to it.
+ We'll have to do this for the typedef too,
+ since we cloned the symbol to define a type in read_type.
+ Stabs info examples:
+ __1C :Ztl
+ foo__1CFv :ZtF (first def foo__1CFv:F(0,3);(0,24))
+ C:ZsC;;__ct__1CFv func1__1CFv func2__1CFv ... ;;;
+ where C is the name of the class.
+ Unfortunately, we can't lookup the original symbol yet 'cuz
+ we haven't finished reading all the symbols.
+ Instead, we save it for processing later */
+ process_later (sym, p, resolve_cfront_continuation);
+ SYMBOL_TYPE (sym) = error_type (&p, objfile); /* FIXME! change later */
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ SYMBOL_VALUE (sym) = 0;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ /* Don't add to list - we'll delete it later when
+ we add the continuation to the real sym */
+ return sym;
+ /* End of new code added to support cfront stabs strings */
+
+ default:
+ SYMBOL_TYPE (sym) = error_type (&p, objfile);
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ SYMBOL_VALUE (sym) = 0;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, &file_symbols);
+ break;
+ }
+
+ /* When passing structures to a function, some systems sometimes pass
+ the address in a register, not the structure itself. */
+
+ if (REG_STRUCT_HAS_ADDR_P ()
+ && REG_STRUCT_HAS_ADDR (processing_gcc_compilation, SYMBOL_TYPE (sym))
+ && (SYMBOL_CLASS (sym) == LOC_REGPARM || SYMBOL_CLASS (sym) == LOC_ARG))
+ {
+ struct type *symbol_type = check_typedef (SYMBOL_TYPE (sym));
+
+ if ((TYPE_CODE (symbol_type) == TYPE_CODE_STRUCT)
+ || (TYPE_CODE (symbol_type) == TYPE_CODE_UNION)
+ || (TYPE_CODE (symbol_type) == TYPE_CODE_BITSTRING)
+ || (TYPE_CODE (symbol_type) == TYPE_CODE_SET))
+ {
+ /* If REG_STRUCT_HAS_ADDR yields non-zero we have to convert
+ LOC_REGPARM to LOC_REGPARM_ADDR for structures and unions. */
+ if (SYMBOL_CLASS (sym) == LOC_REGPARM)
+ SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+ /* Likewise for converting LOC_ARG to LOC_REF_ARG (for the 7th
+ and subsequent arguments on the sparc, for example). */
+ else if (SYMBOL_CLASS (sym) == LOC_ARG)
+ SYMBOL_CLASS (sym) = LOC_REF_ARG;
+ }
+ }
+
+ /* Is there more to parse? For example LRS/alias information? */
+ while (*p && *p == ';')
+ {
+ p++;
+ if (*p && p[0] == 'l' && p[1] == '(')
+ {
+ /* GNU extensions for live range splitting may be appended to
+ the end of the stab string. eg. "l(#1,#2);l(#3,#5)" */
+
+ /* Resolve the live range and add it to SYM's live range list. */
+ if (!resolve_live_range (objfile, sym, p))
+ return NULL;
+
+ /* Find end of live range info. */
+ p = strchr (p, ')');
+ if (!*p || *p != ')')
+ {
+ complain (&lrs_general_complaint, "live range format not recognized");
+ return NULL;
+ }
+ p++;
+ }
+ }
+ return sym;
+}
+
+/* Add the live range found in P to the symbol SYM in objfile OBJFILE. Returns
+ non-zero on success, zero otherwise. */
+
+static int
+resolve_live_range (struct objfile *objfile, struct symbol *sym, char *p)
+{
+ int refnum;
+ CORE_ADDR start, end;
+
+ /* Sanity check the beginning of the stabs string. */
+ if (!*p || *p != 'l')
+ {
+ complain (&lrs_general_complaint, "live range string 1");
+ return 0;
+ }
+ p++;
+
+ if (!*p || *p != '(')
+ {
+ complain (&lrs_general_complaint, "live range string 2");
+ return 0;
+ }
+ p++;
+
+ /* Get starting value of range and advance P past the reference id.
+
+ ?!? In theory, the process_reference should never fail, but we should
+ catch that case just in case the compiler scrogged the stabs. */
+ refnum = process_reference (&p);
+ start = ref_search_value (refnum);
+ if (!start)
+ {
+ complain (&lrs_general_complaint, "Live range symbol not found 1");
+ return 0;
+ }
+
+ if (!*p || *p != ',')
+ {
+ complain (&lrs_general_complaint, "live range string 3");
+ return 0;
+ }
+ p++;
+
+ /* Get ending value of range and advance P past the reference id.
+
+ ?!? In theory, the process_reference should never fail, but we should
+ catch that case just in case the compiler scrogged the stabs. */
+ refnum = process_reference (&p);
+ end = ref_search_value (refnum);
+ if (!end)
+ {
+ complain (&lrs_general_complaint, "Live range symbol not found 2");
+ return 0;
+ }
+
+ if (!*p || *p != ')')
+ {
+ complain (&lrs_general_complaint, "live range string 4");
+ return 0;
+ }
+
+ /* Now that we know the bounds of the range, add it to the
+ symbol. */
+ add_live_range (objfile, sym, start, end);
+
+ return 1;
+}
+
+/* Add a new live range defined by START and END to the symbol SYM
+ in objfile OBJFILE. */
+
+static void
+add_live_range (struct objfile *objfile, struct symbol *sym, CORE_ADDR start,
+ CORE_ADDR end)
+{
+ struct range_list *r, *rs;
+
+ if (start >= end)
+ {
+ complain (&lrs_general_complaint, "end of live range follows start");
+ return;
+ }
+
+ /* Alloc new live range structure. */
+ r = (struct range_list *)
+ obstack_alloc (&objfile->type_obstack,
+ sizeof (struct range_list));
+ r->start = start;
+ r->end = end;
+ r->next = 0;
+
+ /* Append this range to the symbol's range list. */
+ if (!SYMBOL_RANGES (sym))
+ SYMBOL_RANGES (sym) = r;
+ else
+ {
+ /* Get the last range for the symbol. */
+ for (rs = SYMBOL_RANGES (sym); rs->next; rs = rs->next)
+ ;
+ rs->next = r;
+ }
+}
+
+
+/* Skip rest of this symbol and return an error type.
+
+ General notes on error recovery: error_type always skips to the
+ end of the symbol (modulo cretinous dbx symbol name continuation).
+ Thus code like this:
+
+ if (*(*pp)++ != ';')
+ return error_type (pp, objfile);
+
+ is wrong because if *pp starts out pointing at '\0' (typically as the
+ result of an earlier error), it will be incremented to point to the
+ start of the next symbol, which might produce strange results, at least
+ if you run off the end of the string table. Instead use
+
+ if (**pp != ';')
+ return error_type (pp, objfile);
+ ++*pp;
+
+ or
+
+ if (**pp != ';')
+ foo = error_type (pp, objfile);
+ else
+ ++*pp;
+
+ And in case it isn't obvious, the point of all this hair is so the compiler
+ can define new types and new syntaxes, and old versions of the
+ debugger will be able to read the new symbol tables. */
+
+static struct type *
+error_type (char **pp, struct objfile *objfile)
+{
+ complain (&error_type_complaint);
+ while (1)
+ {
+ /* Skip to end of symbol. */
+ while (**pp != '\0')
+ {
+ (*pp)++;
+ }
+
+ /* Check for and handle cretinous dbx symbol name continuation! */
+ if ((*pp)[-1] == '\\' || (*pp)[-1] == '?')
+ {
+ *pp = next_symbol_text (objfile);
+ }
+ else
+ {
+ break;
+ }
+ }
+ return (builtin_type_error);
+}
+
+
+/* Read type information or a type definition; return the type. Even
+ though this routine accepts either type information or a type
+ definition, the distinction is relevant--some parts of stabsread.c
+ assume that type information starts with a digit, '-', or '(' in
+ deciding whether to call read_type. */
+
+struct type *
+read_type (register char **pp, struct objfile *objfile)
+{
+ register struct type *type = 0;
+ struct type *type1;
+ int typenums[2];
+ char type_descriptor;
+
+ /* Size in bits of type if specified by a type attribute, or -1 if
+ there is no size attribute. */
+ int type_size = -1;
+
+ /* Used to distinguish string and bitstring from char-array and set. */
+ int is_string = 0;
+
+ /* Used to distinguish vector from array. */
+ int is_vector = 0;
+
+ /* Read type number if present. The type number may be omitted.
+ for instance in a two-dimensional array declared with type
+ "ar1;1;10;ar1;1;10;4". */
+ if ((**pp >= '0' && **pp <= '9')
+ || **pp == '('
+ || **pp == '-')
+ {
+ if (read_type_number (pp, typenums) != 0)
+ return error_type (pp, objfile);
+
+ /* Type is not being defined here. Either it already exists,
+ or this is a forward reference to it. dbx_alloc_type handles
+ both cases. */
+ if (**pp != '=')
+ return dbx_alloc_type (typenums, objfile);
+
+ /* Type is being defined here. */
+ /* Skip the '='.
+ Also skip the type descriptor - we get it below with (*pp)[-1]. */
+ (*pp) += 2;
+ }
+ else
+ {
+ /* 'typenums=' not present, type is anonymous. Read and return
+ the definition, but don't put it in the type vector. */
+ typenums[0] = typenums[1] = -1;
+ (*pp)++;
+ }
+
+again:
+ type_descriptor = (*pp)[-1];
+ switch (type_descriptor)
+ {
+ case 'x':
+ {
+ enum type_code code;
+
+ /* Used to index through file_symbols. */
+ struct pending *ppt;
+ int i;
+
+ /* Name including "struct", etc. */
+ char *type_name;
+
+ {
+ char *from, *to, *p, *q1, *q2;
+
+ /* Set the type code according to the following letter. */
+ switch ((*pp)[0])
+ {
+ case 's':
+ code = TYPE_CODE_STRUCT;
+ break;
+ case 'u':
+ code = TYPE_CODE_UNION;
+ break;
+ case 'e':
+ code = TYPE_CODE_ENUM;
+ break;
+ default:
+ {
+ /* Complain and keep going, so compilers can invent new
+ cross-reference types. */
+ static struct complaint msg =
+ {"Unrecognized cross-reference type `%c'", 0, 0};
+ complain (&msg, (*pp)[0]);
+ code = TYPE_CODE_STRUCT;
+ break;
+ }
+ }
+
+ q1 = strchr (*pp, '<');
+ p = strchr (*pp, ':');
+ if (p == NULL)
+ return error_type (pp, objfile);
+ if (q1 && p > q1 && p[1] == ':')
+ {
+ int nesting_level = 0;
+ for (q2 = q1; *q2; q2++)
+ {
+ if (*q2 == '<')
+ nesting_level++;
+ else if (*q2 == '>')
+ nesting_level--;
+ else if (*q2 == ':' && nesting_level == 0)
+ break;
+ }
+ p = q2;
+ if (*p != ':')
+ return error_type (pp, objfile);
+ }
+ to = type_name =
+ (char *) obstack_alloc (&objfile->type_obstack, p - *pp + 1);
+
+ /* Copy the name. */
+ from = *pp + 1;
+ while (from < p)
+ *to++ = *from++;
+ *to = '\0';
+
+ /* Set the pointer ahead of the name which we just read, and
+ the colon. */
+ *pp = from + 1;
+ }
+
+ /* Now check to see whether the type has already been
+ declared. This was written for arrays of cross-referenced
+ types before we had TYPE_CODE_TARGET_STUBBED, so I'm pretty
+ sure it is not necessary anymore. But it might be a good
+ idea, to save a little memory. */
+
+ for (ppt = file_symbols; ppt; ppt = ppt->next)
+ for (i = 0; i < ppt->nsyms; i++)
+ {
+ struct symbol *sym = ppt->symbol[i];
+
+ if (SYMBOL_CLASS (sym) == LOC_TYPEDEF
+ && SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE
+ && (TYPE_CODE (SYMBOL_TYPE (sym)) == code)
+ && STREQ (SYMBOL_NAME (sym), type_name))
+ {
+ obstack_free (&objfile->type_obstack, type_name);
+ type = SYMBOL_TYPE (sym);
+ return type;
+ }
+ }
+
+ /* Didn't find the type to which this refers, so we must
+ be dealing with a forward reference. Allocate a type
+ structure for it, and keep track of it so we can
+ fill in the rest of the fields when we get the full
+ type. */
+ type = dbx_alloc_type (typenums, objfile);
+ TYPE_CODE (type) = code;
+ TYPE_TAG_NAME (type) = type_name;
+ INIT_CPLUS_SPECIFIC (type);
+ TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
+
+ add_undefined_type (type);
+ return type;
+ }
+
+ case '-': /* RS/6000 built-in type */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '(':
+ (*pp)--;
+
+ /* We deal with something like t(1,2)=(3,4)=... which
+ the Lucid compiler and recent gcc versions (post 2.7.3) use. */
+
+ /* Allocate and enter the typedef type first.
+ This handles recursive types. */
+ type = dbx_alloc_type (typenums, objfile);
+ TYPE_CODE (type) = TYPE_CODE_TYPEDEF;
+ {
+ struct type *xtype = read_type (pp, objfile);
+ if (type == xtype)
+ {
+ /* It's being defined as itself. That means it is "void". */
+ TYPE_CODE (type) = TYPE_CODE_VOID;
+ TYPE_LENGTH (type) = 1;
+ }
+ else if (type_size >= 0 || is_string)
+ {
+ /* This is the absolute wrong way to construct types. Every
+ other debug format has found a way around this problem and
+ the related problems with unnecessarily stubbed types;
+ someone motivated should attempt to clean up the issue
+ here as well. Once a type pointed to has been created it
+ should not be modified.
+
+ Well, it's not *absolutely* wrong. Constructing recursive
+ types (trees, linked lists) necessarily entails modifying
+ types after creating them. Constructing any loop structure
+ entails side effects. The Dwarf 2 reader does handle this
+ more gracefully (it never constructs more than once
+ instance of a type object, so it doesn't have to copy type
+ objects wholesale), but it still mutates type objects after
+ other folks have references to them.
+
+ Keep in mind that this circularity/mutation issue shows up
+ at the source language level, too: C's "incomplete types",
+ for example. So the proper cleanup, I think, would be to
+ limit GDB's type smashing to match exactly those required
+ by the source language. So GDB could have a
+ "complete_this_type" function, but never create unnecessary
+ copies of a type otherwise. */
+ replace_type (type, xtype);
+ TYPE_NAME (type) = NULL;
+ TYPE_TAG_NAME (type) = NULL;
+ }
+ else
+ {
+ TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
+ TYPE_TARGET_TYPE (type) = xtype;
+ }
+ }
+ break;
+
+ /* In the following types, we must be sure to overwrite any existing
+ type that the typenums refer to, rather than allocating a new one
+ and making the typenums point to the new one. This is because there
+ may already be pointers to the existing type (if it had been
+ forward-referenced), and we must change it to a pointer, function,
+ reference, or whatever, *in-place*. */
+
+ case '*': /* Pointer to another type */
+ type1 = read_type (pp, objfile);
+ type = make_pointer_type (type1, dbx_lookup_type (typenums));
+ break;
+
+ case '&': /* Reference to another type */
+ type1 = read_type (pp, objfile);
+ type = make_reference_type (type1, dbx_lookup_type (typenums));
+ break;
+
+ case 'f': /* Function returning another type */
+ if (os9k_stabs && **pp == '(')
+ {
+ /* Function prototype; parse it.
+ We must conditionalize this on os9k_stabs because otherwise
+ it could be confused with a Sun-style (1,3) typenumber
+ (I think). */
+ struct type *t;
+ ++*pp;
+ while (**pp != ')')
+ {
+ t = read_type (pp, objfile);
+ if (**pp == ',')
+ ++ * pp;
+ }
+ }
+ type1 = read_type (pp, objfile);
+ type = make_function_type (type1, dbx_lookup_type (typenums));
+ break;
+
+ case 'g': /* Prototyped function. (Sun) */
+ {
+ /* Unresolved questions:
+
+ - According to Sun's ``STABS Interface Manual'', for 'f'
+ and 'F' symbol descriptors, a `0' in the argument type list
+ indicates a varargs function. But it doesn't say how 'g'
+ type descriptors represent that info. Someone with access
+ to Sun's toolchain should try it out.
+
+ - According to the comment in define_symbol (search for
+ `process_prototype_types:'), Sun emits integer arguments as
+ types which ref themselves --- like `void' types. Do we
+ have to deal with that here, too? Again, someone with
+ access to Sun's toolchain should try it out and let us
+ know. */
+
+ const char *type_start = (*pp) - 1;
+ struct type *return_type = read_type (pp, objfile);
+ struct type *func_type
+ = make_function_type (return_type, dbx_lookup_type (typenums));
+ struct type_list {
+ struct type *type;
+ struct type_list *next;
+ } *arg_types = 0;
+ int num_args = 0;
+
+ while (**pp && **pp != '#')
+ {
+ struct type *arg_type = read_type (pp, objfile);
+ struct type_list *new = alloca (sizeof (*new));
+ new->type = arg_type;
+ new->next = arg_types;
+ arg_types = new;
+ num_args++;
+ }
+ if (**pp == '#')
+ ++*pp;
+ else
+ {
+ static struct complaint msg = {
+ "Prototyped function type didn't end arguments with `#':\n%s",
+ 0, 0
+ };
+ complain (&msg, type_start);
+ }
+
+ /* If there is just one argument whose type is `void', then
+ that's just an empty argument list. */
+ if (arg_types
+ && ! arg_types->next
+ && TYPE_CODE (arg_types->type) == TYPE_CODE_VOID)
+ num_args = 0;
+
+ TYPE_FIELDS (func_type)
+ = (struct field *) TYPE_ALLOC (func_type,
+ num_args * sizeof (struct field));
+ memset (TYPE_FIELDS (func_type), 0, num_args * sizeof (struct field));
+ {
+ int i;
+ struct type_list *t;
+
+ /* We stuck each argument type onto the front of the list
+ when we read it, so the list is reversed. Build the
+ fields array right-to-left. */
+ for (t = arg_types, i = num_args - 1; t; t = t->next, i--)
+ TYPE_FIELD_TYPE (func_type, i) = t->type;
+ }
+ TYPE_NFIELDS (func_type) = num_args;
+ TYPE_FLAGS (func_type) |= TYPE_FLAG_PROTOTYPED;
+
+ type = func_type;
+ break;
+ }
+
+ case 'k': /* Const qualifier on some type (Sun) */
+ case 'c': /* Const qualifier on some type (OS9000) */
+ /* Because 'c' means other things to AIX and 'k' is perfectly good,
+ only accept 'c' in the os9k_stabs case. */
+ if (type_descriptor == 'c' && !os9k_stabs)
+ return error_type (pp, objfile);
+ type = read_type (pp, objfile);
+ type = make_cv_type (1, TYPE_VOLATILE (type), type,
+ dbx_lookup_type (typenums));
+ break;
+
+ case 'B': /* Volatile qual on some type (Sun) */
+ case 'i': /* Volatile qual on some type (OS9000) */
+ /* Because 'i' means other things to AIX and 'B' is perfectly good,
+ only accept 'i' in the os9k_stabs case. */
+ if (type_descriptor == 'i' && !os9k_stabs)
+ return error_type (pp, objfile);
+ type = read_type (pp, objfile);
+ type = make_cv_type (TYPE_CONST (type), 1, type,
+ dbx_lookup_type (typenums));
+ break;
+
+ case '@':
+ if (isdigit (**pp) || **pp == '(' || **pp == '-')
+ { /* Member (class & variable) type */
+ /* FIXME -- we should be doing smash_to_XXX types here. */
+
+ struct type *domain = read_type (pp, objfile);
+ struct type *memtype;
+
+ if (**pp != ',')
+ /* Invalid member type data format. */
+ return error_type (pp, objfile);
+ ++*pp;
+
+ memtype = read_type (pp, objfile);
+ type = dbx_alloc_type (typenums, objfile);
+ smash_to_member_type (type, domain, memtype);
+ }
+ else
+ /* type attribute */
+ {
+ char *attr = *pp;
+ /* Skip to the semicolon. */
+ while (**pp != ';' && **pp != '\0')
+ ++(*pp);
+ if (**pp == '\0')
+ return error_type (pp, objfile);
+ else
+ ++ * pp; /* Skip the semicolon. */
+
+ switch (*attr)
+ {
+ case 's': /* Size attribute */
+ type_size = atoi (attr + 1);
+ if (type_size <= 0)
+ type_size = -1;
+ break;
+
+ case 'S': /* String attribute */
+ /* FIXME: check to see if following type is array? */
+ is_string = 1;
+ break;
+
+ case 'V': /* Vector attribute */
+ /* FIXME: check to see if following type is array? */
+ is_vector = 1;
+ break;
+
+ default:
+ /* Ignore unrecognized type attributes, so future compilers
+ can invent new ones. */
+ break;
+ }
+ ++*pp;
+ goto again;
+ }
+ break;
+
+ case '#': /* Method (class & fn) type */
+ if ((*pp)[0] == '#')
+ {
+ /* We'll get the parameter types from the name. */
+ struct type *return_type;
+
+ (*pp)++;
+ return_type = read_type (pp, objfile);
+ if (*(*pp)++ != ';')
+ complain (&invalid_member_complaint, symnum);
+ type = allocate_stub_method (return_type);
+ if (typenums[0] != -1)
+ *dbx_lookup_type (typenums) = type;
+ }
+ else
+ {
+ struct type *domain = read_type (pp, objfile);
+ struct type *return_type;
+ struct type **args;
+
+ if (**pp != ',')
+ /* Invalid member type data format. */
+ return error_type (pp, objfile);
+ else
+ ++(*pp);
+
+ return_type = read_type (pp, objfile);
+ args = read_args (pp, ';', objfile);
+ type = dbx_alloc_type (typenums, objfile);
+ smash_to_method_type (type, domain, return_type, args);
+ }
+ break;
+
+ case 'r': /* Range type */
+ type = read_range_type (pp, typenums, objfile);
+ if (typenums[0] != -1)
+ *dbx_lookup_type (typenums) = type;
+ break;
+
+ case 'b':
+ if (os9k_stabs)
+ /* Const and volatile qualified type. */
+ type = read_type (pp, objfile);
+ else
+ {
+ /* Sun ACC builtin int type */
+ type = read_sun_builtin_type (pp, typenums, objfile);
+ if (typenums[0] != -1)
+ *dbx_lookup_type (typenums) = type;
+ }
+ break;
+
+ case 'R': /* Sun ACC builtin float type */
+ type = read_sun_floating_type (pp, typenums, objfile);
+ if (typenums[0] != -1)
+ *dbx_lookup_type (typenums) = type;
+ break;
+
+ case 'e': /* Enumeration type */
+ type = dbx_alloc_type (typenums, objfile);
+ type = read_enum_type (pp, type, objfile);
+ if (typenums[0] != -1)
+ *dbx_lookup_type (typenums) = type;
+ break;
+
+ case 's': /* Struct type */
+ case 'u': /* Union type */
+ {
+ enum type_code type_code = TYPE_CODE_UNDEF;
+ type = dbx_alloc_type (typenums, objfile);
+ switch (type_descriptor)
+ {
+ case 's':
+ type_code = TYPE_CODE_STRUCT;
+ break;
+ case 'u':
+ type_code = TYPE_CODE_UNION;
+ break;
+ }
+ type = read_struct_type (pp, type, type_code, objfile);
+ break;
+ }
+
+ case 'a': /* Array type */
+ if (**pp != 'r')
+ return error_type (pp, objfile);
+ ++*pp;
+
+ type = dbx_alloc_type (typenums, objfile);
+ type = read_array_type (pp, type, objfile);
+ if (is_string)
+ TYPE_CODE (type) = TYPE_CODE_STRING;
+ if (is_vector)
+ TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
+ break;
+
+ case 'S': /* Set or bitstring type */
+ type1 = read_type (pp, objfile);
+ type = create_set_type ((struct type *) NULL, type1);
+ if (is_string)
+ TYPE_CODE (type) = TYPE_CODE_BITSTRING;
+ if (typenums[0] != -1)
+ *dbx_lookup_type (typenums) = type;
+ break;
+
+ default:
+ --*pp; /* Go back to the symbol in error */
+ /* Particularly important if it was \0! */
+ return error_type (pp, objfile);
+ }
+
+ if (type == 0)
+ {
+ warning ("GDB internal error, type is NULL in stabsread.c\n");
+ return error_type (pp, objfile);
+ }
+
+ /* Size specified in a type attribute overrides any other size. */
+ if (type_size != -1)
+ TYPE_LENGTH (type) = (type_size + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT;
+
+ return type;
+}
+
+/* RS/6000 xlc/dbx combination uses a set of builtin types, starting from -1.
+ Return the proper type node for a given builtin type number. */
+
+static struct type *
+rs6000_builtin_type (int typenum)
+{
+ /* We recognize types numbered from -NUMBER_RECOGNIZED to -1. */
+#define NUMBER_RECOGNIZED 34
+ /* This includes an empty slot for type number -0. */
+ static struct type *negative_types[NUMBER_RECOGNIZED + 1];
+ struct type *rettype = NULL;
+
+ if (typenum >= 0 || typenum < -NUMBER_RECOGNIZED)
+ {
+ complain (&rs6000_builtin_complaint, typenum);
+ return builtin_type_error;
+ }
+ if (negative_types[-typenum] != NULL)
+ return negative_types[-typenum];
+
+#if TARGET_CHAR_BIT != 8
+#error This code wrong for TARGET_CHAR_BIT not 8
+ /* These definitions all assume that TARGET_CHAR_BIT is 8. I think
+ that if that ever becomes not true, the correct fix will be to
+ make the size in the struct type to be in bits, not in units of
+ TARGET_CHAR_BIT. */
+#endif
+
+ switch (-typenum)
+ {
+ case 1:
+ /* The size of this and all the other types are fixed, defined
+ by the debugging format. If there is a type called "int" which
+ is other than 32 bits, then it should use a new negative type
+ number (or avoid negative type numbers for that case).
+ See stabs.texinfo. */
+ rettype = init_type (TYPE_CODE_INT, 4, 0, "int", NULL);
+ break;
+ case 2:
+ rettype = init_type (TYPE_CODE_INT, 1, 0, "char", NULL);
+ break;
+ case 3:
+ rettype = init_type (TYPE_CODE_INT, 2, 0, "short", NULL);
+ break;
+ case 4:
+ rettype = init_type (TYPE_CODE_INT, 4, 0, "long", NULL);
+ break;
+ case 5:
+ rettype = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED,
+ "unsigned char", NULL);
+ break;
+ case 6:
+ rettype = init_type (TYPE_CODE_INT, 1, 0, "signed char", NULL);
+ break;
+ case 7:
+ rettype = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_UNSIGNED,
+ "unsigned short", NULL);
+ break;
+ case 8:
+ rettype = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_UNSIGNED,
+ "unsigned int", NULL);
+ break;
+ case 9:
+ rettype = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_UNSIGNED,
+ "unsigned", NULL);
+ case 10:
+ rettype = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_UNSIGNED,
+ "unsigned long", NULL);
+ break;
+ case 11:
+ rettype = init_type (TYPE_CODE_VOID, 1, 0, "void", NULL);
+ break;
+ case 12:
+ /* IEEE single precision (32 bit). */
+ rettype = init_type (TYPE_CODE_FLT, 4, 0, "float", NULL);
+ break;
+ case 13:
+ /* IEEE double precision (64 bit). */
+ rettype = init_type (TYPE_CODE_FLT, 8, 0, "double", NULL);
+ break;
+ case 14:
+ /* This is an IEEE double on the RS/6000, and different machines with
+ different sizes for "long double" should use different negative
+ type numbers. See stabs.texinfo. */
+ rettype = init_type (TYPE_CODE_FLT, 8, 0, "long double", NULL);
+ break;
+ case 15:
+ rettype = init_type (TYPE_CODE_INT, 4, 0, "integer", NULL);
+ break;
+ case 16:
+ rettype = init_type (TYPE_CODE_BOOL, 4, TYPE_FLAG_UNSIGNED,
+ "boolean", NULL);
+ break;
+ case 17:
+ rettype = init_type (TYPE_CODE_FLT, 4, 0, "short real", NULL);
+ break;
+ case 18:
+ rettype = init_type (TYPE_CODE_FLT, 8, 0, "real", NULL);
+ break;
+ case 19:
+ rettype = init_type (TYPE_CODE_ERROR, 0, 0, "stringptr", NULL);
+ break;
+ case 20:
+ rettype = init_type (TYPE_CODE_CHAR, 1, TYPE_FLAG_UNSIGNED,
+ "character", NULL);
+ break;
+ case 21:
+ rettype = init_type (TYPE_CODE_BOOL, 1, TYPE_FLAG_UNSIGNED,
+ "logical*1", NULL);
+ break;
+ case 22:
+ rettype = init_type (TYPE_CODE_BOOL, 2, TYPE_FLAG_UNSIGNED,
+ "logical*2", NULL);
+ break;
+ case 23:
+ rettype = init_type (TYPE_CODE_BOOL, 4, TYPE_FLAG_UNSIGNED,
+ "logical*4", NULL);
+ break;
+ case 24:
+ rettype = init_type (TYPE_CODE_BOOL, 4, TYPE_FLAG_UNSIGNED,
+ "logical", NULL);
+ break;
+ case 25:
+ /* Complex type consisting of two IEEE single precision values. */
+ rettype = init_type (TYPE_CODE_COMPLEX, 8, 0, "complex", NULL);
+ TYPE_TARGET_TYPE (rettype) = init_type (TYPE_CODE_FLT, 4, 0, "float",
+ NULL);
+ break;
+ case 26:
+ /* Complex type consisting of two IEEE double precision values. */
+ rettype = init_type (TYPE_CODE_COMPLEX, 16, 0, "double complex", NULL);
+ TYPE_TARGET_TYPE (rettype) = init_type (TYPE_CODE_FLT, 8, 0, "double",
+ NULL);
+ break;
+ case 27:
+ rettype = init_type (TYPE_CODE_INT, 1, 0, "integer*1", NULL);
+ break;
+ case 28:
+ rettype = init_type (TYPE_CODE_INT, 2, 0, "integer*2", NULL);
+ break;
+ case 29:
+ rettype = init_type (TYPE_CODE_INT, 4, 0, "integer*4", NULL);
+ break;
+ case 30:
+ rettype = init_type (TYPE_CODE_CHAR, 2, 0, "wchar", NULL);
+ break;
+ case 31:
+ rettype = init_type (TYPE_CODE_INT, 8, 0, "long long", NULL);
+ break;
+ case 32:
+ rettype = init_type (TYPE_CODE_INT, 8, TYPE_FLAG_UNSIGNED,
+ "unsigned long long", NULL);
+ break;
+ case 33:
+ rettype = init_type (TYPE_CODE_INT, 8, TYPE_FLAG_UNSIGNED,
+ "logical*8", NULL);
+ break;
+ case 34:
+ rettype = init_type (TYPE_CODE_INT, 8, 0, "integer*8", NULL);
+ break;
+ }
+ negative_types[-typenum] = rettype;
+ return rettype;
+}
+
+/* This page contains subroutines of read_type. */
+
+/* Read member function stabs info for C++ classes. The form of each member
+ function data is:
+
+ NAME :: TYPENUM[=type definition] ARGS : PHYSNAME ;
+
+ An example with two member functions is:
+
+ afunc1::20=##15;:i;2A.;afunc2::20:i;2A.;
+
+ For the case of overloaded operators, the format is op$::*.funcs, where
+ $ is the CPLUS_MARKER (usually '$'), `*' holds the place for an operator
+ name (such as `+=') and `.' marks the end of the operator name.
+
+ Returns 1 for success, 0 for failure. */
+
+static int
+read_member_functions (struct field_info *fip, char **pp, struct type *type,
+ struct objfile *objfile)
+{
+ int nfn_fields = 0;
+ int length = 0;
+ /* Total number of member functions defined in this class. If the class
+ defines two `f' functions, and one `g' function, then this will have
+ the value 3. */
+ int total_length = 0;
+ int i;
+ struct next_fnfield
+ {
+ struct next_fnfield *next;
+ struct fn_field fn_field;
+ }
+ *sublist;
+ struct type *look_ahead_type;
+ struct next_fnfieldlist *new_fnlist;
+ struct next_fnfield *new_sublist;
+ char *main_fn_name;
+ register char *p;
+
+ /* Process each list until we find something that is not a member function
+ or find the end of the functions. */
+
+ while (**pp != ';')
+ {
+ /* We should be positioned at the start of the function name.
+ Scan forward to find the first ':' and if it is not the
+ first of a "::" delimiter, then this is not a member function. */
+ p = *pp;
+ while (*p != ':')
+ {
+ p++;
+ }
+ if (p[1] != ':')
+ {
+ break;
+ }
+
+ sublist = NULL;
+ look_ahead_type = NULL;
+ length = 0;
+
+ new_fnlist = (struct next_fnfieldlist *)
+ xmalloc (sizeof (struct next_fnfieldlist));
+ make_cleanup (xfree, new_fnlist);
+ memset (new_fnlist, 0, sizeof (struct next_fnfieldlist));
+
+ if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && is_cplus_marker ((*pp)[2]))
+ {
+ /* This is a completely wierd case. In order to stuff in the
+ names that might contain colons (the usual name delimiter),
+ Mike Tiemann defined a different name format which is
+ signalled if the identifier is "op$". In that case, the
+ format is "op$::XXXX." where XXXX is the name. This is
+ used for names like "+" or "=". YUUUUUUUK! FIXME! */
+ /* This lets the user type "break operator+".
+ We could just put in "+" as the name, but that wouldn't
+ work for "*". */
+ static char opname[32] =
+ {'o', 'p', CPLUS_MARKER};
+ char *o = opname + 3;
+
+ /* Skip past '::'. */
+ *pp = p + 2;
+
+ STABS_CONTINUE (pp, objfile);
+ p = *pp;
+ while (*p != '.')
+ {
+ *o++ = *p++;
+ }
+ main_fn_name = savestring (opname, o - opname);
+ /* Skip past '.' */
+ *pp = p + 1;
+ }
+ else
+ {
+ main_fn_name = savestring (*pp, p - *pp);
+ /* Skip past '::'. */
+ *pp = p + 2;
+ }
+ new_fnlist->fn_fieldlist.name = main_fn_name;
+
+ do
+ {
+ new_sublist =
+ (struct next_fnfield *) xmalloc (sizeof (struct next_fnfield));
+ make_cleanup (xfree, new_sublist);
+ memset (new_sublist, 0, sizeof (struct next_fnfield));
+
+ /* Check for and handle cretinous dbx symbol name continuation! */
+ if (look_ahead_type == NULL)
+ {
+ /* Normal case. */
+ STABS_CONTINUE (pp, objfile);
+
+ new_sublist->fn_field.type = read_type (pp, objfile);
+ if (**pp != ':')
+ {
+ /* Invalid symtab info for member function. */
+ return 0;
+ }
+ }
+ else
+ {
+ /* g++ version 1 kludge */
+ new_sublist->fn_field.type = look_ahead_type;
+ look_ahead_type = NULL;
+ }
+
+ (*pp)++;
+ p = *pp;
+ while (*p != ';')
+ {
+ p++;
+ }
+
+ /* If this is just a stub, then we don't have the real name here. */
+
+ if (TYPE_STUB (new_sublist->fn_field.type))
+ {
+ if (!TYPE_DOMAIN_TYPE (new_sublist->fn_field.type))
+ TYPE_DOMAIN_TYPE (new_sublist->fn_field.type) = type;
+ new_sublist->fn_field.is_stub = 1;
+ }
+ new_sublist->fn_field.physname = savestring (*pp, p - *pp);
+ *pp = p + 1;
+
+ /* Set this member function's visibility fields. */
+ switch (*(*pp)++)
+ {
+ case VISIBILITY_PRIVATE:
+ new_sublist->fn_field.is_private = 1;
+ break;
+ case VISIBILITY_PROTECTED:
+ new_sublist->fn_field.is_protected = 1;
+ break;
+ }
+
+ STABS_CONTINUE (pp, objfile);
+ switch (**pp)
+ {
+ case 'A': /* Normal functions. */
+ new_sublist->fn_field.is_const = 0;
+ new_sublist->fn_field.is_volatile = 0;
+ (*pp)++;
+ break;
+ case 'B': /* `const' member functions. */
+ new_sublist->fn_field.is_const = 1;
+ new_sublist->fn_field.is_volatile = 0;
+ (*pp)++;
+ break;
+ case 'C': /* `volatile' member function. */
+ new_sublist->fn_field.is_const = 0;
+ new_sublist->fn_field.is_volatile = 1;
+ (*pp)++;
+ break;
+ case 'D': /* `const volatile' member function. */
+ new_sublist->fn_field.is_const = 1;
+ new_sublist->fn_field.is_volatile = 1;
+ (*pp)++;
+ break;
+ case '*': /* File compiled with g++ version 1 -- no info */
+ case '?':
+ case '.':
+ break;
+ default:
+ complain (&const_vol_complaint, **pp);
+ break;
+ }
+
+ switch (*(*pp)++)
+ {
+ case '*':
+ {
+ int nbits;
+ /* virtual member function, followed by index.
+ The sign bit is set to distinguish pointers-to-methods
+ from virtual function indicies. Since the array is
+ in words, the quantity must be shifted left by 1
+ on 16 bit machine, and by 2 on 32 bit machine, forcing
+ the sign bit out, and usable as a valid index into
+ the array. Remove the sign bit here. */
+ new_sublist->fn_field.voffset =
+ (0x7fffffff & read_huge_number (pp, ';', &nbits)) + 2;
+ if (nbits != 0)
+ return 0;
+
+ STABS_CONTINUE (pp, objfile);
+ if (**pp == ';' || **pp == '\0')
+ {
+ /* Must be g++ version 1. */
+ new_sublist->fn_field.fcontext = 0;
+ }
+ else
+ {
+ /* Figure out from whence this virtual function came.
+ It may belong to virtual function table of
+ one of its baseclasses. */
+ look_ahead_type = read_type (pp, objfile);
+ if (**pp == ':')
+ {
+ /* g++ version 1 overloaded methods. */
+ }
+ else
+ {
+ new_sublist->fn_field.fcontext = look_ahead_type;
+ if (**pp != ';')
+ {
+ return 0;
+ }
+ else
+ {
+ ++*pp;
+ }
+ look_ahead_type = NULL;
+ }
+ }
+ break;
+ }
+ case '?':
+ /* static member function. */
+ {
+ int slen = strlen (main_fn_name);
+
+ new_sublist->fn_field.voffset = VOFFSET_STATIC;
+
+ /* For static member functions, we can't tell if they
+ are stubbed, as they are put out as functions, and not as
+ methods.
+ GCC v2 emits the fully mangled name if
+ dbxout.c:flag_minimal_debug is not set, so we have to
+ detect a fully mangled physname here and set is_stub
+ accordingly. Fully mangled physnames in v2 start with
+ the member function name, followed by two underscores.
+ GCC v3 currently always emits stubbed member functions,
+ but with fully mangled physnames, which start with _Z. */
+ if (!(strncmp (new_sublist->fn_field.physname,
+ main_fn_name, slen) == 0
+ && new_sublist->fn_field.physname[slen] == '_'
+ && new_sublist->fn_field.physname[slen + 1] == '_'))
+ {
+ new_sublist->fn_field.is_stub = 1;
+ }
+ break;
+ }
+
+ default:
+ /* error */
+ complain (&member_fn_complaint, (*pp)[-1]);
+ /* Fall through into normal member function. */
+
+ case '.':
+ /* normal member function. */
+ new_sublist->fn_field.voffset = 0;
+ new_sublist->fn_field.fcontext = 0;
+ break;
+ }
+
+ new_sublist->next = sublist;
+ sublist = new_sublist;
+ length++;
+ STABS_CONTINUE (pp, objfile);
+ }
+ while (**pp != ';' && **pp != '\0');
+
+ (*pp)++;
+ STABS_CONTINUE (pp, objfile);
+
+ /* Skip GCC 3.X member functions which are duplicates of the callable
+ constructor/destructor. */
+ if (strcmp (main_fn_name, "__base_ctor") == 0
+ || strcmp (main_fn_name, "__base_dtor") == 0
+ || strcmp (main_fn_name, "__deleting_dtor") == 0)
+ {
+ xfree (main_fn_name);
+ }
+ else
+ {
+ new_fnlist->fn_fieldlist.fn_fields = (struct fn_field *)
+ obstack_alloc (&objfile->type_obstack,
+ sizeof (struct fn_field) * length);
+ memset (new_fnlist->fn_fieldlist.fn_fields, 0,
+ sizeof (struct fn_field) * length);
+ for (i = length; (i--, sublist); sublist = sublist->next)
+ {
+ new_fnlist->fn_fieldlist.fn_fields[i] = sublist->fn_field;
+ }
+
+ new_fnlist->fn_fieldlist.length = length;
+ new_fnlist->next = fip->fnlist;
+ fip->fnlist = new_fnlist;
+ nfn_fields++;
+ total_length += length;
+ }
+ }
+
+ if (nfn_fields)
+ {
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
+ TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * nfn_fields);
+ memset (TYPE_FN_FIELDLISTS (type), 0,
+ sizeof (struct fn_fieldlist) * nfn_fields);
+ TYPE_NFN_FIELDS (type) = nfn_fields;
+ TYPE_NFN_FIELDS_TOTAL (type) = total_length;
+ }
+
+ return 1;
+}
+
+/* Special GNU C++ name.
+
+ Returns 1 for success, 0 for failure. "failure" means that we can't
+ keep parsing and it's time for error_type(). */
+
+static int
+read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type,
+ struct objfile *objfile)
+{
+ register char *p;
+ char *name;
+ char cpp_abbrev;
+ struct type *context;
+
+ p = *pp;
+ if (*++p == 'v')
+ {
+ name = NULL;
+ cpp_abbrev = *++p;
+
+ *pp = p + 1;
+
+ /* At this point, *pp points to something like "22:23=*22...",
+ where the type number before the ':' is the "context" and
+ everything after is a regular type definition. Lookup the
+ type, find it's name, and construct the field name. */
+
+ context = read_type (pp, objfile);
+
+ switch (cpp_abbrev)
+ {
+ case 'f': /* $vf -- a virtual function table pointer */
+ name = type_name_no_tag (context);
+ if (name == NULL)
+ {
+ name = "";
+ }
+ fip->list->field.name =
+ obconcat (&objfile->type_obstack, vptr_name, name, "");
+ break;
+
+ case 'b': /* $vb -- a virtual bsomethingorother */
+ name = type_name_no_tag (context);
+ if (name == NULL)
+ {
+ complain (&invalid_cpp_type_complaint, symnum);
+ name = "FOO";
+ }
+ fip->list->field.name =
+ obconcat (&objfile->type_obstack, vb_name, name, "");
+ break;
+
+ default:
+ complain (&invalid_cpp_abbrev_complaint, *pp);
+ fip->list->field.name =
+ obconcat (&objfile->type_obstack,
+ "INVALID_CPLUSPLUS_ABBREV", "", "");
+ break;
+ }
+
+ /* At this point, *pp points to the ':'. Skip it and read the
+ field type. */
+
+ p = ++(*pp);
+ if (p[-1] != ':')
+ {
+ complain (&invalid_cpp_abbrev_complaint, *pp);
+ return 0;
+ }
+ fip->list->field.type = read_type (pp, objfile);
+ if (**pp == ',')
+ (*pp)++; /* Skip the comma. */
+ else
+ return 0;
+
+ {
+ int nbits;
+ FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ';', &nbits);
+ if (nbits != 0)
+ return 0;
+ }
+ /* This field is unpacked. */
+ FIELD_BITSIZE (fip->list->field) = 0;
+ fip->list->visibility = VISIBILITY_PRIVATE;
+ }
+ else
+ {
+ complain (&invalid_cpp_abbrev_complaint, *pp);
+ /* We have no idea what syntax an unrecognized abbrev would have, so
+ better return 0. If we returned 1, we would need to at least advance
+ *pp to avoid an infinite loop. */
+ return 0;
+ }
+ return 1;
+}
+
+static void
+read_one_struct_field (struct field_info *fip, char **pp, char *p,
+ struct type *type, struct objfile *objfile)
+{
+ /* The following is code to work around cfront generated stabs.
+ The stabs contains full mangled name for each field.
+ We try to demangle the name and extract the field name out of it.
+ */
+ if (ARM_DEMANGLING && current_subfile->language == language_cplus)
+ {
+ char save_p;
+ char *dem, *dem_p;
+ save_p = *p;
+ *p = '\0';
+ dem = cplus_demangle (*pp, DMGL_ANSI | DMGL_PARAMS);
+ if (dem != NULL)
+ {
+ dem_p = strrchr (dem, ':');
+ if (dem_p != 0 && *(dem_p - 1) == ':')
+ dem_p++;
+ FIELD_NAME (fip->list->field) =
+ obsavestring (dem_p, strlen (dem_p), &objfile->type_obstack);
+ }
+ else
+ {
+ FIELD_NAME (fip->list->field) =
+ obsavestring (*pp, p - *pp, &objfile->type_obstack);
+ }
+ *p = save_p;
+ }
+ /* end of code for cfront work around */
+
+ else
+ fip->list->field.name =
+ obsavestring (*pp, p - *pp, &objfile->type_obstack);
+ *pp = p + 1;
+
+ /* This means we have a visibility for a field coming. */
+ if (**pp == '/')
+ {
+ (*pp)++;
+ fip->list->visibility = *(*pp)++;
+ }
+ else
+ {
+ /* normal dbx-style format, no explicit visibility */
+ fip->list->visibility = VISIBILITY_PUBLIC;
+ }
+
+ fip->list->field.type = read_type (pp, objfile);
+ if (**pp == ':')
+ {
+ p = ++(*pp);
+#if 0
+ /* Possible future hook for nested types. */
+ if (**pp == '!')
+ {
+ fip->list->field.bitpos = (long) -2; /* nested type */
+ p = ++(*pp);
+ }
+ else
+ ...;
+#endif
+ while (*p != ';')
+ {
+ p++;
+ }
+ /* Static class member. */
+ SET_FIELD_PHYSNAME (fip->list->field, savestring (*pp, p - *pp));
+ *pp = p + 1;
+ return;
+ }
+ else if (**pp != ',')
+ {
+ /* Bad structure-type format. */
+ complain (&stabs_general_complaint, "bad structure-type format");
+ return;
+ }
+
+ (*pp)++; /* Skip the comma. */
+
+ {
+ int nbits;
+ FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ',', &nbits);
+ if (nbits != 0)
+ {
+ complain (&stabs_general_complaint, "bad structure-type format");
+ return;
+ }
+ FIELD_BITSIZE (fip->list->field) = read_huge_number (pp, ';', &nbits);
+ if (nbits != 0)
+ {
+ complain (&stabs_general_complaint, "bad structure-type format");
+ return;
+ }
+ }
+
+ if (FIELD_BITPOS (fip->list->field) == 0
+ && FIELD_BITSIZE (fip->list->field) == 0)
+ {
+ /* This can happen in two cases: (1) at least for gcc 2.4.5 or so,
+ it is a field which has been optimized out. The correct stab for
+ this case is to use VISIBILITY_IGNORE, but that is a recent
+ invention. (2) It is a 0-size array. For example
+ union { int num; char str[0]; } foo. Printing "<no value>" for
+ str in "p foo" is OK, since foo.str (and thus foo.str[3])
+ will continue to work, and a 0-size array as a whole doesn't
+ have any contents to print.
+
+ I suspect this probably could also happen with gcc -gstabs (not
+ -gstabs+) for static fields, and perhaps other C++ extensions.
+ Hopefully few people use -gstabs with gdb, since it is intended
+ for dbx compatibility. */
+
+ /* Ignore this field. */
+ fip->list->visibility = VISIBILITY_IGNORE;
+ }
+ else
+ {
+ /* Detect an unpacked field and mark it as such.
+ dbx gives a bit size for all fields.
+ Note that forward refs cannot be packed,
+ and treat enums as if they had the width of ints. */
+
+ struct type *field_type = check_typedef (FIELD_TYPE (fip->list->field));
+
+ if (TYPE_CODE (field_type) != TYPE_CODE_INT
+ && TYPE_CODE (field_type) != TYPE_CODE_RANGE
+ && TYPE_CODE (field_type) != TYPE_CODE_BOOL
+ && TYPE_CODE (field_type) != TYPE_CODE_ENUM)
+ {
+ FIELD_BITSIZE (fip->list->field) = 0;
+ }
+ if ((FIELD_BITSIZE (fip->list->field)
+ == TARGET_CHAR_BIT * TYPE_LENGTH (field_type)
+ || (TYPE_CODE (field_type) == TYPE_CODE_ENUM
+ && FIELD_BITSIZE (fip->list->field) == TARGET_INT_BIT)
+ )
+ &&
+ FIELD_BITPOS (fip->list->field) % 8 == 0)
+ {
+ FIELD_BITSIZE (fip->list->field) = 0;
+ }
+ }
+}
+
+
+/* Read struct or class data fields. They have the form:
+
+ NAME : [VISIBILITY] TYPENUM , BITPOS , BITSIZE ;
+
+ At the end, we see a semicolon instead of a field.
+
+ In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for
+ a static field.
+
+ The optional VISIBILITY is one of:
+
+ '/0' (VISIBILITY_PRIVATE)
+ '/1' (VISIBILITY_PROTECTED)
+ '/2' (VISIBILITY_PUBLIC)
+ '/9' (VISIBILITY_IGNORE)
+
+ or nothing, for C style fields with public visibility.
+
+ Returns 1 for success, 0 for failure. */
+
+static int
+read_struct_fields (struct field_info *fip, char **pp, struct type *type,
+ struct objfile *objfile)
+{
+ register char *p;
+ struct nextfield *new;
+
+ /* We better set p right now, in case there are no fields at all... */
+
+ p = *pp;
+
+ /* Read each data member type until we find the terminating ';' at the end of
+ the data member list, or break for some other reason such as finding the
+ start of the member function list. */
+ /* Stab string for structure/union does not end with two ';' in
+ SUN C compiler 5.3 i.e. F6U2, hence check for end of string. */
+
+ while (**pp != ';' && **pp != '\0')
+ {
+ if (os9k_stabs && **pp == ',')
+ break;
+ STABS_CONTINUE (pp, objfile);
+ /* Get space to record the next field's data. */
+ new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+ make_cleanup (xfree, new);
+ memset (new, 0, sizeof (struct nextfield));
+ new->next = fip->list;
+ fip->list = new;
+
+ /* Get the field name. */
+ p = *pp;
+
+ /* If is starts with CPLUS_MARKER it is a special abbreviation,
+ unless the CPLUS_MARKER is followed by an underscore, in
+ which case it is just the name of an anonymous type, which we
+ should handle like any other type name. */
+
+ if (is_cplus_marker (p[0]) && p[1] != '_')
+ {
+ if (!read_cpp_abbrev (fip, pp, type, objfile))
+ return 0;
+ continue;
+ }
+
+ /* Look for the ':' that separates the field name from the field
+ values. Data members are delimited by a single ':', while member
+ functions are delimited by a pair of ':'s. When we hit the member
+ functions (if any), terminate scan loop and return. */
+
+ while (*p != ':' && *p != '\0')
+ {
+ p++;
+ }
+ if (*p == '\0')
+ return 0;
+
+ /* Check to see if we have hit the member functions yet. */
+ if (p[1] == ':')
+ {
+ break;
+ }
+ read_one_struct_field (fip, pp, p, type, objfile);
+ }
+ if (p[0] == ':' && p[1] == ':')
+ {
+ /* chill the list of fields: the last entry (at the head) is a
+ partially constructed entry which we now scrub. */
+ fip->list = fip->list->next;
+ }
+ return 1;
+}
+/* *INDENT-OFF* */
+/* The stabs for C++ derived classes contain baseclass information which
+ is marked by a '!' character after the total size. This function is
+ called when we encounter the baseclass marker, and slurps up all the
+ baseclass information.
+
+ Immediately following the '!' marker is the number of base classes that
+ the class is derived from, followed by information for each base class.
+ For each base class, there are two visibility specifiers, a bit offset
+ to the base class information within the derived class, a reference to
+ the type for the base class, and a terminating semicolon.
+
+ A typical example, with two base classes, would be "!2,020,19;0264,21;".
+ ^^ ^ ^ ^ ^ ^ ^
+ Baseclass information marker __________________|| | | | | | |
+ Number of baseclasses __________________________| | | | | | |
+ Visibility specifiers (2) ________________________| | | | | |
+ Offset in bits from start of class _________________| | | | |
+ Type number for base class ___________________________| | | |
+ Visibility specifiers (2) _______________________________| | |
+ Offset in bits from start of class ________________________| |
+ Type number of base class ____________________________________|
+
+ Return 1 for success, 0 for (error-type-inducing) failure. */
+/* *INDENT-ON* */
+
+
+
+static int
+read_baseclasses (struct field_info *fip, char **pp, struct type *type,
+ struct objfile *objfile)
+{
+ int i;
+ struct nextfield *new;
+
+ if (**pp != '!')
+ {
+ return 1;
+ }
+ else
+ {
+ /* Skip the '!' baseclass information marker. */
+ (*pp)++;
+ }
+
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ {
+ int nbits;
+ TYPE_N_BASECLASSES (type) = read_huge_number (pp, ',', &nbits);
+ if (nbits != 0)
+ return 0;
+ }
+
+#if 0
+ /* Some stupid compilers have trouble with the following, so break
+ it up into simpler expressions. */
+ TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *)
+ TYPE_ALLOC (type, B_BYTES (TYPE_N_BASECLASSES (type)));
+#else
+ {
+ int num_bytes = B_BYTES (TYPE_N_BASECLASSES (type));
+ char *pointer;
+
+ pointer = (char *) TYPE_ALLOC (type, num_bytes);
+ TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer;
+ }
+#endif /* 0 */
+
+ B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type));
+
+ for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
+ {
+ new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+ make_cleanup (xfree, new);
+ memset (new, 0, sizeof (struct nextfield));
+ new->next = fip->list;
+ fip->list = new;
+ FIELD_BITSIZE (new->field) = 0; /* this should be an unpacked field! */
+
+ STABS_CONTINUE (pp, objfile);
+ switch (**pp)
+ {
+ case '0':
+ /* Nothing to do. */
+ break;
+ case '1':
+ SET_TYPE_FIELD_VIRTUAL (type, i);
+ break;
+ default:
+ /* Unknown character. Complain and treat it as non-virtual. */
+ {
+ static struct complaint msg =
+ {
+ "Unknown virtual character `%c' for baseclass", 0, 0};
+ complain (&msg, **pp);
+ }
+ }
+ ++(*pp);
+
+ new->visibility = *(*pp)++;
+ switch (new->visibility)
+ {
+ case VISIBILITY_PRIVATE:
+ case VISIBILITY_PROTECTED:
+ case VISIBILITY_PUBLIC:
+ break;
+ default:
+ /* Bad visibility format. Complain and treat it as
+ public. */
+ {
+ static struct complaint msg =
+ {
+ "Unknown visibility `%c' for baseclass", 0, 0
+ };
+ complain (&msg, new->visibility);
+ new->visibility = VISIBILITY_PUBLIC;
+ }
+ }
+
+ {
+ int nbits;
+
+ /* The remaining value is the bit offset of the portion of the object
+ corresponding to this baseclass. Always zero in the absence of
+ multiple inheritance. */
+
+ FIELD_BITPOS (new->field) = read_huge_number (pp, ',', &nbits);
+ if (nbits != 0)
+ return 0;
+ }
+
+ /* The last piece of baseclass information is the type of the
+ base class. Read it, and remember it's type name as this
+ field's name. */
+
+ new->field.type = read_type (pp, objfile);
+ new->field.name = type_name_no_tag (new->field.type);
+
+ /* skip trailing ';' and bump count of number of fields seen */
+ if (**pp == ';')
+ (*pp)++;
+ else
+ return 0;
+ }
+ return 1;
+}
+
+/* The tail end of stabs for C++ classes that contain a virtual function
+ pointer contains a tilde, a %, and a type number.
+ The type number refers to the base class (possibly this class itself) which
+ contains the vtable pointer for the current class.
+
+ This function is called when we have parsed all the method declarations,
+ so we can look for the vptr base class info. */
+
+static int
+read_tilde_fields (struct field_info *fip, char **pp, struct type *type,
+ struct objfile *objfile)
+{
+ register char *p;
+
+ STABS_CONTINUE (pp, objfile);
+
+ /* If we are positioned at a ';', then skip it. */
+ if (**pp == ';')
+ {
+ (*pp)++;
+ }
+
+ if (**pp == '~')
+ {
+ (*pp)++;
+
+ if (**pp == '=' || **pp == '+' || **pp == '-')
+ {
+ /* Obsolete flags that used to indicate the presence
+ of constructors and/or destructors. */
+ (*pp)++;
+ }
+
+ /* Read either a '%' or the final ';'. */
+ if (*(*pp)++ == '%')
+ {
+ /* The next number is the type number of the base class
+ (possibly our own class) which supplies the vtable for
+ this class. Parse it out, and search that class to find
+ its vtable pointer, and install those into TYPE_VPTR_BASETYPE
+ and TYPE_VPTR_FIELDNO. */
+
+ struct type *t;
+ int i;
+
+ t = read_type (pp, objfile);
+ p = (*pp)++;
+ while (*p != '\0' && *p != ';')
+ {
+ p++;
+ }
+ if (*p == '\0')
+ {
+ /* Premature end of symbol. */
+ return 0;
+ }
+
+ TYPE_VPTR_BASETYPE (type) = t;
+ if (type == t) /* Our own class provides vtbl ptr */
+ {
+ for (i = TYPE_NFIELDS (t) - 1;
+ i >= TYPE_N_BASECLASSES (t);
+ --i)
+ {
+ if (!strncmp (TYPE_FIELD_NAME (t, i), vptr_name,
+ sizeof (vptr_name) - 1))
+ {
+ TYPE_VPTR_FIELDNO (type) = i;
+ goto gotit;
+ }
+ }
+ /* Virtual function table field not found. */
+ complain (&vtbl_notfound_complaint, TYPE_NAME (type));
+ return 0;
+ }
+ else
+ {
+ TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t);
+ }
+
+ gotit:
+ *pp = p + 1;
+ }
+ }
+ return 1;
+}
+
+static int
+attach_fn_fields_to_type (struct field_info *fip, register struct type *type)
+{
+ register int n;
+
+ for (n = TYPE_NFN_FIELDS (type);
+ fip->fnlist != NULL;
+ fip->fnlist = fip->fnlist->next)
+ {
+ --n; /* Circumvent Sun3 compiler bug */
+ TYPE_FN_FIELDLISTS (type)[n] = fip->fnlist->fn_fieldlist;
+ }
+ return 1;
+}
+
+/* read cfront class static data.
+ pp points to string starting with the list of static data
+ eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;;
+ ^^^^^^^^
+
+ A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;;
+ ^
+ */
+
+static int
+read_cfront_static_fields (struct field_info *fip, char **pp, struct type *type,
+ struct objfile *objfile)
+{
+ struct nextfield *new;
+ struct type *stype;
+ char *sname;
+ struct symbol *ref_static = 0;
+
+ if (**pp == ';') /* no static data; return */
+ {
+ ++(*pp);
+ return 1;
+ }
+
+ /* Process each field in the list until we find the terminating ";" */
+
+ /* eg: p = "as__1A ;;;" */
+ STABS_CONTINUE (pp, objfile); /* handle \\ */
+ while (**pp != ';' && (sname = get_substring (pp, ' '), sname))
+ {
+ ref_static = lookup_symbol (sname, 0, VAR_NAMESPACE, 0, 0); /*demangled_name */
+ if (!ref_static)
+ {
+ static struct complaint msg =
+ {"\
+ Unable to find symbol for static data field %s\n",
+ 0, 0};
+ complain (&msg, sname);
+ continue;
+ }
+ stype = SYMBOL_TYPE (ref_static);
+
+ /* allocate a new fip */
+ new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+ make_cleanup (xfree, new);
+ memset (new, 0, sizeof (struct nextfield));
+ new->next = fip->list;
+ fip->list = new;
+
+ /* set visibility */
+ /* FIXME! no way to tell visibility from stabs??? */
+ new->visibility = VISIBILITY_PUBLIC;
+
+ /* set field info into fip */
+ fip->list->field.type = stype;
+
+ /* set bitpos & bitsize */
+ SET_FIELD_PHYSNAME (fip->list->field, savestring (sname, strlen (sname)));
+
+ /* set name field */
+ /* The following is code to work around cfront generated stabs.
+ The stabs contains full mangled name for each field.
+ We try to demangle the name and extract the field name out of it.
+ */
+ if (ARM_DEMANGLING)
+ {
+ char *dem, *dem_p;
+ dem = cplus_demangle (sname, DMGL_ANSI | DMGL_PARAMS);
+ if (dem != NULL)
+ {
+ dem_p = strrchr (dem, ':');
+ if (dem_p != 0 && *(dem_p - 1) == ':')
+ dem_p++;
+ fip->list->field.name =
+ obsavestring (dem_p, strlen (dem_p), &objfile->type_obstack);
+ }
+ else
+ {
+ fip->list->field.name =
+ obsavestring (sname, strlen (sname), &objfile->type_obstack);
+ }
+ } /* end of code for cfront work around */
+ } /* loop again for next static field */
+ return 1;
+}
+
+/* Copy structure fields to fip so attach_fields_to_type will work.
+ type has already been created with the initial instance data fields.
+ Now we want to be able to add the other members to the class,
+ so we want to add them back to the fip and reattach them again
+ once we have collected all the class members. */
+
+static int
+copy_cfront_struct_fields (struct field_info *fip, struct type *type,
+ struct objfile *objfile)
+{
+ int nfields = TYPE_NFIELDS (type);
+ int i;
+ struct nextfield *new;
+
+ /* Copy the fields into the list of fips and reset the types
+ to remove the old fields */
+
+ for (i = 0; i < nfields; i++)
+ {
+ /* allocate a new fip */
+ new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+ make_cleanup (xfree, new);
+ memset (new, 0, sizeof (struct nextfield));
+ new->next = fip->list;
+ fip->list = new;
+
+ /* copy field info into fip */
+ new->field = TYPE_FIELD (type, i);
+ /* set visibility */
+ if (TYPE_FIELD_PROTECTED (type, i))
+ new->visibility = VISIBILITY_PROTECTED;
+ else if (TYPE_FIELD_PRIVATE (type, i))
+ new->visibility = VISIBILITY_PRIVATE;
+ else
+ new->visibility = VISIBILITY_PUBLIC;
+ }
+ /* Now delete the fields from the type since we will be
+ allocing new space once we get the rest of the fields
+ in attach_fields_to_type.
+ The pointer TYPE_FIELDS(type) is left dangling but should
+ be freed later by objstack_free */
+ TYPE_FIELDS (type) = 0;
+ TYPE_NFIELDS (type) = 0;
+
+ return 1;
+}
+
+/* Create the vector of fields, and record how big it is.
+ We need this info to record proper virtual function table information
+ for this class's virtual functions. */
+
+static int
+attach_fields_to_type (struct field_info *fip, register struct type *type,
+ struct objfile *objfile)
+{
+ register int nfields = 0;
+ register int non_public_fields = 0;
+ register struct nextfield *scan;
+
+ /* Count up the number of fields that we have, as well as taking note of
+ whether or not there are any non-public fields, which requires us to
+ allocate and build the private_field_bits and protected_field_bits
+ bitfields. */
+
+ for (scan = fip->list; scan != NULL; scan = scan->next)
+ {
+ nfields++;
+ if (scan->visibility != VISIBILITY_PUBLIC)
+ {
+ non_public_fields++;
+ }
+ }
+
+ /* Now we know how many fields there are, and whether or not there are any
+ non-public fields. Record the field count, allocate space for the
+ array of fields, and create blank visibility bitfields if necessary. */
+
+ TYPE_NFIELDS (type) = nfields;
+ TYPE_FIELDS (type) = (struct field *)
+ TYPE_ALLOC (type, sizeof (struct field) * nfields);
+ memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
+
+ if (non_public_fields)
+ {
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+
+ TYPE_FIELD_PRIVATE_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
+
+ TYPE_FIELD_PROTECTED_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
+
+ TYPE_FIELD_IGNORE_BITS (type) =
+ (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+ B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
+ }
+
+ /* Copy the saved-up fields into the field vector. Start from the head
+ of the list, adding to the tail of the field array, so that they end
+ up in the same order in the array in which they were added to the list. */
+
+ while (nfields-- > 0)
+ {
+ TYPE_FIELD (type, nfields) = fip->list->field;
+ switch (fip->list->visibility)
+ {
+ case VISIBILITY_PRIVATE:
+ SET_TYPE_FIELD_PRIVATE (type, nfields);
+ break;
+
+ case VISIBILITY_PROTECTED:
+ SET_TYPE_FIELD_PROTECTED (type, nfields);
+ break;
+
+ case VISIBILITY_IGNORE:
+ SET_TYPE_FIELD_IGNORE (type, nfields);
+ break;
+
+ case VISIBILITY_PUBLIC:
+ break;
+
+ default:
+ /* Unknown visibility. Complain and treat it as public. */
+ {
+ static struct complaint msg =
+ {
+ "Unknown visibility `%c' for field", 0, 0};
+ complain (&msg, fip->list->visibility);
+ }
+ break;
+ }
+ fip->list = fip->list->next;
+ }
+ return 1;
+}
+
+
+static struct complaint multiply_defined_struct =
+{"struct/union type gets multiply defined: %s%s", 0, 0};
+
+
+/* Complain that the compiler has emitted more than one definition for the
+ structure type TYPE. */
+static void
+complain_about_struct_wipeout (struct type *type)
+{
+ char *name = "";
+ char *kind = "";
+
+ if (TYPE_TAG_NAME (type))
+ {
+ name = TYPE_TAG_NAME (type);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_STRUCT: kind = "struct "; break;
+ case TYPE_CODE_UNION: kind = "union "; break;
+ case TYPE_CODE_ENUM: kind = "enum "; break;
+ default: kind = "";
+ }
+ }
+ else if (TYPE_NAME (type))
+ {
+ name = TYPE_NAME (type);
+ kind = "";
+ }
+ else
+ {
+ name = "<unknown>";
+ kind = "";
+ }
+
+ complain (&multiply_defined_struct, kind, name);
+}
+
+
+/* Read the description of a structure (or union type) and return an object
+ describing the type.
+
+ PP points to a character pointer that points to the next unconsumed token
+ in the the stabs string. For example, given stabs "A:T4=s4a:1,0,32;;",
+ *PP will point to "4a:1,0,32;;".
+
+ TYPE points to an incomplete type that needs to be filled in.
+
+ OBJFILE points to the current objfile from which the stabs information is
+ being read. (Note that it is redundant in that TYPE also contains a pointer
+ to this same objfile, so it might be a good idea to eliminate it. FIXME).
+ */
+
+static struct type *
+read_struct_type (char **pp, struct type *type, enum type_code type_code,
+ struct objfile *objfile)
+{
+ struct cleanup *back_to;
+ struct field_info fi;
+
+ fi.list = NULL;
+ fi.fnlist = NULL;
+
+ /* When describing struct/union/class types in stabs, G++ always drops
+ all qualifications from the name. So if you've got:
+ struct A { ... struct B { ... }; ... };
+ then G++ will emit stabs for `struct A::B' that call it simply
+ `struct B'. Obviously, if you've got a real top-level definition for
+ `struct B', or other nested definitions, this is going to cause
+ problems.
+
+ Obviously, GDB can't fix this by itself, but it can at least avoid
+ scribbling on existing structure type objects when new definitions
+ appear. */
+ if (! (TYPE_CODE (type) == TYPE_CODE_UNDEF
+ || TYPE_STUB (type)))
+ {
+ complain_about_struct_wipeout (type);
+
+ /* It's probably best to return the type unchanged. */
+ return type;
+ }
+
+ back_to = make_cleanup (null_cleanup, 0);
+
+ INIT_CPLUS_SPECIFIC (type);
+ TYPE_CODE (type) = type_code;
+ TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
+
+ /* First comes the total size in bytes. */
+
+ {
+ int nbits;
+ TYPE_LENGTH (type) = read_huge_number (pp, 0, &nbits);
+ if (nbits != 0)
+ return error_type (pp, objfile);
+ }
+
+ /* Now read the baseclasses, if any, read the regular C struct or C++
+ class member fields, attach the fields to the type, read the C++
+ member functions, attach them to the type, and then read any tilde
+ field (baseclass specifier for the class holding the main vtable). */
+
+ if (!read_baseclasses (&fi, pp, type, objfile)
+ || !read_struct_fields (&fi, pp, type, objfile)
+ || !attach_fields_to_type (&fi, type, objfile)
+ || !read_member_functions (&fi, pp, type, objfile)
+ || !attach_fn_fields_to_type (&fi, type)
+ || !read_tilde_fields (&fi, pp, type, objfile))
+ {
+ type = error_type (pp, objfile);
+ }
+
+ do_cleanups (back_to);
+ return (type);
+}
+
+/* Read a definition of an array type,
+ and create and return a suitable type object.
+ Also creates a range type which represents the bounds of that
+ array. */
+
+static struct type *
+read_array_type (register char **pp, register struct type *type,
+ struct objfile *objfile)
+{
+ struct type *index_type, *element_type, *range_type;
+ int lower, upper;
+ int adjustable = 0;
+ int nbits;
+
+ /* Format of an array type:
+ "ar<index type>;lower;upper;<array_contents_type>".
+ OS9000: "arlower,upper;<array_contents_type>".
+
+ Fortran adjustable arrays use Adigits or Tdigits for lower or upper;
+ for these, produce a type like float[][]. */
+
+ if (os9k_stabs)
+ index_type = builtin_type_int;
+ else
+ {
+ index_type = read_type (pp, objfile);
+ if (**pp != ';')
+ /* Improper format of array type decl. */
+ return error_type (pp, objfile);
+ ++*pp;
+ }
+
+ if (!(**pp >= '0' && **pp <= '9') && **pp != '-')
+ {
+ (*pp)++;
+ adjustable = 1;
+ }
+ lower = read_huge_number (pp, os9k_stabs ? ',' : ';', &nbits);
+ if (nbits != 0)
+ return error_type (pp, objfile);
+
+ if (!(**pp >= '0' && **pp <= '9') && **pp != '-')
+ {
+ (*pp)++;
+ adjustable = 1;
+ }
+ upper = read_huge_number (pp, ';', &nbits);
+ if (nbits != 0)
+ return error_type (pp, objfile);
+
+ element_type = read_type (pp, objfile);
+
+ if (adjustable)
+ {
+ lower = 0;
+ upper = -1;
+ }
+
+ range_type =
+ create_range_type ((struct type *) NULL, index_type, lower, upper);
+ type = create_array_type (type, element_type, range_type);
+
+ return type;
+}
+
+
+/* Read a definition of an enumeration type,
+ and create and return a suitable type object.
+ Also defines the symbols that represent the values of the type. */
+
+static struct type *
+read_enum_type (register char **pp, register struct type *type,
+ struct objfile *objfile)
+{
+ register char *p;
+ char *name;
+ register long n;
+ register struct symbol *sym;
+ int nsyms = 0;
+ struct pending **symlist;
+ struct pending *osyms, *syms;
+ int o_nsyms;
+ int nbits;
+ int unsigned_enum = 1;
+
+#if 0
+ /* FIXME! The stabs produced by Sun CC merrily define things that ought
+ to be file-scope, between N_FN entries, using N_LSYM. What's a mother
+ to do? For now, force all enum values to file scope. */
+ if (within_function)
+ symlist = &local_symbols;
+ else
+#endif
+ symlist = &file_symbols;
+ osyms = *symlist;
+ o_nsyms = osyms ? osyms->nsyms : 0;
+
+ if (os9k_stabs)
+ {
+ /* Size. Perhaps this does not have to be conditionalized on
+ os9k_stabs (assuming the name of an enum constant can't start
+ with a digit). */
+ read_huge_number (pp, 0, &nbits);
+ if (nbits != 0)
+ return error_type (pp, objfile);
+ }
+
+ /* The aix4 compiler emits an extra field before the enum members;
+ my guess is it's a type of some sort. Just ignore it. */
+ if (**pp == '-')
+ {
+ /* Skip over the type. */
+ while (**pp != ':')
+ (*pp)++;
+
+ /* Skip over the colon. */
+ (*pp)++;
+ }
+
+ /* Read the value-names and their values.
+ The input syntax is NAME:VALUE,NAME:VALUE, and so on.
+ A semicolon or comma instead of a NAME means the end. */
+ while (**pp && **pp != ';' && **pp != ',')
+ {
+ STABS_CONTINUE (pp, objfile);
+ p = *pp;
+ while (*p != ':')
+ p++;
+ name = obsavestring (*pp, p - *pp, &objfile->symbol_obstack);
+ *pp = p + 1;
+ n = read_huge_number (pp, ',', &nbits);
+ if (nbits != 0)
+ return error_type (pp, objfile);
+
+ sym = (struct symbol *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_NAME (sym) = name;
+ SYMBOL_LANGUAGE (sym) = current_subfile->language;
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_VALUE (sym) = n;
+ if (n < 0)
+ unsigned_enum = 0;
+ add_symbol_to_list (sym, symlist);
+ nsyms++;
+ }
+
+ if (**pp == ';')
+ (*pp)++; /* Skip the semicolon. */
+
+ /* Now fill in the fields of the type-structure. */
+
+ TYPE_LENGTH (type) = TARGET_INT_BIT / HOST_CHAR_BIT;
+ TYPE_CODE (type) = TYPE_CODE_ENUM;
+ TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
+ if (unsigned_enum)
+ TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+ TYPE_NFIELDS (type) = nsyms;
+ TYPE_FIELDS (type) = (struct field *)
+ TYPE_ALLOC (type, sizeof (struct field) * nsyms);
+ memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nsyms);
+
+ /* Find the symbols for the values and put them into the type.
+ The symbols can be found in the symlist that we put them on
+ to cause them to be defined. osyms contains the old value
+ of that symlist; everything up to there was defined by us. */
+ /* Note that we preserve the order of the enum constants, so
+ that in something like "enum {FOO, LAST_THING=FOO}" we print
+ FOO, not LAST_THING. */
+
+ for (syms = *symlist, n = nsyms - 1; syms; syms = syms->next)
+ {
+ int last = syms == osyms ? o_nsyms : 0;
+ int j = syms->nsyms;
+ for (; --j >= last; --n)
+ {
+ struct symbol *xsym = syms->symbol[j];
+ SYMBOL_TYPE (xsym) = type;
+ TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+ TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
+ TYPE_FIELD_BITSIZE (type, n) = 0;
+ }
+ if (syms == osyms)
+ break;
+ }
+
+ return type;
+}
+
+/* Sun's ACC uses a somewhat saner method for specifying the builtin
+ typedefs in every file (for int, long, etc):
+
+ type = b <signed> <width> <format type>; <offset>; <nbits>
+ signed = u or s.
+ optional format type = c or b for char or boolean.
+ offset = offset from high order bit to start bit of type.
+ width is # bytes in object of this type, nbits is # bits in type.
+
+ The width/offset stuff appears to be for small objects stored in
+ larger ones (e.g. `shorts' in `int' registers). We ignore it for now,
+ FIXME. */
+
+static struct type *
+read_sun_builtin_type (char **pp, int typenums[2], struct objfile *objfile)
+{
+ int type_bits;
+ int nbits;
+ int signed_type;
+ enum type_code code = TYPE_CODE_INT;
+
+ switch (**pp)
+ {
+ case 's':
+ signed_type = 1;
+ break;
+ case 'u':
+ signed_type = 0;
+ break;
+ default:
+ return error_type (pp, objfile);
+ }
+ (*pp)++;
+
+ /* For some odd reason, all forms of char put a c here. This is strange
+ because no other type has this honor. We can safely ignore this because
+ we actually determine 'char'acterness by the number of bits specified in
+ the descriptor.
+ Boolean forms, e.g Fortran logical*X, put a b here. */
+
+ if (**pp == 'c')
+ (*pp)++;
+ else if (**pp == 'b')
+ {
+ code = TYPE_CODE_BOOL;
+ (*pp)++;
+ }
+
+ /* The first number appears to be the number of bytes occupied
+ by this type, except that unsigned short is 4 instead of 2.
+ Since this information is redundant with the third number,
+ we will ignore it. */
+ read_huge_number (pp, ';', &nbits);
+ if (nbits != 0)
+ return error_type (pp, objfile);
+
+ /* The second number is always 0, so ignore it too. */
+ read_huge_number (pp, ';', &nbits);
+ if (nbits != 0)
+ return error_type (pp, objfile);
+
+ /* The third number is the number of bits for this type. */
+ type_bits = read_huge_number (pp, 0, &nbits);
+ if (nbits != 0)
+ return error_type (pp, objfile);
+ /* The type *should* end with a semicolon. If it are embedded
+ in a larger type the semicolon may be the only way to know where
+ the type ends. If this type is at the end of the stabstring we
+ can deal with the omitted semicolon (but we don't have to like
+ it). Don't bother to complain(), Sun's compiler omits the semicolon
+ for "void". */
+ if (**pp == ';')
+ ++(*pp);
+
+ if (type_bits == 0)
+ return init_type (TYPE_CODE_VOID, 1,
+ signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *) NULL,
+ objfile);
+ else
+ return init_type (code,
+ type_bits / TARGET_CHAR_BIT,
+ signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *) NULL,
+ objfile);
+}
+
+static struct type *
+read_sun_floating_type (char **pp, int typenums[2], struct objfile *objfile)
+{
+ int nbits;
+ int details;
+ int nbytes;
+ struct type *rettype;
+
+ /* The first number has more details about the type, for example
+ FN_COMPLEX. */
+ details = read_huge_number (pp, ';', &nbits);
+ if (nbits != 0)
+ return error_type (pp, objfile);
+
+ /* The second number is the number of bytes occupied by this type */
+ nbytes = read_huge_number (pp, ';', &nbits);
+ if (nbits != 0)
+ return error_type (pp, objfile);
+
+ if (details == NF_COMPLEX || details == NF_COMPLEX16
+ || details == NF_COMPLEX32)
+ {
+ rettype = init_type (TYPE_CODE_COMPLEX, nbytes, 0, NULL, objfile);
+ TYPE_TARGET_TYPE (rettype)
+ = init_type (TYPE_CODE_FLT, nbytes / 2, 0, NULL, objfile);
+ return rettype;
+ }
+
+ return init_type (TYPE_CODE_FLT, nbytes, 0, NULL, objfile);
+}
+
+/* Read a number from the string pointed to by *PP.
+ The value of *PP is advanced over the number.
+ If END is nonzero, the character that ends the
+ number must match END, or an error happens;
+ and that character is skipped if it does match.
+ If END is zero, *PP is left pointing to that character.
+
+ If the number fits in a long, set *BITS to 0 and return the value.
+ If not, set *BITS to be the number of bits in the number and return 0.
+
+ If encounter garbage, set *BITS to -1 and return 0. */
+
+static long
+read_huge_number (char **pp, int end, int *bits)
+{
+ char *p = *pp;
+ int sign = 1;
+ long n = 0;
+ int radix = 10;
+ char overflow = 0;
+ int nbits = 0;
+ int c;
+ long upper_limit;
+
+ if (*p == '-')
+ {
+ sign = -1;
+ p++;
+ }
+
+ /* Leading zero means octal. GCC uses this to output values larger
+ than an int (because that would be hard in decimal). */
+ if (*p == '0')
+ {
+ radix = 8;
+ p++;
+ }
+
+ if (os9k_stabs)
+ upper_limit = ULONG_MAX / radix;
+ else
+ upper_limit = LONG_MAX / radix;
+
+ while ((c = *p++) >= '0' && c < ('0' + radix))
+ {
+ if (n <= upper_limit)
+ {
+ n *= radix;
+ n += c - '0'; /* FIXME this overflows anyway */
+ }
+ else
+ overflow = 1;
+
+ /* This depends on large values being output in octal, which is
+ what GCC does. */
+ if (radix == 8)
+ {
+ if (nbits == 0)
+ {
+ if (c == '0')
+ /* Ignore leading zeroes. */
+ ;
+ else if (c == '1')
+ nbits = 1;
+ else if (c == '2' || c == '3')
+ nbits = 2;
+ else
+ nbits = 3;
+ }
+ else
+ nbits += 3;
+ }
+ }
+ if (end)
+ {
+ if (c && c != end)
+ {
+ if (bits != NULL)
+ *bits = -1;
+ return 0;
+ }
+ }
+ else
+ --p;
+
+ *pp = p;
+ if (overflow)
+ {
+ if (nbits == 0)
+ {
+ /* Large decimal constants are an error (because it is hard to
+ count how many bits are in them). */
+ if (bits != NULL)
+ *bits = -1;
+ return 0;
+ }
+
+ /* -0x7f is the same as 0x80. So deal with it by adding one to
+ the number of bits. */
+ if (sign == -1)
+ ++nbits;
+ if (bits)
+ *bits = nbits;
+ }
+ else
+ {
+ if (bits)
+ *bits = 0;
+ return n * sign;
+ }
+ /* It's *BITS which has the interesting information. */
+ return 0;
+}
+
+static struct type *
+read_range_type (char **pp, int typenums[2], struct objfile *objfile)
+{
+ char *orig_pp = *pp;
+ int rangenums[2];
+ long n2, n3;
+ int n2bits, n3bits;
+ int self_subrange;
+ struct type *result_type;
+ struct type *index_type = NULL;
+
+ /* First comes a type we are a subrange of.
+ In C it is usually 0, 1 or the type being defined. */
+ if (read_type_number (pp, rangenums) != 0)
+ return error_type (pp, objfile);
+ self_subrange = (rangenums[0] == typenums[0] &&
+ rangenums[1] == typenums[1]);
+
+ if (**pp == '=')
+ {
+ *pp = orig_pp;
+ index_type = read_type (pp, objfile);
+ }
+
+ /* A semicolon should now follow; skip it. */
+ if (**pp == ';')
+ (*pp)++;
+
+ /* The remaining two operands are usually lower and upper bounds
+ of the range. But in some special cases they mean something else. */
+ n2 = read_huge_number (pp, ';', &n2bits);
+ n3 = read_huge_number (pp, ';', &n3bits);
+
+ if (n2bits == -1 || n3bits == -1)
+ return error_type (pp, objfile);
+
+ if (index_type)
+ goto handle_true_range;
+
+ /* If limits are huge, must be large integral type. */
+ if (n2bits != 0 || n3bits != 0)
+ {
+ char got_signed = 0;
+ char got_unsigned = 0;
+ /* Number of bits in the type. */
+ int nbits = 0;
+
+ /* Range from 0 to <large number> is an unsigned large integral type. */
+ if ((n2bits == 0 && n2 == 0) && n3bits != 0)
+ {
+ got_unsigned = 1;
+ nbits = n3bits;
+ }
+ /* Range from <large number> to <large number>-1 is a large signed
+ integral type. Take care of the case where <large number> doesn't
+ fit in a long but <large number>-1 does. */
+ else if ((n2bits != 0 && n3bits != 0 && n2bits == n3bits + 1)
+ || (n2bits != 0 && n3bits == 0
+ && (n2bits == sizeof (long) * HOST_CHAR_BIT)
+ && n3 == LONG_MAX))
+ {
+ got_signed = 1;
+ nbits = n2bits;
+ }
+
+ if (got_signed || got_unsigned)
+ {
+ return init_type (TYPE_CODE_INT, nbits / TARGET_CHAR_BIT,
+ got_unsigned ? TYPE_FLAG_UNSIGNED : 0, NULL,
+ objfile);
+ }
+ else
+ return error_type (pp, objfile);
+ }
+
+ /* A type defined as a subrange of itself, with bounds both 0, is void. */
+ if (self_subrange && n2 == 0 && n3 == 0)
+ return init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile);
+
+ /* If n3 is zero and n2 is positive, we want a floating type, and n2
+ is the width in bytes.
+
+ Fortran programs appear to use this for complex types also. To
+ distinguish between floats and complex, g77 (and others?) seem
+ to use self-subranges for the complexes, and subranges of int for
+ the floats.
+
+ Also note that for complexes, g77 sets n2 to the size of one of
+ the member floats, not the whole complex beast. My guess is that
+ this was to work well with pre-COMPLEX versions of gdb. */
+
+ if (n3 == 0 && n2 > 0)
+ {
+ struct type *float_type
+ = init_type (TYPE_CODE_FLT, n2, 0, NULL, objfile);
+
+ if (self_subrange)
+ {
+ struct type *complex_type =
+ init_type (TYPE_CODE_COMPLEX, 2 * n2, 0, NULL, objfile);
+ TYPE_TARGET_TYPE (complex_type) = float_type;
+ return complex_type;
+ }
+ else
+ return float_type;
+ }
+
+ /* If the upper bound is -1, it must really be an unsigned int. */
+
+ else if (n2 == 0 && n3 == -1)
+ {
+ /* It is unsigned int or unsigned long. */
+ /* GCC 2.3.3 uses this for long long too, but that is just a GDB 3.5
+ compatibility hack. */
+ return init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+ TYPE_FLAG_UNSIGNED, NULL, objfile);
+ }
+
+ /* Special case: char is defined (Who knows why) as a subrange of
+ itself with range 0-127. */
+ else if (self_subrange && n2 == 0 && n3 == 127)
+ return init_type (TYPE_CODE_INT, 1, 0, NULL, objfile);
+
+ else if (current_symbol && SYMBOL_LANGUAGE (current_symbol) == language_chill
+ && !self_subrange)
+ goto handle_true_range;
+
+ /* We used to do this only for subrange of self or subrange of int. */
+ else if (n2 == 0)
+ {
+ /* -1 is used for the upper bound of (4 byte) "unsigned int" and
+ "unsigned long", and we already checked for that,
+ so don't need to test for it here. */
+
+ if (n3 < 0)
+ /* n3 actually gives the size. */
+ return init_type (TYPE_CODE_INT, -n3, TYPE_FLAG_UNSIGNED,
+ NULL, objfile);
+
+ /* Is n3 == 2**(8n)-1 for some integer n? Then it's an
+ unsigned n-byte integer. But do require n to be a power of
+ two; we don't want 3- and 5-byte integers flying around. */
+ {
+ int bytes;
+ unsigned long bits;
+
+ bits = n3;
+ for (bytes = 0; (bits & 0xff) == 0xff; bytes++)
+ bits >>= 8;
+ if (bits == 0
+ && ((bytes - 1) & bytes) == 0) /* "bytes is a power of two" */
+ return init_type (TYPE_CODE_INT, bytes, TYPE_FLAG_UNSIGNED, NULL,
+ objfile);
+ }
+ }
+ /* I think this is for Convex "long long". Since I don't know whether
+ Convex sets self_subrange, I also accept that particular size regardless
+ of self_subrange. */
+ else if (n3 == 0 && n2 < 0
+ && (self_subrange
+ || n2 == -TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT))
+ return init_type (TYPE_CODE_INT, -n2, 0, NULL, objfile);
+ else if (n2 == -n3 - 1)
+ {
+ if (n3 == 0x7f)
+ return init_type (TYPE_CODE_INT, 1, 0, NULL, objfile);
+ if (n3 == 0x7fff)
+ return init_type (TYPE_CODE_INT, 2, 0, NULL, objfile);
+ if (n3 == 0x7fffffff)
+ return init_type (TYPE_CODE_INT, 4, 0, NULL, objfile);
+ }
+
+ /* We have a real range type on our hands. Allocate space and
+ return a real pointer. */
+handle_true_range:
+
+ if (self_subrange)
+ index_type = builtin_type_int;
+ else
+ index_type = *dbx_lookup_type (rangenums);
+ if (index_type == NULL)
+ {
+ /* Does this actually ever happen? Is that why we are worrying
+ about dealing with it rather than just calling error_type? */
+
+ static struct type *range_type_index;
+
+ complain (&range_type_base_complaint, rangenums[1]);
+ if (range_type_index == NULL)
+ range_type_index =
+ init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+ 0, "range type index type", NULL);
+ index_type = range_type_index;
+ }
+
+ result_type = create_range_type ((struct type *) NULL, index_type, n2, n3);
+ return (result_type);
+}
+
+/* Read in an argument list. This is a list of types, separated by commas
+ and terminated with END. Return the list of types read in, or (struct type
+ **)-1 if there is an error. */
+
+static struct type **
+read_args (char **pp, int end, struct objfile *objfile)
+{
+ /* FIXME! Remove this arbitrary limit! */
+ struct type *types[1024], **rval; /* allow for fns of 1023 parameters */
+ int n = 0;
+
+ while (**pp != end)
+ {
+ if (**pp != ',')
+ /* Invalid argument list: no ','. */
+ return (struct type **) -1;
+ (*pp)++;
+ STABS_CONTINUE (pp, objfile);
+ types[n++] = read_type (pp, objfile);
+ }
+ (*pp)++; /* get past `end' (the ':' character) */
+
+ if (n == 1)
+ {
+ rval = (struct type **) xmalloc (2 * sizeof (struct type *));
+ }
+ else if (TYPE_CODE (types[n - 1]) != TYPE_CODE_VOID)
+ {
+ rval = (struct type **) xmalloc ((n + 1) * sizeof (struct type *));
+ memset (rval + n, 0, sizeof (struct type *));
+ }
+ else
+ {
+ rval = (struct type **) xmalloc (n * sizeof (struct type *));
+ }
+ memcpy (rval, types, n * sizeof (struct type *));
+ return rval;
+}
+
+/* Common block handling. */
+
+/* List of symbols declared since the last BCOMM. This list is a tail
+ of local_symbols. When ECOMM is seen, the symbols on the list
+ are noted so their proper addresses can be filled in later,
+ using the common block base address gotten from the assembler
+ stabs. */
+
+static struct pending *common_block;
+static int common_block_i;
+
+/* Name of the current common block. We get it from the BCOMM instead of the
+ ECOMM to match IBM documentation (even though IBM puts the name both places
+ like everyone else). */
+static char *common_block_name;
+
+/* Process a N_BCOMM symbol. The storage for NAME is not guaranteed
+ to remain after this function returns. */
+
+void
+common_block_start (char *name, struct objfile *objfile)
+{
+ if (common_block_name != NULL)
+ {
+ static struct complaint msg =
+ {
+ "Invalid symbol data: common block within common block",
+ 0, 0};
+ complain (&msg);
+ }
+ common_block = local_symbols;
+ common_block_i = local_symbols ? local_symbols->nsyms : 0;
+ common_block_name = obsavestring (name, strlen (name),
+ &objfile->symbol_obstack);
+}
+
+/* Process a N_ECOMM symbol. */
+
+void
+common_block_end (struct objfile *objfile)
+{
+ /* Symbols declared since the BCOMM are to have the common block
+ start address added in when we know it. common_block and
+ common_block_i point to the first symbol after the BCOMM in
+ the local_symbols list; copy the list and hang it off the
+ symbol for the common block name for later fixup. */
+ int i;
+ struct symbol *sym;
+ struct pending *new = 0;
+ struct pending *next;
+ int j;
+
+ if (common_block_name == NULL)
+ {
+ static struct complaint msg =
+ {"ECOMM symbol unmatched by BCOMM", 0, 0};
+ complain (&msg);
+ return;
+ }
+
+ sym = (struct symbol *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
+ /* Note: common_block_name already saved on symbol_obstack */
+ SYMBOL_NAME (sym) = common_block_name;
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+
+ /* Now we copy all the symbols which have been defined since the BCOMM. */
+
+ /* Copy all the struct pendings before common_block. */
+ for (next = local_symbols;
+ next != NULL && next != common_block;
+ next = next->next)
+ {
+ for (j = 0; j < next->nsyms; j++)
+ add_symbol_to_list (next->symbol[j], &new);
+ }
+
+ /* Copy however much of COMMON_BLOCK we need. If COMMON_BLOCK is
+ NULL, it means copy all the local symbols (which we already did
+ above). */
+
+ if (common_block != NULL)
+ for (j = common_block_i; j < common_block->nsyms; j++)
+ add_symbol_to_list (common_block->symbol[j], &new);
+
+ SYMBOL_TYPE (sym) = (struct type *) new;
+
+ /* Should we be putting local_symbols back to what it was?
+ Does it matter? */
+
+ i = hashname (SYMBOL_NAME (sym));
+ SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i];
+ global_sym_chain[i] = sym;
+ common_block_name = NULL;
+}
+
+/* Add a common block's start address to the offset of each symbol
+ declared to be in it (by being between a BCOMM/ECOMM pair that uses
+ the common block name). */
+
+static void
+fix_common_block (struct symbol *sym, int valu)
+{
+ struct pending *next = (struct pending *) SYMBOL_TYPE (sym);
+ for (; next; next = next->next)
+ {
+ register int j;
+ for (j = next->nsyms - 1; j >= 0; j--)
+ SYMBOL_VALUE_ADDRESS (next->symbol[j]) += valu;
+ }
+}
+
+
+
+/* What about types defined as forward references inside of a small lexical
+ scope? */
+/* Add a type to the list of undefined types to be checked through
+ once this file has been read in. */
+
+void
+add_undefined_type (struct type *type)
+{
+ if (undef_types_length == undef_types_allocated)
+ {
+ undef_types_allocated *= 2;
+ undef_types = (struct type **)
+ xrealloc ((char *) undef_types,
+ undef_types_allocated * sizeof (struct type *));
+ }
+ undef_types[undef_types_length++] = type;
+}
+
+/* Go through each undefined type, see if it's still undefined, and fix it
+ up if possible. We have two kinds of undefined types:
+
+ TYPE_CODE_ARRAY: Array whose target type wasn't defined yet.
+ Fix: update array length using the element bounds
+ and the target type's length.
+ TYPE_CODE_STRUCT, TYPE_CODE_UNION: Structure whose fields were not
+ yet defined at the time a pointer to it was made.
+ Fix: Do a full lookup on the struct/union tag. */
+void
+cleanup_undefined_types (void)
+{
+ struct type **type;
+
+ for (type = undef_types; type < undef_types + undef_types_length; type++)
+ {
+ switch (TYPE_CODE (*type))
+ {
+
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_ENUM:
+ {
+ /* Check if it has been defined since. Need to do this here
+ as well as in check_typedef to deal with the (legitimate in
+ C though not C++) case of several types with the same name
+ in different source files. */
+ if (TYPE_STUB (*type))
+ {
+ struct pending *ppt;
+ int i;
+ /* Name of the type, without "struct" or "union" */
+ char *typename = TYPE_TAG_NAME (*type);
+
+ if (typename == NULL)
+ {
+ static struct complaint msg =
+ {"need a type name", 0, 0};
+ complain (&msg);
+ break;
+ }
+ for (ppt = file_symbols; ppt; ppt = ppt->next)
+ {
+ for (i = 0; i < ppt->nsyms; i++)
+ {
+ struct symbol *sym = ppt->symbol[i];
+
+ if (SYMBOL_CLASS (sym) == LOC_TYPEDEF
+ && SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE
+ && (TYPE_CODE (SYMBOL_TYPE (sym)) ==
+ TYPE_CODE (*type))
+ && STREQ (SYMBOL_NAME (sym), typename))
+ replace_type (*type, SYMBOL_TYPE (sym));
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ {
+ static struct complaint msg =
+ {"\
+GDB internal error. cleanup_undefined_types with bad type %d.", 0, 0};
+ complain (&msg, TYPE_CODE (*type));
+ }
+ break;
+ }
+ }
+
+ undef_types_length = 0;
+}
+
+/* Scan through all of the global symbols defined in the object file,
+ assigning values to the debugging symbols that need to be assigned
+ to. Get these symbols from the minimal symbol table. */
+
+void
+scan_file_globals (struct objfile *objfile)
+{
+ int hash;
+ struct minimal_symbol *msymbol;
+ struct symbol *sym, *prev, *rsym;
+ struct objfile *resolve_objfile;
+
+ /* SVR4 based linkers copy referenced global symbols from shared
+ libraries to the main executable.
+ If we are scanning the symbols for a shared library, try to resolve
+ them from the minimal symbols of the main executable first. */
+
+ if (symfile_objfile && objfile != symfile_objfile)
+ resolve_objfile = symfile_objfile;
+ else
+ resolve_objfile = objfile;
+
+ while (1)
+ {
+ /* Avoid expensive loop through all minimal symbols if there are
+ no unresolved symbols. */
+ for (hash = 0; hash < HASHSIZE; hash++)
+ {
+ if (global_sym_chain[hash])
+ break;
+ }
+ if (hash >= HASHSIZE)
+ return;
+
+ for (msymbol = resolve_objfile->msymbols;
+ msymbol && SYMBOL_NAME (msymbol) != NULL;
+ msymbol++)
+ {
+ QUIT;
+
+ /* Skip static symbols. */
+ switch (MSYMBOL_TYPE (msymbol))
+ {
+ case mst_file_text:
+ case mst_file_data:
+ case mst_file_bss:
+ continue;
+ default:
+ break;
+ }
+
+ prev = NULL;
+
+ /* Get the hash index and check all the symbols
+ under that hash index. */
+
+ hash = hashname (SYMBOL_NAME (msymbol));
+
+ for (sym = global_sym_chain[hash]; sym;)
+ {
+ if (SYMBOL_NAME (msymbol)[0] == SYMBOL_NAME (sym)[0] &&
+ STREQ (SYMBOL_NAME (msymbol) + 1, SYMBOL_NAME (sym) + 1))
+ {
+
+ struct alias_list *aliases;
+
+ /* Splice this symbol out of the hash chain and
+ assign the value we have to it. */
+ if (prev)
+ {
+ SYMBOL_VALUE_CHAIN (prev) = SYMBOL_VALUE_CHAIN (sym);
+ }
+ else
+ {
+ global_sym_chain[hash] = SYMBOL_VALUE_CHAIN (sym);
+ }
+
+ /* Check to see whether we need to fix up a common block. */
+ /* Note: this code might be executed several times for
+ the same symbol if there are multiple references. */
+
+ /* If symbol has aliases, do minimal symbol fixups for each.
+ These live aliases/references weren't added to
+ global_sym_chain hash but may also need to be fixed up. */
+ /* FIXME: Maybe should have added aliases to the global chain, resolved symbol name, then treated aliases as normal
+ symbols? Still, we wouldn't want to add_to_list. */
+ /* Now do the same for each alias of this symbol */
+ rsym = sym;
+ aliases = SYMBOL_ALIASES (sym);
+ while (rsym)
+ {
+ if (SYMBOL_CLASS (rsym) == LOC_BLOCK)
+ {
+ fix_common_block (rsym,
+ SYMBOL_VALUE_ADDRESS (msymbol));
+ }
+ else
+ {
+ SYMBOL_VALUE_ADDRESS (rsym)
+ = SYMBOL_VALUE_ADDRESS (msymbol);
+ }
+ SYMBOL_SECTION (rsym) = SYMBOL_SECTION (msymbol);
+ if (aliases)
+ {
+ rsym = aliases->sym;
+ aliases = aliases->next;
+ }
+ else
+ rsym = NULL;
+ }
+
+
+ if (prev)
+ {
+ sym = SYMBOL_VALUE_CHAIN (prev);
+ }
+ else
+ {
+ sym = global_sym_chain[hash];
+ }
+ }
+ else
+ {
+ prev = sym;
+ sym = SYMBOL_VALUE_CHAIN (sym);
+ }
+ }
+ }
+ if (resolve_objfile == objfile)
+ break;
+ resolve_objfile = objfile;
+ }
+
+ /* Change the storage class of any remaining unresolved globals to
+ LOC_UNRESOLVED and remove them from the chain. */
+ for (hash = 0; hash < HASHSIZE; hash++)
+ {
+ sym = global_sym_chain[hash];
+ while (sym)
+ {
+ prev = sym;
+ sym = SYMBOL_VALUE_CHAIN (sym);
+
+ /* Change the symbol address from the misleading chain value
+ to address zero. */
+ SYMBOL_VALUE_ADDRESS (prev) = 0;
+
+ /* Complain about unresolved common block symbols. */
+ if (SYMBOL_CLASS (prev) == LOC_STATIC)
+ SYMBOL_CLASS (prev) = LOC_UNRESOLVED;
+ else
+ complain (&unresolved_sym_chain_complaint,
+ objfile->name, SYMBOL_NAME (prev));
+ }
+ }
+ memset (global_sym_chain, 0, sizeof (global_sym_chain));
+}
+
+/* Initialize anything that needs initializing when starting to read
+ a fresh piece of a symbol file, e.g. reading in the stuff corresponding
+ to a psymtab. */
+
+void
+stabsread_init (void)
+{
+}
+
+/* Initialize anything that needs initializing when a completely new
+ symbol file is specified (not just adding some symbols from another
+ file, e.g. a shared library). */
+
+void
+stabsread_new_init (void)
+{
+ /* Empty the hash table of global syms looking for values. */
+ memset (global_sym_chain, 0, sizeof (global_sym_chain));
+}
+
+/* Initialize anything that needs initializing at the same time as
+ start_symtab() is called. */
+
+void
+start_stabs (void)
+{
+ global_stabs = NULL; /* AIX COFF */
+ /* Leave FILENUM of 0 free for builtin types and this file's types. */
+ n_this_object_header_files = 1;
+ type_vector_length = 0;
+ type_vector = (struct type **) 0;
+
+ /* FIXME: If common_block_name is not already NULL, we should complain(). */
+ common_block_name = NULL;
+
+ os9k_stabs = 0;
+}
+
+/* Call after end_symtab() */
+
+void
+end_stabs (void)
+{
+ if (type_vector)
+ {
+ xfree (type_vector);
+ }
+ type_vector = 0;
+ type_vector_length = 0;
+ previous_stab_code = 0;
+}
+
+void
+finish_global_stabs (struct objfile *objfile)
+{
+ if (global_stabs)
+ {
+ patch_block_stabs (global_symbols, global_stabs, objfile);
+ xfree (global_stabs);
+ global_stabs = NULL;
+ }
+}
+
+/* Initializer for this module */
+
+void
+_initialize_stabsread (void)
+{
+ undef_types_allocated = 20;
+ undef_types_length = 0;
+ undef_types = (struct type **)
+ xmalloc (undef_types_allocated * sizeof (struct type *));
+}
diff --git a/gdb/stabsread.h b/gdb/stabsread.h
new file mode 100644
index 00000000000..59504da552b
--- /dev/null
+++ b/gdb/stabsread.h
@@ -0,0 +1,226 @@
+/* Include file for stabs debugging format support functions.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1999, 2000 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. */
+
+/* Definitions, prototypes, etc for stabs debugging format support
+ functions.
+
+ Variables declared in this file can be defined by #define-ing
+ the name EXTERN to null. It is used to declare variables that
+ are normally extern, but which get defined in a single module
+ using this technique. */
+
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+
+/* Hash table of global symbols whose values are not known yet.
+ They are chained thru the SYMBOL_VALUE_CHAIN, since we don't
+ have the correct data for that slot yet.
+
+ The use of the LOC_BLOCK code in this chain is nonstandard--
+ it refers to a FORTRAN common block rather than the usual meaning, and
+ the such LOC_BLOCK symbols use their fields in nonstandard ways. */
+
+EXTERN struct symbol *global_sym_chain[HASHSIZE];
+
+extern void common_block_start (char *, struct objfile *);
+extern void common_block_end (struct objfile *);
+
+/* Kludge for xcoffread.c */
+
+struct pending_stabs
+ {
+ int count;
+ int length;
+ char *stab[1];
+ };
+
+EXTERN struct pending_stabs *global_stabs;
+
+/* The type code that process_one_symbol saw on its previous invocation.
+ Used to detect pairs of N_SO symbols. */
+
+EXTERN int previous_stab_code;
+
+/* Support for Sun changes to dbx symbol format */
+
+/* For each identified header file, we have a table of types defined
+ in that header file.
+
+ header_files maps header file names to their type tables.
+ It is a vector of n_header_files elements.
+ Each element describes one header file.
+ It contains a vector of types.
+
+ Sometimes it can happen that the same header file produces
+ different results when included in different places.
+ This can result from conditionals or from different
+ things done before including the file.
+ When this happens, there are multiple entries for the file in this table,
+ one entry for each distinct set of results.
+ The entries are distinguished by the INSTANCE field.
+ The INSTANCE field appears in the N_BINCL and N_EXCL symbol table and is
+ used to match header-file references to their corresponding data. */
+
+struct header_file
+ {
+
+ /* Name of header file */
+
+ char *name;
+
+ /* Numeric code distinguishing instances of one header file that produced
+ different results when included. It comes from the N_BINCL or N_EXCL. */
+
+ int instance;
+
+ /* Pointer to vector of types */
+
+ struct type **vector;
+
+ /* Allocated length (# elts) of that vector */
+
+ int length;
+
+ };
+
+/* The table of header_files of this OBJFILE. */
+#define HEADER_FILES(OBJFILE) (DBX_SYMFILE_INFO (OBJFILE)->header_files)
+
+/* The actual length of HEADER_FILES. */
+#define N_HEADER_FILES(OBJFILE) (DBX_SYMFILE_INFO (OBJFILE)->n_header_files)
+
+/* The allocated lengh of HEADER_FILES. */
+#define N_ALLOCATED_HEADER_FILES(OBJFILE) \
+ (DBX_SYMFILE_INFO (OBJFILE)->n_allocated_header_files)
+
+/* Within each object file, various header files are assigned numbers.
+ A type is defined or referred to with a pair of numbers
+ (FILENUM,TYPENUM) where FILENUM is the number of the header file
+ and TYPENUM is the number within that header file.
+ TYPENUM is the index within the vector of types for that header file.
+
+ FILENUM == 0 is special; it refers to the main source of the object file,
+ and not to any header file. FILENUM != 1 is interpreted by looking it up
+ in the following table, which contains indices in header_files. */
+
+EXTERN int *this_object_header_files;
+
+EXTERN int n_this_object_header_files;
+
+EXTERN int n_allocated_this_object_header_files;
+
+extern struct complaint unknown_symtype_complaint;
+extern struct complaint unknown_symchar_complaint;
+
+extern struct type *read_type (char **, struct objfile *);
+
+extern void cleanup_undefined_types (void);
+
+extern struct type **dbx_lookup_type (int[2]);
+
+extern long read_number (char **, int);
+
+extern void add_undefined_type (struct type *);
+
+extern struct symbol *define_symbol (CORE_ADDR, char *, int, int,
+ struct objfile *);
+
+extern void stabsread_init (void);
+
+extern void stabsread_new_init (void);
+
+extern void start_stabs (void);
+
+extern void end_stabs (void);
+
+extern void finish_global_stabs (struct objfile *objfile);
+
+
+EXTERN int os9k_stabs;
+
+/* COFF files can have multiple .stab sections, if they are linked
+ using --split-by-reloc. This linked list is used to pass the
+ information into the functions in dbxread.c. */
+struct stab_section_list
+ {
+ /* Next in list. */
+ struct stab_section_list *next;
+
+ /* Stab section. */
+ asection *section;
+ };
+
+/* Functions exported by dbxread.c. These are not in stabsread.c because
+ they are only used by some stabs readers. */
+
+extern struct partial_symtab *end_psymtab (struct partial_symtab *pst,
+ char **include_list,
+ int num_includes,
+ int capping_symbol_offset,
+ CORE_ADDR capping_text,
+ struct partial_symtab
+ **dependency_list,
+ int number_dependencies,
+ int textlow_not_set);
+
+extern void
+process_one_symbol (int, int, CORE_ADDR, char *,
+ struct section_offsets *, struct objfile *);
+
+extern void elfstab_build_psymtabs
+ (struct objfile *objfile,
+ int mainline,
+ file_ptr staboff, unsigned int stabsize,
+ file_ptr stabstroffset, unsigned int stabstrsize);
+
+extern void coffstab_build_psymtabs
+ (struct objfile *objfile,
+ int mainline,
+ CORE_ADDR textaddr, unsigned int textsize,
+ struct stab_section_list *stabs,
+ file_ptr stabstroffset, unsigned int stabstrsize);
+
+extern void stabsect_build_psymtabs
+ (struct objfile *objfile,
+ int mainline, char *stab_name, char *stabstr_name, char *text_name);
+
+extern void elfstab_offset_sections (struct objfile *,
+ struct partial_symtab *);
+
+extern void process_later
+ (struct symbol *, char *,
+ int (*f) (struct objfile *, struct symbol *, char *));
+
+extern int symbol_reference_defined (char **);
+
+extern void ref_add (int, struct symbol *, char *, CORE_ADDR);
+
+extern struct symbol *ref_search (int);
+
+extern int resolve_cfront_continuation
+ (struct objfile *objfile, struct symbol *sym, char *p);
+
+extern void free_header_files (void);
+
+extern void init_header_files (void);
+
+#undef EXTERN
diff --git a/gdb/stack.c b/gdb/stack.c
new file mode 100644
index 00000000000..2dab0deb016
--- /dev/null
+++ b/gdb/stack.c
@@ -0,0 +1,1973 @@
+/* Print and select stack frames for GDB, the GNU debugger.
+
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 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 <ctype.h>
+#include "defs.h"
+#include "gdb_string.h"
+#include "value.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "language.h"
+#include "frame.h"
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "breakpoint.h"
+#include "demangle.h"
+#include "inferior.h"
+#include "annotate.h"
+#include "ui-out.h"
+
+/* Prototypes for exported functions. */
+
+void args_info (char *, int);
+
+void locals_info (char *, int);
+
+void (*selected_frame_level_changed_hook) (int);
+
+void _initialize_stack (void);
+
+/* Prototypes for local functions. */
+
+static void return_command (char *, int);
+
+static void down_command (char *, int);
+
+static void down_silently_base (char *);
+
+static void down_silently_command (char *, int);
+
+static void up_command (char *, int);
+
+static void up_silently_base (char *);
+
+static void up_silently_command (char *, int);
+
+void frame_command (char *, int);
+
+static void current_frame_command (char *, int);
+
+static void select_frame_command (char *, int);
+
+static void print_frame_arg_vars (struct frame_info *, struct ui_file *);
+
+static void catch_info (char *, int);
+
+static void args_plus_locals_info (char *, int);
+
+static void print_frame_label_vars (struct frame_info *, int,
+ struct ui_file *);
+
+static void print_frame_local_vars (struct frame_info *, int,
+ struct ui_file *);
+
+static int print_block_frame_labels (struct block *, int *,
+ struct ui_file *);
+
+static int print_block_frame_locals (struct block *,
+ struct frame_info *,
+ int,
+ struct ui_file *);
+
+static void print_frame (struct frame_info *fi,
+ int level,
+ int source,
+ int args,
+ struct symtab_and_line sal);
+
+static void print_frame_info_base (struct frame_info *, int, int, int);
+
+static void print_stack_frame_base (struct frame_info *, int, int);
+
+static void backtrace_command (char *, int);
+
+struct frame_info *parse_frame_specification (char *);
+
+static void frame_info (char *, int);
+
+extern int addressprint; /* Print addresses, or stay symbolic only? */
+extern int lines_to_list; /* # of lines "list" command shows by default */
+
+/* The "selected" stack frame is used by default for local and arg access.
+ May be zero, for no selected frame. */
+
+struct frame_info *selected_frame;
+
+/* Level of the selected frame:
+ 0 for innermost, 1 for its caller, ...
+ or -1 for frame specified by address with no defined level. */
+
+/* Level of the selected frame: 0 for innermost, 1 for its caller, ...
+ or -1 for NULL frame. */
+
+int
+frame_relative_level (struct frame_info *fi)
+{
+ if (fi == NULL)
+ return -1;
+ else
+ return fi->level;
+}
+
+/* Zero means do things normally; we are interacting directly with the
+ user. One means print the full filename and linenumber when a
+ frame is printed, and do so in a format emacs18/emacs19.22 can
+ parse. Two means print similar annotations, but in many more
+ cases and in a slightly different syntax. */
+
+int annotation_level = 0;
+
+
+struct print_stack_frame_args
+ {
+ struct frame_info *fi;
+ int level;
+ int source;
+ int args;
+ };
+
+static int print_stack_frame_base_stub (char *);
+
+/* Show and print the frame arguments.
+ Pass the args the way catch_errors wants them. */
+static int show_and_print_stack_frame_stub (void *args);
+static int
+show_and_print_stack_frame_stub (void *args)
+{
+ struct print_stack_frame_args *p = (struct print_stack_frame_args *) args;
+
+ print_frame_info (p->fi, p->level, p->source, p->args);
+
+ return 0;
+}
+
+/* Show or print the frame arguments.
+ Pass the args the way catch_errors wants them. */
+static int print_stack_frame_stub (void *args);
+static int
+print_stack_frame_stub (void *args)
+{
+ struct print_stack_frame_args *p = (struct print_stack_frame_args *) args;
+
+ print_frame_info_base (p->fi, p->level, p->source, p->args);
+ return 0;
+}
+
+/* Print a stack frame briefly. FRAME_INFI should be the frame info
+ and LEVEL should be its level in the stack (or -1 for level not
+ defined). */
+
+/* Pass the args the way catch_errors wants them. */
+static int
+print_stack_frame_base_stub (char *args)
+{
+ struct print_stack_frame_args *p = (struct print_stack_frame_args *) args;
+
+ print_frame_info_base (p->fi, p->level, p->source, p->args);
+ return 0;
+}
+
+/* print the frame arguments to the terminal.
+ Pass the args the way catch_errors wants them. */
+static int print_only_stack_frame_stub (void *);
+static int
+print_only_stack_frame_stub (void *args)
+{
+ struct print_stack_frame_args *p = (struct print_stack_frame_args *) args;
+
+ print_frame_info_base (p->fi, p->level, p->source, p->args);
+ return 0;
+}
+
+/* Print a stack frame briefly. FRAME_INFI should be the frame info
+ and LEVEL should be its level in the stack (or -1 for level not defined).
+ This prints the level, the function executing, the arguments,
+ and the file name and line number.
+ If the pc is not at the beginning of the source line,
+ the actual pc is printed at the beginning.
+
+ If SOURCE is 1, print the source line as well.
+ If SOURCE is -1, print ONLY the source line. */
+
+static void
+print_stack_frame_base (struct frame_info *fi, int level, int source)
+{
+ struct print_stack_frame_args args;
+
+ args.fi = fi;
+ args.level = level;
+ args.source = source;
+ args.args = 1;
+
+ catch_errors (print_stack_frame_stub, &args, "", RETURN_MASK_ALL);
+}
+
+/* Show and print a stack frame briefly. FRAME_INFI should be the frame info
+ and LEVEL should be its level in the stack (or -1 for level not defined).
+ This prints the level, the function executing, the arguments,
+ and the file name and line number.
+ If the pc is not at the beginning of the source line,
+ the actual pc is printed at the beginning.
+
+ If SOURCE is 1, print the source line as well.
+ If SOURCE is -1, print ONLY the source line. */
+
+void
+show_and_print_stack_frame (struct frame_info *fi, int level, int source)
+{
+ struct print_stack_frame_args args;
+
+ args.fi = fi;
+ args.level = level;
+ args.source = source;
+ args.args = 1;
+
+ catch_errors (show_and_print_stack_frame_stub, &args, "", RETURN_MASK_ALL);
+}
+
+
+/* Show or print a stack frame briefly. FRAME_INFI should be the frame info
+ and LEVEL should be its level in the stack (or -1 for level not defined).
+ This prints the level, the function executing, the arguments,
+ and the file name and line number.
+ If the pc is not at the beginning of the source line,
+ the actual pc is printed at the beginning.
+
+ If SOURCE is 1, print the source line as well.
+ If SOURCE is -1, print ONLY the source line. */
+
+void
+print_stack_frame (struct frame_info *fi, int level, int source)
+{
+ struct print_stack_frame_args args;
+
+ args.fi = fi;
+ args.level = level;
+ args.source = source;
+ args.args = 1;
+
+ catch_errors (print_stack_frame_stub, (char *) &args, "", RETURN_MASK_ALL);
+}
+
+/* Print a stack frame briefly. FRAME_INFI should be the frame info
+ and LEVEL should be its level in the stack (or -1 for level not defined).
+ This prints the level, the function executing, the arguments,
+ and the file name and line number.
+ If the pc is not at the beginning of the source line,
+ the actual pc is printed at the beginning.
+
+ If SOURCE is 1, print the source line as well.
+ If SOURCE is -1, print ONLY the source line. */
+
+void
+print_only_stack_frame (struct frame_info *fi, int level, int source)
+{
+ struct print_stack_frame_args args;
+
+ args.fi = fi;
+ args.level = level;
+ args.source = source;
+ args.args = 1;
+
+ catch_errors (print_only_stack_frame_stub, &args, "", RETURN_MASK_ALL);
+}
+
+struct print_args_args
+{
+ struct symbol *func;
+ struct frame_info *fi;
+ struct ui_file *stream;
+};
+
+static int print_args_stub (PTR);
+
+/* Pass the args the way catch_errors wants them. */
+
+static int
+print_args_stub (PTR args)
+{
+ int numargs;
+ struct print_args_args *p = (struct print_args_args *) args;
+
+ numargs = FRAME_NUM_ARGS (p->fi);
+ print_frame_args (p->func, p->fi, numargs, p->stream);
+ return 0;
+}
+
+/* Print information about a frame for frame "fi" at level "level".
+ Used in "where" output, also used to emit breakpoint or step
+ messages.
+ LEVEL is the level of the frame, or -1 if it is the
+ innermost frame but we don't want to print the level.
+ The meaning of the SOURCE argument is:
+ SRC_LINE: Print only source line
+ LOCATION: Print only location
+ LOC_AND_SRC: Print location and source line. */
+
+static void
+print_frame_info_base (struct frame_info *fi, int level, int source, int args)
+{
+ struct symtab_and_line sal;
+ int source_print;
+ int location_print;
+
+#if 0
+ char buf[MAX_REGISTER_RAW_SIZE];
+ CORE_ADDR sp;
+
+ /* On the 68k, this spends too much time in m68k_find_saved_regs. */
+
+ /* Get the value of SP_REGNUM relative to the frame. */
+ get_saved_register (buf, (int *) NULL, (CORE_ADDR *) NULL,
+ FRAME_INFO_ID (fi), SP_REGNUM, (enum lval_type *) NULL);
+ sp = extract_address (buf, REGISTER_RAW_SIZE (SP_REGNUM));
+
+ /* This is not a perfect test, because if a function alloca's some
+ memory, puts some code there, and then jumps into it, then the test
+ will succeed even though there is no call dummy. Probably best is
+ to check for a bp_call_dummy breakpoint. */
+ if (PC_IN_CALL_DUMMY (fi->pc, sp, fi->frame))
+#else
+ if (frame_in_dummy (fi))
+#endif
+ {
+ annotate_frame_begin (level == -1 ? 0 : level, fi->pc);
+
+ /* Do this regardless of SOURCE because we don't have any source
+ to list for this frame. */
+ if (level >= 0)
+ printf_filtered ("#%-2d ", level);
+ annotate_function_call ();
+ printf_filtered ("<function called from gdb>\n");
+ annotate_frame_end ();
+ return;
+ }
+ if (fi->signal_handler_caller)
+ {
+ annotate_frame_begin (level == -1 ? 0 : level, fi->pc);
+
+ /* Do this regardless of SOURCE because we don't have any source
+ to list for this frame. */
+ if (level >= 0)
+ printf_filtered ("#%-2d ", level);
+ annotate_signal_handler_caller ();
+ printf_filtered ("<signal handler called>\n");
+ annotate_frame_end ();
+ return;
+ }
+
+ /* If fi is not the innermost frame, that normally means that fi->pc
+ points to *after* the call instruction, and we want to get the line
+ containing the call, never the next line. But if the next frame is
+ a signal_handler_caller or a dummy frame, then the next frame was
+ not entered as the result of a call, and we want to get the line
+ containing fi->pc. */
+ sal =
+ find_pc_line (fi->pc,
+ fi->next != NULL
+ && !fi->next->signal_handler_caller
+ && !frame_in_dummy (fi->next));
+
+ location_print = (source == LOCATION
+ || source == LOC_AND_ADDRESS
+ || source == SRC_AND_LOC);
+
+ if (location_print || !sal.symtab)
+ print_frame (fi, level, source, args, sal);
+
+ source_print = (source == SRC_LINE || source == SRC_AND_LOC);
+
+ if (source_print && sal.symtab)
+ {
+ int done = 0;
+ int mid_statement = (source == SRC_LINE) && (fi->pc != sal.pc);
+
+ if (annotation_level)
+ done = identify_source_line (sal.symtab, sal.line, mid_statement,
+ fi->pc);
+ if (!done)
+ {
+ if (print_frame_info_listing_hook)
+ {
+ print_frame_info_listing_hook (sal.symtab, sal.line, sal.line + 1, 0);
+ current_source_symtab = sal.symtab;
+ }
+ else
+ {
+ /* We used to do this earlier, but that is clearly
+ wrong. This function is used by many different
+ parts of gdb, including normal_stop in infrun.c,
+ which uses this to print out the current PC
+ when we stepi/nexti into the middle of a source
+ line. Only the command line really wants this
+ behavior. Other UIs probably would like the
+ ability to decide for themselves if it is desired. */
+ if (addressprint && mid_statement)
+ {
+ ui_out_field_core_addr (uiout, "addr", fi->pc);
+ ui_out_text (uiout, "\t");
+ }
+
+ print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
+ }
+ }
+ current_source_line = max (sal.line - lines_to_list / 2, 1);
+ }
+
+ if (source != 0)
+ set_default_breakpoint (1, fi->pc, sal.symtab, sal.line);
+
+ annotate_frame_end ();
+
+ gdb_flush (gdb_stdout);
+}
+
+static void
+print_frame (struct frame_info *fi,
+ int level,
+ int source,
+ int args,
+ struct symtab_and_line sal)
+{
+ struct symbol *func;
+ register char *funname = 0;
+ enum language funlang = language_unknown;
+ struct ui_stream *stb;
+ struct cleanup *old_chain;
+ struct cleanup *list_chain;
+
+ stb = ui_out_stream_new (uiout);
+ old_chain = make_cleanup_ui_out_stream_delete (stb);
+
+ func = find_pc_function (fi->pc);
+ if (func)
+ {
+ /* In certain pathological cases, the symtabs give the wrong
+ function (when we are in the first function in a file which
+ is compiled without debugging symbols, the previous function
+ is compiled with debugging symbols, and the "foo.o" symbol
+ that is supposed to tell us where the file with debugging symbols
+ ends has been truncated by ar because it is longer than 15
+ characters). This also occurs if the user uses asm() to create
+ a function but not stabs for it (in a file compiled -g).
+
+ So look in the minimal symbol tables as well, and if it comes
+ up with a larger address for the function use that instead.
+ I don't think this can ever cause any problems; there shouldn't
+ be any minimal symbols in the middle of a function; if this is
+ ever changed many parts of GDB will need to be changed (and we'll
+ create a find_pc_minimal_function or some such). */
+
+ struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
+ if (msymbol != NULL
+ && (SYMBOL_VALUE_ADDRESS (msymbol)
+ > BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
+ {
+#if 0
+ /* There is no particular reason to think the line number
+ information is wrong. Someone might have just put in
+ a label with asm() but left the line numbers alone. */
+ /* In this case we have no way of knowing the source file
+ and line number, so don't print them. */
+ sal.symtab = 0;
+#endif
+ /* We also don't know anything about the function besides
+ its address and name. */
+ func = 0;
+ funname = SYMBOL_NAME (msymbol);
+ funlang = SYMBOL_LANGUAGE (msymbol);
+ }
+ else
+ {
+ /* I'd like to use SYMBOL_SOURCE_NAME() here, to display the
+ demangled name that we already have stored in the symbol
+ table, but we stored a version with DMGL_PARAMS turned
+ on, and here we don't want to display parameters. So call
+ the demangler again, with DMGL_ANSI only. (Yes, I know
+ that printf_symbol_filtered() will again try to demangle
+ the name on the fly, but the issue is that if
+ cplus_demangle() fails here, it'll fail there too. So we
+ want to catch the failure ("demangled==NULL" case below)
+ here, while we still have our hands on the function
+ symbol.) */
+ char *demangled;
+ funname = SYMBOL_NAME (func);
+ funlang = SYMBOL_LANGUAGE (func);
+ if (funlang == language_cplus)
+ {
+ demangled = cplus_demangle (funname, DMGL_ANSI);
+ if (demangled == NULL)
+ /* If the demangler fails, try the demangled name from
+ the symbol table. This'll have parameters, but
+ that's preferable to diplaying a mangled name. */
+ funname = SYMBOL_SOURCE_NAME (func);
+ }
+ }
+ }
+ else
+ {
+ struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
+ if (msymbol != NULL)
+ {
+ funname = SYMBOL_NAME (msymbol);
+ funlang = SYMBOL_LANGUAGE (msymbol);
+ }
+ }
+
+ annotate_frame_begin (level == -1 ? 0 : level, fi->pc);
+
+ list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
+
+ if (level >= 0)
+ {
+ ui_out_text (uiout, "#");
+ ui_out_field_fmt (uiout, "level", "%-2d", level);
+ ui_out_spaces (uiout, 1);
+ }
+ if (addressprint)
+ if (fi->pc != sal.pc || !sal.symtab || source == LOC_AND_ADDRESS)
+ {
+ annotate_frame_address ();
+ ui_out_field_core_addr (uiout, "addr", fi->pc);
+ annotate_frame_address_end ();
+ ui_out_text (uiout, " in ");
+ }
+ annotate_frame_function_name ();
+ fprintf_symbol_filtered (stb->stream, funname ? funname : "??", funlang,
+ DMGL_ANSI);
+ ui_out_field_stream (uiout, "func", stb);
+ ui_out_wrap_hint (uiout, " ");
+ annotate_frame_args ();
+
+ ui_out_text (uiout, " (");
+ if (args)
+ {
+ struct print_args_args args;
+ struct cleanup *args_list_chain;
+ args.fi = fi;
+ args.func = func;
+ args.stream = gdb_stdout;
+ args_list_chain = make_cleanup_ui_out_list_begin_end (uiout, "args");
+ catch_errors (print_args_stub, &args, "", RETURN_MASK_ALL);
+ /* FIXME: args must be a list. If one argument is a string it will
+ have " that will not be properly escaped. */
+ /* Invoke ui_out_tuple_end. */
+ do_cleanups (args_list_chain);
+ QUIT;
+ }
+ ui_out_text (uiout, ")");
+ if (sal.symtab && sal.symtab->filename)
+ {
+ annotate_frame_source_begin ();
+ ui_out_wrap_hint (uiout, " ");
+ ui_out_text (uiout, " at ");
+ annotate_frame_source_file ();
+ ui_out_field_string (uiout, "file", sal.symtab->filename);
+ annotate_frame_source_file_end ();
+ ui_out_text (uiout, ":");
+ annotate_frame_source_line ();
+ ui_out_field_int (uiout, "line", sal.line);
+ annotate_frame_source_end ();
+ }
+
+#ifdef PC_SOLIB
+ if (!funname || (!sal.symtab || !sal.symtab->filename))
+ {
+ char *lib = PC_SOLIB (fi->pc);
+ if (lib)
+ {
+ annotate_frame_where ();
+ ui_out_wrap_hint (uiout, " ");
+ ui_out_text (uiout, " from ");
+ ui_out_field_string (uiout, "from", lib);
+ }
+ }
+#endif /* PC_SOLIB */
+
+ /* do_cleanups will call ui_out_tuple_end() for us. */
+ do_cleanups (list_chain);
+ ui_out_text (uiout, "\n");
+ do_cleanups (old_chain);
+}
+
+
+/* Show or print the frame info. If this is the tui, it will be shown in
+ the source display */
+void
+print_frame_info (struct frame_info *fi, register int level, int source,
+ int args)
+{
+ print_frame_info_base (fi, level, source, args);
+}
+
+/* Show the frame info. If this is the tui, it will be shown in
+ the source display otherwise, nothing is done */
+void
+show_stack_frame (struct frame_info *fi)
+{
+}
+
+
+/* Read a frame specification in whatever the appropriate format is.
+ Call error() if the specification is in any way invalid (i.e.
+ this function never returns NULL). */
+
+struct frame_info *
+parse_frame_specification (char *frame_exp)
+{
+ int numargs = 0;
+#define MAXARGS 4
+ CORE_ADDR args[MAXARGS];
+ int level;
+
+ if (frame_exp)
+ {
+ char *addr_string, *p;
+ struct cleanup *tmp_cleanup;
+
+ while (*frame_exp == ' ')
+ frame_exp++;
+
+ while (*frame_exp)
+ {
+ if (numargs > MAXARGS)
+ error ("Too many args in frame specification");
+ /* Parse an argument. */
+ for (p = frame_exp; *p && *p != ' '; p++)
+ ;
+ addr_string = savestring (frame_exp, p - frame_exp);
+
+ {
+ struct value *vp;
+
+ tmp_cleanup = make_cleanup (xfree, addr_string);
+
+ /* NOTE: we call parse_and_eval and then both
+ value_as_long and value_as_address rather than calling
+ parse_and_eval_long and parse_and_eval_address because
+ of the issue of potential side effects from evaluating
+ the expression. */
+ vp = parse_and_eval (addr_string);
+ if (numargs == 0)
+ level = value_as_long (vp);
+
+ args[numargs++] = value_as_address (vp);
+ do_cleanups (tmp_cleanup);
+ }
+
+ /* Skip spaces, move to possible next arg. */
+ while (*p == ' ')
+ p++;
+ frame_exp = p;
+ }
+ }
+
+ switch (numargs)
+ {
+ case 0:
+ if (selected_frame == NULL)
+ error ("No selected frame.");
+ return selected_frame;
+ /* NOTREACHED */
+ case 1:
+ {
+ struct frame_info *fid =
+ find_relative_frame (get_current_frame (), &level);
+ struct frame_info *tfid;
+
+ if (level == 0)
+ /* find_relative_frame was successful */
+ return fid;
+
+ /* If SETUP_ARBITRARY_FRAME is defined, then frame specifications
+ take at least 2 addresses. It is important to detect this case
+ here so that "frame 100" does not give a confusing error message
+ like "frame specification requires two addresses". This of course
+ does not solve the "frame 100" problem for machines on which
+ a frame specification can be made with one address. To solve
+ that, we need a new syntax for a specifying a frame by address.
+ I think the cleanest syntax is $frame(0x45) ($frame(0x23,0x45) for
+ two args, etc.), but people might think that is too much typing,
+ so I guess *0x23,0x45 would be a possible alternative (commas
+ really should be used instead of spaces to delimit; using spaces
+ normally works in an expression). */
+#ifdef SETUP_ARBITRARY_FRAME
+ error ("No frame %s", paddr_d (args[0]));
+#endif
+
+ /* If (s)he specifies the frame with an address, he deserves what
+ (s)he gets. Still, give the highest one that matches. */
+
+ for (fid = get_current_frame ();
+ fid && fid->frame != args[0];
+ fid = get_prev_frame (fid))
+ ;
+
+ if (fid)
+ while ((tfid = get_prev_frame (fid)) &&
+ (tfid->frame == args[0]))
+ fid = tfid;
+
+ /* We couldn't identify the frame as an existing frame, but
+ perhaps we can create one with a single argument. */
+ }
+
+ default:
+#ifdef SETUP_ARBITRARY_FRAME
+ return SETUP_ARBITRARY_FRAME (numargs, args);
+#else
+ /* Usual case. Do it here rather than have everyone supply
+ a SETUP_ARBITRARY_FRAME that does this. */
+ if (numargs == 1)
+ return create_new_frame (args[0], 0);
+ error ("Too many args in frame specification");
+#endif
+ /* NOTREACHED */
+ }
+ /* NOTREACHED */
+}
+
+/* FRAME_ARGS_ADDRESS_CORRECT is just like FRAME_ARGS_ADDRESS except
+ that if it is unsure about the answer, it returns 0
+ instead of guessing (this happens on the VAX and i960, for example).
+
+ On most machines, we never have to guess about the args address,
+ so FRAME_ARGS_ADDRESS{,_CORRECT} are the same. */
+#if !defined (FRAME_ARGS_ADDRESS_CORRECT)
+#define FRAME_ARGS_ADDRESS_CORRECT FRAME_ARGS_ADDRESS
+#endif
+
+/* Print verbosely the selected frame or the frame at address ADDR.
+ This means absolutely all information in the frame is printed. */
+
+static void
+frame_info (char *addr_exp, int from_tty)
+{
+ struct frame_info *fi;
+ struct symtab_and_line sal;
+ struct symbol *func;
+ struct symtab *s;
+ struct frame_info *calling_frame_info;
+ int i, count, numregs;
+ char *funname = 0;
+ enum language funlang = language_unknown;
+
+ if (!target_has_stack)
+ error ("No stack.");
+
+ fi = parse_frame_specification (addr_exp);
+ if (fi == NULL)
+ error ("Invalid frame specified.");
+
+ sal = find_pc_line (fi->pc,
+ fi->next != NULL
+ && !fi->next->signal_handler_caller
+ && !frame_in_dummy (fi->next));
+ func = get_frame_function (fi);
+ s = find_pc_symtab (fi->pc);
+ if (func)
+ {
+ /* I'd like to use SYMBOL_SOURCE_NAME() here, to display
+ * the demangled name that we already have stored in
+ * the symbol table, but we stored a version with
+ * DMGL_PARAMS turned on, and here we don't want
+ * to display parameters. So call the demangler again,
+ * with DMGL_ANSI only. RT
+ * (Yes, I know that printf_symbol_filtered() will
+ * again try to demangle the name on the fly, but
+ * the issue is that if cplus_demangle() fails here,
+ * it'll fail there too. So we want to catch the failure
+ * ("demangled==NULL" case below) here, while we still
+ * have our hands on the function symbol.)
+ */
+ char *demangled;
+ funname = SYMBOL_NAME (func);
+ funlang = SYMBOL_LANGUAGE (func);
+ if (funlang == language_cplus)
+ {
+ demangled = cplus_demangle (funname, DMGL_ANSI);
+ /* If the demangler fails, try the demangled name
+ * from the symbol table. This'll have parameters,
+ * but that's preferable to diplaying a mangled name.
+ */
+ if (demangled == NULL)
+ funname = SYMBOL_SOURCE_NAME (func);
+ }
+ }
+ else
+ {
+ register struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
+ if (msymbol != NULL)
+ {
+ funname = SYMBOL_NAME (msymbol);
+ funlang = SYMBOL_LANGUAGE (msymbol);
+ }
+ }
+ calling_frame_info = get_prev_frame (fi);
+
+ if (!addr_exp && frame_relative_level (selected_frame) >= 0)
+ {
+ printf_filtered ("Stack level %d, frame at ",
+ frame_relative_level (selected_frame));
+ print_address_numeric (fi->frame, 1, gdb_stdout);
+ printf_filtered (":\n");
+ }
+ else
+ {
+ printf_filtered ("Stack frame at ");
+ print_address_numeric (fi->frame, 1, gdb_stdout);
+ printf_filtered (":\n");
+ }
+ printf_filtered (" %s = ", REGISTER_NAME (PC_REGNUM));
+ print_address_numeric (fi->pc, 1, gdb_stdout);
+
+ wrap_here (" ");
+ if (funname)
+ {
+ printf_filtered (" in ");
+ fprintf_symbol_filtered (gdb_stdout, funname, funlang,
+ DMGL_ANSI | DMGL_PARAMS);
+ }
+ wrap_here (" ");
+ if (sal.symtab)
+ printf_filtered (" (%s:%d)", sal.symtab->filename, sal.line);
+ puts_filtered ("; ");
+ wrap_here (" ");
+ printf_filtered ("saved %s ", REGISTER_NAME (PC_REGNUM));
+ print_address_numeric (FRAME_SAVED_PC (fi), 1, gdb_stdout);
+ printf_filtered ("\n");
+
+ {
+ int frameless;
+ frameless = FRAMELESS_FUNCTION_INVOCATION (fi);
+ if (frameless)
+ printf_filtered (" (FRAMELESS),");
+ }
+
+ if (calling_frame_info)
+ {
+ printf_filtered (" called by frame at ");
+ print_address_numeric (calling_frame_info->frame, 1, gdb_stdout);
+ }
+ if (fi->next && calling_frame_info)
+ puts_filtered (",");
+ wrap_here (" ");
+ if (fi->next)
+ {
+ printf_filtered (" caller of frame at ");
+ print_address_numeric (fi->next->frame, 1, gdb_stdout);
+ }
+ if (fi->next || calling_frame_info)
+ puts_filtered ("\n");
+ if (s)
+ printf_filtered (" source language %s.\n", language_str (s->language));
+
+#ifdef PRINT_EXTRA_FRAME_INFO
+ PRINT_EXTRA_FRAME_INFO (fi);
+#endif
+
+ {
+ /* Address of the argument list for this frame, or 0. */
+ CORE_ADDR arg_list = FRAME_ARGS_ADDRESS_CORRECT (fi);
+ /* Number of args for this frame, or -1 if unknown. */
+ int numargs;
+
+ if (arg_list == 0)
+ printf_filtered (" Arglist at unknown address.\n");
+ else
+ {
+ printf_filtered (" Arglist at ");
+ print_address_numeric (arg_list, 1, gdb_stdout);
+ printf_filtered (",");
+
+ numargs = FRAME_NUM_ARGS (fi);
+ if (numargs < 0)
+ puts_filtered (" args: ");
+ else if (numargs == 0)
+ puts_filtered (" no args.");
+ else if (numargs == 1)
+ puts_filtered (" 1 arg: ");
+ else
+ printf_filtered (" %d args: ", numargs);
+ print_frame_args (func, fi, numargs, gdb_stdout);
+ puts_filtered ("\n");
+ }
+ }
+ {
+ /* Address of the local variables for this frame, or 0. */
+ CORE_ADDR arg_list = FRAME_LOCALS_ADDRESS (fi);
+
+ if (arg_list == 0)
+ printf_filtered (" Locals at unknown address,");
+ else
+ {
+ printf_filtered (" Locals at ");
+ print_address_numeric (arg_list, 1, gdb_stdout);
+ printf_filtered (",");
+ }
+ }
+
+ FRAME_INIT_SAVED_REGS (fi);
+ if (fi->saved_regs != NULL)
+ {
+ /* The sp is special; what's returned isn't the save address, but
+ actually the value of the previous frame's sp. */
+ printf_filtered (" Previous frame's sp is ");
+ print_address_numeric (fi->saved_regs[SP_REGNUM], 1, gdb_stdout);
+ printf_filtered ("\n");
+ count = 0;
+ numregs = NUM_REGS + NUM_PSEUDO_REGS;
+ for (i = 0; i < numregs; i++)
+ if (fi->saved_regs[i] && i != SP_REGNUM)
+ {
+ if (count == 0)
+ puts_filtered (" Saved registers:\n ");
+ else
+ puts_filtered (",");
+ wrap_here (" ");
+ printf_filtered (" %s at ", REGISTER_NAME (i));
+ print_address_numeric (fi->saved_regs[i], 1, gdb_stdout);
+ count++;
+ }
+ if (count)
+ puts_filtered ("\n");
+ }
+ else
+ {
+ /* We could get some information about saved registers by
+ calling get_saved_register on each register. Which info goes
+ with which frame is necessarily lost, however, and I suspect
+ that the users don't care whether they get the info. */
+ puts_filtered ("\n");
+ }
+}
+
+#if 0
+/* Set a limit on the number of frames printed by default in a
+ backtrace. */
+
+static int backtrace_limit;
+
+static void
+set_backtrace_limit_command (char *count_exp, int from_tty)
+{
+ int count = parse_and_eval_long (count_exp);
+
+ if (count < 0)
+ error ("Negative argument not meaningful as backtrace limit.");
+
+ backtrace_limit = count;
+}
+
+static void
+backtrace_limit_info (char *arg, int from_tty)
+{
+ if (arg)
+ error ("\"Info backtrace-limit\" takes no arguments.");
+
+ printf_unfiltered ("Backtrace limit: %d.\n", backtrace_limit);
+}
+#endif
+
+/* Print briefly all stack frames or just the innermost COUNT frames. */
+
+static void backtrace_command_1 (char *count_exp, int show_locals,
+ int from_tty);
+static void
+backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
+{
+ struct frame_info *fi;
+ register int count;
+ register int i;
+ register struct frame_info *trailing;
+ register int trailing_level;
+
+ if (!target_has_stack)
+ error ("No stack.");
+
+ /* The following code must do two things. First, it must
+ set the variable TRAILING to the frame from which we should start
+ printing. Second, it must set the variable count to the number
+ of frames which we should print, or -1 if all of them. */
+ trailing = get_current_frame ();
+
+ /* The target can be in a state where there is no valid frames
+ (e.g., just connected). */
+ if (trailing == NULL)
+ error ("No stack.");
+
+ trailing_level = 0;
+ if (count_exp)
+ {
+ count = parse_and_eval_long (count_exp);
+ if (count < 0)
+ {
+ struct frame_info *current;
+
+ count = -count;
+
+ current = trailing;
+ while (current && count--)
+ {
+ QUIT;
+ current = get_prev_frame (current);
+ }
+
+ /* Will stop when CURRENT reaches the top of the stack. TRAILING
+ will be COUNT below it. */
+ while (current)
+ {
+ QUIT;
+ trailing = get_prev_frame (trailing);
+ current = get_prev_frame (current);
+ trailing_level++;
+ }
+
+ count = -1;
+ }
+ }
+ else
+ count = -1;
+
+ if (info_verbose)
+ {
+ struct partial_symtab *ps;
+
+ /* Read in symbols for all of the frames. Need to do this in
+ a separate pass so that "Reading in symbols for xxx" messages
+ don't screw up the appearance of the backtrace. Also
+ if people have strong opinions against reading symbols for
+ backtrace this may have to be an option. */
+ i = count;
+ for (fi = trailing;
+ fi != NULL && i--;
+ fi = get_prev_frame (fi))
+ {
+ QUIT;
+ ps = find_pc_psymtab (fi->pc);
+ if (ps)
+ PSYMTAB_TO_SYMTAB (ps); /* Force syms to come in */
+ }
+ }
+
+ for (i = 0, fi = trailing;
+ fi && count--;
+ i++, fi = get_prev_frame (fi))
+ {
+ QUIT;
+
+ /* Don't use print_stack_frame; if an error() occurs it probably
+ means further attempts to backtrace would fail (on the other
+ hand, perhaps the code does or could be fixed to make sure
+ the frame->prev field gets set to NULL in that case). */
+ print_frame_info_base (fi, trailing_level + i, 0, 1);
+ if (show_locals)
+ print_frame_local_vars (fi, 1, gdb_stdout);
+ }
+
+ /* If we've stopped before the end, mention that. */
+ if (fi && from_tty)
+ printf_filtered ("(More stack frames follow...)\n");
+}
+
+static void
+backtrace_command (char *arg, int from_tty)
+{
+ struct cleanup *old_chain = (struct cleanup *) NULL;
+ char **argv = (char **) NULL;
+ int argIndicatingFullTrace = (-1), totArgLen = 0, argc = 0;
+ char *argPtr = arg;
+
+ if (arg != (char *) NULL)
+ {
+ int i;
+
+ argv = buildargv (arg);
+ old_chain = make_cleanup_freeargv (argv);
+ argc = 0;
+ for (i = 0; (argv[i] != (char *) NULL); i++)
+ {
+ unsigned int j;
+
+ for (j = 0; (j < strlen (argv[i])); j++)
+ argv[i][j] = tolower (argv[i][j]);
+
+ if (argIndicatingFullTrace < 0 && subset_compare (argv[i], "full"))
+ argIndicatingFullTrace = argc;
+ else
+ {
+ argc++;
+ totArgLen += strlen (argv[i]);
+ }
+ }
+ totArgLen += argc;
+ if (argIndicatingFullTrace >= 0)
+ {
+ if (totArgLen > 0)
+ {
+ argPtr = (char *) xmalloc (totArgLen + 1);
+ if (!argPtr)
+ nomem (0);
+ else
+ {
+ memset (argPtr, 0, totArgLen + 1);
+ for (i = 0; (i < (argc + 1)); i++)
+ {
+ if (i != argIndicatingFullTrace)
+ {
+ strcat (argPtr, argv[i]);
+ strcat (argPtr, " ");
+ }
+ }
+ }
+ }
+ else
+ argPtr = (char *) NULL;
+ }
+ }
+
+ backtrace_command_1 (argPtr, (argIndicatingFullTrace >= 0), from_tty);
+
+ if (argIndicatingFullTrace >= 0 && totArgLen > 0)
+ xfree (argPtr);
+
+ if (old_chain)
+ do_cleanups (old_chain);
+}
+
+static void backtrace_full_command (char *arg, int from_tty);
+static void
+backtrace_full_command (char *arg, int from_tty)
+{
+ backtrace_command_1 (arg, 1, from_tty);
+}
+
+
+/* Print the local variables of a block B active in FRAME.
+ Return 1 if any variables were printed; 0 otherwise. */
+
+static int
+print_block_frame_locals (struct block *b, register struct frame_info *fi,
+ int num_tabs, register struct ui_file *stream)
+{
+ register int i, j;
+ register struct symbol *sym;
+ register int values_printed = 0;
+
+ ALL_BLOCK_SYMBOLS (b, i, sym)
+ {
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_LOCAL:
+ case LOC_REGISTER:
+ case LOC_STATIC:
+ case LOC_BASEREG:
+ values_printed = 1;
+ for (j = 0; j < num_tabs; j++)
+ fputs_filtered ("\t", stream);
+ fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream);
+ fputs_filtered (" = ", stream);
+ print_variable_value (sym, fi, stream);
+ fprintf_filtered (stream, "\n");
+ break;
+
+ default:
+ /* Ignore symbols which are not locals. */
+ break;
+ }
+ }
+ return values_printed;
+}
+
+/* Same, but print labels. */
+
+static int
+print_block_frame_labels (struct block *b, int *have_default,
+ register struct ui_file *stream)
+{
+ register int i;
+ register struct symbol *sym;
+ register int values_printed = 0;
+
+ ALL_BLOCK_SYMBOLS (b, i, sym)
+ {
+ if (STREQ (SYMBOL_NAME (sym), "default"))
+ {
+ if (*have_default)
+ continue;
+ *have_default = 1;
+ }
+ if (SYMBOL_CLASS (sym) == LOC_LABEL)
+ {
+ struct symtab_and_line sal;
+ sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), 0);
+ values_printed = 1;
+ fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream);
+ if (addressprint)
+ {
+ fprintf_filtered (stream, " ");
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, stream);
+ }
+ fprintf_filtered (stream, " in file %s, line %d\n",
+ sal.symtab->filename, sal.line);
+ }
+ }
+ return values_printed;
+}
+
+/* Print on STREAM all the local variables in frame FRAME,
+ including all the blocks active in that frame
+ at its current pc.
+
+ Returns 1 if the job was done,
+ or 0 if nothing was printed because we have no info
+ on the function running in FRAME. */
+
+static void
+print_frame_local_vars (register struct frame_info *fi, register int num_tabs,
+ register struct ui_file *stream)
+{
+ register struct block *block = get_frame_block (fi, 0);
+ register int values_printed = 0;
+
+ if (block == 0)
+ {
+ fprintf_filtered (stream, "No symbol table info available.\n");
+ return;
+ }
+
+ while (block != 0)
+ {
+ if (print_block_frame_locals (block, fi, num_tabs, stream))
+ values_printed = 1;
+ /* After handling the function's top-level block, stop.
+ Don't continue to its superblock, the block of
+ per-file symbols. */
+ if (BLOCK_FUNCTION (block))
+ break;
+ block = BLOCK_SUPERBLOCK (block);
+ }
+
+ if (!values_printed)
+ {
+ fprintf_filtered (stream, "No locals.\n");
+ }
+}
+
+/* Same, but print labels. */
+
+static void
+print_frame_label_vars (register struct frame_info *fi, int this_level_only,
+ register struct ui_file *stream)
+{
+ register struct blockvector *bl;
+ register struct block *block = get_frame_block (fi, 0);
+ register int values_printed = 0;
+ int index, have_default = 0;
+ char *blocks_printed;
+ CORE_ADDR pc = fi->pc;
+
+ if (block == 0)
+ {
+ fprintf_filtered (stream, "No symbol table info available.\n");
+ return;
+ }
+
+ bl = blockvector_for_pc (BLOCK_END (block) - 4, &index);
+ blocks_printed = (char *) alloca (BLOCKVECTOR_NBLOCKS (bl) * sizeof (char));
+ memset (blocks_printed, 0, BLOCKVECTOR_NBLOCKS (bl) * sizeof (char));
+
+ while (block != 0)
+ {
+ CORE_ADDR end = BLOCK_END (block) - 4;
+ int last_index;
+
+ if (bl != blockvector_for_pc (end, &index))
+ error ("blockvector blotch");
+ if (BLOCKVECTOR_BLOCK (bl, index) != block)
+ error ("blockvector botch");
+ last_index = BLOCKVECTOR_NBLOCKS (bl);
+ index += 1;
+
+ /* Don't print out blocks that have gone by. */
+ while (index < last_index
+ && BLOCK_END (BLOCKVECTOR_BLOCK (bl, index)) < pc)
+ index++;
+
+ while (index < last_index
+ && BLOCK_END (BLOCKVECTOR_BLOCK (bl, index)) < end)
+ {
+ if (blocks_printed[index] == 0)
+ {
+ if (print_block_frame_labels (BLOCKVECTOR_BLOCK (bl, index), &have_default, stream))
+ values_printed = 1;
+ blocks_printed[index] = 1;
+ }
+ index++;
+ }
+ if (have_default)
+ return;
+ if (values_printed && this_level_only)
+ return;
+
+ /* After handling the function's top-level block, stop.
+ Don't continue to its superblock, the block of
+ per-file symbols. */
+ if (BLOCK_FUNCTION (block))
+ break;
+ block = BLOCK_SUPERBLOCK (block);
+ }
+
+ if (!values_printed && !this_level_only)
+ {
+ fprintf_filtered (stream, "No catches.\n");
+ }
+}
+
+/* ARGSUSED */
+void
+locals_info (char *args, int from_tty)
+{
+ if (!selected_frame)
+ error ("No frame selected.");
+ print_frame_local_vars (selected_frame, 0, gdb_stdout);
+}
+
+static void
+catch_info (char *ignore, int from_tty)
+{
+ struct symtab_and_line *sal;
+
+ /* Check for target support for exception handling */
+ sal = target_enable_exception_callback (EX_EVENT_CATCH, 1);
+ if (sal)
+ {
+ /* Currently not handling this */
+ /* Ideally, here we should interact with the C++ runtime
+ system to find the list of active handlers, etc. */
+ fprintf_filtered (gdb_stdout, "Info catch not supported with this target/compiler combination.\n");
+#if 0
+ if (!selected_frame)
+ error ("No frame selected.");
+#endif
+ }
+ else
+ {
+ /* Assume g++ compiled code -- old v 4.16 behaviour */
+ if (!selected_frame)
+ error ("No frame selected.");
+
+ print_frame_label_vars (selected_frame, 0, gdb_stdout);
+ }
+}
+
+static void
+print_frame_arg_vars (register struct frame_info *fi,
+ register struct ui_file *stream)
+{
+ struct symbol *func = get_frame_function (fi);
+ register struct block *b;
+ register int i;
+ register struct symbol *sym, *sym2;
+ register int values_printed = 0;
+
+ if (func == 0)
+ {
+ fprintf_filtered (stream, "No symbol table info available.\n");
+ return;
+ }
+
+ b = SYMBOL_BLOCK_VALUE (func);
+ ALL_BLOCK_SYMBOLS (b, i, sym)
+ {
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_ARG:
+ case LOC_LOCAL_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_BASEREG_ARG:
+ values_printed = 1;
+ fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream);
+ fputs_filtered (" = ", stream);
+
+ /* We have to look up the symbol because arguments can have
+ two entries (one a parameter, one a local) and the one we
+ want is the local, which lookup_symbol will find for us.
+ This includes gcc1 (not gcc2) on the sparc when passing a
+ small structure and gcc2 when the argument type is float
+ and it is passed as a double and converted to float by
+ the prologue (in the latter case the type of the LOC_ARG
+ symbol is double and the type of the LOC_LOCAL symbol is
+ float). There are also LOC_ARG/LOC_REGISTER pairs which
+ are not combined in symbol-reading. */
+
+ sym2 = lookup_symbol (SYMBOL_NAME (sym),
+ b, VAR_NAMESPACE, (int *) NULL, (struct symtab **) NULL);
+ print_variable_value (sym2, fi, stream);
+ fprintf_filtered (stream, "\n");
+ break;
+
+ default:
+ /* Don't worry about things which aren't arguments. */
+ break;
+ }
+ }
+ if (!values_printed)
+ {
+ fprintf_filtered (stream, "No arguments.\n");
+ }
+}
+
+void
+args_info (char *ignore, int from_tty)
+{
+ if (!selected_frame)
+ error ("No frame selected.");
+ print_frame_arg_vars (selected_frame, gdb_stdout);
+}
+
+
+static void
+args_plus_locals_info (char *ignore, int from_tty)
+{
+ args_info (ignore, from_tty);
+ locals_info (ignore, from_tty);
+}
+
+
+/* Select frame FI (or NULL - to invalidate the current frame). */
+
+void
+select_frame (struct frame_info *fi)
+{
+ register struct symtab *s;
+
+ selected_frame = fi;
+ /* NOTE: cagney/2002-05-04: FI can be NULL. This occures when the
+ frame is being invalidated. */
+ if (selected_frame_level_changed_hook)
+ selected_frame_level_changed_hook (frame_relative_level (fi));
+
+ /* Ensure that symbols for this frame are read in. Also, determine the
+ source language of this frame, and switch to it if desired. */
+ if (fi)
+ {
+ s = find_pc_symtab (fi->pc);
+ if (s
+ && s->language != current_language->la_language
+ && s->language != language_unknown
+ && language_mode == language_mode_auto)
+ {
+ set_language (s->language);
+ }
+ }
+}
+
+
+/* Select frame FI. Also print the stack frame and show the source if
+ this is the tui version. */
+static void
+select_and_print_frame (struct frame_info *fi)
+{
+ select_frame (fi);
+ if (fi)
+ {
+ print_stack_frame (fi, frame_relative_level (fi), 1);
+ }
+}
+
+
+/* Store the selected frame and its level into *FRAMEP and *LEVELP.
+ If there is no selected frame, *FRAMEP is set to NULL. */
+
+void
+record_selected_frame (CORE_ADDR *frameaddrp, int *levelp)
+{
+ *frameaddrp = selected_frame ? selected_frame->frame : 0;
+ *levelp = frame_relative_level (selected_frame);
+}
+
+/* Return the symbol-block in which the selected frame is executing.
+ Can return zero under various legitimate circumstances.
+
+ If ADDR_IN_BLOCK is non-zero, set *ADDR_IN_BLOCK to the relevant
+ code address within the block returned. We use this to decide
+ which macros are in scope. */
+
+struct block *
+get_selected_block (CORE_ADDR *addr_in_block)
+{
+ if (!target_has_stack)
+ return 0;
+
+ if (!selected_frame)
+ return get_current_block (addr_in_block);
+ return get_frame_block (selected_frame, addr_in_block);
+}
+
+/* Find a frame a certain number of levels away from FRAME.
+ LEVEL_OFFSET_PTR points to an int containing the number of levels.
+ Positive means go to earlier frames (up); negative, the reverse.
+ The int that contains the number of levels is counted toward
+ zero as the frames for those levels are found.
+ If the top or bottom frame is reached, that frame is returned,
+ but the final value of *LEVEL_OFFSET_PTR is nonzero and indicates
+ how much farther the original request asked to go. */
+
+struct frame_info *
+find_relative_frame (register struct frame_info *frame,
+ register int *level_offset_ptr)
+{
+ register struct frame_info *prev;
+ register struct frame_info *frame1;
+
+ /* Going up is simple: just do get_prev_frame enough times
+ or until initial frame is reached. */
+ while (*level_offset_ptr > 0)
+ {
+ prev = get_prev_frame (frame);
+ if (prev == 0)
+ break;
+ (*level_offset_ptr)--;
+ frame = prev;
+ }
+ /* Going down is just as simple. */
+ if (*level_offset_ptr < 0)
+ {
+ while (*level_offset_ptr < 0)
+ {
+ frame1 = get_next_frame (frame);
+ if (!frame1)
+ break;
+ frame = frame1;
+ (*level_offset_ptr)++;
+ }
+ }
+ return frame;
+}
+
+/* The "select_frame" command. With no arg, NOP.
+ With arg LEVEL_EXP, select the frame at level LEVEL if it is a
+ valid level. Otherwise, treat level_exp as an address expression
+ and select it. See parse_frame_specification for more info on proper
+ frame expressions. */
+
+/* ARGSUSED */
+void
+select_frame_command_wrapper (char *level_exp, int from_tty)
+{
+ select_frame_command (level_exp, from_tty);
+}
+
+static void
+select_frame_command (char *level_exp, int from_tty)
+{
+ register struct frame_info *frame, *frame1;
+ unsigned int level = 0;
+
+ if (!target_has_stack)
+ error ("No stack.");
+
+ frame = parse_frame_specification (level_exp);
+
+ select_frame (frame);
+}
+
+/* The "frame" command. With no arg, print selected frame briefly.
+ With arg, behaves like select_frame and then prints the selected
+ frame. */
+
+void
+frame_command (char *level_exp, int from_tty)
+{
+ select_frame_command (level_exp, from_tty);
+ show_and_print_stack_frame (selected_frame,
+ frame_relative_level (selected_frame), 1);
+}
+
+/* The XDB Compatibility command to print the current frame. */
+
+static void
+current_frame_command (char *level_exp, int from_tty)
+{
+ if (target_has_stack == 0 || selected_frame == 0)
+ error ("No stack.");
+ print_only_stack_frame (selected_frame,
+ frame_relative_level (selected_frame), 1);
+}
+
+/* Select the frame up one or COUNT stack levels
+ from the previously selected frame, and print it briefly. */
+
+/* ARGSUSED */
+static void
+up_silently_base (char *count_exp)
+{
+ register struct frame_info *fi;
+ int count = 1, count1;
+ if (count_exp)
+ count = parse_and_eval_long (count_exp);
+ count1 = count;
+
+ if (target_has_stack == 0 || selected_frame == 0)
+ error ("No stack.");
+
+ fi = find_relative_frame (selected_frame, &count1);
+ if (count1 != 0 && count_exp == 0)
+ error ("Initial frame selected; you cannot go up.");
+ select_frame (fi);
+}
+
+static void
+up_silently_command (char *count_exp, int from_tty)
+{
+ up_silently_base (count_exp);
+}
+
+static void
+up_command (char *count_exp, int from_tty)
+{
+ up_silently_base (count_exp);
+ show_and_print_stack_frame (selected_frame,
+ frame_relative_level (selected_frame), 1);
+}
+
+/* Select the frame down one or COUNT stack levels
+ from the previously selected frame, and print it briefly. */
+
+/* ARGSUSED */
+static void
+down_silently_base (char *count_exp)
+{
+ register struct frame_info *frame;
+ int count = -1, count1;
+ if (count_exp)
+ count = -parse_and_eval_long (count_exp);
+ count1 = count;
+
+ if (target_has_stack == 0 || selected_frame == 0)
+ error ("No stack.");
+
+ frame = find_relative_frame (selected_frame, &count1);
+ if (count1 != 0 && count_exp == 0)
+ {
+
+ /* We only do this if count_exp is not specified. That way "down"
+ means to really go down (and let me know if that is
+ impossible), but "down 9999" can be used to mean go all the way
+ down without getting an error. */
+
+ error ("Bottom (i.e., innermost) frame selected; you cannot go down.");
+ }
+
+ select_frame (frame);
+}
+
+/* ARGSUSED */
+static void
+down_silently_command (char *count_exp, int from_tty)
+{
+ down_silently_base (count_exp);
+}
+
+static void
+down_command (char *count_exp, int from_tty)
+{
+ down_silently_base (count_exp);
+ show_and_print_stack_frame (selected_frame,
+ frame_relative_level (selected_frame), 1);
+}
+
+void
+return_command_wrapper (char *retval_exp, int from_tty)
+{
+ return_command (retval_exp, from_tty);
+}
+
+static void
+return_command (char *retval_exp, int from_tty)
+{
+ struct symbol *thisfun;
+ CORE_ADDR selected_frame_addr;
+ CORE_ADDR selected_frame_pc;
+ struct frame_info *frame;
+ struct value *return_value = NULL;
+
+ if (selected_frame == NULL)
+ error ("No selected frame.");
+ thisfun = get_frame_function (selected_frame);
+ selected_frame_addr = FRAME_FP (selected_frame);
+ selected_frame_pc = selected_frame->pc;
+
+ /* Compute the return value (if any -- possibly getting errors here). */
+
+ if (retval_exp)
+ {
+ struct type *return_type = NULL;
+
+ return_value = parse_and_eval (retval_exp);
+
+ /* Cast return value to the return type of the function. */
+ if (thisfun != NULL)
+ return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun));
+ if (return_type == NULL)
+ return_type = builtin_type_int;
+ return_value = value_cast (return_type, return_value);
+
+ /* Make sure we have fully evaluated it, since
+ it might live in the stack frame we're about to pop. */
+ if (VALUE_LAZY (return_value))
+ value_fetch_lazy (return_value);
+ }
+
+ /* If interactive, require confirmation. */
+
+ if (from_tty)
+ {
+ if (thisfun != 0)
+ {
+ if (!query ("Make %s return now? ", SYMBOL_SOURCE_NAME (thisfun)))
+ {
+ error ("Not confirmed.");
+ /* NOTREACHED */
+ }
+ }
+ else if (!query ("Make selected stack frame return now? "))
+ error ("Not confirmed.");
+ }
+
+ /* Do the real work. Pop until the specified frame is current. We
+ use this method because the selected_frame is not valid after
+ a POP_FRAME. The pc comparison makes this work even if the
+ selected frame shares its fp with another frame. */
+
+ while (selected_frame_addr != (frame = get_current_frame ())->frame
+ || selected_frame_pc != frame->pc)
+ POP_FRAME;
+
+ /* Then pop that frame. */
+
+ POP_FRAME;
+
+ /* Compute the return value (if any) and store in the place
+ for return values. */
+
+ if (retval_exp)
+ set_return_value (return_value);
+
+ /* If we are at the end of a call dummy now, pop the dummy frame too. */
+
+ if (CALL_DUMMY_HAS_COMPLETED (read_pc(), read_sp (),
+ FRAME_FP (get_current_frame ())))
+ POP_FRAME;
+
+ /* If interactive, print the frame that is now current. */
+
+ if (from_tty)
+ frame_command ("0", 1);
+ else
+ select_frame_command ("0", 0);
+}
+
+/* Sets the scope to input function name, provided that the
+ function is within the current stack frame */
+
+struct function_bounds
+{
+ CORE_ADDR low, high;
+};
+
+static void func_command (char *arg, int from_tty);
+static void
+func_command (char *arg, int from_tty)
+{
+ struct frame_info *fp;
+ int found = 0;
+ struct symtabs_and_lines sals;
+ int i;
+ int level = 1;
+ struct function_bounds *func_bounds = (struct function_bounds *) NULL;
+
+ if (arg != (char *) NULL)
+ return;
+
+ fp = parse_frame_specification ("0");
+ sals = decode_line_spec (arg, 1);
+ func_bounds = (struct function_bounds *) xmalloc (
+ sizeof (struct function_bounds) * sals.nelts);
+ for (i = 0; (i < sals.nelts && !found); i++)
+ {
+ if (sals.sals[i].pc == (CORE_ADDR) 0 ||
+ find_pc_partial_function (sals.sals[i].pc,
+ (char **) NULL,
+ &func_bounds[i].low,
+ &func_bounds[i].high) == 0)
+ {
+ func_bounds[i].low =
+ func_bounds[i].high = (CORE_ADDR) NULL;
+ }
+ }
+
+ do
+ {
+ for (i = 0; (i < sals.nelts && !found); i++)
+ found = (fp->pc >= func_bounds[i].low &&
+ fp->pc < func_bounds[i].high);
+ if (!found)
+ {
+ level = 1;
+ fp = find_relative_frame (fp, &level);
+ }
+ }
+ while (!found && level == 0);
+
+ if (func_bounds)
+ xfree (func_bounds);
+
+ if (!found)
+ printf_filtered ("'%s' not within current stack frame.\n", arg);
+ else if (fp != selected_frame)
+ select_and_print_frame (fp);
+}
+
+/* Gets the language of the current frame. */
+
+enum language
+get_frame_language (void)
+{
+ register struct symtab *s;
+ enum language flang; /* The language of the current frame */
+
+ if (selected_frame)
+ {
+ s = find_pc_symtab (selected_frame->pc);
+ if (s)
+ flang = s->language;
+ else
+ flang = language_unknown;
+ }
+ else
+ flang = language_unknown;
+
+ return flang;
+}
+
+void
+_initialize_stack (void)
+{
+#if 0
+ backtrace_limit = 30;
+#endif
+
+ add_com ("return", class_stack, return_command,
+ "Make selected stack frame return to its caller.\n\
+Control remains in the debugger, but when you continue\n\
+execution will resume in the frame above the one now selected.\n\
+If an argument is given, it is an expression for the value to return.");
+
+ add_com ("up", class_stack, up_command,
+ "Select and print stack frame that called this one.\n\
+An argument says how many frames up to go.");
+ add_com ("up-silently", class_support, up_silently_command,
+ "Same as the `up' command, but does not print anything.\n\
+This is useful in command scripts.");
+
+ add_com ("down", class_stack, down_command,
+ "Select and print stack frame called by this one.\n\
+An argument says how many frames down to go.");
+ add_com_alias ("do", "down", class_stack, 1);
+ add_com_alias ("dow", "down", class_stack, 1);
+ add_com ("down-silently", class_support, down_silently_command,
+ "Same as the `down' command, but does not print anything.\n\
+This is useful in command scripts.");
+
+ add_com ("frame", class_stack, frame_command,
+ "Select and print a stack frame.\n\
+With no argument, print the selected stack frame. (See also \"info frame\").\n\
+An argument specifies the frame to select.\n\
+It can be a stack frame number or the address of the frame.\n\
+With argument, nothing is printed if input is coming from\n\
+a command file or a user-defined command.");
+
+ add_com_alias ("f", "frame", class_stack, 1);
+
+ if (xdb_commands)
+ {
+ add_com ("L", class_stack, current_frame_command,
+ "Print the current stack frame.\n");
+ add_com_alias ("V", "frame", class_stack, 1);
+ }
+ add_com ("select-frame", class_stack, select_frame_command,
+ "Select a stack frame without printing anything.\n\
+An argument specifies the frame to select.\n\
+It can be a stack frame number or the address of the frame.\n");
+
+ add_com ("backtrace", class_stack, backtrace_command,
+ "Print backtrace of all stack frames, or innermost COUNT frames.\n\
+With a negative argument, print outermost -COUNT frames.\n\
+Use of the 'full' qualifier also prints the values of the local variables.\n");
+ add_com_alias ("bt", "backtrace", class_stack, 0);
+ if (xdb_commands)
+ {
+ add_com_alias ("t", "backtrace", class_stack, 0);
+ add_com ("T", class_stack, backtrace_full_command,
+ "Print backtrace of all stack frames, or innermost COUNT frames \n\
+and the values of the local variables.\n\
+With a negative argument, print outermost -COUNT frames.\n\
+Usage: T <count>\n");
+ }
+
+ add_com_alias ("where", "backtrace", class_alias, 0);
+ add_info ("stack", backtrace_command,
+ "Backtrace of the stack, or innermost COUNT frames.");
+ add_info_alias ("s", "stack", 1);
+ add_info ("frame", frame_info,
+ "All about selected stack frame, or frame at ADDR.");
+ add_info_alias ("f", "frame", 1);
+ add_info ("locals", locals_info,
+ "Local variables of current stack frame.");
+ add_info ("args", args_info,
+ "Argument variables of current stack frame.");
+ if (xdb_commands)
+ add_com ("l", class_info, args_plus_locals_info,
+ "Argument and local variables of current stack frame.");
+
+ if (dbx_commands)
+ add_com ("func", class_stack, func_command,
+ "Select the stack frame that contains <func>.\nUsage: func <name>\n");
+
+ add_info ("catch", catch_info,
+ "Exceptions that can be caught in the current stack frame.");
+
+#if 0
+ add_cmd ("backtrace-limit", class_stack, set_backtrace_limit_command,
+ "Specify maximum number of frames for \"backtrace\" to print by default.",
+ &setlist);
+ add_info ("backtrace-limit", backtrace_limit_info,
+ "The maximum number of frames for \"backtrace\" to print by default.");
+#endif
+}
diff --git a/gdb/standalone.c b/gdb/standalone.c
new file mode 100644
index 00000000000..6ae8f5398b8
--- /dev/null
+++ b/gdb/standalone.c
@@ -0,0 +1,579 @@
+/* Interface to bare machine for GDB running as kernel debugger.
+ Copyright 1986, 1989, 1991, 1992, 1993, 1995, 1996, 2000, 2001
+ 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 <stdio.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include "gdb_stat.h"
+
+#if defined (SIGTSTP) && defined (SIGIO)
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif /* SIGTSTP and SIGIO defined (must be 4.2) */
+
+#include "defs.h"
+#include <signal.h>
+#include "symtab.h"
+#include "frame.h"
+#include "inferior.h"
+#include "gdb_wait.h"
+
+
+/* Random system calls, mostly no-ops to prevent link problems */
+
+ioctl (int desc, int code, int arg)
+{
+}
+
+int (*signal ()) ()
+{
+}
+
+kill (void)
+{
+}
+
+getpid (void)
+{
+ return 0;
+}
+
+sigsetmask (void)
+{
+}
+
+chdir (void)
+{
+}
+
+char *
+getcwd (char *buf, unsigned int len)
+{
+ buf[0] = '/';
+ buf[1] = 0;
+ return buf;
+}
+
+/* Used to check for existence of .gdbinit. Say no. */
+
+access (void)
+{
+ return -1;
+}
+
+exit (void)
+{
+ error ("Fatal error; restarting.");
+}
+
+/* Reading "files". The contents of some files are written into kdb's
+ data area before it is run. These files are used to contain the
+ symbol table for kdb to load, and the source files (in case the
+ kdb user wants to print them). The symbols are stored in a file
+ named "kdb-symbols" in a.out format (except that all the text and
+ data have been stripped to save room).
+
+ The files are stored in the following format:
+ int number of bytes of data for this file, including these four.
+ char[] name of the file, ending with a null.
+ padding to multiple of 4 boundary.
+ char[] file contents. The length can be deduced from what was
+ specified before. There is no terminating null here.
+
+ If the int at the front is zero, it means there are no more files.
+
+ Opening a file in kdb returns a nonzero value to indicate success,
+ but the value does not matter. Only one file can be open, and only
+ for reading. All the primitives for input from the file know
+ which file is open and ignore what is specified for the descriptor
+ or for the stdio stream.
+
+ Input with fgetc can be done either on the file that is open
+ or on stdin (which reads from the terminal through tty_input () */
+
+/* Address of data for the files stored in format described above. */
+char *files_start;
+
+/* The file stream currently open: */
+
+char *sourcebeg; /* beginning of contents */
+int sourcesize; /* size of contents */
+char *sourceptr; /* current read pointer */
+int sourceleft; /* number of bytes to eof */
+
+/* "descriptor" for the file now open.
+ Incremented at each close.
+ If specified descriptor does not match this,
+ it means the program is trying to use a closed descriptor.
+ We report an error for that. */
+
+int sourcedesc;
+
+open (char *filename, int modes)
+{
+ register char *next;
+
+ if (modes)
+ {
+ errno = EROFS;
+ return -1;
+ }
+
+ if (sourceptr)
+ {
+ errno = EMFILE;
+ return -1;
+ }
+
+ for (next = files_start; *(int *) next; next += *(int *) next)
+ {
+ if (!strcmp (next + 4, filename))
+ {
+ sourcebeg = next + 4 + strlen (next + 4) + 1;
+ sourcebeg = (char *) (((int) sourcebeg + 3) & (-4));
+ sourceptr = sourcebeg;
+ sourcesize = next + *(int *) next - sourceptr;
+ sourceleft = sourcesize;
+ return sourcedesc;
+ }
+ }
+ return 0;
+}
+
+close (int desc)
+{
+ sourceptr = 0;
+ sourcedesc++;
+ /* Don't let sourcedesc get big enough to be confused with stdin. */
+ if (sourcedesc == 100)
+ sourcedesc = 5;
+}
+
+FILE *
+fopen (char *filename, char *modes)
+{
+ return (FILE *) open (filename, *modes == 'w');
+}
+
+FILE *
+fdopen (int desc)
+{
+ return (FILE *) desc;
+}
+
+fclose (int desc)
+{
+ close (desc);
+}
+
+fstat (int desc, struct stat *statbuf)
+{
+ if (desc != sourcedesc)
+ {
+ errno = EBADF;
+ return -1;
+ }
+ statbuf->st_size = sourcesize;
+}
+
+myread (int desc, char *destptr, int size, char *filename)
+{
+ int len = min (sourceleft, size);
+
+ if (desc != sourcedesc)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ memcpy (destptr, sourceptr, len);
+ sourceleft -= len;
+ return len;
+}
+
+int
+fread (int bufp, int numelts, int eltsize, int stream)
+{
+ register int elts = min (numelts, sourceleft / eltsize);
+ register int len = elts * eltsize;
+
+ if (stream != sourcedesc)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ memcpy (bufp, sourceptr, len);
+ sourceleft -= len;
+ return elts;
+}
+
+int
+fgetc (int desc)
+{
+
+ if (desc == (int) stdin)
+ return tty_input ();
+
+ if (desc != sourcedesc)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (sourceleft-- <= 0)
+ return EOF;
+ return *sourceptr++;
+}
+
+lseek (int desc, int pos)
+{
+
+ if (desc != sourcedesc)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (pos < 0 || pos > sourcesize)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ sourceptr = sourcebeg + pos;
+ sourceleft = sourcesize - pos;
+}
+
+/* Output in kdb can go only to the terminal, so the stream
+ specified may be ignored. */
+
+printf (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9)
+{
+ char buffer[1024];
+ sprintf (buffer, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ display_string (buffer);
+}
+
+fprintf (int ign, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9)
+{
+ char buffer[1024];
+ sprintf (buffer, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ display_string (buffer);
+}
+
+fwrite (register char *buf, int numelts, int size, int stream)
+{
+ register int i = numelts * size;
+ while (i-- > 0)
+ fputc (*buf++, stream);
+}
+
+fputc (int c, int ign)
+{
+ char buf[2];
+ buf[0] = c;
+ buf[1] = 0;
+ display_string (buf);
+}
+
+/* sprintf refers to this, but loading this from the
+ library would cause fflush to be loaded from it too.
+ In fact there should be no need to call this (I hope). */
+
+_flsbuf (void)
+{
+ error ("_flsbuf was actually called.");
+}
+
+fflush (int ign)
+{
+}
+
+/* Entries into core and inflow, needed only to make things link ok. */
+
+exec_file_command (void)
+{
+}
+
+core_file_command (void)
+{
+}
+
+char *
+get_exec_file (int err)
+{
+ /* Makes one printout look reasonable; value does not matter otherwise. */
+ return "run";
+}
+
+/* Nonzero if there is a core file. */
+
+have_core_file_p (void)
+{
+ return 0;
+}
+
+kill_command (void)
+{
+ inferior_ptid = null_ptid;
+}
+
+terminal_inferior (void)
+{
+}
+
+terminal_ours (void)
+{
+}
+
+terminal_init_inferior (void)
+{
+}
+
+write_inferior_register (void)
+{
+}
+
+read_inferior_register (void)
+{
+}
+
+read_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ memcpy (myaddr, memaddr, len);
+}
+
+/* Always return 0 indicating success. */
+
+write_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ memcpy (memaddr, myaddr, len);
+ return 0;
+}
+
+static REGISTER_TYPE saved_regs[NUM_REGS];
+
+REGISTER_TYPE
+read_register (int regno)
+{
+ if (regno < 0 || regno >= NUM_REGS)
+ error ("Register number %d out of range.", regno);
+ return saved_regs[regno];
+}
+
+void
+write_register (int regno, REGISTER_TYPE value)
+{
+ if (regno < 0 || regno >= NUM_REGS)
+ error ("Register number %d out of range.", regno);
+ saved_regs[regno] = value;
+}
+
+/* System calls needed in relation to running the "inferior". */
+
+vfork (void)
+{
+ /* Just appear to "succeed". Say the inferior's pid is 1. */
+ return 1;
+}
+
+/* These are called by code that normally runs in the inferior
+ that has just been forked. That code never runs, when standalone,
+ and these definitions are so it will link without errors. */
+
+ptrace (void)
+{
+}
+
+setpgrp (void)
+{
+}
+
+execle (void)
+{
+}
+
+_exit (void)
+{
+}
+
+/* Malloc calls these. */
+
+malloc_warning (char *str)
+{
+ printf ("\n%s.\n\n", str);
+}
+
+char *next_free;
+char *memory_limit;
+
+char *
+sbrk (int amount)
+{
+ if (next_free + amount > memory_limit)
+ return (char *) -1;
+ next_free += amount;
+ return next_free - amount;
+}
+
+/* Various ways malloc might ask where end of memory is. */
+
+char *
+ulimit (void)
+{
+ return memory_limit;
+}
+
+int
+vlimit (void)
+{
+ return memory_limit - next_free;
+}
+
+getrlimit (struct rlimit *addr)
+{
+ addr->rlim_cur = memory_limit - next_free;
+}
+
+/* Context switching to and from program being debugged. */
+
+/* GDB calls here to run the user program.
+ The frame pointer for this function is saved in
+ gdb_stack by save_frame_pointer; then we restore
+ all of the user program's registers, including PC and PS. */
+
+static int fault_code;
+static REGISTER_TYPE gdb_stack;
+
+resume (void)
+{
+ REGISTER_TYPE restore[NUM_REGS];
+
+ PUSH_FRAME_PTR;
+ save_frame_pointer ();
+
+ memcpy (restore, saved_regs, sizeof restore);
+ POP_REGISTERS;
+ /* Control does not drop through here! */
+}
+
+save_frame_pointer (CORE_ADDR val)
+{
+ gdb_stack = val;
+}
+
+/* Fault handlers call here, running in the user program stack.
+ They must first push a fault code,
+ old PC, old PS, and any other info about the fault.
+ The exact format is machine-dependent and is known only
+ in the definition of PUSH_REGISTERS. */
+
+fault (void)
+{
+ /* Transfer all registers and fault code to the stack
+ in canonical order: registers in order of GDB register number,
+ followed by fault code. */
+ PUSH_REGISTERS;
+
+ /* Transfer them to saved_regs and fault_code. */
+ save_registers ();
+
+ restore_gdb ();
+ /* Control does not reach here */
+}
+
+restore_gdb (void)
+{
+ CORE_ADDR new_fp = gdb_stack;
+ /* Switch to GDB's stack */
+ POP_FRAME_PTR;
+ /* Return from the function `resume'. */
+}
+
+/* Assuming register contents and fault code have been pushed on the stack as
+ arguments to this function, copy them into the standard place
+ for the program's registers while GDB is running. */
+
+save_registers (int firstreg)
+{
+ memcpy (saved_regs, &firstreg, sizeof saved_regs);
+ fault_code = (&firstreg)[NUM_REGS];
+}
+
+/* Store into the structure such as `wait' would return
+ the information on why the program faulted,
+ converted into a machine-independent signal number. */
+
+static int fault_table[] = FAULT_TABLE;
+
+int
+wait (WAITTYPE *w)
+{
+ WSETSTOP (*w, fault_table[fault_code / FAULT_CODE_UNITS]);
+ return PIDGET (inferior_ptid);
+}
+
+/* Allocate a big space in which files for kdb to read will be stored.
+ Whatever is left is where malloc can allocate storage.
+
+ Initialize it, so that there will be space in the executable file
+ for it. Then the files can be put into kdb by writing them into
+ kdb's executable file. */
+
+/* The default size is as much space as we expect to be available
+ for kdb to use! */
+
+#ifndef HEAP_SIZE
+#define HEAP_SIZE 400000
+#endif
+
+char heap[HEAP_SIZE] =
+{0};
+
+#ifndef STACK_SIZE
+#define STACK_SIZE 100000
+#endif
+
+int kdb_stack_beg[STACK_SIZE / sizeof (int)];
+int kdb_stack_end;
+
+_initialize_standalone (void)
+{
+ register char *next;
+
+ /* Find start of data on files. */
+
+ files_start = heap;
+
+ /* Find the end of the data on files. */
+
+ for (next = files_start; *(int *) next; next += *(int *) next)
+ {
+ }
+
+ /* That is where free storage starts for sbrk to give out. */
+ next_free = next;
+
+ memory_limit = heap + sizeof heap;
+}
diff --git a/gdb/std-regs.c b/gdb/std-regs.c
new file mode 100644
index 00000000000..b96c9018783
--- /dev/null
+++ b/gdb/std-regs.c
@@ -0,0 +1,150 @@
+/* Builtin frame register, for GDB, the GNU debugger.
+
+ Copyright 2002 Free Software Foundation, Inc.
+
+ Contributed by Red Hat.
+
+ 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 "defs.h"
+#include "builtin-regs.h"
+#include "frame.h"
+#include "gdbtypes.h"
+#include "value.h"
+
+/* Types that describe the various builtin registers. */
+
+static struct type *builtin_type_frame_reg;
+
+/* Constructors for those types. */
+
+static void
+build_builtin_type_frame_reg (void)
+{
+ /* $frame. */
+ if (builtin_type_frame_reg == NULL)
+ {
+#if 0
+ struct frame
+ {
+ void *base;
+ };
+#endif
+ builtin_type_frame_reg = init_composite_type ("frame", TYPE_CODE_STRUCT);
+ append_composite_type_field (builtin_type_frame_reg, "base",
+ builtin_type_void_data_ptr);
+ }
+}
+
+static struct value *
+value_of_builtin_frame_reg (struct frame_info *frame)
+{
+ struct value *val;
+ char *buf;
+ build_builtin_type_frame_reg ();
+ val = allocate_value (builtin_type_frame_reg);
+ VALUE_LVAL (val) = not_lval;
+ buf = VALUE_CONTENTS_RAW (val);
+ memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0);
+ /* frame.base. */
+ if (frame != NULL)
+ ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf, frame->frame);
+ buf += TYPE_LENGTH (builtin_type_void_data_ptr);
+ /* frame.XXX. */
+ return val;
+}
+
+static struct value *
+value_of_builtin_frame_fp_reg (struct frame_info *frame)
+{
+#ifdef FP_REGNUM
+ if (FP_REGNUM >= 0)
+ return value_of_register (FP_REGNUM, frame);
+#endif
+ {
+ struct value *val = allocate_value (builtin_type_void_data_ptr);
+ char *buf = VALUE_CONTENTS_RAW (val);
+ if (frame == NULL)
+ memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0);
+ else
+ ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf, frame->frame);
+ return val;
+ }
+}
+
+static struct value *
+value_of_builtin_frame_pc_reg (struct frame_info *frame)
+{
+#ifdef PC_REGNUM
+ if (PC_REGNUM >= 0)
+ return value_of_register (PC_REGNUM, frame);
+#endif
+ {
+ struct value *val = allocate_value (builtin_type_void_data_ptr);
+ char *buf = VALUE_CONTENTS_RAW (val);
+ if (frame == NULL)
+ memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0);
+ else
+ ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf, frame->pc);
+ return val;
+ }
+}
+
+static struct value *
+value_of_builtin_frame_sp_reg (struct frame_info *frame)
+{
+#ifdef SP_REGNUM
+ if (SP_REGNUM >= 0)
+ return value_of_register (SP_REGNUM, frame);
+#endif
+ error ("Standard register ``$sp'' is not available for this target");
+}
+
+static struct value *
+value_of_builtin_frame_ps_reg (struct frame_info *frame)
+{
+#ifdef PS_REGNUM
+ if (PS_REGNUM >= 0)
+ return value_of_register (PS_REGNUM, frame);
+#endif
+ error ("Standard register ``$ps'' is not available for this target");
+}
+
+void
+_initialize_frame_reg (void)
+{
+ /* FIXME: cagney/2002-02-08: At present the local builtin types
+ can't be initialized using _initialize*() or gdbarch. Due mainly
+ to non-multi-arch targets, GDB initializes things piece meal and,
+ as a consequence can leave these types NULL. */
+ REGISTER_GDBARCH_SWAP (builtin_type_frame_reg);
+
+ /* Frame based $fp, $pc, $sp and $ps. These only come into play
+ when the target does not define its own version of these
+ registers. */
+ add_builtin_reg ("fp", value_of_builtin_frame_fp_reg);
+ add_builtin_reg ("pc", value_of_builtin_frame_pc_reg);
+ add_builtin_reg ("sp", value_of_builtin_frame_sp_reg);
+ add_builtin_reg ("ps", value_of_builtin_frame_ps_reg);
+
+ /* NOTE: cagney/2002-04-05: For moment leave the $frame / $gdbframe
+ / $gdb.frame disabled. It isn't yet clear which of the many
+ options is the best. */
+ if (0)
+ add_builtin_reg ("frame", value_of_builtin_frame_reg);
+}
diff --git a/gdb/stop-gdb.c b/gdb/stop-gdb.c
new file mode 100644
index 00000000000..ee84609664c
--- /dev/null
+++ b/gdb/stop-gdb.c
@@ -0,0 +1,109 @@
+/* A client to make GDB return to command level in Mach 3.
+ Copyright 1992, 1993, 1994, 2000 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. */
+
+/* Authors: Jukka Virtanen <jtv@hut.fi> and Peter Stout <pds@cs.cmu.edu>.
+
+ A simple client to make GDB (versions 4.4 and later) on Mach 3 return
+ to the command level when it is waiting for the inferior to stop.
+
+ Actions: Lookup the send right to the GDB message port from the
+ NetMsgServer.
+
+ Send an asynchronous message with msgh_id
+ GDB_MESSAGE_ID_STOP to that port.
+ */
+
+#include <stdio.h>
+
+#include "defs.h"
+
+#include <mach.h>
+#include <mach/message.h>
+#include <mach_error.h>
+#include <servers/netname.h>
+#include <servers/netname_defs.h>
+
+void
+main (int argc, char **argv)
+{
+ kern_return_t kr;
+ mach_msg_header_t msg;
+ mach_port_t gdb_port;
+ char *host;
+ char *name;
+
+ if (argc == 1)
+ argv[argc++] = GDB_DEF_NAME;
+
+ if (argc != 2)
+ {
+ fprintf (stderr, "Usage : %s <GDB name>\n", argv[0]);
+ exit (1);
+ }
+
+ /* Allow the user to specify a remote host. */
+ host = strchr (argv[1], '@');
+ if (host)
+ *(host++) = '\0';
+ else
+ host = (char *) "";
+
+ name = malloc (strlen (argv[1]) + sizeof (GDB_NAME_PREFIX));
+ if (name == NULL)
+ {
+ fprintf (stderr, "Unable to allocate memory for name.");
+ exit (1);
+ }
+
+ strcpy (name, GDB_NAME_PREFIX);
+ strcat (name, argv[1]);
+
+ /* Look up the GDB service port. For convenience, add the
+ GDB_NAME_PREFIX the argument before looking up the name.
+ For backwards compatibility, do it without. */
+
+ kr = netname_look_up (name_server_port, host, name, &gdb_port);
+ if (kr == NETNAME_NOT_CHECKED_IN)
+ kr = netname_look_up (name_server_port, host, argv[1], &gdb_port);
+ if (kr != KERN_SUCCESS)
+ {
+ fprintf (stderr, "Unable to lookup the GDB service port: %s.\n",
+ mach_error_string (kr));
+ exit (1);
+ }
+
+ /* Code generated by mig stub generator, with minor cleanups :-)
+
+ simpleroutine stop_inferior(gdb_port : mach_port_t); */
+
+ msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0);
+ msg.msgh_remote_port = gdb_port;
+ msg.msgh_local_port = MACH_PORT_NULL;
+ msg.msgh_size = sizeof (msg);
+ msg.msgh_seqno = 0;
+ msg.msgh_id = GDB_MESSAGE_ID_STOP;
+
+ kr = mach_msg_send (&msg);
+ if (kr != KERN_SUCCESS)
+ fprintf (stderr, "Message not sent, return code %d : %s\n", kr,
+ mach_error_string (kr));
+
+ exit (kr != KERN_SUCCESS);
+}
diff --git a/gdb/sun3-nat.c b/gdb/sun3-nat.c
new file mode 100644
index 00000000000..988ed37ad06
--- /dev/null
+++ b/gdb/sun3-nat.c
@@ -0,0 +1,165 @@
+/* Host-dependent code for Sun-3 for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1996, 1999, 2000, 2001
+ 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 "defs.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#include <sys/ptrace.h>
+#define KERNEL /* To get floating point reg definitions */
+#include <machine/reg.h>
+
+static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
+
+void
+fetch_inferior_registers (int regno)
+{
+ struct regs inferior_registers;
+ struct fp_status inferior_fp_registers;
+
+ registers_fetched ();
+
+ ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers);
+
+ if (FP0_REGNUM >= 0)
+ ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers);
+
+ memcpy (registers, &inferior_registers, 16 * 4);
+ if (FP0_REGNUM >= 0)
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
+ sizeof inferior_fp_registers.fps_regs);
+
+ *(int *) &registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
+ *(int *) &registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
+ if (FP0_REGNUM >= 0)
+ memcpy (&registers[REGISTER_BYTE (FPC_REGNUM)],
+ &inferior_fp_registers.fps_control,
+ sizeof inferior_fp_registers -
+ sizeof inferior_fp_registers.fps_regs);
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is -1, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (int regno)
+{
+ struct regs inferior_registers;
+ struct fp_status inferior_fp_registers;
+
+ memcpy (&inferior_registers, registers, 16 * 4);
+ if (FP0_REGNUM >= 0)
+ memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
+ sizeof inferior_fp_registers.fps_regs);
+
+ inferior_registers.r_ps = *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
+ inferior_registers.r_pc = *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
+
+ if (FP0_REGNUM >= 0)
+ memcpy (&inferior_fp_registers.fps_control,
+ &registers[REGISTER_BYTE (FPC_REGNUM)],
+ sizeof inferior_fp_registers -
+ sizeof inferior_fp_registers.fps_regs);
+
+ ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_registers);
+ if (FP0_REGNUM >= 0)
+ ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & inferior_fp_registers);
+}
+
+
+/* All of this stuff is only relevant if both host and target are sun3. */
+
+/* Provide registers to GDB from a core file.
+
+ CORE_REG_SECT points to an array of bytes, which were obtained from
+ a core file which BFD thinks might contain register contents.
+ CORE_REG_SIZE is its size.
+
+ WHICH says which register set corelow suspects this is:
+ 0 --- the general-purpose register set
+ 2 --- the floating-point register set
+
+ REG_ADDR isn't used. */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+ struct regs *regs = (struct regs *) core_reg_sect;
+
+ if (which == 0)
+ {
+ if (core_reg_size < sizeof (struct regs))
+ error ("Can't find registers in core file");
+
+ memcpy (registers, (char *) regs, 16 * 4);
+ supply_register (PS_REGNUM, (char *) &regs->r_ps);
+ supply_register (PC_REGNUM, (char *) &regs->r_pc);
+
+ }
+ else if (which == 2)
+ {
+
+#define fpustruct ((struct fpu *) core_reg_sect)
+
+ if (core_reg_size >= sizeof (struct fpu))
+ {
+ if (FP0_REGNUM >= 0)
+ {
+ memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)],
+ fpustruct->f_fpstatus.fps_regs,
+ sizeof fpustruct->f_fpstatus.fps_regs);
+ memcpy (&registers[REGISTER_BYTE (FPC_REGNUM)],
+ &fpustruct->f_fpstatus.fps_control,
+ sizeof fpustruct->f_fpstatus -
+ sizeof fpustruct->f_fpstatus.fps_regs);
+ }
+ }
+ else
+ fprintf_unfiltered (gdb_stderr,
+ "Couldn't read float regs from core file\n");
+ }
+}
+
+
+/* Register that we are able to handle sun3 core file formats.
+ FIXME: is this really bfd_target_unknown_flavour? */
+
+static struct core_fns sun3_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_sun3 (void)
+{
+ add_core_fns (&sun3_core_fns);
+}
diff --git a/gdb/symfile.c b/gdb/symfile.c
new file mode 100644
index 00000000000..d087b1fe4c7
--- /dev/null
+++ b/gdb/symfile.c
@@ -0,0 +1,3353 @@
+/* Generic symbol file reading for the GNU debugger, GDB.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Support, using pieces from other GDB modules.
+
+ 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "frame.h"
+#include "target.h"
+#include "value.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbcmd.h"
+#include "breakpoint.h"
+#include "language.h"
+#include "complaints.h"
+#include "demangle.h"
+#include "inferior.h" /* for write_pc */
+#include "gdb-stabs.h"
+#include "obstack.h"
+#include "completer.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "gdb_string.h"
+#include "gdb_stat.h"
+#include <ctype.h>
+#include <time.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#ifdef HPUXHPPA
+
+/* Some HP-UX related globals to clear when a new "main"
+ symbol file is loaded. HP-specific. */
+
+extern int hp_som_som_object_present;
+extern int hp_cxx_exception_support_initialized;
+#define RESET_HP_UX_GLOBALS() do {\
+ hp_som_som_object_present = 0; /* indicates HP-compiled code */ \
+ hp_cxx_exception_support_initialized = 0; /* must reinitialize exception stuff */ \
+ } while (0)
+#endif
+
+int (*ui_load_progress_hook) (const char *section, unsigned long num);
+void (*show_load_progress) (const char *section,
+ unsigned long section_sent,
+ unsigned long section_size,
+ unsigned long total_sent,
+ unsigned long total_size);
+void (*pre_add_symbol_hook) (char *);
+void (*post_add_symbol_hook) (void);
+void (*target_new_objfile_hook) (struct objfile *);
+
+static void clear_symtab_users_cleanup (void *ignore);
+
+/* Global variables owned by this file */
+int readnow_symbol_files; /* Read full symbols immediately */
+
+struct complaint oldsyms_complaint =
+{
+ "Replacing old symbols for `%s'", 0, 0
+};
+
+struct complaint empty_symtab_complaint =
+{
+ "Empty symbol table found for `%s'", 0, 0
+};
+
+struct complaint unknown_option_complaint =
+{
+ "Unknown option `%s' ignored", 0, 0
+};
+
+/* External variables and functions referenced. */
+
+extern void report_transfer_performance (unsigned long, time_t, time_t);
+
+/* Functions this file defines */
+
+#if 0
+static int simple_read_overlay_region_table (void);
+static void simple_free_overlay_region_table (void);
+#endif
+
+static void set_initial_language (void);
+
+static void load_command (char *, int);
+
+static void symbol_file_add_main_1 (char *args, int from_tty, int flags);
+
+static void add_symbol_file_command (char *, int);
+
+static void add_shared_symbol_files_command (char *, int);
+
+static void cashier_psymtab (struct partial_symtab *);
+
+bfd *symfile_bfd_open (char *);
+
+int get_section_index (struct objfile *, char *);
+
+static void find_sym_fns (struct objfile *);
+
+static void decrement_reading_symtab (void *);
+
+static void overlay_invalidate_all (void);
+
+static int overlay_is_mapped (struct obj_section *);
+
+void list_overlays_command (char *, int);
+
+void map_overlay_command (char *, int);
+
+void unmap_overlay_command (char *, int);
+
+static void overlay_auto_command (char *, int);
+
+static void overlay_manual_command (char *, int);
+
+static void overlay_off_command (char *, int);
+
+static void overlay_load_command (char *, int);
+
+static void overlay_command (char *, int);
+
+static void simple_free_overlay_table (void);
+
+static void read_target_long_array (CORE_ADDR, unsigned int *, int);
+
+static int simple_read_overlay_table (void);
+
+static int simple_overlay_update_1 (struct obj_section *);
+
+static void add_filename_language (char *ext, enum language lang);
+
+static void set_ext_lang_command (char *args, int from_tty);
+
+static void info_ext_lang_command (char *args, int from_tty);
+
+static void init_filename_language_table (void);
+
+void _initialize_symfile (void);
+
+/* List of all available sym_fns. On gdb startup, each object file reader
+ calls add_symtab_fns() to register information on each format it is
+ prepared to read. */
+
+static struct sym_fns *symtab_fns = NULL;
+
+/* Flag for whether user will be reloading symbols multiple times.
+ Defaults to ON for VxWorks, otherwise OFF. */
+
+#ifdef SYMBOL_RELOADING_DEFAULT
+int symbol_reloading = SYMBOL_RELOADING_DEFAULT;
+#else
+int symbol_reloading = 0;
+#endif
+
+/* If non-zero, shared library symbols will be added automatically
+ when the inferior is created, new libraries are loaded, or when
+ attaching to the inferior. This is almost always what users will
+ want to have happen; but for very large programs, the startup time
+ will be excessive, and so if this is a problem, the user can clear
+ this flag and then add the shared library symbols as needed. Note
+ that there is a potential for confusion, since if the shared
+ library symbols are not loaded, commands like "info fun" will *not*
+ report all the functions that are actually present. */
+
+int auto_solib_add = 1;
+
+/* For systems that support it, a threshold size in megabytes. If
+ automatically adding a new library's symbol table to those already
+ known to the debugger would cause the total shared library symbol
+ size to exceed this threshhold, then the shlib's symbols are not
+ added. The threshold is ignored if the user explicitly asks for a
+ shlib to be added, such as when using the "sharedlibrary"
+ command. */
+
+int auto_solib_limit;
+
+
+/* Since this function is called from within qsort, in an ANSI environment
+ it must conform to the prototype for qsort, which specifies that the
+ comparison function takes two "void *" pointers. */
+
+static int
+compare_symbols (const void *s1p, const void *s2p)
+{
+ register struct symbol **s1, **s2;
+
+ s1 = (struct symbol **) s1p;
+ s2 = (struct symbol **) s2p;
+ return (strcmp (SYMBOL_SOURCE_NAME (*s1), SYMBOL_SOURCE_NAME (*s2)));
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ compare_psymbols -- compare two partial symbols by name
+
+ DESCRIPTION
+
+ Given pointers to pointers to two partial symbol table entries,
+ compare them by name and return -N, 0, or +N (ala strcmp).
+ Typically used by sorting routines like qsort().
+
+ NOTES
+
+ Does direct compare of first two characters before punting
+ and passing to strcmp for longer compares. Note that the
+ original version had a bug whereby two null strings or two
+ identically named one character strings would return the
+ comparison of memory following the null byte.
+
+ */
+
+static int
+compare_psymbols (const void *s1p, const void *s2p)
+{
+ register struct partial_symbol **s1, **s2;
+ register char *st1, *st2;
+
+ s1 = (struct partial_symbol **) s1p;
+ s2 = (struct partial_symbol **) s2p;
+ st1 = SYMBOL_SOURCE_NAME (*s1);
+ st2 = SYMBOL_SOURCE_NAME (*s2);
+
+
+ if ((st1[0] - st2[0]) || !st1[0])
+ {
+ return (st1[0] - st2[0]);
+ }
+ else if ((st1[1] - st2[1]) || !st1[1])
+ {
+ return (st1[1] - st2[1]);
+ }
+ else
+ {
+ return (strcmp (st1, st2));
+ }
+}
+
+void
+sort_pst_symbols (struct partial_symtab *pst)
+{
+ /* Sort the global list; don't sort the static list */
+
+ qsort (pst->objfile->global_psymbols.list + pst->globals_offset,
+ pst->n_global_syms, sizeof (struct partial_symbol *),
+ compare_psymbols);
+}
+
+/* Call sort_block_syms to sort alphabetically the symbols of one block. */
+
+void
+sort_block_syms (register struct block *b)
+{
+ qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b),
+ sizeof (struct symbol *), compare_symbols);
+}
+
+/* Call sort_symtab_syms to sort alphabetically
+ the symbols of each block of one symtab. */
+
+void
+sort_symtab_syms (register struct symtab *s)
+{
+ register struct blockvector *bv;
+ int nbl;
+ int i;
+ register struct block *b;
+
+ if (s == 0)
+ return;
+ bv = BLOCKVECTOR (s);
+ nbl = BLOCKVECTOR_NBLOCKS (bv);
+ for (i = 0; i < nbl; i++)
+ {
+ b = BLOCKVECTOR_BLOCK (bv, i);
+ if (BLOCK_SHOULD_SORT (b))
+ sort_block_syms (b);
+ }
+}
+
+/* Make a null terminated copy of the string at PTR with SIZE characters in
+ the obstack pointed to by OBSTACKP . Returns the address of the copy.
+ Note that the string at PTR does not have to be null terminated, I.E. it
+ may be part of a larger string and we are only saving a substring. */
+
+char *
+obsavestring (char *ptr, int size, struct obstack *obstackp)
+{
+ register char *p = (char *) obstack_alloc (obstackp, size + 1);
+ /* Open-coded memcpy--saves function call time. These strings are usually
+ short. FIXME: Is this really still true with a compiler that can
+ inline memcpy? */
+ {
+ register char *p1 = ptr;
+ register char *p2 = p;
+ char *end = ptr + size;
+ while (p1 != end)
+ *p2++ = *p1++;
+ }
+ p[size] = 0;
+ return p;
+}
+
+/* Concatenate strings S1, S2 and S3; return the new string. Space is found
+ in the obstack pointed to by OBSTACKP. */
+
+char *
+obconcat (struct obstack *obstackp, const char *s1, const char *s2,
+ const char *s3)
+{
+ register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
+ register char *val = (char *) obstack_alloc (obstackp, len);
+ strcpy (val, s1);
+ strcat (val, s2);
+ strcat (val, s3);
+ return val;
+}
+
+/* True if we are nested inside psymtab_to_symtab. */
+
+int currently_reading_symtab = 0;
+
+static void
+decrement_reading_symtab (void *dummy)
+{
+ currently_reading_symtab--;
+}
+
+/* Get the symbol table that corresponds to a partial_symtab.
+ This is fast after the first time you do it. In fact, there
+ is an even faster macro PSYMTAB_TO_SYMTAB that does the fast
+ case inline. */
+
+struct symtab *
+psymtab_to_symtab (register struct partial_symtab *pst)
+{
+ /* If it's been looked up before, return it. */
+ if (pst->symtab)
+ return pst->symtab;
+
+ /* If it has not yet been read in, read it. */
+ if (!pst->readin)
+ {
+ struct cleanup *back_to = make_cleanup (decrement_reading_symtab, NULL);
+ currently_reading_symtab++;
+ (*pst->read_symtab) (pst);
+ do_cleanups (back_to);
+ }
+
+ return pst->symtab;
+}
+
+/* Initialize entry point information for this objfile. */
+
+void
+init_entry_point_info (struct objfile *objfile)
+{
+ /* Save startup file's range of PC addresses to help blockframe.c
+ decide where the bottom of the stack is. */
+
+ if (bfd_get_file_flags (objfile->obfd) & EXEC_P)
+ {
+ /* Executable file -- record its entry point so we'll recognize
+ the startup file because it contains the entry point. */
+ objfile->ei.entry_point = bfd_get_start_address (objfile->obfd);
+ }
+ else
+ {
+ /* Examination of non-executable.o files. Short-circuit this stuff. */
+ objfile->ei.entry_point = INVALID_ENTRY_POINT;
+ }
+ objfile->ei.entry_file_lowpc = INVALID_ENTRY_LOWPC;
+ objfile->ei.entry_file_highpc = INVALID_ENTRY_HIGHPC;
+ objfile->ei.entry_func_lowpc = INVALID_ENTRY_LOWPC;
+ objfile->ei.entry_func_highpc = INVALID_ENTRY_HIGHPC;
+ objfile->ei.main_func_lowpc = INVALID_ENTRY_LOWPC;
+ objfile->ei.main_func_highpc = INVALID_ENTRY_HIGHPC;
+}
+
+/* Get current entry point address. */
+
+CORE_ADDR
+entry_point_address (void)
+{
+ return symfile_objfile ? symfile_objfile->ei.entry_point : 0;
+}
+
+/* Remember the lowest-addressed loadable section we've seen.
+ This function is called via bfd_map_over_sections.
+
+ In case of equal vmas, the section with the largest size becomes the
+ lowest-addressed loadable section.
+
+ If the vmas and sizes are equal, the last section is considered the
+ lowest-addressed loadable section. */
+
+void
+find_lowest_section (bfd *abfd, asection *sect, PTR obj)
+{
+ asection **lowest = (asection **) obj;
+
+ if (0 == (bfd_get_section_flags (abfd, sect) & SEC_LOAD))
+ return;
+ if (!*lowest)
+ *lowest = sect; /* First loadable section */
+ else if (bfd_section_vma (abfd, *lowest) > bfd_section_vma (abfd, sect))
+ *lowest = sect; /* A lower loadable section */
+ else if (bfd_section_vma (abfd, *lowest) == bfd_section_vma (abfd, sect)
+ && (bfd_section_size (abfd, (*lowest))
+ <= bfd_section_size (abfd, sect)))
+ *lowest = sect;
+}
+
+
+/* Build (allocate and populate) a section_addr_info struct from
+ an existing section table. */
+
+extern struct section_addr_info *
+build_section_addr_info_from_section_table (const struct section_table *start,
+ const struct section_table *end)
+{
+ struct section_addr_info *sap;
+ const struct section_table *stp;
+ int oidx;
+
+ sap = xmalloc (sizeof (struct section_addr_info));
+ memset (sap, 0, sizeof (struct section_addr_info));
+
+ for (stp = start, oidx = 0; stp != end; stp++)
+ {
+ if (bfd_get_section_flags (stp->bfd,
+ stp->the_bfd_section) & (SEC_ALLOC | SEC_LOAD)
+ && oidx < MAX_SECTIONS)
+ {
+ sap->other[oidx].addr = stp->addr;
+ sap->other[oidx].name
+ = xstrdup (bfd_section_name (stp->bfd, stp->the_bfd_section));
+ sap->other[oidx].sectindex = stp->the_bfd_section->index;
+ oidx++;
+ }
+ }
+
+ return sap;
+}
+
+
+/* Free all memory allocated by build_section_addr_info_from_section_table. */
+
+extern void
+free_section_addr_info (struct section_addr_info *sap)
+{
+ int idx;
+
+ for (idx = 0; idx < MAX_SECTIONS; idx++)
+ if (sap->other[idx].name)
+ xfree (sap->other[idx].name);
+ xfree (sap);
+}
+
+
+/* Parse the user's idea of an offset for dynamic linking, into our idea
+ of how to represent it for fast symbol reading. This is the default
+ version of the sym_fns.sym_offsets function for symbol readers that
+ don't need to do anything special. It allocates a section_offsets table
+ for the objectfile OBJFILE and stuffs ADDR into all of the offsets. */
+
+void
+default_symfile_offsets (struct objfile *objfile,
+ struct section_addr_info *addrs)
+{
+ int i;
+ asection *sect = NULL;
+
+ objfile->num_sections = SECT_OFF_MAX;
+ objfile->section_offsets = (struct section_offsets *)
+ obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
+ memset (objfile->section_offsets, 0, SIZEOF_SECTION_OFFSETS);
+
+ /* Now calculate offsets for section that were specified by the
+ caller. */
+ for (i = 0; i < MAX_SECTIONS && addrs->other[i].name; i++)
+ {
+ struct other_sections *osp ;
+
+ osp = &addrs->other[i] ;
+ if (osp->addr == 0)
+ continue;
+
+ /* Record all sections in offsets */
+ /* The section_offsets in the objfile are here filled in using
+ the BFD index. */
+ (objfile->section_offsets)->offsets[osp->sectindex] = osp->addr;
+ }
+
+ /* Remember the bfd indexes for the .text, .data, .bss and
+ .rodata sections. */
+
+ sect = bfd_get_section_by_name (objfile->obfd, ".text");
+ if (sect)
+ objfile->sect_index_text = sect->index;
+
+ sect = bfd_get_section_by_name (objfile->obfd, ".data");
+ if (sect)
+ objfile->sect_index_data = sect->index;
+
+ sect = bfd_get_section_by_name (objfile->obfd, ".bss");
+ if (sect)
+ objfile->sect_index_bss = sect->index;
+
+ sect = bfd_get_section_by_name (objfile->obfd, ".rodata");
+ if (sect)
+ objfile->sect_index_rodata = sect->index;
+
+ /* This is where things get really weird... We MUST have valid
+ indices for the various sect_index_* members or gdb will abort.
+ So if for example, there is no ".text" section, we have to
+ accomodate that. Except when explicitly adding symbol files at
+ some address, section_offsets contains nothing but zeros, so it
+ doesn't matter which slot in section_offsets the individual
+ sect_index_* members index into. So if they are all zero, it is
+ safe to just point all the currently uninitialized indices to the
+ first slot. */
+
+ for (i = 0; i < objfile->num_sections; i++)
+ {
+ if (ANOFFSET (objfile->section_offsets, i) != 0)
+ {
+ break;
+ }
+ }
+ if (i == objfile->num_sections)
+ {
+ if (objfile->sect_index_text == -1)
+ objfile->sect_index_text = 0;
+ if (objfile->sect_index_data == -1)
+ objfile->sect_index_data = 0;
+ if (objfile->sect_index_bss == -1)
+ objfile->sect_index_bss = 0;
+ if (objfile->sect_index_rodata == -1)
+ objfile->sect_index_rodata = 0;
+ }
+}
+
+/* Process a symbol file, as either the main file or as a dynamically
+ loaded file.
+
+ OBJFILE is where the symbols are to be read from.
+
+ ADDR is the address where the text segment was loaded, unless the
+ objfile is the main symbol file, in which case it is zero.
+
+ MAINLINE is nonzero if this is the main symbol file, or zero if
+ it's an extra symbol file such as dynamically loaded code.
+
+ VERBO is nonzero if the caller has printed a verbose message about
+ the symbol reading (and complaints can be more terse about it). */
+
+void
+syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
+ int mainline, int verbo)
+{
+ asection *lower_sect;
+ asection *sect;
+ CORE_ADDR lower_offset;
+ struct section_addr_info local_addr;
+ struct cleanup *old_chain;
+ int i;
+
+ /* If ADDRS is NULL, initialize the local section_addr_info struct and
+ point ADDRS to it. We now establish the convention that an addr of
+ zero means no load address was specified. */
+
+ if (addrs == NULL)
+ {
+ memset (&local_addr, 0, sizeof (local_addr));
+ addrs = &local_addr;
+ }
+
+ init_entry_point_info (objfile);
+ find_sym_fns (objfile);
+
+ if (objfile->sf == NULL)
+ return; /* No symbols. */
+
+ /* Make sure that partially constructed symbol tables will be cleaned up
+ if an error occurs during symbol reading. */
+ old_chain = make_cleanup_free_objfile (objfile);
+
+ if (mainline)
+ {
+ /* We will modify the main symbol table, make sure that all its users
+ will be cleaned up if an error occurs during symbol reading. */
+ make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/);
+
+ /* Since no error yet, throw away the old symbol table. */
+
+ if (symfile_objfile != NULL)
+ {
+ free_objfile (symfile_objfile);
+ symfile_objfile = NULL;
+ }
+
+ /* Currently we keep symbols from the add-symbol-file command.
+ If the user wants to get rid of them, they should do "symbol-file"
+ without arguments first. Not sure this is the best behavior
+ (PR 2207). */
+
+ (*objfile->sf->sym_new_init) (objfile);
+ }
+
+ /* Convert addr into an offset rather than an absolute address.
+ We find the lowest address of a loaded segment in the objfile,
+ and assume that <addr> is where that got loaded.
+
+ We no longer warn if the lowest section is not a text segment (as
+ happens for the PA64 port. */
+ if (!mainline)
+ {
+ /* Find lowest loadable section to be used as starting point for
+ continguous sections. FIXME!! won't work without call to find
+ .text first, but this assumes text is lowest section. */
+ lower_sect = bfd_get_section_by_name (objfile->obfd, ".text");
+ if (lower_sect == NULL)
+ bfd_map_over_sections (objfile->obfd, find_lowest_section,
+ (PTR) &lower_sect);
+ if (lower_sect == NULL)
+ warning ("no loadable sections found in added symbol-file %s",
+ objfile->name);
+ else
+ if ((bfd_get_section_flags (objfile->obfd, lower_sect) & SEC_CODE) == 0)
+ warning ("Lowest section in %s is %s at %s",
+ objfile->name,
+ bfd_section_name (objfile->obfd, lower_sect),
+ paddr (bfd_section_vma (objfile->obfd, lower_sect)));
+ if (lower_sect != NULL)
+ lower_offset = bfd_section_vma (objfile->obfd, lower_sect);
+ else
+ lower_offset = 0;
+
+ /* Calculate offsets for the loadable sections.
+ FIXME! Sections must be in order of increasing loadable section
+ so that contiguous sections can use the lower-offset!!!
+
+ Adjust offsets if the segments are not contiguous.
+ If the section is contiguous, its offset should be set to
+ the offset of the highest loadable section lower than it
+ (the loadable section directly below it in memory).
+ this_offset = lower_offset = lower_addr - lower_orig_addr */
+
+ /* Calculate offsets for sections. */
+ for (i=0 ; i < MAX_SECTIONS && addrs->other[i].name; i++)
+ {
+ if (addrs->other[i].addr != 0)
+ {
+ sect = bfd_get_section_by_name (objfile->obfd, addrs->other[i].name);
+ if (sect)
+ {
+ addrs->other[i].addr -= bfd_section_vma (objfile->obfd, sect);
+ lower_offset = addrs->other[i].addr;
+ /* This is the index used by BFD. */
+ addrs->other[i].sectindex = sect->index ;
+ }
+ else
+ {
+ warning ("section %s not found in %s", addrs->other[i].name,
+ objfile->name);
+ addrs->other[i].addr = 0;
+ }
+ }
+ else
+ addrs->other[i].addr = lower_offset;
+ }
+ }
+
+ /* Initialize symbol reading routines for this objfile, allow complaints to
+ appear for this new file, and record how verbose to be, then do the
+ initial symbol reading for this file. */
+
+ (*objfile->sf->sym_init) (objfile);
+ clear_complaints (1, verbo);
+
+ (*objfile->sf->sym_offsets) (objfile, addrs);
+
+#ifndef IBM6000_TARGET
+ /* This is a SVR4/SunOS specific hack, I think. In any event, it
+ screws RS/6000. sym_offsets should be doing this sort of thing,
+ because it knows the mapping between bfd sections and
+ section_offsets. */
+ /* This is a hack. As far as I can tell, section offsets are not
+ target dependent. They are all set to addr with a couple of
+ exceptions. The exceptions are sysvr4 shared libraries, whose
+ offsets are kept in solib structures anyway and rs6000 xcoff
+ which handles shared libraries in a completely unique way.
+
+ Section offsets are built similarly, except that they are built
+ by adding addr in all cases because there is no clear mapping
+ from section_offsets into actual sections. Note that solib.c
+ has a different algorithm for finding section offsets.
+
+ These should probably all be collapsed into some target
+ independent form of shared library support. FIXME. */
+
+ if (addrs)
+ {
+ struct obj_section *s;
+
+ /* Map section offsets in "addr" back to the object's
+ sections by comparing the section names with bfd's
+ section names. Then adjust the section address by
+ the offset. */ /* for gdb/13815 */
+
+ ALL_OBJFILE_OSECTIONS (objfile, s)
+ {
+ CORE_ADDR s_addr = 0;
+ int i;
+
+ for (i = 0;
+ !s_addr && i < MAX_SECTIONS && addrs->other[i].name;
+ i++)
+ if (strcmp (bfd_section_name (s->objfile->obfd,
+ s->the_bfd_section),
+ addrs->other[i].name) == 0)
+ s_addr = addrs->other[i].addr; /* end added for gdb/13815 */
+
+ s->addr -= s->offset;
+ s->addr += s_addr;
+ s->endaddr -= s->offset;
+ s->endaddr += s_addr;
+ s->offset += s_addr;
+ }
+ }
+#endif /* not IBM6000_TARGET */
+
+ (*objfile->sf->sym_read) (objfile, mainline);
+
+ if (!have_partial_symbols () && !have_full_symbols ())
+ {
+ wrap_here ("");
+ printf_filtered ("(no debugging symbols found)...");
+ wrap_here ("");
+ }
+
+ /* Don't allow char * to have a typename (else would get caddr_t).
+ Ditto void *. FIXME: Check whether this is now done by all the
+ symbol readers themselves (many of them now do), and if so remove
+ it from here. */
+
+ TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;
+ TYPE_NAME (lookup_pointer_type (builtin_type_void)) = 0;
+
+ /* Mark the objfile has having had initial symbol read attempted. Note
+ that this does not mean we found any symbols... */
+
+ objfile->flags |= OBJF_SYMS;
+
+ /* Discard cleanups as symbol reading was successful. */
+
+ discard_cleanups (old_chain);
+
+ /* Call this after reading in a new symbol table to give target
+ dependent code a crack at the new symbols. For instance, this
+ could be used to update the values of target-specific symbols GDB
+ needs to keep track of (such as _sigtramp, or whatever). */
+
+ TARGET_SYMFILE_POSTREAD (objfile);
+}
+
+/* Perform required actions after either reading in the initial
+ symbols for a new objfile, or mapping in the symbols from a reusable
+ objfile. */
+
+void
+new_symfile_objfile (struct objfile *objfile, int mainline, int verbo)
+{
+
+ /* If this is the main symbol file we have to clean up all users of the
+ old main symbol file. Otherwise it is sufficient to fixup all the
+ breakpoints that may have been redefined by this symbol file. */
+ if (mainline)
+ {
+ /* OK, make it the "real" symbol file. */
+ symfile_objfile = objfile;
+
+ clear_symtab_users ();
+ }
+ else
+ {
+ breakpoint_re_set ();
+ }
+
+ /* We're done reading the symbol file; finish off complaints. */
+ clear_complaints (0, verbo);
+}
+
+/* Process a symbol file, as either the main file or as a dynamically
+ loaded file.
+
+ NAME is the file name (which will be tilde-expanded and made
+ absolute herein) (but we don't free or modify NAME itself).
+ FROM_TTY says how verbose to be. MAINLINE specifies whether this
+ is the main symbol file, or whether it's an extra symbol file such
+ as dynamically loaded code. If !mainline, ADDR is the address
+ where the text segment was loaded.
+
+ Upon success, returns a pointer to the objfile that was added.
+ Upon failure, jumps back to command level (never returns). */
+
+struct objfile *
+symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
+ int mainline, int flags)
+{
+ struct objfile *objfile;
+ struct partial_symtab *psymtab;
+ bfd *abfd;
+
+ /* Open a bfd for the file, and give user a chance to burp if we'd be
+ interactively wiping out any existing symbols. */
+
+ abfd = symfile_bfd_open (name);
+
+ if ((have_full_symbols () || have_partial_symbols ())
+ && mainline
+ && from_tty
+ && !query ("Load new symbol table from \"%s\"? ", name))
+ error ("Not confirmed.");
+
+ objfile = allocate_objfile (abfd, flags);
+
+ /* If the objfile uses a mapped symbol file, and we have a psymtab for
+ it, then skip reading any symbols at this time. */
+
+ if ((objfile->flags & OBJF_MAPPED) && (objfile->flags & OBJF_SYMS))
+ {
+ /* We mapped in an existing symbol table file that already has had
+ initial symbol reading performed, so we can skip that part. Notify
+ the user that instead of reading the symbols, they have been mapped.
+ */
+ if (from_tty || info_verbose)
+ {
+ printf_filtered ("Mapped symbols for %s...", name);
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+ }
+ init_entry_point_info (objfile);
+ find_sym_fns (objfile);
+ }
+ else
+ {
+ /* We either created a new mapped symbol table, mapped an existing
+ symbol table file which has not had initial symbol reading
+ performed, or need to read an unmapped symbol table. */
+ if (from_tty || info_verbose)
+ {
+ if (pre_add_symbol_hook)
+ pre_add_symbol_hook (name);
+ else
+ {
+ printf_filtered ("Reading symbols from %s...", name);
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+ }
+ }
+ syms_from_objfile (objfile, addrs, mainline, from_tty);
+ }
+
+ /* We now have at least a partial symbol table. Check to see if the
+ user requested that all symbols be read on initial access via either
+ the gdb startup command line or on a per symbol file basis. Expand
+ all partial symbol tables for this objfile if so. */
+
+ if ((flags & OBJF_READNOW) || readnow_symbol_files)
+ {
+ if (from_tty || info_verbose)
+ {
+ printf_filtered ("expanding to full symbols...");
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+ }
+
+ for (psymtab = objfile->psymtabs;
+ psymtab != NULL;
+ psymtab = psymtab->next)
+ {
+ psymtab_to_symtab (psymtab);
+ }
+ }
+
+ if (from_tty || info_verbose)
+ {
+ if (post_add_symbol_hook)
+ post_add_symbol_hook ();
+ else
+ {
+ printf_filtered ("done.\n");
+ gdb_flush (gdb_stdout);
+ }
+ }
+
+ if (objfile->sf == NULL)
+ return objfile; /* No symbols. */
+
+ new_symfile_objfile (objfile, mainline, from_tty);
+
+ if (target_new_objfile_hook)
+ target_new_objfile_hook (objfile);
+
+ return (objfile);
+}
+
+/* Call symbol_file_add() with default values and update whatever is
+ affected by the loading of a new main().
+ Used when the file is supplied in the gdb command line
+ and by some targets with special loading requirements.
+ The auxiliary function, symbol_file_add_main_1(), has the flags
+ argument for the switches that can only be specified in the symbol_file
+ command itself. */
+
+void
+symbol_file_add_main (char *args, int from_tty)
+{
+ symbol_file_add_main_1 (args, from_tty, 0);
+}
+
+static void
+symbol_file_add_main_1 (char *args, int from_tty, int flags)
+{
+ symbol_file_add (args, from_tty, NULL, 1, flags);
+
+#ifdef HPUXHPPA
+ RESET_HP_UX_GLOBALS ();
+#endif
+
+ /* Getting new symbols may change our opinion about
+ what is frameless. */
+ reinit_frame_cache ();
+
+ set_initial_language ();
+}
+
+void
+symbol_file_clear (int from_tty)
+{
+ if ((have_full_symbols () || have_partial_symbols ())
+ && from_tty
+ && !query ("Discard symbol table from `%s'? ",
+ symfile_objfile->name))
+ error ("Not confirmed.");
+ free_all_objfiles ();
+
+ /* solib descriptors may have handles to objfiles. Since their
+ storage has just been released, we'd better wipe the solib
+ descriptors as well.
+ */
+#if defined(SOLIB_RESTART)
+ SOLIB_RESTART ();
+#endif
+
+ symfile_objfile = NULL;
+ if (from_tty)
+ printf_unfiltered ("No symbol file now.\n");
+#ifdef HPUXHPPA
+ RESET_HP_UX_GLOBALS ();
+#endif
+}
+
+/* This is the symbol-file command. Read the file, analyze its
+ symbols, and add a struct symtab to a symtab list. The syntax of
+ the command is rather bizarre--(1) buildargv implements various
+ quoting conventions which are undocumented and have little or
+ nothing in common with the way things are quoted (or not quoted)
+ elsewhere in GDB, (2) options are used, which are not generally
+ used in GDB (perhaps "set mapped on", "set readnow on" would be
+ better), (3) the order of options matters, which is contrary to GNU
+ conventions (because it is confusing and inconvenient). */
+/* Note: ezannoni 2000-04-17. This function used to have support for
+ rombug (see remote-os9k.c). It consisted of a call to target_link()
+ (target.c) to get the address of the text segment from the target,
+ and pass that to symbol_file_add(). This is no longer supported. */
+
+void
+symbol_file_command (char *args, int from_tty)
+{
+ char **argv;
+ char *name = NULL;
+ struct cleanup *cleanups;
+ int flags = OBJF_USERLOADED;
+
+ dont_repeat ();
+
+ if (args == NULL)
+ {
+ symbol_file_clear (from_tty);
+ }
+ else
+ {
+ if ((argv = buildargv (args)) == NULL)
+ {
+ nomem (0);
+ }
+ cleanups = make_cleanup_freeargv (argv);
+ while (*argv != NULL)
+ {
+ if (STREQ (*argv, "-mapped"))
+ flags |= OBJF_MAPPED;
+ else
+ if (STREQ (*argv, "-readnow"))
+ flags |= OBJF_READNOW;
+ else
+ if (**argv == '-')
+ error ("unknown option `%s'", *argv);
+ else
+ {
+ name = *argv;
+
+ symbol_file_add_main_1 (name, from_tty, flags);
+ }
+ argv++;
+ }
+
+ if (name == NULL)
+ {
+ error ("no symbol file name was specified");
+ }
+ do_cleanups (cleanups);
+ }
+}
+
+/* Set the initial language.
+
+ A better solution would be to record the language in the psymtab when reading
+ partial symbols, and then use it (if known) to set the language. This would
+ be a win for formats that encode the language in an easily discoverable place,
+ such as DWARF. For stabs, we can jump through hoops looking for specially
+ named symbols or try to intuit the language from the specific type of stabs
+ we find, but we can't do that until later when we read in full symbols.
+ FIXME. */
+
+static void
+set_initial_language (void)
+{
+ struct partial_symtab *pst;
+ enum language lang = language_unknown;
+
+ pst = find_main_psymtab ();
+ if (pst != NULL)
+ {
+ if (pst->filename != NULL)
+ {
+ lang = deduce_language_from_filename (pst->filename);
+ }
+ if (lang == language_unknown)
+ {
+ /* Make C the default language */
+ lang = language_c;
+ }
+ set_language (lang);
+ expected_language = current_language; /* Don't warn the user */
+ }
+}
+
+/* Open file specified by NAME and hand it off to BFD for preliminary
+ analysis. Result is a newly initialized bfd *, which includes a newly
+ malloc'd` copy of NAME (tilde-expanded and made absolute).
+ In case of trouble, error() is called. */
+
+bfd *
+symfile_bfd_open (char *name)
+{
+ bfd *sym_bfd;
+ int desc;
+ char *absolute_name;
+
+
+
+ name = tilde_expand (name); /* Returns 1st new malloc'd copy */
+
+ /* Look down path for it, allocate 2nd new malloc'd copy. */
+ desc = openp (getenv ("PATH"), 1, name, O_RDONLY | O_BINARY, 0, &absolute_name);
+#if defined(__GO32__) || defined(_WIN32) || defined (__CYGWIN__)
+ if (desc < 0)
+ {
+ char *exename = alloca (strlen (name) + 5);
+ strcat (strcpy (exename, name), ".exe");
+ desc = openp (getenv ("PATH"), 1, exename, O_RDONLY | O_BINARY,
+ 0, &absolute_name);
+ }
+#endif
+ if (desc < 0)
+ {
+ make_cleanup (xfree, name);
+ perror_with_name (name);
+ }
+ xfree (name); /* Free 1st new malloc'd copy */
+ name = absolute_name; /* Keep 2nd malloc'd copy in bfd */
+ /* It'll be freed in free_objfile(). */
+
+ sym_bfd = bfd_fdopenr (name, gnutarget, desc);
+ if (!sym_bfd)
+ {
+ close (desc);
+ make_cleanup (xfree, name);
+ error ("\"%s\": can't open to read symbols: %s.", name,
+ bfd_errmsg (bfd_get_error ()));
+ }
+ sym_bfd->cacheable = 1;
+
+ if (!bfd_check_format (sym_bfd, bfd_object))
+ {
+ /* FIXME: should be checking for errors from bfd_close (for one thing,
+ on error it does not free all the storage associated with the
+ bfd). */
+ bfd_close (sym_bfd); /* This also closes desc */
+ make_cleanup (xfree, name);
+ error ("\"%s\": can't read symbols: %s.", name,
+ bfd_errmsg (bfd_get_error ()));
+ }
+ return (sym_bfd);
+}
+
+/* Return the section index for the given section name. Return -1 if
+ the section was not found. */
+int
+get_section_index (struct objfile *objfile, char *section_name)
+{
+ asection *sect = bfd_get_section_by_name (objfile->obfd, section_name);
+ if (sect)
+ return sect->index;
+ else
+ return -1;
+}
+
+/* Link a new symtab_fns into the global symtab_fns list. Called on gdb
+ startup by the _initialize routine in each object file format reader,
+ to register information about each format the the reader is prepared
+ to handle. */
+
+void
+add_symtab_fns (struct sym_fns *sf)
+{
+ sf->next = symtab_fns;
+ symtab_fns = sf;
+}
+
+
+/* Initialize to read symbols from the symbol file sym_bfd. It either
+ returns or calls error(). The result is an initialized struct sym_fns
+ in the objfile structure, that contains cached information about the
+ symbol file. */
+
+static void
+find_sym_fns (struct objfile *objfile)
+{
+ struct sym_fns *sf;
+ enum bfd_flavour our_flavour = bfd_get_flavour (objfile->obfd);
+ char *our_target = bfd_get_target (objfile->obfd);
+
+ if (our_flavour == bfd_target_srec_flavour
+ || our_flavour == bfd_target_ihex_flavour
+ || our_flavour == bfd_target_tekhex_flavour)
+ return; /* No symbols. */
+
+ /* Special kludge for apollo. See dstread.c. */
+ if (STREQN (our_target, "apollo", 6))
+ our_flavour = (enum bfd_flavour) -2;
+
+ for (sf = symtab_fns; sf != NULL; sf = sf->next)
+ {
+ if (our_flavour == sf->sym_flavour)
+ {
+ objfile->sf = sf;
+ return;
+ }
+ }
+ error ("I'm sorry, Dave, I can't do that. Symbol format `%s' unknown.",
+ bfd_get_target (objfile->obfd));
+}
+
+/* This function runs the load command of our current target. */
+
+static void
+load_command (char *arg, int from_tty)
+{
+ if (arg == NULL)
+ arg = get_exec_file (1);
+ target_load (arg, from_tty);
+
+ /* After re-loading the executable, we don't really know which
+ overlays are mapped any more. */
+ overlay_cache_invalid = 1;
+}
+
+/* This version of "load" should be usable for any target. Currently
+ it is just used for remote targets, not inftarg.c or core files,
+ on the theory that only in that case is it useful.
+
+ Avoiding xmodem and the like seems like a win (a) because we don't have
+ to worry about finding it, and (b) On VMS, fork() is very slow and so
+ we don't want to run a subprocess. On the other hand, I'm not sure how
+ performance compares. */
+
+static int download_write_size = 512;
+static int validate_download = 0;
+
+/* Callback service function for generic_load (bfd_map_over_sections). */
+
+static void
+add_section_size_callback (bfd *abfd, asection *asec, void *data)
+{
+ bfd_size_type *sum = data;
+
+ *sum += bfd_get_section_size_before_reloc (asec);
+}
+
+/* Opaque data for load_section_callback. */
+struct load_section_data {
+ unsigned long load_offset;
+ unsigned long write_count;
+ unsigned long data_count;
+ bfd_size_type total_size;
+};
+
+/* Callback service function for generic_load (bfd_map_over_sections). */
+
+static void
+load_section_callback (bfd *abfd, asection *asec, void *data)
+{
+ struct load_section_data *args = data;
+
+ if (bfd_get_section_flags (abfd, asec) & SEC_LOAD)
+ {
+ bfd_size_type size = bfd_get_section_size_before_reloc (asec);
+ if (size > 0)
+ {
+ char *buffer;
+ struct cleanup *old_chain;
+ CORE_ADDR lma = bfd_section_lma (abfd, asec) + args->load_offset;
+ bfd_size_type block_size;
+ int err;
+ const char *sect_name = bfd_get_section_name (abfd, asec);
+ bfd_size_type sent;
+
+ if (download_write_size > 0 && size > download_write_size)
+ block_size = download_write_size;
+ else
+ block_size = size;
+
+ buffer = xmalloc (size);
+ old_chain = make_cleanup (xfree, buffer);
+
+ /* Is this really necessary? I guess it gives the user something
+ to look at during a long download. */
+ ui_out_message (uiout, 0, "Loading section %s, size 0x%s lma 0x%s\n",
+ sect_name, paddr_nz (size), paddr_nz (lma));
+
+ bfd_get_section_contents (abfd, asec, buffer, 0, size);
+
+ sent = 0;
+ do
+ {
+ int len;
+ bfd_size_type this_transfer = size - sent;
+
+ if (this_transfer >= block_size)
+ this_transfer = block_size;
+ len = target_write_memory_partial (lma, buffer,
+ this_transfer, &err);
+ if (err)
+ break;
+ if (validate_download)
+ {
+ /* Broken memories and broken monitors manifest
+ themselves here when bring new computers to
+ life. This doubles already slow downloads. */
+ /* NOTE: cagney/1999-10-18: A more efficient
+ implementation might add a verify_memory()
+ method to the target vector and then use
+ that. remote.c could implement that method
+ using the ``qCRC'' packet. */
+ char *check = xmalloc (len);
+ struct cleanup *verify_cleanups =
+ make_cleanup (xfree, check);
+
+ if (target_read_memory (lma, check, len) != 0)
+ error ("Download verify read failed at 0x%s",
+ paddr (lma));
+ if (memcmp (buffer, check, len) != 0)
+ error ("Download verify compare failed at 0x%s",
+ paddr (lma));
+ do_cleanups (verify_cleanups);
+ }
+ args->data_count += len;
+ lma += len;
+ buffer += len;
+ args->write_count += 1;
+ sent += len;
+ if (quit_flag
+ || (ui_load_progress_hook != NULL
+ && ui_load_progress_hook (sect_name, sent)))
+ error ("Canceled the download");
+
+ if (show_load_progress != NULL)
+ show_load_progress (sect_name, sent, size,
+ args->data_count, args->total_size);
+ }
+ while (sent < size);
+
+ if (err != 0)
+ error ("Memory access error while loading section %s.", sect_name);
+
+ do_cleanups (old_chain);
+ }
+ }
+}
+
+void
+generic_load (char *args, int from_tty)
+{
+ asection *s;
+ bfd *loadfile_bfd;
+ time_t start_time, end_time; /* Start and end times of download */
+ char *filename;
+ struct cleanup *old_cleanups;
+ char *offptr;
+ struct load_section_data cbdata;
+ CORE_ADDR entry;
+
+ cbdata.load_offset = 0; /* Offset to add to vma for each section. */
+ cbdata.write_count = 0; /* Number of writes needed. */
+ cbdata.data_count = 0; /* Number of bytes written to target memory. */
+ cbdata.total_size = 0; /* Total size of all bfd sectors. */
+
+ /* Parse the input argument - the user can specify a load offset as
+ a second argument. */
+ filename = xmalloc (strlen (args) + 1);
+ old_cleanups = make_cleanup (xfree, filename);
+ strcpy (filename, args);
+ offptr = strchr (filename, ' ');
+ if (offptr != NULL)
+ {
+ char *endptr;
+
+ cbdata.load_offset = strtoul (offptr, &endptr, 0);
+ if (offptr == endptr)
+ error ("Invalid download offset:%s\n", offptr);
+ *offptr = '\0';
+ }
+ else
+ cbdata.load_offset = 0;
+
+ /* Open the file for loading. */
+ loadfile_bfd = bfd_openr (filename, gnutarget);
+ if (loadfile_bfd == NULL)
+ {
+ perror_with_name (filename);
+ return;
+ }
+
+ /* FIXME: should be checking for errors from bfd_close (for one thing,
+ on error it does not free all the storage associated with the
+ bfd). */
+ make_cleanup_bfd_close (loadfile_bfd);
+
+ if (!bfd_check_format (loadfile_bfd, bfd_object))
+ {
+ error ("\"%s\" is not an object file: %s", filename,
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+ bfd_map_over_sections (loadfile_bfd, add_section_size_callback,
+ (void *) &cbdata.total_size);
+
+ start_time = time (NULL);
+
+ bfd_map_over_sections (loadfile_bfd, load_section_callback, &cbdata);
+
+ end_time = time (NULL);
+
+ entry = bfd_get_start_address (loadfile_bfd);
+ ui_out_text (uiout, "Start address ");
+ ui_out_field_fmt (uiout, "address", "0x%s", paddr_nz (entry));
+ ui_out_text (uiout, ", load size ");
+ ui_out_field_fmt (uiout, "load-size", "%lu", cbdata.data_count);
+ ui_out_text (uiout, "\n");
+ /* We were doing this in remote-mips.c, I suspect it is right
+ for other targets too. */
+ write_pc (entry);
+
+ /* FIXME: are we supposed to call symbol_file_add or not? According to
+ a comment from remote-mips.c (where a call to symbol_file_add was
+ commented out), making the call confuses GDB if more than one file is
+ loaded in. remote-nindy.c had no call to symbol_file_add, but remote-vx.c
+ does. */
+
+ print_transfer_performance (gdb_stdout, cbdata.data_count,
+ cbdata.write_count, end_time - start_time);
+
+ do_cleanups (old_cleanups);
+}
+
+/* Report how fast the transfer went. */
+
+/* DEPRECATED: cagney/1999-10-18: report_transfer_performance is being
+ replaced by print_transfer_performance (with a very different
+ function signature). */
+
+void
+report_transfer_performance (unsigned long data_count, time_t start_time,
+ time_t end_time)
+{
+ print_transfer_performance (gdb_stdout, data_count,
+ end_time - start_time, 0);
+}
+
+void
+print_transfer_performance (struct ui_file *stream,
+ unsigned long data_count,
+ unsigned long write_count,
+ unsigned long time_count)
+{
+ ui_out_text (uiout, "Transfer rate: ");
+ if (time_count > 0)
+ {
+ ui_out_field_fmt (uiout, "transfer-rate", "%lu",
+ (data_count * 8) / time_count);
+ ui_out_text (uiout, " bits/sec");
+ }
+ else
+ {
+ ui_out_field_fmt (uiout, "transferred-bits", "%lu", (data_count * 8));
+ ui_out_text (uiout, " bits in <1 sec");
+ }
+ if (write_count > 0)
+ {
+ ui_out_text (uiout, ", ");
+ ui_out_field_fmt (uiout, "write-rate", "%lu", data_count / write_count);
+ ui_out_text (uiout, " bytes/write");
+ }
+ ui_out_text (uiout, ".\n");
+}
+
+/* This function allows the addition of incrementally linked object files.
+ It does not modify any state in the target, only in the debugger. */
+/* Note: ezannoni 2000-04-13 This function/command used to have a
+ special case syntax for the rombug target (Rombug is the boot
+ monitor for Microware's OS-9 / OS-9000, see remote-os9k.c). In the
+ rombug case, the user doesn't need to supply a text address,
+ instead a call to target_link() (in target.c) would supply the
+ value to use. We are now discontinuing this type of ad hoc syntax. */
+
+/* ARGSUSED */
+static void
+add_symbol_file_command (char *args, int from_tty)
+{
+ char *filename = NULL;
+ int flags = OBJF_USERLOADED;
+ char *arg;
+ int expecting_option = 0;
+ int section_index = 0;
+ int argcnt = 0;
+ int sec_num = 0;
+ int i;
+ int expecting_sec_name = 0;
+ int expecting_sec_addr = 0;
+
+ struct
+ {
+ char *name;
+ char *value;
+ } sect_opts[SECT_OFF_MAX];
+
+ struct section_addr_info section_addrs;
+ struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL);
+
+ dont_repeat ();
+
+ if (args == NULL)
+ error ("add-symbol-file takes a file name and an address");
+
+ /* Make a copy of the string that we can safely write into. */
+ args = xstrdup (args);
+
+ /* Ensure section_addrs is initialized */
+ memset (&section_addrs, 0, sizeof (section_addrs));
+
+ while (*args != '\000')
+ {
+ /* Any leading spaces? */
+ while (isspace (*args))
+ args++;
+
+ /* Point arg to the beginning of the argument. */
+ arg = args;
+
+ /* Move args pointer over the argument. */
+ while ((*args != '\000') && !isspace (*args))
+ args++;
+
+ /* If there are more arguments, terminate arg and
+ proceed past it. */
+ if (*args != '\000')
+ *args++ = '\000';
+
+ /* Now process the argument. */
+ if (argcnt == 0)
+ {
+ /* The first argument is the file name. */
+ filename = tilde_expand (arg);
+ make_cleanup (xfree, filename);
+ }
+ else
+ if (argcnt == 1)
+ {
+ /* The second argument is always the text address at which
+ to load the program. */
+ sect_opts[section_index].name = ".text";
+ sect_opts[section_index].value = arg;
+ section_index++;
+ }
+ else
+ {
+ /* It's an option (starting with '-') or it's an argument
+ to an option */
+
+ if (*arg == '-')
+ {
+ if (strcmp (arg, "-mapped") == 0)
+ flags |= OBJF_MAPPED;
+ else
+ if (strcmp (arg, "-readnow") == 0)
+ flags |= OBJF_READNOW;
+ else
+ if (strcmp (arg, "-s") == 0)
+ {
+ if (section_index >= SECT_OFF_MAX)
+ error ("Too many sections specified.");
+ expecting_sec_name = 1;
+ expecting_sec_addr = 1;
+ }
+ }
+ else
+ {
+ if (expecting_sec_name)
+ {
+ sect_opts[section_index].name = arg;
+ expecting_sec_name = 0;
+ }
+ else
+ if (expecting_sec_addr)
+ {
+ sect_opts[section_index].value = arg;
+ expecting_sec_addr = 0;
+ section_index++;
+ }
+ else
+ error ("USAGE: add-symbol-file <filename> <textaddress> [-mapped] [-readnow] [-s <secname> <addr>]*");
+ }
+ }
+ argcnt++;
+ }
+
+ /* Print the prompt for the query below. And save the arguments into
+ a sect_addr_info structure to be passed around to other
+ functions. We have to split this up into separate print
+ statements because local_hex_string returns a local static
+ string. */
+
+ printf_filtered ("add symbol table from file \"%s\" at\n", filename);
+ for (i = 0; i < section_index; i++)
+ {
+ CORE_ADDR addr;
+ char *val = sect_opts[i].value;
+ char *sec = sect_opts[i].name;
+
+ val = sect_opts[i].value;
+ if (val[0] == '0' && val[1] == 'x')
+ addr = strtoul (val+2, NULL, 16);
+ else
+ addr = strtoul (val, NULL, 10);
+
+ /* Here we store the section offsets in the order they were
+ entered on the command line. */
+ section_addrs.other[sec_num].name = sec;
+ section_addrs.other[sec_num].addr = addr;
+ printf_filtered ("\t%s_addr = %s\n",
+ sec,
+ local_hex_string ((unsigned long)addr));
+ sec_num++;
+
+ /* The object's sections are initialized when a
+ call is made to build_objfile_section_table (objfile).
+ This happens in reread_symbols.
+ At this point, we don't know what file type this is,
+ so we can't determine what section names are valid. */
+ }
+
+ if (from_tty && (!query ("%s", "")))
+ error ("Not confirmed.");
+
+ symbol_file_add (filename, from_tty, &section_addrs, 0, flags);
+
+ /* Getting new symbols may change our opinion about what is
+ frameless. */
+ reinit_frame_cache ();
+ do_cleanups (my_cleanups);
+}
+
+static void
+add_shared_symbol_files_command (char *args, int from_tty)
+{
+#ifdef ADD_SHARED_SYMBOL_FILES
+ ADD_SHARED_SYMBOL_FILES (args, from_tty);
+#else
+ error ("This command is not available in this configuration of GDB.");
+#endif
+}
+
+/* Re-read symbols if a symbol-file has changed. */
+void
+reread_symbols (void)
+{
+ struct objfile *objfile;
+ long new_modtime;
+ int reread_one = 0;
+ struct stat new_statbuf;
+ int res;
+
+ /* With the addition of shared libraries, this should be modified,
+ the load time should be saved in the partial symbol tables, since
+ different tables may come from different source files. FIXME.
+ This routine should then walk down each partial symbol table
+ and see if the symbol table that it originates from has been changed */
+
+ for (objfile = object_files; objfile; objfile = objfile->next)
+ {
+ if (objfile->obfd)
+ {
+#ifdef IBM6000_TARGET
+ /* If this object is from a shared library, then you should
+ stat on the library name, not member name. */
+
+ if (objfile->obfd->my_archive)
+ res = stat (objfile->obfd->my_archive->filename, &new_statbuf);
+ else
+#endif
+ res = stat (objfile->name, &new_statbuf);
+ if (res != 0)
+ {
+ /* FIXME, should use print_sys_errmsg but it's not filtered. */
+ printf_filtered ("`%s' has disappeared; keeping its symbols.\n",
+ objfile->name);
+ continue;
+ }
+ new_modtime = new_statbuf.st_mtime;
+ if (new_modtime != objfile->mtime)
+ {
+ struct cleanup *old_cleanups;
+ struct section_offsets *offsets;
+ int num_offsets;
+ char *obfd_filename;
+
+ printf_filtered ("`%s' has changed; re-reading symbols.\n",
+ objfile->name);
+
+ /* There are various functions like symbol_file_add,
+ symfile_bfd_open, syms_from_objfile, etc., which might
+ appear to do what we want. But they have various other
+ effects which we *don't* want. So we just do stuff
+ ourselves. We don't worry about mapped files (for one thing,
+ any mapped file will be out of date). */
+
+ /* If we get an error, blow away this objfile (not sure if
+ that is the correct response for things like shared
+ libraries). */
+ old_cleanups = make_cleanup_free_objfile (objfile);
+ /* We need to do this whenever any symbols go away. */
+ make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/);
+
+ /* Clean up any state BFD has sitting around. We don't need
+ to close the descriptor but BFD lacks a way of closing the
+ BFD without closing the descriptor. */
+ obfd_filename = bfd_get_filename (objfile->obfd);
+ if (!bfd_close (objfile->obfd))
+ error ("Can't close BFD for %s: %s", objfile->name,
+ bfd_errmsg (bfd_get_error ()));
+ objfile->obfd = bfd_openr (obfd_filename, gnutarget);
+ if (objfile->obfd == NULL)
+ error ("Can't open %s to read symbols.", objfile->name);
+ /* bfd_openr sets cacheable to true, which is what we want. */
+ if (!bfd_check_format (objfile->obfd, bfd_object))
+ error ("Can't read symbols from %s: %s.", objfile->name,
+ bfd_errmsg (bfd_get_error ()));
+
+ /* Save the offsets, we will nuke them with the rest of the
+ psymbol_obstack. */
+ num_offsets = objfile->num_sections;
+ offsets = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
+ memcpy (offsets, objfile->section_offsets, SIZEOF_SECTION_OFFSETS);
+
+ /* Nuke all the state that we will re-read. Much of the following
+ code which sets things to NULL really is necessary to tell
+ other parts of GDB that there is nothing currently there. */
+
+ /* FIXME: Do we have to free a whole linked list, or is this
+ enough? */
+ if (objfile->global_psymbols.list)
+ xmfree (objfile->md, objfile->global_psymbols.list);
+ memset (&objfile->global_psymbols, 0,
+ sizeof (objfile->global_psymbols));
+ if (objfile->static_psymbols.list)
+ xmfree (objfile->md, objfile->static_psymbols.list);
+ memset (&objfile->static_psymbols, 0,
+ sizeof (objfile->static_psymbols));
+
+ /* Free the obstacks for non-reusable objfiles */
+ free_bcache (&objfile->psymbol_cache);
+ free_bcache (&objfile->macro_cache);
+ obstack_free (&objfile->psymbol_obstack, 0);
+ obstack_free (&objfile->symbol_obstack, 0);
+ obstack_free (&objfile->type_obstack, 0);
+ objfile->sections = NULL;
+ objfile->symtabs = NULL;
+ objfile->psymtabs = NULL;
+ objfile->free_psymtabs = NULL;
+ objfile->msymbols = NULL;
+ objfile->minimal_symbol_count = 0;
+ memset (&objfile->msymbol_hash, 0,
+ sizeof (objfile->msymbol_hash));
+ memset (&objfile->msymbol_demangled_hash, 0,
+ sizeof (objfile->msymbol_demangled_hash));
+ objfile->fundamental_types = NULL;
+ if (objfile->sf != NULL)
+ {
+ (*objfile->sf->sym_finish) (objfile);
+ }
+
+ /* We never make this a mapped file. */
+ objfile->md = NULL;
+ /* obstack_specify_allocation also initializes the obstack so
+ it is empty. */
+ obstack_specify_allocation (&objfile->psymbol_cache.cache, 0, 0,
+ xmalloc, xfree);
+ obstack_specify_allocation (&objfile->macro_cache.cache, 0, 0,
+ xmalloc, xfree);
+ obstack_specify_allocation (&objfile->psymbol_obstack, 0, 0,
+ xmalloc, xfree);
+ obstack_specify_allocation (&objfile->symbol_obstack, 0, 0,
+ xmalloc, xfree);
+ obstack_specify_allocation (&objfile->type_obstack, 0, 0,
+ xmalloc, xfree);
+ if (build_objfile_section_table (objfile))
+ {
+ error ("Can't find the file sections in `%s': %s",
+ objfile->name, bfd_errmsg (bfd_get_error ()));
+ }
+
+ /* We use the same section offsets as from last time. I'm not
+ sure whether that is always correct for shared libraries. */
+ objfile->section_offsets = (struct section_offsets *)
+ obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
+ memcpy (objfile->section_offsets, offsets, SIZEOF_SECTION_OFFSETS);
+ objfile->num_sections = num_offsets;
+
+ /* What the hell is sym_new_init for, anyway? The concept of
+ distinguishing between the main file and additional files
+ in this way seems rather dubious. */
+ if (objfile == symfile_objfile)
+ {
+ (*objfile->sf->sym_new_init) (objfile);
+#ifdef HPUXHPPA
+ RESET_HP_UX_GLOBALS ();
+#endif
+ }
+
+ (*objfile->sf->sym_init) (objfile);
+ clear_complaints (1, 1);
+ /* The "mainline" parameter is a hideous hack; I think leaving it
+ zero is OK since dbxread.c also does what it needs to do if
+ objfile->global_psymbols.size is 0. */
+ (*objfile->sf->sym_read) (objfile, 0);
+ if (!have_partial_symbols () && !have_full_symbols ())
+ {
+ wrap_here ("");
+ printf_filtered ("(no debugging symbols found)\n");
+ wrap_here ("");
+ }
+ objfile->flags |= OBJF_SYMS;
+
+ /* We're done reading the symbol file; finish off complaints. */
+ clear_complaints (0, 1);
+
+ /* Getting new symbols may change our opinion about what is
+ frameless. */
+
+ reinit_frame_cache ();
+
+ /* Discard cleanups as symbol reading was successful. */
+ discard_cleanups (old_cleanups);
+
+ /* If the mtime has changed between the time we set new_modtime
+ and now, we *want* this to be out of date, so don't call stat
+ again now. */
+ objfile->mtime = new_modtime;
+ reread_one = 1;
+
+ /* Call this after reading in a new symbol table to give target
+ dependent code a crack at the new symbols. For instance, this
+ could be used to update the values of target-specific symbols GDB
+ needs to keep track of (such as _sigtramp, or whatever). */
+
+ TARGET_SYMFILE_POSTREAD (objfile);
+ }
+ }
+ }
+
+ if (reread_one)
+ clear_symtab_users ();
+}
+
+
+
+typedef struct
+{
+ char *ext;
+ enum language lang;
+}
+filename_language;
+
+static filename_language *filename_language_table;
+static int fl_table_size, fl_table_next;
+
+static void
+add_filename_language (char *ext, enum language lang)
+{
+ if (fl_table_next >= fl_table_size)
+ {
+ fl_table_size += 10;
+ filename_language_table =
+ xrealloc (filename_language_table,
+ fl_table_size * sizeof (*filename_language_table));
+ }
+
+ filename_language_table[fl_table_next].ext = xstrdup (ext);
+ filename_language_table[fl_table_next].lang = lang;
+ fl_table_next++;
+}
+
+static char *ext_args;
+
+static void
+set_ext_lang_command (char *args, int from_tty)
+{
+ int i;
+ char *cp = ext_args;
+ enum language lang;
+
+ /* First arg is filename extension, starting with '.' */
+ if (*cp != '.')
+ error ("'%s': Filename extension must begin with '.'", ext_args);
+
+ /* Find end of first arg. */
+ while (*cp && !isspace (*cp))
+ cp++;
+
+ if (*cp == '\0')
+ error ("'%s': two arguments required -- filename extension and language",
+ ext_args);
+
+ /* Null-terminate first arg */
+ *cp++ = '\0';
+
+ /* Find beginning of second arg, which should be a source language. */
+ while (*cp && isspace (*cp))
+ cp++;
+
+ if (*cp == '\0')
+ error ("'%s': two arguments required -- filename extension and language",
+ ext_args);
+
+ /* Lookup the language from among those we know. */
+ lang = language_enum (cp);
+
+ /* Now lookup the filename extension: do we already know it? */
+ for (i = 0; i < fl_table_next; i++)
+ if (0 == strcmp (ext_args, filename_language_table[i].ext))
+ break;
+
+ if (i >= fl_table_next)
+ {
+ /* new file extension */
+ add_filename_language (ext_args, lang);
+ }
+ else
+ {
+ /* redefining a previously known filename extension */
+
+ /* if (from_tty) */
+ /* query ("Really make files of type %s '%s'?", */
+ /* ext_args, language_str (lang)); */
+
+ xfree (filename_language_table[i].ext);
+ filename_language_table[i].ext = xstrdup (ext_args);
+ filename_language_table[i].lang = lang;
+ }
+}
+
+static void
+info_ext_lang_command (char *args, int from_tty)
+{
+ int i;
+
+ printf_filtered ("Filename extensions and the languages they represent:");
+ printf_filtered ("\n\n");
+ for (i = 0; i < fl_table_next; i++)
+ printf_filtered ("\t%s\t- %s\n",
+ filename_language_table[i].ext,
+ language_str (filename_language_table[i].lang));
+}
+
+static void
+init_filename_language_table (void)
+{
+ if (fl_table_size == 0) /* protect against repetition */
+ {
+ fl_table_size = 20;
+ fl_table_next = 0;
+ filename_language_table =
+ xmalloc (fl_table_size * sizeof (*filename_language_table));
+ add_filename_language (".c", language_c);
+ add_filename_language (".C", language_cplus);
+ add_filename_language (".cc", language_cplus);
+ add_filename_language (".cp", language_cplus);
+ add_filename_language (".cpp", language_cplus);
+ add_filename_language (".cxx", language_cplus);
+ add_filename_language (".c++", language_cplus);
+ add_filename_language (".java", language_java);
+ add_filename_language (".class", language_java);
+ add_filename_language (".ch", language_chill);
+ add_filename_language (".c186", language_chill);
+ add_filename_language (".c286", language_chill);
+ add_filename_language (".f", language_fortran);
+ add_filename_language (".F", language_fortran);
+ add_filename_language (".s", language_asm);
+ add_filename_language (".S", language_asm);
+ add_filename_language (".pas", language_pascal);
+ add_filename_language (".p", language_pascal);
+ add_filename_language (".pp", language_pascal);
+ }
+}
+
+enum language
+deduce_language_from_filename (char *filename)
+{
+ int i;
+ char *cp;
+
+ if (filename != NULL)
+ if ((cp = strrchr (filename, '.')) != NULL)
+ for (i = 0; i < fl_table_next; i++)
+ if (strcmp (cp, filename_language_table[i].ext) == 0)
+ return filename_language_table[i].lang;
+
+ return language_unknown;
+}
+
+/* allocate_symtab:
+
+ Allocate and partly initialize a new symbol table. Return a pointer
+ to it. error() if no space.
+
+ Caller must set these fields:
+ LINETABLE(symtab)
+ symtab->blockvector
+ symtab->dirname
+ symtab->free_code
+ symtab->free_ptr
+ possibly free_named_symtabs (symtab->filename);
+ */
+
+struct symtab *
+allocate_symtab (char *filename, struct objfile *objfile)
+{
+ register struct symtab *symtab;
+
+ symtab = (struct symtab *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct symtab));
+ memset (symtab, 0, sizeof (*symtab));
+ symtab->filename = obsavestring (filename, strlen (filename),
+ &objfile->symbol_obstack);
+ symtab->fullname = NULL;
+ symtab->language = deduce_language_from_filename (filename);
+ symtab->debugformat = obsavestring ("unknown", 7,
+ &objfile->symbol_obstack);
+
+ /* Hook it to the objfile it comes from */
+
+ symtab->objfile = objfile;
+ symtab->next = objfile->symtabs;
+ objfile->symtabs = symtab;
+
+ /* FIXME: This should go away. It is only defined for the Z8000,
+ and the Z8000 definition of this macro doesn't have anything to
+ do with the now-nonexistent EXTRA_SYMTAB_INFO macro, it's just
+ here for convenience. */
+#ifdef INIT_EXTRA_SYMTAB_INFO
+ INIT_EXTRA_SYMTAB_INFO (symtab);
+#endif
+
+ return (symtab);
+}
+
+struct partial_symtab *
+allocate_psymtab (char *filename, struct objfile *objfile)
+{
+ struct partial_symtab *psymtab;
+
+ if (objfile->free_psymtabs)
+ {
+ psymtab = objfile->free_psymtabs;
+ objfile->free_psymtabs = psymtab->next;
+ }
+ else
+ psymtab = (struct partial_symtab *)
+ obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct partial_symtab));
+
+ memset (psymtab, 0, sizeof (struct partial_symtab));
+ psymtab->filename = obsavestring (filename, strlen (filename),
+ &objfile->psymbol_obstack);
+ psymtab->symtab = NULL;
+
+ /* Prepend it to the psymtab list for the objfile it belongs to.
+ Psymtabs are searched in most recent inserted -> least recent
+ inserted order. */
+
+ psymtab->objfile = objfile;
+ psymtab->next = objfile->psymtabs;
+ objfile->psymtabs = psymtab;
+#if 0
+ {
+ struct partial_symtab **prev_pst;
+ psymtab->objfile = objfile;
+ psymtab->next = NULL;
+ prev_pst = &(objfile->psymtabs);
+ while ((*prev_pst) != NULL)
+ prev_pst = &((*prev_pst)->next);
+ (*prev_pst) = psymtab;
+ }
+#endif
+
+ return (psymtab);
+}
+
+void
+discard_psymtab (struct partial_symtab *pst)
+{
+ struct partial_symtab **prev_pst;
+
+ /* From dbxread.c:
+ Empty psymtabs happen as a result of header files which don't
+ have any symbols in them. There can be a lot of them. But this
+ check is wrong, in that a psymtab with N_SLINE entries but
+ nothing else is not empty, but we don't realize that. Fixing
+ that without slowing things down might be tricky. */
+
+ /* First, snip it out of the psymtab chain */
+
+ prev_pst = &(pst->objfile->psymtabs);
+ while ((*prev_pst) != pst)
+ prev_pst = &((*prev_pst)->next);
+ (*prev_pst) = pst->next;
+
+ /* Next, put it on a free list for recycling */
+
+ pst->next = pst->objfile->free_psymtabs;
+ pst->objfile->free_psymtabs = pst;
+}
+
+
+/* Reset all data structures in gdb which may contain references to symbol
+ table data. */
+
+void
+clear_symtab_users (void)
+{
+ /* Someday, we should do better than this, by only blowing away
+ the things that really need to be blown. */
+ clear_value_history ();
+ clear_displays ();
+ clear_internalvars ();
+ breakpoint_re_set ();
+ set_default_breakpoint (0, 0, 0, 0);
+ current_source_symtab = 0;
+ current_source_line = 0;
+ clear_pc_function_cache ();
+ if (target_new_objfile_hook)
+ target_new_objfile_hook (NULL);
+}
+
+static void
+clear_symtab_users_cleanup (void *ignore)
+{
+ clear_symtab_users ();
+}
+
+/* clear_symtab_users_once:
+
+ This function is run after symbol reading, or from a cleanup.
+ If an old symbol table was obsoleted, the old symbol table
+ has been blown away, but the other GDB data structures that may
+ reference it have not yet been cleared or re-directed. (The old
+ symtab was zapped, and the cleanup queued, in free_named_symtab()
+ below.)
+
+ This function can be queued N times as a cleanup, or called
+ directly; it will do all the work the first time, and then will be a
+ no-op until the next time it is queued. This works by bumping a
+ counter at queueing time. Much later when the cleanup is run, or at
+ the end of symbol processing (in case the cleanup is discarded), if
+ the queued count is greater than the "done-count", we do the work
+ and set the done-count to the queued count. If the queued count is
+ less than or equal to the done-count, we just ignore the call. This
+ is needed because reading a single .o file will often replace many
+ symtabs (one per .h file, for example), and we don't want to reset
+ the breakpoints N times in the user's face.
+
+ The reason we both queue a cleanup, and call it directly after symbol
+ reading, is because the cleanup protects us in case of errors, but is
+ discarded if symbol reading is successful. */
+
+#if 0
+/* FIXME: As free_named_symtabs is currently a big noop this function
+ is no longer needed. */
+static void clear_symtab_users_once (void);
+
+static int clear_symtab_users_queued;
+static int clear_symtab_users_done;
+
+static void
+clear_symtab_users_once (void)
+{
+ /* Enforce once-per-`do_cleanups'-semantics */
+ if (clear_symtab_users_queued <= clear_symtab_users_done)
+ return;
+ clear_symtab_users_done = clear_symtab_users_queued;
+
+ clear_symtab_users ();
+}
+#endif
+
+/* Delete the specified psymtab, and any others that reference it. */
+
+static void
+cashier_psymtab (struct partial_symtab *pst)
+{
+ struct partial_symtab *ps, *pprev = NULL;
+ int i;
+
+ /* Find its previous psymtab in the chain */
+ for (ps = pst->objfile->psymtabs; ps; ps = ps->next)
+ {
+ if (ps == pst)
+ break;
+ pprev = ps;
+ }
+
+ if (ps)
+ {
+ /* Unhook it from the chain. */
+ if (ps == pst->objfile->psymtabs)
+ pst->objfile->psymtabs = ps->next;
+ else
+ pprev->next = ps->next;
+
+ /* FIXME, we can't conveniently deallocate the entries in the
+ partial_symbol lists (global_psymbols/static_psymbols) that
+ this psymtab points to. These just take up space until all
+ the psymtabs are reclaimed. Ditto the dependencies list and
+ filename, which are all in the psymbol_obstack. */
+
+ /* We need to cashier any psymtab that has this one as a dependency... */
+ again:
+ for (ps = pst->objfile->psymtabs; ps; ps = ps->next)
+ {
+ for (i = 0; i < ps->number_of_dependencies; i++)
+ {
+ if (ps->dependencies[i] == pst)
+ {
+ cashier_psymtab (ps);
+ goto again; /* Must restart, chain has been munged. */
+ }
+ }
+ }
+ }
+}
+
+/* If a symtab or psymtab for filename NAME is found, free it along
+ with any dependent breakpoints, displays, etc.
+ Used when loading new versions of object modules with the "add-file"
+ command. This is only called on the top-level symtab or psymtab's name;
+ it is not called for subsidiary files such as .h files.
+
+ Return value is 1 if we blew away the environment, 0 if not.
+ FIXME. The return value appears to never be used.
+
+ FIXME. I think this is not the best way to do this. We should
+ work on being gentler to the environment while still cleaning up
+ all stray pointers into the freed symtab. */
+
+int
+free_named_symtabs (char *name)
+{
+#if 0
+ /* FIXME: With the new method of each objfile having it's own
+ psymtab list, this function needs serious rethinking. In particular,
+ why was it ever necessary to toss psymtabs with specific compilation
+ unit filenames, as opposed to all psymtabs from a particular symbol
+ file? -- fnf
+ Well, the answer is that some systems permit reloading of particular
+ compilation units. We want to blow away any old info about these
+ compilation units, regardless of which objfiles they arrived in. --gnu. */
+
+ register struct symtab *s;
+ register struct symtab *prev;
+ register struct partial_symtab *ps;
+ struct blockvector *bv;
+ int blewit = 0;
+
+ /* We only wack things if the symbol-reload switch is set. */
+ if (!symbol_reloading)
+ return 0;
+
+ /* Some symbol formats have trouble providing file names... */
+ if (name == 0 || *name == '\0')
+ return 0;
+
+ /* Look for a psymtab with the specified name. */
+
+again2:
+ for (ps = partial_symtab_list; ps; ps = ps->next)
+ {
+ if (STREQ (name, ps->filename))
+ {
+ cashier_psymtab (ps); /* Blow it away...and its little dog, too. */
+ goto again2; /* Must restart, chain has been munged */
+ }
+ }
+
+ /* Look for a symtab with the specified name. */
+
+ for (s = symtab_list; s; s = s->next)
+ {
+ if (STREQ (name, s->filename))
+ break;
+ prev = s;
+ }
+
+ if (s)
+ {
+ if (s == symtab_list)
+ symtab_list = s->next;
+ else
+ prev->next = s->next;
+
+ /* For now, queue a delete for all breakpoints, displays, etc., whether
+ or not they depend on the symtab being freed. This should be
+ changed so that only those data structures affected are deleted. */
+
+ /* But don't delete anything if the symtab is empty.
+ This test is necessary due to a bug in "dbxread.c" that
+ causes empty symtabs to be created for N_SO symbols that
+ contain the pathname of the object file. (This problem
+ has been fixed in GDB 3.9x). */
+
+ bv = BLOCKVECTOR (s);
+ if (BLOCKVECTOR_NBLOCKS (bv) > 2
+ || BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK))
+ || BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)))
+ {
+ complain (&oldsyms_complaint, name);
+
+ clear_symtab_users_queued++;
+ make_cleanup (clear_symtab_users_once, 0);
+ blewit = 1;
+ }
+ else
+ {
+ complain (&empty_symtab_complaint, name);
+ }
+
+ free_symtab (s);
+ }
+ else
+ {
+ /* It is still possible that some breakpoints will be affected
+ even though no symtab was found, since the file might have
+ been compiled without debugging, and hence not be associated
+ with a symtab. In order to handle this correctly, we would need
+ to keep a list of text address ranges for undebuggable files.
+ For now, we do nothing, since this is a fairly obscure case. */
+ ;
+ }
+
+ /* FIXME, what about the minimal symbol table? */
+ return blewit;
+#else
+ return (0);
+#endif
+}
+
+/* Allocate and partially fill a partial symtab. It will be
+ completely filled at the end of the symbol list.
+
+ FILENAME is the name of the symbol-file we are reading from. */
+
+struct partial_symtab *
+start_psymtab_common (struct objfile *objfile,
+ struct section_offsets *section_offsets, char *filename,
+ CORE_ADDR textlow, struct partial_symbol **global_syms,
+ struct partial_symbol **static_syms)
+{
+ struct partial_symtab *psymtab;
+
+ psymtab = allocate_psymtab (filename, objfile);
+ psymtab->section_offsets = section_offsets;
+ psymtab->textlow = textlow;
+ psymtab->texthigh = psymtab->textlow; /* default */
+ psymtab->globals_offset = global_syms - objfile->global_psymbols.list;
+ psymtab->statics_offset = static_syms - objfile->static_psymbols.list;
+ return (psymtab);
+}
+
+/* Add a symbol with a long value to a psymtab.
+ Since one arg is a struct, we pass in a ptr and deref it (sigh). */
+
+void
+add_psymbol_to_list (char *name, int namelength, namespace_enum namespace,
+ enum address_class class,
+ struct psymbol_allocation_list *list, long val, /* Value as a long */
+ CORE_ADDR coreaddr, /* Value as a CORE_ADDR */
+ enum language language, struct objfile *objfile)
+{
+ register struct partial_symbol *psym;
+ char *buf = alloca (namelength + 1);
+ /* psymbol is static so that there will be no uninitialized gaps in the
+ structure which might contain random data, causing cache misses in
+ bcache. */
+ static struct partial_symbol psymbol;
+
+ /* Create local copy of the partial symbol */
+ memcpy (buf, name, namelength);
+ buf[namelength] = '\0';
+ SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, &objfile->psymbol_cache);
+ /* val and coreaddr are mutually exclusive, one of them *will* be zero */
+ if (val != 0)
+ {
+ SYMBOL_VALUE (&psymbol) = val;
+ }
+ else
+ {
+ SYMBOL_VALUE_ADDRESS (&psymbol) = coreaddr;
+ }
+ SYMBOL_SECTION (&psymbol) = 0;
+ SYMBOL_LANGUAGE (&psymbol) = language;
+ PSYMBOL_NAMESPACE (&psymbol) = namespace;
+ PSYMBOL_CLASS (&psymbol) = class;
+ SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language);
+
+ /* Stash the partial symbol away in the cache */
+ psym = bcache (&psymbol, sizeof (struct partial_symbol), &objfile->psymbol_cache);
+
+ /* Save pointer to partial symbol in psymtab, growing symtab if needed. */
+ if (list->next >= list->list + list->size)
+ {
+ extend_psymbol_list (list, objfile);
+ }
+ *list->next++ = psym;
+ OBJSTAT (objfile, n_psyms++);
+}
+
+/* Add a symbol with a long value to a psymtab. This differs from
+ * add_psymbol_to_list above in taking both a mangled and a demangled
+ * name. */
+
+void
+add_psymbol_with_dem_name_to_list (char *name, int namelength, char *dem_name,
+ int dem_namelength, namespace_enum namespace,
+ enum address_class class,
+ struct psymbol_allocation_list *list, long val, /* Value as a long */
+ CORE_ADDR coreaddr, /* Value as a CORE_ADDR */
+ enum language language,
+ struct objfile *objfile)
+{
+ register struct partial_symbol *psym;
+ char *buf = alloca (namelength + 1);
+ /* psymbol is static so that there will be no uninitialized gaps in the
+ structure which might contain random data, causing cache misses in
+ bcache. */
+ static struct partial_symbol psymbol;
+
+ /* Create local copy of the partial symbol */
+
+ memcpy (buf, name, namelength);
+ buf[namelength] = '\0';
+ SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, &objfile->psymbol_cache);
+
+ buf = alloca (dem_namelength + 1);
+ memcpy (buf, dem_name, dem_namelength);
+ buf[dem_namelength] = '\0';
+
+ switch (language)
+ {
+ case language_c:
+ case language_cplus:
+ SYMBOL_CPLUS_DEMANGLED_NAME (&psymbol) =
+ bcache (buf, dem_namelength + 1, &objfile->psymbol_cache);
+ break;
+ case language_chill:
+ SYMBOL_CHILL_DEMANGLED_NAME (&psymbol) =
+ bcache (buf, dem_namelength + 1, &objfile->psymbol_cache);
+
+ /* FIXME What should be done for the default case? Ignoring for now. */
+ }
+
+ /* val and coreaddr are mutually exclusive, one of them *will* be zero */
+ if (val != 0)
+ {
+ SYMBOL_VALUE (&psymbol) = val;
+ }
+ else
+ {
+ SYMBOL_VALUE_ADDRESS (&psymbol) = coreaddr;
+ }
+ SYMBOL_SECTION (&psymbol) = 0;
+ SYMBOL_LANGUAGE (&psymbol) = language;
+ PSYMBOL_NAMESPACE (&psymbol) = namespace;
+ PSYMBOL_CLASS (&psymbol) = class;
+ SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language);
+
+ /* Stash the partial symbol away in the cache */
+ psym = bcache (&psymbol, sizeof (struct partial_symbol), &objfile->psymbol_cache);
+
+ /* Save pointer to partial symbol in psymtab, growing symtab if needed. */
+ if (list->next >= list->list + list->size)
+ {
+ extend_psymbol_list (list, objfile);
+ }
+ *list->next++ = psym;
+ OBJSTAT (objfile, n_psyms++);
+}
+
+/* Initialize storage for partial symbols. */
+
+void
+init_psymbol_list (struct objfile *objfile, int total_symbols)
+{
+ /* Free any previously allocated psymbol lists. */
+
+ if (objfile->global_psymbols.list)
+ {
+ xmfree (objfile->md, (PTR) objfile->global_psymbols.list);
+ }
+ if (objfile->static_psymbols.list)
+ {
+ xmfree (objfile->md, (PTR) objfile->static_psymbols.list);
+ }
+
+ /* Current best guess is that approximately a twentieth
+ of the total symbols (in a debugging file) are global or static
+ oriented symbols */
+
+ objfile->global_psymbols.size = total_symbols / 10;
+ objfile->static_psymbols.size = total_symbols / 10;
+
+ if (objfile->global_psymbols.size > 0)
+ {
+ objfile->global_psymbols.next =
+ objfile->global_psymbols.list = (struct partial_symbol **)
+ xmmalloc (objfile->md, (objfile->global_psymbols.size
+ * sizeof (struct partial_symbol *)));
+ }
+ if (objfile->static_psymbols.size > 0)
+ {
+ objfile->static_psymbols.next =
+ objfile->static_psymbols.list = (struct partial_symbol **)
+ xmmalloc (objfile->md, (objfile->static_psymbols.size
+ * sizeof (struct partial_symbol *)));
+ }
+}
+
+/* OVERLAYS:
+ The following code implements an abstraction for debugging overlay sections.
+
+ The target model is as follows:
+ 1) The gnu linker will permit multiple sections to be mapped into the
+ same VMA, each with its own unique LMA (or load address).
+ 2) It is assumed that some runtime mechanism exists for mapping the
+ sections, one by one, from the load address into the VMA address.
+ 3) This code provides a mechanism for gdb to keep track of which
+ sections should be considered to be mapped from the VMA to the LMA.
+ This information is used for symbol lookup, and memory read/write.
+ For instance, if a section has been mapped then its contents
+ should be read from the VMA, otherwise from the LMA.
+
+ Two levels of debugger support for overlays are available. One is
+ "manual", in which the debugger relies on the user to tell it which
+ overlays are currently mapped. This level of support is
+ implemented entirely in the core debugger, and the information about
+ whether a section is mapped is kept in the objfile->obj_section table.
+
+ The second level of support is "automatic", and is only available if
+ the target-specific code provides functionality to read the target's
+ overlay mapping table, and translate its contents for the debugger
+ (by updating the mapped state information in the obj_section tables).
+
+ The interface is as follows:
+ User commands:
+ overlay map <name> -- tell gdb to consider this section mapped
+ overlay unmap <name> -- tell gdb to consider this section unmapped
+ overlay list -- list the sections that GDB thinks are mapped
+ overlay read-target -- get the target's state of what's mapped
+ overlay off/manual/auto -- set overlay debugging state
+ Functional interface:
+ find_pc_mapped_section(pc): if the pc is in the range of a mapped
+ section, return that section.
+ find_pc_overlay(pc): find any overlay section that contains
+ the pc, either in its VMA or its LMA
+ overlay_is_mapped(sect): true if overlay is marked as mapped
+ section_is_overlay(sect): true if section's VMA != LMA
+ pc_in_mapped_range(pc,sec): true if pc belongs to section's VMA
+ pc_in_unmapped_range(...): true if pc belongs to section's LMA
+ sections_overlap(sec1, sec2): true if mapped sec1 and sec2 ranges overlap
+ overlay_mapped_address(...): map an address from section's LMA to VMA
+ overlay_unmapped_address(...): map an address from section's VMA to LMA
+ symbol_overlayed_address(...): Return a "current" address for symbol:
+ either in VMA or LMA depending on whether
+ the symbol's section is currently mapped
+ */
+
+/* Overlay debugging state: */
+
+enum overlay_debugging_state overlay_debugging = ovly_off;
+int overlay_cache_invalid = 0; /* True if need to refresh mapped state */
+
+/* Target vector for refreshing overlay mapped state */
+static void simple_overlay_update (struct obj_section *);
+void (*target_overlay_update) (struct obj_section *) = simple_overlay_update;
+
+/* Function: section_is_overlay (SECTION)
+ Returns true if SECTION has VMA not equal to LMA, ie.
+ SECTION is loaded at an address different from where it will "run". */
+
+int
+section_is_overlay (asection *section)
+{
+ /* FIXME: need bfd *, so we can use bfd_section_lma methods. */
+
+ if (overlay_debugging)
+ if (section && section->lma != 0 &&
+ section->vma != section->lma)
+ return 1;
+
+ return 0;
+}
+
+/* Function: overlay_invalidate_all (void)
+ Invalidate the mapped state of all overlay sections (mark it as stale). */
+
+static void
+overlay_invalidate_all (void)
+{
+ struct objfile *objfile;
+ struct obj_section *sect;
+
+ ALL_OBJSECTIONS (objfile, sect)
+ if (section_is_overlay (sect->the_bfd_section))
+ sect->ovly_mapped = -1;
+}
+
+/* Function: overlay_is_mapped (SECTION)
+ Returns true if section is an overlay, and is currently mapped.
+ Private: public access is thru function section_is_mapped.
+
+ Access to the ovly_mapped flag is restricted to this function, so
+ that we can do automatic update. If the global flag
+ OVERLAY_CACHE_INVALID is set (by wait_for_inferior), then call
+ overlay_invalidate_all. If the mapped state of the particular
+ section is stale, then call TARGET_OVERLAY_UPDATE to refresh it. */
+
+static int
+overlay_is_mapped (struct obj_section *osect)
+{
+ if (osect == 0 || !section_is_overlay (osect->the_bfd_section))
+ return 0;
+
+ switch (overlay_debugging)
+ {
+ default:
+ case ovly_off:
+ return 0; /* overlay debugging off */
+ case ovly_auto: /* overlay debugging automatic */
+ /* Unles there is a target_overlay_update function,
+ there's really nothing useful to do here (can't really go auto) */
+ if (target_overlay_update)
+ {
+ if (overlay_cache_invalid)
+ {
+ overlay_invalidate_all ();
+ overlay_cache_invalid = 0;
+ }
+ if (osect->ovly_mapped == -1)
+ (*target_overlay_update) (osect);
+ }
+ /* fall thru to manual case */
+ case ovly_on: /* overlay debugging manual */
+ return osect->ovly_mapped == 1;
+ }
+}
+
+/* Function: section_is_mapped
+ Returns true if section is an overlay, and is currently mapped. */
+
+int
+section_is_mapped (asection *section)
+{
+ struct objfile *objfile;
+ struct obj_section *osect;
+
+ if (overlay_debugging)
+ if (section && section_is_overlay (section))
+ ALL_OBJSECTIONS (objfile, osect)
+ if (osect->the_bfd_section == section)
+ return overlay_is_mapped (osect);
+
+ return 0;
+}
+
+/* Function: pc_in_unmapped_range
+ If PC falls into the lma range of SECTION, return true, else false. */
+
+CORE_ADDR
+pc_in_unmapped_range (CORE_ADDR pc, asection *section)
+{
+ /* FIXME: need bfd *, so we can use bfd_section_lma methods. */
+
+ int size;
+
+ if (overlay_debugging)
+ if (section && section_is_overlay (section))
+ {
+ size = bfd_get_section_size_before_reloc (section);
+ if (section->lma <= pc && pc < section->lma + size)
+ return 1;
+ }
+ return 0;
+}
+
+/* Function: pc_in_mapped_range
+ If PC falls into the vma range of SECTION, return true, else false. */
+
+CORE_ADDR
+pc_in_mapped_range (CORE_ADDR pc, asection *section)
+{
+ /* FIXME: need bfd *, so we can use bfd_section_vma methods. */
+
+ int size;
+
+ if (overlay_debugging)
+ if (section && section_is_overlay (section))
+ {
+ size = bfd_get_section_size_before_reloc (section);
+ if (section->vma <= pc && pc < section->vma + size)
+ return 1;
+ }
+ return 0;
+}
+
+
+/* Return true if the mapped ranges of sections A and B overlap, false
+ otherwise. */
+int
+sections_overlap (asection *a, asection *b)
+{
+ /* FIXME: need bfd *, so we can use bfd_section_vma methods. */
+
+ CORE_ADDR a_start = a->vma;
+ CORE_ADDR a_end = a->vma + bfd_get_section_size_before_reloc (a);
+ CORE_ADDR b_start = b->vma;
+ CORE_ADDR b_end = b->vma + bfd_get_section_size_before_reloc (b);
+
+ return (a_start < b_end && b_start < a_end);
+}
+
+/* Function: overlay_unmapped_address (PC, SECTION)
+ Returns the address corresponding to PC in the unmapped (load) range.
+ May be the same as PC. */
+
+CORE_ADDR
+overlay_unmapped_address (CORE_ADDR pc, asection *section)
+{
+ /* FIXME: need bfd *, so we can use bfd_section_lma methods. */
+
+ if (overlay_debugging)
+ if (section && section_is_overlay (section) &&
+ pc_in_mapped_range (pc, section))
+ return pc + section->lma - section->vma;
+
+ return pc;
+}
+
+/* Function: overlay_mapped_address (PC, SECTION)
+ Returns the address corresponding to PC in the mapped (runtime) range.
+ May be the same as PC. */
+
+CORE_ADDR
+overlay_mapped_address (CORE_ADDR pc, asection *section)
+{
+ /* FIXME: need bfd *, so we can use bfd_section_vma methods. */
+
+ if (overlay_debugging)
+ if (section && section_is_overlay (section) &&
+ pc_in_unmapped_range (pc, section))
+ return pc + section->vma - section->lma;
+
+ return pc;
+}
+
+
+/* Function: symbol_overlayed_address
+ Return one of two addresses (relative to the VMA or to the LMA),
+ depending on whether the section is mapped or not. */
+
+CORE_ADDR
+symbol_overlayed_address (CORE_ADDR address, asection *section)
+{
+ if (overlay_debugging)
+ {
+ /* If the symbol has no section, just return its regular address. */
+ if (section == 0)
+ return address;
+ /* If the symbol's section is not an overlay, just return its address */
+ if (!section_is_overlay (section))
+ return address;
+ /* If the symbol's section is mapped, just return its address */
+ if (section_is_mapped (section))
+ return address;
+ /*
+ * HOWEVER: if the symbol is in an overlay section which is NOT mapped,
+ * then return its LOADED address rather than its vma address!!
+ */
+ return overlay_unmapped_address (address, section);
+ }
+ return address;
+}
+
+/* Function: find_pc_overlay (PC)
+ Return the best-match overlay section for PC:
+ If PC matches a mapped overlay section's VMA, return that section.
+ Else if PC matches an unmapped section's VMA, return that section.
+ Else if PC matches an unmapped section's LMA, return that section. */
+
+asection *
+find_pc_overlay (CORE_ADDR pc)
+{
+ struct objfile *objfile;
+ struct obj_section *osect, *best_match = NULL;
+
+ if (overlay_debugging)
+ ALL_OBJSECTIONS (objfile, osect)
+ if (section_is_overlay (osect->the_bfd_section))
+ {
+ if (pc_in_mapped_range (pc, osect->the_bfd_section))
+ {
+ if (overlay_is_mapped (osect))
+ return osect->the_bfd_section;
+ else
+ best_match = osect;
+ }
+ else if (pc_in_unmapped_range (pc, osect->the_bfd_section))
+ best_match = osect;
+ }
+ return best_match ? best_match->the_bfd_section : NULL;
+}
+
+/* Function: find_pc_mapped_section (PC)
+ If PC falls into the VMA address range of an overlay section that is
+ currently marked as MAPPED, return that section. Else return NULL. */
+
+asection *
+find_pc_mapped_section (CORE_ADDR pc)
+{
+ struct objfile *objfile;
+ struct obj_section *osect;
+
+ if (overlay_debugging)
+ ALL_OBJSECTIONS (objfile, osect)
+ if (pc_in_mapped_range (pc, osect->the_bfd_section) &&
+ overlay_is_mapped (osect))
+ return osect->the_bfd_section;
+
+ return NULL;
+}
+
+/* Function: list_overlays_command
+ Print a list of mapped sections and their PC ranges */
+
+void
+list_overlays_command (char *args, int from_tty)
+{
+ int nmapped = 0;
+ struct objfile *objfile;
+ struct obj_section *osect;
+
+ if (overlay_debugging)
+ ALL_OBJSECTIONS (objfile, osect)
+ if (overlay_is_mapped (osect))
+ {
+ const char *name;
+ bfd_vma lma, vma;
+ int size;
+
+ vma = bfd_section_vma (objfile->obfd, osect->the_bfd_section);
+ lma = bfd_section_lma (objfile->obfd, osect->the_bfd_section);
+ size = bfd_get_section_size_before_reloc (osect->the_bfd_section);
+ name = bfd_section_name (objfile->obfd, osect->the_bfd_section);
+
+ printf_filtered ("Section %s, loaded at ", name);
+ print_address_numeric (lma, 1, gdb_stdout);
+ puts_filtered (" - ");
+ print_address_numeric (lma + size, 1, gdb_stdout);
+ printf_filtered (", mapped at ");
+ print_address_numeric (vma, 1, gdb_stdout);
+ puts_filtered (" - ");
+ print_address_numeric (vma + size, 1, gdb_stdout);
+ puts_filtered ("\n");
+
+ nmapped++;
+ }
+ if (nmapped == 0)
+ printf_filtered ("No sections are mapped.\n");
+}
+
+/* Function: map_overlay_command
+ Mark the named section as mapped (ie. residing at its VMA address). */
+
+void
+map_overlay_command (char *args, int from_tty)
+{
+ struct objfile *objfile, *objfile2;
+ struct obj_section *sec, *sec2;
+ asection *bfdsec;
+
+ if (!overlay_debugging)
+ error ("\
+Overlay debugging not enabled. Use either the 'overlay auto' or\n\
+the 'overlay manual' command.");
+
+ if (args == 0 || *args == 0)
+ error ("Argument required: name of an overlay section");
+
+ /* First, find a section matching the user supplied argument */
+ ALL_OBJSECTIONS (objfile, sec)
+ if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args))
+ {
+ /* Now, check to see if the section is an overlay. */
+ bfdsec = sec->the_bfd_section;
+ if (!section_is_overlay (bfdsec))
+ continue; /* not an overlay section */
+
+ /* Mark the overlay as "mapped" */
+ sec->ovly_mapped = 1;
+
+ /* Next, make a pass and unmap any sections that are
+ overlapped by this new section: */
+ ALL_OBJSECTIONS (objfile2, sec2)
+ if (sec2->ovly_mapped
+ && sec != sec2
+ && sec->the_bfd_section != sec2->the_bfd_section
+ && sections_overlap (sec->the_bfd_section,
+ sec2->the_bfd_section))
+ {
+ if (info_verbose)
+ printf_filtered ("Note: section %s unmapped by overlap\n",
+ bfd_section_name (objfile->obfd,
+ sec2->the_bfd_section));
+ sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2 */
+ }
+ return;
+ }
+ error ("No overlay section called %s", args);
+}
+
+/* Function: unmap_overlay_command
+ Mark the overlay section as unmapped
+ (ie. resident in its LMA address range, rather than the VMA range). */
+
+void
+unmap_overlay_command (char *args, int from_tty)
+{
+ struct objfile *objfile;
+ struct obj_section *sec;
+
+ if (!overlay_debugging)
+ error ("\
+Overlay debugging not enabled. Use either the 'overlay auto' or\n\
+the 'overlay manual' command.");
+
+ if (args == 0 || *args == 0)
+ error ("Argument required: name of an overlay section");
+
+ /* First, find a section matching the user supplied argument */
+ ALL_OBJSECTIONS (objfile, sec)
+ if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args))
+ {
+ if (!sec->ovly_mapped)
+ error ("Section %s is not mapped", args);
+ sec->ovly_mapped = 0;
+ return;
+ }
+ error ("No overlay section called %s", args);
+}
+
+/* Function: overlay_auto_command
+ A utility command to turn on overlay debugging.
+ Possibly this should be done via a set/show command. */
+
+static void
+overlay_auto_command (char *args, int from_tty)
+{
+ overlay_debugging = ovly_auto;
+ enable_overlay_breakpoints ();
+ if (info_verbose)
+ printf_filtered ("Automatic overlay debugging enabled.");
+}
+
+/* Function: overlay_manual_command
+ A utility command to turn on overlay debugging.
+ Possibly this should be done via a set/show command. */
+
+static void
+overlay_manual_command (char *args, int from_tty)
+{
+ overlay_debugging = ovly_on;
+ disable_overlay_breakpoints ();
+ if (info_verbose)
+ printf_filtered ("Overlay debugging enabled.");
+}
+
+/* Function: overlay_off_command
+ A utility command to turn on overlay debugging.
+ Possibly this should be done via a set/show command. */
+
+static void
+overlay_off_command (char *args, int from_tty)
+{
+ overlay_debugging = ovly_off;
+ disable_overlay_breakpoints ();
+ if (info_verbose)
+ printf_filtered ("Overlay debugging disabled.");
+}
+
+static void
+overlay_load_command (char *args, int from_tty)
+{
+ if (target_overlay_update)
+ (*target_overlay_update) (NULL);
+ else
+ error ("This target does not know how to read its overlay state.");
+}
+
+/* Function: overlay_command
+ A place-holder for a mis-typed command */
+
+/* Command list chain containing all defined "overlay" subcommands. */
+struct cmd_list_element *overlaylist;
+
+static void
+overlay_command (char *args, int from_tty)
+{
+ printf_unfiltered
+ ("\"overlay\" must be followed by the name of an overlay command.\n");
+ help_list (overlaylist, "overlay ", -1, gdb_stdout);
+}
+
+
+/* Target Overlays for the "Simplest" overlay manager:
+
+ This is GDB's default target overlay layer. It works with the
+ minimal overlay manager supplied as an example by Cygnus. The
+ entry point is via a function pointer "target_overlay_update",
+ so targets that use a different runtime overlay manager can
+ substitute their own overlay_update function and take over the
+ function pointer.
+
+ The overlay_update function pokes around in the target's data structures
+ to see what overlays are mapped, and updates GDB's overlay mapping with
+ this information.
+
+ In this simple implementation, the target data structures are as follows:
+ unsigned _novlys; /# number of overlay sections #/
+ unsigned _ovly_table[_novlys][4] = {
+ {VMA, SIZE, LMA, MAPPED}, /# one entry per overlay section #/
+ {..., ..., ..., ...},
+ }
+ unsigned _novly_regions; /# number of overlay regions #/
+ unsigned _ovly_region_table[_novly_regions][3] = {
+ {VMA, SIZE, MAPPED_TO_LMA}, /# one entry per overlay region #/
+ {..., ..., ...},
+ }
+ These functions will attempt to update GDB's mappedness state in the
+ symbol section table, based on the target's mappedness state.
+
+ To do this, we keep a cached copy of the target's _ovly_table, and
+ attempt to detect when the cached copy is invalidated. The main
+ entry point is "simple_overlay_update(SECT), which looks up SECT in
+ the cached table and re-reads only the entry for that section from
+ the target (whenever possible).
+ */
+
+/* Cached, dynamically allocated copies of the target data structures: */
+static unsigned (*cache_ovly_table)[4] = 0;
+#if 0
+static unsigned (*cache_ovly_region_table)[3] = 0;
+#endif
+static unsigned cache_novlys = 0;
+#if 0
+static unsigned cache_novly_regions = 0;
+#endif
+static CORE_ADDR cache_ovly_table_base = 0;
+#if 0
+static CORE_ADDR cache_ovly_region_table_base = 0;
+#endif
+enum ovly_index
+ {
+ VMA, SIZE, LMA, MAPPED
+ };
+#define TARGET_LONG_BYTES (TARGET_LONG_BIT / TARGET_CHAR_BIT)
+
+/* Throw away the cached copy of _ovly_table */
+static void
+simple_free_overlay_table (void)
+{
+ if (cache_ovly_table)
+ xfree (cache_ovly_table);
+ cache_novlys = 0;
+ cache_ovly_table = NULL;
+ cache_ovly_table_base = 0;
+}
+
+#if 0
+/* Throw away the cached copy of _ovly_region_table */
+static void
+simple_free_overlay_region_table (void)
+{
+ if (cache_ovly_region_table)
+ xfree (cache_ovly_region_table);
+ cache_novly_regions = 0;
+ cache_ovly_region_table = NULL;
+ cache_ovly_region_table_base = 0;
+}
+#endif
+
+/* Read an array of ints from the target into a local buffer.
+ Convert to host order. int LEN is number of ints */
+static void
+read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr, int len)
+{
+ /* FIXME (alloca): Not safe if array is very large. */
+ char *buf = alloca (len * TARGET_LONG_BYTES);
+ int i;
+
+ read_memory (memaddr, buf, len * TARGET_LONG_BYTES);
+ for (i = 0; i < len; i++)
+ myaddr[i] = extract_unsigned_integer (TARGET_LONG_BYTES * i + buf,
+ TARGET_LONG_BYTES);
+}
+
+/* Find and grab a copy of the target _ovly_table
+ (and _novlys, which is needed for the table's size) */
+static int
+simple_read_overlay_table (void)
+{
+ struct minimal_symbol *novlys_msym, *ovly_table_msym;
+
+ simple_free_overlay_table ();
+ novlys_msym = lookup_minimal_symbol ("_novlys", NULL, NULL);
+ if (! novlys_msym)
+ {
+ error ("Error reading inferior's overlay table: "
+ "couldn't find `_novlys' variable\n"
+ "in inferior. Use `overlay manual' mode.");
+ return 0;
+ }
+
+ ovly_table_msym = lookup_minimal_symbol ("_ovly_table", NULL, NULL);
+ if (! ovly_table_msym)
+ {
+ error ("Error reading inferior's overlay table: couldn't find "
+ "`_ovly_table' array\n"
+ "in inferior. Use `overlay manual' mode.");
+ return 0;
+ }
+
+ cache_novlys = read_memory_integer (SYMBOL_VALUE_ADDRESS (novlys_msym), 4);
+ cache_ovly_table
+ = (void *) xmalloc (cache_novlys * sizeof (*cache_ovly_table));
+ cache_ovly_table_base = SYMBOL_VALUE_ADDRESS (ovly_table_msym);
+ read_target_long_array (cache_ovly_table_base,
+ (int *) cache_ovly_table,
+ cache_novlys * 4);
+
+ return 1; /* SUCCESS */
+}
+
+#if 0
+/* Find and grab a copy of the target _ovly_region_table
+ (and _novly_regions, which is needed for the table's size) */
+static int
+simple_read_overlay_region_table (void)
+{
+ struct minimal_symbol *msym;
+
+ simple_free_overlay_region_table ();
+ msym = lookup_minimal_symbol ("_novly_regions", NULL, NULL);
+ if (msym != NULL)
+ cache_novly_regions = read_memory_integer (SYMBOL_VALUE_ADDRESS (msym), 4);
+ else
+ return 0; /* failure */
+ cache_ovly_region_table = (void *) xmalloc (cache_novly_regions * 12);
+ if (cache_ovly_region_table != NULL)
+ {
+ msym = lookup_minimal_symbol ("_ovly_region_table", NULL, NULL);
+ if (msym != NULL)
+ {
+ cache_ovly_region_table_base = SYMBOL_VALUE_ADDRESS (msym);
+ read_target_long_array (cache_ovly_region_table_base,
+ (int *) cache_ovly_region_table,
+ cache_novly_regions * 3);
+ }
+ else
+ return 0; /* failure */
+ }
+ else
+ return 0; /* failure */
+ return 1; /* SUCCESS */
+}
+#endif
+
+/* Function: simple_overlay_update_1
+ A helper function for simple_overlay_update. Assuming a cached copy
+ of _ovly_table exists, look through it to find an entry whose vma,
+ lma and size match those of OSECT. Re-read the entry and make sure
+ it still matches OSECT (else the table may no longer be valid).
+ Set OSECT's mapped state to match the entry. Return: 1 for
+ success, 0 for failure. */
+
+static int
+simple_overlay_update_1 (struct obj_section *osect)
+{
+ int i, size;
+ bfd *obfd = osect->objfile->obfd;
+ asection *bsect = osect->the_bfd_section;
+
+ size = bfd_get_section_size_before_reloc (osect->the_bfd_section);
+ for (i = 0; i < cache_novlys; i++)
+ if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect)
+ && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect)
+ /* && cache_ovly_table[i][SIZE] == size */ )
+ {
+ read_target_long_array (cache_ovly_table_base + i * TARGET_LONG_BYTES,
+ (int *) cache_ovly_table[i], 4);
+ if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect)
+ && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect)
+ /* && cache_ovly_table[i][SIZE] == size */ )
+ {
+ osect->ovly_mapped = cache_ovly_table[i][MAPPED];
+ return 1;
+ }
+ else /* Warning! Warning! Target's ovly table has changed! */
+ return 0;
+ }
+ return 0;
+}
+
+/* Function: simple_overlay_update
+ If OSECT is NULL, then update all sections' mapped state
+ (after re-reading the entire target _ovly_table).
+ If OSECT is non-NULL, then try to find a matching entry in the
+ cached ovly_table and update only OSECT's mapped state.
+ If a cached entry can't be found or the cache isn't valid, then
+ re-read the entire cache, and go ahead and update all sections. */
+
+static void
+simple_overlay_update (struct obj_section *osect)
+{
+ struct objfile *objfile;
+
+ /* Were we given an osect to look up? NULL means do all of them. */
+ if (osect)
+ /* Have we got a cached copy of the target's overlay table? */
+ if (cache_ovly_table != NULL)
+ /* Does its cached location match what's currently in the symtab? */
+ if (cache_ovly_table_base ==
+ SYMBOL_VALUE_ADDRESS (lookup_minimal_symbol ("_ovly_table", NULL, NULL)))
+ /* Then go ahead and try to look up this single section in the cache */
+ if (simple_overlay_update_1 (osect))
+ /* Found it! We're done. */
+ return;
+
+ /* Cached table no good: need to read the entire table anew.
+ Or else we want all the sections, in which case it's actually
+ more efficient to read the whole table in one block anyway. */
+
+ if (! simple_read_overlay_table ())
+ return;
+
+ /* Now may as well update all sections, even if only one was requested. */
+ ALL_OBJSECTIONS (objfile, osect)
+ if (section_is_overlay (osect->the_bfd_section))
+ {
+ int i, size;
+ bfd *obfd = osect->objfile->obfd;
+ asection *bsect = osect->the_bfd_section;
+
+ size = bfd_get_section_size_before_reloc (osect->the_bfd_section);
+ for (i = 0; i < cache_novlys; i++)
+ if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect)
+ && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect)
+ /* && cache_ovly_table[i][SIZE] == size */ )
+ { /* obj_section matches i'th entry in ovly_table */
+ osect->ovly_mapped = cache_ovly_table[i][MAPPED];
+ break; /* finished with inner for loop: break out */
+ }
+ }
+}
+
+
+void
+_initialize_symfile (void)
+{
+ struct cmd_list_element *c;
+
+ c = add_cmd ("symbol-file", class_files, symbol_file_command,
+ "Load symbol table from executable file FILE.\n\
+The `file' command can also load symbol tables, as well as setting the file\n\
+to execute.", &cmdlist);
+ set_cmd_completer (c, filename_completer);
+
+ c = add_cmd ("add-symbol-file", class_files, add_symbol_file_command,
+ "Usage: add-symbol-file FILE ADDR [-s <SECT> <SECT_ADDR> -s <SECT> <SECT_ADDR> ...]\n\
+Load the symbols from FILE, assuming FILE has been dynamically loaded.\n\
+ADDR is the starting address of the file's text.\n\
+The optional arguments are section-name section-address pairs and\n\
+should be specified if the data and bss segments are not contiguous\n\
+with the text. SECT is a section name to be loaded at SECT_ADDR.",
+ &cmdlist);
+ set_cmd_completer (c, filename_completer);
+
+ c = add_cmd ("add-shared-symbol-files", class_files,
+ add_shared_symbol_files_command,
+ "Load the symbols from shared objects in the dynamic linker's link map.",
+ &cmdlist);
+ c = add_alias_cmd ("assf", "add-shared-symbol-files", class_files, 1,
+ &cmdlist);
+
+ c = add_cmd ("load", class_files, load_command,
+ "Dynamically load FILE into the running program, and record its symbols\n\
+for access from GDB.", &cmdlist);
+ set_cmd_completer (c, filename_completer);
+
+ add_show_from_set
+ (add_set_cmd ("symbol-reloading", class_support, var_boolean,
+ (char *) &symbol_reloading,
+ "Set dynamic symbol table reloading multiple times in one run.",
+ &setlist),
+ &showlist);
+
+ add_prefix_cmd ("overlay", class_support, overlay_command,
+ "Commands for debugging overlays.", &overlaylist,
+ "overlay ", 0, &cmdlist);
+
+ add_com_alias ("ovly", "overlay", class_alias, 1);
+ add_com_alias ("ov", "overlay", class_alias, 1);
+
+ add_cmd ("map-overlay", class_support, map_overlay_command,
+ "Assert that an overlay section is mapped.", &overlaylist);
+
+ add_cmd ("unmap-overlay", class_support, unmap_overlay_command,
+ "Assert that an overlay section is unmapped.", &overlaylist);
+
+ add_cmd ("list-overlays", class_support, list_overlays_command,
+ "List mappings of overlay sections.", &overlaylist);
+
+ add_cmd ("manual", class_support, overlay_manual_command,
+ "Enable overlay debugging.", &overlaylist);
+ add_cmd ("off", class_support, overlay_off_command,
+ "Disable overlay debugging.", &overlaylist);
+ add_cmd ("auto", class_support, overlay_auto_command,
+ "Enable automatic overlay debugging.", &overlaylist);
+ add_cmd ("load-target", class_support, overlay_load_command,
+ "Read the overlay mapping state from the target.", &overlaylist);
+
+ /* Filename extension to source language lookup table: */
+ init_filename_language_table ();
+ c = add_set_cmd ("extension-language", class_files, var_string_noescape,
+ (char *) &ext_args,
+ "Set mapping between filename extension and source language.\n\
+Usage: set extension-language .foo bar",
+ &setlist);
+ set_cmd_cfunc (c, set_ext_lang_command);
+
+ add_info ("extensions", info_ext_lang_command,
+ "All filename extensions associated with a source language.");
+
+ add_show_from_set
+ (add_set_cmd ("download-write-size", class_obscure,
+ var_integer, (char *) &download_write_size,
+ "Set the write size used when downloading a program.\n"
+ "Only used when downloading a program onto a remote\n"
+ "target. Specify zero, or a negative value, to disable\n"
+ "blocked writes. The actual size of each transfer is also\n"
+ "limited by the size of the target packet and the memory\n"
+ "cache.\n",
+ &setlist),
+ &showlist);
+}
diff --git a/gdb/symfile.h b/gdb/symfile.h
new file mode 100644
index 00000000000..39eb3080f13
--- /dev/null
+++ b/gdb/symfile.h
@@ -0,0 +1,328 @@
+/* Definitions for reading symbol files into GDB.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001
+ 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. */
+
+#if !defined (SYMFILE_H)
+#define SYMFILE_H
+
+/* This file requires that you first include "bfd.h". */
+
+/* Partial symbols are stored in the psymbol_cache and pointers to them
+ are kept in a dynamically grown array that is obtained from malloc and
+ grown as necessary via realloc. Each objfile typically has two of these,
+ one for global symbols and one for static symbols. Although this adds
+ a level of indirection for storing or accessing the partial symbols,
+ it allows us to throw away duplicate psymbols and set all pointers
+ to the single saved instance. */
+
+struct psymbol_allocation_list
+ {
+
+ /* Pointer to beginning of dynamically allocated array of pointers to
+ partial symbols. The array is dynamically expanded as necessary to
+ accommodate more pointers. */
+
+ struct partial_symbol **list;
+
+ /* Pointer to next available slot in which to store a pointer to a partial
+ symbol. */
+
+ struct partial_symbol **next;
+
+ /* Number of allocated pointer slots in current dynamic array (not the
+ number of bytes of storage). The "next" pointer will always point
+ somewhere between list[0] and list[size], and when at list[size] the
+ array will be expanded on the next attempt to store a pointer. */
+
+ int size;
+ };
+
+/* Define an array of addresses to accommodate non-contiguous dynamic
+ loading of modules. This is for use when entering commands, so we
+ can keep track of the section names until we read the file and
+ can map them to bfd sections. This structure is also used by
+ solib.c to communicate the section addresses in shared objects to
+ symbol_file_add (). */
+
+#define MAX_SECTIONS 64
+struct section_addr_info
+{
+ /* Sections whose names are file format dependent. */
+ struct other_sections
+ {
+ CORE_ADDR addr;
+ char *name;
+ int sectindex;
+ } other[MAX_SECTIONS];
+};
+
+/* Structure to keep track of symbol reading functions for various
+ object file types. */
+
+struct sym_fns
+ {
+
+ /* BFD flavour that we handle, or (as a special kludge, see xcoffread.c,
+ (enum bfd_flavour)-1 for xcoff). */
+
+ enum bfd_flavour sym_flavour;
+
+ /* Initializes anything that is global to the entire symbol table. It is
+ called during symbol_file_add, when we begin debugging an entirely new
+ program. */
+
+ void (*sym_new_init) (struct objfile *);
+
+ /* Reads any initial information from a symbol file, and initializes the
+ struct sym_fns SF in preparation for sym_read(). It is called every
+ time we read a symbol file for any reason. */
+
+ void (*sym_init) (struct objfile *);
+
+ /* sym_read (objfile, mainline)
+ Reads a symbol file into a psymtab (or possibly a symtab).
+ OBJFILE is the objfile struct for the file we are reading.
+ MAINLINE is 1 if this is the
+ main symbol table being read, and 0 if a secondary
+ symbol file (e.g. shared library or dynamically loaded file)
+ is being read. */
+
+ void (*sym_read) (struct objfile *, int);
+
+ /* Called when we are finished with an objfile. Should do all cleanup
+ that is specific to the object file format for the particular objfile. */
+
+ void (*sym_finish) (struct objfile *);
+
+ /* This function produces a file-dependent section_offsets structure,
+ allocated in the objfile's storage, and based on the parameter.
+ The parameter is currently a CORE_ADDR (FIXME!) for backward compatibility
+ with the higher levels of GDB. It should probably be changed to
+ a string, where NULL means the default, and others are parsed in a file
+ dependent way. */
+
+ void (*sym_offsets) (struct objfile *, struct section_addr_info *);
+
+ /* Finds the next struct sym_fns. They are allocated and initialized
+ in whatever module implements the functions pointed to; an
+ initializer calls add_symtab_fns to add them to the global chain. */
+
+ struct sym_fns *next;
+
+ };
+
+/* The default version of sym_fns.sym_offsets for readers that don't
+ do anything special. */
+
+extern void
+default_symfile_offsets (struct objfile *objfile, struct section_addr_info *);
+
+
+extern void
+extend_psymbol_list (struct psymbol_allocation_list *, struct objfile *);
+
+/* Add any kind of symbol to a psymbol_allocation_list. */
+
+/* #include "demangle.h" */
+
+extern void
+add_psymbol_to_list (char *, int, namespace_enum, enum address_class,
+ struct psymbol_allocation_list *, long, CORE_ADDR,
+ enum language, struct objfile *);
+
+extern void
+add_psymbol_with_dem_name_to_list (char *, int, char *, int, namespace_enum,
+ enum address_class,
+ struct psymbol_allocation_list *,
+ long, CORE_ADDR,
+ enum language, struct objfile *);
+
+
+extern void init_psymbol_list (struct objfile *, int);
+
+extern void sort_pst_symbols (struct partial_symtab *);
+
+extern struct symtab *allocate_symtab (char *, struct objfile *);
+
+extern int free_named_symtabs (char *);
+
+extern void fill_in_vptr_fieldno (struct type *);
+
+extern void add_symtab_fns (struct sym_fns *);
+
+extern void init_entry_point_info (struct objfile *);
+
+extern void
+syms_from_objfile (struct objfile *, struct section_addr_info *, int, int);
+
+extern void new_symfile_objfile (struct objfile *, int, int);
+
+extern struct objfile *symbol_file_add (char *, int,
+ struct section_addr_info *, int, int);
+
+/* Build (allocate and populate) a section_addr_info struct from
+ an existing section table. */
+
+struct section_table;
+extern struct section_addr_info *
+build_section_addr_info_from_section_table (const struct section_table *start,
+ const struct section_table *end);
+
+/* Free all memory allocated by build_section_addr_info_from_section_table. */
+
+extern void
+free_section_addr_info (struct section_addr_info *);
+
+
+extern struct partial_symtab *start_psymtab_common (struct objfile *,
+ struct section_offsets *,
+ char *, CORE_ADDR,
+ struct partial_symbol **,
+ struct partial_symbol **);
+
+/* Sorting your symbols for fast lookup or alphabetical printing. */
+
+extern void sort_block_syms (struct block *);
+
+extern void sort_symtab_syms (struct symtab *);
+
+/* Make a copy of the string at PTR with SIZE characters in the symbol obstack
+ (and add a null character at the end in the copy).
+ Returns the address of the copy. */
+
+extern char *obsavestring (char *, int, struct obstack *);
+
+/* Concatenate strings S1, S2 and S3; return the new string.
+ Space is found in the symbol_obstack. */
+
+extern char *obconcat (struct obstack *obstackp, const char *, const char *,
+ const char *);
+
+ /* Variables */
+
+/* If non-zero, shared library symbols will be added automatically
+ when the inferior is created, new libraries are loaded, or when
+ attaching to the inferior. This is almost always what users will
+ want to have happen; but for very large programs, the startup time
+ will be excessive, and so if this is a problem, the user can clear
+ this flag and then add the shared library symbols as needed. Note
+ that there is a potential for confusion, since if the shared
+ library symbols are not loaded, commands like "info fun" will *not*
+ report all the functions that are actually present. */
+
+extern int auto_solib_add;
+
+/* For systems that support it, a threshold size in megabytes. If
+ automatically adding a new library's symbol table to those already
+ known to the debugger would cause the total shared library symbol
+ size to exceed this threshhold, then the shlib's symbols are not
+ added. The threshold is ignored if the user explicitly asks for a
+ shlib to be added, such as when using the "sharedlibrary"
+ command. */
+
+extern int auto_solib_limit;
+
+/* From symfile.c */
+
+extern CORE_ADDR entry_point_address (void);
+
+extern struct partial_symtab *allocate_psymtab (char *, struct objfile *);
+
+extern void discard_psymtab (struct partial_symtab *);
+
+extern void find_lowest_section (bfd *, asection *, PTR);
+
+extern bfd *symfile_bfd_open (char *);
+
+extern int get_section_index (struct objfile *, char *);
+
+/* Utility functions for overlay sections: */
+extern enum overlay_debugging_state {
+ ovly_off,
+ ovly_on,
+ ovly_auto
+} overlay_debugging;
+extern int overlay_cache_invalid;
+
+/* return the "mapped" overlay section containing the PC */
+extern asection *find_pc_mapped_section (CORE_ADDR);
+
+/* return any overlay section containing the PC (even in its LMA region) */
+extern asection *find_pc_overlay (CORE_ADDR);
+
+/* return true if the section is an overlay */
+extern int section_is_overlay (asection *);
+
+/* return true if the overlay section is currently "mapped" */
+extern int section_is_mapped (asection *);
+
+/* return true if pc belongs to section's VMA */
+extern CORE_ADDR pc_in_mapped_range (CORE_ADDR, asection *);
+
+/* return true if pc belongs to section's LMA */
+extern CORE_ADDR pc_in_unmapped_range (CORE_ADDR, asection *);
+
+/* map an address from a section's LMA to its VMA */
+extern CORE_ADDR overlay_mapped_address (CORE_ADDR, asection *);
+
+/* map an address from a section's VMA to its LMA */
+extern CORE_ADDR overlay_unmapped_address (CORE_ADDR, asection *);
+
+/* convert an address in an overlay section (force into VMA range) */
+extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, asection *);
+
+/* Load symbols from a file. */
+extern void symbol_file_add_main (char *args, int from_tty);
+
+/* Clear GDB symbol tables. */
+extern void symbol_file_clear (int from_tty);
+
+/* From dwarfread.c */
+
+extern void
+dwarf_build_psymtabs (struct objfile *, int, file_ptr, unsigned int,
+ file_ptr, unsigned int);
+
+/* From dwarf2read.c */
+
+extern int dwarf2_has_info (bfd * abfd);
+
+extern void dwarf2_build_psymtabs (struct objfile *, int);
+extern void dwarf2_build_frame_info (struct objfile *);
+
+/* From mdebugread.c */
+
+/* Hack to force structures to exist before use in parameter list. */
+struct ecoff_debug_hack
+ {
+ struct ecoff_debug_swap *a;
+ struct ecoff_debug_info *b;
+ };
+extern void
+mdebug_build_psymtabs (struct objfile *,
+ const struct ecoff_debug_swap *,
+ struct ecoff_debug_info *);
+
+extern void
+elfmdebug_build_psymtabs (struct objfile *,
+ const struct ecoff_debug_swap *, asection *);
+
+#endif /* !defined(SYMFILE_H) */
diff --git a/gdb/symm-nat.c b/gdb/symm-nat.c
new file mode 100644
index 00000000000..d6867774310
--- /dev/null
+++ b/gdb/symm-nat.c
@@ -0,0 +1,902 @@
+/* Sequent Symmetry host interface, for GDB when running under Unix.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1999, 2000,
+ 2001
+ 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. */
+
+/* FIXME, some 387-specific items of use taken from i387-tdep.c -- ought to be
+ merged back in. */
+
+#include "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "symtab.h"
+#include "target.h"
+#include "regcache.h"
+
+/* FIXME: What is the _INKERNEL define for? */
+#define _INKERNEL
+#include <signal.h>
+#undef _INKERNEL
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/dir.h>
+#include <sys/ioctl.h>
+#include "gdb_stat.h"
+#ifdef _SEQUENT_
+#include <sys/ptrace.h>
+#else
+/* Dynix has only machine/ptrace.h, which is already included by sys/user.h */
+/* Dynix has no mptrace call */
+#define mptrace ptrace
+#endif
+#include "gdbcore.h"
+#include <fcntl.h>
+#include <sgtty.h>
+#define TERMINAL struct sgttyb
+
+#include "gdbcore.h"
+
+void
+store_inferior_registers (int regno)
+{
+ struct pt_regset regs;
+ int i;
+
+ /* FIXME: Fetching the registers is a kludge to initialize all elements
+ in the fpu and fpa status. This works for normal debugging, but
+ might cause problems when calling functions in the inferior.
+ At least fpu_control and fpa_pcr (probably more) should be added
+ to the registers array to solve this properly. */
+ mptrace (XPT_RREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regs, 0);
+
+ regs.pr_eax = *(int *) &registers[REGISTER_BYTE (0)];
+ regs.pr_ebx = *(int *) &registers[REGISTER_BYTE (5)];
+ regs.pr_ecx = *(int *) &registers[REGISTER_BYTE (2)];
+ regs.pr_edx = *(int *) &registers[REGISTER_BYTE (1)];
+ regs.pr_esi = *(int *) &registers[REGISTER_BYTE (6)];
+ regs.pr_edi = *(int *) &registers[REGISTER_BYTE (7)];
+ regs.pr_esp = *(int *) &registers[REGISTER_BYTE (14)];
+ regs.pr_ebp = *(int *) &registers[REGISTER_BYTE (15)];
+ regs.pr_eip = *(int *) &registers[REGISTER_BYTE (16)];
+ regs.pr_flags = *(int *) &registers[REGISTER_BYTE (17)];
+ for (i = 0; i < 31; i++)
+ {
+ regs.pr_fpa.fpa_regs[i] =
+ *(int *) &registers[REGISTER_BYTE (FP1_REGNUM + i)];
+ }
+ memcpy (regs.pr_fpu.fpu_stack[0], &registers[REGISTER_BYTE (ST0_REGNUM)], 10);
+ memcpy (regs.pr_fpu.fpu_stack[1], &registers[REGISTER_BYTE (ST1_REGNUM)], 10);
+ memcpy (regs.pr_fpu.fpu_stack[2], &registers[REGISTER_BYTE (ST2_REGNUM)], 10);
+ memcpy (regs.pr_fpu.fpu_stack[3], &registers[REGISTER_BYTE (ST3_REGNUM)], 10);
+ memcpy (regs.pr_fpu.fpu_stack[4], &registers[REGISTER_BYTE (ST4_REGNUM)], 10);
+ memcpy (regs.pr_fpu.fpu_stack[5], &registers[REGISTER_BYTE (ST5_REGNUM)], 10);
+ memcpy (regs.pr_fpu.fpu_stack[6], &registers[REGISTER_BYTE (ST6_REGNUM)], 10);
+ memcpy (regs.pr_fpu.fpu_stack[7], &registers[REGISTER_BYTE (ST7_REGNUM)], 10);
+ mptrace (XPT_WREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regs, 0);
+}
+
+void
+fetch_inferior_registers (int regno)
+{
+ int i;
+ struct pt_regset regs;
+
+ registers_fetched ();
+
+ mptrace (XPT_RREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regs, 0);
+ *(int *) &registers[REGISTER_BYTE (EAX_REGNUM)] = regs.pr_eax;
+ *(int *) &registers[REGISTER_BYTE (EBX_REGNUM)] = regs.pr_ebx;
+ *(int *) &registers[REGISTER_BYTE (ECX_REGNUM)] = regs.pr_ecx;
+ *(int *) &registers[REGISTER_BYTE (EDX_REGNUM)] = regs.pr_edx;
+ *(int *) &registers[REGISTER_BYTE (ESI_REGNUM)] = regs.pr_esi;
+ *(int *) &registers[REGISTER_BYTE (EDI_REGNUM)] = regs.pr_edi;
+ *(int *) &registers[REGISTER_BYTE (EBP_REGNUM)] = regs.pr_ebp;
+ *(int *) &registers[REGISTER_BYTE (ESP_REGNUM)] = regs.pr_esp;
+ *(int *) &registers[REGISTER_BYTE (EIP_REGNUM)] = regs.pr_eip;
+ *(int *) &registers[REGISTER_BYTE (EFLAGS_REGNUM)] = regs.pr_flags;
+ for (i = 0; i < FPA_NREGS; i++)
+ {
+ *(int *) &registers[REGISTER_BYTE (FP1_REGNUM + i)] =
+ regs.pr_fpa.fpa_regs[i];
+ }
+ memcpy (&registers[REGISTER_BYTE (ST0_REGNUM)], regs.pr_fpu.fpu_stack[0], 10);
+ memcpy (&registers[REGISTER_BYTE (ST1_REGNUM)], regs.pr_fpu.fpu_stack[1], 10);
+ memcpy (&registers[REGISTER_BYTE (ST2_REGNUM)], regs.pr_fpu.fpu_stack[2], 10);
+ memcpy (&registers[REGISTER_BYTE (ST3_REGNUM)], regs.pr_fpu.fpu_stack[3], 10);
+ memcpy (&registers[REGISTER_BYTE (ST4_REGNUM)], regs.pr_fpu.fpu_stack[4], 10);
+ memcpy (&registers[REGISTER_BYTE (ST5_REGNUM)], regs.pr_fpu.fpu_stack[5], 10);
+ memcpy (&registers[REGISTER_BYTE (ST6_REGNUM)], regs.pr_fpu.fpu_stack[6], 10);
+ memcpy (&registers[REGISTER_BYTE (ST7_REGNUM)], regs.pr_fpu.fpu_stack[7], 10);
+}
+
+/* FIXME: This should be merged with i387-tdep.c as well. */
+static
+print_fpu_status (struct pt_regset ep)
+{
+ int i;
+ int bothstatus;
+ int top;
+ int fpreg;
+ unsigned char *p;
+
+ printf_unfiltered ("80387:");
+ if (ep.pr_fpu.fpu_ip == 0)
+ {
+ printf_unfiltered (" not in use.\n");
+ return;
+ }
+ else
+ {
+ printf_unfiltered ("\n");
+ }
+ if (ep.pr_fpu.fpu_status != 0)
+ {
+ print_387_status_word (ep.pr_fpu.fpu_status);
+ }
+ print_387_control_word (ep.pr_fpu.fpu_control);
+ printf_unfiltered ("last exception: ");
+ printf_unfiltered ("opcode 0x%x; ", ep.pr_fpu.fpu_rsvd4);
+ printf_unfiltered ("pc 0x%x:0x%x; ", ep.pr_fpu.fpu_cs, ep.pr_fpu.fpu_ip);
+ printf_unfiltered ("operand 0x%x:0x%x\n", ep.pr_fpu.fpu_data_offset, ep.pr_fpu.fpu_op_sel);
+
+ top = (ep.pr_fpu.fpu_status >> 11) & 7;
+
+ printf_unfiltered ("regno tag msb lsb value\n");
+ for (fpreg = 7; fpreg >= 0; fpreg--)
+ {
+ double val;
+
+ printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
+
+ switch ((ep.pr_fpu.fpu_tag >> (fpreg * 2)) & 3)
+ {
+ case 0:
+ printf_unfiltered ("valid ");
+ break;
+ case 1:
+ printf_unfiltered ("zero ");
+ break;
+ case 2:
+ printf_unfiltered ("trap ");
+ break;
+ case 3:
+ printf_unfiltered ("empty ");
+ break;
+ }
+ for (i = 9; i >= 0; i--)
+ printf_unfiltered ("%02x", ep.pr_fpu.fpu_stack[fpreg][i]);
+
+ i387_to_double ((char *) ep.pr_fpu.fpu_stack[fpreg], (char *) &val);
+ printf_unfiltered (" %g\n", val);
+ }
+ if (ep.pr_fpu.fpu_rsvd1)
+ warning ("rsvd1 is 0x%x\n", ep.pr_fpu.fpu_rsvd1);
+ if (ep.pr_fpu.fpu_rsvd2)
+ warning ("rsvd2 is 0x%x\n", ep.pr_fpu.fpu_rsvd2);
+ if (ep.pr_fpu.fpu_rsvd3)
+ warning ("rsvd3 is 0x%x\n", ep.pr_fpu.fpu_rsvd3);
+ if (ep.pr_fpu.fpu_rsvd5)
+ warning ("rsvd5 is 0x%x\n", ep.pr_fpu.fpu_rsvd5);
+}
+
+
+print_1167_control_word (unsigned int pcr)
+{
+ int pcr_tmp;
+
+ pcr_tmp = pcr & FPA_PCR_MODE;
+ printf_unfiltered ("\tMODE= %#x; RND= %#x ", pcr_tmp, pcr_tmp & 12);
+ switch (pcr_tmp & 12)
+ {
+ case 0:
+ printf_unfiltered ("RN (Nearest Value)");
+ break;
+ case 1:
+ printf_unfiltered ("RZ (Zero)");
+ break;
+ case 2:
+ printf_unfiltered ("RP (Positive Infinity)");
+ break;
+ case 3:
+ printf_unfiltered ("RM (Negative Infinity)");
+ break;
+ }
+ printf_unfiltered ("; IRND= %d ", pcr_tmp & 2);
+ if (0 == pcr_tmp & 2)
+ {
+ printf_unfiltered ("(same as RND)\n");
+ }
+ else
+ {
+ printf_unfiltered ("(toward zero)\n");
+ }
+ pcr_tmp = pcr & FPA_PCR_EM;
+ printf_unfiltered ("\tEM= %#x", pcr_tmp);
+ if (pcr_tmp & FPA_PCR_EM_DM)
+ printf_unfiltered (" DM");
+ if (pcr_tmp & FPA_PCR_EM_UOM)
+ printf_unfiltered (" UOM");
+ if (pcr_tmp & FPA_PCR_EM_PM)
+ printf_unfiltered (" PM");
+ if (pcr_tmp & FPA_PCR_EM_UM)
+ printf_unfiltered (" UM");
+ if (pcr_tmp & FPA_PCR_EM_OM)
+ printf_unfiltered (" OM");
+ if (pcr_tmp & FPA_PCR_EM_ZM)
+ printf_unfiltered (" ZM");
+ if (pcr_tmp & FPA_PCR_EM_IM)
+ printf_unfiltered (" IM");
+ printf_unfiltered ("\n");
+ pcr_tmp = FPA_PCR_CC;
+ printf_unfiltered ("\tCC= %#x", pcr_tmp);
+ if (pcr_tmp & FPA_PCR_20MHZ)
+ printf_unfiltered (" 20MHZ");
+ if (pcr_tmp & FPA_PCR_CC_Z)
+ printf_unfiltered (" Z");
+ if (pcr_tmp & FPA_PCR_CC_C2)
+ printf_unfiltered (" C2");
+
+ /* Dynix defines FPA_PCR_CC_C0 to 0x100 and ptx defines
+ FPA_PCR_CC_C1 to 0x100. Use whichever is defined and assume
+ the OS knows what it is doing. */
+#ifdef FPA_PCR_CC_C1
+ if (pcr_tmp & FPA_PCR_CC_C1)
+ printf_unfiltered (" C1");
+#else
+ if (pcr_tmp & FPA_PCR_CC_C0)
+ printf_unfiltered (" C0");
+#endif
+
+ switch (pcr_tmp)
+ {
+ case FPA_PCR_CC_Z:
+ printf_unfiltered (" (Equal)");
+ break;
+#ifdef FPA_PCR_CC_C1
+ case FPA_PCR_CC_C1:
+#else
+ case FPA_PCR_CC_C0:
+#endif
+ printf_unfiltered (" (Less than)");
+ break;
+ case 0:
+ printf_unfiltered (" (Greater than)");
+ break;
+ case FPA_PCR_CC_Z |
+#ifdef FPA_PCR_CC_C1
+ FPA_PCR_CC_C1
+#else
+ FPA_PCR_CC_C0
+#endif
+ | FPA_PCR_CC_C2:
+ printf_unfiltered (" (Unordered)");
+ break;
+ default:
+ printf_unfiltered (" (Undefined)");
+ break;
+ }
+ printf_unfiltered ("\n");
+ pcr_tmp = pcr & FPA_PCR_AE;
+ printf_unfiltered ("\tAE= %#x", pcr_tmp);
+ if (pcr_tmp & FPA_PCR_AE_DE)
+ printf_unfiltered (" DE");
+ if (pcr_tmp & FPA_PCR_AE_UOE)
+ printf_unfiltered (" UOE");
+ if (pcr_tmp & FPA_PCR_AE_PE)
+ printf_unfiltered (" PE");
+ if (pcr_tmp & FPA_PCR_AE_UE)
+ printf_unfiltered (" UE");
+ if (pcr_tmp & FPA_PCR_AE_OE)
+ printf_unfiltered (" OE");
+ if (pcr_tmp & FPA_PCR_AE_ZE)
+ printf_unfiltered (" ZE");
+ if (pcr_tmp & FPA_PCR_AE_EE)
+ printf_unfiltered (" EE");
+ if (pcr_tmp & FPA_PCR_AE_IE)
+ printf_unfiltered (" IE");
+ printf_unfiltered ("\n");
+}
+
+print_1167_regs (long regs[FPA_NREGS])
+{
+ int i;
+
+ union
+ {
+ double d;
+ long l[2];
+ }
+ xd;
+ union
+ {
+ float f;
+ long l;
+ }
+ xf;
+
+
+ for (i = 0; i < FPA_NREGS; i++)
+ {
+ xf.l = regs[i];
+ printf_unfiltered ("%%fp%d: raw= %#x, single= %f", i + 1, regs[i], xf.f);
+ if (!(i & 1))
+ {
+ printf_unfiltered ("\n");
+ }
+ else
+ {
+ xd.l[1] = regs[i];
+ xd.l[0] = regs[i + 1];
+ printf_unfiltered (", double= %f\n", xd.d);
+ }
+ }
+}
+
+print_fpa_status (struct pt_regset ep)
+{
+
+ printf_unfiltered ("WTL 1167:");
+ if (ep.pr_fpa.fpa_pcr != 0)
+ {
+ printf_unfiltered ("\n");
+ print_1167_control_word (ep.pr_fpa.fpa_pcr);
+ print_1167_regs (ep.pr_fpa.fpa_regs);
+ }
+ else
+ {
+ printf_unfiltered (" not in use.\n");
+ }
+}
+
+#if 0 /* disabled because it doesn't go through the target vector. */
+i386_float_info (void)
+{
+ char ubuf[UPAGES * NBPG];
+ struct pt_regset regset;
+
+ if (have_inferior_p ())
+ {
+ PTRACE_READ_REGS (PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & regset);
+ }
+ else
+ {
+ int corechan = bfd_cache_lookup (core_bfd);
+ if (lseek (corechan, 0, 0) < 0)
+ {
+ perror ("seek on core file");
+ }
+ if (myread (corechan, ubuf, UPAGES * NBPG) < 0)
+ {
+ perror ("read on core file");
+ }
+ /* only interested in the floating point registers */
+ regset.pr_fpu = ((struct user *) ubuf)->u_fpusave;
+ regset.pr_fpa = ((struct user *) ubuf)->u_fpasave;
+ }
+ print_fpu_status (regset);
+ print_fpa_status (regset);
+}
+#endif
+
+static volatile int got_sigchld;
+
+/*ARGSUSED */
+/* This will eventually be more interesting. */
+void
+sigchld_handler (int signo)
+{
+ got_sigchld++;
+}
+
+/*
+ * Signals for which the default action does not cause the process
+ * to die. See <sys/signal.h> for where this came from (alas, we
+ * can't use those macros directly)
+ */
+#ifndef sigmask
+#define sigmask(s) (1 << ((s) - 1))
+#endif
+#define SIGNALS_DFL_SAFE sigmask(SIGSTOP) | sigmask(SIGTSTP) | \
+ sigmask(SIGTTIN) | sigmask(SIGTTOU) | sigmask(SIGCHLD) | \
+ sigmask(SIGCONT) | sigmask(SIGWINCH) | sigmask(SIGPWR) | \
+ sigmask(SIGURG) | sigmask(SIGPOLL)
+
+#ifdef ATTACH_DETACH
+/*
+ * Thanks to XPT_MPDEBUGGER, we have to mange child_wait().
+ */
+ptid_t
+child_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ int save_errno, rv, xvaloff, saoff, sa_hand;
+ struct pt_stop pt;
+ struct user u;
+ sigset_t set;
+ /* Host signal number for a signal which the inferior terminates with, or
+ 0 if it hasn't terminated due to a signal. */
+ static int death_by_signal = 0;
+#ifdef SVR4_SHARED_LIBS /* use this to distinguish ptx 2 vs ptx 4 */
+ prstatus_t pstatus;
+#endif
+ int pid = PIDGET (ptid);
+
+ do
+ {
+ set_sigint_trap (); /* Causes SIGINT to be passed on to the
+ attached process. */
+ save_errno = errno;
+
+ got_sigchld = 0;
+
+ sigemptyset (&set);
+
+ while (got_sigchld == 0)
+ {
+ sigsuspend (&set);
+ }
+
+ clear_sigint_trap ();
+
+ rv = mptrace (XPT_STOPSTAT, 0, (char *) &pt, 0);
+ if (-1 == rv)
+ {
+ printf ("XPT_STOPSTAT: errno %d\n", errno); /* DEBUG */
+ continue;
+ }
+
+ pid = pt.ps_pid;
+
+ if (pid != PIDGET (inferior_ptid))
+ {
+ /* NOTE: the mystery fork in csh/tcsh needs to be ignored.
+ * We should not return new children for the initial run
+ * of a process until it has done the exec.
+ */
+ /* inferior probably forked; send it on its way */
+ rv = mptrace (XPT_UNDEBUG, pid, 0, 0);
+ if (-1 == rv)
+ {
+ printf ("child_wait: XPT_UNDEBUG: pid %d: %s\n", pid,
+ safe_strerror (errno));
+ }
+ continue;
+ }
+ /* FIXME: Do we deal with fork notification correctly? */
+ switch (pt.ps_reason)
+ {
+ case PTS_FORK:
+ /* multi proc: treat like PTS_EXEC */
+ /*
+ * Pretend this didn't happen, since gdb isn't set up
+ * to deal with stops on fork.
+ */
+ rv = ptrace (PT_CONTSIG, pid, 1, 0);
+ if (-1 == rv)
+ {
+ printf ("PTS_FORK: PT_CONTSIG: error %d\n", errno);
+ }
+ continue;
+ case PTS_EXEC:
+ /*
+ * Pretend this is a SIGTRAP.
+ */
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ break;
+ case PTS_EXIT:
+ /*
+ * Note: we stop before the exit actually occurs. Extract
+ * the exit code from the uarea. If we're stopped in the
+ * exit() system call, the exit code will be in
+ * u.u_ap[0]. An exit due to an uncaught signal will have
+ * something else in here, see the comment in the default:
+ * case, below. Finally,let the process exit.
+ */
+ if (death_by_signal)
+ {
+ status->kind = TARGET_WAITKIND_SIGNALED;
+ status->value.sig = target_signal_from_host (death_by_signal);
+ death_by_signal = 0;
+ break;
+ }
+ xvaloff = (unsigned long) &u.u_ap[0] - (unsigned long) &u;
+ errno = 0;
+ rv = ptrace (PT_RUSER, pid, (char *) xvaloff, 0);
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = rv;
+ /*
+ * addr & data to mptrace() don't matter here, since
+ * the process is already dead.
+ */
+ rv = mptrace (XPT_UNDEBUG, pid, 0, 0);
+ if (-1 == rv)
+ {
+ printf ("child_wait: PTS_EXIT: XPT_UNDEBUG: pid %d error %d\n", pid,
+ errno);
+ }
+ break;
+ case PTS_WATCHPT_HIT:
+ internal_error (__FILE__, __LINE__,
+ "PTS_WATCHPT_HIT\n");
+ break;
+ default:
+ /* stopped by signal */
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = target_signal_from_host (pt.ps_reason);
+ death_by_signal = 0;
+
+ if (0 == (SIGNALS_DFL_SAFE & sigmask (pt.ps_reason)))
+ {
+ break;
+ }
+ /* else default action of signal is to die */
+#ifdef SVR4_SHARED_LIBS
+ rv = ptrace (PT_GET_PRSTATUS, pid, (char *) &pstatus, 0);
+ if (-1 == rv)
+ error ("child_wait: signal %d PT_GET_PRSTATUS: %s\n",
+ pt.ps_reason, safe_strerror (errno));
+ if (pstatus.pr_cursig != pt.ps_reason)
+ {
+ printf ("pstatus signal %d, pt signal %d\n",
+ pstatus.pr_cursig, pt.ps_reason);
+ }
+ sa_hand = (int) pstatus.pr_action.sa_handler;
+#else
+ saoff = (unsigned long) &u.u_sa[0] - (unsigned long) &u;
+ saoff += sizeof (struct sigaction) * (pt.ps_reason - 1);
+ errno = 0;
+ sa_hand = ptrace (PT_RUSER, pid, (char *) saoff, 0);
+ if (errno)
+ error ("child_wait: signal %d: RUSER: %s\n",
+ pt.ps_reason, safe_strerror (errno));
+#endif
+ if ((int) SIG_DFL == sa_hand)
+ {
+ /* we will be dying */
+ death_by_signal = pt.ps_reason;
+ }
+ break;
+ }
+
+ }
+ while (pid != PIDGET (inferior_ptid)); /* Some other child died or stopped */
+
+ return pid_to_ptid (pid);
+}
+#else /* !ATTACH_DETACH */
+/*
+ * Simple child_wait() based on inftarg.c child_wait() for use until
+ * the MPDEBUGGER child_wait() works properly. This will go away when
+ * that is fixed.
+ */
+ptid_t
+child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+{
+ int save_errno;
+ int status;
+ int pid = PIDGET (ptid);
+
+ do
+ {
+ pid = wait (&status);
+ save_errno = errno;
+
+ if (pid == -1)
+ {
+ if (save_errno == EINTR)
+ continue;
+ fprintf (stderr, "Child process unexpectedly missing: %s.\n",
+ safe_strerror (save_errno));
+ ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
+ ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
+ return pid_to_ptid (-1);
+ }
+ }
+ while (pid != PIDGET (inferior_ptid)); /* Some other child died or stopped */
+ store_waitstatus (ourstatus, status);
+ return pid_to_ptid (pid);
+}
+#endif /* ATTACH_DETACH */
+
+
+
+/* This function simply calls ptrace with the given arguments.
+ It exists so that all calls to ptrace are isolated in this
+ machine-dependent file. */
+int
+call_ptrace (int request, int pid, PTRACE_ARG3_TYPE addr, int data)
+{
+ return ptrace (request, pid, addr, data);
+}
+
+int
+call_mptrace (int request, int pid, PTRACE_ARG3_TYPE addr, int data)
+{
+ return mptrace (request, pid, addr, data);
+}
+
+#if defined (DEBUG_PTRACE)
+/* For the rest of the file, use an extra level of indirection */
+/* This lets us breakpoint usefully on call_ptrace. */
+#define ptrace call_ptrace
+#define mptrace call_mptrace
+#endif
+
+void
+kill_inferior (void)
+{
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return;
+
+ /* For MPDEBUGGER, don't use PT_KILL, since the child will stop
+ again with a PTS_EXIT. Just hit him with SIGKILL (so he stops)
+ and detach. */
+
+ kill (PIDGET (inferior_ptid), SIGKILL);
+#ifdef ATTACH_DETACH
+ detach (SIGKILL);
+#else /* ATTACH_DETACH */
+ ptrace (PT_KILL, PIDGET (inferior_ptid), 0, 0);
+ wait ((int *) NULL);
+#endif /* ATTACH_DETACH */
+ target_mourn_inferior ();
+}
+
+/* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+void
+child_resume (ptid_t ptid, int step, enum target_signal signal)
+{
+ int pid = PIDGET (ptid);
+
+ errno = 0;
+
+ if (pid == -1)
+ pid = PIDGET (inferior_ptid);
+
+ /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where
+ it was. (If GDB wanted it to start some other way, we have already
+ written a new PC value to the child.)
+
+ If this system does not support PT_SSTEP, a higher level function will
+ have called single_step() to transmute the step request into a
+ continue request (by setting breakpoints on all possible successor
+ instructions), so we don't have to worry about that here. */
+
+ if (step)
+ ptrace (PT_SSTEP, pid, (PTRACE_ARG3_TYPE) 1, signal);
+ else
+ ptrace (PT_CONTSIG, pid, (PTRACE_ARG3_TYPE) 1, signal);
+
+ if (errno)
+ perror_with_name ("ptrace");
+}
+
+#ifdef ATTACH_DETACH
+/* Start debugging the process whose number is PID. */
+int
+attach (int pid)
+{
+ sigset_t set;
+ int rv;
+
+ rv = mptrace (XPT_DEBUG, pid, 0, 0);
+ if (-1 == rv)
+ {
+ error ("mptrace(XPT_DEBUG): %s", safe_strerror (errno));
+ }
+ rv = mptrace (XPT_SIGNAL, pid, 0, SIGSTOP);
+ if (-1 == rv)
+ {
+ error ("mptrace(XPT_SIGNAL): %s", safe_strerror (errno));
+ }
+ attach_flag = 1;
+ return pid;
+}
+
+void
+detach (int signo)
+{
+ int rv;
+
+ rv = mptrace (XPT_UNDEBUG, PIDGET (inferior_ptid), 1, signo);
+ if (-1 == rv)
+ {
+ error ("mptrace(XPT_UNDEBUG): %s", safe_strerror (errno));
+ }
+ attach_flag = 0;
+}
+
+#endif /* ATTACH_DETACH */
+
+/* Default the type of the ptrace transfer to int. */
+#ifndef PTRACE_XFER_TYPE
+#define PTRACE_XFER_TYPE int
+#endif
+
+
+/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
+ in the NEW_SUN_PTRACE case.
+ It ought to be straightforward. But it appears that writing did
+ not write the data that I specified. I cannot understand where
+ it got the data that it actually did write. */
+
+/* Copy LEN bytes to or from inferior's memory starting at MEMADDR
+ to debugger memory starting at MYADDR. Copy to inferior if
+ WRITE is nonzero. TARGET is ignored.
+
+ Returns the length copied, which is either the LEN argument or zero.
+ This xfer function does not do partial moves, since child_ops
+ doesn't allow memory operations to cross below us in the target stack
+ anyway. */
+
+int
+child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ register int i;
+ /* Round starting address down to longword boundary. */
+ register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
+ /* Round ending address up; get number of longwords that makes. */
+ register int count
+ = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
+ / sizeof (PTRACE_XFER_TYPE);
+ /* Allocate buffer of that many longwords. */
+ /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe
+ because it uses alloca to allocate a buffer of arbitrary size.
+ For very large xfers, this could crash GDB's stack. */
+ register PTRACE_XFER_TYPE *buffer
+ = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
+
+ if (write)
+ {
+ /* Fill start and end extra bytes of buffer with existing memory data. */
+
+ if (addr != memaddr || len < (int) sizeof (PTRACE_XFER_TYPE))
+ {
+ /* Need part of initial word -- fetch it. */
+ buffer[0] = ptrace (PT_RTEXT, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) addr,
+ 0);
+ }
+
+ if (count > 1) /* FIXME, avoid if even boundary */
+ {
+ buffer[count - 1]
+ = ptrace (PT_RTEXT, PIDGET (inferior_ptid),
+ ((PTRACE_ARG3_TYPE)
+ (addr + (count - 1) * sizeof (PTRACE_XFER_TYPE))),
+ 0);
+ }
+
+ /* Copy data to be written over corresponding part of buffer */
+
+ memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
+ myaddr,
+ len);
+
+ /* Write the entire buffer. */
+
+ for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ ptrace (PT_WDATA, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) addr,
+ buffer[i]);
+ if (errno)
+ {
+ /* Using the appropriate one (I or D) is necessary for
+ Gould NP1, at least. */
+ errno = 0;
+ ptrace (PT_WTEXT, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) addr,
+ buffer[i]);
+ }
+ if (errno)
+ return 0;
+ }
+ }
+ else
+ {
+ /* Read all the longwords */
+ for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
+ {
+ errno = 0;
+ buffer[i] = ptrace (PT_RTEXT, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) addr, 0);
+ if (errno)
+ return 0;
+ QUIT;
+ }
+
+ /* Copy appropriate bytes out of the buffer. */
+ memcpy (myaddr,
+ (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
+ len);
+ }
+ return len;
+}
+
+
+void
+_initialize_symm_nat (void)
+{
+#ifdef ATTACH_DETACH
+/*
+ * the MPDEBUGGER is necessary for process tree debugging and attach
+ * to work, but it alters the behavior of debugged processes, so other
+ * things (at least child_wait()) will have to change to accomodate
+ * that.
+ *
+ * Note that attach is not implemented in dynix 3, and not in ptx
+ * until version 2.1 of the OS.
+ */
+ int rv;
+ sigset_t set;
+ struct sigaction sact;
+
+ rv = mptrace (XPT_MPDEBUGGER, 0, 0, 0);
+ if (-1 == rv)
+ {
+ internal_error (__FILE__, __LINE__,
+ "_initialize_symm_nat(): mptrace(XPT_MPDEBUGGER): %s",
+ safe_strerror (errno));
+ }
+
+ /*
+ * Under MPDEBUGGER, we get SIGCLHD when a traced process does
+ * anything of interest.
+ */
+
+ /*
+ * Block SIGCHLD. We leave it blocked all the time, and then
+ * call sigsuspend() in child_wait() to wait for the child
+ * to do something. None of these ought to fail, but check anyway.
+ */
+ sigemptyset (&set);
+ rv = sigaddset (&set, SIGCHLD);
+ if (-1 == rv)
+ {
+ internal_error (__FILE__, __LINE__,
+ "_initialize_symm_nat(): sigaddset(SIGCHLD): %s",
+ safe_strerror (errno));
+ }
+ rv = sigprocmask (SIG_BLOCK, &set, (sigset_t *) NULL);
+ if (-1 == rv)
+ {
+ internal_error (__FILE__, __LINE__,
+ "_initialize_symm_nat(): sigprocmask(SIG_BLOCK): %s",
+ safe_strerror (errno));
+ }
+
+ sact.sa_handler = sigchld_handler;
+ sigemptyset (&sact.sa_mask);
+ sact.sa_flags = SA_NOCLDWAIT; /* keep the zombies away */
+ rv = sigaction (SIGCHLD, &sact, (struct sigaction *) NULL);
+ if (-1 == rv)
+ {
+ internal_error (__FILE__, __LINE__,
+ "_initialize_symm_nat(): sigaction(SIGCHLD): %s",
+ safe_strerror (errno));
+ }
+#endif
+}
diff --git a/gdb/symm-tdep.c b/gdb/symm-tdep.c
new file mode 100644
index 00000000000..37a2f511aa7
--- /dev/null
+++ b/gdb/symm-tdep.c
@@ -0,0 +1,102 @@
+/* Sequent Symmetry target interface, for GDB.
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 2000
+ 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. */
+
+/* many 387-specific items of use taken from i386-dep.c */
+
+#include "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "symtab.h"
+
+#include <signal.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/dir.h>
+#include <sys/ioctl.h>
+#include "gdb_stat.h"
+#include "gdbcore.h"
+#include <fcntl.h>
+
+void
+symmetry_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ union
+ {
+ double d;
+ int l[2];
+ }
+ xd;
+ struct minimal_symbol *msymbol;
+ float f;
+
+ if (TYPE_CODE_FLT == TYPE_CODE (type))
+ {
+ msymbol = lookup_minimal_symbol ("1167_flt", NULL, NULL);
+ if (msymbol != NULL)
+ {
+ /* found "1167_flt" means 1167, %fp2-%fp3 */
+ /* float & double; 19= %fp2, 20= %fp3 */
+ /* no single precision on 1167 */
+ xd.l[1] = *((int *) &regbuf[REGISTER_BYTE (19)]);
+ xd.l[0] = *((int *) &regbuf[REGISTER_BYTE (20)]);
+ switch (TYPE_LENGTH (type))
+ {
+ case 4:
+ /* FIXME: broken for cross-debugging. */
+ f = (float) xd.d;
+ memcpy (valbuf, &f, TYPE_LENGTH (type));
+ break;
+ case 8:
+ /* FIXME: broken for cross-debugging. */
+ memcpy (valbuf, &xd.d, TYPE_LENGTH (type));
+ break;
+ default:
+ error ("Unknown floating point size");
+ break;
+ }
+ }
+ else
+ {
+ /* 387 %st(0), gcc uses this */
+ i387_to_double (((int *) &regbuf[REGISTER_BYTE (3)]),
+ &xd.d);
+ switch (TYPE_LENGTH (type))
+ {
+ case 4: /* float */
+ f = (float) xd.d;
+ /* FIXME: broken for cross-debugging. */
+ memcpy (valbuf, &f, 4);
+ break;
+ case 8: /* double */
+ /* FIXME: broken for cross-debugging. */
+ memcpy (valbuf, &xd.d, 8);
+ break;
+ default:
+ error ("Unknown floating point size");
+ break;
+ }
+ }
+ }
+ else
+ {
+ memcpy (valbuf, regbuf, TYPE_LENGTH (type));
+ }
+}
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
new file mode 100644
index 00000000000..39b10a6a02c
--- /dev/null
+++ b/gdb/symmisc.c
@@ -0,0 +1,1073 @@
+/* Do various things to symbol tables (other than lookup), for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "breakpoint.h"
+#include "command.h"
+#include "obstack.h"
+#include "language.h"
+#include "bcache.h"
+
+#include "gdb_string.h"
+
+#ifndef DEV_TTY
+#define DEV_TTY "/dev/tty"
+#endif
+
+/* Unfortunately for debugging, stderr is usually a macro. This is painful
+ when calling functions that take FILE *'s from the debugger.
+ So we make a variable which has the same value and which is accessible when
+ debugging GDB with itself. Because stdin et al need not be constants,
+ we initialize them in the _initialize_symmisc function at the bottom
+ of the file. */
+FILE *std_in;
+FILE *std_out;
+FILE *std_err;
+
+/* Prototypes for local functions */
+
+static void dump_symtab (struct objfile *, struct symtab *,
+ struct ui_file *);
+
+static void dump_psymtab (struct objfile *, struct partial_symtab *,
+ struct ui_file *);
+
+static void dump_msymbols (struct objfile *, struct ui_file *);
+
+static void dump_objfile (struct objfile *);
+
+static int block_depth (struct block *);
+
+static void print_partial_symbols (struct partial_symbol **, int,
+ char *, struct ui_file *);
+
+static void free_symtab_block (struct objfile *, struct block *);
+
+void _initialize_symmisc (void);
+
+struct print_symbol_args
+ {
+ struct symbol *symbol;
+ int depth;
+ struct ui_file *outfile;
+ };
+
+static int print_symbol (PTR);
+
+static void free_symtab_block (struct objfile *, struct block *);
+
+
+/* Free a struct block <- B and all the symbols defined in that block. */
+
+static void
+free_symtab_block (struct objfile *objfile, struct block *b)
+{
+ register int i, n;
+ n = BLOCK_NSYMS (b);
+ for (i = 0; i < n; i++)
+ {
+ xmfree (objfile->md, SYMBOL_NAME (BLOCK_SYM (b, i)));
+ xmfree (objfile->md, (PTR) BLOCK_SYM (b, i));
+ }
+ xmfree (objfile->md, (PTR) b);
+}
+
+/* Free all the storage associated with the struct symtab <- S.
+ Note that some symtabs have contents malloc'ed structure by structure,
+ while some have contents that all live inside one big block of memory,
+ and some share the contents of another symbol table and so you should
+ not free the contents on their behalf (except sometimes the linetable,
+ which maybe per symtab even when the rest is not).
+ It is s->free_code that says which alternative to use. */
+
+void
+free_symtab (register struct symtab *s)
+{
+ register int i, n;
+ register struct blockvector *bv;
+
+ switch (s->free_code)
+ {
+ case free_nothing:
+ /* All the contents are part of a big block of memory (an obstack),
+ and some other symtab is in charge of freeing that block.
+ Therefore, do nothing. */
+ break;
+
+ case free_contents:
+ /* Here all the contents were malloc'ed structure by structure
+ and must be freed that way. */
+ /* First free the blocks (and their symbols. */
+ bv = BLOCKVECTOR (s);
+ n = BLOCKVECTOR_NBLOCKS (bv);
+ for (i = 0; i < n; i++)
+ free_symtab_block (s->objfile, BLOCKVECTOR_BLOCK (bv, i));
+ /* Free the blockvector itself. */
+ xmfree (s->objfile->md, (PTR) bv);
+ /* Also free the linetable. */
+
+ case free_linetable:
+ /* Everything will be freed either by our `free_ptr'
+ or by some other symtab, except for our linetable.
+ Free that now. */
+ if (LINETABLE (s))
+ xmfree (s->objfile->md, (PTR) LINETABLE (s));
+ break;
+ }
+
+ /* If there is a single block of memory to free, free it. */
+ if (s->free_ptr != NULL)
+ xmfree (s->objfile->md, s->free_ptr);
+
+ /* Free source-related stuff */
+ if (s->line_charpos != NULL)
+ xmfree (s->objfile->md, (PTR) s->line_charpos);
+ if (s->fullname != NULL)
+ xmfree (s->objfile->md, s->fullname);
+ if (s->debugformat != NULL)
+ xmfree (s->objfile->md, s->debugformat);
+ xmfree (s->objfile->md, (PTR) s);
+}
+
+void
+print_symbol_bcache_statistics (void)
+{
+ struct objfile *objfile;
+
+ immediate_quit++;
+ ALL_OBJFILES (objfile)
+ {
+ printf_filtered ("Byte cache statistics for '%s':\n", objfile->name);
+ print_bcache_statistics (&objfile->psymbol_cache, "partial symbol cache");
+ }
+ immediate_quit--;
+}
+
+void
+print_objfile_statistics (void)
+{
+ struct objfile *objfile;
+
+ immediate_quit++;
+ ALL_OBJFILES (objfile)
+ {
+ printf_filtered ("Statistics for '%s':\n", objfile->name);
+ if (OBJSTAT (objfile, n_stabs) > 0)
+ printf_filtered (" Number of \"stab\" symbols read: %d\n",
+ OBJSTAT (objfile, n_stabs));
+ if (OBJSTAT (objfile, n_minsyms) > 0)
+ printf_filtered (" Number of \"minimal\" symbols read: %d\n",
+ OBJSTAT (objfile, n_minsyms));
+ if (OBJSTAT (objfile, n_psyms) > 0)
+ printf_filtered (" Number of \"partial\" symbols read: %d\n",
+ OBJSTAT (objfile, n_psyms));
+ if (OBJSTAT (objfile, n_syms) > 0)
+ printf_filtered (" Number of \"full\" symbols read: %d\n",
+ OBJSTAT (objfile, n_syms));
+ if (OBJSTAT (objfile, n_types) > 0)
+ printf_filtered (" Number of \"types\" defined: %d\n",
+ OBJSTAT (objfile, n_types));
+ if (OBJSTAT (objfile, sz_strtab) > 0)
+ printf_filtered (" Space used by a.out string tables: %d\n",
+ OBJSTAT (objfile, sz_strtab));
+ printf_filtered (" Total memory used for psymbol obstack: %d\n",
+ obstack_memory_used (&objfile->psymbol_obstack));
+ printf_filtered (" Total memory used for psymbol cache: %d\n",
+ obstack_memory_used (&objfile->psymbol_cache.cache));
+ printf_filtered (" Total memory used for macro cache: %d\n",
+ obstack_memory_used (&objfile->macro_cache.cache));
+ printf_filtered (" Total memory used for symbol obstack: %d\n",
+ obstack_memory_used (&objfile->symbol_obstack));
+ printf_filtered (" Total memory used for type obstack: %d\n",
+ obstack_memory_used (&objfile->type_obstack));
+ }
+ immediate_quit--;
+}
+
+static void
+dump_objfile (struct objfile *objfile)
+{
+ struct symtab *symtab;
+ struct partial_symtab *psymtab;
+
+ printf_filtered ("\nObject file %s: ", objfile->name);
+ printf_filtered ("Objfile at ");
+ gdb_print_host_address (objfile, gdb_stdout);
+ printf_filtered (", bfd at ");
+ gdb_print_host_address (objfile->obfd, gdb_stdout);
+ printf_filtered (", %d minsyms\n\n",
+ objfile->minimal_symbol_count);
+
+ if (objfile->psymtabs)
+ {
+ printf_filtered ("Psymtabs:\n");
+ for (psymtab = objfile->psymtabs;
+ psymtab != NULL;
+ psymtab = psymtab->next)
+ {
+ printf_filtered ("%s at ",
+ psymtab->filename);
+ gdb_print_host_address (psymtab, gdb_stdout);
+ printf_filtered (", ");
+ if (psymtab->objfile != objfile)
+ {
+ printf_filtered ("NOT ON CHAIN! ");
+ }
+ wrap_here (" ");
+ }
+ printf_filtered ("\n\n");
+ }
+
+ if (objfile->symtabs)
+ {
+ printf_filtered ("Symtabs:\n");
+ for (symtab = objfile->symtabs;
+ symtab != NULL;
+ symtab = symtab->next)
+ {
+ printf_filtered ("%s at ", symtab->filename);
+ gdb_print_host_address (symtab, gdb_stdout);
+ printf_filtered (", ");
+ if (symtab->objfile != objfile)
+ {
+ printf_filtered ("NOT ON CHAIN! ");
+ }
+ wrap_here (" ");
+ }
+ printf_filtered ("\n\n");
+ }
+}
+
+/* Print minimal symbols from this objfile. */
+
+static void
+dump_msymbols (struct objfile *objfile, struct ui_file *outfile)
+{
+ struct minimal_symbol *msymbol;
+ int index;
+ char ms_type;
+
+ fprintf_filtered (outfile, "\nObject file %s:\n\n", objfile->name);
+ if (objfile->minimal_symbol_count == 0)
+ {
+ fprintf_filtered (outfile, "No minimal symbols found.\n");
+ return;
+ }
+ for (index = 0, msymbol = objfile->msymbols;
+ SYMBOL_NAME (msymbol) != NULL; msymbol++, index++)
+ {
+ switch (msymbol->type)
+ {
+ case mst_unknown:
+ ms_type = 'u';
+ break;
+ case mst_text:
+ ms_type = 'T';
+ break;
+ case mst_solib_trampoline:
+ ms_type = 'S';
+ break;
+ case mst_data:
+ ms_type = 'D';
+ break;
+ case mst_bss:
+ ms_type = 'B';
+ break;
+ case mst_abs:
+ ms_type = 'A';
+ break;
+ case mst_file_text:
+ ms_type = 't';
+ break;
+ case mst_file_data:
+ ms_type = 'd';
+ break;
+ case mst_file_bss:
+ ms_type = 'b';
+ break;
+ default:
+ ms_type = '?';
+ break;
+ }
+ fprintf_filtered (outfile, "[%2d] %c ", index, ms_type);
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (msymbol), 1, outfile);
+ fprintf_filtered (outfile, " %s", SYMBOL_NAME (msymbol));
+ if (SYMBOL_BFD_SECTION (msymbol))
+ fprintf_filtered (outfile, " section %s",
+ bfd_section_name (objfile->obfd,
+ SYMBOL_BFD_SECTION (msymbol)));
+ if (SYMBOL_DEMANGLED_NAME (msymbol) != NULL)
+ {
+ fprintf_filtered (outfile, " %s", SYMBOL_DEMANGLED_NAME (msymbol));
+ }
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ if (msymbol->filename)
+ fprintf_filtered (outfile, " %s", msymbol->filename);
+#endif
+ fputs_filtered ("\n", outfile);
+ }
+ if (objfile->minimal_symbol_count != index)
+ {
+ warning ("internal error: minimal symbol count %d != %d",
+ objfile->minimal_symbol_count, index);
+ }
+ fprintf_filtered (outfile, "\n");
+}
+
+static void
+dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
+ struct ui_file *outfile)
+{
+ int i;
+
+ fprintf_filtered (outfile, "\nPartial symtab for source file %s ",
+ psymtab->filename);
+ fprintf_filtered (outfile, "(object ");
+ gdb_print_host_address (psymtab, outfile);
+ fprintf_filtered (outfile, ")\n\n");
+ fprintf_unfiltered (outfile, " Read from object file %s (",
+ objfile->name);
+ gdb_print_host_address (objfile, outfile);
+ fprintf_unfiltered (outfile, ")\n");
+
+ if (psymtab->readin)
+ {
+ fprintf_filtered (outfile,
+ " Full symtab was read (at ");
+ gdb_print_host_address (psymtab->symtab, outfile);
+ fprintf_filtered (outfile, " by function at ");
+ gdb_print_host_address ((PTR) psymtab->read_symtab, outfile);
+ fprintf_filtered (outfile, ")\n");
+ }
+
+ fprintf_filtered (outfile, " Relocate symbols by ");
+ for (i = 0; i < psymtab->objfile->num_sections; ++i)
+ {
+ if (i != 0)
+ fprintf_filtered (outfile, ", ");
+ wrap_here (" ");
+ print_address_numeric (ANOFFSET (psymtab->section_offsets, i),
+ 1,
+ outfile);
+ }
+ fprintf_filtered (outfile, "\n");
+
+ fprintf_filtered (outfile, " Symbols cover text addresses ");
+ print_address_numeric (psymtab->textlow, 1, outfile);
+ fprintf_filtered (outfile, "-");
+ print_address_numeric (psymtab->texthigh, 1, outfile);
+ fprintf_filtered (outfile, "\n");
+ fprintf_filtered (outfile, " Depends on %d other partial symtabs.\n",
+ psymtab->number_of_dependencies);
+ for (i = 0; i < psymtab->number_of_dependencies; i++)
+ {
+ fprintf_filtered (outfile, " %d ", i);
+ gdb_print_host_address (psymtab->dependencies[i], outfile);
+ fprintf_filtered (outfile, " %s\n",
+ psymtab->dependencies[i]->filename);
+ }
+ if (psymtab->n_global_syms > 0)
+ {
+ print_partial_symbols (objfile->global_psymbols.list
+ + psymtab->globals_offset,
+ psymtab->n_global_syms, "Global", outfile);
+ }
+ if (psymtab->n_static_syms > 0)
+ {
+ print_partial_symbols (objfile->static_psymbols.list
+ + psymtab->statics_offset,
+ psymtab->n_static_syms, "Static", outfile);
+ }
+ fprintf_filtered (outfile, "\n");
+}
+
+static void
+dump_symtab (struct objfile *objfile, struct symtab *symtab,
+ struct ui_file *outfile)
+{
+ register int i, j;
+ int len, blen;
+ register struct linetable *l;
+ struct blockvector *bv;
+ struct symbol *sym;
+ register struct block *b;
+ int depth;
+
+ fprintf_filtered (outfile, "\nSymtab for file %s\n", symtab->filename);
+ if (symtab->dirname)
+ fprintf_filtered (outfile, "Compilation directory is %s\n",
+ symtab->dirname);
+ fprintf_filtered (outfile, "Read from object file %s (", objfile->name);
+ gdb_print_host_address (objfile, outfile);
+ fprintf_filtered (outfile, ")\n");
+ fprintf_filtered (outfile, "Language: %s\n", language_str (symtab->language));
+
+ /* First print the line table. */
+ l = LINETABLE (symtab);
+ if (l)
+ {
+ fprintf_filtered (outfile, "\nLine table:\n\n");
+ len = l->nitems;
+ for (i = 0; i < len; i++)
+ {
+ fprintf_filtered (outfile, " line %d at ", l->item[i].line);
+ print_address_numeric (l->item[i].pc, 1, outfile);
+ fprintf_filtered (outfile, "\n");
+ }
+ }
+ /* Now print the block info, but only for primary symtabs since we will
+ print lots of duplicate info otherwise. */
+ if (symtab->primary)
+ {
+ fprintf_filtered (outfile, "\nBlockvector:\n\n");
+ bv = BLOCKVECTOR (symtab);
+ len = BLOCKVECTOR_NBLOCKS (bv);
+ for (i = 0; i < len; i++)
+ {
+ b = BLOCKVECTOR_BLOCK (bv, i);
+ depth = block_depth (b) * 2;
+ print_spaces (depth, outfile);
+ fprintf_filtered (outfile, "block #%03d, object at ", i);
+ gdb_print_host_address (b, outfile);
+ if (BLOCK_SUPERBLOCK (b))
+ {
+ fprintf_filtered (outfile, " under ");
+ gdb_print_host_address (BLOCK_SUPERBLOCK (b), outfile);
+ }
+ blen = BLOCK_NSYMS (b);
+ fprintf_filtered (outfile, ", %d syms in ", blen);
+ print_address_numeric (BLOCK_START (b), 1, outfile);
+ fprintf_filtered (outfile, "..");
+ print_address_numeric (BLOCK_END (b), 1, outfile);
+ if (BLOCK_FUNCTION (b))
+ {
+ fprintf_filtered (outfile, ", function %s", SYMBOL_NAME (BLOCK_FUNCTION (b)));
+ if (SYMBOL_DEMANGLED_NAME (BLOCK_FUNCTION (b)) != NULL)
+ {
+ fprintf_filtered (outfile, ", %s",
+ SYMBOL_DEMANGLED_NAME (BLOCK_FUNCTION (b)));
+ }
+ }
+ if (BLOCK_GCC_COMPILED (b))
+ fprintf_filtered (outfile, ", compiled with gcc%d", BLOCK_GCC_COMPILED (b));
+ fprintf_filtered (outfile, "\n");
+ /* Now print each symbol in this block. */
+ /* FIXMED: Sort? */
+ ALL_BLOCK_SYMBOLS (b, j, sym)
+ {
+ struct print_symbol_args s;
+ s.symbol = sym;
+ s.depth = depth + 1;
+ s.outfile = outfile;
+ catch_errors (print_symbol, &s, "Error printing symbol:\n",
+ RETURN_MASK_ALL);
+ }
+ }
+ fprintf_filtered (outfile, "\n");
+ }
+ else
+ {
+ fprintf_filtered (outfile, "\nBlockvector same as previous symtab\n\n");
+ }
+}
+
+void
+maintenance_print_symbols (char *args, int from_tty)
+{
+ char **argv;
+ struct ui_file *outfile;
+ struct cleanup *cleanups;
+ char *symname = NULL;
+ char *filename = DEV_TTY;
+ struct objfile *objfile;
+ struct symtab *s;
+
+ dont_repeat ();
+
+ if (args == NULL)
+ {
+ error ("\
+Arguments missing: an output file name and an optional symbol file name");
+ }
+ else if ((argv = buildargv (args)) == NULL)
+ {
+ nomem (0);
+ }
+ cleanups = make_cleanup_freeargv (argv);
+
+ if (argv[0] != NULL)
+ {
+ filename = argv[0];
+ /* If a second arg is supplied, it is a source file name to match on */
+ if (argv[1] != NULL)
+ {
+ symname = argv[1];
+ }
+ }
+
+ filename = tilde_expand (filename);
+ make_cleanup (xfree, filename);
+
+ outfile = gdb_fopen (filename, FOPEN_WT);
+ if (outfile == 0)
+ perror_with_name (filename);
+ make_cleanup_ui_file_delete (outfile);
+
+ immediate_quit++;
+ ALL_SYMTABS (objfile, s)
+ if (symname == NULL || (STREQ (symname, s->filename)))
+ dump_symtab (objfile, s, outfile);
+ immediate_quit--;
+ do_cleanups (cleanups);
+}
+
+/* Print symbol ARGS->SYMBOL on ARGS->OUTFILE. ARGS->DEPTH says how
+ far to indent. ARGS is really a struct print_symbol_args *, but is
+ declared as char * to get it past catch_errors. Returns 0 for error,
+ 1 for success. */
+
+static int
+print_symbol (PTR args)
+{
+ struct symbol *symbol = ((struct print_symbol_args *) args)->symbol;
+ int depth = ((struct print_symbol_args *) args)->depth;
+ struct ui_file *outfile = ((struct print_symbol_args *) args)->outfile;
+
+ print_spaces (depth, outfile);
+ if (SYMBOL_NAMESPACE (symbol) == LABEL_NAMESPACE)
+ {
+ fprintf_filtered (outfile, "label %s at ", SYMBOL_SOURCE_NAME (symbol));
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1, outfile);
+ if (SYMBOL_BFD_SECTION (symbol))
+ fprintf_filtered (outfile, " section %s\n",
+ bfd_section_name (SYMBOL_BFD_SECTION (symbol)->owner,
+ SYMBOL_BFD_SECTION (symbol)));
+ else
+ fprintf_filtered (outfile, "\n");
+ return 1;
+ }
+ if (SYMBOL_NAMESPACE (symbol) == STRUCT_NAMESPACE)
+ {
+ if (TYPE_TAG_NAME (SYMBOL_TYPE (symbol)))
+ {
+ LA_PRINT_TYPE (SYMBOL_TYPE (symbol), "", outfile, 1, depth);
+ }
+ else
+ {
+ fprintf_filtered (outfile, "%s %s = ",
+ (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_ENUM
+ ? "enum"
+ : (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_STRUCT
+ ? "struct" : "union")),
+ SYMBOL_NAME (symbol));
+ LA_PRINT_TYPE (SYMBOL_TYPE (symbol), "", outfile, 1, depth);
+ }
+ fprintf_filtered (outfile, ";\n");
+ }
+ else
+ {
+ if (SYMBOL_CLASS (symbol) == LOC_TYPEDEF)
+ fprintf_filtered (outfile, "typedef ");
+ if (SYMBOL_TYPE (symbol))
+ {
+ /* Print details of types, except for enums where it's clutter. */
+ LA_PRINT_TYPE (SYMBOL_TYPE (symbol), SYMBOL_SOURCE_NAME (symbol),
+ outfile,
+ TYPE_CODE (SYMBOL_TYPE (symbol)) != TYPE_CODE_ENUM,
+ depth);
+ fprintf_filtered (outfile, "; ");
+ }
+ else
+ fprintf_filtered (outfile, "%s ", SYMBOL_SOURCE_NAME (symbol));
+
+ switch (SYMBOL_CLASS (symbol))
+ {
+ case LOC_CONST:
+ fprintf_filtered (outfile, "const %ld (0x%lx)",
+ SYMBOL_VALUE (symbol),
+ SYMBOL_VALUE (symbol));
+ break;
+
+ case LOC_CONST_BYTES:
+ {
+ unsigned i;
+ struct type *type = check_typedef (SYMBOL_TYPE (symbol));
+ fprintf_filtered (outfile, "const %u hex bytes:",
+ TYPE_LENGTH (type));
+ for (i = 0; i < TYPE_LENGTH (type); i++)
+ fprintf_filtered (outfile, " %02x",
+ (unsigned) SYMBOL_VALUE_BYTES (symbol)[i]);
+ }
+ break;
+
+ case LOC_STATIC:
+ fprintf_filtered (outfile, "static at ");
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1, outfile);
+ if (SYMBOL_BFD_SECTION (symbol))
+ fprintf_filtered (outfile, " section %s",
+ bfd_section_name
+ (SYMBOL_BFD_SECTION (symbol)->owner,
+ SYMBOL_BFD_SECTION (symbol)));
+ break;
+
+ case LOC_INDIRECT:
+ fprintf_filtered (outfile, "extern global at *(");
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1, outfile);
+ fprintf_filtered (outfile, "),");
+ break;
+
+ case LOC_REGISTER:
+ fprintf_filtered (outfile, "register %ld", SYMBOL_VALUE (symbol));
+ break;
+
+ case LOC_ARG:
+ fprintf_filtered (outfile, "arg at offset 0x%lx",
+ SYMBOL_VALUE (symbol));
+ break;
+
+ case LOC_LOCAL_ARG:
+ fprintf_filtered (outfile, "arg at offset 0x%lx from fp",
+ SYMBOL_VALUE (symbol));
+ break;
+
+ case LOC_REF_ARG:
+ fprintf_filtered (outfile, "reference arg at 0x%lx", SYMBOL_VALUE (symbol));
+ break;
+
+ case LOC_REGPARM:
+ fprintf_filtered (outfile, "parameter register %ld", SYMBOL_VALUE (symbol));
+ break;
+
+ case LOC_REGPARM_ADDR:
+ fprintf_filtered (outfile, "address parameter register %ld", SYMBOL_VALUE (symbol));
+ break;
+
+ case LOC_LOCAL:
+ fprintf_filtered (outfile, "local at offset 0x%lx",
+ SYMBOL_VALUE (symbol));
+ break;
+
+ case LOC_BASEREG:
+ fprintf_filtered (outfile, "local at 0x%lx from register %d",
+ SYMBOL_VALUE (symbol), SYMBOL_BASEREG (symbol));
+ break;
+
+ case LOC_BASEREG_ARG:
+ fprintf_filtered (outfile, "arg at 0x%lx from register %d",
+ SYMBOL_VALUE (symbol), SYMBOL_BASEREG (symbol));
+ break;
+
+ case LOC_TYPEDEF:
+ break;
+
+ case LOC_LABEL:
+ fprintf_filtered (outfile, "label at ");
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1, outfile);
+ if (SYMBOL_BFD_SECTION (symbol))
+ fprintf_filtered (outfile, " section %s",
+ bfd_section_name
+ (SYMBOL_BFD_SECTION (symbol)->owner,
+ SYMBOL_BFD_SECTION (symbol)));
+ break;
+
+ case LOC_BLOCK:
+ fprintf_filtered (outfile, "block object ");
+ gdb_print_host_address (SYMBOL_BLOCK_VALUE (symbol), outfile);
+ fprintf_filtered (outfile, ", ");
+ print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (symbol)),
+ 1,
+ outfile);
+ fprintf_filtered (outfile, "..");
+ print_address_numeric (BLOCK_END (SYMBOL_BLOCK_VALUE (symbol)),
+ 1,
+ outfile);
+ if (SYMBOL_BFD_SECTION (symbol))
+ fprintf_filtered (outfile, " section %s",
+ bfd_section_name
+ (SYMBOL_BFD_SECTION (symbol)->owner,
+ SYMBOL_BFD_SECTION (symbol)));
+ break;
+
+ case LOC_UNRESOLVED:
+ fprintf_filtered (outfile, "unresolved");
+ break;
+
+ case LOC_OPTIMIZED_OUT:
+ fprintf_filtered (outfile, "optimized out");
+ break;
+
+ default:
+ fprintf_filtered (outfile, "botched symbol class %x",
+ SYMBOL_CLASS (symbol));
+ break;
+ }
+ }
+ fprintf_filtered (outfile, "\n");
+ return 1;
+}
+
+void
+maintenance_print_psymbols (char *args, int from_tty)
+{
+ char **argv;
+ struct ui_file *outfile;
+ struct cleanup *cleanups;
+ char *symname = NULL;
+ char *filename = DEV_TTY;
+ struct objfile *objfile;
+ struct partial_symtab *ps;
+
+ dont_repeat ();
+
+ if (args == NULL)
+ {
+ error ("print-psymbols takes an output file name and optional symbol file name");
+ }
+ else if ((argv = buildargv (args)) == NULL)
+ {
+ nomem (0);
+ }
+ cleanups = make_cleanup_freeargv (argv);
+
+ if (argv[0] != NULL)
+ {
+ filename = argv[0];
+ /* If a second arg is supplied, it is a source file name to match on */
+ if (argv[1] != NULL)
+ {
+ symname = argv[1];
+ }
+ }
+
+ filename = tilde_expand (filename);
+ make_cleanup (xfree, filename);
+
+ outfile = gdb_fopen (filename, FOPEN_WT);
+ if (outfile == 0)
+ perror_with_name (filename);
+ make_cleanup_ui_file_delete (outfile);
+
+ immediate_quit++;
+ ALL_PSYMTABS (objfile, ps)
+ if (symname == NULL || (STREQ (symname, ps->filename)))
+ dump_psymtab (objfile, ps, outfile);
+ immediate_quit--;
+ do_cleanups (cleanups);
+}
+
+static void
+print_partial_symbols (struct partial_symbol **p, int count, char *what,
+ struct ui_file *outfile)
+{
+ fprintf_filtered (outfile, " %s partial symbols:\n", what);
+ while (count-- > 0)
+ {
+ fprintf_filtered (outfile, " `%s'", SYMBOL_NAME (*p));
+ if (SYMBOL_DEMANGLED_NAME (*p) != NULL)
+ {
+ fprintf_filtered (outfile, " `%s'", SYMBOL_DEMANGLED_NAME (*p));
+ }
+ fputs_filtered (", ", outfile);
+ switch (SYMBOL_NAMESPACE (*p))
+ {
+ case UNDEF_NAMESPACE:
+ fputs_filtered ("undefined namespace, ", outfile);
+ break;
+ case VAR_NAMESPACE:
+ /* This is the usual thing -- don't print it */
+ break;
+ case STRUCT_NAMESPACE:
+ fputs_filtered ("struct namespace, ", outfile);
+ break;
+ case LABEL_NAMESPACE:
+ fputs_filtered ("label namespace, ", outfile);
+ break;
+ default:
+ fputs_filtered ("<invalid namespace>, ", outfile);
+ break;
+ }
+ switch (SYMBOL_CLASS (*p))
+ {
+ case LOC_UNDEF:
+ fputs_filtered ("undefined", outfile);
+ break;
+ case LOC_CONST:
+ fputs_filtered ("constant int", outfile);
+ break;
+ case LOC_STATIC:
+ fputs_filtered ("static", outfile);
+ break;
+ case LOC_INDIRECT:
+ fputs_filtered ("extern global", outfile);
+ break;
+ case LOC_REGISTER:
+ fputs_filtered ("register", outfile);
+ break;
+ case LOC_ARG:
+ fputs_filtered ("pass by value", outfile);
+ break;
+ case LOC_REF_ARG:
+ fputs_filtered ("pass by reference", outfile);
+ break;
+ case LOC_REGPARM:
+ fputs_filtered ("register parameter", outfile);
+ break;
+ case LOC_REGPARM_ADDR:
+ fputs_filtered ("register address parameter", outfile);
+ break;
+ case LOC_LOCAL:
+ fputs_filtered ("stack parameter", outfile);
+ break;
+ case LOC_TYPEDEF:
+ fputs_filtered ("type", outfile);
+ break;
+ case LOC_LABEL:
+ fputs_filtered ("label", outfile);
+ break;
+ case LOC_BLOCK:
+ fputs_filtered ("function", outfile);
+ break;
+ case LOC_CONST_BYTES:
+ fputs_filtered ("constant bytes", outfile);
+ break;
+ case LOC_LOCAL_ARG:
+ fputs_filtered ("shuffled arg", outfile);
+ break;
+ case LOC_UNRESOLVED:
+ fputs_filtered ("unresolved", outfile);
+ break;
+ case LOC_OPTIMIZED_OUT:
+ fputs_filtered ("optimized out", outfile);
+ break;
+ default:
+ fputs_filtered ("<invalid location>", outfile);
+ break;
+ }
+ fputs_filtered (", ", outfile);
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (*p), 1, outfile);
+ fprintf_filtered (outfile, "\n");
+ p++;
+ }
+}
+
+void
+maintenance_print_msymbols (char *args, int from_tty)
+{
+ char **argv;
+ struct ui_file *outfile;
+ struct cleanup *cleanups;
+ char *filename = DEV_TTY;
+ char *symname = NULL;
+ struct objfile *objfile;
+
+ dont_repeat ();
+
+ if (args == NULL)
+ {
+ error ("print-msymbols takes an output file name and optional symbol file name");
+ }
+ else if ((argv = buildargv (args)) == NULL)
+ {
+ nomem (0);
+ }
+ cleanups = make_cleanup_freeargv (argv);
+
+ if (argv[0] != NULL)
+ {
+ filename = argv[0];
+ /* If a second arg is supplied, it is a source file name to match on */
+ if (argv[1] != NULL)
+ {
+ symname = argv[1];
+ }
+ }
+
+ filename = tilde_expand (filename);
+ make_cleanup (xfree, filename);
+
+ outfile = gdb_fopen (filename, FOPEN_WT);
+ if (outfile == 0)
+ perror_with_name (filename);
+ make_cleanup_ui_file_delete (outfile);
+
+ immediate_quit++;
+ ALL_OBJFILES (objfile)
+ if (symname == NULL || (STREQ (symname, objfile->name)))
+ dump_msymbols (objfile, outfile);
+ immediate_quit--;
+ fprintf_filtered (outfile, "\n\n");
+ do_cleanups (cleanups);
+}
+
+void
+maintenance_print_objfiles (char *ignore, int from_tty)
+{
+ struct objfile *objfile;
+
+ dont_repeat ();
+
+ immediate_quit++;
+ ALL_OBJFILES (objfile)
+ dump_objfile (objfile);
+ immediate_quit--;
+}
+
+/* Check consistency of psymtabs and symtabs. */
+
+void
+maintenance_check_symtabs (char *ignore, int from_tty)
+{
+ register struct symbol *sym;
+ register struct partial_symbol **psym;
+ register struct symtab *s = NULL;
+ register struct partial_symtab *ps;
+ struct blockvector *bv;
+ register struct objfile *objfile;
+ register struct block *b;
+ int length;
+
+ ALL_PSYMTABS (objfile, ps)
+ {
+ s = PSYMTAB_TO_SYMTAB (ps);
+ if (s == NULL)
+ continue;
+ bv = BLOCKVECTOR (s);
+ b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ psym = ps->objfile->static_psymbols.list + ps->statics_offset;
+ length = ps->n_static_syms;
+ while (length--)
+ {
+ sym = lookup_block_symbol (b, SYMBOL_NAME (*psym),
+ NULL, SYMBOL_NAMESPACE (*psym));
+ if (!sym)
+ {
+ printf_filtered ("Static symbol `");
+ puts_filtered (SYMBOL_NAME (*psym));
+ printf_filtered ("' only found in ");
+ puts_filtered (ps->filename);
+ printf_filtered (" psymtab\n");
+ }
+ psym++;
+ }
+ b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ psym = ps->objfile->global_psymbols.list + ps->globals_offset;
+ length = ps->n_global_syms;
+ while (length--)
+ {
+ sym = lookup_block_symbol (b, SYMBOL_NAME (*psym),
+ NULL, SYMBOL_NAMESPACE (*psym));
+ if (!sym)
+ {
+ printf_filtered ("Global symbol `");
+ puts_filtered (SYMBOL_NAME (*psym));
+ printf_filtered ("' only found in ");
+ puts_filtered (ps->filename);
+ printf_filtered (" psymtab\n");
+ }
+ psym++;
+ }
+ if (ps->texthigh < ps->textlow)
+ {
+ printf_filtered ("Psymtab ");
+ puts_filtered (ps->filename);
+ printf_filtered (" covers bad range ");
+ print_address_numeric (ps->textlow, 1, gdb_stdout);
+ printf_filtered (" - ");
+ print_address_numeric (ps->texthigh, 1, gdb_stdout);
+ printf_filtered ("\n");
+ continue;
+ }
+ if (ps->texthigh == 0)
+ continue;
+ if (ps->textlow < BLOCK_START (b) || ps->texthigh > BLOCK_END (b))
+ {
+ printf_filtered ("Psymtab ");
+ puts_filtered (ps->filename);
+ printf_filtered (" covers ");
+ print_address_numeric (ps->textlow, 1, gdb_stdout);
+ printf_filtered (" - ");
+ print_address_numeric (ps->texthigh, 1, gdb_stdout);
+ printf_filtered (" but symtab covers only ");
+ print_address_numeric (BLOCK_START (b), 1, gdb_stdout);
+ printf_filtered (" - ");
+ print_address_numeric (BLOCK_END (b), 1, gdb_stdout);
+ printf_filtered ("\n");
+ }
+ }
+}
+
+
+/* Return the nexting depth of a block within other blocks in its symtab. */
+
+static int
+block_depth (struct block *block)
+{
+ register int i = 0;
+ while ((block = BLOCK_SUPERBLOCK (block)) != NULL)
+ {
+ i++;
+ }
+ return i;
+}
+
+
+/* Increase the space allocated for LISTP, which is probably
+ global_psymbols or static_psymbols. This space will eventually
+ be freed in free_objfile(). */
+
+void
+extend_psymbol_list (register struct psymbol_allocation_list *listp,
+ struct objfile *objfile)
+{
+ int new_size;
+ if (listp->size == 0)
+ {
+ new_size = 255;
+ listp->list = (struct partial_symbol **)
+ xmmalloc (objfile->md, new_size * sizeof (struct partial_symbol *));
+ }
+ else
+ {
+ new_size = listp->size * 2;
+ listp->list = (struct partial_symbol **)
+ xmrealloc (objfile->md, (char *) listp->list,
+ new_size * sizeof (struct partial_symbol *));
+ }
+ /* Next assumes we only went one over. Should be good if
+ program works correctly */
+ listp->next = listp->list + listp->size;
+ listp->size = new_size;
+}
+
+
+/* Do early runtime initializations. */
+void
+_initialize_symmisc (void)
+{
+ std_in = stdin;
+ std_out = stdout;
+ std_err = stderr;
+}
diff --git a/gdb/symtab.c b/gdb/symtab.c
new file mode 100644
index 00000000000..3d687be09d1
--- /dev/null
+++ b/gdb/symtab.c
@@ -0,0 +1,3985 @@
+/* Symbol table lookup for the GNU debugger, GDB.
+
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "frame.h"
+#include "target.h"
+#include "value.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbcmd.h"
+#include "call-cmds.h"
+#include "gdb_regex.h"
+#include "expression.h"
+#include "language.h"
+#include "demangle.h"
+#include "inferior.h"
+#include "linespec.h"
+#include "filenames.h" /* for FILENAME_CMP */
+
+#include "obstack.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "gdb_string.h"
+#include "gdb_stat.h"
+#include <ctype.h>
+#include "cp-abi.h"
+
+/* Prototype for one function in parser-defs.h,
+ instead of including that entire file. */
+
+extern char *find_template_name_end (char *);
+
+/* Prototypes for local functions */
+
+static void completion_list_add_name (char *, char *, int, char *, char *);
+
+static void rbreak_command (char *, int);
+
+static void types_info (char *, int);
+
+static void functions_info (char *, int);
+
+static void variables_info (char *, int);
+
+static void sources_info (char *, int);
+
+static void output_source_filename (char *, int *);
+
+static int find_line_common (struct linetable *, int, int *);
+
+/* This one is used by linespec.c */
+
+char *operator_chars (char *p, char **end);
+
+static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *,
+ const char *, int,
+ namespace_enum);
+
+static struct symbol *lookup_symbol_aux (const char *name,
+ const char *mangled_name,
+ const struct block *block,
+ const namespace_enum namespace,
+ int *is_a_field_of_this,
+ struct symtab **symtab);
+
+
+static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr);
+
+/* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */
+/* Signals the presence of objects compiled by HP compilers */
+int hp_som_som_object_present = 0;
+
+static void fixup_section (struct general_symbol_info *, struct objfile *);
+
+static int file_matches (char *, char **, int);
+
+static void print_symbol_info (namespace_enum,
+ struct symtab *, struct symbol *, int, char *);
+
+static void print_msymbol_info (struct minimal_symbol *);
+
+static void symtab_symbol_info (char *, namespace_enum, int);
+
+static void overload_list_add_symbol (struct symbol *sym, char *oload_name);
+
+void _initialize_symtab (void);
+
+/* */
+
+/* The single non-language-specific builtin type */
+struct type *builtin_type_error;
+
+/* Block in which the most recently searched-for symbol was found.
+ Might be better to make this a parameter to lookup_symbol and
+ value_of_this. */
+
+const struct block *block_found;
+
+/* While the C++ support is still in flux, issue a possibly helpful hint on
+ using the new command completion feature on single quoted demangled C++
+ symbols. Remove when loose ends are cleaned up. FIXME -fnf */
+
+static void
+cplusplus_hint (char *name)
+{
+ while (*name == '\'')
+ name++;
+ printf_filtered ("Hint: try '%s<TAB> or '%s<ESC-?>\n", name, name);
+ printf_filtered ("(Note leading single quote.)\n");
+}
+
+/* Check for a symtab of a specific name; first in symtabs, then in
+ psymtabs. *If* there is no '/' in the name, a match after a '/'
+ in the symtab filename will also work. */
+
+struct symtab *
+lookup_symtab (const char *name)
+{
+ register struct symtab *s;
+ register struct partial_symtab *ps;
+ register struct objfile *objfile;
+ char *real_path = NULL;
+ char *full_path = NULL;
+
+ /* Here we are interested in canonicalizing an absolute path, not
+ absolutizing a relative path. */
+ if (IS_ABSOLUTE_PATH (name))
+ {
+ full_path = xfullpath (name);
+ make_cleanup (xfree, full_path);
+ real_path = gdb_realpath (name);
+ make_cleanup (xfree, real_path);
+ }
+
+got_symtab:
+
+ /* First, search for an exact match */
+
+ ALL_SYMTABS (objfile, s)
+ {
+ if (FILENAME_CMP (name, s->filename) == 0)
+ {
+ return s;
+ }
+
+ /* If the user gave us an absolute path, try to find the file in
+ this symtab and use its absolute path. */
+
+ if (full_path != NULL)
+ {
+ const char *fp = symtab_to_filename (s);
+ if (FILENAME_CMP (full_path, fp) == 0)
+ {
+ return s;
+ }
+ }
+
+ if (real_path != NULL)
+ {
+ char *rp = gdb_realpath (symtab_to_filename (s));
+ make_cleanup (xfree, rp);
+ if (FILENAME_CMP (real_path, rp) == 0)
+ {
+ return s;
+ }
+ }
+ }
+
+ /* Now, search for a matching tail (only if name doesn't have any dirs) */
+
+ if (lbasename (name) == name)
+ ALL_SYMTABS (objfile, s)
+ {
+ if (FILENAME_CMP (lbasename (s->filename), name) == 0)
+ return s;
+ }
+
+ /* Same search rules as above apply here, but now we look thru the
+ psymtabs. */
+
+ ps = lookup_partial_symtab (name);
+ if (!ps)
+ return (NULL);
+
+ if (ps->readin)
+ error ("Internal: readin %s pst for `%s' found when no symtab found.",
+ ps->filename, name);
+
+ s = PSYMTAB_TO_SYMTAB (ps);
+
+ if (s)
+ return s;
+
+ /* At this point, we have located the psymtab for this file, but
+ the conversion to a symtab has failed. This usually happens
+ when we are looking up an include file. In this case,
+ PSYMTAB_TO_SYMTAB doesn't return a symtab, even though one has
+ been created. So, we need to run through the symtabs again in
+ order to find the file.
+ XXX - This is a crock, and should be fixed inside of the the
+ symbol parsing routines. */
+ goto got_symtab;
+}
+
+/* Lookup the partial symbol table of a source file named NAME.
+ *If* there is no '/' in the name, a match after a '/'
+ in the psymtab filename will also work. */
+
+struct partial_symtab *
+lookup_partial_symtab (const char *name)
+{
+ register struct partial_symtab *pst;
+ register struct objfile *objfile;
+ char *full_path = NULL;
+ char *real_path = NULL;
+
+ /* Here we are interested in canonicalizing an absolute path, not
+ absolutizing a relative path. */
+ if (IS_ABSOLUTE_PATH (name))
+ {
+ full_path = xfullpath (name);
+ make_cleanup (xfree, full_path);
+ real_path = gdb_realpath (name);
+ make_cleanup (xfree, real_path);
+ }
+
+ ALL_PSYMTABS (objfile, pst)
+ {
+ if (FILENAME_CMP (name, pst->filename) == 0)
+ {
+ return (pst);
+ }
+
+ /* If the user gave us an absolute path, try to find the file in
+ this symtab and use its absolute path. */
+ if (full_path != NULL)
+ {
+ if (pst->fullname == NULL)
+ source_full_path_of (pst->filename, &pst->fullname);
+ if (pst->fullname != NULL
+ && FILENAME_CMP (full_path, pst->fullname) == 0)
+ {
+ return pst;
+ }
+ }
+
+ if (real_path != NULL)
+ {
+ char *rp = NULL;
+ if (pst->fullname == NULL)
+ source_full_path_of (pst->filename, &pst->fullname);
+ if (pst->fullname != NULL)
+ {
+ rp = gdb_realpath (pst->fullname);
+ make_cleanup (xfree, rp);
+ }
+ if (rp != NULL && FILENAME_CMP (real_path, rp) == 0)
+ {
+ return pst;
+ }
+ }
+ }
+
+ /* Now, search for a matching tail (only if name doesn't have any dirs) */
+
+ if (lbasename (name) == name)
+ ALL_PSYMTABS (objfile, pst)
+ {
+ if (FILENAME_CMP (lbasename (pst->filename), name) == 0)
+ return (pst);
+ }
+
+ return (NULL);
+}
+
+/* Mangle a GDB method stub type. This actually reassembles the pieces of the
+ full method name, which consist of the class name (from T), the unadorned
+ method name from METHOD_ID, and the signature for the specific overload,
+ specified by SIGNATURE_ID. Note that this function is g++ specific. */
+
+char *
+gdb_mangle_name (struct type *type, int method_id, int signature_id)
+{
+ int mangled_name_len;
+ char *mangled_name;
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (type, method_id);
+ struct fn_field *method = &f[signature_id];
+ char *field_name = TYPE_FN_FIELDLIST_NAME (type, method_id);
+ char *physname = TYPE_FN_FIELD_PHYSNAME (f, signature_id);
+ char *newname = type_name_no_tag (type);
+
+ /* Does the form of physname indicate that it is the full mangled name
+ of a constructor (not just the args)? */
+ int is_full_physname_constructor;
+
+ int is_constructor;
+ int is_destructor = is_destructor_name (physname);
+ /* Need a new type prefix. */
+ char *const_prefix = method->is_const ? "C" : "";
+ char *volatile_prefix = method->is_volatile ? "V" : "";
+ char buf[20];
+ int len = (newname == NULL ? 0 : strlen (newname));
+
+ /* Nothing to do if physname already contains a fully mangled v3 abi name
+ or an operator name. */
+ if ((physname[0] == '_' && physname[1] == 'Z')
+ || is_operator_name (field_name))
+ return xstrdup (physname);
+
+ is_full_physname_constructor = is_constructor_name (physname);
+
+ is_constructor =
+ is_full_physname_constructor || (newname && STREQ (field_name, newname));
+
+ if (!is_destructor)
+ is_destructor = (strncmp (physname, "__dt", 4) == 0);
+
+ if (is_destructor || is_full_physname_constructor)
+ {
+ mangled_name = (char *) xmalloc (strlen (physname) + 1);
+ strcpy (mangled_name, physname);
+ return mangled_name;
+ }
+
+ if (len == 0)
+ {
+ sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+ }
+ else if (physname[0] == 't' || physname[0] == 'Q')
+ {
+ /* The physname for template and qualified methods already includes
+ the class name. */
+ sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+ newname = NULL;
+ len = 0;
+ }
+ else
+ {
+ sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
+ }
+ mangled_name_len = ((is_constructor ? 0 : strlen (field_name))
+ + strlen (buf) + len + strlen (physname) + 1);
+
+ {
+ mangled_name = (char *) xmalloc (mangled_name_len);
+ if (is_constructor)
+ mangled_name[0] = '\0';
+ else
+ strcpy (mangled_name, field_name);
+ }
+ strcat (mangled_name, buf);
+ /* If the class doesn't have a name, i.e. newname NULL, then we just
+ mangle it using 0 for the length of the class. Thus it gets mangled
+ as something starting with `::' rather than `classname::'. */
+ if (newname != NULL)
+ strcat (mangled_name, newname);
+
+ strcat (mangled_name, physname);
+ return (mangled_name);
+}
+
+
+/* Initialize a symbol's mangled name. */
+
+/* Try to initialize the demangled name for a symbol, based on the
+ language of that symbol. If the language is set to language_auto,
+ it will attempt to find any demangling algorithm that works and
+ then set the language appropriately. If no demangling of any kind
+ is found, the language is set back to language_unknown, so we can
+ avoid doing this work again the next time we encounter the symbol.
+ Any required space to store the name is obtained from the specified
+ obstack. */
+
+void
+symbol_init_demangled_name (struct general_symbol_info *gsymbol,
+ struct obstack *obstack)
+{
+ char *mangled = gsymbol->name;
+ char *demangled = NULL;
+
+ if (gsymbol->language == language_unknown)
+ gsymbol->language = language_auto;
+ if (gsymbol->language == language_cplus
+ || gsymbol->language == language_auto)
+ {
+ demangled =
+ cplus_demangle (gsymbol->name, DMGL_PARAMS | DMGL_ANSI);
+ if (demangled != NULL)
+ {
+ gsymbol->language = language_cplus;
+ gsymbol->language_specific.cplus_specific.demangled_name =
+ obsavestring (demangled, strlen (demangled), obstack);
+ xfree (demangled);
+ }
+ else
+ {
+ gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+ }
+ }
+ if (gsymbol->language == language_java)
+ {
+ demangled =
+ cplus_demangle (gsymbol->name,
+ DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA);
+ if (demangled != NULL)
+ {
+ gsymbol->language = language_java;
+ gsymbol->language_specific.cplus_specific.demangled_name =
+ obsavestring (demangled, strlen (demangled), obstack);
+ xfree (demangled);
+ }
+ else
+ {
+ gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+ }
+ }
+ if (demangled == NULL
+ && (gsymbol->language == language_chill
+ || gsymbol->language == language_auto))
+ {
+ demangled =
+ chill_demangle (gsymbol->name);
+ if (demangled != NULL)
+ {
+ gsymbol->language = language_chill;
+ gsymbol->language_specific.chill_specific.demangled_name =
+ obsavestring (demangled, strlen (demangled), obstack);
+ xfree (demangled);
+ }
+ else
+ {
+ gsymbol->language_specific.chill_specific.demangled_name = NULL;
+ }
+ }
+}
+
+
+
+
+
+/* Find which partial symtab on contains PC and SECTION. Return 0 if none. */
+
+struct partial_symtab *
+find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
+{
+ register struct partial_symtab *pst;
+ register struct objfile *objfile;
+ struct minimal_symbol *msymbol;
+
+ /* If we know that this is not a text address, return failure. This is
+ necessary because we loop based on texthigh and textlow, which do
+ not include the data ranges. */
+ msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
+ if (msymbol
+ && (msymbol->type == mst_data
+ || msymbol->type == mst_bss
+ || msymbol->type == mst_abs
+ || msymbol->type == mst_file_data
+ || msymbol->type == mst_file_bss))
+ return NULL;
+
+ ALL_PSYMTABS (objfile, pst)
+ {
+ if (pc >= pst->textlow && pc < pst->texthigh)
+ {
+ struct partial_symtab *tpst;
+
+ /* An objfile that has its functions reordered might have
+ many partial symbol tables containing the PC, but
+ we want the partial symbol table that contains the
+ function containing the PC. */
+ if (!(objfile->flags & OBJF_REORDERED) &&
+ section == 0) /* can't validate section this way */
+ return (pst);
+
+ if (msymbol == NULL)
+ return (pst);
+
+ for (tpst = pst; tpst != NULL; tpst = tpst->next)
+ {
+ if (pc >= tpst->textlow && pc < tpst->texthigh)
+ {
+ struct partial_symbol *p;
+
+ p = find_pc_sect_psymbol (tpst, pc, section);
+ if (p != NULL
+ && SYMBOL_VALUE_ADDRESS (p)
+ == SYMBOL_VALUE_ADDRESS (msymbol))
+ return (tpst);
+ }
+ }
+ return (pst);
+ }
+ }
+ return (NULL);
+}
+
+/* Find which partial symtab contains PC. Return 0 if none.
+ Backward compatibility, no section */
+
+struct partial_symtab *
+find_pc_psymtab (CORE_ADDR pc)
+{
+ return find_pc_sect_psymtab (pc, find_pc_mapped_section (pc));
+}
+
+/* Find which partial symbol within a psymtab matches PC and SECTION.
+ Return 0 if none. Check all psymtabs if PSYMTAB is 0. */
+
+struct partial_symbol *
+find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
+ asection *section)
+{
+ struct partial_symbol *best = NULL, *p, **pp;
+ CORE_ADDR best_pc;
+
+ if (!psymtab)
+ psymtab = find_pc_sect_psymtab (pc, section);
+ if (!psymtab)
+ return 0;
+
+ /* Cope with programs that start at address 0 */
+ best_pc = (psymtab->textlow != 0) ? psymtab->textlow - 1 : 0;
+
+ /* Search the global symbols as well as the static symbols, so that
+ find_pc_partial_function doesn't use a minimal symbol and thus
+ cache a bad endaddr. */
+ for (pp = psymtab->objfile->global_psymbols.list + psymtab->globals_offset;
+ (pp - (psymtab->objfile->global_psymbols.list + psymtab->globals_offset)
+ < psymtab->n_global_syms);
+ pp++)
+ {
+ p = *pp;
+ if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
+ && SYMBOL_CLASS (p) == LOC_BLOCK
+ && pc >= SYMBOL_VALUE_ADDRESS (p)
+ && (SYMBOL_VALUE_ADDRESS (p) > best_pc
+ || (psymtab->textlow == 0
+ && best_pc == 0 && SYMBOL_VALUE_ADDRESS (p) == 0)))
+ {
+ if (section) /* match on a specific section */
+ {
+ fixup_psymbol_section (p, psymtab->objfile);
+ if (SYMBOL_BFD_SECTION (p) != section)
+ continue;
+ }
+ best_pc = SYMBOL_VALUE_ADDRESS (p);
+ best = p;
+ }
+ }
+
+ for (pp = psymtab->objfile->static_psymbols.list + psymtab->statics_offset;
+ (pp - (psymtab->objfile->static_psymbols.list + psymtab->statics_offset)
+ < psymtab->n_static_syms);
+ pp++)
+ {
+ p = *pp;
+ if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
+ && SYMBOL_CLASS (p) == LOC_BLOCK
+ && pc >= SYMBOL_VALUE_ADDRESS (p)
+ && (SYMBOL_VALUE_ADDRESS (p) > best_pc
+ || (psymtab->textlow == 0
+ && best_pc == 0 && SYMBOL_VALUE_ADDRESS (p) == 0)))
+ {
+ if (section) /* match on a specific section */
+ {
+ fixup_psymbol_section (p, psymtab->objfile);
+ if (SYMBOL_BFD_SECTION (p) != section)
+ continue;
+ }
+ best_pc = SYMBOL_VALUE_ADDRESS (p);
+ best = p;
+ }
+ }
+
+ return best;
+}
+
+/* Find which partial symbol within a psymtab matches PC. Return 0 if none.
+ Check all psymtabs if PSYMTAB is 0. Backwards compatibility, no section. */
+
+struct partial_symbol *
+find_pc_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc)
+{
+ return find_pc_sect_psymbol (psymtab, pc, find_pc_mapped_section (pc));
+}
+
+/* Debug symbols usually don't have section information. We need to dig that
+ out of the minimal symbols and stash that in the debug symbol. */
+
+static void
+fixup_section (struct general_symbol_info *ginfo, struct objfile *objfile)
+{
+ struct minimal_symbol *msym;
+ msym = lookup_minimal_symbol (ginfo->name, NULL, objfile);
+
+ if (msym)
+ {
+ ginfo->bfd_section = SYMBOL_BFD_SECTION (msym);
+ ginfo->section = SYMBOL_SECTION (msym);
+ }
+}
+
+struct symbol *
+fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
+{
+ if (!sym)
+ return NULL;
+
+ if (SYMBOL_BFD_SECTION (sym))
+ return sym;
+
+ fixup_section (&sym->ginfo, objfile);
+
+ return sym;
+}
+
+struct partial_symbol *
+fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
+{
+ if (!psym)
+ return NULL;
+
+ if (SYMBOL_BFD_SECTION (psym))
+ return psym;
+
+ fixup_section (&psym->ginfo, objfile);
+
+ return psym;
+}
+
+/* Find the definition for a specified symbol name NAME
+ in namespace NAMESPACE, visible from lexical block BLOCK.
+ Returns the struct symbol pointer, or zero if no symbol is found.
+ If SYMTAB is non-NULL, store the symbol table in which the
+ symbol was found there, or NULL if not found.
+ C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if
+ NAME is a field of the current implied argument `this'. If so set
+ *IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
+ BLOCK_FOUND is set to the block in which NAME is found (in the case of
+ a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
+
+/* This function has a bunch of loops in it and it would seem to be
+ attractive to put in some QUIT's (though I'm not really sure
+ whether it can run long enough to be really important). But there
+ are a few calls for which it would appear to be bad news to quit
+ out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c, and
+ nindy_frame_chain_valid in nindy-tdep.c. (Note that there is C++
+ code below which can error(), but that probably doesn't affect
+ these calls since they are looking for a known variable and thus
+ can probably assume it will never hit the C++ code). */
+
+struct symbol *
+lookup_symbol (const char *name, const struct block *block,
+ const namespace_enum namespace, int *is_a_field_of_this,
+ struct symtab **symtab)
+{
+ char *modified_name = NULL;
+ char *modified_name2 = NULL;
+ const char *mangled_name = NULL;
+ int needtofreename = 0;
+ struct symbol *returnval;
+
+ if (case_sensitivity == case_sensitive_off)
+ {
+ char *copy;
+ int len, i;
+
+ len = strlen (name);
+ copy = (char *) alloca (len + 1);
+ for (i= 0; i < len; i++)
+ copy[i] = tolower (name[i]);
+ copy[len] = 0;
+ modified_name = copy;
+ }
+ else
+ modified_name = (char *) name;
+
+ /* If we are using C++ language, demangle the name before doing a lookup, so
+ we can always binary search. */
+ if (current_language->la_language == language_cplus)
+ {
+ modified_name2 = cplus_demangle (modified_name, DMGL_ANSI | DMGL_PARAMS);
+ if (modified_name2)
+ {
+ mangled_name = name;
+ modified_name = modified_name2;
+ needtofreename = 1;
+ }
+ }
+
+ returnval = lookup_symbol_aux (modified_name, mangled_name, block,
+ namespace, is_a_field_of_this, symtab);
+ if (needtofreename)
+ xfree (modified_name2);
+
+ return returnval;
+}
+
+static struct symbol *
+lookup_symbol_aux (const char *name, const char *mangled_name,
+ const struct block *block, const namespace_enum namespace,
+ int *is_a_field_of_this, struct symtab **symtab)
+{
+ register struct symbol *sym;
+ register struct symtab *s = NULL;
+ register struct partial_symtab *ps;
+ register struct blockvector *bv;
+ register struct objfile *objfile = NULL;
+ register struct block *b;
+ register struct minimal_symbol *msymbol;
+
+
+ /* Search specified block and its superiors. */
+
+ while (block != 0)
+ {
+ sym = lookup_block_symbol (block, name, mangled_name, namespace);
+ if (sym)
+ {
+ block_found = block;
+ if (symtab != NULL)
+ {
+ /* Search the list of symtabs for one which contains the
+ address of the start of this block. */
+ ALL_SYMTABS (objfile, s)
+ {
+ bv = BLOCKVECTOR (s);
+ b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ if (BLOCK_START (b) <= BLOCK_START (block)
+ && BLOCK_END (b) > BLOCK_START (block))
+ goto found;
+ }
+ found:
+ *symtab = s;
+ }
+
+ return fixup_symbol_section (sym, objfile);
+ }
+ block = BLOCK_SUPERBLOCK (block);
+ }
+
+ /* FIXME: this code is never executed--block is always NULL at this
+ point. What is it trying to do, anyway? We already should have
+ checked the STATIC_BLOCK above (it is the superblock of top-level
+ blocks). Why is VAR_NAMESPACE special-cased? */
+ /* Don't need to mess with the psymtabs; if we have a block,
+ that file is read in. If we don't, then we deal later with
+ all the psymtab stuff that needs checking. */
+ /* Note (RT): The following never-executed code looks unnecessary to me also.
+ * If we change the code to use the original (passed-in)
+ * value of 'block', we could cause it to execute, but then what
+ * would it do? The STATIC_BLOCK of the symtab containing the passed-in
+ * 'block' was already searched by the above code. And the STATIC_BLOCK's
+ * of *other* symtabs (those files not containing 'block' lexically)
+ * should not contain 'block' address-wise. So we wouldn't expect this
+ * code to find any 'sym''s that were not found above. I vote for
+ * deleting the following paragraph of code.
+ */
+ if (namespace == VAR_NAMESPACE && block != NULL)
+ {
+ struct block *b;
+ /* Find the right symtab. */
+ ALL_SYMTABS (objfile, s)
+ {
+ bv = BLOCKVECTOR (s);
+ b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ if (BLOCK_START (b) <= BLOCK_START (block)
+ && BLOCK_END (b) > BLOCK_START (block))
+ {
+ sym = lookup_block_symbol (b, name, mangled_name, VAR_NAMESPACE);
+ if (sym)
+ {
+ block_found = b;
+ if (symtab != NULL)
+ *symtab = s;
+ return fixup_symbol_section (sym, objfile);
+ }
+ }
+ }
+ }
+
+
+ /* C++: If requested to do so by the caller,
+ check to see if NAME is a field of `this'. */
+ if (is_a_field_of_this)
+ {
+ struct value *v = value_of_this (0);
+
+ *is_a_field_of_this = 0;
+ if (v && check_field (v, name))
+ {
+ *is_a_field_of_this = 1;
+ if (symtab != NULL)
+ *symtab = NULL;
+ return NULL;
+ }
+ }
+
+ /* Now search all global blocks. Do the symtab's first, then
+ check the psymtab's. If a psymtab indicates the existence
+ of the desired name as a global, then do psymtab-to-symtab
+ conversion on the fly and return the found symbol. */
+
+ ALL_SYMTABS (objfile, s)
+ {
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, mangled_name, namespace);
+ if (sym)
+ {
+ block_found = block;
+ if (symtab != NULL)
+ *symtab = s;
+ return fixup_symbol_section (sym, objfile);
+ }
+ }
+
+#ifndef HPUXHPPA
+
+ /* Check for the possibility of the symbol being a function or
+ a mangled variable that is stored in one of the minimal symbol tables.
+ Eventually, all global symbols might be resolved in this way. */
+
+ if (namespace == VAR_NAMESPACE)
+ {
+ msymbol = lookup_minimal_symbol (name, NULL, NULL);
+ if (msymbol != NULL)
+ {
+ s = find_pc_sect_symtab (SYMBOL_VALUE_ADDRESS (msymbol),
+ SYMBOL_BFD_SECTION (msymbol));
+ if (s != NULL)
+ {
+ /* This is a function which has a symtab for its address. */
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
+ mangled_name, namespace);
+ /* We kept static functions in minimal symbol table as well as
+ in static scope. We want to find them in the symbol table. */
+ if (!sym)
+ {
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
+ mangled_name, namespace);
+ }
+
+ /* sym == 0 if symbol was found in the minimal symbol table
+ but not in the symtab.
+ Return 0 to use the msymbol definition of "foo_".
+
+ This happens for Fortran "foo_" symbols,
+ which are "foo" in the symtab.
+
+ This can also happen if "asm" is used to make a
+ regular symbol but not a debugging symbol, e.g.
+ asm(".globl _main");
+ asm("_main:");
+ */
+
+ if (symtab != NULL)
+ *symtab = s;
+ return fixup_symbol_section (sym, objfile);
+ }
+ else if (MSYMBOL_TYPE (msymbol) != mst_text
+ && MSYMBOL_TYPE (msymbol) != mst_file_text
+ && !STREQ (name, SYMBOL_NAME (msymbol)))
+ {
+ /* This is a mangled variable, look it up by its
+ mangled name. */
+ return lookup_symbol_aux (SYMBOL_NAME (msymbol), mangled_name, block,
+ namespace, is_a_field_of_this, symtab);
+ }
+ /* There are no debug symbols for this file, or we are looking
+ for an unmangled variable.
+ Try to find a matching static symbol below. */
+ }
+ }
+
+#endif
+
+ ALL_PSYMTABS (objfile, ps)
+ {
+ if (!ps->readin && lookup_partial_symbol (ps, name, 1, namespace))
+ {
+ s = PSYMTAB_TO_SYMTAB (ps);
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, mangled_name, namespace);
+ if (!sym)
+ {
+ /* This shouldn't be necessary, but as a last resort
+ * try looking in the statics even though the psymtab
+ * claimed the symbol was global. It's possible that
+ * the psymtab gets it wrong in some cases.
+ */
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_block_symbol (block, name, mangled_name, namespace);
+ if (!sym)
+ error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>).",
+ name, ps->filename, name, name);
+ }
+ if (symtab != NULL)
+ *symtab = s;
+ return fixup_symbol_section (sym, objfile);
+ }
+ }
+
+ /* Now search all static file-level symbols.
+ Not strictly correct, but more useful than an error.
+ Do the symtabs first, then check the psymtabs.
+ If a psymtab indicates the existence
+ of the desired name as a file-level static, then do psymtab-to-symtab
+ conversion on the fly and return the found symbol. */
+
+ ALL_SYMTABS (objfile, s)
+ {
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_block_symbol (block, name, mangled_name, namespace);
+ if (sym)
+ {
+ block_found = block;
+ if (symtab != NULL)
+ *symtab = s;
+ return fixup_symbol_section (sym, objfile);
+ }
+ }
+
+ ALL_PSYMTABS (objfile, ps)
+ {
+ if (!ps->readin && lookup_partial_symbol (ps, name, 0, namespace))
+ {
+ s = PSYMTAB_TO_SYMTAB (ps);
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_block_symbol (block, name, mangled_name, namespace);
+ if (!sym)
+ {
+ /* This shouldn't be necessary, but as a last resort
+ * try looking in the globals even though the psymtab
+ * claimed the symbol was static. It's possible that
+ * the psymtab gets it wrong in some cases.
+ */
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, mangled_name, namespace);
+ if (!sym)
+ error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>).",
+ name, ps->filename, name, name);
+ }
+ if (symtab != NULL)
+ *symtab = s;
+ return fixup_symbol_section (sym, objfile);
+ }
+ }
+
+#ifdef HPUXHPPA
+
+ /* Check for the possibility of the symbol being a function or
+ a global variable that is stored in one of the minimal symbol tables.
+ The "minimal symbol table" is built from linker-supplied info.
+
+ RT: I moved this check to last, after the complete search of
+ the global (p)symtab's and static (p)symtab's. For HP-generated
+ symbol tables, this check was causing a premature exit from
+ lookup_symbol with NULL return, and thus messing up symbol lookups
+ of things like "c::f". It seems to me a check of the minimal
+ symbol table ought to be a last resort in any case. I'm vaguely
+ worried about the comment below which talks about FORTRAN routines "foo_"
+ though... is it saying we need to do the "minsym" check before
+ the static check in this case?
+ */
+
+ if (namespace == VAR_NAMESPACE)
+ {
+ msymbol = lookup_minimal_symbol (name, NULL, NULL);
+ if (msymbol != NULL)
+ {
+ /* OK, we found a minimal symbol in spite of not
+ * finding any symbol. There are various possible
+ * explanations for this. One possibility is the symbol
+ * exists in code not compiled -g. Another possibility
+ * is that the 'psymtab' isn't doing its job.
+ * A third possibility, related to #2, is that we were confused
+ * by name-mangling. For instance, maybe the psymtab isn't
+ * doing its job because it only know about demangled
+ * names, but we were given a mangled name...
+ */
+
+ /* We first use the address in the msymbol to try to
+ * locate the appropriate symtab. Note that find_pc_symtab()
+ * has a side-effect of doing psymtab-to-symtab expansion,
+ * for the found symtab.
+ */
+ s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol));
+ if (s != NULL)
+ {
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
+ mangled_name, namespace);
+ /* We kept static functions in minimal symbol table as well as
+ in static scope. We want to find them in the symbol table. */
+ if (!sym)
+ {
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
+ mangled_name, namespace);
+ }
+ /* If we found one, return it */
+ if (sym)
+ {
+ if (symtab != NULL)
+ *symtab = s;
+ return sym;
+ }
+
+ /* If we get here with sym == 0, the symbol was
+ found in the minimal symbol table
+ but not in the symtab.
+ Fall through and return 0 to use the msymbol
+ definition of "foo_".
+ (Note that outer code generally follows up a call
+ to this routine with a call to lookup_minimal_symbol(),
+ so a 0 return means we'll just flow into that other routine).
+
+ This happens for Fortran "foo_" symbols,
+ which are "foo" in the symtab.
+
+ This can also happen if "asm" is used to make a
+ regular symbol but not a debugging symbol, e.g.
+ asm(".globl _main");
+ asm("_main:");
+ */
+ }
+
+ /* If the lookup-by-address fails, try repeating the
+ * entire lookup process with the symbol name from
+ * the msymbol (if different from the original symbol name).
+ */
+ else if (MSYMBOL_TYPE (msymbol) != mst_text
+ && MSYMBOL_TYPE (msymbol) != mst_file_text
+ && !STREQ (name, SYMBOL_NAME (msymbol)))
+ {
+ return lookup_symbol_aux (SYMBOL_NAME (msymbol), mangled_name,
+ block, namespace, is_a_field_of_this,
+ symtab);
+ }
+ }
+ }
+
+#endif
+
+ if (symtab != NULL)
+ *symtab = NULL;
+ return 0;
+}
+
+/* Look, in partial_symtab PST, for symbol NAME. Check the global
+ symbols if GLOBAL, the static symbols if not */
+
+static struct partial_symbol *
+lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
+ namespace_enum namespace)
+{
+ struct partial_symbol *temp;
+ struct partial_symbol **start, **psym;
+ struct partial_symbol **top, **bottom, **center;
+ int length = (global ? pst->n_global_syms : pst->n_static_syms);
+ int do_linear_search = 1;
+
+ if (length == 0)
+ {
+ return (NULL);
+ }
+ start = (global ?
+ pst->objfile->global_psymbols.list + pst->globals_offset :
+ pst->objfile->static_psymbols.list + pst->statics_offset);
+
+ if (global) /* This means we can use a binary search. */
+ {
+ do_linear_search = 0;
+
+ /* Binary search. This search is guaranteed to end with center
+ pointing at the earliest partial symbol with the correct
+ name. At that point *all* partial symbols with that name
+ will be checked against the correct namespace. */
+
+ bottom = start;
+ top = start + length - 1;
+ while (top > bottom)
+ {
+ center = bottom + (top - bottom) / 2;
+ if (!(center < top))
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ if (!do_linear_search
+ && (SYMBOL_LANGUAGE (*center) == language_java))
+ {
+ do_linear_search = 1;
+ }
+ if (strcmp (SYMBOL_SOURCE_NAME (*center), name) >= 0)
+ {
+ top = center;
+ }
+ else
+ {
+ bottom = center + 1;
+ }
+ }
+ if (!(top == bottom))
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+ /* djb - 2000-06-03 - Use SYMBOL_MATCHES_NAME, not a strcmp, so
+ we don't have to force a linear search on C++. Probably holds true
+ for JAVA as well, no way to check.*/
+ while (SYMBOL_MATCHES_NAME (*top,name))
+ {
+ if (SYMBOL_NAMESPACE (*top) == namespace)
+ {
+ return (*top);
+ }
+ top++;
+ }
+ }
+
+ /* Can't use a binary search or else we found during the binary search that
+ we should also do a linear search. */
+
+ if (do_linear_search)
+ {
+ for (psym = start; psym < start + length; psym++)
+ {
+ if (namespace == SYMBOL_NAMESPACE (*psym))
+ {
+ if (SYMBOL_MATCHES_NAME (*psym, name))
+ {
+ return (*psym);
+ }
+ }
+ }
+ }
+
+ return (NULL);
+}
+
+/* Look up a type named NAME in the struct_namespace. The type returned
+ must not be opaque -- i.e., must have at least one field defined
+
+ This code was modelled on lookup_symbol -- the parts not relevant to looking
+ up types were just left out. In particular it's assumed here that types
+ are available in struct_namespace and only at file-static or global blocks. */
+
+
+struct type *
+lookup_transparent_type (const char *name)
+{
+ register struct symbol *sym;
+ register struct symtab *s = NULL;
+ register struct partial_symtab *ps;
+ struct blockvector *bv;
+ register struct objfile *objfile;
+ register struct block *block;
+
+ /* Now search all the global symbols. Do the symtab's first, then
+ check the psymtab's. If a psymtab indicates the existence
+ of the desired name as a global, then do psymtab-to-symtab
+ conversion on the fly and return the found symbol. */
+
+ ALL_SYMTABS (objfile, s)
+ {
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+ if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+ {
+ return SYMBOL_TYPE (sym);
+ }
+ }
+
+ ALL_PSYMTABS (objfile, ps)
+ {
+ if (!ps->readin && lookup_partial_symbol (ps, name, 1, STRUCT_NAMESPACE))
+ {
+ s = PSYMTAB_TO_SYMTAB (ps);
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+ if (!sym)
+ {
+ /* This shouldn't be necessary, but as a last resort
+ * try looking in the statics even though the psymtab
+ * claimed the symbol was global. It's possible that
+ * the psymtab gets it wrong in some cases.
+ */
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+ if (!sym)
+ error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>).",
+ name, ps->filename, name, name);
+ }
+ if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+ return SYMBOL_TYPE (sym);
+ }
+ }
+
+ /* Now search the static file-level symbols.
+ Not strictly correct, but more useful than an error.
+ Do the symtab's first, then
+ check the psymtab's. If a psymtab indicates the existence
+ of the desired name as a file-level static, then do psymtab-to-symtab
+ conversion on the fly and return the found symbol.
+ */
+
+ ALL_SYMTABS (objfile, s)
+ {
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+ if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+ {
+ return SYMBOL_TYPE (sym);
+ }
+ }
+
+ ALL_PSYMTABS (objfile, ps)
+ {
+ if (!ps->readin && lookup_partial_symbol (ps, name, 0, STRUCT_NAMESPACE))
+ {
+ s = PSYMTAB_TO_SYMTAB (ps);
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+ if (!sym)
+ {
+ /* This shouldn't be necessary, but as a last resort
+ * try looking in the globals even though the psymtab
+ * claimed the symbol was static. It's possible that
+ * the psymtab gets it wrong in some cases.
+ */
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+ if (!sym)
+ error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>).",
+ name, ps->filename, name, name);
+ }
+ if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+ return SYMBOL_TYPE (sym);
+ }
+ }
+ return (struct type *) 0;
+}
+
+
+/* Find the psymtab containing main(). */
+/* FIXME: What about languages without main() or specially linked
+ executables that have no main() ? */
+
+struct partial_symtab *
+find_main_psymtab (void)
+{
+ register struct partial_symtab *pst;
+ register struct objfile *objfile;
+
+ ALL_PSYMTABS (objfile, pst)
+ {
+ if (lookup_partial_symbol (pst, main_name (), 1, VAR_NAMESPACE))
+ {
+ return (pst);
+ }
+ }
+ return (NULL);
+}
+
+/* Search BLOCK for symbol NAME in NAMESPACE.
+
+ Note that if NAME is the demangled form of a C++ symbol, we will fail
+ to find a match during the binary search of the non-encoded names, but
+ for now we don't worry about the slight inefficiency of looking for
+ a match we'll never find, since it will go pretty quick. Once the
+ binary search terminates, we drop through and do a straight linear
+ search on the symbols. Each symbol which is marked as being a C++
+ symbol (language_cplus set) has both the encoded and non-encoded names
+ tested for a match.
+
+ If MANGLED_NAME is non-NULL, verify that any symbol we find has this
+ particular mangled name.
+*/
+
+struct symbol *
+lookup_block_symbol (register const struct block *block, const char *name,
+ const char *mangled_name,
+ const namespace_enum namespace)
+{
+ register int bot, top, inc;
+ register struct symbol *sym;
+ register struct symbol *sym_found = NULL;
+ register int do_linear_search = 1;
+
+ /* If the blocks's symbols were sorted, start with a binary search. */
+
+ if (BLOCK_SHOULD_SORT (block))
+ {
+ /* Reset the linear search flag so if the binary search fails, we
+ won't do the linear search once unless we find some reason to
+ do so */
+
+ do_linear_search = 0;
+ top = BLOCK_NSYMS (block);
+ bot = 0;
+
+ /* Advance BOT to not far before the first symbol whose name is NAME. */
+
+ while (1)
+ {
+ inc = (top - bot + 1);
+ /* No need to keep binary searching for the last few bits worth. */
+ if (inc < 4)
+ {
+ break;
+ }
+ inc = (inc >> 1) + bot;
+ sym = BLOCK_SYM (block, inc);
+ if (!do_linear_search && (SYMBOL_LANGUAGE (sym) == language_java))
+ {
+ do_linear_search = 1;
+ }
+ if (SYMBOL_SOURCE_NAME (sym)[0] < name[0])
+ {
+ bot = inc;
+ }
+ else if (SYMBOL_SOURCE_NAME (sym)[0] > name[0])
+ {
+ top = inc;
+ }
+ else if (strcmp (SYMBOL_SOURCE_NAME (sym), name) < 0)
+ {
+ bot = inc;
+ }
+ else
+ {
+ top = inc;
+ }
+ }
+
+ /* Now scan forward until we run out of symbols, find one whose
+ name is greater than NAME, or find one we want. If there is
+ more than one symbol with the right name and namespace, we
+ return the first one; I believe it is now impossible for us
+ to encounter two symbols with the same name and namespace
+ here, because blocks containing argument symbols are no
+ longer sorted. The exception is for C++, where multiple functions
+ (cloned constructors / destructors, in particular) can have
+ the same demangled name. So if we have a particular
+ mangled name to match, try to do so. */
+
+ top = BLOCK_NSYMS (block);
+ while (bot < top)
+ {
+ sym = BLOCK_SYM (block, bot);
+ if (SYMBOL_NAMESPACE (sym) == namespace
+ && (mangled_name
+ ? strcmp (SYMBOL_NAME (sym), mangled_name) == 0
+ : SYMBOL_MATCHES_NAME (sym, name)))
+ {
+ return sym;
+ }
+ if (SYMBOL_SOURCE_NAME (sym)[0] > name[0])
+ {
+ break;
+ }
+ bot++;
+ }
+ }
+
+ /* Here if block isn't sorted, or we fail to find a match during the
+ binary search above. If during the binary search above, we find a
+ symbol which is a Java symbol, then we have re-enabled the linear
+ search flag which was reset when starting the binary search.
+
+ This loop is equivalent to the loop above, but hacked greatly for speed.
+
+ Note that parameter symbols do not always show up last in the
+ list; this loop makes sure to take anything else other than
+ parameter symbols first; it only uses parameter symbols as a
+ last resort. Note that this only takes up extra computation
+ time on a match. */
+
+ if (do_linear_search)
+ {
+ top = BLOCK_NSYMS (block);
+ bot = 0;
+ while (bot < top)
+ {
+ sym = BLOCK_SYM (block, bot);
+ if (SYMBOL_NAMESPACE (sym) == namespace
+ && (mangled_name
+ ? strcmp (SYMBOL_NAME (sym), mangled_name) == 0
+ : SYMBOL_MATCHES_NAME (sym, name)))
+ {
+ /* If SYM has aliases, then use any alias that is active
+ at the current PC. If no alias is active at the current
+ PC, then use the main symbol.
+
+ ?!? Is checking the current pc correct? Is this routine
+ ever called to look up a symbol from another context?
+
+ FIXME: No, it's not correct. If someone sets a
+ conditional breakpoint at an address, then the
+ breakpoint's `struct expression' should refer to the
+ `struct symbol' appropriate for the breakpoint's
+ address, which may not be the PC.
+
+ Even if it were never called from another context,
+ it's totally bizarre for lookup_symbol's behavior to
+ depend on the value of the inferior's current PC. We
+ should pass in the appropriate PC as well as the
+ block. The interface to lookup_symbol should change
+ to require the caller to provide a PC. */
+
+ if (SYMBOL_ALIASES (sym))
+ sym = find_active_alias (sym, read_pc ());
+
+ sym_found = sym;
+ if (SYMBOL_CLASS (sym) != LOC_ARG &&
+ SYMBOL_CLASS (sym) != LOC_LOCAL_ARG &&
+ SYMBOL_CLASS (sym) != LOC_REF_ARG &&
+ SYMBOL_CLASS (sym) != LOC_REGPARM &&
+ SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR &&
+ SYMBOL_CLASS (sym) != LOC_BASEREG_ARG)
+ {
+ break;
+ }
+ }
+ bot++;
+ }
+ }
+ return (sym_found); /* Will be NULL if not found. */
+}
+
+/* Given a main symbol SYM and ADDR, search through the alias
+ list to determine if an alias is active at ADDR and return
+ the active alias.
+
+ If no alias is active, then return SYM. */
+
+static struct symbol *
+find_active_alias (struct symbol *sym, CORE_ADDR addr)
+{
+ struct range_list *r;
+ struct alias_list *aliases;
+
+ /* If we have aliases, check them first. */
+ aliases = SYMBOL_ALIASES (sym);
+
+ while (aliases)
+ {
+ if (!SYMBOL_RANGES (aliases->sym))
+ return aliases->sym;
+ for (r = SYMBOL_RANGES (aliases->sym); r; r = r->next)
+ {
+ if (r->start <= addr && r->end > addr)
+ return aliases->sym;
+ }
+ aliases = aliases->next;
+ }
+
+ /* Nothing found, return the main symbol. */
+ return sym;
+}
+
+
+/* Return the symbol for the function which contains a specified
+ lexical block, described by a struct block BL. */
+
+struct symbol *
+block_function (struct block *bl)
+{
+ while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0)
+ bl = BLOCK_SUPERBLOCK (bl);
+
+ return BLOCK_FUNCTION (bl);
+}
+
+/* Find the symtab associated with PC and SECTION. Look through the
+ psymtabs and read in another symtab if necessary. */
+
+struct symtab *
+find_pc_sect_symtab (CORE_ADDR pc, asection *section)
+{
+ register struct block *b;
+ struct blockvector *bv;
+ register struct symtab *s = NULL;
+ register struct symtab *best_s = NULL;
+ register struct partial_symtab *ps;
+ register struct objfile *objfile;
+ CORE_ADDR distance = 0;
+ struct minimal_symbol *msymbol;
+
+ /* If we know that this is not a text address, return failure. This is
+ necessary because we loop based on the block's high and low code
+ addresses, which do not include the data ranges, and because
+ we call find_pc_sect_psymtab which has a similar restriction based
+ on the partial_symtab's texthigh and textlow. */
+ msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
+ if (msymbol
+ && (msymbol->type == mst_data
+ || msymbol->type == mst_bss
+ || msymbol->type == mst_abs
+ || msymbol->type == mst_file_data
+ || msymbol->type == mst_file_bss))
+ return NULL;
+
+ /* Search all symtabs for the one whose file contains our address, and which
+ is the smallest of all the ones containing the address. This is designed
+ to deal with a case like symtab a is at 0x1000-0x2000 and 0x3000-0x4000
+ and symtab b is at 0x2000-0x3000. So the GLOBAL_BLOCK for a is from
+ 0x1000-0x4000, but for address 0x2345 we want to return symtab b.
+
+ This happens for native ecoff format, where code from included files
+ gets its own symtab. The symtab for the included file should have
+ been read in already via the dependency mechanism.
+ It might be swifter to create several symtabs with the same name
+ like xcoff does (I'm not sure).
+
+ It also happens for objfiles that have their functions reordered.
+ For these, the symtab we are looking for is not necessarily read in. */
+
+ ALL_SYMTABS (objfile, s)
+ {
+ bv = BLOCKVECTOR (s);
+ b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+
+ if (BLOCK_START (b) <= pc
+ && BLOCK_END (b) > pc
+ && (distance == 0
+ || BLOCK_END (b) - BLOCK_START (b) < distance))
+ {
+ /* For an objfile that has its functions reordered,
+ find_pc_psymtab will find the proper partial symbol table
+ and we simply return its corresponding symtab. */
+ /* In order to better support objfiles that contain both
+ stabs and coff debugging info, we continue on if a psymtab
+ can't be found. */
+ if ((objfile->flags & OBJF_REORDERED) && objfile->psymtabs)
+ {
+ ps = find_pc_sect_psymtab (pc, section);
+ if (ps)
+ return PSYMTAB_TO_SYMTAB (ps);
+ }
+ if (section != 0)
+ {
+ int i;
+
+ for (i = 0; i < b->nsyms; i++)
+ {
+ fixup_symbol_section (b->sym[i], objfile);
+ if (section == SYMBOL_BFD_SECTION (b->sym[i]))
+ break;
+ }
+ if (i >= b->nsyms)
+ continue; /* no symbol in this symtab matches section */
+ }
+ distance = BLOCK_END (b) - BLOCK_START (b);
+ best_s = s;
+ }
+ }
+
+ if (best_s != NULL)
+ return (best_s);
+
+ s = NULL;
+ ps = find_pc_sect_psymtab (pc, section);
+ if (ps)
+ {
+ if (ps->readin)
+ /* Might want to error() here (in case symtab is corrupt and
+ will cause a core dump), but maybe we can successfully
+ continue, so let's not. */
+ warning ("\
+(Internal error: pc 0x%s in read in psymtab, but not in symtab.)\n",
+ paddr_nz (pc));
+ s = PSYMTAB_TO_SYMTAB (ps);
+ }
+ return (s);
+}
+
+/* Find the symtab associated with PC. Look through the psymtabs and
+ read in another symtab if necessary. Backward compatibility, no section */
+
+struct symtab *
+find_pc_symtab (CORE_ADDR pc)
+{
+ return find_pc_sect_symtab (pc, find_pc_mapped_section (pc));
+}
+
+
+#if 0
+
+/* Find the closest symbol value (of any sort -- function or variable)
+ for a given address value. Slow but complete. (currently unused,
+ mainly because it is too slow. We could fix it if each symtab and
+ psymtab had contained in it the addresses ranges of each of its
+ sections, which also would be required to make things like "info
+ line *0x2345" cause psymtabs to be converted to symtabs). */
+
+struct symbol *
+find_addr_symbol (CORE_ADDR addr, struct symtab **symtabp, CORE_ADDR *symaddrp)
+{
+ struct symtab *symtab, *best_symtab;
+ struct objfile *objfile;
+ register int bot, top;
+ register struct symbol *sym;
+ register CORE_ADDR sym_addr;
+ struct block *block;
+ int blocknum;
+
+ /* Info on best symbol seen so far */
+
+ register CORE_ADDR best_sym_addr = 0;
+ struct symbol *best_sym = 0;
+
+ /* FIXME -- we should pull in all the psymtabs, too! */
+ ALL_SYMTABS (objfile, symtab)
+ {
+ /* Search the global and static blocks in this symtab for
+ the closest symbol-address to the desired address. */
+
+ for (blocknum = GLOBAL_BLOCK; blocknum <= STATIC_BLOCK; blocknum++)
+ {
+ QUIT;
+ block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), blocknum);
+ top = BLOCK_NSYMS (block);
+ for (bot = 0; bot < top; bot++)
+ {
+ sym = BLOCK_SYM (block, bot);
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_STATIC:
+ case LOC_LABEL:
+ sym_addr = SYMBOL_VALUE_ADDRESS (sym);
+ break;
+
+ case LOC_INDIRECT:
+ sym_addr = SYMBOL_VALUE_ADDRESS (sym);
+ /* An indirect symbol really lives at *sym_addr,
+ * so an indirection needs to be done.
+ * However, I am leaving this commented out because it's
+ * expensive, and it's possible that symbolization
+ * could be done without an active process (in
+ * case this read_memory will fail). RT
+ sym_addr = read_memory_unsigned_integer
+ (sym_addr, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ */
+ break;
+
+ case LOC_BLOCK:
+ sym_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+ break;
+
+ default:
+ continue;
+ }
+
+ if (sym_addr <= addr)
+ if (sym_addr > best_sym_addr)
+ {
+ /* Quit if we found an exact match. */
+ best_sym = sym;
+ best_sym_addr = sym_addr;
+ best_symtab = symtab;
+ if (sym_addr == addr)
+ goto done;
+ }
+ }
+ }
+ }
+
+done:
+ if (symtabp)
+ *symtabp = best_symtab;
+ if (symaddrp)
+ *symaddrp = best_sym_addr;
+ return best_sym;
+}
+#endif /* 0 */
+
+/* Find the source file and line number for a given PC value and SECTION.
+ Return a structure containing a symtab pointer, a line number,
+ and a pc range for the entire source line.
+ The value's .pc field is NOT the specified pc.
+ NOTCURRENT nonzero means, if specified pc is on a line boundary,
+ use the line that ends there. Otherwise, in that case, the line
+ that begins there is used. */
+
+/* The big complication here is that a line may start in one file, and end just
+ before the start of another file. This usually occurs when you #include
+ code in the middle of a subroutine. To properly find the end of a line's PC
+ range, we must search all symtabs associated with this compilation unit, and
+ find the one whose first PC is closer than that of the next line in this
+ symtab. */
+
+/* If it's worth the effort, we could be using a binary search. */
+
+struct symtab_and_line
+find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
+{
+ struct symtab *s;
+ register struct linetable *l;
+ register int len;
+ register int i;
+ register struct linetable_entry *item;
+ struct symtab_and_line val;
+ struct blockvector *bv;
+ struct minimal_symbol *msymbol;
+ struct minimal_symbol *mfunsym;
+
+ /* Info on best line seen so far, and where it starts, and its file. */
+
+ struct linetable_entry *best = NULL;
+ CORE_ADDR best_end = 0;
+ struct symtab *best_symtab = 0;
+
+ /* Store here the first line number
+ of a file which contains the line at the smallest pc after PC.
+ If we don't find a line whose range contains PC,
+ we will use a line one less than this,
+ with a range from the start of that file to the first line's pc. */
+ struct linetable_entry *alt = NULL;
+ struct symtab *alt_symtab = 0;
+
+ /* Info on best line seen in this file. */
+
+ struct linetable_entry *prev;
+
+ /* If this pc is not from the current frame,
+ it is the address of the end of a call instruction.
+ Quite likely that is the start of the following statement.
+ But what we want is the statement containing the instruction.
+ Fudge the pc to make sure we get that. */
+
+ INIT_SAL (&val); /* initialize to zeroes */
+
+ /* It's tempting to assume that, if we can't find debugging info for
+ any function enclosing PC, that we shouldn't search for line
+ number info, either. However, GAS can emit line number info for
+ assembly files --- very helpful when debugging hand-written
+ assembly code. In such a case, we'd have no debug info for the
+ function, but we would have line info. */
+
+ if (notcurrent)
+ pc -= 1;
+
+ /* elz: added this because this function returned the wrong
+ information if the pc belongs to a stub (import/export)
+ to call a shlib function. This stub would be anywhere between
+ two functions in the target, and the line info was erroneously
+ taken to be the one of the line before the pc.
+ */
+ /* RT: Further explanation:
+
+ * We have stubs (trampolines) inserted between procedures.
+ *
+ * Example: "shr1" exists in a shared library, and a "shr1" stub also
+ * exists in the main image.
+ *
+ * In the minimal symbol table, we have a bunch of symbols
+ * sorted by start address. The stubs are marked as "trampoline",
+ * the others appear as text. E.g.:
+ *
+ * Minimal symbol table for main image
+ * main: code for main (text symbol)
+ * shr1: stub (trampoline symbol)
+ * foo: code for foo (text symbol)
+ * ...
+ * Minimal symbol table for "shr1" image:
+ * ...
+ * shr1: code for shr1 (text symbol)
+ * ...
+ *
+ * So the code below is trying to detect if we are in the stub
+ * ("shr1" stub), and if so, find the real code ("shr1" trampoline),
+ * and if found, do the symbolization from the real-code address
+ * rather than the stub address.
+ *
+ * Assumptions being made about the minimal symbol table:
+ * 1. lookup_minimal_symbol_by_pc() will return a trampoline only
+ * if we're really in the trampoline. If we're beyond it (say
+ * we're in "foo" in the above example), it'll have a closer
+ * symbol (the "foo" text symbol for example) and will not
+ * return the trampoline.
+ * 2. lookup_minimal_symbol_text() will find a real text symbol
+ * corresponding to the trampoline, and whose address will
+ * be different than the trampoline address. I put in a sanity
+ * check for the address being the same, to avoid an
+ * infinite recursion.
+ */
+ msymbol = lookup_minimal_symbol_by_pc (pc);
+ if (msymbol != NULL)
+ if (MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
+ {
+ mfunsym = lookup_minimal_symbol_text (SYMBOL_NAME (msymbol), NULL, NULL);
+ if (mfunsym == NULL)
+ /* I eliminated this warning since it is coming out
+ * in the following situation:
+ * gdb shmain // test program with shared libraries
+ * (gdb) break shr1 // function in shared lib
+ * Warning: In stub for ...
+ * In the above situation, the shared lib is not loaded yet,
+ * so of course we can't find the real func/line info,
+ * but the "break" still works, and the warning is annoying.
+ * So I commented out the warning. RT */
+ /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_NAME(msymbol)) */ ;
+ /* fall through */
+ else if (SYMBOL_VALUE (mfunsym) == SYMBOL_VALUE (msymbol))
+ /* Avoid infinite recursion */
+ /* See above comment about why warning is commented out */
+ /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_NAME(msymbol)) */ ;
+ /* fall through */
+ else
+ return find_pc_line (SYMBOL_VALUE (mfunsym), 0);
+ }
+
+
+ s = find_pc_sect_symtab (pc, section);
+ if (!s)
+ {
+ /* if no symbol information, return previous pc */
+ if (notcurrent)
+ pc++;
+ val.pc = pc;
+ return val;
+ }
+
+ bv = BLOCKVECTOR (s);
+
+ /* Look at all the symtabs that share this blockvector.
+ They all have the same apriori range, that we found was right;
+ but they have different line tables. */
+
+ for (; s && BLOCKVECTOR (s) == bv; s = s->next)
+ {
+ /* Find the best line in this symtab. */
+ l = LINETABLE (s);
+ if (!l)
+ continue;
+ len = l->nitems;
+ if (len <= 0)
+ {
+ /* I think len can be zero if the symtab lacks line numbers
+ (e.g. gcc -g1). (Either that or the LINETABLE is NULL;
+ I'm not sure which, and maybe it depends on the symbol
+ reader). */
+ continue;
+ }
+
+ prev = NULL;
+ item = l->item; /* Get first line info */
+
+ /* Is this file's first line closer than the first lines of other files?
+ If so, record this file, and its first line, as best alternate. */
+ if (item->pc > pc && (!alt || item->pc < alt->pc))
+ {
+ alt = item;
+ alt_symtab = s;
+ }
+
+ for (i = 0; i < len; i++, item++)
+ {
+ /* Leave prev pointing to the linetable entry for the last line
+ that started at or before PC. */
+ if (item->pc > pc)
+ break;
+
+ prev = item;
+ }
+
+ /* At this point, prev points at the line whose start addr is <= pc, and
+ item points at the next line. If we ran off the end of the linetable
+ (pc >= start of the last line), then prev == item. If pc < start of
+ the first line, prev will not be set. */
+
+ /* Is this file's best line closer than the best in the other files?
+ If so, record this file, and its best line, as best so far. */
+
+ if (prev && (!best || prev->pc > best->pc))
+ {
+ best = prev;
+ best_symtab = s;
+
+ /* Discard BEST_END if it's before the PC of the current BEST. */
+ if (best_end <= best->pc)
+ best_end = 0;
+ }
+
+ /* If another line (denoted by ITEM) is in the linetable and its
+ PC is after BEST's PC, but before the current BEST_END, then
+ use ITEM's PC as the new best_end. */
+ if (best && i < len && item->pc > best->pc
+ && (best_end == 0 || best_end > item->pc))
+ best_end = item->pc;
+ }
+
+ if (!best_symtab)
+ {
+ if (!alt_symtab)
+ { /* If we didn't find any line # info, just
+ return zeros. */
+ val.pc = pc;
+ }
+ else
+ {
+ val.symtab = alt_symtab;
+ val.line = alt->line - 1;
+
+ /* Don't return line 0, that means that we didn't find the line. */
+ if (val.line == 0)
+ ++val.line;
+
+ val.pc = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
+ val.end = alt->pc;
+ }
+ }
+ else if (best->line == 0)
+ {
+ /* If our best fit is in a range of PC's for which no line
+ number info is available (line number is zero) then we didn't
+ find any valid line information. */
+ val.pc = pc;
+ }
+ else
+ {
+ val.symtab = best_symtab;
+ val.line = best->line;
+ val.pc = best->pc;
+ if (best_end && (!alt || best_end < alt->pc))
+ val.end = best_end;
+ else if (alt)
+ val.end = alt->pc;
+ else
+ val.end = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
+ }
+ val.section = section;
+ return val;
+}
+
+/* Backward compatibility (no section) */
+
+struct symtab_and_line
+find_pc_line (CORE_ADDR pc, int notcurrent)
+{
+ asection *section;
+
+ section = find_pc_overlay (pc);
+ if (pc_in_unmapped_range (pc, section))
+ pc = overlay_mapped_address (pc, section);
+ return find_pc_sect_line (pc, section, notcurrent);
+}
+
+/* Find line number LINE in any symtab whose name is the same as
+ SYMTAB.
+
+ If found, return the symtab that contains the linetable in which it was
+ found, set *INDEX to the index in the linetable of the best entry
+ found, and set *EXACT_MATCH nonzero if the value returned is an
+ exact match.
+
+ If not found, return NULL. */
+
+struct symtab *
+find_line_symtab (struct symtab *symtab, int line, int *index, int *exact_match)
+{
+ int exact;
+
+ /* BEST_INDEX and BEST_LINETABLE identify the smallest linenumber > LINE
+ so far seen. */
+
+ int best_index;
+ struct linetable *best_linetable;
+ struct symtab *best_symtab;
+
+ /* First try looking it up in the given symtab. */
+ best_linetable = LINETABLE (symtab);
+ best_symtab = symtab;
+ best_index = find_line_common (best_linetable, line, &exact);
+ if (best_index < 0 || !exact)
+ {
+ /* Didn't find an exact match. So we better keep looking for
+ another symtab with the same name. In the case of xcoff,
+ multiple csects for one source file (produced by IBM's FORTRAN
+ compiler) produce multiple symtabs (this is unavoidable
+ assuming csects can be at arbitrary places in memory and that
+ the GLOBAL_BLOCK of a symtab has a begin and end address). */
+
+ /* BEST is the smallest linenumber > LINE so far seen,
+ or 0 if none has been seen so far.
+ BEST_INDEX and BEST_LINETABLE identify the item for it. */
+ int best;
+
+ struct objfile *objfile;
+ struct symtab *s;
+
+ if (best_index >= 0)
+ best = best_linetable->item[best_index].line;
+ else
+ best = 0;
+
+ ALL_SYMTABS (objfile, s)
+ {
+ struct linetable *l;
+ int ind;
+
+ if (!STREQ (symtab->filename, s->filename))
+ continue;
+ l = LINETABLE (s);
+ ind = find_line_common (l, line, &exact);
+ if (ind >= 0)
+ {
+ if (exact)
+ {
+ best_index = ind;
+ best_linetable = l;
+ best_symtab = s;
+ goto done;
+ }
+ if (best == 0 || l->item[ind].line < best)
+ {
+ best = l->item[ind].line;
+ best_index = ind;
+ best_linetable = l;
+ best_symtab = s;
+ }
+ }
+ }
+ }
+done:
+ if (best_index < 0)
+ return NULL;
+
+ if (index)
+ *index = best_index;
+ if (exact_match)
+ *exact_match = exact;
+
+ return best_symtab;
+}
+
+/* Set the PC value for a given source file and line number and return true.
+ Returns zero for invalid line number (and sets the PC to 0).
+ The source file is specified with a struct symtab. */
+
+int
+find_line_pc (struct symtab *symtab, int line, CORE_ADDR *pc)
+{
+ struct linetable *l;
+ int ind;
+
+ *pc = 0;
+ if (symtab == 0)
+ return 0;
+
+ symtab = find_line_symtab (symtab, line, &ind, NULL);
+ if (symtab != NULL)
+ {
+ l = LINETABLE (symtab);
+ *pc = l->item[ind].pc;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+/* Find the range of pc values in a line.
+ Store the starting pc of the line into *STARTPTR
+ and the ending pc (start of next line) into *ENDPTR.
+ Returns 1 to indicate success.
+ Returns 0 if could not find the specified line. */
+
+int
+find_line_pc_range (struct symtab_and_line sal, CORE_ADDR *startptr,
+ CORE_ADDR *endptr)
+{
+ CORE_ADDR startaddr;
+ struct symtab_and_line found_sal;
+
+ startaddr = sal.pc;
+ if (startaddr == 0 && !find_line_pc (sal.symtab, sal.line, &startaddr))
+ return 0;
+
+ /* This whole function is based on address. For example, if line 10 has
+ two parts, one from 0x100 to 0x200 and one from 0x300 to 0x400, then
+ "info line *0x123" should say the line goes from 0x100 to 0x200
+ and "info line *0x355" should say the line goes from 0x300 to 0x400.
+ This also insures that we never give a range like "starts at 0x134
+ and ends at 0x12c". */
+
+ found_sal = find_pc_sect_line (startaddr, sal.section, 0);
+ if (found_sal.line != sal.line)
+ {
+ /* The specified line (sal) has zero bytes. */
+ *startptr = found_sal.pc;
+ *endptr = found_sal.pc;
+ }
+ else
+ {
+ *startptr = found_sal.pc;
+ *endptr = found_sal.end;
+ }
+ return 1;
+}
+
+/* Given a line table and a line number, return the index into the line
+ table for the pc of the nearest line whose number is >= the specified one.
+ Return -1 if none is found. The value is >= 0 if it is an index.
+
+ Set *EXACT_MATCH nonzero if the value returned is an exact match. */
+
+static int
+find_line_common (register struct linetable *l, register int lineno,
+ int *exact_match)
+{
+ register int i;
+ register int len;
+
+ /* BEST is the smallest linenumber > LINENO so far seen,
+ or 0 if none has been seen so far.
+ BEST_INDEX identifies the item for it. */
+
+ int best_index = -1;
+ int best = 0;
+
+ if (lineno <= 0)
+ return -1;
+ if (l == 0)
+ return -1;
+
+ len = l->nitems;
+ for (i = 0; i < len; i++)
+ {
+ register struct linetable_entry *item = &(l->item[i]);
+
+ if (item->line == lineno)
+ {
+ /* Return the first (lowest address) entry which matches. */
+ *exact_match = 1;
+ return i;
+ }
+
+ if (item->line > lineno && (best == 0 || item->line < best))
+ {
+ best = item->line;
+ best_index = i;
+ }
+ }
+
+ /* If we got here, we didn't get an exact match. */
+
+ *exact_match = 0;
+ return best_index;
+}
+
+int
+find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
+{
+ struct symtab_and_line sal;
+ sal = find_pc_line (pc, 0);
+ *startptr = sal.pc;
+ *endptr = sal.end;
+ return sal.symtab != 0;
+}
+
+/* Given a function symbol SYM, find the symtab and line for the start
+ of the function.
+ If the argument FUNFIRSTLINE is nonzero, we want the first line
+ of real code inside the function. */
+
+struct symtab_and_line
+find_function_start_sal (struct symbol *sym, int funfirstline)
+{
+ CORE_ADDR pc;
+ struct symtab_and_line sal;
+
+ pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+ fixup_symbol_section (sym, NULL);
+ if (funfirstline)
+ { /* skip "first line" of function (which is actually its prologue) */
+ asection *section = SYMBOL_BFD_SECTION (sym);
+ /* If function is in an unmapped overlay, use its unmapped LMA
+ address, so that SKIP_PROLOGUE has something unique to work on */
+ if (section_is_overlay (section) &&
+ !section_is_mapped (section))
+ pc = overlay_unmapped_address (pc, section);
+
+ pc += FUNCTION_START_OFFSET;
+ pc = SKIP_PROLOGUE (pc);
+
+ /* For overlays, map pc back into its mapped VMA range */
+ pc = overlay_mapped_address (pc, section);
+ }
+ sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
+
+#ifdef PROLOGUE_FIRSTLINE_OVERLAP
+ /* Convex: no need to suppress code on first line, if any */
+ sal.pc = pc;
+#else
+ /* Check if SKIP_PROLOGUE left us in mid-line, and the next
+ line is still part of the same function. */
+ if (sal.pc != pc
+ && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= sal.end
+ && sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
+ {
+ /* First pc of next line */
+ pc = sal.end;
+ /* Recalculate the line number (might not be N+1). */
+ sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
+ }
+ sal.pc = pc;
+#endif
+
+ return sal;
+}
+
+/* If P is of the form "operator[ \t]+..." where `...' is
+ some legitimate operator text, return a pointer to the
+ beginning of the substring of the operator text.
+ Otherwise, return "". */
+char *
+operator_chars (char *p, char **end)
+{
+ *end = "";
+ if (strncmp (p, "operator", 8))
+ return *end;
+ p += 8;
+
+ /* Don't get faked out by `operator' being part of a longer
+ identifier. */
+ if (isalpha (*p) || *p == '_' || *p == '$' || *p == '\0')
+ return *end;
+
+ /* Allow some whitespace between `operator' and the operator symbol. */
+ while (*p == ' ' || *p == '\t')
+ p++;
+
+ /* Recognize 'operator TYPENAME'. */
+
+ if (isalpha (*p) || *p == '_' || *p == '$')
+ {
+ register char *q = p + 1;
+ while (isalnum (*q) || *q == '_' || *q == '$')
+ q++;
+ *end = q;
+ return p;
+ }
+
+ while (*p)
+ switch (*p)
+ {
+ case '\\': /* regexp quoting */
+ if (p[1] == '*')
+ {
+ if (p[2] == '=') /* 'operator\*=' */
+ *end = p + 3;
+ else /* 'operator\*' */
+ *end = p + 2;
+ return p;
+ }
+ else if (p[1] == '[')
+ {
+ if (p[2] == ']')
+ error ("mismatched quoting on brackets, try 'operator\\[\\]'");
+ else if (p[2] == '\\' && p[3] == ']')
+ {
+ *end = p + 4; /* 'operator\[\]' */
+ return p;
+ }
+ else
+ error ("nothing is allowed between '[' and ']'");
+ }
+ else
+ {
+ /* Gratuitous qoute: skip it and move on. */
+ p++;
+ continue;
+ }
+ break;
+ case '!':
+ case '=':
+ case '*':
+ case '/':
+ case '%':
+ case '^':
+ if (p[1] == '=')
+ *end = p + 2;
+ else
+ *end = p + 1;
+ return p;
+ case '<':
+ case '>':
+ case '+':
+ case '-':
+ case '&':
+ case '|':
+ if (p[0] == '-' && p[1] == '>')
+ {
+ /* Struct pointer member operator 'operator->'. */
+ if (p[2] == '*')
+ {
+ *end = p + 3; /* 'operator->*' */
+ return p;
+ }
+ else if (p[2] == '\\')
+ {
+ *end = p + 4; /* Hopefully 'operator->\*' */
+ return p;
+ }
+ else
+ {
+ *end = p + 2; /* 'operator->' */
+ return p;
+ }
+ }
+ if (p[1] == '=' || p[1] == p[0])
+ *end = p + 2;
+ else
+ *end = p + 1;
+ return p;
+ case '~':
+ case ',':
+ *end = p + 1;
+ return p;
+ case '(':
+ if (p[1] != ')')
+ error ("`operator ()' must be specified without whitespace in `()'");
+ *end = p + 2;
+ return p;
+ case '?':
+ if (p[1] != ':')
+ error ("`operator ?:' must be specified without whitespace in `?:'");
+ *end = p + 2;
+ return p;
+ case '[':
+ if (p[1] != ']')
+ error ("`operator []' must be specified without whitespace in `[]'");
+ *end = p + 2;
+ return p;
+ default:
+ error ("`operator %s' not supported", p);
+ break;
+ }
+
+ *end = "";
+ return *end;
+}
+
+
+/* If FILE is not already in the table of files, return zero;
+ otherwise return non-zero. Optionally add FILE to the table if ADD
+ is non-zero. If *FIRST is non-zero, forget the old table
+ contents. */
+static int
+filename_seen (const char *file, int add, int *first)
+{
+ /* Table of files seen so far. */
+ static const char **tab = NULL;
+ /* Allocated size of tab in elements.
+ Start with one 256-byte block (when using GNU malloc.c).
+ 24 is the malloc overhead when range checking is in effect. */
+ static int tab_alloc_size = (256 - 24) / sizeof (char *);
+ /* Current size of tab in elements. */
+ static int tab_cur_size;
+ const char **p;
+
+ if (*first)
+ {
+ if (tab == NULL)
+ tab = (const char **) xmalloc (tab_alloc_size * sizeof (*tab));
+ tab_cur_size = 0;
+ }
+
+ /* Is FILE in tab? */
+ for (p = tab; p < tab + tab_cur_size; p++)
+ if (strcmp (*p, file) == 0)
+ return 1;
+
+ /* No; maybe add it to tab. */
+ if (add)
+ {
+ if (tab_cur_size == tab_alloc_size)
+ {
+ tab_alloc_size *= 2;
+ tab = (const char **) xrealloc ((char *) tab,
+ tab_alloc_size * sizeof (*tab));
+ }
+ tab[tab_cur_size++] = file;
+ }
+
+ return 0;
+}
+
+/* Slave routine for sources_info. Force line breaks at ,'s.
+ NAME is the name to print and *FIRST is nonzero if this is the first
+ name printed. Set *FIRST to zero. */
+static void
+output_source_filename (char *name, int *first)
+{
+ /* Since a single source file can result in several partial symbol
+ tables, we need to avoid printing it more than once. Note: if
+ some of the psymtabs are read in and some are not, it gets
+ printed both under "Source files for which symbols have been
+ read" and "Source files for which symbols will be read in on
+ demand". I consider this a reasonable way to deal with the
+ situation. I'm not sure whether this can also happen for
+ symtabs; it doesn't hurt to check. */
+
+ /* Was NAME already seen? */
+ if (filename_seen (name, 1, first))
+ {
+ /* Yes; don't print it again. */
+ return;
+ }
+ /* No; print it and reset *FIRST. */
+ if (*first)
+ {
+ *first = 0;
+ }
+ else
+ {
+ printf_filtered (", ");
+ }
+
+ wrap_here ("");
+ fputs_filtered (name, gdb_stdout);
+}
+
+static void
+sources_info (char *ignore, int from_tty)
+{
+ register struct symtab *s;
+ register struct partial_symtab *ps;
+ register struct objfile *objfile;
+ int first;
+
+ if (!have_full_symbols () && !have_partial_symbols ())
+ {
+ error ("No symbol table is loaded. Use the \"file\" command.");
+ }
+
+ printf_filtered ("Source files for which symbols have been read in:\n\n");
+
+ first = 1;
+ ALL_SYMTABS (objfile, s)
+ {
+ output_source_filename (s->filename, &first);
+ }
+ printf_filtered ("\n\n");
+
+ printf_filtered ("Source files for which symbols will be read in on demand:\n\n");
+
+ first = 1;
+ ALL_PSYMTABS (objfile, ps)
+ {
+ if (!ps->readin)
+ {
+ output_source_filename (ps->filename, &first);
+ }
+ }
+ printf_filtered ("\n");
+}
+
+static int
+file_matches (char *file, char *files[], int nfiles)
+{
+ int i;
+
+ if (file != NULL && nfiles != 0)
+ {
+ for (i = 0; i < nfiles; i++)
+ {
+ if (strcmp (files[i], lbasename (file)) == 0)
+ return 1;
+ }
+ }
+ else if (nfiles == 0)
+ return 1;
+ return 0;
+}
+
+/* Free any memory associated with a search. */
+void
+free_search_symbols (struct symbol_search *symbols)
+{
+ struct symbol_search *p;
+ struct symbol_search *next;
+
+ for (p = symbols; p != NULL; p = next)
+ {
+ next = p->next;
+ xfree (p);
+ }
+}
+
+static void
+do_free_search_symbols_cleanup (void *symbols)
+{
+ free_search_symbols (symbols);
+}
+
+struct cleanup *
+make_cleanup_free_search_symbols (struct symbol_search *symbols)
+{
+ return make_cleanup (do_free_search_symbols_cleanup, symbols);
+}
+
+/* Helper function for sort_search_symbols and qsort. Can only
+ sort symbols, not minimal symbols. */
+static int
+compare_search_syms (const void *sa, const void *sb)
+{
+ struct symbol_search **sym_a = (struct symbol_search **) sa;
+ struct symbol_search **sym_b = (struct symbol_search **) sb;
+
+ return strcmp (SYMBOL_SOURCE_NAME ((*sym_a)->symbol),
+ SYMBOL_SOURCE_NAME ((*sym_b)->symbol));
+}
+
+/* Sort the ``nfound'' symbols in the list after prevtail. Leave
+ prevtail where it is, but update its next pointer to point to
+ the first of the sorted symbols. */
+static struct symbol_search *
+sort_search_symbols (struct symbol_search *prevtail, int nfound)
+{
+ struct symbol_search **symbols, *symp, *old_next;
+ int i;
+
+ symbols = (struct symbol_search **) xmalloc (sizeof (struct symbol_search *)
+ * nfound);
+ symp = prevtail->next;
+ for (i = 0; i < nfound; i++)
+ {
+ symbols[i] = symp;
+ symp = symp->next;
+ }
+ /* Generally NULL. */
+ old_next = symp;
+
+ qsort (symbols, nfound, sizeof (struct symbol_search *),
+ compare_search_syms);
+
+ symp = prevtail;
+ for (i = 0; i < nfound; i++)
+ {
+ symp->next = symbols[i];
+ symp = symp->next;
+ }
+ symp->next = old_next;
+
+ xfree (symbols);
+ return symp;
+}
+
+/* Search the symbol table for matches to the regular expression REGEXP,
+ returning the results in *MATCHES.
+
+ Only symbols of KIND are searched:
+ FUNCTIONS_NAMESPACE - search all functions
+ TYPES_NAMESPACE - search all type names
+ METHODS_NAMESPACE - search all methods NOT IMPLEMENTED
+ VARIABLES_NAMESPACE - search all symbols, excluding functions, type names,
+ and constants (enums)
+
+ free_search_symbols should be called when *MATCHES is no longer needed.
+
+ The results are sorted locally; each symtab's global and static blocks are
+ separately alphabetized.
+ */
+void
+search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
+ struct symbol_search **matches)
+{
+ register struct symtab *s;
+ register struct partial_symtab *ps;
+ register struct blockvector *bv;
+ struct blockvector *prev_bv = 0;
+ register struct block *b;
+ register int i = 0;
+ register int j;
+ register struct symbol *sym;
+ struct partial_symbol **psym;
+ struct objfile *objfile;
+ struct minimal_symbol *msymbol;
+ char *val;
+ int found_misc = 0;
+ static enum minimal_symbol_type types[]
+ =
+ {mst_data, mst_text, mst_abs, mst_unknown};
+ static enum minimal_symbol_type types2[]
+ =
+ {mst_bss, mst_file_text, mst_abs, mst_unknown};
+ static enum minimal_symbol_type types3[]
+ =
+ {mst_file_data, mst_solib_trampoline, mst_abs, mst_unknown};
+ static enum minimal_symbol_type types4[]
+ =
+ {mst_file_bss, mst_text, mst_abs, mst_unknown};
+ enum minimal_symbol_type ourtype;
+ enum minimal_symbol_type ourtype2;
+ enum minimal_symbol_type ourtype3;
+ enum minimal_symbol_type ourtype4;
+ struct symbol_search *sr;
+ struct symbol_search *psr;
+ struct symbol_search *tail;
+ struct cleanup *old_chain = NULL;
+
+ if (kind < VARIABLES_NAMESPACE)
+ error ("must search on specific namespace");
+
+ ourtype = types[(int) (kind - VARIABLES_NAMESPACE)];
+ ourtype2 = types2[(int) (kind - VARIABLES_NAMESPACE)];
+ ourtype3 = types3[(int) (kind - VARIABLES_NAMESPACE)];
+ ourtype4 = types4[(int) (kind - VARIABLES_NAMESPACE)];
+
+ sr = *matches = NULL;
+ tail = NULL;
+
+ if (regexp != NULL)
+ {
+ /* Make sure spacing is right for C++ operators.
+ This is just a courtesy to make the matching less sensitive
+ to how many spaces the user leaves between 'operator'
+ and <TYPENAME> or <OPERATOR>. */
+ char *opend;
+ char *opname = operator_chars (regexp, &opend);
+ if (*opname)
+ {
+ int fix = -1; /* -1 means ok; otherwise number of spaces needed. */
+ if (isalpha (*opname) || *opname == '_' || *opname == '$')
+ {
+ /* There should 1 space between 'operator' and 'TYPENAME'. */
+ if (opname[-1] != ' ' || opname[-2] == ' ')
+ fix = 1;
+ }
+ else
+ {
+ /* There should 0 spaces between 'operator' and 'OPERATOR'. */
+ if (opname[-1] == ' ')
+ fix = 0;
+ }
+ /* If wrong number of spaces, fix it. */
+ if (fix >= 0)
+ {
+ char *tmp = (char *) alloca (8 + fix + strlen (opname) + 1);
+ sprintf (tmp, "operator%.*s%s", fix, " ", opname);
+ regexp = tmp;
+ }
+ }
+
+ if (0 != (val = re_comp (regexp)))
+ error ("Invalid regexp (%s): %s", val, regexp);
+ }
+
+ /* Search through the partial symtabs *first* for all symbols
+ matching the regexp. That way we don't have to reproduce all of
+ the machinery below. */
+
+ ALL_PSYMTABS (objfile, ps)
+ {
+ struct partial_symbol **bound, **gbound, **sbound;
+ int keep_going = 1;
+
+ if (ps->readin)
+ continue;
+
+ gbound = objfile->global_psymbols.list + ps->globals_offset + ps->n_global_syms;
+ sbound = objfile->static_psymbols.list + ps->statics_offset + ps->n_static_syms;
+ bound = gbound;
+
+ /* Go through all of the symbols stored in a partial
+ symtab in one loop. */
+ psym = objfile->global_psymbols.list + ps->globals_offset;
+ while (keep_going)
+ {
+ if (psym >= bound)
+ {
+ if (bound == gbound && ps->n_static_syms != 0)
+ {
+ psym = objfile->static_psymbols.list + ps->statics_offset;
+ bound = sbound;
+ }
+ else
+ keep_going = 0;
+ continue;
+ }
+ else
+ {
+ QUIT;
+
+ /* If it would match (logic taken from loop below)
+ load the file and go on to the next one */
+ if (file_matches (ps->filename, files, nfiles)
+ && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (*psym))
+ && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
+ && SYMBOL_CLASS (*psym) != LOC_BLOCK)
+ || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK)
+ || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)
+ || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK))))
+ {
+ PSYMTAB_TO_SYMTAB (ps);
+ keep_going = 0;
+ }
+ }
+ psym++;
+ }
+ }
+
+ /* Here, we search through the minimal symbol tables for functions
+ and variables that match, and force their symbols to be read.
+ This is in particular necessary for demangled variable names,
+ which are no longer put into the partial symbol tables.
+ The symbol will then be found during the scan of symtabs below.
+
+ For functions, find_pc_symtab should succeed if we have debug info
+ for the function, for variables we have to call lookup_symbol
+ to determine if the variable has debug info.
+ If the lookup fails, set found_misc so that we will rescan to print
+ any matching symbols without debug info.
+ */
+
+ if (nfiles == 0 && (kind == VARIABLES_NAMESPACE || kind == FUNCTIONS_NAMESPACE))
+ {
+ ALL_MSYMBOLS (objfile, msymbol)
+ {
+ if (MSYMBOL_TYPE (msymbol) == ourtype ||
+ MSYMBOL_TYPE (msymbol) == ourtype2 ||
+ MSYMBOL_TYPE (msymbol) == ourtype3 ||
+ MSYMBOL_TYPE (msymbol) == ourtype4)
+ {
+ if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
+ {
+ if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)))
+ {
+ if (kind == FUNCTIONS_NAMESPACE
+ || lookup_symbol (SYMBOL_NAME (msymbol),
+ (struct block *) NULL,
+ VAR_NAMESPACE,
+ 0, (struct symtab **) NULL) == NULL)
+ found_misc = 1;
+ }
+ }
+ }
+ }
+ }
+
+ ALL_SYMTABS (objfile, s)
+ {
+ bv = BLOCKVECTOR (s);
+ /* Often many files share a blockvector.
+ Scan each blockvector only once so that
+ we don't get every symbol many times.
+ It happens that the first symtab in the list
+ for any given blockvector is the main file. */
+ if (bv != prev_bv)
+ for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
+ {
+ struct symbol_search *prevtail = tail;
+ int nfound = 0;
+ b = BLOCKVECTOR_BLOCK (bv, i);
+ for (j = 0; j < BLOCK_NSYMS (b); j++)
+ {
+ QUIT;
+ sym = BLOCK_SYM (b, j);
+ if (file_matches (s->filename, files, nfiles)
+ && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym))
+ && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (sym) != LOC_TYPEDEF
+ && SYMBOL_CLASS (sym) != LOC_BLOCK
+ && SYMBOL_CLASS (sym) != LOC_CONST)
+ || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK)
+ || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+ || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK))))
+ {
+ /* match */
+ psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
+ psr->block = i;
+ psr->symtab = s;
+ psr->symbol = sym;
+ psr->msymbol = NULL;
+ psr->next = NULL;
+ if (tail == NULL)
+ sr = psr;
+ else
+ tail->next = psr;
+ tail = psr;
+ nfound ++;
+ }
+ }
+ if (nfound > 0)
+ {
+ if (prevtail == NULL)
+ {
+ struct symbol_search dummy;
+
+ dummy.next = sr;
+ tail = sort_search_symbols (&dummy, nfound);
+ sr = dummy.next;
+
+ old_chain = make_cleanup_free_search_symbols (sr);
+ }
+ else
+ tail = sort_search_symbols (prevtail, nfound);
+ }
+ }
+ prev_bv = bv;
+ }
+
+ /* If there are no eyes, avoid all contact. I mean, if there are
+ no debug symbols, then print directly from the msymbol_vector. */
+
+ if (found_misc || kind != FUNCTIONS_NAMESPACE)
+ {
+ ALL_MSYMBOLS (objfile, msymbol)
+ {
+ if (MSYMBOL_TYPE (msymbol) == ourtype ||
+ MSYMBOL_TYPE (msymbol) == ourtype2 ||
+ MSYMBOL_TYPE (msymbol) == ourtype3 ||
+ MSYMBOL_TYPE (msymbol) == ourtype4)
+ {
+ if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
+ {
+ /* Functions: Look up by address. */
+ if (kind != FUNCTIONS_NAMESPACE ||
+ (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol))))
+ {
+ /* Variables/Absolutes: Look up by name */
+ if (lookup_symbol (SYMBOL_NAME (msymbol),
+ (struct block *) NULL, VAR_NAMESPACE,
+ 0, (struct symtab **) NULL) == NULL)
+ {
+ /* match */
+ psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
+ psr->block = i;
+ psr->msymbol = msymbol;
+ psr->symtab = NULL;
+ psr->symbol = NULL;
+ psr->next = NULL;
+ if (tail == NULL)
+ {
+ sr = psr;
+ old_chain = make_cleanup_free_search_symbols (sr);
+ }
+ else
+ tail->next = psr;
+ tail = psr;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ *matches = sr;
+ if (sr != NULL)
+ discard_cleanups (old_chain);
+}
+
+/* Helper function for symtab_symbol_info, this function uses
+ the data returned from search_symbols() to print information
+ regarding the match to gdb_stdout.
+ */
+static void
+print_symbol_info (namespace_enum kind, struct symtab *s, struct symbol *sym,
+ int block, char *last)
+{
+ if (last == NULL || strcmp (last, s->filename) != 0)
+ {
+ fputs_filtered ("\nFile ", gdb_stdout);
+ fputs_filtered (s->filename, gdb_stdout);
+ fputs_filtered (":\n", gdb_stdout);
+ }
+
+ if (kind != TYPES_NAMESPACE && block == STATIC_BLOCK)
+ printf_filtered ("static ");
+
+ /* Typedef that is not a C++ class */
+ if (kind == TYPES_NAMESPACE
+ && SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE)
+ typedef_print (SYMBOL_TYPE (sym), sym, gdb_stdout);
+ /* variable, func, or typedef-that-is-c++-class */
+ else if (kind < TYPES_NAMESPACE ||
+ (kind == TYPES_NAMESPACE &&
+ SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE))
+ {
+ type_print (SYMBOL_TYPE (sym),
+ (SYMBOL_CLASS (sym) == LOC_TYPEDEF
+ ? "" : SYMBOL_SOURCE_NAME (sym)),
+ gdb_stdout, 0);
+
+ printf_filtered (";\n");
+ }
+ else
+ {
+#if 0
+ /* Tiemann says: "info methods was never implemented." */
+ char *demangled_name;
+ c_type_print_base (TYPE_FN_FIELD_TYPE (t, block),
+ gdb_stdout, 0, 0);
+ c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (t, block),
+ gdb_stdout, 0);
+ if (TYPE_FN_FIELD_STUB (t, block))
+ check_stub_method (TYPE_DOMAIN_TYPE (type), j, block);
+ demangled_name =
+ cplus_demangle (TYPE_FN_FIELD_PHYSNAME (t, block),
+ DMGL_ANSI | DMGL_PARAMS);
+ if (demangled_name == NULL)
+ fprintf_filtered (stream, "<badly mangled name %s>",
+ TYPE_FN_FIELD_PHYSNAME (t, block));
+ else
+ {
+ fputs_filtered (demangled_name, stream);
+ xfree (demangled_name);
+ }
+#endif
+ }
+}
+
+/* This help function for symtab_symbol_info() prints information
+ for non-debugging symbols to gdb_stdout.
+ */
+static void
+print_msymbol_info (struct minimal_symbol *msymbol)
+{
+ char *tmp;
+
+ if (TARGET_ADDR_BIT <= 32)
+ tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
+ & (CORE_ADDR) 0xffffffff,
+ "08l");
+ else
+ tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
+ "016l");
+ printf_filtered ("%s %s\n",
+ tmp, SYMBOL_SOURCE_NAME (msymbol));
+}
+
+/* This is the guts of the commands "info functions", "info types", and
+ "info variables". It calls search_symbols to find all matches and then
+ print_[m]symbol_info to print out some useful information about the
+ matches.
+ */
+static void
+symtab_symbol_info (char *regexp, namespace_enum kind, int from_tty)
+{
+ static char *classnames[]
+ =
+ {"variable", "function", "type", "method"};
+ struct symbol_search *symbols;
+ struct symbol_search *p;
+ struct cleanup *old_chain;
+ char *last_filename = NULL;
+ int first = 1;
+
+ /* must make sure that if we're interrupted, symbols gets freed */
+ search_symbols (regexp, kind, 0, (char **) NULL, &symbols);
+ old_chain = make_cleanup_free_search_symbols (symbols);
+
+ printf_filtered (regexp
+ ? "All %ss matching regular expression \"%s\":\n"
+ : "All defined %ss:\n",
+ classnames[(int) (kind - VARIABLES_NAMESPACE)], regexp);
+
+ for (p = symbols; p != NULL; p = p->next)
+ {
+ QUIT;
+
+ if (p->msymbol != NULL)
+ {
+ if (first)
+ {
+ printf_filtered ("\nNon-debugging symbols:\n");
+ first = 0;
+ }
+ print_msymbol_info (p->msymbol);
+ }
+ else
+ {
+ print_symbol_info (kind,
+ p->symtab,
+ p->symbol,
+ p->block,
+ last_filename);
+ last_filename = p->symtab->filename;
+ }
+ }
+
+ do_cleanups (old_chain);
+}
+
+static void
+variables_info (char *regexp, int from_tty)
+{
+ symtab_symbol_info (regexp, VARIABLES_NAMESPACE, from_tty);
+}
+
+static void
+functions_info (char *regexp, int from_tty)
+{
+ symtab_symbol_info (regexp, FUNCTIONS_NAMESPACE, from_tty);
+}
+
+
+static void
+types_info (char *regexp, int from_tty)
+{
+ symtab_symbol_info (regexp, TYPES_NAMESPACE, from_tty);
+}
+
+#if 0
+/* Tiemann says: "info methods was never implemented." */
+static void
+methods_info (char *regexp)
+{
+ symtab_symbol_info (regexp, METHODS_NAMESPACE, 0, from_tty);
+}
+#endif /* 0 */
+
+/* Breakpoint all functions matching regular expression. */
+
+void
+rbreak_command_wrapper (char *regexp, int from_tty)
+{
+ rbreak_command (regexp, from_tty);
+}
+
+static void
+rbreak_command (char *regexp, int from_tty)
+{
+ struct symbol_search *ss;
+ struct symbol_search *p;
+ struct cleanup *old_chain;
+
+ search_symbols (regexp, FUNCTIONS_NAMESPACE, 0, (char **) NULL, &ss);
+ old_chain = make_cleanup_free_search_symbols (ss);
+
+ for (p = ss; p != NULL; p = p->next)
+ {
+ if (p->msymbol == NULL)
+ {
+ char *string = (char *) alloca (strlen (p->symtab->filename)
+ + strlen (SYMBOL_NAME (p->symbol))
+ + 4);
+ strcpy (string, p->symtab->filename);
+ strcat (string, ":'");
+ strcat (string, SYMBOL_NAME (p->symbol));
+ strcat (string, "'");
+ break_command (string, from_tty);
+ print_symbol_info (FUNCTIONS_NAMESPACE,
+ p->symtab,
+ p->symbol,
+ p->block,
+ p->symtab->filename);
+ }
+ else
+ {
+ break_command (SYMBOL_NAME (p->msymbol), from_tty);
+ printf_filtered ("<function, no debug info> %s;\n",
+ SYMBOL_SOURCE_NAME (p->msymbol));
+ }
+ }
+
+ do_cleanups (old_chain);
+}
+
+
+/* Return Nonzero if block a is lexically nested within block b,
+ or if a and b have the same pc range.
+ Return zero otherwise. */
+int
+contained_in (struct block *a, struct block *b)
+{
+ if (!a || !b)
+ return 0;
+ return BLOCK_START (a) >= BLOCK_START (b)
+ && BLOCK_END (a) <= BLOCK_END (b);
+}
+
+
+/* Helper routine for make_symbol_completion_list. */
+
+static int return_val_size;
+static int return_val_index;
+static char **return_val;
+
+#define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \
+ do { \
+ if (SYMBOL_DEMANGLED_NAME (symbol) != NULL) \
+ /* Put only the mangled name on the list. */ \
+ /* Advantage: "b foo<TAB>" completes to "b foo(int, int)" */ \
+ /* Disadvantage: "b foo__i<TAB>" doesn't complete. */ \
+ completion_list_add_name \
+ (SYMBOL_DEMANGLED_NAME (symbol), (sym_text), (len), (text), (word)); \
+ else \
+ completion_list_add_name \
+ (SYMBOL_NAME (symbol), (sym_text), (len), (text), (word)); \
+ } while (0)
+
+/* Test to see if the symbol specified by SYMNAME (which is already
+ demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
+ characters. If so, add it to the current completion list. */
+
+static void
+completion_list_add_name (char *symname, char *sym_text, int sym_text_len,
+ char *text, char *word)
+{
+ int newsize;
+ int i;
+
+ /* clip symbols that cannot match */
+
+ if (strncmp (symname, sym_text, sym_text_len) != 0)
+ {
+ return;
+ }
+
+ /* We have a match for a completion, so add SYMNAME to the current list
+ of matches. Note that the name is moved to freshly malloc'd space. */
+
+ {
+ char *new;
+ if (word == sym_text)
+ {
+ new = xmalloc (strlen (symname) + 5);
+ strcpy (new, symname);
+ }
+ else if (word > sym_text)
+ {
+ /* Return some portion of symname. */
+ new = xmalloc (strlen (symname) + 5);
+ strcpy (new, symname + (word - sym_text));
+ }
+ else
+ {
+ /* Return some of SYM_TEXT plus symname. */
+ new = xmalloc (strlen (symname) + (sym_text - word) + 5);
+ strncpy (new, word, sym_text - word);
+ new[sym_text - word] = '\0';
+ strcat (new, symname);
+ }
+
+ if (return_val_index + 3 > return_val_size)
+ {
+ newsize = (return_val_size *= 2) * sizeof (char *);
+ return_val = (char **) xrealloc ((char *) return_val, newsize);
+ }
+ return_val[return_val_index++] = new;
+ return_val[return_val_index] = NULL;
+ }
+}
+
+/* Return a NULL terminated array of all symbols (regardless of class)
+ which begin by matching TEXT. If the answer is no symbols, then
+ the return value is an array which contains only a NULL pointer.
+
+ Problem: All of the symbols have to be copied because readline frees them.
+ I'm not going to worry about this; hopefully there won't be that many. */
+
+char **
+make_symbol_completion_list (char *text, char *word)
+{
+ register struct symbol *sym;
+ register struct symtab *s;
+ register struct partial_symtab *ps;
+ register struct minimal_symbol *msymbol;
+ register struct objfile *objfile;
+ register struct block *b, *surrounding_static_block = 0;
+ register int i, j;
+ struct partial_symbol **psym;
+ /* The symbol we are completing on. Points in same buffer as text. */
+ char *sym_text;
+ /* Length of sym_text. */
+ int sym_text_len;
+
+ /* Now look for the symbol we are supposed to complete on.
+ FIXME: This should be language-specific. */
+ {
+ char *p;
+ char quote_found;
+ char *quote_pos = NULL;
+
+ /* First see if this is a quoted string. */
+ quote_found = '\0';
+ for (p = text; *p != '\0'; ++p)
+ {
+ if (quote_found != '\0')
+ {
+ if (*p == quote_found)
+ /* Found close quote. */
+ quote_found = '\0';
+ else if (*p == '\\' && p[1] == quote_found)
+ /* A backslash followed by the quote character
+ doesn't end the string. */
+ ++p;
+ }
+ else if (*p == '\'' || *p == '"')
+ {
+ quote_found = *p;
+ quote_pos = p;
+ }
+ }
+ if (quote_found == '\'')
+ /* A string within single quotes can be a symbol, so complete on it. */
+ sym_text = quote_pos + 1;
+ else if (quote_found == '"')
+ /* A double-quoted string is never a symbol, nor does it make sense
+ to complete it any other way. */
+ {
+ return_val = (char **) xmalloc (sizeof (char *));
+ return_val[0] = NULL;
+ return return_val;
+ }
+ else
+ {
+ /* It is not a quoted string. Break it based on the characters
+ which are in symbols. */
+ while (p > text)
+ {
+ if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
+ --p;
+ else
+ break;
+ }
+ sym_text = p;
+ }
+ }
+
+ sym_text_len = strlen (sym_text);
+
+ return_val_size = 100;
+ return_val_index = 0;
+ return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *));
+ return_val[0] = NULL;
+
+ /* Look through the partial symtabs for all symbols which begin
+ by matching SYM_TEXT. Add each one that you find to the list. */
+
+ ALL_PSYMTABS (objfile, ps)
+ {
+ /* If the psymtab's been read in we'll get it when we search
+ through the blockvector. */
+ if (ps->readin)
+ continue;
+
+ for (psym = objfile->global_psymbols.list + ps->globals_offset;
+ psym < (objfile->global_psymbols.list + ps->globals_offset
+ + ps->n_global_syms);
+ psym++)
+ {
+ /* If interrupted, then quit. */
+ QUIT;
+ COMPLETION_LIST_ADD_SYMBOL (*psym, sym_text, sym_text_len, text, word);
+ }
+
+ for (psym = objfile->static_psymbols.list + ps->statics_offset;
+ psym < (objfile->static_psymbols.list + ps->statics_offset
+ + ps->n_static_syms);
+ psym++)
+ {
+ QUIT;
+ COMPLETION_LIST_ADD_SYMBOL (*psym, sym_text, sym_text_len, text, word);
+ }
+ }
+
+ /* At this point scan through the misc symbol vectors and add each
+ symbol you find to the list. Eventually we want to ignore
+ anything that isn't a text symbol (everything else will be
+ handled by the psymtab code above). */
+
+ ALL_MSYMBOLS (objfile, msymbol)
+ {
+ QUIT;
+ COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, word);
+ }
+
+ /* Search upwards from currently selected frame (so that we can
+ complete on local vars. */
+
+ for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
+ {
+ if (!BLOCK_SUPERBLOCK (b))
+ {
+ surrounding_static_block = b; /* For elmin of dups */
+ }
+
+ /* Also catch fields of types defined in this places which match our
+ text string. Only complete on types visible from current context. */
+
+ ALL_BLOCK_SYMBOLS (b, i, sym)
+ {
+ COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+ if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+ {
+ struct type *t = SYMBOL_TYPE (sym);
+ enum type_code c = TYPE_CODE (t);
+
+ if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
+ {
+ for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
+ {
+ if (TYPE_FIELD_NAME (t, j))
+ {
+ completion_list_add_name (TYPE_FIELD_NAME (t, j),
+ sym_text, sym_text_len, text, word);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Go through the symtabs and check the externs and statics for
+ symbols which match. */
+
+ ALL_SYMTABS (objfile, s)
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+ ALL_BLOCK_SYMBOLS (b, i, sym)
+ {
+ COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+ }
+ }
+
+ ALL_SYMTABS (objfile, s)
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+ /* Don't do this block twice. */
+ if (b == surrounding_static_block)
+ continue;
+ ALL_BLOCK_SYMBOLS (b, i, sym)
+ {
+ COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+ }
+ }
+
+ return (return_val);
+}
+
+/* Like make_symbol_completion_list, but returns a list of symbols
+ defined in a source file FILE. */
+
+char **
+make_file_symbol_completion_list (char *text, char *word, char *srcfile)
+{
+ register struct symbol *sym;
+ register struct symtab *s;
+ register struct block *b;
+ register int i;
+ /* The symbol we are completing on. Points in same buffer as text. */
+ char *sym_text;
+ /* Length of sym_text. */
+ int sym_text_len;
+
+ /* Now look for the symbol we are supposed to complete on.
+ FIXME: This should be language-specific. */
+ {
+ char *p;
+ char quote_found;
+ char *quote_pos = NULL;
+
+ /* First see if this is a quoted string. */
+ quote_found = '\0';
+ for (p = text; *p != '\0'; ++p)
+ {
+ if (quote_found != '\0')
+ {
+ if (*p == quote_found)
+ /* Found close quote. */
+ quote_found = '\0';
+ else if (*p == '\\' && p[1] == quote_found)
+ /* A backslash followed by the quote character
+ doesn't end the string. */
+ ++p;
+ }
+ else if (*p == '\'' || *p == '"')
+ {
+ quote_found = *p;
+ quote_pos = p;
+ }
+ }
+ if (quote_found == '\'')
+ /* A string within single quotes can be a symbol, so complete on it. */
+ sym_text = quote_pos + 1;
+ else if (quote_found == '"')
+ /* A double-quoted string is never a symbol, nor does it make sense
+ to complete it any other way. */
+ {
+ return_val = (char **) xmalloc (sizeof (char *));
+ return_val[0] = NULL;
+ return return_val;
+ }
+ else
+ {
+ /* It is not a quoted string. Break it based on the characters
+ which are in symbols. */
+ while (p > text)
+ {
+ if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
+ --p;
+ else
+ break;
+ }
+ sym_text = p;
+ }
+ }
+
+ sym_text_len = strlen (sym_text);
+
+ return_val_size = 10;
+ return_val_index = 0;
+ return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *));
+ return_val[0] = NULL;
+
+ /* Find the symtab for SRCFILE (this loads it if it was not yet read
+ in). */
+ s = lookup_symtab (srcfile);
+ if (s == NULL)
+ {
+ /* Maybe they typed the file with leading directories, while the
+ symbol tables record only its basename. */
+ const char *tail = lbasename (srcfile);
+
+ if (tail > srcfile)
+ s = lookup_symtab (tail);
+ }
+
+ /* If we have no symtab for that file, return an empty list. */
+ if (s == NULL)
+ return (return_val);
+
+ /* Go through this symtab and check the externs and statics for
+ symbols which match. */
+
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+ ALL_BLOCK_SYMBOLS (b, i, sym)
+ {
+ COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+ }
+
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+ ALL_BLOCK_SYMBOLS (b, i, sym)
+ {
+ COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+ }
+
+ return (return_val);
+}
+
+/* A helper function for make_source_files_completion_list. It adds
+ another file name to a list of possible completions, growing the
+ list as necessary. */
+
+static void
+add_filename_to_list (const char *fname, char *text, char *word,
+ char ***list, int *list_used, int *list_alloced)
+{
+ char *new;
+ size_t fnlen = strlen (fname);
+
+ if (*list_used + 1 >= *list_alloced)
+ {
+ *list_alloced *= 2;
+ *list = (char **) xrealloc ((char *) *list,
+ *list_alloced * sizeof (char *));
+ }
+
+ if (word == text)
+ {
+ /* Return exactly fname. */
+ new = xmalloc (fnlen + 5);
+ strcpy (new, fname);
+ }
+ else if (word > text)
+ {
+ /* Return some portion of fname. */
+ new = xmalloc (fnlen + 5);
+ strcpy (new, fname + (word - text));
+ }
+ else
+ {
+ /* Return some of TEXT plus fname. */
+ new = xmalloc (fnlen + (text - word) + 5);
+ strncpy (new, word, text - word);
+ new[text - word] = '\0';
+ strcat (new, fname);
+ }
+ (*list)[*list_used] = new;
+ (*list)[++*list_used] = NULL;
+}
+
+static int
+not_interesting_fname (const char *fname)
+{
+ static const char *illegal_aliens[] = {
+ "_globals_", /* inserted by coff_symtab_read */
+ NULL
+ };
+ int i;
+
+ for (i = 0; illegal_aliens[i]; i++)
+ {
+ if (strcmp (fname, illegal_aliens[i]) == 0)
+ return 1;
+ }
+ return 0;
+}
+
+/* Return a NULL terminated array of all source files whose names
+ begin with matching TEXT. The file names are looked up in the
+ symbol tables of this program. If the answer is no matchess, then
+ the return value is an array which contains only a NULL pointer. */
+
+char **
+make_source_files_completion_list (char *text, char *word)
+{
+ register struct symtab *s;
+ register struct partial_symtab *ps;
+ register struct objfile *objfile;
+ int first = 1;
+ int list_alloced = 1;
+ int list_used = 0;
+ size_t text_len = strlen (text);
+ char **list = (char **) xmalloc (list_alloced * sizeof (char *));
+ const char *base_name;
+
+ list[0] = NULL;
+
+ if (!have_full_symbols () && !have_partial_symbols ())
+ return list;
+
+ ALL_SYMTABS (objfile, s)
+ {
+ if (not_interesting_fname (s->filename))
+ continue;
+ if (!filename_seen (s->filename, 1, &first)
+#if HAVE_DOS_BASED_FILE_SYSTEM
+ && strncasecmp (s->filename, text, text_len) == 0
+#else
+ && strncmp (s->filename, text, text_len) == 0
+#endif
+ )
+ {
+ /* This file matches for a completion; add it to the current
+ list of matches. */
+ add_filename_to_list (s->filename, text, word,
+ &list, &list_used, &list_alloced);
+ }
+ else
+ {
+ /* NOTE: We allow the user to type a base name when the
+ debug info records leading directories, but not the other
+ way around. This is what subroutines of breakpoint
+ command do when they parse file names. */
+ base_name = lbasename (s->filename);
+ if (base_name != s->filename
+ && !filename_seen (base_name, 1, &first)
+#if HAVE_DOS_BASED_FILE_SYSTEM
+ && strncasecmp (base_name, text, text_len) == 0
+#else
+ && strncmp (base_name, text, text_len) == 0
+#endif
+ )
+ add_filename_to_list (base_name, text, word,
+ &list, &list_used, &list_alloced);
+ }
+ }
+
+ ALL_PSYMTABS (objfile, ps)
+ {
+ if (not_interesting_fname (ps->filename))
+ continue;
+ if (!ps->readin)
+ {
+ if (!filename_seen (ps->filename, 1, &first)
+#if HAVE_DOS_BASED_FILE_SYSTEM
+ && strncasecmp (ps->filename, text, text_len) == 0
+#else
+ && strncmp (ps->filename, text, text_len) == 0
+#endif
+ )
+ {
+ /* This file matches for a completion; add it to the
+ current list of matches. */
+ add_filename_to_list (ps->filename, text, word,
+ &list, &list_used, &list_alloced);
+
+ }
+ else
+ {
+ base_name = lbasename (ps->filename);
+ if (base_name != ps->filename
+ && !filename_seen (base_name, 1, &first)
+#if HAVE_DOS_BASED_FILE_SYSTEM
+ && strncasecmp (base_name, text, text_len) == 0
+#else
+ && strncmp (base_name, text, text_len) == 0
+#endif
+ )
+ add_filename_to_list (base_name, text, word,
+ &list, &list_used, &list_alloced);
+ }
+ }
+ }
+
+ return list;
+}
+
+/* Determine if PC is in the prologue of a function. The prologue is the area
+ between the first instruction of a function, and the first executable line.
+ Returns 1 if PC *might* be in prologue, 0 if definately *not* in prologue.
+
+ If non-zero, func_start is where we think the prologue starts, possibly
+ by previous examination of symbol table information.
+ */
+
+int
+in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
+{
+ struct symtab_and_line sal;
+ CORE_ADDR func_addr, func_end;
+
+ /* We have several sources of information we can consult to figure
+ this out.
+ - Compilers usually emit line number info that marks the prologue
+ as its own "source line". So the ending address of that "line"
+ is the end of the prologue. If available, this is the most
+ reliable method.
+ - The minimal symbols and partial symbols, which can usually tell
+ us the starting and ending addresses of a function.
+ - If we know the function's start address, we can call the
+ architecture-defined SKIP_PROLOGUE function to analyze the
+ instruction stream and guess where the prologue ends.
+ - Our `func_start' argument; if non-zero, this is the caller's
+ best guess as to the function's entry point. At the time of
+ this writing, handle_inferior_event doesn't get this right, so
+ it should be our last resort. */
+
+ /* Consult the partial symbol table, to find which function
+ the PC is in. */
+ if (! find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ CORE_ADDR prologue_end;
+
+ /* We don't even have minsym information, so fall back to using
+ func_start, if given. */
+ if (! func_start)
+ return 1; /* We *might* be in a prologue. */
+
+ prologue_end = SKIP_PROLOGUE (func_start);
+
+ return func_start <= pc && pc < prologue_end;
+ }
+
+ /* If we have line number information for the function, that's
+ usually pretty reliable. */
+ sal = find_pc_line (func_addr, 0);
+
+ /* Now sal describes the source line at the function's entry point,
+ which (by convention) is the prologue. The end of that "line",
+ sal.end, is the end of the prologue.
+
+ Note that, for functions whose source code is all on a single
+ line, the line number information doesn't always end up this way.
+ So we must verify that our purported end-of-prologue address is
+ *within* the function, not at its start or end. */
+ if (sal.line == 0
+ || sal.end <= func_addr
+ || func_end <= sal.end)
+ {
+ /* We don't have any good line number info, so use the minsym
+ information, together with the architecture-specific prologue
+ scanning code. */
+ CORE_ADDR prologue_end = SKIP_PROLOGUE (func_addr);
+
+ return func_addr <= pc && pc < prologue_end;
+ }
+
+ /* We have line number info, and it looks good. */
+ return func_addr <= pc && pc < sal.end;
+}
+
+
+/* Begin overload resolution functions */
+/* Helper routine for make_symbol_completion_list. */
+
+static int sym_return_val_size;
+static int sym_return_val_index;
+static struct symbol **sym_return_val;
+
+/* Test to see if the symbol specified by SYMNAME (which is already
+ demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
+ characters. If so, add it to the current completion list. */
+
+static void
+overload_list_add_symbol (struct symbol *sym, char *oload_name)
+{
+ int newsize;
+ int i;
+
+ /* Get the demangled name without parameters */
+ char *sym_name = cplus_demangle (SYMBOL_NAME (sym), DMGL_ARM | DMGL_ANSI);
+ if (!sym_name)
+ {
+ sym_name = (char *) xmalloc (strlen (SYMBOL_NAME (sym)) + 1);
+ strcpy (sym_name, SYMBOL_NAME (sym));
+ }
+
+ /* skip symbols that cannot match */
+ if (strcmp (sym_name, oload_name) != 0)
+ {
+ xfree (sym_name);
+ return;
+ }
+
+ /* If there is no type information, we can't do anything, so skip */
+ if (SYMBOL_TYPE (sym) == NULL)
+ return;
+
+ /* skip any symbols that we've already considered. */
+ for (i = 0; i < sym_return_val_index; ++i)
+ if (!strcmp (SYMBOL_NAME (sym), SYMBOL_NAME (sym_return_val[i])))
+ return;
+
+ /* We have a match for an overload instance, so add SYM to the current list
+ * of overload instances */
+ if (sym_return_val_index + 3 > sym_return_val_size)
+ {
+ newsize = (sym_return_val_size *= 2) * sizeof (struct symbol *);
+ sym_return_val = (struct symbol **) xrealloc ((char *) sym_return_val, newsize);
+ }
+ sym_return_val[sym_return_val_index++] = sym;
+ sym_return_val[sym_return_val_index] = NULL;
+
+ xfree (sym_name);
+}
+
+/* Return a null-terminated list of pointers to function symbols that
+ * match name of the supplied symbol FSYM.
+ * This is used in finding all overloaded instances of a function name.
+ * This has been modified from make_symbol_completion_list. */
+
+
+struct symbol **
+make_symbol_overload_list (struct symbol *fsym)
+{
+ register struct symbol *sym;
+ register struct symtab *s;
+ register struct partial_symtab *ps;
+ register struct objfile *objfile;
+ register struct block *b, *surrounding_static_block = 0;
+ register int i;
+ /* The name we are completing on. */
+ char *oload_name = NULL;
+ /* Length of name. */
+ int oload_name_len = 0;
+
+ /* Look for the symbol we are supposed to complete on.
+ * FIXME: This should be language-specific. */
+
+ oload_name = cplus_demangle (SYMBOL_NAME (fsym), DMGL_ARM | DMGL_ANSI);
+ if (!oload_name)
+ {
+ oload_name = (char *) xmalloc (strlen (SYMBOL_NAME (fsym)) + 1);
+ strcpy (oload_name, SYMBOL_NAME (fsym));
+ }
+ oload_name_len = strlen (oload_name);
+
+ sym_return_val_size = 100;
+ sym_return_val_index = 0;
+ sym_return_val = (struct symbol **) xmalloc ((sym_return_val_size + 1) * sizeof (struct symbol *));
+ sym_return_val[0] = NULL;
+
+ /* Look through the partial symtabs for all symbols which begin
+ by matching OLOAD_NAME. Make sure we read that symbol table in. */
+
+ ALL_PSYMTABS (objfile, ps)
+ {
+ struct partial_symbol **psym;
+
+ /* If the psymtab's been read in we'll get it when we search
+ through the blockvector. */
+ if (ps->readin)
+ continue;
+
+ for (psym = objfile->global_psymbols.list + ps->globals_offset;
+ psym < (objfile->global_psymbols.list + ps->globals_offset
+ + ps->n_global_syms);
+ psym++)
+ {
+ /* If interrupted, then quit. */
+ QUIT;
+ /* This will cause the symbol table to be read if it has not yet been */
+ s = PSYMTAB_TO_SYMTAB (ps);
+ }
+
+ for (psym = objfile->static_psymbols.list + ps->statics_offset;
+ psym < (objfile->static_psymbols.list + ps->statics_offset
+ + ps->n_static_syms);
+ psym++)
+ {
+ QUIT;
+ /* This will cause the symbol table to be read if it has not yet been */
+ s = PSYMTAB_TO_SYMTAB (ps);
+ }
+ }
+
+ /* Search upwards from currently selected frame (so that we can
+ complete on local vars. */
+
+ for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
+ {
+ if (!BLOCK_SUPERBLOCK (b))
+ {
+ surrounding_static_block = b; /* For elimination of dups */
+ }
+
+ /* Also catch fields of types defined in this places which match our
+ text string. Only complete on types visible from current context. */
+
+ ALL_BLOCK_SYMBOLS (b, i, sym)
+ {
+ overload_list_add_symbol (sym, oload_name);
+ }
+ }
+
+ /* Go through the symtabs and check the externs and statics for
+ symbols which match. */
+
+ ALL_SYMTABS (objfile, s)
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+ ALL_BLOCK_SYMBOLS (b, i, sym)
+ {
+ overload_list_add_symbol (sym, oload_name);
+ }
+ }
+
+ ALL_SYMTABS (objfile, s)
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+ /* Don't do this block twice. */
+ if (b == surrounding_static_block)
+ continue;
+ ALL_BLOCK_SYMBOLS (b, i, sym)
+ {
+ overload_list_add_symbol (sym, oload_name);
+ }
+ }
+
+ xfree (oload_name);
+
+ return (sym_return_val);
+}
+
+/* End of overload resolution functions */
+
+struct symtabs_and_lines
+decode_line_spec (char *string, int funfirstline)
+{
+ struct symtabs_and_lines sals;
+ if (string == 0)
+ error ("Empty line specification.");
+ sals = decode_line_1 (&string, funfirstline,
+ current_source_symtab, current_source_line,
+ (char ***) NULL);
+ if (*string)
+ error ("Junk at end of line specification: %s", string);
+ return sals;
+}
+
+/* Track MAIN */
+static char *name_of_main;
+
+void
+set_main_name (const char *name)
+{
+ if (name_of_main != NULL)
+ {
+ xfree (name_of_main);
+ name_of_main = NULL;
+ }
+ if (name != NULL)
+ {
+ name_of_main = xstrdup (name);
+ }
+}
+
+char *
+main_name (void)
+{
+ if (name_of_main != NULL)
+ return name_of_main;
+ else
+ return "main";
+}
+
+
+void
+_initialize_symtab (void)
+{
+ add_info ("variables", variables_info,
+ "All global and static variable names, or those matching REGEXP.");
+ if (dbx_commands)
+ add_com ("whereis", class_info, variables_info,
+ "All global and static variable names, or those matching REGEXP.");
+
+ add_info ("functions", functions_info,
+ "All function names, or those matching REGEXP.");
+
+
+ /* FIXME: This command has at least the following problems:
+ 1. It prints builtin types (in a very strange and confusing fashion).
+ 2. It doesn't print right, e.g. with
+ typedef struct foo *FOO
+ type_print prints "FOO" when we want to make it (in this situation)
+ print "struct foo *".
+ I also think "ptype" or "whatis" is more likely to be useful (but if
+ there is much disagreement "info types" can be fixed). */
+ add_info ("types", types_info,
+ "All type names, or those matching REGEXP.");
+
+#if 0
+ add_info ("methods", methods_info,
+ "All method names, or those matching REGEXP::REGEXP.\n\
+If the class qualifier is omitted, it is assumed to be the current scope.\n\
+If the first REGEXP is omitted, then all methods matching the second REGEXP\n\
+are listed.");
+#endif
+ add_info ("sources", sources_info,
+ "Source files in the program.");
+
+ add_com ("rbreak", class_breakpoint, rbreak_command,
+ "Set a breakpoint for all functions matching REGEXP.");
+
+ if (xdb_commands)
+ {
+ add_com ("lf", class_info, sources_info, "Source files in the program");
+ add_com ("lg", class_info, variables_info,
+ "All global and static variable names, or those matching REGEXP.");
+ }
+
+ /* Initialize the one built-in type that isn't language dependent... */
+ builtin_type_error = init_type (TYPE_CODE_ERROR, 0, 0,
+ "<unknown type>", (struct objfile *) NULL);
+}
diff --git a/gdb/symtab.h b/gdb/symtab.h
new file mode 100644
index 00000000000..bb22d0d4eaa
--- /dev/null
+++ b/gdb/symtab.h
@@ -0,0 +1,1396 @@
+/* Symbol table definitions for GDB.
+ Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001
+ 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. */
+
+#if !defined (SYMTAB_H)
+#define SYMTAB_H 1
+
+/* Some definitions and declarations to go with use of obstacks. */
+
+#include "obstack.h"
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free xfree
+#include "bcache.h"
+
+/* Don't do this; it means that if some .o's are compiled with GNU C
+ and some are not (easy to do accidentally the way we configure
+ things; also it is a pain to have to "make clean" every time you
+ want to switch compilers), then GDB dies a horrible death. */
+/* GNU C supports enums that are bitfields. Some compilers don't. */
+#if 0 && defined(__GNUC__) && !defined(BYTE_BITFIELD)
+#define BYTE_BITFIELD :8;
+#else
+#define BYTE_BITFIELD /*nothing */
+#endif
+
+/* Define a structure for the information that is common to all symbol types,
+ including minimal symbols, partial symbols, and full symbols. In a
+ multilanguage environment, some language specific information may need to
+ be recorded along with each symbol.
+
+ These fields are ordered to encourage good packing, since we frequently
+ have tens or hundreds of thousands of these. */
+
+struct general_symbol_info
+ {
+ /* Name of the symbol. This is a required field. Storage for the name is
+ allocated on the psymbol_obstack or symbol_obstack for the associated
+ objfile. */
+
+ char *name;
+
+ /* Value of the symbol. Which member of this union to use, and what
+ it means, depends on what kind of symbol this is and its
+ SYMBOL_CLASS. See comments there for more details. All of these
+ are in host byte order (though what they point to might be in
+ target byte order, e.g. LOC_CONST_BYTES). */
+
+ union
+ {
+ /* The fact that this is a long not a LONGEST mainly limits the
+ range of a LOC_CONST. Since LOC_CONST_BYTES exists, I'm not
+ sure that is a big deal. */
+ long ivalue;
+
+ struct block *block;
+
+ char *bytes;
+
+ CORE_ADDR address;
+
+ /* for opaque typedef struct chain */
+
+ struct symbol *chain;
+ }
+ value;
+
+ /* Since one and only one language can apply, wrap the language specific
+ information inside a union. */
+
+ union
+ {
+ struct cplus_specific /* For C++ */
+ /* and Java */
+ {
+ char *demangled_name;
+ }
+ cplus_specific;
+ struct chill_specific /* For Chill */
+ {
+ char *demangled_name;
+ }
+ chill_specific;
+ }
+ language_specific;
+
+ /* Record the source code language that applies to this symbol.
+ This is used to select one of the fields from the language specific
+ union above. */
+
+ enum language language BYTE_BITFIELD;
+
+ /* Which section is this symbol in? This is an index into
+ section_offsets for this objfile. Negative means that the symbol
+ does not get relocated relative to a section.
+ Disclaimer: currently this is just used for xcoff, so don't
+ expect all symbol-reading code to set it correctly (the ELF code
+ also tries to set it correctly). */
+
+ short section;
+
+ /* The bfd section associated with this symbol. */
+
+ asection *bfd_section;
+ };
+
+extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, asection *);
+
+#define SYMBOL_NAME(symbol) (symbol)->ginfo.name
+#define SYMBOL_VALUE(symbol) (symbol)->ginfo.value.ivalue
+#define SYMBOL_VALUE_ADDRESS(symbol) (symbol)->ginfo.value.address
+#define SYMBOL_VALUE_BYTES(symbol) (symbol)->ginfo.value.bytes
+#define SYMBOL_BLOCK_VALUE(symbol) (symbol)->ginfo.value.block
+#define SYMBOL_VALUE_CHAIN(symbol) (symbol)->ginfo.value.chain
+#define SYMBOL_LANGUAGE(symbol) (symbol)->ginfo.language
+#define SYMBOL_SECTION(symbol) (symbol)->ginfo.section
+#define SYMBOL_BFD_SECTION(symbol) (symbol)->ginfo.bfd_section
+
+#define SYMBOL_CPLUS_DEMANGLED_NAME(symbol) \
+ (symbol)->ginfo.language_specific.cplus_specific.demangled_name
+
+/* Macro that initializes the language dependent portion of a symbol
+ depending upon the language for the symbol. */
+
+#define SYMBOL_INIT_LANGUAGE_SPECIFIC(symbol,language) \
+ do { \
+ SYMBOL_LANGUAGE (symbol) = language; \
+ if (SYMBOL_LANGUAGE (symbol) == language_cplus \
+ || SYMBOL_LANGUAGE (symbol) == language_java \
+ ) \
+ { \
+ SYMBOL_CPLUS_DEMANGLED_NAME (symbol) = NULL; \
+ } \
+ else if (SYMBOL_LANGUAGE (symbol) == language_chill) \
+ { \
+ SYMBOL_CHILL_DEMANGLED_NAME (symbol) = NULL; \
+ } \
+ else \
+ { \
+ memset (&(symbol)->ginfo.language_specific, 0, \
+ sizeof ((symbol)->ginfo.language_specific)); \
+ } \
+ } while (0)
+
+#define SYMBOL_INIT_DEMANGLED_NAME(symbol,obstack) \
+ (symbol_init_demangled_name (&symbol->ginfo, (obstack)))
+extern void symbol_init_demangled_name (struct general_symbol_info *symbol,
+ struct obstack *obstack);
+
+
+/* Macro that returns the demangled name for a symbol based on the language
+ for that symbol. If no demangled name exists, returns NULL. */
+
+#define SYMBOL_DEMANGLED_NAME(symbol) \
+ (SYMBOL_LANGUAGE (symbol) == language_cplus \
+ || SYMBOL_LANGUAGE (symbol) == language_java \
+ ? SYMBOL_CPLUS_DEMANGLED_NAME (symbol) \
+ : (SYMBOL_LANGUAGE (symbol) == language_chill \
+ ? SYMBOL_CHILL_DEMANGLED_NAME (symbol) \
+ : NULL))
+
+#define SYMBOL_CHILL_DEMANGLED_NAME(symbol) \
+ (symbol)->ginfo.language_specific.chill_specific.demangled_name
+
+/* Macro that returns the "natural source name" of a symbol. In C++ this is
+ the "demangled" form of the name if demangle is on and the "mangled" form
+ of the name if demangle is off. In other languages this is just the
+ symbol name. The result should never be NULL. */
+
+#define SYMBOL_SOURCE_NAME(symbol) \
+ (demangle && SYMBOL_DEMANGLED_NAME (symbol) != NULL \
+ ? SYMBOL_DEMANGLED_NAME (symbol) \
+ : SYMBOL_NAME (symbol))
+
+/* Macro that returns the "natural assembly name" of a symbol. In C++ this is
+ the "mangled" form of the name if demangle is off, or if demangle is on and
+ asm_demangle is off. Otherwise if asm_demangle is on it is the "demangled"
+ form. In other languages this is just the symbol name. The result should
+ never be NULL. */
+
+#define SYMBOL_LINKAGE_NAME(symbol) \
+ (demangle && asm_demangle && SYMBOL_DEMANGLED_NAME (symbol) != NULL \
+ ? SYMBOL_DEMANGLED_NAME (symbol) \
+ : SYMBOL_NAME (symbol))
+
+/* Macro that tests a symbol for a match against a specified name string.
+ First test the unencoded name, then looks for and test a C++ encoded
+ name if it exists. Note that whitespace is ignored while attempting to
+ match a C++ encoded name, so that "foo::bar(int,long)" is the same as
+ "foo :: bar (int, long)".
+ Evaluates to zero if the match fails, or nonzero if it succeeds. */
+
+#define SYMBOL_MATCHES_NAME(symbol, name) \
+ (STREQ (SYMBOL_NAME (symbol), (name)) \
+ || (SYMBOL_DEMANGLED_NAME (symbol) != NULL \
+ && strcmp_iw (SYMBOL_DEMANGLED_NAME (symbol), (name)) == 0))
+
+/* Macro that tests a symbol for an re-match against the last compiled regular
+ expression. First test the unencoded name, then look for and test a C++
+ encoded name if it exists.
+ Evaluates to zero if the match fails, or nonzero if it succeeds. */
+
+#define SYMBOL_MATCHES_REGEXP(symbol) \
+ (re_exec (SYMBOL_NAME (symbol)) != 0 \
+ || (SYMBOL_DEMANGLED_NAME (symbol) != NULL \
+ && re_exec (SYMBOL_DEMANGLED_NAME (symbol)) != 0))
+
+/* Define a simple structure used to hold some very basic information about
+ all defined global symbols (text, data, bss, abs, etc). The only required
+ information is the general_symbol_info.
+
+ In many cases, even if a file was compiled with no special options for
+ debugging at all, as long as was not stripped it will contain sufficient
+ information to build a useful minimal symbol table using this structure.
+ Even when a file contains enough debugging information to build a full
+ symbol table, these minimal symbols are still useful for quickly mapping
+ between names and addresses, and vice versa. They are also sometimes
+ used to figure out what full symbol table entries need to be read in. */
+
+struct minimal_symbol
+ {
+
+ /* The general symbol info required for all types of symbols.
+
+ The SYMBOL_VALUE_ADDRESS contains the address that this symbol
+ corresponds to. */
+
+ struct general_symbol_info ginfo;
+
+ /* The info field is available for caching machine-specific information
+ so it doesn't have to rederive the info constantly (over a serial line).
+ It is initialized to zero and stays that way until target-dependent code
+ sets it. Storage for any data pointed to by this field should be allo-
+ cated on the symbol_obstack for the associated objfile.
+ The type would be "void *" except for reasons of compatibility with older
+ compilers. This field is optional.
+
+ Currently, the AMD 29000 tdep.c uses it to remember things it has decoded
+ from the instructions in the function header, and the MIPS-16 code uses
+ it to identify 16-bit procedures. */
+
+ char *info;
+
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+ /* Which source file is this symbol in? Only relevant for mst_file_*. */
+ char *filename;
+#endif
+
+ /* Classification types for this symbol. These should be taken as "advisory
+ only", since if gdb can't easily figure out a classification it simply
+ selects mst_unknown. It may also have to guess when it can't figure out
+ which is a better match between two types (mst_data versus mst_bss) for
+ example. Since the minimal symbol info is sometimes derived from the
+ BFD library's view of a file, we need to live with what information bfd
+ supplies. */
+
+ enum minimal_symbol_type
+ {
+ mst_unknown = 0, /* Unknown type, the default */
+ mst_text, /* Generally executable instructions */
+ mst_data, /* Generally initialized data */
+ mst_bss, /* Generally uninitialized data */
+ mst_abs, /* Generally absolute (nonrelocatable) */
+ /* GDB uses mst_solib_trampoline for the start address of a shared
+ library trampoline entry. Breakpoints for shared library functions
+ are put there if the shared library is not yet loaded.
+ After the shared library is loaded, lookup_minimal_symbol will
+ prefer the minimal symbol from the shared library (usually
+ a mst_text symbol) over the mst_solib_trampoline symbol, and the
+ breakpoints will be moved to their true address in the shared
+ library via breakpoint_re_set. */
+ mst_solib_trampoline, /* Shared library trampoline code */
+ /* For the mst_file* types, the names are only guaranteed to be unique
+ within a given .o file. */
+ mst_file_text, /* Static version of mst_text */
+ mst_file_data, /* Static version of mst_data */
+ mst_file_bss /* Static version of mst_bss */
+ }
+ type BYTE_BITFIELD;
+
+ /* Minimal symbols with the same hash key are kept on a linked
+ list. This is the link. */
+
+ struct minimal_symbol *hash_next;
+
+ /* Minimal symbols are stored in two different hash tables. This is
+ the `next' pointer for the demangled hash table. */
+
+ struct minimal_symbol *demangled_hash_next;
+ };
+
+#define MSYMBOL_INFO(msymbol) (msymbol)->info
+#define MSYMBOL_TYPE(msymbol) (msymbol)->type
+
+
+
+/* All of the name-scope contours of the program
+ are represented by `struct block' objects.
+ All of these objects are pointed to by the blockvector.
+
+ Each block represents one name scope.
+ Each lexical context has its own block.
+
+ The blockvector begins with some special blocks.
+ The GLOBAL_BLOCK contains all the symbols defined in this compilation
+ whose scope is the entire program linked together.
+ The STATIC_BLOCK contains all the symbols whose scope is the
+ entire compilation excluding other separate compilations.
+ Blocks starting with the FIRST_LOCAL_BLOCK are not special.
+
+ Each block records a range of core addresses for the code that
+ is in the scope of the block. The STATIC_BLOCK and GLOBAL_BLOCK
+ give, for the range of code, the entire range of code produced
+ by the compilation that the symbol segment belongs to.
+
+ The blocks appear in the blockvector
+ in order of increasing starting-address,
+ and, within that, in order of decreasing ending-address.
+
+ This implies that within the body of one function
+ the blocks appear in the order of a depth-first tree walk. */
+
+struct blockvector
+ {
+ /* Number of blocks in the list. */
+ int nblocks;
+ /* The blocks themselves. */
+ struct block *block[1];
+ };
+
+#define BLOCKVECTOR_NBLOCKS(blocklist) (blocklist)->nblocks
+#define BLOCKVECTOR_BLOCK(blocklist,n) (blocklist)->block[n]
+
+/* Special block numbers */
+
+#define GLOBAL_BLOCK 0
+#define STATIC_BLOCK 1
+#define FIRST_LOCAL_BLOCK 2
+
+struct block
+ {
+
+ /* Addresses in the executable code that are in this block. */
+
+ CORE_ADDR startaddr;
+ CORE_ADDR endaddr;
+
+ /* The symbol that names this block, if the block is the body of a
+ function; otherwise, zero. */
+
+ struct symbol *function;
+
+ /* The `struct block' for the containing block, or 0 if none.
+
+ The superblock of a top-level local block (i.e. a function in the
+ case of C) is the STATIC_BLOCK. The superblock of the
+ STATIC_BLOCK is the GLOBAL_BLOCK. */
+
+ struct block *superblock;
+
+ /* Version of GCC used to compile the function corresponding
+ to this block, or 0 if not compiled with GCC. When possible,
+ GCC should be compatible with the native compiler, or if that
+ is not feasible, the differences should be fixed during symbol
+ reading. As of 16 Apr 93, this flag is never used to distinguish
+ between gcc2 and the native compiler.
+
+ If there is no function corresponding to this block, this meaning
+ of this flag is undefined. */
+
+ unsigned char gcc_compile_flag;
+
+ /* Number of local symbols. */
+
+ int nsyms;
+
+ /* The symbols. If some of them are arguments, then they must be
+ in the order in which we would like to print them. */
+
+ struct symbol *sym[1];
+ };
+
+#define BLOCK_START(bl) (bl)->startaddr
+#define BLOCK_END(bl) (bl)->endaddr
+#define BLOCK_NSYMS(bl) (bl)->nsyms
+#define BLOCK_SYM(bl, n) (bl)->sym[n]
+#define BLOCK_FUNCTION(bl) (bl)->function
+#define BLOCK_SUPERBLOCK(bl) (bl)->superblock
+#define BLOCK_GCC_COMPILED(bl) (bl)->gcc_compile_flag
+
+/* Macro to loop through all symbols in a block BL.
+ i counts which symbol we are looking at, and sym points to the current
+ symbol.
+ The contortion at the end is to avoid reading past the last valid
+ BLOCK_SYM. */
+#define ALL_BLOCK_SYMBOLS(bl, i, sym) \
+ for ((i) = 0, (sym) = BLOCK_SYM ((bl), (i)); \
+ (i) < BLOCK_NSYMS ((bl)); \
+ ++(i), (sym) = ((i) < BLOCK_NSYMS ((bl))) \
+ ? BLOCK_SYM ((bl), (i)) \
+ : NULL)
+
+/* Nonzero if symbols of block BL should be sorted alphabetically.
+ Don't sort a block which corresponds to a function. If we did the
+ sorting would have to preserve the order of the symbols for the
+ arguments. */
+
+#define BLOCK_SHOULD_SORT(bl) ((bl)->nsyms >= 40 && BLOCK_FUNCTION (bl) == NULL)
+
+
+/* Represent one symbol name; a variable, constant, function or typedef. */
+
+/* Different name spaces for symbols. Looking up a symbol specifies a
+ namespace and ignores symbol definitions in other name spaces. */
+
+typedef enum
+ {
+ /* UNDEF_NAMESPACE is used when a namespace has not been discovered or
+ none of the following apply. This usually indicates an error either
+ in the symbol information or in gdb's handling of symbols. */
+
+ UNDEF_NAMESPACE,
+
+ /* VAR_NAMESPACE is the usual namespace. In C, this contains variables,
+ function names, typedef names and enum type values. */
+
+ VAR_NAMESPACE,
+
+ /* STRUCT_NAMESPACE is used in C to hold struct, union and enum type names.
+ Thus, if `struct foo' is used in a C program, it produces a symbol named
+ `foo' in the STRUCT_NAMESPACE. */
+
+ STRUCT_NAMESPACE,
+
+ /* LABEL_NAMESPACE may be used for names of labels (for gotos);
+ currently it is not used and labels are not recorded at all. */
+
+ LABEL_NAMESPACE,
+
+ /* Searching namespaces. These overlap with VAR_NAMESPACE, providing
+ some granularity with the search_symbols function. */
+
+ /* Everything in VAR_NAMESPACE minus FUNCTIONS_-, TYPES_-, and
+ METHODS_NAMESPACE */
+ VARIABLES_NAMESPACE,
+
+ /* All functions -- for some reason not methods, though. */
+ FUNCTIONS_NAMESPACE,
+
+ /* All defined types */
+ TYPES_NAMESPACE,
+
+ /* All class methods -- why is this separated out? */
+ METHODS_NAMESPACE
+
+ }
+namespace_enum;
+
+/* An address-class says where to find the value of a symbol. */
+
+enum address_class
+ {
+ /* Not used; catches errors */
+
+ LOC_UNDEF,
+
+ /* Value is constant int SYMBOL_VALUE, host byteorder */
+
+ LOC_CONST,
+
+ /* Value is at fixed address SYMBOL_VALUE_ADDRESS */
+
+ LOC_STATIC,
+
+ /* Value is in register. SYMBOL_VALUE is the register number. */
+
+ LOC_REGISTER,
+
+ /* It's an argument; the value is at SYMBOL_VALUE offset in arglist. */
+
+ LOC_ARG,
+
+ /* Value address is at SYMBOL_VALUE offset in arglist. */
+
+ LOC_REF_ARG,
+
+ /* Value is in register number SYMBOL_VALUE. Just like LOC_REGISTER
+ except this is an argument. Probably the cleaner way to handle
+ this would be to separate address_class (which would include
+ separate ARG and LOCAL to deal with FRAME_ARGS_ADDRESS versus
+ FRAME_LOCALS_ADDRESS), and an is_argument flag.
+
+ For some symbol formats (stabs, for some compilers at least),
+ the compiler generates two symbols, an argument and a register.
+ In some cases we combine them to a single LOC_REGPARM in symbol
+ reading, but currently not for all cases (e.g. it's passed on the
+ stack and then loaded into a register). */
+
+ LOC_REGPARM,
+
+ /* Value is in specified register. Just like LOC_REGPARM except the
+ register holds the address of the argument instead of the argument
+ itself. This is currently used for the passing of structs and unions
+ on sparc and hppa. It is also used for call by reference where the
+ address is in a register, at least by mipsread.c. */
+
+ LOC_REGPARM_ADDR,
+
+ /* Value is a local variable at SYMBOL_VALUE offset in stack frame. */
+
+ LOC_LOCAL,
+
+ /* Value not used; definition in SYMBOL_TYPE. Symbols in the namespace
+ STRUCT_NAMESPACE all have this class. */
+
+ LOC_TYPEDEF,
+
+ /* Value is address SYMBOL_VALUE_ADDRESS in the code */
+
+ LOC_LABEL,
+
+ /* In a symbol table, value is SYMBOL_BLOCK_VALUE of a `struct block'.
+ In a partial symbol table, SYMBOL_VALUE_ADDRESS is the start address
+ of the block. Function names have this class. */
+
+ LOC_BLOCK,
+
+ /* Value is a constant byte-sequence pointed to by SYMBOL_VALUE_BYTES, in
+ target byte order. */
+
+ LOC_CONST_BYTES,
+
+ /* Value is arg at SYMBOL_VALUE offset in stack frame. Differs from
+ LOC_LOCAL in that symbol is an argument; differs from LOC_ARG in
+ that we find it in the frame (FRAME_LOCALS_ADDRESS), not in the
+ arglist (FRAME_ARGS_ADDRESS). Added for i960, which passes args
+ in regs then copies to frame. */
+
+ LOC_LOCAL_ARG,
+
+ /* Value is at SYMBOL_VALUE offset from the current value of
+ register number SYMBOL_BASEREG. This exists mainly for the same
+ things that LOC_LOCAL and LOC_ARG do; but we need to do this
+ instead because on 88k DWARF gives us the offset from the
+ frame/stack pointer, rather than the offset from the "canonical
+ frame address" used by COFF, stabs, etc., and we don't know how
+ to convert between these until we start examining prologues.
+
+ Note that LOC_BASEREG is much less general than a DWARF expression.
+ We don't need the generality (at least not yet), and storing a general
+ DWARF expression would presumably take up more space than the existing
+ scheme. */
+
+ LOC_BASEREG,
+
+ /* Same as LOC_BASEREG but it is an argument. */
+
+ LOC_BASEREG_ARG,
+
+ /* Value is at fixed address, but the address of the variable has
+ to be determined from the minimal symbol table whenever the
+ variable is referenced.
+ This happens if debugging information for a global symbol is
+ emitted and the corresponding minimal symbol is defined
+ in another object file or runtime common storage.
+ The linker might even remove the minimal symbol if the global
+ symbol is never referenced, in which case the symbol remains
+ unresolved. */
+
+ LOC_UNRESOLVED,
+
+ /* Value is at a thread-specific location calculated by a
+ target-specific method. */
+
+ LOC_THREAD_LOCAL_STATIC,
+
+ /* The variable does not actually exist in the program.
+ The value is ignored. */
+
+ LOC_OPTIMIZED_OUT,
+
+ /* The variable is static, but actually lives at * (address).
+ * I.e. do an extra indirection to get to it.
+ * This is used on HP-UX to get at globals that are allocated
+ * in shared libraries, where references from images other
+ * than the one where the global was allocated are done
+ * with a level of indirection.
+ */
+
+ LOC_INDIRECT
+
+ };
+
+/* Linked list of symbol's live ranges. */
+
+struct range_list
+ {
+ CORE_ADDR start;
+ CORE_ADDR end;
+ struct range_list *next;
+ };
+
+/* Linked list of aliases for a particular main/primary symbol. */
+struct alias_list
+ {
+ struct symbol *sym;
+ struct alias_list *next;
+ };
+
+struct symbol
+ {
+
+ /* The general symbol info required for all types of symbols. */
+
+ struct general_symbol_info ginfo;
+
+ /* Data type of value */
+
+ struct type *type;
+
+ /* Name space code. */
+
+#ifdef __MFC4__
+ /* FIXME: don't conflict with C++'s namespace */
+ /* would be safer to do a global change for all namespace identifiers. */
+#define namespace _namespace
+#endif
+ namespace_enum namespace BYTE_BITFIELD;
+
+ /* Address class */
+
+ enum address_class aclass BYTE_BITFIELD;
+
+ /* Line number of definition. FIXME: Should we really make the assumption
+ that nobody will try to debug files longer than 64K lines? What about
+ machine generated programs? */
+
+ unsigned short line;
+
+ /* Some symbols require an additional value to be recorded on a per-
+ symbol basis. Stash those values here. */
+
+ union
+ {
+ /* Used by LOC_BASEREG and LOC_BASEREG_ARG. */
+ short basereg;
+ }
+ aux_value;
+
+
+ /* Link to a list of aliases for this symbol.
+ Only a "primary/main symbol may have aliases. */
+ struct alias_list *aliases;
+
+ /* List of ranges where this symbol is active. This is only
+ used by alias symbols at the current time. */
+ struct range_list *ranges;
+ };
+
+
+#define SYMBOL_NAMESPACE(symbol) (symbol)->namespace
+#define SYMBOL_CLASS(symbol) (symbol)->aclass
+#define SYMBOL_TYPE(symbol) (symbol)->type
+#define SYMBOL_LINE(symbol) (symbol)->line
+#define SYMBOL_BASEREG(symbol) (symbol)->aux_value.basereg
+#define SYMBOL_ALIASES(symbol) (symbol)->aliases
+#define SYMBOL_RANGES(symbol) (symbol)->ranges
+
+/* A partial_symbol records the name, namespace, and address class of
+ symbols whose types we have not parsed yet. For functions, it also
+ contains their memory address, so we can find them from a PC value.
+ Each partial_symbol sits in a partial_symtab, all of which are chained
+ on a partial symtab list and which points to the corresponding
+ normal symtab once the partial_symtab has been referenced. */
+
+struct partial_symbol
+ {
+
+ /* The general symbol info required for all types of symbols. */
+
+ struct general_symbol_info ginfo;
+
+ /* Name space code. */
+
+ namespace_enum namespace BYTE_BITFIELD;
+
+ /* Address class (for info_symbols) */
+
+ enum address_class aclass BYTE_BITFIELD;
+
+ };
+
+#define PSYMBOL_NAMESPACE(psymbol) (psymbol)->namespace
+#define PSYMBOL_CLASS(psymbol) (psymbol)->aclass
+
+
+/* Source-file information. This describes the relation between source files,
+ line numbers and addresses in the program text. */
+
+struct sourcevector
+ {
+ int length; /* Number of source files described */
+ struct source *source[1]; /* Descriptions of the files */
+ };
+
+/* Each item represents a line-->pc (or the reverse) mapping. This is
+ somewhat more wasteful of space than one might wish, but since only
+ the files which are actually debugged are read in to core, we don't
+ waste much space. */
+
+struct linetable_entry
+ {
+ int line;
+ CORE_ADDR pc;
+ };
+
+/* The order of entries in the linetable is significant. They should
+ be sorted by increasing values of the pc field. If there is more than
+ one entry for a given pc, then I'm not sure what should happen (and
+ I not sure whether we currently handle it the best way).
+
+ Example: a C for statement generally looks like this
+
+ 10 0x100 - for the init/test part of a for stmt.
+ 20 0x200
+ 30 0x300
+ 10 0x400 - for the increment part of a for stmt.
+
+ If an entry has a line number of zero, it marks the start of a PC
+ range for which no line number information is available. It is
+ acceptable, though wasteful of table space, for such a range to be
+ zero length. */
+
+struct linetable
+ {
+ int nitems;
+
+ /* Actually NITEMS elements. If you don't like this use of the
+ `struct hack', you can shove it up your ANSI (seriously, if the
+ committee tells us how to do it, we can probably go along). */
+ struct linetable_entry item[1];
+ };
+
+/* All the information on one source file. */
+
+struct source
+ {
+ char *name; /* Name of file */
+ struct linetable contents;
+ };
+
+/* How to relocate the symbols from each section in a symbol file.
+ Each struct contains an array of offsets.
+ The ordering and meaning of the offsets is file-type-dependent;
+ typically it is indexed by section numbers or symbol types or
+ something like that.
+
+ To give us flexibility in changing the internal representation
+ of these offsets, the ANOFFSET macro must be used to insert and
+ extract offset values in the struct. */
+
+struct section_offsets
+ {
+ CORE_ADDR offsets[1]; /* As many as needed. */
+ };
+
+#define ANOFFSET(secoff, whichone) \
+ ((whichone == -1) \
+ ? (internal_error (__FILE__, __LINE__, "Section index is uninitialized"), -1) \
+ : secoff->offsets[whichone])
+
+/* The maximum possible size of a section_offsets table. */
+
+#define SIZEOF_SECTION_OFFSETS \
+ (sizeof (struct section_offsets) \
+ + sizeof (((struct section_offsets *) 0)->offsets) * (SECT_OFF_MAX-1))
+
+/* Each source file or header is represented by a struct symtab.
+ These objects are chained through the `next' field. */
+
+struct symtab
+ {
+
+ /* Chain of all existing symtabs. */
+
+ struct symtab *next;
+
+ /* List of all symbol scope blocks for this symtab. May be shared
+ between different symtabs (and normally is for all the symtabs
+ in a given compilation unit). */
+
+ struct blockvector *blockvector;
+
+ /* Table mapping core addresses to line numbers for this file.
+ Can be NULL if none. Never shared between different symtabs. */
+
+ struct linetable *linetable;
+
+ /* Section in objfile->section_offsets for the blockvector and
+ the linetable. Probably always SECT_OFF_TEXT. */
+
+ int block_line_section;
+
+ /* If several symtabs share a blockvector, exactly one of them
+ should be designated the primary, so that the blockvector
+ is relocated exactly once by objfile_relocate. */
+
+ int primary;
+
+ /* The macro table for this symtab. Like the blockvector, this
+ may be shared between different symtabs --- and normally is for
+ all the symtabs in a given compilation unit. */
+ struct macro_table *macro_table;
+
+ /* Name of this source file. */
+
+ char *filename;
+
+ /* Directory in which it was compiled, or NULL if we don't know. */
+
+ char *dirname;
+
+ /* This component says how to free the data we point to:
+ free_contents => do a tree walk and free each object.
+ free_nothing => do nothing; some other symtab will free
+ the data this one uses.
+ free_linetable => free just the linetable. FIXME: Is this redundant
+ with the primary field? */
+
+ enum free_code
+ {
+ free_nothing, free_contents, free_linetable
+ }
+ free_code;
+
+ /* Pointer to one block of storage to be freed, if nonzero. */
+ /* This is IN ADDITION to the action indicated by free_code. */
+
+ char *free_ptr;
+
+ /* Total number of lines found in source file. */
+
+ int nlines;
+
+ /* line_charpos[N] is the position of the (N-1)th line of the
+ source file. "position" means something we can lseek() to; it
+ is not guaranteed to be useful any other way. */
+
+ int *line_charpos;
+
+ /* Language of this source file. */
+
+ enum language language;
+
+ /* String that identifies the format of the debugging information, such
+ as "stabs", "dwarf 1", "dwarf 2", "coff", etc. This is mostly useful
+ for automated testing of gdb but may also be information that is
+ useful to the user. */
+
+ char *debugformat;
+
+ /* String of version information. May be zero. */
+
+ char *version;
+
+ /* Full name of file as found by searching the source path.
+ NULL if not yet known. */
+
+ char *fullname;
+
+ /* Object file from which this symbol information was read. */
+
+ struct objfile *objfile;
+
+ };
+
+#define BLOCKVECTOR(symtab) (symtab)->blockvector
+#define LINETABLE(symtab) (symtab)->linetable
+
+
+/* Each source file that has not been fully read in is represented by
+ a partial_symtab. This contains the information on where in the
+ executable the debugging symbols for a specific file are, and a
+ list of names of global symbols which are located in this file.
+ They are all chained on partial symtab lists.
+
+ Even after the source file has been read into a symtab, the
+ partial_symtab remains around. They are allocated on an obstack,
+ psymbol_obstack. FIXME, this is bad for dynamic linking or VxWorks-
+ style execution of a bunch of .o's. */
+
+struct partial_symtab
+ {
+
+ /* Chain of all existing partial symtabs. */
+
+ struct partial_symtab *next;
+
+ /* Name of the source file which this partial_symtab defines */
+
+ char *filename;
+
+ /* Full path of the source file. NULL if not known. */
+
+ char *fullname;
+
+ /* Information about the object file from which symbols should be read. */
+
+ struct objfile *objfile;
+
+ /* Set of relocation offsets to apply to each section. */
+
+ struct section_offsets *section_offsets;
+
+ /* Range of text addresses covered by this file; texthigh is the
+ beginning of the next section. */
+
+ CORE_ADDR textlow;
+ CORE_ADDR texthigh;
+
+ /* Array of pointers to all of the partial_symtab's which this one
+ depends on. Since this array can only be set to previous or
+ the current (?) psymtab, this dependency tree is guaranteed not
+ to have any loops. "depends on" means that symbols must be read
+ for the dependencies before being read for this psymtab; this is
+ for type references in stabs, where if foo.c includes foo.h, declarations
+ in foo.h may use type numbers defined in foo.c. For other debugging
+ formats there may be no need to use dependencies. */
+
+ struct partial_symtab **dependencies;
+
+ int number_of_dependencies;
+
+ /* Global symbol list. This list will be sorted after readin to
+ improve access. Binary search will be the usual method of
+ finding a symbol within it. globals_offset is an integer offset
+ within global_psymbols[]. */
+
+ int globals_offset;
+ int n_global_syms;
+
+ /* Static symbol list. This list will *not* be sorted after readin;
+ to find a symbol in it, exhaustive search must be used. This is
+ reasonable because searches through this list will eventually
+ lead to either the read in of a files symbols for real (assumed
+ to take a *lot* of time; check) or an error (and we don't care
+ how long errors take). This is an offset and size within
+ static_psymbols[]. */
+
+ int statics_offset;
+ int n_static_syms;
+
+ /* Pointer to symtab eventually allocated for this source file, 0 if
+ !readin or if we haven't looked for the symtab after it was readin. */
+
+ struct symtab *symtab;
+
+ /* Pointer to function which will read in the symtab corresponding to
+ this psymtab. */
+
+ void (*read_symtab) (struct partial_symtab *);
+
+ /* Information that lets read_symtab() locate the part of the symbol table
+ that this psymtab corresponds to. This information is private to the
+ format-dependent symbol reading routines. For further detail examine
+ the various symbol reading modules. Should really be (void *) but is
+ (char *) as with other such gdb variables. (FIXME) */
+
+ char *read_symtab_private;
+
+ /* Non-zero if the symtab corresponding to this psymtab has been readin */
+
+ unsigned char readin;
+ };
+
+/* A fast way to get from a psymtab to its symtab (after the first time). */
+#define PSYMTAB_TO_SYMTAB(pst) \
+ ((pst) -> symtab != NULL ? (pst) -> symtab : psymtab_to_symtab (pst))
+
+
+/* The virtual function table is now an array of structures which have the
+ form { int16 offset, delta; void *pfn; }.
+
+ In normal virtual function tables, OFFSET is unused.
+ DELTA is the amount which is added to the apparent object's base
+ address in order to point to the actual object to which the
+ virtual function should be applied.
+ PFN is a pointer to the virtual function.
+
+ Note that this macro is g++ specific (FIXME). */
+
+#define VTBL_FNADDR_OFFSET 2
+
+/* External variables and functions for the objects described above. */
+
+/* This symtab variable specifies the current file for printing source lines */
+
+extern struct symtab *current_source_symtab;
+
+/* This is the next line to print for listing source lines. */
+
+extern int current_source_line;
+
+/* See the comment in symfile.c about how current_objfile is used. */
+
+extern struct objfile *current_objfile;
+
+/* True if we are nested inside psymtab_to_symtab. */
+
+extern int currently_reading_symtab;
+
+/* From utils.c. */
+extern int demangle;
+extern int asm_demangle;
+
+/* symtab.c lookup functions */
+
+/* lookup a symbol table by source file name */
+
+extern struct symtab *lookup_symtab (const char *);
+
+/* lookup a symbol by name (optional block, optional symtab) */
+
+extern struct symbol *lookup_symbol (const char *, const struct block *,
+ const namespace_enum, int *,
+ struct symtab **);
+
+/* lookup a symbol by name, within a specified block */
+
+extern struct symbol *lookup_block_symbol (const struct block *, const char *,
+ const char *,
+ const namespace_enum);
+
+/* lookup a [struct, union, enum] by name, within a specified block */
+
+extern struct type *lookup_struct (char *, struct block *);
+
+extern struct type *lookup_union (char *, struct block *);
+
+extern struct type *lookup_enum (char *, struct block *);
+
+/* lookup the function corresponding to the block */
+
+extern struct symbol *block_function (struct block *);
+
+/* from blockframe.c: */
+
+/* lookup the function symbol corresponding to the address */
+
+extern struct symbol *find_pc_function (CORE_ADDR);
+
+/* lookup the function corresponding to the address and section */
+
+extern struct symbol *find_pc_sect_function (CORE_ADDR, asection *);
+
+/* lookup function from address, return name, start addr and end addr */
+
+extern int
+find_pc_partial_function (CORE_ADDR, char **, CORE_ADDR *, CORE_ADDR *);
+
+extern void clear_pc_function_cache (void);
+
+extern int
+find_pc_sect_partial_function (CORE_ADDR, asection *,
+ char **, CORE_ADDR *, CORE_ADDR *);
+
+/* from symtab.c: */
+
+/* lookup partial symbol table by filename */
+
+extern struct partial_symtab *lookup_partial_symtab (const char *);
+
+/* lookup partial symbol table by address */
+
+extern struct partial_symtab *find_pc_psymtab (CORE_ADDR);
+
+/* lookup partial symbol table by address and section */
+
+extern struct partial_symtab *find_pc_sect_psymtab (CORE_ADDR, asection *);
+
+/* lookup full symbol table by address */
+
+extern struct symtab *find_pc_symtab (CORE_ADDR);
+
+/* lookup full symbol table by address and section */
+
+extern struct symtab *find_pc_sect_symtab (CORE_ADDR, asection *);
+
+/* lookup partial symbol by address */
+
+extern struct partial_symbol *find_pc_psymbol (struct partial_symtab *,
+ CORE_ADDR);
+
+/* lookup partial symbol by address and section */
+
+extern struct partial_symbol *find_pc_sect_psymbol (struct partial_symtab *,
+ CORE_ADDR, asection *);
+
+extern int find_pc_line_pc_range (CORE_ADDR, CORE_ADDR *, CORE_ADDR *);
+
+extern int contained_in (struct block *, struct block *);
+
+extern void reread_symbols (void);
+
+extern struct type *lookup_transparent_type (const char *);
+
+
+/* Macro for name of symbol to indicate a file compiled with gcc. */
+#ifndef GCC_COMPILED_FLAG_SYMBOL
+#define GCC_COMPILED_FLAG_SYMBOL "gcc_compiled."
+#endif
+
+/* Macro for name of symbol to indicate a file compiled with gcc2. */
+#ifndef GCC2_COMPILED_FLAG_SYMBOL
+#define GCC2_COMPILED_FLAG_SYMBOL "gcc2_compiled."
+#endif
+
+/* Functions for dealing with the minimal symbol table, really a misc
+ address<->symbol mapping for things we don't have debug symbols for. */
+
+extern void prim_record_minimal_symbol (const char *, CORE_ADDR,
+ enum minimal_symbol_type,
+ struct objfile *);
+
+extern struct minimal_symbol *prim_record_minimal_symbol_and_info
+ (const char *, CORE_ADDR,
+ enum minimal_symbol_type,
+ char *info, int section, asection * bfd_section, struct objfile *);
+
+extern unsigned int msymbol_hash_iw (const char *);
+
+extern unsigned int msymbol_hash (const char *);
+
+extern void
+add_minsym_to_hash_table (struct minimal_symbol *sym,
+ struct minimal_symbol **table);
+
+extern struct minimal_symbol *lookup_minimal_symbol (const char *,
+ const char *,
+ struct objfile *);
+
+extern struct minimal_symbol *lookup_minimal_symbol_text (const char *,
+ const char *,
+ struct objfile *);
+
+struct minimal_symbol *lookup_minimal_symbol_solib_trampoline (const char *,
+ const char *,
+ struct objfile
+ *);
+
+extern struct minimal_symbol *lookup_minimal_symbol_by_pc (CORE_ADDR);
+
+extern struct minimal_symbol *lookup_minimal_symbol_by_pc_section (CORE_ADDR,
+ asection
+ *);
+
+extern struct minimal_symbol
+ *lookup_solib_trampoline_symbol_by_pc (CORE_ADDR);
+
+extern CORE_ADDR find_solib_trampoline_target (CORE_ADDR);
+
+extern void init_minimal_symbol_collection (void);
+
+extern struct cleanup *make_cleanup_discard_minimal_symbols (void);
+
+extern void install_minimal_symbols (struct objfile *);
+
+/* Sort all the minimal symbols in OBJFILE. */
+
+extern void msymbols_sort (struct objfile *objfile);
+
+struct symtab_and_line
+ {
+ struct symtab *symtab;
+ asection *section;
+ /* Line number. Line numbers start at 1 and proceed through symtab->nlines.
+ 0 is never a valid line number; it is used to indicate that line number
+ information is not available. */
+ int line;
+
+ CORE_ADDR pc;
+ CORE_ADDR end;
+ };
+
+#define INIT_SAL(sal) { \
+ (sal)->symtab = 0; \
+ (sal)->section = 0; \
+ (sal)->line = 0; \
+ (sal)->pc = 0; \
+ (sal)->end = 0; \
+}
+
+struct symtabs_and_lines
+ {
+ struct symtab_and_line *sals;
+ int nelts;
+ };
+
+
+
+/* Some types and macros needed for exception catchpoints.
+ Can't put these in target.h because symtab_and_line isn't
+ known there. This file will be included by breakpoint.c,
+ hppa-tdep.c, etc. */
+
+/* Enums for exception-handling support */
+enum exception_event_kind
+ {
+ EX_EVENT_THROW,
+ EX_EVENT_CATCH
+ };
+
+/* Type for returning info about an exception */
+struct exception_event_record
+ {
+ enum exception_event_kind kind;
+ struct symtab_and_line throw_sal;
+ struct symtab_and_line catch_sal;
+ /* This may need to be extended in the future, if
+ some platforms allow reporting more information,
+ such as point of rethrow, type of exception object,
+ type expected by catch clause, etc. */
+ };
+
+#define CURRENT_EXCEPTION_KIND (current_exception_event->kind)
+#define CURRENT_EXCEPTION_CATCH_SAL (current_exception_event->catch_sal)
+#define CURRENT_EXCEPTION_CATCH_LINE (current_exception_event->catch_sal.line)
+#define CURRENT_EXCEPTION_CATCH_FILE (current_exception_event->catch_sal.symtab->filename)
+#define CURRENT_EXCEPTION_CATCH_PC (current_exception_event->catch_sal.pc)
+#define CURRENT_EXCEPTION_THROW_SAL (current_exception_event->throw_sal)
+#define CURRENT_EXCEPTION_THROW_LINE (current_exception_event->throw_sal.line)
+#define CURRENT_EXCEPTION_THROW_FILE (current_exception_event->throw_sal.symtab->filename)
+#define CURRENT_EXCEPTION_THROW_PC (current_exception_event->throw_sal.pc)
+
+
+/* Given a pc value, return line number it is in. Second arg nonzero means
+ if pc is on the boundary use the previous statement's line number. */
+
+extern struct symtab_and_line find_pc_line (CORE_ADDR, int);
+
+/* Same function, but specify a section as well as an address */
+
+extern struct symtab_and_line find_pc_sect_line (CORE_ADDR, asection *, int);
+
+/* Given an address, return the nearest symbol at or below it in memory.
+ Optionally return the symtab it's from through 2nd arg, and the
+ address in inferior memory of the symbol through 3rd arg. */
+
+extern struct symbol *find_addr_symbol (CORE_ADDR, struct symtab **,
+ CORE_ADDR *);
+
+/* Given a symtab and line number, return the pc there. */
+
+extern int find_line_pc (struct symtab *, int, CORE_ADDR *);
+
+extern int
+find_line_pc_range (struct symtab_and_line, CORE_ADDR *, CORE_ADDR *);
+
+extern void resolve_sal_pc (struct symtab_and_line *);
+
+/* Given a string, return the line specified by it. For commands like "list"
+ and "breakpoint". */
+
+extern struct symtabs_and_lines decode_line_spec (char *, int);
+
+extern struct symtabs_and_lines decode_line_spec_1 (char *, int);
+
+/* Symmisc.c */
+
+void maintenance_print_symbols (char *, int);
+
+void maintenance_print_psymbols (char *, int);
+
+void maintenance_print_msymbols (char *, int);
+
+void maintenance_print_objfiles (char *, int);
+
+void maintenance_check_symtabs (char *, int);
+
+/* maint.c */
+
+void maintenance_print_statistics (char *, int);
+
+extern void free_symtab (struct symtab *);
+
+/* Symbol-reading stuff in symfile.c and solib.c. */
+
+extern struct symtab *psymtab_to_symtab (struct partial_symtab *);
+
+extern void clear_solib (void);
+
+/* source.c */
+
+extern int identify_source_line (struct symtab *, int, int, CORE_ADDR);
+
+extern void print_source_lines (struct symtab *, int, int, int);
+
+extern void forget_cached_source_info (void);
+
+extern void select_source_symtab (struct symtab *);
+
+extern char **make_symbol_completion_list (char *, char *);
+
+extern char **make_file_symbol_completion_list (char *, char *, char *);
+
+extern struct symbol **make_symbol_overload_list (struct symbol *);
+
+extern char **make_source_files_completion_list (char *, char *);
+
+/* symtab.c */
+
+extern struct partial_symtab *find_main_psymtab (void);
+
+extern struct symtab *find_line_symtab (struct symtab *, int, int *, int *);
+
+extern struct symtab_and_line find_function_start_sal (struct symbol *sym, int);
+
+/* blockframe.c */
+
+extern struct blockvector *blockvector_for_pc (CORE_ADDR, int *);
+
+extern struct blockvector *blockvector_for_pc_sect (CORE_ADDR, asection *,
+ int *, struct symtab *);
+
+/* symfile.c */
+
+extern void clear_symtab_users (void);
+
+extern enum language deduce_language_from_filename (char *);
+
+/* symtab.c */
+
+extern int in_prologue (CORE_ADDR pc, CORE_ADDR func_start);
+
+extern struct symbol *fixup_symbol_section (struct symbol *,
+ struct objfile *);
+
+extern struct partial_symbol *fixup_psymbol_section (struct partial_symbol
+ *psym,
+ struct objfile *objfile);
+
+/* Symbol searching */
+
+/* When using search_symbols, a list of the following structs is returned.
+ Callers must free the search list using free_search_symbols! */
+struct symbol_search
+ {
+ /* The block in which the match was found. Could be, for example,
+ STATIC_BLOCK or GLOBAL_BLOCK. */
+ int block;
+
+ /* Information describing what was found.
+
+ If symtab abd symbol are NOT NULL, then information was found
+ for this match. */
+ struct symtab *symtab;
+ struct symbol *symbol;
+
+ /* If msymbol is non-null, then a match was made on something for
+ which only minimal_symbols exist. */
+ struct minimal_symbol *msymbol;
+
+ /* A link to the next match, or NULL for the end. */
+ struct symbol_search *next;
+ };
+
+extern void search_symbols (char *, namespace_enum, int, char **,
+ struct symbol_search **);
+extern void free_search_symbols (struct symbol_search *);
+extern struct cleanup *make_cleanup_free_search_symbols (struct symbol_search *);
+
+/* The name of the ``main'' function.
+ FIXME: cagney/2001-03-20: Can't make main_name() const since some
+ of the calling code currently assumes that the string isn't
+ const. */
+extern void set_main_name (const char *name);
+extern /*const*/ char *main_name (void);
+
+#endif /* !defined(SYMTAB_H) */
diff --git a/gdb/target.c b/gdb/target.c
new file mode 100644
index 00000000000..2cd492809f4
--- /dev/null
+++ b/gdb/target.c
@@ -0,0 +1,2317 @@
+/* Select target systems and architectures at runtime for GDB.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002
+ 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 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 "defs.h"
+#include <errno.h>
+#include "gdb_string.h"
+#include "target.h"
+#include "gdbcmd.h"
+#include "symtab.h"
+#include "inferior.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdb_wait.h"
+#include "dcache.h"
+#include <signal.h>
+#include "regcache.h"
+
+extern int errno;
+
+static void target_info (char *, int);
+
+static void cleanup_target (struct target_ops *);
+
+static void maybe_kill_then_create_inferior (char *, char *, char **);
+
+static void default_clone_and_follow_inferior (int, int *);
+
+static void maybe_kill_then_attach (char *, int);
+
+static void kill_or_be_killed (int);
+
+static void default_terminal_info (char *, int);
+
+static int nosymbol (char *, CORE_ADDR *);
+
+static void tcomplain (void);
+
+static int nomemory (CORE_ADDR, char *, int, int, struct target_ops *);
+
+static int return_zero (void);
+
+static int return_one (void);
+
+void target_ignore (void);
+
+static void target_command (char *, int);
+
+static struct target_ops *find_default_run_target (char *);
+
+static void update_current_target (void);
+
+static void nosupport_runtime (void);
+
+static void normal_target_post_startup_inferior (ptid_t ptid);
+
+/* Transfer LEN bytes between target address MEMADDR and GDB address
+ MYADDR. Returns 0 for success, errno code for failure (which
+ includes partial transfers -- if you want a more useful response to
+ partial transfers, try either target_read_memory_partial or
+ target_write_memory_partial). */
+
+static int
+target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write);
+
+static void init_dummy_target (void);
+
+static void debug_to_open (char *, int);
+
+static void debug_to_close (int);
+
+static void debug_to_attach (char *, int);
+
+static void debug_to_detach (char *, int);
+
+static void debug_to_resume (ptid_t, int, enum target_signal);
+
+static ptid_t debug_to_wait (ptid_t, struct target_waitstatus *);
+
+static void debug_to_fetch_registers (int);
+
+static void debug_to_store_registers (int);
+
+static void debug_to_prepare_to_store (void);
+
+static int
+debug_to_xfer_memory (CORE_ADDR, char *, int, int, struct mem_attrib *,
+ struct target_ops *);
+
+static void debug_to_files_info (struct target_ops *);
+
+static int debug_to_insert_breakpoint (CORE_ADDR, char *);
+
+static int debug_to_remove_breakpoint (CORE_ADDR, char *);
+
+static void debug_to_terminal_init (void);
+
+static void debug_to_terminal_inferior (void);
+
+static void debug_to_terminal_ours_for_output (void);
+
+static void debug_to_terminal_ours (void);
+
+static void debug_to_terminal_info (char *, int);
+
+static void debug_to_kill (void);
+
+static void debug_to_load (char *, int);
+
+static int debug_to_lookup_symbol (char *, CORE_ADDR *);
+
+static void debug_to_create_inferior (char *, char *, char **);
+
+static void debug_to_mourn_inferior (void);
+
+static int debug_to_can_run (void);
+
+static void debug_to_notice_signals (ptid_t);
+
+static int debug_to_thread_alive (ptid_t);
+
+static void debug_to_stop (void);
+
+static int debug_to_query (int /*char */ , char *, char *, int *);
+
+/* Pointer to array of target architecture structures; the size of the
+ array; the current index into the array; the allocated size of the
+ array. */
+struct target_ops **target_structs;
+unsigned target_struct_size;
+unsigned target_struct_index;
+unsigned target_struct_allocsize;
+#define DEFAULT_ALLOCSIZE 10
+
+/* The initial current target, so that there is always a semi-valid
+ current target. */
+
+static struct target_ops dummy_target;
+
+/* Top of target stack. */
+
+struct target_stack_item *target_stack;
+
+/* The target structure we are currently using to talk to a process
+ or file or whatever "inferior" we have. */
+
+struct target_ops current_target;
+
+/* Command list for target. */
+
+static struct cmd_list_element *targetlist = NULL;
+
+/* Nonzero if we are debugging an attached outside process
+ rather than an inferior. */
+
+int attach_flag;
+
+/* Non-zero if we want to see trace of target level stuff. */
+
+static int targetdebug = 0;
+
+static void setup_target_debug (void);
+
+DCACHE *target_dcache;
+
+/* The user just typed 'target' without the name of a target. */
+
+/* ARGSUSED */
+static void
+target_command (char *arg, int from_tty)
+{
+ fputs_filtered ("Argument required (target name). Try `help target'\n",
+ gdb_stdout);
+}
+
+/* Add a possible target architecture to the list. */
+
+void
+add_target (struct target_ops *t)
+{
+ if (!target_structs)
+ {
+ target_struct_allocsize = DEFAULT_ALLOCSIZE;
+ target_structs = (struct target_ops **) xmalloc
+ (target_struct_allocsize * sizeof (*target_structs));
+ }
+ if (target_struct_size >= target_struct_allocsize)
+ {
+ target_struct_allocsize *= 2;
+ target_structs = (struct target_ops **)
+ xrealloc ((char *) target_structs,
+ target_struct_allocsize * sizeof (*target_structs));
+ }
+ target_structs[target_struct_size++] = t;
+/* cleanup_target (t); */
+
+ if (targetlist == NULL)
+ add_prefix_cmd ("target", class_run, target_command,
+ "Connect to a target machine or process.\n\
+The first argument is the type or protocol of the target machine.\n\
+Remaining arguments are interpreted by the target protocol. For more\n\
+information on the arguments for a particular protocol, type\n\
+`help target ' followed by the protocol name.",
+ &targetlist, "target ", 0, &cmdlist);
+ add_cmd (t->to_shortname, no_class, t->to_open, t->to_doc, &targetlist);
+}
+
+/* Stub functions */
+
+void
+target_ignore (void)
+{
+}
+
+void
+target_load (char *arg, int from_tty)
+{
+ dcache_invalidate (target_dcache);
+ (*current_target.to_load) (arg, from_tty);
+}
+
+/* ARGSUSED */
+static int
+nomemory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct target_ops *t)
+{
+ errno = EIO; /* Can't read/write this location */
+ return 0; /* No bytes handled */
+}
+
+static void
+tcomplain (void)
+{
+ error ("You can't do that when your target is `%s'",
+ current_target.to_shortname);
+}
+
+void
+noprocess (void)
+{
+ error ("You can't do that without a process to debug.");
+}
+
+/* ARGSUSED */
+static int
+nosymbol (char *name, CORE_ADDR *addrp)
+{
+ return 1; /* Symbol does not exist in target env */
+}
+
+/* ARGSUSED */
+static void
+nosupport_runtime (void)
+{
+ if (ptid_equal (inferior_ptid, null_ptid))
+ noprocess ();
+ else
+ error ("No run-time support for this");
+}
+
+
+/* ARGSUSED */
+static void
+default_terminal_info (char *args, int from_tty)
+{
+ printf_unfiltered ("No saved terminal information.\n");
+}
+
+/* This is the default target_create_inferior and target_attach function.
+ If the current target is executing, it asks whether to kill it off.
+ If this function returns without calling error(), it has killed off
+ the target, and the operation should be attempted. */
+
+static void
+kill_or_be_killed (int from_tty)
+{
+ if (target_has_execution)
+ {
+ printf_unfiltered ("You are already running a program:\n");
+ target_files_info ();
+ if (query ("Kill it? "))
+ {
+ target_kill ();
+ if (target_has_execution)
+ error ("Killing the program did not help.");
+ return;
+ }
+ else
+ {
+ error ("Program not killed.");
+ }
+ }
+ tcomplain ();
+}
+
+static void
+maybe_kill_then_attach (char *args, int from_tty)
+{
+ kill_or_be_killed (from_tty);
+ target_attach (args, from_tty);
+}
+
+static void
+maybe_kill_then_create_inferior (char *exec, char *args, char **env)
+{
+ kill_or_be_killed (0);
+ target_create_inferior (exec, args, env);
+}
+
+static void
+default_clone_and_follow_inferior (int child_pid, int *followed_child)
+{
+ target_clone_and_follow_inferior (child_pid, followed_child);
+}
+
+/* Clean up a target struct so it no longer has any zero pointers in it.
+ We default entries, at least to stubs that print error messages. */
+
+static void
+cleanup_target (struct target_ops *t)
+{
+
+#define de_fault(field, value) \
+ if (!t->field) \
+ t->field = value
+
+ de_fault (to_open,
+ (void (*) (char *, int))
+ tcomplain);
+ de_fault (to_close,
+ (void (*) (int))
+ target_ignore);
+ de_fault (to_attach,
+ maybe_kill_then_attach);
+ de_fault (to_post_attach,
+ (void (*) (int))
+ target_ignore);
+ de_fault (to_require_attach,
+ maybe_kill_then_attach);
+ de_fault (to_detach,
+ (void (*) (char *, int))
+ target_ignore);
+ de_fault (to_require_detach,
+ (void (*) (int, char *, int))
+ target_ignore);
+ de_fault (to_resume,
+ (void (*) (ptid_t, int, enum target_signal))
+ noprocess);
+ de_fault (to_wait,
+ (ptid_t (*) (ptid_t, struct target_waitstatus *))
+ noprocess);
+ de_fault (to_post_wait,
+ (void (*) (ptid_t, int))
+ target_ignore);
+ de_fault (to_fetch_registers,
+ (void (*) (int))
+ target_ignore);
+ de_fault (to_store_registers,
+ (void (*) (int))
+ noprocess);
+ de_fault (to_prepare_to_store,
+ (void (*) (void))
+ noprocess);
+ de_fault (to_xfer_memory,
+ (int (*) (CORE_ADDR, char *, int, int, struct mem_attrib *, struct target_ops *))
+ nomemory);
+ de_fault (to_files_info,
+ (void (*) (struct target_ops *))
+ target_ignore);
+ de_fault (to_insert_breakpoint,
+ memory_insert_breakpoint);
+ de_fault (to_remove_breakpoint,
+ memory_remove_breakpoint);
+ de_fault (to_terminal_init,
+ (void (*) (void))
+ target_ignore);
+ de_fault (to_terminal_inferior,
+ (void (*) (void))
+ target_ignore);
+ de_fault (to_terminal_ours_for_output,
+ (void (*) (void))
+ target_ignore);
+ de_fault (to_terminal_ours,
+ (void (*) (void))
+ target_ignore);
+ de_fault (to_terminal_info,
+ default_terminal_info);
+ de_fault (to_kill,
+ (void (*) (void))
+ noprocess);
+ de_fault (to_load,
+ (void (*) (char *, int))
+ tcomplain);
+ de_fault (to_lookup_symbol,
+ (int (*) (char *, CORE_ADDR *))
+ nosymbol);
+ de_fault (to_create_inferior,
+ maybe_kill_then_create_inferior);
+ de_fault (to_post_startup_inferior,
+ (void (*) (ptid_t))
+ target_ignore);
+ de_fault (to_acknowledge_created_inferior,
+ (void (*) (int))
+ target_ignore);
+ de_fault (to_clone_and_follow_inferior,
+ default_clone_and_follow_inferior);
+ de_fault (to_post_follow_inferior_by_clone,
+ (void (*) (void))
+ target_ignore);
+ de_fault (to_insert_fork_catchpoint,
+ (int (*) (int))
+ tcomplain);
+ de_fault (to_remove_fork_catchpoint,
+ (int (*) (int))
+ tcomplain);
+ de_fault (to_insert_vfork_catchpoint,
+ (int (*) (int))
+ tcomplain);
+ de_fault (to_remove_vfork_catchpoint,
+ (int (*) (int))
+ tcomplain);
+ de_fault (to_has_forked,
+ (int (*) (int, int *))
+ return_zero);
+ de_fault (to_has_vforked,
+ (int (*) (int, int *))
+ return_zero);
+ de_fault (to_can_follow_vfork_prior_to_exec,
+ (int (*) (void))
+ return_zero);
+ de_fault (to_post_follow_vfork,
+ (void (*) (int, int, int, int))
+ target_ignore);
+ de_fault (to_insert_exec_catchpoint,
+ (int (*) (int))
+ tcomplain);
+ de_fault (to_remove_exec_catchpoint,
+ (int (*) (int))
+ tcomplain);
+ de_fault (to_has_execd,
+ (int (*) (int, char **))
+ return_zero);
+ de_fault (to_reported_exec_events_per_exec_call,
+ (int (*) (void))
+ return_one);
+ de_fault (to_has_syscall_event,
+ (int (*) (int, enum target_waitkind *, int *))
+ return_zero);
+ de_fault (to_has_exited,
+ (int (*) (int, int, int *))
+ return_zero);
+ de_fault (to_mourn_inferior,
+ (void (*) (void))
+ noprocess);
+ de_fault (to_can_run,
+ return_zero);
+ de_fault (to_notice_signals,
+ (void (*) (ptid_t))
+ target_ignore);
+ de_fault (to_thread_alive,
+ (int (*) (ptid_t))
+ return_zero);
+ de_fault (to_find_new_threads,
+ (void (*) (void))
+ target_ignore);
+ de_fault (to_extra_thread_info,
+ (char *(*) (struct thread_info *))
+ return_zero);
+ de_fault (to_stop,
+ (void (*) (void))
+ target_ignore);
+ de_fault (to_rcmd,
+ (void (*) (char *, struct ui_file *))
+ tcomplain);
+ de_fault (to_enable_exception_callback,
+ (struct symtab_and_line * (*) (enum exception_event_kind, int))
+ nosupport_runtime);
+ de_fault (to_get_current_exception_event,
+ (struct exception_event_record * (*) (void))
+ nosupport_runtime);
+ de_fault (to_pid_to_exec_file,
+ (char *(*) (int))
+ return_zero);
+ de_fault (to_can_async_p,
+ (int (*) (void))
+ return_zero);
+ de_fault (to_is_async_p,
+ (int (*) (void))
+ return_zero);
+ de_fault (to_async,
+ (void (*) (void (*) (enum inferior_event_type, void*), void*))
+ tcomplain);
+#undef de_fault
+}
+
+/* Go through the target stack from top to bottom, copying over zero entries in
+ current_target. In effect, we are doing class inheritance through the
+ pushed target vectors. */
+
+static void
+update_current_target (void)
+{
+ struct target_stack_item *item;
+ struct target_ops *t;
+
+ /* First, reset current_target */
+ memset (&current_target, 0, sizeof current_target);
+
+ for (item = target_stack; item; item = item->next)
+ {
+ t = item->target_ops;
+
+#define INHERIT(FIELD, TARGET) \
+ if (!current_target.FIELD) \
+ current_target.FIELD = TARGET->FIELD
+
+ INHERIT (to_shortname, t);
+ INHERIT (to_longname, t);
+ INHERIT (to_doc, t);
+ INHERIT (to_open, t);
+ INHERIT (to_close, t);
+ INHERIT (to_attach, t);
+ INHERIT (to_post_attach, t);
+ INHERIT (to_require_attach, t);
+ INHERIT (to_detach, t);
+ INHERIT (to_require_detach, t);
+ INHERIT (to_resume, t);
+ INHERIT (to_wait, t);
+ INHERIT (to_post_wait, t);
+ INHERIT (to_fetch_registers, t);
+ INHERIT (to_store_registers, t);
+ INHERIT (to_prepare_to_store, t);
+ INHERIT (to_xfer_memory, t);
+ INHERIT (to_files_info, t);
+ INHERIT (to_insert_breakpoint, t);
+ INHERIT (to_remove_breakpoint, t);
+ INHERIT (to_terminal_init, t);
+ INHERIT (to_terminal_inferior, t);
+ INHERIT (to_terminal_ours_for_output, t);
+ INHERIT (to_terminal_ours, t);
+ INHERIT (to_terminal_info, t);
+ INHERIT (to_kill, t);
+ INHERIT (to_load, t);
+ INHERIT (to_lookup_symbol, t);
+ INHERIT (to_create_inferior, t);
+ INHERIT (to_post_startup_inferior, t);
+ INHERIT (to_acknowledge_created_inferior, t);
+ INHERIT (to_clone_and_follow_inferior, t);
+ INHERIT (to_post_follow_inferior_by_clone, t);
+ INHERIT (to_insert_fork_catchpoint, t);
+ INHERIT (to_remove_fork_catchpoint, t);
+ INHERIT (to_insert_vfork_catchpoint, t);
+ INHERIT (to_remove_vfork_catchpoint, t);
+ INHERIT (to_has_forked, t);
+ INHERIT (to_has_vforked, t);
+ INHERIT (to_can_follow_vfork_prior_to_exec, t);
+ INHERIT (to_post_follow_vfork, t);
+ INHERIT (to_insert_exec_catchpoint, t);
+ INHERIT (to_remove_exec_catchpoint, t);
+ INHERIT (to_has_execd, t);
+ INHERIT (to_reported_exec_events_per_exec_call, t);
+ INHERIT (to_has_syscall_event, t);
+ INHERIT (to_has_exited, t);
+ INHERIT (to_mourn_inferior, t);
+ INHERIT (to_can_run, t);
+ INHERIT (to_notice_signals, t);
+ INHERIT (to_thread_alive, t);
+ INHERIT (to_find_new_threads, t);
+ INHERIT (to_pid_to_str, t);
+ INHERIT (to_extra_thread_info, t);
+ INHERIT (to_stop, t);
+ INHERIT (to_query, t);
+ INHERIT (to_rcmd, t);
+ INHERIT (to_enable_exception_callback, t);
+ INHERIT (to_get_current_exception_event, t);
+ INHERIT (to_pid_to_exec_file, t);
+ INHERIT (to_stratum, t);
+ INHERIT (DONT_USE, t);
+ INHERIT (to_has_all_memory, t);
+ INHERIT (to_has_memory, t);
+ INHERIT (to_has_stack, t);
+ INHERIT (to_has_registers, t);
+ INHERIT (to_has_execution, t);
+ INHERIT (to_has_thread_control, t);
+ INHERIT (to_sections, t);
+ INHERIT (to_sections_end, t);
+ INHERIT (to_can_async_p, t);
+ INHERIT (to_is_async_p, t);
+ INHERIT (to_async, t);
+ INHERIT (to_async_mask_value, t);
+ INHERIT (to_find_memory_regions, t);
+ INHERIT (to_make_corefile_notes, t);
+ INHERIT (to_magic, t);
+
+#undef INHERIT
+ }
+}
+
+/* Push a new target type into the stack of the existing target accessors,
+ possibly superseding some of the existing accessors.
+
+ Result is zero if the pushed target ended up on top of the stack,
+ nonzero if at least one target is on top of it.
+
+ Rather than allow an empty stack, we always have the dummy target at
+ the bottom stratum, so we can call the function vectors without
+ checking them. */
+
+int
+push_target (struct target_ops *t)
+{
+ struct target_stack_item *cur, *prev, *tmp;
+
+ /* Check magic number. If wrong, it probably means someone changed
+ the struct definition, but not all the places that initialize one. */
+ if (t->to_magic != OPS_MAGIC)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "Magic number of %s target struct wrong\n",
+ t->to_shortname);
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+
+ /* Find the proper stratum to install this target in. */
+
+ for (prev = NULL, cur = target_stack; cur; prev = cur, cur = cur->next)
+ {
+ if ((int) (t->to_stratum) >= (int) (cur->target_ops->to_stratum))
+ break;
+ }
+
+ /* If there's already targets at this stratum, remove them. */
+
+ if (cur)
+ while (t->to_stratum == cur->target_ops->to_stratum)
+ {
+ /* There's already something on this stratum. Close it off. */
+ if (cur->target_ops->to_close)
+ (cur->target_ops->to_close) (0);
+ if (prev)
+ prev->next = cur->next; /* Unchain old target_ops */
+ else
+ target_stack = cur->next; /* Unchain first on list */
+ tmp = cur->next;
+ xfree (cur);
+ cur = tmp;
+ }
+
+ /* We have removed all targets in our stratum, now add the new one. */
+
+ tmp = (struct target_stack_item *)
+ xmalloc (sizeof (struct target_stack_item));
+ tmp->next = cur;
+ tmp->target_ops = t;
+
+ if (prev)
+ prev->next = tmp;
+ else
+ target_stack = tmp;
+
+ update_current_target ();
+
+ cleanup_target (&current_target); /* Fill in the gaps */
+
+ if (targetdebug)
+ setup_target_debug ();
+
+ return prev != 0;
+}
+
+/* Remove a target_ops vector from the stack, wherever it may be.
+ Return how many times it was removed (0 or 1). */
+
+int
+unpush_target (struct target_ops *t)
+{
+ struct target_stack_item *cur, *prev;
+
+ if (t->to_close)
+ t->to_close (0); /* Let it clean up */
+
+ /* Look for the specified target. Note that we assume that a target
+ can only occur once in the target stack. */
+
+ for (cur = target_stack, prev = NULL; cur; prev = cur, cur = cur->next)
+ if (cur->target_ops == t)
+ break;
+
+ if (!cur)
+ return 0; /* Didn't find target_ops, quit now */
+
+ /* Unchain the target */
+
+ if (!prev)
+ target_stack = cur->next;
+ else
+ prev->next = cur->next;
+
+ xfree (cur); /* Release the target_stack_item */
+
+ update_current_target ();
+ cleanup_target (&current_target);
+
+ return 1;
+}
+
+void
+pop_target (void)
+{
+ (current_target.to_close) (0); /* Let it clean up */
+ if (unpush_target (target_stack->target_ops) == 1)
+ return;
+
+ fprintf_unfiltered (gdb_stderr,
+ "pop_target couldn't find target %s\n",
+ current_target.to_shortname);
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+}
+
+#undef MIN
+#define MIN(A, B) (((A) <= (B)) ? (A) : (B))
+
+/* target_read_string -- read a null terminated string, up to LEN bytes,
+ from MEMADDR in target. Set *ERRNOP to the errno code, or 0 if successful.
+ Set *STRING to a pointer to malloc'd memory containing the data; the caller
+ is responsible for freeing it. Return the number of bytes successfully
+ read. */
+
+int
+target_read_string (CORE_ADDR memaddr, char **string, int len, int *errnop)
+{
+ int tlen, origlen, offset, i;
+ char buf[4];
+ int errcode = 0;
+ char *buffer;
+ int buffer_allocated;
+ char *bufptr;
+ unsigned int nbytes_read = 0;
+
+ /* Small for testing. */
+ buffer_allocated = 4;
+ buffer = xmalloc (buffer_allocated);
+ bufptr = buffer;
+
+ origlen = len;
+
+ while (len > 0)
+ {
+ tlen = MIN (len, 4 - (memaddr & 3));
+ offset = memaddr & 3;
+
+ errcode = target_xfer_memory (memaddr & ~3, buf, 4, 0);
+ if (errcode != 0)
+ {
+ /* The transfer request might have crossed the boundary to an
+ unallocated region of memory. Retry the transfer, requesting
+ a single byte. */
+ tlen = 1;
+ offset = 0;
+ errcode = target_xfer_memory (memaddr, buf, 1, 0);
+ if (errcode != 0)
+ goto done;
+ }
+
+ if (bufptr - buffer + tlen > buffer_allocated)
+ {
+ unsigned int bytes;
+ bytes = bufptr - buffer;
+ buffer_allocated *= 2;
+ buffer = xrealloc (buffer, buffer_allocated);
+ bufptr = buffer + bytes;
+ }
+
+ for (i = 0; i < tlen; i++)
+ {
+ *bufptr++ = buf[i + offset];
+ if (buf[i + offset] == '\000')
+ {
+ nbytes_read += i + 1;
+ goto done;
+ }
+ }
+
+ memaddr += tlen;
+ len -= tlen;
+ nbytes_read += tlen;
+ }
+done:
+ if (errnop != NULL)
+ *errnop = errcode;
+ if (string != NULL)
+ *string = buffer;
+ return nbytes_read;
+}
+
+/* Read LEN bytes of target memory at address MEMADDR, placing the results in
+ GDB's memory at MYADDR. Returns either 0 for success or an errno value
+ if any error occurs.
+
+ If an error occurs, no guarantee is made about the contents of the data at
+ MYADDR. In particular, the caller should not depend upon partial reads
+ filling the buffer with good data. There is no way for the caller to know
+ how much good data might have been transfered anyway. Callers that can
+ deal with partial reads should call target_read_memory_partial. */
+
+int
+target_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ return target_xfer_memory (memaddr, myaddr, len, 0);
+}
+
+int
+target_write_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ return target_xfer_memory (memaddr, myaddr, len, 1);
+}
+
+static int trust_readonly = 0;
+
+/* Move memory to or from the targets. The top target gets priority;
+ if it cannot handle it, it is offered to the next one down, etc.
+
+ Result is -1 on error, or the number of bytes transfered. */
+
+int
+do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib)
+{
+ int res;
+ int done = 0;
+ struct target_ops *t;
+ struct target_stack_item *item;
+
+ /* Zero length requests are ok and require no work. */
+ if (len == 0)
+ return 0;
+
+ /* to_xfer_memory is not guaranteed to set errno, even when it returns
+ 0. */
+ errno = 0;
+
+ if (!write && trust_readonly)
+ {
+ /* User-settable option, "trust-readonly-sections". If true,
+ then memory from any SEC_READONLY bfd section may be read
+ directly from the bfd file. */
+
+ struct section_table *secp;
+
+ for (secp = current_target.to_sections;
+ secp < current_target.to_sections_end;
+ secp++)
+ {
+ if (bfd_get_section_flags (secp->bfd, secp->the_bfd_section)
+ & SEC_READONLY)
+ if (memaddr >= secp->addr && memaddr < secp->endaddr)
+ return xfer_memory (memaddr, myaddr, len, 0,
+ attrib, &current_target);
+ }
+ }
+
+ /* The quick case is that the top target can handle the transfer. */
+ res = current_target.to_xfer_memory
+ (memaddr, myaddr, len, write, attrib, &current_target);
+
+ /* If res <= 0 then we call it again in the loop. Ah well. */
+ if (res <= 0)
+ {
+ for (item = target_stack; item; item = item->next)
+ {
+ t = item->target_ops;
+ if (!t->to_has_memory)
+ continue;
+
+ res = t->to_xfer_memory (memaddr, myaddr, len, write, attrib, t);
+ if (res > 0)
+ break; /* Handled all or part of xfer */
+ if (t->to_has_all_memory)
+ break;
+ }
+
+ if (res <= 0)
+ return -1;
+ }
+
+ return res;
+}
+
+
+/* Perform a memory transfer. Iterate until the entire region has
+ been transfered.
+
+ Result is 0 or errno value. */
+
+static int
+target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
+{
+ int res;
+ int reg_len;
+ struct mem_region *region;
+
+ /* Zero length requests are ok and require no work. */
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ while (len > 0)
+ {
+ region = lookup_mem_region(memaddr);
+ if (memaddr + len < region->hi)
+ reg_len = len;
+ else
+ reg_len = region->hi - memaddr;
+
+ switch (region->attrib.mode)
+ {
+ case MEM_RO:
+ if (write)
+ return EIO;
+ break;
+
+ case MEM_WO:
+ if (!write)
+ return EIO;
+ break;
+ }
+
+ while (reg_len > 0)
+ {
+ if (region->attrib.cache)
+ res = dcache_xfer_memory (target_dcache, memaddr, myaddr,
+ reg_len, write);
+ else
+ res = do_xfer_memory (memaddr, myaddr, reg_len, write,
+ &region->attrib);
+
+ if (res <= 0)
+ {
+ /* If this address is for nonexistent memory, read zeros
+ if reading, or do nothing if writing. Return
+ error. */
+ if (!write)
+ memset (myaddr, 0, len);
+ if (errno == 0)
+ return EIO;
+ else
+ return errno;
+ }
+
+ memaddr += res;
+ myaddr += res;
+ len -= res;
+ reg_len -= res;
+ }
+ }
+
+ return 0; /* We managed to cover it all somehow. */
+}
+
+
+/* Perform a partial memory transfer.
+
+ Result is -1 on error, or the number of bytes transfered. */
+
+static int
+target_xfer_memory_partial (CORE_ADDR memaddr, char *myaddr, int len,
+ int write_p, int *err)
+{
+ int res;
+ int reg_len;
+ struct mem_region *region;
+
+ /* Zero length requests are ok and require no work. */
+ if (len == 0)
+ {
+ *err = 0;
+ return 0;
+ }
+
+ region = lookup_mem_region(memaddr);
+ if (memaddr + len < region->hi)
+ reg_len = len;
+ else
+ reg_len = region->hi - memaddr;
+
+ switch (region->attrib.mode)
+ {
+ case MEM_RO:
+ if (write_p)
+ {
+ *err = EIO;
+ return -1;
+ }
+ break;
+
+ case MEM_WO:
+ if (write_p)
+ {
+ *err = EIO;
+ return -1;
+ }
+ break;
+ }
+
+ if (region->attrib.cache)
+ res = dcache_xfer_memory (target_dcache, memaddr, myaddr,
+ reg_len, write_p);
+ else
+ res = do_xfer_memory (memaddr, myaddr, reg_len, write_p,
+ &region->attrib);
+
+ if (res <= 0)
+ {
+ if (errno != 0)
+ *err = errno;
+ else
+ *err = EIO;
+
+ return -1;
+ }
+
+ *err = 0;
+ return res;
+}
+
+int
+target_read_memory_partial (CORE_ADDR memaddr, char *buf, int len, int *err)
+{
+ return target_xfer_memory_partial (memaddr, buf, len, 0, err);
+}
+
+int
+target_write_memory_partial (CORE_ADDR memaddr, char *buf, int len, int *err)
+{
+ return target_xfer_memory_partial (memaddr, buf, len, 1, err);
+}
+
+/* ARGSUSED */
+static void
+target_info (char *args, int from_tty)
+{
+ struct target_ops *t;
+ struct target_stack_item *item;
+ int has_all_mem = 0;
+
+ if (symfile_objfile != NULL)
+ printf_unfiltered ("Symbols from \"%s\".\n", symfile_objfile->name);
+
+#ifdef FILES_INFO_HOOK
+ if (FILES_INFO_HOOK ())
+ return;
+#endif
+
+ for (item = target_stack; item; item = item->next)
+ {
+ t = item->target_ops;
+
+ if (!t->to_has_memory)
+ continue;
+
+ if ((int) (t->to_stratum) <= (int) dummy_stratum)
+ continue;
+ if (has_all_mem)
+ printf_unfiltered ("\tWhile running this, GDB does not access memory from...\n");
+ printf_unfiltered ("%s:\n", t->to_longname);
+ (t->to_files_info) (t);
+ has_all_mem = t->to_has_all_memory;
+ }
+}
+
+/* This is to be called by the open routine before it does
+ anything. */
+
+void
+target_preopen (int from_tty)
+{
+ dont_repeat ();
+
+ if (target_has_execution)
+ {
+ if (!from_tty
+ || query ("A program is being debugged already. Kill it? "))
+ target_kill ();
+ else
+ error ("Program not killed.");
+ }
+
+ /* Calling target_kill may remove the target from the stack. But if
+ it doesn't (which seems like a win for UDI), remove it now. */
+
+ if (target_has_execution)
+ pop_target ();
+}
+
+/* Detach a target after doing deferred register stores. */
+
+void
+target_detach (char *args, int from_tty)
+{
+ /* Handle any optimized stores to the inferior. */
+#ifdef DO_DEFERRED_STORES
+ DO_DEFERRED_STORES;
+#endif
+ (current_target.to_detach) (args, from_tty);
+}
+
+void
+target_link (char *modname, CORE_ADDR *t_reloc)
+{
+ if (STREQ (current_target.to_shortname, "rombug"))
+ {
+ (current_target.to_lookup_symbol) (modname, t_reloc);
+ if (*t_reloc == 0)
+ error ("Unable to link to %s and get relocation in rombug", modname);
+ }
+ else
+ *t_reloc = (CORE_ADDR) -1;
+}
+
+int
+target_async_mask (int mask)
+{
+ int saved_async_masked_status = target_async_mask_value;
+ target_async_mask_value = mask;
+ return saved_async_masked_status;
+}
+
+/* Look through the list of possible targets for a target that can
+ execute a run or attach command without any other data. This is
+ used to locate the default process stratum.
+
+ Result is always valid (error() is called for errors). */
+
+static struct target_ops *
+find_default_run_target (char *do_mesg)
+{
+ struct target_ops **t;
+ struct target_ops *runable = NULL;
+ int count;
+
+ count = 0;
+
+ for (t = target_structs; t < target_structs + target_struct_size;
+ ++t)
+ {
+ if ((*t)->to_can_run && target_can_run (*t))
+ {
+ runable = *t;
+ ++count;
+ }
+ }
+
+ if (count != 1)
+ error ("Don't know how to %s. Try \"help target\".", do_mesg);
+
+ return runable;
+}
+
+void
+find_default_attach (char *args, int from_tty)
+{
+ struct target_ops *t;
+
+ t = find_default_run_target ("attach");
+ (t->to_attach) (args, from_tty);
+ return;
+}
+
+void
+find_default_require_attach (char *args, int from_tty)
+{
+ struct target_ops *t;
+
+ t = find_default_run_target ("require_attach");
+ (t->to_require_attach) (args, from_tty);
+ return;
+}
+
+void
+find_default_require_detach (int pid, char *args, int from_tty)
+{
+ struct target_ops *t;
+
+ t = find_default_run_target ("require_detach");
+ (t->to_require_detach) (pid, args, from_tty);
+ return;
+}
+
+void
+find_default_create_inferior (char *exec_file, char *allargs, char **env)
+{
+ struct target_ops *t;
+
+ t = find_default_run_target ("run");
+ (t->to_create_inferior) (exec_file, allargs, env);
+ return;
+}
+
+void
+find_default_clone_and_follow_inferior (int child_pid, int *followed_child)
+{
+ struct target_ops *t;
+
+ t = find_default_run_target ("run");
+ (t->to_clone_and_follow_inferior) (child_pid, followed_child);
+ return;
+}
+
+static int
+return_zero (void)
+{
+ return 0;
+}
+
+static int
+return_one (void)
+{
+ return 1;
+}
+
+/*
+ * Resize the to_sections pointer. Also make sure that anyone that
+ * was holding on to an old value of it gets updated.
+ * Returns the old size.
+ */
+
+int
+target_resize_to_sections (struct target_ops *target, int num_added)
+{
+ struct target_ops **t;
+ struct section_table *old_value;
+ int old_count;
+
+ old_value = target->to_sections;
+
+ if (target->to_sections)
+ {
+ old_count = target->to_sections_end - target->to_sections;
+ target->to_sections = (struct section_table *)
+ xrealloc ((char *) target->to_sections,
+ (sizeof (struct section_table)) * (num_added + old_count));
+ }
+ else
+ {
+ old_count = 0;
+ target->to_sections = (struct section_table *)
+ xmalloc ((sizeof (struct section_table)) * num_added);
+ }
+ target->to_sections_end = target->to_sections + (num_added + old_count);
+
+ /* Check to see if anyone else was pointing to this structure.
+ If old_value was null, then no one was. */
+
+ if (old_value)
+ {
+ for (t = target_structs; t < target_structs + target_struct_size;
+ ++t)
+ {
+ if ((*t)->to_sections == old_value)
+ {
+ (*t)->to_sections = target->to_sections;
+ (*t)->to_sections_end = target->to_sections_end;
+ }
+ }
+ }
+
+ return old_count;
+
+}
+
+/* Remove all target sections taken from ABFD.
+
+ Scan the current target stack for targets whose section tables
+ refer to sections from BFD, and remove those sections. We use this
+ when we notice that the inferior has unloaded a shared object, for
+ example. */
+void
+remove_target_sections (bfd *abfd)
+{
+ struct target_ops **t;
+
+ for (t = target_structs; t < target_structs + target_struct_size; t++)
+ {
+ struct section_table *src, *dest;
+
+ dest = (*t)->to_sections;
+ for (src = (*t)->to_sections; src < (*t)->to_sections_end; src++)
+ if (src->bfd != abfd)
+ {
+ /* Keep this section. */
+ if (dest < src) *dest = *src;
+ dest++;
+ }
+
+ /* If we've dropped any sections, resize the section table. */
+ if (dest < src)
+ target_resize_to_sections (*t, dest - src);
+ }
+}
+
+
+
+
+/* Find a single runnable target in the stack and return it. If for
+ some reason there is more than one, return NULL. */
+
+struct target_ops *
+find_run_target (void)
+{
+ struct target_ops **t;
+ struct target_ops *runable = NULL;
+ int count;
+
+ count = 0;
+
+ for (t = target_structs; t < target_structs + target_struct_size; ++t)
+ {
+ if ((*t)->to_can_run && target_can_run (*t))
+ {
+ runable = *t;
+ ++count;
+ }
+ }
+
+ return (count == 1 ? runable : NULL);
+}
+
+/* Find a single core_stratum target in the list of targets and return it.
+ If for some reason there is more than one, return NULL. */
+
+struct target_ops *
+find_core_target (void)
+{
+ struct target_ops **t;
+ struct target_ops *runable = NULL;
+ int count;
+
+ count = 0;
+
+ for (t = target_structs; t < target_structs + target_struct_size;
+ ++t)
+ {
+ if ((*t)->to_stratum == core_stratum)
+ {
+ runable = *t;
+ ++count;
+ }
+ }
+
+ return (count == 1 ? runable : NULL);
+}
+
+/*
+ * Find the next target down the stack from the specified target.
+ */
+
+struct target_ops *
+find_target_beneath (struct target_ops *t)
+{
+ struct target_stack_item *cur;
+
+ for (cur = target_stack; cur; cur = cur->next)
+ if (cur->target_ops == t)
+ break;
+
+ if (cur == NULL || cur->next == NULL)
+ return NULL;
+ else
+ return cur->next->target_ops;
+}
+
+
+/* The inferior process has died. Long live the inferior! */
+
+void
+generic_mourn_inferior (void)
+{
+ extern int show_breakpoint_hit_counts;
+
+ inferior_ptid = null_ptid;
+ attach_flag = 0;
+ breakpoint_init_inferior (inf_exited);
+ registers_changed ();
+
+#ifdef CLEAR_DEFERRED_STORES
+ /* Delete any pending stores to the inferior... */
+ CLEAR_DEFERRED_STORES;
+#endif
+
+ reopen_exec_file ();
+ reinit_frame_cache ();
+
+ /* It is confusing to the user for ignore counts to stick around
+ from previous runs of the inferior. So clear them. */
+ /* However, it is more confusing for the ignore counts to disappear when
+ using hit counts. So don't clear them if we're counting hits. */
+ if (!show_breakpoint_hit_counts)
+ breakpoint_clear_ignore_counts ();
+
+ if (detach_hook)
+ detach_hook ();
+}
+
+/* Helper function for child_wait and the Lynx derivatives of child_wait.
+ HOSTSTATUS is the waitstatus from wait() or the equivalent; store our
+ translation of that in OURSTATUS. */
+void
+store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus)
+{
+#ifdef CHILD_SPECIAL_WAITSTATUS
+ /* CHILD_SPECIAL_WAITSTATUS should return nonzero and set *OURSTATUS
+ if it wants to deal with hoststatus. */
+ if (CHILD_SPECIAL_WAITSTATUS (ourstatus, hoststatus))
+ return;
+#endif
+
+ if (WIFEXITED (hoststatus))
+ {
+ ourstatus->kind = TARGET_WAITKIND_EXITED;
+ ourstatus->value.integer = WEXITSTATUS (hoststatus);
+ }
+ else if (!WIFSTOPPED (hoststatus))
+ {
+ ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
+ ourstatus->value.sig = target_signal_from_host (WTERMSIG (hoststatus));
+ }
+ else
+ {
+ ourstatus->kind = TARGET_WAITKIND_STOPPED;
+ ourstatus->value.sig = target_signal_from_host (WSTOPSIG (hoststatus));
+ }
+}
+
+/* Returns zero to leave the inferior alone, one to interrupt it. */
+int (*target_activity_function) (void);
+int target_activity_fd;
+
+/* Convert a normal process ID to a string. Returns the string in a static
+ buffer. */
+
+char *
+normal_pid_to_str (ptid_t ptid)
+{
+ static char buf[30];
+
+ sprintf (buf, "process %d", PIDGET (ptid));
+ return buf;
+}
+
+/* Some targets (such as ttrace-based HPUX) don't allow us to request
+ notification of inferior events such as fork and vork immediately
+ after the inferior is created. (This because of how gdb gets an
+ inferior created via invoking a shell to do it. In such a scenario,
+ if the shell init file has commands in it, the shell will fork and
+ exec for each of those commands, and we will see each such fork
+ event. Very bad.)
+
+ This function is used by all targets that allow us to request
+ notification of forks, etc at inferior creation time; e.g., in
+ target_acknowledge_forked_child.
+ */
+static void
+normal_target_post_startup_inferior (ptid_t ptid)
+{
+ /* This space intentionally left blank. */
+}
+
+/* Error-catcher for target_find_memory_regions */
+/* ARGSUSED */
+static int dummy_find_memory_regions (int (*ignore1) (), void *ignore2)
+{
+ error ("No target.");
+ return 0;
+}
+
+/* Error-catcher for target_make_corefile_notes */
+/* ARGSUSED */
+static char * dummy_make_corefile_notes (bfd *ignore1, int *ignore2)
+{
+ error ("No target.");
+ return NULL;
+}
+
+/* Set up the handful of non-empty slots needed by the dummy target
+ vector. */
+
+static void
+init_dummy_target (void)
+{
+ dummy_target.to_shortname = "None";
+ dummy_target.to_longname = "None";
+ dummy_target.to_doc = "";
+ dummy_target.to_attach = find_default_attach;
+ dummy_target.to_require_attach = find_default_require_attach;
+ dummy_target.to_require_detach = find_default_require_detach;
+ dummy_target.to_create_inferior = find_default_create_inferior;
+ dummy_target.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior;
+ dummy_target.to_pid_to_str = normal_pid_to_str;
+ dummy_target.to_stratum = dummy_stratum;
+ dummy_target.to_find_memory_regions = dummy_find_memory_regions;
+ dummy_target.to_make_corefile_notes = dummy_make_corefile_notes;
+ dummy_target.to_magic = OPS_MAGIC;
+}
+
+
+static struct target_ops debug_target;
+
+static void
+debug_to_open (char *args, int from_tty)
+{
+ debug_target.to_open (args, from_tty);
+
+ fprintf_unfiltered (gdb_stdlog, "target_open (%s, %d)\n", args, from_tty);
+}
+
+static void
+debug_to_close (int quitting)
+{
+ debug_target.to_close (quitting);
+
+ fprintf_unfiltered (gdb_stdlog, "target_close (%d)\n", quitting);
+}
+
+static void
+debug_to_attach (char *args, int from_tty)
+{
+ debug_target.to_attach (args, from_tty);
+
+ fprintf_unfiltered (gdb_stdlog, "target_attach (%s, %d)\n", args, from_tty);
+}
+
+
+static void
+debug_to_post_attach (int pid)
+{
+ debug_target.to_post_attach (pid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_post_attach (%d)\n", pid);
+}
+
+static void
+debug_to_require_attach (char *args, int from_tty)
+{
+ debug_target.to_require_attach (args, from_tty);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_require_attach (%s, %d)\n", args, from_tty);
+}
+
+static void
+debug_to_detach (char *args, int from_tty)
+{
+ debug_target.to_detach (args, from_tty);
+
+ fprintf_unfiltered (gdb_stdlog, "target_detach (%s, %d)\n", args, from_tty);
+}
+
+static void
+debug_to_require_detach (int pid, char *args, int from_tty)
+{
+ debug_target.to_require_detach (pid, args, from_tty);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_require_detach (%d, %s, %d)\n", pid, args, from_tty);
+}
+
+static void
+debug_to_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ debug_target.to_resume (ptid, step, siggnal);
+
+ fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n", PIDGET (ptid),
+ step ? "step" : "continue",
+ target_signal_to_name (siggnal));
+}
+
+static ptid_t
+debug_to_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ ptid_t retval;
+
+ retval = debug_target.to_wait (ptid, status);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_wait (%d, status) = %d, ", PIDGET (ptid),
+ PIDGET (retval));
+ fprintf_unfiltered (gdb_stdlog, "status->kind = ");
+ switch (status->kind)
+ {
+ case TARGET_WAITKIND_EXITED:
+ fprintf_unfiltered (gdb_stdlog, "exited, status = %d\n",
+ status->value.integer);
+ break;
+ case TARGET_WAITKIND_STOPPED:
+ fprintf_unfiltered (gdb_stdlog, "stopped, signal = %s\n",
+ target_signal_to_name (status->value.sig));
+ break;
+ case TARGET_WAITKIND_SIGNALLED:
+ fprintf_unfiltered (gdb_stdlog, "signalled, signal = %s\n",
+ target_signal_to_name (status->value.sig));
+ break;
+ case TARGET_WAITKIND_LOADED:
+ fprintf_unfiltered (gdb_stdlog, "loaded\n");
+ break;
+ case TARGET_WAITKIND_FORKED:
+ fprintf_unfiltered (gdb_stdlog, "forked\n");
+ break;
+ case TARGET_WAITKIND_VFORKED:
+ fprintf_unfiltered (gdb_stdlog, "vforked\n");
+ break;
+ case TARGET_WAITKIND_EXECD:
+ fprintf_unfiltered (gdb_stdlog, "execd\n");
+ break;
+ case TARGET_WAITKIND_SPURIOUS:
+ fprintf_unfiltered (gdb_stdlog, "spurious\n");
+ break;
+ default:
+ fprintf_unfiltered (gdb_stdlog, "unknown???\n");
+ break;
+ }
+
+ return retval;
+}
+
+static void
+debug_to_post_wait (ptid_t ptid, int status)
+{
+ debug_target.to_post_wait (ptid, status);
+
+ fprintf_unfiltered (gdb_stdlog, "target_post_wait (%d, %d)\n",
+ PIDGET (ptid), status);
+}
+
+static void
+debug_print_register (const char * func, int regno)
+{
+ fprintf_unfiltered (gdb_stdlog, "%s ", func);
+ if (regno >= 0 && regno < NUM_REGS + NUM_PSEUDO_REGS
+ && REGISTER_NAME (regno) != NULL && REGISTER_NAME (regno)[0] != '\0')
+ fprintf_unfiltered (gdb_stdlog, "(%s)", REGISTER_NAME (regno));
+ else
+ fprintf_unfiltered (gdb_stdlog, "(%d)", regno);
+ if (regno >= 0)
+ {
+ int i;
+ unsigned char *buf = alloca (MAX_REGISTER_RAW_SIZE);
+ read_register_gen (regno, buf);
+ fprintf_unfiltered (gdb_stdlog, " = ");
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i++)
+ {
+ fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
+ }
+ if (REGISTER_RAW_SIZE (regno) <= sizeof (LONGEST))
+ {
+ fprintf_unfiltered (gdb_stdlog, " 0x%s %s",
+ paddr_nz (read_register (regno)),
+ paddr_d (read_register (regno)));
+ }
+ }
+ fprintf_unfiltered (gdb_stdlog, "\n");
+}
+
+static void
+debug_to_fetch_registers (int regno)
+{
+ debug_target.to_fetch_registers (regno);
+ debug_print_register ("target_fetch_registers", regno);
+}
+
+static void
+debug_to_store_registers (int regno)
+{
+ debug_target.to_store_registers (regno);
+ debug_print_register ("target_store_registers", regno);
+ fprintf_unfiltered (gdb_stdlog, "\n");
+}
+
+static void
+debug_to_prepare_to_store (void)
+{
+ debug_target.to_prepare_to_store ();
+
+ fprintf_unfiltered (gdb_stdlog, "target_prepare_to_store ()\n");
+}
+
+static int
+debug_to_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ int retval;
+
+ retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write,
+ attrib, target);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d",
+ (unsigned int) memaddr, /* possable truncate long long */
+ len, write ? "write" : "read", retval);
+
+
+
+ if (retval > 0)
+ {
+ int i;
+
+ fputs_unfiltered (", bytes =", gdb_stdlog);
+ for (i = 0; i < retval; i++)
+ {
+ if ((((long) &(myaddr[i])) & 0xf) == 0)
+ fprintf_unfiltered (gdb_stdlog, "\n");
+ fprintf_unfiltered (gdb_stdlog, " %02x", myaddr[i] & 0xff);
+ }
+ }
+
+ fputc_unfiltered ('\n', gdb_stdlog);
+
+ return retval;
+}
+
+static void
+debug_to_files_info (struct target_ops *target)
+{
+ debug_target.to_files_info (target);
+
+ fprintf_unfiltered (gdb_stdlog, "target_files_info (xxx)\n");
+}
+
+static int
+debug_to_insert_breakpoint (CORE_ADDR addr, char *save)
+{
+ int retval;
+
+ retval = debug_target.to_insert_breakpoint (addr, save);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_insert_breakpoint (0x%lx, xxx) = %ld\n",
+ (unsigned long) addr,
+ (unsigned long) retval);
+ return retval;
+}
+
+static int
+debug_to_remove_breakpoint (CORE_ADDR addr, char *save)
+{
+ int retval;
+
+ retval = debug_target.to_remove_breakpoint (addr, save);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_remove_breakpoint (0x%lx, xxx) = %ld\n",
+ (unsigned long) addr,
+ (unsigned long) retval);
+ return retval;
+}
+
+static void
+debug_to_terminal_init (void)
+{
+ debug_target.to_terminal_init ();
+
+ fprintf_unfiltered (gdb_stdlog, "target_terminal_init ()\n");
+}
+
+static void
+debug_to_terminal_inferior (void)
+{
+ debug_target.to_terminal_inferior ();
+
+ fprintf_unfiltered (gdb_stdlog, "target_terminal_inferior ()\n");
+}
+
+static void
+debug_to_terminal_ours_for_output (void)
+{
+ debug_target.to_terminal_ours_for_output ();
+
+ fprintf_unfiltered (gdb_stdlog, "target_terminal_ours_for_output ()\n");
+}
+
+static void
+debug_to_terminal_ours (void)
+{
+ debug_target.to_terminal_ours ();
+
+ fprintf_unfiltered (gdb_stdlog, "target_terminal_ours ()\n");
+}
+
+static void
+debug_to_terminal_info (char *arg, int from_tty)
+{
+ debug_target.to_terminal_info (arg, from_tty);
+
+ fprintf_unfiltered (gdb_stdlog, "target_terminal_info (%s, %d)\n", arg,
+ from_tty);
+}
+
+static void
+debug_to_kill (void)
+{
+ debug_target.to_kill ();
+
+ fprintf_unfiltered (gdb_stdlog, "target_kill ()\n");
+}
+
+static void
+debug_to_load (char *args, int from_tty)
+{
+ debug_target.to_load (args, from_tty);
+
+ fprintf_unfiltered (gdb_stdlog, "target_load (%s, %d)\n", args, from_tty);
+}
+
+static int
+debug_to_lookup_symbol (char *name, CORE_ADDR *addrp)
+{
+ int retval;
+
+ retval = debug_target.to_lookup_symbol (name, addrp);
+
+ fprintf_unfiltered (gdb_stdlog, "target_lookup_symbol (%s, xxx)\n", name);
+
+ return retval;
+}
+
+static void
+debug_to_create_inferior (char *exec_file, char *args, char **env)
+{
+ debug_target.to_create_inferior (exec_file, args, env);
+
+ fprintf_unfiltered (gdb_stdlog, "target_create_inferior (%s, %s, xxx)\n",
+ exec_file, args);
+}
+
+static void
+debug_to_post_startup_inferior (ptid_t ptid)
+{
+ debug_target.to_post_startup_inferior (ptid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_post_startup_inferior (%d)\n",
+ PIDGET (ptid));
+}
+
+static void
+debug_to_acknowledge_created_inferior (int pid)
+{
+ debug_target.to_acknowledge_created_inferior (pid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_acknowledge_created_inferior (%d)\n",
+ pid);
+}
+
+static void
+debug_to_clone_and_follow_inferior (int child_pid, int *followed_child)
+{
+ debug_target.to_clone_and_follow_inferior (child_pid, followed_child);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_clone_and_follow_inferior (%d, %d)\n",
+ child_pid, *followed_child);
+}
+
+static void
+debug_to_post_follow_inferior_by_clone (void)
+{
+ debug_target.to_post_follow_inferior_by_clone ();
+
+ fprintf_unfiltered (gdb_stdlog, "target_post_follow_inferior_by_clone ()\n");
+}
+
+static int
+debug_to_insert_fork_catchpoint (int pid)
+{
+ int retval;
+
+ retval = debug_target.to_insert_fork_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_insert_fork_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_remove_fork_catchpoint (int pid)
+{
+ int retval;
+
+ retval = debug_target.to_remove_fork_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_remove_fork_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_insert_vfork_catchpoint (int pid)
+{
+ int retval;
+
+ retval = debug_target.to_insert_vfork_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_insert_vfork_catchpoint (%d)= %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_remove_vfork_catchpoint (int pid)
+{
+ int retval;
+
+ retval = debug_target.to_remove_vfork_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_remove_vfork_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_has_forked (int pid, int *child_pid)
+{
+ int has_forked;
+
+ has_forked = debug_target.to_has_forked (pid, child_pid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_has_forked (%d, %d) = %d\n",
+ pid, *child_pid, has_forked);
+
+ return has_forked;
+}
+
+static int
+debug_to_has_vforked (int pid, int *child_pid)
+{
+ int has_vforked;
+
+ has_vforked = debug_target.to_has_vforked (pid, child_pid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_has_vforked (%d, %d) = %d\n",
+ pid, *child_pid, has_vforked);
+
+ return has_vforked;
+}
+
+static int
+debug_to_can_follow_vfork_prior_to_exec (void)
+{
+ int can_immediately_follow_vfork;
+
+ can_immediately_follow_vfork = debug_target.to_can_follow_vfork_prior_to_exec ();
+
+ fprintf_unfiltered (gdb_stdlog, "target_can_follow_vfork_prior_to_exec () = %d\n",
+ can_immediately_follow_vfork);
+
+ return can_immediately_follow_vfork;
+}
+
+static void
+debug_to_post_follow_vfork (int parent_pid, int followed_parent, int child_pid,
+ int followed_child)
+{
+ debug_target.to_post_follow_vfork (parent_pid, followed_parent, child_pid, followed_child);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_post_follow_vfork (%d, %d, %d, %d)\n",
+ parent_pid, followed_parent, child_pid, followed_child);
+}
+
+static int
+debug_to_insert_exec_catchpoint (int pid)
+{
+ int retval;
+
+ retval = debug_target.to_insert_exec_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_insert_exec_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_remove_exec_catchpoint (int pid)
+{
+ int retval;
+
+ retval = debug_target.to_remove_exec_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_remove_exec_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_has_execd (int pid, char **execd_pathname)
+{
+ int has_execd;
+
+ has_execd = debug_target.to_has_execd (pid, execd_pathname);
+
+ fprintf_unfiltered (gdb_stdlog, "target_has_execd (%d, %s) = %d\n",
+ pid, (*execd_pathname ? *execd_pathname : "<NULL>"),
+ has_execd);
+
+ return has_execd;
+}
+
+static int
+debug_to_reported_exec_events_per_exec_call (void)
+{
+ int reported_exec_events;
+
+ reported_exec_events = debug_target.to_reported_exec_events_per_exec_call ();
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_reported_exec_events_per_exec_call () = %d\n",
+ reported_exec_events);
+
+ return reported_exec_events;
+}
+
+static int
+debug_to_has_syscall_event (int pid, enum target_waitkind *kind,
+ int *syscall_id)
+{
+ int has_syscall_event;
+ char *kind_spelling = "??";
+
+ has_syscall_event = debug_target.to_has_syscall_event (pid, kind, syscall_id);
+ if (has_syscall_event)
+ {
+ switch (*kind)
+ {
+ case TARGET_WAITKIND_SYSCALL_ENTRY:
+ kind_spelling = "SYSCALL_ENTRY";
+ break;
+ case TARGET_WAITKIND_SYSCALL_RETURN:
+ kind_spelling = "SYSCALL_RETURN";
+ break;
+ default:
+ break;
+ }
+ }
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_has_syscall_event (%d, %s, %d) = %d\n",
+ pid, kind_spelling, *syscall_id, has_syscall_event);
+
+ return has_syscall_event;
+}
+
+static int
+debug_to_has_exited (int pid, int wait_status, int *exit_status)
+{
+ int has_exited;
+
+ has_exited = debug_target.to_has_exited (pid, wait_status, exit_status);
+
+ fprintf_unfiltered (gdb_stdlog, "target_has_exited (%d, %d, %d) = %d\n",
+ pid, wait_status, *exit_status, has_exited);
+
+ return has_exited;
+}
+
+static void
+debug_to_mourn_inferior (void)
+{
+ debug_target.to_mourn_inferior ();
+
+ fprintf_unfiltered (gdb_stdlog, "target_mourn_inferior ()\n");
+}
+
+static int
+debug_to_can_run (void)
+{
+ int retval;
+
+ retval = debug_target.to_can_run ();
+
+ fprintf_unfiltered (gdb_stdlog, "target_can_run () = %d\n", retval);
+
+ return retval;
+}
+
+static void
+debug_to_notice_signals (ptid_t ptid)
+{
+ debug_target.to_notice_signals (ptid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_notice_signals (%d)\n",
+ PIDGET (ptid));
+}
+
+static int
+debug_to_thread_alive (ptid_t ptid)
+{
+ int retval;
+
+ retval = debug_target.to_thread_alive (ptid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_thread_alive (%d) = %d\n",
+ PIDGET (ptid), retval);
+
+ return retval;
+}
+
+static void
+debug_to_find_new_threads (void)
+{
+ debug_target.to_find_new_threads ();
+
+ fputs_unfiltered ("target_find_new_threads ()\n", gdb_stdlog);
+}
+
+static void
+debug_to_stop (void)
+{
+ debug_target.to_stop ();
+
+ fprintf_unfiltered (gdb_stdlog, "target_stop ()\n");
+}
+
+static int
+debug_to_query (int type, char *req, char *resp, int *siz)
+{
+ int retval;
+
+ retval = debug_target.to_query (type, req, resp, siz);
+
+ fprintf_unfiltered (gdb_stdlog, "target_query (%c, %s, %s, %d) = %d\n", type, req, resp, *siz, retval);
+
+ return retval;
+}
+
+static void
+debug_to_rcmd (char *command,
+ struct ui_file *outbuf)
+{
+ debug_target.to_rcmd (command, outbuf);
+ fprintf_unfiltered (gdb_stdlog, "target_rcmd (%s, ...)\n", command);
+}
+
+static struct symtab_and_line *
+debug_to_enable_exception_callback (enum exception_event_kind kind, int enable)
+{
+ struct symtab_and_line *result;
+ result = debug_target.to_enable_exception_callback (kind, enable);
+ fprintf_unfiltered (gdb_stdlog,
+ "target get_exception_callback_sal (%d, %d)\n",
+ kind, enable);
+ return result;
+}
+
+static struct exception_event_record *
+debug_to_get_current_exception_event (void)
+{
+ struct exception_event_record *result;
+ result = debug_target.to_get_current_exception_event ();
+ fprintf_unfiltered (gdb_stdlog, "target get_current_exception_event ()\n");
+ return result;
+}
+
+static char *
+debug_to_pid_to_exec_file (int pid)
+{
+ char *exec_file;
+
+ exec_file = debug_target.to_pid_to_exec_file (pid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_pid_to_exec_file (%d) = %s\n",
+ pid, exec_file);
+
+ return exec_file;
+}
+
+static void
+setup_target_debug (void)
+{
+ memcpy (&debug_target, &current_target, sizeof debug_target);
+
+ current_target.to_open = debug_to_open;
+ current_target.to_close = debug_to_close;
+ current_target.to_attach = debug_to_attach;
+ current_target.to_post_attach = debug_to_post_attach;
+ current_target.to_require_attach = debug_to_require_attach;
+ current_target.to_detach = debug_to_detach;
+ current_target.to_require_detach = debug_to_require_detach;
+ current_target.to_resume = debug_to_resume;
+ current_target.to_wait = debug_to_wait;
+ current_target.to_post_wait = debug_to_post_wait;
+ current_target.to_fetch_registers = debug_to_fetch_registers;
+ current_target.to_store_registers = debug_to_store_registers;
+ current_target.to_prepare_to_store = debug_to_prepare_to_store;
+ current_target.to_xfer_memory = debug_to_xfer_memory;
+ current_target.to_files_info = debug_to_files_info;
+ current_target.to_insert_breakpoint = debug_to_insert_breakpoint;
+ current_target.to_remove_breakpoint = debug_to_remove_breakpoint;
+ current_target.to_terminal_init = debug_to_terminal_init;
+ current_target.to_terminal_inferior = debug_to_terminal_inferior;
+ current_target.to_terminal_ours_for_output = debug_to_terminal_ours_for_output;
+ current_target.to_terminal_ours = debug_to_terminal_ours;
+ current_target.to_terminal_info = debug_to_terminal_info;
+ current_target.to_kill = debug_to_kill;
+ current_target.to_load = debug_to_load;
+ current_target.to_lookup_symbol = debug_to_lookup_symbol;
+ current_target.to_create_inferior = debug_to_create_inferior;
+ current_target.to_post_startup_inferior = debug_to_post_startup_inferior;
+ current_target.to_acknowledge_created_inferior = debug_to_acknowledge_created_inferior;
+ current_target.to_clone_and_follow_inferior = debug_to_clone_and_follow_inferior;
+ current_target.to_post_follow_inferior_by_clone = debug_to_post_follow_inferior_by_clone;
+ current_target.to_insert_fork_catchpoint = debug_to_insert_fork_catchpoint;
+ current_target.to_remove_fork_catchpoint = debug_to_remove_fork_catchpoint;
+ current_target.to_insert_vfork_catchpoint = debug_to_insert_vfork_catchpoint;
+ current_target.to_remove_vfork_catchpoint = debug_to_remove_vfork_catchpoint;
+ current_target.to_has_forked = debug_to_has_forked;
+ current_target.to_has_vforked = debug_to_has_vforked;
+ current_target.to_can_follow_vfork_prior_to_exec = debug_to_can_follow_vfork_prior_to_exec;
+ current_target.to_post_follow_vfork = debug_to_post_follow_vfork;
+ current_target.to_insert_exec_catchpoint = debug_to_insert_exec_catchpoint;
+ current_target.to_remove_exec_catchpoint = debug_to_remove_exec_catchpoint;
+ current_target.to_has_execd = debug_to_has_execd;
+ current_target.to_reported_exec_events_per_exec_call = debug_to_reported_exec_events_per_exec_call;
+ current_target.to_has_syscall_event = debug_to_has_syscall_event;
+ current_target.to_has_exited = debug_to_has_exited;
+ current_target.to_mourn_inferior = debug_to_mourn_inferior;
+ current_target.to_can_run = debug_to_can_run;
+ current_target.to_notice_signals = debug_to_notice_signals;
+ current_target.to_thread_alive = debug_to_thread_alive;
+ current_target.to_find_new_threads = debug_to_find_new_threads;
+ current_target.to_stop = debug_to_stop;
+ current_target.to_query = debug_to_query;
+ current_target.to_rcmd = debug_to_rcmd;
+ current_target.to_enable_exception_callback = debug_to_enable_exception_callback;
+ current_target.to_get_current_exception_event = debug_to_get_current_exception_event;
+ current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
+
+}
+
+
+static char targ_desc[] =
+"Names of targets and files being debugged.\n\
+Shows the entire stack of targets currently in use (including the exec-file,\n\
+core-file, and process, if any), as well as the symbol file name.";
+
+static void
+do_monitor_command (char *cmd,
+ int from_tty)
+{
+ if ((current_target.to_rcmd
+ == (void (*) (char *, struct ui_file *)) tcomplain)
+ || (current_target.to_rcmd == debug_to_rcmd
+ && (debug_target.to_rcmd
+ == (void (*) (char *, struct ui_file *)) tcomplain)))
+ {
+ error ("\"monitor\" command not supported by this target.\n");
+ }
+ target_rcmd (cmd, gdb_stdtarg);
+}
+
+void
+initialize_targets (void)
+{
+ init_dummy_target ();
+ push_target (&dummy_target);
+
+ add_info ("target", target_info, targ_desc);
+ add_info ("files", target_info, targ_desc);
+
+ add_show_from_set
+ (add_set_cmd ("target", class_maintenance, var_zinteger,
+ (char *) &targetdebug,
+ "Set target debugging.\n\
+When non-zero, target debugging is enabled.", &setdebuglist),
+ &showdebuglist);
+
+ add_show_from_set
+ (add_set_boolean_cmd
+ ("trust-readonly-sections", class_support,
+ &trust_readonly,
+ "Set mode for reading from readonly sections.\n\
+When this mode is on, memory reads from readonly sections (such as .text)\n\
+will be read from the object file instead of from the target. This will\n\
+result in significant performance improvement for remote targets.",
+ &setlist),
+ &showlist);
+
+ add_com ("monitor", class_obscure, do_monitor_command,
+ "Send a command to the remote monitor (remote targets only).");
+
+ target_dcache = dcache_init ();
+}
diff --git a/gdb/target.h b/gdb/target.h
new file mode 100644
index 00000000000..1797fc1d3e3
--- /dev/null
+++ b/gdb/target.h
@@ -0,0 +1,1269 @@
+/* Interface between GDB and target environments, including files and processes
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Cygnus Support. Written by John Gilmore.
+
+ 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. */
+
+#if !defined (TARGET_H)
+#define TARGET_H
+
+/* This include file defines the interface between the main part
+ of the debugger, and the part which is target-specific, or
+ specific to the communications interface between us and the
+ target.
+
+ A TARGET is an interface between the debugger and a particular
+ kind of file or process. Targets can be STACKED in STRATA,
+ so that more than one target can potentially respond to a request.
+ In particular, memory accesses will walk down the stack of targets
+ until they find a target that is interested in handling that particular
+ address. STRATA are artificial boundaries on the stack, within
+ which particular kinds of targets live. Strata exist so that
+ people don't get confused by pushing e.g. a process target and then
+ a file target, and wondering why they can't see the current values
+ of variables any more (the file target is handling them and they
+ never get to the process target). So when you push a file target,
+ it goes into the file stratum, which is always below the process
+ stratum. */
+
+#include "bfd.h"
+#include "symtab.h"
+#include "dcache.h"
+#include "memattr.h"
+
+enum strata
+ {
+ dummy_stratum, /* The lowest of the low */
+ file_stratum, /* Executable files, etc */
+ core_stratum, /* Core dump files */
+ download_stratum, /* Downloading of remote targets */
+ process_stratum, /* Executing processes */
+ thread_stratum /* Executing threads */
+ };
+
+enum thread_control_capabilities
+ {
+ tc_none = 0, /* Default: can't control thread execution. */
+ tc_schedlock = 1, /* Can lock the thread scheduler. */
+ tc_switch = 2 /* Can switch the running thread on demand. */
+ };
+
+/* Stuff for target_wait. */
+
+/* Generally, what has the program done? */
+enum target_waitkind
+ {
+ /* The program has exited. The exit status is in value.integer. */
+ TARGET_WAITKIND_EXITED,
+
+ /* The program has stopped with a signal. Which signal is in
+ value.sig. */
+ TARGET_WAITKIND_STOPPED,
+
+ /* The program has terminated with a signal. Which signal is in
+ value.sig. */
+ TARGET_WAITKIND_SIGNALLED,
+
+ /* The program is letting us know that it dynamically loaded something
+ (e.g. it called load(2) on AIX). */
+ TARGET_WAITKIND_LOADED,
+
+ /* The program has forked. A "related" process' ID is in
+ value.related_pid. I.e., if the child forks, value.related_pid
+ is the parent's ID. */
+
+ TARGET_WAITKIND_FORKED,
+
+ /* The program has vforked. A "related" process's ID is in
+ value.related_pid. */
+
+ TARGET_WAITKIND_VFORKED,
+
+ /* The program has exec'ed a new executable file. The new file's
+ pathname is pointed to by value.execd_pathname. */
+
+ TARGET_WAITKIND_EXECD,
+
+ /* The program has entered or returned from a system call. On
+ HP-UX, this is used in the hardware watchpoint implementation.
+ The syscall's unique integer ID number is in value.syscall_id */
+
+ TARGET_WAITKIND_SYSCALL_ENTRY,
+ TARGET_WAITKIND_SYSCALL_RETURN,
+
+ /* Nothing happened, but we stopped anyway. This perhaps should be handled
+ within target_wait, but I'm not sure target_wait should be resuming the
+ inferior. */
+ TARGET_WAITKIND_SPURIOUS,
+
+ /* This is used for target async and extended-async
+ only. Remote_async_wait() returns this when there is an event
+ on the inferior, but the rest of the world is not interested in
+ it. The inferior has not stopped, but has just sent some output
+ to the console, for instance. In this case, we want to go back
+ to the event loop and wait there for another event from the
+ inferior, rather than being stuck in the remote_async_wait()
+ function. This way the event loop is responsive to other events,
+ like for instance the user typing. */
+ TARGET_WAITKIND_IGNORE
+ };
+
+struct target_waitstatus
+ {
+ enum target_waitkind kind;
+
+ /* Forked child pid, execd pathname, exit status or signal number. */
+ union
+ {
+ int integer;
+ enum target_signal sig;
+ int related_pid;
+ char *execd_pathname;
+ int syscall_id;
+ }
+ value;
+ };
+
+/* Possible types of events that the inferior handler will have to
+ deal with. */
+enum inferior_event_type
+ {
+ /* There is a request to quit the inferior, abandon it. */
+ INF_QUIT_REQ,
+ /* Process a normal inferior event which will result in target_wait
+ being called. */
+ INF_REG_EVENT,
+ /* Deal with an error on the inferior. */
+ INF_ERROR,
+ /* We are called because a timer went off. */
+ INF_TIMER,
+ /* We are called to do stuff after the inferior stops. */
+ INF_EXEC_COMPLETE,
+ /* We are called to do some stuff after the inferior stops, but we
+ are expected to reenter the proceed() and
+ handle_inferior_event() functions. This is used only in case of
+ 'step n' like commands. */
+ INF_EXEC_CONTINUE
+ };
+
+/* Return the string for a signal. */
+extern char *target_signal_to_string (enum target_signal);
+
+/* Return the name (SIGHUP, etc.) for a signal. */
+extern char *target_signal_to_name (enum target_signal);
+
+/* Given a name (SIGHUP, etc.), return its signal. */
+enum target_signal target_signal_from_name (char *);
+
+
+/* If certain kinds of activity happen, target_wait should perform
+ callbacks. */
+/* Right now we just call (*TARGET_ACTIVITY_FUNCTION) if I/O is possible
+ on TARGET_ACTIVITY_FD. */
+extern int target_activity_fd;
+/* Returns zero to leave the inferior alone, one to interrupt it. */
+extern int (*target_activity_function) (void);
+
+struct thread_info; /* fwd decl for parameter list below: */
+
+struct target_ops
+ {
+ char *to_shortname; /* Name this target type */
+ char *to_longname; /* Name for printing */
+ char *to_doc; /* Documentation. Does not include trailing
+ newline, and starts with a one-line descrip-
+ tion (probably similar to to_longname). */
+ void (*to_open) (char *, int);
+ void (*to_close) (int);
+ void (*to_attach) (char *, int);
+ void (*to_post_attach) (int);
+ void (*to_require_attach) (char *, int);
+ void (*to_detach) (char *, int);
+ void (*to_require_detach) (int, char *, int);
+ void (*to_resume) (ptid_t, int, enum target_signal);
+ ptid_t (*to_wait) (ptid_t, struct target_waitstatus *);
+ void (*to_post_wait) (ptid_t, int);
+ void (*to_fetch_registers) (int);
+ void (*to_store_registers) (int);
+ void (*to_prepare_to_store) (void);
+
+ /* Transfer LEN bytes of memory between GDB address MYADDR and
+ target address MEMADDR. If WRITE, transfer them to the target, else
+ transfer them from the target. TARGET is the target from which we
+ get this function.
+
+ Return value, N, is one of the following:
+
+ 0 means that we can't handle this. If errno has been set, it is the
+ error which prevented us from doing it (FIXME: What about bfd_error?).
+
+ positive (call it N) means that we have transferred N bytes
+ starting at MEMADDR. We might be able to handle more bytes
+ beyond this length, but no promises.
+
+ negative (call its absolute value N) means that we cannot
+ transfer right at MEMADDR, but we could transfer at least
+ something at MEMADDR + N. */
+
+ int (*to_xfer_memory) (CORE_ADDR memaddr, char *myaddr,
+ int len, int write,
+ struct mem_attrib *attrib,
+ struct target_ops *target);
+
+#if 0
+ /* Enable this after 4.12. */
+
+ /* Search target memory. Start at STARTADDR and take LEN bytes of
+ target memory, and them with MASK, and compare to DATA. If they
+ match, set *ADDR_FOUND to the address we found it at, store the data
+ we found at LEN bytes starting at DATA_FOUND, and return. If
+ not, add INCREMENT to the search address and keep trying until
+ the search address is outside of the range [LORANGE,HIRANGE).
+
+ If we don't find anything, set *ADDR_FOUND to (CORE_ADDR)0 and
+ return. */
+
+ void (*to_search) (int len, char *data, char *mask,
+ CORE_ADDR startaddr, int increment,
+ CORE_ADDR lorange, CORE_ADDR hirange,
+ CORE_ADDR * addr_found, char *data_found);
+
+#define target_search(len, data, mask, startaddr, increment, lorange, hirange, addr_found, data_found) \
+ (*current_target.to_search) (len, data, mask, startaddr, increment, \
+ lorange, hirange, addr_found, data_found)
+#endif /* 0 */
+
+ void (*to_files_info) (struct target_ops *);
+ int (*to_insert_breakpoint) (CORE_ADDR, char *);
+ int (*to_remove_breakpoint) (CORE_ADDR, char *);
+ void (*to_terminal_init) (void);
+ void (*to_terminal_inferior) (void);
+ void (*to_terminal_ours_for_output) (void);
+ void (*to_terminal_ours) (void);
+ void (*to_terminal_info) (char *, int);
+ void (*to_kill) (void);
+ void (*to_load) (char *, int);
+ int (*to_lookup_symbol) (char *, CORE_ADDR *);
+ void (*to_create_inferior) (char *, char *, char **);
+ void (*to_post_startup_inferior) (ptid_t);
+ void (*to_acknowledge_created_inferior) (int);
+ void (*to_clone_and_follow_inferior) (int, int *);
+ void (*to_post_follow_inferior_by_clone) (void);
+ int (*to_insert_fork_catchpoint) (int);
+ int (*to_remove_fork_catchpoint) (int);
+ int (*to_insert_vfork_catchpoint) (int);
+ int (*to_remove_vfork_catchpoint) (int);
+ int (*to_has_forked) (int, int *);
+ int (*to_has_vforked) (int, int *);
+ int (*to_can_follow_vfork_prior_to_exec) (void);
+ void (*to_post_follow_vfork) (int, int, int, int);
+ int (*to_insert_exec_catchpoint) (int);
+ int (*to_remove_exec_catchpoint) (int);
+ int (*to_has_execd) (int, char **);
+ int (*to_reported_exec_events_per_exec_call) (void);
+ int (*to_has_syscall_event) (int, enum target_waitkind *, int *);
+ int (*to_has_exited) (int, int, int *);
+ void (*to_mourn_inferior) (void);
+ int (*to_can_run) (void);
+ void (*to_notice_signals) (ptid_t ptid);
+ int (*to_thread_alive) (ptid_t ptid);
+ void (*to_find_new_threads) (void);
+ char *(*to_pid_to_str) (ptid_t);
+ char *(*to_extra_thread_info) (struct thread_info *);
+ void (*to_stop) (void);
+ int (*to_query) (int /*char */ , char *, char *, int *);
+ void (*to_rcmd) (char *command, struct ui_file *output);
+ struct symtab_and_line *(*to_enable_exception_callback) (enum
+ exception_event_kind,
+ int);
+ struct exception_event_record *(*to_get_current_exception_event) (void);
+ char *(*to_pid_to_exec_file) (int pid);
+ enum strata to_stratum;
+ struct target_ops
+ *DONT_USE; /* formerly to_next */
+ int to_has_all_memory;
+ int to_has_memory;
+ int to_has_stack;
+ int to_has_registers;
+ int to_has_execution;
+ int to_has_thread_control; /* control thread execution */
+ struct section_table
+ *to_sections;
+ struct section_table
+ *to_sections_end;
+ /* ASYNC target controls */
+ int (*to_can_async_p) (void);
+ int (*to_is_async_p) (void);
+ void (*to_async) (void (*cb) (enum inferior_event_type, void *context),
+ void *context);
+ int to_async_mask_value;
+ int (*to_find_memory_regions) (int (*) (CORE_ADDR,
+ unsigned long,
+ int, int, int,
+ void *),
+ void *);
+ char * (*to_make_corefile_notes) (bfd *, int *);
+ int to_magic;
+ /* Need sub-structure for target machine related rather than comm related?
+ */
+ };
+
+/* Magic number for checking ops size. If a struct doesn't end with this
+ number, somebody changed the declaration but didn't change all the
+ places that initialize one. */
+
+#define OPS_MAGIC 3840
+
+/* The ops structure for our "current" target process. This should
+ never be NULL. If there is no target, it points to the dummy_target. */
+
+extern struct target_ops current_target;
+
+/* An item on the target stack. */
+
+struct target_stack_item
+ {
+ struct target_stack_item *next;
+ struct target_ops *target_ops;
+ };
+
+/* The target stack. */
+
+extern struct target_stack_item *target_stack;
+
+/* Define easy words for doing these operations on our current target. */
+
+#define target_shortname (current_target.to_shortname)
+#define target_longname (current_target.to_longname)
+
+/* The open routine takes the rest of the parameters from the command,
+ and (if successful) pushes a new target onto the stack.
+ Targets should supply this routine, if only to provide an error message. */
+
+#define target_open(name, from_tty) \
+ do { \
+ dcache_invalidate (target_dcache); \
+ (*current_target.to_open) (name, from_tty); \
+ } while (0)
+
+/* Does whatever cleanup is required for a target that we are no longer
+ going to be calling. Argument says whether we are quitting gdb and
+ should not get hung in case of errors, or whether we want a clean
+ termination even if it takes a while. This routine is automatically
+ always called just before a routine is popped off the target stack.
+ Closing file descriptors and freeing memory are typical things it should
+ do. */
+
+#define target_close(quitting) \
+ (*current_target.to_close) (quitting)
+
+/* Attaches to a process on the target side. Arguments are as passed
+ to the `attach' command by the user. This routine can be called
+ when the target is not on the target-stack, if the target_can_run
+ routine returns 1; in that case, it must push itself onto the stack.
+ Upon exit, the target should be ready for normal operations, and
+ should be ready to deliver the status of the process immediately
+ (without waiting) to an upcoming target_wait call. */
+
+#define target_attach(args, from_tty) \
+ (*current_target.to_attach) (args, from_tty)
+
+/* The target_attach operation places a process under debugger control,
+ and stops the process.
+
+ This operation provides a target-specific hook that allows the
+ necessary bookkeeping to be performed after an attach completes. */
+#define target_post_attach(pid) \
+ (*current_target.to_post_attach) (pid)
+
+/* Attaches to a process on the target side, if not already attached.
+ (If already attached, takes no action.)
+
+ This operation can be used to follow the child process of a fork.
+ On some targets, such child processes of an original inferior process
+ are automatically under debugger control, and thus do not require an
+ actual attach operation. */
+
+#define target_require_attach(args, from_tty) \
+ (*current_target.to_require_attach) (args, from_tty)
+
+/* Takes a program previously attached to and detaches it.
+ The program may resume execution (some targets do, some don't) and will
+ no longer stop on signals, etc. We better not have left any breakpoints
+ in the program or it'll die when it hits one. ARGS is arguments
+ typed by the user (e.g. a signal to send the process). FROM_TTY
+ says whether to be verbose or not. */
+
+extern void target_detach (char *, int);
+
+/* Detaches from a process on the target side, if not already dettached.
+ (If already detached, takes no action.)
+
+ This operation can be used to follow the parent process of a fork.
+ On some targets, such child processes of an original inferior process
+ are automatically under debugger control, and thus do require an actual
+ detach operation.
+
+ PID is the process id of the child to detach from.
+ ARGS is arguments typed by the user (e.g. a signal to send the process).
+ FROM_TTY says whether to be verbose or not. */
+
+#define target_require_detach(pid, args, from_tty) \
+ (*current_target.to_require_detach) (pid, args, from_tty)
+
+/* Resume execution of the target process PTID. STEP says whether to
+ single-step or to run free; SIGGNAL is the signal to be given to
+ the target, or TARGET_SIGNAL_0 for no signal. The caller may not
+ pass TARGET_SIGNAL_DEFAULT. */
+
+#define target_resume(ptid, step, siggnal) \
+ do { \
+ dcache_invalidate(target_dcache); \
+ (*current_target.to_resume) (ptid, step, siggnal); \
+ } while (0)
+
+/* Wait for process pid to do something. PTID = -1 to wait for any
+ pid to do something. Return pid of child, or -1 in case of error;
+ store status through argument pointer STATUS. Note that it is
+ _NOT_ OK to throw_exception() out of target_wait() without popping
+ the debugging target from the stack; GDB isn't prepared to get back
+ to the prompt with a debugging target but without the frame cache,
+ stop_pc, etc., set up. */
+
+#define target_wait(ptid, status) \
+ (*current_target.to_wait) (ptid, status)
+
+/* The target_wait operation waits for a process event to occur, and
+ thereby stop the process.
+
+ On some targets, certain events may happen in sequences. gdb's
+ correct response to any single event of such a sequence may require
+ knowledge of what earlier events in the sequence have been seen.
+
+ This operation provides a target-specific hook that allows the
+ necessary bookkeeping to be performed to track such sequences. */
+
+#define target_post_wait(ptid, status) \
+ (*current_target.to_post_wait) (ptid, status)
+
+/* Fetch at least register REGNO, or all regs if regno == -1. No result. */
+
+#define target_fetch_registers(regno) \
+ (*current_target.to_fetch_registers) (regno)
+
+/* Store at least register REGNO, or all regs if REGNO == -1.
+ It can store as many registers as it wants to, so target_prepare_to_store
+ must have been previously called. Calls error() if there are problems. */
+
+#define target_store_registers(regs) \
+ (*current_target.to_store_registers) (regs)
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that REGISTERS contains all the registers from the program being
+ debugged. */
+
+#define target_prepare_to_store() \
+ (*current_target.to_prepare_to_store) ()
+
+extern DCACHE *target_dcache;
+
+extern int do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib);
+
+extern int target_read_string (CORE_ADDR, char **, int, int *);
+
+extern int target_read_memory (CORE_ADDR memaddr, char *myaddr, int len);
+
+extern int target_write_memory (CORE_ADDR memaddr, char *myaddr, int len);
+
+extern int xfer_memory (CORE_ADDR, char *, int, int,
+ struct mem_attrib *, struct target_ops *);
+
+extern int child_xfer_memory (CORE_ADDR, char *, int, int,
+ struct mem_attrib *, struct target_ops *);
+
+/* Make a single attempt at transfering LEN bytes. On a successful
+ transfer, the number of bytes actually transfered is returned and
+ ERR is set to 0. When a transfer fails, -1 is returned (the number
+ of bytes actually transfered is not defined) and ERR is set to a
+ non-zero error indication. */
+
+extern int
+target_read_memory_partial (CORE_ADDR addr, char *buf, int len, int *err);
+
+extern int
+target_write_memory_partial (CORE_ADDR addr, char *buf, int len, int *err);
+
+extern char *child_pid_to_exec_file (int);
+
+extern char *child_core_file_to_sym_file (char *);
+
+#if defined(CHILD_POST_ATTACH)
+extern void child_post_attach (int);
+#endif
+
+extern void child_post_wait (ptid_t, int);
+
+extern void child_post_startup_inferior (ptid_t);
+
+extern void child_acknowledge_created_inferior (int);
+
+extern void child_clone_and_follow_inferior (int, int *);
+
+extern void child_post_follow_inferior_by_clone (void);
+
+extern int child_insert_fork_catchpoint (int);
+
+extern int child_remove_fork_catchpoint (int);
+
+extern int child_insert_vfork_catchpoint (int);
+
+extern int child_remove_vfork_catchpoint (int);
+
+extern int child_has_forked (int, int *);
+
+extern int child_has_vforked (int, int *);
+
+extern void child_acknowledge_created_inferior (int);
+
+extern int child_can_follow_vfork_prior_to_exec (void);
+
+extern void child_post_follow_vfork (int, int, int, int);
+
+extern int child_insert_exec_catchpoint (int);
+
+extern int child_remove_exec_catchpoint (int);
+
+extern int child_has_execd (int, char **);
+
+extern int child_reported_exec_events_per_exec_call (void);
+
+extern int child_has_syscall_event (int, enum target_waitkind *, int *);
+
+extern int child_has_exited (int, int, int *);
+
+extern int child_thread_alive (ptid_t);
+
+/* From exec.c */
+
+extern void print_section_info (struct target_ops *, bfd *);
+
+/* Print a line about the current target. */
+
+#define target_files_info() \
+ (*current_target.to_files_info) (&current_target)
+
+/* Insert a breakpoint at address ADDR in the target machine.
+ SAVE is a pointer to memory allocated for saving the
+ target contents. It is guaranteed by the caller to be long enough
+ to save "sizeof BREAKPOINT" bytes. Result is 0 for success, or
+ an errno value. */
+
+#define target_insert_breakpoint(addr, save) \
+ (*current_target.to_insert_breakpoint) (addr, save)
+
+/* Remove a breakpoint at address ADDR in the target machine.
+ SAVE is a pointer to the same save area
+ that was previously passed to target_insert_breakpoint.
+ Result is 0 for success, or an errno value. */
+
+#define target_remove_breakpoint(addr, save) \
+ (*current_target.to_remove_breakpoint) (addr, save)
+
+/* Initialize the terminal settings we record for the inferior,
+ before we actually run the inferior. */
+
+#define target_terminal_init() \
+ (*current_target.to_terminal_init) ()
+
+/* Put the inferior's terminal settings into effect.
+ This is preparation for starting or resuming the inferior. */
+
+#define target_terminal_inferior() \
+ (*current_target.to_terminal_inferior) ()
+
+/* Put some of our terminal settings into effect,
+ enough to get proper results from our output,
+ but do not change into or out of RAW mode
+ so that no input is discarded.
+
+ After doing this, either terminal_ours or terminal_inferior
+ should be called to get back to a normal state of affairs. */
+
+#define target_terminal_ours_for_output() \
+ (*current_target.to_terminal_ours_for_output) ()
+
+/* Put our terminal settings into effect.
+ First record the inferior's terminal settings
+ so they can be restored properly later. */
+
+#define target_terminal_ours() \
+ (*current_target.to_terminal_ours) ()
+
+/* Print useful information about our terminal status, if such a thing
+ exists. */
+
+#define target_terminal_info(arg, from_tty) \
+ (*current_target.to_terminal_info) (arg, from_tty)
+
+/* Kill the inferior process. Make it go away. */
+
+#define target_kill() \
+ (*current_target.to_kill) ()
+
+/* Load an executable file into the target process. This is expected
+ to not only bring new code into the target process, but also to
+ update GDB's symbol tables to match. */
+
+extern void target_load (char *arg, int from_tty);
+
+/* Look up a symbol in the target's symbol table. NAME is the symbol
+ name. ADDRP is a CORE_ADDR * pointing to where the value of the
+ symbol should be returned. The result is 0 if successful, nonzero
+ if the symbol does not exist in the target environment. This
+ function should not call error() if communication with the target
+ is interrupted, since it is called from symbol reading, but should
+ return nonzero, possibly doing a complain(). */
+
+#define target_lookup_symbol(name, addrp) \
+ (*current_target.to_lookup_symbol) (name, addrp)
+
+/* Start an inferior process and set inferior_ptid 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().
+ On VxWorks and various standalone systems, we ignore exec_file. */
+
+#define target_create_inferior(exec_file, args, env) \
+ (*current_target.to_create_inferior) (exec_file, args, env)
+
+
+/* Some targets (such as ttrace-based HPUX) don't allow us to request
+ notification of inferior events such as fork and vork immediately
+ after the inferior is created. (This because of how gdb gets an
+ inferior created via invoking a shell to do it. In such a scenario,
+ if the shell init file has commands in it, the shell will fork and
+ exec for each of those commands, and we will see each such fork
+ event. Very bad.)
+
+ Such targets will supply an appropriate definition for this function. */
+
+#define target_post_startup_inferior(ptid) \
+ (*current_target.to_post_startup_inferior) (ptid)
+
+/* On some targets, the sequence of starting up an inferior requires
+ some synchronization between gdb and the new inferior process, PID. */
+
+#define target_acknowledge_created_inferior(pid) \
+ (*current_target.to_acknowledge_created_inferior) (pid)
+
+/* An inferior process has been created via a fork() or similar
+ system call. This function will clone the debugger, then ensure
+ that CHILD_PID is attached to by that debugger.
+
+ FOLLOWED_CHILD is set TRUE on return *for the clone debugger only*,
+ and FALSE otherwise. (The original and clone debuggers can use this
+ to determine which they are, if need be.)
+
+ (This is not a terribly useful feature without a GUI to prevent
+ the two debuggers from competing for shell input.) */
+
+#define target_clone_and_follow_inferior(child_pid,followed_child) \
+ (*current_target.to_clone_and_follow_inferior) (child_pid, followed_child)
+
+/* This operation is intended to be used as the last in a sequence of
+ steps taken when following both parent and child of a fork. This
+ is used by a clone of the debugger, which will follow the child.
+
+ The original debugger has detached from this process, and the
+ clone has attached to it.
+
+ On some targets, this requires a bit of cleanup to make it work
+ correctly. */
+
+#define target_post_follow_inferior_by_clone() \
+ (*current_target.to_post_follow_inferior_by_clone) ()
+
+/* On some targets, we can catch an inferior fork or vfork event when
+ it occurs. These functions insert/remove an already-created
+ catchpoint for such events. */
+
+#define target_insert_fork_catchpoint(pid) \
+ (*current_target.to_insert_fork_catchpoint) (pid)
+
+#define target_remove_fork_catchpoint(pid) \
+ (*current_target.to_remove_fork_catchpoint) (pid)
+
+#define target_insert_vfork_catchpoint(pid) \
+ (*current_target.to_insert_vfork_catchpoint) (pid)
+
+#define target_remove_vfork_catchpoint(pid) \
+ (*current_target.to_remove_vfork_catchpoint) (pid)
+
+/* Returns TRUE if PID has invoked the fork() system call. And,
+ also sets CHILD_PID to the process id of the other ("child")
+ inferior process that was created by that call. */
+
+#define target_has_forked(pid,child_pid) \
+ (*current_target.to_has_forked) (pid,child_pid)
+
+/* Returns TRUE if PID has invoked the vfork() system call. And,
+ also sets CHILD_PID to the process id of the other ("child")
+ inferior process that was created by that call. */
+
+#define target_has_vforked(pid,child_pid) \
+ (*current_target.to_has_vforked) (pid,child_pid)
+
+/* Some platforms (such as pre-10.20 HP-UX) don't allow us to do
+ anything to a vforked child before it subsequently calls exec().
+ On such platforms, we say that the debugger cannot "follow" the
+ child until it has vforked.
+
+ This function should be defined to return 1 by those targets
+ which can allow the debugger to immediately follow a vforked
+ child, and 0 if they cannot. */
+
+#define target_can_follow_vfork_prior_to_exec() \
+ (*current_target.to_can_follow_vfork_prior_to_exec) ()
+
+/* An inferior process has been created via a vfork() system call.
+ The debugger has followed the parent, the child, or both. The
+ process of setting up for that follow may have required some
+ target-specific trickery to track the sequence of reported events.
+ If so, this function should be defined by those targets that
+ require the debugger to perform cleanup or initialization after
+ the vfork follow. */
+
+#define target_post_follow_vfork(parent_pid,followed_parent,child_pid,followed_child) \
+ (*current_target.to_post_follow_vfork) (parent_pid,followed_parent,child_pid,followed_child)
+
+/* On some targets, we can catch an inferior exec event when it
+ occurs. These functions insert/remove an already-created
+ catchpoint for such events. */
+
+#define target_insert_exec_catchpoint(pid) \
+ (*current_target.to_insert_exec_catchpoint) (pid)
+
+#define target_remove_exec_catchpoint(pid) \
+ (*current_target.to_remove_exec_catchpoint) (pid)
+
+/* Returns TRUE if PID has invoked a flavor of the exec() system call.
+ And, also sets EXECD_PATHNAME to the pathname of the executable
+ file that was passed to exec(), and is now being executed. */
+
+#define target_has_execd(pid,execd_pathname) \
+ (*current_target.to_has_execd) (pid,execd_pathname)
+
+/* Returns the number of exec events that are reported when a process
+ invokes a flavor of the exec() system call on this target, if exec
+ events are being reported. */
+
+#define target_reported_exec_events_per_exec_call() \
+ (*current_target.to_reported_exec_events_per_exec_call) ()
+
+/* Returns TRUE if PID has reported a syscall event. And, also sets
+ KIND to the appropriate TARGET_WAITKIND_, and sets SYSCALL_ID to
+ the unique integer ID of the syscall. */
+
+#define target_has_syscall_event(pid,kind,syscall_id) \
+ (*current_target.to_has_syscall_event) (pid,kind,syscall_id)
+
+/* Returns TRUE if PID has exited. And, also sets EXIT_STATUS to the
+ exit code of PID, if any. */
+
+#define target_has_exited(pid,wait_status,exit_status) \
+ (*current_target.to_has_exited) (pid,wait_status,exit_status)
+
+/* The debugger has completed a blocking wait() call. There is now
+ some process event that must be processed. This function should
+ be defined by those targets that require the debugger to perform
+ cleanup or internal state changes in response to the process event. */
+
+/* The inferior process has died. Do what is right. */
+
+#define target_mourn_inferior() \
+ (*current_target.to_mourn_inferior) ()
+
+/* Does target have enough data to do a run or attach command? */
+
+#define target_can_run(t) \
+ ((t)->to_can_run) ()
+
+/* post process changes to signal handling in the inferior. */
+
+#define target_notice_signals(ptid) \
+ (*current_target.to_notice_signals) (ptid)
+
+/* Check to see if a thread is still alive. */
+
+#define target_thread_alive(ptid) \
+ (*current_target.to_thread_alive) (ptid)
+
+/* Query for new threads and add them to the thread list. */
+
+#define target_find_new_threads() \
+ (*current_target.to_find_new_threads) (); \
+
+/* Make target stop in a continuable fashion. (For instance, under
+ Unix, this should act like SIGSTOP). This function is normally
+ used by GUIs to implement a stop button. */
+
+#define target_stop current_target.to_stop
+
+/* Queries the target side for some information. The first argument is a
+ letter specifying the type of the query, which is used to determine who
+ should process it. The second argument is a string that specifies which
+ information is desired and the third is a buffer that carries back the
+ response from the target side. The fourth parameter is the size of the
+ output buffer supplied. */
+
+#define target_query(query_type, query, resp_buffer, bufffer_size) \
+ (*current_target.to_query) (query_type, query, resp_buffer, bufffer_size)
+
+/* Send the specified COMMAND to the target's monitor
+ (shell,interpreter) for execution. The result of the query is
+ placed in OUTBUF. */
+
+#define target_rcmd(command, outbuf) \
+ (*current_target.to_rcmd) (command, outbuf)
+
+
+/* Get the symbol information for a breakpointable routine called when
+ an exception event occurs.
+ Intended mainly for C++, and for those
+ platforms/implementations where such a callback mechanism is available,
+ e.g. HP-UX with ANSI C++ (aCC). Some compilers (e.g. g++) support
+ different mechanisms for debugging exceptions. */
+
+#define target_enable_exception_callback(kind, enable) \
+ (*current_target.to_enable_exception_callback) (kind, enable)
+
+/* Get the current exception event kind -- throw or catch, etc. */
+
+#define target_get_current_exception_event() \
+ (*current_target.to_get_current_exception_event) ()
+
+/* Pointer to next target in the chain, e.g. a core file and an exec file. */
+
+#define target_next \
+ (current_target.to_next)
+
+/* Does the target include all of memory, or only part of it? This
+ determines whether we look up the target chain for other parts of
+ memory if this target can't satisfy a request. */
+
+#define target_has_all_memory \
+ (current_target.to_has_all_memory)
+
+/* Does the target include memory? (Dummy targets don't.) */
+
+#define target_has_memory \
+ (current_target.to_has_memory)
+
+/* Does the target have a stack? (Exec files don't, VxWorks doesn't, until
+ we start a process.) */
+
+#define target_has_stack \
+ (current_target.to_has_stack)
+
+/* Does the target have registers? (Exec files don't.) */
+
+#define target_has_registers \
+ (current_target.to_has_registers)
+
+/* Does the target have execution? Can we make it jump (through
+ hoops), or pop its stack a few times? FIXME: If this is to work that
+ way, it needs to check whether an inferior actually exists.
+ remote-udi.c and probably other targets can be the current target
+ when the inferior doesn't actually exist at the moment. Right now
+ this just tells us whether this target is *capable* of execution. */
+
+#define target_has_execution \
+ (current_target.to_has_execution)
+
+/* Can the target support the debugger control of thread execution?
+ a) Can it lock the thread scheduler?
+ b) Can it switch the currently running thread? */
+
+#define target_can_lock_scheduler \
+ (current_target.to_has_thread_control & tc_schedlock)
+
+#define target_can_switch_threads \
+ (current_target.to_has_thread_control & tc_switch)
+
+/* Can the target support asynchronous execution? */
+#define target_can_async_p() (current_target.to_can_async_p ())
+
+/* Is the target in asynchronous execution mode? */
+#define target_is_async_p() (current_target.to_is_async_p())
+
+/* Put the target in async mode with the specified callback function. */
+#define target_async(CALLBACK,CONTEXT) \
+ (current_target.to_async((CALLBACK), (CONTEXT)))
+
+/* This is to be used ONLY within run_stack_dummy(). It
+ provides a workaround, to have inferior function calls done in
+ sychronous mode, even though the target is asynchronous. After
+ target_async_mask(0) is called, calls to target_can_async_p() will
+ return FALSE , so that target_resume() will not try to start the
+ target asynchronously. After the inferior stops, we IMMEDIATELY
+ restore the previous nature of the target, by calling
+ target_async_mask(1). After that, target_can_async_p() will return
+ TRUE. ANY OTHER USE OF THIS FEATURE IS DEPRECATED.
+
+ FIXME ezannoni 1999-12-13: we won't need this once we move
+ the turning async on and off to the single execution commands,
+ from where it is done currently, in remote_resume(). */
+
+#define target_async_mask_value \
+ (current_target.to_async_mask_value)
+
+extern int target_async_mask (int mask);
+
+extern void target_link (char *, CORE_ADDR *);
+
+/* Converts a process id to a string. Usually, the string just contains
+ `process xyz', but on some systems it may contain
+ `process xyz thread abc'. */
+
+#undef target_pid_to_str
+#define target_pid_to_str(PID) current_target.to_pid_to_str (PID)
+
+#ifndef target_tid_to_str
+#define target_tid_to_str(PID) \
+ target_pid_to_str (PID)
+extern char *normal_pid_to_str (ptid_t ptid);
+#endif
+
+/* Return a short string describing extra information about PID,
+ e.g. "sleeping", "runnable", "running on LWP 3". Null return value
+ is okay. */
+
+#define target_extra_thread_info(TP) \
+ (current_target.to_extra_thread_info (TP))
+
+/*
+ * New Objfile Event Hook:
+ *
+ * Sometimes a GDB component wants to get notified whenever a new
+ * objfile is loaded. Mainly this is used by thread-debugging
+ * implementations that need to know when symbols for the target
+ * thread implemenation are available.
+ *
+ * The old way of doing this is to define a macro 'target_new_objfile'
+ * that points to the function that you want to be called on every
+ * objfile/shlib load.
+ *
+ * The new way is to grab the function pointer, 'target_new_objfile_hook',
+ * and point it to the function that you want to be called on every
+ * objfile/shlib load.
+ *
+ * If multiple clients are willing to be cooperative, they can each
+ * save a pointer to the previous value of target_new_objfile_hook
+ * before modifying it, and arrange for their function to call the
+ * previous function in the chain. In that way, multiple clients
+ * can receive this notification (something like with signal handlers).
+ */
+
+extern void (*target_new_objfile_hook) (struct objfile *);
+
+#ifndef target_pid_or_tid_to_str
+#define target_pid_or_tid_to_str(ID) \
+ target_pid_to_str (ID)
+#endif
+
+/* Attempts to find the pathname of the executable file
+ that was run to create a specified process.
+
+ The process PID must be stopped when this operation is used.
+
+ If the executable file cannot be determined, NULL is returned.
+
+ Else, a pointer to a character string containing the pathname
+ is returned. This string should be copied into a buffer by
+ the client if the string will not be immediately used, or if
+ it must persist. */
+
+#define target_pid_to_exec_file(pid) \
+ (current_target.to_pid_to_exec_file) (pid)
+
+/*
+ * Iterator function for target memory regions.
+ * Calls a callback function once for each memory region 'mapped'
+ * in the child process. Defined as a simple macro rather than
+ * as a function macro so that it can be tested for nullity.
+ */
+
+#define target_find_memory_regions(FUNC, DATA) \
+ (current_target.to_find_memory_regions) (FUNC, DATA)
+
+/*
+ * Compose corefile .note section.
+ */
+
+#define target_make_corefile_notes(BFD, SIZE_P) \
+ (current_target.to_make_corefile_notes) (BFD, SIZE_P)
+
+/* Hook to call target-dependent code after reading in a new symbol table. */
+
+#ifndef TARGET_SYMFILE_POSTREAD
+#define TARGET_SYMFILE_POSTREAD(OBJFILE)
+#endif
+
+/* Hook to call target dependent code just after inferior target process has
+ started. */
+
+#ifndef TARGET_CREATE_INFERIOR_HOOK
+#define TARGET_CREATE_INFERIOR_HOOK(PID)
+#endif
+
+/* Hardware watchpoint interfaces. */
+
+/* Returns non-zero if we were stopped by a hardware watchpoint (memory read or
+ write). */
+
+#ifndef STOPPED_BY_WATCHPOINT
+#define STOPPED_BY_WATCHPOINT(w) 0
+#endif
+
+/* HP-UX supplies these operations, which respectively disable and enable
+ the memory page-protections that are used to implement hardware watchpoints
+ on that platform. See wait_for_inferior's use of these. */
+
+#if !defined(TARGET_DISABLE_HW_WATCHPOINTS)
+#define TARGET_DISABLE_HW_WATCHPOINTS(pid)
+#endif
+
+#if !defined(TARGET_ENABLE_HW_WATCHPOINTS)
+#define TARGET_ENABLE_HW_WATCHPOINTS(pid)
+#endif
+
+/* Provide defaults for systems that don't support hardware watchpoints. */
+
+#ifndef TARGET_HAS_HARDWARE_WATCHPOINTS
+
+/* Returns non-zero if we can set a hardware watchpoint of type TYPE. TYPE is
+ one of bp_hardware_watchpoint, bp_read_watchpoint, bp_write_watchpoint, or
+ bp_hardware_breakpoint. CNT is the number of such watchpoints used so far
+ (including this one?). OTHERTYPE is who knows what... */
+
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE,CNT,OTHERTYPE) 0
+
+#if !defined(TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT)
+#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(byte_count) \
+ ((LONGEST)(byte_count) <= REGISTER_SIZE)
+#endif
+
+
+/* Set/clear a hardware watchpoint starting at ADDR, for LEN bytes. TYPE is 0
+ for write, 1 for read, and 2 for read/write accesses. Returns 0 for
+ success, non-zero for failure. */
+
+#define target_remove_watchpoint(ADDR,LEN,TYPE) -1
+#define target_insert_watchpoint(ADDR,LEN,TYPE) -1
+
+#endif /* TARGET_HAS_HARDWARE_WATCHPOINTS */
+
+#ifndef target_insert_hw_breakpoint
+#define target_remove_hw_breakpoint(ADDR,SHADOW) -1
+#define target_insert_hw_breakpoint(ADDR,SHADOW) -1
+#endif
+
+#ifndef target_stopped_data_address
+#define target_stopped_data_address() 0
+#endif
+
+/* If defined, then we need to decr pc by this much after a hardware break-
+ point. Presumably this overrides DECR_PC_AFTER_BREAK... */
+
+#ifndef DECR_PC_AFTER_HW_BREAK
+#define DECR_PC_AFTER_HW_BREAK 0
+#endif
+
+/* Sometimes gdb may pick up what appears to be a valid target address
+ from a minimal symbol, but the value really means, essentially,
+ "This is an index into a table which is populated when the inferior
+ is run. Therefore, do not attempt to use this as a PC." */
+
+#if !defined(PC_REQUIRES_RUN_BEFORE_USE)
+#define PC_REQUIRES_RUN_BEFORE_USE(pc) (0)
+#endif
+
+/* This will only be defined by a target that supports catching vfork events,
+ such as HP-UX.
+
+ On some targets (such as HP-UX 10.20 and earlier), resuming a newly vforked
+ child process after it has exec'd, causes the parent process to resume as
+ well. To prevent the parent from running spontaneously, such targets should
+ define this to a function that prevents that from happening. */
+#if !defined(ENSURE_VFORKING_PARENT_REMAINS_STOPPED)
+#define ENSURE_VFORKING_PARENT_REMAINS_STOPPED(PID) (0)
+#endif
+
+/* This will only be defined by a target that supports catching vfork events,
+ such as HP-UX.
+
+ On some targets (such as HP-UX 10.20 and earlier), a newly vforked child
+ process must be resumed when it delivers its exec event, before the parent
+ vfork event will be delivered to us. */
+
+#if !defined(RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK)
+#define RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK() (0)
+#endif
+
+/* Routines for maintenance of the target structures...
+
+ add_target: Add a target to the list of all possible targets.
+
+ push_target: Make this target the top of the stack of currently used
+ targets, within its particular stratum of the stack. Result
+ is 0 if now atop the stack, nonzero if not on top (maybe
+ should warn user).
+
+ unpush_target: Remove this from the stack of currently used targets,
+ no matter where it is on the list. Returns 0 if no
+ change, 1 if removed from stack.
+
+ pop_target: Remove the top thing on the stack of current targets. */
+
+extern void add_target (struct target_ops *);
+
+extern int push_target (struct target_ops *);
+
+extern int unpush_target (struct target_ops *);
+
+extern void target_preopen (int);
+
+extern void pop_target (void);
+
+/* Struct section_table maps address ranges to file sections. It is
+ mostly used with BFD files, but can be used without (e.g. for handling
+ raw disks, or files not in formats handled by BFD). */
+
+struct section_table
+ {
+ CORE_ADDR addr; /* Lowest address in section */
+ CORE_ADDR endaddr; /* 1+highest address in section */
+
+ sec_ptr the_bfd_section;
+
+ bfd *bfd; /* BFD file pointer */
+ };
+
+/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR.
+ Returns 0 if OK, 1 on error. */
+
+extern int
+build_section_table (bfd *, struct section_table **, struct section_table **);
+
+/* From mem-break.c */
+
+extern int memory_remove_breakpoint (CORE_ADDR, char *);
+
+extern int memory_insert_breakpoint (CORE_ADDR, char *);
+
+extern int default_memory_remove_breakpoint (CORE_ADDR, char *);
+
+extern int default_memory_insert_breakpoint (CORE_ADDR, char *);
+
+extern const unsigned char *memory_breakpoint_from_pc (CORE_ADDR *pcptr,
+ int *lenptr);
+
+
+/* From target.c */
+
+extern void initialize_targets (void);
+
+extern void noprocess (void);
+
+extern void find_default_attach (char *, int);
+
+extern void find_default_require_attach (char *, int);
+
+extern void find_default_require_detach (int, char *, int);
+
+extern void find_default_create_inferior (char *, char *, char **);
+
+extern void find_default_clone_and_follow_inferior (int, int *);
+
+extern struct target_ops *find_run_target (void);
+
+extern struct target_ops *find_core_target (void);
+
+extern struct target_ops *find_target_beneath (struct target_ops *);
+
+extern int
+target_resize_to_sections (struct target_ops *target, int num_added);
+
+extern void remove_target_sections (bfd *abfd);
+
+
+/* Stuff that should be shared among the various remote targets. */
+
+/* Debugging level. 0 is off, and non-zero values mean to print some debug
+ information (higher values, more information). */
+extern int remote_debug;
+
+/* Speed in bits per second, or -1 which means don't mess with the speed. */
+extern int baud_rate;
+/* Timeout limit for response from target. */
+extern int remote_timeout;
+
+
+/* Functions for helping to write a native target. */
+
+/* This is for native targets which use a unix/POSIX-style waitstatus. */
+extern void store_waitstatus (struct target_waitstatus *, int);
+
+/* Predicate to target_signal_to_host(). Return non-zero if the enum
+ targ_signal SIGNO has an equivalent ``host'' representation. */
+/* FIXME: cagney/1999-11-22: The name below was chosen in preference
+ to the shorter target_signal_p() because it is far less ambigious.
+ In this context ``target_signal'' refers to GDB's internal
+ representation of the target's set of signals while ``host signal''
+ refers to the target operating system's signal. Confused? */
+
+extern int target_signal_to_host_p (enum target_signal signo);
+
+/* Convert between host signal numbers and enum target_signal's.
+ target_signal_to_host() returns 0 and prints a warning() on GDB's
+ console if SIGNO has no equivalent host representation. */
+/* FIXME: cagney/1999-11-22: Here ``host'' is used incorrectly, it is
+ refering to the target operating system's signal numbering.
+ Similarly, ``enum target_signal'' is named incorrectly, ``enum
+ gdb_signal'' would probably be better as it is refering to GDB's
+ internal representation of a target operating system's signal. */
+
+extern enum target_signal target_signal_from_host (int);
+extern int target_signal_to_host (enum target_signal);
+
+/* Convert from a number used in a GDB command to an enum target_signal. */
+extern enum target_signal target_signal_from_command (int);
+
+/* Any target can call this to switch to remote protocol (in remote.c). */
+extern void push_remote_target (char *name, int from_tty);
+
+/* Imported from machine dependent code */
+
+/* Blank target vector entries are initialized to target_ignore. */
+void target_ignore (void);
+
+#endif /* !defined (TARGET_H) */
diff --git a/gdb/terminal.h b/gdb/terminal.h
new file mode 100644
index 00000000000..cb164515cf6
--- /dev/null
+++ b/gdb/terminal.h
@@ -0,0 +1,91 @@
+/* Terminal interface definitions for GDB, the GNU Debugger.
+ Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1995, 1996, 1999, 2000
+ 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. */
+
+#if !defined (TERMINAL_H)
+#define TERMINAL_H 1
+
+
+/* If we're using autoconf, it will define HAVE_TERMIOS_H,
+ HAVE_TERMIO_H and HAVE_SGTTY_H for us. One day we can rewrite
+ ser-unix.c and inflow.c to inspect those names instead of
+ HAVE_TERMIOS, HAVE_TERMIO and the implicit HAVE_SGTTY (when neither
+ HAVE_TERMIOS or HAVE_TERMIO is set). Until then, make sure that
+ nothing has already defined the one of the names, and do the right
+ thing. */
+
+#if !defined (HAVE_TERMIOS) && !defined(HAVE_TERMIO) && !defined(HAVE_SGTTY)
+#if defined(HAVE_TERMIOS_H)
+#define HAVE_TERMIOS
+#else /* ! defined (HAVE_TERMIOS_H) */
+#if defined(HAVE_TERMIO_H)
+#define HAVE_TERMIO
+#else /* ! defined (HAVE_TERMIO_H) */
+#if defined(HAVE_SGTTY_H)
+#define HAVE_SGTTY
+#endif /* ! defined (HAVE_SGTTY_H) */
+#endif /* ! defined (HAVE_TERMIO_H) */
+#endif /* ! defined (HAVE_TERMIOS_H) */
+#endif /* !defined (HAVE_TERMIOS) && !defined(HAVE_TERMIO) && !defined(HAVE_SGTTY) */
+
+#if defined(HAVE_TERMIOS)
+#include <termios.h>
+#endif
+
+#if !defined(_WIN32) && !defined (HAVE_TERMIOS)
+
+/* Define a common set of macros -- BSD based -- and redefine whatever
+ the system offers to make it look like that. FIXME: serial.h and
+ ser-*.c deal with this in a much cleaner fashion; as soon as stuff
+ is converted to use them, can get rid of this crap. */
+
+#ifdef HAVE_TERMIO
+
+#include <termio.h>
+
+#undef TIOCGETP
+#define TIOCGETP TCGETA
+#undef TIOCSETN
+#define TIOCSETN TCSETA
+#undef TIOCSETP
+#define TIOCSETP TCSETAF
+#define TERMINAL struct termio
+
+#else /* sgtty */
+
+#include <fcntl.h>
+#include <sgtty.h>
+#include <sys/ioctl.h>
+#define TERMINAL struct sgttyb
+
+#endif /* sgtty */
+#endif
+
+extern void new_tty (void);
+
+/* Do we have job control? Can be assumed to always be the same within
+ a given run of GDB. In inflow.c. */
+extern int job_control;
+
+/* Set the process group of the caller to its own pid, or do nothing if
+ we lack job control. */
+extern int gdb_setpgid (void);
+
+#endif /* !defined (TERMINAL_H) */
diff --git a/gdb/testsuite/.gdbinit b/gdb/testsuite/.gdbinit
new file mode 100644
index 00000000000..62bcb743093
--- /dev/null
+++ b/gdb/testsuite/.gdbinit
@@ -0,0 +1 @@
+set height 400
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
new file mode 100644
index 00000000000..c033fa374fe
--- /dev/null
+++ b/gdb/testsuite/ChangeLog
@@ -0,0 +1,9078 @@
+2002-05-27 Michael Chastain <mec@shout.net>
+From Benjamin Kosnik <bkoz@redhat.com>
+
+ * gdb.c++/m-data.cc: New file.
+ * gdb.c++/m-data.exp: New file.
+
+2002-05-27 Michael Chastain <mec@shout.net>
+From Benjamin Kosnik <bkoz@redhat.com>
+
+ * gdb.c++/try_catch.cc: New file.
+ * gdb.c++/try_catch.exp: New file.
+
+2002-05-27 Michael Chastain <mec@shout.net>
+
+ * gdb.c++/local.exp: Accept more nested types in output.
+
+2002-05-26 Michael Chastain <mec@shout.net>
+
+ * gdb.base/call-rt-st.exp: Fix typo in brace quoting.
+
+2002-05-15 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * lib/gdb.exp (gdb_wrapper_init): Just because
+ gdb_wrapper_file exists, this does not mean that the file
+ should not be rebuilt. That is what gdb_wrapper_initialized
+ is for.
+ (default_gdb_init): Reset gdb_wrapper_initialized.
+
+2002-05-23 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/all-bin.exp: Revise previous patch by just reducing
+ the precision of the floating point test results.
+ * gdb.base/call-rt-st.exp: Ditto.
+
+ * gdb.base/all-bin.exp: Allow for reduced floating point precision.
+ * gdb.base/call-rt-st.exp: Ditto.
+
+2002-05-19 Michael Chastain <mec@shout.net>
+
+ * gdb.c++/inherit.exp: Accept "VTT for ..." in output strings.
+
+2002-05-19 Elena Zannoni <ezannoni@redhat.com>
+
+ * configure.in (configdirs): Add gdb.arch.
+ * configure: Regenerate.
+
+2002-05-17 Jim Blandy <jimb@redhat.com>
+
+ * gdb.base/completion.exp: Recognize the more detailed error
+ messages produced by the macro expander's lexical analyzer.
+
+2002-05-14 Elena Zannoni <ezannoni@redhat.com>
+
+ * gdb.arch/altivec-abi.c: New file.
+ * gdb.arch/altivec-abi.exp: New file.
+ * gdb.arch/altivec-regs.c: New file.
+ * gdb.arch/altivec-regs.exp: New file.
+
+2002-05-14 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.base/maint.exp (maint print type): Update for new type
+ structure.
+
+2002-05-14 Elena Zannoni <ezannoni@redhat.com>
+
+ * gdb.arch: New directory.
+ * gdb.arch/configure.in: New file.
+ * gdb.arch/configure: New file.
+ * gdb.arch/Makefile.in: New file.
+
+2002-05-13 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.asm/asm-source.exp: Add v850 as supported target.
+ * gdb.asm/v850.inc: New file.
+
+2002-05-13 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.c++/annota2.exp (annotate-quit): Add comment.
+
+2002-05-12 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.base/break.exp: Check 'break "marker2"'.
+
+2002-05-10 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/long_long.exp: Fix typo.
+
+2002-05-10 Jim Blandy <jimb@redhat.com>
+
+ * gdb.base/printcmds.exp: Don't xfail the ptype command. This is
+ a bug.
+
+ * gdb.base/printcmds.exp (test_integer_literals_rejected):
+ Recognize more detailed error message produced by the macro
+ expander's lexical analyzer.
+ * lib/gdb.exp (test_print_reject): Same.
+
+2002-05-09 Mark Kettenis <kettenis@gnu.org>
+
+ * gdb.c++/method.exp: Fix typo.
+
+2002-05-08 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.mi/mi-var-child.exp: Accept (void) as well as ().
+ * gdb.mi/mi0-var-child.exp: Accept (void) as well as ().
+ * gdb.base/default.exp: Merge clauses for arm, strongarm, xscale.
+ * gdb.base/long_long.exp: Merge clauses for arm and xscale.
+ Add iftarget clause for strongarm.
+
+2002-05-06 Michael Snyder <msnyder@redhat.com>
+
+ * lib/gdb.exp (gdb_test): Add case to allow for status wrapper.
+ (gdb_continue_to_end): Accept output from status wrapper.
+ * gdb.base/ending-run.exp: Add case for output from status wrapper.
+ Clean up fail messages to match pass messages.
+
+ Enable the "needs_status_wrapper" testsuite feature.
+ * lib/gdb.exp (gdb_wrapper_init): New procedure.
+ (gdb_compile): Conditionally call gdb_wrapper_init.
+ * gdb.base/a2-run.exp: Recognize output from status wrapper.
+ * gdb.c++/method.exp: Recognize output from status wrapper.
+
+2002-05-06 Ben Elliston <bje@redhat.com>
+From Graydon Hoare <graydon@redhat.com>
+
+ * config/sid.exp: Include support for "rawsid" protocol.
+
+2002-05-03 Jim Blandy <jimb@redhat.com>
+
+ * gdb.c++/hang.exp: Check for corruption of the cv_type chain.
+ * gdb.c++/hang3.C: New file.
+
+2002-05-04 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.base/default.exp: Remove obsolete code.
+ * gdb.c++/misc.exp: Ditto. Update copyright.
+ * gdb.c++/cplusfuncs.exp: Ditto. Update copyright.
+ * gdb.base/whatis.exp: Ditto. Update copyright.
+ * gdb.base/scope.exp: Ditto. Update copyright.
+ * gdb.base/ptype.exp: Ditto. Update copyright.
+ * gdb.base/printcmds.exp: Ditto. Update copyright.
+ * gdb.base/opaque.exp: Ditto. Update copyright.
+ * gdb.base/list.exp: Ditto.
+ * gdb.base/funcargs.exp: Ditto. Update copyright.
+ * gdb.hp/gdb.threads-hp/usrthbasic.c: Delete.
+ * gdb.hp/gdb.threads-hp/usrthbasic.exp: Delete.
+ * gdb.hp/gdb.threads-hp/usrthcore.c: Delete.
+ * gdb.hp/gdb.threads-hp/usrthcore.exp: Delete.
+ * gdb.hp/gdb.threads-hp/usrthfork.c: Delete.
+ * gdb.hp/gdb.threads-hp/usrthfork.exp: Delete.
+
+2002-05-02 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/watchpoint.exp: Add xscale target.
+ * gdb.base/long_long.exp: Add xscale target.
+ * gdb.base/default.exp: Add xscale target.
+
+2002-05-01 Jim Blandy <jimb@redhat.com>
+
+ * gdb.c++/hang1.C, gdb.c++/hang2.C, gdb.c++/hang.H,
+ gdb.c++/hang.exp: New test.
+
+2002-05-01 Fred Fish <fnf@redhat.com>
+
+ * gdb.base/completion.exp: Handle completions of "./Make" for
+ more than one completion possibility, as is the case when we
+ build and test in the source tree.
+
+2002-04-29 Anthony Green <green@redhat.com>
+
+ * gdb.java/jmisc1.exp: New file.
+ * gdb.java/jmisc2.exp: New file.
+
+2002-04-24 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.threads/linux-dp.exp: Use 'unset' instead of 'array unset'.
+
+2002-04-23 Elena Zannoni <ezannoni@redhat.com>
+
+ * gdb.base/help.exp: Change 'help status' to allow for target
+ dependent output differences.
+
+2002-04-22 Michael Chastain <mec@shout.net>
+
+ * gdb.c++/local.exp: Add PR numbers: gdb/482, gdb/483.
+
+2002-04-22 Michael Chastain <mec@shout.net>
+
+ * gdb.c++/method.exp: Fix syntax of reference to gdb/277.
+
+2002-04-17 David S. Miller <davem@redhat.com>
+
+ * gdb.asm/sparc64.inc: New file.
+ * gdb.asm/asm-source.exp: Handle sparc64-*-*.
+
+2002-04-19 Elena Zannoni <ezannoni@redhat.com>
+
+ * gdb.asm/asm-source.exp: Don't use a symlink, just copy the
+ instruction file directly into the build tree. Clean up at end of
+ test.
+
+2002-04-18 David S. Miller <davem@redhat.com>
+
+ * gdb.base/annota1.exp: Expect addresses as $hex + whitespace to
+ handle 64-bit platforms correctly.
+ * gdb.base/maint.exp: Likewise.
+
+2002-04-18 Kevin Buettner <kevinb@redhat.com>
+
+ * gdb.base/shlib-call.exp (additional_flags): AIX doesn't need
+ ``-fpic'' when compiling files comprising a shared library, but
+ it does need additional linker flags in order to find shared
+ libraries at run time.
+
+2002-04-18 Kevin Buettner <kevinb@redhat.com>
+
+ * gdb.base/cvexpr.c (use): New function.
+ (main): Invoke use() on all global variables to prevent
+ some linkers from deleting these otherwise unused symbols.
+
+2002-04-17 Michael Chastain <mec@shout.net>
+From David S. Miller <davem@redhat.com>
+
+ * gdb.c++/ovldbreak.exp: Expect addresses as $hex + whitespace to
+ handle 64-bit platforms correctly.
+
+2002-04-12 Michael Snyder <msnyder@redhat.com>
+From Jim Blandy <jimb@redhat.com>
+ * gdb.base/foo.c (foox): Remove section attribute; the linker
+ script can handle this instead.
+ * gdb.base/bar.c (barx): Same.
+ * gdb.base/baz.c (bazx): Same.
+ * gdb.base/grbx.c (grbxx): Same.
+
+ * gdb.base/overlays.exp: New test: check that GDB's manual overlay
+ manager doesn't automatically unmap overlays unnecessarily.
+
+2002-04-10 Martin M. Hunt <hunt@redhat.com>
+
+ * gdb.base/ending-run.exp: Fix pattern for Mips targets
+ stepping out of main.
+
+2002-04-09 Michael Chastain <mec@shout.net>
+
+ * gdb.c++/local.cc (main): Move call to marker1() inside nested
+ scope so that the nested scope tests will make sense.
+ * gdb.c++/local.exp: Write patterns that actually work with gcc
+ (the HP patterns "were never known to work with gcc").
+ Keep the old aCC patterns too.
+
+2002-04-09 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.base/attach.exp: Correct target board test.
+
+2002-04-08 Michael Chastain <mec@shout.net>
+
+ * gdb.c++/method.exp: Require "const ... A * ..." for "ptype this"
+ in a const method. Add some xfail and fail cases for configurations
+ that do not emit the "const ...".
+
+2002-04-07 Michael Chastain <mec@shout.net>
+
+ * gdb.c++/method.exp: Use gdb_test instead of send_gdb/gdb_expect.
+ Accept "A * const" and "const A * const" as type of "this".
+ Fix spelling of getFunky throughout. Make messages uniform.
+
+2002-04-07 Elena Zannoni <ezannoni@redhat.com>
+
+ Work around for PR gdb/285:
+ * gdb.asm/asm-source.exp: Bail out if multilibs are detected.
+
+2002-04-07 Elena Zannoni <ezannoni@redhat.com>
+
+ * gdb.asm/asm-source.exp: Build symbolic link to arch specific
+ instructions file at run time instead of configure time.
+ Sometimes we run the test in a directory that is not the one we
+ configured in.
+ * gdb.asm/configure.in: Delete creation of symlink.
+ * gdb.asm/configure: Regenerate.
+
+2002-04-05 J. Brobecker <brobecker@gnat.com>
+
+ * gdb.gdb/xfullpath.exp: New test, to exercise the new
+ xfullpath () function.
+
+2002-04-04 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.asm/Makefile.in: Correct dependencies.
+
+ * gdb.asm/powerpc.inc: New file.
+ * gdb.asm/asm-source.exp: Add PowerPC.
+ * gdb.asm/configure.in: Likewise.
+ * gdb.asm/configure: Regenerated.
+
+2002-04-04 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.base/relocate.exp: New file.
+ * gdb.base/relocate.c: New file.
+
+2002-04-04 Fred Fish <fnf@redhat.com>
+
+ * gdb.base/step-test.exp: Update comment regarding stopping in
+ memcpy/bcopy calls inserted as part of the compiler runtime.
+
+2002-04-04 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/ovlymgr.c: Add overlay event breakpoint support.
+
+2002-04-03 Daniel Jacobowitz <drow@mvista.com>
+
+ * lib/gdb.exp (gdb_test): Move -notransfer inside of gdb_expect.
+ (gdb_expect): Remove $notransfer hack.
+
+2002-04-02 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.c++/classes.exp ("calling method for small class"): Match
+ updated register output.
+
+2002-03-30 Daniel Jacobowitz <drow@mvista.com>
+
+ Fix PR gdb/452
+ * gdb.base/dbx.exp: Restore old definition of gdb_file_cmd
+ when finished. Make gdb_file_cmd send "exec-file" when
+ appropriate.
+
+2002-03-30 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.base/attach.exp: Remove extra setup_xfail.
+
+2002-03-26 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/default.exp: Add tests for dump, append, and restore.
+ * gdb.base/help.exp: Add tests for dump, append, and restore.
+ * gdb.base/dump.exp: New file, test dump, append and restore.
+ * gdb.base/dump.c: New file.
+
+2002-03-27 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/help.exp: Modify expect strings to reflect
+ clean-ups in help messages.
+
+2002-03-26 Fred Fish <fnf@redhat.com>
+
+ * gdb.base/step-test.exp: Accept stopping in memcpy/bcopy when we
+ have debugging info for those functions and the compiler uses them
+ internally to copy structs around.
+
+2002-03-26 Fred Fish <fnf@redhat.com>
+
+ * gdb.base/list.exp: Revert the change made yesterday and add note
+ about why we don't list the default lines for remote targets.
+
+2002-03-25 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/help.exp: Clean up unnecessary wild cards in regexps.
+
+2002-03-25 Fred Fish <fnf@redhat.com>
+
+ * gdb.base/list.exp: This test works on remote targets so remove
+ the short circuit for remote targets. Update copyright.
+
+2002-03-25 Fred Fish <fnf@redhat.com>
+
+ * gdb.base/attach.exp: Fix logic error that was suppressing this
+ test for all non hppa*-*-hpux* targets, instead of the hp target.
+ Move comments closer to the suppression point. Also now need to
+ check that we are running natively.
+
+2002-03-22 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/default.exp: Add test for gcore. Update copyright.
+ * gdb.base/help.exp: Add test for gcore. Update copyright.
+
+2002-03-06 Fred Fish <fnf@redhat.com>
+
+ * gdb.base/funcargs.c: Remove extraneous ';' character.
+ * gdb.trace/gdb_c_test.c: Remove extraneous ';' character.
+
+2002-03-04 Michael Chastain <mec@shout.net>
+
+ * gdb.mi/mi-var-cmd.exp: In test "create local variable func",
+ accommodate gcc v3 function signature.
+ * gdb.mi/mi0-var-cmd-exp: Ditto.
+
+2002-02-24 Andrew Cagney <ac131313@redhat.com>
+
+ * testsuite/gdb.base/huge.c: Replace ``Linux'' with either
+ ``GNU/Linux'' or ``Linux kernel''
+ * testsuite/gdb.threads/pthreads.c: Ditto.
+
+2002-02-24 Michael Chastain <mec@shout.net>
+
+ * gdb.threads/pthreads.c (thread1): Add a return statement.
+ (thread2): Likewise.
+ (foo): Likewise.
+
+2002-02-23 Michael Chastain <mec@shout.net>
+
+ * gdb.threads/linux-dp.c (philosopher): Add a return statement
+ to placate gcc.
+
+2002-02-23 Michael Chastain <mec@shout.net>
+
+ * gdb.c++/templates.exp: Remove setup_xfail_format "stabs" on
+ test "ptype bint". The test passes on all my stabs configurations.
+
+2002-02-21 Jim Blandy <jimb@redhat.com>
+
+ * gdb.asm/asm-source.exp: Parse the output from `info sources' one
+ filename at a time, and watch for the ones we want to see.
+
+ * gdb.base/ptype.exp, gdb.base/ptype.c: Add tests for printing
+ types of pointers to prototyped functions.
+
+2002-02-20 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.base/sizeof.c (main): Call fill_structs. Print value of
+ signed, unsigned and straight char.
+ (padding_char, padding_short, padding_int, padding_long,
+ padding_long_long, padding_float, padding_double,
+ padding_long_double): New global variables.
+ (fill, fill_structs): New functions.
+
+ * gdb.base/sizeof.exp: Check for signed and unsigned char. Check
+ for correctly sized writes. Update copyright.
+ (get_valueof): New procedure.
+ (get_sizeof): Call get_valueof.
+ (check_valueof): New procedure.
+ (check_padding): New procedure.
+
+2002-02-20 Michael Chastain <mec@shout.net>
+
+ * gdb.c++/virtfunc.exp (test_virtual_calls): Remove obsolete calls
+ to setup_xfail. Document some of the remaining calls.
+
+2002-02-18 Michael Chastain <mec@shout.net>
+
+ * gdb.c++/userdef.exp: Update copyright year.
+
+2002-02-18 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.c++/userdef.exp: Test overloaded operators properly.
+ Remove xfails.
+
+2002-02-14 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/gcore.exp: Relax recognition of function breakpoint.
+
+2002-02-14 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.base/a2-run.exp: Check for a remote target properly.
+ * gdb.base/annota1.exp: Likewise.
+ * gdb.base/list.exp: Likewise.
+ * gdb.base/reread.exp: Likewise.
+ * gdb.base/scope.exp: Likewise.
+ * gdb.base/shlib-call.exp: Likewise.
+ * gdb.base/term.exp: Likewise.
+ * gdb.c++/annota2.exp: Likewise.
+
+2002-02-13 Richard Earnshaw <rearnsha@arm.com>
+
+ * gdb.base/watchpoint.exp: Restore previous timeout at end of test.
+
+2002-02-10 Michael Chastain <mec@shout.net>
+
+ * gdb.base/funcargs.c (localvars_after_alloca): Fix return type.
+ (call_after_alloca): Ditto.
+
+2002-02-10 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.base/ending-run.exp: Guard "cont" test with
+ gdb_skip_stdio_test.
+
+2002-02-06 Jim Blandy <jimb@redhat.com>
+
+ * gdb.base/callfwmall.c, gdb.base/callfwmall.exp: Move these tests
+ from here...
+ * gdb.hp/gdb.base-hp/callfwmall.c, gdb.hp/gdb.base-hp/callfwmall.exp:
+ To here. Disable this test on non-HP platforms. Add big comment.
+
+2002-02-04 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/ovlymgr.c (ovly_copy): Generalize for targets
+ other than d10v and m32r.
+
+2002-02-02 Richard Earnshaw <rearnsha@arm.com>
+
+ * gdb.base/default.exp: Rewrite test patterns to reduce time
+ taken to match them.
+
+2002-01-30 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.base/annota1.exp (backtrace from shlibrary): Fix spelling.
+ Allow a start function above main.
+ * gdb.threads/linux-dp.exp: Fix copyright date.
+
+2002-01-30 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.threads/linux-dp.exp: Use 'array unset', not 'array set'.
+ (check_philosopher_stack): Check for manager thread before checking
+ for a just-starting thread.
+
+2002-01-30 Daniel Jacobowitz <drow@mvista.com>
+
+ From Neil Booth <neil@daikokuya.demon.co.uk>:
+ * gdb.base/bitfields.c: Correct assignments to bitfields to avoid
+ warnings.
+
+2002-01-21 Fred Fish <fnf@redhat.com>
+
+ * gdb.base/restore.exp (restore_tests): Fix obvious typo, callee
+ not caller.
+
+2002-01-21 Jim Blandy <jimb@redhat.com>
+
+ * gdb.base/reread.exp: Check that GDB properly re-reads the
+ executable file when it changes while no inferior is running.
+
+2002-01-21 Fred Fish <fnf@redhat.com>
+
+ * gdb.base/maint.exp: Simplify the "maint info breakpoints" test to
+ optionally accept the "shlib events" variation.
+
+2002-01-21 Jim Blandy <jimb@redhat.com>
+
+ * gdb.base/ending-run.c (main): Avoid messing with setvbuf; just
+ call `fflush' after every `printf', so that the output is produced
+ at predictable points, regardless of whatever buffering does (or
+ doesn't) take place.
+ * gdb.base/ending-run.exp: Adjust tests to expect output to appear
+ at different points.
+
+2002-01-20 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.c++/inherit.exp: Update copyright years.
+ * gdb.c++/method.exp: Likewise.
+
+2002-01-20 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.c++/classes.exp: Update for improved v3 support and skipping
+ artificial methods/arguments.
+ * gdb.c++/derivation.exp: Likewise.
+ * gdb.c++/inherit.exp: Likewise.
+ * gdb.c++/method.exp: Likewise.
+ * gdb.c++/virtfunc.exp: Likewise.
+
+2002-01-18 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.hp/gdb.threads-hp/usrthfork.exp: Mark as obsolete.
+ * gdb.hp/gdb.threads-hp/usrthcore.exp: Ditto.
+ * gdb.hp/gdb.threads-hp/usrthbasic.exp: Ditto.
+ * gdb.hp/gdb.threads-hp/usrthfork.c: Ditto.
+ * gdb.hp/gdb.threads-hp/usrthbasic.c: Ditto.
+ * gdb.hp/gdb.threads-hp/usrthcore.c: Ditto.
+
+2002-01-17 Jim Blandy <jimb@redhat.com>
+
+ * gdb.asm/asm-source.exp (info symbol): Take another shot at
+ anchoring the pattern matching the entry point symbol's name.
+
+2002-01-17 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.base/maint.exp: Update ``maint internal-error'' to match
+ continue/quit query. Update copyright.
+
+2002-01-14 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/gcore.exp: Remove extra debugging output.
+
+2002-01-13 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.c++/demangle.exp: Accept slightly dubious v2 demangler result
+ for slightly dubious v2 mangled string.
+
+2002-01-13 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.base/completion.exp: Expand ${srcdir} to an absolute path.
+
+2002-01-10 Jason Merrill <jason@redhat.com>
+
+ * gdb.c++/namespace.exp: Accept trailing const for 'this'.
+
+ * gdb.c++/classes.exp: Accept 'A const' or 'const A' in copy
+ constructors.
+ * gdb.c++/derivation.exp: Likewise.
+ * gdb.c++/templates.exp: Likewise.
+ * gdb.c++/virtfunc.exp: Likewise.
+
+2002-01-10 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.c++/namespace.exp: Accept both '\0' and '\000'.
+
+2002-01-08 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/gcore.exp: New test for generate-core-file command.
+ * gdb.base/gcore.c: Testcase for above.
+ * gdb.threads/gcore-thread.exp: New test for gcore (threaded).
+
+2002-01-08 Jason Merrill <jason@redhat.com>
+
+ * gdb.c++/userdef.cc: Use <iostream> instead of <iostream.h>.
+
+2002-01-07 Fred Fish <fnf@redhat.com>
+
+ * gdb.c++/overload.exp: Remove unconditional xfails for:
+ print foo_instance1.overloadargs(1)
+ print foo_instance1.overloadargs(1, 2)
+ print foo_instance1.overloadargs(1, 2, 3)
+ print foo_instance1.overloadargs(1, 2, 3, 4)
+ print foo_instance1.overloadargs(1, 2, 3, 4, 5)
+ print foo_instance1.overloadargs(1, 2, 3, 4, 5, 6)
+ print foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7)
+ print foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7, 8)
+ print foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7, 8, 9)
+ print foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
+ print foo_instance1.overload1arg()
+ print foo_instance1.overload1arg((char)arg2)
+ print foo_instance1.overload1arg((signed char)arg3)
+ print foo_instance1.overload1arg((unsigned char)arg4)
+ print foo_instance1.overload1arg((int)arg7)
+ print foo_instance1.overload1arg((unsigned int)arg8)
+ print foo_instance1.overload1arg((float)arg11)
+ print foo_instance1.overload1arg((double)arg12)
+
+2002-01-07 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/huge.exp: New test. Print a very large target data object.
+ (skip_huge_test): New test variable. Define if you want to skip this
+ test. The test reads an 8 megabyte data object from the target, so it
+ might be very time consuming on remote targets with a slow connection.
+ * gdb.base/huge.c: New file. Test case for above.
+
+2002-01-07 Fred Fish <fnf@redhat.com>
+
+ * gdb.c++/derivation.exp: Remove gcc xfails for g_instance.afoo,
+ g_instance.bfoo, and g_instance.cfoo.
+
+Mon Jan 7 12:22:18 2002 Jeffrey A Law (law@redhat.com)
+
+ * gdb.base/break.c (multi_line_if_conditional): New function.
+ (multi_ilne_while_conditional): Likewise.
+ * gdb.base/break.exp: Verify that a breakpoint on a multi-line
+ IF or WHILE condition puts the breakpoint at the start of
+ the condition.
+
+ * gdb.base/selftest.exp (backtrace through signal handler): Remove
+ hppa*-*-hpux* expected failure.
+ * gdb.base/structs.exp (do_function_calls): Similarly.
+
+ * gdb.c++/annota2.exp (watch triggered on a.x): Handle hardware
+ watchpoints.
+
+2002-01-06 Andrew Cagney <ac131313@redhat.com>
+
+ Fix PR gdb/66.
+ * gdb.base/structs.exp: Replace skip for a29k with skip for
+ gdb,cannot_call_functions.
+ * gdb.base/call-ar-st.exp: Remove references to a29k in comments.
+ * gdb.base/callfuncs.exp: Ditto.
+ * gdb.base/call-rt-st.exp: Ditto.
+ * gdb.base/call-strs.exp: Ditto.
+ * gdb.base/callfwmall.exp: Ditto.
+ * gdb.base/scope.exp: Obsolete xfail a29k.
+ * gdb.c++/misc.exp: Ditto.
+ * gdb.c++/cplusfuncs.exp: Ditto.
+ * gdb.base/ptype.exp: Ditto.
+ * gdb.base/printcmds.exp: Ditto.
+ * gdb.base/opaque.exp: Ditto.
+ * gdb.base/list.exp: Ditto.
+ * gdb.base/funcargs.exp: Ditto.
+ * gdb.base/default.exp: Ditto.
+
+2002-01-04 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/info-proc.exp: New file, test for "info proc" cmd.
+ * gdb.base/maint.exp: Add tests for maint info sections options.
+
+Fri Dec 21 09:42:11 2001 Jeffrey A Law (law@redhat.com)
+
+ * gdb.base/default.exp: Remove bogus hppa*-hp-hpux* xfails.
+
+2001-12-20 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.asm/arm.inc: New file.
+ * gdb.asm/asm-source.exp: Add arm targets.
+ * gdb.asm/configure.in: Ditto.
+ * gdb.asm/configure: Recreated from configure.in.
+
+Thu Dec 20 09:54:36 2001 Jeffrey A Law (law@redhat.com)
+
+ * gdb.hp/gdb.defects/bs15503.exp: Only run this test if compiling
+ with HP's compiler.
+ * gdb.hp/gdb.objdbg/objdbg01.exp: Likewise.
+ * gdb.hp/gdb.objdbg/objdbg02.exp: Likewise.
+ * gdb.hp/gdb.objdbg/objdbg03.exp: Likewise.
+ * gdb.hp/gdb.objdbg/objdbg04.exp: Likewise.
+
+ * gdb.hp/gdb.defects/solib-d.exp: Update to handle building with
+ either HP's compilers or GCC.
+
+ * gdb.hp/gdb.base-hp/hwwatchbus.exp: Allow inferior to get either
+ a SIGBUS or SIGSEGV.
+
+ * gdb.hp/gdb.base-hp/so-thresh.exp: Remove useless send_user command.
+
+ * gdb.hp/gdb.defects/bs14602.exp: Revamp slightly so that test
+ can be compiled with either HP's compiler or GCC.
+
+ * gdb.hp/gdb.threads-hp/usrthbasic.exp: Disable completely.
+ * gdb.hp/gdb.threads-hp/usrthcore.exp: Disable completely.
+ * gdb.hp/gdb.threads-hp/usrthfork.exp: Disable completely.
+
+ * gdb.hp/gdb.base-hp/so-thresh.exp: Update text in expect strings
+ to match current gdb output. Update due to using auto-solib-limit
+ for limiting instead of overloading auto-solib-add.
+ * gdb.hp/gdb.base-hp/so-thresh.mk: Always use "cc" to build the
+ test program.
+
+ * gdb.c++/templates.exp: Use "hppa64-*-*", not "hppa2.0w-*-*"
+ * gdb.hp/gdb.base-hp/dollar.exp: Likewise
+ * gdb.hp/gdb.base-hp/pxdb.exp: Likewise.
+ * gdb.hp/gdb.base-hp/reg-pa64.exp: Likewise.
+ * gdb.hp/gdb.base-hp/reg.exp: Likewise.
+ * gdb.hp/gdb.compat/xdb3.exp: Likewise.
+ * gdb.hp/gdb.defects/bs15503.exp: Likewise.
+ * gdb.hp/gdb.objdbg/objdbg01.exp: Likewise
+ * gdb.hp/gdb.objdbg/objdbg02.exp: Likewise
+ * gdb.hp/gdb.objdbg/objdbg03.exp: Likewise
+ * gdb.hp/gdb.threads-hp/usrthbasic.exp: Likewise.
+ * gdb.hp/gdb.threads-hp/usrthcore.exp: Likewise.
+ * gdb.hp/gdb.threads-hp/usrthfork.exp: Likewise.
+
+ * gdb.base/annota1.exp: Expect failure for hpux11 when posting
+ a SIGTRAP to the inferior.
+
+2001-12-19 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.asm/asm-source.exp: Drop setting link-flags for xstormy16.
+ Substitute call to target_link by call to gdb_compile.
+
+Wed Dec 19 14:10:57 2001 Jeffrey A Law (law@redhat.com)
+
+ * gdb.base/break.exp: Fix HP specific search string when testing
+ backtracing in a called function.
+
+ * gdb.base/constvars.exp: Only set lang to C++ if we're
+ compiling the test with HP's compilers.
+ * gdb.base/volatile.exp: Similarly.
+
+2001-12-19 Jim Blandy <jimb@redhat.com>
+
+ * gdb.base/printcmds.exp: Expect the null character to be printed
+ as '\0', and the '\013' to be printed as '\v'.
+ * gdb.base/callfuncs.exp ("backtrace at nested call level 4"): Same.
+ * gdb.base/setvar.exp: Same.
+
+2001-12-17 Jim Blandy <jimb@redhat.com>
+
+ * gdb.base/completion.exp: Rather than completing very long
+ filenames, which can make the readline library produce output we
+ don't recognize, cd to the directory first, and then complete
+ using nice, short relative paths.
+
+ * gdb.base/completion.exp: On some systems, there is, in fact, a
+ variable named `b' in scope, since GDB treats all static
+ variables as being in scope. So use `no_var_named_this'
+ instead of `b'.
+
+ * gdb.base/corefile.exp: Recognize the message saying that GDB
+ can't find the core file's registers as a failure.
+
+2001-12-13 Jackie Smith Cashion <jsmith@redhat.com>
+
+ * gdb.base/commands.exp (user_defined_command_test): Make "show user"
+ test expect string more specific.
+
+2001-12-13 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.asm/asm-source.exp: Add support for xstormy16.
+ * gdb.asm/configure.in: Ditto.
+ * gdb.asm/configure: Rebuild.
+ * gdb.asm/xstormy16.inc: New file.
+
+2001-12-10 Fred Fish <fnf@redhat.com>
+
+ * gdb.base/maint.exp: Update to match changes in type dumping code.
+
+2001-12-10 Jim Blandy <jimb@redhat.com>
+
+ * gdb.asm/asm-source.exp (info symbol): Anchor the pattern
+ matching the entry point symbol's name at the beginning of the
+ line.
+
+2001-12-07 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.c++/classes.exp, gdb.c++/derivation.exp,
+ gdb.c++/inherit.exp, gdb.c++/method.exp,
+ gdb.c++/namespace.exp, gdb.c++/templates.exp,
+ gdb.c++/userdef.exp, gdb.c++/virtfunc.exp: Updates for v3 demangler
+ and class layout support.
+
+2001-12-07 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.c++/classes.exp: Add test for static member function.
+ * gdb.c++/misc.cc: Add class with static member function.
+
+2001-12-07 Jim Blandy <jimb@redhat.com>
+
+ If GDB says it can't find the struct the function returned, report
+ those tests as `unsupported'.
+ * gdb.base/call-rt-st.exp (print_struct_call): New function.
+ Rewrite subsequent tests to use it.
+
+ If GDB says it can't find the struct the function returned, report
+ those tests as `unsupported'.
+ * gdb.base/structs.exp (call_struct_func): New function.
+ (do_function_calls): Use call_struct_func to call the functions
+ returning structs.
+
+ * gdb.base/callfuncs.exp: The stabs generated by GCC don't tell us
+ whether functions are prototyped or not, so we can't possibly pass
+ arguments to t_float_values2 properly.
+
+ * gdb.base/break.exp: (test_next_with_recursion): Don't change the
+ value of `timeout' for targets other than the mips*tx39-*.
+
+2001-12-06 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.asm/asm-source.exp: Add tests for info target, info symbol,
+ and detect whether the start symbol has a leading underscore.
+
+2001-12-04 Jim Blandy <jimb@redhat.com>
+
+ * gdb.base/completion.exp: Clarify indentation.
+
+2001-12-03 Jim Blandy <jimb@redhat.com>
+
+ * gdb.asm/s390.inc (gdbasm_datavar): Use `.long' to create `int'
+ variables on the S/390, not `.word'.
+
+2001-11-30 Jim Blandy <jimb@redhat.com>
+
+ Add assembly-source tests for s390-ibm-linux.
+ * gdb.asm/s390.inc: New file.
+ * gdb.asm/configure.in, gdb.asm/asm-source.exp: Add clauses for
+ the S/390 architecture.
+ * gdb.asm/configure: Regenerated.
+
+2001-11-30 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.asm/asm-source.exp: Add tests for list, search, finish, return,
+ next, info source, info sources, info line, global and static
+ variables, and static functions.
+ * gdb.asm/common.inc: New macro gdbasm_datavar (default definition).
+ * gdb.asm/i386.inc: Override default definition of gdbasm_datavar.
+ * gdb.asm/asmsrc1.s: Add a static function and some variables.
+ * gdb.asm/asmsrc2.s: Make foo2 call foo3 twice (to test 'next').
+ * gdb.asm/d10v.inc (gdbasm_enter): Set up frame pointer.
+ (gdbasm_leave): Restore frame pointer.
+ (gdbasm_startup): Copy stack set-up from crt0.S.
+
+2001-11-26 Fernando Nasser <fnasser@redhat.com>
+
+ From 2001-11-12 Jackie Smith Cashion <jsmith@redhat.com>:
+ * gdb.base/callfuncs.c (t_structs_a): Do not return a pointer
+ to a local (non-static) variable. Copy tstruct.a to a static buffer
+ and return a pointer to that buffer.
+ * gdb.base/callfwmall.c (t_structs_a): Ditto.
+
+2001-11-24 Mark Kettenis <kettenis@gnu.org>
+
+ * gdb.asm/configure.in: Fix recognition of ix86 target.
+ * gdb.asm/configure: Regenerate.
+
+2001-11-21 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.asm/sparc.inc: New file.
+ * gdb.asm/asm-source.exp: Recognize sparc target.
+ * gdb.asm/configure.in: Recognize sparc target.
+ * gdb.asm/configure: Regenerate.
+
+2001-11-21 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.asm/m32r.inc: New file.
+ * gdb.asm/asm-source.exp: Recognize m32r target.
+ * gdb.asm/configure.in: Recognize m32r target.
+ * gdb.asm/configure: Regenerate.
+
+2001-11-20 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.asm/i386.inc: New file.
+ * gdb.asm/asm-source.exp: Recognize ix86 target.
+ * gdb.asm/configure.in: Recognize ix86 target.
+ * gdb.asm/configure: Regenerate.
+
+ * gdb.c++/namespace.exp: Fix quotes in output messages.
+
+2001-11-14 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/code-expr.exp: New file. Tests use of the "@code"
+ qualifier in a type cast expression, to designate an address
+ in the instruction space (Harvard architecture).
+
+2001-11-13 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/cvexpr.c, gdb.base/cvexpr.exp: New files.
+ Tests for expressions using 'const' and 'volatile'.
+
+2001-11-13 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.asm/asm-sources.exp: Allow defining linker flags.
+
+2001-11-12 Daniel Jacobowitz <drow@mvista.com>
+
+ * lib/mi-support.exp (mi_run_to_helper): Move comments
+ outside of gdb_expect.
+
+2001-11-11 Daniel Jacobowitz <drow@mvista.com>
+
+ * lib/mi-support.exp: (mi_run_to_helper, mi_run_to,
+ mi_step_to, mi_next_to, mi_continue_to, mi_finish_to,
+ mi0_step_to, mi0_next_to, mi0_continue_to, mi0_finish_to,
+ mi0_run_to): New functions.
+ * gdb.mi/mi-simplerun.exp: Use them.
+ * gdb.mi/mi0-simplerun.exp: Likewise.
+ * gdb.mi/mi-var-cmd.exp: Likewise.
+ * gdb.mi/mi0-var-cmd.exp: Likewise.
+
+2001-11-10 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.asm/asmsrc1.s: Add ``gdbasm_'' prefix to all macros.
+ * gdb.asm/asmsrc2.s, gdb.asm/d10v.inc: Update.
+
+2001-11-09 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.base/restore.exp: Include $expected value in restored test
+ message.
+
+2001-11-09 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.asm/asm-source.exp: Supress file, instead of skip, when not
+ implemented.
+
+2001-11-08 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/callfuncs.exp: Add tests for nested call dummies.
+ Add pass/fail message for stop at breakpoint in call dummy function.
+
+2001-11-07 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.c++/templates.exp (test_template_breakpoints):
+ If we get an overload menu, but it does not match what
+ we expect, we still need to issue the "cancel" command.
+ * gdb.c++/templates.exp: Replace "void \\*" with "void ?\\*",
+ making the whitespace optional. Argument for "new" may be
+ "unsigned" as well as "unsigned int/long".
+ * gdb.c++/templates.exp: Replace "const &" with "const ?&",
+ making the whitespace optional. Also replace "(void) with
+ "((void|)), making the keyword "void" optional.
+ * gdb.c++/virtfunc.exp: Replace "const &" with "const ?&",
+ making the whitespace optional. Also replace "(void) with
+ "((void|)), making the keyword "void" optional.
+ * gdb.base/callfuncs.c (t_float_values): This function must
+ _not_ be prototyped, and the following function (t_float_values2)
+ must be prototyped (if the compiler supports it), so that GDB
+ can be tested against both cases. Usually one case involves
+ promotion of float to double, while the other does not.
+ * gdb.base/callfwmall.c: Ditto.
+ * gdb.asm/asm-source.exp (bt ALL in foo2): Accept a backtrace that
+ includes a stack frame for "start".
+
+2001-11-05 Jim Blandy <jimb@redhat.com>
+
+ * gdb.stabs/weird.exp: Delete "p v_comb" test. It assumes that
+ pointers are 32 bits long, and that offsets of relocs are always
+ stored in the data (REL-style), and not in the reloc entry itself
+ (RELA-style).
+ * gdb.stabs/weird.def (v_comb, v_comb_shared): Remove symbols and
+ stabs.
+
+2001-11-01 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.c++/cplusfuncs.exp: Fix conflicts between operator names
+ and regular expression operators by using quoting.
+
+2001-10-31 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.c++/overload.exp: Select overloadfnarg(void) or overloadfnarg(),
+ depending on what the symbol table contains.
+ * gdb.c++/derivation.exp: Accept both "foo(void)" and "foo()" in
+ the output of the ptype command. Similarly, accept both "const &"
+ and "const&".
+
+2001-10-31 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.base/miscexprs.c (main): Add usage of preprocessor
+ symbol `STORAGE' to allow to choose the storage class of
+ the local datastructures.
+ * gdb.base/miscexprs.exp: Handle setting a `-DSTORAGE=...'
+ compiler directive.
+
+2001-10-30 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/jump.exp: Allow it to run for all targets.
+
+2001-10-29 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.base/call-ar-st.c (print_double_array): Match for loop
+ with new double_array size.
+ (main): Change storage class of all local variables to static.
+ Reduce size of double_array to 9.
+ * gdb.base/call-ar-st.exp: Increase timeout value.
+ Change expected output for double array to match new size in
+ call-ar-st.c.
+
+2001-10-29 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.base/ending-run.exp: Create identical output when passing
+ `step to end of run' case. Add regular expression branch satisfying
+ Stormy16 target.
+
+2001-10-28 Mark Kettenis <kettenis@gnu.org>
+
+ * gdb.base/interrupt.exp: Treat SIGILL similar to SIGSEGV such
+ that we catch the expected failure under Linux/x86.
+
+2001-10-29 Orjan Friberg <orjanf@axis.com>
+
+ * gdb.base/setvar.exp: Escape curly braces.
+ * gdb.stabs/weird.exp: Ditto.
+
+2001-10-27 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.mi/mi-hack-cli.exp: Remove excess newlines from test strings.
+ * gdm.mi/mi0-hack-cli.exp: Likewise.
+
+2001-10-25 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.stabs/weird.exp: Unify ``variable VAR printed properly''
+ messages.
+
+2001-10-21 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/mi-support.exp (mi_gdb_start): Don't require MI_OUT when
+ checking MI enabled.
+
+2001-10-09 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.base/maint.exp: Treat $EXEEXT as optional in output.
+
+2001-10-04 Frank Ch. Eigler <fche@redhat.com>
+
+ * lib/insight-support.exp (gdbtk_start): Don't exit dejagnu
+ if gdb child process crashes, just signal an error.
+
+2001-10-02 Jim Blandy <jimb@redhat.com>
+
+ * lib/gdb.exp (test_xfail_format): Simplify.
+
+ * lib/gdb.exp (setup_xfail_format): Don't forget to put a `$' in
+ front of the variable name `format'. Simplify `if'.
+
+2001-10-01 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.threads/pthreads.exp: Wait for output and delay
+ before sending ^C.
+
+2001-10-01 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.mi/mi-var-display.exp (continue to incr_a): Recognize
+ some incorrect output instead of timing out.
+ * gdb.mi/mi-var-display.exp (continue to incr_a): Likewise.
+
+2001-09-28 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.base/volatile.exp (local_compiler_xfail_check): Change qux2
+ check to allow additional `int'.
+
+2001-09-27 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdb.base/completion.exp: Remove incorrect 'p "a' test.
+ Add tests for 'p "break' (pass) and 'p "break.' (xfail).
+
+2001-09-27 Michael Snyder <msnyder@redhat.com>
+
+ * lib/gdb.exp (test_debug_format): New proc.
+ (setup_xfail_format): Use new proc test_debug_format.
+ * gdb.base/constvars.exp (local_compiler_xfail_check): New
+ proc; use new service proc test_debug_format.
+ Replace all other "gcc_compiled" tests with this test.
+ * gdb.base/volatile.exp (local_compiler_xfail_check): New
+ proc; use new service proc test_debug_format.
+ Replace all other "gcc_compiled" tests with this test.
+
+2001-09-27 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/cvexpr.exp: New file.
+ * gdb.base/cvexpr.c: New file
+ Test for expressions using const and volatile keywords.
+
+2001-09-26 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.base/constvars.exp: Check for different orders of keywords
+ and additional "int" strings in output.
+
+2001-09-22 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.base/maint.exp: Add "maintenance set/show" to list of valid
+ responses from "help maint".
+
+2001-09-19 Frank Ch. Eigler <fche@redhat.com>
+
+ * lib/insight-support.exp (_gdbtk_xvfb_init): Set DISPLAY
+ to localhost:NNN instead of :NNN, in case Xvfb is listening
+ only on TCP.
+
+2001-09-19 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.base/recurse.exp: When checking leaving the watchpoint
+ scope, recognize when gdb is in function's epilogue and pass.
+
+2001-09-18 Keith Seitz <keiths@redhat.com>
+
+ * lib/insight-support.exp (_gdbtk_export_target_info): Add
+ support for running tests against sid targets.
+ (gdbtk_done): Ditto.
+
+2001-09-18 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.base/ending-run.c (main): Set stdout buffersize
+ to the same reasonable value for any target.
+ * gdb.base/ending-run.exp: Add a regular expression
+ to make testsuite happy on Sanyo Stormy16 target.
+
+2001-09-17 Corinna Vinschen <vinschen@redhat.com>
+
+ * gdb.base/display.c (do_loops): Add float variable `f'.
+ Increment f in loop.
+ * gdb.base/display.exp: Increment timeout by 60 seconds.
+ Change float display test to use variable `f'.
+
+2001-09-17 Jim Blandy <jimb@redhat.com>
+
+ * gdb.base/restore.exp: Use temporary breakpoints, to avoid
+ overflowing the limited breakpoint tables on some ROM monitors
+ (like the ROM68K).
+
+2001-09-15 Frank Ch. Eigler <fche@redhat.com>
+
+ * lib/insight-support.exp (_gdbtk_xvfb_init): Start Xvfb with
+ the "-ac" (disable access control) flag.
+
+2001-08-30 Jeff Holcomb <jeffh@redhat.com>
+
+ * gdb.base/remote.c: Use a small buffer for targets with 16-bit
+ ints.
+
+2001-08-30 Keith Seitz <keiths@redhat.com>
+
+ * lib/gdb.exp: Move all insight-related functionality into
+ separate file.
+ * lib/insight-support.exp: New file.
+
+2001-08-29 Frank Ch. Eigler <fche@redhat.com>
+
+ * config/sid.exp (sid_start): Never set sid verbosity; disable
+ expect_background {} that consumed its stdout; tolerate </dev/null.
+ Attempt to set endianness override in "sid" protocol mode. Cleanup.
+
+2001-08-18 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/mi-support.exp (mi_gdb_start): If a remote target, use the
+ CLI jump command to start it.
+ (mi_run_to_main): Fail immediatly when unexpected output.
+
+2001-08-18 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/mi-support.exp (mi_gdb_start): Move call to sid_start to
+ beginning of function. Fix PR gdb/191.
+
+2001-08-16 Frank Ch. Eigler <fche@redhat.com>
+
+ * config/sid.exp (sid_start): Don't warn if we cannot figure out
+ what to force sid endianness to.
+
+2001-08-15 Keith Seitz <keiths@redhat.com>
+
+ * lib/gdb.exp (gdbtk_start): Don't set environment
+ variables for TCL_LIBRARY and friends. Insight will
+ now figure these out for itself.
+
+2001-08-02 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/completion.exp: Remove the symbol "a64l" from
+ the expect string; this is target-specific, and not related
+ to what is being tested.
+
+2001-08-02 Dave Brolley <brolley@redhat.com>
+
+ * config/sid.exp: Rename gdb-socket to cpu-gdb-socket.
+
+2001-07-25 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/consecutive.exp: New file. Test stepping over
+ breakpoints on consecutive instructions.
+ * gdb.base/consecutive.c: New file.
+
+ * gdb.base/call-rt-st.exp: Use double-backslash to quote
+ curly braces in regular expressions.
+
+2001-07-25 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/ending-run.exp: Accept "Program exited normally" as
+ legitimate output from stepping out of main.
+
+2001-07-22 Keith Seitz <keiths@redhat.com>
+
+ * lib/gdb.exp (_gdbtk_xvfb_init): If GDB_DISPLAY is
+ the empty string, do not run the tests.
+
+2001-07-17 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * gdb.base/long_long.exp: Detect size of pointer. Take into
+ account 2-byte pointers when testing for p/a results.
+
+2001-07-17 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * gdb.base/remote.c (RANDOM_DATA_SIZE): New define, defaults to 48K
+ and defined to 1K for m68hc11.
+ (random_data): Reduce table to 1K for embedded platforms (68hc11).
+ * gdb.base/remote.exp (get_sizeof): New function from sizeof.exp.
+ (sizeof_random_data): New variable to tell the size of the data table;
+ don't test past this size; always run to main.
+
+2001-07-16 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * gdb.base/return2.exp: return of long long and double fails for
+ 68HC11; don't execute these tests on that platform.
+ * gdb.base/return.exp: Return of a double fails for 68hc11.
+
+2001-07-16 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * call-ar-st.exp: Use gdb_skip_float_test to avoid executing
+ tests that print a float.
+ * call-rt-st.exp: Likewise.
+
+2001-07-12 Mark Kettenis <kettenis@gnu.org>
+
+ * gdb.base/so-impl-ld.exp: Remove stray space that prevented
+ running this test on Linux.
+
+2001-06-24 Michael Chastain <chastain@redhat.com>
+
+ * gdb.base/arithmet.exp: Remove some tests to make all test names
+ unique.
+
+2001-07-03 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.c++/classes.exp: Accept both "foo(void)" and "foo()" in
+ the output of the ptype command.
+
+2001-07-02 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/completion.exp: Don't assume that break.c is the only
+ source file that may contain functions named "marker".
+ * gdb.base/corefile.exp: Quote the curly braces in regexp.
+
+2001-06-28 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.disasm/Makefile.in (clean mostlyclean): Add h8300s to list
+ of files to delete.
+
+ From 2000-06-15 Kazu Hirata <kazu@hxi.com>:
+ * gdb.disasm/h8300s.exp: New file.
+ gdb.disasm/h8300s.s: Likewise.
+
+2001-06-27 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/mi-support.exp (mi_delete_breakpoints): Accept mi1 format
+ empty breakpoint tables.
+
+2001-06-25 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/mi-support.exp: Update args=... part of stop-reason
+ patterns. Accept either a list or a tuple.
+
+2001-06-23 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/mi-support.exp: Remove local emacs variable defining
+ change-log-default-name.
+
+2001-06-22 Michael Chastain <chastain@redhat.com>
+
+ * gdb.base/arithmet.exp: Use gdb_test instead of send_gdb/gdb_expect.
+ This is operationally compatible with the previous version.
+
+2001-06-13 Jim Blandy <jimb@redhat.com>
+
+ * lib/gdb.exp (gdb_test): Doc fix.
+
+2001-06-10 Michael Chastain <chastain@redhat.com>
+
+ * gdb.base/exprs.exp: Remove a duplicate test.
+
+2001-06-06 Jim Blandy <jimb@redhat.com>
+
+ * gdb.base/return2.exp (main): Use values to test float and double
+ returns that are not NaN's, to avoid being confused by IEEE
+ comparison rules.
+
+2001-06-04 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.threads/pthreads.exp (check_control_c): Return 0 for success,
+ non-zero if control_c fails. Terminate the test on failure,
+ rather than wait for 12 more tests to time out.
+
+2001-06-06 Jim Blandy <jimb@redhat.com>
+
+ * gdb.base/exprs.exp ("sizeof (long long) > sizeof (long) (true)"):
+ Don't forget to match the GDB prompt.
+
+ * gdb.trace/gdb_c_test.c, actions.c: Fix misspellings.
+
+2001-06-04 Jim Blandy <jimb@redhat.com>
+
+ * gdb.base/help.exp: Update pattern to exclude `print-load-map'
+ command.
+
+2001-05-31 Kevin Buettner <kevinb@redhat.com>
+
+ * gdb.base/annota1.exp (info break): Match four or more spaces
+ after "Address".
+
+2001-05-31 Michael Chastain <chastain@redhat.com>
+
+ * gdb.c++/cplusfuncs.cc (dm_type_char_star): Remove superfluous cast.
+ (dm_type_int_star): Likewise.
+ (dm_type_long_star): Likewise.
+ (dm_type_void_star): Likewise.
+
+2001-05-29 Kevin Buettner <kevinb@redhat.com>
+
+ * gdb.base/completion.exp (INPUTRC): Set this environment variable
+ to a known value in order to get consistent results regardless
+ of the setting of INPUTRC or the presence or contents of .inputrc.
+
+2001-05-24 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.threads/linux-dp.exp: Remove assumptions about thread ordering.
+ Don't require that the main thread and the manager thread are the
+ first in the list.
+
+ * gdb.threads/pthreads.exp (test_startup): Relax test for thread
+ debugging. If test fails, issue an "unsupported" not a "fail".
+
+2001-05-24 Jim Blandy <jimb@redhat.com>
+
+ Don't assume that short is shorter than int.
+ * gdb.base/exprs.exp ("print unsigned short == (~0)"): Don't
+ assume that shorts are smaller than ints. On a 16-bit machine,
+ this isn't true.
+ ("print unsigned char == (~0)"): Add test that verifies that ~0,
+ an int, is not equal to ~0 stored in an unsigned char. This tests
+ the same thing that the previous test meant to, but works on
+ 16-bit machines, too.
+ ("print unsigned char != (~0)"): Same test, complemented.
+
+2001-05-24 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.threads/pthreads.exp (all_threads_running): Add an explicit
+ test for (full_coverage == 0). This makes the test run faster,
+ and prevents dejagnu getting out of step.
+
+2001-05-23 Kevin Buettner <kevinb@redhat.com>
+
+ * gdb.base/finish.exp (finish_void): Revise pattern for
+ stopping on the call statement to not permit stopping at
+ the start of the instructions comprising the call sequence.
+
+2001-05-19 Michael Chastain <chastain@redhat.com>
+
+ * gdb.base/callfuncs.exp: Make all test names unique.
+ * gdb.base/commands.exp: Make all test names unique.
+ * gdb.base/condbreak.exp: Make all test names unique.
+ * gdb.base/dbx.exp: Make all test names unique.
+ * gdb.base/default.exp: Make all test names unique.
+ * gdb.base/define.exp: Make all test names unique. Conform some FAIL
+ and TIMEOUT messages to their corresponding PASS message.
+ * gdb.base/ending-run.exp: Make all test names unique.
+ * gdb.base/long_long.exp: Remove duplicate test.
+
+2001-05-21 Kevin Buettner <kevinb@redhat.com>
+
+ * gdb.base/finish.exp (finish_void): Allow "finish" command to
+ stop on the call statement as well as the statement after the
+ call.
+
+2001-05-21 Michael Snyder <msnyder@redhat.com>
+
+ * gdb.base/long_long.exp: Allow for targets with 4-byte short.
+
+2001-05-10 Elena Zannoni <ezannoni@redhat.com>
+
+ * gdb.base/completion.exp: Revamp test. Make it execute on all
+ platforms.
+
+2001-05-10 Elena Zannoni <ezannoni@redhat.com>
+
+ * config/gdbserver.exp (gdb_load): Handle the case
+ in which the arguments to gdbserver are given in the
+ baseboard configuration file.
+ Also handle the case in which the server needs to do a
+ load.
+
+2001-05-07 Keith Seitz <keiths@cygnus.com>
+
+ * lib/gdb.exp (gdbtk_initialize_display): New proc which will
+ set up the display for testing.
+ (gdbtk_start): Convert all paths to paths that tcl will like.
+ Export target information to environment.
+ (_gdbtk_xvfb_init): New proc to start Xvfb if available and
+ necessary.
+ (_gdbtk_xvfb_exit): New proc to kill Xvfb if necessary.
+ (to_tcl_path): New proc to convert a given pathname into
+ a path acceptible as an argument to a tcl command.
+ (_gdbtk_export_target_info): New proc to export target info
+ into the environment for gdbtk testing.
+ (gdbtk_done): New proc to signal end-of-test.
+
+2001-05-06 Jim Blandy <jimb@redhat.com>
+
+ * restore.c: Make the code of caller0 correspond to its comment.
+
+2001-05-03 Michael Snyder <msnyder@redhat.com>
+
+ * config/sid.exp (gdb_target_sid): Check for error messages.
+ On error or timeout, don't make expect exit (which will terminate
+ all subsequent tests); instead just make gdb exit.
+ (gdb_load): Check for error messages. On error or timeout,
+ return a negative value.
+
+2001-04-24 Jim Blandy <jimb@redhat.com>
+
+ * gdb.c++/templates.exp: If we see the prompt for the overload
+ list, but we haven't recognized any of the longer patterns,
+ arrange for this test to fail, not hang.
+
+ * gdb.c++/classes.exp (ptype class A): Tolerate whitespace
+ variations.
+
+2001-04-22 Michael Chastain <chastain@redhat.com>
+
+ * gdb.c++/local.exp: Use the 'runto' library function.
+ * gdb.c++/namespace.exp: Likewise.
+ * gdb.c++/overload.exp: Likewise.
+
+2001-03-26 Kevin Buettner <kevinb@redhat.com>
+
+ * gdb.base/Makefile.in (EXECUTABLES): Add step-line.
+ * gdb.base/step-line.exp: New file. Test step/next in presence of
+ #line directives.
+ * gdb.base/step-line.c: New file. Test program for the above.
+ * gdb.base/step-line.inp: New file. We pretend that this file has
+ been transformed by some other tool into step-line.c.
+
+2001-03-21 Jim Blandy <jimb@redhat.com>
+
+ * gdb.c++/userdef.exp: Check that GDB tolerates whitespace in
+ unmangled operator names.
+
+2001-03-20 Jim Blandy <jimb@redhat.com>
+
+ * gdb.threads/linux-dp.exp: Recognize an additional message
+ generated by GDB when it doesn't understand how to debug threads
+ on the target system.
+
+2001-03-19 Andrew Cagney <ac131313@redhat.com>
+
+ * gdb.mi/mi-console.exp: Document ``Hello'' as a known bug.
+
+2001-03-12 Michael Chastain <chastain@redhat.com>
+
+ * gdb.c++/derivation.exp: Use the 'runto' library function.
+
+2001-03-12 Michael Chastain <chastain@redhat.com>
+
+ * gdb.c++/annota2.exp: Fix regular expression for "post-query".
+
+2001-02-24 Michael Chastain <chastain@redhat.com>
+
+ * gdb.c++/ref-types.exp: Change handwritten code to library
+ function 'runto'.
+
+2001-03-16 Orjan Friberg <orjanf@axis.com>
+
+ * gdb.base/signals.exp: Set count to 0 explicitly.
+
+2001-03-15 Mark Salter <msalter@redhat.com>
+
+ * config/monitor.exp (gdb_target_cmd): Add explicit error return.
+ (gdb_target_monitor): Add check of gdb_target_cmd return value.
+ (gdb_load): Add support for additional target_info: gdb_download_size
+ and gdb_load_timeout.
+
+Thu Mar 8 16:06:00 2001 David Taylor <taylor@redhat.com>
+
+ * gdb.base/annota1.exp: Move test of isnative to earlier in the
+ file -- to prevent failing when the compile fails but we have no
+ intention of running the tests anyway.
+
+ * gdb.base/long_long.exp: Test target_info for no_long_long, skip
+ tests if set.
+
+ * gdb.base/maint.exp: Support 2 byte integers as well as 4 byte
+ integers.
+
+ * gdb.c++/ctti.exp: Skip tests if skip_cplus_tests returns true.
+ * gdb.c++/namespace.exp: Ditto.
+
+2001-03-07 Orjan Friberg <orjanf@axis.com>
+
+ * gdb.base/pointers.c: Don't assume doubles are >= 8 bytes.
+ * gdb.base/pointers.exp: Relax pattern match of decimals.
+
+2001-03-06 Kevin Buettner <kevinb@redhat.com>
+
+ * Makefile.in, config/abug.exp, config/cfdbug.exp,
+ config/cpu32bug.exp, config/dve.exp, config/est.exp,
+ config/gdbserver.exp, config/hmsirom.exp, config/hppro.exp,
+ config/i960.exp, config/m32r.exp, config/mn10300-eval.exp,
+ config/monitor.exp, config/proelf.exp, config/rom68k.exp,
+ config/sh.exp, config/sid.exp, config/slite.exp,
+ config/sparclet.exp, config/udi.exp, config/unknown.exp,
+ config/vr4300.exp, config/vr5000.exp, config/vx.exp,
+ config/vxworks.exp, config/vxworks29k.exp,
+ gdb.asm/asm-source.exp, gdb.base/a2-run.exp,
+ gdb.base/all-bin.exp, gdb.base/annota1.exp,
+ gdb.base/arithmet.exp, gdb.base/assign.exp,
+ gdb.base/async.exp, gdb.base/attach.exp,
+ gdb.base/bitfields.exp, gdb.base/bitops.exp,
+ gdb.base/break.exp, gdb.base/call-ar-st.exp,
+ gdb.base/call-rt-st.exp, gdb.base/call-strs.exp,
+ gdb.base/callfuncs.exp, gdb.base/callfwmall.exp,
+ gdb.base/commands.exp, gdb.base/completion.exp,
+ gdb.base/cond-expr.exp, gdb.base/condbreak.exp,
+ gdb.base/constvars.exp, gdb.base/corefile.exp,
+ gdb.base/dbx.exp, gdb.base/default.exp, gdb.base/define.exp,
+ gdb.base/display.exp, gdb.base/ena-dis-br.exp,
+ gdb.base/ending-run.exp, gdb.base/environ.exp,
+ gdb.base/eval-skip.exp, gdb.base/exprs.exp,
+ gdb.base/finish.exp, gdb.base/foll-exec.exp,
+ gdb.base/foll-fork.exp, gdb.base/foll-vfork.exp,
+ gdb.base/funcargs.exp, gdb.base/help.exp,
+ gdb.base/interrupt.exp, gdb.base/jump.exp, gdb.base/list.exp,
+ gdb.base/logical.exp, gdb.base/long_long.exp,
+ gdb.base/maint.exp, gdb.base/mips_pro.exp,
+ gdb.base/miscexprs.exp, gdb.base/nodebug.exp,
+ gdb.base/opaque.exp, gdb.base/overlays.exp, gdb.base/page.exp,
+ gdb.base/pointers.exp, gdb.base/printcmds.exp,
+ gdb.base/ptype.exp, gdb.base/radix.exp, gdb.base/recurse.exp,
+ gdb.base/regs.exp, gdb.base/relational.exp,
+ gdb.base/remote.exp, gdb.base/reread.exp,
+ gdb.base/restore.exp, gdb.base/return2.exp,
+ gdb.base/scope.exp, gdb.base/sect-cmd.exp,
+ gdb.base/selftest.exp, gdb.base/setshow.exp,
+ gdb.base/setvar.exp, gdb.base/shlib-call.exp,
+ gdb.base/sigall.exp, gdb.base/signals.exp,
+ gdb.base/sizeof.exp, gdb.base/so-impl-ld.exp,
+ gdb.base/so-indr-cl.exp, gdb.base/solib.exp,
+ gdb.base/step-test.exp, gdb.base/structs.c,
+ gdb.base/structs.exp, gdb.base/structs2.exp,
+ gdb.base/term.exp, gdb.base/twice.exp, gdb.base/varargs.exp,
+ gdb.base/volatile.exp, gdb.base/watchpoint.exp,
+ gdb.base/whatis-exp.exp, gdb.base/whatis.exp,
+ gdb.c++/ambiguous.exp, gdb.c++/annota2.exp,
+ gdb.c++/anon-union.exp, gdb.c++/classes.exp, gdb.c++/ctti.exp,
+ gdb.c++/derivation.exp, gdb.c++/inherit.exp,
+ gdb.c++/local.exp, gdb.c++/member-ptr.exp, gdb.c++/method.exp,
+ gdb.c++/misc.exp, gdb.c++/namespace.exp, gdb.c++/overload.exp,
+ gdb.c++/ref-types.exp, gdb.c++/templates.exp,
+ gdb.c++/userdef.exp, gdb.c++/virtfunc.exp,
+ gdb.disasm/am33.exp, gdb.disasm/hppa.exp,
+ gdb.disasm/mn10200.exp, gdb.disasm/mn10300.exp,
+ gdb.fortran/types.exp, gdb.java/jmisc.exp,
+ gdb.java/jv-exp.exp, gdb.java/jv-print.exp,
+ gdb.stabs/weird.exp, gdb.threads/linux-dp.exp,
+ gdb.trace/actions.exp, gdb.trace/backtrace.exp,
+ gdb.trace/circ.exp, gdb.trace/collection.exp,
+ gdb.trace/deltrace.exp, gdb.trace/infotrace.exp,
+ gdb.trace/limits.exp, gdb.trace/packetlen.exp,
+ gdb.trace/passc-dyn.exp, gdb.trace/passcount.exp,
+ gdb.trace/report.exp, gdb.trace/save-trace.exp,
+ gdb.trace/tfind.exp, gdb.trace/tracecmd.exp,
+ gdb.trace/while-dyn.exp, gdb.trace/while-stepping.exp,
+ lib/gdb.exp, lib/mi-support.exp: Update/correct copyright
+ notices.
+
+2001-02-27 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/varargs.c (find_max_double): Fix printf format string:
+ first arg is int not float.
+
+2001-02-22 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/reread.exp: Unsupported for non-native targets;
+ doesn't work for remote debugging.
+
+2001-02-19 Fernando Nasser <fnasser@redhat.com>
+
+ From Drew Moseley <dmoseley@redhat.com>
+ * gdb.base/ending-run.exp: Properly handle the BSP state when
+ stepping past the end of main.
+
+2001-02-19 John Moore <jmoore@redhat.com>
+
+ * gdb.base/commands.exp (infrun_breakpoint_command_test):
+ Converted HPUX fix for non-expected items following multiple
+ step commands into general solution for all platforms.
+
+2001-02-18 Michael Chastain <chastain@redhat.com>
+
+ * gdb.c++/classes.exp (do_tests): Change runto statements
+ from "runto 'foo(void)'" to "runto 'foo'". This makes the
+ statements demangler agnostic.
+ * gdb.c++/virtfunc.exp (do_tests): Likewise.
+ (gdb_virtfunc_restart): Likewise.
+
+2001-02-14 Michael Chastain <chastain@redhat.com>
+
+ * gdb.c++/inherit.exp (do_tests): Change runto statements
+ from "runto 'foo(void)'" to "runto 'foo'". This makes the
+ statements demangler agnostic.
+
+Sun Feb 4 17:32:21 2001 Andrew Cagney <cagney@redhat.com>
+
+ * gdb.threads/pthreads.exp: Unify pass/fail messages for
+ ``continue to bkpt at common_routine in thread 2'' and ``stopped
+ before calling common_routine 15 times'' tests.
+
+2001-02-11 Michael Chastain <chastain@redhat.com>
+
+ * gdb.c++/cplusfuncs.cc (dm_type_char_star): New function.
+ Helps the test script figure out which demangler is in use.
+ (dm_type_foo_ref): Ditto.
+ (dm_type_int_star): Ditto.
+ (dm_type_long_star): Ditto.
+ (dm_type_unsigned_int): Ditto.
+ (dm_type_void): Ditto.
+ (dm_type_void_star): Ditto.
+ * gdb.base/cplusfuncs.exp (probe_demangler): New function.
+ Probe the gdb demangler and set variables to accommodate
+ formatting differences.
+ (info_func_regexp): New function. Same as info_func, but
+ matches against a regexp.
+ (info_func): Match against a literal string.
+ (print_addr_2): New function. Match against a literal string,
+ which can be different from the input to gdb.
+ (print_addr): Simply call print_addr_2 with the same argument twice.
+ (test_lookup_operator_functions): Use demangler formatting variables.
+ Blow away the xfails and workarounds for gnats gdb bug gdb/18. Sort
+ the tests in the same order as the C++ class declaration.
+ (test_paddr_operator_functions): Ditto.
+ (test_paddr_overloaded_functions): Ditto.
+ (test_paddr_hairy_functions): Use demangler formatting variables.
+ Add reference to gdb/19 for related tests.
+ (do_tests): Call probe_demangler.
+
+2001-01-30 Kevin Buettner <kevinb@redhat.com>
+
+ * gdb.c++/templates.cc (printf): Remove unused function definition.
+
+2001-01-26 Felix Lee <flee@redhat.com>
+
+ * sid.exp (sid_exit): Pass host, not target, to remote_close.
+
+2001-01-25 matthew green <mrg@redhat.com>
+
+ * config/sid.exp (sid_start): Call `remote_push_conn' after firing
+ up sid.
+ (sid_exit): Call `remote_pop_conn' after GDB is gone.
+
+2001-01-25 matthew green <mrg@redhat.com>
+
+ * config/sid.exp (sid_start): Use `remote_spawn' instead of `spawn.'
+ Deprecate $sid_spawn_id.
+ (sid_exit): Remove code necessary only for `spawn.'
+
+2001-01-25 matthew green <mrg@redhat.com>
+
+ * config/sid.exp (sid_start): Handle sim,protocol of `sid.'
+
+2001-01-28 Michael Chastain <chastain@redhat.com>
+
+ * gdb.c++/ovldbreak.exp (take_gdb_out_of_choice_menu): New proc
+ to call when tests fail. It takes gdb out of the overloaded
+ function choice menu back to the main prompt, so that the test
+ program stays synchronized.
+ (set_bp_overloaded): New proc to collect all the common
+ code for setting a breakpoint on an overloaded name. Calls
+ take_gdb_out_of_choice_menu when needed.
+ (menu_overload1arg): New variable to collect the repeated
+ instances of the expected menu for an overloaded name. Change
+ the regular expression to handle changes in g++ type encoding:
+ "void" can be either "void" or "", and "unsigned int" can be
+ either "unsigned int" or "unsigned".
+ (continue_to_bp_overloaded): Change regular expressions to handle
+ changes in g++ type encoding.
+ (no proc): Call take_gdb_out_of_choice_menu when needed.
+ Remove redundant calls to "info break". Accept either "canceled"
+ or "cancelled". Change regular expressions in "info break"
+ calls to handle changes in g++ type encoding. Give all tests
+ unique strings.
+
+2001-01-17 Ben Elliston <bje@redhat.com>
+
+ * config/sid.exp: New file.
+
+Fri Jan 12 18:29:01 2001 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/callfuncs.exp: Add space after ``Value returned is''.
+
+2000-12-21 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/finish.exp: Accept '1' instead of \001 from char_func.
+ Add a RE to accept a non-ascii char if one is ever presented.
+
+2000-12-20 Fernando Nasser <fnasser@redhat.com>
+
+ * lib/mi-support.exp (mi_gdb_start): Test for MI_OUT, not UI_OUT.
+
+2000-12-18 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/setvar.exp: Use double '\\' to quote curly braces
+ in regexp. One '\' does not suffice on Linux.
+
+2000-12-09 Michael Chastain <chastain@redhat.com>
+
+ * gdb.base/break.exp (test_clear_command): Use a marker function
+ rather than 'main' for the test function. Also move this
+ test to an execution point where the marker function names are
+ guaranteed to be bound to functions. (Executing tests after a
+ 'finish' from main runs into name conflicts with local names
+ in __libc_start_main).
+
+2000-12-07 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/finish.exp: New test for gdb's "finish" command.
+ * gdb.base/return2.exp: New test for gdb's "return" command.
+ * gdb.base/return2.c: New source file for above.
+
+2000-12-05 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/constvars.exp: Add a "pass" message if "up" succeeds.
+ * gdb.base/miscexprs.exp: Ditto.
+ * gdb.base/pointers.exp: Ditto.
+ * gdb.c++/derivation.exp: Ditto.
+ * gdb.c++/local.exp: Ditto.
+ * gdb.c++/namespace.exp: Ditto.
+ * gdb.c++/overload.exp: Ditto.
+ * gdb.c++/ref-types.exp: Ditto.
+
+2000-12-05 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/constvars.exp: Test result of "up" command.
+ * gdb.base/miscexprs.exp: Ditto.
+ * gdb.base/pointers.exp: Ditto.
+ * gdb.base/scope.exp: Ditto.
+ * gdb.c++/derivation.exp: Ditto.
+ * gdb.c++/local.exp: Ditto.
+ * gdb.c++/namespace.exp: Ditto.
+ * gdb.c++/overload.exp: Ditto.
+ * gdb.c++/ref-types.exp: Ditto.
+
+2000-11-22 Michael Chastain <chastain@redhat.com>
+
+ * mips_pro.exp: Accept either "middle -> top -> main" or
+ "middle -> main" in the backtrace, because gcc can optimize
+ tail calls to jumps. Remove setup_xfail for the hppa case.
+ Add a comment with the original warning messages from PR 3016,
+ which was filed in 1993, to preserve them for posterity.
+
+2000-11-17 Nick Duffek <nsd@redhat.com>
+
+ * lib/gdb.exp (gdb_test): Override timeout with board info.
+
+2000-11-17 Nick Duffek <nsd@redhat.com>
+
+ * gdb.base/display.exp: Don't kill running stub. Add "again" to
+ the second kill and detach messages.
+
+2000-11-17 Nick Duffek <nsd@redhat.com>
+
+ * configure.in: Add AC_EXEEXT.
+ * configure: Regenerate.
+ * Makefile.in (just-check): Export EXEEXT.
+ * lib/gdb.exp ($EXEEXT): Import from environment.
+ * gdb.base/maint.exp: Expect $EXEEXT in executable name. Don't
+ expect "maint dump-me" on Cygwin.
+ * gdb.base/reread.exp ($binfile, $binfile1, $binfile2): Append
+ $EXEEXT.
+
+2000-11-17 Nick Duffek <nsd@redhat.com>
+
+ * gdb.base/break.exp: Test backtrace and finish from called
+ function on all platforms, not just HP-UX.
+
+2000-11-03 Michael Snyder <msnyder@cygnus.com>
+
+ * config/monitor.exp (gdb_target_cmd): Abstracts some of the
+ code from gdb_target_monitor, so it can be used independantly
+ for gdbserver. Also comment out an unnecessary PUTS.
+
+2000-11-03 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/a2-run.exp: Use gdb_skip_stdio_test.
+ * gdb.base/corefile.exp: Expect the message "Program is being
+ debugged already" when we send the "corefile" command, since
+ the preceeding gdb_load may have connected gdb to a remote target.
+ * gdb.base/display.exp: Disable hardware watchpoints if new
+ board info variable "no_hardware_watchpoints" is true.
+ Replace single-letter commands with more readable ones.
+ * gdb.base/recurse.exp (recurse_tests): Disable hardware watchpoints
+ if new board info variable "no_hardware_watchpoints" is true.
+ * gdb.base/restore.exp (restore_tests): Call gdb_skip_stdio_tests
+ to see if stdio (printf) testing is possible.
+ * gdb.base/watchpoint.exp: Disable hardware watchpoints if new
+ board info variable "no_hardware_watchpoints" is true. Use new
+ proc "gdb_skip_stdio_tests" to see if printf tests are possible.
+
+2000-11-13 Fernando Nasser <fnasser@redhat.com>
+
+ From Orjan Friberg <orjanf@axis.com>:
+ * gdb.base/printcmds.exp: Escape curly braces followed by a number
+ in array print pattern match.
+
+2000-11-09 Fernando Nasser <fnasser@redhat.com>
+
+ * gdb.c++/templates.exp (test_template_breakpoints): Change Britsh
+ spelling "cancelled" to U.S. spelling "canceled" to match changes
+ made to gdb.
+ * gdb.c++/ovldbreak.exp: Ditto.
+
+2000-11-06 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * gdb.base/callfuncs.c (main): Moved to end of file, call
+ t_double_values to initialize the FPU before inferior calls are made.
+ * gdb.base/callfuncs.exp: Test for register preservation after calling
+ inferior functions. Add tests for continuining, finishing and
+ returning from a stop in a call dummy.
+
+2000-10-24 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/commands.exp: Break up long lines, and re-indent.
+
+2000-10-19 Michael Snyder <msnyder@cygnus.com>
+
+ * config/gdbserver.exp: Rewritten from the ground up, to make it
+ compatible with the current dejagnu tree, and to make it work with
+ the new "gdbserver" in libremote.
+
+2000-10-16 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/sizeof.exp (check_sizeof): Skip if no printf support.
+ * gdb.base/varargs.exp: Skip entire test if no printf support.
+ * gdb.base/ending-run.exp (Step to return): Skip if no printf supt.
+ * gdb.base/shlib-call.exp: Skip several tests if no printf support.
+
+2000-10-13 Michael Snyder <msnyder@cygnus.com>
+
+ * lib/gdb.exp (gdb_skip_float_test): New proc. Skip test if
+ no floating point support.
+ (gdb_skip_stdio_test): New proc. Skip test if no stdio support.
+ * gdb.base/call-ar-st.exp: Use above procs to skip tests.
+ * gdb.base/call-rt-st.exp: Ditto.
+ * gdb.base/call-strs.exp: Ditto.
+
+2000-08-02 Jimmy Guo <guo@hpcleara.cup.hp.com>
+
+ * gdb.base/sizeof.c: include <stdio.h>.
+
+ * gdb.c++/classes.exp: Use gdb_test instead of send_gdb to
+ 'finish', otherwise uncaptured gdb_prompt would potentially
+ throw remaining test points out of sync.
+
+2000-07-26 Scott Bambrough <scottb@netwinder.org>
+
+ * gdb.base/recurse.exp: Run tests for all targets.
+ * gdb.base/so-impl-ld.exp: Added wildcard to handle the
+ gnu-oldld case on ARM.
+ * gdb.base/watchpoint.exp (test_stepping): Clear xfail
+ for ARM targets.
+
+Mon Jul 24 07:46:02 CDT 2000 Clinton Popetz <cpopetz@cygnus.com>
+
+ * gdb.java/configure.in (AC_INIT): Use jmisc.exp.
+ * gdb.java/configure: Rebuild.
+
+Sun Jul 23 21:42:34 2000 Anthony Green <green@redhat.com>
+
+ * gdb.java/jv-exp.exp: New file.
+
+Sun Jul 23 21:02:42 2000 Anthony Green <green@redhat.com>
+
+ * configure: Rebuilt.
+ * configure.in (configdirs): Add gdb.java.
+ * gdb.java/jmisc.java: New file.
+ * gdb.java/jmisc.exp: New file.
+ * gdb.java/Makefile.in: New file.
+ * gdb.java/configure: Rebuilt.
+ * gdb.java/configure.in: New file.
+ * lib/java.exp: New file.
+
+Wed Jul 12 18:14:29 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/exprs.exp: Test casts to a pointer including over and
+ underflow.
+
+Thu Jul 13 11:52:53 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/sizeof.exp, gdb.base/sizeof.c: New files. Compare GDB
+ and the compilers sizes.
+
+2000-07-09 Nick Duffek <nsd@redhat.com>
+
+ * gdb.c++/misc.cc (class ClassParam, class_param): Define.
+ (use_methods): New function.
+ (main): Call use_methods().
+ * gdb.c++/classes.exp (test_method_param_class): New procedure.
+ (do_tests): Call test_method_param_class.
+
+2000-07-09 Nick Duffek <nsd@redhat.com>
+
+ * gdb.c++/classes.exp (test_nonexistant_members): Fix name
+ spelling.
+ (test_enums): New procedure. Move enum tests from end of script
+ to here. Set breakpoint on function name instead of line number.
+ * gdb.c++/misc.cc (ClassWithEnum): Move past Foo definitions.
+ (enums2): New marker function.
+ (enums1): New function.
+ (main): Call enums1(). Move enum tests to enums1().
+
+Tue Jul 4 03:43:49 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.asm/asm-source.exp: Use raw AS/LD instead of CC to
+ compile/link program. Update line numbers.
+ * gdb.asm/d10v.inc: Define ``startup''.
+ * gdb.asm/asmsrc1.s: Add definition of _start.
+
+Fri Jun 23 17:45:52 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/call-ar-st.exp: More rewrites of multi-line patterns.
+
+2000-06-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/maint.exp: Add 'maint print architecture' item to output
+ of 'help maint print' command.
+
+Fri Jun 16 18:22:05 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/call-ar-st.exp: Rewrite all multi-line patterns so that
+ they use gdb_expect_list.
+
+Wed Jun 7 13:02:40 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/commands.exp: Use ``set remote
+ memory-read-packet-size'' instead of ``set endian big'' to test
+ long commands.
+
+2000-06-03 Daniel Berlin <dan@cgsoftware.com>
+
+ * gdb.c++/templates.exp (do_tests): Make all of these work under
+ g++, and stop skipping them.
+
+ * gdb.c++/namespace.exp: Move from gdb.hp/gdb.aCC to here, make it
+ work under g++.
+
+ * gdb.c++/misc.cc: Fix ambiguous initialization with correct
+ initialization.
+
+2000-06-02 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/annota1.exp (run until main breakpoint): Loosen up
+ the regular expression: accept an (almost) arbitrary sequence of
+ "frames-invalid" and "breakpoints-invalid" messages both before
+ and after the "starting" message.
+
+2000-06-02 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.c++/local.exp: This test has never been known to work with g++.
+
+2000-05-18 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/annota1.exp (annotate-signal-handler-caller):
+ Relax the regular expression a little, make it pass on Solaris 8.
+
+2000-05-12 Kevin Buettner <kevinb@redhat.com>
+
+ * gdb.base/step-test.exp: On IA-64 targets, when stepping out of
+ a call, do not require that gdb stop on the line after the call.
+ Instead, it is permissible for gdb to stop on the line of the
+ call itself.
+
+2000-05-12 Michael Snyder <msnyder@.cygnus.com>
+
+ * gdb.base/break.exp (bp on small function, optimized file):
+ Add a second pass pattern. The behavior differs here between stabs
+ and dwarf for one-line functions. Stabs preserves two line symbols
+ (one before the prologue and one after) with the same line number,
+ but dwarf regards these as duplicates and discards one of them.
+ Therefore the address after the prologue (where the breakpoint is)
+ has no exactly matching line symbol, and GDB reports the breakpoint
+ as if it were in the middle of a line rather than at the beginning.
+
+2000-05-08 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/interrupt.exp: Make "pass" message say "send"
+ rather than "send_gdb" (for consistancy).
+
+Mon May 1 15:37:58 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From 2000-04-28 Andreas Jaeger <aj@suse.de>:
+ * gdb.c++/templates.cc: Properly check for GCC version number.
+ * lib/compiler.cc: Likewise
+
+2000-04-28 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/break.exp: When compiled with -O2 optimization,
+ gdb may not stop at the first line of main, due to code motion.
+
+2000-04-26 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/call-ar-st.exp: Bail out if target is sparclet.
+ This test depends on parsing the printf output from the target.
+ Since the sparclet stub doesn't do stdio, this will never work.
+ * gdb.base/call-rt-st.exp: ditto.
+ * gdb.base/call-strs: ditto.
+
+2000-04-24 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/miscexprs.exp: make sizeof long array test portable.
+
+ * gdb.base/ending-run.exp: After connecting to a remote target,
+ but before running, the target will appear to be in a random
+ location. Specify both a file and a line for breakpoints.
+ Also, the function that calls main may be called 'init'
+ rather than 'start'.
+
+2000-04-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/help.exp: Update output for add-symbol-file command.
+
+2000-04-10 Fernando Nasser <fnasser@cygnus.com>
+
+ From Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+ * gdb.base/structs2.c: Support platforms defaulting to a unsigned char.
+
+2000-04-07 J.T. Conklin <jtc@redback.com>
+
+ * gdb.base/call-ar-st.exp: Relax patterns matching tab characters.
+
+ * gdb.base/funcargs.exp: Relax patterns matching pointers to char.
+
+Thu Mar 30 13:26:19 2000 Philippe De Muyter <phdm@macqel.be>
+
+ * gdb.base/call-ar-st.c (init_small_structs, main): Use floating-point
+ values that can be represented exactly.
+ * gdb.base/call-ar-st.exp (print print_small_structs): Fixed to match
+ above change, and to not check against the directory part of the source
+ file name.
+ (step into print_long_arg_list): Likewise.
+ (print print_small_structs from print_long_arg_list): Likewise.
+ (print print_long_arg_list): Likewise.
+
+2000-03-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/printcmds.c: Terminate char array ctable2 with 0.
+
+Mon Mar 27 14:46:37 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ChangeLog, gdb.base/commands.exp: Revert whitespace changes.
+
+2000-03-25 Daniel Berlin <dan@cgsoftware.com>
+
+ * gdb.base/commands.exp (deprecated_command_test): Add test for
+ deprecate with no arguments.
+
+2000-03-24 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * gdb.base/break.exp: Add new test for setting breakpoints on
+ optimized code so we can test breakpoints work even when function
+ prologues may be optimized away
+
+2000-03-23 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ From David Whedon <dwhedon@gordian.com>
+ * gdb.base/commands.exp : Added command deprecator tests.
+
+2000-03-22 Daniel Berlin <dan@cgsoftware.com>
+
+ * gdb.base/help.exp: Added test for new apropos command.
+
+2000-03-21 Kevin Buettner <kevinb@redhat.com>
+
+ * gdb.base/pointers.c (usevar): New function.
+ (main): Make sure that global variables v_int_pointer2, rptr,
+ and y are all referenced someplace in the program by calling
+ usevar() on them. [Some linkers delete symbols which are
+ never referenced. The space remains, but there's no way to
+ get a (symbolic) handle on the variable from the debugger.]
+
+2000-03-14 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/printcmds.c: Add typedeffed arrays.
+
+ * gdb.base/printcmds.exp (test_print_typedef_arrays): New
+ procedure to test arrays that are typedef'd.
+
+2000-03-13 James Ingham <jingham@leda.cygnus.com>
+
+ * lib/gdb.exp: Fix the gdbtk_start routine to correctly find all
+ the library directories.
+
+Mon Feb 21 13:05:36 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (configdirs): Add sub directory gdb.mi.
+ * configure: Re-generate.
+
+ * gdb.mi: New directory.
+
+2000-02-25 Scott Bambrough <scottb@netwinder.org>
+
+ * gdb.base/long_long.exp: Correct test suite failure when printing
+ a long long value as a double on ARM platforms.
+
+2000-02-16 Jim Blandy <jimb@redhat.com>
+
+ * gdb.base/break.exp ("breakpoint line number"): Make sure the
+ default source file is set properly before running this test.
+
+2000-02-14 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * lib/gdb.exp: Tell the testsuite that now gdbtk is in the
+ gdbtk/library directory, not in gdbtcl2.
+
+2000-02-04 Jim Blandy <jimb@redhat.com>
+
+ * gdb.c++/templates.exp: ("ptype T5<int>"): Remove extraneous
+ backslash from regexp pattern.
+
+ * gdb.c++/ovldbreak.exp (continue_to_bp_overloaded): New
+ procedure. Use it to run all the "continue to bp overloaded"
+ tests. Note that this changes the names of the tests slightly.
+ If the breakpoint hit message includes a hex PC value, because
+ GCC's Dwarf 2 line info doesn't help us distinguish the prologue
+ from the real source code, still consider that a pass.
+
+ * gdb.base/condbreak.exp ("run until breakpoint at marker2"):
+ XFAIL here if the breakpoint message contains a hex address. Note
+ similar change on 1999-11-02.
+
+ * gdb.base/step-test.exp: Comment Fernando's change of 2000-02-02.
+
+ * gdb.base/ptype.exp: Establish a default source file before
+ calling get_debug_format.
+
+2000-02-03 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.base/watchpoint.exp: Remove duplication of test messages.
+
+2000-02-02 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.base/step-test.exp: Fix the steps to enter a callee by means
+ of successive stepi commands -- while in the prologue we should see
+ the function entry bracket.
+
+2000-02-02 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.base/ending-run.exp: Add ARM in thumb mode case, where we
+ reach __change_mode() when stepping through the end of main().
+
+2000-01-17 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.base/default.exp: Fix expected pattern.
+ * gdb.base/help.exp: Same.
+
+2000-01-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/so-indr-cl.exp: Don't execute the test if not on HPUX.
+ Don't use xfail's because that affects only the following test.
+
+ * gdb.base/so-impl-ld.exp: Don't execute the tests if not on hpux,
+ solaris or linux.
+
+ * gdb.base/selftest.exp: Update to reflect changes to main.c.
+
+2000-01-07 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/display.exp: Some yacc parsers like to say
+ "A syntax error" rather than "A parse error". Accept both.
+
+2000-01-06 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.base/default.exp: Remove OS dependent string from "target
+ remote" test.
+ * gdb.base/help.exp: Same for "help target remote" test.
+
+2000-01-04 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Jim Kingdon <kingdon@redhat.com>:
+
+ * gdb.c++/annota2.exp: Fix "delete bps" test to wait for the
+ prompt (cleanup rather than necessity, but still might keep output
+ from spilling to next test).
+
+2000-01-02 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/ptype.c (FALSE, TRUE): #undef these to avoid clash on
+ AIX, which defines them in <sys/types.h>.
+
+1999-12-16 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/default.exp: Match arm* etc instead of arm in "info
+ float" test.
+
+1999-12-13 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.base/watchpoint.exp: Add missing "(timeout)" to test message.
+
+ * gdb.base/break.exp: Add missing anchor to reg exp on "finish from
+ outermost frame disallowed".
+
+1999-12-09 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.base/setvar.exp: New tests for setting the value of a struct
+ with a constant list.
+
+1999-12-08 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.base/setvar.exp: Remove pair os tests that expected gdb to
+ require the user to type a cast before setting the value of a struct.
+
+1999-12-06 Jim Blandy <jimb@cygnus.com>
+
+ * gdb.base/default.exp: Expect the new 'info float' command on
+ all i386 platforms.
+
+ * gdb.threads/linux-dp.exp: Expand our ability to recognize
+ LinuxThreads libraries that don't support debugging.
+
+Sat Dec 4 15:21:18 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/remote.c: Fill the buffer with truely random data.
+ Change the buffer type to ``unsigned char'' to simplify size
+ arithmetic.
+
+ * gdb.base/remote.exp: Reduce download numbers by one. Typical
+ stub only handles 400-1 byte packets. Verify that the download
+ worked.
+
+1999-11-30 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * lib/gdb.exp (gdb_expect_list): FAIL only once on multiple pattern
+ tests, using UNRESOLVED for the untested cases. Also, does not wait
+ for a timeout if the prompt was received before a recognizable pattern.
+
+1999-11-29 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * lib/gdb.exp (gdb_expect_list): Fix spelling.
+
+1999-11-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/watchpoint.exp: Add tests cases for the hit count of
+ watchpoints.
+
+1999-11-24 Jason Merrill <jason@casey.cygnus.com>
+
+ * gdb.base/condbreak.exp: Add missing '$gdb_prompt $'.
+
+ * gdb.c++/local.exp: Be more flexible in recognizing local class
+ name mangling. Don't allow horribly truncated method names.
+ * gdb.c++/derivation.exp: Expect protected inheritance.
+ * gdb.c++/inherit.exp: Be more flexible in recognizing vbase pointers.
+ * gdb.c++/virtfunc.exp: Likewise.
+ * gdb.c++/classes.exp: Likewise. Don't require the enclosing scope
+ when printing a nested enum.
+
+1999-11-22 Jim Blandy <jimb@cygnus.com>
+
+ * gdb.base/step-test.exp: Properly await GDB's response to setting
+ a breakpoint on the call to large_struct_by_value.
+
+ * gdb.base/ending-run.exp ("step to end of run 1"): Don't fail
+ just because we have debug info for the `start' function.
+
+1999-11-19 Jim Blandy <jimb@zenia.red-bean.com>
+
+ * gdb.threads/linux-dp.exp ("create philosopher"): Recognize the
+ "Unknown signal" messages, which indicate (on LinuxThreads) that
+ GDB doesn't know how to debug threads on this system. This is
+ better than hanging while philosopher 0 dumps chatter into gdb.log.
+
+1999-11-18 Tom Tromey <tromey@cygnus.com>
+
+ * gdb.trace/deltrace.exp: Updated test to reflect new error text.
+
+1999-11-18 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/coremaker2.c: Add sample program for generating
+ cores that is more self contained than coremaker.c. Eventually
+ I'll add more code to this and tie it into the testsuite.
+
+1999-11-12 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/dollar.exp: Remove, now in gdb.hp.
+
+1999-11-10 Jimmy Guo <guo@cup.hp.com>
+
+ * gdb.exp (get_compiler_info): pick up compiler.c and compiler.cc
+ from $srcdir/lib/.
+ * lib/compiler.c, lib/compiler.cc: New files, moved from gdb.base/
+ and gdb.c++/.
+
+ * gdb.c++/derivation.exp: remove redundant get compiler info code.
+
+ * gdb.base/commands.exp: add '$gdb_prompt $' anchor to
+ 'continue with watch' test point.
+
+1999-11-08 Jim Blandy <jimb@zenia.red-bean.com>
+
+ Merged from p2linux-990323-branch:
+
+ * lib/gdb.exp (gdb_continue_to_breakpoint): New function.
+
+Mon Nov 8 23:07:09 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * gdb.base/remote.exp: Test ``set remote memory-write-packet-sized
+ {limit,fixed}''. Test ``set download-write-size''.
+
+Sun Nov 7 17:37:01 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/funcargs.exp: Rewrite stack traceback checks using
+ gdb_expect_list.
+
+Fri Nov 5 18:40:52 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdb.exp (gdb_expect_list): Return a success/fail indication.
+
+1999-11-03 Mark Salter <msalter@cygnus.com>
+
+ * gdb.base/break.exp: Fix "stub continue" pattern.
+
+1999-11-03 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdb.base/shlib-call.exp ("next to shr1"): Fix test name.
+
+1999-11-02 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdb.base/display.exp ("finish"): Add timeout clause.
+
+ * gdb.base/condbreak.exp ("run until breakpoint at marker1"): Add
+ plain prompt clause, so this doesn't have to time out in order to
+ fail.
+
+ * gdb.base/condbreak.exp, gdb.base/ena-dis-br.exp: XFAIL if the
+ breakpoint hit messages include an address.
+
+ * gdb.base/display.exp: Don't forget to escape parens in regular
+ expressions. Unix regexp notatation sucks.
+
+1999-11-02 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/annota1.exp: Test for annotate-signalled: change output
+ order for 'signalled' message.
+
+1999-11-01 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Jimmy Guo <guo@cup.hp.com>:
+ * gdb.base/annota1.exp: Add tests for annotate ignore count change.
+ * gdb.base/annota1.c: Add code for tests to work with.
+
+1999-10-26 Frank Ch. Eigler <fche@cygnus.com>
+
+ * gdb.base/remote.exp: New test for remote downloading settings.
+ * gdb.base/remote.c: New file with large .data.
+
+1999-10-18 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdb.threads/linux-dp.c, gdb.threads/linux-dp.exp: New test suite
+ for LinuxThreads support, merged from the Code Fusion branch.
+
+Mon Oct 11 13:57:21 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * lib/gdb.exp (gdb_run_cmd): Break complicated gdb_expect
+ containing exp_continue into a while within an expect. Don't
+ attempt a start more than three times. Check return value from
+ gdb_load.
+
+Wed Oct 6 12:05:58 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/watchpoint.exp: Match fail ``finish from marker1'' with
+ a pass case.
+
+1999-10-01 Kevin Buettner <kevinb@cygnus.com>
+
+ * gdb.base/break.c (main): Added a statement that we can step
+ off of.
+ * gdb.base/break.exp: Added tests for setting a breakpoint
+ at an offset and stepping onto a breakpoint.
+
+1999-10-01 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/help.exp (help add-symbol-file): Update to match current
+ gdb output.
+
+1999-09-18 Jim Blandy <jimb@cris.red-bean.com>
+
+ * gdb.base/break.exp: Code locations are in hex, don't forget!
+ (For HP-UX.)
+
+1999-09-17 Stan Shebs <shebs@andros.cygnus.com>
+
+ * condbreak.exp: Use break.c as test program.
+ * condbreak.c: Remove, redundant with break.c.
+
+1999-09-15 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/monitor.exp (gdb_target_monitor): Disable X- and
+ Z-packets if the target needs it.
+
+1999-09-13 James Ingham <jingham@leda.cygnus.com>
+
+ * gdb.c++/overload.exp: Added tests for listing overloaded
+ functions with function pointers in the arg, explicitly calling
+ out the version you want.
+
+1999-09-09 Stan Shebs <shebs@andros.cygnus.com>
+
+ * long_long.exp: Add variations of test cases that work for
+ targets with 16-bit ints and 32-bit doubles.
+
+1999-09-08 Stan Shebs <shebs@andros.cygnus.com>
+
+ * break.c (main): Compare a possibly-uninitialized argc with an
+ unlikely value that fits in 16 bits.
+
+1999-09-07 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/restore.c, gdb.base/restore.exp: Use 0x7eeb instead of
+ 0xfeeb, don't want negative numbers if ints are 16 bits.
+
+ * lib/gdb.exp (skip_cplus_tests): New proc.
+ * gdb.c++/ambiguous.exp, gdb.c++/annota2.exp,
+ gdb.c++/anon-union.exp, gdb.c++/classes.exp,
+ gdb.c++/cplusfuncs.exp, gdb.c++/ctti.exp, gdb.c++/demangle.exp,
+ gdb.c++/derivation.exp, gdb.c++/inherit.exp, gdb.c++/local.exp,
+ gdb.c++/member-ptr.exp, gdb.c++/method.exp, gdb.c++/misc.exp,
+ gdb.c++/overload.exp, gdb.c++/ovldbreak.exp,
+ gdb.c++/ref-types.exp, gdb.c++/templates.exp, gdb.c++/userdef.exp,
+ gdb.c++/virtfunc.exp: Use it to skip over C++ tests.
+
+ * gdb.c++/cplusfuncs.exp: Use get_compiler_info consistently.
+
+Fri Sep 3 15:37:12 1999 Kevin Buettner <kevinb@cygnus.com>
+
+ * gdb.base/corefile.exp (up): Allow a parameter to appear
+ in the frame that we're going up to.
+
+ From Jim Blandy <jimb@cygnus.com>:
+
+ * gdb.base/default.exp (info float): Expect some output now.
+
+ * gdb.base/callfuncs.exp (do_function_calls): We no longer expect
+ returning floating-point values to fail on the x86.
+ * gdb.base/callfwmall.exp (do_function_calls): Same.
+
+ * gdb.base/list.exp (test_listsize): Correct expectations for
+ listing line 1 with listsize 2. Also, listing a single line
+ works now, as does listing three lines. [Kevin's note: There
+ were a number of other cases fixed too where the expectations
+ differed...]
+
+1999-09-02 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/selftest.exp: Add case for when version prints as
+ constant string instead of char pointer.
+
+1999-08-25 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/ending-run.exp: Add Solaris case for what happens when
+ stepping out of main.
+
+ * gdb.c++/derivation.exp: XFAIL inf fn calls for all configs, if
+ G++ used.
+
+ * gdb.c++/local.exp: Expect ptype NestedInnerLocal to succeed
+ always, expect ptype InnerLocal::NestedInnerLocal to fail always.
+
+ * gdb.c++/ovldbreak.exp: Update match string in test that
+ includes a warning of multiple breakpoints.
+
+1999-08-24 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/display.exp: Improve precision of step-after-finish
+ added yesterday.
+
+ * gdb.base/signals.exp: Add extra wildcard to "handle all print"
+ test.
+
+ * gdb.c++/classes.exp: XFAIL HP-compiler-only tests for all
+ configs when using G++, not just hppa*.
+
+1999-08-24 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/async.c: New file.
+ * gdb.base/async.exp: New file.
+
+Tue Aug 24 03:24:53 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/break.exp: Tweak PA specific tests to properly handle
+ PA64.
+
+Mon Aug 23 10:25:20 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/display.exp: "finish" can leave us mid-line on many
+ targets, deal with it. Add a small constant to main, instead of
+ 1000 since main+1000 may not be a valid address in the target.
+
+ * gdb.base/dollar.exp: Do not run for PA processors in wide mode
+ on hpux11.
+
+ * gdb.base/attach.exp: Handle another hpux11 error message variant
+ when attaching to a process that does not exist.
+
+1999-08-19 J.T. Conklin <jtc@redback.com>
+
+ * gdb.base/call-ar-exp.exp: Fix pattern matching whitespace
+ characters in 'continue to 1241' test.
+
+1999-08-17 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/call-ar-st.exp: Add a shorter match case for the
+ stop in print_long_arg_list, define and use a whitespace
+ variable in print_small_structs test, add an XFAIL for Solaris.
+ * gdb.base/dbx.exp: XFAIL func commands until somebody is
+ interested enough to fix.
+
+1999-08-13 Keith Seitz <keiths@cygnus.com>
+
+ * gdb.base/dbx.exp (dbx_gdb_file_cmd): Rename to gdb_file_cmd.
+ (dbx_gdb_load): Remove. Use gdb_load instead, since that
+ proc knows about targets other than the natives.
+ (test_assign): Use "gdb_run_cmd" to "run" the target.
+ Check that we've actually hit the breakpoint at main.
+ When we attempt to assign a value to a local variable, check
+ that the variable is in the current scope, i.e., don't use
+ a test with an empty result.
+
+Tue Aug 10 15:25:16 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/maint.exp: Add test of ``maintenance internal-error''
+ command.
+
+1999-08-09 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Jimmy Guo <guo@cup.hp.com> and others at HP:
+ gdb.hp: Move tests into subdirectories gdb.aCC, gdb.base-hp,
+ gdb.compat, gdb.threads-hp.
+ gdb.hp/configure, gdb.hp/configure.in: New files.
+ gdb.hp/Makefile.in: Recurse into new subdirs.
+ gdb.hp/gdb.defects: New directory, tests for HP bug reports.
+ gdb.hp/gdb.objdbg: New directory, tests for debugging info
+ in object files.
+ gdb.hp/tools: New directory, aux tools for HP-specific tests.
+
+1999-08-05 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/display.exp: Help expect by putting a newline in the
+ funky printf, remove a bogus p/a test.
+
+1999-08-05 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/display.exp: Make sure that when we say 'run', we are
+ connected to the target. This is necessary when running not
+ natively.
+
+1999-08-03 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/step-test.exp: Removed some extraneous messages.
+
+ * gdb.base/long_long.exp: Don't run memory examination tests
+ on little-endian targets (they will need a different set of
+ results to match).
+
+1999-08-02 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.c++/virtfunc.exp: Expect to fail the virtual call tests
+ until somebody decides to fix GDB.
+
+ * gdb.base/long_long.c: Stop compiler complaint by specifying long
+ constant as "ULL".
+ * gdb.base/long_long.exp: Loosen x/c test, add partial result
+ matches for a couple x/2 commands.
+
+1999-07-30 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.c++/ref-types.cc, gdb.c++/ref-types.exp: Appease doschk
+ by merging in ref-types2 tests.
+ * gdb.c++/ref-types2.cc, gdb.c++/ref-types2.exp: Remove.
+
+ From Jimmy Guo <guo@cup.hp.com> and others at HP:
+ * gdb.c++/Makefile.in: Add standard actions.
+ (EXECUTABLES): Rename from PROGS, update list.
+ * gdb.c++/ambiguous.cc, gdb.c++/ambiguous.exp: Move to here
+ from gdb.hp.
+ * gdb.c++/anon-union.cc: Don't use anonymous struct, make
+ foo and bar locals.
+ * gdb.c++/anon-union.exp: Fix tests to match.
+ * gdb.c++/classes.exp: Run if HP compiler used, add extra
+ expect matches to handle output variations.
+ * gdb.c++/cplusfuncs.cc: Make operator -> return foo *.
+ * gdb.c++/cplusfuncs.exp: Update to match, allow word "class" in
+ output, add HP alternatives for new and delete prints.
+ * gdb.c++/ctti.exp, gdb.c++/cttiadd.cc, gdb.c++/cttiadd1.cc,
+ gdb.c++/cttiadd2.cc, gdb.c++/cttiadd3.cc: Move here from gdb.hp.
+ * gdb.c++/demangle.exp: Use $style when reporting failure.
+ * gdb.c++/derivation.exp: Add some xfails if GCC-compiled.
+ * gdb.c++/inherit.exp: Run if HP compiler used, add some
+ match alternatives.
+ * gdb.c++/local.exp: Add match alternatives or xfails for HP
+ compilers.
+ * gdb.c++/member-ptr.exp: Add xfails for hppa*-*-*.
+ * gdb.c++/method.exp: Add match alternatives.
+ * gdb.c++/misc.cc: Add bool types.
+ * gdb.c++/misc.exp: Add tests for bool types.
+ * gdb.c++/overload.exp: Add xfails.
+ * gdb.c++/templates.cc: Remove bogus arglist init, init fvpchar.
+ * gdb.c++/templates.exp: Run if HP compiler used, add some xfails,
+ add some more template parameter tests (only for HP currently).
+ * gdb.c++/userdef.exp: Add xfails for hppa*-*-*.
+ * gdb.c++/virtfunc.cc: Add return type and value for main.
+ * gdb.c++/virtfunc.exp: Run if HP compiler used, add some
+ match alternatives.
+
+1999-07-30 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/display.exp: Fix output of 'p/a &&j' test.
+
+1999-07-29 Jim Blandy <jimb@savonarola.red-bean.com>
+
+ * gdb.base/signals.exp: Don't expect getting a backtrace from
+ within a signal handler to fail on Linux.
+
+1999-07-29 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Jimmy Guo <guo@cup.hp.com> and others at HP:
+ * lib/gdb.exp: Remove some gratuitious semicolons.
+ (delete_breakpoints): Increase timeout.
+ (gdb_expect): Add -notransfer option.
+ (gdb_test): Use -notransfer option.
+ (get_compiler_info): Add f77 case.
+ (get_compiler): New proc, split out from gdb_preprocess, add f77
+ case.
+ (gdb_preprocess): Call get_compiler.
+
+ * gdb.base/Makefile.in (EXECUTABLES): Update the list.
+ * gdb.base/attach.exp, gdb.base/display.exp,
+ gdb.base/ending-run.exp, gdb.base/gdbvars.exp,
+ gdb.base/long_long.exp, gdb.base/printcmds.exp,
+ gdb.base/structs.exp, gdb.base/structs2.exp: Remove or fill in
+ third arg to gdb_test.
+ * gdb.base/call-ar-st.exp: Add HP-UX xfail for >10-arg functions.
+ * gdb.base/callfuncs.exp, gdb.base/callfwmall.exp: Remove some
+ HP-UX xfails, add others.
+ * gdb.base/completion.exp: Reflect name change of self-test.
+ * gdb.base/condbreak.exp, gdb.base/corefile.exp,
+ gdb.base/foll-exec.exp, gdb.base/interrupt.exp,
+ gdb.base/ptype.exp, gdb.base/scope.exp, gdb.base/setvar.exp: Note
+ HP failure number.
+ * gdb.base/foll-vfork.exp: Loosen matches slightly, remove
+ useless HP-UX 10.30 references.
+ * gdb.base/maint.exp: Loosen matches.
+ * gdb.base/pointers.c (main): Declare more_code.
+ * gdb.base/pointers.exp: Match on output of a `next'.
+ * gdb.base/structs.c: Add prototypes.
+ * gdb.base/watchpoint.exp: Remove HP-UX 10.30 reference.
+ * gdb.base/whatis.exp: Fail for both HP-UX 10.20 and 11.
+
+1999-07-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/list.exp: Add tests for repeating 'list <linenum>'
+ command.
+
+1999-07-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.c++/annota2.exp: Fix delete breakpoint query testcase.
+ Fix run to main failures. Watchpoint can be hardware watchpoint.
+
+ * gdb.base/annota1.exp: Clean up some more, in case printf has
+ debug info. Deal with lack of signal hanlder info in stack.
+
+ From Jim Kingdon <kingdon@redhat.com>:
+ * gdb.base/annota1.exp: If printf has debug info, deal with it.
+
+1999-07-19 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/foll-exec.exp, gdb.base/foll-fork.exp,
+ gdb.base/foll-vfork.exp: Don't run for crosses.
+
+Tue Jul 13 23:37:18 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/configure.in: Check for gdbvars.exp instead of
+ a1-selftest.exp.
+ * gdb.base/configure: Re-generate.
+
+1999-07-12 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/selftest.exp: Rename from a1-selftest.exp, no point
+ in trying to run first and name is too long.
+
+ * gdb.base/pointers.c, gdb.base/pointers.exp: Add contents of
+ pointers2.c and pointers2.exp, respectively.
+ * gdb.base/pointers2.c, gdb.base/pointers2.exp: Remove, makes
+ doschk happier.
+
+1999-07-08 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/callfwmall.c, gdb.base/callfwmall.exp: Renamed from
+ callfuncs2.c and callfuncs2.exp.
+
+ * gdb.base/list.exp: Remove mistaken xfails.
+ * gdb.base/list0.h: Add optional prototypes.
+
+Wed Jul 7 00:27:35 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * gdb.base/setvar.exp: Increase the time-out on tests indirectly
+ calling malloc.
+ * nodebug.exp, printcmds.exp, ptype.exp, setvar.exp: Ditto.
+ * ptype.exp: Move test for get_debug_format to before its first
+ use.
+
+1999-07-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/Makefile.in (EXECUTABLES): Remove annota2 executable.
+ * gdb.base/annota2.cc, annota2.exp: Move from here.
+ * gdb.c++/annota2.cc, annota2.exp: To here.
+ * gdb.c++/Makefile.in (PROGS): Add annota2 executable.
+
+Tue Jun 29 11:56:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdb.exp (gdb_expect_list): Output one message per pattern in
+ a consistent format.
+
+1999-06-25 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Jimmy Guo <guo@cup.hp.com> and others at HP:
+ * lib/gdb.exp (get_compiler_info): Add detection for assorted
+ HP compilers, also set the globals $true and $false.
+
+ * gdb.base/annota1.c, bitfields.c, break.c, call-ar-st.c,
+ call-rt-st.c, call-strs.c, callfuncs.c, callfuncs2.c, condbreak.c,
+ coremaker.c, ending-run.c, exprs.c, funcargs.c, interrupt.c,
+ jump.c, langs0.c, langs1.c, langs2.c, list0.c, list1.c,
+ long_long.c, mips_pro.c, nodebug.c, opaque0.c, opaque1.c,
+ printcmds.c, ptype.c, recurse.c, restore.c, return.c, run.c,
+ scope0.c, scope1.c, setshow.c, setvar.c, shmain.c, shr1.c, shr2.c,
+ sigall.c, signals.c, so-impl-ld.c, so-indr-cl.c, solib.c,
+ solib1.c, solib2.c, step-test.c, twice.c, varargs.c, watchpoint.c,
+ whatis.c} Add C++ compatible function definitions and return
+ types, add includes for library functions.
+ * gdb.base/ptype.c (my_false, my_true): Use instead of false/true.
+ * gdb.base/step-test.c (myglob): Rename from glob.
+ * gdb.base/attach.c, attach2.c, average.c, execd-prog.c,
+ foll-exec.c, foll-fork.c, foll-vfork.c, sum.c, vforked-prog.c: New
+ files, move here from gdb.hp.
+ * gdb.base/annota1.exp, break.exp, call-ar-st.exp, call-rt-st.exp,
+ commands.exp, condbreak.exp, define.exp, ena-dis-br.exp,
+ ending-run.exp, jump.exp. list.exp, long_long.exp, so-impl-ld.exp:
+ Adjust line numbers in regexps.
+
+ * gdb.base/all-bin.exp, eval-skip.exp, exprs.exp, logical.exp,
+ miscexprs.exp, pointers.exp, relational.exp: Use $true and $false
+ instead of 0/1.
+
+ * gdb.base/attach.exp, dbx.exp, foll-exec.exp, foll-fork.exp,
+ foll-vfork.exp: New files, move here from gdb.hp.
+ * gdb.base/page.exp: New file, test of pagination command.
+
+ * gdb.base/watchpoint.c (recurser): New function, for watchpoint
+ recursion test.
+ * gdb.base/watchpoint.exp: Add more test cases for watchpoints.
+
+ * gdb.base/so-impl-ld.exp, gdb.base/so-indr-cl.exp,
+ gdb.base/solib.exp: Fix compiler invocation process.
+
+ * gdb.base/callfuncs.exp, gdb.base/callfuncs2.exp: Don't xfail for
+ HP-UX 11, turn off overload resolution explicitly.
+ * gdb.base/commands.exp: Set argument list explicitly, add
+ watchpoint test.
+ * gdb.base/completion.exp: Enable if HP-UX, tweak tests to make
+ them work.
+ * gdb.base/constvars.exp, gdb.base/volatile.exp: Escape the
+ expressions properly.
+ * gdb.base/corefile.exp: Loosen the match slightly.
+ * gdb.base/default.exp: Allow "Error accessing memory" message
+ also.
+ * gdb.base/display.exp: Skip over x/0 j if PA64.
+ * gdb.base/funcargs.exp: Add xfails for HP-UX.
+ * gdb.base/interrupt.exp: Ditto.
+ * gdb.base/langs.exp: Add symbolic matches governed by compiler
+ in use.
+ * gdb.base/list.exp: Add xfails for HP-UX.
+ * gdb.base/long_long.exp: Refine some of the numeric matches.
+ * gdb.base/mips_pro.exp: Xfail on HP-UX.
+ * gdb.base/miscexprs.exp: Add PA2.0 case for array size test.
+ * gdb.base/nodebug.exp: Succeed on more varieties of output.
+ * gdb.base/opaque.exp: Remove some HP-UX xfails.
+ * gdb.base/ptype.exp: Succeed on more varieties of output.
+ * gdb.base/scope.exp: Add xfails for HP-UX.
+ * gdb.base/sect-cmd.exp: Add more cases.
+ * gdb.base/setvar.exp: Add xfails for HP-UX.
+ * gdb.base/shlib-call.exp: Loosen some matches slightly.
+ * gdb.base/signals.exp: Match on void symbolically.
+ * gdb.base/step-test.exp: Add case for PA64.
+ * gdb.base/term.exp: Add exit and restart.
+ * gdb.base/twice.exp: Clean up after self.
+ * gdb.base/varargs.exp: Disable overload resolution explicitly.
+ * gdb.base/whatis.exp: Allow more ways to pass tests.
+
+ * gdb.base/smoke.exp, gdb.base/smoke.c, gdb.base/smoke.cc: Remove,
+ no longer useful.
+
+Fri Jun 25 19:27:28 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdb.exp (proc gdb_expect_list): New procedure. Matches a
+ list of patterns.
+ * gdb.base/call-ar-st.exp: Use gdb_expect_list in "print
+ print_double_array(double_array)", "continuing to breakpoint
+ 1018", "print print_double_array(array_d)" and "continuing to
+ 1034" tests.
+
+1999-06-24 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * Makefile.in: Add empty html and install-html targets.
+
+1999-06-24 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/mt-*: Remove, these haven't been used since 1996.
+
+1999-06-22 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/call-strs.c, gdb.base/ending-run.c,
+ gdb.base/step-test.c: Include stdlib.h and string.h as needed.
+ * gdb.c++/member-ptr.exp: Skip over these tests if using G++.
+
+1999-06-18 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.c++/overload.exp: XFAIL everything if using G++, add a
+ simpler match case for the ptype of the big class.
+
+1999-06-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.exp: Fix test for gdb_prompt existence.
+
+1999-06-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.exp (gdb_test): Add fail after calls to perror.
+
+1999-06-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.exp (gdb_test): Accept variations of Undefined command messages.
+
+1999-06-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.exp (gdb_test): Fix anchors on gdb_expect statement.
+
+Fri Jun 11 12:56:50 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/call-strs.c (link_malloc): New function. Ensure that
+ malloc() is linked in.
+
+1999-06-08 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.base/ending-run.exp: Make sure we fail and do not timeout at
+ step at end.
+
+ * gdb.base/annota1.exp: Increase match_max to prevent timeout.
+
+1999-06-08 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdb.java/jv-print.exp: New file. (Our first Java test!)
+
+Fri Jun 4 10:47:46 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/a1-selftest.exp: Remove bogus hppa xfail.
+ * gdb.base/mips_pro.exp: Likewise.
+
+1999-06-02 Keith Seitz <keiths@cygnus.com>
+
+ * gdb.c++/templates.cc: Change all "new" operators to throw
+ an exception.
+ * gdb.c++/cplusfuncs.cc: Likewise.
+
+ * gdb.base/Makefile.in (EXECUTABLES): Add smoke1, annota1, and annota2.
+
+Wed Jun 2 17:37:05 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/condbreak.exp: Use rerun_to_main to start the program.
+ * gdb.base/ending-run.exp: When stepping out of main, accept a
+ step into an arbitrary assembler file.
+
+1999-05-20 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/annota1.exp: Allow any number of "frames-invalid" and
+ "breakpoint-invalid" to be printed.
+ * gdb.base/annota2.exp: Revise line number for main breakpoint. Allow any
+ number of "frames-invalid" and "breakpoint-invalid" to be printed.
+ * gdb.base/annota2.cc: Initialize a.x to 0.
+
+1999-05-17 Keith Seitz <keiths@cygnus.com>
+
+ * gdb.base/call-ar-st.exp: Skip "print print_double_array (double_array)"
+ when "skip_float_tests" set.
+ Ditto for "print print_double_array(array_d)", "print print_small_structs",
+ "print print_ten_doubles", and "step into print_long_arg_list".
+ Don't assume we can step into "print_long_arg_list": we could step into memcpy.
+ * gdb.base/call-rt-st.exp: Don't run float-related tests when "skip_float_tests"
+ is set: "print print_one_double(*d1)" and "print print_two_floats(*f3)".
+ * gdb.base/funcargs.exp: Don't run "float_and_integral_args" when
+ "skip_float_tests" is set.
+ * gdb.base/varargs.exp: Skip "print find_max_double(5,1.0,17.0,2.0,3.0,4.0)"
+ when "skip_float_tests" set.
+
+1999-05-06 Keith Seitz <keiths@cygnus.com>
+
+ * gdb.base/annota2.cc: Include stdio.h.
+
+Wed May 5 17:44:31 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/crossload.exp: Remove, this has been disabled ever
+ since BFD stopped including all targets, and cross-GDB gets
+ plenty of testing anyway.
+ * gdb.base/i486-elf.u, gdb.base/m68k-aout.u, gdb.base/m68k-elf.u,
+ gdb.base/sparc-aout.u, gdb.base/i860-elf.u, gdb.base/m68k-aout2.u,
+ gdb.base/mips-ecoff.u, gdb.base/sparc-elf.u: Remove.
+ * gdb.base/README: Remove, was doc for this.
+ * gdb.base/Makefile.in (CROSS_EXECUTABLES): Remove, no longer
+ needed.
+
+1999-05-04 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/call-ar-st.exp: Fix one regular expression in test
+ output.
+
+ * gdb.base/annota1.exp: New file. Annotation level 2 tests.
+ * gdb.base/annota2.exp: New file. More annotation tests.
+ * gdb.base/annota1.c: New file. Source file for annota1.exp.
+ * gdb.base/annota2.cc: New file. Source file for annota2.exp.
+
+1999-04-23 Angela Marie Thomas <angela@cygnus.com>
+
+ * config/cfdbug.exp: New file.
+
+1999-04-20 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdb.c++/demangle.exp (test_gnu_style_demangling): Add tests for
+ Marcus Daniel's and Dale Hawkins's demangler crashes.
+
+ * gdb.c++/demangle.exp (test_gnu_style_demangling,
+ test_lucid_style_demangling, test_arm_style_demangling,
+ test_hp_style_demangling): Try Tom Tromey's core-dumping
+ identifier under each demangling style.
+
+1999-04-07 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdb.c++/demangle.exp: Include the current demangling style
+ in all test names.
+ (current_demangling_style): New global variable.
+ (set_demangling_style, test_demangling_core, test_demangling,
+ test_demangling_exact): New functions.
+ (test_gnu_style_demangling, test_lucid_style_demangling,
+ test_arm_style_demangling, test_hp_style_demangling): Use those,
+ instead of calling gdb_test and gdb_test_exact directly.
+ (catch_demangling_errors): New function, which reports errors
+ signalled by the demangling test functions in an orderly way.
+ (do_tests): Use catch_demangling_errors.
+
+1999-04-06 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdb.base/signals.exp (test_handle_all_print): Use () for
+ grouping in expressions, not {}.
+
+ * gdb.base/smoke.exp: Test value of x, not y. The latter isn't
+ initialized yet.
+
+1999-04-01 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.c++/derivation.exp: Pass ptype tests if synthesized methods
+ are listed.
+
+1999-03-26 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.stabs/weird.exp: Test for CC being defined before
+ looking at its value.
+
+1999-03-25 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/call-ar-st.exp: Remove stray '#'.
+ * gdb.base/miscexprs.exp: Allow "short" and "long" as well as
+ "short int" and "long int".
+ * gdb.c++/overload.cc: Cast the string added in the previous
+ change, to mollify finicky HP compiler.
+ * gdb.hp/reg-test.exp (testfile): Fix file name.
+ * gdb.stabs/weird.exp: Don't try to run if HP compiler in use.
+
+ * gdb.c++/misc.cc (main): Initialize obj_with_enum.
+ * gdb.c++/classes.exp: Fix test of obj_with_enum values, allow
+ alternate form of enum ptype.
+
+1999-03-23 Stan Shebs <shebs@andros.cygnus.com>
+
+ * lib/gdb.exp (skip_hp_tests): Remove gcc_used argument.
+ * gdb.hp/*.exp: Change all to run compiler probe only after
+ passing skip_hp_tests, so as not to waste time on guaranteed
+ failure.
+
+ * gdb.c++/overload.cc: Pass string instead of char addr, always
+ init ccpfoo.
+ * gdb.c++/templates.cc: Fix syntax error.
+
+Tue Mar 23 14:56:36 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.base/commands.exp: Add test for correct position of '>'
+ when issuing the 'commands' command after a 'while' or 'if'
+ command.
+
+1999-03-18 James Ingham <jingham@cygnus.com>
+
+ * gdb.c++/ovldbreak.exp: Use gdb_continue_to_end
+
+ * gdb.c++/method.exp: It was testing an uninitialized int on the
+ stack and assuming it was positive.
+
+ * gdb.base/watchpoint.exp: Use gdb_continue_to_end.
+
+ * gdb.base/step-test.exp: Catch a case where finish is broken and
+ keep it from killing the rest of the tests.
+ Use gdb_continue_to_end.
+
+ * gdb.base/sigall.exp: use gdb_continue_to_end.
+
+ * gdb.base/ena-dis-br.exp: use gdb_continue_to_end.
+
+ * gdb.base/display.exp: use runto_main, not run.
+
+ * gdb.base/default.exp: Check for the current error message in the
+ r abbreviation test.
+ Add strongarm to the targets that know info float.
+
+ * gdb.base/condbreak.exp: Use the gdb_run command rather than just
+ run which doesn't work with monitors.
+
+ * gdb.base/call-ar-st.exp: fixed bogus regexp in continuing to 1034 test.
+
+ * gdb.base/break.exp: use the gdb_continue_to_end proc.
+
+ * lib/gdb.exp: I had added gdb_continue_to_end used to run to the end of a
+ program. Traps the case (in Cygmon) when the program never really
+ exits. Same as Mark's continue_to_exit, but I had put it in a lot
+ more places, so I used my name. Sorry Mark...
+
+ * config/monitor.exp (gdb_target_monitor): added another
+ target_info parameter: remotebinarydownload. This will set the
+ remotebinarydownload flag if this is causing some boards trouble.
+
+1999-03-18 Mark Salter <msalter@cygnus.com>
+
+ * lib/gdb.exp (continue_to_exit): New function.
+
+ * gdb.base/ena-dis-br.exp: Clean up for remote targets.
+ * gdb.base/ending-run.exp: Ditto.
+ * gdb.base/step-test.exp: Ditto.
+
+1999-03-16 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/miscexprs.c: Clean up file, clear cbig.c[0] explicitly
+ (suggested by Art Haas <ahaas@neosoft.com>).
+
+1999-03-16 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdb.base/signals.exp: Filter out *-*-linux* before matching *-*-gnu*.
+
+Fri Mar 12 18:06:21 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.c++/ref-types.exp, ref-types2.exp: Allow alternate
+ descriptions of types (short unsigned int vs unsigned short, etc).
+
+1999-03-12 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdb.base/call-strs.exp: Don't assume that `step' will step over
+ a call to strlen; sometimes we do have sources.
+
+1999-03-08 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdb.base/call-ar-st.c (main): Terminate char_array with a null
+ character, so GDB won't print garbage after its end.
+
+ * gdb.base/call-ar-st.exp: Don't step into sum_array_print; set a
+ breakpoint there instead. Sometimes GCC emits memcpy to handle
+ the large structures being passed by value, so we step into that
+ instead of sum_array_print, which obscures what we're really testing.
+ * gdb.base/step-test.exp: However, we do want a test that notices
+ the bizarre steps into memcpy, so do that here. Add check for
+ stepping into function calls that pass large structures by value.
+ ("Is that a noun clause, or are you just happy to see me?")
+ Remove all references to specific line numbers.
+ * gdb.base/step-test.c (struct rhomboidal, large_struct_by_value):
+ New type and function.
+ (main): Call large_struct_by_value, passing it a large struct by value.
+ * lib/gdb.exp (gdb_get_line_number): New function.
+
+ * gdb.base/step-test.exp: Rewrite `stepi' and `nexti' tests to be
+ more portable.
+
+1999-03-08 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * lib/gdb.exp: Doc fixes.
+
+1999-03-05 Nick Clifton <nickc@cygnus.com>
+
+ * gdb.base/a2-run.exp: Add expected fails for strongarm-coff.
+
+1999-03-04 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdb.base/display.exp: Don't exercise the "detach" and "kill"
+ commands. They're not germane to this test, and they don't work
+ that way on remote targets.
+
+1999-03-01 James Ingham <jingham@cygnus.com>
+
+ * Changelog entries merged over from gdb development branch.
+
+ Tue Jan 5 12:33:47 1999 Keith Seitz <keiths@cygnus.com>
+
+ * lib/gdb.exp (gdbtk_analyze_results): Generic function
+ for outputting results of test run.
+
+ 1998-12-07 Martin M. Hunt <hunt@cygnus.com>
+
+ * lib/gdb.exp (gdbtk_start): Fix path for itcl library.
+
+1999-02-25 Felix Lee <flee@cygnus.com>
+
+ * lib/gdb.exp (debug_format): initialize
+
+1999-02-25 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * gdb.base/call-ar-st.c: Include string.h, not strings.h.
+ * gdb.base/call-rt-st.c: Ditto.
+
+1999-02-13 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdb.threads/pthreads.exp (horiz): New variable.
+ (test_startup): Fix regexps that capture thread numbers.
+
+1999-02-10 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * gdb.base/smoke.exp: Disambiguate two test case names (both
+ called ``print'').
+
+Fri Feb 5 12:42:56 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/volatile.exp: Use gdb_test, add xfails for GCC
+ compilation.
+
+1999-02-04 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * gdb.base/miscexprs.exp: Change patterns to match GDB's
+ actual output formatting.
+ * gdb.base/smoke.exp: GDB removes leading 0's.
+ * gdb.base/volatile.exp: Don't check type of remuneration;
+ that variable is no longer defined in constvars.c.
+ * gdb.base/step-test.c (main): Exit with explicit exit code.
+ * gdb.base/step-test.exp: Remove two nexti checks--they are
+ not portable.
+
+1999-02-04 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * gdb.base/help.exp ("help delete display"): Fix test to match
+ gdb's output.
+
+ * gdb.base/long_long.c (known_types): Initialize values to zero.
+ * gdb.base/long_long.exp: Step one more line
+ so 'dec' is initialized in "get to known place". GDB removes
+ leading zeros. Explicitly ask for hex formatting. Use
+ unique test case names.
+
+Tue Feb 2 10:16:08 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * lib/gdb.exp (gdb_preprocess): Remove 'puts' statement.
+
+ * gdb.c++/method.exp: Add missing close brace.
+
+1999-01-30 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdb.base/maint.exp: Use 'set height 0' to disable page
+ prompting, not 'set height 400'.
+
+ Fix a bunch of timeouts.
+ * gdb.base/maint.exp ("maint print objfiles"): Break this up into
+ four separate tests, so expect doesn't take forever to match a ton
+ of text against a regexp with lots of .* forms.
+ ("maint print psymbols", "maint print symbols"): Make some of
+ these greps more selective, so that expect doesn't try to wade
+ through huge piles of output and time out.
+
+ * gdb.base/maint.exp ("maint print msymbols"): Fix pattern.
+
+ * gdb.base/maint.exp ("maint info breakpoints"): Split into two
+ tests: one which doesn't expect shlib events to be reported, and
+ another which does, but is XFAIL for all platforms other than
+ HP/UX.
+
+ * gdb.base/break.exp: Teach the test suite that the `catch
+ fork', `catch vfork', and `catch exec' commands produce error
+ messages on platforms that don't provide these features.
+
+Mon Jan 25 18:35:56 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.hp/gen-so-thresh.c, so-thresh.sh, so-thresh.exp,
+ so-thresh.linkopts, so-thresh.mk: Move to gdb.hp from gdb.base
+ (shortening names from solib_threshold.exp etc), won't run on
+ anything but HP-UX for the foreseeable future.
+ * gdb.hp/Makefile.in, gdb.base/Makefile.in (clean): Adjust to
+ reflect move.
+
+Thu Jan 21 15:46:49 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/Makefile.in, gdb.c++/Makefile.in,
+ gdb.trace/Makefile.in (clean): Remove all test executables.
+
+Tue Jan 19 17:20:09 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * gdb.base/shlib-call.exp: add test cases to verify that gdb
+ successfully re-sets breakpoints in shared libraries.
+ * gdb.base/shmain.c (main): return 0, don't fall off the end.
+
+Fri Jan 15 14:04:57 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.hp/xdb3.exp: do not execute unless on hppa-hpux platform
+ and compiled w/o GCC.
+
+ * gdb.hp/watch-cmd.exp: ditto.
+
+ * gdb.hp/watch-hp.exp: ditto.
+
+ * gdb.hp/xdb1.exp: ditto.
+
+ * gdb.hp/xdb2.exp: ditto.
+
+ * gdb.hp/dbx.exp: ditto.
+
+Thu Jan 14 18:36:48 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * constvars.c: Remove C++-isms.
+ * constvars.exp: Use gdb_test everywhere, add xfails if compiled
+ with GCC.
+
+Mon Jan 11 10:08:03 1999 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes are part of the HP merge.
+
+ * gdb.base/break.exp: new tests to verify that catchpoints for
+ fork, vfork, and exec don't trigger inappropriately.
+
+ * gdb.base/opaque.exp: compile one file at a time, then link.
+
+ * gdb.base/signals.exp: be more restrictive about which hppa
+ systems receive a setup_xfail. new tests.
+
+ * gdb.base/solib_threshold.build: new file.
+ * gdb.base/solib_threshold.exp: new file.
+ * gdb.base/solib_threshold.link_opts: new file.
+ * gdb.base/solib_threshold.mk: new file.
+ * gdb.base/gen_solib_threshold.c: new file.
+
+ * gdb.c++/classes.exp: if on HPUX and not using gcc, skip the
+ tests. New tests for enums inside classes.
+
+ * gdb.c++/compiler.cc: indicate support of template debugging.
+
+ * gdb.c++/demangle.exp: run hp style demangling tests.
+
+ * gdb.c++/inherit.exp: if on HPUX and not using gcc, skip the
+ tests.
+
+ * gdb.c++/misc.cc: changes to support new tests.
+
+ * gdb.c++/templates.cc: changes to support HP's compiler; changes
+ to support new tests.
+
+ * gdb.c++/virtfunc.exp: if we are on HPUX and we are not using
+ gcc, then skip these tests.
+
+Sun Jan 10 23:44:11 1999 David Taylor <taylor@texas.cygnus.com>
+
+ The following files are part of the HP merge; some had longer
+ names at HP, but have been renamed to be no more than 14
+ characters in length.
+
+ * gdb.hp/ambiguous.cc: new file.
+ * gdb.hp/ambiguous.exp: new file.
+ * gdb.hp/attach.exp: new file.
+ * gdb.hp/attach2.exp: new file.
+ * gdb.hp/classes-hp.exp: new file.
+ * gdb.hp/ctti.exp: new file.
+ * gdb.hp/ctti-add.cc: new file.
+ * gdb.hp/ctti-add1.cc: new file.
+ * gdb.hp/ctti-add2.cc: new file.
+ * gdb.hp/ctti-add3.cc: new file.
+ * gdb.hp/dbx.exp: new file.
+ * gdb.hp/exception.cc: new file.
+ * gdb.hp/exception.exp: new file.
+ * gdb.hp/foll-exec.c: new file.
+ * gdb.hp/foll-exec.exp: new file.
+ * gdb.hp/foll-fork.c: new file.
+ * gdb.hp/foll-fork.exp: new file.
+ * gdb.hp/foll-vfork.c: new file.
+ * gdb.hp/foll-vfork.exp: new file.
+ * gdb.hp/inherit-hp.exp: new file.
+ * gdb.hp/more-steps.exp: new file.
+ * gdb.hp/namespace.cc: new file.
+ * gdb.hp/namespace.exp: new file.
+ * gdb.hp/optimize.exp: new file.
+ * gdb.hp/pxdb.c: new file.
+ * gdb.hp/pxdb.exp: new file.
+ * gdb.hp/quicksort.exp: new file.
+ * gdb.hp/reg-test.exp: new file.
+ * gdb.hp/reg-test.s: new file.
+ * gdb.hp/sized-enum.c: new file.
+ * gdb.hp/sized-enum.exp: new file.
+ * gdb.hp/start-stop.exp: new file.
+ * gdb.hp/templ-hp.cc: new file.
+ * gdb.hp/templ-hp.exp: new file.
+ * gdb.hp/thr-lib.c: new file.
+ * gdb.hp/thr-lib.exp: new file.
+ * gdb.hp/thr-lib.h: new file.
+ * gdb.hp/thr-liblib.c: new file.
+ * gdb.hp/virtfun-hp.c: new file.
+ * gdb.hp/virtfun-hp.exp: new file.
+ * gdb.hp/watch-cmd.exp: new file.
+ * gdb.hp/watch-hp.exp: new file.
+ * gdb.hp/xdb1.exp: new file.
+ * gdb.hp/xdb2.exp: new file.
+ * gdb.hp/xdb3.exp: new file.
+
+Wed Jan 6 18:41:15 1999 David Taylor <taylor@texas.cygnus.com>
+
+ The following files are part of the HP merge; some had longer
+ names at HP, but have been renamed to be no more than 14
+ characters in length.
+
+ * gdb.base/ss.h: new file.
+ * gdb.base/call-ar-st.c: new file.
+ * gdb.base/call-ar-st.exp: new file.
+ * gdb.base/call-rt-st.c: new file.
+ * gdb.base/call-rt-st-exp: new file.
+ * gdb.base/call-strs.exp: new file.
+ * gdb.base/ena-dis-br.exp: new file.
+ * gdb.base/environ.exp: new file.
+ * gdb.base/long_long.exp: new file.
+ * gdb.base/sect-cmd.exp: new file.
+ * gdb.base/shlib-cl2.exp: new file.
+ * gdb.base/smoke.exp: new file.
+ * gdb.base/so-impl-ld.c: new file.
+ * gdb.base/so-impl-ld.exp: new file.
+ * gdb.base/so-indr-cl.c: new file.
+ * gdb.base/so-indr-cl.exp: new file.
+ * gdb.base/varargs.exp: new file.
+ * gdb.base/volatile.exp: new file.
+ * gdb.base/whatis-exp.exp: new file.
+ * gdb.base/display.exp: new file.
+ * gdb.c++/derivation.exp: new file.
+ * gdb.c++/local.exp: new file.
+ * gdb.c++/member-ptr.exp: new file.
+ * gdb.c++/overload.exp: new file.
+ * gdb.c++/ovldbreak.exp: new file.
+ * gdb.c++/ref-types.exp: new file.
+ * gdb.c++/ref-types2.exp: new file.
+ * gdb.c++/userdef.exp: new file.
+
+Wed Jan 6 13:50:57 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/default.exp: Reflect wording change in remote.c.
+
+Tue Jan 5 19:14:51 1999 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/help.exp: Update to reflect current text.
+
+Tue Jan 5 13:05:32 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * gdb.c++/anon-union.cc: make foo and bar global, otherwise
+ they're stack variables and contain garbage.
+ * gdb.c++/anon-union.exp: new file.
+
+ The following changes were made by David Taylor
+ <taylor@cygnus.com>, Elena Zannoni <ezannoni@cygnus.com>, and
+ Edith Epstein <eepstein@cygnus.com> as part of a project to merge
+ in changes by HP.
+
+ * gdb.base/bitops.exp: new file.
+ * gdb.base/default.exp: change expected messages for catch and
+ info catch tests to reflect HP merge changes.
+ * gdb.base/enable-disable-break.exp
+ * gdb.base/ending-run.c: new file.
+ * gdb.base/long_long.c: new file.
+ * gdb.base/maint.exp: new file.
+ * gdb.base/pointers2.exp: new file.
+ * gdb.base/shlib-call2.exp: new file.
+ * gdb.base/solib.exp: new file.
+ * gdb.base/step-test.c: new file.
+ * gdb.c++/anon-union.cc: new file.
+ * gdb.c++/local.cc: new file.
+ * gdb.c++/member-pointer.cc: new file.
+ * gdb.c++/method.cc: new file.
+ * gdb.c++/ref-types.cc: new file.
+ * gdb.c++/ref-types2.cc: new file.
+ * gdb.c++/userdef.cc: new file.
+
+ * gdb.base/scope.exp: compile one file at a time, then link.
+ * gdb.base/langs.exp: ditto.
+ * gdb.base/list.exp: ditto.
+
+Mon Jan 4 10:06:43 1999 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by David Taylor
+ <taylor@cygnus.com>, Elena Zannoni <ezannoni@cygnus.com>, and
+ Edith Epstein <eepstein@cygnus.com> as part of a project to merge
+ in changes by HP.
+
+ * gdb.c++/inherit.exp: if on hppa*-*-hpux* and not using gcc,
+ skip tests. When compiling pass c++ flag to gdb_compile.
+ * gdb.c++/
+
+ * lib/gdb.exp (get_compiler_info): new, optional argument -- args;
+ test for on hppa*-*-hpux*; use args to see if c++ was specified.
+ (skip_hp_tests): new function.
+ (gdb_preprocess): new function.
+
+ * configure.in (hpdir): decide whether to configure gdb.hp.
+ * configure: regenerated.
+
+ * gdb.base/Makefile.in (MISCELLANEOUS): new macros -- extra things
+ to delete on clean.
+ (EXECUTABLES): update to reflect new additions.
+ * gdb.base/commands.exp: update message expected.
+ * gdb.base/default.exp: add copyright notice.
+ * gdb.base/funcargs.exp (timeout): if hpux, increase timeout.
+ * gdb.base/help.exp: update messages to reflect current text.
+ * gdb.base/recurse.exp: add hpppa*-*-bsd* to 'list' of enabled
+ targets for recurse tests.
+ * gdb.base/watchpoint.exp: if on hpux and not gcc compiled, then
+ skip this file.
+
+ * gdb.c++/Makefile.in (PROGS): update to reflect new executables.
+ * gdb.c++/cplusfuncs.exp: tell gdb_compile that it's a c++
+ compilation.
+ * gdb.c++/misc.exp: ditto.
+ * gdb.c++/templates.exp: if we're on hpux and it's not gcc, don't
+ run the tests. tell gdb_compile that it's a c++ compilation.
+
+ * gdb.threads/pthreads.exp: fix typo in message.
+
+ * gdb.base/all-bin.exp: new file.
+ * gdb.base/arithmet.exp: new file.
+ * gdb.base/assign.exp: new file.
+ * gdb.base/completion.exp: new file.
+ * gdb.base/cond-expr.exp: new file.
+ * gdb.base/condbreak.exp: new file.
+ * gdb.base/define.exp: new file.
+ * gdb.base/dollar.exp: new file.
+ * gdb.base/environment.exp: new file.
+ * gdb.base/eval-skip.exp: new file.
+ * gdb.base/jump.exp: new file.
+ * gdb.base/logical.exp: new file.
+ * gdb.base/pointers.exp: new file.
+ * gdb.base/relational.exp: new file.
+ * gdb.base/section_command.exp: new file.
+ * gdb.base/whatis-expr.exp: new file.
+
+ * gdb.base/all-types.c: new file.
+ * gdb.base/call-array-struct.c: new file.
+ * gdb.base/call-return-struct.c: new file.
+ * gdb.base/call-strings.c: new file.
+ * gdb.base/callfuncs2.c: new file.
+ * gdb.base/condbreak.c: new file.
+ * gdb.base/constvars.c: new file.
+ * gdb.base/display.c: new file.
+ * gdb.base/int-type.c: new file.
+ * gdb.base/jump.c: new file.
+ * gdb.base/miscexprs.c: new file.
+ * gdb.base/pointers.c: new file.
+ * gdb.base/pointers2.c: new file.
+ * gdb.base/shmain.c: new file.
+ * gdb.base/shr1.c: new file.
+ * gdb.base/shr2.c: new file.
+ * gdb.base/solib.c: new file.
+ * gdb.base/solib1.c: new file.
+ * gdb.base/solib2.c: new file.
+ * gdb.base/varargs.c: new file.
+ * gdb.c++/derivation.cc: new file.
+ * gdb.c++/overload.cc: new file.
+ * gdb.c++/ovldbreak.cc: new file.
+ * gdb.hp/attach.c: new file.
+ * gdb.hp/attach2.c: new file.
+ * gdb.hp/average.c: new file.
+ * gdb.hp/compiler.c: new file.
+ * gdb.hp/compiler.cc: new file.
+ * gdb.hp/execd-program.c: new file.
+ * gdb.hp/follow-exec.c: new file.
+ * gdb.hp/follow-fork.c: new file.
+ * gdb.hp/follow-vfork-and-exec.c: new file.
+ * gdb.hp/misc-hp.cc: new file.
+ * gdb.hp/more-steps.c: new file.
+ * gdb.hp/optimize.c: new file.
+ * gdb.hp/quicksort.c: new file.
+ * gdb.hp/run-hp.c: new file.
+ * gdb.hp/start-stop.c: new file.
+ * gdb.hp/sum.c: new file.
+ * gdb.hp/templates-hp.cc: new file.
+ * gdb.hp/thread-local-in-lib.c: new file.
+ * gdb.hp/thread-local-in-lib.h: new file.
+ * gdb.hp/thread-local-in-lib.lib.c: new file.
+ * gdb.hp/vforked-program.c: new file.
+ * gdb.hp/virtfunc-hp.cc: new file.
+ * gdb.hp/watchpoint-hp.c: new file.
+ * gdb.hp/xdb.c: new file.
+ * gdb.hp/xdb0.c: new file.
+ * gdb.hp/xdb0.h: new file.
+ * gdb.hp/xdb1.c: new file.
+
+Mon Dec 21 14:08:38 1998 David Taylor <taylor@texas.cygnus.com>
+
+ The following change was made by Edith Epstein
+ <eepstein@cygnus.com> as part of a project to merge in changes
+ originally made by HP; HP did not create ChangeLog entries.
+
+ * gdb.c++/demangle.exp: changed the expected output for some
+ ARM-style mangling -- removed second reference to datatype.
+ For example, maint demangle __dt__11T1__pt__2_cFv
+ T1<char>::~T1<char>(void)
+ becomes,
+ maint demangle __dt__11T1__pt__2_cFv
+ T1<char>::~T1(void)
+
+ (test_hp_style_demangling): new hp specific demangling test cases.
+
+Mon Dec 14 15:07:03 1998 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.trace/actions.exp: Ignore compiler warnings compiling actions.c
+ * gdb.trace/backtrace.exp: Likewise.
+ * gdb.trace/circ.exp: Likewise.
+ * gdb.trace/collection.exp: Likewise.
+ * gdb.trace/deltrace.exp: Likewise.
+ * gdb.trace/infotrace.exp: Likewise.
+ * gdb.trace/limits.exp: Likewise.
+ * gdb.trace/packetlen.exp: Likewise.
+ * gdb.trace/passc-dyn.exp: Likewise.
+ * gdb.trace/passcount.exp: Likewise.
+ * gdb.trace/report.exp: Likewise.
+ * gdb.trace/save-trace.exp: Likewise.
+ * gdb.trace/tfind.exp: Likewise.
+ * gdb.trace/tracecmd.exp: Likewise.
+ * gdb.trace/while-dyn.exp: Likewise.
+ * gdb.trace/while-stepping.exp: Likewise.
+
+1998-12-07 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gdb.base/restore.exp, gdb.base/restore.c: New tests.
+
+Wed Dec 2 20:03:53 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Brendan Kehoe:
+ * gdb.c++/cplusfuncs.cc, misc.cc, virtfunc.cc: Add now-required
+ int return types.
+
+Sat Oct 24 18:04:22 1998 Felix Lee <flee@cygnus.com>
+
+ * config/slite.exp (gdb_load): use gdb_file_cmd, so we can do
+ remote dos host testing right.
+
+Mon Oct 19 01:31:59 1998 Felix Lee <flee@cygnus.com>
+
+ * gdb.base/corefile.exp: remove some xfails.
+
+Thu Oct 15 10:04:38 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/reread.exp: Sleep 1 - ensures that the two executables
+ have different timestamps.
+
+Thu Oct 1 20:56:14 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdb.exp, gdb.base/default.exp, config/monitor.exp,
+ gdb.base/default.exp: Replace "exec" with "executable".
+
+Tue Sep 29 15:06:29 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/default.exp: Change else if to elseif from previous
+ delta.
+
+Mon Sep 28 13:21:43 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gdb.base/default.exp: Add brace missing from previous delta.
+
+Mon Sep 21 14:39:27 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gdb.base/default.exp: Support test for info float for all
+ varieties of arm toolchain.
+
+Fri Sep 18 14:07:44 1998 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.trace/*.exp: remove "remote_download" command.
+
+Wed Sep 16 11:38:21 1998 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.trace/*.exp: remove -gdwarf from compile.
+
+Wed Sep 16 01:23:11 1998 Felix Lee <flee@cygnus.com>
+
+ * gdb.trace/configure.in(AC_INIT): typo
+ * gdb.trace/configure: regenerated
+
+Mon Sep 14 20:00:04 1998 Michael Snyder <msnyder@cygnus.com>
+
+ * config/m68k-emc.exp: New file.
+ * lib/<emc-support.exp trace-support.exp}: New files.
+ * configure.in: add new test directory gdb.trace.
+ * gdb.trace/{configure configure.in Makefile.in}: New files.
+ * gdb.trace/{actions.c actions.exp gdb_c_test.c}: New files.
+ * gdb.trace/{circ.c circ.exp limits.c limits.exp}: New files.
+ * gdb.trace/{collection.c collection.exp tfind.exp }: New files.
+ * gdb.trace/{backtrace.exp deltrace.exp infotrace.exp}: New files.
+ * gdb.trace/{packetlen.exp passc-dyn.exp passcount.exp}: New files.
+ * gdb.trace/{report.exp save-trace.exp tracecmd.exp}: New files.
+ * gdb.trace/{while-dyn.exp while-stepping.exp}: New files.
+
+Fri Sep 11 13:58:02 1998 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.c++/classes.exp: Change all regular expressions to match
+ arbitrary combinations of newline/carriage-return, so that they
+ will work equally well on Unix and Windows.
+ * gdb.c++/inherit.exp: ditto.
+ * gdb.c++/virtfunc.exp: ditto.
+
+1998-08-11 Dawn Perchik <dawn@cygnus.com>
+
+ * gdb.base/setshow.exp: Fix error introduced by call to runto_main.
+
+Fri Jul 24 15:51:34 1998 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.disasm/am33.s: Add tests for autoincrement instructions.
+ * gdb.disasm/am33.exp: Run time. Update tests which use r8-r15
+ to use a0-a3/d0-d3 as needed.
+
+Thu Jul 16 18:20:46 1998 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.disasm/am33.s: Add 4 operand mul and mulu tests.
+ * gdb.disasm/am33.exp: Corresponding changes.
+
+1998-07-11 Felix Lee <flee@cygnus.com>
+
+ * gdb.base/callfuncs.exp: add cmp10 test.
+ * gdb.base/callfuncs.c (cmp10): new function.
+
+Thurs Jul 9 11:08:31 1998 Dawn Perchik <dawn@cygnus.com>
+
+ * gdb.base/commands.exp: Break up infrun_breakpoint_command_test
+ into two parts to get around a synchronization problem in expect.
+
+Fri Jun 26 14:27:13 1998 Keith Seitz <keiths@cygnus.com>
+
+ * lib/gdb.exp (gdbtk_start): Add startup for gdbtk.
+
+ * configure.in: Add options for gdbtk testsuite.
+
+ * configure: Regenerate.
+
+ * gdb.gdbtk: New directory to hold gdbtk tests.
+
+Fri Jun 26 14:52:47 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * gdb.fortran/types.exp: Escape brackets in expect patterns
+ for test_float_literal_types_accepted tests.
+ * gdb.base/scope.exp: Remove extraneous newline in filelocal_bss
+ before run test.
+
+Fri Jun 26 11:12:17 1998 Jeffrey A Law (law@cygnus.com)
+
+ * am33.exp: Just compile, do not link the testcase.
+ * am33.s: Add ".am33" pseudoop to force am33 mode.
+
+1998-06-25 Felix Lee <flee@cygnus.com>
+
+ * gdb.base/setshow.exp: make sure $pc is sane.
+
+ * gdb.stabs/weird.exp: split expect patterns properly.
+
+Wed Jun 24 13:03:15 1998 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.disasm/am33.s: New disassembler testfile for the am33.
+ * gdb.disasm/am33.exp: Run it.
+
+Tue Jun 23 11:45:01 1998 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/funcargs.exp: simplify expect strings to ease pattern
+ match processing (and eliminate spurious timeouts when running).
+
+Fri Jun 12 17:28:22 1998 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/signals.exp (test_handle_all_print): put back Mach
+ exception test, but conditionalize it on target [mach | gnu].
+
+Wed Jun 10 10:40:03 1998 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/overlays.exp: fixup compile line for linker script.
+
+Thu Jun 4 21:54:15 1998 Felix Lee <flee@zog.cygnus.com>
+
+ * gdb.fortran/types.exp: don't guess at float size.
+
+Thu May 21 02:28:37 1998 Felix Lee <flee@zog.cygnus.com>
+
+ * gdb.base/exprs.exp: delete test that depends on int size.
+
+Sun May 17 17:10:22 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/sim.exp: Removed checks for target triplets.
+ (gdb_target_sim): Use gdb,target_sim_options.
+
+Sat May 16 23:43:35 1998 Mark Alexander <marka@cygnus.com>
+
+ * gdb.base/reread.exp: New file.
+ * gdb.base/reread1.c: New file.
+ * gdb.base/reread2.c: New file.
+
+Sat May 16 23:22:09 1998 Mark Alexander <marka@cygnus.com>
+
+ * config/sim.exp: Use 'target sim -sparclite' when running
+ SPARClite programs.
+
+Sat May 16 18:48:08 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * gdb.base/structs2.exp: New file.
+ * gdb.base/structs2.c: New file.
+
+Wed May 13 13:36:14 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * gdb.asm/common.inc: New file.
+ * gdb.asm/d10v.inc: New file.
+ * asm-source.exp: Pass -I's to gas to find .inc files.
+ Update line numbers in expected output.
+ * asmsrc1.s: Rewrite.
+ * asmsrc2.s: Rewrite.
+ * configure.in: Create arch.inc symlink.
+ * configure: Regenerate.
+ * Makefile.in (distclean): Delete arch.inc.
+
+Wed May 6 10:30:54 1998 John Metzler <jmetzler@cygnus.com>
+
+ * callfuncs.c (t_enum_value1) : Cleanup return value warnings
+ (t_enum_value2): ditto
+ (t_enum_value3): ditto
+ (main): ditto
+Fri May 1 09:33:37 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * gdb.base/break.exp: Remove xfail for `deleting all breakpoints
+ when none' unexpected prompt case, fixed by breakpoint.c:delete_command
+ change.
+ Use gdb_test instead of send_gdb/gdb_expect sequences.
+
+Thu Apr 23 12:56:19 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * gdb.c++/virtfunc.cc: Declare extern "C" printf to return int,
+ not void.
+
+Thu Apr 16 10:52:34 1998 John Metzler <jmetzler@cygnus.com>
+
+ * gdb.base/branches.c: Code with lots of loops and
+ subroutines. Used to test gdbs ability to single step through PC
+ changes, especially to test mips-tdep.c:mips_next_pc
+
+Mon Apr 13 22:32:51 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * gdb.c++/virtfunc.cc: Make extern "C" printf declaration pass
+ more rigorous EGCS C++ error checking.
+
+Fri Apr 10 22:38:12 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/help.exp: Clean up `help set args' and `help show args'
+ tests.
+ * gdb.base/interrupt.exp: Add "i*86-*-solaris2*" xfail for calling
+ function when asleep.
+ * gdb.base/signals.exp: Add "i*86-*-solaris2*" xfails. Add comment
+ for i*86 Linux and SVR4 signal handling problems.
+ Remove linux xfail for `next to handler in signals_tests_1', fixed
+ by recent infrun.c change.
+ Limit backtrace to 10 frames to avoid timeout problems with infinite
+ stack backtraces.
+ Adjust expect pattern in `handle all print' test to match Apr 28 1997
+ target.[ch] change.
+
+Tue Mar 31 00:40:32 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gdb.exp(gdb_test): Send multiline commands one at a time; wait
+ for a newline from gdb before continuing.
+ (default_gdb_exit): Just look for y or n.
+ (gdb_test): Detect abnormal exit from GDB running on DOS; if
+ it does, fail the rests of the tests in the file.
+
+Tue Mar 24 22:44:52 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/cygmon.exp: New file.
+
+Mon Mar 16 21:39:11 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/list.exp: Fix problem with "list default lines around
+ main" test on remote targets.
+
+ * gdb.base/scope.exp: Fix problem with filelocal_bss before
+ run test on remote targets.
+
+Thu Mar 12 16:23:00 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * gdb.asm: New directory.
+ * configure.in: Configure it.
+ * configure: Regenerate.
+ * gdb.asm/{Makefile.in,configure.in,configure}: New files.
+ * gdb.asm/{asm-source.exp,asmsrc1.s,asmsrc2.s}: New files.
+
+Mon Feb 23 08:22:44 1998 Mark Alexander <marka@cygnus.com>
+
+ * config/mn10300-eval.exp: New file to support MN10300 eval board.
+
+Wed Feb 18 16:43:46 1998 Michael Snyder (msnyder@cygnus.com)
+
+ * gdb.base/overlays (several files): Merge the two overlay
+ managers into one. Change variables (foox, barx, bazx, grbxx)
+ back into ints but force them to load in their proper sections.
+
+Thu Feb 12 13:49:30 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/d10vovly.c (D10VTranslate): Map IMAP0 to low 128k of
+ on-chip insn memory and IMAP1 to upper 128k.
+ (D10VCopy): Handle memory regions crossing 16k boundaries.
+ (D10VCopy): Transfer data in 32 bit chunks.
+
+Tue Feb 10 17:23:22 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/overlays.c (main): Exit normally when result is
+ correct.
+
+ * gdb.base/d10v.ld: Update LMAs to reflect current d10v address
+ map. Include space for printf in .text segment.
+
+ * gdb.base/d10vovly.c (D10VTranslate): New function, handle
+ updated d10v memory VMA/LMA map.
+ (D10VCopy): Call D10VTranslate.
+
+Fri Feb 6 14:13:12 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/m32rovly.c: Force variable _novlys into .data section.
+
+ * gdb.base/bar.c (barx, bar): Change variable to small array so
+ that it won't be put into the .sdata - small data -
+ section. Update reference.
+ * gdb.base/baz.c (bazx, baz): Ditto.
+ * gdb.base/foo.c (foox, foo): Ditto.
+ * gdb.base/grbx.c (grbxx, grbx): Ditto.
+
+ * gdb.base/overlays.exp: Expect variables barx, bazx, foox, grbxx
+ to be arrays.
+
+Thu Jan 29 14:48:19 1998 Michael Snyder (msnyder@cygnus.com)
+
+ * gdb.base/overlays.exp: fix up and get working again.
+ Add tests for backtraces from an overlay function.
+
+Fri Jan 23 07:52:45 1998 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/watchpoint.exp: Set "d10v*-*-*" clear_xfail for
+ "calling function with watchpoint enabled".
+
+Thu Jan 22 14:23:29 1998 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/break.exp (test_next_with_recursion): Remove
+ gdb_suppress_tests for d10v-*-*.
+ * lib/gdb.exp (gdb_suppress_tests): Disable this function
+ pending review of whether it is useful or not.
+
+Tue Jan 20 13:02:09 1998 Mark Alexander <marka@cygnus.com>
+
+ * gdb.base/funcargs.exp: Increase timeout for slow TX39 boards.
+
+Mon Jan 19 08:53:04 1998 Mark Alexander <marka@cygnus.com>
+
+ * gdb.base/break.exp: Increase timeout for slow TX39 boards.
+ * config/dve.exp: New file to support Densan boards.
+
+Mon Dec 15 22:38:05 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/interrupt.exp: Document problem of simulators, signals,
+ reads and BSD.
+
+Wed Nov 26 22:29:18 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/monitor.exp: Be a bit less picky about the "Remote debugging"
+ response.
+
+ * gdb.c++/misc.exp: Call runto_main instead of doint it manually.
+
+Tue Nov 25 12:46:36 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/mips_pro.exp: Add "mips64*-*-elf" xfail for backtrace
+ test.
+
+ * gdb.base/funcargs.exp: Query GDB for target_sizeof_int,
+ target_sizeof_long and target_bigendian_p.
+ (structs_by_value, structs_by_reference): Check values according
+ to targets word size and endianess.
+
+Mon Nov 24 16:37:06 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.base/langs.exp: For "continue to exit" ignore any trailing
+ output.
+
+Fri Oct 17 13:24:43 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/default.exp, gdb.base/help.exp, gdb.base/setshow.exp:
+ Update test of set args help to match source change.
+
+Fri Sep 26 17:36:20 1997 Jason Molenda (crash@pern.cygnus.com)
+
+ * gdb.base/default.exp: Expect help system output to be in
+ alphabetical order.
+ * gdb.base/help.exp: Ditto.
+
+Wed Sep 24 13:08:14 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/signals.exp: Change "i*86-pc-linux-gnu" to
+ "i*86-pc-linux-gnu*".
+ * gdb.base/interrupt.exp: Ditto.
+ * gdb.base/corefile.exp: Ditto.
+
+ * lib/gdb.exp(gdb_compile): If is_vxworks target feature is set,
+ define vxworks when building the testcase.
+
+ * gdb.base/ptype.exp: Fix testnames to be unique.
+ * gdb.base/radix.exp: Ditto.
+ * gdb.base/term.exp: Ditto.
+ * gdb.base/whatis.exp: Ditto.
+ * gdb.c++/classes.exp: Ditto.
+
+Tue Sep 16 22:21:48 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/callfuncs.exp: Fix indentation.
+
+ * lib/gdb.exp(gdb_expect): Set remote_suppress_flag if
+ suppress_flag has been set.
+ (gdb_step_for_stub): Check for gdb,use_breakpoint_for_stub
+ target feature.
+
+Mon Sep 15 15:43:17 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.stabs/weird.exp: Don't start gdb 'til after we've compiled
+ the testcase.
+
+ * gdb.c++/cplusfuncs.cc(main): Add extern "C" declaration for
+ set_debug_traps() and breakpoint().
+ * gdb.c++/misc.cc (main): Ditto.
+ * gdb.c++/templates.cc (main): Ditto.
+ * gdb.c++/virtfunc.cc (main): Ditto.
+
+Fri Sep 12 16:56:38 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gdb.exp(gdb_step_for_stub): New function.
+ (gdb_run_cmd): Look for gdb,do_reload_on_run target feature--if it
+ exists, reload the executable and do a "continue" instead of
+ doing a jump.
+ (runto_main): Use gdb_step_for_stub.
+
+ * gdb.base/break.exp: Use gdb_step_for_stub. Also, rename certain
+ tests to have unique names.
+ * gdb.base/callfuncs.exp: Ditto.
+ * gdb.base/commands.exp: Ditto.
+ * gdb.base/default.exp: Ditto.
+ * gdb.base/help.exp: Ditto.
+ * gdb.base/list.exp: Ditto.
+ * gdb.base/opaque.exp: Ditto.
+ * gdb.base/printcmds.exp: Ditto. Use a loop to emit multiple
+ similar tests.
+
+ * gdb.base/setshow.c: Add set_debug_traps/breakpoint calls.
+ * gdb.c++/cplusfuncs.cc: Ditto.
+ * gdb.c++/virtfunc.cc: Ditto.
+
+ * config/monitor.exp: Keep track of the last file we saw, rather
+ than trying to get the info from gdb.
+
+ * gdb.fortran/types.exp: Move comment to previous line.
+
+Tue Sep 2 19:55:34 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/sparclet.exp: Detect gratuitous change to sparclet gdb
+ target mode.
+
+Mon Jul 28 12:14:47 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Bob Manson:
+ * config/monitor.exp (gdb_target_monitor): Look for "Connected to"
+ string from GDB when it connects.
+
+ * lib/gdb.exp: Look for $TOOL_EXECUTABLE.
+
+Thu Jul 3 15:35:12 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gdb.exp(get_debug_format): Don't cause the testsuite to fail
+ if we can't get a debug format from GDB (we may be testing an
+ older GDB). Use a 10 second timeout when checking for the format.
+
+ * gdb.stabs/weird.exp: Fix quoting.
+
+ * config/sparclet.exp: Renamed sparclet-loader.c to stub-loader.c.
+
+Mon Jun 30 18:31:43 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/arm-ice.exp: New file.
+
+Sun Jun 29 16:43:30 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/overlays.exp: Preliminary fixes; temporarily disabled
+ until it has been modified to work with the new testsuite.
+
+ * gdb.*/*.exp: Instead of causing 1 unresolved test when the
+ testcase won't compile, cause all of the testcases in the file to
+ fail instead.
+
+ * lib/gdb.exp(gdb_suppress_entire_file): New procedure.
+ (gdb_clear_suppressed): New procedure.
+ (gdb_stop_suppressing_tests): Only clear suppress_flag if
+ it contains a positive value.
+
+Sat Jun 28 13:31:11 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gdb.exp(default_gdb_start): Use gdb_opts host feature.
+
+ * gdb.c++/virtfunc.exp: Remove setting of libs variable.
+
+Fri Jun 27 07:44:25 1997 Fred Fish <fnf@cygnus.com>
+
+ * lib/gdb.exp (setup_xfail_format): New function.
+ (get_debug_format): New function to get debug format.
+ (debug_format): New global variable to hold last value set
+ by get_debug_format.
+ * gdb.base/list.exp: Call get_debug_format and expect some
+ tests to fail for DWARF 1 and COFF formats.
+ * gdb.c++/ptype.exp: Ditto.
+ * gdb.c++/classes.exp: Ditto.
+ * gdb.c++/cplusfuncs.exp: Ditto.
+ * gdb.c++/inherit.exp: Ditto.
+ * gdb.c++/templates.exp: Ditto.
+ * gdb.c++/virtfunc.exp: Ditto.
+
+Wed Jun 25 09:08:51 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gdb.exp(default_gdb_exit): Don't give an error if the remote
+ host doesn't have a currently-open connection.
+
+ * config/sparclet.exp: Cleanups and fixes to make it generic for
+ any gdb stub target. Handle cases where gdb doesn't respond when
+ interrupted in a sane fashion.
+
+ * config/m32r-stub.exp: Load sparclet.exp instead of trying to do the
+ same thing in a totally different way.
+
+ * config/monitor.exp: Pass in timeouts to gdb_expect instead of
+ setting "timeout".
+ (gdb_start): We set the global gdb_prompt variable in
+ default_gdb_init now.
+
+Sun Jun 22 09:11:02 1997 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/printcmds.exp: Fix "check for floating addition"
+ regexp to accept results within approx +/- .01 of exact value.
+ * lib/gdb.exp (gdb_test): Remove unused expect_out global decl.
+
+Wed Jun 18 11:11:39 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gdb.exp(gdb_init): Pass our arguments to default_gdb_init
+ properly.
+ (gdb_expect): Add optional timeout parameter, and add timeout
+ value to various calls.
+ (gdb_suppress_tests): Only give one warning message per group.
+
+Tue Jun 17 13:10:10 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gdb.exp(gdb_expect): Declare errorInfo and errorCode as
+ global variables. Handle getting a value for $timeout more
+ gracefully.
+
+Sat Jun 14 09:23:26 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gdb.exp: Close connection to remote host if gdb doesn't
+ initialize.
+ (default_gdb_init): New procedure; allow gdb_init to be overridden
+ by a target configuration file.
+ (gdb_expect): Pass the timeout to remote_expect.
+
+ * config/monitor.exp(gdb_load): Fix typo in regexp.
+
+Thu Jun 12 20:57:12 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/funcargs.exp: Remove spurious suppress tests call.
+
+Tue Jun 3 15:20:20 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/monitor.exp(gdb_target_monitor): Call gdb_file_cmd
+ here. Call gdb_target_exec before rebooting the target, to make
+ sure the connection to the target is closed.
+ (gdb_load): Pass the name of the executable to gdb_target_monitor.
+ Don't call gdb_file_cmd here; let gdb_target_monitor do it.
+ Also detect "Timeout reading from remote" error.
+
+ * config/gdbserver.exp: Pass the executable being loaded to
+ gdb_target_monitor. Don't call gdb_file_cmd here; let
+ gdb_target_monitor do it.
+
+ * gdb.disasm/hppa.exp: Don't use exec_output.
+
+Fri May 23 13:28:29 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/list.exp: If we're debugging a non-native target,
+ try to set the pc register to point to the start of the
+ program before doing the first list command.
+
+ * gdb.c++/virtfunc.exp(gdb_virtfunc_restart): Make sure we run
+ test_calls after restarting.
+
+ * lib/gdb.exp(gdb_run_cmd): Send jump command again after
+ reloading.
+
+ * gdb.base/watchpoint.exp: Fix typo.
+
+ * gdb.base/setshow.exp: Check for use_gdb_stub.
+
+ * gdb.base/break.exp: Fix continue until exit test for the gdb
+ stub case.
+ * gdb.base/langs.exp: Ditto.
+
+ * config/monitor.exp(gdb_load): Handle gdb_sect_offset and
+ gdb_load_offset. If we weren't given a file to load, figure out
+ what the current file is and use it.
+
+ * config/i386-bozo.exp: New file.
+
+Thu May 22 18:51:32 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gdb.exp(gdb_expect): Look for gdb,timeout target
+ feature.
+
+ * config/proelf.exp: New entry.
+
+Wed May 21 21:23:16 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gdb.exp: Remove spurious .* patterns at the beginning
+ of regexps.
+
+ * gdb.base/watchpoint.exp: Don't run the test_stepping
+ tests if gdb can't call functions on the target.
+
+ * gdb.base/setshow.exp: Don't run the set prompt tests if
+ the board has gdb_prompt set.
+
+Tue May 20 08:58:49 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/a2-run.exp: Change "gdb,noargs" to just "noargs".
+ * gdb.base/commands.exp: Likewise.
+ * gdb.base/setshow.exp: Likewise.
+
+Mon May 19 15:37:50 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/monitor.exp(gdb_start): Look for gdb_prompt target
+ feature.
+
+ * config/i960.exp: New file.
+
+Thu May 1 18:01:50 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/funcargs.exp: Check for gdb,short_int target
+ feature instead of looking for explicit target triplets.
+
+Mon Apr 28 17:27:40 1997 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/printcmds.exp: add a couple more tests a la
+ "p 123DEADBEEF", to check parse_number.
+ * top.c: change "to enable to enable" to "to enable" in a couple
+ of help strings.
+
+Thu Apr 24 14:38:18 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/callfuncs.exp: Mark some tests as expected to fail
+ on the mn10300.
+
+Mon Apr 21 15:05:42 1997 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/a2-run.exp: Add arm-*-coff setup_xfails for cases
+ where the test executable is run with explicit args.
+ * gdb.base/default.exp: Handle arm-*-coff case for "info float".
+
+Mon Apr 21 13:38:58 1997 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/run.c: Use FAKEARGV to build test executable that
+ does not require a command line arg, since most simulators
+ don't currently support passing such an arg into the simulated
+ program.
+ * gdb.base/commands.exp: Change tests to insert the proper
+ value as the arg to the first recursive factorial call. Change
+ compilation line to define FAKEARGV at compile time.
+
+Wed Apr 9 11:12:36 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/recurse.exp: Enable these tests for the mn10300.
+ * gdb.base/watchpoint.exp: Don't expect a failure for an "calling
+ function with watchpoint enabled" test.
+
+Tue Apr 8 19:33:20 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/watchpoint.exp(test_watchpoint_triggered_in_syscall):
+ Don't call gdb_test when the command doesn't return to a gdb prompt.
+
+ * lib/gdb.exp(gdb_stop_suppressing_tests): Don't print gratuitous
+ "Tests restarted" messages.
+
+Tue Apr 8 16:38:46 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.disasm/mn10300.exp: Fix buglets in "other" tests.
+
+Thu Apr 3 15:21:26 1997 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/help.exp: update help msg for INFO ADDR; add help test
+ for INFO SYMBOL; add help tests for OVERLAY commands.
+ * gdb.base/default.exp: add tests for INFO SYMBOL command;
+ add tests for OVERLAY commands
+ * gdb.base/overlays.c overlays.exp foo.c bar.c baz.c grbx.c ovlymgr.h
+ d10v.ld m32r.ld d10vovly.c m32rovly.c: add test case for overlays.
+ * gdb.base/sigall.c: add usestubs code frag
+ * gdb.base/watchpoint.exp: turn on complex watchpoint test for M32R.
+
+Thu Apr 3 09:38:53 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gdb.exp(gdb_suppress_tests): Add explanation for subsequent
+ failures.
+ (gdb_stop_suppressing_tests): Note that tests have restarted.
+
+Wed Apr 2 19:04:20 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/h8300.exp: New file.
+
+Sun Mar 30 13:38:25 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/setshow.exp: Check for the existence of a
+ feature, not its value.
+
+Sat Mar 29 11:19:46 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.c++/virtfunc.exp: Restart gdb in a sane fashion.
+
+ * gdb.base/scope.exp: It's now init0(), not init().
+
+ * gdb.base/scope0.c: For now, change init() to be init0().
+
+ * config/monitor.exp: Use gdb_serial in preference to serial
+ or netport.
+
+ * lib/gdb.exp: Set GDB to [transform gdb] if we're using a remote host
+ and it's not already set.
+
+Fri Mar 28 19:54:18 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/setshow.exp: Only test the run command if the target
+ isn't using a stub and if it supports argument passing.
+
+Sat Mar 22 19:50:25 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/udi.exp(gdb_start): Make sure UDICONF is set
+ properly before starting gdb.
+
+Mon Mar 24 14:40:33 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.disasm/mn10300.s: New test file for mn10300 disassembler.
+ * gdb.disasm/mn10300.exp: Run mn10300 disassembler tests.
+ * gdb.disasm/Makefile.in: Remove "mn10300" when cleaning.
+
+Tue Mar 11 11:42:58 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/vx.exp: Use remote_ld, not vxworks_ld. Don't use
+ specialized code to reboot the board, use remote_reboot instead.
+
+ * config/vxworks29k.exp: Use vx.exp, not vx-gdb.exp.
+
+ * lib/gdb.exp: Add GDB_TESTCASE_OPTIONS.
+
+ * config/monitor.exp: Make sure we disconnect from the target.
+ Also, try a reboot/reload cycle instead of failing if the
+ load fails.
+
+Fri Mar 7 13:48:30 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/default.exp: Don't set match_max.
+ * gdb.base/help.exp: Ditto.
+ * gdb.base/list.exp: Ditto.
+ * gdb.base/signals.exp: Ditto.
+
+ * config/monitor.exp(gdb_load): If gdb,use_standard_load is
+ set, use remote_ld to download the testcase instead of
+ the GDB loader.
+
+Wed Mar 5 00:00:43 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/vr5000.exp: New file.
+
+ * config/monitor.exp(gdb_target_monitor): Add pattern for
+ "Ending remote" to detect errors in connecting.
+
+ * gdb.base/setshow.exp: Add .* within auto language test.
+
+ * lib/gdb.exp(gdb_run_cmd): Add check for gdb_init_command
+ target feature.
+
+ * config/monitor.exp(gdb_load): Check for a failure when loading,
+ and reboot the board if necessary.
+
+ * gdb.base/setvar.exp(test_set): Handle multiple prints within
+ a set of tests. Remove print.* from the patterns being checked.
+
+Mon Mar 3 11:57:43 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/a1-selftest.exp: Use send_gdb consistently. Don't
+ refer to gdb_spawn_id.
+
+ * config/m32r-stub.exp: Remove references to gdb_spawn_id, no
+ longer used.
+ * config/sparclet.exp: Ditto.
+ * config/sparclet-old.exp: Ditto.
+ * config/slite.exp: Ditto.
+ * config/sim.exp: Ditto.
+ * gdb.base/funcargs.exp: Ditto.
+
+ * lib/gdb.exp:Remove references to gdb_spawn_id.
+ (gdb_expect): Move to remote.exp.
+
+Fri Feb 28 20:47:39 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/monitor.exp: Detect the "Couldn't establish connection"
+ message from GDB.
+
+Tue Feb 25 14:08:55 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/bitfields.exp: Use runto instead of explicit
+ gdb_run_cmd/gdb_expect sequences.
+
+ * gdb.base/break.exp(text_next_with_recursion): Add match for
+ gdb_expect call.
+
+ * config/monitor.exp(gdb_target_monitor): Calling exit loses big.
+ We also need to handle the "A program is being debugged already"
+ prompt from gdb. Use gdb_test to set the baud rate.
+
+ * lib/gdb.exp(gdb_init): Increase the default expect buffer size
+ to 20000. Really. I mean it.
+
+Mon Feb 24 13:23:26 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gdb.exp(gdb_test): Generate a FAIL message when send_gdb
+ fails. If suppress_flag is set, skip perror message about not
+ being able to send to GDB.
+ (send_gdb): If suppress_flag is set, don't try to send commands to
+ GDB.
+ (gdb_expect): If suppress_flag is set, always fail immediately.
+ (gdb_suppress_tests, gdb_stop_suppressing_tests): New functions.
+ (gdb_init): Call gdb_stop_suppressing_tests.
+ (default_gdb_exit): Ditto.
+ (default_gdb_start): Ditto.
+
+ * gdb.base/bitfields.exp: Call gdb_suppress_tests and
+ gdb_stop_suppressing_tests as appropriate.
+ * gdb.base/break.exp: Ditto.
+ * gdb.base/callfuncs.exp: Ditto.
+ * gdb.base/commands.exp: Ditto.
+ * gdb.base/exprs.exp: Ditto.
+ * gdb.base/funcargs.exp: Ditto.
+ * gdb.base/list.exp: Ditto.
+ * gdb.base/recurse.exp: Ditto.
+ * gdb.base/scope.exp: Ditto.
+ * gdb.base/structs.exp: Ditto.
+ * gdb.c++/inherit.exp: Ditto.
+
+Sun Feb 23 19:56:02 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/vr4300.exp: New file.
+
+ * gdb.*/*.exp: Call gdb_expect instead of expect.
+
+ * lib/gdb.exp(gdb_expect): New function.
+
+Thu Feb 20 13:57:01 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gdb.exp(gdb_init): New function.
+
+ * gdb.base/setvar.exp(test_set): Don't bother printing a PASS/FAIL
+ for each individual variable set.
+
+ * gdb.base/exprs.exp(test_expr): Make sure each test gets a unique
+ name.
+
+ * gdb.base/help.exp: Fix the syntax of a few gdb_test calls.
+
+ * gdb.base/scope.exp: Use gdb_test.
+
+ * gdb.base/ptype.exp: Don't call "gdb_exit; gdb_start" if we're
+ aborting; the testsuite driver will do that for us (see
+ gdb_finish). Also, use gdb_test in a few more places.
+
+Thu Feb 20 13:32:24 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/help.exp: Fix syntax of "help info all-registers" test.
+
+Thu Feb 20 10:34:21 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.disasm/mn10200.s: Add "nop" after "main" so that "main"
+ and "add_tests" are not at the same address.
+
+Fri Feb 14 18:47:23 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/ptype.exp: Use gdb_test.
+
+Thu Feb 13 16:09:36 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.disasm/mn10200.s (misc_tests): Fix targets for "jsr" insns.
+ * gdb.disasm/mn10200.exp (misc_tests): Remove bogus line accidentally
+ left in. No longer expect them to fail.
+
+ * gdb.stabs/*.mt; Deleted, no longer used.
+ * gdb.stabs/configure.in: Remove references to target makefile
+ frags.
+ * gdb.stabs/configure: Rebuilt.
+
+ * gdb.disasm/*.mt: Deleted, no longer used.
+ * gdb.disasm/configure.in: Remove references to target makefile
+ frags. Use "sh3.s" as the unique filename for this directory.
+ * gdb.disasm/configure: Rebuilt.
+
+ * gdb.disasm/mn10200.s: New test file for mn10200 disassembler.
+ * gdb.disasm/mn10200.exp: Run mn10200 disassembler tests.
+ * gdb.disasm/Makefile.in: Remove "mn10200" when cleaning.
+
+Tue Feb 11 16:57:58 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/udi.exp: Use mondfe,name instead of remote_host.
+
+Tue Feb 11 11:22:36 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/watchpoint.exp: Don't expect a failure when calling
+ a function with a watchpoint enabled on the mn10200.
+
+ * gdb.stabs/weird.exp: Don't quit if "weird.s" doesn't exist
+ before trying to create it!
+
+Mon Feb 10 16:40:47 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/vx.exp: Use hostname instead of netport.
+
+ * config/vxworks.exp: New file.
+
+ * gdb.base/a2-run.exp: Change vxworks cases to use gdb_spawn_id.
+
+ * config/monitor.exp(gdb_target_monitor): Look for a prompt from
+ gdb before assuming everything worked. Send a ^C if a timeout
+ occurs.
+
+ * lib/gdb.exp(gdb_test): Check the result of send_gdb. Use
+ $gdb_spawn_id directly.
+ (gdb_run_cmd): Try _start as well as start. Use the target feature
+ gdb,start_symbol as the symbol to start from when jumping.
+
+Mon Feb 10 11:26:59 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/exprs.exp: Delete bogus/incorrect (and probably
+ redundant) test.
+
+ * gdb.base/recurse.exp: Relax final value test for 'b' so that
+ it doesn't lose for 16bit integer systems.
+
+Fri Feb 7 09:31:21 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.fortran/types.exp: If the target doesn't support "double"
+ data types, then expect "real" types to only be 4 bytes.
+
+ * gdb.c++/virtfunc.exp: Expect failure for virtual function
+ call tests if the target doesn't support inferior function calls.
+
+ * gdb.base/printcmds.exp: Allow minor deviation in FP values
+ in printf tests.
+
+Thu Feb 6 12:46:14 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/help.exp: Disable "help set", "help show", and
+ "help support". Simplify regexp for "help stack".
+
+ * gdb.base/default.exp: Set match_max to 5000 and the timeout
+ to 60 seconds. Temporarily set match_max to 15000 around the
+ "info copying" test.
+
+ * gdb.base/nodebug.exp: Don't try to do an inferior function
+ call if the target doesn't support them.
+ * gdb.base/printcmds.exp: Likewise.
+ * gdb.base/setvar.exp: Likewise.
+ * gdb.base/structs.exp: Likewise.
+ * gdb.c++/templates.exp: Likewise.
+ * gdb.base/ptype.exp: Likewise. Remove UDI specific stuff.
+
+ * gdb.base/recurse.exp: Enable for the mn10200.
+
+ * configure.in: Do configure gdb.stabs directory for *-*-elf
+ targets.
+ * configure: Rebuilt.
+
+ * gdb.base/break.exp: Check for gdb,noresults before testing
+ exit status and/or results from the target.
+ * gdb.base/watchpoint.exp, gdb.base/langs.exp: Likewise.
+ * lib/gdb.exp: Remove old (now bogus) initialization of
+ noinferior, noargs, noresults and nosignals.
+
+Tue Feb 4 21:52:17 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/sh.exp: New file.
+
+ * config/slite.exp: Try to connect multiple times to the board
+ before rebooting. Only send a "monitor run" if need_monitor_run
+ is set.
+
+ * gdb.base/break.exp: Don't do the "stub continue" test if
+ the target has gdb_stub set.
+
+ * gdb.base/callfuncs.exp: Increase the timeout.
+
+ * gdb.base/interrupt.exp: Don't even try to compile the testcase
+ if the target has gdb,noinferiorio set.
+
+ * gdb.base/list.exp: Increase match_max to 10000 characters.
+
+ * gdb.base/sigall.exp: Check for gdb,nosignals on the target.
+
+ * gdb.base/watchpoint.exp: Check for gdb,noinferiorio on the
+ target.
+
+ * lib/gdb.exp(gdb_run_cmd): Fix for targets that use stubs.
+
+Mon Feb 3 12:09:37 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/a1-selftest.exp: Make sure we call gdb_exit before
+ trying to delete the copy of gdb. Catch the file delete so we
+ don't die if the delete fails; also, the file should be copied to
+ the host, not to the build.
+
+Sun Feb 2 00:55:14 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gdb.exp(gdb_test): Surround the result pattern with
+ parenthesis in case it contains multiple regexps separated
+ with |.
+
+ * gdb.base/watchpoint.exp: Use gdb_test.
+ * gdb.base/default.exp: Ditto.
+
+Sat Feb 1 23:51:01 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.*/*.exp: Replace $prompt with $gdb_prompt.
+
+ * gdb.base/scope.exp: Use gdb_test.
+ * gdb.c++/classes.exp: Ditto.
+ * gdb.c++/inherit.exp: Ditto.
+
+Fri Jan 31 13:09:12 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gdb.base/crossload.exp: Don't use execute_anywhere, use
+ remote_exec instead.
+ * gdb.base/corefile.exp: Don't be ridiculous.
+ * gdb.base/*.c: Add missing stub invocations.
+
+Thu Jan 30 16:49:25 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/slite.exp: Miscellaneous fixes.
+
+ * lib/gdb.exp: Fix runto.
+
+ * gdb.base/signals.exp: Check for a gdb,nosignals feature of
+ the target.
+
+ * gdb.base/watchpoint.exp: Fix regexp.
+
+ * lib/gdb.exp(default_gdb_exit): Add a catch to the
+ close and wait commands, as the descriptor may now be
+ invalid. Always call "remote_close host".
+
+Tue Jan 28 14:42:31 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ Major rewrite for testsuite revision.
+
+ * lib/gdb.exp: Remove references to global CC, CXX, B_OPTIONS,
+ TARGET_INCLUDES, LDFLAGS and target_alias. Use gdb_spawn_id
+ instead of relying on spawn_id to always contain a valid
+ spawn id.
+ (get_compiler_info): New procedure to build the ${binfile}.ci
+ file, instead of replicating this in N different places.
+ (gdb_compile): New procedure.
+
+ gdb.*/*.exp: Use gdb_compile and get_compiler_info (with
+ appropriate arguments) instead of compile. Use gdb_test in a lot
+ more places. Use send_gdb instead of send. Always run gdb_start
+ at the start of a testcase, as this is no longer done magically.
+
+ config/*-gdb.exp: Rename without the -gdb suffix.
+
+ config/mips.exp: Use remote_close instead of exit_remote_shell.
+ config/monitor.exp: Use target_info instead of looking at
+ baud, timeout, etc.
+ config/sim.exp: Use gdb_spawn_id instead of relying on spawn_id.
+
+Sat Dec 14 00:43:57 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.c++/templates.exp (test_ptype_of_templates),
+ gdb.c++/inherit.exp (test_ptype_si, test_print_anon_union):
+ Update expect patterns for destructors and assignment operators
+ to match corresponding c-typeprint.c changes.
+ * gdb.c++/templates.exp (test_template_breakpoints): Revert change
+ to destructor breakpoint test, GDB should be able to set the
+ destructor breakpoint without specifying arguments.
+
+Tue Dec 3 20:17:52 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.threads/pthreads.exp: Change result for failure to compile due
+ to lack of pthreads runtime support from an error to simply an
+ unsupported test, per dejagnu standards.
+
+Sun Dec 1 00:18:59 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * lib/gdb.exp (gdb_test): Simplify expect pattern for the case
+ where GDB exits to reduce pattern match time.
+ (skip_chill_tests): Skip chill tests for mips*-sgi-irix6*.
+
+ * gdb.base/nodebug.exp: Add mips*-sgi-irix6* xfails.
+
+Tue Nov 26 18:29:23 1996 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/callfuncs.exp: Turn on function call tests for h8300.
+ * gdb.base/default.exp: ditto.
+ * gdb.base/nodebug.exp: ditto.
+ * gdb.base/printcmds.exp: ditto.
+ * gdb.base/ptype.exp: ditto.
+ * gdb.base/setvar.exp: ditto.
+ * gdb.base/structs.exp: ditto.
+ * gdb.base/setshow.c: Guard against uninitialized values of argc.
+
+Tue Nov 26 17:23:28 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure, */configure: Rebuild with autoconf 2.12.
+
+Sat Nov 23 13:32:15 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/a1-selftest.exp: Change x86 linux setup_xfails to
+ use new i*86-pc-linux*-gnu quads.
+ * gdb.base/corefile.exp: Ditto.
+ * gdb.base/signals.exp: Ditto.
+ * gdb.base/sigall.exp: Ditto.
+ * gdb.base/interrupt.exp: Ditto.
+
+ * gdb.base/signals.exp (signal_tests_1): Remove setup_xfail
+ "i*86-*-linux" for "signal SIGUSR1". Now works, at least with
+ RedHat 4.0.
+
+ * gdb.threads/pthreads.c (_MIT_POSIX_THREADS): Define if target is
+ linux. This allows the test case to at least compile on latest
+ linux, but still not run due to missing the threads runtime library.
+
+Fri Nov 22 10:13:29 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/a1-selftest.exp (do_steps_and_nexts): Reinitialize source
+ directory to search gdb directory. Accept and step over conditional
+ stack alignment code. Consume $prompt in failure cases.
+ Reset timeout to $oldtimeout instead of some arbitrary value.
+ * gdb.base/nodebug.exp: Limit backtrace to 10 frames to avoid
+ timeout problems with infinite stack backtraces.
+ * gdb.base/ptype.exp (ptype struct link, union tu_link):
+ Accept function parameters for linkfunc member.
+
+Thu Nov 21 09:17:19 1996 Fred Fish <fnf@cygnus.com>
+
+ * lib/gdb.exp (CFLAGS): Remove, unreferenced.
+ (CXXFLAGS): Remove, unreferenced.
+ (B_OPTIONS): Add for -B options and add code to initialize with
+ previous -B options and also add -B option to pick up cross compiled
+ runtime.
+ (TARGET_INCLUDES): Add for -I options and add code to initialize when
+ doing cross compiles.
+ (target_alias): Declare global.
+ (xgcc): Set variable to full path of gcc in build tree. Use findfile
+ to verify that gcc exists in build tree, and if so set CC to that
+ gcc and to use B_OPTIONS and TARGET_INCLUDES.
+
+Tue Nov 12 16:20:13 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.c++/inherit.exp (test_print_anon_union): Reenable
+ ptype test for anonymous union. Fixup testcase to match
+ current gcc debug output.
+
+Mon Nov 11 14:12:06 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/funcargs.c: Use cast rather than "UL" suffix to
+ force argument to an unsigned long type.
+
+Mon Nov 11 10:27:55 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.c++/inherit.exp (test_ptype_si): Fix tagless struct ptype
+ tests and anonymous union print/ptype tests.
+ * gdb.base/list.exp (test_forward-search): Increase timeout by
+ 5 minutes for the "search extremely long line" case.
+ * lib/gdb.exp (gdb_test): Document that the third arg to gdb_test is
+ completely optional and that the pass/fail messages use the command as
+ the message if that third arg is a null string.
+ (gdb_test_exact): Arrange that a null string pattern means match a
+ null string output rather than any output, which might include random
+ errors.
+ * gdb.base/mips_pro.exp: Add "mips*-sgi-irix4*" xfail for
+ backtrace test.
+ * gdb.c++/demangle.exp: Add a "*-*-*" xfail for test that was
+ always failing and failure is now exposed by gdb.exp changes.
+
+Sat Nov 9 11:13:24 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.c++/inherit.exp (test_ptype_vi): Log some passes that
+ weren't being noted.
+
+Sat Nov 9 01:05:10 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/corefile.exp: Consume $prompt in mmap fail cases.
+ * gdb.stabs/weird.exp: Remove v_comb xfails.
+
+Tue Nov 5 10:44:23 1996 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/[bitfields.exp crossload.exp funcargs.exp interrupt.exp
+ list.exp scope.exp watchpoint.exp]
+ Make all timeout error msgs explicitly say "(timeout)".
+
+Mon Nov 4 12:03:06 1996 Michael Snyder <msnyder@cygnus.com>
+
+ * config/monitor.exp: Increase download timeout to 1000 seconds.
+
+Mon Nov 4 12:02:26 1996 Michael Snyder <msnyder@cygnus.com>
+
+ * config/m32r.exp: Increase timeout to 120 seconds.
+
+Sun Nov 3 14:37:05 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.c++/classes.exp: Modify to handle current gcc C++ member ordering
+ and accept older ordering as obsolescent gcc or gdb.
+ * gdb.c++/templates.exp: Ditto.
+ * gdb.c++/virtfunc.exp: Ditto.
+
+Fri Nov 1 11:56:09 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/coremaker.c: Add code to mmap some data so we
+ can check that it ends up in the core file.
+ * gdb.base/corefile.exp: Add test to read mmapped data
+ from core file.
+
+Wed Oct 30 18:19:16 1996 Michael Snyder <msnyder@cygnus.com>
+
+ * config/m32r.exp: New file.
+
+Mon Oct 21 14:40:50 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * testsuite/gdb.base/nodebug.exp: Whack out -g options by hand so
+ that cflags can contains -gstabs, and work correctly for other tests.
+
+Mon Oct 21 14:00:37 1996 Michael Snyder <msnyder@cygnus.com>
+
+ * gdb.base/setshow.exp: New file, tests show and set.
+ * gdb.base/setshow.c: New file, tests show and set.
+ * gdb.base/help.exp: Add test for help set|show annotate.
+ * gdb.base/default.exp: Add test for set|show annotate.
+
+Wed Oct 16 19:03:54 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * testsuite/gdb.base/break.exp: Make backtrace from factorial
+ errors unique.
+ * testsuite/gdb.base/nodebug.exp: Whack out all -g options
+ explicitly.
+
+Tue Oct 15 16:45:02 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config/sim-gdb.exp (gdb_target_sim): Remove setting of height
+ and width commands. This is done elsewhere.
+ * (gdb_start): Don't call gdb_start_sim here. That's already
+ done in gdb_load. This fixes lots of failures in default.exp.
+
+Sun Oct 13 10:40:23 1996 Fred Fish <fnf@cygnus.com>
+
+ From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>:
+ * gdb.base/mips_pro.exp: Fix misplaced gdb_exit/gdb_start/gdb_load.
+ * lib/gdb.exp (gdb_test): Treat failures due to program exiting
+ in the same we we treat other failures (since it may be an expected
+ condition), rather than as an error.
+ * gdb.base/signals.exp (test_handle_all_print): Revert back to
+ old test format.
+
+Fri Oct 11 17:05:22 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (clean mostlyclean): Also remove chill *.grt files.
+ (distclean maintainer-clean realclean): No need to remove files
+ twice. Nuke the duplicates.
+ * gdb.base/Makefile.in (EXECUTABLES): Add "structs".
+ * gdb.threads/Makefile.in (distclean maintainer-clean realclean):
+ Remove config.h along with other config files.
+
+Mon Sep 30 20:16:22 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/interrupt.exp: Add i*86-*-linux* setup_xfail for
+ "p func1 ()" and note that rests of tests are skipped.
+ * gdb.base/corefile.exp: Add i*86-*-linux* and m68*-*-hpux*
+ setup_xfails for "print func2::coremaker_local".
+ Add i*86-*-linux* setup_xfail for "backtrace in corefile.exp".
+ * gdb.base/mips_pro.exp: Restart gdb in this test so it isn't
+ affected by the previous run test.
+ * gdb.chill/misc.exp: Add m68*-*-hpux* setup_xfails for
+ "print array () ubyte (foo)" and "print/x array () byte (\$i)"
+ * gdb.chill/pr-8742.exp: Add m68*-*-hpux* setup_xfails for
+ "pass int powerset tuple" and "pass modeless int powerset tuple".
+ * gdb.chill/tests2.exp: Add m68*-*-hpux* setup xfails for
+ "real write 4" and "real write 8".
+ * gdb.shill/tuples.exp: Add i*86-*-linux* and m68*-*-hpux*
+ setup_xfails for "print vs1 after tuple assign 2",
+ "print \$i after tuple assign 2", and
+ "print vs2 after tuple assign 2".
+ * lib/gdb.exp (gdb_test): When a gdb aborts, print a more
+ meaningful error message and return -1 so the caller can
+ suppress further tests and avoid a cascade of errors.
+
+Fri Sep 27 10:34:51 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/a1-selftest.exp: Tweak tests to account for new
+ format for printing version.
+ * gdb.base/default.exp: Ditto.
+ * gdb.base/interrupt.exp: Fix problem with cascade of
+ errors if child process dies while calling a function.
+
+Fri Sep 13 21:43:48 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (VPATH): Add
+ * Makefile.in (Makefile, config.status): Fix rules so things get
+ remade when necessary.
+
+Fri Sep 13 18:16:10 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (just-check): Add path to sibling expect dir
+ to environment variable specified by RPATH_ENVVAR.
+
+Fri Sep 13 12:05:34 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (RPATH_ENVVAR): New var, set to @RPATH_ENVVAR@.
+ (just-check): Add shared library paths for libstdc++, tk,
+ tcl, bfd, and opcodes to the environment variable specified
+ in RPATH_ENVVAR.
+ * configure.in: Add support to recognize --enable-shared flag
+ and generate correct value for RPATH_ENVVAR.
+ * configure: Regenerated with autoconf.
+
+Mon Sep 2 06:36:02 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/break.exp: Expand "Delete all breakpoints" xfail to
+ include all osf versions.
+ * gdb.threads/pthreads.exp: Expand "run to main" xfail to include
+ all osf versions. Add -D_MIT_POSIX_THREADS to compilation command
+ when target is linux. When failing to build pthreads test
+ executable, give more meaningful message.
+ * gdb.threads/pthreads.c: Hpux also uses old definition of second
+ arg for pthread_create.
+
+Mon Aug 19 09:58:59 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.threads/pthreads.c (PTHREAD_CREATE_ARG2,
+ PTHREAD_CREATE_NULL_ARG2): Accomodate old pthreads implementations.
+ * gdb.threads/pthreads.exp: Try linking with both -lpthread (Solaris)
+ and -lpthreads (everybody else).
+ (test_startup): Fail gracefully if threads are not supported.
+ * gdb.base/nodebug.exp: Add setup_xfail hppa*-*-hpux* for
+ "p/c array_index("abcdef",2)" when not gcc compiled.
+ * gdb.base/corefile.exp: Add setup_xfail hppa*-*-hpux* for
+ "print func2::coremaker_local" when not gcc compiled.
+ * gdb.base/opaque.exp: Remove setup_xfail hppa*-*-hpux* for
+ "ptype on opaque struct tagname (statically)",
+ "ptype on opaque struct tagname (dynamically) 1", and
+ "ptype on opaque struct tagname (dynamically) 2"
+ for not compiled with gcc.
+ * gdb.base/mips_pro.exp: Only do setup_xfail hppa*-*-* for
+ backtrace when compiled with gcc.
+ * lib/gdb.exp (runto_main): Return result of "runto main" rather
+ than always return success.
+
+Sat Aug 17 13:28:00 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.c++/virtfunc.exp: Remove setup_xfail for "mips-*-irix5*".
+
+Tue Aug 13 10:26:10 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/structs.exp: Undo last change.
+
+Mon Aug 12 15:29:08 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/a1-selftest.exp (do_steps_and_nexts): New routine to
+ encapsulate all the steps/nexts done during self test, starting
+ at main, and makes them less sensitive to optimization issues.
+ Add "hppa*-*-hpux*" to setup_xfail for "backtrace through
+ signal handler" test.
+ * gdb.threads/pthreads.exp: Only run this for native configs.
+ * gdb.base/structs.exp (do_function_calls): Add hppa*-*-hpux9*"
+ setup_xfails for "p fun5()", "p fun6()", "p fun7()", and "p fun8"
+ tests.
+ gdb.c++/virtfunc.exp (do_tests): Add "mips-*-irix5*" setup_xfail
+ for "runto test_calls(void)" test.
+
+Sun Aug 11 13:11:24 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/term.exp: Set 7-bit strings, address off, width to 0,
+ and don't expect address info in breakpoint confirmations.
+
+Wed Aug 7 20:47:43 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/list.exp (test_forward_search): Increase timeout
+ temporarily by 60 seconds for searching extremely long line,
+ and then reset to old value when done. Increase expect input
+ buffer to 10000.
+
+Wed Aug 7 15:34:22 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/list.exp (test_forward_search): Fix to handle very
+ long source line without overflowing expect's input buffer.
+
+Wed Aug 7 12:03:25 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * config/slite-gdb.exp (gdb_start): Use "full_buffer", not
+ "buffer_full".
+
+ * config/nind-gdb.exp (gdb_start): Use "full_buffer", not
+ "buffer_full".
+
+ * config/mips-gdb.exp (gdb_start): Use "full_buffer", not
+ "buffer_full".
+
+ * lib/gdb.exp (gdb_test): Correct pattern is "full_buffer", not
+ "buffer_full".
+
+Wed Aug 7 11:05:47 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in (configdirs): Add gdb.threads.
+ * configure: Regenerated with autoconf.
+ * gdb.threads/{config.in, pthreads.c, pthreads.exp}: New.
+ * gdb.threads/{Makefile.in, configure.in}: Complete rewrites.
+ * gdb.threads/configure: New, generated with autoconf.
+
+Tue Aug 6 10:23:04 1996 Tom Tromey <tromey@rtl.cygnus.com>
+
+ * lib/gdb.exp (gdb_test_exact): Turn \n in pattern into \r\n.
+
+Mon Aug 5 18:11:53 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/signals.exp (test_handle_all_print): Test separately for
+ each signal's status in the output of "handle all print".
+ * lib/gdb.exp (gdb_test): Document that the pattern must NOT include
+ the \r\n sequence that immediately precedes the gdb prompt.
+ * gdb.base/a1-selftest.exp: Save original timeout and restore
+ after test.
+
+Sun Aug 4 10:20:50 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.disasm/hppa.s: Export fmemLRbug_tests_4 as a ST_CODE
+ symbol.
+
+Fri Aug 2 17:37:26 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * config/vx-gdb.exp (gdb_start): Fix syntax of `$shell_id < 0'.
+
+Thu Jun 27 20:41:40 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/signals.exp (test_handle_all_print): Temporarily increase
+ timeout by 60 seconds.
+
+Thu Jun 27 18:13:57 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/unix-gdb.exp: Increase default timeout from 30 to 60 sec.
+ * config/netware.exp (gdb_run_cmd): Restore old timeout before doing
+ error return.
+
+Thu Jun 27 10:54:58 1996 Fred Fish <fnf@cygnus.com>
+
+ * lib/gdb.exp (default_gdb_start): When reporting a timeout during
+ gdb initialization, also report how long dejagnu waited. Restore
+ old timeout before doing error return. Temporarily increase timeout
+ by 3 minutes to allow for slow startups over heavy NFS use.
+
+Tue Jun 25 19:59:17 1996 Fred Fish <fnf@cygnus.com>
+
+ * lib/gdb.exp: Report timeout value for verbosity level 2.
+ * config/gdbserver.exp: Ditto.
+ * config/hppro.exp: Ditto.
+ * config/mips-gdb.exp: Ditto.
+ * config/monitor.exp: Ditto.
+ * config/netware.exp: Ditto.
+ * config/sim-gdb.exp: Ditto.
+ * config/slite-gdb.exp: Ditto.
+ * config/udi-gdb.exp: Ditto.
+ * config/unix-gdb.exp: Ditto.
+ * config/vx-gdb.exp: Ditto.
+ * gdb.base/a1-selftest.exp: Ditto.
+ * gdb.base/a2-run.exp: Ditto.
+ * gdb.base/break.exp: Ditto.
+ * gdb.base/corefile.exp: Ditto.
+ * gdb.base/list.exp: Ditto.
+ * gdb.base/recurse.exp: Ditto.
+ * gdb.base/scope.exp: Ditto.
+ * gdb.base/signals.exp: Ditto.
+
+Tue Jun 25 23:16:58 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * gdb.threads/Makefile.in (docdir): Removed.
+
+Tue Jun 25 17:02:39 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ * gdb.{base,c++,chill,disasm,stabs}/Makefile.in (VPATH): set to
+ @srcdir@.
+ * gdb.{base,c++,chill,disasm,stabs}/configure.in (AC_PREREQ):
+ autoconf 2.5 or higher.
+ * gdb.{base,c++,chill,disasm,stabs}/configure: Rebuilt.
+
+Thu Jun 13 11:16:10 1996 Tom Tromey <tromey@thepub.cygnus.com>
+
+ * configure: Regenerated.
+ * aclocal.m4 (CY_AC_PATH_TCLH, CY_AC_PATH_TKH): Use odd names to
+ avoid name clashes with SunOS headers.
+
+Wed Jun 5 16:43:27 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.c++/virtfunc.exp: Search $objdir/../../libstdc++ for libstdc++.
+
+Thu May 30 11:35:11 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/callfuncs.exp: Finish last change -- make sure the
+ prototype information ends up in the compiler info file.
+
+Thu May 23 12:48:41 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/callfuncs.exp: Remove the compiler info file prior to
+ attempting to regenerate it. Eliminate use of a temporary file
+ and just generate the info file directly. Source it immediately,
+ for consistency of use.
+ * gdb.base/corefile.exp: Ditto
+ * gdb.base/exprs.exp: Ditto.
+ * gdb.base/funcargs.exp: Ditto.
+ * gdb.base/langs.exp: Ditto.
+ * gdb.base/list.exp: Ditto.
+ * gdb.base/mips_pro.exp: Ditto.
+ * gdb.base/nodebug.exp: Ditto.
+ * gdb.base/opaque.exp: Ditto.
+ * gdb.base/ptype.exp: Ditto.
+ * gdb.base/scope.exp: Ditto.
+ * gdb.base/setvar.exp: Ditto.
+ * gdb.base/signals.exp: Ditto.
+ * gdb.base/whatis.exp: Ditto.
+ * gdb.c++/templates.exp: Ditto.
+ * gdb.c++/virtfunc.exp: Ditto.
+ * gdb.c++/virtfunc.exp: Use contents of gcc_compiled to decide
+ whether or not to add -lstdc++ to the compile command line args.
+
+Sat May 18 02:43:58 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/recurse.exp: Remove setup_xfail for "sparc*-*-sunos4*",
+ it got fixed by the recent lookup_minimal_symbol_by_pc change.
+ Increase timeout, a lot of single stepping might be needed if the
+ target has no hardware watchpoints.
+
+Wed May 15 08:47:42 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/break.exp: Ignore compiler warnings when compiling
+ break.c.
+ * gdb.base/callfuncs.exp: Don't run these tests on the h8300.
+ * gdb.base/default.exp: Add h8300 xfails. Handle messages
+ from remote-sim.
+ * gdb.base/exprs.exp: Add h8300 xfails.
+ * gdb.base/funcargs.exp: Likewise.
+ * gdb.base/nodebug.exp: Likewise.
+ * gdb.base/printcmds.exp: Likewise.
+ * gdb.base/ptype.exp: Likewise.
+ * gdb.base/setvar.exp: Handle sizeof (int) != 4 for h8300. Add
+ h8300 xfails.
+ * gdb.base/return.exp: Handle float/double precision problems
+ on the h8300.
+ * gdb.base/funcargs.c: Explicitly make last constant argument to
+ call_after_alloca_subr an unsigned long type.
+ * gdb.base/return.c: Include stdio.h.
+
+Tue May 7 22:01:12 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * config/abug.exp: New file for the older Motorola Bug monitor
+ that runs on the mvme13x series VME boards.
+ * config/monitor.exp: Use the new config array for target settings
+ if they exist.
+
+Fri May 3 16:02:55 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * sim-gdb.exp: Make the SH simulator allocate less space when
+ it is targeted.
+
+Thu May 2 12:31:56 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/mips_pro.exp: Expect failure for hppa*-*-* in backtrace
+ test.
+
+Wed Mar 20 08:48:03 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/list.exp (test_list_function): Remove setup_xfail for
+ "rs6000-*-*" for "list function in include file" when gcc compiled.
+ * gdb.base/printcmds.exp: Remove setup_xfail for "rs6000-*-aix*"
+ for "p ctable1[120]".
+ * gdb.base/scope.exp: Remove setup_xfail for "rs6000-*-*" for
+ "print 'scope0.c'::filelocal_bss before run" when gcc compiled.
+ Remove setup_xfail for "rs6000-*-*" for
+ "print 'scope0.c'::filelocal before run".
+ * gdb.base/{langs.exp, lists.exp, opaque.exp, scope.exp},
+ gdb.stabs/weird.exp: Remove use of compiler options "-c -o ..."
+ since some compilers don't allow both options to be given
+ on the same command line. Create object file and move it.
+
+Tue Mar 19 23:49:31 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/corefile.exp: Always regenerate the core file, since
+ we always regenerate the coremaker program. Detect special case
+ where registers cannot be read from core file.
+
+Tue Mar 19 16:52:49 1996 Fred Fish <fnf@cygnus.com>
+
+ From Peter Schauer <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
+ * gdb.base/funcargs.c: Patch for SPARCworks alloca compatibility
+ * gdb.c++/templates.exp: Only match on basename of file since
+ some formats like xcoff don't encode directory information.
+ * gdb.stabs/weird.exp: Use the right sed script for powerpc
+ and rs6000 AIX xcoff targets.
+ * configure.in: Add stabsdirs to configdirs for powerpc-*-aix*.
+ * configure: Regenerate.
+ * gdb.base/Makefile.in (clean): Remove generated file twice-tmp.c
+ here, rather than in distclean.
+
+Sun Mar 17 13:35:31 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/mips_pro.exp: Create mips_pro.ci to get gcc_compiled
+ defined, and use it to compile the test case with -O2. The
+ native compilation still uses no optimization.
+ * gdb.base/mips_pro.c: Remove inline assembly code since
+ it is compiled PIC by default, which results in assembler
+ warnings that make the testsuite think the compilation
+ was unsuccessful.
+
+Sat Mar 16 15:02:24 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.c++/misc.exp: Add note to message for
+ "print s.a for foo struct" that this is a known gcc 2.7.2
+ and earlier bug.
+
+Fri Mar 15 17:49:57 1996 Fred Fish (fnf@cygnus.com)
+
+ * gdb.base/break.exp: Fix pattern for matching "Delete all
+ breakpoints (y or n) ". Add "mips-dec-ultrix*" to
+ setup_xfail for deleting all breakpoints test. Fix various
+ timeout messages to include "(timeout)".
+ * gdb.base/callfuncs.exp: Add "i*86-*-sysv4*" to setup_xfail
+ for "p t_float_values2(3.14159,float_val2)".
+ * gdb.base/funcargs.exp: Remove "mips-sgi-irix4*" setup_xfail
+ for "continue to call2g" when gcc compiled.
+ * gdb.base/langs.exp: Remove "i*86-*-sysv4*" setup_xfail for
+ "up to foo in langs.exp", "show language at foo in langs.exp",
+ "show language at cppsub_ in langs.exp", "up to fsub in langs.exp",
+ and "show language at fsub in langs.exp".
+ * gdb.base/list.exp: Remove "*-*-sysv4*" setup_xfail for
+ "list line 1 in include file", "list message for lines past EOF",
+ "list function in include file", "list list0.h:foo", and
+ "list filename:function; nonexistant function".
+ * gdb.base/ptype.exp: Change "i*86-*-sysv4*" setup_xfail for
+ "whatis unnamed typedef'd enum (compiler bug in IBM's xlc)"
+ and "ptype t_char_array" to be for native cc only.
+
+Fri Mar 15 16:17:22 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/corefile.exp: Remove "alpha-dec-osf2*" native compiled
+ setup_xfail for "print coremaker_bss", "print coremaker_ro",
+ "print func2::coremaker_local", and "backtrace in corefile.exp".
+
+Wed Mar 13 14:54:11 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/signals.exp: Remove "alpha-*-osf2*" setup_xfail for
+ "bt in signals.exp". This problem only appears when running
+ the testsuite, and then only intermittently.
+
+Tue Mar 12 15:00:16 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/return.exp (return_tests): Differentiate between
+ two tests of continuing.
+
+Tue Mar 5 14:33:33 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * */Makefile.in (maintainer-clean): Remove config.log.
+ * gdb.base/Makefile.in (EXECUTABLES): Replace twice with twice-tmp.
+ * gdb.c++/Makefile.in (PROGS): Add inherit.
+ (clean): Remove *.ci.
+
+Tue Feb 20 16:36:10 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.c++/misc.cc: Add test code from Mike Stump.
+ * gdb.c++/misc.exp: Add test to print s.a, for Mike Stump.
+
+Sun Feb 18 11:39:12 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/signals.exp: Change setup_xfail for "alpha-*-osf2"
+ to "alpha-*-osf2*" and add comment.
+ * gdb.base/a1-selftest.exp (test_with_self): Remove "alpha-dec-osf2*"
+ setup_xfail for "step over execarg initialization" and
+ "step over corearg initialization".
+ * gdb.base/callfuncs.exp (do_function_calls): Restore setup_xfail
+ for "hppa*-*-*", "sparc-*-*", "mips*-*-*", and "alpha-dec-osf2*".
+ * gdb.base/corefile.exp: Add "alpha-dec-osf2*" setup_xfail when not
+ gcc compiled for "print coremaker_bss", "print coremaker_ro",
+ "print func2::coremaker_local", and "backtrace in corefile.exp".
+ * gdb.base/signals.exp: Build and source signals.ci.
+ Change "alpha-dec-osf2*" setup_xfail for "bt in signals.exp"
+ to be for gcc only.
+ * lib/gdb.exp: Move verbose statements outside conditionals.
+
+Sat Feb 17 02:22:14 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/sigall.exp: Remove setup_xfail for irix4. Fixed by
+ Feb 3 procfs.c change.
+
+Fri Feb 16 13:25:31 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/unix-gdb.exp: Remove extraneous newlines from end of file.
+
+Thu Feb 15 08:12:55 1996 Fred Fish <fnf@cygnus.com>
+
+ * config/unix-gdb.exp: Default timeout in UNIX case to 30 seconds, up
+ from dejagnu's apparent default of 10 seconds, which gives random
+ results when running the tests over NFS on moderately loaded systems.
+ * lib/gdb.exp (gdb_run_cmd): Add "(timeout)" in timeout case.
+
+Mon Feb 12 16:50:28 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/callfuncs.exp: Remove setup_xfail for PR 5318. Now fixed.
+ * gdb.base/a2-run.exp: Replace $binfile with $testfile in test
+ result reports.
+
+Fri Feb 9 15:56:51 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in (CY_AC_PATH_TCLH): Remove.
+ * configure: Regenerate.
+
+Fri Feb 9 08:21:31 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.c++/Makefile.in (clean): Add missing '{'.
+
+Fri Feb 2 10:19:40 1996 Jeffrey A Law (law@cygnus.com)
+
+ * lib/gdb.exp: Provide a default value for noinferior.
+
+ * lib/gdb.exp: Fix typos (LDLAGS -> LDFLAGS).
+ Load libgloss.exp.
+
+Thu Feb 1 20:20:14 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.disasm/hppa.exp: Compile directly into an executable, use
+ the executable, not the .o to run the tests from.
+
+Wed Jan 31 14:21:09 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/break.exp: Don't test for program exit or exit status
+ if $noresults if nonzero.
+ * gdb.base/langs.exp: Likewise.
+ * gdb.base/watchpoint.exp: Likewise.
+
+ * gdb.base/default.exp: Remove extraneous call to load gdb.exp.
+ * gdb.chill/pr-8405.exp: Move skip_chill_tests check to just before
+ trying to compile the testcase.
+
+Wed Jan 24 23:42:39 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * gdb.base/interrupt.exp (p func1): xfail sparc64-*-solaris2.
+ * gdb.base/signals.exp (continue to handler): Likewise.
+
+Tue Jan 23 16:28:22 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * gdb.c++/classes.exp: Now = returns false/true, not 1/0.
+
+ * gdb.fortran/exprs.exp: .LT. and .GT. now return .TRUE. or .FALSE..
+
+Tue Jan 23 15:41:57 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/corefile.exp: Recognize "not found" as failure
+ when trying to determine if a core file was generated.
+ If no core file was generate the first time, try again without
+ the ulimit -c to work around braindamaged shells.
+
+Mon Jan 15 09:33:00 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.stabs/configure.in (alpha-*-*,mips-*-*): Replace
+ [] tests with "test" and enclose string in quotes.
+ * gdb.stabs/configure: Rebuild
+
+Thu Jan 11 09:43:14 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ Changes in sync with expect:
+ * aclocal.m4 (CY_AC_PATH_TCLH): Handle Tcl 7.5 and greater.
+ (CY_AC_PATH_TCLLIB): Handle Tcl 7.5 and greater.
+ (CY_AC_PATH_TKH): Handle Tk 4.1 and greater.
+ (CY_AC_PATH_TKLIB): Handle Tk 4.1 and greater. Properly quote
+ argument to AC_REQUIRE.
+ * configure: Regenerated.
+
+Thu Jan 4 08:17:22 1996 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/corefile.exp: When generating a core, discard any
+ error messages about ulimit not found and the "core dumped"
+ message from the shell that runs the coredumper.
+
+Wed Jan 3 01:30:41 1996 Jeffrey A Law (law@cygnus.com)
+
+ * lib/gdb.exp (skip_chill_tests): Skip them on the PA too.
+
+ * gdb.stabs/weird.exp: Use ${target_triplet} to determine
+ which sed script to run. Expect failure for v_comb test
+ on PA targets too.
+
+Sat Dec 30 16:09:04 1995 Fred Fish <fnf@rtl.cygnus.com>
+
+ * gdb.base/corefile.exp: Remove "i*86-*-linux" xfail for
+ "print func2::coremaker_local" and for "backtrace in corefile.exp"
+
+Sat Dec 30 12:59:12 1995 Fred Fish <fnf@cygnus.com>
+
+ * lib/gdb.exp: Fix typo and rewrite skip_chill_tests.
+ * gdb.stabs/weird.exp: Setup "sparc-sun-sunos4*" and
+ "sparc-sun-solaris*" xfails for "p v_comb".
+ * lib/gdb.exp (default_gdb_start): Fix typo.
+ * gdb.base/corefile.exp: Allow "Core was generated by ..."
+ messages to not include the full program name that caused
+ the core dump since some systems (such as solaris) apparently
+ truncate this path to about 80 characters.
+ When generating a core file first try increasing the core file
+ size limit to unlimited since some systems may default it to
+ zero, and it is harmless to try it. Move the test for failing
+ to generate a core file to where it will actually get executed.
+ * gdb.c++/templates.exp (test_ptype_of_templates): Accept
+ new gdb result from g++ debug info improvements and make old
+ pattern obsolescent. Also account for size_t differences
+ (may be int or long).
+ * gdb.base/a1-selftest.exp (test_with_self): Check for case where
+ initialization before function call is placed in the delay slot
+ and thus appears to be skipped over by commands such as "next".
+
+Fri Dec 29 16:09:20 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/a1-selftest.exp (test_with_self): Run without windows.
+
+Wed Dec 6 10:45:42 1995 Jeffrey A. Law <law@sethra.cygnus.com>
+
+ * gdb.base/*.exp: Make ${srcfile} only be the basename of the
+ input source file; fix code to compile test to deal with this
+ convention.
+ * gdb.c++/*.exp: Likewise.
+
+Mon Nov 27 11:40:16 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/signals.exp: Setup "alpha-*-osf2*" xfail for
+ "bt in signals.exp".
+
+Sat Nov 25 20:52:15 1995 Fred Fish <fnf@phydeaux.cygnus.com>
+
+ * gdb.base/a1-selftest.exp: Add alpha-dec-osf2 setup_xfail for
+ "step over execarg initialization" and
+ "step over corearg initialization".
+
+Sat Nov 25 18:20:14 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/ptype.c (main): Declare malloc as a "char *" for systems
+ with sizeof(pointer) > sizeof(int). Avoid "void *" or include files.
+
+Sat Nov 25 11:03:42 1995 Fred Fish <fnf@cygnus.com>
+
+ From Rob Savoye (rob@poseidon.cygnus.com)
+ * Makefile.in, configure.in, gdb.base/{Makefile.in, configure.in},
+ gdb.c++/{Makefile.in, configure.in}, gdb.chill/{Makefile.in,
+ configure.in}, gdb.disasm/{Makefile.in, configure.in},
+ gdb.stabs/{Makefile.in, configure.in}, gdb.threads/{Makefile.in,
+ configure.in}: Major reworking for autoconfig.
+ * aclocal.m4, configure, gdb.base/configure, gdb.c++/configure,
+ gdb.disasm/configure, gdb.stabs/configure, gdb.stabs/default.mt :
+ New files.
+ * config/unix-gdb.exp: Make GDB global.
+ * gdb.base/{a1-selftest.exp, a2-run.exp,bitfields.exp, break.exp,
+ callfuncs.exp, commands.exp, corefile.exp, crossload.exp, exprs.exp,
+ funcargs.exp, interrupt.exp, langs.exp, list.exp, mips_pro.exp,
+ nodebug.exp, opaque.exp, printcmds.exp, ptype.exp, recurse.exp,
+ regs.exp, return.exp, scope.exp, setvar.exp, sigall.exp, signals.exp,
+ term.exp, twice.exp, watchpoint.exp, whatis.exp},
+ gdb.c++/{classes.exp, callfuncs.exp, inherit.exp, misc.exp,
+ templates.exp, virtfunc.exp}, gdb.chill/{callch.exp, chillvars.exp,
+ misc.exp, pr-4975.exp, pr-5016.exp, pr-5020.exp, pr-5022.exp,
+ pr-5646.exp, pr-5984.exp, pr-6292.exp, pr-6632.exp, pr-8134.exp,
+ pr-8136.exp, result.exp, string.exp, tuples.exp},
+ gdb.disasm/{hppa.exp, sh3.exp}, gdb.stabs/weird.exp: Change continues
+ to returns as necessary, arrange for test to compile own testcase
+ executable.
+ * lib/gdb.exp: Changes for testsuite to compile own test cases.
+
+Tue Nov 21 16:15:45 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.c++/classes.exp (test_pointers_to_class_members): Add
+ clear_xfail at end of test which might not call either pass or fail.
+ * gdb.base/a1-selftest.exp: Add i*86-*-linuxaout xfail for
+ "backtrace through signal handler".
+
+Sat Nov 18 04:09:31 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/sigall.exp: Work around OSF/1-3.x kernel bug when
+ continuing from a job control stop signal.
+ * gdb.stabs/alpha.mt: Use $(CFLAGS) when building weird.o.
+
+Wed Nov 15 00:28:03 1995 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/callfuncs.exp: Remove bogus hppa xfails.
+ * gdb.base/corefile.exp: Likewise.
+ * gdb.base/funcargs.exp: Likewise.
+
+Tue Nov 14 15:18:10 1995 Stu Grossman (grossman@cygnus.com)
+
+ * config/hmsirom.exp: Setup for talking to hmsi ROM monitor.
+ * config/monitor.exp: Add support for setting baud rate.
+
+Sat Nov 4 15:35:52 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/a1-selftest.exp: Remove i*86-*-sysv4* and
+ i*86-*-linux* xfails for "backtrace through signal handler".
+ * gdb.base/corefile.exp: Add i*86-*-sysv4* xfail for
+ "print func2::coremaker_local".
+ * gdb.base/break.exp: Add i*86-*-sysv4*, sparc-sun-sunos4,
+ alpha-dec-osf2* xfail for
+ "delete all breakpoints when none".
+
+Wed Nov 1 15:57:16 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/break.exp: Change test that deletes all breakpoints
+ when no user breakpoints are installed. A post 4.15 change
+ causes gdb to no longer prompt in this case.
+
+Tue Oct 31 15:13:43 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/return.exp (return_tests): Change xfail for test
+ "correct value returned double test" to stop xfailing at
+ Solaris 2.5. Apparently the bug has been fixed.
+
+Sun Oct 29 12:18:16 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.stabs/ecoff.sed: Remove comment lines except for first one.
+ IRIX 4.0 /bin/sed chokes on them, though they work fine elsewhere.
+
+Tue Oct 24 11:12:12 1995 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.disasm/hppa.exp: Test lci and syncdma instructions.
+ * gdb.disasm/hppa.s: Corresponding changes.
+
+Wed Oct 18 11:27:47 1995 Jeffrey A Law (law@cygnus.com)
+
+ * gdb.base/configure.in (hppa*-*-hpux*): No longer needs target
+ makefile fragment.
+ * config/mt-hpux: Deleted.
+
+Tue Oct 17 23:02:12 1995 Jeffrey A Law (law@cygnus.com)
+
+ * Many files: When warning about suppressed tests due to a
+ nonexistant test binary, avoid incrementing the warning count.
+
+Tue Oct 10 11:00:41 1995 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (TARGET_FLAGS_TO_PASS): Remove BISON.
+
+Sun Oct 8 04:23:14 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/return.exp: Change xfail from "sparc-*-solaris2.*" to
+ "sparc-*-solaris2*".
+
+Sat Sep 23 01:22:23 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/coremaker.c: Produce a full core dump for AIX targets.
+ Add global and local variables and initialize them.
+ * gdb.base/corefile.exp: Test correct mapping of corefile sections
+ by printing variables. Remove rs6000 and powerpc xfails, BFD now
+ extracts the file name and terminating signal from the core file.
+ * TODO: Remove note about tests for correct mapping of corefile.
+ * gdb.base/ptype.c (main): Use boolean2 to inhibit AIX 4.1 xlc
+ from optimizing it away.
+ * gdb.stabs/weird.exp: Remove rs6000 xfail, xcoffread.c now
+ handles common blocks.
+
+Thu Sep 21 01:28:10 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.disasm/sh3.s (fmac): Update for new assembler syntax
+ * gdb.disasm/sh3.exp (fmac): Corresponding changes.
+
+Wed Sep 20 13:15:05 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean): New target, synonym for
+ realclean.
+ * gdb.base/Makefile.in (maintainer-clean): Likewise.
+ * gdb.c++/Makefile.in (maintainer-clean): Likewise.
+ * gdb.chill/Makefile.in (maintainer-clean): Likewise.
+ * gdb.disasm/Makefile.in (maintainer-clean): Likewise.
+ * gdb.stabs/Makefile.in (maintainer-clean): Likewise.
+ * gdb.threads/Makefile.in (maintainer-clean): Likewise.
+
+Sun Sep 10 13:14:01 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/scope.exp (text_at_main): Add "hppa*-*-hpux*"
+ xfails when not gcc compiled for "print foo::funclocal".
+ (test_at_foo): Add "hppa*-*-hpux*" xfails when not gcc compiled for:
+ "print foo::funclocal at foo",
+ "print 'scope1.c'::foo::funclocal at foo",
+ "print foo::funclocal_bss at foo",
+ "print 'scope1.c'::foo::funclocal_bss at foo",
+ "print foo::funclocal_ro at foo",
+ "print 'scope1.c'::foo::funclocal_ro at foo",
+ "print bar::funclocal at foo" and
+ "print 'scope1.c'::bar::funclocal at foo".
+ (test_at_bar): Add "hppa*-*-hpux*" xfails when not
+ gcc compiled for "print foo::funclocal at bar".
+ Expand all messages to ensure that they identify that
+ the test is at bar().
+ * gdb.base/opaque.exp: Add "hppa*-*-hpux*" xfails when not
+ gcc compiled for:
+ "ptype on opaque struct pointer (statically)",
+ "ptype on opaque struct tagname (statically)",
+ "ptype on opaque struct pointer (dynamically) 1",
+ "ptype on opaque struct tagname (dynamically) 1",
+ "ptype on opaque struct pointer (dynamically) 2" and
+ "ptype on opaque struct tagname (dynamically) 2
+ * gdb.base/nodebug.exp: Add "hppa*-*-hpux*" xfails when not
+ gcc compiled for:
+ "p datalocal"
+ "whatis datalocal",
+ "ptype datalocal",
+ "p bsslocal",
+ "whatis bsslocal", and
+ "ptype bsslocal".
+ * gdb.base/langs.exp: Add "hppa*-*-hpux*" xfails for
+ "backtrace in langs.exp" and "up to langs0__2do in langs.exp"
+ when not gcc compiled.
+ * gdb.base/funcargs.exp (float_and_integral_args): Add
+ "hppa*-*-hpux*" xfail for "run to call2a" when not gcc
+ compiled.
+ (discard_and_shuffle): Add "hppa*-*-hpux*" xfail for
+ "backtrace from call6a" when not gcc compiled.
+ (shuffle_round_robin): Add "hppa*-*-hpux*" xfail for
+ "backtrace from call7a" when not gcc compiled.
+ * gdb.base/callfuncs.exp (do_function_calls):
+ Add "hppa*-*-hpux*" xfail when not gcc compiled for
+ "p t_char_array_values(char_array_val2,char_array_val1)",
+ "p t_char_array_values(char_array_val1,char_array_val2)",
+ "p t_char_array_values("carray 1","carray 2")",
+ "p t_char_array_values("carray 1",char_array_val2)",
+ "p t_char_array_values(char_array_val1,"carray 2")",
+ "p sum_args(1,{2})",
+ "p sum_args(2,{2,3})",
+ "p sum_args(3,{2,3,4})",
+ "p sum_args(4,{2,3,4,5})"
+ * gdb.base/corefile.exp: Add "hppa*-*-hpux*" xfail for
+ "backtrace in corefile.exp" when not gcc compiled.
+
+Sat Sep 9 01:35:39 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/signals.exp: Rewrite `handle all print' test as
+ a procedure. Accept blanks or TABs as whitespace, increase
+ timeout and expect input buffer size for the large output
+ from the command. Remove "i*86-*-bsdi2.0" xfail.
+
+Sat Sep 2 06:41:26 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/setvar.exp: Add new testcases for truncation when
+ assigning invalid values to bitfields.
+
+Sat Sep 2 00:17:31 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/callfuncs.exp (do_function_calls): Remove
+ mips-sgi-irix* xfail for
+ "call inferior func with struct - returns char *"
+ and fix test so that an optional (unsigned char *) cast is
+ accepted in the result.
+
+Fri Sep 1 13:42:01 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/funcargs.exp (float_and_integral_args): Remove
+ sparc-sun-solaris2* xfail for "print f1 after run to call2a".
+ * gdb.c++/Makefile.in (SUFFIXES): Add .SUFFIXES and ".cc" suffix.
+ * gdb.base/signals.exp: Remove duplicate "handle all print" test
+ that accidentally got checked in.
+
+Sun Aug 27 23:35:35 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/callfuncs.exp (do_function_calls): Add alpha-dec-osf2*
+ clear_xfail for "p t_float_values2(3.14159,float_val2)" for gcc
+ compiled test.
+ * gdb.base/opaque.exp (setup_xfail_on_opaque_pointer):
+ Add mips-sgi-irix5* xfail for not gcc compiled.
+ * gdb.base/Makefile.in (nodebug.o): Also create nodebug.ci.
+ * gdb.base/nodebug.exp: Add mips-sgi-irix5 xfail when not gcc compiled for
+ "p top", "whatis top", "p middle", and "whatis middle".
+ * gdb.base/whatis.exp: Add mips-sgi-irix* xfail for
+ "whatis signed char" for not gcc compiled.
+ * gdb.base/setvar.exp: Add mips-sgi-irix4* xfail (works on irix5) for
+ "set variable signed char=-1 (-1)" and
+ "set variable signed char=0xFF (0xFF)" for not gcc compiled.
+ * gdb.base/funcargs.exp (float_and_integral_args):
+ Add mips-sgi-irix5* xfail for "run to call2a" for not gcc compiled.
+ Add mips-sgi-irix* xfail when not gcc compiled for
+ "continue to call2b".
+ Add mips-sgi-irix4* xfail (works with irix5) when gcc compiled for
+ "continue to call2g".
+ (discard_and_shuffle): Add mips-sgi-irix5* xfail whn not gcc compiled for
+ "backtrace from call6a"
+ (shuffle_round_robin): Add mips-sgi-irix* xfail when not gcc compiled for
+ "backtrace from call7k".
+ Add mips-sgi-irix5* xfail when not gcc compiled for
+ "backtrace from call7a".
+ (localvars_after_alloca): Fix gdb_test cmds for
+ "print * after runto ...".
+ Remove rs6000-*-* xfails for
+ "print i after runto localvars_after_alloca" and
+ "print l after runto localvars_after_alloca"
+ for all compilers.
+ * gdb.base/exprs.exp: Add mips-sgi-irix4* xfails (works with irix5),
+ when not compiled with gcc, for:
+ "print signed char == (minus)",
+ "print signed char != (minus)",
+ "print signed char < (minus)",
+ "print signed char > (minus)".
+ * gdb.base/callfuncs.exp (do_function_calls):
+ Add mips-sgi-irix* xfail, when compiled with native compiler, for
+ "call inferior func with struct - returns char *".
+ * gdb.base/return.exp (return_tests): Change xfail for
+ "correct value returned double test" to include Solaris 2.4.
+ * gdb.base/funcargs.exp (float_and_integral_args):
+ Add sparc-sun-solaris2* xfail for "print f1 after run to call2a".
+
+Sat Aug 26 00:26:11 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/setvar.c, gdb.base/setvar.exp: Add new tests for
+ enumeration bitfields if compiling with GNU C.
+ * lib/gdb.exp: Consume `(y or n) ' in `Reinitialize source path
+ to empty' prompt.
+
+Tue Aug 22 00:30:37 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.base/scope.exp: xfail 'scope0.c'::filelocal_bss before run
+ test for PRO targets.
+
+ * gdb.base/funcargs.exp: Avoid ever setting more than 8
+ breakpoints in the inferior at any given time by making
+ two groups of breakpoints for call2*, call6* and call7*
+ tests.
+
+Sun Aug 20 06:58:25 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/funcargs.exp: Fix typos introduced by Aug 15 change.
+ * gdb.base/callfuncs.c (main): Use struct_val1 to inhibit xlc
+ from optimizing it away.
+ * gdb.base/callfuncs.exp: Remove rs6000-*-* xfails for
+ "call inferior func with struct".
+
+Wed Aug 16 11:57:15 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.in: Only configure gdb.chill for particular targets.
+
+Tue Aug 15 09:42:44 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/Makefile.in: Add action to .c.o transformation
+ rule that generates a .ci file for each .o file and remove
+ explicit .c.o rules except for callfuncs.o.
+ * gdb.c++/Makefile.in: Add .cc.o transformation rule that
+ generates a .ci file for each .o file and remove explicit
+ .cc.o rules.
+ (clean): Remove *.tmp *.ci files.
+ (EXECUTABLES): Remove templ-info.exp.
+ * gdb.base/compiler.c: New file.
+ * gdb.c++/compiler.cc: New file
+ * gdb.base/scope.exp: Source gdb.base/scope.ci.
+ Change rs6000-*-* xfail for
+ "print 'scope0.c'::filelocal_ro" and
+ "print 'scope1.c'::filelocal" and
+ "print 'scope1.c'::filelocal_bss" and
+ "print 'scope1.c'::filelocal_ro" and
+ "print 'scope1.c'::foo::funclocal" and
+ "print 'scope1.c'::foo::funclocal_ro" and
+ "print 'scope1.c'::bar::funclocal" and
+ "print 'scope0.c'::filelocal_ro" and
+ "print 'scope1.c'::filelocal at foo" and
+ "print 'scope1.c'::filelocal_bss at foo" and
+ "print 'scope1.c'::filelocal_ro at foo" and
+ "print 'scope1.c'::foo::funclocal at foo" and
+ "print 'scope1.c'::foo::funclocal_bss at foo" and
+ "print 'scope1.c'::foo::funclocal_ro at foo" and
+ "print 'scope1.c'::bar::funclocal at foo" and
+ "print 'scope0.c'::filelocal_ro" and
+ "print 'scope1.c'::filelocal" and
+ "print 'scope1.c'::filelocal_bss" and
+ "print 'scope1.c'::filelocal_ro" and
+ "print 'scope1.c'::foo::funclocal" and
+ "print 'scope1.c'::foo::funclocal_bss" and
+ "print 'scope1.c'::foo::funclocal_ro" and
+ "print 'scope1.c'::bar::funclocal" and
+ "print 'scope1.c'::bar::funclocal_bss"
+ to only be xfail'd when not compiled with gcc.
+ Add rs6000-*-* xfail for
+ "print 'scope0.c'::filelocal_bss before run"
+ when compiled with gcc.
+ (test_at_main): Add rs6000-*-* xfail for
+ "print filelocal_ro in test_at_main"
+ when compiled with gcc.
+ * gdb.base/ptype.exp: Source gdb.base/ptype.ci.
+ Add rs6000-*-aix* xfail for
+ "whatis unnamed typedef'd enum (compiler bug in IBM's xlc)" and
+ "ptype t_char_array", not compiled with gcc.
+ * gdb.base/list.exp (test_list_function): Add rs6000-*-*
+ xfail for "list foo (in include file)" when gcc compiled.
+ * gdb.base/funcargs.exp: Source gdb.base/funcargs.ci
+ (integral_args): Add rs6000-*-* xfail for
+ "run to call0a" if not compiled with gcc.
+ (unsigned_integral_args): Add rs6000-*-* xfail for
+ "run to call1a" if not compiled with gcc.
+ (float_and_integral_args): Add rs6000-*-* xfail for
+ "run to call2a" if not compiled with gcc and for
+ "continue to call2b" for any compiler.
+ Add rs6000-*-* xfail to
+ "print f1 after run to call2a" for gcc compiled.
+ (discard_and_shuffle): Add rs6000-*-* xfail for
+ "run to call6a".
+ (shuffle_round_robin): Add rs6000-*-* xfail for
+ "backtrace from call7a" if not compiled with gcc.
+ Add rs6000-*-* xfail for
+ "backtrace from call7b" if compiled with gcc.
+ (call_after_alloca): Add rs6000-*-* xfail for
+ "print c in call_after_alloca" and
+ "print s in call_after_alloca" and
+ "backtrace from call_after_alloca_subr"
+ if not compiled with gcc.
+ (localvars_in_indirect_call): Add rs6000-*-* xfail for
+ "print c in localvars_in_indirect_call" and
+ "print c in localvars_in_indirect_call" and
+ "backtrace in indirectly called function" and
+ "stepping into indirectly called function"
+ if not compiled with gcc.
+ (localvars_after_alloca): Add rs6000-*-* xfail for
+ "print c after runto localvars_after_alloca" and
+ "print s after runto localvars_after_alloca" and
+ "print i after runto localvars_after_alloca" and
+ "print l after runto localvars_after_alloca"
+ for all compilers.
+ * gdb.base/whatis.exp: Source gdb.base/whatis.ci rather
+ than whatis-info.exp.
+ * gdb.base/opaque.exp: Source gdb.base/opaque0.ci rather
+ than opaque-info.exp.
+ Setup rs6000-*-* xfail for
+ "ptype on opaque struct pointer (statically)" and
+ "ptype on opaque struct pointer (dynamically)" when
+ not compiled with gcc.
+ * gdb.base/callfuncs.exp: Source gdb.base/callfuncs.ci
+ rather than callf-info.exp.
+ (do_function_calls): Add clear_xfail for rs6000-*-* for
+ "p t_float_values2(3.14159,float_val2)". Seems to work
+ fine there, both with xlc and gcc. Need to find out what
+ it is doing right and fix other platforms.
+ * gdb.base/callfuncs.exp: Add rs6000-*-* xfail for
+ "call inferior func with struct - returns int",
+ "call inferior func with struct - returns long",
+ "call inferior func with struct - returns float",
+ "call inferior func with struct - returns double",
+ "call inferior func with struct - returns char *",
+ but only if not gcc compiled (presumes xlc compiled).
+ Change rs6000-*-* xfails for
+ "call inferior func with struct - returns char" and
+ " call inferior func with struct - returns short" to only
+ xfail if not using gcc.
+ (clean mostlyclean): Remove *.ci and *.tmp files.
+ * gdb.c++/templates.exp: Source gdb.c++/templates.ci rather
+ than templ-info.exp.
+ * gdb.base/langs.exp: Source gdb.base/langs.ci.
+ Add rs6000-*-* xfail for "up to foo in langs.exp"
+ "up to cppsub_ in langs.exp" and "up to fsub in langs.exp"
+ when not gcc compiled.
+
+Sat Aug 12 15:05:36 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * gdb.base/callfuncs.exp: Add xfails for the powerpc.
+ * gdb.base/corefile.exp: Likewise.
+ * gdb.base/list.exp: Likewise.
+ * gdb.base/scope.exp: Likewise.
+ * gdb.base/siganls.exp: Likewise.
+
+ * gdb.base/nodebug.exp: Add xfails for the powerpc. Handle aix4
+ compiler output.
+ * gdb.base/whatis.exp: Likewise.
+
+Fri Aug 11 13:36:20 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.disasm/sh3.exp (all_fp_misc_tests): No longer expect a
+ failure (opcode table has been fixed to match reality).
+
+Mon Aug 14 09:01:59 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/callfuncs.exp: Add rs6000-*-* xfails for
+ "call inferior func with struct - returns char",
+ "call inferior func with struct - returns short"
+
+ * gdb.base/scope.exp: Remove rs6000-*-* xfails for
+ "print 'scope0.c'::filelocal at main",
+ "print 'scope0.c'::filelocal_bss in test_at_main",
+ "print 'scope0.c'::filelocal at foo",
+ "print 'scope0.c'::filelocal_bss in test_at_foo",
+ "print 'scope0.c'::filelocal at bar",
+ "print 'scope0.c'::filelocal_bss in test_at_bar"
+
+ * gdb.base/list.exp: Remove rs6000-*-* xfail for "list function
+ in source file 1". This bug seems to have been fixed with both
+ gcc and native cc (was native assembler bug?).
+
+Wed Aug 9 08:04:12 1995 Fred Fish (fnf@cygnus.com)
+
+ * gdb.base/a1-selftest.exp: Change "i*86-*-sysv4" xfail for
+ "backtrace through signal handler" to "i*86-*-sysv4*".
+ * gdb.base/signals.exp: Add xfail for "'next' behaved as
+ continue" case. Add "known SVR4 bug" to fail message.
+ Add "i*86-*-bsdi2.0" xfail for "handle all print".
+ Add "i*86-*-bsdi2.0" xfail for "backtrace in signals_tests_1".
+ * gdb.base/ptype.exp: Add "i*86-*-sysv4*" xfail for
+ "whatis unnamed typedef'd enum..." and "ptype t_char_array".
+ * gdb.base/langs.exp: Add "i*86-*-sysv4*" xfail for
+ "up to foo in langs.exp", "show language at foo in
+ langs.exp", "up to cppsub_ in langs.exp", "show
+ language at cppsub_ in langs.exp", "up to fsub in
+ langs.exp", and "show language at fsub in langs.exp".
+ * gdb.base/corefile.exp: Add "i*86-*-sysv4*" to xfail for
+ "bactrace in corefile.exp".
+ * gdb.base/callfuncs.exp: Change xfail to "i*86-*-*" for
+ "call inferior function with struct - returns float" and
+ "call inferior function with struct - returns double".
+
+Mon Aug 7 02:43:28 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.disasm/sh3.s: Source for sh3 disassembler tests.
+ * gdb.disasm/sh3.exp: Run the sh3 disassembler tests.
+ * gdb.disasm/configure.in (sh-*-*): Use sh3.mt makefile fragment.
+ * gdb.disasm/sh3.mt: Makefile fragment for sh3 ests.
+
+Mon Aug 7 08:09:37 1995 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (CHILL_FOR_TARGET): Use previously defined
+ (or overriden) "CHILL" macro rather then bare "gcc".
+ Also look for ../../gcc/xgcc since that is what we will
+ actually need, not "Makefile". Remove following assignment
+ of CHILL to CHILL_FOR_TARGET because that results in
+ recursive definition.
+
+Sun Aug 6 16:52:29 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/corefile.exp: Change xfail for backtrace in
+ corefile.exp from linuxaout to all linux.
+ * gdb.base/sigall.exp (test_one_sig): Specifically deal with
+ cases where we miss the breakpoint at the signal handler
+ for some reason. Setup xfail for linuxoldld/linuxaout and
+ getting SIGIO. Setup xfail for linuxoldld/linuxaout for
+ hitting SIGURG breakpoint.
+ * gdb.base/signals.exp: Setup xfail for "next" acting like
+ continue to add linuxoldld. Setup xfail for all linux for
+ "next to handler in signals_tests_1", "backtrace in
+ signals_tests_1", "continue to func1", "pass SIGUSR1",
+ and continue to handler".
+
+Thu Aug 3 10:45:37 1995 Fred Fish <fnf@cygnus.com>
+
+ * Update all FSF addresses except those in COPYING* files.
+
+Sun Jul 30 17:50:35 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/a2-run.exp: Change messages to be more explicit about
+ the status of args, and quote binfile in results.
+
+Sun Jul 30 10:24:20 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/callfuncs.exp: Add tests for passing structs to
+ inferior functions and return various types.
+ * gdb.base/callfuncs.c: Add functions to receive a struct
+ and return a member of the struct, in various types.
+
+Sat Jul 29 14:22:33 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/Makefile.in (clean): Remove callf-info.exp.
+
+Fri Jul 28 13:36:11 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * config/vxworks29k.exp: New file, sources vxworks.exp.
+
+Fri Jul 28 00:28:36 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * config/gdbremote.exp: New file. Testing framework using
+ gdbserver.
+
+Thu Jul 27 12:17:14 1995 Fred Fish (fnf@cygnus.com)
+
+ * gdb.base/interrupt.exp: Setup "i*86-*-linux" xfail for
+ "call function when asleep" and "send end of file".
+ * gdb.base/corefile.exp: Add "i*86-*-linuxaout" to xfail list
+ for "backtrace in corefile.exp".
+ * gdb.base/a1-selftest.exp: Add "i*86-*-linux*" to xfail list
+ for "backtrace through signal handler".
+ * gdb.base/corefile.exp: Make sure we actually generate a core file
+ before trying the core tests. Some systems allow the user to suppress
+ generation of core files and default to that (linux for example).
+ * gdb.base/signals.exp: Change xfail for "next" acting like "continue"
+ from "i*86-*-linux" to "i*86-*-linuxaout". Works with ELF beta.
+
+Tue Jul 25 17:30:10 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * gdb.threads: New directory with some crude multi-threaded
+ gdb tests (step.exp and step2.exp).
+ * config/mt-lynx (STEP_EXECUTABLE): Define.
+ (THREADFLAGS): Define.
+
+Tue Jul 25 01:03:52 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.base/sigall.exp: Avoid losing in SIGPRIO test on lynx.
+
+ * gdb.base/signals.exp: Disable whole file for lynx until
+ further notice.
+
+ * gdb.base/signals.exp: xfail test where "next" acts like
+ "continue" for lynx.
+
+ * gdb.base/interrupt.exp: xfail test for calling function while
+ inferior is asleep for lynx.
+
+ * gdb.base/watchpoint.exp: Handle more cases of gdb echoing more
+ than one cr-lf after each command.
+
+Sun Jul 23 23:33:18 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * configure.in: Reinstate setting of stabsdirs variable, fix
+ typo in setting up configdirs for native builds.
+
+ * gdb.base/return.exp: Fix typo in return double test.
+ * gdb.base/return.c (tmp2, tmp3): Made global to inhibit the
+ compiler from optimizing them away.
+
+Fri Jul 21 11:39:34 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.base/gdbvars.exp: Expect zero or more additional cr-lf
+ sequences to be echo'd by gdb when using gdb_test.
+ * gdb.chill/chexp.exp: Likewise.
+ * gdb.fortran/exprs.exp: Likewise
+
+Thu Jul 20 13:28:36 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * gdb.base/a1-selftest.exp: Reset the timeout value to 30 seconds
+ after the inferior gdb has started.
+
+ * gdb.base/a2-run.exp: Handle gdb echoing more than one cr-lf
+ after each command.
+ * gdb.base/funcargs.exp: Likewise.
+ * gdb.base/gdbvars.exp: Likewise.
+ * gdb.base/interrupt.exp: Likewise.
+ * gdb.base/list.exp: Likewise.
+ * gdb.base/watchpoint.exp: Likewise.
+ * gdb.c++/demangle.exp: Likewise.
+ * gdb.c++/inherit.exp: Likewise.
+ * gdb.chill/chexp.exp: Likewise.
+ * gdb.fortran/exprs.exp: Likewise.
+
+ * gdb.base/watchpoint.exp: Disable watchpoint triggered in syscall
+ test if we can't handle IO to/from the inferior.
+
+ * gdb.c++/misc.exp: Always check for a program already being
+ started after sending a "run" command to gdb.
+
+ * gdb.base/twice.exp: Start with a fresh gdb.
+
+ * gdb.chill/chexp.exp: Remove skip_chill_tests check; these tests
+ only depend on gdb's expression code, not the chill runtime.
+
+ * gdb.base/return.c: Put return values into variables so we
+ can have gdb print them rather than depending on the program
+ to print them.
+ * gdb.base/return.exp: Corresponding changes.
+
+ * lib/gdb.exp: Provide default value for noinferiorio.
+ * gdb.base/interrupt.exp: Skip tests if we can't handle IO to/from
+ the inferior.
+
+ * gdb.base/break.exp: Always check for a program already being
+ started after sending a "run" command to gdb.
+ (text_next_with_recursion): Don't check the output from the
+ program's printf statement. Instead just make sure the program
+ exited.
+
+ * gdb.base/commands.exp: Protect tests which need arguments with
+ $noargs conditionals.
+
+Wed Jul 19 22:42:43 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/printcmds.exp: Adjust expect patterns for addresses
+ of structure member arrays to match gdb/valops.c:value_addr change.
+
+Mon Jul 17 10:12:27 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.base/a1-selftest.exp: Fix unmatched quotes in many timeout
+ cases.
+
+Wed Jul 12 10:20:08 1995 Fred Fish (fnf@cygnus.com)
+
+ * configure.in (configdirs): Remove gdb.chill from default list
+ of subdirs and then add it back in only if doing a native build.
+ The current chill compiler does not yet work in any cross build.
+ * Revert all signal changes from Jul 6.
+ * gdb.base/{sigall.c signals.c}: Define away signal() and alarm()
+ for sh-hms targets, allowing these tests to link, with no other
+ changes. Testing is suppressed by setting "nosignals" in site.exp.
+
+Thu Jul 6 20:58:30 1995 Fred Fish (fnf@cygnus.com)
+
+ * configure.in (signaldirs): Define and add to configdirs for all
+ targets except some specific ones that are known to not support signals.
+ Also clean up formatting.
+ * gdb.base/Makefile.in (EXECUTABLES): Remove sigall and signals.
+ (signals, sigall): Remove rules to build.
+ * gdb.base/{sigall.c, sigall.exp, signals.c, signals.exp}:
+ Moved to new gdb.signals directory.
+ * gdb.signals: New test directory.
+ * gdb.signals/{Makefile.in, configure.in, sigall.c, sigall.exp,
+ signals.c signals.exp}: New or moved files.
+
+Sun Jun 25 12:55:18 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.base/interrupt.exp: Don't choke if $nointerrupts doesn't exist.
+
+Wed Jun 21 16:35:55 1995 Fred Fish <fnf@cygnus.com>
+
+ * gdb.base/return.exp: Xfail `return double' test failure
+ on at least Solaris 2.3 and handle future/past versions on
+ a case by case basis as appropriate. Also update message
+ to include i*86 failures.
+
+Wed May 24 07:10:10 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in: Change variable CFLAGS to TESTSUITE_CFLAGS.
+
+ * lib/gdb.exp: Fix comment which erroneously identified
+ gdb_file_cmd as gdb_load (the 19 May change was in fact to
+ gdb_file_cmd not gdb_load).
+ * config/unix-gdb.exp (gdb_load): Add "upvar timeout timeout".
+
+ * gdb.base/setvar.exp: Make test names consistent between pass and
+ fail cases. Use gdb_test more.
+
+Fri May 19 07:22:58 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * lib/gdb.exp (gdb_load): Add "upvar timeout timeout".
+
+Mon May 15 23:50:51 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/help.exp: Fix expected help string for `show commands'.
+
+Thu May 11 07:55:11 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * gdb.stabs/xcoff.sed: Change N_LSYM to C_DECL not C_LSYM.
+
+ * gdb.stabs/weird.exp: Remove xfail for xcoff bitching about lack
+ of a text section.
+
+Thu May 11 15:02:24 1995 Stu Grossman (grossman@andros.cygnus.com)
+
+ * config/monitor.exp (gdb_target_monitor): Fix loop interator so
+ that loop eventually terminates. Fix Connection refused logic so
+ that testsuite will expire nicely.
+
+Wed May 10 17:57:35 1995 Stu Grossman (grossman@andros.cygnus.com)
+
+ * config/cpu32bug.exp, config/est.exp, config/hppro.exp,
+ config/rom68k.exp: New tcl glue for the appropriate monitors.
+ These all just end up calling monitor.exp.
+ * config/monitor.exp (gdb_target_monitor): Handle `Connection
+ refused' by retrying. Cleanup some timeout issues.
+ * (gdb_load): Reduce timeout. Cleanup some timeout issues.
+ * lib/gdb.exp (gdb_test gdb_test_exact): Upvar timeout so that
+ callers don't have to set/restore global timeout variable.
+
+ * The following set of changes centralizes management of the global
+ timeout variable. This way, it can be set in one target dependent
+ place instead of dozens of places scattered throughout the test suite.
+ If you need to lengthen a timeout, then you should either set timeout
+ in one of the config/{target}.exp files, or multiply it by a factor.
+ Setting it to an absolute value is always going to lose for some
+ targets.
+ * gdb.base/a1-selftest.exp (test_with_self): Only use local timeout.
+ * gdb.base/callfuncs.exp (do_function_calls): Don't set timeout.
+ * gdb.base/funcargs.exp: Don't set timeout.
+ * gdb.base/list.exp (test_forward_search): Only use local timeout.
+ * gdb.base/printcmds.exp (test_print_string_constants
+ test_print_array_constants): Don't set timeout.
+ * gdb.base/ptype.exp: Don't set timeout.
+ * gdb.base/recurse.exp: Don't set timeout.
+ * gdb.base/return.exp: Don't set timeout.
+ * gdb.base/watchpoint.exp: Don't set timeout.
+ * gdb.c++/classes.exp (do_tests): Don't set timeout.
+ * gdb.c++/virtfunc.exp (test_virtual_calls): Don't set timeout.
+
+Wed May 10 16:03:23 1995 Torbjorn Granlund <tege@adder.cygnus.com>
+
+ * Makefile.in: Make clean targets work also when SUBDIRS is empty.
+
+Mon May 1 07:32:48 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * lib/gdb.exp: Disable chill tests for irix5.
+
+Wed Apr 26 07:36:03 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/scope.exp: Make test names unique. Use gdb_test. Make
+ each test pass or fail.
+
+Sun Apr 23 21:32:32 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/opaque.exp: Remove xfails for aix; print a warning if
+ xlc not gcc.
+
+Fri Apr 21 15:44:02 1995 Stu Grossman (grossman@rtl.cygnus.com)
+
+ * cpu32bug.exp est.exp rom68k.exp: Delete. Unify into monitor.exp.
+
+Wed Apr 19 17:41:21 1995 Stu Grossman (grossman@cygnus.com)
+
+ * config/est.exp: Fix copyright and comments. Remove dead code.
+ Use targetname, serialport and baud variables instead of fixed
+ constants.
+ * config/rom68k.exp: Fix copyright and comments. Remove dead code.
+ * config/cpu32bug.exp: New file to support cpu32bug monitors.
+
+Wed Apr 19 13:47:16 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/watchpoint.exp: Don't run
+ test_watchpoint_triggered_in_syscall for sunos.
+
+Mon Apr 17 12:48:52 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/{break.c,run.c}: Don't include vxWorks.h or stdioLib.h;
+ they don't seem to exist. Do include stdio.h.
+
+Fri Apr 14 09:40:22 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/a1-selftest.exp: Add alpha xfail.
+
+Mon Apr 10 13:07:50 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/watchpoint.c (main): Prompt before calling read().
+ * gdb.base/watchpoint.exp (test_watchpoint_triggered_in_syscall):
+ Revise accordingly. Remove cruft about sending "123" several
+ times, until it gets noticed. Clean up the "print buf[0]" stuff
+ so that it passes or fails, and waits for prompts in the usual way.
+
+Sun Apr 9 09:02:36 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/recurse.exp: Fix comment.
+
+ * TODO: Remove item about printing variables in nodebug.exp. Add
+ item about enabling tests which are only run on some targets.
+
+ * gdb.base/watchpoint.exp: Various cleanups (make each test pass or
+ fail, make test names unique, use new gdb_test convention
+ regarding pattern, use gdb_test more, etc.).
+
+ * gdb.base/bitfields.exp: Various cleanups (make each test pass or
+ fail, make test names unique, etc.).
+
+Sat Apr 8 02:47:45 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/nodebug.c: Change return type of top and middle to
+ short.
+ * gdb.base/nodebug.exp: Remove xfails for ecoff systems, they
+ are fixed by the recent mdebugread.c changes. Allow `short ()'
+ as type for top and middle.
+
+Thu Apr 6 08:54:18 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/break.exp: Remove commented out if $usestubs {}. As
+ nearly as I can tell, the whole thing was an accident in Stu's
+ change of 24 Mar 1995 (logged in ../ChangeLog), in which he meant
+ to replace a send/expect pair with gdb_test, but ended up only
+ adding the gdb_test. My change of 24 Mar 1995 and Kung's change
+ of 30 Mar 1995 took care of it, but left this vestigial comment
+ which I am now nuking.
+
+Mon Apr 3 09:00:27 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/break.exp: Look for different line number for
+ breakpoint at main depending on usestubs.
+
+Sun Apr 2 08:15:45 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/list.exp: Adjust some alternate expect patterns to
+ match recent list0.c change. Add alternate expect pattern for
+ output from `list default lines around main' for optimizing
+ compilers.
+
+Sat Apr 1 07:23:22 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * lib/gdb.exp: If nosignals is not set, set it to 0.
+
+Fri Mar 31 16:13:48 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * config/slite-gdb.exp: Responds to load symbol table prompt.
+ * gdb.base/break.exp: Adjust line number, fix rerun.
+ * gdb.base/langs0.c: Add #ifdef usestubs.
+
+Thu Mar 30 15:36:55 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * gdb.base/list.exp: Adjust line contents after adding new lines in
+ list0.c. Also fix a syntax error.
+
+ * lib/gdb.exp (gdb_run_cmd): Special handling for targets use stubs.
+ * gdb.base/break.exp: ditto.
+ * gdb.base/list.exp: ditto.
+ * gdb.base/bitfields.c: Add #ifdef usestubs in main().
+ * gdb.base/run.c: ditto.
+ * gdb.base/list0.c: ditto.
+ * gdb.base/funcargs.c: ditto.
+
+Wed Mar 29 17:09:29 1995 Stu Grossman (grossman@cygnus.com)
+
+ * testsuite/config/rom68k.exp (gdb_target_rom68k): Use
+ $targetname, $serialport and $baud instead of hardwired variables.
+ * testsuite/gdb.base/{sigall.exp signals.exp}: Skip these if the
+ target doesn't support signals.
+
+Wed Mar 29 12:29:34 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * lib/gdb.exp (runto_main): Fix regular expression bug, add return 1.
+
+Tue Mar 28 08:46:45 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/recurse.exp: Make test names unique. Change \\(+ to \\(.
+ Don't rely on the value of an auto variable before it has been
+ initialized. Use gdb_test more.
+
+Mon Mar 27 08:00:34 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * lib/gdb.exp (default_gdb_version): A version number must start
+ with a digit, but other than that contains all characters up to
+ the first whitespace character.
+
+Sun Mar 26 13:19:32 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/commands.exp (breakpoint_command_test): New tests.
+
+Sat Mar 25 15:38:06 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.c++/*.exp: Warn if executable does not exist. The original
+ reason for skipping the warning was that configure.in sometimes
+ intentionally skipped building the executables but the tcl code
+ had no way of knowing. That (a) was always bogus with respect to
+ error handling, (b) is no longer true (right now there is no way
+ to skip C++ tests).
+
+ * gdb.c++/demangle.exp: Remove unused binfile and srcfile variables.
+
+Sat Mar 25 01:16:10 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/list.exp: Add expect patterns for output from
+ SunPRO compiled executables.
+ * gdb.base/whatis.exp: Allow leading `signed' for all v_signed_*
+ types.
+
+Fri Mar 24 06:11:05 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/break.exp (test_next_with_recursion): Accept any line
+ number (we are already testing that the correct source line text
+ gets printed).
+
+ * gdb.base/break.exp: Make one test if $usestubs. I'm not sure
+ that is what is intended, but something needed to be done to get
+ sunos4 native working again.
+
+ * gdb.c++/misc.cc (main): Fix typo (#iffef -> #ifdef).
+
+ * gdb.base/a1-selftest.exp (test_with_self): Remove comment which
+ apparently went with a (very) old xfail.
+
+Fri Mar 24 13:41:09 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * gdb.base/callfuncs.exp: call runto_main instead of runto main.
+ runto_main is a proc in gdb.exp that will do 'step' for target use
+ stubs.
+ * gdb.base/exprs.exp: ditto.
+ * gdb.base/interrupt.exp: ditto.
+ * gdb.base/opaque.exp: ditto.
+ * gdb.base/printcmds.exp: ditto.
+ * gdb.base/ptype.exp: ditto.
+ * gdb.base/scope.exp: ditto.
+ * gdb.base/setvar.exp: ditto.
+ * gdb.base/signals.exp: ditto.
+ * gdb.base/twice.exp: ditto.
+ * gdb.c++/classes.exp: ditto.
+ * gdb.c++/inherit.exp: ditto.
+ * gdb.c++/templates.exp: ditto.
+ * gdb.base/break.exp: no run and hit main for stubs. Change line
+ numbers for breakpoints and info breakpoint.
+ * gdb.base/break.c: Add #ifdef usestubs for set_debug_traps() and
+ breakpoint().
+ * gdb.base/callfuncs.c: ditto.
+ * gdb.base/exprs: ditto.
+ * gdb.base/interrupt.c: ditto.
+ * gdb.base/opaque0.c: ditto.
+ * gdb.base/printcmds.c: ditto.
+ * gdb.base/ptype.c: ditto.
+ * gdb.base/scope0.c: ditto.
+ * gdb.base/setvar.c: ditto.
+ * gdb.base/signals.c: ditto.
+ * gdb.base/twice.c: ditto.
+ * gdb.c++/misc.cc: ditto.
+ * gdb.c++/templates.cc: ditto.
+
+Fri Mar 24 06:11:05 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/vx-gdb.exp, lib/gdb.exp: Regexp cleanups (\[(\] -> \\(, etc.).
+
+ * gdb.base/a1-selftest.exp: Don't check for # followed by a digit
+ somewhere between `read' and `main.c'. I'm pretty sure the
+ pattern ".*#\[0-9\].*" was slowing down pattern matching a lot,
+ and it isn't particularly useful.
+
+ * gdb.base/scope.exp: Make test names unique. \[(\] -> \\(.
+
+Thu Mar 23 14:58:35 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/commands.exp (infrun_breakpoint_command_test): New test.
+
+Wed Mar 22 18:36:05 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * config/mt-slite: add LIBS and -nostdlib.
+ * config/slite-gdb.exp: add this new file to support sparclite target.
+
+Tue Mar 21 21:41:04 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/vx-gdb.exp (gdb_load): Update test of vxworks_ld return code.
+
+ * gdb.base/a2-run.exp: Change argument to istarget from
+ "*-*-vxworks" to "*-*-vxworks*".
+ * gdb.base/{break.exp,default.exp,scope.exp}: Likewise.
+
+Tue Mar 21 17:08:47 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * lib/gdb.exp: add proc runto_main, for targets that use stubs, this
+ will not runto main but do a 'step' to step out of breakpoint().
+ * config/mt-slite: add -Dusestubs.
+
+Tue Mar 21 12:14:12 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/printcmds.exp (test_artificial_arrays): Send ^V@
+ instead of just @.
+
+ * gdb.base/signals.exp: Add test for "handle all print".
+ * TODO: Remove "handle all print". Also remove item about
+ checking copyright date (I don't like the idea of a spurious FAIL
+ based on when we run the tests).
+
+ * gdb.base/recurse.exp: Enable test for SunOS4. xfail one test
+ for SunOS4 (reason for failure not investigated). Remove
+ redundant test for $binfile.
+
+ * gdb.base/nodebug.c (array_index): Call malloc.
+
+ * gdb.base/{corefile.exp,default.exp}: Make names of "up" tests unique.
+
+Mon Mar 20 10:08:17 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.base/recurse.exp: Update gdb_test invocation to use new
+ conventions and slightly simplify the matching regexp.
+
+Fri Mar 17 05:43:28 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/break.exp: Update gdb_test invocation to use new
+ convention.
+
+ * lib/gdb.exp: If noargs is not set, set it to 0.
+
+ * gdb.base/nodebug.exp: Comment out redundant test. Make name of
+ tests unique.
+
+ * lib/gdb.exp: Skip CHILL for AIX and Solaris.
+
+Thu Mar 16 16:27:07 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/nodebug.exp: It is OK if GDB thinks top and middle have
+ one argument of type "<non-float parameter>".
+
+Wed Mar 15 15:54:56 1995 Stu Grossman (grossman@cygnus.com)
+
+ * config/rom68k.exp: New file to support Motorola IDP board.
+ * gdb.base/a2-run.exp: Skip this file if noargs is set.
+ * gdb.base/break.c: Change things around so that this program
+ doesn't depend upon args. This is necessary to make remote
+ targets work (in general, they can't take args).
+ * gdb.base/break.exp: Don't try to send args to program. Don't
+ expect output. Also, replace lots of code with gdb_test.
+
+Wed Mar 15 04:11:14 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/printcmds.exp (test_character_literals_accepted): Test
+ printing of '\'' (which is what the comment says we are testing,
+ even though we were not), not '''.
+ (test_integer_literals_rejected): Test that printing ''' is an error.
+
+ * gdb.fortran/exprs.exp, gdb.fortran/types.exp,
+ gdb.chill/chexp.exp, gdb.base/printcmds.exp,
+ gdb.c++/cplusfuncs.exp, gdb.chill/callch.exp, gdb.chill/misc.exp,
+ gdb.chill/pr-6292.exp, gdb.chill/string.exp, gdb.chill/tuples.exp:
+ Use gdb_test not test_print_accept.
+ * lib/gdb.exp: Remove test_print_accept.
+
+ * gdb.base/signals.exp (signal_tests_1): Make pass message
+ consistent with fail message.
+
+ * gdb.base/whatis.exp: Remove xfails for printing char vs.
+ unsigned char; the bug (PR 1821) is fixed.
+
+ * gdb.base/scope.exp: Remove xfails for PRs 1843 and 1868.
+
+ * gdb.base/scope.exp (test_at_localscopes): Call pass for
+ successful tests--makes xfailing them work right.
+
+Tue Mar 14 07:39:19 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * lib/gdb.exp (gdb_test): Between $pattern and $prompt, expect
+ only \r\n, not .*. The test can pass .* as the last thing in
+ $pattern if that is what it wants. In addition to providing this
+ flexibility, this change should speed up pattern matching in cases
+ where the pattern already ended with .* (there were a number of
+ them). This change also helps catch bad patterns--in the old
+ scheme the typo "char \*" instead of "char \\*" would pass. Now
+ it is caught.
+ * Many .exp files: Update callers.
+
+ * gdb.base/funcargs.exp: Replace \[(\]+ with \\(. The latter is
+ clearer and does not spuriously match multiple ('s. Likewise for
+ ) and *.
+
+ * gdb.base/nodebug.exp: Test ability to call a function and pass
+ it a string (even with no debugging info).
+
+ * gdb.base/printcmds.exp (test_integer_literals_rejected): Change
+ "p '\'", which is the same as "p ''" once tcl gets done with
+ quoting, to "p '\\'", which I suspect is what is intended (one
+ backslash gets sent to GDB).
+
+ * gdb.base/printcmds.exp (test_artificial_arrays): New tests.
+
+Fri Mar 10 13:31:46 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/a1-selftest.exp: Remove xfail for solaris. The bug (PR
+ 1817) was fixed literally years ago.
+
+Fri Mar 10 02:49:40 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/funcargs.exp (call_after_alloca): Remove `next'
+ test, it causes stepping out of call_after_alloca_subr with
+ optimizing compilers.
+ (localvars_in_indirect_call): Consume GDB prompt if `finish'
+ fails.
+
+ * gdb.c++/templates.exp: Source templ-info.exp only if
+ the templates executable exists.
+
+ * gdb.c++/misc.cc (class Contains_static_instance,
+ class Contains_nested_static_instance),
+ gdb.c++/classes.exp (test_static_members): Test printing of
+ a class that contains a static instance of the class.
+
+Thu Mar 9 11:43:55 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/langs2.c (cppsub_): Don't prototype.
+ * gdb.base/langs2.cxx (cppsub_): Fix prototype (cosmetic value
+ only, I believe).
+
+Wed Mar 8 10:29:33 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * lib/gdb.exp (skip_chill_tests): New procedure.
+
+ * gdb.base/signals.exp (signal_tests_1): xfail for irix.
+
+Mon Mar 6 10:44:06 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.disasm/hppa.exp: Delete redundant ".*" at the beginning of
+ each expect pattern. Cuts runtime from 12 to about 4 seconds.
+
+Thu Mar 2 05:31:34 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/langs.exp: Don't insist that foo__Fi be demangled.
+
+ * gdb.disasm/hppa.exp (all_fpu_comparison_tests): Only
+ disassemble 8, not 16, instructions for part 4.
+
+ * config/vx-gdb.exp (gdb_start): Use \030, not \CX. tcl doesn't
+ support the latter anymore.
+
+ * gdb.base/Makefile.in: Try compiling callfuncs.c, if that fails try
+ -DNO_PROTOTYPES.
+ * gdb.base/callfuncs.c: Control use of prototypes based on
+ NO_PROTOTYPES, not __STDC__.
+ * gdb.base/callfuncs.exp (do_function_calls): xfail one of the
+ t_float_values2 tests if prototypes in use.
+
+ * gdb.base/callfuncs.c (t_float_values, t_float_values2,
+ t_double_values): When checking differences against DELTA, check
+ that difference is within the range (-DELTA,DELTA), not just
+ (-infinity,DELTA).
+
+Tue Feb 28 16:28:54 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * config/mips-gdb.exp (gdb_load): In every test case, we need to do
+ 'file' command firts, then 'target', then 'load', this is due to gdb
+ target set up.
+ * config/mips-gdb.exp: Fix a couple regular exp bugs.
+
+Thu Feb 23 17:44:55 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.disasm/hppa.s (fmemLRbug_tests): Add tests for the indexing
+ FP load/store variants.
+ * gdb.disasm/hppa.exp (fmemLRbug_tests): Test new variants.
+
+Wed Feb 22 18:29:08 1995 Jim Kingdon <kingdon@rtl.cygnus.com>
+
+ * gdb.base/term.exp: Do not give a warning if not native, it is
+ not an abnormal condition.
+
+Tue Feb 21 13:08:47 1995 Jim Kingdon <kingdon@cygnus.com>
+
+ * gdb.base/ptype.exp: Accept char[0] as well as char[] for "ptype
+ t_char_array".
+
+Sun Feb 19 13:10:06 1995 Jim Kingdon <kingdon@rtl.cygnus.com>
+
+ * lib/gdb.exp (default_gdb_version): Pass GDBFLAGS to gdb when we
+ are getting the version number.
+
+ * gdb.base/{a1-selftest.exp,corefile.exp}: Do not give a warning
+ if not native, it is not an abnormal condition.
+
+Thu Feb 16 15:56:56 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * lib/gdb.exp: Just use "file exists", rather than undocumented
+ dejagnu procedure "findfile".
+
+Thu Feb 16 10:30:24 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/mt-vxworks (CFLAGS): Set to -g -Dvxworks.
+ (LDFLAGS): Set to -Xlinker -Ur.
+
+ * Makefile.in, gdb.{base,c++,chill}/Makefile.in (GDB, GDBFLAGS):
+ Removed, these values are set by lib/gdb.exp.
+
+ * lib/gdb.exp: If GDBFLAGS is unset, set it to -nx.
+
+Wed Feb 15 14:23:28 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/vx-gdb.exp (spawn_vxgdb): Use default_gdb_start instead
+ of replicating gdb startup code.
+
+ * config/mt-vxworks (LDFLAGS): Set to -r.
+ (CFLAGS_FOR_TARGET): Removed.
+
+ * config/vx-gdb.exp: always set prompt; gdb.exp sets it to
+ (gdb) and gdb for vxworks uses (vxgdb).
+
+ * Makefile.in, gdb.{base,c++,chill}/Makefile.in (GDB): If a gdb
+ executable is not in the tree and host != target, use sed and
+ program_transform_name to determine the gdb name used by the
+ target.
+
+ * configure.in, gdb.{base,c++,chill}/configure.in: changed so
+ *-*-vxworks* matches vxworks and *-*-netware* matches NetWare.
+
+Sun Feb 12 08:11:58 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/{callfuncs.exp,callfuncs.c}: Add tests for passing
+ floats, chars, and shorts where there are ANSI-style function
+ definitions.
+
+ * gdb.base/langs.exp, gdb.base/langs*: New test.
+ * gdb.base/Makefile.in: Build it.
+ * TODO: Remove item about checking that C names don't get C++
+ demangling applied; this test tests it.
+
+Thu Feb 9 12:43:56 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.stabs/weird.exp: Remove "Haven't examined" comment which
+ went with the const70 xfail. The xfail went away a year ago.
+
+ * gdb.base/signals.exp: Rename a bunch of tests to give unique names.
+
+ * gdb.base/corefile.exp: Give backtrace test unique name. xfail
+ for hp300.
+
+ * gdb.base/interrupt.exp: Also xfail hpux (for hp300).
+
+ * gdb.base/a1-selftest.exp: Don't run on hp300.
+
+Sat Feb 4 15:04:32 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (site.exp): Set host_alias and target_alias as well
+ as host_triplet and target_triplet.
+
+Wed Feb 1 08:03:48 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/a1-selftest.exp: Invoke stty before starting inferior.
+
+ * gdb.base/nodebug.exp: Add xfails for ultrix and irix5 (same
+ places as other ecoff systems).
+
+ * gdb.base/a1-selftest.exp (test_with_self): Don't invoke stty on
+ ultrix.
+
+Mon Jan 30 11:44:52 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/nodebug.c (inner): Use variables so AIX linker doesn't
+ remove them.
+ * gdb.base/nodebug.exp: Accept "function" in addition to "text
+ variable and "variable" in addition to "data variable".
+ * gdb.base/nodebug.exp: xfail datalocal and bsslocal tests for AIX.
+
+ * gdb.base/list.exp (test_forward_search): Set listsize to 4 not
+ 2.
+ * gdb.base/list1.c (long_line): Add additional statement at start
+ of function.
+ * gdb.base/list.exp (test_forward_search): Update line number to
+ reflect new statement.
+
+Sun Jan 29 13:34:25 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/signals.exp: Reinitialize searched source directories
+ after gdb_start call.
+
+Sat Jan 28 01:34:44 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.disasm/Makefile.in (clean): Delete "errs" file.
+ * gdb.stabs/Makefile.in: Likewise.
+
+ * gdb.disasm/hppa.exp (all_fpu_comparison_tests): Revert last
+ change. Instead split the tests into smaller pieces.
+ * gdb.disasm/hppa.s: Corresponding changes.
+
+Fri Jan 27 09:24:51 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/a1-selftest.exp (test_with_self), gdb.base/interrupt.exp:
+ Quote ^C when passing it to stty. For some shells ^ is a pipe.
+
+ * gdb.base/funcargs.exp: Modify many tests so that every test
+ either passes or fails. Make some test names unique.
+
+Thu Jan 26 19:20:34 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/a1-selftest.exp (test_with_self), gdb.base/interrupt.exp:
+ Call stty to set interrupt character.
+
+ * gdb.disasm/hppa.mt (hppa), gdb.stabs/hppa.mt (weird.o): Check
+ for HP assembler versus GNU assembler based on actual behavior of
+ $(CC), rather than assuming that $(AS) is always the GNU assembler.
+
+ * TODO: Suggest a few more stepping tests.
+
+Wed Jan 25 14:52:41 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/default.exp: xfail no-stack backtraces for h8300,
+ restart GDB for h8300 after a continue.
+ (return): Add pattern to match a29k-udi behavior.
+ * gdb.base/nodebug.exp: Remove obsolete comment.
+ * gdb.base/regs.exp: New file, testing of register displays.
+ * gdb.base/return.exp: Fix typo in reference to $objdir.
+ * gdb.base/whatis.exp: Always start with a fresh GDB.
+
+Wed Jan 25 11:12:07 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.disasm/hppa.exp (all_fpu_comparison_tests): Set timeout
+ higher, these tests generate a lot of output.
+
+Tue Jan 24 07:58:44 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * lib/gdb.exp (gdb_test): Remove catch from around the send. The
+ code following the catch silently ignored some errors; without the
+ catch they should be thrown like any other tcl error. Also, the
+ catch used "" instead of {} which meant all the callers who wanted
+ to include one of the characters "[]$ had to quote it an extra time.
+ * gdb.base/{callfuncs.exp,commands.exp,gdbvars.exp,printcmds.exp,
+ ptype.exp,signals.exp,watchpoint.exp}, gdb.c++/{cplusfuncs.exp,
+ demangle.exp}, gdb.chill/chexp.exp, gdb.fortran/exprs.exp:
+ Remove extra quoting.
+
+Mon Jan 23 21:57:54 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.base/commands.exp: Make test names unique; every test either
+ passes or fails. Update some comments.
+
+ * gdb.disasm/hppa.exp (do_system_control_tests): Update.
+
+Sat Jan 21 15:34:52 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ The following fixes a FAIL caused by the fact that the alpha stabs
+ configuration didn't use the ".if alpha" code in weird.def.
+ * gdb.stabs/weird.def (v_comb): Use type attribute to specify 32
+ bit pointer, so the 32 bit version works even on the alpha.
+ * gdb.stabs/{alpha.mt,ecoff.mt,aout.sed,hppa.sed,xcoff.sed,weird.def}:
+ Remove the stuff which allowed us to have separate versions for
+ alpha and everything else.
+
+ * gdb.c++/cplusfuncs.exp (test_lookup_operator_functions): Fix
+ regexp which "info func operator\[\](" is supposed to match. Fix
+ string to send to GDB. Note that GDB still doesn't work right. Add a
+ new test for "info func .perator\[\](" which GDB does handle correctly.
+
+ * gdb.base/nodebug.exp: xfail most of the new tests for ecoff systems.
+
+Fri Jan 20 12:14:23 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.c++/classes.exp, gdb.c++/cplusfuncs.exp,
+ gdb.c++/inherit.exp, gdb.c++/templates.exp, gdb.c++/virtfunc.exp,
+ gdb.fortran/exprs.exp, gdb.fortran/types.exp, gdb.chill/chexp.exp,
+ gdb.base/printcmds.exp: Remove passcount, failcount, etc., stuff;
+ it makes the tests harder to understand and confuses test-o-matic.
+ The preferred style is that each test provides a PASS or a FAIL,
+ and has a unique message (e.g. "continue #54" not just "continue")
+ which is the same for the pass and the fail.
+ * gdb.fortran/exprs.exp, gdb.fortran/types.exp,
+ gdb.chill/chexp.exp: Move test_print_accept and test_print_reject
+ to lib/gdb.exp.
+ * gdb.base/printcmds.exp: Use test_print_accept. Remove
+ prt_accept which was basically the same thing. Likewise for
+ test_print_reject and prt_reject.
+ * lib/gdb.exp (test_print_reject): Add some more error message
+ patterns to match from the former printcmds.exp (prt_reject).
+ * gdb.c++/classes.exp, gdb.base/scope.exp: Remove spurious xfails.
+ One defect of the passcount stuff is that some of it failed to
+ report XPASS where appropriate.
+ * gdb.c++/cplusfuncs.exp (print_addr_of): No longer accept extra
+ stuff before and after arg in expected pattern.
+ (test_paddr_operator_functions): Re-do test without print_addr_of;
+ this is the only test which seems to want extra stuff there.
+
+Tue Jan 17 10:47:53 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * gdb.base/nodebug.exp: Update new tests to reflect improved
+ wording of gdb output.
+
+ * gdb.base/nodebug.exp: Add tests to check that "print", "whatis"
+ and "ptype" work on variables in files compiled without -g.
+ Replaces commented out "maint print msymbol" tests.
+
+Mon Jan 16 12:13:28 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * gdb.base/setvar.c (dummy): Call malloc.
+
+ * gdb.stabs/aout.sed: Enclose comments within a sed command to avoid
+ losing with the irix4 sed.
+
+ * gdb.base/sigall.exp (test_one_sig): Add xfail for "get signal
+ ALRM" on irix4.
+
+Sun Jan 15 21:58:26 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * TODO: Remove items about corefile.exp testing new exec-file and
+ backtrace; both are now done. Add items about printing enums.
+
+Sat Jan 14 11:25:28 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * gdb.base/sigall.exp (test_one_sig): Attempt to recover if
+ "get signal $thissig" test fails.
+
+ * gdb.base/setvar.exp: Check for and reject crazy expected type hacks.
+
+Thu Jan 12 01:14:53 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * gdb.base/sigall.c (gen_*): Pass argument to handle_* to avoid
+ compiler warning with dec alpha compiler.
+
+ * gdb.base/commands.exp (if_while_breakpoint_command_test): Remove
+ extra \n from gdb_test call (this explains why the prompt test
+ that I removed yesterday was there).
+ (user_defined_command_test): Remove extra \n and prompt test.
+
+ * gdb.base/sigall.c: If SIGABRT == SIGLOST, just act as if SIGLOST
+ doesn't exist. Likewise if SIGIO == SIGPOLL, pretend SIGPOLL
+ doesn't exist.
+ * gdb.base/sigall.exp: Remove special handling for SIGIO and SIGPOLL.
+ Also remove alpha workaround, which turns out to be because
+ SIGABRT == SIGLOST.
+
+ * gdb.base/sigall.exp: Add workaround for alpha weirdness.
+
+ * gdb.base/help.exp: Don't test "help show".
+
+Wed Jan 11 14:37:04 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * gdb.base/commands.exp: Call gdb_exit and gdb_start so that
+ "set print address" is on.
+ * gdb.base/commands.exp (if_while_breakpoint_command_test): Don't
+ pass prompt to gdb_test; gdb_test already looks for the prompt.
+
+ * gdb.base/help.exp: Replace most of docstring for "define" with ".*".
+
+ * gdb.base/a1-selftest.exp: Don't test "maint dump-me". That test
+ was a vestige of the manual TESTSTRATEGY, and the purpose of it
+ was to make sure that gdb can read a core file. But (a) the "read
+ the corefile" part didn't make it to a1-selftest.exp, we just
+ delete the corefile after creating it, and (b) we test reading
+ corefiles in corefile.exp anyway. Also, this test left around a
+ xgdb process on Solaris.
+
+ * gdb.base/corefile.exp: Also test backtrace.
+
+Wed Jan 11 00:14:40 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.base/commands.exp: Test a simple user defined command with
+ arguments and if/while statements; verify the full user command is
+ printed by "show user".
+
+ * gdb.base/commands.exp: Test if/while commands as part of a
+ breakpoint command list; verify they appear in breakpoint
+ information.
+
+Wed Jan 11 00:47:58 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * gdb.base/sigall.c (gen_FPE): Generate SIGFPE with kill() rather
+ than by dividing by zero.
+
+Tue Jan 10 21:38:05 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.base/watchpoint.exp: hppa*-*-*bsd* no longer has problems
+ performing an inferior call with watchpoints enabled.
+ * gdb.base/watchpoint.c (main): Delete second unnecessary read
+ call.
+
+Tue Jan 10 18:42:07 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * gdb.stabs/weird.exp: Allow spaces followed by backspaces in echo
+ of "file" command.
+
+ * gdb.c++/classes.exp (test_ptype_class_objects, ptype class Foo):
+ Add additional pattern for when "int operator int(void);" appears
+ in a different order.
+
+Mon Jan 9 16:22:46 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * gdb.base/signals.exp: Call gdb_exit and gdb_start.
+
+ * gdb.base/help.exp: Replace most of docstrings for "info signals"
+ and "signal" with ".*".
+
+Wed Jan 4 11:35:19 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Add note about "handle all nostop".
+
+ * gdb.base/{sigall.c, sigall.exp}: New test.
+ * gdb.base/Makefile.in: Add it.
+
+Thu Jan 5 17:34:03 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * lib/gdb.exp, gdb.base/corefile.exp: Supply -nw as argument
+ when invoking GDB, suppresses any windowing interface.
+
+Mon Jan 2 17:40:21 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/sim-gdb: New file, simulator testing support.
+
+Wed Dec 28 12:21:50 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.base/interrupt.exp: Test calling func1 twice.
+
+Wed Dec 21 12:51:37 1994 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * gdb.base/list.exp (test_forward_search): Set timeout higher
+ when we'll be getting lots of output from gdb.
+
+ * gdb.base/a1-selftest.exp: Move code that was inside expect -re
+ "init_malloc" to after the expect statement. Run it if that
+ regexp is taken, but also for two others which happen if source
+ cannot be found.
+
+Tue Dec 20 12:35:21 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/printcmds.exp: New test, for printing register before
+ program is running.
+
+Mon Dec 19 00:32:55 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/list.exp: Correct some alternate expect patterns
+ to reflect changes in list1.c.
+
+Sat Dec 17 14:20:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Add item regarding large frames.
+
+ * gdb.base/{funcargs.exp, funcargs.c} (call_after_alloca): New test.
+
+ * TODO: Remove item about enabling return.exp; it
+ is enabled. Suggest a few more "return" tests.
+
+Sat Dec 17 02:33:37 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.c++/misc.cc, gdb.c++/inherit.exp: Add testcases for
+ anonymous unions.
+
+Tue Dec 13 11:26:00 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.chill/Makefile.in: Put all rule before rules for pr-4975.o
+ and pr-5646.o, so "make" is the same as "make all", not "make
+ pr-4975.o".
+
+Wed Dec 7 19:02:02 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/list.exp: Adjust expectations to reflect changes in
+ list1.c.
+ (test_forward_search): New test proc.
+ * gdb.base/list1.c (long_line): New function, has long source line.
+
+Thu Dec 1 23:14:49 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ * gdb.base/a1-selftest.exp: Change initial stepping to know about
+ additional line of code that was added.
+
+Wed Nov 30 19:43:14 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.disasm/hppa.s: Break the large branching tests into smaller
+ tests so as not to overflow expect's input buffers.
+ * gdb.disasm/hppa.exp: Corresponding changes.
+
+Fri Nov 25 13:37:10 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ Beginnings of template debugging tests.
+ * gdb.c++/templ-info.cc: New file to test for template
+ debugging capability of the compiler.
+ * gdb.c++/Makefile.in: Add rule to build templ-info.exp from
+ templ-info.cc.
+ * gdb.c++/templates.cc: Add explicit template instantiations
+ to enable compiling with -fno-implicit-templates. Add destructor
+ and 'value' method to T5 class for template tests.
+ * gdb.c++/templates.exp: Add testcases for printing of template
+ types, setting breakpoints on template methods and calling a
+ template method.
+
+Sat Nov 5 00:20:17 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.disasm/hppa.exp (branch_tests): Allow any symbol as the
+ branch target since some assemblers (gas-2.5) may emit a
+ relocation for the branch instead of resolving it in the
+ assembler.
+
+Sat Oct 29 02:40:40 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/a1-selftest.exp: Remove RS/6000 xfail for backtrace
+ through signal handler.
+
+Fri Oct 21 11:10:16 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * configure.in (*-*-netware): Use config/mt-netware.
+
+ * config/mt-netware: New file.
+ * config/mt-i386-netware: Removed, separate configs for different
+ netware architectures are no longer needed now that we have
+ --with-headers.
+
+Sat Oct 15 03:43:00 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/exprs.exp: Remove xfail for alpha, it is fixed
+ by the recent changes to use ANSI C arithmetic conversions.
+
+Sun Oct 9 07:44:06 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/corefile.exp: Add (xfail'd) test for reinit_frame_cache
+ bug involving using inferior_pid to figure out whether to select a
+ frame.
+
+Wed Sep 28 23:12:02 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.disasm/hppa.exp: Change arg[0..3] to r[26..23] to
+ match the current disassembler output.
+
+Fri Sep 16 11:42:41 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * gdb.fortran/exprs.exp: Expect VOID instead of void.
+ * gdb.fortran/types.exp: Escape the expected '*'s in Fortran
+ types, expect "int" as type of integer values (for now).
+
+Wed Sep 7 23:33:51 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.base/commands.exp: New tests for if/while commands.
+
+Tue Sep 6 13:16:11 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * lib/gdb.exp (runto): Replace sub-pattern for hex value
+ by .*, since hex values have different syntax in Chill mode.
+
+Tue Sep 6 02:15:51 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.c++/demangle.exp (test_arm_style_demangling): Remove
+ linefeed from expect pattern for repeated types with indices > 9.
+
+Mon Aug 29 14:20:44 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ First part of Fortran test suite.
+ * gdb.fortran: New directory.
+ * gdb.fortran/exprs.exp, gdb.fortran/types.exp: New files.
+
+Sat Aug 27 23:32:43 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/default.exp: Update expect pattern for load command
+ without arguments.
+
+Wed Aug 24 13:15:02 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure.in: Change i386 to i[345]86.
+ * gdb.base/configure.in: Likewise.
+ * gdb.c++/configure.in: Likewise.
+ * gdb.chill/configure.in: Likewise.
+
+Tue Aug 23 19:14:06 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * lib/gdb.exp (gdb_run_cmd): Move comment out from between expect
+ patterns, since that is not a valid context for comments.
+
+Fri Aug 19 15:07:30 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * gdb.c++/demangle.exp (test_arm_style_demangling): Add tests for
+ repeated types and repeated types with indices > 9.
+
+Tue Aug 16 15:57:52 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * gdb.base/printcmds.exp: Remove all the a29k XFAILs tagged with
+ 2417; old bug has been fixed.
+
+Fri Aug 12 19:35:41 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.base/interrupt.exp: When trying to wake up the inferior,
+ send the newline ourselves instead of assuming gdb_test will do
+ so when passed an empty input string.
+
+ * gdb.stabs/hppa.mt: Use $(AS), not $(CC) to assemble the
+ stabs testcode.
+
+Fri Aug 5 17:01:07 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * lib/gdb.exp (gdb_test): Don't send anything if the first
+ argument is an empty string. This makes cases where we want to
+ match output that is already in expect's buffers (for example,
+ matching a breakpoint after gdb_run_cmd has been called) work
+ reliably.
+
+Tue Aug 2 10:24:08 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * config/netware.exp: New file.
+
+Thu Jul 28 12:54:07 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * config/mt-slite (LDFLAGS): If using the newlib in the tree, set
+ the -B and -L prefixes so we can find the debugging stub.
+
+ * Makefile.in (CC_FOR_TARGET, CXX_FOR_TARGET): Use newlib if it is
+ there and we are using the gcc from the tree.
+
+ * gdb.base/types.c: Removed.
+
+ * gdb.base/configure.in: Look for makefile fragments in ../config.
+ Recognize i386-*-netware.
+ * gdb.c++/configure.in: Likewise.
+
+Mon Jul 25 23:48:50 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/corefile.exp: Change `else if' to `elseif', which is
+ the correct TCL syntax.
+
+Mon Jul 25 15:35:56 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * gdb.base/opaque.exp: use runto instead of messing around with
+ breakpoints. Simplify by using gdb_test.
+
+ * gdb.base/bitfields.exp: restart between tests on netware targets
+ because breakpoints aren't relocated after target death. Run
+ processes to completion.
+
+ * gdb.base/{opaque,watchpoint}.exp: Use gdb_run_cmd.
+
+Sun Jul 24 09:55:51 1994 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in: Remove extra tabs that confuse some versions
+ of "make". Use the newly built gdb to test with by default,
+ rather than the first one in the tester's search path.
+
+Sat Jul 23 15:05:47 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * gdb.base/whatis.exp (v_signed_short_array): Fix a typo.
+
+ * gdb.base/help.exp: Update expected add-symbol-file, ignore, and
+ condition help.
+
+Tue Jul 19 10:26:32 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * lib/gdb.exp (runto): Rewrite in terms of gdb_run_cmd.
+
+ * lib/gdb.exp (gdb_run_cmd): New function, used to start program
+ running.
+ * gdb.base/bitfields.exp: Use gdb_run_cmd to start program.
+ * gdb.base/funcargs.exp: Likewise.
+
+ * gdb.base/bitfields.exp: Simplify by using gdb_test.
+ * gdb.base/funcargs.exp: Likewise.
+
+ * lib/gdb.exp (gdb_test): if match times out, don't call fail if
+ message is "".
+
+Mon Jul 18 12:18:07 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * gdb.base/{a2-run,callfuncs,funcargs,interrupt,mips_pro,nodebug,
+ return,signals,twice}.exp: Handle non-existant binaries
+ consistantly.
+
+ * gdb.base/corefile.exp: Execute coremaker to generate core dump.
+ * gdb.base/Makefile.in: Don't try to generate a core dump, we
+ might testing a cross development system.
+
+Thu Jul 14 18:13:56 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * Makefile.in (RUNTEST_FOR_TARGET): Fix relative pathname, the
+ runtest script is relative to ${srcdir}, not ${rootdir}.
+
+Thu Jul 14 14:56:59 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * gdb.base/signals.exp: Allow for optionality of breakpoint
+ address.
+
+Thu Jul 14 11:21:27 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.base/{ptype.exp,ptype.c}: Add t_char_array test.
+
+Tue Jul 12 12:22:32 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * gdb.c++/cplusfuncs.cc: Include <stddef.h>, not <sys/types.h>,
+ for size_t definition.
+ * gdb.c++/templates.cc: Likewise
+
+ * config/mt-i386-netware: New file.
+
+ * gdb.base/interrupt.c: Do not test if errno == EINTR if it's not
+ defined.
+
+ * gdb.base/Makefile.in: Added support for systems that name core
+ files by appending "core" to the program name.
+ * gdb.base/a1-selftest.exp: Likewise.
+
+Mon Jul 11 23:59:18 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/return.exp: Add comment and message for `return double'
+ test failure on Sparc Solaris.
+
+Mon Jul 4 12:10:48 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * lib/gdb.exp (runto): Allow for optionality of breakpoint address.
+
+Wed Jun 29 00:26:17 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.c++/misc.cc: Instantiate classes to inhibit the compiler
+ from optimizing them away.
+ * gdb.c++/classes.exp, gdb.c++/inherit.exp: Update ptype expect
+ patterns to include default constructors and assignment operators,
+ to match gcc versions beyond 2.5.8. Accept any cplus demangling
+ character in the output of the virtual base pointer.
+
+Fri Jun 24 08:15:42 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.c++/cplusfuncs.exp: Use string_to_regexp and a regular
+ expression match in print_addr_of to avoid unintented matches.
+ * gdb.c++/virtfunc.exp: Accept alternate ptype output of g++
+ versions up to 2.5.8.
+
+Mon Jun 20 23:54:37 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.base/list.exp: Tweak alternate pattern for listing of an
+ included file to run under newer versions of expect.
+ * gdb.c++/demangle.exp: Add spaces to the expect patterns between
+ consecutive >'s in templates to accomodate recent cplus-dem.c change.
+ Remove xfail for the virtual table of BDDHookV.
+
+Sat Jun 18 12:51:34 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * lib/gdb.exp (string_to_regexp): Set a default result.
+ (default_gdb_start): Fix misleading message.
+
+Wed Jun 15 12:10:10 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/mt-a29k-udi, config/mt-i960-nindy, config/mt-sparc-aout:
+ Remove all CC, etc definitions.
+ * config/mt-hpux: New file.
+ * config/mt-mips-ecoff (CFLAGS_FOR_TARGET): Remove:
+ (CFLAGS, LDFLAGS): Define.
+ * config/mt-slite (CFLAGS_FOR_TARGET): Change to LDFLAGS.
+
+ * Makefile.in (site.exp): Don't insert host_os, etc.
+ (just-check): Just use RUNTEST with RUNTESTFLAGS only.
+ (distclean): Check existence of subdir.
+ * gdb.base/configure.in (hppa*-*-hpux*): Recognize.
+ * gdb.base/Makefile.in: General cleanup and simplification.
+ Use CC, CFLAGS, and LDFLAGS instead of ..._FOR_TARGET versions
+ to build executables. Use default rule to build .o files.
+ (EXPECT, RUNTEST, CC): Fix relative pathname.
+ (site.exp): Don't insert host_os, etc.
+ * gdb.base/signals.c (main): Don't call signal unless SIGALRM
+ and/or SIGUSR1 defined.
+ * gdb.base/watchpoint.c: Don't include stdio.h a second time.
+ * gdb.c++/Makefile.in: General cleanup and simplification.
+ Use CC, CFLAGS, and LDFLAGS instead of ..._FOR_TARGET versions
+ (CFLAGS): Remove.
+ (EXPECT, RUNTEST_FOR_TARGET, CXX): Fix relative pathname.
+
+Fri Jun 10 10:55:09 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gdb.base/recurse.exp: Misc changes to get tests running again
+ after Kung's changes to the watchpoint code.
+ * gdb.base/watchpoint.exp: Likewise.
+
+Thu Jun 9 15:16:55 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * lib/gdb.exp (string_to_regexp): Convert {\} also.
+
+Wed Jun 8 12:12:17 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/udi-gdb.exp, config/unix-gdb.exp: Call default_gdb_start.
+ * lib/gdb.exp (default_gdb_start): Define.
+ * gdb.base/bitfields.exp, gdb.base/break.exp, gdb.base/exprs.exp,
+ gdb.base/funcargs.exp, gdb.base/opaque.exp,
+ gdb.base/printcmds.exp, gdb.base/ptype.exp, gdb.base/recurse.exp,
+ gdb.base/scope.exp, gdb.base/setvar.exp, gdb.base/watchpoint.exp,
+ gdb.c++/classes.exp, gdb.c++/misc.exp, gdb.c++/virtfunc.exp:
+ Don't call gdb_target_udi in between tests.
+
+Tue Jun 7 08:30:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.c++/demangle.exp: Use gdb_test_exact, rather than demangle
+ (which was basically just a local version of the same thing). In
+ addition to avoiding duplication, gdb_test_exact is faster.
+ * lib/gdb.exp (gdb_test_exact): Fix typo.
+
+ * lib/gdb.exp (delete_breakpoints): If there were no breakpoints,
+ don't give an error.
+
+ * gdb.base/term.exp: Call delete_breakpoints before starting.
+
+ * gdb.base/Makefile.in (EXECUTABLES): Remove t10.
+ (t10): Add comment.
+
+Mon Jun 6 18:26:50 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ Reorganization of the GDB Test Suite.
+
+ * gdb.base: New directory, contains all the basic tests.
+ * gdb.c++: New directory, tests specific to C++.
+ * gdb.chill: New directory, tests specific to Chill.
+ * gdb.t00, gdb.t01, gdb.t02, gdb.t03, gdb.t04, gdb.t05, gdb.t06,
+ gdb.t07, gdb.t08, gdb.t09, gdb.t10, gdb.t11, gdb.t12, gdb.t13,
+ gdb.t15, gdb.t16, gdb.t17, gdb.t20, gdb.t21, gdb.t22, gdb.t23,
+ gdb.t24, gdb.t30, gdb.t31: Removed directories, contents moved
+ into appropriate new directories (t00-t17 to base, t20-t23 to c++,
+ t30-31 to chill).
+ * */gdbme.*: Rename to match appropriate expect scripts.
+ * gdb.base/bitfields.c, gdb.base/break.c, gdb.base/callfuncs.c,
+ gdb.base/coremaker.c, gdb.base/exprs.c, gdb.base/funcargs.c,
+ gdb.base/interrupt.c, gdb.base/list0.c, gdb.base/list0.h,
+ gdb.base/list1.c, gdb.base/mips_pro.c, gdb.base/nodebug.c,
+ gdb.base/opaque-info.c, gdb.base/opaque0.c, gdb.base/opaque1.c,
+ gdb.base/printcmds.c, gdb.base/ptype.c, gdb.base/recurse.c,
+ gdb.base/return.c, gdb.base/run.c, gdb.base/scope0.c,
+ gdb.base/scope1.c, gdb.base/setvar.c, gdb.base/signals.c,
+ gdb.base/types.c, gdb.base/twice.c, gdb.base/watchpoint.c,
+ gdb.base/whatis-info.c, gdb.base/whatis.c: New names of C files.
+ * gdb.c++/cplusfuncs.cc, gdb.c++/templates.cc, gdb.c++/misc.cc,
+ gdb.c++/virtfunc.cc: New names of C++ files.
+ * gdb.chill/chillvars.ch: New name of Chill file.
+ * gdb.base/configure.in, gdb.c++/configure.in,
+ gdb.chill/configure.in: Merge in contents of gdb.t*/configure.in.
+ * gdb.base/Makefile.in, gdb.c++/Makefile.in,
+ gdb.chill/Makefile.in: Merge in contents of gdb.t*/Makefile.in.
+ * configure.in (configdirs): Update to reflect directory changes.
+ (target_abbrev): No longer define for any configuration.
+ * Makefile.in: Cosmetic improvements to header comments.
+
+Fri Jun 3 18:56:06 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ Various changes to gdb.t31:
+
+ * Makefile.in (gdbme.o): Compile with -fspecial_UC.
+ * gdbme.ch: Make all key-words and predefineds be upper-case.
+ * chillvars.exp: Expect key-words and predefinds in upper-case.
+
+ * chillvars.exp: Use gdb_test_exact many places.
+ Change expected output for arrays (which now includes index labels).
+
+ * pr-5020.exp, gdme.ch (module PR_5020):
+ New test, for PR-5020.
+
+Thu Jun 2 16:02:41 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * lib/gdb.exp (string_to_regexp, gdb_test_exact): New procedures.
+ * Makefile.in (CHILL_LIB): Remove bogus redundant definitions.
+
+Sun May 29 22:31:42 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in: Fix bit-rot in definitions of CHILL,
+ CHILL_FOR_TARGET and Chill_LIB.
+ * gdb.t31/gdbme.ch: Fix syntax of nested array tuples.
+ * gdb.t31/Makefile.in: Add definitions for CHILLFLAGS,
+ CHILL, and CHILL_LIB.
+
+Sat May 21 10:05:08 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * Revert the previous changes. Please see Rob's directory
+ /lisa/test/rob/progressive/gdb/testsuite for these fixes.
+
+Thu May 19 12:51:00 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * Makefile.in, configure.in, config/mips-gdb.exp,
+ config/mt-a29k-udi, config/mt-i386-aout, config/mt-i960-nindy,
+ config/mt-sparc-aout, config/udi-gdb.exp, config/unix-gdb.exp,
+ config/unknown.exp, gdb.t00/default.exp, gdb.t00/help.exp,,
+ gdb.t00/teststrategy.exp, gdb.t01/Makefile.in, gdb.t02/Makefile.in,
+ gdb.t02/whatis.exp, gdb.t03/Makefile.in, gdb.t03/gdbme.c,
+ gdb.t04/Makefile.in, gdb.t05/Makefile.in, gdb.t06/Makefile.in,
+ gdb.t06/break.exp, gdb.t06/signals.c, gdb.t06/signals.exp,
+ gdb.t08/Makefile.in, gdb.t08/opaque.exp, gdb.t09/Makefile.in,
+ gdb.t10/Makefile.in, gdb.t11/Makefile.in, gdb.t12/Makefile.in,
+ gdb.t13/Makefile.in, gdb.t15/Makefile.in, gdb.t15/funcargs.exp,
+ gdb.t15/gdbme.c, gdb.t15/return.exp, gdb.t16/Makefile.in,
+ gdb.t17/Makefile.in, gdb.t17/callfuncs.exp, gdb.t17/gdbme.c,
+ gdb.t20/Makefile.in, gdb.t21/Makefile.in, gdb.t21/cplusfuncs.exp,
+ gdb.t22/Makefile.in, gdb.t22/virtfunc.exp, gdb.t23/Makefile.in,
+ gdb.t24/demangle.exp, lib/gdb.exp: Check in Rob's testing
+ changes from 94Q1.
+
+Wed May 18 17:04:03 1994 Bill Cox (bill@rtl.cygnus.com),
+
+ * config/mt-lynx, config/mt-m68k, config/mt-mips-ecoff,
+ config/mt-slite, config/mt-unix, config/mt-vxworks: Add
+ Rob's new testing fragments.
+
+Tue May 17 15:04:14 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * config/mips-gdb.exp, config/udi-gdb.exp, config/vx-gdb.exp,
+ lib/gdb.exp: Replace error proc calls with perror.
+
+Mon May 16 19:00:50 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * gdb.t00/teststrategy.exp: Reorder so that AIX gdb can print the
+ version also, match on casted version strings, and match on
+ gdb startup case where the line numbers might be messed up.
+
+Fri May 13 18:00:27 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * config/mt-i960-vx (LDFLAGS): Add '-r' option for test links.
+ (CFLAGS): Delete it from here.
+
+Tue May 3 16:08:09 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * gdb.t22/virtfunc.exp: Fix g++ ptype expected outputs.
+
+Fri Apr 29 14:26:35 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in (RUNTEST): Default to just "runtest".
+
+Tue Apr 26 22:21:40 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gdb.t17/callfuncs.exp: More comments about t_func_values tests.
+ * gdb.t17/gdbme.c (t_func_values): Add comments about how and why
+ the code has been restructured.
+
+Thu Apr 21 12:48:07 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t00/default.exp (set write): Allow any number of \r and/or
+ \n, not just one of each.
+
+ * gdb.t07/gdbme.c (main): Don't take address of an array; SunOS4
+ /bin/cc gives a warning if you do.
+
+Thu Apr 21 11:54:04 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * gdb.t24/demangle.exp: change expect pattern of
+ __t10ListS_link1ZUiRCUiPT0
+
+Wed Apr 13 15:05:00 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gdb.t07/{recurse.exp, recurse.c}: New tests for watchpoints
+ on local variables in recursive functions.
+
+ * gdb.t07/Makefile.in: Build the new test.
+
+Tue Apr 12 20:45:25 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gdb.t17/gdbme.c (t_func_values): Do not compare function pointers
+ directly. Instead compare the return values from actual calls.
+
+Mon Apr 11 10:31:00 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * Makefile.in (check): Set TCL_LIBRARY for runtest.
+
+Mon Apr 11 09:15:30 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * From Peter Schauer with minor modifications.
+ * gdb.t15/return.exp (return_tests): Handle targets where "return"
+ stops in mid-line in the caller. Add xfail for returning a float
+ value on X86 targets.
+
+Tue Apr 5 15:16:33 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gdb.disasm/hppa.exp (fcmp_tests): Break up into two halves
+ to avoid expect lossage.
+ (fmem_LRbug_tests): Likewise.
+ * gdb.disasm/hppa.s: Corresponding changes.
+
+ * gdb.disasm/hppa.exp: Rework escape sequences and end-of-line
+ conditions to work with latest dejagnu/expect.
+
+ * gdb.t15/funcargs.exp (finish from indirect call): No longer
+ expected to fail on the PA.
+ (backtrace in call with trampolines): Explicitly require main
+ to be frame #1 (no trampolines should show up in backtrace).
+
+ * gdb.t00/default.exp: Use "exp_continue" rather than obsolete
+ "continue -expect".
+ * gdb.t06/break.exp: Likewise.
+ * gdb.t07/watchpoint.exp: Likewise.
+ * gdb.t13/bitfields.exp: Likewise.
+ * gdb.t15/{funcargs,return}.exp: Likewise.
+ * gdb.stabs/weird.exp: Likewise.
+ * config/{mips,udi}-gdb.exp: Likewise.
+
+ * hppa.sed: Enclose comments within a sed command to avoid
+ losing with the old OSF1 sed.
+
+Wed Mar 30 00:31:49 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t02/whatis.exp, gdb.t08/opaque.exp: Add XFAILs for
+ sequent dynix.
+ * gdb.t06/signals.exp: Add clear_xfail for sequent dynix.
+ * gdb.t15/funcargs.exp: Conditionally step again to really
+ finish from marker_call_with_trampolines. Handle the case where
+ the first step from within call_with_trampolines already steps
+ us back to main.
+ * gdb.t15/gdbme.c: Add comment to closing brace of
+ call_with_trampolines for funcargs.exp.
+
+Tue Mar 29 23:55:27 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gdb.t07/watchpoint.exp (test_watchpoint_triggered_in_syscall):
+ Fix typo(s).
+
+Sun Mar 27 16:53:14 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gdb.t07/gdbme.c: More code for watchpoint testing.
+
+ * gdb.t07/watchpoint.exp: Accept both "Watchpoint" and
+ "Hardware watchpoint" throughout file.
+ (test_watchpoint_triggered_in_syscall): New test.
+ (test_complex_watchpoint): New test.
+
+Fri Mar 25 17:05:31 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gdbme.c (call_with_trampolines): New function to try and step
+ into. Tests trampoline problems on the PA.
+
+ * funcargs.exp (localvars_in_indirect_call): No longer expect
+ stepping into indirect call to fail on PAs.
+ (test_stepping_over_trampolines): New test.
+
+Wed Mar 23 07:43:33 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Add suggestions for static member function tests, and
+ completion tests.
+
+Wed Mar 16 08:28:28 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Add suggestions for "p/a" tests.
+
+ * lib/gdb.exp: Set prompt to (gdb) if it isn't already set.
+ (default_gdb_exit): Replace all the hair with sending "quit" to
+ the process with a simple close.
+
+Tue Mar 15 08:45:50 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Add suggestions for shared library tests.
+
+Sun Mar 13 10:45:22 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Add suggestions for x/s tests.
+
+Fri Mar 11 08:22:00 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t00/help.exp: Replace most of docstrings for "tbreak",
+ "enable once", and "enable breakpoints once" with ".*".
+
+Thu Mar 10 08:34:27 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Add suggestions about structure passing tests.
+
+Mon Mar 7 13:45:54 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t03/gdbme.c: gcc version 1 puts out the wrong stabs for
+ the primary1 test, use work around if __GNUC__ < 2.
+ * gdb.t06/signals.c: Add comments for signals.exp pattern matching.
+ * gdb.t06/signals.exp: Add XFAILs for i386 bsd and vax ultrix.
+ Test for bad output rather than waiting for timeout. Issue
+ second continue only if first continue failed.
+
+Wed Mar 2 10:08:01 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * gdb.t21/cplusfuncs.exp (test_paddr_operator_functions): Do
+ operator[] test with gdb_test because the old code didn't seem to
+ be getting the quoting right with the new dejagnu.
+
+Thu Feb 24 19:49:25 1994 Rob Savoye (rob@poseidon.cygnus.com)
+
+ * lib/gdb.exp: Set GDB to a fresh gdb if there is one, else use
+ one from the path.
+ * Makefile.in: Use a fresh expect if there is one, use runtest
+ from the src tree if there is one.
+
+Thu Feb 24 18:49:37 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * gdb.t06/break.exp (test_next_with_recursion): Remove xfail for
+ next over recursive call. Revise the tests from that point on
+ (which had been skipped) to match GDB's actual (correct) output.
+
+ * gdb.t07/watchpoint.exp (test_stepping): Remove xfail for bug
+ with next over a breakpoint whose condition is false.
+
+ * gdb.t00/help.exp: Comment out "help set print" tests just like
+ (and for same reason as) "help set" test.
+
+Mon Feb 14 09:58:23 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gdb.disasm/hppa.s (fmemLRbug_tests): New tests.
+ * gdb.disasm/hppa.exp (fmemLRbug_tests): Run them.
+
+Sun Feb 6 15:36:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t06/break.exp (test_next_with_recursion): Remove no longer
+ necessary gdb_target_udi.
+
+ * gdb.t03/ptype.exp: For UDI, skip tests which call malloc.
+
+ * gdb.t02/whatis.exp, gdb.t03/ptype.exp: Remove xfails for PRs
+ 1838 and 2417; they are fixed.
+
+ * gdb.t02/whatis.exp (v_char_array, v_signed_char_array),
+ gdb.t03/ptype.exp (ptype structure, ptype union):
+ Remove xfails; the test is looser than when the xfails were added.
+
+ * gdb.t00/{help.exp,default.exp}: Don't test "target remote" on UDI.
+ * gdb.t00/help.exp: Don't expect remote to be in "help target" output.
+
+ * gdb.t01/run.exp: Only run shell test if isnative.
+
+ * config/udi-gdb.exp (gdb_load): Use "file", not "load" command,
+ since "run" automatically loads if necessary. Call gdb_target_udi
+ after the "file" since "file" kills any execution target.
+
+ * config/udi-gdb.exp (gdb_start): Don't send "set args main" to
+ GDB. GDB doesn't work that way (not anymore at least) on UDI.
+ * gdb.t01/run.exp, gdb.t06/break.exp: Don't pass extra first
+ argument for UDI.
+
+Fri Feb 4 12:19:32 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * gdb.t17/interrupt.c: If we get EINTR, don't print an error message.
+
+ * gdb.t17/callfuncs.exp: Add xfails for rs6000.
+
+Sat Feb 5 09:11:56 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t24/demangle.exp: Re-write demangle to just call gdb_test,
+ properly quoting regexps. This makes the second argument to
+ demangle a fixed string, which matches the callers, instead of a
+ shell-style pattern which is what the previous implementation
+ used. Update some of the callers.
+
+Sat Feb 5 10:19:09 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gdb.disasm/hppa.s (comib_tests): Add missing instruction.
+ (comib_nullified_tests): Fix typo.
+ * gdb.disasm/hppa.exp (all comb tests): Fix thinkos in expect
+ strings. No longer expected to fail.
+
+ * gdb.disasm/hppa.s (addib_tests): Fix typo.
+ * gdb.disasm/hppa.exp (all addb tests): Fix thinkos in expect
+ strings. No longer expected to fail.
+
+ * gdb.disasm/hppa.exp (fmpy_addsub_tests): Fix typo in expect
+ string. No longer expected to fail.
+
+Fri Feb 4 23:45:11 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gdb.disasm/hppa.exp (fcmp_tests): Fix thinko in expect string.
+ No longer expected to fail.
+
+ * gdb.disasm/hppa.exp (xmpyu_tests): Fix buglet in expect
+ string. No longer expected to fail.
+
+Fri Feb 4 10:35:42 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t24/demangle.exp: Remove a bunch more tests which differ
+ only in the names (I probably got most of them). I was even
+ generous with some which differed in underscores in names, and
+ probably missed a few, and I *still* was able to remove almost a
+ third of the file with almost no impact on testsuite coverage.
+
+Thu Feb 3 12:04:49 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t00/default.exp: Match udi_attach error message as well as
+ the one from child_attach.
+
+ * gdb.t00/default.exp: Use "." instead of "?" to match a question mark.
+
+ * gdb.stabs/weird.exp: Remove xfail for const70; just fixed in GDB.
+
+ * gdb.stabs/weird.def (bad_neg0type): Size of this type is 16, not 8.
+ * gdb.stabs/weird.exp: Remove xfail for "p bad_neg0"; this fixes it.
+
+ * Move test with enums and partial symbols back to
+ gdb.t03/{ptype.exp,gdbme.c} from gdb.stabs/{weird.def,weird.exp}.
+ Reverts the change of 26 May 93. Per today's change to
+ stabs.texinfo, the behavior that weird.exp was expecting was
+ unreasonable; what is important is that the compiler+gdb get
+ things right, which happens with a recent gcc. Also fix the test
+ to deal with native compilers which put out the stab gdb can't
+ deal with.
+
+Mon Jan 31 15:40:11 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t24/demangle.exp: Remove a bunch of tests which differ only
+ in the names. The main thing these accomplish is to slow things down.
+ Many more such duplicates surely remain.
+
+ * gdb.t00/help.exp: Comment out "help support" test just like
+ (and for same reason as) "help set" test.
+
+Mon Jan 31 06:43:45 1994 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t06/break.exp: Remove setup_xfails for
+ sparc-sun-solaris2.*, these tests now pass with latest gcc and gdb.
+ * gdb.t20/inherit.exp (test_ptype_si): Update warning message
+ about known bug in gcc to include up through 2.5.8.
+ * gdb.t20/inherit.exp (test_ptype_vi): Accept "_vb." as well as
+ well as "_vb$".
+ * gdb.t21/cplusfuncs.exp (test_lookup_operator_functions):
+ Remove setup_xfails for sparc-sun-solaris2.*, these tests now pass
+ with latest gcc and gdb.
+ * gdb.t22/virtfunc.exp (test_ptype_of_classes): Accept "_vb." as
+ well as "_vb$".
+
+Sat Jan 29 23:31:26 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * configure.in (hppa*-*-*): Also configure and build stabs-only
+ tests.
+
+Thu Jan 27 08:21:16 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gdb.t10/hppa.mt: A makefile fragment for the PA.
+ * gdb.t10/configure.in (hppa*-*-*): Use it.
+
+Tue Jan 25 12:58:26 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t09/corefile: Increase timeout when spawning gdb explicitly.
+
+Wed Jan 19 12:40:25 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t06/signals.exp: Handle blocked SIGTRAP on sun3 for bash
+ versions prior to 1.13.5.
+
+Tue Jan 18 20:10:50 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t00/default.exp (show prompt): In FAIL case, only match if
+ the prompt is at the start of a line.
+
+Mon Jan 17 20:07:51 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gdb.disasm/hppa.s: Add new tests for sfu and copr instructions.
+ Enable "diag" instruction. Delete copr from fpu_misc_tests, it's
+ in the copr tests now.
+ * gdb.disasm/hppa.exp: Run new sfu and copr tests. Do not expect
+ copr in the fpu_misc tests anymore. fpu_misc tests are no longer
+ expected to fail.
+
+Fri Jan 14 14:24:21 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * gdb.t00/teststrategy.exp, gdb.t07/watchpoint.exp,
+ gdb.t31/chillvars.exp, lib/gdb.exp:
+ Tweak to run under either version of expect.
+ * lib/gdb.exp (default_gdb_exit): Remove "catch" statement.
+ * gdb.t00/teststrategy.exp: Use isnative and verbose procedures.
+ * gdb.t11/list.exp: Remove extraneous whitespace.
+
+Sat Jan 15 09:57:22 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t16/printcmds.exp (test_print_strings): Accept
+ "(unsigned char *) " before the string.
+
+ * TODO: Add notes about printing of fancy types and GDB expressions.
+
+Thu Jan 13 17:16:09 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in: Pass LDFLAGS and LIBS to sub-makes.
+ * gdb.t06/configure.in: Don't try to compile signals test program
+ if doing mips-idt-ecoff.
+
+Thu Jan 13 08:25:55 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * Most .exp files: Tweak to run under either version of expect.
+
+Tue Jan 11 15:21:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t12/scope.exp: Add xfails for rs6000. Remove 1806 from existing
+ xfails; I'm not sure why they are failing, but not because of PR 1806.
+
+Mon Jan 10 22:14:20 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * config/unix-gdb.exp: Remove gdb_unload cause it's already
+ defined in lib/gdb.exp.
+
+Fri Jan 7 12:42:45 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t07/watchpoint.exp: Clear xfail for calling function with
+ watchpoint enabled on mips, CALL_DUMMY_BREAKPOINT_OFFSET got defined.
+ * gdb.t20/gdbme.cc, gdb.t21/gdbme.cc: Conversion operator functions
+ have to be typeless.
+
+Tue Jan 4 09:32:22 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Add suggestion for copyright year test.
+
+Mon Jan 3 11:35:26 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * configure.in (*-*-lynxos*): Add stabs tests.
+
+Wed Dec 1 21:54:05 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gdb.stabs/hppa.sed: Only lables should ever start in column zero,
+ so insert a tab before any assembler directive in column zero.
+
+ * gdb.disasm/hppa.exp (all_fpu_memory_tests): Test FP quadword
+ stores.
+ * gdb.disasm/hppa.s (fpu_memory_indexing_tests): Add FP quadword
+ stores.
+ (fpu_short_memory_tests): Likewise.
+
+Mon Nov 22 13:23:22 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.stabs/ecoff.mt: Delete alpha specific if block, fix typo.
+ * gdb.stabs/ecoff.sed: Escape inserted blanks with backslashes, embed
+ .stabs directives in comments.
+
+Fri Nov 19 14:09:02 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: New file, describing tests we could write.
+ * gdb.t09/corefile.exp: Move description of tests to write to TODO.
+
+Tue Nov 16 21:07:44 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t06/signals.exp: Add kludge to force re-sync.
+
+ * gdb.t00/teststrategy.exp: If we accidently send the "maint dump-me"
+ to xgdb instead of gdb, get out of gdb.
+
+Tue Nov 16 10:21:57 1993 Rob Savoye (rob@cygnus.com)
+
+ * lib/gdb.exp: Make GDB and GDBFLAGS global so the scoping work
+ for info.
+
+Sat Nov 13 23:17:48 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gdb.stabs/hppa.mt: A makefile fragment for the PA.
+ * gdb.stabs/configure.in (hppa*-*-*): Use it.
+ * gdb.stabs/hppa.sed: New sed script for the PA.
+
+Sat Nov 13 22:50:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.stabs: Re-write weird.def and configuration to use sed
+ instead of cpp. sed is portable and POSIX; cpp is neither.
+
+Fri Nov 12 15:26:36 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t06/signals.exp: Remove one sun3 XFAIL which has been fixed.
+
+Mon Nov 8 16:55:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t20/gdbme.cc: Add comment about pmi being optimized out.
+
+Thu Nov 4 23:07:59 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.stabs/weird.exp, gdb.t22/virtfunc.exp: Accept "_vb." as well as
+ "_vb$".
+ * gdb.t00/teststrategy.exp: Add xfail for RS/6000.
+ * gdb.t03/ptype.exp: Add comments and messages about FAILs with xlc.
+
+Wed Nov 3 13:53:34 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * lib/gdb.exp: Comment out code which depends on non-existent
+ `transform' procedure.
+
+Wed Nov 3 11:23:11 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * lib/gdb.exp (default_gdb_exit): Remove `catch "close"'.
+ * lib/gdb.exp: Transform tool name.
+ * gdb.t*/*.exp: Change error to perror so it works with DejaGnu
+ 1.1's new error handling system.
+
+Mon Nov 1 10:36:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in, gdb.t2*/Makefile.in: Add -O to CXXFLAGS.
+
+Fri Oct 29 17:58:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t00/default.exp: Avoid tests with a lot of .* in them.
+ They made pattern matching so slow that timeouts happened on
+ heavily loaded systems. Now any output from "show print" which
+ gets us back to the GDB prompt is a PASS.
+
+Mon Oct 25 14:36:50 1993 Stu Grossman (grossman at cygnus.com)
+
+ * gdb.disasm/hppa.mt: Use $(srcdir) in hppa.o make rule.
+
+Mon Oct 25 13:35:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t06/signals.exp: Skip whole file with xfail for HPPA.
+
+ * gdb.t24/demangle.exp: Remove "3220" from the one remaining xfail.
+ It is not from PR 3220.
+
+Sun Oct 24 18:49:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t00/{help.exp,default.exp}: Loosen up a few more tests which
+ just started failing because they depended on the order the
+ subcommands are presented, or exact docstring text. This kind of
+ test is a pain and has minimal benefit.
+
+Thu Oct 21 08:26:48 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t09/corefile.exp: At end of test, use "core" command with
+ no arguments.
+
+Wed Oct 20 08:56:02 1993 Stu Grossman (grossman at cygnus.com)
+
+ * gdb.t{01 02 03 04 05 06 07 08 09 10 11 12 13 15 16
+ 17}/Makefile.in: Make it possible to run the testsuite with Sun
+ make and CC = cross gcc by adding explicit build rules for .o
+ files.
+
+Tue Oct 19 14:57:38 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t15/funcargs.exp: Don't put comments on same line as
+ setup_xfail (@#$*%& tcl braindamage!).
+
+Mon Oct 18 21:50:08 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.disasm/hppa.exp: Use $objdir/$subdir/$binfile not just $binfile.
+
+Fri Oct 15 15:39:54 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * gdb.t20/classes.exp: 'const xxx &' becomes 'xxx const &'.
+ * gdb.t20/inherit.exp: remove three dumplicate entries.
+
+Fri Oct 15 13:45:25 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t06/break.exp: For "next over recursive call", fail on any
+ incorrect output, not just on "factorial (value=2)".
+
+Fri Oct 15 11:52:56 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t12/scope.exp: Remove xfails, filename::var syntax should be
+ working now. Add an xfail if accesing a bss variable causes
+ a memory error if the target is not yet run.
+
+Thu Oct 14 19:16:56 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t24/demangle.exp: Clean up spacing (2 strings), inclusion of
+ constructor name (2 string), name of _GLOBAL_ demangling (2 strings),
+ name of __st* demangling (2 strings). Did Kung really get the
+ more than 95 others right without testing them?
+
+Thu Oct 14 16:27:08 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * gdb.t24/demangle.exp: clean up XFAILS, more than 100
+
+Thu Oct 14 11:40:30 1993 Jeffrey Law (law@cs.uah.edu)
+
+ * configure.in (configdirs): Add gdb.disasm
+ * gdb.disasm: New directory for GDB disassembler tests.
+ * gdb.disasm/hppa.{exp,s,mt}: Disassembly tests for the HPPA.
+
+Thu Oct 14 11:40:30 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t00/help.exp: Don't test "help set".
+
+ * gdb.t20/inherit.exp, gdb.t22/virtfunc.exp: Remove all xfails
+ from within expect statements. None of these happen anymore and
+ they cause regressions to be silently unnoticed.
+
+ * gdb.t20/inherit.exp, gdb.t22/virtfunc.exp: Add notes (in failure
+ messages) about known failures with gcc cygnus-2.4.5-930417.
+
+ * gdb.t02/Makefile.in, gdb.t08/Makefile.in: Make all depend on
+ comp-info.exp so it gets built if it doesn't exist.
+
+ * gdb.t13/{Makefile.in,bitfields.exp}: Remove comp-info.exp stuff;
+ it is no longer used.
+ * gdb.t13/comp-info.c: Removed.
+
+Wed Oct 13 22:54:06 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * gdb.t06/signals.exp: Add xfail for sun3.
+
+Thu Oct 7 12:01:03 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t17/interrupt.exp: Add xfail for Irix (currently not really
+ relevant because ^C doesn't get sent but failure can be reproduced
+ interactively).
+
+Tue Oct 5 10:43:11 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.stabs/alpha.mt: New configuration file for alpha.
+ * gdb.stabs/configure.in: Use it.
+ * gdb.stabs/ecoff.mt, weird-ecoff.sed: Change sed script to enable
+ sharing with alpha.mt, redefine long to word via preprocessor.
+ * gdb.stabs/weird.def: Conditionally adapt storage layout of v_comb
+ for alpha.
+ * gdb.stabs/weird.exp: Handle compilation of weird.s by alpha
+ native cc.
+ * gdb.t00/teststrategy.exp: Change expect string so that we
+ consume the `(xgdb)' from the command echo and from the gdb prompt.
+ * gdb.t05/expr.exp: xfail "print unsigned int == (~0)" on the alpha.
+ gdb currently compares all values as long, so this failure probably
+ applies to any configuration where LONGEST is bigger than a target int.
+ * gdb.t08/comp-info.c: New file to determine if gdbme is compiled
+ with gcc.
+ * gdb.t08/Makefile.in, opaque.exp: Use it. Alpha native cc is unable
+ to handle opaque pointers, gcc is.
+ * gdb.t21/gdbme.cc, gdb.t23/gdbme.cc: operator new takes a size_t
+ as first argument. Include <sys/types.h> and change all operator
+ new definitions to use size_t.
+ * gdb.t21/cplusfuncs.exp: Handle changes in output for operator new
+ now that we use size_t.
+
+Wed Sep 29 00:55:49 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t03/ptype.exp, gdb.t15/printcmds.exp: When constructing
+ a long or float array cast all array members to the same type.
+ * gdb.t04/setvar.exp: Handle the decimal output of an unsigned long
+ with 64 bit longs.
+ * gdb.t07/watchpoint.exp: Add finish and until variations encountered
+ on alpha.
+ * gdb.t08/opaque.exp, gdb.t17/interrupt.exp: Add xfails for alpha.
+
+Tue Sep 28 17:26:47 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t24 (demangle.exp): Constructors of templates have names like
+ vector<int>::vector(int) not vector<int>::vector<int>(int). See
+ section 14.6 of the ARM.
+
+ * gdb.t24 (demangle.exp): Remove a whole bunch of tests of the form
+ "_vt$MoveCmd"; these differ only in name from "_vt$foo", so they
+ accomplish little and slow down the testsuite.
+
+ * gdb.t24 (demangle.exp): Accept "XXX const" as well as "const XXX".
+ Accept spaces various places.
+
+Tue Sep 21 17:28:45 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t07/watchpoint.exp: On sparc, clear xfail for calling function
+ with watchpoint enabled.
+
+ * Makefile.in: Remove definition of CC and remove the second
+ definition of CXX (the "CXX = gcc" one remains). These definitions
+ were causing backquotes to be expanded within backquotes, which
+ doesn't work.
+
+Sat Sep 18 09:43:21 1993 Jim Kingdon (kingdon@poseidon.cygnus.com)
+
+ * gdb.t17/callfuncs.exp: Add "return 0" to end.
+
+Fri Sep 17 04:41:17 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.stabs/ecoff.mt: Remove STABSCC hack.
+ * gdb.stabs/weird.exp: Handle the case where weird.o is compiled
+ by mips cc and contains no stabs entries.
+
+Thu Sep 16 17:22:12 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * config/vx-gdb.exp: Use fake device to load files rather than
+ NFS.
+ * lib/gdb.exp: New proc to do "file" command.
+ * config/unix-gdb.exp: Use new "file" proc.
+
+Thu Sep 16 13:45:44 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/mips-gdb.exp (gdb_load): Increase timeout to 2400.
+ Rework board rebooting slightly.
+ (gdb_exit): Don't exit from the remote shell; there isn't one.
+ * gdb.stabs/weird.exp: If a program is being debugged already,
+ kill it.
+ * gdb.t04/setvar.exp: Stop and restart gdb.
+ * gdb.t05/expr.exp: Likewise.
+ * gdb.t07/watchpoint.exp: If target is mips-idt-*, stop and
+ restart gdb and reload the program.
+ * gdb.t08/opaque.exp: Likewise.
+ * gdb.t12/scope.exp: Likewise.
+ * gdb.t13/bitfields.exp: Likewise.
+ * gdb.t15/funcargs.exp: Likewise.
+ * gdb.t20/classes.exp: Likewise.
+ * gdb.t03/ptype.exp: Increase timeout.
+ * gdb.t16/printcmds.exp (test_print_string_constants,
+ test_print_array_constants): Likewise.
+ * gdb.t17/callfuncs.exp (do_function_calls): Likewise.
+ * gdb.t20/classes.exp (do_tests): Likewise.
+ * gdb.t22/virtfunc.exp (test_virtual_calls): Likewise.
+
+Wed Sep 15 14:24:36 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * gdb.stabs: Renamed *wierd* to *weird*.
+
+Wed Sep 15 10:36:50 1993 Jim Kingdon (kingdon@cirdan.cygnus.com)
+
+ * gdb.t13/bitfields.exp: Test for bad output rather than waiting
+ for timeout. Add "known gcc 2.4.5 bug" to failure message.
+
+Tue Sep 14 17:16:44 1993 Jim Kingdon (kingdon@cirdan.cygnus.com)
+
+ * gdb.stabs/wierd.exp (print_wierd_var): Test size, not type name.
+ (do_tests): Remove xfail for whatis on one_var and two_var.
+
+Wed Sep 8 23:14:23 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * Makefile.in: Made cross building work better by adding
+ {RUNTEST,CC}_FOR_TARGET and using TARGET_FLAGS_TO_PASS.
+
+Tue Sep 7 14:11:52 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t15/{return.c,return.exp,Makefile.in}:
+ New test, currently commented out.
+
+Tue Aug 31 16:51:29 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * config/udi-gdb.exp: gdb_exit now kills any isstip processes
+ still running and removes the leftover named socket so GDb can do
+ clean restarts.
+
+Mon Aug 30 17:55:16 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * gdb.t01/run.exp: Add match for VxWorks, cause I/O comes out the
+ console, not GDB.
+ * config/mt-*: Added default values for RUNTEST and RUNTESTFLAGS so
+ cross testing works better with "make check"
+ * config/unix-gdb: Use default procedures for exit and version.
+ * config/vx-gdb.exp: Cleaned up and massaged back to working order
+ with the newest VxWorks.
+
+Thu Aug 26 17:50:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t20/classes.exp: For "ptype class Base1", continue to accept
+ old form.
+
+ * gdb.t22/virtfunc.exp: If it prints `struct' (not `class') with a
+ name (e.g. devo gdb with gcc 2.4.5), it is still a pass.
+
+ * gdb.t10/crossload.exp: Skip whole file (for now, until we fix it).
+
+ * config/unix-gdb.exp: Remove this version of gdb_exit
+ * lib/gdb.exp: Merge in all the crap from config/unix-gdb.exp.
+ Rob says he'll look at it when he gets back to testing boards.
+
+Thu Aug 26 07:20:00 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * gdb.t22/virtfunc.exp: Accept missing struct/class names as
+ an expected fail for certain ptype commands.
+
+ * gdb.t20/classes.exp: Update expected results of "ptype class
+ Base1" to account for the constructor that now appears in the type.
+
+Wed Aug 25 16:48:05 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * configure.in (configdirs): Restore gdb.t04, which mysteriously
+ disappeared from list.
+ * config/{udi-gdb.exp, gdb-unix.exp}: Replace calls to obsolete
+ "alldone" proc with call to cleanup and exit.
+ * {gdb.t01/run.exp, gdb.t01/term.exp, gdb.t02/whatis.exp,
+ gdb.t03/ptype.exp, gdb.t04/setvar.exp, gdb.t05/expr.exp,
+ gdb.t06/break.exp, gdb.t07/watchpoint.exp, gdb.t08/opaque.exp,
+ gdb.t09/corefile.exp, gdb.t10/crossload.exp, gdb.t11/list.exp,
+ gdb.t12/scope.exp, gdb.t13/bitfields.exp}: Replace calls to
+ "alldone" proc with simple returns that suppress remaining
+ tests. The alldone proc went away many months ago.
+
+Tue Aug 24 11:04:06 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t10/nodebug.exp: Comment out "maint print msymbols" tests.
+
+ * gdb.t12/gdbme0.c (localscopes, autovars): Modify to foil gcc -O.
+
+Thu Aug 19 22:08:41 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t15/funcargs.exp: Allow arguments for main in backtraces
+ as vax gdb will display them.
+
+Thu Aug 19 18:18:59 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t20/gdbme.cc: Do some calculation with v.x, to confound
+ optimizers.
+
+ * scope.exp: Change "bad value for localval" messages so each one
+ is unique.
+
+ * config/unix-gdb.exp (gdb_exit): Move info on this vs.
+ lib/gdb.exp (gdb_exit) from ChangeLog to comments.
+
+ * gdb.t06/signals.exp: Skip the whole file with xfail for delta68.
+
+Tue Aug 17 00:05:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t00/teststrategy.exp: Deal with it if cmdsize = 1 line
+ doesn't exist (due to optimization).
+
+Mon Aug 16 21:05:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.stabs/wierd.exp: Deal with it if echo of "file" command
+ contains \r because the filename is long.
+
+ * gdb.t06/signals.exp: Revise comments regarding "'next' behaved as
+ 'continue'" bug, and change xfail back to i*86-univel-sysv4*.
+
+Mon Aug 16 03:05:17 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t00/help.exp, gdb.t02/whatis.exp, gdb.t07/watchpoint.exp,
+ gdb.t08/opaque.exp, gdb.t17/interrupt.exp: Update for vax running
+ Ultrix.
+ * gdb.t02/whatis.exp: Use procedure to setup xfails on long versus
+ int tests.
+ * gdb.t08/opaque.exp: Use procedure to setup xfails for opaque tests.
+
+Thu Aug 12 15:24:28 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * Makefile.in (distclean): Remove *.log *.plog *.sum *.psum site.*.
+
+ * gdb.t17/interrupt.exp: Fix 'missing Continuing' case so pattern
+ to match does not match the passing case but still matches the
+ failing case.
+
+Thu Aug 12 16:58:59 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (distclean): Remove *.plog *.sum *.psum site.*.
+
+Wed Aug 11 19:47:27 1993 John Gilmore (gnu@rtl.cygnus.com)
+
+ * lib/gdb.exp (gdb_exit): Move the best version of gdb_exit
+ to here. Fix 'Quit anyway.*?' bug (? is a regexp metacharacter).
+ * config/{mips-gdb.exp, nind-gdb.exp, udi-gdb.exp, vx-gdb.exp}:
+ Remove various versions of gdb_exit.
+ * config/vx-gdb.exp: Remove quit_vxgdb, change a caller to call
+ gdb_exit.
+ * config/unix-gdb.exp: gdb_exit remains here, and should override
+ the generic version, since it's doing a lot of wierd stuff that
+ the other versions aren't. FIXME, fold it in, or abandon this
+ version.
+
+Wed Aug 11 12:09:32 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t24/demangle.exp: Add tests for PR 3220.
+
+Tue Aug 10 15:49:35 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t24/demangle.exp: Add lucid test for __vtbl__3foo__vt_cc_main_.
+
+Tue Aug 10 15:45:25 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * gdb.t07/watchpoint.exp: Clear xfail with "i*86-*-*", not just
+ "i386-*-*". Works for i486 as well.
+
+ * gdb.t06/signals.exp: Rework code that recognizes known SVR4
+ bug, and expand domain of xfail to all SVR4 systems, since the
+ actual problem is likely to be in generic SVR4 /proc support.
+
+Tue Aug 10 15:49:35 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/unix-gdb.exp (gdb_load): Add eof to expect statement.
+
+Tue Aug 10 09:56:56 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * gdb.t17/interrupt.exp: Set up xfail for *-*-sysv4*, in chain of
+ xfails for other systems. Match a missing 'Continuing.' as an
+ explicit fail for i*86-*-sysv4*, so it doesn't hose other tests.
+
+ * gdb.t20 {classes.exp, inherit.exp, misc.exp}, gdb.t21/cplusfuncs.exp,
+ gdb.t22/virtfunc.exp, gdb.t23/templates.exp, gdb.t31/chillvars.exp:
+ Only issue warning for missing executables if -all option is used.
+
+ * gdb.stabs/wierd.exp: Only issue warning for missing wierd.o
+ file if -all option is used. It's like an unpredictable XFAIL.
+
+Mon Aug 9 10:13:34 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t15/funcargs.exp: Add comments that hppa xfails are only
+ for dynamically linked binaries.
+
+ * gdb.t10/crossload.exp: Add `set gnutarget auto' at end of tests.
+
+Sun Aug 8 14:21:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t20/inherit.exp: Change message for "print tagless struct"
+ to state that this is a known bug in old versions of g++.
+
+Fri Aug 6 21:40:30 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t17/interrupt.exp: Add xfail for 386 bsd. Accept echoed newline
+ while waiting for `Continuing'.
+
+Fri Aug 6 13:38:08 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * gdb.t10/nodebug.exp: Expect to find local/global minimal symbols
+ in text, data, and bss.
+ * gdb.t10/nodebug.c: Add local and global test variables for
+ initialized and uninitialized data.
+
+Thu Aug 5 12:18:40 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/unix-gdb.exp (gdb_exit): Add "wait".
+
+Thu Aug 5 18:14:06 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t06/signals.exp: xfail the continue from the handler for all
+ targets.
+
+ * gdb.t07/watchpoint.exp: clear_xfail for i386 when calling a
+ function with watchpoints enabled, the i386 call dummy starts with
+ a call.
+
+ * gdb.t00/teststrategy.exp, gdb.t09/Makefile.in: Handle the way
+ 386 bsd names its corefiles.
+
+Wed Aug 4 08:53:41 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t10/Makefile.in (nodebug.o): Don't use "-c -o", many
+ compilers don't grok it.
+ * gdb.t16/gdbme.c (ctable1): Initialize unsigned char array
+ with small octal ints rather than character constants, which
+ are signed and might not fit if first promoted to int.
+
+Tue Aug 3 18:28:25 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t09/Makefile.in (clean): Remove corefile.
+
+Mon Aug 2 12:47:44 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t07/watchpoint.exp: Add missing `$prompt $'.
+
+Mon Aug 2 12:30:14 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+ and Jim Kingdon (kingdon@cygnus.com)
+
+ * gdb.t06/signals.exp: Change xfail from "*-*-*" to be only for
+ NO_SINGLE_STEP machines. Fix comment about its cause. Uncomment
+ the `continue' test right after it (also xfailed if NO_SINGLE_STEP).
+
+Fri Jul 30 19:46:55 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t17/interrupt.exp: Add xfail for hppa.
+
+Fri Jul 30 12:54:11 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t02/whatis.exp, gdb.t03/ptype.exp, gdb.t08/opaque.exp,
+ gdb.t09/corefile.exp: Cleanup xfails for fixed mips bugs.
+ * gdb.t13/bitfields.exp, gdbme.c: Examine a variable in the inferior
+ to determine signed-ness of bitfields and use the result to setup
+ the xfail.
+ * gdb.t15/gdbme.c: Add comments to the two indirect call0a lines.
+ * gdb.t15/funcargs.exp: Use them to step until the second indirect
+ call line is reached if necessary.
+
+Thu Jul 29 20:33:08 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.stabs/wierd.exp: New test, for nameless baseclasses.
+
+Mon Jul 26 00:15:02 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t06/break.exp: Also test `clear' command.
+
+Wed Jul 21 18:03:38 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * gdb.t00/teststrategy.exp: Remove extra quote.
+
+ * gdb.t07/watchpoint.exp: Change xfail for calling function with
+ watchpoint enabled to be for all non-68k machines.
+
+ * gdb.t15/{mips_pro.{c,exp},Makefile.in}: New test.
+
+Mon Jul 19 23:59:26 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.stabs/configure.in: If configured -with-gnu-as for mips-*-*
+ targets use aout.mt instead of ecoff.mt as gas understands
+ standard aout format.
+
+Mon Jul 19 18:14:06 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * lib/gdb.exp (runto): Don't insist that function we are running to
+ was compiled with -g.
+
+ * gdb.t10/{nodebug.{c,exp},Makefile.in}: New test.
+
+ * gdb.t17/interrupt.exp: Before sending ^C, give the inferior time
+ to get back into the read system call.
+ Accept leading newline in case where we woke it up.
+
+Sun Jul 18 08:40:45 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.stabs/{ecoff.mt,wierd-ecoff.S,wierd-ecoff.sed}: New files
+ to make the stabs test work on ecoff systems using gcc and -with-stabs.
+ * gdb.stabs/{Makefile.in,configure.in,aout.mt,xcoff.mt}: Modify to
+ enable ecoff configuration.
+
+Thu Jul 15 11:54:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t15/funcargs.exp (localvars_in_indirect_call): New test.
+
+Wed Jul 14 09:36:42 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t16/printcmds.exp: Add another printf test.
+
+Wed Jul 14 15:37:13 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in: If configured -with-stabs on any target, add
+ stabsdirs to configdirs.
+
+Wed Jul 14 09:36:42 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t16/printcmds.exp: Change printf "%f\n" to printf "%f is
+ fun" so pattern does not match the command itself.
+
+Mon Jul 12 11:22:06 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t15/{gdbme.c,funcargs.exp}: Test for alloca-influenced frames.
+
+Sun Jul 11 12:03:24 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t17/interrupt.exp: Test for more things.
+
+Fri Jul 9 14:11:17 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t07/watchpoint.exp: In until test, deal with the way the DEC
+ compiler arranges the code and line numbers.
+
+ * gdb.t17/interrupt.exp: Don't send \n after ^C.
+
+Fri Jul 9 09:47:02 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t00/help.exp: Increase expect input buffer size.
+
+Thu Jul 8 14:26:50 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t06/signals.exp: Remove sparc xfail; bug fixed.
+
+ * gdb.t07/watchpoint.exp: Add xfail for hppa.
+
+ * gdb.t17/{gdbme.c,callfuncs.exp}: Add sum10 function, to test pa bug.
+
+ * gdb.t06/signals.exp: At "p func1 ()" test, check for breakpoint
+ [0-9]*, not just [0-9].
+
+Wed Jul 7 17:52:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t20/{gdbme.cc,classes.exp}: Add xfail for gdb/2972.
+
+ * gdb.t2*: Set CXXFLAGS, not CFLAGS, since that's what we use.
+
+Tue Jul 6 13:54:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t00/help.exp: Replace most of docstring for "continue" with .*.
+
+Mon Jul 5 22:03:45 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t06/signals.c: Add xfails for sun3.
+
+ * gdb.t07/watchpoint.exp: Comment out xfail for fixed bug 1836.
+
+ * gdb.t07/{gdbme.c,watchpoint.exp}: Add test for 2597. Also add
+ test_stepping tests.
+
+Fri Jul 2 09:08:10 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t{06,17}/Makefile.in (clean): Remove all executables.
+
+ * gdb.t17/{interrupt.{c,exp},Makefile.in}: New test for solaris bug.
+
+ * gdb.t06/twice.exp, Makefile.in: Just use an include of twice.c
+ rather than actually putting it through cpp twice.
+
+ * gdb.t06/signals.exp: Add xfails for unixware and rs6000.
+
+Fri Jul 2 10:48:03 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/mips-gdb.exp (gdb_exit): Removed close statement which is
+ no longer needed.
+
+Fri Jul 2 09:08:10 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t06/signals.exp: Add test for sparc bug with do_save_insn.
+
+ * gdb.t20/{classes,inherit}.exp: If a class which doesn't use any
+ C++ features prints as "struct", make it a pass, not an xfail.
+
+Thu Jul 1 22:03:33 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t22/virtfunc.exp: Remove a bunch of xfails.
+ Don't require VA to print as "class" rather than "struct".
+
+Thu Jul 1 18:27:40 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * gdb.t06/twice.exp: Don't care about the file name GDB prints.
+
+Wed Jun 30 18:01:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t{02,13}/comp-info.c, gdb.t06/twice.exp: Add "return 0" to end.
+
+Tue Jun 29 13:15:42 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t12/scope.exp: Remove xfail for parameter printing in wrong
+ order.
+
+Tue Jun 29 09:22:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t16/printcmds.exp: Add printf tests.
+
+ * gdb.t06/{twice.{c,exp},Makefile.in}: New test.
+
+ * gdb.t10/Makefile.in (clean): Remove $(EXECUTABLES) too.
+
+Mon Jun 28 11:25:59 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t20/classes.exp: Add clear_xfail's before printing summary
+ pass counts, to counteract any existing or future setup_xfails.
+
+Mon Jun 28 09:15:17 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.stabs/wierd{.def,-aout.S,-xcoff.S}: Use new macros
+ {BEGIN,END}_COMMON for common block instead of STAB.
+ * gdb.stabs/wierd.exp: Add xfail for rs6000.
+
+ * gdb.stabs/wierd.def: Make value of N_GSYM's 0.
+ intp_var should be N_GSYM not N_LSYM.
+ wierd-aout.S: Use a label for the value of the N_SO.
+ wierd.def: Remove all backslashes.
+ wierd-{aout,xcoff}.S: Put a few tests with backslashes here.
+
+Mon Jun 28 07:21:51 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t20/gdbme.cc (main): Move variable initialization for AIX to
+ get the expected next to inheritance3.
+
+Sun Jun 27 12:29:53 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t00/teststrategy.exp: Remove expected failure for mips-*-*
+ now that gcc-2.4 gets it right.
+
+Fri Jun 25 12:00:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.stabs/wierd{.def,.exp,-aout.S,-xcoff.S}: Add common block test.
+
+ * gdb.t{02,13}/{Makefile.in,gdbme.c,comp-info.c}: New way of
+ generating comp-info.exp which works for cross-compilation.
+
+Thu Jun 24 16:55:05 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t11/list.exp: For SVR4 xfails, match "*-*-sysv4*", not
+ "*-*-sysv4.*".
+
+Tue Jun 22 21:17:26 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t01/run.exp: Start with a fresh gdb.
+ * gdb.t11/list.exp: For SVR4 xfails, match on all versions of
+ SVR4.x.
+
+Mon Jun 21 15:23:22 1993 Fred Fish (fnf@cygnus.com)
+
+ * {gdb.t01, gdb.t02, gdb.t03, gdb.t04, gdb.t05, gdb.t06, gdb.t07,
+ gdb.t08, gdb.t09, gdb.t10, gdb.t11, gdb.t12, gdb.t13, gdb.t15,
+ gdb.t16, gdb.t17, gdb.t20, gdb.t21, gdb.t22, gdb.t23, gdb.t30}/
+ Makefile.in (distclean, realclean): Remove gdbme.c from list of
+ things to remove.
+
+Sat Jun 19 07:49:10 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t24/demangle.exp (test_gnu_style_demangling): Add some new
+ test cases from bug reports.
+
+Fri Jun 18 10:38:49 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t06/break.exp: Add xfails for sparc-sun-solaris2.*.
+ * gdb.t12/scope.exp: Add clear_xfails at appropriate places to
+ avoid spurious xfails.
+ * gdb.t20/classes.exp: Add xfails for longstanding C++ problems.
+ * gdb.t21/cplusfuncs.exp: Add xfails for sparc-sun-solaris2.*.
+ * gdb.t22/virtfunc.exp: Add xfails for longstanding C++ problems.
+
+Wed Jun 16 10:11:57 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t00/teststrategy.exp: Rework to provide more useful
+ description of each test, fix problem with systems that define
+ ALIGN_STACK_ON_STARTUP code, other misc cleanups.
+ * gdb.t06/break.exp (test_next_with_recursion): Fix expected
+ results for "next over recursive call" so timeouts aren't taken
+ by error.
+
+Mon Jun 14 09:09:04 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * gdb.t12/scope.exp: Test printing of variables before run.
+
+ * gdb.t12/{gdbme0.c,scope.exp}: Test for bug where parameters are
+ printed in wrong order due to sorting.
+
+Sat Jun 12 15:03:58 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t00/teststrategy.exp: Fix expected results for printing
+ user entered string constant. Is array of char, prints with no
+ address.
+
+ * gdb.t00/{default.exp, help.exp}: Account for changes to radix
+ commands.
+ * gdb.t16/gdbme.c: Add and use struct containing arrays of char.
+ * gdb.t16/printcmds.exp: Fix all lines that match "unsigned char *".
+ * gdb.t16/printcmds.exp (test_print_char_arrays): Test printing
+ of struct of char arrays.
+ * gdb.t00/radix.exp: New tests for radix commands.
+
+Fri Jun 11 13:12:27 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * gdb.t16/printcmd.exp: Print a variable before running program
+ (with xfail for AIX).
+
+Thu Jun 10 11:04:04 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * gdb.t06/{signals.exp,signals.c,Makefile.in}: New test.
+
+ * gdb.t16/printcmd.exp: Don't print variables before running program.
+
+ * gdb.t06/break.exp: Don't require envp argument to main.
+
+ * gdb.t0{2,3,4,5}/gdbme.c [_AIX]: Use signed keyword.
+
+ * gdb.t02/whatis.exp, gdb.t11/list.exp:
+ Add xfails for rs6000.
+
+ * gdb.t02/whatis.exp: Change other tests not to re-test something
+ we already tested.
+
+ * gdb.t{03,15,16}/gdbme.c: Reference all variables and make sure
+ each type used has a variable of that type.
+
+Tue Jun 8 16:45:20 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * gdb.t20/{inherit.exp,gdbme.cc}: Test tagless structure.
+
+Fri Jun 4 11:07:19 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: change srctrigger to be a file, not a directory
+
+Fri Jun 4 08:23:57 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in (mips-idt-ecoff*): Added trailing '*'.
+
+ * gdb.t11/list.exp: Fixed a couple of typos.
+
+Tue Jun 1 21:28:06 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t00 (teststrategy.exp): Remove notice about PR 1823. Bug
+ is fixed and PR is closed.
+ * gdb.t16 (gdbme.c): Add simple test string variable.
+ * gdb.t16 (printcmds.exp): Add tests with simple test string
+ variable, primarily for boundaries on "set print elements".
+
+Mon May 31 11:36:08 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * gdb.stabs/wierd.exp: Remove xfail for printing big integer.
+ Make leading 0's optional and don't expect a tab in the middle
+ of the number.
+
+ * gdb.t00/teststrategy.exp: Remove xgdb before trying the copy.
+
+ * gdb.stabs/wierd.def: Type attributes must be preceded by number=.
+ * gdb.stabs/wierd.exp: Remove xfails for type attributes. Also
+ don't end command passed to gdb_test with newline.
+
+ * gdb.t13/{Makefile.in,gdbme.c,bitfields.exp}: If we #defined the
+ signed keyword away, don't expect signed bitfields to be signed.
+
+ * gdb.t13/bitfields.exp (bitfield containment): Accept the fields
+ printing with only as many 1's as are in the field as well as printing
+ with 32 1's (see comment).
+
+Sat May 29 17:57:01 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t00/default.exp: Start with a fresh gdb.
+ * configure.in (configdirs): Remove gdb.t31 until the chill
+ compiler works again. It no longer is able to find chillrt0
+ since it isn't in libchill.a anymore.
+ * gdb.stabs/wierd.exp: Rewrite to properly handling a missing
+ wierd.o, make more modular.
+ * gdb.stabs/wierd.def (bad_neg0type, bad_neg0const): Remove
+ spurious newlines that caused problems.
+
+Wed May 26 09:57:19 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Move test with enums and partial symbols from gdb.t03/ptype.exp
+ to gdb.stabs/wierd.exp since GCC has worked around the bug.
+ gdb.stabs/wierd.{exp,def}: Many new tests.
+
+ * gdb.t00/default.exp: update info line for new message.
+
+ * gdb.t02/{whatis.exp,gdbme.c}:
+ Test that "char *" doesn't print as "caddr_t".
+
+Tue May 25 13:28:27 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t00/help.exp: Use .* in place of some help messages which
+ just changed.
+ gdb.t00/default.exp: Update "info frame" test for new message.
+ * gdb.stabs/wierd.exp: Check for eof, directly or via gdb_test.
+ Remove some xfails
+
+Mon May 24 00:24:47 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdb.t03/{gdbme.c,ptype.exp}:
+ Add tests for typedef'd struct and union without tags.
+ Also check "whatis" on a variable of a typedef'd enum without a tag.
+
+ * gdb.t00/teststrategy.exp: For p "foo", remove sun4 XFAIL (see
+ PRMS 1823; the bug still exists but isn't reproduced by this test
+ anymore), and remove rs6000 XFAIL (the bug is fixed).
+
+ * gdb.t03/ptype.exp: Comment out a lot of tests which are basically
+ duplicated from whatis.exp. For those that are left, accept
+ "long", "long int", or "int" for long variables (whatis.exp already
+ has an XFAIL for "int", so no need to fail it here).
+
+ * gdb.t02/whatis.exp, gdb.t10/crossload.exp:
+ Deal with GCC's names for types now that GDB uses the compiler's names.
+
+ * gdb.t02/{Makefile.in,gdbme.c,whatis.exp}: If not GCC, do some
+ setup_xfail's for sunos4. If we #defined the signed keyword away,
+ don't expect GDB to know that char it is signed.
+
+ * gdb.t00/teststrategy.exp: Update for symbolic signal names.
+
+Sun May 23 08:44:55 1993 Fred Fish (fnf@cygnus.com)
+
+ * configure.in (configdirs): Add gdb.t24 for C++ tests that
+ should work on any system, regardless of debugging format.
+ * gdb.t21/demangle.exp: Move to gdb.t24.
+ * gdb.t24/demangle.exp: Move from gdb.t21.
+ * gdb.t24/{Makefile.in, configure.in}: New files.
+
+Thu May 20 19:39:03 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.in: Do gdb.stabs and C++ tests only for stabs.
+ * gdb.stabs: New directory.
+
+Tue May 18 21:12:09 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/{mips,nind,udi,unix,vx}-gdb.exp: Look for "Quit anyway.*?"
+ not just "Quit anyway?".
+
+Tue May 18 17:13:20 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t21/demangle.exp: Add a couple of new patterns. Ensure
+ that all setup_xfails are immediately followed by clear_xfails.
+
+Tue May 11 09:10:47 1993 Fred Fish (fnf@cygnus.com)
+
+ * config/unix-gdb.exp, gdb.t00/echo.exp, gdb.t00/help.exp,
+ gdb.t00/teststrategy.exp, gdb.t00/gdbvars.exp, gdb.t01/run.exp,
+ gdb.t01/term.exp, gdb.t02/whatis.exp, gdb.t03/ptype.exp,
+ gdb.t04/setvar.exp, gdb.t05/expr.exp, gdb.t06/break.exp,
+ gdb.t07/watchpoint.exp, gdb.t08/opaque.exp, gdb.t09/corefile.exp,
+ gdb.t10/crossload.exp, gdb.t11/list.exp, gdb.t12/scope.exp,
+ gdb.t13/bitfields.exp, gdb.t15/funcargs.exp, gdb.t16/printcmds.exp,
+ gdb.t17/callfuncs.exp, gdb.t20/misc.exp, gdb.t20/inherit.exp,
+ gdb.t20/classes.exp, gdb.t21/demangle.exp, gdb.t21/cplusfuncs.exp,
+ gdb.t22/virtfunc.exp, gdb.t23/templates.exp, gdb.t30/chexp.exp,
+ gdb.t31/chillvars.exp, lib/gdb.exp:
+ Change place to report bugs from bug-dejagnu@prep.ai.mit.edu to
+ bug-gdb@prep.ai.mit.edu.
+
+Fri May 7 09:15:35 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t17/callfuncs.exp (do_function_calls): Call t_double_values
+ with 0.0, not integer 0.
+
+Fri Apr 30 13:17:24 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * gdb.t06/break.exp: Update for "Kill the program" message change.
+
+Fri Apr 30 09:42:57 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (GDBFLAGS): Set to -nx.
+ * Makefile.in (site.exp): Use GDBFLAGS.
+
+Wed Apr 28 13:19:07 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * */Makefile.in (CFLAGS): add CFLAGS = -g to all subdirectory
+ Makefiles.
+ (check): depend on just-check.
+ (just-check): added so that tests can be run without a noop
+ build pass.
+
+Fri Apr 23 18:13:28 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ Switch to using configure's configdirs.
+ * Makefile.in (Makefile): add configure.in dependency.
+ (SUBDIRS): removed redundant assignment.
+ * configure.in: switch subdirs assignment to configdirs.
+ * gdb.t*/configure.in: new files.
+
+Thu Apr 22 08:27:53 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * gdb.t07/watchpoint.exp: Removed a29k expected failure which now
+ works.
+
+Tue Apr 20 13:38:40 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.{t20,t21,t22,t23}/Makefile.in: Use $(srcdir) to avoid $<
+ in explicit rules. Apparently this is not supported by some makes.
+
+Mon Apr 19 01:54:53 1993 John Gilmore (gnu@cygnus.com)
+
+ * gdb.t31/Makefile.in: Use $(srcdir) when avoiding $<, sigh.
+
+Fri Apr 16 09:33:46 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/unix-gdb.exp: Add back missing return 0 which mysteriously
+ disappeared.
+
+Thu Apr 15 02:28:24 1993 John Gilmore (gnu@cacophony.cygnus.com)
+
+ * gdb.t31/Makefile.in: Avoid $< in explicit rule.
+
+Wed Apr 14 16:38:47 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t07/watchpoint.exp: Remove setup_xfail for i486
+ watchpoint problem that is now fixed.
+ * gdb.t30/chexp.exp: Remove setup_xfail for printing
+ uninitialized convenience variables.
+ * gdb.t31/chillvars.exp: Fix expected patterns for printing
+ structures.
+
+Wed Apr 14 12:55:58 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t00/help.exp: Compensate for bug in mips-*-ultrix* OS
+ which causes expect to get out of sync with gdb on long output
+ from help set.
+ * gdb.t09/corefile.exp: Make expected pattern for core file
+ failing signal and frame output format less sun specific.
+
+Tue Apr 13 23:18:07 1993 Per Bothner (bothner@cygnus.com)
+
+ * gdb.t31/chillvars.exp: Add and remove initial dummy
+ breakpoint, so that symbol table is forced in.
+ (Needed at least on Sunos4, though it seems not SVR4.)
+ * gdb.t31/chillvars.exp: Update for changed output format.
+
+Sun Apr 11 17:21:45 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * config/unix-gdb.exp: Gracefully exits if $GDB is a bogus path.
+
+Wed Apr 7 21:28:21 1993 Rob Savoye (rob@cygnus.com)
+
+ * Makefile.in: Added --srcdir when invoking runtest, removed the
+ need for a local config file. (optional now)
+
+Wed Apr 7 14:13:41 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t21/demangle.exp: Only count real fails (not xfails) for
+ failure count used to force early termination. Add some more
+ expected failures for gnu style demangling.
+
+Thu Apr 1 09:50:30 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * Makefile.in (CXXFLAGS): Remove -O. It caused the debug info for the
+ pmi variable from gdb.t20/gdbme to get optimized away.
+ * gdb.t00/teststrategy.exp: Added expected failure for mips-*-*.
+ Check for written corefile upon timeout _and_ eof.
+
+Tue Mar 30 09:58:16 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/unix-gdb.exp: Add missing return 0.
+
+Tue Mar 30 08:34:25 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * gdb.t16/printcmds.exp: Remove misplaced xfail that caused an early
+ test termination.
+
+Mon Mar 29 17:37:25 1993 Fred Fish (fnf@cygnus.com)
+
+ * configure.in (subdirs): Put back gdb.t17 which mysteriously
+ disappeared.
+
+Thu Mar 25 21:05:16 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t10/crossload.exp: Disable the i860-elf test until such
+ time as i860 support works.
+
+ * gdb.t15/funcargs.exp: Fix expected outputs to include
+ "backtrace 100\r" rather than just "backtrace\r", to match last
+ change.
+
+Thu Mar 25 12:14:28 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/udi-gdb.exp (gdb_exit): Remove close command.
+ (gdb_target_udi): New procedure to set the UDI target.
+ (gdb_start): Don't remove *_soc files. Use gdb_target_udi.
+ * gdb.t00/default.exp: Added expected failures for a29k-*-udi.
+ Added waits for prompts after several question responses. Added
+ some more responses used by a29k-amd-udi-gdb.
+ * gdb.t01/run.exp, gdb.t06/break.exp: Added a29k-*-udi support:
+ pass different arguments, restart UDI connection after program
+ completion.
+ * gdb.t02/whatis.exp, gdb.t03/ptype.exp, gdb.t07/watchpoint.exp,
+ gdb.t08/opaque.exp, gdb.t11/list.exp, gdb.t12/scope.exp,
+ gdb.t15/funcargs.exp, gdb.t16/printcmds.exp, gdb.t20/misc.exp,
+ gdb.t21/cplusfuncs.exp: Added expected failures for a29k-*-*.
+ * gdb.t04/setvar.exp, gdb.t05/expr.exp, gdb.t07/watchpoint.exp,
+ gdb.t08/opaque.exp, gdb.t12/scope.exp, gdb.t13/bitfields.exp,
+ gdb.t15/funcargs.exp, gdb.t16/printcmds.exp,
+ gdb.t17/callfuncs.exp, gdb.t20/classes.exp, gdb.t20/inherit.exp,
+ gdb.t20/misc.exp, gdb.t22/virtfuncs.exp: Restart UDI connection
+ after program completion.
+ * gdb.t10/crossload.exp: Does not work for a29k-*-*, since BFD is
+ compiled with a SELECT_VECS setting.
+ * gdb.t15/funcargs.exp: Use argument to backtrace to prevent
+ infinite recursion.
+
+ * gdb.t20/classes.exp, gdb.t20/inherit.exp, gdb.t22/virtfuncs.exp:
+ Added checks for COFF results, and made them expected failures for
+ all targets. It would be better to make them expected failures
+ for COFF targets only.
+
+Wed Mar 24 14:43:38 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com)
+
+ * Makefile.in: add null dvi target, don't bother to recurse
+ through test directories for info and install-info; rename
+ $(datadir) to be dejagnu instead of deja-gnu
+
+Wed Mar 24 09:48:03 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t31/gdbme.ch: Re-enable code that previously caused
+ compiler to coredump.
+ * gdb.t31/chillvars.exp: Re-enable tests that depend on that
+ code.
+
+Tue Mar 23 08:53:42 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t31/gdbme.ch: Comment out code that causes chill compiler
+ coredump.
+ * gdb.t31/chillvars.exp: Comment out tests that depend on that
+ code.
+
+Sun Mar 21 17:56:47 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * gdb.t03/ptype.exp: tests for return code from gdb_test.
+ * gdb.t00/teststrategy.exp: Uses which proc rather than spawning
+ which in a shell. Deletes xgdb when done.
+ * config/unix-gdb.exp: Won't try to spawn $GDB unless it exists.
+ Tests the return from the "set height" or "set width" commands.
+ Added a few return codes where needed.
+
+Wed Mar 17 11:31:01 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (SUBDIRS): Add gdb.t17.
+ * configure.in (subdirs): Add gdb.t17.
+ * gdb.t17/{Makefile.in, callfuncs.exp, gdbme.c}: New test
+ files to test gdb's calling of functions in the inferior with
+ the correct arguments and gdb's ability to retrieve any
+ result returned.
+
+Tue Mar 16 15:37:11 1993 Fred Fish (fnf@cygnus.com)
+
+ * config/unix-gdb.exp (gdb_exit): Remove close commands that
+ may be called after gdb goes away. Previous versions of expect
+ needed these to avoid file descriptor leaks, but they cause
+ errors with the current revision of expect.
+ * gdb.t00/gdbvars.exp: Use -re on expected output after
+ setting sevenbit-strings.
+ * gdb.t04/setvar.exp, gdb.t13/bitfields.exp: Make commands
+ to set sevenbit-strings consistent across tests.
+ gdb.t30/chexp.exp, gdb.t31/chillvars.exp: Make commands to
+ set sevenbit-strings consistent across tests.
+
+Fri Mar 12 08:47:20 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t21/demangle.exp (proc demangle): Adjust quotes in an
+ expected output to match current "expect" expectations.
+
+Wed Mar 10 18:01:49 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t00/default.exp: Change expected output for default "source"
+ command, to match new gdb behavior which requires a filename to
+ source.
+
+Tue Mar 9 11:00:56 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t07/watchpoint.exp (test_simple_watchpoint): Set up
+ expected fail for i486-*-* that misses the marker2 function.
+ * gdb.t10/crossload.exp (bfddefault): Allow successful
+ recognition of a format to pass even if no symbols are found.
+ Explicitly catch failures where the format is not recognized
+ or is ambiguous, and add the reason to the fail message.
+ * gdb.t10/crossload.exp (bfdexplicit): Catch failure where
+ the cause is and invalid target and add reason to failure message.
+ * gdb.t10/crossload.exp: Fix bfd target names for elf32-m68k,
+ elf32-i386, elf32-sparc, and elf32-i860.
+ * gdb.t12/scope.exp (test_at_main, test_at_foo, test_at_bar):
+ Set up expected failure for 'filename'::variable scope resolution,
+ which is now apparently broken on all targets.
+ * gdb.t20/classes.exp, gdb.t20/inherit.exp, gdb.t20/misc.exp,
+ gdb.t21/cplusfuncs.exp, gdb.t22/virtfunc.exp,
+ gdb.t23/templates.exp: Change failure for missing binfile into
+ just a warning.
+ gdb.t21/demangle.exp: Change all cfront references to 'arm'
+ references.
+
+Mon Mar 8 19:20:28 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t00/default.exp: Add expected output for default "source"
+ command, to match new gdb behavior.
+ * gdb.t09/corefile.exp: Use GDBFLAGS when spawning GDB.
+
+Sun Mar 7 15:14:09 1993 Rob Savoye (rob@cygnus.com)
+
+ * config/*-gdb.exp: returns an error, rather than exiting on
+ internal errors.
+
+Tue Mar 2 18:09:32 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t03/gdbme.c: Add pointer to struct variable.
+ * gdb.t03/ptype.exp: Test equivalence of '.' and '->' for
+ referencing struct members.
+
+Thu Feb 25 10:39:06 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in (mips-idt-ecoff): New target.
+ * config/mips-gdb.exp: New file for remote board using MIPS remote
+ debugging protocol.
+
+ * Redid configuration scheme. Removed gdb.t*/configure.in.
+ Renamed gdb.t*/in-gdbme* to gdb.t*/gdbme*. Changed to use CC, CXX
+ instead of CC_FOR_TARGET, CXX_FOR_TARGET. Added mostlyclean and
+ distclean targets. Built executables via .o files. Adjusted
+ tests to account for source files in $(srcdir) rather than
+ $(objdir).
+ * lib/gdb.exp (runto): Don't expect () after the function name,
+ because it may have arguments.
+
+Wed Feb 24 08:05:38 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * gdb.t00/default.exp, gdb.t01/run.exp, gdb.t02/whatis.exp,
+ gdb.t03/ptype.exp, gdb.t06/break.exp, gdb.t12/scope.exp: Added
+ expected failures for mips-idt-* and mips-sgi-*.
+ * gdb.t00/default.exp (attach): Kill process if requested.
+ * gdb.t00/help.exp (help target core, help target): Accept a gdb
+ that does not read core files.
+ * gdb.t01/run.exp: Removed checks for exit status code.
+ * gdb.t03/in-gdbme.c: Make explicit call to malloc to ensure that
+ it is linked in.
+ * gdb.t03/ptype.exp: Increase timeout when calling malloc.
+ * gdb.t04/setvar.exp, gdb.t05/expr.exp: Use runto function where
+ appropriate, rather than doing it by hand.
+ * gdb.t07/watchpoint.exp: If mips-idt-*, reload file after first
+ execution.
+ * gdb.t10/crossload.exp: Kill existing program if needed.
+ * gdb.t15/funcargs.exp: Use delete_breakpoints function where
+ appropriate, rather than doing it by hand. Always increase
+ timeout for this test, not just for VxWorks.
+
+Wed Feb 24 08:03:38 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t31/chillvars.exp (test_structs): New proc to test printing
+ of Chill STRUCT types and STRUCT values.
+ * gdb.t31/chillvars.exp (test_strings): Expect "CHAR" now, rather
+ than "char".
+ * gdb.t31/in-gdbme.ch (simple_struct, nested_struct, struct1,
+ struct2): New struct definitions and initializations to test
+ simple Chill STRUCT types.
+
+Tue Feb 23 11:55:06 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t00/teststrategy.exp: Track reversion in gdb to not print
+ the null byte at the end of strings.
+ * gdb.t00/default.exp: Make show version insensitive to copyright
+ date.
+ * gdb.t16/in-gdbme.c (ctable1, ctable2): Make explicitly unsigned
+ to avoid dependencies on target char signedness.
+ * gdb.t16/printcmds.exp: Update expected results for explicitly
+ unsigned char.
+ * gdb.t16/printcmds.exp: Remove setup_xfails for i960 that should
+ now work.
+ * gdb.t21/demangle.exp: Add many more patterns for template
+ demangling, most of them being expected failures.
+ * gdb.t21/demangle.exp (proc demangle): Quote the demangled
+ string we are matching for, to match on the whole string.
+ * gdb.t21/demangle.exp: Add many new test strings to demangle,
+ and fix a whole bunch that had incorrect expected output but were
+ passing anyway because of the bug in "proc demangle".
+ * gdb.t31/chillvars.exp: Remove setup_xfail for printing string
+ type.
+ * gdb.t31/in-gdbme.ch: Uncomment string4, now compiles.
+
+Mon Feb 22 07:54:03 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * gdb/testsuite: made modifications to testcases, etc., to allow
+ them to work properly given the reorganization of deja-gnu and the
+ relocation of the testcases from deja-gnu to a "tool" subdirectory.
+
+Sun Feb 21 10:55:55 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * gdb/testsuite: Initial creation of gdb/testsuite.
+ Migrated dejagnu testcases and support files for testing nm to
+ gdb/testsuite from deja-gnu. These files were moved "as is"
+ with no modifications. This migration is part of a major overhaul
+ of dejagnu. The modifications to these testcases, etc., which
+ will allow them to work with the new version of dejagnu will be
+ made in a future update.
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/testsuite/Makefile.in b/gdb/testsuite/Makefile.in
new file mode 100644
index 00000000000..b936e39fdb9
--- /dev/null
+++ b/gdb/testsuite/Makefile.in
@@ -0,0 +1,192 @@
+# Makefile for regression testing the GNU debugger.
+# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000
+# Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB 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, or (at your option)
+# any later version.
+
+# GDB 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.
+
+VPATH = @srcdir@
+srcdir = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+host_alias = @host_alias@
+target_alias = @target_alias@
+program_transform_name = @program_transform_name@
+build_canonical = @build@
+host_canonical = @host@
+target_canonical = @target@
+target_cpu = @gdb_target_cpu@
+
+SHELL = @SHELL@
+EXEEXT = @EXEEXT@
+SUBDIRS = @subdirs@
+RPATH_ENVVAR = @RPATH_ENVVAR@
+
+EXPECT = `if [ -f $${rootme}/../../expect/expect ] ; then \
+ echo $${rootme}/../../expect/expect ; \
+ else echo expect ; fi`
+
+RUNTEST = $(RUNTEST_FOR_TARGET)
+
+RUNTESTFLAGS =
+
+RUNTEST_FOR_TARGET = `\
+ if [ -f $${srcdir}/../../dejagnu/runtest ]; then \
+ echo $${srcdir}/../../dejagnu/runtest; \
+ else \
+ if [ "$(host_canonical)" = "$(target_canonical)" ]; then \
+ echo runtest; \
+ else \
+ t='$(program_transform_name)'; echo runtest | sed -e '' $$t; \
+ fi; \
+ fi`
+
+#### host, target, and site specific Makefile frags come in here.
+
+# The use of $$(x_FOR_TARGET) reduces the command line length by not
+# duplicating the lengthy definition.
+
+TARGET_FLAGS_TO_PASS = \
+ "prefix=$(prefix)" \
+ "exec_prefix=$(exec_prefix)" \
+ "against=$(against)" \
+ 'CC=$$(CC_FOR_TARGET)' \
+ "CC_FOR_TARGET=$(CC_FOR_TARGET)" \
+ "CFLAGS=$(TESTSUITE_CFLAGS)" \
+ "CHILLFLAGS=$(CHILLFLAGS)" \
+ 'CHILL=$$(CHILL_FOR_TARGET)' \
+ "CHILL_FOR_TARGET=$(CHILL_FOR_TARGET)" \
+ "CHILL_LIB=$(CHILL_LIB)" \
+ 'CXX=$$(CXX_FOR_TARGET)' \
+ "CXX_FOR_TARGET=$(CXX_FOR_TARGET)" \
+ "CXXFLAGS=$(CXXFLAGS)" \
+ "MAKEINFO=$(MAKEINFO)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "LIBS=$(LIBS)" \
+ "RUNTEST=$(RUNTEST)" \
+ "RUNTESTFLAGS=$(RUNTESTFLAGS)"
+
+all:
+ @echo "Nothing to be done for all..."
+
+.NOEXPORT:
+INFODIRS=doc
+info:
+install-info:
+dvi:
+html:
+install-html:
+
+install:
+
+uninstall: force
+
+site.exp: ./config.status Makefile
+ @echo "Making a new config file..."
+ -@rm -f ./tmp?
+ @touch site.exp
+ -@mv site.exp site.bak
+ @echo "## these variables are automatically generated by make ##" > ./tmp0
+ @echo "# Do not edit here. If you wish to override these values" >> ./tmp0
+ @echo "# add them to the last section" >> ./tmp0
+ @echo "set host_alias $(host_alias)" >> ./tmp0
+ @echo "set host_triplet ${host_canonical}" >> ./tmp0
+ @echo "set target_alias $(target_alias)" >> ./tmp0
+ @echo "set target_triplet ${target_canonical}" >> ./tmp0
+ @echo "set build_triplet ${build_canonical}" >> ./tmp0
+ @echo "set srcdir ${srcdir}" >> ./tmp0
+ @echo "set tool gdb" >> ./tmp0
+ @echo "## All variables above are generated by configure. Do Not Edit ##" >> ./tmp0
+ @cat ./tmp0 > site.exp
+ @cat site.bak | sed \
+ -e '1,/^## All variables above are.*##/ d' >> site.exp
+ -@rm -f ./tmp?
+
+installcheck:
+
+check: site.exp all just-check
+
+just-check:
+ rootme=`pwd`; export rootme; \
+ srcdir=${srcdir} ; export srcdir ; \
+ EXPECT=${EXPECT} ; export EXPECT ; \
+ EXEEXT=${EXEEXT} ; export EXEEXT ; \
+ $(RPATH_ENVVAR)=$$rootme/../../expect:$$rootme/../../libstdc++:$$rootme/../../tk/unix:$$rootme/../../tcl/unix:$$rootme/../../bfd:$$rootme/../../opcodes:$$$(RPATH_ENVVAR); \
+ export $(RPATH_ENVVAR); \
+ if [ -f $${rootme}/../../expect/expect ] ; then \
+ TCL_LIBRARY=$${srcdir}/../../tcl/library ; \
+ export TCL_LIBRARY ; fi ; \
+ $(RUNTEST) $(RUNTESTFLAGS)
+
+subdir_do: force
+ @for i in $(DODIRS); do \
+ if [ -d ./$$i ] ; then \
+ if (rootme=`pwd`/ ; export rootme ; \
+ rootsrc=`cd $(srcdir); pwd`/ ; export rootsrc ; \
+ cd ./$$i; \
+ $(MAKE) $(TARGET_FLAGS_TO_PASS) $(DO)) ; then true ; \
+ else exit 1 ; fi ; \
+ else true ; fi ; \
+ done
+
+force:;
+
+subdirs:
+ for dir in ${SUBDIRS} ; \
+ do \
+ echo "$$dir:" ; \
+ if [ -d $$dir ] ; then \
+ (rootme=`pwd`/ ; export rootme ; \
+ rootsrc=`cd $(srcdir); pwd`/ ; export rootsrc ; \
+ cd $$dir; $(MAKE) $(TARGET_FLAGS_TO_PASS)); \
+ fi; \
+ done
+
+clean mostlyclean:
+ -rm -f *~ core *.o a.out xgdb *.x *.grt
+ if [ x"${SUBDIRS}" != x ] ; then \
+ for dir in ${SUBDIRS}; \
+ do \
+ echo "$$dir:"; \
+ if [ -d $$dir ]; then \
+ (cd $$dir; $(MAKE) clean); \
+ fi; \
+ done ; \
+ else true; fi
+
+distclean maintainer-clean realclean: clean
+ -rm -f *~ core
+ -rm -f Makefile config.status *-init.exp
+ -rm -fr *.log summary detail *.plog *.sum *.psum site.*
+ if [ x"${SUBDIRS}" != x ] ; then \
+ for dir in ${SUBDIRS}; \
+ do \
+ echo "$$dir:"; \
+ if [ -d $$dir ]; then \
+ (cd $$dir; $(MAKE) distclean); \
+ fi; \
+ done ; \
+ else true; fi
+
+Makefile : Makefile.in config.status $(host_makefile_frag) $(target_makefile_frag)
+ $(SHELL) config.status
+
+config.status: configure
+ $(SHELL) config.status --recheck
diff --git a/gdb/testsuite/TODO b/gdb/testsuite/TODO
new file mode 100644
index 00000000000..978991c77cd
--- /dev/null
+++ b/gdb/testsuite/TODO
@@ -0,0 +1,202 @@
+The highest priority item is not on this list: Fix bugs in the
+existing testsuite, fix the GDB/compiler/shell/etc bugs which it
+detects (particularly when they are hard to XFAIL), make it run
+reliably without unexpected failures on the "standard" machines, etc.
+This list exists largely as "tests we can add when we are ready to
+risk destabilizing it again".
+
+There are some tests which are only run on some platforms because they
+have not been tested on more platforms. Enable them and fix any
+problems. A partial list: recurse.exp, watchpoint.exp
+(test_watchpoint_triggered_in_syscall, test_complex_watchpoint).
+
+Test printing of structures passed by value, for the 7th, 8th, and 9th
+arguments (PR 1714). Test printing structure arguments of
+2,4,6,8,12,16,and 20 bytes. Same for structure return of all those
+sizes ("return", "finish", and call function).
+
+Get crossload tests to use --enable-targets and reenable them.
+
+corefile.exp:
+Test ability to run program when there is a core target, then go
+back to the core file when the program exits.
+
+Test handling of floating point variables
+1. float, double, or long double
+2. in register or saved register or memory. Also the case where a
+double is in two float registers and only one of them is saved.
+3. print them or set them
+4. (Alpha) integer (32 or 64 bit) in floating point register.
+
+Print registers--"p $r5", "p sizeof ($r5)". Test that they print
+appropriately (integer registers in decimal, registers which always
+contain addresses (pc, probably sp and fp, maybe others) in hex,
+floating point).
+
+Test completer. Test that it completes a variety of things correctly
+(see the list of test cases in main.c in the gdb source). Test TAB,
+M-?, and the "complete" command.
+
+Test "info line" with all kinds of linespecs. Test that the last line
+of the file works right.
+
+weird.exp--test that unrecognized cross-reference types or
+unrecognized visibility or virtual characters get skipped properly
+(see stabs.texinfo).
+
+Test C++ nested types (especially if PR 1954 is fixed; even if not
+*some* things already should work even in the presence of nested
+types). Test classes nested more than 9 levels deep (g++ mangles
+these differently) (both a demangle test and some tests which also
+test the compiler). Test calling a method of a class nested more than
+9 levels (for gdb_mangle_name and demangling).
+
+Test static member functions (C++). Test that "ptype" shows them
+correctly, both before and after they have been converted from stub
+methods. Test that we can call them.
+
+Test printing complicated types, including functions, pointers to
+arrays of pointers of functions, functions which return pointers to
+functions, etc.
+
+printcmd.exp--test printing enum values. Test printing an enum
+variable whose value is out of range. Test "p (int)enum_var", "p/x
+enum_var". Test that in something like "enum {FOO, LAST_THING=FOO}"
+we print FOO, not LAST_THING.
+
+Test GDB expressions--test all operators (and overloaded operators for
+C++). Test integer constants which are signed or unsigned int, long,
+or long long. Test detection of overflow of an integer constant.
+Here are a few integer constants to test (test they get the right
+types): 5, 5LL, 5LuL, 5L6u (invalid), 5LU. Maybe things like
+0x12345678, 0x87654321, etc., but their types depend on sizes of int,
+long, etc.
+
+Test that printing const-qualified versions of various types works.
+In particular, on the sparc and probably other machines, "double" is
+handled differently from most types because it requires more alignment
+and thus goes in a different section (there is a gcc 2.4.5 bug with
+"const double" on sparc).
+
+Test that GDB's "source" command works and that things work if stdin
+is redirected (to a file or a pipe). Test user defined command. Run
+an inferior each of these ways (to test that inflow.c works). Test
+that GDB works if the last line of stdin or a source'd file lacks a
+newline.
+
+Test that unmatched single quotes produce error messages, both in
+expressions and linespecs.
+
+Test "cd". "foo/bar/.." should get simplified to "foo". "/../.."
+should not get simplified (for Mach). "/.." should not get simplified
+(for other networked OSes; POSIX.1 section B.2.3.7). All these
+examples should continue to work with trailing slashes.
+
+Test scoping; here is a start
+ 1 int i=2;
+ 2 int j=3;
+ 3 main()
+ 4 {
+ 5 int i;
+ 6 for (i=600; i>0; i--)
+ 7 print_line(i);
+ 8 }
+ 9
+10 print_line(i)
+11 int i;
+12 {
+13 h();
+14 printf("%d\n",i);
+15 }
+16
+17 h()
+18 {
+19 printf("In h...");
+20 }
+Set a breakpoint in h, and print i, print_line::i, and main::i. Set a
+breakpoint in main (or don't run the program), and test that
+print_line::i is an error. But if i were static, "p main::i" should
+work even if the program is not being run.
+
+Write a test for the reentracy bug with rs6000_struct_return_address
+in rs6000-tdep.c.
+
+Test "return" from dummy frames. Test "return" from non-innermost
+frame. Test that "return" from a non-innermost frame restores
+registers which are saved not in that frame but in a frame more inner
+(I believe this currently works on few if any architectures).
+
+FORTRAN common blocks (a.out and xcoff--weird.exp has the start of
+one but it is not quite right as of 19 Nov 1993).
+
+Test that "x" command sets $_ and $__. Test $_ in general.
+
+Test that "p/a" works when given addresses in text, data, and bss
+segments. Test that it works if program is compiled with or without
+-g. Test that it works if preceding symbol is static or if it is
+extern.
+
+Given `char abc[] = "abc\0def";' test "x/s abc" followed by "x/s"
+(should display "abc" followed by "def"). Test this works with no
+error message even if this is the last thing in the section (tests
+that val_print_string ignores an error if the error occurs after the
+'\0').
+
+Test ability to process NMAGIC a.out files.
+
+Test shared libraries: "next" over printf, "step" into a function in
+a shared library which has line number info, breakpoint in a function
+in a shared library (either before or after the program is run and the
+shared libraries are loaded--also maybe write a test where the PLT
+will be in an unloaded state even though the shared library is loaded).
+
+If there are two breakpoints in the same place, and exactly one of
+them has its condition true, test that the correct breakpoint gets
+printed.
+
+Test "jump" including jump to a breakpoint (the latter will need an
+xfail for UDI and probably VxWorks (PR 1786 for vxworks; PR 2416
+contains some info for 29k).
+
+Set a watchpoint on a local variable (to be interesting, make a few
+calls, to be more interesting, make a recursive call). Test that it
+gets disabled when leaving that scope.
+
+Test calling a function, hitting a breakpoint in the called function,
+calling another function, and hitting a breakpoint. Test backtrace
+works in the presence of multiple dummy frames. Test that "continue"
+will get you out of the inner called function, and "continue" again
+will get you back to where you were when you called the first one.
+
+Test special longjmp handling in wait_for_inferior (need to figure out
+in detail what the proper behavior in each case is). Test longjmp to
+a place where there is a breakpoint (such that
+BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE happens). In general, test
+interactions between longjmp and watchpoints, breakpoints, stepping,
+call function, etc.
+
+Test jumping right past a breakpoint (the case where wait_for_inferior
+passes not_a_breakpoint to bpstat_stop_status). Might already be
+tested by some of the sun3 tests. Probably want a .s test to avoid
+compiler dependencies.
+
+Test more obscure wait_for_inferior cases, expanding on the tests in
+watchpoint.exp, signals.exp, etc.
+
+Test stepping into functions which are one line long and functions
+which are on line 1 of the source file. (there is a class of bugs in
+which gdb doesn't find the line number information, and thus doesn't
+step into the function).
+
+Test that prologue recognition, backtrace, printing locals, etc.,
+still work in the presence of large frames (the point being that at
+some point immediate fields in RISC instructions will overflow and
+prologues will need to look different. For sparc, the immediate field
+is 13 bits (signed), so I believe the threshold would be 4K bytes in a
+frame).
+
+
+(this is for editing this file with GNU emacs)
+Local Variables:
+mode: text
+End:
diff --git a/gdb/testsuite/aclocal.m4 b/gdb/testsuite/aclocal.m4
new file mode 100644
index 00000000000..c754fdcf2f7
--- /dev/null
+++ b/gdb/testsuite/aclocal.m4
@@ -0,0 +1,583 @@
+dnl This file is duplicated in four places:
+dnl * gdb/aclocal.m4
+dnl * gdb/testsuite/aclocal.m4
+dnl * expect/aclocal.m4
+dnl * dejagnu/aclocal.m4
+dnl Consider modifying all copies in parallel.
+dnl written by Rob Savoye <rob@cygnus.com> for Cygnus Support
+dnl CYGNUS LOCAL: This gets the right posix flag for gcc
+AC_DEFUN(CY_AC_TCL_LYNX_POSIX,
+[AC_REQUIRE([AC_PROG_CC])AC_REQUIRE([AC_PROG_CPP])
+AC_MSG_CHECKING([to see if this is LynxOS])
+AC_CACHE_VAL(ac_cv_os_lynx,
+[AC_EGREP_CPP(yes,
+[/*
+ * The old Lynx "cc" only defines "Lynx", but the newer one uses "__Lynx__"
+ */
+#if defined(__Lynx__) || defined(Lynx)
+yes
+#endif
+], ac_cv_os_lynx=yes, ac_cv_os_lynx=no)])
+#
+if test "$ac_cv_os_lynx" = "yes" ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(LYNX)
+ AC_MSG_CHECKING([whether -mposix or -X is available])
+ AC_CACHE_VAL(ac_cv_c_posix_flag,
+ [AC_TRY_COMPILE(,[
+ /*
+ * This flag varies depending on how old the compiler is.
+ * -X is for the old "cc" and "gcc" (based on 1.42).
+ * -mposix is for the new gcc (at least 2.5.8).
+ */
+ #if defined(__GNUC__) && __GNUC__ >= 2
+ choke me
+ #endif
+ ], ac_cv_c_posix_flag=" -mposix", ac_cv_c_posix_flag=" -X")])
+ CC="$CC $ac_cv_c_posix_flag"
+ AC_MSG_RESULT($ac_cv_c_posix_flag)
+ else
+ AC_MSG_RESULT(no)
+fi
+])
+
+AC_DEFUN(CY_AC_PATH_TCLH, [
+#
+# Ok, lets find the tcl source trees so we can use the headers
+# Warning: transition of version 9 to 10 will break this algorithm
+# because 10 sorts before 9. We also look for just tcl. We have to
+# be careful that we don't match stuff like tclX by accident.
+# the alternative search directory is involked by --with-tclinclude
+#
+no_tcl=true
+AC_MSG_CHECKING(for Tcl private headers)
+AC_ARG_WITH(tclinclude, [ --with-tclinclude directory where tcl private headers are], with_tclinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_tclh,[
+# first check to see if --with-tclinclude was specified
+if test x"${with_tclinclude}" != x ; then
+ if test -f ${with_tclinclude}/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tclinclude} directory doesn't contain private headers])
+ fi
+fi
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../../tcl \
+ `ls -dr ${srcdir}/../../tcl[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../../../tcl \
+ `ls -dr ${srcdir}/../../../tcl[[0-9]]* 2>/dev/null ` ; do
+ if test -f $i/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i; pwd)`
+ break
+ fi
+ # Tcl 7.5 and greater puts headers in subdirectory.
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i; pwd)`/generic
+ break
+ fi
+ done
+fi
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tcl[[0-9]]* 2>/dev/null` \
+ `ls -dr /usr/local/lib/tcl[[0-9]]* 2>/dev/null` \
+ /usr/local/src/tcl \
+ /usr/local/lib/tcl \
+ ${prefix}/include ; do
+ if test -f $i/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i; pwd)`
+ break
+ fi
+ done
+fi
+# see if one is installed
+if test x"${ac_cv_c_tclh}" = x ; then
+ AC_HEADER_CHECK(tclInt.h, ac_cv_c_tclh=installed, ac_cv_c_tclh="")
+fi
+])
+if test x"${ac_cv_c_tclh}" = x ; then
+ TCLHDIR="# no Tcl private headers found"
+ AC_MSG_ERROR([Can't find Tcl private headers])
+fi
+if test x"${ac_cv_c_tclh}" != x ; then
+ no_tcl=""
+ if test x"${ac_cv_c_tclh}" = x"installed" ; then
+ AC_MSG_RESULT([is installed])
+ TCLHDIR=""
+ else
+ AC_MSG_RESULT([found in ${ac_cv_c_tclh}])
+ # this hack is cause the TCLHDIR won't print if there is a "-I" in it.
+ TCLHDIR="-I${ac_cv_c_tclh}"
+ fi
+fi
+
+AC_MSG_CHECKING([Tcl version])
+orig_includes="$CPPFLAGS"
+
+if test x"${TCLHDIR}" != x ; then
+ CPPFLAGS="$CPPFLAGS $TCLHDIR"
+fi
+
+# Get major and minor versions of Tcl. Use funny names to avoid
+# clashes with eg SunOS.
+cat > conftest.c <<'EOF'
+#include "tcl.h"
+MaJor = TCL_MAJOR_VERSION
+MiNor = TCL_MINOR_VERSION
+EOF
+
+tclmajor=
+tclminor=
+if (eval "$CPP $CPPFLAGS conftest.c") 2>/dev/null >conftest.out; then
+ # Success.
+ tclmajor=`egrep '^MaJor = ' conftest.out | sed -e 's/^MaJor = *//' -e 's/ *$//'`
+ tclminor=`egrep '^MiNor = ' conftest.out | sed -e 's/^MiNor = *//' -e 's/ *$//'`
+fi
+rm -f conftest.c conftest.out
+
+if test -z "$tclmajor" || test -z "$tclminor"; then
+ AC_MSG_RESULT([fatal error: could not find major or minor version number of Tcl])
+ exit 1
+fi
+AC_MSG_RESULT(${tclmajor}.${tclminor})
+
+CPPFLAGS="${orig_includes}"
+
+AC_PROVIDE([$0])
+AC_SUBST(TCLHDIR)
+])
+AC_DEFUN(CY_AC_PATH_TCLLIB, [
+#
+# Ok, lets find the tcl library
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tcllib
+#
+
+if test $tclmajor -ge 7 -a $tclminor -ge 4 ; then
+ installedtcllibroot=tcl$tclversion
+else
+ installedtcllibroot=tcl
+fi
+
+if test x"${no_tcl}" = x ; then
+ # we reset no_tcl incase something fails here
+ no_tcl=true
+ AC_ARG_WITH(tcllib, [ --with-tcllib directory where the tcl library is],
+ with_tcllib=${withval})
+ AC_MSG_CHECKING([for Tcl library])
+ AC_CACHE_VAL(ac_cv_c_tcllib,[
+ # First check to see if --with-tcllib was specified.
+ # This requires checking for both the installed and uninstalled name-styles
+ # since we have no idea if it's installed or not.
+ if test x"${with_tcllib}" != x ; then
+ if test -f "${with_tcllib}/lib$installedtcllibroot.so" ; then
+ ac_cv_c_tcllib=`(cd ${with_tcllib}; pwd)`/lib$installedtcllibroot.so
+ elif test -f "${with_tcllib}/libtcl.so" ; then
+ ac_cv_c_tcllib=`(cd ${with_tcllib}; pwd)`/libtcl.so
+ # then look for a freshly built statically linked library
+ # if Makefile exists we assume its configured and libtcl will be built first.
+ elif test -f "${with_tcllib}/lib$installedtcllibroot.a" ; then
+ ac_cv_c_tcllib=`(cd ${with_tcllib}; pwd)`/lib$installedtcllibroot.a
+ elif test -f "${with_tcllib}/libtcl.a" ; then
+ ac_cv_c_tcllib=`(cd ${with_tcllib}; pwd)`/libtcl.a
+ else
+ AC_MSG_ERROR([${with_tcllib} directory doesn't contain libraries])
+ fi
+ fi
+ # then check for a private Tcl library
+ # Since these are uninstalled, use the simple lib name root.
+ if test x"${ac_cv_c_tcllib}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[[0-9]]* 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[[0-9]]* 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[[0-9]]* 2>/dev/null` ; do
+ # Tcl 7.5 and greater puts library in subdir. Look there first.
+ if test -f "$i/unix/libtcl.so" ; then
+ ac_cv_c_tcllib=`(cd $i; pwd)`/unix/libtcl.so
+ break
+ elif test -f "$i/unix/libtcl.a" -o -f "$i/unix/Makefile"; then
+ ac_cv_c_tcllib=`(cd $i; pwd)`/unix/libtcl.a
+ break
+ # look for a freshly built dynamically linked library
+ elif test -f "$i/libtcl.so" ; then
+ ac_cv_c_tcllib=`(cd $i; pwd)`/libtcl.so
+ break
+
+ # then look for a freshly built statically linked library
+ # if Makefile exists we assume its configured and libtcl will be
+ # built first.
+ elif test -f "$i/libtcl.a" -o -f "$i/Makefile" ; then
+ ac_cv_c_tcllib=`(cd $i; pwd)`/libtcl.a
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tcllib}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ # first look for a freshly built dynamically linked library
+ if test -f "$i/lib$installedtcllibroot.so" ; then
+ ac_cv_c_tcllib=`(cd $i; pwd)`/lib$installedtcllibroot.so
+ break
+ # then look for a freshly built statically linked library
+ # if Makefile exists we assume its configured and libtcl will be built first.
+ elif test -f "$i/lib$installedtcllibroot.a" -o -f "$i/Makefile" ; then
+ ac_cv_c_tcllib=`(cd $i; pwd)`/lib$installedtcllibroot.a
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_tcllib}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[[0-9]]* 2>/dev/null` ; do
+ # Tcl 7.5 and greater puts library in subdir. Look there first.
+ if test -f "$i/unix/libtcl.so" ; then
+ ac_cv_c_tcllib=`(cd $i; pwd)`/unix/libtcl.so
+ break
+ elif test -f "$i/unix/libtcl.a" -o -f "$i/unix/Makefile"; then
+ ac_cv_c_tcllib=`(cd $i; pwd)`/unix/libtcl.a
+ break
+ # look for a freshly built dynamically linked library
+ elif test -f "$i/libtcl.so" ; then
+ ac_cv_c_tcllib=`(cd $i; pwd)`/libtcl.so
+ break
+
+ # then look for a freshly built statically linked library
+ # if Makefile exists we assume its configured and libtcl will be
+ # built first.
+ elif test -f "$i/libtcl.a" -o -f "$i/Makefile" ; then
+ ac_cv_c_tcllib=`(cd $i; pwd)`/libtcl.a
+ break
+ fi
+ done
+ fi
+
+ # see if one is conveniently installed with the compiler
+ if test x"${ac_cv_c_tcllib}" = x ; then
+ orig_libs="$LIBS"
+ LIBS="$LIBS -l$installedtcllibroot -lm"
+ AC_TRY_RUN([
+ Tcl_AppInit()
+ { exit(0); }], ac_cv_c_tcllib="-l$installedtcllibroot", ac_cv_c_tcllib=""
+ , ac_cv_c_tclib="-l$installedtcllibroot")
+ LIBS="${orig_libs}"
+ fi
+ ])
+ if test x"${ac_cv_c_tcllib}" = x ; then
+ TCLLIB="# no Tcl library found"
+ AC_MSG_WARN(Can't find Tcl library)
+ else
+ TCLLIB=${ac_cv_c_tcllib}
+ AC_MSG_RESULT(found $TCLLIB)
+ no_tcl=
+ fi
+fi
+
+AC_PROVIDE([$0])
+AC_SUBST(TCLLIB)
+])
+AC_DEFUN(CY_AC_PATH_TKH, [
+#
+# Ok, lets find the tk source trees so we can use the headers
+# If the directory (presumably symlink) named "tk" exists, use that one
+# in preference to any others. Same logic is used when choosing library
+# and again with Tcl. The search order is the best place to look first, then in
+# decreasing significance. The loop breaks if the trigger file is found.
+# Note the gross little conversion here of srcdir by cd'ing to the found
+# directory. This converts the path from a relative to an absolute, so
+# recursive cache variables for the path will work right. We check all
+# the possible paths in one loop rather than many seperate loops to speed
+# things up.
+# the alternative search directory is invoked by --with-tkinclude
+#
+AC_MSG_CHECKING(for Tk private headers)
+AC_ARG_WITH(tkinclude, [ --with-tkinclude directory where the tk private headers are],
+ with_tkinclude=${withval})
+no_tk=true
+AC_CACHE_VAL(ac_cv_c_tkh,[
+# first check to see if --with-tkinclude was specified
+if test x"${with_tkinclude}" != x ; then
+ if test -f ${with_tkinclude}/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tkinclude} directory doesn't contain private headers])
+ fi
+fi
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse the entire list
+# and search for the worst fit, overwriting it with better fits as we find them
+if test x"${ac_cv_c_tkh}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../../tk \
+ `ls -dr ${srcdir}/../../tk[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../../../tk \
+ `ls -dr ${srcdir}/../../../tk[[0-9]]* 2>/dev/null ` ; do
+ if test -f $i/tk.h ; then
+ ac_cv_c_tkh=`(cd $i; pwd)`
+ break
+ fi
+ # Tk 4.1 and greater puts this in a subdir.
+ if test -f $i/generic/tk.h; then
+ ac_cv_c_tkh=`(cd $i; pwd)`/generic
+ fi
+ done
+fi
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse the entire list
+# and search for the worst fit, overwriting it with better fits as we find them
+if test x"${ac_cv_c_tkh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tk[[0-9]]* 2>/dev/null` \
+ `ls -dr /usr/local/lib/tk[[0-9]]* 2>/dev/null` \
+ /usr/local/src/tk \
+ /usr/local/lib/tk \
+ ${prefix}/include ; do
+ if test -f $i/tk.h ; then
+ ac_cv_c_tkh=`(cd $i; pwd)`
+ break
+ fi
+ done
+fi
+# see if one is installed
+if test x"${ac_cv_c_tkh}" = x ; then
+ AC_HEADER_CHECK(tk.h, ac_cv_c_tkh=installed)
+fi
+])
+if test x"${ac_cv_c_tkh}" != x ; then
+ no_tk=""
+ if test x"${ac_cv_c_tkh}" = x"installed" ; then
+ AC_MSG_RESULT([is installed])
+ TKHDIR=""
+ else
+ AC_MSG_RESULT([found in $ac_cv_c_tkh])
+ # this hack is cause the TKHDIR won't print if there is a "-I" in it.
+ TKHDIR="-I${ac_cv_c_tkh}"
+ fi
+else
+ TKHDIR="# no Tk directory found"
+ AC_MSG_WARN([Can't find Tk private headers])
+ no_tk=true
+fi
+
+# if Tk is installed, extract the major/minor version
+if test x"${no_tk}" = x ; then
+AC_MSG_CHECKING([Tk version])
+orig_includes="$CPPFLAGS"
+
+if test x"${TCLHDIR}" != x ; then
+ CPPFLAGS="$CPPFLAGS $TCLHDIR"
+fi
+if test x"${TKHDIR}" != x ; then
+ CPPFLAGS="$CPPFLAGS $TKHDIR"
+fi
+if test x"${x_includes}" != x -a x"${x_includes}" != xNONE ; then
+ CPPFLAGS="$CPPFLAGS -I$x_includes"
+fi
+
+# Get major and minor versions of Tk. Use funny names to avoid
+# clashes with eg SunOS.
+cat > conftest.c <<'EOF'
+#include "tk.h"
+MaJor = TK_MAJOR_VERSION
+MiNor = TK_MINOR_VERSION
+EOF
+
+tkmajor=
+tkminor=
+if (eval "$CPP $CPPFLAGS conftest.c") 2>/dev/null >conftest.out; then
+ # Success.
+ tkmajor=`egrep '^MaJor = ' conftest.out | sed -e 's/^MaJor = *//' -e 's/ *$//'`
+ tkminor=`egrep '^MiNor = ' conftest.out | sed -e 's/^MiNor = *//' -e 's/ *$//'`
+fi
+rm -f conftest.c conftest.out
+
+if test -z "$tkmajor" || test -z "$tkminor"; then
+ AC_MSG_RESULT([fatal error: could not find major or minor version number of Tk])
+ exit 1
+fi
+AC_MSG_RESULT(${tkmajor}.${tkminor})
+
+CPPFLAGS="${orig_includes}"
+fi
+
+AC_PROVIDE([$0])
+AC_SUBST(TKHDIR)
+])
+AC_DEFUN(CY_AC_PATH_TKLIB, [
+AC_REQUIRE([CY_AC_PATH_TCL])
+#
+# Ok, lets find the tk library
+# First, look for the latest private (uninstalled) copy
+# Notice that the destinations in backwards priority since the tests have
+# no break.
+# Then we look for either .a, .so, or Makefile. A Makefile is acceptable
+# is it indicates the target has been configured and will (probably)
+# soon be built. This allows an entire tree of Tcl software to be
+# configured at once and then built.
+# the alternative search directory is invoked by --with-tklib
+#
+
+if test x"${no_tk}" = x ; then
+ # reset no_tk incase something fails here
+ no_tk="true"
+
+ if test $tkmajor -ge 4 ; then
+ installedtklibroot=tk$tkversion
+ else
+ installedtkllibroot=tk
+ fi
+
+ AC_ARG_WITH(tklib, [ --with-tklib directory where the tk library is],
+ with_tklib=${withval})
+ AC_MSG_CHECKING([for Tk library])
+ AC_CACHE_VAL(ac_cv_c_tklib,[
+ # first check to see if --with-tklib was specified
+ # This requires checking for both the installed and uninstalled name-styles
+ # since we have no idea if it's installed or not.
+ if test x"${with_tklib}" != x ; then
+ if test -f "${with_tklib}/lib$installedtklibroot.so" ; then
+ ac_cv_c_tklib=`(cd ${with_tklib}; pwd)`/lib$installedtklibroot.so
+ no_tk=""
+ elif test -f "${with_tklib}/libtk.so" ; then
+ ac_cv_c_tklib=`(cd ${with_tklib}; pwd)`/libtk.so
+ no_tk=""
+ # then look for a freshly built statically linked library
+ # if Makefile exists we assume its configured and libtk will be built
+ elif test -f "${with_tklib}/lib$installedtklibroot.a" ; then
+ ac_cv_c_tklib=`(cd ${with_tklib}; pwd)`/lib$installedtklibroot.a
+ no_tk=""
+ elif test -f "${with_tklib}/libtk.a" ; then
+ ac_cv_c_tklib=`(cd ${with_tklib}; pwd)`/libtk.a
+ no_tk=""
+ else
+ AC_MSG_ERROR([${with_tklib} directory doesn't contain libraries])
+ fi
+ fi
+ # then check for a private Tk library
+ # Since these are uninstalled, use the simple lib name root.
+ if test x"${ac_cv_c_tklib}" = x ; then
+ for i in \
+ ../tk \
+ `ls -dr ../tk[[0-9]]* 2>/dev/null` \
+ ../../tk \
+ `ls -dr ../../tk[[0-9]]* 2>/dev/null` \
+ ../../../tk \
+ `ls -dr ../../../tk[[0-9]]* 2>/dev/null` ; do
+ # Tk 4.1 and greater puts things in subdirs. Check these first.
+ if test -f "$i/unix/libtk.so" ; then
+ ac_cv_c_tklib=`(cd $i; pwd)`/unix/libtk.so
+ no_tk=
+ break
+ elif test -f "$i/unix/libtk.a" -o -f "$i/unix/Makefile"; then
+ ac_cv_c_tklib=`(cd $i; pwd)`/unix/libtk.a
+ no_tk=
+ break
+ # look for a freshly built dynamically linked library
+ elif test -f "$i/libtk.so" ; then
+ ac_cv_c_tklib=`(cd $i; pwd)`/libtk.so
+ no_tk=
+ break
+ # then look for a freshly built statically linked library
+ # if Makefile exists we assume its configured and libtk will be built
+ elif test -f "$i/libtk.a" -o -f "$i/Makefile" ; then
+ ac_cv_c_tklib=`(cd $i; pwd)`/libtk.a
+ no_tk=""
+ break
+ fi
+ done
+ fi
+ # finally check in a few common install locations
+ if test x"${ac_cv_c_tklib}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ # first look for a freshly built dynamically linked library
+ if test -f "$i/lib$installedtklibroot.so" ; then
+ ac_cv_c_tklib=`(cd $i; pwd)`/lib$installedtklibroot.so
+ no_tk=""
+ break
+ # then look for a freshly built statically linked library
+ # if Makefile exists, we assume it's configured and libtcl will be built
+ elif test -f "$i/lib$installedtklibroot.a" -o -f "$i/Makefile" ; then
+ ac_cv_c_tklib=`(cd $i; pwd)`/lib$installedtklibroot.a
+ no_tk=""
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_tklib}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[[0-9]]* 2>/dev/null` ; do
+ # Tk 4.1 and greater puts things in subdirs. Check these first.
+ if test -f "$i/unix/libtk.so" ; then
+ ac_cv_c_tklib=`(cd $i; pwd)`/unix/libtk.so
+ no_tk=
+ break
+ elif test -f "$i/unix/libtk.a" -o -f "$i/unix/Makefile"; then
+ ac_cv_c_tcllib=`(cd $i; pwd)`/unix/libtk.a
+ no_tk=
+ break
+ # look for a freshly built dynamically linked library
+ elif test -f "$i/libtk.so" ; then
+ ac_cv_c_tklib=`(cd $i; pwd)`/libtk.so
+ no_tk=""
+ break
+ # then look for a freshly built statically linked library
+ # if Makefile exists, we assume it's configured and libtcl will be built
+ elif test -f "$i/libtk.a" -o -f "$i/Makefile" ; then
+ ac_cv_c_tklib=`(cd $i; pwd)`/libtk.a
+ no_tk=""
+ break
+ fi
+ done
+ fi
+ # see if one is conveniently installed with the compiler
+ if test x"${ac_cv_c_tklib}" = x ; then
+ AC_REQUIRE([AC_PATH_X])
+ orig_libs="$LIBS"
+ LIBS="$LIBS -l$installedtklibroot $x_libraries $ac_cv_c_tcllib -lm"
+ AC_TRY_RUN([
+ Tcl_AppInit()
+ { exit(0); }], ac_cv_c_tklib="-l$installedtklibroot", ac_cv_c_tklib=""
+ , ac_cv_c_tklib="-l$installedtklibroot")
+ LIBS="${orig_libs}"
+ fi
+ ])
+ if test x"${ac_cv_c_tklib}" = x ; then
+ TKLIB="# no Tk library found"
+ AC_MSG_WARN(Can't find Tk library)
+ else
+ TKLIB=$ac_cv_c_tklib
+ AC_MSG_RESULT(found $TKLIB)
+ no_tk=
+ fi
+fi
+AC_PROVIDE([$0])
+AC_SUBST(TKLIB)
+])
+AC_DEFUN(CY_AC_PATH_TK, [
+ CY_AC_PATH_TKH
+ CY_AC_PATH_TKLIB
+])
+AC_DEFUN(CY_AC_PATH_TCL, [
+ CY_AC_PATH_TCLH
+ CY_AC_PATH_TCLLIB
+])
diff --git a/gdb/testsuite/config/abug.exp b/gdb/testsuite/config/abug.exp
new file mode 100644
index 00000000000..99b8a9db1f7
--- /dev/null
+++ b/gdb/testsuite/config/abug.exp
@@ -0,0 +1,20 @@
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib ../config/monitor.exp
diff --git a/gdb/testsuite/config/arm-ice.exp b/gdb/testsuite/config/arm-ice.exp
new file mode 100644
index 00000000000..d9842743d94
--- /dev/null
+++ b/gdb/testsuite/config/arm-ice.exp
@@ -0,0 +1 @@
+load_lib "../config/monitor.exp";
diff --git a/gdb/testsuite/config/cfdbug.exp b/gdb/testsuite/config/cfdbug.exp
new file mode 100644
index 00000000000..edd91e4df76
--- /dev/null
+++ b/gdb/testsuite/config/cfdbug.exp
@@ -0,0 +1,20 @@
+# Copyright 1997, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib "../config/monitor.exp"
diff --git a/gdb/testsuite/config/cpu32bug.exp b/gdb/testsuite/config/cpu32bug.exp
new file mode 100644
index 00000000000..99b8a9db1f7
--- /dev/null
+++ b/gdb/testsuite/config/cpu32bug.exp
@@ -0,0 +1,20 @@
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib ../config/monitor.exp
diff --git a/gdb/testsuite/config/cygmon.exp b/gdb/testsuite/config/cygmon.exp
new file mode 100644
index 00000000000..d9842743d94
--- /dev/null
+++ b/gdb/testsuite/config/cygmon.exp
@@ -0,0 +1 @@
+load_lib "../config/monitor.exp";
diff --git a/gdb/testsuite/config/d10v.exp b/gdb/testsuite/config/d10v.exp
new file mode 100644
index 00000000000..955288c7ff0
--- /dev/null
+++ b/gdb/testsuite/config/d10v.exp
@@ -0,0 +1,20 @@
+# Copyright (C) 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib "../config/monitor.exp"
diff --git a/gdb/testsuite/config/dve.exp b/gdb/testsuite/config/dve.exp
new file mode 100644
index 00000000000..4b60b5aa965
--- /dev/null
+++ b/gdb/testsuite/config/dve.exp
@@ -0,0 +1,23 @@
+# Copyright 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib ../config/monitor.exp
+set timeout 1000
+verbose "Timeout is now $timeout seconds" 2
+
diff --git a/gdb/testsuite/config/est.exp b/gdb/testsuite/config/est.exp
new file mode 100644
index 00000000000..99b8a9db1f7
--- /dev/null
+++ b/gdb/testsuite/config/est.exp
@@ -0,0 +1,20 @@
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib ../config/monitor.exp
diff --git a/gdb/testsuite/config/gdbserver.exp b/gdb/testsuite/config/gdbserver.exp
new file mode 100644
index 00000000000..2c63729d72e
--- /dev/null
+++ b/gdb/testsuite/config/gdbserver.exp
@@ -0,0 +1,212 @@
+# Test framework for GDB (remote protocol) using a "gdbserver",
+# ie. a debug agent running as a native process on the same or
+# a different host.
+
+# Copyright 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder. (msnyder@redhat.com)
+
+#
+# This module to be used for testing gdb with a "gdbserver"
+# built either from libremote or from gdb/gdbserver.
+#
+
+# Load the basic testing library, and the remote stuff.
+load_lib ../config/monitor.exp
+
+#
+# To be addressed or set in your baseboard config file:
+#
+# set_board_info gdb_protocol "remote"
+# Unles you have a gdbserver that uses a different protocol...
+#
+# set_board_info use_gdb_stub 1
+# This tells the rest of the test suite not to do things
+# like "run" which don't work well on remote targets.
+#
+# set_board_info gdb,do_reload_on_run 1
+# Unles you have a gdbserver that can handle multiple sessions.
+#
+# set_board_info noargs 1
+# At present there is no provision in the remote protocol
+# for passing arguments. This test framework does not
+# address the issue, so it's best to set this variable
+# in your baseboard configuration file.
+# FIXME: there's no reason why the test harness couldn't
+# pass commandline args when it spawns gdbserver.
+#
+# set_board_info gdb,noinferiorio 1
+# Neither the traditional gdbserver nor the one in libremote
+# can presently capture stdout and relay it to GDB via the
+# 'O' packet. This means that tests involving printf will
+# fail unles you set this varibale in your baseboard
+# configuration file.
+#
+# set_board_info gdb,no_hardware_watchpoints 1
+# Unles you have a gdbserver that supports hardware watchpoints.
+# FIXME: gdb should detect if the target doesn't support them,
+# and fall back to using software watchpoints.
+#
+# set_board_info gdb_server_prog
+# This will be the path to the gdbserver program you want to test.
+# Defaults to "gdbserver".
+#
+# set_board_info sockethost
+# The name of the host computer whose socket is being used.
+# Defaults to "localhost". Note: old gdbserver requires
+# that you define this, but libremote/gdbserver does not.
+#
+# set_board_info socketport
+# Port id to use for socket connection. If not set explicitly,
+# it will start at "2345" and increment for each use.
+#
+
+
+
+#
+# gdb_load -- load a file into the debugger.
+# return a -1 if anything goes wrong.
+#
+
+global server_exec;
+global portnum;
+set portnum "2345";
+
+proc gdb_load { args } {
+ global server_exec;
+ global portnum;
+ global verbose;
+ global gdb_prompt;
+
+ # Port id -- either specified in baseboard file, or managed here.
+ if [target_info exists gdb,socketport] {
+ set portnum [target_info gdb,socketport];
+ } else {
+ # Bump the port number to avoid conflicts with hung ports.
+ incr portnum;
+ }
+
+ # Extract the local and remote host ids from the target board struct.
+
+ if [target_info exists sockethost] {
+ set debughost [target_info sockethost];
+ } else {
+ set debughost "localhost:";
+ }
+ # Extract the protocol
+ if [target_info exists gdb_protocol] {
+ set protocol [target_info gdb_protocol];
+ } else {
+ set protocol "remote";
+ }
+
+ # Extract the name of the gdbserver, if known (default 'gdbserver').
+ if [target_info exists gdb_server_prog] {
+ set gdbserver [target_info gdb_server_prog];
+ } else {
+ set gdbserver "gdbserver";
+ }
+ # Extract the socket hostname
+ if [target_info exists sockethost] {
+ set sockethost [target_info sockethost];
+ } else {
+ set sockethost ""
+ }
+
+ # Export the host:port pair.
+ set gdbport $debughost$portnum;
+
+ if { $args == "" || $args == "{}" } {
+ if [info exists server_exec] {
+ set args $server_exec;
+ } else {
+ send_gdb "info files\n";
+ gdb_expect 30 {
+ -re "Symbols from \"(\[^\"\]+)\"" {
+ set args $expect_out(1,string);
+ exp_continue;
+ }
+ -re "Local exec file:\[\r\n\]+\[ \t\]*`(\[^'\]+)'," {
+ set args $expect_out(1,string);
+ exp_continue;
+ }
+ -re "$gdb_prompt $" { }
+ }
+ }
+ }
+
+ # remember new exec file
+ set server_exec $args;
+
+ # Fire off the debug agent
+ if [target_info exists gdb_server_args] {
+ # This flavour of gdbserver takes as arguments those specified
+ # in the board configuration file
+ set custom_args [target_info gdb_server_args];
+ remote_spawn host \
+ "$gdbserver $custom_args >& /dev/null < /dev/null &" \
+ writeonly
+ } else {
+ # This flavour of gdbserver takes as arguments the port information
+ # and the name of the executable file to be debugged.
+ remote_spawn host \
+ "$gdbserver $sockethost$portnum $args >& /dev/null < /dev/null &" \
+ writeonly
+ }
+ # Give it a little time to establish
+ sleep 2
+
+ # tell gdb what file we are debugging
+ if [gdb_file_cmd $args] {
+ return -1;
+ }
+
+ # attach to the "serial port"
+ gdb_target_cmd $protocol $gdbport;
+
+ # do the real load if needed
+ if [target_info exists gdb_server_do_load] {
+ send_gdb "load\n"
+ set timeout 2400
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ -re ".*$gdb_prompt $" {
+ if $verbose>1 then {
+ send_user "Loaded $arg into $GDB\n"
+ }
+ set timeout 30
+ verbose "Timeout is now $timeout seconds" 2
+ return 1
+ }
+ -re "$gdb_prompt $" {
+ if $verbose>1 then {
+ perror "GDB couldn't load."
+ }
+ }
+ timeout {
+ if $verbose>1 then {
+ perror "Timed out trying to load $arg."
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/gdb/testsuite/config/h8300.exp b/gdb/testsuite/config/h8300.exp
new file mode 100644
index 00000000000..d9842743d94
--- /dev/null
+++ b/gdb/testsuite/config/h8300.exp
@@ -0,0 +1 @@
+load_lib "../config/monitor.exp";
diff --git a/gdb/testsuite/config/hmsirom.exp b/gdb/testsuite/config/hmsirom.exp
new file mode 100644
index 00000000000..8c6e7dad560
--- /dev/null
+++ b/gdb/testsuite/config/hmsirom.exp
@@ -0,0 +1,22 @@
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Support for testing against a Hitachi SH3 target rom
+
+load_lib ../config/monitor.exp
diff --git a/gdb/testsuite/config/hppro.exp b/gdb/testsuite/config/hppro.exp
new file mode 100644
index 00000000000..e341ae6e9e5
--- /dev/null
+++ b/gdb/testsuite/config/hppro.exp
@@ -0,0 +1,24 @@
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib ../config/monitor.exp
+
+# Hppro monitor is very slow...
+set timeout 540
+verbose "Timeout is now $timeout seconds" 2
diff --git a/gdb/testsuite/config/i386-bozo.exp b/gdb/testsuite/config/i386-bozo.exp
new file mode 100644
index 00000000000..78090937380
--- /dev/null
+++ b/gdb/testsuite/config/i386-bozo.exp
@@ -0,0 +1 @@
+load_lib "../config/monitor.exp"
diff --git a/gdb/testsuite/config/i960.exp b/gdb/testsuite/config/i960.exp
new file mode 100644
index 00000000000..99b8a9db1f7
--- /dev/null
+++ b/gdb/testsuite/config/i960.exp
@@ -0,0 +1,20 @@
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib ../config/monitor.exp
diff --git a/gdb/testsuite/config/m32r-stub.exp b/gdb/testsuite/config/m32r-stub.exp
new file mode 100644
index 00000000000..cd04787ddb6
--- /dev/null
+++ b/gdb/testsuite/config/m32r-stub.exp
@@ -0,0 +1 @@
+load_lib "../../testsuite/config/sparclet.exp"
diff --git a/gdb/testsuite/config/m32r.exp b/gdb/testsuite/config/m32r.exp
new file mode 100644
index 00000000000..39688ba8cf9
--- /dev/null
+++ b/gdb/testsuite/config/m32r.exp
@@ -0,0 +1,23 @@
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib ../config/monitor.exp
+set timeout 120
+verbose "Timeout is now $timeout seconds" 2
+
diff --git a/gdb/testsuite/config/m68k-emc.exp b/gdb/testsuite/config/m68k-emc.exp
new file mode 100644
index 00000000000..70b8f5ef426
--- /dev/null
+++ b/gdb/testsuite/config/m68k-emc.exp
@@ -0,0 +1,17 @@
+load_lib gdb.exp
+load_lib "../config/monitor.exp"
+
+proc gdb_emclaptop_command { command } {
+ global board_info;
+ set tname [board_info target name];
+
+ if ![info exists board_info($tname,m68k_connected)] {
+ m68k_emc_board_connect target;
+ }
+ # This is about all we can do for now. *sigh*
+ set dos_host [board_info target dos_host];
+
+ remote_send $dos_host "${command}\n";
+ #remote_expect $dos_host {
+ #}
+}
diff --git a/gdb/testsuite/config/mips-idt.exp b/gdb/testsuite/config/mips-idt.exp
new file mode 100644
index 00000000000..72664dff1b1
--- /dev/null
+++ b/gdb/testsuite/config/mips-idt.exp
@@ -0,0 +1,22 @@
+# Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_lib ../config/monitor.exp
+
+
diff --git a/gdb/testsuite/config/mips.exp b/gdb/testsuite/config/mips.exp
new file mode 100644
index 00000000000..72664dff1b1
--- /dev/null
+++ b/gdb/testsuite/config/mips.exp
@@ -0,0 +1,22 @@
+# Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_lib ../config/monitor.exp
+
+
diff --git a/gdb/testsuite/config/mn10300-eval.exp b/gdb/testsuite/config/mn10300-eval.exp
new file mode 100644
index 00000000000..4b60b5aa965
--- /dev/null
+++ b/gdb/testsuite/config/mn10300-eval.exp
@@ -0,0 +1,23 @@
+# Copyright 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib ../config/monitor.exp
+set timeout 1000
+verbose "Timeout is now $timeout seconds" 2
+
diff --git a/gdb/testsuite/config/monitor.exp b/gdb/testsuite/config/monitor.exp
new file mode 100644
index 00000000000..c0fb464fb95
--- /dev/null
+++ b/gdb/testsuite/config/monitor.exp
@@ -0,0 +1,271 @@
+# Test Framework Driver for GDB driving a ROM monitor (via monitor.c).
+# Copyright 1995, 1996, 1997, 1998, 1999, 2000
+# Free Software Foundation, Inc.
+#
+# 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.
+
+load_lib gdb.exp
+# puts "***** DID USE MONITOR ******"
+
+#
+# gdb_target_cmd
+# Send gdb the "target" command
+#
+proc gdb_target_cmd { targetname serialport } {
+ global gdb_prompt
+
+ for {set i 1} {$i <= 3} {incr i} {
+ send_gdb "target $targetname $serialport\n"
+ gdb_expect 60 {
+ -re "A program is being debugged already.*ill it.*y or n. $" {
+ send_gdb "y\n";
+ exp_continue;
+ }
+ -re "Couldn't establish connection to remote.*$gdb_prompt" {
+ verbose "Connection failed";
+ }
+ -re "Remote MIPS debugging.*$gdb_prompt" {
+ verbose "Set target to $targetname";
+ return 0;
+ }
+ -re "Remote debugging using .*$serialport.*$gdb_prompt" {
+ verbose "Set target to $targetname";
+ return 0;
+ }
+ -re "Remote target $targetname connected to.*$gdb_prompt" {
+ verbose "Set target to $targetname";
+ return 0;
+ }
+ -re "Connected to.*$gdb_prompt" {
+ verbose "Set target to $targetname";
+ return 0;
+ }
+ -re "Ending remote.*$gdb_prompt" { }
+ -re "Connection refused.*$gdb_prompt" {
+ verbose "Connection refused by remote target. Pausing, and trying again."
+ sleep 30
+ continue
+ }
+ -re "Timeout reading from remote system.*$gdb_prompt" {
+ verbose "Got timeout error from gdb.";
+ }
+ timeout {
+ send_gdb "";
+ break
+ }
+ }
+ }
+ return 1
+}
+
+
+
+#
+# gdb_target_monitor
+# Set gdb to target the monitor
+#
+proc gdb_target_monitor { exec_file } {
+ global gdb_prompt
+ global exit_status
+ global timeout
+
+ if [target_info exists gdb_protocol] {
+ set targetname "[target_info gdb_protocol]"
+ } else {
+ perror "No protocol specified for [target_info name].";
+ return -1;
+ }
+ if [target_info exists baud] {
+ gdb_test "set remotebaud [target_info baud]" "" ""
+ }
+ if [target_info exists binarydownload] {
+ gdb_test "set remotebinarydownload [target_info binarydownload]" "" ""
+ }
+ if { [ target_info exists disable_x_packet ] } {
+ gdb_test "set remote X-packet disable" ""
+ }
+ if { [ target_info exists disable_z_packet ] } {
+ gdb_test "set remote Z-packet disable" ""
+ }
+ if [target_info exists gdb_serial] {
+ set serialport "[target_info gdb_serial]";
+ } elseif [target_info exists netport] {
+ set serialport "[target_info netport]"
+ } else {
+ set serialport "[target_info serial]"
+ }
+
+ for {set j 1} {$j <= 2} {incr j} {
+ if [gdb_file_cmd $exec_file] { return -1; }
+
+ if ![gdb_target_cmd $targetname $serialport] { return 0; }
+
+ gdb_target_exec;
+
+ if { $j == 1 && ![reboot_target] } {
+ break;
+ }
+ }
+
+ perror "Couldn't set target for $targetname, port is $serialport.";
+ return -1;
+}
+
+proc gdb_target_exec { } {
+ gdb_test "target exec" "No executable file now." "" ".*Kill it.*y or n.*" "y"
+
+}
+#
+# gdb_load -- load a file into the debugger.
+# return a -1 if anything goes wrong.
+#
+proc gdb_load { arg } {
+ global verbose
+ global loadpath
+ global loadfile
+ global GDB
+ global gdb_prompt
+ global timeout
+ global last_gdb_file;
+
+ if [target_info exists gdb_download_size] {
+ send_gdb "set download-write-size [target_info gdb_download_size]\n";
+ gdb_expect 30 {
+ -re "$gdb_prompt $" { }
+ default {
+ perror "Setting download-write-size for target failed";
+ return -1;
+ }
+ }
+ }
+
+ if { $arg == "" } {
+ if [info exists last_gdb_file] {
+ set arg $last_gdb_file;
+ } else {
+ send_gdb "info files\n";
+ gdb_expect 30 {
+ -re "Symbols from \"(\[^\"\]+)\"" {
+ set arg $expect_out(1,string);
+ exp_continue;
+ }
+ -re "Local exec file:\[\r\n\]+\[ \t\]*`(\[^'\]+)'," {
+ set arg $expect_out(1,string);
+ exp_continue;
+ }
+ -re "$gdb_prompt $" { }
+ }
+ }
+ }
+
+ set last_gdb_file $arg;
+
+ for { set j 1; } { $j <= 2 } {incr j; } {
+ if [target_info exists gdb,use_standard_load] {
+ gdb_target_exec;
+ if ![target_info exists gdb,no_push_conn] {
+ remote_push_conn host;
+ }
+ set state [remote_ld target $arg];
+ if ![target_info exists gdb,no_push_conn] {
+ remote_close target;
+ remote_pop_conn host;
+ }
+ if { $state == "pass" } {
+ if [gdb_target_monitor $arg] { return -1; }
+ gdb_test "list main" ".*" ""
+ verbose "Loaded $arg into $GDB\n";
+ return 0;
+ }
+ } else {
+
+ if [gdb_target_monitor $arg] { return -1 }
+
+ if [is_remote host] {
+ # FIXME: Multiple downloads. bleah.
+ set farg [remote_download host $arg];
+ } else {
+ set farg $arg;
+ }
+
+ if { $arg != "" && [target_info exists gdb_sect_offset] } {
+ set textoff [target_info gdb_sect_offset];
+ send_gdb "sect .text $textoff\n";
+ gdb_expect 30 {
+ -re "(0x\[0-9a-z]+) - 0x\[0-9a-z\]+ is \\.data" {
+ set dataoff $expect_out(1,string);
+ exp_continue;
+ }
+ -re "(0x\[0-9a-z\]+) - 0x\[0-9a-z\]+ is \\.bss" {
+ set bssoff $expect_out(1,string);
+ exp_continue;
+ }
+ -re "$gdb_prompt" { }
+ }
+ set dataoff [format 0x%x [expr $dataoff + $textoff]];
+ set bssoff [format 0x%x [expr $bssoff + $textoff]];
+ send_gdb "sect .data $dataoff\n";
+ gdb_expect 30 {
+ -re "$gdb_prompt" { }
+ }
+ send_gdb "sect .bss $bssoff\n";
+ gdb_expect 30 {
+ -re "$gdb_prompt" { }
+ }
+ }
+
+ verbose "Loading $farg"
+ if [target_info exists gdb_load_offset] {
+ set command "load $farg [target_info gdb_load_offset]\n";
+ } else {
+ set command "load $farg\n";
+ }
+ if [target_info exists gdb_load_timeout] {
+ set loadtimeout [target_info gdb_load_timeout]
+ } else {
+ set loadtimeout 1600
+ }
+
+ send_gdb $command;
+ gdb_expect $loadtimeout {
+ -re "\[Ff\]ailed.*$gdb_prompt $" {
+ verbose "load failed";
+ }
+ -re "Timeout reading from remote.*$gdb_prompt" {
+ }
+ -re "$gdb_prompt $" {
+ verbose "Loaded $farg into $GDB\n"
+ return 0;
+ }
+ timeout {
+ if { $verbose > 1 } {
+ perror "Timed out trying to load $farg."
+ }
+ }
+ }
+ }
+
+ # Make sure we don't have an open connection to the target.
+ gdb_target_exec;
+
+ if { $j == 1 } {
+ if { ![reboot_target] } {
+ break;
+ }
+ }
+ }
+ perror "Couldn't load file into GDB.";
+ return -1;
+}
diff --git a/gdb/testsuite/config/netware.exp b/gdb/testsuite/config/netware.exp
new file mode 100644
index 00000000000..2538ccf49b6
--- /dev/null
+++ b/gdb/testsuite/config/netware.exp
@@ -0,0 +1,218 @@
+# Copyright (C) 1988, 1990, 1991, 1992, 1994, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by J.T. Conklin. (jtc@cygnus.com)
+
+load_lib gdb.exp
+load_lib remote.exp
+
+global shell_id
+
+global LD
+if ![info exists LD] then {
+ set LD [findfile "$base_dir/../../ld/ld.new"]
+}
+
+global NLMCONV
+if ![info exists NLMCONV] then {
+ set NLMCONV [findfile "$base_dir/../../binutils/nlmconv"]
+}
+
+#
+# gdb_version -- extract and print the version number of gcc
+#
+proc gdb_version {} {
+ default_gdb_version
+}
+
+#
+# gdb_unload -- unload a file if one is loaded
+#
+
+#
+# gdb_load -- load a file into the debugger.
+# return a -1 if anything goes wrong.
+#
+proc gdb_load { arg } {
+ global gdb_prompt
+ global LD
+ global NLMCONV
+ global errorCode
+ global shell_id
+
+ # FIXME: this is wrong.
+ set targetname [target_info name];
+
+ set obj [file tail $arg]
+ set nlm "$obj.nlm"
+ set lnk "$obj.lnk"
+
+ # build *.lnk file
+ set fd [open $lnk w]
+ puts $fd "description \"[file tail $nlm]\""
+ puts $fd "screenname \"System Console\""
+ puts $fd "module clib.nlm"
+ puts $fd "module mathlib.nlm"
+ puts $fd "stack 32768"
+# puts $fd "stack 64512"
+ puts $fd "debug"
+ # FIXME: don't hardcode location of prelude.o
+ puts $fd "input /s1/cygnus/dejagnu/i386-netware/lib/prelude.o"
+ puts $fd "input $arg"
+ puts $fd "output $nlm"
+ close $fd
+
+ # run nlmconv
+ verbose "Executing: $NLMCONV -l$LD -T$lnk" 1
+ catch "exec $NLMCONV -l$LD -T$lnk" output
+ if ![string match "" $output] then {
+ verbose $output 1
+ }
+ if ![string match "NONE" $errorCode] {
+ warning "Can't link $arg"
+
+ return -1
+ }
+ catch "exec rm -f $lnk"
+
+ # download
+ verbose "Downloading $nlm" 1
+ catch "exec cp $nlm /.NetWare/$targetname.nws/sys.nwv/tmp/x.nlm" output
+ if ![string match "" $output] then {
+ verbose $output 1
+ return -1
+ }
+
+ gdb_file_cmd $nlm
+}
+
+proc gdb_run_cmd { } {
+ global shell_id
+ global gdb_prompt
+ global timeout
+
+ set connhost [target_info name];
+ if [board_info $connhost exists serial] {
+ set serialport [board_info $connhost serial];
+ } else {
+ set serialport [board_info $connhost netport];
+ }
+
+ if [board_info $connhost exists baud] {
+ set baud [board_info $connhost baud];
+ } else {
+ set baud 9600;
+ }
+ # FIXME: This is wrong.
+ send "kill\n"
+ gdb_expect {
+ -re ".*Kill the program being debugged.*y or n. $" {
+ send "y\n"
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" {}
+ }
+
+ verbose "Starting GDB stub on [target_info name]" 1
+ send -i $shell_id "load nlmstub BAUD=$baud x.nlm\r\n"
+
+ send "set remotebaud $baud\n"
+ gdb_expect {
+ -re "$gdb_prompt" {}
+ timeout {
+ perror "Couldn't set remote baud rate"
+ return
+ }
+ }
+
+ set otimeout $timeout
+ set timeout 60
+ verbose "Timeout is now $timeout seconds" 2
+ send "target remote $serialport\n"
+ gdb_expect {
+ -re "Couldn't establish connection to remote target" {
+ send "target remote $serialport\n"
+ exp_continue
+ }
+ -re "$gdb_prompt" {}
+ timeout {
+ set timeout $otimeout
+ verbose "Timeout restored to $timeout seconds" 2
+ perror "Couldn't set remote target"
+ return
+ }
+ }
+ set timeout $otimeout
+ verbose "Timeout restored to $timeout seconds" 2
+
+ send "continue\n"
+ gdb_expect {
+ "Continuing.$" {}
+ }
+
+ return
+}
+
+
+
+#
+# start the remote shell
+#
+
+set shell_prompt "Password:"
+set shell_id [remote_open target]
+
+if $shell_id<0 then {
+ warning "Couldn't connect to target"
+ return -1
+}
+
+if [string match "" $passwd] then {
+ stty -echo
+ send_user "Password: "
+ expect_user -re "(.*)\n"
+ send_user "\n"
+ set passwd "$expect_out(1,string)"
+ stty echo
+}
+
+send -i $shell_id "$passwd\n"
+gdb_expect {
+ -i $shell_id ":" {
+ verbose "Got termtype prompt" 0
+ }
+
+ -i $shell_id timeout {
+ warning "Connection timed out"
+ return -1
+ }
+}
+
+
+# FIXME: this is wrong.
+set shell_prompt "[string toupper [target_info name]]:"
+send -i $shell_id "1\n"
+
+gdb_expect {
+ -i $shell_id -re "$shell_prompt" {}
+ -i $shell_id timeout {
+ warning "Connection timed out"
+ return -1
+ }
+}
diff --git a/gdb/testsuite/config/nind.exp b/gdb/testsuite/config/nind.exp
new file mode 100644
index 00000000000..d8aecdbc60a
--- /dev/null
+++ b/gdb/testsuite/config/nind.exp
@@ -0,0 +1,49 @@
+# Test Framework Driver
+# Copyright (C) 1988, 1990, 1991, 1992, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+load_lib gdb.exp
+
+#
+# gdb_load -- load a file into the debugger.
+#
+proc gdb_load { arg } {
+ global verbose
+ global loadpath
+ global loadfile
+ global gdb_prompt
+ global GDB
+ set loadfile [file tail $arg]
+ set loadpath [file dirname $arg]
+ send_user "Not implememted yet\n" ; return -1
+}
+
+#
+# gdb_start -- start GDB running
+#
+proc gdb_start { } {
+ global GDB
+ global GDBFLAGS
+ global spawn_id
+ global gdb_prompt
+ global verbose
+ send_user "Not implememted yet\n" ; return -1
+}
diff --git a/gdb/testsuite/config/proelf.exp b/gdb/testsuite/config/proelf.exp
new file mode 100644
index 00000000000..99b8a9db1f7
--- /dev/null
+++ b/gdb/testsuite/config/proelf.exp
@@ -0,0 +1,20 @@
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib ../config/monitor.exp
diff --git a/gdb/testsuite/config/rom68k.exp b/gdb/testsuite/config/rom68k.exp
new file mode 100644
index 00000000000..99b8a9db1f7
--- /dev/null
+++ b/gdb/testsuite/config/rom68k.exp
@@ -0,0 +1,20 @@
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib ../config/monitor.exp
diff --git a/gdb/testsuite/config/sh.exp b/gdb/testsuite/config/sh.exp
new file mode 100644
index 00000000000..99b8a9db1f7
--- /dev/null
+++ b/gdb/testsuite/config/sh.exp
@@ -0,0 +1,20 @@
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib ../config/monitor.exp
diff --git a/gdb/testsuite/config/sid.exp b/gdb/testsuite/config/sid.exp
new file mode 100644
index 00000000000..987c9beab12
--- /dev/null
+++ b/gdb/testsuite/config/sid.exp
@@ -0,0 +1,216 @@
+# Test Framework Driver for GDB driving an external simulator
+# Copyright 1999, 2001 Free Software Foundation, Inc.
+#
+# 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.
+
+load_lib gdb.exp
+
+proc sid_start {} {
+ global verbose
+
+ set port [lindex [split [target_info netport] ":"] 1]
+
+ # Set a default endianness
+ case [target_info multilib_flags] in {
+ { *big-endian* *-EB* *-meb* } { set sidendian "-EB" }
+ { *little-endian* *-EL* *-mel* } { set sidendian "-EL" }
+ default {
+ if {[target_info exists sim,defaultendian]} then {
+ set sidendian [target_info sim,defaultendian]
+ } else {
+ # rely on endianness settings in sid configuration defaults
+ set sidendian ""
+ }
+ }
+ }
+ case $sidendian in {
+ { -EB } { set sidendian2 {-e "set cpu endian big"} }
+ { -EL } { set sidendian2 {-e "set cpu endian little"} }
+ default { set sidendian2 {} }
+ }
+
+ # test to see whether to use use sid in build or install tree
+ set use_build_tree [file exists ../../sid]
+
+ if {$use_build_tree} then {
+ set pre_spawn {
+ global env
+ set env(SID_LIBRARY_PATH) [join [glob "../../sid/component/*"] ":"]
+ set env(SID) "../../sid/main/dynamic/sid"
+ if {! [file exists $env(SID)]} then { error "Cannot find sid in build tree" }
+ }
+ if { [board_info target sim,protocol] == "sid" } {
+ set spawncmd "[target_info sim] [target_info sim,options] $sidendian2 -e \"set cpu-gdb-socket sockaddr-local 0.0.0.0:$port\""
+ } elseif { [board_info target sim,protocol] == "rawsid" } {
+ set spawncmd "[target_info sim] [target_info sim,options] -$sidendian --gdb=$port"
+ } else {
+ set spawncmd "../../sid/bsp/[target_info sim] $sidendian --gdb=$port [target_info sim,options]"
+ }
+ set post_spawn {
+ global env
+ unset env(SID_LIBRARY_PATH)
+ unset env(SID)
+ }
+ } else {
+ set pre_spawn {}
+ if { [board_info target sim,protocol] == "sid" } {
+ # FIXME: sim,options may be from the build tree, should find
+ # it in the install tree.
+ set spawncmd "sid [target_info sim,options] $sidendian2 -e \"set cpu-gdb-socket sockaddr-local 0.0.0.0:$port\""
+ } elseif { [board_info target sim,protocol] == "rawsid" } {
+ set spawncmd "[target_info sim] [target_info sim,options] -$sidendian --gdb=$port"
+ } else {
+ set spawncmd "[target_info sim] $sidendian --gdb=$port [target_info sim,options]"
+ }
+ set post_spawn {}
+ }
+
+ eval $pre_spawn
+ if {[catch [list remote_spawn host $spawncmd] msg]} {
+ perror $msg
+ exit 1
+ }
+ eval $post_spawn
+
+ # Don't do the following any more; it breaks with "runtest ... < /dev/null"
+# expect_background {
+# -re \[^\n\]*\n {
+# regsub "\n" $expect_out(buffer) {} msg
+# verbose "SID: $msg" 2
+# }
+# }
+
+ # There should be no need to sleep to give SID time to start;
+ # GDB would wait for a fair while for the stub to respond.
+ sleep 4
+
+ if ![target_info exists gdb,no_push_conn] {
+ remote_push_conn host;
+ }
+}
+
+#
+# Handle GDB talking to SID
+#
+
+proc gdb_start {} {
+ sid_start
+ return [default_gdb_start]
+}
+
+proc sid_exit {} {
+ if ![target_info exists gdb,no_push_conn] {
+ remote_close host;
+ remote_pop_conn host;
+ }
+}
+
+proc gdb_exit {} {
+ set result [default_gdb_exit]
+ sid_exit
+ return $result
+}
+
+#
+# gdb_target_sid
+# Set gdb to target the simulator
+#
+proc send_target_sid { } {
+ # wait a little while, giving sid time to shut down & restart its
+ # gdb socket
+ sleep 4
+ send_gdb "target [target_info gdb_protocol] [target_info netport]\n"
+}
+
+proc gdb_target_sid { } {
+ global gdb_prompt
+ global exit_status
+
+ send_target_sid
+
+ global timeout
+ set prev_timeout $timeout
+ set timeout 60
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ -re ".*\[Ee\]rror.*$gdb_prompt $" {
+ perror "Couldn't set target for remote simulator."
+ cleanup
+ gdb_exit
+ }
+ -re "Remote debugging using.*$gdb_prompt" {
+ verbose "Set target to sid"
+ }
+ timeout {
+ perror "Couldn't set target for remote simulator."
+ cleanup
+ gdb_exit
+ }
+ }
+ set timeout $prev_timeout
+ verbose "Timeout is now $timeout seconds" 2
+}
+
+#
+# gdb_load -- load a file into the debugger.
+# return a -1 if anything goes wrong.
+#
+proc gdb_load { arg } {
+ global verbose
+ global loadpath
+ global loadfile
+ global GDB
+ global gdb_prompt
+ global retval
+
+ gdb_unload
+ if [gdb_file_cmd $arg] then { return -1 }
+ gdb_target_sid
+
+ send_gdb "load\n"
+ global timeout
+ set prev_timeout $timeout
+ set timeout 2400
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ -re ".*\[Ee\]rror.*$gdb_prompt $" {
+ if $verbose>1 then {
+ perror "Error during download."
+ }
+ set retval -1;
+ }
+ -re ".*$gdb_prompt $" {
+ if $verbose>1 then {
+ send_user "Loaded $arg into $GDB\n"
+ }
+ set retval 1;
+ }
+ -re "$gdb_prompt $" {
+ if $verbose>1 then {
+ perror "GDB couldn't load."
+ }
+ set retval -1;
+ }
+ timeout {
+ if $verbose>1 then {
+ perror "Timed out trying to load $arg."
+ }
+ set retval -1;
+ }
+ }
+ set timeout $prev_timeout
+ verbose "Timeout is now $timeout seconds" 2
+ return $retval;
+}
diff --git a/gdb/testsuite/config/sim.exp b/gdb/testsuite/config/sim.exp
new file mode 100644
index 00000000000..5d8a93d5311
--- /dev/null
+++ b/gdb/testsuite/config/sim.exp
@@ -0,0 +1,85 @@
+# Test Framework Driver for GDB driving a builtin simulator
+# Copyright 1994, 1997, 1998 Free Software Foundation, Inc.
+#
+# 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.
+
+load_lib gdb.exp
+
+#
+# gdb_target_sim
+# Set gdb to target the simulator
+#
+proc gdb_target_sim { } {
+ global gdb_prompt
+ global exit_status
+
+ set target_sim_options "[board_info target gdb,target_sim_options]";
+
+ send_gdb "target sim $target_sim_options\n"
+ set timeout 60
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ -re "Connected to the simulator.*$gdb_prompt $" {
+ verbose "Set target to sim"
+ }
+ timeout {
+ perror "Couldn't set target for simulator."
+ cleanup
+ exit $exit_status
+ }
+ }
+ set timeout 10
+ verbose "Timeout is now $timeout seconds" 2
+}
+
+#
+# gdb_load -- load a file into the debugger.
+# return a -1 if anything goes wrong.
+#
+proc gdb_load { arg } {
+ global verbose
+ global loadpath
+ global loadfile
+ global GDB
+ global gdb_prompt
+
+ if [gdb_file_cmd $arg] then { return -1 }
+
+ gdb_target_sim
+
+ send_gdb "load\n"
+ set timeout 2400
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ -re ".*$gdb_prompt $" {
+ if $verbose>1 then {
+ send_user "Loaded $arg into $GDB\n"
+ }
+ set timeout 30
+ verbose "Timeout is now $timeout seconds" 2
+ return 1
+ }
+ -re "$gdb_prompt $" {
+ if $verbose>1 then {
+ perror "GDB couldn't load."
+ }
+ }
+ timeout {
+ if $verbose>1 then {
+ perror "Timed out trying to load $arg."
+ }
+ }
+ }
+}
diff --git a/gdb/testsuite/config/slite.exp b/gdb/testsuite/config/slite.exp
new file mode 100644
index 00000000000..3656665536c
--- /dev/null
+++ b/gdb/testsuite/config/slite.exp
@@ -0,0 +1,183 @@
+# Copyright 1993, 1997, 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was written by Ian Lance Taylor <ian@cygnus.com>.
+
+# GDB support routines for a board using the MIPS remote debugging
+# protocol. These are actually pretty generic.
+
+# DejaGnu currently assumes that debugging is being done over the main
+# console port. It would probably be more convenient for people using
+# IDT boards to permit the debugging port and the connected port to be
+# different, since an IDT board has two ports. This would require
+# extending some of the tests in a fashion similar to that done for
+# VxWorks, because the test output would appear on the other port,
+# rather than being displayed by gdb.
+
+load_lib remote.exp
+load_lib gdb.exp
+set gdb_prompt "\\(gdb\\)"
+
+#
+# gdb_load -- load a file into the GDB.
+# Returns a 0 if there was an error,
+# 1 if it load successfully.
+#
+proc gdb_load { arg } {
+ global verbose
+ global loadpath
+ global loadfile
+ global gdb_prompt
+ global GDB
+ global expect_out
+
+ set loadfile [file tail $arg]
+ set loadpath [file dirname $arg]
+
+ gdb_file_cmd $arg
+
+ if [target_info exists gdb_protocol] {
+ set protocol [target_info gdb_protocol];
+ } else {
+ set protocol "sparclite"
+ }
+
+ if [target_info exists serial] {
+ set targetname [target_info serial];
+ set command "target $protocol [target_info serial]\n";
+ } else {
+ if ![target_info exists netport] {
+ perror "Need either netport or gdb_serial entry for [target_info name].";
+ return -1;
+ }
+ set targetname [target_info netport];
+ set command "target $protocol udp [target_info netport]\n";
+ }
+ set timeout 60
+ verbose "Timeout is now $timeout seconds" 2
+ set try_count 0;
+ send_gdb $command;
+ gdb_expect {
+ -re "Unknown response.*resetting the board.|remote timeout" {
+ incr try_count;
+ if { $try_count > 3 } {
+ set try_count 0;
+ reboot_target;
+ sleep 5;
+ }
+ sleep 1;
+ send_gdb $command;
+ exp_continue;
+ }
+ -re "Remote target.*$gdb_prompt $" { }
+ -re ".*SPARClite appears to be alive.*$gdb_prompt $" {
+ if $verbose>1 then {
+ send_user "Set target to $targetname\n"
+ }
+ }
+ timeout {
+ perror "Couldn't set SLITE target."
+ set timeout 10
+ verbose "Timeout is now $timeout seconds" 2
+ return -1
+ }
+ }
+
+ if [target_info exists gdb_load_offset] {
+ set offset "[target_info gdb_load_offset]";
+ } else {
+ set offset "";
+ }
+ if { 1 } {
+ if [is_remote host] {
+ set arg [remote_download host $arg];
+ if { $arg == "" } {
+ error "download failed"
+ return -1;
+ }
+ }
+ send_gdb "load $arg $offset\n"
+ verbose "Loading $arg into $GDB" 2
+ set timeout 2400
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ -re "Loading.*$gdb_prompt $" {
+ verbose "Loaded $arg into $GDB" 1
+ set timeout 30
+ verbose "Timeout is now $timeout seconds" 2
+ }
+ -re "$gdb_prompt $" {
+ if $verbose>1 then {
+ perror "GDB couldn't load."
+ }
+ }
+ timeout {
+ if $verbose>1 then {
+ perror "Timed out trying to load $arg."
+ }
+ }
+ }
+ }
+ # Some SPARClite boards automagically do a run after the program is
+ # loaded.
+ if [target_info exists need_monitor_run] {
+ set timeout 10
+ verbose "Timeout is now $timeout seconds, doing monitor run" 2
+ send_gdb "monitor run\n";
+ sleep 2;
+ send_gdb "";
+ gdb_expect {
+ -re ".*$gdb_prompt $" { verbose "Run command succeded" }
+ default {
+ perror "error sending monitor run command";
+ }
+ }
+ } else {
+ sleep 2;
+ }
+
+ if [target_info exists gdb_serial] {
+ set serial [target_info gdb_serial];
+ } else {
+ set serial [target_info serial];
+ }
+ send_gdb "target remote $serial\n"
+ set timeout 60
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ -re ".*Kill it?.*y or n.*" {
+ send_gdb "y\n";
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" {
+ verbose "Set remote target to [target_info serial]" 2
+ }
+ timeout {
+ perror "Couldn't set remote target."
+ set timeout 10
+ verbose "Timeout is now $timeout seconds" 2
+ return -1
+ }
+ }
+
+ if [info exists expect_out(buffer)] then {
+ send_log $expect_out(buffer)
+ }
+ return 0
+}
diff --git a/gdb/testsuite/config/sparclet.exp b/gdb/testsuite/config/sparclet.exp
new file mode 100644
index 00000000000..83dc8c4e079
--- /dev/null
+++ b/gdb/testsuite/config/sparclet.exp
@@ -0,0 +1,391 @@
+# Copyright 1996, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was written by Michael Snyder <msnyder@cygnus.com>.
+
+# GDB support routines for a board using the sparclet remote debugging
+# protocol.
+
+load_lib remote.exp
+load_lib gdb.exp
+
+#
+# Sparclet remote run command.
+#
+
+proc gdb_start { } {
+ global gdb_prompt
+
+ if ![file exists loader] {
+ global libdir
+ set loader loader;
+
+ if [target_info exists gdb_stub_offset] {
+ set result [target_compile "${libdir}/stub-loader.c" $loader executable "libs=-Wl,-Ttext,[target_info gdb_stub_offset]"];
+ } else {
+ set result [target_compile "${libdir}/stub-loader.c" $loader executable "ldscript=[target_info gdb_stub_ldscript]"];
+ }
+ }
+
+ verbose -log "$gdb_prompt is gdb prompt"
+
+ set result 0;
+ for { set y 0; } { $y < 4 } { incr y } {
+ if { [default_gdb_start] != 0 } {
+ return -1;
+ }
+
+ if [target_info exists baud] {
+ send_gdb "set remotebaud [target_info baud]\n"
+ gdb_expect {
+ -re "$gdb_prompt" { }
+ default {
+ perror "Error setting baud rate."
+ return -1;
+ }
+ }
+ }
+
+ for {set x 1;} { $x < 4 } {incr x} {
+ set result [gdb_sparclet_startup $result];
+ if { $result > 0 } {
+ return 1;
+ }
+ # mmmmm, magic numbers.
+ if { $result == -42 || $result == -43 } {
+ break;
+ } else {
+ reboot_target;
+ }
+ }
+ if { $x == 4 } {
+ return -1;
+ }
+ gdb_exit;
+ sleep 5;
+ }
+ return -1;
+}
+
+proc gdb_sparclet_startup { arg } {
+ global gdb_prompt
+ global GDB
+ global verbose
+
+ set is_running_stub 0;
+
+ if [target_info exists serial] {
+ set serial [target_info serial];
+ } else {
+ set serial [target_info netport];
+ }
+ set protocol [target_info gdb_protocol];
+ set check_stub 1;
+ if { $arg != -42 } {
+ send_gdb "target $protocol $serial\n";
+ # 10 seconds may be a bit short.
+ gdb_expect 10 {
+ -re "already.*y or n." {
+ gdb_send "y\n";
+ exp_continue;
+ }
+ -re "Remote target.*connected to.*$gdb_prompt" { set check_stub 0; }
+ -re "$gdb_prompt" { }
+ timeout { }
+ }
+ if { $check_stub } {
+ verbose "timed out, checking if stub is already running"
+ send_gdb "\003";
+ sleep 1;
+ send_gdb "\003";
+ gdb_expect 10 {
+ -re "$gdb_prompt" { }
+ default {
+ remote_close host;
+ return -42;
+ }
+ }
+ }
+ }
+ if [target_info exists gdb_serial] {
+ set gdb_serial [target_info gdb_serial];
+ } else {
+ set gdb_serial $serial;
+ }
+ if { $check_stub } {
+ send_gdb "target remote $gdb_serial\n";
+ gdb_expect 15 {
+ -re "Remote debugging.*$gdb_prompt" {
+ verbose "stub is already running"
+ set is_running_stub 1;
+ }
+ default {
+ warning "board isn't responding";
+ remote_close host;
+ remote_reboot target;
+ return -43;
+ }
+ }
+ }
+
+ if { $is_running_stub == 0 } {
+ global srcdir
+
+ if [is_remote host] {
+ set loader [remote_download host "loader"];
+ } else {
+ set loader "loader";
+ }
+ send_gdb "file $loader\n";
+ gdb_expect {
+ -re "A program is being debug.*Kill it.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "Load new symbol table.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "Reading symbols from.*done..*$gdb_prompt $" {}
+ -re "$gdb_prompt $" { perror "GDB couldn't find loader" }
+ timeout {
+ perror "(timeout) read symbol file" ;
+ return -1
+ }
+ }
+
+ send_gdb "target $protocol $serial\n";
+ gdb_expect {
+ -re "Remote target.*connected to.*$gdb_prompt" { }
+ default {
+ perror "Error reconnecting to board.";
+ return -1;
+ }
+ }
+
+ send_gdb "load $loader [target_info gdb_stub_offset]\n"
+ verbose "Loading $loader into $GDB" 2
+ set no_run_command 0;
+ gdb_expect 1200 {
+ -re "Loading.*$gdb_prompt $" {
+ verbose "Loaded $loader into $GDB" 1
+ }
+ -re "Transfer rate:.*Switching to remote protocol.*Remote debugging" {
+ set no_run_command 1;
+ }
+ -re "$gdb_prompt $" {
+ if $verbose>1 then {
+ perror "GDB couldn't load."
+ }
+ }
+ timeout {
+ if $verbose>1 then {
+ perror "Timed out trying to load $arg."
+ }
+ }
+ }
+
+ if !$no_run_command {
+ send_gdb "run\n";
+ gdb_expect 60 {
+ -re "A program is being debug.*Kill it.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "The program being debugged .*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "Starting program:.*loader.*$" {
+ verbose "Starting loader succeeded"
+ }
+ timeout {
+ perror "(timeout) starting the loader" ;
+ return -1
+ }
+ default {
+ perror "error starting the loader";
+ }
+ }
+ }
+ sleep 2;
+ send_gdb ""
+ sleep 1;
+ send_gdb ""
+ verbose "Sent ^C^C"
+ gdb_expect 10 {
+ -re "Give up .and stop debugging it.*$" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "$gdb_prompt $" {
+ verbose "Running loader succeeded"
+ }
+ timeout {
+ warning "(timeout) interrupting the loader" ;
+ remote_close host;
+ }
+ default {
+ warning "error interrupting the loader";
+ }
+ }
+
+ gdb_exit;
+ return [gdb_start];
+ }
+ return 1;
+}
+
+proc gdb_run_cmd { args } {
+ global gdb_prompt
+
+ gdb_breakpoint exit;
+ send_gdb "set \$fp=0\n";
+ gdb_expect {
+ -re "$gdb_prompt" { }
+ }
+ # This is needed for the SparcLite. Whee.
+ if [target_info exists gdb,start_symbol] {
+ set start_comm "jump *[target_info gdb,start_symbol]\n";
+ } else {
+ set start_comm "jump *start\n";
+ }
+ send_gdb "break copyloop\n";
+ gdb_expect 10 {
+ -re "Breakpoint.*$gdb_prompt $" {
+ set start_comm "continue\n";
+ }
+ -re "$gdb_prompt $" { }
+ timeout { warning "break copyloop failed badly"; }
+ }
+ send_gdb $start_comm;
+ gdb_expect 10 {
+ -re "y or n. $" {
+ remote_send host "y\n"
+ exp_continue;
+ }
+ -re "Breakpoint.*in copyloop.*$gdb_prompt $" {
+ remote_send host "jump relocd\n";
+ exp_continue;
+ }
+ -re "Continuing at.*\[\r\n\]" { }
+ default {
+ return -1;
+ }
+ }
+
+ return "";
+}
+
+
+#
+# gdb_load -- load a file into the GDB.
+# Returns a 0 if there was an error,
+# 1 if it load successfully.
+#
+proc gdb_load { arg } {
+ global verbose
+ global loadpath
+ global loadfile
+ global gdb_prompt
+ global GDB
+ global expect_out
+
+ set loadfile [file tail $arg]
+ set loadpath [file dirname $arg]
+
+ set protocol [target_info gdb_protocol];
+
+ if [is_remote host] {
+ set arg [remote_download host $arg];
+ }
+ send_gdb "file $arg\n"
+ gdb_expect 30 {
+ -re "A program is being debug.*Kill it.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "Load new symbol table.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "Reading symbols from.*done..*$gdb_prompt $" {}
+ -re "$gdb_prompt $" { perror "GDB couldn't read file" }
+ timeout {
+ perror "(timeout) read symbol file" ;
+ return -1
+ }
+ }
+
+ if [target_info exists gdb_serial] {
+ set gdb_serial [target_info gdb_serial];
+ } else {
+ if [target_info exists serial] {
+ set gdb_serial [target_info serial];
+ } else {
+ set gdb_serial [target_info netport];
+ }
+ }
+ send_gdb "target remote $gdb_serial\n"
+ gdb_expect 30 {
+ -re "Kill it?.*y or n.*" {
+ send_gdb "y\n";
+ exp_continue
+ }
+ -re "$gdb_prompt $" {
+ verbose "Set remote target to $gdb_serial" 2
+ }
+ timeout {
+ perror "Couldn't set remote target."
+ return -1
+ }
+ }
+ if [target_info exists gdb_load_offset] {
+ set offset "[target_info gdb_load_offset]";
+ } else {
+ set offset "";
+ }
+ send_gdb "load $arg $offset\n"
+ verbose "Loading $arg into $GDB" 2
+ gdb_expect 1200 {
+ -re "Loading.*$gdb_prompt $" {
+ verbose "Loaded $arg into $GDB" 1
+ }
+ -re "$gdb_prompt $" {
+ if $verbose>1 then {
+ perror "GDB couldn't load."
+ }
+ }
+ timeout {
+ if $verbose>1 then {
+ perror "Timed out trying to load $arg."
+ }
+ }
+ }
+ send_gdb "list main\n";
+ gdb_expect 60 {
+ -re "$gdb_prompt" { }
+ default {
+ perror "command for list main never completed";
+ return -1;
+ }
+ }
+
+ return 0
+}
diff --git a/gdb/testsuite/config/udi.exp b/gdb/testsuite/config/udi.exp
new file mode 100644
index 00000000000..2360d6b8d3d
--- /dev/null
+++ b/gdb/testsuite/config/udi.exp
@@ -0,0 +1,113 @@
+# Test Framework Driver for GDB driving Universal Debug Interface on 29K
+# Copyright 1988, 1990, 1991, 1992, 1993, 1994, 1997
+# Free Software Foundation, Inc.
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+load_lib gdb.exp
+
+#
+# gdb_target_udi
+# Set gdb to the desired UDI target
+#
+proc gdb_target_udi { } {
+ global gdb_prompt
+ global verbose
+ global exit_status
+
+ set targetname [target_info mondfe,name];
+ # set targets hostname
+ send_gdb "target udi $targetname\n"
+ set timeout 60
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ -re "target udi $targetname\[\r\n\]+" {
+ exp_continue
+ }
+ -re "TIP UDI 1.2 Conformant.*$gdb_prompt $" {
+ verbose "Set target to $targetname"
+ }
+ -re "TIP-ipc WARNING,.*failed:" {
+ warning "$expect_out(buffer)"
+ }
+ -re "TIP-ipc ERROR,.*failed:" {
+ perror "$expect_out(buffer)"
+ }
+ -re "A program is being debugged already. Kill it\? \(y or n\)" {
+ send "y\n"
+ exp_continue
+ }
+ timeout {
+ perror "Couldn't set target for UDI."
+ cleanup
+ exit $exit_status
+ }
+ }
+ set timeout 10
+ verbose "Timeout is now $timeout seconds" 2
+}
+
+#
+# gdb_load -- load a file into the debugger.
+# return a -1 if anything goes wrong.
+#
+
+proc gdb_load { arg } {
+ global verbose
+ global loadpath
+ global loadfile
+ global GDB
+ global gdb_prompt
+
+ if [gdb_file_cmd $arg] {
+ return -1
+ }
+
+ gdb_target_udi
+}
+
+#
+# gdb_start -- start GDB running. This assumes that there the
+# UDICONF enviroment variable is set.
+#
+proc gdb_start { } {
+ global env;
+
+ set env(UDICONF) [target_info mondfe,udi_soc];
+ default_gdb_start
+ verbose "Setting up target, Please wait..."
+ gdb_target_udi
+}
+
+#
+# gdb_exit -- exit gdb
+#
+proc gdb_exit { } {
+ catch default_gdb_exit
+ set in [open [concat "|ls -F"] r]
+ while {[gets $in line]>-1} {
+ if [regexp "=$" $line] then {
+ set line [string trimright $line "="]
+ verbose "Removing the $line named socket"
+ exec rm -f $line
+ }
+ }
+ close $in
+}
diff --git a/gdb/testsuite/config/unix.exp b/gdb/testsuite/config/unix.exp
new file mode 100644
index 00000000000..321ad542d7a
--- /dev/null
+++ b/gdb/testsuite/config/unix.exp
@@ -0,0 +1,29 @@
+# Copyright (C) 1988, 1990, 1991, 1992, 1994, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+# Set a default timeout to be used for the tests under UNIX, rather than
+# accepting whatever default dejagnu gives us (apparently 10 seconds).
+# When running the tests over NFS, under somewhat heavy load, 10 seconds
+# does not seem to be enough. Try starting with 60.
+set timeout 60
+verbose "Timeout is now $timeout seconds" 2
+
+load_lib gdb.exp
diff --git a/gdb/testsuite/config/unknown.exp b/gdb/testsuite/config/unknown.exp
new file mode 100644
index 00000000000..f61e5af030f
--- /dev/null
+++ b/gdb/testsuite/config/unknown.exp
@@ -0,0 +1,21 @@
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+perror "Sorry, there is no support for this target"
+exit 1
diff --git a/gdb/testsuite/config/vr4300.exp b/gdb/testsuite/config/vr4300.exp
new file mode 100644
index 00000000000..99b8a9db1f7
--- /dev/null
+++ b/gdb/testsuite/config/vr4300.exp
@@ -0,0 +1,20 @@
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib ../config/monitor.exp
diff --git a/gdb/testsuite/config/vr5000.exp b/gdb/testsuite/config/vr5000.exp
new file mode 100644
index 00000000000..99b8a9db1f7
--- /dev/null
+++ b/gdb/testsuite/config/vr5000.exp
@@ -0,0 +1,20 @@
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib ../config/monitor.exp
diff --git a/gdb/testsuite/config/vx.exp b/gdb/testsuite/config/vx.exp
new file mode 100644
index 00000000000..b02142c5052
--- /dev/null
+++ b/gdb/testsuite/config/vx.exp
@@ -0,0 +1,131 @@
+# Copyright 1988, 1990, 1991, 1992, 1995, 1997
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+#
+# load support libraries
+#
+load_lib remote.exp
+load_lib gdb.exp
+
+set shell_prompt "->"
+set gdb_prompt "\\(vxgdb\\)"
+
+#
+# gdb_version -- extract and print the version number of gcc
+#
+proc gdb_version {} {
+ default_gdb_version
+}
+
+#
+# gdb_load -- load a file into the debugger.
+# We have to stop and start gdb each time we do this, because when
+# vxgdb loads two files in a row, the symbols in the first file loaded
+# take precedence. Returns -1 on error, else 0.
+#
+proc gdb_load { arg } {
+ set result 0
+
+ if { [remote_ld target $arg] != 0 } {
+ perror "Couldn't load $arg"
+ return -1
+ }
+
+ return [gdb_file_cmd $arg]
+}
+
+#
+# gdb_start -- start gdb running
+#
+proc gdb_start { } {
+ global gdb_prompt
+ global verbose
+ global connectmode
+ global reboot
+
+ # get a connection to the board
+ for { set x 0; } { $x < 3 } { incr x } {
+ set shell_id [remote_open target]
+ if { $shell_id > 0 } {
+ verbose "Spawn id for remote shell is $shell_id"
+
+ set timeout 10
+ verbose "Timeout is now $timeout seconds" 2
+
+ set state [spawn_vxgdb];
+ if { $state == "pass" } {
+ return 0;
+ }
+ if { $state == "fail" } {
+ return -1;
+ }
+ }
+ remote_reboot target;
+ }
+}
+
+proc spawn_vxgdb { } {
+ global gdb_prompt
+
+ default_gdb_start
+
+ # set the default arguments to "main", so that "run" with no
+ # arguments will work correctly.
+ send_gdb "set args main\n"
+ gdb_expect -re ".*$gdb_prompt $" {}
+
+ verbose "Setting up target, Please wait..."
+ # set targets hostname
+ send_gdb "target vxworks [target_info hostname]\n"
+ set timeout 60
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ -re "Done\..*$gdb_prompt $" {
+ verbose "Set target to [target_info hostname]" 1
+ set timeout 10;
+ return "pass";
+ }
+ -re "net_connect: RPC: (Program not registered|.*Timed out).*$" {
+ warning "Couldn't set GDB to target [target_info netport]."
+ }
+ timeout {
+ warning "Couldn't set target for vxworks."
+ }
+ }
+ return "retry";
+}
+
+proc gdb_exit { } {
+ remote_close target;
+ catch default_gdb_exit
+}
+
+#expect_after {
+# "<return>" { send "\n"; perror "Window too small." }
+# -re "\(y or n\) " { send "n\n"; perror "Got interactive prompt." }
+# buffer_full { perror "internal buffer is full." }
+# eof { perror "eof -- pty is hosed." }
+# timeout { perror "timeout." }
+# "virtual memory exhausted" { perror "virtual memory exhausted." }
+# "Undefined command" { perror "send string probably wrong." }
+#}
+
diff --git a/gdb/testsuite/config/vxworks.exp b/gdb/testsuite/config/vxworks.exp
new file mode 100644
index 00000000000..e3434063e4a
--- /dev/null
+++ b/gdb/testsuite/config/vxworks.exp
@@ -0,0 +1,20 @@
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+load_lib ../config/vx.exp
diff --git a/gdb/testsuite/config/vxworks29k.exp b/gdb/testsuite/config/vxworks29k.exp
new file mode 100644
index 00000000000..795963b97bf
--- /dev/null
+++ b/gdb/testsuite/config/vxworks29k.exp
@@ -0,0 +1,27 @@
+# Copyright 1995, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was written by Brendan Kehoe (brendan@cygnus.com).
+
+# We need this file here because the targetname for the 29k board
+# is `vxworks29k', not `vxworks'. That way other tools (e.g., gcc)
+# can differentiate between the stuff run on that board and others.
+
+verbose "Loading ${srcdir}/config/vx.exp"
+source ${srcdir}/config/vx.exp
diff --git a/gdb/testsuite/configure b/gdb/testsuite/configure
new file mode 100755
index 00000000000..bdfc4cd443e
--- /dev/null
+++ b/gdb/testsuite/configure
@@ -0,0 +1,1214 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-shared use shared libraries"
+ac_help="$ac_help
+ --enable-gdbtk "
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+sitefile=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --site-file=FILE use FILE as the site file
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -site-file | --site-file | --site-fil | --site-fi | --site-f)
+ ac_prev=sitefile ;;
+ -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
+ sitefile="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=gdb.base
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$sitefile"; then
+ if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+ fi
+else
+ CONFIG_SITE="$sitefile"
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../.. $srcdir/`cd $srcdir;pwd`/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../.. $srcdir/`cd $srcdir;pwd`/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:590: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:611: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:629: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+# Directories to use in all configurations.
+configdirs="gdb.arch \
+ gdb.asm \
+ gdb.base \
+ gdb.c++ \
+ gdb.java \
+ gdb.disasm \
+ gdb.chill \
+ gdb.mi \
+ gdb.threads \
+ gdb.trace"
+
+
+# Directories to use for a configuration which uses stabs.
+stabsdirs="gdb.stabs"
+
+ # this section is for targets that use stabs
+# add stabs tests for appropriate targets
+case "${target}" in
+ powerpc-*-aix*) configdirs="${configdirs} ${stabsdirs}" ;;
+ rs6000-*-aix*) configdirs="${configdirs} ${stabsdirs}" ;;
+ *-*-bsd*) configdirs="${configdirs} ${stabsdirs}" ;;
+ *-*-go32*) configdirs="${configdirs} ${stabsdirs}" ;;
+ *-*-linux*) configdirs="${configdirs} ${stabsdirs}" ;;
+ *-*-lynxos*) configdirs="${configdirs} ${stabsdirs}" ;;
+ *-sun-*) configdirs="${configdirs} ${stabsdirs}" ;;
+ hppa*-*-*) configdirs="${configdirs} ${stabsdirs}" ;;
+ *-*-elf*) configdirs="${configdirs} ${stabsdirs}" ;;
+ *) if test "x${with_stabs}" = x"yes" ; then
+ configdirs="${configdirs} ${stabsdirs}"
+ fi ;;
+esac
+
+# Directory with HP specific tests. They will run only with HP's compilers.
+# These tests will not work on other platforms and compilers.
+
+hpdir="gdb.hp"
+
+case "${target}" in
+ hppa*-*-hpux*) configdirs="${configdirs} ${hpdir}" ;;
+esac
+
+
+# Begin stuff to support --enable-shared
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ case "${enableval}" in
+ yes) shared=true ;;
+ no) shared=false ;;
+ *) shared=true ;;
+esac
+fi
+RPATH_ENVVAR=LD_LIBRARY_PATH
+# If we have shared libraries, try to set RPATH_ENVVAR reasonably.
+if test "${shared}" = "true"; then
+ case "${host}" in
+ *-*-hpux*)
+ RPATH_ENVVAR=SHLIB_PATH
+ ;;
+ esac
+fi
+
+# End stuff to support --enable-shared
+# Start stuff to support --enable-gdbtk
+# Check whether --enable-gdbtk or --disable-gdbtk was given.
+if test "${enable_gdbtk+set}" = set; then
+ enableval="$enable_gdbtk"
+ case "${enableval}" in
+ yes)
+ case "$host" in
+ *go32*)
+ enable_gdbtk=no ;;
+ *windows*)
+ enable_gdbtk=no ;;
+ *)
+ enable_gdbtk=yes ;;
+ esac ;;
+ no)
+ enable_gdbtk=no ;;
+ *)
+ { echo "configure: error: bad value ${enableval} given for gdbtk option" 1>&2; exit 1; } ;;
+esac
+else
+
+# Default is on for everything but go32 and windows
+case "$host" in
+ *go32* | *windows*)
+ ;;
+ *)
+ enable_gdbtk=yes ;;
+ esac
+
+fi
+
+
+if test "${enable_gdbtk}" = "yes"; then
+ configdirs="${configdirs} gdb.gdbtk"
+fi
+# End stuff to support --enable-shared
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:754: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 759 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:770: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:787: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 792 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:799: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:818: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:828: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+
+# configure the subdirectories too
+subdirs="$configdirs"
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@RPATH_ENVVAR@%$RPATH_ENVVAR%g
+s%@EXEEXT@%$EXEEXT%g
+s%@subdirs@%$subdirs%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+if test "$no_recursion" != yes; then
+
+ # Remove --cache-file and --srcdir arguments so they do not pile up.
+ ac_sub_configure_args=
+ ac_prev=
+ for ac_arg in $ac_configure_args; do
+ if test -n "$ac_prev"; then
+ ac_prev=
+ continue
+ fi
+ case "$ac_arg" in
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ ;;
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ ;;
+ *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;;
+ esac
+ done
+
+ for ac_config_dir in $configdirs; do
+
+ # Do not complain, so a configure script can configure whichever
+ # parts of a large source tree are present.
+ if test ! -d $srcdir/$ac_config_dir; then
+ continue
+ fi
+
+ echo configuring in $ac_config_dir
+
+ case "$srcdir" in
+ .) ;;
+ *)
+ if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :;
+ else
+ { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; }
+ fi
+ ;;
+ esac
+
+ ac_popdir=`pwd`
+ cd $ac_config_dir
+
+ # A "../" for each directory in /$ac_config_dir.
+ ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
+
+ case "$srcdir" in
+ .) # No --srcdir option. We are building in place.
+ ac_sub_srcdir=$srcdir ;;
+ /*) # Absolute path.
+ ac_sub_srcdir=$srcdir/$ac_config_dir ;;
+ *) # Relative path.
+ ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;;
+ esac
+
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_sub_srcdir/configure; then
+ ac_sub_configure=$ac_sub_srcdir/configure
+ elif test -f $ac_sub_srcdir/configure.in; then
+ ac_sub_configure=$ac_configure
+ else
+ echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2
+ ac_sub_configure=
+ fi
+
+ # The recursion is here.
+ if test -n "$ac_sub_configure"; then
+
+ # Make the cache file name correct relative to the subdirectory.
+ case "$cache_file" in
+ /*) ac_sub_cache_file=$cache_file ;;
+ *) # Relative path.
+ ac_sub_cache_file="$ac_dots$cache_file" ;;
+ esac
+
+ echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir"
+ # The eval makes quoting arguments work.
+ if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir
+ then :
+ else
+ { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; }
+ fi
+ fi
+
+ cd $ac_popdir
+ done
+fi
+
diff --git a/gdb/testsuite/configure.in b/gdb/testsuite/configure.in
new file mode 100644
index 00000000000..48e50d873f4
--- /dev/null
+++ b/gdb/testsuite/configure.in
@@ -0,0 +1,117 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.12.1)
+AC_INIT(gdb.base)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../..)
+AC_CANONICAL_SYSTEM
+
+# Directories to use in all configurations.
+configdirs="gdb.arch \
+ gdb.asm \
+ gdb.base \
+ gdb.c++ \
+ gdb.java \
+ gdb.disasm \
+ gdb.chill \
+ gdb.mi \
+ gdb.threads \
+ gdb.trace"
+
+
+# Directories to use for a configuration which uses stabs.
+stabsdirs="gdb.stabs"
+
+ # this section is for targets that use stabs
+# add stabs tests for appropriate targets
+case "${target}" in
+ powerpc-*-aix*) configdirs="${configdirs} ${stabsdirs}" ;;
+ rs6000-*-aix*) configdirs="${configdirs} ${stabsdirs}" ;;
+ *-*-bsd*) configdirs="${configdirs} ${stabsdirs}" ;;
+ *-*-go32*) configdirs="${configdirs} ${stabsdirs}" ;;
+ *-*-linux*) configdirs="${configdirs} ${stabsdirs}" ;;
+ *-*-lynxos*) configdirs="${configdirs} ${stabsdirs}" ;;
+ *-sun-*) configdirs="${configdirs} ${stabsdirs}" ;;
+ hppa*-*-*) configdirs="${configdirs} ${stabsdirs}" ;;
+ *-*-elf*) configdirs="${configdirs} ${stabsdirs}" ;;
+ *) if test "x${with_stabs}" = x"yes" ; then
+ configdirs="${configdirs} ${stabsdirs}"
+ fi ;;
+esac
+
+# Directory with HP specific tests. They will run only with HP's compilers.
+# These tests will not work on other platforms and compilers.
+
+hpdir="gdb.hp"
+
+case "${target}" in
+ hppa*-*-hpux*) configdirs="${configdirs} ${hpdir}" ;;
+esac
+
+
+# Begin stuff to support --enable-shared
+AC_ARG_ENABLE(shared,
+[ --enable-shared use shared libraries],
+[case "${enableval}" in
+ yes) shared=true ;;
+ no) shared=false ;;
+ *) shared=true ;;
+esac])dnl
+RPATH_ENVVAR=LD_LIBRARY_PATH
+# If we have shared libraries, try to set RPATH_ENVVAR reasonably.
+if test "${shared}" = "true"; then
+ case "${host}" in
+ *-*-hpux*)
+ RPATH_ENVVAR=SHLIB_PATH
+ ;;
+ esac
+fi
+AC_SUBST(RPATH_ENVVAR)
+# End stuff to support --enable-shared
+# Start stuff to support --enable-gdbtk
+AC_ARG_ENABLE(gdbtk,
+[ --enable-gdbtk ],
+[case "${enableval}" in
+ yes)
+ case "$host" in
+ *go32*)
+ enable_gdbtk=no ;;
+ *windows*)
+ enable_gdbtk=no ;;
+ *)
+ enable_gdbtk=yes ;;
+ esac ;;
+ no)
+ enable_gdbtk=no ;;
+ *)
+ AC_MSG_ERROR(bad value ${enableval} given for gdbtk option) ;;
+esac],
+[
+# Default is on for everything but go32 and windows
+case "$host" in
+ *go32* | *windows*)
+ ;;
+ *)
+ enable_gdbtk=yes ;;
+ esac
+])
+
+if test "${enable_gdbtk}" = "yes"; then
+ configdirs="${configdirs} gdb.gdbtk"
+fi
+# End stuff to support --enable-shared
+
+dnl Check for exe extension set on certain hosts (e.g. Win32)
+AC_EXEEXT
+
+# configure the subdirectories too
+AC_CONFIG_SUBDIRS($configdirs)
+
+dnl AC_SUBST(gdb_target_cpu)
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.arch/Makefile.in b/gdb/testsuite/gdb.arch/Makefile.in
new file mode 100644
index 00000000000..f2dc1a930ab
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/Makefile.in
@@ -0,0 +1,31 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES = altivec-abi altivec-regs
+
+MISCELLANEOUS =
+
+all:
+ @echo "Nothing to be done for all..."
+
+info:
+install-info:
+dvi:
+install:
+uninstall: force
+installcheck:
+check:
+
+clean mostlyclean:
+ -rm -f *~ *.o a.out *.x *.ci *.tmp
+ -rm -f core core.coremaker coremaker.core corefile $(EXECUTABLES)
+ -rm -f $(MISCELLANEOUS)
+
+distclean maintainer-clean realclean: clean
+ -rm -f *~ core
+ -rm -f Makefile config.status config.log
+ -rm -f *-init.exp
+ -rm -fr *.log summary detail *.plog *.sum *.psum site.*
+
+Makefile : $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.arch/altivec-abi.c b/gdb/testsuite/gdb.arch/altivec-abi.c
new file mode 100644
index 00000000000..f68ec255642
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/altivec-abi.c
@@ -0,0 +1,141 @@
+#include <altivec.h>
+
+vector short vshort = {111, 222, 333, 444, 555, 666, 777, 888};
+vector unsigned short vushort = {100, 200, 300, 400, 500, 600, 700, 800};
+vector int vint = {-10, -20, -30, -40};
+vector unsigned int vuint = {1111, 2222, 3333, 4444};
+vector char vchar = {'a','b','c','d','e','f','g','h','i','l','m','n','o','p','q','r'};
+vector unsigned char vuchar = {'A','B','C','D','E','F','G','H','I','L','M','N','O','P','Q','R'};
+vector float vfloat = {1.25, 3.75, 5.5, 1.25};
+
+vector short vshort_d = {0,0,0,0,0,0,0,0};
+vector unsigned short vushort_d = {0,0,0,0,0,0,0,0};
+vector int vint_d = {0,0,0,0};
+vector unsigned int vuint_d = {0,0,0,0};
+vector char vchar_d = {'z','z','z','z','z','z','z','z','z','z','z','z','z','z','z','z'};
+vector unsigned char vuchar_d = {'Z','Z','Z','Z','Z','Z','Z','Z','Z','Z','Z','Z','Z','Z','Z','Z'};
+vector float vfloat_d = {1.0, 1.0, 1.0, 1.0};
+
+struct test_vec_struct
+{
+ vector signed short vshort1;
+ vector signed short vshort2;
+ vector signed short vshort3;
+ vector signed short vshort4;
+};
+
+static vector signed short test4[4] =
+{
+ (vector signed short) {1, 2, 3, 4, 5, 6, 7, 8},
+ (vector signed short) {11, 12, 13, 14, 15, 16, 17, 18},
+ (vector signed short) {21, 22, 23, 24, 25, 26, 27, 28},
+ (vector signed short) {31, 32, 33, 34, 35, 36, 37, 38}
+};
+
+void
+struct_of_vector_func (struct test_vec_struct vector_struct)
+{
+ vector_struct.vshort1 = vec_add (vector_struct.vshort1, vector_struct.vshort2);
+ vector_struct.vshort3 = vec_add (vector_struct.vshort3, vector_struct.vshort4);
+}
+
+void
+array_of_vector_func (vector signed short *matrix)
+{
+ matrix[0] = vec_add (matrix[0], matrix[1]);
+ matrix[2] = vec_add (matrix[2], matrix[3]);
+}
+
+vector int
+vec_func (vector short vshort_f, /* goes in v2 */
+ vector unsigned short vushort_f, /* goes in v3 */
+ vector int vint_f, /* goes in v4 */
+ vector unsigned int vuint_f, /* goes in v5 */
+ vector char vchar_f, /* goes in v6 */
+ vector unsigned char vuchar_f, /* goes in v7 */
+ vector float vfloat_f, /* goes in v8 */
+ vector short x_f, /* goes in v9 */
+ vector int y_f, /* goes in v10 */
+ vector char a_f, /* goes in v11 */
+ vector float b_f, /* goes in v12 */
+ vector float c_f, /* goes in v13 */
+ vector int intv_on_stack_f)
+{
+
+ vector int vint_res;
+ vector unsigned int vuint_res;
+ vector short vshort_res;
+ vector unsigned short vushort_res;
+ vector char vchar_res;
+ vector float vfloat_res;
+ vector unsigned char vuchar_res;
+
+ vint_res = vec_add (vint_f, intv_on_stack_f);
+ vint_res = vec_add (vint_f, y_f);
+ vuint_res = vec_add (vuint_f, ((vector unsigned int) {5,6,7,8}));
+ vshort_res = vec_add (vshort_f, x_f);
+ vushort_res = vec_add (vushort_f,
+ ((vector unsigned short) {1,2,3,4,5,6,7,8}));
+ vchar_res = vec_add (vchar_f, a_f);
+ vfloat_res = vec_add (vfloat_f, b_f);
+ vfloat_res = vec_add (c_f, ((vector float) {1.1,1.1,1.1,1.1}));
+ vuchar_res = vec_add (vuchar_f,
+ ((vector unsigned char) {'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a'}));
+
+ return vint_res;
+}
+
+void marker(void) {};
+
+int
+main (void)
+{
+ vector int result = {-1,-1,-1,-1};
+ vector short x = {1,2,3,4,5,6,7,8};
+ vector int y = {12, 22, 32, 42};
+ vector int intv_on_stack = {12, 34, 56, 78};
+ vector char a = {'v','e','c','t','o','r',' ','o','f',' ','c','h','a','r','s','.' };
+ vector float b = {5.5, 4.5, 3.75, 2.25};
+ vector float c = {1.25, 3.5, 5.5, 7.75};
+
+ vector short x_d = {0,0,0,0,0,0,0,0};
+ vector int y_d = {0,0,0,0};
+ vector int intv_on_stack_d = {0,0,0,0};
+ vector char a_d = {'q','q','q','q','q','q','q','q','q','q','q','q','q','q','q','q'};
+ vector float b_d = {5.0, 5.0, 5.0, 5.0};
+ vector float c_d = {3.0, 3.0, 3.0, 3.0};
+
+ int var_int = 44;
+ short var_short = 3;
+ struct test_vec_struct vect_struct;
+
+ vect_struct.vshort1 = (vector signed short){1, 2, 3, 4, 5, 6, 7, 8};
+ vect_struct.vshort2 = (vector signed short){11, 12, 13, 14, 15, 16, 17, 18};
+ vect_struct.vshort3 = (vector signed short){21, 22, 23, 24, 25, 26, 27, 28};
+ vect_struct.vshort4 = (vector signed short){31, 32, 33, 34, 35, 36, 37, 38};
+
+ marker ();
+#if 0
+ /* This line is useful for cutting and pasting from the gdb command line. */
+vec_func(vshort,vushort,vint,vuint,vchar,vuchar,vfloat,x,y,a,b,c,intv_on_stack)
+#endif
+ result = vec_func (vshort, /* goes in v2 */
+ vushort, /* goes in v3 */
+ vint, /* goes in v4 */
+ vuint, /* goes in v5 */
+ vchar, /* goes in v6 */
+ vuchar, /* goes in v7 */
+ vfloat, /* goes in v8 */
+ x, /* goes in v9 */
+ y, /* goes in v10 */
+ a, /* goes in v11 */
+ b, /* goes in v12 */
+ c, /* goes in v13 */
+ intv_on_stack);
+
+ struct_of_vector_func (vect_struct);
+ array_of_vector_func (test4);
+
+ return 0;
+}
+
diff --git a/gdb/testsuite/gdb.arch/altivec-abi.exp b/gdb/testsuite/gdb.arch/altivec-abi.exp
new file mode 100644
index 00000000000..8a9f29dd813
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/altivec-abi.exp
@@ -0,0 +1,113 @@
+# Copyright (C) 2002 Free Software Foundation, Inc.
+#
+# 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.
+#
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+#
+
+# Tests for Powerpc AltiVec ABI
+
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+#
+# This file uses altivec.c for input.
+#
+
+set prms_id 0
+set bug_id 0
+
+if ![istarget "powerpc-*altivec"] then {
+ verbose "Skipping altivec abi tests."
+ return
+}
+
+set testfile "altivec"
+set binfile ${objdir}/${subdir}/${testfile}
+
+set src1 ${srcdir}/${subdir}/${testfile}.c
+
+if { [gdb_compile ${src1} ${binfile} executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+ gdb_suppress_tests
+}
+
+gdb_test "b marker" "Breakpoint 2 at.*file.*altivec.c, line \[0-9\]+." "break marker"
+gdb_test "continue" "Breakpoint 2.*marker.*altivec.c.*" "continue to marker"
+gdb_test "finish" "Run till exit from .0.*in marker.*at.*altivec.c.*main \\(\\) at.*altivec.c.*result = vec_func \\(vshort,.*goes in v2.*" "back to main (1)"
+
+# now all the arguments of vec_fun are initialized
+
+set pattern "vec_func .vshort_f=.111, 222, 333, 444, 555, 666, 777, 888., vushort_f=.100, 200, 300, 400, 500, 600, 700, 800., vint_f=.-10, -20, -30, -40., vuint_f=.1111, 2222, 3333, 4444., vchar_f=.abcdefghilmnopqr., vuchar_f=.ABCDEFGHILMNOPQR., vfloat_f=.1.25, 3.75, 5.5, 1.25., x_f=.1, 2, 3, 4, 5, 6, 7, 8., y_f=.12, 22, 32, 42., a_f=.vector of chars.., b_f=.5.5, 4.5, 3.75, 2.25., c_f=.1.25, 3.5, 5.5, 7.75., intv_on_stack_f=.12, 34, 56, 78.."
+
+set pattern1 $pattern
+append pattern1 " at.*altivec.c.*vint_res = vec_add.*vint_f, intv_on_stack_f.;"
+
+# Now let's call the function. This function has > 12 args,
+# the last one will go on the stack.
+gdb_test "p vec_func(vshort,vushort,vint,vuint,vchar,vuchar,vfloat,x,y,a,b,c,intv_on_stack)" \
+".\[0-9\]+ = .2, 2, 2, 2." "call inferior function with vectors (1) "
+
+# Let's call the function again with dummy arguments. This is to clean
+# up the contents of the vector registers before the next call.
+gdb_test "p vec_func(vshort_d,vushort_d,vint_d,vuint_d,vchar_d,vuchar_d,vfloat_d,x_d,y_d,a_d,b_d,c_d,intv_on_stack_d)" \
+".\[0-9\]+ = .0, 0, 0, 0." "call inferior function with vectors (2) "
+
+# Let's step into the function, to see if the args are printed correctly.
+gdb_test "step" \
+ $pattern1 \
+ "step into vec_fun"
+
+set pattern2 $pattern
+append pattern2 " at.*altivec.c.*in main.*result = vec_func .vshort,.*goes in v2.*Value returned is.*= .2, 2, 2, 2."
+
+# Let's see if the result is returned correctly.
+gdb_test "finish" \
+ "Run till exit from .0.*$pattern2" \
+ "vector value returned correctly"
+
+# can we print the args correctly for this function?
+gdb_test "break struct_of_vector_func" "" ""
+
+set pattern "struct_of_vector_func .vector_struct=.vshort1 = .1, 2, 3, 4, 5, 6, 7, 8., vshort2 = .11, 12, 13, 14, 15, 16, 17, 18., vshort3 = .21, 22, 23, 24, 25, 26, 27, 28., vshort4 = .31, 32, 33, 34, 35, 36, 37, 38... at.*altivec.c.*"
+
+gdb_test "continue" \
+ "Breakpoint 3, $pattern.*vector_struct.vshort1 = vec_add .vector_struct.vshort1, vector_struct.vshort2.;" \
+ "continue to struct_of_vector_func"
+
+gdb_test "finish" \
+ "Run till exit from .0 $pattern\[ \r\n\]+main.*altivec.c.*array_of_vector_func.*" \
+ "back to main (2)"
+
+gdb_test "step" "" "step into array_of_vector_func"
+gdb_test "p matrix\[0\]" ".*= .1, 2, 3, 4, 5, 6, 7, 8." "print first vector"
+gdb_test "p matrix\[1\]" ".*= .11, 12, 13, 14, 15, 16, 17, 18." "print second vector"
+gdb_test "p matrix\[2\]" ".*= .21, 22, 23, 24, 25, 26, 27, 28." "print third vector"
+gdb_test "p matrix\[3\]" ".*= .31, 32, 33, 34, 35, 36, 37, 38." "print fourth vector"
+
diff --git a/gdb/testsuite/gdb.arch/altivec-regs.c b/gdb/testsuite/gdb.arch/altivec-regs.c
new file mode 100644
index 00000000000..4d4fe3f5dbb
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/altivec-regs.c
@@ -0,0 +1,41 @@
+#include <altivec.h>
+#include <stdio.h>
+
+vector unsigned int
+vector_fun (vector unsigned int a, vector unsigned int b)
+{
+ vector unsigned int c;
+ a = ((vector unsigned int) vec_splat_u8(2));
+ b = ((vector unsigned int) vec_splat_u8(3));
+
+ c = vec_add (a, b);
+ return c;
+}
+
+int
+main ()
+{
+ vector unsigned int y;
+ vector unsigned int x;
+ vector unsigned int z;
+ int a;
+
+ /* This line may look unnecessary but we do need it, because we want to
+ have a line to do a next over (so that gdb refetches the registers)
+ and we don't want the code to change any vector registers.
+ The splat operations below modify the VRs,i
+ so we don't want to execute them yet. */
+ a = 9;
+ x = ((vector unsigned int) vec_splat_u8 (-2));
+ y = ((vector unsigned int) vec_splat_u8 (1));
+
+ z = vector_fun (x, y);
+ x = vec_sld (x,y,2);
+
+ x = vec_add (x, ((vector unsigned int){5,6,7,8}));
+ z = (vector unsigned int) vec_splat_u8 ( -2);
+ y = vec_add (x, z);
+ z = (vector unsigned int) vec_cmpeq (x,y);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.arch/altivec-regs.exp b/gdb/testsuite/gdb.arch/altivec-regs.exp
new file mode 100644
index 00000000000..80433bff155
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/altivec-regs.exp
@@ -0,0 +1,220 @@
+# Copyright (C) 2002 Free Software Foundation, Inc.
+#
+# 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.
+#
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+#
+
+# Tests for Powerpc AltiVec register setting and fetching
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+#
+# Test the use of registers, especially AltiVec registers, for Powerpc.
+# This file uses altivec-regs.c for input.
+#
+
+set prms_id 0
+set bug_id 0
+
+if ![istarget "powerpc-*altivec"] then {
+ verbose "Skipping altivec register tests."
+ return
+}
+
+set testfile "altivec-regs"
+set binfile ${objdir}/${subdir}/${testfile}
+set src1 ${srcdir}/${subdir}/${testfile}.c
+
+if { [gdb_compile ${src1} ${binfile} executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+ gdb_suppress_tests
+}
+
+# set all the registers integer portions to 1
+for {set i 0} {$i < 32} {incr i 1} {
+ for {set j 0} {$j < 4} {incr j 1} {
+ gdb_test "set \$vr$i.v4_int32\[$j\] = 1" "" "set reg vr$i.v4si.f\[$j\]"
+ }
+}
+
+gdb_test "set \$vscr = 1" "" ""
+gdb_test "set \$vrsave = 1" "" ""
+
+# Now execute some target code, so that GDB's register cache is flushed.
+
+gdb_test "next" "" ""
+
+send_gdb "show endian\n"
+gdb_expect {
+ -re "(The target endianness is set automatically .currently )(big|little)( endian.*)$gdb_prompt $" {
+ pass "endianness"
+ set endianness $expect_out(2,string)
+ }
+ -re ".*$gdb_prompt $" {
+ fail "couldn't get endianness"
+ }
+ timeout { fail "(timeout) endianness" }
+}
+
+# And then read the AltiVec registers back, to see that
+# a) the register write above worked, and
+# b) the register read (below) also works.
+
+if {$endianness == "big"} {
+set vector_register ".uint128 = 0x00000001000000010000000100000001, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.."
+} else {
+set vector_register ".uint128 = 0x00000001000000010000000100000001, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0.."
+}
+
+for {set i 0} {$i < 32} {incr i 1} {
+ gdb_test "info reg vr$i" "vr$i.*$vector_register" "info reg vr$i"
+}
+
+gdb_test "info reg vrsave" "vrsave.*0x1" "info reg vrsave"
+gdb_test "info reg vscr" "vscr.*0x1" "info reg vscr"
+
+# Now redo the same tests, but using the print command.
+# Note: in LE case, the char array is printed WITHOUT the last character.
+# Gdb treats the terminating null char in the array like the terminating
+# null char in a string and doesn't print it. This is not a failure, but
+# the way gdb works.
+
+if {$endianness == "big"} {
+ set decimal_vector ".uint128 = 0x00000001000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .0, 1, 0, 1, 0, 1, 0, 1., v16_int8 = ..0.0.0.001.0.0.0.001.0.0.0.001.0.0.0.001.."
+} else {
+ set decimal_vector ".uint128 = 0x00000001000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .1, 0, 1, 0, 1, 0, 1, 0., v16_int8 = ..001.0.0.0.001.0.0.0.001.0.0.0.001.0.0.."
+}
+
+for {set i 0} {$i < 32} {incr i 1} {
+ gdb_test "print \$vr$i" ".* = $decimal_vector" "print vr$i"
+}
+
+gdb_test "print \$vrsave" ".* = 1" "print vrsave"
+gdb_test "print \$vscr" ".* = 1" "print vscr"
+
+for {set i 0} {$i < 32} {incr i 1} {
+ set pattern$i ".*vr$i.*"
+ append pattern$i $vector_register
+}
+
+send_gdb "info powerpc altivec\n"
+gdb_expect_list "info powerpc altivec" ".*$gdb_prompt $" {
+[$pattern0]
+[$pattern1]
+[$pattern2]
+[$pattern3]
+[$pattern4]
+[$pattern5]
+[$pattern6]
+[$pattern7]
+[$pattern8]
+[$pattern9]
+[$pattern10]
+[$pattern11]
+[$pattern12]
+[$pattern13]
+[$pattern14]
+[$pattern15]
+[$pattern16]
+[$pattern17]
+[$pattern18]
+[$pattern19]
+[$pattern20]
+[$pattern21]
+[$pattern22]
+[$pattern23]
+[$pattern24]
+[$pattern25]
+[$pattern26]
+[$pattern27]
+[$pattern28]
+[$pattern29]
+[$pattern30]
+[$pattern31]
+"\[ \t\n\r\]+vscr\[ \t\]+0x1"
+"\[ \t\n\r\]+vrsave\[ \t\]+0x1"
+}
+
+gdb_test "break vector_fun" \
+ "Breakpoint 2 at.*altivec-regs.c, line \[0-9\]+\\." \
+ "Set breakpoint at vector_fun"
+
+# Actually it is nuch easier to see these results printed in hex.
+gdb_test "set output-radix 16" \
+ "Output radix now set to decimal 16, hex 10, octal 20." \
+ "Set output radix to hex"
+
+gdb_test "continue" \
+ "Breakpoint 2, vector_fun .a=.0xfefefefe, 0xfefefefe, 0xfefefefe, 0xfefefefe., b=.0x1010101, 0x1010101, 0x1010101, 0x1010101.*altivec-regs.c.*vec_splat_u8.2..;" \
+ "continue to vector_fun"
+
+# Do a next over the assignment to vector 'a'.
+gdb_test "next" ".*b = \\(\\(vector unsigned int\\) vec_splat_u8\\(3\\)\\);" \
+ "next (1)"
+
+# Do a next over the assignment to vector 'b'.
+gdb_test "next" "c = vec_add \\(a, b\\);" \
+ "next (2)"
+
+# Now 'a' should be '0x02020202...' and 'b' should be '0x03030303...'
+gdb_test "print/x a" \
+ ".*= .0x2020202, 0x2020202, 0x2020202, 0x2020202." \
+ "print vector parameter a"
+
+gdb_test "print/x b" \
+ ".*= .0x3030303, 0x3030303, 0x3030303, 0x3030303." \
+ "print vector parameter b"
+
+# If we do an 'up' now, and print 'x' and 'y' we should see the values they
+# have in main, not the values they have in vector_fun.
+gdb_test "up" ".1.*main \\(\\) at.*altivec-regs.c.*z = vector_fun \\(x, y\\);" \
+ "up to main"
+
+gdb_test "print/x x" \
+ ".*= .0xfefefefe, 0xfefefefe, 0xfefefefe, 0xfefefefe." \
+ "print vector x"
+
+gdb_test "print/x y" \
+ ".*= .0x1010101, 0x1010101, 0x1010101, 0x1010101." \
+ "print vector y"
+
+# now go back to vector_func and do a finish, to see if we can print the return
+# value correctly.
+
+gdb_test "down" \
+ ".0 vector_fun \\(a=.0x2020202, 0x2020202, 0x2020202, 0x2020202., b=.0x3030303, 0x3030303, 0x3030303, 0x3030303.\\) at.*altivec-regs.c.*c = vec_add \\(a, b\\);" \
+ "down to vector_fun"
+
+gdb_test "finish" \
+ "Run till exit from .0 vector_fun \\(a=.0x2020202, 0x2020202, 0x2020202, 0x2020202., b=.0x3030303, 0x3030303, 0x3030303, 0x3030303.\\) at.*altivec-regs.c.*in main \\(\\) at.*altivec-regs.c.*z = vector_fun \\(x, y\\);.*Value returned is.*= .0x5050505, 0x5050505, 0x5050505, 0x5050505." \
+ "finish returned correct value"
+
+
+
diff --git a/gdb/testsuite/gdb.arch/configure b/gdb/testsuite/gdb.arch/configure
new file mode 100755
index 00000000000..205116b09da
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/configure
@@ -0,0 +1,913 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+sitefile=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --site-file=FILE use FILE as the site file
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -site-file | --site-file | --site-fil | --site-fi | --site-f)
+ ac_prev=sitefile ;;
+ -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
+ sitefile="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=Makefile.in
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$sitefile"; then
+ if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+ fi
+else
+ CONFIG_SITE="$sitefile"
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:586: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:607: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:625: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.arch/configure.in b/gdb/testsuite/gdb.arch/configure.in
new file mode 100644
index 00000000000..d72edff83a5
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/configure.in
@@ -0,0 +1,15 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(Makefile.in)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.asm/Makefile.in b/gdb/testsuite/gdb.asm/Makefile.in
new file mode 100644
index 00000000000..05ed656a387
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/Makefile.in
@@ -0,0 +1,36 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES =
+
+# uuencoded format to avoid SCCS/RCS problems with binary files.
+CROSS_EXECUTABLES =
+
+all:
+ @echo "Nothing to be done for all..."
+
+info:
+install-info:
+dvi:
+install:
+uninstall: force
+installcheck:
+check:
+
+clean mostlyclean:
+ -rm -f *~ *.o a.out xgdb *.x $(CROSS_EXECUTABLES) *.ci *.tmp
+ -rm -f core core.coremaker coremaker.core corefile $(EXECUTABLES)
+ -rm -f twice-tmp.c
+
+distclean maintainer-clean realclean: clean
+ -rm -f *~ core
+ -rm -f Makefile config.status config.log
+ -rm -f arch.inc
+ -rm -f *-init.exp
+ -rm -fr *.log summary detail *.plog *.sum *.psum site.*
+
+Makefile : $(srcdir)/Makefile.in config.status
+ $(SHELL) ./config.status
+
+config.status: $(srcdir)/configure
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.asm/arm.inc b/gdb/testsuite/gdb.asm/arm.inc
new file mode 100644
index 00000000000..701ecbf56bc
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/arm.inc
@@ -0,0 +1,34 @@
+ comment "subroutine prologue"
+ .macro gdbasm_enter
+ mov ip, sp
+ stmdb sp!, {fp, ip, lr, pc}
+ sub fp, ip, #4
+ .endm
+
+ comment "subroutine epilogue"
+ .macro gdbasm_leave
+ ldmea fp, {fp, sp, pc}
+ .endm
+
+ .macro gdbasm_call subr
+ bl \subr
+ .endm
+
+ .macro gdbasm_several_nops
+ nop
+ nop
+ nop
+ nop
+ .endm
+
+ comment "exit (0)"
+ .macro gdbasm_exit0
+ mov r0, #0
+ swi 0x00123456
+ .endm
+
+ comment "crt0 startup"
+ .macro gdbasm_startup
+ mov sp, #0
+ .endm
+
diff --git a/gdb/testsuite/gdb.asm/asm-source.exp b/gdb/testsuite/gdb.asm/asm-source.exp
new file mode 100644
index 00000000000..f6ce1c73b2b
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/asm-source.exp
@@ -0,0 +1,288 @@
+# Copyright 1998, 2000, 2002 Free Software Foundation, Inc.
+#
+# 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.
+#
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+#
+# This file was written by Kendra.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+#
+# Test debugging assembly level programs.
+# This file uses asmsrc[12].s for input.
+#
+
+set prms_id 0
+set bug_id 0
+
+set asm-arch ""
+set asm-flags ""
+set link-flags ""
+
+if [istarget "*arm-*-*"] then {
+ set asm-arch arm
+}
+if [istarget "xscale-*-*"] then {
+ set asm-arch arm
+}
+if [istarget "d10v-*-*"] then {
+ set asm-arch d10v
+}
+if [istarget "s390-*-*"] then {
+ set asm-arch s390
+}
+if [istarget "i\[3456\]86-*-*"] then {
+ set asm-arch i386
+}
+if [istarget "m32r*-*"] then {
+ set asm-arch m32r
+}
+if [istarget "powerpc*-*"] then {
+ set asm-arch powerpc
+}
+if [istarget "sparc-*-*"] then {
+ set asm-arch sparc
+}
+if [istarget "sparc64-*-*"] then {
+ set asm-arch sparc64
+ set asm-flags "-xarch=v9 -gstabs -I${srcdir}/${subdir} -I${objdir}/${subdir}"
+}
+if [istarget "xstormy16-*-*"] then {
+ set asm-arch xstormy16
+ set asm-flags "-gdwarf2 -I${srcdir}/${subdir} -I${objdir}/${subdir}"
+}
+if [istarget "v850-*-*"] then {
+ set asm-arch v850
+ set gdb_wrapper_initialized 1
+}
+if { "${asm-arch}" == "" } {
+ gdb_suppress_entire_file "Assembly source test -- not implemented for this target."
+}
+
+# Watch out, we are invoking the assembler, but the testsuite sets multilib
+# switches according to compiler syntax. If we pass these options straight
+# to the assembler, they won't always make sense. If we don't pass them to
+# the assembler, the final link will complain that the object files were
+# built with different defaults. So no matter what we do, we lose. We may as
+# well get out of this test sooner rather than later.
+set dest [target_info name]
+if [board_info $dest exists multilib_flags] {
+ set multilib_flags [board_info $dest multilib_flags]
+ if { "${multilib_flags}" != "" } {
+ gdb_suppress_entire_file "Assembly source test -- multilibs not supported by this test."
+ return;
+ }
+}
+
+set testfile "asm-source"
+set binfile ${objdir}/${subdir}/${testfile}
+set src1 ${srcdir}/${subdir}/asmsrc1.s
+set src2 ${srcdir}/${subdir}/asmsrc2.s
+
+remote_exec build "rm -f ${subdir}/arch.inc"
+remote_download host ${srcdir}/${subdir}/${asm-arch}.inc ${subdir}/arch.inc
+
+if { "${asm-flags}" == "" } {
+ #set asm-flags "-Wa,-gstabs,-I${srcdir}/${subdir},-I${objdir}/${subdir}"
+ set asm-flags "-gstabs -I${srcdir}/${subdir} -I${objdir}/${subdir}"
+}
+
+if {[target_assemble ${src1} asmsrc1.o "${asm-flags}"] != ""} then {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+if {[target_assemble ${src2} asmsrc2.o "${asm-flags}"] != ""} then {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+set opts "debug ldflags=-nostartfiles"
+foreach i ${link-flags} {
+ append opts " ldflags=$i"
+}
+if { [gdb_compile "asmsrc1.o asmsrc2.o" "${binfile}" executable $opts] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+remote_exec build "mv asmsrc1.o asmsrc2.o ${objdir}/${subdir}"
+
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+ gdb_suppress_tests
+}
+
+# Execute the `f' command and see if the result includes source info.
+gdb_test "f" "asmsrc1\[.\]s:29.*several_nops" "f at main"
+
+# See if we properly `next' over a macro with several insns.
+gdb_test "n" "33\[ \]*.*foo2" "next over macro"
+
+# See if we can properly `step' into a subroutine call.
+gdb_test "s" "8\[ \]*.*" "step into foo2"
+
+# Test 'info target', and incidentally capture the entry point address.
+set entry_point 0
+send_gdb "info target\n"
+gdb_expect {
+ -re "Symbols from .*asm-source.*Entry point: 0x(\[01232456789abcdefABCDEF\]+).*$gdb_prompt $" {
+ set entry_point $expect_out(1,string)
+ pass "info target"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "info target"
+ }
+ timeout {
+ fail "info target (timeout)"
+ }
+}
+
+# Capture the start symbol (may be '_start' or 'start')
+set entry_symbol ""
+send_gdb "info symbol 0x$entry_point\n"
+gdb_expect {
+ -re "info symbol 0x$entry_point\[\r\n\]+(\[^\r\n\]*) in section .*$gdb_prompt $" {
+ # We match the echoed `info symbol' command here, to help us
+ # reliably identify the beginning of the start symbol in the
+ # command's output. You might think we could just use '^' to
+ # start matching at the beginning of the line, but
+ # unfortunately, in Expect, '^' matches the beginning of the
+ # input that hasn't been matched by any expect clause yet. If
+ # every expect clause consumes a complete line, along with its
+ # terminating CR/LF, this is equivalent to the beginning of a
+ # line. But expect clauses that end with `.*' will consume as
+ # much as happened to arrive from the TTY --- exactly where
+ # they leave you depends on inter-process timing. :(
+ set entry_symbol $expect_out(1,string)
+ pass "info symbol"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "info symbol"
+ }
+ timeout {
+ fail "info symbol (timeout)"
+ }
+}
+
+# Now try a 'list' from the other source file.
+gdb_test "list $entry_symbol" ".*gdbasm_startup.*" "list"
+
+# Now try a source file search
+gdb_test "search A routine for foo2 to call" \
+ "39\[ \t\]+comment \"A routine for foo2 to call.\"" "search"
+
+# See if `f' prints the right source file.
+gdb_test "f" ".*asmsrc2\[.\]s:8.*" "f in foo2"
+
+# `next' one insn (or macro) to set up our stackframe (for the following bt).
+gdb_test "n" "12\[ \]*.*foo3" "n in foo2"
+
+# See if a simple `bt' prints the right source files and
+# doesn't fall off the stack.
+
+gdb_test "bt 10" \
+ "\#0.*foo2.*asmsrc2\[.\]s:12.*\#1.*main.*asmsrc1\[.\]s:33(.*\#2.*start\[^\r\n\]*)?" \
+ "bt ALL in foo2"
+
+# See if a capped `bt' prints the right source files.
+gdb_test "bt 2" "\#0.*foo2.*asmsrc2\[.\]s:12.*\#1.*main.*asmsrc1\[.\]s:33.*" "bt 2 in foo2"
+
+# Step into another subroutine which lives back in the first source file.
+gdb_test "s" "" "s 2"
+
+# Next over insns to set up the stack frame.
+gdb_test "n" "" "n 2"
+
+# Now see if a capped `bt' is correct.
+gdb_test "bt 3" "\#0.*foo3.*asmsrc1\[.\]s:44.*\#1.*foo2.*asmsrc2\[.\]s:12.*\#2.*main.*asmsrc1\[.\]s:33.*" "bt 3 in foo3"
+
+# Try 'info source' from asmsrc1.s
+gdb_test "info source" \
+ "Current source file is .*asmsrc1.s.*Source language is asm.*" \
+ "info source asmsrc1.s"
+
+# Try 'finishing' from foo3
+gdb_test "finish" "Run till exit from.*\[\r\n\]13\[ \t\]+gdbasm_call foo3" \
+ "finish from foo3"
+
+# Try 'info source' from asmsrc2.s
+gdb_test "info source" \
+ "Current source file is .*asmsrc2.s.*Source language is asm.*" \
+ "info source asmsrc2.s"
+
+# Try 'info sources'. This can produce a lot of output on systems
+# with dynamic linking, where the system's shared libc was compiled
+# with debugging info; for example, on Linux, this produces 47kb of
+# output. So we consume it as we go.
+send_gdb "info sources\n"
+set seen_asmsrc_1 0
+set seen_asmsrc_2 0
+gdb_expect {
+ -re "^\[^,\]*asmsrc1.s(, |\[\r\n\]+)" {
+ set seen_asmsrc_1 1
+ exp_continue
+ }
+ -re "^\[^,\]*asmsrc2.s(, |\[\r\n\]+)" {
+ set seen_asmsrc_2 1
+ exp_continue
+ }
+ -re ", " {
+ exp_continue
+ }
+ -re "$gdb_prompt $" {
+ if {$seen_asmsrc_1 && $seen_asmsrc_2} {
+ pass "info sources"
+ } else {
+ fail "info sources"
+ }
+ }
+ timeout {
+ fail "info sources (timeout)"
+ }
+}
+
+
+# Try 'info line'
+gdb_test "info line" \
+ "Line 13 of.*asmsrc2.s.*starts at.*<foo2+.*> and ends at.*<foo2+.*>." \
+ "info line"
+
+# Try 'nexting' over next call to foo3
+gdb_test "next" "17\[ \t\]+gdbasm_leave" "next over foo3"
+
+# Try 'return' from foo2
+gdb_test "return" "\#0 main .*37\[ \t\]+gdbasm_exit0" "return from foo2" \
+ "Make selected stack frame return now\?.*" "y"
+
+# See if we can look at a global variable
+gdb_test "print globalvar" ".* = 11" "look at global variable"
+
+# See if we can look at a static variable
+gdb_test "print staticvar" ".* = 5" "look at static variable"
+
+# See if we can look at a static function
+gdb_test "disassem foostatic" ".*<foostatic>:.*End of assembler dump." \
+ "look at static function"
+
+remote_exec build "rm -f ${subdir}/arch.inc"
diff --git a/gdb/testsuite/gdb.asm/asmsrc1.s b/gdb/testsuite/gdb.asm/asmsrc1.s
new file mode 100644
index 00000000000..f14cd915921
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/asmsrc1.s
@@ -0,0 +1,63 @@
+ .include "common.inc"
+ .include "arch.inc"
+
+comment "WARNING: asm-source.exp checks for line numbers printed by gdb."
+comment "Be careful about changing this file without also changing"
+comment "asm-source.exp."
+
+
+comment "This file is not linked with crt0."
+comment "Provide very simplistic equivalent."
+
+ .global _start
+_start:
+ gdbasm_startup
+ gdbasm_call main
+ gdbasm_exit0
+
+
+comment "main routine for assembly source debugging test"
+comment "This particular testcase uses macros in <arch>.inc to achieve"
+comment "machine independence."
+
+ .global main
+main:
+ gdbasm_enter
+
+comment "Call a macro that consists of several lines of assembler code."
+
+ gdbasm_several_nops
+
+comment "Call a subroutine in another file."
+
+ gdbasm_call foo2
+
+comment "All done."
+
+ gdbasm_exit0
+
+comment "A routine for foo2 to call."
+
+ .global foo3
+foo3:
+ gdbasm_enter
+ gdbasm_leave
+
+ .global exit
+exit:
+ gdbasm_exit0
+
+comment "A static function"
+
+foostatic:
+ gdbasm_enter
+ gdbasm_leave
+
+comment "A global variable"
+
+ .global globalvar
+gdbasm_datavar globalvar 11
+
+comment "A static variable"
+
+gdbasm_datavar staticvar 5
diff --git a/gdb/testsuite/gdb.asm/asmsrc2.s b/gdb/testsuite/gdb.asm/asmsrc2.s
new file mode 100644
index 00000000000..9d7713fad84
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/asmsrc2.s
@@ -0,0 +1,17 @@
+ .include "common.inc"
+ .include "arch.inc"
+
+comment "Second file in assembly source debugging testcase."
+
+ .global foo2
+foo2:
+ gdbasm_enter
+
+comment "Call someplace else (several times)."
+
+ gdbasm_call foo3
+ gdbasm_call foo3
+
+comment "All done, return."
+
+ gdbasm_leave
diff --git a/gdb/testsuite/gdb.asm/common.inc b/gdb/testsuite/gdb.asm/common.inc
new file mode 100644
index 00000000000..51493929765
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/common.inc
@@ -0,0 +1,28 @@
+ .macro comment text
+ .endm
+
+ comment "Can't rely on assembler comment character so do this."
+
+ .macro include arch file
+ .include "\arch\file"
+ .endm
+
+ comment "Declare a data variable"
+ .macro gdbasm_datavar name value
+ .data
+\name:
+ .word \value
+ .endm
+
+comment "arch.inc is responsible for defining the following macros:"
+comment "enter - subroutine prologue"
+comment "leave - subroutine epilogue"
+comment "call - call a named subroutine"
+comment "several_nops - execute several (typically 4) nops"
+comment "exit0 - exit (0)"
+
+comment "arch.inc may also override the default definitions of:"
+comment "datavar - define a data variable"
+
+comment "macros to label a subroutine may also eventually be needed"
+comment "i.e. .global foo\nfoo:\n"
diff --git a/gdb/testsuite/gdb.asm/configure b/gdb/testsuite/gdb.asm/configure
new file mode 100755
index 00000000000..1dd81387d9c
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/configure
@@ -0,0 +1,913 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+sitefile=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --site-file=FILE use FILE as the site file
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -site-file | --site-file | --site-fil | --site-fi | --site-f)
+ ac_prev=sitefile ;;
+ -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
+ sitefile="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=asm-source.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$sitefile"; then
+ if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+ fi
+else
+ CONFIG_SITE="$sitefile"
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:586: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:607: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:625: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.asm/configure.in b/gdb/testsuite/gdb.asm/configure.in
new file mode 100644
index 00000000000..bded89e9693
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/configure.in
@@ -0,0 +1,15 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(asm-source.exp)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.asm/d10v.inc b/gdb/testsuite/gdb.asm/d10v.inc
new file mode 100644
index 00000000000..bd9463fc891
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/d10v.inc
@@ -0,0 +1,55 @@
+ comment "subroutine prologue"
+ .macro gdbasm_enter
+ st r11,@-sp
+ st r13,@-sp
+ mv r11,sp
+ .endm
+
+ comment "subroutine epilogue"
+ .macro gdbasm_leave
+ add3 sp,r11,0
+ ld r13,@sp+
+ ld r11,@sp+
+ jmp r13
+ .endm
+
+ .macro gdbasm_call subr
+ bl \subr
+ .endm
+
+ .macro gdbasm_several_nops
+ nop
+ nop
+ nop
+ nop
+ .endm
+
+ comment "exit (0)"
+ .macro gdbasm_exit0
+ ldi r4, 1
+ ldi r0, 0
+ trap 15
+ .endm
+
+ comment "crt0 startup"
+ .macro gdbasm_startup
+; R14 always contains memory base address (0)
+
+ ldi r14,0
+
+; Set the USER and SYSTEM stack pointers.
+
+ ldi r0, 0 ; zero arguments
+ ldi r1, 0
+ mvtc r0, psw ; select SPI and set it
+ ldi sp, _stack
+ ldi r10, 0x8000 ; select SPU/FP and set it
+ mvtc r10, psw || ldi r11, 0; clear stack frame
+ ldi sp, _stack - 0x200
+ ldi r13, 0
+
+ st r11, @-sp
+ st r13, @-sp
+; mv r11, sp
+
+ .endm
diff --git a/gdb/testsuite/gdb.asm/i386.inc b/gdb/testsuite/gdb.asm/i386.inc
new file mode 100644
index 00000000000..9746646ba62
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/i386.inc
@@ -0,0 +1,39 @@
+ comment "subroutine prologue"
+ .macro gdbasm_enter
+ push %ebp
+ mov %esp,%ebp
+ .endm
+
+ comment "subroutine epilogue"
+ .macro gdbasm_leave
+ pop %ebp
+ ret
+ .endm
+
+ .macro gdbasm_call subr
+ call \subr
+ .endm
+
+ .macro gdbasm_several_nops
+ nop
+ nop
+ nop
+ nop
+ .endm
+
+ comment "exit (0)"
+ .macro gdbasm_exit0
+ hlt
+ .endm
+
+ comment "crt0 startup"
+ .macro gdbasm_startup
+ xor %ebp, %ebp
+ .endm
+
+ comment "Declare a data variable"
+ .macro gdbasm_datavar name value
+ .data
+\name:
+ .long \value
+ .endm
diff --git a/gdb/testsuite/gdb.asm/m32r.inc b/gdb/testsuite/gdb.asm/m32r.inc
new file mode 100644
index 00000000000..6110373df41
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/m32r.inc
@@ -0,0 +1,35 @@
+ comment "subroutine prologue"
+ .macro gdbasm_enter
+ push fp -> push lr
+ addi sp,#-4 -> mv fp,sp
+ .endm
+
+ comment "subroutine epilogue"
+ .macro gdbasm_leave
+ addi sp,#4 -> pop lr
+ pop fp -> jmp lr
+ .endm
+
+ .macro gdbasm_call subr
+ bl \subr -> nop
+ .endm
+
+ .macro gdbasm_several_nops
+ nop
+ nop
+ nop
+ nop
+ .endm
+
+ comment "exit (0)"
+ .macro gdbasm_exit0
+ ldi r0,#1 -> ldi r1,#0
+ ldi r2,#0 -> ldi r3,#0
+ trap #0 -> nop
+ .endm
+
+ comment "crt0 startup"
+ .macro gdbasm_startup
+ ld24 sp,_stack
+ ldi fp,#0
+ .endm
diff --git a/gdb/testsuite/gdb.asm/powerpc.inc b/gdb/testsuite/gdb.asm/powerpc.inc
new file mode 100644
index 00000000000..5aefde2c02f
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/powerpc.inc
@@ -0,0 +1,46 @@
+ comment "subroutine prologue"
+ .macro gdbasm_enter
+ stwu 1, -16(1)
+ stw 31, 8(1)
+ mr 31, 1
+ mflr 0
+ stw 0, 20(1)
+ .endm
+
+ comment "subroutine epilogue"
+ .macro gdbasm_leave
+ lwz 0, 20(1)
+ mtlr 0
+ lwz 31, 8(1)
+ lwz 1, 0(1)
+ blr
+ .endm
+
+ .macro gdbasm_call subr
+ bl \subr
+ .endm
+
+ .macro gdbasm_several_nops
+ nop
+ nop
+ nop
+ nop
+ .endm
+
+ comment "exit (0)"
+ .macro gdbasm_exit0
+ comment "Don't know how to exit, but this will certainly halt..."
+ li 0, 0
+ lwz 0, 0(0)
+ .endm
+
+ comment "crt0 startup"
+ .macro gdbasm_startup
+ .endm
+
+ comment "Declare a data variable"
+ .macro gdbasm_datavar name value
+ .data
+\name:
+ .long \value
+ .endm
diff --git a/gdb/testsuite/gdb.asm/s390.inc b/gdb/testsuite/gdb.asm/s390.inc
new file mode 100644
index 00000000000..196a9603c93
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/s390.inc
@@ -0,0 +1,75 @@
+### entry point code
+ .macro gdbasm_startup
+
+ # Align the stack pointer to an 8-byte boundary.
+ lhi %r0,-8
+ nr %r15,%r0
+
+ # Reserve space for the standard stack frame:
+ # back chain, and space for the callee to save its registers.
+ ahi %r15,-104
+
+ # Zero this frame's back chain pointer.
+ xc 0(4,%r15),0(%r15)
+ .endm
+
+
+### Call a function.
+ .macro gdbasm_call subr
+
+ # Put the address of the constant in %r1, load the constant
+ # (SUBR's address), and jump to it.
+ bras %r1, .Lafterconst\@
+ .long \subr
+.Lafterconst\@:
+ l %r1,0(%r1)
+ basr %r14,%r1
+ .endm
+
+
+### Exit with a zero status.
+ .macro gdbasm_exit0
+ lhi %r2, 0
+ svc 1
+ .endm
+
+### Standard subroutine prologue.
+ .macro gdbasm_enter
+
+ # Save all the callee-saves registers. What the heck.
+ stm %r6,%r15,24(%r15)
+
+ # Allocate the stack frame, and write the back chain pointer.
+ # Keep the original SP in %r11.
+ lr %r1,%r15
+ ahi %r15,-96
+ st %r1,0(%r15)
+ .endm
+
+
+### Standard subroutine epilogue.
+ .macro gdbasm_leave
+
+ # Restore all our registers. This also pops the frame, and
+ # restores our return address.
+ lm %r6,%r15,120(%r15)
+
+ # Jump to the return address.
+ br %r14
+
+ .endm
+
+### Several nops.
+ .macro gdbasm_several_nops
+ lr %r0, %r0
+ lr %r0, %r0
+ lr %r0, %r0
+ lr %r0, %r0
+ .endm
+
+### Declare an `int' variable.
+ .macro gdbasm_datavar name value
+ .data
+\name:
+ .long \value
+ .endm
diff --git a/gdb/testsuite/gdb.asm/sparc.inc b/gdb/testsuite/gdb.asm/sparc.inc
new file mode 100644
index 00000000000..916a9e0e794
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/sparc.inc
@@ -0,0 +1,34 @@
+ comment "subroutine prologue"
+ .macro gdbasm_enter
+ save %sp, -112, %sp
+ .endm
+
+ comment "subroutine epilogue"
+ .macro gdbasm_leave
+ ret
+ restore
+ .endm
+
+ .macro gdbasm_call subr
+ call \subr
+ nop
+ .endm
+
+ .macro gdbasm_several_nops
+ nop
+ nop
+ nop
+ nop
+ .endm
+
+ comment "exit (0)"
+ .macro gdbasm_exit0
+ comment "Don't know how to exit, but this will certainly halt..."
+ ld [%g0], %i0
+ .endm
+
+ comment "crt0 startup"
+ .macro gdbasm_startup
+ clr %fp
+ .endm
+
diff --git a/gdb/testsuite/gdb.asm/sparc64.inc b/gdb/testsuite/gdb.asm/sparc64.inc
new file mode 100644
index 00000000000..fb2253e0c39
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/sparc64.inc
@@ -0,0 +1,34 @@
+ comment "subroutine prologue"
+ .macro gdbasm_enter
+ save %sp, -192, %sp
+ .endm
+
+ comment "subroutine epilogue"
+ .macro gdbasm_leave
+ return %i7 + 8
+ nop
+ .endm
+
+ .macro gdbasm_call subr
+ call \subr
+ nop
+ .endm
+
+ .macro gdbasm_several_nops
+ nop
+ nop
+ nop
+ nop
+ .endm
+
+ comment "exit (0)"
+ .macro gdbasm_exit0
+ comment "Don't know how to exit, but this will certainly halt..."
+ ldx [%g0], %i0
+ .endm
+
+ comment "crt0 startup"
+ .macro gdbasm_startup
+ clr %fp
+ .endm
+
diff --git a/gdb/testsuite/gdb.asm/v850.inc b/gdb/testsuite/gdb.asm/v850.inc
new file mode 100644
index 00000000000..87977919f0c
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/v850.inc
@@ -0,0 +1,41 @@
+ comment "subroutine prologue"
+ .macro gdbasm_enter
+ add -8,sp
+ st.w r31,4[sp]
+ st.w r29,0[sp]
+ mov sp,r29
+ .endm
+
+ comment "subroutine epilogue"
+ .macro gdbasm_leave
+ mov r29,sp
+ ld.w 0[sp],r29
+ ld.w 4[sp],r31
+ add 8,sp
+ jmp [r31]
+ .endm
+
+ .macro gdbasm_call subr
+ jarl \subr,r31
+ .endm
+
+ .macro gdbasm_several_nops
+ nop
+ nop
+ nop
+ nop
+ .endm
+
+ comment "exit (0)"
+ .macro gdbasm_exit0
+ halt
+ .endm
+
+ comment "crt0 startup"
+ .macro gdbasm_startup
+ movea 255,r0,r20
+ mov r0, r21
+ ori 65535, r0, r21
+ movhi 32, r0, sp
+ .endm
+
diff --git a/gdb/testsuite/gdb.asm/x86_64.inc b/gdb/testsuite/gdb.asm/x86_64.inc
new file mode 100644
index 00000000000..5bcaeae25ab
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/x86_64.inc
@@ -0,0 +1,39 @@
+ comment "subroutine prologue"
+ .macro gdbasm_enter
+ push %rbp
+ mov %rsp,%rbp
+ .endm
+
+ comment "subroutine epilogue"
+ .macro gdbasm_leave
+ pop %rbp
+ ret
+ .endm
+
+ .macro gdbasm_call subr
+ call \subr
+ .endm
+
+ .macro gdbasm_several_nops
+ nop
+ nop
+ nop
+ nop
+ .endm
+
+ comment "exit (0)"
+ .macro gdbasm_exit0
+ hlt
+ .endm
+
+ comment "crt0 startup"
+ .macro gdbasm_startup
+ xor %rbp, %rbp
+ .endm
+
+ comment "Declare a data variable"
+ .macro gdbasm_datavar name value
+ .data
+\name:
+ .long \value
+ .endm
diff --git a/gdb/testsuite/gdb.asm/xstormy16.inc b/gdb/testsuite/gdb.asm/xstormy16.inc
new file mode 100644
index 00000000000..22827f3eb1c
--- /dev/null
+++ b/gdb/testsuite/gdb.asm/xstormy16.inc
@@ -0,0 +1,34 @@
+ comment "subroutine prologue"
+ .macro gdbasm_enter
+ push r13
+ mov r13,r15
+ .endm
+
+ comment "subroutine epilogue"
+ .macro gdbasm_leave
+ pop r13
+ ret
+ .endm
+
+ .macro gdbasm_call subr
+ callf \subr
+ .endm
+
+ .macro gdbasm_several_nops
+ add r0,#0
+ add r0,#0
+ add r0,#0
+ add r0,#0
+ .endm
+
+ comment "exit (0)"
+ .macro gdbasm_exit0
+ mov.w r2,#0
+ halt
+ .endm
+
+ comment "crt0 startup"
+ .macro gdbasm_startup
+ mov r15,#2
+ .endm
+
diff --git a/gdb/testsuite/gdb.base/Makefile.in b/gdb/testsuite/gdb.base/Makefile.in
new file mode 100644
index 00000000000..c878f15de7c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/Makefile.in
@@ -0,0 +1,43 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES = all-types annota1 bitfields break \
+ call-ar-st call-rt-st call-strs callfuncs callfwmall \
+ commands compiler condbreak constvars coremaker \
+ dbx-test display ending-run execd-prog exprs \
+ foll-exec foll-fork foll-vfork funcargs int-type interrupt jump \
+ langs list long_long mips_pro miscexprs nodebug opaque overlays \
+ pointers pointers2 printcmds ptype \
+ recurse reread reread1 restore return run \
+ scope section_command setshow setvar shmain sigall signals \
+ solib solib_sl so-impl-ld so-indr-cl \
+ step-line step-test structs structs2 \
+ twice-tmp varargs vforked-prog watchpoint whatis
+
+MISCELLANEOUS = coremmap.data ../foobar.baz \
+ shr1.sl shr2.sl solib_sl.sl solib1.sl solib2.sl
+
+all:
+ @echo "Nothing to be done for all..."
+
+info:
+install-info:
+dvi:
+install:
+uninstall: force
+installcheck:
+check:
+
+clean mostlyclean:
+ -rm -f *~ *.o a.out xgdb *.x *.ci *.tmp
+ -rm -f core core.coremaker coremaker.core corefile $(EXECUTABLES)
+ -rm -f $(MISCELLANEOUS) twice-tmp.c
+
+distclean maintainer-clean realclean: clean
+ -rm -f *~ core
+ -rm -f Makefile config.status config.log
+ -rm -f *-init.exp
+ -rm -fr *.log summary detail *.plog *.sum *.psum site.*
+
+Makefile : $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.base/a2-run.exp b/gdb/testsuite/gdb.base/a2-run.exp
new file mode 100644
index 00000000000..fbc704470cb
--- /dev/null
+++ b/gdb/testsuite/gdb.base/a2-run.exp
@@ -0,0 +1,257 @@
+# Copyright 1988, 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1999, 2000
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+# These tests don't work for targets can't take arguments...
+
+if [target_info exists noargs] then {
+ verbose "Skipping a2-run.exp because of noargs."
+ return
+}
+
+# Can't do this test without stdio support.
+if [gdb_skip_stdio_test "a2run.exp"] {
+ return
+}
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "run"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Run with no arguments.
+# On VxWorks this justs make sure the program was run.
+gdb_run_cmd
+
+if [istarget "*-*-vxworks*"] then {
+ set timeout 120
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ "Program exited normally" {
+ unresolved "run \"$testfile\" with no args"
+ }
+ -re "usage: factorial <number>" {
+ pass "run \"$testfile\" with no args"
+ }
+ timeout {
+ fail "(timeout) run \"$testfile\" with no args"
+ }
+ }
+ set timeout 10
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect -re "$gdb_prompt $" {}
+} else {
+ gdb_expect {
+ -re ".*usage: factorial <number>.*Program exited with code 01.*$gdb_prompt $" {
+ pass "run \"$testfile\" with no args"
+ }
+ -re ".*usage: factorial <number>.* EXIT code 1.*Program exited normally.*$gdb_prompt $" {
+ pass "run \"$testfile\" with no args (exit wrapper)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "run \"$testfile\" with no args"
+ verbose "expect_out is $expect_out(buffer)" 2
+ }
+ timeout {
+ fail "(timeout) run \"$testfile\" no args"
+ }
+ }
+}
+# Now run with some arguments
+if [istarget "*-*-vxworks*"] then {
+ send_gdb "run vxmain \"5\"\n"
+ gdb_expect -re "run vxmain \"5\"\r\n" {}
+ set timeout 120
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ "Program exited normally" {
+ unresolved "run \"$testfile\" with arg"
+ }
+ "120" {
+ pass "run \"$testfile\" with arg"
+ }
+ timeout {
+ fail "(timeout) run \"$testfile\" with arg"
+ }
+ }
+ set timeout 10
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect -re "$gdb_prompt $" {}
+} else {
+ setup_xfail "mips-idt-*" "arm-*-coff strongarm-*-coff"
+ gdb_run_cmd 5
+ gdb_expect {
+ -re ".*120.*$gdb_prompt $"\
+ { pass "run \"$testfile\" with arg" }
+ -re ".*$gdb_prompt $" { fail "run \"$testfile\" with arg" }
+ timeout { fail "(timeout) run \"$testfile\" with arg" }
+ }
+}
+
+# Run again with same arguments.
+setup_xfail "mips-idt-*"
+gdb_run_cmd
+
+if [istarget "*-*-vxworks*"] then {
+ set timeout 120
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ "Program exited normally" {
+ unresolved "run \"$testfile\" again with same args"
+ }
+ "120" { pass "run \"$testfile\" again with same args" }
+ timeout { fail "(timeout) run \"$testfile\" again with same args" }
+ }
+ set timeout 10
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect -re "$gdb_prompt $" {}
+} else {
+ setup_xfail "arm-*-coff strongarm-*-coff"
+ gdb_expect {
+ -re ".*120.*$gdb_prompt $"\
+ { pass "run \"$testfile\" again with same args" }
+ -re ".*$gdb_prompt $" { fail "run \"$testfile\" again with same args" }
+ timeout { fail "(timeout) run \"$testfile\" again with same args" }
+ }
+}
+
+# Use "set args" command to specify no arguments as default and run again.
+if [istarget "*-*-vxworks*"] then {
+ send_gdb "set args main\n"
+} else {
+ send_gdb "set args\n"
+}
+gdb_expect -re "$gdb_prompt $"
+
+gdb_run_cmd
+
+if [istarget "*-*-vxworks*"] then {
+ set timeout 120
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ "Program exited normally" {
+ unresolved "run after setting args to nil"
+ }
+ "usage: factorial <number>" {
+ pass "run after setting args to nil"
+ }
+ timeout {
+ fail "(timeout) run after setting args to nil"
+ }
+ }
+ set timeout 10
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect -re "$gdb_prompt $" {}
+} else {
+ gdb_expect {
+ -re ".*usage: factorial <number>.*$gdb_prompt $" {
+ pass "run after setting args to nil"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "run after setting args to nil"
+ }
+ timeout {
+ fail "(timeout) run after setting args to nil"
+ }
+ }
+}
+
+# Use "set args" command to specify an argument and run again.
+setup_xfail "mips-idt-*"
+if [istarget "*-*-vxworks*"] then {
+ send_gdb "set args vxmain \"6\"\n"
+} else {
+ send_gdb "set args 6\n"
+}
+gdb_expect -re "$gdb_prompt $"
+gdb_run_cmd
+
+if [istarget "*-*-vxworks*"] then {
+ set timeout 120
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect {
+ "Program exited normally" {
+ unresolved "run \"$testfile\" again after setting args"
+ }
+ "720" {
+ pass "run \"$testfile\" again after setting args"
+ }
+ timeout {
+ fail "(timeout) run \"$testfile\" again after setting args"
+ }
+ }
+ set timeout 10
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_expect -re "$gdb_prompt $" {}
+} else {
+ setup_xfail "arm-*-coff strongarm-*-coff"
+ gdb_expect {
+ -re ".*720.*$gdb_prompt $" {
+ pass "run \"$testfile\" again after setting args"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "run \"$testfile\" again after setting args"
+ }
+ timeout {
+ fail "(timeout) run \"$testfile\" again after setting args"
+ }
+ }
+}
+
+# GOAL: Test that shell is being used with "run". For remote debugging
+# targets, there is no guarantee that a "shell" (whatever that is) is used.
+if ![is_remote target] then {
+ send_gdb "run `echo 8`\n"
+ gdb_expect {
+ -re "Starting program.*40320.*$gdb_prompt $" {
+ pass "run \"$testfile\" with shell"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "run \"$testfile\" with shell"
+ }
+ timeout {
+ fail "(timeout) run \"$testfile\" with shell"
+ }
+ }
+}
+
+# Reset the default arguments for VxWorks
+if [istarget "*-*-vxworks*"] then {
+ send_gdb "set args main\n"
+ gdb_expect -re ".*$gdb_prompt $" {}
+}
diff --git a/gdb/testsuite/gdb.base/all-bin.exp b/gdb/testsuite/gdb.base/all-bin.exp
new file mode 100644
index 00000000000..fe6b7558e4c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/all-bin.exp
@@ -0,0 +1,471 @@
+# Copyright 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+# This file is part of the gdb testsuite
+#
+# tests for arithmetic, logical and relational operators
+# with mixed types
+#
+
+
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "all-types"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+gdb_test "next" "return 0;" "continuing after dummy()"
+
+send_gdb "print v_int+v_char\n"
+gdb_expect {
+ -re ".*71.*$gdb_prompt $" {
+ pass "print value of v_int+v_char"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int+v_char" }
+ timeout { fail "(timeout) print value of v_int+v_char" }
+ }
+
+send_gdb "print v_int+v_short\n"
+gdb_expect {
+ -re ".*9.*$gdb_prompt $" {
+ pass "print value of v_int+v_short"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int+v_short" }
+ timeout { fail "(timeout) print value of v_int+v_short" }
+ }
+
+
+send_gdb "print v_int+v_signed_char\n"
+gdb_expect {
+ -re ".*72.*$gdb_prompt $" {
+ pass "print value of v_int+v_signed_char"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int+v_signed_char" }
+ timeout { fail "(timeout) print value of v_int+v_signed_char" }
+ }
+
+
+send_gdb "print v_int+v_unsigned_char\n"
+gdb_expect {
+ -re ".*73.*$gdb_prompt $" {
+ pass "print value of v_int+v_unsigned_char"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int+v_unsigned_char" }
+ timeout { fail "(timeout) print value of v_int+v_unsigned_char" }
+ }
+
+
+send_gdb "print v_int+v_signed_short\n"
+gdb_expect {
+ -re ".*10.*$gdb_prompt $" {
+ pass "print value of v_int+v_signed_short"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int+v_signed_short" }
+ timeout { fail "(timeout) print value of v_int+v_signed_short" }
+ }
+
+
+send_gdb "print v_int+v_unsigned_short\n"
+gdb_expect {
+ -re ".*11.*$gdb_prompt $" {
+ pass "print value of v_int+v_unsigned_short"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int+v_unsigned_short" }
+ timeout { fail "(timeout) print value of v_int+v_unsigned_short" }
+ }
+
+
+send_gdb "print v_int+v_signed_int\n"
+gdb_expect {
+ -re ".*13.*$gdb_prompt $" {
+ pass "print value of v_int+v_signed_int"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int+v_signed_int" }
+ timeout { fail "(timeout) print value of v_int+v_signed_int" }
+ }
+
+
+send_gdb "print v_int+v_unsigned_int\n"
+gdb_expect {
+ -re ".*14.*$gdb_prompt $" {
+ pass "print value of v_int+v_unsigned_int"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int+v_unsigned_int" }
+ timeout { fail "(timeout) print value of v_int+v_unsigned_int" }
+ }
+
+
+send_gdb "print v_int+v_long\n"
+gdb_expect {
+ -re ".*15.*$gdb_prompt $" {
+ pass "print value of v_int+v_long"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int+v_long" }
+ timeout { fail "(timeout) print value of v_int+v_long" }
+ }
+
+
+send_gdb "print v_int+v_signed_long\n"
+gdb_expect {
+ -re ".*16.*$gdb_prompt $" {
+ pass "print value of v_int+v_signed_long"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int+v_signed_long" }
+ timeout { fail "(timeout) print value of v_int+v_signed_long" }
+ }
+
+
+send_gdb "print v_int+v_unsigned_long\n"
+gdb_expect {
+ -re ".*17.*$gdb_prompt $" {
+ pass "print value of v_int+v_unsigned_long"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int+v_unsigned_long" }
+ timeout { fail "(timeout) print value of v_int+v_unsigned_long" }
+ }
+
+
+send_gdb "print v_int+v_float\n"
+gdb_expect {
+ -re ".*106.34343.*$gdb_prompt $" {
+ pass "print value of v_int+v_float"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int+v_float" }
+ timeout { fail "(timeout) print value of v_int+v_float" }
+ }
+
+
+send_gdb "print v_int+v_double\n"
+gdb_expect {
+ -re ".*206.565.*$gdb_prompt $" {
+ pass "print value of v_int+v_double"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int+v_double" }
+ timeout { fail "(timeout) print value of v_int+v_double" }
+}
+
+
+#
+# test the relational operators with mixed types
+#
+
+send_gdb "print v_int <= v_char\n"
+gdb_expect {
+ -re ".*1.*$gdb_prompt $" {
+ pass "print value of v_int<=v_char"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int<=v_char" }
+ timeout { fail "(timeout) print value of v_int<=v_char" }
+ }
+
+send_gdb "print v_int <= v_short\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of v_int<=v_short"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int<=v_short" }
+ timeout { fail "(timeout) print value of v_int<=v_short" }
+ }
+
+
+send_gdb "print v_int <= v_signed_char\n"
+gdb_expect {
+ -re ".*1.*$gdb_prompt $" {
+ pass "print value of v_int<=v_signed_char"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int<=v_signed_char" }
+ timeout { fail "(timeout) print value of v_int<=v_signed_char" }
+ }
+
+
+send_gdb "print v_int <= v_unsigned_char\n"
+gdb_expect {
+ -re ".*1.*$gdb_prompt $" {
+ pass "print value of v_int<=v_unsigned_char"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int<=v_unsigned_char" }
+ timeout { fail "(timeout) print value of v_int<=v_unsigned_char" }
+ }
+
+
+send_gdb "print v_int <= v_signed_short\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of v_int<=v_signed_short"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int<=v_signed_short" }
+ timeout { fail "(timeout) print value of v_int<=v_signed_short" }
+ }
+
+
+send_gdb "print v_int <= v_unsigned_short\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of v_int<=v_unsigned_short"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int<=v_unsigned_short" }
+ timeout { fail "(timeout) print value of v_int<=v_unsigned_short" }
+ }
+
+
+send_gdb "print v_int <= v_signed_int\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int<=v_signed_int"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int<=v_signed_int" }
+ timeout { fail "(timeout) print value of v_int<=v_signed_int" }
+ }
+
+
+send_gdb "print v_int <= v_unsigned_int\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int<=v_unsigned_int"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int<=v_unsigned_int" }
+ timeout { fail "(timeout) print value of v_int<=v_unsigned_int" }
+ }
+
+
+send_gdb "print v_int <= v_long\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int<=v_long"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int<=v_long" }
+ timeout { fail "(timeout) print value of v_int<=v_long" }
+ }
+
+
+send_gdb "print v_int <= v_signed_long\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int<=v_signed_long"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int<=v_signed_long" }
+ timeout { fail "(timeout) print value of v_int<=v_signed_long" }
+ }
+
+
+send_gdb "print v_int <= v_unsigned_long\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int<=v_unsigned_long"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int<=v_unsigned_long" }
+ timeout { fail "(timeout) print value of v_int<=v_unsigned_long" }
+ }
+
+
+send_gdb "print v_int <= v_float\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int<=v_float"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int<=v_float" }
+ timeout { fail "(timeout) print value of v_int<=v_float" }
+ }
+
+
+send_gdb "print v_int <= v_double\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int<=v_double"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int<=v_double" }
+ timeout { fail "(timeout) print value of v_int<=v_double" }
+ }
+
+
+
+#
+# test the logical operators with mixed types
+#
+
+gdb_test "set variable v_char=0" "" "set v_char=0"
+gdb_test "set variable v_double=0.0" "" "set v_double=0"
+gdb_test "set variable v_unsigned_long=0" "" "set v_unsigned_long=0"
+
+send_gdb "print v_int && v_char\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of v_int&&v_char"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int&&v_char" }
+ timeout { fail "(timeout) print value of v_int&&v_char" }
+ }
+
+send_gdb "print v_int && v_short\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int&&v_short"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int&&v_short" }
+ timeout { fail "(timeout) print value of v_int&&v_short" }
+ }
+
+
+send_gdb "print v_int && v_signed_char\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int&&v_signed_char"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int&&v_signed_char" }
+ timeout { fail "(timeout) print value of v_int&&v_signed_char" }
+ }
+
+
+send_gdb "print v_int && v_unsigned_char\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int&&v_unsigned_char"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int&&v_unsigned_char" }
+ timeout { fail "(timeout) print value of v_int&&v_unsigned_char" }
+ }
+
+
+send_gdb "print v_int && v_signed_short\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int&&v_signed_short"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int&&v_signed_short" }
+ timeout { fail "(timeout) print value of v_int&&v_signed_short" }
+ }
+
+
+send_gdb "print v_int && v_unsigned_short\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int&&v_unsigned_short"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int&&v_unsigned_short" }
+ timeout { fail "(timeout) print value of v_int&&v_unsigned_short" }
+ }
+
+
+send_gdb "print v_int && v_signed_int\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int&&v_signed_int"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int&&v_signed_int" }
+ timeout { fail "(timeout) print value of v_int&&v_signed_int" }
+ }
+
+
+send_gdb "print v_int && v_unsigned_int\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int&&v_unsigned_int"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int&&v_unsigned_int" }
+ timeout { fail "(timeout) print value of v_int&&v_unsigned_int" }
+ }
+
+
+send_gdb "print v_int && v_long\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int&&v_long"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int&&v_long" }
+ timeout { fail "(timeout) print value of v_int&&v_long" }
+ }
+
+
+send_gdb "print v_int && v_signed_long\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int&&v_signed_long"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int&&v_signed_long" }
+ timeout { fail "(timeout) print value of v_int&&v_signed_long" }
+ }
+
+
+send_gdb "print v_int && v_unsigned_long\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of v_int&&v_unsigned_long"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int&&v_unsigned_long" }
+ timeout { fail "(timeout) print value of v_int&&v_unsigned_long" }
+ }
+
+
+send_gdb "print v_int && v_float\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of v_int&&v_float"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int&&v_float" }
+ timeout { fail "(timeout) print value of v_int&&v_float" }
+ }
+
+
+send_gdb "print v_int && v_double\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of v_int&&v_double"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of v_int&&v_double" }
+ timeout { fail "(timeout) print value of v_int&&v_double" }
+ }
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.base/all-types.c b/gdb/testsuite/gdb.base/all-types.c
new file mode 100644
index 00000000000..2f3a31f739b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/all-types.c
@@ -0,0 +1,62 @@
+/*
+ * the basic C types.
+ */
+
+#if !defined (__STDC__) && !defined (_AIX)
+#define signed /**/
+#endif
+
+char v_char;
+signed char v_signed_char;
+unsigned char v_unsigned_char;
+
+short v_short;
+signed short v_signed_short;
+unsigned short v_unsigned_short;
+
+int v_int;
+signed int v_signed_int;
+unsigned int v_unsigned_int;
+
+long v_long;
+signed long v_signed_long;
+unsigned long v_unsigned_long;
+
+float v_float;
+double v_double;
+
+int main ()
+{
+ extern void dummy();
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ dummy();
+ return 0;
+
+}
+
+void dummy()
+{
+ /* Some linkers (e.g. on AIX) remove unreferenced variables,
+ so make sure to reference them. */
+ v_char = 'A';
+ v_signed_char = 'B';
+ v_unsigned_char = 'C';
+
+ v_short = 3;
+ v_signed_short = 4;
+ v_unsigned_short = 5;
+
+ v_int = 6;
+ v_signed_int = 7;
+ v_unsigned_int = 8;
+
+ v_long = 9;
+ v_signed_long = 10;
+ v_unsigned_long = 11;
+
+ v_float = 100.343434;
+ v_double = 200.565656;
+}
diff --git a/gdb/testsuite/gdb.base/annota1.c b/gdb/testsuite/gdb.base/annota1.c
new file mode 100644
index 00000000000..6a13ee9d53d
--- /dev/null
+++ b/gdb/testsuite/gdb.base/annota1.c
@@ -0,0 +1,51 @@
+#include <stdio.h>
+#include <signal.h>
+
+#ifdef __sh__
+#define signal(a,b) /* Signals not supported on this target - make them go away */
+#endif
+
+
+#ifdef PROTOTYPES
+void
+handle_USR1 (int sig)
+{
+}
+#else
+void
+handle_USR1 (sig)
+ int sig;
+{
+}
+#endif
+
+int value;
+
+#ifdef PROTOTYPES
+int
+main (void)
+#else
+int
+main ()
+#endif
+{
+ int my_array[3] = { 1, 2, 3 };
+
+ value = 7;
+
+#ifdef SIGUSR1
+ signal (SIGUSR1, handle_USR1);
+#endif
+
+ printf ("value is %d\n", value);
+ printf ("my_array[2] is %d\n", my_array[2]);
+
+ {
+ int i;
+ for (i = 0; i < 5; i++)
+ value++;
+ }
+
+ return 0;
+}
+
diff --git a/gdb/testsuite/gdb.base/annota1.exp b/gdb/testsuite/gdb.base/annota1.exp
new file mode 100644
index 00000000000..bda2bec3975
--- /dev/null
+++ b/gdb/testsuite/gdb.base/annota1.exp
@@ -0,0 +1,463 @@
+# Copyright 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+
+# are we on a target board? If so, don't run these tests.
+# note: this is necessary because we cannot use runto_main (which would
+# work for remote targets too) because of the different prompt we get
+# when using annotation level 2.
+#
+if [is_remote target] then {
+ return 0
+}
+
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "annota1"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+
+#
+# the line at which break main will put the breakpoint
+#
+set main_line 32
+
+# The commands we test here produce many lines of output; disable "press
+# <return> to continue" prompts.
+send_gdb "set height 0\n"
+gdb_expect -re "$gdb_prompt $"
+
+#
+# break at main
+#
+gdb_test "break main" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "breakpoint main"
+
+
+#
+# NOTE: this prompt is OK only when the annotation level is > 1
+# NOTE: When this prompt is in use the gdb_test procedure cannot be used because
+# it assumes that the last char after the gdb_prompt is a white space. This is not
+# true with this annotated prompt. So we must use send_gdb and gdb_expect.
+#
+
+set old_gdb_prompt $gdb_prompt
+set gdb_prompt "\r\n\032\032pre-prompt\r\n$gdb_prompt \r\n\032\032prompt\r\n"
+
+
+
+#
+# set the annotation level to 2
+#
+# of course, this will test:
+# annotate-pre-prompt
+# annotate-prompt
+# annotate-post-prompt (in the next block)
+#
+send_gdb "set annotate 2\n"
+gdb_expect {
+ -re "set annotate 2\r\n$gdb_prompt$" { pass "annotation set at level 2" }
+ -re ".*$gdb_prompt$" { fail "annotation set at level 2" }
+ timeout { fail "annotation set at level 2 (timeout)" }
+ }
+
+
+#
+# info break will test:
+# annotate-breakpoints-headers
+# annotate-field
+# annotate-breakpoints-table
+# annotate-record
+# annotate-breakpoints-table-end
+#
+send_gdb "info break\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\n\r\n\032\032breakpoints-headers\r\n\r\n\032\032field 0\r\nNum \r\n\032\032field 1\r\nType \r\n\032\032field 2\r\nDisp \r\n\032\032field 3\r\nEnb \r\n\032\032field 4\r\nAddress +\r\n\032\032field 5\r\nWhat\r\n\r\n\032\032breakpoints-table\r\n\r\n\032\032record\r\n\r\n\032\032field 0\r\n1 \r\n\032\032field 1\r\nbreakpoint \r\n\032\032field 2\r\nkeep \r\n\032\032field 3\r\ny \r\n\032\032field 4\r\n$hex +\r\n\032\032field 5\r\nin main at ${srcdir}/${subdir}/${srcfile}:$main_line\r\n\r\n\032\032breakpoints-table-end\r\n$gdb_prompt$" \
+ {pass "breakpoint info"}
+ -re ".*$gdb_prompt$" { fail "breakpoint info" }
+ timeout { fail "breakpoint info (timeout)" }
+}
+
+
+#
+# run to a break point will test:
+# annotate-frames-invalid
+# annotate-breakpoints-invalid (a.k.a. breakpoints-changed)
+# annotate-starting
+# annotate-breakpoint
+# annotate-frame-begin
+# annotate-frame-function-name
+# annotate-frame-args
+# annotate-frame-source-begin
+# annotate-frame-source-file
+# annotate-frame-source-file-end
+# annotate-frame-source-line
+# annotate-frame-source-end
+# annotate-source
+# annotate-frame-end
+# annotate-stopped
+#
+#exp_internal 1
+send_gdb "run\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\nStarting program: $binfile \(\r\n\r\n\032\032frames-invalid\)+\(\(\r\n\r\n\032\032frames-invalid\)|\(\r\n\r\n\032\032breakpoints-invalid\)\)*\r\n\r\n\032\032starting\(\r\n\r\n\032\032frames-invalid\)+\(\(\r\n\r\n\032\032frames-invalid\)|\(\r\n\r\n\032\032breakpoints-invalid\)\)*\r\n\r\n\032\032breakpoint 1\r\n\r\nBreakpoint 1, \r\n\032\032frame-begin 0 $hex\r\n\r\n\032\032frame-function-name\r\nmain\r\n\032\032frame-args\r\n \\(\\)\r\n\032\032frame-source-begin\r\n at \r\n\032\032frame-source-file\r\n.*annota1.c\r\n\032\032frame-source-file-end\r\n:\r\n\032\032frame-source-line\r\n$main_line\r\n\032\032frame-source-end\r\n\r\n\r\n\032\032source.*$srcfile:$main_line:.*:beg:$hex\r\n\r\n\032\032frame-end\r\n\r\n\032\032stopped.*$gdb_prompt$" {
+ pass "run until main breakpoint"
+ }
+ -re ".*$gdb_prompt$" {
+ fail "run until main breakpoint"
+ }
+ timeout {
+ fail "run until main breakpoint (timeout)"
+ }
+ }
+#exp_internal 0
+#exit 0
+
+#
+# Let's do a next, to get to a point where the array is initialized
+# We don't care about the annotated output for this operation, it is the same as
+# the one produced by run above
+#
+send_gdb "next\n"
+gdb_expect {
+ -re ".*$gdb_prompt$" { pass "go after array init line" }
+ timeout { fail "go after array init line (timeout)" }
+}
+
+
+#
+# printing the array will test:
+# annotate-value-history-begin
+# annotate-value-history-value
+# annotate-array-section-begin
+# annotate-elt
+# FIXME: annotate-elt-rep and annotate-elt-rep-end not tested
+# annotate-array-section-end
+# annotate-value-history-end
+# FIXME: annotate-value-begin and annotate-value-end not tested (the gdb output
+# command would cause them to be used)
+#
+send_gdb "print my_array\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\n\r\n\032\032value-history-begin 1 -\r\n.*= \r\n\032\032value-history-value\r\n.\r\n\032\032array-section-begin 0 -\r\n1\r\n\032\032elt\r\n, 2\r\n\032\032elt\r\n, 3\r\n\032\032elt\r\n\r\n\032\032array-section-end\r\n.\r\n\r\n\032\032value-history-end\r\n$gdb_prompt$" \
+ { pass "print array" }
+ -re ".*$gdb_prompt$" { fail "print array" }
+ timeout { fail "print array (timeout)" }
+}
+
+
+#
+# this should generate an error message, so to test:
+# annotate-error-begin
+# FIXME: annotate-error not tested
+#
+
+#exp_internal 1
+send_gdb "print non_existent_value\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\n\r\n\032\032error-begin\r\nNo symbol \"non_existent_value\" in current context.\r\n\r\n\032\032error\r\n$gdb_prompt$" \
+ { pass "print non_existent_value" }
+ -re ".*$gdb_prompt$" { fail "print non_existent_value" }
+ timeout { fail "print non_existent_value (timeout)" }
+}
+
+
+#
+# break at signal handler. So that, once we are in the sig handler, if we do a bt
+# we can test annotate-signal-handler-caller
+#
+send_gdb "break handle_USR1\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\n\r\n\032\032breakpoints-invalid\r\nBreakpoint.*at $hex: file.*$srcfile, line.*\r\n$gdb_prompt$" \
+ { pass "breakpoint handle_USR1" }
+ -re ".*$gdb_prompt$" { fail "break at handle_USR1" }
+ timeout { fail "break at handle_USR1 (timeout)" }
+}
+
+#
+# break at printf. When we are stopped at printf, we can test
+#
+send_gdb "break printf\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\n\r\n\032\032breakpoints-invalid\r\nBreakpoint.*at $hex.*$gdb_prompt$" \
+ { pass "breakpoint printf" }
+ -re ".*$gdb_prompt$" { fail "break printf" }
+ timeout { fail "break printf (timeout)" }
+}
+
+#
+# get to printf
+#
+send_gdb "continue\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\nContinuing.\r\n\r\n\032\032starting\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032breakpoint 3\r\n\r\nBreakpoint 3, \r\n\032\032frame-begin 0 $hex\r\n\r\n(\032\032frame-address\r\n$hex\r\n\032\032frame-address-end\r\n in \r\n)*\032\032frame-function-name\r\nprintf\r\n\032\032frame-args\r\n.*\032\032frame-end\r\n\r\n\032\032stopped\r\n$gdb_prompt$" \
+ { pass "continue to printf" }
+ -re ".*$gdb_prompt$" { fail "continue to printf" }
+ timeout { fail "continue to printf (timeout)" }
+}
+
+#
+# test:
+# annotate-frame-where
+# annotate-frame-address
+# annotate-frame-address-end
+#
+send_gdb "backtrace\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\n\r\n\032\032frame-begin 0 $hex\r\n.0 \r\n(\032\032frame-address\r\n$hex\r\n\032\032frame-address-end\r\n in \r\n)*\032\032frame-function-name\r\nprintf\r\n\032\032frame-args\r\n \\(.*frame-end\r\n\r\n\032\032frame-begin 1 $hex\r\n.1 \r\n\032\032frame-address\r\n$hex\r\n\032\032frame-address-end\r\n in \r\n\032\032frame-function-name\r\nmain\r\n\032\032frame-args\r\n \\(\\)\r\n\032\032frame-source-begin\r\n at \r\n\032\032frame-source-file\r\n${srcdir}/${subdir}/${srcfile}\r\n\032\032frame-source-file-end\r\n:\r\n\032\032frame-source-line\r\n.*\r\n\032\032frame-source-end\r\n\r\n\r\n\032\032frame-end\r\n(\r\n\032\032frame-begin .*\r\n\r\n\032\032frame-end\r\n)*$gdb_prompt$" \
+ { pass "backtrace from shlibrary" }
+ -re ".*$gdb_prompt$" { fail "backtrace from shlibrary" }
+ timeout { fail "backtrace from shlibrary (timeout)" }
+}
+
+
+#
+# test printing a frame with some arguments:
+# annotate-arg-begin
+# annotate-arg-name-end
+# annotate-arg-value
+# annotate-arg-end
+#
+send_gdb "signal SIGUSR1\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\nContinuing with signal SIGUSR1.\r\n\r\n\032\032starting\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032breakpoint 2\r\n\r\nBreakpoint 2, \r\n\032\032frame-begin 0 $hex\r\n\r\n\032\032frame-function-name\r\nhandle_USR1\r\n\032\032frame-args\r\n \\(\r\n\032\032arg-begin\r\nsig\r\n\032\032arg-name-end\r\n=\r\n\032\032arg-value -\r\n$decimal\r\n\032\032arg-end\r\n\\)\r\n\032\032frame-source-begin\r\n at \r\n\032\032frame-source-file\r\n${srcdir}/${subdir}/${srcfile}\r\n\032\032frame-source-file-end\r\n:\r\n\032\032frame-source-line\r\n.*\r\n\032\032frame-source-end\r\n\r\n\r\n\032\032source.*annota1.c:.*:.*:beg:$hex\r\n\r\n\032\032frame-end\r\n\r\n\032\032stopped\r\n$gdb_prompt$" \
+ { pass "send SIGUSR1" }
+ -re ".*$gdb_prompt$" { fail "send SIGUSR1" }
+ timeout { fail "send SIGUSR1 (timeout)" }
+}
+
+
+#
+# test:
+# annotate-signal-handler-caller
+#
+verbose "match_max local is: [match_max]"
+verbose "match_max default is: [match_max -d]"
+# This is necessary because a 2000 buffer is not enought to get everything
+# up to the prompt ad the test gets a timeout.
+match_max 3000
+verbose "match_max now is: [match_max]"
+send_gdb "backtrace\n"
+gdb_expect {
+ -re "frame-begin 0 $hex\r\n#0.*frame-end.*frame-begin 1 $hex\r\n#1.*(\032\032signal-handler-caller\r\n.signal handler called.\r\n\r\n)*\032\032frame-end\r\n\r\n\032\032frame-begin 2 $hex\r\n#2.*(frame-begin 3 $hex\r\n#3.*)*frame-end.*$gdb_prompt$" {
+ pass "backtrace @ signal handler"
+ }
+ -re ".*$gdb_prompt$" { fail "backtrace @ signal handler" }
+ timeout { fail "backtrace @ signal handler (timeout)" }
+}
+
+#
+# delete all the breakpoints
+#
+send_gdb "delete 1\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\n$gdb_prompt$" \
+ { pass "delete bp 1" }
+ -re ".*$gdb_prompt$" { fail "delete bp 1" }
+ timeout { fail "delete bp 1 (timeout)" }
+}
+
+send_gdb "delete 2\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\n$gdb_prompt$" \
+ { pass "delete bp 2" }
+ -re ".*$gdb_prompt$" { fail "delete bp 2 " }
+ timeout { fail "delete bp 2 (timeout)" }
+}
+
+send_gdb "delete 3\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\n$gdb_prompt$" \
+ { pass "delete bp 3" }
+ -re ".*$gdb_prompt$" { fail "delete bp 3" }
+ timeout { fail "delete bp 3 (timeout)" }
+}
+
+#
+# break at main, after value is initialized. This is in preparation
+# to test the annotate output for the display command.
+#
+send_gdb "break main\n"
+gdb_expect {
+ -re "post-prompt.*\032\032breakpoints-invalid.*Breakpoint 4 at $hex: file ${srcdir}/${subdir}/${srcfile}, line $main_line.*$gdb_prompt$" \
+ { pass "break at 28" }
+ -re ".*$gdb_prompt$" { fail "break at 28" }
+ timeout { fail "break at 28 (timeout)" }
+}
+
+#
+# display the value; test:
+# annotate-display-begin
+# annotate-display-number-end
+# annotate-display-format
+# annotate-display-expression
+# annotate-display-expression-end
+# annotate-display-end
+# FIXME: annotate-display-value not tested
+#
+send_gdb "display value\n"
+gdb_expect {
+ -re "post-prompt\r\n\r\n\032\032display-begin\r\n1\r\n\032\032display-number-end\r\n: \r\n\032\032display-format\r\n\r\n\032\032display-expression\r\nvalue\r\n\032\032display-expression-end\r\n = \r\n\032\032display-expression\r\n7\r\n\r\n\032\032display-end\r\n$gdb_prompt$" \
+ { pass "set up display" }
+ -re ".*$gdb_prompt$" { fail "set up display" }
+ timeout { fail "set up display (timeout)" }
+}
+
+
+# should ask query. Test annotate-query.
+# we don't care about anything else here, only the query.
+
+send_gdb "run\n"
+gdb_expect {
+ -re "pre-query.*already.*\\(y or n\\).*query\r\n" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re ".*post-query.*$gdb_prompt$" \
+ { pass "re-run" }
+ -re ".*$gdb_prompt$" { fail "re-run" }
+ timeout { fail "re-run (timeout)" }
+ }
+ }
+ -re ".*$gdb_prompt$" { fail "re-run" }
+ timeout { fail "re-run (timeout)" }
+}
+
+#
+# Test that breakpoints-invalid is issued once and only once for
+# breakpoint ignore count changes, after annotation stopped.
+#
+send_gdb "break 46\n"
+gdb_expect {
+ -re "Breakpoint 5 at $hex: file .*$srcfile, line 46.*$gdb_prompt$" {
+ pass "break at 46"
+ }
+ -re ".*$gdb_prompt$" { fail "break at 46" }
+ timeout { fail "break at 46 (timeout)" }
+}
+
+send_gdb "ignore 5 4\n"
+gdb_expect {
+ -re "Will ignore next 4 crossings of breakpoint 5.*$gdb_prompt$" {
+ pass "ignore 5 4"
+ }
+ -re ".*$gdb_prompt$" { fail "ignore 5 4" }
+ timeout { fail "ignore 5 4 (timeout)" }
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re ".*$srcfile:46:.*\032\032stopped\r\n\r\n\032\032breakpoints-invalid\r\n$gdb_prompt$" {
+ pass "annotate ignore count change"
+ }
+ -re ".*$gdb_prompt$" { fail "annotate ignore count change" }
+ timeout { fail "annotate ignore count change (timeout)" }
+}
+
+# check that ignore command is working, or the above can provide
+# misleading assurance ...
+
+send_gdb "next\n"
+gdb_expect {
+ -re "$gdb_prompt$" {}
+ timeout { fail "next to exit loop" }
+}
+
+send_gdb "next\n"
+gdb_expect {
+ -re ".*$srcfile:49:.*$gdb_prompt$" {
+ pass "breakpoint ignore count"
+ }
+ -re ".*$gdb_prompt$" { fail "breakpoint ignore count" }
+ timeout { fail "breakpoint ignore count (timeout)" }
+}
+
+#
+# Send a signal that is not handled; test:
+# annotate-signalled
+# annotate-signal-name
+# annotate-signal-name-end
+# annotate-signal-string
+# annotate-signal-string-end
+# FIXME: annotate-signal not tested (requires that the inferior be
+# stopped by a "random" signal)
+#
+# SIGTRAP signals are dropped before they get to the inferior process
+# on hpux11. In theory, this behaivor can be controlled by setting
+# TTEO_NORM_SIGTRAP in the inferior, but doing so did not cause
+# the signal to be properly delivered.
+#
+# It has been verified that other signals will be delivered. However,
+# rather than twiddle the test, I choose to leave it as-is as it
+# exposes an interesting failure on hpux11.
+setup_xfail hppa*-*-hpux11*
+send_gdb "signal SIGTRAP\n"
+gdb_expect {
+ -re ".*\032\032post-prompt\r\nContinuing with signal SIGTRAP.\r\n\r\n\032\032starting\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032signalled\r\n\r\nProgram terminated with signal \r\n\032\032signal-name\r\nSIGTRAP\r\n\032\032signal-name-end\r\n, \r\n\032\032signal-string\r\nTrace.breakpoint trap\r\n\032\032signal-string-end\r\n.\r\nThe program no longer exists.\r\n\r\n\032\032stopped\r\n$gdb_prompt$" \
+ { pass "signal sent" }
+ -re ".*$gdb_prompt$" { fail "signal sent" }
+ timeout { fail "signal sent (timeout)" }
+}
+
+
+# Check for production of a core file
+# and remove it!
+
+set exec_output [remote_exec build "ls core"]
+
+if [ regexp "core not found" $exec_output] {
+ pass "No core dumped"
+} else {
+ if [ regexp "No such file or directory" $exec_output] {
+ pass "No core dumped"
+ } else {
+ remote_exec build "rm -f core"
+ pass "Core dumped and removed"
+ }
+}
+
+# restore the original prompt for the rest of the testsuite
+
+set gdb_prompt $old_gdb_prompt
diff --git a/gdb/testsuite/gdb.base/arithmet.exp b/gdb/testsuite/gdb.base/arithmet.exp
new file mode 100644
index 00000000000..6e7e6852530
--- /dev/null
+++ b/gdb/testsuite/gdb.base/arithmet.exp
@@ -0,0 +1,117 @@
+# Copyright 1998, 1999, 2001 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+# Rewritten to use gdb_test by Michael Chastain (chastain@redhat.com)
+
+# This file is part of the gdb testsuite
+#
+# tests for correctness of arithmetic operators, associativity and precedence
+# with integer type variables
+#
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "int-type"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+#
+# test expressions with "int" types
+#
+
+gdb_test "set variable x=14" ""
+gdb_test "set variable y=2" ""
+gdb_test "set variable z=2" ""
+gdb_test "set variable w=3" ""
+
+gdb_test "print x" "14"
+gdb_test "print y" "2"
+gdb_test "print z" "2"
+gdb_test "print w" "3"
+
+gdb_test "print x+y" "16"
+gdb_test "print x-y" "12"
+gdb_test "print x*y" "28"
+gdb_test "print x/y" "7"
+gdb_test "print x%y" "0"
+
+# x y z w
+# 14 2 2 3
+
+# Test associativity of +, -, *, % ,/
+
+gdb_test "print x+y+z" "18"
+gdb_test "print x-y-z" "10"
+gdb_test "print x*y*z" "56"
+gdb_test "print x/y/z" "3"
+gdb_test "print x%y%z" "0"
+
+# test precedence rules on pairs of arithmetic operators
+
+gdb_test "set variable x=10" ""
+gdb_test "set variable y=4" ""
+
+# x y z w
+# 10 4 2 3
+
+gdb_test "print x+y-z" "12"
+gdb_test "print x+y*z" "18"
+gdb_test "print x+y%w" "11"
+gdb_test "print x+y/w" "11"
+gdb_test "print x-y*z" "2"
+gdb_test "print x-y%z" "10"
+gdb_test "print x-y/z" "8"
+gdb_test "print x*y/z" "20"
+gdb_test "print x*y%w" "1"
+gdb_test "print x/y%w" "2"
+
+# test use of parentheses to enforce different order of evaluation
+
+gdb_test "print x-(y+w)" "3"
+gdb_test "print x/(y*w)" "0"
+gdb_test "print x-(y/w)" "9"
+gdb_test "print (x+y)*w" "42"
diff --git a/gdb/testsuite/gdb.base/assign.exp b/gdb/testsuite/gdb.base/assign.exp
new file mode 100644
index 00000000000..4bd15c38e05
--- /dev/null
+++ b/gdb/testsuite/gdb.base/assign.exp
@@ -0,0 +1,446 @@
+# Copyright 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+# This file is part of the gdb testsuite
+#
+# tests for all the assignemnt operators
+# with mixed types and with int type variables
+#
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "all-types"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+gdb_test "next" "return 0;" "continuing after dummy()"
+
+send_gdb "print v_int=57\n"
+gdb_expect {
+ -re ".*57.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*57.*$gdb_prompt $" {
+ pass "v_int=57"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int=57" }
+ timeout { fail "(timeout) v_int=57" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int=57" }
+ timeout { fail "(timeout) v_int=57" }
+ }
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+
+send_gdb "print v_int+=57\n"
+gdb_expect {
+ -re ".*63.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*63.*$gdb_prompt $" {
+ pass "v_int+=57"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=57" }
+ timeout { fail "(timeout) v_int+=57" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=57" }
+ timeout { fail "(timeout) v_int+=57" }
+ }
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+send_gdb "print v_int-=57\n"
+gdb_expect {
+ -re ".*-51.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*-51.*$gdb_prompt $" {
+ pass "v_int-=57"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int-=57" }
+ timeout { fail "(timeout) v_int-=57" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int-=57" }
+ timeout { fail "(timeout) v_int-=57" }
+ }
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+send_gdb "print v_int*=5\n"
+gdb_expect {
+ -re ".*30.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*30.*$gdb_prompt $" {
+ pass "v_int*=5"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int*=5" }
+ timeout { fail "(timeout) v_int*=5" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int*=5" }
+ timeout { fail "(timeout) v_int*=5" }
+ }
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+send_gdb "print v_int/=4\n"
+gdb_expect {
+ -re ".*1.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*1.*$gdb_prompt $" {
+ pass "v_int/=4"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int/=4" }
+ timeout { fail "(timeout) v_int/=4" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int/=4" }
+ timeout { fail "(timeout) v_int/=4" }
+ }
+
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+send_gdb "print v_int%=4\n"
+gdb_expect {
+ -re ".*2.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*2.*$gdb_prompt $" {
+ pass "v_int%=4"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int%=4" }
+ timeout { fail "(timeout) v_int%=4" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int%=4" }
+ timeout { fail "(timeout) v_int%=4" }
+ }
+
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+
+
+send_gdb "print v_int+=v_char\n"
+gdb_expect {
+ -re ".*71.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*71.*$gdb_prompt $" {
+ pass "v_int+=char"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_char" }
+ timeout { fail "(timeout) v_int+=v_char" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_char" }
+ timeout { fail "(timeout) v_int+=v_char" }
+ }
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+
+
+send_gdb "print v_int+=v_signed_char\n"
+gdb_expect {
+ -re ".*72.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*72.*$gdb_prompt $" {
+ pass "v_int+=signed_char"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_signed_char" }
+ timeout { fail "(timeout) v_int+=v_signed_char" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_signed_char" }
+ timeout { fail "(timeout) v_int+=v_signed_char" }
+ }
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+
+
+send_gdb "print v_int+=v_unsigned_char\n"
+gdb_expect {
+ -re ".*73.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*73.*$gdb_prompt $" {
+ pass "v_int+=unsigned_char"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_unsigned_char" }
+ timeout { fail "(timeout) v_int+=v_unsigned_char" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_unsigned_char" }
+ timeout { fail "(timeout) v_int+=v_unsigned_char" }
+ }
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+
+
+send_gdb "print v_int+=v_short\n"
+gdb_expect {
+ -re ".*9.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*9.*$gdb_prompt $" {
+ pass "v_int+=short"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_short" }
+ timeout { fail "(timeout) v_int+=v_short" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_short" }
+ timeout { fail "(timeout) v_int+=v_short" }
+ }
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+
+
+send_gdb "print v_int+=v_signed_short\n"
+gdb_expect {
+ -re ".*10.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*10.*$gdb_prompt $" {
+ pass "v_int+=signed_short"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_signed_short" }
+ timeout { fail "(timeout) v_int+=v_signed_short" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_signed_short" }
+ timeout { fail "(timeout) v_int+=v_signed_short" }
+ }
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+
+
+send_gdb "print v_int+=v_unsigned_short\n"
+gdb_expect {
+ -re ".*11.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*11.*$gdb_prompt $" {
+ pass "v_int=+unsigned_short"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_unsigned_short" }
+ timeout { fail "(timeout) v_int+=v_unsigned_short" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_unsigned_short" }
+ timeout { fail "(timeout) v_int+=v_unsigned_short" }
+ }
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+
+
+send_gdb "print v_int+=v_signed_int\n"
+gdb_expect {
+ -re ".*13.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*13.*$gdb_prompt $" {
+ pass "v_int+=signed_int"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_signed_int" }
+ timeout { fail "(timeout) v_int+=v_signed_int" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_signed_int" }
+ timeout { fail "(timeout) v_int+=v_signed_int" }
+ }
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+
+
+send_gdb "print v_int+=v_unsigned_int\n"
+gdb_expect {
+ -re ".*14.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*14.*$gdb_prompt $" {
+ pass "v_int+=unsigned_int"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_unsigned_int" }
+ timeout { fail "(timeout) v_int+=v_unsigned_int" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_unsigned_int" }
+ timeout { fail "(timeout) v_int+=v_unsigned_int" }
+ }
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+
+
+send_gdb "print v_int+=v_long\n"
+gdb_expect {
+ -re ".*15.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*15.*$gdb_prompt $" {
+ pass "v_int+=long"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_long" }
+ timeout { fail "(timeout) v_int+=v_long" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_long" }
+ timeout { fail "(timeout) v_int+=v_long" }
+ }
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+
+
+send_gdb "print v_int+=v_signed_long\n"
+gdb_expect {
+ -re ".*16.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*16.*$gdb_prompt $" {
+ pass "v_int+=signed_long"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_signed_long" }
+ timeout { fail "(timeout) v_int+=v_signed_long" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_signed_long" }
+ timeout { fail "(timeout) v_int+=v_signed_long" }
+ }
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+
+send_gdb "print v_int+=v_unsigned_long\n"
+gdb_expect {
+ -re ".*17.*$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*17.*$gdb_prompt $" {
+ pass "v_int+=unsigned_long"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_unsigned_long" }
+ timeout { fail "(timeout) v_int+=v_unsigned_long" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_unsigned_long" }
+ timeout { fail "(timeout) v_int+=v_unsigned_long" }
+ }
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+
+send_gdb "print v_int+=v_float\n"
+gdb_expect {
+ -re ".*106\r\n$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*106\r\n$gdb_prompt $" {
+ pass "v_int+=v_float"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_float" }
+ timeout { fail "(timeout) v_int+=v_float" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_float" }
+ timeout { fail "(timeout) v_int+=v_float" }
+ }
+
+
+gdb_test "set variable v_int = 6" "" "set v_int to 6"
+
+
+send_gdb "print v_int+=v_double\n"
+gdb_expect {
+ -re ".*206\r\n$gdb_prompt $" {
+ send_gdb "print v_int\n"
+ gdb_expect {
+ -re ".*206\r\n$gdb_prompt $" {
+ pass "v_int+=double"
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_double" }
+ timeout { fail "(timeout) v_int+=v_double" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "v_int+=v_signed_long" }
+ timeout { fail "(timeout) v_int+=v_double" }
+ }
+
+
diff --git a/gdb/testsuite/gdb.base/async.c b/gdb/testsuite/gdb.base/async.c
new file mode 100644
index 00000000000..0d9c8752b70
--- /dev/null
+++ b/gdb/testsuite/gdb.base/async.c
@@ -0,0 +1,48 @@
+
+
+#ifdef PROTOTYPES
+int
+foo (void)
+#else
+int
+foo ()
+#endif
+{
+ int x, y;
+
+ x = 5;
+ y = 3;
+
+ return x + y;
+}
+
+#ifdef PROTOTYPES
+int
+main (void)
+#else
+int
+main ()
+#endif
+{
+ int y, z;
+
+ y = 2;
+ z = 9;
+ y = foo ();
+ z = y;
+ y = y + 2;
+ y = baz ();
+ return 0;
+}
+
+
+#ifdef PROTOTYPES
+int
+baz (void)
+#else
+int
+baz ()
+#endif
+{
+ return 5;
+}
diff --git a/gdb/testsuite/gdb.base/async.exp b/gdb/testsuite/gdb.base/async.exp
new file mode 100644
index 00000000000..d135cfdb19d
--- /dev/null
+++ b/gdb/testsuite/gdb.base/async.exp
@@ -0,0 +1,153 @@
+# Copyright 1999
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "async"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+########################################
+##
+## Don't do any of these tests until we reach consensus on this file.
+##
+return 0
+########################################
+
+set board [target_info name]
+set current_target [target_info gdb_protocol]
+if { $current_target == "remote" } {
+ unset_board_info "gdb_protocol"
+ set_board_info "gdb_protocol" "async"
+ } else {
+ return 0
+ }
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+
+#
+# set it up at a breakpoint so we can play with it
+#
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+gdb_test "break baz" "" ""
+
+#
+# Make sure we get a 'completed' message when the target is done.
+#
+gdb_test "set display-exec-done on" "" ""
+
+
+send_gdb "next&\n"
+gdb_expect {
+ -re "^next&\r\n$gdb_prompt.*z = 9.*completed\.\r\n" { pass "next &" }
+ -re "$gdb_prompt.*completed\.$" { fail "next &" }
+ timeout { fail "(timeout) next &" }
+}
+
+send_gdb "step&\n"
+gdb_expect {
+ -re "^step&\r\n$gdb_prompt.*y = foo \\(\\).*completed\.\r\n" { pass "step &" }
+ -re "$gdb_prompt.*completed\.$" { fail "step &" }
+ timeout { fail "(timeout) step &" }
+}
+
+send_gdb "step&\n"
+gdb_expect {
+ -re "^step&\r\n$gdb_prompt foo \\(\\) at .*async.c.*x = 5.*completed\.\r\n" \
+ { pass "step &" }
+ -re "$gdb_prompt.*completed\.$" { fail "step &" }
+ timeout { fail "(timeout) step &" }
+}
+
+send_gdb "stepi&\n"
+gdb_expect {
+ -re "^stepi&\r\n$gdb_prompt.*$hex.*x = 5.*completed\.\r\n" { pass "stepi &" }
+ -re "$gdb_prompt.*completed\.$" { fail "stepi &" }
+ timeout { fail "(timeout) stepi &" }
+}
+
+send_gdb "nexti&\n"
+gdb_expect {
+ -re "^nexti&\r\n$gdb_prompt.*y = 3.*completed\.\r\n" { pass "nexti &" }
+ -re "$gdb_prompt.*completed\.$" { fail "nexti &" }
+ timeout { fail "(timeout) nexti &" }
+}
+
+send_gdb "finish&\n"
+gdb_expect {
+ -re "^finish&\r\nRun till exit from #0 foo \\(\\) at.*async.c.*\r\n$gdb_prompt.*$hex in main \\(\\) at.*async.c.*y = foo \\(\\).*Value returned is.*= 8.*completed\.\r\n" \
+ { pass "finish &" }
+ -re "$gdb_prompt.*completed\.$" { fail "finish &" }
+ timeout { fail "(timeout) finish &" }
+}
+
+send_gdb "jump 33&\n"
+gdb_expect {
+ -re "^jump 33&.*Continuing at $hex.*$gdb_prompt.*Breakpoint 2, baz \\(\\) at.*async.c.*return 5.*completed\.\r\n" \
+ { pass "jump &" }
+ -re ".*$gdb_prompt.*completed\.$" { fail "jump &" }
+ timeout { fail "(timeout) jump &" }
+}
+
+send_gdb "until 35&\n"
+gdb_expect {
+ -re "^until 35&.*$gdb_prompt.*$hex in main \\(\\) at.*async.c.*y = baz \\(\\).*completed\.\r\n" \
+ { pass "until &" }
+ -re "$gdb_prompt.*completed\.$" { fail "until &" }
+ timeout { fail "(timeout) until &" }
+}
+
+gdb_test "set display-exec-done off" "" ""
+
+unset_board_info "gdb_protocol"
+set_board_info "gdb_protocol" "remote"
+
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.base/attach.c b/gdb/testsuite/gdb.base/attach.c
new file mode 100644
index 00000000000..0041b4732d2
--- /dev/null
+++ b/gdb/testsuite/gdb.base/attach.c
@@ -0,0 +1,20 @@
+/* This program is intended to be started outside of gdb, and then
+ attached to by gdb. Thus, it simply spins in a loop. The loop
+ is exited when & if the variable 'should_exit' is non-zero. (It
+ is initialized to zero in this program, so the loop will never
+ exit unless/until gdb sets the variable to non-zero.)
+ */
+#include <stdio.h>
+
+int should_exit = 0;
+
+int main ()
+{
+ int local_i = 0;
+
+ while (! should_exit)
+ {
+ local_i++;
+ }
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/attach.exp b/gdb/testsuite/gdb.base/attach.exp
new file mode 100644
index 00000000000..2b341af009f
--- /dev/null
+++ b/gdb/testsuite/gdb.base/attach.exp
@@ -0,0 +1,432 @@
+# Copyright 1997, 1999, 2002 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+set prms_id 0
+set bug_id 0
+
+# On HP-UX 11.0, this test is causing a process running the program
+# "attach" to be left around spinning. Until we figure out why, I am
+# commenting out the test to avoid polluting tiamat (our 11.0 nightly
+# test machine) with these processes. RT
+#
+# Setting the magic bit in the target app should work. I added a
+# "kill", and also a test for the R3 register warning. JB
+if { [istarget "hppa*-*-hpux*"] } {
+ return 0
+}
+
+# are we on a target board
+if [is_remote target] then {
+ return 0
+}
+
+set testfile "attach"
+set srcfile ${testfile}.c
+set srcfile2 ${testfile}2.c
+set binfile ${objdir}/${subdir}/${testfile}
+set binfile2 ${objdir}/${subdir}/${testfile}2
+set cleanupfile ${objdir}/${subdir}/${testfile}.awk
+
+#execute_anywhere "rm -f ${binfile} ${binfile2}"
+remote_exec build "rm -f ${binfile} ${binfile2}"
+# For debugging this test
+#
+#log_user 1
+
+# Clean out any old files from past runs.
+#
+remote_exec build "${cleanupfile}"
+
+# build the first test case
+#
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Because we can't attach over nfs, copy binfile to /tmp/${binfile}.${pid}
+# and replace binfile with a symbolic link
+
+ set pid [pid]
+ exec /bin/cp -f ${binfile} /tmp/attach1.${pid}
+ exec rm -f ${binfile}
+ set binfile /tmp/attach1.${pid}
+# exec ln -s /tmp/attach1.${pid} ${binfile}
+
+# Build the in-system-call test
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Because we can't attach over nfs, copy binfile2 to /tmp/${binfile2}.${pid}
+# and replace binfile2 with a symbolic link
+
+ set pid [pid]
+ exec cp -f ${binfile2} /tmp/attach2.${pid}
+ exec rm -f ${binfile2}
+ set binfile2 /tmp/attach2.${pid}
+# exec ln -s /tmp/attach2.${pid} ${binfile2}
+
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+proc do_attach_tests {} {
+ global gdb_prompt
+ global binfile
+ global srcfile
+ global testfile
+ global objdir
+ global subdir
+ global timeout
+
+ # Start the program running and then wait for a bit, to be sure
+ # that it can be attached to.
+ #
+ set testpid [eval exec $binfile &]
+ exec sleep 2
+
+ # Verify that we cannot attach to nonsense.
+ #
+ send_gdb "attach abc\n"
+ gdb_expect {
+ -re ".*Illegal process-id: abc.*$gdb_prompt $"\
+ {pass "attach to nonsense is prohibited"}
+ -re "Attaching to.*$gdb_prompt $"\
+ {fail "attach to nonsense is prohibited (bogus pid allowed)"}
+ -re "$gdb_prompt $" {fail "attach to nonsense is prohibited"}
+ timeout {fail "(timeout) attach to nonsense is prohibited"}
+ }
+
+ # Verify that we cannot attach to what appears to be a valid
+ # process ID, but is a process that doesn't exist. (I don't
+ # believe any process is ever assigned #0, at least on HPUX.)
+ #
+ send_gdb "attach 0\n"
+ gdb_expect {
+ # This reponse is expected on HP-UX 10.20 (i.e., ptrace-based).
+ -re "Attaching to.*, process 0.*No such process.*$gdb_prompt $"\
+ {pass "attach to nonexistent process is prohibited"}
+ # This response is expected on HP-UX 11.0 (i.e., ttrace-based).
+ -re "Attaching to.*, process 0 failed.*Hint.*$gdb_prompt $"\
+ {pass "attach to nonexistent process is prohibited"}
+ -re "Attaching to.*, process 0.*denied.*$gdb_prompt $"\
+ {pass "attach to nonexistent process is prohibited"}
+ -re "$gdb_prompt $" {fail "attach to nonexistent process is prohibited"}
+ timeout {fail "(timeout) attach to nonexistent process is prohibited"}
+ }
+
+ # Verify that we can attach to the process by first giving its
+ # executable name via the file command, and using attach with
+ # the process ID.
+ #
+ # (Actually, the test system appears to do this automatically
+ # for us. So, we must also be prepared to be asked if we want
+ # to discard an existing set of symbols.)
+ #
+ send_gdb "file $binfile\n"
+ gdb_expect {
+ -re "Load new symbol table from.*y or n.*$" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "Reading symbols from $binfile\.\.\.*done.*$gdb_prompt $"\
+ {pass "(re)set file, before attach1"}
+ -re "$gdb_prompt $" {fail "(re)set file, before attach1"}
+ timeout {fail "(timeout) (re)set file, before attach1"}
+ }
+ }
+ -re "Reading symbols from $binfile\.\.\.*done.*$gdb_prompt $"\
+ {pass "set file, before attach1"}
+ -re "$gdb_prompt $" {fail "set file, before attach1"}
+ timeout {fail "(timeout) set file, before attach1"}
+ }
+
+ send_gdb "attach $testpid\n"
+ gdb_expect {
+ -re "Attaching to program.*$binfile, process $testpid.*main.*at .*$srcfile:.*$gdb_prompt $"\
+ {pass "attach1, after setting file"}
+ -re "$gdb_prompt $" {fail "attach1, after setting file"}
+ timeout {fail "(timeout) attach1, after setting file"}
+ }
+
+ # Verify that we can "see" the variable "should_exit" in the
+ # program, and that it is zero.
+ #
+ send_gdb "print should_exit\n"
+ gdb_expect {
+ -re ".* = 0.*$gdb_prompt $"\
+ {pass "after attach1, print should_exit"}
+ -re "$gdb_prompt $" {fail "after attach1, print should_exit"}
+ timeout {fail "(timeout) after attach1, print should_exit"}
+ }
+
+ # Detach the process.
+ #
+ send_gdb "detach\n"
+ gdb_expect {
+ -re "Detaching from program: .*$binfile.*$gdb_prompt $"\
+ {pass "attach1 detach"}
+ -re "$gdb_prompt $" {fail "attach1 detach"}
+ timeout {fail "(timeout) attach1 detach"}
+ }
+
+ # Wait a bit for gdb to finish detaching
+ #
+ exec sleep 5
+
+ # Purge the symbols from gdb's brain. (We want to be certain
+ # the next attach, which won't be preceded by a "file" command,
+ # is really getting the executable file without our help.)
+ #
+ set old_timeout $timeout
+ set timeout 15
+ send_gdb "file\n"
+ gdb_expect {
+ -re ".*gdb internal error.*$" {
+ fail "Internal error, prob. Memory corruption"
+ }
+ -re "No executable file now.*Discard symbol table.*y or n.*$" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "No symbol file now.*$gdb_prompt $"\
+ {pass "attach1, purging symbols after detach"}
+ -re "$gdb_prompt $" {fail "attach1, purging symbols after detach"}
+ timeout {fail "(timeout) attach1, purging symbols after detach"}
+ }
+ }
+ -re "$gdb_prompt $" {fail "attach1, purging file after detach"}
+ timeout {
+ fail "(timeout) attach1, purging file after detach"
+ }
+ }
+ set timeout $old_timeout
+
+ # Verify that we can attach to the process just by giving the
+ # process ID.
+ #
+ send_gdb "attach $testpid\n"
+ gdb_expect {
+ -re "Attaching to process $testpid.*Reading symbols from $binfile.*main.*at .*$gdb_prompt $"\
+ {pass "attach2"}
+ -re "$gdb_prompt $" {fail "attach2"}
+ timeout {fail "(timeout) attach2"}
+ }
+
+ # Verify that we can modify the variable "should_exit" in the
+ # program.
+ #
+ send_gdb "set should_exit=1\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "after attach2, set should_exit"}
+ timeout {fail "(timeout) after attach2, set should_exit"}
+ }
+
+ # Verify that the modification really happened.
+ #
+ send_gdb "tbreak 19\n"
+ gdb_expect {
+ -re "Breakpoint .*at.*$srcfile, line 19.*$gdb_prompt $"\
+ {pass "after attach2, set tbreak postloop"}
+ -re "$gdb_prompt $" {fail "after attach2, set tbreak postloop"}
+ timeout {fail "(timeout) after attach2, set tbreak postloop"}
+ }
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "main.*at.*$srcfile:19.*$gdb_prompt $"\
+ {pass "after attach2, reach tbreak postloop"}
+ -re "$gdb_prompt $" {fail "after attach2, reach tbreak postloop"}
+ timeout {fail "(timeout) after attach2, reach tbreak postloop"}
+ }
+
+ # Allow the test process to exit, to cleanup after ourselves.
+ #
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Program exited normally.*$gdb_prompt $"\
+ {pass "after attach2, exit"}
+ -re "$gdb_prompt $" {fail "after attach2, exit"}
+ timeout {fail "(timeout) after attach2, exit"}
+ }
+
+ # Make sure we don't leave a process around to confuse
+ # the next test run (and prevent the compile by keeping
+ # the text file busy), in case the "set should_exit" didn't
+ # work.
+ #
+ remote_exec build "kill -9 ${testpid}"
+ # Start the program running and then wait for a bit, to be sure
+ # that it can be attached to.
+ #
+ set testpid [eval exec $binfile &]
+ exec sleep 2
+
+ # Verify that we can attach to the process, and find its a.out
+ # when we're cd'd to some directory that doesn't contain the
+ # a.out. (We use the source path set by the "dir" command.)
+ #
+ send_gdb "dir ${objdir}/${subdir}\n"
+ gdb_expect {
+ -re ".*Source directories searched: .*$gdb_prompt $"\
+ {pass "set source path"}
+ -re "$gdb_prompt $" {fail "set source path"}
+ timeout {fail "(timeout) set source path"}
+ }
+
+ send_gdb "cd /tmp\n"
+ gdb_expect {
+ -re ".*Working directory /tmp.*$gdb_prompt $"\
+ {pass "cd away from process' a.out"}
+ -re "$gdb_prompt $" {fail "cd away from process' a.out"}
+ timeout {fail "(timeout) cd away from process' a.out"}
+ }
+
+ # Explicitly flush out any knowledge of the previous attachment.
+ send_gdb "symbol\n"
+ gdb_expect {
+ -re ".*Discard symbol table from.*y or n. $"\
+ {send_gdb "y\n"
+ gdb_expect {
+ -re ".*No symbol file now.*$gdb_prompt $"\
+ {pass "before attach3, flush symbols"}
+ -re "$gdb_prompt $" {fail "before attach3, flush symbols"}
+ timeout {fail "(timeout) before attach3, flush symbols"}
+ }
+ }
+ -re ".*No symbol file now.*$gdb_prompt $"\
+ {pass "before attach3, flush symbols"}
+ -re "$gdb_prompt $" {fail "before attach3, flush symbols"}
+ timeout {fail "(timeout) before attach3, flush symbols"}
+ }
+ send_gdb "exec\n"
+ gdb_expect {
+ -re ".*No executable file now.*$gdb_prompt $"\
+ {pass "before attach3, flush exec"}
+ -re "$gdb_prompt $" {fail "before attach3, flush exec"}
+ timeout {fail "(timeout) before attach3, flush exec"}
+ }
+
+ send_gdb "attach $testpid\n"
+ gdb_expect {
+ -re "Attaching to process $testpid.*Reading symbols from $binfile.*main.*at .*$gdb_prompt $"\
+ {pass "attach when process' a.out not in cwd"}
+ -re "$gdb_prompt $" {fail "attach when process' a.out not in cwd"}
+ timeout {fail "(timeout) attach when process' a.out not in cwd"}
+ }
+
+ send_gdb "kill\n"
+ gdb_expect {
+ -re ".*Kill the program being debugged.*y or n. $"\
+ {send_gdb "y\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "after attach3, exit"}
+ timeout {fail "(timeout) after attach3, exit"}
+ }
+ }
+ -re "$gdb_prompt $" {fail "after attach3, exit"}
+ timeout {fail "(timeout) after attach3, exit"}
+ }
+}
+
+proc do_call_attach_tests {} {
+ global gdb_prompt
+ global binfile2
+
+ # Start the program running and then wait for a bit, to be sure
+ # that it can be attached to.
+ #
+ set testpid [eval exec $binfile2 &]
+ exec sleep 2
+
+ # Attach
+ #
+ gdb_test "file $binfile2" ".*" "force switch to gdb64, if necessary"
+ send_gdb "attach $testpid\n"
+ gdb_expect {
+ -re ".*warning: reading register.*I.*O error.*$gdb_prompt $" {
+ fail "attach call, read register 3 error"
+ }
+ -re "Attaching to.*process $testpid.*libc.*$gdb_prompt $" {
+ pass "attach call"
+ }
+ -re "$gdb_prompt $" {fail "attach call"}
+ timeout {fail "(timeout) attach call"}
+ }
+
+ # See if other registers are problems
+ #
+ send_gdb "i r r3\n"
+ gdb_expect {
+ -re ".*warning: reading register.*$gdb_prompt $" {
+ pass "CHFts23490: known bug"
+ }
+ -re ".*r3.*$gdb_prompt $" {
+ pass "Bug fixed, Yayyy!"
+ }
+ timeout { fail "timeout on info reg" }
+ }
+
+ # Get rid of the process
+ #
+ gdb_test "p should_exit = 1" ".*"
+ gdb_test "c" ".*Program exited normally.*"
+
+ # Be paranoid
+ #
+ remote_exec build "kill -9 ${testpid}"
+
+}
+
+
+# Start with a fresh gdb
+#
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# This is a test of gdb's ability to attach to a running process.
+#
+do_attach_tests
+
+# Test attaching when the target is inside a system call
+#
+gdb_exit
+gdb_start
+
+# this seems not necessary. - guo
+#
+# # Since we have moved the executable to /tmp, it will be hard for gdb
+# # to find the object file/executable to read the symbols. This is
+# # a known limitation. We try and get the name of the executable the
+# # process is running from a variety of methods, but none is foolproof.
+# # Using "dir" will get us the symbols.
+#
+# gdb_test "dir ./gdb.base" ".*" "set up directory before attach"
+gdb_reinitialize_dir $srcdir/$subdir
+do_call_attach_tests
+
+# Cleanup the files placed in /tmp and the symlinks
+ remote_exec build "rm -f ${binfile} ${binfile2} /tmp/attach1.${pid} /tmp/attach2.${pid}"
+
+return 0
diff --git a/gdb/testsuite/gdb.base/attach2.c b/gdb/testsuite/gdb.base/attach2.c
new file mode 100644
index 00000000000..a78037ed387
--- /dev/null
+++ b/gdb/testsuite/gdb.base/attach2.c
@@ -0,0 +1,24 @@
+/* This program is intended to be started outside of gdb, and then
+ attached to by gdb. Thus, it simply spins in a loop. The loop
+ is exited when & if the variable 'should_exit' is non-zero. (It
+ is initialized to zero in this program, so the loop will never
+ exit unless/until gdb sets the variable to non-zero.)
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int should_exit = 0;
+
+int main ()
+{
+ int local_i = 0;
+
+ sleep( 10 ); /* System call causes register fetch to fail */
+ /* This is a known HPUX "feature" */
+ while (! should_exit)
+ {
+ local_i++;
+ }
+ return (0);
+}
diff --git a/gdb/testsuite/gdb.base/average.c b/gdb/testsuite/gdb.base/average.c
new file mode 100644
index 00000000000..e1695cea58c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/average.c
@@ -0,0 +1,46 @@
+/* This is a sample program for the HP WDB debugger. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef PROTOTYPES
+extern int sum(int *, int, int);
+#else
+extern int sum();
+#endif
+
+#define num 10
+
+static int my_list[num] = {3,4,2,0,2,1,8,3,6,7};
+
+#ifdef PROTOTYPES
+void print_average(int *list, int low, int high)
+#else
+void print_average(list, low, high)
+int *list, low, high;
+#endif
+ {
+ int total = 0, num_elements = 0, average = 0;
+ total = sum(list, low, high);
+ num_elements = high - low; /* note this is an off-by-one bug */
+
+ average = total / num_elements;
+ printf("%10.d\n", average);
+ }
+
+#ifdef PROTOTYPES
+int main(void)
+#else
+main ()
+#endif
+{
+ char c;
+ int first = 0, last = 0;
+ last = num-1;
+
+ /* Try two test cases. */
+ print_average (my_list, first, last);
+ print_average (my_list, first, last - 3);
+
+ exit(0);
+}
diff --git a/gdb/testsuite/gdb.base/bar.c b/gdb/testsuite/gdb.base/bar.c
new file mode 100644
index 00000000000..dd0bf923a3d
--- /dev/null
+++ b/gdb/testsuite/gdb.base/bar.c
@@ -0,0 +1,9 @@
+static int barx = 'b' + 'a' + 'r';
+
+int bar (int x)
+{
+ if (x)
+ return barx;
+ else
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/baz.c b/gdb/testsuite/gdb.base/baz.c
new file mode 100644
index 00000000000..8da4ffa47a1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/baz.c
@@ -0,0 +1,9 @@
+static int bazx = 'b' + 'a' + 'z';
+
+int baz (int x)
+{
+ if (x)
+ return bazx;
+ else
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/bitfields.c b/gdb/testsuite/gdb.base/bitfields.c
new file mode 100644
index 00000000000..bd411f7b647
--- /dev/null
+++ b/gdb/testsuite/gdb.base/bitfields.c
@@ -0,0 +1,194 @@
+/* Test program to test bit field operations */
+
+/* For non-ANSI compilers, use plain ints for the signed bit fields. However,
+ whether they actually end up signed or not is implementation defined, so
+ this may cause some tests to fail. But at least we can still compile
+ the test program and run the tests... */
+
+#if !defined(__STDC__) && !defined(__cplusplus)
+#define signed /**/
+#endif
+
+struct fields
+{
+ unsigned char uc ;
+ signed int s1 : 1;
+ unsigned int u1 : 1;
+ signed int s2 : 2;
+ unsigned int u2 : 2;
+ signed int s3 : 3;
+ unsigned int u3 : 3;
+ signed int s9 : 9;
+ unsigned int u9 : 9;
+ signed char sc ;
+} flags;
+
+void break1 ()
+{
+}
+
+void break2 ()
+{
+}
+
+void break3 ()
+{
+}
+
+void break4 ()
+{
+}
+
+void break5 ()
+{
+}
+
+void break6 ()
+{
+}
+
+void break7 ()
+{
+}
+
+void break8 ()
+{
+}
+
+void break9 ()
+{
+}
+
+void break10 ()
+{
+}
+
+/* This is used by bitfields.exp to determine if the target understands
+ signed bitfields. */
+int i;
+
+int main ()
+{
+ /* For each member, set that member to 1, allow gdb to verify that the
+ member (and only that member) is 1, and then reset it back to 0. */
+
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ flags.uc = 1;
+ break1 ();
+ flags.uc = 0;
+
+ flags.s1 = -1;
+ break1 ();
+ flags.s1 = 0;
+
+ flags.u1 = 1;
+ break1 ();
+ flags.u1 = 0;
+
+ flags.s2 = 1;
+ break1 ();
+ flags.s2 = 0;
+
+ flags.u2 = 1;
+ break1 ();
+ flags.u2 = 0;
+
+ flags.s3 = 1;
+ break1 ();
+ flags.s3 = 0;
+
+ flags.u3 = 1;
+ break1 ();
+ flags.u3 = 0;
+
+ flags.s9 = 1;
+ break1 ();
+ flags.s9 = 0;
+
+ flags.u9 = 1;
+ break1 ();
+ flags.u9 = 0;
+
+ flags.sc = 1;
+ break1 ();
+ flags.sc = 0;
+
+ /* Fill alternating fields with all 1's and verify that none of the bits
+ "bleed over" to the other fields. */
+
+ flags.uc = 0xFF;
+ flags.u1 = 0x1;
+ flags.u2 = 0x3;
+ flags.u3 = 0x7;
+ flags.u9 = 0x1FF;
+ break2 ();
+ flags.uc = 0;
+ flags.u1 = 0;
+ flags.u2 = 0;
+ flags.u3 = 0;
+ flags.u9 = 0;
+
+ flags.s1 = -1;
+ flags.s2 = -1;
+ flags.s3 = -1;
+ flags.s9 = -1;
+ flags.sc = 0xFF;
+ break2 ();
+ flags.s1 = 0;
+ flags.s2 = 0;
+ flags.s3 = 0;
+ flags.s9 = 0;
+ flags.sc = 0;
+
+ /* Fill the unsigned fields with the maximum positive value and verify
+ that the values are printed correctly. */
+
+ /* Maximum positive values */
+ flags.u1 = 0x1;
+ flags.u2 = 0x3;
+ flags.u3 = 0x7;
+ flags.u9 = 0x1FF;
+ break3 ();
+ flags.u1 = 0;
+ flags.u2 = 0;
+ flags.u3 = 0;
+ flags.u9 = 0;
+
+ /* Fill the signed fields with the maximum positive value, then the maximally
+ negative value, then -1, and verify in each case that the values are
+ printed correctly. */
+
+ /* Maximum positive values */
+ flags.s1 = 0x0;
+ flags.s2 = 0x1;
+ flags.s3 = 0x3;
+ flags.s9 = 0xFF;
+ break4 ();
+
+ /* Maximally negative values */
+ flags.s1 = -0x1;
+ flags.s2 = -0x2;
+ flags.s3 = -0x4;
+ flags.s9 = -0x100;
+ /* Extract bitfield value so that bitfield.exp can check if the target
+ understands signed bitfields. */
+ i = flags.s9;
+ break4 ();
+
+ /* -1 */
+ flags.s1 = -1;
+ flags.s2 = -1;
+ flags.s3 = -1;
+ flags.s9 = -1;
+ break4 ();
+
+ flags.s1 = 0;
+ flags.s2 = 0;
+ flags.s3 = 0;
+ flags.s9 = 0;
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/bitfields.exp b/gdb/testsuite/gdb.base/bitfields.exp
new file mode 100644
index 00000000000..148eec84cfc
--- /dev/null
+++ b/gdb/testsuite/gdb.base/bitfields.exp
@@ -0,0 +1,268 @@
+# Copyright 1992, 1994, 1995, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "bitfields"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+#
+# Test bitfield locating and uniqueness.
+# For each member, set that member to 1 and verify that the member (and only
+# that member) is 1, then reset it back to 0.
+#
+
+proc bitfield_uniqueness {} {
+ global decimal
+ global hex
+ global gdb_prompt
+ global srcfile
+
+ if { ! [runto break1] } {
+ gdb_suppress_tests;
+ }
+
+ if [gdb_test "print flags" ".*uc = 1 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 0.*"] {
+ gdb_suppress_tests;
+ }
+ if [gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #1"] {
+ gdb_suppress_tests;
+ }
+ # Note that we check for s1 as either 1 or -1, so that failure to
+ # treat it correctly as a signed 1bit field (values 0 or -1) while
+ # printing its value does not cause a spurious failure. We do the
+ # signedness preservation test later.
+ if [gdb_test "print flags" ".*uc = 0 .*, s1 = (1|-1), u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness (s1)"] {
+ gdb_suppress_tests;
+ }
+ if [gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #2"] {
+ gdb_suppress_tests;
+ }
+ if [gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 1, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness (u1)"] {
+ gdb_suppress_tests;
+ }
+ if [gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #3"] {
+ gdb_suppress_tests;
+ }
+ if [gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 1, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness (s2)"] {
+ gdb_suppress_tests;
+ }
+ if [gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #4"] {
+ gdb_suppress_tests;
+ }
+ if [gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 1, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness (u2)"] {
+ gdb_suppress_tests;
+ }
+ if [gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #5"] {
+ gdb_suppress_tests;
+ }
+ if [gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 1, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness (s3)"] {
+ gdb_suppress_tests;
+ }
+ if [gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #6"] {
+ gdb_suppress_tests;
+ }
+ if [gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 1, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness (u3)"] {
+ gdb_suppress_tests
+ }
+ if [gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #7"] {
+ gdb_suppress_tests
+ }
+ if [gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 1, u9 = 0, sc = 0.*" "bitfield uniqueness (s9)"] {
+ gdb_suppress_tests
+ }
+ if [gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #8"] {
+ gdb_suppress_tests
+ }
+ if [gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 1, sc = 0.*" "bitfield uniqueness (u9)"] {
+ gdb_suppress_tests
+ }
+ if [gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #9"] {
+ gdb_suppress_tests
+ }
+ if [gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 1.*" "bitfield uniqueness (sc)"] {
+ gdb_suppress_tests
+ }
+ # Hmmmm?
+ gdb_stop_suppressing_tests;
+}
+
+
+#
+# Test bitfield containment.
+# Fill alternating fields with all 1's and verify that none of the bits
+# "bleed over" to the other fields.
+#
+
+proc bitfield_containment {} {
+ global decimal
+ global hex
+ global gdb_prompt
+ global srcfile
+
+ delete_breakpoints
+
+ if { ![runto break2] } {
+ gdb_suppress_tests
+ }
+
+ if [gdb_test "print/x flags" "= {uc = 0xff, s1 = 0x0, u1 = 0x1, s2 = 0x0, u2 = 0x3, s3 = 0x0, u3 = 0x7, s9 = 0x0, u9 = 0x1ff, sc = 0x0}" "bitfield containment #1"] {
+ gdb_suppress_tests
+ }
+
+ if [gdb_test "cont" "Break.*break2 \\(\\) at .*$srcfile:$decimal.*" "continuing to break2"] {
+ gdb_suppress_tests
+ }
+
+ # If program is compiled with Sun CC, then these print out as their
+ # actual sizes; if compiled with gcc, they print out as 0xffffffff
+ # (which strikes me as bogus, but accept it at least for now).
+ if [gdb_test "print/x flags" "= {uc = 0x0, s1 = 0x(1|f*), u1 = 0x0, s2 = 0x(3|f*), u2 = 0x0, s3 = 0x(7|f*), u3 = 0x0, s9 = 0x(1ff|f*), u9 = 0x0, sc = 0xff}" "bitfield containment #2"] {
+ gdb_suppress_tests
+ }
+ gdb_stop_suppressing_tests;
+}
+
+# Test unsigned bitfields for unsignedness and range.
+# Fill the unsigned fields with the maximum positive value and verify that
+# the values are printed correctly.
+
+proc bitfield_unsignedness {} {
+ global decimal
+ global hex
+ global gdb_prompt
+ global srcfile
+
+ delete_breakpoints
+
+ if { ![runto break3] } {
+ gdb_suppress_tests
+ }
+
+ if [gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 1, s2 = 0, u2 = 3, s3 = 0, u3 = 7, s9 = 0, u9 = 511, sc = 0.*" "unsigned bitfield ranges"] {
+ gdb_suppress_tests
+ }
+ gdb_stop_suppressing_tests;
+}
+
+#
+# Test signed bitfields for signedness and range.
+# Fill the signed fields with the maximum positive value, then the maximally
+# negative value, then -1, and verify in each case that the values are
+# printed correctly.
+#
+
+proc bitfield_signedness {} {
+ global decimal
+ global hex
+ global gdb_prompt
+ global srcfile
+
+ delete_breakpoints
+
+ if { ! [runto break4] } {
+ gdb_suppress_tests
+ }
+
+ if [gdb_test "print flags" "= {uc = 0 .*, s1 = 0, u1 = 0, s2 = 1, u2 = 0, s3 = 3, u3 = 0, s9 = 255, u9 = 0, sc = 0 .*}" "signed bitfields, max positive values"] {
+ gdb_suppress_tests
+ }
+
+ if [gdb_test "cont" "Break.*break4 \\(\\) at .*$srcfile:$decimal.*" "continuing to break4 #1"] {
+ gdb_suppress_tests
+ }
+
+ # Determine if the target has signed bitfields so we can xfail the
+ # the signed bitfield tests if it doesn't.
+ send_gdb "print i\n"
+ gdb_expect {
+ -re ".* = -256.*$gdb_prompt $" {
+ pass "determining signed-ness of bitfields"
+ }
+ -re ".* = 256.*$gdb_prompt $" {
+ pass "determining signed-ness of bitfields"
+ setup_xfail "*-*-*"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "determining signed-ness of bitfields"
+ gdb_suppress_tests
+ }
+ default {
+ fail "determining signed-ness of bitfields" ;
+ gdb_suppress_tests;
+ }
+ }
+
+ if [gdb_test "print flags" ".*uc = 0 .*, s1 = -1, u1 = 0, s2 = -2, u2 = 0, s3 = -4, u3 = 0, s9 = -256, u9 = 0, sc = 0.*" "signed bitfields, max negative values"] {
+ gdb_suppress_tests
+ }
+
+ if [gdb_test "cont" "Break.*break4 \\(\\) at .*$srcfile:$decimal.*" "continuing to break4 #2"] {
+ gdb_suppress_tests
+ }
+
+ if [gdb_test "print flags" ".*uc = 0 .*, s1 = -1, u1 = 0, s2 = -1, u2 = 0, s3 = -1, u3 = 0, s9 = -1, u9 = 0, sc = 0.*" "signed bitfields with -1"] {
+ gdb_suppress_tests
+ }
+ # Hmmmm???
+ gdb_stop_suppressing_tests;
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+send_gdb "set print sevenbit-strings\n" ; gdb_expect -re "$gdb_prompt $"
+
+bitfield_uniqueness
+if [istarget "mips-idt-*"] then {
+ # Restart because IDT/SIM runs out of file descriptors.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+}
+bitfield_containment
+if [istarget "mips-idt-*"] then {
+ # Restart because IDT/SIM runs out of file descriptors.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+}
+bitfield_unsignedness
+if [istarget "mips-idt-*"] then {
+ # Restart because IDT/SIM runs out of file descriptors.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+}
+bitfield_signedness
diff --git a/gdb/testsuite/gdb.base/bitops.exp b/gdb/testsuite/gdb.base/bitops.exp
new file mode 100644
index 00000000000..607ab7787d8
--- /dev/null
+++ b/gdb/testsuite/gdb.base/bitops.exp
@@ -0,0 +1,365 @@
+# Copyright 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+# This file is part of the gdb testsuite
+#
+# tests expressions with bitwise operators, and some
+# logical operators
+# Does not use a target program
+#
+
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+
+send_gdb "print !1\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of !1"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !1" }
+ timeout { fail "(timeout) print value of !1" }
+ }
+
+
+send_gdb "print !0\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1.*$gdb_prompt $" {
+ pass "print value of !0"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !0" }
+ timeout { fail "(timeout) print value of !0" }
+ }
+
+
+send_gdb "print !100\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of !100"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !100" }
+ timeout { fail "(timeout) print value of !100" }
+ }
+
+
+send_gdb "print !1000\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of !1000"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !1000" }
+ timeout { fail "(timeout) print value of !1000" }
+ }
+
+
+send_gdb "print !10\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of !10"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !10" }
+ timeout { fail "(timeout) print value of !10" }
+ }
+
+
+send_gdb "print !2\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of !2 "
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !2" }
+ timeout { fail "(timeout) print value of !2" }
+ }
+
+
+send_gdb "print 10 | 5\n"
+gdb_expect {
+ -re ".\[0-9\]* = 15.*$gdb_prompt $" {
+ pass "print value of 10 | 5"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 10 | 5" }
+ timeout { fail "(timeout) print value of 10 | 5" }
+ }
+
+
+send_gdb "print 10 & 5\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of 10 & 5"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 10 & 5" }
+ timeout { fail "(timeout) print value of 10 & 5" }
+ }
+
+
+send_gdb "print 10 ^ 5\n"
+gdb_expect {
+ -re ".\[0-9\]* = 15.*$gdb_prompt $" {
+ pass "print value of 10 ^ 5"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 10 ^ 5" }
+ timeout { fail "(timeout) print value of 10 ^ 5" }
+ }
+
+
+send_gdb "print -!0\n"
+gdb_expect {
+ -re ".\[0-9\]* = -1.*$gdb_prompt $" {
+ pass "print value of -!0"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of -!0" }
+ timeout { fail "(timeout) print value of -!0" }
+ }
+
+
+send_gdb "print ~-!0\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of ~-!0"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of ~-!0" }
+ timeout { fail "(timeout) print value of ~-!0" }
+ }
+
+
+
+send_gdb "print 3 * 2 / 4.0 * 2.0\n"
+gdb_expect {
+ -re ".\[0-9\]* = 3.*$gdb_prompt $" {
+ pass "print value of 3 * 2 / 4.0 * 2.0"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 3 * 2 / 4.0 * 2.0" }
+ timeout { fail "(timeout) print value of 3 * 2 / 4.0 * 2.0" }
+ }
+
+
+send_gdb "print 8 << 2 >> 4\n"
+gdb_expect {
+ -re ".\[0-9\]* = 2.*$gdb_prompt $" {
+ pass "print value of 8 << 2 >> 4"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 8 << 2 >> 4" }
+ timeout { fail "(timeout) print value of 8 << 2 >> 4" }
+ }
+
+
+send_gdb "print -1 < 0 > 1\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of -1 < 0 > 1"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of -1 < 0 > 1" }
+ timeout { fail "(timeout) print value of -1 < 0 > 1" }
+ }
+
+
+send_gdb "print 15 ^ 10 ^ 5 ^ 7\n"
+gdb_expect {
+ -re ".\[0-9\]* = 7.*$gdb_prompt $" {
+ pass "print value of 15 ^ 10 ^ 5 ^ 7"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 15 ^ 10 ^ 5 ^ 7" }
+ timeout { fail "(timeout) print value of 15 ^ 10 ^ 5 ^ 7" }
+ }
+
+
+send_gdb "print 3.5 < 4.0\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1.*$gdb_prompt $" {
+ pass "print value of 3.5 < 4.0"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 3.5 < 4.0" }
+ timeout { fail "(timeout) print value of 3.5 < 4.0" }
+ }
+
+
+send_gdb "print 3.5 < -4.0\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of 3.5 < -4.0"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 3.5 < -4.0" }
+ timeout { fail "(timeout) print value of 3.5 < -4.0" }
+ }
+
+
+send_gdb "print 2 > -3\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1.*$gdb_prompt $" {
+ pass "print value of 2 > -3"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 2 > -3" }
+ timeout { fail "(timeout) print value of 2 > -3" }
+ }
+
+
+send_gdb "print -3>4\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of -3>4"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of -3>4" }
+ timeout { fail "(timeout) print value of -3>4" }
+ }
+
+
+send_gdb "print (-3 > 4)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of (-3 > 4)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (-3 > 4)" }
+ timeout { fail "(timeout) print value of (-3 > 4)" }
+ }
+
+
+send_gdb "print 3>=2.5\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1.*$gdb_prompt $" {
+ pass "print value of 3>=2.5"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 3>=2.5" }
+ timeout { fail "(timeout) print value of 3>=2.5" }
+ }
+
+
+send_gdb "print 3>=4.5\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of 3>=4.5"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 3>=4.5" }
+ timeout { fail "(timeout) print value of 3>=4.5" }
+ }
+
+
+send_gdb "print 3==3.0\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1.*$gdb_prompt $" {
+ pass "print value of 3==3.0"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 3==3.0" }
+ timeout { fail "(timeout) print value of 3==3.0" }
+ }
+
+
+send_gdb "print 3==4.0\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of 3==4.0"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 3==4.0" }
+ timeout { fail "(timeout) print value of 3==4.0" }
+ }
+
+
+send_gdb "print 3!=3.0\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of 3!=3.0"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 3!=3.0" }
+ timeout { fail "(timeout) print value of 3!=3.0" }
+ }
+
+
+send_gdb "print 3!=5.0\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1.*$gdb_prompt $" {
+ pass "print value of 3!=5.0"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 3!=5.0" }
+ timeout { fail "(timeout) print value of 3!=5.0" }
+ }
+
+
+send_gdb "print 0 || 1 && 0 | 0 ^ 0 == 8 > 128 >>1 +2 *2\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of 0 || 1 && 0 | 0 ^ 0 == 8 > 128 >>1 +2 *2"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 0 || 1 && 0 | 0 ^ 0 == 8 > 128 >>1 +2 *2" }
+ timeout { fail "(timeout) print value of 0 || 1 && 0 | 0 ^ 0 == 8 > 128 >>1 +2 *2" }
+ }
+
+
+send_gdb "print 1.0 || 0\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1.*$gdb_prompt $" {
+ pass "print value of 1.0 || 0"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 1.0 || 0" }
+ timeout { fail "(timeout) print value of 1.0 || 0" }
+ }
+
+
+send_gdb "print 0.0 || 1.0\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1.*$gdb_prompt $" {
+ pass "print value of 0.0 || 1.0"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 0.0 || 1.0" }
+ timeout { fail "(timeout) print value of 0.0 || 1.0" }
+ }
+
+
+send_gdb "print 0.0 || 0\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of 0.0 || 0"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 0.0 || 0" }
+ timeout { fail "(timeout) print value of 0.0 || 0" }
+ }
+
+
+send_gdb "print 0 || 1 && 0 | 0 ^ 0 == 8\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of 0 || 1 && 0 | 0 ^ 0 == 8"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 0 || 1 && 0 | 0 ^ 0 == 8" }
+ timeout { fail "(timeout) print value of 0 || 1 && 0 | 0 ^ 0 == 8" }
+ }
+
+
+send_gdb "print 0 == 8 > 128 >> 1 + 2 * 2\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of 0 == 8 > 128 >> 1 + 2 * 2"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of 0 == 8 > 128 >> 1 + 2 * 2" }
+ timeout { fail "(timeout) print value of 0 == 8 > 128 >> 1 + 2 * 2" }
+ }
+
diff --git a/gdb/testsuite/gdb.base/branches.c b/gdb/testsuite/gdb.base/branches.c
new file mode 100644
index 00000000000..df3b7c052be
--- /dev/null
+++ b/gdb/testsuite/gdb.base/branches.c
@@ -0,0 +1,113 @@
+/* Tests for single stepping through various branch conditions */
+
+int noscramble(int a)
+{
+ return a ;
+}
+
+int echo(int a)
+{ return noscramble(a) ; }
+
+int equaltest(int a,int b)
+{ int retval ;
+ if (a == b)
+ retval = noscramble(1) ;
+ else retval = noscramble(0) ;
+ return retval ;
+}
+
+int neqtest(int a , int b)
+{ int retval ;
+ if (a != b)
+ retval = echo(1) ;
+ else retval = echo(2) ;
+ return retval ;
+}
+int zerotest(int a )
+{ int retval ;
+ a = echo(a) ;
+ if (a ==0)
+ retval = echo(1) ;
+ else
+ retval = echo(0) ;
+ retval = echo(retval) ;
+ return retval ;
+}
+
+int zerotest2(int a)
+{
+ return (a==0) ;
+}
+
+int nonzerotest(int a)
+{
+ int retval ;
+ if (a != 0)
+ retval = echo(0) ;
+ else retval = echo(1) ;
+ return retval ;
+}
+
+int whiletest(int a)
+{
+ while (a > 0)
+ {
+ a-- ;
+ }
+ return 0 ;
+}
+int whiletest2(int a)
+{
+ while (a > 0)
+ {
+ a = noscramble(a) ;
+ a-- ;
+ }
+ return a ;
+}
+
+int decr(int x) { return x - 1 ; }
+
+int while3(int a)
+{
+ int b = a ;
+ while (a == b)
+ {
+ a = echo(a) ;
+ b = decr(b) ;
+ }
+ return a ;
+}
+
+void done (int x) { }
+
+int main()
+{
+ int a,b,c,d ;
+ done(1) ;
+ a = echo(123456) ;
+ b = echo(123456) ;
+ c = echo(56789) ;
+ d = echo(0) ;
+#if 1
+ equaltest(a,b) ;
+ done(7) ;
+ equaltest(a,c) ;
+ done(8) ;
+ whiletest(3) ; /* worked */
+ done(3) ;
+ while3(3) ;
+ done(6) ;
+#endif
+ neqtest(a,b) ;
+ neqtest(a,b) ;
+ neqtest(a,c) ;
+ zerotest(d) ;
+ zerotest(a) ;
+ done(5) ;
+ nonzerotest(d) ;
+ done(4) ;
+ nonzerotest(a) ;
+ done(111) ;
+ return 1 ;
+}
diff --git a/gdb/testsuite/gdb.base/break.c b/gdb/testsuite/gdb.base/break.c
new file mode 100644
index 00000000000..9e458b316bb
--- /dev/null
+++ b/gdb/testsuite/gdb.base/break.c
@@ -0,0 +1,131 @@
+#ifdef vxworks
+
+# include <stdio.h>
+
+/* VxWorks does not supply atoi. */
+static int
+atoi (z)
+ char *z;
+{
+ int i = 0;
+
+ while (*z >= '0' && *z <= '9')
+ i = i * 10 + (*z++ - '0');
+ return i;
+}
+
+/* I don't know of any way to pass an array to VxWorks. This function
+ can be called directly from gdb. */
+
+vxmain (arg)
+char *arg;
+{
+ char *argv[2];
+
+ argv[0] = "";
+ argv[1] = arg;
+ main (2, argv, (char **) 0);
+}
+
+#else /* ! vxworks */
+# include <stdio.h>
+# include <stdlib.h>
+#endif /* ! vxworks */
+
+/*
+ * The following functions do nothing useful. They are included simply
+ * as places to try setting breakpoints at. They are explicitly
+ * "one-line functions" to verify that this case works (some versions
+ * of gcc have or have had problems with this).
+ */
+
+#ifdef PROTOTYPES
+int marker1 (void) { return (0); }
+int marker2 (int a) { return (1); }
+void marker3 (char *a, char *b) {}
+void marker4 (long d) {}
+#else
+int marker1 () { return (0); }
+int marker2 (a) int a; { return (1); }
+void marker3 (a, b) char *a, *b; {}
+void marker4 (d) long d; {}
+#endif
+
+/*
+ * This simple classical example of recursion is useful for
+ * testing stack backtraces and such.
+ */
+
+#ifdef PROTOTYPES
+int factorial(int);
+
+int
+main (int argc, char **argv, char **envp)
+#else
+int
+main (argc, argv, envp)
+int argc;
+char *argv[], **envp;
+#endif
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ if (argc == 12345) { /* an unlikely value < 2^16, in case uninited */
+ fprintf (stderr, "usage: factorial <number>\n");
+ return 1;
+ }
+ printf ("%d\n", factorial (atoi ("6")));
+
+ marker1 ();
+ marker2 (43);
+ marker3 ("stack", "trace");
+ marker4 (177601976L);
+ argc = (argc == 12345); /* This is silly, but we can step off of it */
+ return argc;
+}
+
+#ifdef PROTOTYPES
+int factorial (int value)
+#else
+int factorial (value)
+int value;
+#endif
+{
+ if (value > 1) {
+ value *= factorial (value - 1);
+ }
+ return (value);
+}
+
+#ifdef PROTOTYPES
+int multi_line_if_conditional (int a, int b, int c)
+#else
+int multi_line_if_conditional (a, b, c)
+ int a, b, c;
+#endif
+{
+ if (a
+ && b
+ && c)
+ return 0;
+ else
+ return 1;
+}
+
+#ifdef PROTOTYPES
+int multi_line_while_conditional (int a, int b, int c)
+#else
+int multi_line_while_conditional (a, b, c)
+ int a, b, c;
+#endif
+{
+ while (a
+ && b
+ && c)
+ {
+ a--, b--, c--;
+ }
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/break.exp b/gdb/testsuite/gdb.base/break.exp
new file mode 100644
index 00000000000..e3aa922bc50
--- /dev/null
+++ b/gdb/testsuite/gdb.base/break.exp
@@ -0,0 +1,949 @@
+# Copyright 1988, 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2002
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "break"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+#
+# test simple breakpoint setting commands
+#
+
+# Test deleting all breakpoints when there are none installed,
+# GDB should not prompt for confirmation.
+# Note that gdb-init.exp provides a "delete_breakpoints" proc
+# for general use elsewhere.
+
+send_gdb "delete breakpoints\n"
+gdb_expect {
+ -re "Delete all breakpoints.*$" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {
+ fail "Delete all breakpoints when none (unexpected prompt)"
+ }
+ timeout { fail "Delete all breakpoints when none (timeout after unexpected prompt)" }
+ }
+ }
+ -re ".*$gdb_prompt $" { pass "Delete all breakpoints when none" }
+ timeout { fail "Delete all breakpoints when none (timeout)" }
+}
+
+#
+# test break at function
+#
+gdb_test "break main" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "breakpoint function"
+
+#
+# test break at quoted function
+#
+gdb_test "break \"marker2\"" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "breakpoint quoted function"
+
+#
+# test break at function in file
+#
+gdb_test "break $srcfile:factorial" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "breakpoint function in file"
+
+#
+# test break at line number
+#
+# Note that the default source file is the last one whose source text
+# was printed. For native debugging, before we've executed the
+# program, this is the file containing main, but for remote debugging,
+# it's wherever the processor was stopped when we connected to the
+# board. So, to be sure, we do a list command.
+#
+gdb_test "list main" \
+ ".*main \\(argc, argv, envp\\).*" \
+ "use `list' to establish default source file"
+gdb_test "break 79" \
+ "Breakpoint.*at.* file .*$srcfile, line 79\\." \
+ "breakpoint line number"
+
+#
+# test duplicate breakpoint
+#
+gdb_test "break 79" \
+ "Note: breakpoint \[0-9\]+ also set at pc.*Breakpoint \[0-9\]+ at.* file .*$srcfile, line 79\\." \
+ "breakpoint duplicate"
+
+#
+# test break at line number in file
+#
+gdb_test "break $srcfile:85" \
+ "Breakpoint.*at.* file .*$srcfile, line 85\\." \
+ "breakpoint line number in file"
+
+
+#
+# Test putting a break at the start of a multi-line if conditional.
+# Verify the breakpoint was put at the start of the conditional.
+#
+gdb_test "break multi_line_if_conditional" \
+ "Breakpoint.*at.* file .*$srcfile, line 109\\." \
+ "breakpoint at start of multi line if conditional"
+
+gdb_test "break multi_line_while_conditional" \
+ "Breakpoint.*at.* file .*$srcfile, line 124\\." \
+ "breakpoint at start of multi line while conditional"
+
+#
+# check to see what breakpoints are set
+#
+if [target_info exists gdb_stub] {
+ set main_line 72
+} else {
+ set main_line 75
+}
+
+if {$hp_aCC_compiler} {
+ set proto "\\(int\\)"
+} else {
+ set proto ""
+}
+gdb_test "info break" \
+ "Num Type\[ \]+Disp Enb Address\[ \]+What.*
+\[0-9\]+\[\t \]+breakpoint keep y.* in main at .*$srcfile:$main_line.*
+\[0-9\]+\[\t \]+breakpoint keep y.* in marker2 at .*$srcfile:4\[49\].*
+\[0-9\]+\[\t \]+breakpoint keep y.* in factorial$proto at .*$srcfile:96.*
+\[0-9\]+\[\t \]+breakpoint keep y.* in main at .*$srcfile:79.*
+\[0-9\]+\[\t \]+breakpoint keep y.* in main at .*$srcfile:79.*
+\[0-9\]+\[\t \]+breakpoint keep y.* in main at .*$srcfile:85.*
+\[0-9\]+\[\t \]+breakpoint keep y.* in multi_line_if_conditional at .*$srcfile:109.*
+\[0-9\]+\[\t \]+breakpoint keep y.* in multi_line_while_conditional at .*$srcfile:124" \
+ "breakpoint info"
+
+
+# FIXME: The rest of this test doesn't work with anything that can't
+# handle arguments.
+# Huh? There doesn't *appear* to be anything that passes arguments
+# below.
+if [istarget "mips-idt-*"] then {
+ return
+}
+
+#
+# run until the breakpoint at main is hit. For non-stubs-using targets.
+#
+if ![target_info exists use_gdb_stub] {
+ if [istarget "*-*-vxworks*"] then {
+ send_gdb "run vxmain \"2\"\n"
+ set timeout 120
+ verbose "Timeout is now $timeout seconds" 2
+ } else {
+ send_gdb "run\n"
+ }
+ gdb_expect {
+ -re "The program .* has been started already.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "Starting program.*Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:75.*75\[\t \]+if .argc.* \{.*$gdb_prompt $"\
+ { pass "run until function breakpoint" }
+ -re ".*$gdb_prompt $" { fail "run until function breakpoint" }
+ timeout { fail "run until function breakpoint (timeout)" }
+ }
+} else {
+ if ![target_info exists gdb_stub] {
+ gdb_test continue ".*Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:75.*75\[\t \]+if .argc.*\{.*" "stub continue"
+ }
+}
+
+#
+# run until the breakpoint at a line number
+#
+gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:79.*79\[\t \]+printf.*factorial.*" \
+ "run until breakpoint set at a line number"
+
+#
+# Run until the breakpoint set in a function in a file
+#
+for {set i 6} {$i >= 1} {incr i -1} {
+ gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, factorial \\(value=$i\\) at .*$srcfile:96.*96\[\t \]+.*if .value > 1. \{.*" \
+ "run until file:function($i) breakpoint"
+}
+
+#
+# Run until the breakpoint set at a quoted function
+#
+gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, (0x\[0-9a-f\]+ in )?marker2 \\(a=43\\) at .*$srcfile:4\[49\].*" \
+ "run until quoted breakpoint"
+#
+# run until the file:function breakpoint at a line number in a file
+#
+gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:85.*85\[\t \]+argc = \\(argc == 12345\\);.*" \
+ "run until file:linenum breakpoint"
+
+# Test break at offset +1
+
+gdb_test "break +1" \
+ "Breakpoint.*at.* file .*$srcfile, line 86\\." \
+ "breakpoint offset +1"
+
+# Check to see if breakpoint is hit when stepped onto
+
+gdb_test "step" \
+ ".*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:86.*86\[\t \]+return argc;" \
+ "step onto breakpoint"
+
+#
+# delete all breakpoints so we can start over, course this can be a test too
+#
+delete_breakpoints
+
+#
+# test temporary breakpoint at function
+#
+
+gdb_test "tbreak main" "Breakpoint.*at.* file .*$srcfile, line.*" "Temporary breakpoint function"
+
+#
+# test break at function in file
+#
+
+gdb_test "tbreak $srcfile:factorial" "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "Temporary breakpoint function in file"
+
+#
+# test break at line number
+#
+send_gdb "tbreak 79\n"
+gdb_expect {
+ -re "Breakpoint.*at.* file .*$srcfile, line 79.*$gdb_prompt $" { pass "Temporary breakpoint line number #1" }
+ -re ".*$gdb_prompt $" { pass "Temporary breakpoint line number #1" }
+ timeout { fail "breakpoint line number #1 (timeout)" }
+}
+
+gdb_test "tbreak 75" "Breakpoint.*at.* file .*$srcfile, line 75.*" "Temporary breakpoint line number #2"
+
+#
+# test break at line number in file
+#
+send_gdb "tbreak $srcfile:85\n"
+gdb_expect {
+ -re "Breakpoint.*at.* file .*$srcfile, line 85.*$gdb_prompt $" { pass "Temporary breakpoint line number in file #1" }
+ -re ".*$gdb_prompt $" { pass "Temporary breakpoint line number in file #1" }
+ timeout { fail "Temporary breakpoint line number in file #1 (timeout)" }
+}
+
+gdb_test "tbreak $srcfile:81" "Breakpoint.*at.* file .*$srcfile, line 81.*" "Temporary breakpoint line number in file #2"
+
+#
+# check to see what breakpoints are set (temporary this time)
+#
+gdb_test "info break" "Num Type.*Disp Enb Address.*What.*\[\r\n\]
+\[0-9\]+\[\t \]+breakpoint del.*y.*in main at .*$srcfile:$main_line.*\[\r\n\]
+\[0-9\]+\[\t \]+breakpoint del.*y.*in factorial$proto at .*$srcfile:96.*\[\r\n\]
+\[0-9\]+\[\t \]+breakpoint del.*y.*in main at .*$srcfile:79.*\[\r\n\]
+\[0-9\]+\[\t \]+breakpoint del.*y.*in main at .*$srcfile:75.*\[\r\n\]
+\[0-9\]+\[\t \]+breakpoint del.*y.*in main at .*$srcfile:85.*\[\r\n\]
+\[0-9\]+\[\t \]+breakpoint del.*y.*in main at .*$srcfile:81.*" \
+ "Temporary breakpoint info"
+
+
+#***********
+
+# Verify that catchpoints for fork, vfork and exec don't trigger
+# inappropriately. (There are no calls to those system functions
+# in this test program.)
+#
+if ![runto_main] then { fail "break tests suppressed" }
+
+send_gdb "catch\n"
+gdb_expect {
+ -re "Catch requires an event name.*$gdb_prompt $"\
+ {pass "catch requires an event name"}
+ -re "$gdb_prompt $"\
+ {fail "catch requires an event name"}
+ timeout {fail "(timeout) catch requires an event name"}
+}
+
+
+set name "set catch fork, never expected to trigger"
+send_gdb "catch fork\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\]* .fork..*$gdb_prompt $"
+ {pass $name}
+ -re "Catch of fork not yet implemented.*$gdb_prompt $"
+ {pass $name}
+ -re "$gdb_prompt $"
+ {fail $name}
+ timeout {fail "(timeout) $name"}
+}
+
+
+set name "set catch vfork, never expected to trigger"
+send_gdb "catch vfork\n"
+
+# If we are on HP-UX 10.20, we expect an error message to be
+# printed if we type "catch vfork" at the gdb gdb_prompt. This is
+# because on HP-UX 10.20, we cannot catch vfork events.
+
+if [istarget "hppa*-hp-hpux10.20"] then {
+ gdb_expect {
+ -re "Catch of vfork events not supported on HP-UX 10.20..*$gdb_prompt $"
+ {pass $name}
+ -re "$gdb_prompt $"
+ {fail $name}
+ timeout {fail "(timeout) $name"}
+ }
+} else {
+ gdb_expect {
+ -re "Catchpoint \[0-9\]* .vfork..*$gdb_prompt $"
+ {pass $name}
+ -re "Catch of vfork not yet implemented.*$gdb_prompt $"
+ {pass $name}
+ -re "$gdb_prompt $"
+ {fail $name}
+ timeout {fail "(timeout) $name"}
+ }
+}
+
+set name "set catch exec, never expected to trigger"
+send_gdb "catch exec\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\]* .exec..*$gdb_prompt $"
+ {pass $name}
+ -re "Catch of exec not yet implemented.*$gdb_prompt $"
+ {pass $name}
+ -re "$gdb_prompt $" {fail $name}
+ timeout {fail "(timeout) $name"}
+}
+
+# Verify that "until <location>" works. (This is really just syntactic
+# sugar for "tbreak <location>; continue".)
+#
+send_gdb "until 79\n"
+gdb_expect {
+ -re "main .* at .*:79.*$gdb_prompt $"\
+ {pass "until 79"}
+ -re "$gdb_prompt $"\
+ {fail "until 79"}
+ timeout {fail "(timeout) until 79"}
+}
+
+# Verify that a malformed "until" is gracefully caught.
+#
+send_gdb "until 80 then stop\n"
+gdb_expect {
+ -re "Junk at end of arguments..*$gdb_prompt $"\
+ {pass "malformed until"}
+ -re "$gdb_prompt $"\
+ {fail "malformed until"}
+ timeout {fail "(timeout) malformed until"}
+}
+
+# Verify that GDB responds gracefully when asked to set a breakpoint
+# on a nonexistent source line.
+#
+send_gdb "break 999\n"
+gdb_expect {
+ -re "No line 999 in file .*$gdb_prompt $"\
+ {pass "break on non-existent source line"}
+ -re "$gdb_prompt $"\
+ {fail "break on non-existent source line"}
+ timeout {fail "(timeout) break on non-existent source line"}
+}
+
+# Verify that GDB allows one to just say "break", which is treated
+# as the "default" breakpoint. Note that GDB gets cute when printing
+# the informational message about other breakpoints at the same
+# location. We'll hit that bird with this stone too.
+#
+send_gdb "break\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]*.*$gdb_prompt $"\
+ {pass "break on default location, 1st time"}
+ -re "$gdb_prompt $"\
+ {fail "break on default location, 1st time"}
+ timeout {fail "(timeout) break on default location, 1st time"}
+}
+
+send_gdb "break\n"
+gdb_expect {
+ -re "Note: breakpoint \[0-9\]* also set at .*Breakpoint \[0-9\]*.*$gdb_prompt $"\
+ {pass "break on default location, 2nd time"}
+ -re "$gdb_prompt $"\
+ {fail "break on default location, 2nd time"}
+ timeout {fail "(timeout) break on default location, 2nd time"}
+}
+
+send_gdb "break\n"
+gdb_expect {
+ -re "Note: breakpoints \[0-9\]* and \[0-9\]* also set at .*Breakpoint \[0-9\]*.*$gdb_prompt $"\
+ {pass "break on default location, 3rd time"}
+ -re "$gdb_prompt $"\
+ {fail "break on default location, 3rd time"}
+ timeout {fail "(timeout) break on default location, 3rd time"}
+}
+
+send_gdb "break\n"
+gdb_expect {
+ -re "Note: breakpoints \[0-9\]*, \[0-9\]* and \[0-9\]* also set at .*Breakpoint \[0-9\]*.*$gdb_prompt $"\
+ {pass "break on default location, 4th time"}
+ -re "$gdb_prompt $"\
+ {fail "break on default location, 4th time"}
+ timeout {fail "(timeout) break on default location, 4th time"}
+}
+
+# Verify that a "silent" breakpoint can be set, and that GDB is indeed
+# "silent" about its triggering.
+#
+if ![runto_main] then { fail "break tests suppressed" }
+
+send_gdb "break 79\n"
+gdb_expect {
+ -re "Breakpoint (\[0-9\]*) at .*, line 79.*$gdb_prompt $"\
+ {pass "set to-be-silent break 79"}
+ -re "$gdb_prompt $"\
+ {fail "set to-be-silent break 79"}
+ timeout {fail "(timeout) set to-be-silent break 79"}
+}
+
+send_gdb "commands $expect_out(1,string)\n"
+send_gdb "silent\n"
+send_gdb "end\n"
+gdb_expect {
+ -re ".*$gdb_prompt $"\
+ {pass "set silent break 79"}
+ timeout {fail "(timeout) set silent break 79"}
+}
+
+send_gdb "info break $expect_out(1,string)\n"
+gdb_expect {
+ -re "\[0-9\]*\[ \t\]*breakpoint.*:79\r\n\[ \t\]*silent.*$gdb_prompt $"\
+ {pass "info silent break 79"}
+ -re "$gdb_prompt $"\
+ {fail "info silent break 79"}
+ timeout {fail "(timeout) info silent break 79"}
+}
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing.\r\n$gdb_prompt $"\
+ {pass "hit silent break 79"}
+ -re "$gdb_prompt $"\
+ {fail "hit silent break 79"}
+ timeout {fail "(timeout) hit silent break 79"}
+}
+send_gdb "bt\n"
+gdb_expect {
+ -re "#0 main .* at .*:79.*$gdb_prompt $"\
+ {pass "stopped for silent break 79"}
+ -re "$gdb_prompt $"\
+ {fail "stopped for silent break 79"}
+ timeout {fail "(timeout) stopped for silent break 79"}
+}
+
+# Verify that GDB can at least parse a breakpoint with the
+# "thread" keyword. (We won't attempt to test here that a
+# thread-specific breakpoint really triggers appropriately.
+# The gdb.threads subdirectory contains tests for that.)
+#
+send_gdb "break 80 thread 999\n"
+gdb_expect {
+ -re "Unknown thread 999.*$gdb_prompt $"\
+ {pass "thread-specific breakpoint on non-existent thread disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "thread-specific breakpoint on non-existent thread disallowed"}
+ timeout {fail "(timeout) thread-specific breakpoint on non-existent thread disallowed"}
+}
+send_gdb "break 80 thread foo\n"
+gdb_expect {
+ -re "Junk after thread keyword..*$gdb_prompt $"\
+ {pass "thread-specific breakpoint on bogus thread ID disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "thread-specific breakpoint on bogus thread ID disallowed"}
+ timeout {fail "(timeout) thread-specific breakpoint on bogus thread ID disallowed"}
+}
+
+# Verify that GDB responds gracefully to a breakpoint command with
+# trailing garbage.
+#
+send_gdb "break 80 foo\n"
+gdb_expect {
+ -re "Junk at end of arguments..*$gdb_prompt $"\
+ {pass "breakpoint with trailing garbage disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "breakpoint with trailing garbage disallowed"}
+ timeout {fail "(timeout) breakpoint with trailing garbage disallowed"}
+}
+
+# Verify that GDB responds gracefully to a "clear" command that has
+# no matching breakpoint. (First, get us off the current source line,
+# which we know has a breakpoint.)
+#
+send_gdb "next\n"
+gdb_expect {
+ -re ".*$gdb_prompt $"\
+ {pass "step over breakpoint"}
+ timeout {fail "(timeout) step over breakpoint"}
+}
+send_gdb "clear 81\n"
+gdb_expect {
+ -re "No breakpoint at 81..*$gdb_prompt $"\
+ {pass "clear line has no breakpoint disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "clear line has no breakpoint disallowed"}
+ timeout {fail "(timeout) clear line has no breakpoint disallowed"}
+}
+send_gdb "clear\n"
+gdb_expect {
+ -re "No breakpoint at this line..*$gdb_prompt $"\
+ {pass "clear current line has no breakpoint disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "clear current line has no breakpoint disallowed"}
+ timeout {fail "(timeout) clear current line has no breakpoint disallowed"}
+}
+
+# Verify that we can set and clear multiple breakpoints.
+#
+# We don't test that it deletes the correct breakpoints. We do at
+# least test that it deletes more than one breakpoint.
+#
+gdb_test "break marker3" "Breakpoint.*at.*" "break marker3 #1"
+gdb_test "break marker3" "Breakpoint.*at.*" "break marker3 #2"
+gdb_test "clear marker3" {Deleted breakpoints [0-9]+ [0-9]+.*}
+
+# Verify that a breakpoint can be set via a convenience variable.
+#
+send_gdb "set \$foo=81\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "set convenience variable \$foo to 81"}
+ timeout {fail "(timeout) set convenience variable \$foo to 81"}
+}
+send_gdb "break \$foo\n"
+gdb_expect {
+ -re "Breakpoint (\[0-9\]*) at .*, line 81.*$gdb_prompt $"\
+ {pass "set breakpoint via convenience variable"}
+ -re "$gdb_prompt $"\
+ {fail "set breakpoint via convenience variable"}
+ timeout {fail "(timeout) set breakpoint via convenience variable"}
+}
+
+# Verify that GDB responds gracefully to an attempt to set a
+# breakpoint via a convenience variable whose type is not integer.
+#
+send_gdb "set \$foo=81.5\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "set convenience variable \$foo to 81.5"}
+ timeout {fail "(timeout) set convenience variable \$foo to 81.5"}
+}
+send_gdb "break \$foo\n"
+gdb_expect {
+ -re "Convenience variables used in line specs must have integer values..*$gdb_prompt $"\
+ {pass "set breakpoint via non-integer convenience variable disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "set breakpoint via non-integer convenience variable disallowed"}
+ timeout {fail "(timeout) set breakpoint via non-integer convenience variable disallowed"}
+}
+
+# Verify that we can set and trigger a breakpoint in a user-called function.
+#
+send_gdb "break marker2\n"
+gdb_expect {
+ -re "Breakpoint (\[0-9\]*) at .*, line 4\[49\].*$gdb_prompt $"\
+ {pass "set breakpoint on to-be-called function"}
+ -re "$gdb_prompt $"\
+ {fail "set breakpoint on to-be-called function"}
+ timeout {fail "(timeout) set breakpoint on to-be-called function"}
+}
+send_gdb "print marker2(99)\n"
+gdb_expect {
+ -re "The program being debugged stopped while in a function called from GDB.\r\nWhen the function .marker2$proto. is done executing, GDB will silently\r\nstop .instead of continuing to evaluate the expression containing\r\nthe function call...*$gdb_prompt $"\
+ {pass "hit breakpoint on called function"}
+ -re "$gdb_prompt $"\
+ {fail "hit breakpoint on called function"}
+ timeout {fail "(timeout) hit breakpoint on called function"}
+}
+
+# As long as we're stopped (breakpointed) in a called function,
+# verify that we can successfully backtrace & such from here.
+#
+# In this and the following test, the _sr4export check apparently is needed
+# for hppa*-*-hpux.
+#
+send_gdb "bt\n"
+gdb_expect {
+ -re "#0\[ \t\]*($hex in )?marker2.*:4\[49\]\r\n#1.*_sr4export.*$gdb_prompt $"\
+ {pass "backtrace while in called function"}
+ -re "#0\[ \t\]*($hex in )?marker2.*:4\[49\]\r\n#1.*function called from gdb.*$gdb_prompt $"\
+ {pass "backtrace while in called function"}
+ -re "$gdb_prompt $"\
+ {fail "backtrace while in called function"}
+ timeout {fail "(timeout) backtrace while in called function"}
+}
+
+# Return from the called function. For remote targets, it's important to do
+# this before runto_main, which otherwise may silently stop on the dummy
+# breakpoint inserted by GDB at the program's entry point.
+#
+send_gdb "finish\n"
+gdb_expect {
+ -re "Run till exit from .*marker2.* at .*4\[49\]\r\n.* in _sr4export.*$gdb_prompt $"\
+ {pass "finish from called function"}
+ -re "Run till exit from .*marker2.* at .*4\[49\]\r\n.*function called from gdb.*$gdb_prompt $"\
+ {pass "finish from called function"}
+ -re "Run till exit from .*marker2.* at .*4\[49\]\r\n.*Value returned.*$gdb_prompt $"\
+ {pass "finish from called function"}
+ -re "$gdb_prompt $"\
+ {fail "finish from called function"}
+ timeout {fail "(timeout) finish from called function"}
+}
+
+# Verify that GDB responds gracefully to a "finish" command with
+# arguments.
+#
+if ![runto_main] then { fail "break tests suppressed" }
+
+send_gdb "finish 123\n"
+gdb_expect {
+ -re "The \"finish\" command does not take any arguments.\r\n$gdb_prompt $"\
+ {pass "finish with arguments disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "finish with arguments disallowed"}
+ timeout {fail "(timeout) finish with arguments disallowed"}
+}
+
+# Verify that GDB responds gracefully to a request to "finish" from
+# the outermost frame. On a stub that never exits, this will just
+# run to the stubs routine, so we don't get this error... Thus the
+# second condition.
+#
+
+send_gdb "finish\n"
+gdb_expect {
+ -re "\"finish\" not meaningful in the outermost frame.\r\n$gdb_prompt $"\
+ {pass "finish from outermost frame disallowed"}
+ -re "Run till exit from.*\r\n$gdb_prompt $" {
+ pass "finish from outermost frame disallowed"
+ }
+ -re "$gdb_prompt $"\
+ {fail "finish from outermost frame disallowed"}
+ timeout {fail "(timeout) finish from outermost frame disallowed"}
+}
+
+# Verify that we can explicitly ask GDB to stop on all shared library
+# events, and that it does so.
+#
+if [istarget "hppa*-*-hpux*"] then {
+ if ![runto_main] then { fail "break tests suppressed" }
+
+ send_gdb "set stop-on-solib-events 1\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "set stop-on-solib-events"}
+ timeout {fail "(timeout) set stop-on-solib-events"}
+ }
+
+ send_gdb "run\n"
+ gdb_expect {
+ -re ".*Start it from the beginning.*y or n. $"\
+ {send_gdb "y\n"
+ gdb_expect {
+ -re ".*Stopped due to shared library event.*$gdb_prompt $"\
+ {pass "triggered stop-on-solib-events"}
+ -re "$gdb_prompt $"\
+ {fail "triggered stop-on-solib-events"}
+ timeout {fail "(timeout) triggered stop-on-solib-events"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "rerun for stop-on-solib-events"}
+ timeout {fail "(timeout) rerun for stop-on-solib-events"}
+ }
+
+ send_gdb "set stop-on-solib-events 0\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "reset stop-on-solib-events"}
+ timeout {fail "(timeout) reset stop-on-solib-events"}
+ }
+}
+
+# Hardware breakpoints are unsupported on HP-UX. Verify that GDB
+# gracefully responds to requests to create them.
+#
+if [istarget "hppa*-*-hpux*"] then {
+ if ![runto_main] then { fail "break tests suppressed" }
+
+ send_gdb "hbreak\n"
+ gdb_expect {
+ -re "No hardware breakpoint support in the target.*$gdb_prompt $"\
+ {pass "hw breaks disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "hw breaks disallowed"}
+ timeout {fail "(timeout) hw breaks disallowed"}
+ }
+
+ send_gdb "thbreak\n"
+ gdb_expect {
+ -re "No hardware breakpoint support in the target.*$gdb_prompt $"\
+ {pass "temporary hw breaks disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "temporary hw breaks disallowed"}
+ timeout {fail "(timeout) temporary hw breaks disallowed"}
+ }
+}
+
+#********
+
+
+#
+# Test "next" over recursive function call.
+#
+
+proc test_next_with_recursion {} {
+ global gdb_prompt
+ global decimal
+ global binfile
+
+ if [target_info exists use_gdb_stub] {
+ # Reload the program.
+ delete_breakpoints
+ gdb_load ${binfile};
+ } else {
+ # FIXME: should be using runto
+ gdb_test "kill" "" "kill program" "Kill the program being debugged.*y or n. $" "y"
+
+ delete_breakpoints
+ }
+
+ gdb_test "break factorial" "Breakpoint $decimal at .*" "break at factorial"
+
+ # Run until we call factorial with 6
+
+ if [istarget "*-*-vxworks*"] then {
+ send_gdb "run vxmain \"6\"\n"
+ } else {
+ gdb_run_cmd
+ }
+ gdb_expect {
+ -re "Break.* factorial .value=6. .*$gdb_prompt $" {}
+ -re ".*$gdb_prompt $" {
+ fail "run to factorial(6)";
+ gdb_suppress_tests;
+ }
+ timeout { fail "run to factorial(6) (timeout)" ; gdb_suppress_tests }
+ }
+
+ # Continue until we call factorial recursively with 5.
+
+ if [gdb_test "continue" \
+ "Continuing.*Break.* factorial .value=5. .*" \
+ "continue to factorial(5)"] then { gdb_suppress_tests }
+
+ # Do a backtrace just to confirm how many levels deep we are.
+
+ if [gdb_test "backtrace" \
+ "#0\[ \t\]+ factorial .value=5..*" \
+ "backtrace from factorial(5)"] then { gdb_suppress_tests }
+
+ # Now a "next" should position us at the recursive call, which
+ # we will be performing with 4.
+
+ if [gdb_test "next" \
+ ".* factorial .value - 1.;.*" \
+ "next to recursive call"] then { gdb_suppress_tests }
+
+ # Disable the breakpoint at the entry to factorial by deleting them all.
+ # The "next" should run until we return to the next line from this
+ # recursive call to factorial with 4.
+ # Buggy versions of gdb will stop instead at the innermost frame on
+ # the line where we are trying to "next" to.
+
+ delete_breakpoints
+
+ if [istarget "mips*tx39-*"] {
+ set timeout 60
+ }
+ # We used to set timeout here for all other targets as well. This
+ # is almost certainly wrong. The proper timeout depends on the
+ # target system in use, and how we communicate with it, so there
+ # is no single value appropriate for all targets. The timeout
+ # should be established by the Dejagnu config file(s) for the
+ # board, and respected by the test suite.
+ #
+ # For example, if I'm running GDB over an SSH tunnel talking to a
+ # portmaster in California talking to an ancient 68k board running
+ # a crummy ROM monitor (a situation I can only wish were
+ # hypothetical), then I need a large timeout. But that's not the
+ # kind of knowledge that belongs in this file.
+
+ gdb_test next "\[0-9\]*\[\t \]+return \\(value\\);.*" \
+ "next over recursive call"
+
+ # OK, we should be back in the same stack frame we started from.
+ # Do a backtrace just to confirm.
+
+ set result [gdb_test "backtrace" \
+ "#0\[ \t\]+ factorial .value=120.*\r\n#1\[ \t\]+ \[0-9a-fx\]+ in factorial .value=6..*" \
+ "backtrace from factorial(5.1)"]
+ if { $result != 0 } { gdb_suppress_tests }
+
+ if [target_info exists gdb,noresults] { gdb_suppress_tests }
+ gdb_continue_to_end "recursive next test"
+ gdb_stop_suppressing_tests;
+}
+
+test_next_with_recursion
+
+
+#********
+
+# build a new file with optimization enabled so that we can try breakpoints
+# on targets with optimized prologues
+
+set binfileo2 ${objdir}/${subdir}/${testfile}o2
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfileo2}" executable {debug additional_flags="-O2" }] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfileo2}] {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfileo2}
+
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+
+#
+# test break at function
+#
+gdb_test "break main" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "breakpoint function, optimized file"
+
+#
+# test break at function
+#
+gdb_test "break marker4" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "breakpoint small function, optimized file"
+
+#
+# run until the breakpoint at main is hit. For non-stubs-using targets.
+#
+if ![target_info exists use_gdb_stub] {
+ if [istarget "*-*-vxworks*"] then {
+ send_gdb "run vxmain \"2\"\n"
+ set timeout 120
+ verbose "Timeout is now $timeout seconds" 2
+ } else {
+ send_gdb "run\n"
+ }
+ gdb_expect {
+ -re "The program .* has been started already.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "Starting program.*Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:75.*75\[\t \]+if .argc.* \{.*$gdb_prompt $"\
+ { pass "run until function breakpoint, optimized file" }
+ -re "Starting program.*Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$gdb_prompt $"\
+ { pass "run until function breakpoint, optimized file (code motion)" }
+ -re ".*$gdb_prompt $" { fail "run until function breakpoint, optimized file" }
+ timeout { fail "run until function breakpoint, optimized file (timeout)" }
+ }
+} else {
+ if ![target_info exists gdb_stub] {
+ gdb_test continue ".*Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:75.*75\[\t \]+if .argc.*\{.*" "stub continue, optimized file"
+ }
+}
+
+#
+# run until the breakpoint at a small function
+#
+
+#
+# Add a second pass pattern. The behavior differs here between stabs
+# and dwarf for one-line functions. Stabs preserves two line symbols
+# (one before the prologue and one after) with the same line number,
+# but dwarf regards these as duplicates and discards one of them.
+# Therefore the address after the prologue (where the breakpoint is)
+# has no exactly matching line symbol, and GDB reports the breakpoint
+# as if it were in the middle of a line rather than at the beginning.
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:51\[\r\n\]+51\[\t \]+void marker4.*" {
+ pass "run until breakpoint set at small function, optimized file"
+ }
+ -re "Breakpoint $decimal, $hex in marker4 \\(d=177601976\\) at .*$srcfile:51\[\r\n\]+51\[\t \]+void marker4.*" {
+ pass "run until breakpoint set at small function, optimized file"
+ }
+ -re ".*$gdb_prompt " {
+ fail "run until breakpoint set at small function, optimized file"
+ }
+ timeout {
+ fail "run until breakpoint set at small function, optimized file (timeout)"
+ }
+}
+
+
+# Reset the default arguments for VxWorks
+if [istarget "*-*-vxworks*"] {
+ set timeout 10
+ verbose "Timeout is now $timeout seconds" 2
+ send_gdb "set args main\n"
+ gdb_expect -re ".*$gdb_prompt $" {}
+}
diff --git a/gdb/testsuite/gdb.base/call-ar-st.c b/gdb/testsuite/gdb.base/call-ar-st.c
new file mode 100644
index 00000000000..d903f0d3f6b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/call-ar-st.c
@@ -0,0 +1,1339 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/**************************************************************************
+ * TESTS :
+ * -- function arguments that are enumerated types
+ * -- small structure arguments ( <= 64 bits )
+ * -- stored in registers
+ * -- stored on the stack
+ * -- large structure arguments ( > 64 bits )
+ * -- stored in registers
+ * -- stored on the stack
+ * -- array arguments
+ * -- caller is a leaf routine :
+ * -- use the call command from within an init routine (i.e.
+ * init_bit_flags, init_bit_flags_combo, init_array_rep)
+ * -- caller doesn't have enough space for all the function arguments :
+ * -- call print_long_arg_list from inside print_small_structs
+ ***************************************************************************/
+
+/* Some enumerated types -- used to test that the structureal data type is
+ * retrieved for function arguments with typedef data types.
+ */
+typedef int id_int;
+
+typedef enum {
+ BLACK,
+ BLUE,
+ BROWN,
+ ECRUE,
+ GOLD,
+ GRAY,
+ GREEN,
+ IVORY,
+ MAUVE,
+ ORANGE,
+ PINK,
+ PURPLE,
+ RED,
+ SILVER,
+ TAN,
+ VIOLET,
+ WHITE,
+ YELLOW} colors;
+
+/* A large structure (> 64 bits) used to test passing large structures as
+ * parameters
+ */
+
+struct array_rep_info_t {
+ int next_index[10];
+ int values[10];
+ int head;
+};
+
+/*****************************************************************************
+ * Small structures ( <= 64 bits). These are used to test passing small
+ * structures as parameters and test argument size promotion.
+ *****************************************************************************/
+
+ /* 64 bits
+ */
+struct small_rep_info_t {
+ int value;
+ int head;
+};
+
+/* 6 bits : really fits in 8 bits and is promoted to 32 bits
+ */
+struct bit_flags_t {
+ unsigned alpha :1;
+ unsigned beta :1;
+ unsigned gamma :1;
+ unsigned delta :1;
+ unsigned epsilon :1;
+ unsigned omega :1;
+};
+
+/* 22 bits : really fits in 40 bits and is promoted to 64 bits
+ */
+struct bit_flags_combo_t {
+ unsigned alpha :1;
+ unsigned beta :1;
+ char ch1;
+ unsigned gamma :1;
+ unsigned delta :1;
+ char ch2;
+ unsigned epsilon :1;
+ unsigned omega :1;
+};
+
+/* 64 bits
+ */
+struct one_double_t {
+ double double1;
+};
+
+/* 64 bits
+ */
+struct two_floats_t {
+ float float1;
+ float float2;
+};
+
+/* 16 bits : promoted to 32 bits
+ */
+struct two_char_t {
+ char ch1;
+ char ch2;
+};
+
+/* 24 bits : promoted to 32 bits
+ */
+struct three_char_t {
+ char ch1;
+ char ch2;
+ char ch3;
+};
+
+/* 40 bits : promoted to 64 bits
+ */
+struct five_char_t {
+ char ch1;
+ char ch2;
+ char ch3;
+ char ch4;
+ char ch5;
+};
+
+/* 40 bits : promoted to 64 bits
+ */
+struct int_char_combo_t {
+ int int1;
+ char ch1;
+};
+
+/*****************************************************************
+ * PRINT_STUDENT_ID_SHIRT_COLOR :
+ * IN id_int student -- enumerated type
+ * IN colors shirt -- enumerated type
+ *****************************************************************/
+#ifdef PROTOTYPES
+void print_student_id_shirt_color (id_int student, colors shirt)
+#else
+void print_student_id_shirt_color ( student, shirt )
+ id_int student;
+ colors shirt;
+#endif
+{
+
+ printf("student id : %d\t", student);
+ printf("shirt color : ");
+ switch (shirt) {
+ case BLACK : printf("BLACK\n");
+ break;
+ case BLUE : printf("BLUE\n");
+ break;
+ case BROWN : printf("BROWN\n");
+ break;
+ case ECRUE : printf("ECRUE\n");
+ break;
+ case GOLD : printf("GOLD\n");
+ break;
+ case GRAY : printf("GRAY\n");
+ break;
+ case GREEN : printf("GREEN\n");
+ break;
+ case IVORY : printf("IVORY\n");
+ break;
+ case MAUVE : printf("MAUVE\n");
+ break;
+ case ORANGE : printf("ORANGE\n");
+ break;
+ case PINK : printf("PINK\n");
+ break;
+ case PURPLE : printf("PURPLE\n");
+ break;
+ case RED : printf("RED\n");
+ break;
+ case SILVER : printf("SILVER\n");
+ break;
+ case TAN : printf("TAN\n");
+ break;
+ case VIOLET : printf("VIOLET\n");
+ break;
+ case WHITE : printf("WHITE\n");
+ break;
+ case YELLOW : printf("YELLOW\n");
+ break;
+ }
+}
+
+/*****************************************************************
+ * PRINT_CHAR_ARRAY :
+ * IN char array_c[] -- character array
+ *****************************************************************/
+#ifdef PROTOTYPES
+void print_char_array (char array_c[])
+#else
+void print_char_array ( array_c )
+ char array_c[];
+#endif
+{
+
+ int index;
+
+ printf("array_c :\n");
+ printf("=========\n\n");
+ for (index = 0; index < 120; index++) {
+ printf("%1c", array_c[index]);
+ if ((index%50) == 0) printf("\n");
+ }
+ printf("\n\n");
+}
+
+/*****************************************************************
+ * PRINT_DOUBLE_ARRAY :
+ * IN double array_d[] -- array of doubles
+ *****************************************************************/
+#ifdef PROTOTYPES
+void print_double_array (double array_d[])
+#else
+void print_double_array (array_d)
+ double array_d[];
+#endif
+{
+
+ int index;
+
+ printf("array_d :\n");
+ printf("=========\n\n");
+ for (index = 0; index < 9; index++) {
+ printf("%f ", array_d[index]);
+ if ((index%8) == 0) printf("\n");
+ }
+ printf("\n\n");
+}
+
+/*****************************************************************
+ * PRINT_FLOAT_ARRAY:
+ * IN float array_f[] -- array of floats
+ *****************************************************************/
+#ifdef PROTOTYPES
+void print_float_array (float array_f[])
+#else
+void print_float_array ( array_f )
+ float array_f[];
+#endif
+{
+
+ int index;
+
+ printf("array_f :\n");
+ printf("=========\n\n");
+ for (index = 0; index < 15; index++) {
+ printf("%f ", array_f[index]);
+ if ((index%8) == 0) printf("\n");
+
+ }
+ printf("\n\n");
+}
+
+/*****************************************************************
+ * PRINT_INT_ARRAY:
+ * IN int array_i[] -- array of integers
+ *****************************************************************/
+#ifdef PROTOTYPES
+void print_int_array (int array_i[])
+#else
+void print_int_array ( array_i )
+ int array_i[];
+#endif
+{
+
+ int index;
+
+ printf("array_i :\n");
+ printf("=========\n\n");
+ for (index = 0; index < 50; index++) {
+ printf("%d ", array_i[index]);
+ if ((index%8) == 0) printf("\n");
+ }
+ printf("\n\n");
+
+}
+
+/*****************************************************************
+ * PRINT_ALL_ARRAYS:
+ * IN int array_i[] -- array of integers
+ * IN char array_c[] -- array of characters
+ * IN float array_f[] -- array of floats
+ * IN double array_d[] -- array of doubles
+ *****************************************************************/
+#ifdef PROTOTYPES
+void print_all_arrays(int array_i[], char array_c[], float array_f[], double array_d[])
+#else
+void print_all_arrays( array_i, array_c, array_f, array_d )
+ int array_i[];
+ char array_c[];
+ float array_f[];
+ double array_d[];
+#endif
+{
+ print_int_array(array_i);
+ print_char_array(array_c);
+ print_float_array(array_f);
+ print_double_array(array_d);
+}
+
+/*****************************************************************
+ * LOOP_COUNT :
+ * A do nothing function. Used to provide a point at which calls can be made.
+ *****************************************************************/
+void loop_count () {
+
+ int index;
+
+ for (index=0; index<4; index++);
+}
+
+/*****************************************************************
+ * COMPUTE_WITH_SMALL_STRUCTS :
+ * A do nothing function. Used to provide a point at which calls can be made.
+ * IN int seed
+ *****************************************************************/
+#ifdef PROTOTYPES
+void compute_with_small_structs (int seed)
+#else
+void compute_with_small_structs ( seed )
+ int seed;
+#endif
+{
+
+ struct small_rep_info_t array[4];
+ int index;
+
+ for (index = 0; index < 4; index++) {
+ array[index].value = index*seed;
+ array[index].head = (index+1)*seed;
+ }
+
+ for (index = 1; index < 4; index++) {
+ array[index].value = array[index].value + array[index-1].value;
+ array[index].head = array[index].head + array[index-1].head;
+ }
+}
+
+/*****************************************************************
+ * INIT_BIT_FLAGS :
+ * Initializes a bit_flags_t structure. Can call this function see
+ * the call command behavior when integer arguments do not fit into
+ * registers and must be placed on the stack.
+ * OUT struct bit_flags_t *bit_flags -- structure to be filled
+ * IN unsigned a -- 0 or 1
+ * IN unsigned b -- 0 or 1
+ * IN unsigned g -- 0 or 1
+ * IN unsigned d -- 0 or 1
+ * IN unsigned e -- 0 or 1
+ * IN unsigned o -- 0 or 1
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_bit_flags (struct bit_flags_t *bit_flags, unsigned a, unsigned b, unsigned g, unsigned d, unsigned e, unsigned o)
+#else
+void init_bit_flags ( bit_flags, a, b, g, d, e, o )
+struct bit_flags_t *bit_flags;
+unsigned a;
+unsigned b;
+unsigned g;
+unsigned d;
+unsigned e;
+unsigned o;
+#endif
+{
+
+ bit_flags->alpha = a;
+ bit_flags->beta = b;
+ bit_flags->gamma = g;
+ bit_flags->delta = d;
+ bit_flags->epsilon = e;
+ bit_flags->omega = o;
+}
+
+/*****************************************************************
+ * INIT_BIT_FLAGS_COMBO :
+ * Initializes a bit_flags_combo_t structure. Can call this function
+ * to see the call command behavior when integer and character arguments
+ * do not fit into registers and must be placed on the stack.
+ * OUT struct bit_flags_combo_t *bit_flags_combo -- structure to fill
+ * IN unsigned a -- 0 or 1
+ * IN unsigned b -- 0 or 1
+ * IN char ch1
+ * IN unsigned g -- 0 or 1
+ * IN unsigned d -- 0 or 1
+ * IN char ch2
+ * IN unsigned e -- 0 or 1
+ * IN unsigned o -- 0 or 1
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_bit_flags_combo (struct bit_flags_combo_t *bit_flags_combo, unsigned a, unsigned b, char ch1, unsigned g, unsigned d, char ch2, unsigned e, unsigned o)
+#else
+void init_bit_flags_combo ( bit_flags_combo, a, b, ch1, g, d, ch2, e, o )
+ struct bit_flags_combo_t *bit_flags_combo;
+ unsigned a;
+ unsigned b;
+ char ch1;
+ unsigned g;
+ unsigned d;
+ char ch2;
+ unsigned e;
+ unsigned o;
+#endif
+{
+
+ bit_flags_combo->alpha = a;
+ bit_flags_combo->beta = b;
+ bit_flags_combo->ch1 = ch1;
+ bit_flags_combo->gamma = g;
+ bit_flags_combo->delta = d;
+ bit_flags_combo->ch2 = ch2;
+ bit_flags_combo->epsilon = e;
+ bit_flags_combo->omega = o;
+}
+
+
+/*****************************************************************
+ * INIT_ONE_DOUBLE :
+ * OUT struct one_double_t *one_double -- structure to fill
+ * IN double init_val
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_one_double (struct one_double_t *one_double, double init_val)
+#else
+void init_one_double ( one_double, init_val )
+ struct one_double_t *one_double;
+ double init_val;
+#endif
+{
+
+ one_double->double1 = init_val;
+}
+
+/*****************************************************************
+ * INIT_TWO_FLOATS :
+ * OUT struct two_floats_t *two_floats -- structure to be filled
+ * IN float init_val1
+ * IN float init_val2
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_two_floats (struct two_floats_t *two_floats, float init_val1, float init_val2)
+#else
+void init_two_floats ( two_floats, init_val1, init_val2 )
+ struct two_floats_t *two_floats;
+ float init_val1;
+ float init_val2;
+#endif
+{
+ two_floats->float1 = init_val1;
+ two_floats->float2 = init_val2;
+}
+
+/*****************************************************************
+ * INIT_TWO_CHARS :
+ * OUT struct two_char_t *two_char -- structure to be filled
+ * IN char init_val1
+ * IN char init_val2
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_two_chars (struct two_char_t *two_char, char init_val1, char init_val2)
+#else
+void init_two_chars ( two_char, init_val1, init_val2 )
+ struct two_char_t *two_char;
+ char init_val1;
+ char init_val2;
+#endif
+{
+
+ two_char->ch1 = init_val1;
+ two_char->ch2 = init_val2;
+}
+
+/*****************************************************************
+ * INIT_THREE_CHARS :
+ * OUT struct three_char_t *three_char -- structure to be filled
+ * IN char init_val1
+ * IN char init_val2
+ * IN char init_val3
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_three_chars (struct three_char_t *three_char, char init_val1, char init_val2, char init_val3)
+#else
+void init_three_chars ( three_char, init_val1, init_val2, init_val3 )
+ struct three_char_t *three_char;
+ char init_val1;
+ char init_val2;
+ char init_val3;
+#endif
+{
+
+ three_char->ch1 = init_val1;
+ three_char->ch2 = init_val2;
+ three_char->ch3 = init_val3;
+}
+
+/*****************************************************************
+ * INIT_FIVE_CHARS :
+ * OUT struct five_char_t *five_char -- structure to be filled
+ * IN char init_val1
+ * IN char init_val2
+ * IN char init_val3
+ * IN char init_val4
+ * IN char init_val5
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_five_chars (struct five_char_t *five_char, char init_val1, char init_val2, char init_val3, char init_val4, char init_val5)
+#else
+void init_five_chars ( five_char, init_val1, init_val2, init_val3,init_val4,init_val5 )
+ struct five_char_t *five_char;
+ char init_val1;
+ char init_val2;
+ char init_val3;
+ char init_val4;
+ char init_val5;
+#endif
+{
+ five_char->ch1 = init_val1;
+ five_char->ch2 = init_val2;
+ five_char->ch3 = init_val3;
+ five_char->ch4 = init_val4;
+ five_char->ch5 = init_val5;
+}
+
+/*****************************************************************
+ * INIT_INT_CHAR_COMBO :
+ * OUT struct int_char_combo_t *combo -- structure to be filled
+ * IN int init_val1
+ * IN char init_val2
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_int_char_combo (struct int_char_combo_t *combo, int init_val1, char init_val2)
+#else
+void init_int_char_combo ( combo, init_val1, init_val2 )
+ struct int_char_combo_t *combo;
+ int init_val1;
+ char init_val2;
+#endif
+{
+
+ combo->int1 = init_val1;
+ combo->ch1 = init_val2;
+}
+
+/*****************************************************************
+ * INIT_STRUCT_REP :
+ * OUT struct small_rep_into_t *small_struct -- structure to be filled
+ * IN int seed
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_struct_rep(struct small_rep_info_t *small_struct, int seed)
+#else
+void init_struct_rep( small_struct, seed )
+ struct small_rep_info_t *small_struct;
+ int seed;
+#endif
+{
+
+ small_struct->value = 2 + (seed*2);
+ small_struct->head = 0;
+}
+
+/*****************************************************************
+ * INIT_SMALL_STRUCTS :
+ * Takes all the small structures as input and calls the appropriate
+ * initialization routine for each structure
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_small_structs (
+ struct small_rep_info_t *struct1,
+ struct small_rep_info_t *struct2,
+ struct small_rep_info_t *struct3,
+ struct small_rep_info_t *struct4,
+ struct bit_flags_t *flags,
+ struct bit_flags_combo_t *flags_combo,
+ struct three_char_t *three_char,
+ struct five_char_t *five_char,
+ struct int_char_combo_t *int_char_combo,
+ struct one_double_t *d1,
+ struct one_double_t *d2,
+ struct one_double_t *d3,
+ struct two_floats_t *f1,
+ struct two_floats_t *f2,
+ struct two_floats_t *f3)
+#else
+void init_small_structs (struct1, struct2, struct3,struct4,flags,flags_combo,
+three_char, five_char,int_char_combo, d1, d2,d3,f1,f2,f3)
+ struct small_rep_info_t *struct1;
+ struct small_rep_info_t *struct2;
+ struct small_rep_info_t *struct3;
+ struct small_rep_info_t *struct4;
+ struct bit_flags_t *flags;
+ struct bit_flags_combo_t *flags_combo;
+ struct three_char_t *three_char;
+ struct five_char_t *five_char;
+ struct int_char_combo_t *int_char_combo;
+ struct one_double_t *d1;
+ struct one_double_t *d2;
+ struct one_double_t *d3;
+ struct two_floats_t *f1;
+ struct two_floats_t *f2;
+ struct two_floats_t *f3;
+#endif
+{
+
+ init_bit_flags(flags, (unsigned)1, (unsigned)0, (unsigned)1,
+ (unsigned)0, (unsigned)1, (unsigned)0 );
+ init_bit_flags_combo(flags_combo, (unsigned)1, (unsigned)0, 'y',
+ (unsigned)1, (unsigned)0, 'n',
+ (unsigned)1, (unsigned)0 );
+ init_three_chars(three_char, 'a', 'b', 'c');
+ init_five_chars(five_char, 'l', 'm', 'n', 'o', 'p');
+ init_int_char_combo(int_char_combo, 123, 'z');
+ init_struct_rep(struct1, 2);
+ init_struct_rep(struct2, 4);
+ init_struct_rep(struct3, 5);
+ init_struct_rep(struct4, 6);
+ init_one_double ( d1, 10.5);
+ init_one_double ( d2, -3.375);
+ init_one_double ( d3, 675.09375);
+ init_two_floats ( f1, 45.234, 43.6);
+ init_two_floats ( f2, 78.01, 122.10);
+ init_two_floats ( f3, -1232.345, -199.21);
+}
+
+/*****************************************************************
+ * PRINT_TEN_DOUBLES :
+ * ?????????????????????????????
+ ****************************************************************/
+#ifdef PROTOTYPES
+void print_ten_doubles (
+ double d1,
+ double d2,
+ double d3,
+ double d4,
+ double d5,
+ double d6,
+ double d7,
+ double d8,
+ double d9,
+ double d10)
+#else
+void print_ten_doubles ( d1, d2, d3, d4, d5, d6, d7, d8, d9, d10 )
+ double d1;
+ double d2;
+ double d3;
+ double d4;
+ double d5;
+ double d6;
+ double d7;
+ double d8;
+ double d9;
+ double d10;
+#endif
+{
+
+ printf("Two Doubles : %f\t%f\n", d1, d2);
+ printf("Two Doubles : %f\t%f\n", d3, d4);
+ printf("Two Doubles : %f\t%f\n", d5, d6);
+ printf("Two Doubles : %f\t%f\n", d7, d8);
+ printf("Two Doubles : %f\t%f\n", d9, d10);
+}
+
+/*****************************************************************
+ * PRINT_BIT_FLAGS :
+ * IN struct bit_flags_t bit_flags
+ ****************************************************************/
+#ifdef PROTOTYPES
+void print_bit_flags (struct bit_flags_t bit_flags)
+#else
+void print_bit_flags ( bit_flags )
+struct bit_flags_t bit_flags;
+#endif
+{
+
+ if (bit_flags.alpha) printf("alpha\n");
+ if (bit_flags.beta) printf("beta\n");
+ if (bit_flags.gamma) printf("gamma\n");
+ if (bit_flags.delta) printf("delta\n");
+ if (bit_flags.epsilon) printf("epsilon\n");
+ if (bit_flags.omega) printf("omega\n");
+}
+
+/*****************************************************************
+ * PRINT_BIT_FLAGS_COMBO :
+ * IN struct bit_flags_combo_t bit_flags_combo
+ ****************************************************************/
+#ifdef PROTOTYPES
+void print_bit_flags_combo (struct bit_flags_combo_t bit_flags_combo)
+#else
+void print_bit_flags_combo ( bit_flags_combo )
+ struct bit_flags_combo_t bit_flags_combo;
+#endif
+{
+
+ if (bit_flags_combo.alpha) printf("alpha\n");
+ if (bit_flags_combo.beta) printf("beta\n");
+ if (bit_flags_combo.gamma) printf("gamma\n");
+ if (bit_flags_combo.delta) printf("delta\n");
+ if (bit_flags_combo.epsilon) printf("epsilon\n");
+ if (bit_flags_combo.omega) printf("omega\n");
+ printf("ch1: %c\tch2: %c\n", bit_flags_combo.ch1, bit_flags_combo.ch2);
+}
+
+/*****************************************************************
+ * PRINT_ONE_DOUBLE :
+ * IN struct one_double_t one_double
+ ****************************************************************/
+#ifdef PROTOTYPES
+void print_one_double (struct one_double_t one_double)
+#else
+void print_one_double ( one_double )
+struct one_double_t one_double;
+#endif
+{
+
+ printf("Contents of one_double_t: \n\n");
+ printf("%f\n", one_double.double1);
+}
+
+/*****************************************************************
+ * PRINT_TWO_FLOATS :
+ * IN struct two_floats_t two_floats
+ ****************************************************************/
+#ifdef PROTOTYPES
+void print_two_floats (struct two_floats_t two_floats)
+#else
+void print_two_floats ( two_floats )
+struct two_floats_t two_floats;
+#endif
+{
+
+ printf("Contents of two_floats_t: \n\n");
+ printf("%f\t%f\n", two_floats.float1, two_floats.float2);
+}
+
+/*****************************************************************
+ * PRINT_TWO_CHARS :
+ * IN struct two_char_t two_char
+ ****************************************************************/
+#ifdef PROTOTYPES
+void print_two_chars (struct two_char_t two_char)
+#else
+void print_two_chars ( two_char )
+struct two_char_t two_char;
+#endif
+{
+
+ printf("Contents of two_char_t: \n\n");
+ printf("%c\t%c\n", two_char.ch1, two_char.ch2);
+}
+
+/*****************************************************************
+ * PRINT_THREE_CHARS :
+ * IN struct three_char_t three_char
+ ****************************************************************/
+#ifdef PROTOTYPES
+void print_three_chars (struct three_char_t three_char)
+#else
+void print_three_chars ( three_char )
+struct three_char_t three_char;
+#endif
+{
+
+ printf("Contents of three_char_t: \n\n");
+ printf("%c\t%c\t%c\n", three_char.ch1, three_char.ch2, three_char.ch3);
+}
+
+/*****************************************************************
+ * PRINT_FIVE_CHARS :
+ * IN struct five_char_t five_char
+ ****************************************************************/
+#ifdef PROTOTYPES
+void print_five_chars (struct five_char_t five_char)
+#else
+void print_five_chars ( five_char )
+struct five_char_t five_char;
+#endif
+{
+
+ printf("Contents of five_char_t: \n\n");
+ printf("%c\t%c\t%c\t%c\t%c\n", five_char.ch1, five_char.ch2,
+ five_char.ch3, five_char.ch4,
+ five_char.ch5);
+}
+
+/*****************************************************************
+ * PRINT_INT_CHAR_COMBO :
+ * IN struct int_char_combo_t int_char_combo
+ ****************************************************************/
+#ifdef PROTOTYPES
+void print_int_char_combo (struct int_char_combo_t int_char_combo)
+#else
+void print_int_char_combo ( int_char_combo )
+struct int_char_combo_t int_char_combo;
+#endif
+{
+
+ printf("Contents of int_char_combo_t: \n\n");
+ printf("%d\t%c\n", int_char_combo.int1, int_char_combo.ch1);
+}
+
+/*****************************************************************
+ * PRINT_STRUCT_REP :
+ * The last parameter must go onto the stack rather than into a register.
+ * This is a good function to call to test small structures.
+ * IN struct small_rep_info_t struct1
+ * IN struct small_rep_info_t struct2
+ * IN struct small_rep_info_t struct3
+ ****************************************************************/
+#ifdef PROTOTYPES
+void print_struct_rep(
+ struct small_rep_info_t struct1,
+ struct small_rep_info_t struct2,
+ struct small_rep_info_t struct3)
+#else
+void print_struct_rep( struct1, struct2, struct3)
+ struct small_rep_info_t struct1;
+ struct small_rep_info_t struct2;
+ struct small_rep_info_t struct3;
+#endif
+{
+
+
+ printf("Contents of struct1: \n\n");
+ printf("%10d%10d\n", struct1.value, struct1.head);
+ printf("Contents of struct2: \n\n");
+ printf("%10d%10d\n", struct2.value, struct2.head);
+ printf("Contents of struct3: \n\n");
+ printf("%10d%10d\n", struct3.value, struct3.head);
+
+}
+
+/*****************************************************************
+ * SUM_STRUCT_PRINT :
+ * The last two parameters must go onto the stack rather than into a register.
+ * This is a good function to call to test small structures.
+ * IN struct small_rep_info_t struct1
+ * IN struct small_rep_info_t struct2
+ * IN struct small_rep_info_t struct3
+ * IN struct small_rep_info_t struct4
+ ****************************************************************/
+#ifdef PROTOTYPES
+void sum_struct_print (
+ int seed,
+ struct small_rep_info_t struct1,
+ struct small_rep_info_t struct2,
+ struct small_rep_info_t struct3,
+ struct small_rep_info_t struct4)
+#else
+void sum_struct_print ( seed, struct1, struct2, struct3, struct4)
+ int seed;
+ struct small_rep_info_t struct1;
+ struct small_rep_info_t struct2;
+ struct small_rep_info_t struct3;
+ struct small_rep_info_t struct4;
+#endif
+{
+ int sum;
+
+ printf("Sum of the 4 struct values and seed : \n\n");
+ sum = seed + struct1.value + struct2.value + struct3.value + struct4.value;
+ printf("%10d\n", sum);
+}
+
+/*****************************************************************
+ * PRINT_SMALL_STRUCTS :
+ * This is a good function to call to test small structures.
+ * All of the small structures of odd sizes (40 bits, 8bits, etc.)
+ * are pushed onto the stack.
+ ****************************************************************/
+#ifdef PROTOTYPES
+void print_small_structs (
+ struct small_rep_info_t struct1,
+ struct small_rep_info_t struct2,
+ struct small_rep_info_t struct3,
+ struct small_rep_info_t struct4,
+ struct bit_flags_t flags,
+ struct bit_flags_combo_t flags_combo,
+ struct three_char_t three_char,
+ struct five_char_t five_char,
+ struct int_char_combo_t int_char_combo,
+ struct one_double_t d1,
+ struct one_double_t d2,
+ struct one_double_t d3,
+ struct two_floats_t f1,
+ struct two_floats_t f2,
+ struct two_floats_t f3)
+#else
+void print_small_structs ( struct1, struct2, struct3, struct4, flags,
+flags_combo, three_char, five_char, int_char_combo, d1, d2,d3,f1,f2,f3)
+ struct small_rep_info_t struct1;
+ struct small_rep_info_t struct2;
+ struct small_rep_info_t struct3;
+ struct small_rep_info_t struct4;
+ struct bit_flags_t flags;
+ struct bit_flags_combo_t flags_combo;
+ struct three_char_t three_char;
+ struct five_char_t five_char;
+ struct int_char_combo_t int_char_combo;
+ struct one_double_t d1;
+ struct one_double_t d2;
+ struct one_double_t d3;
+ struct two_floats_t f1;
+ struct two_floats_t f2;
+ struct two_floats_t f3;
+#endif
+{
+ print_bit_flags(flags);
+ print_bit_flags_combo(flags_combo);
+ print_three_chars(three_char);
+ print_five_chars(five_char);
+ print_int_char_combo(int_char_combo);
+ sum_struct_print(10, struct1, struct2, struct3, struct4);
+ print_struct_rep(struct1, struct2, struct3);
+ print_one_double(d1);
+ print_one_double(d2);
+ print_one_double(d3);
+ print_two_floats(f1);
+ print_two_floats(f2);
+ print_two_floats(f3);
+}
+
+/*****************************************************************
+ * PRINT_LONG_ARG_LIST :
+ * This is a good function to call to test small structures.
+ * The first two parameters ( the doubles ) go into registers. The
+ * remaining arguments are pushed onto the stack. Depending on where
+ * print_long_arg_list is called from, the size of the argument list
+ * may force more space to be pushed onto the stack as part of the callers
+ * frame.
+ ****************************************************************/
+#ifdef PROTOTYPES
+void print_long_arg_list (
+ double a,
+ double b,
+ int c,
+ int d,
+ int e,
+ int f,
+ struct small_rep_info_t struct1,
+ struct small_rep_info_t struct2,
+ struct small_rep_info_t struct3,
+ struct small_rep_info_t struct4,
+ struct bit_flags_t flags,
+ struct bit_flags_combo_t flags_combo,
+ struct three_char_t three_char,
+ struct five_char_t five_char,
+ struct int_char_combo_t int_char_combo,
+ struct one_double_t d1,
+ struct one_double_t d2,
+ struct one_double_t d3,
+ struct two_floats_t f1,
+ struct two_floats_t f2,
+ struct two_floats_t f3)
+#else
+void print_long_arg_list ( a, b, c, d, e, f, struct1, struct2, struct3,
+struct4, flags, flags_combo, three_char, five_char, int_char_combo, d1,d2,d3,
+f1, f2, f3 )
+ double a;
+ double b;
+ int c;
+ int d;
+ int e;
+ int f;
+ struct small_rep_info_t struct1;
+ struct small_rep_info_t struct2;
+ struct small_rep_info_t struct3;
+ struct small_rep_info_t struct4;
+ struct bit_flags_t flags;
+ struct bit_flags_combo_t flags_combo;
+ struct three_char_t three_char;
+ struct five_char_t five_char;
+ struct int_char_combo_t int_char_combo;
+ struct one_double_t d1;
+ struct one_double_t d2;
+ struct one_double_t d3;
+ struct two_floats_t f1;
+ struct two_floats_t f2;
+ struct two_floats_t f3;
+#endif
+{
+ printf("double : %f\n", a);
+ printf("double : %f\n", b);
+ printf("int : %d\n", c);
+ printf("int : %d\n", d);
+ printf("int : %d\n", e);
+ printf("int : %d\n", f);
+ print_small_structs( struct1, struct2, struct3, struct4, flags, flags_combo,
+ three_char, five_char, int_char_combo, d1, d2, d3,
+ f1, f2, f3);
+}
+
+
+#ifdef PROTOTYPES
+void print_one_large_struct (struct array_rep_info_t linked_list1)
+#else
+void print_one_large_struct( linked_list1 )
+ struct array_rep_info_t linked_list1;
+#endif
+{
+
+ /* printf("Contents of linked list1: \n\n");
+ printf("Element Value | Index of Next Element\n");
+ printf("-------------------------------------\n");
+ printf(" | \n");*/
+ /*for (index = 0; index < 10; index++) {*/
+
+ printf("%10d%10d\n", linked_list1.values[0],
+ linked_list1.next_index[0]);
+ /*}*/
+}
+
+/*****************************************************************
+ * PRINT_ARRAY_REP :
+ * The three structure parameters should fit into registers.
+ * IN struct array_rep_info_t linked_list1
+ * IN struct array_rep_info_t linked_list2
+ * IN struct array_rep_info_t linked_list3
+ ****************************************************************/
+#ifdef PROTOTYPES
+void print_array_rep(
+ struct array_rep_info_t linked_list1,
+ struct array_rep_info_t linked_list2,
+ struct array_rep_info_t linked_list3)
+#else
+void print_array_rep( linked_list1, linked_list2, linked_list3 )
+ struct array_rep_info_t linked_list1;
+ struct array_rep_info_t linked_list2;
+ struct array_rep_info_t linked_list3;
+#endif
+{
+
+ int index;
+
+ printf("Contents of linked list1: \n\n");
+ printf("Element Value | Index of Next Element\n");
+ printf("-------------------------------------\n");
+ printf(" | \n");
+ for (index = 0; index < 10; index++) {
+
+ printf("%10d%10d\n", linked_list1.values[index],
+ linked_list1.next_index[index]);
+ }
+
+ printf("Contents of linked list2: \n\n");
+ printf("Element Value | Index of Next Element\n");
+ printf("-------------------------------------\n");
+ printf(" | \n");
+ for (index = 0; index < 10; index++) {
+
+ printf("%10d%10d\n", linked_list2.values[index],
+ linked_list2.next_index[index]);
+ }
+
+ printf("Contents of linked list3: \n\n");
+ printf("Element Value | Index of Next Element\n");
+ printf("-------------------------------------\n");
+ printf(" | \n");
+ for (index = 0; index < 10; index++) {
+
+ printf("%10d%10d\n", linked_list3.values[index],
+ linked_list3.next_index[index]);
+ }
+
+}
+
+/*****************************************************************
+ * SUM_ARRAY_PRINT :
+ * The last structure parameter must be pushed onto the stack
+ * IN int seed
+ * IN struct array_rep_info_t linked_list1
+ * IN struct array_rep_info_t linked_list2
+ * IN struct array_rep_info_t linked_list3
+ * IN struct array_rep_info_t linked_list4
+ ****************************************************************/
+#ifdef PROTOTYPES
+void sum_array_print (
+ int seed,
+ struct array_rep_info_t linked_list1,
+ struct array_rep_info_t linked_list2,
+ struct array_rep_info_t linked_list3,
+ struct array_rep_info_t linked_list4)
+#else
+void sum_array_print ( seed, linked_list1, linked_list2, linked_list3,linked_list4)
+ int seed;
+ struct array_rep_info_t linked_list1;
+ struct array_rep_info_t linked_list2;
+ struct array_rep_info_t linked_list3;
+ struct array_rep_info_t linked_list4;
+#endif
+{
+ int index;
+ int sum;
+
+ printf("Sum of 4 arrays, by element (add in seed as well): \n\n");
+ printf("Seed: %d\n", seed);
+ printf("Element Index | Sum \n");
+ printf("-------------------------\n");
+ printf(" | \n");
+
+ for (index = 0; index < 10; index++) {
+
+ sum = seed + linked_list1.values[index] + linked_list2.values[index] +
+ linked_list3.values[index] + linked_list4.values[index];
+ printf("%10d%10d\n", index, sum);
+ }
+}
+
+/*****************************************************************
+ * INIT_ARRAY_REP :
+ * IN struct array_rep_info_t *linked_list
+ * IN int seed
+ ****************************************************************/
+#ifdef PROTOTYPES
+void init_array_rep(
+ struct array_rep_info_t *linked_list,
+ int seed)
+#else
+void init_array_rep( linked_list, seed )
+ struct array_rep_info_t *linked_list;
+ int seed;
+#endif
+{
+
+ int index;
+
+ for (index = 0; index < 10; index++) {
+
+ linked_list->values[index] = (2*index) + (seed*2);
+ linked_list->next_index[index] = index + 1;
+ }
+ linked_list->head = 0;
+}
+
+
+int main () {
+
+ /* variables for array and enumerated type testing
+ */
+ static char char_array[121];
+ static double double_array[9];
+ static float float_array[15];
+ static int integer_array[50];
+ static int index;
+ static id_int student_id = 23;
+ static colors my_shirt = YELLOW;
+
+ /* variables for large structure testing
+ */
+ static int number = 10;
+ static struct array_rep_info_t *list1;
+ static struct array_rep_info_t *list2;
+ static struct array_rep_info_t *list3;
+ static struct array_rep_info_t *list4;
+
+ /* variables for testing a very long argument list
+ */
+ static double a;
+ static double b;
+ static int c;
+ static int d;
+ static int e;
+ static int f;
+
+ /* variables for testing a small structures and a very long argument list
+ */
+ static struct small_rep_info_t *struct1;
+ static struct small_rep_info_t *struct2;
+ static struct small_rep_info_t *struct3;
+ static struct small_rep_info_t *struct4;
+ static struct bit_flags_t *flags;
+ static struct bit_flags_combo_t *flags_combo;
+ static struct three_char_t *three_char;
+ static struct five_char_t *five_char;
+ static struct int_char_combo_t *int_char_combo;
+ static struct one_double_t *d1;
+ static struct one_double_t *d2;
+ static struct one_double_t *d3;
+ static struct two_floats_t *f1;
+ static struct two_floats_t *f2;
+ static struct two_floats_t *f3;
+
+ /* Initialize arrays
+ */
+ for (index = 0; index < 120; index++) {
+ if ((index%2) == 0) char_array[index] = 'Z';
+ else char_array[index] = 'a';
+ }
+ char_array[120] = '\0';
+
+ for (index = 0; index < 9; index++) {
+ double_array[index] = index*23.4567;
+ }
+
+ for (index = 0; index < 15; index++) {
+ float_array[index] = index/7.02;
+ }
+
+ for (index = 0; index < 50; index++) {
+ integer_array[index] = -index;
+ }
+
+ /* Print arrays
+ */
+ print_char_array(char_array);
+ print_double_array(double_array);
+ print_float_array(float_array);
+ print_student_id_shirt_color(student_id, my_shirt);
+ print_int_array(integer_array);
+ print_all_arrays(integer_array, char_array, float_array, double_array);
+
+ /* Allocate space for large structures
+ */
+ list1 = (struct array_rep_info_t *)malloc(sizeof(struct array_rep_info_t));
+ list2 = (struct array_rep_info_t *)malloc(sizeof(struct array_rep_info_t));
+ list3 = (struct array_rep_info_t *)malloc(sizeof(struct array_rep_info_t));
+ list4 = (struct array_rep_info_t *)malloc(sizeof(struct array_rep_info_t));
+
+ /* Initialize large structures
+ */
+ init_array_rep(list1, 2);
+ init_array_rep(list2, 4);
+ init_array_rep(list3, 5);
+ init_array_rep(list4, 10);
+ printf("HELLO WORLD\n");
+ printf("BYE BYE FOR NOW\n");
+ printf("VERY GREEN GRASS\n");
+
+ /* Print large structures
+ */
+ sum_array_print(10, *list1, *list2, *list3, *list4);
+ print_array_rep(*list1, *list2, *list3);
+ print_one_large_struct(*list1);
+
+ /* Allocate space for small structures
+ */
+ struct1 = (struct small_rep_info_t *)malloc(sizeof(struct small_rep_info_t));
+ struct2 = (struct small_rep_info_t *)malloc(sizeof(struct small_rep_info_t));
+ struct3 = (struct small_rep_info_t *)malloc(sizeof(struct small_rep_info_t));
+ struct4 = (struct small_rep_info_t *)malloc(sizeof(struct small_rep_info_t));
+ flags = (struct bit_flags_t *)malloc(sizeof(struct bit_flags_t));
+ flags_combo = (struct bit_flags_combo_t *)malloc(sizeof(struct bit_flags_combo_t));
+ three_char = (struct three_char_t *)malloc(sizeof(struct three_char_t));
+ five_char = (struct five_char_t *)malloc(sizeof(struct five_char_t));
+ int_char_combo = (struct int_char_combo_t *)malloc(sizeof(struct int_char_combo_t));
+
+ d1 = (struct one_double_t *)malloc(sizeof(struct one_double_t));
+ d2 = (struct one_double_t *)malloc(sizeof(struct one_double_t));
+ d3 = (struct one_double_t *)malloc(sizeof(struct one_double_t));
+
+ f1 = (struct two_floats_t *)malloc(sizeof(struct two_floats_t));
+ f2 = (struct two_floats_t *)malloc(sizeof(struct two_floats_t));
+ f3 = (struct two_floats_t *)malloc(sizeof(struct two_floats_t));
+
+ /* Initialize small structures
+ */
+ init_small_structs ( struct1, struct2, struct3, struct4, flags,
+ flags_combo, three_char, five_char, int_char_combo,
+ d1, d2, d3, f1, f2, f3);
+
+ /* Print small structures
+ */
+ print_small_structs ( *struct1, *struct2, *struct3, *struct4, *flags,
+ *flags_combo, *three_char, *five_char, *int_char_combo,
+ *d1, *d2, *d3, *f1, *f2, *f3);
+
+ /* Print a very long arg list
+ */
+ a = 22.25;
+ b = 33.375;
+ c = 0;
+ d = -25;
+ e = 100;
+ f = 2345;
+
+ print_long_arg_list ( a, b, c, d, e, f, *struct1, *struct2, *struct3, *struct4,
+ *flags, *flags_combo, *three_char, *five_char, *int_char_combo,
+ *d1, *d2, *d3, *f1, *f2, *f3);
+
+ /* Initialize small structures
+ */
+ init_one_double ( d1, 1.11111);
+ init_one_double ( d2, -345.34);
+ init_one_double ( d3, 546464.2);
+ init_two_floats ( f1, 0.234, 453.1);
+ init_two_floats ( f2, 78.345, 23.09);
+ init_two_floats ( f3, -2.345, 1.0);
+ init_bit_flags(flags, (unsigned)1, (unsigned)0, (unsigned)1,
+ (unsigned)0, (unsigned)1, (unsigned)0 );
+ init_bit_flags_combo(flags_combo, (unsigned)1, (unsigned)0, 'y',
+ (unsigned)1, (unsigned)0, 'n',
+ (unsigned)1, (unsigned)0 );
+ init_three_chars(three_char, 'x', 'y', 'z');
+ init_five_chars(five_char, 'h', 'e', 'l', 'l', 'o');
+ init_int_char_combo(int_char_combo, 13, '!');
+ init_struct_rep(struct1, 10);
+ init_struct_rep(struct2, 20);
+ init_struct_rep(struct3, 30);
+ init_struct_rep(struct4, 40);
+
+ compute_with_small_structs(35);
+ loop_count();
+ printf("HELLO WORLD\n");
+ printf("BYE BYE FOR NOW\n");
+ printf("VERY GREEN GRASS\n");
+
+ /* Print small structures
+ */
+ print_one_double(*d1);
+ print_one_double(*d2);
+ print_one_double(*d3);
+ print_two_floats(*f1);
+ print_two_floats(*f2);
+ print_two_floats(*f3);
+ print_bit_flags(*flags);
+ print_bit_flags_combo(*flags_combo);
+ print_three_chars(*three_char);
+ print_five_chars(*five_char);
+ print_int_char_combo(*int_char_combo);
+ sum_struct_print(10, *struct1, *struct2, *struct3, *struct4);
+ print_struct_rep(*struct1, *struct2, *struct3);
+
+ return 0;
+}
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.base/call-ar-st.exp b/gdb/testsuite/gdb.base/call-ar-st.exp
new file mode 100644
index 00000000000..d9bb350f8d1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/call-ar-st.exp
@@ -0,0 +1,705 @@
+# Copyright 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "call-ar-st"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Test depends on printf, which the sparclet stub doesn't support.
+if { [istarget "sparclet-*-*"] } {
+ return 0;
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+# Some targets can't call functions, so don't even bother with this
+# test.
+if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ continue
+}
+
+set oldtimeout $timeout
+set timeout [expr "$timeout + 60"]
+
+# Set the current language to C. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_c {} {
+ global gdb_prompt
+
+ send_gdb "set language c\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language c (timeout)" ; return 0; }
+ }
+
+ send_gdb "show language\n"
+ gdb_expect {
+ -re ".* source language is \"c\".*$gdb_prompt $" {
+ pass "set language to \"c\""
+ return 1
+ }
+ -re ".*$gdb_prompt $" {
+ fail "setting language to \"c\""
+ return 0
+ }
+ timeout {
+ fail "can't show language (timeout)"
+ return 0
+ }
+ }
+}
+
+source ${binfile}.ci
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+send_gdb "set print sevenbit-strings\n" ; gdb_expect -re "$gdb_prompt $"
+send_gdb "set print address off\n" ; gdb_expect -re "$gdb_prompt $"
+send_gdb "set width 0\n" ; gdb_expect -re "$gdb_prompt $"
+
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+#go -until 1209
+gdb_test "tbreak 1209" \
+ "Breakpoint \[0-9\]+.*file.*$srcfile, line 1209.*" \
+ "tbreakpoint line 1209"
+
+gdb_test continue \
+"Continuing\\..*main \\(\\) at.*$srcfile:1209.*" \
+"run until breakpoint set at a line"
+
+
+#call print_double_array(double_array)
+if {![gdb_skip_float_test "print print_double_array(double_array)"] && \
+ ![gdb_skip_stdio_test "print print_double_array(double_array)"] } {
+ send_gdb "print print_double_array(double_array)\n"
+ gdb_expect_list "print print_double_array(double_array)" ".*$gdb_prompt $" {
+ "\[ \t\r\n\]+array_d :"
+ "\[ \t\r\n\]+========="
+ "\[ \t\r\n\]+0.000000"
+ "\[ \t\r\n\]+23.456700 46.913400 70.370100 93.826800 117.283500 140.740200 164.196900 187.653600"
+ "\[ \t\r\n\]+"
+ }
+}
+
+#call print_char_array(char_array)
+
+if ![gdb_skip_stdio_test "print_char_array(char_array)"] {
+ send_gdb "print print_char_array(char_array)\n"
+ gdb_expect_list "print print_char_array(char_array)" ".*$gdb_prompt $" {
+ "\[ \t\r\n\]+array_c :"
+ "\[ \t\r\n\]+========="
+ "\[ \t\r\n\]+\[ \t\r\n\]+Z"
+ "\[ \t\r\n\]+aZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZ"
+ "\[ \t\r\n\]+aZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZ"
+ "\[ \t\r\n\]+aZaZaZaZaZaZaZaZaZa\[ \t\r\n\]+\[ \t\r\n\]+"
+ }
+}
+
+
+
+
+#go -until 1216
+gdb_test "tbreak 1216" \
+"Breakpoint.*file.*$srcfile, line 1216.*" \
+"tbreakpoint line 1216"
+
+if ![gdb_skip_stdio_test "continue to 1216"] {
+ send_gdb "continue\n"
+ gdb_expect_list "continue to 1216" ".*$gdb_prompt $" {
+ "\[ \t\r\n\]+array_c :"
+ "\[ \t\r\n\]+========="
+ "\[ \t\r\n\]+\[ \t\r\n\]+Z"
+ "\[ \t\r\n\]+aZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZ"
+ "\[ \t\r\n\]+aZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZ"
+ "\[ \t\r\n\]+aZaZaZaZaZaZaZaZaZa"
+ "\[ \t\r\n\]+main.*at.*:1216"
+ "\[ \t\r\n\]+1216.*print_double_array\\(double_array\\)"
+ }
+} else {
+ gdb_test "continue" "" ""
+}
+
+# I am disabling this test, because it takes too long. I verified by
+# hand that it works, feel free to check for yourself.
+#call print_all_arrays(integer_array, char_array, float_array, double_array)
+#send_gdb "print print_all_arrays(integer_array, char_array, float_array, double_array)\n"
+#gdb_expect {
+# -re ".*array_i :\[ \t\r\n\]+=========\[ \t\r\n\]+\[ \t\r\n\]+0\[ \t\r\n\]+-1 -2 -3 -4 -5 -6 -7 -8\[ \t\r\n\]+-9 -10 -11 -12 -13 -14 -15 -16\[ \t\r\n\]+-17 -18 -19 -20 -21 -22 -23 -24\[ \t\r\n\]+-25 -26 -27 -28 -29 -30 -31 -32\[ \t\r\n\]+-33 -34 -35 -36 -37 -38 -39 -40\[ \t\r\n\]+-41 -42 -43 -44 -45 -46 -47 -48\[ \t\r\n\]+-49\[ \t\r\n\]+\[ \t\r\n\]+array_c :\[ \t\r\n\]+=========\[ \t\r\n\]+\[ \t\r\n\]+Z\[ \t\r\n\]+aZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZ\[ \t\r\n\]+aZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZ\[ \t\r\n\]+aZaZaZaZaZaZaZaZaZa\[ \t\r\n\]+\[ \t\r\n\]+array_f :\[ \t\r\n\]+=========\[ \t\r\n\]+\[ \t\r\n\]+0.000000\[ \t\r\n\]+0.142450 0.284900 0.427350 0.569801 0.712251 0.854701 0.997151 1.139601\[ \t\r\n\]+1.282051 1.424501 1.566952 1.709402 1.851852 1.994302\[ \t\r\n\]+\[ \t\r\n\]+array_d :\[ \t\r\n\]+=========\[ \t\r\n\]+\[ \t\r\n\]+0.000000\[ \t\r\n\]+23.456700 46.913400 70.370100 93.826800 117.283500 140.740200 164.196900 187.653600\[ \t\r\n\]+211.110300 234.567000 258.023700 281.480400 304.937100 328.393800 351.850500 375.307200\[ \t\r\n\]+398.763900 422.220600 445.677300 469.134000 492.590700 516.047400 539.504100 562.960800\[ \t\r\n\]+586.41750 609.874200 633.330900 656.787600 680.244300 703.701000 727.157700 750.614400\[ \t\r\n\]+774.071100 797.527800 820.984500 844.441200 867.897900 891.354600 914.811300 938.268000\[ \t\r\n\]+961.724700 985.181400 1008.638100 1032.094800 1055.551500 1079.008200 1102.464900 1125.921600\[ \t\r\n\]+1149.378300 1172.835000 1196.291700 1219.748400 1243.205100 1266.661800 1290.118500 1313.575200\[ \t\r\n\]+1337.031900 1360.488600 1383.945300 1407.402000 1430.858700 1454.315400 1477.772100 1501.228800\[ \t\r\n\]+1524.685500 1548.142200 1571.598900 1595.055600 1618.512300 1641.969000 1665.425700 1688.882400\[ \t\r\n\]+1712.339100 1735.795800 1759.252500 1782.709200 1806.165900 1829.622600 1853.079300 1876.536000\[ \t\r\n\]+1899.992700 1923.449400 1946.906100 1970.362800 1993.819500 2017.276200 2040.732900 2064.189600\[ \t\r\n\]+2087.646300 2111.103000 2134.559700 2158.016400 2181.473100 2204.929800 2228.386500 2251.843200\[ \t\r\n\]+2275.299900 2298.756600 2322.213300.*$gdb_prompt $" {
+# pass "print print_all_arrays(integer_array, char_array, float_array, double_array)"
+# }
+# -re ".*$gdb_prompt $" { fail "print print_all_arrays(integer_array, char_array, float_array, double_array)" }
+# timeout { fail "(timeout) print print_all_arrays(integer_array, char_array, float_array, double_array)" }
+# }
+
+#set timeout $oldtimeout
+#go -until 1220
+gdb_test "tbreak 1220" \
+ "Breakpoint.* file .*$srcfile, line 1220.*" \
+ "tbreakpoint line 1220"
+
+if {![gdb_skip_float_test "continuing to breakpoint 1220"] && \
+ ![gdb_skip_stdio_test "continuing to breakpoint 1220"] } {
+ send_gdb "continue\n"
+ gdb_expect_list "continuing to breakpoint 1220" ".*$gdb_prompt $" {
+ "Continuing\\."
+ "\[ \t\r\n\]+array_d :"
+ "\[ \t\r\n\]+========="
+ "\[ \t\r\n\]+0.000000"
+ "\[ \t\r\n\]+23.456700 46.913400 70.370100 93.826800 117.283500 140.740200 164.196900 187.653600"
+ "\[ \t\r\n\]+"
+ ".*array_f :"
+ ".*student id :\[\t \]+.*YELLOW"
+ ".*array_i :"
+ ".*main \\(\\) at .*call-ar-st.c:1220\[ \t\r\n\]+.*print_all_arrays\\(integer_array, char_array, float_array, double_array\\)."
+ }
+} else {
+ gdb_test "continue" "" ""
+}
+
+#step
+send_gdb "step\n"
+gdb_expect {
+ -re "print_all_arrays \\(array_i=, array_c=.ZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZaZa., array_f=, array_d=\\) at .*call-ar-st.c:306\[ \t\r\n\]+306.*print_int_array\\(array_i\\);.*$gdb_prompt $" {pass "step inside print_all_arrays"}
+ -re ".*$gdb_prompt $" { fail "step inside print_all_arrays" }
+ timeout { fail "step inside print_all_arrays (timeout)" }
+}
+
+
+#step -over
+if ![gdb_skip_stdio_test "next over print_int_array in print_all_arrays"] {
+ send_gdb "next\n"
+ gdb_expect {
+ -re "array_i :.*307.*print_char_array.*$gdb_prompt $" {
+ pass "next over print_int_array in print-all_arrays"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "next over print_int_array in print-all_arrays"
+ }
+ timeout {
+ fail "next over print_int_array in print-all_arrays (timeout)"
+ }
+ }
+} else {
+ gdb_test "next" "" ""
+}
+
+#call print_double_array(array_d)
+if {![gdb_skip_float_test "print print_double_array(array_d)"] && \
+ ![gdb_skip_stdio_test "print print_double_array(array_d)"] } {
+ send_gdb "print print_double_array(array_d)\n"
+ gdb_expect_list "print print_double_array(array_d)" ".*$gdb_prompt $" {
+ "array_d :"
+ "\[ \t\r\n\]+========="
+ "\[ \t\r\n\]+\[ \t\r\n\]+0.000000"
+ "\[ \t\r\n\]+23.456700 46.913400 70.370100 93.826800 117.283500 140.740200 164.196900 187.653600"
+ "\[ \t\r\n\]+"
+ }
+}
+
+#go -until 1236
+gdb_test "tbreak 1236" \
+"Breakpoint.* file .*$srcfile, line 1236.*" \
+"tbreakpoint line 1236"
+
+if {![gdb_skip_float_test "continuing to 1236"] && \
+ ![gdb_skip_stdio_test "continuing to 1236"] } {
+ send_gdb "continue\n"
+ gdb_expect_list "continuing to 1236" ".*$gdb_prompt $" {
+ "Continuing\\..*array_c"
+ ".*array_f"
+ "\[ \t\r\n\]+array_d :"
+ "\[ \t\r\n\]+========="
+ "\[ \t\r\n\]+0.000000"
+ "\[ \t\r\n\]+23.456700 46.913400 70.370100 93.826800 117.283500 140.740200 164.196900 187.653600"
+ "\[ \t\r\n\]+.*HELLO WORLD.*main \\(\\) at .*call-ar-st.c:1236.*printf\\(.BYE BYE FOR NOW.n.\\)."
+ }
+} else {
+ gdb_test "continue" "" ""
+}
+
+
+#call sum_array_print(10, *list1, *list2, *list3, *list4)
+
+if ![gdb_skip_stdio_test "print sum_array_print(...)"] {
+ send_gdb "print sum_array_print(10, *list1, *list2, *list3, *list4)\n"
+ gdb_expect {
+ -re ".*Sum of 4 arrays, by element \\(add in seed as well\\):\[ \t\r\n\]+Seed: 10\[ \t\r\n\]+Element Index . Sum\[ \t\r\n\]+-------------------------\[ \t\r\n\]+.*\[ \t\]+0\[ \t\]+52\[ \t\r\n\]+1\[ \t\]+60\[ \t\r\n\]+2\[ \t\]+68\[ \t\r\n\]+3\[ \t\]+76\[ \t\r\n\]+4\[ \t\]+84\[ \t\r\n\]+5\[ \t\]+92\[ \t\r\n\]+6\[ \t\]+100\[ \t\r\n\]+7\[ \t\]+108\[ \t\r\n\]+8\[ \t\]+116\[ \t\r\n\]+9\[ \t\]+124\[ \t\r\n\]+.*$gdb_prompt $" {
+ pass "print sum_array_print(10, *list1, *list2, *list3, *list4)"
+ }
+ -re ".*$gdb_prompt $" { fail "print sum_array_print(10, *list1, *list2, *list3, *list4)" }
+ timeout { fail "(timeout) print sum_array_print(10, *list1, *list2, *list3, *list4)" }
+ }
+}
+
+#step over
+if ![gdb_skip_stdio_test "next to 1237"] {
+ send_gdb "next\n"
+ gdb_expect {
+ -re ".*BYE BYE FOR NOW.*1237.*printf\\(.VERY GREEN GRASS.n.\\);.*$gdb_prompt $" { pass "next to 1237"}
+ -re ".*$gdb_prompt $" { fail "next to 1237" }
+ timeout { fail "next to 1237(timeout)" }
+ }
+} else {
+ gdb_test "next" "" ""
+}
+
+#call print_array_rep(\*list1, \*list2, \*list3)
+
+if ![gdb_skip_stdio_test "print print_array_rep(...)"] {
+ send_gdb "print print_array_rep(\*list1, \*list2, \*list3)\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {
+ pass "print print_array_rep(*list1, *list2, *list3)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "print print_array_rep(*list1, *list2, *list3)"
+ }
+ timeout {
+ fail "(timeout) print print_array_rep(*list1, *list2, *list3)"
+ }
+ }
+}
+
+#go -until 1241
+gdb_test "tbreak 1241" \
+ "Breakpoint..* file .*$srcfile, line 1241.*" \
+ "tbreakpoint line 1241"
+
+send_gdb "continue\n"
+gdb_expect {
+ -re ".*main \\(\\) at .*call-ar-st.c:1241\r\n1241\[\t \]+sum_array_print\\(10, \\*list1, \\*list2, \\*list3, \\*list4\\);.*$gdb_prompt $" {
+ pass "continue to 1241"}
+ -re ".*$gdb_prompt $" { fail "continue to 1241"}
+ timeout { fail "(timeout) continue to 1241"}
+}
+
+
+
+# Run into sum_array_print, and verify that the arguments were passed
+# accurately.
+#
+# Note that we shouldn't use a `step' here to get into
+# sum_array_print; GCC may emit calls to memcpy to put the arguments
+# in the right place, and a step may end up in memcpy instead. This
+# may itself be a bug, but it's not the one we're trying to catch
+# here. I've added something to step-test.exp for this.
+gdb_test "break sum_array_print" \
+ ".*Breakpoint ${decimal}: file .*call-ar-st.c, line.*" \
+ "set breakpoint in sum_array_print"
+gdb_test "continue" \
+ ".*Breakpoint ${decimal}, sum_array_print \\(seed=10, linked_list1=.next_index = .1, 2, 3, 4, 5, 6, 7, 8, 9, 10., values = .4, 6, 8, 10, 12, 14, 16, 18, 20, 22., head = 0., linked_list2=.next_index = .1, 2, 3, 4, 5, 6, 7, 8, 9, 10., values = .8, 10, 12, 14, 16, 18, 20, 22, 24, 26., head = 0., linked_list3=.next_index = .1, 2, 3, 4, 5, 6, 7, 8, 9, 10., values = .10, 12, 14, 16, 18, 20, 22, 24, 26, 28., head = 0., linked_list4=.next_index = .1, 2, 3, 4, 5, 6, 7, 8, 9, 10., values = .20, 22, 24, 26, 28, 30, 32, 34, 36, 38., head = 0.\\) at .*call-ar-st.c:1105\[ \t\n\r\]+1105.*printf\\(.Sum of 4 arrays, by element \\(add in seed as well\\).*\\);.*" \
+ "check args of sum_array_print"
+
+#call print_array_rep(linked_list1, linked_list2, linked_list3)
+# this calls works from gdb without gdb_expect. But it does seem to hang
+#from within gdb_expect.
+#I comment this out
+#send_gdb "print print_array_rep(linked_list1, linked_list2, linked_list3)\n"
+#gdb_expect {
+# -re ".*Contents of linked list1:\[ \t\n\r\]+Element Value . Index of Next Element\[ \t\n\r\]+-------------------------------------\[ \t\n\r\]+.*\[ \t\n\r\]+.*4.*1\[ \t\n\r\]+.*6.*2\[ \t\n\r\]+.*8.*3\[ \t\n\r\]+.*10.*4\[ \t\n\r\]+.*12.*5\[ \t\n\r\]+.*14.*6\[ \t\n\r\]+.*16.*7\[ \t\n\r\]+.*18.*8\[ \t\n\r\]+.*20.*9\[ \t\n\r\]+.*22.*10\[ \t\n\r\]+Contents of linked list2:\[ \t\n\r\]+Element Value | Index of Next Element\[ \t\n\r\]+-------------------------------------\[ \t\n\r\]+.*\[ \t\n\r\]+.*8.*1\[ \t\n\r\]+.*10.*2\[ \t\n\r\]+.*12.*3\[ \t\n\r\]+.*14.*4\[ \t\n\r\]+.*16.*5\[ \t\n\r\]+.*18.*6\[ \t\n\r\]+.*20.*7\[ \t\n\r\]+.*22.*8\[ \t\n\r\]+.*24.*9\[ \t\n\r\]+.*26.*10\[ \t\n\r\]+Contents of linked list3:\[ \t\n\r\]+Element Value | Index of Next Element\[ \t\n\r\]+-------------------------------------\[ \t\n\r\]+.*\[ \t\n\r\]+.*10.*1\[ \t\n\r\]+.*12.*2\[ \t\n\r\]+.*14.*3\[ \t\n\r\]+.*16.*4\[ \t\n\r\]+.*18.*5\[ \t\n\r\]+.*20.*6\[ \t\n\r\]+.*22.*7\[ \t\n\r\]+.*24.*8\[ \t\n\r\]+.*26.*9\[ \t\n\r\]+.*28.*10\[ \t\n\r\]+.*$gdb_prompt $" {
+# pass "print print_array_rep(linked_list1, linked_list2, linked_list3)"
+# }
+# -re ".*$gdb_prompt $" { fail "print print_array_rep(linked_list1, linked_list2, linked_list3)" }
+# timeout { fail "(timeout) print print_array_rep(linked_list1, linked_list2, linked_list3)" }
+#}
+
+
+#go -until 1281
+gdb_test "tbreak 1281" \
+ "Breakpoint.* file .*call-ar-st.c, line 1281.*" \
+ "tbreakpoint line 1281"
+
+if ![gdb_skip_stdio_test "continuing to 1281"] {
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Continuing\\..*Sum of 4 arrays.*Contents of linked list1.*Contents of two_floats_t.*main \\(\\) at .*call-ar-st.c:1281.*c = 0.*$gdb_prompt $" {
+ pass "continue to 1281"
+ }
+ -re ".*$gdb_prompt $" { fail "continue to 1281"}
+ timeout { fail "(timeout) continue to 1281"}
+ }
+} else {
+ gdb_test "continue" "" ""
+}
+
+#call print_small_structs(*struct1, *struct2, *struct3, *struct4,
+# *flags, *flags_combo, *three_char, *five_char,
+# *int_char_combo, *d1, *d2, *d3, *f1, *f2, *f3)
+
+if {![gdb_skip_float_test "print print_small_structs(...)"] && \
+ ![gdb_skip_stdio_test "print print_small_structs(...)"] } {
+ send_gdb "print print_small_structs(*struct1, *struct2, *struct3, *struct4, *flags, *flags_combo, *three_char, *five_char, *int_char_combo, *d1, *d2, *d3, *f1, *f2, *f3)\n"
+ gdb_expect_list "print print_small_structs" ".*$gdb_prompt $" {
+ "\[\t\r\n \]+alpha"
+ "\[\t\r\n \]+gamma"
+ "\[\t\r\n \]+epsilon"
+ "\[\t\r\n \]+alpha"
+ "\[\t\r\n \]+gamma"
+ "\[\t\r\n \]+epsilon"
+ "\[\t\r\n \]+ch1: y[ \t]*ch2: n"
+ "\[\t\r\n \]+Contents of three_char_t:"
+ "\[\t\r\n \]+a[ \t]*b[ \t]*c"
+ "\[\t\r\n \]+Contents of five_char_t:"
+ "\[\t\r\n \]+l[ \t]*m[ \t]*n[ \t]*o[ \t]*p"
+ "\[\t\r\n \]+Contents of int_char_combo_t:"
+ "\[\t\r\n \]+123[ \t]*z"
+ "\[\t\r\n \]+Sum of the 4 struct values and seed :"
+ "\[\t\r\n \]+52"
+ "\[\t\r\n \]+Contents of struct1:"
+ "\[\t\r\n \]+6[ \t]*0"
+ "\[\t\r\n \]+Contents of struct2:"
+ "\[\t\r\n \]+10[ \t]*0"
+ "\[\t\r\n \]+Contents of struct3:"
+ "\[\t\r\n \]+12[ \t]*0"
+ "\[\t\r\n \]+Contents of one_double_t:"
+ "\[\t\r\n \]+10.500000"
+ "\[\t\r\n \]+Contents of one_double_t:"
+ "\[\t\r\n \]+-3.375000"
+ "\[\t\r\n \]+Contents of one_double_t:"
+ "\[\t\r\n \]+675.093750"
+ "\[\t\r\n \]+Contents of two_floats_t:"
+ "\[\t\r\n \]+45.234001[ \t]*43.599998"
+ "\[\t\r\n \]+Contents of two_floats_t:"
+ "\[\t\r\n \]+78.010002[ \t]*122.099998"
+ "\[\t\r\n \]+Contents of two_floats_t:"
+ "\[\t\r\n \]+-1232.344971[ \t]*-199.210007"
+ }
+}
+
+#call compute_with_small_structs(20)
+send_gdb "print compute_with_small_structs(20)\n"
+gdb_expect {
+ -re ".*\[0-9\]+ =.*$gdb_prompt $" {
+ pass "print compute_with_small_structs(20)"
+ }
+ -re ".*$gdb_prompt $" { fail "print compute_with_small_structs(20)" }
+ timeout { fail "(timeout) compute_with_small_structs(20)" }
+ }
+
+
+#call print_ten_doubles(123.456, 123.456, -0.12, -1.23, 343434.8, 89.098,
+# 3.14, -5678.12345, -0.11111111, 216.97065)
+
+if {![gdb_skip_float_test "print print_ten_doubles(...)"] && \
+ ![gdb_skip_stdio_test "print print_ten_doubles(...)"]} {
+ send_gdb "print print_ten_doubles(123.456, 123.456, -0.12, -1.23, 343434.8, 89.098, 3.14, -5678.12345, -0.11111111, 216.97065)\n"
+ gdb_expect_list "print print_ten_doubles" ".*$gdb_prompt $" {
+ "\[\t\r\n \]+Two Doubles : 123.456000.*123.456000"
+ "\[\t\r\n \]+Two Doubles : -0.120000.*-1.230000"
+ "\[\t\r\n \]+Two Doubles : 343434.800000.*89.098000"
+ "\[\t\r\n \]+Two Doubles : 3.140000.*-5678.123450"
+ "\[\t\r\n \]+Two Doubles : -0.111111.*216.970650"
+ }
+}
+
+#go -until 1286
+gdb_test "tbreak 1286" \
+ "Breakpoint .* file .*call-ar-st.c, line 1286.*" \
+ "tbreakpoint line 1286"
+
+gdb_test continue "Continuing\\..*main \\(.*\\) at.*call-ar-st.c:1286\[\t\r\n \]+1286.*print_long_arg_list \\( a, b, c, d, e, f, .struct1, .struct2, .struct3, .struct4,.*" "continue to 1286"
+
+if { [istarget "hppa*-*-hpux*"] } {
+ #
+ # NOTE:(FIXME)
+ # the aCC demangler cannot demangle the name of a function with >10 args.
+ # so I added a .* after the name of the function, to match the
+ # incredibly long mangled name
+ # (getting aCC's libdemangle.a bundled w/ the system?)
+ # DTS CLLbs16994 coulter 990114
+ #
+ # FIXME: use step for hppa* testing for now
+ # guo 990621
+ #
+ send_gdb "step\n"
+ gdb_expect {
+ -re ".*print_long_arg_list.*\\(a=22.25, b=33.375, c=0, d=-25, e=100, f=2345, struct1=\{value = 6, head = 0\}, struct2=\{value = 10, head = 0\}, struct3=\{value = 12, head = 0\}, struct4=\{value = 14, head = 0\}, flags=\{alpha = 1, beta = 0, gamma = 1, delta = 0, epsilon = 1, omega = 0\}, flags_combo=\{alpha = 1, beta = 0, ch1 = 121 \'y\', gamma = 1, delta = 0, ch2 = 110 \'n\', epsilon = 1, omega = 0\}, three_char=\{ch1 = 97 \'a\', ch2 = 98 \'b\', ch3 = 99 \'c\'\}, five_char=\{ch1 = 108 \'l\', ch2 = 109 \'m\', ch3 = 110 \'n\', ch4 = 111 \'o\', ch5 = 112 \'p\'\}, int_char_combo=\{int1 = 123, ch1 = 122 \'z\'\}, d1=\{double1 = 10.5\}, d2=\{double1 = -3.375\}, d3=\{double1 = 675.09375\}, f1=\{float1 = 45.2340012, float2 = 43.5999985\}, f2=\{float1 = 78.0100021, float2 = 122.099998\}, f3=\{float1 = -1232.34497, float2 = -199.210007\}\\) at .*${srcfile}:992\[\r\n\]+992\[ \t\]+printf\\(\"double :.*\", a\\);.*$gdb_prompt $" {pass "step into print_long_arg_list"}
+ -re ".*$gdb_prompt $" { fail "step into print_long_arg_list" }
+ timeout { fail "step into print_long_arg_list (timeout)" }
+ }
+} else {
+
+ # We can't just assume that a "step" will get us into
+ # print_long_arg_list here,either.
+ gdb_test "tbreak print_long_arg_list" \
+ "Breakpoint .* file .*call-ar-st.c, line .*" \
+ "tbreak in print_long_arg_list after stepping into memcpy"
+ # The short match case below handles cases where a buffer
+ # overflows or something, and expect can't deal with the full
+ # line. Perhaps a more elegant solution exists... -sts 1999-08-17
+ send_gdb "continue\n"
+ if {![gdb_skip_float_test "step into print_long_arg_list"]} {
+ gdb_expect {
+ -re ".*print_long_arg_list \\(a=22.25, b=33.375, c=0, d=-25, e=100, f=2345, struct1=\{value = 6, head = 0\}, struct2=\{value = 10, head = 0\}, struct3=\{value = 12, head = 0\}, struct4=\{value = 14, head = 0\}, flags=\{alpha = 1, beta = 0, gamma = 1, delta = 0, epsilon = 1, omega = 0\}, flags_combo=\{alpha = 1, beta = 0, ch1 = 121 \'y\', gamma = 1, delta = 0, ch2 = 110 \'n\', epsilon = 1, omega = 0\}, three_char=\{ch1 = 97 \'a\', ch2 = 98 \'b\', ch3 = 99 \'c\'\}, five_char=\{ch1 = 108 \'l\', ch2 = 109 \'m\', ch3 = 110 \'n\', ch4 = 111 \'o\', ch5 = 112 \'p\'\}, int_char_combo=\{int1 = 123, ch1 = 122 \'z\'\}, d1=\{double1 = 10.5\}, d2=\{double1 = -3.375\}, d3=\{double1 = 675.09375\}, f1=\{float1 = 45.2340012, float2 = 43.5999985\}, f2=\{float1 = 78.0100021, float2 = 122.099998\}, f3=\{float1 = -1232.34497, float2 = -199.210007\}\\) at .*${srcfile}:992\[\r\n\]+992\[ \t\]+printf\\(\"double :.*\", a\\);.*$gdb_prompt $" { pass "step into print_long_arg_list" }
+ -re ".*print_long_arg_list.*\\(a=22.25, b=33.375, c=0, d=-25, e=100, f=2345, struct1=\{value = 6, head = 0\}, struct2=\{value = 10, head = 0\}, struct3=\{value = 12, head = 0\}, struct4=\{value = 14, head = 0\}, flags=\{alpha = 1, beta = 0, gamma = 1, delta = 0, epsilon = 1, omega = 0\}, flags_combo=\{alpha = 1, beta = 0, ch1 = 121 \'y\', gamma = 1, delta = 0, ch2 = 110 \'n\', epsilon = 1, omega = 0\}, three_char=\{ch1 = 97 \'a\', ch2 = 98 \'b\', ch3 = 99 \'c\'\}.*\\) at .*${srcfile}:992\[\r\n\]+992\[ \t\]+printf\\(\"double :.*\", a\\);.*$gdb_prompt $" {pass "step into print_long_arg_list (short match)"}
+ -re ".*$gdb_prompt $" { fail "step into print_long_arg_list" }
+ timeout { fail "step into print_long_arg_list (timeout)" }
+ }
+ } else {
+ # If skipping float tests, don't expect anything in arg list.
+ gdb_expect {
+ -re ".*print_long_arg_list \\(.*\\).*$gdb_prompt $" { pass "step into print_long_arg_list" }
+ -re ".*$gdb_prompt $" { fail "step into print_long_arg_list" }
+ timeout { fail "step into print_long_arg_list (timeout)" }
+ }
+ }
+}
+
+set ws "\[\n\r\t \]+"
+
+#call print_small_structs(struct1, struct2, struct3, struct4, flags,
+# flags_combo, three_char, five_char, int_char_combo,
+# d1, d2, d3, f1, f2, f3)
+
+if {![gdb_skip_float_test "print_small_structs from print_long_arg_list"] && \
+ ![gdb_skip_stdio_test "print_small_structs from print_long_arg_list"] } {
+ # On Solaris, some of the args are passed by ref, others by value,
+ # and GDB gets confused and says "Invalid cast" because it thinks
+ # it has to cast the structure into a pointer to structure. A real
+ # GDB bug, probably for all Sparc configs, but obscure. -sts 1999-08-17.
+ setup_xfail "sparc*-*-solaris*"
+ send_gdb "print print_small_structs(struct1, struct2, struct3, struct4, flags, flags_combo, three_char, five_char, int_char_combo, d1, d2, d3, f1, f2, f3)\n"
+ gdb_expect_list "print print_small_structs from print_long_arg_list" ".*$gdb_prompt $" {
+ "\[\t\r\n \]+alpha"
+ "\[\t\r\n \]+gamma"
+ "\[\t\r\n \]+epsilon"
+ "\[\t\r\n \]+alpha"
+ "\[\t\r\n \]+gamma"
+ "\[\t\r\n \]+epsilon"
+ "\[\t\r\n \]+ch1: y[ \t]*ch2: n"
+ "\[\t\r\n \]+Contents of three_char_t:"
+ "\[\t\r\n \]+a\[ \t\]*b\[ \t\]*c"
+ "\[\t\r\n \]+Contents of five_char_t:"
+ "\[\t\r\n \]+l\[ \t\]*m\[ \t\]*n\[ \t\]*o\[ \t\]*p"
+ "\[\t\r\n \]+Contents of int_char_combo_t:"
+ "\[\t\r\n \]+123\[ \t\]*z"
+ "\[\t\r\n \]+Sum of the 4 struct values and seed :"
+ "\[\t\r\n \]+52"
+ "\[\t\r\n \]+Contents of struct1:"
+ "\[\t\r\n \]+6\[ \t\]*0"
+ "\[\t\r\n \]+Contents of struct2:"
+ "\[\t\r\n \]+10\[ \t\]*0"
+ "\[\t\r\n \]+Contents of struct3:"
+ "\[\t\r\n \]+12\[ \t\]*0"
+ "\[\t\r\n \]+Contents of one_double_t:"
+ "\[\t\r\n \]+10.500000"
+ "\[\t\r\n \]+Contents of one_double_t:"
+ "\[\t\r\n \]+-3.375000"
+ "\[\t\r\n \]+Contents of one_double_t:"
+ "\[\t\r\n \]+675.093750"
+ "\[\t\r\n \]+Contents of two_floats_t:"
+ "\[\t\r\n \]+45.234001\[ \t\]*43.599998"
+ "\[\t\r\n \]+Contents of two_floats_t:"
+ "\[\t\r\n \]+78.010002\[ \t\]*122.099998"
+ "\[\t\r\n \]+Contents of two_floats_t:"
+ "\[\t\r\n \]+-1232.344971\[ \t\]*-199.210007"
+ }
+}
+
+
+#go -until 1300
+gdb_test "tbreak 1300" \
+ "Breakpoint.* file .*call-ar-st.c, line 1300.*" \
+ "tbreakpoint line 1300"
+
+if ![gdb_skip_stdio_test "continuing to 1300"] {
+ gdb_test "continue" "Continuing\\..*Contents of two_floats_t:.*main \\(\\) at.*call-ar-st.c:1300.*1300.*init_bit_flags_combo\\(flags_combo, \\(unsigned\\)1, \\(unsigned\\)0, .y.,.*" \
+ "continue to 1300"
+} else {
+ gdb_test "continue" "" ""
+}
+
+#step
+ send_gdb "step\n"
+ gdb_expect {
+ -re "
+init_bit_flags_combo \\(bit_flags_combo=, a=1, b=0, ch1=121 .y., g=1, d=0, ch2=110 .n., e=1, o=0\\) at .*call-ar-st.c:416\[ \t\n\r\]+416.*bit_flags_combo->alpha = a;.*$gdb_prompt $" {
+ pass "step into init_bit_flags_combo"}
+ -re ".*$gdb_prompt $" { fail "step into init_bit_flags_combo" }
+ timeout { fail "step into init_bit_flags_combo (timeout)" }
+ }
+
+#call print_bit_flags_combo(*bit_flags_combo)
+if ![gdb_skip_stdio_test "continuing to 1300"] {
+ send_gdb "print print_bit_flags_combo(*bit_flags_combo)\n"
+ gdb_expect {
+ -re ".*alpha.*gamma.*epsilon.*ch1: y.*ch2: n.*$gdb_prompt $" {
+ pass "print print_bit_flags_combo from init_bit_flags_combo"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "print print_bit_flags_combo from init_bit_flags_combo"
+ }
+ timeout {
+ fail "(timeout) print_bit_flags_combo from init_bit_flags_combo"
+ }
+ }
+}
+
+
+#go -until 1305
+gdb_test "tbreak 1305" \
+ "Breakpoint.* file .*call-ar-st.c, line 1305.*" \
+ "tbreakpoint line 1305"
+
+gdb_test continue "Continuing\\..*main \\(\\) at .*call-ar-st.c:1305\[\r\n\t \]+1305.*init_int_char_combo\\(int_char_combo, 13, .!.\\);" \
+"continue to 1305"
+
+#call print_long_arg_list(a, b, c, d, e, f, *struct1, *struct2, *struct3, *struct4, *flags, *flags_combo, *three_char, *five_char, *int_char_combo, *d1, *d2, *d3, *f1, *f2, *f3)
+
+# FIXME:
+# HP aCC demangler currently does not handle hp aCC functions with >10 args
+# DTS CLLbs16994 coulter 990114
+
+if {$hp_aCC_compiler} {setup_xfail "hppa*-*-*" CLLbs16994}
+
+if {![gdb_skip_float_test "print print_long_arg_list"] && \
+ ![gdb_skip_stdio_test "print print_long_arg_list"] } {
+ send_gdb "print print_long_arg_list(a, b, c, d, e, f, *struct1, *struct2, *struct3, *struct4, *flags, *flags_combo, *three_char, *five_char, *int_char_combo, *d1, *d2, *d3, *f1, *f2, *f3)\n"
+ gdb_expect_list "print print_long_arg_list" ".*$gdb_prompt $" {
+ "\[ \n\r\t\]+double : 22.250000"
+ "\[ \n\r\t\]+double : 33.375000"
+ "\[ \n\r\t\]+int : 0"
+ "\[ \n\r\t\]+int : -25"
+ "\[ \n\r\t\]+int : 100"
+ "\[ \n\r\t\]+int : 2345"
+ "\[ \n\r\t\]+alpha"
+ "\[ \n\r\t\]+gamma"
+ "\[ \n\r\t\]+epsilon"
+ "\[ \n\r\t\]+ch1: y\[ \t\]+ch2: n"
+ "\[ \n\r\t\]+Contents of three_char_t:"
+ "\[ \n\r\t\]+x\[ \t\]+y\[ \t\]+z"
+ "\[ \n\r\t\]+Contents of five_char_t:"
+ "\[ \n\r\t\]+h\[ \t\]+e\[ \t\]+l\[ \t\]+l\[ \t\]+o"
+ "\[ \n\r\t\]+Contents of int_char_combo_t:"
+ "\[ \n\r\t\]+123\[ \t\]+z"
+ "\[ \n\r\t\]+Sum of the 4 struct values and seed :"
+ "\[ \n\r\t\]+52"
+ "\[ \n\r\t\]+Contents of struct1:"
+ "\[ \n\r\t\]+6\[ \t\]+0"
+ "\[ \n\r\t\]+Contents of struct2:"
+ "\[ \n\r\t\]+10\[ \t\]+0"
+ "\[ \n\r\t\]+Contents of struct3:"
+ "\[ \n\r\t\]+12\[ \t\]+0"
+ "\[ \n\r\t\]+Contents of one_double_t:"
+ "\[ \n\r\t\]+1.111110"
+ "\[ \n\r\t\]+Contents of one_double_t:"
+ "\[ \n\r\t\]+-345.340000"
+ "\[ \n\r\t\]+Contents of one_double_t:"
+ "\[ \n\r\t\]+546464.200000"
+ "\[ \n\r\t\]+Contents of two_floats_t:"
+ "\[ \n\r\t\]+0.234000\[ \t\]+453.100006"
+ "\[ \n\r\t\]+Contents of two_floats_t:"
+ "\[ \n\r\t\]+78.345001\[ \t\]+23.090000"
+ "\[ \n\r\t\]+Contents of two_floats_t:"
+ "\[ \n\r\t\]+-2.345000\[ \t\]+1.000000"
+ }
+}
+
+
+#go -until 1311
+gdb_test "tbreak 1311" \
+ "Breakpoint.* file .*call-ar-st.c, line 1311.*" \
+ "tbreakpoint line 1311"
+
+gdb_test continue "Continuing\\..*main \\(\\) at .*call-ar-st.c:1311\[ \t\n\r\]+1311.*compute_with_small_structs\\(35\\);" \
+"continue to 1311"
+
+
+#call sum_struct_print(10, *struct1, *struct2, *struct3, *struct4)
+if ![gdb_skip_stdio_test "print sum_struct_print(...)"] {
+ send_gdb "print sum_struct_print(10, *struct1, *struct2, *struct3, *struct4)\n"
+ gdb_expect {
+ -re ".*Sum of the 4 struct values and seed :\[ \t\n\r\]+218.*$gdb_prompt $" {
+ pass "print sum_struct_print(10, *struct1, *struct2, *struct3, *struct4)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "print sum_struct_print(10, *struct1, *struct2, *struct3, *struct4)"
+ }
+ timeout {
+ fail "(timeout) sum_struct_print(10, *struct1, *struct2, *struct3, *struct4)"
+ }
+ }
+}
+
+
+#call print_struct_rep(*struct1, *struct2, *struct3)
+if ![gdb_skip_stdio_test "print print_struct_rep(...)"] {
+ send_gdb "print print_struct_rep(*struct1, *struct2, *struct3)\n"
+ gdb_expect_list "print print_struct_rep(*struct1, *struct2, *struct3)" \
+ ".*$gdb_prompt $" {
+ "\[ \t\n\r\]+Contents of struct1:"
+ "\[ \t\n\r\]+ 22 0"
+ "\[ \t\n\r\]+Contents of struct2:"
+ "\[ \t\n\r\]+ 42 0"
+ "\[ \t\n\r\]+Contents of struct3:"
+ "\[ \t\n\r\]+ 62 0"
+ }
+}
+
+if ![gdb_skip_stdio_test "print print_one_large_struct(...)"] {
+ send_gdb "print print_one_large_struct(*list1)\n"
+ gdb_expect {
+ -re ".* 4 1.*$gdb_prompt $" {
+ pass "print print_one_large_struct(*list1)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "print print_one_large_struct(*list1)"
+ }
+ timeout {
+ fail "(timeout) print_one_large_struct(*list1)"
+ }
+ }
+}
+
+set timeout $oldtimeout
+return
+
diff --git a/gdb/testsuite/gdb.base/call-rt-st.c b/gdb/testsuite/gdb.base/call-rt-st.c
new file mode 100644
index 00000000000..712f70ecbb5
--- /dev/null
+++ b/gdb/testsuite/gdb.base/call-rt-st.c
@@ -0,0 +1,633 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/**************************************************************************
+ * TESTS :
+ * function returning large structures, which go on the stack
+ * functions returning varied sized structs which go on in the registers.
+ ***************************************************************************/
+
+
+/* A large structure (> 64 bits) used to test passing large structures as
+ * parameters
+ */
+
+struct array_rep_info_t {
+ int next_index[10];
+ int values[10];
+ int head;
+};
+
+/*****************************************************************************
+ * Small structures ( <= 64 bits). These are used to test passing small
+ * structures as parameters and test argument size promotion.
+ *****************************************************************************/
+
+ /* 64 bits
+ */
+struct small_rep_info_t {
+ int value;
+ int head;
+};
+
+/* 6 bits : really fits in 8 bits and is promoted to 32 bits
+ */
+struct bit_flags_t {
+ unsigned alpha :1;
+ unsigned beta :1;
+ unsigned gamma :1;
+ unsigned delta :1;
+ unsigned epsilon :1;
+ unsigned omega :1;
+};
+
+/* 22 bits : really fits in 40 bits and is promoted to 64 bits
+ */
+struct bit_flags_combo_t {
+ unsigned alpha :1;
+ unsigned beta :1;
+ char ch1;
+ unsigned gamma :1;
+ unsigned delta :1;
+ char ch2;
+ unsigned epsilon :1;
+ unsigned omega :1;
+};
+
+/* 64 bits
+ */
+struct one_double_t {
+ double double1;
+};
+
+/* 64 bits
+ */
+struct two_floats_t {
+ float float1;
+ float float2;
+};
+
+
+/* 24 bits : promoted to 32 bits
+ */
+struct three_char_t {
+ char ch1;
+ char ch2;
+ char ch3;
+};
+
+/* 40 bits : promoted to 64 bits
+ */
+struct five_char_t {
+ char ch1;
+ char ch2;
+ char ch3;
+ char ch4;
+ char ch5;
+};
+
+/* 40 bits : promoted to 64 bits
+ */
+struct int_char_combo_t {
+ int int1;
+ char ch1;
+};
+
+
+/*****************************************************************
+ * LOOP_COUNT :
+ * A do nothing function. Used to provide a point at which calls can be made.
+ *****************************************************************/
+void loop_count () {
+
+ int index;
+
+ for (index=0; index<4; index++);
+}
+
+/*****************************************************************
+ * INIT_BIT_FLAGS :
+ * Initializes a bit_flags_t structure. Can call this function see
+ * the call command behavior when integer arguments do not fit into
+ * registers and must be placed on the stack.
+ * OUT struct bit_flags_t *bit_flags -- structure to be filled
+ * IN unsigned a -- 0 or 1
+ * IN unsigned b -- 0 or 1
+ * IN unsigned g -- 0 or 1
+ * IN unsigned d -- 0 or 1
+ * IN unsigned e -- 0 or 1
+ * IN unsigned o -- 0 or 1
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_bit_flags (
+struct bit_flags_t *bit_flags,
+unsigned a,
+unsigned b,
+unsigned g,
+unsigned d,
+unsigned e,
+unsigned o)
+#else
+void init_bit_flags (bit_flags,a,b,g,d,e,o)
+struct bit_flags_t *bit_flags;
+unsigned a;
+unsigned b;
+unsigned g;
+unsigned d;
+unsigned e;
+unsigned o;
+#endif
+{
+
+ bit_flags->alpha = a;
+ bit_flags->beta = b;
+ bit_flags->gamma = g;
+ bit_flags->delta = d;
+ bit_flags->epsilon = e;
+ bit_flags->omega = o;
+}
+
+/*****************************************************************
+ * INIT_BIT_FLAGS_COMBO :
+ * Initializes a bit_flags_combo_t structure. Can call this function
+ * to see the call command behavior when integer and character arguments
+ * do not fit into registers and must be placed on the stack.
+ * OUT struct bit_flags_combo_t *bit_flags_combo -- structure to fill
+ * IN unsigned a -- 0 or 1
+ * IN unsigned b -- 0 or 1
+ * IN char ch1
+ * IN unsigned g -- 0 or 1
+ * IN unsigned d -- 0 or 1
+ * IN char ch2
+ * IN unsigned e -- 0 or 1
+ * IN unsigned o -- 0 or 1
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_bit_flags_combo (
+struct bit_flags_combo_t *bit_flags_combo,
+unsigned a,
+unsigned b,
+char ch1,
+unsigned g,
+unsigned d,
+char ch2,
+unsigned e,
+unsigned o)
+#else
+void init_bit_flags_combo (bit_flags_combo, a, b, ch1, g, d, ch2, e, o)
+struct bit_flags_combo_t *bit_flags_combo;
+unsigned a;
+unsigned b;
+char ch1;
+unsigned g;
+unsigned d;
+char ch2;
+unsigned e;
+unsigned o;
+#endif
+{
+
+ bit_flags_combo->alpha = a;
+ bit_flags_combo->beta = b;
+ bit_flags_combo->ch1 = ch1;
+ bit_flags_combo->gamma = g;
+ bit_flags_combo->delta = d;
+ bit_flags_combo->ch2 = ch2;
+ bit_flags_combo->epsilon = e;
+ bit_flags_combo->omega = o;
+}
+
+
+/*****************************************************************
+ * INIT_ONE_DOUBLE :
+ * OUT struct one_double_t *one_double -- structure to fill
+ * IN double init_val
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_one_double ( struct one_double_t *one_double, double init_val)
+#else
+void init_one_double (one_double, init_val)
+struct one_double_t *one_double;
+double init_val;
+#endif
+{
+
+ one_double->double1 = init_val;
+}
+
+/*****************************************************************
+ * INIT_TWO_FLOATS :
+ * OUT struct two_floats_t *two_floats -- structure to be filled
+ * IN float init_val1
+ * IN float init_val2
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_two_floats (
+ struct two_floats_t *two_floats,
+ float init_val1,
+ float init_val2)
+#else
+void init_two_floats (two_floats, init_val1, init_val2)
+struct two_floats_t *two_floats;
+float init_val1;
+float init_val2;
+#endif
+{
+
+ two_floats->float1 = init_val1;
+ two_floats->float2 = init_val2;
+}
+
+/*****************************************************************
+ * INIT_THREE_CHARS :
+ * OUT struct three_char_t *three_char -- structure to be filled
+ * IN char init_val1
+ * IN char init_val2
+ * IN char init_val3
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_three_chars (
+struct three_char_t *three_char,
+char init_val1,
+char init_val2,
+char init_val3)
+#else
+void init_three_chars ( three_char, init_val1, init_val2, init_val3)
+struct three_char_t *three_char;
+char init_val1;
+char init_val2;
+char init_val3;
+#endif
+{
+
+ three_char->ch1 = init_val1;
+ three_char->ch2 = init_val2;
+ three_char->ch3 = init_val3;
+}
+
+/*****************************************************************
+ * INIT_FIVE_CHARS :
+ * OUT struct five_char_t *five_char -- structure to be filled
+ * IN char init_val1
+ * IN char init_val2
+ * IN char init_val3
+ * IN char init_val4
+ * IN char init_val5
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_five_chars (
+struct five_char_t *five_char,
+char init_val1,
+char init_val2,
+char init_val3,
+char init_val4,
+char init_val5)
+#else
+void init_five_chars ( five_char, init_val1, init_val2, init_val3, init_val4, init_val5)
+struct five_char_t *five_char;
+char init_val1;
+char init_val2;
+char init_val3;
+char init_val4;
+char init_val5;
+#endif
+{
+
+ five_char->ch1 = init_val1;
+ five_char->ch2 = init_val2;
+ five_char->ch3 = init_val3;
+ five_char->ch4 = init_val4;
+ five_char->ch5 = init_val5;
+}
+
+/*****************************************************************
+ * INIT_INT_CHAR_COMBO :
+ * OUT struct int_char_combo_t *combo -- structure to be filled
+ * IN int init_val1
+ * IN char init_val2
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_int_char_combo (
+struct int_char_combo_t *combo,
+int init_val1,
+char init_val2)
+#else
+void init_int_char_combo ( combo, init_val1, init_val2)
+struct int_char_combo_t *combo;
+int init_val1;
+char init_val2;
+#endif
+{
+
+ combo->int1 = init_val1;
+ combo->ch1 = init_val2;
+}
+
+/*****************************************************************
+ * INIT_STRUCT_REP :
+ * OUT struct small_rep_into_t *small_struct -- structure to be filled
+ * IN int seed
+ *****************************************************************/
+#ifdef PROTOTYPES
+void init_struct_rep(
+ struct small_rep_info_t *small_struct,
+ int seed)
+#else
+void init_struct_rep( small_struct, seed)
+struct small_rep_info_t *small_struct;
+int seed;
+#endif
+{
+
+ small_struct->value = 2 + (seed*2);
+ small_struct->head = 0;
+}
+
+/*****************************************************************
+ * PRINT_BIT_FLAGS :
+ * IN struct bit_flags_t bit_flags
+ ****************************************************************/
+#ifdef PROTOTYPES
+struct bit_flags_t print_bit_flags (struct bit_flags_t bit_flags)
+#else
+struct bit_flags_t print_bit_flags ( bit_flags)
+struct bit_flags_t bit_flags;
+#endif
+{
+
+ if (bit_flags.alpha) printf("alpha\n");
+ if (bit_flags.beta) printf("beta\n");
+ if (bit_flags.gamma) printf("gamma\n");
+ if (bit_flags.delta) printf("delta\n");
+ if (bit_flags.epsilon) printf("epsilon\n");
+ if (bit_flags.omega) printf("omega\n");
+ return bit_flags;
+
+}
+
+/*****************************************************************
+ * PRINT_BIT_FLAGS_COMBO :
+ * IN struct bit_flags_combo_t bit_flags_combo
+ ****************************************************************/
+#ifdef PROTOTYPES
+struct bit_flags_combo_t print_bit_flags_combo (struct bit_flags_combo_t bit_flags_combo)
+#else
+struct bit_flags_combo_t print_bit_flags_combo ( bit_flags_combo )
+struct bit_flags_combo_t bit_flags_combo;
+#endif
+{
+
+ if (bit_flags_combo.alpha) printf("alpha\n");
+ if (bit_flags_combo.beta) printf("beta\n");
+ if (bit_flags_combo.gamma) printf("gamma\n");
+ if (bit_flags_combo.delta) printf("delta\n");
+ if (bit_flags_combo.epsilon) printf("epsilon\n");
+ if (bit_flags_combo.omega) printf("omega\n");
+ printf("ch1: %c\tch2: %c\n", bit_flags_combo.ch1, bit_flags_combo.ch2);
+ return bit_flags_combo;
+
+}
+
+/*****************************************************************
+ * PRINT_ONE_DOUBLE :
+ * IN struct one_double_t one_double
+ ****************************************************************/
+#ifdef PROTOTYPES
+struct one_double_t print_one_double (struct one_double_t one_double)
+#else
+struct one_double_t print_one_double ( one_double )
+struct one_double_t one_double;
+#endif
+{
+
+ printf("Contents of one_double_t: \n\n");
+ printf("%f\n", one_double.double1);
+ return one_double;
+
+}
+
+/*****************************************************************
+ * PRINT_TWO_FLOATS :
+ * IN struct two_floats_t two_floats
+ ****************************************************************/
+#ifdef PROTOTYPES
+struct two_floats_t print_two_floats (struct two_floats_t two_floats)
+#else
+struct two_floats_t print_two_floats ( two_floats )
+struct two_floats_t two_floats;
+#endif
+{
+
+ printf("Contents of two_floats_t: \n\n");
+ printf("%f\t%f\n", two_floats.float1, two_floats.float2);
+ return two_floats;
+
+}
+
+/*****************************************************************
+ * PRINT_THREE_CHARS :
+ * IN struct three_char_t three_char
+ ****************************************************************/
+#ifdef PROTOTYPES
+struct three_char_t print_three_chars (struct three_char_t three_char)
+#else
+struct three_char_t print_three_chars ( three_char )
+struct three_char_t three_char;
+#endif
+{
+
+ printf("Contents of three_char_t: \n\n");
+ printf("%c\t%c\t%c\n", three_char.ch1, three_char.ch2, three_char.ch3);
+ return three_char;
+
+}
+
+/*****************************************************************
+ * PRINT_FIVE_CHARS :
+ * IN struct five_char_t five_char
+ ****************************************************************/
+#ifdef PROTOTYPES
+struct five_char_t print_five_chars (struct five_char_t five_char)
+#else
+struct five_char_t print_five_chars ( five_char )
+struct five_char_t five_char;
+#endif
+{
+
+ printf("Contents of five_char_t: \n\n");
+ printf("%c\t%c\t%c\t%c\t%c\n", five_char.ch1, five_char.ch2,
+ five_char.ch3, five_char.ch4,
+ five_char.ch5);
+ return five_char;
+
+}
+
+/*****************************************************************
+ * PRINT_INT_CHAR_COMBO :
+ * IN struct int_char_combo_t int_char_combo
+ ****************************************************************/
+#ifdef PROTOTYPES
+struct int_char_combo_t print_int_char_combo (struct int_char_combo_t int_char_combo)
+#else
+struct int_char_combo_t print_int_char_combo ( int_char_combo )
+struct int_char_combo_t int_char_combo;
+#endif
+{
+
+ printf("Contents of int_char_combo_t: \n\n");
+ printf("%d\t%c\n", int_char_combo.int1, int_char_combo.ch1);
+ return int_char_combo;
+
+}
+
+/*****************************************************************
+ * PRINT_STRUCT_REP :
+ ****************************************************************/
+#ifdef PROTOTYPES
+struct small_rep_info_t print_struct_rep(struct small_rep_info_t struct1)
+#else
+struct small_rep_info_t print_struct_rep( struct1 )
+struct small_rep_info_t struct1;
+#endif
+{
+
+ printf("Contents of struct1: \n\n");
+ printf("%10d%10d\n", struct1.value, struct1.head);
+ struct1.value =+5;
+
+ return struct1;
+
+
+}
+
+
+#ifdef PROTOTYPES
+struct array_rep_info_t print_one_large_struct(struct array_rep_info_t linked_list1)
+#else
+struct array_rep_info_t print_one_large_struct( linked_list1 )
+struct array_rep_info_t linked_list1;
+#endif
+{
+
+
+ printf("%10d%10d\n", linked_list1.values[0],
+ linked_list1.next_index[0]);
+
+ return linked_list1;
+
+}
+
+/*****************************************************************
+ * INIT_ARRAY_REP :
+ * IN struct array_rep_info_t *linked_list
+ * IN int seed
+ ****************************************************************/
+#ifdef PROTOTYPES
+void init_array_rep(struct array_rep_info_t *linked_list, int seed)
+#else
+void init_array_rep( linked_list, seed )
+struct array_rep_info_t *linked_list;
+int seed;
+#endif
+{
+
+ int index;
+
+ for (index = 0; index < 10; index++) {
+
+ linked_list->values[index] = (2*index) + (seed*2);
+ linked_list->next_index[index] = index + 1;
+ }
+ linked_list->head = 0;
+}
+
+
+int main () {
+
+ /* variables for large structure testing
+ */
+ int number = 10;
+ struct array_rep_info_t *list1;
+
+ /* variables for testing a small structures and a very long argument list
+ */
+ struct small_rep_info_t *struct1;
+ struct bit_flags_t *flags;
+ struct bit_flags_combo_t *flags_combo;
+ struct three_char_t *three_char;
+ struct five_char_t *five_char;
+ struct int_char_combo_t *int_char_combo;
+ struct one_double_t *d1;
+ struct two_floats_t *f3;
+
+
+ /* Allocate space for large structures
+ */
+ list1 = (struct array_rep_info_t *)malloc(sizeof(struct array_rep_info_t));
+
+ /* Initialize large structures
+ */
+ init_array_rep(list1, 2);
+
+ /* Print large structures
+ */
+ print_one_large_struct(*list1);
+
+ /* Allocate space for small structures
+ */
+ struct1 = (struct small_rep_info_t *)malloc(sizeof(struct small_rep_info_t));
+ flags = (struct bit_flags_t *)malloc(sizeof(struct bit_flags_t));
+ flags_combo = (struct bit_flags_combo_t *)malloc(sizeof(struct bit_flags_combo_t));
+ three_char = (struct three_char_t *)malloc(sizeof(struct three_char_t));
+ five_char = (struct five_char_t *)malloc(sizeof(struct five_char_t));
+ int_char_combo = (struct int_char_combo_t *)malloc(sizeof(struct int_char_combo_t));
+
+ d1 = (struct one_double_t *)malloc(sizeof(struct one_double_t));
+ f3 = (struct two_floats_t *)malloc(sizeof(struct two_floats_t));
+
+ /* Initialize small structures
+ */
+ init_one_double ( d1, 1.11111);
+ init_two_floats ( f3, -2.345, 1.0);
+ init_bit_flags(flags, (unsigned)1, (unsigned)0, (unsigned)1,
+ (unsigned)0, (unsigned)1, (unsigned)0 );
+ init_bit_flags_combo(flags_combo, (unsigned)1, (unsigned)0, 'y',
+ (unsigned)1, (unsigned)0, 'n',
+ (unsigned)1, (unsigned)0 );
+ init_three_chars(three_char, 'x', 'y', 'z');
+ init_five_chars(five_char, 'h', 'e', 'l', 'l', 'o');
+ init_int_char_combo(int_char_combo, 13, '!');
+ init_struct_rep(struct1, 10);
+
+
+ /* Print small structures
+ */
+ print_one_double(*d1);
+ print_two_floats(*f3);
+ print_bit_flags(*flags);
+ print_bit_flags_combo(*flags_combo);
+ print_three_chars(*three_char);
+ print_five_chars(*five_char);
+ print_int_char_combo(*int_char_combo);
+ print_struct_rep(*struct1);
+
+ loop_count();
+
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.base/call-rt-st.exp b/gdb/testsuite/gdb.base/call-rt-st.exp
new file mode 100644
index 00000000000..115dcb3fa7e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/call-rt-st.exp
@@ -0,0 +1,213 @@
+# Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+# this file tests command line calls with functions returning structures
+# corresponding source file: call_return_struct.c
+
+
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "call-rt-st"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+
+# Test depends on printf, which the sparclet stub doesn't support.
+if { [istarget "sparclet-*-*"] } {
+ return 0;
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+
+
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+# Some targets can't do function calls, so don't even bother with this
+# test.
+if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ continue
+}
+
+# Set the current language to C. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_c {} {
+ global gdb_prompt
+
+ send_gdb "set language c\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language c (timeout)" ; return 0; }
+ }
+
+ send_gdb "show language\n"
+ gdb_expect {
+ -re ".* source language is \"c\".*$gdb_prompt $" {
+ pass "set language to \"c\""
+ return 1
+ }
+ -re ".*$gdb_prompt $" {
+ fail "setting language to \"c\""
+ return 0
+ }
+ timeout {
+ fail "can't show language (timeout)"
+ return 0
+ }
+ }
+}
+
+
+
+source ${binfile}.ci
+
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+send_gdb "set print sevenbit-strings\n" ; gdb_expect -re "$gdb_prompt $"
+send_gdb "set print address off\n" ; gdb_expect -re "$gdb_prompt $"
+send_gdb "set width 0\n" ; gdb_expect -re "$gdb_prompt $"
+
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+
+gdb_test "break loop_count" \
+ "Breakpoint.* file .*call-rt-st.c, line 106\\." \
+ "breakpoint loop_count"
+
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing\\..*Breakpoint.*loop_count \\(\\) at.*call-rt-st.c:106\[ \t\r\n\]+106\[\t \]+for \\(index=0; index.4; index..\\);\[\r\n \]+$gdb_prompt $" {
+ pass "continue to loop_count"}
+ -re ".*$gdb_prompt $" { fail "continue to loop_count"}
+ timeout { fail "(timeout) continue to loop_count"}
+}
+
+send_gdb "finish\n"
+gdb_expect {
+ -re "Run till exit from .0 loop_count \\(\\) at.*call-rt-st.c:106\[ \t\r\n\]+main \\(\\) at.*call-rt-st.c:617\[ \t\r\n\]+617\[\t \]+return 0;.*$gdb_prompt $" {
+ pass "finish out from loop_count (line 617)"}
+ -re "Run till exit from .0 loop_count \\(\\) at.*call-rt-st.c:106\[ \t\r\n\]+main \\(\\) at.*call-rt-st.c:615\[ \t\r\n\]+615\[\t \]+loop_count.*$gdb_prompt $" {
+ pass "finish out from loop_count (line 615)"}
+ -re ".*$gdb_prompt $" { fail "finish out from loop_count"}
+ timeout { fail "(timeout)finish out from loop_count"}
+}
+
+# Ask GDB to print the value of EXPR, and expect to see the regexp
+# RESULT in the output. If we get back the error message "Function
+# return value unknown", call that an `unsupported' test; on some
+# architectures, it's impossible to find structs returned by value
+# reliably.
+proc print_struct_call { expr result } {
+ global gdb_prompt
+
+ set command "print $expr"
+ send_gdb "${command}\n"
+ gdb_expect {
+ -re "$result\[\r\n\]+$gdb_prompt $" {
+ pass "$command"
+ }
+ -re "Function return value unknown.\[\r\n\]+$gdb_prompt $" {
+ unsupported "$command"
+ }
+ -re "$gdb_prompt $" {
+ fail "$command"
+ }
+ timeout {
+ fail "$command (timeout)"
+ }
+ }
+}
+
+
+if ![gdb_skip_stdio_test "print print_struct_rep(*struct1)"] {
+ print_struct_call "print_struct_rep(*struct1)" \
+ ".*Contents of struct1:\[ \t\n\r\]+22\[ \t\]+0\[ \t\n\r\]+.\[0-9\]+ = \\{value = 5, head = 0\\}"
+}
+
+if ![gdb_skip_stdio_test "print print_one_large_struct(...)"] {
+ print_struct_call "print_one_large_struct(*list1)" \
+ ".*\[ \t\]+4\[ \t\]+1\[ \r\n\]+.\[0-9\]+ = \\{next_index = \\{1, 2, 3, 4, 5, 6, 7, 8, 9, 10\\}, values = \\{4, 6, 8, 10, 12, 14, 16, 18, 20, 22\\}, head = 0\\}"
+}
+
+if {![gdb_skip_float_test "print print_one_double(*d1)"] && \
+ ![gdb_skip_stdio_test "print print_one_double(*d1)"] } {
+ print_struct_call "print_one_double(*d1)" \
+ ".*Contents of one_double_t:\[ \r\n\]+1\\.111110\[ \r\n\]+.\[0-9\]+ = \\{double1 = 1\\.111\[0-9\]*\\}"
+}
+
+if {![gdb_skip_float_test "print print_two_floats(*f3)"] && \
+ ![gdb_skip_stdio_test "print print_two_floats(*f3)"] } {
+ print_struct_call "print_two_floats(*f3)" \
+ ".*Contents of two_floats_t:\[ \r\n\]+-2\\.345000\[ \t]+1\\.000000\[ \r\n\]+.\[0-9\]+ = \\{float1 = -2\\.34500003, float2 = 1\\}"
+}
+
+if ![gdb_skip_stdio_test "print print_bit_flags(*flags)"] {
+ print_struct_call "print_bit_flags(*flags)" \
+ ".*alpha\[ \r\n\]+gamma\[ \r\n\]+epsilon\[ \r\n\]+.\[0-9\]+ = \\{alpha = 1, beta = 0, gamma = 1, delta = 0, epsilon = 1, omega = 0\\}"
+}
+
+if ![gdb_skip_stdio_test "print print_bit_flags_combo(*flags_combo)"] {
+ print_struct_call "print_bit_flags_combo(*flags_combo)" \
+ ".*alpha\[ \r\n\]+gamma\[ \r\n\]+epsilon\[ \r\n\]+ch1: y\[ \t\]+ch2: n\[ \r\n\]+.\[0-9\]+ = \\{alpha = 1, beta = 0, ch1 = 121 'y', gamma = 1, delta = 0, ch2 = 110 'n', epsilon = 1, omega = 0\\}"
+}
+
+if ![gdb_skip_stdio_test "print print_three_chars(*three_chars)"] {
+ print_struct_call "print_three_chars(*three_char)" \
+ ".*Contents of three_char_t:\[ \r\n\]+x\[ \t\]+y\[ \t\]+z\[ \r\n\]+.\[0-9\]+ = \\{ch1 = 120 'x', ch2 = 121 'y', ch3 = 122 'z'\\}"
+}
+
+if ![gdb_skip_stdio_test "print print_five_chars(*five_chars)"] {
+ print_struct_call "print_five_chars(*five_char)" \
+ ".*Contents of five_char_t:\[ \r\n\]+h\[ \t\]+e\[ \t\]+l\[ \t\]+l\[ \t\]+o\[ \r\n\]+.\[0-9\]+ = \\{ch1 = 104 'h', ch2 = 101 'e', ch3 = 108 'l', ch4 = 108 'l', ch5 = 111 'o'\\}"
+}
+
+if ![gdb_skip_stdio_test "print print_int_char_combo(*int_char_combo)"] {
+ print_struct_call "print_int_char_combo(*int_char_combo)" \
+ ".*Contents of int_char_combo_t:\[ \r\n\]+13\[ \t\]+!\[ \r\n\]+.\[0-9\]+ = \\{int1 = 13, ch1 = 33 '!'\\}"
+}
+
+return
diff --git a/gdb/testsuite/gdb.base/call-strs.c b/gdb/testsuite/gdb.base/call-strs.c
new file mode 100644
index 00000000000..f3bc8da9166
--- /dev/null
+++ b/gdb/testsuite/gdb.base/call-strs.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char buf[100];
+char bigbuf[1000];
+char * s;
+
+#ifdef PROTOTYPES
+char * str_func1(char *s1)
+#else
+char * str_func1(s1)
+char *s1;
+#endif
+{
+ printf("first string arg is: %s\n", s1);
+ strcpy(bigbuf, s1);
+ return bigbuf;
+}
+
+#ifdef PROTOTYPES
+char * str_func(
+char * s1,
+char * s2,
+char * s3,
+char * s4,
+char * s5,
+char * s6,
+char * s7)
+#else
+char * str_func(s1,
+ s2,
+ s3,
+ s4,
+ s5,
+ s6,
+ s7)
+char * s1;
+char * s2;
+char * s3;
+char * s4;
+char * s5;
+char * s6;
+char * s7;
+#endif
+{
+ printf("first string arg is: %s\n", s1);
+ printf("second string arg is: %s\n", s2);
+ printf("third string arg is: %s\n", s3);
+ printf("fourth string arg is: %s\n", s4);
+ printf("fifth string arg is: %s\n", s5);
+ printf("sixth string arg is: %s\n", s6);
+ printf("seventh string arg is: %s\n", s7);
+ strcpy(bigbuf, s1);
+ strcat(bigbuf, s2);
+ strcat(bigbuf, s3);
+ strcat(bigbuf, s4);
+ strcat(bigbuf, s5);
+ strcat(bigbuf, s6);
+ strcat(bigbuf, s7);
+ return bigbuf;
+}
+
+char *
+link_malloc ()
+{
+ return (char*) malloc (1);
+}
+
+int main()
+{
+ s = &buf[0];
+ strcpy(buf, "test string");
+ str_func("abcd", "efgh", "ijkl", "mnop", "qrst", "uvwx", "yz12");
+ str_func1("abcd");
+ return 0;
+}
+
diff --git a/gdb/testsuite/gdb.base/call-strs.exp b/gdb/testsuite/gdb.base/call-strs.exp
new file mode 100644
index 00000000000..63fc27427fd
--- /dev/null
+++ b/gdb/testsuite/gdb.base/call-strs.exp
@@ -0,0 +1,268 @@
+# Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+# This test deals with calling functions which have strings as parameters.
+# it plays around with constant strings.
+# the corresponding source file is call-strs.c
+#
+
+#debug strarg
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "call-strs"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Test depends on printf, which the sparclet stub doesn't support.
+if { [istarget "sparclet-*-*"] } {
+ return 0;
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+
+# Some targets can't call functions, so don't even bother with this
+# test.
+if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ continue
+}
+
+# Set the current language to C. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_c {} {
+ global gdb_prompt
+
+ send_gdb "set language c\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language c (timeout)" ; return 0; }
+ }
+
+ send_gdb "show language\n"
+ gdb_expect {
+ -re ".* source language is \"c\".*$gdb_prompt $" {
+ pass "set language to \"c\""
+ return 1
+ }
+ -re ".*$gdb_prompt $" {
+ fail "setting language to \"c\""
+ return 0
+ }
+ timeout {
+ fail "can't show language (timeout)"
+ return 0
+ }
+ }
+}
+
+
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+send_gdb "set print sevenbit-strings\n" ; gdb_expect -re "$gdb_prompt $"
+send_gdb "set print address off\n" ; gdb_expect -re "$gdb_prompt $"
+send_gdb "set width 0\n" ; gdb_expect -re "$gdb_prompt $"
+
+set timeout 120
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+#step
+send_gdb "step\n"
+gdb_expect {
+ -re ".*strcpy\\(buf, \"test string\"\\);.*$gdb_prompt $" {pass "step after assignment to s"}
+ -re ".*$gdb_prompt $" { fail "step after assignment to s" }
+ timeout { fail "step after assignment to s (timeout)" }
+ }
+
+
+#step
+send_gdb "next\n"
+gdb_expect {
+ -re ".*str_func\\(\"abcd\", \"efgh\", \"ijkl\", \"mnop\", \"qrst\", \"uvwx\", \"yz12\"\\);.*$gdb_prompt $" {pass "next over strcpy"}
+ -re ".*$gdb_prompt $" { fail "next over strcpy" }
+ timeout { fail "next over strcpy (timeout)" }
+ }
+
+#print buf
+send_gdb "print buf\n"
+gdb_expect {
+ -re ".*\"test string\",.*repeats 88 times.*$gdb_prompt $" {
+ pass "print buf"
+ }
+ -re ".*$gdb_prompt $" { fail "print buf" }
+ timeout { fail "(timeout) print buf" }
+ }
+
+
+#print s
+send_gdb "print s\n"
+gdb_expect {
+ -re ".*= \"test string\".*$gdb_prompt $" {
+ pass "print s"
+ }
+ -re ".*$gdb_prompt $" { fail "print s" }
+ timeout { fail "(timeout) print sum_array_print(10, *list1, *list2, *list3, *list4)" }
+ }
+
+
+#print str_func1(s)
+if ![gdb_skip_stdio_test "print str_func1(s)"] {
+ send_gdb "print str_func1(s)\n"
+ gdb_expect {
+ -re "first string arg is: test string.*\"test string\".*$gdb_prompt $" {
+ pass "print str_func1(s)"
+ }
+ -re ".*$gdb_prompt $" { fail "print str_func1(s)" }
+ timeout { fail "(timeout) print str_func1(s)" }
+ }
+}
+
+
+#print str_func1("test string")
+if ![gdb_skip_stdio_test "print str_func1(teststring)"] {
+ send_gdb "print str_func1(\"test string\")\n"
+ gdb_expect {
+ -re "first string arg is: test string.*\"test string\".*$gdb_prompt $" {
+ pass "print str_func1(\"test string\")"
+ }
+ -re ".*$gdb_prompt $" { fail "print str_func1(\"test string\")" }
+ timeout { fail "(timeout) print str_func1(\"test string\")" }
+ }
+}
+
+#call str_func1(s)
+if ![gdb_skip_stdio_test "call str_func1(s)"] {
+ send_gdb "call str_func1(s)\n"
+ gdb_expect {
+ -re "first string arg is: test string.*\"test string\".*$gdb_prompt $" {
+ pass "call str_func1(s)"
+ }
+ -re ".*$gdb_prompt $" { fail "call str_func1(s)" }
+ timeout { fail "(timeout) call str_func1(s)" }
+ }
+}
+
+#call str_func1("test string")
+if ![gdb_skip_stdio_test "call str_func1 (...)"] {
+ send_gdb "call str_func1(\"test string\")\n"
+ gdb_expect {
+ -re "first string arg is: test string.*\"test string\".*$gdb_prompt $" {
+ pass "call str_func1(\"test string\")"
+ }
+ -re ".*$gdb_prompt $" { fail "call str_func1(\"test string\")" }
+ timeout { fail "(timeout) call str_func1(\"test string\")" }
+ }
+}
+
+#print str_func1(buf)
+if ![gdb_skip_stdio_test "print str_func1(buf)"] {
+ send_gdb "print str_func1(buf)\n"
+ gdb_expect {
+ -re "first string arg is: test string.*\"test string\".*$gdb_prompt $" {
+ pass "print str_func1(buf)"
+ }
+ -re ".*$gdb_prompt $" { fail "print str_func1(buf)" }
+ timeout { fail "(timeout) print str_func1(buf)" }
+ }
+}
+
+#call str_func1(buf)
+if ![gdb_skip_stdio_test "call str_func1(buf)"] {
+ send_gdb "call str_func1(buf)\n"
+ gdb_expect {
+ -re "first string arg is: test string.*\"test string\".*$gdb_prompt $" {
+ pass "call str_func1(buf)"
+ }
+ -re ".*$gdb_prompt $" { fail "call str_func1(buf)" }
+ timeout { fail "(timeout) call str_func1(buf)" }
+ }
+}
+
+#print str_func("a","b","c","d","e","f","g")
+if ![gdb_skip_stdio_test "print str_func(a,b,c,d,e,f,g)"] {
+ send_gdb "print str_func(\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\")\n"
+ gdb_expect {
+ -re "first string arg is: a\[ \t\r\n\]+second string arg is: b\[ \t\r\n\]+third string arg is: c\[ \t\r\n\]+fourth string arg is: d\[ \t\r\n\]+fifth string arg is: e\[ \t\r\n\]+sixth string arg is: f\[ \t\r\n\]+seventh string arg is: g\[ \t\r\n\]+.*= \"abcdefg\".*$gdb_prompt $" {
+ pass "print str_func(\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\")"
+ }
+ -re ".*$gdb_prompt $" { fail "print str_func(\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\")" }
+ timeout { fail "(timeout) print str_func(\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\")" }
+ }
+}
+
+#call str_func("a","b","c","d","e","f","g")
+if ![gdb_skip_stdio_test "call str_func(a,b,c,d,e,f,g)"] {
+ send_gdb "call str_func(\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\")\n"
+ gdb_expect {
+ -re "first string arg is: a\[ \t\r\n\]+second string arg is: b\[ \t\r\n\]+third string arg is: c\[ \t\r\n\]+fourth string arg is: d\[ \t\r\n\]+fifth string arg is: e\[ \t\r\n\]+sixth string arg is: f\[ \t\r\n\]+seventh string arg is: g\[ \t\r\n\]+.*= \"abcdefg\".*$gdb_prompt $" {
+ pass "call str_func(\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\")"
+ }
+ -re ".*$gdb_prompt $" { fail "call str_func(\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\")" }
+ timeout { fail "(timeout) call str_func(\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\")" }
+ }
+}
+
+#print str_func(s,s,s,s,s,s,s)
+if ![gdb_skip_stdio_test "print str_func(s,s,s,s,s,s,s,s)"] {
+ send_gdb "print str_func(s,s,s,s,s,s,s)\n"
+ gdb_expect {
+ -re "first string arg is: test string\[ \t\r\n\]+second string arg is: test string\[ \t\r\n\]+third string arg is: test string\[ \t\r\n\]+fourth string arg is: test string\[ \t\r\n\]+fifth string arg is: test string\[ \t\r\n\]+sixth string arg is: test string\[ \t\r\n\]+seventh string arg is: test string\[ \t\r\n\]+.*\"test stringtest stringtest stringtest stringtest stringtest stringtest string\".*$gdb_prompt $" {
+ pass "print str_func(s,s,s,s,s,s,s)"
+ }
+ -re ".*$gdb_prompt $" { fail "print str_func(s,s,s,s,s,s,s)" }
+ timeout { fail "(timeout) print str_func(s,s,s,s,s,s,s)" }
+ }
+}
+
+#call str_func(s,s,s,s,s,s,s)
+if ![gdb_skip_stdio_test "call str_func(s,s,s,s,s,s,s,s)"] {
+ send_gdb "call str_func(s,s,s,s,s,s,s)\n"
+ gdb_expect {
+ -re "first string arg is: test string\[ \t\r\n\]+second string arg is: test string\[ \t\r\n\]+third string arg is: test string\[ \t\r\n\]+fourth string arg is: test string\[ \t\r\n\]+fifth string arg is: test string\[ \t\r\n\]+sixth string arg is: test string\[ \t\r\n\]+seventh string arg is: test string\[ \t\r\n\]+.*\"test stringtest stringtest stringtest stringtest stringtest stringtest string\".*$gdb_prompt $" {
+ pass "call str_func(s,s,s,s,s,s,s)"
+ }
+ -re ".*$gdb_prompt $" { fail "call str_func(s,s,s,s,s,s,s)" }
+ timeout { fail "(timeout) call str_func(s,s,s,s,s,s,s)" }
+ }
+}
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.base/callfuncs.c b/gdb/testsuite/gdb.base/callfuncs.c
new file mode 100644
index 00000000000..9917e788d0a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/callfuncs.c
@@ -0,0 +1,371 @@
+/* Support program for testing gdb's ability to call functions
+ in the inferior, pass appropriate arguments to those functions,
+ and get the returned result. */
+
+#ifdef NO_PROTOTYPES
+#define PARAMS(paramlist) ()
+#else
+#define PARAMS(paramlist) paramlist
+#endif
+
+# include <stdlib.h>
+# include <string.h>
+
+char char_val1 = 'a';
+char char_val2 = 'b';
+
+short short_val1 = 10;
+short short_val2 = -23;
+
+int int_val1 = 87;
+int int_val2 = -26;
+
+long long_val1 = 789;
+long long_val2 = -321;
+
+float float_val1 = 3.14159;
+float float_val2 = -2.3765;
+
+double double_val1 = 45.654;
+double double_val2 = -67.66;
+
+#define DELTA (0.001)
+
+char *string_val1 = (char *)"string 1";
+char *string_val2 = (char *)"string 2";
+
+char char_array_val1[] = "carray 1";
+char char_array_val2[] = "carray 2";
+
+struct struct1 {
+ char c;
+ short s;
+ int i;
+ long l;
+ float f;
+ double d;
+ char a[4];
+} struct_val1 = { 'x', 87, 76, 51, 2.1234, 9.876, "foo" };
+
+/* Some functions that can be passed as arguments to other test
+ functions, or called directly. */
+#ifdef PROTOTYPES
+int add (int a, int b)
+#else
+int add (a, b) int a, b;
+#endif
+{
+ return (a + b);
+}
+
+#ifdef PROTOTYPES
+int doubleit (int a)
+#else
+int doubleit (a) int a;
+#endif
+{
+ return (a + a);
+}
+
+int (*func_val1) PARAMS((int,int)) = add;
+int (*func_val2) PARAMS((int)) = doubleit;
+
+/* An enumeration and functions that test for specific values. */
+
+enum enumtype { enumval1, enumval2, enumval3 };
+enum enumtype enum_val1 = enumval1;
+enum enumtype enum_val2 = enumval2;
+enum enumtype enum_val3 = enumval3;
+
+#ifdef PROTOTYPES
+int t_enum_value1 (enum enumtype enum_arg)
+#else
+int t_enum_value1 (enum_arg) enum enumtype enum_arg;
+#endif
+{
+ return (enum_arg == enum_val1);
+}
+
+#ifdef PROTOTYPES
+int t_enum_value2 (enum enumtype enum_arg)
+#else
+int t_enum_value2 (enum_arg) enum enumtype enum_arg;
+#endif
+{
+ return (enum_arg == enum_val2);
+}
+
+#ifdef PROTOTYPES
+int t_enum_value3 (enum enumtype enum_arg)
+#else
+int t_enum_value3 (enum_arg) enum enumtype enum_arg;
+#endif
+{
+ return (enum_arg == enum_val3);
+}
+
+/* A function that takes a vector of integers (along with an explicit
+ count) and returns their sum. */
+
+#ifdef PROTOTYPES
+int sum_args (int argc, int argv[])
+#else
+int sum_args (argc, argv) int argc; int argv[];
+#endif
+{
+ int sumval = 0;
+ int idx;
+
+ for (idx = 0; idx < argc; idx++)
+ {
+ sumval += argv[idx];
+ }
+ return (sumval);
+}
+
+/* Test that we can call functions that take structs and return
+ members from that struct */
+
+#ifdef PROTOTYPES
+char t_structs_c (struct struct1 tstruct) { return (tstruct.c); }
+short t_structs_s (struct struct1 tstruct) { return (tstruct.s); }
+int t_structs_i (struct struct1 tstruct) { return (tstruct.i); }
+long t_structs_l (struct struct1 tstruct) { return (tstruct.l); }
+float t_structs_f (struct struct1 tstruct) { return (tstruct.f); }
+double t_structs_d (struct struct1 tstruct) { return (tstruct.d); }
+char *t_structs_a (struct struct1 tstruct)
+{
+ static char buf[8];
+ strcpy (buf, tstruct.a);
+ return buf;
+}
+#else
+char t_structs_c (tstruct) struct struct1 tstruct; { return (tstruct.c); }
+short t_structs_s (tstruct) struct struct1 tstruct; { return (tstruct.s); }
+int t_structs_i (tstruct) struct struct1 tstruct; { return (tstruct.i); }
+long t_structs_l (tstruct) struct struct1 tstruct; { return (tstruct.l); }
+float t_structs_f (tstruct) struct struct1 tstruct; { return (tstruct.f); }
+double t_structs_d (tstruct) struct struct1 tstruct; { return (tstruct.d); }
+char *t_structs_a (tstruct) struct struct1 tstruct;
+{
+ static char buf[8];
+ strcpy (buf, tstruct.a);
+ return buf;
+}
+#endif
+
+/* Test that calling functions works if there are a lot of arguments. */
+#ifdef PROTOTYPES
+int
+sum10 (int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9)
+#else
+int
+sum10 (i0, i1, i2, i3, i4, i5, i6, i7, i8, i9)
+ int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
+#endif
+{
+ return i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9;
+}
+
+/* Test that args are passed in the right order. */
+#ifdef PROTOTYPES
+int
+cmp10 (int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9)
+#else
+int
+cmp10 (i0, i1, i2, i3, i4, i5, i6, i7, i8, i9)
+ int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
+#endif
+{
+ return
+ (i0 == 0) && (i1 == 1) && (i2 == 2) && (i3 == 3) && (i4 == 4) &&
+ (i5 == 5) && (i6 == 6) && (i7 == 7) && (i8 == 8) && (i9 == 9);
+}
+
+/* Functions that expect specific values to be passed and return
+ either 0 or 1, depending upon whether the values were
+ passed incorrectly or correctly, respectively. */
+
+#ifdef PROTOTYPES
+int t_char_values (char char_arg1, char char_arg2)
+#else
+int t_char_values (char_arg1, char_arg2)
+char char_arg1, char_arg2;
+#endif
+{
+ return ((char_arg1 == char_val1) && (char_arg2 == char_val2));
+}
+
+int
+#ifdef PROTOTYPES
+t_small_values (char arg1, short arg2, int arg3, char arg4, short arg5,
+ char arg6, short arg7, int arg8, short arg9, short arg10)
+#else
+t_small_values (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
+ char arg1;
+ short arg2;
+ int arg3;
+ char arg4;
+ short arg5;
+ char arg6;
+ short arg7;
+ int arg8;
+ short arg9;
+ short arg10;
+#endif
+{
+ return arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9 + arg10;
+}
+
+#ifdef PROTOTYPES
+int t_short_values (short short_arg1, short short_arg2)
+#else
+int t_short_values (short_arg1, short_arg2)
+ short short_arg1, short_arg2;
+#endif
+{
+ return ((short_arg1 == short_val1) && (short_arg2 == short_val2));
+}
+
+#ifdef PROTOTYPES
+int t_int_values (int int_arg1, int int_arg2)
+#else
+int t_int_values (int_arg1, int_arg2)
+int int_arg1, int_arg2;
+#endif
+{
+ return ((int_arg1 == int_val1) && (int_arg2 == int_val2));
+}
+
+#ifdef PROTOTYPES
+int t_long_values (long long_arg1, long long_arg2)
+#else
+int t_long_values (long_arg1, long_arg2)
+long long_arg1, long_arg2;
+#endif
+{
+ return ((long_arg1 == long_val1) && (long_arg2 == long_val2));
+}
+
+/* NOTE: THIS FUNCTION MUST NOT BE PROTOTYPED!!!!!
+ There must be one version of "t_float_values" (this one)
+ that is not prototyped, and one (if supported) that is (following).
+ That way GDB can be tested against both cases. */
+
+int t_float_values (float_arg1, float_arg2)
+float float_arg1, float_arg2;
+{
+ return ((float_arg1 - float_val1) < DELTA
+ && (float_arg1 - float_val1) > -DELTA
+ && (float_arg2 - float_val2) < DELTA
+ && (float_arg2 - float_val2) > -DELTA);
+}
+
+int
+#ifdef NO_PROTOTYPES
+/* In this case we are just duplicating t_float_values, but that is the
+ easiest way to deal with either ANSI or non-ANSI. */
+t_float_values2 (float_arg1, float_arg2)
+ float float_arg1, float_arg2;
+#else
+t_float_values2 (float float_arg1, float float_arg2)
+#endif
+{
+ return ((float_arg1 - float_val1) < DELTA
+ && (float_arg1 - float_val1) > -DELTA
+ && (float_arg2 - float_val2) < DELTA
+ && (float_arg2 - float_val2) > -DELTA);
+}
+
+#ifdef PROTOTYPES
+int t_double_values (double double_arg1, double double_arg2)
+#else
+int t_double_values (double_arg1, double_arg2)
+double double_arg1, double_arg2;
+#endif
+{
+ return ((double_arg1 - double_val1) < DELTA
+ && (double_arg1 - double_val1) > -DELTA
+ && (double_arg2 - double_val2) < DELTA
+ && (double_arg2 - double_val2) > -DELTA);
+}
+
+#ifdef PROTOTYPES
+int t_string_values (char *string_arg1, char *string_arg2)
+#else
+int t_string_values (string_arg1, string_arg2)
+char *string_arg1, *string_arg2;
+#endif
+{
+ return (!strcmp (string_arg1, string_val1) &&
+ !strcmp (string_arg2, string_val2));
+}
+
+#ifdef PROTOTYPES
+int t_char_array_values (char char_array_arg1[], char char_array_arg2[])
+#else
+int t_char_array_values (char_array_arg1, char_array_arg2)
+char char_array_arg1[], char_array_arg2[];
+#endif
+{
+ return (!strcmp (char_array_arg1, char_array_val1) &&
+ !strcmp (char_array_arg2, char_array_val2));
+}
+
+
+/* This used to simply compare the function pointer arguments with
+ known values for func_val1 and func_val2. Doing so is valid ANSI
+ code, but on some machines (RS6000, HPPA, others?) it may fail when
+ called directly by GDB.
+
+ In a nutshell, it's not possible for GDB to determine when the address
+ of a function or the address of the function's stub/trampoline should
+ be passed.
+
+ So, to avoid GDB lossage in the common case, we perform calls through the
+ various function pointers and compare the return values. For the HPPA
+ at least, this allows the common case to work.
+
+ If one wants to try something more complicated, pass the address of
+ a function accepting a "double" as one of its first 4 arguments. Call
+ that function indirectly through the function pointer. This would fail
+ on the HPPA. */
+
+#ifdef PROTOTYPES
+int t_func_values (int (*func_arg1)(int, int), int (*func_arg2)(int))
+#else
+int t_func_values (func_arg1, func_arg2)
+int (*func_arg1) PARAMS ((int, int));
+int (*func_arg2) PARAMS ((int));
+#endif
+{
+ return ((*func_arg1) (5,5) == (*func_val1) (5,5)
+ && (*func_arg2) (6) == (*func_val2) (6));
+}
+
+#ifdef PROTOTYPES
+int t_call_add (int (*func_arg1)(int, int), int a, int b)
+#else
+int t_call_add (func_arg1, a, b)
+int (*func_arg1) PARAMS ((int, int));
+int a, b;
+#endif
+{
+ return ((*func_arg1)(a, b));
+}
+
+
+/* Gotta have a main to be able to generate a linked, runnable
+ executable, and also provide a useful place to set a breakpoint. */
+extern void * malloc() ;
+int main ()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ malloc(1);
+ t_double_values(double_val1, double_val2);
+ t_structs_c(struct_val1);
+ return 0 ;
+}
diff --git a/gdb/testsuite/gdb.base/callfuncs.exp b/gdb/testsuite/gdb.base/callfuncs.exp
new file mode 100644
index 00000000000..90f83434f43
--- /dev/null
+++ b/gdb/testsuite/gdb.base/callfuncs.exp
@@ -0,0 +1,441 @@
+# Copyright 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+# and modified by Bob Manson. (manson@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "callfuncs"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+if {$hp_aCC_compiler} {
+ set prototypes 1
+} else {
+ set prototypes 0
+}
+
+# Some targets can't do function calls, so don't even bother with this
+# test.
+if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ continue
+}
+
+# Set the current language to C. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_c {} {
+ global gdb_prompt
+
+ send_gdb "set language c\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language c (timeout)" ; return 0; }
+ }
+
+ send_gdb "show language\n"
+ gdb_expect {
+ -re ".* source language is \"c\".*$gdb_prompt $" {
+ pass "set language to \"c\""
+ return 1
+ }
+ -re ".*$gdb_prompt $" {
+ fail "setting language to \"c\""
+ return 0
+ }
+ timeout {
+ fail "can't show language (timeout)"
+ return 0
+ }
+ }
+}
+
+# FIXME: Before calling this proc, we should probably verify that
+# we can call inferior functions and get a valid integral value
+# returned.
+# Note that it is OK to check for 0 or 1 as the returned values, because C
+# specifies that the numeric value of a relational or logical expression
+# (computed in the inferior) is 1 for true and 0 for false.
+
+proc do_function_calls {} {
+ global prototypes
+ global gcc_compiled
+ global gdb_prompt
+
+ # We need to up this because this can be really slow on some boards.
+ set timeout 60;
+
+ gdb_test "p t_char_values(0,0)" " = 0"
+ gdb_test "p t_char_values('a','b')" " = 1"
+ gdb_test "p t_char_values(char_val1,char_val2)" " = 1"
+ gdb_test "p t_char_values('a',char_val2)" " = 1"
+ gdb_test "p t_char_values(char_val1,'b')" " = 1"
+
+ gdb_test "p t_short_values(0,0)" " = 0"
+ gdb_test "p t_short_values(10,-23)" " = 1"
+ gdb_test "p t_short_values(short_val1,short_val2)" " = 1"
+ gdb_test "p t_short_values(10,short_val2)" " = 1"
+ gdb_test "p t_short_values(short_val1,-23)" " = 1"
+
+ gdb_test "p t_int_values(0,0)" " = 0"
+ gdb_test "p t_int_values(87,-26)" " = 1"
+ gdb_test "p t_int_values(int_val1,int_val2)" " = 1"
+ gdb_test "p t_int_values(87,int_val2)" " = 1"
+ gdb_test "p t_int_values(int_val1,-26)" " = 1"
+
+ gdb_test "p t_long_values(0,0)" " = 0"
+ gdb_test "p t_long_values(789,-321)" " = 1"
+ gdb_test "p t_long_values(long_val1,long_val2)" " = 1"
+ gdb_test "p t_long_values(789,long_val2)" " = 1"
+ gdb_test "p t_long_values(long_val1,-321)" " = 1"
+
+ if ![target_info exists gdb,skip_float_tests] {
+ gdb_test "p t_float_values(0.0,0.0)" " = 0"
+
+ # These next four tests fail on the mn10300.
+ # The first value is passed in regs, the other in memory.
+ # Gcc emits different stabs for the two parameters; the first is
+ # claimed to be a float, the second a double.
+ # dbxout.c in gcc claims this is the desired behavior.
+ setup_xfail "mn10300-*-*"
+ gdb_test "p t_float_values(3.14159,-2.3765)" " = 1"
+ setup_xfail "mn10300-*-*"
+ gdb_test "p t_float_values(float_val1,float_val2)" " = 1"
+ setup_xfail "mn10300-*-*"
+ gdb_test "p t_float_values(3.14159,float_val2)" " = 1"
+ setup_xfail "mn10300-*-*"
+ gdb_test "p t_float_values(float_val1,-2.3765)" " = 1"
+
+ # Test passing of arguments which might not be widened.
+ # Under stabs, GCC doesn't tell us whether the function was
+ # prototyped or not.
+ if {$gcc_compiled} { setup_xfail_format "stabs" }
+ gdb_test "p t_float_values2(0.0,0.0)" " = 0"
+
+ # Although PR 5318 mentions SunOS specifically, this seems
+ # to be a generic problem on quite a few platforms.
+ if $prototypes then {
+ setup_xfail "sparc-*-*" "mips*-*-*" 5318
+ if {!$gcc_compiled} then {
+ setup_xfail "alpha-dec-osf2*" "i*86-*-sysv4*" 5318
+ }
+ }
+
+ # Under stabs, GCC doesn't tell us whether the function was
+ # prototyped or not.
+ if {$gcc_compiled} { setup_xfail_format "stabs" }
+ gdb_test "p t_float_values2(3.14159,float_val2)" " = 1"
+
+ gdb_test "p t_small_values(1,2,3,4,5,6,7,8,9,10)" " = 55"
+
+ gdb_test "p t_double_values(0.0,0.0)" " = 0"
+ gdb_test "p t_double_values(45.654,-67.66)" " = 1"
+ gdb_test "p t_double_values(double_val1,double_val2)" " = 1"
+ gdb_test "p t_double_values(45.654,double_val2)" " = 1"
+ gdb_test "p t_double_values(double_val1,-67.66)" " = 1"
+ }
+
+ gdb_test "p t_string_values(string_val2,string_val1)" " = 0"
+ gdb_test "p t_string_values(string_val1,string_val2)" " = 1"
+ gdb_test "p t_string_values(\"string 1\",\"string 2\")" " = 1"
+ gdb_test "p t_string_values(\"string 1\",string_val2)" " = 1"
+ gdb_test "p t_string_values(string_val1,\"string 2\")" " = 1"
+
+ gdb_test "p t_char_array_values(char_array_val2,char_array_val1)" " = 0"
+ gdb_test "p t_char_array_values(char_array_val1,char_array_val2)" " = 1"
+ gdb_test "p t_char_array_values(\"carray 1\",\"carray 2\")" " = 1"
+ gdb_test "p t_char_array_values(\"carray 1\",char_array_val2)" " = 1"
+ gdb_test "p t_char_array_values(char_array_val1,\"carray 2\")" " = 1"
+
+ gdb_test "p doubleit(4)" " = 8"
+ gdb_test "p add(4,5)" " = 9"
+ gdb_test "p t_func_values(func_val2,func_val1)" " = 0"
+ gdb_test "p t_func_values(func_val1,func_val2)" " = 1"
+
+ # On the rs6000, we need to pass the address of the trampoline routine,
+ # not the address of add itself. I don't know how to go from add to
+ # the address of the trampoline. Similar problems exist on the HPPA,
+ # and in fact can present an unsolvable problem as the stubs may not
+ # even exist in the user's program. We've slightly recoded t_func_values
+ # to avoid such problems in the common case. This may or may not help
+ # the RS6000.
+ setup_xfail "rs6000*-*-*"
+ setup_xfail "powerpc*-*-*"
+ if {![istarget hppa*-*-hpux*]} then {
+ gdb_test "p t_func_values(add,func_val2)" " = 1"
+ }
+
+ setup_xfail "rs6000*-*-*"
+ setup_xfail "powerpc*-*-*"
+ if {![istarget hppa*-*-hpux*]} then {
+ gdb_test "p t_func_values(func_val1,doubleit)" " = 1"
+ }
+
+ setup_xfail "rs6000*-*-*"
+ setup_xfail "powerpc*-*-*"
+ if {![istarget hppa*-*-hpux*]} then {
+ gdb_test "p t_call_add(add,3,4)" " = 7"
+ }
+ gdb_test "p t_call_add(func_val1,3,4)" " = 7"
+
+ gdb_test "p t_enum_value1(enumval1)" " = 1"
+ gdb_test "p t_enum_value1(enum_val1)" " = 1"
+ gdb_test "p t_enum_value1(enum_val2)" " = 0"
+
+ gdb_test "p t_enum_value2(enumval2)" " = 1"
+ gdb_test "p t_enum_value2(enum_val2)" " = 1"
+ gdb_test "p t_enum_value2(enum_val1)" " = 0"
+
+ gdb_test "p sum_args(1,{2})" " = 2"
+ gdb_test "p sum_args(2,{2,3})" " = 5"
+ gdb_test "p sum_args(3,{2,3,4})" " = 9"
+ gdb_test "p sum_args(4,{2,3,4,5})" " = 14"
+
+ gdb_test "p sum10 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)" " = 55"
+
+ gdb_test "p cmp10 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)" " = 1"
+
+ gdb_test "p t_structs_c(struct_val1)" "= 120 'x'" \
+ "call inferior func with struct - returns char"
+ gdb_test "p t_structs_s(struct_val1)" "= 87" \
+ "call inferior func with struct - returns short"
+ gdb_test "p t_structs_i(struct_val1)" "= 76" \
+ "call inferior func with struct - returns int"
+ gdb_test "p t_structs_l(struct_val1)" "= 51" \
+ "call inferior func with struct - returns long"
+ gdb_test "p t_structs_f(struct_val1)" "= 2.12.*" \
+ "call inferior func with struct - returns float"
+ gdb_test "p t_structs_d(struct_val1)" "= 9.87.*" \
+ "call inferior func with struct - returns double"
+ gdb_test "p t_structs_a(struct_val1)" "= (.unsigned char .. )?\"foo\"" \
+ "call inferior func with struct - returns char *"
+}
+
+# Procedure to get current content of all registers.
+global all_registers_content
+set all_registers_content ""
+proc do_get_all_registers { } {
+ global gdb_prompt
+ global expect_out
+ global all_registers_content
+
+ set all_registers_content ""
+ send_gdb "info all-registers\n"
+ gdb_expect {
+ -re "info all-registers\r\n(.*)$gdb_prompt $" {
+ set all_registers_content $expect_out(1,string)
+ }
+ default {}
+ }
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set print sevenbit-strings" ""
+gdb_test "set print address off" ""
+gdb_test "set width 0" ""
+
+if { $hp_aCC_compiler } {
+ # Do not set language explicitly to 'C'. This will cause aCC
+ # tests to fail because promotion rules are different. Just let
+ # the language be set to the default.
+
+ if { ![runto_main] } {
+ gdb_suppress_tests;
+ }
+
+ # However, turn off overload-resolution for aCC. Having it on causes
+ # a lot of failures.
+
+ gdb_test "set overload-resolution 0" ".*"
+} else {
+ if { ![set_lang_c] } {
+ gdb_suppress_tests;
+ } else {
+ if { ![runto_main] } {
+ gdb_suppress_tests;
+ }
+ }
+}
+
+get_debug_format
+
+# Make sure that malloc gets called and that the floating point unit
+# is initialized via a call to t_double_values.
+gdb_test "next" "t_double_values\\(double_val1, double_val2\\);.*" \
+ "next to t_double_values"
+gdb_test "next" "t_structs_c\\(struct_val1\\);.*" \
+ "next to t_structs_c"
+
+# Save all register contents.
+do_get_all_registers
+set old_reg_content $all_registers_content
+
+# Perform function calls.
+do_function_calls
+
+# Check if all registers still have the same value.
+do_get_all_registers
+set new_reg_content $all_registers_content
+if ![string compare $old_reg_content $new_reg_content] then {
+ pass "gdb function calls preserve register contents"
+} else {
+ set old_reg_content $all_registers_content
+ fail "gdb function calls preserve register contents"
+}
+
+# Set breakpoint at a function we will call from gdb.
+gdb_breakpoint add
+
+# Call function (causing a breakpoint hit in the call dummy) and do a continue,
+# make sure we are back at main and still have the same register contents.
+gdb_test "print add(4,5)" \
+ "The program being debugged stopped while.*" \
+ "stop at breakpoint in call dummy function"
+gdb_test "continue" "Continuing.*" "continue from call dummy breakpoint"
+if ![gdb_test "bt 2" \
+ "#0 main.*" \
+ "bt after continuing from call dummy breakpoint"] then {
+ do_get_all_registers
+ set new_reg_content $all_registers_content
+ if ![string compare $old_reg_content $new_reg_content] then {
+ pass "continue after stop in call dummy preserves register contents"
+ } else {
+ fail "continue after stop in call dummy preserves register contents"
+ }
+}
+
+# Call function (causing a breakpoint hit in the call dummy) and do a finish,
+# make sure we are back at main and still have the same register contents.
+gdb_test "print add(4,5)" "The program being debugged stopped while.*" ""
+gdb_test "finish" \
+ "Value returned is .* = 9" \
+ "finish from call dummy breakpoint returns correct value"
+if ![gdb_test "bt 2" \
+ "#0 main.*" \
+ "bt after finishing from call dummy breakpoint"] then {
+ do_get_all_registers
+ set new_reg_content $all_registers_content
+ if ![string compare $old_reg_content $new_reg_content] then {
+ pass "finish after stop in call dummy preserves register contents"
+ } else {
+ fail "finish after stop in call dummy preserves register contents"
+ }
+}
+
+# Call function (causing a breakpoint hit in the call dummy) and do a return
+# with a value, make sure we are back at main with the same register contents.
+gdb_test "print add(4,5)" "The program being debugged stopped while.*" ""
+if ![gdb_test "return 7" \
+ "#0 main.*" \
+ "back at main after return from call dummy breakpoint" \
+ "Make add return now. .y or n.*" \
+ "y"] then {
+ do_get_all_registers
+ set new_reg_content $all_registers_content
+ if ![string compare $old_reg_content $new_reg_content] then {
+ pass "return after stop in call dummy preserves register contents"
+ } else {
+ fail "return after stop in call dummy preserves register contents"
+ }
+}
+
+# Call function (causing a breakpoint hit in the call dummy), and
+# call another function from the call dummy frame (thereby setting up
+# several nested call dummy frames). Test that backtrace and finish
+# work when several call dummies are nested.
+gdb_breakpoint sum10
+gdb_breakpoint t_small_values
+gdb_test "print add(2,3)" "The program being debugged stopped while.*" \
+ "stop at nested call level 1"
+gdb_test "backtrace" \
+ "\#0 add \\(a=2, b=3\\).*\#1 <function called from gdb>.*\#2 main.*" \
+ "backtrace at nested call level 1"
+gdb_test "print add(4,5)" "The program being debugged stopped while.*" \
+ "stop at nested call level 2"
+gdb_test "backtrace" \
+ "\#0 add \\(a=4, b=5\\).*\#1 <function called from gdb>.*\#2 add \\(a=2, b=3\\).*\#3 <function called from gdb>.*\#4 main.*" \
+ "backtrace at nested call level 2"
+gdb_test "print sum10(2,4,6,8,10,12,14,16,18,20)" \
+ "The program being debugged stopped while.*" \
+ "stop at nested call level 3"
+gdb_test "backtrace" \
+ "\#0 sum10 \\(i0=2, i1=4, i2=6, i3=8, i4=10, i5=12, i6=14, i7=16, i8=18, i9=20\\).*\#1 <function called from gdb>.*\#2 add \\(a=4, b=5\\).*\#3 <function called from gdb>.*\#4 add \\(a=2, b=3\\).*\#5 <function called from gdb>.*\#6 main.*" \
+ "backtrace at nested call level 3"
+gdb_test "print t_small_values(1,3,5,7,9,11,13,15,17,19)" \
+ "The program being debugged stopped while.*" \
+ "stop at nested call level 4"
+gdb_test "backtrace" \
+ "\#0 t_small_values \\(arg1=1 '.001', arg2=3, arg3=5, arg4=7 '.a', arg5=9, arg6=11 '.v', arg7=13, arg8=15, arg9=17, arg10=19\\).*\#2 sum10 \\(i0=2, i1=4, i2=6, i3=8, i4=10, i5=12, i6=14, i7=16, i8=18, i9=20\\).*\#3 <function called from gdb>.*\#4 add \\(a=4, b=5\\).*\#5 <function called from gdb>.*\#6 add \\(a=2, b=3\\).*\#7 <function called from gdb>.*\#8 main.*" \
+ "backtrace at nested call level 4"
+gdb_test "finish" "Value returned is .* = 100" \
+ "Finish from nested call level 4"
+gdb_test "backtrace" \
+ "\#0 sum10 \\(i0=2, i1=4, i2=6, i3=8, i4=10, i5=12, i6=14, i7=16, i8=18, i9=20\\).*\#1 <function called from gdb>.*\#2 add \\(a=4, b=5\\).*\#3 <function called from gdb>.*\#4 add \\(a=2, b=3\\).*\#5 <function called from gdb>.*\#6 main.*" \
+ "backtrace after finish from nested call level 4"
+gdb_test "finish" "Value returned is .* = 110" \
+ "Finish from nested call level 3"
+gdb_test "backtrace" \
+ "\#0 add \\(a=4, b=5\\).*\#1 <function called from gdb>.*\#2 add \\(a=2, b=3\\).*\#3 <function called from gdb>.*\#4 main.*" \
+ "backtrace after finish from nested call level 3"
+gdb_test "finish" "Value returned is .* = 9" \
+ "Finish from nested call level 2"
+gdb_test "backtrace" \
+ "\#0 add \\(a=2, b=3\\).*\#1 <function called from gdb>.*\#2 main.*" \
+ "backtrace after finish from nested call level 2"
+gdb_test "finish" "Value returned is .* = 5" \
+ "Finish from nested call level 1"
+gdb_test "backtrace" "\#0 main .*" \
+ "backtrace after finish from nested call level 1"
+
+do_get_all_registers
+set new_reg_content $all_registers_content
+if ![string compare $old_reg_content $new_reg_content] then {
+ pass "nested call dummies preserve register contents"
+} else {
+ fail "nested call dummies preserve register contents"
+}
+
+return 0
+
diff --git a/gdb/testsuite/gdb.base/code-expr.exp b/gdb/testsuite/gdb.base/code-expr.exp
new file mode 100644
index 00000000000..03cc4effe74
--- /dev/null
+++ b/gdb/testsuite/gdb.base/code-expr.exp
@@ -0,0 +1,395 @@
+# Copyright (C) 2001 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Written by Michael Snyder, Red Hat, Inc., 9/20/2001
+
+# This file is part of the gdb testsuite
+# Tests for type expressions using the new "@code" and "@data" modifiers.
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "cvexpr"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+
+gdb_test "set print sevenbit-strings" "" ""
+gdb_test "set print address off" "" ""
+gdb_test "set width 0" "" ""
+
+set ws "\[ \t\]*"
+
+#
+# Test casting a scalar to const
+#
+
+gdb_test "whatis (@code char) v_char" \
+ "type = @code char" \
+ "(@code char)"
+gdb_test "whatis (@code signed char) v_signed_char" \
+ "type = @code signed char" \
+ "(@code signed char)"
+gdb_test "whatis (@code unsigned char) v_unsigned_char" \
+ "type = @code (unsigned char|char)" \
+ "(@code unsigned char)"
+gdb_test "whatis (@code short) v_short" \
+ "type = @code (short|short int)" \
+ "(@code short)"
+gdb_test "whatis (@code signed short) v_signed_short" \
+ "type = @code (short|short int|signed short|signed short int)" \
+ "(@code signed short)"
+gdb_test "whatis (@code unsigned short) v_unsigned_short" \
+ "type = @code (unsigned short|short unsigned int)" \
+ "(@code unsigned short)"
+gdb_test "whatis (@code int) v_int" \
+ "type = @code int" \
+ "(@code int)"
+gdb_test "whatis (@code signed int) v_signed_int" \
+ "type = @code (signed int|int)" \
+ "(@code signed int)"
+gdb_test "whatis (@code unsigned int) v_unsigned_int" \
+ "type = @code unsigned int" \
+ "(@code unsigned int)"
+gdb_test "whatis (@code long) v_long" \
+ "type = @code (long|long int)" \
+ "(@code long)"
+gdb_test "whatis (@code signed long) v_signed_long" \
+ "type = @code (signed |)long( int|)" \
+ "(@code signed long)"
+gdb_test "whatis (@code unsigned long) v_unsigned_long" \
+ "type = @code (unsigned long|long unsigned int)" \
+ "(@code unsigned long)"
+gdb_test "whatis (@code long long) v_long_long" \
+ "type = @code long long( int|)" \
+ "(@code long long)"
+gdb_test "whatis (@code signed long long) v_signed_long_long" \
+ "type = @code (signed |)long long( int|)" \
+ "(@code signed long long)"
+gdb_test "whatis (@code unsigned long long) v_unsigned_long_long" \
+ "type = @code (unsigned long long|long long unsigned int)" \
+ "(@code unsigned long long)"
+gdb_test "whatis (@code float) v_float" \
+ "type = @code float" \
+ "(@code float)"
+gdb_test "whatis (@code double) v_double" \
+ "type = @code double" \
+ "(@code double)"
+
+#
+# Test casting a scalar to @data
+#
+
+gdb_test "whatis (@data char) v_char" \
+ "type = @data char" \
+ "(@data char)"
+gdb_test "whatis (@data signed char) v_signed_char" \
+ "type = @data signed char" \
+ "(@data signed char)"
+gdb_test "whatis (@data unsigned char) v_unsigned_char" \
+ "type = @data (unsigned char|char)" \
+ "(@data unsigned char)"
+gdb_test "whatis (@data short) v_short" \
+ "type = @data (short|short int)" \
+ "(@data short)"
+gdb_test "whatis (@data signed short) v_signed_short" \
+ "type = @data (short|short int|signed short|signed short int)" \
+ "(@data signed short)"
+gdb_test "whatis (@data unsigned short) v_unsigned_short" \
+ "type = @data (unsigned short|short unsigned int)" \
+ "(@data unsigned short)"
+gdb_test "whatis (@data int) v_int" \
+ "type = @data int" \
+ "(@data int)"
+gdb_test "whatis (@data signed int) v_signed_int" \
+ "type = @data (signed int|int)" \
+ "(@data signed int)"
+gdb_test "whatis (@data unsigned int) v_unsigned_int" \
+ "type = @data unsigned int" \
+ "(@data unsigned int)"
+gdb_test "whatis (@data long) v_long" \
+ "type = @data (long|long int)" \
+ "(@data long)"
+gdb_test "whatis (@data signed long) v_signed_long" \
+ "type = @data (signed |)long( int|)" \
+ "(@data signed long)"
+gdb_test "whatis (@data unsigned long) v_unsigned_long" \
+ "type = @data (unsigned long|long unsigned int)" \
+ "(@data unsigned long)"
+gdb_test "whatis (@data long long) v_long_long" \
+ "type = @data long long( int|)" \
+ "(@data long long)"
+gdb_test "whatis (@data signed long long) v_signed_long_long" \
+ "type = @data (signed |)long long( int|)" \
+ "(@data signed long long)"
+gdb_test "whatis (@data unsigned long long) v_unsigned_long_long" \
+ "type = @data (unsigned long long|long long unsigned int)" \
+ "(@data unsigned long long)"
+gdb_test "whatis (@data float) v_float" \
+ "type = @data float" \
+ "(@data float)"
+gdb_test "whatis (@data double) v_double" \
+ "type = @data double" \
+ "(@data double)"
+
+#
+# Now put the '@code' and '@data' keywords after the base type.
+#
+
+gdb_test "whatis (char @code) v_char" \
+ "type = @code char" \
+ "(char @code)"
+gdb_test "whatis (signed char @code) v_signed_char" \
+ "type = @code signed char" \
+ "(signed char @code)"
+gdb_test "whatis (unsigned char @code) v_unsigned_char" \
+ "type = @code (unsigned char|char)" \
+ "(unsigned char @code)"
+gdb_test "whatis (short @code) v_short" \
+ "type = @code (short|short int)" \
+ "(short @code)"
+gdb_test "whatis (signed short @code) v_signed_short" \
+ "type = @code (short|short int|signed short|signed short int)" \
+ "(signed short @code)"
+gdb_test "whatis (unsigned short @code) v_unsigned_short" \
+ "type = @code (unsigned short|short unsigned int)" \
+ "(unsigned short @code)"
+gdb_test "whatis (int @code) v_int" \
+ "type = @code int" \
+ "(int @code)"
+gdb_test "whatis (signed int @code) v_signed_int" \
+ "type = @code (signed int|int)" \
+ "(signed int @code)"
+gdb_test "whatis (unsigned int @code) v_unsigned_int" \
+ "type = @code unsigned int" \
+ "(unsigned int @code)"
+gdb_test "whatis (long @code) v_long" \
+ "type = @code (long|long int)" \
+ "(long @code)"
+gdb_test "whatis (signed long @code) v_signed_long" \
+ "type = @code (signed |)long( int|)" \
+ "(signed long @code)"
+gdb_test "whatis (unsigned long @code) v_unsigned_long" \
+ "type = @code (unsigned long|long unsigned int)" \
+ "(unsigned long @code)"
+gdb_test "whatis (long long @code) v_long_long" \
+ "type = @code long long( int|)" \
+ "(long long @code)"
+gdb_test "whatis (signed long long @code) v_signed_long_long" \
+ "type = @code (signed |)long long( int|)" \
+ "(signed long long @code)"
+gdb_test "whatis (unsigned long long @code) v_unsigned_long_long" \
+ "type = @code (unsigned long long|long long unsigned int)" \
+ "(unsigned long long @code)"
+gdb_test "whatis (float @code) v_float" \
+ "type = @code float" \
+ "(float @code)"
+gdb_test "whatis (double @code) v_double" \
+ "type = @code double" \
+ "(double @code)"
+
+gdb_test "whatis (char @data) v_char" \
+ "type = @data char" \
+ "(char @data)"
+gdb_test "whatis (signed char @data) v_signed_char" \
+ "type = @data signed char" \
+ "(signed char @data)"
+gdb_test "whatis (unsigned char @data) v_unsigned_char" \
+ "type = @data (unsigned char|char)" \
+ "(unsigned char @data)"
+gdb_test "whatis (short @data) v_short" \
+ "type = @data (short|short int)" \
+ "(short @data)"
+gdb_test "whatis (signed short @data) v_signed_short" \
+ "type = @data (short|short int|signed short|signed short int)" \
+ "(signed short @data)"
+gdb_test "whatis (unsigned short @data) v_unsigned_short" \
+ "type = @data (unsigned short|short unsigned int)" \
+ "(unsigned short @data)"
+gdb_test "whatis (int @data) v_int" \
+ "type = @data int" \
+ "(int @data)"
+gdb_test "whatis (signed int @data) v_signed_int" \
+ "type = @data (signed int|int)" \
+ "(signed int @data)"
+gdb_test "whatis (unsigned int @data) v_unsigned_int" \
+ "type = @data unsigned int" \
+ "(unsigned int @data)"
+gdb_test "whatis (long @data) v_long" \
+ "type = @data (long|long int)" \
+ "(long @data)"
+gdb_test "whatis (signed long @data) v_signed_long" \
+ "type = @data (signed |)long( int|)" \
+ "(signed long @data)"
+gdb_test "whatis (unsigned long @data) v_unsigned_long" \
+ "type = @data (unsigned long|long unsigned int)" \
+ "(unsigned long @data)"
+gdb_test "whatis (long long @data) v_long_long" \
+ "type = @data long long( int|)" \
+ "(long long @data)"
+gdb_test "whatis (signed long long @data) v_signed_long_long" \
+ "type = @data (signed |)long long( int|)" \
+ "(signed long long @data)"
+gdb_test "whatis (unsigned long long @data) v_unsigned_long_long" \
+ "type = @data (unsigned long long|long long unsigned int)" \
+ "(unsigned long long @data)"
+gdb_test "whatis (float @data) v_float" \
+ "type = @data float" \
+ "(float @data)"
+gdb_test "whatis (double @data) v_double" \
+ "type = @data double" \
+ "(double @data)"
+
+#
+# enums
+#
+
+gdb_test "whatis (@code enum misordered) v_misordered" \
+ "type = @code enum misordered" \
+ "(@code enum misordered)"
+gdb_test "whatis (enum misordered @code) v_misordered" \
+ "type = @code enum misordered" \
+ "(enum misordered @code)"
+gdb_test "whatis (@data enum misordered) v_misordered" \
+ "type = @data enum misordered" \
+ "(@data enum misordered)"
+gdb_test "whatis (enum misordered @data) v_misordered" \
+ "type = @data enum misordered" \
+ "(enum misordered @data)"
+
+#
+# Pointers
+#
+
+gdb_test "whatis (@code int *) v_int_pointer" \
+ "type = @code int${ws}\\*" \
+ "(@code int *)"
+gdb_test "whatis (int @code *) v_int_pointer" \
+ "type = @code int${ws}\\*" \
+ "(int @code *)"
+gdb_test "whatis (int * @code) v_int_pointer" \
+ "type = int \\*${ws}@code" \
+ "(int * @code)"
+gdb_test "whatis (@code int * @code) v_int_pointer" \
+ "type = @code int${ws}\\*${ws}@code" \
+ "(@code int * @code)"
+gdb_test "whatis (int @code * @code) v_int_pointer" \
+ "type = @code int${ws}\\*${ws}@code" \
+ "(int @code * @code)"
+
+gdb_test "whatis (@code int **) v_int_pointer_pointer" \
+ "type = @code int${ws}\\*${ws}\\*" \
+ "(@code int **)"
+gdb_test "whatis (int @code **) v_int_pointer_pointer" \
+ "type = @code int${ws}\\*${ws}\\*" \
+ "(int @code **)"
+gdb_test "whatis (int ** @code) v_int_pointer_pointer" \
+ "type = int \\*${ws}\\*${ws}@code" \
+ "(int ** @code)"
+gdb_test "whatis (@code int * @code *) v_int_pointer_pointer" \
+ "type = @code int${ws}\\*${ws}@code${ws}\\*" \
+ "(@code int * @code *)"
+gdb_test "whatis (int @code * @code *) v_int_pointer_pointer" \
+ "type = @code int${ws}\\*${ws}@code${ws}\\*" \
+ "(int @code * @code *)"
+gdb_test "whatis (@code int * @code * @code) v_int_pointer_pointer" \
+ "type = @code int${ws}\\*${ws}@code${ws}\\*${ws}@code" \
+ "(@code int * @code * @code)"
+gdb_test "whatis (int @code * @code * @code) v_int_pointer_pointer" \
+ "type = @code int${ws}\\*${ws}@code${ws}\\*${ws}@code" \
+ "(int @code * @code * @code)"
+
+#
+# Arrays TODO
+#
+
+#
+# Pointers to arrays, arrays of pointers TODO
+#
+
+#
+# Structs and Unions
+#
+
+gdb_test "whatis (@code struct t_struct) v_struct1" \
+ "type = @code struct t_struct" \
+ "(@code struct t_struct)"
+gdb_test "whatis (@code union t_union) v_union" \
+ "type = @code union t_union" \
+ "(@code union t_union)"
+gdb_test "whatis (struct t_struct @code) v_struct1" \
+ "type = @code struct t_struct" \
+ "(struct t_struct @code)"
+gdb_test "whatis (union t_union @code) v_union" \
+ "type = @code union t_union" \
+ "(union t_union @code)"
+gdb_test "whatis (@code struct t_struct *) &v_struct1" \
+ "type = @code struct t_struct${ws}\\*" \
+ "(@code struct t_struct *)"
+gdb_test "whatis (@code union t_union *) &v_union" \
+ "type = @code union t_union${ws}\\*" \
+ "(@code union t_union *)"
+gdb_test "whatis (struct t_struct @code *) &v_struct1" \
+ "type = @code struct t_struct${ws}\\*" \
+ "(struct t_struct @code *)"
+gdb_test "whatis (union t_union @code *) &v_union" \
+ "type = @code union t_union${ws}\\*" \
+ "(union t_union @code *)"
+gdb_test "whatis (struct t_struct * @code) &v_struct1" \
+ "type = struct t_struct${ws}\\*${ws}@code" \
+ "(struct t_struct * @code)"
+gdb_test "whatis (union t_union * @code) &v_union" \
+ "type = union t_union${ws}\\*${ws}@code" \
+ "(union t_union * @code)"
+gdb_test "whatis (@code struct t_struct * @code) &v_struct1" \
+ "type = @code struct t_struct${ws}\\*${ws}@code" \
+ "(@code struct t_struct * @code)"
+gdb_test "whatis (@code union t_union * @code) &v_union" \
+ "type = @code union t_union${ws}\\*${ws}@code" \
+ "(@code union t_union * @code)"
+gdb_test "whatis (struct t_struct @code * @code) &v_struct1" \
+ "type = @code struct t_struct${ws}\\*${ws}@code" \
+ "(struct t_struct @code * @code)"
+gdb_test "whatis (union t_union @code * @code) &v_union" \
+ "type = @code union t_union${ws}\\*${ws}@code" \
+ "(union t_union @code * @code)"
+
+#
+# Function pointers TODO
+#
+
diff --git a/gdb/testsuite/gdb.base/commands.exp b/gdb/testsuite/gdb.base/commands.exp
new file mode 100644
index 00000000000..dfaf965ca99
--- /dev/null
+++ b/gdb/testsuite/gdb.base/commands.exp
@@ -0,0 +1,456 @@
+# Copyright 1988, 1990, 1991, 1992, 1994, 1995, 1997, 1998, 1999, 2000,
+# 2001 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+#
+# test special commands (if, while, etc)
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "run"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/commands
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+delete_breakpoints
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+proc gdbvar_simple_if_test {} {
+ global gdb_prompt
+
+ gdb_test "set \$foo = 0" "" "set foo in gdbvar_simple_if_test"
+ # All this test should do is print 0xdeadbeef once.
+ gdb_test "if \$foo == 1\np/x 0xfeedface\nelse\np/x 0xdeadbeef\nend" \
+ "\\\$\[0-9\]* = 0xdeadbeef" "gdbvar_simple_if_test #1"
+ # All this test should do is print 0xfeedface once.
+ gdb_test "if \$foo == 0\np/x 0xfeedface\nelse\np/x 0xdeadbeef\nend" \
+ "\\\$\[0-9\]* = 0xfeedface" "gdbvar_simple_if_test #2"
+}
+
+proc gdbvar_simple_while_test {} {
+ global gdb_prompt
+
+ gdb_test "set \$foo = 5" "" "set foo in gdbvar_simple_while_test"
+ # This test should print 0xfeedface five times.
+ gdb_test "while \$foo > 0\np/x 0xfeedface\nset \$foo -= 1\nend" \
+ "\\\$\[0-9\]* = 0xfeedface\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface" \
+ "gdbvar_simple_while_test #1"
+}
+
+proc gdbvar_complex_if_while_test {} {
+ global gdb_prompt
+
+ gdb_test "set \$foo = 4" "" "set foo in gdbvar complex_if_while_test"
+ # This test should alternate between 0xdeadbeef and 0xfeedface two times.
+ gdb_test "while \$foo > 0\nset \$foo -= 1\nif \(\$foo % 2\) == 1\np/x 0xdeadbeef\nelse\np/x 0xfeedface\nend\nend" \
+ "\\\$\[0-9\]* = 0xdeadbeef\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface\[^\n\]*\n\\\$\[0-9\]* = 0xdeadbeef\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface" \
+ "gdbvar_complex_if_while_test #1"
+}
+
+proc progvar_simple_if_test {} {
+ global gdb_prompt
+
+ if [target_info exists noargs] {
+ verbose "Skipping progvar_simple_if_test because of noargs."
+ return
+ }
+
+ if { ![runto factorial] } then { gdb_suppress_tests; }
+ # Don't depend upon argument passing, since most simulators don't
+ # currently support it. Bash value variable to be what we want.
+ gdb_test "p value=5" "" "set value to 5 in progvar_simple_if_test #1"
+ # All this test should do is print 0xdeadbeef once.
+ gdb_test "if value == 1\np/x 0xfeedface\nelse\np/x 0xdeadbeef\nend" \
+ "\\\$\[0-9\]* = 0xdeadbeef" \
+ "progvar_simple_if_test #1"
+ # All this test should do is print 0xfeedface once.
+ gdb_test "if value == 5\np/x 0xfeedface\nelse\np/x 0xdeadbeef\nend" \
+ "\\\$\[0-9\]* = 0xfeedface" \
+ "progvar_simple_if_test #2"
+ gdb_stop_suppressing_tests;
+}
+
+proc progvar_simple_while_test {} {
+ global gdb_prompt
+
+ if [target_info exists noargs] {
+ verbose "Skipping progvar_simple_while_test because of noargs."
+ return
+ }
+
+ gdb_test "set args 5" "" "set args in progvar_simple_while_test"
+ if { ![runto factorial] } then { gdb_suppress_tests }
+ # Don't depend upon argument passing, since most simulators don't
+ # currently support it. Bash value variable to be what we want.
+ gdb_test "p value=5" "" "set value to 5 in progvar_simple_if_test #2"
+ # This test should print 0xfeedface five times.
+ gdb_test "while value > 0\np/x 0xfeedface\nset value -= 1\nend" \
+ "\\\$\[0-9\]* = 0xfeedface\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface" \
+ "progvar_simple_while_test #1"
+ gdb_stop_suppressing_tests;
+}
+
+proc progvar_complex_if_while_test {} {
+ global gdb_prompt
+
+ if [target_info exists noargs] {
+ verbose "Skipping progvar_simple_if_while_test because of noargs."
+ return
+ }
+
+ gdb_test "set args 4" "" "set args in progvar_complex_if_while_test"
+ if { ![runto factorial] } then { gdb_suppress_tests }
+ # Don't depend upon argument passing, since most simulators don't
+ # currently support it. Bash value variable to be what we want.
+ gdb_test "p value=4" "" "set value to 4 in progvar_simple_if_test"
+ # This test should alternate between 0xdeadbeef and 0xfeedface two times.
+ gdb_test "while value > 0\nset value -= 1\nif \(value % 2\) == 1\np/x 0xdeadbeef\nelse\np/x 0xfeedface\nend\nend" \
+ "\\\$\[0-9\]* = 0xdeadbeef\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface\[^\n\]*\n\\\$\[0-9\]* = 0xdeadbeef\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface" \
+ "progvar_complex_if_while_test #1"
+ gdb_stop_suppressing_tests;
+}
+
+proc if_while_breakpoint_command_test {} {
+ if [target_info exists noargs] {
+ verbose "Skipping if_while_breakpoint_command_test because of noargs."
+ return
+ }
+
+ gdb_test "set args 5" "" "set args in if_while_breakpoint_command_test"
+ if { ![runto factorial] } then { gdb_suppress_tests }
+ # Don't depend upon argument passing, since most simulators don't
+ # currently support it. Bash value variable to be what we want.
+ gdb_test "p value=5" "" "set value to 5 in progvar_simple_if_test"
+ delete_breakpoints
+ gdb_test "break factorial" "Breakpoint.*at.*" "break factorial #1"
+
+ send_gdb "commands\n"
+ gdb_expect {
+ -re "End with" {
+ pass "commands in if_while_breakpoint_command_test"
+ }
+ default {
+ fail "(timeout or eof) commands in if_while_breakpoint_command_test"
+ }
+ }
+ # This test should alternate between 0xdeadbeef and 0xfeedface two times.
+ gdb_test "while value > 0\nset value -= 1\nif \(value % 2\) == 1\np/x 0xdeadbeef\nelse\np/x 0xfeedface\nend\nend\nend" \
+ "" \
+ "commands part 2 in if_while_breakpoint_command_test"
+ gdb_test "continue" \
+ "\\\$\[0-9\]* = 0xdeadbeef\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface\[^\n\]*\n\\\$\[0-9\]* = 0xdeadbeef\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface" \
+ "if_while_breakpoint_command_test #1"
+ gdb_test "info break" \
+ "while.*set.*if.*p/x.*else.*p/x.*end.*" \
+ "info break in if_while_breakpoint_command_test"
+ gdb_stop_suppressing_tests;
+}
+
+# Test that we can run the inferior from breakpoint commands.
+#
+# The expected behavior is that all commands after the first "step"
+# shall be ignored. See the gdb manual, "Break Commands",
+# subsection "Breakpoint command lists".
+
+proc infrun_breakpoint_command_test {} {
+ if [target_info exists noargs] {
+ verbose "Skipping infrun_breakpoint_command_test because of noargs."
+ return
+ }
+
+ gdb_test "set args 6" "" "set args in infrun_breakpoint_command_test"
+ if { ![runto factorial] } then { gdb_suppress_tests }
+ # Don't depend upon argument passing, since most simulators don't
+ # currently support it. Bash value variable to be what we want.
+ gdb_test "p value=6" "" "set value to 6 in progvar_simple_if_test #1"
+ delete_breakpoints
+ gdb_test "break factorial if value == 5" "Breakpoint.*at.*"
+
+# infrun_breakpoint_command_test - This test was broken into two parts
+# to get around a synchronization problem in expect.
+# part1: issue the gdb command "commands"
+# part2: send the list of commands
+ send_gdb "commands\n"
+ gdb_expect {
+ -re "End with" {
+ pass "commands in infrun_breakpoint_command_test #1"
+ }
+ default {
+ fail "(timeout or eof) commands in infrun_breakpoint_command_test"
+ }
+ }
+ gdb_test "step\nstep\nstep\nstep\nend" "" \
+ "commands in infrun_breakpoint_command_test #2"
+
+ gdb_test "continue" \
+ "Continuing.*.*.*Breakpoint \[0-9\]*, factorial \\(value=5\\).*at.*\[0-9\]*\[ \]*if \\(value > 1\\) \{.*\[0-9\]*\[ \]*value \\*= factorial \\(value - 1\\);.*" \
+ "continue in infrun_breakpoint_command_test"
+
+ gdb_stop_suppressing_tests;
+}
+
+proc breakpoint_command_test {} {
+ if [target_info exists noargs] {
+ verbose "Skipping breakpoint_command_test because of noargs."
+ return
+ }
+
+ gdb_test "set args 6" "" "set args in breakpoint_command_test"
+ if { ![runto factorial] } then { gdb_suppress_tests; }
+ # Don't depend upon argument passing, since most simulators don't
+ # currently support it. Bash value variable to be what we want.
+ gdb_test "p value=6" "" "set value to 6 in progvar_simple_if_test #2"
+ delete_breakpoints
+ gdb_test "break factorial" "Breakpoint.*at.*" "break factorial #2"
+ gdb_test "commands\nprintf \"Now the value is %d\\n\", value\nend" \
+ "End with.*" "commands in breakpoint_command_test"
+ gdb_test "continue" \
+ "Breakpoint \[0-9\]*, factorial.*Now the value is 5" \
+ "continue in breakpoint_command_test"
+ gdb_test "print value" " = 5" "print value in breakpoint_command_test"
+ gdb_stop_suppressing_tests;
+}
+
+# Test a simple user defined command (with arguments)
+proc user_defined_command_test {} {
+ global gdb_prompt
+
+ gdb_test "set \$foo = 4" "" "set foo in user_defined_command_test"
+
+ send_gdb "define mycommand\n"
+ gdb_expect {
+ -re "End with" {
+ pass "define mycommand in user_defined_command_test"
+ }
+ default {
+ fail "(timeout or eof) define mycommand in user_defined_command_test"
+ }
+ }
+ # This test should alternate between 0xdeadbeef and 0xfeedface two times.
+ gdb_test "while \$arg0 > 0\nset \$arg0 -= 1\nif \(\$arg0 % 2\) == 1\np/x 0xdeadbeef\nelse\np/x 0xfeedface\nend\nend\nend" \
+ "" \
+ "enter commands in user_defined_command_test"
+
+ gdb_test "mycommand \$foo" \
+ "\\\$\[0-9\]* = 0xdeadbeef\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface\[^\n\]*\n\\\$\[0-9\]* = 0xdeadbeef\[^\n\]*\n\\\$\[0-9\]* = 0xfeedface" \
+ "execute user defined command in user_defined_command_test"
+ gdb_test "show user mycommand" \
+ " while \\\$arg0.*set.* if \\\(\\\$arg0.*p/x.* else\[^\n\].*p/x.* end\[^\n\].* end\[^\n\].*" \
+ "display user command in user_defined_command_test"
+}
+
+proc watchpoint_command_test {} {
+ global noargs
+ global gdb_prompt
+
+ if [target_info exists noargs] {
+ verbose "Skipping watchpoint_command_test because of noargs."
+ return
+ }
+
+ gdb_test "set args 6" "" "set args in watchpoint_command_test"
+ if { ![runto factorial] } then { return }
+ delete_breakpoints
+
+ # Verify that we can create a watchpoint, and give it a commands
+ # list that continues the inferior. We set the watchpoint on a
+ # local variable, too, so that it self-deletes when the watched
+ # data goes out of scope.
+ #
+ # What should happen is: Each time the watchpoint triggers, it
+ # continues the inferior. Eventually, the watchpoint will self-
+ # delete, when the watched variable is out of scope. But by that
+ # time, the inferior should have exited. GDB shouldn't crash or
+ # anything untoward as a result of this.
+ #
+ set wp_id -1
+
+ send_gdb "watch local_var\n"
+ gdb_expect {
+ -re ".*\[Ww\]atchpoint (\[0-9\]*): local_var.*$gdb_prompt $" {
+ set wp_id $expect_out(1,string)
+ pass "watch local_var"
+ }
+ -re "$gdb_prompt $"\
+ {fail "watch local_var"}
+ timeout {fail "(timeout) watch local_var"}
+ }
+
+ if {$wp_id == -1} {return}
+
+ send_gdb "commands $wp_id\n"
+ gdb_expect {
+ -re "Type commands for when breakpoint $wp_id is hit, one per line.*>" {
+ pass "begin commands on watch"
+ }
+ -re "$gdb_prompt $" {fail "begin commands on watch"}
+ timeout {fail "(timeout) begin commands on watch"}
+ }
+ send_gdb "print value\n"
+ gdb_expect {
+ -re ">" {pass "add print command to watch"}
+ -re "$gdb_prompt $" {fail "add print command to watch"}
+ timeout {fail "(timeout) add print command to watch"}
+ }
+ send_gdb "continue\n"
+ gdb_expect {
+ -re ">" {pass "add continue command to watch"}
+ -re "$gdb_prompt $" {fail "add continue command to watch"}
+ timeout {fail "(timeout) add continue command to watch"}
+ }
+ send_gdb "end\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "end commands on watch"}
+ timeout {fail "(timeout) end commands on watch"}
+ }
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Continuing.*\[Ww\]atchpoint $wp_id deleted because the program has left the block in.*which its expression is valid.*run.c:57.*$gdb_prompt $" {
+ pass "continue with watch"
+ }
+ -re "$gdb_prompt $" {fail "continue with watch"}
+ timeout {fail "(timeout) continue with watch"}
+ }
+}
+
+proc test_command_prompt_position {} {
+ global gdb_prompt
+
+ if [target_info exists noargs] {
+ verbose "Skipping test_command_prompt_position because of noargs."
+ return
+ }
+
+ if { ![runto factorial] } then { gdb_suppress_tests; }
+ # Don't depend upon argument passing, since most simulators don't
+ # currently support it. Bash value variable to be what we want.
+ delete_breakpoints
+ gdb_test "break factorial" "Breakpoint.*at.*" "break factorial #3"
+ gdb_test "p value=5" "" "set value to 5 in test_command_prompt_position"
+ # All this test should do is print 0xdeadbeef once.
+ gdb_test "if value == 1\np/x 0xfeedface\nelse\np/x 0xdeadbeef\nend" \
+ "\\\$\[0-9\]* = 0xdeadbeef" \
+ "if test in test_command_prompt_position"
+
+ # Now let's test for the correct position of the '>' in gdb's
+ # prompt for commands. It should be at the beginning of the line,
+ # and not after one space.
+
+ send_gdb "commands\n"
+ gdb_expect {
+ -re "Type commands.*End with.*\[\r\n\]>$" {
+ send_gdb "printf \"Now the value is %d\\n\", value\n"
+ gdb_expect {
+ -re "^printf.*value\r\n>$" {
+ send_gdb "end\n"
+ gdb_expect {
+ -re "^end\r\n$gdb_prompt $" {
+ pass "> OK in test_command_prompt_position"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "some other message in test_command_prompt_position"
+ }
+ timeout {
+ fail "(timeout) 1 in test_command_prompt_position"
+ }
+ }
+ }
+ -re "^ >$" { fail "> not OK in test_command_prompt_position" }
+ -re ".*$gdb_prompt $" {
+ fail "wrong message in test_command_prompt_position"
+ }
+ timeout {
+ fail "(timeout) 2 in test_command_prompt_position "
+ }
+ }
+ }
+ -re "Type commands.*End with.*\[\r\n\] >$" {
+ fail "prompt not OK in test_command_prompt_position"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "commands in test_command_prompt_position"
+ }
+ timeout { fail "(timeout) 3 commands in test_command_prompt_position" }
+ }
+
+ gdb_stop_suppressing_tests;
+}
+
+
+
+proc deprecated_command_test {} {
+ gdb_test "maintenance deprecate blah" "Can't find command.*" \
+ "tried to deprecate non-existing command"
+
+ gdb_test "maintenance deprecate p \"new_p\"" "" "maintenance deprecate p \"new_p\" /1/"
+ gdb_test "p 5" \
+ "Warning: 'p', an alias for the command 'print' is deprecated.*Use 'new_p'.*" \
+ "p deprecated warning, with replacement"
+ gdb_test "p 5" ".\[0-9\]* = 5.*" "Deprecated warning goes away /1/"
+
+ gdb_test "maintenance deprecate p \"new_p\"" "" "maintenance deprecate p \"new_p\" /2/"
+ gdb_test "maintenance deprecate print \"new_print\"" ""
+ gdb_test "p 5" \
+ "Warning: command 'print' \\(p\\) is deprecated.*Use 'new_print'.*" \
+ "both alias and command are deprecated"
+ gdb_test "p 5" ".\[0-9\]* = 5.*" "Deprecated warning goes away /2/"
+
+ gdb_test "maintenance deprecate set remote memory-read-packet-size \"srm\" " \
+ "" \
+ "deprecate long command /1/"
+ gdb_test "set remote memory-read-packet-size" \
+ "Warning: command 'set remote memory-read-packet-size' is deprecated.*Use 'srm'.*" \
+ "long command deprecated /1/"
+
+ gdb_test "maintenance deprecate set remote memory-read-packet-size" \
+ "" \
+ "deprecate long command /2/"
+ gdb_test "set remote memory-read-packet-size" \
+ "Warning: command 'set remote memory-read-packet-size' is deprecated.*No alternative known.*" \
+ "long command deprecated with no alternative /2/"
+
+ gdb_test "maintenance deprecate" \
+ "\"maintenance deprecate\".*" \
+ "deprecate with no arguments"
+}
+
+
+gdbvar_simple_if_test
+gdbvar_simple_while_test
+gdbvar_complex_if_while_test
+progvar_simple_if_test
+progvar_simple_while_test
+progvar_complex_if_while_test
+if_while_breakpoint_command_test
+infrun_breakpoint_command_test
+breakpoint_command_test
+user_defined_command_test
+watchpoint_command_test
+test_command_prompt_position
+deprecated_command_test
diff --git a/gdb/testsuite/gdb.base/completion.exp b/gdb/testsuite/gdb.base/completion.exp
new file mode 100644
index 00000000000..332e1697a7f
--- /dev/null
+++ b/gdb/testsuite/gdb.base/completion.exp
@@ -0,0 +1,749 @@
+# Copyright 1998, 1999, 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+# This file is part of the gdb testsuite.
+
+#
+# tests for command completion
+#
+# Here are some useful test cases for completion.
+# They should be tested with both M-? and TAB.
+#
+# "show output-" "radix"
+# "show output" "-radix"
+# "p" ambiguous (commands starting with p--path, print, printf, etc.)
+# "p " ambiguous (all symbols)
+# "info t foo" no completions
+# "info t " no completions
+# "info t" ambiguous ("info target", "info terminal", etc.)
+# "info ajksdlfk" no completions
+# "info ajksdlfk " no completions
+# "info" " "
+# "info " ambiguous (all info commands)
+# "p \"break" unambiguous (completes to filename "break.c")
+# "p \"break." unambiguous (should complete to "break.c" but does not,
+# due to readline limitations)
+# "p 'a" ambiguous (all symbols starting with a)
+# "p b-a" ambiguous (all symbols starting with a)
+# "p b-" ambiguous (all symbols)
+# "file Make" "file" (word break hard to screw up here)
+# "file ../gdb.stabs/we" "ird" (needs to not break word at slash)
+#
+
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+
+global usestubs
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "break"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+gdb_exit
+
+# Don't let a .inputrc file or an existing setting of INPUTRC mess up
+# the test results. Even if /dev/null doesn't exist on the particular
+# platform, the readline library will use the default setting just by
+# failing to open the file. OTOH, opening /dev/null successfully will
+# also result in the default settings being used since nothing will be
+# read from this file.
+global env
+if [info exists env(INPUTRC)] {
+ set old_inputrc $env(INPUTRC)
+}
+set env(INPUTRC) "/dev/null"
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ perror "tests suppressed"
+}
+
+set oldtimeout1 $timeout
+set timeout 30
+
+
+send_gdb "hfgfh\t"
+sleep 1
+gdb_expect {
+ -re "^hfgfh\\\x07$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "Undefined command: \"hfgfh\"\\. Try \"help\"\\..*$gdb_prompt $"\
+ { pass "complete 'hfgfh'"}
+ -re ".*$gdb_prompt $" { fail "complete 'hfgfh'"}
+ timeout {fail "(timeout) complete 'hfgfh'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'hfgfh'" }
+ timeout { fail "(timeout) complete 'hfgfh'" }
+ }
+
+#exp_internal 0
+
+send_gdb "show output\t"
+sleep 1
+gdb_expect {
+ -re "^show output-radix $"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "Default output radix for printing of values is 10\\..*$gdb_prompt $"\
+ { pass "complete 'show output'"}
+ -re ".*$gdb_prompt $" { fail "complete 'show output'"}
+ timeout {fail "(timeout) complete 'show output'"}
+ }
+ }
+ -re "^show output$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "Default output radix for printing of values is 10\\..*$gdb_prompt $"\
+ { fail "complete 'show output'"}
+ -re ".*$gdb_prompt $" { fail "complete 'show output'"}
+ timeout { fail "(timeout) complete 'show output'"}
+ }
+
+ }
+
+ -re ".*$gdb_prompt $" { fail "complete 'show output'" }
+ timeout { fail "(timeout) complete 'show output'" }
+ }
+
+
+send_gdb "show output-\t"
+sleep 1
+gdb_expect {
+ -re "^show output-radix $"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "Default output radix for printing of values is 10\\..*$gdb_prompt $"\
+ { pass "complete 'show output-'"}
+ -re ".*$gdb_prompt $" { fail "complete 'show output-'"}
+ timeout {fail "(timeout) complete 'show output-'"}
+ }
+ }
+ -re "^show output-$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "Default output radix for printing of values is 10\\..*$gdb_prompt $"\
+ { fail "complete 'show output-'"}
+ -re ".*$gdb_prompt $" { fail "complete 'show output-'"}
+ timeout { fail "(timeout) complete 'show output-'"}
+ }
+
+ }
+
+ -re ".*$gdb_prompt $" { fail "complete 'show output-'" }
+ timeout { fail "(timeout) complete 'show output-'" }
+ }
+
+send_gdb "p\t"
+sleep 1
+gdb_expect {
+ -re "^p\\\x07$"\
+ { send_gdb "\n"
+ sleep 1
+ gdb_expect {
+ -re "The history is empty\\..*$gdb_prompt $"\
+ { pass "complete 'p'"}
+ -re ".*$gdb_prompt $" { fail "complete 'p'"}
+ timeout {fail "(timeout) complete 'p' 2"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'p'" }
+ timeout { fail "(timeout) complete 'p' 1" }
+ }
+
+send_gdb "p \t"
+sleep 3
+gdb_expect {
+ -re "^p \\\x07$"\
+ { send_gdb "\n"
+ sleep 1
+ gdb_expect {
+ -re "The history is empty\\..*$gdb_prompt $"\
+ { pass "complete 'p '"}
+ -re ".*$gdb_prompt $" { fail "complete 'p '"}
+ timeout {fail "(timeout) complete 'p ' 1"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'p '" }
+ timeout { fail "(timeout) complete 'p ' 2" }
+ }
+
+
+send_gdb "info t foo\t"
+sleep 1
+gdb_expect {
+ -re "^info t foo\\\x07$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "Ambiguous info command \"t foo\": target, terminal, threads, tp, tracepoints, types\\..*$gdb_prompt $"\
+ { pass "complete 'info t foo'"}
+ -re ".*$gdb_prompt $" { fail "complete 'info t foo'"}
+ timeout {fail "(timeout) complete 'info t foo'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'info t foo'" }
+ timeout { fail "(timeout) complete 'info t foo'" }
+ }
+
+send_gdb "info t\t"
+sleep 1
+gdb_expect {
+ -re "^info t\\\x07$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "Ambiguous info command \"t\": target, terminal, threads, tp, tracepoints, types\\..
+*$gdb_prompt $"\
+ { pass "complete 'info t'"}
+ -re ".*$gdb_prompt $" { fail "complete 'info t'"}
+ timeout {fail "(timeout) complete 'info t'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'info t'" }
+ timeout { fail "(timeout) complete 'info t'" }
+ }
+
+
+send_gdb "info t \t"
+sleep 1
+gdb_expect {
+ -re "^info t \\\x07$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "Ambiguous info command \"t \": target, terminal, threads, tp, tracepoints, types\\..
+*$gdb_prompt $"\
+ { pass "complete 'info t '"}
+ -re ".*$gdb_prompt $" { fail "complete 'info t '"}
+ timeout {fail "(timeout) complete 'info t '"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'info t '" }
+ timeout { fail "(timeout) complete 'info t '" }
+ }
+
+
+send_gdb "info asdfgh\t"
+sleep 1
+gdb_expect {
+ -re "^info asdfgh\\\x07$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "Undefined info command: \"asdfgh\". Try \"help info\"\\..
+*$gdb_prompt $"\
+ { pass "complete 'info asdfgh'"}
+ -re ".*$gdb_prompt $" { fail "complete 'info asdfgh'"}
+ timeout {fail "(timeout) complete 'info asdfgh'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'info asdfgh'" }
+ timeout { fail "(timeout) complete 'info asdfgh'" }
+ }
+
+
+send_gdb "info asdfgh \t"
+sleep 1
+gdb_expect {
+ -re "^info asdfgh \\\x07$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "Undefined info command: \"asdfgh \". Try \"help info\"\\..
+*$gdb_prompt $"\
+ { pass "complete 'info asdfgh '"}
+ -re ".*$gdb_prompt $" { fail "complete 'info asdfgh '"}
+ timeout {fail "(timeout) complete 'info asdfgh '"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'info asdfgh '" }
+ timeout { fail "(timeout) complete 'info asdfgh '" }
+ }
+
+send_gdb "info\t"
+sleep 1
+gdb_expect {
+ -re "^info $"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "\"info\" must be followed by the name of an info command\\.\r\nList of info subcommands:\r\n\r\n.*info address.*info watchpoints.*\r\n\r\nType \"help info\" followed by info subcommand name for full documentation.\r\nCommand name abbreviations are allowed if unambiguous\\..*$gdb_prompt $"\
+ { pass "complete 'info'"}
+ -re ".*$gdb_prompt $" { fail "complete 'info'"}
+ timeout {fail "(timeout) complete 'info'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'info'" }
+ timeout { fail "(timeout) complete 'info'" }
+ }
+
+send_gdb "info \t"
+sleep 1
+gdb_expect {
+ -re "^info \\\x07$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "\"info\" must be followed by the name of an info command\\.\r\nList of info subcommands:\r\n\r\n.*info address.*Type \"help info\" followed by info subcommand name for full documentation.\r\nCommand name abbreviations are allowed if unambiguous\\..*$gdb_prompt $"\
+ { pass "complete 'info '"}
+ -re ".*$gdb_prompt $" { fail "complete 'info '"}
+ timeout {fail "(timeout) complete 'info '"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'info '" }
+ timeout { fail "(timeout) complete 'info '" }
+ }
+
+
+send_gdb "info \t"
+sleep 1
+gdb_expect {
+ -re "^info \\\x07$"\
+ { send_gdb "\t"
+ gdb_expect {
+ -re "address.*types.*$gdb_prompt info $"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "\"info\".*unambiguous\\..*$gdb_prompt $"\
+ { pass "complete (2) 'info '"}
+ -re ".*$gdb_prompt $" { fail "complete (2) 'info '"}
+ timeout {fail "(timeout) complete (2) 'info '"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete (2) 'info '"}
+ timeout {fail "(timeout) complete (2) 'info '"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete (2) 'info '" }
+ timeout { fail "(timeout) complete (2) 'info '" }
+ }
+
+
+send_gdb "p \"break\t"
+sleep 1
+gdb_expect {
+ -re "^p \"break\\\x07$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" { fail "complete 'p \"break'"}
+ timeout {fail "(timeout) complete 'p \"break'"}
+ }
+ }
+ -re "^p \"break\\.c\"$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" { pass "complete 'p \"break'"}
+ timeout {fail "(timeout) complete 'p \"break'"}
+ }
+ }
+ -re "^p \"break.*$"
+ { send_gdb "\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" { fail "complete 'p \"break'"}
+ timeout {fail "(timeout) complete 'p \"break'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'p \"break'" }
+ timeout { fail "(timeout) complete 'p \"break'" }
+ }
+
+setup_xfail "*-*-*"
+send_gdb "p \"break.\t"
+sleep 1
+gdb_expect {
+ -re "^p \"break\\.\\\x07$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" { fail "complete 'p \"break.'"}
+ timeout {fail "(timeout) complete 'p \"break.'"}
+ }
+ }
+ -re "^p \"break\\.c\"$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" { pass "complete 'p \"break.'"}
+ timeout {fail "(timeout) complete 'p \"break.'"}
+ }
+ }
+ -re "^p \"break\\..*$"
+ { send_gdb "\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" { fail "complete 'p \"break.'"}
+ timeout {fail "(timeout) complete 'p \"break.'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'p \"break.'" }
+ timeout { fail "(timeout) complete 'p \"break.'" }
+ }
+
+send_gdb "p 'a\t"
+sleep 1
+gdb_expect {
+ -re "^p 'a\\\x07$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "(Invalid character constant\\.|Unmatched single quote\\.).*$gdb_prompt $"\
+ { pass "complete 'p \'a'"}
+ -re ".*$gdb_prompt $" { fail "complete 'p \'a'"}
+ timeout {fail "(timeout) complete 'p \'a'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'p \'a'" }
+ timeout { fail "(timeout) complete 'p \'a'" }
+ }
+
+send_gdb "p 'a\t"
+sleep 1
+gdb_expect {
+ -re "^p 'a\\\x07$" {
+ send_gdb "\t"
+ gdb_expect {
+ -re ".*argv.*$gdb_prompt p .a$" {
+ send_gdb "\n"
+ gdb_expect {
+ -re "(Invalid character constant\\.|Unmatched single quote\\.).*$gdb_prompt $" {
+ pass "complete (2) 'p \'a'"
+ }
+ -re ".*$gdb_prompt $" { fail "complete (2) 'p \'a'" }
+ timeout { fail "(timeout) complete (2) 'p \'a'" }
+ }
+ }
+ -re "(There are $decimal possibilities\\. Do you really\r\nwish to see them all.|Display all $decimal possibilities.) \\(y or n\\)$" {
+ send_gdb "n"
+ gdb_expect {
+ -re "\\(gdb\\) p 'a$" {
+ send_gdb "\n"
+ gdb_expect {
+ -re "(Invalid character constant\\.|Unmatched single quote\\.).*$gdb_prompt $" {
+ pass "complete (2) 'p \'a'"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "complete (2) 'p \'a'"
+ }
+ timeout { fail "(timeout) complete (2) 'p \'a'" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete (2) 'p \'a'" }
+ timeout { fail "(timeout) complete (2) 'p \'a'" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete (2) 'p \'a'" }
+ timeout { fail "(timeout) complete (2) 'p \'a'" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete (2) 'p \'a'" }
+ timeout { fail "(timeout) complete (2) 'p \'a'" }
+}
+
+
+# These tests used to try completing the shorter "p b-a".
+# Unfortunately, on some systems, there are .o files in system
+# libraries which declare static variables named `b'. Of course,
+# those variables aren't really in scope, as far as the compiler is
+# concerned. But GDB deliberately tries to be more liberal: if you
+# enter an identifier that doesn't have any binding in scope, GDB will
+# search all the program's compilation units for a static variable of
+# the given name.
+#
+# This behavior can help avoid a lot of pedantry, so it's usually a
+# good thing. But in this test case, it causes GDB to print the value
+# of some random variable, instead of giving us the "No symbol..."
+# error we were expecting.
+#
+# For example, on S/390 linux, the file s_atan.c in libm.a declares a
+# `b', which is a structure containing an int and a float, so GDB says
+# ``Argument to arithmetic operation not a number or boolean'' instead
+# of ``No symbol ...''.
+#
+# So, I'm hoping that there is no system with a static library variable named
+# `no_var_by_this_name'.
+send_gdb "p no_var_named_this-a\t"
+sleep 1
+gdb_expect {
+ -re "^p no_var_named_this-a\\\x07$" {
+ send_gdb "\n"
+ gdb_expect {
+ -re "No symbol \"no_var_named_this\" in current context\\..*$gdb_prompt $" {
+ pass "complete 'p no_var_named_this-a'"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "complete 'p no_var_named_this-a'"
+ }
+ timeout {
+ fail "(timeout) complete 'p no_var_named_this-a'"
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "complete 'p no_var_named_this-a'"
+ }
+ timeout {
+ fail "(timeout) complete 'p no_var_named_this-a'"
+ }
+}
+
+send_gdb "p no_var_named_this-a\t"
+sleep 1
+gdb_expect {
+ -re "^p no_var_named_this-a\\\x07$" {
+ send_gdb "\t"
+ gdb_expect {
+ -re ".*argv.*$gdb_prompt p no_var_named_this-a$" {
+ send_gdb "\n"
+ gdb_expect {
+ -re "No symbol \"no_var_named_this\" in current context\\..*$gdb_prompt $" {
+ pass "complete (2) 'p no_var_named_this-a'"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "complete (2) 'p no_var_named_this-a'"
+ }
+ timeout {
+ fail "(timeout) complete (2) 'p no_var_named_this-a'"
+ }
+ }
+ }
+ -re "(There are $decimal possibilities\\. Do you really\r\nwish to see them all.|Display all $decimal possibilities.) \\(y or n\\)$" {
+ send_gdb "n"
+ gdb_expect {
+ -re "\\(gdb\\) p no_var_named_this-a$" {
+ send_gdb "\n"
+ gdb_expect {
+ -re "No symbol \"no_var_named_this\" in current context\\..*$gdb_prompt $" {
+ pass "complete (2) 'p no_var_named_this-a'"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "complete (2) 'p no_var_named_this-a'"
+ }
+ timeout {
+ fail "(timeout) complete (2) 'p no_var_named_this-a'"
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "complete (2) 'p no_var_named_this-a'"
+ }
+ timeout {
+ fail "(timeout) complete (2) 'p no_var_named_this-a'"
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "complete (2) 'p no_var_named_this-a'"
+ }
+ timeout { fail "(timeout) complete (2) 'p no_var_named_this-a'" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete (2) 'p no_var_named_this-a'" }
+ timeout { fail "(timeout) complete (2) 'p no_var_named_this-a'" }
+}
+
+send_gdb "p no_var_named_this-\t"
+sleep 1
+gdb_expect {
+ -re "^p no_var_named_this-\\\x07$" {
+ send_gdb "\t"
+ gdb_expect {
+ -re "(There are $decimal possibilities\\. Do you really\r\nwish to see them all.|Display all $decimal possibilities.) \\(y or n\\)$" {
+ send_gdb "n"
+ gdb_expect {
+ -re "\\(gdb\\) p no_var_named_this-$" {
+ send_gdb "\n"
+ gdb_expect {
+ -re "No symbol \"no_var_named_this\" in current context\\..*$gdb_prompt $" {
+ pass "complete (2) 'p no_var_named_this-'"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "complete (2) 'p no_var_named_this-'"
+ }
+ timeout {
+ fail "(timeout) complete (2) 'p no_var_named_this-'"
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "complete (2) 'p no_var_named_this-'"
+ }
+ timeout {
+ fail "(timeout) complete (2) 'p no_var_named_this-'"
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "complete (2) 'p no_var_named_this-'"
+ }
+ timeout { fail "(timeout) complete (2) 'p no_var_named_this-'" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete (2) 'p no_var_named_this-'" }
+ timeout { fail "(timeout) complete (2) 'p no_var_named_this-'" }
+}
+
+
+# The following tests used to simply try to complete `${objdir}/Make',
+# and so on. The problem is that ${objdir} can be very long; the
+# completed filename may be more than eighty characters wide. When
+# this happens, readline tries to manage things, producing output that
+# may make sense on the screen, but is rather hard for our script to
+# recognize.
+#
+# In the case that motivated this change, the (gdb) prompt occupied
+# the leftmost six columns, and `${objdump}/' was seventy-four
+# characters long --- eighty in all. After printing the slash,
+# readline emitted a space, a carriage return, and then `Makefile'
+# (the tab character being received as input after `Make'.
+#
+# Basically, you have to let readline do whatever it's going to do to
+# make the screen look right. If it happens to use a different
+# strategy on Tuesdays to get the cursor in the right place, that's
+# not something the testsuite should care about.
+#
+# So, we avoid long lines. We `cd' to ${objdir} first, and then do
+# the completion relative to the current directory.
+#
+# Note that if we are building in the source tree, then there will be
+# more than one completion for ./Make, so we need to handle that also.
+# A better long term solution might be to create a temporary directory,
+# populate it with a set of known names, and use that directory to
+# test completions.
+
+gdb_test "cd ${objdir}" "Working directory ${objdir}.*" "cd to \${objdir}"
+send_gdb "file ./Make\t"
+sleep 1
+gdb_expect {
+ -re "^file ./Make(\\\x07|)file.*$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "\r\nA program is being debugged already\\. Kill it\\? \\(y or n\\) $"\
+ { send_gdb "n\n"
+ gdb_expect {
+ -re "\r\nProgram not killed\\.\r\n$gdb_prompt $"\
+ { pass "complete 'file ./Make'"}
+ -re ".*$gdb_prompt $" { fail "complete 'file ./Make'"}
+ timeout {fail "(timeout) complete 'file ./Make'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'file ./Make'"}
+ timeout {fail "(timeout) complete 'file ./Make'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'file ./Make'" }
+ timeout { fail "(timeout) complete 'file ./Make'" }
+ }
+
+# ${srcdir} may be a relative path. We want to make sure we end up
+# in the right directory - so make sure we know where it is.
+set mydir [pwd]
+cd ${srcdir}
+set fullsrcdir [pwd]
+cd ${mydir}
+
+gdb_test "cd ${fullsrcdir}" "Working directory ${fullsrcdir}.*" "cd to \${srcdir}"
+send_gdb "file ./gdb.base/compl\t"
+sleep 1
+gdb_expect {
+ -re "^file ./gdb.base/completion\\.exp $"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "\r\nA program is being debugged already\\. Kill it\\? \\(y or n\\) $"
+\
+ { send_gdb "n\n"
+ gdb_expect {
+ -re "\r\nProgram not killed\\.\r\n$gdb_prompt $"\
+ { pass "complete 'file ./gdb.base/compl'"}
+ -re ".*$gdb_prompt $" { fail "complete 'file ./gdb.base/compl'"}
+ timeout {fail "(timeout) complete 'file ./gdb.base/compl'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'file ./gdb.base/compl'"}
+ timeout {fail "(timeout) complete 'file ./gdb.base/compl'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'file ./gdb.base/compl'" }
+ timeout { fail "(timeout) complete 'file ./gdb.base/compl'" }
+ }
+
+send_gdb "info func mark\t"
+sleep 1
+gdb_expect {
+ -re "^info func mark.*er$"\
+ {
+ send_gdb "\t\t"
+ sleep 3
+ gdb_expect {
+ -re "marker1.*$gdb_prompt info func marker$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "All functions matching regular expression \"marker\":.*File.*break.c:\r\nint marker1\\(\\);\r\nint marker2\\(int\\).*marker3\\(char.*char.*\\).*marker4\\(long int\\);.*$gdb_prompt $"\
+ { pass "complete 'info func mar'"}
+ -re ".*$gdb_prompt $" { fail "complete 'info func mar'"}
+ timeout {fail "(timeout) complete 'info func mar'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'info func mar'"}
+ timeout {fail "(timeout) complete 'info func mar'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'info func mar'" }
+ timeout { fail "(timeout) complete 'info func mar'" }
+ }
+
+
+send_gdb "set follow-fork-mode \t\t"
+sleep 1
+gdb_expect {
+ -re "ask.*child.*parent.*$gdb_prompt set follow-fork-mode $"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "Requires an argument.*ask.*child.*parent.*$gdb_prompt $"\
+ { pass "complete 'set follow-fork-mode'"}
+ -re "Ambiguous item \"\"\\..*$gdb_prompt $"\
+ { pass "complete 'set follow-fork-mode'"}
+ -re ".*$gdb_prompt $" { fail "complete 'set follow-fork-mode'"}
+ timeout {fail "(timeout) complete 'set follow-fork-mode'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'set follow-fork-mode'" }
+ timeout { fail "(timeout) complete 'set follow-fork-mode'" }
+ }
+
+# Restore globals modified in this test...
+if [info exists old_inputrc] {
+ set env(INPUTRC) $old_inputrc
+} else {
+ unset env(INPUTRC)
+}
+set timeout $oldtimeout1
+
+return 0
diff --git a/gdb/testsuite/gdb.base/cond-expr.exp b/gdb/testsuite/gdb.base/cond-expr.exp
new file mode 100644
index 00000000000..746873cac8a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/cond-expr.exp
@@ -0,0 +1,122 @@
+# Copyright 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+# This file is part of the gdb testsuite
+
+#
+# test of evaluation of conditional expressions, with constants and
+# variables. Using the print and the whatis command
+# written with the only purpose in mind to cover the holes in the
+# eval.c file
+#
+# source file "int-type.c"
+#
+
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+# Check to see if we have an executable to test. If not, then either we
+# haven't tried to compile one, or the compilation failed for some reason.
+# In either case, just notify the user and skip the tests in this file.
+
+set testfile "int-type"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+send_gdb "print (2 ? 3 : 4)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 3.*$gdb_prompt $" {
+ pass "print value of cond expr (const true)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of cond expr (const true)" }
+ timeout { fail "(timeout) print value of cond expr (const true)" }
+ }
+
+send_gdb "print (0 ? 3 : 4)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 4.*$gdb_prompt $" {
+ pass "print value of cond expr (const false)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of cond expr (const false)" }
+ timeout { fail "(timeout) print value of cond expr (const false)" }
+ }
+
+gdb_test "set variable x=14" "" "set variable x=14"
+gdb_test "set variable y=2" "" "set variable y=2"
+gdb_test "set variable z=3" "" "set variable z=3"
+
+send_gdb "print (x ? y : z)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 2.*$gdb_prompt $" {
+ pass "print value of cond expr (var true)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of cond expr (var true)" }
+ timeout { fail "(timeout) print value of cond expr (var true)" }
+ }
+
+gdb_test "set variable x=0" "" "set variable x=0"
+
+send_gdb "print (x ? y : z)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 3.*$gdb_prompt $" {
+ pass "print value of cond expr (var false)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of cond expr (var false)" }
+ timeout { fail "(timeout) print value of cond expr (var false)" }
+ }
+
+
+send_gdb "whatis (0 ? 3 : 4)\n"
+gdb_expect {
+ -re "type = int.*$gdb_prompt $" {
+ pass "print whatis of cond expr"
+ }
+ -re ".*$gdb_prompt $" { fail "print whatis of cond expr" }
+ timeout { fail "(timeout) print whatis of cond expr" }
+ }
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.base/condbreak.exp b/gdb/testsuite/gdb.base/condbreak.exp
new file mode 100644
index 00000000000..c234431f15f
--- /dev/null
+++ b/gdb/testsuite/gdb.base/condbreak.exp
@@ -0,0 +1,207 @@
+# Copyright 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This test was written by Rich Title.
+# Purpose is to test conditional breakpoints.
+# Modeled after "break.exp".
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+global usestubs
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "break"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+
+#
+# test break at function
+#
+gdb_test "break main" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "breakpoint function"
+
+#
+# test conditional break at function
+#
+gdb_test "break marker1 if 1==1" \
+ "Breakpoint.*at.* file .*$srcfile, line.*"
+
+gdb_test "delete 2" ""
+
+#
+# test conditional break at line number
+#
+gdb_test "break 79 if 1==1" \
+ "Breakpoint.*at.* file .*$srcfile, line 79\\."
+
+gdb_test "delete 3" ""
+
+#
+# test conditional break at function
+#
+gdb_test "break marker1 if (1==1)" \
+ "Breakpoint.*at.* file .*$srcfile, line.*"
+
+#
+# test conditional break at line number
+#
+gdb_test "break 79 if (1==1)" \
+ "Breakpoint.*at.* file .*$srcfile, line 79\\."
+
+gdb_test "break marker2 if (a==43)" \
+ "Breakpoint.*at.* file .*$srcfile, line.*"
+
+#
+# check to see what breakpoints are set
+#
+
+if {$hp_aCC_compiler} {
+ set marker1_proto "\\(void\\)"
+ set marker2_proto "\\(int\\)"
+} else {
+ set marker1_proto ""
+ set marker2_proto ""
+}
+
+set main_line 75
+gdb_test "info break" \
+ "Num Type\[ \]+Disp Enb Address\[ \]+What.*
+\[0-9\]+\[\t \]+breakpoint keep y.* in main at .*$srcfile:$main_line.*
+\[0-9\]+\[\t \]+breakpoint keep y.* in marker1$marker1_proto at .*$srcfile:4\[38\].*
+\[\t \]+stop only if 1 == 1.*
+\[0-9\]+\[\t \]+breakpoint keep y.* in main at .*$srcfile:79.*
+\[\t \]+stop only if 1 == 1.*
+\[0-9\]+\[\t \]+breakpoint keep y.* in marker2$marker2_proto at .*$srcfile:4\[49\].*
+\[\t \]+stop only if a == 43.*" \
+ "breakpoint info"
+
+
+#
+# run until the breakpoint at main is hit.
+#
+
+
+rerun_to_main
+
+#
+# run until the breakpoint at a line number
+#
+gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:79.*79\[\t \]+printf.*factorial.*" \
+ "run until breakpoint set at a line number"
+
+#
+# run until the breakpoint at marker1
+#
+# If the inferior stops at the first instruction of a source line, GDB
+# won't print the actual PC value; the source line is enough to
+# exactly specify the PC. But if the inferior is instead stopped in
+# the midst of a source line, GDB will include the PC in the
+# breakpoint hit message. This way, GDB always provides the exact
+# stop location, but avoids clutter when possible.
+#
+# Suppose you have a function written completely on one source line, like:
+# int foo (int x) { return 0; }
+# Setting a breakpoint at `foo' actually places the breakpoint after
+# foo's prologue.
+#
+# GCC's STABS writer always emits a line entry attributing the
+# prologue instructions to the line containing the function's open
+# brace, even if the first user instruction is also on that line.
+# This means that, in the case of a one-line function, you will get
+# two line entries in the debug info for the same line: one at the
+# function's entry point, and another at the first user instruction.
+# GDB preserves these duplicated line entries, and prefers the later
+# one; thus, when the program stops after the prologue, at the first
+# user instruction, GDB's search finds the second line entry, decides
+# that the PC is indeed at the beginning of a source line, and doesn't
+# print an address in the breakpoint hit message.
+#
+# GCC's Dwarf2 writer, on the other hand, squeezes out duplicate line
+# entries, so GDB considers the source line to begin at the start of
+# the function's prologue. Thus, if the program stops at the
+# breakpoint, GDB will decide that the PC is not at the beginning of a
+# source line, and will print an address.
+#
+# I think the Dwarf2 writer's behavior is arguably correct, but not
+# helpful. If the user sets a breakpoint at that source line, they
+# want that breakpoint to fall after the prologue. Identifying the
+# prologue's code with the opening brace is nice, but it shouldn't
+# take precedence over real code.
+#
+# Until the Dwarf2 writer gets fixed, I'm going to XFAIL its behavior.
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing\\..*Breakpoint \[0-9\]+, marker1 \\(\\) at .*$srcfile:4\[38\].*4\[38\]\[\t \]+.*$gdb_prompt $" {
+ pass "run until breakpoint at marker1"
+ }
+ -re "Continuing\\..*Breakpoint \[0-9\]+, $hex in marker1 \\(\\) at .*$srcfile:4\[38\].*4\[38\]\[\t \]+.*$gdb_prompt $" {
+ xfail "run until breakpoint at marker1"
+ }
+ -re "$gdb_prompt $" {
+ fail "run until breakpoint at marker1"
+ }
+ timeout {
+ fail "(timeout) run until breakpoint at marker1"
+ }
+}
+
+# run until the breakpoint at marker2
+# Same issues here as above.
+setup_xfail hppa2.0w-*-* 11512CLLbs
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing\\..*Breakpoint \[0-9\]+, marker2 \\(a=43\\) at .*$srcfile:4\[49\].*4\[49\]\[\t \]+.*" {
+ pass "run until breakpoint at marker2"
+ }
+ -re "Continuing\\..*Breakpoint \[0-9\]+, $hex in marker2 \\(a=43\\) at .*$srcfile:4\[49\].*4\[49\]\[\t \]+.*" {
+ xfail "run until breakpoint at marker2"
+ }
+ -re "$gdb_prompt $" {
+ fail "run until breakpoint at marker2"
+ }
+ timeout {
+ fail "(timeout) run until breakpoint at marker2"
+ }
+}
diff --git a/gdb/testsuite/gdb.base/configure b/gdb/testsuite/gdb.base/configure
new file mode 100644
index 00000000000..77d2d144ada
--- /dev/null
+++ b/gdb/testsuite/gdb.base/configure
@@ -0,0 +1,902 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=gdbvars.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:575: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:596: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:614: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.base/configure.in b/gdb/testsuite/gdb.base/configure.in
new file mode 100644
index 00000000000..7c4e397caa2
--- /dev/null
+++ b/gdb/testsuite/gdb.base/configure.in
@@ -0,0 +1,15 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(gdbvars.exp)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.base/consecutive.c b/gdb/testsuite/gdb.base/consecutive.c
new file mode 100644
index 00000000000..bfea4296aec
--- /dev/null
+++ b/gdb/testsuite/gdb.base/consecutive.c
@@ -0,0 +1,20 @@
+/*
+ Purpose of this test: to test breakpoints on consecutive instructions.
+*/
+
+int a[7] = {1, 2, 3, 4, 5, 6, 7};
+
+/* assert: first line of foo has more than one instruction. */
+int foo ()
+{
+ return a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6];
+}
+
+main()
+{
+#ifdef usestubs
+ set_debug_traps ();
+ breakpoint ();
+#endif
+ foo ();
+}
diff --git a/gdb/testsuite/gdb.base/consecutive.exp b/gdb/testsuite/gdb.base/consecutive.exp
new file mode 100644
index 00000000000..b04ae5ae9b8
--- /dev/null
+++ b/gdb/testsuite/gdb.base/consecutive.exp
@@ -0,0 +1,111 @@
+# Copyright 2001
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder. (msnyder@redhat.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+#
+# Test breakpoints at consecutive instruction addresses.
+#
+
+set prms_id 0
+set bug_id 0
+
+set testfile "consecutive"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+set nl "\[\r\n\]+"
+
+gdb_breakpoint foo
+gdb_test "continue" "Breakpoint $decimal, foo .*" \
+ "continue to breakpoint in foo"
+
+set bp_addr 0
+set stop_addr 0
+
+send_gdb "x /2i \$pc\n"
+gdb_expect {
+ global hex
+ global nl
+ global bp_addr
+ global gdb_prompt
+
+ -re "$hex.*${nl}($hex).*$gdb_prompt $" {
+ set bp_addr $expect_out(1,string)
+ pass "get breakpoint address for foo"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "get breakpoint address for foo"
+ return 0;
+ }
+ timeout {
+ fail "get breakpoint address for foo (timeout)"
+ return 0;
+ }
+}
+
+gdb_test "break \*$bp_addr" "Breakpoint $decimal at $bp_addr: file .*" \
+ "set bp, 2nd instr"
+
+send_gdb "step\n"
+gdb_expect {
+ -re "Breakpoint $decimal, ($hex) in foo.*$gdb_prompt $" {
+ set stop_addr $expect_out(1,string)
+ if [eval expr "$bp_addr == $stop_addr"] then {
+ pass "stopped at bp, 2nd instr"
+ } else {
+ fail "stopped at bp, 2nd instr (wrong address)"
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "stopped at bp, 2nd instr"
+ }
+ timeout {
+ fail "stopped at bp, 2nd instr (timeout)"
+
+ }
+}
+
diff --git a/gdb/testsuite/gdb.base/constvars.c b/gdb/testsuite/gdb.base/constvars.c
new file mode 100644
index 00000000000..b0ce7529ecb
--- /dev/null
+++ b/gdb/testsuite/gdb.base/constvars.c
@@ -0,0 +1,183 @@
+void marker1 (void)
+{
+}
+
+/* misc. function params */
+
+int
+qux1 (const char cc, const char /*&*/ccr, const char *ccp, char *const cpc)
+{
+ return 33;
+}
+
+int
+qux2 (volatile unsigned char vuc, const volatile int cvi,
+ volatile short /*&*/vsr, volatile long *vlp, float *volatile fpv,
+ const volatile signed char *const volatile cvscpcv)
+{
+ return 400;
+}
+
+int
+main (void)
+{
+ char lave = 'B';
+ unsigned char lavish = 10;
+ short lax = 20;
+ unsigned short lecherous = 30;
+ long lechery = 40;
+ unsigned long lectern = 50;
+ float leeway = 60;
+ double legacy = 70;
+ signed char lemonade = 35;
+
+ const char laconic = 'A';
+ const unsigned char laggard = 1;
+ const short lagoon = 2;
+ const unsigned short laity = 3;
+ const long lambent = 4;
+ const unsigned long laminated = 5;
+ const float lampoon = 6;
+ const double languid = 7;
+
+ /* pointers to constant variables */
+
+ const char *legend = &lave;
+ const unsigned char *legerdemain = &lavish;
+ const short *leniency = &lax;
+ const unsigned short *leonine = &lecherous;
+ const long *lesion = &lechery;
+ const unsigned long *lethal = &lectern;
+ const float *lethargic = &leeway;
+ const double *levity = &legacy;
+
+ /* constant pointers to constant variables */
+
+ const char *const lewd = &laconic;
+ const unsigned char *const lexicographer = &laggard;
+ const short *const lexicon = &lagoon;
+ const unsigned short *const liaison = &laity;
+ const long *const libation = &lambent;
+ const unsigned long *const libelous = &laminated;
+ const float *const libertine = &lampoon;
+ const double *const libidinous = &languid;
+
+ /* this is the same as const char * legend .... */
+
+ char const *languish = &laconic;
+ unsigned char const *languor = &laggard;
+ short const *lank = &lagoon;
+ unsigned short const *lapidary = &laity;
+ long const *larceny = &lambent;
+ unsigned long const *largess = &laminated;
+ float const *lascivious = &lampoon;
+ double const *lassitude = &languid;
+
+ /* constant pointers to variable */
+
+ char *const lamprey = &lave;
+ unsigned char *const lariat = &lavish;
+ short *const laudanum = &lax;
+ unsigned short *const lecithin = &lecherous;
+ long *const leviathan = &lechery;
+ unsigned long *const libretto = &lectern;
+ float *const lissome = &leeway;
+ double *const locust = &legacy;
+
+ /* volatile variables */
+
+ volatile char vox = 'X';
+ volatile unsigned char victuals = 13;
+ volatile short vixen = 200;
+ volatile unsigned short vitriol = 300;
+ volatile long vellum = 1000;
+ volatile unsigned long valve = 2000;
+ volatile float vacuity = 3.0;
+ volatile double vertigo = 10.3;
+
+ /* pointers to volatile variables */
+
+ volatile char * vampire = &vox;
+ volatile unsigned char * viper = &victuals;
+ volatile short * vigour = &vixen;
+ volatile unsigned short * vapour = &vitriol;
+ volatile long * ventricle = &vellum;
+ volatile unsigned long * vigintillion = &valve;
+ volatile float * vocation = &vacuity;
+ volatile double * veracity = &vertigo;
+
+ /* volatile pointers to volatile variables */
+
+ volatile char * volatile vapidity = &vox;
+ volatile unsigned char * volatile velocity = &victuals;
+ volatile short * volatile veneer = &vixen;
+ volatile unsigned short * volatile video = &vitriol;
+ volatile long * volatile vacuum = &vellum;
+ volatile unsigned long * volatile veniality = &valve;
+ volatile float * volatile vitality = &vacuity;
+ volatile double * volatile voracity = &vertigo;
+
+ /* const volatile vars */
+
+ const volatile char victor = 'Y';
+ const volatile unsigned char vicar = 11;
+
+ /* pointers to const volatiles */
+
+ const volatile char * victory = &victor;
+ const volatile unsigned char * vicarage = &vicar;
+
+ /* const pointers to volatile vars */
+
+ volatile char * const vein = &vox;
+ volatile unsigned char * const vogue = &victuals;
+
+ /* const pointers to const volatile vars */
+
+ const volatile char * const cavern = &victor;
+ const volatile unsigned char * const coverlet = &vicar;
+
+ /* volatile pointers to const vars */
+
+ const char * volatile caveat = &laconic;
+ const unsigned char * volatile covenant = &laggard;
+
+ /* volatile pointers to const volatile vars */
+
+ const volatile char * volatile vizier = &victor;
+ const volatile unsigned char * volatile vanadium = &vicar;
+
+ /* const volatile pointers */
+
+ char * const volatile vane = &lave;
+ unsigned char * const volatile veldt = &lavish;
+
+ /* const volatile pointers to const vars */
+
+ const char * const volatile cove = &laconic;
+ const unsigned char * const volatile cavity = &laggard;
+
+ /* const volatile pointers to volatile vars */
+
+ volatile char * const volatile vagus = &vox;
+ volatile unsigned char * const volatile vagrancy = &victuals;
+
+ /* const volatile pointers to const volatile */
+
+ const volatile char * const volatile vagary = &victor;
+ const volatile unsigned char * const volatile vendor = &vicar;
+
+ /* misc. references */
+ /*
+ const char & radiation = laconic;
+ volatile signed char & remuneration = lemonade;
+ */
+#ifdef usestubs
+ set_debug_traps ();
+ breakpoint ();
+#endif
+ marker1 ();
+
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/constvars.exp b/gdb/testsuite/gdb.base/constvars.exp
new file mode 100644
index 00000000000..bb062ef5cb9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/constvars.exp
@@ -0,0 +1,283 @@
+# Copyright 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# written by Elena Zannoni (elz@apollo.hp.com)
+#
+# This file is part of the gdb testsuite
+#
+# tests for const variables
+# const pointers to vars
+# pointers to const variables
+# const pointers to const vars
+# with mixed types
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "constvars"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+if {$hp_aCC_compiler || $hp_cc_compiler} {
+ set lang "c++"
+} else {
+ set lang ""
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [concat debug $lang]] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+get_debug_format
+
+proc local_compiler_xfail_check { } {
+ global gcc_compiled;
+
+ if {$gcc_compiled} then {
+ if { ![test_debug_format "HP"] \
+ && ![test_debug_format "DWARF 2"] } then {
+ setup_xfail "*-*-*"
+ }
+ }
+}
+
+send_gdb "break marker1\n" ; gdb_expect -re ".*$gdb_prompt $"
+
+ send_gdb "cont\n"
+ gdb_expect {
+ -re "Break.* marker1 \\(\\) at .*:$decimal.*$gdb_prompt $" {
+ send_gdb "up\n"
+ gdb_expect {
+ -re ".*main.*$gdb_prompt $" {
+ pass "up from marker1"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "up from marker1"
+ }
+ timeout { fail "up from marker1 (timeout)" }
+ }
+ }
+ -re "Break.* marker1__.* \\(\\) at .*:$decimal.*$gdb_prompt $" {
+ fail "continue to marker1 (demangling)"
+ send_gdb "up\n"
+ gdb_expect {
+ -re ".*main.*$gdb_prompt $" {
+ pass "up from marker1"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "up from marker1"
+ }
+ timeout { fail "up from marker1 (timeout)" }
+ }
+ }
+ -re "$gdb_prompt $" { fail "continue to marker1" }
+ timeout { fail "(timeout) continue to marker1" }
+ }
+
+# test function parameters
+
+local_compiler_xfail_check
+send_gdb "ptype qux1\n"
+gdb_expect {
+ -re "type = int \\(const char, const char, const char \\*, char \\* const\\).*$gdb_prompt $" {
+ pass "ptype qux1"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype qux1" }
+ timeout { fail "(timeout) ptype qux1" }
+}
+
+# test vars and pointers
+
+proc do_constvar_tests {} {
+ gdb_test "print lave" " = 66 'B'"
+ gdb_test "ptype lave" "type = char"
+ gdb_test "print lavish" " = 10 '\\\\n'"
+ gdb_test "ptype lavish" "type = unsigned char"
+ gdb_test "print lax" " = 20"
+ gdb_test "ptype lax" "type = short.*"
+ gdb_test "print lecherous" " = 30"
+ local_compiler_xfail_check
+ gdb_test "ptype lecherous" "type = (unsigned short|short unsigned)( int)?"
+ gdb_test "print lechery" " = 40"
+ gdb_test "ptype lechery" "type = long.*"
+ gdb_test "print lectern" " = 50"
+ local_compiler_xfail_check
+ gdb_test "ptype lectern" "type = (unsigned long|long unsigned)( int)?"
+ gdb_test "print leeway" " = 60"
+ gdb_test "ptype leeway" "type = float"
+ gdb_test "print legacy" " = 70"
+ gdb_test "ptype legacy" "type = double"
+ gdb_test "print laconic" " = 65 'A'"
+ local_compiler_xfail_check
+ gdb_test "ptype laconic" "type = const char"
+ gdb_test "print laggard" " = 1 '.001'"
+ local_compiler_xfail_check
+ gdb_test "ptype laggard" "type = const unsigned char"
+ gdb_test "print lagoon" " = 2"
+ local_compiler_xfail_check
+ gdb_test "ptype lagoon" "type = const short( int)?"
+ gdb_test "print laity" " = 3"
+ local_compiler_xfail_check
+ gdb_test "ptype laity" "type = const (unsigned short|short unsigned)( int)?"
+ gdb_test "print lambent" " = 4"
+ local_compiler_xfail_check
+ gdb_test "ptype lambent" "type = const long( int)?"
+ gdb_test "print laminated" " = 5"
+ local_compiler_xfail_check
+ gdb_test "ptype laminated" "type = const (unsigned long|long unsigned)( int)?"
+ gdb_test "print lampoon" " = 6"
+ local_compiler_xfail_check
+ gdb_test "ptype lampoon" "type = const float"
+ gdb_test "print languid" " = 7"
+ local_compiler_xfail_check
+ gdb_test "ptype languid" "type = const double"
+ gdb_test "print *legend" " = 66 'B'"
+ local_compiler_xfail_check
+ gdb_test "ptype legend" "type = const char \\*"
+ gdb_test "print *legerdemain" " = 10 '\\\\n'"
+ local_compiler_xfail_check
+ gdb_test "ptype legerdemain" "type = const unsigned char \\*"
+ gdb_test "print *leniency" " = 20"
+ local_compiler_xfail_check
+ gdb_test "ptype leniency" "type = const short( int)? \\*"
+ gdb_test "print *leonine" " = 30"
+ local_compiler_xfail_check
+ gdb_test "ptype leonine" "type = const (unsigned short|short unsigned)( int)? \\*"
+ gdb_test "print *lesion" " = 40"
+ local_compiler_xfail_check
+ gdb_test "ptype lesion" "type = const long( int)? \\*"
+ gdb_test "print *lethal" " = 50"
+ local_compiler_xfail_check
+ gdb_test "ptype lethal" "type = const (unsigned long|long unsigned)( int)? \\*"
+ gdb_test "print *lethargic" " = 60"
+ local_compiler_xfail_check
+ gdb_test "ptype lethargic" "type = const float \\*"
+ gdb_test "print *levity" " = 70"
+ local_compiler_xfail_check
+ gdb_test "ptype levity" "type = const double \\*"
+ gdb_test "print *lewd" " = 65 'A'"
+ local_compiler_xfail_check
+ gdb_test "ptype lewd" "type = const char \\* const"
+ gdb_test "print *lexicographer" " = 1 '.001'"
+ local_compiler_xfail_check
+ gdb_test "ptype lexicographer" "type = const unsigned char \\* const"
+ gdb_test "print *lexicon" " = 2"
+ local_compiler_xfail_check
+ gdb_test "ptype lexicon" "type = const short( int)? \\* const"
+ gdb_test "print *liaison" " = 3"
+ local_compiler_xfail_check
+ gdb_test "ptype liaison" "type = const (unsigned short|short unsigned)( int)? \\* const"
+ gdb_test "print *libation" " = 4"
+ local_compiler_xfail_check
+ gdb_test "ptype libation" "type = const long( int)? \\* const"
+ gdb_test "print *libelous" " = 5"
+ local_compiler_xfail_check
+ gdb_test "ptype libelous" "type = const (unsigned long|long unsigned)( int)? \\* const"
+ gdb_test "print *libertine" " = 6"
+ local_compiler_xfail_check
+ gdb_test "ptype libertine" "type = const float \\* const"
+ gdb_test "print *libidinous" " = 7"
+ local_compiler_xfail_check
+ gdb_test "ptype libidinous" "type = const double \\* const"
+ gdb_test "print *languish" " = 65 'A'"
+ local_compiler_xfail_check
+ gdb_test "ptype languish" "type = const char \\*"
+ gdb_test "print *languor" " = 1 '.001'"
+ local_compiler_xfail_check
+ gdb_test "ptype languor" "type = const unsigned char \\*"
+ gdb_test "print *lank" " = 2"
+ local_compiler_xfail_check
+ gdb_test "ptype lank" "type = const short( int)? \\*"
+ gdb_test "print *lapidary" " = 3"
+ local_compiler_xfail_check
+ gdb_test "ptype lapidary" "type = const (unsigned short|short unsigned)( int)? \\*"
+ gdb_test "print *larceny" " = 4"
+ local_compiler_xfail_check
+ gdb_test "ptype larceny" "type = const long( int)? \\*"
+ gdb_test "print *largess" " = 5"
+ local_compiler_xfail_check
+ gdb_test "ptype largess" "type = const (unsigned long|long unsigned)( int)? \\*"
+ gdb_test "print *lascivious" " = 6"
+ local_compiler_xfail_check
+
+ gdb_test "ptype lascivious" "type = const float \\*"
+ gdb_test "print *lassitude" " = 7"
+ local_compiler_xfail_check
+ gdb_test "ptype lassitude" "type = const double \\*"
+ gdb_test "print *lamprey" " = 66 'B'"
+ local_compiler_xfail_check
+ gdb_test "ptype lamprey" "type = char \\* const"
+ gdb_test "print *lariat" " = 10 '\\\\n'"
+ local_compiler_xfail_check
+ gdb_test "ptype lariat" "type = unsigned char \\* const"
+ gdb_test "print *laudanum" " = 20"
+ local_compiler_xfail_check
+ gdb_test "ptype laudanum" "type = short( int)? \\* const"
+ gdb_test "print *lecithin" " = 30"
+ local_compiler_xfail_check
+ gdb_test "ptype lecithin" "type = (unsigned short|short unsigned)( int)? \\* const"
+ gdb_test "print *leviathan" " = 40"
+ local_compiler_xfail_check
+ gdb_test "ptype leviathan" "type = long( int)? \\* const"
+ gdb_test "print *libretto" " = 50"
+ local_compiler_xfail_check
+ gdb_test "ptype libretto" "type = (unsigned long|long unsigned)( int)? \\* const"
+ gdb_test "print *lissome" " = 60"
+ local_compiler_xfail_check
+ gdb_test "ptype lissome" "type = float \\* const"
+ gdb_test "print *locust" " = 70"
+ local_compiler_xfail_check
+ gdb_test "ptype locust" "type = double \\* const"
+}
+
+do_constvar_tests
diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp
new file mode 100644
index 00000000000..e25c03c2ea6
--- /dev/null
+++ b/gdb/testsuite/gdb.base/corefile.exp
@@ -0,0 +1,232 @@
+# Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# are we on a target board
+if ![isnative] then {
+ return
+}
+
+set testfile "coremaker"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+# Create a core file named "corefile" rather than just "core", to
+# avoid problems with sys admin types that like to regularly prune all
+# files named "core" from the system.
+#
+# Arbitrarily try setting the core size limit to "unlimited" since
+# this does not hurt on systems where the command does not work and
+# allows us to generate a core on systems where it does.
+#
+# Some systems append "core" to the name of the program; others append
+# the name of the program to "core".
+set found 0
+catch "system \"(cd ${objdir}/${subdir}; ulimit -c unlimited; ${binfile}; true) >/dev/null 2>&1\""
+# remote_exec host "${binfile}"
+foreach i "${objdir}/${subdir}/core ${objdir}/${subdir}/core.coremaker.c ${binfile}.core" {
+ if [remote_file build exists $i] {
+ remote_exec build "mv $i ${objdir}/${subdir}/corefile"
+ set found 1
+ }
+}
+if { $found == 0 } {
+ # The braindamaged HPUX shell quits after the ulimit -c above
+ # without executing ${binfile}. So we try again without the
+ # ulimit here if we didn't find a core file above.
+ # Oh, I should mention that any "braindamaged" non-Unix system has
+ # the same problem. I like the cd bit too, it's really neat'n stuff.
+ catch "system \"(cd ${objdir}/${subdir}; ${binfile}; true) >/dev/null 2>&1\""
+ foreach i "${objdir}/${subdir}/core ${objdir}/${subdir}/core.coremaker.c ${binfile}.core" {
+ if [remote_file build exists $i] {
+ remote_exec build "mv $i ${objdir}/${subdir}/corefile"
+ set found 1
+ }
+ }
+
+ if { $found == 0 } {
+ warning "can't generate a core file - core tests suppressed - check ulimit -c"
+ return 0
+ }
+}
+
+#
+# Test that we can simply startup with a "-core=corefile" command line arg
+# and recognize that the core file is a valid, usable core file.
+# To do this, we must shutdown the currently running gdb and restart
+# with the -core args. We can't use gdb_start because it looks for
+# the first gdb prompt, and the message we are looking for occurs
+# before the first prompt. Also, we can't include GDBFLAGS because
+# if it is empty, this confuses gdb with an empty argument that it
+# grumbles about (said grumbling currently being ignored in gdb_start).
+# **FIXME**
+#
+# Another problem is that on some systems (solaris for example), there
+# is apparently a limit on the length of a fully specified path to
+# the coremaker executable, at about 80 chars. For this case, consider
+# it a pass, but note that the program name is bad.
+
+gdb_exit
+if $verbose>1 then {
+ send_user "Spawning $GDB -nw $GDBFLAGS -core=$objdir/$subdir/corefile\n"
+}
+
+set oldtimeout $timeout
+set timeout [expr "$timeout + 60"]
+verbose "Timeout is now $timeout seconds" 2
+eval "spawn $GDB -nw $GDBFLAGS -core=$objdir/$subdir/corefile"
+expect {
+ -re "Couldn't find .* registers in core file.*$gdb_prompt $" {
+ fail "args: -core=corefile (couldn't find regs)"
+ }
+ -re "Core was generated by .*coremaker.*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" {
+ pass "args: -core=corefile"
+ }
+ -re "Core was generated by .*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" {
+ pass "args: -core=corefile (with bad program name)"
+ }
+ -re ".*registers from core file: File in wrong format.* $" {
+ fail "args: -core=corefile (could not read registers from core file)"
+ }
+ -re ".*$gdb_prompt $" { fail "args: -core=corefile" }
+ timeout { fail "(timeout) starting with -core" }
+}
+
+
+#
+# Test that startup with both an executable file and -core argument.
+# See previous comments above, they are still applicable.
+#
+
+close;
+
+if $verbose>1 then {
+ send_user "Spawning $GDB -nw $GDBFLAGS $binfile -core=$objdir/$subdir/corefile\n"
+}
+
+
+eval "spawn $GDB -nw $GDBFLAGS $binfile -core=$objdir/$subdir/corefile";
+expect {
+ -re "Core was generated by .*coremaker.*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" {
+ pass "args: execfile -core=corefile"
+ }
+ -re "Core was generated by .*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" {
+ pass "args: execfile -core=corefile (with bad program name)"
+ }
+ -re ".*registers from core file: File in wrong format.* $" {
+ fail "args: execfile -core=corefile (could not read registers from core file)"
+ }
+ -re ".*$gdb_prompt $" { fail "args: execfile -core=corefile" }
+ timeout { fail "(timeout) starting with -core" }
+}
+set timeout $oldtimeout
+verbose "Timeout is now $timeout seconds" 2
+
+close;
+
+# Now restart normally.
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Test basic corefile recognition via core-file command.
+
+send_gdb "core-file $objdir/$subdir/corefile\n"
+gdb_expect {
+ -re ".* program is being debugged already.*y or n. $" {
+ # gdb_load may connect us to a gdbserver.
+ send_gdb "y\n"
+ exp_continue;
+ }
+ -re "Core was generated by .*coremaker.*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" {
+ pass "core-file command"
+ }
+ -re "Core was generated by .*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" {
+ pass "core-file command (with bad program name)"
+ }
+ -re ".*registers from core file: File in wrong format.* $" {
+ fail "core-file command (could not read registers from core file)"
+ }
+ -re ".*$gdb_prompt $" { fail "core-file command" }
+ timeout { fail "(timeout) core-file command" }
+}
+
+# Test correct mapping of corefile sections by printing some variables.
+
+gdb_test "print coremaker_data" "\\\$$decimal = 202"
+gdb_test "print coremaker_bss" "\\\$$decimal = 10"
+gdb_test "print coremaker_ro" "\\\$$decimal = 201"
+
+gdb_test "print func2::coremaker_local" "\\\$$decimal = \\{0, 1, 2, 3, 4\\}"
+
+# Somehow we better test the ability to read the registers out of the core
+# file correctly. I don't think the other tests do this.
+
+gdb_test "bt" "abort.*func2.*func1.*main.*" "backtrace in corefile.exp"
+gdb_test "up" "#\[0-9\]* *\[0-9xa-fH'\]* in .* \\(.*\\).*" "up in corefile.exp"
+
+# Test ability to read mmap'd data
+
+gdb_test "x/8bd buf1" ".*:.*0.*1.*2.*3.*4.*5.*6.*7" "accessing original mmap data in core file"
+setup_xfail "*-*-sunos*" "*-*-ultrix*" "*-*-aix*"
+send_gdb "x/8bd buf2\n"
+gdb_expect {
+ -re ".*:.*0.*1.*2.*3.*4.*5.*6.*7.*$gdb_prompt $" {
+ pass "accessing mmapped data in core file"
+ }
+ -re "0x\[f\]*:.*Cannot access memory at address 0x\[f\]*.*$gdb_prompt $" {
+ fail "accessing mmapped data (mapping failed at runtime)"
+ }
+ -re "0x.*:.*Cannot access memory at address 0x.*$gdb_prompt $" {
+ fail "accessing mmapped data (mapping address not found in core file)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "accessing mmapped data (incorrect data found in core file)"
+ }
+ timeout {
+ fail "accessing mmapped data (timeout)"
+ }
+}
+
+# test reinit_frame_cache
+
+gdb_load ${binfile}
+setup_xfail "*-*-*" CLLbs17002
+gdb_test "up" "#\[0-9\]* *\[0-9xa-fH'\]* in .* \\(\\)" "up in corefile.exp (reinit)"
+
+gdb_test "core" "No core file now."
diff --git a/gdb/testsuite/gdb.base/coremaker.c b/gdb/testsuite/gdb.base/coremaker.c
new file mode 100644
index 00000000000..4bb16d46aa4
--- /dev/null
+++ b/gdb/testsuite/gdb.base/coremaker.c
@@ -0,0 +1,122 @@
+/* Simple little program that just generates a core dump from inside some
+ nested function calls. */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifndef __STDC__
+#define const /**/
+#endif
+
+#define MAPSIZE (8 * 1024)
+
+/* Don't make these automatic vars or we will have to walk back up the
+ stack to access them. */
+
+char *buf1;
+char *buf2;
+
+int coremaker_data = 1; /* In Data section */
+int coremaker_bss; /* In BSS section */
+
+const int coremaker_ro = 201; /* In Read-Only Data section */
+
+/* Note that if the mapping fails for any reason, we set buf2
+ to -1 and the testsuite notices this and reports it as
+ a failure due to a mapping error. This way we don't have
+ to test for specific errors when running the core maker. */
+
+void
+mmapdata ()
+{
+ int j, fd;
+
+ /* Allocate and initialize a buffer that will be used to write
+ the file that is later mapped in. */
+
+ buf1 = (char *) malloc (MAPSIZE);
+ for (j = 0; j < MAPSIZE; ++j)
+ {
+ buf1[j] = j;
+ }
+
+ /* Write the file to map in */
+
+ fd = open ("coremmap.data", O_CREAT | O_RDWR, 0666);
+ if (fd == -1)
+ {
+ perror ("coremmap.data open failed");
+ buf2 = (char *) -1;
+ return;
+ }
+ write (fd, buf1, MAPSIZE);
+
+ /* Now map the file into our address space as buf2 */
+
+ buf2 = (char *) mmap (0, MAPSIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ if (buf2 == (char *) -1)
+ {
+ perror ("mmap failed");
+ return;
+ }
+
+ /* Verify that the original data and the mapped data are identical.
+ If not, we'd rather fail now than when trying to access the mapped
+ data from the core file. */
+
+ for (j = 0; j < MAPSIZE; ++j)
+ {
+ if (buf1[j] != buf2[j])
+ {
+ fprintf (stderr, "mapped data is incorrect");
+ buf2 = (char *) -1;
+ return;
+ }
+ }
+}
+
+void
+func2 ()
+{
+ int coremaker_local[5];
+ int i;
+
+#ifdef SA_FULLDUMP
+ /* Force a corefile that includes the data section for AIX. */
+ {
+ struct sigaction sa;
+
+ sigaction (SIGABRT, (struct sigaction *)0, &sa);
+ sa.sa_flags |= SA_FULLDUMP;
+ sigaction (SIGABRT, &sa, (struct sigaction *)0);
+ }
+#endif
+
+ /* Make sure that coremaker_local doesn't get optimized away. */
+ for (i = 0; i < 5; i++)
+ coremaker_local[i] = i;
+ coremaker_bss = 0;
+ for (i = 0; i < 5; i++)
+ coremaker_bss += coremaker_local[i];
+ coremaker_data = coremaker_ro + 1;
+ abort ();
+}
+
+void
+func1 ()
+{
+ func2 ();
+}
+
+int main ()
+{
+ mmapdata ();
+ func1 ();
+ return 0;
+}
+
diff --git a/gdb/testsuite/gdb.base/coremaker2.c b/gdb/testsuite/gdb.base/coremaker2.c
new file mode 100644
index 00000000000..94f9d000f48
--- /dev/null
+++ b/gdb/testsuite/gdb.base/coremaker2.c
@@ -0,0 +1,58 @@
+/* Simple little program that just generates a core dump from inside some
+ nested function calls. Keep this as self contained as possible, I.E.
+ use no environment resources other than possibly abort(). */
+
+#ifndef __STDC__
+#define const /**/
+#endif
+
+#ifndef HAVE_ABORT
+#define HAVE_ABORT 1
+#endif
+
+#if HAVE_ABORT
+#define ABORT abort()
+#else
+#define ABORT {char *invalid = 0; *invalid = 0xFF;}
+#endif
+
+/* Don't make these automatic vars or we will have to walk back up the
+ stack to access them. */
+
+char *buf1;
+char *buf2;
+
+int coremaker_data = 1; /* In Data section */
+int coremaker_bss; /* In BSS section */
+
+const int coremaker_ro = 201; /* In Read-Only Data section */
+
+void
+func2 (int x)
+{
+ int coremaker_local[5];
+ int i;
+ static int y;
+
+ /* Make sure that coremaker_local doesn't get optimized away. */
+ for (i = 0; i < 5; i++)
+ coremaker_local[i] = i;
+ coremaker_bss = 0;
+ for (i = 0; i < 5; i++)
+ coremaker_bss += coremaker_local[i];
+ coremaker_data = coremaker_ro + 1;
+ y = 10 * x;
+ ABORT;
+}
+
+void
+func1 (int x)
+{
+ func2 (x * 2);
+}
+
+int main ()
+{
+ func1 (10);
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/cvexpr.c b/gdb/testsuite/gdb.base/cvexpr.c
new file mode 100644
index 00000000000..587120928e4
--- /dev/null
+++ b/gdb/testsuite/gdb.base/cvexpr.c
@@ -0,0 +1,434 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+
+ 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.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@prep.ai.mit.edu */
+
+
+/*
+ * Initial set of typed variables borrowed from ptype.c
+ */
+
+#if !defined (__STDC__) && !defined (_AIX)
+#define signed /**/
+#endif
+
+char v_char;
+signed char v_signed_char;
+unsigned char v_unsigned_char;
+
+short v_short;
+signed short v_signed_short;
+unsigned short v_unsigned_short;
+
+int v_int;
+signed int v_signed_int;
+unsigned int v_unsigned_int;
+
+long v_long;
+signed long v_signed_long;
+unsigned long v_unsigned_long;
+
+long long v_long_long;
+signed long long v_signed_long_long;
+unsigned long long v_unsigned_long_long;
+
+float v_float;
+double v_double;
+
+/*
+ * Now some derived types, which are arrays, functions-returning,
+ * pointers, structures, unions, and enumerations.
+ */
+
+/**** arrays *******/
+
+char v_char_array[2];
+signed char v_signed_char_array[2];
+unsigned char v_unsigned_char_array[2];
+
+short v_short_array[2];
+signed short v_signed_short_array[2];
+unsigned short v_unsigned_short_array[2];
+
+int v_int_array[2];
+signed int v_signed_int_array[2];
+unsigned int v_unsigned_int_array[2];
+
+long v_long_array[2];
+signed long v_signed_long_array[2];
+unsigned long v_unsigned_long_array[2];
+
+float v_float_array[2];
+double v_double_array[2];
+
+/* PR 3742 */
+typedef char t_char_array[];
+
+/**** pointers *******/
+
+char *v_char_pointer;
+signed char *v_signed_char_pointer;
+unsigned char *v_unsigned_char_pointer;
+
+short *v_short_pointer;
+signed short *v_signed_short_pointer;
+unsigned short *v_unsigned_short_pointer;
+
+int *v_int_pointer;
+signed int *v_signed_int_pointer;
+unsigned int *v_unsigned_int_pointer;
+
+long *v_long_pointer;
+signed long *v_signed_long_pointer;
+unsigned long *v_unsigned_long_pointer;
+
+float *v_float_pointer;
+double *v_double_pointer;
+
+char **v_char_pointer_pointer;
+signed char **v_signed_char_pointer_pointer;
+unsigned char **v_unsigned_char_pointer_pointer;
+
+short **v_short_pointer_pointer;
+signed short **v_signed_short_pointer_pointer;
+unsigned short **v_unsigned_short_pointer_pointer;
+
+int **v_int_pointer_pointer;
+signed int **v_signed_int_pointer_pointer;
+unsigned int **v_unsigned_int_pointer_pointer;
+
+long **v_long_pointer_pointer;
+signed long **v_signed_long_pointer_pointer;
+unsigned long **v_unsigned_long_pointer_pointer;
+
+float **v_float_pointer_pointer;
+double **v_double_pointer_pointer;
+
+/**** pointers to arrays, arrays of pointers *******/
+
+char *v_char_array_pointer[2];
+signed char *v_signed_char_array_pointer[2];
+unsigned char *v_unsigned_char_array_pointer[2];
+
+short *v_short_array_pointer[2];
+signed short *v_signed_short_array_pointer[2];
+unsigned short *v_unsigned_short_array_pointer[2];
+
+int *v_int_array_pointer[2];
+signed int *v_signed_int_array_pointer[2];
+unsigned int *v_unsigned_int_array_pointer[2];
+
+long *v_long_array_pointer[2];
+signed long *v_signed_long_array_pointer[2];
+unsigned long *v_unsigned_long_array_pointer[2];
+
+float *v_float_array_pointer[2];
+double *v_double_array_pointer[2];
+
+char (*v_char_pointer_array)[2];
+signed char (*v_signed_char_pointer_array)[2];
+unsigned char (*v_unsigned_char_pointer_array)[2];
+
+short (*v_short_pointer_array)[2];
+signed short (*v_signed_short_pointer_array)[2];
+unsigned short (*v_unsigned_short_pointer_array)[2];
+
+int (*v_int_pointer_array)[2];
+signed int (*v_signed_int_pointer_array)[2];
+unsigned int (*v_unsigned_int_pointer_array)[2];
+
+long (*v_long_pointer_array)[2];
+signed long (*v_signed_long_pointer_array)[2];
+unsigned long (*v_unsigned_long_pointer_array)[2];
+
+float (*v_float_pointer_array)[2];
+double (*v_double_pointer_array)[2];
+
+
+/**** structs *******/
+
+struct t_struct {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_struct1;
+
+struct t_struct *v_t_struct_p;
+
+struct {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_struct2;
+
+/* typedef'd struct without a tag. */
+typedef struct {
+ double v_double_member;
+ int v_int_member;
+} t_struct3;
+/* GCC seems to want a variable of this type, or else it won't put out
+ a symbol. */
+t_struct3 v_struct3;
+
+/**** unions *******/
+
+union t_union {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_union;
+
+union {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_union2;
+
+/* typedef'd union without a tag. */
+typedef union {
+ double v_double_member;
+ int v_int_member;
+} t_union3;
+/* GCC seems to want a variable of this type, or else it won't put out
+ a symbol. */
+t_union3 v_union3;
+
+/**** Enumerations *******/
+
+enum
+/* Work around the bug for compilers which don't put out the right stabs. */
+#if __GNUC__ < 2 && !defined (_AIX)
+primary1_tag
+#endif
+{red1, green1, blue1} primary1;
+
+enum {red, green, blue} primary;
+enum colors {yellow, purple, pink} nonprimary;
+
+enum {chevy, ford} clunker;
+enum cars {bmw, porsche} sportscar;
+
+#undef FALSE
+#undef TRUE
+typedef enum {FALSE, TRUE} boolean;
+boolean v_boolean;
+/*note: aCC has bool type predefined with 'false' and 'true'*/
+typedef enum bvals {my_false, my_true} boolean2;
+boolean2 v_boolean2;
+
+enum misordered {two = 2, one = 1, zero = 0, three = 3};
+
+/* Seems like we need a variable of this type to get the type to be put
+ in the executable, at least for AIX xlc. */
+enum misordered v_misordered = three;
+
+/**** Function pointers *******/
+
+char (*v_char_func) (int, int*);
+signed char (*v_signed_char_func) (int, int*);
+unsigned char (*v_unsigned_char_func) (int, int*);
+
+short (*v_short_func) (int, int*);
+signed short (*v_signed_short_func) (int, int*);
+unsigned short (*v_unsigned_short_func) (int, int*);
+
+int (*v_int_func) (int, int*);
+signed int (*v_signed_int_func) (int, int*);
+unsigned int (*v_unsigned_int_func) (int, int*);
+
+long (*v_long_func) (int, int*);
+signed long (*v_signed_long_func) (int, int*);
+unsigned long (*v_unsigned_long_func) (int, int*);
+
+long long (*v_long_long_func) (int, int*);
+signed long long (*v_signed_long_long_func) (int, int*);
+unsigned long long (*v_unsigned_long_long_func) (int, int*);
+
+float (*v_float_func) (int, int*);
+double (*v_double_func) (int, int*);
+
+void use (void *p)
+{
+}
+
+int main ()
+{
+ use (&v_char);
+ use (&v_signed_char);
+ use (&v_unsigned_char);
+
+ use (&v_short);
+ use (&v_signed_short);
+ use (&v_unsigned_short);
+
+ use (&v_int);
+ use (&v_signed_int);
+ use (&v_unsigned_int);
+
+ use (&v_long);
+ use (&v_signed_long);
+ use (&v_unsigned_long);
+
+ use (&v_long_long);
+ use (&v_signed_long_long);
+ use (&v_unsigned_long_long);
+
+ use (&v_float);
+ use (&v_double);
+
+ use (v_char_array);
+ use (v_signed_char_array);
+ use (v_unsigned_char_array);
+
+ use (v_short_array);
+ use (v_signed_short_array);
+ use (v_unsigned_short_array);
+
+ use (v_int_array);
+ use (v_signed_int_array);
+ use (v_unsigned_int_array);
+
+ use (v_long_array);
+ use (v_signed_long_array);
+ use (v_unsigned_long_array);
+
+ use (v_float_array);
+ use (v_double_array);
+
+ use (v_char_pointer);
+ use (v_signed_char_pointer);
+ use (v_unsigned_char_pointer);
+
+ use (v_short_pointer);
+ use (v_signed_short_pointer);
+ use (v_unsigned_short_pointer);
+
+ use (v_int_pointer);
+ use (v_signed_int_pointer);
+ use (v_unsigned_int_pointer);
+
+ use (v_long_pointer);
+ use (v_signed_long_pointer);
+ use (v_unsigned_long_pointer);
+
+ use (v_float_pointer);
+ use (v_double_pointer);
+
+ use (v_char_pointer_pointer);
+ use (v_signed_char_pointer_pointer);
+ use (v_unsigned_char_pointer_pointer);
+
+ use (v_short_pointer_pointer);
+ use (v_signed_short_pointer_pointer);
+ use (v_unsigned_short_pointer_pointer);
+
+ use (v_int_pointer_pointer);
+ use (v_signed_int_pointer_pointer);
+ use (v_unsigned_int_pointer_pointer);
+
+ use (v_long_pointer_pointer);
+ use (v_signed_long_pointer_pointer);
+ use (v_unsigned_long_pointer_pointer);
+
+ use (v_float_pointer_pointer);
+ use (v_double_pointer_pointer);
+
+ use (v_char_array_pointer);
+ use (v_signed_char_array_pointer);
+ use (v_unsigned_char_array_pointer);
+
+ use (v_short_array_pointer);
+ use (v_signed_short_array_pointer);
+ use (v_unsigned_short_array_pointer);
+
+ use (v_int_array_pointer);
+ use (v_signed_int_array_pointer);
+ use (v_unsigned_int_array_pointer);
+
+ use (v_long_array_pointer);
+ use (v_signed_long_array_pointer);
+ use (v_unsigned_long_array_pointer);
+
+ use (v_float_array_pointer);
+ use (v_double_array_pointer);
+
+ use (v_char_pointer_array);
+ use (v_signed_char_pointer_array);
+ use (v_unsigned_char_pointer_array);
+
+ use (v_short_pointer_array);
+ use (v_signed_short_pointer_array);
+ use (v_unsigned_short_pointer_array);
+
+ use (v_int_pointer_array);
+ use (v_signed_int_pointer_array);
+ use (v_unsigned_int_pointer_array);
+
+ use (v_long_pointer_array);
+ use (v_signed_long_pointer_array);
+ use (v_unsigned_long_pointer_array);
+
+ use (v_float_pointer_array);
+ use (v_double_pointer_array);
+
+ use (&v_struct1);
+ use (&v_struct2);
+ use (&v_struct3);
+
+ use (&v_union);
+ use (&v_union2);
+ use (&v_union3);
+
+ use (&v_boolean);
+ use (&v_boolean2);
+ use (&v_misordered);
+
+ use (v_char_func);
+ use (v_signed_char_func);
+ use (v_unsigned_char_func);
+
+ use (v_short_func);
+ use (v_signed_short_func);
+ use (v_unsigned_short_func);
+
+ use (v_int_func);
+ use (v_signed_int_func);
+ use (v_unsigned_int_func);
+
+ use (v_long_func);
+ use (v_signed_long_func);
+ use (v_unsigned_long_func);
+
+ use (v_long_long_func);
+ use (v_signed_long_long_func);
+ use (v_unsigned_long_long_func);
+
+ use (v_float_func);
+ use (v_double_func);
+}
diff --git a/gdb/testsuite/gdb.base/cvexpr.exp b/gdb/testsuite/gdb.base/cvexpr.exp
new file mode 100644
index 00000000000..56afb9dd229
--- /dev/null
+++ b/gdb/testsuite/gdb.base/cvexpr.exp
@@ -0,0 +1,510 @@
+# Copyright (C) 2001 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Written by Michael Snyder, Red Hat, Inc., 9/20/2001
+
+# This file is part of the gdb testsuite
+# Tests for type expressions using const and volatile keywords.
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "cvexpr"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+
+gdb_test "set print sevenbit-strings" "" ""
+gdb_test "set print address off" "" ""
+gdb_test "set width 0" "" ""
+
+set ws "\[ \t\]*"
+
+#
+# Test casting a scalar to const
+#
+
+gdb_test "whatis (const char) v_char" \
+ "type = const char" \
+ "(const char)"
+gdb_test "whatis (const signed char) v_signed_char" \
+ "type = const signed char" \
+ "(const signed char)"
+gdb_test "whatis (const unsigned char) v_unsigned_char" \
+ "type = const (unsigned char|char)" \
+ "(const unsigned char)"
+gdb_test "whatis (const short) v_short" \
+ "type = const (short|short int)" \
+ "(const short)"
+gdb_test "whatis (const signed short) v_signed_short" \
+ "type = const (short|short int|signed short|signed short int)" \
+ "(const signed short)"
+gdb_test "whatis (const unsigned short) v_unsigned_short" \
+ "type = const (unsigned short|short unsigned int)" \
+ "(const unsigned short)"
+gdb_test "whatis (const int) v_int" \
+ "type = const int" \
+ "(const int)"
+gdb_test "whatis (const signed int) v_signed_int" \
+ "type = const (signed int|int)" \
+ "(const signed int)"
+gdb_test "whatis (const unsigned int) v_unsigned_int" \
+ "type = const unsigned int" \
+ "(const unsigned int)"
+gdb_test "whatis (const long) v_long" \
+ "type = const (long|long int)" \
+ "(const long)"
+gdb_test "whatis (const signed long) v_signed_long" \
+ "type = const (signed |)long( int|)" \
+ "(const signed long)"
+gdb_test "whatis (const unsigned long) v_unsigned_long" \
+ "type = const (unsigned long|long unsigned int)" \
+ "(const unsigned long)"
+gdb_test "whatis (const long long) v_long_long" \
+ "type = const long long( int|)" \
+ "(const long long)"
+gdb_test "whatis (const signed long long) v_signed_long_long" \
+ "type = const (signed |)long long( int|)" \
+ "(const signed long long)"
+gdb_test "whatis (const unsigned long long) v_unsigned_long_long" \
+ "type = const (unsigned long long|long long unsigned int)" \
+ "(const unsigned long long)"
+gdb_test "whatis (const float) v_float" \
+ "type = const float" \
+ "(const float)"
+gdb_test "whatis (const double) v_double" \
+ "type = const double" \
+ "(const double)"
+
+#
+# Test casting a scalar to volatile
+#
+
+gdb_test "whatis (volatile char) v_char" \
+ "type = volatile char" \
+ "(volatile char)"
+gdb_test "whatis (volatile signed char) v_signed_char" \
+ "type = volatile signed char" \
+ "(volatile signed char)"
+gdb_test "whatis (volatile unsigned char) v_unsigned_char" \
+ "type = volatile (unsigned char|char)" \
+ "(volatile unsigned char)"
+gdb_test "whatis (volatile short) v_short" \
+ "type = volatile (short|short int)" \
+ "(volatile short)"
+gdb_test "whatis (volatile signed short) v_signed_short" \
+ "type = volatile (short|short int|signed short|signed short int)" \
+ "(volatile signed short)"
+gdb_test "whatis (volatile unsigned short) v_unsigned_short" \
+ "type = volatile (unsigned short|short unsigned int)" \
+ "(volatile unsigned short)"
+gdb_test "whatis (volatile int) v_int" \
+ "type = volatile int" \
+ "(volatile int)"
+gdb_test "whatis (volatile signed int) v_signed_int" \
+ "type = volatile (signed int|int)" \
+ "(volatile signed int)"
+gdb_test "whatis (volatile unsigned int) v_unsigned_int" \
+ "type = volatile unsigned int" \
+ "(volatile unsigned int)"
+gdb_test "whatis (volatile long) v_long" \
+ "type = volatile (long|long int)" \
+ "(volatile long)"
+gdb_test "whatis (volatile signed long) v_signed_long" \
+ "type = volatile (signed |)long( int|)" \
+ "(volatile signed long)"
+gdb_test "whatis (volatile unsigned long) v_unsigned_long" \
+ "type = volatile (unsigned long|long unsigned int)" \
+ "(volatile unsigned long)"
+gdb_test "whatis (volatile long long) v_long_long" \
+ "type = volatile long long( int|)" \
+ "(volatile long long)"
+gdb_test "whatis (volatile signed long long) v_signed_long_long" \
+ "type = volatile (signed |)long long( int|)" \
+ "(volatile signed long long)"
+gdb_test "whatis (volatile unsigned long long) v_unsigned_long_long" \
+ "type = volatile (unsigned long long|long long unsigned int)" \
+ "(volatile unsigned long long)"
+gdb_test "whatis (volatile float) v_float" \
+ "type = volatile float" \
+ "(volatile float)"
+gdb_test "whatis (volatile double) v_double" \
+ "type = volatile double" \
+ "(volatile double)"
+
+#
+# Combine const and volatile
+#
+
+gdb_test "whatis (const volatile int) v_int" \
+ "type = const volatile int" \
+ "(const volatile int)"
+gdb_test "whatis (volatile const int) v_int" \
+ "type = const volatile int" \
+ "(volatile const int)"
+gdb_test "whatis (const int volatile) v_int" \
+ "type = const volatile int" \
+ "(const int volatile)"
+gdb_test "whatis (volatile int const) v_int" \
+ "type = const volatile int" \
+ "(volatile int const)"
+gdb_test "whatis (int const volatile) v_int" \
+ "type = const volatile int" \
+ "(int const volatile)"
+gdb_test "whatis (int volatile const) v_int" \
+ "type = const volatile int" \
+ "(int volatile const)"
+
+gdb_test "whatis (const volatile int *) v_int_pointer" \
+ "type = const volatile int${ws}\\*" \
+ "(const volatile int *)"
+gdb_test "whatis (volatile const int *) v_int_pointer" \
+ "type = const volatile int${ws}\\*" \
+ "(volatile const int *)"
+gdb_test "whatis (const int volatile *) v_int_pointer" \
+ "type = const volatile int${ws}\\*" \
+ "(const int volatile)"
+gdb_test "whatis (volatile int const *) v_int_pointer" \
+ "type = const volatile int${ws}\\*" \
+ "(volatile int const *)"
+gdb_test "whatis (int const volatile *) v_int_pointer" \
+ "type = const volatile int${ws}\\*" \
+ "(int const volatile *)"
+gdb_test "whatis (int volatile const *) v_int_pointer" \
+ "type = const volatile int${ws}\\*" \
+ "(int volatile const *)"
+gdb_test "whatis (int * const volatile) v_int_pointer" \
+ "type = int${ws}\\*${ws}const volatile" \
+ "(int * const volatile)"
+gdb_test "whatis (int * volatile const) v_int_pointer" \
+ "type = int${ws}\\*${ws}const volatile" \
+ "(int * volatile const)"
+
+
+#
+# Put 'signed' and 'unsigned' before const/volatile (FIXME)
+#
+
+#gdb_test "whatis (signed const char) v_signed_char" \
+# "type = const char" \
+# "(signed const char)"
+#gdb_test "whatis (unsigned const char) v_unsigned_char" \
+# "type = const (unsigned char|char)" \
+# "(unsigned const char)"
+#gdb_test "whatis (signed const short) v_signed_short" \
+# "type = const (short|short int|signed short|signed short int)" \
+# "(signed const short)"
+#gdb_test "whatis (unsigned const short) v_unsigned_short" \
+# "type = const (unsigned short|short unsigned int)" \
+# "(unsigned const short)"
+#gdb_test "whatis (signed const int) v_signed_int" \
+# "type = const (signed int|int)" \
+# "(signed const int)"
+#gdb_test "whatis (unsigned const int) v_unsigned_int" \
+# "type = const unsigned int" \
+# "(unsigned const int)"
+#gdb_test "whatis (signed const long) v_signed_long" \
+# "type = const (signed |)long( int|)" \
+# "(signed const long)"
+#gdb_test "whatis (unsigned const long) v_unsigned_long" \
+# "type = const (unsigned long|long unsigned int)" \
+# "(unsigned const long)"
+#gdb_test "whatis (signed const long long) v_signed_long_long" \
+# "type = const (signed |)long long( int|)" \
+# "(signed const long long)"
+#gdb_test "whatis (unsigned const long long) v_unsigned_long_long" \
+# "type = const (unsigned long long|long long unsigned int)" \
+# "(const unsigned long long)"
+
+#gdb_test "whatis (signed volatile char) v_signed_char" \
+# "type = volatile char" \
+# "(signed volatile char)"
+#gdb_test "whatis (unsigned volatile char) v_unsigned_char" \
+# "type = volatile (unsigned char|char)" \
+# "(unsigned volatile char)"
+#gdb_test "whatis (signed volatile short) v_signed_short" \
+# "type = volatile (short|short int|signed short|signed short int)" \
+# "(signed volatile short)"
+#gdb_test "whatis (unsigned volatile short) v_unsigned_short" \
+# "type = volatile (unsigned short|short unsigned int)" \
+# "(unsigned volatile short)"
+#gdb_test "whatis (signed volatile int) v_signed_int" \
+# "type = volatile (signed int|int)" \
+# "(signed volatile int)"
+#gdb_test "whatis (unsigned volatile int) v_unsigned_int" \
+# "type = volatile unsigned int" \
+# "(unsigned volatile int)"
+#gdb_test "whatis (signed volatile long) v_signed_long" \
+# "type = volatile (signed |)long( int|)" \
+# "(signed volatile long)"
+#gdb_test "whatis (unsigned volatile long) v_unsigned_long" \
+# "type = volatile (unsigned long|long unsigned int)" \
+# "(unsigned volatile long)"
+#gdb_test "whatis (signed volatile long long) v_signed_long_long" \
+# "type = volatile (signed |)long long( int|)" \
+# "(signed volatile long long)"
+#gdb_test "whatis (unsigned volatile long long) v_unsigned_long_long" \
+# "type = volatile (unsigned long long|long long unsigned int)" \
+# "(unsigned volatile long long)"
+
+#
+# Now put the 'const' and 'volatile' keywords after the base type.
+#
+
+gdb_test "whatis (char const) v_char" \
+ "type = const char" \
+ "(char const)"
+gdb_test "whatis (signed char const) v_signed_char" \
+ "type = const signed char" \
+ "(signed char const)"
+gdb_test "whatis (unsigned char const) v_unsigned_char" \
+ "type = const (unsigned char|char)" \
+ "(unsigned char const)"
+gdb_test "whatis (short const) v_short" \
+ "type = const (short|short int)" \
+ "(short const)"
+gdb_test "whatis (signed short const) v_signed_short" \
+ "type = const (short|short int|signed short|signed short int)" \
+ "(signed short const)"
+gdb_test "whatis (unsigned short const) v_unsigned_short" \
+ "type = const (unsigned short|short unsigned int)" \
+ "(unsigned short const)"
+gdb_test "whatis (int const) v_int" \
+ "type = const int" \
+ "(int const)"
+gdb_test "whatis (signed int const) v_signed_int" \
+ "type = const (signed int|int)" \
+ "(signed int const)"
+gdb_test "whatis (unsigned int const) v_unsigned_int" \
+ "type = const unsigned int" \
+ "(unsigned int const)"
+gdb_test "whatis (long const) v_long" \
+ "type = const (long|long int)" \
+ "(long const)"
+gdb_test "whatis (signed long const) v_signed_long" \
+ "type = const (signed |)long( int|)" \
+ "(signed long const)"
+gdb_test "whatis (unsigned long const) v_unsigned_long" \
+ "type = const (unsigned long|long unsigned int)" \
+ "(unsigned long const)"
+gdb_test "whatis (long long const) v_long_long" \
+ "type = const long long( int|)" \
+ "(long long const)"
+gdb_test "whatis (signed long long const) v_signed_long_long" \
+ "type = const (signed |)long long( int|)" \
+ "(signed long long const)"
+gdb_test "whatis (unsigned long long const) v_unsigned_long_long" \
+ "type = const (unsigned long long|long long unsigned int)" \
+ "(unsigned long long const)"
+gdb_test "whatis (float const) v_float" \
+ "type = const float" \
+ "(float const)"
+gdb_test "whatis (double const) v_double" \
+ "type = const double" \
+ "(double const)"
+
+gdb_test "whatis (char volatile) v_char" \
+ "type = volatile char" \
+ "(char volatile)"
+gdb_test "whatis (signed char volatile) v_signed_char" \
+ "type = volatile signed char" \
+ "(signed char volatile)"
+gdb_test "whatis (unsigned char volatile) v_unsigned_char" \
+ "type = volatile (unsigned char|char)" \
+ "(unsigned char volatile)"
+gdb_test "whatis (short volatile) v_short" \
+ "type = volatile (short|short int)" \
+ "(short volatile)"
+gdb_test "whatis (signed short volatile) v_signed_short" \
+ "type = volatile (short|short int|signed short|signed short int)" \
+ "(signed short volatile)"
+gdb_test "whatis (unsigned short volatile) v_unsigned_short" \
+ "type = volatile (unsigned short|short unsigned int)" \
+ "(unsigned short volatile)"
+gdb_test "whatis (int volatile) v_int" \
+ "type = volatile int" \
+ "(int volatile)"
+gdb_test "whatis (signed int volatile) v_signed_int" \
+ "type = volatile (signed int|int)" \
+ "(signed int volatile)"
+gdb_test "whatis (unsigned int volatile) v_unsigned_int" \
+ "type = volatile unsigned int" \
+ "(unsigned int volatile)"
+gdb_test "whatis (long volatile) v_long" \
+ "type = volatile (long|long int)" \
+ "(long volatile)"
+gdb_test "whatis (signed long volatile) v_signed_long" \
+ "type = volatile (signed |)long( int|)" \
+ "(signed long volatile)"
+gdb_test "whatis (unsigned long volatile) v_unsigned_long" \
+ "type = volatile (unsigned long|long unsigned int)" \
+ "(unsigned long volatile)"
+gdb_test "whatis (long long volatile) v_long_long" \
+ "type = volatile long long( int|)" \
+ "(long long volatile)"
+gdb_test "whatis (signed long long volatile) v_signed_long_long" \
+ "type = volatile (signed |)long long( int|)" \
+ "(signed long long volatile)"
+gdb_test "whatis (unsigned long long volatile) v_unsigned_long_long" \
+ "type = volatile (unsigned long long|long long unsigned int)" \
+ "(unsigned long long volatile)"
+gdb_test "whatis (float volatile) v_float" \
+ "type = volatile float" \
+ "(float volatile)"
+gdb_test "whatis (double volatile) v_double" \
+ "type = volatile double" \
+ "(double volatile)"
+
+#
+# enums
+#
+
+gdb_test "whatis (const enum misordered) v_misordered" \
+ "type = const enum misordered" \
+ "(const enum misordered)"
+gdb_test "whatis (enum misordered const) v_misordered" \
+ "type = const enum misordered" \
+ "(enum misordered const)"
+gdb_test "whatis (volatile enum misordered) v_misordered" \
+ "type = volatile enum misordered" \
+ "(volatile enum misordered)"
+gdb_test "whatis (enum misordered volatile) v_misordered" \
+ "type = volatile enum misordered" \
+ "(enum misordered volatile)"
+
+#
+# Pointers
+#
+
+gdb_test "whatis (const int *) v_int_pointer" \
+ "type = const int${ws}\\*" \
+ "(const int *)"
+gdb_test "whatis (int const *) v_int_pointer" \
+ "type = const int${ws}\\*" \
+ "(int const *)"
+gdb_test "whatis (int * const) v_int_pointer" \
+ "type = int \\*${ws}const" \
+ "(int * const)"
+gdb_test "whatis (const int * const) v_int_pointer" \
+ "type = const int${ws}\\*${ws}const" \
+ "(const int * const)"
+gdb_test "whatis (int const * const) v_int_pointer" \
+ "type = const int${ws}\\*${ws}const" \
+ "(int const * const)"
+
+gdb_test "whatis (const int **) v_int_pointer_pointer" \
+ "type = const int${ws}\\*${ws}\\*" \
+ "(const int **)"
+gdb_test "whatis (int const **) v_int_pointer_pointer" \
+ "type = const int${ws}\\*${ws}\\*" \
+ "(int const **)"
+gdb_test "whatis (int ** const) v_int_pointer_pointer" \
+ "type = int \\*${ws}\\*${ws}const" \
+ "(int ** const)"
+gdb_test "whatis (const int * const *) v_int_pointer_pointer" \
+ "type = const int${ws}\\*${ws}const${ws}\\*" \
+ "(const int * const *)"
+gdb_test "whatis (int const * const *) v_int_pointer_pointer" \
+ "type = const int${ws}\\*${ws}const${ws}\\*" \
+ "(int const * const *)"
+gdb_test "whatis (const int * const * const) v_int_pointer_pointer" \
+ "type = const int${ws}\\*${ws}const${ws}\\*${ws}const" \
+ "(const int * const * const)"
+gdb_test "whatis (int const * const * const) v_int_pointer_pointer" \
+ "type = const int${ws}\\*${ws}const${ws}\\*${ws}const" \
+ "(int const * const * const)"
+
+#
+# Arrays TODO
+#
+
+#
+# Pointers to arrays, arrays of pointers TODO
+#
+
+#
+# Structs and Unions
+#
+
+gdb_test "whatis (const struct t_struct) v_struct1" \
+ "type = const struct t_struct" \
+ "(const struct t_struct)"
+gdb_test "whatis (const union t_union) v_union" \
+ "type = const union t_union" \
+ "(const union t_union)"
+gdb_test "whatis (struct t_struct const) v_struct1" \
+ "type = const struct t_struct" \
+ "(struct t_struct const)"
+gdb_test "whatis (union t_union const) v_union" \
+ "type = const union t_union" \
+ "(union t_union const)"
+gdb_test "whatis (const struct t_struct *) &v_struct1" \
+ "type = const struct t_struct${ws}\\*" \
+ "(const struct t_struct *)"
+gdb_test "whatis (const union t_union *) &v_union" \
+ "type = const union t_union${ws}\\*" \
+ "(const union t_union *)"
+gdb_test "whatis (struct t_struct const *) &v_struct1" \
+ "type = const struct t_struct${ws}\\*" \
+ "(struct t_struct const *)"
+gdb_test "whatis (union t_union const *) &v_union" \
+ "type = const union t_union${ws}\\*" \
+ "(union t_union const *)"
+gdb_test "whatis (struct t_struct * const) &v_struct1" \
+ "type = struct t_struct${ws}\\*${ws}const" \
+ "(struct t_struct * const)"
+gdb_test "whatis (union t_union * const) &v_union" \
+ "type = union t_union${ws}\\*${ws}const" \
+ "(union t_union * const)"
+gdb_test "whatis (const struct t_struct * const) &v_struct1" \
+ "type = const struct t_struct${ws}\\*${ws}const" \
+ "(const struct t_struct * const)"
+gdb_test "whatis (const union t_union * const) &v_union" \
+ "type = const union t_union${ws}\\*${ws}const" \
+ "(const union t_union * const)"
+gdb_test "whatis (struct t_struct const * const) &v_struct1" \
+ "type = const struct t_struct${ws}\\*${ws}const" \
+ "(struct t_struct const * const)"
+gdb_test "whatis (union t_union const * const) &v_union" \
+ "type = const union t_union${ws}\\*${ws}const" \
+ "(union t_union const * const)"
+
+#
+# Function pointers TODO
+#
+
diff --git a/gdb/testsuite/gdb.base/d10v.ld b/gdb/testsuite/gdb.base/d10v.ld
new file mode 100644
index 00000000000..3c4c38a3c9c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/d10v.ld
@@ -0,0 +1,155 @@
+OUTPUT_FORMAT("elf32-d10v", "elf32-d10v",
+ "elf32-d10v")
+OUTPUT_ARCH(d10v)
+ENTRY(_start)
+ SEARCH_DIR(/usr/cygnus/d10v-961230/H-sparc-sun-sunos4.1//lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Overlay sections: */
+ .ovly0 0x01010000 : AT (0x12010000) { foo.o(.text) }
+ .ovly1 0x01010000 : AT (0x12011000) { bar.o(.text) }
+ .ovly2 0x01011000 : AT (0x12012000) { baz.o(.text) }
+ .ovly3 0x01011000 : AT (0x12013000) { grbx.o(.text) }
+ .data00 0x00001000 : AT (0x12014000) { foo.o(.data) }
+ .data01 0x00001000 : AT (0x12015000) { bar.o(.data) }
+ .data02 0x00002000 : AT (0x12016000) { baz.o(.data) }
+ .data03 0x00002000 : AT (0x12017000) { grbx.o(.data) }
+ /* Read-only sections, merged into data segment: */
+ . = 0x00000004;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .plt : { *(.plt) }
+ .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
+ .rodata1 : { *(.rodata1) }
+ /* Adjust the address for the data segment. */
+ . = ALIGN(4);
+ .data :
+ {
+ *(.data)
+ *(.gnu.linkonce.d*)
+ _ovly_table = .;
+ LONG(ABSOLUTE(ADDR(.ovly0)));
+ LONG(SIZEOF(.ovly0));
+ LONG(LOADADDR(.ovly0));
+ LONG(0);
+ LONG(ABSOLUTE(ADDR(.ovly1)));
+ LONG(SIZEOF(.ovly1));
+ LONG(LOADADDR(.ovly1));
+ LONG(0);
+ LONG(ABSOLUTE(ADDR(.ovly2)));
+ LONG(SIZEOF(.ovly2));
+ LONG(LOADADDR(.ovly2));
+ LONG(0);
+ LONG(ABSOLUTE(ADDR(.ovly3)));
+ LONG(SIZEOF(.ovly3));
+ LONG(LOADADDR(.ovly3));
+ LONG(0);
+ LONG(ABSOLUTE(ADDR(.data00)));
+ LONG(SIZEOF(.data00));
+ LONG(LOADADDR(.data00));
+ LONG(0);
+ LONG(ABSOLUTE(ADDR(.data01)));
+ LONG(SIZEOF(.data01));
+ LONG(LOADADDR(.data01));
+ LONG(0);
+ LONG(ABSOLUTE(ADDR(.data02)));
+ LONG(SIZEOF(.data02));
+ LONG(LOADADDR(.data02));
+ LONG(0);
+ LONG(ABSOLUTE(ADDR(.data03)));
+ LONG(SIZEOF(.data03));
+ LONG(LOADADDR(.data03));
+ LONG(0);
+ _novlys = .;
+ LONG((_novlys - _ovly_table) / 16);
+ CONSTRUCTORS
+ }
+ .data1 : { *(.data1) }
+ .ctors :
+ {
+ *(.ctors)
+ }
+ .dtors :
+ {
+ *(.dtors)
+ }
+ .got : { *(.got.plt) *(.got) }
+ .dynamic : { *(.dynamic) }
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata : { *(.sdata) }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ .sbss : { *(.sbss) *(.scommon) }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the .debug DWARF section are relative to the beginning of the
+ section so we begin .debug at 0. It's not clear yet what needs to happen
+ for the others. */
+ .debug 0 : { *(.debug) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ .line 0 : { *(.line) }
+ /* These must appear regardless of . */
+ /* Hmmm, there's got to be a better way. This sets the stack to the
+ top of the simulator memory (i.e. top of 64K data space). */
+ .stack 0x00007FFE : { _stack = .; *(.stack) }
+ .text 0x1000000 :
+ {
+ *(.init)
+ *(.fini)
+ *(.text)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ } =0
+ _etext = .;
+ PROVIDE (etext = .);
+}
diff --git a/gdb/testsuite/gdb.base/d10vovly.c b/gdb/testsuite/gdb.base/d10vovly.c
new file mode 100644
index 00000000000..bdb90feae6b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/d10vovly.c
@@ -0,0 +1,225 @@
+
+/*
+ * Ovlymgr.c -- Runtime Overlay Manager for the GDB testsuite.
+ */
+
+#include "ovlymgr.h"
+
+/* Local functions and data: */
+
+extern unsigned long _ovly_table[][4];
+extern unsigned long _novlys __attribute__ ((section (".data")));
+enum ovly_index { VMA, SIZE, LMA, MAPPED};
+
+static void ovly_copy (unsigned long dst, unsigned long src, long size);
+
+/* Flush the data and instruction caches at address START for SIZE bytes.
+ Support for each new port must be added here. */
+/* FIXME: Might be better to have a standard libgloss function that
+ ports provide that we can then use. Use libgloss instead of newlib
+ since libgloss is the one intended to handle low level system issues.
+ I would suggest something like _flush_cache to avoid the user's namespace
+ but not be completely obscure as other things may need this facility. */
+
+static void
+FlushCache (void)
+{
+#ifdef __M32R__
+ volatile char *mspr = (char *) 0xfffffff7;
+ *mspr = 1;
+#endif
+}
+
+/* OverlayLoad:
+ * Copy the overlay into its runtime region,
+ * and mark the overlay as "mapped".
+ */
+
+bool
+OverlayLoad (unsigned long ovlyno)
+{
+ unsigned long i;
+
+ if (ovlyno < 0 || ovlyno >= _novlys)
+ exit (-1); /* fail, bad ovly number */
+
+ if (_ovly_table[ovlyno][MAPPED])
+ return TRUE; /* this overlay already mapped -- nothing to do! */
+
+ for (i = 0; i < _novlys; i++)
+ if (i == ovlyno)
+ _ovly_table[i][MAPPED] = 1; /* this one now mapped */
+ else if (_ovly_table[i][VMA] == _ovly_table[ovlyno][VMA])
+ _ovly_table[i][MAPPED] = 0; /* this one now un-mapped */
+
+ ovly_copy (_ovly_table[ovlyno][VMA],
+ _ovly_table[ovlyno][LMA],
+ _ovly_table[ovlyno][SIZE]);
+
+ FlushCache ();
+
+ return TRUE;
+}
+
+/* OverlayUnload:
+ * Copy the overlay back into its "load" region.
+ * Does NOT mark overlay as "unmapped", therefore may be called
+ * more than once for the same mapped overlay.
+ */
+
+bool
+OverlayUnload (unsigned long ovlyno)
+{
+ if (ovlyno < 0 || ovlyno >= _novlys)
+ exit (-1); /* fail, bad ovly number */
+
+ if (!_ovly_table[ovlyno][MAPPED])
+ exit (-1); /* error, can't copy out a segment that's not "in" */
+
+ ovly_copy (_ovly_table[ovlyno][LMA],
+ _ovly_table[ovlyno][VMA],
+ _ovly_table[ovlyno][SIZE]);
+
+ return TRUE;
+}
+
+#ifdef __D10V__
+#define IMAP0 (*(short *)(0xff00))
+#define IMAP1 (*(short *)(0xff02))
+#define DMAP (*(short *)(0xff04))
+
+static void
+D10VTranslate (unsigned long logical,
+ short *dmap,
+ unsigned long **addr)
+{
+ unsigned long physical;
+ unsigned long seg;
+ unsigned long off;
+
+ /* to access data, we use the following mapping
+ 0x00xxxxxx: Logical data address segment (DMAP translated memory)
+ 0x01xxxxxx: Logical instruction address segment (IMAP translated memory)
+ 0x10xxxxxx: Physical data memory segment (On-chip data memory)
+ 0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)
+ 0x12xxxxxx: Phisical unified memory segment (Unified memory)
+ */
+
+ /* Addresses must be correctly aligned */
+ if (logical & (sizeof (**addr) - 1))
+ exit (-1);
+
+ /* If the address is in one of the two logical address spaces, it is
+ first translated into a physical address */
+ seg = (logical >> 24);
+ off = (logical & 0xffffffL);
+ switch (seg)
+ {
+ case 0x00: /* in logical data address segment */
+ if (off <= 0x7fffL)
+ physical = (0x10L << 24) + off;
+ else
+ /* Logical address out side of on-chip segment, not
+ supported */
+ exit (-1);
+ break;
+ case 0x01: /* in logical instruction address segment */
+ {
+ short map;
+ if (off <= 0x1ffffL)
+ map = IMAP0;
+ else if (off <= 0x3ffffL)
+ map = IMAP1;
+ else
+ /* Logical address outside of IMAP[01] segment, not
+ supported */
+ exit (-1);
+ if (map & 0x1000L)
+ {
+ /* Instruction memory */
+ physical = (0x11L << 24) | off;
+ }
+ else
+ {
+ /* Unified memory */
+ physical = ((map & 0x7fL) << 17) + (off & 0x1ffffL);
+ if (physical > 0xffffffL)
+ /* Address outside of unified address segment */
+ exit (-1);
+ physical |= (0x12L << 24);
+ }
+ break;
+ }
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ physical = logical;
+ break;
+ default:
+ exit (-1); /* error */
+ }
+
+ seg = (physical >> 24);
+ off = (physical & 0xffffffL);
+ switch (seg)
+ {
+ case 0x10: /* dst is a 15 bit offset into the on-chip memory */
+ *dmap = 0;
+ *addr = (long *) (0x0000 + ((short)off & 0x7fff));
+ break;
+ case 0x11: /* dst is an 18-bit offset into the on-chip
+ instruction memory */
+ *dmap = 0x1000L | ((off & 0x3ffffL) >> 14);
+ *addr = (long *) (0x8000 + ((short)off & 0x3fff));
+ break;
+ case 0x12: /* dst is a 24-bit offset into unified memory */
+ *dmap = off >> 14;
+ *addr = (long *) (0x8000 + ((short)off & 0x3fff));
+ break;
+ default:
+ exit (-1); /* error */
+ }
+}
+#endif /* __D10V__ */
+
+static void
+ovly_copy (unsigned long dst, unsigned long src, long size)
+{
+#ifdef __M32R__
+ memcpy ((void *) dst, (void *) src, size);
+ return;
+#endif /* M32R */
+
+#ifdef __D10V__
+ unsigned long *s, *d, tmp;
+ short dmap_src, dmap_dst;
+ short dmap_save;
+
+ /* all section sizes should by multiples of 4 bytes */
+ dmap_save = DMAP;
+
+ D10VTranslate (src, &dmap_src, &s);
+ D10VTranslate (dst, &dmap_dst, &d);
+
+ while (size > 0)
+ {
+ /* NB: Transfer 4 byte (long) quantites, problems occure
+ when only two bytes are transfered */
+ DMAP = dmap_src;
+ tmp = *s;
+ DMAP = dmap_dst;
+ *d = tmp;
+ d++;
+ s++;
+ size -= sizeof (tmp);
+ src += sizeof (tmp);
+ dst += sizeof (tmp);
+ if ((src & 0x3fff) == 0)
+ D10VTranslate (src, &dmap_src, &s);
+ if ((dst & 0x3fff) == 0)
+ D10VTranslate (dst, &dmap_dst, &d);
+ }
+ DMAP = dmap_save;
+#endif /* D10V */
+}
+
diff --git a/gdb/testsuite/gdb.base/dbx.exp b/gdb/testsuite/gdb.base/dbx.exp
new file mode 100644
index 00000000000..161333c8ea3
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dbx.exp
@@ -0,0 +1,340 @@
+# Copyright 1998, 1999, 2001 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile1 "average"
+set testfile2 "sum"
+set testfile "dbx-test"
+set binfile1 ${objdir}/${subdir}/${testfile1}
+set binfile2 ${objdir}/${subdir}/${testfile2}
+set binfile ${objdir}/${subdir}/${testfile}
+
+
+
+if { [gdb_compile "${srcdir}/${subdir}/average.c" "${binfile1}.o" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/sum.c" "${binfile2}.o" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${binfile1}.o ${binfile2}.o" ${binfile} executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+#
+# start gdb -- start gdb running, default procedure
+#
+proc dbx_gdb_start { } {
+ global verbose
+ global GDB
+ global GDBFLAGS
+ global prompt
+ global spawn_id
+ global timeout
+ verbose "Spawning $GDB -nw $GDBFLAGS"
+
+ if { [which $GDB] == 0 } then {
+ perror "$GDB does not exist."
+ exit 1
+ }
+
+ set oldtimeout $timeout
+ set timeout [expr "$timeout + 60"]
+ eval "spawn $GDB -nw -dbx $GDBFLAGS"
+ gdb_expect {
+ -re ".*\r\n$gdb_prompt $" {
+ verbose "GDB initialized."
+ }
+ -re "$prompt $" {
+ perror "GDB never initialized."
+ return -1
+ }
+ timeout {
+ perror "(timeout) GDB never initialized."
+ return -1
+ }
+ }
+ set timeout $oldtimeout
+ # force the height to "unlimited", so no pagers get used
+ send_gdb "set height 0\n"
+ gdb_expect {
+ -re ".*$prompt $" {
+ verbose "Setting height to 0." 2
+ }
+ timeout {
+ warning "Couldn't set the height to 0."
+ }
+ }
+ # force the width to "unlimited", so no wraparound occurs
+ send_gdb "set width 0\n"
+ gdb_expect {
+ -re ".*$prompt $" {
+ verbose "Setting width to 0." 2
+ }
+ timeout {
+ warning "Couldn't set the width to 0."
+ }
+ }
+}
+
+
+proc dbx_reinitialize_dir { subdir } {
+ global gdb_prompt
+
+ send_gdb "use\n"
+ gdb_expect {
+ -re "Reinitialize source path to empty.*y or n. " {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "Source directories searched.*$gdb_prompt $" {
+ send_gdb "use $subdir\n"
+ gdb_expect {
+ -re "Source directories searched.*$gdb_prompt $" {
+ verbose "Dir set to $subdir"
+ }
+ -re ".*$gdb_prompt $" {
+ perror "Dir \"$subdir\" failed."
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ perror "Dir \"$subdir\" failed."
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ perror "Dir \"$subdir\" failed."
+ }
+ }
+}
+
+# In "testsuite/config/unix-gdb.exp", the routine "gdb_load"
+# is defined as "gdb_file_cmd". The binding of "gdb_file_cmd"
+# is done at invocation time. Before this file is processed,
+# it binds to the definition in "testsuite/lib/gdb.exp"; after
+# this file is processed, it binds to this definition.
+# TCL lets us overrides a previous routine definition without a
+# warning (isn't that special?).
+#
+# This means that tests before use "file" to load a target, and
+# tests afterwards use the pair "symbol-file" "exec-file".
+#
+# I'm leaving it as it is for now because at the moment it
+# is the only test we have of the use of the combination of
+# "symbol-file" and "exec-file" to load a debugging target (the
+# other definition uses "file".
+#
+# Symbol-file and exec-file should be tested explicitly, not
+# as a side effect of running a particular test (in this case,
+# "testsuite/gdb.compat/dbx.exp").
+#
+# CM: Renamed the procedure so it does not override the orginal file name.
+# Having the test suite change behavior depending on the tests run makes
+# it extremely difficult to reproduce errors. I've also added a
+# "dbx_gdb_load" procedure. This and only this test will call these
+# procedures now. I also added an "expect" to the "send exec-file" line.
+# The "expect" waits for a prompt to appear. Otherwise, if the tests run
+# too quickly, the caller could send another command before the prompt
+# of this command returns, causing the test to get out of sync and fail
+# seemingly randomly or only on a loaded system.
+#
+# Problem is, though, that the testsuite config files can override the definition of
+# gdb_load (without notice, as was mentioned above). Unfortunately, the gdb_load proc
+# that was copied into this test was a copy of the unix native version.
+#
+# The real problem that we're attempting to solve is how to load an exec and symbol
+# file into gdb for a dbx session. So why not just override gdb_file_cmd with the
+# right sequence of events, allowing gdb_load to do its normal thing? This way
+# remotes and simulators will work, too.
+#
+# [drow 2002-03-30]: We can restore the old gdb_file_cmd afterwards, though.
+set old_gdb_file_cmd_args [info args gdb_file_cmd]
+set old_gdb_file_cmd_body [info body gdb_file_cmd]
+
+proc gdb_file_cmd {arg} {
+ global verbose
+ global loadpath
+ global loadfile
+ global GDB
+ global gdb_prompt
+ global spawn_id
+ upvar timeout timeout
+
+ if [is_remote host] {
+ set arg [remote_download host $arg];
+ if { $arg == "" } {
+ error "download failed"
+ return -1;
+ }
+ }
+
+ send_gdb "symbol-file $arg\n"
+ gdb_expect {
+ -re "Detected 64-bit symbol file.\r\nInvoking.*gdb64.*$gdb_prompt $" {
+ verbose "\t\tLoaded $arg into the $GDB"
+ send_gdb "exec-file $arg\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {
+ verbose "\t\tLoaded $arg with new symbol table into $GDB"
+ return 0
+ }
+ timeout {
+ perror "(timeout) Couldn't load $arg"
+ return -1
+ }
+ }
+ return 0
+ }
+ -re "Reading symbols from.*done.*$gdb_prompt $" {
+ verbose "\t\tLoaded $arg into the $GDB"
+ send_gdb "exec-file $arg\n"
+ gdb_expect {
+ -re "A program is being debugged already.*Kill it.*y or n. $" {
+ send_gdb "y\n"
+ verbose "\t\tKilling previous program being debugged"
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" {
+ verbose "\t\tLoaded $arg with new symbol table into $GDB"
+ return 0
+ }
+ timeout {
+ perror "(timeout) Couldn't load $arg"
+ return -1
+ }
+ }
+ return 0
+ }
+ -re "has no symbol-table.*$gdb_prompt $" {
+ perror "$arg wasn't compiled with \"-g\""
+ return -1
+ }
+ -re "Load new symbol table from \".*\".*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re ".*No such file or directory.*$gdb_prompt $" {
+ perror "($arg) No such file or directory\n"
+ return -1
+ }
+ -re "$gdb_prompt $" {
+ perror "couldn't load $arg into $GDB."
+ return -1
+ }
+ timeout {
+ perror "couldn't load $arg into $GDB (timed out)."
+ return -1
+ }
+ eof {
+ # This is an attempt to detect a core dump, but seems not to
+ # work. Perhaps we need to match .* followed by eof, in which
+ # expect does not seem to have a way to do that.
+ perror "couldn't load $arg into $GDB (end of file)."
+ return -1
+ }
+ }
+}
+
+#
+#test_breakpoints
+#
+proc test_breakpoints { } {
+ gdb_test "stop in main" "Breakpoint.*at.*: file.*average\.c, line 38\."
+ gdb_test "status" "Num.*Type.*Disp.*Enb.*Address.*What\r\n1\[ \r\]+breakpoint\[ \r\]+keep y.*in main at.*average\.c:38.*"
+ gdb_test "stop at 43" "Breakpoint.*at.*: file.*average\.c, line 43.*"
+ gdb_test "stop in 43" "Usage: stop in <function . address>"
+ gdb_test "stop at main" "Usage: stop at <line>"
+}
+
+#
+#test_assign
+#
+proc test_assign { } {
+ global decimal
+ global gdb_prompt
+
+ gdb_run_cmd
+ gdb_expect 30 {
+ -re "Break.* at .*:$decimal.*$gdb_prompt $" { pass "running to main" }
+ -re "Breakpoint \[0-9\]*, \[0-9xa-f\]* in .*$gdb_prompt $" { pass "running to main" }
+ -re "$gdb_prompt $" { fail "running to main" }
+ timeout { fail "running to main (timeout)" }
+ }
+ send_gdb "assign first=1\n"
+ gdb_expect {
+ -re "No symbol \"first\" in current context.*$" { fail "assign first" }
+ "$gdb_prompt $" { pass "assign first" }
+ timeout { fail "assign first (timeout)" }
+ }
+ gdb_test "print first" ".1 = 1"
+}
+
+#
+#test_whereis
+#
+proc test_whereis { } {
+ gdb_test "whereis my_list" "All variables matching regular expression \"my_list\":\r\n\r\nFile.*average\.c:\r\nstatic int my_list\\\[10\\\];"
+}
+
+#
+#test_func
+#
+proc test_func { } {
+ gdb_test "cont" "" "cont 1"
+ gdb_test "step" ""
+ # This always fails, but it's not clear why. -sts 1999-08-17
+ setup_xfail "*-*-*"
+ gdb_test "func sum" "'sum' not within current stack frame\."
+ gdb_test "stop in sum" "Breakpoint.*at.*: file.*sum\.c, line 11\."
+ gdb_test "cont" "" "cont 2"
+ # This always fails, but it's not clear why. -sts 1999-08-17
+ setup_xfail "*-*-*"
+ gdb_test "func print_average" ".*in print_average.*\\(list=.*, low=0, high=6\\).*at.*average\.c:24\r\n24\[ \t\]+total = sum\\(list, low, high\\);"
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+global GDBFLAGS
+set saved_gdbflags $GDBFLAGS
+
+set GDBFLAGS "$GDBFLAGS --dbx"
+gdb_start
+dbx_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+test_breakpoints
+test_assign
+test_whereis
+gdb_test "file average.c:1" "1\[ \t\]+/. This is a sample program.*"
+test_func
+
+#exit and cleanup
+gdb_exit
+
+set GDBFLAGS $saved_gdbflags
+eval proc gdb_file_cmd {$old_gdb_file_cmd_args} {$old_gdb_file_cmd_body}
+
+return 0
diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp
new file mode 100644
index 00000000000..ea8ba503c6b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/default.exp
@@ -0,0 +1,818 @@
+# Copyright 1988, 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Start with a fresh gdb
+
+gdb_exit
+gdb_start
+
+set timeout 60
+
+#
+# test default actions of gdb commands
+#
+
+#load_lib gdb.exp
+
+gdb_test "add-symbol-file" "add-symbol-file takes a file name and an address" "add-symbol-file"
+
+# test append
+gdb_test "append" "\"append\" must be followed by a subcommand\.\[\r\n\]+List of append subcommands:.*"
+gdb_test "append binary" "\"append binary\" must be followed by a subcommand\.\[\r\n\]+List of append binary subcommands:.*"
+gdb_test "append memory" "Missing filename\."
+gdb_test "append value" "Missing filename\."
+gdb_test "append binary memory" "Missing filename\."
+gdb_test "append binary value" "Missing filename\."
+
+setup_xfail "mips-idt-*"
+send_gdb "attach\n"
+gdb_expect {
+ -re "Argument required .(process-id|program) to attach.*$gdb_prompt $"\
+ { pass "attach" }
+ -re "You can't do that when your target is `None'.*$gdb_prompt $"\
+ { pass "attach" }
+ -re "You can't do that without a process to debug.*$gdb_prompt $"\
+ { pass "attach" }
+ -re "Don't know how to attach. Try \"help target\"..*$gdb_prompt $"\
+ { pass "attach" }
+ -re "Kill it. .y or n." {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "$gdb_prompt $" { fail "attach" }
+ timeout { fail "(timeout) attach" }
+}
+
+if ![target_info exists use_gdb_stub] {
+ gdb_test "break" "No default breakpoint address now." "break"
+ foreach i "b br bre brea" {
+ gdb_test $i "No default breakpoint address now." "break \"$i\" abbreviation"
+ }
+
+
+ setup_xfail "mips-idt-*"
+ gdb_test "backtrace" "No stack."
+
+ # ba and bac are no longer unique command prefixes. So these tests
+ # elict an error from GDB.
+ # GDB needs to be fixed to map unique alias here for ba bac.
+ #
+ foreach i "bt ba bac" {
+ setup_xfail "mips-idt-*"
+ gdb_test $i "No stack." "backtrace \"$i\" abbreviation"
+ }
+} else {
+ warning "Skipping backtrace and break tests because of GDB stub."
+}
+
+# This works on the MIPS IDT board, but confuses future tests.
+if ![istarget "mips-idt-*"] then {
+ gdb_test "continue" "The program is not being run." "continue"
+ gdb_test "c" "The program is not being run." "continue \"c\" abbreviation"
+}
+
+#test call
+gdb_test "call" "The history is empty..*" "call"
+
+
+#test catch
+gdb_test "catch" "Catch requires an event name..*" "catch"
+
+#test cd
+gdb_test "cd" "Argument required .new working directory.*" "cd"
+
+#test clear
+gdb_test "clear" "No source file specified..*" "clear"
+
+#test commands
+gdb_test "commands" "No breakpoint number 0..*" "commands"
+
+#test condition
+gdb_test "condition" "Argument required .breakpoint number.*" "condition"
+
+#test core-file
+gdb_test "core-file" "No core file now.|GDB can't read core files on this machine." "core-file"
+#test delete "d" abbreviation
+gdb_test "d" "" "delete \"d\" abbreviation"
+#test delete
+gdb_test "delete" "" "delete"
+#test define
+gdb_test "define" "Argument required \[(\]name of command to define\[)\]." "define"
+#test delete breakpoints
+gdb_test "delete breakpoints" "" "delete breakpoints"
+#test delete display
+# FIXME -- need to dump full output to detailed log
+send_gdb "delete display\n"
+gdb_expect {
+ -re "Delete all auto-display expressions.*y or n. $" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "$gdb_prompt $" { pass "delete display prompt" }
+ timeout { fail "(timeout) delete display prompt" }
+ }
+ }
+ timeout { fail "(timeout) delete display prompt" }
+
+}
+
+#test detach
+gdb_test "detach" "" "detach"
+
+if [istarget "h8300-*-hms"] then {
+ gdb_exit
+ gdb_start
+}
+
+#test directory
+# FIXME -- need to dump full output to detailed log
+
+send_gdb "directory\n"
+gdb_expect {
+ -re "Reinitialize source path to empty.*y or n. $" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "Source directories searched: .cdir:.cwd.*$gdb_prompt $"\
+ { pass "directory prompt" }
+ timeout { fail "(timeout) directory prompt" }
+ }
+ }
+}
+
+#test disable "dis" abbreviation
+gdb_test "dis" "" "disable \"dis\" abbreviation"
+#test disable "disa" abbreviation
+gdb_test "disa" "" "disable \"disa\" abbreviation"
+#test disable
+gdb_test "disable" "" "disable"
+#test disable breakpoints
+gdb_test "disable breakpoints" "" "disable breakpoints"
+#test disable display
+gdb_test "disable display" "" "disable display"
+#test disassemble
+gdb_test "disassemble" "No frame selected." "disassemble"
+#test display
+gdb_test "display" "" "display"
+#test do
+gdb_test "do" "No stack." "do"
+#test document
+gdb_test "document" "Argument required .name of command to define.*" "document"
+#test down
+gdb_test "down" "No stack.*" "down"
+#test down-silently
+gdb_test "down-silently" "No stack." "down-silently"
+# test dump
+gdb_test "dump" "\"dump\" must be followed by a subcommand\.\[\r\n\]+List of dump subcommands:.*"
+gdb_test "dump binary" "\"dump binary\" must be followed by a subcommand\.\[\r\n\]+List of dump binary subcommands:.*"
+gdb_test "dump ihex" "\"dump ihex\" must be followed by a subcommand\.\[\r\n\]+List of dump ihex subcommands:.*"
+gdb_test "dump memory" "Missing filename\."
+gdb_test "dump srec" "\"dump srec\" must be followed by a subcommand\.\[\r\n\]+List of dump srec subcommands:.*"
+gdb_test "dump tekhex" "\"dump tekhex\" must be followed by a subcommand\.\[\r\n\]+List of dump tekhex subcommands:.*"
+gdb_test "dump value" "Missing filename\."
+gdb_test "dump binary memory" "Missing filename\."
+gdb_test "dump binary value" "Missing filename\."
+gdb_test "dump ihex memory" "Missing filename\."
+gdb_test "dump ihex value" "Missing filename\."
+gdb_test "dump srec memory" "Missing filename\."
+gdb_test "dump srec value" "Missing filename\."
+gdb_test "dump tekhex memory" "Missing filename\."
+gdb_test "dump tekhex value" "Missing filename\."
+#test echo
+gdb_test "echo" "" "echo"
+#test enable breakpoints delete
+gdb_test "enable breakpoints delete" "Argument required .one or more breakpoint numbers.*" "enable breakpoints delete"
+#test enable breakpoints once
+gdb_test "enable breakpoints once" "Argument required .one or more breakpoint numbers.*" "enable breakpoints once"
+#test enable breakpoints
+gdb_test "enable breakpoints" "" "enable breakpoints"
+#test enable delete
+gdb_test "enable delete" "Argument required .one or more breakpoint numbers.*" "enable delete"
+#test enable display
+gdb_test "enable display" "" "enable display"
+#test enable once
+gdb_test "enable once" "Argument required .one or more breakpoint numbers.*" "enable once"
+#test enable
+gdb_test "enable" "" "enable"
+#test exec-file
+send_gdb "exec-file\n"
+gdb_expect {
+ -re "No executable file now..*$gdb_prompt $" {
+ pass "exec-file"
+ }
+ -re "exec-file.*A program is being debugged already. Kill it. .y or n.*$" {
+ send_gdb "n\n"
+ if $verbose>1 then {
+ send_user "\tDidn't kill program being debugged\n"
+ }
+ gdb_expect -re "$gdb_prompt $" { }
+ pass "exec-file"
+ }
+ -re "$gdb_prompt $" { fail "exec-file" }
+ timeout { fail "(timeout) exec-file" }
+}
+
+#test frame "f" abbreviation
+gdb_test "f" "No stack." "frame \"f\" abbreviation"
+#test frame
+gdb_test "frame" "No stack." "frame"
+#test fg
+gdb_test "fg" "The program is not being run." "fg"
+# FIXME: fg kills the udi connection
+#test file
+send_gdb "file\n"
+gdb_expect {
+ -re "No executable file now..*$gdb_prompt $"\
+ { pass "file" }
+ -re ".*A program is being debugged already. Kill it. .y or n.*$" {
+ send_gdb "n\n"
+ if $verbose>1 then {
+ send_user "\t\tDidn't kill program being debugged\n"
+ }
+ gdb_expect -re "$gdb_prompt $" { }
+ pass "file"
+ }
+ -re ".*$gdb_prompt $" { fail "file" }
+ timeout { fail "(timeout) file" }
+}
+
+#test finish
+gdb_test "finish" "The program is not running." "finish"
+#test forward-search
+# The message here comes from the regexp library, not gdb, and so can
+# vary on different systems.
+gdb_test "forward-search" "No previous regular expression.*|There is no previous regular expression.*" "forward-search"
+#test gcore
+send_gdb "gcore\n"
+gdb_expect {
+ -re "You can\'t do that without a process to debug.*$gdb_prompt $" {
+ pass "gcore"
+ }
+ -re "Undefined command: .*$gdb_prompt $" {
+ pass "gcore"
+ }
+ default { fail "gcore" }
+}
+send_gdb "generate-core-file\n"
+gdb_expect {
+ -re "You can\'t do that without a process to debug.*$gdb_prompt $" {
+ pass "generate-core-file"
+ }
+ -re "Undefined command: .*$gdb_prompt $" {
+ pass "generate-core-file"
+ }
+ default { fail "generate-core-file" }
+}
+#test help "h" abbreviation
+gdb_test "h" "List of classes of commands:(\[^\r\n\]*\[\r\n\])+aliases -- Aliases of other commands(\[^\r\n\]*\[\r\n\])+breakpoints -- Making program stop at certain points(\[^\r\n\]*\[\r\n\])+data -- Examining data(\[^\r\n\]*\[\r\n\])+files -- Specifying and examining files(\[^\r\n\]*\[\r\n\])+obscure -- Obscure features(\[^\r\n\]*\[\r\n\])+running -- Running the program(\[^\r\n\]*\[\r\n\])+stack -- Examining the stack(\[^\r\n\]*\[\r\n\])+status -- Status inquiries(\[^\r\n\]*\[\r\n\])+support -- Support facilities(\[^\r\n\]*\[\r\n\])+user-defined -- User-defined commands(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by a class name for a list of commands in that class.(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by command name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "help \"h\" abbreviation"
+#test help
+gdb_test "help" "List of classes of commands:(\[^\r\n\]*\[\r\n\])+aliases -- Aliases of other commands(\[^\r\n\]*\[\r\n\])+breakpoints -- Making program stop at certain points(\[^\r\n\]*\[\r\n\])+data -- Examining data(\[^\r\n\]*\[\r\n\])+files -- Specifying and examining files(\[^\r\n\]*\[\r\n\])+obscure -- Obscure features(\[^\r\n\]*\[\r\n\])+running -- Running the program(\[^\r\n\]*\[\r\n\])+stack -- Examining the stack(\[^\r\n\]*\[\r\n\])+status -- Status inquiries(\[^\r\n\]*\[\r\n\])+support -- Support facilities(\[^\r\n\]*\[\r\n\])+user-defined -- User-defined commands(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by a class name for a list of commands in that class.(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by command name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "help"
+#test handle
+gdb_test "handle" "Argument required .signal to handle.*" "handle"
+#test info "i" abbreviation
+gdb_test "i" "\"info\" must be followed by the name of an info command.(\[^\r\n\]*\[\r\n\])+List of info subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help info\" followed by info subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "info \"i\" abbreviation"
+#test info
+gdb_test "info" "\"info\" must be followed by the name of an info command.(\[^\r\n\]*\[\r\n\])+List of info subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help info\" followed by info subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "info"
+#test ignore
+gdb_test "ignore" "Argument required .a breakpoint number.*" "ignore"
+#test info address
+gdb_test "info address" "Argument required." "info address"
+#test info all-registers
+gdb_test "info all-registers" "The program has no registers now." "info all-registers"
+#test info args
+gdb_test "info args" "No frame selected." "info args"
+#test info bogus-gdb-command
+gdb_test "info bogus-gdb-command" "Undefined info command: \"bogus-gdb-command\". Try \"help info\".*" "info bogus-gdb-command"
+#test info breakpoints
+gdb_test "info breakpoints" "No breakpoints or watchpoints." "info breakpoints"
+#test info catch
+gdb_test "info catch" "You can't do that without a process to debug." "info catch"
+#test info copying
+# FIXME -- doesn't work worth a shit
+#send_gdb "info copying"
+# -re "GNU GENERAL PUBLIC LICENSE.*#of preserving the free status of all derivatives of our free software and.*#of promoting the sharing and reuse of software generally."#
+gdb_test "info copying"
+# }
+#
+#
+#test info display
+gdb_test "info display" "There are no auto-display expressions now." "info display"
+#test info frame "f" abbreviation
+gdb_test "info f" "No stack.*|No selected frame.*" "info frame \"f\" abbreviation"
+#test info frame
+gdb_test "info frame" "No stack.|No selected frame." "info frame"
+#test info files
+gdb_test "info files" "" "info files"
+#test info float
+if { [istarget "arm*-*-*"] || \
+ [istarget "xscale*-*-*"] || \
+ [istarget "strongarm*-*-*"] } then {
+ gdb_test "info float" "Software FPU type.*mask:.*flags:.*" "info float"
+} elseif [istarget "i\[3456\]86-*-*"] then {
+ gdb_test "info float" "R7:.*Status Word:.*Opcode:.*" "info float"
+} else {
+ gdb_test "info float" "No floating point info available for this processor." "info float"
+}
+#test info functions
+gdb_test "info functions" "All defined functions:" "info functions"
+#test info locals
+gdb_test "info locals" "No frame selected." "info locals"
+#test info program
+gdb_test "info program" "The program being debugged is not being run." "info program"
+#test info registers
+gdb_test "info registers" "The program has no registers now." "info registers"
+#test info stack "s" abbreviation
+gdb_test "info s" "No stack." "info stack \"s\" abbreviation"
+#test info stack
+gdb_test "info stack" "No stack." "info stack"
+#test info set
+# FIXME -- needs to match the entire output
+# FIXME -- on native solaris 2.8, this test fails due to this line:
+# prompt: Gdb's prompt is "(gdb) ".^M
+gdb_test "info set" "confirm: Whether to confirm potentially dangerous operations is o\[a-z\]*.(\[^\r\n\]*\[\r\n\])+history filename: The filename in which to record the command history is (\[^\r\n\]*\[\r\n\])+listsize: Number of source lines gdb will list by default is 10.*" "info set"
+gdb_test "info symbol" "Argument required .address.."
+#test info source
+gdb_test "info source" "No current source file..*" "info source"
+#test info sources
+gdb_test "info sources" "No symbol table is loaded. Use the \"file\" command.*" "info sources"
+#test info target
+gdb_test "info target" "" "info target"
+#test info terminal
+gdb_test "info terminal" "No saved terminal information." "info terminal"
+#test info types
+gdb_test "info types" "All defined types:" "info types"
+#test info variables
+gdb_test "info variables" "All defined variables:" "info variables"
+#test info warranty
+gdb_test "info warranty" "NO WARRANTY(\[^\r\n\]*\[\r\n\])+ *11. *BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY(\[^\r\n\]*\[\r\n\])+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN(\[^\r\n\]*\[\r\n\])+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES(\[^\r\n\]*\[\r\n\])+PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED(\[^\r\n\]*\[\r\n\])+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF(\[^\r\n\]*\[\r\n\])+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS(\[^\r\n\]*\[\r\n\])+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE(\[^\r\n\]*\[\r\n\])+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,(\[^\r\n\]*\[\r\n\])+REPAIR OR CORRECTION.(\[^\r\n\]*\[\r\n\])+ *12. *IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING(\[^\r\n\]*\[\r\n\])+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR(\[^\r\n\]*\[\r\n\])+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,(\[^\r\n\]*\[\r\n\])+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING(\[^\r\n\]*\[\r\n\])+OUT OF THE USE OR INABILITY TO USE THE PROGRAM .INCLUDING BUT NOT LIMITED(\[^\r\n\]*\[\r\n\])+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY(\[^\r\n\]*\[\r\n\])+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER(\[^\r\n\]*\[\r\n\])+PROGRAMS., EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE(\[^\r\n\]*\[\r\n\])+POSSIBILITY OF SUCH DAMAGES.*" "info warranty"
+#test info watchpoints
+gdb_test "info watchpoints" "No breakpoints or watchpoints." "info watchpoints"
+#test inspect
+gdb_test "inspect" "The history is empty." "inspect"
+#test jump
+gdb_test "jump" "The program is not being run." "jump"
+#test kill
+gdb_test "kill" "The program is not being run." "kill"
+#test list "l" abbreviation
+gdb_test "l" "No symbol table is loaded. Use the \"file\" command.*" "list \"l\" abbreviation"
+#test list
+gdb_test "list" "No symbol table is loaded. Use the \"file\" command.*" "list"
+#test load
+# The ``takes a file name'' case is for vxgdb.
+# The ``Use the "file" command'' case is for newer GDB versions which try
+# to deduce the filename from the exec file.
+gdb_test "load" "You can't do that when your target is `None'.*|The load command takes a file name.*|Must specify at least a file name with the load command.*|.*Use the .file. or .exec-file. command.*" "load"
+#test next "n" abbreviation
+gdb_test "n" "The program is not being run." "next \"n\" abbreviation"
+#test next
+gdb_test "next" "The program is not being run." "next"
+#test nexti "ni" abbreviation
+gdb_test "ni" "The program is not being run." "nexti \"ni\" abbreviation"
+#test nexti
+gdb_test "nexti" "The program is not being run." "nexti"
+#test output
+gdb_test "output" "Argument required .expression to compute.*" "output"
+
+#test overlay
+gdb_test "overlay" "\"overlay\" must be followed by the name of .*"
+#test a non-existant overlay subcommand
+gdb_test "overlay on" "Undefined overlay command.* Try \"help overlay\"."
+gdb_test "overlay manual" "" "overlay manual #1"
+gdb_test "overlay auto" ""
+gdb_test "overlay off" ""
+gdb_test "overlay list" "No sections are mapped."
+gdb_test "overlay map" "Overlay debugging not enabled.*" "overlay map #1"
+gdb_test "overlay unmap" "Overlay debugging not enabled.*" "overlay unmap #1"
+gdb_test "overlay manual" "" "overlay manual #2"
+gdb_test "overlay map" "Argument required: name of an overlay section." "overlay map #2"
+gdb_test "overlay unmap" "Argument required: name of an overlay section." "overlay unmap #2"
+
+#test print "p" abbreviation
+gdb_test "p" "The history is empty." "print \"p\" abbreviation"
+#test print
+gdb_test "print" "The history is empty." "print"
+#test printf
+gdb_test "printf" "Argument required .format-control string and values to print.*" "printf"
+#test ptype
+gdb_test "ptype" "The history is empty." "ptype"
+#test pwd
+gdb_test "pwd" "Working directory .*" "pwd"
+
+#test run "r" abbreviation
+if [istarget "*-*-vxworks*"] then {
+ gdb_test "set args" "" ""
+
+ gdb_test "r" "Starting program: .*
+You must specify a function name to run, and arguments if any"\
+ "run \"r\" abbreviation"
+ gdb_test "set args main" "" ""
+
+} else {
+ send_gdb "r\n"
+ gdb_expect {
+ -re "Starting program: .*
+You can't do that when your target is `None'.*$gdb_prompt $"\
+ { pass "run \"r\" abbreviation" }
+ -re "Starting program: .*
+No executable file specified.*
+Use the \"file\" or \"exec-file\" command.*$gdb_prompt $"\
+ { pass "run \"r\" abbreviation" }
+ -re "Starting program: .*
+No image loaded into target.*$gdb_prompt $"\
+ { pass "run \"r\" abbreviation" }
+ -re "Starting program: .*
+No program loaded.*$gdb_prompt $"\
+ { pass "run \"r\" abbreviation" }
+ -re "Don't know how to run. Try \"help target\"..*$gdb_prompt $"\
+ { pass "run \"r\" abbreviation" }
+ -re ".*$gdb_prompt $" { fail "run \"r\" abbreviation" }
+ timeout { fail "(timeout) run \"r\" abbreviation" }
+ }
+}
+
+#test run
+if [istarget "*-*-vxworks*"] then {
+ gdb_test "set args" "" ""
+
+ gdb_test "run" "Starting program: .*
+You must specify a function name to run, and arguments if any"
+ gdb_test "set args main" "" ""
+
+} else {
+ send_gdb "run\n"
+ gdb_expect {
+ -re "Starting program:.*You can't do that when your target is `None'.*$gdb_prompt $" { pass "run" }
+ -re "Starting program: .*
+No executable file specified.*
+Use the \"file\" or \"exec-file\" command.*$gdb_prompt $"\
+ { pass "run" }
+ -re "Starting program: .*
+No image loaded into target.*$gdb_prompt $"\
+ { pass "run" }
+ -re "Starting program: .*
+No program loaded.*$gdb_prompt $"\
+ { pass "run \"r\" abbreviation" }
+ -re "Don't know how to run. Try \"help target\"..*$gdb_prompt $"\
+ { pass "run" }
+ -re ".*$gdb_prompt $" { fail "run" }
+ timeout { fail "(timeout) run" }
+ }
+}
+
+#test rbreak
+gdb_test "rbreak" "" "rbreak"
+
+# test restore
+gdb_test "restore" "You can't do that without a process to debug\."
+
+#test return
+# The middle case accomodated the obsolete a29k, where doing the "ni"
+# above causes an initial stack to be created.
+gdb_test "return" "No selected frame..*" "return" "Make .* return now.*y or n. $" "y"
+
+
+#test reverse-search
+gdb_test "reverse-search" "No previous regular expression.*|There is no previous regular expression.*" "reverse-search"
+#test step "s" abbreviation
+gdb_test "s" "The program is not being run." "step \"s\" abbreviation #1"
+#test step
+gdb_test "step" "The program is not being run." "step #1"
+#test search
+gdb_test "search" "No previous regular expression.*|There is no previous regular expression.*" "search"
+#test section
+gdb_test "section" "Must specify section name and its virtual address.*" "section"
+#test set annotate
+gdb_test "set annotate" "Argument required .integer to set it to.*" "set annotate"
+#test set args
+gdb_test "set args" "" "set args"
+#test set check "c" abbreviation
+gdb_test "set c" "\"set check\" must be followed by the name of a check subcommand.(\[^\r\n\]*\[\r\n\])+List of set check subcommands:(\[^\r\n\]*\[\r\n\])+set check range -- Set range checking(\[^\r\n\]*\[\r\n\])+set check type -- Set type checking(\[^\r\n\]*\[\r\n\])+Type \"help set check\" followed by set check subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set check \"c\" abbreviation"
+#test set check "ch" abbreviation
+gdb_test "set ch" "\"set check\" must be followed by the name of a check subcommand.(\[^\r\n\]*\[\r\n\])+List of set check subcommands:(\[^\r\n\]*\[\r\n\])+set check range -- Set range checking(\[^\r\n\]*\[\r\n\])+set check type -- Set type checking(\[^\r\n\]*\[\r\n\])+Type \"help set check\" followed by set check subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set check \"ch\" abbreviation"
+#test set check
+gdb_test "set check" "\"set check\" must be followed by the name of a check subcommand.(\[^\r\n\]*\[\r\n\])+List of set check subcommands:(\[^\r\n\]*\[\r\n\])+set check range -- Set range checking(\[^\r\n\]*\[\r\n\])+set check type -- Set type checking(\[^\r\n\]*\[\r\n\])+Type \"help set check\" followed by set check subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set check"
+#test set check range
+gdb_test "set check range" "" "set check range"
+#test set check type
+gdb_test "set check type" "" "set check type"
+#test set complaints
+gdb_test "set complaints" "Argument required .integer to set it to.*" "set complaints"
+#test set confirm
+gdb_test "set confirm" "" "set confirm"
+# Don't test set editing. What if we're talking to a gdb that
+# won't do editing correctly while we're talking to it?
+# gdb_test "set editing" "" "set editing"
+
+#test set environment
+gdb_test "set environment" "Argument required .environment variable and value.*" "set environment"
+#test set height
+gdb_test "set height" "Argument required .integer to set it to.*" "set height"
+#test set history expansion
+gdb_test "set history expansion" "" "set history expansion"
+#test set history filename
+gdb_test "set history filename" "Argument required .filename to set it to.*" "set history filename"
+#test set history save
+gdb_test "set history save" "" "set history save"
+#test set history size
+gdb_test "set history size" "Argument required .integer to set it to.*" "set history size"
+#test set history
+gdb_test "set history" "\"set history\" must be followed by the name of a history subcommand.(\[^\r\n\]*\[\r\n\])+List of set history subcommands:(\[^\r\n\]*\[\r\n\])+set history expansion -- Set history expansion on command input(\[^\r\n\]*\[\r\n\])+set history filename -- Set the filename in which to record the command history(\[^\r\n\]*\[\r\n\])+set history save -- Set saving of the history record on exit(\[^\r\n\]*\[\r\n\])+set history size -- Set the size of the command history(\[^\r\n\]*\[\r\n\])+Type \"help set history\" followed by set history subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set history"
+#test set language
+gdb_test "set language" "The currently understood settings are:(\[^\r\n\]*\[\r\n\])+local or auto *Automatic setting based on source file(\[^\r\n\]*\[\r\n\])+c *Use the C language(\[^\r\n\]*\[\r\n\])+c\[+\]+ *Use the C\[+\]+ language(\[^\r\n\]*\[\r\n\])+modula-2 *Use the Modula-2 language.*" "set language"
+#test set listsize
+gdb_test "set listsize" "Argument required .integer to set it to.*" "set listsize"
+#test set print "p" abbreviation
+gdb_test "set p" "\"set print\" must be followed by the name of a print subcommand.(\[^\r\n\]*\[\r\n\])+List of set print subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by set print subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print \"p\" abbreviation"
+#test set print "pr" abbreviation
+gdb_test "set pr" "\"set print\" must be followed by the name of a print subcommand.(\[^\r\n\]*\[\r\n\])+List of set print subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by set print subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print \"pr\" abbreviation"
+#test set print
+gdb_test "set print" "\"set print\" must be followed by the name of a print subcommand.(\[^\r\n\]*\[\r\n\])+List of set print subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by set print subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print"
+#test set print address
+gdb_test "set print address" "" "set print address"
+#test set print array
+gdb_test "set print array" "" "set print array"
+#test set print asm-demangle
+gdb_test "set print asm-demangle" "" "set print asm-demangle"
+#test set print demangle
+gdb_test "set print demangle" "" "set print demangle"
+#test set print elements
+gdb_test "set print elements" "Argument required .integer to set it to.*" "set print elements"
+#test set print object
+gdb_test "set print object" "" "set print object"
+#test set print pretty
+gdb_test "set print pretty" "" "set print pretty"
+#test set print sevenbit-strings
+gdb_test "set print sevenbit-strings" "" "set print sevenbit-strings"
+#test set print union
+gdb_test "set print union" "" "set print union"
+#test set print vtbl
+gdb_test "set print vtbl" "" "set print vtbl"
+# FIXME -- need a test for "set prompt"
+#test set radix
+gdb_test "set radix" "Input and output radices now set to decimal 10, hex a, octal 12.*" "set radix"
+#test set symbol-reloading
+gdb_test "set symbol-reloading" "" "set symbol-reloading"
+#test set variable
+gdb_test "set variable" "Argument required .expression to compute.*" "set variable"
+#test set verbose
+gdb_test "set verbose" "" "set verbose"
+#test set width
+gdb_test "set width" "Argument required .integer to set it to.*" "set width"
+#test set write
+# This is only supported on targets which use exec.o.
+gdb_test "set write" "" "set write"
+#test set
+gdb_test "set" "Argument required .expression to compute.*" "set"
+#test shell echo Hi dad!
+gdb_test "shell echo Hi dad!" "Hi dad!" "shell echo Hi dad!"
+#test show annotate
+gdb_test "show annotate" "Annotation_level is 0." "show annotate"
+#test show args
+gdb_test "show args" "Argument list to give program being debugged when it is started is \"\"." "show args"
+#test show check "c" abbreviation
+gdb_test "show c" "range: *Range checking is \"auto; currently off\".(\[^\r\n\]*\[\r\n\])+type: *Type checking is \"auto; currently off\".*" "show check \"c\" abbreviation"
+#test show check "ch" abbreviation
+gdb_test "show ch" "range: *Range checking is \"auto; currently off\".(\[^\r\n\]*\[\r\n\])+type: *Type checking is \"auto; currently off\"." "show check \"ch\" abbreviation"
+#test show check
+gdb_test "show check" "range: *Range checking is \"auto; currently off\".(\[^\r\n\]*\[\r\n\])+type: *Type checking is \"auto; currently off\"." "show check"
+#test show check range
+gdb_test "show check range" "Range checking is \"auto; currently off\"." "show check range"
+#test show check type
+gdb_test "show check type" "Type checking is \"auto; currently off\"." "show check type"
+#test show commands
+gdb_test "show commands" "" "show commands"
+#test show complaints
+gdb_test "show complaints" "Max number of complaints about incorrect symbols is 0." "show complaints"
+#test show confirm
+gdb_test "show confirm" "Whether to confirm potentially dangerous operations is o\[a-z\]*." "show confirm"
+#test show convenience
+gdb_test "show convenience" "No debugger convenience variables now defined.(\[^\r\n\]*\[\r\n\])+Convenience variables have names starting with \".\";(\[^\r\n\]*\[\r\n\])+use \"set\" as in \"set .foo = 5\" to define them." "show convenience"
+#test show directories
+gdb_test "show directories" "Source directories searched: .cdir:.cwd" "show directories"
+#test show editing
+gdb_test "show editing" "Editing of command lines as they are typed is o\[a-z\]*." "show editing"
+#test show height
+gdb_test "show height" "Number of lines gdb thinks are in a page is.*" "show height"
+#test show history expansion
+gdb_test "show history expansion" "History expansion on command input is o\[a-z\]*.*" "show history expansion"
+#test show history filename
+gdb_test "show history filename" "The filename in which to record the command history is.*.gdb_history.*" "show history filename"
+#test show history save
+gdb_test "show history save" "Saving of the history record on exit is on." "show history save"
+#test show history size
+gdb_test "show history size" "The size of the command history is.*" "show history size"
+#test show history
+gdb_test "show history" "expansion: *History expansion on command input is o(\[^\r\n\]*\[\r\n\])+filename: *The filename in which to record the command history is.*.gdb_history(\[^\r\n\]*\[\r\n\])+save: *Saving of the history record on exit is o(\[^\r\n\]*\[\r\n\])+size: * The size of the command history is.*" "show history"
+#test show language
+gdb_test "show language" "The current source language is \"auto; currently c\"." "show language"
+#test show listsize
+gdb_test "show listsize" "Number of source lines gdb will list by default is 10." "show listsize"
+#test show print "p" abbreviation
+gdb_test "show p" ".*" "show p"
+#test show print "pr" abbreviation
+gdb_test "show pr" ".*" "show pr"
+#test show print
+gdb_test "show print" "" "show print"
+#test show paths
+gdb_test "show paths" "Executable and object file path:.*" "show paths"
+#test show print address
+gdb_test "show print address" "Printing of addresses is on." "show print address"
+#test show print array
+gdb_test "show print array" "Prettyprinting of arrays is on." "show print array"
+#test show print asm-demangle
+gdb_test "show print asm-demangle" "Demangling of C\[+\]+ names in disassembly listings is on." "show print asm-demangle"
+#test show print demangle
+gdb_test "show print demangle" "Demangling of encoded C\[+\]+ names when displaying symbols is on." "show print demangle"
+#test show print elements
+gdb_test "show print elements" "Limit on string chars or array elements to print is 200." "show print elements"
+#test show print object
+gdb_test "show print object" "Printing of object's derived type based on vtable info is on." "show print object"
+#test show print pretty
+gdb_test "show print pretty" "Prettyprinting of structures is on." "show print pretty"
+#test show print sevenbit-strings
+gdb_test "show print sevenbit-strings" "Printing of 8-bit characters in strings as .nnn is on." "show print sevenbit-strings"
+#test show print union
+gdb_test "show print union" "Printing of unions interior to structures is on." "show print union"
+#test show print vtbl
+gdb_test "show print vtbl" "Printing of C\[+\]+ virtual function tables is on." "show print vtbl"
+#test show prompt
+# In the FAIL case, can't just look for $gdb_prompt because that will match
+# the output, rather than the prompt. So look for $gdb_prompt at the start
+# of a line.
+gdb_test "show prompt" "Gdb's prompt is \"$gdb_prompt \".*" "show prompt"
+#test show radix
+gdb_test "show radix" "Input and output radices set to decimal 10, hex a, octal 12." "show radix"
+#test show symbol-reloading
+gdb_test "show symbol-reloading" "Dynamic symbol table reloading multiple times in one run is on." "show symbol-reloading"
+#test show user
+gdb_test "show user" "" "show user"
+#test show values
+gdb_test "show values" "" "show values"
+#test show verbose
+gdb_test "show verbose" "Verbose printing of informational messages is o.*|Verbosity is off.*" "show verbose"
+#test show version
+gdb_test "show version" "GNU gdb \[0-9\.\]*(\[^\r\n\]*\[\r\n\])+Copyright \[0-9\]* Free Software Foundation, Inc(\[^\r\n\]*\[\r\n\])+GDB is free software, covered by the GNU General Public License, and you are(\[^\r\n\]*\[\r\n\])+welcome to change it and/or distribute copies of it under certain conditions(\[^\r\n\]*\[\r\n\])+Type \"show copying\" to see the conditions(\[^\r\n\]*\[\r\n\])+There is absolutely no warranty for GDB. Type \"show warranty\" for details(\[^\r\n\]*\[\r\n\])+This GDB was configured as .*|GDB is free software and you are welcome to distribute copies of it(\[^\r\n\]*\[\r\n\])+ under certain conditions; type \"show copying\" to see the conditions.(\[^\r\n\]*\[\r\n\])+There is absolutely no warranty for GDB; type \"show warranty\" for details.(\[^\r\n\]*\[\r\n\])+GDB.*Copyright \[0-9\]* Free Software Foundation, Inc.*" "show version"
+#test show width
+gdb_test "show width" "Number of characters gdb thinks are in a line is.*" "show width"
+#test show write
+# This is only supported on targets which use exec.o.
+gdb_test "show write" "Writing into executable and core files is o.*" "show write"
+#test show
+gdb_test "show" "confirm: *Whether to confirm potentially dangerous operations is on.(\[^\r\n\]*\[\r\n\])+history filename: *The filename in which to record the command history is (\[^\r\n\]*\[\r\n\])+history save: *Saving of the history record on exit is on.(\[^\r\n\]*\[\r\n\])+history size: *The size of the command history is(\[^\r\n\]*\[\r\n\])+listsize: *Number of source lines gdb will list by default is 10(\[^\r\n]*\[\r\n\])+print elements: *Limit on string chars or array elements to print is 200..*" "show"
+#test stepi "si" abbreviation
+gdb_test "si" "The program is not being run." "stepi \"si\" abbreviation"
+#test stepi
+gdb_test "stepi" "The program is not being run." "stepi"
+#test signal
+gdb_test "signal" "The program is not being run." "signal"
+#test source
+gdb_test "source" "source command requires pathname of file to source..*|No such file or directory.*" "source"
+#test step "s" abbreviation
+gdb_test "s" "The program is not being run." "step \"s\" abbreviation #2"
+#test step
+gdb_test "step" "The program is not being run." "step #2"
+#test symbol-file
+gdb_test "symbol-file" "" "symbol-file"
+
+#test target child
+gdb_test "target child" "Use the \"run\" command to start a Unix child process.*|Undefined target command: \"child\". *Try \"help target\".*" "target child"
+
+#test target procfs
+gdb_test "target procfs" "Use the \"run\" command to start a Unix child process.*|Undefined target command: \"procfs\". *Try \"help target\".*" "target procfs"
+
+#test target core
+send_gdb "target core\n"
+gdb_expect {
+ -re "No core file specified..*$gdb_prompt $" { pass "target core" }
+ -re ".*A program is being debugged already. Kill it. .y or n.*$" {
+ send_gdb "n\n"
+ if $verbose>1 then {
+ send_user "\t\tDidn't kill program being debugged\n"
+ }
+ gdb_expect -re "$gdb_prompt $" { }
+ pass "target core"
+ }
+ -re "Undefined target command: \"core\". Try \"help target\"..*$gdb_prompt $" { pass "target core" }
+ -re ".*$gdb_prompt $" { fail "target core" }
+ timeout { fail "(timeout) target core" }
+}
+
+#test target exec
+send_gdb "target exec\n"
+gdb_expect {
+ -re "No executable file now..*$gdb_prompt $"\
+ { pass "target exec" }
+ -re ".*A program is being debugged already. Kill it. .y or n.*$" {
+ send_gdb "n\n"
+ if $verbose>1 then {
+ send_user "\t\tDidn't kill program being debugged\n"
+ }
+ gdb_expect -re "$gdb_prompt $" { }
+ pass "target exec"
+ }
+ -re ".*$gdb_prompt $" { fail "target exec" }
+ timeout { fail "(timeout) target exec" }
+ }
+
+#test target remote
+if ![istarget "*-*-udi*"] then {
+ send_gdb "target remote\n"
+ gdb_expect {
+ -re "To open a remote debug connection, you need to specify what.*serial.*device is attached to the remote system.*.e.g. .*$gdb_prompt $"\
+ { pass "target remote" }
+ -re ".*A program is being debugged already. Kill it. .y or n.*$" {
+ send_gdb "n\n"
+ if $verbose>1 then {
+ send_user "\t\tDidn't kill program being debugged\n"
+ }
+ gdb_expect -re "$gdb_prompt $" { }
+ pass "target remote"
+ }
+ -re ".*$gdb_prompt $" { fail "target remote" }
+ timeout { fail "(timeout) target remote" }
+ }
+}
+
+#test target
+gdb_test "target" "Argument required .target name.*" "target"
+#test tbreak
+gdb_test "tbreak" "No default breakpoint address now." "tbreak"
+#test tty
+gdb_test "tty" "Argument required .terminal name for running target process.*" "tty"
+#test until "u" abbreviation
+gdb_test "u" "The program is not running." "until \"u\" abbreviation"
+#test until
+gdb_test "until" "The program is not running." "until"
+#test undisplay
+# FIXME -- need to dump full output to detailed log
+send_gdb "undisplay\n"
+gdb_expect {
+ -re "Delete all auto-display expressions.*y or n. $" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "$gdb_prompt $" { pass "undisplay prompt" }
+ timeout { fail "(timeout) (timeout) undisplay prompt" }
+ }
+ }
+ timeout { fail "(timeout) (timeout) undisplay prompt" }
+}
+
+#test unset environment
+send_gdb "unset environment\n"
+gdb_expect {
+ -re "Delete all environment variables?.*y or n. $" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "$gdb_prompt $" { pass "unset environmentprompt" }
+ timeout {
+ fail "(timeout) (timeout) unset environment prompt"
+ }
+ }
+ }
+ timeout {
+ fail "(timeout) (timeout) unset environment prompt"
+ }
+}
+
+#test unset
+gdb_test "unset" "\"unset\" must be followed by the name of an unset subcommand.(\[^\r\n\]*\[\r\n\])+List of unset subcommands:(\[^\r\n\]*\[\r\n\])+unset environment -- Cancel environment variable VAR for the program(\[^\r\n\]*\[\r\n\])+Type \"help unset\" followed by unset subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "unset"
+#test up
+#test up-silently
+gdb_test "up-silently" "No stack." "up-silently"
+#test watch
+gdb_test "watch" "Argument required .expression to compute.*" "watch"
+#test whatis
+gdb_test "whatis" "The history is empty." "whatis"
+#test where
+gdb_test "where" "No stack." "where"
+#test x
+#The case in which it prints a number is for vxgdb.
+send_gdb "x\n"
+gdb_expect {
+ -re "0x0:.*Cannot access memory at address 0x0..*$gdb_prompt $" {
+ pass "x"
+ }
+ -re "0x0:.*Error accessing memory address 0x0:.*$gdb_prompt $" {
+ pass "x"
+ }
+ -re ".*$gdb_prompt $" { fail "x" }
+ timeout { fail "(timeout) x" }
+}
+
+gdb_exit
diff --git a/gdb/testsuite/gdb.base/define.exp b/gdb/testsuite/gdb.base/define.exp
new file mode 100644
index 00000000000..06ea1c0f4f8
--- /dev/null
+++ b/gdb/testsuite/gdb.base/define.exp
@@ -0,0 +1,304 @@
+# Copyright 1998, 1999, 2001 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni. (ezannoni@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+global usestubs
+
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "break"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then { fail "define tests suppressed" }
+
+# Verify that GDB allows a user to define their very own commands.
+#
+send_gdb "define nextwhere\n"
+gdb_expect {
+ -re "Type commands for definition of \"nextwhere\".\r\nEnd with a line saying just \"end\".\r\n>$"\
+ {send_gdb "next\nbt\nend\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "define user command: nextwhere"}
+ timeout {fail "(timeout) define user command: nextwhere"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "define user command: nextwhere"}
+ timeout {fail "(timeout) define user command: nextwhere"}
+}
+
+# Verify that those commands work as gdb_expected.
+#
+send_gdb "nextwhere\n"
+gdb_expect {
+ -re ".*79\[ \t\]*printf.*#0\[ \t\]*main.*:79.*$gdb_prompt $"\
+ {pass "use user command: nextwhere"}
+ -re "$gdb_prompt $"\
+ {fail "use user command: nextwhere"}
+ timeout {fail "(timeout) use user command: nextwhere"}
+}
+
+# Verify that a user can define a command whose spelling is a
+# proper substring of another user-defined command.
+#
+send_gdb "define nextwh\n"
+gdb_expect {
+ -re "Type commands for definition of \"nextwh\".\r\nEnd with a line saying just \"end\".\r\n>$"\
+ {send_gdb "next 2\nbt\nend\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "define user command: nextwh"}
+ timeout {fail "(timeout) define user command: nextwh"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "define user command: nextwh"}
+ timeout {fail "(timeout) define user command: nextwh"}
+}
+
+# Verify that a user can redefine their commands. (Test both the
+# confirmed and unconfirmed cases.)
+#
+send_gdb "define nextwhere\n"
+gdb_expect {
+ -re "Redefine command \"nextwhere\".*y or n. $"\
+ {send_gdb "n\n"
+ gdb_expect {
+ -re "Command \"nextwhere\" not redefined.*$gdb_prompt $"\
+ {pass "redefine user command aborted: nextwhere"}
+ -re "$gdb_prompt $"\
+ {fail "redefine user command aborted: nextwhere"}
+ timeout {fail "(timeout) redefine user command aborted: nextwhere"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "redefine user command aborted: nextwhere"}
+ timeout {fail "(timeout) redefine user command aborted: nextwhere"}
+}
+
+send_gdb "define nextwhere\n"
+gdb_expect {
+ -re "Redefine command \"nextwhere\".*y or n. $"\
+ {send_gdb "y\n"
+ gdb_expect {
+ -re "Type commands for definition of \"nextwhere\".\r\nEnd with a line saying just \"end\".\r\n>$"\
+ {send_gdb "bt\nnext\nend\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "redefine user command: nextwhere"}
+ timeout {fail "(timeout) redefine user command: nextwhere"}
+ }
+ }
+ timeout {fail "(timeout) redefine user command: nextwhere"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "redefine user command: nextwhere"}
+ timeout {fail "(timeout) redefine user command: nextwhere"}
+}
+
+# Verify that GDB gracefully handles an attempt to redefine the
+# help text for a builtin command.
+#
+send_gdb "document step\n"
+gdb_expect {
+ -re "Command \"step\" is built-in..*$gdb_prompt $"\
+ {pass "redocumenting builtin command disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "redocumenting builtin command disallowed"}
+ timeout {fail "(timeout) redocumenting builtin command disallowed"}
+}
+
+# Verify that a user can document their own commands. (And redocument
+# them.)
+#
+send_gdb "document nextwhere\n"
+gdb_expect {
+ -re "Type documentation for \"nextwhere\".\r\nEnd with a line saying just \"end\".\r\n>$"\
+ {send_gdb "A next command that frist shows you where you're stepping from.\nend\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "document user command: nextwhere"}
+ timeout {fail "(timeout) document user command: nextwhere"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "document user command: nextwhere"}
+ timeout {fail "(timeout) document user command: nextwhere"}
+}
+
+send_gdb "document nextwhere\n"
+gdb_expect {
+ -re "Type documentation for \"nextwhere\".\r\nEnd with a line saying just \"end\".\r\n>$"\
+ {send_gdb "A next command that first shows you where you're stepping from.\nend\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "re-document user command: nextwhere"}
+ timeout {fail "(timeout) re-document user command: nextwhere"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "re-document user command: nextwhere"}
+ timeout {fail "(timeout) re-document user command: nextwhere"}
+}
+
+send_gdb "help nextwhere\n"
+gdb_expect {
+ -re "A next command that first shows you where you're stepping from.\r\n$gdb_prompt $"\
+ {pass "help user command: nextwhere"}
+ -re "$gdb_prompt $"\
+ {fail "help user command: nextwhere"}
+ timeout {fail "(timeout) help user command: nextwhere"}
+}
+
+# Verify that the user can "hook" a builtin command. We choose to
+# hook the "stop" pseudo command, and we'll define it to use a user-
+# define command.
+#
+send_gdb "define user-bt\n"
+gdb_expect {
+ -re "Type commands for definition of \"user-bt\".\r\nEnd with a line saying just \"end\".\r\n>$"\
+ {send_gdb "bt\nend\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "define user command: user-bt"}
+ timeout {fail "(timeout) define user command: user-bt"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "define user command: user-bt"}
+ timeout {fail "(timeout) define user command: user-bt"}
+}
+
+send_gdb "define hook-stop\n"
+gdb_expect {
+ -re "Type commands for definition of \"hook-stop\".\r\nEnd with a line saying just \"end\".\r\n>$"\
+ {send_gdb "user-b\nend\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "define hook-stop command"}
+ timeout {fail "(timeout) define hook-stop command"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "define hook-stop command"}
+ timeout {fail "(timeout) define hook-stop command"}
+}
+
+send_gdb "next\n"
+gdb_expect {
+ -re "#0\[ \t\]*main.*:81.*$gdb_prompt $"\
+ {pass "use hook-stop command"}
+ -re "$gdb_prompt $"\
+ {fail "use hook-stop command"}
+ timeout {fail "(timeout) use hook-stop command"}
+}
+
+# Verify that GDB responds gracefully to an attempt to define a "hook
+# command" which doesn't exist. (Test both the confirmed and unconfirmed
+# cases.)
+#
+send_gdb "define hook-bar\n"
+gdb_expect {
+ -re "warning: Your new `hook-bar' command does not hook any existing command.\r\nProceed.*y or n. $"\
+ {send_gdb "n\n"
+ gdb_expect {
+ -re "Not confirmed.*$gdb_prompt $"\
+ {pass "define hook undefined command aborted: bar"}
+ -re "$gdb_prompt $"\
+ {fail "define hook undefined command aborted: bar"}
+ timeout {fail "(timeout) define hook undefined command aborted: bar"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "define hook undefined command aborted: bar"}
+ timeout {fail "(timeout) define hook undefined command aborted: bar"}
+}
+
+send_gdb "define hook-bar\n"
+gdb_expect {
+ -re "warning: Your new `hook-bar' command does not hook any existing command.\r\nProceed.*y or n. $"\
+ {send_gdb "y\n"
+ gdb_expect {
+ -re "Type commands for definition of \"hook-bar\".\r\nEnd with a line saying just \"end\".\r\n>$"\
+ {send_gdb "nextwhere\nend\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "define hook undefined command: bar"}
+ timeout {fail "(timeout) define hook undefined command: bar"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "define hook undefined command: bar"}
+ timeout {fail "(timeout) define hook undefined command: bar"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "define hook undefined command: bar"}
+ timeout {fail "(timeout) define hook undefined command: bar"}
+}
+
+# This is a quasi-define command: Verify that the user can redefine
+# GDB's gdb_prompt.
+#
+send_gdb "set prompt \\(blah\\) \n"
+gdb_expect {
+ -re "\\(blah\\) $"\
+ {pass "set gdb_prompt"}
+ -re "$gdb_prompt $"\
+ {fail "set gdb_prompt"}
+ timeout {fail "(timeout) set gdb_prompt"}
+}
+
+send_gdb "set prompt \\(gdb\\) \n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "reset gdb_prompt"}
+ timeout {fail "(timeout) reset gdb_prompt"}
+}
+
+gdb_exit
+return 0
+
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.base/display.c b/gdb/testsuite/gdb.base/display.c
new file mode 100644
index 00000000000..365240922d1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/display.c
@@ -0,0 +1,52 @@
+/* Loop and vars for tests of display commands
+*/
+#include <stdio.h>
+#define LOOP 10
+
+int sum = 0;
+
+int do_loops()
+{
+ int i=0;
+ int k=0;
+ int j=0;
+ float f=3.1415;
+ for( i = 0; i < LOOP; i++ ) {
+ for( j = 0; j < LOOP; j++ ) {
+ for( k = 0; k < LOOP; k++ ) {
+ sum++; f++;
+ }
+ }
+ }
+ return i;
+}
+
+int do_vars()
+{
+ int j;
+ int i = 9;
+ float f = 1.234;
+ char c = 'Q';
+ int *p_i = &i;
+ float *p_f = &f;
+ char *p_c = "rubarb and fries";
+
+ /* Need some code here to set breaks on.
+ */
+ for( j = 0; j < LOOP; j++ ) {
+ if( p_c[j] == c ) {
+ j++;
+ }
+ else {
+ i++;
+ }
+ }
+
+ return *p_i;
+}
+
+main()
+{
+ do_loops();
+ do_vars();
+}
diff --git a/gdb/testsuite/gdb.base/display.exp b/gdb/testsuite/gdb.base/display.exp
new file mode 100644
index 00000000000..e285729adab
--- /dev/null
+++ b/gdb/testsuite/gdb.base/display.exp
@@ -0,0 +1,215 @@
+# Copyright 1997, 1998, 1999, 2000
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# display.exp Test display commands
+# Also do some printing stuff for coverage's sake.
+#
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile display
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+
+
+if { [gdb_compile "${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+
+# Preserve the old timeout, and set a new one that should be
+# sufficient to avoid timing out during this test.
+set oldtimeout $timeout
+set timeout [expr "$timeout + 60"]
+verbose "Timeout is now $timeout seconds" 2
+
+# use this to debug:
+#log_user 1
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Some coverage stuff
+#
+if ![target_info exists use_gdb_stub] {
+ gdb_test "kill" ".*The program is not being run.*"
+ gdb_test "detach" ".*"
+ gdb_test "run" ".*"
+
+ gdb_load ${binfile}
+ gdb_test "kill" ".*" "kill again"
+ gdb_test "detach" ".*" "detach again"
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+}
+
+# Ok, on to real life
+#
+if ![runto_main] then {
+ fail "Could not run to main - other tests will fail."
+ continue
+}
+
+# Disable hardware watchpoints if necessary.
+if [target_info exists gdb,no_hardware_watchpoints] {
+ gdb_test "set can-use-hw-watchpoints 0" "" ""
+}
+
+gdb_test "break 14" ".*Breakpoint 2.*" "break do_loops"
+gdb_test "cont" ".*Breakpoint 2, do_loops.*" "get to do_loops"
+
+# Create stopping points.
+#
+gdb_test "watch sum" ".*\[Ww\]atchpoint 3: sum.*" "set watch"
+gdb_test "break 19" ".*Breakpoint 4.*" "break 19"
+
+# Create displays for those points
+#
+gdb_test "info disp" ".*There are no auto-display expressions now..*" "inf disp"
+gdb_test "disp i" ".*1: i = 0.*" "display i"
+gdb_test "disp/x j" ".*2: /x j = 0x0.*" "display j"
+gdb_test "disp/i &k" ".*3: x/i &k $hex:.*" "display &k"
+gdb_test "disp/f f" ".*4: /f f = 3.1415*" "display/f f"
+gdb_test "disp/s &sum" ".*5: x/s &sum $hex.*sum.:.*" "display/s &sum"
+
+# Hit the displays
+#
+gdb_test "cont" ".*\[Ww\]atchpoint 3: sum.*\[1-9\]*: x/s &sum.*\[1-9\]*: /f f = 3.1415\r\n\[1-9\]*: x/i &k.*\r\n\[1-9\]*: /x j = 0x0\r\n\[1-9\]*: i = 0.*" "first disp"
+gdb_test "cont" ".*\[Ww\]atchpoint 3: sum.*\[1-9\]*: x/s &sum.*\[1-9\]*: /f f = 4.1415\r\n\[1-9\]*: x/i &k.*\r\n\[1-9\]*: /x j = 0x0.*\[1-9\]*: i = 0.*" "second disp"
+
+gdb_test "enab disp 6" ".*No display number 6..*" "catch err"
+gdb_test "disab disp 1" ".*" "disab disp 1"
+gdb_test "disab disp 2" ".*" "disab disp 2"
+gdb_test "enab disp 1" ".*" "re-enab"
+gdb_test "enab disp 1" ".*" "re-enab of enab"
+gdb_test "undisp 5" ".*" "undisp"
+gdb_test "info disp" ".*Auto-display expressions now in effect.*y /f f.*y /1bi &k.*n /x j.*y i.*" "info disp"
+
+gdb_test "cont" ".*\[Ww\]atch.*5.1415.*.*i = 0.*" "next hit"
+
+send_gdb "undisp\n"
+gdb_expect {
+ -re ".*Delete all auto-display expressions.*y or n. $" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "y\r\n$gdb_prompt $" {
+ pass "undisp all"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "some un-helpful response"
+ }
+ -re ".*Delete all.*$" {
+ fail "re-ask question"
+ }
+ timeout { fail "timeout" }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "undisp all"
+ }
+ timeout { fail "timeout" }
+}
+
+gdb_test "disab 3" ".*.*" "disab 3"
+gdb_test "cont" ".*Breakpoint 4.*" "watch off"
+
+# Now the printf tests
+#
+# The "finish" command may leave us mid-line in the caller on some
+# targets, including but not limited to the m68k, i386 & PA. So we
+# have to arrange to step until we hit the line with the call to
+# "do_vars".
+send_gdb "finish\n"
+gdb_expect {
+ -re ".*do_loops\\(\\);.*$gdb_prompt $" {
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re ".*do_vars.*$gdb_prompt $" {
+ pass "finish"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "finish"
+ gdb_suppress_tests
+ }
+ timeout {
+ fail "(timeout) finish"
+ gdb_suppress_tests
+ }
+}
+
+gdb_test "step" ".*do_vars.*.*27.*"
+gdb_test "tbreak 37" ".*Breakpoint 5 a.*"
+gdb_test "cont" ".*do_vars.*37.*37.*"
+
+# Beat on printf a bit
+#
+gdb_test "printf" ".*Argument required.*"
+gdb_test "printf %d" ".*Bad format string, missing.*"
+gdb_test "printf \"%d" ".*Bad format string, non-terminated.*"
+gdb_test "printf \"%d%d\",i" ".*Wrong number of arguments.*"
+gdb_test "printf \"\\\\!\\a\\f\\r\\t\\v\\b\\n\"" ".*!.*"
+gdb_test "printf \"\"" ".*" "re-set term"
+gdb_test "printf \"\\w\"" ".*Unrecognized escape character.*"
+gdb_test "printf \"%d\" j" ".*Invalid argument syntax.*"
+
+# play with "print", too
+#
+gdb_test "print/r j" ".*Undefined output format.*"
+gdb_test "print j" ".*" "debug test output"
+
+# x/0 j doesn't produce any output and terminates PA64 process when testing
+if [istarget "hppa2.0w-hp-hpux11*"] {
+ xfail "'x/0 j' terminates PA64 process - skipped test point"
+} else {
+ gdb_test "x/0 j" ".*"
+}
+if [istarget "hppa*-hp-hpux*"] {
+ # on HP-UX you could access the first page without getting an error
+ gdb_test "x/rx j" ".*(Cannot access|Error accessing) memory.*|.*0xa:\[ \t\]*\[0-9\]+.*"
+}
+gdb_test "print/0 j" ".*Item count other than 1 is meaningless.*" "print/0 j"
+gdb_test "print/s sum" ".*Format letter.*is meaningless.*" " no s"
+gdb_test "print/i sum" ".*Format letter.*is meaningless.*.*" "no i"
+gdb_test "print/a &sum" ".*= $hex.*<sum>.*"
+# If the constant below is larger than the length of main, then
+# this test will (incorrectly) fail. So use a small number.
+gdb_test "print/a main+4" ".*= $hex.*<.*>.*"
+gdb_test "print/a \$pc" ".*= $hex.*<do_vars+.*>.*"
+gdb_test "print/a &&j" ".*A .* error in expression.*"
+
+# Done!
+#
+gdb_exit
+
+# Restore the preserved old timeout value.
+set timeout $oldtimeout
+verbose "Timeout is now $timeout seconds" 2
+
+return 0
diff --git a/gdb/testsuite/gdb.base/dump.c b/gdb/testsuite/gdb.base/dump.c
new file mode 100644
index 00000000000..784edf6ac8b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dump.c
@@ -0,0 +1,44 @@
+#define ARRSIZE 32
+int intarray[ARRSIZE], intarray2[ARRSIZE];
+
+struct teststruct {
+ int a;
+ int b;
+ int c;
+ int d;
+ int e;
+ int f;
+ int g;
+} intstruct, intstruct2;
+
+void checkpoint1 ()
+{
+ /* intarray and teststruct have been initialized. */
+}
+
+void
+zero_all ()
+{
+ memset ((char *) &intarray, 0, sizeof (intarray));
+ memset ((char *) &intarray2, 0, sizeof (intarray2));
+ memset ((char *) &intstruct, 0, sizeof (intstruct));
+ memset ((char *) &intstruct2, 0, sizeof (intstruct2));
+}
+
+main()
+{
+ int i;
+
+ for (i = 0; i < ARRSIZE; i++)
+ intarray[i] = i+1;
+
+ intstruct.a = 12 * 1;
+ intstruct.b = 12 * 2;
+ intstruct.c = 12 * 3;
+ intstruct.d = 12 * 4;
+ intstruct.e = 12 * 5;
+ intstruct.f = 12 * 6;
+ intstruct.g = 12 * 7;
+
+ checkpoint1 ();
+}
diff --git a/gdb/testsuite/gdb.base/dump.exp b/gdb/testsuite/gdb.base/dump.exp
new file mode 100644
index 00000000000..826fdfb0bfd
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dump.exp
@@ -0,0 +1,442 @@
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@redhat.com)
+# This is a test for the gdb command "dump".
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "dump"
+
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Clean up any stale output files from previous test runs
+
+remote_exec build "rm -f intarr1.bin intarr1b.bin intarr1.ihex intarr1.srec intarr1.tekhex intarr2.bin intarr2b.bin intarr2.ihex intarr2.srec intarr2.tekhex intstr1.bin intstr1b.bin intstr1.ihex intstr1.srec intstr1.tekhex intstr2.bin intstr2b.bin intstr2.ihex intstr2.srec intstr2.tekhex intarr3.srec"
+
+# Test help (FIXME:)
+
+# Run target program until data structs are initialized.
+
+if { ! [ runto checkpoint1 ] } then {
+ gdb_suppress_entire_file "Program failed to run, so all tests in this file will automatically fail."
+}
+
+# Now generate some dump files.
+
+proc make_dump_file { command msg } {
+ global gdb_prompt
+
+ send_gdb "${command}\n"
+ gdb_expect {
+ -re ".*\[Ee\]rror.*$gdb_prompt $" { fail $msg }
+ -re ".*\[Ww\]arning.*$gdb_prompt $" { fail $msg }
+ -re ".*\[Uu\]ndefined .*$gdb_prompt $" { fail $msg }
+ -re ".*$gdb_prompt $" { pass $msg }
+ timeout { fail "$msg (timeout)" }
+ }
+}
+
+make_dump_file "dump val intarr1.bin intarray" \
+ "dump array as value, default"
+
+make_dump_file "dump val intstr1.bin intstruct" \
+ "dump struct as value, default"
+
+make_dump_file "dump bin val intarr1b.bin intarray" \
+ "dump array as value, binary"
+
+make_dump_file "dump bin val intstr1b.bin intstruct" \
+ "dump struct as value, binary"
+
+make_dump_file "dump srec val intarr1.srec intarray" \
+ "dump array as value, srec"
+
+make_dump_file "dump srec val intstr1.srec intstruct" \
+ "dump struct as value, srec"
+
+make_dump_file "dump ihex val intarr1.ihex intarray" \
+ "dump array as value, intel hex"
+
+make_dump_file "dump ihex val intstr1.ihex intstruct" \
+ "dump struct as value, intel hex"
+
+make_dump_file "dump tekhex val intarr1.tekhex intarray" \
+ "dump array as value, tekhex"
+
+make_dump_file "dump tekhex val intstr1.tekhex intstruct" \
+ "dump struct as value, tekhex"
+
+proc capture_value { expression } {
+ global gdb_prompt
+ global expect_out
+
+ set output_string ""
+ send_gdb "print ${expression}\n"
+ gdb_expect {
+ -re ".*\[\r\n\]+.\[0123456789\]+ = (\[^\r\n\]+).*$gdb_prompt $" {
+ set output_string $expect_out(1,string)
+ }
+ default {
+ fail "capture_value failed on $expression."
+ }
+ }
+ return $output_string
+}
+
+set array_start [capture_value "/x &intarray\[0\]"]
+set array_end [capture_value "/x &intarray\[32\]"]
+set struct_start [capture_value "/x &intstruct"]
+set struct_end [capture_value "/x &intstruct + 1"]
+
+set array_val [capture_value "intarray"]
+set struct_val [capture_value "intstruct"]
+
+make_dump_file "dump mem intarr2.bin $array_start $array_end" \
+ "dump array as memory, default"
+
+make_dump_file "dump mem intstr2.bin $struct_start $struct_end" \
+ "dump struct as memory, default"
+
+make_dump_file "dump bin mem intarr2b.bin $array_start $array_end" \
+ "dump array as memory, binary"
+
+make_dump_file "dump bin mem intstr2b.bin $struct_start $struct_end" \
+ "dump struct as memory, binary"
+
+make_dump_file "dump srec mem intarr2.srec $array_start $array_end" \
+ "dump array as memory, srec"
+
+make_dump_file "dump srec mem intstr2.srec $struct_start $struct_end" \
+ "dump struct as memory, srec"
+
+make_dump_file "dump ihex mem intarr2.ihex $array_start $array_end" \
+ "dump array as memory, ihex"
+
+make_dump_file "dump ihex mem intstr2.ihex $struct_start $struct_end" \
+ "dump struct as memory, ihex"
+
+make_dump_file "dump tekhex mem intarr2.tekhex $array_start $array_end" \
+ "dump array as memory, tekhex"
+
+make_dump_file "dump tekhex mem intstr2.tekhex $struct_start $struct_end" \
+ "dump struct as memory, tekhex"
+
+# test complex expressions
+make_dump_file \
+ "dump srec mem intarr3.srec &intarray \(char *\) &intarray + sizeof intarray" \
+ "dump array as mem, srec, expressions"
+
+
+# Now start a fresh gdb session, and reload the saved value files.
+
+gdb_exit
+gdb_start
+gdb_file_cmd ${binfile}
+
+# Reload saved values one by one, and compare.
+
+if { ![string compare $array_val [capture_value "intarray"]] } then {
+ fail "start with intarray un-initialized"
+} else {
+ pass "start with intarray un-initialized"
+}
+
+if { ![string compare $struct_val [capture_value "intstruct"]] } then {
+ fail "start with intstruct un-initialized"
+} else {
+ pass "start with intstruct un-initialized"
+}
+
+proc test_reload_saved_value { filename msg oldval newval } {
+ global gdb_prompt
+
+ gdb_file_cmd $filename
+ if { ![string compare $oldval [capture_value $newval]] } then {
+ pass $msg
+ } else {
+ fail $msg
+ }
+}
+
+proc test_restore_saved_value { restore_args msg oldval newval } {
+ global gdb_prompt
+
+ gdb_test "restore $restore_args" \
+ "Restoring .*" \
+ "Restore command, $msg"
+
+ if { ![string compare $oldval [capture_value $newval]] } then {
+ pass "Restored value, $msg"
+ } else {
+ fail "Restored value, $msg"
+ }
+}
+
+test_reload_saved_value "intarr1.srec" "reload array as value, srec" \
+ $array_val "intarray"
+test_reload_saved_value "intstr1.srec" "reload struct as value, srec" \
+ $struct_val "intstruct"
+test_reload_saved_value "intarr2.srec" "reload array as memory, srec" \
+ $array_val "intarray"
+test_reload_saved_value "intstr2.srec" "reload struct as memory, srec" \
+ $struct_val "intstruct"
+
+test_reload_saved_value "intarr1.ihex" "reload array as value, intel hex" \
+ $array_val "intarray"
+test_reload_saved_value "intstr1.ihex" "reload struct as value, intel hex" \
+ $struct_val "intstruct"
+test_reload_saved_value "intarr2.ihex" "reload array as memory, intel hex" \
+ $array_val "intarray"
+test_reload_saved_value "intstr2.ihex" "reload struct as memory, intel hex" \
+ $struct_val "intstruct"
+
+test_reload_saved_value "intarr1.tekhex" "reload array as value, tekhex" \
+ $array_val "intarray"
+test_reload_saved_value "intstr1.tekhex" "reload struct as value, tekhex" \
+ $struct_val "intstruct"
+test_reload_saved_value "intarr2.tekhex" "reload array as memory, tekhex" \
+ $array_val "intarray"
+test_reload_saved_value "intstr2.tekhex" "reload struct as memory, tekhex" \
+ $struct_val "intstruct"
+
+# Start a fresh gdb session
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Run to main.
+if { ! [ runto main ] } then {
+ gdb_suppress_entire_file "Program failed to run, so remaining tests in this file will automatically fail."
+}
+
+if { ![string compare $array_val [capture_value "intarray"]] } then {
+ fail "start with intarray un-initialized, runto main"
+} else {
+ pass "start with intarray un-initialized, runto main"
+}
+
+if { ![string compare $struct_val [capture_value "intstruct"]] } then {
+ fail "start with intstruct un-initialized, runto main"
+} else {
+ pass "start with intstruct un-initialized, runto main"
+}
+
+test_restore_saved_value "intarr1.srec" "array as value, srec" \
+ $array_val "intarray"
+
+test_restore_saved_value "intstr1.srec" "struct as value, srec" \
+ $struct_val "intstruct"
+
+gdb_test "print zero_all ()" "void" "zero all"
+
+test_restore_saved_value "intarr2.srec" "array as memory, srec" \
+ $array_val "intarray"
+
+test_restore_saved_value "intstr2.srec" "struct as memory, srec" \
+ $struct_val "intstruct"
+
+gdb_test "print zero_all ()" ""
+
+test_restore_saved_value "intarr1.ihex" "array as value, ihex" \
+ $array_val "intarray"
+
+test_restore_saved_value "intstr1.ihex" "struct as value, ihex" \
+ $struct_val "intstruct"
+
+gdb_test "print zero_all ()" ""
+
+test_restore_saved_value "intarr2.ihex" "array as memory, ihex" \
+ $array_val "intarray"
+
+test_restore_saved_value "intstr2.ihex" "struct as memory, ihex" \
+ $struct_val "intstruct"
+
+gdb_test "print zero_all ()" ""
+
+test_restore_saved_value "intarr1.tekhex" "array as value, tekhex" \
+ $array_val "intarray"
+
+test_restore_saved_value "intstr1.tekhex" "struct as value, tekhex" \
+ $struct_val "intstruct"
+
+gdb_test "print zero_all ()" ""
+
+test_restore_saved_value "intarr2.tekhex" "array as memory, tekhex" \
+ $array_val "intarray"
+
+test_restore_saved_value "intstr2.tekhex" "struct as memory, tekhex" \
+ $struct_val "intstruct"
+
+gdb_test "print zero_all ()" ""
+
+test_restore_saved_value "intarr1.bin binary $array_start" \
+ "array as value, binary" \
+ $array_val "intarray"
+
+test_restore_saved_value "intstr1.bin binary $struct_start" \
+ "struct as value, binary" \
+ $struct_val "intstruct"
+
+gdb_test "print zero_all ()" ""
+
+test_restore_saved_value "intarr2.bin binary $array_start" \
+ "array as memory, binary" \
+ $array_val "intarray"
+
+test_restore_saved_value "intstr2.bin binary $struct_start" \
+ "struct as memory, binary" \
+ $struct_val "intstruct"
+
+# test restore with offset.
+
+set array2_start [capture_value "/x &intarray2\[0\]"]
+set struct2_start [capture_value "/x &intstruct2"]
+set array2_offset \
+ [capture_value "/x (char *) &intarray2 - (char *) &intarray"]
+set struct2_offset \
+ [capture_value "/x (char *) &intstruct2 - (char *) &intstruct"]
+
+gdb_test "print zero_all ()" ""
+
+test_restore_saved_value "intarr1.srec $array2_offset" \
+ "array copy, srec" \
+ $array_val "intarray2"
+
+test_restore_saved_value "intstr1.srec $struct2_offset" \
+ "struct copy, srec" \
+ $struct_val "intstruct2"
+
+gdb_test "print zero_all ()" ""
+
+test_restore_saved_value "intarr1.ihex $array2_offset" \
+ "array copy, ihex" \
+ $array_val "intarray2"
+
+test_restore_saved_value "intstr1.ihex $struct2_offset" \
+ "struct copy, ihex" \
+ $struct_val "intstruct2"
+
+gdb_test "print zero_all ()" ""
+
+test_restore_saved_value "intarr1.tekhex $array2_offset" \
+ "array copy, tekhex" \
+ $array_val "intarray2"
+
+test_restore_saved_value "intstr1.tekhex $struct2_offset" \
+ "struct copy, tekhex" \
+ $struct_val "intstruct2"
+
+gdb_test "print zero_all ()" ""
+
+test_restore_saved_value "intarr1.bin binary $array2_start" \
+ "array copy, binary" \
+ $array_val "intarray2"
+
+test_restore_saved_value "intstr1.bin binary $struct2_start" \
+ "struct copy, binary" \
+ $struct_val "intstruct2"
+
+#
+# test restore with start/stop addresses.
+#
+# For this purpose, we will restore just the third element of the array,
+# and check to see that adjacent elements are not modified.
+#
+# We will need the address and offset of the third and fourth elements.
+#
+
+set element3_start [capture_value "/x &intarray\[3\]"]
+set element4_start [capture_value "/x &intarray\[4\]"]
+set element3_offset \
+ [capture_value "/x (char *) &intarray\[3\] - (char *) &intarray\[0\]"]
+set element4_offset \
+ [capture_value "/x (char *) &intarray\[4\] - (char *) &intarray\[0\]"]
+
+gdb_test "print zero_all ()" ""
+
+test_restore_saved_value "intarr1.srec 0 $element3_start $element4_start" \
+ "array partial, srec" \
+ [capture_value "4"] "intarray\[3\]"
+
+gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 1"
+gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 1"
+
+gdb_test "print zero_all ()" ""
+
+test_restore_saved_value "intarr1.ihex 0 $element3_start $element4_start" \
+ "array partial, ihex" \
+ [capture_value "4"] "intarray\[3\]"
+
+gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 2"
+gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 2"
+
+gdb_test "print zero_all ()" ""
+
+test_restore_saved_value "intarr1.tekhex 0 $element3_start $element4_start" \
+ "array partial, tekhex" \
+ [capture_value "4"] "intarray\[3\]"
+
+gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 3"
+gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 3"
+
+gdb_test "print zero_all ()" ""
+
+test_restore_saved_value \
+ "intarr1.bin binary $array_start $element3_offset $element4_offset" \
+ "array partial, binary" \
+ [capture_value "4"] "intarray\[3\]"
+
+gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 4"
+gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 4"
+
+gdb_test "print zero_all ()" "" ""
+
+# restore with expressions
+test_restore_saved_value \
+ "intarr3.srec ${array2_start}-${array_start} &intarray\[3\] &intarray\[4\]" \
+ "array partial with expressions" \
+ [capture_value "4"] "intarray2\[3\]"
+
+gdb_test "print intarray2\[2\] == 0" " = 1" "element 2 not changed, == 4"
+gdb_test "print intarray2\[4\] == 0" " = 1" "element 4 not changed, == 4"
+
+
+# clean up files
+
+remote_exec build "rm -f intarr1.bin intarr1b.bin intarr1.ihex intarr1.srec intarr1.tekhex intarr2.bin intarr2b.bin intarr2.ihex intarr2.srec intarr2.tekhex intstr1.bin intstr1b.bin intstr1.ihex intstr1.srec intstr1.tekhex intstr2.bin intstr2b.bin intstr2.ihex intstr2.srec intstr2.tekhex intarr3.srec"
+
diff --git a/gdb/testsuite/gdb.base/echo.exp b/gdb/testsuite/gdb.base/echo.exp
new file mode 100644
index 00000000000..c8220ff2d65
--- /dev/null
+++ b/gdb/testsuite/gdb.base/echo.exp
@@ -0,0 +1,44 @@
+# Copyright (C) 1988, 1990, 1991, 1992, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+# Crank up gdb.
+gdb_start
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+#
+# test the echo command
+#
+
+# this sets the prms id number. This is the number that will appear
+# on all the output logs.
+# ex: set prms_id 643
+set prms_id 0
+
+# this sets the bug id id. This is the number that will appear
+# on all the output logs. This is optional and if it is not set
+# it will appear on all output logs as a 0.
+# ex: set bug_id 12
+set bug_id 0
+
+gdb_test "echo Hello world!\\n" "Hello world!" "Echo test"
diff --git a/gdb/testsuite/gdb.base/ena-dis-br.exp b/gdb/testsuite/gdb.base/ena-dis-br.exp
new file mode 100644
index 00000000000..40b0bda3fd4
--- /dev/null
+++ b/gdb/testsuite/gdb.base/ena-dis-br.exp
@@ -0,0 +1,493 @@
+# Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+global usestubs
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "break"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+proc rerun_to_main {} {
+ global gdb_prompt
+
+ if [target_info exists use_gdb_stub] {
+ gdb_run_cmd
+ gdb_expect {
+ -re ".*Breakpoint .*main .*$gdb_prompt $"\
+ {pass "rerun to main" ; return 0}
+ -re "$gdb_prompt $"\
+ {fail "rerun to main" ; return 0}
+ timeout {fail "(timeout) rerun to main" ; return 0}
+ }
+ } else {
+ send_gdb "run\n"
+ gdb_expect {
+ -re "Starting program.*$gdb_prompt $"\
+ {pass "rerun to main" ; return 0}
+ -re "$gdb_prompt $"\
+ {fail "rerun to main" ; return 0}
+ timeout {fail "(timeout) rerun to main" ; return 0}
+ }
+ }
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then { fail "enable/disable break tests suppressed" }
+
+# Verify that we can set a breakpoint (the location is irrelevant),
+# then enable it (yes, it's already enabled by default), then hit it.
+#
+send_gdb "break marker1\n"
+gdb_expect {
+ -re "Breakpoint (\[0-9\]*) at .*, line 4\[38\].*$gdb_prompt $"\
+ {pass "break marker1"}
+ -re "$gdb_prompt $"\
+ {fail "break marker1"}
+ timeout {fail "(timeout) break marker1"}
+}
+
+send_gdb "enable $expect_out(1,string)\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "enable break marker1"}
+ timeout {fail "(timeout) enable break marker1"}
+}
+
+send_gdb "info break $expect_out(1,string)\n"
+gdb_expect {
+ -re "\[0-9\]*\[ \t\]+breakpoint\[ \t\]+keep\[ \t\]+y.*$gdb_prompt $"\
+ {pass "info break marker1"}
+ -re "$gdb_prompt $"\
+ {fail "info break marker1"}
+ timeout {fail "(timeout) info break marker1"}
+}
+
+# See the comments in condbreak.exp for "run until breakpoint at marker1"
+# for an explanation of the xfail below.
+send_gdb "continue\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]*, marker1.*$gdb_prompt $"\
+ {pass "continue to break marker1"}
+ -re "Breakpoint \[0-9\]*, $hex in marker1.*$gdb_prompt $"\
+ {xfail "continue to break marker1"}
+ -re "$gdb_prompt $"\
+ {fail "continue to break marker1"}
+ timeout {fail "(timeout) continue to break marker1"}
+}
+
+send_gdb "delete $expect_out(1,string)\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "delete break marker1"}
+ timeout {fail "(timeout) delete break marker1"}
+}
+
+# Verify that we can set a breakpoint to be self-disabling after
+# the first time it triggers.
+#
+send_gdb "break marker2\n"
+gdb_expect {
+ -re "Breakpoint (\[0-9\]*) at .*, line 4\[49\].*$gdb_prompt $"\
+ {pass "break marker2"}
+ -re "$gdb_prompt $"\
+ {fail "break marker2"}
+ timeout {fail "(timeout) break marker2"}
+}
+
+send_gdb "enable once $expect_out(1,string)\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "enable once break marker2"}
+ timeout {fail "(timeout) enable once break marker2"}
+}
+
+send_gdb "info break $expect_out(1,string)\n"
+gdb_expect {
+ -re "\[0-9\]*\[ \t\]+breakpoint\[ \t\]+dis\[ \t\]+y.*$gdb_prompt $"\
+ {pass "info auto-disabled break marker2"}
+ -re "$gdb_prompt $"\
+ {fail "info auto-disabled break marker2"}
+ timeout {fail "(timeout) info auto-disabled break marker2"}
+}
+
+# See the comments in condbreak.exp for "run until breakpoint at marker1"
+# for an explanation of the xfail below.
+send_gdb "continue\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]*, marker2.*$gdb_prompt $"\
+ {pass "continue to auto-disabled break marker2"}
+ -re "Breakpoint \[0-9\]*, $hex in marker2.*$gdb_prompt $"\
+ {xfail "continue to auto-disabled break marker2"}
+ -re "$gdb_prompt $"\
+ {fail "continue to auto-disabled break marker2"}
+ timeout {fail "(timeout) continue to auto-disabled break marker2"}
+}
+
+send_gdb "info break $expect_out(1,string)\n"
+gdb_expect {
+ -re "\[0-9\]*\[ \t\]+breakpoint\[ \t\]+dis\[ \t\]+n.*$gdb_prompt $"\
+ {pass "info auto-disabled break marker2"}
+ -re "$gdb_prompt $"\
+ {fail "info auto-disabled break marker2"}
+ timeout {fail "(timeout) info auto-disabled break marker2"}
+}
+
+# Verify that we don't stop at a disabled breakpoint.
+#
+gdb_continue_to_end "no stop"
+rerun_to_main
+gdb_continue_to_end "no stop at auto-disabled break marker2"
+
+# Verify that we can set a breakpoint to be self-deleting after
+# the first time it triggers.
+#
+if ![runto_main] then { fail "enable/disable break tests suppressed" }
+
+send_gdb "break marker3\n"
+gdb_expect {
+ -re "Breakpoint (\[0-9\]*) at .*, line (45|50).*$gdb_prompt $"\
+ {pass "break marker3"}
+ -re "$gdb_prompt $"\
+ {fail "break marker3"}
+ timeout {fail "(timeout) break marker3"}
+}
+
+send_gdb "enable del $expect_out(1,string)\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "enable del break marker3"}
+ timeout {fail "(timeout) enable del break marker3"}
+}
+
+send_gdb "info break $expect_out(1,string)\n"
+gdb_expect {
+ -re "\[0-9\]*\[ \t\]+breakpoint\[ \t\]+del\[ \t\]+y.*$gdb_prompt $"\
+ {pass "info auto-deleted break marker2"}
+ -re "$gdb_prompt $"\
+ {fail "info auto-deleted break marker2"}
+ timeout {fail "(timeout) info auto-deleted break marker2"}
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re ".*marker3 .*:(45|50).*$gdb_prompt $"\
+ {pass "continue to auto-deleted break marker3"}
+ -re "Breakpoint \[0-9\]*, marker3.*$gdb_prompt $"\
+ {fail "continue to auto-deleted break marker3"}
+ -re "$gdb_prompt $"\
+ {fail "continue to auto-deleted break marker3"}
+ timeout {fail "(timeout) continue to break marker3"}
+}
+
+send_gdb "info break $expect_out(1,string)\n"
+gdb_expect {
+ -re ".*No breakpoint or watchpoint number.*$gdb_prompt $"\
+ {pass "info auto-deleted break marker3"}
+ -re "\[0-9\]*\[ \t\]+breakpoint\[ \t\].*$gdb_prompt $"\
+ {fail "info auto-deleted break marker3"}
+ -re "$gdb_prompt $"\
+ {fail "info auto-deleted break marker3"}
+ timeout {fail "(timeout) info auto-deleted break marker3"}
+}
+
+# Verify that we can set a breakpoint and manually disable it (we've
+# already proven that disabled bp's don't trigger).
+#
+send_gdb "break marker4\n"
+gdb_expect {
+ -re "Breakpoint (\[0-9\]*) at .*, line (46|51).*$gdb_prompt $"\
+ {pass "break marker4"}
+ -re "$gdb_prompt $"\
+ {fail "break marker4"}
+ timeout {fail "(timeout) break marker4"}
+}
+
+send_gdb "disable $expect_out(1,string)\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "disable break marker4"}
+ timeout {fail "(timeout) disable break marker4"}
+}
+
+send_gdb "info break $expect_out(1,string)\n"
+gdb_expect {
+ -re "\[0-9\]*\[ \t\]+breakpoint\[ \t\]+keep\[ \t\]+n.*$gdb_prompt $"\
+ {pass "info break marker4"}
+ -re "$gdb_prompt $"\
+ {fail "info break marker4"}
+ timeout {fail "(timeout) info break marker4"}
+}
+
+# Verify that we can set a breakpoint with an ignore count N, which
+# should cause the next N triggers of the bp to be ignored. (This is
+# a flavor of enablement/disablement, after all.)
+#
+if ![runto_main] then { fail "enable/disable break tests suppressed" }
+
+send_gdb "break marker1\n"
+gdb_expect {
+ -re "Breakpoint (\[0-9\]*) at .*, line 4\[38\].*$gdb_prompt $"\
+ {pass "break marker1"}
+ -re "$gdb_prompt $"\
+ {fail "break marker1"}
+ timeout {fail "(timeout) break marker1"}
+}
+
+# Verify that an ignore of a non-existent breakpoint is gracefully
+# handled.
+#
+send_gdb "ignore 999 2\n"
+gdb_expect {
+ -re "No breakpoint number 999..*$gdb_prompt $"\
+ {pass "ignore non-existent break"}
+ -re "$gdb_prompt $"\
+ {fail "ignore non-existent break"}
+ timeout {fail "(timeout) ignore non-existent break"}
+}
+
+# Verify that a missing ignore count is gracefully handled.
+#
+send_gdb "ignore $expect_out(1,string) \n"
+gdb_expect {
+ -re "Second argument .specified ignore-count. is missing..*$gdb_prompt $"\
+ {pass "ignore break with missing ignore count"}
+ -re "$gdb_prompt $"\
+ {fail "ignore break with missing ignore count"}
+ timeout {fail "(timeout) ignore break with missing ignore count"}
+}
+
+# Verify that a negative or zero ignore count is handled gracefully
+# (they both are treated the same).
+#
+send_gdb "ignore $expect_out(1,string) -1\n"
+gdb_expect {
+ -re "Will stop next time breakpoint \[0-9\]* is reached..*$gdb_prompt $"\
+ {pass "ignore break marker1 -1"}
+ -re "$gdb_prompt $"\
+ {fail "ignore break marker1 -1"}
+ timeout {fail "(timeout) ignore break marker1 -1"}
+}
+
+send_gdb "ignore $expect_out(1,string) 0\n"
+gdb_expect {
+ -re "Will stop next time breakpoint \[0-9\]* is reached..*$gdb_prompt $"\
+ {pass "ignore break marker1 0"}
+ -re "$gdb_prompt $"\
+ {fail "ignore break marker1 0"}
+ timeout {fail "(timeout) ignore break marker1 0"}
+}
+
+send_gdb "ignore $expect_out(1,string) 1\n"
+gdb_expect {
+ -re "Will ignore next crossing of breakpoint \[0-9\]*.*$gdb_prompt $"\
+ {pass "ignore break marker1"}
+ -re "$gdb_prompt $"\
+ {fail "ignore break marker1"}
+ timeout {fail "(timeout) ignore break marker1"}
+}
+
+send_gdb "info break $expect_out(1,string)\n"
+gdb_expect {
+ -re "\[0-9\]*\[ \t\]+breakpoint\[ \t\]+keep\[ \t\]+y.*ignore next 1 hits.*$gdb_prompt $"\
+ {pass "info ignored break marker1"}
+ -re "$gdb_prompt $"\
+ {fail "info ignored break marker1"}
+ timeout {fail "(timeout) info ignored break marker1"}
+}
+
+gdb_continue_to_end "no stop at ignored break marker1"
+rerun_to_main
+
+# See the comments in condbreak.exp for "run until breakpoint at marker1"
+# for an explanation of the xfail below.
+send_gdb "continue\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]*, marker1.*$gdb_prompt $"\
+ {pass "continue to break marker1, 2nd time"}
+ -re "Breakpoint \[0-9\]*, $hex in marker1.*$gdb_prompt $"\
+ {xfail "continue to break marker1, 2nd time"}
+ -re "$gdb_prompt $"\
+ {fail "continue to break marker1, 2nd time"}
+ timeout {fail "(timeout) continue to break marker1, 2nd time"}
+}
+
+# Verify that we can specify both an ignore count and an auto-delete.
+#
+if ![runto_main] then { fail "enable/disable break tests suppressed" }
+
+send_gdb "break marker1\n"
+gdb_expect {
+ -re "Breakpoint (\[0-9\]*) at .*, line 4\[38\].*$gdb_prompt $"\
+ {pass "break marker1"}
+ -re "$gdb_prompt $"\
+ {fail "break marker1"}
+ timeout {fail "(timeout) break marker1"}
+}
+
+send_gdb "ignore $expect_out(1,string) 1\n"
+gdb_expect {
+ -re "Will ignore next crossing of breakpoint \[0-9\]*.*$gdb_prompt $"\
+ {pass "ignore break marker1"}
+ -re "$gdb_prompt $"\
+ {fail "ignore break marker1"}
+ timeout {fail "(timeout) ignore break marker1"}
+}
+
+send_gdb "enable del $expect_out(1,string)\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "enable del break marker1"}
+ timeout {fail "(timeout) enable del break marker1"}
+}
+
+send_gdb "info break $expect_out(1,string)\n"
+gdb_expect {
+ -re "\[0-9\]*\[ \t\]+breakpoint\[ \t\]+del\[ \t\]+y.*ignore next 1 hits.*$gdb_prompt $"\
+ {pass "info break marker1"}
+ -re "$gdb_prompt $"\
+ {fail "info break marker1"}
+ timeout {fail "(timeout) info break marker2"}
+}
+
+gdb_continue_to_end "no stop at ignored & auto-deleted break marker1"
+rerun_to_main
+
+send_gdb "continue\n"
+gdb_expect {
+ -re ".*marker1 .*:4\[38\].*$gdb_prompt $"\
+ {pass "continue to ignored & auto-deleted break marker1"}
+ -re "Breakpoint \[0-9\]*, marker1.*$gdb_prompt $"\
+ {fail "continue to ignored & auto-deleted break marker1"}
+ -re "$gdb_prompt $"\
+ {fail "continue to ignored & auto-deleted break marker1"}
+ timeout {fail "(timeout) continue to ignored & auto-deleted break marker1"}
+}
+
+# Verify that a disabled breakpoint's ignore count isn't updated when
+# the bp is encountered.
+#
+if ![runto_main] then { fail "enable/disable break tests suppressed" }
+
+send_gdb "break marker1\n"
+gdb_expect {
+ -re "Breakpoint (\[0-9\]*) at .*, line 4\[38\].*$gdb_prompt $"\
+ {pass "break marker1"}
+ -re "$gdb_prompt $"\
+ {fail "break marker1"}
+ timeout {fail "(timeout) break marker1"}
+}
+
+send_gdb "ignore $expect_out(1,string) 10\n"
+gdb_expect {
+ -re "Will ignore next 10 crossings of breakpoint \[0-9\]*.*$gdb_prompt $"\
+ {pass "ignore break marker1"}
+ -re "$gdb_prompt $"\
+ {fail "ignore break marker1"}
+ timeout {fail "(timeout) ignore break marker1"}
+}
+
+send_gdb "disable $expect_out(1,string)\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "disable break marker1"}
+ timeout {fail "(timeout) disable break marker1"}
+}
+
+gdb_continue_to_end "no stop at ignored & disabled break marker1"
+rerun_to_main
+
+send_gdb "info break $expect_out(1,string)\n"
+gdb_expect {
+ -re "\[0-9\]*\[ \t\]+breakpoint\[ \t\]+keep\[ \t\]+n.*ignore next 10 hits.*$gdb_prompt $"\
+ {pass "info ignored & disabled break marker1"}
+ -re "$gdb_prompt $"\
+ {fail "info ignored & disabled break marker1"}
+ timeout {fail "(timeout) info ignored & disabled break marker1"}
+}
+
+# Verify that GDB correctly handles the "continue" command with an argument,
+# which is an ignore count to set on the currently stopped-at breakpoint.
+# (Also verify that GDB gracefully handles the case where the inferior
+# isn't stopped at a breakpoint.)
+#
+if ![runto_main] then { fail "enable/disable break tests suppressed" }
+
+send_gdb "break 79\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]*.*, line 79.*$gdb_prompt $"\
+ {pass "prepare to continue with ignore count"}
+ -re "$gdb_prompt $"\
+ {fail "prepare to continue with ignore count"}
+ timeout {fail "(timeout) prepare to continue with ignore count"}
+}
+send_gdb "continue 2\n"
+gdb_expect {
+ -re "Will ignore next crossing of breakpoint \[0-9\]*. Continuing..*$gdb_prompt $"\
+ {pass "continue with ignore count"}
+ -re "$gdb_prompt $"\
+ {fail "continue with ignore count"}
+ timeout {fail "(timeout) continue with ignore count"}
+}
+
+send_gdb "next\n"
+gdb_expect {
+ -re ".*81\[ \t\]*marker1.*$gdb_prompt $"\
+ {pass "step after continue with ignore count"}
+ -re "$gdb_prompt $"\
+ {fail "step after continue with ignore count"}
+ timeout {fail "(timeout) step after continue with ignore count"}
+}
+
+# ??rehrauer: Huh. This appears to be an actual bug. (No big
+# surprise, since this feature hasn't been tested...) Looks like
+# GDB is currently trying to set the ignore count of bp # -1!
+#
+setup_xfail hppa_*_*
+send_gdb "continue 2\n"
+gdb_expect {
+ -re "Not stopped at any breakpoint; argument ignored..*$gdb_prompt $"\
+ {pass "continue with ignore count, not stopped at bpt"}
+ -re "No breakpoint number -1.*$gdb_prompt $"\
+ {xfail "(DTS'd) continue with ignore count, not stopped at bpt"}
+ -re "$gdb_prompt $"\
+ {fail "continue with ignore count, not stopped at bpt"}
+ timeout {fail "(timeout) step after continue with ignore count, not stopped at bpt"}
+}
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.base/ending-run.c b/gdb/testsuite/gdb.base/ending-run.c
new file mode 100644
index 00000000000..8c67706fbe9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/ending-run.c
@@ -0,0 +1,33 @@
+/* Test program for <next-at-end> and
+ * <leaves-core-file-on-quit> bugs.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef PROTOTYPES
+int callee (int x)
+#else
+int callee( x )
+int x;
+#endif
+{
+ int y = x * x;
+ return (y - 2);
+}
+
+int main()
+{
+
+ int *p;
+ int i;
+
+ p = (int *) malloc( 4 );
+
+ for (i = 1; i < 10; i++)
+ {
+ printf( "%d ", callee( i ));
+ fflush (stdout);
+ }
+ printf( " Goodbye!\n" ); fflush (stdout);
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/ending-run.exp b/gdb/testsuite/gdb.base/ending-run.exp
new file mode 100644
index 00000000000..656601efc98
--- /dev/null
+++ b/gdb/testsuite/gdb.base/ending-run.exp
@@ -0,0 +1,289 @@
+# Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# use this to debug:
+#
+#log_user 1
+
+# ending-run.exp -- Expect script to test ending a test run in gdb
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile ending-run
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+remote_exec build "rm -f ${binfile}"
+remote_exec build "rm -f core"
+
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# CHFts23469: Test that you can "clear" a bp set at
+# a line _before_ the routine (which will default to the
+# first line in the routine, which turns out to correspond
+# to the prolog--that's another bug...)
+#
+
+gdb_test "b ending-run.c:1" ".*Breakpoint.*ending-run.c, line 1.*" \
+ "bpt at line before routine"
+
+gdb_test "b ending-run.c:13" \
+ ".*Note.*also.*Breakpoint 2.*ending-run.c, line 13.*" \
+ "b ending-run.c:13, one"
+
+# Set up to go to the next-to-last line of the program
+#
+gdb_test "b ending-run.c:31" ".*Breakpoint 3.*ending-run.c, line 31.*"
+
+# Expect to hit the bp at line "1", but symbolize this
+# as line "13". Then try to clear it--this should work.
+#
+if [target_info exists use_gdb_stub] {
+ gdb_test "continue" ".*Breakpoint.*1.*callee.*13.*"
+} else {
+ gdb_test "r" ".*Breakpoint.*1.*callee.*13.*"
+}
+gdb_test "cle" ".*Deleted breakpoints 2 1.*" "clear worked"
+send_gdb "i b\n"
+gdb_expect {
+ -re ".*breakpoint.*breakpoint.*$gdb_prompt $" {
+ fail "cleared bp at line before routine"
+ }
+ -re ".*3.*main.*31.*$gdb_prompt $" {
+ pass "cleared bp at line before routine"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "cleared bp at line before routine (info b)"
+ }
+}
+
+# Test some other "clear" combinations
+#
+gdb_test "b ending-run.c:1" ".*Breakpoint.*4.*"
+gdb_test "b ending-run.c:13" ".*Note.*also.*Breakpoint.*5.*" "b ending-run.c:13, two"
+gdb_test "cle ending-run.c:13" \
+ ".*Deleted breakpoint 5.*" "Only cleared 1 by line"
+
+send_gdb "inf line ending-run.c:13\n"
+gdb_expect {
+ -re ".*address (0x\[0-9a-fA-F]*).*$gdb_prompt $" {
+ set line_eight $expect_out(1,string)
+ gdb_test "b 13" ".*Breakpoint.*6.*"
+ gdb_test "cle *$line_eight" ".*Deleted breakpoints 6 4.*" "Clear 2 by address"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "need to fix test for new compile outcome"
+ }
+}
+
+send_gdb "inf line ending-run.c:14\n"
+gdb_expect {
+ -re ".*address (0x\[0-9a-fA-F]*).*$gdb_prompt $" {
+ set line_nine $expect_out(1,string)
+ gdb_test "b ending-run.c:14" ".*Breakpoint 7.*ending-run.c, line 14.*"
+ gdb_test "b *$line_nine" ".*Note.*also.*Breakpoint 8.*"
+ gdb_test "c" ".*Breakpoint.*7.*callee.*14.*"
+ gdb_test "cle" ".*Deleted breakpoints 8 7.*" "Clear 2 by default"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "need to fix test for new compile outcome"
+ }
+}
+
+send_gdb "i b\n"
+gdb_expect {
+ -re ".*breakpoint.*breakpoint.*$gdb_prompt $" {
+ fail "all set to continue (didn't clear bps)"
+ }
+ -re ".*3.*main.*31.*$gdb_prompt $" {
+ pass "all set to continue"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "all set to continue (missing bp at end)"
+ }
+}
+
+
+# See if we can step out with control. The "1 2 3" stuff
+# is output from the program.
+#
+if ![gdb_skip_stdio_test "cont"] {
+ gdb_test "cont" ".*1 2 7 14 23 34 47 62 79.*Breakpoint.*31.*"
+} else {
+ gdb_test "cont" ".*Breakpoint.*31.*"
+}
+
+if ![gdb_skip_stdio_test "Step to return"] {
+ gdb_test "next" ".*Goodbye!.*32.*" \
+ "Step to return"
+} else {
+ gdb_test "next" "" ""
+}
+
+set old_timeout $timeout
+set timeout 50
+set program_exited 0
+send_gdb "next\n"
+gdb_expect {
+ -re "33.*$gdb_prompt $" {
+ # sometimes we stop at the closing brace, if so, do another next
+ send_gdb "next\n"
+ gdb_expect {
+ -re ".*Unable to find return pc for this frame.*$gdb_prompt $" {
+ fail "step out of main (Old bug came back!)"
+ gdb_test "n" ".*" ""
+ }
+ -re ".*in.*start.*$gdb_prompt $" {
+ pass "step out of main"
+ }
+ -re ".*in.*bsp_trap.*$gdb_prompt $" {
+ pass "step out of main"
+ }
+ -re ".*in.*init.*$gdb_prompt $" {
+ # This is what happens on sparc64-elf ultra.
+ pass "step out of main"
+ }
+ -re ".*Program exited normally.*$gdb_prompt $" {
+ # This is what happens on Linux i86 (and I would expect others)
+ set program_exited 1
+ pass "step out of main"
+ }
+ -re ".*in .nope ().*$gdb_prompt $" {
+ # This is what happens on Solaris currently -sts 1999-08-25
+ pass "step out of main (on Solaris)"
+ }
+ -re ".*in _int_reset ().*$gdb_prompt $" {
+ # This is what happens on Sanyo XStormy16
+ pass "step out of main"
+ }
+ -re ".*init ().*$gdb_prompt $" {
+ # This is what happens on many Mips targets
+ pass "step out of main"
+ }
+ -re ".*in ..change.mode ().*$gdb_prompt $" {
+ # This is what happens on ARM in thumb mode -fn 2000-02-01
+ pass "step out of main (on ARM thumb)"
+ }
+ -re ".*in.*\\\$START\\\$.*from.*dld.sl.*$gdb_prompt $" {
+ pass "step out of main"
+ }
+ -re ".*in __wrap_main ().*$gdb_prompt $" {
+ pass "step out of main (status wrapper)"
+ }
+ -re ".*$gdb_prompt $" { fail "step out of main (at end 2)" }
+ timeout {
+ fail "step out of main (hang or timeout on step at end 2)"
+ }
+ }
+ }
+ -re ".*Unable to find return pc for this frame.*$gdb_prompt $" {
+ fail "Old bug came back!"
+ gdb_test "n" ".*" ""
+ }
+ -re ".*in.*start.*$gdb_prompt $" {
+ pass "step out of main"
+ }
+ -re ".*in.*\\\$START\\\$.*from.*dld.sl.*$gdb_prompt $" {
+ pass "step out of main (2)"
+ }
+ -re ".*Program exited normally.*$gdb_prompt $" {
+ # This is what happens on Linux i86 (and I would expect others)
+ set program_exited 1
+ pass "step out of main"
+ }
+ -re ".*in.*currently asm.*$gdb_prompt $" {
+ pass "step out of main (into assembler)"
+ }
+ -re ".*Program received signal SIGTRAP.*$gdb_prompt $" {
+ pass "Cygmon stopped in ending trap."
+ }
+ -re ".*$gdb_prompt $" { fail "step out of main (at end 1)" }
+ timeout { fail "step out of main (hang or timeout on step at end 1)" }
+}
+
+if {![target_info exists use_cygmon] || ![target_info use_cygmon]} {
+ global program_exited;
+ if {[eval expr $program_exited == 0]} {
+ send_gdb "n\n"
+ gdb_expect {
+ -re "Program exited normally.*$gdb_prompt $" {
+ # If we actually have debug info for the start function,
+ # then we won't get the "Single-stepping until function
+ # exit" message.
+ pass "step to end of run"
+ }
+ -re "Single.*EXIT code 0.*Program exited normally.*$gdb_prompt $" {
+ pass "step to end of run (status wrapper)"
+ }
+ -re ".*Single.*Program exited.*$gdb_prompt $" {
+ pass "step to end of run"
+ }
+ -re ".*Single.*in exit.*from.*dld.sl.*$gdb_prompt $" {
+ pass "step to end of run"
+ gdb_test "c" ".*" "continue after exit"
+ }
+ -re ".*Single.*_int_reset.*$gdb_prompt $" {
+ pass "step to end of run"
+ setup_xfail "xstormy16-*-*"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "step to end of run"
+ }
+ timeout {
+ fail "(timeout) step to end of run"
+ }
+ }
+ }
+
+ set timeout $old_timeout
+
+ gdb_test "n" ".*The program is not being run.*" "don't step after run"
+
+ set exec_output [remote_exec host "ls core"]
+
+ if [ regexp "core not found" $exec_output] {
+ pass "No core dumped on quit"
+ } else {
+ if [ regexp "No such file or directory" $exec_output] {
+ pass "ls: core (No core dumped on quit)"
+ } else {
+ remote_exec build "rm -f core"
+ fail "ls: core (Core dumped on quit)"
+ }
+ }
+}
+
+#remote_exec build "rm -f ${binfile}"
+return 0
+
+
+
+
diff --git a/gdb/testsuite/gdb.base/environ.exp b/gdb/testsuite/gdb.base/environ.exp
new file mode 100644
index 00000000000..55ff0a0b779
--- /dev/null
+++ b/gdb/testsuite/gdb.base/environ.exp
@@ -0,0 +1,329 @@
+# Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+global usestubs
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+# This test exists solely to exercise the "environment" commands for
+# code-coverage on HP-UX.
+#
+if ![istarget "hppa*-*-hpux*"] then {
+ return
+}
+
+set testfile "break"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then { fail "environment command tests suppressed" }
+
+# (No, this is not really related to the environment commands. But it's
+# a convenient place to verify that this command works.)
+#
+send_gdb "info program\n"
+gdb_expect {
+ -re ".*Using the running image of child process \[0-9\]*.\r\nProgram stopped at 0x\[0-9a-fA-F\]*.\r\nIt stopped at breakpoint 1..*$gdb_prompt $"\
+ {pass "info program"}
+ -re "$gdb_prompt $"\
+ {fail "info program"}
+ timeout {fail "(timeout) info program"}
+}
+
+# We don't really care where this step lands, so long as it gets
+# the inferior pushed off the breakpoint it's currently on...
+#
+send_gdb "next\n"
+gdb_expect {
+ -re ".*$gdb_prompt $"\
+ {pass "step before info program"}
+ timeout {fail "(timeout) step before info program"}
+}
+send_gdb "info program\n"
+gdb_expect {
+ -re ".*Using the running image of child process \[0-9\]*.\r\nProgram stopped at 0x\[0-9a-fA-F\]*.\r\nIt stopped after being stepped..*$gdb_prompt $"\
+ {pass "info program after step"}
+ -re "$gdb_prompt $"\
+ {fail "info program after step"}
+ timeout {fail "(timeout) info program after step"}
+}
+
+if ![runto_main] then { fail "environment command tests suppressed" }
+
+send_gdb "delete\n"
+gdb_expect {
+ -re ".*y or n. $"\
+ {send_gdb "y\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $"\
+ {pass "delete breakpoint before info program"}
+ timeout {fail "(timeout) delete breakpoint before info program"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "delete breakpoint before info program"}
+ timeout {fail "(timeout) delete breakpoint before info program"}
+}
+send_gdb "info program\n"
+gdb_expect {
+ -re ".*Using the running image of child process \[0-9\]*.\r\nProgram stopped at 0x\[0-9a-fA-F\]*.\r\nIt stopped at a breakpoint that has since been deleted..*$gdb_prompt $"\
+ {pass "info program after deleted breakpoint"}
+ -re "$gdb_prompt $"\
+ {fail "info program after deleted breakpoint"}
+ timeout {fail "(timeout) info program after deleted breakpoint"}
+}
+
+# Verify that we can show all currently-set environment variables.
+# (It's a bit hacky, but nonetheless probably safe to check for at
+# least the SHELL variable.)
+#
+# need to increase timeout because of very long output
+set oldtimeout $timeout
+set timeout [expr "$timeout + 300"]
+
+send_gdb "show environment\n"
+gdb_expect {
+ -re ".*SHELL=(\[a-zA-Z0-9\]*).*$gdb_prompt $"\
+ {pass "show environment"}
+ -re "$gdb_prompt $"\
+ {fail "show environment"}
+ timeout {fail "(timeout) show environment"}
+}
+set timeout $oldtimeout
+
+# Verify that we can unset a specific environment variable.
+#
+send_gdb "unset environment EDITOR\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "issue unset environment"}
+ timeout {fail "(timeout) issue unset environment"}
+}
+send_gdb "show environment EDITOR\n"
+gdb_expect {
+ -re "Environment variable \"EDITOR\" not defined.\r\n$gdb_prompt $"\
+ {pass "unset environment"}
+ -re "$gdb_prompt $"\
+ {fail "unset environment"}
+ timeout {fail "(timeout) unset environment"}
+}
+
+# Verify that we can unset all environment variables.
+#
+send_gdb "unset environment\n"
+gdb_expect {
+ -re "Delete all environment variables.*y or n. $"\
+ {send_gdb "y\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "unset entire environment"}
+ timeout {fail "(timeout) unset entire environment"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "unset entire environment"}
+ timeout {fail "(timeout) unset entire environment"}
+}
+
+# Verify that we can set a specific environment variable.
+#
+send_gdb "set environment EDITOR emacs\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "issue set environment"}
+ timeout {fail "(timeout) issue set environment"}
+}
+send_gdb "show environment EDITOR\n"
+gdb_expect {
+ -re "EDITOR = emacs\r\n$gdb_prompt $"\
+ {pass "set environment"}
+ -re "$gdb_prompt $"\
+ {fail "set environment"}
+ timeout {fail "(timeout) set environment"}
+}
+
+# Verify that GDB responds gracefully to a request to set environment,
+# with no variable name.
+#
+send_gdb "set environment\n"
+gdb_expect {
+ -re "Argument required .environment variable and value..*$gdb_prompt $"\
+ {pass "set environment without variable disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "set environment without variable disallowed"}
+ timeout {fail "(timeout) set environment without variable disallowed"}
+}
+
+# I'm not sure just what GDB has in mind in explicitly checking
+# for this variant, but since GDB handles it, test it.
+#
+send_gdb "set environment =\n"
+gdb_expect {
+ -re "Argument required .environment variable to set..*$gdb_prompt $"\
+ {pass "set environment equals without variable disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "set environment equals without variable disallowed"}
+ timeout {fail "(timeout) set environment equals without variable disallowed"}
+}
+
+# Setting an environment variable without a value sets it to a NULL
+# value.
+#
+send_gdb "set environment EDITOR\n"
+gdb_expect {
+ -re "Setting environment variable \"EDITOR\" to null value..*$gdb_prompt $"\
+ {pass "issue set environment without variable value"}
+ -re "$gdb_prompt $"\
+ {fail "issue set environment without variable value"}
+ timeout {fail "(timeout) issue set environment without variable value"}
+}
+send_gdb "show environment EDITOR\n"
+gdb_expect {
+ -re "EDITOR = \r\n$gdb_prompt $"\
+ {pass "set environment without variable value"}
+ -re "$gdb_prompt $"\
+ {fail "set environment without variable value"}
+ timeout {fail "(timeout) set environment without variable value"}
+}
+
+# Verify that GDB responds gracefully to an attempt to show a
+# non-existent environment variable. (We hope this variable is
+# undefined!)
+#
+send_gdb "show environment FOOBARBAZGRUNGESPAZBALL\n"
+gdb_expect {
+ -re "Environment variable \"FOOBARBAZGRUNGESPAZBALL\" not defined..*$gdb_prompt $"\
+ {pass "show non-existent environment variable disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "show non-existent environment variable disallowed"}
+ timeout {fail "(timeout) show non-existent environment variable disallowed"}
+}
+
+# Verify that GDB can set an environment variable hitherto undefined.
+#
+send_gdb "set environment FOOBARBAZGRUNGESPAZBALL t\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "issue set environment for previously undefined variable"}
+ timeout {fail "(timeout) issue set environment for previously undefined variable"}
+}
+send_gdb "show environment FOOBARBAZGRUNGESPAZBALL\n"
+gdb_expect {
+ -re "FOOBARBAZGRUNGESPAZBALL = t\r\n$gdb_prompt $"\
+ {pass "set environment for previously undefined variable"}
+ -re "$gdb_prompt $"\
+ {fail "set environment for previously undefined variable"}
+ timeout {fail "(timeout) set environment for previously undefined variable"}
+}
+
+# Verify that GDB can also set an environment variable using the "="
+# syntax.
+#
+send_gdb "set environment FOOBARBAZGRUNGESPAZBALL = t\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "issue set environment with equals"}
+ timeout {fail "(timeout) issue set environment with equals"}
+}
+send_gdb "show environment FOOBARBAZGRUNGESPAZBALL\n"
+gdb_expect {
+ -re "FOOBARBAZGRUNGESPAZBALL = t\r\n$gdb_prompt $"\
+ {pass "set environment with equals"}
+ -re "$gdb_prompt $"\
+ {fail "set environment with equals"}
+ timeout {fail "(timeout) set environment with equals"}
+}
+
+# Verify that GDB can set an environment variable to a value that has
+# an embedded (trailing, in this case) equals.
+#
+send_gdb "set environment FOOBARBAZGRUNGESPAZBALL t=\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "issue set environment with trailing equals"}
+ timeout {fail "(timeout) issue set environment with trailing equals"}
+}
+send_gdb "show environment FOOBARBAZGRUNGESPAZBALL\n"
+gdb_expect {
+ -re "FOOBARBAZGRUNGESPAZBALL = t=\r\n$gdb_prompt $"\
+ {pass "set environment with trailing equals"}
+ -re "$gdb_prompt $"\
+ {fail "set environment with trailing equals"}
+ timeout {fail "(timeout) set environment with trailing equals"}
+}
+
+# Verify that GDB can set an environment variable to a value preceded
+# by whitespace, and that such whitespace is ignored (not included
+# in the set value).
+#
+send_gdb "set environment FOOBARBAZGRUNGESPAZBALL = foo\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "issue set environment with preceding whitespace"}
+ timeout {fail "(timeout) issue set environment with preceding whitespace"}
+}
+send_gdb "show environment FOOBARBAZGRUNGESPAZBALL\n"
+gdb_expect {
+ -re "FOOBARBAZGRUNGESPAZBALL = foo\r\n$gdb_prompt $"\
+ {pass "set environment with preceding whitespace"}
+ -re "$gdb_prompt $"\
+ {fail "set environment with preceding whitespace"}
+ timeout {fail "(timeout) set environment with preceding whitespace"}
+}
+
+# Verify that GDB can manipulate the distinguished PATH variable.
+#
+send_gdb "path /tmp/FOOBARBAZGRUNGESPAZBALL\n"
+gdb_expect {
+ -re ".*Executable and object file path: /tmp/FOOBARBAZGRUNGESPAZBALL.*$gdb_prompt $"\
+ {pass "issue path"}
+ -re "$gdb_prompt $"\
+ {fail "issue path"}
+ timeout {fail "(timeout) issue path"}
+}
+send_gdb "show paths\n"
+gdb_expect {
+ -re "Executable and object file path: /tmp/FOOBARBAZGRUNGESPAZBALL.*$gdb_prompt $"\
+ {pass "show paths"}
+ -re "$gdb_prompt $"\
+ {fail "show paths"}
+ timeout {fail "(timeout) show paths"}
+}
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.base/eval-skip.exp b/gdb/testsuite/gdb.base/eval-skip.exp
new file mode 100644
index 00000000000..a2ab25cdaf7
--- /dev/null
+++ b/gdb/testsuite/gdb.base/eval-skip.exp
@@ -0,0 +1,352 @@
+# Copyright 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+# This file is part of the gdb testsuite
+
+#
+# tests to cover evaluate_subexp_standard with the EVAL_SKIP flag set.
+# this happens for instance when there is short circuit evaluation in the && and ||
+# operators, or in the non returned part of a (x ? y: z) expression.
+# the part that is not evaluated is parsed and evaluated anyway, but with
+# the EVAL_SKIP flag set
+#
+# source file "int-type.c"
+#
+
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+# Check to see if we have an executable to test. If not, then either we
+# haven't tried to compile one, or the compilation failed for some reason.
+# In either case, just notify the user and skip the tests in this file.
+
+set testfile "int-type"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+
+if [get_compiler_info $binfile] {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+gdb_test "set variable x=14" "" "set variable x=14"
+gdb_test "set variable y=2" "" "set variable y=2"
+gdb_test "set variable z=2" "" "set variable z=2"
+gdb_test "set variable w=3" "" "set variable w=3"
+
+send_gdb "print (0 && (x+y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x+y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x+y))" }
+ timeout { fail "(timeout) print value of (0 && (x+y))" }
+ }
+
+
+send_gdb "print (0 && (x-y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x-y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x-y))" }
+ timeout { fail "(timeout) print value of (0 && (x-y))" }
+ }
+
+
+send_gdb "print (0 && (x*y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x*y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x*y))" }
+ timeout { fail "(timeout) print value of (0 && (x*y))" }
+ }
+
+
+
+send_gdb "print (0 && (x/y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x/y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x/y))" }
+ timeout { fail "(timeout) print value of (0 && (x/y))" }
+ }
+
+
+send_gdb "print (0 && (x%y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x%y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x%y))" }
+ timeout { fail "(timeout) print value of (0 && (x%y))" }
+ }
+
+
+send_gdb "print (0 && (x&&y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x&&y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x&&y))" }
+ timeout { fail "(timeout) print value of (0 && (x&&y))" }
+ }
+
+
+
+send_gdb "print (0 && (x||y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x||y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x||y))" }
+ timeout { fail "(timeout) print value of (0 && (x||y))" }
+ }
+
+
+
+send_gdb "print (0 && (x&y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x&y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x&y))" }
+ timeout { fail "(timeout) print value of (0 && (x&y))" }
+ }
+
+
+send_gdb "print (0 && (x|y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x|y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x|y))" }
+ timeout { fail "(timeout) print value of (0 && (x|y))" }
+ }
+
+
+send_gdb "print (0 && (x^y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x^y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x^y))" }
+ timeout { fail "(timeout) print value of (0 && (x^y))" }
+ }
+
+
+
+send_gdb "print (0 && (x < y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x < y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x < y))" }
+ timeout { fail "(timeout) print value of (0 && (x < y))" }
+ }
+
+
+send_gdb "print (0 && (x <= y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x <= y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x <= y))" }
+ timeout { fail "(timeout) print value of (0 && (x <= y))" }
+ }
+
+
+
+send_gdb "print (0 && (x>y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x>y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x>y))" }
+ timeout { fail "(timeout) print value of (0 && (x>y))" }
+ }
+
+
+send_gdb "print (0 && (x>=y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x>=y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x>=y))" }
+ timeout { fail "(timeout) print value of (0 && (x>=y))" }
+ }
+
+
+
+send_gdb "print (0 && (x==y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x==y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x==y))" }
+ timeout { fail "(timeout) print value of (0 && (x==y))" }
+ }
+
+
+send_gdb "print (0 && (x!=y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x!=y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x!=y))" }
+ timeout { fail "(timeout) print value of (0 && (x!=y))" }
+ }
+
+
+send_gdb "print (0 && (x<<31))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x<<31))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x<<31))" }
+ timeout { fail "(timeout) print value of (0 && (x<<31))" }
+ }
+
+
+send_gdb "print (0 && (x>>31))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x>>31))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x>>31))" }
+ timeout { fail "(timeout) print value of (0 && (x>>31))" }
+ }
+
+
+
+send_gdb "print (0 && (!x))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (!x))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (!x))" }
+ timeout { fail "(timeout) print value of (0 && (!x))" }
+ }
+
+
+send_gdb "print (0 && (~x))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (~x))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (~x))" }
+ timeout { fail "(timeout) print value of (0 && (~x))" }
+ }
+
+send_gdb "print (0 && (-x))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (-x))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (-x))" }
+ timeout { fail "(timeout) print value of (0 && (-x))" }
+ }
+
+
+send_gdb "print (0 && (x++))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x++))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x++))" }
+ timeout { fail "(timeout) print value of (0 && (x++))" }
+ }
+
+
+send_gdb "print (0 && (++x))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (++x))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (++x))" }
+ timeout { fail "(timeout) print value of (0 && (++x))" }
+ }
+
+
+send_gdb "print (0 && (x--))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x--))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x--))" }
+ timeout { fail "(timeout) print value of (0 && (x--))" }
+ }
+
+
+send_gdb "print (0 && (--x))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (--x))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (--x))" }
+ timeout { fail "(timeout) print value of (0 && (--x))" }
+ }
+
+send_gdb "print (0 && (x+=7))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x+=7))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x+=7))" }
+ timeout { fail "(timeout) print value of (0 && (x+=7))" }
+ }
+
+send_gdb "print (0 && (x=y))\n"
+gdb_expect {
+ -re ".$decimal = $false\r\n$gdb_prompt $" {
+ pass "print value of (0 && (x=y))"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (0 && (x=y))" }
+ timeout { fail "(timeout) print value of (0 && (x=y))" }
+ }
+
+gdb_exit
+return 0
+
+
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.base/execd-prog.c b/gdb/testsuite/gdb.base/execd-prog.c
new file mode 100644
index 00000000000..5469f656c0c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/execd-prog.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* There is a global_i in foll-exec, which exec's us. We
+ should not be able to see that other definition of global_i
+ after we are exec'd.
+ */
+int global_i = 0;
+
+#ifdef PROTOTYPES
+int main (int argc, char **argv)
+#else
+main (argc, argv)
+ int argc;
+ char * argv[];
+#endif
+{
+ /* There is a local_j in foll-exec, which exec's us. We
+ should not be able to see that other definition of local_j
+ after we are exec'd.
+ */
+ int local_j = argc;
+ char * s;
+
+ printf ("Hello from execd-prog...\n");
+ if (argc != 2)
+ {
+ printf ("expected one string argument\n");
+ exit (-1);
+ }
+ s = argv[1];
+ printf ("argument received: %s\n", s);
+}
diff --git a/gdb/testsuite/gdb.base/exprs.c b/gdb/testsuite/gdb.base/exprs.c
new file mode 100644
index 00000000000..b35c3a58d25
--- /dev/null
+++ b/gdb/testsuite/gdb.base/exprs.c
@@ -0,0 +1,254 @@
+#ifdef PROTOTYPES
+int main (int argc, char **argv, char **envp)
+#else
+main (argc, argv, envp)
+ int argc;
+ char **argv;
+ char **envp;
+#endif
+{
+ extern void dummy();
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ dummy();
+ return 0;
+
+}
+
+/* We put main() right up front so its line number doesn't keep changing. */
+
+/*
+ * Test file with lots of different types, for testing the
+ * "whatis" command.
+ */
+
+/*
+ * First the basic C types.
+ */
+
+#if !defined (__STDC__) && !defined (_AIX)
+#define signed /**/
+#endif
+
+char v_char;
+signed char v_signed_char;
+unsigned char v_unsigned_char;
+
+short v_short;
+signed short v_signed_short;
+unsigned short v_unsigned_short;
+
+int v_int;
+signed int v_signed_int;
+unsigned int v_unsigned_int;
+
+long v_long;
+signed long v_signed_long;
+unsigned long v_unsigned_long;
+
+float v_float;
+double v_double;
+/*
+ * Now some derived types, which are arrays, functions-returning,
+ * pointers, structures, unions, and enumerations.
+ */
+
+/**** arrays *******/
+
+char v_char_array[2];
+signed char v_signed_char_array[2];
+unsigned char v_unsigned_char_array[2];
+
+short v_short_array[2];
+signed short v_signed_short_array[2];
+unsigned short v_unsigned_short_array[2];
+
+int v_int_array[2];
+signed int v_signed_int_array[2];
+unsigned int v_unsigned_int_array[2];
+
+long v_long_array[2];
+signed long v_signed_long_array[2];
+unsigned long v_unsigned_long_array[2];
+
+float v_float_array[2];
+double v_double_array[2];
+/**** pointers *******/
+
+char *v_char_pointer;
+signed char *v_signed_char_pointer;
+unsigned char *v_unsigned_char_pointer;
+
+short *v_short_pointer;
+signed short *v_signed_short_pointer;
+unsigned short *v_unsigned_short_pointer;
+
+int *v_int_pointer;
+signed int *v_signed_int_pointer;
+unsigned int *v_unsigned_int_pointer;
+
+long *v_long_pointer;
+signed long *v_signed_long_pointer;
+unsigned long *v_unsigned_long_pointer;
+
+float *v_float_pointer;
+double *v_double_pointer;
+
+/**** structs *******/
+
+struct t_struct {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_struct1;
+
+struct {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_struct2;
+
+/**** unions *******/
+
+union t_union {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_union;
+
+union {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_union2;
+
+/*** Functions returning type ********/
+
+char v_char_func () { return(0); }
+signed char v_signed_char_func () { return (0); }
+unsigned char v_unsigned_char_func () { return (0); }
+
+short v_short_func () { return (0); }
+signed short v_signed_short_func () { return (0); }
+unsigned short v_unsigned_short_func () { return (0); }
+
+int v_int_func () { return (0); }
+signed int v_signed_int_func () { return (0); }
+unsigned int v_unsigned_int_func () { return (0); }
+
+long v_long_func () { return (0); }
+signed long v_signed_long_func () { return (0); }
+unsigned long v_unsigned_long_func () { return (0); }
+
+float v_float_func () { return (0.0); }
+double v_double_func () { return (0.0); }
+
+/**** Some misc more complicated things *******/
+
+struct link {
+ struct link *next;
+#ifdef __STDC__
+ struct link *(*linkfunc) (struct link *this, int flags);
+#else
+ struct link *(*linkfunc) ();
+#endif
+ struct t_struct stuff[1][2][3];
+} *s_link;
+
+union tu_link {
+ struct link *next;
+#ifdef __STDC__
+ struct link *(*linkfunc) (struct link *this, int flags);
+#else
+ struct link *(*linkfunc) ();
+#endif
+ struct t_struct stuff[1][2][3];
+} u_link;
+
+/**** Enumerations *******/
+
+enum colors {red, green, blue} color;
+enum cars {chevy, ford, porsche} clunker;
+
+
+void dummy()
+{
+ /* Some linkers (e.g. on AIX) remove unreferenced variables,
+ so make sure to reference them. */
+ v_char = 0;
+ v_signed_char = 1;
+ v_unsigned_char = 2;
+
+ v_short = 3;
+ v_signed_short = 4;
+ v_unsigned_short = 5;
+
+ v_int = 6;
+ v_signed_int = 7;
+ v_unsigned_int = 8;
+
+ v_long = 9;
+ v_signed_long = 10;
+ v_unsigned_long = 11;
+
+ v_float = 100.0;
+ v_double = 200.0;
+ v_char_array[0] = v_char;
+ v_signed_char_array[0] = v_signed_char;
+ v_unsigned_char_array[0] = v_unsigned_char;
+
+ v_short_array[0] = v_short;
+ v_signed_short_array[0] = v_signed_short;
+ v_unsigned_short_array[0] = v_unsigned_short;
+
+ v_int_array[0] = v_int;
+ v_signed_int_array[0] = v_signed_int;
+ v_unsigned_int_array[0] = v_unsigned_int;
+
+ v_long_array[0] = v_long;
+ v_signed_long_array[0] = v_signed_long;
+ v_unsigned_long_array[0] = v_unsigned_long;
+
+ v_float_array[0] = v_float;
+ v_double_array[0] = v_double;
+ v_char_pointer = &v_char;
+ v_signed_char_pointer = &v_signed_char;
+ v_unsigned_char_pointer = &v_unsigned_char;
+
+ v_short_pointer = &v_short;
+ v_signed_short_pointer = &v_signed_short;
+ v_unsigned_short_pointer = &v_unsigned_short;
+
+ v_int_pointer = &v_int;
+ v_signed_int_pointer = &v_signed_int;
+ v_unsigned_int_pointer = &v_unsigned_int;
+
+ v_long_pointer = &v_long;
+ v_signed_long_pointer = &v_signed_long;
+ v_unsigned_long_pointer = &v_unsigned_long;
+
+ v_float_pointer = &v_float;
+ v_double_pointer = &v_double;
+
+ color = red;
+ clunker = porsche;
+
+ u_link.next = s_link;
+
+ v_struct2.v_int_member = v_struct1.v_int_member;
+ v_union2.v_short_member = v_union.v_short_member;
+}
diff --git a/gdb/testsuite/gdb.base/exprs.exp b/gdb/testsuite/gdb.base/exprs.exp
new file mode 100644
index 00000000000..49df15a2f60
--- /dev/null
+++ b/gdb/testsuite/gdb.base/exprs.exp
@@ -0,0 +1,259 @@
+# Copyright 1988, 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 2000, 2001
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "exprs"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+proc test_expr { args } {
+ if { [llength $args] % 2 } {
+ warning "an even # of arguments should be passed to test_expr"
+ }
+ set last_ent [expr [llength $args] - 1];
+ set testname [lindex $args $last_ent];
+ if [gdb_test [lindex $args 0] "" "$testname (setup)"] {
+ gdb_suppress_tests;
+ }
+ for {set x 1} {$x < $last_ent} {set x [expr $x + 2]} {
+ if [gdb_test [lindex $args $x] [lindex $args [expr $x + 1]] "$testname ([lindex $args $x])"] {
+ gdb_suppress_tests;
+ }
+ }
+ gdb_stop_suppressing_tests;
+}
+#
+# test expressions with "char" types
+#
+test_expr "set variable v_char=127" "print v_char == 0" "\\$\[0-9\]* = $false" "print v_char == 127" "\\$\[0-9\]* = $true" "print char =="
+test_expr "set variable v_char=127" "print v_char != 0" "\\$\[0-9\]* = $true" "print v_char != 127" "\\$\[0-9\]* = $false" "print char !="
+test_expr "set variable v_char=127" "print v_char < 0" "\\$\[0-9\]* = $false" "print v_char < 127" "\\$\[0-9\]* = $false" "print char <"
+test_expr "set variable v_char=127" "print v_char > 0" "\\$\[0-9\]* = $true" "print v_char > 127" "\\$\[0-9\]* = $false" "print char >"
+#
+# test expressions with "signed char" types
+#
+test_expr "set variable v_signed_char=127" "print v_signed_char == 0" "\\$\[0-9\]* = $false" "print v_signed_char == 127" "\\$\[0-9\]* = $true" "print signed char =="
+test_expr "set variable v_signed_char=127" "print v_signed_char != 0" "\\$\[0-9\]* = $true" "print v_signed_char != 127" "\\$\[0-9\]* = $false" "print signed char !="
+test_expr "set variable v_signed_char=127" "print v_signed_char < 0" "\\$\[0-9\]* = $false" "print v_signed_char < 127" "\\$\[0-9\]* = $false" "print signed char <"
+test_expr "set variable v_signed_char=127" "print v_signed_char > 0" "\\$\[0-9\]* = $true" "print v_signed_char > 127" "\\$\[0-9\]* = $false" "print signed char >"
+# make char a minus
+test_expr "set variable v_signed_char=-1" "print v_signed_char == 0" "\\$\[0-9\]* = $false" "print v_signed_char == -1" "\\$\[0-9\]* = $true" "print signed char == (minus)"
+test_expr "set variable v_signed_char=-1" "print v_signed_char != 0" "\\$\[0-9\]* = $true" "print v_signed_char != -1" "\\$\[0-9\]* = $false" "print signed char != (minus)"
+test_expr "set variable v_signed_char=-1" "print v_signed_char < 0" "\\$\[0-9\]* = $true" "print v_signed_char < 127" "\\$\[0-9\]* = $true" "print signed char < (minus)"
+test_expr "set variable v_signed_char=-1" "print v_signed_char > 0" "\\$\[0-9\]* = $false" "print v_signed_char > 127" "\\$\[0-9\]* = $false" "print signed char > (minus)"
+#
+# test expressions with "unsigned char" types
+#
+test_expr "set variable v_unsigned_char=127" "print v_unsigned_char == 0" "\\$\[0-9\]* = $false" "print v_unsigned_char == 127" "\\$\[0-9\]* = $true" "print unsigned char =="
+test_expr "set variable v_unsigned_char=127" "print v_unsigned_char != 0" "\\$\[0-9\]* = $true" "print v_unsigned_char != 127" "\\$\[0-9\]* = $false" "print unsigned char !="
+test_expr "set variable v_unsigned_char=127" "print v_unsigned_char < 0" "\\$\[0-9\]* = $false" "print v_unsigned_char < 127" "\\$\[0-9\]* = $false" "print unsigned char <"
+test_expr "set variable v_unsigned_char=127" "print v_unsigned_char > 0" "\\$\[0-9\]* = $true" "print v_unsigned_char > 127" "\\$\[0-9\]* = $false" "print unsigned char >"
+# make char a minus
+# FIXME: gdb mishandles the cast (unsigned char) on the i960, so I've
+# set up an expected failure for this case.
+setup_xfail "i960-*-*" 1821
+test_expr "set variable v_unsigned_char=~0" "print v_unsigned_char == 0" "\\$\[0-9\]* = $false" "print v_unsigned_char == ~0" "\\$\[0-9\]* = $false" "print v_unsigned_char == (unsigned char)~0" "\\$\[0-9\]* = $true" "print unsigned char == (~0)"
+# FIXME: gdb mishandles the cast (unsigned char) on the i960, so I've
+# set up an expected failure for this case.
+setup_xfail "i960-*-*" 1821
+test_expr "set variable v_unsigned_char=~0" "print v_unsigned_char != 0" "\\$\[0-9\]* = $true" "print v_unsigned_char != (unsigned char)~0" "\\$\[0-9\]* = $false" "print v_unsigned_char != ~0" "\\$\[0-9\]* = $true" "print unsigned char != (~0)"
+test_expr "set variable v_unsigned_char=~0" "print v_unsigned_char < 0" "\\$\[0-9\]* = $false" "print v_unsigned_char < 127" "\\$\[0-9\]* = $false" "print unsigned char < (~0)"
+test_expr "set variable v_unsigned_char=~0" "print v_unsigned_char > 0" "\\$\[0-9\]* = $true" "print v_unsigned_char > 127" "\\$\[0-9\]* = $true" "print unsigned char > (~0)"
+#
+# test expressions with "short" types
+#
+test_expr "set variable v_short=0x7FFF" "print v_short == 0" "\\$\[0-9\]* = $false" "print v_short == 0x7FFF" "\\$\[0-9\]* = $true" "print signed short =="
+test_expr "set variable v_short=0x7FFF" "print v_short != 0" "\\$\[0-9\]* = $true" "print v_short != 0x7FFF" "\\$\[0-9\]* = $false" "print signed short !="
+test_expr "set variable v_short=0x7FFF" "print v_short < 0" "\\$\[0-9\]* = $false" "print v_short < 0x7FFF" "\\$\[0-9\]* = $false" "print signed short <"
+test_expr "set variable v_short=0x7FFF" "print v_short > 0" "\\$\[0-9\]* = $true" "print v_short > 0x7FFF" "\\$\[0-9\]* = $false" "print signed short >"
+# make short a minus
+test_expr "set variable v_short=-1" "print v_short == 0" "\\$\[0-9\]* = $false" "print v_short == -1" "\\$\[0-9\]* = $true" "print signed short == (minus)"
+test_expr "set variable v_short=-1" "print v_short != 0" "\\$\[0-9\]* = $true" "print v_short != -1" "\\$\[0-9\]* = $false" "print signed short != (minus)"
+test_expr "set variable v_short=-1" "print v_short < 0" "\\$\[0-9\]* = $true" "print v_short < 0x7FFF" "\\$\[0-9\]* = $true" "print signed short < (minus)"
+test_expr "set variable v_short=-1" "print v_short > 0" "\\$\[0-9\]* = $false" "print v_short > 0x7FFF" "\\$\[0-9\]* = $false" "print signed short > (minus)"
+#
+# test expressions with "signed short" types
+#
+test_expr "set variable v_signed_short=0x7FFF" "print v_signed_short == 0" "\\$\[0-9\]* = $false" "print v_signed_short == 0x7FFF" "\\$\[0-9\]* = $true" "print signed signed short =="
+test_expr "set variable v_signed_short=0x7FFF" "print v_signed_short != 0" "\\$\[0-9\]* = $true" "print v_signed_short != 0x7FFF" "\\$\[0-9\]* = $false" "print signed signed short !="
+test_expr "set variable v_signed_short=0x7FFF" "print v_signed_short < 0" "\\$\[0-9\]* = $false" "print v_signed_short < 0x7FFF" "\\$\[0-9\]* = $false" "print signed signed short <"
+test_expr "set variable v_signed_short=0x7FFF" "print v_signed_short > 0" "\\$\[0-9\]* = $true" "print v_signed_short > 0x7FFF" "\\$\[0-9\]* = $false" "print signed signed short >"
+# make short a minus
+test_expr "set variable v_signed_short=-1" "print v_signed_short == 0" "\\$\[0-9\]* = $false" "print v_signed_short == -1" "\\$\[0-9\]* = $true" "print signed signed short == (minus)"
+test_expr "set variable v_signed_short=-1" "print v_signed_short != 0" "\\$\[0-9\]* = $true" "print v_signed_short != -1" "\\$\[0-9\]* = $false" "print signed signed short != (minus)"
+test_expr "set variable v_signed_short=-1" "print v_signed_short < 0" "\\$\[0-9\]* = $true" "print v_signed_short < 0x7FFF" "\\$\[0-9\]* = $true" "print signed signed short < (minus)"
+test_expr "set variable v_signed_short=-1" "print v_signed_short > 0" "\\$\[0-9\]* = $false" "print v_signed_short > 0x7FFF" "\\$\[0-9\]* = $false" "print signed signed short > (minus)"
+#
+# test expressions with "unsigned short" types
+#
+test_expr "set variable v_unsigned_short=0x7FFF" "print v_unsigned_short == 0" "\\$\[0-9\]* = $false" "print v_unsigned_short == 0x7FFF" "\\$\[0-9\]* = $true" "print unsigned short =="
+test_expr "set variable v_unsigned_short=0x7FFF" "print v_unsigned_short != 0" "\\$\[0-9\]* = $true" "print v_unsigned_short != 0x7FFF" "\\$\[0-9\]* = $false" "print unsigned short !="
+test_expr "set variable v_unsigned_short=0x7FFF" "print v_unsigned_short < 0" "\\$\[0-9\]* = $false" "print v_unsigned_short < 0x7FFF" "\\$\[0-9\]* = $false" "print unsigned short <"
+test_expr "set variable v_unsigned_short=0x7FFF" "print v_unsigned_short > 0" "\\$\[0-9\]* = $true" "print v_unsigned_short > 0x7FFF" "\\$\[0-9\]* = $false" "print unsigned short >"
+# make short a minus
+test_expr "set variable v_unsigned_short=~0" "print v_unsigned_short == 0" "\\$\[0-9\]* = $false" "print sizeof (v_unsigned_short) < sizeof (~0) && v_unsigned_short == ~0" "\\$\[0-9\]* = $false" "print v_unsigned_short == (unsigned short)~0" "\\$\[0-9\]* = $true" "print unsigned short == (~0)"
+test_expr "set variable v_unsigned_short=~0" "print v_unsigned_short != 0" "\\$\[0-9\]* = $true" "print v_unsigned_short != (unsigned short)~0" "\\$\[0-9\]* = $false" "print unsigned short != (~0)"
+test_expr "set variable v_unsigned_short=~0" "print v_unsigned_short < 0" "\\$\[0-9\]* = $false" "print v_unsigned_short < 0x7FFF" "\\$\[0-9\]* = $false" "print unsigned short < (~0)"
+test_expr "set variable v_unsigned_short=~0" "print v_unsigned_short > 0" "\\$\[0-9\]* = $true" "print v_unsigned_short > 0x7FFF" "\\$\[0-9\]* = $true" "print unsigned short > (~0)"
+#
+# test expressions with "int" types
+#
+test_expr "set variable v_int=0x7FFF" "print v_int == 0" "\\$\[0-9\]* = $false" "print v_int == 0x7FFF" "\\$\[0-9\]* = $true" "print signed int =="
+test_expr "set variable v_int=0x7FFF" "print v_int != 0" "\\$\[0-9\]* = $true" "print v_int != 0x7FFF" "\\$\[0-9\]* = $false" "print signed int !="
+test_expr "set variable v_int=0x7FFF" "print v_int < 0" "\\$\[0-9\]* = $false" "print v_int < 0x7FFF" "\\$\[0-9\]* = $false" "print signed int <"
+test_expr "set variable v_int=0x7FFF" "print v_int > 0" "\\$\[0-9\]* = $true" "print v_int > 0x7FFF" "\\$\[0-9\]* = $false" "print signed int >"
+# make int a minus
+test_expr "set variable v_int=-1" "print v_int == 0" "\\$\[0-9\]* = $false" "print v_int == -1" "\\$\[0-9\]* = $true" "print signed int == (minus)"
+test_expr "set variable v_int=-1" "print v_int != 0" "\\$\[0-9\]* = $true" "print v_int != -1" "\\$\[0-9\]* = $false" "print signed int != (minus)"
+test_expr "set variable v_int=-1" "print v_int < 0" "\\$\[0-9\]* = $true" "print v_int < 0x7FFF" "\\$\[0-9\]* = $true" "print signed int < (minus)"
+test_expr "set variable v_int=-1" "print v_int > 0" "\\$\[0-9\]* = $false" "print v_int > 0x7FFF" "\\$\[0-9\]* = $false" "print signed int > (minus)"
+#
+# test expressions with "signed int" types
+#
+test_expr "set variable v_signed_int=0x7FFF" "print v_signed_int == 0" "\\$\[0-9\]* = $false" "print v_signed_int == 0x7FFF" "\\$\[0-9\]* = $true" "print signed signed int =="
+test_expr "set variable v_signed_int=0x7FFF" "print v_signed_int != 0" "\\$\[0-9\]* = $true" "print v_signed_int != 0x7FFF" "\\$\[0-9\]* = $false" "print signed signed int !="
+test_expr "set variable v_signed_int=0x7FFF" "print v_signed_int < 0" "\\$\[0-9\]* = $false" "print v_signed_int < 0x7FFF" "\\$\[0-9\]* = $false" "print signed signed int <"
+test_expr "set variable v_signed_int=0x7FFF" "print v_signed_int > 0" "\\$\[0-9\]* = $true" "print v_signed_int > 0x7FFF" "\\$\[0-9\]* = $false" "print signed signed int >"
+# make int a minus
+test_expr "set variable v_signed_int=-1" "print v_signed_int == 0" "\\$\[0-9\]* = $false" "print v_signed_int == -1" "\\$\[0-9\]* = $true" "print signed signed int == (minus)"
+test_expr "set variable v_signed_int=-1" "print v_signed_int != 0" "\\$\[0-9\]* = $true" "print v_signed_int != -1" "\\$\[0-9\]* = $false" "print signed signed int != (minus)"
+test_expr "set variable v_signed_int=-1" "print v_signed_int < 0" "\\$\[0-9\]* = $true" "print v_signed_int < 0x7FFF" "\\$\[0-9\]* = $true" "print signed signed int < (minus)"
+test_expr "set variable v_signed_int=-1" "print v_signed_int > 0" "\\$\[0-9\]* = $false" "print v_signed_int > 0x7FFF" "\\$\[0-9\]* = $false" "print signed signed int > (minus)"
+#
+# test expressions with "unsigned int" types
+#
+test_expr "set variable v_unsigned_int=0x7FFF" "print v_unsigned_int == 0" "\\$\[0-9\]* = $false" "print v_unsigned_int == 0x7FFF" "\\$\[0-9\]* = $true" "print unsigned int =="
+test_expr "set variable v_unsigned_int=0x7FFF" "print v_unsigned_int != 0" "\\$\[0-9\]* = $true" "print v_unsigned_int != 0x7FFF" "\\$\[0-9\]* = $false" "print unsigned int !="
+test_expr "set variable v_unsigned_int=0x7FFF" "print v_unsigned_int < 0" "\\$\[0-9\]* = $false" "print v_unsigned_int < 0x7FFF" "\\$\[0-9\]* = $false" "print unsigned int <"
+test_expr "set variable v_unsigned_int=0x7FFF" "print v_unsigned_int > 0" "\\$\[0-9\]* = $true" "print v_unsigned_int > 0x7FFF" "\\$\[0-9\]* = $false" "print unsigned int >"
+# make int a minus
+test_expr "set variable v_unsigned_int=~0" "print v_unsigned_int == 0" "\\$\[0-9\]* = $false" "print v_unsigned_int == ~0" "\\$\[0-9\]* = $true" "print v_unsigned_int == (unsigned int)~0" "\\$\[0-9\]* = $true" "print unsigned int == (~0)"
+test_expr "set variable v_unsigned_int=~0" "print v_unsigned_int != 0" "\\$\[0-9\]* = $true" "print v_unsigned_int != (unsigned int)~0" "\\$\[0-9\]* = $false" "print unsigned int != (~0)"
+test_expr "set variable v_unsigned_int=~0" "print v_unsigned_int < 0" "\\$\[0-9\]* = $false" "print v_unsigned_int < 0x7FFF" "\\$\[0-9\]* = $false" "print unsigned int < (~0)"
+test_expr "set variable v_unsigned_int=~0" "print v_unsigned_int > 0" "\\$\[0-9\]* = $true" "print v_unsigned_int > 0x7FFF" "\\$\[0-9\]* = $true" "print unsigned int > (~0)"
+#
+# test expressions with "long" types
+#
+test_expr "set variable v_long=0x7FFF" "print v_long == 0" "\\$\[0-9\]* = $false" "print v_long == 0x7FFF" "\\$\[0-9\]* = $true" "print signed long =="
+test_expr "set variable v_long=0x7FFF" "print v_long != 0" "\\$\[0-9\]* = $true" "print v_long != 0x7FFF" "\\$\[0-9\]* = $false" "print signed long !="
+test_expr "set variable v_long=0x7FFF" "print v_long < 0" "\\$\[0-9\]* = $false" "print v_long < 0x7FFF" "\\$\[0-9\]* = $false" "print signed long <"
+test_expr "set variable v_long=0x7FFF" "print v_long > 0" "\\$\[0-9\]* = $true" "print v_long > 0x7FFF" "\\$\[0-9\]* = $false" "print signed long >"
+# make long a minus
+test_expr "set variable v_long=-1" "print v_long == 0" "\\$\[0-9\]* = $false" "print v_long == -1" "\\$\[0-9\]* = $true" "print signed long == (minus)"
+test_expr "set variable v_long=-1" "print v_long != 0" "\\$\[0-9\]* = $true" "print v_long != -1" "\\$\[0-9\]* = $false" "print signed long != (minus)"
+test_expr "set variable v_long=-1" "print v_long < 0" "\\$\[0-9\]* = $true" "print v_long < 0x7FFF" "\\$\[0-9\]* = $true" "print signed long < (minus)"
+test_expr "set variable v_long=-1" "print v_long > 0" "\\$\[0-9\]* = $false" "print v_long > 0x7FFF" "\\$\[0-9\]* = $false" "print signed long > (minus)"
+#
+# test expressions with "signed long" types
+#
+test_expr "set variable v_signed_long=0x7FFF" "print v_signed_long == 0" "\\$\[0-9\]* = $false" "print v_signed_long == 0x7FFF" "\\$\[0-9\]* = $true" "print signed signed long =="
+test_expr "set variable v_signed_long=0x7FFF" "print v_signed_long != 0" "\\$\[0-9\]* = $true" "print v_signed_long != 0x7FFF" "\\$\[0-9\]* = $false" "print signed signed long !="
+test_expr "set variable v_signed_long=0x7FFF" "print v_signed_long < 0" "\\$\[0-9\]* = $false" "print v_signed_long < 0x7FFF" "\\$\[0-9\]* = $false" "print signed signed long <"
+test_expr "set variable v_signed_long=0x7FFF" "print v_signed_long > 0" "\\$\[0-9\]* = $true" "print v_signed_long > 0x7FFF" "\\$\[0-9\]* = $false" "print signed signed long >"
+# make long a minus
+test_expr "set variable v_signed_long=-1" "print v_signed_long == 0" "\\$\[0-9\]* = $false" "print v_signed_long == -1" "\\$\[0-9\]* = $true" "print signed signed long == (minus)"
+test_expr "set variable v_signed_long=-1" "print v_signed_long != 0" "\\$\[0-9\]* = $true" "print v_signed_long != -1" "\\$\[0-9\]* = $false" "print signed signed long != (minus)"
+test_expr "set variable v_signed_long=-1" "print v_signed_long < 0" "\\$\[0-9\]* = $true" "print v_signed_long < 0x7FFF" "\\$\[0-9\]* = $true" "print signed signed long < (minus)"
+test_expr "set variable v_signed_long=-1" "print v_signed_long > 0" "\\$\[0-9\]* = $false" "print v_signed_long > 0x7FFF" "\\$\[0-9\]* = $false" "print signed signed long > (minus)"
+#
+# test expressions with "unsigned long" types
+#
+test_expr "set variable v_unsigned_long=0x7FFF" "print v_unsigned_long == 0" "\\$\[0-9\]* = $false" "print v_unsigned_long == 0x7FFF" "\\$\[0-9\]* = $true" "print unsigned long =="
+test_expr "set variable v_unsigned_long=0x7FFF" "print v_unsigned_long != 0" "\\$\[0-9\]* = $true" "print v_unsigned_long != 0x7FFF" "\\$\[0-9\]* = $false" "print unsigned long !="
+test_expr "set variable v_unsigned_long=0x7FFF" "print v_unsigned_long < 0" "\\$\[0-9\]* = $false" "print v_unsigned_long < 0x7FFF" "\\$\[0-9\]* = $false" "print unsigned long <"
+test_expr "set variable v_unsigned_long=0x7FFF" "print v_unsigned_long > 0" "\\$\[0-9\]* = $true" "print v_unsigned_long > 0x7FFF" "\\$\[0-9\]* = $false" "print unsigned long >"
+# make long a minus
+test_expr "set variable v_unsigned_long=~0" "print v_unsigned_long == 0" "\\$\[0-9\]* = $false" "print v_unsigned_long == ~0" "\\$\[0-9\]* = $true" "print v_unsigned_long == (unsigned long)~0" "\\$\[0-9\]* = $true" "print unsigned long == (~0)"
+test_expr "set variable v_unsigned_long=~0" "print v_unsigned_long != 0" "\\$\[0-9\]* = $true" "print v_unsigned_long != (unsigned long)~0" "\\$\[0-9\]* = $false" "print unsigned long != (~0)"
+test_expr "set variable v_unsigned_long=~0" "print v_unsigned_long < 0" "\\$\[0-9\]* = $false" "print v_unsigned_long < 0x7FFF" "\\$\[0-9\]* = $false" "print unsigned long < (~0)"
+test_expr "set variable v_unsigned_long=~0" "print v_unsigned_long > 0" "\\$\[0-9\]* = $true" "print v_unsigned_long > 0x7FFF" "\\$\[0-9\]* = $true" "print unsigned long > (~0)"
+#
+# Test expressions with casts to a pointer.
+# NB: Some architectures convert a ``NULL'' pointer into
+# something else. Don't simply test for 0.
+#
+test_expr "set variable v_signed_char = 0" "print (void*)v_signed_char" "\\$\[0-9\]* = .void \\*. $hex" "print (void*)v_signed_char"
+test_expr "set variable v_signed_short = 0" "print (void*)v_signed_short" "\\$\[0-9\]* = .void \\*. $hex" "print (void*)v_signed_short"
+test_expr "set variable v_signed_int = 0" "print (void*)v_signed_int" "\\$\[0-9\]* = .void \\*. $hex" "print (void*)v_signed_int"
+test_expr "set variable v_signed_long = 0" "print (void*)v_signed_long" "\\$\[0-9\]* = .void \\*. $hex" "print (void*)v_signed_long"
+test_expr "set variable v_unsigned_char = 0" "print (void*)v_unsigned_char" "\\$\[0-9\]* = .void \\*. $hex" "print (void*)v_unsigned_char"
+test_expr "set variable v_unsigned_short = 0" "print (void*)v_unsigned_short" "\\$\[0-9\]* = .void \\*. $hex" "print (void*)v_unsigned_short"
+test_expr "set variable v_unsigned_int = 0" "print (void*)v_unsigned_int" "\\$\[0-9\]* = .void \\*. $hex" "print (void*)v_unsigned_int"
+test_expr "set variable v_unsigned_long = 0" "print (void*)v_unsigned_long" "\\$\[0-9\]* = .void \\*. $hex" "print (void*)v_unsigned_long"
+#
+# Test expressions with pointers out of range
+#
+# NB: For some architectures, all of sizeof(long),
+# sizeof(long long) and sizeof(void*) are
+# the same size so this test can not work.
+#
+send_gdb "print sizeof (long long) > sizeof (long)\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = $true.*$gdb_prompt" {
+ set ok 1
+ pass "sizeof (long long) > sizeof (long) (true)"
+ }
+ -re "\\$\[0-9\]* = $false.*$gdb_prompt" {
+ set ok 0
+ pass "sizeof (long long) > sizeof (long) (false)"
+ }
+ timeout {
+ set ok 0
+ fail "sizeof (long long) > sizeof (long) (timeout)"
+ }
+}
+if [expr ! $ok] { setup_xfail "*-*-*" }
+gdb_test "print (void*) ((long long) (unsigned long) -1 + 1)" \
+ "warning: value truncated.*" "truncate (void*) 0x00000000ffffffff + 1"
+if [expr ! $ok] { setup_xfail "*-*-*" }
+gdb_test "print (void*) (~((long long)(unsigned long) -1) - 1)" \
+ "warning: value truncated.*" "truncate (void*) 0xffffffff00000000 - 1"
diff --git a/gdb/testsuite/gdb.base/finish.exp b/gdb/testsuite/gdb.base/finish.exp
new file mode 100644
index 00000000000..064f26e39dc
--- /dev/null
+++ b/gdb/testsuite/gdb.base/finish.exp
@@ -0,0 +1,125 @@
+# Copyright 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@redhat.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# re-use the program from the "return2" test.
+set testfile "return2"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+proc finish_1 { type } {
+ global gdb_prompt
+
+ gdb_test "break ${type}_func" "Breakpoint \[0123456789\].*" \
+ "set break on ${type}_func"
+ gdb_test "continue" "Breakpoint.* ${type}_func.*" \
+ "continue to ${type}_func"
+ send_gdb "finish\n"
+ gdb_expect {
+ -re ".*Value returned is .* = 49 '1'\r\n$gdb_prompt $" {
+ if { $type == "char" } {
+ pass "finish from char_func"
+ } else {
+ fail "finish from ${type}_func"
+ }
+ }
+ -re ".*Value returned is .* = \[0123456789\]* '1'\r\n$gdb_prompt $" {
+ if { $type == "char" } {
+ pass "finish from char_func (non-ASCII char set?)"
+ } else {
+ fail "finish from ${type}_func"
+ }
+ }
+ -re ".*Value returned is .* = 1\r\n$gdb_prompt $" {
+ pass "finish from ${type}_func"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "finish from ${type}_func"
+ }
+ timeout {
+ fail "finish from ${type}_func (timeout)"
+ }
+ }
+}
+
+proc finish_void { } {
+ global gdb_prompt
+
+ gdb_test "break void_func" "Breakpoint \[0123456789\].*" \
+ "set break on void_func"
+ gdb_test "continue" "Breakpoint.* void_func.*" \
+ "continue to void_func"
+ send_gdb "finish\n"
+ # Some architectures will have one or more instructions after the
+ # call instruction which still is part of the call sequence, so we
+ # must be prepared for a "finish" to show us the void_func call
+ # again as well as the statement after.
+ gdb_expect {
+ -re ".*void_checkpoint.*$gdb_prompt $" {
+ pass "finish from void_func"
+ }
+ -re "0x\[0-9a-fA-F\]+ in main.*call to void_func.*$gdb_prompt $" {
+ pass "finish from void_func"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "finish from void_func"
+ }
+ timeout {
+ fail "finish from void_func (timeout)"
+ }
+ }
+}
+
+proc finish_tests { } {
+ global gdb_prompt
+
+ if { ! [ runto main ] } then {
+ gdb_suppress_entire_file "Run to main failed, so all tests in this file will automatically fail."
+ }
+
+ finish_void
+ finish_1 "char"
+ finish_1 "short"
+ finish_1 "int"
+ finish_1 "long"
+ finish_1 "long_long"
+ finish_1 "float"
+ finish_1 "double"
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set timeout 30
+finish_tests
diff --git a/gdb/testsuite/gdb.base/foll-exec.c b/gdb/testsuite/gdb.base/foll-exec.c
new file mode 100644
index 00000000000..1b760903dd7
--- /dev/null
+++ b/gdb/testsuite/gdb.base/foll-exec.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+
+int global_i = 100;
+
+#ifdef PROTOTYPES
+int main (void)
+#else
+main ()
+#endif
+{
+ int local_j = global_i+1;
+ int local_k = local_j+1;
+
+ printf ("foll-exec is about to execlp(execd-prog)...\n");
+
+ execlp ("gdb.base/execd-prog",
+ "gdb.base/execd-prog",
+ "execlp arg1 from foll-exec",
+ (char *)0);
+
+ printf ("foll-exec is about to execl(execd-prog)...\n");
+
+ execl ("gdb.base/execd-prog",
+ "gdb.base/execd-prog",
+ "execl arg1 from foll-exec",
+ "execl arg2 from foll-exec",
+ (char *)0);
+
+ {
+ static char * argv[] = {
+ (char *)"gdb.base/execd-prog",
+ (char *)"execv arg1 from foll-exec",
+ (char *)0};
+
+ printf ("foll-exec is about to execv(execd-prog)...\n");
+
+ execv ("gdb.base/execd-prog", argv);
+ }
+}
diff --git a/gdb/testsuite/gdb.base/foll-exec.exp b/gdb/testsuite/gdb.base/foll-exec.exp
new file mode 100644
index 00000000000..482a0df3c3d
--- /dev/null
+++ b/gdb/testsuite/gdb.base/foll-exec.exp
@@ -0,0 +1,400 @@
+# Copyright 1997, 1999 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+if { ![isnative] } then {
+ continue
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "foll-exec"
+set testfile2 "execd-prog"
+set srcfile ${testfile}.c
+set srcfile2 ${testfile2}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set binfile2 ${objdir}/${subdir}/${testfile2}
+
+# build the first test case
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+# Until "catch exec" is implemented on other targets...
+#
+if ![istarget "hppa*-hp-hpux*"] then {
+ continue
+}
+
+proc zap_session {} {
+ global gdb_prompt
+ global binfile
+
+ send_gdb "kill\n"
+ gdb_expect {
+ -re ".*Kill the program being debugged.*y or n. $" {
+ send_gdb "y\n"
+ send_gdb "file $binfile\n"
+ gdb_expect {
+ -re ".*Load new symbol table from.*y or n. $" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "Reading symbols from.*$gdb_prompt $" {}
+ timeout { fail "loading symbols (timeout)"; return }
+ }
+ }
+ -re ".*gdb_prompt $" {}
+ timeout { fail "loading symbols (timeout)"; return }
+ }
+ }
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "killing inferior (timeout)" ; return }
+ }
+}
+
+proc do_exec_tests {} {
+ global gdb_prompt
+ global binfile
+ global srcfile
+ global srcfile2
+ global testfile
+ global testfile2
+
+ # Start the program running, and stop at main.
+ #
+ if ![runto_main] then {
+ perror "Couldn't run ${testfile}"
+ return
+ }
+
+ # Verify that we can see various global and local variables
+ # in this program, and that they have expected values. Some
+ # of these variables are also declared in the program we'll
+ # exec in a moment.
+ #
+ send_gdb "next 3\n"
+ gdb_expect {
+ -re "20.*execlp.*$gdb_prompt $"\
+ {pass "step to exec call"}
+ -re "$gdb_prompt $" {fail "step to exec call"}
+ timeout {fail "(timeout) step to exec call"}
+ }
+ send_gdb "print global_i\n"
+ gdb_expect {
+ -re ".* = 100.*$gdb_prompt $"\
+ {pass "print follow-exec/global_i"}
+ -re "$gdb_prompt $" {fail "print follow-exec/global_i"}
+ timeout {fail "(timeout) print follow-exec/global_i"}
+ }
+ send_gdb "print local_j\n"
+ gdb_expect {
+ -re ".* = 101.*$gdb_prompt $"\
+ {pass "print follow-exec/local_j"}
+ -re "$gdb_prompt $" {fail "print follow-exec/local_j"}
+ timeout {fail "(timeout) print follow-exec/local_j"}
+ }
+ send_gdb "print local_k\n"
+ gdb_expect {
+ -re ".* = 102.*$gdb_prompt $"\
+ {pass "print follow-exec/local_k"}
+ -re "$gdb_prompt $" {fail "print follow-exec/local_k"}
+ timeout {fail "(timeout) print follow-exec/local_k"}
+ }
+
+ # Try stepping through an execlp call, without catching it.
+ # We should stop in execd-program, at its first statement.
+ #
+ send_gdb "next\n"
+ gdb_expect {
+ -re "Executing new program: .*${testfile2}.*${srcfile2}:23.*int local_j = argc;.*$gdb_prompt $"\
+ {pass "step through execlp call"}
+ -re "$gdb_prompt $" {fail "step through execlp call"}
+ timeout {fail "(timeout) step through execlp call"}
+ }
+
+ # Verify that we can see the variables defined in the newly-exec'd
+ # program, and CANNOT see those defined in the exec'ing program.
+ #
+ send_gdb "next\n"
+ gdb_expect {
+ -re "26.*printf.*$gdb_prompt $"\
+ {pass "step after execlp call"}
+ -re "$gdb_prompt $" {fail "step after execlp call"}
+ timeout {fail "(timeout) step after execlp call"}
+ }
+ send_gdb "print global_i\n"
+ gdb_expect {
+ -re ".* = 0.*$gdb_prompt $"\
+ {pass "print execd-program/global_i (after execlp)"}
+ -re "$gdb_prompt $" {fail "print execd-program/global_i (after execlp)"}
+ timeout {fail "(timeout) print execd-program/global_i (after execlp)"}
+ }
+ send_gdb "print local_j\n"
+ gdb_expect {
+ -re ".* = 2.*$gdb_prompt $"\
+ {pass "print execd-program/local_j (after execlp)"}
+ -re "$gdb_prompt $" {fail "print execd-program/local_j (after execlp)"}
+ timeout {fail "(timeout) print execd-program/local_j (after execlp)"}
+ }
+ send_gdb "print local_k\n"
+ gdb_expect {
+ -re "No symbol \"local_k\" in current context.*$gdb_prompt $"\
+ {pass "print follow-exec/local_k (after execlp)"}
+ -re "$gdb_prompt $" {fail "print follow-exec/local_k (after execlp)"}
+ timeout {fail "(timeout) print follow-exec/local_k (after execlp)"}
+ }
+
+ # Explicitly kill this program, or a subsequent rerun actually runs
+ # the exec'd program, not the original program...
+ zap_session
+
+ # Start the program running, and stop at main.
+ #
+ if ![runto_main] then {
+ perror "Couldn't run ${testfile} (2nd try)"
+ return
+ }
+
+ # Verify that we can catch an exec event, and then continue
+ # to follow through the exec. (Since there's a breakpoint on
+ # "main", it'll also be transferred to the exec'd program,
+ # and we expect to stop there.)
+ #
+ send_gdb "catch exec\n"
+ gdb_expect {
+ -re "Catchpoint .*(exec).*$gdb_prompt $"\
+ {pass "set catch exec"}
+ -re "$gdb_prompt $" {fail "set catch exec"}
+ timeout {fail "(timeout) set catch exec"}
+ }
+
+ # Verify that the catchpoint is mentioned in an "info breakpoints",
+ # and further that the catchpoint mentions no program name.
+ #
+ send_gdb "info breakpoints\n"
+ gdb_expect {
+ -re ".*catch exec.*keep y.*$gdb_prompt $"\
+ {pass "info shows catchpoint without exec pathname"}
+ -re ".*catch exec.*program \"\".*$gdb_prompt $"\
+ {fail "info shows catchpoint without exec pathname"}
+ -re "$gdb_prompt $" {fail "info shows catchpoint without exec pathname"}
+ timeout {fail "(timeout) info shows catchpoint without exec pathname"}
+ }
+
+ # DTS CLLbs16760
+ # PA64 doesn't know about $START$ in dld.sl at this point. It should.
+ # - Michael Coulter
+ setup_xfail hppa2.0w-hp-hpux* CLLbs16760
+ send_gdb "continue\n"
+ gdb_expect {
+ -re ".*Executing new program:.*${testfile2}.*Catchpoint .*(exec\'d .*${testfile2}).*in .START..*$gdb_prompt $"\
+ {pass "hit catch exec"}
+ -re "$gdb_prompt $" {fail "hit catch exec"}
+ timeout {fail "(timeout) hit catch exec"}
+ }
+
+ # DTS CLLbs16760
+ # test gets out of sync if previous test fails.
+ gdb_test "bt" ".*" "sync up after possible failure 1"
+ gdb_test "bt" "#0.*" "sync up after possible failure 2"
+
+ # Verify that the catchpoint is mentioned in an "info breakpoints",
+ # and further that the catchpoint managed to capture the exec'd
+ # program's name.
+ #
+ send_gdb "info breakpoints\n"
+ gdb_expect {
+ -re ".*catch exec .*program \".*${testfile2}\".*$gdb_prompt $"\
+ {pass "info shows catchpoint exec pathname"}
+ -re "$gdb_prompt $" {fail "info shows catchpoint exec pathname"}
+ timeout {fail "(timeout) info shows catchpoint exec pathname"}
+ }
+
+ # Verify that we can continue from the catchpoint, and land in the
+ # main of the newly-exec'd program.
+ #
+ send_gdb "continue\n"
+ gdb_expect {
+ -re ".*${srcfile2}:23.*$gdb_prompt $"\
+ {pass "continue after hit catch exec"}
+ -re "$gdb_prompt $" {fail "continue after hit catch exec"}
+ timeout {fail "(timeout) continue after hit catch exec"}
+ }
+
+ # Explicitly kill this program, or a subsequent rerun actually runs
+ # the exec'd program, not the original program...
+ zap_session
+
+ # Start the program running, and stop at main.
+ #
+ if ![runto_main] then {
+ perror "Couldn't run ${testfile} (3rd try)"
+ return
+ }
+
+ # Verify that we can follow through follow an execl()
+ # call. (We must jump around earlier exec* calls.)
+ #
+ send_gdb "tbreak 27\n"
+ gdb_expect {
+ -re "Breakpoint .*file .*${srcfile}, line 27.*$gdb_prompt $"\
+ {pass "prepare to jump to execl call"}
+ -re "$gdb_prompt $" {fail "prepare to jump to execl call"}
+ timeout {fail "(timeout) prepare to jump to execl call"}
+ }
+ send_gdb "jump 27\n"
+ gdb_expect {
+ -re "main.* at .*${srcfile}:27.*$gdb_prompt $"\
+ {pass "jump to execl call"}
+ -re "$gdb_prompt $" {fail "jump to execl call"}
+ timeout {fail "(timeout) jump to execl call"}
+ }
+ # Note that stepping through an exec call causes the step-count
+ # to be reset to zero. I.e.: you may specify "next 2" at the
+ # call, but you'll actually stop at the first breakpoint set in
+ # the newly-exec'd program, not after the remaining step-count
+ # reaches zero.
+ #
+ send_gdb "next 2\n"
+ gdb_expect {
+ -re "Executing new program: .*${testfile2}.*${srcfile2}:23.*int local_j = argc;.*$gdb_prompt $"\
+ {pass "step through execl call"}
+ -re "$gdb_prompt $" {fail "step through execl call"}
+ timeout {fail "(timeout) step through execl call"}
+ }
+ send_gdb "next\n"
+ gdb_expect {
+ -re "26.*printf.*$gdb_prompt $"\
+ {pass "step after execl call"}
+ -re "$gdb_prompt $" {fail "step after execl call"}
+ timeout {fail "(timeout) step after execl call"}
+ }
+
+ # Verify that we can print a local variable (which happens to be
+ # assigned the value of main's argc).
+ #
+ send_gdb "print local_j\n"
+ gdb_expect {
+ -re ".* = 3.*$gdb_prompt $"\
+ {pass "print execd-program/local_j (after execl)"}
+ -re "$gdb_prompt $" {fail "print execd-program/local_j (after execl)"}
+ timeout {fail "(timeout) print execd-program/local_j (after execl)"}
+ }
+
+ # Explicitly kill this program, or a subsequent rerun actually runs
+ # the exec'd program, not the original program...
+ zap_session
+
+ # Start the program running, and stop at main.
+ #
+ if ![runto_main] then {
+ perror "Couldn't run ${testfile} (4th try)"
+ return
+ }
+
+ # Verify that we can follow through follow an execv()
+ # call. (We must jump around earlier exec* calls.)
+ #
+ send_gdb "tbreak 41\n"
+ gdb_expect {
+ -re "Breakpoint .*file .*${srcfile}, line 41.*$gdb_prompt $"\
+ {pass "prepare to jump to execv call"}
+ -re "$gdb_prompt $" {fail "prepare to jump to execv call"}
+ timeout {fail "(timeout) prepare to jump to execv call"}
+ }
+ send_gdb "jump 41\n"
+ gdb_expect {
+ -re "main.* at .*${srcfile}:41.*$gdb_prompt $"\
+ {pass "jump to execv call"}
+ -re "$gdb_prompt $" {fail "jump to execv call"}
+ timeout {fail "(timeout) jump to execv call"}
+ }
+ send_gdb "next\n"
+ gdb_expect {
+ -re "Executing new program: .*${testfile2}.*${srcfile2}:23.*int local_j = argc;.*$gdb_prompt $"\
+ {pass "step through execv call"}
+ -re "$gdb_prompt $" {fail "step through execv call"}
+ timeout {fail "(timeout) step through execv call"}
+ }
+ send_gdb "next\n"
+ gdb_expect {
+ -re "26.*printf.*$gdb_prompt $"\
+ {pass "step after execv call"}
+ -re "$gdb_prompt $" {fail "step after execv call"}
+ timeout {fail "(timeout) step after execv call"}
+ }
+
+ # Verify that we can print a local variable (which happens to be
+ # assigned the value of main's argc).
+ #
+ send_gdb "print local_j\n"
+ gdb_expect {
+ -re ".* = 2.*$gdb_prompt $"\
+ {pass "print execd-program/local_j (after execv)"}
+ -re "$gdb_prompt $" {fail "print execd-program/local_j (after execv)"}
+ timeout {fail "(timeout) print execd-program/local_j (after execv)"}
+ }
+
+ # Explicitly kill this program, or a subsequent rerun actually runs
+ # the exec'd program, not the original program...
+ zap_session
+
+ # Start the program running, and stop at main.
+ #
+ if ![runto_main] then {
+ perror "Couldn't run ${testfile} (5th try)"
+ return
+ }
+
+ # Verify that we can just continue and thereby follow through an
+ # exec call. (Since the breakpoint on "main" is reset, we should
+ # just stop in main of the newly-exec'd program.)
+ #
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Executing new program: .*${testfile2}.*${srcfile2}:23.*int local_j = argc;.*$gdb_prompt $"\
+ {pass "continue through exec"}
+ -re "$gdb_prompt $" {fail "continue through exec"}
+ timeout {fail "(timeout) continue through exec"}
+ }
+}
+
+# Start with a fresh gdb
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+# This is a test of gdb's ability to follow a process through a
+# Unix exec() system call.
+#
+do_exec_tests
+
+return 0
diff --git a/gdb/testsuite/gdb.base/foll-fork.c b/gdb/testsuite/gdb.base/foll-fork.c
new file mode 100644
index 00000000000..841258f147c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/foll-fork.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <unistd.h>
+
+#ifdef PROTOTYPES
+void callee (int i)
+#else
+void callee (i)
+ int i;
+#endif
+{
+ printf("callee: %d\n", i);
+}
+
+#ifdef PROTOTYPES
+int main (void)
+#else
+main ()
+#endif
+{
+ int pid;
+ int v = 5;
+
+ pid = fork ();
+ if (pid == 0)
+ {
+ v++;
+ /* printf ("I'm the child!\n"); */
+ }
+ else
+ {
+ v--;
+ /* printf ("I'm the proud parent of child #%d!\n", pid); */
+ }
+}
diff --git a/gdb/testsuite/gdb.base/foll-fork.exp b/gdb/testsuite/gdb.base/foll-fork.exp
new file mode 100644
index 00000000000..d3fb1676878
--- /dev/null
+++ b/gdb/testsuite/gdb.base/foll-fork.exp
@@ -0,0 +1,367 @@
+# Copyright 1997, 1999 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+if { ![isnative] } then {
+ continue
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "foll-fork"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+
+# Until "set follow-fork-mode" and "catch fork" are implemented on
+# other targets...
+#
+if ![istarget "hppa*-hp-hpux*"] then {
+ continue
+}
+
+proc default_fork_parent_follow {} {
+ global gdb_prompt
+
+ send_gdb "show follow\n"
+ gdb_expect {
+ -re "Debugger response to a program call of fork or vfork is \"parent\"..*$gdb_prompt $"\
+ {pass "default show parent follow, no catchpoints"}
+ -re "$gdb_prompt $" {fail "default show parent follow, no catchpoints"}
+ timeout {fail "(timeout) default show parent follow, no catchpoints"}
+ }
+ send_gdb "next 2\n"
+ gdb_expect {
+ -re "Detaching after fork from.*$gdb_prompt $"\
+ {pass "default parent follow, no catchpoints"}
+ -re "$gdb_prompt $" {fail "default parent follow, no catchpoints"}
+ timeout {fail "(timeout) default parent follow, no catchpoints" }
+ }
+ # The child has been detached; allow time for any output it might
+ # generate to arrive, so that output doesn't get confused with
+ # any expected debugger output from a subsequent testpoint.
+ #
+ exec sleep 1
+}
+
+proc explicit_fork_parent_follow {} {
+ global gdb_prompt
+
+ send_gdb "set follow parent\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "set follow parent"}
+ timeout {fail "(timeout) set follow parent"}
+ }
+ send_gdb "show follow\n"
+ gdb_expect {
+ -re "Debugger response to a program call of fork or vfork is \"parent\"..*$gdb_prompt $"\
+ {pass "explicit show parent follow, no catchpoints"}
+ -re "$gdb_prompt $" {fail "explicit show parent follow, no catchpoints"}
+ timeout {fail "(timeout) explicit show parent follow, no catchpoints"}
+ }
+ send_gdb "next 2\n"
+ gdb_expect {
+ -re "Detaching after fork from.*$gdb_prompt $"\
+ {pass "explicit parent follow, no catchpoints"}
+ -re "$gdb_prompt $" {fail "explicit parent follow, no catchpoints"}
+ timeout {fail "(timeout) explicit parent follow, no catchpoints"}
+ }
+ # The child has been detached; allow time for any output it might
+ # generate to arrive, so that output doesn't get confused with
+ # any expected debugger output from a subsequent testpoint.
+ #
+ exec sleep 1
+}
+
+proc explicit_fork_child_follow {} {
+ global gdb_prompt
+
+ send_gdb "set follow child\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "set follow child"}
+ timeout {fail "(timeout) set follow child"}
+ }
+ send_gdb "show follow\n"
+ gdb_expect {
+ -re "Debugger response to a program call of fork or vfork is \"child\"..*$gdb_prompt $"\
+ {pass "explicit show child follow, no catchpoints"}
+ -re "$gdb_prompt $" {fail "explicit show child follow, no catchpoints"}
+ timeout {fail "(timeout) explicit show child follow, no catchpoints"}
+ }
+ send_gdb "next 2\n"
+ gdb_expect {
+ -re "Detaching from program:.*Attaching after fork to.*$gdb_prompt $"\
+ {pass "explicit child follow, no catchpoints"}
+ -re "$gdb_prompt $" {fail "explicit child follow, no catchpoints"}
+ timeout {fail "(timeout) explicit child follow, no catchpoints"}
+ }
+ # The child has been detached; allow time for any output it might
+ # generate to arrive, so that output doesn't get confused with
+ # any gdb_expected debugger output from a subsequent testpoint.
+ #
+ exec sleep 1
+}
+
+proc catch_fork_child_follow {} {
+ global gdb_prompt
+
+ send_gdb "catch fork\n"
+ gdb_expect {
+ -re "Catchpoint .*(fork).*$gdb_prompt $"\
+ {pass "explicit child follow, set catch fork"}
+ -re "$gdb_prompt $" {fail "explicit child follow, set catch fork"}
+ timeout {fail "(timeout) explicit child follow, set catch fork"}
+ }
+
+ # Verify that the catchpoint is mentioned in an "info breakpoints",
+ # and further that the catchpoint mentions no process id.
+ #
+ send_gdb "info breakpoints\n"
+ gdb_expect {
+ -re ".*catch fork.*keep y.*$gdb_prompt $"\
+ {pass "info shows catchpoint without pid"}
+ -re ".*catch fork.*process .*$gdb_prompt $"\
+ {fail "info shows catchpoint without pid"}
+ -re "$gdb_prompt $" {fail "info shows catchpoint without pid"}
+ timeout {fail "(timeout) info shows catchpoint without pid"}
+ }
+
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Catchpoint.*(forked process.*),.*in _fork_sys.*$gdb_prompt $"\
+ {pass "explicit child follow, catch fork"}
+ -re "$gdb_prompt $" {fail "explicit child follow, catch fork"}
+ timeout {fail "(timeout) explicit child follow, catch fork"}
+ }
+
+ # Verify that the catchpoint is mentioned in an "info breakpoints",
+ # and further that the catchpoint managed to capture a process id.
+ #
+ send_gdb "info breakpoints\n"
+ gdb_expect {
+ -re ".*catch fork .*process \[0-9\]+.*$gdb_prompt $"\
+ {pass "info shows catchpoint pid"}
+ -re "$gdb_prompt $" {fail "info shows catchpoint pid"}
+ timeout {fail "(timeout) info shows catchpoint pid"}
+ }
+
+ send_gdb "set follow child\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "set follow child"}
+ timeout {fail "(timeout) set follow child"}
+ }
+ send_gdb "tbreak 24\n"
+ gdb_expect {
+ -re "Breakpoint.*, line 24.*$gdb_prompt $"\
+ {pass "set follow child, tbreak"}
+ -re "$gdb_prompt $" {fail "set follow child, tbreak"}
+ timeout {fail "(timeout) set follow child, tbreak"}
+ }
+ send_gdb "continue\n"
+ gdb_expect {
+ -re ".*Detaching from program:.*Attaching after fork to.* at .*24.*$gdb_prompt $"\
+ {pass "set follow child, hit tbreak"}
+ -re "$gdb_prompt $" {fail "set follow child, hit tbreak"}
+ timeout {fail "(timeout) set follow child, hit tbreak"}
+ }
+ # The child has been detached; allow time for any output it might
+ # generate to arrive, so that output doesn't get confused with
+ # any expected debugger output from a subsequent testpoint.
+ #
+ exec sleep 1
+ send_gdb "delete breakpoints\n"
+ gdb_expect {
+ -re "Delete all breakpoints.*$" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "set follow child, cleanup"}
+ timeout {fail "(timeout) set follow child, cleanup"}
+ }
+ }
+ -re "$gdb_prompt $" {fail "set follow child, cleanup"}
+ timeout {fail "(timeout) set follow child, cleanup"}
+ }
+}
+
+proc tcatch_fork_parent_follow {} {
+ global gdb_prompt
+
+ send_gdb "catch fork\n"
+ gdb_expect {
+ -re "Catchpoint .*(fork).*$gdb_prompt $"\
+ {pass "explicit parent follow, set tcatch fork"}
+ -re "$gdb_prompt $" {fail "explicit parent follow, set tcatch fork"}
+ timeout {fail "(timeout) explicit parent follow, set tcatch fork"}
+ }
+# ??rehrauer: I don't yet know how to get the id of the tcatch
+# via this script, so that I can add a -do list to it. For now,
+# do the follow stuff after the catch happens.
+
+ send_gdb "continue\n"
+ gdb_expect {
+ -re ".*in _fork_sys.*$gdb_prompt $"\
+ {pass "explicit parent follow, tcatch fork"}
+ -re "$gdb_prompt $" {fail "explicit parent follow, tcatch fork"}
+ timeout {fail "(timeout) explicit parent follow, tcatch fork"}
+ }
+ send_gdb "set follow parent\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "set follow parent"}
+ timeout {fail "(timeout) set follow parent"}
+ }
+ send_gdb "tbreak 24\n"
+ gdb_expect {
+ -re "Breakpoint.*, line 24.*$gdb_prompt $"\
+ {pass "set follow parent, tbreak"}
+ -re "$gdb_prompt $" {fail "set follow parent, tbreak"}
+ timeout {fail "(timeout) set follow child, tbreak"}
+ }
+ send_gdb "continue\n"
+ gdb_expect {
+ -re ".*Detaching after fork from.* at .*24.*$gdb_prompt $"\
+ {pass "set follow parent, hit tbreak"}
+ -re "$gdb_prompt $" {fail "set follow parent, hit tbreak"}
+ timeout {fail "(timeout) set follow parent, hit tbreak"}
+ }
+ # The child has been detached; allow time for any output it might
+ # generate to arrive, so that output doesn't get confused with
+ # any expected debugger output from a subsequent testpoint.
+ #
+ exec sleep 1
+ send_gdb "delete breakpoints\n"
+ gdb_expect {
+ -re "Delete all breakpoints.*$" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "set follow parent, cleanup"}
+ timeout {fail "(timeout) set follow parent, cleanup"}
+ }
+ }
+ -re "$gdb_prompt $" {fail "set follow parent, cleanup"}
+ timeout {fail "(timeout) set follow parent, cleanup"}
+ }
+}
+
+proc do_fork_tests {} {
+ global gdb_prompt
+
+ # Verify that help is available for "set follow-fork-mode".
+ #
+ send_gdb "help set follow-fork-mode\n"
+ gdb_expect {
+ -re "Set debugger response to a program call of fork or vfork..*
+A fork or vfork creates a new process. follow-fork-mode can be:.*
+.*parent - the original process is debugged after a fork.*
+.*child - the new process is debugged after a fork.*
+.*ask - the debugger will ask for one of the above choices.*
+For \"parent\" or \"child\", the unfollowed process will run free..*
+By default, the debugger will follow the parent process..*$gdb_prompt $"\
+ { pass "help set follow" }
+ -re "$gdb_prompt $" { fail "help set follow" }
+ timeout { fail "(timeout) help set follow" }
+ }
+
+ # Verify that we can set follow-fork-mode, using an abbreviation
+ # for both the flag and its value.
+ #
+ send_gdb "set follow ch\n"
+ send_gdb "show fol\n"
+ gdb_expect {
+ -re "Debugger response to a program call of fork or vfork is \"child\".*$gdb_prompt $"\
+ {pass "set follow, using abbreviations"}
+ timeout {fail "(timeout) set follow, using abbreviations"}
+ }
+
+ # Verify that we cannot set follow-fork-mode to nonsense.
+ #
+ send_gdb "set follow chork\n"
+ gdb_expect {
+ -re "Undefined item: \"chork\".*$gdb_prompt $"\
+ {pass "set follow to nonsense is prohibited"}
+ -re "$gdb_prompt $" {fail "set follow to nonsense is prohibited"}
+ timeout {fail "(timeout) set follow to nonsense is prohibited"}
+ }
+ send_gdb "set follow parent\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "set follow to nonsense is prohibited (reset parent)"}
+ timeout {fail "set follow to nonsense is prohibited (reset parent)"}
+ }
+
+ # Test the default behaviour, which is to follow the parent of a
+ # fork, and detach from the child. Do this without catchpoints.
+ #
+ if [runto_main] then { default_fork_parent_follow }
+
+ # Test the ability to explicitly follow the parent of a fork, and
+ # detach from the child. Do this without catchpoints.
+ #
+ if [runto_main] then { explicit_fork_parent_follow }
+
+ # Test the ability to follow the child of a fork, and detach from
+ # the parent. Do this without catchpoints.
+ #
+ if [runto_main] then { explicit_fork_child_follow }
+
+ # Test the ability to follow both child and parent of a fork. Do
+ # this without catchpoints.
+ # ??rehrauer: NYI. Will add testpoints here when implemented.
+ #
+
+ # Test the ability to have the debugger ask the user at fork-time
+ # whether to follow the parent, child or both. Do this without
+ # catchpoints.
+ # ??rehrauer: NYI. Will add testpoints here when implemented.
+ #
+
+ # Test the ability to catch a fork, specify that the child be
+ # followed, and continue. Make the catchpoint permanent.
+ #
+ if [runto_main] then { catch_fork_child_follow }
+
+ # Test the ability to catch a fork, specify via a -do clause that
+ # the parent be followed, and continue. Make the catchpoint temporary.
+ #
+ if [runto_main] then { tcatch_fork_parent_follow }
+}
+
+# Start with a fresh gdb
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+# This is a test of gdb's ability to follow the parent, child or both
+# parent and child of a Unix fork() system call.
+#
+do_fork_tests
+
+return 0
diff --git a/gdb/testsuite/gdb.base/foll-vfork.c b/gdb/testsuite/gdb.base/foll-vfork.c
new file mode 100644
index 00000000000..3c7fab573fa
--- /dev/null
+++ b/gdb/testsuite/gdb.base/foll-vfork.c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include <unistd.h>
+
+#ifdef PROTOTYPES
+int main (void)
+#else
+main ()
+#endif
+{
+ int pid;
+
+ pid = vfork ();
+ if (pid == 0) {
+ printf ("I'm the child!\n");
+ execlp ("gdb.base/vforked-prog", "gdb.base/vforked-prog", (char *)0);
+ }
+ else {
+ printf ("I'm the proud parent of child #%d!\n", pid);
+ }
+}
diff --git a/gdb/testsuite/gdb.base/foll-vfork.exp b/gdb/testsuite/gdb.base/foll-vfork.exp
new file mode 100644
index 00000000000..1fed06bb966
--- /dev/null
+++ b/gdb/testsuite/gdb.base/foll-vfork.exp
@@ -0,0 +1,369 @@
+# Copyright 1997, 1999 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+if { ![isnative] } then {
+ continue
+}
+
+set prms_id 0
+set bug_id 0
+
+if [istarget "hppa2.0w-hp-hpux*"] {
+ warning "Don't run gdb.base/foll-vfork.exp until JAGaa43495 kernel problem is fixed."
+ return 0
+}
+
+set testfile "foll-vfork"
+set testfile2 "vforked-prog"
+set srcfile ${testfile}.c
+set srcfile2 ${testfile2}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set binfile2 ${objdir}/${subdir}/${testfile2}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+# Until "set follow-fork-mode" and "catch vfork" are implemented on
+# other targets...
+#
+if ![istarget "hppa*-hp-hpux*"] then {
+ continue
+}
+
+# Test to see if we are on an HP-UX 10.20 and if so,
+# do not run these tests as catching vfork is disabled for
+# 10.20.
+
+if [istarget "hppa*-hp-hpux10.20"] then {
+ return 0
+}
+
+# A few of these tests require a little more time than the standard
+# timeout allows.
+set oldtimeout $timeout
+set timeout [expr "$timeout + 10"]
+
+proc vfork_parent_follow_through_step {} {
+ global gdb_prompt
+
+ send_gdb "set follow parent\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "set follow parent, vfork through step"}
+ timeout {fail "set follow parent, vfork through step"}
+ }
+ send_gdb "next\n"
+ gdb_expect {
+ -re "Detaching after fork from.*13.*$gdb_prompt "\
+ {pass "vfork parent follow, through step"}
+ -re "$gdb_prompt $" {fail "vfork parent follow, through step"}
+ timeout {fail "(timeout) vfork parent follow, through step" }
+ }
+ # The child has been detached; allow time for any output it might
+ # generate to arrive, so that output doesn't get confused with
+ # any gdb_expected debugger output from a subsequent testpoint.
+ #
+ exec sleep 1
+}
+
+proc vfork_parent_follow_to_bp {} {
+ global gdb_prompt
+
+ send_gdb "set follow parent\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "set follow parent, vfork to bp"}
+ timeout {fail "set follow parent, vfork to bp"}
+ }
+ send_gdb "break 18\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "break, vfork to bp"}
+ timeout {fail "break, vfork to bp"}
+ }
+ send_gdb "continue\n"
+ gdb_expect {
+ -re ".*Detaching after fork from process.*Breakpoint.*18.*$gdb_prompt "\
+ {pass "vfork parent follow, to bp"}
+ -re "$gdb_prompt $" {fail "vfork parent follow, to bp"}
+ timeout {fail "(timeout) vfork parent follow, to bp" }
+ }
+ # The child has been detached; allow time for any output it might
+ # generate to arrive, so that output doesn't get confused with
+ # any expected debugger output from a subsequent testpoint.
+ #
+ exec sleep 1
+}
+
+proc vfork_and_exec_child_follow_to_main_bp {} {
+ global gdb_prompt
+ global binfile
+
+ send_gdb "set follow child\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "set follow child, vfork and exec to main bp"}
+ timeout {fail "set follow child, vfork and exec to main bp"}
+ }
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Detaching from program.*Attaching after fork to.*Executing new program.*Breakpoint.*vforked-prog.c:9.*$gdb_prompt "\
+ {pass "vfork and exec child follow, to main bp"}
+ -re "$gdb_prompt $" {fail "vfork and exec child follow, to main bp"}
+ timeout {fail "(timeout) vfork and exec child follow, to main bp" }
+ }
+ # The parent has been detached; allow time for any output it might
+ # generate to arrive, so that output doesn't get confused with
+ # any gdb_expected debugger output from a subsequent testpoint.
+ #
+ exec sleep 1
+
+ # Explicitly kill this child, or a subsequent rerun actually runs
+ # the exec'd child, not the original program...
+ send_gdb "kill\n"
+ gdb_expect {
+ -re ".*Kill the program being debugged.*y or n. $" {
+ send_gdb "y\n"
+ send_gdb "file $binfile\n"
+ gdb_expect {
+ -re ".*Load new symbol table from.*y or n. $" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "Reading symbols from.*$gdb_prompt $" {}
+ timeout { fail "loading symbols (timeout)"; return }
+ }
+ }
+ -re ".*gdb_prompt $" {}
+ timeout { fail "loading symbols (timeout)"; return }
+ }
+ }
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "killing inferior (timeout)" ; return }
+ }
+}
+
+proc vfork_and_exec_child_follow_through_step {} {
+ global gdb_prompt
+ global binfile
+
+# This test cannot be performed prior to HP-UX 10.30, because ptrace-based
+# debugging of a vforking program basically doesn't allow the child to do
+# things like hit a breakpoint between a vfork and exec. This means that
+# saying "set follow child; next" at a vfork() call won't work, because
+# the implementation of "next" sets a "step resume" breakpoint at the
+# return from the vfork(), which the child will hit on its way to exec'ing.
+#
+ if { ![istarget "hppa*-*-hpux11.*"] } {
+ verbose "vfork child-following next test ignored for non-hppa or pre-HP/UX-10.30 targets."
+ return 0
+ }
+
+ send_gdb "set follow child\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "set follow child, vfork and exec through step"}
+ timeout {fail "set follow child, vfork and exec through step"}
+ }
+ send_gdb "next\n"
+ gdb_expect {
+ -re "Detaching from program.*Attaching after fork to.*Executing new program.*Breakpoint.*vforked-prog.c:9.*$gdb_prompt "\
+ {pass "vfork and exec child follow, through step"}
+ -re "$gdb_prompt $" {fail "vfork and exec child follow, through step"}
+ timeout {fail "(timeout) vfork and exec child follow, through step" }
+ }
+ # The parent has been detached; allow time for any output it might
+ # generate to arrive, so that output doesn't get confused with
+ # any expected debugger output from a subsequent testpoint.
+ #
+ exec sleep 1
+
+ # Explicitly kill this child, or a subsequent rerun actually runs
+ # the exec'd child, not the original program...
+ send_gdb "kill\n"
+ gdb_expect {
+ -re ".*Kill the program being debugged.*y or n. $" {
+ send_gdb "y\n"
+ send_gdb "file $binfile\n"
+ gdb_expect {
+ -re ".*Load new symbol table from.*y or n. $" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "Reading symbols from.*$gdb_prompt $" {}
+ timeout { fail "loading symbols (timeout)"; return }
+ }
+ }
+ -re ".*gdb_prompt $" {}
+ timeout { fail "loading symbols (timeout)"; return }
+ }
+ }
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "killing inferior (timeout)" ; return }
+ }
+}
+
+proc tcatch_vfork_then_parent_follow {} {
+ global gdb_prompt
+ global srcfile
+
+ send_gdb "set follow parent\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "set follow parent, tcatch vfork"}
+ timeout {fail "set follow parent, tcatch vfork"}
+ }
+ send_gdb "tcatch vfork\n"
+ gdb_expect {
+ -re "Catchpoint .*(vfork).*$gdb_prompt $"\
+ {pass "vfork parent follow, set tcatch vfork"}
+ -re "$gdb_prompt $" {fail "vfork parent follow, set tcatch vfork"}
+ timeout {fail "(timeout) vfork parent follow, set tcatch vfork"}
+ }
+ send_gdb "continue\n"
+# HP-UX 10.20 seems to stop you in "vfork", while more recent HP-UXs
+# stop you in "_vfork".
+ gdb_expect {
+ -re "0x\[0-9a-fA-F\]*.*vfork.*$gdb_prompt "\
+ {pass "vfork parent follow, tcatch vfork"}
+ -re "0x\[0-9a-fA-F\]*.*_vfork.*$gdb_prompt "\
+ {pass "vfork parent follow, tcatch vfork"}
+ -re "$gdb_prompt $" {fail "vfork parent follow, tcatch vfork"}
+ timeout {fail "(timeout) vfork parent follow, tcatch vfork"}
+ }
+ send_gdb "finish\n"
+ gdb_expect {
+ -re "Run till exit from.*vfork.*0x\[0-9a-fA-F\]* in main .* at .*${srcfile}:12.*$gdb_prompt "\
+ {pass "vfork parent follow, finish after tcatch vfork"}
+ -re "$gdb_prompt $" {fail "vfork parent follow, finish after tcatch vfork"}
+ timeout {fail "(timeout) vfork parent follow, finish after tcatch vfork" }
+ }
+ # The child has been detached; allow time for any output it might
+ # generate to arrive, so that output doesn't get confused with
+ # any expected debugger output from a subsequent testpoint.
+ #
+ exec sleep 1
+}
+
+proc tcatch_vfork_then_child_follow {} {
+ global gdb_prompt
+ global srcfile2
+
+ send_gdb "set follow child\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "set follow child, tcatch vfork"}
+ timeout {fail "set follow child, tcatch vfork"}
+ }
+ send_gdb "tcatch vfork\n"
+ gdb_expect {
+ -re "Catchpoint .*(vfork).*$gdb_prompt $"\
+ {pass "vfork child follow, set tcatch vfork"}
+ -re "$gdb_prompt $" {fail "vfork child follow, set tcatch vfork"}
+ timeout {fail "(timeout) vfork child follow, set tcatch vfork"}
+ }
+ send_gdb "continue\n"
+# HP-UX 10.20 seems to stop you in "vfork", while more recent HP-UXs
+# stop you in "_vfork".
+ gdb_expect {
+ -re "0x\[0-9a-fA-F\]*.*vfork.*$gdb_prompt "\
+ {pass "vfork child follow, tcatch vfork"}
+ -re "0x\[0-9a-fA-F\]*.*_vfork.*$gdb_prompt "\
+ {pass "vfork child follow, tcatch vfork"}
+ -re "$gdb_prompt $" {fail "vfork child follow, tcatch vfork"}
+ timeout {fail "(timeout) vfork child follow, tcatch vfork"}
+ }
+ send_gdb "finish\n"
+ gdb_expect {
+ -re "Run till exit from.*vfork.*${srcfile2}:9.*$gdb_prompt "\
+ {pass "vfork child follow, finish after tcatch vfork"}
+ -re "$gdb_prompt $" {fail "vfork child follow, finish after tcatch vfork"}
+ timeout {fail "(timeout) vfork child follow, finish after tcatch vfork" }
+ }
+ # The parent has been detached; allow time for any output it might
+ # generate to arrive, so that output doesn't get confused with
+ # any expected debugger output from a subsequent testpoint.
+ #
+ exec sleep 1
+}
+
+proc do_vfork_and_exec_tests {} {
+ global gdb_prompt
+
+ # Try following the parent process by stepping through a call to
+ # vfork. Do this without catchpoints.
+ if [runto_main] then { vfork_parent_follow_through_step }
+
+ # Try following the parent process by setting a breakpoint on the
+ # other side of a vfork, and running to that point. Do this
+ # without catchpoints.
+ if [runto_main] then { vfork_parent_follow_to_bp }
+
+ # Try following the child process by just continuing through the
+ # vfork, and letting the parent's breakpoint on "main" be auto-
+ # magically reset in the child.
+ #
+ if [runto_main] then { vfork_and_exec_child_follow_to_main_bp }
+
+ # Try following the child process by stepping through a call to
+ # vfork. The child also executes an exec. Since the child cannot
+ # be debugged until after it has exec'd, and since there's a bp on
+ # "main" in the parent, and since the bp's for the parent are
+ # recomputed in the exec'd child, the step through a vfork should
+ # land us in the "main" for the exec'd child, too.
+ #
+ if [runto_main] then { vfork_and_exec_child_follow_through_step }
+
+ # Try catching a vfork, and stepping out to the parent.
+ #
+ if [runto_main] then { tcatch_vfork_then_parent_follow }
+
+ # Try catching a vfork, and stepping out to the child.
+ #
+ if [runto_main] then { tcatch_vfork_then_child_follow }
+
+ # Test the ability to follow both child and parent of a vfork. Do
+ # this without catchpoints.
+ # ??rehrauer: NYI. Will add testpoints here when implemented.
+ #
+
+ # Test the ability to have the debugger ask the user at vfork-time
+ # whether to follow the parent, child or both. Do this without
+ # catchpoints.
+ # ??rehrauer: NYI. Will add testpoints here when implemented.
+ #
+}
+
+# Start with a fresh gdb
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+# This is a test of gdb's ability to follow the parent or child
+# of a Unix vfork() system call. (The child will subsequently
+# call a variant of a Unix exec() system call.)
+#
+do_vfork_and_exec_tests
+
+set timeout $oldtimeout
+return 0
diff --git a/gdb/testsuite/gdb.base/foo.c b/gdb/testsuite/gdb.base/foo.c
new file mode 100644
index 00000000000..2553607d5ec
--- /dev/null
+++ b/gdb/testsuite/gdb.base/foo.c
@@ -0,0 +1,9 @@
+static int foox = 'f' + 'o' + 'o';
+
+int foo (int x)
+{
+ if (x)
+ return foox;
+ else
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/funcargs.c b/gdb/testsuite/gdb.base/funcargs.c
new file mode 100644
index 00000000000..f7dfc649676
--- /dev/null
+++ b/gdb/testsuite/gdb.base/funcargs.c
@@ -0,0 +1,792 @@
+/* Test passing of arguments to functions. Use various sorts of arguments,
+ including basic types, pointers to those types, structures, lots of
+ args, etc, in various combinations. */
+
+/* AIX requires this to be the first thing in the file. */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+# define HAVE_STACK_ALLOCA 1
+#else /* not __GNUC__ */
+# ifdef _AIX
+ #pragma alloca
+# define HAVE_STACK_ALLOCA 1
+# else /* Not AIX */
+# ifdef sparc
+# include <alloca.h>
+# define HAVE_STACK_ALLOCA 1
+# ifdef __STDC__
+ void *alloca ();
+# else
+ char *alloca ();
+# endif /* __STDC__ */
+# endif /* sparc */
+# endif /* Not AIX */
+#endif /* not __GNUC__ */
+
+char c = 'a';
+char *cp = &c;
+
+unsigned char uc = 'b';
+unsigned char *ucp = &uc;
+
+short s = 1;
+short *sp = &s;
+
+unsigned short us = 6;
+unsigned short *usp = &us;
+
+int i = 2;
+int *ip = &i;
+
+unsigned int ui = 7;
+unsigned int *uip = &ui;
+
+long l = 3;
+long *lp = &l;
+
+unsigned long ul = 8;
+unsigned long *ulp = &ul;
+
+float f = 4.0;
+float *fp = &f;
+
+double d = 5.0;
+double *dp = &d;
+
+struct stag {
+ int s1;
+ int s2;
+} st = { 101, 102 };
+struct stag *stp = &st;
+
+union utag {
+ int u1;
+ long u2;
+} un;
+union utag *unp = &un;
+
+char carray[] = {'a', 'n', ' ', 'a', 'r', 'r', 'a', 'y', '\0'};
+
+
+/* Test various permutations and interleaving of integral arguments */
+
+
+#ifdef PROTOTYPES
+void call0a (char c, short s, int i, long l)
+#else
+call0a (c, s, i, l)
+char c; short s; int i; long l;
+#endif
+{
+ c = 'a';
+ s = 5;
+ i = 6;
+ l = 7;
+}
+
+#ifdef PROTOTYPES
+void call0b (short s, int i, long l, char c)
+#else
+call0b (s, i, l, c)
+short s; int i; long l; char c;
+#endif
+{
+ s = 6; i = 7; l = 8; c = 'j';
+}
+
+#ifdef PROTOTYPES
+void call0c (int i, long l, char c, short s)
+#else
+call0c (i, l, c, s)
+int i; long l; char c; short s;
+#endif
+{
+ i = 3; l = 4; c = 'k'; s = 5;
+}
+
+#ifdef PROTOTYPES
+void call0d (long l, char c, short s, int i)
+#else
+call0d (l, c, s, i)
+long l; char c; short s; int i;
+#endif
+{
+ l = 7; c = 'z'; s = 8; i = 9;
+}
+
+#ifdef PROTOTYPES
+void call0e (char c1, long l, char c2, int i, char c3, short s, char c4, char c5)
+#else
+call0e (c1, l, c2, i, c3, s, c4, c5)
+char c1; long l; char c2; int i; char c3; short s; char c4; char c5;
+#endif
+{
+ c1 = 'a'; l = 5; c2 = 'b'; i = 7; c3 = 'c'; s = 7; c4 = 'f'; c5 = 'g';
+}
+
+
+/* Test various permutations and interleaving of unsigned integral arguments */
+
+
+#ifdef PROTOTYPES
+void call1a (unsigned char uc, unsigned short us, unsigned int ui, unsigned long ul)
+#else
+call1a (uc, us, ui, ul)
+unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
+#endif
+{
+ uc = 5; us = 6; ui = 7; ul = 8;
+}
+
+#ifdef PROTOTYPES
+void call1b (unsigned short us, unsigned int ui, unsigned long ul, unsigned char uc)
+#else
+call1b (us, ui, ul, uc)
+unsigned short us; unsigned int ui; unsigned long ul; unsigned char uc;
+#endif
+{
+ uc = 5; us = 6; ui = 7; ul = 8;
+}
+
+#ifdef PROTOTYPES
+void call1c (unsigned int ui, unsigned long ul, unsigned char uc, unsigned short us)
+#else
+call1c (ui, ul, uc, us)
+unsigned int ui; unsigned long ul; unsigned char uc; unsigned short us;
+#endif
+{
+ uc = 5; us = 6; ui = 7; ul = 8;
+}
+
+#ifdef PROTOTYPES
+void call1d (unsigned long ul, unsigned char uc, unsigned short us, unsigned int ui)
+#else
+call1d (ul, uc, us, ui)
+unsigned long ul; unsigned char uc; unsigned short us; unsigned int ui;
+#endif
+{
+ uc = 5; us = 6; ui = 7; ul = 8;
+}
+
+#ifdef PROTOTYPES
+void call1e (unsigned char uc1, unsigned long ul, unsigned char uc2, unsigned int ui, unsigned char uc3, unsigned short us, unsigned char uc4, unsigned char uc5)
+#else
+call1e (uc1, ul, uc2, ui, uc3, us, uc4, uc5)
+unsigned char uc1; unsigned long ul; unsigned char uc2; unsigned int ui;
+unsigned char uc3; unsigned short us; unsigned char uc4; unsigned char uc5;
+#endif
+{
+ uc1 = 5; ul = 7; uc2 = 8; ui = 9; uc3 = 10; us = 11; uc4 = 12; uc5 = 55;
+}
+
+/* Test various permutations and interleaving of integral arguments with
+ floating point arguments. */
+
+
+#ifdef PROTOTYPES
+void call2a (char c, float f1, short s, double d1, int i, float f2, long l, double d2)
+#else
+call2a (c, f1, s, d1, i, f2, l, d2)
+char c; float f1; short s; double d1; int i; float f2; long l; double d2;
+#endif
+{
+ c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
+}
+
+#ifdef PROTOTYPES
+void call2b (float f1, short s, double d1, int i, float f2, long l, double d2, char c)
+#else
+call2b (f1, s, d1, i, f2, l, d2, c)
+float f1; short s; double d1; int i; float f2; long l; double d2; char c;
+#endif
+{
+ c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
+}
+
+#ifdef PROTOTYPES
+void call2c (short s, double d1, int i, float f2, long l, double d2, char c, float f1)
+#else
+call2c (s, d1, i, f2, l, d2, c, f1)
+short s; double d1; int i; float f2; long l; double d2; char c; float f1;
+#endif
+{
+ c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
+}
+
+#ifdef PROTOTYPES
+void call2d (double d1, int i, float f2, long l, double d2, char c, float f1, short s)
+#else
+call2d (d1, i, f2, l, d2, c, f1, s)
+double d1; int i; float f2; long l; double d2; char c; float f1; short s;
+#endif
+{
+ c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
+}
+
+#ifdef PROTOTYPES
+void call2e (int i, float f2, long l, double d2, char c, float f1, short s, double d1)
+#else
+call2e (i, f2, l, d2, c, f1, s, d1)
+int i; float f2; long l; double d2; char c; float f1; short s; double d1;
+#endif
+{
+ c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
+}
+
+#ifdef PROTOTYPES
+void call2f (float f2, long l, double d2, char c, float f1, short s, double d1, int i)
+#else
+call2f (f2, l, d2, c, f1, s, d1, i)
+float f2; long l; double d2; char c; float f1; short s; double d1; int i;
+#endif
+{
+ c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
+}
+
+#ifdef PROTOTYPES
+void call2g (long l, double d2, char c, float f1, short s, double d1, int i, float f2)
+#else
+call2g (l, d2, c, f1, s, d1, i, f2)
+long l; double d2; char c; float f1; short s; double d1; int i; float f2;
+#endif
+{
+ c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
+}
+
+#ifdef PROTOTYPES
+void call2h (double d2, char c, float f1, short s, double d1, int i, float f2, long l)
+#else
+call2h (d2, c, f1, s, d1, i, f2, l)
+double d2; char c; float f1; short s; double d1; int i; float f2; long l;
+#endif
+{
+ c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
+}
+
+#ifdef PROTOTYPES
+void call2i (char c1, float f1, char c2, char c3, double d1, char c4, char c5, char c6, float f2, short s, char c7, double d2)
+#else
+call2i (c1, f1, c2, c3, d1, c4, c5, c6, f2, s, c7, d2)
+char c1; float f1; char c2; char c3; double d1; char c4; char c5; char c6;
+float f2; short s; char c7; double d2;
+#endif
+{
+ c1 = 'a'; f1 = 0.0; c2 = 5; d1 = 0.0; c3 = 6; f2 = 0.1; c4 = 7; d2 = 0.2;
+ c5 = 's'; c6 = 'f'; c7 = 'z'; s = 77;
+}
+
+
+/* Test pointers to various integral and floating types. */
+
+
+#ifdef PROTOTYPES
+void call3a (char *cp, short *sp, int *ip, long *lp)
+#else
+call3a (cp, sp, ip, lp)
+char *cp; short *sp; int *ip; long *lp;
+#endif
+{
+ cp = 0; sp = 0; ip = 0; lp = 0;
+}
+
+#ifdef PROTOTYPES
+void call3b (unsigned char *ucp, unsigned short *usp, unsigned int *uip, unsigned long *ulp)
+#else
+call3b (ucp, usp, uip, ulp)
+unsigned char *ucp; unsigned short *usp; unsigned int *uip;
+unsigned long *ulp;
+#endif
+{
+ ucp = 0; usp = 0; uip = 0; ulp = 0;
+}
+
+#ifdef PROTOTYPES
+void call3c (float *fp, double *dp)
+#else
+call3c (fp, dp)
+float *fp; double *dp;
+#endif
+{
+ fp = 0; dp = 0;
+}
+
+
+/* Test passing structures and unions by reference. */
+
+
+#ifdef PROTOTYPES
+void call4a (struct stag *stp)
+#else
+call4a (stp)
+struct stag *stp;
+#endif
+{stp = 0;}
+
+#ifdef PROTOTYPES
+void call4b (union utag *unp)
+#else
+call4b (unp)
+union utag *unp;
+#endif
+{
+ unp = 0;
+}
+
+
+/* Test passing structures and unions by value. */
+
+
+#ifdef PROTOTYPES
+void call5a (struct stag st)
+#else
+call5a (st)
+struct stag st;
+#endif
+{st.s1 = 5;}
+
+#ifdef PROTOTYPES
+void call5b (union utag un)
+#else
+call5b (un)
+union utag un;
+#endif
+{un.u1 = 7;}
+
+
+/* Test shuffling of args */
+
+
+void call6k ()
+{
+}
+
+#ifdef PROTOTYPES
+void call6j (unsigned long ul)
+#else
+call6j (ul)
+unsigned long ul;
+#endif
+{
+ ul = ul;
+ call6k ();
+}
+
+#ifdef PROTOTYPES
+void call6i (unsigned int ui, unsigned long ul)
+#else
+call6i (ui, ul)
+unsigned int ui; unsigned long ul;
+#endif
+{
+ ui = ui;
+ call6j (ul);
+}
+
+#ifdef PROTOTYPES
+void call6h (unsigned short us, unsigned int ui, unsigned long ul)
+#else
+call6h (us, ui, ul)
+unsigned short us; unsigned int ui; unsigned long ul;
+#endif
+{
+ us = us;
+ call6i (ui, ul);
+}
+
+#ifdef PROTOTYPES
+void call6g (unsigned char uc, unsigned short us, unsigned int ui, unsigned long ul)
+#else
+call6g (uc, us, ui, ul)
+unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
+#endif
+{
+ uc = uc;
+ call6h (us, ui, ul);
+}
+
+#ifdef PROTOTYPES
+void call6f (double d, unsigned char uc, unsigned short us, unsigned int ui, unsigned long ul)
+#else
+call6f (d, uc, us, ui, ul)
+double d;
+unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
+#endif
+{
+ d = d;
+ call6g (uc, us, ui, ul);
+}
+
+#ifdef PROTOTYPES
+void call6e (float f, double d, unsigned char uc, unsigned short us, unsigned int ui, unsigned long ul)
+#else
+call6e (f, d, uc, us, ui, ul)
+float f; double d;
+unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
+#endif
+{
+ f = f;
+ call6f (d, uc, us, ui, ul);
+}
+
+#ifdef PROTOTYPES
+void call6d (long l, float f, double d, unsigned char uc, unsigned short us, unsigned int ui, unsigned long ul)
+#else
+call6d (l, f, d, uc, us, ui, ul)
+long l; float f; double d;
+unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
+#endif
+{
+ l = l;
+ call6e (f, d, uc, us, ui, ul);
+}
+
+#ifdef PROTOTYPES
+void call6c (int i, long l, float f, double d, unsigned char uc, unsigned short us, unsigned int ui, unsigned long ul)
+#else
+call6c (i, l, f, d, uc, us, ui, ul)
+int i; long l; float f; double d;
+unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
+#endif
+{
+ i = i;
+ call6d (l, f, d, uc, us, ui, ul);
+}
+
+#ifdef PROTOTYPES
+void call6b (short s, int i, long l, float f, double d, unsigned char uc, unsigned short us, unsigned int ui, unsigned long ul)
+#else
+call6b (s, i, l, f, d, uc, us, ui, ul)
+short s; int i; long l; float f; double d;
+unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
+#endif
+{
+ s = s;
+ call6c (i, l, f, d, uc, us, ui, ul);
+}
+
+#ifdef PROTOTYPES
+void call6a (char c, short s, int i, long l, float f, double d, unsigned char uc, unsigned short us, unsigned int ui, unsigned long ul)
+#else
+call6a (c, s, i, l, f, d, uc, us, ui, ul)
+char c; short s; int i; long l; float f; double d;
+unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
+#endif
+{
+ c = c;
+ call6b (s, i, l, f, d, uc, us, ui, ul);
+}
+
+/* Test shuffling of args, round robin */
+
+
+#ifdef PROTOTYPES
+void call7k (char c, int i, short s, long l, float f, unsigned char uc, double d, unsigned short us, unsigned long ul, unsigned int ui)
+#else
+call7k (c, i, s, l, f, uc, d, us, ul, ui)
+char c; int i; short s; long l; float f; unsigned char uc; double d; unsigned short us; unsigned long ul; unsigned int ui;
+#endif
+{
+ c = 'a'; i = 7; s = 8; l = 7; f = 0.3; uc = 44; d = 0.44; us = 77;
+ ul = 43; ui = 33;
+}
+
+#ifdef PROTOTYPES
+void call7j (unsigned int ui, char c, int i, short s, long l, float f, unsigned char uc, double d, unsigned short us, unsigned long ul)
+#else
+call7j (ui, c, i, s, l, f, uc, d, us, ul)
+unsigned int ui; char c; int i; short s; long l; float f; unsigned char uc; double d; unsigned short us; unsigned long ul;
+#endif
+{
+ call7k (c, i, s, l, f, uc, d, us, ul, ui);
+}
+
+#ifdef PROTOTYPES
+void call7i (unsigned long ul, unsigned int ui, char c, int i, short s, long l, float f, unsigned char uc, double d, unsigned short us)
+#else
+call7i (ul, ui, c, i, s, l, f, uc, d, us)
+unsigned long ul; unsigned int ui; char c; int i; short s; long l; float f; unsigned char uc; double d; unsigned short us;
+#endif
+{
+ call7j (ui, c, i, s, l, f, uc, d, us, ul);
+}
+
+#ifdef PROTOTYPES
+void call7h (unsigned short us, unsigned long ul, unsigned int ui, char c, int i, short s, long l, float f, unsigned char uc, double d)
+#else
+call7h (us, ul, ui, c, i, s, l, f, uc, d)
+unsigned short us; unsigned long ul; unsigned int ui; char c; int i; short s; long l; float f; unsigned char uc; double d;
+#endif
+{
+ call7i (ul, ui, c, i, s, l, f, uc, d, us);
+}
+
+#ifdef PROTOTYPES
+void call7g (double d, unsigned short us, unsigned long ul, unsigned int ui, char c, int i, short s, long l, float f, unsigned char uc)
+#else
+call7g (d, us, ul, ui, c, i, s, l, f, uc)
+double d; unsigned short us; unsigned long ul; unsigned int ui; char c; int i; short s; long l; float f; unsigned char uc;
+#endif
+{
+ call7h (us, ul, ui, c, i, s, l, f, uc, d);
+}
+
+#ifdef PROTOTYPES
+void call7f (unsigned char uc, double d, unsigned short us, unsigned long ul, unsigned int ui, char c, int i, short s, long l, float f)
+#else
+call7f (uc, d, us, ul, ui, c, i, s, l, f)
+unsigned char uc; double d; unsigned short us; unsigned long ul; unsigned int ui; char c; int i; short s; long l; float f;
+#endif
+{
+ call7g (d, us, ul, ui, c, i, s, l, f, uc);
+}
+
+#ifdef PROTOTYPES
+void call7e (float f, unsigned char uc, double d, unsigned short us, unsigned long ul, unsigned int ui, char c, int i, short s, long l)
+#else
+call7e (f, uc, d, us, ul, ui, c, i, s, l)
+float f; unsigned char uc; double d; unsigned short us; unsigned long ul; unsigned int ui; char c; int i; short s; long l;
+#endif
+{
+ call7f (uc, d, us, ul, ui, c, i, s, l, f);
+}
+
+#ifdef PROTOTYPES
+void call7d (long l, float f, unsigned char uc, double d, unsigned short us, unsigned long ul, unsigned int ui, char c, int i, short s)
+#else
+call7d (l, f, uc, d, us, ul, ui, c, i, s)
+long l; float f; unsigned char uc; double d; unsigned short us; unsigned long ul; unsigned int ui; char c; int i; short s;
+#endif
+{
+ call7e (f, uc, d, us, ul, ui, c, i, s, l);
+}
+
+#ifdef PROTOTYPES
+void call7c (short s, long l, float f, unsigned char uc, double d, unsigned short us, unsigned long ul, unsigned int ui, char c, int i)
+#else
+call7c (s, l, f, uc, d, us, ul, ui, c, i)
+short s; long l; float f; unsigned char uc; double d; unsigned short us; unsigned long ul; unsigned int ui; char c; int i;
+#endif
+{
+ call7d (l, f, uc, d, us, ul, ui, c, i, s);
+}
+
+#ifdef PROTOTYPES
+void call7b (int i, short s, long l, float f, unsigned char uc, double d, unsigned short us, unsigned long ul, unsigned int ui, char c)
+#else
+call7b (i, s, l, f, uc, d, us, ul, ui, c)
+int i; short s; long l; float f; unsigned char uc; double d; unsigned short us; unsigned long ul; unsigned int ui; char c;
+#endif
+{
+ call7c (s, l, f, uc, d, us, ul, ui, c, i);
+}
+
+#ifdef PROTOTYPES
+void call7a (char c, int i, short s, long l, float f, unsigned char uc, double d, unsigned short us, unsigned long ul, unsigned int ui)
+#else
+call7a (c, i, s, l, f, uc, d, us, ul, ui)
+char c; int i; short s; long l; float f; unsigned char uc; double d; unsigned short us; unsigned long ul; unsigned int ui;
+#endif
+{
+ call7b (i, s, l, f, uc, d, us, ul, ui, c);
+}
+
+
+/* Test printing of structures passed as arguments to recursive functions. */
+
+
+typedef struct s
+{
+ short s;
+ int i;
+ long l;
+} SVAL;
+
+void hitbottom ()
+{
+}
+
+#ifdef PROTOTYPES
+void recurse (SVAL a, int depth)
+#else
+void recurse (a, depth)
+SVAL a;
+int depth;
+#endif
+{
+ a.s = a.i = a.l = --depth;
+ if (depth == 0)
+ hitbottom ();
+ else
+ recurse (a, depth);
+}
+
+void test_struct_args ()
+{
+ SVAL s; s.s = 5; s.i = 5; s.l = 5;
+
+ recurse (s, 5);
+}
+
+/* On various machines (pa, 29k, and rs/6000, at least), a function which
+ calls alloca may do things differently with respect to frames. So give
+ it a try. */
+
+#ifdef PROTOTYPES
+void localvars_after_alloca (char c, short s, int i, long l)
+#else
+void
+localvars_after_alloca (c, s, i, l)
+ char c;
+ short s;
+ int i;
+ long l;
+#endif
+{
+#ifdef HAVE_STACK_ALLOCA
+ /* No need to use the alloca.c alloca-on-top-of-malloc; it doesn't
+ test what we are looking for, so if we don't have an alloca which
+ allocates on the stack, just don't bother to call alloca at all. */
+
+ char *z = alloca (s + 50);
+#endif
+ c = 'a';
+ s = 5;
+ i = 6;
+ l = 7;
+}
+
+#ifdef PROTOTYPES
+void call_after_alloca_subr (char c, short s, int i, long l, unsigned char uc, unsigned short us, unsigned int ui, unsigned long ul)
+#else
+void
+call_after_alloca_subr (c, s, i, l, uc, us, ui, ul)
+char c; int i; short s; long l; unsigned char uc; unsigned short us; unsigned long ul; unsigned int ui;
+#endif
+{
+ c = 'a';
+ i = 7; s = 8; l = 7; uc = 44; us = 77;
+ ul = 43; ui = 33;
+}
+
+#ifdef PROTOTYPES
+void call_after_alloca (char c, short s, int i, long l)
+#else
+void
+call_after_alloca (c, s, i, l)
+ char c;
+ short s;
+ int i;
+ long l;
+#endif
+{
+#ifdef HAVE_STACK_ALLOCA
+ /* No need to use the alloca.c alloca-on-top-of-malloc; it doesn't
+ test what we are looking for, so if we don't have an alloca which
+ allocates on the stack, just don't bother to call alloca at all. */
+
+ char *z = alloca (s + 50);
+#endif
+ call_after_alloca_subr (c, s, i, l, 'b', 11, 12, (unsigned long)13);
+}
+
+
+
+/* The point behind this test is the PA will call this indirectly
+ through dyncall. Unlike the indirect calls to call0a, this test
+ will require a trampoline between dyncall and this function on the
+ call path, then another trampoline on between this function and main
+ on the return path. */
+#ifdef PROTOTYPES
+double call_with_trampolines (double d1)
+#else
+double
+call_with_trampolines (d1)
+double d1;
+#endif
+{
+ return d1;
+} /* End of call_with_trampolines, this comment is needed by funcargs.exp */
+
+/* Dummy functions which the testsuite can use to run to, etc. */
+
+void
+marker_indirect_call () {}
+
+void
+marker_call_with_trampolines () {}
+
+int main ()
+{
+ void (*pointer_to_call0a) (char, short, int, long) = (void (*)(char, short, int, long))call0a;
+ double (*pointer_to_call_with_trampolines) (double) = call_with_trampolines;
+
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ /* Test calling with basic integer types */
+ call0a (c, s, i, l);
+ call0b (s, i, l, c);
+ call0c (i, l, c, s);
+ call0d (l, c, s, i);
+ call0e (c, l, c, i, c, s, c, c);
+
+ /* Test calling with unsigned integer types */
+ call1a (uc, us, ui, ul);
+ call1b (us, ui, ul, uc);
+ call1c (ui, ul, uc, us);
+ call1d (ul, uc, us, ui);
+ call1e (uc, ul, uc, ui, uc, us, uc, uc);
+
+ /* Test calling with integral types mixed with floating point types */
+ call2a (c, f, s, d, i, f, l, d);
+ call2b (f, s, d, i, f, l, d, c);
+ call2c (s, d, i, f, l, d, c, f);
+ call2d (d, i, f, l, d, c, f, s);
+ call2e (i, f, l, d, c, f, s, d);
+ call2f (f, l, d, c, f, s, d, i);
+ call2g (l, d, c, f, s, d, i, f);
+ call2h (d, c, f, s, d, i, f, l);
+ call2i (c, f, c, c, d, c, c, c, f, s, c, d);
+
+ /* Test dereferencing pointers to various integral and floating types */
+
+ call3a (cp, sp, ip, lp);
+ call3b (ucp, usp, uip, ulp);
+ call3c (fp, dp);
+
+ /* Test dereferencing pointers to structs and unions */
+
+ call4a (stp);
+ un.u1 = 1;
+ call4b (unp);
+
+ /* Test calling with structures and unions. */
+
+ call5a (st);
+ un.u1 = 2;
+ call5b (un);
+
+ /* Test shuffling of args */
+
+ call6a (c, s, i, l, f, d, uc, us, ui, ul);
+ call7a (c, i, s, l, f, uc, d, us, ul, ui);
+
+ /* Test passing structures recursively. */
+
+ test_struct_args ();
+
+ localvars_after_alloca (c, s, i, l);
+
+ call_after_alloca (c, s, i, l);
+
+ /* This is for localvars_in_indirect_call. */
+ marker_indirect_call ();
+ /* The comment on the following two lines is used by funcargs.exp,
+ don't change it. */
+ (*pointer_to_call0a) (c, s, i, l); /* First step into call0a. */
+ (*pointer_to_call0a) (c, s, i, l); /* Second step into call0a. */
+ marker_call_with_trampolines ();
+ (*pointer_to_call_with_trampolines) (d); /* Test multiple trampolines. */
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/funcargs.exp b/gdb/testsuite/gdb.base/funcargs.exp
new file mode 100644
index 00000000000..2ed154a007b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/funcargs.exp
@@ -0,0 +1,1262 @@
+# Copyright 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "funcargs"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+#
+# Locate actual args; integral types.
+#
+
+proc integral_args {} {
+ global gdb_prompt
+ global det_file
+ global gcc_compiled
+
+ delete_breakpoints
+
+ gdb_breakpoint call0a
+ gdb_breakpoint call0b
+ gdb_breakpoint call0c
+ gdb_breakpoint call0d
+ gdb_breakpoint call0e
+
+ # Run; should stop at call0a and print actual arguments.
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_run_cmd
+ gdb_expect {
+ -re ".* call0a \\(c=97 'a', s=1, i=2, l=3\\) .*$gdb_prompt $" {
+ pass "run to call0a"
+ }
+ -re "$gdb_prompt $" { fail "run to call0a" ; gdb_suppress_tests }
+ timeout { fail "(timeout) run to call0a" ; gdb_suppress_tests }
+ }
+
+ # Print each arg as a double check to see if we can print
+ # them here as well as with backtrace.
+ gdb_test "print c" ".* = 97 'a'" "print c after run to call0a"
+ gdb_test "print s" ".* = 1" "print s after run to call0a"
+ gdb_test "print i" ".* = 2" "print i after run to call0a"
+ gdb_test "print l " ".* = 3" "print l after run to call0a"
+
+ # Continue; should stop at call0b and print actual arguments.
+ if [gdb_test "cont" ".* call0b \\(s=1, i=2, l=3, c=97 'a'\\) .*" "continue to call0b"] {
+ gdb_suppress_tests;
+ }
+
+ # Continue; should stop at call0c and print actual arguments.
+ if [gdb_test "cont" ".* call0c \\(i=2, l=3, c=97 'a', s=1\\) .*" "continue to call0c"] {
+ gdb_suppress_tests;
+ }
+
+ # Continue; should stop at call0d and print actual arguments.
+ if [gdb_test "cont" ".* call0d \\(l=3, c=97 'a', s=1, i=2\\) .*" "continue to call0d";] {
+ gdb_suppress_tests;
+ }
+
+ # Continue; should stop at call0e and print actual arguments.
+ if [gdb_test "cont" ".* call0e \\(c1=97 'a', l=3, c2=97 'a', i=2, c3=97 'a', s=1, c4=97 'a', c5=97 'a'\\) .*" "continue to call0e" ] {
+ gdb_suppress_tests;
+ }
+ gdb_stop_suppressing_tests;
+}
+
+#
+# Locate actual args; unsigned integral types.
+#
+
+proc unsigned_integral_args {} {
+ global gdb_prompt
+ global det_file
+ global gcc_compiled
+
+ delete_breakpoints
+
+ gdb_breakpoint call1a;
+ gdb_breakpoint call1b;
+ gdb_breakpoint call1c;
+ gdb_breakpoint call1d;
+ gdb_breakpoint call1e;
+
+ # Run; should stop at call1a and print actual arguments.
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_run_cmd
+ gdb_expect {
+ -re ".* call1a \\(uc=98 'b', us=6, ui=7, ul=8\\) .*$gdb_prompt $" {
+ pass "run to call1a"
+ }
+ -re "$gdb_prompt $" { fail "run to call1a" ; gdb_suppress_tests; }
+ timeout { fail "(timeout) run to call1a" ; gdb_suppress_tests; }
+ }
+
+ # Print each arg as a double check to see if we can print
+ # them here as well as with backtrace.
+ gdb_test "print uc" ".* = 98 'b'"
+ gdb_test "print us" ".* = 6"
+ gdb_test "print ui" ".* = 7"
+ gdb_test "print ul" ".* = 8"
+
+ # Continue; should stop at call1b and print actual arguments.
+ if [gdb_test "cont" ".* call1b \\(us=6, ui=7, ul=8, uc=98 'b'\\) .*" "continue to call1b"] {
+ gdb_suppress_tests;
+ }
+
+ # Continue; should stop at call1c and print actual arguments.
+ if [gdb_test "cont" ".* call1c \\(ui=7, ul=8, uc=98 'b', us=6\\) .*" "continue to call1c"] {
+ gdb_suppress_tests;
+ }
+
+ # Continue; should stop at call1d and print actual arguments.
+ if [gdb_test "cont" ".* call1d \\(ul=8, uc=98 'b', us=6, ui=7\\) .*" "continue to call1d"] {
+ gdb_suppress_tests;
+ }
+
+ # Continue; should stop at call1e and print actual arguments.
+ if [gdb_test "cont" ".* call1e \\(uc1=98 'b', ul=8, uc2=98 'b', ui=7, uc3=98 'b', us=6, uc4=98 'b', uc5=98 'b'\\) .*" "continue to call1e"] {
+ gdb_suppress_tests;
+ }
+ gdb_stop_suppressing_tests;
+}
+
+#
+# Locate actual args; integrals mixed with floating point.
+#
+
+proc float_and_integral_args {} {
+ global gdb_prompt
+ global det_file
+ global gcc_compiled
+ global hp_cc_compiler
+
+ delete_breakpoints
+
+ gdb_breakpoint call2a
+ gdb_breakpoint call2b
+ gdb_breakpoint call2c
+ gdb_breakpoint call2d
+ gdb_breakpoint call2e
+ gdb_breakpoint call2f
+ gdb_breakpoint call2g
+ gdb_breakpoint call2h
+
+ # Run; should stop at call2a and print actual arguments.
+
+ setup_xfail "i960-*-*" 1813
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" "mips-sgi-irix5*" }
+ # The debug info. for "f" is not correct. It's a known bug.
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ gdb_run_cmd
+ gdb_expect {
+ -re ".* call2a \\(c=97 'a', f1=4, s=1, d1=5, i=2, f2=4, l=3, d2=5\\) .*$gdb_prompt $" { pass "run to call2a" }
+ -re ".* call2a \\(c=97 'a', f1=.*, s=1, d1=5, i=2, f2=4, l=3, d2=5\\) .*$gdb_prompt $" { xfail "run to call2a" }
+ -re "$gdb_prompt $" { fail "run to call2a" ; gdb_suppress_tests; }
+ timeout { fail "(timeout) run to call2a" ; gdb_suppress_tests; }
+ }
+
+ # Print each arg as a double check to see if we can print
+ gdb_test "print c" ".* = 97 'a'" "print c after run to call2a"
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ gdb_test "print f1" ".* = 4" "print f1 after run to call2a"
+ gdb_test "print s" ".* = 1" "print s after run to call2a"
+ gdb_test "print d1" ".* = 5" "print d1 after run to call2a"
+ gdb_test "print i" ".* = 2" "print i after run to call2a"
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ gdb_test "print f2" ".* = 4" "print f2 after run to call2a"
+ gdb_test "print l" ".* = 3" "print l after run to call2a"
+ gdb_test "print d2" ".* = 5" "print d2 after run to call2a"
+
+ setup_xfail "rs6000-*-*"
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix*" }
+ # Continue; should stop at call2b and print actual arguments.
+ if [gdb_test "cont" ".* call2b \\(f1=4, s=1, d1=5, i=2, f2=4, l=3, d2=5, c=97 'a'\\) .*" "continue to call2b"] {
+ gdb_suppress_tests;
+ }
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ # Continue; should stop at call2c and print actual arguments.
+ if [gdb_test "cont" ".* call2c \\(s=1, d1=5, i=2, f2=4, l=3, d2=5, c=97 'a', f1=4\\) .*" "continue to call2c"] {
+ gdb_suppress_tests;
+ }
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ # Continue; should stop at call2d and print actual arguments.
+ if [gdb_test "cont" ".* call2d \\(d1=5, i=2, f2=4, l=3, d2=5, c=97 'a', f1=4, s=1\\) .*" "continue to call2d"] {
+ gdb_suppress_tests;
+ }
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ # Continue; should stop at call2e and print actual arguments.
+ if [gdb_test "cont" ".* call2e \\(i=2, f2=4, l=3, d2=5, c=97 'a', f1=4, s=1, d1=5\\) .*" "continue to call2e"] {
+ gdb_suppress_tests;
+ }
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ # Continue; should stop at call2f and print actual arguments.
+ if [gdb_test "cont" ".* call2f \\(f2=4, l=3, d2=5, c=97 'a', f1=4, s=1, d1=5, i=2\\) .*" "continue to call2f"] {
+ gdb_suppress_tests;
+ }
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ # Continue; should stop at call2g and print actual arguments.
+ if [gdb_test "cont" ".* call2g \\(l=3, d2=5, c=97 'a', f1=4, s=1, d1=5, i=2, f2=4\\) .*" "continue to call2g"] {
+ gdb_suppress_tests;
+ }
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ # Continue; should stop at call2h and print actual arguments.
+ if [gdb_test "cont" ".* call2h \\(d2=5, c=97 'a', f1=4, s=1, d1=5, i=2, f2=4, l=3\\) .*" "continue to call2h"] {
+ gdb_suppress_tests;
+ }
+
+ # monitor only allows 8 breakpoints; w89k board allows 10, so
+ # break them up into two groups.
+ delete_breakpoints
+ gdb_breakpoint call2i
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ # Continue; should stop at call2i and print actual arguments.
+ if [gdb_test "cont" ".* call2i \\(c1=97 'a', f1=4, c2=97 'a', c3=97 'a', d1=5, c4=97 'a', c5=97 'a', c6=97 'a', f2=4, s=1, c7=97 'a', d2=5\\) .*" "continue to call2i"] {
+ gdb_suppress_tests;
+ }
+ gdb_stop_suppressing_tests;
+}
+
+#
+# Locate actual args; dereference pointers to ints and floats.
+#
+
+proc pointer_args {} {
+ global gdb_prompt
+ global hex
+ global det_file
+
+ delete_breakpoints
+
+ gdb_breakpoint call3a
+ gdb_breakpoint call3b
+ gdb_breakpoint call3c
+
+ # Run; should stop at call3a and print actual arguments.
+ # Try dereferencing the arguments.
+
+ gdb_run_cmd
+ gdb_expect {
+ -re ".* call3a \\(cp=$hex \"a.*\", sp=$hex, ip=$hex, lp=$hex\\) .*$gdb_prompt $" { pass "run to call3a" }
+ -re "$gdb_prompt $" { fail "run to call3a" ; gdb_suppress_tests; }
+ timeout { fail "(timeout) run to call3a" ; gdb_suppress_tests; }
+ }
+
+ gdb_test "print *cp" ".* = 97 'a'"
+ gdb_test "print *sp" ".* = 1"
+ gdb_test "print *ip" ".* = 2"
+ gdb_test "print *lp" ".* = 3"
+
+ # Continue; should stop at call3b and print actual arguments.
+ # Try dereferencing the arguments.
+ if [gdb_test "cont" ".* call3b \\(ucp=$hex \"b.*\", usp=$hex, uip=$hex, ulp=$hex\\) .*" "continue to call3b"] {
+ gdb_suppress_tests;
+ }
+
+ gdb_test "print *ucp" ".* = 98 'b'"
+ gdb_test "print *usp" ".* = 6"
+ gdb_test "print *uip" ".* = 7"
+ gdb_test "print *ulp" ".* = 8"
+
+ # Continue; should stop at call3c and print actual arguments.
+ # Try dereferencing the arguments.
+ if [gdb_test "cont" ".* call3c \\(fp=$hex, dp=$hex\\) .*" "continue to call3c"] {
+ gdb_suppress_tests;
+ }
+
+ gdb_test "print *fp" ".* = 4"
+ gdb_test "print *dp" ".* = 5"
+
+# pass "locate actual args, pointer types"
+ gdb_stop_suppressing_tests;
+}
+
+#
+# Locate actual args; structures and unions passed by reference.
+#
+
+proc structs_by_reference {} {
+ global gdb_prompt
+ global hex
+ global det_file
+ global target_sizeof_int
+ global target_sizeof_long
+ global target_bigendian_p
+
+ delete_breakpoints
+
+ gdb_breakpoint call4a
+ gdb_breakpoint call4b
+
+ # Run; should stop at call4a and print actual arguments.
+ # Try dereferencing the arguments.
+
+ gdb_run_cmd
+ gdb_expect {
+ -re ".* call4a \\(stp=$hex\\) .*$gdb_prompt $" {
+ pass "run to call4a"
+ }
+ -re "$gdb_prompt $" { fail "run to call4a" ; gdb_suppress_tests; }
+ timeout { fail "(timeout) run to call4a" ; gdb_suppress_tests; }
+ }
+
+ gdb_test "print *stp" ".* = \{s1 = 101, s2 = 102\}"
+
+ # Continue; should stop at call4b and print actual arguments.
+
+ gdb_test "cont" ".* call4b \\(unp=$hex\\) .*" "continue to call4b"
+
+ # Try dereferencing the arguments.
+ if { $target_sizeof_long == $target_sizeof_int } {
+ gdb_test "print *unp" ".* = \{u1 = 1, u2 = 1\}" \
+ "print *unp (sizeof long == sizeof int)"
+ } elseif { ! $target_bigendian_p } {
+ gdb_test "print *unp" ".* = \{u1 = 1, u2 = 1\}" \
+ "print *unp (little-endian, sizeof long != sizeof int)"
+ } elseif { $target_sizeof_long == 8 && $target_sizeof_int == 4 } {
+ gdb_test "print *unp" ".* = \{u1 = 1, u2 = 4294967296\}" \
+ "print *unp (big-endian, sizeof long == 8, sizeof int = 4)"
+ } elseif { $target_sizeof_long == 4 && $target_sizeof_int == 2 } {
+ gdb_test "print *unp" ".* = \{u1 = 1, u2 = 65536\}" \
+ "print *unp (big-endian, sizeof long == 4, sizeof int = 2)"
+ } else {
+ fail "print *unp (unknown case)"
+ }
+
+ pass "locate actual args, structs/unions passed by reference"
+ gdb_stop_suppressing_tests;
+}
+
+#
+# Locate actual args; structures and unions passed by value.
+#
+
+proc structs_by_value {} {
+ global gdb_prompt
+ global hex
+ global det_file
+ global target_sizeof_int
+ global target_sizeof_long
+ global target_bigendian_p
+
+ delete_breakpoints
+
+ gdb_breakpoint call5a
+ gdb_breakpoint call5b
+
+ # Run; should stop at call5a and print actual arguments.
+ # Try dereferencing the arguments.
+
+ gdb_run_cmd
+ gdb_expect {
+ -re ".* call5a \\(st=\{s1 = 101, s2 = 102\}\\) .*$gdb_prompt $" {
+ pass "run to call5a"
+ }
+ -re "$gdb_prompt $" { fail "run to call5a" ; gdb_suppress_tests; }
+ timeout { fail "(timeout) run to call5a" ; gdb_suppress_tests; }
+ }
+
+ gdb_test "print st" ".* = \{s1 = 101, s2 = 102\}"
+
+ # Continue; should stop at call5b and print actual arguments.
+ if { $target_sizeof_long == $target_sizeof_int } {
+ gdb_test "cont" ".* call5b \\(un=\{u1 = 2, u2 = 2\}\\) .*" \
+ "continue to call5b (sizeof long == sizeof int)"
+ } elseif { ! $target_bigendian_p } {
+ gdb_test "cont" ".* call5b \\(un=\{u1 = 2, u2 = 2\}\\) .*" \
+ "continue to call5b (little-endian, sizeof long != sizeof int)"
+ } elseif { $target_sizeof_long == 8 && $target_sizeof_int == 4 } {
+ gdb_test "cont" ".* call5b \\(un=\{u1 = 2, u2 = 8589934592\}\\) .*" \
+ "continue to call5b (big-endian, sizeof long == 8, sizeof int = 4)"
+ } elseif { $target_sizeof_long == 4 && $target_sizeof_int == 2 } {
+ gdb_test "cont" ".* call5b \\(un=\{u1 = 2, u2 = 131072\}\\) .*" \
+ "continue to call5b (big-endian, sizeof long == 4, sizeof int = 2)"
+ } else {
+ fail "continue to call5b (unknown case)"
+ }
+
+ # Try dereferencing the arguments.
+ if { $target_sizeof_long == $target_sizeof_int } {
+ gdb_test "print un" ".* = \{u1 = 2, u2 = 2\}" \
+ "print un (sizeof long == sizeof int)"
+ } elseif { ! $target_bigendian_p } {
+ gdb_test "print un" ".* = \{u1 = 2, u2 = 2\}" \
+ "print un (little-endian, sizeof long != sizeof int)"
+ } elseif { $target_sizeof_long == 8 && $target_sizeof_int == 4 } {
+ gdb_test "print un" ".* = \{u1 = 2, u2 = 8589934592\}" \
+ "print un (big-endian, sizeof long == 8, sizeof int = 4)"
+ } elseif { $target_sizeof_long == 4 && $target_sizeof_int == 2 } {
+ gdb_test "print un" ".* = \{u1 = 2, u2 = 131072\}" \
+ "print un (big-endian, sizeof long == 4, sizeof int = 2)"
+ } else {
+ fail "print un (unknown case)"
+ }
+
+ gdb_stop_suppressing_tests;
+}
+
+#
+# Locate actual args; discard, shuffle, and call
+#
+
+proc discard_and_shuffle {} {
+ global gdb_prompt
+ global hex
+ global decimal
+ global det_file
+ global gcc_compiled
+ global hp_cc_compiler
+
+ delete_breakpoints
+
+ gdb_breakpoint call6a
+ gdb_breakpoint call6b
+ gdb_breakpoint call6c
+ gdb_breakpoint call6d
+ gdb_breakpoint call6e
+ gdb_breakpoint call6f
+ gdb_breakpoint call6g
+ gdb_breakpoint call6h
+
+ # Run; should stop at call6a and print actual arguments.
+ # Print backtrace.
+
+ gdb_run_cmd
+ gdb_expect {
+ -re ".*Breakpoint $decimal, call6a .*$gdb_prompt $" { pass "run to call6a" }
+ -re "$gdb_prompt $" { fail "run to call6a" ; gdb_suppress_tests; }
+ timeout { fail "(timeout) run to call6a" ; gdb_suppress_tests; }
+ }
+
+ setup_xfail "rs6000-*-*"
+
+ if {!$gcc_compiled} {
+ setup_xfail "mips-sgi-irix5*"
+ }
+
+ # The debug info. for "f" is not correct. It's a known bug.
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ send_gdb "backtrace 100\n"
+ gdb_expect {
+ -re "backtrace 100\[\r\n\]+
+.* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\r
+.* main \\(.*\\) .*\r
+$gdb_prompt $" {
+ pass "backtrace from call6a"
+ }
+ -re "backtrace 100\[\r\n\]+
+.* call6a \\(c=97 'a', s=1, i=2, l=3, f=.*, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\r
+.* main \\(.*\\) .*\r
+$gdb_prompt $" {
+ xfail "backtrace from call6a"
+ }
+ -re "$gdb_prompt $" {
+ fail "backtrace from call6a"
+ gdb_suppress_tests
+ }
+ timeout {
+ fail "(timeout) backtrace from call6a"
+ gdb_suppress_tests
+ }
+ }
+
+ # Continue; should stop at call6b and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call6b
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ send_gdb "backtrace 100\n"
+ if [gdb_expect_list "backtrace from call6b" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#1 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#2 .* main \\(.*\\) "
+ } ] {
+ gdb_suppress_tests;
+ }
+
+ # Continue; should stop at call6c and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call6c
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ send_gdb "backtrace 100\n"
+ if [gdb_expect_list "backtrace from call6c" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#1 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#2 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#3 .* main \\(.*\\) "
+ } ] {
+ gdb_suppress_tests;
+ }
+ # Continue; should stop at call6d and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call6d
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ send_gdb "backtrace 100\n"
+ if [gdb_expect_list "backtrace from call6d" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#1 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#2 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#3 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#4 .* main \\(.*\\) "
+ } ] {
+ gdb_suppress_tests;
+ }
+
+ # Continue; should stop at call6e and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call6e
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ send_gdb "backtrace 100\n"
+ if [gdb_expect_list "backtrace from call6e" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#1 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#2 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#3 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#4 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#5 .* main \\(.*\\) "
+ } ] {
+ gdb_suppress_tests;
+ }
+
+ # Continue; should stop at call6f and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call6f
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ send_gdb "backtrace 100\n"
+ if [gdb_expect_list "backtrace from call6f" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#1 .* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#2 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#3 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#4 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#5 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#6 .* main \\(.*\\) "
+ } ] {
+ gdb_suppress_tests;
+ }
+
+ # Continue; should stop at call6g and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call6g
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ send_gdb "backtrace 100\n"
+ if [gdb_expect_list "backtrace from call6g" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#1 .* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#2 .* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#3 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#4 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#5 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#6 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#7 .* main \\(.*\\) "
+ } ] {
+ gdb_suppress_tests;
+ }
+
+ # Continue; should stop at call6h and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call6h
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ send_gdb "backtrace 100\n"
+ if [gdb_expect_list "backtrace from call6h" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call6h \\(us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#1 .* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#2 .* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#3 .* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#4 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#5 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#6 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#7 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#8 .* main \\(.*\\) "
+ } ] {
+ gdb_suppress_tests;
+ }
+
+ # monitor only allows 8 breakpoints; w89k board allows 10, so
+ # break them up into two groups.
+ delete_breakpoints
+ gdb_breakpoint call6i
+ gdb_breakpoint call6j
+ gdb_breakpoint call6k
+
+ # Continue; should stop at call6i and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call6i
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ send_gdb "backtrace 100\n"
+ if [gdb_expect_list "backtrace from call6i" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call6i \\(ui=7, ul=8\\) "
+ ".*\[\r\n\]#1 .* call6h \\(us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#2 .* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#3 .* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#4 .* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#5 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#6 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#7 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#8 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#9 .* main \\(.*\\) "
+ } ] {
+ gdb_suppress_tests;
+ }
+
+ # Continue; should stop at call6j and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call6j
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ send_gdb "backtrace 100\n"
+ if [gdb_expect_list "backtrace from call6j" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call6j \\(ul=8\\) "
+ ".*\[\r\n\]#1 .* call6i \\(ui=7, ul=8\\) "
+ ".*\[\r\n\]#2 .* call6h \\(us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#3 .* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#4 .* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#5 .* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#6 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#7 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#8 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#9 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#10 .* main \\(.*\\) "
+ } ] {
+ gdb_suppress_tests;
+ }
+
+ # Continue; should stop at call6k and print actual arguments.
+ # Print backtrace.
+ # This fails on i960-*-vxworks because gdb gets confused by
+ # breakpoints on adjacent instructions.
+ setup_xfail "i960-*-vxworks" 1786
+ gdb_continue call6k
+
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ send_gdb "backtrace 100\n"
+ if [gdb_expect_list "backtrace from call6k" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call6k \\(\\) "
+ ".*\[\r\n\]#1 .* call6j \\(ul=8\\) "
+ ".*\[\r\n\]#2 .* call6i \\(ui=7, ul=8\\) "
+ ".*\[\r\n\]#3 .* call6h \\(us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#4 .* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#5 .* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#6 .* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#7 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#8 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#9 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#10 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) "
+ ".*\[\r\n\]#11 .* main \\(.*\\) "
+ } ] {
+ gdb_suppress_tests;
+ }
+ gdb_stop_suppressing_tests;
+}
+
+
+#
+# Locate actual args; shuffle round robin and call
+#
+
+proc shuffle_round_robin {} {
+ global gdb_prompt
+ global hex
+ global decimal
+ global det_file
+ global gcc_compiled
+ global hp_cc_compiler
+
+ delete_breakpoints
+
+ gdb_breakpoint call7a
+ gdb_breakpoint call7b
+ gdb_breakpoint call7c
+ gdb_breakpoint call7d
+ gdb_breakpoint call7e
+ gdb_breakpoint call7f
+ gdb_breakpoint call7g
+ gdb_breakpoint call7h
+
+ # Run; should stop at call7a and print actual arguments.
+ # Print backtrace.
+
+ gdb_run_cmd
+ gdb_expect {
+ -re ".*Breakpoint $decimal, call7a .*$gdb_prompt $" {
+ pass "run to call7a"
+ }
+ -re "$gdb_prompt $" { fail "run to call7a" ; gdb_suppress_tests; }
+ timeout { fail "(timeout) run to call7a" ; gdb_suppress_tests; }
+ }
+
+ setup_xfail "i960-*-*" 1813
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" "mips-sgi-irix5*" }
+ # The debug info. for "f" is not correct. It's a known bug.
+ if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*}
+ send_gdb "backtrace 100\n"
+ gdb_expect {
+ -re "backtrace 100\[\r\n\]+
+.* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) .*\r
+.* main \\(.*\\) .*\r
+$gdb_prompt $" {
+ pass "backtrace from call7a"
+ }
+ -re "backtrace 100\[\r\n\]+
+.* call7a \\(c=97 'a', i=2, s=1, l=3, f=.*, uc=98 'b', d=5, us=6, ul=8, ui=7\\) .*\r
+.* main \\(.*\\) .*\r
+$gdb_prompt $" {
+ xfail "backtrace from call7a"
+ }
+ -re "$gdb_prompt $" { fail "backtrace from call7a" ; return }
+ timeout { fail "(timeout) backtrace from call7a" ; return }
+ }
+
+ # Continue; should stop at call7b and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call7b
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+
+ send_gdb "backtrace 100\n"
+ gdb_expect_list "backtrace from call7b" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) "
+ ".*\[\r\n\]#1 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) "
+ ".*\[\r\n\]#2 .* main \\(.*\\) "
+ }
+
+ # Continue; should stop at call7c and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call7c
+
+ send_gdb "backtrace 100\n"
+ gdb_expect_list "backtrace from call7c" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) "
+ ".*\[\r\n\]#1 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) "
+ ".*\[\r\n\]#2 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) "
+ ".*\[\r\n\]#3 .* main \\(.*\\) "
+ }
+
+ # Continue; should stop at call7d and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call7d
+
+ send_gdb "backtrace 100\n"
+ gdb_expect_list "backtrace from call7d" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) "
+ ".*\[\r\n\]#1 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) "
+ ".*\[\r\n\]#2 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) "
+ ".*\[\r\n\]#3 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) "
+ ".*\[\r\n\]#4 .* main \\(.*\\) "
+ }
+
+ gdb_continue call7e
+
+ send_gdb "backtrace 100\n"
+ gdb_expect_list "backtrace from call7e" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) "
+ ".*\[\r\n\]#1 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) "
+ ".*\[\r\n\]#2 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) "
+ ".*\[\r\n\]#3 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) "
+ ".*\[\r\n\]#4 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) "
+ ".*\[\r\n\]#5 .* main \\(.*\\) "
+ }
+
+ # Continue; should stop at call7f and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call7f
+
+ send_gdb "backtrace 100\n"
+ gdb_expect_list "backtrace from call7f" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) "
+ ".*\[\r\n\]#1 .* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) "
+ ".*\[\r\n\]#2 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) "
+ ".*\[\r\n\]#3 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) "
+ ".*\[\r\n\]#4 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) "
+ ".*\[\r\n\]#5 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) "
+ ".*\[\r\n\]#6 .* main \\(.*\\) "
+ }
+
+ # Continue; should stop at call7g and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call7g
+
+ send_gdb "backtrace 100\n"
+ gdb_expect_list "backtrace from call7g" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) "
+ ".*\[\r\n\]#1 .* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) "
+ ".*\[\r\n\]#2 .* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) "
+ ".*\[\r\n\]#3 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) "
+ ".*\[\r\n\]#4 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) "
+ ".*\[\r\n\]#5 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) "
+ ".*\[\r\n\]#6 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) "
+ ".*\[\r\n\]#7 .* main \\(.*\\) "
+ }
+
+ gdb_continue call7h
+
+ send_gdb "backtrace 100\n"
+ gdb_expect_list "backtrace from call7h" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call7h \\(us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5\\) "
+ ".*\[\r\n\]#1 .* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) "
+ ".*\[\r\n\]#2 .* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) "
+ ".*\[\r\n\]#3 .* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) "
+ ".*\[\r\n\]#4 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) "
+ ".*\[\r\n\]#5 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) "
+ ".*\[\r\n\]#6 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) "
+ ".*\[\r\n\]#7 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) "
+ ".*\[\r\n\]#8 .* main \\(.*\\) "
+ }
+
+ # monitor only allows 8 breakpoints; w89k board allows 10, so
+ # break them up into two groups.
+ delete_breakpoints
+ gdb_breakpoint call7i
+ gdb_breakpoint call7j
+ gdb_breakpoint call7k
+
+ # Continue; should stop at call7i and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call7i
+
+ send_gdb "backtrace 100\n"
+ gdb_expect_list "backtrace from call7i" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call7i \\(ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6\\) "
+ ".*\[\r\n\]#1 .* call7h \\(us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5\\) "
+ ".*\[\r\n\]#2 .* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) "
+ ".*\[\r\n\]#3 .* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) "
+ ".*\[\r\n\]#4 .* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) "
+ ".*\[\r\n\]#5 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) "
+ ".*\[\r\n\]#6 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) "
+ ".*\[\r\n\]#7 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) "
+ ".*\[\r\n\]#8 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) "
+ ".*\[\r\n\]#9 .* main \\(.*\\) "
+ }
+
+ # Continue; should stop at call7j and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call7j
+
+ send_gdb "backtrace 100\n"
+ gdb_expect_list "backtrace from call7j" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call7j \\(ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8\\) "
+ ".*\[\r\n\]#1 .* call7i \\(ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6\\) "
+ ".*\[\r\n\]#2 .* call7h \\(us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5\\) "
+ ".*\[\r\n\]#3 .* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) "
+ ".*\[\r\n\]#4 .* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) "
+ ".*\[\r\n\]#5 .* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) "
+ ".*\[\r\n\]#6 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) "
+ ".*\[\r\n\]#7 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) "
+ ".*\[\r\n\]#8 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) "
+ ".*\[\r\n\]#9 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) "
+ ".*\[\r\n\]#10 .* main \\(.*\\) "
+ }
+
+ # Continue; should stop at call7k and print actual arguments.
+ # Print backtrace.
+
+ gdb_continue call7k
+
+ if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix*" }
+ send_gdb "backtrace 100\n"
+ gdb_expect_list "backtrace from call7k" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* call7k \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) "
+ ".*\[\r\n\]#1 .* call7j \\(ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8\\) "
+ ".*\[\r\n\]#2 .* call7i \\(ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6\\) "
+ ".*\[\r\n\]#3 .* call7h \\(us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5\\) "
+ ".*\[\r\n\]#4 .* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) "
+ ".*\[\r\n\]#5 .* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) "
+ ".*\[\r\n\]#6 .* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) "
+ ".*\[\r\n\]#7 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) "
+ ".*\[\r\n\]#8 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) "
+ ".*\[\r\n\]#9 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) "
+ ".*\[\r\n\]#10 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) "
+ ".*\[\r\n\]#11 .* main \\(.*\\) "
+ }
+ gdb_stop_suppressing_tests;
+}
+
+#
+# Locate actual args; recursive passing of structs by value
+#
+
+proc recursive_structs_by_value {} {
+ global gdb_prompt
+ global hex
+ global decimal
+ global det_file
+
+ delete_breakpoints
+
+ gdb_breakpoint hitbottom
+
+ # Run; should stop at hitbottom and print actual arguments.
+ # Print backtrace.
+ gdb_run_cmd
+ gdb_expect {
+ -re ".*Breakpoint $decimal, hitbottom .*$gdb_prompt $" { pass "run to hitbottom" }
+ -re "$gdb_prompt $" { fail "run to hitbottom" ; gdb_suppress_tests; }
+ timeout { fail "(timeout) run to hitbottom" ; gdb_suppress_tests; }
+ }
+
+ if ![istarget sparclet-*-*] {
+ send_gdb "backtrace 100\n"
+ gdb_expect_list "recursive passing of structs by value" ".*$gdb_prompt $" {
+ ".*\[\r\n\]#0 .* hitbottom \\(\\) "
+ ".*\[\r\n\]#1 .* recurse \\(a=\{s = 0, i = 0, l = 0\}, depth=0\\) "
+ ".*\[\r\n\]#2 .* recurse \\(a=\{s = 1, i = 1, l = 1\}, depth=1\\) "
+ ".*\[\r\n\]#3 .* recurse \\(a=\{s = 2, i = 2, l = 2\}, depth=2\\) "
+ ".*\[\r\n\]#4 .* recurse \\(a=\{s = 3, i = 3, l = 3\}, depth=3\\) "
+ ".*\[\r\n\]#5 .* recurse \\(a=\{s = 4, i = 4, l = 4\}, depth=4\\) "
+ ".*\[\r\n\]#6 .* test_struct_args \\(\\) "
+ ".*\[\r\n\]#7 .* main \\(.*\\) "
+ }
+ } else {
+ fail "recursive passing of structs by value (sparclet)"
+ }
+ gdb_stop_suppressing_tests;
+}
+
+proc funcargs_reload { } {
+ global objdir
+ global subdir
+ global binfile
+ global srcdir
+
+ if [istarget "mips-idt-*"] {
+ # Restart because IDT/SIM runs out of file descriptors.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+ }
+}
+
+#
+# Test for accessing local stack variables in functions which call alloca
+#
+proc localvars_after_alloca { } {
+ global gdb_prompt
+ global hex
+ global decimal
+ global gcc_compiled
+
+ if { ! [ runto localvars_after_alloca ] } then { gdb_suppress_tests; }
+
+ # Print each arg as a double check to see if we can print
+ # them here as well as with backtrace.
+
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "print c" " = 97 'a'" "print c after runto localvars_after_alloca"
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "print s" " = 1" "print s after runto localvars_after_alloca"
+ gdb_test "print i" " = 2" "print i after runto localvars_after_alloca"
+ gdb_test "print l" " = 3" "print l after runto localvars_after_alloca"
+
+ # Lame regexp.
+ gdb_test "next" ".*" "next in localvars_after_alloca()"
+
+ # Print each arg as a double check to see if we can print
+ # them here as well as with backtrace.
+
+ gdb_test "print c" " = 97 'a'" "print c in localvars_after_alloca"
+ gdb_test "print s" " = 1" "print s in localvars_after_alloca"
+ gdb_test "print i" " = 2" "print i in localvars_after_alloca"
+ gdb_test "print l" " = 3" "print l in localvars_after_alloca"
+
+ gdb_test "backtrace 8" "#0.*localvars_after_alloca \\(c=97 'a', s=1, i=2, l=3\\).*#1.*main.*" "backtrace after alloca"
+ gdb_stop_suppressing_tests;
+}
+
+proc call_after_alloca { } {
+ global gdb_prompt
+ global hex
+ global decimal
+ global gcc_compiled
+
+ if { ! [ runto call_after_alloca_subr ] } then { gdb_suppress_tests; }
+
+ # Print each arg as a double check to see if we can print
+ # them here as well as with backtrace.
+
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "print c" " = 97 'a'" "print c in call_after_alloca"
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "print s" " = 1" "print s in call_after_alloca"
+ gdb_test "print i" " = 2" "print i in call_after_alloca"
+ gdb_test "print l" " = 3" "print l in call_after_alloca"
+
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "backtrace 8" "#0.*call_after_alloca_subr \\(c=97 'a', s=1, i=2, l=3, uc=98 'b', us=11, ui=12, ul=13\\).*#1.*call_after_alloca \\(c=97 'a', s=1, i=2, l=3\\).*#2.*main.*" "backtrace from call_after_alloca_subr"
+ gdb_stop_suppressing_tests;
+}
+
+#
+# Test for accessing local stack variables, backtraces, finish,
+# and finally stepping into indirect calls. The point is that on the PA
+# these use a funky `dyncall' mechanism which GDB needs to know about.
+#
+proc localvars_in_indirect_call { } {
+ global gdb_prompt
+ global hex
+ global decimal
+ global gcc_compiled
+
+ # Can not use "runto call0a" as call0a is called several times
+ # during single run. Instead stop in a marker function and
+ # take control from there.
+ if { ! [ runto marker_indirect_call ] } then { gdb_suppress_tests; }
+
+ # break on the next call to call0a, then delete all the breakpoints
+ # and start testing.
+ gdb_breakpoint call0a
+ gdb_continue call0a
+ delete_breakpoints
+
+ # Print each arg as a double check to see if we can print
+ # them here as well as with backtrace.
+
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "print c" " = 97 'a'" "print c in localvars_in_indirect_call"
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "print s" " = 1" "print s in localvars_in_indirect_call"
+ gdb_test "print i" " = 2" "print i in localvars_in_indirect_call"
+ gdb_test "print l" " = 3" "print l in localvars_in_indirect_call"
+
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "backtrace 8" \
+ "#0.*call0a \\(c=97 'a', s=1, i=2, l=3\\).*#1.*main.*" \
+ "backtrace in indirectly called function"
+
+ #
+ # "finish" brings us back to main. We then will try to step through
+ # the second indirect call.
+ # On some targets (e.g. m68k) gdb will stop from the finish in midline
+ # of the first indirect call. This is due to stack adjustment instructions
+ # after the indirect call. In these cases we will step till we hit the
+ # second indirect call.
+ #
+
+ send_gdb "finish\n"
+ gdb_expect {
+ -re "\\(\\*pointer_to_call0a\\) \\(c, s, i, l\\);.*First.*$gdb_prompt $" {
+#On hppa2.0w-hp-hpux11.00, gdb finishes at one line earlier than
+#hppa1.1-hp-hpux11.00. Therefore, an extra "step" is necessary to continue the test.
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re ".*\\(\\*pointer_to_call0a\\) \\(c, s, i, l\\);.*Second.*$gdb_prompt $" {
+ pass "finish from indirectly called function"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "finish from indirectly called function"
+ gdb_suppress_tests;
+ }
+ default { fail "finish from indirectly called function" ; gdb_suppress_tests; }
+ }
+
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "step" "call0a \\(c=97 'a', s=1, i=2, l=3\\).*" \
+ "stepping into indirectly called function"
+ gdb_stop_suppressing_tests;
+}
+
+#
+# Test for stepping into indirect calls which may have trampolines (possibly
+# cascaded) on both the call path and the gdb_suppress_tests; path.
+# to handle trampolines.
+#
+proc test_stepping_over_trampolines { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ # Stop in a marker function and take control from there.
+ if { ! [ runto marker_call_with_trampolines ] } then { gdb_suppress_tests; }
+
+ # Cater for gdb stopping in midline, see comment for finish above.
+ send_gdb "finish\n"
+ gdb_expect {
+ -re "marker_call_with_trampolines ..;.*$gdb_prompt $" {
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re "pointer_to_call_with_trampolines.*$gdb_prompt $" {
+ pass "finish from marker_call_with_trampolines"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "finish from marker_call_with_trampolines"
+ }
+ default { fail "finish from marker_call_with_trampolines" ; gdb_suppress_tests; }
+ }
+
+ # Try to step into the target function.
+ gdb_test "step" "call_with_trampolines \\(d1=5\\).*" \
+ "stepping into function called with trampolines"
+
+ # Make we can backtrace and the argument looks correct. */
+ gdb_test "backtrace 8" "#0.*call_with_trampolines \\(d1=5\\).*1.*main.*" \
+ "backtrace through call with trampolines"
+
+ # Make sure we can get back to main.
+ # Stepping back to main might stop again after the gdb_suppress_tests; statement
+ # or immediately transfer control back to main if optimizations
+ # are performed.
+ send_gdb "step\n"
+ gdb_expect {
+ -re "main .* at.*$gdb_prompt $" {
+ pass "stepping back to main from function called with trampolines" ;
+ gdb_suppress_tests
+ }
+ -re "\}.*End of call_with_trampolines.*$gdb_prompt $" {
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" {
+ fail "stepping back to main from function called with trampolines"
+ }
+ default { fail "stepping back to main from function called with trampolines" ; gdb_suppress_tests; }
+ }
+ gdb_stop_suppressing_tests;
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if [istarget "mips*tx39-*"] {
+ set timeout 300
+} elseif [istarget "hppa*-hp-hpux*"] then {
+ set timeout 240
+} else {
+ set timeout 60
+}
+
+# Determine expected output for unsigned long variables,
+# the output varies with sizeof (unsigned long).
+
+set target_sizeof_long 4
+send_gdb "print sizeof (long)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 4.*$gdb_prompt $" { }
+ -re ".\[0-9\]* = 8.*$gdb_prompt $" { set target_sizeof_long 8 }
+ -re ".*$gdb_prompt $" {
+ fail "getting sizeof long"
+ }
+ default { fail "(timeout) getting sizeof long" }
+}
+
+set target_sizeof_int 4
+send_gdb "print sizeof (int)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 2.*$gdb_prompt $" { set target_sizeof_int 2 }
+ -re ".\[0-9\]* = 4.*$gdb_prompt $" { }
+ -re ".\[0-9\]* = 8.*$gdb_prompt $" { set target_sizeof_int 8 }
+ -re ".*$gdb_prompt $" {
+ fail "getting sizeof unsigned long"
+ }
+ default { fail "(timeout) getting sizeof int" }
+}
+
+set target_bigendian_p 1
+send_gdb "show endian\n"
+gdb_expect {
+ -re ".*little endian.*$gdb_prompt $" { set target_bigendian_p 0 }
+ -re ".*big endian.*$gdb_prompt $" { }
+ -re ".*$gdb_prompt $" {
+ fail "getting target endian"
+ }
+ default { fail "(timeout) getting target endian" }
+}
+
+# Perform tests
+
+integral_args
+funcargs_reload
+unsigned_integral_args
+funcargs_reload
+if {![target_info exists gdb,skip_float_tests]} {
+ float_and_integral_args
+}
+funcargs_reload
+pointer_args
+funcargs_reload
+structs_by_reference
+funcargs_reload
+structs_by_value
+funcargs_reload
+discard_and_shuffle
+funcargs_reload
+shuffle_round_robin
+funcargs_reload
+recursive_structs_by_value
+funcargs_reload
+localvars_after_alloca
+funcargs_reload
+call_after_alloca
+funcargs_reload
+localvars_in_indirect_call
+funcargs_reload
+test_stepping_over_trampolines
diff --git a/gdb/testsuite/gdb.base/gcore.c b/gdb/testsuite/gdb.base/gcore.c
new file mode 100644
index 00000000000..af09dced7e1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gcore.c
@@ -0,0 +1,52 @@
+/*
+ * Test GDB's ability to save and reload a corefile.
+ */
+
+#include <stdlib.h>
+
+int extern_array[4] = {1, 2, 3, 4};
+static int static_array[4] = {5, 6, 7, 8};
+static int un_initialized_array[4];
+static char *heap_string;
+
+void
+terminal_func ()
+{
+ return;
+}
+
+void
+array_func ()
+{
+ int local_array[4];
+ int i;
+
+ heap_string = (char *) malloc (80);
+ strcpy (heap_string, "I'm a little teapot, short and stout...");
+ for (i = 0; i < 4; i++)
+ {
+ un_initialized_array[i] = extern_array[i] + 8;
+ local_array[i] = extern_array[i] + 12;
+ }
+ terminal_func ();
+}
+
+#ifdef PROTOTYPES
+int factorial_func (int value)
+#else
+int factorial_func (value)
+ int value;
+#endif
+{
+ if (value > 1) {
+ value *= factorial_func (value - 1);
+ }
+ array_func ();
+ return (value);
+}
+
+main()
+{
+ factorial_func (6);
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/gcore.exp b/gdb/testsuite/gdb.base/gcore.exp
new file mode 100644
index 00000000000..f8d5baac614
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gcore.exp
@@ -0,0 +1,220 @@
+# Copyright 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@redhat.com)
+# This is a test for the gdb command "generate-core-file".
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "gcore"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Does this gdb support gcore?
+send_gdb "help gcore\n"
+gdb_expect {
+ -re "Undefined command: .gcore.*$gdb_prompt $" {
+ # gcore command not supported -- nothing to test here.
+ unsupported "gdb does not support gcore on this target"
+ return -1;
+ }
+ -re "Save a core file .*$gdb_prompt $" {
+ pass "help gcore"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "help gcore"
+ }
+ timeout {
+ fail "help gcore (timeout)"
+ }
+}
+
+if { ! [ runto main ] } then {
+ gdb_suppress_entire_file "Run to main failed, so all tests in this file will automatically fail."
+}
+
+proc capture_command_output { command prefix } {
+ global gdb_prompt
+ global expect_out
+
+ set output_string ""
+ send_gdb "$command\n"
+ gdb_expect {
+ -re "${command}\[\r\n\]+${prefix}(.*)\[\r\n\]+$gdb_prompt $" {
+ set output_string $expect_out(1,string)
+ }
+ default {
+ fail "capture_command_output failed on $command."
+ }
+ }
+ return $output_string
+}
+
+gdb_test "break terminal_func" "Breakpoint .* at .*${srcfile}, line .*" \
+ "set breakpoint at terminal_func"
+
+gdb_test "continue" "Breakpoint .* terminal_func.*" \
+ "continue to terminal_func"
+
+set print_prefix ".\[0123456789\]* = "
+
+set pre_corefile_backtrace [capture_command_output "backtrace" ""]
+set pre_corefile_regs [capture_command_output "info registers" ""]
+set pre_corefile_allregs [capture_command_output "info all-reg" ""]
+set pre_corefile_static_array \
+ [capture_command_output "print static_array" "$print_prefix"]
+set pre_corefile_uninit_array \
+ [capture_command_output "print un_initialized_array" "$print_prefix"]
+set pre_corefile_heap_string \
+ [capture_command_output "print heap_string" "$print_prefix"]
+set pre_corefile_local_array \
+ [capture_command_output "print array_func::local_array" "$print_prefix"]
+set pre_corefile_extern_array \
+ [capture_command_output "print extern_array" "$print_prefix"]
+
+gdb_test "gcore ${objdir}/${subdir}/gcore.test" \
+ "Saved corefile ${objdir}/${subdir}/gcore.test" \
+ "save a corefile"
+
+# Now restart gdb and load the corefile.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+send_gdb "core ${objdir}/${subdir}/gcore.test\n"
+gdb_expect {
+ -re ".* is not a core dump:.*$gdb_prompt $" {
+ fail "re-load generated corefile (bad file format)"
+ # No use proceeding from here.
+ return;
+ }
+ -re ".*: No such file or directory.*$gdb_prompt $" {
+ fail "re-load generated corefile (file not found)"
+ # No use proceeding from here.
+ return;
+ }
+ -re ".*Couldn't find .* registers in core file.*$gdb_prompt $" {
+ fail "re-load generated corefile (incomplete note section)"
+ }
+ -re "Core was generated by .*$gdb_prompt $" {
+ pass "re-load generated corefile"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "re-load generated corefile"
+ }
+ timeout {
+ fail "re-load generated corefile (timeout)"
+ }
+}
+
+send_gdb "where\n"
+gdb_expect_list "where in corefile" ".*$gdb_prompt $" {
+ ".*\[\r\n\]+#0 .* terminal_func \\(\\) at "
+ ".*\[\r\n\]+#1 .* array_func \\(\\) at "
+ ".*\[\r\n\]+#2 .* factorial_func \\(value=1\\) at "
+ ".*\[\r\n\]+#3 .* factorial_func \\(value=2\\) at "
+ ".*\[\r\n\]+#4 .* factorial_func \\(value=3\\) at "
+ ".*\[\r\n\]+#5 .* factorial_func \\(value=4\\) at "
+ ".*\[\r\n\]+#6 .* factorial_func \\(value=5\\) at "
+ ".*\[\r\n\]+#7 .* factorial_func \\(value=6\\) at "
+ ".*\[\r\n\]+#8 .* main \\(.*\\) at "
+}
+
+set post_corefile_regs [capture_command_output "info registers" ""]
+if ![string compare $pre_corefile_regs $post_corefile_regs] then {
+ pass "corefile restored general registers"
+} else {
+ fail "corefile restored general registers"
+}
+
+set post_corefile_allregs [capture_command_output "info all-reg" ""]
+if ![string compare $pre_corefile_allregs $post_corefile_allregs] then {
+ pass "corefile restored all registers"
+} else {
+ fail "corefile restored all registers"
+}
+
+set post_corefile_extern_array \
+ [capture_command_output "print extern_array" "$print_prefix"]
+pass "extern_array = $post_corefile_extern_array"
+if ![string compare $pre_corefile_extern_array $post_corefile_extern_array] {
+ pass "corefile restored extern array"
+} else {
+ fail "corefile restored extern array"
+}
+
+set post_corefile_static_array \
+ [capture_command_output "print static_array" "$print_prefix"]
+pass "static_array = $post_corefile_static_array"
+if ![string compare $pre_corefile_static_array $post_corefile_static_array] {
+ pass "corefile restored static array"
+} else {
+ fail "corefile restored static array"
+}
+
+set post_corefile_uninit_array \
+ [capture_command_output "print un_initialized_array" "$print_prefix"]
+pass "uninit_array = $post_corefile_uninit_array"
+if ![string compare $pre_corefile_uninit_array $post_corefile_uninit_array] {
+ pass "corefile restored un-initialized array"
+} else {
+ fail "corefile restored un-initialized array"
+}
+
+set post_corefile_heap_string \
+ [capture_command_output "print heap_string" "$print_prefix"]
+pass "heap_string = $post_corefile_heap_string"
+if ![string compare $pre_corefile_heap_string $post_corefile_heap_string] {
+ pass "corefile restored heap array"
+} else {
+ fail "corefile restored heap array"
+}
+
+set post_corefile_local_array \
+ [capture_command_output "print array_func::local_array" "$print_prefix"]
+pass "local_array = $post_corefile_local_array"
+if ![string compare $pre_corefile_local_array $post_corefile_local_array] {
+ pass "corefile restored stack array"
+} else {
+ fail "corefile restored stack array"
+}
+
+set post_corefile_backtrace [capture_command_output "backtrace" ""]
+if ![string compare $pre_corefile_backtrace $post_corefile_backtrace] {
+ pass "corefile restored backtrace"
+} else {
+ fail "corefile restored backtrace"
+}
diff --git a/gdb/testsuite/gdb.base/gdbvars.exp b/gdb/testsuite/gdb.base/gdbvars.exp
new file mode 100644
index 00000000000..9678df6bb6e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gdbvars.exp
@@ -0,0 +1,117 @@
+# Copyright (C) 1992, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+proc test_convenience_variables {} {
+ global gdb_prompt
+
+ gdb_test "set \$foo = 101" "" \
+ "Set a new convenience variable"
+
+ gdb_test "print \$foo" " = 101" \
+ "Print contents of new convenience variable"
+
+ gdb_test "set \$foo = 301" "" \
+ "Set convenience variable to a new value"
+
+ gdb_test "print \$foo" " = 301" \
+ "Print new contents of convenience variable"
+
+ gdb_test "set \$_ = 11" "" \
+ "Set convenience variable \$_"
+
+ gdb_test "print \$_" " = 11" \
+ "Print contents of convenience variable \$_"
+
+ gdb_test "print \$foo + 10" " = 311" \
+ "Use convenience variable in arithmetic expression"
+
+ gdb_test "print (\$foo = 32) + 4" " = 36" \
+ "Use convenience variable assignment in arithmetic expression"
+
+ gdb_test "print \$bar" " = void" \
+ "Print contents of uninitialized convenience variable"
+}
+
+proc test_value_history {} {
+ global gdb_prompt
+
+ gdb_test "print 101" "\\\$1 = 101" \
+ "Set value-history\[1\] using \$1"
+
+ gdb_test "print 102" "\\\$2 = 102" \
+ "Set value-history\[2\] using \$2"
+
+ gdb_test "print 103" "\\\$3 = 103" \
+ "Set value-history\[3\] using \$3"
+
+ gdb_test "print \$\$" "\\\$4 = 102" \
+ "Print value-history\[MAX-1\] using inplicit index \$\$"
+
+ gdb_test "print \$\$" "\\\$5 = 103" \
+ "Print value-history\[MAX-1\] again using implicit index \$\$"
+
+ gdb_test "print \$" "\\\$6 = 103" \
+ "Print value-history\[MAX\] using implicit index \$"
+
+ gdb_test "print \$\$2" "\\\$7 = 102" \
+ "Print value-history\[MAX-2\] using explicit index \$\$2"
+
+ gdb_test "print \$0" "\\\$8 = 102" \
+ "Print value-history\[MAX\] using explicit index \$0"
+
+ gdb_test "print 108" "\\\$9 = 108"
+
+ gdb_test "print \$\$0" "\\\$10 = 108" \
+ "Print value-history\[MAX\] using explicit index \$\$0"
+
+ gdb_test "print \$1" "\\\$11 = 101" \
+ "Print value-history\[1\] using explicit index \$1"
+
+ gdb_test "print \$2" "\\\$12 = 102" \
+ "Print value-history\[2\] using explicit index \$2"
+
+ gdb_test "print \$3" "\\\$13 = 103" \
+ "Print value-history\[3\] using explicit index \$3"
+
+ gdb_test "print \$-3" "\\\$14 = 100" \
+ "Print (value-history\[MAX\] - 3) using implicit index \$"
+
+ gdb_test "print \$1 + 3" "\\\$15 = 104" \
+ "Use value-history element in arithmetic expression"
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+send_gdb "set print sevenbit-strings\n" ; gdb_expect -re ".*$gdb_prompt $"
+
+test_value_history
+test_convenience_variables
diff --git a/gdb/testsuite/gdb.base/grbx.c b/gdb/testsuite/gdb.base/grbx.c
new file mode 100644
index 00000000000..58034bbbaae
--- /dev/null
+++ b/gdb/testsuite/gdb.base/grbx.c
@@ -0,0 +1,10 @@
+static int grbxx = 'g' + 'r' + 'b' + 'x';
+
+int grbx (int x)
+{
+ if (x)
+ return grbxx;
+ else
+ return 0;
+}
+
diff --git a/gdb/testsuite/gdb.base/help.exp b/gdb/testsuite/gdb.base/help.exp
new file mode 100644
index 00000000000..4b3d2eebd81
--- /dev/null
+++ b/gdb/testsuite/gdb.base/help.exp
@@ -0,0 +1,597 @@
+# Copyright 1988, 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2002
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+#
+# test gdb help commands
+#
+
+set prms_id 0
+set bug_id 0
+
+gdb_start
+
+# force the height of the debugger to be pretty large so no pagers getused
+gdb_test "set height 400" "" "test set height"
+
+# use a larger expect input buffer for long help outputs.
+# test help add-symbol-file
+gdb_test "help add-symbol-file" "Usage: add-symbol-file FILE ADDR \\\[-s <SECT> <SECT_ADDR> -s <SECT> <SECT_ADDR> \.\.\.\\\]\[\r\n\]+Load the symbols from FILE, assuming FILE has been dynamically loaded\.\[\r\n\]+ADDR is the starting address of the file's text\.\[\r\n\]+The optional arguments are section-name section-address pairs and\[\r\n\]+should be specified if the data and bss segments are not contiguous\[\r\n\]+with the text\. SECT is a section name to be loaded at SECT_ADDR\." "help add-symbol-file"
+# test help aliases
+gdb_test "help aliases" "Aliases of other commands\.\[\r\n\]+List of commands\:.*\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help aliases"
+# test help append
+gdb_test "help append" "Append target code/data to a local file\.\[\r\n\]+List of append subcommands:.*"
+gdb_test "help append binary" "Append target code/data to a raw binary file\.\[\r\n\]+List of append binary subcommands:.*"
+gdb_test "help append memory" "Append contents of memory to a raw binary file\.\[\r\n\]+Arguments are FILE START STOP\. Writes the contents of memory within the\[\r\n\]+range \\\[START \.\. STOP\\) to the specifed FILE in raw target ordered bytes\."
+gdb_test "help append value" "Append the value of an expression to a raw binary file\.\[\r\n\]+Arguments are FILE EXPRESSION\. Writes the value of EXPRESSION to\[\r\n\]+the specified FILE in raw target ordered bytes\."
+gdb_test "help append binary memory" "Append contents of memory to a raw binary file\.\[\r\n\]+Arguments are FILE START STOP\. Writes the contents of memory within the\[\r\n\]+range \\\[START \.\. STOP\\) to the specifed FILE in raw target ordered bytes\."
+gdb_test "help append binary value" "Append the value of an expression to a raw binary file\.\[\r\n\]+Arguments are FILE EXPRESSION\. Writes the value of EXPRESSION\[\r\n\]+to the specified FILE in raw target ordered bytes\."
+# test help attach
+gdb_test "help attach" "Attach to a process or file outside of GDB\.\[\r\n\]+This command attaches to another target, of the same type as your last\[\r\n\]+\"target\" command \\(\"info files\" will show your target stack\\)\.\[\r\n\]+The command may take as argument a process id or a device file\.\[\r\n\]+For a process id, you must have permission to send the process a signal,\[\r\n\]+and it must have the same effective uid as the debugger\.\[\r\n\]+When using \"attach\" with a process id, the debugger finds the\[\r\n\]+program running in the process, looking first in the current working\[\r\n\]+directory, or \\(if not found there\\) using the source file search path\[\r\n\]+\\(see the \"directory\" command\\)\. You can also use the \"file\" command\[\r\n\]+to specify the program, and to load its symbol table\." "help attach"
+# test help breakpoint "b" abbreviation
+gdb_test "help b" "Set breakpoint at specified line or function\.\[\r\n\]+Argument may be line number, function name, or \"\[*\]\" and an address\.\[\r\n\]+If line number is specified, break at start of code for that line\.\[\r\n\]+If function is specified, break at start of code for that function\.\[\r\n\]+If an address is specified, break at that exact address\.\[\r\n\]+With no arg, uses current execution address of selected stack frame\.\[\r\n\]+This is useful for breaking on return to a stack frame\.\[\r\n\]+Multiple breakpoints at one place are permitted, and useful if conditional\.\[\r\n\]+Do \"help breakpoints\" for info on other commands dealing with breakpoints\." "help breakpoint \"b\" abbreviation"
+# test help breakpoint "br" abbreviation
+gdb_test "help br" "Set breakpoint at specified line or function\.\[\r\n\]+Argument may be line number, function name, or \"\[*\]\" and an address\.\[\r\n\]+If line number is specified, break at start of code for that line\.\[\r\n\]+If function is specified, break at start of code for that function\.\[\r\n\]+If an address is specified, break at that exact address\.\[\r\n\]+With no arg, uses current execution address of selected stack frame\.\[\r\n\]+This is useful for breaking on return to a stack frame\.\[\r\n\]+Multiple breakpoints at one place are permitted, and useful if conditional\.\[\r\n\]+Do \"help breakpoints\" for info on other commands dealing with breakpoints\." "help breakpoint \"br\" abbreviation"
+# test help breakpoint "bre" abbreviation
+gdb_test "help bre" "Set breakpoint at specified line or function\.\[\r\n\]+Argument may be line number, function name, or \"\[*\]\" and an address\.\[\r\n\]+If line number is specified, break at start of code for that line\.\[\r\n\]+If function is specified, break at start of code for that function\.\[\r\n\]+If an address is specified, break at that exact address\.\[\r\n\]+With no arg, uses current execution address of selected stack frame\.\[\r\n\]+This is useful for breaking on return to a stack frame\.\[\r\n\]+Multiple breakpoints at one place are permitted, and useful if conditional\.\[\r\n\]+Do \"help breakpoints\" for info on other commands dealing with breakpoints\." "help breakpoint \"bre\" abbreviation"
+# test help breakpoint "brea" abbreviation
+gdb_test "help brea" "Set breakpoint at specified line or function\.\[\r\n\]+Argument may be line number, function name, or \"\[*\]\" and an address\.\[\r\n\]+If line number is specified, break at start of code for that line\.\[\r\n\]+If function is specified, break at start of code for that function\.\[\r\n\]+If an address is specified, break at that exact address\.\[\r\n\]+With no arg, uses current execution address of selected stack frame\.\[\r\n\]+This is useful for breaking on return to a stack frame\.\[\r\n\]+Multiple breakpoints at one place are permitted, and useful if conditional\.\[\r\n\]+Do \"help breakpoints\" for info on other commands dealing with breakpoints\." "help breakpoint \"brea\" abbreviation"
+# test help breakpoint "break" abbreviation
+gdb_test "help break" "Set breakpoint at specified line or function\.\[\r\n\]+Argument may be line number, function name, or \"\[*\]\" and an address\.\[\r\n\]+If line number is specified, break at start of code for that line\.\[\r\n\]+If function is specified, break at start of code for that function\.\[\r\n\]+If an address is specified, break at that exact address\.\[\r\n\]+With no arg, uses current execution address of selected stack frame\.\[\r\n\]+This is useful for breaking on return to a stack frame\.\[\r\n\]+Multiple breakpoints at one place are permitted, and useful if conditional\.\[\r\n\]+Do \"help breakpoints\" for info on other commands dealing with breakpoints\." "help breakpoint \"break\" abbreviation"
+# test help breakpoints
+gdb_test "help breakpoints" "Making program stop at certain points\.\[\r\n\]+List of commands:\[\r\n\]+awatch -- Set a watchpoint for an expression\[\r\n\]+break -- Set breakpoint at specified line or function\[\r\n\]+catch -- Set catchpoints to catch events\[\r\n\]+clear -- Clear breakpoint at specified line or function\[\r\n\]+commands -- Set commands to be executed when a breakpoint is hit\[\r\n\]+condition -- Specify breakpoint number N to break only if COND is true\[\r\n\]+delete -- Delete some breakpoints or auto-display expressions\[\r\n\]+disable -- Disable some breakpoints\[\r\n\]+enable -- Enable some breakpoints\[\r\n\]+hbreak -- Set a hardware assisted breakpoint\[\r\n\]+ignore -- Set ignore-count of breakpoint number N to COUNT\[\r\n\]+rbreak -- Set a breakpoint for all functions matching REGEXP\[\r\n\]+rwatch -- Set a read watchpoint for an expression\[\r\n\]+tbreak -- Set a temporary breakpoint\[\r\n\]+tcatch -- Set temporary catchpoints to catch events\[\r\n\]+thbreak -- Set a temporary hardware assisted breakpoint\[\r\n\]+watch -- Set a watchpoint for an expression\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help breakpoints"
+# test help backtrace "bt" abbreviation
+gdb_test "help bt" "Print backtrace of all stack frames, or innermost COUNT frames\.\[\r\n\]+With a negative argument, print outermost -COUNT frames\.\[\r\n\]+Use of the 'full' qualifier also prints the values of the local variables\." "help backtrace \"bt\" abbreviation"
+# test help backtrace
+gdb_test "help backtrace" "Print backtrace of all stack frames, or innermost COUNT frames\.\[\r\n\]+With a negative argument, print outermost -COUNT frames\.\[\r\n\]+Use of the 'full' qualifier also prints the values of the local variables\." "help backtrace"
+# test help continue "c" abbreviation
+gdb_test "help c" "Continue program being debugged.*" "help continue \"c\" abbreviation"
+# test help continue
+gdb_test "help continue" "Continue program being debugged.*" "help continue"
+# test help call
+gdb_test "help call" "Call a function.*" "help call"
+# test help catch
+gdb_test "help catch" "Set catchpoints to catch events.*Raised signals may be caught:.*catch signal.*all signals.*catch signal.*signame.*a particular signal.*Raised exceptions may be caught:.*catch throw.*all exceptions, when thrown.*catch throw.*exceptname.*a particular exception, when thrown.*catch catch.*all exceptions, when caught.*catch catch.*exceptname.*a particular exception, when caught.*Thread or process events may be caught:.*catch thread_start.*any threads, just after creation.*catch thread_exit.*any threads, just before expiration.*catch thread_join.*any threads, just after joins.*catch start.*any processes, just after creation.*catch exit.*any processes, just before expiration.*catch fork.*calls to fork.*catch vfork.*calls to vfork.*catch exec.*calls to exec.*Dynamically.linked library events may be caught:.*catch load.*loads of any library.*catch load.*libname.*loads of a particular library.*catch unload.*unloads of any library.*catch unload.*libname.*unloads of a particular library.*The act of your program's execution stopping may also be caught:.*catch stop.*Do.*help set follow-fork-mode.*for info on debugging your program.*after a fork or vfork is caught.*Do.*help breakpoints.*for info on other commands dealing with breakpoints." "help catch"
+# test help cd
+gdb_test "help cd" "Set working directory to DIR for debugger and program being debugged\.\[\r\n\]+The change does not take effect for the program being debugged\[\r\n\]+until the next time it is started\." "help cd"
+# test help clear
+gdb_test "help clear" "Clear breakpoint at specified line or function\.\[\r\n\]+Argument may be line number, function name, or \"\\*\" and an address\.\[\r\n\]+If line number is specified, all breakpoints in that line are cleared\.\[\r\n\]+If function is specified, breakpoints at beginning of function are cleared\.\[\r\n\]+If an address is specified, breakpoints at that address are cleared\.\[\r\n\]+With no argument, clears all breakpoints in the line that the selected frame\[\r\n\]+is executing in\.\[\r\n\]+See also the \"delete\" command which clears breakpoints by number\." "help clear"
+# test help commands
+gdb_test "help commands" "Set commands to be executed when a breakpoint is hit\.\[\r\n\]+Give breakpoint number as argument after \"commands\"\.\[\r\n\]+With no argument, the targeted breakpoint is the last one set\.\[\r\n\]+The commands themselves follow starting on the next line\.\[\r\n\]+Type a line containing \"end\" to indicate the end of them\.\[\r\n\]+Give \"silent\" as the first line to make the breakpoint silent;\[\r\n\]+then no output is printed when it is hit, except what the commands print\." "help commands"
+# test help condition
+gdb_test "help condition" "Specify breakpoint number N to break only if COND is true\.\[\r\n\]+Usage is `condition N COND', where N is an integer and COND is an\[\r\n\]+expression to be evaluated whenever breakpoint N is reached." "help condition"
+# test help core-file
+gdb_test "help core-file" "Use FILE as core dump for examining memory and registers\.\[\r\n\]+No arg means have no core file\. This command has been superseded by the\[\r\n\]+`target core' and `detach' commands\." "help core-file"
+# test help delete "d" abbreviation
+gdb_test "help d" "Delete some breakpoints or auto-display expressions\.\[\r\n\]+Arguments are breakpoint numbers with spaces in between\.\[\r\n\]+To delete all breakpoints, give no argument\.\[\r\n\]+Also a prefix command for deletion of other GDB objects\.\[\r\n\]+The \"unset\" command is also an alias for \"delete\"\.\[\r\n\]+List of delete subcommands:\[\r\n\]+delete breakpoints -- Delete some breakpoints or auto-display expressions\[\r\n\]+delete display -- Cancel some expressions to be displayed when program stops\[\r\n\]+delete mem -- Delete memory region\[\r\n\]+delete tracepoints -- Delete specified tracepoints\[\r\n\]+Type \"help delete\" followed by delete subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help delete \"d\" abbreviation"
+# test help delete
+gdb_test "help delete" "Delete some breakpoints or auto-display expressions\.\[\r\n\]+Arguments are breakpoint numbers with spaces in between\.\[\r\n\]+To delete all breakpoints, give no argument\.\[\r\n\]+Also a prefix command for deletion of other GDB objects\.\[\r\n\]+The \"unset\" command is also an alias for \"delete\"\.\[\r\n\]+List of delete subcommands:\[\r\n\]+delete breakpoints -- Delete some breakpoints or auto-display expressions\[\r\n\]+delete display -- Cancel some expressions to be displayed when program stops\[\r\n\]+delete mem -- Delete memory region\[\r\n\]+delete tracepoints -- Delete specified tracepoints\[\r\n\]+Type \"help delete\" followed by delete subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help delete"
+# test help data
+gdb_test "help data" "Examining data\.\[\r\n\]+List of commands:.*\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help data"
+# test help define
+gdb_test "help define" "Define a new command.*" "help define"
+# test help delete breakpoints
+gdb_test "help delete breakpoints" "Delete some breakpoints or auto-display expressions\.\[\r\n\]+Arguments are breakpoint numbers with spaces in between\.\[\r\n\]+To delete all breakpoints, give no argument\.\[\r\n\]+This command may be abbreviated \"delete\"\." "help delete breakpoints"
+# test help delete display
+gdb_test "help delete display" "Cancel some expressions to be displayed when program stops\.\[\r\n\]+Arguments are the code numbers of the expressions to stop displaying\.\[\r\n\]+No argument means cancel all automatic-display expressions\.\[\r\n\]+Do \"info display\" to see current list of code numbers\." "help delete display"
+# test help detach
+gdb_test "help detach" "Detach a process or file previously attached\.\[\r\n\]+If a process, it is no longer traced, and it continues its execution\.\[ \r\n\]+If\[ \r\n\]+you were debugging a file, the file is closed and gdb no longer accesses it\." "help detach"
+# test help directory
+gdb_test "help directory" "Add directory DIR to beginning of search path for source files\.\[\r\n\]+Forget cached info on source file locations and line positions\.\[\r\n\]+DIR can also be \\\$cwd for the current working directory, or \\\$cdir for the\[\r\n\]+directory in which the source file was compiled into object code\.\[\r\n\]+With no argument, reset the search path to \\\$cdir:\\\$cwd, the default\." "help directory"
+# test help disable "dis" abbreviation
+gdb_test "help dis" "Disable some breakpoints\.\[\r\n\]+Arguments are breakpoint numbers with spaces in between\.\[\r\n\]+To disable all breakpoints, give no argument\.\[\r\n\]+A disabled breakpoint is not forgotten, but has no effect until reenabled\.\[\r\n\]+List of disable subcommands:\[\r\n\]+disable breakpoints -- Disable some breakpoints\[\r\n\]+disable display -- Disable some expressions to be displayed when program stops\[\r\n\]+disable mem -- Disable memory region\[\r\n\]+disable tracepoints -- Disable specified tracepoints\[\r\n\]+Type \"help disable\" followed by disable subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help disable \"dis\" abbreviation"
+# test help disable "disa" abbreviation
+gdb_test "help disa" "Disable some breakpoints\.\[\r\n\]+Arguments are breakpoint numbers with spaces in between\.\[\r\n\]+To disable all breakpoints, give no argument\.\[\r\n\]+A disabled breakpoint is not forgotten, but has no effect until reenabled\.\[\r\n\]+List of disable subcommands:\[\r\n\]+disable breakpoints -- Disable some breakpoints\[\r\n\]+disable display -- Disable some expressions to be displayed when program stops\[\r\n\]+disable mem -- Disable memory region\[\r\n\]+disable tracepoints -- Disable specified tracepoints\[\r\n\]+Type \"help disable\" followed by disable subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help disable \"disa\" abbreviation"
+# test help disable
+gdb_test "help disable" "Disable some breakpoints\.\[\r\n\]+Arguments are breakpoint numbers with spaces in between\.\[\r\n\]+To disable all breakpoints, give no argument\.\[\r\n\]+A disabled breakpoint is not forgotten, but has no effect until reenabled\.\[\r\n\]+List of disable subcommands:\[\r\n\]+disable breakpoints -- Disable some breakpoints\[\r\n\]+disable display -- Disable some expressions to be displayed when program stops\[\r\n\]+disable mem -- Disable memory region\[\r\n\]+disable tracepoints -- Disable specified tracepoints\[\r\n\]+Type \"help disable\" followed by disable subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help disable"
+# test help disable breakpoints
+gdb_test "help disable breakpoints" "Disable some breakpoints\.\[\r\n\]+Arguments are breakpoint numbers with spaces in between\.\[\r\n\]+To disable all breakpoints, give no argument\.\[\r\n\]+A disabled breakpoint is not forgotten, but has no effect until reenabled\.\[\r\n\]+This command may be abbreviated \"disable\"." "help disable breakpoints"
+# test help disable display
+gdb_test "help disable display" "Disable some expressions to be displayed when program stops\.\[\r\n\]+Arguments are the code numbers of the expressions to stop displaying\.\[\r\n\]+No argument means disable all automatic-display expressions\.\[\r\n\]+Do \"info display\" to see current list of code numbers\." "help disable display"
+# test help disassemble
+gdb_test "help disassemble" "Disassemble a specified section of memory\.\[\r\n\]+Default is the function surrounding the pc of the selected frame\.\[\r\n\]+With a single argument, the function surrounding that address is dumped\.\[\r\n\]+Two arguments are taken as a range of memory to dump\." "help disassemble"
+# test help display
+gdb_test "help display" "Print value of expression EXP each time the program stops\.\[\r\n\]+/FMT may be used before EXP as in the \"print\" command\.\[\r\n\]+/FMT \"i\" or \"s\" or including a size-letter is allowed,\[\r\n\]+as in the \"x\" command, and then EXP is used to get the address to examine\[\r\n\]+and examining is done as in the \"x\" command\.\[\r\n\]+With no argument, display all currently requested auto-display expressions\.\[\r\n\]+Use \"undisplay\" to cancel display requests previously made\." "help display"
+# test help do
+gdb_test "help do" "Select and print stack frame called by this one\.\[\r\n\]+An argument says how many frames down to go\." "help do"
+# test help document
+gdb_test "help document" "Document a user-defined command\.\[\r\n\]+Give command name as argument\. Give documentation on following lines\.\[\r\n\]+End with a line of just \"end\"\." "help document"
+# test help down
+gdb_test "help down" "Select and print stack frame called by this one\.\[\r\n\]+An argument says how many frames down to go\." "help down"
+# test help down-silently
+gdb_test "help down-silently" "Same as the `down' command, but does not print anything\.\[\r\n\]+This is useful in command scripts\." "help down-silently"
+# test help dump
+gdb_test "help dump" "Dump target code/data to a local file\.\[\r\n\]+List of dump subcommands:.*"
+gdb_test "help dump binary" "Write target code/data to a raw binary file\.\[\r\n\]+List of dump binary subcommands:.*"
+gdb_test "help dump ihex" "Write target code/data to an intel hex file\.\[\r\n\]+List of dump ihex subcommands:.*"
+gdb_test "help dump memory" "Write contents of memory to a raw binary file\.\[\r\n\]+Arguments are FILE START STOP\. Writes the contents of memory within the\[\r\n\]+range \\\[START \.\. STOP\\) to the specifed FILE in raw target ordered bytes\."
+gdb_test "help dump srec" "Write target code/data to an srec file\.\[\r\n\]+List of dump srec subcommands:.*"
+gdb_test "help dump tekhex" "Write target code/data to a tekhex file\.\[\r\n\]+List of dump tekhex subcommands:.*"
+gdb_test "help dump value" "Write the value of an expression to a raw binary file\.\[\r\n\]+Arguments are FILE EXPRESSION\. Writes the value of EXPRESSION to\[\r\n\]+the specified FILE in raw target ordered bytes\."
+gdb_test "help dump binary memory" "Write contents of memory to a raw binary file\.\[\r\n\]+Arguments are FILE START STOP\. Writes the contents of memory\[\r\n\]+within the range \\\[START \.\. STOP\\) to the specifed FILE in binary format\."
+gdb_test "help dump binary value" "Write the value of an expression to a raw binary file\.\[\r\n\]+Arguments are FILE EXPRESSION\. Writes the value of EXPRESSION\[\r\n\]+to the specified FILE in raw target ordered bytes\." "help dump binary value"
+gdb_test "help dump ihex memory" "Write contents of memory to an ihex file\.\[\r\n\]+Arguments are FILE START STOP\. Writes the contents of memory within\[\r\n\]+the range \\\[START \.\. STOP\\) to the specifed FILE in intel hex format\."
+gdb_test "help dump ihex value" "Write the value of an expression to an ihex file\.\[\r\n\]+Arguments are FILE EXPRESSION\. Writes the value of EXPRESSION\[\r\n\]+to the specified FILE in intel hex format\."
+gdb_test "help dump srec memory" "Write contents of memory to an srec file\.\[\r\n\]+Arguments are FILE START STOP\. Writes the contents of memory\[\r\n\]+within the range \\\[START \.\. STOP\\) to the specifed FILE in srec format\."
+gdb_test "help dump srec value" "Write the value of an expression to an srec file\.\[\r\n\]+Arguments are FILE EXPRESSION\. Writes the value of EXPRESSION\[\r\n\]+to the specified FILE in srec format\."
+gdb_test "help dump tekhex memory" "Write contents of memory to a tekhex file\.\[\r\n\]+Arguments are FILE START STOP\. Writes the contents of memory\[\r\n\]+within the range \\\[START \.\. STOP\\) to the specifed FILE in tekhex format\."
+gdb_test "help dump tekhex value" "Write the value of an expression to a tekhex file\.\[\r\n\]+Arguments are FILE EXPRESSION\. Writes the value of EXPRESSION\[\r\n\]+to the specified FILE in tekhex format\."
+# this command was removed from GDB 4.5.8
+# test help dump-me
+#send_gdb "help dump-me"
+# -re "Get fatal error; make debugger dump its core\."
+#
+# }
+# test help echo
+gdb_test "help echo" "Print a constant string\. Give string as argument\.\[\r\n\]+C escape sequences may be used in the argument\.\[\r\n\]+No newline is added at the end of the argument;\[\r\n\]+use \"\\\\n\" if you want a newline to be printed\.\[\r\n\]+Since leading and trailing whitespace are ignored in command arguments,\[\r\n\]+if you want to print some you must use \"\\\\\" before leading whitespace\[\r\n\]+to be printed or after trailing whitespace\." "help echo"
+# test help enable breakpoints delete
+gdb_test "help enable breakpoints delete" "Enable breakpoints and delete when hit\. Give breakpoint numbers\.\[\r\n\]+If a breakpoint is hit while enabled in this fashion, it is deleted\." "help enable breakpoints delete"
+# test help enable breakpoints once
+gdb_test "help enable breakpoints once" "Enable breakpoints for one hit.*" "help enable breakpoints once"
+# test help enable breakpoints
+gdb_test "help enable breakpoints" "Enable some breakpoints\.\[\r\n\]+Give breakpoint numbers \\(separated by spaces\\) as arguments\.\[\r\n\]+This is used to cancel the effect of the \"disable\" command\.\[\r\n\]+May be abbreviated to simply \"enable\"\.\[\r\n\]+List of enable breakpoints subcommands:\[\r\n\]+enable breakpoints delete -- Enable breakpoints and delete when hit\[\r\n\]+enable breakpoints once -- Enable breakpoints for one hit\[\r\n\]+Type \"help enable breakpoints\" followed by enable breakpoints subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help enable breakpoints"
+# test help enable delete
+gdb_test "help enable delete" "Enable breakpoints and delete when hit\. Give breakpoint numbers\.\[\r\n\]+If a breakpoint is hit while enabled in this fashion, it is deleted\." "help enable delete"
+# test help enable display
+gdb_test "help enable display" "Enable some expressions to be displayed when program stops\.\[\r\n\]+Arguments are the code numbers of the expressions to resume displaying\.\[\r\n\]+No argument means enable all automatic-display expressions\.\[\r\n\]+Do \"info display\" to see current list of code numbers\." "help enable display"
+# test help enable once
+gdb_test "help enable once" "Enable breakpoints for one hit.*" "help enable once"
+# test help enable
+gdb_test "help enable" "Enable some breakpoints\.\[\r\n\]+Give breakpoint numbers \\(separated by spaces\\) as arguments\.\[\r\n\]+With no subcommand, breakpoints are enabled until you command otherwise\.\[\r\n\]+This is used to cancel the effect of the \"disable\" command\.\[\r\n\]+With a subcommand you can enable temporarily\.\[\r\n\]+List of enable subcommands:\[\r\n\]+enable delete -- Enable breakpoints and delete when hit\[\r\n\]+enable display -- Enable some expressions to be displayed when program stops\[\r\n\]+enable mem -- Enable memory region\[\r\n\]+enable once -- Enable breakpoints for one hit\[\r\n\]+enable tracepoints -- Enable specified tracepoints\[\r\n\]+Type \"help enable\" followed by enable subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help enable"
+# test help exec-file
+gdb_test "help exec-file" "Use FILE as program for getting contents of pure memory\.\[\r\n\]+If FILE cannot be found as specified, your execution directory path\[\r\n\]+is searched for a command of that name\.\[\r\n\]+No arg means have no executable file\." "help exec-file"
+# test help frame "f" abbreviation
+gdb_test "help f" "Select and print a stack frame\.\[\r\n\]+With no argument, print the selected stack frame\. \\(See also \"info frame\"\\)\.\[\r\n\]+An argument specifies the frame to select\.\[\r\n\]+It can be a stack frame number or the address of the frame\.\[\r\n\]+With argument, nothing is printed if input is coming from\[\r\n\]+a command file or a user-defined command\." "help frame \"f\" abbreviation"
+# test help frame
+gdb_test "help frame" "Select and print a stack frame\.\[\r\n\]+With no argument, print the selected stack frame\. \\(See also \"info frame\"\\)\.\[\r\n\]+An argument specifies the frame to select\.\[\r\n\]+It can be a stack frame number or the address of the frame\.\[\r\n\]+With argument, nothing is printed if input is coming from\[\r\n\]+a command file or a user-defined command\." "help frame"
+# test help fg
+gdb_test "help fg" "Continue program being debugged.*" "help fg"
+# test help file
+gdb_test "help file" "Use FILE as program to be debugged\.\[\r\n\]+It is read for its symbols, for getting the contents of pure memory,\[\r\n\]+and it is the program executed when you use the `run' command\.\[\r\n\]+If FILE cannot be found as specified, your execution directory path\[\r\n\]+\\(\\\$PATH\\) is searched for a command of that name\.\[\r\n\]+No arg means to have no executable file and no symbols\." "help file"
+# test help files
+gdb_test "help files" "Specifying.*" "help files"
+# test help finish
+gdb_test "help finish" "Execute until selected stack frame returns\.\[\r\n\]+Upon return, the value returned is printed and put in the value history\." "help finish"
+# test help forward-search
+gdb_test "help forward-search" "Search for regular expression \\(see regex\\(3\\)\\) from last line listed.*" "help forward-search"
+# test help gcore
+send_gdb "help gcore\n"
+gdb_expect {
+ -re "Undefined command: \"gcore\"\. Try \"help\".*$gdb_prompt $" {
+ pass "help gcore"
+ }
+ -re "Save a core file with the current state of the debugged process\.\[\r\n\]+Argument is optional filename\. Default filename is 'core\.<process_id>'.*$gdb_prompt $" {
+ pass "help gcore"
+ }
+ default { fail "help gcore" }
+}
+send_gdb "help generate-core-file\n"
+gdb_expect {
+ -re "Undefined command: \"generate-core-file\"\. Try \"help\".*$gdb_prompt $" {
+ pass "help gcore"
+ }
+ -re "Save a core file with the current state of the debugged process\.\[\r\n\]+Argument is optional filename\. Default filename is 'core\.<process_id>'.*$gdb_prompt $" {
+ pass "help gcore"
+ }
+ default { fail "help gcore" }
+}
+# test help help "h" abbreviation
+gdb_test "help h" "Print list of commands\." "help help \"h\" abbreviation"
+# test help help
+gdb_test "help help" "Print list of commands\." "help help"
+# test help handle
+gdb_test "help handle" "Specify how to handle a signal\..*" "help handle"
+# test help info "i" abbreviation
+gdb_test "help i" "Generic command for showing things about the program being debugged\.\[\r\n\]+List of info subcommands:.*\[\r\n\]+Type \"help info\" followed by info subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help info \"i\" abbreviation"
+# test help info
+gdb_test "help info" "Generic command for showing things about the program being debugged\.\[\r\n\]+List of info subcommands:.*\[\r\n\]+Type \"help info\" followed by info subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help info"
+# test help ignore
+gdb_test "help ignore" "Set ignore-count of breakpoint number N to COUNT\.\[\r\n\]+Usage is `ignore N COUNT'\." "help ignore"
+# test help info address
+gdb_test "help info address" "Describe where symbol SYM is stored\." "help info address"
+# test help info all-registers
+gdb_test "help info all-registers" "List of all registers and their contents, for selected stack frame\.\[\r\n\]+Register name as argument means describe only that register\." "help info all-registers"
+# test help info args
+gdb_test "help info args" "Argument variables of current stack frame\." "help info args"
+# test help info breakpoints
+gdb_test "help info breakpoints" "Status of user-settable breakpoints, or breakpoint number NUMBER\..*\[\r\n\]+breakpoint set\." "help info breakpoints"
+# test help info catch
+gdb_test "help info catch" "Exceptions that can be caught in the current stack frame\." "help info catch"
+# test help info copying
+gdb_test "help info copying" "Conditions for redistributing copies of GDB\." "help info copying"
+# test help info display
+gdb_test "help info display" "Expressions to display when program stops, with code numbers\." "help info display"
+# test help info frame "f" abbreviation
+gdb_test "help info f" "All about selected stack frame, or frame at ADDR\." "help info frame \"f\" abbreviation"
+# test help info frame
+gdb_test "help info frame" "All about selected stack frame, or frame at ADDR\." "help info frame"
+# test help info files
+gdb_test "help info files" "Names of targets and files being debugged\.\[\r\n\]+Shows the entire stack of targets currently in use \\(including the exec-file,\[\r\n\]+core-file, and process, if any\\), as well as the symbol file name\." "help info files"
+# test help info float
+gdb_test "help info float" "Print the status of the floating point unit" "help info float"
+# test help info functions
+gdb_test "help info functions" "All function names, or those matching REGEXP\." "help info functions"
+# test help info line
+gdb_test "help info line" "Core addresses of the code for a source line\.\[\r\n\]+Line can be specified as\[\r\n\]+ LINENUM, to list around that line in current file,\[\r\n\]+ FILE:LINENUM, to list around that line in that file,\[\r\n\]+ FUNCTION, to list around beginning of that function,\[\r\n\]+ FILE:FUNCTION, to distinguish among like-named static functions\.\[\r\n\]+Default is to describe the last source line that was listed\.\[\r\n\]+This sets the default address for \"x\" to the line's first instruction\[\r\n\]+so that \"x/i\" suffices to start examining the machine code\.\[\r\n\]+The address is also stored as the value of \"\\\$_\"\." "help info line"
+# test help info locals
+gdb_test "help info locals" "Local variables of current stack frame\." "help info locals"
+# test help info program
+gdb_test "help info program" "Execution status of the program\." "help info program"
+# test help info registers
+gdb_test "help info registers" "List of integer registers and their contents, for selected stack frame\.\[\r\n\]+Register name as argument means describe only that register\." "help info registers"
+# test help info stack "s" abbreviation
+gdb_test "help info s" "Backtrace of the stack, or innermost COUNT frames\." "help info stack \"s\" abbreviation"
+# test help info stack
+gdb_test "help info stack" "Backtrace of the stack, or innermost COUNT frames\." "help info stack"
+# test help info set
+gdb_test "help info set" "Show all GDB settings\." "help info set"
+# test help info signals
+gdb_test "help info signals" "What debugger does when program gets various signals.*" "help info signals"
+# test help info source
+gdb_test "help info source" "Information about the current source file\." "help info source"
+# test help info sources
+gdb_test "help info sources" "Source files in the program\." "help info sources"
+# test help info symbol
+gdb_test "help info symbol" "Describe what symbol is at location ADDR.*"
+# test help info target
+gdb_test "help info target" "Names of targets and files being debugged\.\[\r\n\]+Shows the entire stack of targets currently in use \\(including the exec-file,\[\r\n\]+core-file, and process, if any\\), as well as the symbol file name\." "help info target"
+# test help info terminal
+gdb_test "help info terminal" "Print inferior's saved terminal status\." "help info terminal"
+# test help info types
+gdb_test "help info types" "All type names, or those matching REGEXP\." "help info types"
+# test help info variables
+gdb_test "help info variables" "All global and static variable names, or those matching REGEXP\." "help info variables"
+# test help info warranty
+gdb_test "help info warranty" "Various kinds of warranty you do not have\." "help info warranty"
+# test help info watchpoints
+gdb_test "help info watchpoints" "Synonym for ``info breakpoints''\." "help info watchpoints"
+# test help inspect
+gdb_test "help inspect" "Same as \"print\" command, except that if you are running in the epoch\[\r\n\]+environment, the value is printed in its own window\." "help inspect"
+# test help jump
+gdb_test "help jump" "Continue program being debugged at specified line or address\.\[\r\n\]+Give as argument either LINENUM or \[*\]+ADDR, where ADDR is an expression\[\r\n\]+for an address to start at\." "help jump"
+# test help kill
+gdb_test "help kill" "Kill execution of program being debugged\." "help kill"
+# test help list "l" abbreviation
+gdb_test "help l" "List specified function or line\.\[\r\n\]+With no argument, lists ten more lines after or around previous listing\.\[\r\n\]+\"list -\" lists the ten lines before a previous ten-line listing\.\[\r\n\]+One argument specifies a line, and ten lines are listed around that line\.\[\r\n\]+Two arguments with comma between specify starting and ending lines to list\.\[\r\n\]+Lines can be specified in these ways:\[\r\n\]+ LINENUM, to list around that line in current file,\[\r\n\]+ FILE:LINENUM, to list around that line in that file,\[\r\n\]+ FUNCTION, to list around beginning of that function,\[\r\n\]+ FILE:FUNCTION, to distinguish among like-named static functions\.\[\r\n\]+ \[*\]ADDRESS, to list around the line containing that address\.\[\r\n\]+With two args if one is empty it stands for ten lines away from the other arg\." "help list \"l\" abbreviation"
+# test help list
+gdb_test "help list" "List specified function or line\.\[\r\n\]+With no argument, lists ten more lines after or around previous listing\.\[\r\n\]+\"list -\" lists the ten lines before a previous ten-line listing\.\[\r\n\]+One argument specifies a line, and ten lines are listed around that line\.\[\r\n\]+Two arguments with comma between specify starting and ending lines to list\.\[\r\n\]+Lines can be specified in these ways:\[\r\n\]+ LINENUM, to list around that line in current file,\[\r\n\]+ FILE:LINENUM, to list around that line in that file,\[\r\n\]+ FUNCTION, to list around beginning of that function,\[\r\n\]+ FILE:FUNCTION, to distinguish among like-named static functions\.\[\r\n\]+ \[*\]ADDRESS, to list around the line containing that address\.\[\r\n\]+With two args if one is empty it stands for ten lines away from the other arg\." "help list"
+# test help load
+gdb_test "help load" "Dynamically load FILE into the running program, and record its symbols\[\r\n\]+for access from GDB\." "help load"
+# test help make
+gdb_test "help make" "Run the ``make'' program using the rest of the line as arguments\." "help make"
+# test help next "n" abbreviation
+gdb_test "help n" "Step program, proceeding through subroutine calls\.\[\r\n\]+Like the \"step\" command as long as subroutine calls do not happen;\[\r\n\]+when they do, the call is treated as one instruction\.\[\r\n\]+Argument N means do this N times \\(or till program stops for another reason\\)\." "help next \"n\" abbreviation"
+# test help next
+gdb_test "help next" "Step program, proceeding through subroutine calls\.\[\r\n\]+Like the \"step\" command as long as subroutine calls do not happen;\[\r\n\]+when they do, the call is treated as one instruction\.\[\r\n\]+Argument N means do this N times \\(or till program stops for another reason\\)\." "help next"
+# test help nexti
+gdb_test "help ni" "Step one instruction, but proceed through subroutine calls\.\[\r\n\]+Argument N means do this N times \\(or till program stops for another reason\\)\." "help nexti"
+# all the commands that used to be here are now in "maintainance" instead
+# test help obscure
+gdb_test "help obscure" "Obscure features\.\[\r\n\]+List of commands:.*\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help obscure"
+# test help output
+gdb_test "help output" "Like \"print\" but don't put in value history and don't print newline\.\[\r\n\]+This is useful in user-defined commands\." "help output"
+# test help overlay
+gdb_test "help overlay" "Commands for debugging overlays.*"
+gdb_test "help overlay off" "Disable overlay debugging\."
+gdb_test "help overlay manual" "Enable overlay debugging\."
+gdb_test "help overlay auto" "Enable automatic overlay debugging\."
+gdb_test "help overlay list" "List mappings of overlay sections\."
+gdb_test "help overlay map" "Assert that an overlay section is mapped\."
+gdb_test "help overlay unmap" "Assert that an overlay section is unmapped\."
+gdb_test "help overlay load" "Read the overlay mapping state from the target\."
+# test help print "p" abbreviation
+gdb_test "help p" "Print value of expression EXP\.\[\r\n\]+Variables accessible are those of the lexical environment of the selected.*\[\r\n\]+EXP may be preceded with /FMT, where FMT is a format letter\[\r\n\]+but no count or size letter \\(see \"x\" command\\)\." "help print \"p\" abbreviation"
+# test help print
+gdb_test "help print" "Print value of expression EXP\.\[\r\n\]+Variables accessible are those of the lexical environment of the selected.*\[\r\n\]+EXP may be preceded with /FMT, where FMT is a format letter\[\r\n\]+but no count or size letter \\(see \"x\" command\\)\." "help print"
+# test help path
+gdb_test "help path" "Add directory DIR\\(s\\) to beginning of search path for object files\.\[\r\n\]+\\\$cwd in the path means the current working directory\.\[\r\n\]+This path is equivalent to the \\\$PATH shell variable\. It is a list of\[\r\n\]+directories, separated by colons\. These directories are searched to find\[\r\n\]+fully linked executable files and separately compiled object files as needed\." "help path"
+# test help printcmds
+gdb_test "help printcmds" "Undefined command: \"printcmds\"\. Try \"help\"\." "help printcmds"
+# test help printf
+gdb_test "help printf" "printf \"printf format string\", arg1, arg2, arg3, \.\.\., argn\[\r\n\]+This is useful for formatted output in user-defined commands\." "help printf"
+# test help ptype
+gdb_test "help ptype" "Print definition of type.*" "help ptype"
+# test help pwd
+gdb_test "help pwd" "Print working directory\. This is used for your program as well\." "help pwd"
+# test help quit "q" abbreviation
+gdb_test "help q" "Exit gdb\." "help quit \"q\" abbreviation"
+# test help quit
+gdb_test "help quit" "Exit gdb\." "help quit"
+# test help run "r" abbreviation
+gdb_test "help r" "Start debugged program\. You may specify arguments to give it\.\[\r\n\]+Args may include \"\\*\", or \"\\\[\.\.\.\\\]\"; they are expanded using \"sh\"\.\[\r\n\]+Input and output redirection with \">\", \"<\", or \">>\" are also allowed\.\[\r\n\]+With no arguments, uses arguments last specified \\(with \"run\" or \"set args\"\\)\.\[\r\n\]+To cancel previous arguments and run with no arguments,\[\r\n\]+use \"set args\" without arguments\." "help run \"r\" abbreviation"
+# test help run
+gdb_test "help run" "Start debugged program\. You may specify arguments to give it\.\[\r\n\]+Args may include \"\\*\", or \"\\\[\.\.\.\\\]\"; they are expanded using \"sh\"\.\[\r\n\]+Input and output redirection with \">\", \"<\", or \">>\" are also allowed\.\[\r\n\]+With no arguments, uses arguments last specified \\(with \"run\" or \"set args\"\\)\.\[\r\n\]+To cancel previous arguments and run with no arguments,\[\r\n\]+use \"set args\" without arguments\." "help run"
+# test help rbreak
+gdb_test "help rbreak" "Set a breakpoint for all functions matching REGEXP\." "help rbreak"
+# test help restore
+gdb_test "help restore" "Restore the contents of FILE to target memory\.\[\r\n\]+Arguments are FILE OFFSET START END where all except FILE are optional\.\[\r\n\]+OFFSET will be added to the base address of the file \\(default zero\\)\.\[\r\n\]+If START and END are given, only the file contents within that range\[\r\n\]+\\(file relative\\) will be restored to target memory\."
+# test help return
+gdb_test "help return" "Make selected stack frame return to its caller\.\[\r\n\]+Control remains in the debugger, but when you continue\[\r\n\]+execution will resume in the frame above the one now selected\.\[\r\n\]+If an argument is given, it is an expression for the value to return\." "help return"
+# test help reverse-search
+gdb_test "help reverse-search" "Search backward for regular expression \\(see regex\\(3\\)\\) from last line listed\..*" "help reverse-search"
+# test help running
+gdb_test "help running" "Running the program\.\[\r\n\]+List of commands:.*\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help running"
+# test help step "s" abbreviation
+gdb_test "help s" "Step program until it reaches a different source line\.\[\r\n\]+Argument N means do this N times \\(or till program stops for another reason\\)\." "help step \"s\" abbreviation"
+# test help step
+gdb_test "help step" "Step program until it reaches a different source line\.\[\r\n\]+Argument N means do this N times \\(or till program stops for another reason\\)\." "help step #1"
+# test help search
+gdb_test "help search" "Search for regular expression \\(see regex\\(3\\)\\) from last line listed\..*" "help search"
+# test help section
+gdb_test "help section" "Change the base address of section SECTION of the exec file to ADDR\.\[\r\n\]+This can be used if the exec file does not contain section addresses,\[\r\n\]+\\(such as in the a\.out format\\), or when the addresses specified in the\[\r\n\]+file itself are wrong\. Each section must be changed separately\. The\[\r\n\]+``info files'' command lists all the sections and their addresses\." "help section"
+#test help set annotate
+gdb_test "help set annotate" "Set annotation_level\.\[\r\n\]+0 == normal; 1 == fullname \\(for use when running under emacs\\)\[\r\n\]+2 == output annotated suitably for use by programs that control GDB\." "help set annotate"
+# test help set args
+gdb_test "help set args" "Set argument list to give program being debugged when it is started\.\[\r\n\]+Follow this command with any number of args, to be passed to the program\."
+# test help set check "c" abbreviation
+gdb_test "help set c" "Set the status of the type/range checker\.\[\r\n\]+List of set check subcommands:\[\r\n\]+set check range -- Set range checking\[\r\n\]+set check type -- Set type checking\[\r\n\]+Type \"help set check\" followed by set check subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help set check \"c\" abbreviation"
+# test help set check "ch" abbreviation
+gdb_test "help set ch" "Set the status of the type/range checker\.\[\r\n\]+List of set check subcommands:\[\r\n\]+set check range -- Set range checking\[\r\n\]+set check type -- Set type checking\[\r\n\]+Type \"help set check\" followed by set check subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help set check \"ch\" abbreviation"
+# test help set check
+gdb_test "help set check" "Set the status of the type/range checker\.\[\r\n\]+List of set check subcommands:\[\r\n\]+set check range -- Set range checking\[\r\n\]+set check type -- Set type checking\[\r\n\]+Type \"help set check\" followed by set check subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help set check"
+# test help set check range
+gdb_test "help set check range" "Set range checking\. \\(on/warn/off/auto\\)" "help set check range"
+# test help set check type
+gdb_test "help set check type" "Set type checking\. \\(on/warn/off/auto\\)." "help set check type"
+# test help set complaints
+gdb_test "help set complaints" "Set max number of complaints about incorrect symbols\." "help set complaints"
+# test help set confirm
+gdb_test "help set confirm" "Set whether to confirm potentially dangerous operations\." "help set confirm"
+# test help set editing
+gdb_test "help set editing" "Set editing of command lines as they are typed\.\[\r\n\]+Use \"on\" to enable the editing, and \"off\" to disable it\.\[\r\n\]+Without an argument, command line editing is enabled\. To edit, use\[\r\n\]+EMACS-like or VI-like commands like control-P or ESC\." "help set editing"
+# test help set environment
+gdb_test "help set environment" "Set environment variable value to give the program\.\[\r\n\]+Arguments are VAR VALUE where VAR is variable name and VALUE is value\.\[\r\n\]+VALUES of environment variables are uninterpreted strings\.\[\r\n\]+This does not affect the program until the next \"run\" command\." "help set environment"
+# test help set height
+gdb_test "help set height" "Set number of lines gdb thinks are in a page\." "help set height"
+# test help set history expansion
+gdb_test "help set history expansion" "Set history expansion on command input\.\[\r\n\]+Without an argument, history expansion is enabled\." "help set history expansion"
+# test help set history filename
+gdb_test "help set history filename" "Set the filename in which to record the command history\[\r\n\]+\\(the list of previous commands of which a record is kept\\)\." "help set history filename"
+# test help set history save
+gdb_test "help set history save" "Set saving of the history record on exit\.\[\r\n\]+Use \"on\" to enable the saving, and \"off\" to disable it\.\[\r\n\]+Without an argument, saving is enabled\." "help set history save"
+# test help set history size
+gdb_test "help set history size" "Set the size of the command history,\[\r\n\]+ie\. the number of previous commands to keep a record of\." "help set history size"
+# test help set history
+gdb_test "help set history" "Generic command for setting command history parameters\.\[\r\n\]+List of set history subcommands:\[\r\n\]+set history expansion -- Set history expansion on command input\[\r\n\]+set history filename -- Set the filename in which to record the command history\[\r\n\]+set history save -- Set saving of the history record on exit\[\r\n\]+set history size -- Set the size of the command history\[\r\n\]+Type \"help set history\" followed by set history subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help set history"
+# test help set language
+gdb_test "help set language" "Set the current source language\." "help set language"
+# test help set listsize
+gdb_test "help set listsize" "Set number of source lines gdb will list by default\." "help set listsize"
+# test help set print "p" abbreviation
+# FIXME -- Ultrix hangs randomly on this very long output from gdb and
+# continues with its output only if something is sent to gdb.
+# Also, if the system is slow, it may time out because the output is large.
+gdb_test "help set p" "Generic command for setting how things print\.\[\r\n\]+List of set print subcommands:.*\[\r\n\]+Type \"help set print\" followed by set print subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help set print \"p\" abbreviation"
+# test help set print "pr" abbreviation
+gdb_test "help set pr" "Generic command for setting how things print\.\[\r\n\]+List of set print subcommands:.*\[\r\n\]+Type \"help set print\" followed by set print subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help set print \"pr\" abbreviation"
+# test help set print
+gdb_test "help set print" "Generic command for setting how things print\.\[\r\n\]+List of set print subcommands:.*\[\r\n\]+Type \"help set print\" followed by set print subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help set print"
+# test help set print address
+gdb_test "help set print address" "Set printing of addresses\." "help set print address"
+# test help set print array
+gdb_test "help set print array" "Set prettyprinting of arrays\." "help set print array"
+# test help set print asm-demangle
+gdb_test "help set print asm-demangle" "Set demangling of C\[+\]+ names in disassembly listings\." "help set print asm-demangle"
+# test help set print demangle
+gdb_test "help set print demangle" "Set demangling of encoded C\[+\]+ names when displaying symbols\." "help set print demangle"
+# test help set print elements
+gdb_test "help set print elements" "Set limit on string chars or array elements to print\.\[\r\n\]+\"set print elements 0\" causes there to be no limit\." "help set print elements"
+# test help set print object
+gdb_test "help set print object" "Set printing of object's derived type based on vtable info\." "help set print object"
+# test help set print pretty
+gdb_test "help set print pretty" "Set prettyprinting of structures\." "help set print pretty"
+# test help set print sevenbit-strings
+gdb_test "help set print sevenbit-strings" "Set printing of 8-bit characters in strings as \\\\nnn\." "help set print sevenbit-strings"
+# test help set print union
+gdb_test "help set print union" "Set printing of unions interior to structures\." "help set print union"
+# test help set print vtbl
+gdb_test "help set print vtbl" "Set printing of C\[+\]+ virtual function tables\." "help set print vtbl"
+# test help set prompt
+gdb_test "help set prompt" "Set gdb's prompt" "help set prompt"
+# test help set radix
+gdb_test "help set radix" "Set default input and output number radices\.\[\r\n\]+Use \'set input-radix\' or \'set output-radix\' to independently set each\.\[\r\n\]+Without an argument, sets both radices back to the default value of 10\." "help set radix"
+# test help set symbol-reloading
+gdb_test "help set symbol-reloading" "Set dynamic symbol table reloading multiple times in one run\." "help set symbol-reloading"
+# test help set variable
+gdb_test "help set variable" "Evaluate expression EXP and assign result to variable VAR, using assignment\[\r\n\]+syntax appropriate for the current language \\(VAR = EXP or VAR := EXP for\[\r\n\]+example\\)\. VAR may be a debugger \"convenience\" variable \\(names starting\[\r\n\]+with \\\$\\), a register \\(a few standard names starting with \\\$\\), or an actual\[\r\n\]+variable in the program being debugged\. EXP is any valid expression\.\[\r\n\]+This may usually be abbreviated to simply \"set\"\." "help set variable"
+# test help set verbose
+gdb_test "help set verbose" "Set verbosity\." "help set verbose"
+#test help set width
+gdb_test "help set width" "Set number of characters gdb thinks are in a line\." "help set width"
+# test help set write
+# This is only supported on targets which use exec.o.
+gdb_test "help set write" "Set writing into executable and core files\." "help set write"
+# test help set
+# FIXME -- Ultrix hangs randomly on this very long output from gdb and
+# continues with its output only if something is sent to gdb.
+# Also, if the system is slow, it may time out because the output is large.
+gdb_test "help set" "Evaluate expression EXP and assign result to variable VAR, using assignment\[\r\n\]+syntax appropriate for the current language \\(VAR = EXP or VAR := EXP for\[\r\n\]+example\\)\. VAR may be a debugger \"convenience\" variable \\(names starting\[\r\n\]+with \\\$\\), a register \\(a few standard names starting with \\\$\\), or an actual\[\r\n\]+variable in the program being debugged\. EXP is any valid expression.*\[\r\n\]+set listsize -- Set number of source lines gdb will list by default.*\[\r\n\]+Type \"help set\" followed by set subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous..*\[\r\n\]+" "help set"
+# test help shell
+gdb_test "help shell" "Execute the rest of the line as a shell command\.\[\r\n\]+With no arguments, run an inferior shell\." "help shell"
+#test help show annotate
+gdb_test "help show annotate" "Show annotation_level\.\[\r\n\]+0 == normal; 1 == fullname \\(for use when running under emacs\\)\[\r\n\]+2 == output annotated suitably for use by programs that control GDB\." "help show annotate"
+# test help show args
+gdb_test "help show args" "Show argument list to give program being debugged when it is started\.\[\r\n\]+Follow this command with any number of args, to be passed to the program\."
+# test help show check "c" abbreviation
+gdb_test "help show c" "Show the status of the type/range checker\.\[\r\n\]+List of show check subcommands:\[\r\n\]+show check range -- Show range checking\[\r\n\]+show check type -- Show type checking\[\r\n\]+Type \"help show check\" followed by show check subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help show check \"c\" abbreviation"
+# test help show check
+gdb_test "help show check" "Show the status of the type/range checker\.\[\r\n\]+List of show check subcommands:\[\r\n\]+show check range -- Show range checking\[\r\n\]+show check type -- Show type checking\[\r\n\]+Type \"help show check\" followed by show check subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help show check"
+# test help show check range
+gdb_test "help show check range" "Show range checking\. \\(on/warn/off/auto\\)" "help show check range"
+# test help show check type
+gdb_test "help show check type" "Show type checking\. \\(on/warn/off/auto\\)" "help show check type"
+# test help show commands
+gdb_test "help show commands" "Show the history of commands you typed\.\[\r\n\]+You can supply a command number to start with, or a `\[+\]' to start after\[\r\n\]+the previous command number shown\." "help show commands"
+# test help show complaints
+gdb_test "help show complaints" "Show max number of complaints about incorrect symbols\." "help show complaints"
+# test help show confirm
+gdb_test "help show confirm" "Show whether to confirm potentially dangerous operations\." "help show confirm"
+# test help show convenience
+gdb_test "help show convenience" "Debugger convenience \\(\"\\\$foo\"\\) variables\.\[\r\n\]+These variables are created when you assign them values;\[\r\n\]+thus, \"print \\\$foo=1\" gives \"\\\$foo\" the value 1\. Values may be any type\.\[\r\n\]+A few convenience variables are given values automatically:\[\r\n\]+\"\\\$_\"holds the last address examined with \"x\" or \"info lines\",\[\r\n\]+\"\\\$__\" holds the contents of the last address examined with \"x\"\." "help show convenience"
+# test help show directories
+gdb_test "help show directories" "Current search path for finding source files\.\[\r\n\]+\\\$cwd in the path means the current working directory\.\[\r\n\]+\\\$cdir in the path means the compilation directory of the source file\." "help show directories"
+# test help show editing
+gdb_test "help show editing" "Show editing of command lines as they are typed\.\[\r\n\]+Use \"on\" to enable the editing, and \"off\" to disable it\.\[\r\n\]+Without an argument, command line editing is enabled\. To edit, use\[\r\n\]+EMACS-like or VI-like commands like control-P or ESC\." "help show editing"
+# test help show environment
+gdb_test "help show environment" "The environment to give the program, or one variable's value\.\[\r\n\]+With an argument VAR, prints the value of environment variable VAR to\[\r\n\]+give the program being debugged\. With no arguments, prints the entire\[\r\n\]+environment to be given to the program\." "help show environment"
+# test help show height
+gdb_test "help show height" "Show number of lines gdb thinks are in a page\." "help show height"
+# test help show history expansion
+gdb_test "help show history expansion" "Show history expansion on command input\.\[\r\n\]+Without an argument, history expansion is enabled\." "help show history expansion"
+# test help show history filename
+gdb_test "help show history filename" "Show the filename in which to record the command history\[\r\n\]+\\(the list of previous commands of which a record is kept\\)\." "help show history filename"
+# test help show history save
+gdb_test "help show history save" "Show saving of the history record on exit\.\[\r\n\]+Use \"on\" to enable the saving, and \"off\" to disable it\.\[\r\n\]+Without an argument, saving is enabled\." "help show history save"
+# test help show history size
+gdb_test "help show history size" "Show the size of the command history,\[\r\n\]+ie\. the number of previous commands to keep a record of\." "help show history size"
+# test help show history
+gdb_test "help show history" "Generic command for showing command history parameters\.\[\r\n\]+List of show history subcommands:\[\r\n\]+show history expansion -- Show history expansion on command input\[\r\n\]+show history filename -- Show the filename in which to record the command history\[\r\n\]+show history save -- Show saving of the history record on exit\[\r\n\]+show history size -- Show the size of the command history\[\r\n\]+Type \"help show history\" followed by show history subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help show history"
+# test help show language
+gdb_test "help show language" "Show the current source language\." "help show language"
+# test help show listsize
+gdb_test "help show listsize" "Show number of source lines gdb will list by default\." "help show listsize"
+# test help show print "p" abbreviation
+gdb_test "help show p" "Generic command for showing print settings\.\[\r\n\]+List of show print subcommands:.*\[\r\n\]+Type \"help show print\" followed by show print subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help show print \"p\" abbreviation"
+# test help show print "pr" abbreviation
+gdb_test "help show pr" "Generic command for showing print settings\.\[\r\n\]+List of show print subcommands:.*\[\r\n\]+Type \"help show print\" followed by show print subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help show print \"pr\" abbreviation"
+# test help show print
+gdb_test "help show print" "Generic command for showing print settings\.\[\r\n\]+List of show print subcommands:.*\[\r\n\]+Type \"help show print\" followed by show print subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help show print"
+# test help show paths
+gdb_test "help show paths" "Current search path for finding object files\.\[\r\n\]+\\\$cwd in the path means the current working directory\.\[\r\n\]+This path is equivalent to the \\\$PATH shell variable\. It is a list of\[\r\n\]+directories, separated by colons\. These directories are searched to find\[\r\n\]+fully linked executable files and separately compiled object files as needed\." "help show paths"
+# test help show print address
+gdb_test "help show print address" "Show printing of addresses\." "help show print address"
+# test help show print array
+gdb_test "help show print array" "Show prettyprinting of arrays\." "help show print array"
+# test help show print asm-demangle
+gdb_test "help show print asm-demangle" "Show demangling of C\[+\]+ names in disassembly listings\." "help show print asm-demangle"
+# test help show print demangle
+gdb_test "help show print demangle" "Show demangling of encoded C\[+\]+ names when displaying symbols\." "help show print demangle"
+# test help show print elements
+gdb_test "help show print elements" "Show limit on string chars or array elements to print\.\[\r\n\]+\"set print elements 0\" causes there to be no limit\." "help show print elements"
+# test help show print object
+gdb_test "help show print object" "Show printing of object's derived type based on vtable info\." "help show print object"
+# test help show print pretty
+gdb_test "help show print pretty" "Show prettyprinting of structures\." "help show print pretty"
+# test help show print sevenbit-strings
+gdb_test "help show print sevenbit-strings" "Show printing of 8-bit characters in strings as \\\\nnn\." "help show print sevenbit-strings"
+# test help show print union
+gdb_test "help show print union" "Show printing of unions interior to structures\." "help show print union"
+# test help show print vtbl
+gdb_test "help show print vtbl" "Show printing of C\[+\]+ virtual function tables\." "help show print vtbl"
+# test help show prompt
+gdb_test "help show prompt" "Show gdb's prompt" "help show prompt"
+# test help show radix
+gdb_test "help show radix" "Show the default input and output number radices\.\[\r\n\]+Use \'show input-radix\' or \'show output-radix\' to independently show each\." "help show radix"
+# test help show symbol-reloading
+gdb_test "help show symbol-reloading" "Show dynamic symbol table reloading multiple times in one run\." "help show symbol-reloading"
+# test help show user
+gdb_test "help show user" "Show definitions of user defined commands\.\[\r\n\]+Argument is the name of the user defined command\.\[\r\n\]+With no argument, show definitions of all user defined commands\." "help show user"
+# test help show values
+gdb_test "help show values" "Elements of value history around item number IDX \\(or last ten\\)\." "help show values"
+# test help show verbose
+gdb_test "help show verbose" "Show verbosity\." "help show verbose"
+# test help show version
+gdb_test "help show version" "Show what version of GDB this is\." "help show version"
+# test help show width
+gdb_test "help show width" "Show number of characters gdb thinks are in a line\." "help show width"
+# test help show write
+# This is only supported on targets which use exec.o.
+gdb_test "help show write" "Show writing into executable and core files\." "help show write"
+# test help show
+# FIXME -- Ultrix hangs randomly on this very long output from gdb and
+# continues with its output only if something is sent to gdb.
+# Also, if the system is slow, it may time out because the output is large.
+gdb_test "help show" "Generic command for showing things about the debugger\.\[\r\n\]+List of show subcommands:.*\[\r\n\]+show directories -- Current search path for finding source files.*\[\r\n\]+show listsize -- Show number of source lines gdb will list by default.*\[\r\n\]+Type \"help show\" followed by show subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help show"
+# test help step
+gdb_test "help step" "Step program until it reaches a different source line\.\[\r\n\]+Argument N means do this N times \\(or till program stops for another reason\\)\." "help step #2"
+# test help stepi "si" abbreviation
+gdb_test "help si" "Step one instruction exactly\.\[\r\n\]+Argument N means do this N times \\(or till program stops for another reason\\)\." "help stepi \"si\" abbreviation"
+# test help stepi
+gdb_test "help stepi" "Step one instruction exactly\.\[\r\n\]+Argument N means do this N times \\(or till program stops for another reason\\)\." "help stepi"
+# test help signal
+gdb_test "help signal" "Continue program giving it signal.*" "help signal"
+# test help source
+# vxgdb reads .vxgdbinit
+gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when gdb is started\." "help source"
+# test help stack
+gdb_test "help stack" "Examining the stack\..*\[\r\n\]+When the program being debugged stops, gdb selects the innermost frame\.\[\r\n\]+The commands below can be used to select other frames by number or address\.\[\r\n\]+List of commands:\[\r\n\]+backtrace -- Print backtrace of all stack frames\[\r\n\]+bt -- Print backtrace of all stack frames\[\r\n\]+down -- Select and print stack frame called by this one\[\r\n\]+frame -- Select and print a stack frame\[\r\n\]+return -- Make selected stack frame return to its caller\[\r\n\]+select-frame -- Select a stack frame without printing anything\[\r\n\]+up -- Select and print stack frame that called this one\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help stack"
+# test help status
+gdb_test "help status" "Status inquiries\.\[\r\n\]+List of commands:\[\r\n\]+info -- Generic command for showing things about the program being debugged.*\[\r\n\]+show -- Generic command for showing things about the debugger\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help status"
+
+# test help support
+# FIXME -- Ultrix hangs randomly on this very long output from gdb and
+# continues with its output only if something is sent to gdb.
+# Also, if the system is slow, it may time out because the output is large.
+gdb_test "help support" "Support facilities\.\[\r\n\]+List of commands:.*\[\r\n\]+show confirm -- Show whether to confirm potentially dangerous operations.*\[\r\n\]+show history -- Generic command for showing command history parameters.*\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help support"
+# test help symbol-file
+gdb_test "help symbol-file" "Load symbol table from executable file FILE\.\[\r\n\]+The `file' command can also load symbol tables, as well as setting the file\[\r\n\]+to execute\." "help symbol-file"
+# test help target child
+gdb_test "help target child" "Unix child process \\(started by the \"run\" command\\)\.|Undefined target command: \"child\"\. Try \"help target\"\." "help target child"
+# test help target procfs
+gdb_test "help target procfs" "Unix /proc child process \\(started by the \"run\" command\\)\.|Undefined target command: \"procfs\"\. Try \"help target\"\." "help target procfs (procfs version)"
+# test help target core
+gdb_test "help target core" "Use a core file as a target\. Specify the filename of the core file\.|(Undefined target command: \"core\"\. Try \"help target\"\.)" "help target core"
+# test help target exec
+gdb_test "help target exec" "Use an executable file as a target\.\[\r\n\]+Specify the filename of the executable file\." "help target exec"
+# test help target remote
+gdb_test "help target remote" "Use a remote computer via a serial line, using a gdb-specific protocol\.\[\r\n\]+Specify the serial device it is connected to\[\r\n\]+\\(e.g. .*" "help target remote"
+# test help target
+# the child process target may be "target child" or "target procfs"
+gdb_test "help target" "Connect to a target machine or process\.\[\r\n\]+The first argument is the type or protocol of the target machine\.\[\r\n\]+Remaining arguments are interpreted by the target protocol\. For more\[\r\n\]+information on the arguments for a particular protocol, type\[\r\n\]+`help target ' followed by the protocol name\.\[\r\n\]+List of target subcommands:.*\[\r\n\]+target exec -- Use an executable file as a target.*\[\r\n\]+Type \"help target\" followed by target subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help target"
+# test help tbreak
+gdb_test "help tbreak" "Set a temporary breakpoint.*" "help tbreak"
+# test help tty
+gdb_test "help tty" "Set terminal for future runs of program being debugged\." "help tty"
+# test help until "u" abbreviation
+gdb_test "help u" "Execute until the program reaches a source line greater than the current\[\r\n\]+or a specified line or address or function \\(same args as break command\\)\.\[\r\n\]+Execution will also stop upon exit from the current stack frame\." "help until \"u\" abbreviation"
+# test help until
+gdb_test "help until" "Execute until the program reaches a source line greater than the current\[\r\n\]+or a specified line or address or function \\(same args as break command\\)\.\[\r\n\]+Execution will also stop upon exit from the current stack frame\." "help until"
+# test help undisplay
+gdb_test "help undisplay" "Cancel some expressions to be displayed when program stops\.\[\r\n\]+Arguments are the code numbers of the expressions to stop displaying\.\[\r\n\]+No argument means cancel all automatic-display expressions\.\[\r\n\]+\"delete display\" has the same effect as this command\.\[\r\n\]+Do \"info display\" to see current list of code numbers\." "help undisplay"
+# test help unset environment
+gdb_test "help unset environment" "Cancel environment variable VAR for the program\.\[\r\n\]+This does not affect the program until the next \"run\" command\." "help unset environment"
+# test help unset
+gdb_test "help unset" "Complement to certain \"set\" commands\.\[\r\n\]+List of unset subcommands:\[\r\n\]+unset environment -- Cancel environment variable VAR for the program\[\r\n\]+Type \"help unset\" followed by unset subcommand name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help unset"
+# test help up
+gdb_test "help up" "Select and print stack frame that called this one\.\[\r\n\]+An argument says how many frames up to go\." "help up"
+# test help up-silently
+gdb_test "help up-silently" "Same as the `up' command, but does not print anything\.\[\r\n\]+This is useful in command scripts\." "help up-silently"
+# test help user-defined
+gdb_test "help user-defined" "User-defined commands\.\[\r\n\]+The commands in this class are those defined by the user\.\[\r\n\]+Use the \"define\" command to define a command\.\[\r\n\]+List of commands:.*\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help user-defined"
+# test help watch
+gdb_test "help watch" "Set a watchpoint for an expression\.\[\r\n\]+A watchpoint stops execution of your program whenever the value of\[\r\n\]+an expression changes\." "help watch"
+# test help whatis
+gdb_test "help whatis" "Print data type of expression EXP\." "help whatis"
+# test help where
+gdb_test "help where" "Print backtrace of all stack frames, or innermost COUNT frames\.\[\r\n\]+With a negative argument, print outermost -COUNT frames\.\[\r\n\]+Use of the 'full' qualifier also prints the values of the local variables\." "help where"
+# test help x
+gdb_test "help x" "Examine memory: x/FMT ADDRESS\.\[\r\n\]+ADDRESS is an expression for the memory address to examine\.\[\r\n\]+FMT is a repeat count followed by a format letter and a size letter\..*\[\r\n\]+Defaults for format and size letters are those previously used\.\[\r\n\]+Default count is 1\. Default address is following last thing printed\[\r\n\]+with this command or \"print\"\." "help x"
+# test help info bogus-gdb-command
+gdb_test "help info bogus-gdb-command" "Undefined info command: \"bogus-gdb-command\"\. Try \"help info\"\." "help info bogus-gdb-command"
+# test help gotcha
+gdb_test "help gotcha" "Undefined command: \"gotcha\"\. Try \"help\"\." "help gotcha"
+# test apropos regex
+gdb_test "apropos \\\(print\[\^ bsiedf\\\".-\]\\\)" "handle -- Specify how to handle a signal"
+# test apropos >1 word string
+gdb_test "apropos handle a signal" "handle -- Specify how to handle a signal"
+# test apropos apropos
+gdb_test "apropos apropos" "apropos -- Search for commands matching a REGEXP"
diff --git a/gdb/testsuite/gdb.base/huge.c b/gdb/testsuite/gdb.base/huge.c
new file mode 100644
index 00000000000..419b92cc5b7
--- /dev/null
+++ b/gdb/testsuite/gdb.base/huge.c
@@ -0,0 +1,17 @@
+/*
+ * Test GDB's ability to read a very large data object from target memory.
+ */
+
+/* A value that will produce a target data object large enough to
+ crash GDB. 0x200000 is big enough on GNU/Linux, other systems may
+ need a larger number. */
+
+#define CRASH_GDB 0x200000
+
+static int a[CRASH_GDB], b[CRASH_GDB];
+
+main()
+{
+ memcpy (a, b, sizeof (a));
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/huge.exp b/gdb/testsuite/gdb.base/huge.exp
new file mode 100644
index 00000000000..fa50d0115ac
--- /dev/null
+++ b/gdb/testsuite/gdb.base/huge.exp
@@ -0,0 +1,57 @@
+# Copyright 2001 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@redhat.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# Define if you want to skip this test
+# (could be very time-consuming on remote targets with slow connection).
+#
+if [target_info exists gdb,skip_huge_test] {
+ return;
+}
+
+set testfile "huge"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set timeout 30
+
+if { ! [ runto main ] } then {
+ gdb_suppress_entire_file "Run to main failed, so all tests in this file will automatically fail."
+}
+
+gdb_test "print a" ".1 = .0 .repeats \[0123456789\]+ times.." "print a very large data object"
+
diff --git a/gdb/testsuite/gdb.base/info-proc.exp b/gdb/testsuite/gdb.base/info-proc.exp
new file mode 100644
index 00000000000..2a9a4b09a3d
--- /dev/null
+++ b/gdb/testsuite/gdb.base/info-proc.exp
@@ -0,0 +1,75 @@
+# Copyright 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@redhat.com)
+# This is a test for the gdb command "info proc"
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "break"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set ws "\[ \t\]+"
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Does this gdb support info proc?
+send_gdb "help info proc\n"
+gdb_expect {
+ -re "Undefined info command: .proc.. Try .help info.*$gdb_prompt $" {
+ # info proc command not supported -- nothing to test here.
+ unsupported "gdb does not support info proc on this target"
+ return -1;
+ }
+ -re "Show /proc process information about .*$gdb_prompt $" {
+ pass "help info proc"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "help info proc"
+ }
+ timeout {
+ fail "help info proc (timeout)"
+ }
+}
+
+gdb_test "info proc" "No current process.*" "info proc without a process"
+
+if { ! [ runto main ] } then {
+ gdb_suppress_entire_file "Run to main failed, so all tests in this file will automatically fail."
+}
+
+gdb_test "info proc" "process ${decimal}.*" "info proc with process"
+
+gdb_test "info proc mapping" \
+ ".*Mapped address spaces:.*${hex}${ws}${hex}${ws}${hex}${ws}${hex}.*" \
+ "info proc mapping"
diff --git a/gdb/testsuite/gdb.base/int-type.c b/gdb/testsuite/gdb.base/int-type.c
new file mode 100644
index 00000000000..548ca9c36bb
--- /dev/null
+++ b/gdb/testsuite/gdb.base/int-type.c
@@ -0,0 +1,25 @@
+
+int x;
+int y;
+int z;
+int w;
+
+
+
+int main ()
+{
+
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+
+ x = 14;
+ y = 3;
+ z = 2;
+ w = 2;
+
+ return 0;
+
+}
+
diff --git a/gdb/testsuite/gdb.base/interrupt.c b/gdb/testsuite/gdb.base/interrupt.c
new file mode 100644
index 00000000000..a895d4b7d81
--- /dev/null
+++ b/gdb/testsuite/gdb.base/interrupt.c
@@ -0,0 +1,40 @@
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+int
+main ()
+{
+ char x;
+ int nbytes;
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ printf ("talk to me baby\n");
+ while (1)
+ {
+ nbytes = read (0, &x, 1);
+ if (nbytes < 0)
+ {
+#ifdef EINTR
+ if (errno != EINTR)
+#endif
+ perror ("");
+ }
+ else if (nbytes == 0)
+ {
+ printf ("end of file\n");
+ exit (0);
+ }
+ else
+ write (1, &x, 1);
+ }
+ return 0;
+}
+
+int
+func1 ()
+{
+ return 4;
+}
diff --git a/gdb/testsuite/gdb.base/interrupt.exp b/gdb/testsuite/gdb.base/interrupt.exp
new file mode 100644
index 00000000000..b370b53a52d
--- /dev/null
+++ b/gdb/testsuite/gdb.base/interrupt.exp
@@ -0,0 +1,185 @@
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if [host_info exists name] {
+ if [board_info host exists gdb,nointerrupts] {
+ verbose "Skipping interrupt.exp because of nointerrupts."
+ continue
+ }
+}
+
+if [target_info exists gdb,noinferiorio] {
+ verbose "Skipping interrupt.exp because of noinferiorio."
+ return
+}
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile interrupt
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_start
+
+
+if ![file exists $binfile] then {
+ perror "$binfile does not exist."
+ return 0
+} else {
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+ # Hope this is unix :-)
+ gdb_test "shell stty intr '^C'" "" \
+ "set interrupt character in interrupt.exp"
+ if [runto_main] then {
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "\r\ntalk to me baby\r\n$" {
+ pass "child process is alive"
+ }
+ timeout { fail "run (timeout)" }
+ eof { fail "run (eof)" }
+ }
+ # This should appear twice, once for the echo and once for the
+ # program's output. Under dejagnu (but not interactively) for
+ # SunOS4, it only appears once. Don't worry about it, I imagine
+ # dejagnu has just done something to the tty modes.
+ send_gdb "a\n"
+ gdb_expect {
+ -re "^a\r\n(|a\r\n)$" {
+ pass "child process ate our char"
+ }
+ timeout { fail "echo a (timeout)" }
+ eof { fail "echo a (eof)" }
+ }
+ # Wait until the program is in the read system call again.
+ sleep 2
+
+ # Cntrl-c may fail for simulator targets running on a BSD host.
+ # This is the result of a combination of the read syscall
+ # being restarted and gdb capturing the cntrl-c signal.
+
+ # Cntrl-c may fail for simulator targets on slow hosts.
+ # This is because there is a race condition between entering
+ # the read and delivering the cntrl-c.
+
+ send_gdb "\003"
+ gdb_expect {
+ -re "Program received signal SIGINT.*$gdb_prompt $" {
+ pass "send_gdb control C"
+ }
+ -re ".*$gdb_prompt $" { fail "send_gdb control C" }
+ timeout { fail "send_gdb control C (timeout)" }
+ eof { fail "send_gdb control C (eof)" }
+ }
+
+ send_gdb "p func1 ()\n"
+ gdb_expect {
+ -re " = 4.*$gdb_prompt $" { pass "call function when asleep" }
+ -re ".*Program received signal SIG(SEGV|ILL).*$gdb_prompt $" {
+ setup_xfail "i*86-pc-linux*-gnu*"
+ fail "child died when we called func1, skipped rest of tests"
+ return
+ }
+ -re "$gdb_prompt $" {
+ # On HPUX-11.0 'send "p func1 ()"' above
+ # terminates the program. A defect is pending on this
+ # issue [defect #DTS CHFts24203]. Hence calling setup_xfail
+ # below.
+ setup_xfail "hppa*-*-*11*" CHFts24203
+ fail "call function when asleep (wrong output)"
+ }
+ default {
+
+ # This fail probably happens whenever we use /proc (we
+ # don't use PRSABORT), but apparently also happens on
+ # other machines as well.
+
+ setup_xfail "sparc*-*-solaris2*"
+ setup_xfail "mips-*-ultrix*"
+ setup_xfail "i386*-*-bsd*"
+ setup_xfail "i*86-*-solaris2*"
+ setup_xfail "*-*-sysv4*"
+ setup_xfail "vax-*-*"
+ setup_xfail "alpha-*-*"
+ setup_xfail "*-*-irix*"
+ setup_xfail "*-*-hpux*"
+ setup_xfail "*-*-*lynx*"
+ fail "call function when asleep (stays asleep)"
+ # Send_Gdb a newline to wake it up
+ send_gdb "\n"
+ gdb_test "" " = 4" "call function after waking it"
+ }
+# eof { fail "call function when asleep (eof)" }
+ }
+
+ # Now try calling the function again.
+ gdb_test "p func1 ()" " = 4" "call function a second time"
+
+ # And the program should still be doing the same thing.
+ # The optional trailing \r\n is in case we sent a newline above
+ # to wake the program, in which case the program now sends it
+ # back. We check for it either here or in the next gdb_expect
+ # command, because which one it ends up in is timing dependent.
+ send_gdb "continue\n"
+ # For some reason, i386-*-sysv4 gdb fails to issue the Continuing
+ # message, but otherwise appears normal (FIXME).
+ gdb_expect {
+ -re "^continue\r\nContinuing.\r\n(\r\n|)$" { pass "continue" }
+ -re "^continue\r\n\r\n" { fail "continue (missing Continuing.)" }
+ -re "$gdb_prompt $" { fail "continue" }
+ timeout { fail "continue (timeout)" }
+ eof { fail "continue (eof)" }
+ }
+
+ send_gdb "data\n"
+ # The optional leading \r\n is in case we sent a newline above
+ # to wake the program, in which case the program now sends it
+ # back.
+ # FIXME: The pattern below leads to an expected success on HPUX-11.0
+ # but the success is spurious. Need to provide the right reg.expr.
+ # here.
+ gdb_expect {
+ -re "^(\r\n|)data\r\n(|data\r\n)$" { pass "echo data" }
+ timeout { fail "echo data (timeout)" }
+ eof { fail "echo data (eof)" }
+ }
+
+ setup_xfail "i*86-pc-linux*-gnu*"
+ send_gdb "\004"
+ gdb_expect {
+ -re "end of file.*Program exited normally.*$gdb_prompt $" {
+ pass "send end of file"
+ }
+ -re "$gdb_prompt $" { fail "send end of file" }
+ timeout { fail "send end of file (timeout)" }
+ eof { fail "send end of file (eof)" }
+ }
+ }
+}
+return 0
diff --git a/gdb/testsuite/gdb.base/jump.c b/gdb/testsuite/gdb.base/jump.c
new file mode 100644
index 00000000000..aae94f7e85a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/jump.c
@@ -0,0 +1,24 @@
+/* This program is used to test the "jump" command. There's nothing
+ particularly deep about the functionality nor names in here.
+ */
+
+#ifdef PROTOTYPES
+static int square (int x)
+#else
+static int square (x)
+ int x;
+#endif
+{
+ return x*x;
+}
+
+
+int main ()
+{
+ int i = 99;
+
+ i++;
+ i = square (i);
+ i--;
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/jump.exp b/gdb/testsuite/gdb.base/jump.exp
new file mode 100644
index 00000000000..a2c53ee7788
--- /dev/null
+++ b/gdb/testsuite/gdb.base/jump.exp
@@ -0,0 +1,187 @@
+# Copyright 1998, 1999 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+set prms_id 0
+set bug_id 0
+
+clear_xfail "*-*-*"
+
+set testfile "jump"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Build the test case
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+
+
+# Start with a fresh gdb
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ perror "Couldn't run to main"
+ return -1
+}
+
+# Set a breakpoint on the statement that we're about to jump to.
+# The statement doesn't contain a function call.
+#
+send_gdb "break 22\n"
+set bp_on_non_call 0
+gdb_expect {
+ -re "\[Bb\]reakpoint (\[0-9\]*) at 0x\[0-9a-fA-F\]*: file .*${srcfile}, line 22.*$gdb_prompt $"\
+ {set bp_on_non_call $expect_out(1,string)
+ pass "break before jump to non-call"}
+ -re "$gdb_prompt $"\
+ {fail "break before jump to non-call"}
+ timeout {fail "(timeout) break before jump to non-call"}
+}
+
+# Can we jump to the statement? Do we stop there?
+#
+send_gdb "jump 22\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]*, .*${srcfile}:22.*$gdb_prompt $"\
+ {pass "jump to non-call"}
+ -re "$gdb_prompt $"\
+ {fail "jump to non-call"}
+ timeout {fail "(timeout) jump to non-call"}
+}
+
+# Set a breakpoint on the statement that we're about to jump to.
+# The statement does contain a function call.
+#
+send_gdb "break 21\n"
+set bp_on_call 0
+gdb_expect {
+ -re "\[Bb\]reakpoint (\[0-9\]*) at 0x\[0-9a-fA-F\]*: file .*${srcfile}, line 21.*$gdb_prompt $"\
+ {set bp_on_call $expect_out(1,string)
+ pass "break before jump to call"}
+ -re "$gdb_prompt $"\
+ {fail "break before jump to call"}
+ timeout {fail "(timeout) break before jump to call"}
+}
+
+# Can we jump to the statement? Do we stop there?
+#
+send_gdb "jump 21\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]*, .*${srcfile}:21.*$gdb_prompt $"\
+ {pass "jump to call"}
+ -re "$gdb_prompt $"\
+ {fail "jump to call"}
+ timeout {fail "(timeout) jump to call"}
+}
+
+# If we disable the breakpoint at the function call, and then
+# if we jump to that statement, do we not stop there, but at
+# the following breakpoint?
+#
+send_gdb "disable $bp_on_call\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "disable breakpoint on call"}
+ timeout {fail "(timeout) disable breakpoint on call"}
+}
+
+send_gdb "jump 21\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]*, .*${srcfile}:22.*$gdb_prompt $"\
+ {pass "jump to call with disabled breakpoint"}
+ -re "$gdb_prompt $"\
+ {fail "jump to call with disabled breakpoint"}
+ timeout {fail "(timeout) jump to call with disabled breakpoint"}
+}
+
+# Verify that GDB responds gracefully to the "jump" command without
+# an argument.
+#
+send_gdb "jump\n"
+gdb_expect {
+ -re "Argument required .starting address..*$gdb_prompt $"\
+ {pass "jump without argument disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "jump without argument disallowed"}
+ timeout {fail "(timeout) jump without argument disallowed"}
+}
+
+# Verify that GDB responds gracefully to the "jump" command with
+# trailing junk.
+#
+send_gdb "jump 21 100\n"
+gdb_expect {
+ -re "Junk at end of line specification: 100.*$gdb_prompt $"\
+ {pass "jump with trailing argument junk"}
+ -re "$gdb_prompt $"\
+ {fail "jump with trailing argument junk"}
+ timeout {fail "(timeout) jump with trailing argument junk"}
+}
+
+# Verify that GDB responds gracefully to a request to jump out of
+# the current function. (Note that this will very likely cause the
+# inferior to die. Be prepared to rerun the inferior, if further
+# testing is desired.)
+#
+# Try it both ways: confirming and not confirming the jump.
+#
+send_gdb "jump 12\n"
+gdb_expect {
+ -re "Line 12 is not in `main'. Jump anyway.*y or n. $"\
+ {send_gdb "n\n"
+ gdb_expect {
+ -re "Not confirmed.*$gdb_prompt $"\
+ {pass "aborted jump out of current function"}
+ -re "$gdb_prompt $"\
+ {fail "aborted jump out of current function"}
+ timeout {fail "(timeout) aborted jump out of current function"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "aborted jump out of current function"}
+ timeout {fail "(timeout) aborted jump out of current function"}
+}
+
+send_gdb "jump 12\n"
+gdb_expect {
+ -re "Line 12 is not in `main'. Jump anyway.*y or n. $"\
+ {send_gdb "y\n"
+ gdb_expect {
+ -re "Continuing at.*$gdb_prompt $"\
+ {pass "jump out of current function"}
+ -re "$gdb_prompt $"\
+ {fail "jump out of current function"}
+ timeout {fail "(timeout) jump out of current function"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "jump out of current function"}
+ timeout {fail "(timeout) jump out of current function"}
+}
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.base/langs.exp b/gdb/testsuite/gdb.base/langs.exp
new file mode 100644
index 00000000000..9ed1e91a289
--- /dev/null
+++ b/gdb/testsuite/gdb.base/langs.exp
@@ -0,0 +1,149 @@
+# Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile langs
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [is_remote host] {
+ remote_download host ${srcdir}/${subdir}/langs1.f
+ remote_download host ${srcdir}/${subdir}/langs2.cxx
+}
+
+
+if { [gdb_compile "${srcdir}/${subdir}/langs0.c" "${binfile}0.o" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/langs1.c" "${binfile}1.o" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/langs2.c" "${binfile}2.o" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${binfile}0.o ${binfile}1.o ${binfile}2.o" ${binfile} executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+set oldtimeout $timeout
+set timeout 10
+
+
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_test "b langs0" "Function \"langs0\" not defined\.|Breakpoint .* (deferred).*" \
+ "break on nonexistent function in langs.exp"
+
+if {$hp_aCC_compiler} {
+ set isfixed 1
+ set lang c\\+\\+
+ set ext cxx
+ set foo_func foo__Fi__Fi
+ set do_func do::langs0
+} else {
+ if {$hp_cc_compiler} {
+ set isfixed 1
+ set lang c
+ set ext c
+ } else {
+ set isfixed 0
+ }
+ set foo_func foo__Fi
+ set do_func langs0__2do
+}
+
+if [runto csub] then {
+
+ if { !$isfixed } { set lang c }
+ gdb_test "show language" "currently $lang\".*" \
+ "show language at csub in langs.exp"
+ # On some machines, foo doesn't get demangled because the N_SOL for
+ # langs2.cxx is seen only after the function stab for foo. So
+ # the following regexps are kludged to accept foo__Fi as well as foo,
+ # even though only the latter is correct. I haven't tried to xfail it
+ # because it depends on details of the compiler.
+
+ # Take out xfail. This test has been passing for some time now.
+ #if {!$gcc_compiled} then { setup_xfail "hppa*-*-hpux*" }
+ gdb_test "bt" "#0.*csub.*#1.*(foo|$foo_func) \\(.*#2.*cppsub_ .*#3.*fsub.*#4.*$do_func \\(.*#5 \[0-9a-fx\]* in main.*" "backtrace in langs.exp"
+
+ if { !$isfixed } { set lang c\\+\\+; set ext cxx }
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "up" ".* in (foo|$foo_func).* at langs2\\.$ext.*return csub \\(.*" \
+ "up to foo in langs.exp"
+ gdb_test "show language" "currently $lang.*" \
+ "show language at foo in langs.exp"
+
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "up" ".* in cppsub_ .* at langs2\\.$ext.*return foo \\(.*" \
+ "up to cppsub_ in langs.exp"
+ gdb_test "show language" "currently $lang.*" \
+ "show language at cppsub_ in langs.exp"
+
+ if { !$isfixed } { set lang fortran }
+ if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "up" ".* in fsub.* at langs1\\.f.*" \
+ "up to fsub in langs.exp"
+ gdb_test "show language" "currently $lang.*" \
+ "show language at fsub in langs.exp"
+
+ # Take out xfail. This test has been passing for sometime now.
+ #if {!$gcc_compiled} then { setup_xfail "hppa*-*-hpux*" }
+ if { !$isfixed } { set lang c }
+ gdb_test "up" ".* in $do_func .* at .*langs0\\.c.*return fsub.*" \
+ "up to langs0__2do in langs.exp"
+ gdb_test "show language" "currently $lang\".*" \
+ "show language at langs0__2do in langs.exp"
+
+ gdb_test "up" ".* in main .* at .*langs0\\.c.*if \\(langs0__2do \\(.*" \
+ "up to main in langs.exp"
+ gdb_test "show language" "currently $lang\".*" \
+ "show language at main in langs.exp"
+
+ if [target_info exists gdb,noresults] { return }
+
+ if [target_info exists use_gdb_stub] {
+ gdb_breakpoint "exit"
+ gdb_test "cont" "Breakpoint .*exit.*" "continue to exit in langs.exp"
+ } else {
+ gdb_test "cont" "Program exited normally\\..*" \
+ "continue to exit in langs.exp"
+ }
+}
+
+set timeout $oldtimeout
+return 0
diff --git a/gdb/testsuite/gdb.base/langs0.c b/gdb/testsuite/gdb.base/langs0.c
new file mode 100644
index 00000000000..1477a324f91
--- /dev/null
+++ b/gdb/testsuite/gdb.base/langs0.c
@@ -0,0 +1,34 @@
+/* This file is actually in C, it is not supposed to simulate something
+ translated from another language or anything like that. */
+#ifdef PROTOTYPES
+extern int fsub_();
+
+int csub (int x)
+#else
+int
+csub (x)
+ int x;
+#endif
+{
+ return x + 1;
+}
+
+int
+langs0__2do ()
+{
+ return fsub_ () + 2;
+}
+
+int
+main ()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ if (langs0__2do () == 5003)
+ /* Success. */
+ return 0;
+ else
+ return 1;
+}
diff --git a/gdb/testsuite/gdb.base/langs1.c b/gdb/testsuite/gdb.base/langs1.c
new file mode 100644
index 00000000000..8ffd13f0840
--- /dev/null
+++ b/gdb/testsuite/gdb.base/langs1.c
@@ -0,0 +1,41 @@
+/* langs1.f -- translated by f2c (version of 5 May 1990 1:12:08). */
+
+/* f2c output hacked as follows for GDB testsuite:
+ 1. Change commented out "#" lines to #line directives.
+ I don't know why this behavior isn't the default for f2c -g.
+ 2. Remove include of f2c.h and put in just a typedef for "integer".
+ Additional notes:
+ 3. f2c was called as "f2c -g langs1.f".
+ 4. We don't need to use the fortran libraries. */
+
+typedef int integer;
+
+/* Table of constant values */
+
+static integer c__10000 = 10000;
+
+/* I am not sure whether there is a way to have a fortran program without */
+/* a MAIN, but it does not really harm us to have one. */
+#ifdef PROTOTYPES
+/* Main program */ void MAIN__()
+#else
+/* Main program */ MAIN__()
+#endif
+{
+} /* MAIN__ */
+
+#line 4 "langs1.f"
+/* Subroutine */ int fsub_()
+{
+#ifdef PROTOTYPES
+ extern integer cppsub_(int*);
+#else
+ extern integer cppsub_();
+#endif
+
+#line 5 "langs1.f"
+#line 6 "langs1.f"
+ return cppsub_(&c__10000);
+#line 7 "langs1.f"
+} /* fsub_ */
+
diff --git a/gdb/testsuite/gdb.base/langs1.f b/gdb/testsuite/gdb.base/langs1.f
new file mode 100644
index 00000000000..35ce6911472
--- /dev/null
+++ b/gdb/testsuite/gdb.base/langs1.f
@@ -0,0 +1,7 @@
+c I am not sure whether there is a way to have a fortran program without
+c a MAIN, but it does not really harm us to have one.
+ end
+ subroutine fsub
+ integer*4 cppsub
+ return (cppsub (10000))
+ end
diff --git a/gdb/testsuite/gdb.base/langs2.c b/gdb/testsuite/gdb.base/langs2.c
new file mode 100644
index 00000000000..502b80063f0
--- /dev/null
+++ b/gdb/testsuite/gdb.base/langs2.c
@@ -0,0 +1,32 @@
+/* This is intended to be a vague simulation of cfront output. */
+#ifdef PROTOTYPES
+#line 1 "langs2.cxx"
+extern int csub (int);
+int
+foo__Fi (int x)
+{
+ return csub (x / 2);
+}
+
+extern int cppsub_ (int *y);
+int
+cppsub_ (int * y)
+{
+ return foo__Fi (*y);
+}
+#else
+#line 1 "langs2.cxx"
+extern int csub ();
+int
+foo__Fi (x) int x;
+{
+ return csub (x / 2);
+}
+
+extern int cppsub_ ();
+int
+cppsub_ (y) int *y;
+{
+ return foo__Fi (*y);
+}
+#endif
diff --git a/gdb/testsuite/gdb.base/langs2.cxx b/gdb/testsuite/gdb.base/langs2.cxx
new file mode 100644
index 00000000000..5a2ca8a1568
--- /dev/null
+++ b/gdb/testsuite/gdb.base/langs2.cxx
@@ -0,0 +1,13 @@
+extern "C" int csub (int);
+int
+foo (int x)
+{
+ return csub (x / 2);
+}
+
+extern "C" int cppsub_ (int *);
+int
+cppsub_ (int *y)
+{
+ return foo (*y);
+}
diff --git a/gdb/testsuite/gdb.base/list.exp b/gdb/testsuite/gdb.base/list.exp
new file mode 100644
index 00000000000..881e0e6bff9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/list.exp
@@ -0,0 +1,559 @@
+# Copyright 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2002
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "list"
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Need to download the header to the host.
+remote_download host ${srcdir}/${subdir}/list0.h list0.h
+
+
+if { [gdb_compile "${srcdir}/${subdir}/list0.c" "${binfile}0.o" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/list1.c" "${binfile}1.o" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${binfile}0.o ${binfile}1.o" ${binfile} executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+#
+# Local utility proc just to set and verify listsize
+# Return 1 if success, 0 if fail.
+#
+
+set set_listsize_count 0;
+
+proc set_listsize { arg } {
+ global gdb_prompt
+ global set_listsize_count;
+
+ incr set_listsize_count;
+ if [gdb_test "set listsize $arg" "" "setting listsize to $arg #$set_listsize_count"] {
+ return 0;
+ }
+ if { $arg <= 0 } {
+ set arg "unlimited";
+ }
+
+ if [gdb_test "show listsize" "Number of source lines.* is ${arg}.*" "show listsize $arg #$set_listsize_count"] {
+ return 0;
+ }
+ return 1
+}
+
+#
+# Test display of listsize lines around a given line number.
+#
+
+proc test_listsize {} {
+ global gdb_prompt
+ global hp_cc_compiler
+ global hp_aCC_compiler
+
+ # Show default size
+
+ gdb_test "show listsize" "Number of source lines gdb will list by default is 10.*" "show default list size"
+
+ # Show the default lines
+ # Note that remote targets that have debugging info for _start available will
+ # list the lines there instead of main, so we skip this test for remote targets.
+ # The second case is for optimized code, it is still correct.
+
+ if [is_remote target] {
+ runto_main;
+ unsupported "list default lines around main";
+ } else {
+ gdb_test "list" "(1\[ \t\]+#include \"list0.h\".*10\[ \t\]+x = 0;|2.*11\[ \t\]+foo .x\[+)\]+;)" "list default lines around main"
+ }
+
+ # Ensure we can limit printouts to one line
+
+ if [set_listsize 1] {
+ gdb_test "list 1" "1\[ \t\]+#include \"list0.h\"" "list line 1 with listsize 1"
+ gdb_test "list 2" "2\[ \t\]+" "list line 2 with listsize 1"
+ }
+
+ # Try just two lines
+
+ if [ set_listsize 2 ] {
+ gdb_test "list 1" "1\[ \t\]+#include \"list0.h\"\r\n2\[ \t\]+" "list line 1 with listsize 2"
+ gdb_test "list 2" "1\[ \t\]+#include \"list0.h\"\r\n2\[ \t\]+" "list line 2 with listsize 2"
+ gdb_test "list 3" "2\[ \t\]+\r\n3\[ \t\]+int main \[)(\]+" "list line 3 with listsize 2"
+ }
+
+ # Try small listsize > 1 that is an odd number
+
+ if [ set_listsize 3 ] {
+ gdb_test "list 1" "1\[ \t\]+#include \"list0.h\".*3\[ \t\]+int main \[)(\]+" "list line 1 with listsize 3"
+ gdb_test "list 2" "1\[ \t\]+#include \"list0.h\".*3\[ \t\]+int main \[)(\]+" "list line 2 with listsize 3"
+ gdb_test "list 3" "2\[ \t\]+\r\n3\[ \t\]+int main \[(\]+\[)\]+\r\n4\[ \t\]+\{" "list line 3 with listsize 3"
+ }
+
+ # Try small listsize > 2 that is an even number.
+
+ if [ set_listsize 4 ] then {
+ gdb_test "list 1" "1\[ \t\]+#include \"list0.h\".*4\[ \t\]+\{" "list line 1 with listsize 4"
+ gdb_test "list 2" "1\[ \t\]+#include \"list0.h\".*4\[ \t\]+\{" "list line 2 with listsize 4"
+
+ gdb_test "list 3" "1\[ \t\]+#include \"list0.h\".*4\[ \t\]+\{" "list line 3 with listsize 4"
+ gdb_test "list 4" "2\[ \t\]+\r\n.*5\[ \t\]+int x;.*" "list line 4 with listsize 4"
+ }
+
+ # Try a size larger than the entire file.
+
+ if [ set_listsize 100 ] then {
+ gdb_test "list 1" "1\[ \t\]+#include \"list0.h\".*\r\n4\[23\]\[ \t\]+\}" "list line 1 with listsize 100"
+
+ gdb_test "list 10" "1\[ \t\]+#include \"list0.h\".*\r\n4\[23\]\[ \t\]+\}" "list line 10 with listsize 100"
+ }
+
+ # Try listsize of 0 which suppresses printing.
+
+ set_listsize 0
+ gdb_test "list 1" "" "listsize of 0 suppresses output"
+
+ # Try listsize of -1 which is special, and means unlimited.
+
+ set_listsize -1
+ setup_xfail "*-*-*"
+ gdb_test "list 1" "1\[ \t\]+#include .*\r\n39\[ \t\]+\}" "list line 1 with unlimited listsize"
+}
+
+#
+# Test "list filename:number" for C include file
+#
+
+proc test_list_include_file {} {
+ global gdb_prompt
+
+ setup_xfail_format "DWARF 1"
+ setup_xfail_format "COFF"
+ gdb_test "list list0.h:1" "1\[ \t\]+/\[*\]+ An include file .*10\[ \t\]+bar \\(x\\+\\+\\);" "list line 1 in include file"
+
+ setup_xfail_format "DWARF 1"
+ setup_xfail_format "COFF"
+ gdb_test "list list0.h:100" "Line number 95 out of range; .*list0.h has 3\[67\] lines." "list message for lines past EOF"
+}
+
+#
+# Test "list filename:number" for C source file
+#
+
+proc test_list_filename_and_number {} {
+ global gdb_prompt
+
+ set testcnt 0
+
+ send_gdb "list list0.c:1\n"
+ gdb_expect {
+ -re "1\[ \t\]+#include \"list0.h\".*10\[ \t]+x = 0;\r\n$gdb_prompt $" {
+ incr testcnt
+ }
+ -re ".*$gdb_prompt $" { fail "list list0.c:1" ; gdb_suppress_tests }
+ timeout { fail "list list0.c:1 (timeout)" ; gdb_suppress_tests }
+ }
+ send_gdb "list list0.c:10\n"
+ gdb_expect {
+ -re "5\[ \t\]+int x;.*14\[ \t\]+foo .x\[+)\]+;\r\n$gdb_prompt $" {
+ incr testcnt
+ }
+ -re ".*$gdb_prompt $" { fail "list list.c:10" ; gdb_suppress_tests }
+ timeout { fail "list list.c:10 (timeout)" ; gdb_suppress_tests }
+ }
+ send_gdb "list list1.c:1\n"
+ gdb_expect {
+ -re "1\[ \t\]+\#include.*4\[ \t\]+.*int oof\[ \t\]*\(.*\);\r\n.*$gdb_prompt $" {
+ incr testcnt
+ }
+ -re ".*$gdb_prompt $" { fail "list list1.c:1" ; gdb_suppress_tests }
+ timeout { fail "list list1.c:1 (timeout)" ; gdb_suppress_tests }
+ }
+ send_gdb "list list1.c:12\n"
+ gdb_expect {
+ -re "12\[ \t\]+long_line \[(\]+.*\[)\]+;.*13\[ \t\]+\}\r\n.*$gdb_prompt $" {
+ incr testcnt
+ }
+ -re ".*$gdb_prompt $" { fail "list list1.c:12" ; gdb_suppress_tests }
+ timeout { fail "list list1.c:12 (timeout)" ; gdb_suppress_tests }
+ }
+ pass "list filename:number ($testcnt tests)"
+ gdb_stop_suppressing_tests;
+}
+
+#
+# Test "list function" for C source file
+#
+
+proc test_list_function {} {
+ global gdb_prompt
+ global gcc_compiled
+
+ # gcc appears to generate incorrect debugging information for code
+ # in include files, which breaks this test.
+ # SunPRO cc is the second case below, it's also correct.
+ gdb_test "list main" "(5\[ \t\]+int x;.*14\[ \t\]+foo \[(\]+.*\[)\]+;|1\[ \t\]+#include .*10\[ \t\]+x = 0;)" "list function in source file 1"
+
+ # Ultrix gdb takes the second case below; it's also correct.
+ # SunPRO cc is the third case.
+ gdb_test "list bar" "(4\[ \t\]+void.*\[ \t\]*long_line.*;.*bar.*9\[ \t\]*.*|1\[ \t\]+void.*8\[ \t\]+\}|1\[ \t\]+void.*7\[ \t\]*long_line ..;|7\[ \t\]+void.*14\[ \t\]+\})" "list function in source file 2"
+
+ # Test "list function" for C include file
+ # Ultrix gdb is the second case, still correct.
+ # SunPRO cc is the third case.
+ setup_xfail "powerpc-*-*"
+ setup_xfail_format "DWARF 1"
+ gdb_test "list foo" "(3\[ \t\]+.*12\[ \t\]+bar \[(\]+.*\[)\]+;|2\[ \t\]+including file.*11\[ \t\]+bar \[(\]+.*\[)\]+;|1\[ \t\]+/. An include file.*10\[ \t\]+bar \[(\]+.*\[)\]+;)" "list function in include file"
+}
+
+proc test_list_forward {} {
+ global gdb_prompt
+
+ set testcnt 0
+
+ send_gdb "list list0.c:10\n"
+ gdb_expect {
+ -re "5\[ \t\]+int x;.*14\[ \t\]+foo \[(\]+.*\[)\]+;\r\n$gdb_prompt $" { incr testcnt }
+ -re ".*$gdb_prompt $" { fail "list list0.c:10" ; gdb_suppress_tests }
+ timeout { fail "list list0.c:10 (timeout)" ; gdb_suppress_tests }
+ }
+
+ send_gdb "list\n"
+ gdb_expect {
+ -re "15\[ \t\]+foo \[(\]+.*\[)\]+;.*24\[ \t\]+foo \[(\]+.*\[)\]+;\r\n$gdb_prompt $" { incr testcnt }
+ -re ".*$gdb_prompt $" { fail "list 15-24" ; gdb_suppress_tests }
+ timeout { fail "list 15-24 (timeout)" ; gdb_suppress_tests }
+ }
+
+ send_gdb "list\n"
+ gdb_expect {
+ -re "25\[ \t\]+foo \[(\]+.*\[)\]+;.*34\[ \t\]+foo \[(\]+.*\[)\]+;\r\n$gdb_prompt $" { incr testcnt }
+ -re ".*$gdb_prompt $" { fail "list 25-34" ; gdb_suppress_tests }
+ timeout { fail "list 25-34 (timeout)" ; gdb_suppress_tests }
+ }
+
+ send_gdb "list\n"
+ gdb_expect {
+ -re "35\[ \t\]+foo \\(.*\\);.*42\[ \t\]+.*\}\r\n$gdb_prompt $" { incr testcnt }
+ -re ".*$gdb_prompt $" { fail "list 35-42" ; gdb_suppress_tests }
+ timeout { fail "list 35-42 (timeout)" ; gdb_suppress_tests }
+ }
+
+ pass "successive list commands to page forward ($testcnt tests)"
+ gdb_stop_suppressing_tests;
+}
+
+# Test that repeating the list linenum command doesn't print the same
+# lines over again. Note that this test makes sure that the argument
+# linenum is dropped, when we repeat the previous command. 'x/5i $pc'
+# works the same way.
+
+proc test_repeat_list_command {} {
+ global gdb_prompt
+
+ set testcnt 0
+
+ send_gdb "list list0.c:10\n"
+ gdb_expect {
+ -re "5\[ \t\]+int x;.*14\[ \t\]+foo \[(\]+.*\[)\]+;\r\n$gdb_prompt $" { incr testcnt }
+ -re ".*$gdb_prompt $" { fail "list list0.c:10" ; gdb_suppress_tests }
+ timeout { fail "list list0.c:10 (timeout)" ; gdb_suppress_tests }
+ }
+
+ send_gdb "\n"
+ gdb_expect {
+ -re "15\[ \t\]+foo \[(\]+.*\[)\]+;.*24\[ \t\]+foo \[(\]+.*\[)\]+;\r\n$gdb_prompt $" { incr testcnt }
+ -re ".*$gdb_prompt $" { fail "list 15-24" ; gdb_suppress_tests }
+ timeout { fail "list 15-24 (timeout)" ; gdb_suppress_tests }
+ }
+
+ send_gdb "\n"
+ gdb_expect {
+ -re "25\[ \t\]+foo \[(\]+.*\[)\]+;.*34\[ \t\]+foo \[(\]+.*\[)\]+;\r\n$gdb_prompt $" { incr testcnt }
+ -re ".*$gdb_prompt $" { fail "list 25-34" ; gdb_suppress_tests }
+ timeout { fail "list 25-34 (timeout)" ; gdb_suppress_tests }
+ }
+
+ send_gdb "\n"
+ gdb_expect {
+ -re "35\[ \t\]+foo \\(.*\\);.*42\[ \t\]+.*\}\r\n$gdb_prompt $" { incr testcnt }
+ -re ".*$gdb_prompt $" { fail "list 35-42" ; gdb_suppress_tests }
+ timeout { fail "list 35-42 (timeout)" ; gdb_suppress_tests }
+ }
+
+ pass "repeat list commands to page forward using 'return' ($testcnt tests)"
+ gdb_stop_suppressing_tests;
+}
+
+proc test_list_backwards {} {
+ global gdb_prompt
+
+ set testcnt 0
+
+ send_gdb "list list0.c:33\n"
+ gdb_expect {
+ -re "28\[ \t\]+foo \\(.*\\);.*37\[ \t\]+\}\r\n$gdb_prompt $" { incr testcnt }
+ -re ".*$gdb_prompt $" { fail "list list0.c:33" ; gdb_suppress_tests }
+ timeout { fail "list list0.c:33 (timeout)" ; gdb_suppress_tests }
+ }
+
+ send_gdb "list -\n"
+ gdb_expect {
+ -re "18\[ \t\]+foo \[(\]+.*\[)\]+;.*27\[ \t\]+foo \[(\]+.*\[)\]+;\r\n$gdb_prompt $" { incr testcnt }
+ -re ".*$gdb_prompt $" { fail "list 18-27" ; gdb_suppress_tests }
+ timeout { fail "list 18-27 (timeout)" ; gdb_suppress_tests }
+ }
+
+ send_gdb "list -\n"
+ gdb_expect {
+ -re "8\[ \t\]+breakpoint\[(\]\[)\];.*17\[ \t\]+foo \[(\]+.*\[)\]+;\r\n$gdb_prompt $" { incr testcnt }
+ -re ".*$gdb_prompt $" { fail "list 8-17" ; gdb_suppress_tests }
+ timeout { fail "list 8-17 (timeout)" ; gdb_suppress_tests }
+ }
+
+ send_gdb "list -\n"
+ gdb_expect {
+ -re "1\[ \t\]+#include .*7\[ \t\]+set_debug_traps\[(\]\[)\]+;\r\n$gdb_prompt $" { incr testcnt }
+ -re ".*$gdb_prompt $" { fail "list 1-7" ; gdb_suppress_tests }
+ timeout { fail "list 1-7 (timeout)" ; gdb_suppress_tests }
+ }
+
+ pass "$testcnt successive \"list -\" commands to page backwards"
+ gdb_stop_suppressing_tests;
+}
+
+#
+# Test "list first,last"
+#
+
+proc test_list_range {} {
+ global gdb_prompt
+
+ gdb_test "list list0.c:2,list0.c:5" "2\[ \t\]+\r\n3\[ \t\]+int main \[)(\]+.*5\[ \t\]+int x;" "list range; filename:line1,filename:line2"
+
+ gdb_test "list 2,5" "2\[ \t\]+\r\n3\[ \t\]+int main \[)(\]+.*5\[ \t\]+int x;" "list range; line1,line2"
+
+# gdb_test "list -1,6" "Line number 0 out of range; .*list0.c has 39 lines." "list range; lower bound negative"
+
+# gdb_test "list -100,-40" "Line number -60 out of range; .*list0.c has 39 lines." "list range; both bounds negative"
+
+ gdb_test "list 30,45" "30\[ \t\]+foo \(.*\);.*43\[ \t\]+\}" "list range; upper bound past EOF"
+
+ gdb_test "list 45,100" "Line number 45 out of range; .*list0.c has 43 lines." "list range; both bounds past EOF"
+
+ gdb_test "list list0.c:2,list1.c:17" "Specified start and end are in different files." "list range, must be same files"
+}
+
+#
+# Test "list filename:function"
+#
+
+proc test_list_filename_and_function {} {
+ global gdb_prompt
+
+ set testcnt 0
+
+ # gcc appears to generate incorrect debugging information for code
+ # in include files, which breaks this test.
+ # SunPRO cc is the second case below, it's also correct.
+ send_gdb "list list0.c:main\n"
+ gdb_expect {
+ -re "1\[ \t\]+#include .*10\[ \t\]+x = 0;\r\n$gdb_prompt $" {
+ incr testcnt
+ }
+ -re "5\[ \t\]+int x;.*14\[ \t\]+foo \[(\]+.*\[)\]+;\r\n$gdb_prompt $" {
+ pass "list function in source file 1"
+ }
+ -re ".*$gdb_prompt $" { fail "list list0.c:main" }
+ timeout { fail "list list0.c:main (timeout)" }
+ }
+
+ # The i960 is a second case
+
+ # Not sure what the point of having this function be unused is.
+ # AIX is legitimately removing it.
+ setup_xfail "rs6000-*-aix*"
+ send_gdb "list list0.c:unused\n"
+ gdb_expect {
+ -re "40\[ \t\]+unused.*43\[ \t\]+\}\r\n$gdb_prompt $" {
+ incr testcnt
+ }
+ -re "37.*42\[ \t\]+\}\r\n$gdb_prompt $" {
+ incr testcnt
+ }
+ -re ".*$gdb_prompt $" { fail "list list0.c:unused" }
+ timeout { fail "list list0.c:unused (timeout)" }
+ }
+ clear_xfail "rs6000-*-aix*"
+
+ # gcc appears to generate incorrect debugging information for code
+ # in include files, which breaks this test.
+ # Ultrix gdb is the second case, one line different but still correct.
+ # SunPRO cc is the third case.
+ setup_xfail "rs6000-*-*" 1804
+ setup_xfail "powerpc-*-*" 1804
+ setup_xfail_format "DWARF 1"
+ setup_xfail_format "COFF"
+ send_gdb "list list0.h:foo\n"
+ gdb_expect {
+ -re "2\[ \t\]+including file. This.*11\[ \t\]+bar \[(\]+.*\[)\]+;\r\n$gdb_prompt $" {
+ incr testcnt
+ }
+ -re "1\[ \t\]+/. An include file.*10\[ \t\]+bar \[(\]+.*\[)\]+;\r\n$gdb_prompt $" {
+ incr testcnt
+ }
+ -re "3\[ \t\]+.*12\[ \t\]+bar \[(\]+.*\[)\]+;\r\n$gdb_prompt $" {
+ incr testcnt
+ }
+ -re "No source file named list0.h.\r\n$gdb_prompt $" {
+ fail "list list0.h:foo"
+ }
+ -re ".*$gdb_prompt $" { fail "list list0.h:foo" }
+ timeout { fail "list list0.h:foo (timeout)" }
+ }
+
+ # Ultrix gdb is the second case.
+ send_gdb "list list1.c:bar\n"
+ gdb_expect {
+ -re "4\[ \t\]+void.*13\[ \t\]+\}\r\n$gdb_prompt $" {
+ incr testcnt
+ }
+ -re "4\[ \t\]+void.*12\[ \t\]*long_line ..;\r\n$gdb_prompt $" {
+ incr testcnt
+ }
+ -re "4\[ \t\]+void.*11\[ \t\]*\r\n$gdb_prompt $" {
+ incr testcnt
+ }
+ -re ".*$gdb_prompt $" { fail "list list1.c:bar" }
+ timeout { fail "list list1.c:bar (timeout)" }
+ }
+
+ # The i960 is a second case
+
+ # Not sure what the point of having this function be unused is.
+ # AIX is legitimately removing it.
+ setup_xfail "rs6000-*-aix*"
+ send_gdb "list list1.c:unused\n"
+ gdb_expect {
+ -re "12\[ \t\]+long_line \[(\]\[)\];.*13\[ \t\]+\}\r\n.*$gdb_prompt $" {
+ incr testcnt
+ }
+ -re "14.*19\[ \t\]+\}\r\n.*$gdb_prompt $" {
+ incr testcnt
+ }
+ -re ".*$gdb_prompt $" { fail "list list1.c:unused" }
+ timeout { fail "list list1.c:unused (timeout)" }
+ }
+ clear_xfail "rs6000-*-aix*"
+
+ pass "list filename:function ($testcnt tests)"
+
+ # Test some invalid specs
+ # The following test takes the FIXME result on most systems using
+ # DWARF. It fails to notice that main() is not in the file requested.
+
+ setup_xfail "*-*-*"
+
+# Does this actually work ANYWHERE? I believe not, as this is an `aspect' of
+# lookup_symbol(), where, when it is given a specific symtab which does not
+# contain the requested symbol, it will subsequently search all of the symtabs
+# for the requested symbol.
+
+ gdb_test "list list0.c:foo" "Function \"foo\" not defined in .*list0.c" "list filename:function; wrong filename rejected"
+
+ gdb_test "list foobar.c:main" "No source file named foobar.c.|Location not found" "list filename:function; nonexistant file"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "list list0.h:foobar" "Function \"foobar\" not defined.|Location not found" "list filename:function; nonexistant function"
+
+}
+
+proc test_forward_search {} {
+ global timeout
+
+ gdb_test "set listsize 4" ""
+ # On SunOS4, this gives us lines 19-22. On AIX, it gives us
+ # lines 20-23. This depends on whether the line number of a function
+ # is considered to be the openbrace or the first statement--either one
+ # is acceptable.
+ gdb_test "list long_line" "24\[ \t\]+long_line .*"
+
+ gdb_test "search 4321" " not found"
+
+ gdb_test "search 6789" "28\[ \t\]+oof .6789.;"
+
+ # Test that GDB won't crash if the line being searched is extremely long.
+
+ set oldtimeout $timeout
+ set timeout [expr "$timeout + 300"]
+ verbose "Timeout is now $timeout seconds" 2
+ gdb_test "search 1234" ".*1234.*" "search extremely long line (> 5000 chars)"
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+
+gdb_test "set width 0" "" "set width 0"
+
+test_listsize
+get_debug_format
+if [ set_listsize 10 ] then {
+ test_list_include_file
+ test_list_filename_and_number
+ test_list_function
+ test_list_forward
+ test_list_backwards
+ test_repeat_list_command
+ test_list_range
+ test_list_filename_and_function
+ test_forward_search
+}
+
+remote_exec build "rm -f list0.h"
diff --git a/gdb/testsuite/gdb.base/list0.c b/gdb/testsuite/gdb.base/list0.c
new file mode 100644
index 00000000000..b50fdd4323d
--- /dev/null
+++ b/gdb/testsuite/gdb.base/list0.c
@@ -0,0 +1,43 @@
+#include "list0.h"
+
+int main ()
+{
+ int x;
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ x = 0;
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ return 0;
+}
+
+static void
+unused ()
+{
+ /* Not used for anything */
+}
diff --git a/gdb/testsuite/gdb.base/list0.h b/gdb/testsuite/gdb.base/list0.h
new file mode 100644
index 00000000000..d46833060e5
--- /dev/null
+++ b/gdb/testsuite/gdb.base/list0.h
@@ -0,0 +1,37 @@
+/* An include file that actually causes code to be generated in the including file. This is known to cause problems on some systems. */
+#ifdef PROTOTYPES
+extern void bar(int);
+static void foo (int x)
+#else
+static void foo (x) int x;
+#endif
+{
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+}
diff --git a/gdb/testsuite/gdb.base/list1.c b/gdb/testsuite/gdb.base/list1.c
new file mode 100644
index 00000000000..6094104b9cd
--- /dev/null
+++ b/gdb/testsuite/gdb.base/list1.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+#ifdef PROTOTYPES
+void long_line (); int oof (int);
+void bar (int x)
+#else
+void bar (x) int x;
+#endif
+{
+ printf ("%d\n", x);
+
+ long_line ();
+}
+
+static void
+unused ()
+{
+ /* Not used for anything */
+}
+/* This routine has a very long line that will break searching in older versions of GDB. */
+#ifdef PROTOTYPES
+void
+#endif
+long_line ()
+{
+ oof (67);
+
+ oof (6789);
+
+ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 5 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 10 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 15 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 20 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 25 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 30 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 35 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 40 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 45 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 50 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 55 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 60 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 65 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (1234); /* 70 */
+}
+#ifdef PROTOTYPES
+int oof (int n)
+#else
+oof (n) int n;
+#endif
+{
+ return n + 1;
+}
diff --git a/gdb/testsuite/gdb.base/logical.exp b/gdb/testsuite/gdb.base/logical.exp
new file mode 100644
index 00000000000..304f45c66ec
--- /dev/null
+++ b/gdb/testsuite/gdb.base/logical.exp
@@ -0,0 +1,577 @@
+# Copyright 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+# This file is part of the gdb testsuite
+
+#
+# tests for correctenss of logical operators, associativity and precedence
+# with integer type variables
+#
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "int-type"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+#
+# test expressions with "int" types
+#
+
+gdb_test "set variable x=0" "" "set variable x=0"
+gdb_test "set variable y=0" "" "set variable y=0"
+gdb_test "set variable z=0" "" "set variable z=0"
+
+send_gdb "print x\n"
+gdb_expect {
+ -re ".*0.*$gdb_prompt $" {
+ pass "print value of x"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x" }
+ timeout { fail "(timeout) print value of x" }
+ }
+
+
+send_gdb "print y\n"
+gdb_expect {
+ -re ".*0.*$gdb_prompt $" {
+ pass "print value of y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of y" }
+ timeout { fail "(timeout) print value of y" }
+ }
+
+send_gdb "print z\n"
+gdb_expect {
+ -re ".*0.*$gdb_prompt $" {
+ pass "print value of z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of z" }
+ timeout { fail "(timeout) print value of z" }
+ }
+
+
+# truth tables for && , || , !
+
+send_gdb "print x && y\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x<y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<y" }
+ timeout { fail "(timeout) print value of x<y" }
+ }
+
+
+
+send_gdb "print x || y\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x<=y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<=y" }
+ timeout { fail "(timeout) print value of x<=y" }
+ }
+
+send_gdb "print !x\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x>y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x>y" }
+ timeout { fail "(timeout) print value of x>y" }
+ }
+
+gdb_test "set variable y=1" "" "set variable y=1"
+
+send_gdb "print x && y\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x<y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<y" }
+ timeout { fail "(timeout) print value of x<y" }
+ }
+
+
+
+send_gdb "print x || y\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x<=y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<=y" }
+ timeout { fail "(timeout) print value of x<=y" }
+ }
+
+gdb_test "set variable x=1" "" "set variable x=1"
+
+send_gdb "print x && y\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x<y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<y" }
+ timeout { fail "(timeout) print value of x<y" }
+ }
+
+
+
+send_gdb "print x || y\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x<=y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<=y" }
+ timeout { fail "(timeout) print value of x<=y" }
+ }
+
+send_gdb "print !x\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x>y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x>y" }
+ timeout { fail "(timeout) print value of x>y" }
+ }
+
+gdb_test "set variable y=0" "" "set variable y=0"
+
+send_gdb "print x && y\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x<y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<y" }
+ timeout { fail "(timeout) print value of x<y" }
+ }
+
+
+
+send_gdb "print x || y\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x<=y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<=y" }
+ timeout { fail "(timeout) print value of x<=y" }
+ }
+
+
+# end truth tables for &&, ||, !
+
+
+# test associativity of && , || , !
+
+gdb_test "set variable x=0" "" "set variable x=0"
+gdb_test "set variable y=0" "" "set variable y=0"
+gdb_test "set variable z=0" "" "set variable z=0"
+
+send_gdb "print x && y && z\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x && y && z (000)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x && y && z (000) " }
+ timeout { fail "(timeout) print value of x && y && z (000) " }
+ }
+
+send_gdb "print x || y || z\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x || y || z (000)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x || y || z (000)" }
+ timeout { fail "(timeout) print value of x || y || z (000) " }
+ }
+
+send_gdb "print !!x\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of !!x (0)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !!x (0)" }
+ timeout { fail "(timeout) print value of !!x (0) " }
+ }
+
+
+gdb_test "set variable y=1" "" "set variable y=1"
+
+send_gdb "print x && y && z\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x && y && z (010)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x && y && z (010) " }
+ timeout { fail "(timeout) print value of x && y && z (010) " }
+ }
+
+send_gdb "print x || y || z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x || y || z (010)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x || y || z (010)" }
+ timeout { fail "(timeout) print value of x || y || z (010) " }
+ }
+
+
+gdb_test "set variable z=1" "" "set variable z=1"
+
+send_gdb "print x && y && z\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x && y && z (011)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x && y && z (011) " }
+ timeout { fail "(timeout) print value of x && y && z (011) " }
+ }
+
+send_gdb "print x || y || z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x || y || z (011)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x || y || z (011)" }
+ timeout { fail "(timeout) print value of x || y || z (011) " }
+ }
+
+
+gdb_test "set variable x=1" "" "set variable x=1"
+
+send_gdb "print x && y && z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x && y && z (111)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x && y && z (111) " }
+ timeout { fail "(timeout) print value of x && y && z (111) " }
+ }
+
+send_gdb "print x || y || z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x || y || z (111)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x || y || z (111)" }
+ timeout { fail "(timeout) print value of x || y || z (111) " }
+ }
+
+send_gdb "print !!x\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of !!x (1)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !!x (1)" }
+ timeout { fail "(timeout) print value of !!x (1) " }
+ }
+
+
+gdb_test "set variable z=0" "" "set variable z=0"
+
+send_gdb "print x && y && z\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x && y && z (110)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x && y && z (110) " }
+ timeout { fail "(timeout) print value of x && y && z (110) " }
+ }
+
+send_gdb "print x || y || z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x || y || z (110)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x || y || z (110)" }
+ timeout { fail "(timeout) print value of x || y || z (110) " }
+ }
+
+
+
+
+gdb_test "set variable y=0" "" "set variable y=0"
+
+send_gdb "print x && y && z\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x && y && z (100)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x && y && z (100) " }
+ timeout { fail "(timeout) print value of x && y && z (100) " }
+ }
+
+send_gdb "print x || y || z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x || y || z (100)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x || y || z (100)" }
+ timeout { fail "(timeout) print value of x || y || z (100) " }
+ }
+
+
+
+
+gdb_test "set variable z=1" "" "set variable z=1"
+
+send_gdb "print x && y && z\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x && y && z (101)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x && y && z (101) " }
+ timeout { fail "(timeout) print value of x && y && z (101) " }
+ }
+
+send_gdb "print x || y || z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x || y || z (101)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x || y || z (101)" }
+ timeout { fail "(timeout) print value of x || y || z (101) " }
+ }
+
+
+gdb_test "set variable x=0" "" "set variable x=0"
+
+send_gdb "print x && y && z\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x && y && z (001)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x && y && z (001) " }
+ timeout { fail "(timeout) print value of x && y && z (001) " }
+ }
+
+send_gdb "print x || y || z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x || y || z (001)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x || y || z (001)" }
+ timeout { fail "(timeout) print value of x || y || z (001) " }
+ }
+
+
+
+
+# test precedence of &&, || ,!
+
+
+send_gdb "print !x && y\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of !x && y (00)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !x && y (00)" }
+ timeout { fail "(timeout) print value of !x && y (00) " }
+ }
+
+
+gdb_test "set variable x=1" "" "set variable x=1"
+
+
+send_gdb "print !x && y\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of !x && y (10)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !x && y (10)" }
+ timeout { fail "(timeout) print value of !x && y (10) " }
+ }
+
+
+
+
+gdb_test "set variable y=1" "" "set variable y=1"
+
+send_gdb "print !x || y\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of !x || y (11)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !x || y (11)" }
+ timeout { fail "(timeout) print value of !x || y (11) " }
+ }
+
+
+gdb_test "set variable x=0" "" "set variable x=0"
+
+
+send_gdb "print !x || y\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of !x || y (01)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !x || y (01)" }
+ timeout { fail "(timeout) print value of !x || y (01) " }
+ }
+
+
+
+gdb_test "set variable x=1" "" "set variable x=1"
+gdb_test "set variable z=0" "" "set variable z=0"
+
+send_gdb "print x || y && z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x || y && z (110)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x || y && z (110)" }
+ timeout { fail "(timeout) print value of x || y && z (110) " }
+ }
+
+
+gdb_test "set variable y=0" "" "set variable y=0"
+
+
+send_gdb "print x || y && z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x || y && z (100)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x || y && z (100)" }
+ timeout { fail "(timeout) print value of x || y && z (100) " }
+ }
+
+
+
+gdb_test "set variable x=0" "" "set variable x=0"
+
+send_gdb "print x || !y && z\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+
+ gdb_test "set variable x=1" "" "set variable x=1"
+ send_gdb "print x || !y && z\n"
+ gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x || !y && z "
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x || !y && z" }
+ timeout { fail "(timeout) print value of x || !y && z " }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x || y && z " }
+ timeout { fail "(timeout) print value of x || y && z " }
+ }
+
+
+
+
+
+gdb_test "set variable x=1" "" "set variable x=1"
+gdb_test "set variable y=2" "" "set variable y=2"
+gdb_test "set variable w=3" "" "set variable w=3"
+gdb_test "set variable z=3" "" "set variable z=3"
+
+
+send_gdb "print x > y || w == z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x > y || w == z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x > y || w == z" }
+ timeout { fail "(timeout) print value of x > y || w == z " }
+ }
+
+
+gdb_test "set variable x=1" "" "set variable x=1"
+gdb_test "set variable y=2" "" "set variable y=2"
+gdb_test "set variable w=1" "" "set variable w=1"
+gdb_test "set variable z=3" "" "set variable z=3"
+
+
+send_gdb "print x >= y && w != z\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x >= y || w != z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x >= y || w != z" }
+ timeout { fail "(timeout) print value of x >= y || w != z " }
+ }
+
+
+
+gdb_test "set variable x=2" "" "set variable x=2"
+gdb_test "set variable y=2" "" "set variable y=2"
+gdb_test "set variable w=2" "" "set variable w=2"
+gdb_test "set variable z=3" "" "set variable z=3"
+
+
+send_gdb "print ! x > y || w + z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x > y || w != z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x > y || w != z" }
+ timeout { fail "(timeout) print value of x > y || w != z " }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.base/long_long.c b/gdb/testsuite/gdb.base/long_long.c
new file mode 100644
index 00000000000..04fba92897e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/long_long.c
@@ -0,0 +1,61 @@
+/* Test long long expression; test printing in general.
+ *
+ * /CLO/BUILD_ENV/Exports/cc -g +e -o long_long long_long.c
+ *
+ * or
+ *
+ * cc +e +DA2.0 -g -o long_long long_long.c
+ */
+
+#ifdef PROTOTYPES
+long long callee(long long i)
+#else
+long long callee( i )
+long long i;
+#endif
+{
+ register long long result;
+
+ result = 0x12345678;
+ result = result << i;
+ result += 0x9abcdef0;
+
+ return result;
+}
+
+int known_types()
+{
+ long long bin = 0, oct = 0, dec = 0, hex = 0;
+
+ /* Known values, filling the full 64 bits.
+ */
+ bin = 0x123456789abcdefLL; /* 64 bits = 16 hex digits */
+ oct = 01234567123456701234567LL; /* = 21+ octal digits */
+ dec = 12345678901234567890ULL; /* = 19+ decimal digits */
+
+ /* Stop here and look!
+ */
+ hex = bin - dec | oct;
+
+ return 0;
+}
+
+int main() {
+
+ register long long x, y;
+ register long long i;
+
+ x = (long long) 0xfedcba9876543210LL;
+ y = x++;
+ x +=y;
+ i = 11;
+ x = callee( i );
+ y += x;
+
+ known_types();
+
+ return 0;
+}
+
+
+
diff --git a/gdb/testsuite/gdb.base/long_long.exp b/gdb/testsuite/gdb.base/long_long.exp
new file mode 100644
index 00000000000..7084a8deee1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/long_long.exp
@@ -0,0 +1,304 @@
+# Copyright 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+
+# long_long.exp Test printing of 64-bit things in 32-bit gdb.
+# Also test differnet kinds of formats.
+#
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [target_info exists no_long_long] {
+ return 0
+}
+
+set testfile long_long
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# What compiler are we using?
+#
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+if {$hp_cc_compiler} {
+ set flag "+e"
+} else {
+ set flag ""
+}
+
+if { [gdb_compile "${srcfile}" "${binfile}" executable [concat debug "additional_flags=$flag -w"]] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# use this to debug:
+#log_user 1
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if { ![runto known_types] } then {
+ fail "run to known_types"
+ return
+}
+
+set target_bigendian_p 1
+send_gdb "show endian\n"
+gdb_expect {
+ -re ".*little endian.*$gdb_prompt $" { set target_bigendian_p 0 }
+ -re ".*big endian.*$gdb_prompt $" { }
+ -re ".*$gdb_prompt $" {
+ fail "getting target endian"
+ }
+ default { fail "(timeout) getting target endian" }
+}
+
+# Detect targets with 2-byte integers. Yes, it's not general to assume
+# that all others have 4-byte ints, but don't worry about it until one
+# actually exists.
+
+set sizeof_int 4
+send_gdb "print sizeof(int)\n"
+gdb_expect {
+ -re ".* = 2.*$gdb_prompt $" { set sizeof_int 2 }
+ -re ".*$gdb_prompt $" { }
+ default { }
+}
+
+# Detect targets with 2-byte pointers. Assume all others use 4-bytes.
+set sizeof_ptr 4
+send_gdb "print sizeof(void*)\n"
+gdb_expect {
+ -re ".* = 2.*$gdb_prompt $" { set sizeof_ptr 2 }
+ -re ".*$gdb_prompt $" { }
+ default { }
+}
+
+# Detect targets with 4-byte shorts. Assume all others use 2-bytes.
+
+set sizeof_short 2
+send_gdb "print sizeof(short)\n"
+gdb_expect {
+ -re ".* = 4.*$gdb_prompt $" { set sizeof_short 4 }
+ -re ".*$gdb_prompt $" { }
+ default { }
+}
+
+# Detect targets with 4-byte doubles.
+
+set sizeof_double 8
+send_gdb "print sizeof(double)\n"
+gdb_expect {
+ -re ".* = 4.*$gdb_prompt $" { set sizeof_double 4 }
+ -re ".*$gdb_prompt $" { }
+ default { }
+}
+
+gdb_test "n 4" ".*38.*" "get to known place"
+
+# Check the hack for long long prints.
+#
+gdb_test "p/x hex" ".*0x0*0.*" "hex print p/x"
+gdb_test "p/x dec" ".*0xab54a98ceb1f0ad2.*" "decimal print p/x"
+# see if 'p/<code>' is handled same as 'p /<code>'
+#
+gdb_test "p /x dec" ".*0xab54a98ceb1f0ad2.*" "default print dec"
+gdb_test "p /x bin" ".*0x0*123456789abcdef.*" "default print bin"
+gdb_test "p /x oct" ".*0xa72ee53977053977.*" "default print oct"
+gdb_test "p hex" ".*= 0*x*0*0.*" "default print hex"
+
+gdb_test "p/u dec" ".*12345678901234567890.*" "decimal print p/u"
+gdb_test "p/t bin" ".*0*100100011010001010110011110001001101010111100110111101111.*" "binary print"
+gdb_test "p/o oct" ".*01234567123456701234567.*" "octal print"
+gdb_test "p /d bin" ".*81985529216486895.*" "print +ve long long"
+gdb_test "p/d dec" ".*-6101065172474983726.*" "decimal print p/d"
+
+# Try all the combinations to bump up coverage.
+#
+gdb_test "p/d oct" ".*-6399925985474168457.*"
+gdb_test "p/u oct" ".*12046818088235383159.*"
+gdb_test "p/o oct" ".*.*"
+gdb_test "p/t oct" ".*1010011100101110111001010011100101110111000001010011100101110111.*"
+if { $sizeof_ptr == 2 } {
+ gdb_test "p/a oct" ".*0x.*3977.*"
+} else {
+ gdb_test "p/a oct" ".*0x.*77053977.*"
+}
+gdb_test "p/c oct" ".*'w'.*"
+
+if { $sizeof_double == 8 } {
+
+# ARM floating point numbers are not strictly little endian or big endian,
+# but a hybrid. They are in little endian format with the two words
+# swapped in big endian format.
+
+ if { [istarget "arm*-*-*"] || \
+ [istarget "xscale*-*-*"] || \
+ [istarget "strongarm*-*-*"] } then {
+ # assume the long long represents a floating point double in ARM format
+ gdb_test "p/f oct" ".*2.1386676354387559e\\+265.*"
+ } else {
+ # assume the long long represents a floating point double in little
+ # endian format
+ gdb_test "p/f oct" ".*-5.9822653797615723e-120.*"
+ }
+
+} else {
+
+ gdb_test "p/f oct" ".*-2.42716126e-15.*"
+
+}
+
+if { $target_bigendian_p } {
+
+ if { $sizeof_int == 4 } {
+
+ gdb_test "p/d *(int *)&oct" ".*-1490098887.*"
+ gdb_test "p/u *(int *)&oct" ".*2804868409.*"
+ gdb_test "p/o *(int *)&oct" ".*024713562471.*"
+ gdb_test "p/t *(int *)&oct" ".*10100111001011101110010100111001.*"
+
+ if { $sizeof_ptr == 2 } {
+ gdb_test "p/a *(int *)&oct" ".*0xe539.*"
+ } else {
+ gdb_test "p/a *(int *)&oct" ".*0xf*a72ee539.*"
+ }
+
+ gdb_test "p/c *(int *)&oct" ".*57 '9'.*"
+ gdb_test "p/f *(int *)&oct" ".*-2.42716126e-15.*"
+
+ } else {
+
+ gdb_test "p/d *(int *)&oct" ".*-22738.*"
+ gdb_test "p/u *(int *)&oct" ".*42798.*"
+ gdb_test "p/o *(int *)&oct" ".*0123456.*"
+ gdb_test "p/t *(int *)&oct" ".*1010011100101110.*"
+
+ if { $sizeof_ptr == 2 } {
+ gdb_test "p/a *(int *)&oct" ".*0xa72e.*"
+ } else {
+ gdb_test "p/a *(int *)&oct" ".*0xffffa72e.*"
+ }
+ gdb_test "p/c *(int *)&oct" ".*46 '.'.*"
+ gdb_test "p/f *(int *)&oct" ".*-22738.*"
+
+ }
+
+ if { $sizeof_short == 2 } {
+ gdb_test "p/d *(short *)&oct" ".*-22738.*"
+ gdb_test "p/u *(short *)&oct" ".*42798.*"
+ gdb_test "p/o *(short *)&oct" ".*0123456.*"
+ gdb_test "p/t *(short *)&oct" ".*1010011100101110.*"
+ if { $sizeof_ptr == 2 } {
+ gdb_test "p/a *(short *)&oct" ".*0xa72e.*"
+ } else {
+ gdb_test "p/a *(short *)&oct" ".*0xf*ffffa72e.*"
+ }
+ gdb_test "p/c *(short *)&oct" ".* 46 '.'.*"
+ gdb_test "p/f *(short *)&oct" ".*-22738.*"
+ } else {
+ gdb_test "p/d *(short *)&oct" ".*-1490098887.*"
+ gdb_test "p/u *(short *)&oct" ".*2804868409.*"
+ gdb_test "p/o *(short *)&oct" ".*024713562471.*"
+ gdb_test "p/t *(short *)&oct" ".*10100111001011101110010100111001.*"
+ gdb_test "p/a *(short *)&oct" ".*0xf*a72ee539.*"
+ gdb_test "p/c *(short *)&oct" ".* 57 '9'.*"
+ gdb_test "p/f *(short *)&oct" ".*-2.42716126e-15.*"
+ }
+
+ gdb_test "x/x &oct" ".*0xa72ee539.*"
+ gdb_test "x/d &oct" ".*.-1490098887*"
+ gdb_test "x/u &oct" ".*2804868409.*"
+ gdb_test "x/o &oct" ".*024713562471.*"
+ gdb_test "x/t &oct" ".*10100111001011101110010100111001.*"
+ if { $sizeof_ptr == 2 } {
+ gdb_test "x/a &oct" ".*0xa72e.*"
+ } else {
+ gdb_test "x/a &oct" ".*0xa72ee539.*"
+ }
+ gdb_test "x/c &oct" ".*-89 .*"
+ # FIXME GDB's output is correct, but this longer match fails.
+ # gdb_test "x/c &oct" ".*-89 '\\\\247'.*"
+ if { $sizeof_double == 8 } {
+ gdb_test "x/f &oct" ".*-5.9822653797615723e-120.*"
+ } else {
+ gdb_test "x/f &oct" ".*-2.42716126e-15.*"
+ }
+
+ # FIXME Fill in the results for all the following tests. (But be careful
+ # about looking at locations with unspecified contents!)
+
+ gdb_test "x/2x &oct" ".*0xa72ee53977053977.*"
+ gdb_test "x/2d &oct" ".*-6399925985474168457.*"
+ gdb_test "x/2u &oct" ".*.*"
+ gdb_test "x/2o &oct" ".*.*"
+ gdb_test "x/2t &oct" ".*.*"
+ gdb_test "x/2a &oct" ".*.*"
+ gdb_test "x/2c &oct" ".*.*"
+ gdb_test "x/2f &oct" ".*.*"
+
+ gdb_test "x/2bx &oct" ".*.*"
+ gdb_test "x/2bd &oct" ".*.*"
+ gdb_test "x/2bu &oct" ".*.*"
+ gdb_test "x/2bo &oct" ".*.*"
+ gdb_test "x/2bt &oct" ".*.*"
+ gdb_test "x/2ba &oct" ".*.*"
+ gdb_test "x/2bc &oct" ".*.*"
+ gdb_test "x/2bf &oct" ".*.*"
+
+ gdb_test "x/2hx &oct" ".*.*"
+ gdb_test "x/2hd &oct" ".*.*"
+ gdb_test "x/2hu &oct" ".*.*"
+ gdb_test "x/2ho &oct" ".*.*"
+ gdb_test "x/2ht &oct" ".*.*"
+ gdb_test "x/2ha &oct" ".*.*"
+ gdb_test "x/2hc &oct" ".*.*"
+ gdb_test "x/2hf &oct" ".*.*"
+
+ gdb_test "x/2wx &oct" ".*.*"
+ gdb_test "x/2wd &oct" ".*.*"
+ gdb_test "x/2wu &oct" ".*.*"
+ gdb_test "x/2wo &oct" ".*.*"
+ gdb_test "x/2wt &oct" ".*.*"
+ gdb_test "x/2wa &oct" ".*.*"
+ gdb_test "x/2wc &oct" ".*.*"
+ gdb_test "x/2wf &oct" ".*.*"
+
+ gdb_test "x/2gx &oct" ".*.*"
+ gdb_test "x/2gd &oct" ".*.*"
+ gdb_test "x/2gu &oct" ".*.*"
+ gdb_test "x/2go &oct" ".*.*"
+ gdb_test "x/2gt &oct" ".*.*"
+ gdb_test "x/2ga &oct" ".*.*"
+ gdb_test "x/2gc &oct" ".*.*"
+ gdb_test "x/2gf &oct" ".*.*"
+
+} else {
+
+ # FIXME Add little-endian versions of these tests, or define a
+ # gdb_test_bi with two strings to match on.
+
+}
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.base/m32r.ld b/gdb/testsuite/gdb.base/m32r.ld
new file mode 100644
index 00000000000..b96077adb6a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/m32r.ld
@@ -0,0 +1,160 @@
+OUTPUT_FORMAT("elf32-m32r", "elf32-m32r",
+ "elf32-m32r")
+OUTPUT_ARCH(m32r)
+ENTRY(_start)
+ SEARCH_DIR(/usr/cygnus/m32r-961018/H-sparc-sun-sunos4.1//lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ OVERLAY 0x300000 : AT (0x400000)
+ {
+ .ovly0 { foo.o(.text) }
+ .ovly1 { bar.o(.text) }
+ }
+ OVERLAY 0x380000 : AT (0x480000)
+ {
+ .ovly2 { baz.o(.text) }
+ .ovly3 { grbx.o(.text) }
+ }
+ OVERLAY 0x340000 : AT (0x440000)
+ {
+ .data00 { foo.o(.data) }
+ .data01 { bar.o(.data) }
+ }
+ OVERLAY 0x3C0000 : AT (0x4C0000)
+ {
+ .data02 { baz.o(.data) }
+ .data03 { grbx.o(.data) }
+ }
+
+ /* Read-only sections, merged into text segment: */
+ . = 0x208000;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) } =0
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ } =0
+ _etext = .;
+ PROVIDE (etext = .);
+ .fini : { *(.fini) } =0
+ .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
+ .rodata1 : { *(.rodata1) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. */
+ . = ALIGN(32) + (ALIGN(8) & (32 - 1));
+ .data :
+ {
+ *(.data)
+ *(.gnu.linkonce.d*)
+ _ovly_table = .;
+ _ovly0_entry = .;
+ LONG(ABSOLUTE(ADDR(.ovly0)));
+ LONG(SIZEOF(.ovly0));
+ LONG(LOADADDR(.ovly0));
+ LONG(0);
+ _ovly1_entry = .;
+ LONG(ABSOLUTE(ADDR(.ovly1)));
+ LONG(SIZEOF(.ovly1));
+ LONG(LOADADDR(.ovly1));
+ LONG(0);
+ _ovly2_entry = .;
+ LONG(ABSOLUTE(ADDR(.ovly2)));
+ LONG(SIZEOF(.ovly2));
+ LONG(LOADADDR(.ovly2));
+ LONG(0);
+ _ovly3_entry = .;
+ LONG(ABSOLUTE(ADDR(.ovly3)));
+ LONG(SIZEOF(.ovly3));
+ LONG(LOADADDR(.ovly3));
+ LONG(0);
+ _data00_entry = .;
+ LONG(ABSOLUTE(ADDR(.data00)));
+ LONG(SIZEOF(.data00));
+ LONG(LOADADDR(.data00));
+ LONG(0);
+ _data01_entry = .;
+ LONG(ABSOLUTE(ADDR(.data01)));
+ LONG(SIZEOF(.data01));
+ LONG(LOADADDR(.data01));
+ LONG(0);
+ _data02_entry = .;
+ LONG(ABSOLUTE(ADDR(.data02)));
+ LONG(SIZEOF(.data02));
+ LONG(LOADADDR(.data02));
+ LONG(0);
+ _data03_entry = .;
+ LONG(ABSOLUTE(ADDR(.data03)));
+ LONG(SIZEOF(.data03));
+ LONG(LOADADDR(.data03));
+ LONG(0);
+ _novlys = .;
+ LONG((_novlys - _ovly_table) / 16);
+
+ CONSTRUCTORS
+ }
+ .data1 : { *(.data1) }
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+ .got : { *(.got.plt) *(.got)}
+ .dynamic : { *(.dynamic) }
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata : { *(.sdata) }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ .sbss : { *(.sbss) *(.scommon) }
+ .bss : { *(.dynbss) *(.bss) *(COMMON) }
+ _end = . ;
+ PROVIDE (end = .);
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the .debug DWARF section are relative to the beginning of the
+ section so we begin .debug at 0. It's not clear yet what needs to happen
+ for the others. */
+ .debug 0 : { *(.debug) }
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ .line 0 : { *(.line) }
+ .stack 0x5ffffc : { _stack = .; *(.stack) }
+ /* These must appear regardless of . */
+}
diff --git a/gdb/testsuite/gdb.base/m32rovly.c b/gdb/testsuite/gdb.base/m32rovly.c
new file mode 100644
index 00000000000..bdb90feae6b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/m32rovly.c
@@ -0,0 +1,225 @@
+
+/*
+ * Ovlymgr.c -- Runtime Overlay Manager for the GDB testsuite.
+ */
+
+#include "ovlymgr.h"
+
+/* Local functions and data: */
+
+extern unsigned long _ovly_table[][4];
+extern unsigned long _novlys __attribute__ ((section (".data")));
+enum ovly_index { VMA, SIZE, LMA, MAPPED};
+
+static void ovly_copy (unsigned long dst, unsigned long src, long size);
+
+/* Flush the data and instruction caches at address START for SIZE bytes.
+ Support for each new port must be added here. */
+/* FIXME: Might be better to have a standard libgloss function that
+ ports provide that we can then use. Use libgloss instead of newlib
+ since libgloss is the one intended to handle low level system issues.
+ I would suggest something like _flush_cache to avoid the user's namespace
+ but not be completely obscure as other things may need this facility. */
+
+static void
+FlushCache (void)
+{
+#ifdef __M32R__
+ volatile char *mspr = (char *) 0xfffffff7;
+ *mspr = 1;
+#endif
+}
+
+/* OverlayLoad:
+ * Copy the overlay into its runtime region,
+ * and mark the overlay as "mapped".
+ */
+
+bool
+OverlayLoad (unsigned long ovlyno)
+{
+ unsigned long i;
+
+ if (ovlyno < 0 || ovlyno >= _novlys)
+ exit (-1); /* fail, bad ovly number */
+
+ if (_ovly_table[ovlyno][MAPPED])
+ return TRUE; /* this overlay already mapped -- nothing to do! */
+
+ for (i = 0; i < _novlys; i++)
+ if (i == ovlyno)
+ _ovly_table[i][MAPPED] = 1; /* this one now mapped */
+ else if (_ovly_table[i][VMA] == _ovly_table[ovlyno][VMA])
+ _ovly_table[i][MAPPED] = 0; /* this one now un-mapped */
+
+ ovly_copy (_ovly_table[ovlyno][VMA],
+ _ovly_table[ovlyno][LMA],
+ _ovly_table[ovlyno][SIZE]);
+
+ FlushCache ();
+
+ return TRUE;
+}
+
+/* OverlayUnload:
+ * Copy the overlay back into its "load" region.
+ * Does NOT mark overlay as "unmapped", therefore may be called
+ * more than once for the same mapped overlay.
+ */
+
+bool
+OverlayUnload (unsigned long ovlyno)
+{
+ if (ovlyno < 0 || ovlyno >= _novlys)
+ exit (-1); /* fail, bad ovly number */
+
+ if (!_ovly_table[ovlyno][MAPPED])
+ exit (-1); /* error, can't copy out a segment that's not "in" */
+
+ ovly_copy (_ovly_table[ovlyno][LMA],
+ _ovly_table[ovlyno][VMA],
+ _ovly_table[ovlyno][SIZE]);
+
+ return TRUE;
+}
+
+#ifdef __D10V__
+#define IMAP0 (*(short *)(0xff00))
+#define IMAP1 (*(short *)(0xff02))
+#define DMAP (*(short *)(0xff04))
+
+static void
+D10VTranslate (unsigned long logical,
+ short *dmap,
+ unsigned long **addr)
+{
+ unsigned long physical;
+ unsigned long seg;
+ unsigned long off;
+
+ /* to access data, we use the following mapping
+ 0x00xxxxxx: Logical data address segment (DMAP translated memory)
+ 0x01xxxxxx: Logical instruction address segment (IMAP translated memory)
+ 0x10xxxxxx: Physical data memory segment (On-chip data memory)
+ 0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)
+ 0x12xxxxxx: Phisical unified memory segment (Unified memory)
+ */
+
+ /* Addresses must be correctly aligned */
+ if (logical & (sizeof (**addr) - 1))
+ exit (-1);
+
+ /* If the address is in one of the two logical address spaces, it is
+ first translated into a physical address */
+ seg = (logical >> 24);
+ off = (logical & 0xffffffL);
+ switch (seg)
+ {
+ case 0x00: /* in logical data address segment */
+ if (off <= 0x7fffL)
+ physical = (0x10L << 24) + off;
+ else
+ /* Logical address out side of on-chip segment, not
+ supported */
+ exit (-1);
+ break;
+ case 0x01: /* in logical instruction address segment */
+ {
+ short map;
+ if (off <= 0x1ffffL)
+ map = IMAP0;
+ else if (off <= 0x3ffffL)
+ map = IMAP1;
+ else
+ /* Logical address outside of IMAP[01] segment, not
+ supported */
+ exit (-1);
+ if (map & 0x1000L)
+ {
+ /* Instruction memory */
+ physical = (0x11L << 24) | off;
+ }
+ else
+ {
+ /* Unified memory */
+ physical = ((map & 0x7fL) << 17) + (off & 0x1ffffL);
+ if (physical > 0xffffffL)
+ /* Address outside of unified address segment */
+ exit (-1);
+ physical |= (0x12L << 24);
+ }
+ break;
+ }
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ physical = logical;
+ break;
+ default:
+ exit (-1); /* error */
+ }
+
+ seg = (physical >> 24);
+ off = (physical & 0xffffffL);
+ switch (seg)
+ {
+ case 0x10: /* dst is a 15 bit offset into the on-chip memory */
+ *dmap = 0;
+ *addr = (long *) (0x0000 + ((short)off & 0x7fff));
+ break;
+ case 0x11: /* dst is an 18-bit offset into the on-chip
+ instruction memory */
+ *dmap = 0x1000L | ((off & 0x3ffffL) >> 14);
+ *addr = (long *) (0x8000 + ((short)off & 0x3fff));
+ break;
+ case 0x12: /* dst is a 24-bit offset into unified memory */
+ *dmap = off >> 14;
+ *addr = (long *) (0x8000 + ((short)off & 0x3fff));
+ break;
+ default:
+ exit (-1); /* error */
+ }
+}
+#endif /* __D10V__ */
+
+static void
+ovly_copy (unsigned long dst, unsigned long src, long size)
+{
+#ifdef __M32R__
+ memcpy ((void *) dst, (void *) src, size);
+ return;
+#endif /* M32R */
+
+#ifdef __D10V__
+ unsigned long *s, *d, tmp;
+ short dmap_src, dmap_dst;
+ short dmap_save;
+
+ /* all section sizes should by multiples of 4 bytes */
+ dmap_save = DMAP;
+
+ D10VTranslate (src, &dmap_src, &s);
+ D10VTranslate (dst, &dmap_dst, &d);
+
+ while (size > 0)
+ {
+ /* NB: Transfer 4 byte (long) quantites, problems occure
+ when only two bytes are transfered */
+ DMAP = dmap_src;
+ tmp = *s;
+ DMAP = dmap_dst;
+ *d = tmp;
+ d++;
+ s++;
+ size -= sizeof (tmp);
+ src += sizeof (tmp);
+ dst += sizeof (tmp);
+ if ((src & 0x3fff) == 0)
+ D10VTranslate (src, &dmap_src, &s);
+ if ((dst & 0x3fff) == 0)
+ D10VTranslate (dst, &dmap_dst, &d);
+ }
+ DMAP = dmap_save;
+#endif /* D10V */
+}
+
diff --git a/gdb/testsuite/gdb.base/macscp.exp b/gdb/testsuite/gdb.base/macscp.exp
new file mode 100644
index 00000000000..283fe844573
--- /dev/null
+++ b/gdb/testsuite/gdb.base/macscp.exp
@@ -0,0 +1,403 @@
+# Test macro scoping.
+# Copyright 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "macscp"
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile "${srcdir}/${subdir}/macscp1.c" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+# Ask GDB to show the current definition of MACRO, and return a list
+# describing the result.
+#
+# The return value has the form {FILE1 FILE2 ... DEF}, which means
+# that MACRO has the definition `DEF', and was defined in `FILE1',
+# which was included from `FILE2', included from ... .
+#
+# If GDB says that MACRO has no definition, return the string `undefined'.
+#
+# If GDB complains that it doesn't have any information about
+# preprocessor macro definitions, return the string `no-macro-info'.
+#
+# If expect times out waiting for GDB, we return the string `timeout'.
+#
+# If GDB's output doesn't otherwise match what we're expecting, we
+# return the empty string.
+
+proc info_macro {macro} {
+ global gdb_prompt
+ global decimal
+
+ set filepat {macscp[0-9]+\.[ch]}
+ set definition {}
+ set location {}
+
+ send_gdb "info macro ${macro}\n"
+
+ set debug_me 0
+
+ if {$debug_me} {exp_internal 1}
+ gdb_expect {
+ -re "Defined at \[^\r\n\]*(${filepat}):${decimal}\[\r\n\]" {
+ # `location' and `definition' should be empty when we see
+ # this message.
+ if {[llength $location] == 0 && [llength $definition] == 0} {
+ set location $expect_out(1,string)
+ exp_continue
+ } else {
+ # Exit this expect loop, with a result indicating failure.
+ set definition {}
+ }
+ }
+ -re "The symbol `${macro}' has no definition as a C/C\\+\\+ preprocessor macro\[^\r\n\]*\[\r\n\]" {
+ # `location' and `definition' should be empty when we see
+ # this message.
+ if {[llength $location] == 0 && [llength $definition] == 0} {
+ set definition undefined
+ exp_continue
+ } else {
+ # Exit this expect loop, with a result indicating failure.
+ set definition {}
+ }
+ }
+ -re "^\[\r\n\]* included at \[^\r\n\]*(${filepat}):${decimal}\[\r\n\]" {
+ # `location' should *not* be empty when we see this
+ # message. It should have recorded at least the initial
+ # `Defined at ' message (for definitions) or ` at' message
+ # (for undefined symbols).
+ if {[llength $location] != 0} {
+ lappend location $expect_out(1,string)
+ exp_continue
+ } else {
+ # Exit this expect loop, with a result indicating failure.
+ set definition {}
+ }
+ }
+ -re "^\[\r\n\]*at \[^\r\n\]*(${filepat}):${decimal}\[\r\n\]" {
+ # This appears after a `has no definition' message.
+ # `location' should be empty when we see it.
+ if {[string compare $definition undefined] == 0 \
+ && [llength $location] == 0} {
+ set location $expect_out(1,string)
+ exp_continue
+ } else {
+ # Exit this expect loop, with a result indicating failure.
+ set definition {}
+ }
+ }
+ -re "#define ${macro} (\[^\r\n\]*)\[\r\n\]" {
+ # `definition' should be empty when we see this message.
+ if {[string compare $definition ""] == 0} {
+ set definition $expect_out(1,string)
+ exp_continue
+ } else {
+ # Exit this expect loop, with a result indicating failure.
+ set definition {}
+ }
+ }
+ -re "has no preprocessor macro information.*$gdb_prompt $" {
+ set definition no-macro-info
+ }
+ -re "$gdb_prompt $" {
+ # Exit the expect loop; let the existing value of `definition'
+ # indicate failure or success.
+ }
+ timeout {
+ set definition timeout
+ }
+ }
+ if {$debug_me} {exp_internal 0}
+
+ switch -exact -- $definition {
+ no-macro-info { return no-macro-info }
+ timeout { return timeout }
+ undefined -
+ default {
+ if {[llength $location] >= 1} {
+ return [concat $location [list $definition]]
+ } else {
+ return {}
+ }
+ }
+ }
+}
+
+
+# Call info_macro to show the definition of MACRO. Expect a result of
+# EXPECTED. Use WHERE in pass/fail messages to identify the context.
+# Return non-zero if we should abort the entire test file, or zero if
+# we can continue.
+proc check_macro {macro expected where} {
+ set func_def [info_macro $macro]
+ if {[string compare $func_def $expected] == 0} {
+ pass "info macro $macro $where"
+ } else {
+ switch -exact -- $func_def {
+ no-macro-info {
+ xfail "executable includes no macro debugging information"
+ return 1
+ }
+ timeout {
+ fail "info macro $macro $where (timeout)"
+ }
+ default {
+ fail "info macro $macro $where"
+ }
+ }
+ }
+ return 0
+}
+
+
+# List the function FUNC, and then show the definition of MACRO,
+# expecting the result EXPECTED.
+proc list_and_check_macro {func macro expected} {
+ gdb_test "list $func" ".*${func}.*"
+ return [check_macro $macro $expected "after `list $func'"]
+}
+
+
+if {[list_and_check_macro main WHERE {macscp1.c {before macscp1_3}}]} {
+ return 0
+}
+list_and_check_macro macscp2_2 WHERE {macscp2.h macscp1.c {before macscp2_2}}
+list_and_check_macro macscp3_2 WHERE {macscp3.h macscp1.c {before macscp3_2}}
+
+
+# Although GDB's macro table structures distinguish between multiple
+# #inclusions of the same file, GDB's other structures don't. So the
+# `list' command here doesn't reliably select one #inclusion or the
+# other, even though it could. It would be nice to eventually change
+# GDB's structures to handle this correctly.
+gdb_test "list macscp4_2_from_macscp2" ".*macscp4_2_, MACSCP4_INCLUSION.*"
+switch -exact -- [info_macro WHERE] {
+ {macscp4.h macscp2.h macscp1.c {before macscp4_2_..., from macscp2.h}} {
+ pass "info macro WHERE after `list macscp_4_2_from_macscp2'"
+ }
+ {macscp4.h macscp3.h macscp1.c {before macscp4_2_..., from macscp3.h}} {
+ # setup_kfail "gdb/555"
+ fail "info macro WHERE after `list macscp_4_2_from_macscp2' (gdb/555)"
+ }
+ timeout {
+ fail "info macro WHERE after `list macscp_4_2_from_macscp2' (timeout)"
+ }
+ default { fail "info macro WHERE after `list macscp_4_2_from_macscp2'" }
+}
+
+gdb_test "list macscp4_2_from_macscp3" ".*macscp4_2_, MACSCP4_INCLUSION.*"
+switch -exact -- [info_macro WHERE] {
+ {macscp4.h macscp3.h macscp1.c {before macscp4_2_..., from macscp3.h}} {
+ pass "info macro WHERE after `list macscp_4_2_from_macscp3'"
+ }
+ {macscp4.h macscp2.h macscp1.c {before macscp4_2_..., from macscp2.h}} {
+ # setup_kfail "gdb/555"
+ fail "info macro WHERE after `list macscp_4_2_from_macscp3' (gdb/555)"
+ }
+ timeout {
+ fail "info macro WHERE after `list macscp_4_2_from_macscp3' (timeout)"
+ }
+ default { fail "info macro WHERE after `list macscp_4_2_from_macscp3'" }
+}
+
+
+#### Test the selection of the macro scope by the current frame.
+
+### A table of functions, in the order they will be reached, which is
+### also the order they appear in the preprocessed output. Each entry
+### has the form {FUNCNAME WHERE KFAILWHERE}, where:
+### - FUNCNAME is the name of the function,
+### - WHERE is the definition we expect to see for the macro `WHERE', as
+### returned by `info_macro', and
+### - KFAILWHERE is an alternate definition which should be reported
+### as a `known failure', due to GDB's inability to distinguish multiple
+### #inclusions of the same file.
+### KFAILWHERE may be omitted.
+
+set funcs {
+ {
+ macscp1_1
+ {macscp1.c {before macscp1_1}}
+ }
+ {
+ macscp2_1
+ {macscp2.h macscp1.c {before macscp2_1}}
+ }
+ {
+ macscp4_1_from_macscp2
+ {macscp4.h macscp2.h macscp1.c {before macscp4_1_..., from macscp2.h}}
+ {macscp4.h macscp3.h macscp1.c {before macscp4_1_..., from macscp3.h}}
+ }
+ {
+ macscp4_2_from_macscp2
+ {macscp4.h macscp2.h macscp1.c {before macscp4_2_..., from macscp2.h}}
+ {macscp4.h macscp3.h macscp1.c {before macscp4_2_..., from macscp3.h}}
+ }
+ {
+ macscp2_2
+ {macscp2.h macscp1.c {before macscp2_2}}
+ }
+ {
+ macscp1_2
+ {macscp1.c {before macscp1_2}}
+ }
+ {
+ macscp3_1
+ {macscp3.h macscp1.c {before macscp3_1}}
+ }
+ {
+ macscp4_1_from_macscp3
+ {macscp4.h macscp3.h macscp1.c {before macscp4_1_..., from macscp3.h}}
+ {macscp4.h macscp2.h macscp1.c {before macscp4_1_..., from macscp2.h}}
+ }
+ {
+ macscp4_2_from_macscp3
+ {macscp4.h macscp3.h macscp1.c {before macscp4_2_..., from macscp3.h}}
+ {macscp4.h macscp2.h macscp1.c {before macscp4_2_..., from macscp2.h}}
+ }
+ {
+ macscp3_2
+ {macscp3.h macscp1.c {before macscp3_2}}
+ }
+ {
+ macscp1_3
+ {macscp1.c {before macscp1_3}}
+ }
+}
+
+
+# Start the program running.
+if {! [runto_main]} {
+ fail "macro tests suppressed: couldn't run to main"
+ return 0
+}
+
+# Set a breakpoint on each of the functions.
+foreach func_entry $funcs {
+ set func [lindex $func_entry 0]
+ gdb_test "break $func" "Breakpoint.*"
+}
+
+# Run to each of the breakpoints and check the definition (or lack
+# thereof) of each macro.
+for {set i 0} {$i < [llength $funcs]} {incr i} {
+ set func_entry [lindex $funcs $i]
+ set func [lindex $func_entry 0]
+ set expected [lindex $func_entry 1]
+ set kfail_expected [lindex $func_entry 2]
+
+ # Run to the breakpoint for $func.
+ gdb_test "continue" "Breakpoint $decimal, $func .*" "continue to $func"
+
+ # Check the macro WHERE.
+ set result [info_macro WHERE]
+ if {[string compare $result $expected] == 0} {
+ pass "info macro WHERE stopped in $func"
+ } elseif {[string compare $result $kfail_expected] == 0} {
+ # setup_kfail "gdb/555"
+ fail "info macro WHERE stopped in $func (gdb/555)"
+ } elseif {[string compare $result timeout] == 0} {
+ fail "info macro WHERE stopped in $func (timeout)"
+ } else {
+ fail "info macro WHERE stopped in $func"
+ }
+
+ # Check that the BEFORE_<func> macros for all prior functions are
+ # #defined, and that those for all subsequent functions are not.
+ for {set j 0} {$j < [llength $funcs]} {incr j} {
+ if {$j != $i} {
+ set func_j_entry [lindex $funcs $j]
+ set func_j [lindex $func_j_entry 0]
+
+ set before_macro "BEFORE_[string toupper $func_j]"
+ set test_name \
+ "$before_macro defined/undefined when stopped at $func"
+ set result [info_macro $before_macro]
+
+ # We can't get the right scope info when we're stopped in
+ # the macro4_ functions.
+ if {[string match macscp4_* $func]} {
+ # setup_kfail "gdb/555"
+ set test_name "$test_name (gdb/555)"
+ }
+ if {$j < $i} {
+ if {[llength $result] >= 2 && \
+ [string compare [lindex $result end] {}] == 0} {
+ pass $test_name
+ } elseif {[string compare $result timeout] == 0} {
+ fail "$test_name (timeout)"
+ } else {
+ fail "$test_name"
+ }
+ } elseif {$j > $i} {
+ switch -- [lindex $result end] {
+ undefined { pass $test_name }
+ timeout { fail "$test_name (timeout)" }
+ default {
+ fail "$test_name"
+ }
+ }
+ }
+
+ set until_macro "UNTIL_[string toupper $func_j]"
+ set test_name \
+ "$until_macro defined/undefined when stopped at $func"
+ set result [info_macro $until_macro]
+
+ # We can't get the right scope info when we're stopped in
+ # the macro4_ functions.
+ if {[string match macscp4_* $func]} {
+ # setup_kfail "gdb/555"
+ set test_name "$test_name (gdb/555)"
+ }
+ if {$j <= $i} {
+ switch -- [lindex $result end] {
+ undefined { pass $test_name }
+ timeout { fail "$test_name (timeout)" }
+ default {
+ fail "$test_name"
+ }
+ }
+ } elseif {$j > $i} {
+ if {[llength $result] >= 2 && \
+ [string compare [lindex $result end] {}] == 0} {
+ pass $test_name
+ } elseif {[string compare $result timeout] == 0} {
+ fail "$test_name (timeout)"
+ } else {
+ fail "$test_name"
+ }
+ }
+ }
+ }
+}
diff --git a/gdb/testsuite/gdb.base/macscp1.c b/gdb/testsuite/gdb.base/macscp1.c
new file mode 100644
index 00000000000..89a1b07d1e6
--- /dev/null
+++ b/gdb/testsuite/gdb.base/macscp1.c
@@ -0,0 +1,80 @@
+#include <stdio.h>
+
+#define SPLICE(a, b) INNER_SPLICE(a, b)
+#define INNER_SPLICE(a, b) a ## b
+#define STRINGIFY(a) INNER_STRINGIFY(a)
+#define INNER_STRINGIFY(a) #a
+
+/* A macro named UNTIL_<func> is #defined until just before the
+ definition of the function <func>.
+
+ A macro named BEFORE_<func> is not #defined until just before the
+ definition of <func>.
+
+ The macro WHERE is redefined before each function <func> to the
+ token list ``before <func>''.
+
+ The macscp IN_MACSCP2_H and IN_MACSCP3_H are defined while
+ processing those header files; macscp4.h uses them to choose
+ appropriate function names, output strings, and macro definitions. */
+
+#define UNTIL_MACSCP1_1
+#define UNTIL_MACSCP2_1
+#define UNTIL_MACSCP4_1_FROM_MACSCP2
+#define UNTIL_MACSCP4_2_FROM_MACSCP2
+#define UNTIL_MACSCP2_2
+#define UNTIL_MACSCP1_2
+#define UNTIL_MACSCP3_1
+#define UNTIL_MACSCP4_1_FROM_MACSCP3
+#define UNTIL_MACSCP4_2_FROM_MACSCP3
+#define UNTIL_MACSCP3_2
+#define UNTIL_MACSCP1_3
+
+#define WHERE before macscp1_1
+#define BEFORE_MACSCP1_1
+#undef UNTIL_MACSCP1_1
+void
+macscp1_1 ()
+{
+ puts ("macscp1_1");
+}
+
+#include "macscp2.h"
+
+#undef WHERE
+#define WHERE before macscp1_2
+#define BEFORE_MACSCP1_2
+#undef UNTIL_MACSCP1_2
+void
+macscp1_2 ()
+{
+ puts ("macscp1_2");
+}
+
+#include "macscp3.h"
+
+#undef WHERE
+#define WHERE before macscp1_3
+#define BEFORE_MACSCP1_3
+#undef UNTIL_MACSCP1_3
+void
+macscp1_3 ()
+{
+ puts ("macscp1_3");
+}
+
+int
+main (int argc, char **argv)
+{
+ macscp1_1 ();
+ macscp2_1 ();
+ macscp4_1_from_macscp2 ();
+ macscp4_2_from_macscp2 ();
+ macscp2_2 ();
+ macscp1_2 ();
+ macscp3_1 ();
+ macscp4_1_from_macscp3 ();
+ macscp4_2_from_macscp3 ();
+ macscp3_2 ();
+ macscp1_3 ();
+}
diff --git a/gdb/testsuite/gdb.base/macscp2.h b/gdb/testsuite/gdb.base/macscp2.h
new file mode 100644
index 00000000000..ef0feaac5a5
--- /dev/null
+++ b/gdb/testsuite/gdb.base/macscp2.h
@@ -0,0 +1,25 @@
+#define IN_MACSCP2_H
+
+#undef WHERE
+#define WHERE before macscp2_1
+#define BEFORE_MACSCP2_1
+#undef UNTIL_MACSCP2_1
+void
+macscp2_1 ()
+{
+ puts ("macscp2_1");
+}
+
+#include "macscp4.h"
+
+#undef WHERE
+#define WHERE before macscp2_2
+#define BEFORE_MACSCP2_2
+#undef UNTIL_MACSCP2_2
+void
+macscp2_2 ()
+{
+ puts ("macscp2_2");
+}
+
+#undef IN_MACSCP2_H
diff --git a/gdb/testsuite/gdb.base/macscp3.h b/gdb/testsuite/gdb.base/macscp3.h
new file mode 100644
index 00000000000..ebfcc6e1930
--- /dev/null
+++ b/gdb/testsuite/gdb.base/macscp3.h
@@ -0,0 +1,25 @@
+#define IN_MACSCP3_H
+
+#undef WHERE
+#define WHERE before macscp3_1
+#define BEFORE_MACSCP3_1
+#undef UNTIL_MACSCP3_1
+void
+macscp3_1 ()
+{
+ puts ("macscp3_1");
+}
+
+#include "macscp4.h"
+
+#undef WHERE
+#define WHERE before macscp3_2
+#define BEFORE_MACSCP3_2
+#undef UNTIL_MACSCP3_2
+void
+macscp3_2 ()
+{
+ puts ("macscp3_2");
+}
+
+#undef IN_MACSCP3_H
diff --git a/gdb/testsuite/gdb.base/macscp4.h b/gdb/testsuite/gdb.base/macscp4.h
new file mode 100644
index 00000000000..5302d8d3c47
--- /dev/null
+++ b/gdb/testsuite/gdb.base/macscp4.h
@@ -0,0 +1,44 @@
+/* Put together a macro we can use as part of function names. */
+#undef MACSCP4_INCLUSION
+#ifdef IN_MACSCP2_H
+#define MACSCP4_INCLUSION from_macscp2
+#endif
+#ifdef IN_MACSCP3_H
+#define MACSCP4_INCLUSION from_macscp3
+#endif
+
+#undef WHERE
+#ifdef IN_MACSCP2_H
+#define WHERE before macscp4_1_..., from macscp2.h
+#define BEFORE_MACSCP4_1_FROM_MACSCP2
+#undef UNTIL_MACSCP4_1_FROM_MACSCP2
+#endif
+#ifdef IN_MACSCP3_H
+#define WHERE before macscp4_1_..., from macscp3.h
+#define BEFORE_MACSCP4_1_FROM_MACSCP3
+#undef UNTIL_MACSCP4_1_FROM_MACSCP3
+#endif
+void
+SPLICE (macscp4_1_, MACSCP4_INCLUSION) ()
+{
+ puts ("macscp4_1_" STRINGIFY(MACSCP4_INCLUSION));
+}
+
+#undef WHERE
+#ifdef IN_MACSCP2_H
+#define WHERE before macscp4_2_..., from macscp2.h
+#define BEFORE_MACSCP4_2_FROM_MACSCP2
+#undef UNTIL_MACSCP4_2_FROM_MACSCP2
+#endif
+#ifdef IN_MACSCP3_H
+#define WHERE before macscp4_2_..., from macscp3.h
+#define BEFORE_MACSCP4_2_FROM_MACSCP3
+#undef UNTIL_MACSCP4_2_FROM_MACSCP3
+#endif
+void
+SPLICE (macscp4_2_, MACSCP4_INCLUSION) ()
+{
+ puts ("macscp4_2_" STRINGIFY(MACSCP4_INCLUSION));
+}
+
+#define DEFINED_IN_MACSCP4 this was defined in macscp4.h.
diff --git a/gdb/testsuite/gdb.base/maint.exp b/gdb/testsuite/gdb.base/maint.exp
new file mode 100644
index 00000000000..ac2e9f87526
--- /dev/null
+++ b/gdb/testsuite/gdb.base/maint.exp
@@ -0,0 +1,678 @@
+# Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+# this file tests maintenance commands and help on those.
+
+# source file used is break.c
+
+
+#maintenance check-symtabs -- Check consistency of psymtabs and symtabs
+#maintenance space -- Set the display of space usage
+#maintenance set -- Set GDB internal variables used by the GDB maintainer
+#maintenance show -- Show GDB internal variables used by the GDB maintainer
+#maintenance time -- Set the display of time usage
+#maintenance demangle -- Demangle a C++ mangled name
+#maintenance dump-me -- Get fatal error; make debugger dump its core
+#maintenance print -- Maintenance command for printing GDB internal state
+#maintenance info -- Commands for showing internal info about the program being debugged
+#maintenance internal-error -- Give GDB an internal error.
+#
+#maintenance print statistics -- Print statistics about internal gdb state
+#maintenance print objfiles -- Print dump of current object file definitions
+#maintenance print psymbols -- Print dump of current partial symbol definitions
+#maintenance print msymbols -- Print dump of current minimal symbol definitions
+#maintenance print symbols -- Print dump of current symbol definitions
+#maintenance print type -- Print a type chain for a given symbol
+#maintenance print unwind -- Print unwind table entry at given address
+#
+#
+#maintenance info sections -- List the BFD sections of the exec and core files
+#maintenance info breakpoints -- Status of all breakpoints
+#
+
+
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+global usestubs
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "break"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != ""
+ } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ perror "tests suppressed"
+}
+
+
+# The commands we test here produce many lines of output; disable "press
+# <return> to continue" prompts.
+send_gdb "set height 0\n"
+gdb_expect -re "$gdb_prompt $"
+
+# use a larger expect input buffer for long help outputs.
+match_max 6000
+
+#
+# this command does not produce any output
+# unless there is some problem with the symtabs and psymtabs
+# so that branch will really never be covered in this tests here!!
+#
+
+# guo: on linux this command output is huge. for some reason splitting up
+# the regexp checks works.
+#
+send_gdb "maint check-symtabs\n"
+gdb_expect {
+ -re "^maint check-symtabs" {
+ gdb_expect {
+ -re "$gdb_prompt $" \
+ { pass "maint check-symtabs" }
+ timeout { fail "(timeout) maint check-symtabs" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "maint check-symtabs" }
+ timeout { fail "(timeout) maint check-symtabs" }
+ }
+
+send_gdb "maint space\n"
+gdb_expect {
+ -re "\"maintenance space\" takes a numeric argument\\..*$gdb_prompt $"\
+ { pass "maint space" }
+ -re ".*$gdb_prompt $" { fail "maint space" }
+ timeout { fail "(timeout) maint space" }
+ }
+
+send_gdb "maint space 1\n"
+gdb_expect {
+ -re "Space used: $decimal \\(\\+$decimal for this command\\).*$gdb_prompt $"\
+ { pass "maint space 1" }
+ -re ".*$gdb_prompt $" { fail "maint space 1" }
+ timeout { fail "(timeout) maint space 1" }
+ }
+
+
+send_gdb "maint time\n"
+gdb_expect {
+ -re "\"maintenance time\" takes a numeric argument\\..*Space used: $decimal \\(\\+$decimal for this command\\).*$gdb_prompt $"\
+ { pass "maint time" }
+ -re ".*$gdb_prompt $" { fail "maint time" }
+ timeout { fail "(timeout) maint time" }
+ }
+
+send_gdb "maint time 1\n"
+gdb_expect {
+ -re "Command execution time: $decimal.*Space used: $decimal \\(\\+$decimal for this command\\).*$gdb_prompt $"\
+ { pass "maint time 1" }
+ -re ".*$gdb_prompt $" { fail "maint time 1" }
+ timeout { fail "(timeout) maint time 1" }
+ }
+
+send_gdb "maint time 0\n"
+gdb_expect {
+ -re "Space used: $decimal \\(\\+$decimal for this command\\).*$gdb_prompt $"\
+ { pass "maint time 0" }
+ -re ".*$gdb_prompt $" { fail "maint time 0" }
+ timeout { fail "(timeout) maint time 0" }
+ }
+
+
+send_gdb "maint space 0\n"
+gdb_expect {
+ -re "maint space 0\r\n$gdb_prompt $"\
+ { pass "maint space 0" }
+ -re ".*$gdb_prompt $" { fail "maint space 0" }
+ timeout { fail "(timeout) maint space 0" }
+ }
+
+send_gdb "maint demangle\n"
+gdb_expect {
+ -re "\"maintenance demangle\" takes an argument to demangle\\..*$gdb_prompt $"\
+ { pass "maint demangle" }
+ -re ".*$gdb_prompt $" { fail "maint demangle" }
+ timeout { fail "(timeout) maint demangle" }
+ }
+
+send_gdb "maint demangle main\n"
+gdb_expect {
+ -re "Can't demangle \"main\".*$gdb_prompt $"\
+ { pass "maint demangle" }
+ -re ".*$gdb_prompt $" { fail "maint demangle" }
+ timeout { fail "(timeout) maint demangle" }
+ }
+
+
+send_gdb "maint print statistics\n"
+gdb_expect {
+ -re "Statistics for.*break.*Number of \"minimal\" symbols read.*Number of \"partial\" symbols read.*Number of \"types\" defined.*Total memory used for psymbol obstack.*Total memory used for psymbol cache.*Total memory used for symbol obstack.*Total memory used for type obstack.*$gdb_prompt $"\
+ { pass "maint print statistics" }
+ -re ".*$gdb_prompt $" { fail "maint print statistics" }
+ timeout { fail "(timeout) maint print statistics" }
+ }
+
+send_gdb "maint print objfiles\n"
+
+# To avoid timeouts, we avoid expects with many .* patterns that match
+# many lines. Instead, we keep track of which milestones we've seen
+# in the output, and stop when we've seen all of them.
+
+set header 0
+set psymtabs 0
+set symtabs 0
+set keep_looking 1
+
+while {$keep_looking} {
+ gdb_expect {
+
+ -re ".*Object file.*break($EXEEXT)?: Objfile at $hex, bfd at $hex, \[0-9\]* minsyms\[\r\t \]+\n" { set header 1 }
+ -re ".*Psymtabs:\[\r\t \]+\n" { set psymtabs 1 }
+ -re ".*Symtabs:\[\r\t \]+\n" { set symtabs 1 }
+
+ -re ".*$gdb_prompt $" {
+ set keep_looking 0
+ }
+ timeout {
+ fail "(timeout) maint print objfiles"
+ set keep_looking 0
+ }
+ }
+}
+
+proc maint_pass_if {val name} {
+ if $val { pass $name } else { fail $name }
+}
+
+maint_pass_if $header "maint print objfiles: header"
+maint_pass_if $psymtabs "maint print objfiles: psymtabs"
+maint_pass_if $symtabs "maint print objfiles: symtabs"
+
+send_gdb "maint print psymbols\n"
+gdb_expect {
+ -re "print-psymbols takes an output file name and optional symbol file name.*$gdb_prompt $"\
+ { pass "maint print psymbols w/o args" }
+ -re ".*$gdb_prompt $" { fail "maint print psymbols w/o args" }
+ timeout { fail "(timeout) maint print psymbols w/o args" }
+ }
+
+send_gdb "maint print psymbols psymbols_output\n"
+gdb_expect {
+ -re "^maint print psymbols psymbols_output\r\n$gdb_prompt $"\
+ {
+ send_gdb "shell ls psymbols_output\n"
+ gdb_expect {
+ -re "psymbols_output\r\n$gdb_prompt $"\
+ {
+ # We want this grep to be as specific as possible,
+ # so it's less likely to match symbol file names in
+ # psymbols_output. Yes, this actually happened;
+ # poor expect got tons of output, and timed out
+ # trying to match it. --- Jim Blandy <jimb@cygnus.com>
+ send_gdb "shell grep 'main.*function' psymbols_output\n"
+ gdb_expect {
+ -re ".main., function, $hex.*$gdb_prompt $"\
+ { pass "maint print psymbols 1" }
+ -re ".*main. .., function, $hex.*$gdb_prompt $"\
+ { pass "maint print psymbols 2" }
+ -re ".*$gdb_prompt $" { fail "maint print psymbols" }
+ timeout { fail "(timeout) maint print psymbols" }
+ }
+ gdb_test "shell rm -f psymbols_output" ""
+
+ }
+ -re ".*$gdb_prompt $" { fail "maint print psymbols" }
+ timeout { fail "(timeout) maint print psymbols" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "maint print psymbols" }
+ timeout { fail "(timeout) maint print psymbols" }
+ }
+
+
+send_gdb "maint print msymbols\n"
+gdb_expect {
+ -re "print-msymbols takes an output file name and optional symbol file name.*$gdb_prompt $"\
+ { pass "maint print msymbols w/o args" }
+ -re ".*$gdb_prompt $" { fail "maint print msymbols w/o args" }
+ timeout { fail "(timeout) maint print msymbols w/o args" }
+ }
+
+send_gdb "maint print msymbols msymbols_output\n"
+gdb_expect {
+ -re "^maint print msymbols msymbols_output\r\n$gdb_prompt $"\
+ {
+ send_gdb "shell ls msymbols_output\n"
+ gdb_expect {
+ -re "msymbols_output\r\n$gdb_prompt $"\
+ {
+ send_gdb "shell grep factorial msymbols_output\n"
+ gdb_expect {
+ -re "\\\[ *$decimal\\\] T\[ \t\]+$hex factorial.*$gdb_prompt $"\
+ { pass "maint print msymbols" }
+ -re ".*$gdb_prompt $" { fail "maint print msymbols" }
+ timeout { fail "(timeout) maint print msymbols" }
+ }
+ gdb_test "shell rm -f msymbols_output" ""
+
+ }
+ -re ".*$gdb_prompt $" { fail "maint print msymbols" }
+ timeout { fail "(timeout) maint print msymbols" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "maint print msymbols" }
+ timeout { fail "(timeout) maint print msymbols" }
+ }
+
+
+send_gdb "maint print symbols\n"
+gdb_expect {
+ -re "Arguments missing: an output file name and an optional symbol file name.*$gdb_prompt $"\
+ { pass "maint print symbols w/o args" }
+ -re ".*$gdb_prompt $" { fail "maint print symbols w/o args" }
+ timeout { fail "(timeout) maint print symbols w/o args" }
+ }
+
+# This command can legitimately take many minutes to execute. If the
+# executable is dynamically linked, then you get all the debugging
+# info for the entire library --- 89Mb on my system. -jimb
+
+set old_timeout $timeout
+set timeout 600
+
+send_gdb "maint print symbols symbols_output\n"
+gdb_expect {
+ -re "^maint print symbols symbols_output\r\n$gdb_prompt $"\
+ {
+ send_gdb "shell ls symbols_output\n"
+ gdb_expect {
+ -re "symbols_output\r\n$gdb_prompt $"\
+ {
+ # See comments for `maint print psymbols'.
+ send_gdb "shell grep 'main(.*block' symbols_output\n"
+ gdb_expect {
+ -re "int main\\(int, char \\*\\*, char \\*\\*\\); block.*$gdb_prompt $"\
+ { pass "maint print symbols" }
+ -re ".*$gdb_prompt $" { fail "maint print symbols" }
+ timeout { fail "(timeout) maint print symbols" }
+ }
+ gdb_test "shell rm -f symbols_output" ""
+
+ }
+ -re ".*$gdb_prompt $" { fail "maint print symbols" }
+ timeout { fail "(timeout) maint print symbols" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "maint print symbols" }
+ timeout { fail "(timeout) maint print symbols" }
+ }
+
+set timeout $old_timeout
+
+send_gdb "maint print type argc\n"
+gdb_expect {
+ -re "type node $hex\r\nname .int. \\($hex\\)\r\ntagname .<NULL>. \\($hex\\)\r\ncode $hex \\(TYPE_CODE_INT\\)\r\nlength \[24\]\r\nupper_bound_type $hex \\(BOUND_SIMPLE\\)\r\nlower_bound_type $hex \\(BOUND_SIMPLE\\)\r\nobjfile $hex\r\ntarget_type $hex\r\npointer_type $hex\r\nreference_type $hex\r\ntype_chain $hex\r\ninstance_flags $hex\r\nflags $hex\r\nnfields 0 $hex\r\nvptr_basetype $hex\r\nvptr_fieldno -1\r\ntype_specific $hex\r\n$gdb_prompt $"\
+ { pass "maint print type" }
+ -re ".*$gdb_prompt $" { fail "maint print type" }
+ timeout { fail "(timeout) maint print type" }
+ }
+
+if [istarget "hppa*-*-11*"] {
+ setup_xfail hppa*-*-*11* CLLbs14860
+ send "maint print unwind &main\n"
+ expect {
+ -re ".*unwind_table_entry \\($hex\\):\r\n\tregion_start = $hex <main>\r\n\tregion_end = $hex <main\\+\[0-9\]*>\r\n\tflags = Args_stored Save_RP\r\n\tRegion_description = $hex\r\n\tEntry_FR = $hex\r\n\tEntry_GR = $hex\r\n\tTotal_frame_size = $hex\r\n$gdb_prompt $"\
+ { pass "maint print unwind" }
+ -re ".*unwind_table_entry \\($hex\\):\r\n\tregion_start = $hex <main>\r\n\tregion_end = $hex <main\\+\[0-9\]*>\r\n\tflags = Args_stored Save_RP\r\n\tFLD = $hex\r\n\tFLD = $hex\r\n\tFLD = $hex\r\n\tFLD = $hex\r\n$gdb_prompt $"\
+ { xfail "maint print unwind" }
+ -re ".*$gdb_prompt $" { xfail "maint info unwind" }
+ timeout { fail "(timeout) maint print unwind" }
+ }
+}
+
+set oldtimeout $timeout
+set timeout [expr $timeout + 300]
+
+# It'd be nice to check for every possible section. However, that's
+# problematic, since the relative ordering wanders from release to
+# release of the compilers. Instead, we'll just check for two
+# sections which appear to always come out in the same relative
+# order. (If that changes, then we should just check for one
+# section.)
+#
+# And by the way: This testpoint will break for PA64, where a.out's
+# are ELF files.
+#
+send_gdb "maint info sections\n"
+gdb_expect {
+ -re "Exec file:\r\n.*break($EXEEXT)?., file type.*$gdb_prompt $"\
+ { pass "maint info sections" }
+ -re ".*$gdb_prompt $" { fail "maint info sections" }
+ timeout { fail "(timeout) maint info sections" }
+ }
+
+# Test for new option: maint info sections <section name>
+# If you don't have a .text section, this will require tweaking.
+send_gdb "maint info sections .text\n"
+gdb_expect {
+ -re ".*bss.*$gdb_prompt $" { fail "maint info sections .text" }
+ -re ".*data.*$gdb_prompt $" { fail "maint info sections .text" }
+ -re ".* .text .*$gdb_prompt $" { pass "maint info sections .text" }
+ timeout { fail "(timeout) maint info sections .text" }
+}
+
+# Test for new option: CODE section flag
+# If your data section is tagged CODE, xfail this test.
+send_gdb "maint info sections CODE\n"
+gdb_expect {
+ -re ".* .data .*$gdb_prompt $" { fail "maint info sections CODE" }
+ -re ".* .text .*$gdb_prompt $" { pass "maint info sections CODE" }
+ timeout { fail "(timeout) maint info sections CODE" }
+}
+
+# Test for new option: DATA section flag
+# If your text section is tagged DATA, xfail this test.
+send_gdb "maint info sections DATA\n"
+gdb_expect {
+ -re ".* .text .*$gdb_prompt $" { fail "maint info sections DATA" }
+ -re ".* .data .*$gdb_prompt $" { pass "maint info sections DATA" }
+ timeout { fail "(timeout) maint info sections DATA" }
+}
+
+send_gdb "maint info breakpoints\n"
+gdb_expect {
+ -re "Num\[ \t\]+Type\[ \t\]+Disp\[ \t\]+Enb\[ \t\]+Address\[ \t\]+What\r\n1\[ \t\]+breakpoint\[ \t\]+keep\[ \t\]+y\[ \t\]+$hex\[ \t\]+in main at.*break.c:75\r\n\[ \t\]+breakpoint already hit 1 time\r\n.*$gdb_prompt $"\
+ { pass "maint info breakpoints" }
+ -re "Num\[ \t\]+Type\[ \t\]+Disp\[ \t\]+Enb\[ \t\]+Address\[ \t\]+What\r\n1\[ \t\]+breakpoint\[ \t\]+keep\[ \t\]+y\[ \t\]+$hex in main at.*break.c:75\r\n\[ \t\]+breakpoint already hit 1 time\r\n-1\[ \t\]+shlib events\[ \t\]+keep\[ \t\]+y\[ \t\]+$hex.*breakpoint already hit.*$gdb_prompt $"\
+ { pass "maint info breakpoints (with shlib events)" }
+ -re ".*$gdb_prompt $" { fail "maint info breakpoints" }
+ timeout { fail "(timeout) maint info breakpoints" }
+}
+
+send_gdb "maint print\n"
+gdb_expect {
+ -re "\"maintenance print\" must be followed by the name of a print command\\.\r\nList.*unambiguous\\..*$gdb_prompt $"\
+ { pass "maint print w/o args" }
+ -re ".*$gdb_prompt $" { fail "maint print w/o args" }
+ timeout { fail "(timeout) maint print w/o args" }
+ }
+
+send_gdb "maint info\n"
+gdb_expect {
+ -re "\"maintenance info\" must be followed by the name of an info command\\.\r\nList.*unambiguous\\..*$gdb_prompt $"\
+ { pass "maint info w/o args" }
+ -re ".*$gdb_prompt $" { fail "maint info w/o args" }
+ timeout { fail "(timeout) maint info w/o args" }
+ }
+
+send_gdb "maint\n"
+gdb_expect {
+ -re "\"maintenance\" must be followed by the name of a maintenance command\\.\r\nList.*unambiguous\\..*$gdb_prompt $"\
+ { pass "maint w/o args" }
+ -re ".*$gdb_prompt $" { fail "maint w/o args" }
+ timeout { fail "(timeout) maint w/o args" }
+ }
+
+
+set timeout $oldtimeout
+
+#============test help on maint commands
+
+send_gdb "help maint\n"
+gdb_expect {
+ -re "Commands for use by GDB maintainers\\..*Includes commands to dump specific internal GDB structures in.*a human readable form, to cause GDB to deliberately dump core,.*to test internal functions such as the C.. demangler, etc\\..*List of maintenance subcommands:.*maintenance check-symtabs.*maintenance demangle.*(maintenance dump-me.*)?maintenance info.*maintenance internal-error.*maintenance print.*maintenance set.*maintenance show.*maintenance space.*maintenance time.*Type.*help maintenance.*followed by maintenance subcommand name for full documentation\\..*Command name abbreviations are allowed if unambiguous\\..*$gdb_prompt $"\
+ { pass "help maint" }
+ -re ".*$gdb_prompt $" { fail "help maint" }
+ timeout { fail "(timeout) help maint" }
+ }
+
+
+send_gdb "help maint check-symtabs\n"
+gdb_expect {
+ -re "Check consistency of psymtabs and symtabs\\..*$gdb_prompt $"\
+ { pass "help maint check-symtabs" }
+ -re ".*$gdb_prompt $" { fail "help maint check-symtabs" }
+ timeout { fail "(timeout) help maint check-symtabs" }
+ }
+
+send_gdb "help maint space\n"
+gdb_expect {
+ -re "Set the display of space usage\\.\r\nIf nonzero, will cause the execution space for each command to be\r\ndisplayed, following the command's output\\..*$gdb_prompt $"\
+ { pass "help maint space" }
+ -re ".*$gdb_prompt $" { fail "help maint space" }
+ timeout { fail "(timeout) help maint space" }
+ }
+
+send_gdb "help maint time\n"
+gdb_expect {
+ -re "Set the display of time usage\\.\r\nIf nonzero, will cause the execution time for each command to be\r\ndisplayed, following the command's output\\..*$gdb_prompt $"\
+ { pass "help maint time" }
+ -re ".*$gdb_prompt $" { fail "help maint time" }
+ timeout { fail "(timeout) help maint time" }
+ }
+
+send_gdb "help maint demangle\n"
+gdb_expect {
+ -re "Demangle a C\\+\\+ mangled name\\.\r\nCall internal GDB demangler routine to demangle a C\\+\\+ link name\r\nand prints the result\\..*$gdb_prompt $"\
+ { pass "help maint demangle" }
+ -re ".*$gdb_prompt $" { fail "help maint demangle" }
+ timeout { fail "(timeout) help maint demangle" }
+ }
+
+# dump-me is disabled ifdef _WIN32.
+if [ishost *cygwin*] {
+ setup_xfail "*-*-*"
+}
+send_gdb "help maint dump-me\n"
+gdb_expect {
+ -re "Get fatal error; make debugger dump its core\\.\r\nGDB sets it's handling of SIGQUIT back to SIG_DFL and then sends\r\nitself a SIGQUIT signal\\..*$gdb_prompt $"\
+ { pass "help maint dump-me" }
+ -re ".*$gdb_prompt $" { fail "help maint dump-me" }
+ timeout { fail "(timeout) help maint dump-me" }
+ }
+
+send_gdb "help maint internal-error\n"
+gdb_expect {
+ -re "Give GDB an internal error\\.\r\nCause GDB to behave as if an internal error was detected\\..*$gdb_prompt $"\
+ { pass "help maint internal-error" }
+ -re ".*$gdb_prompt $" { fail "help maint internal-error" }
+ timeout { fail "(timeout) help maint internal-error" }
+ }
+
+send_gdb "help maint print statistics\n"
+gdb_expect {
+ -re "Print statistics about internal gdb state\\..*$gdb_prompt $"\
+ { pass "help maint print statistics" }
+ -re ".*$gdb_prompt $" { fail "help maint print statistics" }
+ timeout { fail "(timeout) help maint print statistics" }
+ }
+
+send_gdb "help maint print objfiles\n"
+gdb_expect {
+ -re "Print dump of current object file definitions\\..*$gdb_prompt $"\
+ { pass "help maint print objfiles" }
+ -re ".*$gdb_prompt $" { fail "help maint print objfiles" }
+ timeout { fail "(timeout) help maint print objfiles" }
+ }
+
+send_gdb "help maint print psymbols\n"
+gdb_expect {
+ -re "Print dump of current partial symbol definitions\\.\r\nEntries in the partial symbol table are dumped to file OUTFILE\\.\r\nIf a SOURCE file is specified, dump only that file's partial symbols\\..*$gdb_prompt $"\
+ { pass "help maint print psymbols" }
+ -re ".*$gdb_prompt $" { fail "help maint print psymbols" }
+ timeout { fail "(timeout) help maint print psymbols" }
+ }
+
+send_gdb "help maint print msymbols\n"
+gdb_expect {
+ -re "Print dump of current minimal symbol definitions\\.\r\nEntries in the minimal symbol table are dumped to file OUTFILE\\.\r\nIf a SOURCE file is specified, dump only that file's minimal symbols\\..*$gdb_prompt $"\
+ { pass "help maint print msymbols" }
+ -re ".*$gdb_prompt $" { fail "help maint print msymbols" }
+ timeout { fail "(timeout) help maint print msymbols" }
+ }
+
+send_gdb "help maint print symbols\n"
+gdb_expect {
+ -re "Print dump of current symbol definitions\\.\r\nEntries in the full symbol table are dumped to file OUTFILE\\.\r\nIf a SOURCE file is specified, dump only that file's symbols\\..*$gdb_prompt $"\
+ { pass "help maint print symbols" }
+ -re ".*$gdb_prompt $" { fail "help maint print symbols" }
+ timeout { fail "(timeout) help maint print symbols" }
+ }
+
+
+send_gdb "help maint print type\n"
+gdb_expect {
+ -re "Print a type chain for a given symbol\\.\r\nFor each node in a type chain, print the raw data for each member of\r\nthe type structure, and the interpretation of the data\\..*$gdb_prompt $"\
+ { pass "help maint print type" }
+ -re ".*$gdb_prompt $" { fail "help maint print type" }
+ timeout { fail "(timeout) help maint print type" }
+ }
+
+if [istarget "hppa*-*-*"] {
+ send_gdb "help maint print unwind\n"
+ gdb_expect {
+ -re "Print unwind table entry at given address\\..*$gdb_prompt $"\
+ { pass "help maint print unwind" }
+ -re ".*$gdb_prompt $" { fail "help maint print unwind" }
+ timeout { fail "(timeout) help maint print unwind" }
+ }
+}
+
+send_gdb "help maint info sections\n"
+gdb_expect {
+ -re "List the BFD sections of the exec and core files\\..*$gdb_prompt $"\
+ { pass "help maint info sections" }
+ -re ".*$gdb_prompt $" { fail "help maint info sections" }
+ timeout { fail "(timeout) help maint info sections" }
+ }
+
+
+send_gdb "help maint info breakpoints\n"
+gdb_expect {
+-re "Status of all breakpoints, or breakpoint number NUMBER.*$gdb_prompt $" { pass "help maint info breakpoints" }
+ -re ".*$gdb_prompt $" { fail "help maint info breakpoints" }
+ timeout { fail "(timeout) help maint info breakpoints" }
+ }
+
+#send_gdb "help maint info breakpoints\n"
+#expect {
+# -re "Status of all breakpoints, or breakpoint number NUMBER\\.\[ \r\n\t\]+The \"Type\" column indicates one of:\[ \r\n\t\]+breakpoint\[ \t\]+- normal breakpoint\[ \r\n\t\]+watchpoint\[ \t\]+- watchpoint\[ \r\n\t\]+longjmp\[ \t\]+- internal breakpoint used to step through longjmp\\(\\)\[ \r\n\t\]+longjmp resume - internal breakpoint at the target of longjmp\\(\\)\[ \r\n\t\]+until\[ \t\]+- internal breakpoint used by the \"until\" command\[ \r\n\t\]+finish\[ \t\]+- internal breakpoint used by the \"finish\" command\[ \r\n\t\]+The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\[ \r\n\t\]+the disposition of the breakpoint after it gets hit\\. \"dis\" means that the\[ \r\n\t\]+breakpoint will be disabled\\. The \"Address\" and \"What\" columns indicate the\[ \r\n\t\]+address and file.line number respectively\\.\[ \r\n\t\]+Convenience variable \".*\" and default examine address for \"x\"\[ \r\n\t\]+are set to the address of the last breakpoint listed\\.\[ \r\n\t\]+Convenience variable \".bpnum\" contains the number of the last\[ \r\n\t\]+breakpoint set\\..*$gdb_prompt $"\
+# { pass "help maint info breakpoints" }
+# -re ".*$gdb_prompt $" { fail "help maint info breakpoints" }
+# timeout { fail "(timeout) help maint info breakpoints" }
+# }
+
+send_gdb "help maint info\n"
+gdb_expect {
+ -re "Commands for showing internal info about the program being debugged.*unambiguous\\..*$gdb_prompt $"\
+ { pass "help maint info" }
+ -re ".*$gdb_prompt $" { fail "help maint info" }
+ timeout { fail "(timeout) help maint info" }
+ }
+
+send_gdb "help maint print\n"
+gdb_expect {
+ -re "Maintenance command for printing GDB internal state\\.\[\r\n\]+List of maintenance print subcommands:\[\r\n\]+maintenance print architecture -- Print the internal architecture configuration.*maintenance print msymbols -- Print dump of current minimal symbol definitions.*maintenance print objfiles -- Print dump of current object file definitions.*maintenance print psymbols -- Print dump of current partial symbol definitions.*maintenance print statistics -- Print statistics about internal gdb state.*maintenance print symbols -- Print dump of current symbol definitions.*maintenance print type -- Print a type chain for a given symbol.*Type .help maintenance print. followed by maintenance print subcommand name for full documentation\\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\\..*$gdb_prompt $"\
+ { pass "help maint print" }
+ -re ".*$gdb_prompt $" { fail "help maint print" }
+ timeout { fail "(timeout) help maint print" }
+ }
+
+send_gdb "help maint\n"
+gdb_expect {
+ -re "Commands for use by GDB maintainers\\.\[\r\n\]+Includes commands to dump specific internal GDB structures in\[\r\n\]+a human readable form, to cause GDB to deliberately dump core,\[\r\n\]+to test internal functions such as the C\\+\\+ demangler, etc\\..*Type.*help maintenance.*followed by maintenance subcommand name for full documentation\\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\\..*$gdb_prompt $"\
+ { pass "help maint" }
+ -re ".*$gdb_prompt $" { fail "help maint" }
+ timeout { fail "(timeout) help maint" }
+ }
+
+#set oldtimeout $timeout
+#set timeout [expr $timeout + 300]
+
+if [ishost *cygwin*] {
+ setup_xfail "*-*-*"
+}
+send_gdb "maint dump-me\n"
+gdb_expect {
+ -re "Should GDB dump core.*\\(y or n\\) $"\
+ { send_gdb "n\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" { pass "maint dump-me" }
+ timeout { fail "(timeout) maint dump-me" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "maint dump-me" }
+ timeout { fail "(timeout) maint dump-me" }
+ }
+
+send_gdb "maint internal-error\n"
+gdb_expect {
+ -re "Quit this debugging session.*\\(y or n\\) $" {
+ send_gdb "n\n"
+ gdb_expect {
+ -re "Create a core file.*\\(y or n\\) $" {
+ send_gdb "n\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {
+ pass "maint internal-error"
+ }
+ timeout {
+ fail "(timeout) maint internal-error"
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "maint internal-error"
+ }
+ timeout {
+ fail "(timeout) maint internal-error"
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "maint internal-error"
+ }
+ timeout {
+ fail "(timeout) maint internal-error"
+ }
+}
+
+#set timeout $oldtimeout
+
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.base/mips_pro.c b/gdb/testsuite/gdb.base/mips_pro.c
new file mode 100644
index 00000000000..b659d82ded2
--- /dev/null
+++ b/gdb/testsuite/gdb.base/mips_pro.c
@@ -0,0 +1,57 @@
+/* Tests regarding examination of prologues. */
+
+#ifdef PROTOTYPES
+int
+inner (int z)
+#else
+int
+inner (z)
+ int z;
+#endif
+{
+ return 2 * z;
+}
+
+#ifdef PROTOTYPES
+int
+middle (int x)
+#else
+int
+middle (x)
+ int x;
+#endif
+{
+ if (x == 0)
+ return inner (5);
+ else
+ return inner (6);
+}
+
+#ifdef PROTOTYPES
+int
+top (int y)
+#else
+int
+top (y)
+ int y;
+#endif
+{
+ return middle (y + 1);
+}
+
+#ifdef PROTOTYPES
+int
+main (int argc, char **argv)
+#else
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+#endif
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ return top (-1) + top (1);
+}
diff --git a/gdb/testsuite/gdb.base/mips_pro.exp b/gdb/testsuite/gdb.base/mips_pro.exp
new file mode 100644
index 00000000000..1697eee136a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/mips_pro.exp
@@ -0,0 +1,67 @@
+# Copyright 1997, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile mips_pro
+set srcfile ${srcdir}/$subdir/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+
+# This test must be compiled with -O2 if using gcc.
+
+if {$gcc_compiled} then {
+ if { [gdb_compile "${srcfile}" "${binfile}" executable {debug additional_flags=-O2}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+} else {
+ if { [gdb_compile "${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if [runto middle] then {
+ # PR 3016
+ # warning: Hit heuristic-fence-post without finding
+ # warning: enclosing function for pc 0x1006ead0
+ if {$gcc_compiled} then {
+ setup_xfail "mips*-sgi-irix4*" "mips64*-*-elf"
+ }
+ # The call chain is main -> top -> middle. But gcc can optimize a tail
+ # call to a jump, so the stack may contain either main -> top -> middle
+ # or main -> middle.
+ gdb_test "backtrace" "#0.*middle.*#\[12\].*main.*"
+}
+return 0
diff --git a/gdb/testsuite/gdb.base/miscexprs.c b/gdb/testsuite/gdb.base/miscexprs.c
new file mode 100644
index 00000000000..580255d27cf
--- /dev/null
+++ b/gdb/testsuite/gdb.base/miscexprs.c
@@ -0,0 +1,49 @@
+void
+marker1 ()
+{
+
+}
+
+int
+main ()
+{
+ STORAGE struct {
+ char c[100];
+ } cbig;
+
+ STORAGE struct {
+ int i[800];
+ } ibig;
+
+ STORAGE struct {
+ long l[900];
+ } lbig;
+
+ STORAGE struct {
+ float f[200];
+ } fbig;
+
+ STORAGE struct {
+ double d[300];
+ } dbig;
+
+ STORAGE struct {
+ short s[400];
+ } sbig;
+
+ ibig.i[100] = 5;
+ cbig.c[0] = '\0';
+ cbig.c[100] = 'A';
+ fbig.f[100] = 11.99999;
+ dbig.d[202] = 9.99999999;
+ sbig.s[90] = 255;
+ lbig.l[333] = 999999999;
+
+#ifdef usestubs
+ set_debug_traps ();
+ breakpoint ();
+#endif
+
+ marker1 ();
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/miscexprs.exp b/gdb/testsuite/gdb.base/miscexprs.exp
new file mode 100644
index 00000000000..ad8e11d837f
--- /dev/null
+++ b/gdb/testsuite/gdb.base/miscexprs.exp
@@ -0,0 +1,311 @@
+# Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+
+# This file is part of the gdb testsuite
+# file written by Elena Zannoni (ezannoni@cygnus.com)
+
+#
+# tests for expressions with struct/array elements and mixed operator types
+# with elementary types
+#
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+# By default, the datastructures are allocated on the stack. For targets
+# with very small stack, that will not work. In that case, just set
+# storage to `-DSTORAGE=static' which changes the datastructures to be
+# allocated in data segment.
+set storage "-DSTORAGE="
+if [target_info exists gdb,small_stack_section] {
+ set storage "-DSTORAGE=static"
+}
+
+set additional_flags "additional_flags=-w ${storage}"
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "miscexprs"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug ${additional_flags}]] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+send_gdb "break marker1\n" ; gdb_expect -re ".*$gdb_prompt $"
+
+ send_gdb "cont\n"
+ gdb_expect {
+ -re "Break.* marker1 \\(\\) at .*:$decimal.*$gdb_prompt $" {
+ send_gdb "up\n"
+ gdb_expect {
+ -re ".*main.*$gdb_prompt $" {
+ pass "up from marker1"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "up from marker1"
+ }
+ timeout { fail "up from marker1 (timeout)" }
+ }
+ }
+ -re "$gdb_prompt $" { fail "continue to marker1" }
+ timeout { fail "(timeout) continue to marker1" }
+ }
+
+global hex
+
+send_gdb "print &ibig.i\[0\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(int \\*\\) $hex.*$gdb_prompt $" {
+ pass "print value of &ibig.i\[0\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of &ibig.i\[0\]" }
+ timeout { fail "(timeout) print value of &ibig.i\[0\]" }
+ }
+
+send_gdb "print &cbig.c\[0\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = $hex \"\".*$gdb_prompt $" {
+ pass "print value of &cbig.c\[0\]"
+ }
+ -re ".\[0-9\]* = $hex \"*\".*$gdb_prompt $" {
+ pass "print value of &cbig.c\[0\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of &cbig.c\[0\]" }
+ timeout { fail "(timeout) print value of &cbig.c\[0\]" }
+ }
+
+send_gdb "print &fbig.f\[0\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(float \\*\\) $hex.*$gdb_prompt $" {
+ pass "print value of &fbig.f\[0\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of &fbig.f\[0\]" }
+ timeout { fail "(timeout) print value of &fbig.f\[0\]" }
+ }
+
+send_gdb "print &dbig.d\[0\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(double \\*\\) $hex.*$gdb_prompt $" {
+ pass "print value of &dbig.d\[0\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of &dbig.d\[0\]" }
+ timeout { fail "(timeout) print value of &dbig.d\[0\]" }
+ }
+
+send_gdb "print &sbig.s\[0\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(short \\*\\) $hex.*$gdb_prompt $" {
+ pass "print value of &sbig.s\[0\]"
+ }
+ -re ".\[0-9\]* = \\(short int \\*\\) $hex.*$gdb_prompt $" {
+ pass "print value of &sbig.s\[0\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of &sbig.s\[0\]" }
+ timeout { fail "(timeout) print value of &sbig.s\[0\]" }
+ }
+
+send_gdb "print &lbig.l\[0\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(long \\*\\) $hex.*$gdb_prompt $" {
+ pass "print value of &lbig.l\[0\]"
+ }
+ -re ".\[0-9\]* = \\(long int \\*\\) $hex.*$gdb_prompt $" {
+ pass "print value of &lbig.l\[0\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of &lbig.l\[0\]" }
+ timeout { fail "(timeout) print value of &lbig.l\[0\]" }
+ }
+
+
+send_gdb "print ibig.i\[100\] | 1\n"
+gdb_expect {
+ -re ".\[0-9\]* = 5.*$gdb_prompt $" {
+ pass "print value of ibig.i\[100\] | 1"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of ibig.i\[100\] | 1" }
+ timeout { fail "(timeout) print value of ibig.i\[100\] | 1" }
+ }
+
+
+send_gdb "print sbig.s\[90\] & 127\n"
+gdb_expect {
+ -re ".\[0-9\]* = 127.*$gdb_prompt $" {
+ pass "print value of sbig.s\[90\] & 127"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of sbig.s\[90\] & 127" }
+ timeout { fail "(timeout) print value of sbig.s\[90\] & 127" }
+ }
+
+send_gdb "print !ibig.i\[100\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = $false.*$gdb_prompt $" {
+ pass "print value of !ibig.i\[100\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !ibig.i\[100\]" }
+ timeout { fail "(timeout) print value of !ibig.i\[100\]" }
+ }
+
+send_gdb "print !sbig.s\[90\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = $false.*$gdb_prompt $" {
+ pass "print value of !sbig.s\[90\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !sbig.s\[90\]" }
+ timeout { fail "(timeout) print value of !sbig.s\[90\]" }
+ }
+
+
+send_gdb "print !fbig.f\[100\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = $false.*$gdb_prompt $" {
+ pass "print value of !ibig.i\[100\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !ibig.i\[100\]" }
+ timeout { fail "(timeout) print value of !ibig.i\[100\]" }
+ }
+
+send_gdb "print !dbig.d\[202\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = $false.*$gdb_prompt $" {
+ pass "print value of !ibig.i\[100\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !ibig.i\[100\]" }
+ timeout { fail "(timeout) print value of !ibig.i\[100\]" }
+ }
+
+
+
+send_gdb "print sbig.s\[90\] * 10\n"
+gdb_expect {
+ -re ".\[0-9\]* = 2550.*$gdb_prompt $" {
+ pass "print value of !sbig.s\[90\] * 10"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !sbig.s\[90\] * 10" }
+ timeout { fail "(timeout) print value of !sbig.s\[90\] * 10" }
+ }
+
+send_gdb "print ibig.i\[100\] * sbig.s\[90\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1275.*$gdb_prompt $" {
+ pass "print value of ibig.i\[100\] * sbig.s\[90\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of ibig.i\[100\] * sbig.s\[90\]" }
+ timeout { fail "(timeout) print value of ibig.i\[100\] * sbig.s\[90\]" }
+ }
+
+send_gdb "print fbig.f\[100\] * dbig.d\[202\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = 119.99\[0-9\]*.*$gdb_prompt $" {
+ pass "print value of fbig.f\[100\] * dbig.d\[202\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of fbig.f\[100\] * dbig.d\[202\]" }
+ timeout { fail "(timeout) print value of fbig.f\[100\] * dbig.d\[202\]" }
+ }
+
+send_gdb "print !(sbig.s\[90\] * 2)\n"
+gdb_expect {
+ -re ".\[0-9\]* = $false.*$gdb_prompt $" {
+ pass "print value of !(sbig.s\[90\] * 2)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of !(sbig.s\[90\] * 2)" }
+ timeout { fail "(timeout) print value of !(sbig.s\[90\] * 2)" }
+ }
+
+
+send_gdb "print sizeof(sbig)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 800.*$gdb_prompt $" {
+ pass "print value of sizeof(sbig)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of sizeof(sbig)" }
+ timeout { fail "(timeout) print value of sizeof(sbig)" }
+ }
+
+
+send_gdb "print sizeof(cbig)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 100.*$gdb_prompt $" {
+ pass "print value of sizeof(cbig)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of sizeof(cbig)" }
+ timeout { fail "(timeout) print value of sizeof(cbig)" }
+ }
+
+
+send_gdb "print sizeof(lbig)/sizeof(long)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 900.*$gdb_prompt $" {
+ pass "print value of sizeof(lbig)/sizeof(long)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of sizeof(lbig)/sizeof(long)" }
+ timeout { fail "(timeout) print value of sizeof(lbig)/sizeof(long)" }
+ }
+
+send_gdb "print ibig.i\[100\] << 2\n"
+gdb_expect {
+ -re ".\[0-9\]* = 20.*$gdb_prompt $" {
+ pass "print value of ibig.i\[100\] << 2"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of ibig.i\[100\] << 2" }
+ timeout { fail "(timeout) print value of ibig.i\[100\] << 2" }
+ }
+
+send_gdb "print sbig.s\[90\] >> 4\n"
+gdb_expect {
+ -re ".\[0-9\]* = 15.*$gdb_prompt $" {
+ pass "print value of sbig.s\[90\] >> 4"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of sbig.s\[90\] >> 4" }
+ timeout { fail "(timeout) print value of sbig.s\[90\] >> 4" }
+ }
+
+send_gdb "print lbig.l\[333\] >> 6\n"
+gdb_expect {
+ -re ".\[0-9\]* = 15624999.*$gdb_prompt $" {
+ pass "print value of lbig.l\[333\] >> 6"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of lbig.l\[333\] >> 6" }
+ timeout { fail "(timeout) print value of lbig.l\[333\] >> 6" }
+ }
diff --git a/gdb/testsuite/gdb.base/nodebug.c b/gdb/testsuite/gdb.base/nodebug.c
new file mode 100644
index 00000000000..3e0a4ce7862
--- /dev/null
+++ b/gdb/testsuite/gdb.base/nodebug.c
@@ -0,0 +1,81 @@
+#include <stdlib.h>
+/* Test that things still (sort of) work when compiled without -g. */
+
+int dataglobal = 3; /* Should go in global data */
+static int datalocal = 4; /* Should go in local data */
+int bssglobal; /* Should go in global bss */
+static int bsslocal; /* Should go in local bss */
+
+#ifdef PROTOTYPES
+int
+inner (int x)
+#else
+int
+inner (x)
+ int x;
+#endif
+{
+ return x + dataglobal + datalocal + bssglobal + bsslocal;
+}
+
+#ifdef PROTOTYPES
+static short
+middle (int x)
+#else
+static short
+middle (x)
+ int x;
+#endif
+{
+ return 2 * inner (x);
+}
+
+#ifdef PROTOTYPES
+short
+top (int x)
+#else
+short
+top (x)
+ int x;
+#endif
+{
+ return 2 * middle (x);
+}
+
+#ifdef PROTOTYPES
+int
+main (int argc, char **argv)
+#else
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+#endif
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ return top (argc);
+}
+
+int *x;
+
+#ifdef PROTOTYPES
+int array_index (char *arr, int i)
+#else
+int
+array_index (arr, i)
+ char *arr;
+ int i;
+#endif
+{
+ /* The basic concept is just "return arr[i];". But call malloc so that gdb
+ will be able to call functions. */
+ char retval;
+ x = (int *) malloc (sizeof (int));
+ *x = i;
+ retval = arr[*x];
+ free (x);
+ return retval;
+}
diff --git a/gdb/testsuite/gdb.base/nodebug.exp b/gdb/testsuite/gdb.base/nodebug.exp
new file mode 100644
index 00000000000..836ff8637e1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/nodebug.exp
@@ -0,0 +1,181 @@
+# Copyright 1997, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test that things still (sort of) work when compiled without -g.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile nodebug
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable ""] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+source ${binfile}.ci
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+if [runto inner] then {
+
+ # Expect to find global/local symbols in each of text/data/bss.
+
+ # The exact format for some of this output is not necessarily
+ # ideal, particularly interpreting "p top" requires a fair bit of
+ # savvy about gdb's workings and the meaning of the "{}"
+ # construct. So the details maybe could be tweaked. But the
+ # basic purpose should be maintained, which is (a) users should be
+ # able to interact with these variables with some care (they have
+ # to know how to interpret them according to their real type,
+ # since gdb doesn't know the type), but (b) users should be able
+ # to detect that gdb does not know the type, rather than just
+ # being told they are ints or functions returning int like old
+ # versions of gdb used to do.
+
+ # On alpha (and other ecoff systems) the native compilers put
+ # out debugging info for non-aggregate return values of functions
+ # even without -g, which should be accepted.
+ # Irix5, even though it is ELF, counts as "ecoff" because it
+ # encapsulates ecoff debugging info in a .mdebug section.
+ # Irix6 gcc omits no debug info at all for static functions and
+ # variables, so all tests involving statics fail.
+
+ if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix5*" "mips-sgi-irix6*" }
+ gdb_test "p top" \
+ "\{(<(text variable|function), no debug info>|short \\(int\\)|short \\(\\))\} \[0-9a-fx]* <top(\\(int\\)|)>"
+ if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix5*" "mips-sgi-irix6*" }
+ gdb_test "whatis top" \
+ "(<(text variable|function), no debug info>|short \\(int\\)|short \\(\\))"
+ if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
+ gdb_test "ptype top" "(short|int) \\((|void|int|<non-float parameter>|<non-float parameter>, <non-float parameter>)\\)"
+
+ if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix5*" }
+ setup_xfail "mips-sgi-irix6*"
+ gdb_test "p middle" \
+ "\{(<(text variable|function), no debug info>|short \\(int\\)|short \\(\\))\} \[0-9a-fx]* <middle(\\(int\\)|)>"
+ if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix5*" }
+ setup_xfail "mips-sgi-irix6*"
+ gdb_test "whatis middle" \
+ "(<(text variable|function), no debug info>|short \\(int\\)|short \\(\\))"
+ setup_xfail "mips-sgi-irix6*"
+ gdb_test "ptype middle" "(short|int) \\((|void|int|<non-float parameter>|<non-float parameter>, <non-float parameter>)\\)"
+
+ gdb_test "p dataglobal" "= 3"
+ gdb_test "whatis dataglobal" \
+ "<(data variable|variable), no debug info>|int"
+ gdb_test "ptype dataglobal" "<(data variable|variable), no debug info>|int"
+
+ # The only symbol xcoff puts out for statics is for the TOC entry.
+ # Possible, but hairy, for gdb to deal. Right now it doesn't, it
+ # doesn't know the variables exist at all.
+ setup_xfail "rs6000*-*-aix*"
+ setup_xfail "powerpc*-*-aix*"
+ if {!$gcc_compiled} then { setup_xfail "hppa*-*-hpux*" }
+ if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
+ gdb_test "p datalocal" "= 4"
+ setup_xfail "rs6000*-*-aix*"
+ setup_xfail "powerpc*-*-aix*"
+ if {!$gcc_compiled} then { setup_xfail "hppa*-*-hpux*" }
+ if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
+ gdb_test "whatis datalocal" "<(data variable|variable), no debug info>"
+ setup_xfail "rs6000*-*-aix*"
+ setup_xfail "powerpc*-*-aix*"
+ if {!$gcc_compiled} then { setup_xfail "hppa*-*-hpux*" }
+ if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
+ gdb_test "ptype datalocal" "<(data variable|variable), no debug info>"
+
+ gdb_test "p bssglobal" "= 0"
+ gdb_test "whatis bssglobal" "<(data variable|variable), no debug info>|int"
+ gdb_test "ptype bssglobal" "<(data variable|variable), no debug info>|int"
+
+ setup_xfail "rs6000*-*-aix*"
+ setup_xfail "powerpc*-*-aix*"
+ if {!$gcc_compiled} then { setup_xfail "hppa*-*-hpux*" }
+ if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
+ gdb_test "p bsslocal" "= 0"
+ setup_xfail "rs6000*-*-aix*"
+ setup_xfail "powerpc*-*-aix*"
+ if {!$gcc_compiled} then { setup_xfail "hppa*-*-hpux*" }
+ if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
+ gdb_test "whatis bsslocal" "<(data variable|variable), no debug info>"
+ setup_xfail "rs6000*-*-aix*"
+ setup_xfail "powerpc*-*-aix*"
+ if {!$gcc_compiled} then { setup_xfail "hppa*-*-hpux*" }
+ if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
+ gdb_test "ptype bsslocal" "<(data variable|variable), no debug info>"
+
+ if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
+ gdb_test "backtrace 10" "#0.*inner.*#1.*middle.*#2.*top.*#3.*main.*" \
+ "backtrace from inner in nodebug.exp"
+ # Or if that doesn't work, at least hope for the external symbols
+ # Commented out because if we aren't going to xfail the above test
+ # ever, why bother with a weaker test?
+ #gdb_test "backtrace 10" "#0.*inner.*#1.*#2.*top.*#3.*main.*" \
+ # "backtrace from inner in nodebug.exp for externals"
+
+ # This test is not as obscure as it might look. `p getenv ("TERM")'
+ # is a real-world example, at least on many systems.
+ if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
+ if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "p/c array_index(\"abcdef\",2)"
+ } else {
+ #
+ # On HP-UX, a support function (__d_plt_call) necessary to
+ # implement an inferior call is normally only available when
+ # the inferior was compiled with -g. Thus, we expect this
+ # testpoint to fail on HP-UX.
+ if { [istarget "hppa*-hpux*"] } {
+ send_gdb "p/c array_index(\"abcdef\",2)\n"
+ gdb_expect {
+ -re ".*Suggest linking executable with -g.*$gdb_prompt $" { pass "p/c array_index(\"abcdef\",2)" }
+ -re ".*Cannot find __wdb_call_dummy in.*end.o.*" { pass "p/c array_index(\"abcdef\",2)" }
+ -re ".*99 'c'.*" { pass "p/c array_index(\"abcdef\",2)" }
+ timeout { fail "(timeout) p/c array_index" }
+ }
+ } else {
+ # We need to up this because this can be really slow on some boards.
+ # (malloc() is called as part of the test).
+ set timeout 60;
+ gdb_test {p/c array_index("abcdef",2)} " = 99 'c'"
+ }
+ }
+
+ # Now, try that we can give names of file-local symbols which happen
+ # to be unique, and have it still work
+ if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
+ if [runto middle] then {
+ gdb_test "backtrace 10" "#0.*middle.*#1.*top.*#2.*main.*" \
+ "backtrace from middle in nodebug.exp"
+ }
+}
diff --git a/gdb/testsuite/gdb.base/opaque.exp b/gdb/testsuite/gdb.base/opaque.exp
new file mode 100644
index 00000000000..4030b4f528a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/opaque.exp
@@ -0,0 +1,267 @@
+# Copyright 1992, 1994, 1995, 1996, 1997, 1999, 2002 Free Software
+# Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "opaque"
+set binfile ${objdir}/${subdir}/opaque
+
+#if { [gdb_compile "${srcdir}/${subdir}/opaque0.c ${srcdir}/${subdir}/opaque1.c" "${binfile}" executable {debug}] != "" } {
+# gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+#}
+
+if { [gdb_compile "${srcdir}/${subdir}/opaque0.c" "${binfile}0.o" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/opaque1.c" "${binfile}1.o" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${binfile}0.o ${binfile}1.o" ${binfile} executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# Test basic opaque structure handling (statically).
+# The ordering of the tests is significant. We first try the things that
+# might fail if gdb fails to connect the uses of opaque structures to
+# the actual opaque structure definition.
+
+# When we start up, gdb sets the file containing main() as the current
+# source file. The actual structure foo is defined in a different file.
+# A pointer (foop) to an instance of the opaque struct is defined in the same
+# source file as main(). Ensure that gdb correctly "connected" the definition
+# in the other file with the pointer to the opaque struct in the file containing
+# "foop".
+
+# Define a procedure to set up an xfail for all targets that do not support
+# this sort of cross reference.
+# Any target gcc that has a DBX_NO_XREFS definition in its config file will
+# not support it (FIXME: Is this still true; I suspect maybe not).
+
+# Native alpha ecoff doesn't support it either.
+# I don't think this type of cross reference works for any COFF target
+# either.
+
+proc setup_xfail_on_opaque_pointer {} {
+ global gcc_compiled
+
+ setup_xfail "vax-*-*" "i*86-sequent-bsd*"
+ if {!$gcc_compiled} then {
+ setup_xfail "alpha-*-*" "mips-sgi-irix5*"
+ }
+}
+
+# This seems easier than trying to track different versions of xlc; I'm
+# not sure there is much rhyme or reason regarding which tests it fails
+# and which ones it passes.
+if {[istarget "rs6000-*-aix*"] && !$gcc_compiled} then {
+ warning "xfails in opaque.exp may not be set up correctly for xlc"
+}
+
+setup_xfail_on_opaque_pointer
+gdb_test "whatis foop" \
+ "type = struct foo \[*\]+" \
+ "whatis on opaque struct pointer (statically)"
+
+
+# Ensure that we know the form of the structure that foop points to.
+
+setup_xfail_on_opaque_pointer
+if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+gdb_test "ptype foop" \
+ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\} \[*\]+" \
+ "ptype on opaque struct pointer (statically)"
+
+
+# An instance of the opaque structure (afoo) is defined in a different file.
+# Ensure that we can locate afoo and the structure definition.
+
+gdb_test "whatis afoo" \
+ "type = struct foo" \
+ "whatis on opaque struct instance (statically)"
+
+
+# Ensure that we know the form of "afoo".
+
+gdb_test "ptype afoo" \
+ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\}" \
+ "ptype on opaque struct instance (statically)"
+
+
+# Ensure that we know what a struct foo looks like.
+
+gdb_test "ptype struct foo" \
+ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\}" \
+ "ptype on opaque struct tagname (statically)"
+
+
+#
+# Done with static tests, now test dynamic opaque structure handling.
+# We reload the symbol table so we forget about anything we might
+# have learned during the static tests.
+#
+
+if [istarget "mips-idt-*"] then {
+ # Restart because IDT/SIM runs out of file descriptors.
+ gdb_exit
+ gdb_start
+}
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Run to main, where struct foo is incomplete.
+if ![runto_main] {
+ perror "cannot run to breakpoint at main"
+}
+
+
+# The current source file is now the one containing main(). The structure foo
+# is defined in a different file, but we have a pointer to an instance of
+# the opaque structure in the current file. Ensure we know it's type.
+
+setup_xfail_on_opaque_pointer
+gdb_test "whatis foop" \
+ "type = struct foo \[*\]+" \
+ "whatis on opaque struct pointer (dynamically)"
+
+
+# Ensure that we know the form of the thing foop points to.
+
+setup_xfail_on_opaque_pointer
+if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+gdb_test "ptype foop" \
+ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\} \[*\]+" \
+ "ptype on opaque struct pointer (dynamically) 1"
+
+gdb_test "whatis afoo" \
+ "type = struct foo" \
+ "whatis on opaque struct instance (dynamically) 1"
+
+
+# Ensure that we know the form of afoo, an instance of a struct foo.
+
+gdb_test "ptype afoo" \
+ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\}" \
+ "ptype on opaque struct instance (dynamically) xyz 1"
+
+
+# Ensure that we know the form of an explicit struct foo.
+
+if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+gdb_test "ptype struct foo" \
+ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\}" \
+ "ptype on opaque struct tagname (dynamically) 1"
+
+
+# Now reload the symbols again so we forget about anything we might
+# have learned reading the symbols during the previous tests.
+
+if [istarget "mips-idt-*"] then {
+ # Restart because IDT/SIM runs out of file descriptors.
+ gdb_exit
+ gdb_start
+}
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Run to getfoo, where struct foo is complete.
+if ![runto getfoo] {
+ perror "cannot run to breakpoint at getfoo"
+}
+
+
+# Ensure that we know what foop is.
+
+setup_xfail_on_opaque_pointer
+gdb_test "whatis foop" \
+ "type = struct foo \[*\]+" \
+ "whatis on opaque struct pointer (dynamically) 1"
+
+
+# Ensure that we know the form of the thing foop points to.
+
+setup_xfail_on_opaque_pointer
+if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+gdb_test "ptype foop" \
+ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\} \[*\]+" \
+ "ptype on opaque struct pointer (dynamically) 2"
+
+gdb_test "whatis afoo" \
+ "type = struct foo" \
+ "whatis on opaque struct instance (dynamically) 1"
+
+
+# Ensure that we know the form of afoo, an instance of a struct foo.
+
+gdb_test "ptype afoo" \
+ "type = struct foo \{\r\n int a;\r\n int b;\r\n\}" \
+ "ptype on opaque struct instance (dynamically) 1"
+
+gdb_test "ptype afoo" \
+ "type = struct foo \{\[\r\n\]*.*int a;\[\r\n\]*.*int b;\[\r\n\]*}\[\r\n\]*" \
+ "ptype on opaque struct instance (dynamically) pqr 1"
+
+
+# Ensure that we know the form of an explicit struct foo.
+
+gdb_test "ptype foop" \
+ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\} \[*\]+" \
+ "ptype on opaque struct pointer (dynamically) 2"
+
+gdb_test "whatis afoo" \
+ "type = struct foo" \
+ "whatis on opaque struct instance (dynamically) 2"
+
+
+# Ensure that we know the form of afoo, an instance of a struct foo.
+
+gdb_test "ptype afoo" \
+ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\}" \
+ "ptype on opaque struct instance (dynamically) 2"
+
+
+# Ensure that we know the form of an explicit struct foo.
+
+gdb_test "ptype struct foo" \
+ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\}" \
+ "ptype on opaque struct tagname (dynamically) 2"
diff --git a/gdb/testsuite/gdb.base/opaque0.c b/gdb/testsuite/gdb.base/opaque0.c
new file mode 100644
index 00000000000..5ec4a2aa082
--- /dev/null
+++ b/gdb/testsuite/gdb.base/opaque0.c
@@ -0,0 +1,23 @@
+/* Note that struct foo is opaque (never defined) in this file. This
+ is allowed by C since this file does not reference any members of
+ the structure. The debugger needs to be able to associate this
+ opaque structure definition with the full definition in another
+ file.
+*/
+
+struct foo *foop;
+extern struct foo *getfoo ();
+#ifdef PROTOTYPES
+extern void putfoo (struct foo *foop);
+#endif
+
+int main ()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ foop = getfoo ();
+ putfoo (foop);
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/opaque1.c b/gdb/testsuite/gdb.base/opaque1.c
new file mode 100644
index 00000000000..c34f7aaaae1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/opaque1.c
@@ -0,0 +1,18 @@
+struct foo {
+ int a;
+ int b;
+} afoo = { 1, 2};
+
+struct foo *getfoo ()
+{
+ return (&afoo);
+}
+
+#ifdef PROTOTYPES
+void putfoo (struct foo *foop)
+#else
+void putfoo (foop)
+ struct foo *foop;
+#endif
+{
+}
diff --git a/gdb/testsuite/gdb.base/overlays.c b/gdb/testsuite/gdb.base/overlays.c
new file mode 100644
index 00000000000..d02ed707cd1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/overlays.c
@@ -0,0 +1,34 @@
+/* Support program for testing gdb's ability to debug overlays
+ in the inferior. */
+
+#include "ovlymgr.h"
+
+extern int foo PARAMS((int));
+extern int bar PARAMS((int));
+extern int baz PARAMS((int));
+extern int grbx PARAMS((int));
+
+int main ()
+{
+ int a, b, c, d, e;
+
+ OverlayLoad (0);
+ OverlayLoad (4);
+ a = foo (1);
+ OverlayLoad (1);
+ OverlayLoad (5);
+ b = bar (1);
+ OverlayLoad (2);
+ OverlayLoad (6);
+ c = baz (1);
+ OverlayLoad (3);
+ OverlayLoad (7);
+ d = grbx (1);
+ e = a + b + c + d;
+ return (e != ('f' + 'o' +'o'
+ + 'b' + 'a' + 'r'
+ + 'b' + 'a' + 'z'
+ + 'g' + 'r' + 'b' + 'x'));
+
+}
+
diff --git a/gdb/testsuite/gdb.base/overlays.exp b/gdb/testsuite/gdb.base/overlays.exp
new file mode 100644
index 00000000000..9188b278014
--- /dev/null
+++ b/gdb/testsuite/gdb.base/overlays.exp
@@ -0,0 +1,282 @@
+# Copyright 1997, 1998 Free Software Foundation, Inc.
+#
+# 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.
+#
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+#
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+#
+# test running programs
+#
+
+set prms_id 0
+set bug_id 0
+
+if [istarget "d10v-*-*"] then {
+ set linker_script "${srcdir}/${subdir}/d10v.ld";
+} elseif [istarget "m32r-*-*"] then {
+ set linker_script "${srcdir}/${subdir}/m32r.ld";
+} else {
+ verbose "Skipping overlay test -- not implemented for this target."
+ return
+}
+
+set testfile "overlays"
+set binfile ${objdir}/${subdir}/${testfile}
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set foo ${srcdir}/${subdir}/foo.c
+set bar ${srcdir}/${subdir}/bar.c
+set baz ${srcdir}/${subdir}/baz.c
+set grbx ${srcdir}/${subdir}/grbx.c
+
+if {[gdb_compile "${srcfile}" "${testfile}.o" object {debug}] != ""} then {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+if {[gdb_compile "${srcdir}/${subdir}/ovlymgr.c" ovlymgr.o object {debug}] != ""} then {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+if {[gdb_compile "${foo}" foo.o object {debug} ] != ""} then {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if {[gdb_compile "${bar}" bar.o object {debug}] != ""} then {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+if {[gdb_compile "${baz}" baz.o object {debug}] != ""} then {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+if {[gdb_compile "${grbx}" grbx.o object {debug}] != ""} then {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+if {[gdb_compile "${testfile}.o ovlymgr.o foo.o bar.o baz.o grbx.o" ${binfile} executable "ldscript=-Wl,-T$linker_script"] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+remote_exec build "mv ${testfile}.o foo.o bar.o baz.o grbx.o ovlymgr.o ${objdir}/${subdir}"
+
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+
+if ![runto_main] then {
+ gdb_suppress_tests;
+}
+
+# couple of convenience variables
+set fptrcast [string_to_regexp "(int (*)(int))"]
+set iptrcast [string_to_regexp "(int *)"]
+
+gdb_test "overlay manual" ""
+gdb_test "overlay list" "No sections are mapped." "List with none mapped"
+
+# capture the LMA addresses of [foo bar baz grbx foox barx bazx grbxx]
+
+gdb_test "print \$foo_lma = &foo" \
+ ".* $fptrcast 0x.* <\\*foo\\*>" "foo load addr"
+gdb_test "print \$bar_lma = &bar" \
+ ".* $fptrcast 0x.* <\\*bar\\*>" "bar load addr"
+gdb_test "print \$baz_lma = &baz" \
+ ".* $fptrcast 0x.* <\\*baz\\*>" "baz load addr"
+gdb_test "print \$grbx_lma = &grbx" \
+ ".* $fptrcast 0x.* <\\*grbx\\*>" "grbx load addr"
+gdb_test "print \$foox_lma = &foox" \
+ ".* $iptrcast 0x.*" "foox load addr"
+gdb_test "print \$barx_lma = &barx" \
+ ".* $iptrcast 0x.*" "barx load addr"
+gdb_test "print \$bazx_lma = &bazx" \
+ ".* $iptrcast 0x.*" "bazx load addr"
+gdb_test "print \$grbxx_lma = &grbxx" \
+ ".* $iptrcast 0x.*" "grbxx load addr"
+
+# map each overlay successively, and
+# capture the VMA addresses of [foo bar baz grbx foox barx bazx grbxx]
+
+gdb_test "overlay map .ovly0" ""
+gdb_test "overlay list" "Section .ovly0, loaded at.*, mapped at.*" "List ovly0"
+gdb_test "print \$foo_vma = &foo" \
+ ".* $fptrcast 0x.* <foo>" "foo runtime addr"
+
+gdb_test "overlay map .ovly1" ""
+gdb_test "overlay list" "Section .ovly1, loaded at.*, mapped at.*" "List ovly1"
+gdb_test "print \$bar_vma = &bar" \
+ ".* $fptrcast 0x.* <bar>" "bar runtime addr"
+
+gdb_test "overlay map .ovly2" ""
+gdb_test "overlay list" "Section .ovly2, loaded at.*, mapped at.*" "List ovly2"
+gdb_test "print \$baz_vma = &baz" \
+ ".* $fptrcast 0x.* <baz>" "baz runtime addr"
+
+gdb_test "overlay map .ovly3" ""
+gdb_test "overlay list" "Section .ovly3, loaded at.*, mapped at.*" "List ovly3"
+gdb_test "print \$grbx_vma = &grbx" \
+ ".* $fptrcast 0x.* <grbx>" "grbx runtime addr"
+
+gdb_test "overlay map .data00" ""
+gdb_test "overlay list" "Section .data00, loaded .*, mapped .*" "List data00"
+gdb_test "print \$foox_vma = &foox" \
+ ".* $iptrcast 0x.*" "foox runtime addr"
+
+gdb_test "overlay map .data01" ""
+gdb_test "overlay list" "Section .data01, loaded .*, mapped .*" "List data01"
+gdb_test "print \$barx_vma = &barx" \
+ ".* $iptrcast 0x.*" "barx runtime addr"
+
+gdb_test "overlay map .data02" ""
+gdb_test "overlay list" "Section .data02, loaded .*, mapped .*" "List data02"
+gdb_test "print \$bazx_vma = &bazx" \
+ ".* $iptrcast 0x.*" "bazx runtime addr"
+
+gdb_test "overlay map .data03" ""
+gdb_test "overlay list" "Section .data03, loaded .*, mapped .*" "List data03"
+gdb_test "print \$grbxx_vma = &grbxx" \
+ ".* $iptrcast 0x.*" "grbxx runtime addr"
+
+# Verify that LMA != VMA
+
+gdb_test "print \$foo_lma != \$foo_vma" ".* = 1" "foo's LMA != VMA"
+gdb_test "print \$bar_lma != \$bar_vma" ".* = 1" "bar's LMA != VMA"
+gdb_test "print \$baz_lma != \$baz_vma" ".* = 1" "baz's LMA != VMA"
+gdb_test "print \$grbx_lma != \$grbx_vma" ".* = 1" "grbx's LMA != VMA"
+gdb_test "print \$foox_lma != \$foox_vma" ".* = 1" "foox's LMA != VMA"
+gdb_test "print \$barx_lma != \$barx_vma" ".* = 1" "barx's LMA != VMA"
+gdb_test "print \$bazx_lma != \$bazx_vma" ".* = 1" "bazx's LMA != VMA"
+gdb_test "print \$grbxx_lma != \$grbxx_vma" ".* = 1" "grbxx's LMA != VMA"
+
+# Verify that early-mapped overlays have been bumped out
+# by later-mapped overlays layed over in the same VMA range.
+
+send_gdb "overlay list\n"
+gdb_expect {
+ -re ".*ovly0, " { fail ".ovly0 not unmapped by .ovly1" }
+ -re ".*ovly2, " { fail ".ovly2 not unmapped by .ovly3" }
+ -re ".*data00," { fail ".data00 not unmapped by .data01" }
+ -re ".*data02," { fail ".data02 not unmapped by .data03" }
+ -re ".*$gdb_prompt $" { pass "Automatic unmapping" }
+ timeout { fail "(timeout) Automatic unmapping" }
+}
+
+# Verify that both sec1 and sec2 can be loaded simultaneously.
+proc simultaneous_pair { sec1 sec2 } {
+ global gdb_prompt
+
+ set pairname "$sec1 and $sec2 mapped simultaneously"
+ gdb_test "overlay map $sec1" "" "$pairname: map $sec1"
+ gdb_test "overlay map $sec2" "" "$pairname: map $sec2"
+
+ set seen_sec1 0
+ set seen_sec2 0
+
+ send_gdb "overlay list\n"
+ gdb_expect {
+ -re ".*[string_to_regexp $sec1], " { set seen_sec1 1; exp_continue }
+ -re ".*[string_to_regexp $sec2], " { set seen_sec2 1; exp_continue }
+ -re ".*$gdb_prompt $" {
+ if {$seen_sec1 && $seen_sec2} {
+ pass "$pairname"
+ } else {
+ fail "$pairname"
+ }
+ }
+ timeout { fail "(timeout) $pairname" }
+ }
+}
+
+simultaneous_pair .ovly0 .ovly2
+simultaneous_pair .ovly0 .ovly3
+simultaneous_pair .ovly1 .ovly2
+simultaneous_pair .ovly1 .ovly3
+
+simultaneous_pair .data00 .data02
+simultaneous_pair .data00 .data03
+simultaneous_pair .data01 .data02
+simultaneous_pair .data01 .data03
+
+# test automatic mode
+
+gdb_test "overlay auto" ""
+gdb_test "overlay list" "No sections are mapped." "List none mapped (auto)"
+gdb_test "break foo" "Breakpoint .*at .*file .*foo.c.*" "break foo"
+gdb_test "break bar" "Breakpoint .*at .*file .*bar.c.*" "break bar"
+gdb_test "break baz" "Breakpoint .*at .*file .*baz.c.*" "break baz"
+gdb_test "break grbx" "Breakpoint .*at .*file .*grbx.c.*" "break grbx"
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Breakpoint .* foo .x=1. at .*$gdb_prompt $" { pass "hit foo" }
+ -re ".*$gdb_prompt $" { fail "hit foo" }
+ timeout { fail "(timeout) hit foo" }
+}
+
+send_gdb "backtrace\n"
+gdb_expect {
+ -re "#0 .*foo .*#1 .*main .*$gdb_prompt $" { pass "BT foo" }
+ -re ".*$gdb_prompt $" { fail "BT foo" }
+ timeout { fail "(timeout) BT foo" }
+}
+
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Breakpoint .* bar .x=1. at .*$gdb_prompt $" { pass "hit bar" }
+ -re ".*$gdb_prompt $" { fail "hit bar" }
+ timeout { fail "(timeout) hit bar" }
+}
+
+send_gdb "backtrace\n"
+gdb_expect {
+ -re "#0 .*bar .*#1 .*main .*$gdb_prompt $" { pass "BT bar" }
+ -re ".*$gdb_prompt $" { fail "BT bar" }
+ timeout { fail "(timeout) BT bar" }
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Breakpoint .* baz .x=1. at .*$gdb_prompt $" { pass "hit baz" }
+ -re ".*$gdb_prompt $" { fail "hit baz" }
+ timeout { fail "(timeout) hit baz" }
+}
+
+send_gdb "backtrace\n"
+gdb_expect {
+ -re "#0 .*baz .*#1 .*main .*$gdb_prompt $" { pass "BT baz" }
+ -re ".*$gdb_prompt $" { fail "BT baz" }
+ timeout { fail "(timeout) BT baz" }
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Breakpoint .* grbx .x=1. at .*$gdb_prompt $" { pass "hit grbx" }
+ -re ".*$gdb_prompt $" { fail "hit grbx" }
+ timeout { fail "(timeout) hit grbx" }
+}
+
+send_gdb "backtrace\n"
+gdb_expect {
+ -re "#0 .*grbx .*#1 .*main .*$gdb_prompt $" { pass "BT grbx" }
+ -re ".*$gdb_prompt $" { fail "BT grbx" }
+ timeout { fail "(timeout) BT grbx" }
+}
+
diff --git a/gdb/testsuite/gdb.base/ovlymgr.c b/gdb/testsuite/gdb.base/ovlymgr.c
new file mode 100644
index 00000000000..f4958ed14a3
--- /dev/null
+++ b/gdb/testsuite/gdb.base/ovlymgr.c
@@ -0,0 +1,233 @@
+
+/*
+ * Ovlymgr.c -- Runtime Overlay Manager for the GDB testsuite.
+ */
+
+#include "ovlymgr.h"
+
+/* Local functions and data: */
+
+extern unsigned long _ovly_table[][4];
+extern unsigned long _novlys __attribute__ ((section (".data")));
+enum ovly_index { VMA, SIZE, LMA, MAPPED};
+
+static void ovly_copy (unsigned long dst, unsigned long src, long size);
+
+/* Flush the data and instruction caches at address START for SIZE bytes.
+ Support for each new port must be added here. */
+/* FIXME: Might be better to have a standard libgloss function that
+ ports provide that we can then use. Use libgloss instead of newlib
+ since libgloss is the one intended to handle low level system issues.
+ I would suggest something like _flush_cache to avoid the user's namespace
+ but not be completely obscure as other things may need this facility. */
+
+static void
+FlushCache (void)
+{
+#ifdef __M32R__
+ volatile char *mspr = (char *) 0xfffffff7;
+ *mspr = 1;
+#endif
+}
+
+/* _ovly_debug_event:
+ * Debuggers may set a breakpoint here, to be notified
+ * when the overlay table has been modified.
+ */
+static void
+_ovly_debug_event (void)
+{
+}
+
+/* OverlayLoad:
+ * Copy the overlay into its runtime region,
+ * and mark the overlay as "mapped".
+ */
+
+bool
+OverlayLoad (unsigned long ovlyno)
+{
+ unsigned long i;
+
+ if (ovlyno < 0 || ovlyno >= _novlys)
+ exit (-1); /* fail, bad ovly number */
+
+ if (_ovly_table[ovlyno][MAPPED])
+ return TRUE; /* this overlay already mapped -- nothing to do! */
+
+ for (i = 0; i < _novlys; i++)
+ if (i == ovlyno)
+ _ovly_table[i][MAPPED] = 1; /* this one now mapped */
+ else if (_ovly_table[i][VMA] == _ovly_table[ovlyno][VMA])
+ _ovly_table[i][MAPPED] = 0; /* this one now un-mapped */
+
+ ovly_copy (_ovly_table[ovlyno][VMA],
+ _ovly_table[ovlyno][LMA],
+ _ovly_table[ovlyno][SIZE]);
+
+ FlushCache ();
+ _ovly_debug_event ();
+ return TRUE;
+}
+
+/* OverlayUnload:
+ * Copy the overlay back into its "load" region.
+ * Does NOT mark overlay as "unmapped", therefore may be called
+ * more than once for the same mapped overlay.
+ */
+
+bool
+OverlayUnload (unsigned long ovlyno)
+{
+ if (ovlyno < 0 || ovlyno >= _novlys)
+ exit (-1); /* fail, bad ovly number */
+
+ if (!_ovly_table[ovlyno][MAPPED])
+ exit (-1); /* error, can't copy out a segment that's not "in" */
+
+ ovly_copy (_ovly_table[ovlyno][LMA],
+ _ovly_table[ovlyno][VMA],
+ _ovly_table[ovlyno][SIZE]);
+
+ _ovly_debug_event ();
+ return TRUE;
+}
+
+#ifdef __D10V__
+#define IMAP0 (*(short *)(0xff00))
+#define IMAP1 (*(short *)(0xff02))
+#define DMAP (*(short *)(0xff04))
+
+static void
+D10VTranslate (unsigned long logical,
+ short *dmap,
+ unsigned long **addr)
+{
+ unsigned long physical;
+ unsigned long seg;
+ unsigned long off;
+
+ /* to access data, we use the following mapping
+ 0x00xxxxxx: Logical data address segment (DMAP translated memory)
+ 0x01xxxxxx: Logical instruction address segment (IMAP translated memory)
+ 0x10xxxxxx: Physical data memory segment (On-chip data memory)
+ 0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)
+ 0x12xxxxxx: Phisical unified memory segment (Unified memory)
+ */
+
+ /* Addresses must be correctly aligned */
+ if (logical & (sizeof (**addr) - 1))
+ exit (-1);
+
+ /* If the address is in one of the two logical address spaces, it is
+ first translated into a physical address */
+ seg = (logical >> 24);
+ off = (logical & 0xffffffL);
+ switch (seg)
+ {
+ case 0x00: /* in logical data address segment */
+ if (off <= 0x7fffL)
+ physical = (0x10L << 24) + off;
+ else
+ /* Logical address out side of on-chip segment, not
+ supported */
+ exit (-1);
+ break;
+ case 0x01: /* in logical instruction address segment */
+ {
+ short map;
+ if (off <= 0x1ffffL)
+ map = IMAP0;
+ else if (off <= 0x3ffffL)
+ map = IMAP1;
+ else
+ /* Logical address outside of IMAP[01] segment, not
+ supported */
+ exit (-1);
+ if (map & 0x1000L)
+ {
+ /* Instruction memory */
+ physical = (0x11L << 24) | off;
+ }
+ else
+ {
+ /* Unified memory */
+ physical = ((map & 0x7fL) << 17) + (off & 0x1ffffL);
+ if (physical > 0xffffffL)
+ /* Address outside of unified address segment */
+ exit (-1);
+ physical |= (0x12L << 24);
+ }
+ break;
+ }
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ physical = logical;
+ break;
+ default:
+ exit (-1); /* error */
+ }
+
+ seg = (physical >> 24);
+ off = (physical & 0xffffffL);
+ switch (seg)
+ {
+ case 0x10: /* dst is a 15 bit offset into the on-chip memory */
+ *dmap = 0;
+ *addr = (long *) (0x0000 + ((short)off & 0x7fff));
+ break;
+ case 0x11: /* dst is an 18-bit offset into the on-chip
+ instruction memory */
+ *dmap = 0x1000L | ((off & 0x3ffffL) >> 14);
+ *addr = (long *) (0x8000 + ((short)off & 0x3fff));
+ break;
+ case 0x12: /* dst is a 24-bit offset into unified memory */
+ *dmap = off >> 14;
+ *addr = (long *) (0x8000 + ((short)off & 0x3fff));
+ break;
+ default:
+ exit (-1); /* error */
+ }
+}
+#endif /* __D10V__ */
+
+static void
+ovly_copy (unsigned long dst, unsigned long src, long size)
+{
+#ifdef __D10V__
+ unsigned long *s, *d, tmp;
+ short dmap_src, dmap_dst;
+ short dmap_save;
+
+ /* all section sizes should by multiples of 4 bytes */
+ dmap_save = DMAP;
+
+ D10VTranslate (src, &dmap_src, &s);
+ D10VTranslate (dst, &dmap_dst, &d);
+
+ while (size > 0)
+ {
+ /* NB: Transfer 4 byte (long) quantites, problems occure
+ when only two bytes are transfered */
+ DMAP = dmap_src;
+ tmp = *s;
+ DMAP = dmap_dst;
+ *d = tmp;
+ d++;
+ s++;
+ size -= sizeof (tmp);
+ src += sizeof (tmp);
+ dst += sizeof (tmp);
+ if ((src & 0x3fff) == 0)
+ D10VTranslate (src, &dmap_src, &s);
+ if ((dst & 0x3fff) == 0)
+ D10VTranslate (dst, &dmap_dst, &d);
+ }
+ DMAP = dmap_save;
+#else
+ memcpy ((void *) dst, (void *) src, size);
+#endif /* D10V */
+ return;
+}
+
diff --git a/gdb/testsuite/gdb.base/ovlymgr.h b/gdb/testsuite/gdb.base/ovlymgr.h
new file mode 100644
index 00000000000..bd0d40a2640
--- /dev/null
+++ b/gdb/testsuite/gdb.base/ovlymgr.h
@@ -0,0 +1,17 @@
+/*
+ * Sample runtime overlay manager.
+ */
+
+#ifdef NO_PROTOTYPES
+#define PARAMS(paramlist) ()
+#else
+#define PARAMS(paramlist) paramlist
+#endif
+
+typedef enum { FALSE, TRUE } bool;
+
+/* Entry Points: */
+
+bool OverlayLoad PARAMS((unsigned long ovlyno));
+bool OverlayUnload PARAMS((unsigned long ovlyno));
+
diff --git a/gdb/testsuite/gdb.base/page.exp b/gdb/testsuite/gdb.base/page.exp
new file mode 100644
index 00000000000..9791a607599
--- /dev/null
+++ b/gdb/testsuite/gdb.base/page.exp
@@ -0,0 +1,40 @@
+# Copyright 1992, 1994, 1995, 1999 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+global message
+global timeout
+
+set timeout 200
+
+gdb_exit
+gdb_start
+gdb_test "set pagination off" ""
+gdb_test "info set" ".*pagination: State of pagination is off.*"
+gdb_test "set pagination on" ""
+gdb_test "info set" ".*pagination: State of pagination is on.*"
+
+gdb_exit
+return 0
+
diff --git a/gdb/testsuite/gdb.base/pointers.c b/gdb/testsuite/gdb.base/pointers.c
new file mode 100644
index 00000000000..85bfdc98917
--- /dev/null
+++ b/gdb/testsuite/gdb.base/pointers.c
@@ -0,0 +1,216 @@
+
+#if !defined (__STDC__) && !defined (_AIX)
+#define signed /**/
+#endif
+
+char v_char;
+signed char v_signed_char;
+unsigned char v_unsigned_char;
+
+short v_short;
+signed short v_signed_short;
+unsigned short v_unsigned_short;
+
+int v_int;
+signed int v_signed_int;
+unsigned int v_unsigned_int;
+
+long v_long;
+signed long v_signed_long;
+unsigned long v_unsigned_long;
+
+float v_float;
+double v_double;
+
+
+
+char *v_char_pointer;
+signed char *v_signed_char_pointer;
+unsigned char *v_unsigned_char_pointer;
+
+short *v_short_pointer;
+signed short *v_signed_short_pointer;
+unsigned short *v_unsigned_short_pointer;
+
+int *v_int_pointer;
+int *v_int_pointer2;
+signed int *v_signed_int_pointer;
+unsigned int *v_unsigned_int_pointer;
+
+long *v_long_pointer;
+signed long *v_signed_long_pointer;
+unsigned long *v_unsigned_long_pointer;
+
+float *v_float_pointer;
+double *v_double_pointer;
+
+
+char v_char_array[2];
+signed char v_signed_char_array[2];
+unsigned char v_unsigned_char_array[2];
+
+short v_short_array[2];
+signed short v_signed_short_array[2];
+unsigned short v_unsigned_short_array[2];
+
+int v_int_array[2];
+signed int v_signed_int_array[2];
+unsigned int v_unsigned_int_array[2];
+
+long v_long_array[2];
+signed long v_signed_long_array[2];
+unsigned long v_unsigned_long_array[2];
+
+float v_float_array[2];
+double v_double_array[2];
+
+int matrix[2][3] = { { 0, 1, 2}, {3, 4, 5}};
+int (*rptr)[3] = matrix;
+
+float ** ptr_to_ptr_to_float;
+
+int y;
+
+/* Do nothing function used for forcing some of the above variables to
+ be referenced by the program source. If the variables are not
+ referenced, some linkers will remove the symbol from the symbol
+ table making it impossible to refer to the variable in gdb. */
+void usevar (void *var) {}
+
+int main ()
+{
+ void dummy();
+ int more_code();
+
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ dummy();
+
+ more_code ();
+
+ usevar (&v_int_pointer2);
+ usevar (&rptr);
+ usevar (&y);
+
+ return 0;
+
+}
+
+void dummy()
+{
+
+
+ v_char = 0;
+ v_signed_char = 1;
+ v_unsigned_char = 2;
+
+ v_short = 3;
+ v_signed_short = 4;
+ v_unsigned_short = 5;
+
+ v_int = 6;
+ v_signed_int = 7;
+ v_unsigned_int = 8;
+
+ v_long = 9;
+ v_signed_long = 10;
+ v_unsigned_long = 11;
+
+ v_float = 100.0;
+ v_double = 200.0;
+
+
+
+ v_char_pointer = &v_char;
+ v_signed_char_pointer = &v_signed_char;
+ v_unsigned_char_pointer = &v_unsigned_char;
+
+ v_short_pointer = &v_short;
+ v_signed_short_pointer = &v_signed_short;
+ v_unsigned_short_pointer = &v_unsigned_short;
+
+ v_int_pointer = &v_int;
+ v_signed_int_pointer = &v_signed_int;
+ v_unsigned_int_pointer = &v_unsigned_int;
+
+ v_long_pointer = &v_long;
+ v_signed_long_pointer = &v_signed_long;
+ v_unsigned_long_pointer = &v_unsigned_long;
+
+ v_float_pointer = &v_float;
+ v_double_pointer = &v_double;
+
+ ptr_to_ptr_to_float = &v_float_pointer;
+
+
+ v_char_array[0] = v_char;
+ v_signed_char_array[0] = v_signed_char;
+ v_unsigned_char_array[0] = v_unsigned_char;
+
+ v_short_array[0] = v_short;
+ v_signed_short_array[0] = v_signed_short;
+ v_unsigned_short_array[0] = v_unsigned_short;
+
+ v_int_array[0] = v_int;
+ v_int_array[1] = v_int * 3;
+
+ v_signed_int_array[0] = v_signed_int;
+ v_unsigned_int_array[0] = v_unsigned_int;
+
+ v_long_array[0] = v_long;
+ v_signed_long_array[0] = v_signed_long;
+ v_unsigned_long_array[0] = v_unsigned_long;
+
+ v_float_array[0] = v_float;
+ v_double_array[0] = v_double;
+
+}
+
+void marker1 ()
+{
+}
+
+int more_code()
+{
+ char C, *pC, **ppC, ***pppC, ****ppppC, *****pppppC, ******ppppppC;
+ unsigned char UC, *pUC;
+ short S, *pS;
+ unsigned short US, *pUS;
+ int I, *pI;
+ unsigned int UI, *pUI;
+ long L, *pL;
+ unsigned long UL, *pUL;
+ float F, *pF;
+ double D, *pD;
+
+ C = 'A';
+ UC = 21;
+ S = -14;
+ US = 7;
+ I = 102;
+ UI = 1002;
+ L = -234;
+ UL = 234;
+ F = 1.25E10;
+ D = -1.25E-37;
+ pC = &C;
+ ppC = &pC;
+ pppC = &ppC;
+ ppppC = &pppC;
+ pppppC = &ppppC;
+ ppppppC = &pppppC;
+ pUC = &UC;
+ pS = &S;
+ pUS = &US;
+ pI = &I;
+ pUI = &UI;
+ pL = &L;
+ pUL = &UL;
+ pF = &F;
+ pD = &D;
+
+ marker1();
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/pointers.exp b/gdb/testsuite/gdb.base/pointers.exp
new file mode 100644
index 00000000000..5f406ad1533
--- /dev/null
+++ b/gdb/testsuite/gdb.base/pointers.exp
@@ -0,0 +1,596 @@
+# Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+# This file is part of the gdb testsuite
+#
+# tests for pointer arithmetic and pointer dereferencing
+# with integer type variables and pointers to integers
+#
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "pointers"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+gdb_test "next " "more_code.*;" "continuing after dummy()"
+
+
+#
+# let's see if gdb catches some illegal operations on pointers
+#
+# I must comment these out because strict type checking is not
+# supported in this version of GDB. I do not really know
+# what the expected gdb reply is.
+#
+
+#send_gdb "print v_int_pointer2 = &v_int_pointer\n"
+#gdb_expect {
+# -re ".*.*$gdb_prompt $" {
+# pass "illegal pointer assignment rejected"
+# }
+# -re ".*$gdb_prompt $" { fail "illegal pointer assignment rejected" }
+# timeout { fail "(timeout) illegal pointer assignment rejected" }
+# }
+
+
+#send_gdb "print v_unsigned_int_pointer = &v_int\n"
+#gdb_expect {
+# -re ".*.*$gdb_prompt $" {
+# pass "illegal pointer assignment rejected"
+# }
+# -re ".*$gdb_prompt $" { fail "illegal pointer assignment rejected" }
+# timeout { fail "(timeout) ilegal pointer assignment rejected" }
+# }
+
+#send_gdb "print v_unsigned_int_pointer == v_double_pointer\n"
+#gdb_expect {
+# -re ".*.*$gdb_prompt $" {
+# pass "illegal pointer operation (+) rejected"
+# }
+# -re ".*$gdb_prompt $" { fail "illegal pointer operation (+) rejected" }
+# timeout { fail "(timeout) illegal pointer operation (+) rejected" }
+# }
+
+
+#send_gdb "print v_unsigned_int_pointer * v_double_pointer\n"
+#gdb_expect {
+# -re ".*Argument to arithmetic operation not a number or boolean.*$gdb_prompt $" {
+# pass "illegal pointer operation (*) rejected"
+# }
+# -re ".*$gdb_prompt $" { fail "illegal pointer operation (*) rejected" }
+# timeout { fail "(timeout) illegal pointer operation (*) rejected" }
+# }
+
+
+#send_gdb "print v_unsigned_int_pointer = v_double_pointer\n"
+#gdb_expect {
+# -re ".*.*$gdb_prompt $" {
+# pass "ilegal pointer assignment rejected"
+# }
+# -re ".*$gdb_prompt $" { fail "illegal pointer assignment rejected" }
+# timeout { fail "(timeout) illegal pointer assignment rejected" }
+# }
+
+
+#send_gdb "print v_unsigned_int_pointer = v_unsigned_int\n"
+#gdb_expect {
+# -re ".*.*$gdb_prompt $" {
+# pass "illegal pointer assignment rejected"
+# }
+# -re ".*$gdb_prompt $" { fail "illegal pointer assignment rejected" }
+# timeout { fail "(timeout) illegal pointer assignment rejected" }
+# }
+
+gdb_test "set variable v_int_pointer=&v_int_array\[0\]" "" "set pointer to beginning of array"
+gdb_test "set variable v_int_pointer2=&v_int_array\[1\]" "" "set pointer to end of array"
+
+
+send_gdb "print *v_int_pointer\n"
+gdb_expect {
+ -re ".*= 6.*$gdb_prompt $" {
+ pass "print object pointed to"
+ }
+ -re ".*$gdb_prompt $" { fail "print object pointed to" }
+ timeout { fail "(timeout) print object pointed to" }
+ }
+
+send_gdb "print *v_int_pointer2\n"
+gdb_expect {
+ -re ".*= 18.*$gdb_prompt $" {
+ pass "print object pointed to"
+ }
+ -re ".*$gdb_prompt $" { fail "print object pointed to" }
+ timeout { fail "(timeout) print object pointed to" }
+ }
+
+
+send_gdb "print v_int_pointer == v_int_pointer2\n"
+gdb_expect {
+ -re ".*= $false.*$gdb_prompt $" {
+ pass "pointer1==pointer2"
+ }
+ -re ".*$gdb_prompt $" { fail "pointer1==pointer2" }
+ timeout { fail "(timeout) pointer1==pointer2" }
+ }
+
+send_gdb "print v_int_pointer != v_int_pointer2\n"
+gdb_expect {
+ -re ".*= $true.*$gdb_prompt $" {
+ pass "pointer1!=pointer2"
+ }
+ -re ".*$gdb_prompt $" { fail "pointer1!=pointer2" }
+ timeout { fail "(timeout) pointer1!=pointer2" }
+ }
+
+
+send_gdb "print v_int_pointer <= v_int_pointer2\n"
+gdb_expect {
+ -re ".*= $true.*$gdb_prompt $" {
+ pass "pointer1<=pointer2"
+ }
+ -re ".*$gdb_prompt $" { fail "pointer1<=pointer2" }
+ timeout { fail "(timeout) pointer1<=pointer2" }
+ }
+
+
+send_gdb "print v_int_pointer >= v_int_pointer2\n"
+gdb_expect {
+ -re ".*= $false.*$gdb_prompt $" {
+ pass "pointer1>=pointer2"
+ }
+ -re ".*$gdb_prompt $" { fail "pointer1>=pointer2" }
+ timeout { fail "(timeout) pointer1>=pointer2" }
+ }
+
+
+send_gdb "print v_int_pointer < v_int_pointer2\n"
+gdb_expect {
+ -re ".*= $true.*$gdb_prompt $" {
+ pass "pointer1<pointer2"
+ }
+ -re ".*$gdb_prompt $" { fail "pointer1<pointer2" }
+ timeout { fail "(timeout) pointer1<pointer2" }
+ }
+
+send_gdb "print v_int_pointer > v_int_pointer2\n"
+gdb_expect {
+ -re ".*= $false.*$gdb_prompt $" {
+ pass "pointer1>pointer2"
+ }
+ -re ".*$gdb_prompt $" { fail "pointer1>pointer2" }
+ timeout { fail "(timeout) pointer1>pointer2" }
+ }
+
+
+gdb_test "set variable y = *v_int_pointer++" "" "set y = *v_int_pointer++"
+send_gdb "print y\n"
+gdb_expect {
+ -re ".*= 6.*$gdb_prompt $" {
+ send_gdb "print *v_int_pointer\n"
+ gdb_expect {
+ -re ".*= 18.*$gdb_prompt $" {
+ pass "pointer assignment and increment"
+ }
+ -re ".*$gdb_prompt $" { fail "pointer assignment and increment" }
+ timeout { fail "(timeout) pointer assignment and increment" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "pointer assignment and increment" }
+ timeout { fail "(timeout) pointer assignment and increment" }
+ }
+
+
+
+
+gdb_test "set variable y = *--v_int_pointer2" "" "set y = *--v_int_pointer2"
+send_gdb "print y\n"
+gdb_expect {
+ -re ".*= 6.*$gdb_prompt $" {
+ send_gdb "print *v_int_pointer2\n"
+ gdb_expect {
+ -re ".*= 6.*$gdb_prompt $" {
+ pass "pointer decrement and assignment"
+ }
+ -re ".*$gdb_prompt $" { fail "pointer decrement and assignment" }
+ timeout { fail "(timeout) pointer decrement and assignment" }
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "pointer decrement and assignment" }
+ timeout { fail "(timeout) pointer decrement and assignment" }
+ }
+
+gdb_test "set variable y =v_int_pointer-v_int_pointer2" "" "set y =v_int_pointer-v_int_pointer2"
+send_gdb "print y\n"
+gdb_expect {
+ -re ".*= 1.*$gdb_prompt $" {
+ pass "pointer1-pointer2"
+ }
+ -re ".*$gdb_prompt $" { fail "pointer1-pointer2" }
+ timeout { fail "(timeout) pointer1-pointer2" }
+ }
+
+gdb_test "set variable v_int_pointer=v_int_array" "" "set v_int_pointer=v_int_array"
+send_gdb "print *v_int_pointer\n"
+gdb_expect {
+ -re ".*= 6.*$gdb_prompt $" {
+ pass "print array element through pointer"
+ }
+ -re ".*$gdb_prompt $" { fail "print array element through pointer" }
+ timeout { fail "(timeout) print array element through pointer" }
+ }
+
+
+send_gdb "print *(v_int_pointer+1)\n"
+gdb_expect {
+ -re ".*= 18.*$gdb_prompt $" {
+ pass "print array element through pointer"
+ }
+ -re ".*$gdb_prompt $" { fail "print array element through pointer" }
+ timeout { fail "(timeout) print array element through pointer" }
+ }
+
+# test print elements of array through pointers
+
+send_gdb "print (*rptr)\[0\]\n"
+gdb_expect {
+ -re ".*= 0.*$gdb_prompt $" {
+ pass "print array element through pointer"
+ }
+ -re ".*$gdb_prompt $" { fail "print array element through pointer" }
+ timeout { fail "(timeout) print array element through pointer" }
+ }
+
+send_gdb "print (*rptr)\[1\]\n"
+gdb_expect {
+ -re ".*= 1.*$gdb_prompt $" {
+ pass "print array element through pointer"
+ }
+ -re ".*$gdb_prompt $" { fail "print array element through pointer" }
+ timeout { fail "(timeout) print array element through pointer" }
+ }
+
+
+send_gdb "print (*rptr)\[2\]\n"
+gdb_expect {
+ -re ".*= 2.*$gdb_prompt $" {
+ pass "print array element through pointer"
+ }
+ -re ".*$gdb_prompt $" { fail "print array element through pointer" }
+ timeout { fail "(timeout) print array element through pointer" }
+ }
+
+gdb_test "set variable rptr = rptr+1" "" "increment rptr"
+
+send_gdb "print (*rptr)\[0\]\n"
+gdb_expect {
+ -re ".*= 3.*$gdb_prompt $" {
+ pass "print array element through pointer"
+ }
+ -re ".*$gdb_prompt $" { fail "print array element through pointer" }
+ timeout { fail "(timeout) print array element through pointer" }
+ }
+
+
+send_gdb "print (*rptr)\[1\]\n"
+gdb_expect {
+ -re ".*= 4.*$gdb_prompt $" {
+ pass "print array element through pointer"
+ }
+ -re ".*$gdb_prompt $" { fail "print array element through pointer" }
+ timeout { fail "(timeout) print array element through pointer" }
+ }
+
+
+send_gdb "print (*rptr)\[2\]\n"
+gdb_expect {
+ -re ".*= 5.*$gdb_prompt $" {
+ pass "print array element through pointer"
+ }
+ -re ".*$gdb_prompt $" { fail "print array element through pointer" }
+ timeout { fail "(timeout) print array element through pointer" }
+ }
+
+
+send_gdb "print *( *(matrix+1) +2)\n"
+gdb_expect {
+ -re ".*= 5.*$gdb_prompt $" {
+ pass "print array element w/ pointer arithmetic"
+ }
+ -re ".*$gdb_prompt $" { fail "print array element w/ pointer arithemtic" }
+ timeout { fail "(timeout) print array element w/ pointer arithmetic" }
+ }
+
+
+send_gdb "print **ptr_to_ptr_to_float\n"
+gdb_expect {
+ -re ".*= 100.*$gdb_prompt $" {
+ pass "print through ptr to ptr"
+ }
+ -re ".*$gdb_prompt $" { fail "print through ptr to ptr" }
+ timeout { fail "(timeout) print through ptr to ptr" }
+ }
+
+# tests for pointers
+# with elementary type variables and pointers.
+#
+
+send_gdb "break marker1\n" ; gdb_expect -re ".*$gdb_prompt $"
+
+ send_gdb "cont\n"
+ gdb_expect {
+ -re "Break.* marker1 \\(\\) at .*:$decimal.*$gdb_prompt $" {
+ send_gdb "up\n"
+ gdb_expect {
+ -re ".*more_code.*$gdb_prompt $" {
+ pass "up from marker1"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "up from marker1"
+ }
+ timeout { fail "up from marker1 (timeout)" }
+ }
+ }
+ -re "$gdb_prompt $" { fail "continue to marker1" }
+ timeout { fail "(timeout) continue to marker1" }
+ }
+
+
+send_gdb "print *pUC\n"
+gdb_expect {
+ -re ".\[0-9\]* = 21 \'.025\'.*$gdb_prompt $" {
+ pass "print value of *pUC"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of *pUC" }
+ timeout { fail "(timeout) print value of *pUC" }
+ }
+
+
+send_gdb "ptype pUC\n"
+gdb_expect {
+ -re "type = unsigned char \\*.*$gdb_prompt $" { pass "ptype pUC" }
+ -re ".*$gdb_prompt $" { fail "ptype pUC" }
+ timeout { fail "(timeout) ptype pUC" }
+}
+
+send_gdb "print *pS\n"
+gdb_expect {
+ -re ".\[0-9\]* = -14.*$gdb_prompt $" {
+ pass "print value of *pS"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of *pS" }
+ timeout { fail "(timeout) print value of *pS" }
+ }
+
+
+send_gdb "ptype pS\n"
+gdb_expect {
+ -re "type = short \\*.*$gdb_prompt $" { pass "ptype pS" }
+ -re "type = short int \\*.*$gdb_prompt $" { pass "ptype pS" }
+ -re ".*$gdb_prompt $" { fail "ptype pS" }
+ timeout { fail "(timeout) ptype pS" }
+}
+
+send_gdb "print *pUS\n"
+gdb_expect {
+ -re ".\[0-9\]* = 7.*$gdb_prompt $" {
+ pass "print value of *pUS"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of *pUS" }
+ timeout { fail "(timeout) print value of *pUS" }
+ }
+
+
+send_gdb "ptype pUS\n"
+gdb_expect {
+ -re "type = unsigned short \\*.*$gdb_prompt $" { pass "ptype pUS" }
+ -re "type = short unsigned int \\*.*$gdb_prompt $" { pass "ptype pUS" }
+ -re ".*$gdb_prompt $" { fail "ptype pUS" }
+ timeout { fail "(timeout) ptype pUS" }
+}
+
+send_gdb "print *pI\n"
+gdb_expect {
+ -re ".\[0-9\]* = 102.*$gdb_prompt $" {
+ pass "print value of *pI"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of *pI" }
+ timeout { fail "(timeout) print value of *pI" }
+ }
+
+
+send_gdb "ptype pI\n"
+gdb_expect {
+ -re "type = int \\*.*$gdb_prompt $" { pass "ptype pI" }
+ -re ".*$gdb_prompt $" { fail "ptype pI" }
+ timeout { fail "(timeout) ptype pI" }
+}
+
+send_gdb "print *pUI\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1002.*$gdb_prompt $" {
+ pass "print value of *pUI"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of *pUI" }
+ timeout { fail "(timeout) print value of *pUI" }
+ }
+
+
+send_gdb "ptype pUI\n"
+gdb_expect {
+ -re "type = unsigned int \\*.*$gdb_prompt $" { pass "ptype pUI" }
+ -re ".*$gdb_prompt $" { fail "ptype pUI" }
+ timeout { fail "(timeout) ptype pUI" }
+}
+
+send_gdb "print *pL\n"
+gdb_expect {
+ -re ".\[0-9\]* = -234.*$gdb_prompt $" {
+ pass "print value of *pL"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of *pL" }
+ timeout { fail "(timeout) print value of *pL" }
+ }
+
+
+send_gdb "ptype pL\n"
+gdb_expect {
+ -re "type = long \\*.*$gdb_prompt $" { pass "ptype pL" }
+ -re "type = long int \\*.*$gdb_prompt $" { pass "ptype pL" }
+ -re ".*$gdb_prompt $" { fail "ptype pL" }
+ timeout { fail "(timeout) ptype pL" }
+}
+
+send_gdb "print *pUL\n"
+gdb_expect {
+ -re ".\[0-9\]* = 234.*$gdb_prompt $" {
+ pass "print value of *pUL"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of *pUL" }
+ timeout { fail "(timeout) print value of *pUL" }
+ }
+
+
+send_gdb "ptype pUL\n"
+gdb_expect {
+ -re "type = unsigned long \\*.*$gdb_prompt $" { pass "ptype pUL" }
+ -re "type = long unsigned int \\*.*$gdb_prompt $" { pass "ptype pUL" }
+ -re ".*$gdb_prompt $" { fail "ptype pUL" }
+ timeout { fail "(timeout) ptype pUL" }
+}
+
+send_gdb "print *pF\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1.2\[0-9\]*e\\+10.*$gdb_prompt $" {
+ pass "print value of *pF"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of *pF" }
+ timeout { fail "(timeout) print value of *pF" }
+ }
+
+
+send_gdb "ptype pF\n"
+gdb_expect {
+ -re "type = float \\*.*$gdb_prompt $" { pass "ptype pF" }
+ -re ".*$gdb_prompt $" { fail "ptype pF" }
+ timeout { fail "(timeout) ptype pF" }
+}
+
+send_gdb "print *pD\n"
+gdb_expect {
+ -re ".\[0-9\]* = -1.2\[0-9\]*e\\-37.*$gdb_prompt $" {
+ pass "print value of *pD"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of *pD" }
+ timeout { fail "(timeout) print value of *pD" }
+ }
+
+
+send_gdb "ptype pD\n"
+gdb_expect {
+ -re "type = double \\*.*$gdb_prompt $" { pass "ptype pD" }
+ -re ".*$gdb_prompt $" { fail "ptype pD" }
+ timeout { fail "(timeout) ptype pD" }
+}
+
+send_gdb "print ******ppppppC\n"
+gdb_expect {
+ -re ".\[0-9\]* = 65 \'A\'.*$gdb_prompt $" {
+ pass "print value of ******ppppppC"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of ******ppppppC" }
+ timeout { fail "(timeout) print value of ******ppppppC" }
+ }
+
+
+send_gdb "ptype pC\n"
+gdb_expect {
+ -re "type = char \\*.*$gdb_prompt $" { pass "ptype pC" }
+ -re ".*$gdb_prompt $" { fail "ptype pC" }
+ timeout { fail "(timeout) ptype pC" }
+}
+
+send_gdb "ptype ppC\n"
+gdb_expect {
+ -re "type = char \\*\\*.*$gdb_prompt $" { pass "ptype ppC" }
+ -re ".*$gdb_prompt $" { fail "ptype ppC" }
+ timeout { fail "(timeout) ptype ppC" }
+}
+
+send_gdb "ptype pppC\n"
+gdb_expect {
+ -re "type = char \\*\\*\\*.*$gdb_prompt $" { pass "ptype pppC" }
+ -re ".*$gdb_prompt $" { fail "ptype pppC" }
+ timeout { fail "(timeout) ptype pppC" }
+}
+
+send_gdb "ptype ppppC\n"
+gdb_expect {
+ -re "type = char \\*\\*\\*\\*.*$gdb_prompt $" { pass "ptype ppppC" }
+ -re ".*$gdb_prompt $" { fail "ptype ppppC" }
+ timeout { fail "(timeout) ptype ppppC" }
+}
+
+send_gdb "ptype pppppC\n"
+gdb_expect {
+ -re "type = char \\*\\*\\*\\*\\*.*$gdb_prompt $" { pass "ptype pppppC" }
+ -re ".*$gdb_prompt $" { fail "ptype pppppC" }
+ timeout { fail "(timeout) ptype pppppC" }
+}
+
+send_gdb "ptype ppppppC\n"
+gdb_expect {
+ -re "type = char \\*\\*\\*\\*\\*\\*.*$gdb_prompt $" { pass "ptype ppppppC" }
+ -re ".*$gdb_prompt $" { fail "ptype ppppppC" }
+ timeout { fail "(timeout) ptype ppppppC" }
+}
+
diff --git a/gdb/testsuite/gdb.base/printcmds.c b/gdb/testsuite/gdb.base/printcmds.c
new file mode 100644
index 00000000000..8eddeeeccf8
--- /dev/null
+++ b/gdb/testsuite/gdb.base/printcmds.c
@@ -0,0 +1,107 @@
+/* This table is used as a source for every ascii character.
+ It is explicitly unsigned to avoid differences due to native characters
+ being either signed or unsigned. */
+#include <stdlib.h>
+unsigned char ctable1[256] = {
+ 0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
+ 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
+ 0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
+ 0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
+ 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
+ 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
+ 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
+ 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
+ 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+ 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+ 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+ 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
+ 0140, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
+ 0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
+ 0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
+ 0170, 0171, 0172, 0173, 0174, 0175, 0176, 0177,
+ 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
+ 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
+ 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
+ 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
+ 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
+ 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
+ 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
+ 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
+ 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
+ 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
+ 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
+ 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
+ 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
+ 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
+ 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
+ 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
+};
+
+unsigned char ctable2[] = {
+ 'a','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X',
+ 'a','a','X','X','X','X','X','X','X','X','X','X','X','X','X','X',
+ 'a','a','a','X','X','X','X','X','X','X','X','X','X','X','X','X',
+ 'a','a','a','a','X','X','X','X','X','X','X','X','X','X','X','X',
+ 'a','a','a','a','a','X','X','X','X','X','X','X','X','X','X','X',
+ 'a','a','a','a','a','a','X','X','X','X','X','X','X','X','X','X',
+ 'a','a','a','a','a','a','a','X','X','X','X','X','X','X','X','X',
+ 'a','a','a','a','a','a','a','a','X','X','X','X','X','X','X','X',
+ 'a','a','a','a','a','a','a','a','a','X','X','X','X','X','X','X',
+ 'a','a','a','a','a','a','a','a','a','a','X','X','X','X','X','X',
+ 'a','a','a','a','a','a','a','a','a','a','a','X','X','X','X','X',
+ 'a','a','a','a','a','a','a','a','a','a','a','a','X','X','X','X',
+ 'a','a','a','a','a','a','a','a','a','a','a','a','a','X','X','X',
+ 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','X','X',
+ 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','X',
+ 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', 0
+};
+
+/* Single and multidimensional arrays to test access and printing of array
+ members. */
+
+typedef int ArrayInt [10];
+ArrayInt a1 = {2,4,6,8,10,12,14,16,18,20};
+
+typedef char ArrayChar [5];
+ArrayChar a2 = {'a','b','c','d','\0'};
+
+int int1dim[12] = {0,1,2,3,4,5,6,7,8,9,10,11};
+int int2dim[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
+int int3dim[2][3][2] = {{{0,1},{2,3},{4,5}},{{6,7},{8,9},{10,11}}};
+int int4dim[1][2][3][2] = {{{{0,1},{2,3},{4,5}},{{6,7},{8,9},{10,11}}}};
+
+char *teststring = (char*)"teststring contents";
+
+/* Test printing of a struct containing character arrays. */
+
+struct some_arrays {
+ unsigned char array1[4];
+ unsigned char array2[1];
+ unsigned char array3[1];
+ unsigned char array4[2];
+ unsigned char array5[4];
+} arrays = {
+ {'a', 'b', 'c', '\0'},
+ {'d'},
+ {'e'},
+ {'f', 'g' },
+ {'h', 'i', 'j', '\0'}
+};
+
+struct some_arrays *parrays = &arrays;
+
+/* -- */
+
+int main ()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ malloc(1);
+
+ /* Prevent AIX linker from removing variables. */
+ return ctable1[0] + ctable2[0] + int1dim[0] + int2dim[0][0]
+ + int3dim[0][0][0] + int4dim[0][0][0][0] + teststring[0] +
+ *parrays -> array1 + a1[0] + a2[0];
+}
diff --git a/gdb/testsuite/gdb.base/printcmds.exp b/gdb/testsuite/gdb.base/printcmds.exp
new file mode 100644
index 00000000000..7062fc55dc7
--- /dev/null
+++ b/gdb/testsuite/gdb.base/printcmds.exp
@@ -0,0 +1,715 @@
+# Copyright 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2002 Free
+# Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "printcmds"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Set the current language to C. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_c {} {
+ global gdb_prompt
+
+ if [gdb_test "set language c" "" "set language c"] {
+ return 0
+ }
+
+ if [gdb_test "show language" ".* source language is \"c\".*"] {
+ return 0
+ }
+ return 1;
+}
+
+proc test_integer_literals_accepted {} {
+ global gdb_prompt
+
+ # Test various decimal values.
+
+ gdb_test "p 123" " = 123"
+ gdb_test "p -123" " = -123"
+ gdb_test "p/d 123" " = 123"
+
+ # Test various octal values.
+
+ gdb_test "p 0123" " = 83"
+ gdb_test "p 00123" " = 83"
+ gdb_test "p -0123" " = -83"
+ gdb_test "p/o 0123" " = 0123"
+
+ # Test various hexadecimal values.
+
+ gdb_test "p 0x123" " = 291"
+ gdb_test "p -0x123" " = -291"
+ gdb_test "p 0x0123" " = 291"
+ gdb_test "p -0x0123" " = -291"
+ gdb_test "p 0xABCDEF" " = 11259375"
+ gdb_test "p 0xabcdef" " = 11259375"
+ gdb_test "p 0xAbCdEf" " = 11259375"
+ gdb_test "p/x 0x123" " = 0x123"
+}
+
+proc test_character_literals_accepted {} {
+ global gdb_prompt
+
+ gdb_test "p 'a'" " = 97 'a'"
+ gdb_test "p/c 'a'" " = 97 'a'"
+ gdb_test "p/x 'a'" " = 0x61"
+ gdb_test "p/d 'a'" " = 97"
+ gdb_test "p/t 'a'" " = 1100001"
+ gdb_test "p '\\141'" " = 97 'a'"
+ gdb_test "p/x '\\377'" " = 0xff"
+ # Note "p '\''" => "= 39 '\''"
+ gdb_test "p '\\''" " = 39 '\\\\''"
+ # Note "p '\\'" => "= 92 '\\'"
+ gdb_test "p '\\\\'" " = 92 '\\\\\\\\'"
+}
+
+proc test_integer_literals_rejected {} {
+ global gdb_prompt
+
+ test_print_reject "p 0x"
+ gdb_test "p ''" "(Empty character constant\\.|A character constant must contain at least one character\\.)"
+ gdb_test "p '''" "(Empty character constant\\.|A character constant must contain at least one character\\.)"
+ test_print_reject "p '\\'"
+
+ # Note that this turns into "p '\\\'" at gdb's input.
+ test_print_reject "p '\\\\\\'"
+
+ # Test various decimal values.
+
+ test_print_reject "p DEADBEEF"
+
+ # Gdb currently fails this test for all configurations. The C
+ # lexer thinks that 123DEADBEEF is a floating point number, but
+ # then fails to notice that atof() only eats the 123 part.
+ # FIXME: This should be put into PRMS.
+ # Fixed, 4/25/97, by Bob Manson.
+
+ test_print_reject "p 123DEADBEEF"
+ test_print_reject "p 123foobar.bazfoo3"
+ test_print_reject "p 123EEEEEEEEEEEEEEEEE33333k333"
+ gdb_test "p 123.4+56.7" "180.(099\[0-9]*|100\[0-9\]*)" "check for floating addition"
+
+ # Test various octal values.
+
+ test_print_reject "p 09"
+ test_print_reject "p 079"
+
+ # Test various hexadecimal values.
+
+ test_print_reject "p 0xG"
+ test_print_reject "p 0xAG"
+}
+
+proc test_print_all_chars {} {
+ global gdb_prompt
+
+ gdb_test "p ctable1\[0\]" " = 0 '\\\\0'"
+ gdb_test "p ctable1\[1\]" " = 1 '\\\\001'"
+ gdb_test "p ctable1\[2\]" " = 2 '\\\\002'"
+ gdb_test "p ctable1\[3\]" " = 3 '\\\\003'"
+ gdb_test "p ctable1\[4\]" " = 4 '\\\\004'"
+ gdb_test "p ctable1\[5\]" " = 5 '\\\\005'"
+ gdb_test "p ctable1\[6\]" " = 6 '\\\\006'"
+ gdb_test "p ctable1\[7\]" " = 7 '\\\\a'"
+ gdb_test "p ctable1\[8\]" " = 8 '\\\\b'"
+ gdb_test "p ctable1\[9\]" " = 9 '\\\\t'"
+ gdb_test "p ctable1\[10\]" " = 10 '\\\\n'"
+ gdb_test "p ctable1\[11\]" " = 11 '\\\\v'"
+ gdb_test "p ctable1\[12\]" " = 12 '\\\\f'"
+ gdb_test "p ctable1\[13\]" " = 13 '\\\\r'"
+ gdb_test "p ctable1\[14\]" " = 14 '\\\\016'"
+ gdb_test "p ctable1\[15\]" " = 15 '\\\\017'"
+ gdb_test "p ctable1\[16\]" " = 16 '\\\\020'"
+ gdb_test "p ctable1\[17\]" " = 17 '\\\\021'"
+ gdb_test "p ctable1\[18\]" " = 18 '\\\\022'"
+ gdb_test "p ctable1\[19\]" " = 19 '\\\\023'"
+ gdb_test "p ctable1\[20\]" " = 20 '\\\\024'"
+ gdb_test "p ctable1\[21\]" " = 21 '\\\\025'"
+ gdb_test "p ctable1\[22\]" " = 22 '\\\\026'"
+ gdb_test "p ctable1\[23\]" " = 23 '\\\\027'"
+ gdb_test "p ctable1\[24\]" " = 24 '\\\\030'"
+ gdb_test "p ctable1\[25\]" " = 25 '\\\\031'"
+ gdb_test "p ctable1\[26\]" " = 26 '\\\\032'"
+ gdb_test "p ctable1\[27\]" " = 27 '\\\\e'"
+ gdb_test "p ctable1\[28\]" " = 28 '\\\\034'"
+ gdb_test "p ctable1\[29\]" " = 29 '\\\\035'"
+ gdb_test "p ctable1\[30\]" " = 30 '\\\\036'"
+ gdb_test "p ctable1\[31\]" " = 31 '\\\\037'"
+ gdb_test "p ctable1\[32\]" " = 32 ' '"
+ gdb_test "p ctable1\[33\]" " = 33 '!'"
+ gdb_test "p ctable1\[34\]" " = 34 '\"'"
+ gdb_test "p ctable1\[35\]" " = 35 '#'"
+ gdb_test "p ctable1\[36\]" " = 36 '\\\$'"
+ gdb_test "p ctable1\[37\]" " = 37 '%'"
+ gdb_test "p ctable1\[38\]" " = 38 '&'"
+ gdb_test "p ctable1\[39\]" " = 39 '\\\\''"
+ gdb_test "p ctable1\[40\]" " = 40 '\\('"
+ gdb_test "p ctable1\[41\]" " = 41 '\\)'"
+ gdb_test "p ctable1\[42\]" " = 42 '\\*'"
+ gdb_test "p ctable1\[43\]" " = 43 '\\+'"
+ gdb_test "p ctable1\[44\]" " = 44 ','"
+ gdb_test "p ctable1\[45\]" " = 45 '-'"
+ gdb_test "p ctable1\[46\]" " = 46 '.'"
+ gdb_test "p ctable1\[47\]" " = 47 '/'"
+ gdb_test "p ctable1\[48\]" " = 48 '0'"
+ gdb_test "p ctable1\[49\]" " = 49 '1'"
+ gdb_test "p ctable1\[50\]" " = 50 '2'"
+ gdb_test "p ctable1\[51\]" " = 51 '3'"
+ gdb_test "p ctable1\[52\]" " = 52 '4'"
+ gdb_test "p ctable1\[53\]" " = 53 '5'"
+ gdb_test "p ctable1\[54\]" " = 54 '6'"
+ gdb_test "p ctable1\[55\]" " = 55 '7'"
+ gdb_test "p ctable1\[56\]" " = 56 '8'"
+ gdb_test "p ctable1\[57\]" " = 57 '9'"
+ gdb_test "p ctable1\[58\]" " = 58 ':'"
+ gdb_test "p ctable1\[59\]" " = 59 ';'"
+ gdb_test "p ctable1\[60\]" " = 60 '<'"
+ gdb_test "p ctable1\[61\]" " = 61 '='"
+ gdb_test "p ctable1\[62\]" " = 62 '>'"
+ gdb_test "p ctable1\[63\]" " = 63 '\\?'"
+ gdb_test "p ctable1\[64\]" " = 64 '@'"
+ gdb_test "p ctable1\[65\]" " = 65 'A'"
+ gdb_test "p ctable1\[66\]" " = 66 'B'"
+ gdb_test "p ctable1\[67\]" " = 67 'C'"
+ gdb_test "p ctable1\[68\]" " = 68 'D'"
+ gdb_test "p ctable1\[69\]" " = 69 'E'"
+ gdb_test "p ctable1\[70\]" " = 70 'F'"
+ gdb_test "p ctable1\[71\]" " = 71 'G'"
+ gdb_test "p ctable1\[72\]" " = 72 'H'"
+ gdb_test "p ctable1\[73\]" " = 73 'I'"
+ gdb_test "p ctable1\[74\]" " = 74 'J'"
+ gdb_test "p ctable1\[75\]" " = 75 'K'"
+ gdb_test "p ctable1\[76\]" " = 76 'L'"
+ gdb_test "p ctable1\[77\]" " = 77 'M'"
+ gdb_test "p ctable1\[78\]" " = 78 'N'"
+ gdb_test "p ctable1\[79\]" " = 79 'O'"
+ gdb_test "p ctable1\[80\]" " = 80 'P'"
+ gdb_test "p ctable1\[81\]" " = 81 'Q'"
+ gdb_test "p ctable1\[82\]" " = 82 'R'"
+ gdb_test "p ctable1\[83\]" " = 83 'S'"
+ gdb_test "p ctable1\[84\]" " = 84 'T'"
+ gdb_test "p ctable1\[85\]" " = 85 'U'"
+ gdb_test "p ctable1\[86\]" " = 86 'V'"
+ gdb_test "p ctable1\[87\]" " = 87 'W'"
+ gdb_test "p ctable1\[88\]" " = 88 'X'"
+ gdb_test "p ctable1\[89\]" " = 89 'Y'"
+ gdb_test "p ctable1\[90\]" " = 90 'Z'"
+ gdb_test "p ctable1\[91\]" " = 91 '\\\['"
+ gdb_test "p ctable1\[92\]" " = 92 '\\\\\\\\'"
+ gdb_test "p ctable1\[93\]" " = 93 '\\\]'"
+ gdb_test "p ctable1\[94\]" " = 94 '\\^'"
+ gdb_test "p ctable1\[95\]" " = 95 '_'"
+ gdb_test "p ctable1\[96\]" " = 96 '`'"
+ gdb_test "p ctable1\[97\]" " = 97 'a'"
+ gdb_test "p ctable1\[98\]" " = 98 'b'"
+ gdb_test "p ctable1\[99\]" " = 99 'c'"
+ gdb_test "p ctable1\[100\]" " = 100 'd'"
+ gdb_test "p ctable1\[101\]" " = 101 'e'"
+ gdb_test "p ctable1\[102\]" " = 102 'f'"
+ gdb_test "p ctable1\[103\]" " = 103 'g'"
+ gdb_test "p ctable1\[104\]" " = 104 'h'"
+ gdb_test "p ctable1\[105\]" " = 105 'i'"
+ gdb_test "p ctable1\[106\]" " = 106 'j'"
+ gdb_test "p ctable1\[107\]" " = 107 'k'"
+ gdb_test "p ctable1\[108\]" " = 108 'l'"
+ gdb_test "p ctable1\[109\]" " = 109 'm'"
+ gdb_test "p ctable1\[110\]" " = 110 'n'"
+ gdb_test "p ctable1\[111\]" " = 111 'o'"
+ gdb_test "p ctable1\[112\]" " = 112 'p'"
+ gdb_test "p ctable1\[113\]" " = 113 'q'"
+ gdb_test "p ctable1\[114\]" " = 114 'r'"
+ gdb_test "p ctable1\[115\]" " = 115 's'"
+ gdb_test "p ctable1\[116\]" " = 116 't'"
+ gdb_test "p ctable1\[117\]" " = 117 'u'"
+ gdb_test "p ctable1\[118\]" " = 118 'v'"
+ gdb_test "p ctable1\[119\]" " = 119 'w'"
+ gdb_test "p ctable1\[120\]" " = 120 'x'"
+ gdb_test "p ctable1\[121\]" " = 121 'y'"
+ gdb_test "p ctable1\[122\]" " = 122 'z'"
+ gdb_test "p ctable1\[123\]" " = 123 '\[{\]+'"
+ gdb_test "p ctable1\[124\]" " = 124 '\[|\]+'"
+ gdb_test "p ctable1\[125\]" " = 125 '\[}\]+'"
+ gdb_test "p ctable1\[126\]" " = 126 '\[~\]'"
+ gdb_test "p ctable1\[127\]" " = 127 '\\\\177'"
+ gdb_test "p ctable1\[128\]" " = 128 '\\\\200'"
+ gdb_test "p ctable1\[129\]" " = 129 '\\\\201'"
+ gdb_test "p ctable1\[130\]" " = 130 '\\\\202'"
+ gdb_test "p ctable1\[131\]" " = 131 '\\\\203'"
+ gdb_test "p ctable1\[132\]" " = 132 '\\\\204'"
+ gdb_test "p ctable1\[133\]" " = 133 '\\\\205'"
+ gdb_test "p ctable1\[134\]" " = 134 '\\\\206'"
+ gdb_test "p ctable1\[135\]" " = 135 '\\\\207'"
+ gdb_test "p ctable1\[136\]" " = 136 '\\\\210'"
+ gdb_test "p ctable1\[137\]" " = 137 '\\\\211'"
+ gdb_test "p ctable1\[138\]" " = 138 '\\\\212'"
+ gdb_test "p ctable1\[139\]" " = 139 '\\\\213'"
+ gdb_test "p ctable1\[140\]" " = 140 '\\\\214'"
+ gdb_test "p ctable1\[141\]" " = 141 '\\\\215'"
+ gdb_test "p ctable1\[142\]" " = 142 '\\\\216'"
+ gdb_test "p ctable1\[143\]" " = 143 '\\\\217'"
+ gdb_test "p ctable1\[144\]" " = 144 '\\\\220'"
+ gdb_test "p ctable1\[145\]" " = 145 '\\\\221'"
+ gdb_test "p ctable1\[146\]" " = 146 '\\\\222'"
+ gdb_test "p ctable1\[147\]" " = 147 '\\\\223'"
+ gdb_test "p ctable1\[148\]" " = 148 '\\\\224'"
+ gdb_test "p ctable1\[149\]" " = 149 '\\\\225'"
+ gdb_test "p ctable1\[150\]" " = 150 '\\\\226'"
+ gdb_test "p ctable1\[151\]" " = 151 '\\\\227'"
+ gdb_test "p ctable1\[152\]" " = 152 '\\\\230'"
+ gdb_test "p ctable1\[153\]" " = 153 '\\\\231'"
+ gdb_test "p ctable1\[154\]" " = 154 '\\\\232'"
+ gdb_test "p ctable1\[155\]" " = 155 '\\\\233'"
+ gdb_test "p ctable1\[156\]" " = 156 '\\\\234'"
+ gdb_test "p ctable1\[157\]" " = 157 '\\\\235'"
+ gdb_test "p ctable1\[158\]" " = 158 '\\\\236'"
+ gdb_test "p ctable1\[159\]" " = 159 '\\\\237'"
+ gdb_test "p ctable1\[160\]" " = 160 '\\\\240'"
+ gdb_test "p ctable1\[161\]" " = 161 '\\\\241'"
+ gdb_test "p ctable1\[162\]" " = 162 '\\\\242'"
+ gdb_test "p ctable1\[163\]" " = 163 '\\\\243'"
+ gdb_test "p ctable1\[164\]" " = 164 '\\\\244'"
+ gdb_test "p ctable1\[165\]" " = 165 '\\\\245'"
+ gdb_test "p ctable1\[166\]" " = 166 '\\\\246'"
+ gdb_test "p ctable1\[167\]" " = 167 '\\\\247'"
+ gdb_test "p ctable1\[168\]" " = 168 '\\\\250'"
+ gdb_test "p ctable1\[169\]" " = 169 '\\\\251'"
+ gdb_test "p ctable1\[170\]" " = 170 '\\\\252'"
+ gdb_test "p ctable1\[171\]" " = 171 '\\\\253'"
+ gdb_test "p ctable1\[172\]" " = 172 '\\\\254'"
+ gdb_test "p ctable1\[173\]" " = 173 '\\\\255'"
+ gdb_test "p ctable1\[174\]" " = 174 '\\\\256'"
+ gdb_test "p ctable1\[175\]" " = 175 '\\\\257'"
+ gdb_test "p ctable1\[176\]" " = 176 '\\\\260'"
+ gdb_test "p ctable1\[177\]" " = 177 '\\\\261'"
+ gdb_test "p ctable1\[178\]" " = 178 '\\\\262'"
+ gdb_test "p ctable1\[179\]" " = 179 '\\\\263'"
+ gdb_test "p ctable1\[180\]" " = 180 '\\\\264'"
+ gdb_test "p ctable1\[181\]" " = 181 '\\\\265'"
+ gdb_test "p ctable1\[182\]" " = 182 '\\\\266'"
+ gdb_test "p ctable1\[183\]" " = 183 '\\\\267'"
+ gdb_test "p ctable1\[184\]" " = 184 '\\\\270'"
+ gdb_test "p ctable1\[185\]" " = 185 '\\\\271'"
+ gdb_test "p ctable1\[186\]" " = 186 '\\\\272'"
+ gdb_test "p ctable1\[187\]" " = 187 '\\\\273'"
+ gdb_test "p ctable1\[188\]" " = 188 '\\\\274'"
+ gdb_test "p ctable1\[189\]" " = 189 '\\\\275'"
+ gdb_test "p ctable1\[190\]" " = 190 '\\\\276'"
+ gdb_test "p ctable1\[191\]" " = 191 '\\\\277'"
+ gdb_test "p ctable1\[192\]" " = 192 '\\\\300'"
+ gdb_test "p ctable1\[193\]" " = 193 '\\\\301'"
+ gdb_test "p ctable1\[194\]" " = 194 '\\\\302'"
+ gdb_test "p ctable1\[195\]" " = 195 '\\\\303'"
+ gdb_test "p ctable1\[196\]" " = 196 '\\\\304'"
+ gdb_test "p ctable1\[197\]" " = 197 '\\\\305'"
+ gdb_test "p ctable1\[198\]" " = 198 '\\\\306'"
+ gdb_test "p ctable1\[199\]" " = 199 '\\\\307'"
+ gdb_test "p ctable1\[200\]" " = 200 '\\\\310'"
+ gdb_test "p ctable1\[201\]" " = 201 '\\\\311'"
+ gdb_test "p ctable1\[202\]" " = 202 '\\\\312'"
+ gdb_test "p ctable1\[203\]" " = 203 '\\\\313'"
+ gdb_test "p ctable1\[204\]" " = 204 '\\\\314'"
+ gdb_test "p ctable1\[205\]" " = 205 '\\\\315'"
+ gdb_test "p ctable1\[206\]" " = 206 '\\\\316'"
+ gdb_test "p ctable1\[207\]" " = 207 '\\\\317'"
+ gdb_test "p ctable1\[208\]" " = 208 '\\\\320'"
+ gdb_test "p ctable1\[209\]" " = 209 '\\\\321'"
+ gdb_test "p ctable1\[210\]" " = 210 '\\\\322'"
+ gdb_test "p ctable1\[211\]" " = 211 '\\\\323'"
+ gdb_test "p ctable1\[212\]" " = 212 '\\\\324'"
+ gdb_test "p ctable1\[213\]" " = 213 '\\\\325'"
+ gdb_test "p ctable1\[214\]" " = 214 '\\\\326'"
+ gdb_test "p ctable1\[215\]" " = 215 '\\\\327'"
+ gdb_test "p ctable1\[216\]" " = 216 '\\\\330'"
+ gdb_test "p ctable1\[217\]" " = 217 '\\\\331'"
+ gdb_test "p ctable1\[218\]" " = 218 '\\\\332'"
+ gdb_test "p ctable1\[219\]" " = 219 '\\\\333'"
+ gdb_test "p ctable1\[220\]" " = 220 '\\\\334'"
+ gdb_test "p ctable1\[221\]" " = 221 '\\\\335'"
+ gdb_test "p ctable1\[222\]" " = 222 '\\\\336'"
+ gdb_test "p ctable1\[223\]" " = 223 '\\\\337'"
+ gdb_test "p ctable1\[224\]" " = 224 '\\\\340'"
+ gdb_test "p ctable1\[225\]" " = 225 '\\\\341'"
+ gdb_test "p ctable1\[226\]" " = 226 '\\\\342'"
+ gdb_test "p ctable1\[227\]" " = 227 '\\\\343'"
+ gdb_test "p ctable1\[228\]" " = 228 '\\\\344'"
+ gdb_test "p ctable1\[229\]" " = 229 '\\\\345'"
+ gdb_test "p ctable1\[230\]" " = 230 '\\\\346'"
+ gdb_test "p ctable1\[231\]" " = 231 '\\\\347'"
+ gdb_test "p ctable1\[232\]" " = 232 '\\\\350'"
+ gdb_test "p ctable1\[233\]" " = 233 '\\\\351'"
+ gdb_test "p ctable1\[234\]" " = 234 '\\\\352'"
+ gdb_test "p ctable1\[235\]" " = 235 '\\\\353'"
+ gdb_test "p ctable1\[236\]" " = 236 '\\\\354'"
+ gdb_test "p ctable1\[237\]" " = 237 '\\\\355'"
+ gdb_test "p ctable1\[238\]" " = 238 '\\\\356'"
+ gdb_test "p ctable1\[239\]" " = 239 '\\\\357'"
+ gdb_test "p ctable1\[240\]" " = 240 '\\\\360'"
+ gdb_test "p ctable1\[241\]" " = 241 '\\\\361'"
+ gdb_test "p ctable1\[242\]" " = 242 '\\\\362'"
+ gdb_test "p ctable1\[243\]" " = 243 '\\\\363'"
+ gdb_test "p ctable1\[244\]" " = 244 '\\\\364'"
+ gdb_test "p ctable1\[245\]" " = 245 '\\\\365'"
+ gdb_test "p ctable1\[246\]" " = 246 '\\\\366'"
+ gdb_test "p ctable1\[247\]" " = 247 '\\\\367'"
+ gdb_test "p ctable1\[248\]" " = 248 '\\\\370'"
+ gdb_test "p ctable1\[249\]" " = 249 '\\\\371'"
+ gdb_test "p ctable1\[250\]" " = 250 '\\\\372'"
+ gdb_test "p ctable1\[251\]" " = 251 '\\\\373'"
+ gdb_test "p ctable1\[252\]" " = 252 '\\\\374'"
+ gdb_test "p ctable1\[253\]" " = 253 '\\\\375'"
+ gdb_test "p ctable1\[254\]" " = 254 '\\\\376'"
+ gdb_test "p ctable1\[255\]" " = 255 '\\\\377'"
+}
+
+# Test interaction of the number of print elements to print and the
+# repeat count, set to the default of 10.
+
+proc test_print_repeats_10 {} {
+ global gdb_prompt
+
+ for { set x 1; } { $x <= 16 } { incr x; } {
+ gdb_test "set print elements $x" ""
+ for { set e 1; } { $e <= 16 } {incr e; } {
+ set v [expr $e - 1];
+ set command "p &ctable2\[${v}*16\]"
+ if { $x < $e } {
+ set aval $x;
+ } else {
+ set aval $e;
+ }
+ set xval [expr $x - $e];
+ if { $xval < 0 } {
+ set xval 0;
+ }
+ if { $aval > 10 } {
+ set a "'a' <repeats $aval times>";
+ if { $xval > 0 } {
+ set a "${a}, \\\"";
+ }
+ } else {
+ set a "\\\"[string range "aaaaaaaaaaaaaaaa" 1 $aval]";
+ if { $xval > 10 } {
+ set a "$a\\\", ";
+ }
+ }
+ set xstr "";
+ if { $xval > 10 } {
+ set xstr "'X' <repeats $xval times>";
+ } else {
+ if { $xval > 0 } {
+ set xstr "[string range "XXXXXXXXXXXXXXXX" 1 $xval]\\\"";
+ } else {
+ if { $aval <= 10 } {
+ set xstr "\\\"";
+ }
+ }
+ }
+ if { $aval < 16 } {
+ set xstr "${xstr}\[.\]\[.\]\[.\]"
+ }
+ set string " = \[(\]unsigned char \[*\]\[)\] ${a}${xstr}";
+ gdb_test "$command" "$string" "$command with print elements set to $x";
+ }
+ }
+}
+
+proc test_print_strings {} {
+ global gdb_prompt
+
+ # We accept "(unsigned char *) " before the string. char vs. unsigned char
+ # is already tested elsewhere.
+
+ # Test that setting print elements unlimited doesn't completely suppress
+ # printing; this was a bug in older gdb's.
+ gdb_test "set print elements 0" ""
+ gdb_test "p teststring" \
+ " = (.unsigned char .. )?\"teststring contents\"" "p teststring with elements set to 0"
+ gdb_test "set print elements 1" ""
+ gdb_test "p teststring" \
+ " = (.unsigned char .. )?\"t\"\\.\\.\\." "p teststring with elements set to 1"
+ gdb_test "set print elements 5" ""
+ gdb_test "p teststring" \
+ " = (.unsigned char .. )?\"tests\"\\.\\.\\." "p teststring with elements set to 5"
+ gdb_test "set print elements 19" ""
+ gdb_test "p teststring" \
+ " = (.unsigned char .. )?\"teststring contents\"" "p teststring with elements set to 19"
+ gdb_test "set print elements 20" ""
+ gdb_test "p teststring" \
+ " = (.unsigned char .. )?\"teststring contents\"" "p teststring with elements set to 20"
+
+ gdb_test "set print elements 8" ""
+
+ gdb_test "p &ctable1\[0\]" \
+ " = \\(unsigned char \\*\\) \"\""
+ gdb_test "p &ctable1\[1\]" \
+ " = \\(unsigned char \\*\\) \"\\\\001\\\\002\\\\003\\\\004\\\\005\\\\006\\\\a\\\\b\"..."
+ gdb_test "p &ctable1\[1*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\b\\\\t\\\\n\\\\v\\\\f\\\\r\\\\016\\\\017\"..."
+ gdb_test "p &ctable1\[2*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\020\\\\021\\\\022\\\\023\\\\024\\\\025\\\\026\\\\027\"..."
+ gdb_test "p &ctable1\[3*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\030\\\\031\\\\032\\\\e\\\\034\\\\035\\\\036\\\\037\"..."
+ gdb_test "p &ctable1\[4*8\]" \
+ " = \\(unsigned char \\*\\) \" !\\\\\"#\\\$%&'\"..."
+ gdb_test "p &ctable1\[5*8\]" \
+ " = \\(unsigned char \\*\\) \"\\(\\)\\*\\+,-./\"..."
+ gdb_test "p &ctable1\[6*8\]" \
+ " = \\(unsigned char \\*\\) \"01234567\"..."
+ gdb_test "p &ctable1\[7*8\]" \
+ " = \\(unsigned char \\*\\) \"89:;<=>\\?\"..."
+ gdb_test "p &ctable1\[8*8\]" \
+ " = \\(unsigned char \\*\\) \"@ABCDEFG\"..."
+ gdb_test "p &ctable1\[9*8\]" \
+ " = \\(unsigned char \\*\\) \"HIJKLMNO\"..."
+ gdb_test "p &ctable1\[10*8\]" \
+ " = \\(unsigned char \\*\\) \"PQRSTUVW\"..."
+ gdb_test "p &ctable1\[11*8\]" \
+ " = \\(unsigned char \\*\\) \"XYZ\\\[\\\\\\\\\\\]\\^_\"..."
+ gdb_test "p &ctable1\[12*8\]" \
+ " = \\(unsigned char \\*\\) \"`abcdefg\"..."
+ gdb_test "p &ctable1\[13*8\]" \
+ " = \\(unsigned char \\*\\) \"hijklmno\"..."
+ gdb_test "p &ctable1\[14*8\]" \
+ " = \\(unsigned char \\*\\) \"pqrstuvw\"..."
+ gdb_test "p &ctable1\[15*8\]" \
+ " = \\(unsigned char \\*\\) \"xyz\[{|}\]+\\~\\\\177\"..."
+ gdb_test "p &ctable1\[16*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\200\\\\201\\\\202\\\\203\\\\204\\\\205\\\\206\\\\207\"..."
+ gdb_test "p &ctable1\[17*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\210\\\\211\\\\212\\\\213\\\\214\\\\215\\\\216\\\\217\"..."
+ gdb_test "p &ctable1\[18*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\220\\\\221\\\\222\\\\223\\\\224\\\\225\\\\226\\\\227\"..."
+ gdb_test "p &ctable1\[19*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\230\\\\231\\\\232\\\\233\\\\234\\\\235\\\\236\\\\237\"..."
+ gdb_test "p &ctable1\[20*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\240\\\\241\\\\242\\\\243\\\\244\\\\245\\\\246\\\\247\"..."
+ gdb_test "p &ctable1\[21*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\250\\\\251\\\\252\\\\253\\\\254\\\\255\\\\256\\\\257\"..."
+ gdb_test "p &ctable1\[22*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\260\\\\261\\\\262\\\\263\\\\264\\\\265\\\\266\\\\267\"..."
+ gdb_test "p &ctable1\[23*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\270\\\\271\\\\272\\\\273\\\\274\\\\275\\\\276\\\\277\"..."
+ gdb_test "p &ctable1\[24*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\300\\\\301\\\\302\\\\303\\\\304\\\\305\\\\306\\\\307\"..."
+ gdb_test "p &ctable1\[25*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\310\\\\311\\\\312\\\\313\\\\314\\\\315\\\\316\\\\317\"..."
+ gdb_test "p &ctable1\[26*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\320\\\\321\\\\322\\\\323\\\\324\\\\325\\\\326\\\\327\"..."
+ gdb_test "p &ctable1\[27*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\330\\\\331\\\\332\\\\333\\\\334\\\\335\\\\336\\\\337\"..."
+ gdb_test "p &ctable1\[28*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\340\\\\341\\\\342\\\\343\\\\344\\\\345\\\\346\\\\347\"..."
+ gdb_test "p &ctable1\[29*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\350\\\\351\\\\352\\\\353\\\\354\\\\355\\\\356\\\\357\"..."
+ gdb_test "p &ctable1\[30*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\360\\\\361\\\\362\\\\363\\\\364\\\\365\\\\366\\\\367\"..."
+ gdb_test "p &ctable1\[31*8\]" \
+ " = \\(unsigned char \\*\\) \"\\\\370\\\\371\\\\372\\\\373\\\\374\\\\375\\\\376\\\\377\"..."
+}
+
+proc test_print_int_arrays {} {
+ global gdb_prompt
+
+ gdb_test "set print elements 24" ""
+
+ gdb_test_escape_braces "p int1dim" \
+ " = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}"
+ gdb_test_escape_braces "p int2dim" \
+ " = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}}"
+ gdb_test_escape_braces "p int3dim" \
+ " = {{{0, 1}, {2, 3}, {4, 5}}, {{6, 7}, {8, 9}, {10, 11}}}"
+ gdb_test_escape_braces "p int4dim" \
+ " = {{{{0, 1}, {2, 3}, {4, 5}}, {{6, 7}, {8, 9}, {10, 11}}}}"
+}
+
+proc test_print_typedef_arrays {} {
+ global gdb_prompt
+
+ gdb_test "set print elements 24" ""
+
+ gdb_test_escape_braces "p a1" \
+ " = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20}"
+ gdb_test "p a1\[0\]" " = 2"
+ gdb_test "p a1\[9\]" " = 20"
+
+ gdb_test "p a2" \
+ " = \"abcd\""
+ gdb_test "p a2\[0\]" " = 97 'a'"
+ gdb_test "p a2\[3\]" " = 100 'd'"
+}
+
+proc test_artificial_arrays {} {
+ # Send \026@ instead of just @ in case the kill character is @.
+ gdb_test_escape_braces "p int1dim\[0\]\026@2" " = {0, 1}" {p int1dim[0]@2}
+ gdb_test_escape_braces "p int1dim\[0\]\026@2\026@3" \
+ "({{0, 1}, {2, 3}, {4, 5}}|\[Cc\]annot.*)" \
+ {p int1dim[0]@2@3}
+ gdb_test_escape_braces {p/x (short [])0x12345678} \
+ " = ({0x1234, 0x5678}|{0x5678, 0x1234})"
+}
+
+proc test_print_char_arrays {} {
+ global gdb_prompt
+ global hex
+
+ gdb_test "set print elements 24" ""
+ gdb_test "set print address on" ""
+
+ gdb_test "p arrays" \
+ " = {array1 = \"abc\", array2 = \"d\", array3 = \"e\", array4 = \"fg\", array5 = \"hij\"}"
+
+ gdb_test "p parrays" " = \\(struct some_arrays \\*\\) $hex"
+ gdb_test "p parrays->array1" " = \"abc\""
+ gdb_test "p &parrays->array1" " = \\(unsigned char \\(\\*\\)\\\[4\\\]\\) $hex"
+ gdb_test "p parrays->array2" " = \"d\""
+ gdb_test "p &parrays->array2" " = \\(unsigned char \\(\\*\\)\\\[1\\\]\\) $hex"
+ gdb_test "p parrays->array3" " = \"e\""
+ gdb_test "p &parrays->array3" " = \\(unsigned char \\(\\*\\)\\\[1\\\]\\) $hex"
+ gdb_test "p parrays->array4" " = \"fg\""
+ gdb_test "p &parrays->array4" " = \\(unsigned char \\(\\*\\)\\\[2\\\]\\) $hex"
+ gdb_test "p parrays->array5" " = \"hij\""
+ gdb_test "p &parrays->array5" " = \\(unsigned char \\(\\*\\)\\\[4\\\]\\) $hex"
+
+ gdb_test "set print address off" ""
+}
+
+proc test_print_string_constants {} {
+ global gdb_prompt
+
+ gdb_test "set print elements 50" ""
+
+ if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ return
+ }
+
+ # We need to up this because this can be really slow on some boards.
+ # (Test may involve inferior malloc() calls).
+ set timeout 60;
+
+ gdb_test "p \"a string\"" " = \"a string\""
+ gdb_test "p \"embedded \\000 null\"" " = \"embedded \\\\0 null\""
+ gdb_test "p \"abcd\"\[2\]" " = 99 'c'"
+ gdb_test "p sizeof (\"abcdef\")" " = 7"
+ gdb_test "ptype \"foo\"" " = char \\\[4\\\]"
+ gdb_test "p *\"foo\"" " = 102 'f'"
+ gdb_test "ptype *\"foo\"" " = char"
+ gdb_test "p &*\"foo\"" " = \"foo\""
+ # setup_kfail "gdb/538"
+ gdb_test "ptype &*\"foo\"" "type = char \\*"
+ gdb_test "p (char *)\"foo\"" " = \"foo\""
+}
+
+proc test_print_array_constants {} {
+
+ if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ return
+ }
+
+ # We need to up this because this can be really slow on some boards.
+ # (Test may involve inferior malloc() calls).
+ set timeout 60;
+
+ gdb_test "print {'a','b','c'}" " = \"abc\""
+ gdb_test_escape_braces "print {0,1,2}" " = {0, 1, 2}"
+ gdb_test_escape_braces "print {(long)0,(long)1,(long)2}" " = {0, 1, 2}"
+ gdb_test_escape_braces "print {{0,1,2},{3,4,5}}" " = {{0, 1, 2}, {3, 4, 5}}"
+ gdb_test "print {4,5,6}\[2\]" " = 6"
+ gdb_test "print *&{4,5,6}\[1\]" " = 5"
+}
+
+proc test_printf {} {
+ gdb_test "printf \"x=%d,y=%d,z=%d\\n\", 5, 6, 7" "x=5,y=6,z=7"
+ gdb_test "printf \"string=%.4sxx\\n\", teststring" "string=testxx"
+ gdb_test "printf \"string=%sxx\\n\", teststring" \
+ "string=teststring contentsxx"
+
+ gdb_test "printf \"%f is fun\\n\", 1.0" "1\.0+ is fun"
+
+ # Test mixing args of different sizes.
+ gdb_test "printf \"x=%d,y=%f,z=%d\\n\", 5, 6.0, 7" "x=5,y=6\.0+,z=7"
+ gdb_test "printf \"%x %f, %c %x, %x, %f\\n\", 0xbad, -99.541, 'z',\
+0xfeedface, 0xdeadbeef, 5.0" "bad -99.54\[0-9\]+, z feedface, deadbeef, 5.0+"
+}
+
+# Escape a left curly brace to prevent it from being interpreted as
+# the beginning of a bound
+proc gdb_test_escape_braces { args } {
+
+ set pattern [lindex $args 1]
+ regsub -all {\{[0-9]} $pattern {\\&} esc_pattern
+ gdb_test [lindex $args 0] $esc_pattern [lindex $args 2]
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "print \$pc" "No registers\\."
+# FIXME: should also test "print $pc" when there is an execfile but no
+# remote debugging target, process or corefile.
+
+gdb_load ${binfile}
+
+gdb_test "set print sevenbit-strings" ""
+gdb_test "set print address off" ""
+gdb_test "set width 0" ""
+
+if [set_lang_c] then {
+ gdb_test "p ctable1\[120\]" "120 'x'" "p ctable1\[120\] #1"
+
+ if [runto_main] then {
+ test_integer_literals_accepted
+ test_integer_literals_rejected
+ test_character_literals_accepted
+ test_print_all_chars
+ test_print_repeats_10
+ test_print_strings
+ test_print_int_arrays
+ test_print_typedef_arrays
+ test_artificial_arrays
+ test_print_char_arrays
+# We used to do the runto main here.
+ test_print_string_constants
+ test_print_array_constants
+ test_printf
+ }
+} else {
+ fail "C print command tests suppressed"
+}
diff --git a/gdb/testsuite/gdb.base/ptype.c b/gdb/testsuite/gdb.base/ptype.c
new file mode 100644
index 00000000000..2c85c7c88fc
--- /dev/null
+++ b/gdb/testsuite/gdb.base/ptype.c
@@ -0,0 +1,346 @@
+/*
+ * Test file with lots of different types, for testing the
+ * "ptype" command.
+ */
+
+/*
+ * First the basic C types.
+ */
+#include <stdlib.h>
+
+#if !defined (__STDC__) && !defined (_AIX)
+#define signed /**/
+#endif
+
+char v_char;
+signed char v_signed_char;
+unsigned char v_unsigned_char;
+
+short v_short;
+signed short v_signed_short;
+unsigned short v_unsigned_short;
+
+int v_int;
+signed int v_signed_int;
+unsigned int v_unsigned_int;
+
+long v_long;
+signed long v_signed_long;
+unsigned long v_unsigned_long;
+
+float v_float;
+double v_double;
+
+/*
+ * Now some derived types, which are arrays, functions-returning,
+ * pointers, structures, unions, and enumerations.
+ */
+
+/**** arrays *******/
+
+char v_char_array[2];
+signed char v_signed_char_array[2];
+unsigned char v_unsigned_char_array[2];
+
+short v_short_array[2];
+signed short v_signed_short_array[2];
+unsigned short v_unsigned_short_array[2];
+
+int v_int_array[2];
+signed int v_signed_int_array[2];
+unsigned int v_unsigned_int_array[2];
+
+long v_long_array[2];
+signed long v_signed_long_array[2];
+unsigned long v_unsigned_long_array[2];
+
+float v_float_array[2];
+double v_double_array[2];
+
+/* PR 3742 */
+typedef char t_char_array[];
+
+/**** pointers *******/
+
+char *v_char_pointer;
+signed char *v_signed_char_pointer;
+unsigned char *v_unsigned_char_pointer;
+
+short *v_short_pointer;
+signed short *v_signed_short_pointer;
+unsigned short *v_unsigned_short_pointer;
+
+int *v_int_pointer;
+signed int *v_signed_int_pointer;
+unsigned int *v_unsigned_int_pointer;
+
+long *v_long_pointer;
+signed long *v_signed_long_pointer;
+unsigned long *v_unsigned_long_pointer;
+
+float *v_float_pointer;
+double *v_double_pointer;
+
+/**** structs *******/
+
+struct t_struct {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_struct1;
+
+struct t_struct *v_t_struct_p;
+
+struct {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_struct2;
+
+/* typedef'd struct without a tag. */
+typedef struct {
+ double v_double_member;
+ int v_int_member;
+} t_struct3;
+/* GCC seems to want a variable of this type, or else it won't put out
+ a symbol. */
+t_struct3 v_struct3;
+
+/**** unions *******/
+
+union t_union {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_union;
+
+union {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_union2;
+
+/* typedef'd union without a tag. */
+typedef union {
+ double v_double_member;
+ int v_int_member;
+} t_union3;
+/* GCC seems to want a variable of this type, or else it won't put out
+ a symbol. */
+t_union3 v_union3;
+
+/*** Functions returning type ********/
+
+char v_char_func () { return(0); }
+signed char v_signed_char_func () { return (0); }
+unsigned char v_unsigned_char_func () { return (0); }
+
+short v_short_func () { return (0); }
+signed short v_signed_short_func () { return (0); }
+unsigned short v_unsigned_short_func () { return (0); }
+
+int v_int_func () { return (0); }
+signed int v_signed_int_func () { return (0); }
+unsigned int v_unsigned_int_func () { return (0); }
+
+long v_long_func () { return (0); }
+signed long v_signed_long_func () { return (0); }
+unsigned long v_unsigned_long_func () { return (0); }
+
+float v_float_func () { return (0.0); }
+double v_double_func () { return (0.0); }
+
+/**** Some misc more complicated things *******/
+
+struct link {
+ struct link *next;
+#ifdef __STDC__
+ struct link *(*linkfunc) (struct link *this, int flags);
+#else
+ struct link *(*linkfunc) ();
+#endif
+ struct t_struct stuff[1][2][3];
+} *s_link;
+
+union tu_link {
+ struct link *next;
+#ifdef __STDC__
+ struct link *(*linkfunc) (struct link *this, int flags);
+#else
+ struct link *(*linkfunc) ();
+#endif
+ struct t_struct stuff[1][2][3];
+} u_link;
+
+struct outer_struct {
+ int outer_int;
+ struct inner_struct {
+ int inner_int;
+ long inner_long;
+ }inner_struct_instance;
+ union inner_union {
+ int inner_union_int;
+ long inner_union_long;
+ }inner_union_instance;
+ long outer_long;
+} nested_su;
+
+/**** Enumerations *******/
+
+enum
+/* Work around the bug for compilers which don't put out the right stabs. */
+#if __GNUC__ < 2 && !defined (_AIX)
+primary1_tag
+#endif
+{red1, green1, blue1} primary1;
+
+enum {red, green, blue} primary;
+enum colors {yellow, purple, pink} nonprimary;
+
+enum {chevy, ford} clunker;
+enum cars {bmw, porsche} sportscar;
+
+#undef FALSE
+#undef TRUE
+typedef enum {FALSE, TRUE} boolean;
+boolean v_boolean;
+/*note: aCC has bool type predefined with 'false' and 'true'*/
+typedef enum bvals {my_false, my_true} boolean2;
+boolean2 v_boolean2;
+
+enum misordered {two = 2, one = 1, zero = 0, three = 3};
+
+/* Seems like we need a variable of this type to get the type to be put
+ in the executable, at least for AIX xlc. */
+enum misordered v_misordered = three;
+
+/**** Pointers to functions *******/
+
+typedef int (*func_type) (int (*) (int, float), float);
+double (*old_fptr) ();
+double (*new_fptr) (void);
+int (*fptr) (int, float);
+int *(*fptr2) (int (*) (int, float), float);
+int (*xptr) (int (*) (), int (*) (void), int);
+int (*(*ffptr) (char)) (short);
+int (*(*(*fffptr) (char)) (short)) (long);
+
+/* Here are the sort of stabs we expect to see for the above:
+
+ .stabs "func_type:t(0,100)=*(0,101)=g(0,1)(0,102)=*(0,103)=g(0,1)(0,1)(0,14)#(0,14)#",128,0,234,0
+ .stabs "old_fptr:G(0,110)=*(0,111)=f(0,15)",32,0,231,0
+ .stabs "new_fptr:G(0,120)=*(0,121)=g(0,15)(0,122)=(0,122)#",32,0,232,0
+ .stabs "fptr:G(0,130)=*(0,103)#",32,0,233,0
+ .stabs "fptr2:G(0,140)=*(0,141)=g(0,142)=*(0,1)(0,102)(0,14)#",32,0,235,0
+ .stabs "xptr:G(0,150)=*(0,151)=g(0,1)(0,152)=*(0,153)=f(0,1)(0,154)=*(0,155)=g(0,1)(0,122)#(0,1)#",32,0,236,0
+ .stabs "ffptr:G(0,160)=*(0,161)=g(0,162)=*(0,163)=g(0,1)(0,8)#(0,2)#",32,0,237,0\
+ .stabs "fffptr:G(0,170)=*(0,171)=g(0,172)=*(0,173)=g(0,174)=*(0,175)=g(0,1)(0,3)#(0,8)#(0,2)#",32,0,237,0
+
+ Most of these use Sun's extension for prototyped function types ---
+ the 'g' type descriptor. As of around 9 Feb 2002, GCC didn't emit
+ those, but GDB can read them, so the related tests in ptype.exp
+ will all xfail. */
+
+
+/***********/
+
+int main ()
+{
+ /* Ensure that malloc is a pointer type; avoid use of "void" and any include files. */
+/* extern char *malloc();*/
+
+ /* Some of the tests in ptype.exp require invoking malloc, so make
+ sure it is linked in to this program. */
+ v_char_pointer = (char *) malloc (1);
+
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ /* Some linkers (e.g. on AIX) remove unreferenced variables,
+ so make sure to reference them. */
+ primary = blue;
+ primary1 = blue1;
+ nonprimary = pink;
+ sportscar = porsche;
+ clunker = ford;
+ v_struct1.v_int_member = 5;
+ v_struct2.v_int_member = 6;
+ v_struct3.v_int_member = 7;
+
+ v_char = 0;
+ v_signed_char = 0;
+ v_unsigned_char = 0;
+
+ v_short = 0;
+ v_signed_short = 0;
+ v_unsigned_short = 0;
+
+ v_int = 0;
+ v_signed_int = 0;
+ v_unsigned_int = 0;
+
+ v_long = 0;
+ v_signed_long = 0;
+ v_unsigned_long = 0;
+
+ v_float = 0;
+ v_double = 0;
+
+ v_char_array[0] = 0;
+ v_signed_char_array[0] = 0;
+ v_unsigned_char_array[0] = 0;
+
+ v_short_array[0] = 0;
+ v_signed_short_array[0] = 0;
+ v_unsigned_short_array[0] = 0;
+
+ v_int_array[0] = 0;
+ v_signed_int_array[0] = 0;
+ v_unsigned_int_array[0] = 0;
+
+ v_long_array[0] = 0;
+ v_signed_long_array[0] = 0;
+ v_unsigned_long_array[0] = 0;
+
+ v_float_array[0] = 0;
+ v_double_array[0] = 0;
+
+ v_char_pointer = 0;
+ v_signed_char_pointer = 0;
+ v_unsigned_char_pointer = 0;
+
+ v_short_pointer = 0;
+ v_signed_short_pointer = 0;
+ v_unsigned_short_pointer = 0;
+
+ v_int_pointer = 0;
+ v_signed_int_pointer = 0;
+ v_unsigned_int_pointer = 0;
+
+ v_long_pointer = 0;
+ v_signed_long_pointer = 0;
+ v_unsigned_long_pointer = 0;
+
+ v_float_pointer = 0;
+ v_double_pointer = 0;
+
+ nested_su.outer_int = 0;
+ v_t_struct_p = 0;
+
+ v_boolean = FALSE;
+ v_boolean2 = my_false;
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/ptype.exp b/gdb/testsuite/gdb.base/ptype.exp
new file mode 100644
index 00000000000..8ef738e28ab
--- /dev/null
+++ b/gdb/testsuite/gdb.base/ptype.exp
@@ -0,0 +1,609 @@
+# Copyright 1988, 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1999,
+# 2000, 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "ptype"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Test ptype of unnamed enumeration members before any action causes
+# the partial symbol table to be expanded to full symbols. This fails
+# with stabs compilers which fail to use a nameless stab (such as
+# pre-2.4.5 versions of gcc and most non-gcc compilers).
+
+send_gdb "ptype red1\n"
+gdb_expect {
+ -re "type = enum primary1_tag \{red1, green1, blue1\}.*$gdb_prompt $"\
+ {
+ # The workaround is in effect. As this is a compiler, not GDB,
+ # bug, we'll make it a PASS but perhaps it should be an XFAIL.
+ pass "ptype unnamed enumeration member (worked around)"
+ }
+ -re "type = enum \{red1, green1, blue1\}.*$gdb_prompt $"\
+ { pass "ptype unnamed enumeration member" }
+ -re ".*$gdb_prompt $" { fail "ptype unnamed enumeration member" }
+ timeout { fail "(timeout) ptype unnamed enumeration member" }
+}
+
+#
+# test ptype command with structures
+#
+# Here and elsewhere, we accept
+# "long", "long int", or "int" for long variables (whatis.exp already
+# has an XFAIL for "int" (Sun cc bug), so no need to fail it here).
+gdb_test "ptype struct t_struct" "type = struct t_struct \{.*\[\r\n\] (unsigned |)char v_char_member;.*\[\r\n\] (short|short int) v_short_member;.*\[\r\n\] int v_int_member;.*\[\r\n\] (long|long int|int) v_long_member;.*\[\r\n\] float v_float_member;.*\[\r\n\] double v_double_member;.*\[\r\n\]\}.*" "ptype structure"
+
+
+# Test the equivalence between '.' and '->' for struct member references.
+
+if [gdb_test "ptype v_struct1.v_float_member" "type = float"]<0 then {
+ return -1
+}
+if [gdb_test "ptype v_struct1->v_float_member" "type = float"]<0 then {
+ return -1
+}
+if [gdb_test "ptype v_t_struct_p.v_float_member" "type = float"]<0 then {
+ return -1
+}
+if [gdb_test "ptype v_t_struct_p->v_float_member" "type = float"]<0 then {
+ return -1
+}
+
+
+# IBM's xlc puts out bogus stabs--the stuff field is type 42,
+# which isn't defined.
+
+gdb_test "ptype struct link" "type = struct link \{\[\r\n\]+\[ \t\]+struct link \\*next;\[\r\n\]+\[ \t\]+struct link \\*\\(\\*linkfunc\\)\\((struct link \\*, int|void|)\\);\[\r\n\]+\[ \t\]+struct t_struct stuff.1..2..3.;\[\r\n\]+\}.*" "ptype linked list structure"
+
+#
+# test ptype command with unions
+#
+gdb_test "ptype union t_union" "type = union t_union \{.*\[\r\n\] (unsigned |)char v_char_member;.*\[\r\n\] (short|short int) v_short_member;.*\[\r\n\] int v_int_member;.*\[\r\n\] (long|long int|int) v_long_member;.*\[\r\n\] float v_float_member;.*\[\r\n\] double v_double_member;.*\[\r\n\]\}.*" "ptype union"
+
+# IBM's xlc puts out bogus stabs--the stuff field is type 42,
+# which isn't defined.
+gdb_test "ptype union tu_link" "type = union tu_link \{\[\r\n\]+\[ \t\]+struct link \\*next;\[\r\n\]+\[ \t\]+struct link \\*\\(\\*linkfunc\\)\\((struct link \\*, int|void|)\\);\[\r\n\]+\[ \t\]+struct t_struct stuff.1..2..3.;\[\r\n\]+\}.*" "ptype linked list union"
+
+#
+# test ptype command with enums
+#
+
+gdb_test "ptype primary" "type = enum .red, green, blue.*" "ptype unnamed enumeration"
+
+gdb_test "ptype enum colors" "type = enum colors \{yellow, purple, pink\}.*" "ptype named enumeration"
+
+
+#
+# test ptype command with enums as typedef
+#
+gdb_test "ptype boolean" "type = enum (boolean |)\{FALSE, TRUE\}.*" "ptype unnamed typedef'd enumeration"
+
+# And check that whatis shows the name, not "enum {...}".
+# This probably fails for all DWARF 1 cases, so assume so for now. -fnf
+# The problem with xlc is that the stabs look like
+# :t51=eFALSE:0,TRUE:1,;
+# boolean:t55=51
+# v_boolean:G51
+# GDB's behavior is correct; the type which the variable is defined
+# as (51) doesn't have a name. Only 55 has a name.
+
+if {!$gcc_compiled && !$hp_aCC_compiler} {
+ setup_xfail "rs6000-*-*" "i*86-*-sysv4*"
+ setup_xfail "hppa*-*-*" CLLbs14773
+}
+
+# For get_debug_format to do its job, we need to have a current source file.
+gdb_test "list main" ""
+get_debug_format
+setup_xfail_format "DWARF 1"
+gdb_test "whatis v_boolean" "type = (enum |)boolean" \
+ "whatis unnamed typedef'd enum (compiler bug in IBM's xlc)"
+
+# Same thing with struct and union.
+gdb_test "ptype t_struct3" "type = struct (t_struct3 |)\{.*
+ *double v_double_member;.*
+ *int v_int_member;.*\}" "printing typedef'd struct"
+
+gdb_test "ptype t_union3" "type = union (t_union3 |)\{.*
+ *double v_double_member;.*
+ *int v_int_member;.*\}" "printing typedef'd union"
+
+gdb_test "ptype enum bvals" "type = enum bvals \{my_false, my_true\}.*" "ptype named typedef'd enumf'd enum"
+
+#
+# test ptype command with out-of-order enum values
+#
+gdb_test "ptype enum misordered" "type = enum misordered \{two = 2, one = 1, zero = 0, three = 3\}.*" "ptype misordered enumeration"
+
+#
+# test ptype command with a named enum's value
+#
+gdb_test "ptype three" "type = enum misordered \{two = 2, one = 1, zero = 0, three = 3\}.*" "ptype named enumeration member"
+
+gdb_test "ptype red" "type = enum \{red, green, blue\}.*" "ptype unnamed enumeration member #2"
+
+#
+# test ptype command with basic C types
+#
+# I've commented most of this out because it duplicates tests in whatis.exp.
+# I've just left in a token test or 2 which is designed to test that ptype
+# acts like whatis for basic types. If it is thought to be necessary to
+# test both whatis and ptype for all the types, the tests should be
+# merged into whatis.exp, or else maintenance will be a royal pain -kingdon
+#setup_xfail "i960-*-*" 1821
+#setup_xfail "mips-idt-*" "mips-sgi-*"
+#send "ptype v_char\n"
+#gdb_expect {
+# -re "type = char.*$gdb_prompt $" { pass "ptype char" }
+# -re ".*$gdb_prompt $" { fail "ptype char" }
+# timeout { fail "(timeout) ptype char" }
+#}
+#
+#
+#setup_xfail "mips-*-*"
+#send "ptype v_signed_char\n"
+#gdb_expect {
+# -re "type = signed char.*$gdb_prompt $" { pass "ptype signed char" }
+# -re ".*$gdb_prompt $" { fail "ptype signed char" }
+# timeout { fail "(timeout) ptype signed char" }
+#}
+#
+#
+#send "ptype v_unsigned_char\n"
+#gdb_expect {
+# -re "type = unsigned char.*$gdb_prompt $" { pass "ptype unsigned char" }
+# -re ".*$gdb_prompt $" { fail "ptype unsigned char" }
+# timeout { fail "(timeout) ptype unsigned char" }
+#}
+
+gdb_test "ptype v_short" "type = short(| int).*" "ptype short"
+
+#send "ptype v_signed_short\n"
+#gdb_expect {
+# -re "type = short.*$gdb_prompt $" { pass "ptype signed short" }
+# -re ".*$gdb_prompt $" { fail "ptype signed short" }
+# timeout { fail "(timeout) ptype signed short" }
+#}
+#
+#
+#send "ptype v_unsigned_short\n"
+#gdb_expect {
+# -re "type = unsigned short.*$gdb_prompt $" { pass "ptype unsigned short" }
+# -re ".*$gdb_prompt $" { fail "ptype unsigned short" }
+# timeout { fail "(timeout) ptype unsigned short" }
+#}
+
+
+gdb_test "ptype v_int" "type = int.*" "ptype int"
+
+#send "ptype v_signed_int\n"
+#gdb_expect {
+# -re "type = int.*$gdb_prompt $" { pass "ptype signed int" }
+# -re ".*$gdb_prompt $" { fail "ptype signed int" }
+# timeout { fail "(timeout) ptype signed int" }
+#}
+#
+#
+#send "ptype v_unsigned_int\n"
+#gdb_expect {
+# -re "type = unsigned int.*$gdb_prompt $" { pass "ptype unsigned int" }
+# -re ".*$gdb_prompt $" { fail "ptype unsigned int" }
+# timeout { fail "(timeout) ptype unsigned int" }
+#}
+#
+#
+#send "ptype v_long\n"
+#gdb_expect {
+# -re "type = long.*$gdb_prompt $" { pass "ptype long" }
+# -re ".*$gdb_prompt $" { fail "ptype long" }
+# timeout { fail "(timeout) ptype long" }
+#}
+#
+#
+#send "ptype v_signed_long\n"
+#gdb_expect {
+# -re "type = long.*$gdb_prompt $" { pass "ptype signed long" }
+# -re ".*$gdb_prompt $" { fail "ptype signed long" }
+# timeout { fail "(timeout) ptype signed long" }
+#}
+#
+#
+#send "ptype v_unsigned_long\n"
+#gdb_expect {
+# -re "type = unsigned long.*$gdb_prompt $" { pass "ptype unsigned long" }
+# -re ".*$gdb_prompt $" { fail "ptype unsigned long" }
+# timeout { fail "(timeout) ptype unsigned long" }
+#}
+#
+#
+#send "ptype v_float\n"
+#gdb_expect {
+# -re "type = float.*$gdb_prompt $" { pass "ptype float" }
+# -re ".*$gdb_prompt $" { fail "ptype float" }
+# timeout { fail "(timeout) ptype float" }
+#}
+#
+#
+#send "ptype v_double\n"
+#gdb_expect {
+# -re "type = double.*$gdb_prompt $" { pass "ptype double" }
+# -re ".*$gdb_prompt $" { fail "ptype double" }
+# timeout { fail "(timeout) ptype double" }
+#}
+
+
+#
+# test ptype command with arrays
+#
+#setup_xfail "i960-*-*" 1821
+#setup_xfail "mips-idt-*" "mips-sgi-*"
+#send "ptype v_char_array\n"
+#gdb_expect {
+# -re "type = char .2..*$gdb_prompt $" { pass "ptype char array" }
+# -re ".*$gdb_prompt $" { fail "ptype char array" }
+# timeout { fail "(timeout) ptype char array" }
+#}
+#
+#
+#setup_xfail "mips-*-*"
+#send "ptype v_signed_char_array\n"
+#gdb_expect {
+# -re "type = (|signed )char .2..*$gdb_prompt $" { pass "ptype signed char array" }
+# -re ".*$gdb_prompt $" { fail "ptype signed char array" }
+# timeout { fail "(timeout) ptype signed char array" }
+#}
+#
+#
+#send "ptype v_unsigned_char_array\n"
+#gdb_expect {
+# -re "type = unsigned char .2..*$gdb_prompt $" { pass "ptype unsigned char array" }
+# -re ".*$gdb_prompt $" { fail "ptype unsigned char array" }
+# timeout { fail "(timeout) ptype unsigned char array" }
+#}
+#
+#
+#
+#send "ptype v_int_array\n"
+#gdb_expect {
+# -re "type = int .2..*$gdb_prompt $" { pass "ptype int array" }
+# -re ".*$gdb_prompt $" { fail "ptype int array" }
+# timeout { fail "(timeout) ptype int array" }
+#}
+#
+#
+#send "ptype v_signed_int_array\n"
+#gdb_expect {
+# -re "type = int .2..*$gdb_prompt $" { pass "ptype signed int array" }
+# -re ".*$gdb_prompt $" { fail "ptype signed int array" }
+# timeout { fail "(timeout) ptype signed int array" }
+#}
+#
+#
+#send "ptype v_unsigned_int_array\n"
+#gdb_expect {
+# -re "type = unsigned int .2..*$gdb_prompt $" { pass "ptype unsigned int array" }
+# -re ".*$gdb_prompt $" { fail "ptype unsigned int array" }
+# timeout { fail "(timeout) ptype unsigned int array" }
+#}
+#
+#
+#send "ptype v_long_array\n"
+#gdb_expect {
+# -re "type = (long|int|long int) .2..*$gdb_prompt $" {
+# pass "ptype long array" }
+# -re ".*$gdb_prompt $" { fail "ptype long array" }
+# timeout { fail "(timeout) ptype long array" }
+#}
+#
+#
+#send "ptype v_signed_long_array\n"
+#gdb_expect {
+# -re "type = (long|int|long int) .2..*$gdb_prompt $" {
+# pass "ptype signed long array" }
+# -re ".*$gdb_prompt $" { fail "ptype signed long array" }
+# timeout { fail "(timeout) ptype signed long array" }
+#}
+#
+#
+#send "ptype v_unsigned_long_array\n"
+#gdb_expect {
+# -re "type = unsigned long .2..*$gdb_prompt $" { pass "ptype unsigned long array" }
+# -re ".*$gdb_prompt $" { fail "ptype unsigned long array" }
+# timeout { fail "(timeout) ptype unsigned long array" }
+#}
+#
+#
+#send "ptype v_float_array\n"
+#gdb_expect {
+# -re "type = float .2..*$gdb_prompt $" { pass "ptype float array" }
+# -re ".*$gdb_prompt $" { fail "ptype float array" }
+# timeout { fail "(timeout) ptype float array" }
+#}
+#
+#
+#send "ptype v_double_array\n"
+#gdb_expect {
+# -re "type = double .2..*$gdb_prompt $" { pass "ptype double array" }
+# -re ".*$gdb_prompt $" { fail "ptype double array" }
+# timeout { fail "(timeout) ptype double array" }
+#}
+#
+
+if {!$gcc_compiled} then { setup_xfail "rs6000-*-*" "i*86-*-sysv4*" }
+setup_xfail_format "DWARF 1"
+if {$hp_aCC_compiler} {setup_xfail "hppa*-*-*"}
+gdb_test "ptype t_char_array" "type = (|unsigned )char \\\[0?\\\]"
+
+#
+##
+## test ptype command with pointers
+##
+#setup_xfail "i960-*-*" 1821
+#setup_xfail "mips-idt-*" "mips-sgi-*"
+#send "ptype v_char_pointer\n"
+#gdb_expect {
+# -re "type = char \*.*$gdb_prompt $" { pass "ptype char pointer" }
+# -re ".*$gdb_prompt $" { fail "ptype char pointer" }
+# timeout { fail "(timeout) ptype char pointer" }
+#}
+#
+#
+#setup_xfail "mips-*-*"
+#send "ptype v_signed_char_pointer\n"
+#gdb_expect {
+# -re "type = (|signed )char \*.*$gdb_prompt $"
+# { pass "ptype signed char pointer" }
+# -re ".*$gdb_prompt $" { fail "ptype signed char pointer" }
+# timeout { fail "(timeout) ptype signed char pointer" }
+#}
+#
+#
+#send "ptype v_unsigned_char_pointer\n"
+#gdb_expect {
+# -re "type = unsigned char \*.*$gdb_prompt $" { pass "ptype unsigned char pointer" }
+# -re ".*$gdb_prompt $" { fail "ptype unsigned char pointer" }
+# timeout { fail "(timeout) ptype unsigned char pointer" }
+#}
+#
+#
+#send "ptype v_short_pointer\n"
+#gdb_expect {
+# -re "type = (short|short int) \*.*$gdb_prompt $" { pass "ptype short pointer" }
+# -re ".*$gdb_prompt $" { fail "ptype short pointer" }
+# timeout { fail "(timeout) ptype short pointer" }
+#}
+#
+#
+#send "ptype v_signed_short_pointer\n"
+#gdb_expect {
+# -re "type = short \*.*$gdb_prompt $" { pass "ptype signed short pointer" }
+# -re ".*$gdb_prompt $" { fail "ptype signed short pointer" }
+# timeout { fail "(timeout) ptype signed short pointer" }
+#}
+#
+#
+#send "ptype v_unsigned_short_pointer\n"
+#gdb_expect {
+# -re "type = unsigned short \*.*$gdb_prompt $" { pass "ptype unsigned short pointer" }
+# -re ".*$gdb_prompt $" { fail "ptype unsigned short pointer" }
+# timeout { fail "(timeout) ptype unsigned short pointer" }
+#}
+#
+#
+#send "ptype v_int_pointer\n"
+#gdb_expect {
+# -re "type = int \*.*$gdb_prompt $" { pass "ptype int pointer" }
+# -re ".*$gdb_prompt $" { fail "ptype int pointer" }
+# timeout { fail "(timeout) ptype int pointer" }
+#}
+#
+#
+#send "ptype v_signed_int_pointer\n"
+#gdb_expect {
+# -re "type = int \*.*$gdb_prompt $" { pass "ptype signed int pointer" }
+# -re ".*$gdb_prompt $" { fail "ptype signed int pointer" }
+# timeout { fail "(timeout) ptype signed int pointer" }
+#}
+#
+#
+#send "ptype v_unsigned_int_pointer\n"
+#gdb_expect {
+# -re "type = unsigned int \*.*$gdb_prompt $" { pass "ptype unsigned int pointer" }
+# -re ".*$gdb_prompt $" { fail "ptype unsigned int pointer" }
+# timeout { fail "(timeout) ptype unsigned int pointer" }
+#}
+#
+#
+#send "ptype v_long_pointer\n"
+#gdb_expect {
+# -re "type = long \*.*$gdb_prompt $" { pass "ptype long pointer" }
+# -re ".*$gdb_prompt $" { fail "ptype long pointer" }
+# timeout { fail "(timeout) ptype long pointer" }
+#}
+#
+#
+#send "ptype v_signed_long_pointer\n"
+#gdb_expect {
+# -re "type = long \*.*$gdb_prompt $" { pass "ptype signed long pointer" }
+# -re ".*$gdb_prompt $" { fail "ptype signed long pointer" }
+# timeout { fail "(timeout) ptype signed long pointer" }
+#}
+#
+#
+#send "ptype v_unsigned_long_pointer\n"
+#gdb_expect {
+# -re "type = unsigned long \*.*$gdb_prompt $" { pass "ptype unsigned long pointer" }
+# -re ".*$gdb_prompt $" { fail "ptype unsigned long pointer" }
+# timeout { fail "(timeout) ptype unsigned long pointer" }
+#}
+#
+#
+#send "ptype v_float_pointer\n"
+#gdb_expect {
+# -re "type = float \*.*$gdb_prompt $" { pass "ptype float pointer" }
+# -re ".*$gdb_prompt $" { fail "ptype float pointer" }
+# timeout { fail "(timeout) ptype float pointer" }
+#}
+#
+#
+#send "ptype v_double_pointer\n"
+#gdb_expect {
+# -re "type = double \*.*$gdb_prompt $" { pass "ptype double pointer" }
+# -re ".*$gdb_prompt $" { fail "ptype double pointer" }
+# timeout { fail "(timeout) ptype double pointer" }
+#}
+
+#
+# test ptype command with nested structure and union
+#
+if {$hp_aCC_compiler} {
+ set outer "outer_struct::"
+ set struct ""
+ set union ""
+} else {
+ set outer ""
+ set struct "struct"
+ set union "union"
+}
+gdb_test "ptype struct outer_struct" "type = struct outer_struct \{.*\[\r\n\]+\
+.*int outer_int;.*\[\r\n\]+\
+.*(struct|) ${outer}inner_struct inner_struct_instance;.*\[\r\n\]+\
+.*(union|) ${outer}inner_union inner_union_instance;.*\[\r\n\]+\
+.*(long|long int|int) outer_long;.*\[\r\n\]\}.*" "ptype outer structure"
+
+gdb_test "ptype ${struct} ${outer}inner_struct" "type = struct ${outer}inner_struct \{.*\[\r\n\] int inner_int;.*\[\r\n\] (long|long int|int) inner_long;.*\[\r\n\]\}.*" "ptype inner structure"
+
+gdb_test "ptype ${union} ${outer}inner_union" "type = union ${outer}inner_union \{.*\[\r\n\] int inner_union_int;.*\[\r\n\] (long|long int|int) inner_union_long;.*\[\r\n\]\}.*" "ptype inner union"
+
+gdb_test "ptype nested_su" "type = struct outer_struct \{.*\[\r\n\] int outer_int;.*\[\r\n\] (struct |)${outer}inner_struct inner_struct_instance;.*\[\r\n\] (union |)${outer}inner_union inner_union_instance;.*\[\r\n\] (long|long int|int) outer_long;.*\[\r\n\]\}.*" "ptype nested structure"
+
+gdb_test "ptype nested_su.outer_int" "type = int.*" "ptype outer int"
+
+gdb_test "ptype nested_su.inner_struct_instance" "type = struct ${outer}inner_struct \{.*\[\r\n\] int inner_int;.*\[\r\n\] (long|long int|int) inner_long;.*\[\r\n\]\}.*" "ptype nested structure #2"
+
+gdb_test "ptype nested_su.inner_struct_instance.inner_int" "type = int.*" "ptype inner int"
+
+gdb_test "ptype nested_su.inner_union_instance" "type = union ${outer}inner_union \{.*\[\r\n\] int inner_union_int;.*\[\r\n\] (long|long int|int) inner_union_long;.*\[\r\n\]\}.*" "ptype nested union"
+
+
+get_debug_format
+
+# Print the type of the identifier ID, and check the response:
+# - Expect to see PROTOTYPED as the type. PROTOTYPED is not a regular
+# expression; it's a literal string.
+# - If we instead see the unprototyped type PLAIN, and we're using STABS
+# generated by GCC, that's an xfail; as of 9 Feb 2002, GCC never emits
+# prototyped function types in STABS. Like PROTOTYPED, PLAIN is a
+# literal string, not a regular expression.
+# - Otherwise, it's a failure.
+proc ptype_maybe_prototyped { id prototyped plain } {
+ global gdb_prompt
+ global gcc_compiled
+
+ # Turn `prototyped' and `plain', which are literal strings, into
+ # regular expressions by quoting any special characters they contain.
+ regsub -all "\[\]\[*()\]" $prototyped "\\\\&" prototyped
+ regsub -all "\[\]\[*()\]" $plain "\\\\&" plain
+
+ send_gdb "ptype $id\n"
+ gdb_expect {
+ -re "type = $prototyped\[\r\n\]+$gdb_prompt $" {
+ pass "ptype $id"
+ }
+ -re "type = $plain\[\r\n\]+$gdb_prompt $" {
+ if {$gcc_compiled} { setup_xfail_format "stabs" }
+ fail "ptype $id (compiler doesn't emit prototyped types)"
+ }
+ -re "$gdb_prompt $" {
+ fail "ptype $id"
+ }
+ timeout {
+ fail "ptype $id (timeout)"
+ }
+ }
+}
+
+ptype_maybe_prototyped "func_type" "int (*)(int (*)(int, float), float)" \
+ "int (*)()"
+ptype_maybe_prototyped "old_fptr" "double (*)()" "double (*)()"
+ptype_maybe_prototyped "new_fptr" "double (*)(void)" "double (*)()"
+ptype_maybe_prototyped "fptr" "int (*)(int, float)" "int (*)()"
+ptype_maybe_prototyped "fptr2" "int *(*)(int (*)(int, float), float)" \
+ "int *(*)()"
+ptype_maybe_prototyped "xptr" "int (*)(int (*)(), int (*)(void), int)" \
+ "int (*)()"
+ptype_maybe_prototyped "ffptr" "int (*(*)(char))(short int)" \
+ "int (*(*)())()"
+ptype_maybe_prototyped "fffptr" "int (*(*(*)(char))(short int))(long int)" \
+ "int (*(*(*)())())()"
+
+# Test printing type of string constants and array constants, but
+# requires a running process. These call malloc, and can take a long
+# time to execute over a slow serial link, so increase the timeout.
+
+# UDI can't do this (PR 2416). XFAIL is not suitable, because attempting
+# the operation causes a slow painful death rather than a nice simple failure.
+
+if [runto_main] then {
+
+ if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ continue
+ }
+
+ # We need to up this because this can be really slow on some boards.
+ # (malloc() is called as part of the test).
+ set timeout 60;
+
+ gdb_test "ptype \"abc\"" "type = char \\\[4\\\]"
+ gdb_test "ptype {'a','b','c'}" "type = char \\\[3\\\]"
+ gdb_test "ptype {0,1,2}" "type = int \\\[3\\\]"
+ gdb_test "ptype {(long)0,(long)1,(long)2}" "type = long \\\[3\\\]"
+ gdb_test "ptype {(float)0,(float)1,(float)2}" "type = float \\\[3\\\]"
+ gdb_test "ptype {{0,1,2},{3,4,5}}" "type = int \\\[2\\\]\\\[3\\\]"
+ gdb_test "ptype {4,5,6}\[2\]" "type = int"
+ gdb_test "ptype *&{4,5,6}\[1\]" "type = int"
+}
diff --git a/gdb/testsuite/gdb.base/radix.exp b/gdb/testsuite/gdb.base/radix.exp
new file mode 100644
index 00000000000..057751f9aab
--- /dev/null
+++ b/gdb/testsuite/gdb.base/radix.exp
@@ -0,0 +1,201 @@
+# Copyright 1993, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+proc test_input_radix_2 {} {
+ gdb_test "set radix" \
+ "Input and output radices now set to decimal 10, hex a, octal 12." \
+ "set radix #1"
+ gdb_test "set input-radix 2" \
+ "Input radix now set to decimal 2, hex 2, octal 2."
+ gdb_test "show radix" \
+ "Input radix set to decimal 2, hex 2, octal 2.\r\nOutput radix set to decimal 10, hex a, octal 12." \
+ "show radix #1"
+ gdb_test "p 010" "8"
+ gdb_test "p 20." "20"
+ gdb_test "p (int) 20." "20"
+ gdb_test "p 0xf" "15"
+ gdb_test "p 10" "2"
+ gdb_test "p -101" "-5"
+ gdb_test "p 101" "5"
+ gdb_test "p 10101" "21"
+ gdb_test "p 4" "Invalid number \"4\"\\."
+ gdb_test "p -2" "Invalid number \"2\"\\."
+}
+
+# Test input radix 3 (an non-typical radix)
+
+proc test_input_radix_3 {} {
+ gdb_test "set radix" \
+ "Input and output radices now set to decimal 10, hex a, octal 12." \
+ "set radix #2"
+ gdb_test "set input-radix 3" \
+ "Input radix now set to decimal 3, hex 3, octal 3."
+ gdb_test "show radix" \
+ "Input radix set to decimal 3, hex 3, octal 3.\r\nOutput radix set to decimal 10, hex a, octal 12." \
+ "show radix #2"
+ gdb_test "p 010" "8"
+ gdb_test "p 20." "20"
+ gdb_test "p (int) 20." "20"
+ gdb_test "p 0xf" "15"
+ gdb_test "p 10" "3"
+ gdb_test "p 0" "0"
+ gdb_test "p 1" "1"
+ gdb_test "p 2" "2"
+ gdb_test "p 10" "3"
+ gdb_test "p 20" "6"
+ gdb_test "p 100" "9"
+ gdb_test "p -100" "-9"
+ gdb_test "p 3" "Invalid number \"3\"."
+ gdb_test "p 30" "Invalid number \"30\"."
+}
+
+proc test_input_radix_8 {} {
+ gdb_test "set radix" \
+ "Input and output radices now set to decimal 10, hex a, octal 12." \
+ "set radix #3"
+ gdb_test "set input-radix 8" \
+ "Input radix now set to decimal 8, hex 8, octal 10."
+ gdb_test "show radix" \
+ "Input radix set to decimal 8, hex 8, octal 10.\r\nOutput radix set to decimal 10, hex a, octal 12." \
+ "set radix #3"
+ gdb_test "p 010" "8"
+ gdb_test "p 20." "20"
+ gdb_test "p (int) 20." "20"
+ gdb_test "p 0xf" "15"
+ gdb_test "p 10" "8"
+ gdb_test "p 20" "16"
+ gdb_test "p -20" "-16"
+ gdb_test "p 100" "64"
+ gdb_test "p 8" "Invalid number \"8\"."
+ gdb_test "p -9" "Invalid number \"9\"."
+}
+
+proc test_input_radix_10 {} {
+ gdb_test "set radix" \
+ "Input and output radices now set to decimal 10, hex a, octal 12." \
+ "set radix #4"
+ gdb_test "set input-radix 10" \
+ "Input radix now set to decimal 10, hex a, octal 12."
+ gdb_test "show radix" \
+ "Input and output radices set to decimal 10, hex a, octal 12." \
+ "show radix #4"
+ gdb_test "p 010" "8"
+ gdb_test "p 20." "20"
+ gdb_test "p (int) 20." "20"
+ gdb_test "p 0xf" "15"
+ gdb_test "p 10" "10"
+ gdb_test "p -12" "-12"
+}
+
+proc test_input_radix_16 {} {
+ gdb_test "set radix" \
+ "Input and output radices now set to decimal 10, hex a, octal 12." \
+ "set radix #5"
+ gdb_test "set input-radix 16" \
+ "Input radix now set to decimal 16, hex 10, octal 20."
+ gdb_test "show radix" \
+ "Input radix set to decimal 16, hex 10, octal 20.\r\nOutput radix set to decimal 10, hex a, octal 12." \
+ "show radix #5"
+ gdb_test "p 010" "8"
+ gdb_test "p 20." "20"
+ gdb_test "p (int) 20." "20"
+ gdb_test "p 0xf" "15"
+ gdb_test "p 10" "16"
+ gdb_test "p 100" "256"
+}
+
+proc test_output_radix_8 {} {
+ gdb_test "set radix" \
+ "Input and output radices now set to decimal 10, hex a, octal 12." \
+ "set radix #6"
+ gdb_test "set output-radix 8" \
+ "Output radix now set to decimal 8, hex 8, octal 10."
+ gdb_test "show radix" \
+ "Input radix set to decimal 10, hex a, octal 12.\r\nOutput radix set to decimal 8, hex 8, octal 10." \
+ "show radix #6"
+ gdb_test "p 010" "010"
+ # FIXME: If gdb can't handle float printing in different radices, it
+ # should at least warn once the first time that is attempted.
+ setup_xfail "*-*-*"
+ gdb_test "p 20." "24" "Float printing when output radix is 8"
+ gdb_test "p (int) 20." "24"
+ gdb_test "p 0xf" "17"
+ gdb_test "p 10" "12"
+ gdb_test "p 100" "144"
+}
+
+proc test_output_radix_10 {} {
+ gdb_test "set radix" \
+ "Input and output radices now set to decimal 10, hex a, octal 12." \
+ "set radix #7"
+ gdb_test "set output-radix 10" \
+ "Output radix now set to decimal 10, hex a, octal 12."
+ gdb_test "show radix" \
+ "Input and output radices set to decimal 10, hex a, octal 12." \
+ "show radix #7"
+ gdb_test "p 010" "8"
+ gdb_test "p 20." "20"
+ gdb_test "p (int) 20." "20"
+ gdb_test "p 0xf" "15"
+ gdb_test "p 10" "10"
+ gdb_test "p 100" "100"
+}
+
+proc test_output_radix_16 {} {
+ gdb_test "set radix" \
+ "Input and output radices now set to decimal 10, hex a, octal 12." \
+ "set radix #8"
+ gdb_test "set output-radix 16" \
+ "Output radix now set to decimal 16, hex 10, octal 20."
+ gdb_test "show radix" \
+ "Input radix set to decimal 10, hex a, octal 12.\r\nOutput radix set to decimal 16, hex 10, octal 20." \
+ "show radix #8"
+ gdb_test "p 010" "8"
+ # FIXME: If gdb can't handle float printing in different radices, it
+ # should at least warn once the first time that is attempted.
+ setup_xfail "*-*-*"
+ gdb_test "p 20." "14" "Float printing when output radix is 16"
+ gdb_test "p (int) 20." "14"
+ gdb_test "p 0xf" "f"
+ gdb_test "p 10" "a"
+ gdb_test "p 100" "64"
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+
+test_input_radix_2
+test_input_radix_3
+test_input_radix_8
+test_input_radix_10
+test_input_radix_16
+test_output_radix_8
+test_output_radix_10
+test_output_radix_16
diff --git a/gdb/testsuite/gdb.base/recurse.c b/gdb/testsuite/gdb.base/recurse.c
new file mode 100644
index 00000000000..798177888c9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/recurse.c
@@ -0,0 +1,31 @@
+/* Trivial code used to test watchpoints in recursive code and
+ auto-deletion of watchpoints as they go out of scope. */
+
+#ifdef PROTOTYPES
+static int
+recurse (int a)
+#else
+static int
+recurse (a)
+ int a;
+#endif
+{
+ int b = 0;
+
+ if (a == 1)
+ return 1;
+
+ b = a;
+ b *= recurse (a - 1);
+ return b;
+}
+
+int main()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ recurse (10);
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/recurse.exp b/gdb/testsuite/gdb.base/recurse.exp
new file mode 100644
index 00000000000..bd1ecee60d9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/recurse.exp
@@ -0,0 +1,168 @@
+# Copyright 1992, 1994, 1995, 1996, 1997, 1999, 2000
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Jeff Law. (law@cs.utah.edu)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "recurse"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+proc recurse_tests {} {
+
+ # Disable hardware watchpoints if necessary.
+ if [target_info exists gdb,no_hardware_watchpoints] {
+ gdb_test "set can-use-hw-watchpoints 0" "" ""
+ }
+
+ if [runto recurse] then {
+ # First we need to step over the assignment of b, so it has a known
+ # value.
+ gdb_test "next" "if \\(a == 1\\)" "next over b = 0 in first instance"
+ gdb_test "watch b" ".*\[Ww\]atchpoint \[0-9]*: b" \
+ "set first instance watchpoint"
+
+ # Continue until initial set of b.
+ if [gdb_test "continue" \
+ "Continuing.*\[Ww\]atchpoint.*: b.*Old value = 0.*New value = 10.*" \
+ "continue to first instance watchpoint, first time"] then {
+ gdb_suppress_tests;
+ }
+
+ # Continue inward for a few iterations
+ gdb_test "continue" "Breakpoint.* recurse \\(a=9\\).*" \
+ "continue to recurse (a = 9)"
+ gdb_test "continue" "Breakpoint.* recurse \\(a=8\\).*" \
+ "continue to recurse (a = 8)"
+ gdb_test "continue" "Breakpoint.* recurse \\(a=7\\).*" \
+ "continue to recurse (a = 7)"
+ gdb_test "continue" "Breakpoint.* recurse \\(a=6\\).*" \
+ "continue to recurse (a = 6)"
+ gdb_test "continue" "Breakpoint.* recurse \\(a=5\\).*" \
+ "continue to recurse (a = 5)"
+
+ # Put a watchpoint on another instance of b
+ # First we need to step over the assignment of b, so it has a known
+ # value.
+ gdb_test "next" "if \\(a == 1\\)" "next over b = 0 in second instance"
+ gdb_test "watch b" ".*\[Ww\]atchpoint \[0-9]*: b" \
+ "set second instance watchpoint"
+
+ # Continue until initial set of b (second instance).
+ if [gdb_test "continue" \
+ "Continuing.*\[Ww\]atchpoint.*: b.*Old value = 0.*New value = 5.*"\
+ "continue to second instance watchpoint, first time"] then {
+ gdb_suppress_tests;
+ }
+
+ # Continue inward for a few iterations
+ gdb_test "continue" "Breakpoint.* recurse \\(a=4\\).*" \
+ "continue to recurse (a = 4)"
+ gdb_test "continue" "Breakpoint.* recurse \\(a=3\\).*" \
+ "continue to recurse (a = 3)"
+ gdb_test "continue" "Breakpoint.* recurse \\(a=2\\).*" \
+ "continue to recurse (a = 2)"
+ gdb_test "continue" "Breakpoint.* recurse \\(a=1\\).*" \
+ "continue to recurse (a = 1)"
+
+ # Continue until second set of b (second instance).
+ if [gdb_test "continue" \
+ "Continuing.*\[Ww\]atchpoint.*: b.*Old value = 5.*New value = 120.*return.*" \
+ "continue to second instance watchpoint, second time"] then {
+ gdb_suppress_tests;
+ }
+
+ # Continue again. We should have a watchpoint go out of scope now
+ if [gdb_test "continue" \
+ "Continuing.*\[Ww\]atchpoint.*deleted.*recurse \\(a=6\\) .*" \
+ "second instance watchpoint deleted when leaving scope"] then {
+ gdb_suppress_tests;
+ }
+
+ # Continue until second set of b (first instance).
+ # 24320 is allowed as the final value for b as that's the value
+ # b would have on systems with 16bit integers.
+ #
+ # We could fix the test program to deal with this too.
+ if [gdb_test "continue" \
+ "Continuing.*\[Ww\]atchpoint.*b.*Old value = 10.*New value = \(3628800|24320\).*return.*" \
+ "continue to first instance watchpoint, second time"] then {
+ gdb_suppress_tests
+ }
+
+ # Continue again. We should have a watchpoint go out of scope now.
+ #
+ # The former version expected the test to return to main().
+ # Now it expects the test to return to main or to stop in the
+ # function's epilogue.
+ #
+ # The problem is that gdb needs to (but doesn't) understand
+ # function epilogues in the same way as for prologues.
+ #
+ # If there is no hardware watchpoint (such as a x86 debug register),
+ # then watchpoints are done "the hard way" by single-stepping the
+ # target until the value of the watched variable changes. If you
+ # are single-stepping, you will eventually step into an epilogue.
+ # When you do that, the "top" stack frame may become partially
+ # deconstructed (as when you pop the frame pointer, for instance),
+ # and from that point on, GDB can no longer make sense of the stack.
+ #
+ # A test which stops in the epilogue is trying to determine when GDB
+ # leaves the stack frame in which the watchpoint was created. It does
+ # this basically by watching for the frame pointer to change. When
+ # the frame pointer changes, the test expects to be back in main, but
+ # instead it is still in the epilogue of the callee.
+ if [gdb_test "continue" \
+ "Continuing.*\[Ww\]atchpoint.*deleted.*\(main \\(\\) \|21.*\}\).*" \
+ "first instance watchpoint deleted when leaving scope"] then {
+ gdb_suppress_tests;
+ }
+ }
+ gdb_stop_suppressing_tests;
+}
+
+# Preserve the old timeout, and set a new one that should be
+# sufficient to avoid timing out during this test.
+set oldtimeout $timeout
+set timeout [expr "$timeout + 60"]
+verbose "Timeout is now $timeout seconds" 2
+
+recurse_tests
+
+# Restore the preserved old timeout value.
+set timeout $oldtimeout
+verbose "Timeout is now $timeout seconds" 2
+
diff --git a/gdb/testsuite/gdb.base/regs.exp b/gdb/testsuite/gdb.base/regs.exp
new file mode 100644
index 00000000000..93ee35a989e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/regs.exp
@@ -0,0 +1,86 @@
+# Tests of register displays for GDB.
+# Copyright 1994, 1995 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Stan Shebs. (shebs@cygnus.com)
+
+# This does not (yet) have an associated executable, since the IDT board
+# will display registers even without a program being loaded.
+# A more comprehensive register test would actually test reading
+# and writing of registers in a real program, although some care
+# would be required in the writing of the tests.
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+# These tests exercise IDT-specific MIPS registers for several
+# different processor models.
+
+# This should detect the actual processor in use and change
+# the expected results appropriately. FIXME
+
+proc idt_register_tests { } {
+ # Test the generic IDT chip.
+ gdb_test "info registers" ".*"
+ gdb_test "info register zero" "zero(r0): 0x0;"
+ # FIXME access each generic register individually
+ # Test the 3041.
+ gdb_test "set processor r3041" ".*"
+ gdb_test "info registers" ".*"
+ gdb_test "info register bus" "bus.*0x.*"
+ gdb_test "info register ccfg" "ccfg.*0x.*"
+ gdb_test "info register port" "port.*0x.*"
+ gdb_test "info register cmp" "cmp.*0x.*"
+ gdb_test "info register elo" "elo: invalid register"
+ gdb_test "info register ehi" "ehi: invalid register"
+ gdb_test "info register cfg" "cfg: invalid register"
+ gdb_test "info register ctxt" "ctxt: invalid register"
+ # Test the 3051.
+ gdb_test "set processor r3051" ".*"
+ gdb_test "info registers" ".*"
+ gdb_test "info register bus" "bus: invalid register"
+ gdb_test "info register ccfg" "ccfg: invalid register"
+ gdb_test "info register port" "port: invalid register"
+ gdb_test "info register cmp" "cmp: invalid register"
+ gdb_test "info register elo" "elo.*0x.*"
+ gdb_test "info register ehi" "ehi.*0x.*"
+ gdb_test "info register cfg" "cfg: invalid register"
+ gdb_test "info register ctxt" "ctxt: invalid register"
+ # Test the 3071.
+ gdb_test "set processor r3071" ".*"
+ gdb_test "info registers" ".*"
+ gdb_test "info register bus" "bus: invalid register"
+ gdb_test "info register ccfg" "ccfg: invalid register"
+ gdb_test "info register port" "port: invalid register"
+ gdb_test "info register cmp" "cmp: invalid register"
+ gdb_test "info register elo" "elo.*0x.*"
+ gdb_test "info register ehi" "ehi.*0x.*"
+ gdb_test "info register cfg" "cfg.*0x.*"
+ gdb_test "info register ctxt" "ctxt.*0x.*"
+}
+
+if [istarget "mips*-idt-*"] then {
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ idt_register_tests
+} else {
+ verbose "regs.exp tests ignored for this target"
+}
diff --git a/gdb/testsuite/gdb.base/relational.exp b/gdb/testsuite/gdb.base/relational.exp
new file mode 100644
index 00000000000..562a6fc3dce
--- /dev/null
+++ b/gdb/testsuite/gdb.base/relational.exp
@@ -0,0 +1,484 @@
+# Copyright 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+# This file is part of the gdb testsuite
+#
+# tests for correctenss of relational operators, associativity and precedence
+# with integer type variables
+#
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "int-type"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+#
+# test expressions with "int" types
+#
+
+gdb_test "set variable x=14" "" "set variable x=14"
+gdb_test "set variable y=2" "" "set variable y=2"
+gdb_test "set variable z=2" "" "set variable z=2"
+gdb_test "set variable w=3" "" "set variable w=3"
+
+send_gdb "print x\n"
+gdb_expect {
+ -re ".*14.*$gdb_prompt $" {
+ pass "print value of x"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x" }
+ timeout { fail "(timeout) print value of x" }
+ }
+
+
+send_gdb "print y\n"
+gdb_expect {
+ -re ".*2.*$gdb_prompt $" {
+ pass "print value of y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of y" }
+ timeout { fail "(timeout) print value of y" }
+ }
+
+send_gdb "print z\n"
+gdb_expect {
+ -re ".*2.*$gdb_prompt $" {
+ pass "print value of z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of z" }
+ timeout { fail "(timeout) print value of z" }
+ }
+
+send_gdb "print w\n"
+gdb_expect {
+ -re ".*3.*$gdb_prompt $" {
+ pass "print value of w"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of w" }
+ timeout { fail "(timeout) print value of w" }
+ }
+
+
+
+send_gdb "print x < y\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x<y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<y" }
+ timeout { fail "(timeout) print value of x<y" }
+ }
+
+send_gdb "print x <= y\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x<=y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<=y" }
+ timeout { fail "(timeout) print value of x<=y" }
+ }
+
+send_gdb "print x > y\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x>y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x>y" }
+ timeout { fail "(timeout) print value of x>y" }
+ }
+
+send_gdb "print x >= y\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x>=y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x>=y" }
+ timeout { fail "(timeout) print value of x>=y" }
+ }
+
+send_gdb "print x == y\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x==y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x==y" }
+ timeout { fail "(timeout) print value of x==y" }
+ }
+
+send_gdb "print x != y\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x!=y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x!=y" }
+ timeout { fail "(timeout) print value of x!=y" }
+ }
+
+
+
+# Test associativity of <, >, <=, >=, ==, !=
+
+gdb_test "set variable x=3" "" "set variable x"
+gdb_test "set variable y=5" "" "set variable y"
+gdb_test "set variable z=2" "" "set variable z"
+
+
+
+send_gdb "print x < y < z\n"
+gdb_expect {
+ -re ".*$true.*\r\n$gdb_prompt $" {
+ pass "print value of x<y<z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<y<z" }
+ timeout { fail "(timeout) print value of x<y<z" }
+ }
+
+send_gdb "print x <= y <= z\n"
+gdb_expect {
+ -re ".*$true\r\n$gdb_prompt $" {
+ pass "print value of x<=y<=z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<=y<=z" }
+ timeout { fail "(timeout) print value of x<=y<=z" }
+ }
+
+send_gdb "print x > y > z\n"
+gdb_expect {
+ -re ".*$false.*\r\n$gdb_prompt $" {
+ pass "print value of x>y>z"
+ }
+ -re 8".*$gdb_prompt $" { fail "print value of x>y>z" }
+ timeout { fail "(timeout) print value of x>y>z" }
+ }
+
+send_gdb "print x >= y >= z\n"
+gdb_expect {
+ -re ".*$false.*\r\n$gdb_prompt $" {
+ pass "print value of x>=y>=z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x>=y>=z" }
+ timeout { fail "(timeout) print value of x>=y>=z" }
+ }
+
+gdb_test "set variable x=2" "" "set variable x"
+gdb_test "set variable y=2" "" "set variable y"
+gdb_test "set variable z=1" "" "set variable z"
+
+
+send_gdb "print x == y == z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x==y==z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x==y==z" }
+ timeout { fail "(timeout) print value of x==y==z" }
+ }
+
+gdb_test "set variable z=0" "" "set variable z"
+
+
+send_gdb "print x != y != z\n"
+gdb_expect {
+ -re ".*$false\r\n$gdb_prompt $" {
+ pass "print value of x!=y!=z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x!=y!=z" }
+ timeout { fail "(timeout) print value of x!=y!=z" }
+ }
+
+
+# test precedence rules on pairs of relational operators
+
+gdb_test "set variable x=0" "" "set variable x"
+gdb_test "set variable y=2" "" "set variable y"
+gdb_test "set variable z=2" "" "set variable z"
+
+
+send_gdb "print x < y == z\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x<y==z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<y==z" }
+ timeout { fail "(timeout) print value of x<y==z" }
+ }
+
+# 0 2 2
+send_gdb "print x < y != z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x<y!=z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<y!=z" }
+ timeout { fail "(timeout) print value of x<y!=z" }
+ }
+
+gdb_test "set variable x=2" "" "set variable x"
+gdb_test "set variable y=3" "" "set variable y"
+gdb_test "set variable z=1" "" "set variable z"
+
+
+# 2 3 1
+send_gdb "print x < y <= z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x<y<=z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<y<=z" }
+ timeout { fail "(timeout) print value of x<y<=z" }
+ }
+
+
+# 2 3 1
+send_gdb "print x < y >= z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x<y>=z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<y>=z" }
+ timeout { fail "(timeout) print value of x<y>=z" }
+ }
+
+
+gdb_test "set variable z=0" "" " set variable z"
+
+
+# 2 3 0
+send_gdb "print x < y > z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x<y>z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<y>z" }
+ timeout { fail "(timeout) print value of x<y>z" }
+ }
+
+
+gdb_test "set variable x=1" "" " set variable x"
+
+# 1 3 0
+send_gdb "print x > y >= z\n"
+gdb_expect {
+ -re ".*$true.*$gdb_prompt $" {
+ pass "print value of x>y>=z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x>y>=z" }
+ timeout { fail "(timeout) print value of x>y>=z" }
+ }
+
+
+gdb_test "set variable z=2" "" " set variable z"
+
+# 1 3 2
+send_gdb "print x > y == z\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x>y==z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x>y==z" }
+ timeout { fail "(timeout) print value of x>y==z" }
+ }
+
+
+gdb_test "set variable x=2" "" " set variable x"
+gdb_test "set variable z=0" "" " set variable z"
+
+# 2 3 0
+send_gdb "print x > y != z\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x>y!=z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x>y!=z" }
+ timeout { fail "(timeout) print value of x>y!=z" }
+ }
+
+
+gdb_test "set variable x=4" "" "set x to 4"
+
+# 4 3 0
+send_gdb "print x > y <= z\n"
+gdb_expect {
+ -re ".*$false.*$gdb_prompt $" {
+ pass "print value of x>y<=z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x>y<=z" }
+ timeout { fail "(timeout) print value of x>y<=z" }
+ }
+
+# 4 3 0
+send_gdb "print x >= y == z\n"
+gdb_expect {
+ -re ".*$false\r\n$gdb_prompt $" {
+ pass "print value of x>=y==z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x>=y==z" }
+ timeout { fail "(timeout) print value of x>=y==z" }
+ }
+
+
+gdb_test "set variable x=2" "" " set variable x"
+
+# 2 3 0
+send_gdb "print x >= y != z\n"
+gdb_expect {
+ -re ".*$false\r\n$gdb_prompt $" {
+ pass "print value of x>=y!=z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x>=y!=z" }
+ timeout { fail "(timeout) print value of x>=y!=z" }
+ }
+
+
+gdb_test "set variable x=0" "" " set variable x"
+gdb_test "set variable z=4" "" " set variable z"
+
+# 0 3 4
+send_gdb "print x >= y <= z\n"
+gdb_expect {
+ -re ".*$true\r\n$gdb_prompt $" {
+ pass "print value of x>=y<=z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x>=y<=z" }
+ timeout { fail "(timeout) print value of x>=y<=z" }
+ }
+
+# 0 3 4
+send_gdb "print x <= y == z\n"
+gdb_expect {
+ -re ".*$false\r\n$gdb_prompt $" {
+ pass "print value of x<=y==z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<=y==z" }
+ timeout { fail "(timeout) print value of x<=y==z" }
+ }
+
+gdb_test "set variable x=2" "" " set variable x"
+
+# 2 3 4
+send_gdb "print x <= y != z\n"
+gdb_expect {
+ -re ".*$true\r\n$gdb_prompt $" {
+ pass "print value of x<=y!=z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x<=y!=z" }
+ timeout { fail "(timeout) print value of x<=y!=z" }
+ }
+
+
+# 2 3 4
+send_gdb "print x == y != z\n"
+gdb_expect {
+ -re ".*$true\r\n$gdb_prompt $" {
+ pass "print value of x==y!=z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x==y!=z" }
+ timeout { fail "(timeout) print value of x==y!=z" }
+ }
+
+
+
+# test use of parenthesis to enforce different order of evaluation
+
+
+gdb_test "set variable z=0" "" " set variable z"
+
+# 2 3 0
+send_gdb "print x >= (y < z)\n"
+gdb_expect {
+ -re ".*$true\r\n$gdb_prompt $" {
+ pass "print value of x>=(y<z)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x>=(y<z)" }
+ timeout { fail "(timeout) print value of x>=(y<z)" }
+ }
+
+
+# 2 3 0
+send_gdb "print x >= (y != z)\n"
+gdb_expect {
+ -re ".*$true\r\n$gdb_prompt $" {
+ pass "print value of x>=(y!=z)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x>=(y*!=z)" }
+ timeout { fail "(timeout) print value of x>=(y!=z)" }
+ }
+
+# 2 3 0
+send_gdb "print x == (y == z)\n"
+gdb_expect {
+ -re ".*$false\r\n$gdb_prompt $" {
+ pass "print value of x==(y==z)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x==(y==z)" }
+ timeout { fail "(timeout) print value of x==(y==z)" }
+ }
+
+
+gdb_test "set variable x=1" "" " set variable x"
+gdb_test "set variable z=4" "" " set variable z"
+
+# 1 3 4
+send_gdb "print (x == y) < z\n"
+gdb_expect {
+ -re ".*$true\r\n$gdb_prompt $" {
+ pass "print value of (x==y)<z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of (x==y)<z" }
+ timeout { fail "(timeout) print value of (x==y)<z" }
+ }
+
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.base/relocate.c b/gdb/testsuite/gdb.base/relocate.c
new file mode 100644
index 00000000000..d2023920fb4
--- /dev/null
+++ b/gdb/testsuite/gdb.base/relocate.c
@@ -0,0 +1,17 @@
+static int static_foo = 1;
+static int static_bar = 2;
+
+int global_foo = 3;
+int global_bar = 4;
+
+int
+function_foo ()
+{
+ return 5;
+}
+
+int
+function_bar ()
+{
+ return 6;
+}
diff --git a/gdb/testsuite/gdb.base/relocate.exp b/gdb/testsuite/gdb.base/relocate.exp
new file mode 100644
index 00000000000..c4e25ded7ca
--- /dev/null
+++ b/gdb/testsuite/gdb.base/relocate.exp
@@ -0,0 +1,108 @@
+# Copyright 2002 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# relocate.exp -- Expect script to test loading symbols from unrelocated
+# object files.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile relocate
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}.o
+
+remote_exec build "rm -f ${binfile}"
+if { [gdb_compile "${srcfile}" "${binfile}" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+proc get_var_address { var } {
+ global gdb_prompt hex
+
+ send_gdb "print &${var}\n"
+ # Match output like:
+ # $1 = (int *) 0x0
+ # $5 = (int (*)()) 0
+ # $6 = (int (*)()) 0x24 <function_bar>
+ gdb_expect {
+ -re "\\\$\[0-9\]+ = \\(.*\\) (0|$hex)( <${var}>)?\[\r\n\]+${gdb_prompt} $"
+ {
+ pass "get address of ${var}"
+ if { $expect_out(1,string) == "0" } {
+ return "0x0"
+ } else {
+ return $expect_out(1,string)
+ }
+ }
+ -re "${gdb_prompt} $"
+ { fail "get address of ${var} (unknown output)" }
+ timeout
+ { fail "get address of ${var} (timeout)" }
+ }
+ return ""
+}
+
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# Load the object file.
+gdb_test "add-symbol-file ${binfile} 0" \
+ "Reading symbols from .*${testfile}\\.o\\.\\.\\.done\\." \
+ "add-symbol-file ${testfile}.o 0" \
+ "add symbol table from file \".*${testfile}\\.o\" at\[ \t\r\n\]+\.text_addr = 0x0\[\r\n\]+\\(y or n\\) " \
+ "y"
+
+# Print the addresses of static variables.
+set static_foo_addr [get_var_address static_foo]
+set static_bar_addr [get_var_address static_bar]
+
+# Make sure they have different addresses.
+if { "${static_foo_addr}" == "${static_bar_addr}" } {
+ fail "static variables have different addresses"
+} else {
+ pass "static variables have different addresses"
+}
+
+# Print the addresses of global variables.
+set global_foo_addr [get_var_address global_foo]
+set global_bar_addr [get_var_address global_bar]
+
+# Make sure they have different addresses.
+if { "${global_foo_addr}" == "${global_bar_addr}" } {
+ fail "global variables have different addresses"
+} else {
+ pass "global variables have different addresses"
+}
+
+# Print the addresses of functions.
+set function_foo_addr [get_var_address function_foo]
+set function_bar_addr [get_var_address function_bar]
+
+# Make sure they have different addresses.
+if { "${function_foo_addr}" == "${function_bar_addr}" } {
+ fail "functions have different addresses"
+} else {
+ pass "functions have different addresses"
+}
+
+return 0
diff --git a/gdb/testsuite/gdb.base/remote.c b/gdb/testsuite/gdb.base/remote.c
new file mode 100644
index 00000000000..a43c40bc9d8
--- /dev/null
+++ b/gdb/testsuite/gdb.base/remote.c
@@ -0,0 +1,6194 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+/**************************************************************************
+ * TESTS :
+ * -- downloading of a rather large executable
+ ***************************************************************************/
+
+
+/* A large array in .data. If RLE compression becomes available during
+ downloads, this would have to become a bunch of real random data.
+ Here's a quick way of generating such a bunch:
+
+awk < /dev/null '
+BEGIN {
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 16384; j++) {
+ printf ("%4d,", rand()*256);
+ if (j % 8 == 7) print;
+ }
+ }
+}'
+
+*/
+
+#include <limits.h>
+/* For targets with 16bit int, use a 1k buffer. */
+#if INT_MAX < 32768
+# define RANDOM_DATA_SIZE (1024)
+#else
+/* Use a character buffer to avoid byte order problems. 48k is
+ chosen so that the buffer required at least 3 16k packets but
+ targets often have no more than 64k of data. */
+/* If you change this data, you will also have to change the checks
+ for the data in remote.c */
+# define RANDOM_DATA_SIZE (3 * 2048 * 8)
+# define BIG_RANDOM_DATA
+#endif
+
+unsigned char random_data[RANDOM_DATA_SIZE] = {
+ 60, 74, 216, 38, 149, 49, 207, 44,
+ 124, 38, 93, 125, 232, 67, 228, 56,
+ 161, 146, 85, 26, 128, 145, 218, 10,
+ 27, 163, 3, 184, 26, 123, 65, 173,
+ 229, 194, 184, 232, 237, 96, 230, 199,
+ 83, 49, 254, 41, 181, 128, 239, 183,
+ 26, 53, 143, 180, 20, 130, 50, 70,
+ 163, 114, 10, 119, 19, 9, 40, 101,
+ 176, 136, 175, 69, 119, 70, 115, 239,
+ 22, 116, 242, 219, 30, 3, 60, 221,
+ 111, 197, 223, 96, 241, 204, 214, 242,
+ 150, 153, 81, 107, 231, 40, 213, 187,
+ 125, 54, 30, 12, 109, 83, 26, 109,
+ 159, 158, 199, 124, 253, 237, 164, 191,
+ 244, 132, 56, 76, 207, 1, 71, 235,
+ 94, 104, 223, 243, 253, 38, 140, 60,
+ 197, 117, 187, 50, 121, 236, 219, 242,
+ 102, 88, 51, 82, 86, 146, 111, 223,
+ 164, 132, 229, 214, 163, 121, 108, 2,
+ 155, 237, 89, 64, 105, 63, 250, 120,
+ 174, 205, 217, 70, 154, 180, 34, 194,
+ 96, 40, 165, 162, 143, 52, 243, 232,
+ 108, 165, 241, 193, 194, 10, 245, 83,
+ 188, 156, 143, 141, 179, 64, 124, 66,
+ 183, 115, 165, 30, 11, 231, 217, 63,
+ 152, 203, 30, 116, 6, 118, 85, 250,
+ 127, 100, 59, 222, 88, 196, 199, 98,
+ 80, 169, 234, 83, 146, 141, 5, 180,
+ 129, 91, 161, 60, 241, 19, 214, 54,
+ 95, 4, 167, 54, 106, 94, 70, 178,
+ 87, 73, 10, 205, 215, 205, 33, 221,
+ 122, 9, 151, 75, 139, 8, 74, 2,
+ 117, 27, 58, 69, 45, 6, 70, 222,
+ 169, 199, 60, 66, 184, 14, 8, 136,
+ 236, 39, 6, 94, 35, 234, 77, 157,
+ 70, 49, 132, 23, 164, 169, 93, 222,
+ 58, 219, 23, 9, 28, 243, 41, 137,
+ 141, 52, 107, 214, 52, 122, 45, 133,
+ 206, 217, 167, 126, 76, 110, 76, 198,
+ 208, 103, 178, 62, 70, 145, 148, 10,
+ 37, 96, 166, 211, 217, 32, 254, 168,
+ 112, 172, 238, 166, 181, 189, 70, 50,
+ 90, 96, 191, 226, 205, 26, 183, 254,
+ 47, 180, 203, 111, 24, 118, 85, 143,
+ 106, 130, 139, 168, 155, 197, 78, 220,
+ 16, 124, 82, 135, 1, 47, 181, 132,
+ 93, 4, 131, 208, 63, 139, 82, 35,
+ 138, 61, 124, 194, 84, 232, 242, 24,
+ 121, 31, 242, 204, 237, 235, 148, 4,
+ 177, 159, 70, 251, 185, 255, 50, 140,
+ 237, 172, 143, 93, 119, 47, 46, 94,
+ 18, 221, 76, 101, 219, 48, 191, 42,
+ 173, 57, 226, 126, 67, 146, 110, 127,
+ 252, 78, 213, 215, 7, 188, 64, 158,
+ 162, 38, 247, 54, 194, 20, 55, 194,
+ 0, 124, 63, 148, 124, 111, 136, 1,
+ 33, 19, 224, 205, 185, 77, 82, 3,
+ 163, 234, 230, 160, 160, 210, 95, 77,
+ 249, 137, 230, 94, 141, 188, 26, 44,
+ 9, 86, 188, 151, 200, 135, 178, 96,
+ 153, 124, 250, 62, 208, 63, 191, 187,
+ 10, 224, 184, 191, 124, 188, 90, 253,
+ 36, 27, 81, 19, 40, 95, 34, 34,
+ 159, 223, 115, 239, 95, 232, 233, 10,
+ 30, 255, 205, 134, 212, 38, 42, 205,
+ 184, 158, 63, 223, 178, 17, 94, 88,
+ 226, 201, 39, 181, 113, 139, 184, 194,
+ 24, 212, 108, 52, 188, 110, 207, 104,
+ 228, 222, 29, 238, 45, 237, 169, 180,
+ 148, 76, 12, 136, 69, 159, 157, 193,
+ 220, 45, 65, 105, 200, 235, 13, 173,
+ 140, 255, 239, 79, 55, 33, 44, 75,
+ 74, 24, 158, 115, 153, 196, 146, 74,
+ 233, 40, 8, 186, 204, 42, 131, 102,
+ 47, 87, 12, 126, 10, 194, 132, 157,
+ 114, 222, 18, 207, 62, 13, 118, 90,
+ 57, 86, 69, 114, 96, 10, 190, 82,
+ 159, 172, 53, 122, 26, 183, 120, 85,
+ 131, 196, 45, 246, 225, 239, 157, 41,
+ 41, 25, 104, 160, 193, 237, 57, 131,
+ 155, 58, 173, 71, 11, 158, 232, 209,
+ 250, 2, 188, 136, 179, 55, 157, 205,
+ 36, 49, 175, 186, 124, 1, 158, 16,
+ 239, 1, 209, 15, 28, 146, 237, 39,
+ 126, 195, 54, 150, 160, 94, 177, 81,
+ 254, 51, 173, 199, 127, 247, 77, 208,
+ 148, 194, 184, 154, 138, 39, 81, 122,
+ 147, 252, 156, 93, 75, 132, 8, 164,
+ 223, 141, 213, 224, 127, 103, 57, 51,
+ 54, 243, 123, 47, 103, 5, 210, 247,
+ 40, 216, 146, 15, 16, 175, 192, 175,
+ 177, 130, 145, 174, 65, 47, 86, 212,
+ 151, 206, 100, 5, 100, 22, 103, 102,
+ 153, 70, 14, 141, 133, 210, 162, 55,
+ 249, 178, 77, 215, 254, 80, 202, 94,
+ 90, 247, 84, 160, 37, 46, 210, 177,
+ 62, 19, 244, 115, 219, 20, 72, 126,
+ 113, 237, 29, 132, 138, 92, 83, 124,
+ 84, 231, 246, 7, 182, 119, 38, 215,
+ 90, 236, 154, 220, 11, 98, 54, 206,
+ 156, 1, 6, 107, 129, 233, 79, 232,
+ 47, 61, 202, 80, 34, 197, 252, 246,
+ 169, 246, 205, 204, 28, 231, 69, 160,
+ 151, 236, 141, 178, 224, 179, 101, 164,
+ 184, 172, 32, 252, 17, 89, 216, 73,
+ 55, 84, 217, 99, 192, 20, 144, 229,
+ 204, 194, 202, 129, 248, 30, 246, 80,
+ 61, 215, 180, 192, 34, 89, 39, 196,
+ 197, 204, 55, 185, 162, 241, 218, 9,
+ 70, 17, 97, 132, 73, 70, 60, 229,
+ 220, 170, 118, 147, 123, 193, 97, 249,
+ 230, 115, 38, 7, 187, 32, 196, 124,
+ 41, 74, 70, 87, 177, 137, 211, 10,
+ 95, 56, 156, 92, 112, 1, 230, 178,
+ 117, 63, 193, 185, 216, 206, 31, 92,
+ 52, 233, 169, 203, 36, 76, 16, 214,
+ 162, 218, 147, 53, 39, 1, 11, 81,
+ 99, 197, 73, 147, 217, 22, 252, 216,
+ 130, 249, 141, 8, 201, 43, 37, 11,
+ 127, 166, 174, 105, 138, 78, 203, 244,
+ 63, 133, 221, 143, 24, 235, 246, 85,
+ 142, 42, 135, 248, 249, 224, 146, 8,
+ 72, 9, 194, 154, 105, 137, 229, 26,
+ 3, 172, 120, 156, 232, 248, 206, 113,
+ 75, 223, 21, 60, 62, 73, 155, 254,
+ 196, 13, 161, 122, 145, 141, 102, 233,
+ 227, 112, 121, 67, 111, 148, 160, 32,
+ 199, 117, 223, 105, 184, 131, 119, 182,
+#ifdef BIG_RANDOM_DATA
+ 60, 26, 169, 194, 173, 164, 249, 135,
+ 178, 57, 50, 44, 12, 159, 167, 240,
+ 249, 188, 86, 192, 73, 47, 74, 77,
+ 250, 114, 15, 247, 240, 191, 49, 125,
+ 92, 113, 173, 235, 52, 208, 206, 146,
+ 160, 65, 188, 78, 220, 66, 44, 15,
+ 128, 250, 61, 172, 65, 225, 2, 201,
+ 62, 30, 136, 64, 195, 59, 242, 47,
+ 73, 243, 181, 99, 7, 1, 136, 59,
+ 117, 167, 211, 224, 127, 38, 22, 16,
+ 204, 35, 228, 46, 93, 168, 246, 240,
+ 99, 114, 106, 91, 26, 75, 200, 37,
+ 150, 68, 48, 101, 53, 3, 150, 55,
+ 121, 54, 132, 96, 163, 207, 223, 96,
+ 90, 152, 68, 133, 103, 105, 51, 114,
+ 144, 24, 88, 28, 87, 74, 121, 194,
+ 181, 107, 206, 214, 215, 96, 155, 17,
+ 184, 140, 108, 235, 18, 41, 58, 6,
+ 42, 14, 60, 154, 66, 56, 41, 140,
+ 255, 106, 197, 223, 43, 244, 25, 176,
+ 244, 36, 137, 190, 194, 89, 145, 11,
+ 65, 197, 38, 202, 154, 121, 218, 52,
+ 204, 17, 151, 255, 105, 156, 14, 159,
+ 183, 16, 44, 132, 206, 72, 10, 192,
+ 44, 250, 209, 168, 8, 164, 181, 110,
+ 251, 103, 83, 102, 144, 202, 208, 250,
+ 8, 69, 223, 33, 89, 130, 15, 15,
+ 121, 62, 30, 73, 62, 87, 8, 252,
+ 33, 170, 105, 44, 134, 24, 35, 100,
+ 42, 80, 27, 181, 46, 9, 61, 10,
+ 28, 179, 178, 27, 184, 198, 101, 29,
+ 46, 91, 224, 174, 246, 1, 194, 239,
+ 234, 187, 99, 108, 17, 198, 53, 48,
+ 151, 235, 81, 225, 171, 124, 119, 128,
+ 197, 164, 197, 31, 162, 177, 193, 58,
+ 120, 151, 224, 31, 119, 127, 123, 157,
+ 71, 177, 222, 101, 125, 160, 4, 47,
+ 128, 155, 80, 127, 136, 198, 208, 236,
+ 160, 83, 111, 39, 237, 83, 113, 159,
+ 250, 218, 137, 128, 130, 69, 52, 30,
+ 218, 61, 170, 187, 130, 183, 232, 128,
+ 107, 189, 159, 75, 199, 63, 191, 132,
+ 40, 238, 13, 176, 98, 35, 94, 214,
+ 110, 79, 110, 229, 100, 224, 125, 197,
+ 118, 85, 187, 56, 216, 221, 12, 140,
+ 39, 120, 247, 127, 69, 22, 3, 164,
+ 247, 102, 141, 123, 207, 64, 223, 218,
+ 181, 63, 192, 66, 136, 188, 219, 181,
+ 243, 158, 89, 220, 148, 124, 252, 104,
+ 38, 197, 17, 217, 24, 215, 92, 133,
+ 115, 129, 50, 148, 183, 21, 236, 90,
+ 169, 23, 253, 97, 65, 190, 131, 250,
+ 80, 11, 67, 28, 250, 6, 147, 187,
+ 51, 43, 170, 240, 7, 10, 174, 166,
+ 12, 153, 21, 228, 36, 4, 223, 148,
+ 212, 148, 215, 95, 28, 247, 173, 161,
+ 63, 153, 117, 10, 135, 132, 236, 18,
+ 216, 233, 194, 219, 178, 15, 148, 8,
+ 138, 188, 80, 8, 29, 10, 101, 15,
+ 38, 35, 133, 198, 133, 9, 3, 84,
+ 95, 163, 191, 185, 192, 84, 16, 67,
+ 111, 25, 10, 17, 28, 203, 113, 125,
+ 23, 44, 17, 53, 58, 25, 174, 130,
+ 22, 238, 77, 105, 97, 15, 176, 240,
+ 137, 255, 9, 145, 21, 1, 20, 237,
+ 215, 154, 117, 40, 55, 203, 212, 94,
+ 26, 107, 115, 145, 155, 1, 16, 55,
+ 91, 224, 167, 44, 53, 57, 141, 236,
+ 143, 79, 9, 202, 30, 47, 114, 226,
+ 251, 6, 24, 52, 255, 113, 239, 6,
+ 51, 68, 122, 180, 205, 123, 254, 21,
+ 3, 81, 186, 28, 44, 221, 205, 86,
+ 86, 96, 241, 6, 8, 29, 10, 226,
+ 124, 242, 26, 81, 29, 242, 80, 107,
+ 215, 75, 220, 120, 121, 137, 192, 27,
+ 251, 163, 207, 5, 62, 203, 184, 72,
+ 151, 161, 107, 138, 185, 44, 14, 10,
+ 17, 41, 93, 93, 207, 190, 196, 248,
+ 60, 183, 107, 56, 180, 179, 200, 203,
+ 28, 215, 244, 33, 254, 203, 34, 120,
+ 217, 202, 209, 217, 246, 1, 228, 96,
+ 82, 109, 190, 220, 206, 31, 139, 99,
+ 174, 138, 2, 124, 5, 198, 226, 222,
+ 129, 80, 86, 148, 96, 24, 96, 248,
+ 153, 5, 144, 74, 119, 134, 145, 162,
+ 204, 41, 135, 86, 21, 217, 210, 15,
+ 198, 49, 106, 31, 210, 155, 103, 132,
+ 92, 81, 114, 112, 59, 94, 215, 176,
+ 122, 75, 37, 28, 30, 2, 99, 182,
+ 35, 226, 191, 142, 173, 57, 156, 74,
+ 213, 215, 84, 89, 32, 2, 224, 97,
+ 178, 8, 157, 253, 22, 119, 111, 9,
+ 15, 160, 235, 98, 233, 123, 29, 233,
+ 19, 155, 242, 7, 225, 179, 195, 137,
+ 187, 38, 69, 24, 180, 27, 159, 252,
+ 77, 191, 47, 107, 201, 160, 81, 203,
+ 23, 60, 89, 119, 121, 221, 147, 182,
+ 153, 88, 230, 148, 206, 106, 181, 138,
+ 97, 182, 15, 48, 50, 19, 116, 39,
+ 48, 205, 203, 225, 88, 200, 209, 224,
+ 129, 108, 206, 184, 51, 81, 59, 79,
+ 235, 221, 229, 198, 122, 61, 199, 130,
+ 168, 238, 7, 187, 214, 118, 114, 191,
+ 126, 174, 25, 227, 132, 213, 161, 184,
+ 245, 78, 198, 63, 28, 176, 103, 0,
+ 89, 63, 212, 162, 12, 193, 76, 173,
+ 99, 115, 164, 215, 234, 95, 134, 182,
+ 132, 79, 49, 137, 82, 35, 4, 133,
+ 242, 192, 121, 173, 254, 58, 137, 116,
+ 82, 55, 254, 120, 182, 125, 0, 169,
+ 151, 159, 90, 49, 168, 26, 218, 89,
+ 7, 33, 5, 137, 95, 0, 185, 175,
+ 253, 195, 3, 32, 208, 55, 56, 145,
+ 209, 165, 71, 84, 22, 98, 16, 116,
+ 232, 140, 99, 77, 172, 51, 234, 111,
+ 190, 240, 122, 204, 239, 244, 122, 108,
+ 45, 166, 83, 82, 140, 22, 138, 220,
+ 20, 18, 138, 65, 191, 191, 104, 0,
+ 159, 250, 43, 211, 238, 201, 34, 42,
+ 76, 81, 219, 58, 59, 245, 164, 162,
+ 102, 106, 138, 91, 147, 203, 93, 46,
+ 211, 27, 111, 133, 232, 248, 108, 84,
+ 224, 67, 145, 62, 114, 92, 203, 138,
+ 122, 244, 193, 176, 165, 31, 139, 185,
+ 96, 179, 6, 146, 168, 51, 16, 36,
+ 54, 193, 2, 193, 129, 233, 234, 138,
+ 132, 176, 132, 115, 60, 95, 137, 213,
+ 39, 2, 61, 121, 110, 19, 181, 28,
+ 134, 17, 109, 0, 204, 41, 88, 43,
+ 70, 182, 60, 36, 28, 136, 221, 189,
+ 1, 147, 209, 67, 160, 107, 246, 113,
+ 102, 39, 216, 125, 157, 41, 226, 66,
+ 246, 252, 143, 56, 108, 124, 161, 215,
+ 153, 155, 93, 222, 200, 179, 61, 194,
+ 115, 248, 107, 168, 7, 145, 102, 142,
+ 145, 206, 72, 183, 202, 128, 157, 36,
+ 53, 162, 163, 112, 153, 241, 29, 100,
+ 26, 86, 122, 151, 31, 252, 186, 188,
+ 79, 33, 101, 5, 113, 103, 216, 62,
+ 102, 62, 188, 89, 130, 101, 167, 158,
+ 155, 43, 99, 208, 76, 237, 197, 94,
+ 250, 87, 54, 254, 177, 239, 177, 37,
+ 29, 137, 49, 56, 201, 48, 191, 80,
+ 31, 103, 30, 233, 106, 7, 43, 97,
+ 4, 167, 23, 177, 163, 193, 37, 64,
+ 151, 18, 169, 201, 198, 128, 60, 140,
+ 173, 18, 24, 137, 241, 201, 8, 111,
+ 173, 105, 194, 69, 171, 82, 241, 140,
+ 183, 27, 235, 56, 38, 235, 74, 68,
+ 156, 211, 209, 131, 115, 37, 74, 103,
+ 240, 34, 91, 36, 85, 20, 100, 132,
+ 235, 10, 244, 94, 102, 146, 243, 247,
+ 159, 183, 104, 12, 205, 243, 52, 203,
+ 222, 135, 81, 23, 152, 213, 97, 15,
+ 34, 58, 195, 180, 126, 135, 246, 163,
+ 13, 208, 22, 193, 20, 5, 146, 73,
+ 101, 81, 137, 175, 155, 230, 43, 200,
+ 155, 108, 240, 99, 137, 211, 59, 44,
+ 78, 169, 206, 36, 57, 158, 34, 14,
+ 24, 13, 108, 211, 101, 88, 80, 239,
+ 166, 15, 28, 234, 222, 18, 222, 188,
+ 68, 149, 173, 69, 26, 124, 139, 174,
+ 232, 172, 97, 224, 103, 94, 2, 15,
+ 224, 246, 183, 203, 209, 99, 173, 18,
+ 99, 237, 157, 57, 31, 75, 19, 174,
+ 27, 11, 111, 248, 204, 8, 52, 131,
+ 45, 251, 32, 89, 247, 25, 40, 65,
+ 78, 187, 142, 243, 76, 156, 140, 51,
+ 67, 95, 73, 39, 58, 24, 213, 25,
+ 175, 92, 161, 188, 56, 196, 115, 91,
+ 8, 105, 73, 177, 15, 17, 32, 0,
+ 247, 174, 122, 75, 174, 92, 111, 211,
+ 192, 93, 151, 182, 1, 20, 195, 222,
+ 234, 89, 82, 31, 39, 92, 223, 12,
+ 8, 41, 130, 122, 148, 188, 253, 76,
+ 7, 149, 136, 212, 113, 253, 49, 116,
+ 211, 29, 69, 127, 152, 109, 135, 54,
+ 147, 53, 241, 42, 239, 98, 189, 197,
+ 47, 120, 41, 57, 74, 107, 108, 99,
+ 17, 140, 215, 134, 226, 82, 37, 229,
+ 67, 218, 145, 147, 168, 107, 73, 51,
+ 141, 224, 255, 39, 131, 99, 112, 121,
+ 162, 37, 160, 52, 241, 238, 58, 66,
+ 215, 96, 53, 166, 164, 213, 73, 29,
+ 58, 128, 0, 152, 6, 141, 196, 87,
+ 140, 126, 168, 151, 249, 183, 125, 172,
+ 37, 79, 136, 210, 61, 170, 13, 31,
+ 171, 131, 9, 236, 62, 100, 74, 141,
+ 104, 249, 140, 52, 159, 233, 28, 170,
+ 138, 138, 178, 54, 153, 10, 132, 39,
+ 76, 237, 33, 18, 1, 60, 126, 86,
+ 182, 236, 147, 55, 13, 87, 116, 175,
+ 48, 48, 200, 206, 92, 32, 120, 4,
+ 130, 43, 194, 188, 115, 241, 158, 195,
+ 19, 155, 110, 172, 86, 99, 131, 47,
+ 178, 188, 168, 231, 75, 149, 35, 139,
+ 133, 18, 71, 231, 208, 237, 151, 34,
+ 172, 95, 149, 47, 57, 189, 229, 49,
+ 31, 64, 83, 84, 145, 16, 102, 29,
+ 9, 157, 213, 226, 57, 174, 94, 142,
+ 190, 135, 86, 178, 211, 75, 80, 210,
+ 254, 192, 125, 241, 226, 128, 68, 87,
+ 243, 97, 13, 100, 200, 75, 122, 44,
+ 233, 145, 121, 197, 91, 126, 10, 144,
+ 163, 234, 209, 162, 144, 39, 74, 247,
+ 86, 235, 26, 84, 18, 247, 41, 72,
+ 137, 220, 49, 194, 211, 57, 87, 97,
+ 254, 211, 182, 240, 158, 253, 140, 75,
+ 211, 41, 220, 175, 250, 74, 29, 27,
+ 220, 89, 74, 45, 173, 242, 73, 60,
+ 158, 171, 16, 216, 36, 158, 203, 180,
+ 70, 192, 133, 225, 96, 106, 251, 158,
+ 137, 91, 253, 141, 181, 255, 246, 77,
+ 56, 83, 167, 186, 177, 219, 36, 173,
+ 137, 187, 126, 81, 139, 226, 67, 66,
+ 22, 204, 188, 91, 88, 229, 48, 3,
+ 45, 9, 184, 179, 254, 28, 55, 20,
+ 110, 185, 230, 148, 134, 208, 12, 171,
+ 87, 103, 63, 99, 2, 206, 131, 201,
+ 138, 15, 240, 80, 187, 183, 85, 222,
+ 57, 55, 197, 122, 122, 113, 190, 246,
+ 74, 241, 172, 94, 57, 93, 11, 148,
+ 80, 206, 32, 171, 142, 210, 20, 42,
+ 247, 179, 14, 103, 77, 125, 129, 175,
+ 184, 112, 36, 34, 62, 118, 139, 249,
+ 178, 153, 45, 180, 132, 145, 60, 147,
+ 251, 58, 158, 161, 111, 242, 188, 70,
+ 86, 70, 151, 83, 10, 96, 62, 120,
+ 176, 117, 240, 106, 219, 153, 144, 218,
+ 204, 120, 214, 16, 110, 121, 14, 94,
+ 45, 77, 249, 135, 89, 109, 152, 143,
+ 67, 81, 185, 6, 132, 6, 181, 110,
+ 222, 3, 37, 100, 218, 101, 95, 18,
+ 171, 217, 141, 18, 163, 224, 116, 111,
+ 169, 72, 233, 88, 75, 7, 78, 164,
+ 235, 130, 213, 224, 64, 127, 248, 168,
+ 30, 14, 120, 83, 237, 125, 87, 35,
+ 156, 114, 131, 241, 107, 121, 216, 6,
+ 83, 76, 212, 45, 155, 51, 195, 6,
+ 88, 18, 25, 158, 165, 90, 200, 167,
+ 170, 208, 52, 15, 117, 213, 231, 147,
+ 108, 249, 12, 175, 144, 4, 115, 28,
+ 101, 78, 166, 242, 249, 72, 236, 215,
+ 90, 48, 16, 81, 208, 200, 113, 143,
+ 157, 21, 105, 87, 212, 44, 79, 235,
+ 94, 226, 211, 63, 185, 145, 151, 235,
+ 56, 12, 57, 213, 9, 204, 211, 44,
+ 63, 88, 247, 156, 247, 192, 104, 19,
+ 227, 24, 40, 157, 114, 90, 237, 89,
+ 83, 95, 15, 159, 163, 22, 51, 152,
+ 231, 142, 128, 122, 194, 175, 134, 225,
+ 18, 35, 116, 68, 13, 126, 13, 171,
+ 193, 42, 130, 86, 130, 210, 190, 28,
+ 254, 210, 18, 203, 93, 245, 224, 25,
+ 37, 95, 52, 61, 10, 222, 10, 74,
+ 163, 154, 54, 46, 238, 87, 106, 78,
+ 102, 143, 45, 159, 250, 231, 65, 149,
+ 245, 5, 164, 72, 95, 146, 43, 19,
+ 161, 33, 155, 94, 13, 148, 117, 135,
+ 171, 31, 100, 113, 240, 254, 169, 106,
+ 149, 23, 109, 240, 194, 128, 157, 156,
+ 110, 128, 75, 169, 158, 127, 152, 190,
+ 29, 82, 143, 154, 120, 131, 205, 113,
+ 11, 66, 112, 95, 183, 33, 111, 214,
+ 102, 147, 51, 45, 21, 87, 236, 226,
+ 231, 140, 212, 51, 198, 242, 5, 166,
+ 200, 99, 194, 207, 99, 217, 96, 11,
+ 43, 143, 1, 241, 239, 152, 2, 152,
+ 175, 28, 13, 207, 80, 238, 138, 248,
+ 121, 197, 110, 12, 139, 36, 226, 255,
+ 82, 226, 124, 245, 120, 70, 183, 195,
+ 5, 118, 214, 141, 175, 31, 245, 91,
+ 239, 34, 79, 100, 188, 168, 139, 114,
+ 254, 210, 6, 205, 191, 196, 107, 51,
+ 151, 89, 40, 139, 100, 197, 209, 252,
+ 140, 141, 127, 110, 7, 10, 162, 81,
+ 110, 123, 75, 156, 138, 20, 13, 134,
+ 75, 186, 199, 83, 119, 89, 89, 171,
+ 141, 10, 255, 120, 190, 118, 57, 63,
+ 182, 140, 26, 201, 232, 222, 58, 41,
+ 75, 155, 0, 188, 101, 240, 98, 97,
+ 52, 58, 7, 199, 140, 247, 42, 193,
+ 26, 66, 206, 51, 248, 202, 198, 83,
+ 224, 96, 206, 214, 224, 130, 212, 67,
+ 190, 10, 166, 48, 69, 82, 216, 36,
+ 223, 166, 249, 113, 203, 37, 208, 94,
+ 105, 105, 225, 160, 22, 80, 144, 70,
+ 210, 236, 182, 158, 124, 182, 224, 43,
+ 198, 198, 130, 231, 216, 58, 156, 208,
+ 11, 19, 218, 102, 94, 136, 74, 100,
+ 167, 117, 168, 161, 107, 50, 133, 102,
+ 198, 149, 107, 76, 206, 163, 230, 165,
+ 175, 85, 134, 203, 29, 246, 27, 250,
+ 161, 155, 13, 216, 253, 206, 45, 150,
+ 255, 225, 129, 152, 232, 121, 191, 145,
+ 126, 52, 211, 80, 7, 231, 18, 217,
+ 160, 35, 11, 227, 30, 186, 139, 150,
+ 170, 133, 235, 73, 210, 28, 129, 40,
+ 158, 71, 233, 84, 135, 13, 116, 58,
+ 208, 60, 136, 87, 250, 225, 134, 53,
+ 139, 18, 221, 251, 242, 13, 8, 170,
+ 70, 83, 43, 40, 247, 36, 187, 186,
+ 155, 29, 181, 158, 23, 214, 104, 231,
+ 28, 239, 64, 71, 46, 65, 27, 187,
+ 222, 233, 204, 235, 165, 48, 199, 113,
+ 246, 226, 44, 255, 27, 157, 198, 100,
+ 172, 149, 234, 113, 127, 243, 46, 254,
+ 58, 195, 26, 21, 246, 124, 178, 62,
+ 80, 46, 41, 27, 41, 50, 220, 34,
+ 118, 161, 202, 193, 230, 161, 91, 247,
+ 21, 202, 105, 128, 87, 192, 167, 196,
+ 179, 243, 59, 105, 171, 198, 129, 96,
+ 73, 22, 1, 167, 216, 159, 17, 8,
+ 235, 24, 23, 51, 208, 150, 251, 168,
+ 61, 40, 154, 25, 12, 58, 57, 116,
+ 55, 81, 102, 92, 217, 140, 202, 27,
+ 73, 114, 142, 184, 234, 199, 234, 96,
+ 2, 204, 142, 116, 21, 113, 105, 126,
+ 72, 177, 50, 138, 74, 242, 182, 106,
+ 94, 153, 3, 174, 116, 246, 86, 160,
+ 182, 184, 95, 55, 215, 233, 241, 221,
+ 245, 12, 64, 17, 167, 163, 75, 137,
+ 178, 76, 102, 114, 173, 231, 91, 147,
+ 228, 75, 168, 130, 14, 217, 244, 61,
+ 176, 63, 248, 226, 170, 148, 245, 247,
+ 196, 82, 198, 219, 77, 182, 52, 125,
+ 46, 97, 236, 54, 40, 222, 73, 167,
+ 64, 67, 242, 102, 93, 179, 83, 10,
+ 194, 34, 90, 49, 26, 12, 233, 222,
+ 235, 44, 61, 229, 136, 212, 94, 16,
+ 93, 195, 54, 228, 203, 39, 186, 158,
+ 234, 146, 20, 35, 252, 241, 47, 224,
+ 31, 23, 250, 165, 58, 47, 39, 235,
+ 62, 4, 224, 45, 227, 23, 148, 195,
+ 37, 17, 72, 112, 79, 153, 64, 129,
+ 197, 183, 29, 123, 46, 130, 141, 80,
+ 114, 204, 254, 25, 37, 15, 238, 217,
+ 6, 67, 40, 177, 133, 228, 245, 82,
+ 22, 76, 49, 252, 35, 222, 125, 103,
+ 250, 14, 50, 46, 31, 79, 47, 79,
+ 103, 97, 6, 65, 112, 152, 131, 193,
+ 198, 166, 212, 184, 207, 100, 40, 78,
+ 96, 168, 25, 105, 2, 66, 196, 137,
+ 64, 94, 217, 7, 138, 23, 103, 218,
+ 166, 165, 190, 227, 242, 225, 186, 192,
+ 4, 44, 221, 99, 71, 60, 143, 165,
+ 242, 36, 32, 68, 35, 160, 7, 1,
+ 16, 66, 113, 145, 224, 15, 95, 198,
+ 39, 46, 111, 224, 120, 252, 190, 132,
+ 43, 255, 183, 135, 236, 21, 100, 196,
+ 108, 133, 239, 241, 52, 248, 129, 193,
+ 31, 248, 0, 138, 162, 9, 227, 138,
+ 48, 238, 210, 197, 166, 97, 34, 38,
+ 83, 48, 148, 219, 24, 168, 78, 65,
+ 101, 133, 202, 237, 141, 149, 151, 168,
+ 235, 92, 238, 206, 222, 61, 3, 43,
+ 90, 202, 171, 35, 32, 222, 98, 142,
+ 141, 69, 205, 186, 207, 52, 248, 100,
+ 234, 217, 203, 255, 248, 121, 59, 90,
+ 83, 84, 222, 129, 138, 110, 249, 42,
+ 24, 235, 177, 87, 185, 219, 2, 85,
+ 133, 25, 245, 14, 182, 5, 70, 171,
+ 49, 252, 233, 119, 13, 165, 77, 57,
+ 150, 132, 83, 50, 112, 115, 159, 250,
+ 196, 111, 147, 179, 145, 244, 130, 16,
+ 86, 35, 222, 173, 226, 218, 63, 41,
+ 3, 207, 207, 199, 64, 124, 214, 42,
+ 126, 93, 222, 105, 216, 210, 252, 21,
+ 0, 177, 9, 194, 157, 160, 245, 122,
+ 148, 138, 152, 79, 84, 154, 70, 119,
+ 115, 93, 213, 226, 136, 214, 15, 165,
+ 42, 125, 175, 31, 147, 51, 45, 242,
+ 97, 245, 168, 58, 47, 177, 194, 24,
+ 59, 25, 199, 169, 132, 195, 236, 240,
+ 191, 142, 86, 151, 19, 233, 20, 147,
+ 240, 207, 56, 17, 227, 224, 245, 246,
+ 167, 177, 115, 17, 177, 166, 33, 182,
+ 64, 217, 40, 125, 24, 94, 214, 73,
+ 167, 125, 96, 232, 190, 205, 115, 157,
+ 26, 202, 234, 125, 176, 222, 208, 50,
+ 39, 208, 11, 58, 236, 174, 198, 2,
+ 28, 227, 141, 17, 212, 193, 178, 114,
+ 1, 87, 238, 1, 235, 255, 146, 131,
+ 82, 139, 156, 128, 96, 85, 75, 243,
+ 165, 24, 42, 220, 131, 165, 91, 156,
+ 118, 159, 28, 52, 147, 105, 179, 91,
+ 216, 56, 32, 222, 172, 31, 188, 215,
+ 161, 139, 9, 186, 152, 105, 155, 195,
+ 147, 159, 217, 198, 116, 58, 61, 89,
+ 60, 202, 220, 176, 114, 36, 150, 151,
+ 239, 221, 223, 202, 202, 93, 225, 51,
+ 191, 92, 220, 60, 146, 222, 210, 119,
+ 144, 187, 151, 26, 192, 27, 184, 46,
+ 206, 234, 31, 179, 28, 208, 43, 3,
+ 59, 92, 58, 231, 7, 196, 155, 61,
+ 201, 211, 141, 38, 143, 43, 238, 129,
+ 33, 250, 192, 53, 112, 173, 6, 67,
+ 13, 234, 154, 13, 50, 201, 97, 80,
+ 45, 13, 215, 162, 255, 224, 20, 211,
+ 47, 12, 73, 220, 186, 141, 5, 149,
+ 81, 232, 3, 195, 223, 152, 199, 149,
+ 128, 160, 83, 112, 64, 107, 110, 170,
+ 6, 65, 41, 48, 244, 144, 206, 151,
+ 106, 248, 31, 174, 217, 199, 73, 107,
+ 101, 38, 92, 204, 121, 127, 195, 209,
+ 187, 86, 99, 150, 95, 192, 16, 62,
+ 75, 35, 197, 197, 166, 187, 143, 191,
+ 203, 20, 240, 171, 56, 62, 212, 37,
+ 14, 17, 213, 181, 78, 21, 171, 44,
+ 204, 32, 144, 208, 60, 171, 85, 92,
+ 157, 198, 247, 235, 124, 74, 225, 76,
+ 69, 100, 19, 237, 181, 255, 106, 208,
+ 247, 83, 31, 152, 24, 220, 173, 104,
+ 191, 35, 185, 24, 216, 233, 39, 115,
+ 151, 93, 35, 201, 133, 20, 211, 159,
+ 180, 164, 80, 137, 199, 155, 192, 207,
+ 224, 182, 108, 186, 208, 123, 167, 116,
+ 148, 36, 245, 50, 221, 51, 143, 45,
+ 244, 235, 215, 84, 158, 128, 205, 19,
+ 119, 139, 121, 46, 46, 152, 104, 95,
+ 178, 210, 107, 132, 96, 14, 118, 54,
+ 89, 18, 42, 3, 236, 20, 136, 32,
+ 125, 160, 106, 239, 4, 216, 119, 43,
+ 208, 33, 170, 114, 13, 206, 157, 126,
+ 53, 161, 91, 43, 167, 78, 195, 87,
+ 124, 114, 164, 130, 181, 69, 114, 103,
+ 83, 43, 127, 30, 158, 108, 127, 247,
+ 130, 252, 42, 88, 241, 89, 185, 108,
+ 63, 170, 46, 143, 157, 20, 74, 164,
+ 182, 225, 228, 209, 230, 111, 143, 12,
+ 173, 23, 7, 12, 228, 92, 136, 89,
+ 122, 37, 151, 165, 115, 17, 144, 197,
+ 102, 194, 238, 149, 228, 167, 255, 124,
+ 238, 147, 21, 203, 16, 131, 235, 62,
+ 106, 233, 8, 166, 18, 145, 137, 11,
+ 7, 50, 139, 124, 214, 144, 253, 60,
+ 231, 22, 165, 67, 87, 162, 70, 253,
+ 222, 195, 149, 124, 235, 122, 135, 53,
+ 77, 84, 97, 70, 163, 43, 133, 255,
+ 37, 188, 97, 213, 231, 119, 61, 164,
+ 103, 85, 235, 207, 119, 118, 242, 225,
+ 116, 138, 85, 102, 234, 213, 20, 126,
+ 104, 112, 23, 42, 188, 69, 81, 89,
+ 139, 22, 147, 106, 250, 247, 52, 27,
+ 49, 215, 26, 114, 21, 92, 89, 56,
+ 251, 145, 13, 248, 115, 251, 48, 125,
+ 210, 51, 122, 29, 73, 206, 206, 243,
+ 176, 18, 231, 207, 71, 132, 41, 144,
+ 229, 208, 160, 24, 142, 129, 99, 216,
+ 98, 184, 30, 8, 222, 242, 113, 218,
+ 74, 98, 140, 72, 141, 223, 56, 195,
+ 218, 110, 216, 211, 202, 255, 26, 76,
+ 35, 62, 176, 198, 34, 123, 179, 175,
+ 64, 78, 71, 186, 182, 230, 100, 54,
+ 106, 229, 2, 76, 26, 233, 221, 141,
+ 160, 135, 87, 158, 35, 76, 220, 194,
+ 146, 51, 75, 218, 92, 191, 151, 250,
+ 178, 209, 218, 184, 171, 29, 247, 65,
+ 164, 48, 121, 7, 230, 30, 226, 189,
+ 43, 4, 215, 162, 161, 188, 8, 44,
+ 106, 27, 226, 4, 127, 51, 227, 36,
+ 114, 185, 116, 42, 17, 117, 172, 23,
+ 252, 255, 75, 102, 79, 45, 187, 91,
+ 227, 58, 216, 252, 72, 36, 230, 121,
+ 173, 248, 211, 47, 239, 135, 129, 52,
+ 5, 223, 152, 67, 96, 88, 153, 62,
+ 111, 232, 240, 214, 245, 216, 149, 193,
+ 197, 156, 63, 225, 157, 166, 211, 62,
+ 90, 60, 64, 192, 244, 215, 251, 110,
+ 39, 155, 198, 215, 77, 250, 18, 15,
+ 14, 90, 193, 17, 62, 249, 84, 55,
+ 114, 75, 71, 143, 180, 154, 20, 193,
+ 186, 141, 189, 172, 52, 181, 233, 239,
+ 207, 103, 171, 12, 100, 254, 60, 171,
+ 148, 132, 91, 80, 40, 189, 127, 68,
+ 225, 33, 2, 160, 70, 26, 88, 178,
+ 239, 47, 240, 228, 188, 184, 38, 77,
+ 233, 175, 135, 212, 207, 225, 240, 255,
+ 90, 27, 45, 107, 101, 186, 241, 100,
+ 175, 246, 133, 57, 212, 232, 169, 100,
+ 241, 174, 91, 143, 69, 47, 30, 237,
+ 85, 0, 13, 113, 111, 172, 87, 235,
+ 112, 203, 27, 68, 2, 129, 197, 167,
+ 200, 202, 107, 178, 204, 37, 215, 199,
+ 246, 231, 203, 136, 64, 102, 180, 157,
+ 77, 212, 169, 120, 89, 74, 73, 164,
+ 192, 237, 88, 189, 120, 105, 205, 125,
+ 115, 248, 50, 6, 239, 153, 253, 238,
+ 157, 249, 136, 206, 253, 28, 10, 95,
+ 96, 109, 222, 78, 250, 81, 61, 173,
+ 120, 148, 216, 218, 92, 34, 201, 146,
+ 93, 200, 122, 70, 107, 67, 10, 1,
+ 232, 180, 61, 125, 228, 152, 54, 132,
+ 88, 1, 122, 211, 30, 103, 12, 204,
+ 185, 18, 207, 71, 177, 127, 252, 112,
+ 104, 155, 162, 145, 42, 39, 22, 180,
+ 173, 53, 3, 1, 29, 39, 135, 231,
+ 85, 51, 129, 124, 205, 11, 185, 50,
+ 198, 159, 122, 214, 249, 195, 85, 179,
+ 123, 246, 61, 169, 237, 248, 250, 227,
+ 151, 213, 82, 54, 207, 6, 138, 227,
+ 229, 95, 51, 81, 185, 197, 146, 75,
+ 93, 45, 117, 39, 167, 164, 20, 125,
+ 24, 186, 76, 118, 158, 180, 104, 21,
+ 75, 79, 81, 111, 150, 30, 6, 91,
+ 142, 16, 140, 90, 102, 31, 82, 24,
+ 184, 51, 9, 3, 198, 27, 206, 74,
+ 65, 126, 40, 21, 13, 7, 235, 131,
+ 88, 170, 225, 177, 183, 66, 38, 11,
+ 107, 158, 240, 169, 111, 1, 76, 170,
+ 215, 76, 116, 27, 191, 211, 81, 105,
+ 36, 112, 231, 133, 58, 162, 184, 4,
+ 84, 165, 20, 171, 201, 207, 43, 186,
+ 202, 87, 178, 24, 56, 138, 163, 92,
+ 143, 153, 156, 98, 126, 77, 152, 217,
+ 88, 128, 149, 163, 171, 150, 25, 113,
+ 28, 253, 174, 102, 169, 207, 219, 70,
+ 229, 213, 127, 238, 240, 60, 230, 190,
+ 11, 127, 155, 90, 46, 127, 233, 13,
+ 126, 101, 234, 36, 199, 128, 132, 217,
+ 126, 147, 62, 8, 216, 3, 189, 136,
+ 224, 147, 172, 228, 111, 19, 111, 254,
+ 152, 52, 150, 21, 98, 250, 212, 44,
+ 172, 65, 229, 144, 38, 63, 177, 205,
+ 202, 121, 224, 138, 89, 53, 124, 98,
+ 55, 183, 165, 149, 210, 185, 120, 131,
+ 3, 159, 249, 40, 168, 145, 159, 30,
+ 131, 110, 147, 90, 219, 96, 57, 184,
+ 75, 138, 147, 108, 112, 45, 182, 151,
+ 42, 214, 187, 43, 62, 173, 172, 68,
+ 120, 15, 37, 135, 130, 86, 130, 46,
+ 112, 85, 230, 12, 76, 254, 203, 150,
+ 16, 240, 122, 212, 10, 134, 232, 32,
+ 215, 125, 19, 230, 159, 24, 156, 159,
+ 62, 56, 97, 9, 155, 59, 89, 221,
+ 76, 223, 58, 21, 118, 175, 104, 180,
+ 62, 210, 62, 174, 220, 147, 42, 85,
+ 43, 231, 18, 80, 254, 171, 239, 104,
+ 120, 157, 37, 167, 254, 128, 175, 32,
+ 118, 92, 105, 182, 180, 127, 22, 38,
+ 23, 146, 102, 113, 247, 224, 0, 216,
+ 86, 105, 80, 240, 8, 164, 68, 131,
+ 188, 29, 39, 195, 254, 88, 54, 130,
+ 97, 156, 178, 40, 216, 64, 244, 51,
+ 5, 68, 243, 208, 99, 142, 227, 15,
+ 246, 8, 89, 87, 2, 242, 90, 211,
+ 113, 150, 62, 60, 189, 109, 141, 3,
+ 96, 201, 127, 51, 179, 201, 239, 6,
+ 152, 255, 112, 104, 72, 73, 34, 120,
+ 226, 50, 34, 43, 207, 20, 151, 84,
+ 114, 153, 92, 91, 180, 234, 108, 206,
+ 106, 28, 68, 28, 93, 81, 133, 139,
+ 207, 195, 147, 246, 132, 104, 119, 110,
+ 118, 208, 39, 42, 28, 119, 75, 188,
+ 82, 144, 205, 138, 247, 132, 136, 232,
+ 177, 49, 100, 23, 224, 208, 215, 112,
+ 112, 225, 73, 146, 220, 254, 119, 90,
+ 140, 175, 218, 170, 191, 87, 171, 29,
+ 183, 20, 112, 36, 14, 123, 73, 180,
+ 208, 21, 50, 143, 225, 102, 242, 193,
+ 132, 23, 14, 147, 251, 115, 225, 88,
+ 40, 80, 122, 151, 15, 90, 22, 105,
+ 250, 199, 81, 73, 206, 86, 63, 241,
+ 34, 134, 158, 127, 79, 39, 151, 7,
+ 232, 50, 196, 161, 160, 24, 114, 255,
+ 174, 137, 52, 244, 75, 246, 20, 203,
+ 224, 80, 116, 130, 254, 71, 251, 204,
+ 226, 20, 164, 134, 237, 223, 160, 37,
+ 61, 76, 223, 219, 79, 48, 137, 178,
+ 2, 125, 21, 36, 127, 149, 255, 249,
+ 192, 18, 92, 42, 129, 192, 177, 212,
+ 90, 249, 120, 200, 239, 135, 143, 119,
+ 170, 110, 16, 176, 200, 59, 58, 233,
+ 115, 168, 156, 231, 222, 242, 190, 158,
+ 238, 98, 229, 227, 43, 39, 243, 213,
+ 234, 142, 20, 1, 225, 130, 167, 229,
+ 49, 17, 237, 60, 109, 246, 168, 171,
+ 40, 61, 98, 225, 119, 118, 112, 49,
+ 68, 160, 203, 76, 13, 191, 147, 238,
+ 231, 95, 40, 24, 159, 46, 166, 80,
+ 191, 207, 128, 73, 132, 190, 167, 27,
+ 195, 95, 70, 36, 23, 214, 116, 99,
+ 197, 171, 143, 186, 226, 214, 171, 150,
+ 36, 57, 59, 28, 158, 70, 44, 93,
+ 111, 92, 153, 6, 253, 166, 82, 123,
+ 184, 27, 252, 116, 235, 91, 141, 209,
+ 114, 61, 138, 151, 86, 234, 216, 191,
+ 31, 71, 96, 255, 46, 212, 36, 227,
+ 179, 51, 124, 1, 191, 103, 130, 69,
+ 164, 235, 16, 40, 254, 114, 213, 155,
+ 71, 214, 145, 115, 73, 245, 139, 176,
+ 234, 37, 66, 224, 39, 83, 177, 32,
+ 125, 23, 30, 27, 194, 21, 144, 73,
+ 100, 97, 213, 193, 29, 170, 124, 238,
+ 44, 182, 78, 165, 143, 103, 39, 71,
+ 143, 239, 238, 28, 241, 22, 249, 173,
+ 225, 94, 95, 31, 134, 9, 78, 243,
+ 223, 239, 23, 21, 136, 93, 249, 64,
+ 22, 168, 28, 101, 91, 231, 151, 129,
+ 167, 233, 202, 241, 68, 246, 22, 148,
+ 171, 201, 229, 168, 189, 77, 151, 251,
+ 92, 50, 244, 17, 188, 56, 39, 83,
+ 9, 87, 252, 140, 244, 27, 99, 242,
+ 225, 208, 237, 222, 244, 238, 156, 125,
+ 219, 59, 90, 225, 234, 57, 45, 12,
+ 252, 19, 41, 177, 15, 9, 73, 96,
+ 9, 37, 139, 230, 205, 101, 230, 141,
+ 118, 64, 50, 119, 109, 132, 24, 196,
+ 141, 115, 28, 217, 39, 190, 186, 23,
+ 74, 62, 79, 11, 68, 107, 190, 200,
+ 32, 29, 169, 157, 185, 29, 15, 240,
+ 193, 174, 140, 129, 112, 12, 137, 101,
+ 160, 250, 220, 198, 0, 45, 57, 54,
+ 73, 115, 37, 52, 61, 135, 232, 241,
+ 22, 161, 136, 86, 187, 162, 47, 166,
+ 231, 25, 144, 254, 130, 154, 95, 237,
+ 96, 124, 86, 126, 60, 247, 14, 88,
+ 150, 230, 242, 54, 162, 96, 41, 73,
+ 102, 15, 173, 103, 132, 148, 133, 70,
+ 244, 129, 3, 115, 127, 8, 109, 14,
+ 8, 228, 171, 171, 217, 19, 73, 147,
+ 6, 43, 96, 158, 37, 14, 255, 22,
+ 184, 65, 151, 82, 244, 36, 203, 178,
+ 204, 93, 91, 221, 120, 215, 196, 37,
+ 162, 248, 119, 180, 171, 185, 17, 168,
+ 143, 129, 184, 90, 187, 228, 46, 148,
+ 164, 82, 185, 62, 210, 87, 158, 146,
+ 20, 23, 139, 10, 19, 129, 143, 152,
+ 125, 40, 212, 174, 193, 10, 157, 163,
+ 207, 47, 205, 243, 1, 0, 23, 207,
+ 16, 168, 250, 239, 20, 223, 146, 94,
+ 187, 23, 245, 109, 69, 10, 47, 210,
+ 203, 66, 246, 161, 90, 108, 21, 164,
+ 38, 222, 57, 245, 218, 8, 156, 65,
+ 147, 77, 139, 94, 182, 84, 231, 252,
+ 20, 159, 169, 188, 62, 205, 101, 226,
+ 11, 224, 142, 79, 90, 248, 156, 107,
+ 154, 103, 90, 92, 92, 116, 67, 84,
+ 252, 247, 230, 251, 218, 108, 203, 134,
+ 158, 147, 0, 70, 81, 128, 83, 30,
+ 96, 86, 247, 82, 191, 212, 120, 158,
+ 125, 183, 172, 134, 143, 44, 109, 0,
+ 77, 217, 55, 238, 66, 42, 38, 59,
+ 218, 132, 65, 127, 76, 178, 148, 160,
+ 129, 15, 95, 186, 178, 78, 185, 84,
+ 188, 22, 114, 207, 67, 135, 219, 215,
+ 206, 181, 177, 140, 249, 196, 75, 233,
+ 124, 125, 196, 21, 150, 233, 7, 104,
+ 190, 182, 8, 200, 156, 20, 179, 48,
+ 232, 148, 27, 170, 215, 68, 68, 146,
+ 107, 163, 146, 213, 255, 38, 97, 60,
+ 192, 1, 128, 204, 127, 20, 180, 53,
+ 69, 165, 95, 18, 96, 26, 110, 42,
+ 65, 180, 132, 200, 79, 43, 2, 209,
+ 135, 56, 197, 190, 130, 206, 184, 53,
+ 178, 119, 140, 35, 13, 20, 124, 59,
+ 241, 250, 194, 95, 115, 39, 88, 64,
+ 213, 240, 155, 114, 183, 252, 142, 250,
+ 158, 48, 5, 5, 44, 141, 201, 138,
+ 139, 11, 216, 87, 108, 32, 86, 156,
+ 65, 161, 179, 20, 46, 157, 200, 9,
+ 190, 67, 11, 91, 134, 137, 91, 227,
+ 28, 225, 159, 34, 240, 169, 222, 145,
+ 8, 149, 185, 198, 218, 87, 147, 133,
+ 127, 66, 161, 21, 60, 149, 213, 170,
+ 155, 54, 169, 97, 93, 236, 230, 133,
+ 182, 187, 193, 237, 122, 68, 207, 90,
+ 102, 63, 151, 3, 36, 122, 23, 89,
+ 250, 174, 194, 241, 142, 86, 96, 31,
+ 98, 110, 201, 79, 217, 52, 23, 51,
+ 20, 180, 214, 199, 113, 79, 224, 233,
+ 126, 55, 253, 216, 48, 195, 72, 200,
+ 11, 172, 194, 255, 148, 105, 20, 175,
+ 230, 144, 241, 78, 58, 33, 167, 93,
+ 24, 217, 199, 66, 134, 86, 176, 23,
+ 86, 237, 241, 21, 144, 167, 1, 252,
+ 170, 108, 94, 236, 67, 164, 195, 38,
+ 148, 93, 173, 135, 187, 211, 6, 27,
+ 208, 167, 111, 224, 47, 15, 248, 119,
+ 175, 173, 133, 182, 121, 194, 138, 149,
+ 66, 5, 4, 152, 2, 23, 198, 173,
+ 61, 47, 126, 185, 218, 129, 223, 247,
+ 209, 153, 219, 98, 184, 104, 127, 214,
+ 196, 181, 203, 91, 3, 4, 0, 171,
+ 24, 118, 99, 166, 74, 14, 52, 200,
+ 38, 212, 91, 22, 234, 241, 12, 221,
+ 132, 243, 211, 2, 18, 11, 130, 49,
+ 223, 100, 27, 148, 87, 225, 119, 186,
+ 191, 195, 92, 95, 118, 60, 234, 40,
+ 87, 213, 143, 105, 235, 202, 194, 148,
+ 45, 9, 107, 35, 139, 11, 226, 166,
+ 92, 39, 131, 135, 140, 141, 56, 80,
+ 199, 42, 208, 27, 41, 94, 39, 77,
+ 33, 125, 148, 126, 111, 124, 89, 221,
+ 208, 164, 167, 185, 196, 71, 121, 88,
+ 189, 216, 109, 196, 166, 29, 216, 151,
+ 90, 183, 22, 140, 201, 179, 219, 51,
+ 9, 152, 2, 237, 184, 123, 16, 62,
+ 71, 178, 213, 97, 109, 79, 246, 82,
+ 122, 253, 132, 16, 157, 213, 38, 237,
+ 24, 233, 4, 46, 140, 179, 1, 35,
+ 160, 52, 179, 34, 159, 248, 214, 167,
+ 75, 242, 172, 113, 184, 50, 139, 73,
+ 33, 143, 83, 250, 23, 239, 135, 226,
+ 153, 175, 60, 5, 184, 148, 199, 208,
+ 105, 107, 89, 17, 141, 157, 219, 34,
+ 213, 170, 12, 121, 200, 190, 17, 139,
+ 136, 13, 29, 187, 145, 184, 165, 190,
+ 167, 171, 218, 103, 26, 28, 63, 224,
+ 21, 200, 234, 138, 130, 88, 255, 74,
+ 61, 233, 91, 19, 70, 210, 27, 61,
+ 204, 32, 26, 50, 34, 169, 139, 37,
+ 212, 16, 22, 206, 99, 42, 251, 100,
+ 208, 41, 58, 200, 101, 65, 100, 57,
+ 228, 240, 105, 49, 240, 1, 141, 21,
+ 35, 65, 252, 142, 70, 235, 169, 81,
+ 252, 215, 62, 88, 117, 180, 148, 169,
+ 114, 93, 231, 105, 194, 193, 12, 74,
+ 52, 143, 163, 233, 188, 215, 20, 225,
+ 2, 28, 79, 113, 27, 166, 204, 160,
+ 177, 199, 150, 249, 36, 31, 132, 84,
+ 125, 184, 128, 230, 39, 139, 197, 169,
+ 153, 2, 52, 37, 39, 180, 202, 237,
+ 46, 43, 185, 255, 235, 149, 230, 227,
+ 186, 248, 81, 198, 122, 15, 185, 44,
+ 137, 112, 218, 156, 94, 107, 181, 233,
+ 121, 28, 6, 194, 153, 174, 144, 146,
+ 174, 253, 111, 138, 49, 253, 158, 80,
+ 23, 174, 167, 203, 235, 112, 196, 66,
+ 251, 123, 97, 137, 21, 218, 131, 28,
+ 31, 83, 121, 160, 84, 31, 13, 60,
+ 103, 33, 32, 12, 161, 136, 107, 38,
+ 30, 111, 53, 176, 192, 122, 166, 47,
+ 160, 122, 22, 117, 224, 150, 128, 249,
+ 21, 27, 222, 119, 38, 182, 73, 248,
+ 246, 101, 240, 33, 30, 189, 13, 37,
+ 211, 123, 70, 50, 163, 104, 170, 166,
+ 33, 131, 13, 34, 252, 127, 156, 187,
+ 14, 135, 40, 125, 156, 169, 229, 77,
+ 110, 143, 155, 61, 198, 49, 87, 118,
+ 229, 27, 204, 141, 7, 174, 222, 126,
+ 248, 15, 132, 101, 251, 123, 117, 138,
+ 166, 132, 252, 35, 218, 35, 27, 17,
+ 119, 103, 136, 167, 101, 114, 151, 106,
+ 229, 44, 95, 2, 106, 21, 187, 221,
+ 97, 110, 144, 140, 12, 168, 99, 114,
+ 250, 34, 159, 60, 229, 203, 25, 135,
+ 23, 179, 240, 182, 232, 64, 182, 156,
+ 183, 132, 17, 25, 199, 165, 36, 28,
+ 44, 177, 23, 18, 142, 4, 142, 53,
+ 186, 182, 218, 180, 215, 243, 5, 124,
+ 227, 108, 20, 121, 235, 131, 237, 211,
+ 0, 95, 97, 204, 225, 156, 122, 219,
+ 73, 217, 102, 114, 27, 126, 241, 235,
+ 14, 173, 234, 208, 155, 181, 60, 84,
+ 7, 247, 174, 151, 215, 141, 41, 225,
+ 101, 119, 145, 89, 255, 35, 64, 108,
+ 30, 53, 72, 215, 219, 106, 160, 90,
+ 17, 235, 159, 119, 107, 112, 236, 208,
+ 61, 81, 203, 182, 58, 39, 251, 251,
+ 90, 188, 137, 106, 7, 129, 92, 166,
+ 127, 230, 89, 116, 243, 228, 208, 222,
+ 140, 118, 71, 226, 152, 213, 41, 48,
+ 40, 215, 110, 69, 211, 252, 222, 68,
+ 187, 77, 166, 165, 201, 9, 118, 149,
+ 203, 19, 235, 199, 50, 210, 44, 62,
+ 41, 201, 65, 173, 29, 10, 219, 24,
+ 106, 53, 235, 37, 77, 73, 68, 159,
+ 92, 229, 80, 87, 217, 53, 219, 91,
+ 66, 155, 16, 3, 232, 184, 151, 36,
+ 155, 226, 197, 93, 50, 91, 140, 180,
+ 140, 250, 63, 18, 15, 237, 49, 237,
+ 58, 225, 135, 81, 90, 209, 103, 50,
+ 70, 49, 248, 42, 253, 42, 104, 146,
+ 92, 157, 75, 104, 115, 78, 102, 209,
+ 6, 242, 24, 101, 175, 243, 147, 239,
+ 213, 37, 124, 85, 139, 103, 195, 5,
+ 161, 177, 180, 157, 86, 237, 18, 173,
+ 143, 84, 177, 228, 63, 203, 128, 12,
+ 7, 71, 90, 105, 87, 137, 118, 177,
+ 147, 27, 108, 199, 152, 0, 50, 120,
+ 170, 163, 206, 203, 245, 94, 240, 76,
+ 234, 53, 158, 17, 95, 198, 151, 157,
+ 144, 168, 14, 189, 176, 68, 52, 9,
+ 46, 171, 1, 141, 245, 184, 190, 95,
+ 16, 197, 99, 185, 167, 185, 102, 245,
+ 74, 252, 224, 32, 236, 108, 121, 129,
+ 200, 34, 140, 228, 109, 228, 150, 41,
+ 68, 177, 120, 17, 17, 68, 188, 103,
+ 10, 216, 164, 154, 248, 232, 53, 31,
+ 85, 243, 4, 100, 43, 195, 96, 240,
+ 153, 167, 100, 21, 89, 141, 151, 197,
+ 113, 114, 0, 245, 173, 108, 203, 220,
+ 162, 5, 191, 102, 31, 133, 123, 198,
+ 194, 163, 195, 175, 28, 150, 23, 224,
+ 2, 143, 115, 225, 197, 91, 133, 202,
+ 123, 244, 5, 23, 91, 24, 127, 138,
+ 99, 7, 161, 153, 130, 183, 214, 43,
+ 30, 35, 136, 179, 118, 215, 200, 97,
+ 8, 108, 129, 219, 105, 0, 198, 55,
+ 170, 170, 159, 77, 185, 133, 98, 4,
+ 10, 202, 48, 79, 213, 80, 23, 217,
+ 124, 64, 239, 12, 162, 186, 154, 157,
+ 44, 160, 129, 70, 162, 40, 242, 110,
+ 99, 104, 127, 219, 243, 114, 253, 96,
+ 103, 9, 162, 36, 219, 178, 222, 253,
+ 32, 168, 91, 210, 169, 113, 210, 219,
+ 71, 201, 164, 13, 13, 212, 11, 181,
+ 95, 255, 76, 5, 139, 237, 242, 253,
+ 199, 247, 71, 28, 109, 132, 94, 219,
+ 27, 10, 22, 185, 115, 13, 170, 215,
+ 119, 249, 64, 226, 11, 254, 109, 208,
+ 56, 184, 147, 134, 249, 246, 86, 190,
+ 199, 106, 143, 107, 29, 251, 248, 25,
+ 194, 30, 240, 153, 11, 222, 185, 1,
+ 202, 111, 125, 138, 95, 106, 32, 128,
+ 127, 203, 209, 93, 74, 60, 57, 1,
+ 248, 64, 92, 202, 79, 173, 136, 163,
+ 174, 197, 126, 241, 254, 169, 128, 248,
+ 241, 49, 20, 31, 29, 139, 91, 147,
+ 76, 223, 102, 96, 87, 173, 108, 51,
+ 158, 45, 152, 182, 178, 170, 196, 134,
+ 165, 149, 47, 59, 25, 211, 212, 159,
+ 14, 139, 22, 117, 224, 0, 128, 0,
+ 203, 157, 250, 69, 129, 187, 189, 181,
+ 246, 83, 29, 109, 26, 163, 71, 246,
+ 187, 58, 43, 42, 211, 84, 76, 62,
+ 112, 132, 164, 194, 77, 168, 60, 136,
+ 104, 207, 48, 135, 52, 161, 213, 115,
+ 161, 57, 240, 162, 77, 17, 152, 61,
+ 211, 2, 62, 87, 43, 255, 159, 174,
+ 58, 81, 199, 167, 168, 40, 41, 244,
+ 146, 141, 210, 84, 15, 205, 130, 121,
+ 204, 233, 86, 113, 21, 93, 83, 15,
+ 73, 117, 159, 115, 200, 21, 83, 195,
+ 72, 236, 174, 252, 164, 225, 106, 211,
+ 162, 210, 89, 142, 47, 4, 120, 25,
+ 83, 68, 230, 51, 69, 222, 28, 239,
+ 242, 49, 136, 180, 180, 83, 1, 60,
+ 141, 84, 252, 164, 205, 246, 235, 126,
+ 11, 221, 49, 65, 14, 145, 10, 214,
+ 192, 23, 137, 159, 252, 80, 95, 169,
+ 30, 189, 49, 249, 14, 98, 37, 110,
+ 90, 9, 5, 170, 139, 245, 200, 107,
+ 62, 151, 38, 86, 91, 211, 237, 65,
+ 133, 108, 160, 230, 196, 225, 209, 196,
+ 245, 126, 50, 230, 57, 59, 120, 5,
+ 90, 87, 251, 201, 192, 171, 41, 53,
+ 18, 68, 134, 148, 38, 49, 7, 200,
+ 224, 105, 8, 5, 85, 181, 95, 125,
+ 59, 109, 102, 117, 215, 253, 107, 198,
+ 208, 213, 128, 11, 1, 202, 54, 116,
+ 12, 50, 137, 228, 184, 166, 231, 109,
+ 217, 122, 96, 37, 6, 215, 156, 145,
+ 15, 66, 40, 98, 158, 22, 28, 118,
+ 205, 201, 147, 83, 254, 40, 93, 112,
+ 180, 58, 207, 245, 38, 46, 247, 215,
+ 65, 74, 79, 165, 91, 186, 56, 115,
+ 224, 71, 188, 148, 145, 253, 196, 148,
+ 106, 234, 246, 248, 194, 248, 109, 121,
+ 172, 53, 26, 210, 121, 97, 206, 168,
+ 34, 130, 168, 174, 134, 34, 180, 195,
+ 5, 46, 144, 47, 69, 98, 217, 166,
+ 112, 3, 86, 85, 126, 220, 76, 1,
+ 60, 12, 1, 40, 87, 78, 38, 103,
+ 177, 1, 166, 1, 188, 244, 104, 73,
+ 144, 77, 225, 115, 112, 53, 201, 51,
+ 29, 20, 12, 207, 200, 53, 175, 91,
+ 145, 171, 126, 248, 89, 39, 208, 243,
+ 118, 30, 204, 83, 117, 41, 237, 243,
+ 34, 179, 226, 40, 138, 99, 10, 122,
+ 126, 212, 42, 168, 132, 209, 211, 15,
+ 27, 29, 70, 157, 236, 19, 122, 44,
+ 45, 211, 213, 146, 134, 239, 56, 200,
+ 21, 247, 106, 219, 16, 217, 13, 43,
+ 63, 76, 27, 227, 25, 200, 36, 181,
+ 97, 224, 216, 49, 89, 41, 29, 147,
+ 177, 126, 209, 71, 112, 94, 82, 116,
+ 39, 10, 50, 188, 32, 42, 165, 35,
+ 248, 35, 203, 80, 34, 245, 5, 32,
+ 62, 133, 34, 15, 34, 157, 201, 246,
+ 202, 159, 50, 184, 167, 223, 168, 190,
+ 181, 32, 251, 11, 229, 243, 30, 94,
+ 170, 198, 170, 195, 140, 176, 102, 200,
+ 168, 128, 178, 11, 53, 82, 230, 151,
+ 21, 231, 46, 159, 254, 80, 197, 236,
+ 246, 41, 229, 6, 48, 214, 249, 242,
+ 21, 225, 50, 84, 74, 79, 112, 174,
+ 51, 86, 102, 137, 38, 239, 230, 176,
+ 80, 130, 58, 226, 194, 107, 41, 223,
+ 255, 250, 6, 236, 223, 254, 93, 8,
+ 206, 121, 61, 201, 122, 224, 168, 81,
+ 210, 132, 144, 198, 25, 255, 151, 173,
+ 148, 195, 98, 97, 177, 118, 99, 90,
+ 131, 105, 111, 160, 118, 112, 99, 120,
+ 90, 140, 224, 42, 122, 234, 152, 204,
+ 35, 137, 18, 57, 40, 14, 191, 15,
+ 145, 204, 175, 114, 221, 7, 230, 229,
+ 224, 231, 211, 179, 178, 15, 24, 231,
+ 96, 157, 102, 224, 193, 106, 187, 142,
+ 18, 163, 105, 131, 131, 26, 199, 92,
+ 31, 130, 227, 148, 11, 111, 201, 76,
+ 182, 37, 198, 61, 173, 16, 137, 227,
+ 111, 80, 123, 245, 223, 120, 68, 104,
+ 242, 4, 62, 102, 117, 53, 68, 214,
+ 163, 83, 197, 162, 170, 144, 118, 86,
+ 61, 17, 197, 119, 135, 159, 134, 231,
+ 132, 235, 204, 141, 248, 180, 66, 85,
+ 248, 98, 229, 104, 131, 74, 166, 198,
+ 72, 43, 192, 204, 59, 4, 81, 7,
+ 45, 243, 48, 222, 239, 120, 92, 203,
+ 27, 151, 140, 107, 227, 40, 145, 131,
+ 136, 198, 45, 163, 216, 29, 243, 151,
+ 234, 176, 83, 253, 141, 3, 90, 151,
+ 169, 110, 229, 108, 12, 147, 122, 254,
+ 234, 182, 68, 60, 240, 50, 135, 128,
+ 226, 200, 49, 180, 255, 166, 108, 181,
+ 225, 162, 110, 169, 174, 0, 7, 53,
+ 40, 89, 56, 39, 160, 252, 199, 227,
+ 122, 7, 114, 86, 127, 16, 147, 27,
+ 226, 15, 178, 139, 168, 156, 51, 30,
+ 206, 33, 30, 172, 175, 9, 161, 74,
+ 184, 158, 11, 23, 171, 37, 36, 14,
+ 196, 8, 69, 53, 104, 240, 112, 83,
+ 28, 77, 2, 2, 169, 22, 203, 172,
+ 78, 189, 103, 21, 22, 29, 82, 123,
+ 213, 13, 53, 213, 209, 153, 124, 247,
+ 254, 113, 200, 71, 88, 235, 7, 233,
+ 249, 172, 55, 223, 123, 174, 205, 155,
+ 188, 219, 135, 55, 64, 226, 44, 229,
+ 131, 143, 166, 81, 119, 155, 170, 110,
+ 119, 188, 242, 90, 74, 187, 14, 43,
+ 121, 123, 126, 39, 61, 9, 181, 4,
+ 194, 41, 63, 85, 115, 198, 66, 23,
+ 37, 90, 47, 1, 154, 23, 15, 14,
+ 127, 72, 144, 232, 212, 220, 198, 191,
+ 107, 162, 130, 253, 172, 121, 21, 209,
+ 173, 52, 107, 172, 142, 187, 161, 37,
+ 180, 91, 173, 36, 192, 106, 216, 80,
+ 12, 254, 89, 164, 95, 110, 154, 19,
+ 143, 13, 53, 114, 123, 49, 54, 249,
+ 34, 98, 184, 43, 242, 52, 75, 113,
+ 203, 251, 252, 150, 174, 189, 203, 75,
+ 147, 35, 11, 224, 188, 130, 66, 173,
+ 80, 211, 208, 125, 247, 12, 222, 139,
+ 192, 43, 216, 103, 35, 196, 233, 158,
+ 249, 166, 203, 139, 245, 206, 30, 43,
+ 42, 132, 40, 136, 247, 145, 164, 51,
+ 65, 118, 233, 100, 150, 205, 198, 233,
+ 75, 3, 47, 33, 86, 161, 19, 222,
+ 218, 215, 110, 28, 217, 164, 240, 131,
+ 166, 178, 147, 79, 210, 20, 194, 19,
+ 230, 183, 53, 44, 56, 23, 162, 98,
+ 142, 102, 205, 240, 181, 159, 61, 54,
+ 221, 168, 51, 41, 247, 22, 66, 109,
+ 241, 26, 162, 153, 42, 207, 2, 68,
+ 186, 163, 8, 158, 108, 50, 27, 102,
+ 106, 154, 188, 18, 180, 199, 166, 128,
+ 87, 197, 226, 187, 96, 80, 212, 123,
+ 45, 193, 16, 226, 247, 186, 205, 180,
+ 107, 160, 205, 6, 29, 191, 34, 176,
+ 23, 229, 213, 139, 42, 103, 158, 123,
+ 36, 87, 128, 120, 143, 209, 63, 48,
+ 74, 237, 134, 177, 129, 132, 200, 130,
+ 38, 46, 205, 57, 108, 135, 238, 89,
+ 243, 175, 194, 118, 61, 228, 100, 188,
+ 130, 101, 32, 129, 210, 166, 33, 79,
+ 16, 33, 4, 251, 181, 131, 55, 162,
+ 67, 16, 22, 52, 243, 22, 199, 222,
+ 195, 153, 36, 79, 183, 85, 209, 245,
+ 77, 206, 70, 214, 168, 231, 24, 99,
+ 80, 215, 137, 10, 142, 86, 217, 0,
+ 46, 252, 54, 162, 42, 25, 114, 102,
+ 22, 216, 79, 140, 113, 214, 146, 21,
+ 122, 155, 29, 240, 150, 184, 8, 25,
+ 58, 62, 58, 240, 115, 171, 77, 145,
+ 162, 185, 237, 224, 247, 190, 156, 96,
+ 249, 30, 109, 36, 122, 76, 65, 143,
+ 93, 164, 123, 35, 11, 35, 134, 215,
+ 174, 55, 65, 207, 38, 0, 0, 47,
+ 43, 98, 5, 47, 73, 188, 34, 57,
+ 18, 97, 238, 95, 53, 200, 222, 89,
+ 244, 18, 2, 153, 82, 90, 115, 174,
+ 237, 39, 24, 139, 54, 132, 22, 184,
+ 113, 94, 63, 55, 245, 146, 242, 235,
+ 9, 119, 155, 22, 98, 164, 51, 145,
+ 53, 177, 212, 223, 3, 137, 96, 15,
+ 70, 136, 87, 126, 126, 126, 173, 217,
+ 59, 65, 113, 186, 118, 153, 210, 229,
+ 70, 53, 148, 202, 147, 113, 202, 191,
+ 210, 212, 110, 192, 27, 143, 61, 42,
+ 81, 106, 245, 44, 177, 200, 128, 242,
+ 81, 145, 200, 189, 79, 65, 45, 55,
+ 174, 74, 96, 194, 102, 154, 43, 97,
+ 18, 230, 198, 201, 83, 180, 195, 9,
+ 145, 233, 104, 230, 101, 19, 236, 40,
+ 106, 219, 149, 12, 165, 120, 93, 163,
+ 216, 109, 56, 203, 60, 7, 198, 153,
+ 109, 220, 156, 184, 71, 132, 174, 0,
+ 106, 96, 141, 63, 7, 136, 122, 203,
+ 93, 37, 227, 51, 116, 162, 217, 136,
+ 210, 50, 244, 91, 245, 32, 130, 148,
+ 123, 65, 11, 94, 19, 214, 224, 114,
+ 92, 196, 171, 17, 36, 17, 58, 164,
+ 127, 21, 33, 198, 62, 155, 63, 24,
+ 134, 190, 137, 198, 205, 148, 45, 155,
+ 119, 20, 205, 20, 153, 71, 72, 179,
+ 20, 162, 225, 233, 113, 235, 183, 20,
+ 58, 29, 80, 197, 103, 65, 201, 155,
+ 206, 194, 30, 19, 52, 182, 74, 197,
+ 7, 18, 113, 133, 91, 60, 175, 11,
+ 208, 123, 140, 177, 194, 253, 161, 33,
+ 54, 88, 31, 93, 249, 57, 81, 216,
+ 150, 32, 230, 180, 73, 119, 19, 139,
+ 160, 109, 129, 26, 98, 171, 95, 116,
+ 22, 248, 225, 82, 62, 246, 11, 69,
+ 98, 179, 120, 224, 34, 236, 135, 85,
+ 24, 54, 73, 125, 52, 126, 68, 75,
+ 94, 208, 85, 177, 237, 156, 168, 120,
+ 244, 129, 50, 245, 242, 148, 181, 236,
+ 68, 99, 193, 187, 244, 70, 30, 181,
+ 213, 188, 113, 186, 50, 69, 208, 112,
+ 221, 95, 122, 221, 137, 232, 92, 115,
+ 107, 77, 160, 222, 213, 224, 37, 136,
+ 60, 180, 149, 184, 164, 43, 129, 154,
+ 208, 26, 152, 204, 75, 143, 219, 57,
+ 10, 95, 17, 255, 156, 68, 189, 177,
+ 51, 102, 91, 78, 227, 153, 133, 202,
+ 46, 239, 171, 160, 231, 5, 187, 144,
+ 77, 190, 120, 170, 239, 192, 48, 13,
+ 109, 231, 196, 77, 54, 146, 6, 113,
+ 190, 94, 61, 18, 243, 24, 161, 221,
+ 146, 40, 224, 132, 176, 49, 204, 157,
+ 184, 80, 29, 105, 248, 212, 14, 24,
+ 120, 137, 137, 37, 105, 38, 216, 11,
+ 113, 205, 28, 255, 152, 30, 232, 22,
+ 6, 177, 82, 57, 63, 250, 139, 216,
+ 150, 15, 186, 170, 106, 154, 168, 21,
+ 252, 193, 15, 69, 216, 222, 80, 14,
+ 109, 171, 190, 177, 202, 108, 73, 220,
+ 4, 228, 104, 24, 74, 22, 179, 107,
+ 188, 218, 68, 61, 17, 31, 56, 176,
+ 58, 195, 233, 82, 121, 82, 93, 207,
+ 156, 184, 184, 81, 111, 87, 110, 116,
+ 38, 121, 178, 241, 236, 119, 80, 230,
+ 246, 176, 91, 197, 96, 8, 30, 27,
+ 220, 236, 49, 9, 231, 55, 70, 180,
+ 96, 30, 208, 155, 7, 81, 45, 49,
+ 22, 126, 151, 225, 248, 172, 23, 212,
+ 175, 243, 48, 65, 97, 153, 74, 133,
+ 72, 50, 132, 254, 80, 174, 126, 26,
+ 211, 140, 221, 76, 164, 18, 135, 174,
+ 39, 217, 203, 183, 47, 128, 103, 93,
+ 14, 105, 47, 143, 152, 182, 210, 175,
+ 155, 204, 214, 190, 246, 60, 241, 82,
+ 113, 65, 220, 228, 53, 98, 148, 170,
+ 41, 192, 162, 155, 71, 95, 51, 227,
+ 214, 7, 73, 170, 68, 142, 19, 92,
+ 142, 19, 18, 98, 17, 143, 170, 126,
+ 10, 231, 52, 216, 234, 114, 32, 71,
+ 32, 235, 163, 211, 83, 187, 24, 39,
+ 144, 191, 79, 231, 158, 112, 31, 186,
+ 135, 93, 27, 17, 78, 64, 146, 3,
+ 68, 33, 5, 59, 157, 50, 220, 6,
+ 198, 105, 4, 75, 170, 222, 193, 152,
+ 159, 232, 147, 215, 101, 121, 214, 100,
+ 119, 137, 236, 254, 142, 56, 182, 193,
+ 169, 221, 181, 160, 18, 50, 121, 154,
+ 134, 41, 253, 81, 12, 37, 76, 220,
+ 156, 235, 211, 113, 226, 1, 188, 67,
+ 160, 187, 204, 27, 91, 237, 240, 53,
+ 87, 93, 152, 54, 104, 69, 75, 18,
+ 124, 128, 204, 119, 86, 24, 176, 80,
+ 57, 204, 164, 9, 131, 89, 190, 54,
+ 192, 172, 171, 57, 113, 40, 234, 147,
+ 112, 37, 198, 216, 10, 132, 30, 164,
+ 206, 204, 29, 42, 79, 156, 121, 21,
+ 1, 212, 70, 40, 42, 230, 41, 202,
+ 133, 82, 109, 200, 182, 166, 220, 52,
+ 145, 42, 96, 201, 15, 90, 109, 234,
+ 106, 55, 175, 6, 30, 207, 32, 89,
+ 37, 201, 211, 87, 176, 111, 165, 101,
+ 18, 189, 246, 104, 145, 123, 14, 127,
+ 164, 107, 67, 78, 211, 241, 150, 101,
+ 49, 79, 122, 202, 102, 223, 244, 246,
+ 203, 17, 58, 100, 75, 116, 63, 196,
+ 23, 133, 78, 4, 171, 136, 188, 77,
+ 119, 216, 161, 176, 11, 121, 99, 206,
+ 6, 181, 187, 218, 169, 201, 35, 72,
+ 18, 230, 61, 238, 93, 3, 104, 122,
+ 55, 46, 151, 40, 164, 178, 49, 214,
+ 65, 133, 212, 167, 153, 47, 149, 198,
+ 22, 144, 90, 192, 159, 148, 138, 85,
+ 103, 161, 6, 81, 198, 5, 202, 225,
+ 103, 181, 185, 101, 237, 169, 247, 110,
+ 70, 232, 153, 164, 30, 129, 79, 85,
+ 11, 199, 161, 75, 20, 55, 128, 147,
+ 122, 184, 166, 4, 8, 112, 234, 34,
+ 81, 232, 16, 181, 103, 153, 112, 177,
+ 55, 12, 179, 77, 125, 18, 216, 239,
+ 127, 217, 154, 58, 207, 89, 175, 23,
+ 185, 191, 17, 215, 221, 167, 137, 240,
+ 166, 96, 197, 178, 92, 83, 193, 8,
+ 241, 138, 46, 76, 206, 29, 115, 126,
+ 69, 231, 50, 71, 127, 255, 147, 13,
+ 197, 108, 113, 121, 234, 212, 247, 72,
+ 49, 65, 247, 94, 248, 104, 26, 81,
+ 93, 17, 94, 219, 237, 198, 181, 53,
+ 14, 169, 227, 178, 12, 188, 212, 141,
+ 76, 94, 53, 19, 187, 68, 53, 220,
+ 60, 1, 180, 16, 99, 37, 45, 31,
+ 169, 216, 37, 243, 17, 132, 3, 73,
+ 49, 99, 170, 42, 42, 189, 203, 144,
+ 253, 111, 232, 210, 167, 159, 232, 25,
+ 91, 82, 176, 169, 17, 43, 125, 219,
+ 236, 75, 38, 20, 219, 144, 197, 212,
+ 126, 98, 21, 34, 223, 179, 64, 141,
+ 235, 33, 52, 239, 52, 106, 70, 130,
+ 132, 56, 72, 172, 209, 255, 30, 199,
+ 160, 197, 184, 201, 78, 82, 156, 205,
+ 48, 219, 5, 47, 237, 184, 73, 70,
+ 181, 158, 113, 25, 184, 161, 186, 21,
+ 103, 24, 193, 211, 254, 124, 87, 68,
+ 143, 182, 203, 166, 55, 252, 209, 80,
+ 178, 199, 233, 200, 124, 188, 74, 53,
+ 86, 139, 123, 175, 25, 95, 226, 102,
+ 158, 231, 148, 101, 101, 131, 75, 235,
+ 176, 105, 51, 130, 212, 112, 61, 110,
+ 74, 79, 127, 108, 37, 110, 181, 107,
+ 9, 123, 148, 77, 238, 168, 190, 37,
+ 62, 0, 211, 210, 78, 165, 233, 120,
+ 47, 250, 160, 215, 212, 166, 246, 169,
+ 112, 90, 35, 159, 92, 166, 220, 51,
+ 190, 57, 233, 3, 99, 69, 171, 74,
+ 50, 198, 44, 145, 21, 97, 77, 254,
+ 103, 155, 29, 241, 98, 160, 14, 88,
+ 168, 40, 149, 186, 41, 222, 73, 83,
+ 206, 98, 175, 158, 70, 4, 42, 104,
+ 105, 60, 14, 92, 1, 235, 100, 147,
+ 141, 46, 5, 218, 128, 119, 32, 145,
+ 236, 16, 176, 12, 179, 143, 194, 129,
+ 187, 165, 168, 11, 81, 253, 71, 122,
+ 64, 109, 254, 20, 117, 195, 193, 41,
+ 196, 226, 211, 54, 214, 229, 62, 231,
+ 15, 165, 95, 136, 103, 177, 4, 210,
+ 53, 229, 131, 202, 207, 250, 98, 204,
+ 8, 22, 115, 117, 96, 196, 88, 229,
+ 20, 25, 244, 117, 236, 13, 158, 138,
+ 154, 74, 87, 10, 154, 93, 222, 154,
+ 63, 231, 243, 68, 65, 137, 3, 68,
+ 178, 177, 197, 59, 254, 192, 233, 174,
+ 144, 100, 154, 113, 87, 149, 124, 140,
+ 49, 145, 26, 129, 50, 55, 9, 63,
+ 36, 168, 114, 65, 59, 158, 107, 115,
+ 138, 253, 115, 211, 152, 241, 214, 235,
+ 4, 249, 110, 90, 103, 6, 144, 43,
+ 118, 205, 216, 114, 207, 174, 72, 135,
+ 111, 98, 166, 232, 113, 117, 186, 108,
+ 30, 227, 31, 30, 222, 200, 119, 7,
+ 107, 6, 120, 207, 100, 225, 110, 159,
+ 48, 74, 204, 255, 54, 64, 127, 163,
+ 75, 190, 0, 60, 218, 69, 185, 67,
+ 65, 180, 136, 33, 18, 233, 212, 217,
+ 210, 65, 155, 3, 9, 154, 198, 60,
+ 9, 226, 84, 36, 210, 27, 162, 18,
+ 116, 27, 3, 117, 235, 166, 19, 49,
+ 21, 52, 82, 49, 249, 112, 120, 228,
+ 235, 99, 50, 151, 121, 231, 134, 183,
+ 2, 206, 205, 4, 68, 195, 102, 178,
+ 112, 112, 172, 135, 205, 135, 202, 12,
+ 193, 74, 107, 126, 103, 60, 21, 232,
+ 41, 197, 201, 210, 109, 51, 111, 121,
+ 91, 176, 213, 167, 195, 102, 120, 236,
+ 8, 12, 130, 110, 20, 40, 89, 110,
+ 163, 246, 39, 33, 146, 10, 239, 218,
+ 62, 112, 8, 129, 105, 240, 167, 169,
+ 120, 70, 74, 143, 82, 185, 108, 220,
+ 77, 250, 129, 79, 214, 161, 173, 111,
+ 185, 37, 163, 11, 71, 93, 70, 112,
+ 53, 254, 209, 63, 115, 227, 92, 184,
+ 105, 62, 230, 169, 15, 135, 116, 125,
+ 138, 12, 122, 143, 183, 16, 127, 34,
+ 24, 64, 97, 243, 254, 237, 200, 6,
+ 119, 128, 1, 107, 91, 2, 172, 37,
+ 108, 182, 70, 152, 82, 190, 155, 232,
+ 227, 101, 180, 139, 44, 218, 73, 3,
+ 40, 204, 215, 31, 125, 195, 51, 105,
+ 104, 58, 122, 237, 208, 45, 229, 79,
+ 141, 116, 29, 45, 181, 42, 167, 49,
+ 61, 184, 71, 254, 15, 142, 177, 202,
+ 10, 107, 95, 94, 76, 20, 27, 146,
+ 18, 20, 127, 218, 221, 138, 175, 27,
+ 210, 24, 177, 3, 194, 93, 70, 42,
+ 143, 67, 207, 251, 214, 32, 35, 76,
+ 24, 240, 15, 140, 80, 132, 238, 86,
+ 145, 11, 248, 200, 245, 219, 42, 184,
+ 44, 74, 119, 44, 86, 254, 47, 109,
+ 38, 110, 108, 124, 11, 188, 135, 145,
+ 253, 92, 187, 7, 28, 55, 202, 221,
+ 241, 113, 76, 42, 180, 100, 128, 83,
+ 108, 29, 33, 228, 66, 136, 178, 66,
+ 133, 85, 80, 38, 70, 106, 182, 207,
+ 191, 207, 92, 172, 48, 31, 117, 6,
+ 17, 10, 210, 200, 164, 207, 135, 180,
+ 254, 118, 163, 250, 248, 40, 150, 188,
+ 42, 151, 20, 31, 220, 99, 244, 241,
+ 78, 9, 17, 45, 100, 47, 12, 253,
+ 111, 187, 229, 154, 255, 127, 210, 62,
+ 92, 126, 98, 164, 45, 224, 34, 168,
+ 253, 78, 117, 188, 39, 221, 173, 108,
+ 59, 151, 68, 117, 148, 9, 16, 34,
+ 45, 0, 200, 109, 60, 196, 120, 119,
+ 238, 145, 140, 133, 173, 68, 1, 44,
+ 195, 216, 247, 211, 54, 43, 28, 107,
+ 117, 134, 179, 24, 71, 83, 81, 193,
+ 124, 98, 253, 252, 124, 78, 141, 234,
+ 105, 203, 112, 158, 127, 162, 74, 72,
+ 151, 13, 201, 240, 206, 123, 231, 35,
+ 187, 255, 116, 9, 19, 35, 70, 115,
+ 115, 60, 169, 230, 170, 35, 155, 137,
+ 27, 167, 44, 218, 30, 32, 76, 16,
+ 232, 223, 179, 233, 20, 49, 156, 18,
+ 152, 76, 101, 173, 0, 82, 19, 144,
+ 243, 240, 237, 105, 184, 70, 48, 153,
+ 101, 214, 117, 244, 150, 225, 42, 194,
+ 207, 152, 137, 87, 210, 186, 222, 153,
+ 152, 13, 22, 41, 77, 147, 7, 123,
+ 184, 98, 72, 243, 22, 177, 59, 87,
+ 254, 43, 6, 37, 69, 145, 162, 138,
+ 106, 29, 6, 27, 77, 233, 252, 148,
+ 225, 70, 243, 244, 70, 90, 235, 222,
+ 207, 188, 37, 221, 36, 84, 238, 84,
+ 43, 160, 149, 44, 14, 57, 251, 202,
+ 99, 236, 68, 23, 209, 176, 73, 226,
+ 239, 6, 47, 125, 16, 24, 148, 76,
+ 174, 247, 234, 1, 179, 238, 70, 68,
+ 112, 118, 155, 224, 114, 20, 159, 9,
+ 38, 45, 72, 149, 127, 123, 16, 241,
+ 56, 43, 32, 103, 193, 172, 139, 90,
+ 22, 60, 26, 62, 147, 130, 214, 2,
+ 163, 56, 101, 115, 173, 168, 115, 214,
+ 195, 7, 30, 240, 160, 234, 204, 187,
+ 194, 241, 110, 127, 152, 44, 121, 39,
+ 31, 10, 11, 191, 174, 244, 56, 169,
+ 31, 187, 156, 15, 35, 194, 203, 242,
+ 31, 104, 253, 125, 249, 10, 252, 52,
+ 96, 128, 231, 169, 85, 224, 59, 81,
+ 142, 168, 230, 121, 252, 210, 213, 120,
+ 177, 22, 138, 55, 224, 83, 41, 237,
+ 244, 19, 3, 164, 142, 90, 22, 216,
+ 202, 56, 184, 80, 125, 246, 30, 61,
+ 71, 83, 18, 192, 180, 237, 150, 182,
+ 113, 14, 29, 65, 3, 207, 193, 225,
+ 73, 71, 197, 190, 201, 197, 249, 89,
+ 218, 193, 106, 192, 161, 220, 46, 188,
+ 100, 75, 197, 193, 148, 105, 226, 147,
+ 170, 53, 109, 77, 161, 203, 184, 172,
+ 191, 195, 103, 246, 80, 103, 63, 9,
+ 66, 250, 75, 200, 191, 221, 27, 98,
+ 182, 200, 137, 61, 42, 193, 119, 233,
+ 248, 21, 86, 90, 42, 236, 205, 22,
+ 94, 35, 226, 171, 112, 106, 196, 158,
+ 95, 202, 138, 43, 8, 54, 242, 87,
+ 162, 104, 41, 189, 39, 9, 157, 71,
+ 124, 234, 56, 217, 164, 92, 9, 200,
+ 140, 244, 234, 59, 162, 225, 235, 46,
+ 40, 116, 61, 252, 218, 245, 88, 14,
+ 215, 96, 158, 201, 138, 2, 236, 228,
+ 250, 80, 171, 214, 194, 143, 166, 4,
+ 40, 10, 181, 38, 144, 84, 242, 82,
+ 28, 166, 210, 219, 17, 4, 92, 254,
+ 103, 144, 78, 117, 127, 28, 99, 224,
+ 203, 3, 220, 128, 221, 230, 175, 59,
+ 48, 26, 85, 247, 217, 196, 242, 27,
+ 144, 206, 202, 165, 155, 243, 2, 218,
+ 59, 217, 162, 45, 47, 27, 0, 250,
+ 75, 246, 204, 143, 30, 197, 202, 242,
+ 252, 178, 216, 104, 189, 175, 2, 30,
+ 197, 152, 115, 133, 137, 230, 229, 76,
+ 220, 43, 160, 32, 60, 160, 129, 76,
+ 80, 44, 173, 138, 113, 33, 93, 141,
+ 167, 252, 244, 205, 146, 133, 161, 49,
+ 255, 202, 112, 11, 255, 2, 220, 24,
+ 241, 148, 193, 240, 12, 12, 6, 82,
+ 72, 21, 164, 195, 137, 83, 69, 66,
+ 244, 204, 53, 242, 162, 165, 195, 137,
+ 34, 150, 27, 165, 139, 112, 188, 153,
+ 196, 101, 134, 194, 99, 228, 49, 129,
+ 174, 91, 230, 87, 121, 214, 99, 10,
+ 7, 252, 202, 92, 226, 131, 181, 180,
+ 127, 239, 251, 250, 252, 217, 242, 227,
+ 120, 57, 42, 55, 68, 75, 157, 229,
+ 251, 160, 100, 237, 64, 134, 201, 189,
+ 138, 192, 178, 85, 250, 190, 72, 106,
+ 0, 28, 193, 77, 189, 122, 20, 217,
+ 63, 197, 136, 235, 207, 1, 130, 48,
+ 140, 114, 202, 67, 25, 124, 135, 143,
+ 139, 85, 178, 148, 24, 205, 130, 2,
+ 241, 237, 231, 228, 190, 176, 148, 13,
+ 70, 113, 169, 237, 56, 213, 187, 183,
+ 87, 187, 169, 234, 112, 57, 247, 130,
+ 66, 245, 74, 68, 3, 75, 181, 182,
+ 210, 148, 225, 159, 26, 46, 8, 72,
+ 13, 149, 129, 80, 82, 212, 5, 145,
+ 4, 206, 18, 43, 168, 48, 192, 76,
+ 162, 84, 233, 2, 207, 82, 84, 70,
+ 51, 27, 0, 190, 111, 4, 17, 88,
+ 202, 115, 97, 153, 111, 42, 225, 57,
+ 245, 158, 136, 248, 50, 42, 172, 239,
+ 228, 46, 115, 118, 194, 120, 46, 1,
+ 149, 118, 21, 48, 94, 103, 175, 189,
+ 83, 212, 37, 119, 76, 82, 227, 231,
+ 182, 200, 244, 156, 205, 141, 217, 123,
+ 208, 186, 188, 140, 222, 51, 122, 173,
+ 201, 201, 136, 248, 252, 14, 103, 50,
+ 165, 6, 160, 15, 58, 28, 85, 74,
+ 232, 113, 106, 156, 199, 116, 99, 71,
+ 118, 234, 96, 35, 155, 201, 202, 96,
+ 214, 236, 28, 123, 226, 146, 80, 163,
+ 120, 157, 21, 98, 180, 152, 127, 54,
+ 254, 242, 143, 93, 235, 196, 64, 17,
+ 203, 135, 20, 243, 38, 160, 78, 24,
+ 225, 106, 98, 95, 110, 214, 8, 174,
+ 181, 85, 101, 159, 188, 17, 92, 69,
+ 182, 32, 189, 133, 249, 92, 164, 26,
+ 4, 101, 136, 36, 237, 184, 24, 239,
+ 219, 247, 115, 86, 232, 56, 220, 84,
+ 242, 8, 106, 30, 182, 54, 108, 107,
+ 94, 238, 75, 55, 251, 60, 77, 25,
+ 160, 181, 168, 206, 111, 190, 214, 184,
+ 34, 133, 229, 84, 42, 50, 224, 149,
+ 235, 80, 240, 173, 191, 27, 97, 24,
+ 56, 246, 123, 116, 209, 117, 144, 149,
+ 251, 132, 168, 150, 79, 103, 87, 50,
+ 42, 157, 243, 220, 21, 241, 70, 57,
+ 65, 171, 202, 128, 183, 36, 143, 238,
+ 220, 40, 95, 91, 151, 229, 254, 159,
+ 84, 252, 203, 58, 248, 206, 135, 169,
+ 47, 20, 105, 147, 198, 166, 60, 39,
+ 120, 105, 22, 213, 241, 82, 106, 163,
+ 154, 21, 138, 91, 209, 98, 248, 243,
+ 120, 32, 183, 6, 110, 197, 248, 34,
+ 192, 179, 144, 165, 151, 221, 22, 87,
+ 3, 205, 78, 5, 41, 185, 167, 131,
+ 172, 11, 103, 255, 228, 227, 131, 215,
+ 212, 159, 218, 211, 162, 41, 211, 2,
+ 23, 128, 20, 218, 129, 190, 230, 94,
+ 200, 222, 180, 165, 248, 99, 6, 161,
+ 182, 65, 157, 110, 209, 201, 188, 52,
+ 85, 12, 19, 129, 71, 63, 98, 34,
+ 214, 103, 12, 163, 129, 152, 239, 243,
+ 192, 15, 20, 62, 247, 158, 34, 207,
+ 218, 66, 65, 38, 9, 141, 100, 57,
+ 216, 179, 134, 40, 81, 36, 39, 62,
+ 191, 212, 174, 48, 238, 213, 51, 252,
+ 218, 142, 52, 44, 143, 150, 56, 238,
+ 48, 205, 59, 12, 213, 146, 199, 28,
+ 41, 60, 190, 6, 69, 168, 203, 161,
+ 9, 21, 185, 58, 211, 194, 182, 119,
+ 134, 155, 217, 209, 112, 146, 97, 60,
+ 126, 191, 230, 240, 125, 225, 27, 244,
+ 167, 45, 86, 168, 205, 244, 51, 243,
+ 199, 117, 166, 149, 106, 158, 154, 116,
+ 3, 56, 101, 245, 140, 196, 179, 227,
+ 176, 236, 249, 206, 97, 40, 68, 110,
+ 170, 105, 111, 181, 93, 40, 202, 211,
+ 233, 163, 222, 177, 115, 42, 161, 39,
+ 194, 156, 109, 221, 112, 210, 14, 141,
+ 77, 51, 35, 160, 130, 157, 145, 56,
+ 102, 189, 101, 50, 38, 90, 77, 20,
+ 138, 48, 197, 47, 206, 104, 220, 224,
+ 25, 126, 115, 255, 195, 118, 89, 10,
+ 246, 239, 190, 31, 72, 141, 251, 165,
+ 15, 126, 52, 145, 186, 133, 89, 66,
+ 229, 196, 117, 233, 19, 180, 220, 158,
+ 59, 168, 133, 245, 199, 214, 99, 177,
+ 228, 8, 168, 43, 200, 90, 147, 250,
+ 183, 28, 78, 117, 207, 28, 48, 186,
+ 235, 177, 225, 175, 23, 244, 213, 238,
+ 108, 223, 222, 162, 24, 114, 124, 114,
+ 98, 33, 64, 137, 22, 17, 183, 198,
+ 69, 121, 11, 197, 75, 164, 231, 205,
+ 145, 6, 239, 2, 183, 147, 50, 109,
+ 21, 155, 145, 89, 47, 147, 68, 41,
+ 49, 218, 6, 206, 41, 188, 182, 109,
+ 138, 217, 78, 30, 59, 107, 38, 18,
+ 195, 164, 83, 107, 95, 52, 34, 142,
+ 110, 76, 238, 7, 121, 246, 105, 203,
+ 236, 45, 182, 204, 222, 149, 91, 161,
+ 26, 37, 235, 54, 218, 194, 143, 32,
+ 38, 21, 24, 207, 98, 149, 2, 24,
+ 179, 69, 158, 206, 98, 167, 208, 2,
+ 221, 227, 178, 219, 152, 79, 189, 71,
+ 32, 111, 141, 200, 52, 91, 110, 49,
+ 214, 42, 149, 244, 40, 75, 217, 72,
+ 149, 132, 139, 5, 251, 100, 48, 28,
+ 74, 1, 205, 171, 65, 157, 62, 88,
+ 126, 106, 160, 123, 61, 204, 237, 19,
+ 41, 65, 17, 116, 9, 11, 35, 215,
+ 28, 186, 137, 235, 146, 99, 102, 68,
+ 39, 218, 181, 78, 157, 90, 162, 194,
+ 50, 192, 137, 190, 26, 136, 186, 144,
+ 186, 79, 68, 109, 184, 146, 218, 111,
+ 243, 127, 132, 128, 228, 20, 49, 124,
+ 125, 75, 247, 56, 213, 20, 109, 235,
+ 86, 246, 114, 176, 125, 106, 125, 167,
+ 233, 250, 110, 119, 131, 166, 126, 154,
+ 85, 222, 202, 93, 192, 39, 107, 147,
+ 109, 35, 113, 15, 105, 11, 206, 1,
+ 193, 75, 9, 35, 172, 102, 246, 177,
+ 1, 70, 179, 108, 254, 217, 73, 61,
+ 188, 65, 193, 165, 186, 236, 105, 230,
+ 50, 41, 98, 56, 76, 185, 165, 251,
+ 242, 101, 21, 146, 252, 122, 33, 11,
+ 5, 116, 236, 111, 22, 148, 46, 132,
+ 98, 45, 138, 75, 114, 222, 114, 223,
+ 3, 117, 132, 237, 249, 200, 201, 139,
+ 214, 224, 3, 176, 22, 13, 191, 192,
+ 7, 186, 38, 37, 254, 71, 133, 65,
+ 130, 67, 233, 164, 144, 250, 224, 19,
+ 60, 159, 215, 36, 221, 131, 126, 113,
+ 214, 235, 125, 122, 244, 22, 34, 40,
+ 156, 137, 248, 14, 163, 210, 86, 185,
+ 230, 112, 187, 46, 13, 127, 95, 98,
+ 216, 92, 74, 67, 12, 213, 97, 56,
+ 24, 28, 204, 226, 240, 175, 112, 119,
+ 49, 88, 125, 124, 196, 73, 138, 13,
+ 81, 58, 223, 112, 106, 74, 93, 154,
+ 58, 17, 53, 19, 150, 21, 134, 92,
+ 72, 198, 64, 53, 76, 111, 151, 52,
+ 189, 181, 196, 104, 58, 144, 73, 48,
+ 160, 92, 139, 152, 24, 120, 219, 179,
+ 15, 89, 157, 169, 127, 224, 24, 49,
+ 77, 25, 252, 237, 156, 12, 132, 182,
+ 14, 140, 8, 204, 22, 160, 174, 255,
+ 58, 25, 137, 243, 62, 156, 55, 113,
+ 131, 185, 204, 99, 120, 255, 92, 164,
+ 107, 172, 226, 47, 158, 53, 106, 39,
+ 221, 162, 10, 68, 213, 31, 79, 239,
+ 76, 215, 112, 137, 1, 220, 144, 159,
+ 249, 150, 64, 191, 160, 185, 234, 55,
+ 81, 78, 59, 215, 228, 104, 30, 45,
+ 185, 193, 142, 164, 69, 243, 243, 45,
+ 71, 208, 196, 2, 159, 214, 72, 203,
+ 132, 81, 181, 46, 45, 138, 47, 154,
+ 70, 41, 88, 247, 45, 151, 191, 156,
+ 63, 74, 142, 100, 131, 210, 194, 15,
+ 231, 87, 225, 227, 192, 80, 240, 233,
+ 128, 192, 128, 33, 219, 197, 253, 79,
+ 157, 216, 176, 149, 253, 28, 74, 3,
+ 197, 84, 248, 62, 50, 37, 82, 153,
+ 106, 46, 49, 208, 167, 239, 187, 64,
+ 146, 71, 117, 163, 45, 92, 246, 61,
+ 103, 191, 182, 227, 123, 58, 215, 22,
+ 96, 239, 84, 215, 170, 109, 124, 99,
+ 187, 156, 127, 63, 144, 128, 105, 234,
+ 171, 44, 77, 40, 238, 236, 59, 216,
+ 177, 97, 247, 245, 17, 91, 95, 36,
+ 120, 113, 175, 225, 7, 90, 244, 94,
+ 141, 190, 143, 54, 38, 226, 34, 180,
+ 251, 113, 20, 66, 158, 149, 211, 58,
+ 250, 177, 148, 16, 74, 33, 56, 153,
+ 137, 221, 180, 95, 204, 72, 171, 102,
+ 3, 131, 195, 83, 211, 61, 40, 211,
+ 0, 78, 119, 101, 81, 140, 101, 22,
+ 120, 111, 101, 119, 210, 50, 87, 207,
+ 65, 241, 211, 218, 52, 40, 134, 20,
+ 210, 98, 153, 192, 162, 196, 121, 117,
+ 230, 251, 61, 220, 113, 68, 127, 121,
+ 42, 191, 207, 26, 60, 116, 14, 151,
+ 116, 41, 136, 85, 157, 73, 176, 180,
+ 55, 251, 78, 34, 96, 136, 92, 93,
+ 171, 34, 136, 218, 103, 204, 227, 92,
+ 204, 49, 168, 123, 173, 4, 212, 22,
+ 7, 218, 180, 232, 17, 152, 172, 127,
+ 225, 122, 58, 221, 161, 27, 144, 119,
+ 115, 176, 140, 254, 66, 193, 59, 101,
+ 36, 244, 14, 74, 191, 205, 101, 217,
+ 3, 140, 225, 127, 201, 122, 46, 102,
+ 97, 175, 210, 51, 188, 24, 118, 33,
+ 68, 204, 167, 14, 218, 190, 26, 231,
+ 24, 192, 60, 234, 239, 195, 217, 224,
+ 187, 111, 88, 105, 1, 174, 45, 15,
+ 138, 197, 162, 67, 95, 240, 103, 218,
+ 139, 24, 22, 89, 27, 86, 188, 224,
+ 212, 227, 46, 237, 187, 32, 250, 253,
+ 138, 107, 235, 180, 46, 93, 195, 36,
+ 212, 167, 218, 150, 175, 37, 71, 139,
+ 88, 255, 13, 232, 167, 193, 169, 193,
+ 130, 190, 169, 152, 92, 53, 22, 210,
+ 65, 154, 3, 5, 180, 226, 241, 123,
+ 64, 226, 38, 134, 118, 221, 184, 68,
+ 92, 115, 204, 232, 62, 250, 219, 176,
+ 147, 193, 175, 107, 139, 134, 131, 14,
+ 121, 100, 25, 72, 165, 104, 141, 98,
+ 9, 227, 122, 41, 78, 150, 33, 121,
+ 121, 135, 111, 22, 216, 129, 67, 197,
+ 132, 45, 198, 34, 88, 111, 65, 130,
+ 28, 32, 38, 218, 188, 174, 41, 106,
+ 77, 116, 250, 112, 78, 6, 75, 168,
+ 27, 232, 208, 14, 9, 228, 149, 40,
+ 234, 154, 5, 145, 23, 155, 169, 35,
+ 136, 161, 233, 143, 248, 133, 231, 241,
+ 212, 78, 120, 199, 93, 127, 248, 114,
+ 249, 104, 127, 88, 218, 29, 227, 104,
+ 150, 92, 127, 215, 70, 135, 10, 39,
+ 72, 110, 73, 6, 180, 222, 73, 150,
+ 10, 5, 117, 195, 202, 21, 189, 217,
+ 193, 145, 160, 169, 141, 35, 75, 54,
+ 209, 214, 103, 127, 26, 196, 231, 111,
+ 17, 251, 138, 130, 7, 239, 224, 181,
+ 4, 124, 68, 161, 32, 25, 139, 132,
+ 237, 109, 198, 160, 190, 162, 11, 161,
+ 254, 125, 85, 155, 35, 45, 84, 156,
+ 11, 84, 91, 16, 239, 56, 207, 218,
+ 223, 84, 24, 226, 248, 182, 143, 81,
+ 226, 130, 43, 185, 221, 40, 95, 48,
+ 7, 111, 238, 9, 205, 181, 36, 54,
+ 49, 187, 61, 69, 53, 21, 202, 207,
+ 75, 143, 49, 81, 107, 246, 123, 105,
+ 214, 157, 61, 252, 159, 170, 76, 74,
+ 200, 29, 185, 220, 9, 94, 251, 6,
+ 91, 182, 198, 181, 238, 189, 151, 118,
+ 203, 228, 199, 191, 118, 6, 87, 58,
+ 189, 233, 163, 128, 169, 8, 57, 64,
+ 175, 158, 167, 117, 43, 80, 134, 183,
+ 115, 177, 247, 44, 65, 12, 220, 39,
+ 183, 233, 58, 166, 156, 24, 129, 88,
+ 245, 51, 48, 207, 122, 198, 17, 218,
+ 248, 177, 141, 151, 246, 241, 247, 82,
+ 9, 208, 134, 116, 49, 201, 64, 11,
+ 239, 183, 118, 237, 244, 76, 134, 67,
+ 45, 208, 80, 249, 2, 59, 124, 43,
+ 202, 114, 232, 19, 99, 233, 161, 20,
+ 198, 189, 233, 43, 56, 20, 60, 244,
+ 221, 24, 190, 91, 115, 244, 77, 66,
+ 118, 166, 117, 240, 182, 200, 162, 154,
+ 76, 218, 114, 104, 89, 81, 163, 173,
+ 125, 3, 119, 169, 115, 179, 191, 175,
+ 102, 221, 202, 191, 11, 145, 213, 2,
+ 211, 35, 29, 31, 90, 214, 2, 204,
+ 62, 38, 58, 157, 135, 41, 61, 3,
+ 192, 170, 213, 13, 34, 94, 82, 47,
+ 72, 6, 97, 212, 201, 23, 89, 207,
+ 118, 236, 220, 147, 91, 254, 153, 229,
+ 192, 50, 154, 244, 69, 233, 150, 20,
+ 23, 143, 57, 172, 95, 30, 205, 52,
+ 17, 220, 155, 166, 56, 14, 16, 227,
+ 7, 36, 67, 158, 116, 119, 67, 130,
+ 169, 227, 129, 9, 50, 112, 116, 53,
+ 223, 180, 194, 228, 66, 149, 197, 13,
+ 19, 116, 73, 19, 42, 132, 84, 202,
+ 182, 147, 38, 130, 128, 26, 0, 192,
+ 243, 142, 130, 199, 176, 71, 91, 115,
+ 2, 59, 231, 71, 101, 51, 103, 121,
+ 85, 241, 151, 207, 221, 238, 210, 218,
+ 254, 65, 224, 84, 204, 15, 146, 60,
+ 32, 161, 171, 221, 77, 193, 246, 213,
+ 138, 76, 49, 115, 9, 206, 219, 238,
+ 99, 173, 193, 236, 112, 197, 144, 71,
+ 218, 1, 131, 4, 30, 30, 222, 210,
+ 96, 226, 170, 91, 162, 254, 113, 115,
+ 175, 150, 221, 67, 119, 223, 88, 174,
+ 159, 55, 7, 229, 211, 166, 128, 127,
+ 193, 161, 246, 194, 210, 100, 161, 193,
+ 99, 14, 235, 57, 251, 241, 199, 82,
+ 159, 208, 68, 77, 27, 247, 230, 74,
+ 247, 185, 165, 22, 220, 108, 179, 142,
+ 143, 19, 23, 53, 83, 50, 4, 101,
+ 71, 241, 77, 239, 237, 95, 210, 129,
+ 24, 246, 58, 177, 144, 233, 152, 55,
+ 111, 118, 91, 47, 214, 86, 213, 151,
+ 56, 46, 240, 194, 39, 200, 137, 237,
+ 251, 231, 32, 27, 13, 213, 39, 199,
+ 151, 219, 41, 69, 60, 34, 108, 100,
+ 29, 195, 218, 182, 34, 214, 100, 243,
+ 6, 30, 83, 167, 218, 223, 68, 140,
+ 125, 203, 186, 168, 7, 218, 92, 116,
+ 107, 165, 87, 232, 210, 106, 162, 17,
+ 136, 227, 19, 233, 64, 22, 173, 229,
+ 20, 4, 199, 239, 183, 65, 46, 42,
+ 17, 49, 77, 90, 48, 87, 30, 182,
+ 146, 187, 0, 61, 95, 204, 48, 78,
+ 18, 236, 162, 196, 154, 255, 243, 250,
+ 24, 108, 19, 238, 205, 18, 158, 28,
+ 231, 162, 74, 82, 44, 136, 253, 105,
+ 15, 102, 79, 33, 140, 46, 64, 201,
+ 173, 192, 170, 235, 1, 175, 149, 169,
+ 174, 117, 100, 28, 94, 140, 182, 200,
+ 249, 71, 161, 210, 41, 72, 255, 145,
+ 77, 78, 139, 234, 183, 232, 54, 73,
+ 53, 215, 156, 55, 55, 42, 36, 61,
+ 169, 188, 171, 121, 139, 42, 70, 46,
+ 208, 27, 109, 154, 35, 33, 138, 154,
+ 1, 80, 114, 254, 45, 110, 55, 228,
+ 164, 79, 58, 59, 235, 128, 41, 215,
+ 77, 178, 207, 45, 186, 113, 57, 51,
+ 122, 28, 238, 24, 97, 96, 242, 63,
+ 141, 25, 4, 187, 163, 218, 35, 89,
+ 48, 205, 5, 60, 102, 139, 200, 113,
+ 46, 217, 83, 222, 8, 79, 125, 78,
+ 105, 215, 113, 148, 182, 64, 219, 220,
+ 45, 159, 158, 204, 58, 113, 86, 250,
+ 74, 132, 192, 171, 43, 85, 45, 122,
+ 45, 252, 41, 227, 84, 142, 193, 59,
+ 87, 70, 94, 191, 32, 18, 82, 224,
+ 249, 253, 185, 92, 55, 90, 179, 228,
+ 178, 184, 244, 91, 230, 175, 32, 79,
+ 41, 124, 90, 99, 178, 48, 126, 231,
+ 190, 48, 196, 123, 187, 151, 115, 160,
+ 64, 223, 171, 229, 87, 173, 168, 242,
+ 119, 55, 227, 14, 100, 145, 11, 57,
+ 53, 94, 66, 151, 38, 231, 35, 123,
+ 193, 31, 222, 254, 17, 99, 67, 61,
+ 59, 244, 80, 135, 226, 150, 123, 46,
+ 230, 218, 54, 28, 203, 236, 59, 101,
+ 225, 60, 159, 82, 130, 0, 231, 166,
+ 214, 155, 22, 210, 105, 221, 126, 190,
+ 157, 72, 46, 133, 50, 219, 205, 68,
+ 124, 95, 110, 210, 100, 111, 168, 222,
+ 61, 127, 23, 61, 37, 72, 195, 132,
+ 164, 130, 129, 147, 246, 58, 119, 179,
+ 167, 248, 128, 98, 249, 116, 163, 137,
+ 99, 153, 182, 130, 111, 171, 16, 241,
+ 45, 205, 31, 161, 161, 137, 48, 6,
+ 161, 184, 138, 243, 209, 79, 13, 171,
+ 244, 34, 168, 219, 182, 132, 201, 69,
+ 165, 20, 231, 75, 186, 99, 66, 127,
+ 255, 22, 84, 121, 194, 134, 10, 175,
+ 50, 179, 70, 61, 120, 240, 163, 74,
+ 66, 194, 37, 31, 148, 55, 192, 36,
+ 190, 116, 247, 102, 17, 33, 19, 64,
+ 13, 45, 206, 112, 249, 41, 48, 210,
+ 138, 20, 8, 217, 41, 54, 226, 214,
+ 249, 161, 124, 51, 183, 128, 198, 108,
+ 128, 103, 178, 109, 209, 19, 147, 146,
+ 169, 253, 119, 58, 192, 203, 122, 172,
+ 96, 166, 228, 92, 76, 240, 58, 125,
+ 64, 101, 133, 25, 80, 16, 53, 243,
+ 104, 95, 198, 215, 249, 12, 77, 91,
+ 136, 86, 199, 192, 234, 27, 237, 120,
+ 140, 149, 111, 152, 207, 178, 136, 130,
+ 35, 160, 212, 139, 12, 211, 64, 192,
+ 40, 218, 72, 25, 45, 192, 83, 252,
+ 250, 114, 172, 108, 56, 178, 94, 190,
+ 101, 74, 166, 243, 227, 30, 155, 219,
+ 65, 198, 223, 48, 65, 118, 106, 210,
+ 50, 248, 208, 202, 214, 36, 128, 8,
+ 95, 38, 231, 210, 237, 219, 83, 224,
+ 118, 230, 126, 78, 0, 137, 11, 47,
+ 208, 164, 48, 61, 17, 81, 18, 58,
+ 21, 93, 119, 164, 101, 184, 181, 175,
+ 34, 206, 59, 115, 38, 132, 67, 169,
+ 243, 154, 142, 114, 144, 44, 8, 74,
+ 16, 240, 33, 98, 217, 67, 22, 72,
+ 65, 17, 220, 179, 215, 87, 96, 192,
+ 231, 207, 161, 143, 107, 190, 158, 21,
+ 251, 122, 200, 201, 83, 95, 143, 96,
+ 4, 53, 115, 132, 214, 232, 34, 55,
+ 149, 12, 177, 23, 208, 133, 53, 87,
+ 38, 98, 214, 252, 129, 196, 110, 97,
+ 252, 138, 253, 142, 186, 195, 13, 30,
+ 15, 48, 146, 107, 175, 197, 14, 79,
+ 97, 61, 240, 200, 32, 129, 65, 41,
+ 248, 153, 41, 148, 83, 241, 7, 2,
+ 124, 69, 15, 99, 194, 82, 178, 183,
+ 236, 96, 228, 187, 163, 198, 254, 147,
+ 160, 81, 104, 57, 190, 243, 75, 113,
+ 211, 169, 166, 39, 236, 91, 188, 185,
+ 68, 65, 207, 138, 77, 91, 121, 136,
+ 185, 75, 183, 103, 44, 59, 138, 236,
+ 42, 27, 227, 4, 133, 199, 240, 233,
+ 131, 172, 65, 148, 134, 141, 144, 12,
+ 82, 97, 196, 135, 217, 139, 66, 47,
+ 143, 116, 47, 210, 153, 151, 42, 202,
+ 28, 133, 190, 125, 113, 188, 46, 1,
+ 171, 82, 122, 102, 193, 126, 56, 124,
+ 190, 142, 24, 102, 194, 59, 196, 125,
+ 201, 129, 232, 21, 81, 219, 200, 242,
+ 14, 242, 246, 124, 68, 53, 30, 162,
+ 78, 144, 36, 171, 56, 200, 213, 39,
+ 136, 77, 212, 173, 57, 123, 170, 57,
+ 173, 221, 175, 72, 224, 11, 214, 242,
+ 120, 55, 180, 37, 225, 16, 17, 189,
+ 16, 138, 240, 178, 49, 105, 230, 164,
+ 50, 75, 177, 115, 175, 116, 242, 188,
+ 61, 38, 60, 141, 105, 50, 37, 51,
+ 37, 28, 152, 221, 18, 49, 211, 34,
+ 178, 215, 130, 187, 131, 89, 128, 9,
+ 86, 43, 216, 17, 141, 56, 114, 32,
+ 253, 172, 245, 214, 225, 183, 170, 35,
+ 90, 14, 52, 22, 38, 56, 246, 6,
+ 144, 129, 52, 101, 207, 181, 90, 140,
+ 216, 137, 253, 173, 33, 20, 208, 14,
+ 53, 113, 255, 105, 155, 192, 244, 25,
+ 53, 206, 172, 191, 240, 196, 231, 154,
+ 113, 244, 175, 51, 140, 13, 22, 109,
+ 152, 112, 130, 15, 72, 186, 218, 215,
+ 132, 122, 80, 49, 233, 147, 182, 17,
+ 32, 84, 107, 145, 202, 192, 198, 87,
+ 217, 14, 115, 67, 249, 83, 224, 185,
+ 67, 64, 238, 16, 36, 244, 3, 56,
+ 170, 169, 18, 174, 110, 98, 124, 178,
+ 129, 45, 236, 221, 162, 137, 35, 149,
+ 137, 56, 108, 248, 6, 28, 137, 34,
+ 146, 21, 37, 109, 39, 1, 217, 93,
+ 215, 39, 89, 66, 214, 141, 158, 190,
+ 19, 126, 16, 218, 154, 97, 185, 147,
+ 161, 21, 88, 82, 166, 135, 64, 131,
+ 196, 178, 195, 231, 220, 223, 23, 194,
+ 107, 126, 44, 155, 254, 122, 44, 174,
+ 219, 200, 166, 73, 211, 246, 140, 22,
+ 79, 187, 180, 186, 215, 96, 131, 21,
+ 43, 81, 190, 230, 232, 193, 30, 245,
+ 29, 118, 184, 143, 28, 187, 122, 141,
+ 12, 29, 247, 146, 244, 174, 65, 226,
+ 247, 80, 162, 72, 207, 16, 147, 88,
+ 11, 206, 182, 146, 114, 138, 76, 184,
+ 54, 98, 253, 251, 118, 163, 81, 44,
+ 245, 156, 229, 184, 175, 59, 81, 160,
+ 92, 16, 202, 161, 2, 133, 155, 199,
+ 24, 214, 189, 165, 102, 133, 122, 151,
+ 14, 198, 86, 114, 46, 168, 54, 66,
+ 96, 87, 234, 222, 140, 205, 176, 167,
+ 247, 153, 226, 178, 194, 86, 175, 186,
+ 136, 63, 210, 68, 207, 27, 211, 10,
+ 108, 106, 102, 221, 128, 209, 254, 243,
+ 143, 117, 45, 220, 24, 106, 10, 103,
+ 119, 66, 227, 230, 108, 7, 207, 231,
+ 190, 123, 33, 136, 13, 136, 32, 46,
+ 245, 75, 190, 236, 148, 202, 13, 109,
+ 197, 175, 142, 27, 233, 153, 64, 56,
+ 210, 180, 103, 42, 128, 48, 234, 115,
+ 178, 132, 201, 152, 180, 136, 146, 255,
+ 106, 209, 174, 46, 0, 254, 242, 130,
+ 247, 36, 1, 25, 131, 142, 245, 109,
+ 175, 147, 121, 229, 237, 188, 164, 98,
+ 222, 255, 136, 149, 29, 61, 108, 97,
+ 173, 107, 87, 236, 183, 197, 51, 248,
+ 168, 55, 82, 59, 212, 21, 77, 31,
+ 212, 59, 101, 230, 22, 1, 116, 39,
+ 171, 117, 13, 194, 74, 220, 219, 69,
+ 23, 197, 244, 244, 243, 230, 104, 96,
+ 133, 134, 160, 36, 178, 168, 21, 196,
+ 87, 209, 183, 165, 98, 6, 105, 71,
+ 71, 207, 101, 131, 193, 45, 143, 60,
+ 167, 255, 235, 162, 104, 155, 148, 60,
+ 115, 198, 1, 214, 235, 56, 87, 44,
+ 103, 205, 179, 202, 203, 63, 103, 18,
+ 136, 150, 88, 162, 126, 90, 160, 183,
+ 125, 113, 102, 90, 64, 169, 10, 143,
+ 22, 183, 219, 142, 54, 76, 17, 105,
+ 58, 242, 151, 249, 0, 106, 178, 249,
+ 201, 47, 178, 115, 161, 48, 108, 19,
+ 18, 254, 161, 9, 164, 56, 117, 233,
+ 175, 177, 135, 115, 171, 3, 47, 151,
+ 100, 24, 226, 173, 237, 84, 103, 239,
+ 133, 221, 128, 255, 90, 250, 178, 47,
+ 161, 7, 98, 163, 76, 87, 230, 253,
+ 180, 143, 30, 85, 161, 179, 28, 87,
+ 73, 225, 219, 219, 69, 248, 242, 188,
+ 235, 157, 17, 178, 226, 78, 98, 117,
+ 115, 21, 30, 195, 252, 114, 92, 11,
+ 189, 69, 184, 100, 104, 152, 47, 148,
+ 172, 142, 60, 41, 125, 228, 212, 89,
+ 55, 184, 183, 17, 12, 191, 239, 144,
+ 152, 250, 157, 234, 65, 40, 37, 218,
+ 106, 136, 221, 127, 51, 79, 166, 239,
+ 209, 172, 135, 205, 197, 184, 116, 95,
+ 253, 14, 192, 163, 241, 84, 201, 60,
+ 82, 113, 52, 49, 164, 0, 12, 201,
+ 15, 199, 44, 149, 45, 93, 242, 158,
+ 45, 105, 146, 15, 244, 200, 34, 90,
+ 18, 202, 220, 232, 168, 151, 39, 192,
+ 187, 89, 68, 134, 174, 212, 175, 25,
+ 162, 128, 0, 51, 130, 41, 25, 234,
+ 150, 29, 235, 177, 105, 221, 61, 58,
+ 72, 9, 172, 158, 242, 187, 248, 74,
+ 187, 240, 34, 198, 199, 211, 157, 172,
+ 116, 160, 54, 99, 193, 179, 82, 127,
+ 232, 123, 139, 128, 72, 107, 197, 215,
+ 161, 126, 102, 15, 166, 206, 142, 74,
+ 163, 231, 110, 28, 241, 160, 185, 92,
+ 220, 220, 15, 146, 187, 212, 190, 84,
+ 114, 94, 15, 121, 87, 148, 206, 23,
+ 32, 205, 107, 94, 26, 19, 94, 26,
+ 10, 45, 244, 187, 142, 44, 216, 76,
+ 237, 35, 135, 73, 253, 79, 207, 184,
+ 51, 190, 62, 135, 242, 184, 143, 49,
+ 175, 22, 37, 204, 154, 41, 115, 23,
+ 255, 109, 138, 123, 28, 214, 50, 14,
+ 235, 250, 141, 72, 28, 218, 47, 161,
+ 255, 15, 136, 224, 116, 67, 90, 123,
+ 73, 181, 19, 45, 65, 159, 185, 196,
+ 241, 230, 161, 48, 92, 52, 129, 111,
+ 147, 26, 100, 97, 176, 127, 55, 107,
+ 42, 105, 240, 227, 155, 43, 93, 13,
+ 36, 74, 22, 177, 218, 78, 102, 101,
+ 211, 93, 217, 245, 203, 253, 12, 247,
+ 242, 127, 200, 228, 191, 238, 143, 143,
+ 158, 39, 7, 124, 192, 26, 150, 223,
+ 148, 168, 214, 23, 182, 111, 51, 37,
+ 11, 172, 221, 57, 110, 240, 95, 242,
+ 13, 113, 210, 131, 3, 59, 166, 209,
+ 58, 43, 15, 171, 215, 52, 66, 102,
+ 177, 199, 120, 83, 161, 7, 109, 64,
+ 158, 119, 109, 56, 54, 66, 58, 45,
+ 173, 117, 90, 25, 7, 151, 38, 196,
+ 236, 243, 112, 48, 75, 226, 193, 86,
+ 254, 212, 235, 161, 16, 68, 105, 116,
+ 33, 254, 56, 167, 151, 246, 232, 246,
+ 103, 57, 189, 192, 252, 162, 116, 174,
+ 218, 233, 148, 107, 160, 227, 73, 251,
+ 194, 59, 142, 48, 56, 165, 230, 132,
+ 252, 105, 161, 216, 26, 85, 131, 48,
+ 166, 0, 26, 33, 184, 223, 163, 143,
+ 131, 244, 36, 112, 82, 20, 106, 104,
+ 61, 40, 202, 219, 31, 137, 253, 31,
+ 30, 87, 254, 149, 140, 117, 107, 211,
+ 12, 202, 138, 135, 41, 158, 76, 39,
+ 16, 165, 17, 178, 149, 223, 218, 157,
+ 216, 103, 151, 207, 117, 91, 223, 219,
+ 69, 230, 190, 217, 47, 178, 227, 138,
+ 139, 165, 198, 127, 94, 2, 146, 21,
+ 10, 47, 159, 242, 6, 113, 218, 23,
+ 64, 10, 229, 4, 141, 139, 171, 202,
+ 33, 32, 181, 66, 184, 36, 247, 3,
+ 206, 89, 224, 10, 168, 245, 28, 44,
+ 210, 227, 149, 42, 10, 228, 129, 90,
+ 193, 89, 40, 158, 249, 217, 181, 250,
+ 225, 160, 121, 169, 92, 64, 202, 85,
+ 250, 193, 64, 159, 161, 51, 73, 83,
+ 130, 34, 21, 28, 141, 104, 127, 192,
+ 202, 176, 180, 66, 206, 122, 68, 101,
+ 133, 59, 126, 54, 90, 81, 85, 36,
+ 125, 93, 103, 15, 5, 33, 77, 32,
+ 3, 153, 196, 206, 178, 52, 142, 79,
+ 168, 209, 112, 105, 67, 248, 243, 212,
+ 116, 238, 152, 244, 52, 255, 85, 79,
+ 17, 82, 241, 147, 199, 16, 100, 231,
+ 10, 31, 59, 201, 49, 176, 112, 59,
+ 235, 160, 227, 178, 44, 113, 215, 93,
+ 152, 23, 78, 169, 251, 81, 117, 242,
+ 79, 183, 199, 204, 237, 59, 91, 95,
+ 248, 188, 139, 61, 114, 0, 80, 249,
+ 203, 59, 165, 232, 225, 212, 169, 29,
+ 12, 165, 153, 206, 206, 35, 115, 132,
+ 214, 200, 91, 34, 51, 152, 128, 138,
+ 169, 229, 174, 223, 144, 1, 60, 39,
+ 200, 171, 93, 138, 251, 210, 47, 200,
+ 223, 46, 215, 210, 35, 152, 139, 219,
+ 146, 90, 39, 21, 80, 172, 11, 4,
+ 193, 76, 138, 252, 253, 77, 70, 18,
+ 77, 242, 219, 188, 144, 57, 87, 100,
+ 9, 163, 114, 64, 100, 215, 91, 50,
+ 250, 85, 120, 172, 68, 196, 79, 249,
+ 222, 141, 108, 252, 253, 58, 97, 41,
+ 213, 50, 188, 183, 137, 184, 129, 96,
+ 142, 102, 56, 92, 245, 128, 91, 238,
+ 73, 112, 134, 214, 131, 143, 147, 84,
+ 161, 43, 39, 37, 114, 185, 203, 25,
+ 12, 231, 164, 52, 110, 198, 42, 52,
+ 215, 74, 139, 239, 198, 34, 84, 78,
+ 164, 28, 201, 13, 210, 34, 27, 249,
+ 134, 243, 240, 237, 39, 137, 179, 136,
+ 187, 119, 47, 185, 114, 243, 83, 226,
+ 72, 129, 221, 211, 83, 175, 158, 232,
+ 89, 223, 182, 57, 200, 92, 177, 82,
+ 126, 166, 203, 62, 247, 195, 221, 233,
+ 209, 117, 170, 25, 223, 10, 62, 22,
+ 96, 235, 218, 161, 196, 24, 103, 11,
+ 40, 241, 255, 210, 244, 15, 9, 144,
+ 131, 115, 97, 137, 19, 198, 79, 10,
+ 130, 178, 107, 221, 209, 36, 7, 80,
+ 210, 175, 131, 215, 135, 37, 14, 103,
+ 70, 252, 54, 255, 91, 13, 96, 222,
+ 132, 80, 142, 133, 73, 38, 16, 226,
+ 88, 3, 28, 251, 5, 68, 90, 187,
+ 166, 129, 35, 231, 255, 103, 115, 155,
+ 141, 141, 96, 84, 100, 110, 254, 130,
+ 246, 87, 225, 244, 187, 10, 21, 151,
+ 73, 181, 147, 100, 137, 144, 225, 179,
+ 99, 230, 189, 69, 107, 121, 224, 39,
+ 36, 91, 90, 182, 195, 36, 2, 135,
+ 216, 102, 236, 53, 92, 109, 79, 168,
+ 171, 199, 195, 201, 13, 104, 35, 201,
+ 75, 110, 86, 86, 189, 48, 204, 90,
+ 231, 72, 156, 1, 111, 110, 240, 230,
+ 62, 32, 20, 208, 219, 240, 136, 210,
+ 135, 26, 127, 8, 153, 122, 45, 144,
+ 119, 53, 122, 229, 94, 63, 103, 139,
+ 231, 65, 248, 188, 224, 227, 106, 66,
+ 169, 149, 203, 40, 149, 229, 142, 57,
+ 1, 196, 142, 155, 3, 39, 240, 60,
+ 171, 1, 87, 20, 69, 17, 107, 83,
+ 155, 56, 57, 169, 23, 7, 238, 45,
+ 77, 98, 50, 13, 254, 134, 88, 224,
+ 251, 122, 130, 27, 150, 195, 84, 204,
+ 1, 123, 97, 192, 255, 102, 242, 218,
+ 27, 20, 208, 176, 147, 254, 65, 235,
+ 128, 76, 116, 10, 240, 126, 184, 185,
+ 126, 12, 168, 171, 210, 195, 0, 171,
+ 172, 3, 24, 93, 111, 218, 46, 202,
+ 2, 60, 229, 252, 4, 242, 32, 110,
+ 208, 3, 17, 16, 150, 239, 208, 204,
+ 70, 201, 229, 124, 63, 148, 96, 98,
+ 222, 63, 255, 255, 102, 89, 51, 79,
+ 99, 51, 228, 119, 118, 184, 163, 35,
+ 112, 229, 239, 224, 95, 24, 209, 80,
+ 92, 4, 176, 131, 71, 71, 242, 159,
+ 163, 187, 25, 136, 99, 145, 91, 94,
+ 154, 127, 124, 128, 115, 147, 1, 210,
+ 214, 232, 248, 143, 127, 79, 27, 98,
+ 44, 18, 142, 206, 98, 195, 38, 4,
+ 68, 68, 67, 169, 3, 54, 133, 233,
+ 28, 0, 120, 239, 167, 74, 110, 222,
+ 196, 180, 148, 244, 12, 222, 46, 139,
+ 143, 64, 196, 11, 83, 70, 229, 136,
+ 68, 93, 229, 73, 218, 54, 149, 47,
+ 175, 43, 171, 31, 178, 180, 135, 93,
+ 70, 62, 205, 76, 156, 184, 27, 71,
+ 90, 232, 182, 25, 221, 3, 8, 76,
+ 144, 212, 126, 129, 184, 62, 39, 67,
+ 68, 189, 172, 83, 158, 12, 235, 175,
+ 99, 248, 236, 249, 215, 6, 145, 33,
+ 97, 37, 49, 132, 202, 175, 56, 124,
+ 218, 192, 9, 228, 26, 175, 223, 142,
+ 185, 101, 133, 56, 236, 116, 210, 24,
+ 86, 36, 112, 13, 197, 224, 40, 130,
+ 106, 33, 58, 24, 27, 35, 111, 0,
+ 212, 82, 211, 139, 201, 241, 53, 121,
+ 54, 226, 54, 212, 225, 204, 124, 224,
+ 216, 197, 190, 150, 156, 45, 78, 176,
+ 214, 7, 139, 86, 6, 62, 187, 149,
+ 85, 94, 66, 93, 13, 236, 123, 53,
+ 155, 32, 88, 69, 185, 139, 163, 249,
+ 29, 142, 155, 97, 66, 106, 237, 88,
+ 121, 180, 204, 231, 11, 123, 124, 80,
+ 163, 119, 2, 204, 190, 243, 108, 163,
+ 134, 188, 145, 114, 63, 188, 156, 116,
+ 58, 248, 142, 42, 88, 167, 87, 45,
+ 52, 192, 22, 28, 91, 22, 172, 1,
+ 96, 163, 0, 13, 250, 117, 170, 69,
+ 101, 190, 3, 188, 71, 234, 228, 2,
+ 145, 45, 142, 208, 59, 40, 128, 250,
+ 174, 123, 99, 110, 234, 102, 182, 90,
+ 209, 212, 161, 95, 82, 191, 98, 233,
+ 166, 56, 170, 234, 167, 67, 184, 242,
+ 235, 121, 164, 252, 164, 251, 41, 94,
+ 30, 53, 82, 173, 196, 112, 114, 210,
+ 117, 118, 132, 126, 244, 159, 228, 74,
+ 9, 12, 200, 16, 251, 223, 226, 115,
+ 160, 47, 0, 59, 100, 229, 223, 141,
+ 8, 107, 218, 196, 42, 225, 59, 12,
+ 224, 130, 225, 51, 243, 85, 63, 229,
+ 29, 200, 179, 90, 158, 86, 73, 52,
+ 174, 83, 79, 244, 239, 24, 118, 149,
+ 202, 29, 202, 143, 0, 114, 69, 187,
+ 50, 182, 53, 41, 200, 173, 248, 1,
+ 14, 214, 231, 226, 194, 164, 24, 185,
+ 232, 232, 36, 136, 109, 76, 218, 227,
+ 79, 41, 238, 25, 251, 54, 67, 36,
+ 166, 136, 187, 174, 4, 68, 41, 71,
+ 16, 195, 30, 188, 19, 93, 146, 64,
+ 147, 227, 215, 199, 223, 86, 235, 182,
+ 211, 158, 46, 46, 161, 231, 163, 213,
+ 140, 193, 235, 180, 98, 90, 92, 106,
+ 65, 40, 11, 205, 114, 138, 67, 43,
+ 20, 56, 192, 46, 123, 86, 57, 137,
+ 179, 161, 187, 182, 237, 49, 85, 252,
+ 132, 64, 239, 244, 56, 98, 170, 186,
+ 126, 156, 89, 109, 203, 93, 157, 49,
+ 21, 236, 180, 148, 234, 214, 141, 97,
+ 0, 46, 93, 254, 230, 137, 95, 236,
+ 174, 154, 78, 176, 11, 104, 211, 21,
+ 61, 72, 22, 136, 18, 86, 130, 150,
+ 207, 144, 190, 58, 144, 201, 83, 6,
+ 167, 98, 25, 6, 55, 141, 137, 14,
+ 79, 63, 52, 109, 207, 122, 53, 179,
+ 80, 170, 24, 227, 64, 222, 15, 36,
+ 17, 197, 89, 68, 27, 168, 9, 10,
+ 56, 149, 148, 123, 4, 100, 81, 255,
+ 153, 232, 152, 164, 13, 224, 245, 51,
+ 124, 146, 26, 45, 132, 6, 157, 108,
+ 252, 187, 245, 133, 79, 162, 168, 80,
+ 178, 203, 210, 9, 150, 32, 47, 126,
+ 190, 242, 95, 47, 169, 222, 146, 227,
+ 142, 166, 137, 202, 168, 184, 221, 238,
+ 180, 14, 83, 110, 23, 33, 43, 100,
+ 249, 142, 9, 14, 115, 196, 195, 93,
+ 69, 221, 130, 144, 113, 103, 154, 23,
+ 169, 196, 241, 117, 124, 25, 133, 130,
+ 61, 50, 183, 6, 168, 80, 160, 83,
+ 31, 241, 251, 145, 178, 225, 95, 29,
+ 15, 111, 158, 72, 39, 185, 157, 43,
+ 209, 91, 37, 205, 133, 98, 81, 6,
+ 21, 105, 215, 239, 16, 60, 160, 154,
+ 40, 49, 64, 179, 119, 59, 152, 221,
+ 187, 62, 206, 63, 166, 65, 88, 2,
+ 198, 184, 46, 171, 196, 74, 204, 9,
+ 59, 242, 249, 161, 242, 146, 230, 5,
+ 247, 242, 132, 54, 23, 119, 149, 165,
+ 20, 178, 250, 33, 219, 120, 164, 117,
+ 208, 245, 195, 72, 171, 252, 3, 24,
+ 129, 89, 73, 90, 150, 54, 208, 249,
+ 43, 107, 31, 151, 210, 106, 72, 3,
+ 65, 16, 80, 247, 57, 146, 148, 91,
+ 20, 66, 237, 178, 252, 200, 210, 13,
+ 0, 249, 155, 141, 32, 7, 12, 4,
+ 247, 123, 177, 201, 64, 213, 122, 143,
+ 65, 60, 94, 58, 178, 86, 204, 156,
+ 146, 85, 158, 73, 70, 73, 98, 228,
+ 62, 135, 225, 120, 174, 127, 121, 164,
+ 16, 47, 199, 153, 4, 76, 80, 146,
+ 162, 243, 234, 35, 181, 74, 166, 186,
+ 253, 235, 157, 153, 98, 53, 66, 67,
+ 61, 216, 102, 135, 142, 155, 159, 150,
+ 17, 195, 140, 205, 162, 29, 173, 239,
+ 43, 138, 196, 119, 206, 154, 55, 201,
+ 31, 189, 7, 77, 151, 250, 222, 29,
+ 164, 134, 254, 173, 44, 166, 74, 91,
+ 139, 82, 236, 240, 61, 141, 31, 194,
+ 182, 160, 196, 122, 197, 107, 37, 34,
+ 13, 170, 68, 167, 220, 31, 99, 160,
+ 121, 223, 103, 245, 144, 47, 198, 216,
+ 156, 40, 246, 152, 182, 99, 82, 126,
+ 8, 205, 68, 18, 172, 228, 174, 205,
+ 139, 147, 224, 120, 114, 81, 110, 18,
+ 152, 151, 68, 113, 23, 98, 190, 73,
+ 156, 136, 120, 181, 67, 99, 37, 220,
+ 124, 65, 187, 129, 236, 17, 51, 65,
+ 236, 49, 216, 181, 212, 56, 216, 81,
+ 49, 152, 142, 30, 78, 21, 237, 137,
+ 178, 168, 65, 248, 92, 175, 45, 54,
+ 4, 72, 91, 8, 236, 154, 104, 244,
+ 135, 104, 224, 83, 164, 18, 37, 190,
+ 85, 153, 10, 34, 132, 66, 140, 40,
+ 176, 41, 223, 34, 133, 171, 135, 4,
+ 69, 1, 130, 110, 128, 180, 245, 226,
+ 19, 236, 161, 118, 174, 135, 216, 10,
+ 163, 49, 80, 159, 180, 162, 44, 222,
+ 135, 201, 193, 29, 204, 250, 49, 53,
+ 126, 217, 226, 206, 105, 209, 198, 77,
+ 181, 150, 233, 142, 160, 197, 132, 217,
+ 115, 126, 160, 37, 104, 244, 28, 205,
+ 247, 214, 248, 126, 41, 176, 180, 250,
+ 252, 126, 237, 109, 34, 24, 250, 13,
+ 249, 155, 17, 192, 71, 31, 42, 206,
+ 0, 80, 239, 164, 70, 114, 81, 216,
+ 161, 99, 129, 78, 72, 122, 176, 47,
+ 9, 235, 185, 35, 244, 187, 8, 190,
+ 85, 63, 205, 110, 52, 184, 145, 4,
+ 130, 35, 72, 176, 165, 194, 143, 135,
+ 93, 85, 212, 253, 174, 99, 93, 89,
+ 216, 198, 51, 86, 110, 104, 118, 111,
+ 10, 28, 220, 35, 67, 110, 60, 60,
+ 141, 124, 33, 103, 218, 43, 4, 166,
+ 10, 139, 217, 34, 156, 77, 124, 133,
+ 112, 42, 77, 66, 253, 6, 197, 26,
+ 89, 39, 149, 201, 130, 20, 24, 155,
+ 191, 8, 184, 94, 32, 176, 55, 148,
+ 234, 190, 188, 106, 205, 43, 133, 93,
+ 35, 87, 173, 28, 132, 251, 106, 117,
+ 146, 110, 146, 214, 68, 128, 189, 74,
+ 199, 232, 79, 42, 86, 91, 1, 11,
+ 151, 112, 146, 47, 124, 248, 126, 239,
+ 25, 103, 169, 166, 173, 114, 141, 230,
+ 14, 164, 109, 240, 4, 29, 185, 120,
+ 128, 57, 151, 183, 104, 159, 52, 30,
+ 221, 153, 4, 209, 252, 130, 223, 3,
+ 91, 8, 37, 170, 165, 16, 133, 24,
+ 134, 25, 239, 51, 180, 113, 187, 130,
+ 106, 186, 229, 59, 150, 152, 163, 59,
+ 171, 61, 108, 233, 225, 96, 79, 105,
+ 208, 121, 32, 206, 64, 205, 180, 194,
+ 102, 212, 196, 200, 230, 159, 23, 152,
+ 209, 105, 33, 137, 41, 93, 124, 89,
+ 243, 247, 201, 198, 72, 40, 43, 134,
+ 143, 180, 94, 4, 20, 154, 178, 57,
+ 82, 66, 117, 42, 155, 87, 218, 69,
+ 255, 228, 32, 182, 78, 242, 45, 216,
+ 22, 130, 107, 77, 174, 253, 102, 55,
+ 176, 209, 159, 224, 173, 98, 37, 139,
+ 96, 37, 238, 212, 115, 139, 35, 245,
+ 94, 127, 9, 50, 143, 12, 101, 89,
+ 81, 26, 225, 41, 81, 125, 3, 146,
+ 71, 166, 170, 191, 90, 12, 70, 153,
+ 219, 81, 123, 22, 109, 71, 140, 140,
+ 113, 145, 71, 150, 136, 182, 143, 165,
+ 40, 148, 226, 144, 142, 245, 44, 221,
+ 175, 78, 47, 221, 63, 100, 240, 80,
+ 118, 100, 56, 172, 55, 90, 79, 174,
+ 46, 55, 106, 249, 5, 107, 197, 23,
+ 49, 19, 60, 142, 11, 15, 162, 234,
+ 144, 59, 251, 85, 97, 168, 65, 28,
+ 109, 232, 255, 109, 181, 66, 206, 64,
+ 209, 25, 176, 57, 239, 126, 36, 76,
+ 225, 195, 83, 225, 215, 3, 224, 143,
+ 222, 14, 235, 42, 143, 127, 208, 70,
+ 170, 227, 143, 198, 33, 113, 31, 78,
+ 134, 240, 234, 240, 92, 33, 57, 107,
+ 126, 187, 73, 85, 101, 7, 241, 130,
+ 189, 184, 14, 112, 24, 89, 118, 227,
+ 204, 203, 56, 237, 47, 254, 63, 17,
+ 43, 219, 20, 4, 131, 167, 244, 213,
+ 153, 237, 207, 166, 169, 138, 26, 249,
+ 7, 242, 29, 172, 44, 252, 67, 238,
+ 209, 97, 39, 73, 186, 218, 40, 175,
+ 159, 137, 122, 214, 248, 49, 156, 26,
+ 213, 31, 117, 218, 226, 211, 85, 19,
+ 204, 218, 74, 98, 188, 50, 21, 226,
+ 173, 230, 212, 4, 3, 66, 83, 126,
+ 90, 111, 115, 247, 159, 148, 106, 3,
+ 240, 191, 101, 15, 153, 180, 173, 180,
+ 167, 196, 113, 157, 154, 222, 204, 158,
+ 255, 39, 112, 43, 5, 46, 221, 125,
+ 7, 129, 87, 80, 129, 30, 56, 14,
+ 46, 164, 126, 97, 52, 138, 157, 106,
+ 68, 143, 242, 174, 224, 246, 217, 135,
+ 109, 66, 71, 74, 141, 225, 95, 186,
+ 41, 157, 149, 52, 200, 50, 54, 39,
+ 231, 77, 92, 246, 170, 88, 12, 179,
+ 120, 233, 134, 33, 255, 203, 105, 105,
+ 145, 2, 45, 51, 98, 63, 189, 196,
+ 69, 157, 237, 111, 141, 198, 212, 3,
+ 167, 38, 135, 188, 70, 228, 78, 147,
+ 35, 21, 196, 164, 155, 116, 251, 105,
+ 171, 242, 61, 202, 171, 11, 198, 239,
+ 141, 34, 87, 31, 82, 137, 176, 151,
+ 228, 65, 55, 226, 58, 70, 250, 114,
+ 91, 226, 3, 2, 205, 55, 161, 50,
+ 52, 98, 149, 247, 55, 244, 184, 254,
+ 155, 137, 248, 134, 76, 32, 36, 203,
+ 241, 121, 53, 123, 96, 175, 67, 102,
+ 124, 64, 229, 128, 244, 240, 89, 5,
+ 248, 53, 0, 172, 184, 126, 110, 252,
+ 30, 117, 149, 232, 113, 34, 185, 158,
+ 223, 23, 249, 52, 123, 117, 232, 67,
+ 37, 41, 43, 249, 48, 210, 4, 57,
+ 155, 49, 40, 96, 84, 13, 11, 167,
+ 49, 41, 175, 251, 28, 64, 12, 254,
+ 119, 172, 40, 136, 56, 123, 226, 94,
+ 158, 131, 4, 249, 233, 67, 72, 65,
+ 119, 119, 36, 221, 91, 202, 198, 229,
+ 91, 241, 217, 75, 110, 39, 198, 165,
+ 189, 182, 234, 101, 219, 195, 7, 45,
+ 86, 129, 122, 171, 125, 130, 188, 87,
+ 137, 178, 18, 103, 116, 128, 40, 89,
+ 131, 50, 46, 75, 140, 153, 151, 15,
+ 188, 228, 109, 165, 33, 3, 97, 0,
+ 131, 135, 128, 106, 173, 246, 55, 175,
+ 39, 75, 40, 132, 78, 21, 251, 86,
+ 72, 34, 110, 220, 3, 202, 112, 45,
+ 228, 207, 53, 16, 212, 219, 8, 94,
+ 224, 91, 6, 132, 7, 195, 27, 164,
+ 86, 105, 208, 69, 198, 238, 71, 203,
+ 254, 44, 120, 5, 158, 54, 69, 1,
+ 230, 84, 250, 27, 31, 128, 128, 4,
+ 140, 13, 119, 36, 27, 83, 2, 41,
+ 117, 157, 34, 113, 134, 129, 216, 33,
+ 67, 177, 141, 145, 91, 203, 249, 221,
+ 172, 225, 241, 197, 161, 169, 8, 233,
+ 68, 75, 207, 214, 154, 181, 90, 177,
+ 26, 235, 49, 247, 229, 45, 248, 246,
+ 35, 156, 162, 64, 119, 188, 190, 165,
+ 249, 244, 16, 47, 176, 48, 53, 193,
+ 206, 70, 107, 134, 217, 220, 5, 122,
+ 24, 58, 171, 50, 180, 141, 174, 241,
+ 163, 49, 194, 30, 233, 226, 192, 108,
+ 77, 63, 5, 166, 80, 89, 66, 134,
+ 209, 161, 120, 18, 200, 34, 212, 239,
+ 218, 12, 3, 233, 23, 16, 6, 42,
+ 199, 105, 170, 33, 222, 157, 66, 60,
+ 48, 64, 112, 32, 81, 134, 72, 23,
+ 93, 201, 79, 41, 6, 11, 134, 159,
+ 217, 133, 183, 108, 249, 167, 153, 61,
+ 110, 48, 78, 56, 27, 219, 72, 149,
+ 213, 218, 129, 210, 43, 109, 244, 197,
+ 103, 223, 242, 186, 221, 178, 161, 124,
+ 136, 140, 117, 140, 156, 163, 206, 149,
+ 255, 169, 202, 169, 70, 137, 198, 246,
+ 55, 168, 200, 25, 160, 232, 0, 94,
+ 39, 119, 161, 167, 179, 57, 216, 178,
+ 55, 239, 91, 84, 252, 149, 210, 65,
+ 113, 192, 249, 20, 240, 57, 206, 164,
+ 127, 0, 210, 254, 107, 95, 37, 140,
+ 108, 94, 25, 247, 169, 75, 199, 80,
+ 220, 82, 222, 123, 31, 238, 132, 131,
+ 44, 247, 160, 231, 112, 54, 45, 101,
+ 13, 213, 239, 143, 119, 120, 214, 253,
+ 116, 21, 188, 111, 169, 130, 52, 108,
+ 91, 182, 11, 7, 157, 112, 177, 35,
+ 227, 220, 241, 226, 27, 234, 143, 14,
+ 15, 226, 224, 75, 171, 208, 93, 201,
+ 40, 66, 57, 227, 46, 246, 70, 34,
+ 117, 84, 207, 239, 222, 98, 229, 18,
+ 9, 170, 145, 2, 57, 103, 204, 218,
+ 176, 159, 46, 166, 30, 245, 242, 103,
+ 124, 57, 169, 83, 213, 9, 117, 209,
+ 136, 147, 155, 57, 169, 91, 126, 98,
+ 63, 49, 20, 47, 26, 170, 184, 199,
+ 170, 138, 214, 129, 82, 175, 121, 162,
+ 228, 29, 1, 47, 37, 108, 143, 4,
+ 88, 40, 24, 246, 88, 61, 80, 89,
+ 4, 149, 152, 209, 56, 5, 223, 144,
+ 47, 94, 5, 36, 25, 11, 115, 240,
+ 41, 211, 38, 251, 5, 123, 77, 213,
+ 105, 5, 62, 232, 68, 194, 37, 100,
+ 149, 169, 217, 244, 158, 86, 30, 201,
+ 83, 41, 171, 254, 174, 39, 202, 174,
+ 204, 205, 252, 34, 143, 30, 35, 123,
+ 164, 188, 178, 10, 72, 152, 242, 246,
+ 140, 37, 246, 47, 53, 21, 165, 213,
+ 51, 57, 93, 118, 130, 246, 230, 16,
+ 227, 10, 6, 12, 135, 212, 170, 20,
+ 25, 88, 65, 133, 72, 109, 209, 103,
+ 16, 234, 223, 125, 212, 243, 188, 16,
+ 58, 229, 227, 145, 185, 131, 50, 254,
+ 203, 200, 235, 122, 153, 188, 55, 219,
+ 152, 74, 85, 157, 54, 40, 31, 171,
+ 208, 199, 247, 44, 65, 231, 188, 240,
+ 41, 134, 253, 128, 118, 93, 109, 80,
+ 91, 97, 109, 245, 202, 117, 137, 163,
+ 251, 60, 194, 10, 119, 72, 176, 193,
+ 171, 138, 8, 220, 208, 140, 157, 215,
+ 188, 160, 50, 236, 112, 162, 161, 108,
+ 53, 33, 155, 53, 241, 41, 5, 157,
+ 231, 61, 218, 17, 58, 89, 5, 214,
+ 157, 149, 193, 3, 234, 166, 150, 192,
+ 71, 69, 197, 60, 153, 7, 88, 179,
+ 21, 130, 120, 67, 184, 65, 228, 224,
+ 29, 223, 234, 97, 170, 90, 27, 199,
+ 82, 90, 55, 7, 148, 49, 8, 197,
+ 101, 152, 132, 244, 151, 56, 165, 219,
+ 252, 152, 205, 191, 232, 237, 139, 115,
+ 176, 139, 156, 214, 48, 53, 12, 169,
+ 63, 0, 4, 238, 149, 44, 236, 51,
+ 120, 62, 123, 21, 28, 116, 39, 61,
+ 192, 56, 123, 51, 117, 90, 59, 88,
+ 56, 34, 132, 47, 137, 165, 108, 191,
+ 25, 81, 89, 237, 31, 40, 237, 83,
+ 236, 112, 101, 253, 53, 219, 182, 179,
+ 75, 24, 216, 192, 174, 57, 172, 92,
+ 232, 132, 91, 139, 193, 205, 119, 182,
+ 183, 187, 170, 64, 108, 89, 141, 6,
+ 68, 192, 213, 241, 102, 142, 203, 139,
+ 195, 63, 115, 233, 67, 127, 216, 16,
+ 51, 184, 231, 112, 22, 131, 66, 92,
+ 173, 6, 244, 20, 60, 42, 126, 106,
+ 219, 65, 62, 116, 80, 6, 185, 5,
+ 29, 246, 182, 101, 159, 75, 168, 144,
+ 21, 113, 252, 190, 140, 3, 186, 114,
+ 46, 217, 25, 134, 223, 108, 114, 183,
+ 119, 77, 63, 165, 51, 254, 138, 77,
+ 141, 1, 234, 46, 173, 133, 150, 201,
+ 130, 105, 218, 240, 115, 181, 18, 191,
+ 198, 187, 207, 12, 54, 180, 31, 250,
+ 59, 122, 238, 62, 69, 255, 4, 34,
+ 24, 206, 52, 211, 31, 200, 89, 110,
+ 224, 221, 155, 40, 44, 230, 88, 135,
+ 96, 121, 0, 223, 76, 190, 118, 238,
+ 59, 122, 31, 83, 82, 220, 42, 183,
+ 184, 163, 209, 127, 4, 154, 100, 230,
+ 79, 42, 26, 142, 68, 86, 22, 220,
+ 151, 103, 115, 170, 95, 126, 120, 180,
+ 46, 29, 92, 161, 160, 164, 199, 223,
+ 174, 226, 182, 213, 157, 247, 102, 70,
+ 35, 191, 231, 19, 249, 82, 218, 58,
+ 180, 180, 147, 224, 159, 21, 3, 62,
+ 185, 216, 44, 126, 90, 132, 59, 244,
+ 152, 105, 232, 237, 136, 236, 211, 35,
+ 77, 104, 246, 58, 144, 167, 131, 27,
+ 130, 246, 160, 255, 125, 246, 171, 217,
+ 247, 83, 245, 149, 58, 1, 225, 143,
+ 113, 39, 253, 155, 146, 248, 62, 98,
+ 33, 8, 27, 21, 104, 66, 124, 48,
+ 228, 120, 88, 247, 13, 16, 79, 8,
+ 225, 13, 139, 230, 106, 166, 155, 51,
+ 157, 133, 115, 251, 232, 187, 223, 45,
+ 149, 140, 198, 87, 254, 130, 157, 32,
+ 23, 183, 183, 52, 43, 214, 176, 167,
+ 250, 239, 133, 192, 194, 163, 50, 164,
+ 204, 202, 101, 248, 240, 47, 146, 179,
+ 187, 215, 236, 84, 150, 19, 68, 40,
+ 161, 250, 241, 254, 15, 95, 103, 73,
+ 87, 227, 201, 51, 218, 117, 169, 70,
+ 204, 63, 58, 34, 222, 190, 235, 129,
+ 13, 211, 43, 41, 172, 73, 106, 129,
+ 57, 240, 37, 80, 39, 215, 127, 122,
+ 105, 239, 176, 114, 21, 72, 237, 185,
+ 131, 233, 225, 210, 2, 148, 71, 3,
+ 218, 199, 28, 179, 198, 10, 51, 213,
+ 207, 193, 192, 207, 46, 150, 223, 54,
+ 26, 227, 23, 241, 103, 16, 86, 34,
+ 97, 156, 191, 157, 92, 71, 200, 214,
+ 169, 213, 254, 170, 244, 95, 224, 26,
+ 10, 47, 128, 168, 127, 255, 121, 227,
+ 210, 130, 245, 11, 84, 65, 251, 127,
+ 104, 74, 28, 31, 179, 251, 254, 217,
+ 161, 189, 112, 55, 66, 118, 75, 27,
+ 220, 156, 108, 154, 49, 16, 71, 97,
+ 69, 92, 77, 181, 197, 27, 62, 160,
+ 60, 251, 153, 245, 61, 6, 220, 134,
+ 91, 90, 5, 250, 89, 58, 84, 95,
+ 142, 15, 183, 55, 54, 175, 146, 101,
+ 232, 222, 233, 61, 126, 122, 249, 98,
+ 172, 201, 232, 155, 150, 149, 111, 16,
+ 206, 63, 118, 184, 47, 122, 150, 114,
+ 15, 123, 22, 71, 87, 159, 1, 70,
+ 163, 241, 166, 107, 135, 198, 102, 162,
+ 158, 56, 45, 107, 113, 78, 213, 48,
+ 139, 144, 139, 229, 31, 116, 211, 98,
+ 113, 41, 96, 151, 71, 218, 63, 40,
+ 6, 240, 45, 172, 39, 32, 130, 46,
+ 247, 224, 123, 18, 168, 23, 40, 246,
+ 53, 172, 101, 148, 15, 165, 23, 39,
+ 162, 184, 255, 87, 247, 248, 63, 226,
+ 211, 121, 229, 108, 50, 153, 59, 218,
+ 18, 64, 171, 29, 108, 65, 114, 253,
+ 142, 25, 254, 30, 146, 102, 200, 58,
+ 100, 197, 92, 163, 126, 189, 230, 237,
+ 221, 11, 184, 223, 255, 130, 177, 169,
+ 137, 4, 23, 191, 215, 255, 246, 44,
+ 216, 62, 210, 226, 135, 159, 198, 104,
+ 33, 32, 120, 111, 103, 166, 137, 92,
+ 214, 187, 40, 91, 244, 48, 10, 28,
+ 92, 8, 38, 146, 211, 69, 66, 209,
+ 234, 233, 7, 154, 0, 201, 4, 104,
+ 45, 138, 46, 172, 106, 80, 61, 27,
+ 38, 222, 190, 189, 64, 241, 155, 36,
+ 41, 65, 0, 215, 215, 205, 249, 210,
+ 16, 227, 198, 77, 237, 180, 29, 62,
+ 95, 215, 70, 174, 85, 222, 59, 17,
+ 205, 245, 80, 68, 116, 127, 156, 249,
+ 1, 39, 185, 141, 210, 21, 230, 209,
+ 186, 194, 92, 92, 38, 42, 147, 192,
+ 75, 121, 38, 144, 225, 31, 58, 97,
+ 63, 253, 187, 252, 238, 137, 174, 215,
+ 25, 25, 241, 200, 150, 144, 98, 115,
+ 87, 29, 107, 89, 13, 43, 105, 201,
+ 160, 230, 149, 234, 201, 4, 21, 226,
+ 216, 40, 109, 226, 97, 253, 246, 248,
+ 31, 217, 102, 57, 79, 54, 7, 194,
+ 132, 224, 61, 100, 142, 33, 226, 45,
+ 167, 206, 95, 64, 96, 155, 252, 60,
+ 58, 245, 242, 224, 105, 24, 240, 9,
+ 34, 20, 220, 114, 2, 101, 217, 49,
+ 79, 187, 20, 34, 77, 183, 128, 32,
+ 7, 156, 135, 80, 84, 106, 77, 37,
+ 77, 186, 156, 254, 251, 242, 234, 9,
+ 227, 74, 132, 211, 9, 16, 210, 87,
+ 55, 117, 217, 104, 137, 108, 154, 65,
+ 16, 111, 176, 16, 171, 167, 228, 30,
+ 20, 6, 230, 80, 104, 88, 98, 133,
+ 153, 117, 232, 235, 81, 43, 92, 171,
+ 103, 123, 157, 235, 162, 34, 67, 74,
+ 231, 110, 190, 18, 125, 202, 239, 61,
+ 248, 149, 147, 143, 129, 107, 117, 88,
+ 162, 39, 250, 3, 20, 231, 62, 118,
+ 236, 198, 46, 184, 36, 191, 1, 17,
+ 128, 48, 64, 236, 148, 120, 150, 170,
+ 176, 151, 232, 80, 169, 11, 145, 42,
+ 160, 136, 116, 197, 241, 77, 249, 96,
+ 220, 122, 101, 8, 42, 109, 184, 159,
+ 14, 204, 223, 92, 39, 22, 84, 76,
+ 225, 117, 4, 133, 240, 101, 190, 97,
+ 136, 130, 134, 155, 131, 194, 56, 37,
+ 235, 26, 210, 247, 182, 183, 200, 73,
+ 121, 186, 166, 58, 179, 74, 244, 165,
+ 61, 37, 118, 31, 43, 188, 231, 135,
+ 15, 132, 73, 58, 136, 130, 226, 191,
+ 57, 158, 166, 209, 63, 247, 151, 165,
+ 114, 81, 174, 213, 236, 64, 141, 110,
+ 228, 232, 109, 94, 195, 130, 227, 108,
+ 238, 117, 17, 148, 86, 143, 180, 160,
+ 186, 141, 133, 59, 243, 188, 5, 126,
+ 57, 223, 26, 206, 24, 13, 178, 240,
+ 21, 139, 171, 215, 148, 123, 2, 18,
+ 150, 224, 27, 163, 37, 8, 200, 1,
+ 160, 71, 24, 88, 79, 231, 140, 254,
+ 80, 255, 213, 193, 2, 143, 254, 226,
+ 203, 56, 150, 90, 221, 192, 44, 27,
+ 145, 162, 55, 141, 28, 209, 114, 45,
+ 186, 63, 123, 111, 43, 49, 176, 233,
+ 200, 227, 177, 201, 214, 137, 121, 143,
+ 26, 198, 157, 49, 172, 175, 193, 87,
+ 55, 82, 246, 28, 37, 237, 238, 143,
+ 214, 239, 71, 151, 126, 11, 9, 90,
+ 89, 46, 240, 243, 131, 130, 100, 48,
+ 104, 255, 90, 55, 248, 36, 64, 210,
+ 116, 171, 57, 86, 40, 154, 199, 130,
+ 194, 62, 173, 217, 11, 187, 164, 109,
+ 80, 2, 203, 162, 44, 165, 53, 80,
+ 22, 180, 229, 146, 66, 3, 90, 146,
+ 229, 219, 247, 29, 10, 249, 136, 95,
+ 78, 150, 45, 172, 183, 193, 27, 117,
+ 163, 148, 135, 10, 140, 241, 33, 138,
+ 137, 228, 27, 19, 56, 121, 75, 191,
+ 107, 164, 251, 35, 189, 133, 8, 203,
+ 9, 183, 145, 156, 88, 252, 106, 186,
+ 189, 137, 43, 87, 253, 50, 130, 153,
+ 77, 51, 197, 8, 11, 102, 248, 221,
+ 185, 177, 206, 217, 210, 91, 186, 9,
+ 160, 205, 122, 49, 242, 14, 131, 39,
+ 187, 66, 77, 217, 202, 236, 118, 0,
+ 228, 0, 20, 76, 198, 17, 209, 60,
+ 225, 220, 0, 189, 67, 76, 23, 33,
+ 217, 107, 8, 96, 92, 199, 129, 63,
+ 200, 243, 75, 72, 123, 254, 151, 228,
+ 23, 221, 229, 240, 87, 79, 45, 230,
+ 151, 101, 62, 17, 109, 39, 49, 209,
+ 159, 25, 75, 62, 77, 208, 248, 179,
+ 246, 67, 29, 232, 212, 74, 75, 48,
+ 48, 68, 145, 87, 105, 58, 119, 88,
+ 53, 53, 243, 55, 131, 155, 189, 150,
+ 2, 10, 106, 199, 142, 16, 79, 24,
+ 11, 87, 160, 27, 25, 176, 149, 172,
+ 137, 111, 96, 183, 6, 52, 26, 177,
+ 23, 86, 104, 213, 253, 46, 0, 160,
+ 186, 6, 68, 146, 98, 91, 14, 5,
+ 73, 102, 78, 34, 109, 185, 233, 26,
+ 95, 240, 72, 177, 236, 99, 187, 241,
+ 38, 26, 81, 213, 112, 46, 196, 199,
+ 209, 60, 3, 146, 163, 242, 11, 22,
+ 110, 14, 42, 67, 244, 137, 54, 192,
+ 47, 144, 71, 78, 130, 156, 78, 101,
+ 188, 36, 249, 247, 38, 38, 199, 129,
+ 135, 204, 94, 193, 28, 43, 48, 121,
+ 223, 46, 80, 190, 119, 97, 123, 218,
+ 203, 20, 197, 177, 21, 208, 194, 233,
+ 3, 85, 42, 155, 201, 142, 85, 38,
+ 98, 102, 249, 156, 143, 154, 177, 31,
+ 45, 87, 155, 143, 25, 79, 15, 63,
+ 207, 23, 101, 231, 132, 210, 56, 245,
+ 25, 19, 10, 49, 87, 30, 160, 39,
+ 243, 81, 19, 47, 90, 138, 4, 228,
+ 18, 99, 33, 153, 251, 118, 81, 28,
+ 48, 246, 168, 189, 142, 80, 57, 61,
+ 146, 188, 87, 33, 175, 4, 43, 142,
+ 244, 238, 138, 25, 180, 101, 132, 178,
+ 10, 165, 53, 79, 158, 174, 238, 190,
+ 213, 58, 34, 167, 121, 178, 167, 193,
+ 213, 224, 17, 105, 136, 40, 79, 67,
+ 149, 168, 215, 50, 189, 193, 165, 184,
+ 27, 61, 215, 210, 73, 154, 183, 232,
+ 223, 135, 69, 212, 37, 95, 156, 46,
+ 235, 67, 100, 19, 24, 67, 210, 199,
+ 181, 63, 89, 13, 115, 247, 170, 180,
+ 90, 143, 223, 126, 45, 27, 218, 175,
+ 234, 13, 180, 46, 224, 136, 74, 31,
+ 0, 17, 122, 3, 43, 123, 190, 84,
+ 253, 213, 7, 196, 134, 44, 228, 255,
+ 61, 20, 231, 48, 203, 130, 106, 74,
+ 209, 23, 236, 17, 112, 12, 59, 38,
+ 105, 206, 226, 250, 62, 16, 215, 141,
+ 204, 38, 52, 167, 159, 74, 254, 89,
+ 232, 200, 70, 115, 142, 104, 24, 2,
+ 15, 196, 242, 210, 91, 165, 197, 197,
+ 215, 82, 85, 128, 251, 186, 14, 11,
+ 224, 232, 172, 50, 95, 67, 67, 128,
+ 149, 125, 173, 121, 251, 102, 177, 130,
+ 154, 134, 152, 8, 21, 81, 119, 225,
+ 176, 146, 141, 203, 220, 180, 65, 14,
+ 52, 105, 17, 176, 251, 249, 82, 59,
+ 4, 74, 189, 76, 181, 205, 208, 224,
+ 164, 150, 105, 196, 106, 47, 245, 204,
+ 30, 115, 243, 239, 169, 184, 195, 164,
+ 140, 57, 108, 203, 14, 82, 211, 104,
+ 230, 147, 13, 9, 111, 32, 163, 62,
+ 197, 93, 102, 124, 205, 68, 38, 214,
+ 105, 246, 194, 158, 83, 148, 162, 215,
+ 64, 81, 2, 253, 247, 74, 134, 138,
+ 212, 146, 222, 148, 97, 50, 19, 183,
+ 78, 184, 125, 231, 23, 12, 216, 247,
+ 106, 94, 78, 247, 175, 115, 24, 164,
+ 222, 74, 22, 37, 119, 74, 179, 153,
+ 45, 58, 67, 179, 212, 120, 183, 124,
+ 218, 64, 188, 137, 206, 245, 204, 53,
+ 44, 238, 141, 224, 116, 23, 239, 47,
+ 129, 132, 130, 122, 197, 75, 214, 171,
+ 61, 27, 176, 17, 68, 87, 15, 94,
+ 22, 147, 123, 147, 159, 120, 112, 219,
+ 57, 135, 127, 47, 163, 187, 96, 62,
+ 136, 158, 196, 59, 134, 57, 211, 1,
+ 59, 127, 51, 7, 128, 55, 179, 141,
+ 206, 139, 21, 228, 217, 166, 220, 8,
+ 247, 132, 101, 218, 242, 225, 17, 146,
+ 23, 154, 20, 217, 37, 251, 166, 228,
+ 0, 176, 194, 6, 94, 110, 204, 227,
+ 119, 243, 134, 37, 158, 14, 233, 35,
+ 171, 43, 90, 253, 184, 24, 86, 223,
+ 126, 66, 126, 4, 62, 18, 19, 79,
+ 207, 2, 9, 137, 193, 116, 2, 209,
+ 92, 114, 86, 48, 214, 178, 187, 178,
+ 55, 156, 119, 105, 74, 91, 238, 6,
+ 160, 181, 143, 180, 176, 87, 59, 60,
+ 236, 174, 181, 19, 130, 78, 50, 169,
+ 156, 35, 72, 231, 245, 223, 3, 174,
+ 217, 51, 49, 234, 2, 89, 57, 184,
+ 251, 121, 126, 189, 207, 227, 50, 1,
+ 3, 13, 151, 88, 205, 207, 160, 253,
+ 111, 198, 246, 205, 128, 59, 238, 38,
+ 195, 58, 163, 238, 73, 56, 62, 223,
+ 148, 35, 216, 137, 224, 28, 89, 69,
+ 244, 169, 189, 63, 142, 192, 106, 7,
+ 42, 115, 90, 80, 48, 51, 225, 187,
+ 239, 32, 10, 13, 102, 160, 89, 84,
+ 206, 77, 10, 218, 189, 240, 242, 246,
+ 3, 155, 244, 193, 145, 50, 48, 159,
+ 102, 92, 42, 170, 230, 213, 251, 190,
+ 249, 157, 139, 213, 14, 76, 44, 192,
+ 228, 189, 70, 39, 68, 157, 227, 215,
+ 128, 62, 125, 12, 204, 55, 63, 105,
+ 221, 56, 136, 184, 236, 205, 136, 120,
+ 152, 163, 176, 23, 183, 16, 101, 51,
+ 129, 139, 101, 35, 19, 5, 252, 0,
+ 155, 143, 81, 227, 21, 69, 229, 75,
+ 168, 210, 125, 100, 57, 52, 243, 236,
+ 137, 21, 235, 249, 69, 113, 50, 23,
+ 212, 27, 67, 135, 37, 8, 223, 96,
+ 158, 28, 40, 245, 44, 107, 213, 179,
+ 235, 115, 44, 24, 230, 111, 231, 128,
+ 35, 211, 235, 163, 180, 25, 77, 206,
+ 89, 191, 227, 247, 252, 249, 249, 148,
+ 36, 118, 89, 111, 181, 154, 230, 143,
+ 98, 224, 68, 125, 178, 165, 146, 28,
+ 49, 28, 21, 91, 205, 0, 23, 236,
+ 7, 74, 210, 247, 0, 224, 64, 223,
+ 251, 35, 24, 69, 177, 134, 57, 36,
+ 152, 197, 222, 197, 52, 28, 156, 192,
+ 148, 127, 34, 214, 240, 61, 11, 101,
+ 37, 8, 255, 252, 245, 238, 131, 168,
+ 30, 120, 231, 156, 55, 30, 173, 16,
+ 240, 52, 178, 100, 10, 156, 184, 234,
+ 6, 28, 120, 69, 70, 93, 73, 81,
+ 155, 110, 102, 102, 71, 135, 102, 98,
+ 133, 157, 227, 148, 27, 85, 121, 18,
+ 216, 182, 123, 176, 204, 105, 42, 190,
+ 61, 96, 54, 38, 100, 112, 214, 251,
+ 4, 4, 0, 246, 229, 105, 17, 48,
+ 168, 144, 44, 100, 130, 48, 65, 49,
+ 102, 24, 124, 134, 35, 219, 198, 204,
+ 233, 97, 167, 237, 75, 148, 229, 129,
+ 239, 86, 189, 4, 139, 242, 84, 218,
+ 120, 91, 239, 10, 95, 217, 236, 196,
+ 123, 247, 167, 116, 222, 8, 198, 4,
+ 100, 155, 194, 38, 150, 108, 104, 108,
+ 112, 113, 104, 77, 183, 200, 249, 162,
+ 50, 95, 195, 70, 118, 183, 233, 79,
+ 103, 228, 107, 142, 105, 47, 252, 230,
+ 72, 239, 221, 40, 189, 163, 37, 21,
+ 107, 40, 44, 184, 171, 255, 217, 82,
+ 173, 157, 168, 8, 226, 207, 147, 15,
+ 6, 174, 35, 1, 10, 208, 212, 57,
+ 212, 150, 189, 83, 192, 40, 149, 5,
+ 119, 223, 45, 228, 173, 167, 73, 123,
+ 218, 157, 227, 90, 18, 252, 75, 179,
+ 151, 2, 145, 251, 42, 39, 14, 86,
+ 70, 36, 77, 10, 174, 211, 232, 84,
+ 124, 169, 97, 12, 12, 230, 56, 230,
+ 131, 43, 52, 22, 229, 121, 137, 143,
+ 62, 97, 99, 109, 62, 19, 76, 33,
+ 183, 116, 200, 137, 178, 71, 77, 196,
+ 164, 210, 182, 100, 11, 85, 208, 171,
+ 73, 45, 135, 154, 150, 226, 149, 45,
+ 48, 193, 188, 231, 15, 29, 115, 186,
+ 222, 43, 54, 228, 184, 161, 245, 113,
+ 27, 124, 137, 149, 123, 180, 154, 30,
+ 74, 126, 149, 122, 244, 125, 13, 75,
+ 173, 16, 126, 188, 207, 27, 60, 244,
+ 105, 50, 187, 109, 181, 2, 199, 108,
+ 62, 245, 90, 101, 187, 139, 55, 128,
+ 173, 52, 207, 101, 71, 221, 10, 58,
+ 252, 184, 159, 174, 204, 64, 250, 217,
+ 4, 59, 32, 216, 121, 111, 225, 252,
+ 120, 1, 151, 19, 199, 98, 128, 203,
+ 73, 222, 89, 77, 202, 216, 35, 209,
+ 226, 96, 28, 236, 8, 69, 57, 163,
+ 213, 145, 254, 179, 182, 126, 234, 40,
+ 30, 120, 222, 153, 36, 91, 220, 137,
+ 189, 141, 242, 58, 23, 34, 93, 89,
+ 17, 177, 96, 45, 109, 104, 65, 70,
+ 129, 161, 122, 243, 98, 67, 64, 184,
+ 186, 82, 101, 45, 144, 17, 220, 37,
+ 4, 93, 170, 117, 77, 113, 66, 37,
+ 133, 162, 142, 150, 219, 21, 184, 142,
+ 31, 30, 210, 136, 6, 241, 25, 55,
+ 176, 142, 39, 76, 168, 132, 13, 203,
+ 88, 75, 133, 157, 191, 29, 118, 136,
+ 58, 155, 200, 53, 158, 223, 37, 167,
+ 72, 194, 182, 25, 93, 157, 86, 17,
+ 99, 201, 246, 134, 151, 116, 153, 157,
+ 251, 166, 27, 105, 219, 30, 67, 200,
+ 107, 249, 144, 108, 129, 58, 201, 232,
+ 6, 216, 97, 103, 88, 114, 170, 90,
+ 232, 16, 92, 4, 136, 149, 97, 185,
+ 4, 138, 40, 232, 5, 124, 4, 63,
+ 218, 162, 216, 118, 86, 124, 35, 108,
+ 47, 230, 255, 93, 250, 81, 98, 197,
+ 142, 133, 12, 164, 24, 178, 79, 75,
+ 241, 13, 118, 82, 112, 179, 124, 231,
+ 225, 113, 222, 96, 155, 100, 76, 83,
+ 43, 140, 244, 77, 192, 107, 197, 174,
+ 190, 27, 31, 168, 62, 159, 88, 93,
+ 232, 16, 248, 253, 121, 126, 189, 151,
+ 58, 19, 137, 223, 92, 127, 235, 27,
+ 1, 0, 93, 88, 169, 12, 210, 96,
+ 230, 242, 151, 175, 97, 177, 252, 237,
+ 250, 113, 196, 52, 232, 100, 76, 45,
+ 159, 125, 221, 121, 221, 41, 125, 168,
+ 53, 42, 120, 56, 163, 105, 23, 214,
+ 242, 17, 186, 248, 151, 240, 77, 54,
+ 70, 62, 60, 182, 52, 242, 138, 197,
+ 216, 98, 66, 158, 29, 9, 36, 37,
+ 38, 132, 221, 135, 147, 101, 198, 173,
+ 159, 54, 230, 71, 249, 245, 227, 222,
+ 79, 19, 72, 48, 149, 225, 14, 173,
+ 43, 9, 130, 95, 137, 6, 175, 229,
+ 15, 136, 192, 99, 205, 229, 187, 173,
+ 191, 121, 113, 9, 249, 71, 125, 196,
+ 2, 63, 245, 42, 28, 167, 108, 68,
+ 166, 232, 135, 164, 174, 210, 248, 31,
+ 164, 130, 9, 157, 3, 202, 119, 23,
+ 78, 52, 124, 117, 106, 77, 44, 124,
+ 144, 216, 9, 158, 127, 141, 59, 103,
+ 112, 243, 83, 220, 227, 146, 120, 136,
+ 16, 208, 52, 1, 231, 163, 80, 16,
+ 138, 252, 5, 255, 71, 197, 137, 140,
+ 203, 193, 235, 8, 176, 28, 97, 8,
+ 241, 120, 29, 203, 158, 151, 183, 92,
+ 222, 232, 133, 136, 82, 202, 225, 47,
+ 99, 223, 84, 191, 13, 57, 181, 70,
+ 30, 39, 197, 68, 210, 14, 117, 230,
+ 217, 44, 9, 236, 127, 248, 128, 144,
+ 97, 149, 151, 126, 33, 114, 131, 13,
+ 10, 15, 15, 86, 28, 165, 49, 253,
+ 190, 170, 178, 99, 128, 225, 234, 220,
+ 85, 114, 62, 220, 116, 44, 136, 102,
+ 78, 211, 92, 175, 121, 90, 137, 237,
+ 204, 33, 225, 239, 41, 223, 37, 67,
+ 107, 48, 117, 72, 86, 204, 178, 140,
+ 185, 195, 175, 47, 39, 167, 56, 153,
+ 47, 198, 69, 103, 217, 93, 106, 117,
+ 132, 148, 235, 7, 172, 222, 219, 154,
+ 68, 247, 90, 218, 188, 166, 130, 215,
+ 74, 136, 101, 218, 6, 142, 244, 67,
+ 23, 115, 35, 156, 247, 129, 110, 59,
+ 93, 62, 45, 87, 54, 91, 158, 10,
+ 58, 176, 248, 79, 27, 206, 91, 20,
+ 215, 135, 182, 222, 134, 190, 88, 135,
+ 78, 147, 250, 212, 49, 156, 17, 150,
+ 42, 22, 29, 202, 169, 132, 30, 99,
+ 90, 180, 143, 75, 241, 116, 76, 151,
+ 32, 133, 96, 102, 244, 233, 44, 68,
+ 183, 219, 120, 111, 241, 95, 155, 248,
+ 54, 100, 187, 242, 77, 236, 246, 49,
+ 225, 218, 41, 69, 19, 110, 130, 90,
+ 225, 152, 119, 253, 188, 20, 155, 234,
+ 125, 120, 76, 126, 26, 44, 194, 237,
+ 4, 33, 236, 149, 26, 57, 156, 246,
+ 171, 58, 134, 120, 236, 57, 209, 241,
+ 119, 215, 61, 50, 28, 73, 141, 69,
+ 32, 152, 8, 249, 89, 244, 236, 35,
+ 136, 68, 54, 132, 112, 102, 151, 121,
+ 83, 124, 193, 213, 67, 198, 33, 3,
+ 155, 19, 16, 205, 226, 126, 104, 229,
+ 93, 170, 40, 67, 111, 50, 31, 36,
+ 70, 50, 200, 227, 28, 185, 176, 91,
+ 150, 28, 148, 129, 187, 140, 126, 245,
+ 204, 10, 61, 89, 162, 48, 117, 150,
+ 47, 55, 49, 139, 128, 108, 144, 25,
+ 93, 148, 24, 137, 239, 135, 0, 83,
+ 208, 146, 104, 171, 114, 147, 150, 50,
+ 69, 86, 36, 6, 132, 236, 210, 47,
+ 218, 2, 70, 181, 231, 7, 43, 114,
+ 164, 109, 80, 109, 38, 214, 50, 201,
+ 229, 122, 252, 183, 68, 194, 184, 133,
+ 144, 205, 39, 202, 250, 111, 6, 53,
+ 109, 158, 42, 170, 23, 168, 193, 31,
+ 180, 204, 86, 69, 205, 205, 33, 242,
+ 133, 237, 153, 11, 159, 54, 104, 174,
+ 5, 41, 47, 180, 160, 114, 162, 125,
+ 128, 198, 124, 100, 108, 152, 10, 174,
+ 28, 108, 217, 0, 214, 9, 210, 184,
+ 50, 47, 231, 43, 238, 167, 44, 188,
+ 137, 177, 123, 117, 229, 235, 32, 141,
+ 44, 87, 1, 24, 192, 130, 161, 85,
+ 34, 120, 190, 139, 89, 123, 109, 242,
+ 223, 121, 132, 36, 90, 195, 113, 119,
+ 160, 208, 132, 37, 152, 58, 184, 56,
+ 254, 123, 223, 75, 227, 237, 156, 184,
+ 37, 255, 255, 214, 223, 178, 106, 157,
+ 204, 179, 223, 205, 116, 161, 93, 231,
+ 152, 19, 137, 110, 90, 123, 9, 53,
+ 140, 142, 167, 104, 234, 140, 226, 4,
+ 125, 60, 200, 33, 156, 10, 253, 221,
+ 86, 218, 255, 89, 28, 142, 5, 166,
+ 118, 250, 31, 183, 242, 170, 227, 226,
+ 93, 60, 136, 107, 89, 245, 174, 212,
+ 211, 211, 169, 137, 59, 165, 66, 15,
+ 194, 161, 111, 228, 134, 227, 203, 100,
+ 119, 1, 112, 202, 69, 79, 133, 18,
+ 160, 71, 176, 154, 38, 8, 13, 139,
+ 199, 144, 177, 78, 88, 85, 50, 136,
+ 99, 98, 188, 216, 103, 109, 19, 137,
+ 131, 163, 91, 77, 248, 219, 190, 27,
+ 88, 224, 76, 166, 155, 74, 30, 241,
+ 196, 110, 247, 51, 216, 27, 42, 237,
+ 143, 255, 227, 105, 77, 25, 125, 245,
+ 246, 102, 49, 119, 198, 75, 93, 253,
+ 69, 245, 144, 183, 192, 206, 89, 33,
+ 177, 99, 177, 10, 95, 146, 27, 127,
+ 225, 157, 118, 221, 74, 94, 231, 107,
+ 14, 105, 183, 175, 139, 73, 101, 190,
+ 159, 235, 145, 45, 120, 150, 136, 77,
+ 188, 179, 230, 191, 219, 5, 243, 130,
+ 129, 101, 207, 28, 54, 179, 168, 158,
+ 5, 54, 174, 116, 191, 29, 27, 96,
+ 86, 231, 158, 95, 45, 135, 168, 90,
+ 189, 111, 121, 217, 108, 135, 7, 232,
+ 134, 252, 218, 37, 131, 107, 214, 228,
+ 78, 5, 181, 64, 138, 240, 174, 77,
+ 57, 203, 249, 113, 8, 145, 222, 155,
+ 78, 53, 245, 208, 214, 201, 75, 205,
+ 50, 2, 30, 84, 8, 176, 79, 84,
+ 139, 57, 174, 109, 139, 166, 7, 93,
+ 69, 227, 67, 112, 247, 160, 250, 184,
+ 40, 162, 124, 233, 113, 120, 96, 231,
+ 228, 190, 228, 104, 212, 170, 143, 221,
+ 226, 152, 216, 99, 83, 1, 79, 136,
+ 84, 77, 191, 200, 89, 56, 211, 34,
+ 88, 77, 30, 244, 190, 10, 215, 10,
+ 12, 43, 128, 136, 56, 136, 221, 104,
+ 162, 80, 190, 73, 239, 246, 84, 153,
+ 125, 192, 49, 40, 200, 195, 124, 165,
+ 71, 196, 173, 30, 150, 247, 222, 194,
+ 129, 102, 207, 163, 77, 220, 186, 157,
+ 53, 13, 112, 195, 197, 20, 157, 241,
+ 63, 255, 199, 33, 89, 45, 79, 167,
+ 245, 20, 9, 199, 209, 169, 180, 192,
+ 236, 108, 244, 45, 182, 147, 252, 158,
+ 238, 172, 246, 229, 220, 48, 202, 71,
+ 8, 57, 97, 42, 238, 107, 16, 88,
+ 28, 201, 232, 126, 117, 84, 22, 151,
+ 253, 204, 112, 189, 154, 84, 241, 39,
+ 52, 165, 105, 47, 67, 225, 211, 19,
+ 18, 218, 251, 85, 130, 210, 122, 111,
+ 132, 141, 84, 38, 207, 131, 68, 48,
+ 156, 145, 191, 118, 9, 5, 164, 146,
+ 63, 53, 27, 247, 39, 242, 57, 66,
+ 123, 221, 8, 247, 98, 114, 202, 231,
+ 177, 153, 23, 141, 225, 247, 143, 141,
+ 90, 202, 135, 34, 118, 104, 143, 196,
+ 106, 212, 3, 71, 40, 252, 15, 34,
+ 252, 248, 77, 208, 162, 28, 140, 16,
+ 157, 242, 24, 232, 108, 176, 225, 126,
+ 16, 208, 70, 79, 85, 249, 140, 204,
+ 2, 29, 21, 61, 47, 105, 171, 39,
+ 5, 13, 4, 103, 218, 165, 140, 61,
+ 214, 238, 123, 93, 85, 228, 114, 204,
+ 150, 30, 64, 183, 32, 176, 116, 223,
+ 179, 183, 254, 39, 35, 50, 84, 81,
+ 73, 151, 104, 10, 39, 180, 196, 98,
+ 85, 109, 86, 194, 115, 84, 210, 226,
+ 179, 249, 73, 158, 152, 36, 241, 243,
+ 17, 38, 99, 146, 251, 166, 206, 211,
+ 224, 229, 76, 38, 203, 88, 149, 108,
+ 90, 214, 51, 136, 109, 223, 171, 66,
+ 97, 162, 90, 122, 42, 159, 126, 50,
+ 233, 231, 15, 50, 101, 186, 11, 85,
+ 237, 85, 96, 135, 60, 1, 100, 185,
+ 39, 125, 64, 179, 8, 219, 189, 113,
+ 106, 179, 82, 234, 15, 0, 244, 5,
+ 43, 142, 33, 28, 195, 145, 100, 69,
+ 43, 120, 158, 106, 195, 89, 197, 31,
+ 246, 42, 178, 32, 255, 171, 237, 79,
+ 241, 75, 197, 240, 144, 14, 65, 42,
+ 18, 33, 84, 185, 115, 127, 212, 194,
+ 23, 119, 255, 60, 61, 161, 91, 130,
+ 0, 64, 244, 252, 215, 149, 6, 112,
+ 36, 118, 97, 112, 113, 101, 107, 150,
+ 37, 71, 99, 39, 185, 29, 99, 142,
+ 6, 165, 16, 211, 44, 242, 18, 8,
+ 50, 229, 5, 5, 176, 158, 237, 222,
+ 41, 239, 224, 112, 127, 192, 235, 253,
+ 30, 114, 44, 160, 31, 244, 182, 206,
+ 70, 70, 130, 192, 98, 189, 63, 63,
+ 128, 116, 112, 71, 221, 227, 84, 120,
+ 238, 80, 192, 49, 151, 2, 153, 191,
+ 6, 106, 146, 75, 105, 204, 91, 97,
+ 7, 24, 235, 24, 10, 29, 37, 88,
+ 61, 66, 71, 248, 150, 131, 98, 140,
+ 123, 92, 204, 76, 12, 247, 245, 20,
+ 135, 179, 84, 115, 104, 31, 238, 52,
+ 123, 254, 190, 32, 221, 29, 92, 220,
+ 80, 193, 9, 230, 201, 30, 150, 133,
+ 213, 150, 200, 95, 98, 252, 187, 194,
+ 44, 190, 10, 115, 64, 155, 253, 5,
+ 29, 9, 34, 45, 74, 111, 199, 5,
+ 72, 144, 136, 30, 162, 4, 145, 12,
+ 105, 53, 130, 142, 134, 124, 144, 23,
+ 203, 31, 147, 252, 27, 9, 62, 185,
+ 183, 118, 150, 116, 145, 237, 202, 27,
+ 220, 229, 203, 149, 179, 74, 207, 165,
+ 59, 3, 99, 198, 194, 126, 64, 108,
+ 43, 53, 168, 232, 132, 130, 135, 164,
+ 173, 207, 253, 71, 183, 126, 132, 204,
+ 92, 228, 3, 166, 170, 60, 73, 178,
+ 232, 106, 249, 127, 252, 140, 164, 112,
+ 144, 35, 32, 59, 69, 131, 61, 245,
+ 107, 1, 117, 6, 244, 191, 218, 182,
+ 156, 103, 253, 177, 251, 203, 113, 172,
+ 176, 20, 218, 157, 27, 91, 200, 243,
+ 40, 208, 185, 62, 192, 71, 236, 154,
+ 106, 103, 174, 101, 228, 104, 52, 144,
+ 117, 120, 30, 201, 6, 79, 1, 233,
+ 83, 77, 205, 201, 86, 250, 107, 251,
+ 31, 63, 123, 192, 68, 130, 119, 226,
+ 227, 89, 96, 85, 20, 238, 164, 65,
+ 168, 166, 87, 83, 31, 144, 61, 237,
+ 2, 221, 122, 150, 241, 185, 173, 213,
+ 166, 96, 158, 94, 166, 146, 44, 150,
+ 253, 172, 17, 245, 94, 146, 35, 153,
+ 18, 49, 251, 1, 80, 81, 59, 143,
+ 220, 169, 114, 200, 195, 46, 42, 73,
+ 137, 4, 197, 10, 140, 3, 229, 201,
+ 35, 131, 216, 237, 219, 128, 193, 106,
+ 16, 104, 188, 219, 107, 169, 151, 153,
+ 119, 241, 136, 122, 51, 224, 182, 92,
+ 188, 91, 185, 96, 242, 31, 182, 180,
+ 96, 114, 104, 198, 89, 125, 22, 40,
+ 89, 84, 85, 166, 247, 50, 193, 157,
+ 71, 185, 130, 70, 116, 159, 232, 114,
+ 119, 60, 71, 211, 215, 188, 134, 169,
+ 44, 5, 242, 206, 78, 15, 122, 139,
+ 244, 176, 140, 247, 160, 55, 209, 72,
+ 58, 194, 60, 112, 81, 7, 100, 32,
+ 123, 53, 150, 136, 168, 94, 19, 116,
+ 230, 79, 22, 111, 237, 3, 44, 134,
+ 219, 49, 215, 206, 1, 194, 96, 167,
+ 97, 228, 42, 158, 61, 38, 152, 15,
+ 76, 147, 103, 62, 251, 129, 42, 87,
+ 92, 79, 29, 108, 124, 246, 130, 118,
+ 38, 178, 170, 75, 131, 85, 157, 216,
+ 154, 215, 71, 153, 160, 4, 37, 161,
+ 215, 109, 246, 158, 253, 17, 133, 108,
+ 187, 209, 65, 46, 50, 95, 229, 193,
+ 242, 202, 152, 154, 93, 189, 101, 198,
+ 170, 212, 115, 177, 216, 113, 129, 205,
+ 97, 201, 7, 2, 131, 174, 5, 98,
+ 177, 207, 59, 184, 174, 48, 166, 205,
+ 128, 43, 118, 250, 79, 237, 197, 96,
+ 55, 127, 24, 185, 190, 228, 133, 93,
+ 202, 193, 95, 93, 111, 244, 96, 28,
+ 237, 47, 93, 144, 239, 213, 151, 138,
+ 84, 237, 135, 228, 161, 7, 205, 120,
+ 77, 193, 114, 75, 188, 61, 11, 109,
+ 54, 62, 64, 196, 114, 119, 217, 139,
+ 91, 151, 79, 254, 47, 214, 164, 36,
+ 79, 198, 193, 16, 253, 195, 35, 90,
+ 218, 242, 172, 106, 78, 212, 49, 252,
+ 189, 29, 122, 233, 222, 63, 91, 72,
+ 119, 213, 102, 86, 43, 195, 77, 161,
+ 142, 21, 250, 155, 163, 112, 233, 54,
+ 248, 106, 181, 114, 176, 188, 41, 96,
+ 158, 222, 162, 20, 140, 102, 242, 78,
+ 229, 53, 52, 99, 57, 222, 2, 82,
+ 25, 218, 234, 232, 171, 206, 41, 3,
+ 246, 162, 13, 91, 47, 96, 93, 26,
+ 55, 178, 156, 122, 185, 20, 93, 213,
+ 171, 17, 103, 147, 86, 164, 69, 212,
+ 233, 227, 127, 34, 147, 125, 180, 172,
+ 23, 205, 63, 240, 172, 213, 53, 212,
+ 178, 85, 106, 247, 93, 80, 158, 132,
+ 185, 237, 81, 139, 105, 107, 190, 215,
+ 177, 156, 133, 49, 0, 41, 45, 36,
+ 198, 212, 47, 95, 192, 29, 55, 110,
+ 32, 188, 55, 240, 5, 99, 56, 227,
+ 245, 92, 240, 70, 235, 48, 4, 238,
+ 210, 81, 116, 8, 133, 58, 230, 253,
+ 203, 10, 251, 167, 124, 178, 135, 58,
+ 143, 250, 241, 79, 159, 61, 193, 123,
+ 105, 186, 69, 175, 27, 217, 177, 99,
+ 255, 133, 182, 182, 223, 13, 49, 248,
+ 204, 252, 91, 27, 56, 112, 222, 255,
+ 188, 244, 228, 234, 77, 134, 105, 95,
+ 187, 171, 242, 221, 14, 18, 1, 211,
+ 37, 153, 162, 40, 98, 73, 71, 18,
+ 29, 24, 191, 60, 239, 118, 176, 64,
+ 58, 44, 123, 27, 88, 26, 150, 255,
+ 186, 0, 175, 202, 164, 85, 184, 184,
+ 61, 243, 169, 137, 150, 200, 193, 142,
+ 138, 229, 1, 58, 170, 136, 136, 69,
+ 57, 30, 8, 86, 220, 70, 165, 97,
+ 13, 255, 221, 235, 254, 0, 211, 248,
+ 146, 53, 93, 192, 9, 80, 98, 128,
+ 152, 88, 149, 132, 251, 171, 236, 38,
+ 83, 206, 233, 66, 93, 244, 243, 174,
+ 174, 94, 41, 205, 34, 219, 147, 208,
+ 196, 110, 247, 142, 87, 24, 166, 49,
+ 23, 24, 82, 252, 133, 14, 83, 140,
+ 170, 179, 10, 231, 45, 211, 52, 65,
+ 65, 31, 11, 9, 10, 221, 214, 105,
+ 158, 252, 188, 197, 21, 120, 249, 146,
+ 234, 127, 4, 255, 171, 151, 190, 17,
+ 224, 201, 12, 106, 94, 82, 0, 175,
+ 14, 55, 4, 39, 3, 150, 103, 43,
+ 153, 145, 31, 119, 143, 54, 103, 126,
+ 151, 234, 230, 108, 122, 205, 90, 5,
+ 185, 195, 170, 216, 171, 224, 33, 99,
+ 130, 141, 151, 162, 127, 86, 191, 94,
+ 90, 22, 220, 242, 107, 100, 246, 225,
+ 96, 100, 100, 15, 167, 101, 119, 87,
+ 33, 45, 152, 246, 72, 73, 249, 8,
+ 63, 68, 108, 111, 5, 109, 153, 51,
+ 196, 228, 91, 235, 34, 138, 9, 160,
+ 138, 113, 221, 88, 38, 128, 134, 63,
+ 3, 173, 133, 49, 17, 51, 151, 26,
+ 167, 63, 225, 97, 184, 120, 214, 49,
+ 72, 36, 23, 130, 230, 221, 190, 30,
+ 131, 232, 248, 159, 5, 124, 211, 244,
+ 34, 187, 177, 250, 68, 62, 70, 133,
+ 202, 54, 166, 172, 25, 178, 230, 171,
+ 144, 235, 215, 250, 132, 141, 46, 185,
+ 43, 8, 97, 135, 7, 141, 205, 208,
+ 126, 3, 53, 71, 122, 18, 44, 212,
+ 20, 245, 87, 16, 136, 95, 144, 216,
+ 253, 20, 150, 125, 90, 24, 55, 187,
+ 163, 155, 58, 63, 187, 143, 132, 167,
+ 98, 20, 15, 83, 145, 215, 93, 40,
+ 94, 5, 177, 202, 125, 100, 15, 159,
+ 139, 99, 93, 226, 111, 158, 88, 131,
+ 140, 237, 116, 124, 10, 215, 167, 37,
+ 41, 95, 166, 33, 51, 95, 52, 72,
+ 62, 149, 165, 46, 141, 29, 246, 244,
+ 8, 159, 29, 119, 143, 198, 129, 37,
+ 192, 251, 58, 246, 134, 10, 178, 20,
+ 41, 56, 139, 29, 245, 82, 122, 217,
+ 223, 144, 91, 216, 61, 76, 235, 119,
+ 218, 55, 25, 137, 40, 128, 4, 144,
+ 125, 242, 111, 121, 81, 249, 31, 73,
+ 168, 79, 112, 164, 4, 56, 128, 191,
+ 85, 251, 41, 182, 212, 202, 191, 200,
+ 103, 132, 252, 139, 82, 212, 250, 186,
+ 181, 240, 231, 109, 120, 42, 63, 104,
+ 161, 44, 74, 63, 146, 13, 230, 198,
+ 86, 177, 138, 199, 20, 0, 119, 81,
+ 137, 163, 45, 86, 214, 219, 107, 233,
+ 220, 75, 196, 21, 14, 46, 119, 31,
+ 110, 223, 132, 137, 194, 67, 2, 87,
+ 82, 123, 50, 6, 209, 144, 88, 192,
+ 69, 65, 205, 32, 244, 239, 169, 95,
+ 80, 55, 165, 30, 73, 136, 241, 146,
+ 191, 10, 73, 219, 232, 207, 149, 235,
+ 157, 40, 239, 4, 4, 123, 205, 87,
+ 250, 40, 126, 85, 48, 156, 133, 97,
+ 173, 113, 135, 150, 196, 59, 91, 202,
+ 170, 46, 183, 121, 189, 191, 22, 104,
+ 228, 22, 28, 237, 126, 214, 151, 220,
+ 29, 234, 11, 0, 239, 152, 248, 73,
+ 129, 38, 69, 142, 23, 8, 155, 91,
+ 101, 175, 138, 115, 66, 216, 196, 97,
+ 137, 121, 125, 129, 253, 202, 34, 29,
+ 69, 196, 25, 74, 230, 108, 206, 123,
+ 237, 116, 11, 207, 11, 102, 49, 219,
+ 10, 194, 60, 249, 184, 206, 55, 27,
+ 49, 78, 59, 185, 144, 39, 3, 33,
+ 12, 23, 23, 7, 159, 152, 225, 98,
+ 137, 206, 92, 115, 124, 24, 116, 218,
+ 137, 19, 135, 201, 162, 102, 200, 82,
+ 204, 73, 203, 201, 148, 182, 211, 25,
+ 221, 247, 65, 40, 149, 100, 223, 204,
+ 65, 76, 28, 40, 143, 192, 156, 166,
+ 104, 164, 157, 85, 36, 91, 118, 168,
+ 246, 49, 235, 124, 163, 167, 201, 213,
+ 237, 5, 12, 172, 69, 38, 137, 18,
+ 225, 62, 178, 46, 71, 187, 149, 30,
+ 50, 185, 131, 37, 140, 85, 167, 115,
+ 189, 137, 83, 231, 157, 113, 138, 103,
+ 94, 160, 201, 94, 194, 162, 111, 176,
+ 253, 26, 66, 210, 146, 46, 213, 61,
+ 225, 126, 212, 248, 83, 202, 114, 104,
+ 154, 133, 2, 166, 78, 23, 237, 219,
+ 224, 237, 153, 222, 5, 142, 161, 131,
+ 193, 115, 162, 233, 165, 58, 89, 140,
+ 70, 201, 239, 124, 209, 121, 237, 171,
+ 52, 135, 111, 12, 125, 7, 111, 205,
+ 110, 55, 149, 88, 250, 106, 26, 24,
+ 50, 117, 71, 218, 9, 222, 28, 253,
+ 124, 81, 73, 157, 103, 218, 66, 220,
+ 98, 101, 11, 89, 113, 94, 58, 26,
+ 8, 161, 128, 134, 21, 183, 58, 251,
+ 110, 17, 250, 159, 218, 52, 192, 7,
+ 208, 192, 61, 15, 136, 117, 32, 85,
+ 221, 76, 89, 214, 222, 77, 27, 137,
+ 192, 86, 175, 169, 20, 46, 71, 122,
+ 240, 55, 18, 28, 251, 23, 21, 146,
+ 227, 45, 202, 50, 12, 79, 44, 142,
+ 244, 255, 89, 202, 41, 99, 125, 134,
+ 40, 168, 47, 68, 252, 54, 50, 161,
+ 178, 172, 76, 39, 91, 28, 35, 244,
+ 181, 242, 1, 138, 255, 32, 117, 83,
+ 159, 248, 207, 174, 251, 23, 160, 97,
+ 183, 102, 16, 36, 83, 154, 21, 5,
+ 61, 79, 108, 103, 127, 148, 38, 9,
+ 54, 1, 52, 64, 144, 188, 75, 63,
+ 62, 151, 98, 139, 238, 108, 242, 26,
+ 195, 242, 55, 51, 105, 156, 61, 239,
+ 156, 233, 16, 108, 136, 171, 160, 85,
+ 72, 73, 212, 211, 244, 105, 189, 92,
+ 85, 36, 211, 206, 230, 134, 231, 159,
+ 5, 22, 58, 142, 41, 62, 67, 129,
+ 209, 61, 165, 36, 184, 222, 232, 31,
+ 33, 85, 150, 38, 226, 45, 109, 171,
+ 67, 165, 49, 31, 139, 125, 152, 91,
+ 77, 132, 184, 34, 190, 251, 235, 135,
+ 112, 129, 237, 118, 34, 194, 23, 96,
+ 170, 126, 82, 70, 176, 109, 201, 30,
+ 67, 22, 229, 203, 82, 58, 217, 223,
+ 245, 48, 190, 232, 38, 106, 235, 188,
+ 250, 159, 195, 124, 90, 67, 99, 132,
+ 217, 112, 150, 121, 167, 20, 192, 4,
+ 170, 219, 250, 134, 4, 156, 247, 68,
+ 201, 130, 164, 99, 95, 74, 210, 67,
+ 196, 178, 40, 74, 12, 36, 132, 46,
+ 173, 255, 69, 245, 98, 43, 74, 142,
+ 165, 138, 86, 169, 227, 188, 156, 145,
+ 194, 129, 105, 143, 250, 230, 163, 157,
+ 61, 1, 125, 215, 27, 126, 2, 220,
+ 76, 227, 92, 3, 23, 216, 220, 134,
+ 98, 93, 227, 231, 131, 123, 192, 138,
+ 12, 177, 20, 115, 190, 144, 211, 152,
+ 74, 115, 189, 202, 239, 116, 162, 80,
+ 79, 148, 137, 235, 23, 98, 241, 150,
+ 33, 119, 33, 4, 193, 93, 239, 177,
+ 50, 155, 43, 38, 12, 176, 78, 139,
+ 140, 9, 225, 252, 123, 126, 90, 167,
+ 138, 230, 234, 2, 218, 183, 62, 160,
+ 253, 225, 200, 76, 199, 136, 18, 30,
+ 208, 228, 88, 23, 167, 123, 20, 95,
+ 210, 144, 91, 74, 190, 97, 177, 0,
+ 149, 30, 10, 34, 133, 118, 13, 46,
+ 166, 199, 203, 141, 234, 218, 139, 190,
+ 90, 134, 172, 185, 106, 184, 67, 207,
+ 217, 186, 183, 50, 176, 11, 178, 60,
+ 35, 13, 16, 234, 162, 224, 128, 126,
+ 95, 40, 117, 60, 197, 215, 246, 198,
+ 171, 4, 27, 194, 62, 82, 177, 132,
+ 20, 111, 186, 120, 218, 139, 140, 33,
+ 64, 75, 110, 243, 106, 119, 165, 75,
+ 19, 222, 107, 86, 48, 188, 123, 213,
+ 91, 8, 194, 44, 229, 40, 248, 209,
+ 140, 68, 119, 39, 51, 229, 34, 70,
+ 84, 100, 78, 240, 209, 81, 208, 47,
+ 88, 205, 10, 207, 166, 156, 99, 14,
+ 18, 46, 241, 47, 130, 51, 183, 204,
+ 60, 246, 111, 73, 213, 97, 131, 196,
+ 16, 126, 114, 221, 84, 250, 70, 89,
+ 56, 164, 251, 44, 232, 99, 57, 149,
+ 158, 96, 141, 114, 155, 147, 101, 242,
+ 55, 174, 214, 9, 239, 17, 87, 171,
+ 16, 94, 79, 32, 114, 66, 114, 202,
+ 151, 161, 112, 22, 179, 23, 37, 56,
+ 102, 88, 135, 9, 61, 245, 193, 253,
+ 243, 98, 172, 129, 227, 102, 43, 59,
+ 186, 45, 10, 95, 90, 160, 250, 51,
+ 216, 212, 0, 233, 77, 134, 28, 186,
+ 27, 169, 27, 183, 75, 177, 163, 218,
+ 136, 95, 104, 87, 105, 193, 109, 125,
+ 219, 43, 76, 190, 1, 115, 61, 212,
+ 118, 230, 253, 177, 200, 238, 39, 142,
+ 230, 109, 119, 180, 169, 106, 104, 92,
+ 191, 107, 237, 208, 55, 98, 158, 88,
+ 134, 144, 240, 74, 235, 230, 26, 242,
+ 198, 199, 176, 253, 132, 160, 90, 117,
+ 30, 58, 242, 61, 238, 146, 109, 246,
+ 85, 189, 20, 126, 63, 172, 41, 5,
+ 49, 125, 60, 61, 176, 238, 194, 57,
+ 31, 29, 206, 151, 133, 172, 58, 32,
+ 142, 5, 186, 99, 206, 55, 147, 83,
+ 191, 172, 124, 179, 22, 180, 13, 148,
+ 36, 21, 95, 75, 49, 75, 62, 4,
+ 204, 124, 121, 253, 158, 248, 110, 141,
+ 200, 186, 247, 229, 120, 229, 219, 48,
+ 237, 2, 128, 191, 108, 149, 155, 204,
+ 74, 134, 195, 115, 98, 36, 94, 125,
+ 154, 105, 0, 133, 50, 109, 141, 28,
+ 34, 220, 64, 15, 70, 218, 46, 237,
+ 153, 22, 201, 224, 149, 162, 54, 91,
+ 112, 208, 27, 77, 152, 214, 219, 167,
+ 36, 158, 156, 58, 50, 161, 46, 247,
+ 177, 168, 142, 6, 236, 199, 247, 229,
+ 231, 104, 39, 148, 42, 197, 146, 221,
+ 99, 38, 154, 252, 33, 127, 253, 152,
+ 1, 2, 136, 186, 39, 181, 210, 244,
+ 209, 17, 32, 103, 66, 112, 93, 247,
+ 13, 215, 183, 76, 239, 38, 130, 243,
+ 195, 223, 44, 197, 156, 120, 32, 68,
+ 226, 126, 184, 235, 141, 188, 179, 100,
+ 13, 156, 163, 143, 86, 78, 51, 27,
+ 131, 171, 63, 105, 47, 194, 159, 2,
+ 41, 196, 193, 227, 99, 96, 249, 251,
+ 253, 134, 65, 105, 31, 241, 229, 183,
+ 200, 233, 80, 146, 3, 96, 88, 101,
+ 60, 244, 64, 48, 86, 217, 204, 144,
+ 111, 156, 97, 253, 118, 150, 218, 189,
+ 60, 244, 224, 109, 42, 221, 66, 79,
+ 236, 143, 31, 118, 196, 248, 19, 150,
+ 65, 128, 234, 25, 219, 122, 125, 167,
+ 108, 45, 17, 116, 213, 206, 202, 199,
+ 78, 143, 248, 23, 9, 239, 166, 110,
+ 88, 168, 59, 63, 159, 248, 93, 154,
+ 142, 207, 0, 87, 48, 252, 140, 251,
+ 152, 249, 247, 109, 4, 223, 156, 216,
+ 205, 174, 28, 70, 36, 102, 182, 162,
+ 50, 81, 199, 140, 132, 151, 46, 111,
+ 239, 217, 243, 206, 73, 199, 110, 218,
+ 8, 25, 141, 99, 50, 252, 196, 18,
+ 161, 154, 178, 188, 171, 81, 192, 24,
+ 193, 253, 60, 220, 212, 50, 204, 91,
+ 43, 43, 130, 178, 174, 59, 55, 207,
+ 200, 192, 46, 50, 17, 174, 135, 85,
+ 4, 32, 103, 139, 241, 167, 73, 124,
+ 205, 149, 34, 167, 62, 109, 220, 204,
+ 166, 153, 104, 178, 121, 232, 194, 203,
+ 228, 114, 213, 7, 4, 200, 218, 124,
+ 23, 202, 134, 49, 131, 67, 92, 30,
+ 27, 88, 52, 9, 59, 7, 99, 142,
+ 186, 60, 239, 158, 217, 16, 224, 168,
+ 105, 151, 202, 220, 138, 18, 104, 108,
+ 140, 243, 126, 112, 23, 97, 221, 171,
+ 65, 99, 10, 73, 182, 147, 95, 5,
+ 159, 8, 186, 51, 28, 223, 170, 142,
+ 1, 215, 223, 227, 171, 134, 3, 26,
+ 229, 107, 157, 32, 100, 193, 223, 251,
+ 83, 136, 145, 204, 212, 55, 197, 128,
+ 188, 172, 75, 36, 53, 21, 190, 39,
+ 191, 137, 101, 240, 3, 107, 215, 100,
+ 87, 214, 71, 94, 192, 158, 73, 139,
+ 238, 249, 66, 249, 140, 235, 241, 144,
+ 153, 83, 135, 163, 130, 44, 187, 189,
+ 148, 115, 87, 3, 137, 141, 167, 141,
+ 248, 149, 182, 26, 219, 187, 182, 9,
+ 145, 35, 239, 195, 250, 192, 64, 253,
+ 170, 245, 26, 80, 102, 37, 77, 12,
+ 150, 251, 236, 239, 90, 50, 150, 238,
+ 197, 12, 107, 43, 202, 19, 158, 141,
+ 134, 201, 194, 79, 58, 44, 189, 86,
+ 169, 49, 212, 87, 131, 63, 252, 145,
+ 5, 92, 96, 233, 119, 31, 172, 164,
+ 58, 240, 11, 230, 161, 88, 97, 243,
+ 22, 6, 201, 196, 133, 198, 196, 110,
+ 100, 126, 207, 53, 90, 167, 179, 73,
+ 69, 49, 33, 123, 173, 68, 50, 247,
+ 4, 111, 155, 101, 121, 24, 165, 44,
+ 246, 185, 8, 67, 111, 44, 131, 44,
+ 93, 50, 137, 13, 76, 73, 218, 223,
+ 60, 156, 134, 253, 28, 201, 109, 168,
+ 152, 163, 138, 44, 132, 230, 217, 240,
+ 246, 192, 133, 10, 209, 149, 4, 104,
+ 231, 182, 235, 69, 237, 161, 235, 48,
+ 98, 131, 255, 173, 241, 36, 27, 32,
+ 143, 42, 144, 9, 33, 199, 244, 234,
+ 163, 171, 238, 94, 138, 13, 58, 152,
+ 202, 84, 97, 174, 247, 210, 177, 238,
+ 139, 18, 15, 44, 246, 99, 12, 164,
+ 72, 211, 255, 131, 105, 67, 51, 42,
+ 235, 112, 123, 76, 226, 230, 79, 54,
+ 236, 216, 30, 11, 172, 152, 200, 43,
+ 175, 174, 92, 77, 114, 141, 174, 61,
+ 104, 248, 2, 36, 235, 224, 202, 110,
+ 26, 9, 103, 242, 0, 58, 211, 158,
+ 242, 84, 2, 249, 203, 125, 108, 247,
+ 9, 25, 70, 60, 160, 172, 81, 154,
+ 109, 108, 240, 90, 157, 209, 252, 231,
+ 88, 211, 32, 3, 233, 57, 111, 92,
+ 52, 82, 94, 10, 162, 107, 151, 70,
+ 245, 81, 159, 17, 159, 77, 139, 244,
+ 236, 239, 19, 255, 223, 170, 25, 51,
+ 60, 163, 150, 150, 209, 164, 67, 53,
+ 138, 140, 133, 81, 207, 59, 51, 60,
+ 86, 157, 217, 122, 38, 120, 18, 128,
+ 237, 221, 55, 213, 167, 163, 139, 227,
+ 183, 215, 218, 196, 253, 109, 201, 253,
+ 80, 174, 185, 92, 200, 95, 166, 155,
+ 237, 141, 159, 63, 141, 24, 12, 249,
+ 232, 252, 251, 219, 134, 159, 211, 15,
+ 179, 73, 223, 177, 85, 152, 206, 88,
+ 229, 107, 188, 139, 199, 250, 55, 141,
+ 42, 4, 126, 165, 29, 48, 176, 157,
+ 123, 179, 136, 48, 212, 95, 67, 250,
+ 210, 173, 113, 111, 220, 166, 164, 244,
+ 163, 92, 185, 129, 224, 135, 34, 16,
+ 158, 61, 124, 10, 34, 47, 41, 18,
+ 14, 10, 229, 108, 11, 222, 238, 161,
+ 235, 203, 124, 210, 107, 57, 146, 120,
+ 227, 159, 43, 242, 236, 35, 177, 219,
+ 223, 93, 2, 32, 80, 1, 158, 26,
+ 205, 86, 134, 91, 186, 254, 248, 202,
+ 120, 234, 89, 54, 221, 129, 118, 25,
+ 118, 47, 177, 145, 25, 59, 76, 234,
+ 40, 165, 175, 210, 2, 43, 62, 76,
+ 87, 61, 169, 181, 147, 130, 36, 15,
+ 219, 87, 42, 149, 207, 98, 218, 189,
+ 92, 136, 122, 103, 138, 59, 23, 246,
+ 84, 87, 120, 200, 202, 105, 131, 80,
+ 167, 45, 136, 67, 65, 58, 5, 125,
+ 103, 193, 247, 212, 86, 204, 230, 92,
+ 140, 61, 207, 232, 36, 113, 92, 132,
+ 42, 217, 172, 174, 217, 24, 101, 188,
+ 249, 163, 88, 236, 111, 147, 163, 126,
+ 214, 0, 149, 101, 199, 161, 94, 187,
+ 67, 190, 37, 176, 235, 3, 250, 78,
+ 166, 30, 231, 177, 26, 158, 239, 150,
+ 196, 77, 144, 210, 13, 18, 143, 247,
+ 184, 176, 133, 219, 168, 142, 235, 119,
+ 181, 132, 109, 146, 3, 95, 228, 15,
+ 232, 148, 67, 29, 53, 154, 86, 80,
+ 244, 76, 57, 168, 60, 223, 94, 53,
+ 54, 204, 49, 248, 153, 248, 179, 247,
+ 182, 219, 139, 119, 122, 116, 195, 105,
+ 136, 111, 33, 60, 218, 201, 96, 36,
+ 113, 2, 213, 226, 244, 132, 123, 51,
+ 227, 105, 68, 236, 122, 102, 221, 146,
+ 23, 133, 23, 27, 123, 96, 111, 88,
+ 237, 48, 77, 131, 29, 116, 196, 185,
+ 6, 63, 232, 37, 4, 99, 152, 207,
+ 155, 204, 196, 94, 86, 10, 1, 183,
+ 147, 31, 150, 17, 134, 74, 180, 60,
+ 172, 205, 10, 228, 174, 14, 50, 164,
+ 166, 123, 94, 82, 214, 82, 134, 106,
+ 211, 23, 4, 127, 229, 194, 85, 109,
+ 243, 11, 38, 162, 2, 114, 202, 183,
+ 231, 53, 184, 213, 74, 14, 199, 206,
+ 13, 246, 27, 32, 131, 28, 235, 135,
+ 83, 23, 118, 204, 214, 216, 144, 35,
+ 66, 217, 235, 114, 188, 113, 174, 90,
+ 40, 50, 23, 197, 212, 7, 171, 82,
+ 206, 44, 126, 85, 167, 45, 152, 107,
+ 130, 135, 6, 235, 174, 4, 114, 101,
+ 112, 151, 57, 60, 174, 120, 48, 24,
+ 77, 6, 220, 38, 53, 253, 203, 217,
+ 207, 235, 11, 143, 172, 152, 31, 114,
+ 138, 0, 205, 163, 124, 12, 47, 114,
+ 75, 55, 169, 102, 216, 134, 225, 9,
+ 60, 83, 25, 238, 245, 161, 243, 193,
+ 237, 108, 193, 105, 151, 47, 154, 29,
+ 164, 171, 150, 69, 73, 187, 33, 145,
+ 40, 98, 159, 77, 198, 247, 15, 93,
+ 99, 64, 102, 156, 153, 101, 62, 14,
+ 249, 5, 149, 66, 218, 250, 109, 248,
+ 248, 198, 105, 229, 242, 33, 147, 223,
+ 23, 193, 39, 255, 134, 103, 112, 173,
+ 1, 27, 9, 255, 160, 147, 85, 66,
+ 174, 112, 217, 113, 160, 59, 89, 253,
+ 169, 64, 133, 207, 139, 172, 61, 102,
+ 201, 104, 181, 124, 115, 130, 223, 67,
+ 131, 234, 134, 32, 133, 196, 211, 204,
+ 210, 103, 169, 132, 127, 236, 228, 221,
+ 163, 12, 242, 228, 6, 154, 122, 145,
+ 82, 122, 121, 0, 103, 216, 133, 134,
+ 162, 171, 171, 75, 223, 52, 118, 37,
+ 149, 111, 224, 129, 188, 21, 19, 188,
+ 252, 130, 81, 220, 137, 198, 45, 246,
+ 94, 20, 144, 3, 134, 102, 170, 45,
+ 24, 159, 191, 69, 10, 221, 170, 124,
+ 228, 142, 19, 146, 126, 98, 63, 226,
+ 239, 226, 199, 205, 103, 226, 115, 197,
+ 63, 185, 185, 32, 248, 126, 5, 167,
+ 83, 254, 73, 40, 93, 212, 249, 143,
+ 254, 223, 96, 29, 51, 70, 3, 0,
+ 130, 212, 177, 58, 1, 46, 36, 131,
+ 151, 39, 43, 177, 24, 194, 240, 8,
+ 167, 103, 173, 184, 149, 64, 188, 161,
+ 48, 67, 214, 84, 183, 247, 218, 202,
+ 173, 116, 66, 170, 140, 255, 197, 4,
+ 190, 120, 153, 146, 16, 21, 189, 16,
+ 14, 88, 129, 222, 178, 172, 59, 58,
+ 26, 122, 152, 203, 18, 21, 22, 152,
+ 109, 30, 89, 90, 136, 173, 48, 199,
+ 238, 26, 204, 228, 166, 150, 159, 71,
+ 175, 92, 21, 171, 235, 168, 73, 122,
+ 190, 148, 232, 160, 152, 114, 61, 234,
+ 94, 160, 74, 214, 213, 155, 159, 94,
+ 214, 111, 2, 18, 40, 230, 246, 5,
+ 93, 222, 188, 111, 27, 87, 145, 171,
+ 38, 191, 138, 156, 178, 200, 97, 206,
+ 237, 70, 160, 40, 214, 6, 205, 188,
+ 214, 162, 134, 45, 195, 99, 170, 89,
+ 182, 203, 118, 98, 10, 84, 206, 140,
+ 32, 9, 170, 66, 181, 242, 220, 58,
+ 219, 37, 252, 210, 109, 13, 107, 66,
+ 178, 180, 199, 240, 214, 204, 209, 47,
+ 13, 202, 58, 85, 173, 63, 234, 17,
+ 208, 91, 248, 171, 115, 213, 164, 145,
+ 216, 120, 161, 119, 125, 75, 7, 221,
+ 128, 7, 52, 248, 91, 5, 95, 21,
+ 225, 88, 186, 196, 24, 231, 116, 148,
+ 158, 72, 139, 64, 50, 14, 73, 36,
+ 74, 70, 24, 134, 147, 255, 65, 244,
+ 168, 112, 96, 54, 3, 213, 4, 17,
+ 220, 22, 108, 25, 88, 67, 85, 38,
+ 129, 122, 37, 153, 110, 18, 164, 124,
+ 245, 150, 14, 140, 215, 222, 188, 60,
+ 67, 119, 112, 203, 209, 48, 70, 40,
+ 128, 58, 255, 24, 255, 115, 8, 167,
+ 240, 123, 188, 238, 253, 71, 108, 182,
+ 253, 22, 156, 47, 46, 112, 100, 13,
+ 125, 222, 20, 24, 237, 241, 3, 223,
+ 246, 98, 124, 212, 24, 109, 148, 22,
+ 144, 181, 79, 189, 208, 116, 241, 230,
+ 125, 140, 24, 240, 206, 139, 199, 11,
+ 131, 243, 191, 145, 194, 8, 48, 177,
+ 235, 234, 2, 2, 118, 126, 37, 21,
+ 145, 77, 60, 58, 129, 238, 164, 162,
+ 184, 84, 132, 179, 36, 137, 150, 20,
+ 242, 7, 31, 12, 253, 0, 224, 215,
+ 57, 182, 139, 163, 17, 165, 187, 76,
+ 2, 81, 14, 223, 84, 69, 44, 170,
+ 54, 79, 63, 14, 153, 97, 109, 240,
+ 228, 163, 52, 247, 255, 48, 225, 205,
+ 184, 186, 189, 51, 177, 215, 237, 127,
+ 204, 9, 67, 197, 179, 88, 250, 178,
+ 7, 140, 64, 100, 237, 132, 152, 139,
+ 147, 178, 190, 188, 189, 158, 117, 175,
+ 101, 240, 148, 166, 75, 7, 84, 86,
+ 167, 181, 149, 233, 46, 91, 5, 60,
+ 140, 203, 218, 116, 214, 67, 52, 24,
+ 188, 241, 232, 232, 24, 250, 199, 128,
+ 58, 248, 43, 221, 181, 163, 34, 238,
+ 248, 59, 1, 180, 12, 6, 185, 192,
+ 77, 141, 241, 223, 100, 253, 136, 27,
+ 206, 141, 73, 7, 165, 27, 202, 47,
+ 32, 180, 90, 166, 174, 2, 89, 0,
+ 182, 75, 52, 99, 190, 196, 0, 140,
+ 88, 50, 167, 125, 193, 245, 14, 202,
+ 188, 165, 141, 166, 161, 105, 233, 36,
+ 28, 72, 37, 219, 126, 160, 143, 135,
+ 195, 196, 121, 133, 140, 69, 6, 83,
+ 224, 210, 178, 22, 19, 155, 183, 133,
+ 19, 92, 100, 10, 37, 239, 31, 63,
+ 244, 79, 246, 165, 168, 1, 1, 183,
+ 2, 55, 154, 88, 28, 29, 169, 1,
+ 52, 219, 89, 26, 15, 30, 232, 165,
+ 74, 216, 126, 31, 137, 114, 150, 179,
+ 251, 33, 252, 122, 27, 171, 51, 246,
+ 187, 52, 186, 70, 140, 146, 229, 198,
+ 152, 74, 97, 116, 16, 200, 78, 97,
+ 189, 34, 44, 81, 64, 96, 160, 149,
+ 229, 219, 129, 41, 43, 44, 228, 231,
+ 30, 185, 17, 46, 75, 245, 247, 44,
+ 8, 97, 123, 139, 169, 146, 55, 130,
+ 90, 217, 249, 130, 244, 139, 62, 57,
+ 90, 87, 210, 237, 153, 204, 195, 126,
+ 179, 109, 180, 64, 210, 184, 126, 23,
+ 98, 195, 55, 72, 16, 94, 191, 125,
+ 160, 204, 29, 94, 191, 95, 244, 217,
+ 181, 55, 97, 140, 185, 157, 133, 163,
+ 93, 110, 157, 232, 222, 213, 1, 9,
+ 107, 230, 114, 28, 175, 231, 105, 196,
+ 157, 150, 25, 13, 153, 215, 16, 107,
+ 194, 148, 130, 27, 232, 171, 41, 221,
+ 74, 255, 63, 18, 202, 73, 96, 194,
+ 134, 190, 6, 23, 118, 54, 179, 83,
+ 32, 61, 156, 91, 187, 175, 137, 63,
+ 119, 216, 100, 29, 187, 64, 228, 65,
+ 176, 77, 54, 20, 234, 235, 245, 96,
+ 71, 186, 214, 134, 109, 214, 155, 56,
+ 207, 232, 246, 143, 102, 119, 226, 165,
+ 58, 189, 217, 193, 108, 150, 115, 190,
+ 189, 253, 15, 218, 35, 132, 71, 205,
+ 140, 147, 170, 32, 86, 10, 94, 127,
+ 188, 89, 181, 112, 32, 170, 234, 97,
+ 57, 158, 188, 119, 184, 156, 222, 143,
+ 220, 19, 39, 18, 253, 243, 83, 155,
+ 85, 44, 178, 31, 246, 145, 202, 153,
+ 130, 120, 7, 110, 230, 201, 110, 169,
+ 102, 64, 1, 110, 4, 120, 55, 244,
+ 242, 2, 220, 0, 132, 204, 153, 38,
+ 185, 99, 132, 219, 230, 69, 196, 129,
+ 219, 144, 0, 33, 203, 181, 22, 80,
+ 238, 170, 34, 218, 119, 86, 229, 193,
+ 212, 252, 14, 12, 0, 84, 239, 69,
+ 113, 36, 68, 59, 204, 150, 48, 178,
+ 42, 50, 161, 135, 80, 190, 104, 207,
+ 15, 16, 127, 132, 252, 51, 40, 26,
+ 29, 250, 250, 127, 75, 229, 11, 196,
+ 40, 173, 137, 111, 181, 121, 251, 214,
+ 102, 103, 136, 83, 9, 31, 112, 95,
+ 9, 44, 6, 125, 212, 185, 122, 79,
+ 76, 91, 104, 104, 188, 171, 241, 99,
+ 135, 204, 7, 211, 106, 155, 77, 120,
+ 171, 76, 211, 35, 226, 74, 26, 41,
+ 58, 185, 61, 58, 109, 149, 176, 206,
+ 200, 195, 67, 143, 116, 128, 68, 109,
+ 26, 163, 19, 201, 66, 62, 20, 123,
+ 226, 107, 191, 200, 232, 88, 183, 193,
+ 237, 244, 114, 70, 255, 122, 202, 22,
+ 113, 217, 66, 254, 169, 154, 253, 133,
+ 81, 88, 44, 151, 50, 128, 249, 164,
+ 240, 196, 232, 202, 21, 47, 88, 147,
+ 76, 138, 196, 49, 199, 120, 71, 15,
+ 211, 22, 165, 26, 154, 223, 76, 103,
+ 11, 31, 232, 43, 105, 125, 249, 220,
+ 71, 6, 206, 183, 15, 199, 137, 118,
+ 106, 220, 34, 34, 156, 102, 124, 238,
+ 200, 10, 9, 178, 77, 75, 209, 34,
+ 123, 168, 64, 115, 244, 237, 146, 130,
+ 71, 47, 249, 15, 62, 151, 43, 119,
+ 2, 198, 248, 192, 57, 128, 144, 99,
+ 122, 32, 59, 213, 180, 1, 105, 116,
+ 147, 123, 166, 16, 142, 135, 99, 171,
+ 177, 128, 55, 71, 15, 152, 14, 121,
+ 86, 121, 155, 55, 158, 26, 9, 210,
+ 221, 230, 153, 231, 50, 4, 39, 162,
+ 75, 139, 255, 243, 224, 114, 245, 61,
+ 108, 102, 117, 180, 76, 119, 239, 241,
+ 184, 177, 113, 171, 44, 188, 32, 155,
+ 187, 247, 204, 129, 131, 236, 96, 244,
+ 112, 22, 38, 181, 60, 159, 74, 252,
+ 125, 180, 252, 11, 163, 178, 44, 130,
+ 252, 151, 207, 109, 136, 146, 100, 65,
+ 40, 193, 168, 219, 223, 6, 169, 245,
+ 129, 128, 116, 84, 199, 189, 250, 103,
+ 205, 67, 248, 68, 188, 171, 157, 85,
+ 7, 121, 36, 80, 13, 45, 200, 132,
+ 124, 72, 202, 78, 58, 155, 143, 255,
+ 22, 61, 242, 47, 206, 25, 22, 147,
+ 72, 68, 79, 243, 166, 210, 85, 81,
+ 233, 185, 38, 174, 64, 165, 231, 15,
+ 208, 121, 85, 52, 59, 228, 218, 91,
+ 219, 79, 164, 108, 42, 37, 140, 90,
+ 158, 150, 219, 152, 67, 224, 54, 61,
+ 182, 219, 43, 56, 102, 47, 180, 48,
+ 121, 68, 146, 204, 104, 247, 247, 14,
+ 75, 62, 109, 60, 86, 109, 0, 72,
+ 141, 220, 208, 118, 73, 159, 240, 218,
+ 147, 186, 104, 169, 78, 54, 69, 22,
+ 143, 229, 25, 84, 57, 19, 111, 75,
+ 154, 63, 172, 214, 252, 137, 228, 130,
+ 25, 245, 141, 209, 178, 232, 38, 221,
+ 184, 228, 29, 131, 179, 103, 152, 18,
+ 86, 232, 181, 29, 21, 12, 26, 102,
+ 165, 19, 79, 166, 19, 20, 92, 233,
+ 198, 151, 13, 87, 246, 231, 193, 85,
+ 15, 120, 33, 112, 167, 236, 3, 147,
+ 120, 145, 230, 32, 52, 163, 238, 137,
+ 201, 117, 76, 73, 210, 183, 57, 83,
+ 73, 214, 168, 90, 67, 105, 70, 254,
+ 227, 0, 132, 55, 159, 56, 74, 160,
+ 137, 62, 91, 112, 125, 152, 255, 164,
+ 183, 7, 173, 193, 213, 50, 27, 226,
+ 121, 135, 223, 213, 189, 126, 212, 227,
+ 92, 126, 239, 150, 131, 134, 25, 145,
+ 35, 10, 42, 95, 2, 241, 123, 69,
+ 186, 7, 80, 35, 218, 20, 104, 177,
+ 136, 48, 139, 206, 55, 126, 125, 96,
+ 96, 228, 28, 187, 243, 62, 222, 103,
+ 166, 1, 114, 240, 136, 135, 43, 227,
+ 235, 153, 90, 47, 98, 126, 96, 218,
+ 98, 65, 23, 212, 83, 39, 11, 103,
+ 229, 213, 107, 238, 116, 142, 31, 66,
+ 76, 119, 214, 217, 203, 70, 139, 70,
+ 78, 159, 195, 157, 178, 27, 204, 85,
+ 134, 17, 223, 23, 149, 18, 114, 211,
+ 184, 212, 143, 131, 193, 160, 7, 174,
+ 176, 34, 18, 154, 34, 78, 49, 28,
+ 181, 16, 64, 162, 32, 128, 91, 189,
+ 255, 22, 234, 61, 100, 112, 216, 190,
+ 147, 254, 237, 98, 240, 15, 82, 159,
+ 22, 237, 198, 146, 216, 100, 171, 250,
+ 153, 92, 250, 173, 200, 149, 234, 112,
+ 130, 97, 120, 14, 32, 147, 102, 30,
+ 243, 130, 6, 200, 104, 112, 30, 206,
+ 241, 3, 158, 193, 15, 64, 93, 19,
+ 35, 99, 5, 37, 166, 1, 191, 190,
+ 212, 190, 252, 97, 209, 169, 103, 250,
+ 249, 230, 73, 57, 73, 155, 59, 81,
+ 62, 5, 151, 112, 213, 129, 123, 20,
+ 113, 108, 25, 226, 119, 97, 210, 85,
+ 182, 47, 62, 94, 242, 89, 120, 107,
+ 238, 244, 189, 37, 149, 179, 130, 115,
+ 119, 22, 215, 230, 38, 132, 151, 186,
+ 29, 35, 72, 238, 240, 175, 109, 66,
+ 1, 253, 94, 48, 217, 65, 60, 53,
+ 28, 102, 159, 233, 132, 191, 17, 80,
+ 85, 237, 93, 51, 180, 47, 68, 181,
+ 34, 60, 30, 149, 247, 202, 31, 214,
+ 6, 68, 162, 149, 238, 102, 210, 192,
+ 181, 114, 152, 45, 225, 99, 215, 78,
+ 100, 59, 33, 72, 204, 100, 30, 60,
+ 95, 167, 150, 134, 54, 164, 230, 232,
+ 229, 68, 116, 78, 144, 204, 2, 31,
+ 133, 37, 14, 147, 83, 100, 181, 10,
+ 248, 85, 136, 61, 108, 176, 102, 137,
+ 197, 227, 120, 111, 58, 89, 47, 53,
+ 121, 28, 177, 160, 7, 217, 154, 79,
+ 194, 90, 136, 105, 205, 164, 242, 87,
+ 146, 180, 252, 201, 45, 76, 136, 231,
+ 143, 37, 172, 227, 135, 110, 86, 60,
+ 128, 245, 68, 212, 161, 164, 195, 73,
+ 111, 125, 16, 100, 200, 125, 136, 128,
+ 214, 95, 156, 8, 185, 32, 169, 110,
+ 82, 203, 58, 117, 206, 253, 51, 172,
+ 201, 123, 27, 34, 252, 150, 230, 169,
+ 3, 140, 246, 196, 104, 91, 179, 69,
+ 249, 246, 191, 236, 56, 193, 168, 56,
+ 94, 11, 238, 118, 228, 59, 119, 248,
+ 238, 51, 8, 169, 78, 17, 91, 202,
+ 72, 89, 189, 133, 3, 140, 12, 227,
+ 66, 223, 232, 161, 194, 108, 218, 45,
+ 248, 51, 168, 118, 116, 167, 84, 29,
+ 152, 180, 214, 210, 104, 79, 248, 252,
+ 136, 127, 67, 172, 7, 186, 0, 250,
+ 240, 175, 156, 213, 150, 63, 119, 213,
+ 224, 207, 69, 42, 101, 221, 214, 197,
+ 248, 0, 170, 248, 10, 102, 48, 120,
+ 209, 143, 20, 24, 164, 177, 148, 215,
+ 182, 158, 64, 2, 110, 73, 118, 111,
+ 162, 74, 193, 53, 221, 49, 79, 232,
+ 156, 115, 69, 174, 254, 246, 242, 123,
+ 250, 61, 233, 241, 172, 172, 167, 151,
+ 70, 227, 184, 78, 141, 5, 219, 188,
+ 139, 208, 251, 97, 62, 21, 218, 210,
+ 211, 126, 118, 129, 231, 23, 144, 98,
+ 241, 6, 31, 195, 117, 10, 225, 151,
+ 54, 118, 120, 231, 48, 167, 22, 184,
+ 3, 196, 250, 216, 10, 90, 66, 223,
+ 82, 152, 71, 69, 59, 46, 169, 163,
+ 225, 202, 188, 104, 21, 189, 84, 155,
+ 126, 55, 134, 20, 25, 244, 176, 60,
+ 13, 8, 105, 168, 189, 151, 106, 62,
+ 188, 50, 179, 155, 179, 67, 166, 152,
+ 159, 191, 130, 248, 2, 228, 123, 177,
+ 40, 160, 135, 184, 96, 118, 47, 51,
+ 248, 243, 203, 213, 47, 114, 81, 164,
+ 60, 132, 201, 5, 52, 221, 129, 99,
+ 46, 234, 83, 105, 38, 122, 22, 148,
+ 204, 82, 102, 127, 116, 37, 97, 110,
+ 118, 224, 136, 69, 221, 71, 133, 65,
+ 116, 40, 195, 118, 186, 97, 250, 153,
+ 88, 219, 212, 214, 186, 54, 232, 16,
+ 177, 57, 242, 82, 201, 249, 44, 37,
+ 24, 228, 186, 234, 92, 174, 83, 143,
+ 20, 222, 227, 24, 245, 119, 218, 8,
+ 243, 70, 176, 214, 81, 103, 252, 200,
+ 26, 129, 1, 117, 154, 252, 106, 225,
+ 193, 73, 143, 108, 179, 57, 123, 240,
+ 24, 220, 82, 13, 110, 105, 2, 91,
+ 55, 11, 226, 157, 212, 188, 205, 126,
+ 184, 170, 252, 198, 191, 236, 17, 42,
+ 14, 200, 179, 16, 190, 17, 161, 182,
+ 148, 120, 144, 134, 253, 216, 225, 213,
+ 28, 204, 163, 245, 92, 89, 34, 61,
+ 190, 191, 53, 208, 204, 55, 24, 218,
+ 36, 179, 32, 211, 13, 137, 121, 146,
+ 110, 193, 207, 62, 167, 170, 5, 61,
+ 73, 44, 201, 158, 91, 40, 167, 95,
+ 10, 7, 205, 140, 120, 138, 180, 195,
+ 139, 63, 79, 14, 31, 193, 119, 11,
+ 132, 20, 154, 152, 113, 83, 40, 68,
+ 16, 180, 169, 6, 95, 130, 191, 126,
+ 61, 115, 67, 16, 71, 96, 59, 95,
+ 19, 51, 7, 21, 158, 24, 170, 25,
+ 219, 170, 232, 144, 58, 64, 125, 198,
+ 242, 188, 90, 181, 222, 133, 229, 240,
+ 247, 196, 81, 202, 84, 8, 203, 87,
+ 150, 230, 244, 20, 213, 77, 89, 221,
+ 242, 140, 37, 150, 234, 18, 86, 103,
+ 28, 197, 204, 44, 174, 109, 235, 41,
+ 156, 224, 240, 55, 152, 211, 51, 70,
+ 121, 129, 150, 52, 76, 247, 16, 235,
+ 150, 127, 15, 74, 138, 8, 207, 194,
+ 126, 217, 143, 109, 243, 217, 201, 193,
+ 133, 215, 161, 245, 254, 202, 33, 184,
+ 159, 147, 167, 125, 203, 36, 2, 244,
+ 129, 166, 61, 39, 57, 144, 248, 20,
+ 218, 166, 210, 128, 238, 218, 3, 160,
+ 128, 112, 168, 64, 20, 71, 141, 7,
+ 136, 30, 82, 159, 150, 167, 147, 41,
+ 169, 185, 3, 142, 150, 101, 39, 165,
+ 127, 14, 124, 112, 73, 19, 212, 90,
+ 49, 210, 199, 198, 144, 178, 107, 10,
+ 157, 69, 194, 142, 178, 181, 169, 43,
+ 209, 15, 54, 112, 1, 249, 13, 232,
+ 142, 96, 225, 207, 169, 173, 77, 206,
+ 62, 231, 39, 60, 131, 16, 24, 160,
+ 190, 17, 177, 71, 238, 129, 171, 85,
+ 14, 18, 160, 54, 155, 195, 105, 232,
+ 247, 115, 227, 45, 64, 21, 111, 160,
+ 114, 58, 1, 145, 67, 175, 185, 87,
+ 156, 95, 237, 160, 86, 255, 42, 252,
+ 11, 66, 179, 180, 173, 187, 163, 50,
+ 146, 115, 67, 236, 154, 231, 182, 245,
+ 220, 4, 64, 195, 212, 236, 141, 76,
+ 93, 15, 86, 69, 199, 115, 200, 215,
+ 233, 138, 192, 92, 31, 137, 113, 105,
+ 220, 192, 238, 47, 68, 180, 84, 199,
+ 2, 3, 149, 217, 136, 65, 153, 54,
+ 150, 131, 36, 122, 122, 165, 162, 174,
+ 240, 164, 88, 6, 194, 102, 152, 43,
+ 158, 225, 206, 104, 80, 7, 252, 216,
+ 221, 29, 225, 182, 162, 47, 124, 217,
+ 232, 63, 133, 76, 192, 136, 96, 74,
+ 212, 149, 242, 18, 155, 13, 118, 82,
+ 19, 2, 49, 117, 41, 126, 70, 72,
+ 76, 225, 186, 66, 132, 30, 84, 234,
+ 110, 146, 13, 136, 45, 207, 126, 111,
+ 19, 108, 114, 53, 155, 52, 95, 254,
+ 224, 174, 23, 104, 111, 108, 68, 33,
+ 63, 33, 215, 121, 169, 37, 255, 232,
+ 40, 173, 250, 186, 67, 164, 238, 195,
+ 88, 74, 93, 248, 5, 123, 206, 226,
+ 228, 21, 139, 181, 52, 122, 194, 14,
+ 240, 170, 237, 113, 143, 228, 206, 60,
+ 207, 221, 101, 147, 99, 225, 80, 99,
+ 207, 66, 119, 19, 72, 167, 165, 133,
+ 52, 76, 181, 36, 145, 213, 247, 55,
+ 88, 47, 169, 83, 121, 121, 98, 138,
+ 56, 50, 237, 49, 213, 196, 135, 223,
+ 42, 135, 128, 133, 1, 207, 178, 150,
+ 172, 55, 237, 33, 155, 94, 109, 93,
+ 7, 245, 102, 246, 218, 169, 230, 181,
+ 147, 249, 140, 239, 209, 33, 133, 85,
+ 151, 15, 35, 107, 19, 184, 62, 114,
+ 191, 116, 153, 42, 0, 248, 48, 136,
+ 184, 98, 182, 47, 169, 11, 149, 206,
+ 0, 238, 31, 245, 185, 64, 32, 75,
+ 210, 83, 216, 218, 170, 92, 242, 158,
+ 214, 195, 229, 128, 222, 75, 169, 177,
+ 166, 13, 3, 222, 135, 109, 35, 183,
+ 176, 61, 45, 254, 32, 165, 251, 147,
+ 162, 198, 50, 69, 253, 60, 175, 110,
+ 226, 124, 166, 167, 159, 207, 88, 17,
+ 115, 42, 89, 3, 14, 164, 114, 115,
+ 97, 129, 118, 47, 112, 145, 220, 175,
+ 2, 219, 181, 95, 187, 174, 77, 35,
+ 231, 204, 76, 43, 119, 32, 209, 120,
+ 133, 137, 103, 239, 93, 129, 56, 233,
+ 38, 83, 82, 114, 24, 19, 167, 73,
+ 16, 66, 135, 133, 193, 112, 222, 193,
+ 62, 229, 140, 44, 252, 84, 102, 218,
+ 4, 94, 97, 111, 19, 133, 249, 90,
+ 219, 81, 129, 242, 131, 96, 15, 17,
+ 236, 161, 1, 188, 106, 183, 219, 195,
+ 143, 220, 7, 127, 159, 113, 233, 110,
+ 248, 95, 79, 172, 45, 102, 79, 118,
+ 201, 28, 143, 167, 187, 98, 172, 188,
+ 255, 134, 11, 204, 61, 28, 222, 28,
+ 1, 142, 186, 182, 11, 114, 76, 80,
+ 174, 15, 127, 146, 24, 17, 108, 71,
+ 153, 27, 13, 145, 241, 1, 18, 255,
+ 161, 162, 94, 201, 129, 93, 32, 175,
+ 139, 147, 18, 178, 36, 13, 124, 116,
+ 212, 35, 208, 254, 100, 180, 42, 244,
+ 16, 159, 71, 3, 102, 18, 207, 206,
+ 85, 97, 45, 107, 135, 101, 130, 131,
+ 18, 204, 131, 142, 0, 77, 157, 76,
+ 91, 218, 109, 134, 151, 3, 75, 228,
+ 255, 13, 159, 144, 146, 164, 164, 69,
+ 231, 70, 16, 145, 238, 14, 190, 74,
+ 222, 241, 163, 200, 213, 82, 198, 154,
+ 190, 142, 140, 241, 165, 208, 196, 213,
+ 117, 188, 192, 38, 57, 8, 215, 45,
+ 142, 188, 39, 175, 20, 151, 27, 45,
+ 249, 124, 11, 12, 89, 247, 67, 159,
+ 121, 231, 109, 5, 9, 84, 57, 57,
+ 70, 229, 118, 8, 173, 81, 151, 126,
+ 197, 213, 103, 86, 101, 35, 110, 76,
+ 61, 225, 169, 127, 209, 152, 51, 241,
+ 128, 13, 254, 164, 116, 57, 14, 131,
+ 64, 0, 39, 96, 105, 64, 109, 251,
+ 183, 223, 142, 163, 58, 85, 130, 124,
+ 249, 5, 18, 107, 99, 167, 70, 192,
+ 167, 21, 26, 36, 120, 177, 234, 49,
+ 23, 142, 151, 68, 150, 45, 172, 113,
+ 71, 174, 4, 105, 141, 251, 71, 133,
+ 103, 17, 144, 97, 250, 45, 30, 159,
+ 172, 171, 80, 196, 253, 12, 143, 208,
+ 209, 248, 88, 193, 2, 112, 108, 36,
+ 3, 145, 53, 111, 196, 71, 196, 189,
+ 194, 212, 64, 164, 75, 146, 82, 250,
+ 16, 43, 79, 199, 121, 100, 150, 173,
+ 60, 211, 24, 175, 221, 137, 251, 67,
+ 241, 246, 96, 237, 233, 48, 182, 29,
+ 46, 191, 33, 27, 72, 103, 6, 179,
+ 95, 175, 115, 113, 125, 13, 221, 174,
+ 167, 255, 193, 196, 52, 161, 197, 200,
+ 90, 143, 255, 196, 11, 207, 141, 80,
+ 36, 101, 9, 85, 231, 58, 53, 69,
+ 112, 191, 135, 0, 101, 251, 169, 229,
+ 185, 209, 129, 94, 231, 227, 38, 24,
+ 15, 111, 93, 70, 119, 45, 75, 122,
+ 57, 90, 117, 190, 37, 44, 223, 62,
+ 238, 98, 211, 81, 94, 60, 235, 146,
+ 146, 84, 24, 77, 238, 179, 124, 215,
+ 102, 102, 42, 53, 5, 147, 227, 8,
+ 110, 120, 205, 181, 239, 37, 106, 219,
+ 155, 34, 35, 136, 132, 45, 19, 204,
+ 158, 31, 125, 101, 73, 111, 136, 151,
+ 7, 100, 170, 33, 79, 155, 21, 78,
+ 169, 31, 221, 2, 46, 14, 77, 59,
+ 157, 113, 194, 33, 94, 74, 221, 111,
+ 196, 221, 43, 25, 205, 74, 33, 136,
+ 238, 24, 78, 84, 231, 203, 211, 66,
+ 186, 135, 61, 45, 82, 189, 152, 51,
+ 86, 121, 2, 134, 179, 199, 147, 49,
+ 81, 206, 51, 125, 236, 117, 13, 20,
+ 120, 35, 69, 149, 48, 70, 148, 62,
+ 93, 58, 61, 108, 122, 200, 4, 162,
+ 19, 214, 248, 86, 160, 126, 237, 178,
+ 143, 186, 212, 162, 236, 14, 151, 134,
+ 158, 237, 66, 42, 245, 201, 11, 197,
+ 77, 139, 184, 11, 200, 97, 149, 236,
+ 101, 103, 238, 162, 105, 252, 46, 127,
+ 78, 130, 255, 236, 97, 111, 131, 252,
+ 32, 102, 251, 44, 114, 7, 69, 163,
+ 222, 27, 135, 2, 203, 207, 113, 132,
+ 91, 83, 170, 75, 201, 183, 105, 249,
+ 180, 137, 44, 24, 39, 190, 68, 227,
+ 209, 20, 62, 51, 253, 9, 207, 29,
+ 168, 97, 108, 53, 151, 45, 25, 127,
+ 230, 213, 119, 224, 221, 12, 140, 218,
+ 93, 92, 73, 171, 26, 158, 154, 187,
+ 33, 29, 73, 187, 194, 8, 171, 137,
+ 165, 45, 47, 250, 202, 59, 191, 27,
+ 110, 25, 101, 46, 230, 80, 74, 254,
+ 136, 180, 205, 244, 179, 248, 220, 174,
+ 194, 0, 52, 50, 59, 10, 39, 208,
+ 49, 158, 211, 106, 152, 177, 48, 23,
+ 236, 100, 68, 34, 46, 186, 149, 242,
+ 79, 153, 68, 95, 253, 152, 83, 116,
+ 145, 219, 150, 89, 97, 13, 150, 59,
+ 105, 153, 147, 94, 153, 89, 116, 227,
+ 252, 97, 144, 118, 198, 16, 15, 152,
+ 76, 26, 15, 195, 187, 152, 70, 9,
+ 10, 62, 113, 172, 183, 223, 175, 225,
+ 127, 82, 189, 85, 7, 55, 78, 59,
+ 159, 228, 6, 52, 239, 132, 118, 198,
+ 95, 163, 3, 0, 152, 236, 97, 243,
+ 206, 101, 190, 32, 45, 196, 255, 105,
+ 2, 150, 244, 141, 230, 90, 62, 58,
+ 156, 45, 163, 106, 123, 139, 35, 112,
+ 138, 153, 92, 24, 177, 248, 1, 11,
+ 74, 187, 104, 31, 255, 174, 144, 15,
+ 97, 31, 117, 124, 179, 2, 62, 221,
+ 194, 200, 253, 236, 112, 231, 174, 13,
+ 177, 180, 181, 77, 58, 155, 142, 92,
+ 193, 127, 160, 205, 145, 145, 250, 252,
+ 146, 134, 20, 250, 85, 147, 206, 107,
+ 152, 60, 166, 34, 173, 208, 65, 203,
+ 101, 194, 219, 140, 132, 134, 146, 220,
+ 152, 1, 32, 32, 207, 95, 110, 208,
+ 239, 101, 225, 149, 151, 213, 179, 118,
+ 62, 60, 40, 153, 129, 47, 61, 239,
+ 163, 88, 166, 224, 123, 10, 102, 40,
+ 168, 72, 21, 166, 56, 50, 47, 194,
+ 73, 93, 88, 174, 66, 16, 124, 21,
+ 81, 248, 26, 199, 152, 218, 166, 11,
+ 206, 169, 54, 186, 65, 211, 176, 73,
+ 74, 107, 139, 90, 185, 40, 248, 232,
+ 77, 47, 196, 91, 49, 229, 91, 154,
+ 214, 255, 153, 26, 74, 135, 118, 26,
+ 115, 26, 250, 118, 129, 231, 16, 184,
+ 0, 22, 189, 245, 40, 87, 25, 98,
+ 192, 24, 198, 8, 25, 150, 171, 252,
+ 244, 15, 214, 111, 73, 239, 251, 201,
+ 115, 169, 100, 165, 121, 42, 115, 189,
+ 40, 179, 14, 200, 240, 233, 209, 31,
+ 78, 18, 110, 160, 134, 226, 125, 83,
+ 83, 236, 7, 81, 216, 78, 105, 220,
+ 246, 241, 103, 233, 208, 225, 153, 154,
+ 176, 109, 99, 139, 227, 253, 96, 32,
+ 56, 255, 8, 34, 184, 99, 96, 84,
+ 99, 58, 170, 244, 227, 223, 169, 28,
+ 198, 43, 208, 74, 116, 232, 165, 206,
+ 130, 144, 88, 73, 50, 4, 36, 115,
+ 133, 244, 149, 27, 253, 122, 206, 34,
+ 14, 21, 102, 63, 142, 247, 211, 201,
+ 186, 34, 11, 220, 189, 87, 241, 161,
+ 15, 115, 255, 226, 224, 64, 96, 153,
+ 153, 161, 195, 124, 224, 64, 149, 249,
+ 52, 222, 210, 182, 150, 63, 92, 34,
+ 77, 30, 105, 221, 197, 107, 57, 187,
+ 76, 165, 238, 33, 38, 74, 189, 67,
+ 56, 205, 232, 230, 97, 48, 82, 97,
+ 119, 222, 29, 171, 162, 118, 64, 250,
+ 29, 41, 6, 196, 27, 12, 174, 190,
+ 49, 48, 19, 243, 51, 148, 46, 199,
+ 105, 45, 169, 137, 202, 95, 88, 141,
+ 107, 62, 245, 139, 202, 38, 73, 150,
+ 181, 30, 252, 194, 46, 103, 35, 111,
+ 21, 3, 37, 75, 149, 83, 150, 206,
+ 155, 132, 107, 204, 253, 79, 177, 40,
+ 6, 36, 207, 114, 233, 41, 36, 65,
+ 107, 113, 53, 80, 93, 12, 202, 251,
+ 44, 63, 50, 102, 250, 40, 240, 89,
+ 134, 47, 185, 131, 226, 59, 200, 52,
+ 115, 104, 243, 190, 229, 46, 197, 123,
+ 153, 150, 89, 135, 238, 18, 130, 151,
+ 154, 192, 11, 161, 244, 139, 89, 245,
+ 122, 229, 178, 176, 255, 176, 217, 223,
+ 3, 211, 70, 47, 89, 125, 191, 42,
+ 155, 209, 34, 128, 140, 86, 82, 126,
+ 190, 240, 86, 81, 122, 106, 195, 73,
+ 121, 50, 181, 152, 212, 156, 209, 68,
+ 173, 160, 95, 68, 115, 57, 180, 78,
+ 228, 62, 197, 180, 198, 72, 223, 122,
+ 58, 70, 231, 220, 103, 193, 182, 49,
+ 22, 201, 121, 121, 42, 3, 227, 231,
+ 187, 2, 50, 139, 8, 199, 242, 142,
+ 95, 130, 2, 143, 230, 57, 184, 118,
+ 103, 190, 15, 137, 243, 183, 0, 121,
+ 171, 97, 250, 206, 107, 60, 129, 46,
+ 207, 46, 115, 230, 31, 211, 33, 6,
+ 68, 10, 190, 133, 205, 173, 40, 99,
+ 170, 146, 110, 213, 150, 77, 126, 149,
+ 94, 216, 82, 124, 128, 100, 75, 7,
+ 9, 59, 199, 207, 151, 137, 24, 120,
+ 250, 253, 140, 115, 172, 100, 218, 65,
+ 255, 15, 153, 140, 67, 68, 189, 105,
+ 203, 197, 147, 254, 59, 188, 235, 186,
+ 232, 92, 66, 97, 53, 87, 94, 163,
+ 173, 108, 241, 191, 109, 150, 249, 164,
+ 54, 164, 122, 16, 94, 220, 114, 209,
+ 169, 252, 121, 249, 94, 170, 177, 187,
+ 246, 190, 141, 37, 175, 199, 63, 58,
+ 55, 196, 55, 227, 72, 34, 100, 100,
+ 115, 12, 153, 221, 34, 223, 73, 21,
+ 218, 110, 109, 169, 102, 81, 11, 244,
+ 80, 147, 245, 42, 130, 224, 132, 49,
+ 158, 144, 79, 189, 83, 77, 241, 39,
+ 204, 70, 87, 181, 146, 4, 213, 127,
+ 123, 244, 238, 77, 247, 169, 100, 91,
+ 25, 167, 204, 123, 67, 130, 188, 244,
+ 184, 239, 211, 27, 62, 163, 7, 123,
+ 136, 34, 0, 34, 2, 76, 97, 60,
+ 170, 24, 193, 39, 120, 132, 121, 202,
+ 93, 83, 125, 0, 225, 101, 151, 53,
+ 197, 21, 211, 38, 116, 101, 141, 89,
+ 159, 246, 172, 62, 67, 24, 152, 20,
+ 9, 248, 69, 60, 229, 73, 165, 190,
+ 101, 50, 173, 241, 115, 48, 36, 220,
+ 204, 160, 188, 251, 158, 166, 34, 171,
+ 205, 206, 240, 242, 62, 160, 220, 134,
+ 159, 96, 135, 255, 132, 253, 200, 37,
+ 121, 247, 247, 216, 61, 213, 10, 208,
+ 230, 185, 224, 84, 186, 71, 161, 64,
+ 55, 227, 34, 101, 126, 22, 43, 52,
+ 44, 113, 174, 147, 221, 130, 65, 167,
+ 217, 134, 119, 235, 27, 64, 29, 234,
+ 138, 70, 65, 224, 135, 169, 84, 34,
+ 240, 225, 212, 19, 179, 143, 22, 181,
+ 21, 157, 156, 33, 30, 231, 13, 134,
+ 125, 116, 77, 138, 95, 106, 59, 33,
+ 219, 187, 16, 203, 18, 179, 244, 43,
+ 15, 50, 151, 22, 45, 88, 140, 184,
+ 42, 216, 107, 73, 204, 13, 180, 141,
+ 20, 140, 120, 148, 212, 242, 220, 102,
+ 173, 239, 207, 87, 0, 85, 120, 105,
+ 74, 30, 49, 229, 116, 139, 65, 87,
+ 244, 145, 178, 209, 184, 197, 75, 201,
+ 61, 138, 21, 117, 224, 28, 61, 25,
+ 213, 230, 177, 195, 119, 108, 152, 167,
+ 218, 113, 135, 181, 13, 153, 82, 124,
+ 85, 192, 10, 214, 228, 153, 39, 60,
+ 201, 65, 213, 170, 156, 120, 223, 140,
+ 124, 76, 163, 164, 249, 114, 219, 37,
+ 68, 118, 91, 208, 91, 157, 244, 232,
+ 122, 44, 254, 182, 124, 200, 145, 207,
+ 90, 111, 229, 198, 226, 32, 57, 15,
+ 245, 166, 106, 226, 78, 230, 142, 104,
+ 218, 98, 23, 37, 190, 17, 142, 227,
+ 164, 174, 133, 106, 4, 43, 104, 49,
+ 114, 72, 243, 144, 9, 232, 117, 241,
+ 61, 224, 133, 126, 241, 204, 242, 55,
+ 173, 8, 217, 53, 210, 198, 175, 41,
+ 86, 84, 11, 136, 80, 226, 177, 11,
+ 123, 97, 39, 9, 41, 99, 114, 103,
+ 13, 120, 90, 168, 143, 30, 135, 97,
+ 196, 219, 0, 191, 209, 95, 66, 230,
+ 149, 27, 133, 137, 181, 29, 78, 193,
+ 10, 254, 142, 152, 128, 246, 231, 37,
+ 6, 139, 10, 251, 199, 186, 241, 159,
+ 168, 129, 182, 136, 79, 254, 40, 126,
+ 210, 222, 102, 182, 153, 74, 86, 210,
+ 51, 90, 100, 141, 240, 98, 202, 216,
+ 80, 170, 82, 226, 0, 135, 233, 173,
+ 137, 138, 74, 27, 122, 189, 163, 57,
+ 84, 217, 99, 24, 54, 132, 70, 81,
+ 79, 222, 118, 247, 237, 213, 251, 1,
+ 141, 151, 147, 91, 21, 7, 166, 78,
+ 207, 133, 14, 93, 92, 132, 2, 213,
+ 180, 26, 209, 106, 181, 11, 222, 17,
+ 108, 208, 93, 78, 177, 124, 84, 164,
+ 78, 161, 132, 132, 12, 245, 163, 44,
+ 182, 1, 28, 151, 84, 248, 49, 133,
+ 95, 195, 219, 18, 151, 221, 46, 126,
+ 92, 211, 202, 184, 141, 137, 138, 24,
+ 175, 66, 158, 179, 186, 97, 175, 127,
+ 5, 19, 113, 205, 81, 84, 41, 221,
+ 248, 201, 52, 233, 245, 211, 228, 81,
+ 33, 127, 205, 127, 251, 79, 244, 67,
+ 228, 104, 237, 249, 239, 146, 191, 118,
+ 119, 147, 42, 126, 119, 168, 46, 142,
+ 81, 45, 63, 214, 180, 226, 97, 189,
+ 144, 91, 19, 161, 42, 181, 205, 125,
+ 192, 94, 18, 205, 46, 222, 93, 99,
+ 118, 231, 180, 6, 90, 132, 98, 90,
+ 36, 88, 66, 55, 11, 240, 65, 98,
+ 225, 175, 47, 43, 122, 111, 178, 151,
+ 255, 237, 231, 214, 105, 40, 159, 22,
+ 169, 212, 83, 202, 115, 161, 47, 128,
+ 173, 237, 195, 120, 91, 188, 122, 11,
+ 102, 121, 27, 69, 251, 200, 69, 6,
+ 100, 118, 67, 114, 80, 174, 17, 136,
+ 112, 36, 43, 133, 9, 108, 198, 235,
+ 68, 134, 190, 201, 186, 251, 93, 63,
+ 239, 30, 73, 196, 52, 230, 125, 125,
+ 107, 82, 41, 146, 187, 90, 112, 26,
+ 239, 67, 13, 128, 34, 81, 210, 128,
+ 110, 50, 170, 5, 193, 59, 70, 173,
+ 39, 66, 136, 131, 75, 145, 151, 252,
+ 115, 182, 41, 121, 40, 57, 194, 50,
+ 87, 130, 8, 18, 126, 69, 48, 117,
+ 252, 186, 132, 62, 58, 151, 215, 198,
+ 229, 47, 244, 40, 14, 140, 9, 116,
+ 199, 240, 131, 62, 153, 10, 36, 20,
+ 87, 101, 230, 8, 90, 45, 173, 27,
+ 77, 248, 253, 190, 250, 65, 238, 21,
+ 87, 223, 98, 174, 64, 215, 212, 71,
+ 254, 39, 161, 202, 3, 198, 248, 79,
+ 210, 218, 236, 106, 175, 224, 85, 82,
+ 12, 145, 208, 10, 162, 121, 64, 37,
+ 84, 72, 112, 127, 11, 21, 138, 81,
+ 65, 196, 3, 156, 166, 203, 223, 55,
+ 156, 130, 139, 229, 18, 192, 220, 42,
+ 34, 31, 222, 216, 26, 8, 30, 118,
+ 85, 184, 103, 167, 127, 84, 155, 154,
+ 193, 99, 45, 49, 247, 239, 63, 17,
+ 235, 216, 66, 242, 211, 41, 123, 136,
+ 26, 234, 245, 152, 17, 81, 119, 203,
+ 20, 133, 5, 16, 38, 176, 1, 67,
+ 8, 11, 167, 78, 25, 249, 48, 205,
+ 79, 218, 192, 210, 147, 111, 154, 188,
+ 220, 186, 147, 174, 182, 212, 74, 160,
+ 89, 193, 105, 232, 60, 216, 114, 52,
+ 152, 198, 247, 239, 223, 30, 48, 28,
+ 244, 54, 41, 253, 38, 162, 42, 69,
+ 48, 37, 189, 207, 32, 151, 99, 120,
+ 253, 2, 19, 58, 234, 236, 48, 56,
+ 67, 235, 58, 83, 77, 125, 74, 154,
+ 116, 53, 7, 155, 10, 165, 97, 62,
+ 248, 140, 58, 241, 198, 17, 178, 11,
+ 205, 54, 31, 92, 52, 167, 220, 116,
+ 59, 50, 33, 1, 31, 80, 108, 96,
+ 151, 193, 190, 228, 135, 177, 247, 39,
+ 77, 10, 218, 251, 147, 246, 111, 108,
+ 111, 131, 189, 167, 148, 196, 252, 64,
+ 44, 102, 186, 7, 132, 207, 105, 222,
+ 19, 27, 182, 193, 102, 200, 6, 255,
+ 140, 199, 184, 127, 144, 66, 78, 27,
+ 82, 113, 205, 2, 169, 134, 251, 54,
+ 105, 139, 140, 172, 252, 104, 200, 96,
+ 33, 223, 196, 75, 253, 244, 27, 104,
+ 115, 77, 73, 220, 211, 66, 174, 30,
+ 161, 95, 7, 155, 96, 92, 157, 201,
+ 48, 234, 241, 118, 70, 175, 142, 162,
+ 190, 116, 54, 157, 101, 108, 107, 247,
+ 190, 119, 246, 135, 202, 24, 52, 134,
+ 248, 197, 199, 113, 247, 243, 41, 147,
+ 30, 170, 86, 82, 187, 131, 227, 5,
+ 228, 168, 243, 241, 229, 1, 106, 222,
+ 43, 117, 81, 36, 102, 21, 52, 213,
+ 52, 59, 215, 55, 148, 49, 251, 43,
+ 22, 7, 126, 196, 116, 3, 165, 99,
+ 216, 15, 172, 18, 126, 234, 226, 160,
+ 24, 15, 150, 96, 121, 174, 52, 44,
+ 242, 185, 43, 35, 22, 64, 211, 241,
+ 156, 243, 70, 1, 133, 105, 110, 82,
+ 251, 238, 224, 197, 199, 49, 15, 59,
+ 176, 2, 38, 141, 162, 214, 172, 225,
+ 29, 244, 44, 192, 242, 237, 25, 47,
+ 55, 182, 122, 238, 241, 151, 251, 211,
+ 227, 144, 162, 33, 11, 237, 142, 167,
+ 182, 77, 173, 39, 213, 10, 54, 41,
+ 227, 14, 50, 72, 137, 93, 79, 235,
+ 222, 37, 38, 171, 21, 131, 214, 209,
+ 192, 160, 102, 45, 95, 110, 170, 91,
+ 93, 131, 16, 179, 138, 55, 24, 53,
+ 42, 86, 22, 9, 246, 16, 64, 120,
+ 46, 168, 151, 137, 32, 27, 239, 210,
+ 98, 5, 38, 50, 31, 174, 85, 11,
+ 89, 6, 46, 3, 13, 68, 109, 80,
+ 95, 145, 218, 100, 193, 16, 252, 219,
+ 0, 38, 210, 231, 107, 66, 19, 212,
+ 116, 219, 9, 104, 215, 130, 221, 58,
+ 189, 206, 130, 13, 68, 93, 147, 189,
+ 20, 43, 52, 43, 59, 124, 244, 35,
+ 203, 99, 236, 12, 40, 23, 234, 76,
+ 81, 120, 170, 202, 120, 206, 218, 51,
+ 58, 104, 107, 121, 190, 43, 124, 220,
+ 110, 72, 173, 110, 127, 123, 86, 86,
+ 125, 79, 55, 163, 229, 249, 205, 66,
+ 29, 38, 143, 103, 233, 198, 0, 190,
+ 141, 16, 29, 98, 191, 82, 16, 36,
+ 80, 132, 175, 235, 104, 93, 128, 76,
+ 175, 155, 168, 208, 232, 210, 31, 113,
+ 233, 148, 94, 215, 166, 128, 180, 238,
+ 86, 194, 60, 250, 38, 162, 127, 237,
+ 54, 227, 82, 209, 77, 163, 250, 120,
+ 200, 0, 163, 136, 129, 79, 145, 174,
+ 213, 101, 204, 182, 125, 125, 60, 202,
+ 218, 248, 90, 26, 108, 125, 161, 242,
+ 118, 38, 18, 122, 215, 88, 164, 83,
+ 239, 151, 104, 80, 35, 66, 179, 157,
+ 49, 144, 104, 14, 143, 67, 49, 136,
+ 75, 136, 130, 168, 75, 203, 184, 239,
+ 210, 36, 246, 67, 231, 226, 90, 35,
+ 35, 198, 79, 209, 32, 178, 96, 54,
+ 156, 105, 31, 156, 26, 87, 33, 252,
+ 245, 79, 105, 214, 83, 245, 231, 94,
+ 132, 151, 17, 233, 66, 230, 58, 41,
+ 193, 41, 122, 158, 224, 148, 49, 99,
+ 244, 92, 107, 250, 61, 111, 248, 68,
+ 204, 78, 247, 67, 14, 199, 182, 136,
+ 173, 164, 232, 207, 178, 13, 48, 83,
+ 26, 106, 59, 92, 14, 111, 166, 66,
+ 172, 203, 104, 131, 218, 252, 248, 238,
+ 61, 167, 125, 209, 198, 174, 12, 145,
+ 40, 58, 36, 102, 76, 134, 176, 113,
+ 155, 22, 180, 149, 42, 92, 191, 179,
+ 16, 123, 117, 179, 34, 27, 95, 43,
+ 122, 114, 182, 196, 140, 66, 203, 121,
+ 29, 5, 213, 136, 149, 197, 24, 51,
+ 157, 216, 53, 68, 179, 90, 156, 72,
+ 20, 125, 0, 218, 215, 207, 190, 251,
+ 163, 33, 242, 185, 104, 116, 6, 46,
+ 104, 140, 243, 63, 198, 118, 232, 132,
+ 154, 79, 229, 15, 107, 42, 222, 239,
+ 106, 224, 147, 182, 209, 48, 92, 214,
+ 73, 255, 196, 80, 147, 94, 216, 246,
+ 252, 210, 90, 239, 180, 205, 0, 157,
+ 118, 172, 240, 164, 254, 155, 228, 249,
+ 118, 118, 81, 40, 248, 182, 178, 85,
+ 118, 105, 35, 139, 0, 6, 52, 157,
+ 42, 29, 92, 35, 154, 130, 7, 161,
+ 241, 214, 229, 80, 123, 89, 72, 179,
+ 147, 38, 221, 174, 222, 58, 17, 90,
+ 89, 30, 110, 1, 96, 57, 47, 43,
+ 254, 88, 71, 252, 201, 202, 104, 223,
+ 139, 124, 32, 31, 186, 158, 151, 13,
+ 132, 213, 254, 246, 172, 94, 180, 43,
+ 148, 184, 67, 67, 73, 126, 27, 69,
+ 98, 191, 226, 125, 0, 7, 168, 154,
+ 112, 86, 166, 33, 123, 196, 120, 11,
+ 50, 15, 190, 157, 215, 233, 68, 158,
+ 188, 42, 44, 141, 198, 245, 33, 32,
+ 120, 191, 188, 134, 80, 185, 152, 36,
+ 160, 193, 224, 154, 57, 209, 223, 99,
+ 57, 55, 45, 218, 57, 238, 25, 174,
+ 102, 169, 236, 54, 180, 208, 21, 120,
+ 56, 27, 152, 152, 159, 72, 226, 83,
+ 169, 79, 113, 237, 177, 42, 53, 104,
+ 120, 54, 211, 171, 148, 217, 119, 51,
+ 94, 139, 24, 223, 213, 247, 23, 143,
+ 79, 11, 145, 226, 156, 52, 89, 249,
+ 187, 155, 54, 111, 64, 32, 131, 189,
+ 244, 34, 253, 54, 36, 62, 236, 82,
+ 251, 232, 31, 211, 163, 185, 50, 106,
+ 133, 29, 181, 85, 157, 127, 211, 124,
+ 203, 61, 42, 220, 6, 60, 164, 28,
+ 82, 38, 209, 102, 63, 182, 234, 73,
+ 213, 238, 205, 162, 153, 176, 64, 143,
+ 155, 45, 16, 172, 224, 57, 51, 238,
+ 137, 192, 47, 112, 144, 20, 209, 197,
+ 232, 229, 28, 64, 126, 106, 189, 184,
+ 161, 192, 147, 55, 241, 35, 141, 19,
+ 48, 230, 59, 216, 88, 43, 167, 115,
+ 176, 219, 183, 190, 250, 158, 187, 14,
+ 52, 5, 107, 170, 97, 76, 150, 107,
+ 89, 39, 201, 99, 19, 84, 227, 126,
+ 172, 188, 104, 73, 130, 182, 164, 46,
+ 238, 30, 143, 32, 52, 6, 204, 180,
+ 154, 182, 247, 118, 224, 158, 86, 247,
+ 183, 75, 131, 117, 152, 38, 57, 106,
+ 80, 139, 100, 189, 232, 144, 4, 181,
+ 144, 72, 6, 1, 160, 91, 105, 157,
+ 163, 14, 185, 27, 103, 254, 105, 195,
+ 234, 180, 23, 43, 127, 99, 226, 142,
+ 75, 179, 252, 127, 53, 217, 8, 247,
+ 22, 165, 198, 251, 1, 205, 130, 28,
+ 211, 202, 64, 33, 191, 21, 13, 197,
+ 17, 149, 10, 163, 201, 3, 109, 190,
+ 74, 174, 107, 84, 229, 233, 158, 47,
+ 120, 127, 128, 32, 124, 229, 131, 39,
+ 54, 239, 11, 115, 113, 219, 158, 137,
+ 62, 85, 129, 1, 101, 71, 214, 33,
+ 212, 209, 80, 133, 95, 104, 95, 117,
+ 27, 226, 221, 222, 172, 47, 76, 31,
+ 233, 41, 74, 9, 31, 45, 242, 4,
+ 153, 163, 70, 16, 20, 130, 64, 139,
+ 57, 165, 250, 224, 201, 104, 152, 16,
+ 144, 16, 49, 173, 147, 23, 62, 117,
+ 100, 112, 227, 85, 48, 207, 88, 151,
+ 236, 110, 111, 212, 28, 242, 20, 232,
+ 186, 10, 143, 239, 87, 183, 45, 73,
+ 43, 8, 231, 148, 195, 15, 46, 24,
+ 65, 140, 150, 181, 227, 214, 218, 115,
+ 23, 94, 111, 131, 6, 70, 210, 12,
+ 178, 172, 140, 86, 191, 88, 104, 249,
+ 9, 58, 232, 123, 147, 210, 71, 172,
+ 28, 0, 85, 133, 85, 173, 68, 49,
+ 160, 16, 229, 1, 244, 8, 241, 171,
+ 181, 69, 53, 141, 68, 113, 187, 230,
+ 239, 214, 106, 46, 62, 109, 133, 198,
+ 83, 233, 159, 130, 88, 50, 166, 190,
+ 29, 140, 16, 22, 93, 47, 59, 237,
+ 154, 39, 126, 61, 149, 254, 247, 1,
+ 60, 36, 160, 51, 6, 77, 249, 22,
+ 22, 107, 241, 70, 244, 57, 106, 11,
+ 27, 0, 1, 246, 254, 240, 155, 81,
+ 151, 205, 90, 158, 16, 203, 178, 161,
+ 119, 226, 17, 79, 188, 66, 8, 91,
+ 69, 228, 102, 190, 241, 152, 87, 116,
+ 0, 16, 39, 132, 179, 239, 220, 119,
+ 158, 28, 90, 239, 238, 229, 230, 35,
+ 71, 232, 28, 34, 111, 105, 127, 149,
+ 0, 242, 56, 44, 101, 208, 219, 246,
+ 247, 249, 239, 238, 222, 122, 204, 99,
+ 49, 139, 42, 59, 7, 185, 90, 210,
+ 181, 198, 22, 211, 21, 30, 122, 191,
+ 163, 9, 200, 185, 82, 169, 29, 30,
+ 47, 86, 218, 142, 125, 90, 209, 112,
+ 140, 230, 214, 196, 170, 145, 180, 252,
+ 228, 0, 34, 146, 251, 122, 15, 16,
+ 2, 59, 103, 205, 157, 120, 111, 102,
+ 95, 79, 61, 28, 150, 98, 198, 247,
+ 131, 174, 233, 241, 170, 5, 215, 141,
+ 83, 106, 61, 83, 113, 235, 171, 78,
+ 87, 32, 217, 44, 213, 243, 17, 64,
+ 150, 113, 255, 124, 214, 168, 24, 165,
+ 140, 98, 39, 210, 99, 24, 21, 249,
+ 250, 29, 175, 171, 37, 53, 70, 73,
+ 132, 235, 184, 85, 206, 62, 165, 4,
+ 84, 145, 173, 68, 166, 109, 101, 232,
+ 150, 128, 113, 28, 33, 249, 134, 218,
+ 69, 130, 214, 71, 51, 222, 45, 132,
+ 165, 126, 171, 129, 116, 134, 199, 94,
+ 207, 206, 75, 34, 203, 227, 137, 21,
+ 120, 160, 114, 214, 239, 4, 254, 248,
+ 21, 197, 112, 150, 204, 18, 91, 223,
+ 203, 131, 217, 168, 230, 140, 144, 229,
+ 118, 36, 104, 14, 124, 225, 202, 97,
+ 225, 83, 111, 144, 138, 17, 235, 49,
+ 179, 138, 210, 5, 228, 17, 150, 59,
+ 186, 101, 230, 91, 225, 169, 7, 214,
+ 165, 240, 19, 222, 194, 75, 97, 217,
+ 121, 235, 194, 177, 181, 180, 172, 194,
+ 136, 249, 143, 91, 110, 201, 169, 116,
+ 248, 210, 122, 97, 237, 126, 99, 218,
+ 254, 102, 117, 242, 211, 157, 254, 224,
+ 51, 163, 52, 190, 207, 187, 236, 160,
+ 42, 252, 2, 231, 249, 143, 203, 133,
+ 235, 210, 46, 16, 185, 192, 150, 59,
+ 44, 64, 31, 225, 45, 142, 104, 225,
+ 205, 144, 65, 247, 171, 88, 26, 163,
+ 156, 43, 135, 246, 191, 105, 221, 214,
+ 168, 35, 133, 114, 241, 85, 47, 46,
+ 149, 11, 253, 208, 110, 109, 78, 130,
+ 37, 89, 24, 231, 163, 144, 48, 91,
+ 88, 91, 66, 59, 203, 150, 28, 8,
+ 218, 8, 24, 209, 146, 40, 100, 145,
+ 210, 241, 211, 0, 143, 247, 217, 166,
+ 55, 120, 112, 28, 116, 143, 50, 207,
+ 251, 131, 121, 57, 162, 128, 86, 255,
+ 34, 167, 26, 12, 97, 145, 191, 84,
+ 95, 93, 46, 157, 10, 89, 219, 1,
+ 90, 114, 90, 254, 142, 191, 26, 115,
+ 206, 17, 77, 24, 175, 204, 212, 175,
+ 184, 209, 163, 53, 94, 194, 84, 38,
+ 23, 235, 235, 123, 115, 76, 243, 42,
+ 163, 19, 48, 164, 52, 103, 54, 50,
+ 181, 46, 103, 9, 138, 224, 224, 2,
+ 170, 196, 208, 49, 195, 130, 215, 55,
+ 148, 195, 96, 107, 196, 160, 161, 252,
+ 111, 202, 200, 87, 22, 49, 164, 115,
+ 133, 210, 235, 155, 103, 59, 235, 163,
+ 116, 23, 77, 171, 109, 194, 232, 0,
+ 235, 215, 83, 198, 18, 5, 48, 211,
+ 231, 23, 188, 240, 88, 142, 193, 118,
+ 164, 12, 21, 160, 129, 97, 99, 13,
+ 210, 162, 212, 151, 26, 242, 42, 191,
+ 130, 226, 77, 18, 179, 84, 81, 192,
+ 138, 83, 170, 193, 242, 151, 11, 145,
+ 99, 79, 234, 82, 142, 121, 29, 145,
+ 169, 247, 162, 16, 210, 187, 187, 167,
+ 126, 210, 152, 170, 176, 225, 180, 155,
+ 178, 110, 95, 183, 70, 7, 125, 34,
+ 46, 68, 228, 101, 198, 42, 56, 10,
+ 173, 129, 25, 52, 38, 80, 15, 146,
+ 116, 194, 213, 136, 220, 45, 238, 121,
+ 204, 119, 57, 44, 196, 207, 96, 196,
+ 20, 255, 81, 223, 89, 118, 8, 178,
+ 169, 75, 92, 46, 233, 165, 76, 203,
+ 157, 53, 224, 145, 114, 38, 194, 117,
+ 228, 67, 251, 66, 73, 199, 234, 24,
+ 93, 65, 167, 109, 151, 207, 218, 135,
+ 8, 34, 86, 125, 206, 222, 112, 228,
+ 167, 124, 4, 225, 15, 253, 119, 68,
+ 187, 244, 33, 229, 180, 21, 218, 238,
+ 237, 62, 30, 120, 239, 247, 170, 84,
+ 160, 252, 42, 20, 185, 5, 209, 110,
+ 163, 132, 21, 135, 174, 113, 230, 202,
+ 14, 10, 76, 150, 94, 72, 97, 190,
+ 255, 166, 20, 172, 124, 86, 221, 230,
+ 8, 95, 221, 171, 137, 249, 222, 134,
+ 2, 7, 233, 248, 246, 109, 177, 109,
+ 98, 131, 104, 29, 50, 12, 251, 232,
+ 39, 69, 190, 173, 165, 80, 164, 68,
+ 64, 107, 128, 57, 63, 16, 127, 35,
+ 167, 189, 68, 243, 100, 75, 22, 36,
+ 47, 124, 18, 113, 185, 26, 216, 216,
+ 127, 147, 64, 188, 18, 240, 214, 223,
+ 62, 27, 199, 80, 74, 41, 175, 178,
+ 186, 163, 156, 146, 0, 178, 32, 130,
+ 6, 110, 139, 190, 203, 198, 174, 214,
+ 27, 218, 135, 45, 125, 33, 102, 166,
+ 18, 147, 204, 12, 29, 157, 192, 103,
+ 36, 105, 93, 193, 12, 34, 71, 119,
+ 243, 5, 118, 48, 75, 36, 252, 124,
+ 16, 80, 12, 31, 15, 229, 196, 3,
+ 31, 230, 55, 130, 172, 91, 14, 200,
+ 108, 8, 155, 155, 78, 110, 241, 247,
+ 101, 241, 176, 124, 66, 241, 199, 227,
+ 190, 69, 114, 240, 17, 119, 30, 49,
+ 196, 145, 158, 187, 88, 25, 129, 166,
+ 15, 108, 46, 58, 93, 165, 28, 15,
+ 21, 139, 188, 7, 43, 40, 164, 180,
+ 4, 17, 48, 64, 37, 234, 238, 14,
+ 244, 44, 175, 91, 183, 197, 142, 250,
+ 2, 158, 58, 136, 246, 232, 223, 69,
+ 54, 231, 99, 166, 151, 95, 67, 1,
+ 71, 186, 170, 188, 52, 82, 132, 72,
+ 218, 120, 52, 141, 166, 39, 205, 221,
+ 74, 120, 179, 16, 181, 210, 225, 246,
+ 130, 62, 70, 113, 154, 62, 243, 248,
+ 10, 59, 123, 161, 139, 122, 136, 125,
+ 170, 89, 180, 107, 49, 191, 186, 188,
+ 91, 149, 29, 20, 252, 219, 32, 87,
+ 63, 162, 73, 225, 64, 132, 133, 205,
+ 135, 49, 237, 33, 116, 249, 66, 28,
+ 148, 201, 86, 252, 36, 241, 207, 25,
+ 145, 68, 85, 11, 221, 191, 181, 55,
+ 118, 189, 47, 201, 8, 251, 244, 254,
+ 57, 180, 85, 225, 91, 228, 97, 11,
+ 101, 25, 133, 183, 118, 48, 237, 72,
+ 222, 251, 16, 13, 233, 10, 98, 161,
+ 68, 141, 110, 175, 52, 186, 135, 14,
+ 64, 46, 80, 197, 190, 0, 28, 177,
+ 122, 208, 205, 241, 227, 179, 204, 93,
+ 162, 248, 4, 225, 160, 86, 142, 5,
+ 194, 241, 186, 194, 190, 178, 176, 234,
+ 158, 244, 214, 50, 22, 119, 131, 232,
+ 2, 136, 63, 182, 231, 213, 30, 252,
+ 248, 8, 21, 254, 9, 107, 12, 80,
+ 222, 77, 253, 49, 235, 114, 129, 193,
+ 239, 63, 5, 195, 195, 223, 145, 11,
+ 220, 169, 155, 127, 50, 254, 92, 255,
+ 248, 252, 222, 127, 213, 100, 105, 43,
+ 28, 215, 154, 88, 11, 188, 166, 69,
+ 57, 15, 65, 87, 207, 83, 60, 63,
+ 199, 7, 190, 165, 122, 153, 149, 141,
+ 149, 171, 170, 179, 30, 43, 124, 90,
+ 168, 165, 214, 193, 52, 181, 118, 102,
+ 166, 171, 110, 49, 17, 162, 174, 138,
+ 52, 207, 78, 129, 128, 220, 220, 212,
+ 208, 175, 46, 4, 104, 210, 253, 26,
+ 242, 140, 229, 240, 172, 83, 152, 209,
+ 225, 34, 122, 74, 157, 218, 25, 225,
+ 233, 167, 77, 200, 97, 246, 132, 26,
+ 197, 112, 36, 66, 110, 234, 69, 238,
+ 147, 106, 44, 96, 22, 140, 243, 153,
+ 69, 180, 230, 247, 154, 72, 211, 7,
+ 214, 37, 167, 39, 4, 224, 181, 134,
+ 53, 100, 104, 209, 163, 160, 187, 173,
+ 58, 31, 16, 189, 16, 168, 122, 91,
+ 126, 248, 67, 225, 187, 213, 182, 160,
+ 71, 149, 94, 191, 182, 58, 84, 26,
+ 139, 175, 242, 96, 75, 144, 126, 18,
+ 124, 169, 9, 32, 173, 160, 58, 127,
+ 52, 26, 18, 172, 245, 201, 208, 167,
+ 205, 116, 156, 160, 128, 53, 187, 240,
+ 85, 189, 142, 49, 210, 142, 60, 118,
+ 150, 166, 99, 116, 28, 151, 242, 112,
+ 105, 173, 142, 74, 31, 214, 118, 190,
+ 84, 178, 113, 40, 99, 184, 211, 94,
+ 13, 255, 96, 171, 60, 187, 205, 74,
+ 243, 253, 29, 202, 107, 165, 37, 90,
+ 116, 134, 51, 41, 242, 195, 107, 56,
+ 173, 73, 233, 106, 159, 91, 76, 161,
+ 95, 237, 31, 242, 128, 188, 51, 201,
+ 111, 211, 71, 100, 251, 237, 94, 200,
+ 117, 4, 78, 110, 69, 187, 122, 206,
+ 128, 242, 27, 126, 54, 9, 104, 117,
+ 117, 214, 129, 190, 121, 71, 146, 133,
+ 131, 161, 108, 216, 126, 164, 254, 114,
+ 249, 44, 85, 72, 11, 119, 175, 93,
+ 166, 144, 250, 154, 245, 66, 228, 67,
+ 48, 80, 66, 195, 128, 179, 124, 236,
+ 191, 7, 107, 103, 85, 180, 124, 242,
+ 247, 70, 180, 249, 181, 47, 254, 126,
+ 113, 140, 10, 65, 75, 179, 41, 159,
+ 117, 247, 181, 47, 118, 9, 142, 18,
+ 180, 32, 248, 118, 27, 25, 139, 133,
+ 177, 7, 80, 92, 211, 130, 223, 134,
+ 22, 17, 171, 161, 228, 200, 11, 60,
+ 140, 207, 147, 19, 199, 68, 48, 240,
+ 248, 100, 203, 32, 212, 81, 68, 59,
+ 129, 54, 48, 230, 22, 20, 147, 4,
+ 145, 155, 221, 40, 220, 5, 164, 26,
+ 18, 200, 247, 110, 119, 6, 25, 205,
+ 238, 231, 94, 121, 146, 30, 163, 85,
+ 92, 172, 9, 220, 95, 63, 197, 220,
+ 238, 153, 59, 32, 232, 243, 48, 188,
+ 140, 31, 51, 251, 63, 111, 96, 88,
+ 188, 135, 168, 125, 207, 19, 79, 209,
+ 7, 56, 30, 52, 73, 220, 224, 113,
+ 13, 234, 19, 239, 245, 154, 180, 199,
+ 143, 134, 245, 109, 116, 141, 90, 73,
+ 48, 142, 7, 154, 184, 92, 177, 13,
+ 186, 196, 160, 255, 63, 4, 225, 207,
+ 105, 165, 197, 173, 161, 209, 142, 27,
+ 59, 111, 106, 169, 24, 121, 209, 141,
+ 21, 190, 59, 10, 30, 109, 62, 70,
+ 126, 157, 210, 27, 247, 216, 74, 87,
+ 66, 86, 69, 59, 213, 138, 81, 224,
+ 103, 92, 202, 62, 203, 38, 111, 159,
+ 46, 53, 208, 137, 229, 150, 164, 95,
+ 35, 196, 196, 3, 8, 234, 185, 35,
+ 200, 141, 59, 220, 174, 61, 88, 147,
+ 2, 108, 21, 46, 167, 121, 6, 28,
+ 218, 22, 33, 63, 172, 234, 48, 175,
+ 77, 31, 58, 50, 10, 85, 172, 239,
+ 69, 139, 198, 155, 37, 118, 86, 190,
+ 26, 228, 34, 238, 20, 131, 34, 80,
+ 134, 87, 224, 197, 92, 1, 97, 132,
+ 73, 13, 16, 25, 3, 188, 224, 168,
+ 54, 113, 78, 252, 57, 145, 37, 40,
+ 148, 170, 216, 128, 249, 0, 29, 248,
+ 14, 47, 110, 27, 5, 54, 230, 51,
+ 83, 142, 192, 203, 32, 205, 189, 2,
+ 142, 84, 240, 22, 140, 227, 161, 188,
+ 161, 195, 178, 198, 73, 108, 189, 68,
+ 155, 123, 65, 158, 159, 0, 133, 207,
+ 220, 237, 6, 9, 198, 166, 79, 133,
+ 247, 69, 66, 123, 13, 51, 91, 240,
+ 154, 115, 244, 237, 238, 11, 4, 18,
+ 66, 177, 204, 209, 8, 238, 34, 118,
+ 4, 197, 145, 178, 128, 61, 64, 206,
+ 34, 19, 41, 182, 153, 59, 247, 152,
+ 92, 14, 213, 30, 139, 72, 140, 40,
+ 164, 230, 132, 36, 37, 171, 122, 86,
+ 68, 75, 84, 27, 194, 18, 151, 143,
+ 212, 23, 147, 161, 212, 47, 32, 186,
+ 46, 34, 16, 254, 10, 14, 33, 99,
+ 21, 225, 179, 187, 170, 205, 67, 72,
+ 14, 160, 82, 211, 16, 80, 30, 65,
+ 85, 126, 52, 206, 9, 1, 154, 247,
+ 6, 219, 250, 133, 206, 91, 131, 39,
+ 13, 146, 182, 220, 135, 1, 88, 157,
+ 232, 60, 88, 26, 44, 196, 83, 40,
+ 64, 211, 116, 72, 120, 152, 83, 129,
+ 164, 180, 179, 189, 204, 238, 82, 103,
+ 72, 251, 183, 97, 47, 115, 187, 202,
+ 106, 189, 144, 161, 241, 16, 82, 167,
+ 38, 90, 40, 50, 51, 205, 197, 203,
+ 166, 160, 37, 243, 78, 210, 250, 8,
+ 154, 81, 45, 180, 182, 15, 172, 148,
+ 209, 41, 68, 113, 54, 138, 178, 243,
+ 198, 58, 131, 251, 148, 232, 105, 13,
+ 194, 117, 50, 255, 237, 63, 166, 239,
+ 234, 162, 3, 51, 166, 98, 44, 151,
+ 85, 229, 135, 120, 137, 219, 131, 169,
+ 3, 44, 94, 146, 96, 37, 240, 151,
+ 55, 93, 81, 160, 114, 109, 117, 15,
+ 97, 142, 67, 250, 9, 181, 73, 26,
+ 68, 136, 250, 48, 186, 109, 96, 38,
+ 96, 228, 223, 116, 92, 198, 212, 151,
+ 12, 63, 62, 43, 107, 18, 1, 236,
+ 142, 145, 197, 107, 205, 250, 146, 231,
+ 205, 84, 205, 86, 50, 181, 95, 99,
+ 143, 238, 129, 225, 7, 248, 143, 199,
+ 36, 118, 22, 137, 246, 107, 123, 220,
+ 107, 174, 169, 178, 104, 177, 204, 17,
+ 153, 147, 196, 126, 236, 76, 115, 212,
+ 184, 152, 12, 105, 48, 5, 156, 168,
+ 231, 38, 82, 189, 207, 209, 189, 75,
+ 221, 162, 13, 219, 214, 104, 80, 29,
+ 114, 63, 150, 200, 126, 221, 64, 208,
+ 190, 64, 33, 40, 33, 176, 119, 156,
+ 19, 41, 179, 169, 21, 144, 109, 216,
+ 135, 49, 227, 75, 253, 202, 219, 117,
+ 9, 205, 76, 56, 133, 248, 204, 132,
+ 29, 42, 147, 196, 201, 102, 14, 246,
+ 28, 111, 44, 252, 205, 138, 214, 179,
+ 85, 99, 63, 21, 126, 206, 236, 94,
+ 157, 51, 252, 122, 88, 153, 105, 40,
+ 104, 138, 179, 212, 133, 253, 153, 172,
+ 214, 137, 51, 72, 217, 71, 32, 168,
+ 217, 189, 8, 6, 208, 172, 33, 42,
+ 247, 68, 124, 1, 249, 198, 75, 104,
+ 146, 38, 235, 181, 27, 42, 33, 62,
+ 173, 218, 214, 164, 47, 5, 184, 14,
+ 113, 176, 198, 68, 19, 255, 93, 251,
+ 47, 43, 166, 254, 151, 1, 42, 147,
+ 29, 208, 165, 42, 39, 193, 110, 69,
+ 206, 2, 75, 37, 108, 141, 53, 15,
+ 204, 213, 220, 172, 89, 122, 164, 156,
+ 224, 93, 94, 88, 31, 106, 211, 102,
+ 141, 120, 46, 73, 116, 149, 211, 128,
+ 91, 50, 214, 6, 12, 197, 211, 68,
+ 245, 188, 0, 20, 19, 113, 108, 155,
+ 198, 109, 107, 3, 5, 47, 195, 224,
+ 177, 87, 129, 169, 107, 217, 30, 237,
+ 240, 59, 96, 205, 90, 144, 159, 108,
+ 66, 30, 203, 36, 158, 67, 223, 192,
+ 30, 124, 213, 244, 95, 51, 153, 39,
+ 160, 206, 24, 140, 34, 245, 118, 209,
+ 3, 218, 225, 237, 178, 133, 202, 191,
+ 124, 124, 145, 164, 22, 130, 30, 229,
+ 82, 190, 194, 199, 247, 186, 155, 76,
+ 164, 37, 207, 58, 20, 51, 32, 17,
+ 76, 173, 123, 213, 102, 6, 114, 180,
+ 211, 158, 194, 96, 163, 131, 68, 98,
+ 223, 181, 170, 10, 61, 215, 254, 159,
+ 109, 133, 18, 52, 41, 160, 114, 117,
+ 80, 49, 30, 208, 86, 32, 224, 92,
+ 217, 106, 15, 37, 167, 198, 171, 253,
+ 187, 126, 69, 61, 248, 147, 224, 132,
+ 170, 122, 180, 201, 252, 29, 46, 122,
+ 40, 163, 121, 223, 229, 88, 13, 224,
+ 126, 65, 161, 69, 201, 14, 112, 80,
+ 5, 175, 186, 247, 206, 205, 108, 218,
+ 95, 114, 166, 208, 113, 227, 88, 168,
+ 218, 248, 201, 31, 63, 32, 124, 86,
+ 192, 207, 245, 157, 99, 14, 11, 199,
+ 69, 139, 201, 193, 85, 54, 187, 102,
+ 224, 148, 93, 90, 119, 165, 32, 72,
+ 235, 100, 68, 42, 130, 144, 112, 239,
+ 48, 210, 24, 225, 240, 96, 177, 183,
+ 103, 33, 24, 231, 181, 33, 251, 91,
+ 206, 116, 69, 182, 153, 242, 155, 117,
+ 109, 54, 86, 150, 182, 51, 137, 74,
+ 26, 15, 172, 15, 29, 41, 241, 55,
+ 195, 141, 78, 164, 219, 150, 252, 220,
+ 113, 207, 41, 161, 71, 103, 176, 155,
+ 0, 68, 111, 241, 130, 243, 226, 19,
+ 230, 254, 224, 208, 49, 226, 153, 1,
+ 34, 58, 34, 215, 249, 244, 80, 30,
+ 147, 216, 143, 40, 27, 182, 43, 153,
+ 208, 39, 189, 115, 167, 48, 122, 149,
+ 164, 81, 96, 126, 168, 154, 209, 149,
+ 34, 113, 21, 241, 135, 132, 97, 211,
+ 162, 204, 110, 181, 28, 204, 104, 105,
+ 174, 29, 15, 145, 132, 103, 123, 97,
+ 95, 63, 16, 65, 36, 189, 191, 225,
+ 28, 62, 22, 15, 4, 84, 115, 7,
+ 223, 111, 152, 179, 106, 150, 47, 0,
+ 39, 228, 88, 255, 48, 171, 64, 229,
+ 54, 150, 21, 189, 87, 41, 191, 225,
+ 82, 104, 90, 225, 102, 199, 154, 61,
+ 10, 120, 45, 74, 23, 127, 233, 151,
+ 180, 195, 85, 217, 65, 188, 29, 125,
+ 189, 205, 15, 51, 241, 176, 145, 173,
+ 236, 2, 18, 22, 107, 222, 229, 197,
+ 52, 205, 128, 234, 129, 176, 177, 216,
+ 189, 22, 22, 70, 242, 50, 24, 78,
+ 229, 250, 184, 16, 57, 249, 218, 45,
+ 150, 240, 210, 56, 0, 155, 217, 227,
+ 92, 138, 213, 236, 108, 85, 237, 162,
+ 102, 187, 149, 214, 146, 176, 46, 235,
+ 185, 200, 251, 237, 157, 47, 220, 201,
+ 204, 222, 244, 95, 62, 36, 233, 30,
+ 236, 108, 87, 216, 137, 59, 20, 209,
+ 232, 254, 69, 55, 106, 130, 208, 182,
+ 176, 105, 121, 179, 172, 135, 180, 75,
+ 59, 13, 70, 70, 226, 187, 159, 252,
+ 134, 91, 72, 181, 10, 248, 154, 0,
+ 187, 81, 39, 186, 107, 153, 132, 62,
+ 7, 3, 240, 141, 188, 153, 99, 47,
+ 13, 2, 98, 160, 196, 174, 205, 185,
+ 38, 126, 87, 224, 27, 47, 1, 234,
+ 232, 46, 101, 208, 82, 35, 218, 138,
+ 244, 109, 32, 205, 84, 9, 84, 143,
+ 157, 227, 42, 13, 200, 104, 100, 235,
+ 71, 143, 68, 79, 72, 226, 227, 159,
+ 240, 23, 210, 61, 214, 91, 153, 160,
+ 164, 148, 34, 223, 120, 220, 11, 25,
+ 28, 126, 31, 228, 146, 96, 26, 64,
+ 191, 22, 246, 18, 66, 68, 46, 23,
+ 69, 171, 124, 207, 243, 205, 87, 75,
+ 185, 218, 167, 252, 5, 90, 234, 135,
+ 107, 150, 163, 108, 212, 57, 36, 108,
+ 252, 64, 144, 217, 188, 159, 62, 47,
+ 71, 25, 86, 45, 136, 34, 195, 103,
+ 251, 30, 253, 117, 82, 93, 119, 148,
+ 18, 49, 22, 169, 9, 36, 100, 35,
+ 58, 49, 67, 134, 203, 249, 17, 87,
+ 3, 127, 78, 65, 14, 102, 178, 107,
+ 70, 238, 234, 240, 75, 53, 188, 40,
+ 190, 98, 207, 164, 221, 2, 110, 106,
+ 171, 60, 22, 210, 113, 176, 223, 38,
+ 63, 150, 195, 76, 110, 50, 154, 150,
+ 180, 177, 39, 121, 215, 79, 227, 246,
+ 40, 62, 231, 241, 21, 122, 158, 216,
+ 9, 76, 211, 158, 152, 169, 1, 4,
+ 131, 210, 19, 34, 136, 59, 167, 237,
+ 219, 198, 183, 2, 55, 244, 29, 220,
+ 62, 13, 178, 143, 146, 1, 108, 23,
+ 84, 106, 60, 174, 94, 62, 100, 164,
+ 58, 254, 74, 185, 236, 134, 28, 208,
+ 130, 169, 35, 250, 74, 45, 35, 75,
+ 138, 113, 98, 120, 242, 144, 104, 113,
+ 190, 146, 48, 201, 114, 116, 120, 252,
+ 206, 226, 4, 141, 200, 111, 93, 57,
+ 255, 182, 185, 241, 229, 2, 223, 29,
+ 43, 222, 109, 0, 1, 109, 133, 218,
+ 69, 130, 48, 143, 205, 49, 213, 16,
+ 14, 89, 18, 254, 133, 161, 114, 244,
+ 158, 193, 188, 6, 52, 87, 163, 45,
+ 159, 2, 122, 109, 253, 102, 216, 151,
+ 41, 89, 34, 149, 9, 130, 126, 76,
+ 46, 51, 192, 136, 248, 85, 142, 142,
+ 69, 254, 239, 213, 216, 183, 213, 1,
+ 223, 77, 77, 79, 189, 66, 29, 98,
+ 228, 21, 164, 113, 163, 121, 137, 152,
+ 241, 4, 3, 136, 42, 156, 145, 47,
+ 241, 173, 180, 232, 64, 227, 17, 177,
+ 180, 47, 156, 154, 0, 217, 112, 153,
+ 243, 22, 171, 181, 55, 182, 2, 49,
+ 100, 37, 173, 166, 252, 138, 25, 94,
+ 93, 77, 34, 251, 178, 136, 137, 105,
+ 182, 4, 84, 17, 84, 113, 212, 185,
+ 206, 114, 228, 135, 1, 138, 35, 20,
+ 25, 28, 165, 207, 108, 253, 45, 30,
+ 204, 128, 104, 168, 140, 158, 79, 4,
+ 51, 207, 105, 106, 67, 179, 77, 64,
+ 86, 2, 184, 240, 166, 169, 219, 63,
+ 101, 19, 185, 181, 64, 89, 184, 21,
+ 98, 133, 128, 51, 187, 69, 175, 101,
+ 106, 190, 208, 36, 150, 106, 35, 241,
+ 100, 72, 208, 209, 92, 127, 148, 173,
+ 202, 111, 62, 170, 168, 213, 244, 192,
+ 65, 170, 83, 223, 126, 206, 210, 5,
+ 213, 62, 169, 237, 161, 238, 46, 133,
+ 135, 64, 48, 215, 128, 91, 155, 0,
+ 19, 205, 131, 195, 29, 213, 235, 78,
+ 211, 84, 135, 67, 137, 56, 158, 9,
+ 200, 152, 188, 83, 190, 225, 211, 56,
+ 129, 81, 35, 128, 255, 148, 65, 11,
+ 122, 185, 99, 11, 225, 213, 150, 215,
+ 129, 213, 180, 51, 1, 212, 217, 174,
+ 237, 151, 132, 37, 20, 66, 199, 79,
+ 144, 192, 151, 24, 116, 15, 16, 36,
+ 242, 117, 56, 86, 43, 22, 100, 56,
+ 140, 20, 88, 226, 27, 185, 195, 139,
+ 35, 224, 51, 241, 211, 167, 223, 96,
+ 178, 214, 86, 86, 234, 44, 55, 178,
+ 108, 207, 219, 189, 146, 41, 0, 130,
+ 87, 12, 63, 65, 21, 239, 158, 140,
+ 35, 168, 205, 225, 36, 236, 60, 204,
+ 141, 36, 61, 177, 193, 209, 246, 232,
+ 93, 150, 236, 24, 46, 147, 204, 89,
+ 109, 198, 168, 196, 125, 64, 204, 239,
+ 207, 3, 244, 199, 110, 78, 174, 97,
+ 55, 142, 228, 206, 250, 50, 229, 81,
+ 33, 252, 186, 76, 118, 118, 249, 81,
+ 93, 157, 223, 244, 228, 130, 14, 50,
+ 218, 168, 138, 174, 155, 215, 164, 49,
+ 86, 147, 69, 6, 216, 207, 183, 21,
+ 172, 152, 176, 223, 115, 63, 152, 6,
+ 205, 118, 58, 184, 249, 197, 180, 132,
+ 135, 123, 67, 178, 0, 175, 17, 72,
+ 215, 187, 137, 132, 183, 156, 237, 15,
+ 12, 198, 19, 137, 255, 249, 74, 168,
+ 70, 37, 26, 254, 129, 143, 193, 156,
+ 68, 206, 125, 24, 240, 149, 198, 29,
+ 177, 246, 253, 214, 165, 93, 114, 30,
+ 183, 104, 71, 186, 250, 147, 154, 103,
+ 221, 23, 208, 201, 142, 67, 199, 78,
+ 202, 13, 192, 192, 112, 129, 202, 161,
+ 92, 230, 106, 34, 190, 172, 187, 199,
+ 141, 160, 41, 41, 34, 109, 21, 92,
+ 129, 155, 154, 27, 171, 109, 9, 77,
+ 28, 153, 177, 162, 55, 254, 27, 204,
+ 195, 193, 151, 60, 153, 12, 43, 226,
+ 74, 146, 77, 71, 218, 117, 220, 185,
+ 209, 161, 107, 249, 60, 3, 82, 28,
+ 42, 234, 171, 27, 156, 103, 8, 101,
+ 76, 182, 217, 151, 67, 254, 198, 83,
+ 243, 29, 70, 105, 215, 237, 73, 202,
+ 102, 0, 28, 199, 53, 62, 140, 168,
+ 65, 243, 149, 205, 203, 231, 180, 119,
+ 56, 208, 12, 166, 178, 221, 192, 10,
+ 156, 234, 49, 12, 129, 94, 23, 233,
+ 139, 246, 240, 44, 48, 130, 159, 201,
+ 179, 94, 122, 23, 126, 135, 236, 56,
+ 239, 200, 95, 163, 162, 104, 187, 175,
+ 205, 20, 125, 85, 66, 140, 86, 189,
+ 190, 218, 162, 216, 22, 163, 75, 140,
+ 128, 21, 227, 174, 149, 73, 193, 250,
+ 202, 215, 125, 48, 14, 206, 217, 118,
+ 96, 146, 158, 32, 126, 150, 128, 12,
+ 2, 243, 32, 80, 211, 114, 60, 240,
+ 79, 201, 224, 94, 229, 210, 10, 250,
+ 194, 34, 198, 104, 209, 141, 60, 10,
+ 30, 156, 241, 52, 192, 23, 212, 147,
+ 110, 16, 233, 255, 162, 238, 122, 250,
+ 16, 244, 162, 56, 130, 68, 63, 10,
+ 226, 95, 144, 158, 109, 70, 188, 29,
+ 175, 78, 110, 237, 132, 4, 16, 19,
+ 6, 38, 119, 75, 189, 250, 234, 57,
+ 3, 227, 66, 40, 250, 5, 255, 194,
+ 228, 171, 19, 228, 113, 174, 184, 215,
+ 115, 100, 152, 88, 112, 68, 215, 70,
+ 86, 63, 63, 226, 208, 75, 70, 87,
+ 75, 238, 38, 169, 238, 45, 55, 25,
+ 121, 10, 168, 22, 92, 25, 54, 230,
+ 52, 163, 145, 21, 25, 42, 62, 69,
+ 108, 227, 46, 236, 230, 209, 11, 14,
+ 242, 52, 92, 86, 91, 91, 29, 2,
+ 173, 193, 166, 24, 199, 127, 87, 202,
+ 46, 199, 32, 144, 213, 173, 243, 74,
+ 138, 201, 172, 124, 200, 14, 101, 177,
+ 159, 198, 111, 94, 139, 195, 221, 87,
+ 97, 10, 32, 125, 151, 205, 180, 232,
+ 140, 29, 50, 76, 118, 181, 250, 102,
+ 74, 120, 101, 76, 30, 41, 55, 42,
+ 94, 187, 17, 109, 200, 230, 232, 150,
+ 87, 253, 21, 220, 92, 179, 125, 172,
+ 115, 148, 36, 249, 166, 153, 227, 110,
+ 55, 228, 97, 41, 55, 157, 78, 238,
+ 180, 36, 130, 14, 209, 175, 6, 104,
+ 115, 148, 17, 168, 118, 42, 19, 159,
+ 189, 239, 60, 179, 104, 98, 201, 19,
+ 140, 241, 62, 92, 133, 189, 231, 70,
+ 1, 18, 128, 73, 47, 24, 174, 5,
+ 3, 24, 245, 82, 5, 131, 48, 164,
+ 56, 93, 86, 253, 151, 123, 233, 33,
+ 5, 102, 143, 199, 101, 180, 162, 86,
+ 123, 253, 11, 221, 140, 147, 252, 111,
+ 3, 21, 190, 52, 95, 114, 18, 208,
+ 192, 252, 175, 24, 123, 68, 87, 228,
+ 213, 19, 112, 245, 179, 154, 225, 226,
+ 245, 117, 191, 239, 7, 182, 188, 191,
+ 216, 206, 32, 38, 170, 218, 126, 183,
+ 20, 107, 104, 0, 123, 100, 134, 139,
+ 242, 130, 74, 175, 100, 6, 93, 217,
+ 214, 226, 192, 77, 224, 221, 76, 80,
+ 102, 36, 88, 184, 43, 62, 14, 206,
+ 203, 123, 147, 14, 83, 170, 142, 100,
+ 120, 232, 222, 145, 44, 13, 240, 229,
+ 90, 26, 9, 17, 199, 131, 67, 27,
+ 233, 10, 48, 218, 180, 51, 234, 255,
+ 106, 211, 211, 78, 179, 58, 197, 184,
+ 58, 133, 52, 153, 159, 253, 214, 173,
+ 144, 80, 157, 126, 91, 168, 248, 94,
+ 131, 219, 148, 191, 253, 12, 218, 166,
+ 33, 180, 195, 22, 193, 80, 180, 45,
+ 22, 244, 134, 179, 193, 177, 150, 241,
+ 11, 21, 38, 237, 113, 180, 208, 186,
+ 196, 244, 206, 131, 182, 161, 160, 11,
+ 222, 177, 0, 180, 238, 180, 108, 167,
+ 44, 97, 250, 154, 152, 111, 28, 173,
+ 253, 154, 25, 116, 28, 21, 116, 247,
+ 211, 103, 38, 36, 48, 11, 177, 210,
+ 135, 75, 97, 34, 115, 39, 85, 107,
+ 95, 230, 153, 90, 11, 162, 147, 159,
+ 180, 219, 200, 58, 239, 191, 121, 61,
+ 50, 1, 132, 59, 221, 126, 137, 104,
+ 25, 26, 206, 189, 113, 222, 134, 178,
+ 20, 14, 169, 65, 176, 205, 122, 119,
+ 18, 43, 160, 188, 210, 70, 61, 16,
+ 120, 159, 195, 244, 0, 177, 132, 12,
+ 87, 184, 219, 78, 118, 203, 54, 150,
+ 124, 21, 112, 124, 30, 178, 82, 7,
+ 226, 171, 229, 213, 148, 14, 76, 126,
+ 127, 4, 63, 29, 155, 37, 141, 167,
+ 193, 144, 78, 192, 158, 36, 215, 235,
+ 250, 163, 229, 149, 99, 221, 85, 104,
+ 148, 52, 241, 195, 10, 71, 88, 209,
+ 112, 52, 41, 41, 219, 95, 107, 195,
+ 124, 88, 167, 29, 233, 32, 182, 50,
+ 72, 185, 53, 84, 7, 89, 96, 66,
+ 238, 211, 168, 61, 76, 153, 24, 152,
+ 156, 220, 249, 149, 186, 71, 239, 177,
+ 65, 144, 80, 239, 19, 235, 215, 210,
+ 117, 91, 241, 84, 50, 135, 240, 132,
+ 184, 170, 110, 120, 192, 24, 234, 90,
+ 143, 184, 226, 189, 28, 136, 75, 200,
+ 32, 199, 229, 206, 238, 165, 216, 33,
+ 218, 16, 100, 107, 197, 38, 105, 87,
+ 43, 211, 17, 94, 247, 15, 167, 67,
+ 32, 26, 175, 105, 177, 161, 82, 148,
+ 36, 116, 99, 119, 99, 58, 12, 130,
+ 222, 207, 35, 85, 221, 205, 81, 10,
+ 181, 35, 155, 91, 116, 95, 185, 73,
+ 1, 227, 160, 189, 70, 146, 90, 123,
+ 66, 39, 246, 229, 138, 99, 132, 94,
+ 110, 211, 63, 4, 43, 148, 235, 22,
+ 234, 252, 90, 81, 97, 8, 76, 108,
+ 135, 54, 160, 82, 243, 69, 218, 254,
+ 115, 215, 78, 178, 236, 249, 124, 90,
+ 41, 77, 163, 128, 77, 159, 170, 95,
+ 131, 30, 122, 239, 78, 8, 81, 83,
+ 55, 216, 150, 220, 110, 201, 68, 135,
+ 175, 165, 139, 22, 121, 253, 92, 203,
+ 159, 222, 227, 14, 162, 142, 165, 144,
+ 140, 230, 56, 154, 162, 239, 92, 227,
+ 25, 186, 12, 0, 70, 32, 31, 146,
+ 105, 184, 107, 87, 81, 206, 40, 82,
+ 160, 67, 195, 17, 177, 91, 187, 62,
+ 92, 215, 198, 21, 29, 111, 194, 250,
+ 210, 104, 69, 180, 125, 194, 73, 248,
+ 158, 41, 63, 184, 182, 19, 223, 126,
+ 92, 64, 78, 241, 128, 37, 181, 66,
+ 41, 97, 252, 158, 142, 234, 205, 231,
+ 162, 175, 175, 246, 22, 53, 200, 50,
+ 234, 85, 173, 255, 205, 246, 73, 233,
+ 44, 240, 1, 178, 14, 201, 7, 100,
+ 59, 2, 24, 53, 164, 103, 97, 52,
+ 156, 226, 150, 19, 214, 31, 24, 182,
+ 223, 31, 216, 143, 162, 130, 0, 93,
+ 157, 236, 222, 94, 132, 57, 124, 165,
+ 7, 3, 162, 48, 26, 232, 208, 114,
+ 33, 209, 199, 221, 19, 219, 14, 249,
+ 78, 252, 252, 202, 193, 10, 244, 32,
+ 16, 18, 196, 211, 156, 163, 7, 67,
+ 70, 94, 148, 57, 160, 2, 54, 211,
+ 181, 76, 95, 54, 85, 110, 36, 4,
+ 36, 252, 139, 46, 176, 177, 15, 173,
+ 153, 120, 214, 91, 149, 17, 182, 189,
+ 192, 98, 146, 173, 150, 102, 216, 250,
+ 203, 147, 113, 132, 96, 110, 103, 182,
+ 179, 176, 122, 59, 70, 58, 91, 108,
+ 126, 67, 22, 179, 86, 94, 162, 232,
+ 71, 219, 20, 181, 183, 238, 194, 120,
+ 196, 36, 90, 176, 30, 66, 71, 107,
+ 103, 243, 34, 210, 132, 148, 65, 219,
+ 83, 42, 133, 27, 44, 226, 160, 96,
+ 195, 86, 3, 153, 255, 216, 211, 159,
+ 50, 163, 40, 137, 247, 95, 22, 201,
+ 121, 244, 48, 119, 178, 13, 122, 249,
+ 61, 84, 7, 94, 189, 95, 72, 143,
+ 107, 127, 52, 236, 218, 157, 21, 218,
+ 254, 88, 8, 39, 105, 176, 28, 131,
+ 119, 153, 108, 241, 133, 198, 161, 245,
+ 31, 165, 192, 237, 208, 112, 209, 148,
+ 234, 238, 136, 136, 97, 52, 211, 6,
+ 170, 210, 92, 84, 179, 201, 147, 13,
+ 1, 50, 169, 91, 105, 228, 221, 27,
+ 111, 119, 214, 147, 243, 59, 203, 54,
+ 181, 234, 214, 177, 78, 100, 62, 60,
+ 149, 158, 197, 47, 224, 252, 128, 248,
+ 145, 253, 239, 116, 58, 220, 209, 241,
+ 150, 87, 68, 20, 133, 86, 234, 213,
+ 196, 76, 212, 53, 105, 61, 68, 238,
+ 193, 29, 113, 37, 239, 130, 144, 145,
+ 196, 109, 201, 51, 23, 245, 17, 129,
+ 248, 206, 97, 84, 144, 91, 146, 71,
+ 50, 8, 185, 8, 108, 170, 231, 125,
+ 28, 225, 17, 241, 238, 110, 102, 248,
+ 246, 229, 89, 148, 112, 65, 51, 201,
+ 33, 102, 123, 0, 86, 65, 23, 219,
+ 39, 252, 49, 155, 217, 29, 12, 205,
+ 235, 93, 130, 114, 244, 133, 23, 219,
+ 73, 18, 70, 94, 83, 101, 230, 222,
+ 173, 15, 100, 244, 80, 227, 42, 93,
+ 101, 31, 39, 148, 63, 39, 164, 192,
+ 162, 179, 164, 146, 1, 104, 96, 86,
+ 59, 149, 41, 153, 219, 14, 216, 249,
+ 96, 219, 219, 50, 116, 139, 102, 142,
+ 138, 188, 87, 48, 78, 90, 40, 19,
+ 113, 244, 102, 91, 224, 247, 210, 27,
+ 46, 117, 211, 39, 140, 114, 81, 254,
+ 14, 114, 103, 184, 155, 198, 35, 136,
+ 168, 208, 100, 163, 203, 111, 48, 210,
+ 133, 42, 189, 190, 38, 135, 221, 25,
+ 174, 215, 112, 76, 90, 50, 44, 141,
+ 104, 68, 119, 235, 118, 221, 107, 246,
+ 178, 10, 59, 137, 228, 12, 32, 145,
+ 134, 236, 71, 40, 31, 242, 14, 60,
+ 178, 133, 172, 56, 171, 252, 251, 9,
+ 124, 227, 155, 54, 252, 31, 168, 80,
+ 32, 133, 41, 244, 99, 148, 102, 236,
+ 22, 212, 147, 186, 65, 31, 56, 230,
+ 190, 47, 123, 213, 8, 53, 194, 43,
+ 111, 230, 210, 72, 38, 145, 136, 59,
+ 69, 129, 10, 239, 251, 28, 174, 52,
+ 32, 104, 144, 175, 161, 175, 236, 158,
+ 36, 208, 9, 181, 178, 173, 183, 51,
+ 22, 178, 232, 228, 4, 172, 253, 29,
+ 162, 204, 192, 36, 184, 31, 11, 34,
+ 246, 137, 67, 132, 164, 220, 195, 129,
+ 176, 43, 1, 9, 63, 1, 44, 156,
+ 131, 85, 157, 195, 85, 222, 25, 95,
+ 224, 235, 218, 214, 243, 161, 213, 246,
+ 94, 239, 159, 65, 241, 222, 125, 161,
+ 114, 124, 49, 227, 145, 73, 125, 147,
+ 70, 46, 19, 23, 196, 193, 223, 130,
+ 78, 14, 51, 235, 10, 22, 56, 47,
+ 184, 252, 129, 37, 2, 197, 71, 247,
+ 35, 37, 47, 110, 111, 156, 57, 188,
+ 17, 175, 115, 201, 167, 193, 32, 1,
+ 236, 199, 158, 145, 51, 8, 255, 94,
+ 77, 237, 46, 31, 253, 122, 27, 142,
+ 10, 60, 32, 177, 251, 120, 12, 82,
+ 129, 148, 172, 113, 50, 17, 148, 226,
+ 241, 36, 15, 26, 48, 105, 152, 81,
+ 78, 208, 245, 248, 189, 4, 252, 31,
+ 68, 115, 226, 82, 238, 40, 228, 245,
+ 165, 24, 225, 137, 74, 107, 108, 89,
+ 33, 191, 80, 131, 140, 140, 234, 56,
+ 37, 84, 115, 112, 235, 6, 148, 159,
+ 219, 251, 173, 168, 33, 45, 128, 1,
+ 150, 66, 180, 230, 248, 141, 111, 96,
+ 132, 148, 175, 224, 73, 226, 52, 130,
+ 82, 72, 64, 254, 2, 255, 30, 99,
+ 215, 186, 12, 251, 35, 7, 253, 163,
+ 187, 157, 39, 114, 222, 75, 164, 197,
+ 133, 213, 89, 230, 115, 94, 150, 188,
+ 17, 132, 245, 224, 231, 124, 27, 246,
+ 242, 159, 71, 104, 150, 22, 24, 174,
+ 241, 165, 140, 133, 18, 129, 226, 103,
+ 251, 171, 139, 213, 183, 235, 110, 193,
+ 10, 74, 73, 76, 75, 106, 206, 165,
+ 96, 108, 103, 139, 147, 144, 52, 239,
+ 141, 181, 39, 6, 81, 245, 187, 64,
+ 22, 112, 86, 201, 39, 190, 123, 140,
+ 17, 6, 231, 206, 74, 102, 93, 79,
+ 238, 54, 159, 53, 76, 100, 18, 3,
+ 169, 53, 187, 205, 79, 49, 152, 148,
+ 63, 203, 160, 87, 67, 178, 115, 125,
+ 200, 18, 94, 169, 19, 225, 135, 231,
+ 84, 188, 71, 218, 107, 159, 143, 29,
+ 210, 250, 0, 81, 71, 3, 67, 90,
+ 202, 33, 235, 19, 210, 77, 218, 236,
+ 243, 218, 169, 244, 90, 183, 7, 245,
+ 43, 202, 0, 76, 176, 195, 199, 112,
+ 166, 97, 46, 126, 175, 72, 221, 28,
+ 232, 136, 224, 35, 213, 73, 199, 144,
+ 162, 0, 169, 189, 158, 38, 13, 98,
+ 30, 101, 64, 171, 75, 218, 247, 202,
+ 196, 196, 22, 94, 97, 164, 254, 201,
+ 234, 213, 232, 186, 8, 227, 207, 195,
+ 157, 71, 59, 150, 78, 85, 74, 118,
+ 65, 65, 141, 62, 1, 200, 57, 223,
+ 64, 111, 237, 157, 230, 195, 224, 200,
+ 80, 48, 84, 41, 115, 58, 202, 108,
+ 109, 22, 211, 114, 152, 166, 8, 38,
+ 140, 204, 120, 195, 157, 149, 95, 36,
+ 233, 255, 93, 190, 99, 98, 43, 22,
+ 236, 213, 144, 152, 124, 76, 15, 173,
+ 244, 47, 197, 20, 105, 180, 42, 107,
+ 173, 59, 121, 123, 68, 125, 92, 157,
+ 13, 251, 152, 127, 66, 34, 235, 59,
+ 108, 192, 234, 94, 152, 99, 208, 61,
+ 84, 39, 154, 51, 217, 226, 8, 149,
+ 97, 217, 157, 58, 208, 47, 84, 61,
+ 61, 155, 90, 189, 32, 76, 99, 79,
+ 36, 180, 77, 202, 22, 38, 211, 200,
+ 247, 189, 209, 59, 239, 25, 133, 51,
+ 110, 232, 100, 168, 37, 130, 32, 45,
+ 40, 193, 64, 131, 165, 144, 204, 57,
+ 250, 228, 67, 219, 62, 14, 76, 160,
+ 200, 98, 149, 111, 81, 90, 240, 81,
+ 43, 200, 3, 211, 3, 87, 149, 210,
+ 110, 200, 134, 166, 243, 86, 166, 202,
+ 127, 205, 152, 175, 213, 169, 113, 105,
+ 39, 249, 52, 35, 61, 195, 246, 101,
+ 78, 178, 90, 128, 2, 34, 80, 120,
+ 58, 123, 254, 164, 53, 1, 58, 52,
+ 25, 92, 56, 119, 134, 210, 115, 59,
+ 158, 52, 163, 245, 80, 64, 146, 189,
+ 134, 137, 92, 96, 184, 77, 32, 142,
+ 86, 220, 131, 119, 205, 116, 63, 190,
+ 140, 36, 211, 169, 82, 196, 46, 85,
+ 78, 131, 166, 228, 168, 158, 4, 82,
+ 4, 95, 223, 226, 4, 84, 205, 7,
+ 131, 129, 37, 90, 92, 151, 204, 229,
+ 66, 123, 242, 121, 76, 191, 250, 152,
+ 204, 112, 101, 181, 246, 136, 69, 203,
+ 85, 178, 18, 203, 24, 57, 199, 29,
+ 250, 126, 245, 195, 55, 118, 53, 194,
+ 230, 185, 99, 181, 122, 168, 253, 76,
+ 207, 118, 91, 3, 162, 166, 248, 253,
+ 92, 60, 30, 34, 119, 68, 76, 207,
+ 81, 119, 209, 46, 197, 145, 119, 186,
+ 53, 40, 161, 237, 172, 167, 63, 11,
+ 123, 225, 151, 141, 21, 91, 39, 124,
+ 47, 65, 13, 37, 94, 38, 68, 62,
+ 189, 179, 119, 175, 38, 91, 29, 4,
+ 190, 33, 215, 81, 249, 247, 67, 19,
+ 137, 228, 231, 138, 48, 41, 38, 131,
+ 191, 222, 0, 120, 189, 9, 217, 43,
+ 162, 116, 162, 103, 249, 113, 43, 97,
+ 138, 44, 26, 199, 110, 173, 185, 53,
+ 23, 174, 60, 82, 174, 213, 82, 129,
+ 195, 209, 246, 85, 123, 191, 254, 187,
+ 111, 230, 149, 187, 23, 53, 57, 248,
+ 25, 240, 65, 59, 50, 117, 137, 18,
+ 247, 223, 105, 154, 195, 234, 109, 45,
+ 11, 12, 133, 66, 76, 37, 80, 243,
+ 103, 9, 113, 107, 220, 8, 105, 244,
+ 32, 58, 1, 111, 29, 215, 13, 36,
+ 211, 16, 98, 17, 230, 57, 187, 127,
+ 80, 71, 156, 24, 215, 214, 146, 1,
+ 232, 125, 57, 81, 134, 192, 184, 209,
+ 194, 4, 63, 113, 231, 112, 131, 123,
+ 90, 196, 94, 34, 12, 122, 168, 180,
+ 193, 70, 137, 213, 251, 76, 63, 166,
+ 176, 34, 141, 105, 114, 220, 208, 240,
+ 42, 44, 155, 185, 145, 158, 195, 150,
+ 167, 10, 27, 1, 59, 247, 119, 199,
+ 15, 172, 196, 156, 114, 5, 6, 238,
+ 108, 166, 247, 125, 62, 246, 200, 138,
+ 142, 206, 63, 39, 151, 27, 150, 241,
+ 182, 21, 55, 68, 191, 103, 28, 221,
+ 36, 173, 131, 127, 203, 11, 177, 98,
+ 132, 18, 123, 238, 202, 154, 139, 181,
+ 226, 126, 55, 200, 103, 42, 193, 104,
+ 114, 141, 143, 203, 194, 57, 1, 16,
+ 188, 129, 29, 144, 149, 156, 138, 247,
+ 157, 149, 19, 81, 72, 16, 155, 42,
+ 248, 56, 95, 246, 18, 168, 153, 79,
+ 101, 156, 224, 159, 7, 35, 1, 38,
+ 212, 87, 214, 162, 173, 95, 193, 70,
+ 88, 212, 194, 141, 39, 178, 104, 75,
+ 201, 1, 202, 49, 92, 29, 134, 249,
+ 135, 23, 226, 165, 223, 224, 241, 174,
+ 47, 77, 221, 114, 15, 154, 145, 47,
+ 196, 215, 41, 113, 129, 29, 71, 64,
+ 120, 215, 206, 224, 137, 34, 114, 215,
+ 116, 85, 245, 252, 32, 34, 72, 28,
+ 116, 75, 237, 155, 250, 188, 2, 91,
+ 47, 242, 127, 167, 90, 195, 14, 216,
+ 217, 163, 212, 48, 78, 212, 206, 85,
+ 108, 79, 244, 211, 180, 166, 84, 132,
+ 209, 175, 34, 49, 203, 93, 140, 81,
+ 40, 82, 195, 68, 98, 170, 234, 99,
+ 58, 9, 234, 115, 150, 9, 225, 85,
+ 170, 159, 156, 189, 223, 40, 69, 185,
+ 5, 242, 142, 136, 69, 71, 163, 211,
+ 197, 69, 237, 71, 11, 26, 242, 203,
+ 110, 66, 115, 193, 150, 100, 185, 38,
+ 117, 105, 61, 242, 152, 237, 114, 68,
+ 243, 21, 70, 18, 111, 252, 77, 118,
+ 200, 139, 208, 50, 220, 199, 42, 101,
+ 110, 89, 204, 99, 108, 77, 163, 78,
+ 238, 138, 72, 39, 80, 149, 79, 84,
+ 71, 213, 94, 163, 235, 142, 97, 39,
+ 109, 90, 162, 173, 199, 185, 133, 243,
+ 54, 170, 107, 2, 103, 33, 71, 188,
+ 38, 100, 86, 239, 221, 79, 147, 135,
+ 156, 227, 245, 101, 97, 174, 36, 237,
+ 120, 72, 123, 88, 31, 74, 175, 30,
+ 120, 68, 168, 20, 98, 5, 83, 65,
+ 204, 20, 60, 140, 34, 113, 198, 13,
+ 227, 65, 229, 208, 95, 193, 233, 86,
+ 177, 83, 1, 200, 130, 7, 251, 49,
+ 219, 71, 73, 177, 210, 25, 214, 252,
+ 97, 184, 167, 133, 212, 104, 239, 140,
+ 111, 101, 203, 44, 219, 0, 237, 101,
+ 174, 42, 130, 162, 237, 156, 187, 51,
+ 120, 32, 53, 152, 158, 242, 52, 0,
+ 21, 82, 223, 1, 115, 57, 71, 43,
+ 109, 82, 35, 130, 67, 44, 131, 52,
+ 135, 136, 81, 212, 220, 215, 9, 228,
+ 44, 118, 39, 249, 18, 232, 229, 71,
+ 255, 167, 44, 1, 106, 89, 230, 86,
+ 188, 135, 179, 143, 143, 124, 226, 144,
+ 186, 61, 224, 205, 106, 37, 89, 210,
+ 242, 40, 192, 95, 81, 133, 134, 155,
+ 238, 205, 207, 66, 124, 195, 238, 92,
+ 174, 209, 84, 152, 197, 72, 124, 4,
+ 141, 223, 179, 144, 103, 112, 85, 129,
+ 247, 30, 23, 42, 19, 249, 64, 63,
+ 231, 19, 21, 127, 217, 191, 21, 209,
+ 89, 12, 156, 43, 167, 137, 26, 213,
+ 19, 243, 193, 43, 81, 170, 124, 111,
+ 152, 89, 184, 9, 142, 20, 176, 158,
+ 108, 59, 126, 250, 190, 173, 9, 183,
+ 137, 221, 117, 58, 131, 0, 5, 146,
+ 114, 38, 182, 29, 142, 227, 101, 92,
+ 123, 147, 189, 208, 202, 10, 74, 49,
+ 68, 89, 217, 178, 114, 136, 90, 179,
+ 192, 92, 135, 47, 185, 212, 170, 189,
+ 177, 114, 157, 238, 153, 21, 132, 29,
+ 118, 46, 55, 198, 219, 139, 42, 150,
+ 210, 80, 74, 8, 181, 190, 118, 255,
+ 221, 82, 141, 16, 17, 22, 169, 27,
+ 65, 247, 21, 164, 136, 237, 74, 197,
+ 89, 22, 231, 177, 188, 6, 55, 124,
+ 214, 175, 98, 213, 93, 184, 107, 44,
+ 136, 16, 63, 249, 205, 119, 53, 230,
+ 88, 246, 229, 126, 148, 25, 54, 172,
+ 218, 18, 216, 179, 63, 105, 0, 210,
+ 34, 109, 117, 43, 234, 96, 96, 61,
+ 144, 29, 46, 64, 86, 255, 27, 92,
+ 84, 105, 14, 150, 131, 205, 147, 236,
+ 3, 235, 157, 89, 96, 151, 20, 234,
+ 154, 253, 210, 48, 232, 84, 128, 8,
+ 25, 89, 82, 32, 152, 205, 179, 12,
+ 3, 232, 103, 251, 20, 74, 247, 209,
+ 227, 188, 111, 175, 24, 24, 235, 13,
+ 123, 240, 28, 6, 103, 199, 4, 149,
+ 179, 226, 34, 121, 120, 147, 240, 68,
+ 174, 188, 82, 214, 164, 55, 36, 40,
+ 20, 177, 11, 107, 3, 24, 2, 157,
+ 155, 109, 158, 134, 218, 90, 99, 124,
+ 213, 40, 72, 224, 173, 97, 110, 113,
+ 89, 193, 188, 209, 27, 19, 228, 200,
+ 133, 245, 164, 188, 213, 192, 206, 73,
+ 58, 87, 93, 197, 140, 145, 38, 218,
+ 188, 222, 87, 208, 100, 84, 153, 71,
+ 4, 87, 45, 209, 9, 46, 86, 107,
+ 28, 40, 148, 152, 176, 179, 80, 235,
+ 89, 247, 126, 88, 179, 23, 148, 106,
+ 146, 218, 187, 105, 202, 56, 170, 4,
+ 197, 129, 82, 110, 129, 102, 47, 180,
+ 169, 77, 10, 223, 160, 111, 185, 244,
+ 75, 169, 110, 251, 141, 180, 142, 75,
+ 41, 129, 82, 183, 12, 165, 237, 242,
+ 73, 118, 72, 81, 127, 214, 66, 95,
+ 135, 27, 179, 100, 23, 103, 83, 173,
+ 164, 34, 123, 47, 71, 219, 69, 216,
+ 178, 110, 215, 162, 219, 134, 138, 79,
+ 208, 35, 146, 19, 122, 169, 93, 7,
+ 84, 95, 62, 223, 79, 8, 253, 73,
+ 243, 98, 93, 235, 159, 46, 121, 163,
+ 37, 119, 47, 59, 225, 206, 192, 9,
+ 128, 200, 26, 154, 112, 179, 18, 153,
+ 181, 105, 205, 229, 76, 160, 77, 242,
+ 21, 144, 192, 8, 227, 41, 1, 180,
+ 34, 250, 157, 121, 255, 137, 216, 169,
+ 205, 95, 115, 237, 151, 245, 252, 81,
+ 176, 239, 207, 30, 39, 36, 110, 97,
+ 195, 33, 12, 171, 217, 83, 246, 27,
+ 147, 194, 253, 223, 173, 110, 120, 248,
+ 193, 219, 117, 230, 153, 171, 69, 251,
+ 101, 51, 24, 101, 5, 83, 69, 90,
+ 235, 172, 180, 151, 193, 194, 118, 153,
+ 148, 50, 171, 170, 52, 13, 183, 132,
+ 228, 87, 69, 220, 210, 206, 32, 208,
+ 192, 143, 173, 212, 249, 103, 201, 140,
+ 173, 185, 101, 63, 146, 137, 164, 55,
+ 250, 248, 215, 132, 243, 107, 100, 37,
+ 0, 118, 92, 246, 162, 231, 227, 72,
+ 123, 148, 249, 255, 82, 152, 242, 221,
+ 137, 61, 213, 150, 89, 207, 105, 254,
+ 48, 219, 134, 186, 200, 127, 4, 233,
+ 64, 134, 99, 53, 3, 36, 244, 180,
+ 67, 241, 197, 191, 39, 240, 124, 42,
+ 228, 74, 137, 28, 166, 74, 130, 124,
+ 117, 76, 209, 196, 48, 148, 186, 186,
+ 49, 141, 132, 38, 13, 241, 57, 181,
+ 74, 67, 67, 150, 46, 32, 254, 136,
+ 198, 156, 51, 140, 92, 197, 195, 243,
+ 207, 85, 16, 216, 88, 92, 69, 134,
+ 13, 112, 165, 169, 205, 194, 118, 186,
+ 171, 113, 49, 88, 72, 197, 239, 212,
+ 30, 168, 197, 107, 181, 56, 181, 42,
+ 118, 72, 12, 61, 209, 139, 70, 119,
+ 5, 137, 176, 190, 175, 233, 159, 233,
+ 44, 112, 6, 52, 85, 84, 221, 163,
+ 64, 115, 255, 91, 33, 229, 217, 168,
+ 254, 14, 231, 63, 156, 226, 105, 118,
+ 231, 140, 54, 4, 198, 61, 247, 163,
+ 21, 70, 158, 231, 172, 156, 112, 143,
+ 55, 252, 103, 29, 86, 11, 54, 173,
+ 245, 2, 63, 17, 156, 227, 91, 97,
+ 235, 155, 89, 8, 242, 145, 122, 167,
+ 23, 29, 82, 167, 252, 217, 124, 189,
+ 48, 47, 139, 173, 146, 107, 19, 18,
+ 32, 7, 71, 228, 198, 48, 166, 142,
+ 27, 81, 85, 27, 88, 80, 244, 9,
+ 79, 238, 214, 131, 31, 144, 31, 86,
+ 83, 187, 216, 46, 58, 112, 30, 19,
+ 21, 85, 102, 3, 231, 66, 164, 143,
+ 42, 131, 140, 127, 16, 138, 49, 73,
+ 103, 185, 97, 93, 55, 180, 113, 161,
+ 209, 93, 10, 156, 7, 27, 45, 78,
+ 86, 158, 130, 73, 121, 32, 174, 201,
+ 27, 112, 140, 229, 53, 42, 51, 131,
+ 113, 71, 202, 234, 123, 154, 241, 69,
+ 0, 216, 7, 66, 179, 209, 228, 250,
+ 80, 183, 187, 162, 229, 137, 24, 67,
+ 199, 84, 211, 227, 110, 160, 233, 81,
+ 10, 108, 202, 1, 182, 39, 200, 154,
+ 247, 1, 157, 165, 193, 239, 62, 148,
+ 50, 181, 254, 119, 152, 70, 16, 43,
+ 156, 40, 13, 67, 109, 161, 36, 149,
+ 221, 168, 146, 14, 169, 154, 224, 224,
+ 185, 192, 3, 182, 135, 108, 102, 183,
+ 110, 41, 203, 177, 58, 83, 150, 93,
+ 177, 132, 104, 214, 118, 96, 177, 188,
+ 41, 244, 246, 172, 211, 156, 54, 45,
+ 47, 205, 114, 52, 36, 98, 247, 42,
+ 223, 221, 85, 237, 52, 68, 112, 12,
+ 53, 66, 134, 244, 149, 185, 79, 44,
+ 212, 103, 117, 31, 185, 154, 122, 51,
+ 244, 247, 174, 53, 161, 8, 191, 45,
+ 87, 35, 212, 15, 99, 249, 87, 9,
+ 142, 246, 205, 68, 165, 87, 19, 61,
+ 49, 39, 211, 166, 66, 121, 166, 213,
+ 162, 21, 74, 110, 208, 200, 242, 209,
+ 175, 4, 242, 39, 108, 220, 233, 30,
+ 97, 231, 219, 113, 42, 121, 166, 123,
+ 227, 89, 120, 50, 204, 70, 121, 110,
+ 101, 20, 73, 235, 244, 179, 225, 57,
+ 92, 48, 64, 163, 157, 245, 254, 141,
+ 132, 81, 150, 59, 146, 166, 227, 21,
+ 60, 15, 182, 249, 114, 25, 239, 145,
+ 167, 241, 96, 49, 249, 235, 189, 108,
+ 113, 100, 139, 247, 211, 188, 219, 60,
+ 35, 255, 112, 155, 21, 187, 55, 26,
+ 115, 235, 29, 233, 48, 170, 24, 126,
+ 146, 220, 199, 187, 111, 81, 138, 230,
+ 23, 88, 252, 153, 143, 142, 27, 159,
+ 241, 136, 196, 87, 253, 225, 246, 51,
+ 67, 250, 243, 102, 127, 110, 0, 168,
+ 154, 250, 43, 37, 17, 207, 60, 173,
+ 17, 156, 148, 104, 36, 0, 60, 95,
+ 95, 208, 107, 128, 60, 115, 142, 1,
+ 237, 10, 244, 36, 206, 231, 101, 247,
+ 211, 155, 87, 198, 24, 162, 137, 161,
+ 249, 245, 143, 31, 173, 200, 104, 90,
+ 226, 166, 254, 252, 221, 212, 8, 75,
+ 69, 57, 159, 30, 141, 141, 53, 207,
+ 202, 246, 28, 45, 252, 56, 230, 248,
+ 149, 41, 145, 182, 182, 242, 82, 178,
+ 130, 237, 110, 170, 30, 172, 174, 155,
+ 165, 154, 191, 142, 117, 218, 210, 165,
+ 65, 152, 95, 120, 27, 164, 70, 64,
+ 54, 197, 229, 146, 91, 195, 30, 0,
+ 167, 165, 161, 127, 84, 92, 168, 238,
+ 40, 199, 230, 116, 1, 55, 7, 210,
+ 200, 228, 18, 15, 72, 46, 39, 188,
+ 229, 119, 45, 228, 215, 41, 219, 94,
+ 75, 185, 100, 131, 47, 221, 121, 31,
+ 185, 120, 7, 124, 86, 40, 206, 15,
+ 168, 8, 128, 155, 64, 134, 198, 252,
+ 194, 167, 58, 149, 89, 119, 119, 31,
+ 196, 102, 230, 59, 152, 64, 47, 87,
+ 31, 6, 122, 124, 180, 187, 142, 86,
+ 59, 78, 93, 165, 212, 251, 184, 157,
+ 21, 67, 39, 254, 40, 4, 98, 174,
+ 104, 205, 80, 128, 94, 215, 246, 176,
+ 41, 48, 172, 2, 43, 250, 9, 178,
+ 187, 59, 215, 23, 158, 101, 97, 36,
+ 204, 6, 155, 244, 107, 227, 2, 199,
+ 46, 21, 80, 232, 41, 88, 176, 208,
+ 214, 80, 205, 129, 61, 203, 34, 94,
+ 172, 10, 176, 132, 128, 56, 214, 235,
+ 46, 86, 85, 125, 130, 228, 147, 251,
+ 200, 25, 153, 247, 207, 197, 118, 159,
+ 208, 124, 127, 170, 164, 174, 97, 28,
+ 88, 47, 71, 229, 74, 172, 208, 157,
+ 163, 62, 51, 159, 130, 133, 77, 123,
+ 144, 224, 201, 242, 75, 251, 204, 162,
+ 243, 192, 66, 127, 75, 109, 204, 120,
+ 130, 50, 183, 56, 112, 71, 51, 98,
+ 184, 13, 139, 14, 242, 134, 129, 74,
+ 99, 252, 244, 195, 137, 0, 159, 111,
+ 236, 107, 22, 187, 106, 203, 232, 64,
+ 112, 183, 157, 232, 148, 101, 2, 166,
+ 229, 24, 183, 58, 192, 13, 136, 25,
+ 250, 195, 182, 1, 253, 201, 108, 95,
+ 32, 99, 226, 46, 156, 104, 224, 99,
+ 150, 78, 134, 247, 62, 113, 212, 141,
+ 155, 38, 52, 39, 174, 47, 122, 221,
+ 218, 207, 147, 29, 29, 188, 44, 24,
+ 132, 155, 86, 192, 140, 117, 182, 38,
+ 222, 123, 100, 248, 94, 97, 7, 236,
+ 5, 188, 247, 183, 197, 77, 103, 97,
+ 37, 219, 220, 218, 163, 15, 111, 144,
+ 243, 214, 4, 160, 9, 234, 77, 228,
+ 50, 184, 175, 238, 96, 52, 193, 92,
+ 131, 184, 223, 141, 189, 56, 21, 240,
+ 192, 83, 112, 141, 74, 119, 143, 20,
+ 175, 5, 198, 83, 200, 126, 165, 131,
+ 255, 99, 92, 186, 27, 35, 15, 20,
+ 209, 201, 129, 70, 148, 251, 93, 131,
+ 94, 59, 22, 185, 201, 57, 201, 188,
+ 147, 152, 57, 66, 44, 122, 94, 145,
+ 73, 249, 231, 71, 123, 61, 153, 29,
+ 213, 181, 67, 0, 56, 78, 63, 255,
+ 82, 195, 80, 155, 18, 162, 182, 102,
+ 108, 50, 134, 78, 205, 114, 246, 245,
+ 89, 181, 112, 140, 175, 191, 212, 165,
+ 110, 240, 54, 202, 198, 35, 166, 5,
+ 65, 87, 17, 218, 19, 221, 154, 45,
+ 197, 254, 65, 109, 232, 70, 215, 33,
+ 26, 2, 73, 197, 2, 156, 185, 142,
+ 67, 134, 135, 192, 14, 78, 77, 160,
+ 99, 180, 79, 98, 4, 187, 33, 141,
+ 192, 70, 149, 98, 213, 203, 193, 27,
+ 208, 65, 205, 125, 60, 16, 182, 37,
+ 21, 75, 22, 220, 0, 166, 172, 238,
+ 70, 87, 50, 70, 35, 190, 235, 177,
+ 176, 241, 95, 71, 142, 102, 135, 162,
+ 164, 238, 179, 181, 81, 10, 152, 220,
+ 98, 234, 170, 185, 7, 84, 244, 88,
+ 12, 91, 190, 194, 126, 159, 45, 238,
+ 52, 202, 45, 2, 206, 144, 171, 124,
+ 189, 139, 8, 69, 86, 13, 50, 72,
+ 148, 170, 135, 135, 46, 218, 201, 15,
+ 102, 153, 223, 3, 193, 173, 94, 15,
+ 0, 95, 167, 53, 155, 34, 197, 106,
+ 88, 11, 192, 18, 28, 181, 145, 244,
+ 222, 137, 66, 73, 158, 147, 235, 247,
+ 83, 17, 212, 82, 241, 31, 13, 66,
+ 12, 57, 60, 10, 155, 70, 195, 128,
+ 12, 21, 90, 177, 190, 241, 57, 206,
+ 121, 0, 135, 181, 144, 89, 104, 207,
+ 104, 72, 75, 13, 187, 26, 41, 42,
+ 138, 49, 102, 1, 36, 234, 84, 172,
+ 183, 120, 138, 167, 92, 238, 226, 193,
+ 74, 141, 214, 117, 8, 243, 234, 62,
+ 79, 35, 117, 103, 135, 148, 215, 227,
+ 28, 89, 99, 254, 69, 8, 137, 149,
+ 170, 5, 182, 117, 102, 160, 111, 232,
+ 232, 112, 37, 182, 15, 120, 72, 177,
+ 249, 69, 83, 14, 40, 81, 123, 6,
+ 55, 157, 159, 196, 174, 2, 174, 102,
+ 222, 105, 16, 108, 91, 62, 255, 74,
+ 215, 174, 35, 43, 30, 9, 72, 151,
+ 187, 49, 153, 32, 181, 140, 112, 141,
+ 230, 73, 72, 142, 150, 31, 180, 95,
+ 100, 26, 144, 246, 151, 6, 239, 215,
+ 71, 109, 35, 51, 172, 244, 165, 159,
+ 229, 56, 70, 111, 193, 60, 67, 122,
+ 23, 183, 123, 41, 43, 218, 65, 32,
+ 137, 153, 6, 97, 159, 159, 233, 193,
+ 111, 147, 190, 221, 230, 47, 198, 130,
+ 180, 77, 110, 35, 176, 32, 173, 148,
+ 221, 38, 180, 75, 107, 32, 127, 227,
+ 254, 142, 133, 29, 35, 19, 234, 50,
+ 160, 196, 248, 164, 153, 63, 222, 196,
+ 252, 67, 178, 115, 176, 243, 110, 134,
+ 61, 184, 226, 14, 233, 42, 74, 212,
+ 110, 116, 214, 118, 22, 0, 193, 49,
+ 196, 130, 96, 71, 118, 61, 191, 115,
+ 192, 47, 83, 3, 36, 209, 101, 67,
+ 106, 31, 106, 214, 246, 117, 89, 87,
+ 230, 108, 137, 173, 192, 171, 222, 126,
+ 66, 58, 223, 120, 184, 151, 91, 88,
+ 155, 78, 194, 114, 102, 212, 90, 152,
+ 81, 51, 65, 42, 85, 159, 116, 226,
+ 86, 45, 164, 186, 186, 124, 173, 114,
+ 245, 85, 156, 18, 79, 15, 130, 67,
+ 114, 197, 201, 237, 191, 37, 105, 211,
+ 243, 94, 52, 42, 159, 249, 81, 56,
+ 164, 46, 220, 157, 72, 39, 165, 232,
+ 35, 3, 123, 52, 203, 38, 126, 26,
+ 104, 42, 157, 4, 217, 51, 204, 29,
+ 80, 146, 188, 17, 177, 37, 8, 95,
+ 140, 49, 235, 166, 34, 208, 67, 56,
+ 141, 42, 61, 141, 156, 31, 99, 213,
+ 155, 100, 82, 17, 55, 160, 116, 104,
+ 198, 250, 37, 197, 190, 15, 71, 236,
+ 27, 247, 149, 222, 5, 171, 147, 183,
+ 186, 54, 106, 53, 92, 219, 245, 94,
+ 137, 39, 43, 5, 56, 5, 34, 114,
+ 4, 193, 211, 133, 171, 179, 18, 158,
+ 207, 187, 97, 132, 85, 152, 209, 94,
+ 137, 199, 84, 241, 16, 115, 73, 229,
+ 74, 156, 174, 229, 134, 250, 98, 41,
+ 36, 73, 14, 205, 221, 36, 17, 44,
+ 36, 185, 151, 156, 71, 219, 146, 76,
+ 130, 236, 34, 126, 90, 79, 174, 56,
+ 96, 140, 145, 202, 207, 241, 99, 104,
+ 41, 252, 129, 44, 224, 242, 145, 97,
+ 28, 126, 3, 88, 241, 194, 33, 170,
+ 113, 198, 183, 199, 59, 132, 105, 179,
+ 80, 254, 228, 106, 101, 200, 241, 21,
+ 95, 109, 59, 24, 61, 78, 123, 159,
+ 89, 240, 140, 212, 175, 65, 142, 16,
+ 253, 31, 158, 248, 72, 247, 48, 144,
+ 28, 173, 119, 70, 55, 155, 3, 44,
+ 41, 171, 216, 184, 170, 59, 157, 185,
+ 56, 59, 148, 133, 71, 104, 19, 133,
+ 76, 3, 203, 6, 139, 245, 169, 249,
+ 248, 220, 71, 173, 117, 103, 125, 220,
+ 74, 133, 158, 219, 42, 165, 69, 158,
+ 142, 27, 239, 159, 225, 111, 128, 126,
+ 158, 61, 53, 126, 118, 166, 54, 83,
+ 0, 119, 190, 245, 144, 148, 193, 234,
+ 150, 110, 38, 209, 13, 170, 100, 156,
+ 215, 107, 241, 56, 161, 181, 59, 135,
+ 138, 86, 92, 232, 221, 134, 128, 120,
+ 85, 156, 74, 191, 39, 164, 129, 204,
+ 82, 240, 203, 246, 155, 225, 127, 13,
+ 41, 25, 184, 154, 10, 138, 9, 167,
+ 229, 27, 153, 16, 182, 237, 64, 64,
+ 184, 118, 108, 253, 145, 82, 61, 211,
+ 66, 104, 58, 71, 242, 86, 242, 202,
+ 54, 40, 97, 2, 184, 243, 123, 5,
+ 91, 184, 160, 126, 5, 133, 253, 83,
+ 240, 58, 249, 33, 198, 71, 20, 102,
+ 86, 34, 24, 180, 149, 20, 34, 76,
+ 101, 30, 184, 194, 77, 87, 255, 228,
+ 255, 152, 169, 95, 77, 141, 206, 135,
+ 253, 106, 104, 249, 76, 138, 94, 160,
+ 9, 67, 139, 125, 211, 198, 145, 199,
+ 239, 80, 83, 12, 0, 123, 128, 220,
+ 149, 54, 181, 186, 63, 61, 144, 128,
+ 187, 181, 214, 156, 228, 248, 94, 181,
+ 215, 240, 165, 58, 79, 114, 190, 36,
+ 66, 251, 190, 11, 98, 97, 69, 69,
+ 221, 134, 230, 51, 193, 143, 22, 20,
+ 127, 231, 225, 46, 184, 22, 182, 191,
+ 3, 142, 11, 223, 165, 54, 254, 238,
+ 63, 147, 159, 159, 26, 155, 120, 14,
+ 68, 249, 180, 243, 49, 194, 67, 254,
+ 179, 137, 38, 10, 2, 97, 22, 238,
+ 223, 132, 191, 14, 129, 64, 100, 167,
+ 162, 96, 108, 207, 49, 119, 188, 154,
+ 32, 7, 59, 252, 140, 163, 183, 55,
+ 30, 0, 46, 230, 253, 180, 116, 119,
+ 6, 17, 240, 150, 204, 203, 185, 249,
+ 140, 44, 204, 231, 131, 251, 10, 79,
+ 72, 252, 240, 34, 228, 39, 37, 216,
+ 97, 135, 146, 148, 246, 12, 251, 218,
+ 94, 29, 44, 174, 238, 83, 250, 157,
+ 253, 105, 57, 106, 225, 157, 55, 88,
+ 95, 155, 151, 35, 198, 126, 182, 213,
+ 213, 3, 234, 232, 156, 17, 137, 143,
+ 161, 146, 40, 245, 192, 122, 115, 0,
+ 44, 249, 224, 99, 95, 105, 184, 1,
+ 254, 238, 16, 245, 28, 65, 25, 123,
+ 3, 149, 42, 32, 44, 39, 2, 96,
+ 126, 171, 89, 72, 155, 150, 51, 49,
+ 154, 212, 62, 31, 189, 244, 77, 173,
+ 72, 223, 3, 202, 73, 255, 212, 170,
+ 173, 152, 128, 29, 46, 183, 71, 232,
+ 122, 163, 152, 88, 211, 70, 71, 116,
+ 109, 77, 177, 16, 121, 49, 50, 49,
+ 31, 48, 38, 66, 131, 157, 25, 28,
+ 177, 220, 252, 41, 81, 83, 180, 50,
+ 222, 56, 128, 28, 179, 230, 24, 179,
+ 135, 197, 228, 162, 150, 227, 145, 217,
+ 184, 188, 135, 208, 208, 165, 79, 252,
+ 148, 21, 50, 97, 24, 96, 73, 195,
+ 102, 254, 87, 42, 113, 185, 45, 155,
+ 233, 154, 170, 35, 85, 136, 185, 217,
+ 10, 48, 114, 246, 147, 172, 201, 123,
+ 87, 84, 125, 206, 34, 214, 8, 231,
+ 31, 160, 189, 112, 87, 111, 34, 169,
+ 110, 83, 245, 140, 112, 1, 218, 147,
+ 80, 215, 168, 120, 29, 109, 105, 254,
+ 20, 70, 167, 192, 33, 106, 45, 148,
+ 147, 235, 22, 135, 65, 110, 10, 243,
+ 141, 56, 92, 177, 57, 243, 204, 214,
+ 6, 121, 111, 3, 176, 121, 245, 76,
+ 160, 30, 236, 15, 229, 238, 213, 244,
+ 148, 81, 194, 25, 137, 171, 85, 195,
+ 23, 13, 154, 10, 12, 230, 122, 202,
+ 162, 74, 195, 225, 78, 183, 182, 203,
+ 17, 185, 122, 155, 5, 51, 200, 92,
+ 71, 93, 229, 38, 149, 160, 147, 33,
+ 89, 181, 103, 161, 148, 97, 55, 62,
+ 184, 39, 43, 219, 85, 74, 151, 56,
+ 86, 67, 82, 56, 38, 251, 240, 133,
+ 215, 153, 179, 60, 231, 60, 0, 24,
+ 37, 191, 202, 214, 189, 55, 2, 165,
+ 240, 179, 148, 226, 154, 81, 28, 45,
+ 231, 97, 253, 2, 54, 254, 90, 162,
+ 255, 229, 11, 161, 65, 213, 246, 80,
+ 5, 109, 14, 163, 4, 60, 123, 51,
+ 91, 134, 98, 183, 2, 154, 211, 42,
+ 109, 192, 248, 31, 26, 11, 144, 103,
+ 0, 179, 239, 215, 20, 20, 44, 82,
+ 18, 220, 179, 112, 168, 171, 80, 64,
+ 244, 136, 106, 5, 86, 114, 160, 135,
+ 233, 230, 233, 31, 30, 120, 26, 26,
+ 255, 11, 173, 238, 195, 186, 10, 16,
+ 126, 140, 47, 52, 112, 235, 30, 121,
+ 0, 98, 26, 29, 183, 138, 181, 35,
+ 227, 220, 251, 22, 33, 177, 25, 26,
+ 205, 189, 149, 169, 189, 234, 61, 79,
+ 44, 223, 79, 248, 163, 244, 53, 41,
+ 177, 28, 33, 119, 234, 138, 18, 252,
+ 227, 204, 236, 10, 130, 157, 183, 183,
+ 194, 111, 94, 34, 221, 231, 248, 118,
+ 3, 51, 103, 215, 195, 226, 92, 92,
+ 191, 217, 246, 174, 57, 238, 17, 245,
+ 209, 205, 228, 5, 183, 209, 235, 185,
+ 118, 12, 181, 115, 94, 155, 235, 23,
+ 246, 70, 62, 226, 214, 12, 53, 231,
+ 3, 37, 157, 135, 18, 36, 33, 4,
+ 208, 189, 199, 74, 231, 159, 86, 25,
+ 137, 232, 10, 231, 207, 199, 62, 65,
+ 116, 219, 179, 119, 89, 181, 18, 209,
+ 170, 161, 79, 137, 119, 136, 126, 80,
+ 29, 2, 8, 192, 145, 124, 53, 172,
+ 184, 110, 225, 63, 219, 198, 221, 212,
+ 26, 89, 59, 18, 30, 84, 59, 63,
+ 100, 1, 137, 155, 192, 225, 229, 182,
+ 115, 58, 133, 108, 12, 99, 125, 6,
+ 238, 249, 225, 176, 120, 182, 248, 108,
+ 72, 252, 115, 204, 130, 148, 102, 17,
+ 178, 2, 139, 3, 140, 10, 90, 120,
+ 122, 130, 66, 211, 80, 134, 50, 235,
+ 89, 59, 122, 86, 28, 250, 206, 233,
+ 67, 127, 145, 176, 4, 64, 127, 228,
+ 229, 111, 10, 202, 172, 146, 72, 188,
+ 247, 124, 233, 246, 89, 214, 221, 204,
+ 198, 167, 88, 208, 135, 128, 237, 53,
+ 50, 165, 114, 244, 137, 240, 1, 180,
+ 182, 66, 69, 210, 220, 55, 175, 41,
+ 172, 239, 195, 19, 153, 204, 183, 17,
+ 76, 199, 29, 58, 52, 3, 237, 48,
+ 175, 65, 242, 247, 55, 183, 155, 128,
+ 240, 250, 197, 114, 4, 77, 9, 1,
+ 126, 104, 94, 184, 142, 108, 57, 255,
+ 166, 254, 207, 87, 215, 196, 250, 44,
+ 209, 67, 56, 194, 178, 179, 104, 30,
+ 97, 167, 121, 86, 141, 60, 102, 19,
+ 2, 197, 217, 115, 63, 247, 8, 84,
+ 28, 58, 116, 169, 173, 154, 203, 122,
+ 188, 174, 166, 221, 148, 47, 176, 160,
+ 155, 97, 211, 215, 36, 46, 48, 174,
+ 22, 117, 45, 188, 40, 97, 96, 7,
+ 6, 213, 44, 3, 200, 194, 238, 191,
+ 3, 60, 254, 176, 100, 204, 235, 76,
+ 244, 110, 196, 82, 143, 245, 9, 12,
+ 210, 171, 30, 93, 84, 93, 178, 206,
+ 8, 125, 39, 212, 111, 58, 181, 114,
+ 33, 199, 165, 58, 105, 26, 187, 87,
+ 184, 139, 99, 136, 182, 230, 149, 172,
+ 33, 78, 10, 51, 149, 246, 253, 3,
+ 217, 5, 9, 210, 148, 130, 66, 70,
+ 130, 128, 49, 149, 97, 77, 153, 142,
+ 252, 193, 19, 162, 152, 161, 173, 127,
+ 43, 73, 167, 252, 89, 11, 218, 227,
+ 97, 136, 93, 205, 8, 190, 48, 82,
+ 26, 191, 249, 99, 126, 58, 145, 73,
+ 213, 56, 192, 119, 94, 244, 160, 193,
+ 15, 26, 78, 227, 217, 215, 218, 180,
+ 186, 195, 150, 42, 173, 240, 54, 185,
+ 57, 107, 0, 98, 175, 73, 216, 212,
+ 149, 168, 75, 227, 132, 50, 178, 221,
+ 39, 207, 203, 37, 49, 11, 239, 80,
+ 217, 55, 4, 13, 203, 252, 79, 105,
+ 41, 35, 134, 5, 63, 209, 26, 240,
+ 41, 234, 97, 192, 180, 84, 21, 37,
+ 64, 142, 113, 75, 34, 253, 177, 107,
+ 47, 197, 240, 157, 141, 196, 125, 183,
+ 34, 35, 133, 53, 127, 87, 44, 193,
+ 106, 181, 153, 29, 80, 2, 224, 8,
+ 216, 164, 201, 251, 6, 246, 70, 32,
+ 87, 92, 105, 53, 50, 129, 234, 20,
+ 55, 190, 195, 3, 212, 239, 223, 9,
+ 243, 84, 21, 201, 29, 51, 89, 154,
+ 40, 154, 229, 8, 5, 182, 33, 80,
+ 22, 6, 163, 49, 246, 115, 43, 78,
+ 113, 247, 45, 172, 4, 48, 242, 93,
+ 19, 172, 202, 26, 29, 254, 7, 223,
+ 131, 76, 71, 78, 69, 139, 172, 3,
+ 96, 202, 0, 50, 179, 158, 178, 234,
+ 168, 108, 111, 68, 51, 19, 28, 15,
+ 100, 121, 67, 97, 148, 238, 136, 177,
+ 76, 50, 58, 63, 245, 23, 104, 126,
+ 132, 40, 90, 80, 196, 239, 62, 175,
+ 167, 212, 129, 133, 181, 168, 5, 24,
+ 197, 143, 170, 199, 198, 205, 172, 47,
+ 124, 196, 18, 88, 228, 144, 148, 244,
+ 191, 191, 241, 165, 68, 247, 225, 138,
+ 246, 102, 170, 222, 241, 14, 30, 130,
+ 252, 64, 161, 54, 36, 173, 95, 172,
+ 222, 25, 88, 78, 102, 206, 76, 209,
+ 249, 83, 164, 104, 88, 150, 70, 238,
+ 194, 67, 201, 127, 39, 45, 70, 11,
+ 155, 69, 13, 211, 161, 77, 125, 249,
+ 189, 208, 40, 12, 156, 49, 38, 229,
+ 164, 150, 59, 127, 118, 88, 226, 216,
+ 62, 233, 199, 185, 200, 230, 105, 102,
+ 166, 71, 125, 162, 80, 176, 92, 58,
+ 83, 172, 251, 97, 47, 123, 77, 70,
+ 154, 63, 167, 0, 151, 222, 204, 142,
+ 210, 156, 27, 67, 112, 182, 194, 93,
+ 162, 176, 132, 37, 115, 240, 233, 167,
+ 119, 160, 172, 73, 122, 160, 133, 42,
+ 192, 251, 123, 241, 73, 44, 4, 67,
+ 44, 244, 174, 118, 92, 198, 44, 210,
+ 26, 152, 58, 139, 59, 151, 210, 38,
+ 210, 205, 46, 94, 218, 39, 110, 9,
+ 72, 240, 240, 136, 102, 51, 194, 148,
+ 49, 76, 143, 0, 182, 121, 214, 121,
+ 41, 174, 211, 70, 54, 32, 199, 63,
+ 223, 139, 212, 79, 239, 117, 159, 96,
+ 91, 215, 200, 18, 62, 67, 134, 179,
+ 167, 85, 203, 40, 239, 27, 238, 9,
+ 161, 220, 103, 162, 57, 11, 50, 4,
+ 210, 1, 95, 57, 96, 206, 215, 32,
+ 16, 1, 137, 240, 35, 229, 122, 171,
+ 247, 135, 135, 62, 183, 142, 7, 49,
+ 223, 179, 250, 48, 81, 24, 87, 54,
+ 194, 151, 230, 214, 76, 236, 76, 168,
+ 127, 72, 90, 153, 220, 99, 22, 190,
+ 19, 223, 8, 247, 19, 2, 11, 173,
+ 137, 240, 146, 204, 216, 10, 15, 225,
+ 227, 66, 124, 220, 171, 131, 163, 180,
+ 181, 62, 46, 81, 54, 177, 92, 83,
+ 219, 98, 161, 88, 230, 238, 32, 0,
+ 179, 173, 222, 47, 72, 160, 215, 153,
+ 49, 24, 239, 59, 39, 116, 28, 155,
+ 227, 62, 215, 180, 24, 46, 237, 0,
+ 224, 233, 224, 244, 246, 2, 175, 56,
+ 41, 188, 136, 97, 107, 123, 93, 64,
+ 130, 254, 219, 135, 11, 175, 99, 24,
+ 86, 133, 215, 14, 191, 27, 111, 74,
+ 173, 78, 166, 141, 123, 156, 156, 80,
+ 253, 220, 12, 84, 244, 204, 102, 151,
+ 176, 159, 218, 2, 118, 146, 45, 17,
+ 79, 39, 219, 244, 35, 16, 17, 241,
+ 218, 187, 175, 166, 168, 88, 145, 186,
+ 118, 255, 96, 204, 71, 164, 229, 103,
+ 102, 66, 201, 213, 132, 231, 255, 86,
+ 220, 179, 193, 128, 156, 11, 85, 2,
+ 80, 247, 133, 1, 157, 57, 137, 135,
+ 99, 111, 196, 185, 133, 235, 131, 51,
+ 210, 173, 175, 38, 184, 230, 247, 70,
+ 110, 74, 62, 97, 113, 130, 116, 78,
+ 10, 186, 96, 9, 98, 243, 174, 37,
+ 36, 133, 82, 154, 63, 36, 140, 243,
+ 53, 255, 212, 88, 64, 64, 151, 115,
+ 38, 232, 104, 4, 16, 101, 104, 185,
+ 177, 54, 55, 212, 14, 152, 31, 131,
+ 242, 183, 112, 245, 225, 100, 151, 106,
+ 23, 199, 237, 165, 140, 131, 202, 56,
+ 130, 192, 34, 147, 22, 138, 217, 227,
+ 158, 255, 8, 107, 94, 12, 50, 86,
+ 220, 47, 201, 9, 45, 186, 173, 226,
+ 226, 182, 15, 80, 144, 39, 155, 193,
+ 169, 18, 23, 40, 141, 246, 176, 97,
+ 151, 207, 163, 177, 73, 105, 236, 223,
+ 150, 6, 252, 221, 65, 217, 67, 91,
+ 34, 15, 181, 65, 196, 143, 199, 74,
+ 11, 45, 192, 214, 96, 58, 29, 188,
+ 187, 195, 47, 141, 154, 204, 35, 0,
+ 47, 249, 3, 48, 234, 152, 122, 92,
+ 19, 35, 115, 4, 44, 199, 136, 50,
+ 69, 93, 133, 19, 10, 186, 27, 179,
+ 130, 38, 216, 34, 139, 120, 87, 238,
+ 245, 241, 207, 17, 234, 46, 138, 172,
+ 188, 113, 178, 118, 6, 205, 24, 35,
+ 80, 17, 231, 72, 130, 160, 93, 24,
+ 220, 11, 152, 51, 255, 35, 35, 83,
+ 76, 79, 128, 107, 3, 126, 219, 238,
+ 18, 134, 138, 183, 126, 7, 58, 127,
+ 221, 99, 119, 129, 60, 88, 11, 142,
+ 180, 140, 174, 58, 178, 10, 248, 238,
+ 223, 174, 192, 170, 217, 99, 16, 204,
+ 61, 239, 102, 108, 58, 82, 118, 198,
+ 215, 191, 8, 139, 44, 137, 161, 125,
+ 136, 33, 84, 84, 119, 154, 237, 58,
+ 138, 11, 118, 122, 248, 211, 194, 213,
+ 91, 230, 157, 27, 34, 92, 220, 186,
+ 30, 149, 23, 83, 172, 184, 70, 251,
+ 135, 54, 113, 36, 46, 39, 21, 245,
+ 164, 100, 14, 232, 76, 92, 41, 102,
+ 86, 188, 41, 100, 183, 45, 243, 203,
+ 138, 146, 29, 74, 211, 116, 242, 122,
+ 156, 240, 69, 188, 87, 68, 127, 10,
+ 21, 140, 6, 255, 210, 149, 107, 198,
+ 173, 75, 102, 137, 230, 195, 126, 156,
+ 49, 73, 157, 73, 1, 72, 67, 203,
+ 2, 115, 152, 198, 238, 4, 249, 157,
+ 1, 16, 249, 69, 162, 203, 49, 135,
+ 68, 110, 210, 137, 182, 170, 117, 255,
+ 146, 176, 250, 206, 66, 52, 175, 76,
+ 61, 130, 62, 150, 218, 90, 100, 121,
+ 5, 12, 11, 222, 115, 222, 165, 82,
+ 157, 4, 142, 117, 57, 183, 83, 133,
+ 207, 108, 182, 183, 255, 67, 14, 16,
+ 132, 28, 227, 209, 213, 207, 108, 110,
+ 126, 119, 189, 95, 42, 91, 227, 40,
+ 150, 104, 241, 168, 82, 199, 199, 90,
+ 10, 5, 211, 22, 75, 251, 71, 132,
+ 7, 70, 220, 183, 17, 118, 239, 245,
+ 1, 13, 235, 94, 61, 227, 54, 211,
+ 216, 103, 221, 22, 205, 33, 167, 118,
+ 226, 152, 80, 80, 147, 162, 178, 55,
+ 83, 55, 8, 222, 174, 26, 136, 7,
+ 127, 60, 155, 197, 33, 5, 45, 195,
+ 44, 29, 198, 24, 224, 167, 1, 12,
+ 18, 230, 253, 72, 68, 139, 16, 24,
+ 94, 58, 242, 4, 122, 106, 96, 97,
+ 111, 90, 185, 246, 217, 15, 227, 188,
+ 36, 1, 23, 229, 6, 173, 36, 6,
+ 159, 240, 64, 212, 118, 41, 96, 180,
+ 235, 244, 211, 129, 156, 37, 45, 172,
+ 232, 132, 74, 107, 113, 158, 97, 142,
+ 171, 113, 138, 106, 18, 20, 33, 51,
+ 26, 23, 95, 163, 47, 64, 88, 183,
+ 241, 228, 232, 98, 204, 44, 142, 253,
+ 88, 17, 8, 226, 242, 214, 146, 183,
+ 184, 208, 181, 188, 106, 142, 149, 53,
+ 37, 101, 58, 176, 218, 59, 240, 220,
+ 208, 164, 38, 195, 232, 22, 194, 171,
+ 48, 122, 230, 87, 245, 87, 229, 145,
+ 3, 142, 248, 10, 30, 64, 115, 142,
+ 165, 5, 169, 217, 25, 113, 41, 27,
+ 255, 231, 74, 22, 67, 210, 208, 40,
+ 57, 65, 35, 21, 235, 126, 53, 238,
+ 190, 115, 47, 153, 40, 189, 242, 23,
+ 125, 184, 104, 67, 126, 110, 74, 27,
+ 192, 231, 170, 147, 169, 108, 23, 71,
+ 194, 168, 255, 245, 77, 50, 196, 200,
+ 86, 78, 89, 120, 184, 44, 186, 96,
+ 101, 14, 231, 1, 115, 156, 183, 182,
+ 158, 232, 255, 66, 20, 229, 13, 70,
+ 136, 171, 193, 173, 43, 97, 79, 14,
+ 129, 177, 75, 115, 48, 34, 58, 184,
+ 112, 217, 28, 155, 10, 85, 113, 50,
+ 25, 195, 86, 0, 108, 131, 203, 141,
+ 54, 53, 43, 120, 171, 112, 56, 142,
+ 221, 55, 175, 104, 149, 80, 176, 21,
+ 36, 12, 13, 128, 29, 212, 139, 41,
+ 17, 17, 83, 104, 77, 91, 161, 41,
+ 213, 151, 68, 111, 209, 33, 47, 176,
+ 98, 173, 32, 81, 116, 175, 103, 215,
+ 177, 205, 105, 116, 201, 59, 109, 134,
+ 74, 161, 161, 13, 145, 93, 235, 33,
+ 86, 130, 250, 166, 22, 78, 220, 186,
+ 241, 161, 10, 159, 239, 159, 181, 217,
+ 229, 243, 116, 145, 101, 240, 26, 44,
+ 61, 145, 249, 71, 162, 68, 110, 67,
+ 219, 31, 143, 96, 129, 177, 97, 196,
+ 113, 146, 227, 88, 7, 110, 70, 247,
+ 197, 46, 162, 108, 168, 21, 156, 230,
+ 135, 40, 54, 199, 36, 15, 49, 135,
+ 10, 4, 171, 193, 15, 236, 166, 152,
+ 57, 68, 227, 211, 114, 40, 1, 231,
+ 219, 79, 224, 69, 54, 80, 125, 186,
+ 75, 69, 141, 48, 116, 227, 39, 2,
+ 33, 176, 17, 147, 68, 166, 106, 219,
+ 110, 82, 170, 177, 31, 101, 93, 34,
+ 81, 243, 96, 8, 30, 186, 160, 40,
+ 81, 135, 78, 115, 131, 180, 60, 70,
+ 75, 246, 184, 199, 180, 91, 243, 45,
+ 113, 85, 40, 155, 195, 197, 173, 136,
+ 215, 183, 253, 52, 133, 2, 188, 8,
+ 78, 219, 11, 128, 99, 138, 140, 173,
+ 94, 112, 3, 71, 237, 88, 52, 162,
+ 244, 158, 80, 111, 213, 51, 85, 166,
+ 154, 250, 3, 33, 220, 125, 165, 246,
+ 126, 205, 64, 196, 120, 181, 251, 71,
+ 62, 246, 190, 114, 205, 193, 238, 96,
+ 181, 221, 121, 60, 2, 175, 56, 15,
+ 199, 197, 249, 127, 129, 62, 70, 148,
+ 112, 123, 252, 95, 233, 118, 36, 131,
+ 243, 246, 61, 43, 131, 183, 90, 78,
+ 237, 61, 173, 131, 182, 11, 178, 76,
+ 71, 75, 109, 73, 198, 108, 99, 225,
+ 174, 239, 179, 44, 225, 221, 37, 99,
+ 90, 24, 138, 88, 25, 8, 104, 30,
+ 251, 116, 177, 180, 100, 156, 172, 115,
+ 57, 51, 178, 51, 113, 184, 77, 189,
+ 57, 53, 149, 126, 245, 25, 156, 144,
+ 134, 196, 239, 115, 43, 133, 212, 194,
+ 255, 173, 48, 230, 242, 164, 241, 56,
+ 131, 241, 58, 1, 110, 209, 179, 98,
+ 81, 5, 50, 19, 241, 22, 122, 212,
+ 236, 119, 207, 233, 241, 90, 120, 116,
+ 233, 155, 79, 179, 79, 252, 111, 169,
+ 220, 142, 193, 51, 236, 58, 248, 49,
+ 103, 252, 123, 113, 139, 39, 184, 62,
+ 2, 242, 102, 145, 23, 236, 174, 173,
+ 90, 139, 113, 100, 8, 249, 50, 182,
+ 167, 225, 227, 81, 34, 214, 56, 138,
+ 143, 194, 214, 199, 222, 88, 45, 26,
+ 145, 97, 74, 60, 151, 16, 132, 110,
+ 9, 89, 12, 92, 88, 200, 113, 78,
+ 220, 158, 210, 190, 249, 241, 35, 138,
+ 135, 3, 116, 255, 39, 223, 29, 32,
+ 19, 121, 11, 35, 15, 189, 107, 198,
+ 81, 195, 39, 47, 41, 91, 18, 185,
+ 155, 126, 207, 242, 200, 1, 139, 27,
+ 221, 179, 123, 90, 178, 224, 250, 139,
+ 236, 55, 116, 11, 27, 160, 14, 24,
+ 113, 126, 218, 51, 252, 110, 188, 153,
+ 55, 9, 200, 193, 178, 214, 96, 232,
+ 235, 96, 95, 135, 102, 132, 165, 184,
+ 50, 62, 97, 113, 47, 154, 96, 178,
+ 117, 156, 204, 245, 81, 99, 28, 183,
+ 54, 5, 247, 192, 193, 77, 104, 69,
+ 249, 116, 207, 129, 98, 92, 232, 213,
+ 12, 128, 140, 167, 72, 86, 111, 224,
+ 94, 57, 109, 105, 215, 147, 45, 100,
+ 110, 55, 248, 171, 129, 226, 202, 182,
+ 22, 118, 253, 99, 232, 141, 70, 120,
+ 182, 24, 138, 185, 84, 180, 103, 220,
+ 121, 69, 58, 140, 239, 12, 195, 249,
+ 255, 247, 184, 121, 198, 47, 116, 110,
+ 227, 178, 52, 150, 243, 219, 176, 189,
+ 62, 202, 114, 187, 17, 129, 97, 192,
+ 249, 102, 207, 167, 59, 104, 204, 59,
+ 114, 107, 23, 152, 123, 70, 253, 19,
+ 137, 134, 234, 210, 96, 166, 30, 213,
+ 238, 120, 50, 134, 59, 162, 126, 247,
+ 61, 119, 3, 243, 255, 195, 189, 188,
+ 180, 108, 230, 172, 219, 80, 191, 162,
+ 85, 137, 32, 19, 239, 160, 93, 156,
+ 103, 218, 149, 167, 40, 137, 73, 67,
+ 170, 122, 33, 92, 196, 145, 205, 64,
+ 171, 194, 91, 215, 29, 26, 46, 184,
+ 63, 41, 252, 92, 3, 33, 247, 230,
+ 94, 144, 23, 82, 244, 115, 107, 168,
+ 32, 35, 23, 22, 218, 151, 83, 8,
+ 116, 90, 7, 227, 52, 243, 150, 235,
+ 117, 149, 169, 152, 57, 150, 51, 154,
+ 116, 9, 176, 216, 98, 172, 239, 154,
+ 20, 53, 146, 87, 233, 182, 246, 162,
+ 101, 192, 152, 182, 208, 255, 183, 246,
+ 32, 29, 122, 125, 159, 150, 124, 219,
+ 108, 131, 213, 202, 61, 168, 81, 113,
+ 149, 172, 195, 157, 52, 136, 144, 5,
+ 95, 103, 74, 126, 113, 8, 243, 104,
+ 254, 167, 64, 121, 16, 67, 221, 82,
+ 91, 12, 229, 71, 244, 227, 125, 146,
+ 199, 89, 177, 154, 80, 71, 233, 78,
+ 15, 168, 94, 47, 46, 230, 221, 254,
+ 27, 149, 18, 178, 72, 197, 161, 13,
+ 145, 103, 49, 111, 24, 105, 218, 111,
+ 28, 223, 124, 177, 57, 202, 207, 47,
+ 150, 224, 95, 208, 216, 204, 53, 51,
+ 218, 27, 148, 164, 232, 197, 23, 115,
+ 127, 100, 172, 160, 132, 2, 148, 92,
+ 182, 103, 1, 82, 153, 131, 210, 226,
+ 138, 232, 23, 70, 44, 10, 8, 35,
+ 185, 204, 126, 199, 140, 45, 59, 205,
+ 52, 102, 214, 238, 87, 50, 162, 190,
+ 158, 27, 204, 6, 209, 161, 208, 103,
+ 71, 166, 119, 80, 29, 82, 133, 96,
+ 123, 16, 181, 157, 99, 122, 238, 109,
+ 210, 127, 32, 164, 167, 60, 152, 79,
+ 182, 184, 10, 164, 39, 250, 220, 102,
+ 79, 103, 173, 218, 228, 237, 16, 202,
+ 150, 21, 220, 105, 151, 211, 160, 213,
+ 59, 17, 0, 88, 138, 45, 236, 138,
+ 166, 115, 122, 75, 236, 189, 36, 108,
+ 19, 138, 219, 249, 75, 209, 50, 174,
+ 190, 116, 17, 116, 239, 221, 75, 30,
+ 157, 189, 98, 9, 70, 223, 46, 228,
+ 156, 167, 75, 115, 109, 74, 177, 0,
+ 104, 22, 240, 213, 194, 211, 157, 52,
+ 73, 38, 143, 39, 250, 154, 111, 171,
+ 189, 189, 22, 161, 206, 186, 69, 235,
+ 95, 217, 36, 17, 206, 243, 95, 114,
+ 253, 217, 210, 30, 239, 33, 208, 142,
+ 3, 20, 137, 120, 86, 161, 191, 93,
+ 26, 125, 135, 205, 172, 218, 191, 92,
+ 3, 79, 194, 48, 122, 43, 44, 148,
+ 170, 155, 113, 51, 7, 164, 217, 35,
+ 73, 217, 0, 250, 148, 4, 175, 109,
+ 43, 65, 226, 177, 107, 177, 157, 252,
+ 213, 250, 11, 218, 205, 44, 159, 156,
+ 117, 71, 101, 85, 119, 71, 214, 217,
+ 238, 119, 240, 71, 232, 168, 6, 33,
+ 158, 37, 243, 160, 123, 58, 150, 154,
+ 233, 171, 219, 86, 130, 174, 67, 238,
+ 137, 250, 46, 53, 218, 179, 214, 32,
+ 249, 249, 244, 136, 141, 61, 170, 213,
+ 23, 249, 170, 22, 200, 101, 97, 55,
+ 50, 61, 24, 230, 19, 178, 78, 196,
+ 12, 113, 199, 62, 134, 92, 54, 36,
+ 156, 140, 211, 188, 101, 108, 141, 43,
+ 81, 69, 229, 96, 155, 50, 204, 182,
+ 98, 61, 148, 22, 197, 8, 247, 128,
+ 123, 170, 223, 186, 109, 68, 100, 93,
+ 87, 75, 212, 97, 158, 73, 31, 54,
+ 48, 219, 242, 186, 32, 130, 185, 236,
+ 41, 66, 40, 59, 238, 60, 1, 13,
+ 127, 70, 133, 11, 103, 157, 193, 94,
+ 234, 190, 123, 225, 77, 218, 6, 88,
+ 157, 131, 228, 127, 177, 126, 52, 150,
+ 212, 104, 126, 68, 76, 67, 196, 64,
+ 234, 202, 132, 242, 54, 154, 248, 79,
+ 154, 110, 208, 111, 184, 216, 14, 63,
+ 27, 14, 200, 233, 107, 37, 17, 59,
+ 125, 166, 226, 208, 13, 15, 28, 155,
+ 225, 102, 113, 217, 118, 56, 150, 129,
+ 64, 188, 157, 235, 197, 204, 37, 195,
+ 70, 42, 170, 91, 217, 13, 163, 119,
+ 224, 95, 163, 240, 51, 248, 56, 35,
+ 237, 114, 100, 154, 53, 45, 124, 23,
+ 133, 86, 197, 125, 85, 100, 164, 191,
+ 206, 150, 127, 235, 16, 33, 93, 219,
+ 129, 100, 53, 67, 82, 110, 10, 235,
+ 82, 196, 157, 20, 77, 228, 101, 166,
+ 98, 0, 235, 177, 126, 163, 102, 173,
+ 216, 130, 221, 183, 196, 104, 224, 192,
+ 32, 195, 179, 231, 223, 24, 59, 41,
+ 155, 255, 154, 207, 252, 120, 143, 21,
+ 107, 49, 175, 4, 105, 14, 206, 156,
+ 51, 178, 158, 174, 208, 46, 9, 139,
+ 239, 37, 104, 186, 41, 51, 31, 113,
+ 54, 211, 231, 53, 25, 127, 37, 136,
+ 136, 116, 37, 163, 71, 173, 91, 51,
+ 181, 147, 74, 15, 119, 88, 25, 57,
+ 253, 176, 152, 119, 143, 203, 244, 144,
+ 144, 42, 249, 246, 111, 255, 20, 128,
+ 178, 97, 102, 207, 221, 172, 72, 123,
+ 46, 204, 123, 76, 122, 131, 14, 254,
+ 35, 140, 71, 112, 164, 195, 53, 107,
+ 63, 39, 92, 118, 245, 27, 164, 45,
+ 161, 199, 106, 177, 95, 186, 238, 163,
+ 55, 129, 144, 8, 96, 122, 179, 177,
+ 97, 249, 113, 1, 205, 193, 82, 226,
+ 12, 6, 253, 108, 107, 128, 1, 179,
+ 20, 122, 74, 40, 212, 29, 152, 198,
+ 147, 14, 90, 213, 88, 103, 101, 137,
+ 21, 93, 206, 114, 54, 108, 216, 23,
+ 63, 155, 18, 7, 35, 199, 244, 150,
+ 93, 200, 121, 217, 147, 129, 37, 92,
+ 222, 110, 119, 216, 82, 6, 183, 25,
+ 19, 132, 134, 83, 21, 103, 73, 86,
+ 93, 90, 199, 51, 179, 181, 105, 126,
+ 248, 67, 108, 64, 93, 246, 188, 80,
+ 94, 185, 142, 231, 78, 180, 62, 84,
+ 177, 127, 242, 41, 149, 110, 134, 197,
+ 97, 115, 123, 158, 102, 91, 241, 78,
+ 22, 144, 105, 253, 127, 164, 1, 223,
+ 77, 197, 157, 240, 247, 174, 200, 219,
+ 96, 231, 58, 79, 183, 1, 87, 180,
+ 15, 214, 9, 189, 115, 220, 91, 83,
+ 151, 3, 68, 162, 152, 85, 165, 4,
+ 189, 76, 51, 130, 55, 117, 202, 123,
+ 251, 238, 23, 173, 27, 161, 102, 200,
+ 59, 182, 85, 187, 22, 8, 86, 109,
+ 253, 103, 100, 227, 136, 137, 104, 182,
+ 123, 25, 9, 0, 175, 119, 83, 179,
+ 155, 213, 37, 221, 222, 53, 234, 250,
+ 208, 218, 152, 12, 233, 68, 152, 47,
+ 51, 119, 25, 177, 6, 172, 176, 110,
+ 186, 238, 113, 168, 30, 232, 100, 95,
+ 77, 101, 18, 45, 207, 54, 254, 58,
+ 241, 70, 2, 25, 33, 120, 229, 227,
+ 74, 175, 146, 27, 164, 12, 194, 62,
+ 87, 96, 97, 16, 136, 219, 143, 42,
+ 255, 37, 2, 224, 22, 1, 251, 204,
+ 167, 63, 76, 53, 122, 18, 66, 117,
+ 236, 6, 183, 190, 106, 27, 137, 68,
+ 51, 164, 77, 107, 84, 184, 24, 101,
+ 202, 221, 11, 218, 16, 15, 73, 59,
+ 130, 132, 158, 191, 55, 29, 0, 75,
+ 250, 141, 168, 76, 89, 28, 90, 177,
+ 18, 115, 131, 11, 231, 118, 160, 160,
+ 198, 200, 169, 192, 193, 188, 136, 48,
+ 112, 188, 242, 108, 126, 192, 54, 35,
+ 41, 225, 160, 11, 38, 176, 244, 39,
+ 204, 25, 132, 216, 145, 169, 15, 218,
+ 183, 194, 157, 174, 189, 7, 67, 197,
+ 73, 231, 167, 223, 252, 253, 72, 66,
+ 208, 120, 197, 30, 59, 149, 71, 89,
+ 204, 80, 92, 67, 185, 90, 251, 193,
+ 138, 51, 244, 181, 114, 251, 43, 155,
+ 87, 73, 181, 52, 245, 43, 79, 120,
+ 90, 250, 5, 43, 220, 208, 248, 196,
+ 221, 98, 59, 204, 118, 133, 95, 22,
+ 217, 118, 36, 226, 233, 44, 242, 59,
+ 35, 203, 170, 166, 163, 236, 46, 254,
+ 119, 60, 91, 150, 44, 115, 204, 153,
+ 233, 69, 137, 67, 157, 153, 90, 228,
+ 24, 12, 194, 52, 47, 90, 245, 77,
+ 150, 76, 128, 118, 162, 241, 105, 196,
+ 190, 195, 239, 203, 156, 149, 89, 55,
+ 154, 214, 163, 25, 158, 253, 20, 237,
+ 99, 136, 106, 84, 129, 115, 175, 210,
+ 158, 72, 239, 147, 127, 174, 172, 36,
+ 96, 188, 83, 127, 242, 191, 88, 66,
+ 135, 17, 84, 242, 139, 230, 202, 227,
+ 240, 178, 230, 21, 111, 101, 178, 73,
+ 149, 22, 140, 46, 31, 137, 77, 12,
+ 207, 191, 139, 39, 189, 22, 78, 233,
+ 191, 98, 123, 25, 23, 43, 24, 124,
+ 4, 110, 194, 67, 182, 101, 56, 215,
+ 31, 15, 162, 34, 208, 125, 161, 2,
+ 191, 18, 145, 132, 68, 156, 222, 102,
+ 120, 204, 191, 75, 49, 252, 223, 207,
+ 129, 104, 125, 237, 82, 5, 78, 227,
+ 249, 134, 181, 212, 94, 172, 184, 136,
+ 71, 211, 251, 184, 206, 29, 6, 198,
+ 40, 164, 190, 213, 1, 26, 150, 154,
+ 9, 203, 15, 198, 44, 101, 60, 92,
+ 107, 14, 48, 0, 126, 32, 34, 225,
+ 244, 134, 10, 79, 235, 202, 49, 169,
+ 118, 53, 128, 178, 174, 142, 94, 224,
+ 72, 197, 179, 5, 10, 88, 60, 54,
+ 188, 113, 70, 165, 81, 10, 146, 218,
+ 173, 168, 96, 47, 76, 83, 25, 66,
+ 231, 165, 123, 125, 151, 45, 200, 209,
+ 157, 173, 115, 159, 4, 65, 157, 8,
+ 22, 71, 72, 198, 230, 9, 235, 223,
+ 101, 112, 191, 171, 118, 167, 81, 199,
+ 253, 126, 48, 223, 109, 204, 172, 244,
+ 186, 109, 115, 126, 215, 19, 73, 6,
+ 120, 190, 99, 181, 191, 81, 44, 217,
+ 129, 226, 17, 94, 178, 204, 15, 246,
+ 155, 23, 148, 44, 89, 34, 243, 145,
+ 62, 177, 81, 86, 151, 52, 60, 83,
+ 154, 226, 169, 144, 153, 133, 100, 202,
+ 58, 250, 165, 27, 194, 20, 219, 216,
+ 87, 135, 103, 213, 161, 78, 66, 253,
+ 107, 222, 93, 52, 72, 146, 152, 17,
+ 207, 51, 233, 168, 250, 38, 0, 129,
+ 100, 117, 212, 134, 82, 98, 88, 244,
+ 11, 160, 204, 38, 72, 60, 206, 12,
+ 190, 15, 102, 253, 49, 110, 194, 93,
+ 64, 233, 122, 19, 153, 253, 200, 2,
+ 252, 162, 189, 128, 148, 112, 73, 160,
+ 40, 143, 100, 6, 84, 151, 149, 0,
+ 223, 60, 113, 185, 75, 228, 245, 197,
+ 248, 226, 138, 133, 172, 172, 46, 146,
+ 7, 220, 98, 181, 23, 112, 100, 112,
+ 16, 221, 3, 76, 137, 87, 100, 34,
+ 50, 152, 149, 199, 54, 248, 86, 150,
+ 128, 250, 14, 167, 164, 109, 111, 108,
+ 14, 204, 76, 224, 80, 154, 58, 98,
+ 242, 87, 93, 178, 73, 222, 223, 190,
+ 251, 108, 37, 113, 85, 74, 16, 9,
+ 235, 118, 251, 167, 84, 130, 20, 28,
+ 248, 91, 17, 41, 153, 253, 109, 126,
+ 91, 95, 172, 53, 140, 241, 19, 69,
+ 222, 116, 60, 114, 107, 193, 87, 215,
+ 210, 224, 135, 44, 153, 9, 117, 132,
+ 80, 156, 125, 206, 104, 162, 5, 247,
+ 79, 172, 95, 169, 136, 103, 38, 33,
+ 141, 178, 36, 121, 196, 212, 221, 200,
+ 62, 58, 226, 54, 185, 205, 233, 226,
+ 61, 78, 119, 17, 14, 124, 250, 85,
+ 181, 97, 150, 35, 20, 40, 110, 76,
+ 193, 253, 111, 219, 156, 244, 204, 158,
+ 127, 6, 51, 204, 213, 75, 207, 31,
+ 188, 57, 8, 112, 19, 24, 16, 95,
+ 12, 107, 21, 157, 4, 42, 75, 217,
+ 140, 176, 41, 238, 194, 159, 104, 167,
+ 226, 197, 252, 181, 130, 108, 79, 141,
+ 219, 83, 101, 115, 239, 234, 63, 245,
+ 86, 237, 17, 38, 78, 188, 9, 202,
+ 200, 56, 19, 176, 165, 114, 17, 144,
+ 150, 201, 150, 108, 183, 134, 166, 98,
+ 156, 164, 20, 39, 64, 80, 176, 189,
+ 40, 62, 219, 223, 10, 86, 47, 188,
+ 108, 150, 132, 70, 230, 79, 247, 218,
+ 159, 155, 80, 211, 64, 143, 28, 248,
+ 76, 177, 37, 20, 254, 62, 52, 138,
+ 120, 137, 176, 254, 187, 197, 144, 88,
+ 144, 164, 84, 250, 108, 125, 13, 164,
+ 110, 5, 113, 40, 175, 85, 183, 84,
+ 248, 12, 52, 116, 197, 118, 51, 92,
+ 154, 117, 85, 95, 181, 229, 161, 14,
+ 164, 41, 112, 87, 167, 158, 120, 23,
+ 179, 3, 214, 22, 166, 194, 187, 7,
+ 184, 221, 242, 241, 48, 100, 239, 103,
+ 241, 161, 160, 91, 33, 177, 10, 154,
+ 63, 148, 142, 250, 120, 133, 42, 153,
+ 158, 15, 56, 231, 60, 244, 72, 64,
+ 77, 129, 246, 188, 51, 102, 195, 93,
+ 211, 40, 136, 62, 35, 197, 212, 120,
+ 162, 18, 105, 17, 175, 40, 64, 243,
+ 246, 205, 228, 138, 77, 8, 16, 200,
+ 166, 153, 138, 187, 31, 14, 117, 103,
+ 8, 168, 4, 37, 215, 225, 124, 187,
+ 79, 222, 216, 80, 214, 1, 154, 57,
+ 72, 128, 103, 164, 152, 224, 32, 110,
+ 239, 230, 163, 214, 60, 255, 93, 48,
+ 89, 225, 31, 67, 9, 221, 86, 248,
+ 10, 116, 133, 53, 93, 158, 145, 136,
+ 86, 58, 197, 19, 28, 44, 245, 156,
+ 53, 192, 123, 154, 168, 30, 133, 142,
+ 54, 59, 97, 56, 26, 151, 83, 162,
+ 128, 89, 170, 128, 130, 28, 86, 158,
+ 31, 135, 43, 195, 164, 197, 51, 35,
+ 9, 173, 131, 192, 192, 29, 78, 167,
+ 137, 169, 236, 246, 211, 41, 33, 44,
+ 161, 39, 93, 187, 89, 234, 115, 201,
+ 3, 201, 221, 249, 37, 26, 182, 236,
+ 172, 39, 194, 107, 137, 15, 157, 211,
+ 15, 112, 169, 196, 91, 174, 81, 210,
+ 44, 214, 87, 217, 246, 76, 235, 11,
+ 146, 190, 130, 38, 235, 31, 66, 76,
+ 249, 125, 61, 254, 27, 106, 18, 155,
+ 68, 49, 39, 251, 36, 70, 115, 20,
+ 60, 153, 85, 174, 153, 12, 213, 217,
+ 162, 127, 121, 158, 185, 112, 92, 9,
+ 49, 243, 94, 232, 247, 148, 104, 120,
+ 233, 146, 87, 178, 97, 179, 134, 178,
+ 136, 224, 185, 176, 253, 232, 243, 134,
+ 68, 198, 237, 217, 248, 59, 135, 129,
+ 255, 61, 59, 87, 193, 211, 111, 180,
+ 230, 14, 9, 45, 116, 231, 252, 56,
+ 210, 39, 214, 111, 123, 80, 41, 204,
+ 76, 197, 100, 30, 142, 235, 244, 37,
+ 25, 120, 96, 88, 237, 85, 206, 183,
+ 74, 161, 84, 182, 105, 239, 161, 42,
+ 10, 196, 117, 114, 91, 79, 214, 26,
+ 225, 206, 167, 160, 219, 99, 228, 227,
+ 32, 92, 179, 116, 72, 184, 109, 83,
+ 97, 106, 152, 12, 243, 240, 41, 251,
+ 35, 249, 105, 228, 53, 94, 43, 119,
+ 61, 162, 192, 78, 58, 46, 84, 110,
+#endif
+};
+
+int
+main()
+{
+ long size = sizeof (random_data) / sizeof (random_data[0]);
+ printf ("%d\n", random_data [size - 1]);
+}
diff --git a/gdb/testsuite/gdb.base/remote.exp b/gdb/testsuite/gdb.base/remote.exp
new file mode 100644
index 00000000000..e2967c60b58
--- /dev/null
+++ b/gdb/testsuite/gdb.base/remote.exp
@@ -0,0 +1,195 @@
+# Copyright 1999, 2001 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+
+# test only on a remote target board
+if {! [is_remote target]} {
+ return
+}
+
+set testfile "remote"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+gdb_start
+
+set result [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}]
+if {$result != "" } then {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+#
+# Part ONE: Check the down load commands
+#
+
+gdb_test "show download-write-size" \
+ "The write size used when downloading a program is 512." \
+ "download limit default"
+
+gdb_test "set download-write-size" "Argument required.*"
+
+gdb_test "set download-write-size 0" ""
+gdb_test "show download-write-size" \
+ "The write size used when downloading a program is unlimited." \
+ "set download limit - unlimited"
+
+gdb_test "show remote memory-write-packet-size" \
+ "The memory-write-packet-size is 0. Packets are limited to \[0-9\]+ bytes." \
+ "write-packet default"
+
+gdb_test "set remote memory-write-packet-size" \
+ "Argument required .integer, `fixed' or `limited'.\." \
+ "set write-packet - NULL"
+
+gdb_test "set remote memory-write-packet-size 16" ""
+gdb_test "show remote memory-write-packet-size" \
+ "The memory-write-packet-size is 16. Packets are limited to 16 bytes." \
+ "set write-packet - small"
+
+gdb_test "set remote memory-write-packet-size 1" ""
+gdb_test "show remote memory-write-packet-size" \
+ "The memory-write-packet-size is 1. Packets are limited to 16 bytes." \
+ "set write-packet - very-small"
+
+#
+# Part TWO: Check the download behavour
+#
+
+proc gdb_load_timed {executable downloadsize class writesize} {
+ global test gdb_prompt
+ set test "timed download `[file tail $executable]' - $downloadsize, $class, $writesize"
+
+ if {$writesize != ""} then {
+ gdb_test "set remote memory-write-packet-size $writesize" \
+ "" "$test - set packet size"
+ }
+
+ if {$downloadsize != ""} then {
+ gdb_test "set download-write-size $downloadsize" \
+ "" "$test - set download size"
+ }
+
+ if {$downloadsize != ""} then {
+ send_gdb "set remote memory-write-packet-size $class\n"
+ gdb_expect 5 {
+ -re ".*Change the packet size.*$" {
+ send_gdb "y\n"
+ gdb_expect 5 {
+ -re ".*$gdb_prompt $" {
+ pass "$test - set write size class"
+ }
+ timeout {
+ fail "$test - set write size class"
+ return
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" { }
+ timeout {
+ fail "$test - set write size class"
+ return
+ }
+ }
+ }
+
+ set load_begin_time [clock clicks]
+ set result [gdb_load $executable]
+ set load_end_time [clock clicks]
+ if {$result < 0} then { fail "$test - loading executable"; return }
+ verbose "$test - time [expr ($load_end_time - $load_begin_time) / 1000] ms"
+ pass $test
+}
+
+gdb_load_timed $binfile {} "" {}
+
+# Typically about 400-1 bytes can be downloaded
+gdb_load_timed $binfile 0 "limit" 398
+gdb_load_timed $binfile 0 "limit" 400
+
+# Absolute max is 16384
+gdb_load_timed $binfile 0 "fixed" 0
+gdb_load_timed $binfile 0 "fixed" 16385
+
+# fall back to the default
+gdb_load_timed $binfile 0 "limit" 0
+
+# Get size of data uploaded
+
+#
+# Query GDB for the size of various types
+#
+
+proc get_sizeof { type default } {
+ global gdb_prompt
+ send_gdb "print/d sizeof (${type})\n"
+ gdb_expect {
+ -re "\\$\[0-9\]* = (\[0-9\]*).*$gdb_prompt $" {
+ set size $expect_out(1,string)
+ pass "get sizeof ${type} ($size)"
+ }
+ timeout {
+ set size ${default}
+ fail "get sizeof ${type} (timeout)"
+ }
+ }
+ return ${size}
+}
+
+# Get the size of random_data table (defaults to 48K).
+set sizeof_random_data [get_sizeof "random_data" 48*1024]
+
+#
+# Part THREE: Check the upload behavour
+#
+if ![runto_main] then {
+ fail "Cannot run to main"
+}
+
+# Carefully check memory around each of the most common packet edge
+# conditions
+
+gdb_test "x/8ub random_data" \
+ "<random_data>:\[ \t\]+60\[ \t\]+74\[ \t\]+216\[ \t\]+38\[ \t\]+149\[ \t\]+49\[ \t\]+207\[ \t\]+44"
+
+gdb_test "x/8ub random_data + 400 - 4" \
+ "<random_data\\+396>:\[ \t\]+185\[ \t\]+255\[ \t\]+50\[ \t\]+140\[ \t\]+237\[ \t\]+172\[ \t\]+143\[ \t\]+93"
+
+if {$sizeof_random_data > 16380 } then {
+ gdb_test "x/8ub random_data + 16384 - 4" \
+ "<random_data\\+16380>:\[ \t\]+178\[ \t\]+180\[ \t\]+135\[ \t\]+93\[ \t\]+70\[ \t\]+62\[ \t\]+205\[ \t\]+76"
+}
+
+# Read a chunk just larger than the packet size (reduce the packet
+# size to make life easier)
+gdb_test "set remote memory-read-packet-size 16" \
+ ""
+gdb_test "show remote memory-read-packet-size" \
+ "The memory-read-packet-size is 16. Packets are limited to 16 bytes."
+gdb_test "x/17ub random_data" \
+ "<random_data>:\[ \t\]+60\[ \t\]+74\[ \t\]+216\[ \t\]+38\[ \t\]+149\[ \t\]+49\[ \t\]+207\[ \t\]+44.*<random_data\\+8>:\[ \t\]+124\[ \t\]+38\[ \t\]+93\[ \t\]+125\[ \t\]+232\[ \t\]+67\[ \t\]+228\[ \t\]+56.*<random_data\\+16>:\[ \t\]+161"
+
+gdb_exit
diff --git a/gdb/testsuite/gdb.base/reread.exp b/gdb/testsuite/gdb.base/reread.exp
new file mode 100644
index 00000000000..5e17e11df7b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/reread.exp
@@ -0,0 +1,189 @@
+# Copyright 1998, 2000, 2001 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set prototypes 1
+
+# build the first test case
+
+set testfile1 "reread1"
+set srcfile1 ${testfile1}.c
+# Cygwin needs $EXEEXT.
+set binfile1 ${objdir}/${subdir}/${testfile1}$EXEEXT
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile1}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# build the second test case
+
+set testfile2 "reread2"
+set srcfile2 ${testfile2}.c
+set binfile2 ${objdir}/${subdir}/${testfile2}$EXEEXT
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Start with a fresh gdb.
+
+set testfile "reread"
+set binfile ${objdir}/${subdir}/${testfile}$EXEEXT
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+set prms_id 13484
+set bug_id 0
+
+# Load the first executable.
+
+gdb_test "shell mv ${binfile1} ${binfile}" "" ""
+gdb_load ${binfile}
+
+# Set a breakpoint at foo
+
+gdb_test "break foo" \
+ "Breakpoint.*at.* file .*$srcfile1, line 14.*" \
+ "breakpoint foo in first file"
+
+
+# Run, should see "Breakpoint 1, foo () at hello1.c:14"
+
+gdb_run_cmd
+
+gdb_expect {
+ -re ".*Breakpoint.* foo .* at .*$srcfile1:14.*$gdb_prompt $" {
+ pass "run to foo()";
+ }
+ -re ".*$gdb_prompt $" {
+ fail "run to foo()";
+ gdb_suppress_tests;
+ }
+ timeout { fail "run to foo() (timeout)" ; gdb_suppress_tests }
+}
+
+# Restore first executable to its original name, and move
+# second executable into its place. Ensure that the new
+# executable is at least a second newer than the old.
+
+gdb_test "shell mv ${binfile} ${binfile1}" "" ""
+gdb_test "shell mv ${binfile2} ${binfile}" "" ""
+gdb_test "shell sleep 1" "" ""
+gdb_test "shell touch ${binfile}" "" ""
+
+# Run a second time; GDB should detect that the executable has changed
+# and reset the breakpoints correctly.
+# Should see "Breakpoint 1, foo () at reread2.c:9"
+
+set prms_id 0
+
+if [is_remote target] {
+ unsupported "run to foo() second time ";
+} else {
+ gdb_run_cmd
+ gdb_expect {
+ # -re ".*re-reading symbols.*Breakpoint.* foo .* at .*$srcfile2:9.*$gdb_prompt $" {}
+ -re ".*Breakpoint.* foo .* at .*:9.*$gdb_prompt $" {
+ pass "run to foo() second time ";
+ }
+ -re ".*$gdb_prompt $" {
+ fail "run to foo() second time";
+ gdb_suppress_tests;
+ }
+ timeout {
+ fail "run to foo() second time (timeout)" ;
+ gdb_suppress_tests
+ }
+ }
+}
+
+
+### Second pass: verify that GDB checks the executable file's
+### timestamp when the program is *restarted*, not just when it exits.
+
+if [is_remote target] {
+ unsupported "second pass: GDB should check for changes before running"
+} else {
+
+ # Put the older executable back in place.
+ gdb_test "shell mv ${binfile} ${binfile2}" "" ""
+ gdb_test "shell mv ${binfile1} ${binfile}" "" ""
+
+ # Restart GDB entirely.
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+
+ # Set a breakpoint on foo and run to it.
+ gdb_test "break foo" \
+ "Breakpoint.*at.* file .*$srcfile1, line 14.*" \
+ "second pass: breakpoint foo in first file"
+ gdb_run_cmd
+ gdb_expect {
+ -re ".*Breakpoint.* foo .* at .*$srcfile1:14.*$gdb_prompt $" {
+ pass "second pass: run to foo()";
+ }
+ -re ".*$gdb_prompt $" {
+ fail "second pass: run to foo()";
+ gdb_suppress_tests;
+ }
+ timeout {
+ fail "second pass: run to foo() (timeout)"
+ gdb_suppress_tests
+ }
+ }
+
+ # This time, let the program run to completion. If GDB checks the
+ # executable file's timestamp now, it won't notice any change.
+ gdb_test "continue" ".*Program exited.*" \
+ "second pass: continue to completion"
+
+ # Now move the newer executable into place, and re-run. GDB
+ # should still notice that the executable file has changed,
+ # and still re-set the breakpoint appropriately.
+ gdb_test "shell mv ${binfile} ${binfile1}" "" ""
+ gdb_test "shell mv ${binfile2} ${binfile}" "" ""
+ gdb_run_cmd
+ gdb_expect {
+ -re ".*Breakpoint.* foo .* at .*:9.*$gdb_prompt $" {
+ pass "second pass: run to foo() second time ";
+ }
+ -re ".*$gdb_prompt $" {
+ fail "second pass: run to foo() second time";
+ gdb_suppress_tests;
+ }
+ timeout {
+ fail "second pass: run to foo() second time (timeout)" ;
+ gdb_suppress_tests
+ }
+ }
+}
+
+# End of tests.
+
+gdb_stop_suppressing_tests
+
+return 0
diff --git a/gdb/testsuite/gdb.base/reread1.c b/gdb/testsuite/gdb.base/reread1.c
new file mode 100644
index 00000000000..ae9801047d4
--- /dev/null
+++ b/gdb/testsuite/gdb.base/reread1.c
@@ -0,0 +1,26 @@
+/* pr 13484 */
+
+#include <stdio.h>
+
+int x;
+
+void bar()
+{
+ x--;
+}
+
+void foo()
+{
+ x++;
+}
+
+int main()
+{
+#ifdef usestubs
+ set_debug_traps ();
+ breakpoint ();
+#endif
+ foo();
+ bar();
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/reread2.c b/gdb/testsuite/gdb.base/reread2.c
new file mode 100644
index 00000000000..fd9f7b7ad64
--- /dev/null
+++ b/gdb/testsuite/gdb.base/reread2.c
@@ -0,0 +1,21 @@
+/* pr 13484 */
+
+#include <stdio.h>
+
+int x;
+
+void foo()
+{
+ x++;
+ printf("This is foo\n");
+}
+
+int main()
+{
+#ifdef usestubs
+ set_debug_traps ();
+ breakpoint ();
+#endif
+ foo();
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/restore.c b/gdb/testsuite/gdb.base/restore.c
new file mode 100644
index 00000000000..e05d68c2145
--- /dev/null
+++ b/gdb/testsuite/gdb.base/restore.c
@@ -0,0 +1,260 @@
+/* Test GDB's ability to restore saved registers from stack frames
+ when using the `return' command.
+ Jim Blandy <jimb@cygnus.com> --- December 1998 */
+
+#include <stdio.h>
+
+/* This is the Emacs Lisp expression I used to generate the functions
+ in this file. If people modify the functions manually, instead of
+ changing this expression and re-running it, then evaluating this
+ expression could wipe out their work, so you probably shouldn't
+ re-run it. But I leave it here for reference.
+
+ (defun callee (n) (format "callee%d" n))
+ (defun caller (n) (format "caller%d" n))
+ (defun local (n) (format "l%d" n))
+ (defun local-sum (n)
+ (if (zerop n) (insert "0")
+ (let ((j 1))
+ (while (<= j n)
+ (insert (local j))
+ (if (< j n) (insert "+"))
+ (setq j (1+ j))))))
+ (defun local-chain (n previous first-end)
+ (let ((j 1))
+ (while (<= j n)
+ (insert " register int " (local j)
+ " = increment (" previous ");")
+ (if first-end
+ (progn
+ (insert " /" "* " first-end " *" "/")
+ (setq first-end nil)))
+ (insert "\n")
+ (setq previous (local j))
+ (setq j (1+ j))))
+ previous)
+
+ (save-excursion
+ (let ((limit 5))
+ (goto-char (point-max))
+ (search-backward "generated code starts here")
+ (forward-line 1)
+ (let ((start (point)))
+ (search-forward "generated code ends here")
+ (forward-line 0)
+ (delete-region start (point)))
+
+ ;; Generate callee functions.
+ (let ((i 0))
+ (while (<= i limit)
+ (insert (format "/%s Returns n * %d + %d %s/\n"
+ "*" i (/ (+ i (* i i)) 2) "*"))
+ (insert "int\n")
+ (insert (callee i) " (int n)\n")
+ (insert "{\n")
+ (local-chain i "n" (callee i))
+ (insert " return ")
+ (local-sum i)
+ (insert ";\n")
+ (insert "}\n\n")
+ (setq i (1+ i))))
+
+ ;; Generate caller functions.
+ (let ((i 1))
+ (while (<= i limit)
+ (insert "int\n")
+ (insert (caller i) " (void)\n")
+ (insert "{\n")
+ (let ((last (local-chain i "0x7eeb" (caller i))))
+ (insert " register int n;\n")
+ (let ((j 0))
+ (while (<= j limit)
+ (insert " n = " (callee j) " ("
+ (if (> j 0) "n + " "")
+ last ");\n")
+ (setq j (1+ j)))))
+ (insert " return n+")
+ (local-sum i)
+ (insert ";\n")
+ (insert "}\n\n")
+ (setq i (1+ i))))
+
+ ;; Generate driver function.
+ (insert "void\n")
+ (insert "driver (void)\n")
+ (insert "{\n")
+ (let ((i 1))
+ (while (<= i limit)
+ (insert " printf (\"" (caller i) " () => %d\\n\", "
+ (caller i) " ());\n")
+ (setq i (1+ i))))
+ (insert "}\n\n")))
+
+ */
+
+int
+increment (int n)
+{
+ return n + 1;
+}
+
+/* generated code starts here */
+/* Returns n * 0 + 0 */
+int
+callee0 (int n)
+{
+ return 0;
+}
+
+/* Returns n * 1 + 1 */
+int
+callee1 (int n)
+{
+ register int l1 = increment (n); /* callee1 */
+ return l1;
+}
+
+/* Returns n * 2 + 3 */
+int
+callee2 (int n)
+{
+ register int l1 = increment (n); /* callee2 */
+ register int l2 = increment (l1);
+ return l1+l2;
+}
+
+/* Returns n * 3 + 6 */
+int
+callee3 (int n)
+{
+ register int l1 = increment (n); /* callee3 */
+ register int l2 = increment (l1);
+ register int l3 = increment (l2);
+ return l1+l2+l3;
+}
+
+/* Returns n * 4 + 10 */
+int
+callee4 (int n)
+{
+ register int l1 = increment (n); /* callee4 */
+ register int l2 = increment (l1);
+ register int l3 = increment (l2);
+ register int l4 = increment (l3);
+ return l1+l2+l3+l4;
+}
+
+/* Returns n * 5 + 15 */
+int
+callee5 (int n)
+{
+ register int l1 = increment (n); /* callee5 */
+ register int l2 = increment (l1);
+ register int l3 = increment (l2);
+ register int l4 = increment (l3);
+ register int l5 = increment (l4);
+ return l1+l2+l3+l4+l5;
+}
+
+int
+caller1 (void)
+{
+ register int l1 = increment (0x7eeb); /* caller1 */
+ register int n;
+ n = callee0 (l1);
+ n = callee1 (n + l1);
+ n = callee2 (n + l1);
+ n = callee3 (n + l1);
+ n = callee4 (n + l1);
+ n = callee5 (n + l1);
+ return n+l1;
+}
+
+int
+caller2 (void)
+{
+ register int l1 = increment (0x7eeb); /* caller2 */
+ register int l2 = increment (l1);
+ register int n;
+ n = callee0 (l2);
+ n = callee1 (n + l2);
+ n = callee2 (n + l2);
+ n = callee3 (n + l2);
+ n = callee4 (n + l2);
+ n = callee5 (n + l2);
+ return n+l1+l2;
+}
+
+int
+caller3 (void)
+{
+ register int l1 = increment (0x7eeb); /* caller3 */
+ register int l2 = increment (l1);
+ register int l3 = increment (l2);
+ register int n;
+ n = callee0 (l3);
+ n = callee1 (n + l3);
+ n = callee2 (n + l3);
+ n = callee3 (n + l3);
+ n = callee4 (n + l3);
+ n = callee5 (n + l3);
+ return n+l1+l2+l3;
+}
+
+int
+caller4 (void)
+{
+ register int l1 = increment (0x7eeb); /* caller4 */
+ register int l2 = increment (l1);
+ register int l3 = increment (l2);
+ register int l4 = increment (l3);
+ register int n;
+ n = callee0 (l4);
+ n = callee1 (n + l4);
+ n = callee2 (n + l4);
+ n = callee3 (n + l4);
+ n = callee4 (n + l4);
+ n = callee5 (n + l4);
+ return n+l1+l2+l3+l4;
+}
+
+int
+caller5 (void)
+{
+ register int l1 = increment (0x7eeb); /* caller5 */
+ register int l2 = increment (l1);
+ register int l3 = increment (l2);
+ register int l4 = increment (l3);
+ register int l5 = increment (l4);
+ register int n;
+ n = callee0 (l5);
+ n = callee1 (n + l5);
+ n = callee2 (n + l5);
+ n = callee3 (n + l5);
+ n = callee4 (n + l5);
+ n = callee5 (n + l5);
+ return n+l1+l2+l3+l4+l5;
+}
+
+void
+driver (void)
+{
+ printf ("caller1 () => %d\n", caller1 ());
+ printf ("caller2 () => %d\n", caller2 ());
+ printf ("caller3 () => %d\n", caller3 ());
+ printf ("caller4 () => %d\n", caller4 ());
+ printf ("caller5 () => %d\n", caller5 ());
+}
+
+/* generated code ends here */
+
+int main ()
+{
+ register int local;
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ driver ();
+ printf("exiting\n");
+}
diff --git a/gdb/testsuite/gdb.base/restore.exp b/gdb/testsuite/gdb.base/restore.exp
new file mode 100644
index 00000000000..4c7a33a37c9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/restore.exp
@@ -0,0 +1,113 @@
+# Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test GDB's ability to restore saved registers from stack frames
+# when using the `return' command.
+#
+# This file was written by Jim Blandy <jimb@cygnus.com>, with
+# fragments borrowed from return.exp.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "restore"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+proc restore_tests { } {
+ global gdb_prompt
+
+ if { ! [ runto driver ] } then { return 0 }
+
+ set limit 5
+
+ # For each caller function,
+ # call each of the callee functions,
+ # force a return from the callee, and
+ # make sure that the local variables still have the right values.
+ for {set c 1} {$c <= $limit} {incr c} {
+
+ # Set a breakpoint at the next caller function.
+ gdb_test "tbreak caller$c" "Breakpoint.*\[0-9\]*\\." "tbreak caller$c"
+
+ # Continue to the next caller function.
+ gdb_test "continue" ".*/\\* caller$c \\*/" "run to caller$c"
+
+ # Do each callee function.
+ for {set e 1} {$e <= $limit} {incr e} {
+
+ gdb_test "tbreak callee$e" "Breakpoint.*\[0-9\]*\\." \
+ "tbreak callee$e"
+
+ gdb_test "continue" ".*/\\* callee$e \\*/" "run to callee$e"
+
+ # Do a forced return from the callee.
+ send_gdb "return 0\n"
+ gdb_expect {
+ -re "Make .* return now.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "$gdb_prompt $" { }
+ }
+
+ # Check that the values of the local variables are what
+ # they should be.
+ for {set var 1} {$var <= $c} {incr var} {
+ set expected [expr 0x7eeb + $var]
+ gdb_test "print l$var" " = $expected" \
+ "caller$c called callee$e; variable l$var restored to $expected"
+ }
+ }
+ }
+
+ if ![gdb_skip_stdio_test "run to completion"] {
+ send_gdb "continue\n"
+
+ gdb_expect {
+ -re "exiting" {
+ pass "run to completion"
+ }
+ timeout {
+ fail "(timeout) run to completion"
+ }
+ }
+ } else {
+ gdb_test "continue" "" ""
+ }
+}
+
+
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set timeout 30
+restore_tests
diff --git a/gdb/testsuite/gdb.base/return.c b/gdb/testsuite/gdb.base/return.c
new file mode 100644
index 00000000000..d11a4b57e09
--- /dev/null
+++ b/gdb/testsuite/gdb.base/return.c
@@ -0,0 +1,36 @@
+#include <stdio.h>
+/* Test "return" command. */
+
+void func1 ()
+{
+ printf("in func1\n");
+}
+
+int
+func2 ()
+{
+ return -5;
+}
+
+double
+func3 ()
+{
+ return -5.0;
+}
+
+int tmp2;
+double tmp3;
+
+int main ()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ func1 ();
+ printf("in main after func1\n");
+ tmp2 = func2 ();
+ tmp3 = func3 ();
+ printf("exiting\n");
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/return.exp b/gdb/testsuite/gdb.base/return.exp
new file mode 100644
index 00000000000..e7a536bdac6
--- /dev/null
+++ b/gdb/testsuite/gdb.base/return.exp
@@ -0,0 +1,129 @@
+# Copyright (C) 1992, 1997, 2001 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Jeff Law. (law@cs.utah.edu)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "return"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+proc return_tests { } {
+ global gdb_prompt
+
+
+ if { ! [ runto func1 ] } then { return 0 }
+ send_gdb "return\n"
+ gdb_expect {
+ -re "Make .* return now.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "func1 ..;.*$gdb_prompt $" {
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re ".*in main after func1.*$gdb_prompt $" { pass "simple return" }
+ -re "$gdb_prompt $" { fail "simple return" }
+ timeout { fail "(timeout) simple return" }
+ }
+
+ # Set breakpoints in other interesting functions.
+ gdb_test "break func2" "" "break func2"
+ gdb_test "break func3" "" "break func3"
+
+ gdb_test "continue" "return -5;" "continue to return of -5"
+ send_gdb "return 5\n"
+ gdb_expect {
+ -re "Make .* return now.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re ".*tmp2 = func2.*$gdb_prompt $" { }
+ -re "$gdb_prompt $" { fail "did not return (integer test)" }
+ timeout { fail "(timeout) did not return (integer test)" }
+ }
+ gdb_test "next" "tmp3 = func3.*" "next over call to func2"
+
+ gdb_test "p tmp2" ".* = 5" "correct value returned (integer test)"
+
+ gdb_test "continue" "return -5.0;" "continue to return of -5.0"
+
+ # Return of a double does not work for 68hc11 (need struct return
+ # in memory).
+ setup_xfail "m6811-*-*"
+ send_gdb "return 5.0\n"
+ gdb_expect {
+ -re "Make .* return now.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re ".*tmp3 = func3.*$gdb_prompt $" { }
+ -re "$gdb_prompt $" { fail "did not return (double test)" }
+ timeout { fail "(timeout) did not return (double test)" }
+ }
+
+ setup_xfail "m6811-*-*"
+ gdb_test "next" "printf.*" "next over call to func3"
+
+ # This test is going to fail on all i*86 systems using an i*87.
+ # When returning a floating point value from a function, all known
+ # compilers do this via a `fldl' instruction, which pushes the floating
+ # value on the i387 stack. This causes two problems:
+ # a) Most i*86 targets do not store (or cannot store, see comment in
+ # in i386v-nat.c:i386_register_u_addr) the floating point registers
+ # to the target.
+ # b) gdb would have to figure out if the `fldl' instruction (or variants
+ # of it) has already been executed. If not, it would have to simulate
+ # a push instruction, as it is not enough to write the register,
+ # the floating point `stack pointer' has to be updated too.
+ # Do not expect this to get fixed anytime soon.
+
+ # This test also fails for sparc Solaris 2.3 & 2.4, but passes under 2.5
+ # At the time the `next' is issued, the floating point unit for the
+ # process is not yet initialized, and the storing of the floating
+ # point value to the floating point return register is ignored.
+ # Xfail it for current versions that are known to fail. Presumably
+ # if some future version does initialize the floating point unit at
+ # process start, making this test pass, it will be for a version that
+ # is not xfailed.
+
+ setup_xfail "i*86-*-*" "sparc-*-solaris2.3*" "sparc-*-solaris2.4*" "m6811-*-*"
+ gdb_test "p tmp3" ".* = 5.*" "correct value returned double test (known problem with i*86 and sparc solaris"
+}
+
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set timeout 30
+return_tests
diff --git a/gdb/testsuite/gdb.base/return2.c b/gdb/testsuite/gdb.base/return2.c
new file mode 100644
index 00000000000..58d85eca113
--- /dev/null
+++ b/gdb/testsuite/gdb.base/return2.c
@@ -0,0 +1,110 @@
+/* Test gdb's "return" command. */
+
+int void_test = 0;
+int main_test = 0;
+
+char char_returnval = '1';
+short short_returnval = 1;
+int int_returnval = 1;
+long long_returnval = 1;
+long long long_long_returnval = 1;
+float float_returnval = 1;
+double double_returnval = 1;
+
+union {
+ char char_testval;
+ short short_testval;
+ int int_testval;
+ long long_testval;
+ long long long_long_testval;
+ float float_testval;
+ double double_testval;
+ char ffff[80];
+} testval;
+
+void void_func ()
+{
+ void_test = 1;
+}
+
+char char_func ()
+{
+ return char_returnval;
+}
+
+short short_func ()
+{
+ return short_returnval;
+}
+
+int int_func ()
+{
+ return int_returnval;
+}
+
+long long_func ()
+{
+ return long_returnval;
+}
+
+long long long_long_func ()
+{
+ return long_long_returnval;
+}
+
+float float_func ()
+{
+ return float_returnval;
+}
+
+double double_func ()
+{
+ return double_returnval;
+}
+
+int main (int argc, char **argv)
+{
+ char char_resultval;
+ short short_resultval;
+ int int_resultval;
+ long long_resultval;
+ long long long_long_resultval;
+ float float_resultval;
+ double double_resultval;
+ int i;
+
+ /* A "test load" that will insure that the function really returns
+ a ${type} (as opposed to just a truncated or part of a ${type}). */
+ for (i = 0; i < sizeof (testval.ffff); i++)
+ testval.ffff[i] = 0xff;
+
+ void_func (); /* call to void_func */
+ char_resultval = char_func (); /* void_checkpoint */
+ short_resultval = short_func (); /* char_checkpoint */
+ int_resultval = int_func (); /* short_checkpoint */
+ long_resultval = long_func (); /* int_checkpoint */
+ long_long_resultval = long_long_func (); /* long_checkpoint */
+
+ /* On machines using IEEE floating point, the test pattern of all
+ 1-bits established above turns out to be a floating-point NaN
+ ("Not a Number"). According to the IEEE rules, NaN's aren't even
+ equal to themselves. This can lead to stupid conversations with
+ GDB like:
+
+ (gdb) p testval.float_testval == testval.float_testval
+ $7 = 0
+ (gdb)
+
+ This is the correct answer, but it's not the sort of thing
+ return2.exp wants to see. So to make things work the way they
+ ought, we'll set aside the `union' cleverness and initialize the
+ test values explicitly here. These values have interesting bits
+ throughout the value, so we'll still detect truncated values. */
+
+ testval.float_testval = 2.7182818284590452354;/* long_long_checkpoint */
+ float_resultval = float_func ();
+ testval.double_testval = 3.14159265358979323846; /* float_checkpoint */
+ double_resultval = double_func ();
+ main_test = 1; /* double_checkpoint */
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/return2.exp b/gdb/testsuite/gdb.base/return2.exp
new file mode 100644
index 00000000000..d10faf001fb
--- /dev/null
+++ b/gdb/testsuite/gdb.base/return2.exp
@@ -0,0 +1,129 @@
+# Copyright 2000, 2001 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@redhat.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "return2"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+proc return_1 { type } {
+ global gdb_prompt
+
+ gdb_test "break ${type}_func" "Breakpoint \[0123456789\].*" \
+ "set break on ${type}_func"
+ gdb_test "continue" "Breakpoint.* ${type}_func.*" \
+ "continue to ${type}_func"
+ send_gdb "return testval.${type}_testval\n"
+ gdb_expect {
+ -re "Make ${type}_func return now.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re ".*${type}_resultval *= ${type}_func.*$gdb_prompt $" {
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re ".*${type}_checkpoint.*$gdb_prompt $" {
+ pass "return from ${type}_func"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "return from ${type}_func"
+ }
+ timeout {
+ fail "return from ${type}_func (timeout)"
+ }
+ }
+ gdb_test "print ${type}_resultval == testval.${type}_testval" ".* = 1" \
+ "${type} value returned successfully"
+ gdb_test "print ${type}_resultval != ${type}_returnval" ".* = 1" \
+ "validate result value not equal to program return value"
+}
+
+proc return_void { } {
+ global gdb_prompt
+
+ gdb_test "break void_func" "Breakpoint \[0123456789\].*" \
+ "set break on void_func"
+ gdb_test "continue" "Breakpoint.* void_func.*" \
+ "continue to void_func"
+ send_gdb "return \n"
+ gdb_expect {
+ -re "Make void_func return now.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re ".*void_func.*call to void_func.*$gdb_prompt $" {
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re ".*void_checkpoint.*$gdb_prompt $" {
+ pass "return from void_func"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "return from void_func"
+ }
+ timeout {
+ fail "return from void_func (timeout)"
+ }
+ }
+ gdb_test "print void_test == 0" ".* = 1" \
+ "void function returned successfully"
+}
+
+proc return2_tests { } {
+ global gdb_prompt
+
+ if { ! [ runto main ] } then {
+ gdb_suppress_entire_file "Run to main failed, so all tests in this file will automatically fail."
+ }
+
+ return_void
+ return_1 "char"
+ return_1 "short"
+ return_1 "int"
+ return_1 "long"
+ if { ! [istarget "m6811-*-*"] } then {
+ return_1 "long_long"
+ }
+ return_1 "float"
+ if { ! [istarget "m6811-*-*"] } then {
+ return_1 "double"
+ }
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set timeout 30
+return2_tests
diff --git a/gdb/testsuite/gdb.base/run.c b/gdb/testsuite/gdb.base/run.c
new file mode 100644
index 00000000000..25b8a4a4aa4
--- /dev/null
+++ b/gdb/testsuite/gdb.base/run.c
@@ -0,0 +1,82 @@
+/*
+ * This simple classical example of recursion is useful for
+ * testing stack backtraces and such.
+ */
+
+#ifdef vxworks
+
+# include <stdio.h>
+
+/* VxWorks does not supply atoi. */
+static int
+atoi (z)
+ char *z;
+{
+ int i = 0;
+
+ while (*z >= '0' && *z <= '9')
+ i = i * 10 + (*z++ - '0');
+ return i;
+}
+
+/* I don't know of any way to pass an array to VxWorks. This function
+ can be called directly from gdb. */
+
+vxmain (arg)
+char *arg;
+{
+ char *argv[2];
+
+ argv[0] = "";
+ argv[1] = arg;
+ main (2, argv, (char **) 0);
+}
+
+#else /* ! vxworks */
+# include <stdio.h>
+# include <stdlib.h>
+#endif /* ! vxworks */
+
+#ifdef PROTOTYPES
+int factorial (int);
+
+int
+main (int argc, char **argv, char **envp)
+#else
+int
+main (argc, argv, envp)
+int argc;
+char *argv[], **envp;
+#endif
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+#ifdef FAKEARGV
+ printf ("%d\n", factorial (1));
+#else
+ if (argc != 2) {
+ printf ("usage: factorial <number>\n");
+ return 1;
+ } else {
+ printf ("%d\n", factorial (atoi (argv[1])));
+ }
+#endif
+ return 0;
+}
+
+#ifdef PROTOTYPES
+int factorial (int value)
+#else
+int factorial (value) int value;
+#endif
+{
+ int local_var;
+
+ if (value > 1) {
+ value *= factorial (value - 1);
+ }
+ local_var = value;
+ return (value);
+}
diff --git a/gdb/testsuite/gdb.base/scope.exp b/gdb/testsuite/gdb.base/scope.exp
new file mode 100644
index 00000000000..db2c7ea9f91
--- /dev/null
+++ b/gdb/testsuite/gdb.base/scope.exp
@@ -0,0 +1,608 @@
+# Copyright 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002 Free
+# Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "scope"
+set binfile ${objdir}/${subdir}/${testfile}
+
+
+if { [gdb_compile "${srcdir}/${subdir}/scope0.c" "${binfile}0.o" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/scope1.c" "${binfile}1.o" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${binfile}0.o ${binfile}1.o" ${binfile} executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+# Test locating various things when stopped just inside main, after
+# running init0(). To prevent cascading of errors, we report the
+# first one and quit. If all pass, then we print the pass results.
+
+proc test_at_main {} {
+ global gdb_prompt
+ global decimal
+ global det_file
+ global srcdir
+ global subdir
+ global gcc_compiled
+ global hp_cc_compiler
+
+ # skip past init. There may be a call to __main at the start of
+ # main, so the first next may only get us to the init0 call.
+ if [gdb_test "next" "$decimal.*foo \\(\\);" "next over init0() in main" "$decimal.*init0 \\(\\);" "next"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope0.c::filelocal, which is 1
+
+ if [gdb_test "print filelocal" "\\\$$decimal = 1" "print filelocal" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if [gdb_test "print 'scope0.c'::filelocal" "\\\$$decimal = 1" "print 'scope0.c'::filelocal at main" "No symbol \"scope0.c\" in current context.*" "print '$srcdir/$subdir/scope0.c'::filelocal"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope0.c::filelocal_bss, which is 101
+
+ if [gdb_test "print filelocal_bss" "\\\$$decimal = 101" "print filelocal_bss" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if [gdb_test "print 'scope0.c'::filelocal_bss" "\\\$$decimal = 101" "print 'scope0.c'::filelocal_bss in test_at_main" "No symbol \"scope0.c\" in current context.*" "print '$srcdir/$subdir/scope0.c'::filelocal_bss"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope0.c::filelocal_ro, which is 201
+
+ # No clue why the powerpc fails this test.
+ setup_xfail "powerpc-*-*"
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if [gdb_test "print filelocal_ro" "\\\$$decimal = 201" "print filelocal_ro in test_at_main" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ setup_xfail "powerpc-*-*"
+ if [gdb_test "print 'scope0.c'::filelocal_ro" "\\\$$decimal = 201" "print 'scope0.c'::filelocal_ro" "No symbol \"scope0.c\" in current context.*" "print '$srcdir/$subdir/scope0.c'::filelocal_ro"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope1.c::filelocal, which is 2
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if {$hp_cc_compiler} then { setup_xfail "hppa2.0w-*-*" 11747CLLbs}
+ if [gdb_test "print 'scope1.c'::filelocal" "\\\$$decimal = 2" "print 'scope1.c'::filelocal" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::filelocal"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope1.c::filelocal_bss, which is 102
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if {$hp_cc_compiler} then { setup_xfail "hppa2.0w-*-*" 11747CLLbs}
+ if [gdb_test "print 'scope1.c'::filelocal_bss" "\\\$$decimal = 102" "print 'scope1.c'::filelocal_bss" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::filelocal_bss"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope1.c::filelocal_ro, which is 202
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if {$hp_cc_compiler} then { setup_xfail "hppa2.0w-*-*" 11747CLLbs}
+ if [gdb_test "print 'scope1.c'::filelocal_ro" "\\\$$decimal = 202" "print 'scope1.c'::filelocal_ro" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::filelocal_ro"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope1.c::foo::funclocal, which is 3
+
+ if [gdb_test "print foo::funclocal" "\\\$$decimal = 3" "print foo::funclocal" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if [gdb_test "print 'scope1.c'::foo::funclocal" "\\\$$decimal = 3" "print 'scope1.c'::foo::funclocal" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::foo::funclocal"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope1.c::foo::funclocal_ro, which is 203
+
+ if [gdb_test "print foo::funclocal_ro" "\\\$$decimal = 203" "print foo::funclocal_ro" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if [gdb_test "print 'scope1.c'::foo::funclocal_ro" "\\\$$decimal = 203" "print 'scope1.c'::foo::funclocal_ro" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::foo::funclocal_ro"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope1.c::bar::funclocal, which is 4
+
+ if [gdb_test "print bar::funclocal" "\\\$$decimal = 4" "print bar::funclocal" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if [gdb_test "print 'scope1.c'::bar::funclocal" "\\\$$decimal = 4" "print 'scope1.c'::bar::funclocal" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::bar::funclocal"] {
+ gdb_suppress_tests ;
+ }
+ gdb_stop_suppressing_tests;
+
+}
+
+proc test_at_foo {} {
+ global gdb_prompt
+ global decimal
+ global det_file
+ global srcdir
+ global subdir
+ global gcc_compiled
+
+ if [gdb_test "next" ".*bar \\(\\);" "" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope0.c::filelocal, which is 1
+
+ if [gdb_test "print 'scope0.c'::filelocal" "\\\$$decimal = 1" "print 'scope0.c'::filelocal at foo" "No symbol \"scope0.c\" in current context.*" "print '$srcdir/$subdir/scope0.c'::filelocal"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope0.c::filelocal_bss, which is 101
+
+ if [gdb_test "print 'scope0.c'::filelocal_bss" "\\\$$decimal = 101" "print 'scope0.c'::filelocal_bss in test_at_foo" "No symbol \"scope0.c\" in current context.*" "print '$srcdir/$subdir/scope0.c'::filelocal_bss"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope0.c::filelocal_ro, which is 201
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ setup_xfail "powerpc-*-*"
+ if [gdb_test "print 'scope0.c'::filelocal_ro" "\\\$$decimal = 201" "print 'scope0.c'::filelocal_ro" "No symbol \"scope0.c\" in current context.*" "print '$srcdir/$subdir/scope0.c'::filelocal_ro"] {
+ gdb_suppress_tests ;
+ }
+
+
+ gdb_test "print filelocal" "\\\$$decimal = 2" "print filelocal at foo"
+
+ # Print scope1.c::filelocal, which is 2
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if [gdb_test "print 'scope1.c'::filelocal" "\\\$$decimal = 2" "print 'scope1.c'::filelocal at foo" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::filelocal"] {
+ gdb_suppress_tests ;
+ }
+
+
+ gdb_test "print filelocal_bss" "\\\$$decimal = 102" \
+ "print filelocal_bss at foo"
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "print 'scope1.c'::filelocal_bss" "\\\$$decimal = 102" "print 'scope1.c'::filelocal_bss at foo" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::filelocal_bss"
+
+
+ gdb_test "print filelocal_ro" "\\\$$decimal = 202" \
+ "print filelocal_ro at foo"
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "print 'scope1.c'::filelocal_ro" "\\\$$decimal = 202" "print 'scope1.c'::filelocal_ro at foo" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::filelocal_ro"
+
+
+ # Print scope1.c::foo::funclocal, which is 3
+
+ gdb_test "print funclocal" "\\\$$decimal = 3" "print funclocal at foo"
+
+ gdb_test "print foo::funclocal" "\\\$$decimal = 3" \
+ "print foo::funclocal at foo"
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "print 'scope1.c'::foo::funclocal" "\\\$$decimal = 3" "print 'scope1.c'::foo::funclocal at foo" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::foo::funclocal"
+
+
+ # Print scope1.c::foo::funclocal_bss, which is 103
+
+ gdb_test "print funclocal_bss" "\\\$$decimal = 103" \
+ "print funclocal_bss at foo"
+
+ gdb_test "print foo::funclocal_bss" "\\\$$decimal = 103" \
+ "print foo::funclocal_bss at foo"
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "print 'scope1.c'::foo::funclocal_bss" "\\\$$decimal = 103" "print 'scope1.c'::foo::funclocal_bss at foo" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::foo::funclocal_bss"
+
+
+ # Print scope1.c::foo::funclocal_ro, which is 203
+
+ gdb_test "print funclocal_ro" "\\\$$decimal = 203" \
+ "print funclocal_ro at foo"
+
+ gdb_test "print foo::funclocal_ro" "\\\$$decimal = 203" \
+ "print foo::funclocal_ro at foo"
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "print 'scope1.c'::foo::funclocal_ro" "\\\$$decimal = 203" "print 'scope1.c'::foo::funclocal_ro at foo" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::foo::funclocal_ro"
+
+
+ # Print scope1.c::bar::funclocal, which is 4
+
+ gdb_test "print bar::funclocal" "\\\$$decimal = 4" \
+ "print bar::funclocal at foo"
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ gdb_test "print 'scope1.c'::bar::funclocal" "\\\$$decimal = 4" "print 'scope1.c'::bar::funclocal at foo" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::bar::funclocal"
+ gdb_stop_suppressing_tests;
+
+}
+
+proc test_at_bar {} {
+ global gdb_prompt
+ global decimal
+ global det_file
+ global srcdir
+ global subdir
+ global gcc_compiled
+
+ if [gdb_test "next" ".*" "" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope0.c::filelocal, which is 1
+
+ if [gdb_test "print 'scope0.c'::filelocal" "\\\$$decimal = 1" "print 'scope0.c'::filelocal at bar" "No symbol \"scope0.c\" in current context.*" "print '$srcdir/$subdir/scope0.c'::filelocal"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope0.c::filelocal_bss, which is 101
+
+ if [gdb_test "print 'scope0.c'::filelocal_bss" "\\\$$decimal = 101" "print 'scope0.c'::filelocal_bss in test_at_bar" "No symbol \"scope0.c\" in current context.*" "print '$srcdir/$subdir/scope0.c'::filelocal_bss"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope0.c::filelocal_ro, which is 201
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ setup_xfail "powerpc-*-*"
+ if [gdb_test "print 'scope0.c'::filelocal_ro" "\\\$$decimal = 201" "print 'scope0.c'::filelocal_ro at bar" "No symbol \"scope0.c\" in current context.*" "print '$srcdir/$subdir/scope0.c'::filelocal_ro"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope1.c::filelocal, which is 2
+
+ if [gdb_test "print filelocal" "\\\$$decimal = 2" "print filelocal at bar" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if [gdb_test "print 'scope1.c'::filelocal" "\\\$$decimal = 2" "print 'scope1.c'::filelocal at bar" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::filelocal"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope1.c::filelocal_bss, which is 102
+
+ if [gdb_test "print filelocal_bss" "\\\$$decimal = 102" "print filelocal_bss at bar" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if [gdb_test "print 'scope1.c'::filelocal_bss" "\\\$$decimal = 102" "print 'scope1.c'::filelocal_bss at bar" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::filelocal_bss"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope1.c::filelocal_ro, which is 202
+
+ if [gdb_test "print filelocal_ro" "\\\$$decimal = 202" "print filelocal_ro in test_at_bar" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if [gdb_test "print 'scope1.c'::filelocal_ro" "\\\$$decimal = 202" "print 'scope1.c'::filelocal_ro at bar" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::filelocal_ro"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope1.c::foo::funclocal, which is 3
+
+ if [gdb_test "print foo::funclocal" "\\\$$decimal = 3" "print foo::funclocal at bar" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if [gdb_test "print 'scope1.c'::foo::funclocal" "\\\$$decimal = 3" "print 'scope1.c'::foo::funclocal at bar" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::foo::funclocal"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope1.c::foo::funclocal_bss, which is 103
+
+ if [gdb_test "print foo::funclocal_bss" "\\\$$decimal = 103" "print foo::funclocal_bss at bar" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if [gdb_test "print 'scope1.c'::foo::funclocal_bss" "\\\$$decimal = 103" "print 'scope1.c'::foo::funclocal_bss at bar" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::foo::funclocal_bss"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope1.c::foo::funclocal_ro, which is 203
+
+ if [gdb_test "print foo::funclocal_ro" "\\\$$decimal = 203" "print foo::funclocal_ro at bar" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if [gdb_test "print 'scope1.c'::foo::funclocal_ro" "\\\$$decimal = 203" "print 'scope1.c'::foo::funclocal_ro at bar" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::foo::funclocal_ro"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope1.c::bar::funclocal, which is 4
+
+ if [gdb_test "print funclocal" "\\\$$decimal = 4" "print funclocal at bar" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if [gdb_test "print bar::funclocal" "\\\$$decimal = 4" "print bar::funclocal at bar" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if [gdb_test "print 'scope1.c'::bar::funclocal" "\\\$$decimal = 4" "print 'scope1.c'::bar::funclocal at bar" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::bar::funclocal"] {
+ gdb_suppress_tests ;
+ }
+
+
+ # Print scope1.c::bar::funclocal_bss, which is 104
+
+ if [gdb_test "print funclocal_bss" "\\\$$decimal = 104" "print funclocal_bss at bar" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if [gdb_test "print bar::funclocal_bss" "\\\$$decimal = 104" "print bar::funclocal_bss at bar" ] {
+ gdb_suppress_tests ;
+ }
+
+
+ if {$gcc_compiled} then { setup_xfail "rs6000-*-*" }
+ if [gdb_test "print 'scope1.c'::bar::funclocal_bss" "\\\$$decimal = 104" "print 'scope1.c'::bar::funclocal_bss at bar" "No symbol \"scope1.c\" in current context.*" "print '$srcdir/$subdir/scope1.c'::bar::funclocal_bss"] {
+ gdb_suppress_tests ;
+ }
+ gdb_stop_suppressing_tests;
+
+}
+
+# This test has little to do with local scopes, but it is in scope.exp anyway.
+# That's life.
+
+proc test_at_autovars {} {
+ global gdb_prompt
+ global decimal
+ global hex
+ global srcfile
+
+ # Test symbol table lookup with 100 local (auto) variables.
+
+ gdb_breakpoint marker1
+
+ if [gdb_test "cont" "Break.* marker1 \\(\\) at .*:$decimal.*" "continue to marker1"] {
+ gdb_suppress_tests;
+ }
+
+ if [gdb_test "up" ".*autovars.*" "up from marker1 in scope.exp" ] {
+ gdb_suppress_tests ;
+ }
+
+ set count 0
+ while {$count < 100} {
+ if [gdb_test "print i$count" ".* = $count" "" ] {
+ gdb_suppress_tests ;
+ }
+
+ set count [expr $count+1]
+ }
+ clear_xfail "*-*-*"
+ pass "$count auto variables correctly initialized"
+
+ # Test that block variable sorting is not screwing us.
+ gdb_test "frame" "#.*autovars \\(bcd=5, abc=6\\).*" "args in correct order"
+}
+
+proc test_at_localscopes {} {
+ global gdb_prompt
+ global decimal
+ global hex
+ global srcfile
+
+ gdb_breakpoint marker2
+ gdb_breakpoint marker3
+ gdb_breakpoint marker4
+
+ if [gdb_test "cont" "Break.* marker2 \\(\\) at .*:$decimal.*" "continue to marker2"] {
+ gdb_suppress_tests;
+ }
+ if [gdb_test "up" ".*localscopes.*" "up from marker2 in scopes.exp" ] {
+ gdb_suppress_tests ;
+ }
+
+ # Should be at first (outermost) scope. Check values.
+
+ gdb_test "print localval" " = 10" "print localval, outer scope"
+ gdb_test "print localval1" " = 11" "print localval1, outer scope"
+ gdb_test "print localval2" "No symbol \"localval2\" in current context." \
+ "print localval2, outer scope"
+ gdb_test "print localval3" "No symbol \"localval3\" in current context." \
+ "print localval3, outer scope"
+
+ if [gdb_test "cont" "Break.* marker3 \\(\\) at .*:$decimal.*" \
+ "continue to marker3 in scope.exp"] then { gdb_suppress_tests }
+ if [gdb_test "up" ".*localscopes.*" "up from marker3 in scope.exp"] {
+ gdb_suppress_tests
+ }
+
+ # Should be at next (first nested) scope. Check values.
+
+ gdb_test "print localval" " = 20" \
+ "print localval, first nested scope"
+ gdb_test "print localval1" " = 11" "print localval1, first nested scope"
+ gdb_test "print localval2" " = 12" "print localval2, first nested scope"
+ gdb_test "print localval3" "No symbol \"localval3\" in current context." \
+ "print localval3, first nested scope"
+
+ # This test will only fail if the file was compiled by gcc, but
+ # there's no way to check that.
+ if [gdb_test "cont" "Break.* marker4.*at .*:$decimal.*" \
+ "continue to marker4 in scope.exp"] then { gdb_suppress_tests }
+ if [gdb_test "up" ".*localscopes.*" "up from marker4 in scope.exp"] {
+ gdb_suppress_tests
+ }
+
+ gdb_test "print localval" " = 30" "print localval, innermost scope"
+ gdb_test "print localval1" " = 11" "print localval1, innermost scope"
+ gdb_test "print localval2" " = 12" "print localval2, innermost scope"
+ gdb_test "print localval3" " = 13" "print localval3, innermost scope"
+ gdb_stop_suppressing_tests;
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if [istarget "*-*-vxworks*"] {
+ set timeout 120
+ verbose "Timeout is now $timeout seconds" 2
+}
+
+# Test that variables in various segments print out correctly before
+# the program is run.
+
+# AIX--sections get mapped to the same address so we can't get the right one.
+setup_xfail "rs6000-*-*"
+setup_xfail "powerpc-*-*"
+
+gdb_test "print 'scope0.c'::filelocal_ro" "= 201"
+
+# gdb currently cannot access bss memory on some targets if the inferior
+# is not running.
+#
+# For PA boards using monitor/remote-pa.c, the bss test is going to
+# randomly fail. We've already put remote-pa on the target stack,
+# so we actually read memory from the board. Problem is crt0.o
+# is responsible for clearing bss and that hasnt' happened yet.
+#
+# This is a problem for all non-native targets. -- manson
+if [is_remote target] {
+ unsupported "print 'scope0.c'::filelocal_bss before run"
+} else {
+ gdb_test "print 'scope0.c'::filelocal_bss" "= 0" \
+ "print 'scope0.c'::filelocal_bss before run"
+}
+
+gdb_test "print 'scope0.c'::filelocal" "= 1" \
+ "print 'scope0.c'::filelocal before run"
+
+if [runto_main] then { test_at_main }
+if [istarget "mips-idt-*"] then {
+ # Restart because IDT/SIM runs out of file descriptors.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+}
+if [runto foo] then { test_at_foo }
+if [istarget "mips-idt-*"] then {
+ # Restart because IDT/SIM runs out of file descriptors.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+}
+if [runto bar] then { test_at_bar }
+if [istarget "mips-idt-*"] then {
+ # Restart because IDT/SIM runs out of file descriptors.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+}
+if [runto localscopes] then { test_at_localscopes }
+if [istarget "mips-idt-*"] then {
+ # Restart because IDT/SIM runs out of file descriptors.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+}
+if [runto autovars] then { test_at_autovars }
+
+if [istarget "*-*-vxworks*"] {
+ set timeout 120
+ verbose "Timeout is now $timeout seconds" 2
+}
diff --git a/gdb/testsuite/gdb.base/scope0.c b/gdb/testsuite/gdb.base/scope0.c
new file mode 100644
index 00000000000..ad994fc0b21
--- /dev/null
+++ b/gdb/testsuite/gdb.base/scope0.c
@@ -0,0 +1,208 @@
+static int filelocal = 1; /* In Data section */
+static int filelocal_bss; /* In BSS section */
+#ifndef __STDC__
+#define const /**/
+#endif
+static const int filelocal_ro = 201; /* In Read-Only Data section */
+
+extern void init1();
+extern void foo();
+
+int autovars (int bcd, int abc);
+int localscopes (int x);
+int useit (int val);
+void init0();
+void marker1 ();
+void marker2 ();
+void marker3 ();
+void marker4 ();
+
+int main ()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ init0 ();
+ foo ();
+ autovars (5, 6);
+ localscopes (0);
+}
+
+/* On some systems, such as AIX, unreferenced variables are deleted
+ from the executable. */
+void usestatics ()
+{
+ useit (filelocal);
+ useit (filelocal_bss);
+ useit (filelocal_ro);
+}
+
+void init0 ()
+{
+ filelocal_bss = 101;
+ init1 ();
+}
+
+/* This is to derail optimizer in localscopes.
+ Return 1 + 2 + . . . + N. */
+#ifdef PROTOTYPES
+int
+sum_upto (int n)
+#else
+int
+sum_upto (n)
+ int n;
+#endif
+{
+ int i;
+ int retval = 0;
+
+ for (i = 1; i <= n; ++i)
+ retval += i;
+ return retval;
+}
+
+#ifdef PROTOTYPES
+int
+useit (int val)
+#else
+int
+useit (val)
+#endif
+{
+ static int usedval;
+
+ usedval = val;
+ return val + sum_upto (0);
+}
+
+#ifdef PROTOTYPES
+int
+autovars (int bcd, int abc)
+#else
+int
+autovars (bcd, abc)
+ int bcd;
+ int abc;
+#endif
+{
+ int i0 = useit (0), i1 = useit (1), i2 = useit (2);
+ int i3 = useit (3), i4 = useit (4), i5 = useit (5);
+ int i6 = useit (6), i7 = useit (7), i8 = useit (8);
+ int i9 = useit (9), i10 = useit (10), i11 = useit (11);
+ int i12 = useit (12), i13 = useit (13), i14 = useit (14);
+ int i15 = useit (15), i16 = useit (16), i17 = useit (17);
+ int i18 = useit (18), i19 = useit (19), i20 = useit (20);
+ int i21 = useit (21), i22 = useit (22), i23 = useit (23);
+ int i24 = useit (24), i25 = useit (25), i26 = useit (26);
+ int i27 = useit (27), i28 = useit (28), i29 = useit (29);
+ int i30 = useit (30), i31 = useit (31), i32 = useit (32);
+ int i33 = useit (33), i34 = useit (34), i35 = useit (35);
+ int i36 = useit (36), i37 = useit (37), i38 = useit (38);
+ int i39 = useit (39), i40 = useit (40), i41 = useit (41);
+ int i42 = useit (42), i43 = useit (43), i44 = useit (44);
+ int i45 = useit (45), i46 = useit (46), i47 = useit (47);
+ int i48 = useit (48), i49 = useit (49), i50 = useit (50);
+ int i51 = useit (51), i52 = useit (52), i53 = useit (53);
+ int i54 = useit (54), i55 = useit (55), i56 = useit (56);
+ int i57 = useit (57), i58 = useit (58), i59 = useit (59);
+ int i60 = useit (60), i61 = useit (61), i62 = useit (62);
+ int i63 = useit (63), i64 = useit (64), i65 = useit (65);
+ int i66 = useit (66), i67 = useit (67), i68 = useit (68);
+ int i69 = useit (69), i70 = useit (70), i71 = useit (71);
+ int i72 = useit (72), i73 = useit (73), i74 = useit (74);
+ int i75 = useit (75), i76 = useit (76), i77 = useit (77);
+ int i78 = useit (78), i79 = useit (79), i80 = useit (80);
+ int i81 = useit (81), i82 = useit (82), i83 = useit (83);
+ int i84 = useit (84), i85 = useit (85), i86 = useit (86);
+ int i87 = useit (87), i88 = useit (88), i89 = useit (89);
+ int i90 = useit (90), i91 = useit (91), i92 = useit (92);
+ int i93 = useit (93), i94 = useit (94), i95 = useit (95);
+ int i96 = useit (96), i97 = useit (97), i98 = useit (98);
+ int i99 = useit (99);
+
+ /* Use all 100 of the local variables to derail agressive optimizers. */
+
+ useit ( i0); useit ( i1); useit ( i2); useit ( i3); useit ( i4);
+ useit ( i5); useit ( i6); useit ( i7); useit ( i8); useit ( i9);
+ useit (i10); useit (i11); useit (i12); useit (i13); useit (i14);
+ useit (i15); useit (i16); useit (i17); useit (i18); useit (i19);
+ useit (i20); useit (i21); useit (i22); useit (i23); useit (i24);
+ useit (i25); useit (i26); useit (i27); useit (i28); useit (i29);
+ useit (i30); useit (i31); useit (i32); useit (i33); useit (i34);
+ useit (i35); useit (i36); useit (i37); useit (i38); useit (i39);
+ useit (i40); useit (i41); useit (i42); useit (i43); useit (i44);
+ useit (i45); useit (i46); useit (i47); useit (i48); useit (i49);
+ useit (i50); useit (i51); useit (i52); useit (i53); useit (i54);
+ useit (i55); useit (i56); useit (i57); useit (i58); useit (i59);
+ useit (i60); useit (i61); useit (i62); useit (i63); useit (i64);
+ useit (i65); useit (i66); useit (i67); useit (i68); useit (i69);
+ useit (i70); useit (i71); useit (i72); useit (i73); useit (i74);
+ useit (i75); useit (i76); useit (i77); useit (i78); useit (i79);
+ useit (i80); useit (i81); useit (i82); useit (i83); useit (i84);
+ useit (i85); useit (i86); useit (i87); useit (i88); useit (i89);
+ useit (i90); useit (i91); useit (i92); useit (i93); useit (i94);
+ useit (i95); useit (i96); useit (i97); useit (i98); useit (i99);
+
+ useit (abc); useit (bcd);
+
+ marker1 ();
+ return i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10
+ + i11 + i12 + i13 + i14 + i15 + i16 + i17 + i18 + i19 + i20
+ + i21 + i22 + i23 + i24 + i25 + i26 + i27 + i28 + i29 + i30
+ + i31 + i32 + i33 + i34 + i35 + i36 + i37 + i38 + i39 + i40
+ + i41 + i42 + i43 + i44 + i45 + i46 + i47 + i48 + i49 + i50
+ + i51 + i52 + i53 + i54 + i55 + i56 + i57 + i58 + i59 + i60
+ + i61 + i62 + i63 + i64 + i65 + i66 + i67 + i68 + i69 + i70
+ + i71 + i72 + i73 + i74 + i75 + i76 + i77 + i78 + i79 + i80
+ + i81 + i82 + i83 + i84 + i85 + i86 + i87 + i88 + i89 + i90
+ + i91 + i92 + i93 + i94 + i95 + i96 + i97 + i98 + i99 + abc + bcd;
+}
+
+#ifdef PROTOTYPES
+int
+localscopes (int x)
+#else
+int
+localscopes (x)
+ int x;
+#endif
+{
+ int localval;
+ int retval;
+ int i;
+
+ localval = 0;
+ useit (localval);
+
+ {
+ int localval = x + 4 + sum_upto (3); /* 10 */
+ int localval1 = x + 5 + sum_upto (3); /* 11 */
+
+ useit (localval);
+ useit (localval1);
+ marker2 ();
+ {
+ int localval = localval1 + 3 + sum_upto (3); /* 20 */
+ int localval2 = localval1 + sum_upto (1); /* 12 */
+ useit (localval);
+ useit (localval2);
+ marker3 ();
+ {
+ int localval = localval2 + 3 + sum_upto (5); /* 30 */
+ int localval3 = localval2 + sum_upto (1); /* 13 */
+ useit (localval);
+ useit (localval3);
+ marker4 ();
+ retval = x + localval1 + localval2 + localval3;
+ }
+ }
+ }
+ return retval;
+}
+
+void marker1 () {}
+void marker2 () {}
+void marker3 () {}
+void marker4 () {}
diff --git a/gdb/testsuite/gdb.base/scope1.c b/gdb/testsuite/gdb.base/scope1.c
new file mode 100644
index 00000000000..8c325224993
--- /dev/null
+++ b/gdb/testsuite/gdb.base/scope1.c
@@ -0,0 +1,54 @@
+static int filelocal = 2; /* In Data section */
+static int filelocal_bss; /* In BSS section */
+#ifndef __STDC__
+#define const /**/
+#endif
+static const int filelocal_ro = 202; /* In Read-Only Data section */
+
+void foo ()
+{
+
+ void bar ();
+
+ static int funclocal = 3; /* In Data section */
+ static int funclocal_bss; /* In BSS section */
+ static const int funclocal_ro = 203; /* RO Data */
+ static const int funclocal_ro_bss; /* RO Data */
+
+ funclocal_bss = 103;
+ bar ();
+}
+
+void bar ()
+{
+ static int funclocal = 4; /* In data section */
+ static int funclocal_bss; /* In BSS section */
+ funclocal_bss = 104;
+}
+
+void init1 ()
+{
+ filelocal_bss = 102;
+}
+
+/* On some systems, such as AIX, unreferenced variables are deleted
+ from the executable. */
+void usestatics1 ()
+{
+ void useit1 (int val);
+
+ useit1 (filelocal);
+ useit1 (filelocal_bss);
+ useit1 (filelocal_ro);
+}
+
+#ifdef PROTOTYPES
+void useit1 (int val)
+#else
+void useit1 (val) int val;
+#endif
+{
+ static int usedval;
+
+ usedval = val;
+}
diff --git a/gdb/testsuite/gdb.base/sect-cmd.exp b/gdb/testsuite/gdb.base/sect-cmd.exp
new file mode 100644
index 00000000000..10c0e74959a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sect-cmd.exp
@@ -0,0 +1,125 @@
+# Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+global usestubs
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+# This test exists solely to exercise the "section" command for
+# code-coverage on HP-UX. (So far as I can tell, the "section"
+# command isn't needed on HP-UX, but probably is for embedded
+# apps.)
+#
+if ![istarget "hppa*-*-hpux*"] then {
+ return
+}
+
+set testfile "break"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then { fail "section command tests suppressed" }
+
+# Get the $CODE$ section's starting address.
+#
+# (Note that this works for PA32 programs, which use the SOM file
+# format. PA64 uses ELF, and when support for that is added, it's
+# not clear that there'll be a section named "$CODE$" in such
+# programs.)
+#
+
+set address1 ""
+set address2 ""
+send_gdb "info files\n"
+gdb_expect {
+ -re ".*(0x\[0-9a-fA-F\]*) - (0x\[0-9a-fA-F\]*) is .(CODE|text).*$gdb_prompt $"\
+ {pass "info files"
+ set address1 $expect_out(1,string)
+ set address2 $expect_out(2,string)}
+ -re "$gdb_prompt $"\
+ {fail "info files"}
+ timeout {fail "(timeout) info files"}
+}
+
+# Reset the section to that same starting address, which should be
+# harmless (i.e., we just want to exercise the section command).
+#
+if [istarget "hppa2.0w-*-*"] then {
+ send_gdb "section \.text $address1\n"
+ gdb_expect {
+ -re ".*$address1 \- $address2 is .text.*$gdb_prompt $"\
+ {pass "set section command"}
+ -re "$gdb_prompt $"\
+ {fail "set section command"}
+ timeout {fail "(timeout) set section command"}
+ }
+} else {
+ send_gdb "section \$CODE\$ $address1\n"
+ gdb_expect {
+ -re ".*$address1 \- $address2 is .CODE..*$gdb_prompt $"\
+ {pass "set section command"}
+ -re "$gdb_prompt $"\
+ {fail "set section command"}
+ timeout {fail "(timeout) set section command"}
+ }
+}
+
+# Verify that GDB responds gracefully to a non-existent section name.
+#
+send_gdb "section FOOBARBAZ 0x1234\n"
+gdb_expect {
+ -re "Section FOOBARBAZ not found\r\n$gdb_prompt $"\
+ {pass "non-existent section disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "non-existent section disallowed"}
+ timeout {fail "(timeout) non-existent section disallowed"}
+}
+
+# We "happen to know" that GDB uses a fixed size character buffer to
+# parse the section name into, and the buffer is declared to be 100
+# characters in length. Verify that GDB gracefully handles section
+# names longer than that. (The section is also non-existent.)
+#
+send_gdb "section A234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123 0x1234\n"
+gdb_expect {
+ -re "Section A23456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 not found\r\n$gdb_prompt $"\
+ {pass "non-existent too-long section disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "non-existent too-long section disallowed"}
+ timeout {fail "(timeout) non-existent too-long section disallowed"}
+}
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.base/selftest.exp b/gdb/testsuite/gdb.base/selftest.exp
new file mode 100644
index 00000000000..83ceb620e8e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/selftest.exp
@@ -0,0 +1,446 @@
+# Copyright 1988, 1990, 1991, 1992, 1994, 1997, 1999, 2000
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# are we on a target board
+if [is_remote target] {
+ return
+}
+
+if [istarget "m68k*-*-hpux*"] then {
+ # The top-level makefile passes CFLAGS= (no -g) for hp300. This probably
+ # should be fixed (it is only needed for gcc bootstrapping, not gdb),
+ # but until then.....
+ setup_xfail "*-*-*"
+ fail "cannot test self if compiled without debug info"
+ return -1
+}
+
+# Not all of the lines of code near the start of main are executed for
+# every machine. Also, optimization may reorder some of the lines.
+# So all we do is try to step or next over everything until we get
+# to a line that we know is always executed.
+
+proc do_steps_and_nexts {} {
+ global gdb_prompt
+ global srcdir
+
+ gdb_reinitialize_dir $srcdir/..
+
+ for {set count 0} {$count < 22} {incr count} {
+ send_gdb "list\n"
+ gdb_expect {
+ -re ".*context = data.*$gdb_prompt $" {
+ set description "step over context initialization"
+ set command "step"
+ }
+ -re ".*argc = context->argc.*$gdb_prompt $" {
+ set description "step over argc initialization"
+ set command "step"
+ }
+ -re ".*argv = context->argv.*$gdb_prompt $" {
+ set description "step over argv initialization"
+ set command "step"
+ }
+ -re ".*quiet = 0.*$gdb_prompt $" {
+ set description "step over quiet initialization"
+ set command "step"
+ }
+ -re ".*batch = 0.*$gdb_prompt $" {
+ set description "step over batch initialization"
+ set command "step"
+ }
+ -re ".*symarg = NULL.*$gdb_prompt $" {
+ set description "step over symarg initialization"
+ set command "step"
+ }
+ -re ".*execarg = NULL.*$gdb_prompt $" {
+ set description "step over execarg initialization"
+ set command "step"
+ }
+ -re ".*corearg = NULL.*$gdb_prompt $" {
+ set description "step over corearg initialization"
+ set command "step"
+ }
+ -re ".*cdarg = NULL.*$gdb_prompt $" {
+ set description "step over cdarg initialization"
+ set command "step"
+ }
+ -re ".*ttyarg = NULL.*$gdb_prompt $" {
+ set description "step over ttyarg initialization"
+ set command "step"
+ }
+ -re ".*time_at_startup = get_run_time.*$gdb_prompt $" {
+ set description "next over get_run_time and everything it calls"
+ set command "next"
+ }
+ -re ".*START_PROGRESS.*$gdb_prompt $" {
+ set description "next over START_PROGRESS and everything it calls"
+ set command "next"
+ }
+ -re ".*mac_init.*$gdb_prompt $" {
+ set description "next over mac_init and everything it calls"
+ set command "next"
+ }
+ -re ".*init_malloc.*$gdb_prompt $" {
+ set description "next over init_malloc and everything it calls"
+ set command "next"
+ }
+ -re ".*count . 0x3.*$gdb_prompt $" {
+ set description "next over conditional stack alignment code 1"
+ set command "next"
+ }
+ -re ".*if .i != 0.*$gdb_prompt $" {
+ set description "next over conditional stack alignment code 2"
+ set command "next"
+ }
+ -re ".*alloca .i - 4.*$gdb_prompt $" {
+ set description "next over conditional stack alignment alloca"
+ set command "next"
+ }
+ -re ".*cmdsize = 1.*$gdb_prompt $" {
+ set description "step over cmdsize initialization"
+ set command "next"
+ }
+ -re ".*cmdarg = .* xmalloc.*$gdb_prompt $" {
+ set description "next over cmdarg initialization via xmalloc"
+ set command "next"
+ }
+ -re ".*ncmd = 0.*$gdb_prompt $" {
+ set description "next over ncmd initialization"
+ set command "next"
+ }
+ -re ".*dirsize = 1.*$gdb_prompt $" {
+ set description "next over dirsize initialization"
+ set command "next"
+ }
+ -re ".*dirarg = .* xmalloc.*$gdb_prompt $" {
+ return
+ }
+ -re "\[ \t\]+\{\r\n$gdb_prompt $" {
+ setup_xfail "mips-*-irix5*"
+ fail "$description ended up at odd location"
+ }
+ -re ".*main.c.*No such file or directory.*$gdb_prompt $" {
+ setup_xfail "rs6000-*-aix3*"
+ fail "must be able to list source lines"
+ return
+ }
+ -re ".*$gdb_prompt $" {
+ fail "unknown source line after $description"
+ return
+ }
+ default {
+ fail "unknown source line near main"
+ return
+ }
+ }
+ send_gdb "$command\n"
+ gdb_expect {
+ -re ".*No such file or directory.\r\n$gdb_prompt $" {
+ fail "$description (no source available)"
+ }
+ -re ".*A file or directory .* does not exist..\r\n$gdb_prompt $" {
+ fail "$description (no source available)"
+ }
+ -re ".*$gdb_prompt $" {
+ pass "$description"
+ }
+ timeout {
+ fail "$description (timeout)"
+ }
+ }
+ }
+}
+
+proc test_with_self { executable } {
+ global gdb_prompt
+ global tool
+ global det_file
+ global decimal
+ global timeout
+
+ # load yourself into the debugger
+ # This can take a relatively long time, particularly for testing where
+ # the executable is being accessed over a network, or where gdb does not
+ # support partial symbols for a particular target and has to load the
+ # entire symbol table. Set the timeout to 10 minutes, which should be
+ # adequate for most environments (it *has* timed out with 5 min on a
+ # SPARCstation SLC under moderate load, so this isn't unreasonable).
+ # After gdb is started, set the timeout to 30 seconds for the duration
+ # of this test, and then back to the original value.
+
+ set oldtimeout $timeout
+ set timeout 600
+ verbose "Timeout is now $timeout seconds" 2
+ if {[gdb_load $executable] <0} then {
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+ return -1
+ }
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+
+ # disassemble yourself
+ gdb_test "x/10i main" \
+ "x/10i.*main.*main.$decimal.*main.$decimal.*" \
+ "Disassemble main"
+
+ # Set a breakpoint at main
+ gdb_test "break captured_main" \
+ "Breakpoint.*at.* file.*, line.*" \
+ "breakpoint in captured_main"
+
+ # We'll need this when we send a ^C to GDB. Need to do it before we
+ # run the program and gdb starts saving and restoring tty states.
+ # On Ultrix, we don't need it and it is really slow (because shell_escape
+ # doesn't use vfork).
+ if ![istarget "*-*-ultrix*"] then {
+ gdb_test "shell stty intr '^C'" "" \
+ "set interrupt character in test_with_self"
+ }
+
+ # FIXME: If we put this after the run to main, the first list
+ # command doesn't print the same line as the current line where
+ # gdb is stopped.
+ gdb_test "set listsize 1" "" "set listsize to 1"
+
+ # run yourself
+ # It may take a very long time for the inferior gdb to start (lynx),
+ # so we bump it back up for the duration of this command.
+ set timeout 600
+
+ set description "run until breakpoint at captured_main"
+ send_gdb "run -nw\n"
+ gdb_expect {
+ -re "Starting program.*Breakpoint \[0-9\]+,.*captured_main .data.* at .*main.c:.*$gdb_prompt $" {
+ pass "$description"
+ }
+ -re "Starting program.*Breakpoint \[0-9\]+,.*captured_main .data.*$gdb_prompt $" {
+ xfail "$description (line numbers scrambled?)"
+ }
+ -re "vfork: No more processes.*$gdb_prompt $" {
+ fail "$description (out of virtual memory)"
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+ return -1
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$description"
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+ return -1
+ }
+ timeout {
+ fail "$description (timeout)"
+ }
+ }
+
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+
+ # do we have a version number ?
+ send_gdb "print version\n"
+ gdb_expect {
+ -re ".\[0-9\]+ = .\[0-9.\]+.*$gdb_prompt $" {
+ pass "printed version as string"
+ }
+ -re ".\[0-9\]+ = +0x.*\[0-9.\]+.*$gdb_prompt $" {
+ pass "printed version as pointer"
+ }
+ -re ".\[0-9\]+ = +.+ +0x.*\[0-9.\]+.*$gdb_prompt $" {
+ pass "printed version with cast"
+ }
+ -re ".*$gdb_prompt $" { fail "printed version" }
+ timeout { fail "(timeout) printed version" }
+ }
+
+ do_steps_and_nexts
+
+ gdb_test "print \"foo\"" ".\[0-9\]+ = \"foo\"" "print a string"
+
+ # do_steps_and_nexts left us ready to execute an xmalloc call,
+ # so give that a try.
+ # If we don't actually enter the xmalloc call when we give a
+ # step command that seems like a genuine bug. It seems to happen
+ # on most RISC processors.
+ setup_xfail "alpha-*-*" "mips-*-*"
+ set description "step into xmalloc call"
+ send_gdb "step\n"
+ gdb_expect {
+ -re "xmalloc.*size=.*at.*utils.c.*$gdb_prompt $" {
+ pass "$description"
+ }
+ -re ".*No such file or directory.\r\n$gdb_prompt $" {
+ pass "$description (no source available)"
+ }
+ -re "A file or directory .* does not exist..\r\n$gdb_prompt $" {
+ pass "$description (no source available)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$description"
+ }
+ timeout {
+ fail "$description (timeout)"
+ }
+ }
+
+ # start the "xgdb" process
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "GNU gdb \[0-9\.\]*.*
+Copyright \[0-9\]* Free Software Foundation, Inc.*
+GDB is free software, covered by the GNU General Public License, and you are.*
+welcome to change it and/or distribute copies of it under certain conditions.*
+Type \"show copying\" to see the conditions.*
+There is absolutely no warranty for GDB. Type \"show warranty\" for details.*
+This GDB was configured as .*$gdb_prompt $"\
+ { pass "xgdb is at prompt" }
+ -re "GDB is free software and you are welcome to distribute copies of it.*
+ under certain conditions; type \"show copying\" to see the conditions..*
+There is absolutely no warranty for GDB; type \"show warranty\" for details..*
+GDB.*Copyright \[0-9\]+ Free Software Foundation, Inc..*$gdb_prompt $"\
+ { pass "xgdb is at prompt (obsolescent gdb)" }
+ -re ".*$gdb_prompt $" { fail "xgdb is at prompt" }
+ timeout { fail "(timeout) xgdb is at prompt" }
+ }
+
+ # set xgdb prompt so we can tell which is which
+ send_gdb "set prompt (xgdb) \n"
+ gdb_expect {
+ -re "\[(\]xgdb\[)\].*\[(\]xgdb\[)\] $" { pass "Set xgdb prompt" }
+ -re ".*$gdb_prompt $" { fail "Set xgdb prompt" }
+ default { fail "(timeout) Set xgdb prompt" }
+ }
+
+ # kill the xgdb process
+ set description "send ^C to child process"
+ send_gdb "\003"
+ gdb_expect {
+ -re "Program received signal SIGINT.*$gdb_prompt $" {
+ pass "$description"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$description"
+ }
+ timeout {
+ fail "$description (timeout)"
+ }
+ }
+
+ set description "send SIGINT signal to child process"
+ send_gdb "signal SIGINT\n"
+ gdb_expect {
+ -re "Continuing with signal SIGINT.*$gdb_prompt $" {
+ pass "$description"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$description"
+ }
+ timeout {
+ fail "$description (timeout)"
+ }
+ }
+
+ # get a stack trace
+ #
+ # This fails on some linux systems for unknown reasons. On the
+ # systems where it fails, sometimes it works fine when run manually.
+ # The testsuite failures may not be limited to just aout systems.
+ setup_xfail "i*86-pc-linuxaout-gnu"
+ set description "backtrace through signal handler"
+ send_gdb "backtrace\n"
+ gdb_expect {
+ -re "#0.*read.*in main \\(.*\\) at .*main\\.c.*$gdb_prompt $" {
+ pass "$description"
+ }
+ -re ".*$gdb_prompt $" {
+ # On the alpha, we hit the infamous problem about gdb
+ # being unable to get the frame pointer (mentioned in
+ # gdb/README). As it is intermittent, there is no way to
+ # XFAIL it which will give us an XPASS if the problem goes
+ # away.
+ setup_xfail "alpha*-*-osf*"
+ fail "$description"
+ }
+ timeout {
+ fail "$description (timeout)"
+ }
+ }
+
+
+ # Set the timeout back to the value it had when we were called.
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+
+ # Restart gdb in case next test expects it to be started already.
+ return 0
+}
+
+# Find a pathname to a file that we would execute if the shell was asked
+# to run $arg using the current PATH.
+
+proc find_gdb { arg } {
+
+ # If the arg directly specifies an existing executable file, then
+ # simply use it.
+
+ if [file executable $arg] then {
+ return $arg
+ }
+
+ set result [which $arg]
+ if [string match "/" [ string range $result 0 0 ]] then {
+ return $result
+ }
+
+ # If everything fails, just return the unqualified pathname as default
+ # and hope for best.
+
+ return $arg
+}
+
+# Run the test with self.
+# Copy the file executable file in case this OS doesn't like to edit its own
+# text space.
+
+set GDB_FULLPATH [find_gdb $GDB]
+
+# Remove any old copy lying around.
+remote_file host delete x$tool
+
+gdb_start
+set file [remote_download host $GDB_FULLPATH x$tool]
+set result [test_with_self $file];
+gdb_exit;
+catch "remote_file host delete $file";
+
+if {$result <0} then {
+ warning "Couldn't test self"
+ return -1
+}
diff --git a/gdb/testsuite/gdb.base/setshow.c b/gdb/testsuite/gdb.base/setshow.c
new file mode 100644
index 00000000000..fbaba0f5ddf
--- /dev/null
+++ b/gdb/testsuite/gdb.base/setshow.c
@@ -0,0 +1,27 @@
+/* IMPORTANT: leave this comment in the first line of this source file. */
+/* this will guarantee that line 1 contains no code. */
+
+#include <stdio.h>
+
+#ifdef PROTOTYPES
+int
+main(int argc, char **argv)
+#else
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+#endif
+{
+ int i = 1;
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+
+ if (argc <= 0 || argc > 8)
+ return -1;
+ while (i < argc)
+ printf ("%s ", argv[i++]);
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/setshow.exp b/gdb/testsuite/gdb.base/setshow.exp
new file mode 100644
index 00000000000..a1070fd986f
--- /dev/null
+++ b/gdb/testsuite/gdb.base/setshow.exp
@@ -0,0 +1,243 @@
+# Copyright 1992, 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "setshow"
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile ${srcfile} ${binfile} executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Start with a fresh gdb
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# make sure $pc is sane, in case we're talking to a board.
+if { ![runto_main] } {
+ gdb_suppress_tests;
+}
+
+#
+# Test gdb set and show commands.
+# Add tests here for show and set that don't fit neatly elsewhere.
+# FIXME: many rudimentary tests for set and show commands have been
+# added below, but most do nothing more than check that a
+# variable has been set successfully, ie. they do not test
+# whether setting the variable has had the desired effect.
+#
+
+#test default annotation_level is 0
+gdb_test "show annotate" "Annotation_level is 0..*" "default annotation_level is zero"
+
+#test set annotate 2
+send_gdb "set annotate 2\n"
+gdb_expect {
+ -re ".*\032\032pre-prompt.*$gdb_prompt .*\032\032prompt.*$" \
+ { pass "set annotate 2" }
+ -re ".*$gdb_prompt $" { fail "set annotate 2" }
+ timeout { fail "(timeout) set annotate 2" }
+ }
+
+send_gdb "show annotate\n"
+gdb_expect {
+ -re ".*\032\032post-prompt.*Annotation_level is 2..*\032\032pre-prompt.*$gdb_prompt .*\032\032prompt.*$" \
+ { pass "show annotate (2)" }
+ -re ".*$gdb_prompt $" { fail "show annotate (2)" }
+ timeout { fail "(timeout) show annotate (2)" }
+ }
+
+#test annotation_level 2
+send_gdb "info line 1\n"
+gdb_expect {
+ -re ".*\032\032post-prompt.*Line 1 of .* is at address .* but contains no code.*:1:0:beg:0x.*\032\032pre-prompt.*$gdb_prompt .*\032\032prompt.*$" \
+ { pass "annotation_level 2" }
+ -re ".*$gdb_prompt $" { fail "annotation_level 2" }
+ timeout { fail "(timeout) annotation_level 2" }
+ }
+
+#test set annotate 1
+gdb_test "set annotate 1" ".*post-prompt.*" "set annotate 1"
+gdb_test "show annotate" "Annotation_level is 1..*" "show annotate (1)"
+#test annotation_level 1
+gdb_test "info line 1" "Line 1 of .* is at address .* but contains no code.*:1:0:beg:0x.*" "annotation_level 1"
+#test set annotate 0
+gdb_test "set annotate 0" "" "set annotate 0"
+gdb_test "show annotate" "Annotation_level is 0..*" "show annotate (0)"
+#test annotation_level 0
+gdb_test "info line 1" "Line 1 of .* is at address .* but contains no code.*" "annotation_level 0"
+#test set args
+gdb_test "set args foo bar blup baz bubble" "" "set args"
+#test show args
+gdb_test "show args" "Argument list to give program being debugged when it is started is \"foo bar blup baz bubble\"..*" "show args"
+
+# Don't test if we can't pass args or if we're using a stub.
+if { ![target_info exists use_gdb_stub] && ![target_info exists noargs] } {
+ #test passing args
+ gdb_test "cont" "Continuing.*" "continuing"
+ delete_breakpoints
+ gdb_test "run" "Starting program:.*foo bar blup baz bubble.*" "passing args"
+}
+#test set check range on
+gdb_test "set check range on" "" "set check range on"
+#test show check range on
+gdb_test "show check range" "Range checking is \"on\"\..*" "show check range (on)"
+#test set check range auto
+gdb_test "set check range auto" "" "set check range auto"
+#test show check range auto
+gdb_test "show check range" "Range checking is \"auto; currently .*" "show check range (auto)"
+#test set check type on
+gdb_test "set check type on" "" "set check type on"
+#test show check type on
+gdb_test "show check type" "Type checking is \"on\"..*" "show check type (on)"
+#test set check type auto
+gdb_test "set check type auto" "" "set check type auto"
+#test show check type
+gdb_test "show check type" "Type checking is \"auto; currently .*" "show check type (auto)"
+#test set complaints 100
+gdb_test "set complaints 100" "" "set complaints 100"
+#test show complaints 100
+gdb_test "show complaints" "Max number of complaints about incorrect symbols is 100..*" "show complaints (100)"
+#test set complaints 0
+gdb_test "set complaints 0" "" "set complaints 0"
+#test show complaints 0
+gdb_test "show complaints" "Max number of complaints about incorrect symbols is 0..*" "show complaints (0)"
+#test set confirm off
+gdb_test "set confirm off" "" "set confirm off"
+#test show confirm off
+gdb_test "show confirm" "Whether to confirm potentially dangerous operations is off..*" "show confirm (off)"
+#test set confirm on
+gdb_test "set confirm on" "" "set confirm on"
+#test show confirm on
+gdb_test "show confirm" "Whether to confirm potentially dangerous operations is on..*" "show confirm (on)"
+#test set editing off
+gdb_test "set editing off" "" "set editing off"
+#test show editing off
+gdb_test "show editing" "Editing of command lines as they are typed is off..*" "show editing (off)"
+#test set editing on
+#gdb_test "set editing on" "" "set editing on"
+#test show editing on
+#gdb_test "show editing" "Editing of command lines as they are typed is on..*" "show editing (on)"
+#test set environment FOOBARBAZ
+gdb_test "set environment FOOBARBAZ = grbxgrbxgrbx" "" "set environment FOOBARBAZ"
+#test show environment FOOBARBAZ
+gdb_test "show environment FOOBARBAZ" "FOOBARBAZ = grbxgrbxgrbx.*" "show environment FOOBARBAZ"
+#test set height 100
+gdb_test "set height 100" "" "set height 100"
+#test show height 100
+gdb_test "show height" "Number of lines gdb thinks are in a page is 100..*" "show height"
+#test set history expansion on
+gdb_test "set history expansion on" "" "set history expansion on"
+#test show history expansion on
+gdb_test "show history expansion on" "History expansion on command input is on.*" "show history expansion"
+#test set history filename foobar.baz
+gdb_test "set history filename foobar.baz" "" "set history filename foobar.baz"
+#test show history filename foobar.baz
+gdb_test "show history filename" "The filename in which to record the command history is \"foobar.baz\"..*" "show history filename (foobar.baz)"
+#test set history save on
+gdb_test "set history save on" "" "set history save on"
+#test show history save on
+gdb_test "show history save" "Saving of the history record on exit is on..*" "show history save (on)"
+#test set history size 100
+gdb_test "set history size 100" "" "set history size 100"
+#test show history size 100
+gdb_test "show history size" "The size of the command history is 100..*" "show history size (100)"
+#test set language asm
+gdb_test "set language asm" "" "set language asm"
+#test show language asm
+gdb_test "show language" "The current source language is \"asm\"..*" "show language (asm)"
+#test set language auto
+gdb_test "set language auto" "" "set language auto"
+#test show language
+gdb_test "show language" "The current source language is \"auto.*\"..*" "show language (auto)"
+#test set listsize 100
+gdb_test "set listsize 100" "" "set listsize 100"
+#test show listsize 100
+gdb_test "show listsize" "Number of source lines gdb will list by default is 100..*" "show listsize (100)"
+
+if ![board_info target exists gdb_prompt] {
+ #test set prompt (FooBarBaz)
+ set newprompt "\\(FooBarBaz\\)"
+ send_gdb "set prompt (FooBarBaz) \n"
+ gdb_expect {
+ -re "$newprompt $" { pass "set prompt (FooBarBaz) " }
+ timeout { fail "(timeout) set prompt (FooBarBaz) " }
+ }
+
+ #test show prompt (FooBarBaz)
+ send_gdb "show prompt\n"
+ gdb_expect {
+ -re "Gdb's prompt is \"$newprompt \"..* $" \
+ { pass "show prompt (FooBarBaz) " }
+ timeout { fail "(timeout) show prompt (FooBarBaz) " }
+ }
+
+ #test set prompt (gdb)
+ send_gdb "set prompt (gdb) \n"
+ gdb_expect {
+ -re "$gdb_prompt $" { pass "set prompt (gdb) " }
+ timeout { fail "(timeout) set prompt (gdb) " }
+ }
+}
+
+#test set radix 11
+gdb_test "set radix 11" "Unsupported output radix ``decimal 11''; output radix unchanged..*" "set radix 11"
+#test set radix 16
+gdb_test "set radix 16" "Input and output radices now set to decimal 16, hex 10, octal 20..*" "set radix 16"
+#test show radix 16
+gdb_test "show radix" "Input and output radices set to decimal 16, hex 10, octal 20..*" "show radix (16)"
+#test set radix 10
+gdb_test "set radix" "Input and output radices now set to decimal 10, hex a, octal 12..*" "set radix 10"
+#test show radix 10
+gdb_test "show radix" "Input and output radices set to decimal 10, hex a, octal 12..*" "show radix (10)"
+#test set width 90
+gdb_test "set width 90" "" "set width 90"
+#test show width 90
+gdb_test "show width" "Number of characters gdb thinks are in a line is 90..*" "show width (90)"
+#test set write on
+# This is only supported on targets which use exec.o.
+gdb_test "set write on" "" "set write on"
+#test show write on
+# This is only supported on targets which use exec.o.
+gdb_test "show write" "Writing into executable and core files is on..*" "show write (on)"
+#test set symbol-reloading on
+gdb_test "set symbol-reloading on" "" "set symbol-reloading on"
+#test show symbol-reloading on
+gdb_test "show symbol-reloading" "Dynamic symbol table reloading multiple times in one run is on..*" "show symbol-reloading (on)"
+#test show user
+gdb_test "show user" "" "show user"
+#test set verbose on
+gdb_test "set verbose on" "" "set verbose on"
+#test show verbose on
+gdb_test "show verbose" "Verbose printing of informational messages is on..*" "show verbose (on)"
+#test set verbose off
+gdb_test "set verbose off" "" "set verbose off"
+#test show verbose off
+gdb_test "show verbose" "Verbosity is off..*" "show verbose (off)"
diff --git a/gdb/testsuite/gdb.base/setvar.c b/gdb/testsuite/gdb.base/setvar.c
new file mode 100644
index 00000000000..969de0d5e71
--- /dev/null
+++ b/gdb/testsuite/gdb.base/setvar.c
@@ -0,0 +1,278 @@
+#include <stdlib.h>
+
+#ifdef PROTOTYPES
+int main (int argc, char **argv, char **envp)
+#else
+main (argc, argv, envp)
+ int argc;
+ char **argv;
+ char **envp;
+#endif
+{
+ extern void dummy();
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ dummy();
+ return 0;
+}
+
+/* We put main() right up front so its line number doesn't keep changing. */
+
+/*
+ * Test file with lots of different types, for testing the
+ * "whatis" command.
+ */
+
+/*
+ * First the basic C types.
+ */
+
+#if !defined (__STDC__) && !defined (_AIX)
+#define signed /**/
+#endif
+
+char v_char;
+signed char v_signed_char;
+unsigned char v_unsigned_char;
+
+short v_short;
+signed short v_signed_short;
+unsigned short v_unsigned_short;
+
+int v_int;
+signed int v_signed_int;
+unsigned int v_unsigned_int;
+
+long v_long;
+signed long v_signed_long;
+unsigned long v_unsigned_long;
+
+float v_float;
+double v_double;
+
+/*
+ * Now some derived types, which are arrays, functions-returning,
+ * pointers, structures, unions, and enumerations.
+ */
+
+/**** arrays *******/
+
+char v_char_array[2];
+signed char v_signed_char_array[2];
+unsigned char v_unsigned_char_array[2];
+
+short v_short_array[2];
+signed short v_signed_short_array[2];
+unsigned short v_unsigned_short_array[2];
+
+int v_int_array[2];
+signed int v_signed_int_array[2];
+unsigned int v_unsigned_int_array[2];
+
+long v_long_array[2];
+signed long v_signed_long_array[2];
+unsigned long v_unsigned_long_array[2];
+
+float v_float_array[2];
+double v_double_array[2];
+
+/**** pointers *******/
+
+char *v_char_pointer;
+signed char *v_signed_char_pointer;
+unsigned char *v_unsigned_char_pointer;
+
+short *v_short_pointer;
+signed short *v_signed_short_pointer;
+unsigned short *v_unsigned_short_pointer;
+
+int *v_int_pointer;
+signed int *v_signed_int_pointer;
+unsigned int *v_unsigned_int_pointer;
+
+long *v_long_pointer;
+signed long *v_signed_long_pointer;
+unsigned long *v_unsigned_long_pointer;
+
+float *v_float_pointer;
+double *v_double_pointer;
+
+/**** structs *******/
+
+struct t_struct {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_struct1;
+
+struct {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_struct2;
+
+/**** unions *******/
+
+union t_union {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_union;
+
+union {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_union2;
+
+/*** Functions returning type ********/
+
+char v_char_func () { return(0); }
+signed char v_signed_char_func () { return (0); }
+unsigned char v_unsigned_char_func () { return (0); }
+
+short v_short_func () { return (0); }
+signed short v_signed_short_func () { return (0); }
+unsigned short v_unsigned_short_func () { return (0); }
+
+int v_int_func () { return (0); }
+signed int v_signed_int_func () { return (0); }
+unsigned int v_unsigned_int_func () { return (0); }
+
+long v_long_func () { return (0); }
+signed long v_signed_long_func () { return (0); }
+unsigned long v_unsigned_long_func () { return (0); }
+
+float v_float_func () { return (0.0); }
+double v_double_func () { return (0.0); }
+
+/**** Some misc more complicated things *******/
+
+struct link {
+ struct link *next;
+#ifdef __STDC__
+ struct link *(*linkfunc) (struct link *this, int flags);
+#else
+ struct link *(*linkfunc) ();
+#endif
+ struct t_struct stuff[1][2][3];
+} *s_link;
+
+union tu_link {
+ struct link *next;
+#ifdef __STDC__
+ struct link *(*linkfunc) (struct link *this, int flags);
+#else
+ struct link *(*linkfunc) ();
+#endif
+ struct t_struct stuff[1][2][3];
+} u_link;
+
+/**** Enumerations *******/
+
+enum colors {red, green, blue} color;
+enum cars {chevy, ford, porsche} clunker;
+
+/**** Enumeration bitfields, supported by GNU C *******/
+
+#ifdef __GNUC__
+enum senum {sm1 = -1, s1 = 1};
+struct senum_field {enum senum field:2; } sef;
+enum uenum {u1 = 1, u2 = 2};
+struct uenum_field {enum uenum field:2; } uef;
+#endif
+
+void
+dummy ()
+{
+ /* setvar.exp wants to allocate memory for constants. So make sure malloc
+ gets linked into the program. */
+ malloc (1);
+
+ /* Some linkers (e.g. on AIX) remove unreferenced variables,
+ so make sure to reference them. */
+ v_char = 0;
+ v_signed_char = 1;
+ v_unsigned_char = 2;
+
+ v_short = 3;
+ v_signed_short = 4;
+ v_unsigned_short = 5;
+
+ v_int = 6;
+ v_signed_int = 7;
+ v_unsigned_int = 8;
+
+ v_long = 9;
+ v_signed_long = 10;
+ v_unsigned_long = 11;
+
+ v_float = 100.0;
+ v_double = 200.0;
+
+
+ v_char_array[0] = v_char;
+ v_signed_char_array[0] = v_signed_char;
+ v_unsigned_char_array[0] = v_unsigned_char;
+
+ v_short_array[0] = v_short;
+ v_signed_short_array[0] = v_signed_short;
+ v_unsigned_short_array[0] = v_unsigned_short;
+
+ v_int_array[0] = v_int;
+ v_signed_int_array[0] = v_signed_int;
+ v_unsigned_int_array[0] = v_unsigned_int;
+
+ v_long_array[0] = v_long;
+ v_signed_long_array[0] = v_signed_long;
+ v_unsigned_long_array[0] = v_unsigned_long;
+
+ v_float_array[0] = v_float;
+ v_double_array[0] = v_double;
+
+ v_char_pointer = &v_char;
+ v_signed_char_pointer = &v_signed_char;
+ v_unsigned_char_pointer = &v_unsigned_char;
+
+ v_short_pointer = &v_short;
+ v_signed_short_pointer = &v_signed_short;
+ v_unsigned_short_pointer = &v_unsigned_short;
+
+ v_int_pointer = &v_int;
+ v_signed_int_pointer = &v_signed_int;
+ v_unsigned_int_pointer = &v_unsigned_int;
+
+ v_long_pointer = &v_long;
+ v_signed_long_pointer = &v_signed_long;
+ v_unsigned_long_pointer = &v_unsigned_long;
+
+ v_float_pointer = &v_float;
+ v_double_pointer = &v_double;
+
+ color = red;
+ clunker = porsche;
+
+ u_link.next = s_link;
+
+ v_struct2.v_int_member = v_struct1.v_int_member;
+ v_union2.v_short_member = v_union.v_short_member;
+
+#ifdef __GNUC__
+ sef.field = s1;
+ uef.field = u1;
+#endif
+}
diff --git a/gdb/testsuite/gdb.base/setvar.exp b/gdb/testsuite/gdb.base/setvar.exp
new file mode 100644
index 00000000000..e14ed5d948e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/setvar.exp
@@ -0,0 +1,434 @@
+# Copyright 1997, 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Copyright (C) 1988, 1990, 1991, 1992, 1994, 1995
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "setvar"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+#
+# set it up at a breakpoint so we canplay with the variable values
+#
+send_gdb "set print sevenbit-strings\n" ; gdb_expect -re "$gdb_prompt $"
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+# Determine expected output for unsigned long variables,
+# the output varies with sizeof (unsigned long).
+
+set ulong_minus_1 4294967295
+set ulong_minus_456 4294966840
+send_gdb "print sizeof (unsigned long)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 4.*$gdb_prompt $" {}
+ -re ".\[0-9\]* = 8.*$gdb_prompt $" {
+ set ulong_minus_1 18446744073709551615
+ set ulong_minus_456 18446744073709551160
+ }
+ -re ".*$gdb_prompt $" {
+ fail "getting sizeof unsigned long"
+ }
+ default { fail "(timeout) getting sizeof unsigned long" }
+}
+
+proc test_set { args } {
+ global gdb_prompt
+
+ set length [expr [llength $args] - 1];
+ set message "[lindex $args $length]";
+ set final [expr $length - 2];
+ set count 1;
+
+ # Set up the variables.
+ for {set x 0;} {$x < $length} {incr x;} {
+ if { "[lindex $args $x]" != "" } {
+ set arg [lindex $args $x];
+ if { ($x == $final) || ([string first ".*" [lindex $args [expr $x + 1]]] >= 0) } {
+ set match [lindex $args [expr $x + 1]];
+ if { $count == 1 } {
+ set mess "$message"
+ } else {
+ set mess "$message (#$count)";
+ }
+ incr count;
+ incr x;
+ } else {
+ set mess "";
+ set match ""
+ }
+ verbose "doing $arg $match"
+ if [gdb_test "$arg" "$match" "$mess"] {
+ fail "$message -- $match";
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+#
+# test "set variable" for type "char"
+#
+# Because bare char types can be either signed or unsigned, we just test the
+# range of values that are common to both (0-127).
+#
+
+test_set "set variable v_char=0" "print v_char" ".\[0-9\]* = 0 \'.0\'" "set variable char=0"
+test_set "set variable v_char=1" "print v_char" ".\[0-9\]* = 1 \'.001\'" "set variable char=1"
+test_set "set variable v_char=27" "print v_char" ".\[0-9\]* = 27 \'.e\'" "set variable char=27 (Esc)"
+test_set "set variable v_char=32" "print v_char" ".\[0-9\]* = 32 \' \'" "set variable char=32 (SPC)"
+test_set "set variable v_char=65" "print v_char" ".\[0-9\]* = 65 \'A\'" "set variable char=65 ('A')"
+test_set "set variable v_char=97" "print v_char" ".\[0-9\]* = 97 \'a\'" "set variable char=97 ('a')"
+test_set "set variable v_char=126" "print v_char" ".\[0-9\]* = 126 \'~\'" "set variable char=126 ('~')"
+test_set "set variable v_char=127" "print v_char" ".\[0-9\]* = 127 \'.177\'" "set variable char=127 (8-bit)"
+#
+# test "set variable" for type "signed char"
+#
+test_set "set variable v_char=0" "print v_signed_char" ".\[0-9\]* = 0 \'.0\'" "set variable signed char=0"
+test_set "set variable v_signed_char=1" "print v_signed_char" ".\[0-9\]* = 1 \'.001\'" "set variable signed char=1"
+test_set "set variable v_signed_char=27" "print v_signed_char" ".\[0-9\]* = 27 \'.e\'" "set variable signed char=27 (Esc)"
+test_set "set variable v_signed_char=32" "print v_signed_char" ".\[0-9\]* = 32 \' \'" "set variable signed char=32 (SPC)"
+test_set "set variable v_signed_char=65" "print v_signed_char" ".\[0-9\]* = 65 \'A\'" "set variable signed char=65 ('A')"
+test_set "set variable v_signed_char=97" "print v_signed_char" ".\[0-9\]* = 97 \'a\'" "set variable signed char=97 ('a')"
+test_set "set variable v_signed_char=126" "print v_signed_char" ".\[0-9\]* = 126 \'~\'" "set variable signed char=126 ('~')"
+test_set "set variable v_signed_char=127" "print v_signed_char" ".\[0-9\]* = 127 \'.177\'" "set variable signed char=127 (8-bit)"
+gdb_test "set variable v_signed_char=-1" ""
+if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix4*" }
+gdb_test "print v_signed_char" ".\[0-9\]* = -1 \'.377\'" \
+ "set variable signed char=-1 (-1)"
+gdb_test "set variable v_signed_char=0xFF" ""
+if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix4*" }
+gdb_test "print v_signed_char" ".\[0-9\]* = -1 \'.377\'" \
+ "set variable signed char=0xFF (0xFF)"
+#
+# test "set variable" for type "unsigned char"
+#
+test_set "set variable v_unsigned_char=0" "print v_unsigned_char" ".\[0-9\]* = 0 \'.0\'" "set variable unsigned char=0"
+test_set "set variable v_unsigned_char=1" "print v_unsigned_char" ".\[0-9\]* = 1 \'.001\'" "set variable unsigned char=1"
+test_set "set variable v_unsigned_char=27" "print v_unsigned_char" ".\[0-9\]* = 27 \'.e\'" "set variable unsigned char=27 (Esc)"
+test_set "set variable v_unsigned_char=32" "print v_unsigned_char" ".\[0-9\]* = 32 \' \'" "set variable unsigned char=32 (SPC)"
+test_set "set variable v_unsigned_char=65" "print v_unsigned_char" ".\[0-9\]* = 65 \'A\'" "set variable unsigned char=65 ('A')"
+test_set "set variable v_unsigned_char=97" "print v_unsigned_char" ".\[0-9\]* = 97 \'a\'" "set variable unsigned char=97 ('a')"
+test_set "set variable v_unsigned_char=126" "print v_unsigned_char" ".\[0-9\]* = 126 \'~\'" "set variable unsigned char=126 ('~')"
+test_set "set variable v_unsigned_char=~0" "print v_unsigned_char" ".\[0-9\]* = 255 \'.377\'" "set variable unsigned char=255 (8-bit)"
+#
+# test "set variable" for type "short"
+#
+test_set "set variable v_short=0" "print v_short" ".\[0-9\]* = 0" "set variable short=0"
+test_set "set variable v_short=1" "print v_short" ".\[0-9\]* = 1" "set variable short=1"
+test_set "set variable v_short=-1" "print v_short" ".\[0-9\]* = -1" "set variable short=-1 (minus)"
+#
+# test "set variable" for type "signed short"
+#
+test_set "set variable v_signed_short=0" "print v_signed_short" ".\[0-9\]* = 0" "set variable signed short=0"
+test_set "set variable v_signed_short=1" "print v_signed_short" ".\[0-9\]* = 1" "set variable signed short=1"
+test_set "set variable v_signed_short=-1" "print v_signed_short" ".\[0-9\]* = -1" "set variable signed short=-1 (minus)"
+#
+# test "set variable" for type "unsigned short"
+#
+test_set "set variable v_unsigned_short=0" "print v_unsigned_short" ".\[0-9\]* = 0" "set variable unsigned short=0"
+test_set "set variable v_unsigned_short=1" "print v_unsigned_short" ".\[0-9\]* = 1" "set variable unsigned short=1"
+test_set "set variable v_unsigned_short=~0" "print v_unsigned_short" ".\[0-9\]* = 65535" "set variable unsigned short=~0 (minus)"
+#
+# test "set variable" for type "int"
+#
+test_set "set variable v_int=0" "print v_int" ".\[0-9\]* = 0" "set variable int=0"
+test_set "set variable v_int=1" "print v_int" ".\[0-9\]* = 1" "set variable int=1"
+test_set "set variable v_int=-1" "print v_int" ".\[0-9\]* = -1" "set variable int=-1 (minus)"
+#
+# test "set variable" for type "signed int"
+#
+test_set "set variable v_signed_int=0" "print v_signed_int" ".\[0-9\]* = 0" "set variable signed int=0"
+test_set "set variable v_signed_int=1" "print v_signed_int" ".\[0-9\]* = 1" "set variable signed int=1"
+test_set "set variable v_signed_int=-1" "print v_signed_int" ".\[0-9\]* = -1" "set variable signed int=-1 (minus)"
+#
+# test "set variable" for type "unsigned int"
+#
+test_set "set variable v_unsigned_int=0" "print v_unsigned_int" ".\[0-9\]* = 0" "set variable unsigned int=0"
+test_set "set variable v_unsigned_int=1" "print v_unsigned_int" ".\[0-9\]* = 1" "set variable unsigned int=1"
+test_set "set variable v_unsigned_int=~0" "print v_unsigned_int" ".\[0-9\]* = (4294967295|65535)" "set variable unsigned int=~0 (minus)"
+#test_set ".\[0-9\]* = 65535" "set variable unsigned int=~0 (minus)"
+#
+# test "set variable" for type "long"
+#
+test_set "set variable v_long=0" "print v_long" ".\[0-9\]* = 0" "set variable long=0"
+test_set "set variable v_long=1" "print v_long" ".\[0-9\]* = 1" "set variable long=1"
+test_set "set variable v_long=-1" "print v_long" ".\[0-9\]* = -1" "set variable long=-1 (minus)"
+#
+# test "set variable" for type "signed long"
+#
+test_set "set variable v_signed_long=0" "print v_signed_long" ".\[0-9\]* = 0" "set variable signed long=0"
+test_set "set variable v_signed_long=1" "print v_signed_long" ".\[0-9\]* = 1" "set variable signed long=1"
+test_set "set variable v_signed_long=-1" "print v_signed_long" ".\[0-9\]* = -1" "set variable signed long=-1 (minus)"
+#
+# test "set variable" for type "unsigned long"
+#
+test_set "set variable v_unsigned_long=0" "print v_unsigned_long" ".\[0-9\]* = 0" "set variable unsigned long=0"
+test_set "set variable v_unsigned_long=1" "print v_unsigned_long" ".\[0-9\]* = 1" "set variable unsigned long=1"
+test_set "set variable v_unsigned_long=~0" "print v_unsigned_long" ".\[0-9\]* = $ulong_minus_1" "set variable unsigned long=~0 (minus)"
+#
+# test "set variable" for type "float"
+#
+test_set "set variable v_float=0.0" "print v_float" ".\[0-9\]* = 0" "set variable float=0"
+test_set "set variable v_float=1.0" "print v_float" ".\[0-9\]* = 1" "set variable float=1"
+test_set "set variable v_float=-1.0" "print v_float" ".\[0-9\]* = -1" "set variable float=-1 (minus)"
+#
+# test "set variable" for type "double"
+#
+test_set "set variable v_double=0.0" "print v_double" ".\[0-9\]* = 0" "set variable double=0"
+test_set "set variable v_double=1.0" "print v_double" ".\[0-9\]* = 1" "set variable double=1"
+test_set "set variable v_double=-1.0" "print v_double" ".*.\[0-9\]* = -1" "set variable double=-1 (minus)"
+#
+# test "set variable" for "char array[2]"
+#
+test_set "set variable v_char_array\[0\]='h'" "set variable v_char_array\[1\]='i'" "print v_char_array" ".*.\[0-9\]* =.*\"hi\"" "set variable char array=\"hi\" (string)"
+#
+# test "set variable" for "signed char array[2]"
+#
+test_set "set variable v_signed_char_array\[0\]='h'" "set variable v_signed_char_array\[1\]='i'" "print v_signed_char_array" ".*.\[0-9\]* =.*\"hi\"" "set variable signed char array=\"hi\" (string)"
+#
+# test "set variable" for "unsigned char array[2]"
+#
+test_set "set variable v_unsigned_char_array\[0\]='h'" "set variable v_unsigned_char_array\[1\]='i'" "print v_unsigned_char_array" ".*.\[0-9\]* =.*\"hi\"" "set variable unsigned char array=\"hi\" (string)"
+#
+# test "set variable" for "short array[2]"
+#
+test_set "set variable v_short_array\[0\]=123" "set variable v_short_array\[1\]=-456" "print v_short_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "set variable short array"
+#
+# test "set variable" for "signed short array[2]"
+#
+test_set "set variable v_signed_short_array\[0\]=123" "set variable v_signed_short_array\[1\]=-456" "print v_signed_short_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "set variable signed short array"
+#
+# test "set variable" for "unsigned short array[2]"
+#
+test_set "set variable v_unsigned_short_array\[0\]=123" "set variable v_unsigned_short_array\[1\]=-456" "print v_unsigned_short_array" ".*.\[0-9\]* =.*\\{123,.*65080\\}" "set variable unsigned short array"
+#
+# test "set variable" for "int array[2]"
+#
+test_set "set variable v_int_array\[0\]=123" "set variable v_int_array\[1\]=-456" "print v_int_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "set variable int array"
+#
+# test "set variable" for "signed int array[2]"
+#
+test_set "set variable v_signed_int_array\[0\]=123" "set variable v_signed_int_array\[1\]=-456" "print v_signed_int_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "set variable signed int array"
+#
+# test "set variable" for "unsigned int array[2]"
+#
+test_set "set variable v_unsigned_int_array\[0\]=123" "set variable v_unsigned_int_array\[1\]=-456" "print v_unsigned_int_array" ".*.\[0-9\]* =.*\\{123,.*(4294966840|65080)\\}" "set variable unsigned int array"
+#
+# test "set variable" for "long array[2]"
+#
+test_set "set variable v_long_array\[0\]=123" "set variable v_long_array\[1\]=-456" "print v_long_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "set variable long array"
+#
+# test "set variable" for "signed long array[2]"
+#
+test_set "set variable v_signed_long_array\[0\]=123" "set variable v_signed_long_array\[1\]=-456" "print v_signed_long_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "set variable signed long array"
+#
+# test "set variable" for "unsigned long array[2]"
+#
+test_set "set variable v_unsigned_long_array\[0\]=123" "set variable v_unsigned_long_array\[1\]=-456" "print v_unsigned_long_array" ".*.\[0-9\]* =.*\\{123,.*$ulong_minus_456\\}" "set variable unsigned long array"
+#
+# test "set variable" for "float array[2]"
+#
+test_set "set variable v_float_array\[0\]=123.0" "set variable v_float_array\[1\]=-456.0" "print v_float_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "set variable float array"
+#
+# test "set variable" for "double array[2]"
+#
+test_set "set variable v_double_array\[0\]=123.0" "set variable v_double_array\[1\]=-456.0" "print v_double_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "set variable double array"
+#
+# test "set variable" for type "char *"
+#
+test_set "set v_char_pointer=v_char_array" "set variable *(v_char_pointer)='h'" "set variable *(v_char_pointer+1)='i'" "print v_char_array" ".*.\[0-9\]* =.*\"hi\"" "print *(v_char_pointer+1)" ".*.\[0-9\]* = 105 \'i\'" "set variable char pointer=\"hi\" (string)"
+#
+# test "set variable" for type "signed char *"
+#
+test_set "set v_signed_char_pointer=v_signed_char_array" "set variable *(v_signed_char_pointer)='h'" "set variable *(v_signed_char_pointer+1)='i'" "print v_signed_char_array" ".*.\[0-9\]* =.*\"hi\"" "print *(v_signed_char_pointer+1)" ".*.\[0-9\]* = 105 \'i\'" "set variable signed char pointer=\"hi\" (string)"
+#
+# test "set variable" for type "unsigned char *"
+#
+test_set "set v_unsigned_char_pointer=v_unsigned_char_array" "set variable *(v_unsigned_char_pointer)='h'" "set variable *(v_unsigned_char_pointer+1)='i'" "print v_unsigned_char_array" ".*.\[0-9\]* =.*\"hi\"" "print *(v_unsigned_char_pointer+1)" ".*.\[0-9\]* = 105 \'i\'" "set variable unsigned char pointer=\"hi\" (string)"
+#
+# test "set variable" for type "short *"
+#
+test_set "set v_short_pointer=v_short_array" "set variable *(v_short_pointer)=123" "set variable *(v_short_pointer+1)=-456" "print v_short_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "print *(v_short_pointer+1)" ".*.\[0-9\]* = -456" "set variable short pointer"
+#
+# test "set variable" for type "signed short *"
+#
+gdb_test "set v_signed_short_pointer=v_signed_short_array" ""
+gdb_test "set variable *(v_signed_short_pointer)=123" ""
+gdb_test "set variable *(v_signed_short_pointer+1)=-456" ""
+gdb_test "print v_signed_short_array" ".\[0-9\]* =.*\\{123,.*-456\\}" \
+ "set variable signed short pointer"
+gdb_test "print *(v_signed_short_pointer+1)" ".\[0-9\]*.*=.*-456"
+#
+# test "set variable" for type "unsigned short *"
+#
+gdb_test "set v_unsigned_short_pointer=v_unsigned_short_array" ""
+gdb_test "set variable *(v_unsigned_short_pointer)=123" ""
+gdb_test "set variable *(v_unsigned_short_pointer+1)=-456" ""
+# DTS 10060CLLbs - bad type info from cc
+if {$hp_cc_compiler} {setup_xfail hppa*-*-*11* 10060CLLbs}
+gdb_test "print v_unsigned_short_array" ".\[0-9\]* =.*\\{123,.*65080\\}" \
+ "set variable unsigned short pointer"
+# DTS 10060CLLbs - bad type info from cc
+if {$hp_cc_compiler} {setup_xfail hppa*-*-*11* 10060CLLbs}
+gdb_test "print *(v_unsigned_short_pointer+1)" ".\[0-9\]* = 65080"
+#
+# test "set variable" for type "int *"
+#
+test_set "set v_int_pointer=v_int_array" "set variable *(v_int_pointer)=123" "set variable *(v_int_pointer+1)=-456" "print v_int_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "print *(v_int_pointer+1)" ".*.\[0-9\]* = -456" "set variable int pointer"
+#
+# test "set variable" for type "signed int *"
+#
+test_set "set v_signed_int_pointer=v_signed_int_array" "set variable *(v_signed_int_pointer)=123" "set variable *(v_signed_int_pointer+1)=-456" "print v_signed_int_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "print *(v_signed_int_pointer+1)" ".*.\[0-9\]* = -456" "set variable signed int pointer"
+#
+# test "set variable" for type "unsigned int *"
+#
+test_set "set v_unsigned_int_pointer=v_unsigned_int_array" "set variable *(v_unsigned_int_pointer)=123" "set variable *(v_unsigned_int_pointer+1)=-456" "print v_unsigned_int_array" ".*.\[0-9\]* =.*\\{123,.*(4294966840|65080)\\}" "set variable unsigned int pointer"
+test_set "" "print *(v_unsigned_int_pointer+1)" ".*.\[0-9\]* = (4294966840|65080)" "print variable unsigned int pointer+1"
+#
+# test "set variable" for type "long *"
+#
+test_set "set v_long_pointer=v_long_array" "set variable *(v_long_pointer)=123" "set variable *(v_long_pointer+1)=-456" "print v_long_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "print *(v_long_pointer+1)" ".*.\[0-9\]* = -456" "set variable long pointer"
+#
+# test "set variable" for type "signed long *"
+#
+test_set "set v_signed_long_pointer=v_signed_long_array" "set variable *(v_signed_long_pointer)=123" "set variable *(v_signed_long_pointer+1)=-456" "print v_signed_long_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "print *(v_signed_long_pointer+1)" ".*.\[0-9\]* = -456" "set variable signed long pointer"
+#
+# test "set variable" for type "unsigned long *"
+#
+test_set "set v_unsigned_long_pointer=v_unsigned_long_array" "set variable *(v_unsigned_long_pointer)=123" "set variable *(v_unsigned_long_pointer+1)=-456" "print v_unsigned_long_array" ".*.\[0-9\]* =.*\\{123,.*$ulong_minus_456\\}" "print *(v_unsigned_long_pointer+1)" ".*.\[0-9\]* = $ulong_minus_456" "set variable unsigned long pointer"
+#
+# test "set variable" for type "float *"
+#
+test_set "set v_float_pointer=v_float_array" "set variable *(v_float_pointer)=123.0" "set variable *(v_float_pointer+1)=-456.0" "print v_float_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "print *(v_float_pointer+1)" ".*.\[0-9\]* = -456" "set variable float pointer"
+#
+# test "set variable" for type "double *"
+#
+test_set "set v_double_pointer=v_double_array" "set variable *(v_double_pointer)=123.0" "set variable *(v_double_pointer+1)=-456.0" "print v_double_array" ".*.\[0-9\]* =.*\\{123,.*-456\\}" "print *(v_double_pointer+1)" ".*.\[0-9\]* = -456" "set variable double pointer"
+#
+# test "set variable" for struct members
+#
+test_set "set variable v_struct1.v_char_member='h'" "print v_struct1.v_char_member" ".*.\[0-9\]* = 104 \'h\'" "set variable structure char member"
+test_set "set variable v_struct1.v_short_member=1" "print v_struct1.v_short_member" ".*.\[0-9\]* = 1" "set variable structure short member"
+test_set "set variable v_struct1.v_int_member=2" "print v_struct1.v_int_member" ".*.\[0-9\]* = 2" "set variable structure int member"
+test_set "set variable v_struct1.v_long_member=3" "print v_struct1.v_long_member" ".*.\[0-9\]* = 3" "set variable structure long member"
+test_set "set variable v_struct1.v_float_member=4.0" "print v_struct1.v_float_member" ".*.\[0-9\]* = 4" "set variable structure float member"
+test_set "set variable v_struct1.v_double_member=5.0" "print v_struct1.v_double_member" ".*.\[0-9\]* = 5" "set variable structure double member"
+
+gdb_test "print v_struct1" \
+ ".*.\[0-9\]* = \{.*v_char_member = 104 \'h\',.*v_short_member = 1,\
+.*v_int_member = 2,.*\
+v_long_member = 3,.*v_float_member = 4,.*v_double_member = 5.*\}" \
+ "set print structure #1"
+
+# Some believe that the following should be an error. GCC extensions for
+# structure constants require the type of the structure to be specified, as in
+# v_struct1 = (struct t_struct) {32, 33, 34, 35, 36, 37}
+# The argument is that GDB should do the same if it wants to provide this
+# feature, i.e., require the cast.
+# We decided that we don't want the debugger to be as picky as a
+# compiler and make us type complex casts.
+
+# We need to up this because this can be really slow on some boards.
+# (malloc() is called as part of the test).
+set timeout 60;
+
+# Change the values
+test_set "set variable v_struct1 = {32, 33, 34, 35, 36, 37}" \
+ "print v_struct1" \
+ ".*.\[0-9\]* = \\{.*v_char_member = 32 \' \',.*v_short_member = 33,\
+.*v_int_member = 34,.*\
+v_long_member = 35,.*v_float_member = 36,.*v_double_member = 37.*\\}" \
+ "set print structure #2"
+
+# Change them back
+test_set "set variable v_struct1 = {'h', 1, 2, 3, 4.0, 5.0}" \
+ "print v_struct1" \
+ ".*.\[0-9\]* = \\{.*v_char_member = 104 \'h\',.*v_short_member = 1,\
+.*v_int_member = 2,.*\
+v_long_member = 3,.*v_float_member = 4,.*v_double_member = 5.*\\}" \
+ "set print structure #3"
+
+# Test printing of enumeration bitfields.
+# GNU C supports them, some other compilers don't.
+
+if {$gcc_compiled} then {
+ gdb_test "print sef.field=sm1" ".*.\[0-9\]* = sm1"
+ gdb_test "print sef.field" ".*.\[0-9\]* = sm1" "print sef.field (sm1)"
+ gdb_test "print sef.field=s1" ".*.\[0-9\]* = s1"
+ gdb_test "print sef.field" ".*.\[0-9\]* = s1" "print sef.field (s1)"
+ gdb_test "print uef.field=u2" ".*.\[0-9\]* = u2"
+ gdb_test "print uef.field" ".*.\[0-9\]* = u2" "print uef.field (u2)"
+ gdb_test "print uef.field=u1" ".*.\[0-9\]* = u1"
+ gdb_test "print uef.field" ".*.\[0-9\]* = u1" "print uef.field (u1)"
+
+ # Test for truncation when assigning invalid values to bitfields.
+ gdb_test "print sef.field=7" \
+ ".*warning: Value does not fit in 2 bits.*\[0-9\]* = sm1"
+ gdb_test "print uef.field=6" \
+ ".*warning: Value does not fit in 2 bits.*\[0-9\]* = u2"
+}
diff --git a/gdb/testsuite/gdb.base/shlib-call.exp b/gdb/testsuite/gdb.base/shlib-call.exp
new file mode 100644
index 00000000000..47919be4c03
--- /dev/null
+++ b/gdb/testsuite/gdb.base/shlib-call.exp
@@ -0,0 +1,296 @@
+# Copyright 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# file to test calls into shared libraries
+# the source files for this test are:
+#
+# shmain.c
+# shr1.c (shared lib)
+# shr2.c (shared lib)
+# ss.h (header for shr2.c)
+#
+# file written by Elena Zannoni: elz@ch.apollo.com
+#
+
+#debug shmain
+#prop lib shr1.sl
+#prop lib shr2.sl
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# are we on a target board?
+if ![isnative] then {
+ return 0
+}
+
+set testfile "shmain"
+set libfile "shr"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# build the first test case
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}.o" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+# Build the shared libraries this test case needs.
+#
+
+if {$gcc_compiled == 0} {
+ if [istarget "hppa*-hp-hpux*"] then {
+ set additional_flags "additional_flags=+z"
+ } else {
+ # don't know what the compiler is...
+ set additional_flags ""
+ }
+} else {
+ if { ([istarget "powerpc*-*-aix*"]
+ || [istarget "rs6000*-*-aix*"]) } {
+ set additional_flags ""
+ } else {
+ set additional_flags "additional_flags=-fpic"
+ }
+}
+
+if {[gdb_compile "${srcdir}/${subdir}/${libfile}1.c" "${objdir}/${subdir}/${libfile}1.o" object [list debug $additional_flags]] != ""} {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if {[gdb_compile "${srcdir}/${subdir}/${libfile}2.c" "${objdir}/${subdir}/${libfile}2.o" object [list debug $additional_flags]] != ""} {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [istarget "hppa*-*-hpux*"] {
+ remote_exec build "ld -b ${objdir}/${subdir}/${libfile}1.o -o ${objdir}/${subdir}/${libfile}1.sl"
+ remote_exec build "ld -b ${objdir}/${subdir}/${libfile}2.o -o ${objdir}/${subdir}/${libfile}2.sl"
+} else {
+ set additional_flags "additional_flags=-shared"
+ if {[gdb_compile "${objdir}/${subdir}/${libfile}1.o" "${objdir}/${subdir}/${libfile}1.sl" executable [list debug $additional_flags]] != ""} {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ if {[gdb_compile "${objdir}/${subdir}/${libfile}2.o" "${objdir}/${subdir}/${libfile}2.sl" executable [list debug $additional_flags]] != ""} {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+}
+
+if { ($gcc_compiled
+ && ([istarget "powerpc*-*-aix*"]
+ || [istarget "rs6000*-*-aix*"] )) } {
+ set additional_flags "additional_flags=-L${objdir}/${subdir}"
+} else {
+ set additional_flags ""
+}
+if {[gdb_compile "${objdir}/${subdir}/${testfile}.o ${objdir}/${subdir}/${libfile}1.sl ${objdir}/${subdir}/${libfile}2.sl" "${binfile}" executable [list debug $additional_flags]] != ""} {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+send_gdb "set print sevenbit-strings\n" ; gdb_expect -re "$gdb_prompt $"
+send_gdb "set print address off\n" ; gdb_expect -re "$gdb_prompt $"
+send_gdb "set width 0\n" ; gdb_expect -re "$gdb_prompt $"
+
+
+if ![runto_main] then {
+ perror "C function calling tests suppressed"
+}
+
+
+#step -over
+
+ send_gdb "next\n"
+ gdb_expect {
+ -re ".*g = shr1\\(g\\).*$gdb_prompt $" {pass "next to shr1"}
+ -re ".*$gdb_prompt $" { fail "next to shr1" }
+ timeout { fail "next to shr1 (timeout)" }
+ }
+
+
+
+#print g
+
+send_gdb "print g\n"
+gdb_expect {
+ -re ".*\[0-9\]* = 1.*$gdb_prompt $" {
+ pass "print g"
+ }
+ -re ".*$gdb_prompt $" { fail "print g" }
+ timeout { fail "(timeout) print g" }
+ }
+
+
+#step -over
+ if ![gdb_skip_stdio_test "next over shr1"] {
+ send_gdb "next\n"
+ gdb_expect {
+ -re ".*address of sgs is $hex.*g = shr2\\(g\\).*$gdb_prompt $" {
+ pass "next over shr1"
+ }
+ -re ".*$gdb_prompt $" { fail "next over shr1" }
+ timeout { fail "next over shr1 (timeout)" }
+ }
+ } else {
+ gdb_test "next" "" ""
+ }
+
+
+#print g
+send_gdb "print g\n"
+gdb_expect {
+ -re ".*\[0-9\]* = 2.*$gdb_prompt $" {
+ pass "print g" }
+ -re ".*$gdb_prompt $" { fail "print g" }
+ timeout { fail "(timeout) print g" }
+ }
+
+#print shr1(1)
+ if ![gdb_skip_stdio_test "print shr1(1)"] {
+ send_gdb "print shr1(1)\n"
+ gdb_expect {
+ -re ".*address of sgs is $hex.*\[0-9\]* = 2.*$gdb_prompt $" {
+ pass "print shr1(1)"
+ }
+ -re ".*$gdb_prompt $" { fail "print shr1(1)" }
+ timeout { fail "(timeout) print shr1(1)" }
+ }
+ }
+
+#print shr1(g)
+ if ![gdb_skip_stdio_test "print shr1(g)"] {
+ send_gdb "print shr1(g)\n"
+ gdb_expect {
+ -re ".*address of sgs is $hex.*\[0-9\]* = 4.*$gdb_prompt $" {
+ pass "print shr1(g)"
+ }
+ -re ".*$gdb_prompt $" { fail "print shr1(g)" }
+ timeout { fail "(timeout) print shr1(g)" }
+ }
+ }
+
+#break shr2
+#go
+gdb_test "break shr2" \
+ "Breakpoint.*file.*shr2.c, line.*" \
+ "breakpoint function shr2"
+
+gdb_test "continue" \
+ "Continuing\\..*Breakpoint \[0-9\]+, shr2 \\(.*\\) at.*shr2\\.c:7.*7.*return 2.x;" \
+ "run until breakpoint set at a function"
+
+
+#print shr1(1)
+if ![gdb_skip_stdio_test "print shr1(1) 2nd time"] {
+ send_gdb "print shr1(1)\n"
+ gdb_expect {
+ -re ".*address of sgs is $hex.*\[0-9\]* = 2.*$gdb_prompt $" {
+ pass "print shr1(1) 2nd time"
+ }
+ -re ".*$gdb_prompt $" { fail "print shr1(1) 2nd time" }
+ timeout { fail "(timeout) print shr1(1) 2nd time" }
+ }
+}
+
+#print mainshr1(1)
+send_gdb "print mainshr1(1)\n"
+gdb_expect {
+ -re ".*\[0-9\]* = 2.*$gdb_prompt $" {
+ pass "print mainshr1(1) from shlib func"
+ }
+ -re ".*$gdb_prompt $" { fail "print mainshr1(1) from shlib func" }
+ timeout { fail "(timeout) print mainshr1(1) from shlib func" }
+ }
+
+#step -return
+ send_gdb "step\n"
+ gdb_expect {
+ -re ".*\\\}.*$gdb_prompt $" { pass "step inside shr2 (shlib func)"}
+ -re ".*$gdb_prompt $" { fail "step inside shr2 (shlib func)" }
+ timeout { fail "step inside shr2 (shlib func) (timeout)" }
+ }
+
+ send_gdb "step\n"
+ gdb_expect {
+ -re "main \\(\\) at.*g = mainshr1\\(g\\);.*$gdb_prompt $" { pass "step out of shr2 to main"}
+ -re ".*$gdb_prompt $" { fail "step out of shr2 to main" }
+ timeout { fail "step out of shr2 to main (timeout)" }
+ }
+
+#print mainshr1(1)
+send_gdb "print mainshr1(1)\n"
+gdb_expect {
+ -re ".*\[0-9\]* = 2.*$gdb_prompt $" {
+ pass "print mainshr1(1)"
+ }
+ -re ".*$gdb_prompt $" { fail "print mainshr1(1) from main" }
+ timeout { fail "(timeout) print mainshr1(1) from main" }
+ }
+
+#step
+ send_gdb "step\n"
+ gdb_expect {
+ -re ".*mainshr1 \\(g=4\\) at.*return 2.g;.*$gdb_prompt $" { pass "step into mainshr1"}
+ -re ".*$gdb_prompt $" { fail "step into mainshr1" }
+ timeout { fail "step into mainshr1 (timeout)" }
+ }
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+send_gdb "set print sevenbit-strings\n" ; gdb_expect -re "$gdb_prompt $"
+send_gdb "set print address off\n" ; gdb_expect -re "$gdb_prompt $"
+send_gdb "set width 0\n" ; gdb_expect -re "$gdb_prompt $"
+
+# PR's 16495, 18213
+# test that we can re-set breakpoints in shared libraries
+gdb_test "break shr1" "Breakpoint 1.*" "set bp in shared library"
+
+# FIXME: should not send "run" explicitly. Non-portable.
+
+if ![is_remote target] {
+ gdb_test "run" "Starting program:.*Breakpoint 1,.*" \
+ "run to bp in shared library"
+
+ gdb_test "cont" ".*Program exited normally..*"
+
+ gdb_test "run" "Starting program:.*Breakpoint 1,.*" \
+ "re-run to bp in shared library (PR's 16495, 18213)"
+
+ gdb_test "cont" ".*Program exited normally..*"
+}
+
+return 0
diff --git a/gdb/testsuite/gdb.base/shmain.c b/gdb/testsuite/gdb.base/shmain.c
new file mode 100644
index 00000000000..7013db52328
--- /dev/null
+++ b/gdb/testsuite/gdb.base/shmain.c
@@ -0,0 +1,56 @@
+/* A test */
+
+#include "ss.h"
+#include <stdio.h>
+
+extern int structarg(struct s);
+extern int pstructarg(struct s*);
+extern int shr1(int);
+extern int shr2(int);
+extern float sg;
+
+int eglob;
+
+struct {
+ int a;
+ int b;
+} s;
+
+int g;
+
+#ifdef PROTOTYPES
+int local_structarg(struct s x)
+#else
+int local_structarg(x)
+struct s x;
+#endif
+{
+ return x.b;
+}
+
+#ifdef PROTOTYPES
+int mainshr1(int g)
+#else
+int mainshr1(g)
+int g;
+#endif
+{
+ return 2*g;
+}
+
+int main()
+{
+ struct s y;
+ g = 1;
+ g = shr1(g);
+ g = shr2(g);
+ g = mainshr1(g);
+ sg = 1.1;
+ printf("address of sg is 0x%x\n", &sg);
+ y.a = 3;
+ y.b = 4;
+ g = local_structarg(y);
+ g = structarg(y);
+ g = pstructarg(&y);
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/shr1.c b/gdb/testsuite/gdb.base/shr1.c
new file mode 100644
index 00000000000..a0257e40233
--- /dev/null
+++ b/gdb/testsuite/gdb.base/shr1.c
@@ -0,0 +1,63 @@
+#include "ss.h"
+#include <stdio.h>
+
+typedef float f;
+
+float sg = 5.5;
+int sgi = 2;
+static int sgs = 7;
+
+#ifdef PROTOTYPES
+int shr1(int x)
+#else
+int shr1(x)
+int x;
+#endif
+{
+ f mumble;
+ int l;
+ l = 1;
+ {
+ int l;
+ l = 2;
+ }
+ mumble = 7.7;
+ sg = 6.6;
+ sgi++;
+ sgs = 8;
+ printf("address of sgs is 0x%x\n", &sgs);
+ return 2*x;
+}
+
+#ifdef PROTOTYPES
+static int shr1_local(int x)
+#else
+static int shr1_local(x)
+int x;
+#endif
+{
+ return 2*x;
+}
+
+#ifdef PROTOTYPES
+int structarg(struct s x)
+#else
+int structarg(x)
+struct s x;
+#endif
+{
+ return x.a;
+}
+
+#ifdef PROTOTYPES
+int pstructarg(struct s *x)
+#else
+int pstructarg(x)
+struct s *x;
+#endif
+{
+ return x->a;
+}
+
+
+
diff --git a/gdb/testsuite/gdb.base/shr2.c b/gdb/testsuite/gdb.base/shr2.c
new file mode 100644
index 00000000000..de34986d76d
--- /dev/null
+++ b/gdb/testsuite/gdb.base/shr2.c
@@ -0,0 +1,17 @@
+#ifdef PROTOTYPES
+int shr2(int x)
+#else
+int shr2(x) int x;
+#endif
+{
+ return 2*x;
+}
+
+#ifdef PROTOTYPES
+int shr2_local(int x)
+#else
+int shr2_local(x) int x;
+#endif
+{
+ return 2*x;
+}
diff --git a/gdb/testsuite/gdb.base/sigall.c b/gdb/testsuite/gdb.base/sigall.c
new file mode 100644
index 00000000000..30d06f367d3
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sigall.c
@@ -0,0 +1,1810 @@
+#include <signal.h>
+#include <unistd.h>
+
+#ifdef __sh__
+#define signal(a,b) /* Signals not supported on this target - make them go away */
+#endif
+
+/* Signal handlers, we set breakpoints in them to make sure that the
+ signals really get delivered. */
+
+#ifdef PROTOTYPES
+void
+handle_ABRT (int sig)
+#else
+void
+handle_ABRT (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_HUP (int sig)
+#else
+void
+handle_HUP (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_QUIT (int sig)
+#else
+void
+handle_QUIT (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_ILL (int sig)
+#else
+void
+handle_ILL (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_EMT (int sig)
+#else
+void
+handle_EMT (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_FPE (int sig)
+#else
+void
+handle_FPE (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_BUS (int sig)
+#else
+void
+handle_BUS (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_SEGV (int sig)
+#else
+void
+handle_SEGV (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_SYS (int sig)
+#else
+void
+handle_SYS (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_PIPE (int sig)
+#else
+void
+handle_PIPE (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_ALRM (int sig)
+#else
+void
+handle_ALRM (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_URG (int sig)
+#else
+void
+handle_URG (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_TSTP (int sig)
+#else
+void
+handle_TSTP (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_CONT (int sig)
+#else
+void
+handle_CONT (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_CHLD (int sig)
+#else
+void
+handle_CHLD (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_TTIN (int sig)
+#else
+void
+handle_TTIN (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_TTOU (int sig)
+#else
+void
+handle_TTOU (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_IO (int sig)
+#else
+void
+handle_IO (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_XCPU (int sig)
+#else
+void
+handle_XCPU (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_XFSZ (int sig)
+#else
+void
+handle_XFSZ (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_VTALRM (int sig)
+#else
+void
+handle_VTALRM (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_PROF (int sig)
+#else
+void
+handle_PROF (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_WINCH (int sig)
+#else
+void
+handle_WINCH (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_LOST (int sig)
+#else
+void
+handle_LOST (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_USR1 (int sig)
+#else
+void
+handle_USR1 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_USR2 (int sig)
+#else
+void
+handle_USR2 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_PWR (int sig)
+#else
+void
+handle_PWR (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_POLL (int sig)
+#else
+void
+handle_POLL (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_WIND (int sig)
+#else
+void
+handle_WIND (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_PHONE (int sig)
+#else
+void
+handle_PHONE (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_WAITING (int sig)
+#else
+void
+handle_WAITING (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_LWP (int sig)
+#else
+void
+handle_LWP (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_DANGER (int sig)
+#else
+void
+handle_DANGER (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_GRANT (int sig)
+#else
+void
+handle_GRANT (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_RETRACT (int sig)
+#else
+void
+handle_RETRACT (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_MSG (int sig)
+#else
+void
+handle_MSG (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_SOUND (int sig)
+#else
+void
+handle_SOUND (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_SAK (int sig)
+#else
+void
+handle_SAK (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_PRIO (int sig)
+#else
+void
+handle_PRIO (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_33 (int sig)
+#else
+void
+handle_33 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_34 (int sig)
+#else
+void
+handle_34 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_35 (int sig)
+#else
+void
+handle_35 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_36 (int sig)
+#else
+void
+handle_36 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_37 (int sig)
+#else
+void
+handle_37 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_38 (int sig)
+#else
+void
+handle_38 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_39 (int sig)
+#else
+void
+handle_39 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_40 (int sig)
+#else
+void
+handle_40 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_41 (int sig)
+#else
+void
+handle_41 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_42 (int sig)
+#else
+void
+handle_42 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_43 (int sig)
+#else
+void
+handle_43 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_44 (int sig)
+#else
+void
+handle_44 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_45 (int sig)
+#else
+void
+handle_45 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_46 (int sig)
+#else
+void
+handle_46 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_47 (int sig)
+#else
+void
+handle_47 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_48 (int sig)
+#else
+void
+handle_48 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_49 (int sig)
+#else
+void
+handle_49 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_50 (int sig)
+#else
+void
+handle_50 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_51 (int sig)
+#else
+void
+handle_51 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_52 (int sig)
+#else
+void
+handle_52 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_53 (int sig)
+#else
+void
+handle_53 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_54 (int sig)
+#else
+void
+handle_54 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_55 (int sig)
+#else
+void
+handle_55 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_56 (int sig)
+#else
+void
+handle_56 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_57 (int sig)
+#else
+void
+handle_57 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_58 (int sig)
+#else
+void
+handle_58 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_59 (int sig)
+#else
+void
+handle_59 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_60 (int sig)
+#else
+void
+handle_60 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_61 (int sig)
+#else
+void
+handle_61 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_62 (int sig)
+#else
+void
+handle_62 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_63 (int sig)
+#else
+void
+handle_63 (sig)
+ int sig;
+#endif
+{
+}
+
+#ifdef PROTOTYPES
+void
+handle_TERM (int sig)
+#else
+void
+handle_TERM (sig)
+ int sig;
+#endif
+{
+}
+
+/* Functions to send signals. These also serve as markers. */
+int
+gen_ABRT ()
+{
+ kill (getpid (), SIGABRT);
+ return 0;
+}
+
+int
+gen_HUP ()
+{
+#ifdef SIGHUP
+ kill (getpid (), SIGHUP);
+#else
+ handle_HUP (0);
+#endif
+return 0;
+}
+
+int
+gen_QUIT ()
+{
+#ifdef SIGQUIT
+ kill (getpid (), SIGQUIT);
+#else
+ handle_QUIT (0);
+#endif
+return 0;
+}
+
+int
+gen_ILL ()
+{
+#ifdef SIGILL
+ kill (getpid (), SIGILL);
+#else
+ handle_ILL (0);
+#endif
+return 0;
+}
+
+int
+gen_EMT ()
+{
+#ifdef SIGEMT
+ kill (getpid (), SIGEMT);
+#else
+ handle_EMT (0);
+#endif
+return 0;
+}
+
+int x;
+
+int
+gen_FPE ()
+{
+ /* The intent behind generating SIGFPE this way is to check the mapping
+ from the CPU exception itself to the signals. It would be nice to
+ do the same for SIGBUS, SIGSEGV, etc., but I suspect that even this
+ test might turn out to be insufficiently portable. */
+
+#if 0
+ /* Loses on the PA because after the signal handler executes we try to
+ re-execute the failing instruction again. Perhaps we could siglongjmp
+ out of the signal handler? */
+ /* The expect script looks for the word "kill"; don't delete it. */
+ return 5 / x; /* and we both started jumping up and down yelling kill */
+#else
+ kill (getpid (), SIGFPE);
+#endif
+return 0;
+}
+
+int
+gen_BUS ()
+{
+#ifdef SIGBUS
+ kill (getpid (), SIGBUS);
+#else
+ handle_BUS (0);
+#endif
+return 0;
+}
+
+int
+gen_SEGV ()
+{
+#ifdef SIGSEGV
+ kill (getpid (), SIGSEGV);
+#else
+ handle_SEGV (0);
+#endif
+return 0;
+}
+
+int
+gen_SYS ()
+{
+#ifdef SIGSYS
+ kill (getpid (), SIGSYS);
+#else
+ handle_SYS (0);
+#endif
+return 0;
+}
+
+int
+gen_PIPE ()
+{
+#ifdef SIGPIPE
+ kill (getpid (), SIGPIPE);
+#else
+ handle_PIPE (0);
+#endif
+return 0;
+}
+
+int
+gen_ALRM ()
+{
+#ifdef SIGALRM
+ kill (getpid (), SIGALRM);
+#else
+ handle_ALRM (0);
+#endif
+return 0;
+}
+
+int
+gen_URG ()
+{
+#ifdef SIGURG
+ kill (getpid (), SIGURG);
+#else
+ handle_URG (0);
+#endif
+return 0;
+}
+
+int
+gen_TSTP ()
+{
+#ifdef SIGTSTP
+ kill (getpid (), SIGTSTP);
+#else
+ handle_TSTP (0);
+#endif
+return 0;
+}
+
+int
+gen_CONT ()
+{
+#ifdef SIGCONT
+ kill (getpid (), SIGCONT);
+#else
+ handle_CONT (0);
+#endif
+return 0;
+}
+
+int
+gen_CHLD ()
+{
+#ifdef SIGCHLD
+ kill (getpid (), SIGCHLD);
+#else
+ handle_CHLD (0);
+#endif
+return 0;
+}
+
+int
+gen_TTIN ()
+{
+#ifdef SIGTTIN
+ kill (getpid (), SIGTTIN);
+#else
+ handle_TTIN (0);
+#endif
+return 0;
+}
+
+int
+gen_TTOU ()
+{
+#ifdef SIGTTOU
+ kill (getpid (), SIGTTOU);
+#else
+ handle_TTOU (0);
+#endif
+return 0;
+}
+
+int
+gen_IO ()
+{
+#ifdef SIGIO
+ kill (getpid (), SIGIO);
+#else
+ handle_IO (0);
+#endif
+return 0;
+}
+
+int
+gen_XCPU ()
+{
+#ifdef SIGXCPU
+ kill (getpid (), SIGXCPU);
+#else
+ handle_XCPU (0);
+#endif
+return 0;
+}
+
+int
+gen_XFSZ ()
+{
+#ifdef SIGXFSZ
+ kill (getpid (), SIGXFSZ);
+#else
+ handle_XFSZ (0);
+#endif
+return 0;
+}
+
+int
+gen_VTALRM ()
+{
+#ifdef SIGVTALRM
+ kill (getpid (), SIGVTALRM);
+#else
+ handle_VTALRM (0);
+#endif
+return 0;
+}
+
+int
+gen_PROF ()
+{
+#ifdef SIGPROF
+ kill (getpid (), SIGPROF);
+#else
+ handle_PROF (0);
+#endif
+return 0;
+}
+
+int
+gen_WINCH ()
+{
+#ifdef SIGWINCH
+ kill (getpid (), SIGWINCH);
+#else
+ handle_WINCH (0);
+#endif
+return 0;
+}
+
+int
+gen_LOST ()
+{
+#if defined(SIGLOST) && (!defined(SIGABRT) || SIGLOST != SIGABRT)
+ kill (getpid (), SIGLOST);
+#else
+ handle_LOST (0);
+#endif
+return 0;
+}
+
+int
+gen_USR1 ()
+{
+#ifdef SIGUSR1
+ kill (getpid (), SIGUSR1);
+#else
+ handle_USR1 (0);
+#endif
+return 0;
+}
+
+int
+gen_USR2 ()
+{
+#ifdef SIGUSR2
+ kill (getpid (), SIGUSR2);
+#else
+ handle_USR2 (0);
+#endif
+return 0;
+}
+
+int
+gen_PWR ()
+{
+#ifdef SIGPWR
+ kill (getpid (), SIGPWR);
+#else
+ handle_PWR (0);
+#endif
+return 0;
+}
+
+int
+gen_POLL ()
+{
+#if defined (SIGPOLL) && (!defined (SIGIO) || SIGPOLL != SIGIO)
+ kill (getpid (), SIGPOLL);
+#else
+ handle_POLL (0);
+#endif
+return 0;
+}
+
+int
+gen_WIND ()
+{
+#ifdef SIGWIND
+ kill (getpid (), SIGWIND);
+#else
+ handle_WIND (0);
+#endif
+return 0;
+}
+
+int
+gen_PHONE ()
+{
+#ifdef SIGPHONE
+ kill (getpid (), SIGPHONE);
+#else
+ handle_PHONE (0);
+#endif
+return 0;
+}
+
+int
+gen_WAITING ()
+{
+#ifdef SIGWAITING
+ kill (getpid (), SIGWAITING);
+#else
+ handle_WAITING (0);
+#endif
+return 0;
+}
+
+int
+gen_LWP ()
+{
+#ifdef SIGLWP
+ kill (getpid (), SIGLWP);
+#else
+ handle_LWP (0);
+#endif
+return 0;
+}
+
+int
+gen_DANGER ()
+{
+#ifdef SIGDANGER
+ kill (getpid (), SIGDANGER);
+#else
+ handle_DANGER (0);
+#endif
+return 0;
+}
+
+int
+gen_GRANT ()
+{
+#ifdef SIGGRANT
+ kill (getpid (), SIGGRANT);
+#else
+ handle_GRANT (0);
+#endif
+return 0;
+}
+
+int
+gen_RETRACT ()
+{
+#ifdef SIGRETRACT
+ kill (getpid (), SIGRETRACT);
+#else
+ handle_RETRACT (0);
+#endif
+return 0;
+}
+
+int
+gen_MSG ()
+{
+#ifdef SIGMSG
+ kill (getpid (), SIGMSG);
+#else
+ handle_MSG (0);
+#endif
+return 0;
+}
+
+int
+gen_SOUND ()
+{
+#ifdef SIGSOUND
+ kill (getpid (), SIGSOUND);
+#else
+ handle_SOUND (0);
+#endif
+return 0;
+}
+
+int
+gen_SAK ()
+{
+#ifdef SIGSAK
+ kill (getpid (), SIGSAK);
+#else
+ handle_SAK (0);
+#endif
+return 0;
+}
+
+int
+gen_PRIO ()
+{
+#ifdef SIGPRIO
+ kill (getpid (), SIGPRIO);
+#else
+ handle_PRIO (0);
+#endif
+return 0;
+}
+
+int
+gen_33 ()
+{
+#ifdef SIG33
+ kill (getpid (), 33);
+#else
+ handle_33 (0);
+#endif
+return 0;
+}
+
+int
+gen_34 ()
+{
+#ifdef SIG34
+ kill (getpid (), 34);
+#else
+ handle_34 (0);
+#endif
+return 0;
+}
+
+int
+gen_35 ()
+{
+#ifdef SIG35
+ kill (getpid (), 35);
+#else
+ handle_35 (0);
+#endif
+return 0;
+}
+
+int
+gen_36 ()
+{
+#ifdef SIG36
+ kill (getpid (), 36);
+#else
+ handle_36 (0);
+#endif
+return 0;
+}
+
+int
+gen_37 ()
+{
+#ifdef SIG37
+ kill (getpid (), 37);
+#else
+ handle_37 (0);
+#endif
+return 0;
+}
+
+int
+gen_38 ()
+{
+#ifdef SIG38
+ kill (getpid (), 38);
+#else
+ handle_38 (0);
+#endif
+return 0;
+}
+
+int
+gen_39 ()
+{
+#ifdef SIG39
+ kill (getpid (), 39);
+#else
+ handle_39 (0);
+#endif
+return 0;
+}
+
+int
+gen_40 ()
+{
+#ifdef SIG40
+ kill (getpid (), 40);
+#else
+ handle_40 (0);
+#endif
+return 0;
+}
+
+int
+gen_41 ()
+{
+#ifdef SIG41
+ kill (getpid (), 41);
+#else
+ handle_41 (0);
+#endif
+return 0;
+}
+
+int
+gen_42 ()
+{
+#ifdef SIG42
+ kill (getpid (), 42);
+#else
+ handle_42 (0);
+#endif
+return 0;
+}
+
+int
+gen_43 ()
+{
+#ifdef SIG43
+ kill (getpid (), 43);
+#else
+ handle_43 (0);
+#endif
+return 0;
+}
+
+int
+gen_44 ()
+{
+#ifdef SIG44
+ kill (getpid (), 44);
+#else
+ handle_44 (0);
+#endif
+return 0;
+}
+
+int
+gen_45 ()
+{
+#ifdef SIG45
+ kill (getpid (), 45);
+#else
+ handle_45 (0);
+#endif
+return 0;
+}
+
+int
+gen_46 ()
+{
+#ifdef SIG46
+ kill (getpid (), 46);
+#else
+ handle_46 (0);
+#endif
+return 0;
+}
+
+int
+gen_47 ()
+{
+#ifdef SIG47
+ kill (getpid (), 47);
+#else
+ handle_47 (0);
+#endif
+return 0;
+}
+
+int
+gen_48 ()
+{
+#ifdef SIG48
+ kill (getpid (), 48);
+#else
+ handle_48 (0);
+#endif
+return 0;
+}
+
+int
+gen_49 ()
+{
+#ifdef SIG49
+ kill (getpid (), 49);
+#else
+ handle_49 (0);
+#endif
+return 0;
+}
+
+int
+gen_50 ()
+{
+#ifdef SIG50
+ kill (getpid (), 50);
+#else
+ handle_50 (0);
+#endif
+return 0;
+}
+
+int
+gen_51 ()
+{
+#ifdef SIG51
+ kill (getpid (), 51);
+#else
+ handle_51 (0);
+#endif
+return 0;
+}
+
+int
+gen_52 ()
+{
+#ifdef SIG52
+ kill (getpid (), 52);
+#else
+ handle_52 (0);
+#endif
+return 0;
+}
+
+int
+gen_53 ()
+{
+#ifdef SIG53
+ kill (getpid (), 53);
+#else
+ handle_53 (0);
+#endif
+return 0;
+}
+
+int
+gen_54 ()
+{
+#ifdef SIG54
+ kill (getpid (), 54);
+#else
+ handle_54 (0);
+#endif
+return 0;
+}
+
+int
+gen_55 ()
+{
+#ifdef SIG55
+ kill (getpid (), 55);
+#else
+ handle_55 (0);
+#endif
+return 0;
+}
+
+int
+gen_56 ()
+{
+#ifdef SIG56
+ kill (getpid (), 56);
+#else
+ handle_56 (0);
+#endif
+return 0;
+}
+
+int
+gen_57 ()
+{
+#ifdef SIG57
+ kill (getpid (), 57);
+#else
+ handle_57 (0);
+#endif
+return 0;
+}
+
+int
+gen_58 ()
+{
+#ifdef SIG58
+ kill (getpid (), 58);
+#else
+ handle_58 (0);
+#endif
+return 0;
+}
+
+int
+gen_59 ()
+{
+#ifdef SIG59
+ kill (getpid (), 59);
+#else
+ handle_59 (0);
+#endif
+return 0;
+}
+
+int
+gen_60 ()
+{
+#ifdef SIG60
+ kill (getpid (), 60);
+#else
+ handle_60 (0);
+#endif
+return 0;
+}
+
+int
+gen_61 ()
+{
+#ifdef SIG61
+ kill (getpid (), 61);
+#else
+ handle_61 (0);
+#endif
+return 0;
+}
+
+int
+gen_62 ()
+{
+#ifdef SIG62
+ kill (getpid (), 62);
+#else
+ handle_62 (0);
+#endif
+return 0;
+}
+
+int
+gen_63 ()
+{
+#ifdef SIG63
+ kill (getpid (), 63);
+#else
+ handle_63 (0);
+#endif
+return 0;
+}
+
+int
+gen_TERM ()
+{
+ kill (getpid (), SIGTERM);
+return 0;
+}
+
+int
+main ()
+{
+#ifdef usestubs
+ set_debug_traps ();
+ breakpoint ();
+#endif
+ signal (SIGABRT, handle_ABRT);
+#ifdef SIGHUP
+ signal (SIGHUP, handle_HUP);
+#endif
+#ifdef SIGQUIT
+ signal (SIGQUIT, handle_QUIT);
+#endif
+#ifdef SIGILL
+ signal (SIGILL, handle_ILL);
+#endif
+#ifdef SIGEMT
+ signal (SIGEMT, handle_EMT);
+#endif
+#ifdef SIGFPE
+ signal (SIGFPE, handle_FPE);
+#endif
+#ifdef SIGBUS
+ signal (SIGBUS, handle_BUS);
+#endif
+#ifdef SIGSEGV
+ signal (SIGSEGV, handle_SEGV);
+#endif
+#ifdef SIGSYS
+ signal (SIGSYS, handle_SYS);
+#endif
+#ifdef SIGPIPE
+ signal (SIGPIPE, handle_PIPE);
+#endif
+#ifdef SIGALRM
+ signal (SIGALRM, handle_ALRM);
+#endif
+#ifdef SIGURG
+ signal (SIGURG, handle_URG);
+#endif
+#ifdef SIGTSTP
+ signal (SIGTSTP, handle_TSTP);
+#endif
+#ifdef SIGCONT
+ signal (SIGCONT, handle_CONT);
+#endif
+#ifdef SIGCHLD
+ signal (SIGCHLD, handle_CHLD);
+#endif
+#ifdef SIGTTIN
+ signal (SIGTTIN, handle_TTIN);
+#endif
+#ifdef SIGTTOU
+ signal (SIGTTOU, handle_TTOU);
+#endif
+#ifdef SIGIO
+ signal (SIGIO, handle_IO);
+#endif
+#ifdef SIGXCPU
+ signal (SIGXCPU, handle_XCPU);
+#endif
+#ifdef SIGXFSZ
+ signal (SIGXFSZ, handle_XFSZ);
+#endif
+#ifdef SIGVTALRM
+ signal (SIGVTALRM, handle_VTALRM);
+#endif
+#ifdef SIGPROF
+ signal (SIGPROF, handle_PROF);
+#endif
+#ifdef SIGWINCH
+ signal (SIGWINCH, handle_WINCH);
+#endif
+#if defined(SIGLOST) && (!defined(SIGABRT) || SIGLOST != SIGABRT)
+ signal (SIGLOST, handle_LOST);
+#endif
+#ifdef SIGUSR1
+ signal (SIGUSR1, handle_USR1);
+#endif
+#ifdef SIGUSR2
+ signal (SIGUSR2, handle_USR2);
+#endif
+#ifdef SIGPWR
+ signal (SIGPWR, handle_PWR);
+#endif
+#if defined (SIGPOLL) && (!defined (SIGIO) || SIGPOLL != SIGIO)
+ signal (SIGPOLL, handle_POLL);
+#endif
+#ifdef SIGWIND
+ signal (SIGWIND, handle_WIND);
+#endif
+#ifdef SIGPHONE
+ signal (SIGPHONE, handle_PHONE);
+#endif
+#ifdef SIGWAITING
+ signal (SIGWAITING, handle_WAITING);
+#endif
+#ifdef SIGLWP
+ signal (SIGLWP, handle_LWP);
+#endif
+#ifdef SIGDANGER
+ signal (SIGDANGER, handle_DANGER);
+#endif
+#ifdef SIGGRANT
+ signal (SIGGRANT, handle_GRANT);
+#endif
+#ifdef SIGRETRACT
+ signal (SIGRETRACT, handle_RETRACT);
+#endif
+#ifdef SIGMSG
+ signal (SIGMSG, handle_MSG);
+#endif
+#ifdef SIGSOUND
+ signal (SIGSOUND, handle_SOUND);
+#endif
+#ifdef SIGSAK
+ signal (SIGSAK, handle_SAK);
+#endif
+#ifdef SIGPRIO
+ signal (SIGPRIO, handle_PRIO);
+#endif
+#ifdef __Lynx__
+ /* Lynx doesn't seem to have anything in signal.h for this. */
+ signal (33, handle_33);
+ signal (34, handle_34);
+ signal (35, handle_35);
+ signal (36, handle_36);
+ signal (37, handle_37);
+ signal (38, handle_38);
+ signal (39, handle_39);
+ signal (40, handle_40);
+ signal (41, handle_41);
+ signal (42, handle_42);
+ signal (43, handle_43);
+ signal (44, handle_44);
+ signal (45, handle_45);
+ signal (46, handle_46);
+ signal (47, handle_47);
+ signal (48, handle_48);
+ signal (49, handle_49);
+ signal (50, handle_50);
+ signal (51, handle_51);
+ signal (52, handle_52);
+ signal (53, handle_53);
+ signal (54, handle_54);
+ signal (55, handle_55);
+ signal (56, handle_56);
+ signal (57, handle_57);
+ signal (58, handle_58);
+ signal (59, handle_59);
+ signal (60, handle_60);
+ signal (61, handle_61);
+ signal (62, handle_62);
+ signal (63, handle_63);
+#endif /* lynx */
+ signal (SIGTERM, handle_TERM);
+
+ x = 0;
+
+ gen_ABRT ();
+ gen_HUP ();
+ gen_QUIT ();
+ gen_ILL ();
+ gen_EMT ();
+ gen_FPE ();
+ gen_BUS ();
+ gen_SEGV ();
+ gen_SYS ();
+ gen_PIPE ();
+ gen_ALRM ();
+ gen_URG ();
+ gen_TSTP ();
+ gen_CONT ();
+ gen_CHLD ();
+ gen_TTIN ();
+ gen_TTOU ();
+ gen_IO ();
+ gen_XCPU ();
+ gen_XFSZ ();
+ gen_VTALRM ();
+ gen_PROF ();
+ gen_WINCH ();
+ gen_LOST ();
+ gen_USR1 ();
+ gen_USR2 ();
+ gen_PWR ();
+ gen_POLL ();
+ gen_WIND ();
+ gen_PHONE ();
+ gen_WAITING ();
+ gen_LWP ();
+ gen_DANGER ();
+ gen_GRANT ();
+ gen_RETRACT ();
+ gen_MSG ();
+ gen_SOUND ();
+ gen_SAK ();
+ gen_PRIO ();
+ gen_33 ();
+ gen_34 ();
+ gen_35 ();
+ gen_36 ();
+ gen_37 ();
+ gen_38 ();
+ gen_39 ();
+ gen_40 ();
+ gen_41 ();
+ gen_42 ();
+ gen_43 ();
+ gen_44 ();
+ gen_45 ();
+ gen_46 ();
+ gen_47 ();
+ gen_48 ();
+ gen_49 ();
+ gen_50 ();
+ gen_51 ();
+ gen_52 ();
+ gen_53 ();
+ gen_54 ();
+ gen_55 ();
+ gen_56 ();
+ gen_57 ();
+ gen_58 ();
+ gen_59 ();
+ gen_60 ();
+ gen_61 ();
+ gen_62 ();
+ gen_63 ();
+ gen_TERM ();
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/sigall.exp b/gdb/testsuite/gdb.base/sigall.exp
new file mode 100644
index 00000000000..f452f0c6ef7
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sigall.exp
@@ -0,0 +1,210 @@
+# Copyright 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+if [target_info exists gdb,nosignals] {
+ verbose "Skipping sigall.exp because of nosignals."
+ continue
+}
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+set testfile sigall
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Make the first signal SIGABRT because it is always supported.
+set sig_supported 1
+set thissig "ABRT"
+
+proc test_one_sig {nextsig} {
+ global sig_supported
+ global gdb_prompt
+ global thissig
+
+ set this_sig_supported $sig_supported
+ gdb_test "handle SIG$thissig stop print" \
+ "SIG$thissig\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes.*"
+ gdb_test "b handle_$thissig" "Breakpoint \[0-9\]+ .*"
+ gdb_test "b gen_$nextsig" "Breakpoint \[0-9\]+ .*"
+
+ set need_another_continue 1
+ set missed_handler 0
+ if $this_sig_supported then {
+ send_gdb "continue\n"
+ if { $thissig == "IO" } {
+ setup_xfail "i*86-pc-linuxoldld-gnu" "i*86-pc-linuxaout-gnu"
+ }
+ gdb_expect {
+ -re "Continuing.*Program received signal SIG$thissig.*$gdb_prompt $" {
+ pass "get signal $thissig"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "get signal $thissig"
+ set need_another_continue 0
+ }
+ default {
+ fail "get signal $thissig (eof or timeout)"
+ }
+ }
+ }
+ if [ istarget "alpha-dec-osf3*" ] then {
+ # OSF/1-3.x is unable to continue with a job control stop signal.
+ # The inferior remains stopped without an event of interest
+ # and GDB waits forever for the inferior to stop on an event
+ # of interest. Work around the kernel bug.
+ if { $thissig == "TSTP" || $thissig == "TTIN" || $thissig == "TTOU" } {
+ setup_xfail "alpha-dec-osf3*"
+ fail "cannot continue from signal $thissig"
+ set need_another_continue 0
+ }
+ }
+
+ if $need_another_continue then {
+ send_gdb "continue\n"
+ if { $thissig == "URG" } {
+ setup_xfail "i*86-pc-linuxoldld-gnu" "i*86-pc-linuxaout-gnu"
+ }
+ # Either Lynx or GDB screws up on SIGPRIO
+ if { $thissig == "PRIO" } {
+ setup_xfail "*-*-*lynx*"
+ }
+ gdb_expect {
+ -re "Breakpoint.*handle_$thissig.*$gdb_prompt $" {
+ pass "send signal $thissig"
+ }
+ -re "Breakpoint.*gen_$nextsig.*kill.*$gdb_prompt $" {
+ fail "missed breakpoint at handle_$thissig"
+ set missed_handler 1
+ }
+ }
+ }
+
+ if { $missed_handler == "0" } then {
+ send_gdb "signal 0\n"
+ gdb_expect {
+ -re "Breakpoint.*gen_$nextsig.*kill.*$gdb_prompt $" {
+ pass "advance to $nextsig"
+ set sig_supported 1
+ }
+ -re "Breakpoint.*gen_$nextsig.*handle.*$gdb_prompt $" {
+ pass "advance to $nextsig"
+ set sig_supported 0
+ }
+ -re ".*$gdb_prompt $" { fail "advance to $nextsig" }
+ default { fail "advance to $nextsig (eof or timeout)" }
+ }
+ }
+ set thissig $nextsig
+}
+
+gdb_load $binfile
+
+runto gen_ABRT
+test_one_sig HUP
+test_one_sig QUIT
+test_one_sig ILL
+test_one_sig EMT
+test_one_sig FPE
+test_one_sig BUS
+test_one_sig SEGV
+test_one_sig SYS
+test_one_sig PIPE
+test_one_sig ALRM
+test_one_sig URG
+test_one_sig TSTP
+test_one_sig CONT
+test_one_sig CHLD
+test_one_sig TTIN
+test_one_sig TTOU
+test_one_sig IO
+test_one_sig XCPU
+test_one_sig XFSZ
+test_one_sig VTALRM
+test_one_sig PROF
+test_one_sig WINCH
+test_one_sig LOST
+test_one_sig USR1
+test_one_sig USR2
+test_one_sig PWR
+test_one_sig POLL
+test_one_sig WIND
+test_one_sig PHONE
+test_one_sig WAITING
+test_one_sig LWP
+test_one_sig DANGER
+test_one_sig GRANT
+test_one_sig RETRACT
+test_one_sig MSG
+test_one_sig SOUND
+test_one_sig SAK
+test_one_sig PRIO
+test_one_sig 33
+test_one_sig 34
+test_one_sig 35
+test_one_sig 36
+test_one_sig 37
+test_one_sig 38
+test_one_sig 39
+test_one_sig 40
+test_one_sig 41
+test_one_sig 42
+test_one_sig 43
+test_one_sig 44
+test_one_sig 45
+test_one_sig 46
+test_one_sig 47
+test_one_sig 48
+test_one_sig 49
+test_one_sig 50
+test_one_sig 51
+test_one_sig 52
+test_one_sig 53
+test_one_sig 54
+test_one_sig 55
+test_one_sig 56
+test_one_sig 57
+test_one_sig 58
+test_one_sig 59
+test_one_sig 60
+test_one_sig 61
+test_one_sig 62
+test_one_sig 63
+test_one_sig TERM
+
+# The last signal (SIGTERM) gets handled slightly differently because
+# we are not setting up for another test.
+gdb_test "handle SIGTERM stop print" \
+ "SIGTERM\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes.*"
+gdb_test "b handle_TERM" "Breakpoint \[0-9\]+ .*"
+gdb_test "continue" \
+ "Continuing.*Program received signal SIGTERM.*" \
+ "get signal TERM"
+gdb_test "continue" "Breakpoint.*handle_TERM.*" "send signal TERM"
+gdb_continue_to_end "continue to sigall exit"
+
+return 0
diff --git a/gdb/testsuite/gdb.base/signals.c b/gdb/testsuite/gdb.base/signals.c
new file mode 100644
index 00000000000..f1ebcfccb3d
--- /dev/null
+++ b/gdb/testsuite/gdb.base/signals.c
@@ -0,0 +1,59 @@
+/* Test GDB dealing with stuff like stepping into sigtramp. */
+
+#include <signal.h>
+#include <unistd.h>
+
+#ifdef __sh__
+#define signal(a,b) /* Signals not supported on this target - make them go away */
+#define alarm(a) /* Ditto for alarm() */
+#endif
+
+static int count = 0;
+
+#ifdef PROTOTYPES
+static void
+handler (int sig)
+#else
+static void
+handler (sig)
+ int sig;
+#endif
+{
+ signal (sig, handler);
+ ++count;
+}
+
+static void
+func1 ()
+{
+ ++count;
+}
+
+static void
+func2 ()
+{
+ ++count;
+}
+
+int
+main ()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+#ifdef SIGALRM
+ signal (SIGALRM, handler);
+#endif
+#ifdef SIGUSR1
+ signal (SIGUSR1, handler);
+#endif
+ alarm (1);
+ ++count; /* first */
+ alarm (1);
+ ++count; /* second */
+ func1 ();
+ alarm (1);
+ func2 ();
+ return count;
+}
diff --git a/gdb/testsuite/gdb.base/signals.exp b/gdb/testsuite/gdb.base/signals.exp
new file mode 100644
index 00000000000..2bf719234bd
--- /dev/null
+++ b/gdb/testsuite/gdb.base/signals.exp
@@ -0,0 +1,639 @@
+# Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if [target_info exists gdb,nosignals] {
+ verbose "Skipping signals.exp because of nosignals."
+ continue
+}
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile signals
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+if {$hp_cc_compiler} {
+ set void 0
+} else {
+ set void void
+}
+
+proc signal_tests_1 {} {
+ global gdb_prompt
+ if [runto_main] then {
+ gdb_test "next" "signal \\(SIGUSR1.*" \
+ "next over signal (SIGALRM, handler)"
+ gdb_test "next" "alarm \\(.*" \
+ "next over signal (SIGUSR1, handler)"
+ gdb_test "next" "\\+\\+count; /\\* first \\*/" \
+ "next over alarm (1)"
+ # An alarm has been signaled, give the signal time to get delivered.
+ sleep 2
+
+ # i386 BSD currently fails the next test with a SIGTRAP.
+ setup_xfail "i*86-*-bsd*"
+ # But Dynix has a DECR_PC_AFTER_BREAK of zero, so the failure
+ # is shadowed by hitting the through_sigtramp_breakpoint.
+ clear_xfail "i*86-sequent-bsd*"
+ # Univel SVR4 i386 continues instead of stepping.
+ setup_xfail "i*86-univel-sysv4*"
+ # lynx fails with "next" acting like "continue"
+ setup_xfail "*-*-*lynx*"
+ # linux (aout versions) also fails with "next" acting like "continue"
+ # this is probably more dependant on the kernel version than on the
+ # object file format or utils. (sigh)
+ setup_xfail "i*86-pc-linuxaout-gnu" "i*86-pc-linuxoldld-gnu"
+ send_gdb "next\n"
+ gdb_expect {
+ -re "alarm .*$gdb_prompt $" { pass "next to 2nd alarm (1)" }
+ -re "Program received signal SIGTRAP.*first.*$gdb_prompt $" {
+
+ # This can happen on machines that have a trace flag
+ # in their PS register.
+ # The trace flag in the PS register will be set due to
+ # the `next' command.
+ # Before calling the signal handler, the PS register
+ # is pushed along with the context on the user stack.
+ # When the signal handler has finished, it reenters the
+ # the kernel via a sigreturn syscall, which restores the
+ # PS register along with the context.
+ # If the kernel erroneously does not clear the trace flag
+ # in the pushed context, gdb will receive a SIGTRAP from
+ # the set trace flag in the restored context after the
+ # signal handler has finished.
+
+ # I do not yet understand why the SIGTRAP does not occur
+ # after stepping the instruction at the restored PC on
+ # i386 BSDI 1.0 systems.
+
+ # Note that the vax under Ultrix also exhibits
+ # this behaviour (it is uncovered by the `continue from
+ # a break in a signal handler' test below).
+ # With this test the failure is shadowed by hitting the
+ # through_sigtramp_breakpoint upon return from the signal
+ # handler.
+
+ # SVR4 and Linux based i*86 systems exhibit this behaviour
+ # as well (it is uncovered by the `continue from a break
+ # in a signal handler' test below).
+ # As these systems use procfs, where we tell the kernel not
+ # to tell gdb about `pass' signals, and the trace flag is
+ # cleared by the kernel before entering the sigtramp
+ # routine, GDB will not notice the execution of the signal
+ # handler.
+ # Upon return from the signal handler, GDB will receive
+ # a SIGTRAP from the set trace flag in the restored context.
+ # The SIGTRAP marks the end of a (albeit long winded)
+ # single step for GDB, causing this test to pass.
+
+ fail "next to 2nd alarm (1) (probably kernel bug)"
+ gdb_test "next" "alarm.*" "next to 2nd alarm (1)"
+ }
+ -re "Program exited with code.*$gdb_prompt $" {
+
+ # This is apparently a bug in the UnixWare kernel (but
+ # has not been investigated beyond the
+ # resume/target_wait level, and has not been reported
+ # to Univel). If it steps when a signal is pending,
+ # it does a continue instead. I don't know whether
+ # there is a workaround.
+
+ # Perhaps this problem exists on other SVR4 systems;
+ # but (a) we have no reason to think so, and (b) if we
+ # put a wrong xfail here, we never get an XPASS to let
+ # us know that it was incorrect (and then if such a
+ # configuration regresses we have no way of knowing).
+ # Solaris is not a relevant data point either way
+ # because it lacks single stepping.
+
+ # fnf: I don't agree with the above philosophy. We
+ # can never be sure that any particular XFAIL is
+ # specified 100% correctly in that no systems with
+ # the bug are missed and all systems without the bug
+ # are excluded. If we include an XFAIL that isn't
+ # appropriate for a particular system, then when that
+ # system gets tested it will XPASS, and someone should
+ # investigate and fix the setup_xfail as appropriate,
+ # or more preferably, the actual bug. Each such case
+ # adds more data to narrowing down the scope of the
+ # problem and ultimately fixing it.
+
+ setup_xfail "i*86-*-sysv4*"
+ fail "'next' behaved as 'continue (known SVR4 bug)'"
+ return 0
+ }
+ -re ".*$gdb_prompt $" { fail "next to 2nd alarm (1)" }
+ timeout { fail "next to 2nd alarm (1); (timeout)" }
+ eof { fail "next to 2nd alarm (1); (eof)" }
+ }
+
+ gdb_test "break handler" "Breakpoint \[0-9\]+ .*"
+ gdb_test "next" "\\+\\+count; /\\* second \\*/" \
+ "next to 2nd ++count in signals_tests_1"
+ # An alarm has been signaled, give the signal time to get delivered.
+ sleep 2
+
+ set bash_bug 0
+ send_gdb "next\n"
+ gdb_expect {
+ -re "Breakpoint.*handler.*$gdb_prompt $" {
+ pass "next to handler in signals_tests_1"
+ }
+ -re "Program received signal SIGEMT.*$gdb_prompt $" {
+ # Bash versions before 1.13.5 cause this behaviour
+ # by blocking SIGTRAP.
+ fail "next to handler in signals_tests_1 (known problem with bash versions before 1.13.5)"
+ set bash_bug 1
+ gdb_test "signal 0" "Breakpoint.*handler.*"
+ }
+ -re ".*$gdb_prompt $" { fail "next to handler in signals_tests_1" }
+ timeout { fail "next to handler in signals_tests_1 (timeout)" }
+ eof { fail "next to handler in signals_tests_1 (eof)" }
+ }
+
+ # This doesn't test that main is frame #2, just that main is frame
+ # #2, #3, or higher. At some point this should be fixed (but
+ # it quite possibly would introduce new FAILs on some systems).
+ setup_xfail "i*86-*-bsdi2.0"
+ gdb_test "backtrace 10" "#0.*handler.*#1.*#2.*main.*" \
+ "backtrace in signals_tests_1"
+
+ gdb_test "break func1" "Breakpoint \[0-9\]+ .*"
+ gdb_test "break func2" "Breakpoint \[0-9\]+ .*"
+
+ # Vax Ultrix and i386 BSD currently fail the next test with
+ # a SIGTRAP, but with different symptoms.
+ setup_xfail "vax-*-ultrix*"
+ setup_xfail "i*86-*-bsd*"
+ setup_xfail "i*86-pc-linux-gnu*"
+ setup_xfail "i*86-*-solaris2*"
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Breakpoint.*func1.*$gdb_prompt $" { pass "continue to func1" }
+ -re "Program received signal SIGTRAP.*second.*$gdb_prompt $" {
+
+ # See explanation for `next to 2nd alarm (1)' fail above.
+ # We did step into the signal handler, hit a breakpoint
+ # in the handler and continued from the breakpoint.
+ # The set trace flag in the restored context is causing
+ # the SIGTRAP, without stepping an instruction.
+
+ fail "continue to func1 (probably kernel bug)"
+ gdb_test "continue" "Breakpoint.*func1.*" \
+ "extra continue to func1"
+ }
+ -re "Program received signal SIGTRAP.*func1 ..;.*$gdb_prompt $" {
+
+ # On the vax under Ultrix the set trace flag in the restored
+ # context is causing the SIGTRAP, but after stepping one
+ # instruction, as expected.
+
+ fail "continue to func1 (probably kernel bug)"
+ gdb_test "continue" "Breakpoint.*func1.*" \
+ "extra continue to func1"
+ }
+ -re ".*$gdb_prompt $" { fail "continue to func1" }
+ default { fail "continue to func1" }
+ }
+
+ setup_xfail "*-*-irix*"
+ send_gdb "signal SIGUSR1\n"
+ gdb_expect {
+ -re "Breakpoint.*handler.*$gdb_prompt $" { pass "signal SIGUSR1" }
+ -re "Program received signal SIGUSR1.*$gdb_prompt $" {
+ # This is what irix4 and irix5 do.
+ # It would appear to be a kernel bug.
+ fail "signal SIGUSR1"
+ gdb_test "continue" "Breakpoint.*handler.*" "pass it SIGUSR1"
+ }
+ -re ".*$gdb_prompt $" { fail "signal SIGUSR1" }
+ default { fail "signal SIGUSR1" }
+ }
+
+ # Will tend to wrongly require an extra continue.
+
+ # The problem here is that the breakpoint at func1 will be
+ # inserted, and when the system finishes with the signal
+ # handler it will try to execute there. For GDB to try to
+ # remember that it was going to step over a breakpoint when a
+ # signal happened, distinguish this case from the case where
+ # func1 is called from the signal handler, etc., seems
+ # exceedingly difficult. So don't expect this to get fixed
+ # anytime soon.
+
+ setup_xfail "*-*-*"
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Breakpoint.*func2.*$gdb_prompt $" { pass "continue to func2" }
+ -re "Breakpoint.*func1.*$gdb_prompt $" {
+ fail "continue to func2"
+ gdb_test "continue" "Breakpoint.*func2.*" \
+ "extra continue to func2"
+ }
+ -re ".*$gdb_prompt $" { fail "continue to func2" }
+ default { fail "continue to func2" }
+ }
+
+ sleep 2
+
+ # GDB yanks out the breakpoints to step over the breakpoint it
+ # stopped at, which means the breakpoint at handler is yanked.
+ # But if SOFTWARE_SINGLE_STEP_P, we won't get another chance to
+ # reinsert them (at least not with procfs, where we tell the kernel
+ # not to tell gdb about `pass' signals). So the fix would appear to
+ # be to just yank that one breakpoint when we step over it.
+
+ setup_xfail "sparc*-*-*"
+ setup_xfail "rs6000-*-*"
+ setup_xfail "powerpc-*-*"
+
+ # A faulty bash will not step the inferior into sigtramp on sun3.
+ if {$bash_bug} then {
+ setup_xfail "m68*-*-sunos4*"
+ }
+
+ setup_xfail "i*86-pc-linux-gnu*"
+ setup_xfail "i*86-*-solaris2*"
+ gdb_test "continue" "Breakpoint.*handler.*" "continue to handler"
+
+ # If the SOFTWARE_SINGLE_STEP_P failure happened, we have already
+ # exited.
+ # If we succeeded a continue will return from the handler to func2.
+ # GDB now has `forgotten' that it intended to step over the
+ # breakpoint at func2 and will stop at func2.
+ setup_xfail "*-*-*"
+ # The sun3 with a faulty bash will also be `forgetful' but it
+ # already got the spurious stop at func2 and this continue will work.
+ if {$bash_bug} then {
+ clear_xfail "m68*-*-sunos4*"
+ }
+ gdb_test "continue" "Program exited with code 010\\." \
+ "continue to exit in signals_tests_1 "
+ }
+}
+
+# On a few losing systems, ptrace (PT_CONTINUE) or ptrace (PT_STEP)
+# causes pending signals to be cleared, which causes these tests to
+# get nowhere fast. This is totally losing behavior (perhaps there
+# are cases in which is it useful but the user needs more control,
+# which they mostly have in GDB), but some people apparently think it
+# is a feature. It is documented in the ptrace manpage on Motorola
+# Delta Series sysV68 R3V7.1 and on HPUX 9.0. Even the non-HPUX PA
+# OSes (BSD and OSF/1) seem to have figured they had to copy this
+# braindamage.
+
+if {[ istarget "m68*-motorola-*" ] || [ istarget "hppa*-*-bsd*" ] ||
+ [ istarget "hppa*-*-osf*" ]} then {
+ setup_xfail "*-*-*"
+ fail "ptrace loses on signals on this target"
+ return 0
+}
+
+# lynx2.2.2 doesn't lose signals, instead it screws up the stack pointer
+# in some of these tests leading to massive problems. I've
+# reported this to lynx, hopefully it'll be fixed in lynx2.3.
+# Severe braindamage.
+if [ istarget "*-*-*lynx*" ] then {
+ setup_xfail "*-*-*"
+ fail "kernel scroggs stack pointer in signal tests on this target"
+ return 0
+}
+
+gdb_exit
+gdb_start
+
+# This will need to be updated as the exact list of signals changes,
+# but I want to test that TARGET_SIGNAL_0, TARGET_SIGNAL_DEFAULT, and
+# TARGET_SIGNAL_UNKNOWN are skipped.
+proc test_handle_all_print {} {
+ global timeout
+ # Increase timeout and expect input buffer for large output from gdb.
+ # Allow blank or TAB as whitespace characters.
+ set oldtimeout $timeout
+ set timeout [expr "$timeout + 360"]
+ verbose "Timeout is now $timeout seconds" 2
+ if { ![istarget "*-*-linux*"]
+ && ( [istarget "*-*-gnu*"]
+ || [istarget "*-*-mach*"] ) } {
+ gdb_test "handle all print" "Signal\[ \]+Stop\[ \]+Print\[ \]+Pass to program\[ \]+Description\r\nSIGHUP\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Hangup.*SIG63\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Real-time event 63.*EXC_BREAKPOINT\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Breakpoint"
+ } else {
+ gdb_test "handle all print" "Signal\[ \]+Stop\[ \]+Print\[ \]+Pass to program\[ \]+Description\r\nSIGHUP\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Hangup.*SIG63\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Real-time event 63.*"
+ }
+ set timeout $oldtimeout
+ verbose "Timeout restored to $timeout seconds" 2
+}
+test_handle_all_print
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+signal_tests_1
+
+# Force a resync, so we're looking at the right prompt. On SCO we
+# were getting out of sync (I don't understand why).
+send_gdb "p 1+1\n"
+gdb_expect {
+ -re "= 2.*$gdb_prompt $" {}
+ -re ".*$gdb_prompt $" { perror "sync trouble in signals.exp" }
+ default { perror "sync trouble in signals.exp" }
+}
+
+if [runto_main] then {
+ # Since count is a static variable outside main, runto_main
+ # is no guarantee that count will be 0 at this point.
+ gdb_test "set variable count = 0" ""
+ gdb_test "break handler if 0" "Breakpoint \[0-9\]+ .*"
+ gdb_test "set \$handler_breakpoint_number = \$bpnum" ""
+
+ # Get to the point where a signal is waiting to be delivered
+ gdb_test "next" "signal \\(SIGUSR1.*" "next to signal in signals.exp"
+ gdb_test "next" "alarm \\(.*" "next to alarm #1 in signals.exp"
+ gdb_test "next" "\\+\\+count; /\\* first \\*/" \
+ "next to ++count #1 in signals.exp"
+ # Give the signal time to get delivered
+ sleep 2
+
+ # Now call a function. When GDB tries to run the stack dummy,
+ # it will hit the breakpoint at handler. Provided it doesn't
+ # lose its cool, this is not a problem, it just has to note
+ # that the breakpoint condition is false and keep going.
+
+ gdb_test "p func1 ()" "^p func1 \\(\\)\r\n.\[0-9\]* = $void" \
+ "p func1 () #1 in signals.exp"
+
+ # Make sure the count got incremented.
+
+ # Haven't investigated this xfail
+ setup_xfail "rs6000-*-*"
+ setup_xfail "powerpc-*-*"
+ gdb_test "p count" "= 2" "p count #1 in signals.exp"
+ if { [istarget "rs6000-*-*"] || [istarget "powerpc-*-*"] } { return 0 }
+
+ gdb_test "condition \$handler_breakpoint_number" "now unconditional\\."
+ gdb_test "next" "alarm \\(.*" "next to alarm #2 in signals.exp"
+ gdb_test "next" "\\+\\+count; /\\* second \\*/" \
+ "next to ++count #2 in signals.exp"
+ sleep 2
+
+ # This time we stop when GDB tries to run the stack dummy.
+ # So it is OK that we do not print the return value from the function.
+ gdb_test "p func1 ()" \
+"Breakpoint \[0-9\]*, handler.*
+The program being debugged stopped while in a function called from GDB.*" \
+ "p func1 () #2 in signals.exp"
+ # But we should be able to backtrace...
+ # On alpha-*-osf2.0 this test works when run manually but sometime fails when
+ # run under dejagnu, making it very hard to debug the problem. Weird...
+ gdb_test "bt 10" "#0.*handler.*#1.*#2.*main.*" "bt in signals.exp"
+ # ...and continue...
+ gdb_test "continue" "Continuing\\." "continue in signals.exp"
+ # ...and then count should have been incremented
+ gdb_test "p count" "= 5" "p count #2 in signals.exp"
+
+
+# Verify that "info signals" produces reasonable output.
+#
+ send_gdb "info signals\n"
+ gdb_expect {
+ -re "SIGHUP.*SIGINT.*SIGQUIT.*SIGILL.*SIGTRAP.*SIGABRT.*SIGEMT.*SIGFPE.*SIGKILL.*SIGBUS.*SIGSEGV.*SIGSYS.*SIGPIPE.*SIGALRM.*SIGTERM.*SIGURG.*SIGSTOP.*SIGTSTP.*SIGCONT.*SIGCHLD.*SIGTTIN.*SIGTTOU.*SIGIO.*SIGXCPU.*SIGXFSZ.*SIGVTALRM.*SIGPROF.*SIGWINCH.*SIGLOST.*SIGUSR1.*SIGUSR2.*SIGPWR.*SIGPOLL.*SIGWIND.*SIGPHONE.*SIGWAITING.*SIGLWP.*SIGDANGER.*SIGGRANT.*SIGRETRACT.*SIGMSG.*SIGSOUND.*SIGSAK.*SIGPRIO.*SIG33.*SIG34.*SIG35.*SIG36.*SIG37.*SIG38.*SIG39.*SIG40.*SIG41.*SIG42.*SIG43.*SIG44.*SIG45.*SIG46.*SIG47.*SIG48.*SIG49.*SIG50.*SIG51.*SIG52.*SIG53.*SIG54.*SIG55.*SIG56.*SIG57.*SIG58.*SIG59.*SIG60.*SIG61.*SIG62.*SIG63.*Use the \"handle\" command to change these tables.*$gdb_prompt $"\
+ {pass "info signals"}
+ -re "$gdb_prompt $"\
+ {fail "info signals"}
+ timeout {fail "(timeout) info signals"}
+ }
+
+# Verify that "info signal" correctly handles an argument, be it a
+# symbolic signal name, or an integer ID.
+#
+ send_gdb "info signal SIGTRAP\n"
+ gdb_expect {
+ -re ".*SIGTRAP\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*No\[ \t\]*Trace/breakpoint trap.*$gdb_prompt $"\
+ {pass "info signal SIGTRAP"}
+ -re "$gdb_prompt $"\
+ {fail "info signal SIGTRAP"}
+ timeout {fail "(timeout) info signal SIGTRAP"}
+ }
+
+ send_gdb "info signal 5\n"
+ gdb_expect {
+ -re ".*SIGTRAP\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*No\[ \t\]*Trace/breakpoint trap.*$gdb_prompt $"\
+ {pass "info signal 5"}
+ -re "$gdb_prompt $"\
+ {fail "info signal 5"}
+ timeout {fail "(timeout) info signal 5"}
+ }
+
+# Verify that "handle" with illegal arguments is gracefully, um, handled.
+#
+ send_gdb "handle\n"
+ gdb_expect {
+ -re "Argument required .signal to handle.*$gdb_prompt $"\
+ {pass "handle without arguments"}
+ -re "$gdb_prompt $"\
+ {fail "handle without arguments"}
+ timeout {fail "(timeout) handle without arguments"}
+ }
+
+ send_gdb "handle SIGFOO\n"
+ gdb_expect {
+ -re "Unrecognized or ambiguous flag word: \"SIGFOO\".*$gdb_prompt $"\
+ {pass "handle with bogus SIG"}
+ -re "$gdb_prompt $"\
+ {fail "handle with bogus SIG"}
+ timeout {fail "(timeout) handle with bogus SIG"}
+ }
+
+ send_gdb "handle SIGHUP frump\n"
+ gdb_expect {
+ -re "Unrecognized or ambiguous flag word: \"frump\".*$gdb_prompt $"\
+ {pass "handle SIG with bogus action"}
+ -re "$gdb_prompt $"\
+ {fail "handle SIG with bogus action"}
+ timeout {fail "(timeout) handle SIG with bogus action"}
+ }
+
+# Verify that "handle" can take multiple actions per SIG, and that in
+# the case of conflicting actions, that the rightmost action "wins".
+#
+ send_gdb "handle SIGHUP print noprint\n"
+ gdb_expect {
+ -re ".*SIGHUP\[ \t\]*No\[ \t\]*No\[ \t\]*Yes\[ \t\]*Hangup.*$gdb_prompt $"\
+ {pass "handle SIG with multiple conflicting actions"}
+ -re "$gdb_prompt $"\
+ {fail "handle SIG with multiple conflicting actions"}
+ timeout {fail "(timeout) handle SIG with multiple conflicting actions"}
+ }
+
+# Exercise all the various actions. (We don't care what the outcome
+# is, this is just to ensure that they all can be parsed.)
+#
+ send_gdb "handle SIGHUP print noprint stop nostop ignore noignore pass nopass\n"
+ gdb_expect {
+ -re ".*Signal.*$gdb_prompt $"\
+ {pass "handle SIG parses all legal actions"}
+ -re "$gdb_prompt $"\
+ {fail "handle SIG parses all legal actions"}
+ timeout {fail "(timeout) handle SIG parses all legal actions"}
+ }
+
+# Verify that we can "handle" multiple signals at once, interspersed
+# with actions.
+#
+ send_gdb "handle SIG63 print SIGILL\n"
+ gdb_expect {
+ -re ".*SIGILL\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Illegal instruction.*SIG63\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Real-time event 63.*$gdb_prompt $"\
+ {pass "handle multiple SIGs"}
+ -re "$gdb_prompt $"\
+ {fail "handle multiple SIGs"}
+ timeout {fail "(timeout) handle multiple SIGs"}
+ }
+
+# Verify that "handle" can take a numeric argument for the signal ID,
+# rather than a symbolic name. (This may not be portable; works for
+# HP-UX.)
+#
+# Also note that this testpoint overrides SIGTRAP, which on HP-UX at
+# least, is used to implement single-steps and breakpoints. Don't
+# expect to run the inferior after this!
+#
+ send_gdb "handle 5 nopass\n"
+ gdb_expect {
+ -re ".*SIGTRAP is used by the debugger.*Are you sure you want to change it.*y or n.*"\
+ {send_gdb "y\n"
+ gdb_expect {
+ -re ".*SIGTRAP\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*No\[ \t\]*Trace/breakpoint trap.*$gdb_prompt $"\
+ {pass "override SIGTRAP (#5)"}
+ -re "$gdb_prompt $"\
+ {fail "override SIGTRAP (#5)"}
+ timeout {fail "(timeout) override SIGTRAP (#5)"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "override SIGTRAP (#5)"}
+ timeout {fail "(timeout) override SIGTRAP (#5)"}
+ }
+
+# GDB doesn't seem to allow numeric signal IDs larger than 15. Verify
+# that restriction. ??rehrauer: Not sure if this is a feature or a
+# bug, actually. Why is the range 1-15?
+#
+ send_gdb "handle 58\n"
+ gdb_expect {
+ -re "Only signals 1-15 are valid as numeric signals.*Use \"info signals\" for a list of symbolic signals.*$gdb_prompt $"\
+ {pass "invalid signal number rejected"}
+ -re "$gdb_prompt $"\
+ {fail "invalid signal number rejected"}
+ timeout {fail "(timeout) invalid signal number rejected"}
+ }
+
+# Verify that we can accept a signal ID range (number-number).
+# ??rehrauer: This feature isn't documented on the quick-reference
+# card.
+#
+ send_gdb "handle 13-15\n"
+ gdb_expect {
+ -re ".*SIGPIPE.*SIGALRM.*SIGTERM.*$gdb_prompt $"\
+ {pass "handle multiple SIGs via integer range"}
+ -re "$gdb_prompt $"\
+ {fail "handle multiple SIGs via integer range"}
+ timeout {fail "(timeout) handle multiple SIGs via integer range"}
+
+ }
+
+# Bizarrely enough, GDB also allows you to reverse the range
+# stat, stop IDs. E.g., "3-1" and "1-3" mean the same thing.
+# Probably this isn't documented, but the code anticipates it,
+# so we'd best test it...
+#
+ send_gdb "handle 15-13\n"
+ gdb_expect {
+ -re ".*SIGPIPE.*SIGALRM.*SIGTERM.*$gdb_prompt $"\
+ {pass "handle multiple SIGs via integer range"}
+ -re "$gdb_prompt $"\
+ {fail "handle multiple SIGs via integer range"}
+ timeout {fail "(timeout) handle multiple SIGs via integer range"}
+
+ }
+
+# SIGINT is used by the debugger as well. Verify that we can change
+# our minds about changing it.
+#
+ send_gdb "handle SIGINT nopass\n"
+ gdb_expect {
+ -re ".*SIGINT is used by the debugger.*Are you sure you want to change it.*y or n.*"\
+ {send_gdb "n\n"
+# ??rehrauer: When you answer "n", the header for the signal info is
+# printed, but not the actual handler settings. Probably a bug.
+#
+ gdb_expect {
+ -re "Not confirmed, unchanged.*Signal.*$gdb_prompt $"\
+ {pass "override SIGINT"}
+ -re "$gdb_prompt $"\
+ {fail "override SIGINT"}
+ timeout {fail "(timeout) override SIGINT"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "override SIGINT"}
+ timeout {fail "(timeout) override SIGINT"}
+ }
+
+# Verify that GDB responds gracefully to the "signal" command with
+# a missing argument.
+#
+ send_gdb "signal\n"
+ gdb_expect {
+ -re "Argument required .signal number..*$gdb_prompt $"\
+ {pass "signal without arguments disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "signal without arguments disallowed"}
+ timeout {fail "(timeout) signal without arguments disallowed"}
+ }
+
+# Verify that we can successfully send a signal other than 0 to
+# the inferior. (This probably causes the inferior to run away.
+# Be prepared to rerun to main for further testing.)
+#
+ send_gdb "signal 5\n"
+ gdb_expect {
+ -re "Continuing with signal SIGTRAP.*$gdb_prompt $"\
+ {pass "sent signal 5"}
+ -re "$gdb_prompt $"\
+ {fail "sent signal 5"}
+ timeout {fail "(timeout) sent signal 5"}
+ }
+
+}
+
+return 0
diff --git a/gdb/testsuite/gdb.base/sizeof.c b/gdb/testsuite/gdb.base/sizeof.c
new file mode 100644
index 00000000000..95d379ee9ae
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sizeof.c
@@ -0,0 +1,122 @@
+#include <stdio.h>
+
+typedef char padding[16];
+
+struct {
+ padding p1;
+ char v;
+ padding p2;
+} padding_char;
+
+struct {
+ padding p1;
+ short v;
+ padding p2;
+} padding_short;
+
+struct {
+ padding p1;
+ int v;
+ padding p2;
+} padding_int;
+
+struct {
+ padding p1;
+ long v;
+ padding p2;
+} padding_long;
+
+struct {
+ padding p1;
+ long long v;
+ padding p2;
+} padding_long_long;
+
+struct {
+ padding p1;
+ float v;
+ padding p2;
+} padding_float;
+
+struct {
+ padding p1;
+ double v;
+ padding p2;
+} padding_double;
+
+struct {
+ padding p1;
+ long double v;
+ padding p2;
+} padding_long_double;
+
+static void
+fill (void *buf, long sizeof_buf)
+{
+ char *p = buf;
+ int i;
+ for (i = 0; i < sizeof_buf; i++)
+ p[i] = "The quick brown dingo jumped over the layzy dog."[i];
+}
+
+void
+fill_structs (void)
+{
+ fill (&padding_char.p1, sizeof (padding));
+ fill (&padding_char.v, sizeof (padding_char.v));
+ fill (&padding_char.p2, sizeof (padding));
+
+ fill (&padding_short.p1, sizeof (padding));
+ fill (&padding_short.v, sizeof (padding_short.v));
+ fill (&padding_short.p2, sizeof (padding));
+
+ fill (&padding_int.p1, sizeof (padding));
+ fill (&padding_int.v, sizeof (padding_int.v));
+ fill (&padding_int.p2, sizeof (padding));
+
+ fill (&padding_long.p1, sizeof (padding));
+ fill (&padding_long.v, sizeof (padding_long.v));
+ fill (&padding_long.p2, sizeof (padding));
+
+ fill (&padding_long_long.p1, sizeof (padding));
+ fill (&padding_long_long.v, sizeof (padding_long_long.v));
+ fill (&padding_long_long.p2, sizeof (padding));
+
+ fill (&padding_float.p1, sizeof (padding));
+ fill (&padding_float.v, sizeof (padding_float.v));
+ fill (&padding_float.p2, sizeof (padding));
+
+ fill (&padding_double.p1, sizeof (padding));
+ fill (&padding_double.v, sizeof (padding_double.v));
+ fill (&padding_double.p2, sizeof (padding));
+
+ fill (&padding_long_double.p1, sizeof (padding));
+ fill (&padding_long_double.v, sizeof (padding_long_double.v));
+ fill (&padding_long_double.p2, sizeof (padding));
+}
+
+int
+main ()
+{
+ fill_structs ();
+
+ printf ("sizeof (char) == %d\n", sizeof (char));
+ printf ("sizeof (short) == %d\n", sizeof (short));
+ printf ("sizeof (int) == %d\n", sizeof (int));
+ printf ("sizeof (long) == %d\n", sizeof (long));
+ printf ("sizeof (long long) == %d\n", sizeof (long long));
+
+ printf ("sizeof (void *) == %d\n", sizeof (void*));
+ printf ("sizeof (void (*)(void)) == %d\n", sizeof (void (*)(void)));
+
+ printf ("sizeof (float) == %d\n", sizeof (float));
+ printf ("sizeof (double) == %d\n", sizeof (double));
+ printf ("sizeof (long double) == %d\n", sizeof (long double));
+
+ /* Signed char? */
+ printf ("valueof ((int) (char) -1) == %d\n", (int) (char) -1);
+ printf ("valueof ((int) (signed char) -1) == %d\n", (int) (signed char) -1);
+ printf ("valueof ((int) (unsigned char) -1) == %d\n", (int) (unsigned char) -1);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/sizeof.exp b/gdb/testsuite/gdb.base/sizeof.exp
new file mode 100644
index 00000000000..7c0390588a0
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sizeof.exp
@@ -0,0 +1,208 @@
+# Copyright 2000, 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "sizeof"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+#
+# Query GDB for the size of various types
+#
+
+proc get_valueof { fmt exp default } {
+ global gdb_prompt
+ send_gdb "print${fmt} ${exp}\n"
+ gdb_expect {
+ -re "\\$\[0-9\]* = (\[-\]*\[0-9\]*).*$gdb_prompt $" {
+ set val $expect_out(1,string)
+ pass "get value of ${exp} ($val)"
+ }
+ timeout {
+ set size ${default}
+ fail "get value of ${exp} (timeout)"
+ }
+ }
+ return ${val}
+}
+
+proc get_sizeof { type default } {
+ return [get_valueof "/d" "sizeof (${type})" $default]
+}
+
+gdb_test "next"
+
+set sizeof_char [get_sizeof "char" 1]
+set sizeof_short [get_sizeof "short" 2]
+set sizeof_int [get_sizeof "int" 4]
+set sizeof_long [get_sizeof "long" 4]
+set sizeof_long_long [get_sizeof "long long" 8]
+
+set sizeof_data_ptr [get_sizeof "void *" 4]
+set sizeof_func_ptr [get_sizeof "void (*)(void)" 4]
+
+set sizeof_float [get_sizeof "float" 4]
+set sizeof_double [get_sizeof "double" 8]
+set sizeof_long_double [get_sizeof "long double" 8]
+
+#
+# Compare GDB's idea of types with the running program
+#
+
+proc check_sizeof { type size } {
+ global gdb_prompt
+
+ if [gdb_skip_stdio_test "check sizeof $type == $size"] {
+ return;
+ }
+
+ set pat [string_to_regexp "sizeof (${type}) == ${size}"]
+ send_gdb "next\n"
+ gdb_expect {
+ -re "${pat}\[\r\n\].*$gdb_prompt $" {
+ pass "check sizeof ${type} == ${size}"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "check sizeof ${type} == ${size}"
+ }
+ timeout {
+ fail "check sizeof ${type} == ${size} (timeout)"
+ }
+ }
+}
+
+check_sizeof "char" ${sizeof_char}
+check_sizeof "short" ${sizeof_short}
+check_sizeof "int" ${sizeof_int}
+check_sizeof "long" ${sizeof_long}
+check_sizeof "long long" ${sizeof_long_long}
+
+check_sizeof "void *" ${sizeof_data_ptr}
+check_sizeof "void (*)(void)" ${sizeof_func_ptr}
+
+check_sizeof "float" ${sizeof_float}
+check_sizeof "double" ${sizeof_double}
+check_sizeof "long double" ${sizeof_long_double}
+
+proc check_valueof { exp val } {
+ global gdb_prompt
+
+ if [gdb_skip_stdio_test "check valueof $exp == $val"] {
+ return;
+ }
+
+ set pat [string_to_regexp "valueof (${exp}) == ${val}"]
+ send_gdb "next\n"
+ gdb_expect {
+ -re "${pat}\[\r\n\].*$gdb_prompt $" {
+ pass "check valueof ${exp} == ${val}"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "check valueof ${exp} == ${val}"
+ }
+ timeout {
+ fail "check valueof ${exp} == ${val} (timeout)"
+ }
+ }
+}
+
+# Check that GDB and the target agree over the sign of a character.
+
+set signof_char [get_valueof "/d" "(int) (char) -1" -1]
+set signof_signed_char [get_valueof "/d" "(int) (signed char) -1" -1]
+set signof_unsigned_char [get_valueof "/d" "(int) (unsigned char) -1" -1]
+
+check_valueof "(int) (char) -1" ${signof_char}
+check_valueof "(int) (signed char) -1" ${signof_signed_char}
+check_valueof "(int) (unsigned char) -1" ${signof_unsigned_char}
+
+proc check_padding { fmt type val } {
+ global gdb_prompt
+ gdb_test "set padding_${type}.v = ${val}"
+ gdb_test "print padding_${type}.p1" "= \"The quick brown \""
+ gdb_test "print${fmt} padding_${type}.v" "= ${val}"
+ gdb_test "print padding_${type}.p2" "\"The quick brown \".*"
+}
+
+# Check that GDB is managing to store a value in a struct field
+# without corrupting the fields immediately adjacent to it.
+
+check_padding "/d" "char" 1
+check_padding "/d" "short" 2
+check_padding "/d" "int" 4
+check_padding "/d" "long" 4
+check_padding "/d" "long_long" 8
+
+# use multiples of two which can be represented exactly
+check_padding "/f" "float" 1
+check_padding "/f" "double" 2
+check_padding "/f" "long_double" 4
+
+#
+# For reference, dump out the entire architecture
+#
+# The output is very long so use a while loop to consume it
+send_gdb "maint print arch\n"
+set ok 1
+while { $ok } {
+ gdb_expect {
+ -re ".*dump" {
+ #pass "maint print arch $ok"
+ #set ok [expr $ok + 1]
+ }
+ -re "$gdb_prompt $" {
+ pass "maint print arch"
+ set ok 0
+ }
+ timeout {
+ fail "maint print arch (timeout)"
+ set ok 0
+ }
+ }
+}
diff --git a/gdb/testsuite/gdb.base/so-impl-ld.c b/gdb/testsuite/gdb.base/so-impl-ld.c
new file mode 100644
index 00000000000..9310bca1421
--- /dev/null
+++ b/gdb/testsuite/gdb.base/so-impl-ld.c
@@ -0,0 +1,23 @@
+/* This program is linked against SOM shared libraries, which the loader
+ automatically loads along with the program itself).
+ */
+
+#include <stdio.h>
+
+#if defined(__cplusplus) || defined(__STDCPP__)
+extern "C" int solib_main (int arg);
+#else
+int solib_main (int arg);
+#endif
+
+int main ()
+{
+ int result;
+
+ /* Call a shlib function. */
+ result = solib_main (100);
+
+ /* Call it again. */
+ result = solib_main (result);
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/so-impl-ld.exp b/gdb/testsuite/gdb.base/so-impl-ld.exp
new file mode 100644
index 00000000000..68a1bf41c00
--- /dev/null
+++ b/gdb/testsuite/gdb.base/so-impl-ld.exp
@@ -0,0 +1,172 @@
+# Copyright 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+set prms_id 0
+set bug_id 0
+
+# are we on a target board
+if ![isnative] then {
+ return
+}
+
+# This test is presently only valid on HP-UX, since it requires
+# that we use HP-UX-specific compiler & linker options to build
+# the testcase.
+# Actually this test works on solaris, and linux too.
+
+if {! ([istarget "hppa*-*-*hpux*"]
+ || [istarget "sparc-sun-solaris*"]
+ || [istarget "*-*-linux-gnu*"]) } {
+ return
+}
+
+set libfile "solib"
+set testfile "so-impl-ld"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+# Build the shared libraries this test case needs.
+#
+#cd ${subdir}
+#remote_exec build "$CC -g +z -c ${libfile}1.c -o ${libfile}1.o"
+
+
+if {$gcc_compiled == 0} {
+ if [istarget "hppa*-hp-hpux*"] then {
+ set additional_flags "additional_flags=+z"
+ } else {
+ # don't know that the compiler is, hope for the best...
+ set additional_flags ""
+ }
+} else {
+ set additional_flags "additional_flags=-fpic"
+}
+
+if {[gdb_compile "${srcdir}/${subdir}/${libfile}1.c" "${libfile}1.o" object [list debug $additional_flags]] != ""} {
+ perror "Couldn't compile ${libfile}1.c"
+ return -1
+}
+
+if [istarget "hppa*-hp-hpux*"] then {
+ remote_exec build "ld -b ${libfile}1.o -o ${objdir}/${subdir}/${libfile}1.sl"
+} else {
+ set additional_flags "additional_flags=-shared"
+ gdb_compile "${libfile}1.o" "${objdir}/${subdir}/${libfile}1.sl" executable [list debug $additional_flags]
+}
+
+# Build the test case
+#remote_exec build "$CC -Aa -g ${srcfile} ${libfile}1.sl -o ${binfile}"
+
+
+if {$hp_cc_compiler} {
+ set additional_flags "additional_flags=-Ae"
+} else {
+ set additional_flags ""
+}
+
+if {[gdb_compile "${srcdir}/${subdir}/${srcfile} ${objdir}/${subdir}/${libfile}1.sl" "${binfile}" executable [list debug $additional_flags]] != ""} {
+ perror "Couldn't build ${binfile}"
+ return -1
+}
+#cd ..
+
+# Start with a fresh gdb
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# This program implicitly loads SOM shared libraries.
+#
+if ![runto_main] then { fail "implicit solibs tests suppressed" }
+
+# Verify that we can step over the first shlib call.
+#
+send_gdb "next\n"
+gdb_expect {
+ -re "21\[ \t\]*result = solib_main .result.*$gdb_prompt $"\
+ {pass "step over solib call"}
+ -re "$gdb_prompt $"\
+ {fail "step over solib call"}
+ timeout {fail "(timeout) step over solib call"}
+}
+
+# Verify that we can step into the second shlib call.
+#
+send_gdb "step\n"
+gdb_expect {
+ -re "solib_main .arg=10000. at.*${libfile}1.c:17.*$gdb_prompt $"\
+ {pass "step into solib call"}
+ -re "$gdb_prompt $"\
+ {fail "step into solib call"}
+ timeout {fail "(timeout) step into solib call"}
+}
+
+# Verify that we can step within the shlib call.
+#
+send_gdb "next\n"
+gdb_expect {
+ -re "18\[ \t\]*\}.*$gdb_prompt $"\
+ {pass "step in solib call"}
+ -re "$gdb_prompt $"\
+ {fail "step in solib call"}
+ timeout {fail "(timeout) step in solib call"}
+}
+
+# Verify that we can step out of the shlib call, and back out into
+# the caller.
+#
+send_gdb "next\n"
+gdb_expect {
+ -re "0x\[0-9a-f\]*\[ \t\]*9\[ \t\]*.*$gdb_prompt $" {
+ # we haven't left the callee yet, so do another next
+ send_gdb "next\n"
+ gdb_expect {
+ -re "main .. at.*so-impl-ld.c:22.*$gdb_prompt $"\
+ {pass "step out of solib call"}
+ -re "$gdb_prompt $"\
+ {fail "step out of solib call"}
+ timeout {fail "(timeout) step out of solib call"}
+ }
+ }
+
+ -re "main .. at.*so-impl-ld.c:22.*$gdb_prompt $"\
+ {pass "step out of solib call"}
+ -re "$gdb_prompt $"\
+ {fail "step out of solib call"}
+ timeout {fail "(timeout) step out of solib call"}
+}
+
+gdb_exit
+return 0
+
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.base/so-indr-cl.c b/gdb/testsuite/gdb.base/so-indr-cl.c
new file mode 100644
index 00000000000..f31800d04bf
--- /dev/null
+++ b/gdb/testsuite/gdb.base/so-indr-cl.c
@@ -0,0 +1,30 @@
+/* This program is linked against SOM shared libraries, which the loader
+ automatically loads along with the program itself).
+ */
+
+#include <stdio.h>
+#ifdef PROTOTYPES
+extern "C" int solib_main (int);
+
+static int
+solib_wrapper (int (*function)(int))
+#else
+extern int solib_main (int);
+
+static int
+solib_wrapper (function)
+ int (*function)(int);
+#endif
+{
+ return (*function)(100);
+}
+
+
+int main ()
+{
+ int result;
+
+ /* This is an indirect call to solib_main. */
+ result = solib_wrapper (solib_main);
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/so-indr-cl.exp b/gdb/testsuite/gdb.base/so-indr-cl.exp
new file mode 100644
index 00000000000..1232cebabe9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/so-indr-cl.exp
@@ -0,0 +1,139 @@
+# Copyright 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+set prms_id 0
+set bug_id 0
+
+# are we on a target board
+if ![isnative] then {
+ return
+}
+
+# This test is presently only valid on HP-UX, since it requires
+# that we use HP-UX-specific compiler & linker options to build
+# the testcase.
+#
+if {! [istarget "hppa*-*-*hpux*"] } {
+ return
+}
+
+set libfile "solib"
+set testfile "so-indr-cl"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+# Build the shared libraries this test case needs.
+#
+#cd ${subdir}
+#remote_exec build "$CC -g +z -c ${libfile}1.c -o ${libfile}1.o"
+
+
+if {$hp_cc_compiler || $hp_aCC_compiler} {
+ set additional_flags "additional_flags=+z"
+} else {
+ set additional_flags "additional_flags=-fpic"
+}
+if {[gdb_compile "${srcdir}/${subdir}/${libfile}1.c" "${objdir}/${subdir}/${libfile}1.o" object [list debug $additional_flags]] != ""} {
+ perror "Couldn't compile ${libfile}1.c"
+ return -1
+}
+
+if [istarget "hppa*-hp-hpux*"] then {
+ remote_exec build "ld -b ${objdir}/${subdir}/${libfile}1.o -o ${objdir}/${subdir}/${libfile}1.sl"
+} else {
+ set additional_flags "additional_flags=-shared"
+ gdb_compile "${objdir}/${subdir}/${libfile}1.o" "${objdir}/${subdir}/${libfile}1.sl" executable [list debug $additional_flags]
+}
+
+# Build the test case
+#remote_exec build "$CC -Aa -g ${srcfile} ${libfile}1.sl -o ${binfile}"
+
+
+if {$hp_cc_compiler} {
+ set additional_flags "additional_flags=-Ae"
+} else {
+ set additional_flags ""
+}
+if {[gdb_compile "${srcdir}/${subdir}/${srcfile} ${objdir}/${subdir}/${libfile}1.sl" "${binfile}" executable [list debug $additional_flags]] != ""} {
+ perror "Couldn't build ${binfile}"
+ return -1
+}
+
+#cd ..
+
+# Start with a fresh gdb
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# This program implicitly loads SOM shared libraries. We wish to test
+# whether a user can set breakpoints in a shlib before running the
+# program, where the program doesn't directly call the shlib, but
+# indirectly does via passing its address to another function.
+#
+# ??rehrauer: Currently, this doesn't work, but we do catch the case
+# and explicitly disallow it. The reason it fails appears to be that
+#
+# [1] gdb consults only the linker symbol table in this scenario, and
+# [2] For a shlib function that is only indirectly called from the
+# main a.out, there is in the linker symbol table a stub whose
+# address is negative. Possibly this is to be interpreted as
+# an index into the DLT??
+#
+send_gdb "break solib_main\n"
+gdb_expect {
+ -re "Cannot break on solib_main without a running program.*$gdb_prompt $"\
+ {pass "break on indirect solib call before running"}
+ -re "Breakpoint.*deferred.*\\(\"solib_main\" was not found.*$gdb_prompt $"\
+ {pass "break on indirect solib call before running 2"}
+ -re "$gdb_prompt $"\
+ {fail "break on indirect solib call before running"}
+ timeout {fail "(timeout) break on indirect solib call before running"}
+}
+
+# However, if we do run to the program's main, we then ought to be
+# able to set a breakpoint on the indirectly called function. (Apparently,
+# once the inferior is running, gdb consults the debug info rather than
+# the linker symbol table, and is able to find the correct address.)
+#
+if ![runto_main] then { fail "indirect solib call tests suppressed" }
+
+# Verify that we can step over the first shlib call.
+#
+send_gdb "break solib_main\n"
+gdb_expect {
+ -re ".*\[Bb\]reakpoint \[0-9\]* at 0x\[0-9a-fA-F\]*: file.*${libfile}1.c.*$gdb_prompt $"\
+ {pass "break on indirect solib call after running"}
+ -re "$gdb_prompt $"\
+ {fail "break on indirect solib call after running"}
+ timeout {fail "(timeout) break on indirect solib call after running"}
+}
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.base/solib.c b/gdb/testsuite/gdb.base/solib.c
new file mode 100644
index 00000000000..6fb9f5e11da
--- /dev/null
+++ b/gdb/testsuite/gdb.base/solib.c
@@ -0,0 +1,60 @@
+/* This program uses HP-UX-specific features to load and unload SOM
+ shared libraries that it wasn't linked against (i.e., libraries
+ that the loader doesn't automatically load along with the program
+ itself).
+ */
+
+#include <stdio.h>
+#include <dl.h>
+
+int main ()
+{
+ shl_t solib_handle;
+ int dummy;
+ int status;
+ int (*solib_main) (int);
+
+ /* Load a shlib, with immediate binding of all symbols.
+
+ Note that the pathname of the loaded shlib is assumed to be relative
+ to the testsuite directory (from whence the tested GDB is run), not
+ from dot/.
+ */
+ dummy = 1; /* Put some code between shl_ calls... */
+ solib_handle = shl_load ("gdb.base/solib1.sl", BIND_IMMEDIATE, 0);
+
+ /* Find a function within the shlib, and call it. */
+ status = shl_findsym (&solib_handle,
+ "solib_main",
+ TYPE_PROCEDURE,
+ (long *) &solib_main);
+ status = (*solib_main) (dummy);
+
+ /* Unload the shlib. */
+ status = shl_unload (solib_handle);
+
+ /* Load a different shlib, with deferred binding of all symbols. */
+ dummy = 2;
+ solib_handle = shl_load ("gdb.base/solib2.sl", BIND_DEFERRED, 0);
+
+ /* Find a function within the shlib, and call it. */
+ status = shl_findsym (&solib_handle,
+ "solib_main",
+ TYPE_PROCEDURE,
+ (long *) &solib_main);
+ status = (*solib_main) (dummy);
+
+ /* Unload the shlib. */
+ status = shl_unload (solib_handle);
+
+ /* Reload the first shlib again, with deferred symbol binding this time. */
+ dummy = 3;
+ solib_handle = shl_load ("gdb.base/solib1.sl", BIND_IMMEDIATE, 0);
+
+ /* Unload it without trying to find any symbols in it. */
+ status = shl_unload (solib_handle);
+
+ /* All done. */
+ dummy = -1;
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/solib.exp b/gdb/testsuite/gdb.base/solib.exp
new file mode 100644
index 00000000000..3ce0edb7185
--- /dev/null
+++ b/gdb/testsuite/gdb.base/solib.exp
@@ -0,0 +1,360 @@
+# Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+set prms_id 0
+set bug_id 0
+
+# are we on a target board
+if ![isnative] then {
+ return
+}
+
+# This test is presently only valid on HP-UX. It verifies GDB's
+# ability to catch loads and unloads of shared libraries.
+#
+
+#setup_xfail "*-*-*"
+#clear_xfail "hppa*-*-*hpux*"
+if {![istarget "hppa*-*-hpux*"]} {
+ return 0
+}
+
+set testfile "solib"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# build the first test case
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+# Build the shared libraries this test case needs.
+#
+#cd ${subdir}
+#remote_exec build "$CC -g +z -c ${testfile}1.c -o ${testfile}1.o"
+#remote_exec build "$CC -g +z -c ${testfile}2.c -o ${testfile}2.o"
+
+if {$gcc_compiled == 0} {
+ if [istarget "hppa*-hp-hpux*"] then {
+ set additional_flags "additional_flags=+z"
+ } else {
+ # don't know what the compiler is...
+ set additional_flags ""
+ }
+} else {
+ set additional_flags "additional_flags=-fpic"
+}
+
+if {[gdb_compile "${srcdir}/${subdir}/${testfile}1.c" "${binfile}1.o" object [list debug $additional_flags]] != ""} {
+ perror "Couldn't compile ${testfile}1.c"
+ #return -1
+}
+if {[gdb_compile "${srcdir}/${subdir}/${testfile}2.c" "${binfile}2.o" object [list debug, $additional_flags]] != ""} {
+ perror "Couldn't compile ${testfile}2.c"
+ #return -1
+}
+
+if [istarget "hppa*-*-hpux*"] {
+ remote_exec build "ld -b ${binfile}1.o -o ${binfile}1.sl"
+ remote_exec build "ld -b ${binfile}2.o -o ${binfile}2.sl"
+} else {
+ set additional_flags "additional_flags=-shared"
+ gdb_compile "${binfile}1.o" "${binfile}1.sl" executable [list debug $additional_flags]
+ gdb_compile "${binfile}2.o" "${binfile}2.sl" executable [list debug $additional_flags]
+}
+
+# Build a version where the main program is in a shared library. For
+# testing an indirect call made in a shared library.
+
+if {[gdb_compile "${srcdir}/${subdir}/${testfile}.c" "${binfile}_sl.o" object [list debug $additional_flags]] != ""} {
+ perror "Couldn't compile ${testfile}.c for ${binfile}_sl.o"
+ #return -1
+}
+
+if { [istarget "hppa*-*-hpux*"] } {
+ remote_exec build "ld -b ${binfile}_sl.o -o ${binfile}_sl.sl"
+} else {
+ set additional_flags "additional_flags=-shared"
+ gdb_compile "${binfile}_sl.o" "${binfile}_sl.sl" executable [list debug $additional_flags]
+}
+
+if { [istarget "hppa*-*-hpux*"] } {
+ set additional_flags "-Wl,-u,main"
+ if { [gdb_compile "${binfile}_sl.sl" "${binfile}_sl" executable [list debug $additional_flags]] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+} else {
+ # FIXME: need to fill this part in for non-HP build
+}
+
+#cd ..
+
+# Start with a fresh gdb
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# This program manually loads and unloads SOM shared libraries, via calls
+# to shl_load and shl_unload.
+#
+if ![runto_main] then { fail "catch load/unload tests suppressed" }
+
+# Verify that we complain if the user tells us to catch something we
+# don't understand.
+#
+send_gdb "catch a_cold\n"
+gdb_expect {
+ -re "Unknown event kind specified for catch.*$gdb_prompt $"\
+ {pass "bogus catch kind is disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "bogus catch kind is disallowed"}
+ timeout {fail "(timeout) bogus catch kind is disallowed"}
+}
+
+# Verify that we can set a generic catchpoint on shlib loads. I.e., that
+# we can catch any shlib load, without specifying the name.
+#
+send_gdb "catch load\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\]* .load <any library>.*$gdb_prompt $"\
+ {pass "set generic catch load"}
+ -re "$gdb_prompt $"\
+ {fail "set generic catch load"}
+ timeout {fail "(timeout) set generic catch load"}
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\] .loaded gdb.base/solib1.sl.*$gdb_prompt $"\
+ {pass "caught generic solib load"}
+ -re "$gdb_prompt $"\
+ {fail "caught generic solib load"}
+ timeout {fail "(timeout) caught generic solib load"}
+}
+
+# Set a breakpoint on the line following the shl_load call, and
+# continue.
+#
+# ??rehrauer: It appears that we can't just say "finish" from here;
+# GDB is getting confused by the dld's presense on the stack.
+#
+send_gdb "break 27\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]* at.*$gdb_prompt $"\
+ {pass "set break after shl_load"}
+ -re "$gdb_prompt $"\
+ {fail "set break after shl_load"}
+ timeout {fail "(timeout) set break after shl_load"}
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]*, main .. at .*solib.c:27.*$gdb_prompt $"\
+ {pass "continue after generic catch load"}
+ -re "$gdb_prompt $"\
+ {fail "continue after generic catch load"}
+ timeout {fail "(timeout) continue after generic catch load"}
+}
+
+# Step over the call to shl_findsym.
+#
+# ??rehrauer: In theory, since the call to shl_load asked for
+# immediate binding of the shlib's symbols, and since the
+# shlib's symbols should have been auto-loaded, we ought to
+# be able to set a breakpoint on solib_main now. However,
+# that seems not to be the case. Dunno why for sure; perhaps
+# the breakpoint wants to be set on an import stub in the
+# main program for solib_main? There wouldn't be one, in
+# this case...
+#
+send_gdb "next\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "step over shl_findsym"}
+ timeout {fail "(timeout) step over shl_findsym"}
+}
+
+# Verify that we can catch an unload of any library.
+#
+send_gdb "catch unload\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\]* .unload <any library>.*$gdb_prompt $"\
+ {pass "set generic catch unload"}
+ -re "$gdb_prompt $"\
+ {fail "set generic catch unload"}
+ timeout {fail "(timeout) set generic catch load"}
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\] .unloaded gdb.base/solib1.sl.*$gdb_prompt $"\
+ {pass "caught generic solib unload"}
+ -re "$gdb_prompt $"\
+ {fail "caught generic solib unload"}
+ timeout {fail "(timeout) caught generic solib unload"}
+}
+
+# Verify that we can catch a load of a specific library. (Delete
+# all the other catchpoints first, so that the generic catchpoints
+# we've previously set don't trigger.)
+#
+send_gdb "delete\n"
+gdb_expect {
+ -re "Delete all breakpoints.*y or n.*"\
+ {send_gdb "y\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "delete all catchpoints"}
+ timeout {fail "(timeout) delete all catchpoints"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "delete all catchpoints"}
+ timeout {fail "(timeout) delete all catchpoints"}
+}
+
+send_gdb "catch load gdb.base/solib2.sl\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\]* .load gdb.base/solib2.sl.*$gdb_prompt $"\
+ {pass "set specific catch load"}
+ -re "$gdb_prompt $"\
+ {fail "set specific catch load"}
+ timeout {fail "(timeout) set specific catch load"}
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\] .loaded gdb.base/solib2.sl.*$gdb_prompt $"\
+ {pass "caught specific solib load"}
+ -re "$gdb_prompt $"\
+ {fail "caught specific solib load"}
+ timeout {fail "(timeout) caught specific solib load"}
+}
+
+# Verify that we can catch an unload of a specific library.
+#
+send_gdb "catch unload gdb.base/solib2.sl\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\]* .unload gdb.base/solib2.sl.*$gdb_prompt $"\
+ {pass "set specific catch unload"}
+ -re "$gdb_prompt $"\
+ {fail "set specific catch unload"}
+ timeout {fail "(timeout) set specific catch unload"}
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\] .unloaded gdb.base/solib2.sl.*$gdb_prompt $"\
+ {pass "caught specific solib unload"}
+ -re "$gdb_prompt $"\
+ {fail "caught specific solib unload"}
+ timeout {fail "(timeout) caught specific solib unload"}
+}
+
+# Verify that we can set a catchpoint on a specific library that
+# happens not to be loaded by the program. And, that this catchpoint
+# won't trigger inappropriately when other shlibs are loaded.
+#
+send_gdb "break 55\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]* at.*$gdb_prompt $"\
+ {pass "set break on shl_unload"}
+ -re "$gdb_prompt $"\
+ {fail "set break on shl_unload"}
+ timeout {fail "(timeout) set break on shl_unload"}
+}
+
+send_gdb "break 58\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]* at.*$gdb_prompt $"\
+ {pass "set break after shl_unload"}
+ -re "$gdb_prompt $"\
+ {fail "set break after shl_unload"}
+ timeout {fail "(timeout) set break after shl_unload"}
+}
+
+send_gdb "catch load foobar.sl\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\]* .load foobar.sl.*$gdb_prompt $"\
+ {pass "set specific catch load for nonloaded shlib"}
+ -re "$gdb_prompt $"\
+ {fail "set specific catch load for nonloaded shlib"}
+ timeout {fail "(timeout) set specific catch load for nonloaded shlib"}
+}
+
+send_gdb "catch unload foobar.sl\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\]* .unload foobar.sl.*$gdb_prompt $"\
+ {pass "set specific catch unload for nonloaded shlib"}
+ -re "$gdb_prompt $"\
+ {fail "set specific catch unload for nonloaded shlib"}
+ timeout {fail "(timeout) set specific catch unload for nonloaded shlib"}
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]*.*$gdb_prompt $"\
+ {pass "specific catch load doesn't trigger inappropriately"}
+ -re "$gdb_prompt $"\
+ {fail "specific catch load doesn't trigger inappropriately"}
+ timeout {fail "(timeout) specific catch load doesn't trigger inappropriately"}
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]*.*$gdb_prompt $"\
+ {pass "specific catch unload doesn't trigger inappropriately"}
+ -re "$gdb_prompt $"\
+ {fail "specific catch unload doesn't trigger inappropriately"}
+ timeout {fail "(timeout) specific catch unload doesn't trigger inappropriately"}
+}
+
+# ??rehrauer: There ought to be testpoints here that verify that
+# load/unload catchpoints can use conditionals, can be temporary,
+# self-disabling, etc etc.
+#
+
+gdb_exit
+
+#
+# Test stepping into an indirect call in a shared library.
+#
+
+gdb_start
+gdb_load ${binfile}_sl
+gdb_test "break main" ".*deferred. at .main..*" "break on main"
+gdb_test "run" ".*Breakpoint.*main.*solib.c.*" "hit breakpoint at main"
+gdb_test "break 45" "Breakpoint.*solib.c, line 45.*" "break on indirect call"
+gdb_test "continue" "Continuing.*solib.c:45.*" \
+ "continue to break on indirect call"
+gdb_test "step" "solib_main.*solib1.c:17.*return arg.arg.*" \
+ "step into indirect call from a shared library"
+gdb_exit
+
+return 0
diff --git a/gdb/testsuite/gdb.base/solib1.c b/gdb/testsuite/gdb.base/solib1.c
new file mode 100644
index 00000000000..2e517504505
--- /dev/null
+++ b/gdb/testsuite/gdb.base/solib1.c
@@ -0,0 +1,18 @@
+/* This program is intended to be built as an HP-UX SOM shared
+ library, for use by the solib.exp testcase. It simply returns
+ the square of its integer argument.
+ */
+#if defined(__cplusplus) || defined(__STDCPP__)
+extern "C" int
+solib_main (int arg)
+#else
+#ifdef PROTOTYPES
+int solib_main (int arg)
+#else
+int solib_main (arg)
+ int arg;
+#endif
+#endif
+{
+ return arg*arg;
+}
diff --git a/gdb/testsuite/gdb.base/solib2.c b/gdb/testsuite/gdb.base/solib2.c
new file mode 100644
index 00000000000..8c69d8b273e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/solib2.c
@@ -0,0 +1,19 @@
+/* This program is intended to be built as an HP-UX SOM shared
+ library, for use by the solib.exp testcase. It simply returns
+ the cube of its integer argument.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef PROTOTYPES
+int solib_main (int arg)
+#else
+int solib_main (arg)
+ int arg;
+#endif
+{
+ return arg*arg*arg;
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/gdb/testsuite/gdb.base/ss.h b/gdb/testsuite/gdb.base/ss.h
new file mode 100644
index 00000000000..2a4c162dcd6
--- /dev/null
+++ b/gdb/testsuite/gdb.base/ss.h
@@ -0,0 +1,4 @@
+struct s {
+ int a;
+ int b;
+};
diff --git a/gdb/testsuite/gdb.base/step-line.c b/gdb/testsuite/gdb.base/step-line.c
new file mode 100644
index 00000000000..f961120ab1c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/step-line.c
@@ -0,0 +1,84 @@
+/* Test step/next in presence of #line directives.
+ Copyright 2001
+ 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. */
+
+void dummy (int, int);
+int f1 (int);
+int f2 (int);
+
+int
+main (int argc, char **argv)
+{
+ int i;
+ i = f1 (4);
+ i = f1 (i);
+ dummy (0, i);
+ return 0;
+}
+
+int
+f1 (int i)
+{
+#line 40 "step-line.c"
+ dummy (1, i);
+#line 24 "step-line.inp"
+ i = f2 (i);
+#line 44 "step-line.c"
+ dummy (2, i);
+#line 25 "step-line.inp"
+ i = f2 (i);
+#line 48 "step-line.c"
+ dummy (3, i);
+#line 26 "step-line.inp"
+ return i;
+#line 52 "step-line.c"
+}
+
+int
+f2 (int i)
+{
+#line 31 "step-line.inp"
+ int j;
+#line 60 "step-line.c"
+ dummy (4, i);
+#line 32 "step-line.inp"
+ j = i;
+#line 64 "step-line.c"
+ dummy (5, i);
+ dummy (6, j);
+#line 33 "step-line.inp"
+ j = j + 1;
+#line 69 "step-line.c"
+ dummy (7, i);
+ dummy (8, j);
+#line 34 "step-line.inp"
+ j = j - i;
+#line 74 "step-line.c"
+ dummy (9, i);
+ dummy (10, j);
+#line 35 "step-line.inp"
+ return i;
+#line 79 "step-line.c"
+}
+
+void
+dummy (int num, int i)
+{
+}
diff --git a/gdb/testsuite/gdb.base/step-line.exp b/gdb/testsuite/gdb.base/step-line.exp
new file mode 100644
index 00000000000..cac3128fcec
--- /dev/null
+++ b/gdb/testsuite/gdb.base/step-line.exp
@@ -0,0 +1,95 @@
+# Copyright 2001 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+# use this to debug:
+#
+#log_user 1
+
+# step-line.exp -- Expect script to test stepping in files with
+# #line directives.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile step-line
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+remote_exec build "rm -f ${binfile}"
+if { [gdb_compile "${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+gdb_test "break f1" ".*Breakpoint 2 at .* file step-line.c.*" "break f1"
+gdb_test "continue" \
+ "Continuing.*Breakpoint 2, f1 \\(i=4\\).*dummy \\(1, i\\);" \
+ "continue to f1"
+gdb_test "next" \
+ ".*i = f2 \\(i\\);.*" \
+ "next over dummy 1"
+gdb_test "next" \
+ ".*dummy \\(2, i\\);.*" \
+ "next to dummy 2"
+gdb_test "next" \
+ ".*i = f2 \\(i\\);.*" \
+ "next over dummy 2"
+gdb_test "step" \
+ ".*f2 \\(i=4\\).*dummy \\(4, i\\);.*" \
+ "step into f2"
+gdb_test "next" \
+ ".*j = i;.*" \
+ "next over dummy 4"
+gdb_test "next" \
+ ".*dummy \\(5, i\\);.*" \
+ "next to dummy 5"
+gdb_test "next" \
+ ".*dummy \\(6, j\\);.*" \
+ "next to dummy 6"
+gdb_test "next" \
+ ".*j = SUCC \\(j\\);.*" \
+ "next over dummy 6"
+gdb_test "next" \
+ ".*dummy \\(7, i\\);.*" \
+ "next to dummy 7"
+gdb_test "next" \
+ ".*dummy \\(8, j\\);.*" \
+ "next to dummy 8"
+gdb_test "next" \
+ ".*j = j - i;.*" \
+ "next over dummy 8"
+gdb_test "next" \
+ ".*dummy \\(9, i\\);.*" \
+ "next to dummy 9"
+gdb_test "next" \
+ ".*dummy \\(10, j\\);.*" \
+ "next to dummy 10"
+gdb_test "next" \
+ ".*RETURN \\(j\\);.*" \
+ "next over dummy 10"
+return 0
diff --git a/gdb/testsuite/gdb.base/step-line.inp b/gdb/testsuite/gdb.base/step-line.inp
new file mode 100644
index 00000000000..f4060a94152
--- /dev/null
+++ b/gdb/testsuite/gdb.base/step-line.inp
@@ -0,0 +1,41 @@
+# Test step/next in presence of #line directives
+# Copyright 2001
+# Free Software Foundation, Inc.
+
+# 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. */
+
+# We pretend that this file has been transformed by some other tool
+# into step-line.c.
+
+FUNCTION f1 (i : INTEGER);
+ BEGIN
+ i = f2 (i);
+ i = f2 (i);
+ RETURN (i);
+ END
+
+FUNCTION f2 (i : INTEGER);
+ BEGIN
+ VARIABLE j : INTEGER
+ j = i;
+ j = SUCC (j);
+ j = j - i;
+ RETURN (j);
+ END
+
+BEGIN
+ VARIABLE i : INTEGER;;
+
+END
diff --git a/gdb/testsuite/gdb.base/step-test.c b/gdb/testsuite/gdb.base/step-test.c
new file mode 100644
index 00000000000..a1e1dc408cf
--- /dev/null
+++ b/gdb/testsuite/gdb.base/step-test.c
@@ -0,0 +1,61 @@
+#include <stdlib.h>
+#include <string.h>
+
+/* Test various kinds of stepping.
+*/
+int myglob = 0;
+
+int callee() {
+ myglob++; return 0;
+}
+
+/* A structure which, we hope, will need to be passed using memcpy. */
+struct rhomboidal {
+ int rather_large[100];
+};
+
+void
+large_struct_by_value (struct rhomboidal r)
+{
+ myglob += r.rather_large[42]; /* step-test.exp: arrive here 1 */
+}
+
+int main () {
+ int w,x,y,z;
+ int a[10], b[10];
+
+ /* Test "next" and "step" */
+ w = 0;
+ x = 1;
+ y = 2;
+ z = 3;
+ w = w + 2;
+ x = x + 3;
+ y = y + 4;
+ z = z + 5;
+
+ /* Test that "next" goes over a call */
+ callee(); /* OVER */
+
+ /* Test that "step" doesn't */
+ callee(); /* INTO */
+
+ /* Test "stepi" */
+ a[5] = a[3] - a[4];
+ callee(); /* STEPI */
+
+ /* Test "nexti" */
+ callee(); /* NEXTI */
+
+ y = w + z;
+
+ {
+ struct rhomboidal r;
+ memset (r.rather_large, 0, sizeof (r.rather_large));
+ r.rather_large[42] = 10;
+ large_struct_by_value (r); /* step-test.exp: large struct by value */
+ }
+
+ exit (0);
+}
+
diff --git a/gdb/testsuite/gdb.base/step-test.exp b/gdb/testsuite/gdb.base/step-test.exp
new file mode 100644
index 00000000000..9a21136996c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/step-test.exp
@@ -0,0 +1,241 @@
+# Copyright 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# use this to debug:
+#
+#log_user 1
+
+# step-test.exp -- Expect script to test stepping in gdb
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile step-test
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+remote_exec build "rm -f ${binfile}"
+if { [gdb_compile "${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+# Set a breakpoint at line 45, if stepi then finish fails, we would
+# run to the end of the program, which would mess up the rest of the tests.
+
+# Vanilla step/next
+#
+gdb_test "next" ".*${decimal}.*x = 1;.*" "next 1"
+gdb_test "step" ".*${decimal}.*y = 2;.*" "step 1"
+
+# With count
+#
+gdb_test "next 2" ".*${decimal}.*w = w.*2;.*" "next 2"
+gdb_test "step 3" ".*${decimal}.*z = z.*5;.*" "step 3"
+gdb_test "next" ".*${decimal}.*callee.*OVER.*" "next 3"
+
+# Step over call
+#
+gdb_test "next" ".*${decimal}.*callee.*INTO.*" "next over"
+
+# Step into call
+#
+gdb_test "step" ".*${decimal}.*myglob.*" "step into"
+
+# Step out of call
+#
+# I wonder if this is really portable. Are there any caller-saves
+# platforms, on which `finish' will return you to some kind of pop
+# instruction, which is attributed to the line containing the function
+# call?
+
+# On PA64, we end up at a different instruction than PA32.
+# On IA-64, we also end up on callee instead of on the next line due
+# to the restoration of the global pointer (which is a caller-save).
+if { [istarget "hppa2.0w-hp-hpux*"] || [istarget "ia64-*-*"]} {
+ send_gdb "finish\n"
+ gdb_expect {
+ -re ".*${decimal}.*a.*5.*= a.*3.*$gdb_prompt $" { pass "step out 1" }
+ -re ".*${decimal}.*callee.*INTO.*$gdb_prompt $" { pass "step out 2" }
+ timeout { fail "step out" }
+ }
+} else {
+ gdb_test "finish" ".*${decimal}.*a.*5.*= a.*3.*" "step out"
+}
+
+### Testing nexti and stepi.
+###
+### test_i NAME COMMAND HERE THERE
+###
+### Send COMMAND to gdb over and over, while the output matches the
+### regexp HERE, followed by the gdb prompt. Pass if the output
+### eventually matches the regexp THERE, followed by the gdb prompt;
+### fail if we have to iterate more than a hundred times, we time out
+### talking to gdb, or we get output which is neither HERE nor THERE. :)
+###
+### Use NAME as the name of the test.
+###
+### The exact regexps used are "$HERE.*$gdb_prompt $"
+### and "$THERE.*$gdb_prompt $"
+###
+proc test_i {name command here there} {
+ global gdb_prompt
+
+ set i 0
+ while 1 {
+ send_gdb "${command}\n"
+ gdb_expect {
+ -re "$here.*$gdb_prompt $" {
+ # Okay, we're still on the same line. Just step again.
+ }
+ -re "$there.*$gdb_prompt $" {
+ # We've reached the next line. Rah.
+ pass "$name"
+ return
+ }
+ -re "$gdb_prompt $" {
+ # We got something else. Fail.
+ fail "$name"
+ return
+ }
+ timeout {
+ fail "$name (timeout)"
+ return
+ }
+ }
+
+ # Have we gone for too many steps without seeing any progress?
+ if {[incr i] >= 100} {
+ fail "$name (no progress after 100 steps)"
+ return
+ }
+ }
+}
+
+test_i "stepi to next line" "stepi" \
+ ".*${decimal}.*a.*5.* = a.*3" \
+ ".*${decimal}.*callee.*STEPI"
+test_i "stepi into function" "stepi" \
+ ".*${decimal}.*callee.*STEPI" \
+ ".*callee \\(\\) at .*step-test\\.c"
+
+# Continue to step until we reach the function's body. This makes it
+# more likely that we've actually completed the prologue, so "finish"
+# will work.
+test_i "stepi into function's first source line" "stepi" \
+ ".*${decimal}.*int callee" \
+ ".*${decimal}.*myglob.*; return 0;"
+
+# Have to be careful here, if the finish does not work,
+# then we may run to the end of the program, which
+# will cause erroneous failures in the rest of the tests
+send_gdb "finish\n"
+gdb_expect {
+ -re ".*(Program received|Program exited).*$gdb_prompt $" {
+ # Oops... We ran to the end of the program... Better reset
+ if {![runto_main]} then {
+ fail "Can't run to main"
+ return 0
+ }
+ if {![runto step-test.c:45]} {
+ fail "Can't run to line 45"
+ return 0
+ }
+ fail "stepi: finish call"
+ }
+ -re ".*${decimal}.*callee.*NEXTI.*$gdb_prompt $" {
+ pass "stepi: finish call"
+ }
+ -re ".*${decimal}.*callee.*STEPI.*$gdb_prompt $" {
+ # On PA64, we end up at a different instruction than PA32.
+ # On IA-64, we end up on callee instead of on the following line due
+ # to the restoration of the global pointer.
+ if { [istarget "hppa2.0w-hp-hpux*"] || [istarget "ia64-*-*"] } {
+ pass "stepi: finish call 2"
+ } else {
+ fail "stepi: finish call 2"
+ return
+ }
+ }
+ -re "$gdb_prompt $" {
+ # We got something else. Fail.
+ fail "stepi: finish call"
+ return
+ }
+ timeout {
+ fail "stepi: finish call (timeout)"
+ return
+ }
+}
+
+test_i "nexti over function" "nexti" \
+ ".*${decimal}.*callee.*NEXTI" \
+ ".*${decimal}.*y = w \\+ z;"
+
+# On some platforms, if we try to step into a function call that
+# passes a large structure by value, then we actually end up stepping
+# into memcpy, bcopy, or some such --- GCC emits the call to pass the
+# argument. Opinion is bitterly divided about whether this is the
+# right behavior for GDB or not, but we'll catch it here, so folks
+# won't forget about it.
+# Update 4/4/2002 - Regardless of which opinion you have, you would
+# probably have to agree that gdb is currently behaving as designed,
+# in the absence of additional code to not stop in functions used
+# internally by the compiler. Since the testsuite should be checking
+# for conformance to the design, the correct behavior is to accept the
+# cases where gdb stops in memcpy/bcopy.
+
+gdb_test \
+ "break [gdb_get_line_number "step-test.exp: large struct by value"]" \
+ ".*Breakpoint.* at .*" \
+ "set breakpoint at call to large_struct_by_value"
+gdb_test "continue" \
+ ".*Breakpoint ${decimal},.*large_struct_by_value.*" \
+ "run to pass large struct"
+send_gdb "step\n"
+gdb_expect {
+ -re ".*step-test.exp: arrive here 1.*$gdb_prompt $" {
+ pass "large struct by value"
+ }
+ -re ".*(memcpy|bcopy).*$gdb_prompt $" {
+ send_gdb "finish\n" ; gdb_expect -re "$gdb_prompt $"
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" {
+ fail "large struct by value"
+ }
+ timeout {
+ fail "large struct by value (timeout)"
+ }
+}
+
+gdb_continue_to_end "step-test.exp"
+
+return 0
diff --git a/gdb/testsuite/gdb.base/structs.c b/gdb/testsuite/gdb.base/structs.c
new file mode 100644
index 00000000000..356f0729f1e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/structs.c
@@ -0,0 +1,263 @@
+/* Copyright 1996, 1999 Free Software Foundation, Inc.
+
+ 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.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@prep.ai.mit.edu */
+
+struct struct1 { char a;};
+struct struct2 { char a, b;};
+struct struct3 { char a, b, c; };
+struct struct4 { char a, b, c, d; };
+struct struct5 { char a, b, c, d, e; };
+struct struct6 { char a, b, c, d, e, f; };
+struct struct7 { char a, b, c, d, e, f, g; };
+struct struct8 { char a, b, c, d, e, f, g, h; };
+struct struct9 { char a, b, c, d, e, f, g, h, i; };
+struct struct10 { char a, b, c, d, e, f, g, h, i, j; };
+struct struct11 { char a, b, c, d, e, f, g, h, i, j, k; };
+struct struct12 { char a, b, c, d, e, f, g, h, i, j, k, l; };
+struct struct16 { char a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p; };
+
+struct struct1 foo1 = {'1'}, L1;
+struct struct2 foo2 = { 'a', 'b'}, L2;
+struct struct3 foo3 = { 'A', 'B', 'C'}, L3;
+struct struct4 foo4 = {'1', '2', '3', '4'}, L4;
+struct struct5 foo5 = {'a', 'b', 'c', 'd', 'e'}, L5;
+struct struct6 foo6 = {'A', 'B', 'C', 'D', 'E', 'F'}, L6;
+struct struct7 foo7 = {'1', '2', '3', '4', '5', '6', '7'}, L7;
+struct struct8 foo8 = {'1', '2', '3', '4', '5', '6', '7', '8'}, L8;
+struct struct9 foo9 = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}, L9;
+struct struct10 foo10 = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'}, L10;
+struct struct11 foo11 = {
+ '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B'}, L11;
+struct struct12 foo12 = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'}, L12;
+struct struct16 foo16 = {
+ 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'}, L16;
+
+struct struct1 fun1()
+{
+ return foo1;
+}
+struct struct2 fun2()
+{
+ return foo2;
+}
+struct struct3 fun3()
+{
+ return foo3;
+}
+struct struct4 fun4()
+{
+ return foo4;
+}
+struct struct5 fun5()
+{
+ return foo5;
+}
+struct struct6 fun6()
+{
+ return foo6;
+}
+struct struct7 fun7()
+{
+ return foo7;
+}
+struct struct8 fun8()
+{
+ return foo8;
+}
+struct struct9 fun9()
+{
+ return foo9;
+}
+struct struct10 fun10()
+{
+ return foo10;
+}
+struct struct11 fun11()
+{
+ return foo11;
+}
+struct struct12 fun12()
+{
+ return foo12;
+}
+struct struct16 fun16()
+{
+ return foo16;
+}
+
+#ifdef PROTOTYPES
+void Fun1(struct struct1 foo1)
+#else
+void Fun1(foo1)
+ struct struct1 foo1;
+#endif
+{
+ L1 = foo1;
+}
+#ifdef PROTOTYPES
+void Fun2(struct struct2 foo2)
+#else
+void Fun2(foo2)
+ struct struct2 foo2;
+#endif
+{
+ L2 = foo2;
+}
+#ifdef PROTOTYPES
+void Fun3(struct struct3 foo3)
+#else
+void Fun3(foo3)
+ struct struct3 foo3;
+#endif
+{
+ L3 = foo3;
+}
+#ifdef PROTOTYPES
+void Fun4(struct struct4 foo4)
+#else
+void Fun4(foo4)
+ struct struct4 foo4;
+#endif
+{
+ L4 = foo4;
+}
+#ifdef PROTOTYPES
+void Fun5(struct struct5 foo5)
+#else
+void Fun5(foo5)
+ struct struct5 foo5;
+#endif
+{
+ L5 = foo5;
+}
+#ifdef PROTOTYPES
+void Fun6(struct struct6 foo6)
+#else
+void Fun6(foo6)
+ struct struct6 foo6;
+#endif
+{
+ L6 = foo6;
+}
+#ifdef PROTOTYPES
+void Fun7(struct struct7 foo7)
+#else
+void Fun7(foo7)
+ struct struct7 foo7;
+#endif
+{
+ L7 = foo7;
+}
+#ifdef PROTOTYPES
+void Fun8(struct struct8 foo8)
+#else
+void Fun8(foo8)
+ struct struct8 foo8;
+#endif
+{
+ L8 = foo8;
+}
+#ifdef PROTOTYPES
+void Fun9(struct struct9 foo9)
+#else
+void Fun9(foo9)
+ struct struct9 foo9;
+#endif
+{
+ L9 = foo9;
+}
+#ifdef PROTOTYPES
+void Fun10(struct struct10 foo10)
+#else
+void Fun10(foo10)
+ struct struct10 foo10;
+#endif
+{
+ L10 = foo10;
+}
+#ifdef PROTOTYPES
+void Fun11(struct struct11 foo11)
+#else
+void Fun11(foo11)
+ struct struct11 foo11;
+#endif
+{
+ L11 = foo11;
+}
+#ifdef PROTOTYPES
+void Fun12(struct struct12 foo12)
+#else
+void Fun12(foo12)
+ struct struct12 foo12;
+#endif
+{
+ L12 = foo12;
+}
+#ifdef PROTOTYPES
+void Fun16(struct struct16 foo16)
+#else
+void Fun16(foo16)
+ struct struct16 foo16;
+#endif
+{
+ L16 = foo16;
+}
+
+int main()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+
+ /* TEST C FUNCTIONS */
+ L1 = fun1();
+ L2 = fun2();
+ L3 = fun3();
+ L4 = fun4();
+ L5 = fun5();
+ L6 = fun6();
+ L7 = fun7();
+ L8 = fun8();
+ L9 = fun9();
+ L10 = fun10();
+ L11 = fun11();
+ L12 = fun12();
+ L16 = fun16();
+
+ foo1.a = foo2.a = foo3.a = foo4.a = foo5.a = foo6.a = foo7.a = foo8.a =
+ foo9.a = foo10.a = foo11.a = foo12.a = foo16.a = '$';
+
+ Fun1(foo1);
+ Fun2(foo2);
+ Fun3(foo3);
+ Fun4(foo4);
+ Fun5(foo5);
+ Fun6(foo6);
+ Fun7(foo7);
+ Fun8(foo8);
+ Fun9(foo9);
+ Fun10(foo10);
+ Fun11(foo11);
+ Fun12(foo12);
+ Fun16(foo16);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/structs.exp b/gdb/testsuite/gdb.base/structs.exp
new file mode 100644
index 00000000000..ed91c86e482
--- /dev/null
+++ b/gdb/testsuite/gdb.base/structs.exp
@@ -0,0 +1,167 @@
+# Copyright 1996, 1997, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Jeff Law. (law@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set prototypes 1
+set testfile "structs"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# build the first test case
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ # built the second test case since we can't use prototypes
+ warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES"
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DNO_PROTOTYPES}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ set prototypes 0
+}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+
+# Some targets can't call functions, so don't even bother with this
+# test.
+if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ continue
+}
+
+
+# Call FUNC with no arguments, and expect to see the regexp RESULT in
+# the output. If we get back the error message "Function return value
+# unknown", call that an unsupported test; on some architectures, it's
+# impossible to find structs returned by value reliably.
+proc call_struct_func { func result } {
+ global gdb_prompt
+
+ set command "p ${func}()"
+ send_gdb "${command}\n"
+ gdb_expect {
+ -re "$result\[\r\n\]+$gdb_prompt $" {
+ pass "$command"
+ }
+ -re "Function return value unknown.\[\r\n\]+$gdb_prompt $" {
+ unsupported "$command"
+ }
+ -re "$gdb_prompt $" {
+ fail "$command"
+ }
+ timeout {
+ fail "$command (timeout)"
+ }
+ }
+}
+
+# FIXME: Before calling this proc, we should probably verify that
+# we can call inferior functions and get a valid integral value
+# returned.
+# Note that it is OK to check for 0 or 1 as the returned values, because C
+# specifies that the numeric value of a relational or logical expression
+# (computed in the inferior) is 1 for true and 0 for false.
+
+proc do_function_calls {} {
+ global prototypes
+ global gcc_compiled
+ global gdb_prompt
+
+ # First, call the "fun" functions and examine the value they return.
+ call_struct_func "fun1" " = {a = 49 '1'}"
+ call_struct_func "fun2" " = {a = 97 'a', b = 98 'b'}"
+ call_struct_func "fun3" " = {a = 65 'A', b = 66 'B', c = 67 'C'}"
+ call_struct_func "fun4" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4'}"
+ call_struct_func "fun5" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e'}"
+ call_struct_func "fun6" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F'}"
+ call_struct_func "fun7" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7'}"
+ call_struct_func "fun8" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8'}"
+ call_struct_func "fun9" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i'}"
+ call_struct_func "fun10" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J'}"
+ call_struct_func "fun11" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8', i = 57 '9', j = 65 'A', k = 66 'B'}"
+ call_struct_func "fun12" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J', k = 75 'K', l = 76 'L'}"
+ call_struct_func "fun16" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i', j = 106 'j', k = 107 'k', l = 108 'l', m = 109 'm', n = 110 'n', o = 111 'o', p = 112 'p'}"
+
+ # Now call the Fun functions to set the L* variables. This
+ # tests that gdb properly passes structures to functions.
+ gdb_test "p Fun1(foo1)" " = (void|0)"
+ gdb_test "p Fun2(foo2)" " = (void|0)"
+ gdb_test "p Fun3(foo3)" " = (void|0)"
+ gdb_test "p Fun4(foo4)" " = (void|0)"
+ gdb_test "p Fun5(foo5)" " = (void|0)"
+ gdb_test "p Fun6(foo6)" " = (void|0)"
+ gdb_test "p Fun7(foo7)" " = (void|0)"
+ gdb_test "p Fun8(foo8)" " = (void|0)"
+ gdb_test "p Fun9(foo9)" " = (void|0)"
+ gdb_test "p Fun10(foo10)" " = (void|0)"
+ gdb_test "p Fun11(foo11)" " = (void|0)"
+ gdb_test "p Fun12(foo12)" " = (void|0)"
+ gdb_test "p Fun16(foo16)" " = (void|0)"
+
+ # Now print the L* variables and examine their values.
+ gdb_test "p L1" " = {a = 49 '1'}"
+ gdb_test "p L2" " = {a = 97 'a', b = 98 'b'}"
+ gdb_test "p L3" " = {a = 65 'A', b = 66 'B', c = 67 'C'}"
+ gdb_test "p L4" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4'}"
+ gdb_test "p L5" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e'}"
+ gdb_test "p L6" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F'}"
+ gdb_test "p L7" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7'}"
+ gdb_test "p L8" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8'}"
+ gdb_test "p L9" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i'}"
+ gdb_test "p L10" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J'}"
+ gdb_test "p L11" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8', i = 57 '9', j = 65 'A', k = 66 'B'}"
+ gdb_test "p L12" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J', k = 75 'K', l = 76 'L'}"
+ gdb_test "p L16" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i', j = 106 'j', k = 107 'k', l = 108 'l', m = 109 'm', n = 110 'n', o = 111 'o', p = 112 'p'}"
+}
+# Start with a fresh gdb.
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set print sevenbit-strings" ""
+gdb_test "set print address off" ""
+gdb_test "set width 0" ""
+
+if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ return 0
+}
+
+if { ![runto_main] } then {
+ gdb_suppress_tests;
+}
+
+do_function_calls;
+
+gdb_stop_suppressing_tests;
+
+return 0
diff --git a/gdb/testsuite/gdb.base/structs2.c b/gdb/testsuite/gdb.base/structs2.c
new file mode 100644
index 00000000000..f1eeab1adc2
--- /dev/null
+++ b/gdb/testsuite/gdb.base/structs2.c
@@ -0,0 +1,38 @@
+/* pr 13536 */
+
+static void param_reg (register signed char pr_char,
+ register unsigned char pr_uchar,
+ register short pr_short,
+ register unsigned short pr_ushort);
+
+int bkpt;
+
+int
+main ()
+{
+#ifdef usestubs
+ set_debug_traps ();
+ breakpoint ();
+#endif
+
+ bkpt = 0;
+ param_reg (120, 130, 32000, 33000);
+ param_reg (130, 120, 33000, 32000);
+
+ return 0;
+}
+
+static void dummy () {}
+
+static void
+param_reg(register signed char pr_char,
+ register unsigned char pr_uchar,
+ register short pr_short,
+ register unsigned short pr_ushort)
+{
+ bkpt = 1;
+ dummy ();
+ pr_char = 1;
+ pr_uchar = pr_short = pr_ushort = 1;
+ dummy ();
+}
diff --git a/gdb/testsuite/gdb.base/structs2.exp b/gdb/testsuite/gdb.base/structs2.exp
new file mode 100644
index 00000000000..c3c4e671c5e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/structs2.exp
@@ -0,0 +1,79 @@
+# Copyright 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set prototypes 1
+set testfile "structs2"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# build the first test case
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ # built the second test case since we can't use prototypes
+ warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES"
+ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DNO_PROTOTYPES}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ set prototypes 0
+}
+
+# Start with a fresh gdb.
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set width 0" ""
+
+if { ![runto_main] } then {
+ gdb_suppress_tests
+}
+
+# Ok, we're finally ready to actually do our tests.
+
+set prms_id 13536
+set bug_id 0
+
+gdb_test "f" \
+ ".*bkpt = 0.*" \
+ "structs2 sanity check"
+
+gdb_test "break param_reg" \
+ "Breakpoint .* at .*" \
+ "structs2 breakpoint set"
+
+gdb_test "continue" \
+ ".*pr_char=120.*pr_uchar=130.*pr_short=32000.*pr_ushort=33000.*bkpt = 1.*" \
+ "structs2 continue1"
+
+gdb_test "continue" \
+ ".*pr_char=-126.*pr_uchar=120.*pr_short=-32536.*pr_ushort=32000.*bkpt = 1.*" \
+ "structs2 continue2"
+
+# End of tests.
+
+gdb_stop_suppressing_tests
+
+return 0
diff --git a/gdb/testsuite/gdb.base/sum.c b/gdb/testsuite/gdb.base/sum.c
new file mode 100644
index 00000000000..f5a5dbf2631
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sum.c
@@ -0,0 +1,15 @@
+/* This is a sample program for the HP/DDE debugger. */
+#include <stdio.h>
+
+#ifdef PROTOTYPES
+int sum(int *list, int low, int high)
+#else
+int sum(list, low, high)
+int *list, low, high;
+#endif
+ {
+ int i = 0, s = 0;
+ for (i = low; i <= high; i++)
+ s += list[i];
+ return(s);
+ }
diff --git a/gdb/testsuite/gdb.base/term.exp b/gdb/testsuite/gdb.base/term.exp
new file mode 100644
index 00000000000..1a645311297
--- /dev/null
+++ b/gdb/testsuite/gdb.base/term.exp
@@ -0,0 +1,76 @@
+# Copyright 1988, 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1999
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+# Don't try this for remote targets.
+if [is_remote target] then {
+ continue
+}
+
+gdb_start
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "run"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+delete_breakpoints
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set print sevenbit-strings" "" "test set print sevenbit-strings"
+gdb_test "set print address off" "" "test set print address off"
+gdb_test "set width 0" "" "test set width 0"
+gdb_test "info terminal" "No saved terminal information.*" "test info terminal"
+gdb_run_cmd 5
+gdb_expect {
+ -re ".*120.*Program exited normally.*$gdb_prompt $" {
+ gdb_test "info terminal" "No saved terminal information.*" "test info terminal #2"
+ }
+ default {
+ fail "term.exp, factorial didn't run to completion for info terminal"
+ }
+}
+
+# In mid-execution
+gdb_breakpoint main
+gdb_run_cmd 5
+gdb_expect {
+ -re ".*Breakpoint \[0-9\]+,.*main.*if .argc != 2.*$gdb_prompt $" {
+ gdb_test "info terminal" "Inferior's terminal status .currently saved by GDB.:.*" "info terminal at breakpoint"
+ }
+ -re ".*$gdb_prompt $" { fail "info terminal at breakpoint" }
+ timeout { fail "(timeout) info terminal at breakpoint" }
+}
diff --git a/gdb/testsuite/gdb.base/twice.c b/gdb/testsuite/gdb.base/twice.c
new file mode 100644
index 00000000000..09eb2ddf5a2
--- /dev/null
+++ b/gdb/testsuite/gdb.base/twice.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+int nothing ()
+
+{
+ int x = 3 ;
+ return x ;
+}
+
+
+int main ()
+
+{
+ int y ;
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ y = nothing () ;
+ printf ("hello\n") ;
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/twice.exp b/gdb/testsuite/gdb.base/twice.exp
new file mode 100644
index 00000000000..7a86701cb67
--- /dev/null
+++ b/gdb/testsuite/gdb.base/twice.exp
@@ -0,0 +1,64 @@
+# Copyright 1997, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile twice-tmp
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set options debug
+lappend options "additional_flags=-I."
+
+set fileid [open ${objdir}/${subdir}/${srcfile} w];
+puts $fileid "#include \"twice.c\"";
+close $fileid;
+
+remote_download host ${srcdir}/${subdir}/twice.c twice.c
+
+if { [gdb_compile "${objdir}/${subdir}/${srcfile}" "${binfile}" executable $options] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+if [runto_main] then {
+ # Test that GDB can still detect whether we have line numbers
+ # even if we're executing code in an include file.
+
+ # The bug was fixed by
+ #Tue Jun 29 11:02:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+ #
+ # * infrun.c (wait_for_inferior): Use find_pc_line not
+ # find_pc_symtab to check whether there is line number
+ # information.
+
+ gdb_test "step" "nothing \\(\\) at.*"
+}
+remote_exec build "rm -f twice.c"
+return 0
diff --git a/gdb/testsuite/gdb.base/varargs.c b/gdb/testsuite/gdb.base/varargs.c
new file mode 100644
index 00000000000..1122767977c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/varargs.c
@@ -0,0 +1,111 @@
+/* varargs.c -
+ * (Added as part of fix for bug 15306 - "call" to varargs functions fails)
+ * This program is intended to let me try out "call" to varargs functions
+ * with varying numbers of declared args and various argument types.
+ * - RT 9/27/95
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+int find_max1(int, ...);
+int find_max2(int, int, ...);
+double find_max_double(int, double, ...);
+
+char ch;
+unsigned char uc;
+short s;
+unsigned short us;
+int a,b,c,d;
+int max_val;
+long long ll;
+float fa,fb,fc,fd;
+double da,db,dc,dd;
+double dmax_val;
+
+int main() {
+ c = -1;
+ uc = 1;
+ s = -2;
+ us = 2;
+ a = 1;
+ b = 60;
+ max_val = find_max1(1, 60);
+ max_val = find_max1(a, b);
+ a = 3;
+ b = 1;
+ c = 4;
+ d = 2;
+ max_val = find_max1(3, 1, 4, 2);
+ max_val = find_max2(a, b, c, d);
+ da = 3.0;
+ db = 1.0;
+ dc = 4.0;
+ dd = 2.0;
+ dmax_val = find_max_double(3, 1.0, 4.0, 2.0);
+ dmax_val = find_max_double(a, db, dc, dd);
+
+ return 0;
+}
+
+/* Integer varargs, 1 declared arg */
+
+int find_max1(int num_vals, ...) {
+ int max_val = 0;
+ int x;
+ int i;
+ va_list argp;
+ va_start(argp, num_vals);
+ printf("find_max(%d,", num_vals);
+ for (i = 0; i < num_vals; i++) {
+ x = va_arg(argp, int);
+ if (max_val < x) max_val = x;
+ if (i < num_vals - 1)
+ printf(" %d,", x);
+ else
+ printf(" %d)", x);
+ }
+ printf(" returns %d\n", max_val);
+ return max_val;
+}
+
+/* Integer varargs, 2 declared args */
+
+int find_max2(int num_vals, int first_val, ...) {
+ int max_val = 0;
+ int x;
+ int i;
+ va_list argp;
+ va_start(argp, first_val);
+ x = first_val;
+ if (max_val < x) max_val = x;
+ printf("find_max(%d, %d", num_vals, first_val);
+ for (i = 1; i < num_vals; i++) {
+ x = va_arg(argp, int);
+ if (max_val < x) max_val = x;
+ printf(", %d", x);
+ }
+ printf(") returns %d\n", max_val);
+ return max_val;
+}
+
+/* Double-float varargs, 2 declared args */
+
+double find_max_double(int num_vals, double first_val, ...) {
+ double max_val = 0;
+ double x;
+ int i;
+ va_list argp;
+ va_start(argp, first_val);
+ x = first_val;
+ if (max_val < x) max_val = x;
+ printf("find_max(%d, %f", num_vals, first_val);
+ for (i = 1; i < num_vals; i++) {
+ x = va_arg(argp, double);
+ if (max_val < x) max_val = x;
+ printf(", %f", x);
+ }
+ printf(") returns %f\n", max_val);
+ return max_val;
+}
+
diff --git a/gdb/testsuite/gdb.base/varargs.exp b/gdb/testsuite/gdb.base/varargs.exp
new file mode 100644
index 00000000000..22fa84a3c53
--- /dev/null
+++ b/gdb/testsuite/gdb.base/varargs.exp
@@ -0,0 +1,148 @@
+# Copyright 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+
+# this file tests command line calls with functions having variable
+# args list
+# corresponding source file: varargs.c
+
+#print find_max1(5,1,2,3,4,5)
+#print find_max1(1,3)
+#call find_max1(10,1,2,3,4,5,6,7,8,29,0)
+#print find_max2(3,1,2,3)
+#print find_max_double(5,1.0,17.0,2.0,3.0,4.0)
+#quit
+
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set prototypes 0
+set testfile "varargs"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+if {$hp_cc_compiler} {
+ set additional_flags "additional_flags=-Ae"
+} else {
+ set additional_flags ""
+}
+
+# build the first test case
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug ${additional_flags}}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+send_gdb "set print sevenbit-strings\n" ; gdb_expect -re "$gdb_prompt $"
+send_gdb "set print address off\n" ; gdb_expect -re "$gdb_prompt $"
+send_gdb "set width 0\n" ; gdb_expect -re "$gdb_prompt $"
+
+if [gdb_skip_stdio_test "varargs.exp"] {
+ # Nothing in this module is testable without printf.
+ return;
+}
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+if { $hp_aCC_compiler } {
+ # When compiled w/ aCC we need to disable overload resolution
+ # for command line calls.
+ # We need it for vararg calls since the aCC compiler gives us no
+ # information about the undeclared arguments, or even that there
+ # _are_ undeclared arguments. As far as gdb is concerned it only
+ # knows about the declared arguments. So we need to force the call
+ # even though the overload resolution mechanism says that the types
+ # don't match.
+ # - guo
+ gdb_test "set overload-resolution 0" ""
+}
+
+send_gdb "print find_max1(5,1,2,3,4,5)\n"
+gdb_expect {
+ -re ".*find_max\\(5, 1, 2, 3, 4, 5\\) returns 5\[ \r\n\]+.\[0-9\]+ = 5.*$gdb_prompt $" {
+ pass "print find_max1(5,1,2,3,4,5)"
+ }
+ -re ".*$gdb_prompt $" { fail "print find_max1(5,1,2,3,4,5)" }
+ timeout { fail "(timeout) print find_max1(5,1,2,3,4,5)" }
+ }
+
+
+
+
+send_gdb "print find_max1(1,3)\n"
+gdb_expect {
+ -re ".*find_max\\(1, 3\\) returns 3\[ \r\n\]+.\[0-9\]+ = 3.*$gdb_prompt $" {
+ pass "print find_max1(1,3)"
+ }
+ -re ".*$gdb_prompt $" { fail "print find_max1(1,3)" }
+ timeout { fail "(timeout) print find_max1(1,3)" }
+ }
+
+
+send_gdb "print find_max1(10,1,2,3,4,5,6,7,8,29,0)\n"
+gdb_expect {
+ -re ".*find_max\\(10, 1, 2, 3, 4, 5, 6, 7, 8, 29, 0\\) returns 29\[ \r\n\]+.\[0-9\]+ = 29.*$gdb_prompt $" {
+ pass "print find_max1(10,1,2,3,4,5,6,7,8,29,0)"
+ }
+ -re ".*$gdb_prompt $" { fail "print find_max1(10,1,2,3,4,5,6,7,8,29,0)" }
+ timeout { fail "(timeout) print find_max1(10,1,2,3,4,5,6,7,8,29,0)" }
+ }
+
+
+
+send_gdb "print find_max2(3,1,2,3)\n"
+gdb_expect {
+ -re ".*find_max\\(3, 1, 2, 3\\) returns 3\[ \r\n\]+.\[0-9\]+ = 3.*$gdb_prompt $" {
+ pass "print find_max2(3,1,2,3)"
+ }
+ -re ".*$gdb_prompt $" { fail "print find_max2(3,1,2,3)" }
+ timeout { fail "(timeout) print find_max2(3,1,2,3)" }
+ }
+
+
+if {![target_info exists gdb,skip_float_tests]} {
+ send_gdb "print find_max_double(5,1.0,17.0,2.0,3.0,4.0)\n"
+ gdb_expect {
+ -re ".*find_max\\(.*\\) returns 17\\.000000\[ \r\n\]+.\[0-9\]+ = 17.*$gdb_prompt $" {
+ pass "print find_max_double(5,1.0,17.0,2.0,3.0,4.0)"
+ }
+ -re ".*$gdb_prompt $" { fail "print find_max_double(5,1.0,17.0,2.0,3.0,4.0)" }
+ timeout { fail "(timeout) print find_max_double(5,1.0,17.0,2.0,3.0,4.0)" }
+ }
+}
+
diff --git a/gdb/testsuite/gdb.base/vforked-prog.c b/gdb/testsuite/gdb.base/vforked-prog.c
new file mode 100644
index 00000000000..27504db528a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vforked-prog.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+#ifdef PROTOTYPES
+int main (void)
+#else
+main()
+#endif
+{
+ printf("Hello from vforked-prog...\n");
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/volatile.exp b/gdb/testsuite/gdb.base/volatile.exp
new file mode 100644
index 00000000000..efb271b6ec0
--- /dev/null
+++ b/gdb/testsuite/gdb.base/volatile.exp
@@ -0,0 +1,268 @@
+# Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Written by Satish Pai <pai@apollo.hp.com> 1997-07-07
+# In the spirit of constvars.exp: added volatile, const-volatile stuff.
+
+# This file is part of the gdb testsuite
+# Tests for:
+# volatile vars
+# pointers to volatile vars
+# const volatile vars
+# pointers to const volatile vars
+# const pointers to volatile vars
+# volatile pointers to const vars
+# const volatile pointers to const vars
+# const volatile pointers to volatile vars
+# ... etc. (you get the idea)
+# Mostly with char and unsigned char.
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+# Use the same test program constvars.c.
+
+set testfile "constvars"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+if {$hp_aCC_compiler || $hp_cc_compiler} {
+ set lang "c++"
+} else {
+ set lang ""
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [concat debug $lang]] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+remote_exec build "rm -f ${binfile}.ci"
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+source ${binfile}.ci
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+get_debug_format
+
+proc local_compiler_xfail_check { } {
+ global gcc_compiled;
+
+ if {$gcc_compiled} then {
+ if { ![test_debug_format "HP"] \
+ && ![test_debug_format "DWARF 2"] } then {
+ setup_xfail "*-*-*"
+ }
+ }
+}
+
+send_gdb "break marker1\n" ; gdb_expect -re ".*$gdb_prompt $"
+
+ send_gdb "cont\n"
+ gdb_expect {
+ -re "Break.* marker1 \\(\\) at .*:$decimal.*$gdb_prompt $" {
+ send_gdb "up\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "up from marker1" }
+ }
+ }
+ -re "Break.* marker1__.* \\(\\) at .*:$decimal.*$gdb_prompt $" {
+ fail "continue to marker1 (demangling)"
+ send_gdb "up\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "up from marker1" }
+ }
+ }
+ -re "$gdb_prompt $" { fail "continue to marker1" }
+ timeout { fail "(timeout) continue to marker1" }
+ }
+
+# As of Feb 1999, GCC does not issue info about volatility of vars, so
+# these tests are all expected to fail if GCC is the compiler. -sts
+
+local_compiler_xfail_check
+gdb_test "ptype vox" "type = volatile char.*"
+
+local_compiler_xfail_check
+gdb_test "ptype victuals" "type = volatile unsigned char.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vixen" "type = volatile short.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vitriol" "type = volatile (unsigned short|short unsigned)( int)?.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vellum" "type = volatile long.*"
+
+local_compiler_xfail_check
+gdb_test "ptype valve" "type = volatile (unsigned long|long unsigned)( int)?.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vacuity" "type = volatile float.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vertigo" "type = volatile double.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vampire" "type = volatile char \\*.*"
+
+local_compiler_xfail_check
+gdb_test "ptype viper" "type = volatile unsigned char \\*.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vigour" "type = volatile short( int)? \\*.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vapour" "type = volatile (unsigned short|short unsigned)( int)? \\*.*"
+
+local_compiler_xfail_check
+gdb_test "ptype ventricle" "type = volatile long( int)? \\*.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vigintillion" "type = volatile (unsigned long|long unsigned)( int)? \\*.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vocation" "type = volatile float \\*.*"
+
+local_compiler_xfail_check
+gdb_test "ptype veracity" "type = volatile double \\*.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vapidity" "type = volatile char \\* volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype velocity" "type = volatile unsigned char \\* volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype veneer" "type = volatile short( int)? \\* volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype video" "type = volatile (unsigned short|short unsigned)( int) \\* volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vacuum" "type = volatile long( int)? \\* volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype veniality" "type = volatile (unsigned long|long unsigned)( int)? \\* volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vitality" "type = volatile float \\* volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype voracity" "type = volatile double \\* volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype victor" "type = const volatile char.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vicar" "type = const volatile unsigned char.*"
+
+local_compiler_xfail_check
+gdb_test "ptype victory" "type = const volatile char \\*.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vicarage" "type = const volatile unsigned char \\*.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vein" "type = volatile char \\* const.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vogue" "type = volatile unsigned char \\* const.*"
+
+local_compiler_xfail_check
+gdb_test "ptype cavern" "type = const volatile char \\* const.*"
+
+local_compiler_xfail_check
+gdb_test "ptype coverlet" "type = const volatile unsigned char \\* const.*"
+
+local_compiler_xfail_check
+gdb_test "ptype caveat" "type = const char \\* volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype covenant" "type = const unsigned char \\* volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vizier" "type = const volatile char \\* volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vanadium" "type = const volatile unsigned char \\* volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vane" "type = char \\* const volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype veldt" "type = unsigned char \\* const volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype cove" "type = const char \\* const volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype cavity" "type = const unsigned char \\* const volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vagus" "type = volatile char \\* const volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vagrancy" "type = volatile unsigned char \\* const volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vagary" "type = const volatile char \\* const volatile.*"
+
+local_compiler_xfail_check
+gdb_test "ptype vendor" "type = const volatile unsigned char \\* const volatile.*"
+
+# test function parameters
+local_compiler_xfail_check
+send_gdb "ptype qux2\n"
+gdb_expect {
+ -re "type = int \\(volatile unsigned char, const volatile int, volatile short( int)?, volatile long( int)? \\*, float \\* volatile, const volatile signed char \\* const volatile\\).*$gdb_prompt $" {
+ pass "ptype qux2"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype qux2" }
+ timeout { fail "(timeout) ptype qux2" }
+ }
diff --git a/gdb/testsuite/gdb.base/watchpoint.c b/gdb/testsuite/gdb.base/watchpoint.c
new file mode 100644
index 00000000000..14ccecd5253
--- /dev/null
+++ b/gdb/testsuite/gdb.base/watchpoint.c
@@ -0,0 +1,174 @@
+#include <stdio.h>
+#include <unistd.h>
+/*
+ * Since using watchpoints can be very slow, we have to take some pains to
+ * ensure that we don't run too long with them enabled or we run the risk
+ * of having the test timeout. To help avoid this, we insert some marker
+ * functions in the execution stream so we can set breakpoints at known
+ * locations, without worrying about invalidating line numbers by changing
+ * this file. We use null bodied functions are markers since gdb does
+ * not support breakpoints at labeled text points at this time.
+ *
+ * One place we need is a marker for when we start executing our tests
+ * instructions rather than any process startup code, so we insert one
+ * right after entering main(). Another is right before we finish, before
+ * we start executing any process termination code.
+ *
+ * Another problem we have to guard against, at least for the test
+ * suite, is that we need to ensure that the line that causes the
+ * watchpoint to be hit is still the current line when gdb notices
+ * the hit. Depending upon the specific code generated by the compiler,
+ * the instruction after the one that triggers the hit may be part of
+ * the same line or part of the next line. Thus we ensure that there
+ * are always some instructions to execute on the same line after the
+ * code that should trigger the hit.
+ */
+
+int count = -1;
+int ival1 = -1;
+int ival2 = -1;
+int ival3 = -1;
+int ival4 = -1;
+int ival5 = -1;
+char buf[10];
+struct foo
+{
+ int val;
+};
+struct foo struct1, struct2, *ptr1, *ptr2;
+
+int doread = 0;
+
+void marker1 ()
+{
+}
+
+void marker2 ()
+{
+}
+
+void marker4 ()
+{
+}
+
+void marker5 ()
+{
+}
+
+void marker6 ()
+{
+}
+
+#ifdef PROTOTYPES
+void recurser (int x)
+#else
+void recurser (x) int x;
+#endif
+{
+ int local_x;
+
+ if (x > 0)
+ recurser (x-1);
+ local_x = x;
+}
+
+void
+func2 ()
+{
+ int local_a;
+ static int static_b;
+
+ ival5++;
+ local_a = ival5;
+ static_b = local_a;
+}
+
+int
+func1 ()
+{
+ /* The point of this is that we will set a breakpoint at this call.
+
+ Then, if DECR_PC_AFTER_BREAK equals the size of a function call
+ instruction (true on a sun3 if this is gcc-compiled--FIXME we
+ should use asm() to make it work for any compiler, present or
+ future), then we will end up branching to the location just after
+ the breakpoint. And we better not confuse that with hitting the
+ breakpoint. */
+ func2 ();
+ return 73;
+}
+
+int main ()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ struct1.val = 1;
+ struct2.val = 2;
+ ptr1 = &struct1;
+ ptr2 = &struct2;
+ marker1 ();
+ func1 ();
+ for (count = 0; count < 4; count++) {
+ ival1 = count;
+ ival3 = count; ival4 = count;
+ }
+ ival1 = count; /* Outside loop */
+ ival2 = count;
+ ival3 = count; ival4 = count;
+ marker2 ();
+ if (doread)
+ {
+ static char msg[] = "type stuff for buf now:";
+ write (1, msg, sizeof (msg) - 1);
+ read (0, &buf[0], 5);
+ }
+ marker4 ();
+
+ /* We have a watchpoint on ptr1->val. It should be triggered if
+ ptr1's value changes. */
+ ptr1 = ptr2;
+
+ /* This should not trigger the watchpoint. If it does, then we
+ used the wrong value chain to re-insert the watchpoints or we
+ are not evaluating the watchpoint expression correctly. */
+ struct1.val = 5;
+ marker5 ();
+
+ /* We have a watchpoint on ptr1->val. It should be triggered if
+ ptr1's value changes. */
+ ptr1 = ptr2;
+
+ /* This should not trigger the watchpoint. If it does, then we
+ used the wrong value chain to re-insert the watchpoints or we
+ are not evaluating the watchpoint expression correctly. */
+ struct1.val = 5;
+ marker5 ();
+
+ /* We're going to watch locals of func2, to see that out-of-scope
+ watchpoints are detected and properly deleted.
+ */
+ marker6 ();
+
+ /* This invocation is used for watches of a single
+ local variable. */
+ func2 ();
+
+ /* This invocation is used for watches of an expression
+ involving a local variable. */
+ func2 ();
+
+ /* This invocation is used for watches of a static
+ (non-stack-based) local variable. */
+ func2 ();
+
+ /* This invocation is used for watches of a local variable
+ when recursion happens.
+ */
+ marker6 ();
+ recurser (2);
+
+ marker6 ();
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/watchpoint.exp b/gdb/testsuite/gdb.base/watchpoint.exp
new file mode 100644
index 00000000000..e150d555e60
--- /dev/null
+++ b/gdb/testsuite/gdb.base/watchpoint.exp
@@ -0,0 +1,806 @@
+# Copyright 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "watchpoint"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+set wp_set 1
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Prepare for watchpoint tests by setting up two breakpoints and one
+# watchpoint.
+#
+# We use breakpoints at marker functions to get past all the startup code,
+# so we can get to the watchpoints in a reasonable amount of time from a
+# known starting point.
+#
+# For simplicity, so we always know how to reference specific breakpoints or
+# watchpoints by number, we expect a particular ordering and numbering of
+# each in the combined breakpoint/watchpoint table, as follows:
+#
+# Number What Where
+# 1 Breakpoint marker1()
+# 2 Breakpoint marker2()
+# 3 Watchpoint ival3
+
+proc initialize {} {
+ global gdb_prompt
+ global hex
+ global decimal
+ global srcfile
+ global wp_set
+
+ # Disable hardware watchpoints if necessary.
+ if [target_info exists gdb,no_hardware_watchpoints] {
+ gdb_test "set can-use-hw-watchpoints 0" "" ""
+ }
+
+ if [gdb_test "break marker1" "Breakpoint 1 at $hex: file .*$srcfile, line $decimal.*" "set breakpoint at marker1" ] {
+ return 0;
+ }
+
+
+ if [gdb_test "break marker2" "Breakpoint 2 at $hex: file .*$srcfile, line $decimal.*" "set breakpoint at marker2" ] {
+ return 0;
+ }
+
+
+ if [gdb_test "info break" "1\[ \]*breakpoint.*marker1.*\r\n2\[ \]*breakpoint.*marker2.*" "info break in watchpoint.exp" ] {
+ return 0;
+ }
+
+
+ # ??rehrauer: To fix DTS #CHFts23014, in which setting a watchpoint
+ # before running can cause the inferior to croak on HP-UX 11.0 for
+ # reasons yet unknown, we've disabled the ability to set watches
+ # without a running inferior. Verify the restriction.
+ #
+ send_gdb "watch ival3\n"
+ gdb_expect {
+ -re ".*\[Ww\]atchpoint 3: ival3.*$gdb_prompt $" {
+ pass "set watchpoint on ival3"
+ }
+ -re "warning: can't do that without a running program; try \"break main\", \"run\" first.*$gdb_prompt $" {
+ pass "set watchpoint on ival3"
+ set wp_set 0
+ return 1
+ }
+ timeout {
+ fail "(timeout) set watchpoint on ival3"
+ return 0
+ }
+ }
+
+ # "info watch" is the same as "info break"
+
+ if [gdb_test "info watch" "1\[ \]*breakpoint.*marker1.*\r\n2\[ \]*breakpoint.*marker2.*\r\n3\[ \]*.*watchpoint.*ival3" "watchpoint found in watchpoint/breakpoint table" ] {
+ return 0;
+ }
+
+
+ # After installing the watchpoint, we disable it until we are ready
+ # to use it. This allows the test program to run at full speed until
+ # we get to the first marker function.
+
+ if [gdb_test "disable 3" "disable 3\[\r\n\]+" "disable watchpoint" ] {
+ return 0;
+ }
+
+
+ return 1
+}
+
+#
+# Test simple watchpoint.
+#
+
+proc test_simple_watchpoint {} {
+ global gdb_prompt
+ global hex
+ global decimal
+ global wp_set
+
+ # Ensure that the watchpoint is disabled when we startup.
+
+ if { $wp_set } {
+ if [gdb_test "disable 3" "^disable 3\[\r\n\]+" "disable watchpoint in test_simple_watchpoint" ] {
+ return 0;
+ }
+ }
+
+
+ # Run until we get to the first marker function.
+
+ gdb_run_cmd
+ set timeout 600
+ gdb_expect {
+ -re "Breakpoint 1, marker1 .*$gdb_prompt $" {
+ pass "run to marker1 in test_simple_watchpoint"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "run to marker1 in test_simple_watchpoint"
+ return
+ }
+ timeout {
+ fail "run to marker1 in test_simple_watchpoint (timeout)"
+ return
+ }
+ }
+
+ if { !$wp_set } {
+ # ??rehrauer: To fix DTS #CHFts23014, in which setting a watchpoint
+ # before running can cause the inferior to croak on HP-UX 11.0
+ # for reasons yet unknown, we've disabled the ability to set
+ # watches without a running inferior. The following testpoints used
+ # to be in [initialize].
+ #
+ send_gdb "watch ival3\n"
+ gdb_expect {
+ -re ".*\[Ww\]atchpoint 3: ival3\r\n$gdb_prompt $" {
+ pass "set watchpoint on ival3"
+ }
+ -re ".*$gdb_prompt $" { fail "set watchpoint on ival3" }
+ timeout { fail "set watchpoint on ival3 (timeout)" }
+ }
+
+ set wp_set 1
+
+ # "info watch" is the same as "info break"
+
+ send_gdb "info watch\n"
+ gdb_expect {
+ -re "1\[ \]*breakpoint.*marker1.*\r\n2\[ \]*breakpoint.*marker2.*\r\n3\[ \]*.*watchpoint.*ival3\r\n$gdb_prompt $" {
+ pass "watchpoint found in watchpoint/breakpoint table"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "watchpoint found in watchpoint/breakpoint table"
+ }
+ timeout {
+ fail "watchpoint found in watchpoint/breakpoint table"
+ }
+ }
+
+ # After installing the watchpoint, we disable it until we are ready
+ # to use it. This allows the test program to run at full speed until
+ # we get to the first marker function.
+
+ send_gdb "disable 3\n"
+ gdb_expect {
+ -re "disable 3\[\r\n\]+$gdb_prompt $" { pass "disable watchpoint" }
+ -re ".*$gdb_prompt $" { fail "disable watchpoint" }
+ timeout { fail "disable watchpoint (timeout)" }
+ }
+ }
+
+ # After reaching the marker function, enable the watchpoint.
+
+ if [gdb_test "enable 3" "^enable 3\[\r\n\]+" "enable watchpoint" ] {
+ return ;
+ }
+
+
+ gdb_test "break func1" "Breakpoint.*at.*"
+ gdb_test "set \$func1_breakpoint_number = \$bpnum" ""
+
+ gdb_test "continue" "Continuing.*Breakpoint \[0-9\]*, func1.*" \
+ "continue to breakpoint at func1"
+
+ # Continue until the first change, from -1 to 0
+
+ send_gdb "cont\n"
+ gdb_expect {
+ -re "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = -1.*New value = 0.*ival3 = count; ival4 = count;.*$gdb_prompt $" {
+ pass "watchpoint hit, first time"
+ }
+ -re "Continuing.*Breakpoint.*func1.*$gdb_prompt $" {
+ setup_xfail "m68*-*-*" 2597
+ fail "thought it hit breakpoint at func1 twice"
+ gdb_test "delete \$func1_breakpoint_number" ""
+ gdb_test "continue" "\
+Continuing.*\[Ww\]atchpoint.*ival3.*Old value = -1.*New value = 0.*ival3 = count;" \
+ "watchpoint hit, first time"
+ }
+ -re ".*$gdb_prompt $" { fail "watchpoint hit, first time" ; return }
+ timeout { fail "watchpoint hit, first time (timeout)" ; return }
+ eof { fail "watchpoint hit, first time (eof)" ; return }
+ }
+
+ # Check that the hit count is reported correctly
+ gdb_test "info break" ".*watchpoint\[ \t\]+keep\[ \t\]+y\[ \t\]+ival3\r\n\[ \t]+breakpoint already hit 1 time.*" "Watchpoint hit count is 1"
+
+ gdb_test "delete \$func1_breakpoint_number" ""
+
+ # Continue until the next change, from 0 to 1.
+ gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 0.*New value = 1.*ival3 = count; ival4 = count;.*" "watchpoint hit, second time"
+
+ # Check that the hit count is reported correctly
+ gdb_test "info break" ".*watchpoint\[ \t\]+keep\[ \t\]+y\[ \t\]+ival3\r\n\[ \t]+breakpoint already hit 2 times.*" "Watchpoint hit count is 2"
+
+ # Continue until the next change, from 1 to 2.
+ gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 1.*New value = 2.*ival3 = count; ival4 = count;.*" "watchpoint hit, third time"
+
+ # Check that the hit count is reported correctly
+ gdb_test "info break" ".*watchpoint\[ \t\]+keep\[ \t\]+y\[ \t\]+ival3\r\n\[ \t]+breakpoint already hit 3 times.*" "Watchpoint hit count is 3"
+
+ # Continue until the next change, from 2 to 3.
+ gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 2.*New value = 3.*ival3 = count; ival4 = count;.*" "watchpoint hit, fourth time"
+
+ # Check that the hit count is reported correctly
+ gdb_test "info break" ".*watchpoint\[ \t\]+keep\[ \t\]+y\[ \t\]+ival3\r\n\[ \t]+breakpoint already hit 4 times.*" "Watchpoint hit count is 4"
+
+ # Continue until the next change, from 3 to 4.
+ # Note that this one is outside the loop.
+
+ gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 3.*New value = 4.*ival3 = count; ival4 = count;.*" "watchpoint hit, fifth time"
+
+ # Check that the hit count is reported correctly
+ gdb_test "info break" ".*watchpoint\[ \t\]+keep\[ \t\]+y\[ \t\]+ival3\r\n\[ \t]+breakpoint already hit 5 times.*" "Watchpoint hit count is 5"
+
+ # Continue until we hit the finishing marker function.
+ # Make sure we hit no more watchpoints.
+
+ gdb_test "cont" "Continuing.*Breakpoint.*marker2 \(\).*" \
+ "continue to marker2"
+
+ # Disable the watchpoint so we run at full speed until we exit.
+
+ if [gdb_test "disable 3" "^disable 3\[\r\n\]+" "watchpoint disabled" ] {
+ return ;
+ }
+
+
+ # Run until process exits.
+
+ if [target_info exists gdb,noresults] { return }
+
+ gdb_continue_to_end "continue to exit in test_simple_watchpoint"
+}
+
+# Test disabling watchpoints.
+
+proc test_disabling_watchpoints {} {
+ global gdb_prompt
+ global binfile
+ global srcfile
+ global decimal
+ global hex
+
+ # "info watch" is the same as "info break"
+ gdb_test "info watch" "\[0-9\]+\[ \]*breakpoint.*marker1.*\r\n\[0-9\]+\[ \]*breakpoint.*marker2.*\r\n\[0-9]+\[ \]*.*watchpoint.*ival3\r\n\.*\[0-9\]+ times.*" "watchpoints found in watchpoint/breakpoint table"
+
+ # Ensure that the watchpoint is disabled when we startup.
+
+ if [gdb_test "disable 3" "^disable 3\[\r\n\]+" "disable watchpoint in test_disabling_watchpoints" ] {
+ return 0;
+ }
+
+
+ # Run until we get to the first marker function.
+
+ gdb_run_cmd
+ set timeout 600
+ gdb_expect {
+ -re "Breakpoint 1, marker1 .*$gdb_prompt $" {
+ pass "run to marker1 in test_disabling_watchpoints"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "run to marker1 in test_disabling_watchpoints"
+ return
+ }
+ timeout {
+ fail "run to marker1 in test_disabling_watchpoints (timeout)"
+ return
+ }
+ }
+
+ # After reaching the marker function, enable the watchpoint.
+
+ if [gdb_test "enable 3" "^enable 3\[\r\n\]+" "watchpoint enabled" ] {
+ return ;
+ }
+
+
+ # Continue until the first change, from -1 to 0
+ # Don't check the old value, because on VxWorks the variable value
+ # will not have been reinitialized.
+ gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = .*New value = 0.*ival3 = count; ival4 = count;.*" "watchpoint hit in test_disabling_watchpoints, first time"
+
+ # Continue until the next change, from 0 to 1.
+ gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 0.*New value = 1.*ival3 = count; ival4 = count;.*" "watchpoint hit in test_disabling_watchpoints, second time"
+
+ # Disable the watchpoint but leave breakpoints
+
+ if [gdb_test "disable 3" "^disable 3\[\r\n\]+" "disable watchpoint #2 in test_disabling_watchpoints" ] {
+ return 0;
+ }
+
+
+ # Check watchpoint list, looking for the entry that confirms the
+ # watchpoint is disabled.
+ gdb_test "info watchpoints" "\[0-9]+\[ \]*.*watchpoint\[ \]*keep\[ \]*n\[ \]*ival3\r\n.*" "watchpoint disabled in table"
+
+ # Continue until we hit the finishing marker function.
+ # Make sure we hit no more watchpoints.
+ gdb_test "cont" "Continuing.*Breakpoint.*marker2 \\(\\).*" \
+ "disabled watchpoint skipped"
+
+ if [target_info exists gdb,noresults] { return }
+
+ gdb_continue_to_end "continue to exit in test_disabling_watchpoints"
+}
+
+# Test stepping and other mundane operations with watchpoints enabled
+proc test_stepping {} {
+ global gdb_prompt
+
+ if [runto marker1] then {
+ gdb_test "watch ival2" ".*\[Ww\]atchpoint \[0-9\]*: ival2"
+
+ # Well, let's not be too mundane. It should be a *bit* of a challenge
+ gdb_test "break func2 if 0" "Breakpoint.*at.*"
+ gdb_test "p \$func2_breakpoint_number = \$bpnum" " = .*"
+
+ # The problem is that GDB confuses stepping through the call
+ # dummy with hitting the breakpoint at the end of the call dummy.
+ # Will be fixed once all architectures define
+ # CALL_DUMMY_BREAKPOINT_OFFSET.
+ setup_xfail "*-*-*"
+ # This doesn't occur if the call dummy starts with a call,
+ # because we are out of the dummy by the first time the inferior
+ # stops.
+ clear_xfail "arm*-*-*"
+ clear_xfail "xscale*-*-*"
+ clear_xfail "d10v*-*-*"
+ clear_xfail "m68*-*-*"
+ clear_xfail "i*86*-*-*"
+ clear_xfail "vax-*-*"
+ # The following architectures define CALL_DUMMY_BREAKPOINT_OFFSET.
+ clear_xfail "alpha-*-*"
+ clear_xfail "mips*-*-*"
+ clear_xfail "sparc-*-*"
+ clear_xfail "hppa*-*-*bsd*"
+ # It works with the generic inferior function calling code too.
+ clear_xfail "mn10200*-*-*"
+ clear_xfail "mn10300*-*-*"
+ # The following architectures define CALL_DUMMY_HAS_COMPLETED.
+ clear_xfail "hppa*-*-*hpux*"
+ gdb_test "p func1 ()" "= 73" \
+ "calling function with watchpoint enabled"
+
+ #
+ # "finish" brings us back to main.
+ # On some targets (e.g. alpha) gdb will stop from the finish in midline
+ # of the marker1 call. This is due to register restoring code on
+ # the alpha and might be caused by stack adjustment instructions
+ # on other targets. In this case we will step once more.
+ #
+
+ send_gdb "finish\n"
+ gdb_expect {
+ -re "Run.*exit from.*marker1.* at" {
+ pass "finish from marker1"
+ }
+ default { fail "finish from marker1 (timeout)" ; return }
+ }
+
+ gdb_expect {
+ -re "marker1 \\(\\);.*$gdb_prompt $" {
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re "func1 \\(\\);.*$gdb_prompt $" {
+ pass "back at main from marker1"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "back at main from marker1"
+ }
+ default { fail "back at main from marker1 (timeout)" ; return }
+ }
+
+ gdb_test "next" "for \\(count = 0.*" "next to `for' in watchpoint.exp"
+
+ # Now test that "until" works. It's a bit tricky to test
+ # "until", because compilers don't always arrange the code
+ # exactly the same way, and we might get slightly different
+ # sequences of statements. But the following should be true
+ # (if not it is a compiler or a debugger bug): The user who
+ # does "until" at every statement of a loop should end up
+ # stepping through the loop once, and the debugger should not
+ # stop for any of the remaining iterations.
+
+ gdb_test "until" "ival1 = count.*" "until to ival1 assignment"
+ gdb_test "until" "ival3 = count.*" "until to ival3 assignment"
+ send_gdb "until\n"
+ gdb_expect {
+ -re "(for \\(count = 0|\}).*$gdb_prompt $" {
+ gdb_test "until" "ival1 = count; /. Outside loop ./" \
+ "until out of loop"
+ }
+ -re "ival1 = count; /. Outside loop ./.*$gdb_prompt $" {
+ pass "until out of loop"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "until out of loop"
+ }
+ default { fail "until out of loop (timeout)" ; return }
+ }
+
+ gdb_test "step" "ival2 = count.*" "step to ival2 assignment"
+ }
+}
+
+# Test stepping and other mundane operations with watchpoints enabled
+proc test_watchpoint_triggered_in_syscall {} {
+ global gdb_prompt
+
+ # These tests won't work without printf support.
+ if [gdb_skip_stdio_test "watchpoints triggered in syscall"] {
+ return;
+ }
+ # Run until we get to the first marker function.
+ set x 0
+ set y 0
+ set testname "Watch buffer passed to read syscall"
+ if [runto marker2] then {
+ gdb_test "watch buf\[0\]" ".*\[Ww\]atchpoint \[0-9\]*: buf\\\[0\\\]"
+ gdb_test "watch buf\[1\]" ".*\[Ww\]atchpoint \[0-9\]*: buf\\\[1\\\]"
+ gdb_test "watch buf\[2\]" ".*\[Ww\]atchpoint \[0-9\]*: buf\\\[2\\\]"
+ gdb_test "watch buf\[3\]" ".*\[Ww\]atchpoint \[0-9\]*: buf\\\[3\\\]"
+ gdb_test "watch buf\[4\]" ".*\[Ww\]atchpoint \[0-9\]*: buf\\\[4\\\]"
+ gdb_test "break marker4" ".*Breakpoint.*"
+
+ gdb_test "set doread = 1" ""
+
+ # If we send_gdb "123\n" before gdb has switched the tty, then it goes
+ # to gdb, not the inferior, and we lose. So that is why we have
+ # watchpoint.c prompt us, so we can wait for that prompt.
+ send_gdb "continue\n";
+ gdb_expect {
+ -re "Continuing\\.\r\ntype stuff for buf now:" {
+ pass "continue to read"
+ }
+ default {
+ fail "continue to read";
+ return ;
+ }
+ }
+
+ send_gdb "123\n"
+ gdb_expect {
+ -re ".*\[Ww\]atchpoint.*buf\\\[0\\\].*Old value = 0.*New value = 49\[^\n\]*\n" { set x [expr $x+1] ; exp_continue }
+ -re ".*\[Ww\]atchpoint.*buf\\\[1\\\].*Old value = 0.*New value = 50\[^\n\]*\n" { set x [expr $x+1] ; exp_continue }
+ -re ".*\[Ww\]atchpoint.*buf\\\[2\\\].*Old value = 0.*New value = 51\[^\n\]*\n" { set x [expr $x+1] ; exp_continue }
+ -re ".*\[Ww\]atchpoint.*buf\\\[3\\\].*Old value = 0.*New value = 10\[^\n\]*\n" { set x [expr $x+1] ; exp_continue }
+ -re ".*$gdb_prompt $" { pass "sent 123" }
+ timeout { fail "sent 123 (timeout)" }
+ }
+
+ # Examine the values in buf to see how many watchpoints we
+ # should have printed.
+ send_gdb "print buf\[0\]\n"
+ gdb_expect {
+ -re ".*= 49.*$gdb_prompt $" { set y [expr $y+1]; pass "print buf\[0\]"}
+ -re ".*= 0.*$gdb_prompt $" { pass "print buf\[0\]"}
+ -re ".*$gdb_prompt $" { fail "print buf\[0\]"}
+ default { fail "print buf\[0\]"}
+ }
+ send_gdb "print buf\[1\]\n"
+ gdb_expect {
+ -re ".*= 50.*$gdb_prompt $" { set y [expr $y+1]; pass "print buf\[1\]"}
+ -re ".*= 0.*$gdb_prompt $" { pass "print buf\[1\]"}
+ -re ".*$gdb_prompt $" { fail "print buf\[1\]"}
+ default { fail "print buf\[1\]"}
+ }
+ send_gdb "print buf\[2\]\n"
+ gdb_expect {
+ -re ".*= 51.*$gdb_prompt $" { set y [expr $y+1]; pass "print buf\[2\]"}
+ -re ".*= 0.*$gdb_prompt $" { pass "print buf\[2\]"}
+ -re ".*$gdb_prompt $" { fail "print buf\[2\]"}
+ default { fail "print buf\[2\]"}
+ }
+ send_gdb "print buf\[3\]\n"
+ gdb_expect {
+ -re ".*= 10.*$gdb_prompt $" { set y [expr $y+1]; pass "print buf\[3\]"}
+ -re ".*= 0.*$gdb_prompt $" { pass "print buf\[3\]"}
+ -re ".*$gdb_prompt $" { fail "print buf\[3\]" }
+ default { fail "print buf\[3\]" }
+ }
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==$y] then { pass $testname } else { fail "$testname (only triggered $x watchpoints, expected $y)"}
+
+ # Continue until we hit the finishing marker function.
+ # Make sure we hit no more watchpoints.
+ gdb_test "cont" "Continuing.*Breakpoint.*marker4 \\(\\).*" \
+ "continue to marker4"
+
+ # Disable everything so we can finish the program at full speed
+ gdb_test "disable" "" "disable in test_watchpoint_triggered_in_syscall"
+
+ if [target_info exists gdb,noresults] { return }
+
+ gdb_continue_to_end "continue to exit in test_watchpoint_triggered_in_syscall"
+ }
+}
+
+# Do a simple test of of watching through a pointer when the pointer
+# itself changes. Should add some more complicated stuff here.
+
+proc test_complex_watchpoint {} {
+ global gdb_prompt
+
+ if [runto marker4] then {
+ gdb_test "watch ptr1->val" ".*\[Ww\]atchpoint \[0-9\]*: ptr1->val"
+ gdb_test "break marker5" ".*Breakpoint.*"
+
+ gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ptr1->val.*Old value = 1.*New value = 2.*" "Test complex watchpoint"
+
+ # Continue until we hit the marker5 function.
+ # Make sure we hit no more watchpoints.
+
+ gdb_test "cont" "Continuing.*Breakpoint.*marker5 \\(\\).*" \
+ "did not trigger wrong watchpoint"
+
+ # Test watches of things declared locally in a function.
+ # In particular, test that a watch of stack-based things
+ # is deleted when the stack-based things go out of scope.
+ #
+ gdb_test "disable" "" "disable in test_complex_watchpoint"
+ gdb_test "break marker6" ".*Breakpoint.*"
+ gdb_test "cont" "Continuing.*Breakpoint.*marker6 \\(\\).*" \
+ "continue to marker6"
+ gdb_test "break func2" ".*Breakpoint.*"
+ gdb_test "cont" "Continuing.*func2.*"
+
+ # Test a watch of a single stack-based variable, whose scope
+ # is the function we're now in. This should auto-delete when
+ # execution exits the scope of the watchpoint.
+ #
+ gdb_test "watch local_a" ".*\[Ww\]atchpoint \[0-9\]*: local_a" "set local watch"
+ gdb_test "cont" "\[Ww\]atchpoint.*local_a.*" "trigger local watch"
+ gdb_test "cont" "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" "self-delete local watch"
+
+ gdb_test "cont" "Continuing.*func2.*"
+ # We should be in "func2" again now. Test a watch of an
+ # expression which includes both a stack-based local and
+ # something whose scope is larger than this invocation
+ # of "func2". This should also auto-delete.
+ #
+ gdb_test "watch local_a + ival5" ".*\[Ww\]atchpoint \[0-9\]*: local_a . ival5" \
+ "set partially local watch"
+ gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: local_a . ival5.*" \
+ "trigger1 partially local watch"
+ gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: local_a . ival5.*" \
+ "trigger2 partially local watch"
+ gdb_test "cont" "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" \
+ "self-delete partially local watch"
+
+ # We should be in "func2" again now. Test a watch of a
+ # static (non-stack-based) local. Since this has scope
+ # across any invocations of "func2", it should not auto-
+ # delete.
+ #
+ gdb_test "cont" "Continuing.*func2.*"
+ gdb_test "watch static_b" ".*\[Ww\]atchpoint \[0-9\]*: static_b" \
+ "set static local watch"
+ gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: static_b.*" \
+ "trigger static local watch"
+ gdb_test "cont" "Continuing.*marker6 \\(\\).*" \
+ "continue after trigger static local watch"
+ gdb_test "info break" ".*watchpoint.*static_b.*" \
+ "static local watch did not self-delete"
+
+ # We should be in "recurser" now. Test a watch of a stack-
+ # based local. Symbols mentioned in a watchpoint are bound
+ # at watchpoint-creation. Thus, a watch of a stack-based
+ # local to a recursing function should be bound only to that
+ # one invocation, and should not trigger for other invocations.
+ #
+ gdb_test "tbreak recurser" ".*Breakpoint.*"
+ gdb_test "cont" "Continuing.*recurser.*"
+ gdb_test "watch local_x" ".*\[Ww\]atchpoint \[0-9\]*: local_x" \
+ "set local watch in recursive call"
+ gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: local_x.*New value = 2.*" \
+ "trigger local watch in recursive call"
+ gdb_test "cont" "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" \
+ "self-delete local watch in recursive call"
+
+ # Disable everything so we can finish the program at full speed
+ gdb_test "disable" "" "disable in test_complex_watchpoint"
+
+ if [target_info exists gdb,noresults] { return }
+
+ gdb_continue_to_end "continue to exit in test_complex_watchpoint"
+ }
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+set prev_timeout $timeout
+set timeout 600
+verbose "Timeout now 600 sec.\n"
+
+if [initialize] then {
+
+ test_simple_watchpoint
+
+ # The IDT/sim monitor only has 8 (!) open files, of which it uses
+ # 4 (!). So we have to make sure one program exits before
+ # starting another one.
+ if [istarget "mips-idt-*"] then {
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+ initialize
+ }
+
+ test_disabling_watchpoints
+
+ # See above.
+ if [istarget "mips-idt-*"] then {
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+ initialize
+ }
+
+ if ![target_info exists gdb,cannot_call_functions] {
+ test_stepping
+
+ # See above.
+ if [istarget "mips-idt-*"] then {
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+ initialize
+ }
+ }
+
+ # Only enabled for some targets merely because it has not been tested
+ # elsewhere.
+ # On sparc-sun-sunos4.1.3, GDB was running all the way to the marker4
+ # breakpoint before stopping for the watchpoint. I don't know why.
+ if {[istarget "hppa*-*-*"]} then {
+ test_watchpoint_triggered_in_syscall
+ }
+
+ # See above.
+ if [istarget "mips-idt-*"] then {
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+ initialize
+ }
+
+ # Only enabled for some targets merely because it has not been tested
+ # elsewhere.
+ if {[istarget "hppa*-*-*"] || \
+ [istarget "sparc*-*-sunos*"] || \
+ [istarget "m32r-*-*"]} then {
+ test_complex_watchpoint
+ }
+
+ # Verify that a user can force GDB to use "slow" watchpoints.
+ # (This proves rather little on kernels that don't support
+ # fast watchpoints, but still...)
+ #
+ if ![runto_main] then { fail "watch tests suppressed" }
+
+ send_gdb "set can-use-hw-watchpoints 0\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "disable fast watches"}
+ timeout {fail "(timeout) disable fast watches"}
+ }
+ send_gdb "show can-use-hw-watchpoints\n"
+ gdb_expect {
+ -re "Debugger's willingness to use watchpoint hardware is 0.*$gdb_prompt $"\
+ {pass "show disable fast watches"}
+ -re "$gdb_prompt $"\
+ {fail "show disable fast watches"}
+ timeout {fail "(timeout) show disable fast watches"}
+ }
+ send_gdb "watch ival3 if count > 1\n"
+ gdb_expect {
+ -re "Watchpoint \[0-9\]*: ival3.*$gdb_prompt $"\
+ {pass "set slow conditional watch"}
+ -re "$gdb_prompt $"\
+ {fail "set slow conditional watch"}
+ timeout {fail "(timeout) set slow conditional watch"}
+ }
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Watchpoint \[0-9\]*: ival3.*Old value = 1.*New value = 2.*$gdb_prompt $"\
+ {pass "trigger slow conditional watch"}
+ -re "$gdb_prompt $"\
+ {fail "trigger slow conditional watch"}
+ timeout {fail "(timeout) trigger slow conditional watch"}
+ }
+
+ # We've explicitly disabled hardware watches. Verify that GDB
+ #
+ #
+ send_gdb "rwatch ival3\n"
+ gdb_expect {
+ -re "Expression cannot be implemented with read/access watchpoint..*$gdb_prompt $"\
+ {pass "rwatch disallowed when can-set-hw-watchpoints cleared"}
+ -re "$gdb_prompt $"\
+ {fail "rwatch disallowed when can-set-hw-watchpoints cleared"}
+ timeout {fail "(timeout) rwatch disallowed when can-use-hw-watchpoints cleared"}
+ }
+
+ # Read- and access watchpoints are unsupported on HP-UX. Verify
+ # that GDB gracefully responds to requests to create them.
+ #
+ if [istarget "hppa*-*-hpux*"] then {
+ send_gdb "set can-use-hw-watchpoints 1\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "enable fast watches"}
+ timeout {fail "(timeout) enable fast watches"}
+ }
+ send_gdb "rwatch ival3\n"
+ gdb_expect {
+ -re "Target does not have this type of hardware watchpoint support.*$gdb_prompt $"\
+ {pass "read watches disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "read watches disallowed"}
+ timeout {fail "(timeout) read watches disallowed"}
+ }
+
+ send_gdb "awatch ival3\n"
+ gdb_expect {
+ -re "Target does not have this type of hardware watchpoint support.*$gdb_prompt $"\
+ {pass "access watches disallowed"}
+ -re "$gdb_prompt $"\
+ {fail "access watches disallowed"}
+ timeout {fail "(timeout) access watches disallowed"}
+ }
+ }
+}
+
+# Restore old timeout
+set timeout $prev_timeout
+verbose "Timeout now $timeout sec.\n"
diff --git a/gdb/testsuite/gdb.base/whatis-exp.exp b/gdb/testsuite/gdb.base/whatis-exp.exp
new file mode 100644
index 00000000000..e36683ed198
--- /dev/null
+++ b/gdb/testsuite/gdb.base/whatis-exp.exp
@@ -0,0 +1,217 @@
+# Copyright 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+# This file is part of the gdb testsuite
+#
+# tests for whatis command on expressions.
+# used in file eval.c. This flavor of whatis
+# command performs evaluation of expressions w/o actually
+# computing the value, but just the type
+# of the result. It goes through the evaluate_subexp_standard
+# with the EVAL_AVOID_SIDE_EFFECTS flag rather than EVAL_NORMAL
+#
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "int-type"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+#
+# test expressions with "int" types
+#
+
+gdb_test "set variable x=14" "" "set variable x=14"
+gdb_test "set variable y=2" "" "set variable y=2"
+gdb_test "set variable z=2" "" "set variable z=2"
+gdb_test "set variable w=3" "" "set variable w=3"
+
+send_gdb "print x\n"
+gdb_expect {
+ -re ".*14.*$gdb_prompt $" {
+ pass "print value of x"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of x" }
+ timeout { fail "(timeout) print value of x" }
+ }
+
+
+send_gdb "print y\n"
+gdb_expect {
+ -re ".*2.*$gdb_prompt $" {
+ pass "print value of y"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of y" }
+ timeout { fail "(timeout) print value of y" }
+ }
+
+send_gdb "print z\n"
+gdb_expect {
+ -re ".*2.*$gdb_prompt $" {
+ pass "print value of z"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of z" }
+ timeout { fail "(timeout) print value of z" }
+ }
+
+send_gdb "print w\n"
+gdb_expect {
+ -re ".*3.*$gdb_prompt $" {
+ pass "print value of w"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of w" }
+ timeout { fail "(timeout) print value of w" }
+ }
+
+
+
+send_gdb "whatis x+y\n"
+gdb_expect {
+ -re ".*type = long.*$gdb_prompt $" {
+ pass "whatis value of x+y"
+ }
+ -re ".*$gdb_prompt $" { fail "whatis value of x+y" }
+ timeout { fail "(timeout) whatis value of x+y" }
+ }
+
+send_gdb "whatis x-y\n"
+gdb_expect {
+ -re ".*type = long.*$gdb_prompt $" {
+ pass "whatis value of x-y"
+ }
+ -re ".*$gdb_prompt $" { fail "whatis value of x-y" }
+ timeout { fail "(timeout) whatis value of x-y" }
+ }
+
+send_gdb "whatis x*y\n"
+gdb_expect {
+ -re ".*type = long.*$gdb_prompt $" {
+ pass "whatis value of x*y"
+ }
+ -re ".*$gdb_prompt $" { fail "whatis value of x*y" }
+ timeout { fail "(timeout) whatis value of x*y" }
+ }
+
+send_gdb "whatis x/y\n"
+gdb_expect {
+ -re ".*type = int.*$gdb_prompt $" {
+ pass "whatis value of x/y"
+ }
+ -re ".*$gdb_prompt $" { fail "whatis value of x/y" }
+ timeout { fail "(timeout) whatis value of x/y" }
+ }
+
+send_gdb "whatis x%y\n"
+gdb_expect {
+ -re ".*type = int.*$gdb_prompt $" {
+ pass "whatis value of x%y"
+ }
+ -re ".*$gdb_prompt $" { fail "whatis value of x%y" }
+ timeout { fail "(timeout) whatis value of x%y" }
+ }
+
+
+
+send_gdb "whatis x=y\n"
+gdb_expect {
+ -re ".*type = int.*$gdb_prompt $" {
+ pass "whatis value of x=y"
+ }
+ -re ".*$gdb_prompt $" { fail "whatis value of x=y" }
+ timeout { fail "(timeout) whatis value of x=y" }
+ }
+
+
+send_gdb "whatis x+=2\n"
+gdb_expect {
+ -re ".*type = int.*$gdb_prompt $" {
+ pass "whatis value of x+=2"
+ }
+ -re ".*$gdb_prompt $" { fail "whatis value of x+=2" }
+ timeout { fail "(timeout) whatis value of x+=2" }
+ }
+
+
+send_gdb "whatis ++x\n"
+gdb_expect {
+ -re ".*type = int.*$gdb_prompt $" {
+ pass "whatis value of ++x"
+ }
+ -re ".*$gdb_prompt $" { fail "whatis value of ++x" }
+ timeout { fail "(timeout) whatis value of ++x" }
+ }
+
+send_gdb "whatis --x\n"
+gdb_expect {
+ -re ".*type = int.*$gdb_prompt $" {
+ pass "whatis value of --x"
+ }
+ -re ".*$gdb_prompt $" { fail "whatis value of --x" }
+ timeout { fail "(timeout) whatis value of --x" }
+ }
+
+send_gdb "whatis x++\n"
+gdb_expect {
+ -re ".*type = int.*$gdb_prompt $" {
+ pass "whatis value of x++"
+ }
+ -re ".*$gdb_prompt $" { fail "whatis value of x++" }
+ timeout { fail "(timeout) whatis value of x++" }
+ }
+
+send_gdb "whatis x--\n"
+gdb_expect {
+ -re ".*type = int.*$gdb_prompt $" {
+ pass "whatis value of x--"
+ }
+ -re ".*$gdb_prompt $" { fail "whatis value of x--" }
+ timeout { fail "(timeout) whatis value of x--" }
+ }
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.base/whatis.c b/gdb/testsuite/gdb.base/whatis.c
new file mode 100644
index 00000000000..63d5d3dae09
--- /dev/null
+++ b/gdb/testsuite/gdb.base/whatis.c
@@ -0,0 +1,269 @@
+/*
+ * Test file with lots of different types, for testing the
+ * "whatis" command.
+ */
+
+/*
+ * First the basic C types.
+ */
+
+#if !(defined (__STDC__) || defined (_AIX))
+#define signed /**/
+#endif
+
+char v_char;
+signed char v_signed_char;
+unsigned char v_unsigned_char;
+
+short v_short;
+signed short v_signed_short;
+unsigned short v_unsigned_short;
+
+int v_int;
+signed int v_signed_int;
+unsigned int v_unsigned_int;
+
+long v_long;
+signed long v_signed_long;
+unsigned long v_unsigned_long;
+
+float v_float;
+double v_double;
+
+/*
+ * Now some derived types, which are arrays, functions-returning,
+ * pointers, structures, unions, and enumerations.
+ */
+
+/**** arrays *******/
+
+char v_char_array[2];
+signed char v_signed_char_array[2];
+unsigned char v_unsigned_char_array[2];
+
+short v_short_array[2];
+signed short v_signed_short_array[2];
+unsigned short v_unsigned_short_array[2];
+
+int v_int_array[2];
+signed int v_signed_int_array[2];
+unsigned int v_unsigned_int_array[2];
+
+long v_long_array[2];
+signed long v_signed_long_array[2];
+unsigned long v_unsigned_long_array[2];
+
+float v_float_array[2];
+double v_double_array[2];
+
+/**** pointers *******/
+
+/* Make sure they still print as pointer to foo even there is a typedef
+ for that type. Test this not just for char *, which might be
+ a special case kludge in GDB (Unix system include files like to define
+ caddr_t), but for a variety of types. */
+typedef char *char_addr;
+typedef unsigned short *ushort_addr;
+typedef signed long *slong_addr;
+
+char *v_char_pointer;
+signed char *v_signed_char_pointer;
+unsigned char *v_unsigned_char_pointer;
+
+short *v_short_pointer;
+signed short *v_signed_short_pointer;
+unsigned short *v_unsigned_short_pointer;
+
+int *v_int_pointer;
+signed int *v_signed_int_pointer;
+unsigned int *v_unsigned_int_pointer;
+
+long *v_long_pointer;
+signed long *v_signed_long_pointer;
+unsigned long *v_unsigned_long_pointer;
+
+float *v_float_pointer;
+double *v_double_pointer;
+
+/**** structs *******/
+
+struct t_struct {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_struct1;
+
+struct {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_struct2;
+
+/**** unions *******/
+
+union t_union {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_union;
+
+union {
+ char v_char_member;
+ short v_short_member;
+ int v_int_member;
+ long v_long_member;
+ float v_float_member;
+ double v_double_member;
+} v_union2;
+
+/*** Functions returning type ********/
+
+char v_char_func () { return(0); }
+signed char v_signed_char_func () { return (0); }
+unsigned char v_unsigned_char_func () { return (0); }
+
+short v_short_func () { return (0); }
+signed short v_signed_short_func () { return (0); }
+unsigned short v_unsigned_short_func () { return (0); }
+
+int v_int_func () { return (0); }
+signed int v_signed_int_func () { return (0); }
+unsigned int v_unsigned_int_func () { return (0); }
+
+long v_long_func () { return (0); }
+signed long v_signed_long_func () { return (0); }
+unsigned long v_unsigned_long_func () { return (0); }
+
+float v_float_func () { return (0.0); }
+double v_double_func () { return (0.0); }
+
+/**** Some misc more complicated things *******/
+
+struct link {
+ struct link *next;
+#ifdef __STDC__
+ struct link *(*linkfunc) (struct link *this, int flags);
+#else
+ struct link *(*linkfunc) ();
+#endif
+ struct t_struct stuff[1][2][3];
+} *s_link;
+
+union tu_link {
+ struct link *next;
+#ifdef __STDC__
+ struct link *(*linkfunc) (struct link *this, int flags);
+#else
+ struct link *(*linkfunc) ();
+#endif
+ struct t_struct stuff[1][2][3];
+} u_link;
+
+struct outer_struct {
+ int outer_int;
+ struct inner_struct {
+ int inner_int;
+ long inner_long;
+ }inner_struct_instance;
+ union inner_union {
+ int inner_union_int;
+ long inner_union_long;
+ }inner_union_instance;
+ long outer_long;
+} nested_su;
+
+/**** Enumerations *******/
+
+enum colors {red, green, blue} color;
+enum cars {chevy, ford, porsche} clunker;
+
+/***********/
+
+int main ()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ /* Some linkers (e.g. on AIX) remove unreferenced variables,
+ so make sure to reference them. */
+ v_char = 0;
+ v_signed_char = 1;
+ v_unsigned_char = 2;
+
+ v_short = 3;
+ v_signed_short = 4;
+ v_unsigned_short = 5;
+
+ v_int = 6;
+ v_signed_int = 7;
+ v_unsigned_int = 8;
+
+ v_long = 9;
+ v_signed_long = 10;
+ v_unsigned_long = 11;
+
+ v_float = 100.0;
+ v_double = 200.0;
+
+
+ v_char_array[0] = v_char;
+ v_signed_char_array[0] = v_signed_char;
+ v_unsigned_char_array[0] = v_unsigned_char;
+
+ v_short_array[0] = v_short;
+ v_signed_short_array[0] = v_signed_short;
+ v_unsigned_short_array[0] = v_unsigned_short;
+
+ v_int_array[0] = v_int;
+ v_signed_int_array[0] = v_signed_int;
+ v_unsigned_int_array[0] = v_unsigned_int;
+
+ v_long_array[0] = v_long;
+ v_signed_long_array[0] = v_signed_long;
+ v_unsigned_long_array[0] = v_unsigned_long;
+
+ v_float_array[0] = v_float;
+ v_double_array[0] = v_double;
+
+ v_char_pointer = &v_char;
+ v_signed_char_pointer = &v_signed_char;
+ v_unsigned_char_pointer = &v_unsigned_char;
+
+ v_short_pointer = &v_short;
+ v_signed_short_pointer = &v_signed_short;
+ v_unsigned_short_pointer = &v_unsigned_short;
+
+ v_int_pointer = &v_int;
+ v_signed_int_pointer = &v_signed_int;
+ v_unsigned_int_pointer = &v_unsigned_int;
+
+ v_long_pointer = &v_long;
+ v_signed_long_pointer = &v_signed_long;
+ v_unsigned_long_pointer = &v_unsigned_long;
+
+ v_float_pointer = &v_float;
+ v_double_pointer = &v_double;
+
+ color = red;
+ clunker = porsche;
+
+ u_link.next = s_link;
+
+ v_union2.v_short_member = v_union.v_short_member;
+
+ v_struct1.v_char_member = 0;
+ v_struct2.v_char_member = 0;
+
+ nested_su.outer_int = 0;
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/whatis.exp b/gdb/testsuite/gdb.base/whatis.exp
new file mode 100644
index 00000000000..79c48e4da70
--- /dev/null
+++ b/gdb/testsuite/gdb.base/whatis.exp
@@ -0,0 +1,419 @@
+# Copyright 1988, 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1999, 2002
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile whatis
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+# Define a procedure to set up an xfail for all targets that put out a
+# `long' type as an `int' type.
+# Sun/Ultrix cc have this problem.
+# It was said that COFF targets can not distinguish int from long either.
+
+proc setup_xfail_on_long_vs_int {} {
+ global gcc_compiled
+
+ if {!$gcc_compiled} {
+ setup_xfail "*-sun-sunos4*" "*-*-ultrix*" "i*86-sequent-bsd*"
+ }
+}
+
+#
+# Test whatis command with basic C types
+#
+# The name printed now (as of 23 May 1993) is whatever name the compiler
+# uses in the stabs. So we need to deal with names both from gcc and
+# native compilers.
+#
+
+gdb_test "whatis v_char" \
+ "type = (unsigned char|char)" \
+ "whatis char"
+
+# If we did not use the signed keyword when compiling the file, don't
+# expect GDB to know that char is signed.
+if { $hp_cc_compiler || $hp_aCC_compiler } {
+ set signed_keyword_not_used 1
+}
+if $signed_keyword_not_used then {
+ set signed_char "char"
+} else {
+ set signed_char "signed char"
+}
+if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix*" }
+gdb_test "whatis v_signed_char" \
+ "type = $signed_char" \
+ "whatis signed char"
+
+gdb_test "whatis v_unsigned_char" \
+ "type = unsigned char" \
+ "whatis unsigned char"
+
+gdb_test "whatis v_short" \
+ "type = (short|short int)" \
+ "whatis short"
+
+gdb_test "whatis v_signed_short" \
+ "type = (short|short int|signed short|signed short int)" \
+ "whatis signed short"
+
+gdb_test "whatis v_unsigned_short" \
+ "type = (unsigned short|short unsigned int)" \
+ "whatis unsigned short"
+
+gdb_test "whatis v_int" \
+ "type = int" \
+ "whatis int"
+
+gdb_test "whatis v_signed_int" \
+ "type = (signed |)int" \
+ "whatis signed int"
+
+gdb_test "whatis v_unsigned_int" \
+ "type = unsigned int" \
+ "whatis unsigned int"
+
+setup_xfail_on_long_vs_int
+# AIX xlc gets this wrong and unsigned long right. Go figure.
+if {!$gcc_compiled} then {setup_xfail "rs6000-*-aix*"}
+gdb_test "whatis v_long" \
+ "type = (long|long int)" \
+ "whatis long"
+
+setup_xfail_on_long_vs_int
+# AIX xlc gets this wrong and unsigned long right. Go figure.
+if {!$gcc_compiled} then {setup_xfail "rs6000-*-aix*"}
+gdb_test "whatis v_signed_long" \
+ "type = (signed |)(long|long int)" \
+ "whatis signed long"
+
+setup_xfail_on_long_vs_int
+gdb_test "whatis v_unsigned_long" \
+ "type = (unsigned long|long unsigned int)" \
+ "whatis unsigned long"
+
+gdb_test "whatis v_float" \
+ "type = float" \
+ "whatis float"
+
+gdb_test "whatis v_double" \
+ "type = double" \
+ "whatis double"
+
+
+# test whatis command with arrays
+#
+# We already tested whether char prints as "char", so here we accept
+# "unsigned char", "signed char", and other perversions. No need for more
+# than one xfail for the same thing.
+gdb_test "whatis v_char_array" \
+ "type = (signed |unsigned |)char \\\[2\\\]" \
+ "whatis char array"
+
+gdb_test "whatis v_signed_char_array" \
+ "type = (signed |unsigned |)char \\\[2\\\]" \
+ "whatis signed char array"
+
+gdb_test "whatis v_unsigned_char_array" \
+ "type = unsigned char \\\[2\\\]" \
+ "whatis unsigned char array"
+
+gdb_test "whatis v_short_array" \
+ "type = (short|short int) \\\[2\\\]" \
+ "whatis short array"
+
+gdb_test "whatis v_signed_short_array" \
+ "type = (signed |)(short|short int) \\\[2\\\]" \
+ "whatis signed short array"
+
+gdb_test "whatis v_unsigned_short_array" \
+ "type = (unsigned short|short unsigned int) \\\[2\\\]" \
+ "whatis unsigned short array"
+
+gdb_test "whatis v_int_array" \
+ "type = int \\\[2\\\]" \
+ "whatis int array"
+
+gdb_test "whatis v_signed_int_array" \
+ "type = (signed |)int \\\[2\\\]" \
+ "whatis signed int array"
+
+gdb_test "whatis v_unsigned_int_array" \
+ "type = unsigned int \\\[2\\\]" \
+ "whatis unsigned int array"
+
+# We already tested whether long prints as long, so here we accept int
+# No need for more than one xfail for the same thing.
+gdb_test "whatis v_long_array" \
+ "type = (int|long|long int) \\\[2\\\]" \
+ "whatis long array"
+
+gdb_test "whatis v_signed_long_array" \
+ "type = (signed |)(int|long|long int) \\\[2\\\]" \
+ "whatis signed long array"
+
+gdb_test "whatis v_unsigned_long_array" \
+ "type = (unsigned (int|long|long int)|long unsigned int) \\\[2\\\]" \
+ "whatis unsigned long array"
+
+gdb_test "whatis v_float_array" \
+ "type = float \\\[2\\\]" \
+ "whatis float array"
+
+gdb_test "whatis v_double_array" \
+ "type = double \\\[2\\\]" \
+ "whatis double array"
+
+
+# test whatis command with pointers
+#
+# We already tested whether char prints as char, so accept various perversions
+# here. We especially want to make sure we test that it doesn't print as
+# caddr_t.
+gdb_test "whatis v_char_pointer" \
+ "type = (unsigned |signed |)char \\*" \
+ "whatis char pointer"
+
+gdb_test "whatis v_signed_char_pointer" \
+ "type = (unsigned |signed |)char \\*" \
+ "whatis signed char pointer"
+
+gdb_test "whatis v_unsigned_char_pointer" \
+ "type = unsigned char \\*" \
+ "whatis unsigned char pointer"
+
+gdb_test "whatis v_short_pointer" \
+ "type = (short|short int) \\*" \
+ "whatis short pointer"
+
+gdb_test "whatis v_signed_short_pointer" \
+ "type = (signed |)(short|short int) \\*" \
+ "whatis signed short pointer"
+
+gdb_test "whatis v_unsigned_short_pointer" \
+ "type = (unsigned short|short unsigned int) \\*" \
+ "whatis unsigned short pointer"
+
+gdb_test "whatis v_int_pointer" \
+ "type = int \\*" \
+ "whatis int pointer"
+
+gdb_test "whatis v_signed_int_pointer" \
+ "type = (signed |)int \\*" \
+ "whatis signed int pointer"
+
+gdb_test "whatis v_unsigned_int_pointer" \
+ "type = unsigned int \\*" \
+ "whatis unsigned int pointer"
+
+# We already tested whether long prints as long, so here we accept int
+gdb_test "whatis v_long_pointer" \
+ "type = (long|int|long int) \\*" \
+ "whatis long pointer"
+
+gdb_test "whatis v_signed_long_pointer" \
+ "type = (signed |)(long|int|long int) \\*" \
+ "whatis signed long pointer"
+
+gdb_test "whatis v_unsigned_long_pointer" \
+ "type = (unsigned (int|long|long int)|long unsigned int) \\*" \
+ "whatis unsigned long pointer"
+
+gdb_test "whatis v_float_pointer" \
+ "type = float \\*" \
+ "whatis float pointer"
+
+gdb_test "whatis v_double_pointer" \
+ "type = double \\*" \
+ "whatis double pointer"
+
+
+if { $hp_aCC_compiler } {
+ set unstruct "unnamed\.struct\..*"
+ set ununion "unnamed\.union\..*"
+} else {
+ set unstruct "\.\.\."
+ set ununion "\.\.\."
+}
+
+# test whatis command with structure types
+gdb_test "whatis v_struct1" \
+ "type = struct t_struct" \
+ "whatis named structure"
+
+gdb_test "whatis v_struct2" \
+ "type = struct \{$unstruct\}" \
+ "whatis unnamed structure"
+
+
+# test whatis command with union types
+gdb_test "whatis v_union" \
+ "type = union t_union" \
+ "whatis named union"
+
+gdb_test "whatis v_union2" \
+ "type = union \{$ununion\}" \
+ "whatis unnamed union"
+
+
+if { [istarget "hppa*-hp-hpux*"] && $hp_aCC_compiler } {
+ # HP-UX: HP aCC compiler w/ +objdebug option detects language as
+ # c++, so we need the 'void' pattern here.
+ # Without +objdebug compilation option we still need to match ''.
+ # - guo
+ set void "(void|)"
+} else {
+ set void ""
+}
+
+# test whatis command with functions return type
+gdb_test "whatis v_char_func" \
+ "type = (signed |unsigned |)char \\($void\\)" \
+ "whatis char function"
+
+gdb_test "whatis v_signed_char_func" \
+ "type = (signed |unsigned |)char \\($void\\)" \
+ "whatis signed char function"
+
+gdb_test "whatis v_unsigned_char_func" \
+ "type = unsigned char \\($void\\)" \
+ "whatis unsigned char function"
+
+gdb_test "whatis v_short_func" \
+ "type = short (int |)\\($void\\)" \
+ "whatis short function"
+
+gdb_test "whatis v_signed_short_func" \
+ "type = (signed |)short (int |)\\($void\\)" \
+ "whatis signed short function"
+
+gdb_test "whatis v_unsigned_short_func" \
+ "type = (unsigned short|short unsigned int) \\($void\\)" \
+ "whatis unsigned short function"
+
+gdb_test "whatis v_int_func" \
+ "type = int \\($void\\)" \
+ "whatis int function"
+
+gdb_test "whatis v_signed_int_func" \
+ "type = (signed |)int \\($void\\)" \
+ "whatis signed int function"
+
+gdb_test "whatis v_unsigned_int_func" \
+ "type = unsigned int \\($void\\)" \
+ "whatis unsigned int function"
+
+gdb_test "whatis v_long_func" \
+ "type = (long|int|long int) \\($void\\)" \
+ "whatis long function"
+
+gdb_test "whatis v_signed_long_func" \
+ "type = (signed |)(int|long|long int) \\($void\\)" \
+ "whatis signed long function"
+
+gdb_test "whatis v_unsigned_long_func" \
+ "type = (unsigned (int|long|long int)|long unsigned int) \\($void\\)" \
+ "whatis unsigned long function"
+
+# Sun /bin/cc calls this a function returning double.
+if {!$gcc_compiled} then {setup_xfail "*-sun-sunos4*"}
+gdb_test "whatis v_float_func" \
+ "type = float \\($void\\)" \
+ "whatis float function"
+
+gdb_test "whatis v_double_func" \
+ "type = double \\($void\\)" \
+ "whatis double function" \
+
+
+# test whatis command with some misc complicated types
+gdb_test "whatis s_link" \
+ "type = struct link \\*" \
+ "whatis complicated structure"
+
+gdb_test "whatis u_link" \
+ "type = union tu_link" \
+ "whatis complicated union"
+
+
+# test whatis command with enumerations
+gdb_test "whatis clunker" \
+ "type = enum cars" \
+ "whatis enumeration"
+
+
+# test whatis command with nested struct and union
+gdb_test "whatis nested_su" \
+ "type = struct outer_struct" \
+ "whatis outer structure"
+
+gdb_test "whatis nested_su.outer_int" \
+ "type = int" \
+ "whatis outer structure member"
+
+if {$hp_aCC_compiler} {
+ set outer "outer_struct::"
+} else {
+ set outer ""
+}
+
+gdb_test "whatis nested_su.inner_struct_instance" \
+ "type = struct ${outer}inner_struct" \
+ "whatis inner structure"
+
+gdb_test "whatis nested_su.inner_struct_instance.inner_int" \
+ "type = int" \
+ "whatis inner structure member"
+
+gdb_test "whatis nested_su.inner_union_instance" \
+ "type = union ${outer}inner_union" \
+ "whatis inner union"
+
+gdb_test "whatis nested_su.inner_union_instance.inner_union_int" \
+ "type = int" \
+ "whatis inner union member"
diff --git a/gdb/testsuite/gdb.c++/Makefile.in b/gdb/testsuite/gdb.c++/Makefile.in
new file mode 100644
index 00000000000..82672598750
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/Makefile.in
@@ -0,0 +1,27 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES = ambiguous annota2 anon-union cplusfuncs cttiadd \
+ derivation inherit local member-ptr method misc \
+ overload ovldbreak ref-typ ref-typ2 templates userdef virtfunc namespace ref-types
+
+all:
+ @echo "Nothing to be done for all..."
+
+info:
+install-info:
+dvi:
+install:
+uninstall: force
+installcheck:
+check:
+
+clean mostlyclean:
+ -rm -f *~ *.o *.ci
+ -rm -f core ${EXECUTABLES}
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
+
+Makefile: $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.c++/ambiguous.cc b/gdb/testsuite/gdb.c++/ambiguous.cc
new file mode 100644
index 00000000000..6ee7bc18ea9
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/ambiguous.cc
@@ -0,0 +1,110 @@
+
+void marker1()
+{
+ return;
+}
+
+class A1 {
+public:
+ int x;
+ int y;
+};
+
+class A2 {
+public:
+ int x;
+ int y;
+};
+
+class A3 {
+public:
+ int x;
+ int y;
+};
+
+class X : public A1, public A2 {
+public:
+ int z;
+};
+
+class L : public A1 {
+public:
+ int z;
+};
+
+class LV : public virtual A1 {
+public:
+ int z;
+};
+
+class M : public A2 {
+public:
+ int w;
+};
+
+class N : public L, public M {
+public:
+ int r;
+};
+
+class K : public A1 {
+public:
+ int i;
+};
+
+class KV : public virtual A1 {
+public:
+ int i;
+};
+
+class J : public K, public L {
+public:
+ int j;
+};
+
+class JV : public KV, public LV {
+public:
+ int jv;
+};
+
+class JVA1 : public KV, public LV, public A1 {
+public:
+ int jva1;
+};
+
+class JVA2 : public KV, public LV, public A2 {
+public:
+ int jva2;
+};
+
+class JVA1V : public KV, public LV, public virtual A1 {
+public:
+ int jva1v;
+};
+
+int main()
+{
+ A1 a1;
+ A2 a2;
+ A3 a3;
+ X x;
+ L l;
+ M m;
+ N n;
+ K k;
+ J j;
+ JV jv;
+ JVA1 jva1;
+ JVA2 jva2;
+ JVA1V jva1v;
+
+ int i;
+
+ i += k.i + m.w + a1.x + a2.x + a3.x + x.z + l.z + n.r + j.j;
+
+ marker1();
+
+}
+
+
+
diff --git a/gdb/testsuite/gdb.c++/ambiguous.exp b/gdb/testsuite/gdb.c++/ambiguous.exp
new file mode 100644
index 00000000000..4224b2d79fd
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/ambiguous.exp
@@ -0,0 +1,237 @@
+# Copyright 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file is part of the gdb testsuite
+
+# tests relating to ambiguous class members
+# Written by Satish Pai <pai@apollo.hp.com> 1997-07-28
+
+# This file is part of the gdb testsuite
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+
+set prms_id 0
+set bug_id 0
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "ambiguous"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile} "c++"] {
+ return -1;
+}
+
+if { $gcc_compiled } then { continue }
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+send_gdb "break marker1\n" ; gdb_expect -re ".*$gdb_prompt $"
+ send_gdb "cont\n"
+ gdb_expect {
+ -re "Break.* marker1 \\(\\) at .*:$decimal.*$gdb_prompt $" {
+ send_gdb "up\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" { pass "up from marker1" }
+ timeout { fail "up from marker1" }
+ }
+ }
+ -re "$gdb_prompt $" { fail "continue to marker1" }
+ timeout { fail "(timeout) continue to marker1" }
+ }
+
+# print out various class objects' members. The values aren't
+# important, just check that the warning is emitted at the
+# right times.
+
+# X is derived from A1 and A2; both A1 and A2 have a member 'x'
+send_gdb "print x.x\n"
+gdb_expect {
+ -re "warning: x ambiguous; using X::A2::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
+ pass "print x.x"
+ }
+ -re "warning: x ambiguous; using X::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
+ pass "print x.x"
+ }
+ -re ".*$gdb_prompt $" { fail "print x.x" }
+ timeout { fail "(timeout) print x.x" }
+}
+
+
+# N is derived from A1 and A2, but not immediately -- two steps
+# up in the hierarchy. Both A1 and A2 have a member 'x'.
+send_gdb "print n.x\n"
+gdb_expect {
+ -re "warning: x ambiguous; using N::M::A2::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
+ pass "print n.x"
+ }
+ -re "warning: x ambiguous; using N::L::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
+ pass "print n.x"
+ }
+ -re ".*$gdb_prompt $" { fail "print n.x" }
+ timeout { fail "(timeout) print n.x" }
+}
+
+# J is derived from A1 twice. A1 has a member x.
+send_gdb "print j.x\n"
+gdb_expect {
+ -re "warning: x ambiguous; using J::L::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
+ pass "print j.x"
+ }
+ -re "warning: x ambiguous; using J::K::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
+ pass "print j.x"
+ }
+ -re ".*$gdb_prompt $" { fail "print j.x" }
+ timeout { fail "(timeout) print j.x" }
+}
+
+# JV is derived from A1 but A1 is a virtual base. Should not
+# report an ambiguity in this case.
+send_gdb "print jv.x\n"
+gdb_expect {
+ -re "warning: x ambiguous.*Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
+ fail "print jv.x (ambiguity reported)"
+ }
+ -re "\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" { pass "print jv.x" }
+ -re ".*$gdb_prompt $" { fail "print jv.x (??)" }
+ timeout { fail "(timeout) print jv.x" }
+}
+
+# JVA1 is derived from A1; A1 occurs as a virtual base in two
+# ancestors, and as a non-virtual immediate base. Ambiguity must
+# be reported.
+send_gdb "print jva1.x\n"
+gdb_expect {
+ -re "warning: x ambiguous; using JVA1::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
+ pass "print jva1.x"
+ }
+ -re "warning: x ambiguous; using JVA1::KV::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
+ pass "print jva1.x"
+ }
+ -re ".*$gdb_prompt $" { fail "print jva1.x" }
+ timeout { fail "(timeout) print jva1.x" }
+}
+
+# JVA2 is derived from A1 & A2; A1 occurs as a virtual base in two
+# ancestors, and A2 is a non-virtual immediate base. Ambiguity must
+# be reported as A1 and A2 both have a member 'x'.
+send_gdb "print jva2.x\n"
+gdb_expect {
+ -re "warning: x ambiguous; using JVA2::A2::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
+ pass "print jva2.x"
+ }
+ -re "warning: x ambiguous; using JVA2::KV::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
+ pass "print jva2.x"
+ }
+ -re ".*$gdb_prompt $" { fail "print jva2.x" }
+ timeout { fail "(timeout) print jva2.x" }
+}
+
+# JVA1V is derived from A1; A1 occurs as a virtual base in two
+# ancestors, and also as a virtual immediate base. Ambiguity must
+# not be reported.
+send_gdb "print jva1v.x\n"
+gdb_expect {
+ -re "warning: x ambiguous.*Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
+ fail "print jva1v.x (ambiguity reported)"
+ }
+ -re "\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" { pass "print jva1v.x" }
+ -re ".*$gdb_prompt $" { fail "print jva1v.x (??)" }
+ timeout { fail "(timeout) print jva1v.x" }
+}
+
+# Now check for ambiguous bases.
+
+# J is derived from A1 twice; report ambiguity if a J is
+# cast to an A1.
+send_gdb "print (A1)j\n"
+gdb_expect {
+ -re "warning: A1 ambiguous; using J::L::A1. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" {
+ pass "print (A1)j"
+ }
+ -re "warning: A1 ambiguous; using J::K::A1. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" {
+ pass "print (A1)j"
+ }
+ -re ".*$gdb_prompt $" { fail "print (A1)j" }
+ timeout { fail "(timeout) print (A1)j" }
+}
+
+# JV is derived from A1 twice, but A1 is a virtual base; should
+# not report ambiguity when a JV is cast to an A1.
+send_gdb "print (A1)jv\n"
+gdb_expect {
+ -re "warning: A1 ambiguous.*Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" {
+ fail "print (A1)jv (ambiguity reported)"
+ }
+ -re "\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" { pass "print (A1)jv" }
+ -re ".*$gdb_prompt $" { fail "print (A1)jv (??)" }
+ timeout { fail "(timeout) print (A1)jv" }
+}
+
+# JVA1 is derived from A1; A1 is a virtual base and also a
+# non-virtual base. Must report ambiguity if a JVA1 is cast to an A1.
+send_gdb "print (A1)jva1\n"
+gdb_expect {
+ -re "warning: A1 ambiguous; using JVA1::A1. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" {
+ pass "print (A1)jva1"
+ }
+ -re "warning: A1 ambiguous; using JVA1::KV::A1. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" {
+ pass "print (A1)jva1"
+ }
+ -re ".*$gdb_prompt $" { fail "print (A1)jva1" }
+ timeout { fail "(timeout) print (A1)jva1" }
+}
+
+# JVA1V is derived from A1; A1 is a virtual base indirectly
+# and also directly; must not report ambiguity when a JVA1V is cast to an A1.
+send_gdb "print (A1)jva1v\n"
+gdb_expect {
+ -re "warning: A1 ambiguous.*Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" {
+ fail "print (A1)jva1v (ambiguity reported)"
+ }
+ -re "\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" { pass "print (A1)jva1v"
+ }
+ -re ".*$gdb_prompt $" { fail "print (A1)jva1v (??)" }
+ timeout { fail "(timeout) print (A1)jva1v" }
+}
+
diff --git a/gdb/testsuite/gdb.c++/annota2.cc b/gdb/testsuite/gdb.c++/annota2.cc
new file mode 100644
index 00000000000..234752e49af
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/annota2.cc
@@ -0,0 +1,28 @@
+#include <stdio.h>
+
+class A {
+public:
+ int x;
+ int y;
+ int foo (int arg);
+};
+
+
+int A::foo (int arg)
+{
+ x += arg;
+ return arg *2;
+}
+
+int main()
+{
+ A a;
+
+ a.x = 0;
+ a.x = 1;
+ a.y = 2;
+
+ printf ("a.x is %d\n", a.x);
+ return 0;
+}
+
diff --git a/gdb/testsuite/gdb.c++/annota2.exp b/gdb/testsuite/gdb.c++/annota2.exp
new file mode 100644
index 00000000000..51c11168c71
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/annota2.exp
@@ -0,0 +1,231 @@
+# Copyright 1999, 2000, 2001
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "annota2"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++ additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# are we on a target board? If so, don't run these tests.
+# note: this is necessary because we cannot use runto_main (which would
+# work for remote targets too) because of the different prompt we get
+# when using annotation level 2.
+#
+if [is_remote target] then {
+ return 0
+}
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+
+#
+# line number where we need to stop in main
+#
+set main_line 25
+
+# The commands we test here produce many lines of output; disable "press
+# <return> to continue" prompts.
+send_gdb "set height 0\n"
+gdb_expect -re "$gdb_prompt $"
+
+#
+# break at main
+#
+gdb_test "break 25" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "breakpoint main"
+
+
+#
+# NOTE: this prompt is OK only when the annotation level is > 1
+# NOTE: When this prompt is in use the gdb_test procedure cannot be used because
+# it assumes that the last char of the gdb_prompt is a white space. This is not
+# true with this annotated prompt. So we must use send_gdb and gdb_expect.
+#
+
+set old_gdb_prompt $gdb_prompt
+set gdb_prompt "\r\n\032\032pre-prompt\r\n$gdb_prompt \r\n\032\032prompt\r\n"
+
+send_gdb "set annotate 2\n"
+gdb_expect {
+ -re "set annotate 2\r\n$gdb_prompt$" { pass "annotation set at level 2" }
+ -re ".*$gdb_prompt$" { fail "annotation set at level 2" }
+ timeout { fail "annotation set at level 2 (timeout)" }
+ }
+
+send_gdb "run\n"
+ gdb_expect {
+ -re "$main_line.*$gdb_prompt$" { pass "run until main breakpoint" }
+ -re ".*$gdb_prompt$" { fail "run until main breakpoint" }
+ timeout { fail "run until main breakpoint (timeout)" }
+ }
+
+#
+# print class 'a' with public fields.
+# this will test:
+# annotate-field-begin
+# annotate-field-name-end
+# annotate-field-value
+# annotate-field-end
+#
+send_gdb "print a\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\n\r\n\032\032value-history-begin 1 -\r\n.*= \r\n\032\032value-history-value\r\n\\{\r\n\032\032field-begin -\r\nx\r\n\032\032field-name-end\r\n = \r\n\032\032field-value\r\n1\r\n\032\032field-end\r\n, \r\n\032\032field-begin -\r\ny\r\n\032\032field-name-end\r\n = \r\n\032\032field-value\r\n2\r\n\032\032field-end\r\n\\}\r\n\r\n\032\032value-history-end\r\n$gdb_prompt$" \
+ { pass "print class" }
+ -re ".*$gdb_prompt$" { fail "print class" }
+ timeout { fail "print class (timeout)" }
+}
+
+#
+# continue until exit
+# this will test:
+# annotate-exited
+#
+send_gdb "continue\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\nContinuing.\r\n\r\n\032\032starting\r\n\r\n\032\032frames-invalid\r\na.x is 1\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032exited 0\r\n\r\nProgram exited normally.\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032stopped\r\n$gdb_prompt$" \
+ { pass "continue until exit" }
+ -re ".*$gdb_prompt$" { fail "continue to exit" }
+ timeout { fail "continue to exit (timeout)" }
+}
+
+#
+# delete all breakpoints
+#
+send_gdb "delete\n"
+gdb_expect {
+ -re ".*Delete all breakpoints. \\(y or n\\) \r\n\032\032query.*$" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "\r\n\032\032post-query\r\n$gdb_prompt$" { pass "delete bps" }
+ -re ".*$gdb_prompt$" { fail "delete bps" }
+ timeout { fail "delete bps (timeout)" }
+ }
+ }
+ -re ".*$gdb_prompt$" { fail "delete bps" }
+ timeout { fail "delete bps (timeout)" }
+}
+
+#
+# break at first line of main.
+#
+send_gdb "break 22\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\n\r\n\032\032breakpoints-invalid\r\nBreakpoint.*at $hex: file.*$srcfile, line.*\r\n$gdb_prompt$" \
+ { pass "breakpoint at main" }
+ -re ".*$gdb_prompt$" { fail "break at main" }
+ timeout { fail "break at main (timeout)" }
+}
+
+#
+# change value of main_line
+#
+set main_line 22
+
+#
+# run program up to breakpoint.
+#
+
+
+send_gdb "run\n"
+ gdb_expect {
+ -re "$main_line.*$gdb_prompt$" { pass "run until main breakpoint" }
+ -re ".*$gdb_prompt$" { fail "run until main breakpoint" }
+ timeout { fail "run until main breakpoint (timeout)" }
+ }
+
+#
+# set up a watch point on a.x
+#
+send_gdb "watch a.x\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\n\r\n\032\032breakpoints-invalid\r\n.*atchpoint 3: a.x\r\n$gdb_prompt$" \
+ { pass "set watch on a.x" }
+ -re ".*$gdb_prompt$" { fail "set watch on a.x" }
+ timeout { fail "set watch on a.x (timeout)" }
+}
+
+#
+# do a next, so that the watchpoint triggers. This will test:
+# annotate-watchpoint
+#
+send_gdb "next\n"
+gdb_expect {
+ -re "\r\n\032\032post-prompt\r\n\r\n\032\032starting\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032watchpoint 3\r\nWatchpoint 3: a.x\r\n\r\nOld value = 0\r\nNew value = 1\r\n\r\n\032\032frame-begin 0 $hex\r\n\r\n\032\032frame-function-name\r\nmain\r\n\032\032frame-args\r\n \\(\\)\r\n\032\032frame-source-begin\r\n at \r\n\032\032frame-source-file\r\n.*$srcfile\r\n\032\032frame-source-file-end\r\n:\r\n\032\032frame-source-line\r\n$decimal\r\n\032\032frame-source-end\r\n\r\n\r\n\032\032source .*$srcfile.*beg:$hex\r\n\r\n\032\032frame-end\r\n\r\n\032\032stopped\r\n$gdb_prompt$" \
+ { pass "watch triggered on a.x" }
+ -re "\r\n\032\032post-prompt\r\n\r\n\032\032starting\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032watchpoint 3\r\n\.*atchpoint 3: a.x\r\n\r\nOld value = 0\r\nNew value = 1\r\n\r\n\032\032frame-begin 0 $hex\r\n\r\n\032\032frame-function-name\r\nmain\r\n\032\032frame-args\r\n \\(\\)\r\n\032\032frame-source-begin\r\n at \r\n\032\032frame-source-file\r\n.*$srcfile\r\n\032\032frame-source-file-end\r\n:\r\n\032\032frame-source-line\r\n$decimal\r\n\032\032frame-source-end\r\n\r\n\r\n\032\032source .*$srcfile.*beg:$hex\r\n\r\n\032\032frame-end\r\n\r\n\032\032stopped\r\n.*$gdb_prompt$" \
+ { pass "watch triggered on a.x" }
+ -re ".*$gdb_prompt$" { fail "watch triggered on a.x" }
+ timeout { fail "watch triggered on a.x (timeout)" }
+}
+
+
+#
+# send ^C to gdb, so that the quit() function gets called
+# and annotate-quit is tested
+# test:
+# annotate-quit
+#
+# This test sometimes fails, but not reproducibly. See gdb/544.
+#
+send_gdb "\003"
+gdb_expect {
+ -re "\r\n\032\032error-begin\r\nQuit\r\n\r\n\032\032quit\r\n$gdb_prompt$" \
+ { pass "annotate-quit" }
+ -re ".*$gdb_prompt$" { fail "annotate-quit" }
+ timeout { fail "annotate-quit (timeout)" }
+}
+
+#
+# FIXME: the testsuite does not currently have tests for
+# annotate_catchpoints and annotate_function_call
+# and a few variants of the annotations that are
+# tested (marked by FIXME on the annot?.exp files)
+#
+
+# reinstall the old prompt for the rest of the testsuite.
+
+set gdb_prompt $old_gdb_prompt
+
diff --git a/gdb/testsuite/gdb.c++/anon-union.cc b/gdb/testsuite/gdb.c++/anon-union.cc
new file mode 100644
index 00000000000..0b3fd130aeb
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/anon-union.cc
@@ -0,0 +1,55 @@
+
+struct Foo {
+ union {
+ int zero;
+ unsigned int one;
+ } num1;
+ struct X {
+ int rock;
+ unsigned int rock2;
+ };
+ union {
+ int pebble;
+ X x;
+ union {
+ int qux;
+ unsigned int mux;
+ };
+ unsigned int boulder;
+ };
+ union {
+ int paper;
+ unsigned int cloth;
+ };
+ union {
+ int two;
+ unsigned int three;
+ } num2;
+};
+
+union Bar {
+ int x;
+ unsigned int y;
+};
+
+
+int main()
+{
+ Foo foo = {0, 0};
+
+ foo.paper = 33;
+ foo.pebble = 44;
+ foo.mux = 55;
+
+ Bar bar = {0};
+
+ union {
+ int z;
+ unsigned int w;
+ }; w = 0;
+
+ bar.x = 33;
+
+ w = 45;
+
+}
diff --git a/gdb/testsuite/gdb.c++/anon-union.exp b/gdb/testsuite/gdb.c++/anon-union.exp
new file mode 100644
index 00000000000..9b86b5d94ab
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/anon-union.exp
@@ -0,0 +1,347 @@
+# Tests for anonymous union support.
+# Copyright 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Written by Satish Pai <pai@apollo.hp.com> 1997-08-19
+
+# This file is part of the gdb testsuite
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+
+set prms_id 0
+set bug_id 0
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "anon-union"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Start with a fresh gdb
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+send_gdb "set width 0\n"
+gdb_expect -re "$gdb_prompt $"
+
+#send_gdb "ptype foo\n"
+#gdb_expect {
+# -re "\r\n$gdb_prompt $" {
+# pass "ptype foo"
+# }
+# -re ".*$gdb_prompt $" { fail "ptype foo" }
+# timeout { fail "(timeout) ptype foo" }
+#}
+
+#send_gdb "ptype bar\n"
+#gdb_expect {
+# -re "\r\n$gdb_prompt $" {
+# pass "ptype foo"
+# }
+# -re ".*$gdb_prompt $" { fail "ptype foo" }
+# timeout { fail "(timeout) ptype foo" }
+#}
+
+# NOTE: Add -- ptype foo.x, etc. when things are working
+
+#Initialize foo
+send_gdb "next\n"
+gdb_expect {
+ -re "40\[ \t\]*foo.paper = 33;\r\n$gdb_prompt $" {
+ pass "next 1"
+ }
+ -re ".*$gdb_prompt $" { fail "next 1" }
+ timeout { fail "(timeout) next 1" }
+}
+
+# Print out the big anon union.
+send_gdb "print foo\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \{num1 = \{zero = 0, one = 0\}, \{pebble = 0, x = \{rock = 0, rock2 = 0\}, \{qux = 0, mux = 0\}, boulder = 0\}, \{paper = 0, cloth = 0\}, num2 = \{two = 0, three = 0\}\}\r\n$gdb_prompt $" {
+ pass "print foo 1"
+ }
+ -re ".*$gdb_prompt $" { fail "print foo 1" }
+ timeout { fail "(timeout) print foo 1" }
+}
+
+# Step over assignment to member
+
+send_gdb "next\n"
+gdb_expect {
+ -re "41\[ \t\]*foo.pebble = 44;\r\n$gdb_prompt $" {
+ pass "next 1"
+ }
+ -re ".*$gdb_prompt $" { fail "next 1" }
+ timeout { fail "(timeout) next 1" }
+}
+
+# Now print out anon union again
+send_gdb "print foo\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \{num1 = \{zero = 0, one = 0\}, \{pebble = 0, x = \{rock = 0, rock2 = 0\}, \{qux = 0, mux = 0\}, boulder = 0\}, \{paper = 33, cloth = 33\}, num2 = \{two = 0, three = 0\}\}\r\n$gdb_prompt $" {
+ pass "print foo 2"
+ }
+ -re ".*$gdb_prompt $" { fail "print foo 2" }
+ timeout { fail "(timeout) print foo 2" }
+}
+
+# Modify the member just set
+send_gdb "set var foo.cloth = 35\n"
+gdb_expect {
+ -re "\r\n$gdb_prompt $" {
+ pass "set var foo.cloth"
+ }
+ timeout { fail "(timeout) set var foo.cloth" }
+}
+
+# Now print out anon union again to see if the right member was set
+send_gdb "print foo\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \{num1 = \{zero = 0, one = 0\}, \{pebble = 0, x = \{rock = 0, rock2 = 0\}, \{qux = 0, mux = 0\}, boulder = 0\}, \{paper = 35, cloth = 35\}, num2 = \{two = 0, three = 0\}\}\r\n$gdb_prompt $" {
+ pass "print foo 3"
+ }
+ -re ".*$gdb_prompt $" { fail "print foo 3" }
+ timeout { fail "(timeout) print foo 3" }
+}
+
+
+# Step over next assignment to member
+
+send_gdb "next\n"
+gdb_expect {
+ -re "42\[ \t\]*foo.mux = 55;\r\n$gdb_prompt $" {
+ pass "next 2"
+ }
+ -re ".*$gdb_prompt $" { fail "next 2" }
+ timeout { fail "(timeout) next 2" }
+}
+
+# Now print out anon union again
+send_gdb "print foo\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \{num1 = \{zero = 0, one = 0\}, \{pebble = 44, x = \{rock = 44, rock2 = 0\}, \{qux = 44, mux = 44\}, boulder = 44\}, \{paper = 35, cloth = 35\}, num2 = \{two = 0, three = 0\}\}\r\n$gdb_prompt $" {
+ pass "print foo 4"
+ }
+ -re ".*$gdb_prompt $" { fail "print foo 4" }
+ timeout { fail "(timeout) print foo 4" }
+}
+
+# Modify the member just set
+send_gdb "set var foo.pebble = 45\n"
+gdb_expect {
+ -re "\r\n$gdb_prompt $" {
+ pass "set var foo.pebble"
+ }
+ timeout { fail "(timeout) set var foo.pebble" }
+}
+
+# Now print out anon union again to see if the right member was set
+send_gdb "print foo\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \{num1 = \{zero = 0, one = 0\}, \{pebble = 45, x = \{rock = 45, rock2 = 0\}, \{qux = 45, mux = 45\}, boulder = 45\}, \{paper = 35, cloth = 35\}, num2 = \{two = 0, three = 0\}\}\r\n$gdb_prompt $" {
+ pass "print foo 5"
+ }
+ -re ".*$gdb_prompt $" { fail "print foo 5" }
+ timeout { fail "(timeout) print foo 5" }
+}
+
+# Modify another member at a different level
+send_gdb "set var foo.qux = 46\n"
+gdb_expect {
+ -re "\r\n$gdb_prompt $" {
+ pass "set var foo.qux"
+ }
+ timeout { fail "(timeout) set var foo.qux" }
+}
+
+# Now print out anon union again to see if the right member was set
+send_gdb "print foo\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \{num1 = \{zero = 0, one = 0\}, \{pebble = 46, x = \{rock = 46, rock2 = 0\}, \{qux = 46, mux = 46\}, boulder = 46\}, \{paper = 35, cloth = 35\}, num2 = \{two = 0, three = 0\}\}\r\n$gdb_prompt $" {
+ pass "print foo 6"
+ }
+ -re ".*$gdb_prompt $" { fail "print foo 6" }
+ timeout { fail "(timeout) print foo 6" }
+}
+
+# Modify the member at another level, but not the first one in the union
+send_gdb "set var foo.mux = 47\n"
+gdb_expect {
+ -re "\r\n$gdb_prompt $" {
+ pass "set var foo.mux"
+ }
+ timeout { fail "(timeout) set var foo.mux" }
+}
+
+# Now print out anon union again to see if things worked
+send_gdb "print foo\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \{num1 = \{zero = 0, one = 0\}, \{pebble = 47, x = \{rock = 47, rock2 = 0\}, \{qux = 47, mux = 47\}, boulder = 47\}, \{paper = 35, cloth = 35\}, num2 = \{two = 0, three = 0\}\}\r\n$gdb_prompt $" {
+ pass "print foo 7"
+ }
+ -re ".*$gdb_prompt $" { fail "print foo 7" }
+ timeout { fail "(timeout) print foo 7" }
+}
+
+# Modify a member of a struct in an anon union
+send_gdb "set var foo.x.rock = 48\n"
+gdb_expect {
+ -re "\r\n$gdb_prompt $" {
+ pass "set var foo.x.rock"
+ }
+ timeout { fail "(timeout) set var foo.x.rock" }
+}
+
+# Now print out anon union again to see if things worked
+send_gdb "print foo\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \{num1 = \{zero = 0, one = 0\}, \{pebble = 48, x = \{rock = 48, rock2 = 0\}, \{qux = 48, mux = 48\}, boulder = 48\}, \{paper = 35, cloth = 35\}, num2 = \{two = 0, three = 0\}\}\r\n$gdb_prompt $" {
+ pass "print foo 8"
+ }
+ -re ".*$gdb_prompt $" { fail "print foo 8" }
+ timeout { fail "(timeout) print foo 8" }
+}
+
+# Modify a member of a struct in an anon union, but something
+# that doesn't alias to some other union member
+send_gdb "set var foo.x.rock2 = 49\n"
+gdb_expect {
+ -re "\r\n$gdb_prompt $" {
+ pass "set var foo.x.rock2"
+ }
+ timeout { fail "(timeout) set var foo.x.rock2" }
+}
+
+# Now print out anon union again to see if things worked
+send_gdb "print foo\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \{num1 = \{zero = 0, one = 0\}, \{pebble = 48, x = \{rock = 48, rock2 = 49\}, \{qux = 48, mux = 48\}, boulder = 48\}, \{paper = 35, cloth = 35\}, num2 = \{two = 0, three = 0\}\}\r\n$gdb_prompt $" {
+ pass "print foo 9"
+ }
+ -re ".*$gdb_prompt $" { fail "print foo 9" }
+ timeout { fail "(timeout) print foo 9" }
+}
+
+
+# Step over next four assignments
+send_gdb "next 4\n"
+gdb_expect {
+ -re "53\[ \t\]*w = 45;\r\n$gdb_prompt $" {
+ pass "next 3"
+ }
+ -re ".*$gdb_prompt $" { fail "next 3" }
+ timeout { fail "(timeout) next 3" }
+}
+
+# Tests for anon unions that are not members of a class or struct
+
+send_gdb "print w\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 0\r\n$gdb_prompt $" {
+ pass "print w 1"
+ }
+ -re ".*$gdb_prompt $" { fail "print w 1" }
+ timeout { fail "(timeout) print w 1" }
+}
+
+send_gdb "print z\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 0\r\n$gdb_prompt $" {
+ pass "print z 1"
+ }
+ -re ".*$gdb_prompt $" { fail "print z 1" }
+ timeout { fail "(timeout) print z 1" }
+}
+
+# Step over next assignment to w
+send_gdb "next\n"
+gdb_expect {
+ -re "55\[ \t\]*\}\r\n$gdb_prompt $" {
+ pass "next 4"
+ }
+ -re ".*$gdb_prompt $" { fail "next 4" }
+ timeout { fail "(timeout) next 4" }
+}
+
+# See if the change in value is noticed
+send_gdb "print w\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 45\r\n$gdb_prompt $" {
+ pass "print w 2"
+ }
+ -re ".*$gdb_prompt $" { fail "print w 2" }
+ timeout { fail "(timeout) print w 2" }
+}
+
+# See if z shows the same value
+send_gdb "print z\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 45\r\n$gdb_prompt $" {
+ pass "print z 2"
+ }
+ -re ".*$gdb_prompt $" { fail "print z 2" }
+ timeout { fail "(timeout) print z 2" }
+}
+
+# Set the anon union member
+send_gdb "set var z = 27\n"
+gdb_expect {
+ -re "\r\n$gdb_prompt $" {
+ pass "set var z"
+ }
+ timeout { fail "(timeout) set var z" }
+}
+
+# See if the change in value is noticed
+send_gdb "print w\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 27\r\n$gdb_prompt $" {
+ pass "print w 3"
+ }
+ -re ".*$gdb_prompt $" { fail "print w 3" }
+ timeout { fail "(timeout) print w 3" }
+}
+
+# See if z shows the same value
+send_gdb "print z\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 27\r\n$gdb_prompt $" {
+ pass "print z 3"
+ }
+ -re ".*$gdb_prompt $" { fail "print z 3" }
+ timeout { fail "(timeout) print z 3" }
+}
diff --git a/gdb/testsuite/gdb.c++/classes.exp b/gdb/testsuite/gdb.c++/classes.exp
new file mode 100644
index 00000000000..dbdea5d69c6
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/classes.exp
@@ -0,0 +1,929 @@
+# Copyright 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+set ws "\[\r\n\t \]+"
+set nl "\[\r\n\]+"
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "misc"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+
+if [get_compiler_info ${binfile} "c++"] {
+ return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+#
+# Test ptype of class objects.
+#
+
+proc test_ptype_class_objects {} {
+ global gdb_prompt
+ global ws
+ global nl
+
+ # Note that struct members are public by default, so we don't print
+ # "public:" for the public members of structs.
+ # Accept it as an expected failure if gdb just fails to distinguish between
+ # class and struct, and everything else is OK.
+
+ send_gdb "ptype struct default_public_struct\n"
+ gdb_expect {
+ -re "type = struct default_public_struct \{${ws}int a;${ws}int b;$nl\}$nl$gdb_prompt $" {
+ pass "ptype struct default_public_struct"
+ }
+ -re "type = class default_public_struct \{$nl.*int a;${ws}int b;$nl.*\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype struct default_public_struct"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype struct default_public_struct" }
+ timeout { fail "ptype struct default_public_struct (timeout)" ; return }
+ }
+
+ # Note that struct members are public by default, so we don't print
+ # "public:" for the public members of structs.
+ # Accept it as an expected failure if gdb just fails to distinguish between
+ # class and struct, and everything else is OK.
+
+ send_gdb "ptype struct explicit_public_struct\n"
+ gdb_expect {
+ -re "type = struct explicit_public_struct \{${ws}int a;${ws}int b;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype struct explicit_public_struct"
+ }
+ -re "type = class explicit_public_struct \{$nl.*int a;${ws}int b;$nl.*\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype struct explicit_public_struct"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype struct explicit_public_struct" }
+ timeout { fail "ptype struct explicit_public_struct (timeout)" ; return }
+ }
+
+ # Accept it as an expected failure if gdb just fails to distinguish between
+ # class and struct, and everything else is OK.
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype struct protected_struct\n"
+ gdb_expect {
+ -re "type = struct protected_struct \{${ws}protected:${ws}int a;${ws}int b;$nl\}$nl$gdb_prompt $" {
+ pass "ptype struct protected_struct (FIXME)"
+ }
+ -re "type = class protected_struct \{${ws}protected:${ws}int a;${ws}int b;$nl.*\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype struct protected_struct (FIXME)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype struct protected_struct" }
+ timeout { fail "ptype struct protected_struct (timeout)" ; return }
+ }
+
+ # Accept it as an expected failure if gdb just fails to distinguish between
+ # class and struct, and everything else is OK.
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype struct private_struct\n"
+ gdb_expect {
+ -re "type = struct private_struct \{${ws}private:${ws}int a;${ws}int b;$nl\}$nl$gdb_prompt $" {
+ pass "ptype struct private_struct (FIXME)"
+ }
+ -re "type = class private_struct \{${ws}private:${ws}int a;${ws}int b;$nl.*\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype struct private_struct (FIXME)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype struct private_struct" }
+ timeout { fail "ptype struct private_struct (timeout)" ; return }
+ }
+
+ # Accept it as an expected failure if gdb just fails to distinguish between
+ # class and struct, and everything else is OK.
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype struct mixed_protection_struct\n"
+ gdb_expect {
+ -re "type = struct mixed_protection_struct \{${ws}int a;${ws}int b;${ws}private:${ws}int c;${ws}int d;${ws}protected:${ws}int e;${ws}int f;${ws}public:${ws}int g;${ws}private:${ws}int h;${ws}protected:${ws}int i;$nl\}$nl$gdb_prompt $" {
+ pass "ptype struct mixed_protection_struct (FIXME)"
+ }
+ -re "type = struct mixed_protection_struct \{${ws}public:${ws}int a;${ws}int b;${ws}private:${ws}int c;${ws}int d;${ws}protected:${ws}int e;${ws}int f;${ws}public:${ws}int g;${ws}private:${ws}int h;${ws}protected:${ws}int i;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype struct mixed_protection_struct (extra public)"
+ }
+ -re "type = class mixed_protection_struct \{${ws}public:${ws}int a;${ws}int b;${ws}private:${ws}int c;${ws}int d;${ws}protected:${ws}int e;${ws}int f;${ws}public:${ws}int g;${ws}private:${ws}int h;${ws}protected:${ws}int i;$nl.*\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype struct mixed_protection_struct (FIXME)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype struct mixed_protection_struct" }
+ timeout { fail "ptype struct mixed_protection_struct (timeout)" ; return }
+ }
+
+ # Accept it as an expected failure if gdb just fails to distinguish between
+ # class and struct, and everything else is OK.
+
+ send_gdb "ptype class public_class\n"
+ gdb_expect {
+ -re "type = class public_class \{${ws}public:${ws}int a;${ws}int b;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype class public_class (FIXME)"
+ }
+ -re "type = struct public_class \{${ws}int a;${ws}int b;$nl\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype class public_class (FIXME)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype class public_class" }
+ timeout { fail "ptype class public_class (timeout)" ; return }
+ }
+
+ send_gdb "ptype class protected_class\n"
+ gdb_expect {
+ -re "type = class protected_class \{${ws}protected:${ws}int a;${ws}int b;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype class protected_class"
+ }
+ -re "type = struct protected_class \{${ws}int a;${ws}int b;$nl\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype class protected_class"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype class protected_class" }
+ timeout { fail "ptype class protected_class (timeout)" ; return }
+ }
+
+ # Accept it as an expected failure if gdb just emits a superflous "private:"
+ # attribute, since classes default to private and for consistency with
+ # structs (where we don't print the "public:" attribute) we don't print
+ # the "private:" attribute.
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class default_private_class\n"
+ gdb_expect {
+ -re "type = class default_private_class \{${ws}int a;${ws}int b;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype class default_private_class (FIXME)"
+ }
+ -re "type = class default_private_class \{${ws}private:${ws}int a;${ws}int b;$nl.*\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype class default_private_class (FIXME)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype class default_private_class" }
+ timeout { fail "ptype class default_private_class (timeout)" ; return }
+ }
+
+ send_gdb "ptype class explicit_private_class\n"
+ gdb_expect {
+ -re "type = class explicit_private_class \{${ws}private:${ws}int a;${ws}int b;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype class explicit_private_class"
+ }
+ -re "type = class explicit_private_class \{${ws}int a;${ws}int b;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype class explicit_private_class (OK for HP aCC)"
+ }
+ -re "type = struct explicit_private_class \{${ws}int a;${ws}int b;$nl.*\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype class explicit_private_class"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype class explicit_private_class" }
+ timeout { fail "ptype class explicit_private_class (timeout)" ; return }
+ }
+
+ send_gdb "ptype class mixed_protection_class\n"
+ gdb_expect {
+ -re "type = class mixed_protection_class \{${ws}public:${ws}int a;${ws}int b;${ws}private:${ws}int c;${ws}int d;${ws}protected:${ws}int e;${ws}int f;${ws}public:${ws}int g;${ws}private:${ws}int h;${ws}protected:${ws}int i;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype class mixed_protection_class"
+ }
+ -re "type = struct mixed_protection_class \{${ws}int a;${ws}int b;${ws}int c;${ws}int d;${ws}int e;${ws}int f;${ws}int g;${ws}int h;${ws}int i;$nl.*\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype class mixed_protection_class"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype class mixed_protection_class" }
+ timeout { fail "ptype class mixed_protection_class (timeout)" ; return }
+ }
+
+ # This class does not use any C++-specific features, so it's fine for
+ # it to print as "struct".
+ send_gdb "ptype class A\n"
+ gdb_expect {
+ -re "type = (class|struct) A \{(${ws}public:|)${ws}int a;${ws}int x;((${ws}A & operator=\\(A const ?&\\);)|(${ws}A\\((A const|const A) ?&\\);)|(${ws}A\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class A"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype class A"
+ }
+ timeout {
+ fail "ptype class A (timeout)"
+ return
+ }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class B\n"
+ gdb_expect {
+ -re "type = class B : public A \{${ws}public:${ws}int b;${ws}int x;${ws}B & operator=\\(B const ?&\\);${ws}B\\((B const|const B) ?&\\);${ws}B\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class B"
+ }
+ -re "type = class B : public A \{${ws}public:${ws}int b;${ws}int x;((${ws}B & operator=\\(B const ?&\\);)|(${ws}B\\(B const ?&\\);)|(${ws}B\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class B (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype class B"
+ }
+ timeout {
+ fail "ptype class B (timeout)"
+ return
+ }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class C\n"
+ gdb_expect {
+ -re "type = class C : public A \{${ws}public:${ws}int c;${ws}int x;${ws}C & operator=\\(C const ?&\\);${ws}C\\((C const|const C) ?&\\);${ws}C\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class C"
+ }
+ -re "type = class C : public A \{${ws}public:${ws}int c;${ws}int x;((${ws}C & operator=\\(C const ?&\\);)|(${ws}C\\(C const ?&\\);)|(${ws}C\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class C (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype class C"
+ }
+ timeout {
+ fail "ptype class C (timeout)"
+ return
+ }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class D\n"
+ gdb_expect {
+ -re "type = class D : public B, public C \{${ws}public:${ws}int d;${ws}int x;${ws}D & operator=\\(D const ?&\\);${ws}D\\((D const|const D) ?&\\);${ws}D\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class D"
+ }
+ -re "type = class D : public B, public C \{${ws}public:${ws}int d;${ws}int x;((${ws}D & operator=\\(D const ?&\\);)|(${ws}D\\(D const ?&\\);)|(${ws}D\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class D (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype class D"
+ }
+ timeout {
+ fail "ptype class D (timeout)"
+ return
+ }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class E\n"
+ gdb_expect {
+ -re "type = class E : public D \{${ws}public:${ws}int e;${ws}int x;${ws}E & operator=\\(E const ?&\\);${ws}E\\((E const|const E) ?&\\);${ws}E\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class E"
+ }
+ -re "type = class E : public D \{${ws}public:${ws}int e;${ws}int x;((${ws}E & operator=\\(E const ?&\\);)|(${ws}E\\((E const|const E) ?&\\);)|(${ws}E\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class E"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype class E"
+ }
+ timeout {
+ fail "ptype class E (timeout)"
+ return
+ }
+ }
+
+ # With g++ 2.x and stabs debug info, we misinterpret static methods
+ # whose name matches their argument mangling.
+ send_gdb "ptype class Static\n"
+ gdb_expect {
+ -re "type = (class|struct) Static \{(${ws}public:|)${ws}Static & operator=\\(Static const ?&\\);${ws}Static\\((Static const|const Static) ?&\\);${ws}Static\\((void|)\\);${ws}static void ii\\(int, int\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class Static"
+ }
+ -re "type = (class|struct) Static \{(${ws}public:|)${ws}static void ii\\(int, int\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class Static"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype class Static"
+ }
+ timeout {
+ fail "ptype class Static (timeout)"
+ return
+ }
+ }
+
+ send_gdb "ptype class vA\n"
+ gdb_expect {
+ -re "type = (class|struct) vA \{(${ws}public:|)${ws}int va;${ws}int vx;${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class vA"
+ }
+ -re "type = (class|struct) vA \{(${ws}public:|)${ws}int va;${ws}int vx;${ws}vA & operator=\\(vA const ?&\\);${ws}vA\\((vA const|const vA) ?&\\);${ws}vA\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class vA"
+ }
+ -re "type = (class|struct) vA \{(${ws}public:|)${ws}int va;${ws}int vx;((${ws}vA & operator=\\(vA const ?&\\);)|(${ws}vA\\(vA const ?&\\);)|(${ws}vA\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class vA (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype class vA"
+ }
+ timeout {
+ fail "ptype class vA (timeout)"
+ return
+ }
+ }
+
+ # Accept the form with embedded GNU style mangled virtual table constructs
+ # for now, but with a FIXME. At some future point, gdb should use a
+ # portable representation for the virtual table constructs.
+
+ # The format of a g++ virtual base pointer.
+ set vbptr "(_vb\[$.\]|__vb_)\[0-9\]?"
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class vB\n"
+ gdb_expect {
+ -re "type = class vB : public virtual vA \{${ws}public:${ws}int vb;${ws}int vx;${ws}vB & operator=\\(vB const ?&\\);${ws}vB\\((vB const|const vB) ?&\\);${ws}vB\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class vB"
+ }
+ -re "type = class vB : public virtual vA \{${ws}private:${ws}vA \\*${vbptr}vA;${ws}public:${ws}int vb;${ws}int vx;${ws}vB & operator=\\(vB const ?&\\);${ws}vB\\(int, vB const ?&\\);${ws}vB\\(int\\);${ws}\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype class vB (FIXME: non-portable virtual table constructs)"
+ }
+ -re "type = class vB : public virtual vA \{${ws}public:${ws}int vb;${ws}int vx;${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class vB"
+ }
+ -re "type = class vB : public virtual vA \{${ws}private:${ws}vA \\*_vb.vA;${ws}public:${ws}int vb;${ws}int vx;((${ws}vB & operator=\\(vB const ?&\\);)|(${ws}vB\\(int, vB const ?&\\);)|(${ws}vB\\(int\\);))*${ws}\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype class vB (FIXME) (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype class vB"
+ }
+ timeout {
+ fail "ptype class vB (timeout)"
+ return
+ }
+ }
+
+ # Accept the form with embedded GNU style mangled virtual table constructs
+ # for now, but with a FIXME. At some future point, gdb should use a
+ # portable representation for the virtual table constructs.
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class vC\n"
+ gdb_expect {
+ -re "type = class vC : public virtual vA \{${ws}public:${ws}int vc;${ws}int vx;${ws}vC & operator=\\(vC const ?&\\);${ws}vC\\((vC const|const vC) ?&\\);${ws}vC\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class vC"
+ }
+ -re "type = class vC : public virtual vA \{${ws}private:${ws}vA \\*${vbptr}vA;${ws}public:${ws}int vc;${ws}int vx;${ws}vC & operator=\\(vC const ?&\\);${ws}vC\\(int, vC const ?&\\);${ws}vC\\(int\\);${ws}\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype class vC (FIXME: non-portable virtual table constructs)"
+ }
+ -re "type = class vC : public virtual vA \{${ws}public:${ws}int vc;${ws}int vx;${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class vC"
+ }
+ -re "type = class vC : public virtual vA \{${ws}private:${ws}vA \\*_vb.vA;${ws}public:${ws}int vc;${ws}int vx;((${ws}vC & operator=\\(vC const ?&\\);)|(${ws}vC\\(int, vC const ?&\\);)|(${ws}vC\\(int\\);))*${ws}\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype class vC (FIXME) (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype class vC"
+ }
+ timeout {
+ fail "ptype class vC (timeout)"
+ return
+ }
+ }
+
+ # Accept the form with embedded GNU style mangled virtual table constructs
+ # for now, but with a FIXME. At some future point, gdb should use a
+ # portable representation for the virtual table constructs.
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class vD\n"
+ gdb_expect {
+ -re "type = class vD : public virtual vB, public virtual vC \{${ws}public:${ws}int vd;${ws}int vx;${ws}vD & operator=\\(vD const ?&\\);${ws}vD\\((vD const|const vD) ?&\\);${ws}vD\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class vD"
+ }
+ -re "type = class vD : public virtual vB, public virtual vC \{${ws}private:${ws}vC \\*${vbptr}vC;${ws}vB \\*${vbptr}vB;${ws}public:${ws}int vd;${ws}int vx;${ws}vD & operator=\\(vD const ?&\\);${ws}vD\\(int, vD const ?&\\);${ws}vD\\(int\\);${ws}\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype class vD (FIXME: non-portable virtual table constructs)"
+ }
+ -re "type = class vD : public virtual vB, public virtual vC \{${ws}public:${ws}int vd;${ws}int vx;${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class vD"
+ }
+ -re "type = class vD : public virtual vB, public virtual vC \{${ws}private:${ws}vC \\*_vb.vC;${ws}vB \\*_vb.vB;${ws}public:${ws}int vd;${ws}int vx;((${ws}vD & operator=\\(vD const ?&\\);)|(${ws}vD\\(int, vD const ?&\\);)|(${ws}vD\\(int\\);))*${ws}\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype class vD (FIXME) (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype class vD"
+ }
+ timeout {
+ fail "ptype class vD (timeout)"
+ return
+ }
+ }
+
+ # Accept the form with embedded GNU style mangled virtual table constructs
+ # for now, but with a FIXME. At some future point, gdb should use a
+ # portable representation for the virtual table constructs.
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class vE\n"
+ gdb_expect {
+ -re "type = class vE : public virtual vD \{${ws}public:${ws}int ve;${ws}int vx;${ws}vE & operator=\\(vE const ?&\\);${ws}vE\\((vE const|const vE) ?&\\);${ws}vE\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class vE"
+ }
+ -re "type = class vE : public virtual vD \{${ws}private:${ws}vD \\*${vbptr}vD;${ws}public:${ws}int ve;${ws}int vx;${ws}vE & operator=\\(vE const ?&\\);${ws}vE\\(int, vE const ?&\\);${ws}vE\\(int\\);${ws}\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype class vE (FIXME: non-portable virtual table constructs)"
+ }
+ -re "type = class vE : public virtual vD \{${ws}public:${ws}int ve;${ws}int vx;${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class vE"
+ }
+ -re "type = class vE : public virtual vD \{${ws}private:${ws}vD \\*_vb.vD;${ws}public:${ws}int ve;${ws}int vx;((${ws}vE & operator=\\(vE const ?&\\);)|(${ws}vE\\(int, vE const ?&\\);)|(${ws}vE\\(int\\);))*${ws}\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype class vE (FIXME) (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype class vE"
+ }
+ timeout {
+ fail "ptype class vE (timeout)"
+ return
+ }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class Base1\n"
+ gdb_expect {
+ -re "type = class Base1 \{${ws}public:${ws}int x;${ws}Base1 & operator=\\(Base1 const ?&\\);${ws}Base1\\(((Base1 const)|(const Base1)) ?&\\);${ws}Base1\\(int\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class Base1"
+ }
+ -re "type = class Base1 \{${ws}public:${ws}int x;${ws}Base1\\(int\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class Base1"
+ }
+ -re "type = class Base1 \{${ws}public:${ws}int x;((${ws}Base1 & operator=\\(Base1 const ?&\\);)|(${ws}Base1\\(Base1 const ?&\\);)|(${ws}Base1\\(int\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class Base1 (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype class Base1"
+ }
+ timeout {
+ fail "ptype class Base1 (timeout)"
+ return
+ }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class Foo\n"
+ gdb_expect {
+ -re "type = class Foo \{${ws}public:${ws}int x;${ws}int y;${ws}static int st;\r\n${ws}Foo\\(int, int\\);${ws}int operator!\\((void|)\\);${ws}operator int\\((void|)\\);${ws}int times\\(int\\);$nl\}$nl$gdb_prompt $" {
+ pass "ptype class Foo"
+ }
+ -re "type = class Foo \{${ws}public:${ws}int x;${ws}int y;${ws}static int st;${ws}Foo & operator=\\(Foo const ?&\\);${ws}Foo\\((Foo const|const Foo) ?&\\);${ws}Foo\\(int, int\\);${ws}int operator!\\((void|)\\);${ws}operator int\\((void|)\\);${ws}int times\\(int\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class Foo"
+ }
+ -re "type = class Foo \{${ws}public:${ws}int x;${ws}int y;${ws}static int st;((${ws}Foo & operator=\\(Foo const ?&\\);)|(${ws}Foo\\(Foo const ?&\\);)|(${ws}Foo\\(int, int\\);)|(${ws}int operator!\\((void|)\\);)|(${ws}int operator int\\((void|)\\);)|(${ws}int times\\(int\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class Foo (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype class Foo"
+ }
+ timeout {
+ fail "ptype class Foo (timeout)"
+ return
+ }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class Bar\n"
+ gdb_expect {
+ -re "type = class Bar : public Base1, public Foo \{${ws}public:${ws}int z;${ws}Bar & operator=\\(Bar const ?&\\);${ws}Bar\\((Bar const|const Bar) ?&\\);${ws}Bar\\(int, int, int\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class Bar"
+ }
+ -re "type = class Bar : public Base1, public Foo \{${ws}public:${ws}int z;((${ws}Bar & operator=\\(Bar const ?&\\);)|(${ws}Bar\\(Bar const ?&\\);)|(${ws}Bar\\(int, int, int\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype class Bar (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype class Bar"
+ }
+ timeout {
+ fail "ptype class Bar (timeout)"
+ return
+ }
+ }
+}
+
+#
+# Test simple access to class members.
+#
+
+proc test_non_inherited_member_access {} {
+ global gdb_prompt
+
+ # Print non-inherited members of g_A.
+
+ gdb_test "print g_A.a" ".* = 1" "g_A.a incorrect"
+
+ gdb_test "print g_A.x" ".* = 2" "g_A.x incorrect"
+
+ # Print non-inherited members of g_B.
+
+ gdb_test "print g_B.b" ".* = 5" "g_B.b incorrect"
+
+ gdb_test "print g_B.x" ".* = 6" "g_B.x incorrect"
+
+ # Print non-inherited members of g_C.
+
+ gdb_test "print g_C.c" ".* = 9" "g_C.c incorrect"
+
+ gdb_test "print g_C.x" ".* = 10" "g_C.x incorrect"
+
+ # Print non-inherited members of g_D.
+
+ gdb_test "print g_D.d" ".* = 19" "g_D.d incorrect"
+
+ gdb_test "print g_D.x" ".* = 20" "g_D.x incorrect"
+
+ # Print non-inherited members of g_E.
+
+ gdb_test "print g_E.e" ".* = 31" "g_E.e incorrect"
+
+ gdb_test "print g_E.x" ".* = 32" "g_E.x incorrect"
+}
+
+#
+# Try access to non-members that are members of another class.
+# Should give errors.
+#
+
+proc test_wrong_class_members {} {
+ global gdb_prompt
+
+ gdb_test "print g_A.b" "There is no member( or method|) named b." "print g_A.b should be error"
+
+ gdb_test "print g_B.c" "There is no member( or method|) named c." "print g_B.c should be error"
+
+ gdb_test "print g_B.d" "There is no member( or method|) named d." "print g_B.d should be error"
+
+ gdb_test "print g_C.b" "There is no member( or method|) named b." "print g_C.b should be error"
+
+ gdb_test "print g_C.d" "There is no member( or method|) named d." "print g_C.d should be error"
+
+ gdb_test "print g_D.e" "There is no member( or method|) named e." "print g_D.e should be error"
+}
+
+#
+# Try access to non-members that are not members of any class.
+# Should give errors.
+#
+
+proc test_nonexistent_members {} {
+ global gdb_prompt
+
+ gdb_test "print g_A.y" "There is no member( or method|) named y." "print g_A.y should be error"
+
+ gdb_test "print g_B.z" "There is no member( or method|) named z." "print g_B.z should be error"
+
+ gdb_test "print g_C.q" "There is no member( or method|) named q." "print g_C.q should be error"
+
+ gdb_test "print g_D.p" "There is no member( or method|) named p." "print g_D.p should be error"
+}
+
+#
+# Call a method that expects a base class parameter with base, inherited,
+# and unrelated class arguments.
+#
+
+proc test_method_param_class {} {
+ gdb_test "call class_param.Aptr_a (&g_A)" ".* = 1" "base class param->a"
+ gdb_test "call class_param.Aptr_x (&g_A)" ".* = 2" "base class param->x"
+ gdb_test "call class_param.Aptr_a (&g_B)" ".* = 3" "inherited class param->a"
+ gdb_test "call class_param.Aptr_x (&g_B)" ".* = 4" "inherited class param->x"
+ gdb_test "call class_param.Aref_a (g_A)" ".* = 1" "base class (&param)->a"
+ gdb_test "call class_param.Aref_x (g_A)" ".* = 2" "base class (&param)->x"
+ gdb_test "call class_param.Aref_a (g_B)" ".* = 3" "inherited class (&param)->a"
+ gdb_test "call class_param.Aref_x (g_B)" ".* = 4" "inherited class (&param)->x"
+ gdb_test "call class_param.Aval_a (g_A)" ".* = 1" "base class param.a"
+ gdb_test "call class_param.Aval_x (g_A)" ".* = 2" "base class param.x"
+ gdb_test "call class_param.Aval_a (g_B)" ".* = 3" "inherited class param.a"
+ gdb_test "call class_param.Aval_x (g_B)" ".* = 4" "inherited class param.x"
+
+ gdb_test "call class_param.Aptr_a (&foo)" "Cannot resolve .*" "unrelated class *param"
+ gdb_test "call class_param.Aref_a (foo)" "Cannot resolve .*" "unrelated class &param"
+ gdb_test "call class_param.Aval_a (foo)" "Cannot resolve .*" "unrelated class param"
+}
+
+#
+# Examine a class with an enum field.
+#
+
+proc test_enums {} {
+ global gdb_prompt
+ global hp_aCC_compiler
+
+ # print the object
+ send_gdb "print obj_with_enum\n"
+ gdb_expect {
+ -re "\\$\[0-9\]* = \\{priv_enum = red, x = 0\\}.*$gdb_prompt $" { pass "print obj_with_enum (1)" }
+ -re "$gdb_prompt $" { fail "print obj_with_enum (1)" }
+ timeout { fail "(timeout) print obj_with_enum (1)" }
+ }
+
+ send_gdb "next\n"
+ gdb_expect {
+ -re "$gdb_prompt $" { pass "next" }
+ timeout { fail "(timeout) next" }
+ }
+
+ # print the object again
+ send_gdb "print obj_with_enum\n"
+ gdb_expect {
+ -re "\\$\[0-9\]* = \\{priv_enum = green, x = 0\\}.*$gdb_prompt $" { pass "print obj_with_enum (2)" }
+ -re "$gdb_prompt $" { fail "print obj_with_enum (2)" }
+ timeout { fail "(timeout) print obj_with_enum (2)" }
+ }
+
+ # print out the enum member
+ send_gdb "print obj_with_enum.priv_enum\n"
+ gdb_expect {
+ -re "\\$\[0-9\]* = green.*$gdb_prompt $" { pass "print obj_with_enum.priv_enum" }
+ -re "$gdb_prompt $" { fail "print obj_with_enum.priv_enum" }
+ timeout { fail "(timeout) print obj_with_enum.priv_enum" }
+ }
+
+ # ptype on the enum member
+ # The third success case is a little dubious, but it's not clear what
+ # ought to be required of a ptype on a private enum... -sts 19990324
+ send_gdb "ptype obj_with_enum.priv_enum\n"
+ gdb_expect {
+ -re "type = enum ClassWithEnum::PrivEnum \\{red, green, blue, yellow = 42\\}.*$gdb_prompt $" { pass "ptype obj_with_enum.priv_enum" }
+ -re "type = enum PrivEnum \\{red, green, blue, yellow = 42\\}.*$gdb_prompt $" { pass "ptype obj_with_enum.priv_enum" }
+ -re "type = enum \\{red, green, blue, yellow = 42\\}.*$gdb_prompt $" { pass "ptype obj_with_enum.priv_enum" }
+ -re "$gdb_prompt $" { fail "ptype obj_with_enum.priv_enum" }
+ timeout { fail "(timeout) ptype obj_with_enum.priv_enum" }
+ }
+
+ # ptype on the object
+ # g++ is putting out the wrong debug info. This works with aCC
+ if {!$hp_aCC_compiler} {setup_xfail "*-*-*"}
+ send_gdb "ptype obj_with_enum\n"
+ gdb_expect {
+ -re "type = class ClassWithEnum \\{\r\n\[ \t\]*public:\r\n\[ \t\]*(enum |)ClassWithEnum::PrivEnum priv_enum;\r\n\[ \t\]*int x;\r\n\\}\r\n$gdb_prompt $" { pass "ptype obj_with_enum" }
+ -re "$gdb_prompt $" { fail "ptype obj_with_enum" }
+ timeout { fail "(timeout) ptype obj_with_enum" }
+ }
+
+ # g++ is putting out the wrong debug info. This works with aCC
+ if {!$hp_aCC_compiler} {setup_xfail "*-*-*"}
+ send_gdb "print (ClassWithEnum::PrivEnum) 42\n"
+ gdb_expect {
+ -re "\\$\[0-9\]* = yellow.*$gdb_prompt $" { pass "print (ClassWithEnum::PrivEnum) 42" }
+ -re "$gdb_prompt $" { fail "print (ClassWithEnum::PrivEnum) 42" }
+ timeout { fail "(timeout) print (ClassWithEnum::PrivEnum) 42" }
+ }
+}
+
+#
+# Pointers to class members
+#
+
+proc test_pointers_to_class_members {} {
+ global gdb_prompt
+ global decimal
+ global nl
+
+ gdb_test "print Bar::z" ".* = .int\[ \]*\[( \]*Bar::&\[)\]+\[ \]*Bar::z" "print Bar::z"
+
+ gdb_test "print &Foo::x" ".* = .int\[ \]*\[( \]*Foo::\[*)\]+\[ \]*&Foo::x" "print &Foo::x"
+
+ gdb_test "print (int)&Foo::x" ".* = 0" "print (int)&Foo::x"
+
+ send_gdb "print (int)&Bar::y == 2*sizeof(int)\n"
+ gdb_expect {
+ -re ".* = true$nl$gdb_prompt $" {
+ pass "print (int)&Bar::y == 2*sizeof(int)"
+ }
+ -re "There is no field named y.*$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "print (int)&Bar::y == 2*sizeof(int)"
+ }
+ -re ".*$gdb_prompt $" { fail "print (int)&Bar::y == 2*sizeof(int)" }
+ timeout { fail "print (int)&Bar::y == 2*sizeof(int) (timeout)" ; return }
+ }
+
+ send_gdb "next 2\n"
+ setup_xfail "*-*-*"
+ gdb_expect {
+ -re "$decimal\[ \t\]+inheritance3 \[)(\]+;$nl$gdb_prompt $" {}
+ -re ".*$gdb_prompt $" { fail "next to inheritance3" ; return }
+ }
+ clear_xfail "*-*-*"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print (int)pmi == sizeof(int)" ".* = false" "print (int)pmi == sizeof(int)"
+}
+
+#
+# Test static members.
+#
+
+proc test_static_members {} {
+ global gdb_prompt
+ global hex
+ global nl
+
+ send_gdb "print Foo::st\n"
+ gdb_expect {
+ -re ".* = 100$nl$gdb_prompt $" {
+ pass "print Foo::st"
+ }
+ -re "There is no field named st.*$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "print Foo::st"
+ }
+ -re ".*$gdb_prompt $" { fail "print Foo::st" }
+ timeout { fail "print Foo::st (timeout)" ; return }
+ }
+
+ send_gdb "set foo.st = 200\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ }
+
+ send_gdb "print bar.st\n"
+ gdb_expect {
+ -re ".* = 200$nl$gdb_prompt $" {
+ pass "print bar.st"
+ }
+ -re "There is no member( or method|) named st.*$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "print bar.st"
+ }
+ -re ".*$gdb_prompt $" { fail "print bar.st" }
+ timeout { fail "print bar.st (timeout)" ; return }
+ }
+
+ send_gdb "print &foo.st\n"
+ gdb_expect {
+ -re ".* = .int \[*)\]+ $hex$nl$gdb_prompt $" {
+ pass "print &foo.st"
+ }
+ -re "There is no member( or method|) named st.*$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "print &foo.st"
+ }
+ -re ".*$gdb_prompt $" { fail "print &foo.st" }
+ timeout { fail "print &foo.st (timeout)" ; return }
+ }
+
+ set got_bar_st 0
+ send_gdb "print &Bar::st\n"
+ gdb_expect {
+ -re ".* = .int \[*)\]+ $hex$nl$gdb_prompt $" {
+ pass "print &Bar::st"
+ set got_bar_st 1
+ }
+ -re "There is no field named st.*$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "print &Bar::st"
+ }
+ -re ".*$gdb_prompt $" { fail "print &Bar::st" }
+ timeout { fail "print &Bar::st (timeout)" ; return }
+ }
+
+ if $got_bar_st then {
+ gdb_test "print *\$" ".* = 200" "print *\$"
+ }
+
+ gdb_test "set print static-members off" ""
+ gdb_test "print csi" \
+ "{x = 10, y = 20}" \
+ "print csi without static members"
+ gdb_test "print cnsi" \
+ "{x = 30, y = 40}" \
+ "print cnsi without static members"
+
+ gdb_test "set print static-members on" ""
+ setup_xfail_format "DWARF 1"
+ gdb_test "print csi" \
+ "{x = 10, y = 20, static null = {x = 0, y = 0, static null = <same as static member of an already seen type>}}" \
+ "print csi with static members"
+ setup_xfail_format "DWARF 1"
+ gdb_test "print cnsi" \
+ "{x = 30, y = 40, static null = {x = 0, y = 0, static null = <same as static member of an already seen type>, static yy = {z = 5, static xx = {x = 1, y = 2, static null = <same as static member of an already seen type>, static yy = <same as static member of an already seen type>}}}, static yy = <same as static member of an already seen type>}" \
+ "print cnsi with static members"
+}
+
+proc do_tests {} {
+ global prms_id
+ global bug_id
+ global subdir
+ global objdir
+ global srcdir
+ global binfile
+ global gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ send_gdb "set language c++\n"
+ gdb_expect -re "$gdb_prompt $"
+ send_gdb "set width 0\n"
+ gdb_expect -re "$gdb_prompt $"
+
+ # Get the debug format for the compiled test case.
+
+ if [ runto_main ] then {
+ get_debug_format
+ }
+
+ test_ptype_class_objects
+
+ if [ runto 'inheritance2' ] then {
+ test_non_inherited_member_access
+ test_wrong_class_members
+ test_nonexistent_members
+ test_method_param_class
+ }
+
+ gdb_breakpoint enums2
+ if [ gdb_continue "enums2(\\(\\)|)" ]==0 then {
+ gdb_test "finish" "" ""
+ test_enums
+ }
+
+ if [istarget "mips-idt-*"] then {
+ # Restart because IDT/SIM runs out of file descriptors.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+ }
+
+ if [ runto_main ] then {
+ test_pointers_to_class_members
+ test_static_members
+ }
+
+ if [istarget "mips-idt-*"] then {
+ # Restart because IDT/SIM runs out of file descriptors.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+ }
+
+ if [ runto marker_reg1 ] then {
+
+ gdb_test "finish" "Run till exit from.*" "finish from marker_reg1"
+
+ send_gdb "print v.method ()\n"
+ gdb_expect {
+ -re "= 82.*$gdb_prompt $" {
+ pass "calling method for small class"
+ }
+ -re "Address requested for identifier .v. which is in register.*$gdb_prompt $" {
+ setup_xfail "*-*-*" 2972
+ fail "calling method for small class"
+ }
+ -re ".*$gdb_prompt $" { fail "calling method for small class" }
+ timeout { fail "calling method for small class (timeout)" }
+ eof { fail "calling method for small class (eof)" }
+ }
+ }
+
+}
+
+do_tests
+
+send_gdb "maint demangle inheritance1__Fv\n"
+gdb_expect {
+ -re "inheritance1\\(void\\).*$gdb_prompt $" { pass "demangle" }
+ -re ".*$gdb_prompt $" { fail "demangle" }
+ timeout { fail "(timeout) demangle" }
+}
diff --git a/gdb/testsuite/gdb.c++/configure b/gdb/testsuite/gdb.c++/configure
new file mode 100644
index 00000000000..6d0b517b4a6
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/configure
@@ -0,0 +1,899 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=cplusfuncs.cc
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:573: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:594: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:612: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.c++/configure.in b/gdb/testsuite/gdb.c++/configure.in
new file mode 100644
index 00000000000..f989cb82865
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/configure.in
@@ -0,0 +1,15 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(cplusfuncs.cc)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.c++/cplusfuncs.cc b/gdb/testsuite/gdb.c++/cplusfuncs.cc
new file mode 100644
index 00000000000..7f033d6d90c
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/cplusfuncs.cc
@@ -0,0 +1,196 @@
+#include <stddef.h>
+
+class foo {
+public:
+ foo (int);
+ foo (int, const char *);
+ foo (foo&);
+ ~foo ();
+
+ void operator * (foo&);
+ void operator % (foo&);
+ void operator - (foo&);
+ void operator >> (foo&);
+ void operator != (foo&);
+ void operator > (foo&);
+ void operator >= (foo&);
+ void operator | (foo&);
+ void operator && (foo&);
+ void operator ! (void);
+ void operator ++ (int);
+ void operator = (foo&);
+ void operator += (foo&);
+ void operator *= (foo&);
+ void operator %= (foo&);
+ void operator >>= (foo&);
+ void operator |= (foo&);
+ void operator , (foo&);
+ void operator / (foo&);
+ void operator + (foo&);
+ void operator << (foo&);
+ void operator == (foo&);
+ void operator < (foo&);
+ void operator <= (foo&);
+ void operator & (foo&);
+ void operator ^ (foo&);
+ void operator || (foo&);
+ void operator ~ (void);
+ void operator -- (int);
+ foo* operator -> (void);
+ void operator -= (foo&);
+ void operator /= (foo&);
+ void operator <<= (foo&);
+ void operator &= (foo&);
+ void operator ^= (foo&);
+ void operator ->* (foo&);
+ void operator [] (foo&);
+ void operator () (foo&);
+ void* operator new (size_t) throw ();
+ void operator delete (void *);
+ /**/ operator int ();
+ /**/ operator char* ();
+
+ int foofunc (int); // forced to have int return type, which is required
+ int foofunc (int, signed char *); // forced to have int return type, which is required
+ int ifoo;
+ const char *ccpfoo;
+};
+
+#ifdef usestubs
+extern "C" {
+ void set_debug_traps();
+ void breakpoint();
+};
+#endif
+
+int main () {
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ int z=3;
+}
+
+foo::foo (int i) { ifoo = i;}
+foo::foo (int i, const char *ccp) { ifoo = i; ccpfoo = ccp; }
+foo::foo (foo& afoo) { afoo.ifoo = 0; }
+foo::~foo () {}
+
+void foo::operator * (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator % (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator - (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator >> (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator != (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator > (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator >= (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator | (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator && (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator ! (void) {}
+void foo::operator ++ (int ival) { ival = 0; }
+void foo::operator = (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator += (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator *= (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator %= (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator >>= (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator |= (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator , (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator / (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator + (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator << (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator == (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator < (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator <= (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator & (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator ^ (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator || (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator ~ (void) {}
+void foo::operator -- (int ival) { ival = 0; }
+foo* foo::operator -> (void) {return this;}
+void foo::operator -= (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator /= (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator <<= (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator &= (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator ^= (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator ->* (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator [] (foo& afoo) { afoo.ifoo = 0; }
+void foo::operator () (foo& afoo) { afoo.ifoo = 0; }
+void* foo::operator new (size_t ival) throw () { ival = 0; return 0; }
+void foo::operator delete (void *ptr) { ptr = 0; }
+/**/ foo::operator int () { return 0; }
+/**/ foo::operator char* () { return 0; }
+
+/* Some functions to test overloading by varying one argument type. */
+
+void overload1arg (void) { }
+void overload1arg (char arg) { arg = 0; }
+void overload1arg (signed char arg) { arg = 0; }
+void overload1arg (unsigned char arg) { arg = 0; }
+void overload1arg (short arg) { arg = 0; }
+void overload1arg (unsigned short arg) { arg = 0; }
+void overload1arg (int arg) { arg = 0; }
+void overload1arg (unsigned int arg) { arg = 0; }
+void overload1arg (long arg) { arg = 0; }
+void overload1arg (unsigned long arg) { arg = 0; }
+void overload1arg (float arg) { arg = 0; }
+void overload1arg (double arg) { arg = 0; }
+
+/* Some functions to test overloading by varying argument count. */
+
+void overloadargs (int a1) { a1 = 0; }
+void overloadargs (int a1, int a2) { a1 = a2 = 0; }
+void overloadargs (int a1, int a2, int a3) { a1 = a2 = a3 = 0; }
+void overloadargs (int a1, int a2, int a3, int a4)
+ { a1 = a2 = a3 = a4 = 0; }
+void overloadargs (int a1, int a2, int a3, int a4, int a5)
+ { a1 = a2 = a3 = a4 = a5 = 0; }
+void overloadargs (int a1, int a2, int a3, int a4, int a5, int a6)
+ { a1 = a2 = a3 = a4 = a5 = a6 = 0; }
+void overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7)
+ { a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0; }
+void overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8)
+ { a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = 0; }
+void overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9)
+ { a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = 0; }
+void overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9, int a10)
+ { a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 =
+ a10 = 0; }
+void overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9, int a10, int a11)
+ { a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 =
+ a10 = a11 == 0; }
+
+/* Some hairy function definitions.
+ Use typedefs to help maintain sanity. */
+
+typedef int (*PFPc_i)(char *);
+typedef short (*PFPl_s)(long *);
+typedef short (*PFPc_s)(char *);
+typedef int (*PFl_i)(long);
+typedef PFl_i (*PFPc_PFl_i)(char *);
+typedef PFl_i (*PFPi_PFl_i)(int *);
+typedef PFl_i (*PFPFPc_i_PFl_i)(PFPc_i);
+typedef PFl_i (*PFs_PFl_i)(short);
+typedef int (*PFPFPl_s_i)(PFPl_s);
+typedef int (*PFPFPc_s_i)(PFPc_s);
+
+PFs_PFl_i hairyfunc1 (int arg) { arg = 0; return 0; }
+int hairyfunc2 (PFPc_i arg) { arg = 0; return 0; }
+int hairyfunc3 (PFPFPl_s_i arg) { arg = 0; return 0; }
+int hairyfunc4 (PFPFPc_s_i arg) { arg = 0; return 0; }
+int hairyfunc5 (PFPc_PFl_i arg) { arg = 0; return 0; }
+int hairyfunc6 (PFPi_PFl_i arg) { arg = 0; return 0; }
+int hairyfunc7 (PFPFPc_i_PFl_i arg) { arg = 0; return 0; }
+
+/* gdb has two demanglers (one for g++ 2.95, one for g++ 3).
+ These marker functions help me figure out which demangler is in use. */
+
+char * dm_type_char_star (char * p) { return p; }
+int dm_type_foo_ref (foo & foo) { return foo.ifoo; }
+int * dm_type_int_star (int * p) { return p; }
+long * dm_type_long_star (long * p) { return p; }
+int dm_type_unsigned_int (unsigned int i) { return i; }
+int dm_type_void (void) { return 0; }
+void * dm_type_void_star (void * p) { return p; }
diff --git a/gdb/testsuite/gdb.c++/cplusfuncs.exp b/gdb/testsuite/gdb.c++/cplusfuncs.exp
new file mode 100644
index 00000000000..9057cc290fc
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/cplusfuncs.exp
@@ -0,0 +1,542 @@
+# Copyright 1992, 1997, 1999, 2001, 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+# Adapted for g++ 3.0 ABI by Michael Chastain. (chastain@redhat.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "cplusfuncs"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [get_compiler_info $binfile "c++"] } {
+ return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+#
+# g++ changed its ABI between 2.95 and 3.0. gdb has two demanglers
+# for the two different styles. The two demanglers have some subtle
+# discrepancies in their output.
+#
+# old demangler new demangler
+# --- --------- --- ---------
+# "operator, " "operator,"
+# "char *" "char*"
+# "int *" "int*"
+# "long *" "long*"
+# "void *" "void*"
+# "foo &" "foo&"
+# "unsigned int" "unsigned"
+# "void" ""
+#
+# I probe for the forms in use.
+# The defaults are for the v3 demangler (as of 2001-02-13).
+#
+
+set dm_operator_comma ","
+set dm_type_char_star "char*"
+set dm_type_char_star_quoted "char\\*"
+set dm_type_foo_ref "foo&"
+set dm_type_int_star "int*"
+set dm_type_long_star "long*"
+set dm_type_unsigned_int "unsigned"
+set dm_type_void ""
+set dm_type_void_star "void*"
+
+proc probe_demangler { } {
+ global gdb_prompt
+ global dm_operator_comma
+ global dm_type_char_star
+ global dm_type_char_star_quoted
+ global dm_type_foo_ref
+ global dm_type_int_star
+ global dm_type_long_star
+ global dm_type_unsigned_int
+ global dm_type_void
+ global dm_type_void_star
+
+ send_gdb "print &'foo::operator,(foo&)'\n"
+ gdb_expect {
+ -re ".*foo::operator, \\(.*foo.*&.*\\).*\r\n$gdb_prompt $" {
+ # v2 demangler
+ set dm_operator_comma ", "
+ pass "detect dm_operator_comma"
+ }
+ -re ".*foo::operator,\\(.*foo.*&.*\\).*\r\n$gdb_prompt $" {
+ # v3 demangler
+ pass "detect dm_operator_comma"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "detect dm_operator_comma"
+ }
+ timeout {
+ fail "detect dm_operator_comma"
+ }
+ }
+
+ send_gdb "print &'dm_type_char_star'\n"
+ gdb_expect {
+ -re ".*dm_type_char_star\\(char \\*\\).*\r\n$gdb_prompt $" {
+ # v2 demangler
+ set dm_type_char_star "char *"
+ set dm_type_char_star_quoted "char \\*"
+ pass "detect dm_type_char_star"
+ }
+ -re ".*dm_type_char_star\\(char\\*\\).*\r\n$gdb_prompt $" {
+ # v3 demangler
+ pass "detect dm_type_char_star"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "detect dm_type_char_star"
+ }
+ timeout {
+ fail "detect dm_type_char_star (timeout)"
+ }
+ }
+
+ send_gdb "print &'dm_type_foo_ref'\n"
+ gdb_expect {
+ -re ".*dm_type_foo_ref\\(foo &\\).*\r\n$gdb_prompt $" {
+ # v2 demangler
+ set dm_type_foo_ref "foo &"
+ pass "detect dm_type_foo_ref"
+ }
+ -re ".*dm_type_foo_ref\\(foo&\\).*\r\n$gdb_prompt $" {
+ # v3 demangler
+ pass "detect dm_type_foo_ref"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "detect dm_type_foo_ref"
+ }
+ timeout {
+ fail "detect dm_type_foo_ref (timeout)"
+ }
+ }
+
+ send_gdb "print &'dm_type_int_star'\n"
+ gdb_expect {
+ -re ".*dm_type_int_star\\(int \\*\\).*\r\n$gdb_prompt $" {
+ # v2 demangler
+ set dm_type_int_star "int *"
+ pass "detect dm_type_int_star"
+ }
+ -re ".*dm_type_int_star\\(int\\*\\).*\r\n$gdb_prompt $" {
+ # v3 demangler
+ pass "detect dm_type_int_star"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "detect dm_type_int_star"
+ }
+ timeout {
+ fail "detect dm_type_int_star (timeout)"
+ }
+ }
+
+ send_gdb "print &'dm_type_long_star'\n"
+ gdb_expect {
+ -re ".*dm_type_long_star\\(long \\*\\).*\r\n$gdb_prompt $" {
+ # v2 demangler
+ set dm_type_long_star "long *"
+ pass "detect dm_type_long_star"
+ }
+ -re ".*dm_type_long_star\\(long\\*\\).*\r\n$gdb_prompt $" {
+ # v3 demangler
+ pass "detect dm_type_long_star"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "detect dm_type_long_star"
+ }
+ timeout {
+ fail "detect dm_type_long_star (timeout)"
+ }
+ }
+
+ send_gdb "print &'dm_type_unsigned_int'\n"
+ gdb_expect {
+ -re ".*dm_type_unsigned_int\\(unsigned int\\).*\r\n$gdb_prompt $" {
+ # v2 demangler
+ set dm_type_unsigned_int "unsigned int"
+ pass "detect dm_type_unsigned_int"
+ }
+ -re ".*dm_type_unsigned_int\\(unsigned\\).*\r\n$gdb_prompt $" {
+ # v3 demangler
+ pass "detect dm_type_unsigned_int"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "detect dm_type_unsigned_int"
+ }
+ timeout {
+ fail "detect dm_unsigned int (timeout)"
+ }
+ }
+
+ send_gdb "print &'dm_type_void'\n"
+ gdb_expect {
+ -re ".*dm_type_void\\(void\\).*\r\n$gdb_prompt $" {
+ # v2 demangler
+ set dm_type_void "void"
+ pass "detect dm_type_void"
+ }
+ -re ".*dm_type_void\\(\\).*\r\n$gdb_prompt $" {
+ # v3 demangler
+ pass "detect dm_type_void"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "detect dm_type_void"
+ }
+ timeout {
+ fail "detect dm_type_void (timeout)"
+ }
+ }
+
+ send_gdb "print &'dm_type_void_star'\n"
+ gdb_expect {
+ -re ".*dm_type_void_star\\(void \\*\\).*\r\n$gdb_prompt $" {
+ # v2 demangler
+ set dm_type_void_star "void *"
+ pass "detect dm_type_void_star"
+ }
+ -re ".*dm_type_void_star\\(void\\*\\).*\r\n$gdb_prompt $" {
+ # v3 demangler
+ pass "detect dm_type_void_star"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "detect dm_type_void_star"
+ }
+ timeout {
+ fail "detect dm_type_void_star (timeout)"
+ }
+ }
+}
+
+#
+# Lookup a specific C++ function and print the demangled type.
+# This form accepts the demangled type as a regexp.
+#
+
+proc info_func_regexp { name demangled } {
+ global gdb_prompt
+
+ send_gdb "info function $name\n"
+ gdb_expect {
+ -re ".*File .*:\r\n(class |)$demangled\r\n.*$gdb_prompt $" {
+ pass "info function for \"$name\""
+ }
+ -re ".*$gdb_prompt $" {
+ fail "info function for \"$name\""
+ }
+ timeout {
+ fail "info function for \"$name\" (timeout)"
+ }
+ }
+}
+
+#
+# Lookup a specific C++ function and print the demangled type.
+# This form accepts the demangled type as a literal string.
+#
+
+proc info_func { name demangled } {
+ info_func_regexp "$name" [string_to_regexp "$demangled"]
+}
+
+#
+# Print the address of a function.
+# This checks that I can lookup a fully qualified C++ function.
+# This also checks the argument types on the return string.
+#
+
+proc print_addr_2 { name good } {
+ global gdb_prompt
+ global hex
+
+ set good_pattern [string_to_regexp $good]
+
+ send_gdb "print &'$name'\n"
+ gdb_expect {
+ -re ".* = .* $hex <$good_pattern>\r\n$gdb_prompt $" {
+ pass "print &'$name'"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "print &'$name'"
+ }
+ timeout {
+ fail "print &'$name' (timeout)"
+ }
+ }
+}
+
+#
+# Simple interfaces to print_addr_2.
+#
+
+proc print_addr { name } {
+ print_addr_2 "$name" "$name"
+}
+
+#
+# Test name demangling for operators.
+#
+# The '(' at the end of each regex input pattern is so that we match only
+# the one we are looking for. I.E. "operator&" would match both
+# "operator&(foo &)" and "operator&&(foo &)".
+#
+# gdb-gnats bug gdb/18:
+# "gdb can't parse "info func operator*" or "info func operator\*".
+# The star in "operator*" is interpreted as a regexp, but the "\*"
+# in "operator\*" is not a legal operator.
+#
+
+proc test_lookup_operator_functions {} {
+ global dm_operator_comma
+ global dm_type_char_star
+ global dm_type_char_star_quoted
+ global dm_type_foo_ref
+ global dm_type_void
+ global dm_type_void_star
+
+ # operator* requires quoting so that GDB does not treat it as a regexp.
+ info_func "operator\\*(" "void foo::operator*($dm_type_foo_ref);"
+ info_func "operator%(" "void foo::operator%($dm_type_foo_ref);"
+ info_func "operator-(" "void foo::operator-($dm_type_foo_ref);"
+ info_func "operator>>(" "void foo::operator>>($dm_type_foo_ref);"
+ info_func "operator!=(" "void foo::operator!=($dm_type_foo_ref);"
+ info_func "operator>(" "void foo::operator>($dm_type_foo_ref);"
+ info_func "operator>=(" "void foo::operator>=($dm_type_foo_ref);"
+ info_func "operator|(" "void foo::operator|($dm_type_foo_ref);"
+ info_func "operator&&(" "void foo::operator&&($dm_type_foo_ref);"
+ info_func "operator!(" "void foo::operator!($dm_type_void);"
+ info_func "operator++(" "void foo::operator++(int);"
+ info_func "operator=(" "void foo::operator=($dm_type_foo_ref);"
+ info_func "operator+=(" "void foo::operator+=($dm_type_foo_ref);"
+ # operator*= requires quoting so that GDB does not treat it as a regexp.
+ info_func "operator\\*=(" "void foo::operator*=($dm_type_foo_ref);"
+ info_func "operator%=(" "void foo::operator%=($dm_type_foo_ref);"
+ info_func "operator>>=(" "void foo::operator>>=($dm_type_foo_ref);"
+ info_func "operator|=(" "void foo::operator|=($dm_type_foo_ref);"
+ info_func "operator$dm_operator_comma\(" \
+ "void foo::operator$dm_operator_comma\($dm_type_foo_ref);"
+ info_func "operator/(" "void foo::operator/($dm_type_foo_ref);"
+ info_func "operator+(" "void foo::operator+($dm_type_foo_ref);"
+ info_func "operator<<(" "void foo::operator<<($dm_type_foo_ref);"
+ info_func "operator==(" "void foo::operator==($dm_type_foo_ref);"
+ info_func "operator<(" "void foo::operator<($dm_type_foo_ref);"
+ info_func "operator<=(" "void foo::operator<=($dm_type_foo_ref);"
+ info_func "operator&(" "void foo::operator&($dm_type_foo_ref);"
+ info_func "operator^(" "void foo::operator^($dm_type_foo_ref);"
+ info_func "operator||(" "void foo::operator||($dm_type_foo_ref);"
+ info_func "operator~(" "void foo::operator~($dm_type_void);"
+ info_func "operator--(" "void foo::operator--(int);"
+ info_func "operator->(" "foo *foo::operator->($dm_type_void);"
+ info_func "operator-=(" "void foo::operator-=($dm_type_foo_ref);"
+ info_func "operator/=(" "void foo::operator/=($dm_type_foo_ref);"
+ info_func "operator<<=(" "void foo::operator<<=($dm_type_foo_ref);"
+ info_func "operator&=(" "void foo::operator&=($dm_type_foo_ref);"
+ info_func "operator^=(" "void foo::operator^=($dm_type_foo_ref);"
+ # operator->* requires quoting so that GDB does not treat it as a regexp.
+ info_func "operator->\\*(" "void foo::operator->*($dm_type_foo_ref);"
+
+ # operator[] needs double backslashes, so that a single backslash
+ # will be sent to GDB, preventing the square brackets from being
+ # evaluated as a regular expression.
+ info_func "operator\\\[\\\](" "void foo::operator\[\]($dm_type_foo_ref);"
+
+ # These are gnarly because they might end with 'static'.
+ set dm_type_void_star_regexp [string_to_regexp $dm_type_void_star]
+ info_func_regexp "operator new(" "void \\*foo::operator new\\(.*\\)(| static);"
+ info_func_regexp "operator delete(" "void foo::operator delete\\($dm_type_void_star_regexp\\)(| static);"
+
+ info_func "operator int(" "int foo::operator int($dm_type_void);"
+ info_func "operator()(" "void foo::operator()($dm_type_foo_ref);"
+ info_func "operator $dm_type_char_star_quoted\(" \
+ "char *foo::operator $dm_type_char_star\($dm_type_void);"
+
+}
+
+
+proc test_paddr_operator_functions {} {
+ global hex
+ global hp_aCC_compiler
+ global dm_operator_comma
+ global dm_type_char_star
+ global dm_type_foo_ref
+ global dm_type_long_star
+ global dm_type_unsigned_int
+ global dm_type_void
+ global dm_type_void_star
+
+ print_addr "foo::operator*($dm_type_foo_ref)"
+ print_addr "foo::operator%($dm_type_foo_ref)"
+ print_addr "foo::operator-($dm_type_foo_ref)"
+ print_addr "foo::operator>>($dm_type_foo_ref)"
+ print_addr "foo::operator!=($dm_type_foo_ref)"
+ print_addr "foo::operator>($dm_type_foo_ref)"
+ print_addr "foo::operator>=($dm_type_foo_ref)"
+ print_addr "foo::operator|($dm_type_foo_ref)"
+ print_addr "foo::operator&&($dm_type_foo_ref)"
+ print_addr "foo::operator!($dm_type_void)"
+ print_addr "foo::operator++(int)"
+ print_addr "foo::operator=($dm_type_foo_ref)"
+ print_addr "foo::operator+=($dm_type_foo_ref)"
+ print_addr "foo::operator*=($dm_type_foo_ref)"
+ print_addr "foo::operator%=($dm_type_foo_ref)"
+ print_addr "foo::operator>>=($dm_type_foo_ref)"
+ print_addr "foo::operator|=($dm_type_foo_ref)"
+ print_addr "foo::operator$dm_operator_comma\($dm_type_foo_ref)"
+ print_addr "foo::operator/($dm_type_foo_ref)"
+ print_addr "foo::operator+($dm_type_foo_ref)"
+ print_addr "foo::operator<<($dm_type_foo_ref)"
+ print_addr "foo::operator==($dm_type_foo_ref)"
+ print_addr "foo::operator<($dm_type_foo_ref)"
+ print_addr "foo::operator<=($dm_type_foo_ref)"
+ print_addr "foo::operator&($dm_type_foo_ref)"
+ print_addr "foo::operator^($dm_type_foo_ref)"
+ print_addr "foo::operator||($dm_type_foo_ref)"
+ print_addr "foo::operator~($dm_type_void)"
+ print_addr "foo::operator--(int)"
+ print_addr "foo::operator->($dm_type_void)"
+ print_addr "foo::operator-=($dm_type_foo_ref)"
+ print_addr "foo::operator/=($dm_type_foo_ref)"
+ print_addr "foo::operator<<=($dm_type_foo_ref)"
+ print_addr "foo::operator&=($dm_type_foo_ref)"
+ print_addr "foo::operator^=($dm_type_foo_ref)"
+ print_addr "foo::operator->*($dm_type_foo_ref)"
+ print_addr "foo::operator\[\]($dm_type_foo_ref)"
+ print_addr "foo::operator()($dm_type_foo_ref)"
+
+ gdb_test "print &'foo::operator new'" \
+ " = .* $hex <foo::operator new\\(.*\\)(| static)>"
+ if { !$hp_aCC_compiler } {
+ print_addr "foo::operator delete($dm_type_void_star)"
+ } else {
+ gdb_test "print &'foo::operator delete($dm_type_void_star) static'" \
+ " = .*(0x\[0-9a-f\]+|) <foo::operator delete.*>"
+ }
+
+ print_addr "foo::operator int($dm_type_void)"
+ print_addr "foo::operator $dm_type_char_star\($dm_type_void)"
+}
+
+#
+# Test overloaded functions (1 arg).
+#
+
+proc test_paddr_overloaded_functions {} {
+ global dm_type_unsigned_int
+ global dm_type_void
+
+ print_addr "overload1arg($dm_type_void)"
+ print_addr "overload1arg(char)"
+ print_addr "overload1arg(signed char)"
+ print_addr "overload1arg(unsigned char)"
+ print_addr "overload1arg(short)"
+ print_addr "overload1arg(unsigned short)"
+ print_addr "overload1arg(int)"
+ print_addr "overload1arg($dm_type_unsigned_int)"
+ print_addr "overload1arg(long)"
+ print_addr "overload1arg(unsigned long)"
+ print_addr "overload1arg(float)"
+ print_addr "overload1arg(double)"
+
+ print_addr "overloadargs(int)"
+ print_addr "overloadargs(int, int)"
+ print_addr "overloadargs(int, int, int)"
+ print_addr "overloadargs(int, int, int, int)"
+ print_addr "overloadargs(int, int, int, int, int)"
+ print_addr "overloadargs(int, int, int, int, int, int)"
+ print_addr "overloadargs(int, int, int, int, int, int, int)"
+ print_addr "overloadargs(int, int, int, int, int, int, int, int)"
+ print_addr "overloadargs(int, int, int, int, int, int, int, int, int)"
+ print_addr "overloadargs(int, int, int, int, int, int, int, int, int, int)"
+ print_addr "overloadargs(int, int, int, int, int, int, int, int, int, int, int)"
+}
+
+proc test_paddr_hairy_functions {} {
+ global gdb_prompt
+ global hex
+ global dm_type_char_star
+ global dm_type_int_star
+ global dm_type_long_star
+
+ print_addr_2 "hairyfunc1" "hairyfunc1(int)"
+ print_addr_2 "hairyfunc2" "hairyfunc2(int (*)($dm_type_char_star))"
+ print_addr_2 "hairyfunc3" "hairyfunc3(int (*)(short (*)($dm_type_long_star)))"
+ print_addr_2 "hairyfunc4" "hairyfunc4(int (*)(short (*)($dm_type_char_star)))"
+
+ # gdb-gnats bug gdb/19:
+ # "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7"
+ print_addr_2 "hairyfunc5" "hairyfunc5(int (*(*)($dm_type_char_star))(long))"
+ print_addr_2 "hairyfunc6" "hairyfunc6(int (*(*)($dm_type_int_star))(long))"
+ print_addr_2 "hairyfunc7" "hairyfunc7(int (*(*)(int (*)($dm_type_char_star)))(long))"
+}
+
+proc do_tests {} {
+ global prms_id
+ global bug_id
+ global subdir
+ global objdir
+ global srcdir
+ global binfile
+ global gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ send_gdb "set language c++\n"
+ gdb_expect -re "$gdb_prompt $"
+ send_gdb "set width 0\n"
+ gdb_expect -re "$gdb_prompt $"
+
+ # Get the debug format for the compiled test case. If that
+ # format is DWARF 1 then just skip all the tests since none of
+ # them will pass.
+
+ if [ runto_main] then {
+ get_debug_format
+ if [ setup_xfail_format "DWARF 1" ] then {
+ fail "C++ tests skipped due to limited C++ support in DWARF 1 debug format"
+ return
+ }
+ clear_xfail "*-*-*"
+ }
+
+ probe_demangler
+ test_paddr_overloaded_functions
+ test_paddr_operator_functions
+ test_paddr_hairy_functions
+ test_lookup_operator_functions
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.c++/ctti.exp b/gdb/testsuite/gdb.c++/ctti.exp
new file mode 100644
index 00000000000..96e9fcff81a
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/ctti.exp
@@ -0,0 +1,269 @@
+# Copyright 1998, 1999, 2001 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+
+# This file is part of the gdb testsuite
+# file written by Elena Zannoni (ezannoni@cygnus.com)
+#
+# source files cttiadd.cc, cttiadd1.cc, cttiadd2.cc, cttiadd3.cc
+#
+
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if { [skip_cplus_tests] } { continue }
+
+# Check to see if we have an executable to test. If not, then either we
+# haven't tried to compile one, or the compilation failed for some reason.
+# In either case, just notify the user and skip the tests in this file.
+
+set testfile "cttiadd"
+set srcfile ${testfile}.cc
+set srcfile1 ${testfile}1.cc
+set srcfile2 ${testfile}2.cc
+set srcfile3 ${testfile}3.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile} "c++"] {
+ return -1;
+}
+
+if { $gcc_compiled } then { continue }
+
+#if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${srcdir}/${subdir}/${srcfile1} ${srcdir}/${subdir}/${srcfile2} ${srcdir}/${subdir}/${srcfile3}" "${binfile}" executable {debug c++}] != "" } {
+# gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+#}
+
+set cmdline "$CXX_FOR_TARGET ${srcdir}/${subdir}/${srcfile} ${srcdir}/${subdir}/${srcfile1} ${srcdir}/${subdir}/${srcfile2} ${srcdir}/${subdir}/${srcfile3} -g -o ${binfile}"
+
+remote_exec build $cmdline
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+
+send_gdb "n\n"
+gdb_expect {
+ -re "$decimal.*i = 2;.*$gdb_prompt $" {
+ pass "next "
+ }
+ -re ".*$gdb_prompt $" { fail "next " }
+ timeout { fail "next " }
+ }
+
+
+send_gdb "n\n"
+gdb_expect {
+ -re "$decimal.*f = 4.5;.*$gdb_prompt $" {
+ pass "next "
+ }
+ -re ".*$gdb_prompt $" { fail "next " }
+ timeout { fail "next " }
+ }
+
+send_gdb "n\n"
+gdb_expect {
+ -re "$decimal.*c = add\\(c, c\\);.*$gdb_prompt $" {
+ pass "next "
+ }
+ -re ".*$gdb_prompt $" { fail "next " }
+ timeout { fail "next " }
+ }
+
+send_gdb "n\n"
+gdb_expect {
+ -re "$decimal.*i = add\\(i, i\\);.*$gdb_prompt $" {
+ pass "next "
+ }
+ -re ".*$gdb_prompt $" { fail "next " }
+ timeout { fail "next " }
+ }
+
+send_gdb "n\n"
+gdb_expect {
+ -re "$decimal.*f = add\\(f, f\\);.*$gdb_prompt $" {
+ pass "next "
+ }
+ -re ".*$gdb_prompt $" { fail "next " }
+ timeout { fail "next " }
+ }
+
+send_gdb "n\n"
+gdb_expect {
+ -re "$decimal.*add1\\(\\);.*$gdb_prompt $" {
+ pass "next "
+ }
+ -re ".*$gdb_prompt $" { fail "next " }
+ timeout { fail "next " }
+ }
+
+send_gdb "print c\n"
+gdb_expect {
+ -re ".$decimal = -62.*\r\n$gdb_prompt $" {
+ pass "print value of c"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of c" }
+ timeout { fail "(timeout) print value of c" }
+ }
+
+
+send_gdb "print f\n"
+gdb_expect {
+ -re ".$decimal = 9\r\n$gdb_prompt $" {
+ pass "print value of f"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of f" }
+ timeout { fail "(timeout) print value of f" }
+ }
+
+
+send_gdb "print i\n"
+gdb_expect {
+ -re ".$decimal = 4\r\n$gdb_prompt $" {
+ pass "print value of i"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of i" }
+ timeout { fail "(timeout) print value of i" }
+ }
+
+
+
+send_gdb "print add<int>(2,2)\n"
+gdb_expect {
+ -re ".$decimal = 4\r\n$gdb_prompt $" {
+ pass "print value of add<int>(2,2)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of add<int>(2,2)" }
+ timeout { fail "(timeout) print value of add<int>(2,2)" }
+ }
+
+send_gdb "print add<float>(2.3,2.3)\n"
+gdb_expect {
+ -re ".$decimal = 4\\.5\[0-9\]+\r\n$gdb_prompt $" {
+ pass "print value of add<float>(2.3,2.3)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of add<float>(2.3,2.3)" }
+ timeout { fail "(timeout) print value of add<float>(2.3,2.3)" }
+ }
+
+send_gdb "print add<char>('A','A')\n"
+gdb_expect {
+ -re ".$decimal = -126.*202.\r\n$gdb_prompt $" {
+ pass "print value of add<char>('A','A')"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of add<char>('A','A')" }
+ timeout { fail "(timeout) print value of add<char>('A','A')" }
+ }
+
+
+send_gdb "print add2<int>(2,2)\n"
+gdb_expect {
+ -re ".$decimal = 4\r\n$gdb_prompt $" {
+ pass "print value of add2<int>(2,2)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of add2<int>(2,2)" }
+ timeout { fail "(timeout) print value of add2<int>(2,2)" }
+ }
+
+send_gdb "print add2<float>(2.3,2.3)\n"
+gdb_expect {
+ -re ".$decimal = 4\\.5\[0-9\]+\r\n$gdb_prompt $" {
+ pass "print value of add2<float>(2.3,2.3)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of add2<float>(2.3,2.3)" }
+ timeout { fail "(timeout) print value of add2<float>(2.3,2.3)" }
+ }
+
+send_gdb "print add2<char>('A','A')\n"
+gdb_expect {
+ -re ".$decimal = -126.*202.\r\n$gdb_prompt $" {
+ pass "print value of add2<char>('A','A')"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of add2<char>('A','A')" }
+ timeout { fail "(timeout) print value of add2<char>('A','A')" }
+ }
+
+send_gdb "print add3<int>(2,2)\n"
+gdb_expect {
+ -re ".$decimal = 4\r\n$gdb_prompt $" {
+ pass "print value of add3<int>(2,2)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of add3<int>(2,2)" }
+ timeout { fail "(timeout) print value of add3<int>(2,2)" }
+ }
+
+send_gdb "print add3<float>(2.3,2.3)\n"
+gdb_expect {
+ -re ".$decimal = 4\\.5\[0-9\]+\r\n$gdb_prompt $" {
+ pass "print value of add3<float>(2.3,2.3)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of add3<float>(2.3,2.3)" }
+ timeout { fail "(timeout) print value of add3<float>(2.3,2.3)" }
+ }
+
+send_gdb "print add3<char>('A','A')\n"
+gdb_expect {
+ -re ".$decimal = -126.*202.\r\n$gdb_prompt $" {
+ pass "print value of add3<char>('A','A')"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of add3<char>('A','A')" }
+ timeout { fail "(timeout) print value of add3<char>('A','A')" }
+ }
+
+send_gdb "print add4<int>(2,2)\n"
+gdb_expect {
+ -re ".$decimal = 4\r\n$gdb_prompt $" {
+ pass "print value of add4<int>(2,2)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of add4<int>(2,2)" }
+ timeout { fail "(timeout) print value of add4<int>(2,2)" }
+ }
+
+send_gdb "print add4<float>(2.3,2.3)\n"
+gdb_expect {
+ -re ".$decimal = 4\\.5\[0-9\]+\r\n$gdb_prompt $" {
+ pass "print value of add4<float>(2.3,2.3)"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of add4<float>(2.3,2.3)" }
+ timeout { fail "(timeout) print value of add4<float>(2.3,2.3)" }
+ }
+
+send_gdb "print add4<char>('A','A')\n"
+gdb_expect {
+ -re ".$decimal = -126.*202.\r\n$gdb_prompt $" {
+ pass "print value of add4<char>('A','A')"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of add4<char>('A','A')" }
+ timeout { fail "(timeout) print value of add4<char>('A','A')" }
+ }
+
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.c++/cttiadd.cc b/gdb/testsuite/gdb.c++/cttiadd.cc
new file mode 100644
index 00000000000..1f50fae24c1
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/cttiadd.cc
@@ -0,0 +1,29 @@
+template<class T> T add(T v1, T v2)
+{
+ T v3;
+ v3 = v1;
+ v3 += v2;
+ return v3;
+ }
+
+int main()
+{
+ char c;
+ int i;
+ float f;
+ extern void add1();
+ extern void subr2();
+ extern void subr3();
+
+ c = 'a';
+ i = 2;
+ f = 4.5;
+
+ c = add(c, c);
+ i = add(i, i);
+ f = add(f, f);
+
+ add1();
+ subr2();
+ subr3();
+}
diff --git a/gdb/testsuite/gdb.c++/cttiadd1.cc b/gdb/testsuite/gdb.c++/cttiadd1.cc
new file mode 100644
index 00000000000..7113ecea421
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/cttiadd1.cc
@@ -0,0 +1,16 @@
+template<class T> T add(T v1, T v2);
+
+void add1()
+{
+ char c;
+ int i;
+ float f;
+
+ c = 'b';
+ i = 3;
+ f = 6.5;
+
+ c = add(c, c);
+ i = add(i, i);
+ f = add(f, f);
+}
diff --git a/gdb/testsuite/gdb.c++/cttiadd2.cc b/gdb/testsuite/gdb.c++/cttiadd2.cc
new file mode 100644
index 00000000000..d0d9891fb2f
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/cttiadd2.cc
@@ -0,0 +1,22 @@
+template<class T> T add2(T v1, T v2)
+{
+ T v3;
+ v3 = v1;
+ v3 += v2;
+ return v3;
+}
+
+void subr2()
+{
+ char c;
+ int i;
+ float f;
+
+ c = 'b';
+ i = 3;
+ f = 6.5;
+
+ c = add2(c, c);
+ i = add2(i, i);
+ f = add2(f, f);
+}
diff --git a/gdb/testsuite/gdb.c++/cttiadd3.cc b/gdb/testsuite/gdb.c++/cttiadd3.cc
new file mode 100644
index 00000000000..7ba1b019f16
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/cttiadd3.cc
@@ -0,0 +1,33 @@
+template<class T> T add3(T v1, T v2)
+{
+ T v3;
+ v3 = v1;
+ v3 += v2;
+ return v3;
+}
+
+template<class T> T add4(T v1, T v2)
+{
+ T v3;
+ v3 = v1;
+ v3 += v2;
+ return v3;
+}
+
+void subr3()
+{
+ char c;
+ int i;
+ float f;
+
+ c = 'b';
+ i = 3;
+ f = 6.5;
+
+ c = add3(c, c);
+ i = add3(i, i);
+ f = add3(f, f);
+ c = add4(c, c);
+ i = add4(i, i);
+ f = add4(f, f);
+}
diff --git a/gdb/testsuite/gdb.c++/demangle.exp b/gdb/testsuite/gdb.c++/demangle.exp
new file mode 100644
index 00000000000..45a89bd83c9
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/demangle.exp
@@ -0,0 +1,1579 @@
+# Copyright (C) 1992, 1997, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if { [skip_cplus_tests] } { continue }
+
+### The demangling style we last sent to GDB.
+set current_demangling_style none
+
+### Set GDB's current demangling style to STYLE. Subsequent calls to
+### test_demangle will include STYLE in the test name when reporting
+### passes and failures.
+proc set_demangling_style {style} {
+ global gdb_prompt
+ global current_demangling_style
+
+ send_gdb "set demangle-style $style\n"
+ gdb_expect {
+ -re "set demangle-style $style\[\r\n\]+$gdb_prompt $" {
+ pass "$style: set demangle-style"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$style: set demangle-style"
+ error "set_demangling_style: set style"
+ }
+ timeout {
+ fail "$style: set demangle-style (timeout)"
+ error "set_demangling_style: set style"
+ }
+ }
+
+ send_gdb "show demangle-style\n"
+ gdb_expect {
+ -re "The current C\[+\]+ demangling style is \"$style\".\r\n$gdb_prompt $" {
+ pass "$style: check demangling style"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$style: check demangling style"
+ error "set_demangling_style: check style"
+ }
+ timeout {
+ fail "$style: check demangling style (timeout)"
+ error "set_demangling_style: check style"
+ }
+ }
+
+ set current_demangling_style $style
+}
+
+
+### Utility function for test_demangling and test_demangling_exact.
+proc test_demangling_core {tester test result} {
+ global current_demangling_style
+
+ if {! [regexp {^([^ ]+): (.+)$} $test dummy style name]} {
+ error "bad test name passed to test_demangling"
+ }
+
+ if {[string compare $style $current_demangling_style]} {
+ set_demangling_style $style
+ }
+
+ $tester "maintenance demangle $name" $result $test
+}
+
+### Demangle an identifier, and check that the result matches a pattern.
+###
+### TEST should be of the form "STYLE: NAME", where STYLE is the name
+### of a demangling style (like "gnu" or "arm"), and NAME is a mangled
+### identifier to demangle. Pass when the result matches the regular
+### expression RESULT. Report passes and fails using TEST as the name
+### of the test.
+###
+### Why don't we just pass the STYLE and NAME as two separate
+### arguments, or let the style be a global variable? That would be
+### cleaner. However, doing it this way means that:
+###
+### 1) the name of the test, as recorded in the summary and log,
+### appears verbatim in the script, and
+###
+### 2) that test names are unique, even though we try to demangle the same
+### identifiers using several different mangling styles.
+###
+### This makes it a lot easier for people tracking down failures to
+### find the one they care about.
+
+proc test_demangling {test result} {
+ test_demangling_core gdb_test $test $result
+}
+
+### Like test_demangling, above, except that RESULT is not a regexp,
+### but a string that must match exactly.
+
+proc test_demangling_exact {test result} {
+ test_demangling_core gdb_test_exact $test $result
+}
+
+
+
+#
+# Test gnu style name demangling
+#
+
+proc test_gnu_style_demangling {} {
+ global gdb_prompt
+
+ test_demangling "gnu: Abort__FP6EditoriPCc" \
+ "Abort\[(\]+Editor \[*\]+, int, (const char|char const) \[*\]+\[)\]+"
+ test_demangling_exact "gnu: AddAlignment__9ivTSolverUiP12ivInteractorP7ivTGlue" "ivTSolver::AddAlignment(unsigned int, ivInteractor *, ivTGlue *)"
+ test_demangling "gnu: Append__15NameChooserViewPCc" \
+ "NameChooserView::Append\[(\]+(const char|char const) \[*\]+\[)\]+"
+ test_demangling_exact "gnu: ArrowheadIntersects__9ArrowLineP9ArrowheadR6BoxObjP7Graphic" "ArrowLine::ArrowheadIntersects(Arrowhead *, BoxObj &, Graphic *)"
+ test_demangling_exact "gnu: AtEnd__13ivRubberGroup" "ivRubberGroup::AtEnd(void)"
+ test_demangling_exact "gnu: BgFilter__9ivTSolverP12ivInteractor" "ivTSolver::BgFilter(ivInteractor *)"
+ test_demangling "gnu: BitPatterntoa__FRC10BitPatternccc" \
+ "BitPatterntoa\[(\]+(const BitPattern|BitPattern const) &, char, char, char\[)\]+"
+ test_demangling_exact "gnu: Check__6UArrayi" "UArray::Check(int)"
+ test_demangling_exact "gnu: CoreConstDecls__8TextCodeR7ostream" "TextCode::CoreConstDecls(ostream &)"
+ test_demangling_exact "gnu: Detach__8StateVarP12StateVarView" "StateVar::Detach(StateVarView *)"
+ test_demangling_exact "gnu: Done__9ComponentG8Iterator" "Component::Done(Iterator)"
+ test_demangling "gnu: DrawDestinationTransformedImage__FP7_XImageiiT0iiUlUiiiUiUlUlP4_XGCRC13ivTransformeriiii" \
+ "DrawDestinationTransformedImage\[(\]+_XImage \[*\]+, int, int, _XImage \[*\]+, int, int, unsigned long, unsigned int, int, int, unsigned int, unsigned long, unsigned long, _XGC \[*\]+, (const ivTransformer|ivTransformer const) &, int, int, int, int\[)\]+"
+
+ test_demangling "gnu: Edit__12StringEditorPCcii" \
+ "StringEditor::Edit\[(\]+(const char|char const) \[*\]+, int, int\[)\]+"
+ test_demangling_exact "gnu: Effect__11RelateManipR7ivEvent" "RelateManip::Effect(ivEvent &)"
+ test_demangling "gnu: FilterName__FPCc" \
+ "FilterName\[(\]+(const char|char const) \[*\]+\[)\]+"
+ test_demangling "gnu: Filter__6PSTextPCci" \
+ "PSText::Filter\[(\]+(const char|char const) \[*\]+, int\[)\]+"
+ test_demangling "gnu: FindColor__7CatalogPCciii" \
+ "Catalog::FindColor\[(\]+(const char|char const) \[*\]+, int, int, int\[)\]+"
+ test_demangling_exact "gnu: FindFixed__FRP4CNetP4CNet" "FindFixed(CNet *&, CNet *)"
+ test_demangling "gnu: FindFont__7CatalogPCcN21" \
+ "Catalog::FindFont\[(\]+(const char|char const) \[*\]+, (const char|char const) \[*\]+, (const char|char const) \[*\]+\[)\]+"
+ test_demangling_exact "gnu: Fix48_abort__FR8twolongs" "Fix48_abort(twolongs &)"
+ test_demangling_exact "gnu: GetBarInfo__15iv2_6_VScrollerP13ivPerspectiveRiT2" "iv2_6_VScroller::GetBarInfo(ivPerspective *, int &, int &)"
+ test_demangling_exact "gnu: GetBgColor__C9ivPainter" "ivPainter::GetBgColor(void) const"
+
+ test_demangling "gnu: Iisdouble__FPC6IntRep" \
+ "Iisdouble\[(\]+(const IntRep|IntRep const) \[*\]+\[)\]+"
+ test_demangling_exact "gnu: InsertBody__15H_PullrightMenuii" "H_PullrightMenu::InsertBody(int, int)"
+ test_demangling_exact "gnu: InsertCharacter__9TextManipc" "TextManip::InsertCharacter(char)"
+
+ test_demangling_exact "gnu: InsertToplevel__7ivWorldP12ivInteractorT1" "ivWorld::InsertToplevel(ivInteractor *, ivInteractor *)"
+ test_demangling_exact "gnu: InsertToplevel__7ivWorldP12ivInteractorT1iiUi" "ivWorld::InsertToplevel(ivInteractor *, ivInteractor *, int, int, unsigned int)"
+ test_demangling "gnu: IsADirectory__FPCcR4stat" \
+ "IsADirectory\[(\]+(const char|char const) \[*\]+, stat &\[)\]+"
+ test_demangling_exact "gnu: IsAGroup__FP11GraphicViewP11GraphicComp" "IsAGroup(GraphicView *, GraphicComp *)"
+ test_demangling_exact "gnu: IsA__10ButtonCodeUl" "ButtonCode::IsA(unsigned long)"
+
+ test_demangling_exact "gnu: ReadName__FR7istreamPc" "ReadName(istream &, char *)"
+ test_demangling_exact "gnu: Redraw__13StringBrowseriiii" "StringBrowser::Redraw(int, int, int, int)"
+ test_demangling_exact "gnu: Rotate__13ivTransformerf" "ivTransformer::Rotate(float)"
+ test_demangling_exact "gnu: Rotated__C13ivTransformerf" "ivTransformer::Rotated(float) const"
+ test_demangling_exact "gnu: Round__Ff" "Round(float)"
+
+ test_demangling_exact "gnu: SetExport__16MemberSharedNameUi" "MemberSharedName::SetExport(unsigned int)"
+ test_demangling_exact "gnu: Set__14ivControlState13ControlStatusUi" "ivControlState::Set(ControlStatus, unsigned int)"
+ test_demangling_exact "gnu: Set__5DFacePcii" "DFace::Set(char *, int, int)"
+
+ test_demangling_exact "gnu: VConvert__9ivTSolverP12ivInteractorRP8TElementT2" "ivTSolver::VConvert(ivInteractor *, TElement *&, TElement *&)"
+ test_demangling_exact "gnu: VConvert__9ivTSolverP7ivTGlueRP8TElement" "ivTSolver::VConvert(ivTGlue *, TElement *&)"
+ test_demangling_exact "gnu: VOrder__9ivTSolverUiRP12ivInteractorT2" "ivTSolver::VOrder(unsigned int, ivInteractor *&, ivInteractor *&)"
+ test_demangling "gnu: Valid__7CatalogPCcRP4Tool" \
+ "Catalog::Valid\[(\]+(const char|char const) \[*\]+, Tool \[*\]+&\[)\]+"
+ test_demangling_exact "gnu: _10PageButton\$__both" "PageButton::__both"
+ test_demangling_exact "gnu: _3RNG\$singleMantissa" "RNG::singleMantissa"
+ test_demangling_exact "gnu: _5IComp\$_release" "IComp::_release"
+ test_demangling_exact "gnu: _\$_10BitmapComp" "BitmapComp::~BitmapComp(void)"
+
+ test_demangling_exact "gnu: _\$_9__io_defs" "__io_defs::~__io_defs(void)"
+ test_demangling_exact "gnu: _\$_Q23foo3bar" "foo::bar::~bar(void)"
+ test_demangling_exact "gnu: _\$_Q33foo3bar4bell" "foo::bar::bell::~bell(void)"
+ test_demangling_exact "gnu: __10ivTelltaleiP7ivGlyph" "ivTelltale::ivTelltale(int, ivGlyph *)"
+ test_demangling_exact "gnu: __10ivViewportiP12ivInteractorUi" "ivViewport::ivViewport(int, ivInteractor *, unsigned int)"
+ test_demangling_exact "gnu: __10ostrstream" "ostrstream::ostrstream(void)"
+ test_demangling_exact "gnu: __10ostrstreamPcii" "ostrstream::ostrstream(char *, int, int)"
+ test_demangling "gnu: __11BasicDialogiPCcP13ivButtonStateN22Ui" \
+ "BasicDialog::BasicDialog\[(\]+int, (const char|char const) \[*\]+, ivButtonState \[*\]+, (const char|char const) \[*\]+, (const char|char const) \[*\]+, unsigned int\[)\]+"
+ test_demangling_exact "gnu: __11BitmapTablei" "BitmapTable::BitmapTable(int)"
+ test_demangling_exact "gnu: __12ViewportCodeP12ViewportComp" "ViewportCode::ViewportCode(ViewportComp *)"
+ test_demangling "gnu: __12iv2_6_BorderiPCci" \
+ "iv2_6_Border::iv2_6_Border\[(\]+int, (const char|char const) \[*\]+, int\[)\]+"
+ test_demangling_exact "gnu: __12iv2_6_Borderii" "iv2_6_Border::iv2_6_Border(int, int)"
+ test_demangling "gnu: __12ivBackgroundiP7ivGlyphPC7ivColor" \
+ "ivBackground::ivBackground\[(\]+int, ivGlyph \[*\]+, (const ivColor|ivColor const) \[*\]+\[)\]+"
+ test_demangling_exact "gnu: __12ivBreak_Listl" "ivBreak_List::ivBreak_List(long)"
+ test_demangling "gnu: __14TextInteractoriPCcUi" \
+ "TextInteractor::TextInteractor\[(\]+int, (const char|char const) \[*\]+, unsigned int\[)\]+"
+ test_demangling_exact "gnu: __14iv2_6_MenuItemiP12ivInteractor" "iv2_6_MenuItem::iv2_6_MenuItem(int, ivInteractor *)"
+ test_demangling "gnu: __14iv2_6_MenuItemiPCcP12ivInteractor" \
+ "iv2_6_MenuItem::iv2_6_MenuItem\[(\]+int, (const char|char const) \[*\]+, ivInteractor \[*\]+\[)\]+"
+
+ test_demangling_exact "gnu: __20DisplayList_IteratorR11DisplayList" "DisplayList_Iterator::DisplayList_Iterator(DisplayList &)"
+ test_demangling_exact "gnu: __3fooRT0" "foo::foo(foo &)"
+ test_demangling_exact "gnu: __3fooiN31" "foo::foo(int, int, int, int)"
+ test_demangling "gnu: __3fooiPCc" \
+ "foo::foo\[(\]+int, (const char|char const) \[*\]+\[)\]+"
+ test_demangling_exact "gnu: __3fooiRT0iT2iT2" "foo::foo(int, foo &, int, foo &, int, foo &)"
+ test_demangling "gnu: __6GetOptiPPcPCc" \
+ "GetOpt::GetOpt\[(\]+int, char \[*\]+\[*\]+, (const char|char const) \[*\]+\[)\]+"
+ test_demangling_exact "gnu: __6KeyMapPT0" "KeyMap::KeyMap(KeyMap *)"
+ test_demangling "gnu: __7ivWorldPCcRiPPcPC12ivOptionDescPC14ivPropertyData" \
+ "ivWorld::ivWorld\[(\]+(const char|char const) \[*\]+, int &, char \[*\]+\[*\]+, (const ivOptionDesc|ivOptionDesc const) \[*\]+, (const ivPropertyData|ivPropertyData const) \[*\]+\[)\]+"
+ test_demangling "gnu: __7procbufPCci" \
+ "procbuf::procbuf\[(\]+(const char|char const) \[*\]+, int\[)\]+"
+ test_demangling_exact "gnu: __8ArrowCmdP6EditorUiUi" "ArrowCmd::ArrowCmd(Editor *, unsigned int, unsigned int)"
+
+ test_demangling_exact "gnu: __9F_EllipseiiiiP7Graphic" "F_Ellipse::F_Ellipse(int, int, int, int, Graphic *)"
+ test_demangling_exact "gnu: __9FrameDataP9FrameCompi" "FrameData::FrameData(FrameComp *, int)"
+ test_demangling_exact "gnu: __9HVGraphicP9CanvasVarP7Graphic" "HVGraphic::HVGraphic(CanvasVar *, Graphic *)"
+ test_demangling_exact "gnu: __Q23foo3bar" "foo::bar::bar(void)"
+ test_demangling_exact "gnu: __Q33foo3bar4bell" "foo::bar::bell::bell(void)"
+ test_demangling_exact "gnu: __aa__3fooRT0" "foo::operator&&(foo &)"
+ test_demangling_exact "gnu: __aad__3fooRT0" "foo::operator&=(foo &)"
+ test_demangling_exact "gnu: __ad__3fooRT0" "foo::operator&(foo &)"
+ test_demangling_exact "gnu: __adv__3fooRT0" "foo::operator/=(foo &)"
+ test_demangling_exact "gnu: __aer__3fooRT0" "foo::operator^=(foo &)"
+ test_demangling_exact "gnu: __als__3fooRT0" "foo::operator<<=(foo &)"
+ test_demangling_exact "gnu: __amd__3fooRT0" "foo::operator%=(foo &)"
+ test_demangling_exact "gnu: __ami__3fooRT0" "foo::operator-=(foo &)"
+ test_demangling_exact "gnu: __aml__3FixRT0" "Fix::operator*=(Fix &)"
+ test_demangling_exact "gnu: __aml__5Fix16i" "Fix16::operator*=(int)"
+ test_demangling_exact "gnu: __aml__5Fix32RT0" "Fix32::operator*=(Fix32 &)"
+ test_demangling_exact "gnu: __aor__3fooRT0" "foo::operator|=(foo &)"
+ test_demangling_exact "gnu: __apl__3fooRT0" "foo::operator+=(foo &)"
+ test_demangling_exact "gnu: __ars__3fooRT0" "foo::operator>>=(foo &)"
+
+ test_demangling_exact "gnu: __as__3fooRT0" "foo::operator=(foo &)"
+ test_demangling_exact "gnu: __cl__3fooRT0" "foo::operator()(foo &)"
+ test_demangling_exact "gnu: __cl__6Normal" "Normal::operator()(void)"
+ test_demangling_exact "gnu: __cl__6Stringii" "String::operator()(int, int)"
+ test_demangling_exact "gnu: __cm__3fooRT0" "foo::operator, (foo &)"
+ test_demangling_exact "gnu: __co__3foo" "foo::operator~(void)"
+ test_demangling_exact "gnu: __dl__3fooPv" "foo::operator delete(void *)"
+ test_demangling_exact "gnu: __dv__3fooRT0" "foo::operator/(foo &)"
+ test_demangling_exact "gnu: __eq__3fooRT0" "foo::operator==(foo &)"
+ test_demangling_exact "gnu: __er__3fooRT0" "foo::operator^(foo &)"
+ test_demangling_exact "gnu: __ge__3fooRT0" "foo::operator>=(foo &)"
+ test_demangling_exact "gnu: __gt__3fooRT0" "foo::operator>(foo &)"
+ test_demangling_exact "gnu: __le__3fooRT0" "foo::operator<=(foo &)"
+ test_demangling_exact "gnu: __ls__3fooRT0" "foo::operator<<(foo &)"
+ test_demangling_exact "gnu: __ls__FR7ostreamPFR3ios_R3ios" "operator<<(ostream &, ios &(*)(ios &))"
+ test_demangling_exact "gnu: __ls__FR7ostreamR3Fix" "operator<<(ostream &, Fix &)"
+ test_demangling_exact "gnu: __lt__3fooRT0" "foo::operator<(foo &)"
+ test_demangling_exact "gnu: __md__3fooRT0" "foo::operator%(foo &)"
+ test_demangling_exact "gnu: __mi__3fooRT0" "foo::operator-(foo &)"
+ test_demangling_exact "gnu: __ml__3fooRT0" "foo::operator*(foo &)"
+ test_demangling_exact "gnu: __mm__3fooi" "foo::operator--(int)"
+
+ test_demangling_exact "gnu: __ne__3fooRT0" "foo::operator!=(foo &)"
+ test_demangling "gnu: __ne__FRC7ComplexT0" \
+ "operator!=\[(\]+(const Complex|Complex const) &, (const Complex|Complex const) &\[)\]+"
+ test_demangling "gnu: __ne__FRC7Complexd" \
+ "operator!=\[(\]+(const Complex|Complex const) &, double\[)\]+"
+ test_demangling "gnu: __ne__FRC9SubStringRC6String" \
+ "operator!=\[(\]+(const SubString|SubString const) &, (const String|String const) &\[)\]+"
+ test_demangling_exact "gnu: __nt__3foo" "foo::operator!(void)"
+ test_demangling_exact "gnu: __nw__3fooi" "foo::operator new(int)"
+ test_demangling_exact "gnu: __oo__3fooRT0" "foo::operator||(foo &)"
+ test_demangling_exact "gnu: __opPc__3foo" "foo::operator char *(void)"
+ test_demangling_exact "gnu: __opi__3foo" "foo::operator int(void)"
+ test_demangling_exact "gnu: __or__3fooRT0" "foo::operator|(foo &)"
+ test_demangling_exact "gnu: __pl__3fooRT0" "foo::operator+(foo &)"
+ test_demangling_exact "gnu: __pp__3fooi" "foo::operator++(int)"
+ test_demangling_exact "gnu: __rf__3foo" "foo::operator->(void)"
+ test_demangling_exact "gnu: __rm__3fooRT0" "foo::operator->*(foo &)"
+ test_demangling_exact "gnu: __rs__3fooRT0" "foo::operator>>(foo &)"
+ test_demangling "gnu: __vc__3fooRT0" "foo::operator\\\[\\\]\\(foo &\\)"
+ test_demangling "gnu: _gsub__6StringRC5RegexPCci" \
+ "String::_gsub\[(\]+(const Regex|Regex const) &, (const char|char const) \[*\]+, int\[)\]+"
+ test_demangling_exact "gnu: _new_Fix__FUs" "_new_Fix(unsigned short)"
+
+ # gcc 2.4.5 (and earlier) style virtual tables. We want to continue to
+ # correctly demangle these even if newer compilers use a different form.
+ test_demangling_exact "gnu: _vt.foo" "foo virtual table"
+ test_demangling_exact "gnu: _vt.foo.bar" "foo::bar virtual table"
+ test_demangling_exact "gnu: _vt\$foo" "foo virtual table"
+ test_demangling_exact "gnu: _vt\$foo\$bar" "foo::bar virtual table"
+
+ test_demangling_exact "gnu: append__7ivGlyphPT0" "ivGlyph::append(ivGlyph *)"
+ test_demangling "gnu: arg__FRC7Complex" \
+ "arg\[(\]+(const Complex|Complex const) &\[)\]+"
+ test_demangling_exact "gnu: clearok__FP7_win_sti" "clearok(_win_st *, int)"
+
+ test_demangling_exact "gnu: complexfunc2__FPFPc_i" "complexfunc2(int (*)(char *))"
+ test_demangling_exact "gnu: complexfunc3__FPFPFPl_s_i" "complexfunc3(int (*)(short (*)(long *)))"
+ test_demangling_exact "gnu: complexfunc4__FPFPFPc_s_i" "complexfunc4(int (*)(short (*)(char *)))"
+ test_demangling_exact "gnu: complexfunc5__FPFPc_PFl_i" "complexfunc5(int (*(*)(char *))(long))"
+ test_demangling_exact "gnu: complexfunc6__FPFPi_PFl_i" "complexfunc6(int (*(*)(int *))(long))"
+ test_demangling_exact "gnu: complexfunc7__FPFPFPc_i_PFl_i" "complexfunc7(int (*(*)(int (*)(char *)))(long))"
+ test_demangling "gnu: contains__C9BitStringRC10BitPattern" \
+ "BitString::contains\[(\]+(const BitPattern|BitPattern const) &\[)\]+ const"
+ test_demangling "gnu: contains__C9BitStringRC12BitSubStringi" \
+ "BitString::contains\[(\]+(const BitSubString|BitSubString const) &, int\[)\]+ const"
+ test_demangling "gnu: contains__C9BitStringRT0" \
+ "BitString::contains\[(\]+(const BitString|BitString const) &\[)\]+ const"
+ test_demangling "gnu: div__FPC6IntRepT0P6IntRep" \
+ "div\[(\]+(const IntRep|IntRep const) \[*\]+, (const IntRep|IntRep const) \[*\]+, IntRep \[*\]+\[)\]+"
+ test_demangling "gnu: div__FPC6IntReplP6IntRep" \
+ "div\[(\]+(const IntRep|IntRep const) \[*\]+, long, IntRep \[*\]+\[)\]+"
+ test_demangling "gnu: div__FRC8RationalT0R8Rational" \
+ "div\[(\]+(const Rational|Rational const) &, (const Rational|Rational const) &, Rational &\[)\]+"
+ test_demangling "gnu: divide__FRC7IntegerT0R7IntegerT2" \
+ "divide\[(\]+(const Integer|Integer const) &, (const Integer|Integer const) &, Integer &, Integer &\[)\]+"
+ test_demangling "gnu: divide__FRC7IntegerlR7IntegerRl" \
+ "divide\[(\]+(const Integer|Integer const) &, long, Integer &, long &\[)\]+"
+ test_demangling "gnu: enable__14DocumentViewerPCcUi" \
+ "DocumentViewer::enable\[(\]+(const char|char const) \[*\]+, unsigned int\[)\]+"
+
+ test_demangling_exact "gnu: foo__FiN30" "foo(int, int, int, int)"
+ test_demangling_exact "gnu: foo__FiR3fooiT1iT1" "foo(int, foo &, int, foo &, int, foo &)"
+ test_demangling_exact "gnu: foo___3barl" "bar::foo_(long)"
+ test_demangling_exact "gnu: insert__15ivClippingStacklRP8_XRegion" "ivClippingStack::insert(long, _XRegion *&)"
+ test_demangling_exact "gnu: insert__16ChooserInfo_ListlR11ChooserInfo" "ChooserInfo_List::insert(long, ChooserInfo &)"
+ test_demangling_exact "gnu: insert__17FontFamilyRepListlRP15ivFontFamilyRep" "FontFamilyRepList::insert(long, ivFontFamilyRep *&)"
+ test_demangling_exact "gnu: leaveok__FP7_win_stc" "leaveok(_win_st *, char)"
+ test_demangling_exact "gnu: left_mover__C7ivMFKitP12ivAdjustableP7ivStyle" "ivMFKit::left_mover(ivAdjustable *, ivStyle *) const"
+ test_demangling "gnu: matches__C9BitStringRC10BitPatterni" \
+ "BitString::matches\[(\]+(const BitPattern|BitPattern const) &, int\[)\]+ const"
+ test_demangling "gnu: matches__C9SubStringRC5Regex" \
+ "SubString::matches\[(\]+(const Regex|Regex const) &\[)\]+ const"
+
+ test_demangling_exact "gnu: overload1arg__FSc" "overload1arg(signed char)"
+ test_demangling_exact "gnu: overload1arg__FUc" "overload1arg(unsigned char)"
+ test_demangling_exact "gnu: overload1arg__FUi" "overload1arg(unsigned int)"
+ test_demangling_exact "gnu: overload1arg__FUl" "overload1arg(unsigned long)"
+ test_demangling_exact "gnu: overload1arg__FUs" "overload1arg(unsigned short)"
+ test_demangling_exact "gnu: overload1arg__Fc" "overload1arg(char)"
+ test_demangling_exact "gnu: overload1arg__Fd" "overload1arg(double)"
+ test_demangling_exact "gnu: overload1arg__Ff" "overload1arg(float)"
+ test_demangling_exact "gnu: overload1arg__Fi" "overload1arg(int)"
+ test_demangling_exact "gnu: overload1arg__Fl" "overload1arg(long)"
+ test_demangling_exact "gnu: overload1arg__Fs" "overload1arg(short)"
+ test_demangling_exact "gnu: overload1arg__Fv" "overload1arg(void)"
+ test_demangling_exact "gnu: overloadargs__Fi" "overloadargs(int)"
+ test_demangling_exact "gnu: overloadargs__Fii" "overloadargs(int, int)"
+ test_demangling_exact "gnu: overloadargs__Fiii" "overloadargs(int, int, int)"
+ test_demangling_exact "gnu: overloadargs__Fiiii" "overloadargs(int, int, int, int)"
+
+ test_demangling_exact "gnu: overloadargs__Fiiiii" "overloadargs(int, int, int, int, int)"
+ test_demangling_exact "gnu: overloadargs__Fiiiiii" "overloadargs(int, int, int, int, int, int)"
+ test_demangling_exact "gnu: overloadargs__Fiiiiiii" "overloadargs(int, int, int, int, int, int, int)"
+ test_demangling_exact "gnu: overloadargs__Fiiiiiiii" "overloadargs(int, int, int, int, int, int, int, int)"
+ test_demangling_exact "gnu: overloadargs__Fiiiiiiiii" "overloadargs(int, int, int, int, int, int, int, int, int)"
+ test_demangling_exact "gnu: overloadargs__Fiiiiiiiiii" "overloadargs(int, int, int, int, int, int, int, int, int, int)"
+ test_demangling_exact "gnu: overloadargs__Fiiiiiiiiiii" "overloadargs(int, int, int, int, int, int, int, int, int, int, int)"
+ test_demangling "gnu: pick__13ivCompositionP8ivCanvasRC12ivAllocationiR5ivHit" \
+ "ivComposition::pick\[(\]+ivCanvas \[*\]+, (const ivAllocation|ivAllocation const) &, int, ivHit &\[)\]+"
+ test_demangling "gnu: pointer__C11ivHScrollerRC7ivEventRC12ivAllocation" \
+ "ivHScroller::pointer\[(\]+(const ivEvent|ivEvent const) &, (const ivAllocation|ivAllocation const) &\[)\]+ const"
+ test_demangling_exact "gnu: poke__8ivRasterUlUlffff" "ivRaster::poke(unsigned long, unsigned long, float, float, float, float)"
+ test_demangling_exact "gnu: polar__Fdd" "polar(double, double)"
+ test_demangling "gnu: read__10osStdInputRPCc" \
+ "osStdInput::read\[(\]+(const char|char const) \[*\]+&\[)\]+"
+
+ test_demangling_exact "gnu: scale__13ivTransformerff" "ivTransformer::scale(float, float)"
+ test_demangling "gnu: scanw__12CursesWindowPCce" \
+ "CursesWindow::scanw\[(\]+(const char|char const) \[*\]+,...\[)\]+"
+ test_demangling "gnu: scmp__FPCcT0" \
+ "scmp\[(\]+(const char|char const) \[*\]+, (const char|char const) \[*\]+\[)\]+"
+ test_demangling_exact "gnu: sgetn__7filebufPci" "filebuf::sgetn(char *, int)"
+ test_demangling_exact "gnu: shift__FP5_FrepiT0" "shift(_Frep *, int, _Frep *)"
+ test_demangling_exact "gnu: test__C6BitSeti" "BitSet::test(int) const"
+ test_demangling_exact "gnu: test__C6BitSetii" "BitSet::test(int, int) const"
+ test_demangling "gnu: testbit__FRC7Integerl" \
+ "testbit\[(\]+(const Integer|Integer const) &, long\[)\]+"
+ test_demangling_exact "gnu: text_source__8Documentl" "Document::text_source(long)"
+ test_demangling_exact "gnu: variance__6Erlangd" "Erlang::variance(double)"
+ test_demangling "gnu: vform__8iostreamPCcPc" \
+ "iostream::vform\[(\]+(const char|char const) \[*\]+, char \[*\]+\[)\]+"
+ test_demangling_exact "gnu: view__14DocumentViewerP8ItemViewP11TabularItem" "DocumentViewer::view(ItemView *, TabularItem *)"
+ test_demangling_exact "gnu: xy_extents__11ivExtensionffff" "ivExtension::xy_extents(float, float, float, float)"
+ test_demangling_exact "gnu: zero__8osMemoryPvUi" "osMemory::zero(void *, unsigned int)"
+ test_demangling_exact "gnu: _2T4\$N" "T4::N"
+ test_demangling_exact "gnu: _Q22T42t1\$N" "T4::t1::N"
+ test_demangling_exact "gnu: get__2T1" "T1::get(void)"
+ test_demangling_exact "gnu: get__Q22T11a" "T1::a::get(void)"
+ test_demangling_exact "gnu: get__Q32T11a1b" "T1::a::b::get(void)"
+ test_demangling_exact "gnu: get__Q42T11a1b1c" "T1::a::b::c::get(void)"
+ test_demangling_exact "gnu: get__Q52T11a1b1c1d" "T1::a::b::c::d::get(void)"
+ test_demangling_exact "gnu: put__2T1i" "T1::put(int)"
+ test_demangling_exact "gnu: put__Q22T11ai" "T1::a::put(int)"
+ test_demangling_exact "gnu: put__Q32T11a1bi" "T1::a::b::put(int)"
+ test_demangling_exact "gnu: put__Q42T11a1b1ci" "T1::a::b::c::put(int)"
+ test_demangling_exact "gnu: put__Q52T11a1b1c1di" "T1::a::b::c::d::put(int)"
+
+ test_demangling_exact "gnu: bar__3fooPv" "foo::bar(void *)"
+ test_demangling "gnu: bar__3fooPCv" \
+ "foo::bar\[(\]+(const void|void const) *\[*\]+\[)\]+"
+ test_demangling_exact "gnu: bar__C3fooPv" "foo::bar(void *) const"
+ test_demangling "gnu: bar__C3fooPCv" \
+ "foo::bar\[(\]+(const void|void const) *\[*\]+\[)\]+ const"
+ test_demangling_exact "gnu: __eq__3fooRT0" "foo::operator==(foo &)"
+ test_demangling "gnu: __eq__3fooRC3foo" \
+ "foo::operator==\[(\]+(const foo|foo const) &\[)\]+"
+ test_demangling_exact "gnu: __eq__C3fooR3foo" "foo::operator==(foo &) const"
+ test_demangling "gnu: __eq__C3fooRT0" \
+ "foo::operator==\[(\]+(const foo|foo const) &\[)\]+ const"
+
+ test_demangling_exact "gnu: elem__t6vector1Zdi" "vector<double>::elem(int)"
+ test_demangling_exact "gnu: elem__t6vector1Zii" "vector<int>::elem(int)"
+ test_demangling_exact "gnu: __t6vector1Zdi" "vector<double>::vector(int)"
+ test_demangling_exact "gnu: __t6vector1Zii" "vector<int>::vector(int)"
+ test_demangling_exact "gnu: _\$_t6vector1Zdi" "vector<double>::~vector(int)"
+ test_demangling_exact "gnu: _\$_t6vector1Zii" "vector<int>::~vector(int)"
+
+ test_demangling_exact "gnu: __nw__t2T11ZcUi" "T1<char>::operator new(unsigned int)"
+ test_demangling_exact "gnu: __nw__t2T11Z1tUi" "T1<t>::operator new(unsigned int)"
+ test_demangling_exact "gnu: __dl__t2T11ZcPv" "T1<char>::operator delete(void *)"
+ test_demangling_exact "gnu: __dl__t2T11Z1tPv" "T1<t>::operator delete(void *)"
+ test_demangling_exact "gnu: __t2T11Zci" "T1<char>::T1(int)"
+ test_demangling_exact "gnu: __t2T11Zc" "T1<char>::T1(void)"
+ test_demangling_exact "gnu: __t2T11Z1ti" "T1<t>::T1(int)"
+ test_demangling_exact "gnu: __t2T11Z1t" "T1<t>::T1(void)"
+
+ test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity3Pix" \
+ "List<VHDLEntity>::Pix::Pix(void)"
+
+ test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity3PixPQ2t4List1Z10VHDLEntity7element" \
+ "List<VHDLEntity>::Pix::Pix(List<VHDLEntity>::element *)"
+
+ test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity3PixRCQ2t4List1Z10VHDLEntity3Pix" \
+ "List<VHDLEntity>::Pix::Pix(List<VHDLEntity>::Pix const &)"
+
+ test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity7elementRC10VHDLEntityPT0" \
+ "List<VHDLEntity>::element::element(VHDLEntity const &, List<VHDLEntity>::element *)"
+
+ test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity7elementRCQ2t4List1Z10VHDLEntity7element" \
+ "List<VHDLEntity>::element::element(List<VHDLEntity>::element const &)"
+
+ test_demangling_exact "gnu: __cl__C11VHDLLibraryGt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
+ "VHDLLibrary::operator()(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >) const"
+
+ test_demangling_exact "gnu: __cl__Ct4List1Z10VHDLEntityRCQ2t4List1Z10VHDLEntity3Pix" \
+ "List<VHDLEntity>::operator()(List<VHDLEntity>::Pix const &) const"
+
+ test_demangling_exact "gnu: __ne__FPvRCQ2t4List1Z10VHDLEntity3Pix" \
+ "operator!=(void *, List<VHDLEntity>::Pix const &)"
+
+ test_demangling_exact "gnu: __ne__FPvRCt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
+ "operator!=(void *, PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const &)"
+
+ test_demangling_exact "gnu: __t4List1Z10VHDLEntityRCt4List1Z10VHDLEntity" \
+ "List<VHDLEntity>::List(List<VHDLEntity> const &)"
+
+ test_demangling_exact "gnu: __t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
+ "PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(void)"
+
+ test_demangling_exact "gnu: __t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntityP14VHDLLibraryRepGQ2t4List1Z10VHDLEntity3Pix" \
+ "PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(VHDLLibraryRep *, List<VHDLEntity>::Pix)"
+
+ test_demangling_exact "gnu: __t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntityRCt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
+ "PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const &)"
+
+ test_demangling_exact "gnu: nextE__C11VHDLLibraryRt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
+ "VHDLLibrary::nextE(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > &) const"
+
+ test_demangling_exact "gnu: next__Ct4List1Z10VHDLEntityRQ2t4List1Z10VHDLEntity3Pix" \
+ "List<VHDLEntity>::next(List<VHDLEntity>::Pix &) const"
+
+ test_demangling_exact "gnu: _GLOBAL_\$D\$set" "global destructors keyed to set"
+
+ test_demangling_exact "gnu: _GLOBAL_\$I\$set" "global constructors keyed to set"
+
+ test_demangling_exact "gnu: __as__t5ListS1ZUiRCt5ListS1ZUi" \
+ "ListS<unsigned int>::operator=(ListS<unsigned int> const &)"
+
+ test_demangling_exact "gnu: __cl__Ct5ListS1ZUiRCQ2t5ListS1ZUi3Vix" \
+ "ListS<unsigned int>::operator()(ListS<unsigned int>::Vix const &) const"
+
+ test_demangling_exact "gnu: __cl__Ct5SetLS1ZUiRCQ2t5SetLS1ZUi3Vix" \
+ "SetLS<unsigned int>::operator()(SetLS<unsigned int>::Vix const &) const"
+
+ test_demangling_exact "gnu: __t10ListS_link1ZUiRCUiPT0" \
+ "ListS_link<unsigned int>::ListS_link(unsigned int const &, ListS_link<unsigned int> *)"
+
+ test_demangling_exact "gnu: __t10ListS_link1ZUiRCt10ListS_link1ZUi" \
+ "ListS_link<unsigned int>::ListS_link(ListS_link<unsigned int> const &)"
+
+ test_demangling_exact "gnu: __t5ListS1ZUiRCt5ListS1ZUi" \
+ "ListS<unsigned int>::ListS(ListS<unsigned int> const &)"
+
+ test_demangling_exact "gnu: next__Ct5ListS1ZUiRQ2t5ListS1ZUi3Vix" \
+ "ListS<unsigned int>::next(ListS<unsigned int>::Vix &) const"
+
+ test_demangling_exact "gnu: __ne__FPvRCQ2t5SetLS1ZUi3Vix" \
+ "operator!=(void *, SetLS<unsigned int>::Vix const &)"
+ test_demangling_exact "gnu: __t8ListElem1Z5LabelRt4List1Z5Label" \
+ "ListElem<Label>::ListElem(List<Label> &)"
+ test_demangling_exact "gnu: __t8BDDHookV1ZPcRCPc" \
+ "BDDHookV<char *>::BDDHookV(char *const &)"
+
+ test_demangling_exact "gnu: _vt\$t8BDDHookV1ZPc" "BDDHookV<char *> virtual table"
+
+ test_demangling_exact "gnu: __ne__FPvRCQ211BDDFunction4VixB" \
+ "operator!=(void *, BDDFunction::VixB const &)"
+ test_demangling_exact "gnu: __eq__FPvRCQ211BDDFunction4VixB" \
+ "operator==(void *, BDDFunction::VixB const &)"
+
+ test_demangling_exact "gnu: relativeId__CQ36T_phi210T_preserve8FPC_nextRCQ26T_phi210T_preserveRC10Parameters" \
+ "T_phi2::T_preserve::FPC_next::relativeId(T_phi2::T_preserve const &, Parameters const &) const"
+
+ test_demangling_exact "gnu: _Utf390_1__1_9223372036854775807__9223372036854775" \
+ "Can't demangle \"_Utf390_1__1_9223372036854775807__9223372036854775\""
+ test_demangling_exact "gnu: foo__I40" "foo(int64_t)"
+ test_demangling_exact "gnu: foo__I_200_" "foo(int512_t)"
+ test_demangling_exact "gnu: foo__I_200" "Can't demangle \"foo__I_200\""
+
+ ## Buffer overrun. Should make GDB crash. Woo hoo!
+ test_demangling_exact "gnu: foo__I_4000000000000000000000000000000000000000000000000000000000000000000000000" "Can't demangle \"foo__I_4000000000000000000000000000000000000000000000000000000000000000000000000\""
+
+ ## 1999-04-19: "Fix from Dale Hawkins". Shouldn't segfault.
+ # Accept even a dubious demangling; the string is ambiguous.
+ send_gdb "maintenance demangle __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlRPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingRPQ29CosNaming15BindingIterator\n"
+ gdb_expect {
+ -re "virtual function thunk \\(delta:-64\\) for CosNaming::_proxy_NamingContext::_0RL__list\\(unsigned long, _CORBA_Unbounded_Sequence<CosNaming::Binding> \\*\\&, CosNaming::BindingIterator \\*\\&\\)\r\n$gdb_prompt $" {
+ pass "gnu: __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlRPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingRPQ29CosNaming15BindingIterator"
+ }
+ -re ".*Can't demangle \"__thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlRPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingRPQ29CosNaming15BindingIterator\"\r\n$gdb_prompt $" {
+ pass "gnu: __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlRPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingRPQ29CosNaming15BindingIterator"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "gnu: __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlRPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingRPQ29CosNaming15BindingIterator"
+ }
+ timeout {
+ fail "gnu: __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlRPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingRPQ29CosNaming15BindingIterator (timeout)"
+ }
+ }
+}
+
+#
+# Test lucid style name demangling
+#
+
+proc test_lucid_style_demangling {} {
+ test_demangling_exact "lucid: WS__FR7istream" "WS(istream &)"
+ test_demangling_exact "lucid: __aa__3fooFR3foo" "foo::operator&&(foo &)"
+ test_demangling_exact "lucid: __aad__3fooFR3foo" "foo::operator&=(foo &)"
+ test_demangling_exact "lucid: __ad__3fooFR3foo" "foo::operator&(foo &)"
+ test_demangling_exact "lucid: __adv__3fooFR3foo" "foo::operator/=(foo &)"
+ test_demangling_exact "lucid: __adv__7complexF7complex" "complex::operator/=(complex)"
+ test_demangling_exact "lucid: __aer__3fooFR3foo" "foo::operator^=(foo &)"
+ test_demangling_exact "lucid: __als__3fooFR3foo" "foo::operator<<=(foo &)"
+ test_demangling_exact "lucid: __amd__3fooFR3foo" "foo::operator%=(foo &)"
+ test_demangling_exact "lucid: __ami__3fooFR3foo" "foo::operator-=(foo &)"
+ test_demangling_exact "lucid: __amu__3fooFR3foo" "foo::operator*=(foo &)"
+ test_demangling_exact "lucid: __amu__7complexF7complex" "complex::operator*=(complex)"
+ test_demangling_exact "lucid: __aor__3fooFR3foo" "foo::operator|=(foo &)"
+ test_demangling_exact "lucid: __apl__3fooFR3foo" "foo::operator+=(foo &)"
+ test_demangling_exact "lucid: __ars__3fooFR3foo" "foo::operator>>=(foo &)"
+ test_demangling_exact "lucid: __as__18istream_withassignFP9streambuf" "istream_withassign::operator=(streambuf *)"
+ test_demangling_exact "lucid: __as__18istream_withassignFR7istream" "istream_withassign::operator=(istream &)"
+ test_demangling_exact "lucid: __as__3fooFR3foo" "foo::operator=(foo &)"
+ test_demangling_exact "lucid: __as__3iosFR3ios" "ios::operator=(ios &)"
+ test_demangling_exact "lucid: __cl__3fooFR3foo" "foo::operator()(foo &)"
+ test_demangling_exact "lucid: __cm__3fooFR3foo" "foo::operator, (foo &)"
+
+ test_demangling_exact "lucid: __co__3fooFv" "foo::operator~(void)"
+ test_demangling_exact "lucid: __ct__10istrstreamFPc" "istrstream::istrstream(char *)"
+ test_demangling_exact "lucid: __ct__10istrstreamFPci" "istrstream::istrstream(char *, int)"
+ test_demangling_exact "lucid: __ct__10ostrstreamFPciT2" "ostrstream::ostrstream(char *, int, int)"
+ test_demangling_exact "lucid: __ct__10ostrstreamFv" "ostrstream::ostrstream(void)"
+ test_demangling_exact "lucid: __ct__10smanip_intFPFR3iosi_R3iosi" "smanip_int::smanip_int(ios &(*)(ios &, int), int)"
+ test_demangling "lucid: __ct__11c_exceptionFPcRC7complexT2" "c_exception::c_exception\[(\]+char \[*\]+, (const complex|complex const) &, (const complex|complex const) &\[)\]+"
+ test_demangling "lucid: __ct__11fstreambaseFPCciT2" "fstreambase::fstreambase\[(\]+(const char|char const) \[*\]+, int, int\[)\]+"
+ test_demangling_exact "lucid: __ct__11fstreambaseFi" "fstreambase::fstreambase(int)"
+ test_demangling_exact "lucid: __ct__11fstreambaseFiPcT1" "fstreambase::fstreambase(int, char *, int)"
+ test_demangling_exact "lucid: __ct__11fstreambaseFv" "fstreambase::fstreambase(void)"
+ test_demangling_exact "lucid: __ct__11smanip_longFPFR3iosl_R3iosl" "smanip_long::smanip_long(ios &(*)(ios &, long), long)"
+ test_demangling_exact "lucid: __ct__11stdiostreamFP4FILE" "stdiostream::stdiostream(FILE *)"
+ test_demangling_exact "lucid: __ct__12strstreambufFPFl_PvPFPv_v" "strstreambuf::strstreambuf(void *(*)(long), void (*)(void *))"
+ test_demangling_exact "lucid: __ct__12strstreambufFPUciT1" "strstreambuf::strstreambuf(unsigned char *, int, unsigned char *)"
+ test_demangling_exact "lucid: __ct__12strstreambufFPciT1" "strstreambuf::strstreambuf(char *, int, char *)"
+ test_demangling_exact "lucid: __ct__12strstreambufFi" "strstreambuf::strstreambuf(int)"
+ test_demangling_exact "lucid: __ct__12strstreambufFv" "strstreambuf::strstreambuf(void)"
+ test_demangling_exact "lucid: __ct__13strstreambaseFPciT1" "strstreambase::strstreambase(char *, int, char *)"
+ test_demangling_exact "lucid: __ct__3fooFR3foo" "foo::foo(foo &)"
+
+ test_demangling_exact "lucid: __ct__3fooFi" "foo::foo(int)"
+ test_demangling_exact "lucid: __ct__3fooFiN31" "foo::foo(int, int, int, int)"
+ test_demangling "lucid: __ct__3fooFiPCc" \
+ "foo::foo\[(\]+int, (const char|char const) \[*\]+\[)\]+"
+ test_demangling_exact "lucid: __ct__3fooFiR3fooT1T2T1T2" "foo::foo(int, foo &, int, foo &, int, foo &)"
+ test_demangling_exact "lucid: __ct__3iosFP9streambuf" "ios::ios(streambuf *)"
+ test_demangling_exact "lucid: __ct__7filebufFiPcT1" "filebuf::filebuf(int, char *, int)"
+ test_demangling "lucid: __ct__7fstreamFPCciT2" \
+ "fstream::fstream\[(\]+(const char|char const) \[*\]+, int, int\[)\]+"
+ test_demangling_exact "lucid: __ct__7fstreamFiPcT1" "fstream::fstream(int, char *, int)"
+ test_demangling_exact "lucid: __ct__7istreamFP9streambuf" "istream::istream(streambuf *)"
+ test_demangling_exact "lucid: __ct__7istreamFP9streambufiP7ostream" "istream::istream(streambuf *, int, ostream *)"
+ test_demangling_exact "lucid: __ct__7istreamFiPcT1" "istream::istream(int, char *, int)"
+ test_demangling_exact "lucid: __ct__7istreamFiT1P7ostream" "istream::istream(int, int, ostream *)"
+ test_demangling_exact "lucid: __ct__7ostreamFP9streambuf" "ostream::ostream(streambuf *)"
+ test_demangling_exact "lucid: __ct__7ostreamFiPc" "ostream::ostream(int, char *)"
+ test_demangling "lucid: __ct__8ifstreamFPCciT2" \
+ "ifstream::ifstream\[(\]+(const char|char const) \[*\]+, int, int\[)\]+"
+ test_demangling_exact "lucid: __ct__8ifstreamFiPcT1" "ifstream::ifstream(int, char *, int)"
+
+ test_demangling_exact "lucid: __ct__Q23foo3barFv" "foo::bar::bar(void)"
+ test_demangling_exact "lucid: __ct__Q33foo3bar4bellFv" "foo::bar::bell::bell(void)"
+ test_demangling_exact "lucid: __dl__3fooSFPv" "foo::operator delete(void *) static"
+ test_demangling_exact "lucid: __dl__FPv" "operator delete(void *)"
+ test_demangling_exact "lucid: __dt__10istrstreamFv" "istrstream::~istrstream(void)"
+
+ test_demangling_exact "lucid: __dt__Q23foo3barFv" "foo::bar::~bar(void)"
+ test_demangling_exact "lucid: __dt__Q33foo3bar4bellFv" "foo::bar::bell::~bell(void)"
+ test_demangling_exact "lucid: __dv__3fooFR3foo" "foo::operator/(foo &)"
+ test_demangling_exact "lucid: __dv__F7complexT1" "operator/(complex, complex)"
+ test_demangling_exact "lucid: __eq__3fooFR3foo" "foo::operator==(foo &)"
+ test_demangling_exact "lucid: __er__3fooFR3foo" "foo::operator^(foo &)"
+ test_demangling_exact "lucid: __ge__3fooFR3foo" "foo::operator>=(foo &)"
+ test_demangling_exact "lucid: __gt__3fooFR3foo" "foo::operator>(foo &)"
+ test_demangling_exact "lucid: __le__3fooFR3foo" "foo::operator<=(foo &)"
+ test_demangling_exact "lucid: __ls__3fooFR3foo" "foo::operator<<(foo &)"
+ test_demangling_exact "lucid: __ls__7ostreamFP9streambuf" "ostream::operator<<(streambuf *)"
+
+ test_demangling "lucid: __ls__7ostreamFPCc" \
+ "ostream::operator<<\[(\]+(const char|char const) \[*\]+\[)\]+"
+ test_demangling_exact "lucid: __ls__7ostreamFPFR3ios_R3ios" "ostream::operator<<(ios &(*)(ios &))"
+ test_demangling_exact "lucid: __ls__7ostreamFPv" "ostream::operator<<(void *)"
+ test_demangling_exact "lucid: __ls__7ostreamFUi" "ostream::operator<<(unsigned int)"
+ test_demangling_exact "lucid: __ls__7ostreamFUl" "ostream::operator<<(unsigned long)"
+ test_demangling_exact "lucid: __ls__7ostreamFd" "ostream::operator<<(double)"
+ test_demangling_exact "lucid: __ls__7ostreamFf" "ostream::operator<<(float)"
+ test_demangling_exact "lucid: __ls__7ostreamFi" "ostream::operator<<(int)"
+ test_demangling_exact "lucid: __ls__7ostreamFl" "ostream::operator<<(long)"
+ test_demangling_exact "lucid: __ls__FR7ostream7complex" "operator<<(ostream &, complex)"
+ test_demangling_exact "lucid: __lt__3fooFR3foo" "foo::operator<(foo &)"
+ test_demangling_exact "lucid: __md__3fooFR3foo" "foo::operator%(foo &)"
+ test_demangling_exact "lucid: __mi__3fooFR3foo" "foo::operator-(foo &)"
+ test_demangling_exact "lucid: __ml__3fooFR3foo" "foo::operator*(foo &)"
+ test_demangling_exact "lucid: __ml__F7complexT1" "operator*(complex, complex)"
+ test_demangling_exact "lucid: __mm__3fooFi" "foo::operator--(int)"
+ test_demangling_exact "lucid: __ne__3fooFR3foo" "foo::operator!=(foo &)"
+ test_demangling_exact "lucid: __nt__3fooFv" "foo::operator!(void)"
+ test_demangling_exact "lucid: __nw__3fooSFi" "foo::operator new(int) static"
+ test_demangling_exact "lucid: __nw__FUi" "operator new(unsigned int)"
+ test_demangling_exact "lucid: __nw__FUiPv" "operator new(unsigned int, void *)"
+ test_demangling_exact "lucid: __oo__3fooFR3foo" "foo::operator||(foo &)"
+ test_demangling_exact "lucid: __opPc__3fooFv" "foo::operator char *(void)"
+ test_demangling_exact "lucid: __opi__3fooFv" "foo::operator int(void)"
+ test_demangling_exact "lucid: __or__3fooFR3foo" "foo::operator|(foo &)"
+
+ test_demangling_exact "lucid: __pl__3fooFR3foo" "foo::operator+(foo &)"
+ test_demangling_exact "lucid: __pp__3fooFi" "foo::operator++(int)"
+ test_demangling_exact "lucid: __pt__3fooFv" "foo::operator->(void)"
+ test_demangling_exact "lucid: __rm__3fooFR3foo" "foo::operator->*(foo &)"
+ test_demangling_exact "lucid: __rs__3fooFR3foo" "foo::operator>>(foo &)"
+ test_demangling_exact "lucid: __rs__7istreamFP9streambuf" "istream::operator>>(streambuf *)"
+ test_demangling_exact "lucid: __rs__7istreamFPFR3ios_R3ios" "istream::operator>>(ios &(*)(ios &))"
+ test_demangling_exact "lucid: __rs__7istreamFPFR7istream_R7istream" "istream::operator>>(istream &(*)(istream &))"
+ test_demangling_exact "lucid: __rs__7istreamFPUc" "istream::operator>>(unsigned char *)"
+ test_demangling_exact "lucid: __rs__7istreamFPc" "istream::operator>>(char *)"
+ test_demangling_exact "lucid: __rs__7istreamFRUi" "istream::operator>>(unsigned int &)"
+ test_demangling_exact "lucid: __rs__7istreamFRUl" "istream::operator>>(unsigned long &)"
+ test_demangling_exact "lucid: __rs__7istreamFRUs" "istream::operator>>(unsigned short &)"
+ test_demangling_exact "lucid: __rs__7istreamFRd" "istream::operator>>(double &)"
+ test_demangling_exact "lucid: __rs__7istreamFRf" "istream::operator>>(float &)"
+ test_demangling_exact "lucid: __rs__7istreamFRi" "istream::operator>>(int &)"
+ test_demangling_exact "lucid: __rs__7istreamFRl" "istream::operator>>(long &)"
+ test_demangling_exact "lucid: __rs__7istreamFRs" "istream::operator>>(short &)"
+ test_demangling_exact "lucid: __rs__FR7istreamR7complex" "operator>>(istream &, complex &)"
+ test_demangling "lucid: __vc__3fooFR3foo" "foo::operator\\\[\\\]\\(foo &\\)"
+ test_demangling_exact "lucid: __vtbl__10istrstream" "istrstream virtual table"
+ test_demangling_exact "lucid: __vtbl__17ostream__iostream__19iostream_withassign" "iostream_withassign::ostream__iostream virtual table"
+
+ test_demangling_exact "lucid: __vtbl__3ios" "ios virtual table"
+ test_demangling_exact "lucid: __vtbl__3ios__13strstreambase" "strstreambase::ios virtual table"
+
+ # GDB 930414 demangles this as t_cc_main_ (obviously wrong).
+ # GDB 930701 gets into an infinite loop.
+ # GDB 930727 says "Can't demangle".
+ # What is the correct demangling? FIXME.
+ setup_xfail "*-*-*"
+ test_demangling_exact "lucid: __vtbl__3foo__vt_cc_main_" ""
+
+ test_demangling_exact "lucid: abs__F7complex" "abs(complex)"
+ test_demangling_exact "lucid: allocate__9streambufFv" "streambuf::allocate(void)"
+ test_demangling_exact "lucid: attach__11fstreambaseFi" "fstreambase::attach(int)"
+ test_demangling_exact "lucid: bitalloc__3iosSFv" "ios::bitalloc(void) static"
+ test_demangling_exact "lucid: chr__FiT1" "chr(int, int)"
+ test_demangling_exact "lucid: complex_error__FR11c_exception" "complex_error(c_exception &)"
+ test_demangling_exact "lucid: complexfunc2__FPFPc_i" "complexfunc2(int (*)(char *))"
+ test_demangling_exact "lucid: complexfunc3__FPFPFPl_s_i" "complexfunc3(int (*)(short (*)(long *)))"
+
+ test_demangling_exact "lucid: complexfunc4__FPFPFPc_s_i" "complexfunc4(int (*)(short (*)(char *)))"
+ test_demangling_exact "lucid: complexfunc5__FPFPc_PFl_i" "complexfunc5(int (*(*)(char *))(long))"
+ test_demangling_exact "lucid: complexfunc6__FPFPi_PFl_i" "complexfunc6(int (*(*)(int *))(long))"
+ test_demangling_exact "lucid: complexfunc7__FPFPFPc_i_PFl_i" "complexfunc7(int (*(*)(int (*)(char *)))(long))"
+ test_demangling_exact "lucid: complicated_put__7ostreamFc" "ostream::complicated_put(char)"
+ test_demangling_exact "lucid: conv10__FlPc" "conv10(long, char *)"
+ test_demangling_exact "lucid: conv16__FUlPc" "conv16(unsigned long, char *)"
+ test_demangling_exact "lucid: dec__FR3ios" "dec(ios &)"
+ test_demangling_exact "lucid: dec__Fli" "dec(long, int)"
+ test_demangling_exact "lucid: dofield__FP7ostreamPciT2T3" "dofield(ostream *, char *, int, char *, int)"
+
+ test_demangling_exact "lucid: flags__3iosFl" "ios::flags(long)"
+ test_demangling_exact "lucid: flags__3iosFv" "ios::flags(void)"
+ test_demangling_exact "lucid: foo__FiN31" "foo(int, int, int, int)"
+ test_demangling_exact "lucid: foo__FiR3fooT1T2T1T2" "foo(int, foo &, int, foo &, int, foo &)"
+ test_demangling_exact "lucid: foo___3barFl" "bar::foo_(long)"
+ test_demangling "lucid: form__FPCce" "form\[(\]+(const char|char const) \[*\]+,...\[)\]+"
+ test_demangling_exact "lucid: get__7istreamFPcic" "istream::get(char *, int, char)"
+ test_demangling_exact "lucid: get__7istreamFR9streambufc" "istream::get(streambuf &, char)"
+ test_demangling_exact "lucid: get_complicated__7istreamFRUc" "istream::get_complicated(unsigned char &)"
+ test_demangling_exact "lucid: get_complicated__7istreamFRc" "istream::get_complicated(char &)"
+ test_demangling_exact "lucid: getline__7istreamFPUcic" "istream::getline(unsigned char *, int, char)"
+ test_demangling_exact "lucid: getline__7istreamFPcic" "istream::getline(char *, int, char)"
+
+ test_demangling_exact "lucid: ignore__7istreamFiT1" "istream::ignore(int, int)"
+ test_demangling_exact "lucid: init__12strstreambufFPciT1" "strstreambuf::init(char *, int, char *)"
+ test_demangling_exact "lucid: init__3iosFP9streambuf" "ios::init(streambuf *)"
+ test_demangling_exact "lucid: initcount__13Iostream_init" "Iostream_init::initcount"
+ test_demangling_exact "lucid: ipfx__7istreamFi" "istream::ipfx(int)"
+ test_demangling_exact "lucid: ls_complicated__7ostreamFUc" "ostream::ls_complicated(unsigned char)"
+ test_demangling_exact "lucid: ls_complicated__7ostreamFc" "ostream::ls_complicated(char)"
+ test_demangling "lucid: open__11fstreambaseFPCciT2" \
+ "fstreambase::open\[(\]+(const char|char const) \[*\]+, int, int\[)\]+"
+ test_demangling "lucid: open__7filebufFPCciT2" \
+ "filebuf::open\[(\]+(const char|char const) \[*\]+, int, int\[)\]+"
+
+ test_demangling_exact "lucid: overload1arg__FSc" "overload1arg(signed char)"
+ test_demangling_exact "lucid: overload1arg__FUc" "overload1arg(unsigned char)"
+ test_demangling_exact "lucid: overload1arg__FUi" "overload1arg(unsigned int)"
+ test_demangling_exact "lucid: overload1arg__FUl" "overload1arg(unsigned long)"
+ test_demangling_exact "lucid: overload1arg__FUs" "overload1arg(unsigned short)"
+ test_demangling_exact "lucid: overload1arg__Fc" "overload1arg(char)"
+ test_demangling_exact "lucid: overload1arg__Fd" "overload1arg(double)"
+ test_demangling_exact "lucid: overload1arg__Ff" "overload1arg(float)"
+ test_demangling_exact "lucid: overload1arg__Fi" "overload1arg(int)"
+ test_demangling_exact "lucid: overload1arg__Fl" "overload1arg(long)"
+ test_demangling_exact "lucid: overload1arg__Fs" "overload1arg(short)"
+ test_demangling_exact "lucid: overload1arg__Fv" "overload1arg(void)"
+ test_demangling_exact "lucid: overloadargs__FiN21" "overloadargs(int, int, int)"
+ test_demangling_exact "lucid: overloadargs__FiN31" "overloadargs(int, int, int, int)"
+ test_demangling_exact "lucid: overloadargs__FiN41" "overloadargs(int, int, int, int, int)"
+ test_demangling_exact "lucid: overloadargs__FiN51" "overloadargs(int, int, int, int, int, int)"
+ test_demangling_exact "lucid: overloadargs__FiN61" "overloadargs(int, int, int, int, int, int, int)"
+
+ test_demangling_exact "lucid: overloadargs__FiN71" "overloadargs(int, int, int, int, int, int, int, int)"
+ test_demangling_exact "lucid: overloadargs__FiN81" "overloadargs(int, int, int, int, int, int, int, int, int)"
+ test_demangling_exact "lucid: overloadargs__FiN91" "overloadargs(int, int, int, int, int, int, int, int, int, int)"
+ test_demangling_exact "lucid: overloadargs__FiN91N11" "overloadargs(int, int, int, int, int, int, int, int, int, int, int)"
+ test_demangling_exact "lucid: overloadargs__FiT1" "overloadargs(int, int)"
+ test_demangling_exact "lucid: polar__FdT1" "polar(double, double)"
+ test_demangling_exact "lucid: pow__F7complexT1" "pow(complex, complex)"
+ test_demangling_exact "lucid: pow__F7complexd" "pow(complex, double)"
+ test_demangling_exact "lucid: pow__F7complexi" "pow(complex, int)"
+ test_demangling_exact "lucid: pow__Fd7complex" "pow(double, complex)"
+ test_demangling_exact "lucid: pstart__FPciT2" "pstart(char *, int, int)"
+ test_demangling_exact "lucid: put__7ostreamFc" "ostream::put(char)"
+
+ test_demangling_exact "lucid: read__7istreamFPci" "istream::read(char *, int)"
+ test_demangling_exact "lucid: resetiosflags__FR3iosl" "resetiosflags(ios &, long)"
+ test_demangling_exact "lucid: restore_errno__FRi" "restore_errno(int &)"
+ test_demangling_exact "lucid: rs_complicated__7istreamFRUc" "istream::rs_complicated(unsigned char &)"
+ test_demangling_exact "lucid: rs_complicated__7istreamFRc" "istream::rs_complicated(char &)"
+ test_demangling_exact "lucid: seekg__7istreamFl8seek_dir" "istream::seekg(long, seek_dir)"
+ test_demangling_exact "lucid: seekoff__12strstreambufFl8seek_diri" "strstreambuf::seekoff(long, seek_dir, int)"
+ test_demangling_exact "lucid: seekoff__9streambufFlQ2_3ios12ios_seek_diri" "streambuf::seekoff(long, ios::ios_seek_dir, int)"
+ test_demangling_exact "lucid: seekpos__9streambufFli" "streambuf::seekpos(long, int)"
+ test_demangling_exact "lucid: set_new_handler__FPFv_v" "set_new_handler(void (*)(void))"
+ test_demangling_exact "lucid: setb__9streambufFPcT1i" "streambuf::setb(char *, char *, int)"
+
+ test_demangling_exact "lucid: setb__FR3iosi" "setb(ios &, int)"
+ test_demangling_exact "lucid: setbuf__11fstreambaseFPci" "fstreambase::setbuf(char *, int)"
+ test_demangling_exact "lucid: setbuf__9streambufFPUci" "streambuf::setbuf(unsigned char *, int)"
+ test_demangling_exact "lucid: setbuf__9streambufFPciT2" "streambuf::setbuf(char *, int, int)"
+ test_demangling_exact "lucid: setf__3iosFlT1" "ios::setf(long, long)"
+ test_demangling_exact "lucid: setfill__FR3iosi" "setfill(ios &, int)"
+ test_demangling_exact "lucid: setg__9streambufFPcN21" "streambuf::setg(char *, char *, char *)"
+ test_demangling_exact "lucid: setp__9streambufFPcT1" "streambuf::setp(char *, char *)"
+
+ test_demangling "lucid: sputn__9streambufFPCci" \
+ "streambuf::sputn\[(\]+(const char|char const) \[*\]+, int\[)\]+"
+ test_demangling "lucid: str__FPCci" \
+ "str\[(\]+(const char|char const) \[*\]+, int\[)\]+"
+ test_demangling_exact "lucid: tie__3iosFP7ostream" "ios::tie(ostream *)"
+ test_demangling_exact "lucid: uconv10__FUlPc" "uconv10(unsigned long, char *)"
+
+ test_demangling "lucid: write__7ostreamFPCci" \
+ "ostream::write\[(\]+(const char|char const) \[*\]+, int\[)\]+"
+ test_demangling_exact "lucid: xget__7istreamFPc" "istream::xget(char *)"
+ test_demangling_exact "lucid: xsgetn__9streambufFPci" "streambuf::xsgetn(char *, int)"
+ test_demangling "lucid: xsputn__9streambufFPCci" \
+ "streambuf::xsputn\[(\]+(const char|char const) \[*\]+, int\[)\]+"
+
+ test_demangling_exact "lucid: _Utf390_1__1_9223372036854775807__9223372036854775" \
+ "Can't demangle \"_Utf390_1__1_9223372036854775807__9223372036854775\""
+}
+
+#
+# Test arm style name demangling
+#
+
+proc test_arm_style_demangling {} {
+ test_demangling_exact "arm: __dt__21T5__pt__11_PFiPPdPv_iFv" "T5<int (*)(int, double **, void *)>::~T5(void)"
+
+ test_demangling_exact "arm: __ct__1cFi" "c::c(int)"
+
+ test_demangling_exact "arm: __dt__11T5__pt__2_iFv" "T5<int>::~T5(void)"
+
+ test_demangling_exact "arm: __dt__11T5__pt__2_cFv" "T5<char>::~T5(void)"
+
+ test_demangling_exact "arm: __ct__2T2Fi" "T2::T2(int)"
+ test_demangling_exact "arm: __dt__2T1Fv" "T1::~T1(void)"
+
+ test_demangling_exact "arm: __dt__12T5__pt__3_1xFv" "T5<x>::~T5(void)"
+
+ test_demangling_exact "arm: __dt__17T5__pt__8_PFcPv_iFv" "T5<int (*)(char, void *)>::~T5(void)"
+
+ test_demangling "arm: g__FP1cPC1cT1" \
+ "g\[(\]+c *\[*\]+, (const c|c const) *\[*\]+, c *\[*\]+\[)\]+"
+ test_demangling "arm: g__FPUlPCUlT1" \
+ "g\[(\]+unsigned long \[*\]+, (const unsigned long|unsigned long const) \[*\]+, unsigned long \[*\]+\[)\]+"
+ test_demangling "arm: g__FPUiPCUiT1" \
+ "g\[(\]+unsigned int \[*\]+, (const unsigned int|unsigned int const) \[*\]+, unsigned int \[*\]+\[)\]+"
+ test_demangling "arm: g__FPUsPCUsT1" \
+ "g\[(\]+unsigned short \[*\]+, (const unsigned short|unsigned short const) \[*\]+, unsigned short \[*\]+\[)\]+"
+ test_demangling "arm: g__FPUcPCUcT1" \
+ "g\[(\]+unsigned char \[*\]+, (const unsigned char|unsigned char const) \[*\]+, unsigned char \[*\]+\[)\]+"
+ test_demangling "arm: g__F1TPlPClT2" \
+ "g\[(\]+T, long \[*\]+, (const long|long const) \[*\]+, long \[*\]+\[)\]+"
+ test_demangling "arm: g__F1RRlRClT2" \
+ "g\[(\]+R, long &, (const long|long const) &, long &\[)\]+"
+ test_demangling "arm: g__F1TPiPCiT2" \
+ "g\[(\]+T, int \[*\]+, (const int|int const) \[*\]+, int \[*\]+\[)\]+"
+ test_demangling "arm: g__F1RRiRCiT2" \
+ "g\[(\]+R, int &, (const int|int const) &, int &\[)\]+"
+ test_demangling "arm: g__F1TPsPCsT2" \
+ "g\[(\]+T, short \[*\]+, (const short|short const) \[*\]+, short \[*\]+\[)\]+"
+ test_demangling "arm: g__F1RRsRCsT2" \
+ "g\[(\]+R, short &, (const short|short const) &, short &\[)\]+"
+ test_demangling "arm: g__F1TPcPCcT2" \
+ "g\[(\]+T, char \[*\]+, (const char|char const) \[*\]+, char \[*\]+\[)\]+"
+ test_demangling "arm: g__F1RRcRCcT2" \
+ "g\[(\]+R, char &, (const char|char const) &, char &\[)\]+"
+
+ test_demangling_exact "arm: __ct__21T5__pt__11_PFiPPdPv_iFi" "T5<int (*)(int, double **, void *)>::T5(int)"
+
+ test_demangling "arm: __gt__FRC2T2c" \
+ "operator>\[(\]+(const T2|T2 const) &, char\[)\]+"
+ test_demangling "arm: __ge__FRC2T2c" \
+ "operator>=\[(\]+(const T2|T2 const) &, char\[)\]+"
+ test_demangling "arm: __lt__FRC2T2c" \
+ "operator<\[(\]+(const T2|T2 const) &, char\[)\]+"
+
+ test_demangling "arm: __le__FRC2T2c" \
+ "operator<=\[(\]+(const T2|T2 const) &, char\[)\]+"
+ test_demangling "arm: __ne__FRC2T2c" \
+ "operator!=\[(\]+(const T2|T2 const) &, char\[)\]+"
+ test_demangling "arm: __eq__FRC2T2c" \
+ "operator==\[(\]+(const T2|T2 const) &, char\[)\]+"
+ test_demangling_exact "arm: __amd__FR2T2i" "operator%=(T2 &, int)"
+ test_demangling_exact "arm: __adv__FR2T2i" "operator/=(T2 &, int)"
+ test_demangling_exact "arm: __amu__FR2T2i" "operator*=(T2 &, int)"
+ test_demangling_exact "arm: __ami__FR2T2i" "operator-=(T2 &, int)"
+ test_demangling_exact "arm: __apl__FR2T2i" "operator+=(T2 &, int)"
+ test_demangling_exact "arm: __nw__2T1SFUi" "T1::operator new(unsigned int) static"
+ test_demangling_exact "arm: __dl__2T1SFPv" "T1::operator delete(void *) static"
+ test_demangling_exact "arm: put__2T7SFi" "T7::put(int) static"
+
+ test_demangling_exact "arm: __dl__12T5__pt__3_1xSFPv" "T5<x>::operator delete(void *) static"
+
+ test_demangling_exact "arm: h__FUc" "h(unsigned char)"
+ test_demangling_exact "arm: f__Fic" "f(int, char)"
+ test_demangling_exact "arm: h__FUi" "h(unsigned int)"
+ test_demangling_exact "arm: h__Fci" "h(char, int)"
+ test_demangling_exact "arm: h__FUl" "h(unsigned long)"
+ test_demangling_exact "arm: h__Fcl" "h(char, long)"
+ test_demangling_exact "arm: h__FUs" "h(unsigned short)"
+ test_demangling_exact "arm: h__Fcs" "h(char, short)"
+ test_demangling "arm: __amd__FR2T2RC2T2" \
+ "operator%=\[(\]+T2 &, (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: __adv__FR2T2RC2T2" \
+ "operator/=\[(\]+T2 &, (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: __amu__FR2T2RC2T2" \
+ "operator\[*\]+=\[(\]+T2 &, (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: __ami__FR2T2RC2T2" \
+ "operator-=\[(\]+T2 &, (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: __apl__FR2T2RC2T2" \
+ "operator\[+\]+=\[(\]+T2 &, (const T2|T2 const) &\[)\]+"
+
+ test_demangling "arm: g__F1SRPUlRPCUlT2" \
+ "g\[(\]+S, unsigned long \[*\]+&, (const unsigned long|unsigned long const) \[*\]+&, unsigned long \[*\]+&\[)\]+"
+ test_demangling "arm: g__F1SRPUiRPCUiT2" \
+ "g\[(\]+S, unsigned int \[*\]+&, (const unsigned int|unsigned int const) \[*\]+&, unsigned int \[*\]+&\[)\]+"
+ test_demangling "arm: g__F1SRPUsRPCUsT2" \
+ "g\[(\]+S, unsigned short \[*\]+&, (const unsigned short|unsigned short const) \[*\]+&, unsigned short \[*\]+&\[)\]+"
+ test_demangling "arm: g__F1SRPUcRPCUcT2" \
+ "g\[(\]+S, unsigned char \[*\]+&, (const unsigned char|unsigned char const) \[*\]+&, unsigned char \[*\]+&\[)\]+"
+ test_demangling "arm: g__F1T1SRPlRPClT3" \
+ "g\[(\]+T, S, long \[*\]+&, (const long|long const) \[*\]+&, long \[*\]+&\[)\]+"
+ test_demangling "arm: g__F1T1SRPiRPCiT3" \
+ "g\[(\]+T, S, int \[*\]+&, (const int|int const) \[*\]+&, int \[*\]+&\[)\]+"
+ test_demangling "arm: g__F1T1SRPcRPCcT3" \
+ "g\[(\]+T, S, char \[*\]+&, (const char|char const) \[*\]+&, char \[*\]+&\[)\]+"
+
+ test_demangling_exact "arm: X__12T5__pt__3_1x" "T5<x>::X"
+
+ test_demangling_exact "arm: __ct__11T5__pt__2_iFi" "T5<int>::T5(int)"
+
+ test_demangling_exact "arm: __ct__11T5__pt__2_cFi" "T5<char>::T5(int)"
+
+ test_demangling "arm: __gt__FRC2T2T1" \
+ "operator>\[(\]+(const T2|T2 const) &, (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: __ge__FRC2T2T1" \
+ "operator>=\[(\]+(const T2|T2 const) &, (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: __lt__FRC2T2T1" \
+ "operator<\[(\]+(const T2|T2 const) &, (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: __le__FRC2T2T1" \
+ "operator<=\[(\]+(const T2|T2 const) &, (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: __ne__FRC2T2T1" \
+ "operator!=\[(\]+(const T2|T2 const) &, (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: __eq__FRC2T2T1" \
+ "operator==\[(\]+(const T2|T2 const) &, (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: g__FcR1cRC1cT2" \
+ "g\[(\]+char, c &, (const c|c const) &, c &\[)\]+"
+ test_demangling "arm: g__FcRPdRPCdT2" \
+ "g\[(\]+char, double *\[*\]+&, (const double|double const) *\[*\]+&, double *\[*\]+&\[)\]+"
+ test_demangling "arm: g__FcRPfRPCfT2" \
+ "g\[(\]+char, float *\[*\]+&, (const float|float const) *\[*\]+&, float *\[*\]+&\[)\]+"
+ test_demangling_exact "arm: h__FcT1" "h(char, char)"
+ test_demangling_exact "arm: f__Ficd" "f(int, char, double)"
+ test_demangling "arm: g__F1T1SdRPsRPCsT4" \
+ "g\[(\]+T, S, double, short \[*\]+&, (const short|short const) \[*\]+&, short \[*\]+&\[)\]+"
+ test_demangling "arm: g__F1cC1cT1" \
+ "g\[(\]+c, (const c|c const), c\[)\]+"
+ test_demangling "arm: g__FPdPCdT1" \
+ "g\[(\]+double *\[*\]+, (const double|double const) *\[*\]+, double *\[*\]+\[)\]+"
+ test_demangling "arm: g__FPfPCfT1" \
+ "g\[(\]+float *\[*\]+, (const float|float const) *\[*\]+, float *\[*\]+\[)\]+"
+
+ test_demangling "arm: g__FUlCUlT1" \
+ "g\[(\]+unsigned long, (const unsigned long|unsigned long const), unsigned long\[)\]+"
+ test_demangling "arm: g__FPlPClT1" \
+ "g\[(\]+long \[*\]+, (const long|long const) \[*\]+, long \[*\]+\[)\]+"
+ test_demangling "arm: g__FUiCUiT1" \
+ "g\[(\]+unsigned int, (const unsigned int|unsigned int const), unsigned int\[)\]+"
+ test_demangling "arm: g__FPiPCiT1" \
+ "g\[(\]+int \[*\]+, (const int|int const) \[*\]+, int \[*\]+\[)\]+"
+ test_demangling "arm: g__FUsCUsT1" \
+ "g\[(\]+unsigned short, (const unsigned short|unsigned short const), unsigned short\[)\]+"
+ test_demangling "arm: g__FPsPCsT1" \
+ "g\[(\]+short \[*\]+, (const short|short const) \[*\]+, short \[*\]+\[)\]+"
+ test_demangling "arm: g__FUcCUcT1" \
+ "g\[(\]+unsigned char, (const unsigned char|unsigned char const), unsigned char\[)\]+"
+ test_demangling "arm: g__FPcPCcT1" \
+ "g\[(\]+char \[*\]+, (const char|char const) \[*\]+, char \[*\]+\[)\]+"
+ test_demangling "arm: g__F1TlClT2" \
+ "g\[(\]+T, long, (const long|long const), long\[)\]+"
+ test_demangling "arm: g__F1TiCiT2" \
+ "g\[(\]+T, int, (const int|int const), int\[)\]+"
+ test_demangling "arm: g__F1TsCsT2" \
+ "g\[(\]+T, short, (const short|short const), short\[)\]+"
+ test_demangling "arm: g__F1TcCcT2" \
+ "g\[(\]+T, char, (const char|char const), char\[)\]+"
+
+ test_demangling_exact "arm: __dl__17T5__pt__8_PFcPv_iSFPv" "T5<int (*)(char, void *)>::operator delete(void *) static"
+
+ test_demangling "arm: printf__FPCce" \
+ "printf\[(\]+(const char|char const) \[*\]+,...\[)\]+"
+
+ test_demangling_exact "arm: X__17T5__pt__8_PFcPv_i" "T5<int (*)(char, void *)>::X"
+
+ test_demangling_exact "arm: __ct__12T5__pt__3_1xFi" "T5<x>::T5(int)"
+
+ test_demangling "arm: g__F1SRUlRCUlT2" \
+ "g\[(\]+S, unsigned long &, (const unsigned long|unsigned long const) &, unsigned long &\[)\]+"
+ test_demangling "arm: g__F1SRPlRPClT2" \
+ "g\[(\]+S, long \[*\]+&, (const long|long const) \[*\]+&, long \[*\]+&\[)\]+"
+ test_demangling "arm: g__F1RRUiRCUiT2" \
+ "g\[(\]+R, unsigned int &, (const unsigned int|unsigned int const) &, unsigned int &\[)\]+"
+ test_demangling "arm: g__F1SRPiRPCiT2" \
+ "g\[(\]+S, int \[*\]+&, (const int|int const) \[*\]+&, int \[*\]+&\[)\]+"
+ test_demangling "arm: g__F1RRUsRCUsT2" \
+ "g\[(\]+R, unsigned short &, (const unsigned short|unsigned short const) &, unsigned short &\[)\]+"
+ test_demangling "arm: g__F1SRPsRPCsT2" \
+ "g\[(\]+S, short \[*\]+&, (const short|short const) \[*\]+&, short \[*\]+&\[)\]+"
+ test_demangling "arm: g__F1RRUcRCUcT2" \
+ "g\[(\]+R, unsigned char &, (const unsigned char|unsigned char const) &, unsigned char &\[)\]+"
+ test_demangling "arm: g__F1SRPcRPCcT2" \
+ "g\[(\]+S, char \[*\]+&, (const char|char const) \[*\]+&, char \[*\]+&\[)\]+"
+ test_demangling "arm: g__F1T1RRlRClT3" \
+ "g\[(\]+T, R, long &, (const long|long const) &, long &\[)\]+"
+ test_demangling "arm: g__F1T1RRiRCiT3" \
+ "g\[(\]+T, R, int &, (const int|int const) &, int &\[)\]+"
+ test_demangling "arm: g__F1T1RRsRCsT3" \
+ "g\[(\]+T, R, short &, (const short|short const) &, short &\[)\]+"
+ test_demangling "arm: g__F1T1RRcRCcT3" \
+ "g\[(\]+T, R, char &, (const char|char const) &, char &\[)\]+"
+
+ test_demangling_exact "arm: __dl__21T5__pt__11_PFiPPdPv_iSFPv" "T5<int (*)(int, double **, void *)>::operator delete(void *) static"
+
+ test_demangling_exact "arm: __std__foo" "global destructors keyed to foo"
+
+ test_demangling_exact "arm: __sti__bar" "global constructors keyed to bar"
+
+ test_demangling_exact "arm: f__FicdPcPFci_v" "f(int, char, double, char *, void (*)(char, int))"
+ test_demangling_exact "arm: f__FicdPcPFic_v" "f(int, char, double, char *, void (*)(int, char))"
+ test_demangling_exact "arm: get__2T7SFv" "T7::get(void) static"
+
+ test_demangling_exact "arm: X__21T5__pt__11_PFiPPdPv_i" "T5<int (*)(int, double **, void *)>::X"
+
+ test_demangling "arm: g__FcRdRCdT2" \
+ "g\[(\]+char, double &, (const double|double const) &, double &\[)\]+"
+ test_demangling "arm: g__FcRfRCfT2" \
+ "g\[(\]+char, float &, (const float|float const) &, float &\[)\]+"
+ test_demangling "arm: __md__FC2T2i" \
+ "operator%\[(\]+(const T2|T2 const), int\[)\]+"
+ test_demangling "arm: __dv__FC2T2i" \
+ "operator/\[(\]+(const T2|T2 const), int\[)\]+"
+ test_demangling "arm: __ml__FC2T2i" \
+ "operator\[*\]+\[(\]+(const T2|T2 const), int\[)\]+"
+ test_demangling "arm: __mi__FC2T2i" \
+ "operator-\[(\]+(const T2|T2 const), int\[)\]+"
+ test_demangling "arm: __pl__FC2T2i" \
+ "operator\[+\]+\[(\]+(const T2|T2 const), int\[)\]+"
+
+ test_demangling_exact "arm: __dl__11T5__pt__2_iSFPv" "T5<int>::operator delete(void *) static"
+
+ test_demangling_exact "arm: __dl__11T5__pt__2_cSFPv" "T5<char>::operator delete(void *) static"
+
+ test_demangling_exact "arm: h__Fc" "h(char)"
+ test_demangling_exact "arm: h__Fd" "h(double)"
+ test_demangling_exact "arm: h__Ff" "h(float)"
+ test_demangling_exact "arm: h__Fi" "h(int)"
+ test_demangling_exact "arm: f__Fi" "f(int)"
+ test_demangling_exact "arm: h__Fl" "h(long)"
+
+ test_demangling_exact "arm: h__Fs" "h(short)"
+ test_demangling "arm: __md__FC2T2RC2T2" \
+ "operator%\[(\]+(const T2|T2 const), (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: __dv__FC2T2RC2T2" \
+ "operator/\[(\]+(const T2|T2 const), (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: __ml__FC2T2RC2T2" \
+ "operator\[*\]+\[(\]+(const T2|T2 const), (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: __mi__FC2T2RC2T2" \
+ "operator-\[(\]+(const T2|T2 const), (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: __pl__FC2T2RC2T2" \
+ "operator\[+\]+\[(\]+(const T2|T2 const), (const T2|T2 const) &\[)\]+"
+ test_demangling "arm: g__FcRP1cRPC1cT2" \
+ "g\[(\]+char, c *\[*\]+&, (const c|c const) *\[*\]+&, c *\[*\]+&\[)\]+"
+
+ test_demangling_exact "arm: X__11T5__pt__2_c" "T5<char>::X"
+
+ test_demangling_exact "arm: X__11T5__pt__2_i" "T5<int>::X"
+
+ test_demangling "arm: g__FdCdT1" \
+ "g\[(\]+double, (const double|double const), double\[)\]+"
+ test_demangling "arm: g__FfCfT1" \
+ "g\[(\]+float, (const float|float const), float\[)\]+"
+ test_demangling "arm: g__FlClT1" \
+ "g\[(\]+long, (const long|long const), long\[)\]+"
+ test_demangling "arm: g__FiCiT1" \
+ "g\[(\]+int, (const int|int const), int\[)\]+"
+ test_demangling "arm: g__FsCsT1" \
+ "g\[(\]+short, (const short|short const), short\[)\]+"
+ test_demangling "arm: g__FcCcT1" \
+ "g\[(\]+char, (const char|char const), char\[)\]+"
+
+ test_demangling_exact "arm: __ct__17T5__pt__8_PFcPv_iFi" "T5<int (*)(char, void *)>::T5(int)"
+
+ test_demangling_exact "arm: f__FicdPc" "f(int, char, double, char *)"
+ test_demangling_exact "arm: __nw__FUi" "operator new(unsigned int)"
+ test_demangling_exact "arm: __ct__Q3_2T11a1bSFi" "T1::a::b::b(int) static"
+ test_demangling_exact "arm: __dt__Q3_2T11a1bSFi" "T1::a::b::~b(int) static"
+ test_demangling_exact "arm: put__Q3_2T11a1bSFi" "T1::a::b::put(int) static"
+ test_demangling_exact "arm: get__Q2_2T11aSFv" "T1::a::get(void) static"
+ test_demangling_exact "arm: put__2T1SFi" "T1::put(int) static"
+ test_demangling_exact "arm: put__Q5_2T11a1b1c1dSFi" "T1::a::b::c::d::put(int) static"
+ test_demangling_exact "arm: get__Q4_2T11a1b1cSFv" "T1::a::b::c::get(void) static"
+ test_demangling_exact "arm: put__Q2_2T11aSFi" "T1::a::put(int) static"
+ test_demangling_exact "arm: put__Q4_2T11a1b1cSFi" "T1::a::b::c::put(int) static"
+ test_demangling_exact "arm: get__Q3_2T11a1bSFv" "T1::a::b::get(void) static"
+ test_demangling_exact "arm: get__2T1SFv" "T1::get(void) static"
+ test_demangling_exact "arm: get__Q5_2T11a1b1c1dSFv" "T1::a::b::c::d::get(void) static"
+
+ test_demangling_exact "arm: __dt__11T1__pt__2_cFv" "T1<char>::~T1(void)"
+
+ test_demangling_exact "arm: __dt__12T1__pt__3_1tFv" "T1<t>::~T1(void)"
+
+ test_demangling_exact "arm: __dl__12T1__pt__3_1tSFPv" "T1<t>::operator delete(void *) static"
+
+ test_demangling_exact "arm: __ct__11T1__pt__2_cFi" "T1<char>::T1(int)"
+
+ test_demangling_exact "arm: __ct__11T1__pt__2_cFv" "T1<char>::T1(void)"
+
+ test_demangling_exact "arm: __ct__12T1__pt__3_1tFi" "T1<t>::T1(int)"
+
+ test_demangling_exact "arm: __ct__12T1__pt__3_1tFv" "T1<t>::T1(void)"
+
+ test_demangling_exact "arm: __dl__11T1__pt__2_cSFPv" "T1<char>::operator delete(void *) static"
+
+ test_demangling_exact "arm: bar__3fooFPv" "foo::bar(void *)"
+ test_demangling "arm: bar__3fooFPCv" \
+ "foo::bar\[(\]+(const void|void const) *\[*\]+\[)\]+"
+ test_demangling_exact "arm: bar__3fooCFPv" "foo::bar(void *) const"
+ test_demangling "arm: bar__3fooCFPCv" \
+ "foo::bar\[(\]+(const void|void const) *\[*\]+\[)\]+ const"
+ test_demangling_exact "arm: __eq__3fooFR3foo" "foo::operator==(foo &)"
+ test_demangling "arm: __eq__3fooFRC3foo" \
+ "foo::operator==\[(\]+(const foo|foo const) &\[)\]+"
+ test_demangling_exact "arm: __eq__3fooCFR3foo" "foo::operator==(foo &) const"
+ test_demangling "arm: __eq__3fooCFRC3foo" \
+ "foo::operator==\[(\]+(const foo|foo const) &\[)\]+ const"
+
+ test_demangling_exact "arm: elem__15vector__pt__2_dFi" "vector<double>::elem(int)"
+
+ test_demangling_exact "arm: elem__15vector__pt__2_iFi" "vector<int>::elem(int)"
+
+ test_demangling_exact "arm: __ct__15vector__pt__2_dFi" "vector<double>::vector(int)"
+
+ test_demangling_exact "arm: __ct__15vector__pt__2_iFi" "vector<int>::vector(int)"
+
+ test_demangling_exact "arm: __ct__25DListNode__pt__9_R6RLabelFR6RLabelP25DListNode__pt__9_R6RLabelT2" \
+ "DListNode<RLabel &>::DListNode(RLabel &, DListNode<RLabel &> *, DListNode<RLabel &> *)"
+
+ test_demangling_exact "arm: bar__3fooFiT16FooBar" "foo::bar(int, int, FooBar)"
+
+ test_demangling_exact "arm: bar__3fooFPiN51PdN37PcN211T1iN215" \
+ "foo::bar(int *, int *, int *, int *, int *, int *, double *, double *, double *, double *, char *, char *, char *, int *, int, int, int)"
+
+ test_demangling_exact "arm: _Utf390_1__1_9223372036854775807__9223372036854775" \
+ "Can't demangle \"_Utf390_1__1_9223372036854775807__9223372036854775\""
+}
+
+proc test_hp_style_demangling {} {
+
+ # HP aCC mangling style is based on ARM for all the basic stuff,
+ # so first we use some of the ARM tests here. Later we have HP-specific
+ # tests.
+
+ test_demangling "hp: g__FP1cPC1cT1" \
+ "g\[(\]+c *\[*\]+, (const c|c const) *\[*\]+, c *\[*\]+\[)\]+"
+ test_demangling "hp: g__FPUlPCUlT1" \
+ "g\[(\]+unsigned long \[*\]+, (const unsigned long|unsigned long const) \[*\]+, unsigned long \[*\]+\[)\]+"
+ test_demangling "hp: g__FPUiPCUiT1" \
+ "g\[(\]+unsigned int \[*\]+, (const unsigned int|unsigned int const) \[*\]+, unsigned int \[*\]+\[)\]+"
+ test_demangling "hp: g__FPUsPCUsT1" \
+ "g\[(\]+unsigned short \[*\]+, (const unsigned short|unsigned short const) \[*\]+, unsigned short \[*\]+\[)\]+"
+ test_demangling "hp: g__FPUcPCUcT1" \
+ "g\[(\]+unsigned char \[*\]+, (const unsigned char|unsigned char const) \[*\]+, unsigned char \[*\]+\[)\]+"
+ test_demangling "hp: g__F1TPlPClT2" \
+ "g\[(\]+T, long \[*\]+, (const long|long const) \[*\]+, long \[*\]+\[)\]+"
+ test_demangling "hp: g__F1RRlRClT2" \
+ "g\[(\]+R, long &, (const long|long const) &, long &\[)\]+"
+ test_demangling "hp: g__F1TPiPCiT2" \
+ "g\[(\]+T, int \[*\]+, (const int|int const) \[*\]+, int \[*\]+\[)\]+"
+ test_demangling "hp: g__F1RRiRCiT2" \
+ "g\[(\]+R, int &, (const int|int const) &, int &\[)\]+"
+ test_demangling "hp: g__F1TPsPCsT2" \
+ "g\[(\]+T, short \[*\]+, (const short|short const) \[*\]+, short \[*\]+\[)\]+"
+ test_demangling "hp: g__F1RRsRCsT2" \
+ "g\[(\]+R, short &, (const short|short const) &, short &\[)\]+"
+ test_demangling "hp: g__F1TPcPCcT2" \
+ "g\[(\]+T, char \[*\]+, (const char|char const) \[*\]+, char \[*\]+\[)\]+"
+ test_demangling "hp: g__F1RRcRCcT2" \
+ "g\[(\]+R, char &, (const char|char const) &, char &\[)\]+"
+
+ test_demangling "hp: __gt__FRC2T2c" \
+ "operator>\[(\]+(const T2|T2 const) &, char\[)\]+"
+ test_demangling "hp: __ge__FRC2T2c" \
+ "operator>=\[(\]+(const T2|T2 const) &, char\[)\]+"
+ test_demangling "hp: __lt__FRC2T2c" \
+ "operator<\[(\]+(const T2|T2 const) &, char\[)\]+"
+
+ test_demangling "hp: __le__FRC2T2c" \
+ "operator<=\[(\]+(const T2|T2 const) &, char\[)\]+"
+ test_demangling "hp: __ne__FRC2T2c" \
+ "operator!=\[(\]+(const T2|T2 const) &, char\[)\]+"
+ test_demangling "hp: __eq__FRC2T2c" \
+ "operator==\[(\]+(const T2|T2 const) &, char\[)\]+"
+ test_demangling_exact "hp: __amd__FR2T2i" "operator%=(T2 &, int)"
+ test_demangling_exact "hp: __adv__FR2T2i" "operator/=(T2 &, int)"
+ test_demangling_exact "hp: __amu__FR2T2i" "operator*=(T2 &, int)"
+ test_demangling_exact "hp: __ami__FR2T2i" "operator-=(T2 &, int)"
+ test_demangling_exact "hp: __apl__FR2T2i" "operator+=(T2 &, int)"
+ test_demangling_exact "hp: __nw__2T1SFUi" "T1::operator new(unsigned int) static"
+ test_demangling_exact "hp: __dl__2T1SFPv" "T1::operator delete(void *) static"
+ test_demangling_exact "hp: put__2T7SFi" "T7::put(int) static"
+
+ test_demangling_exact "hp: h__FUc" "h(unsigned char)"
+ test_demangling_exact "hp: f__Fic" "f(int, char)"
+ test_demangling_exact "hp: h__FUi" "h(unsigned int)"
+ test_demangling_exact "hp: h__Fci" "h(char, int)"
+ test_demangling_exact "hp: h__FUl" "h(unsigned long)"
+ test_demangling_exact "hp: h__Fcl" "h(char, long)"
+ test_demangling_exact "hp: h__FUs" "h(unsigned short)"
+ test_demangling_exact "hp: h__Fcs" "h(char, short)"
+ test_demangling "hp: __amd__FR2T2RC2T2" \
+ "operator%=\[(\]+T2 &, (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: __adv__FR2T2RC2T2" \
+ "operator/=\[(\]+T2 &, (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: __amu__FR2T2RC2T2" \
+ "operator\[*\]+=\[(\]+T2 &, (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: __ami__FR2T2RC2T2" \
+ "operator-=\[(\]+T2 &, (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: __apl__FR2T2RC2T2" \
+ "operator\[+\]+=\[(\]+T2 &, (const T2|T2 const) &\[)\]+"
+
+ test_demangling "hp: g__F1SRPUlRPCUlT2" \
+ "g\[(\]+S, unsigned long \[*\]+&, (const unsigned long|unsigned long const) \[*\]+&, unsigned long \[*\]+&\[)\]+"
+ test_demangling "hp: g__F1SRPUiRPCUiT2" \
+ "g\[(\]+S, unsigned int \[*\]+&, (const unsigned int|unsigned int const) \[*\]+&, unsigned int \[*\]+&\[)\]+"
+ test_demangling "hp: g__F1SRPUsRPCUsT2" \
+ "g\[(\]+S, unsigned short \[*\]+&, (const unsigned short|unsigned short const) \[*\]+&, unsigned short \[*\]+&\[)\]+"
+ test_demangling "hp: g__F1SRPUcRPCUcT2" \
+ "g\[(\]+S, unsigned char \[*\]+&, (const unsigned char|unsigned char const) \[*\]+&, unsigned char \[*\]+&\[)\]+"
+ test_demangling "hp: g__F1T1SRPlRPClT3" \
+ "g\[(\]+T, S, long \[*\]+&, (const long|long const) \[*\]+&, long \[*\]+&\[)\]+"
+ test_demangling "hp: g__F1T1SRPiRPCiT3" \
+ "g\[(\]+T, S, int \[*\]+&, (const int|int const) \[*\]+&, int \[*\]+&\[)\]+"
+ test_demangling "hp: g__F1T1SRPcRPCcT3" \
+ "g\[(\]+T, S, char \[*\]+&, (const char|char const) \[*\]+&, char \[*\]+&\[)\]+"
+
+
+ test_demangling "hp: __gt__FRC2T2T1" \
+ "operator>\[(\]+(const T2|T2 const) &, (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: __ge__FRC2T2T1" \
+ "operator>=\[(\]+(const T2|T2 const) &, (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: __lt__FRC2T2T1" \
+ "operator<\[(\]+(const T2|T2 const) &, (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: __le__FRC2T2T1" \
+ "operator<=\[(\]+(const T2|T2 const) &, (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: __ne__FRC2T2T1" \
+ "operator!=\[(\]+(const T2|T2 const) &, (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: __eq__FRC2T2T1" \
+ "operator==\[(\]+(const T2|T2 const) &, (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: g__FcR1cRC1cT2" \
+ "g\[(\]+char, c &, (const c|c const) &, c &\[)\]+"
+ test_demangling "hp: g__FcRPdRPCdT2" \
+ "g\[(\]+char, double *\[*\]+&, (const double|double const) *\[*\]+&, double *\[*\]+&\[)\]+"
+ test_demangling "hp: g__FcRPfRPCfT2" \
+ "g\[(\]+char, float *\[*\]+&, (const float|float const) *\[*\]+&, float *\[*\]+&\[)\]+"
+ test_demangling_exact "hp: h__FcT1" "h(char, char)"
+ test_demangling_exact "hp: f__Ficd" "f(int, char, double)"
+ test_demangling "hp: g__F1T1SdRPsRPCsT4" \
+ "g\[(\]+T, S, double, short \[*\]+&, (const short|short const) \[*\]+&, short \[*\]+&\[)\]+"
+ test_demangling "hp: g__F1cC1cT1" \
+ "g\[(\]+c, (const c|c const), c\[)\]+"
+ test_demangling "hp: g__FPdPCdT1" \
+ "g\[(\]+double *\[*\]+, (const double|double const) *\[*\]+, double *\[*\]+\[)\]+"
+ test_demangling "hp: g__FPfPCfT1" \
+ "g\[(\]+float *\[*\]+, (const float|float const) *\[*\]+, float *\[*\]+\[)\]+"
+
+ test_demangling "hp: g__FUlCUlT1" \
+ "g\[(\]+unsigned long, (const unsigned long|unsigned long const), unsigned long\[)\]+"
+ test_demangling "hp: g__FPlPClT1" \
+ "g\[(\]+long \[*\]+, (const long|long const) \[*\]+, long \[*\]+\[)\]+"
+ test_demangling "hp: g__FUiCUiT1" \
+ "g\[(\]+unsigned int, (const unsigned int|unsigned int const), unsigned int\[)\]+"
+ test_demangling "hp: g__FPiPCiT1" \
+ "g\[(\]+int \[*\]+, (const int|int const) \[*\]+, int \[*\]+\[)\]+"
+ test_demangling "hp: g__FUsCUsT1" \
+ "g\[(\]+unsigned short, (const unsigned short|unsigned short const), unsigned short\[)\]+"
+ test_demangling "hp: g__FPsPCsT1" \
+ "g\[(\]+short \[*\]+, (const short|short const) \[*\]+, short \[*\]+\[)\]+"
+ test_demangling "hp: g__FUcCUcT1" \
+ "g\[(\]+unsigned char, (const unsigned char|unsigned char const), unsigned char\[)\]+"
+ test_demangling "hp: g__FPcPCcT1" \
+ "g\[(\]+char \[*\]+, (const char|char const) \[*\]+, char \[*\]+\[)\]+"
+ test_demangling "hp: g__F1TlClT2" \
+ "g\[(\]+T, long, (const long|long const), long\[)\]+"
+ test_demangling "hp: g__F1TiCiT2" \
+ "g\[(\]+T, int, (const int|int const), int\[)\]+"
+ test_demangling "hp: g__F1TsCsT2" \
+ "g\[(\]+T, short, (const short|short const), short\[)\]+"
+ test_demangling "hp: g__F1TcCcT2" \
+ "g\[(\]+T, char, (const char|char const), char\[)\]+"
+
+ test_demangling "hp: printf__FPCce" \
+ "printf\[(\]+(const char|char const) \[*\]+,...\[)\]+"
+
+
+ test_demangling "hp: g__F1SRUlRCUlT2" \
+ "g\[(\]+S, unsigned long &, (const unsigned long|unsigned long const) &, unsigned long &\[)\]+"
+ test_demangling "hp: g__F1SRPlRPClT2" \
+ "g\[(\]+S, long \[*\]+&, (const long|long const) \[*\]+&, long \[*\]+&\[)\]+"
+ test_demangling "hp: g__F1RRUiRCUiT2" \
+ "g\[(\]+R, unsigned int &, (const unsigned int|unsigned int const) &, unsigned int &\[)\]+"
+ test_demangling "hp: g__F1SRPiRPCiT2" \
+ "g\[(\]+S, int \[*\]+&, (const int|int const) \[*\]+&, int \[*\]+&\[)\]+"
+ test_demangling "hp: g__F1RRUsRCUsT2" \
+ "g\[(\]+R, unsigned short &, (const unsigned short|unsigned short const) &, unsigned short &\[)\]+"
+ test_demangling "hp: g__F1SRPsRPCsT2" \
+ "g\[(\]+S, short \[*\]+&, (const short|short const) \[*\]+&, short \[*\]+&\[)\]+"
+ test_demangling "hp: g__F1RRUcRCUcT2" \
+ "g\[(\]+R, unsigned char &, (const unsigned char|unsigned char const) &, unsigned char &\[)\]+"
+ test_demangling "hp: g__F1SRPcRPCcT2" \
+ "g\[(\]+S, char \[*\]+&, (const char|char const) \[*\]+&, char \[*\]+&\[)\]+"
+ test_demangling "hp: g__F1T1RRlRClT3" \
+ "g\[(\]+T, R, long &, (const long|long const) &, long &\[)\]+"
+ test_demangling "hp: g__F1T1RRiRCiT3" \
+ "g\[(\]+T, R, int &, (const int|int const) &, int &\[)\]+"
+ test_demangling "hp: g__F1T1RRsRCsT3" \
+ "g\[(\]+T, R, short &, (const short|short const) &, short &\[)\]+"
+ test_demangling "hp: g__F1T1RRcRCcT3" \
+ "g\[(\]+T, R, char &, (const char|char const) &, char &\[)\]+"
+
+
+ test_demangling_exact "hp: f__FicdPcPFci_v" "f(int, char, double, char *, void (*)(char, int))"
+ test_demangling_exact "hp: f__FicdPcPFic_v" "f(int, char, double, char *, void (*)(int, char))"
+ test_demangling_exact "hp: get__2T7SFv" "T7::get(void) static"
+
+
+ test_demangling "hp: g__FcRdRCdT2" \
+ "g\[(\]+char, double &, (const double|double const) &, double &\[)\]+"
+ test_demangling "hp: g__FcRfRCfT2" \
+ "g\[(\]+char, float &, (const float|float const) &, float &\[)\]+"
+ test_demangling "hp: __md__FC2T2i" \
+ "operator%\[(\]+(const T2|T2 const), int\[)\]+"
+ test_demangling "hp: __dv__FC2T2i" \
+ "operator/\[(\]+(const T2|T2 const), int\[)\]+"
+ test_demangling "hp: __ml__FC2T2i" \
+ "operator\[*\]+\[(\]+(const T2|T2 const), int\[)\]+"
+ test_demangling "hp: __mi__FC2T2i" \
+ "operator-\[(\]+(const T2|T2 const), int\[)\]+"
+ test_demangling "hp: __pl__FC2T2i" \
+ "operator\[+\]+\[(\]+(const T2|T2 const), int\[)\]+"
+
+
+ test_demangling_exact "hp: h__Fc" "h(char)"
+ test_demangling_exact "hp: h__Fd" "h(double)"
+ test_demangling_exact "hp: h__Ff" "h(float)"
+ test_demangling_exact "hp: h__Fi" "h(int)"
+ test_demangling_exact "hp: f__Fi" "f(int)"
+ test_demangling_exact "hp: h__Fl" "h(long)"
+
+ test_demangling_exact "hp: h__Fs" "h(short)"
+ test_demangling "hp: __md__FC2T2RC2T2" \
+ "operator%\[(\]+(const T2|T2 const), (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: __dv__FC2T2RC2T2" \
+ "operator/\[(\]+(const T2|T2 const), (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: __ml__FC2T2RC2T2" \
+ "operator\[*\]+\[(\]+(const T2|T2 const), (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: __mi__FC2T2RC2T2" \
+ "operator-\[(\]+(const T2|T2 const), (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: __pl__FC2T2RC2T2" \
+ "operator\[+\]+\[(\]+(const T2|T2 const), (const T2|T2 const) &\[)\]+"
+ test_demangling "hp: g__FcRP1cRPC1cT2" \
+ "g\[(\]+char, c *\[*\]+&, (const c|c const) *\[*\]+&, c *\[*\]+&\[)\]+"
+
+
+ test_demangling "hp: g__FdCdT1" \
+ "g\[(\]+double, (const double|double const), double\[)\]+"
+ test_demangling "hp: g__FfCfT1" \
+ "g\[(\]+float, (const float|float const), float\[)\]+"
+ test_demangling "hp: g__FlClT1" \
+ "g\[(\]+long, (const long|long const), long\[)\]+"
+ test_demangling "hp: g__FiCiT1" \
+ "g\[(\]+int, (const int|int const), int\[)\]+"
+ test_demangling "hp: g__FsCsT1" \
+ "g\[(\]+short, (const short|short const), short\[)\]+"
+ test_demangling "hp: g__FcCcT1" \
+ "g\[(\]+char, (const char|char const), char\[)\]+"
+
+
+ test_demangling_exact "hp: f__FicdPc" "f(int, char, double, char *)"
+ test_demangling_exact "hp: __nw__FUi" "operator new(unsigned int)"
+ test_demangling_exact "hp: __ct__Q3_2T11a1bSFi" "T1::a::b::b(int) static"
+ test_demangling_exact "hp: __dt__Q3_2T11a1bSFi" "T1::a::b::~b(int) static"
+ test_demangling_exact "hp: put__Q3_2T11a1bSFi" "T1::a::b::put(int) static"
+ test_demangling_exact "hp: get__Q2_2T11aSFv" "T1::a::get(void) static"
+ test_demangling_exact "hp: put__2T1SFi" "T1::put(int) static"
+ test_demangling_exact "hp: put__Q5_2T11a1b1c1dSFi" "T1::a::b::c::d::put(int) static"
+ test_demangling_exact "hp: get__Q4_2T11a1b1cSFv" "T1::a::b::c::get(void) static"
+ test_demangling_exact "hp: put__Q2_2T11aSFi" "T1::a::put(int) static"
+ test_demangling_exact "hp: put__Q4_2T11a1b1cSFi" "T1::a::b::c::put(int) static"
+ test_demangling_exact "hp: get__Q3_2T11a1bSFv" "T1::a::b::get(void) static"
+ test_demangling_exact "hp: get__2T1SFv" "T1::get(void) static"
+ test_demangling_exact "hp: get__Q5_2T11a1b1c1dSFv" "T1::a::b::c::d::get(void) static"
+
+
+ test_demangling_exact "hp: bar__3fooFPv" "foo::bar(void *)"
+ test_demangling "hp: bar__3fooFPCv" \
+ "foo::bar\[(\]+(const void|void const) *\[*\]+\[)\]+"
+ test_demangling_exact "hp: bar__3fooCFPv" "foo::bar(void *) const"
+ test_demangling "hp: bar__3fooCFPCv" \
+ "foo::bar\[(\]+(const void|void const) *\[*\]+\[)\]+ const"
+ test_demangling_exact "hp: __eq__3fooFR3foo" "foo::operator==(foo &)"
+ test_demangling "hp: __eq__3fooFRC3foo" \
+ "foo::operator==\[(\]+(const foo|foo const) &\[)\]+"
+ test_demangling_exact "hp: __eq__3fooCFR3foo" "foo::operator==(foo &) const"
+ test_demangling "hp: __eq__3fooCFRC3foo" \
+ "foo::operator==\[(\]+(const foo|foo const) &\[)\]+ const"
+
+ test_demangling_exact "hp: bar__3fooFiT16FooBar" "foo::bar(int, int, FooBar)"
+
+ test_demangling_exact "hp: bar__3fooFPiN51PdN37PcN211T1iN215" \
+ "foo::bar(int *, int *, int *, int *, int *, int *, double *, double *, double *, double *, char *, char *, char *, int *, int, int, int)"
+
+
+ # HP aCC specific tests. HP aCC demangling does not use __pt__ for
+ # template specifications. There are other differences as well.
+
+ test_demangling_exact "hp: __dt__2T5XTPFiPPdPv_i__Fv" "T5<int (*)(int, double **, void *)>::~T5(void)"
+
+ test_demangling_exact "hp: __ct__1cFi" "c::c(int)"
+
+ test_demangling_exact "hp: __dt__2T5XTi__Fv" "T5<int>::~T5(void)"
+
+ test_demangling_exact "hp: __dt__2T5XTc__Fv" "T5<char>::~T5(void)"
+
+ test_demangling_exact "hp: __ct__2T2Fi" "T2::T2(int)"
+ test_demangling_exact "hp: __dt__2T1Fv" "T1::~T1(void)"
+
+ test_demangling_exact "hp: __dt__2T5XT1x__Fv" "T5<x>::~T5(void)"
+
+ test_demangling_exact "hp: __dt__2T5XTPFcPv_i__Fv" "T5<int (*)(char, void *)>::~T5(void)"
+
+ test_demangling_exact "hp: __ct__2T5XTPFiPPdPv_i__Fi" "T5<int (*)(int, double **, void *)>::T5(int)"
+
+ test_demangling_exact "hp: __dl__2T5XT1x__SFPv" "T5<x>::operator delete(void *) static"
+
+ test_demangling_exact "hp: X__2T5XT1x" "T5<x>::X"
+
+ test_demangling_exact "hp: __ct__2T5XTi__Fi" "T5<int>::T5(int)"
+
+ test_demangling_exact "hp: __ct__2T5XTc__Fi" "T5<char>::T5(int)"
+
+ test_demangling_exact "hp: __dl__2T5XTPFcPv_i__SFPv" "T5<int (*)(char, void *)>::operator delete(void *) static"
+
+ test_demangling_exact "hp: X__2T5XTPFcPv_i" "T5<int (*)(char, void *)>::X"
+
+ test_demangling_exact "hp: __ct__2T5XT1x__Fi" "T5<x>::T5(int)"
+
+ test_demangling_exact "hp: __dl__2T5XTPFiPPdPv_i__SFPv" "T5<int (*)(int, double **, void *)>::operator delete(void *) static"
+ test_demangling_exact "hp: X__2T5XTPFiPPdPv_i" "T5<int (*)(int, double **, void *)>::X"
+
+ test_demangling_exact "hp: __dl__2T5XTi__SFPv" "T5<int>::operator delete(void *) static"
+
+ test_demangling_exact "hp: __dl__2T5XTc__SFPv" "T5<char>::operator delete(void *) static"
+
+ test_demangling_exact "hp: X__2T5XTc" "T5<char>::X"
+
+ test_demangling_exact "hp: X__2T5XTi" "T5<int>::X"
+
+ test_demangling_exact "hp: __ct__2T5XTPFcPv_i__Fi" "T5<int (*)(char, void *)>::T5(int)"
+
+ test_demangling_exact "hp: __dt__2T1XTc__Fv" "T1<char>::~T1(void)"
+
+ test_demangling_exact "hp: __dt__2T1XT1t__Fv" "T1<t>::~T1(void)"
+
+ test_demangling_exact "hp: __dl__2T1XT1t__SFPv" "T1<t>::operator delete(void *) static"
+
+ test_demangling_exact "hp: __ct__2T1XTc__Fi" "T1<char>::T1(int)"
+
+ test_demangling_exact "hp: __ct__2T1XTc__Fv" "T1<char>::T1(void)"
+
+ test_demangling_exact "hp: __ct__2T1XT1t__Fi" "T1<t>::T1(int)"
+
+ test_demangling_exact "hp: __ct__2T1XT1t__Fv" "T1<t>::T1(void)"
+
+ test_demangling_exact "hp: __dl__2T1XTc__SFPv" "T1<char>::operator delete(void *) static"
+
+ test_demangling_exact "hp: elem__6vectorXTd__Fi" "vector<double>::elem(int)"
+
+ test_demangling_exact "hp: elem__6vectorXTi__Fi" "vector<int>::elem(int)"
+
+ test_demangling_exact "hp: __ct__6vectorXTd__Fi" "vector<double>::vector(int)"
+
+ test_demangling_exact "hp: __ct__6vectorXTi__Fi" "vector<int>::vector(int)"
+
+ test_demangling_exact "hp: __ct__9DListNodeXTR6RLabel__FR6RLabelP9DListNodeXTR6RLabel_T2" \
+ "DListNode<RLabel &>::DListNode(RLabel &, DListNode<RLabel &> *, DListNode<RLabel &> *)"
+
+
+ # Absolute integer constants in template args
+
+ test_demangling_exact "hp: elem__6vectorXTiUP34__Fi" "vector<int,34U>::elem(int)"
+ test_demangling_exact "hp: elem__6vectorXUP2701Td__Fi" "vector<2701U,double>::elem(int)"
+ test_demangling_exact "hp: elem__6vectorXTiSP334__Fi" "vector<int,334>::elem(int)"
+ test_demangling_exact "hp: elem__6vectorXTiSN67__Fi" "vector<int,-67>::elem(int)"
+ test_demangling_exact "hp: elem__6vectorXTiSM__SCFPPd" "vector<int,-2147483648>::elem(double **) static const"
+ test_demangling_exact "hp: elem__6vectorXTiSN67UP4000TRs__Fi" "vector<int,-67,4000U,short &>::elem(int)"
+ test_demangling_exact "hp: elem__6vectorXTiSN67TRdTFPv_i__Fi" "vector<int,-67,double &,int (void *)>::elem(int)"
+ test_demangling_exact "hp: X__6vectorXTiSN67TdTPvUP5TRs" "vector<int,-67,double,void *,5U,short &>::X"
+
+ # Named constants in template args
+
+ test_demangling_exact "hp: elem__6vectorXTiA3foo__Fi" "vector<int,&foo>::elem(int)"
+ test_demangling_exact "hp: elem__6vectorXTiA3fooTPvA5Label__FiPPvT2" "vector<int,&foo,void *,&Label>::elem(int, void **, void **)"
+ test_demangling_exact "hp: elem__6vectorXTiSN42A3foo__Fi" "vector<int,-42,&foo>::elem(int)"
+
+ # Alternate entry points for functions
+
+ test_demangling_exact "hp: __ct__2T5XTPFcPv_i__Fi_2" "T5<int (*)(char, void *)>::T5(int)"
+ test_demangling_exact "hp: __ct__2T5XTPFcPv_i__Fi_19" "T5<int (*)(char, void *)>::T5(int)"
+ test_demangling_exact "hp: f__FicdPcPFci_v_34" "f(int, char, double, char *, void (*)(char, int))"
+
+
+ # Template partial specializations
+
+# FIXME! The # characters don't go through expect, and backslashes don't seem to work.
+# test_demangling_exact "hp: spec__13Spec<#1,#1.*>XTiTPi_FPi" "Spec<int,int *>::spec(int *)"
+# test_demangling_exact "hp: spec__16Spec<#1,#1.&,#1>XTiTRiTi_FPi" "Spec<int,int &, int>::spec(int *)"
+# Fake test -- replace # with %
+ test_demangling_exact "hp: spec__13Spec<%1,%1.*>XTiTPi_FPi" "Spec<int,int *>::spec(int *)"
+ test_demangling_exact "hp: spec__16Spec<%1,%1.&,%1>XTiTRiTi_FPi" "Spec<int,int &,int>::spec(int *)"
+
+ # Global template functions
+
+ test_demangling_exact "hp: add__XTc_FcT1" "add<char>(char, char)"
+ test_demangling_exact "hp: add__XTcSP9A5label_FcPPlT1" "add<char,9,&label>(char, long **, char)"
+ test_demangling_exact "hp: add__XTPfTFPd_f_FcT1" "add<float *,float (double *)>(char, char)"
+
+ # Template for template arg
+
+ test_demangling_exact "hp: unLink__12basic_stringXTcT18string_char_traitsXTc_T9allocator_Fv" "basic_string<char,string_char_traits<char>,allocator>::unLink(void)"
+
+ test_demangling_exact "hp: _Utf390_1__1_9223372036854775807__9223372036854775" \
+ "Can't demangle \"_Utf390_1__1_9223372036854775807__9223372036854775\""
+}
+
+
+proc catch_demangling_errors {command} {
+ if {[catch $command result]} {
+ puts "ERROR: demangle.exp: while running $command: $result"
+ }
+}
+
+# Test support for different demangling styles. Note that this does
+# not depend upon running the test program and does not depend upon
+# gdb being able to lookup any C++ symbols. It simply calls the
+# internal demangler with synthesized strings and tests the results.
+
+proc do_tests {} {
+ global prms_id
+ global bug_id
+ global subdir
+ global gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+
+ send_gdb "set language c++\n"
+ gdb_expect -re "$gdb_prompt $"
+ send_gdb "set width 0\n"
+ gdb_expect -re "$gdb_prompt $"
+
+ # Using catch_demangling_errors this way ensures that, if one of
+ # the functions raises a Tcl error, then it'll get reported, and
+ # the rest of the functions will still run.
+ catch_demangling_errors test_lucid_style_demangling
+ catch_demangling_errors test_gnu_style_demangling
+ catch_demangling_errors test_arm_style_demangling
+ catch_demangling_errors test_hp_style_demangling
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.c++/derivation.cc b/gdb/testsuite/gdb.c++/derivation.cc
new file mode 100644
index 00000000000..99efa7605a4
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/derivation.cc
@@ -0,0 +1,240 @@
+class A {
+public:
+ int a;
+ int aa;
+
+ A()
+ {
+ a=1;
+ aa=2;
+ }
+ int afoo();
+ int foo();
+
+};
+
+
+
+class B {
+public:
+ int b;
+ int bb;
+
+ B()
+ {
+ b=3;
+ bb=4;
+ }
+ int bfoo();
+ int foo();
+
+};
+
+
+
+class C {
+public:
+ int c;
+ int cc;
+
+ C()
+ {
+ c=5;
+ cc=6;
+ }
+ int cfoo();
+ int foo();
+
+};
+
+
+
+class D : private A, public B, protected C {
+public:
+ int d;
+ int dd;
+
+ D()
+ {
+ d =7;
+ dd=8;
+ }
+ int dfoo();
+ int foo();
+
+};
+
+
+class E : public A, B, protected C {
+public:
+ int e;
+ int ee;
+
+ E()
+ {
+ e =9;
+ ee=10;
+ }
+ int efoo();
+ int foo();
+
+};
+
+
+class F : A, public B, C {
+public:
+ int f;
+ int ff;
+
+ F()
+ {
+ f =11;
+ ff=12;
+ }
+ int ffoo();
+ int foo();
+
+};
+
+class G : private A, public B, protected C {
+public:
+ int g;
+ int gg;
+ int a;
+ int b;
+ int c;
+
+ G()
+ {
+ g =13;
+ gg =14;
+ a=15;
+ b=16;
+ c=17;
+
+ }
+ int gfoo();
+ int foo();
+
+};
+
+
+
+
+int A::afoo() {
+ return 1;
+}
+
+int B::bfoo() {
+ return 2;
+}
+
+int C::cfoo() {
+ return 3;
+}
+
+int D::dfoo() {
+ return 4;
+}
+
+int E::efoo() {
+ return 5;
+}
+
+int F::ffoo() {
+ return 6;
+}
+
+int G::gfoo() {
+ return 77;
+}
+
+int A::foo()
+{
+ return 7;
+
+}
+
+int B::foo()
+{
+ return 8;
+
+}
+
+int C::foo()
+{
+ return 9;
+
+}
+
+int D::foo()
+{
+ return 10;
+
+}
+
+int E::foo()
+{
+ return 11;
+
+}
+
+int F::foo()
+{
+ return 12;
+
+}
+
+int G::foo()
+{
+ return 13;
+
+}
+
+
+void marker1()
+{
+}
+
+
+int main(void)
+{
+
+ A a_instance;
+ B b_instance;
+ C c_instance;
+ D d_instance;
+ E e_instance;
+ F f_instance;
+ G g_instance;
+
+ #ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+ #endif
+
+
+ marker1();
+
+ a_instance.a = 20;
+ a_instance.aa = 21;
+ b_instance.b = 22;
+ b_instance.bb = 23;
+ c_instance.c = 24;
+ c_instance.cc = 25;
+ d_instance.d = 26;
+ d_instance.dd = 27;
+ e_instance.e = 28;
+ e_instance.ee =29;
+ f_instance.f =30;
+ f_instance.ff =31;
+
+
+
+
+ return 0;
+
+}
+
+
+
diff --git a/gdb/testsuite/gdb.c++/derivation.exp b/gdb/testsuite/gdb.c++/derivation.exp
new file mode 100644
index 00000000000..9128730bcd9
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/derivation.exp
@@ -0,0 +1,319 @@
+# Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Elena Zannoni (ezannoni@cygnus.com)
+
+# This file is part of the gdb testsuite
+#
+
+#
+# tests for inheritance, with several derivations types combinations (private,
+# public, protected)
+# classes have simple members and member functions.
+#
+
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "derivation"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+
+if [get_compiler_info ${binfile} "c++"] {
+ return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+if ![runto 'marker1'] then {
+ perror "couldn't run to marker1"
+ continue
+}
+
+gdb_test "up" ".*main.*" "up from marker1"
+
+
+
+send_gdb "print a_instance\n"
+gdb_expect {
+ -re ".\[0-9\]* = \{a = 1, aa = 2\}\r\n$gdb_prompt $" {
+ pass "print value of a_instance"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of a_instance" }
+ timeout { fail "(timeout) print value of a_instance" }
+ }
+
+
+send_gdb "ptype a_instance\n"
+gdb_expect {
+ -re "type = class A \{\r\n\[\t \]*public:\r\n\[\t \]*int a;\r\n\[\t \]*int aa;\[\r\n\t ]+A & operator=\\(A const ?&\\);\[\r\n\t ]+A\\((A const|const A) ?&\\);\[\r\n\t ]+A\\((void|)\\);\r\n\[\t \]*int afoo\\((void|)\\);\r\n\[\t \]*int foo\\((void|)\\);\r\n\}.*$gdb_prompt $" { pass "ptype a_instance (with synth ops)" }
+ -re "type = class A \{\r\n\[\t \]*public:\r\n\[\t \]*int a;\r\n\[\t \]*int aa;\[\r\n\t \]+A\\(void\\);\r\n\[\t \]*int afoo\\((void|)\\);\r\n\[\t \]*int foo\\((void|)\\);\r\n\}.*$gdb_prompt $" { pass "ptype a_instance (no synth ops)" }
+ -re ".*$gdb_prompt $" { fail "ptype a_instance" }
+ timeout { fail "(timeout) ptype a_instance" }
+}
+
+
+send_gdb "print d_instance\n"
+gdb_expect {
+ -re ".\[0-9\]* = \{<A> = \{a = 1, aa = 2\}, <B> = \{b = 3, bb = 4\}, <C> = \{c = 5, cc = 6\}, d = 7, dd = 8\}\r\n$gdb_prompt $" {
+ pass "print value of d_instance"
+ }
+ -re ".\[0-9\]* = \{<class A> = \{a = 1, aa = 2\}, <class B> = \{b = 3, bb = 4\}, <class C> = \{c = 5, cc = 6\}, d = 7, dd = 8\}\r\n$gdb_prompt $" {
+ pass "print value of d_instance"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of d_instance" }
+ timeout { fail "(timeout) print value of d_instance" }
+ }
+
+ if {$gcc_compiled} then {
+ send_gdb "ptype d_instance\n"
+ gdb_expect {
+ -re "type = class D : private A, public B, (protected|private) C \{\r\n\[\t \]*public:\r\n\[\t \]*int d;\r\n\[\t \]*int dd;\[\r\n\t ]+D & operator=\\(D const ?&\\);\[\r\n\t ]+D\\((D const|const D) ?&\\);\[\r\n\t \]+D\\((void|)\\);\r\n\[\t \]*int dfoo\\((void|)\\);\r\n\[\t \]*int foo\\((void|)\\);\r\n\}.*$gdb_prompt $" { pass "ptype d_instance" }
+ -re "type = class D : private A, public B, (protected|private) C \{\r\n\[\t \]*public:\r\n\[\t \]*int d;\r\n\[\t \]*int dd;\[\r\n\t ]+D & operator=\\(D const ?&\\);\[\r\n\t ]+D\\((D const|const D) ?&\\);\[\r\n\t \]+D\\((void|)\\);\r\n\[\t \]*int dfoo\\((void|)\\);\r\n\[\t \]*int foo\\((void|)\\);\r\n\}.*$gdb_prompt $" { pass "ptype d_instance" }
+ -re "type = class D : private A, public B, (protected|private) C \{\r\n\[\t \]*public:\r\n\[\t \]*int d;\r\n\[\t \]*int dd;\[\r\n\t \]+D\\(void\\);\r\n\[\t \]*int dfoo\\((void|)\\);\r\n\[\t \]*int foo\\((void|)\\);\r\n\}.*$gdb_prompt $" { pass "ptype d_instance" }
+ -re ".*$gdb_prompt $" { fail "ptype d_instance" }
+ timeout { fail "(timeout) ptype d_instance" }
+ }
+ } else {
+ send_gdb "ptype d_instance\n"
+ gdb_expect {
+ -re "type = class D : private A, public B, protected C \{\r\n\[\t \]*public:\r\n\[\t \]*int d;\r\n\[\t \]*int dd;\[\r\n\t \]+D\\(void\\);\r\n\[\t \]*int dfoo\\((void|)\\);\r\n\[\t \]*int foo\\((void|)\\);\r\n\}.*$gdb_prompt $" { pass "ptype d_instance" }
+ -re ".*$gdb_prompt $" { fail "ptype d_instance" }
+ timeout { fail "(timeout) ptype d_instance" }
+ }
+ }
+
+
+send_gdb "print e_instance\n"
+gdb_expect {
+ -re ".\[0-9\]* = \{<A> = \{a = 1, aa = 2\}, <B> = \{b = 3, bb = 4\}, <C> = \{c = 5, cc = 6\}, e = 9, ee = 10\}\r\n$gdb_prompt $" {
+ pass "print value of e_instance"
+ }
+ -re ".\[0-9\]* = \{<class A> = \{a = 1, aa = 2\}, <class B> = \{b = 3, bb = 4\}, <class C> = \{c = 5, cc = 6\}, e = 9, ee = 10\}\r\n$gdb_prompt $" {
+ pass "print value of e_instance"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of e_instance" }
+ timeout { fail "(timeout) print value of e_instance" }
+ }
+
+ if {$gcc_compiled} {
+ send_gdb "ptype e_instance\n"
+ gdb_expect {
+ -re "type = class E : public A, private B, (protected|private) C \{\r\n\[\t \]*public:\r\n\[\t \]*int e;\r\n\[\t \]*int ee;\[\r\n\t ]+E & operator=\\(E const ?&\\);\[\r\n\t ]+E\\((E const|const E) ?&\\);\[\r\n\t \]+E\\((void|)\\);\r\n\[\t \]*int efoo\\((void|)\\);\r\n\[\t \]*int foo\\((void|)\\);\r\n\}.*$gdb_prompt $" { pass "ptype e_instance" }
+ -re "type = class E : public A, private B, (protected|private) C \{\r\n\[\t \]*public:\r\n\[\t \]*int e;\r\n\[\t \]*int ee;\[\r\n\t \]+E\\((void|)\\);\r\n\[\t \]*int efoo\\((void|)\\);\r\n\[\t \]*int foo\\((void|)\\);\r\n\}.*$gdb_prompt $" { pass "ptype e_instance" }
+ -re ".*$gdb_prompt $" { fail "ptype e_instance" }
+ timeout { fail "(timeout) ptype e_instance" }
+ }
+ } else {
+ send_gdb "ptype e_instance\n"
+ gdb_expect {
+ -re "type = class E : public A, private B, protected C \{\r\n\[\t \]*public:\r\n\[\t \]*int e;\r\n\[\t \]*int ee;\[\r\n\t \]+E\\((void|)\\);\r\n\[\t \]*int efoo\\((void|)\\);\r\n\[\t \]*int foo\\((void|)\\);\r\n\}.*$gdb_prompt $" { pass "ptype e_instance" }
+ -re ".*$gdb_prompt $" { fail "ptype e_instance" }
+ timeout { fail "(timeout) ptype e_instance" }
+ }
+ }
+
+
+send_gdb "print f_instance\n"
+gdb_expect {
+ -re ".\[0-9\]* = \{<A> = \{a = 1, aa = 2\}, <B> = \{b = 3, bb = 4\}, <C> = \{c = 5, cc = 6\}, f = 11, ff = 12\}\r\n$gdb_prompt $" {
+ pass "print value of f_instance"
+ }
+ -re ".\[0-9\]* = \{<class A> = \{a = 1, aa = 2\}, <class B> = \{b = 3, bb = 4\}, <class C> = \{c = 5, cc = 6\}, f = 11, ff = 12\}\r\n$gdb_prompt $" {
+ pass "print value of f_instance"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of f_instance" }
+ timeout { fail "(timeout) print value of f_instance" }
+ }
+
+send_gdb "ptype f_instance\n"
+gdb_expect {
+ -re "type = class F : private A, public B, private C \{\r\n\[\t \]*public:\r\n\[\t \]*int f;\r\n\[\t \]*int ff;\[\r\n\t ]+F & operator=\\(F const ?&\\);\[\r\n\t ]+F\\((F const|const F) ?&\\);\[\r\n\t \]+F\\((void|)\\);\r\n\[\t \]*int ffoo\\((void|)\\);\r\n\[\t \]*int foo\\((void|)\\);\r\n\}.*$gdb_prompt $" { pass "ptype f_instance" }
+ -re "type = class F : private A, public B, private C \{\r\n\[\t \]*public:\r\n\[\t \]*int f;\r\n\[\t \]*int ff;\[\r\n\t \]+F\\((void|)\\);\r\n\[\t \]*int ffoo\\((void|)\\);\r\n\[\t \]*int foo\\((void|)\\);\r\n\}.*$gdb_prompt $" { pass "ptype f_instance" }
+ -re ".*$gdb_prompt $" { fail "ptype f_instance" }
+ timeout { fail "(timeout) ptype f_instance" }
+}
+
+
+
+send_gdb "print d_instance.a\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1.*$gdb_prompt $" {
+ pass "print value of d_instance.a"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of d_instance.a" }
+ timeout { fail "(timeout) print value of d_instance.a" }
+ }
+
+send_gdb "print d_instance.aa\n"
+gdb_expect {
+ -re ".\[0-9\]* = 2.*$gdb_prompt $" {
+ pass "print value of d_instance.aa"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of d_instance.aa" }
+ timeout { fail "(timeout) print value of d_instance.aa" }
+ }
+
+send_gdb "print d_instance.b\n"
+gdb_expect {
+ -re ".\[0-9\]* = 3.*$gdb_prompt $" {
+ pass "print value of d_instance.b"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of d_instance.b" }
+ timeout { fail "(timeout) print value of d_instance.b" }
+ }
+
+send_gdb "print d_instance.bb\n"
+gdb_expect {
+ -re ".\[0-9\]* = 4.*$gdb_prompt $" {
+ pass "print value of d_instance.bb"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of d_instance.bb" }
+ timeout { fail "(timeout) print value of d_instance.bb" }
+ }
+
+send_gdb "print d_instance.c\n"
+gdb_expect {
+ -re ".\[0-9\]* = 5.*$gdb_prompt $" {
+ pass "print value of d_instance.c"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of d_instance.c" }
+ timeout { fail "(timeout) print value of d_instance.c" }
+ }
+
+send_gdb "print d_instance.cc\n"
+gdb_expect {
+ -re ".\[0-9\]* = 6.*$gdb_prompt $" {
+ pass "print value of d_instance.cc"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of d_instance.cc" }
+ timeout { fail "(timeout) print value of d_instance.cc" }
+ }
+
+send_gdb "print d_instance.d\n"
+gdb_expect {
+ -re ".\[0-9\]* = 7.*$gdb_prompt $" {
+ pass "print value of d_instance.d"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of d_instance.d" }
+ timeout { fail "(timeout) print value of d_instance.d" }
+ }
+
+send_gdb "print d_instance.dd\n"
+gdb_expect {
+ -re ".\[0-9\]* = 8.*$gdb_prompt $" {
+ pass "print value of d_instance.dd"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of d_instance.dd" }
+ timeout { fail "(timeout) print value of d_instance.dd" }
+ }
+
+send_gdb "print g_instance.a\n"
+gdb_expect {
+ -re "warning.*$gdb_prompt $" {
+ # The compiler doesn't think this is ambiguous.
+ fail "print value of g_instance.a"
+ }
+ -re ".\[0-9\]* = 15.*$gdb_prompt $" {
+ pass "print value of g_instance.a"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of g_instance.a" }
+ timeout { fail "(timeout) print value of g_instance.a" }
+ }
+
+send_gdb "print g_instance.b\n"
+gdb_expect {
+ -re "warning.*$gdb_prompt $" {
+ # The compiler doesn't think this is ambiguous.
+ fail "print value of g_instance.b"
+ }
+ -re ".\[0-9\]* = 16.*$gdb_prompt $" {
+ pass "print value of g_instance.b"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of g_instance.b" }
+ timeout { fail "(timeout) print value of g_instance.b" }
+ }
+
+send_gdb "print g_instance.c\n"
+gdb_expect {
+ -re "warning.*$gdb_prompt $" {
+ # The compiler doesn't think this is ambiguous.
+ fail "print value of g_instance.c"
+ }
+ -re ".\[0-9\]* = 17.*$gdb_prompt $" {
+ pass "print value of g_instance.c"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of g_instance.c" }
+ timeout { fail "(timeout) print value of g_instance.c" }
+ }
+
+send_gdb "print g_instance.afoo()\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1.*$gdb_prompt $" {
+ pass "print value of g_instance.afoo()"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of g_instance.afoo()" }
+ timeout { fail "(timeout) print value of g_instance.afoo()" }
+ }
+
+send_gdb "print g_instance.bfoo()\n"
+gdb_expect {
+ -re ".\[0-9\]* = 2.*$gdb_prompt $" {
+ pass "print value of g_instance.bfoo()"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of g_instance.bfoo()" }
+ timeout { fail "(timeout) print value of g_instance.bfoo()" }
+ }
+
+send_gdb "print g_instance.cfoo()\n"
+gdb_expect {
+ -re ".\[0-9\]* = 3.*$gdb_prompt $" {
+ pass "print value of g_instance.cfoo()"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of g_instance.cfoo()" }
+ timeout { fail "(timeout) print value of g_instance.cfoo()" }
+ }
diff --git a/gdb/testsuite/gdb.c++/hang.H b/gdb/testsuite/gdb.c++/hang.H
new file mode 100644
index 00000000000..26fec8792ad
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/hang.H
@@ -0,0 +1,12 @@
+struct A
+{
+ struct B *b_ptr_in_a;
+};
+
+struct C
+{
+ struct B
+ {
+ int member_of_B_in_C;
+ };
+};
diff --git a/gdb/testsuite/gdb.c++/hang.exp b/gdb/testsuite/gdb.c++/hang.exp
new file mode 100644
index 00000000000..4c117a10744
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/hang.exp
@@ -0,0 +1,128 @@
+# Copyright (C) 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile hang
+set binfile ${objdir}/${subdir}/${testfile}
+
+foreach file {hang1 hang2 hang3} {
+ if {[gdb_compile "${srcdir}/${subdir}/${file}.C" "${file}.o" object {c++ debug}] != ""} {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+}
+
+if {[gdb_compile "hang1.o hang2.o hang3.o" ${binfile} executable {c++ debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+# As of May 1, 2002, GDB hangs trying to read the debug info for the
+# `hang2.o' compilation unit from the executable `hang', when compiled
+# by g++ 2.96 with STABS debugging info. Here's what's going on, as
+# best as I can tell.
+#
+# The definition of `struct A' in `hang.H' refers to `struct B' as an
+# incomplete type. The stabs declare type number (1,3) to be a cross-
+# reference type, `xsB:'.
+#
+# The definition of `struct C' contains a nested definition for
+# `struct B' --- or more properly, `struct C::B'. However, the stabs
+# fail to qualify the structure tag: it just looks like a definition
+# for `struct B'. I think this is a compiler bug, but perhaps GCC
+# doesn't emit qualified names for a reason.
+#
+# `hang.H' gets #included by both `hang1.C' and `hang2.C'. So the
+# stabs for `struct A', the incomplete `struct B', and `struct C'
+# appear in both hang1.o's and hang2.o's stabs.
+#
+# When those two files are linked together, since hang2.o appears
+# later in the command line, its #inclusion of `hang.H' gets replaced
+# with an N_EXCL stab, referring back to hang1.o's stabs for the
+# header file.
+#
+# When GDB builds psymtabs for the executable hang, it notes that
+# hang2.o's stabs contain an N_EXCL referring to a header that appears
+# in full in hang1.o's stabs. So hang2.o's psymtab lists a dependency
+# on hang1.o's psymtab.
+#
+# When the user types the command `print var_in_b', GDB scans the
+# psymtabs for a symbol by that name, and decides to read full symbols
+# for `hang2.o'.
+#
+# Since `hang2.o''s psymtab lists `hang1.o' as a dependency, GDB first
+# reads `hang1.o''s symbols. When GDB sees `(1,3)=xsB:', it creates a
+# type object for `struct B', sets its TYPE_FLAG_STUB flag, and
+# records it as type number `(1,3)'.
+#
+# When GDB finds the definition of `struct C::B', since the stabs
+# don't indicate that the type is nested within C, it treats it as
+# a definition of `struct B'.
+#
+# When GDB is finished reading `hang1.o''s symbols, it calls
+# `cleanup_undefined_types'. This function mistakes the definition of
+# `struct C::B' for a definition for `struct B', and overwrites the
+# incomplete type object for the real `struct B', using `memcpy'. Now
+# stabs type number `(1,3)' refers to this (incorrect) complete type.
+# Furthermore, the `memcpy' simply copies the original's `cv_type'
+# field to the target, giving the target a corrupt `cv_type' ring: the
+# chain does not point back to the target type.
+#
+# Having satisfied `hang2.o''s psymtab's dependencies, GDB begins to
+# read `hang2.o''s symbols. These contain the true definition for
+# `struct B', which refers to type number `(1,3)' as the type it's
+# defining. GDB looks up type `(1,3)', and finds the (incorrect)
+# complete type established by the call to `cleanup_undefined_types'
+# above. However, it doesn't notice that the type is already defined,
+# and passes it to `read_struct_type', which then writes the new
+# definition's size, field list, etc. into the type object which
+# already has those fields initialized. Adding insult to injury,
+# `read_struct_type' then calls `finish_cv_type'; since the `memcpy'
+# in `cleanup_undefined_types' corrupted the target type's `cv_type'
+# ring, `finish_cv_type' enters an infinite loop.
+
+# This checks that GDB recognizes when a structure is about to be
+# overwritten, and refuses, with a complaint.
+gdb_test "print var_in_b" " = 1729" "doesn't overwrite struct type"
+
+# This checks that cleanup_undefined_types doesn't create corrupt
+# cv_type chains. Note that var_in_hang3 does need to be declared in
+# a separate compilation unit, whose psymtab depends on hang1.o's
+# psymtab. Otherwise, GDB won't call cleanup_undefined_types (as it
+# finishes hang1.o's symbols) before it calls make_cv_type (while
+# reading hang3.o's symbols).
+#
+# The bug only happens when you compile with -gstabs+; Otherwise, GCC
+# won't include the `const' qualifier on `const_B_ptr' in `hang3.o''s
+# STABS, so GDB won't try to create a const variant of the smashed
+# struct type, and get caught by the corrupted cv_type chain.
+gdb_test "print var_in_hang3" " = 42" "doesn't corrupt cv_type chain"
diff --git a/gdb/testsuite/gdb.c++/hang1.C b/gdb/testsuite/gdb.c++/hang1.C
new file mode 100644
index 00000000000..4b04d77e68c
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/hang1.C
@@ -0,0 +1,3 @@
+#include "hang.H"
+
+int main (int argc, char **argv) { return 0; }
diff --git a/gdb/testsuite/gdb.c++/hang2.C b/gdb/testsuite/gdb.c++/hang2.C
new file mode 100644
index 00000000000..59732f87d63
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/hang2.C
@@ -0,0 +1,8 @@
+#include "hang.H"
+
+struct B
+{
+ int member_of_B;
+};
+
+int var_in_b = 1729;
diff --git a/gdb/testsuite/gdb.c++/hang3.C b/gdb/testsuite/gdb.c++/hang3.C
new file mode 100644
index 00000000000..92c82fa2441
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/hang3.C
@@ -0,0 +1,4 @@
+#include "hang.H"
+
+const struct B *const_B_ptr;
+int var_in_hang3 = 42;
diff --git a/gdb/testsuite/gdb.c++/inherit.exp b/gdb/testsuite/gdb.c++/inherit.exp
new file mode 100644
index 00000000000..286c27b09f3
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/inherit.exp
@@ -0,0 +1,1062 @@
+# Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+set ws "\[\r\n\t \]+"
+set nl "\[\r\n\]+"
+
+# The format of a g++ virtual base pointer.
+set vbptr "(_vb\[$.\]|__vb_)\[0-9\]?"
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if { [skip_cplus_tests] } { continue }
+
+# Note - create separate "inherit" executable from misc.cc
+
+set testfile "inherit"
+set srcfile misc.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+
+if [get_compiler_info ${binfile} "c++"] {
+ return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+#
+# Single inheritance, print individual members.
+#
+
+proc test_print_si_members {} {
+ # Print all members of g_A using fully qualified form.
+
+ gdb_test "print g_A.A::a" ".* = 1" "print g_A.A::a"
+
+ gdb_test "print g_A.A::x" ".* = 2" "print g_A.A::x"
+
+ # Print members of g_A using nonambiguous compact form.
+
+ gdb_test "print g_A.a" ".* = 1" "print g_A.a"
+
+ gdb_test "print g_A.x" ".* = 2" "print g_A.x"
+
+ # Print all members of g_B using fully qualified form.
+
+ gdb_test "print g_B.A::a" ".* = 3" "print g_B.A::a"
+
+ gdb_test "print g_B.A::x" ".* = 4" "print g_B.A::x"
+
+ gdb_test "print g_B.B::b" ".* = 5" "print g_B.B::b"
+
+ gdb_test "print g_B.B::x" ".* = 6" "print g_B.B::x"
+
+ # Print members of g_B using nonambiguous compact form.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_B.a" ".* = 3" "print g_B.a"
+
+ gdb_test "print g_B.b" ".* = 5" "print g_B.b"
+
+ gdb_test "print g_B.x" ".* = 6" "print g_B.x"
+
+ # Print all members of g_C using fully qualified form.
+
+ gdb_test "print g_C.A::a" ".* = 7" "print g_C.A::a"
+
+ gdb_test "print g_C.A::x" ".* = 8" "print g_C.A::x"
+
+ gdb_test "print g_C.C::c" ".* = 9" "print g_C.C::c"
+
+ gdb_test "print g_C.C::x" ".* = 10" "print g_C.C::x"
+
+ # Print members of g_C using nonambiguous compact form.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_C.a" ".* = 7" "print g_C.a"
+
+ gdb_test "print g_C.c" ".* = 9" "print g_C.c"
+
+ gdb_test "print g_C.x" ".* = 10" "print g_C.x"
+}
+
+#
+# Single inheritance, print type definitions.
+#
+
+proc test_ptype_si {} {
+ global gdb_prompt
+ global ws
+ global nl
+ global hp_aCC_compiler
+
+ # Print class A as a type.
+
+ send_gdb "ptype A\n"
+ gdb_expect {
+ -re "type = class A \{$nl.*\[ \]*int a;$nl\[ \]*int x;$nl.*\[ \]*\}$nl$gdb_prompt $" {
+ pass "ptype A (FIXME)"
+ }
+ -re "type = struct A \{$nl\[ \]*int a;$nl\[ \]*int x;$nl\[ \]*\}$nl$gdb_prompt $" {
+ setup_xfail "*-*-*"
+ fail "ptype A (FIXME)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype A" }
+ timeout { fail "ptype A (timeout)" ; return }
+ }
+
+ # Print class A as an explicit class.
+
+ send_gdb "ptype class A\n"
+ gdb_expect {
+ -re "type = class A \{$nl.*\[ \]*int a;$nl\[ \]*int x;$nl.*\[ \]*\}$nl$gdb_prompt $" {
+ pass "ptype class A (FIXME)"
+ }
+ -re "type = struct A \{$nl\[ \]*int a;$nl\[ \]*int x;$nl\[ \]*\}$nl$gdb_prompt $" {
+ if {!$hp_aCC_compiler} {setup_xfail "*-*-*"}
+ fail "ptype class A (FIXME)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype class A" }
+ timeout { fail "ptype class A (timeout)" ; return }
+ }
+
+ # Print type of an object of type A.
+
+ send_gdb "ptype g_A\n"
+ gdb_expect {
+ -re "type = class A \{$nl.*\[ \]*int a;$nl\[ \]*int x;$nl.*\[ \]*\}$nl$gdb_prompt $" {
+ pass "ptype g_A (FIXME)"
+ }
+ -re "type = struct A \{$nl\[ \]*int a;$nl\[ \]*int x;$nl\[ \]*\}$nl$gdb_prompt $" {
+ if {!$hp_aCC_compiler} {setup_xfail "*-*-*"}
+ fail "ptype g_A (FIXME)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype g_A" }
+ timeout { fail "ptype g_A (timeout)" ; return }
+ }
+
+ # Print class B as a type.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "ptype B" "type = class B : public A \{$nl\[ \]*public:$nl\[ \]*int b;$nl\[ \]*int x;$nl.*\}" "ptype B"
+
+ # Print class B as an explicit class.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "ptype class B" "type = class B : public A \{$nl\[ \]*public:$nl\[ \]*int b;$nl\[ \]*int x;$nl.*\}" "ptype class B"
+
+ # Print type of an object of type B.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "ptype g_B" "type = class B : public A \{$nl\[ \]*public:$nl\[ \]*int b;$nl\[ \]*int x;$nl.*\}" "ptype g_B"
+
+ # Print class C as a type.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "ptype C" "type = class C : public A \{$nl\[ \]*public:$nl\[ \]*int c;$nl\[ \]*int x;$nl.*\}" "ptype C"
+
+ # Print class C as an explicit class.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "ptype class C" "type = class C : public A \{$nl\[ \]*public:$nl\[ \]*int c;$nl\[ \]*int x;$nl.*\}" "ptype class C"
+
+ # Print type of an object of type g_C.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "ptype g_C" "type = class C : public A \{$nl\[ \]*public:$nl\[ \]*int c;$nl\[ \]*int x;$nl.*\}" "ptype g_C"
+
+ # gcc cygnus-2.3.3 (Q1) has this bug, but it was fixed as of
+ # cygnus-2.3.3-930417. PR 2819.
+ send_gdb "ptype tagless_struct\n"
+ gdb_expect {
+ -re "type = class \{${ws}public:${ws}int one;${ws}int two;${ws}tagless_struct & operator=\\(tagless_struct (const ?)?&\\);${ws}tagless_struct\\(tagless_struct (const ?)?&\\);${ws}tagless_struct\\(\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype tagless struct"
+ }
+ -re "type = class \{${ws}public:${ws}int one;${ws}int two;;${ws}\}$nl$gdb_prompt $" {
+ pass "ptype tagless struct"
+ }
+ -re "type = (struct|class).*\{.*int one;.*int two;.*\}$nl$gdb_prompt $" {
+ pass "ptype tagless struct (obsolete gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype tagless struct"
+ }
+ timeout {
+ fail "ptype tagless struct (timeout)"
+ }
+ }
+
+ send_gdb "ptype v_tagless\n"
+ gdb_expect {
+ -re "type = class \{${ws}public:${ws}int one;${ws}int two;${ws}tagless_struct & operator=\\(tagless_struct (const ?)?&\\);${ws}tagless_struct\\(tagless_struct (const ?)?&\\);${ws}tagless_struct\\(\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype variable of type tagless struct"
+ }
+ -re "type = class \{${ws}public:${ws}int one;${ws}int two;;${ws}\}$nl$gdb_prompt $" {
+ pass "ptype tagless struct"
+ }
+ -re "type = (struct|class).*\{.*int one;.*int two;.*\}$nl$gdb_prompt $" {
+ pass "ptype variable of type tagless struct (obsolete gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype variable of type tagless struct"
+ }
+ timeout {
+ fail "ptype variable of type tagless struct (timeout)"
+ }
+ }
+}
+
+#
+# Single inheritance, print complete classes.
+#
+
+proc test_print_si_classes {} {
+ # Print all members of g_A.
+
+ gdb_test "print g_A" ".* = \{a = 1, x = 2\}" "print g_A"
+
+ # Print all members of g_B.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_B" ".* = \{\<(class |)A\> = \{a = 3, x = 4\}, b = 5, x = 6\}" "print g_B"
+
+ # Print all members of g_C.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_C" ".* = \{\<(class |)A\> = \{a = 7, x = 8\}, c = 9, x = 10\}" "print g_C"
+}
+
+#
+# Single inheritance, print anonymous unions.
+# GDB versions prior to 4.14 entered an infinite loop when printing
+# the type of a class containing an anonymous union, and they were also
+# incapable of printing the member of an anonymous union.
+# We test the printing of the member first, and perform the other tests
+# only if the test succeeds, to avoid the infinite loop.
+#
+
+proc test_print_anon_union {} {
+ global gdb_prompt
+ global ws
+ global nl
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_anon_union.a" ".* = 2" "print anonymous union member"
+ setup_xfail_format "DWARF 1"
+ send_gdb "print g_anon_union\n"
+ gdb_expect {
+ -re ".* = \{one = 1, ( = |)\{a = 2, b = 2\}\}$nl$gdb_prompt $" {
+ pass "print variable of type anonymous union"
+ }
+ -re ".* = .*\{one = 1, ( = |)\{a = 2, b = .*\}\}$nl$gdb_prompt $" {
+ pass "print variable of type anonymous union (obsolete gcc or gdb)"
+ }
+ -re ".*$nl$gdb_prompt $" {
+ fail "print variable of type anonymous union"
+ }
+ timeout {
+ fail "print variableof type anonymous union (timeout)"
+ }
+ }
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype g_anon_union\n"
+ gdb_expect {
+ -re "type = class class_with_anon_union \{${ws}public:${ws}int one;${ws}union \{${ws}public:${ws}int a;${ws}long int b;${ws}union \{\.\.\.\} & operator=\\(union \{\.\.\.\} &\\);${ws}\\\$_0 \\(union \{\.\.\.\} &\\);${ws}\\\$_0 \\(\\);${ws}\};${ws}class_with_anon_union & operator=\\(class_with_anon_union const &\\);${ws}class_with_anon_union\\(class_with_anon_union const &\\);${ws}class_with_anon_union\\(void\\);${ws}\}$nl$gdb_prompt $" {
+ pass "print type of anonymous union"
+ }
+ -re "type = class class_with_anon_union \{${ws}public:${ws}int one;${ws}union \{${ws}int a;${ws}long int b;${ws}\};${ws}class_with_anon_union & operator=\\(class_with_anon_union const ?&\\);${ws}class_with_anon_union\\(class_with_anon_union const ?&\\);${ws}class_with_anon_union\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "print type of anonymous union"
+ }
+ -re "type = class class_with_anon_union \{${ws}public:${ws}int one;${ws}union \{${ws}int a;${ws}long int b;${ws}\};${ws}\}$nl$gdb_prompt $" {
+ pass "print type of anonymous union"
+ }
+ -re "type = (struct|class).*\{.*int one;.*union \{.*int a;.*(long|long int|int) b;.*\};.*\}$nl$gdb_prompt $" {
+ pass "print type of anonymous union (obsolete gcc or gdb)"
+ }
+ -re ".*$nl$gdb_prompt $" {
+ fail "print type of anonymous union"
+ }
+ timeout {
+ fail "print type of anonymous union (timeout)"
+ }
+ }
+}
+
+#
+# Multiple inheritance, print individual members.
+#
+
+proc test_print_mi_members {} {
+ global gdb_prompt
+ global nl
+ global hp_aCC_compiler
+
+ # Print all members of g_A.
+
+ gdb_test "print g_A.A::a" ".* = 1" "print g_A.A::a"
+
+ gdb_test "print g_A.A::x" ".* = 2" "print g_A.A::x"
+
+ # Print all members of g_B.
+
+ gdb_test "print g_B.A::a" ".* = 3" "print g_B.A::a"
+
+ gdb_test "print g_B.A::x" ".* = 4" "print g_B.A::x"
+
+ gdb_test "print g_B.B::b" ".* = 5" "print g_B.B::b"
+
+ gdb_test "print g_B.B::x" ".* = 6" "print g_B.B::x"
+
+ # Print all members of g_C.
+
+ gdb_test "print g_C.A::a" ".* = 7" "print g_C.A::a"
+
+ gdb_test "print g_C.A::x" ".* = 8" "print g_C.A::x"
+
+ gdb_test "print g_C.C::c" ".* = 9" "print g_C.C::c"
+
+ gdb_test "print g_C.C::x" ".* = 10" "print g_C.C::x"
+
+ # Print all members of g_D.
+
+ # The following is ambiguous, and gdb should detect this.
+ # For now, accept gdb's behavior as an expected failure if it
+ # simply prints either member correctly.
+
+ if {!$hp_aCC_compiler} {setup_xfail "*-*-*"}
+ send_gdb "print g_D.A::a\n"
+ gdb_expect {
+ -re "warning: A ambiguous; using D::C::A. Use a cast to disambiguate.$nl\\$\[0-9\]* = 15$nl$gdb_prompt $" {
+ pass "print g_D.A::a"
+ }
+ -re "warning: A ambiguous; using D::B::A. Use a cast to disambiguate.$nl\\$\[0-9\]* = 11$nl$gdb_prompt $" {
+ pass "print g_D.A::a (using B)"
+ }
+ -re ".* = 15$nl$gdb_prompt $" {
+ fail "print g_D.A::a (FIXME)"
+ }
+ -re ".* = 11$nl$gdb_prompt $" {
+ fail "print g_D.A::a (FIXME)"
+ }
+ -re ".*$gdb_prompt $" { fail "print g_D.A::a" }
+ timeout { fail "print g_D.A::a (timeout)" ; return }
+ }
+
+ # The following is ambiguous, and gdb should detect this.
+ # For now, accept gdb's behavior as an expected failure if it
+ # simply prints either member correctly.
+
+ if {!$hp_aCC_compiler} {setup_xfail "*-*-*"}
+ send_gdb "print g_D.A::x\n"
+ gdb_expect {
+ -re "warning: A ambiguous; using D::C::A. Use a cast to disambiguate.$nl\\$\[0-9\]* = 16$nl$gdb_prompt $" {
+ pass "print g_D.A::x"
+ }
+ -re "warning: A ambiguous; using D::B::A. Use a cast to disambiguate.$nl\\$\[0-9\]* = 12$nl$gdb_prompt $" {
+ pass "print g_D.A::x (using B)"
+ }
+ -re ".* = 16$nl$gdb_prompt $" {
+ fail "print g_D.A::x (FIXME)"
+ }
+ -re ".* = 12$nl$gdb_prompt $" {
+ fail "print g_D.A::x (FIXME)"
+ }
+ -re ".*$gdb_prompt $" { fail "print g_D.A::x" }
+ timeout { fail "print g_D.A::x (timeout)" ; return }
+ }
+
+ gdb_test "print g_D.B::b" ".* = 13" "print g_D.B::b"
+
+ gdb_test "print g_D.B::x" ".* = 14" "print g_D.B::x"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_D.C::c" ".* = 17" "print g_D.C::c"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_D.C::x" ".* = 18" "print g_D.C::x"
+
+ gdb_test "print g_D.D::d" ".* = 19" "print g_D.D::d"
+
+ gdb_test "print g_D.D::x" ".* = 20" "print g_D.D::x"
+
+ # Print all members of g_E.
+
+ # The following is ambiguous, and gdb should detect this.
+ # For now, accept gdb's behavior as an expected failure if it
+ # simply prints either member correctly.
+
+ setup_xfail "*-*-*"
+ send_gdb "print g_E.A::a\n"
+ gdb_expect {
+ -re ".* = 21$nl$gdb_prompt $" {
+ fail "print g_E.A::a (FIXME)"
+ }
+ -re ".* = 25$nl$gdb_prompt $" {
+ fail "print g_E.A::a (FIXME)"
+ }
+ -re ".*$gdb_prompt $" { fail "print g_E.A::a" }
+ timeout { fail "print g_E.A::a (timeout)" ; return }
+ }
+
+ # The following is ambiguous, and gdb should detect this.
+ # For now, accept gdb's behavior as an expected failure if it
+ # simply prints either member correctly.
+
+ if {!$hp_aCC_compiler} {setup_xfail "*-*-*"}
+ send_gdb "print g_E.A::x\n"
+ gdb_expect {
+ -re "warning: A ambiguous; using E::D::C::A. Use a cast to disambiguate.$nl\\$\[0-9\]* = 26$nl$gdb_prompt $" {
+ pass "print g_E.A::x"
+ }
+ -re "warning: A ambiguous; using E::D::B::A. Use a cast to disambiguate.$nl\\$\[0-9\]* = 22$nl$gdb_prompt $" {
+ pass "print g_E.A::x (using B)"
+ }
+ -re ".* = 26$nl$gdb_prompt $" {
+ fail "print g_E.A::x (FIXME)"
+ }
+ -re ".* = 22$nl$gdb_prompt $" {
+ fail "print g_E.A::x (FIXME)"
+ }
+ -re ".*$gdb_prompt $" { fail "print g_E.A::x" }
+ timeout { fail "print g_E.A::x (timeout)" ; return }
+ }
+
+ gdb_test "print g_E.B::b" ".* = 23" "print g_E.B::b"
+
+ gdb_test "print g_E.B::x" ".* = 24" "print g_E.B::x"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_E.C::c" ".* = 27" "print g_E.C::c"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_E.C::x" ".* = 28" "print g_E.C::x"
+
+ gdb_test "print g_E.D::d" ".* = 29" "print g_E.D::d"
+
+ gdb_test "print g_E.D::x" ".* = 30" "print g_E.D::x"
+
+ gdb_test "print g_E.E::e" ".* = 31" "print g_E.E::e"
+
+ gdb_test "print g_E.E::x" ".* = 32" "print g_E.E::x"
+}
+
+#
+# Multiple inheritance, print type definitions.
+#
+
+proc test_ptype_mi {} {
+ global nl
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "ptype D" "type = class D : public B, public C \{$nl\[ \]*public:$nl\[ \]*int d;$nl\[ \]*int x;$nl.*\}" "ptype D"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "ptype class D" "type = class D : public B, public C \{$nl\[ \]*public:$nl\[ \]*int d;$nl\[ \]*int x;$nl.*\}" "ptype class D"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "ptype g_D" "type = class D : public B, public C \{$nl\[ \]*public:$nl\[ \]*int d;$nl\[ \]*int x;$nl.*\}" "ptype g_D"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "ptype E" "type = class E : public D \{$nl\[ \]*public:$nl\[ \]*int e;$nl\[ \]*int x;$nl.*\}" "ptype E"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "ptype class E" "type = class E : public D \{$nl\[ \]*public:$nl\[ \]*int e;$nl\[ \]*int x;$nl.*\}" "ptype class E"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "ptype g_E" "type = class E : public D \{$nl\[ \]*public:$nl\[ \]*int e;$nl\[ \]*int x;$nl.*\}" "ptype g_E"
+}
+
+#
+# Multiple inheritance, print complete classes.
+#
+
+proc test_print_mi_classes {} {
+ # Print all members of g_D.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_D" ".* = \{\<(class |)B\> = \{\<(class |)A\> = \{a = 11, x = 12\}, b = 13, x = 14\}, \<(class |)C\> = \{\<(class |)A\> = \{a = 15, x = 16\}, c = 17, x = 18\}, d = 19, x = 20\}" "print g_D"
+
+ # Print all members of g_E.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_E" ".* = \{\<(class |)D\> = \{\<(class |)B\> = \{\<(class |)A\> = \{a = 21, x = 22\}, b = 23, x = 24\}, \<(class |)C\> = \{\<(class |)A\> = \{a = 25, x = 26\}, c = 27, x = 28\}, d = 29, x = 30\}, e = 31, x = 32\}" "print g_E"
+}
+
+#
+# Single virtual inheritance, print individual members.
+#
+
+proc test_print_svi_members {} {
+ global gdb_prompt
+ global decimal
+ global nl
+
+ # Print all members of g_vA.
+
+ gdb_test "print g_vA.vA::va" ".* = 1" "print g_vA.vA::va"
+
+ gdb_test "print g_vA.vA::vx" ".* = 2" "print g_vA.vA::vx"
+
+ # Print members of g_vA using compact form.
+
+ gdb_test "print g_vA.va" ".* = 1" "print g_vA.va"
+
+ gdb_test "print g_vA.vx" ".* = 2" "print g_vA.vx"
+
+ # Print all members of g_vB.
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "print g_vB.vA::va\n"
+ gdb_expect {
+ -re ".* = 3$nl$gdb_prompt $" { pass "print g_vB.vA::va" }
+ -re ".*virtual baseclass botch.*$gdb_prompt $" {
+ # Does not happen with gcc cygnus-2.4.5-930828
+ fail "print g_vB.vA::va (known bug with gcc cygnus-2.4.5-930417)"
+ # Many of the rest of these tests have the same problem.
+ return 0
+ }
+ -re ".*$gdb_prompt $" { fail "print g_vB.vA::va" }
+ timeout { fail "print g_vB.vA::va (timeout)" ; return }
+ }
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vB.vA::vx" ".* = 4" "print g_vB.vA::vx"
+
+ gdb_test "print g_vB.vB::vb" ".* = 5" "print g_vB.vB::vb"
+
+ gdb_test "print g_vB.vB::vx" ".* = 6" "print g_vB.vB::vx"
+
+ # Print members of g_vB using compact form.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vB.va" ".* = 3" "print g_vB.va"
+
+ gdb_test "print g_vB.vb" ".* = 5" "print g_vB.vb"
+
+ gdb_test "print g_vB.vx" ".* = 6" "print g_vB.vx"
+
+ # Print all members of g_vC.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vC.vA::va" ".* = 7" "print g_vC.vA::va"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vC.vA::vx" ".* = 8" "print g_vC.vA::vx"
+
+ gdb_test "print g_vC.vC::vc" ".* = 9" "print g_vC.vC::vc"
+
+ gdb_test "print g_vC.vC::vx" ".* = 10" "print g_vC.vC::vx"
+
+ # Print members of g_vC using compact form.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vC.va" ".* = 7" "print g_vC.va"
+
+ gdb_test "print g_vC.vc" ".* = 9" "print g_vC.vc"
+
+ gdb_test "print g_vC.vx" ".* = 10" "print g_vC.vx"
+}
+
+#
+# Single virtual inheritance, print type definitions.
+#
+
+proc test_ptype_vi {} {
+ global gdb_prompt
+ global ws
+ global nl
+ global vbptr
+
+ # This class does not use any C++-specific features, so it's fine for
+ # it to print as "struct".
+ send_gdb "ptype vA\n"
+ gdb_expect {
+ -re "type = class vA \{$nl\[ \]*public:$nl\[ \]*int va;$nl\[ \]*int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype vA"
+ }
+ -re "type = struct vA \{$nl\[ \]*int va;$nl\[ \]*int vx;$nl\}$nl$gdb_prompt $" {
+ pass "ptype vA"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype vA" }
+ timeout { fail "ptype vA (timeout)" ; return }
+ }
+
+ # This class does not use any C++-specific features, so it's fine for
+ # it to print as "struct".
+ send_gdb "ptype class vA\n"
+ gdb_expect {
+ -re "type = class vA \{$nl\[ \]*public:$nl\[ \]*int va;$nl\[ \]*int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype class vA"
+ }
+ -re "type = struct vA \{$nl\[ \]*int va;$nl\[ \]*int vx;$nl\}$nl$gdb_prompt $" {
+ pass "ptype class vA"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype class vA" }
+ timeout { fail "ptype class vA (timeout)" ; return }
+ }
+
+ # This class does not use any C++-specific features, so it's fine for
+ # it to print as "struct".
+ send_gdb "ptype g_vA\n"
+ gdb_expect {
+ -re "type = class vA \{$nl\[ \]*public:$nl\[ \]*int va;$nl\[ \]*int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype g_vA"
+ }
+ -re "type = struct vA \{$nl\[ \]*int va;$nl\[ \]*int vx;$nl\}$nl$gdb_prompt $" {
+ pass "ptype g_vA"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype g_vA" }
+ timeout { fail "ptype g_vA (timeout)" ; return }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype vB\n"
+ gdb_expect {
+ -re "ptype vB${nl}type = class vB : public virtual vA \{$nl private:${ws}vA \\*${vbptr}vA;$nl public:${ws}int vb;${ws}int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype vB"
+ }
+ -re "ptype vB${nl}type = class vB : public virtual vA \{$nl public:${ws}int vb;${ws}int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype vB (aCC)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype vB" }
+ timeout { fail "ptype vB (timeout)" }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class vB\n"
+ gdb_expect {
+ -re "type = class vB : public virtual vA \{$nl\[ \]*private:$nl\[ \]*vA \\*${vbptr}vA;$nl\[ \]*public:$nl\[ \]*int vb;$nl\[ \]*int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype class vB"
+ }
+ -re "type = class vB : public virtual vA \{$nl\[ \]*public:$nl\[ \]*int vb;$nl\[ \]*int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype class vB (aCC)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype class vB" }
+ timeout { fail "ptype class vB (timeout)" }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype g_vB\n"
+ gdb_expect {
+ -re "type = class vB : public virtual vA \{$nl\[ \]*private:$nl\[ \]*vA \\*${vbptr}vA;$nl\[ \]*public:$nl\[ \]*int vb;$nl\[ \]*int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype g_vB"
+ }
+ -re "type = class vB : public virtual vA \{$nl\[ \]*public:$nl\[ \]*int vb;$nl\[ \]*int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype g_vB (aCC)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype g_vB" }
+ timeout { fail "ptype g_vB (timeout)" }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype vC\n"
+ gdb_expect {
+ -re "type = class vC : public virtual vA \{$nl\[ \]*private:$nl\[ \]*vA \\*${vbptr}vA;$nl\[ \]*public:$nl\[ \]*int vc;$nl\[ \]*int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype vC"
+ }
+ -re "type = class vC : public virtual vA \{$nl\[ \]*public:$nl\[ \]*int vc;$nl\[ \]*int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype vC (aCC)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype vC" }
+ timeout { fail "ptype vC (timeout)" }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class vC\n"
+ gdb_expect {
+ -re "type = class vC : public virtual vA \{$nl\[ \]*private:$nl\[ \]*vA \\*${vbptr}vA;$nl\[ \]*public:$nl\[ \]*int vc;$nl\[ \]*int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype class vC"
+ }
+ -re "type = class vC : public virtual vA \{$nl\[ \]*public:$nl\[ \]*int vc;$nl\[ \]*int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype class vC (aCC)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype class vC" }
+ timeout { fail "ptype class vC (timeout)" }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype g_vC\n"
+ gdb_expect {
+ -re "type = class vC : public virtual vA \{$nl\[ \]*private:$nl\[ \]*vA \\*${vbptr}vA;$nl\[ \]*public:$nl\[ \]*int vc;$nl\[ \]*int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype g_vC"
+ }
+ -re "type = class vC : public virtual vA \{$nl\[ \]*public:$nl\[ \]*int vc;$nl\[ \]*int vx;$nl.*\}$nl$gdb_prompt $" {
+ pass "ptype g_vC (aCC)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype g_vC" }
+ timeout { fail "ptype g_vC (timeout)" }
+ }
+}
+
+#
+# Single virtual inheritance, print complete classes.
+#
+
+proc test_print_svi_classes {} {
+ global gdb_prompt
+ global hex
+ global decimal
+ global nl
+ global vbptr
+
+ # Print all members of g_vA.
+
+ gdb_test "print g_vA" ".* = \{va = 1, vx = 2\}" "print g_vA"
+
+ # Print all members of g_vB.
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "print g_vB\n"
+ gdb_expect {
+ -re ".* = \{\<class vA\> = \{va = 3, vx = 4\}, vb = 5, vx = 6, Virtual table at $hex\}$nl$gdb_prompt $" {
+ pass "print g_vB (aCC)"
+ }
+ -re ".* = \{\<class vA\> = \{va = 3, vx = 4\}, vb = 5, vx = 6, __vfp = $hex\}$nl$gdb_prompt $" {
+ pass "print g_vB (aCC)"
+ }
+ -re ".* = \{\<vA\> = \{va = 3, vx = 4\}, ${vbptr}vA = $hex, vb = 5, vx = 6\}$nl$gdb_prompt $" {
+ pass "print g_vB"
+ }
+ -re ".* = \{\<vA\> = \{va = 3, vx = 4\}, _vptr.vB = $hex, vb = 5, vx = 6\}$nl$gdb_prompt $" {
+ pass "print g_vB (FIXME v3 vtbl ptr)"
+ }
+ -re ".*invalid address 0x0.*$gdb_prompt $" {
+ # Does not happen with gcc cygnus-2.4.5-930828
+ fail "print g_vB (known bug with gcc cygnus-2.4.5-930417)"
+ # Many of the rest of these tests have the same problem.
+ return 0
+ }
+ -re ".*$gdb_prompt $" { fail "print g_vB" }
+ timeout { fail "print g_vB (timeout)" ; return }
+ }
+
+ # Print all members of g_vC.
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "print g_vC\n"
+ gdb_expect {
+ -re ".* = \{\<class vA\> = \{va = 7, vx = 8\}, vc = 9, vx = 10, Virtual table at $hex\}$nl$gdb_prompt $" {
+ pass "print g_vC (aCC)"
+ }
+ -re ".* = \{\<class vA\> = \{va = 7, vx = 8\}, vc = 9, vx = 10, __vfp = $hex\}$nl$gdb_prompt $" {
+ pass "print g_vC (aCC)"
+ }
+ -re ".* = \{\<vA\> = \{va = 7, vx = 8\}, ${vbptr}vA = $hex, vc = 9, vx = 10\}$nl$gdb_prompt $" {
+ pass "print g_vC"
+ }
+ -re ".* = \{\<vA\> = \{va = 7, vx = 8\}, _vptr.vC = $hex, vc = 9, vx = 10\}$nl$gdb_prompt $" {
+ pass "print g_vC (FIXME v3 vtbl ptr)"
+ }
+ -re ".*$gdb_prompt $" { fail "print g_vC" }
+ timeout { fail "print g_vC (timeout)" }
+ }
+}
+
+#
+# Multiple virtual inheritance, print individual members.
+#
+
+proc test_print_mvi_members {} {
+ global gdb_prompt
+ global decimal
+ global nl
+
+ # Print all members of g_vD.
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "print g_vD.vA::va\n"
+ gdb_expect {
+ -re ".* = 19$nl$gdb_prompt $" { pass "print g_vD.vA::va" }
+ -re ".*virtual baseclass botch.*$gdb_prompt $" {
+ # Does not happen with gcc cygnus-2.4.5-930828
+ fail "print g_vD.vA::va (known bug with gcc cygnus-2.4.5-930417)"
+ # Many of the rest of these tests have the same problem.
+ return 0
+ }
+ -re ".*$gdb_prompt $" { fail "print g_vD.vA::va" }
+ timeout { fail "print g_vD.vA::va (timeout)" ; return }
+ }
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vD.vA::vx" ".* = 20" "print g_vD.vA::vx"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vD.vB::vb" ".* = 21" "print g_vD.vB::vb"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vD.vB::vx" ".* = 22" "print g_vD.vB::vx"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vD.vC::vc" ".* = 23" "print g_vD.vC::vc"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vD.vC::vx" ".* = 24" "print g_vD.vC::vx"
+
+ gdb_test "print g_vD.vD::vd" ".* = 25" "print g_vD.vD::vd"
+
+ gdb_test "print g_vD.vD::vx" ".* = 26" "print g_vD.vD::vx"
+
+ # Print all members of g_vE.
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vE.vA::va" ".* = 0" "print g_vE.vA::va"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vE.vA::vx" ".* = 0" "print g_vE.vA::vx"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vE.vB::vb" ".* = 0" "print g_vE.vB::vb"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vE.vB::vx" ".* = 0" "print g_vE.vB::vx"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vE.vC::vc" ".* = 0" "print g_vE.vC::vc"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vE.vC::vx" ".* = 0" "print g_vE.vC::vx"
+
+ setup_xfail_format "DWARF 1"
+ gdb_test "print g_vE.vD::vd" ".* = 0" "print g_vE.vD::vd"
+
+ gdb_test "print g_vE.vD::vx" ".* = 0" "print g_vE.vD::vx"
+
+ gdb_test "print g_vE.vE::ve" ".* = 27" "print g_vE.vE::ve"
+
+ gdb_test "print g_vE.vE::vx" ".* = 28" "print g_vE.vE::vx"
+}
+
+#
+# Multiple virtual inheritance, print type definitions.
+#
+
+proc test_ptype_mvi {} {
+ global gdb_prompt
+ global ws
+ global nl
+ global vbptr
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype vD\n"
+ gdb_expect {
+ -re "type = class vD : public virtual vB, public virtual vC \{${ws}private:${ws}vC \\*${vbptr}vC;${ws}vB \\*${vbptr}vB;${ws}public:${ws}int vd;${ws}int vx;$nl.*\}.*$gdb_prompt $" {
+ pass "ptype vD"
+ }
+ -re ".*class vD : public virtual vB, public virtual vC \{${ws}public:${ws}int vd;${ws}int vx;.*\}.*$gdb_prompt $" {
+ pass "ptype vD"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype vD" }
+ timeout { fail "(timeout) ptype vD" }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class vD\n"
+ gdb_expect {
+ -re "type = class vD : public virtual vB, public virtual vC \{${ws}private:${ws}vC \\*${vbptr}vC;${ws}vB \\*${vbptr}vB;${ws}public:${ws}int vd;${ws}int vx;$nl.*\}.*$gdb_prompt $" {
+ pass "ptype class vD"
+ }
+ -re ".*class vD : public virtual vB, public virtual vC \{${ws}public:${ws}int vd;${ws}int vx;.*\}.*$gdb_prompt $" {
+ pass "ptype class vD"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype class vD" }
+ timeout { fail "(timeout) ptype class vD" }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype g_vD\n"
+ gdb_expect {
+ -re "type = class vD : public virtual vB, public virtual vC \{${ws}private:${ws}vC \\*${vbptr}vC;${ws}vB \\*${vbptr}vB;${ws}public:${ws}int vd;${ws}int vx;$nl.*\}.*$gdb_prompt $" {
+ pass "ptype g_vD"
+ }
+ -re ".*class vD : public virtual vB, public virtual vC \{${ws}public:${ws}int vd;${ws}int vx;\r\n.*\}.*$gdb_prompt $" {
+ pass "ptype g_vD"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype g_vD" }
+ timeout { fail "(timeout) ptype g_vD" }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype vE\n"
+ gdb_expect {
+ -re "type = class vE : public virtual vD \{${ws}private:${ws}vD \\*${vbptr}vD;${ws}public:${ws}int ve;${ws}int vx;$nl.*\}.*$gdb_prompt $" {
+ pass "ptype vE"
+ }
+ -re ".*class vE : public virtual vD \{${ws}public:${ws}int ve;${ws}int vx;\r\n.*\}.*$gdb_prompt $" {
+ pass "ptype vE"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype vE" }
+ timeout { fail "(timeout) ptype vE" }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype class vE\n"
+ gdb_expect {
+ -re "type = class vE : public virtual vD \{${ws}private:${ws}vD \\*${vbptr}vD;${ws}public:${ws}int ve;${ws}int vx;$nl.*\}.*$gdb_prompt $" {
+ pass "ptype class vE"
+ }
+ -re "type = class vE : public virtual vD \{${ws}public:${ws}int ve;${ws}int vx;\r\n.*\}.*$gdb_prompt $" {
+ pass "ptype class vE"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype class vE" }
+ timeout { fail "(timeout) ptype class vE" }
+ }
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "ptype g_vE\n"
+ gdb_expect {
+ -re "type = class vE : public virtual vD \{${ws}private:${ws}vD \\*${vbptr}vD;${ws}public:${ws}int ve;${ws}int vx;$nl.*\}.*$gdb_prompt $" {
+ pass "ptype g_vE"
+ }
+ -re "type = class vE : public virtual vD \{${ws}public:${ws}int ve;${ws}int vx;\r\n.*\}.*$gdb_prompt $" {
+ pass "ptype g_vE"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype g_vE" }
+ timeout { fail "(timeout) ptype g_vE" }
+ }
+}
+
+#
+# Multiple virtual inheritance, print complete classes.
+#
+
+proc test_print_mvi_classes {} {
+ global gdb_prompt
+ global hex
+ global decimal
+ global nl
+ global vbptr
+
+ # Print all members of g_vD.
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "print g_vD\n"
+ gdb_expect {
+ -re ".* = \{\<class vB\> = \{\<class vA\> = \{va = 19, vx = 20\}, vb = 21, vx = 22, Virtual table at $hex\}, \<class vC\> = \{vc = 23, vx = 24, Virtual table at $hex\}, vd = 25, vx = 26, Virtual table at $hex\}$nl$gdb_prompt $" {
+ pass "print g_vD (aCC)"
+ }
+ -re ".* = \{\<class vB\> = \{\<class vA\> = \{va = 19, vx = 20\}, vb = 21, vx = 22, __vfp = $hex\}, \<class vC\> = \{vc = 23, vx = 24, __vfp = $hex\}, vd = 25, vx = 26, __vfp = $hex\}$nl$gdb_prompt $" {
+ pass "print g_vD (aCC)"
+ }
+ -re ".* = \{\<vB\> = \{\<vA\> = \{va = 19, vx = 20\}, ${vbptr}vA = $hex, vb = 21, vx = 22\}, \<vC\> = \{${vbptr}vA = $hex, vc = 23, vx = 24\}, ${vbptr}vC = $hex, ${vbptr}vB = $hex, vd = 25, vx = 26\}$nl$gdb_prompt $" {
+ pass "print g_vD"
+ }
+ -re ".* = \{\<vB\> = \{\<vA\> = \{va = 19, vx = 20\}, _vptr.vB = $hex, vb = 21, vx = 22\}, \<vC\> = \{_vptr.vC = $hex, vc = 23, vx = 24\}, _vptr.vD = $hex, vd = 25, vx = 26\}$nl$gdb_prompt $" {
+ pass "print g_vD (FIXME v3 vtbl ptr)"
+ }
+ -re ".*invalid address 0x0.*$gdb_prompt $" {
+ # Does not happen with gcc cygnus-2.4.5-930828
+ fail "print g_vD (known bug with gcc cygnus-2.4.5-930417)"
+ # Many of the rest of these tests have the same problem.
+ return 0
+ }
+ -re ".*$gdb_prompt $" { fail "print g_vD" }
+ timeout { fail "print g_vD (timeout)" ; return }
+ }
+
+ # Print all members of g_vE.
+
+ setup_xfail_format "DWARF 1"
+ send_gdb "print g_vE\n"
+ gdb_expect {
+ -re ".* = \{\<class vD\> = \{\<class vB\> = \{\<class vA\> = \{va = 0, vx = 0\}, vb = 0, vx = 0, Virtual table at $hex\}, \<class vC\> = \{vc = 0, vx = 0, Virtual table at $hex\}, vd = 0, vx = 0, Virtual table at $hex\}, ve = 27, vx = 28, Virtual table at $hex\}$nl$gdb_prompt $" {
+ pass "print g_vE (aCC)"
+ }
+ -re ".* = \{\<class vD\> = \{\<class vB\> = \{\<class vA\> = \{va = 0, vx = 0\}, vb = 0, vx = 0, __vfp = $hex\}, \<class vC\> = \{vc = 0, vx = 0, __vfp = $hex\}, vd = 0, vx = 0, __vfp = $hex\}, ve = 27, vx = 28, __vfp = $hex\}$nl$gdb_prompt $" {
+ pass "print g_vE (aCC)"
+ }
+ -re ".* = \{\<vD\> = \{\<vB\> = \{\<vA\> = \{va = 0, vx = 0\}, ${vbptr}vA = $hex, vb = 0, vx = 0\}, \<vC\> = \{${vbptr}vA = $hex, vc = 0, vx = 0\}, ${vbptr}vC = $hex, ${vbptr}vB = $hex, vd = 0, vx = 0\}, ${vbptr}vD = $hex, ve = 27, vx = 28\}$nl$gdb_prompt $" {
+ pass "print g_vE"
+ }
+ -re ".* = \{\<vD\> = \{\<vB\> = \{\<vA\> = \{va = 0, vx = 0\}, _vptr.vB = $hex *(\<VTT for vD\>)?, vb = 0, vx = 0\}, \<vC\> = \{_vptr.vC = $hex *(\<VTT for vD\>)?, vc = 0, vx = 0\}, _vptr.vD = $hex, vd = 0, vx = 0\}, _vptr.vE = $hex, ve = 27, vx = 28\}$nl$gdb_prompt $" {
+ pass "print g_vE (FIXME v3 vtbl ptr)"
+ }
+ -re ".*$gdb_prompt $" { fail "print g_vE" }
+ timeout { fail "print g_vE (timeout)" }
+ }
+}
+
+proc do_tests {} {
+ global prms_id
+ global bug_id
+ global subdir
+ global objdir
+ global srcdir
+ global binfile
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language c++" ""
+ gdb_test "set width 0" ""
+
+ # Get the debug format for the compiled test case.
+
+ if { ![ runto_main] } {
+ gdb_suppress_tests;
+ } else {
+ get_debug_format
+ }
+
+ test_ptype_si
+ test_ptype_mi
+ test_ptype_vi
+ test_ptype_mvi
+
+ gdb_stop_suppressing_tests;
+
+ if { ![ runto 'inheritance2' ] } {
+ gdb_suppress_tests;
+ }
+
+ test_print_si_members
+ test_print_si_classes
+ test_print_mi_members
+ test_print_mi_classes
+ test_print_anon_union
+
+ gdb_stop_suppressing_tests;
+
+ if { ![ runto 'inheritance4' ] } {
+ gdb_suppress_tests;
+ }
+
+ test_print_svi_members
+ test_print_svi_classes
+ test_print_mvi_members
+ test_print_mvi_classes
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.c++/local.cc b/gdb/testsuite/gdb.c++/local.cc
new file mode 100644
index 00000000000..5bfc44ac43b
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/local.cc
@@ -0,0 +1,61 @@
+// Tests for local types
+
+void marker1 (void)
+{
+}
+
+
+int foobar (int x)
+{
+ class Local {
+ public:
+ int loc1;
+ char loc_foo (char c)
+ {
+ return c + 3;
+ }
+ };
+
+ Local l;
+ static Local l1;
+ char c;
+
+ l.loc1 = 23;
+
+ c = l.loc_foo('x');
+ return c + 2;
+}
+
+int main()
+{
+ int c;
+
+ c = foobar (31);
+
+ { // inner block
+ class InnerLocal {
+ public:
+ char ilc;
+ int * ip;
+ int il_foo (unsigned const char & uccr)
+ {
+ return uccr + 333;
+ }
+ class NestedInnerLocal {
+ public:
+ int nil;
+ int nil_foo (int i)
+ {
+ return i * 27;
+ }
+ };
+ NestedInnerLocal nest1;
+ };
+
+ InnerLocal il;
+
+ il.ilc = 'b';
+ il.ip = &c;
+ marker1();
+ }
+}
diff --git a/gdb/testsuite/gdb.c++/local.exp b/gdb/testsuite/gdb.c++/local.exp
new file mode 100644
index 00000000000..3ec2d5ef8b5
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/local.exp
@@ -0,0 +1,199 @@
+# Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# tests for local variables
+# Written by Satish Pai <pai@apollo.hp.com> 1997-07-08
+# Cleaned by Michael Chastain <mec@shout.net> 2002-04-08
+
+
+# This file is part of the gdb testsuite
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "local"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info $binfile "c++"] {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+if ![runto 'marker1'] then {
+ perror "couldn't run to marker1"
+ continue
+}
+
+gdb_test "up" ".*main.*" "up from marker1"
+
+# Local classes in g++ get names like "main.1::InnerLocal", just like local
+# static variables. Some targets use "___" instead of ".".
+
+# ---
+# Pattern 1:
+# PASS
+# dwarf-2
+# gcc 2.95.3
+#
+# Pattern 2:
+# FAIL
+# This has a duplicate "char loc_foo" line. This is a bug.
+# Historically this has been an XFAIL.
+# dwarf-2
+# gcc 2.96-rh, 3.0.4, gcc-3_1-branch, HEAD
+#
+# Pattern 3:
+# PASS
+# stabs+
+# gcc 2.95.3, 2.96-rh, 3.0.4, gcc-3_1-branch, HEAD
+#
+# Pattern 4:
+# This an old pattern from the hppa aCC version of this file.
+# I left it alone.
+#
+# chastain 2002-04-08
+
+set sep "(\[.\]|___)\[0-9\]"
+
+send_gdb "ptype Local\n"
+gdb_expect {
+ -re "type = class Local \{\[\r\n\t \]*public:\[\r\n\t \]*int loc1;\[\r\n\t \]*char loc_foo\\((const *|)char\\);\[\r\n\t \]*\}.*$gdb_prompt $" { pass "ptype Local" }
+ -re "type = class Local \{\[\r\n\t \]*public:\[\r\n\t \]*int loc1;\[\r\n\t \]*char loc_foo\\((const *|)char\\);\[\r\n\t \]*char loc_foo\\((const *|)char\\);\[\r\n\t \]*\}.*$gdb_prompt $" {
+ # setup_kfail "gdb/483"
+ fail "ptype Local (gdb/483)"
+ }
+ -re "type = class Local \{\[\r\n\t \]*public:\[\r\n\t \]*int loc1;\[\r\n\t \]*Local & operator *=\\((foobar__Fi${sep}::|)Local const *&\\);\[\r\n\t \]*Local\\((foobar__Fi${sep}::|)Local const *&\\);\[\r\n\t \]*Local\\((void|)\\);\[\r\n\t \]*char loc_foo\\(char\\);\[\r\n\t \]*\}.*$gdb_prompt $" { pass "ptype Local" }
+ -re "type = class Local \{\r\n\[\t \]*public:\r\n\[\t \]*int loc1;\r\n\r\n\[\t \]*char loc_foo\\(char\\);\r\n\[\t \]*\\(Local at.*local\\.cc:\[0-9\]*\\)\r\n\}.*$gdb_prompt $" { xpass "ptype Local (old aCC)" }
+ -re ".*$gdb_prompt $" { fail "ptype Local" }
+ timeout { fail "(timeout) ptype Local" }
+}
+
+# DTS CLLbs14316 and CLLbs17058
+# coulter - I added a clause for HP's aCC compiler. We print out the type
+# as xx instead of const unsigned char, but we still have an expected failure
+# because of two reasons:
+# There is a number at the end of InnerLocal4 which should not be there,
+# DTS CLLbs14316
+# The line number for the class
+# setup_xfail "hppa*-*-*" CLLbs14316
+
+# ---
+# Pattern 1:
+# PASS
+# dwarf-2
+# 2.95.3, 2.96-rh, 3.0.4, 3.1, gcc-3_1-branch, HEAD
+#
+# Pattern 2:
+# PASS
+# stabs+
+# 2.95.3, 2.96-rh, 3.0.4, 3.1, gcc-3_1-branch, HEAD
+#
+# Pattern 3:
+# Old hppa pattern.
+#
+# Pattern 4:
+# Old hppa pattern.
+#
+# chastain 2002-05-27
+
+send_gdb "ptype InnerLocal\n"
+gdb_expect {
+ -re "type = class InnerLocal \{\[\r\n\t \]*public:\[\r\n\t \]*char ilc;\[\r\n\t \]*int \\* *ip;\[\r\n\t \]*(InnerLocal::|)NestedInnerLocal nest1;\[\r\n\t \]*int il_foo\\((unsigned char const|const unsigned char) *&\\);\[\r\n\t \]*\}.*$gdb_prompt $" { pass "ptype InnerLocal (pattern 1)" }
+ -re "type = class InnerLocal \{\[\r\n\t \]*public:\[\r\n\t \]*char ilc;\[\r\n\t \]*int \\* *ip;\[\r\n\t \]*(InnerLocal::|)NestedInnerLocal nest1;\[\r\n\t \]*InnerLocal *& operator *=\\((main${sep}::|)InnerLocal const *&\\);\[\r\n\t \]*InnerLocal\\((main${sep}::|)InnerLocal const *&\\);\[\r\n\t \]*InnerLocal\\((void|)\\);\[\r\n\t \]*int il_foo\\(unsigned char const *&\\);\[\r\n\t \]*\}.*$gdb_prompt $" { pass "ptype InnerLocal (pattern 2)" }
+ -re "type = class InnerLocal \{\r\n\[\t \]*public:\r\n\[\t \]*char ilc;\r\n\[\t \]*int \\*ip;\r\n\[\t \]*InnerLocal::NestedInnerLocal nest1;\r\n\r\n\[\t \]*.int il_foo\\(unsigned char const &\\);\r\n\[\t \]*\}\[\t \]*\\(Local at.*local\\.cc:36\\).*$gdb_prompt $" { pass "ptype InnerLocal (old HP aCC)" }
+ -re "type = class InnerLocal \{\r\n\[\t \]*public:\r\n\[\t \]*char ilc;\r\n\[\t \]*int \\*ip;\r\n\[\t \]*class InnerLocal4::NestedInnerLocal nest1;\r\n\r\n\[\t \]*int il_foo\\(unsigned char const &\\);\r\n\[\t \]*\\(Local at.*local\.cc:\[0-9\]+\\)\r\n\}.*$gdb_prompt $" { pass "ptype InnerLocal (old HP aCC)" }
+ -re ".*$gdb_prompt $" { fail "ptype InnerLocal" }
+ timeout { fail "(timeout) ptype InnerLocal" }
+}
+
+#---
+# Pattern 1:
+# PASS
+# dwarf-2
+# gcc 2.95.3, 2.96-rh, 3.0.4, gcc-3_1-branch, HEAD
+#
+# Pattern 2:
+# PASS
+# stabs+
+# gcc 2.95.3, 2.96-rh, 3.0.4, gcc-3_1-branch, HEAD
+#
+# chastain 2002-04-08
+
+send_gdb "ptype NestedInnerLocal\n"
+gdb_expect {
+ -re "type = class NestedInnerLocal \{\[\r\n\t \]*public:\[\r\n\t \]*int nil;\[\r\n\t \]*int nil_foo\\(int\\);\[\r\n\t \]*\}.*$gdb_prompt $" { pass "ptype NestedInnerLocal" }
+ -re "type = class NestedInnerLocal \{\[\r\n\t \]*public:\[\r\n\t \]*int nil;\[\r\n\t \]*NestedInnerLocal *& *operator *= *\\((main${sep}::|)InnerLocal::NestedInnerLocal const *&\\);\[\r\n\t \]*NestedInnerLocal\\((main${sep}::|)InnerLocal::NestedInnerLocal const *&\\);\[\r\n\t \]*NestedInnerLocal\\((void|)\\);\[\r\n\t \]*int nil_foo\\(int\\);\[\r\n\t \]*\}.*$gdb_prompt $" { pass "ptype NestedInnerLocal" }
+ -re ".*$gdb_prompt $" { fail "ptype NestedInnerLocal" }
+ timeout { fail "(timeout) ptype NestedInnerLocal" }
+}
+
+# gdb incorrectly interprets the NestedInnerLocal in
+# InnerLocal::NestedInnerLocal as field name instead of a type name;
+# See CLLbs14784.
+
+#---
+# Pattern 3:
+# FAIL
+# The comment above, about CLLbs14784, is still correct.
+# dwarf-2
+# gcc 2.95.3, 2.96-rh, 3.0.4, gcc-3_1-branch, HEAD
+# stabs+
+# gcc 2.95.3, 2.96-rh, 3.0.4, gcc-3_1-branch, HEAD
+#
+# chastain 2002-04-08
+
+send_gdb "ptype InnerLocal::NestedInnerLocal\n"
+gdb_expect {
+ -re "type = class InnerLocal::NestedInnerLocal \{\[\r\n\t \]*public:\[\r\n\t \]*int nil;\[\r\n\t \]*int nil_foo\\(int\\);\[\r\n\t \]*\}.*$gdb_prompt $" { pass "ptype InnerLocal::NestedInnerLocal" }
+ -re "type = class InnerLocal::NestedInnerLocal \{\[\r\n\t \]*public:\[\r\n\t \]*int nil;\[\r\n\t \]*NestedInnerLocal *& *operator *= *\\((main${sep}::|)InnerLocal::NestedInnerLocal const *&\\);\[\r\n\t \]*NestedInnerLocal\\((main${sep}::|)InnerLocal::NestedInnerLocal const *&\\);\[\r\n\t \]*NestedInnerLocal\\((void|)\\);\[\r\n\t \]*int nil_foo\\(int\\);\[\r\n\t \]*\}.*$gdb_prompt $" { pass "ptype InnerLocal::NestedInnerLocal" }
+ -re "There is no field named NestedInnerLocal.*$gdb_prompt $" {
+ # setup_kfail "gdb/482"
+ fail "ptype InnerLocal::NestedInnerLocal (gdb/482)"
+ }
+ -re "No symbol .*NestedInnerLocal.* in current context.*$gdb_prompt $" { fail "ptype InnerLocal::NestedInnerLocal (bogus symbol lookup)" }
+ -re ".*$gdb_prompt $" { fail "ptype InnerLocal::NestedInnerLocal" }
+ timeout { fail "(timeout) ptype InnerLocal::NestedInnerLocal" }
+}
diff --git a/gdb/testsuite/gdb.c++/m-data.cc b/gdb/testsuite/gdb.c++/m-data.cc
new file mode 100644
index 00000000000..d9950274d7a
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/m-data.cc
@@ -0,0 +1,53 @@
+// 2002-05-13
+
+namespace __gnu_test
+{
+ enum region { oriental, egyptian, greek, etruscan, roman };
+
+ // Test one.
+ class gnu_obj_1
+ {
+ protected:
+ typedef region antiquities;
+ const bool test;
+ const int key1;
+ long key2;
+
+ antiquities value;
+
+ public:
+ gnu_obj_1(antiquities a, long l): test(true), key1(5), key2(l), value(a) {}
+ };
+
+ // Test two.
+ template<typename T>
+ class gnu_obj_2: public virtual gnu_obj_1
+ {
+ protected:
+ antiquities value_derived;
+
+ public:
+ gnu_obj_2(antiquities b): gnu_obj_1(oriental, 7), value_derived(b) { }
+ };
+
+ // Test three.
+ template<typename T>
+ class gnu_obj_3
+ {
+ protected:
+ typedef region antiquities;
+ gnu_obj_2<int> data;
+
+ public:
+ gnu_obj_3(antiquities b): data(etruscan) { }
+ };
+}
+
+int main()
+{
+ using namespace __gnu_test;
+ gnu_obj_1 test1(egyptian, 4589);
+ gnu_obj_2<long> test2(roman);
+ gnu_obj_3<long> test3(greek);
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.c++/m-data.exp b/gdb/testsuite/gdb.c++/m-data.exp
new file mode 100644
index 00000000000..ac6825870da
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/m-data.exp
@@ -0,0 +1,112 @@
+# Copyright 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Tests for member data
+# 2002-05-13 Benjamin Kosnik <bkoz@redhat.com>
+
+# This file is part of the gdb testsuite
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+if { [skip_cplus_tests] } { continue }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "m-data"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile} "c++"] {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+# One.
+gdb_test "break 50" "Breakpoint \[0-9\]*.*line 50\\."
+gdb_test "continue" "Continuing\\.\r\n\r\nBreakpoint.*at.*m-data\\.cc:50\r\n.*" "continue to 50"
+
+# simple object, const bool
+gdb_test "print test1.test" "\\$\[0-9\]* = true" "simple object, const bool"
+
+# simple object, const int
+gdb_test "print test1.key1" "\\$\[0-9\]* = 5" "simple object, const int"
+
+# simple object, long
+gdb_test "print test1.key2" "\\$\[0-9\]* = 4589" "simple object, long"
+
+# simple object, enum
+gdb_test "print test1.value" "\\$\[0-9\]* = egyptian" "simple object, enum"
+
+# Two.
+gdb_test "break 51" "Breakpoint \[0-9\]*.*line 51\\."
+gdb_test "continue" "Continuing\\.\r\n\r\nBreakpoint.*at.*m-data\\.cc:51\r\n.*" "continue to 51"
+
+# derived template object, base const bool
+gdb_test "print test2.test" "\\$\[0-9\]* = true" "derived template object, base const bool"
+
+# derived template object, base const int
+gdb_test "print test2.key1" "\\$\[0-9\]* = 5" "derived template object, base const int"
+
+# derived template object, base long
+gdb_test "print test2.key2" "\\$\[0-9\]* = 7" "derived template object, base long"
+
+# derived template object, base enum
+gdb_test "print test2.value" "\\$\[0-9\]* = oriental" "derived template object, base enum"
+
+# derived template object, enum
+gdb_test "print test2.value_derived" "\\$\[0-9\]* = roman" "derived template object, derived enum"
+
+# Three.
+gdb_test "break 52" "Breakpoint \[0-9\]*.*line 52\\."
+gdb_test "continue" "Continuing\\.\r\n\r\nBreakpoint.*at.*m-data\\.cc:52\r\n.*" "continue to 52"
+
+# template object, derived template data member's base const bool
+gdb_test "print test3.data.test" "\\$\[0-9\]* = true" "template object, const bool"
+
+# template object, derived template data member's base const int
+gdb_test "print test3.data.key1" "\\$\[0-9\]* = 5" "template object, const int"
+
+# template object, derived template data member's base long
+gdb_test "print test3.data.key2" "\\$\[0-9\]* = 7" "template object, long"
+
+# template object, derived template data member's base enum
+gdb_test "print test3.data.value" "\\$\[0-9\]* = oriental" "template object, base enum"
+
+# template object, derived template data member's enum
+gdb_test "print test3.data.value_derived" "\\$\[0-9]\* = etruscan" "template object, derived enum"
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.c++/m-static.cc b/gdb/testsuite/gdb.c++/m-static.cc
new file mode 100644
index 00000000000..24338014365
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/m-static.cc
@@ -0,0 +1,72 @@
+// 2002-05-13
+
+namespace __gnu_test
+{
+ enum region { oriental, egyptian, greek, etruscan, roman };
+
+ // Test one.
+ class gnu_obj_1
+ {
+ protected:
+ typedef region antiquities;
+ static const bool test = true;
+ static const int key1 = 5;
+ static long key2;
+
+ static antiquities value;
+
+ public:
+ gnu_obj_1(antiquities a, long l) {}
+ };
+
+ const bool gnu_obj_1::test;
+ const int gnu_obj_1::key1;
+ long gnu_obj_1::key2 = 77;
+ gnu_obj_1::antiquities gnu_obj_1::value = oriental;
+
+
+ // Test two.
+ template<typename T>
+ class gnu_obj_2: public virtual gnu_obj_1
+ {
+ public:
+ static antiquities value_derived;
+
+ public:
+ gnu_obj_2(antiquities b): gnu_obj_1(oriental, 7) { }
+ };
+
+ template<typename T>
+ typename gnu_obj_2<T>::antiquities gnu_obj_2<T>::value_derived = etruscan;
+
+ // Test three.
+ template<typename T>
+ class gnu_obj_3
+ {
+ public:
+ typedef region antiquities;
+ static gnu_obj_2<int> data;
+
+ public:
+ gnu_obj_3(antiquities b) { }
+ };
+
+ template<typename T>
+ gnu_obj_2<int> gnu_obj_3<T>::data(etruscan);
+}
+
+// instantiate templates explicitly so their static members will exist
+template class __gnu_test::gnu_obj_2<int>;
+template class __gnu_test::gnu_obj_2<long>;
+template class __gnu_test::gnu_obj_3<long>;
+
+int main()
+{
+ using namespace __gnu_test;
+
+ gnu_obj_1 test1(egyptian, 4589);
+ gnu_obj_2<long> test2(roman);
+ gnu_obj_3<long> test3(greek);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.c++/m-static.exp b/gdb/testsuite/gdb.c++/m-static.exp
new file mode 100644
index 00000000000..c05983b6538
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/m-static.exp
@@ -0,0 +1,112 @@
+# Copyright 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Tests for member static data
+# 2002-05-13 Benjamin Kosnik <bkoz@redhat.com>
+
+# This file is part of the gdb testsuite
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+if { [skip_cplus_tests] } { continue }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "m-static"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile} "c++"] {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+# One.
+gdb_test "break 68" "Breakpoint \[0-9\]*.*line 68\\."
+gdb_test "continue" "Continuing\\.\r\n\r\nBreakpoint.*at.*m-static\\.cc:68\r\n.*" "continue to 68"
+
+# simple object, static const bool
+gdb_test "print test1.test" "\\$\[0-9\]* = true" "simple object, static const bool"
+
+# simple object, static const int
+gdb_test "print test1.key1" "\\$\[0-9\]* = 5" "simple object, static const int"
+
+# simple object, static long
+gdb_test "print test1.key2" "\\$\[0-9\]* = 77" "simple object, static long"
+
+# simple object, static enum
+gdb_test "print test1.value" "\\$\[0-9\]* = oriental" "simple object, static enum"
+
+# Two.
+gdb_test "break 69" "Breakpoint \[0-9\]*.*line 69\\."
+gdb_test "continue" "Continuing\\.\r\n\r\nBreakpoint.*at.*m-static\\.cc:69\r\n.*" "continue to 69"
+
+# derived template object, base static const bool
+gdb_test "print test2.test" "\\$\[0-9\]* = true" "derived template object, base static const bool"
+
+# derived template object, base static const int
+gdb_test "print test2.key1" "\\$\[0-9\]* = 5" "derived template object, base static const int"
+
+# derived template object, base static long
+gdb_test "print test2.key2" "\\$\[0-9\]* = 77" "derived template object, base static long"
+
+# derived template object, base static enum
+gdb_test "print test2.value" "\\$\[0-9\].* = oriental" "derived template object, base static enum"
+
+# derived template object, static enum
+gdb_test "print test2.value_derived" "\\$\[0-9\].* = etruscan" "derived template object, static enum"
+
+# Three.
+gdb_test "break 71" "Breakpoint \[0-9\]*.*line 71\\."
+gdb_test "continue" "Continuing\\.\r\n\r\nBreakpoint.*at.*m-static\\.cc:71\r\n.*" "continue to 71"
+
+# template object, static derived template data member's base static const bool
+gdb_test "print test3.data.test" "\\$\[0-9\].* = true" "template object, static const bool"
+
+# template object, static derived template data member's base static const int
+gdb_test "print test3.data.key1" "\\$\[0-9\].* = 5" "template object, static const int"
+
+# template object, static derived template data member's base static long
+gdb_test "print test3.data.key2" "\\$\[0-9\].* = 77" "template object, static long"
+
+# template object, static derived template data member's base static enum
+gdb_test "print test3.data.value" "\\$\[0-9\].* = oriental" "template object, static enum"
+
+# template object, static derived template data member's static enum
+gdb_test "print test3.data.value_derived" "\\$\[0-9\].* = etruscan" "template object, static derived enum"
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.c++/member-ptr.cc b/gdb/testsuite/gdb.c++/member-ptr.cc
new file mode 100644
index 00000000000..4beb92616d4
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/member-ptr.cc
@@ -0,0 +1,106 @@
+extern "C" {
+#include <stdio.h>
+}
+
+
+class A {
+public:
+ A();
+ int foo (int x);
+ int bar (int y);
+ virtual int baz (int z);
+ char c;
+ int j;
+ int jj;
+ static int s;
+};
+
+class B {
+public:
+ static int s;
+};
+
+int A::s = 10;
+int B::s = 20;
+
+A::A()
+{
+ c = 'x';
+ j = 5;
+}
+
+int A::foo (int dummy)
+{
+ j += 3;
+ return j + dummy;
+}
+
+int A::bar (int dummy)
+{
+ int r;
+ j += 13;
+ r = this->foo(15);
+ return r + j + 2 * dummy;
+}
+
+int A::baz (int dummy)
+{
+ int r;
+ j += 15;
+ r = this->foo(15);
+ return r + j + 12 * dummy;
+}
+
+int fum (int dummy)
+{
+ return 2 + 13 * dummy;
+}
+
+typedef int (A::*PMF)(int);
+
+typedef int A::*PMI;
+
+int main ()
+{
+ A a;
+ A * a_p;
+ PMF pmf;
+
+ PMF * pmf_p;
+ PMI pmi;
+
+ a.j = 121;
+ a.jj = 1331;
+
+ int k;
+
+ a_p = &a;
+
+ pmi = &A::j;
+ pmf = &A::bar;
+ pmf_p = &pmf;
+
+ pmi = NULL;
+
+ k = (a.*pmf)(3);
+
+ pmi = &A::jj;
+ pmf = &A::foo;
+ pmf_p = &pmf;
+
+ k = (a.*pmf)(4);
+
+ k = (a.**pmf_p)(5);
+
+ k = a.*pmi;
+
+
+ k = a.bar(2);
+
+ k += fum (4);
+
+ B b;
+
+ k += b.s;
+
+}
diff --git a/gdb/testsuite/gdb.c++/member-ptr.exp b/gdb/testsuite/gdb.c++/member-ptr.exp
new file mode 100644
index 00000000000..f21cd1506e7
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/member-ptr.exp
@@ -0,0 +1,549 @@
+# Copyright 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+# Tests for pointer-to-member support
+# Written by Satish Pai <pai@apollo.hp.com> 1997-08-19
+
+# This file is part of the gdb testsuite
+
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+if { [skip_cplus_tests] } { continue }
+
+#
+# test running programs
+#
+
+# Start with a fresh gdb
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+set prms_id 0
+set bug_id 0
+
+set testfile "member-ptr"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+
+if [get_compiler_info ${binfile} "c++"] {
+ return -1
+}
+
+# Nearly all of these tests fail when compiled with G++, so just give up
+# until GDB gets enhanced. -sts 1999-06-22
+
+if {$gcc_compiled} {
+ continue
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+send_gdb "break 83\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]*.*line 83\\.\r\n$gdb_prompt $" {
+ pass "set break at 83"
+ }
+ -re ".*$gdb_prompt $" { fail "set break at 83" }
+ timeout { fail "(timeout) set break at 83" }
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing\\.\r\n\r\nBreakpoint.*at.*member-ptr\\.cc:83\r\n83\[ \t]*pmi = NULL;\r\n$gdb_prompt $" {
+ pass "continue to 83"
+ }
+ -re ".*$gdb_prompt $" { fail "continue to 83" }
+ timeout { fail "(timeout) continue to 83" }
+}
+
+# ptype on pointer to data member
+
+send_gdb "ptype pmi\n"
+gdb_expect {
+ -re "type = int \\( A::\\*\\)\r\n$gdb_prompt $" {
+ pass "ptype pmi"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype pmi" }
+ timeout { fail "(timeout) ptype pmi" }
+}
+
+# print pointer to data member
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print pmi\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\(int \\( A::\\*\\)\\) &A::j\r\n$gdb_prompt $" {
+ pass "print pmi"
+ }
+ -re ".*$gdb_prompt $" { fail "print pmi" }
+ timeout { fail "(timeout) print pmi" }
+}
+
+
+# print dereferenced pointer to data member
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print a.*pmi\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 121\r\n$gdb_prompt $" {
+ pass "print a.*pmi"
+ }
+ -re ".*$gdb_prompt $" { fail "print a.*pmi" }
+ timeout { fail "(timeout) print a.*pmi" }
+}
+
+# print dereferenced pointer to data member
+# this time, dereferenced through a pointer
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print a_p->*pmi\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 121\r\n$gdb_prompt $" {
+ pass "print a->*pmi"
+ }
+ -re ".*$gdb_prompt $" { fail "print a->*pmi" }
+ timeout { fail "(timeout) print a->*pmi" }
+}
+
+
+# set the pointer to data member
+
+send_gdb "set var pmi = &A::jj\n"
+gdb_expect {
+ -re "$gdb_prompt $" {
+ pass "set var (not really a pass)"
+ }
+ timeout { fail "(timeout) " }
+}
+
+# Now print the pointer again
+
+send_gdb "print pmi\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\(int \\( A::\\*\\)\\) &A::jj\r\n$gdb_prompt $" {
+ pass "print pmi after setting"
+ }
+ -re ".*$gdb_prompt $" { fail "print pmi after setting" }
+ timeout { fail "(timeout) print pmi after setting" }
+}
+
+# print dereferenced pointer to data member again
+
+send_gdb "print a.*pmi\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 1331\r\n$gdb_prompt $" {
+ pass "print a.*pmi after setting"
+ }
+ -re ".*$gdb_prompt $" { fail "print a.*pmi after setting" }
+ timeout { fail "(timeout) print a.*pmi after setting" }
+}
+
+# set the pointer to data member back to A::j
+
+send_gdb "set var pmi = &A::j\n"
+gdb_expect {
+ -re "$gdb_prompt $" {
+ pass "set var back to A::j (not really a pass)"
+ }
+ timeout { fail "(timeout) set var pmi" }
+}
+
+# print dereferenced pointer to data member yet again (extra check, why not)
+
+send_gdb "print a.*pmi\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 121\r\n$gdb_prompt $" {
+ pass "print a.*pmi after resetting"
+ }
+ -re ".*$gdb_prompt $" { fail "print a.*pmi after resetting" }
+ timeout { fail "(timeout) print a.*pmi after resetting" }
+}
+
+# Set the data member pointed to.
+
+send_gdb "print a.*pmi = 33\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 33\r\n$gdb_prompt $" {
+ pass "print command to set"
+ }
+ -re ".*$gdb_prompt $" { fail "print command to set" }
+ timeout { fail "(timeout) print command to set" }
+}
+
+# Now check that the data really was changed
+send_gdb "print a.*pmi\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 33\r\n$gdb_prompt $" {
+ pass "print a.*pmi after setting member pointed to"
+ }
+ -re ".*$gdb_prompt $" { fail "print a.*pmi after setting member pointed to" }
+ timeout { fail "(timeout) print a.*pmi after setting member pointed to" }
+}
+
+# Double-check by printing a.
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print a\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \{c = 120 'x', j = 33, jj = 1331, static s = 10, Virtual table at $hex\}\r\n$gdb_prompt $" {
+ pass "print a after setting member pointed to by pmi"
+ }
+ -re ".*$gdb_prompt $" { fail "print a after setting member pointed to by pmi" }
+ timeout { fail "(timeout) print a after setting member pointed to by pmi" }
+}
+
+
+# Set the data member pointed to, using ->*
+
+send_gdb "print a_p->*pmi = 44\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 44\r\n$gdb_prompt $" {
+ pass "print command to set (->)"
+ }
+ -re ".*$gdb_prompt $" { fail "print command to set (->)" }
+ timeout { fail "(timeout) print command to set (->)" }
+}
+
+# Now check that the data really was changed
+send_gdb "print a_p->*pmi\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 44\r\n$gdb_prompt $" {
+ pass "print a_p->*pmi after setting member pointed to"
+ }
+ -re ".*$gdb_prompt $" { fail "print a_p->*pmi after setting member pointed to" }
+ timeout { fail "(timeout) print a_p->*pmi after setting member pointed to" }
+}
+
+# Double-check by printing a.
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print a\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \{c = 120 'x', j = 44, jj = 1331, static s = 10, Virtual table at $hex\}\r\n$gdb_prompt $" {
+ pass "print a after setting member pointed to by pmi (->) "
+ }
+ -re ".*$gdb_prompt $" { fail "print a after setting member pointed to by pmi (->) " }
+ timeout { fail "(timeout) print a after setting member pointed to by pmi (->) " }
+}
+
+
+# Do a ptype on the dereferenced pointer to member
+# pai/1997-08-20 Doesn't work
+
+# send_gdb "ptype a.*pmi\n"
+# gdb_expect {
+# -re "type = int\r\n$gdb_prompt $" {
+# pass "ptype a.*pmi"
+# }
+# -re ".*$gdb_prompt $" { fail "ptype a.*pmi" }
+# timeout { fail "(timeout) ptype a.*pmi" }
+#}
+
+# Try to dereference the pointer to data member without any object
+
+send_gdb "print *pmi\n"
+gdb_expect {
+ -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
+ pass "attempt to print ptr to member without object"
+ }
+ -re ".*$gdb_prompt $" { fail "attempt to print ptr to member without object" }
+ timeout { fail "(timeout) attempt to print ptr to member without object" }
+}
+
+# Try to ptype a dereference of the pointer to data member without any object
+
+send_gdb "ptype *pmi\n"
+gdb_expect {
+ -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
+ pass "attempt to ptype ptr to member without object"
+ }
+ -re ".*$gdb_prompt $" { fail "attempt to ptype ptr to member without object" }
+ timeout { fail "(timeout) attempt to ptype ptr to member without object" }
+}
+
+# Ptype a pointer to a method.
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "ptype pmf\n"
+gdb_expect {
+ -re "type = int \\( A::\\*\\)\\(\\.\\.\\.\\)\r\n$gdb_prompt $" {
+ pass "ptype pmf"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype pmf" }
+ timeout { fail "(timeout) ptype pmf" }
+}
+
+# print a pointer to a method
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print pmf\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\(int \\( A::\\*\\)\\(\\.\\.\\.\\)\\) \\?\\? <not supported with HP aCC>\r\n$gdb_prompt $" {
+ pass "print pmf"
+ }
+ -re ".*$gdb_prompt $" { fail "print pmf" }
+ timeout { fail "(timeout) print pmf" }
+}
+
+
+# Ptype a pointer to a pointer to a method
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "ptype pmf_p\n"
+gdb_expect {
+ -re "type = int \\( A::\\*\\*\\)\\(\\.\\.\\.\\)\r\n$gdb_prompt $" {
+ pass "ptype pmf_p"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype pmf_p" }
+ timeout { fail "(timeout) ptype pmf_p" }
+}
+
+# print a pointer to a pointer to a method
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print pmf_p\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\(int \\( A::\\*\\*\\)\\(\\.\\.\\.\\)\\) $hex\r\n$gdb_prompt $" {
+ pass "print pmf_p"
+ }
+ -re ".*$gdb_prompt $" { fail "print pmf_p" }
+ timeout { fail "(timeout) print pmf_p" }
+}
+
+# print dereferenced pointer to method
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print a.*pmf\n"
+gdb_expect {
+ -re "Pointers to methods not supported with HP aCC\r\n$gdb_prompt $" {
+ pass "print a.*pmf (known aCC limitation)"
+ }
+ -re ".*$gdb_prompt $" { fail "print a.*pmf" }
+ timeout { fail "(timeout) print a.*pmf" }
+}
+
+# print dereferenced pointer to method, using ->*
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print a_p->*pmf\n"
+gdb_expect {
+ -re "Pointers to methods not supported with HP aCC\r\n$gdb_prompt $" {
+ pass "print a_p->*pmf (known aCC limitation)"
+ }
+ -re ".*$gdb_prompt $" { fail "print a_p->*pmf" }
+ timeout { fail "(timeout) print a_p->*pmf" }
+}
+
+# set the pointer to data member
+
+setup_xfail "hppa*-*-*"
+send_gdb "set var pmf = &A::foo\n"
+gdb_expect {
+ -re "Assignment to pointers to methods not implemented with HP aCC\r\n$gdb_prompt $" {
+ pass "set var pmf (known aCC limitation)"
+ }
+ -re ".*$gdb_prompt $" { fail "set var pmf" }
+ timeout { fail "(timeout) set var pmf" }
+}
+
+# Try to dereference the pointer to method without any object
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print *pmf\n"
+gdb_expect {
+ -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
+ pass "attempt to print ptr to method without object"
+ }
+ -re ".*$gdb_prompt $" { fail "attempt to print ptr to method without object" }
+ timeout { fail "(timeout) attempt to print ptr to method without object" }
+}
+
+# Try to ptype a dereference of the pointer to method without any object
+
+send_gdb "ptype *pmi\n"
+gdb_expect {
+ -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
+ pass "attempt to ptype ptr to member without object"
+ }
+ -re ".*$gdb_prompt $" { fail "attempt to ptype ptr to member without object" }
+ timeout { fail "(timeout) attempt to ptype ptr to member without object" }
+}
+
+# Check cast of pointer to member to integer
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print (int) pmi\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 8\r\n$gdb_prompt $" {
+ pass "casting pmi to int"
+ }
+ -re ".*$gdb_prompt $" { fail "casting pmi to int" }
+ timeout { fail "(timeout) casting pmi to int" }
+}
+
+# Check cast of pointer to method to integer
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print (int) pmf\n"
+gdb_expect {
+ -re "Pointers to methods not supported with HP aCC\r\n$gdb_prompt $" {
+ pass "casting pmf to int (known aCC limitation)"
+ }
+ -re ".*$gdb_prompt $" { fail "casting pmf to int" }
+ timeout { fail "(timeout) casting pmf to int" }
+}
+
+# Try to invoke a function through a pointer to data member
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print (a.*pmi)(3)\n"
+gdb_expect {
+ -re "Not implemented: function invocation through pointer to method with HP aCC\r\n$gdb_prompt $" {
+ pass "print (a.*pmi)(3) -- error message should be different"
+ }
+ -re ".*$gdb_prompt $" { fail "print (a.*pmi)(3)" }
+ timeout { fail "(timeout) print (a.*pmi)(3)" }
+}
+
+# Try to invoke a function through a pointer to a method
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print (a.*pmf)(3)\n"
+gdb_expect {
+ -re "Not implemented: function invocation through pointer to method with HP aCC\r\n$gdb_prompt $" {
+ pass "print (a.*pmi)(3) -- known aCC limitation"
+ }
+ -re ".*$gdb_prompt $" { fail "print (a.*pmf)(3)" }
+ timeout { fail "(timeout) print (a.*pmf)(3)" }
+}
+
+
+# Go past assignment of NULL to pmi
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "next\n"
+gdb_expect {
+ -re "\r\n85\[ \t\]*k = \\(a.\\*pmf\\)\\(3\\);\r\n$gdb_prompt $" {
+ pass "next past 83"
+ }
+ -re ".*$gdb_prompt $" { fail "next past 83" }
+ timeout { fail "(timeout) next past 83" }
+}
+
+#send_gdb "print pmi\n"
+#gdb_expect {
+# -re "Attempted dereference of null pointer-to-member\r\n$gdb_prompt $" {
+# pass ""
+# }
+# -re ".*$gdb_prompt $" { fail "" }
+# timeout { fail "(timeout) " }
+#}
+
+# Dereference the null pointer to member
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print a.*pmi\n"
+gdb_expect {
+ -re "Attempted dereference of null pointer-to-member\r\n$gdb_prompt $" {
+ pass "print a.*NULL"
+ }
+ -re ".*$gdb_prompt $" { fail "print a.*NULL" }
+ timeout { fail "(timeout) print a.*NULL" }
+}
+
+
+# Go to another part of the program
+send_gdb "break 91\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]*.*line 91\\.\r\n$gdb_prompt $" {
+ pass "set break at 91"
+ }
+ -re ".*$gdb_prompt $" { fail "set break at 91" }
+ timeout { fail "(timeout) set break at 91" }
+}
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing\\.\r\n\r\nBreakpoint.*at.*member-ptr\\.cc:91\r\n91\[ \t]*k = \\(a.\\*pmf\\)\\(4\\);\r\n$gdb_prompt $" {
+ pass "continue to 91"
+ }
+ -re ".*$gdb_prompt $" { fail "continue to 91" }
+ timeout { fail "(timeout) continue to 91" }
+}
+
+
+# Now check again that pmi works even when not set to
+# something that's at the beginning of the object
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print pmi\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\(int \\( A::\\*\\)\\) &A::jj\r\n$gdb_prompt $" {
+ pass "print pmi (2)"
+ }
+ -re ".*$gdb_prompt $" { fail "print pmi (2)" }
+ timeout { fail "(timeout) print pmi (2)" }
+}
+
+
+# print dereferenced pointer to data member
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print a.*pmi\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 1331\r\n$gdb_prompt $" {
+ pass "print a.*pmi (2)"
+ }
+ -re ".*$gdb_prompt $" { fail "print a.*pmi (2)" }
+ timeout { fail "(timeout) print a.*pmi (2)" }
+}
+
+# print dereferenced pointer to data member
+# this time, dereferenced through a pointer
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "print a_p->*pmi\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 1331\r\n$gdb_prompt $" {
+ pass "print a->*pmi"
+ }
+ -re ".*$gdb_prompt $" { fail "print a->*pmi (2)" }
+ timeout { fail "(timeout) print a->*pmi (2)" }
+}
+
+
+# p a.*pmf - fail
+
+# p pmi
+
+# p a.*pmi
+
diff --git a/gdb/testsuite/gdb.c++/method.cc b/gdb/testsuite/gdb.c++/method.cc
new file mode 100644
index 00000000000..949b027a02e
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/method.cc
@@ -0,0 +1,80 @@
+// Class funk has a constructor and an ordinary method
+// Test for CHFts23426
+
+class funk
+{
+public:
+ funk();
+ void getFunky(int a, int b);
+ int data_;
+};
+
+funk::funk()
+ : data_(33)
+{
+}
+
+void funk::getFunky(int a, int b)
+{
+ int res;
+ res = a + b - data_;
+ data_ = res;
+}
+
+// Class A has const and volatile methods
+
+class A {
+public:
+ int x;
+ int y;
+ int foo (int arg);
+ int bar (int arg) const;
+ int baz (int arg, char c) volatile;
+ int qux (int arg, float f) const volatile;
+};
+
+int A::foo (int arg)
+{
+ x += arg;
+ return arg *2;
+}
+
+int A::bar (int arg) const
+{
+ return arg + 2 * x;
+}
+
+int A::baz (int arg, char c) volatile
+{
+ return arg - 2 * x + c;
+}
+
+int A::qux (int arg, float f) const volatile
+{
+ if (f > 0)
+ return 2 * arg - x;
+ else
+ return 2 * arg + x;
+}
+
+
+int main()
+{
+ A a;
+ int k;
+
+ k = 10;
+ a.x = k * 2;
+
+ k = a.foo(13);
+
+ k += a.bar(15);
+
+ // Test for CHFts23426 follows
+ funk f;
+ f.getFunky(1, 2);
+ return 0;
+}
+
+
+
diff --git a/gdb/testsuite/gdb.c++/method.exp b/gdb/testsuite/gdb.c++/method.exp
new file mode 100644
index 00000000000..a085b14cdcc
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/method.exp
@@ -0,0 +1,194 @@
+# Copyright 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# tests for misc. C++ method stuff
+# Written by Satish Pai <pai@apollo.hp.com> 1997-07-08
+
+# This file is part of the gdb testsuite
+
+# This tests:
+# 0. method arguments are correct
+# 1. access to class data members inside method scopes
+# 2. correct param types for methods in ptype.
+# 3. const and volatile methods
+
+# (#0 and #1 above relate to an HP specific problem -- GDB must correctly
+# integrate FPARAM symbols in HP debug info into the local var list
+# for the function or method's block.)
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "method"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info $binfile "c++"] {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+gdb_test "break A::foo" \
+ "Breakpoint \[0-9\]* at $hex.*file .*method.cc, line 38\\."
+
+gdb_test "continue" \
+ "Continuing\\.\r\n\r\nBreakpoint \[0-9\]*, A::foo(\\(int\\)|) \\(this=$hex, arg=13\\) at .*method\\.cc:38\r\n38\[\t \]*x \\+= arg;" \
+ "continue to A::foo"
+
+# Check ability to access this-relative stuff.
+
+gdb_test "print x" \
+ "\\$\[0-9\]* = 20" \
+ "print x in A::foo"
+
+# Check access to this pointer
+
+gdb_test "print this" \
+ "\\$\[0-9\]* = \\((class |)A *\\* *(const|)\\) $hex" \
+ "print this in A::foo"
+
+# Now do everything over again for A::bar, because sometimes processing one method
+# (the first one) is fine, but the second one's debug info gets munged beyond recognition.
+
+gdb_test "break A::bar" \
+ "Breakpoint \[0-9\]* at $hex.*file .*method.cc, line 44\\."
+
+gdb_test "continue" \
+ "Continuing\\.\r\n\r\nBreakpoint \[0-9\]*, A::bar(\\(int\\) const|) \\(this=$hex, arg=15\\) at .*method\\.cc:44\r\n44\[\t \]*return arg \\+ 2 \\* x;" \
+ "continue to A::bar"
+
+# Check ability to access this-relative stuff.
+
+gdb_test "print x" \
+ "\\$\[0-9\]* = 33" \
+ "print x in A::bar"
+
+# Check access to this pointer
+
+get_debug_format
+
+send_gdb "print this\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\(const (class |)A *\\* *(const|)\\) $hex\r\n$gdb_prompt $" {
+ pass "print this in A::bar"
+ }
+ -re "\\$\[0-9\]* = \\((class |)A *\\* *(const|)\\) $hex\r\n$gdb_prompt $" {
+ # gcc versions up to 3.0.4 with -gstabs+ do not emit "const" indicators,
+ # so the output is "A *". It should be "const A *" or "const A * const".
+ setup_xfail_format "stabs"
+ fail "print this in A::bar (missing const)"
+ }
+ -re "\\$\[0-9\]* = \\(const (class |)\{\\.\\.\\.\} *\\* *(const|)\\) $hex\r\n$gdb_prompt $" {
+ # gcc versions gcc-3_1-branch%20020404 and HEAD%20020404 with -gstabs+
+ # produce good stabs, but gdb prints "const class {...} *" const.
+ # This is PR gdb/277.
+ # setup_kfail "gdb/277"
+ fail "print this in A::bar (gdb/277)"
+ }
+ -re ".*$gdb_prompt $" { fail "print this in A::bar" }
+ timeout { fail "(timeout) print this in A::bar" }
+}
+
+# Check again with funk::getFunky (this is the original test case
+# for CHFts23426); sometimes having a constructor with no arguments
+# will nuke the debug info read in for other methods in the class.
+
+gdb_test "break 21" \
+ "Breakpoint \[0-9\]* at $hex.*file .*method.cc, line 21\\."
+
+gdb_test "continue" \
+ "Continuing\\.\r\n\r\nBreakpoint \[0-9\]*, funk::getFunky(\\(int, int\\)|) \\(this=$hex, a=1, b=2\\) at .*method\\.cc:21\r\n21\[\t \]*data_ = res;" \
+ "continue to 21"
+
+# Check ability to access this-relative stuff.
+
+gdb_test "print data_" \
+ "\\$\[0-9\]* = 33" \
+ "print data_ in funk::getFunky"
+
+# Check access to this pointer
+
+gdb_test "print this" \
+ "\\$\[0-9\]* = \\((class |)funk *\\* *(const|)\\) $hex" \
+ "print this in funk::getFunky"
+
+# Check access to local variable
+
+gdb_test "print res" \
+ "\\$\[0-9\]* = -30" \
+ "print res in funk::getFunky"
+
+# Check ptype of class -- should show const/volatile methods
+
+send_gdb "ptype A\n"
+gdb_expect {
+ -re "type = class A \{\r\n\[ \]*public:\r\n\[ \]*int x;\r\n\[ \]*int y;\r\n\r\n\[ \]*int foo\\(int\\);\r\n\[ \]*int bar\\(int\\) const;\r\n\[ \]*int baz\\(int, char\\) volatile;\r\n\[ \]*int qux\\(int, float\\) (const volatile|volatile const);\r\n\}\r\n$gdb_prompt $" {
+ pass "ptype A"
+ }
+ -re "type = class A \{\r\n\[ \]*public:\r\n\[ \]*int x;\r\n\[ \]*int y;\r\n\r\n\[ \]*A & operator=\\(A const ?&\\);\r\n\[ \]*A\\(A const ?&\\);\r\n\[ \]*A\\((void|)\\);\r\n\[ \]*int foo\\(int\\);\r\n\[ \]*int bar\\(int\\) const;\r\n\[ \]*int baz\\(int, char\\) volatile;\r\n\[ \]*int qux\\(int, float\\) (const volatile|volatile const);\r\n\}\r\n$gdb_prompt $" {
+ pass "ptype A"
+ }
+ -re "type = class A \{\r\n\[ \]*public:\r\n\[ \]*int x;\r\n\[ \]*int y;\r\n\r\n\[ \]*int foo\\(int\\);\r\n\[ \]*int bar\\(int\\) const;\r\n\[ \]*int baz\\(int, char\\);\r\n\[ \]*int qux\\(int, float\\) const;\r\n\}\r\n$gdb_prompt $" {
+ pass "ptype A (HP aCC bug -- volatile not indicated)"
+ }
+ -re "type = class A \{\r\n\[ \]*public:\r\n\[ \]*int x;\r\n\[ \]*int y;\r\n\r\n\[ \]*int foo\\(int\\);\r\n\[ \]*int bar\\(int\\) const;\r\n\[ \]*int baz\\(int, char\\) volatile;\r\n\[ \]*int qux\\(int, float\\) const volatile;\r\n\}\r\n$gdb_prompt $" {
+ pass "ptype A"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype A" }
+ timeout { fail "(timeout) ptype A" }
+}
+
+send_gdb "cont\n"
+gdb_expect {
+ -re "Continuing.\r\n\r\nProgram exited normally.*$gdb_prompt $" {
+ pass "finish program"
+ }
+ -re "Continuing.* EXIT code 0.*Program exited normally.*$gdb_prompt $" {
+ pass "finish program (exit wrapper)"
+ }
+ -re ".*$gdb_prompt $" { fail "finish program" }
+ default:{ fail "finish program (timeout)" }
+}
+
diff --git a/gdb/testsuite/gdb.c++/misc.cc b/gdb/testsuite/gdb.c++/misc.cc
new file mode 100644
index 00000000000..286c02bc6df
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/misc.cc
@@ -0,0 +1,587 @@
+// Test various -*- C++ -*- things.
+
+// ====================== basic C++ types =======================
+bool v_bool;
+bool v_bool_array[2];
+
+typedef struct fleep fleep;
+struct fleep { int a; } s;
+
+// ====================== simple class structures =======================
+
+struct default_public_struct {
+ // defaults to public:
+ int a;
+ int b;
+};
+
+struct explicit_public_struct {
+ public:
+ int a;
+ int b;
+};
+
+struct protected_struct {
+ protected:
+ int a;
+ int b;
+};
+
+struct private_struct {
+ private:
+ int a;
+ int b;
+};
+
+struct mixed_protection_struct {
+ public:
+ int a;
+ int b;
+ private:
+ int c;
+ int d;
+ protected:
+ int e;
+ int f;
+ public:
+ int g;
+ private:
+ int h;
+ protected:
+ int i;
+};
+
+class public_class {
+ public:
+ int a;
+ int b;
+};
+
+class protected_class {
+ protected:
+ int a;
+ int b;
+};
+
+class default_private_class {
+ // defaults to private:
+ int a;
+ int b;
+};
+
+class explicit_private_class {
+ private:
+ int a;
+ int b;
+};
+
+class mixed_protection_class {
+ public:
+ int a;
+ int b;
+ private:
+ int c;
+ int d;
+ protected:
+ int e;
+ int f;
+ public:
+ int g;
+ private:
+ int h;
+ protected:
+ int i;
+};
+
+class const_vol_method_class {
+public:
+ int a;
+ int b;
+ int foo (int &) const;
+ int bar (int &) volatile;
+ int baz (int &) const volatile;
+};
+
+int const_vol_method_class::foo (int & ir) const
+{
+ return ir + 3;
+}
+int const_vol_method_class::bar (int & ir) volatile
+{
+ return ir + 4;
+}
+int const_vol_method_class::baz (int & ir) const volatile
+{
+ return ir + 5;
+}
+
+// ========================= simple inheritance ==========================
+
+class A {
+ public:
+ int a;
+ int x;
+};
+
+A g_A;
+
+class B : public A {
+ public:
+ int b;
+ int x;
+};
+
+B g_B;
+
+class C : public A {
+ public:
+ int c;
+ int x;
+};
+
+C g_C;
+
+class D : public B, public C {
+ public:
+ int d;
+ int x;
+};
+
+D g_D;
+
+class E : public D {
+ public:
+ int e;
+ int x;
+};
+
+E g_E;
+
+class class_with_anon_union
+{
+ public:
+ int one;
+ union
+ {
+ int a;
+ long b;
+ };
+};
+
+class_with_anon_union g_anon_union;
+
+void inheritance2 (void)
+{
+}
+
+void inheritance1 (void)
+{
+ int ival;
+ int *intp;
+
+ // {A::a, A::x}
+
+ g_A.A::a = 1;
+ g_A.A::x = 2;
+
+ // {{A::a,A::x},B::b,B::x}
+
+ g_B.A::a = 3;
+ g_B.A::x = 4;
+ g_B.B::b = 5;
+ g_B.B::x = 6;
+
+ // {{A::a,A::x},C::c,C::x}
+
+ g_C.A::a = 7;
+ g_C.A::x = 8;
+ g_C.C::c = 9;
+ g_C.C::x = 10;
+
+ // {{{A::a,A::x},B::b,B::x},{{A::a,A::x},C::c,C::x},D::d,D::x}
+
+ // The following initialization code is non-portable, but allows us
+ // to initialize all members of g_D until we can fill in the missing
+ // initialization code with legal C++ code.
+
+ for (intp = (int *) &g_D, ival = 11;
+ intp < ((int *) &g_D + sizeof (g_D) / sizeof (int));
+ intp++, ival++)
+ {
+ *intp = ival;
+ }
+
+ // Overlay the nonportable initialization with legal initialization.
+
+ // ????? = 11; (g_D.A::a = 11; is ambiguous)
+ // ????? = 12; (g_D.A::x = 12; is ambiguous)
+/* djb 6-3-2000
+
+ This should take care of it. Rather than try to initialize using an ambiguous
+ construct, use 2 unambiguous ones for each. Since the ambiguous a/x member is
+ coming from C, and B, initialize D's C::a, and B::a, and D's C::x and B::x.
+ */
+ g_D.C::a = 15;
+ g_D.C::x = 12;
+ g_D.B::a = 11;
+ g_D.B::x = 12;
+ g_D.B::b = 13;
+ g_D.B::x = 14;
+ // ????? = 15;
+ // ????? = 16;
+ g_D.C::c = 17;
+ g_D.C::x = 18;
+ g_D.D::d = 19;
+ g_D.D::x = 20;
+
+
+ // {{{{A::a,A::x},B::b,B::x},{{A::a,A::x},C::c,C::x},D::d,D::x}},E::e,E::x}
+
+ // The following initialization code is non-portable, but allows us
+ // to initialize all members of g_D until we can fill in the missing
+ // initialization code with legal C++ code.
+
+ for (intp = (int *) &g_E, ival = 21;
+ intp < ((int *) &g_E + sizeof (g_E) / sizeof (int));
+ intp++, ival++)
+ {
+ *intp = ival;
+ }
+
+ // Overlay the nonportable initialization with legal initialization.
+
+ // ????? = 21; (g_E.A::a = 21; is ambiguous)
+ // ????? = 22; (g_E.A::x = 22; is ambiguous)
+ g_E.B::b = 23;
+ g_E.B::x = 24;
+ // ????? = 25;
+ // ????? = 26;
+ g_E.C::c = 27;
+ g_E.C::x = 28;
+ g_E.D::d = 29;
+ g_E.D::x = 30;
+ g_E.E::e = 31;
+ g_E.E::x = 32;
+
+ g_anon_union.one = 1;
+ g_anon_union.a = 2;
+
+ inheritance2 ();
+}
+
+// ======================== static member functions =====================
+
+class Static {
+public:
+ static void ii(int, int);
+};
+void Static::ii (int, int) { }
+
+// ======================== virtual base classes=========================
+
+class vA {
+ public:
+ int va;
+ int vx;
+};
+
+vA g_vA;
+
+class vB : public virtual vA {
+ public:
+ int vb;
+ int vx;
+};
+
+vB g_vB;
+
+class vC : public virtual vA {
+ public:
+ int vc;
+ int vx;
+};
+
+vC g_vC;
+
+class vD : public virtual vB, public virtual vC {
+ public:
+ int vd;
+ int vx;
+};
+
+vD g_vD;
+
+class vE : public virtual vD {
+ public:
+ int ve;
+ int vx;
+};
+
+vE g_vE;
+
+void inheritance4 (void)
+{
+}
+
+void inheritance3 (void)
+{
+ int ival;
+ int *intp;
+
+ // {vA::va, vA::vx}
+
+ g_vA.vA::va = 1;
+ g_vA.vA::vx = 2;
+
+ // {{vA::va, vA::vx}, vB::vb, vB::vx}
+
+ g_vB.vA::va = 3;
+ g_vB.vA::vx = 4;
+ g_vB.vB::vb = 5;
+ g_vB.vB::vx = 6;
+
+ // {{vA::va, vA::vx}, vC::vc, vC::vx}
+
+ g_vC.vA::va = 7;
+ g_vC.vA::vx = 8;
+ g_vC.vC::vc = 9;
+ g_vC.vC::vx = 10;
+
+ // {{{{vA::va, vA::vx}, vB::vb, vB::vx}, vC::vc, vC::vx}, vD::vd,vD::vx}
+
+ g_vD.vA::va = 11;
+ g_vD.vA::vx = 12;
+ g_vD.vB::vb = 13;
+ g_vD.vB::vx = 14;
+ g_vD.vC::vc = 15;
+ g_vD.vC::vx = 16;
+ g_vD.vD::vd = 17;
+ g_vD.vD::vx = 18;
+
+
+ // {{{{{vA::va,vA::vx},vB::vb,vB::vx},vC::vc,vC::vx},vD::vd,vD::vx},vE::ve,vE::vx}
+
+ g_vD.vA::va = 19;
+ g_vD.vA::vx = 20;
+ g_vD.vB::vb = 21;
+ g_vD.vB::vx = 22;
+ g_vD.vC::vc = 23;
+ g_vD.vC::vx = 24;
+ g_vD.vD::vd = 25;
+ g_vD.vD::vx = 26;
+ g_vE.vE::ve = 27;
+ g_vE.vE::vx = 28;
+
+ inheritance4 ();
+}
+
+// ======================================================================
+
+class Base1 {
+ public:
+ int x;
+ Base1(int i) { x = i; }
+};
+
+class Foo
+{
+ public:
+ int x;
+ int y;
+ static int st;
+ Foo (int i, int j) { x = i; y = j; }
+ int operator! ();
+ operator int ();
+ int times (int y);
+};
+
+class Bar : public Base1, public Foo {
+ public:
+ int z;
+ Bar (int i, int j, int k) : Base1 (10*k), Foo (i, j) { z = k; }
+};
+
+int Foo::operator! () { return !x; }
+
+int Foo::times (int y) { return x * y; }
+
+int Foo::st = 100;
+
+Foo::operator int() { return x; }
+
+Foo foo(10, 11);
+Bar bar(20, 21, 22);
+
+class ClassWithEnum {
+public:
+ enum PrivEnum { red, green, blue, yellow = 42 };
+ PrivEnum priv_enum;
+ int x;
+};
+
+void enums2 (void)
+{
+}
+
+/* classes.exp relies on statement order in this function for testing
+ enumeration fields. */
+
+void enums1 ()
+{
+ ClassWithEnum obj_with_enum;
+ obj_with_enum.priv_enum = ClassWithEnum::red;
+ obj_with_enum.x = 0;
+ enums2 ();
+ obj_with_enum.priv_enum = ClassWithEnum::green;
+}
+
+class ClassParam {
+public:
+ int Aptr_a (A *a) { return a->a; }
+ int Aptr_x (A *a) { return a->x; }
+ int Aref_a (A &a) { return a.a; }
+ int Aref_x (A &a) { return a.x; }
+ int Aval_a (A a) { return a.a; }
+ int Aval_x (A a) { return a.x; }
+};
+
+ClassParam class_param;
+
+class Contains_static_instance
+{
+ public:
+ int x;
+ int y;
+ Contains_static_instance (int i, int j) { x = i; y = j; }
+ static Contains_static_instance null;
+};
+
+Contains_static_instance Contains_static_instance::null(0,0);
+Contains_static_instance csi(10,20);
+
+class Contains_nested_static_instance
+{
+ public:
+ class Nested
+ {
+ public:
+ Nested(int i) : z(i) {}
+ int z;
+ static Contains_nested_static_instance xx;
+ };
+
+ Contains_nested_static_instance(int i, int j) : x(i), y(j) {}
+
+ int x;
+ int y;
+
+ static Contains_nested_static_instance null;
+ static Nested yy;
+};
+
+Contains_nested_static_instance Contains_nested_static_instance::null(0, 0);
+Contains_nested_static_instance::Nested Contains_nested_static_instance::yy(5);
+Contains_nested_static_instance
+ Contains_nested_static_instance::Nested::xx(1,2);
+Contains_nested_static_instance cnsi(30,40);
+
+typedef struct {
+ int one;
+ int two;
+} tagless_struct;
+tagless_struct v_tagless;
+
+/* Try to get the compiler to allocate a class in a register. */
+class small {
+ public:
+ int x;
+ int method ();
+};
+
+int
+small::method ()
+{
+ return x + 5;
+}
+
+void marker_reg1 () {}
+
+int
+register_class ()
+{
+ /* We don't call any methods for v, so gcc version cygnus-2.3.3-930220
+ might put this variable in a register. This is a lose, though, because
+ it means that GDB can't call any methods for that variable. */
+ register small v;
+
+ int i;
+
+ /* Perform a computation sufficiently complicated that optimizing compilers
+ won't optimized out the variable. If some compiler constant-folds this
+ whole loop, maybe using a parameter to this function here would help. */
+ v.x = 0;
+ for (i = 0; i < 13; ++i)
+ v.x += i;
+ --v.x; /* v.x is now 77 */
+ marker_reg1 ();
+ return v.x + 5;
+}
+
+void dummy()
+{
+ v_bool = true;
+ v_bool_array[0] = false;
+ v_bool_array[1] = v_bool;
+}
+
+void use_methods ()
+{
+ /* Refer to methods so that they don't get optimized away. */
+ int i;
+ i = class_param.Aptr_a (&g_A);
+ i = class_param.Aptr_x (&g_A);
+ i = class_param.Aref_a (g_A);
+ i = class_param.Aref_x (g_A);
+ i = class_param.Aval_a (g_A);
+ i = class_param.Aval_x (g_A);
+}
+
+
+int
+main()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ dummy();
+ inheritance1 ();
+ inheritance3 ();
+ enums1 ();
+ register_class ();
+
+ /* FIXME: pmi gets optimized out. Need to do some more computation with
+ it or something. (No one notices, because the test is xfail'd anyway,
+ but that probably won't always be true...). */
+ int Foo::* pmi = &Foo::y;
+
+ /* Make sure the AIX linker doesn't remove the variable. */
+ v_tagless.one = 5;
+
+ use_methods ();
+
+ return foo.*pmi;
+}
+
+/* Create an instance for some classes, otherwise they get optimized away. */
+
+default_public_struct default_public_s;
+explicit_public_struct explicit_public_s;
+protected_struct protected_s;
+private_struct private_s;
+mixed_protection_struct mixed_protection_s;
+public_class public_c;
+protected_class protected_c;
+default_private_class default_private_c;
+explicit_private_class explicit_private_c;
+mixed_protection_class mixed_protection_c;
diff --git a/gdb/testsuite/gdb.c++/misc.exp b/gdb/testsuite/gdb.c++/misc.exp
new file mode 100644
index 00000000000..a2d122fc69e
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/misc.exp
@@ -0,0 +1,159 @@
+# Copyright 1992, 1994, 1995, 1996, 1997, 1999, 2002 Free Software
+# Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "misc"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+#
+# Deduce language of main()
+#
+
+proc deduce_language_of_main {} {
+ global gdb_prompt
+
+ # See what language gdb thinks main() is, prior to reading full symbols.
+ # I think this fails for COFF targets.
+ send_gdb "show language\n"
+ gdb_expect {
+ -re ".* source language is \"auto; currently c\[+\]+\".*$gdb_prompt $" {
+ pass "deduced language is C++, before full symbols"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "source language not correct for C++ (psymtabs only)"
+ return
+ }
+ timeout {
+ fail "can't show language (timeout)"
+ return
+ }
+ }
+
+ runto_main
+
+ # See if our idea of the language has changed.
+
+ send_gdb "show language\n"
+ gdb_expect {
+ -re ".* source language is \"auto; currently c\[+\]+\".*$gdb_prompt $" {
+ pass "deduced language is C++, after full symbols"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "source language not correct for C++ (full symbols)"
+ return
+ }
+ timeout {
+ fail "can't show language (timeout)"
+ return
+ }
+ }
+}
+
+proc test_expr { args } {
+ if { [llength $args] % 2 } {
+ warning "an even # of arguments should be passed to test_expr"
+ }
+ set last_ent [expr [llength $args] - 1];
+ set testname [lindex $args $last_ent];
+ if [gdb_test [lindex $args 0] "" "$testname (setup)"] {
+ gdb_suppress_tests;
+ }
+ for {set x 1} {$x < $last_ent} {set x [expr $x + 2]} {
+ if [gdb_test [lindex $args $x] [lindex $args [expr $x + 1]] "$testname ([lindex $args $x])"] {
+ gdb_suppress_tests;
+ }
+ }
+ gdb_stop_suppressing_tests;
+}
+
+proc do_tests {} {
+ global prms_id
+ global bug_id
+ global subdir
+ global objdir
+ global srcdir
+ global binfile
+ global gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ deduce_language_of_main
+ # Check for fixes for PRs 8916 and 8630
+ gdb_test "print s.a" ".* = 0" "print s.a for foo struct (known gcc 2.7.2 and earlier bug)"
+}
+
+do_tests
+
+test_expr "set language c++" \
+ "print 1 == 1" "print.*\\$\[0-9\]* = true" \
+ "print 1 == 2" "print.*\\$\[0-9\]* = false" \
+ "print as bool"
+
+# Test bool type printing, etc.
+# Note: Language is already set to C++ above!
+gdb_test "print v_bool" "\\$\[0-9\]* = false" "print a bool var"
+
+# set a bool variable
+test_expr "set variable v_bool = true" \
+ "print v_bool" "\\$\[0-9\]* = true" \
+ "set a bool var"
+
+# next print an array of bool
+gdb_test "print v_bool_array" "\\$\[0-9\]* = \\{false, false\\}" "print a bool array"
+
+# set elements of a bool array
+test_expr "set variable v_bool_array\[1\] = true" \
+ "print v_bool_array" "\\$\[0-9\]* = \\{false, true\\}" \
+ "set a bool array elem"
+
+# bool constants
+gdb_test "print true" "\\$\[0-9\]* = true" "print true"
+gdb_test "print false" "\\$\[0-9\]* = false" "print false"
+
+# arithmetic conversions
+gdb_test "print 1 + true" "\\$\[0-9\]* = 2" "1 + true"
+gdb_test "print 3 + false" "\\$\[0-9\]* = 3" "3 + false"
+gdb_test "print 1 < 2 < 3" "\\$\[0-9\]* = true" "1 < 2 < 3"
+gdb_test "print 2 < 1 > 4" "\\$\[0-9\]* = false" "2 < 1 > 4"
+gdb_test "print (bool)43" "\\$\[0-9\]* = true" "(bool)43"
+gdb_test "print (bool)0" "\\$\[0-9\]* = false" "(bool)0"
+gdb_test "print (bool)17.93" "\\$\[0-9\]* = true" "(bool)17.93"
+gdb_test "print (bool)0.0" "\\$\[0-9\]* = false" "(bool)0.0"
+gdb_test "print (int)true" "\\$\[0-9\]* = 1" "(int)true"
+gdb_test "print (int)false" "\\$\[0-9\]* = 0" "(int)false"
diff --git a/gdb/testsuite/gdb.c++/namespace.cc b/gdb/testsuite/gdb.c++/namespace.cc
new file mode 100644
index 00000000000..7667266c278
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/namespace.cc
@@ -0,0 +1,103 @@
+namespace AAA {
+ char c;
+ int i;
+ int A_xyzq (int);
+ char xyzq (char);
+ class inA {
+ public:
+ int xx;
+ int fum (int);
+ };
+};
+
+int AAA::inA::fum (int i)
+{
+ return 10 + i;
+}
+
+namespace BBB {
+ char c;
+ int i;
+ int B_xyzq (int);
+ char xyzq (char);
+
+ namespace CCC {
+ char xyzq (char);
+ };
+
+ class Class {
+ public:
+ char xyzq (char);
+ int dummy;
+ };
+};
+
+int AAA::A_xyzq (int x)
+{
+ return 2 * x;
+}
+
+char AAA::xyzq (char c)
+{
+ return 'a';
+}
+
+
+int BBB::B_xyzq (int x)
+{
+ return 3 * x;
+}
+
+char BBB::xyzq (char c)
+{
+ return 'b';
+}
+
+char BBB::CCC::xyzq (char c)
+{
+ return 'z';
+}
+
+char BBB::Class::xyzq (char c)
+{
+ return 'o';
+}
+
+void marker1(void)
+{
+ return;
+}
+
+
+int main ()
+{
+ using AAA::inA;
+ char c1;
+
+ using namespace BBB;
+
+ c1 = xyzq ('x');
+ c1 = AAA::xyzq ('x');
+ c1 = BBB::CCC::xyzq ('m');
+
+ inA ina;
+
+ ina.xx = 33;
+
+ int y;
+
+ y = AAA::A_xyzq (33);
+ y += B_xyzq (44);
+
+ BBB::Class cl;
+
+ c1 = cl.xyzq('e');
+
+ marker1();
+
+}
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.c++/namespace.exp b/gdb/testsuite/gdb.c++/namespace.exp
new file mode 100644
index 00000000000..3e502c4b50a
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/namespace.exp
@@ -0,0 +1,188 @@
+# Copyright 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# tests for namespaces
+# Written by Satish Pai <pai@apollo.hp.com> 1997-07-23
+
+# This file is part of the gdb testsuite
+
+# Note: These tests are geared to the HP aCC compiler,
+# which has an idiosyncratic way of emitting debug info
+# for namespaces.
+# Note: As of 2000-06-03, these pass under g++ - djb
+
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+set prms_id 0
+set bug_id 0
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "namespace"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will a
+utomatically fail."
+}
+
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+if ![runto 'marker1'] then {
+ perror "couldn't run to marker1"
+ continue
+}
+
+gdb_test "up" ".*main.*" "up from marker1"
+
+# Access a data item inside a namespace using colons and
+# single quotes :-(
+
+send_gdb "print 'AAA::c'\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 0 '\\\\(0|000)'\r\n$gdb_prompt $" { pass "print 'AAA::c'" }
+ -re ".*$gdb_prompt $" { fail "print 'AAA::c'" }
+ timeout { fail "(timeout) print 'AAA::c'" }
+}
+
+# An object declared using "using".
+
+send_gdb "print ina\n"
+gdb_expect {
+ -re "\\$\[0-9\]+ = {xx = 33}.*$gdb_prompt $" {
+ pass "print ina"
+ }
+ -re ".*$gdb_prompt $" { fail "print ina" }
+ timeout { fail "(timeout) print ina" }
+}
+
+send_gdb "ptype ina\n"
+gdb_expect {
+ -re "type = class (AAA::|)inA \{\r\n\[ \]*public:\r\n\[ \]*int xx;\r\n\[ \]*\r\n\[ \]*.*int fum\\(int\\);\r\n\}\r\n$gdb_prompt $" {
+ pass "ptype ina"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype ina" }
+ timeout { fail "(timeout) ptype ina" }
+}
+
+# Check all functions are known to GDB
+
+setup_xfail hppa*-*-*11* CLLbs14869
+send_gdb "info func xyzq\n"
+gdb_expect {
+ -re "All functions.*File.*namespace.cc:\r\nint AAA::A_xyzq\\(int\\);\r\nint BBB::B_xyzq\\(int\\);\r\nchar AAA::xyzq\\(char\\);\r\nchar BBB::xyzq\\(char\\);\r\nchar BBB::CCC::xyzq\\(char\\);\r\nchar BBB::Class::xyzq\\(char\\);\r\n$gdb_prompt $" {
+ pass "info func xyzq"
+ }
+ -re "All functions.*File.*namespace.cc:\r\nint AAA::A_xyzq\\(int\\);\r\nchar AAA::xyzq\\(char\\);\r\nint BBB::B_xyzq\\(int\\);\r\nchar BBB::CCC::xyzq\\(char\\);\r\nchar BBB::Class::xyzq\\(char\\);\r\nchar BBB::xyzq\\(char\\);\r\n$gdb_prompt $" {
+ pass "info func xyzq"
+ }
+ -re ".*$gdb_prompt $" { fail "info func xyzq" }
+ timeout { fail "(timeout) info func xyzq" }
+}
+
+# Call a function in a namespace
+
+send_gdb "print 'AAA::xyzq'('x')\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 97 'a'\r\n$gdb_prompt $" {
+ pass "print 'AAA::xyzq'('x')"
+ }
+ -re ".*$gdb_prompt $" { fail "print 'AAA::xyzq'('x')" }
+ timeout { fail "(timeout) print 'AAA::xyzq'('x')" }
+}
+
+# Break on a function in a namespace
+
+send_gdb "break AAA::xyzq\n"
+gdb_expect {
+ -re "Breakpoint.*at $hex: file.*namespace.cc, line 42\\.\r\n$gdb_prompt $" {
+ pass "break AAA::xyzq"
+ }
+ -re ".*$gdb_prompt $" { fail "break AAA::xyzq" }
+ timeout { fail "(timeout) break AAA::xyzq" }
+}
+
+# Call a function in a nested namespace
+
+send_gdb "print 'BBB::CCC::xyzq'('x')\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 122 'z'\r\n$gdb_prompt $" {
+ pass "print 'BBB::CCC::xyzq'('x')"
+ }
+ -re ".*$gdb_prompt $" { fail "print 'BBB::CCC::xyzq'('x')" }
+ timeout { fail "(timeout) print 'BBB::CCC::xyzq'('x')" }
+}
+
+# Break on a function in a nested namespace
+
+send_gdb "break BBB::CCC::xyzq\n"
+gdb_expect {
+ -re "Breakpoint.*at $hex: file.*namespace.cc, line 58\\.\r\n$gdb_prompt $" {
+ pass "break BBB::CCC::xyzq"
+ }
+ -re ".*$gdb_prompt $" { fail "break BBB::CCC::xyzq" }
+ timeout { fail "(timeout) break BBB::CCC::xyzq" }
+}
+
+# Print address of a function in a class in a namespace
+
+send_gdb "print 'BBB::Class::xyzq'\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \{char \\((BBB::|)Class \\*( const|), (char|int)\\)\} $hex <BBB::Class::xyzq\\(char\\)>\r\n$gdb_prompt $" {
+ pass "print 'BBB::Class::xyzq'"
+ }
+ -re ".*$gdb_prompt $" { fail "print 'BBB::Class::xyzq'" }
+ timeout { fail "(timeout) print 'BBB::Class::xyzq'" }
+}
+
+# Break on a function in a class in a namespace
+
+send_gdb "break BBB::Class::xyzq\n"
+gdb_expect {
+ -re "Breakpoint.*at $hex: file.*namespace.cc, line 63\\.\r\n$gdb_prompt $" {
+ pass "break BBB::Class::xyzq"
+ }
+ -re ".*$gdb_prompt $" { fail "break BBB::Class::xyzq" }
+ timeout { fail "(timeout) break BBB::Class::xyzq" }
+}
+
diff --git a/gdb/testsuite/gdb.c++/overload.cc b/gdb/testsuite/gdb.c++/overload.cc
new file mode 100644
index 00000000000..97083c5640c
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/overload.cc
@@ -0,0 +1,161 @@
+#include <stddef.h>
+
+class foo {
+public:
+ foo (int);
+ foo (int, const char *);
+ foo (foo&);
+ ~foo ();
+ void foofunc (int);
+ void foofunc (int, signed char *);
+ int ifoo;
+ const char *ccpfoo;
+
+int overload1arg (void);
+int overload1arg (char);
+int overload1arg (signed char);
+int overload1arg (unsigned char);
+int overload1arg (short);
+int overload1arg (unsigned short);
+int overload1arg (int);
+int overload1arg (unsigned int);
+int overload1arg (long);
+int overload1arg (unsigned long);
+int overload1arg (float);
+int overload1arg (double);
+
+int overloadfnarg (void);
+int overloadfnarg (int);
+int overloadfnarg (int, int (*) (int));
+
+int overloadargs (int a1);
+int overloadargs (int a1, int a2);
+int overloadargs (int a1, int a2, int a3);
+int overloadargs (int a1, int a2, int a3, int a4);
+int overloadargs (int a1, int a2, int a3, int a4, int a5);
+int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6);
+int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7);
+int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8);
+int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9);
+int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9, int a10);
+int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9, int a10, int a11);
+
+
+};
+
+void marker1()
+{}
+
+int main ()
+{
+ char arg2 = 2;
+ signed char arg3 =3;
+ unsigned char arg4 =4;
+ short arg5 =5;
+ unsigned short arg6 =6;
+ int arg7 =7;
+ unsigned int arg8 =8;
+ long arg9 =9;
+ unsigned long arg10 =10;
+ float arg11 =100.0;
+ double arg12 = 200.0;
+
+ char *str = (char *) "A";
+ foo foo_instance1(111);
+ foo foo_instance2(222, str);
+ foo foo_instance3(foo_instance2);
+
+ #ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+ #endif
+
+
+ marker1();
+ return 0;
+}
+
+foo::foo (int i) { ifoo = i; ccpfoo = NULL; }
+foo::foo (int i, const char *ccp) { ifoo = i; ccpfoo = ccp; }
+foo::foo (foo& afoo) { ifoo = afoo.ifoo; ccpfoo = afoo.ccpfoo;}
+foo::~foo () {}
+
+
+/* Some functions to test overloading by varying one argument type. */
+
+int foo::overload1arg (void) { return 1; }
+int foo::overload1arg (char arg) { arg = 0; return 2;}
+int foo::overload1arg (signed char arg) { arg = 0; return 3;}
+int foo::overload1arg (unsigned char arg) { arg = 0; return 4;}
+int foo::overload1arg (short arg) { arg = 0; return 5;}
+int foo::overload1arg (unsigned short arg) { arg = 0; return 6;}
+int foo::overload1arg (int arg) { arg = 0; return 7;}
+int foo::overload1arg (unsigned int arg) { arg = 0; return 8;}
+int foo::overload1arg (long arg) { arg = 0; return 9;}
+int foo::overload1arg (unsigned long arg) { arg = 0; return 10;}
+int foo::overload1arg (float arg) { arg = 0; return 11;}
+int foo::overload1arg (double arg) { arg = 0; return 12;}
+
+/* Test to see that we can explicitly request overloaded functions
+ with function pointers in the prototype. */
+
+int foo::overloadfnarg (void) { return ifoo * 20; }
+int foo::overloadfnarg (int arg) { arg = 0; return 13;}
+int foo::overloadfnarg (int arg, int (*foo) (int)) { return foo(arg); }
+
+/* Some functions to test overloading by varying argument count. */
+
+int foo::overloadargs (int a1)
+{ a1 = 0;
+return 1;}
+
+int foo::overloadargs (int a1, int a2)
+{ a1 = a2 = 0;
+return 2;}
+
+int foo::overloadargs (int a1, int a2, int a3)
+{ a1 = a2 = a3 = 0;
+return 3;}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4)
+{ a1 = a2 = a3 = a4 = 0;
+return 4;}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4, int a5)
+{ a1 = a2 = a3 = a4 = a5 = 0;
+return 5;}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4, int a5, int a6)
+{ a1 = a2 = a3 = a4 = a5 = a6 = 0;
+return 6;}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7)
+{ a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0;
+return 7;}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8)
+{ a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = 0;
+return 8;}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9)
+{
+ a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = 0;
+ return 9;
+}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9, int a10)
+ { a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 =
+ a10 = 0; return 10;}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9, int a10, int a11)
+ { a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 =
+ a10 = a11 = 0; return 11;}
+
+
+
diff --git a/gdb/testsuite/gdb.c++/overload.exp b/gdb/testsuite/gdb.c++/overload.exp
new file mode 100644
index 00000000000..e9aaae04fea
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/overload.exp
@@ -0,0 +1,393 @@
+# Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# written by Elena Zannoni (ezannoni@cygnus.com)
+
+# This file is part of the gdb testsuite
+#
+# tests for overloaded member functions. Command Line calls
+#
+
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "overload"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile} "c++"] {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# set it up at a breakpoint so we can play with the variable values
+#
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+if ![runto 'marker1'] then {
+ perror "couldn't run to marker1"
+ continue
+}
+
+gdb_test "up" ".*main.*" "up from marker1"
+
+send_gdb "print foo_instance1\n"
+gdb_expect {
+ -re ".\[0-9\]* = \{ifoo = 111, ccpfoo = 0x0\}\r\n$gdb_prompt $" {
+ pass "print foo_instance1"
+ }
+ -re ".*$gdb_prompt $" { fail "print foo_instance1" }
+ timeout { fail "(timeout) print foo_instance1" }
+ }
+
+
+setup_xfail "hppa*-*-*" CLLbs16901
+send_gdb "ptype foo_instance1\n"
+gdb_expect {
+ -re "type = class foo \{.*public:.*int ifoo;.*const char \\*ccpfoo;.*foo\\(int\\);.*foo\\(int, (const char|char const) \\*\\);.*foo\\(foo &\\);.*~foo\\(void\\);.*void foofunc\\(int\\);.*void foofunc\\(int, signed char \\*\\);.*int overload1arg\\(void\\);.*int overload1arg\\(char\\);.*int overload1arg\\(signed char\\);.*int overload1arg\\(unsigned char\\);.*int overload1arg\\(short\\);.*int overload1arg\\(unsigned short\\);.*int overload1arg\\(int\\);.*int overload1arg\\(unsigned int\\);.*int overload1arg\\(long\\);.*int overload1arg\\(unsigned long\\);.*int overload1arg\\(float\\);.*int overload1arg\\(double\\);.*int overloadargs\\(int\\);.*int overloadargs\\(int, int\\);.*int overloadargs\\(int, int, int\\);.*int overloadargs\\(int, int, int, int\\);.*int overloadargs\\(int, int, int, int, int\\);.*int overloadargs\\(int, int, int, int, int, int\\);.*int overloadargs\\(int, int, int, int, int, int, int\\);.*int overloadargs\\(int, int, int, int, int, int, int, int\\);.*int overloadargs\\(int, int, int, int, int, int, int, int, int\\);.*int overloadargs\\(int, int, int, int, int, int, int, int, int, int\\);.*int overloadargs\\(int, int, int, int, int, int, int, int, int, int, int\\);\r\n\}\r\n$gdb_prompt $" {
+ pass "ptype foo_instance1 (HP aCC -- known quirk with ~foo parameter list)"
+ }
+ -re "type = class foo .*int overloadargs\\(int, int, int, int, int, int, int, int, int, int, int\\);\r\n\}\r\n$gdb_prompt $" {
+ pass "ptype foo_instance1 (shorter match)"
+ }
+ -re ".*$gdb_prompt $" { fail "ptype foo_instance1" }
+ timeout { fail "(timeout) ptype foo_instance1" }
+ }
+
+send_gdb "print foo_instance2\n"
+gdb_expect {
+ -re ".\[0-9\]* = \{ifoo = 222, ccpfoo = $hex \"A\"\}\r\n$gdb_prompt $" {
+ pass "print foo_instance2"
+ }
+ -re ".*$gdb_prompt $" { fail "print foo_instance2" }
+ timeout { fail "(timeout) print foo_instance2" }
+ }
+
+send_gdb "print foo_instance3\n"
+gdb_expect {
+ -re ".\[0-9\]* = \{ifoo = 222, ccpfoo = $hex \"A\"\}\r\n$gdb_prompt $" {
+ pass "print foo_instance3"
+ }
+ -re ".*$gdb_prompt $" { fail "print foo_instance3" }
+ timeout { fail "(timeout) print foo_instance3" }
+ }
+
+
+send_gdb "print foo_instance1.overloadargs(1)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1\r\n$gdb_prompt $" {
+ pass "print call overloaded func 1 arg"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func 1 arg" }
+ timeout { fail "(timeout) print call overloaded func 1 arg" }
+ }
+
+
+send_gdb "print foo_instance1.overloadargs(1, 2)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 2\r\n$gdb_prompt $" {
+ pass "print call overloaded func 2 args"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func 2 args" }
+ timeout { fail "(timeout) print call overloaded func 2 args" }
+ }
+
+
+send_gdb "print foo_instance1.overloadargs(1, 2, 3)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 3\r\n$gdb_prompt $" {
+ pass "print call overloaded func 3 args"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func 3 args" }
+ timeout { fail "(timeout) print call overloaded func 3 args" }
+ }
+
+
+send_gdb "print foo_instance1.overloadargs(1, 2, 3, 4)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 4\r\n$gdb_prompt $" {
+ pass "print call overloaded func 4 args"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func 4 args" }
+ timeout { fail "(timeout) print call overloaded func 4 args" }
+ }
+
+
+send_gdb "print foo_instance1.overloadargs(1, 2, 3, 4, 5)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 5\r\n$gdb_prompt $" {
+ pass "print call overloaded func 5 args"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func 5 args" }
+ timeout { fail "(timeout) print call overloaded func 5 args" }
+ }
+
+
+send_gdb "print foo_instance1.overloadargs(1, 2, 3, 4, 5, 6)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 6\r\n$gdb_prompt $" {
+ pass "print call overloaded func 6 args"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func 6 args" }
+ timeout { fail "(timeout) print call overloaded func 6 args" }
+ }
+
+
+send_gdb "print foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 7\r\n$gdb_prompt $" {
+ pass "print call overloaded func 7 args"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func 7 args" }
+ timeout { fail "(timeout) print call overloaded func 7 args" }
+ }
+
+
+send_gdb "print foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7, 8)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 8\r\n$gdb_prompt $" {
+ pass "print call overloaded func 8 args"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func 8 args" }
+ timeout { fail "(timeout) print call overloaded func 8 args" }
+ }
+
+
+send_gdb "print foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7, 8, 9)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 9\r\n$gdb_prompt $" {
+ pass "print call overloaded func 9 args"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func 9 args" }
+ timeout { fail "(timeout) print call overloaded func 9 args" }
+ }
+
+
+send_gdb "print foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 10\r\n$gdb_prompt $" {
+ pass "print call overloaded func 10 args"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func 10 args" }
+ timeout { fail "(timeout) print call overloaded func 10 args" }
+ }
+
+
+send_gdb "print foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 11\r\n$gdb_prompt $" {
+ pass "print call overloaded func 11 args"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func 11 args" }
+ timeout { fail "(timeout) print call overloaded func 11 args" }
+ }
+
+
+send_gdb "print foo_instance1.overload1arg()\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1\r\n$gdb_prompt $" {
+ pass "print call overloaded func void arg"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func void arg" }
+ timeout { fail "(timeout) print call overloaded func void arg" }
+ }
+
+
+send_gdb "print foo_instance1.overload1arg((char)arg2)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 2\r\n$gdb_prompt $" {
+ pass "print call overloaded func char arg"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func char arg" }
+ timeout { fail "(timeout) print call overloaded func char arg" }
+ }
+
+
+send_gdb "print foo_instance1.overload1arg((signed char)arg3)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 3\r\n$gdb_prompt $" {
+ pass "print call overloaded func signed char arg"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func signed char arg" }
+ timeout { fail "(timeout) print call overloaded func signed char arg" }
+ }
+
+
+send_gdb "print foo_instance1.overload1arg((unsigned char)arg4)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 4\r\n$gdb_prompt $" {
+ pass "print call overloaded func unsigned char arg"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func unsigned char arg" }
+ timeout { fail "(timeout) print call overloaded func unsigned char arg" }
+ }
+
+
+# The overload resolver added by HP (valops.c:find_overload_match) doesn't
+# work right for G++ output, since the list of parameters seems not to
+# be filled in correctly. Until this gets fixed, don't expect to pass
+# some of these tests.
+
+setup_xfail "*-*-*" CLLbs16901
+
+send_gdb "print foo_instance1.overload1arg((short)arg5)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 5\r\n$gdb_prompt $" {
+ pass "print call overloaded func short arg"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func short arg" }
+ timeout { fail "(timeout) print call overloaded func short arg" }
+ }
+
+
+setup_xfail "*-*-*" CLLbs16901
+
+send_gdb "print foo_instance1.overload1arg((unsigned short)arg6)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 6\r\n$gdb_prompt $" {
+ pass "print call overloaded func unsigned short arg"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func unsigned short arg" }
+ timeout { fail "(timeout) print call overloaded func unsigned short arg" }
+ }
+
+
+send_gdb "print foo_instance1.overload1arg((int)arg7)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 7\r\n$gdb_prompt $" {
+ pass "print call overloaded func int arg"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func int arg" }
+ timeout { fail "(timeout) print call overloaded func int arg" }
+ }
+
+
+send_gdb "print foo_instance1.overload1arg((unsigned int)arg8)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 8\r\n$gdb_prompt $" {
+ pass "print call overloaded func unsigned int arg"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func unsigned int arg" }
+ timeout { fail "(timeout) print call overloaded func unsigned int arg" }
+ }
+
+
+setup_xfail "*-*-*" CLLbs16901
+
+send_gdb "print foo_instance1.overload1arg((long)arg9)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 9\r\n$gdb_prompt $" {
+ pass "print call overloaded func long arg"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func long arg" }
+ timeout { fail "(timeout) print call overloaded func long arg" }
+ }
+
+
+setup_xfail "*-*-*" CLLbs16901
+
+send_gdb "print foo_instance1.overload1arg((unsigned long)arg10)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 10\r\n$gdb_prompt $" {
+ pass "print call overloaded func unsigned long arg"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func unsigned long arg" }
+ timeout { fail "(timeout) print call overloaded func unsigned long arg" }
+ }
+
+
+send_gdb "print foo_instance1.overload1arg((float)arg11)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 11\r\n$gdb_prompt $" {
+ pass "print call overloaded func float arg"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func float arg" }
+ timeout { fail "(timeout) print call overloaded func float arg" }
+ }
+
+
+send_gdb "print foo_instance1.overload1arg((double)arg12)\n"
+gdb_expect {
+ -re ".\[0-9\]* = 12\r\n$gdb_prompt $" {
+ pass "print call overloaded func double arg"
+ }
+ -re ".*$gdb_prompt $" { fail "print call overloaded func double arg" }
+ timeout { fail "(timeout) print call overloaded func double arg" }
+ }
+
+# Now some tests to see if we can list overloaded functions properly:
+
+gdb_test "set listsize 1" "" ""
+# send_gdb "set listsize 1\n"
+# gdb_expect -re ".*$gdb_prompt $"
+
+#
+# Decide whether to use "()" or "(void)"
+#
+
+send_gdb "info func overloadfnarg\n"
+gdb_expect {
+ -re ".*overloadfnarg\\(void\\).*$gdb_prompt $" {
+ gdb_test "list foo::overloadfnarg(void)"\
+ ".*int foo::overloadfnarg.*\\(void\\).*" \
+ "list overloaded function with no args"
+ }
+ -re ".*overloadfnarg\\(\\).*$gdb_prompt $" {
+ gdb_test "list foo::overloadfnarg()"\
+ ".*int foo::overloadfnarg.*\\(void\\).*" \
+ "list overloaded function with no args"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "list overloaded function with no args (no matching symbol)"
+ }
+}
+
+gdb_test "list foo::overloadfnarg(int)"\
+ "int foo::overloadfnarg.*\\(int arg\\).*" \
+ "list overloaded function with int arg"
+
+gdb_test "list foo::overloadfnarg(int, int (*)(int))" \
+ "int foo::overloadfnarg.*\\(int arg, int \\(\\*foo\\) \\(int\\)\\).*" \
+ "list overloaded function with function ptr args"
+
+# This one crashes GDB. Don't know why yet.
+gdb_test "list \"foo::overloadfnarg(int, int (*)(int))\"" \
+ "int foo::overloadfnarg.*\\(int arg, int \\(\\*foo\\) \\(int\\)\\).*" \
+ "list overloaded function with function ptr args - quotes around argument"
diff --git a/gdb/testsuite/gdb.c++/ovldbreak.cc b/gdb/testsuite/gdb.c++/ovldbreak.cc
new file mode 100644
index 00000000000..9a5b5cbf7c7
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/ovldbreak.cc
@@ -0,0 +1,177 @@
+#include <stddef.h>
+
+class foo {
+public:
+ foo (int);
+ foo (int, const char *);
+ foo (foo&);
+ ~foo ();
+ void foofunc (int);
+ void foofunc (int, signed char *);
+ int ifoo;
+ const char *ccpfoo;
+
+int overload1arg (void);
+int overload1arg (char);
+int overload1arg (signed char);
+int overload1arg (unsigned char);
+int overload1arg (short);
+int overload1arg (unsigned short);
+int overload1arg (int);
+int overload1arg (unsigned int);
+int overload1arg (long);
+int overload1arg (unsigned long);
+int overload1arg (float);
+int overload1arg (double);
+
+int overloadargs (int a1);
+int overloadargs (int a1, int a2);
+int overloadargs (int a1, int a2, int a3);
+int overloadargs (int a1, int a2, int a3, int a4);
+int overloadargs (int a1, int a2, int a3, int a4, int a5);
+int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6);
+int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7);
+int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8);
+int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9);
+int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9, int a10);
+int overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9, int a10, int a11);
+
+
+};
+
+void marker1()
+{}
+
+int main ()
+{
+ char arg2 = 2;
+ signed char arg3 =3;
+ unsigned char arg4 =4;
+ short arg5 =5;
+ unsigned short arg6 =6;
+ int arg7 =7;
+ unsigned int arg8 =8;
+ long arg9 =9;
+ unsigned long arg10 =10;
+ float arg11 =100.0;
+ double arg12 = 200.0;
+
+ char ch='A';
+ foo foo_instance1(111);
+ foo foo_instance2(222, &ch);
+ foo foo_instance3(foo_instance2);
+
+ foo_instance1.overload1arg();
+ foo_instance1.overload1arg(arg2);
+ foo_instance1.overload1arg(arg3);
+ foo_instance1.overload1arg(arg4);
+ foo_instance1.overload1arg(arg5);
+ foo_instance1.overload1arg(arg6);
+ foo_instance1.overload1arg(arg7);
+ foo_instance1.overload1arg(arg8);
+ foo_instance1.overload1arg(arg9);
+ foo_instance1.overload1arg(arg10);
+ foo_instance1.overload1arg(arg11);
+ foo_instance1.overload1arg(arg12);
+
+ foo_instance1.overloadargs(1);
+ foo_instance1.overloadargs(1, 2);
+ foo_instance1.overloadargs(1, 2, 3);
+ foo_instance1.overloadargs(1, 2, 3, 4);
+ foo_instance1.overloadargs(1, 2, 3, 4, 5);
+ foo_instance1.overloadargs(1, 2, 3, 4, 5, 6);
+ foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7);
+ foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7, 8);
+ foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7, 8, 9);
+ foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+ foo_instance1.overloadargs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
+
+
+ #ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+ #endif
+
+
+ marker1();
+ return 0;
+}
+
+foo::foo (int i) { ifoo = i;}
+foo::foo (int i, const char *ccp) { ifoo = i; ccpfoo = ccp; }
+foo::foo (foo& afoo) { ifoo = afoo.ifoo; ccpfoo = afoo.ccpfoo;}
+foo::~foo () {}
+
+
+/* Some functions to test overloading by varying one argument type. */
+
+int foo::overload1arg (void) { return 1; }
+int foo::overload1arg (char arg) { arg = 0; return 2;}
+int foo::overload1arg (signed char arg) { arg = 0; return 3;}
+int foo::overload1arg (unsigned char arg) { arg = 0; return 4;}
+int foo::overload1arg (short arg) { arg = 0; return 5;}
+int foo::overload1arg (unsigned short arg) { arg = 0; return 6;}
+int foo::overload1arg (int arg) { arg = 0; return 7;}
+int foo::overload1arg (unsigned int arg) { arg = 0; return 8;}
+int foo::overload1arg (long arg) { arg = 0; return 9;}
+int foo::overload1arg (unsigned long arg) { arg = 0; return 10;}
+int foo::overload1arg (float arg) { arg = 0; return 11;}
+int foo::overload1arg (double arg) { arg = 0; return 12;}
+
+
+/* Some functions to test overloading by varying argument count. */
+
+int foo::overloadargs (int a1)
+{ a1 = 0;
+return 1;}
+
+int foo::overloadargs (int a1, int a2)
+{ a1 = a2 = 0;
+return 2;}
+
+int foo::overloadargs (int a1, int a2, int a3)
+{ a1 = a2 = a3 = 0;
+return 3;}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4)
+{ a1 = a2 = a3 = a4 = 0;
+return 4;}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4, int a5)
+{ a1 = a2 = a3 = a4 = a5 = 0;
+return 5;}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4, int a5, int a6)
+{ a1 = a2 = a3 = a4 = a5 = a6 = 0;
+return 6;}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7)
+{ a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0;
+return 7;}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8)
+{ a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = 0;
+return 8;}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9)
+{
+ a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = 0;
+ return 9;
+}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9, int a10)
+ { a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 =
+ a10 = 0; return 10;}
+
+int foo::overloadargs (int a1, int a2, int a3, int a4, int a5, int a6, int a7,
+ int a8, int a9, int a10, int a11)
+ { a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 =
+ a10 = a11 = 0; return 11;}
+
+
+
diff --git a/gdb/testsuite/gdb.c++/ovldbreak.exp b/gdb/testsuite/gdb.c++/ovldbreak.exp
new file mode 100644
index 00000000000..9852cb597b1
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/ovldbreak.exp
@@ -0,0 +1,349 @@
+# Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# written by Elena Zannoni (ezannoni@cygnus.com)
+# modified by Michael Chastain (chastain@redhat.com)
+
+# This file is part of the gdb testsuite
+#
+# tests for overloaded member functions. Set breakpoints on
+# overloaded member functions
+#
+
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "ovldbreak"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# set it up at a breakpoint so we can play with the variable values
+#
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+
+
+# When I ask gdb to set a breakpoint on an overloaded function,
+# gdb gives me a choice menu. I might get stuck in that choice menu
+# (for example, if C++ name mangling is not working properly).
+#
+# This procedure issues a command that works at either the menu
+# prompt or the command prompt to get back to the command prompt.
+#
+# Note that an empty line won't do it (it means 'repeat the previous command'
+# at top level). A line with a single space in it works nicely.
+
+proc take_gdb_out_of_choice_menu {} {
+ global gdb_prompt
+ send_gdb " \n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {
+ }
+ timeout {
+ perror "could not resynchronize to command prompt (timeout)"
+ continue
+ }
+ }
+}
+
+
+
+# This procedure sets an overloaded breakpoint.
+# When I ask for such a breakpoint, gdb gives me a menu of 'cancel' 'all'
+# and a bunch of choices. I then choose from that menu by number.
+
+proc set_bp_overloaded {name expectedmenu mychoice bpnumber linenumber} {
+ global gdb_prompt hex srcfile
+
+ # Get into the overload menu.
+ send_gdb "break $name\n"
+ gdb_expect {
+ -re "$expectedmenu" {
+ pass "bp menu for $name choice $mychoice"
+
+ # Choose my choice.
+ send_gdb "$mychoice\n"
+ gdb_expect {
+ -re "Breakpoint $bpnumber at $hex: file.*$srcfile, line $linenumber.\r\n$gdb_prompt $" {
+ pass "set bp $bpnumber on $name $mychoice line $linenumber"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "set bp $bpnumber on $name $mychoice line $linenumber (bad bp)"
+ }
+ timeout {
+ fail "set bp $bpnumber on $name $mychoice line $linenumber (timeout)"
+ take_gdb_out_of_choice_menu
+ }
+ }
+ }
+ -re ".*\r\n> " {
+ fail "bp menu for $name choice $mychoice (bad menu)"
+ take_gdb_out_of_choice_menu
+ }
+ -re ".*$gdb_prompt $" {
+ fail "bp menu for $name choice $mychoice (no menu)"
+ }
+ timeout {
+ fail "bp menu for $name choice $mychoice (timeout)"
+ take_gdb_out_of_choice_menu
+ }
+ }
+}
+
+# This is the expected menu for overload1arg.
+# Note the arg type variations on lines 6 and 13.
+# This accommodates different versions of g++.
+
+set menu_overload1arg "\\\[0\\\] cancel\r\n\\\[1\\\] all\r\n\\\[2\\\] foo::overload1arg\\(double\\) at.*$srcfile:121\r\n\\\[3\\\] foo::overload1arg\\(float\\) at.*$srcfile:120\r\n\\\[4\\\] foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r\n\\\[5\\\] foo::overload1arg\\(long\\) at.*$srcfile:118\r\n\\\[6\\\] foo::overload1arg\\((unsigned int|unsigned)\\) at.*$srcfile:117\r\n\\\[7\\\] foo::overload1arg\\(int\\) at.*$srcfile:116\r\n\\\[8\\\] foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r\n\\\[9\\\] foo::overload1arg\\(short\\) at.*$srcfile:114\r\n\\\[10\\\] foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r\n\\\[11\\\] foo::overload1arg\\(signed char\\) at.*$srcfile:112\r\n\\\[12\\\] foo::overload1arg\\(char\\) at.*$srcfile:111\r\n\\\[13\\\] foo::overload1arg\\((void|)\\) at.*$srcfile:110\r\n> $"
+
+
+
+# Set breakpoints on foo::overload1arg, one by one.
+
+set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 12 2 111
+set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 11 3 112
+set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 10 4 113
+set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 9 5 114
+set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 8 6 115
+set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 7 7 116
+set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 6 8 117
+set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 5 9 118
+set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 4 10 119
+set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 3 11 120
+set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 2 12 121
+set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 13 13 110
+
+
+
+# Verify the breakpoints.
+
+gdb_test "info break" \
+ "Num Type\[\t \]+Disp Enb Address\[\t \]+What.*
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in main at.*$srcfile:49\r
+\[\t \]+breakpoint already hit 1 time\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \
+ "breakpoint info (after setting one-by-one)"
+
+
+
+# Test choice "cancel".
+# This is copy-and-paste from set_bp_overloaded.
+
+send_gdb "break foo::overload1arg\n"
+gdb_expect {
+ -re "$menu_overload1arg" {
+ pass "bp menu for foo::overload1arg choice cancel"
+ # Choose cancel.
+ send_gdb "0\n"
+ gdb_expect {
+ -re "canceled\r\n$gdb_prompt $" {
+ pass "set bp on overload1arg canceled"
+ }
+ -re "cancelled\r\n$gdb_prompt $" {
+ pass "set bp on overload1arg canceled"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "set bp on overload1arg canceled (bad message)"
+ }
+ timeout {
+ fail "set bp on overload1arg canceled (timeout)"
+ take_gdb_out_of_choice_menu
+ }
+ }
+ }
+ -re ".*\r\n> " {
+ fail "bp menu for foo::overload1arg choice cancel (bad menu)"
+ take_gdb_out_of_choice_menu
+ }
+ -re ".*$gdb_prompt $" {
+ fail "bp menu for foo::overload1arg choice cancel (no menu)"
+ }
+ timeout {
+ fail "bp menu for foo::overload1arg choice cancel (timeout)"
+ take_gdb_out_of_choice_menu
+ }
+}
+
+gdb_test "info break" \
+ "Num Type\[\t \]+Disp Enb Address\[\t \]+What.*
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in main at.*$srcfile:49\r
+\[\t \]+breakpoint already hit 1 time\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \
+ "breakpoint info (after cancel)"
+
+
+
+# Delete these breakpoints.
+
+send_gdb "delete breakpoints\n"
+gdb_expect {
+ -re "Delete all breakpoints.* $" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {
+ pass "delete all breakpoints"
+ }
+ timeout {
+ fail "delete all breakpoints (timeout)"
+ }
+ }
+ }
+ timeout {
+ fail "delete all breakpoints (timeout)"
+ }
+}
+
+gdb_test "info breakpoints" "No breakpoints or watchpoints." "breakpoint info (after delete)"
+
+
+
+# Test choice "all".
+# This is copy-and-paste from set_bp_overloaded.
+
+send_gdb "break foo::overload1arg\n"
+gdb_expect {
+ -re "$menu_overload1arg" {
+ pass "bp menu for foo::overload1arg choice all"
+ # Choose all.
+ send_gdb "1\n"
+ gdb_expect {
+ -re "Breakpoint $decimal at $hex: file.*$srcfile, line 121.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 120.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 119.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 118.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 117.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 116.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 115.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 114.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 113.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 112.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 111.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 110.\r\nwarning: Multiple breakpoints were set.\r\nwarning: Use the .delete. command to delete unwanted breakpoints.\r\n$gdb_prompt $" {
+ pass "set bp on overload1arg all"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "set bp on overload1arg all (bad message)"
+ }
+ timeout {
+ fail "set bp on overload1arg all (timeout)"
+ take_gdb_out_of_choice_menu
+ }
+ }
+ }
+ -re ".*\r\n> " {
+ fail "bp menu for foo::overload1arg choice all (bad menu)"
+ take_gdb_out_of_choice_menu
+ }
+ -re ".*$gdb_prompt $" {
+ fail "bp menu for foo::overload1arg choice all (no menu)"
+ }
+ timeout {
+ fail "bp menu for foo::overload1arg choice all (timeout)"
+ take_gdb_out_of_choice_menu
+ }
+}
+
+gdb_test "info break" \
+ "Num Type\[\t \]+Disp Enb Address\[\t \]+What.*
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
+\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \
+ "breakpoint info (after setting on all)"
+
+
+
+# Run through each breakpoint.
+
+proc continue_to_bp_overloaded {bpnumber argtype actuals} {
+ global gdb_prompt hex decimal srcfile
+
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Continuing.\r\n\r\nBreakpoint ${bpnumber}, (${hex} in )?foo::overload1arg(\\(${argtype}\\))? \\(this=${hex}(, )?${actuals}\\) at.*${srcfile}:${decimal}\r\n${decimal}\[\t \]+int foo::overload1arg \\(${argtype}( arg)?\\).*\r\n.*$gdb_prompt $" {
+ pass "continue to bp overloaded : ${argtype}"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "continue to bp overloaded : ${argtype}"
+ }
+ timeout {
+ fail "continue to bp overloaded : ${argtype} (timeout)"
+ }
+ }
+}
+
+continue_to_bp_overloaded 25 "(void|)" ""
+continue_to_bp_overloaded 24 "char" "arg=2 \\'\\\\002\\'"
+continue_to_bp_overloaded 23 "signed char" "arg=3 \\'\\\\003\\'"
+continue_to_bp_overloaded 22 "unsigned char" "arg=4 \\'\\\\004\\'"
+continue_to_bp_overloaded 21 "short" "arg=5"
+continue_to_bp_overloaded 20 "unsigned short" "arg=6"
+continue_to_bp_overloaded 19 "int" "arg=7"
+continue_to_bp_overloaded 18 "(unsigned|unsigned int)" "arg=8"
+continue_to_bp_overloaded 17 "long" "arg=9"
+continue_to_bp_overloaded 16 "unsigned long" "arg=10"
+continue_to_bp_overloaded 15 "float" "arg=100"
+continue_to_bp_overloaded 14 "double" "arg=200"
+
+
+
+# That's all, folks.
+
+gdb_continue_to_end "finish program"
diff --git a/gdb/testsuite/gdb.c++/ref-types.cc b/gdb/testsuite/gdb.c++/ref-types.cc
new file mode 100644
index 00000000000..23cc51095e3
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/ref-types.cc
@@ -0,0 +1,79 @@
+int main2(void);
+
+void marker1 (void)
+{
+
+}
+
+
+
+int main(void)
+{
+ short s;
+ short &rs = s;
+ short *ps;
+ short *&rps = ps;
+ short as[4];
+ short (&ras)[4] = as;
+ s = -1;
+ ps = &s;
+ as[0] = 0;
+ as[1] = 1;
+ as[2] = 2;
+ as[3] = 3;
+
+ #ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+ #endif
+ marker1();
+
+ main2();
+
+ return 0;
+}
+
+int f()
+{
+ int f1;
+ f1 = 1;
+ return f1;
+}
+
+int main2(void)
+{
+ char C;
+ unsigned char UC;
+ short S;
+ unsigned short US;
+ int I;
+ unsigned int UI;
+ long L;
+ unsigned long UL;
+ float F;
+ double D;
+ char &rC = C;
+ unsigned char &rUC = UC;
+ short &rS = S;
+ unsigned short &rUS = US;
+ int &rI = I;
+ unsigned int &rUI = UI;
+ long &rL = L;
+ unsigned long &rUL = UL;
+ float &rF = F;
+ double &rD = D;
+ C = 'A';
+ UC = 21;
+ S = -14;
+ US = 7;
+ I = 102;
+ UI = 1002;
+ L = -234;
+ UL = 234;
+ F = 1.25E10;
+ D = -1.375E-123;
+ I = f();
+
+ return 0;
+
+}
diff --git a/gdb/testsuite/gdb.c++/ref-types.exp b/gdb/testsuite/gdb.c++/ref-types.exp
new file mode 100644
index 00000000000..dd06f027111
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/ref-types.exp
@@ -0,0 +1,663 @@
+# Tests for reference types with short type variables in GDB.
+# Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# written by Elena Zannoni (ezannoni@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "ref-types"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+if ![runto 'marker1'] then {
+ perror "couldn't run to marker1"
+ continue
+}
+
+gdb_test "up" ".*main.*" "up from marker1 1"
+
+proc gdb_start_again {} {
+ global srcdir
+ global subdir
+ global binfile
+ global gdb_prompt
+ global decimal
+
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+
+ source ${binfile}.ci
+
+ #
+ # set it up at a breakpoint so we can play with the variable values
+ #
+ if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+ }
+
+ if ![runto 'marker1'] then {
+ perror "couldn't run to marker1"
+ continue
+ }
+
+ gdb_test "up" ".*main.*" "up from marker1 2"
+}
+
+
+
+send_gdb "print s\n"
+gdb_expect {
+ -re ".\[0-9\]* = -1.*$gdb_prompt $" {
+ pass "print value of s"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of s" }
+ timeout { fail "(timeout) print value of s" }
+ }
+
+
+send_gdb "ptype s\n"
+gdb_expect {
+ -re "type = short.*$gdb_prompt $" { pass "ptype s" }
+ -re ".*$gdb_prompt $" { fail "ptype s" }
+ timeout { fail "(timeout) ptype s" }
+}
+
+
+send_gdb "print *ps\n"
+gdb_expect {
+ -re ".\[0-9\]* = -1.*$gdb_prompt $" {
+ pass "print value of ps"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of ps" }
+ timeout { fail "(timeout) print value of ps" }
+ }
+
+
+send_gdb "ptype ps\n"
+gdb_expect {
+ -re "type = short \*.*$gdb_prompt $" { pass "ptype ps" }
+ -re ".*$gdb_prompt $" { fail "ptype ps" }
+ timeout { fail "(timeout) ptype ps" }
+}
+
+send_gdb "print as\[0\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of as\[0\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of as\[0\]" }
+ timeout { fail "(timeout) print value of as\[0\]" }
+ }
+
+
+send_gdb "ptype as\n"
+gdb_expect {
+ -re "type = short \\\[4\\\].*$gdb_prompt $" { pass "ptype as" }
+ -re "type = short int \\\[4\\\].*$gdb_prompt $" { pass "ptype as" }
+ -re ".*$gdb_prompt $" { fail "ptype as" }
+ timeout { fail "(timeout) ptype as" }
+}
+
+send_gdb "print as\[1\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1.*$gdb_prompt $" {
+ pass "print value of as\[1\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of as\[1\]" }
+ timeout { fail "(timeout) print value of as\[1\]" }
+ }
+
+send_gdb "print as\[2\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = 2.*$gdb_prompt $" {
+ pass "print value of as\[2\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of as\[2\]" }
+ timeout { fail "(timeout) print value of as\[2\]" }
+ }
+
+send_gdb "print as\[3\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = 3.*$gdb_prompt $" {
+ pass "print value of as\[3\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of as\[3\]" }
+ timeout { fail "(timeout) print value of as\[3\]" }
+ }
+
+send_gdb "print rs\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(short &\\) @$hex: -1.*$gdb_prompt $" {
+ pass "print value of rs"
+ }
+ -re ".\[0-9\]* = \\(short int &\\) @$hex: -1.*$gdb_prompt $" {
+ pass "print value of rs"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of rs" }
+ timeout { fail "(timeout) print value of rs" }
+ eof { fail "print rs ($GDB dumped core) (FIXME)" ; gdb_start_again ; }
+
+ }
+
+send_gdb "ptype rs\n"
+gdb_expect {
+ -re "type = short &.*$gdb_prompt $" { pass "ptype rs" }
+ -re "type = short int &.*$gdb_prompt $" { pass "ptype rs" }
+ -re ".*$gdb_prompt $" { fail "ptype rs" }
+ timeout { fail "(timeout) ptype rs" }
+}
+
+
+send_gdb "print *rps\n"
+gdb_expect {
+ -re ".\[0-9\]* = -1.*$gdb_prompt $" {
+ pass "print value of *rps"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of *rps" }
+ timeout { fail "(timeout) print value of *rps" }
+ }
+
+
+send_gdb "ptype rps\n"
+gdb_expect {
+ -re "type = short \\*&.*$gdb_prompt $" { pass "ptype rps" }
+ -re "type = short int \\*&.*$gdb_prompt $" { pass "ptype rps" }
+ -re ".*$gdb_prompt $" { fail "ptype rps" }
+ timeout { fail "(timeout) ptype rps" }
+}
+
+
+
+send_gdb "print ras\[0\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = 0.*$gdb_prompt $" {
+ pass "print value of ras\[0\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of ras\[0\]" }
+ timeout { fail "(timeout) print value of ras\[0\]" }
+ }
+
+
+send_gdb "ptype ras\n"
+gdb_expect {
+ -re "type = short \\\(&\\\)\\\[4\\\].*$gdb_prompt $" { pass "ptype ras" }
+ -re "type = short int \\\(&\\\)\\\[4\\\].*$gdb_prompt $" { pass "ptype ras" }
+ -re ".*$gdb_prompt $" { fail "ptype ras" }
+ timeout { fail "(timeout) ptype ras" }
+}
+
+send_gdb "print ras\[1\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1.*$gdb_prompt $" {
+ pass "print value of ras\[1\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of ras\[1\]" }
+ timeout { fail "(timeout) print value of ras\[1\]" }
+ }
+
+send_gdb "print ras\[2\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = 2.*$gdb_prompt $" {
+ pass "print value of ras\[2\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of ras\[2\]" }
+ timeout { fail "(timeout) print value of ras\[2\]" }
+ }
+
+send_gdb "print ras\[3\]\n"
+gdb_expect {
+ -re ".\[0-9\]* = 3.*$gdb_prompt $" {
+ pass "print value of ras\[3\]"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of ras\[3\]" }
+ timeout { fail "(timeout) print value of ras\[3\]" }
+ }
+
+
+if ![runto 'f'] then {
+ perror "couldn't run to f"
+ continue
+}
+
+gdb_test "up" ".main2.*" "up from f"
+
+send_gdb "print C\n"
+gdb_expect {
+ -re ".\[0-9\]* = 65 \'A\'.*$gdb_prompt $" {
+ pass "print value of C"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of C" }
+ timeout { fail "(timeout) print value of C" }
+ }
+
+
+send_gdb "ptype C\n"
+gdb_expect {
+ -re "type = char.*$gdb_prompt $" { pass "ptype C" }
+ -re ".*$gdb_prompt $" { fail "ptype C" }
+ timeout { fail "(timeout) ptype C" }
+}
+
+
+send_gdb "print UC\n"
+gdb_expect {
+ -re ".\[0-9\]* = 21 '\.025'\.*$gdb_prompt $" {
+ pass "print value of UC"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of UC" }
+ timeout { fail "(timeout) print value of UC" }
+ }
+
+
+send_gdb "ptype UC\n"
+gdb_expect {
+ -re "type = unsigned char.*$gdb_prompt $" { pass "ptype UC" }
+ -re ".*$gdb_prompt $" { fail "ptype UC" }
+ timeout { fail "(timeout) ptype UC" }
+}
+
+
+send_gdb "print S\n"
+gdb_expect {
+ -re ".\[0-9\]* = -14.*$gdb_prompt $" {
+ pass "print value of S"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of S" }
+ timeout { fail "(timeout) print value of S" }
+ }
+
+
+send_gdb "ptype S\n"
+gdb_expect {
+ -re "type = short.*$gdb_prompt $" { pass "ptype S" }
+ -re ".*$gdb_prompt $" { fail "ptype S" }
+ timeout { fail "(timeout) ptype S" }
+}
+
+
+send_gdb "print US\n"
+gdb_expect {
+ -re ".\[0-9\]* = 7.*$gdb_prompt $" {
+ pass "print value of US"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of US" }
+ timeout { fail "(timeout) print value of US" }
+ }
+
+
+send_gdb "ptype US\n"
+gdb_expect {
+ -re "type = unsigned short.*$gdb_prompt $" { pass "ptype US" }
+ -re "type = short unsigned.*$gdb_prompt $" { pass "ptype US" }
+ -re ".*$gdb_prompt $" { fail "ptype US" }
+ timeout { fail "(timeout) ptype US" }
+}
+
+
+send_gdb "print I\n"
+gdb_expect {
+ -re ".\[0-9\]* = 102.*$gdb_prompt $" {
+ pass "print value of I"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of I" }
+ timeout { fail "(timeout) print value of I" }
+ }
+
+
+send_gdb "ptype I\n"
+gdb_expect {
+ -re "type = int.*$gdb_prompt $" { pass "ptype I" }
+ -re ".*$gdb_prompt $" { fail "ptype I" }
+ timeout { fail "(timeout) ptype I" }
+}
+
+
+send_gdb "print UI\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1002.*$gdb_prompt $" {
+ pass "print value of UI"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of UI" }
+ timeout { fail "(timeout) print value of UI" }
+ }
+
+
+send_gdb "ptype UI\n"
+gdb_expect {
+ -re "type = unsigned int.*$gdb_prompt $" { pass "ptype UI" }
+ -re ".*$gdb_prompt $" { fail "ptype UI" }
+ timeout { fail "(timeout) ptype UI" }
+}
+
+
+send_gdb "print L\n"
+gdb_expect {
+ -re ".\[0-9\]* = -234.*$gdb_prompt $" {
+ pass "print value of L"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of L" }
+ timeout { fail "(timeout) print value of L" }
+ }
+
+
+send_gdb "ptype L\n"
+gdb_expect {
+ -re "type = long.*$gdb_prompt $" { pass "ptype L" }
+ -re ".*$gdb_prompt $" { fail "ptype L" }
+ timeout { fail "(timeout) ptype L" }
+}
+
+
+send_gdb "print UL\n"
+gdb_expect {
+ -re ".\[0-9\]* = 234.*$gdb_prompt $" {
+ pass "print value of UL"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of UL" }
+ timeout { fail "(timeout) print value of UL" }
+ }
+
+
+send_gdb "ptype UL\n"
+gdb_expect {
+ -re "type = unsigned long.*$gdb_prompt $" { pass "ptype UL" }
+ -re "type = long unsigned.*$gdb_prompt $" { pass "ptype UL" }
+ -re ".*$gdb_prompt $" { fail "ptype UL" }
+ timeout { fail "(timeout) ptype UL" }
+}
+
+
+send_gdb "print F\n"
+gdb_expect {
+ -re ".\[0-9\]* = 1.2\[0-9\]*e\\+10.*$gdb_prompt $" {
+ pass "print value of F"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of F" }
+ timeout { fail "(timeout) print value of F" }
+ }
+
+
+
+send_gdb "ptype F\n"
+gdb_expect {
+ -re "type = float.*$gdb_prompt $" { pass "ptype F" }
+ -re ".*$gdb_prompt $" { fail "ptype F" }
+ timeout { fail "(timeout) ptype F" }
+}
+
+
+send_gdb "print D\n"
+gdb_expect {
+ -re ".\[0-9\]* = -1.375e-123.*$gdb_prompt $" {
+ pass "print value of D"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of D" }
+ timeout { fail "(timeout) print value of D" }
+ }
+
+
+send_gdb "ptype D\n"
+gdb_expect {
+ -re "type = double.*$gdb_prompt $" { pass "ptype D" }
+ -re ".*$gdb_prompt $" { fail "ptype D" }
+ timeout { fail "(timeout) ptype D" }
+}
+
+
+
+#
+# test reference types
+#
+
+
+
+
+send_gdb "ptype rC\n"
+gdb_expect {
+ -re "type = char &.*$gdb_prompt $" { pass "ptype rC" }
+ -re ".*$gdb_prompt $" { fail "ptype rC" }
+ timeout { fail "(timeout) ptype rC" }
+}
+
+
+
+
+send_gdb "ptype rUC\n"
+gdb_expect {
+ -re "type = unsigned char &.*$gdb_prompt $" { pass "ptype rUC" }
+ -re ".*$gdb_prompt $" { fail "ptype rUC" }
+ timeout { fail "(timeout) ptype rUC" }
+}
+
+
+
+send_gdb "ptype rS\n"
+gdb_expect {
+ -re "type = short &.*$gdb_prompt $" { pass "ptype rS" }
+ -re "type = short int &.*$gdb_prompt $" { pass "ptype rS" }
+ -re ".*$gdb_prompt $" { fail "ptype rS" }
+ timeout { fail "(timeout) ptype rS" }
+}
+
+
+
+send_gdb "ptype rUS\n"
+gdb_expect {
+ -re "type = unsigned short &.*$gdb_prompt $" { pass "ptype rUS" }
+ -re "type = short unsigned int &.*$gdb_prompt $" { pass "ptype rUS" }
+ -re ".*$gdb_prompt $" { fail "ptype rUS" }
+ timeout { fail "(timeout) ptype rUS" }
+}
+
+
+send_gdb "ptype rI\n"
+gdb_expect {
+ -re "type = int &.*$gdb_prompt $" { pass "ptype rI" }
+ -re ".*$gdb_prompt $" { fail "ptype rI" }
+ timeout { fail "(timeout) ptype rI" }
+}
+
+
+
+send_gdb "ptype rUI\n"
+gdb_expect {
+ -re "type = unsigned int &.*$gdb_prompt $" { pass "ptype rUI" }
+ -re ".*$gdb_prompt $" { fail "ptype rUI" }
+ timeout { fail "(timeout) ptype rUI" }
+}
+
+
+
+send_gdb "ptype rL\n"
+gdb_expect {
+ -re "type = long &.*$gdb_prompt $" { pass "ptype rL" }
+ -re "type = long int &.*$gdb_prompt $" { pass "ptype rL" }
+ -re ".*$gdb_prompt $" { fail "ptype rL" }
+ timeout { fail "(timeout) ptype rL" }
+}
+
+
+send_gdb "ptype rUL\n"
+gdb_expect {
+ -re "type = unsigned long &.*$gdb_prompt $" { pass "ptype rUL" }
+ -re "type = long unsigned int &.*$gdb_prompt $" { pass "ptype rUL" }
+ -re ".*$gdb_prompt $" { fail "ptype rUL" }
+ timeout { fail "(timeout) ptype rUL" }
+}
+
+
+send_gdb "ptype rF\n"
+gdb_expect {
+ -re "type = float &.*$gdb_prompt $" { pass "ptype rF" }
+ -re ".*$gdb_prompt $" { fail "ptype rF" }
+ timeout { fail "(timeout) ptype rF" }
+}
+
+
+send_gdb "ptype rD\n"
+gdb_expect {
+ -re "type = double &.*$gdb_prompt $" { pass "ptype rD" }
+ -re ".*$gdb_prompt $" { fail "ptype rD" }
+ timeout { fail "(timeout) ptype rD" }
+}
+
+
+send_gdb "print rC\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(char &\\) @$hex: 65 \'A\'.*$gdb_prompt $" {
+ pass "print value of rC"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of rC" }
+ timeout { fail "(timeout) print value of rC" }
+ }
+
+
+send_gdb "print rUC\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(unsigned char &\\) @$hex: 21 \'.025\'.*$gdb_prompt $" {
+ pass "print value of rUC"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of rUC" }
+ timeout { fail "(timeout) print value of rUC" }
+ }
+
+
+send_gdb "print rS\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(short &\\) @$hex: -14.*$gdb_prompt $" {
+ pass "print value of rS"
+ }
+ -re ".\[0-9\]* = \\(short int &\\) @$hex: -14.*$gdb_prompt $" {
+ pass "print value of rS"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of rS" }
+ timeout { fail "(timeout) print value of rS" }
+ }
+
+
+send_gdb "print rUS\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(unsigned short &\\) @$hex: 7.*$gdb_prompt $" {
+ pass "print value of rUS"
+ }
+ -re ".\[0-9\]* = \\(short unsigned int &\\) @$hex: 7.*$gdb_prompt $" {
+ pass "print value of rUS"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of rUS" }
+ timeout { fail "(timeout) print value of rUS" }
+ }
+
+
+send_gdb "print rI\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(int &\\) @$hex: 102.*$gdb_prompt $" {
+ pass "print value of rI"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of rI" }
+ timeout { fail "(timeout) print value of rI" }
+ }
+
+
+send_gdb "print rUI\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(unsigned int &\\) @$hex: 1002.*$gdb_prompt $" {
+ pass "print value of UI"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of rUI" }
+ timeout { fail "(timeout) print value of rUI" }
+ }
+
+
+send_gdb "print rL\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(long &\\) @$hex: -234.*$gdb_prompt $" {
+ pass "print value of rL"
+ }
+ -re ".\[0-9\]* = \\(long int &\\) @$hex: -234.*$gdb_prompt $" {
+ pass "print value of rL"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of rL" }
+ timeout { fail "(timeout) print value of rL" }
+ }
+
+
+
+send_gdb "print rUL\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(unsigned long &\\) @$hex: 234.*$gdb_prompt $" {
+ pass "print value of rUL"
+ }
+ -re ".\[0-9\]* = \\(long unsigned int &\\) @$hex: 234.*$gdb_prompt $" {
+ pass "print value of rUL"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of rUL" }
+ timeout { fail "(timeout) print value of rUL" }
+ }
+
+
+send_gdb "print rF\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(float &\\) @$hex: 1.2\[0-9\]*e\\+10.*$gdb_prompt $" {
+ pass "print value of rF"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of rF" }
+ timeout { fail "(timeout) print value of rF" }
+ }
+
+
+send_gdb "print rD\n"
+gdb_expect {
+ -re ".\[0-9\]* = \\(double &\\) @$hex: -1.375e-123.*$gdb_prompt $" {
+ pass "print value of rD"
+ }
+ -re ".*$gdb_prompt $" { fail "print value of rD" }
+ timeout { fail "(timeout) print value of rD" }
+ }
+
diff --git a/gdb/testsuite/gdb.c++/templates.cc b/gdb/testsuite/gdb.c++/templates.cc
new file mode 100644
index 00000000000..c13f18b643f
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/templates.cc
@@ -0,0 +1,785 @@
+/* This test code is from Wendell Baker (wbaker@comet.berkeley.edu) */
+
+#include <stddef.h>
+
+int a_i;
+char a_c;
+double a_d;
+
+typedef void *Pix;
+
+int
+f(int i)
+{ return 0; }
+
+int
+f(int i, char c)
+{ return 0; }
+
+int
+f(int i, char c, double d)
+{ return 0; }
+
+int
+f(int i, char c, double d, char *cs)
+{ return 0; }
+
+int
+f(int i, char c, double d, char *cs, void (*fig)(int, char))
+{ return 0; }
+
+int
+f(int i, char c, double d, char *cs, void (*fig)(char, int))
+{ return 0; }
+
+class R {
+public:
+ int i;
+};
+class S {
+public:
+ int i;
+};
+class T {
+public:
+ int i;
+};
+
+char g(char, const char, volatile char)
+{ return 'c'; }
+char g(R, char&, const char&, volatile char&)
+{ return 'c'; }
+char g(char*, const char*, volatile char*)
+{ return 'c'; }
+char g(S, char*&, const char*&, volatile char*&)
+{ return 'c'; }
+
+signed char g(T,signed char, const signed char, volatile signed char)
+{ return 'c'; }
+signed char g(T, R, signed char&, const signed char&, volatile signed char&)
+{ return 'c'; }
+signed char g(T, signed char*, const signed char*, volatile signed char*)
+{ return 'c'; }
+signed char g(T, S, signed char*&, const signed char*&, volatile signed char*&)
+{ return 'c'; }
+
+unsigned char g(unsigned char, const unsigned char, volatile unsigned char)
+{ return 'c'; }
+unsigned char g(R, unsigned char&, const unsigned char&, volatile unsigned char&)
+{ return 'c'; }
+unsigned char g(unsigned char*, const unsigned char*, volatile unsigned char*)
+{ return 'c'; }
+unsigned char g(S, unsigned char*&, const unsigned char*&, volatile unsigned char*&)
+{ return 'c'; }
+
+short g(short, const short, volatile short)
+{ return 0; }
+short g(R, short&, const short&, volatile short&)
+{ return 0; }
+short g(short*, const short*, volatile short*)
+{ return 0; }
+short g(S, short*&, const short*&, volatile short*&)
+{ return 0; }
+
+signed short g(T, signed short, const signed short, volatile signed short)
+{ return 0; }
+signed short g(T, R, signed short&, const signed short&, volatile signed short&)
+{ return 0; }
+signed short g(T, signed short*, const signed short*, volatile signed short*)
+{ return 0; }
+signed short g(T, S, double, signed short*&, const signed short*&, volatile signed short*&)
+{ return 0; }
+
+unsigned short g(unsigned short, const unsigned short, volatile unsigned short)
+{ return 0; }
+unsigned short g(R, unsigned short&, const unsigned short&, volatile unsigned short&)
+{ return 0; }
+unsigned short g(unsigned short*, const unsigned short*, volatile unsigned short*)
+{ return 0; }
+unsigned short g(S, unsigned short*&, const unsigned short*&, volatile unsigned short*&)
+{ return 0; }
+
+int g(int, const int, volatile int)
+{ return 0; }
+int g(R, int&, const int&, volatile int&)
+{ return 0; }
+int g(int*, const int*, volatile int*)
+{ return 0; }
+int g(S, int*&, const int*&, volatile int*&)
+{ return 0; }
+
+signed int g(T, signed int, const signed int, volatile signed int)
+{ return 0; }
+signed int g(T, R, signed int&, const signed int&, volatile signed int&)
+{ return 0; }
+signed int g(T, signed int*, const signed int*, volatile signed int*)
+{ return 0; }
+signed int g(T, S, signed int*&, const signed int*&, volatile signed int*&)
+{ return 0; }
+
+unsigned int g(unsigned int, const unsigned int, volatile unsigned int)
+{ return 0; }
+unsigned int g(R, unsigned int&, const unsigned int&, volatile unsigned int&)
+{ return 0; }
+unsigned int g(unsigned int*, const unsigned int*, volatile unsigned int*)
+{ return 0; }
+unsigned int g(S, unsigned int*&, const unsigned int*&, volatile unsigned int*&)
+{ return 0; }
+
+long g(long, const long, volatile long)
+{ return 0; }
+long g(R, long&, const long&, volatile long&)
+{ return 0; }
+long g(long*, const long*, volatile long*)
+{ return 0; }
+long g(S, long*&, const long*&, volatile long*&)
+{ return 0; }
+
+signed long g(T, signed long, const signed long, volatile signed long)
+{ return 0; }
+signed long g(T, R, signed long&, const signed long&, volatile signed long&)
+{ return 0; }
+signed long g(T, signed long*, const signed long*, volatile signed long*)
+{ return 0; }
+signed long g(T, S, signed long*&, const signed long*&, volatile signed long*&)
+{ return 0; }
+
+unsigned long g(unsigned long, const unsigned long, volatile unsigned long)
+{ return 0; }
+unsigned long g(S, unsigned long&, const unsigned long&, volatile unsigned long&)
+{ return 0; }
+unsigned long g(unsigned long*, const unsigned long*, volatile unsigned long*)
+{ return 0; }
+unsigned long g(S, unsigned long*&, const unsigned long*&, volatile unsigned long*&)
+{ return 0; }
+
+#ifdef __GNUC__
+long long g(long long, const long long, volatile long long)
+{ return 0; }
+long long g(S, long long&, const long long&, volatile long long&)
+{ return 0; }
+long long g(long long*, const long long*, volatile long long*)
+{ return 0; }
+long long g(R, long long*&, const long long*&, volatile long long*&)
+{ return 0; }
+
+signed long long g(T, signed long long, const signed long long, volatile signed long long)
+{ return 0; }
+signed long long g(T, R, signed long long&, const signed long long&, volatile signed long long&)
+{ return 0; }
+signed long long g(T, signed long long*, const signed long long*, volatile signed long long*)
+{ return 0; }
+signed long long g(T, S, signed long long*&, const signed long long*&, volatile signed long long*&)
+{ return 0; }
+
+unsigned long long g(unsigned long long, const unsigned long long, volatile unsigned long long)
+{ return 0; }
+unsigned long long g(R, unsigned long long*, const unsigned long long*, volatile unsigned long long*)
+{ return 0; }
+unsigned long long g(unsigned long long&, const unsigned long long&, volatile unsigned long long&)
+{ return 0; }
+unsigned long long g(S, unsigned long long*&, const unsigned long long*&, volatile unsigned long long*&)
+{ return 0; }
+#endif
+
+float g(float, const float, volatile float)
+{ return 0; }
+float g(char, float&, const float&, volatile float&)
+{ return 0; }
+float g(float*, const float*, volatile float*)
+{ return 0; }
+float g(char, float*&, const float*&, volatile float*&)
+{ return 0; }
+
+double g(double, const double, volatile double)
+{ return 0; }
+double g(char, double&, const double&, volatile double&)
+{ return 0; }
+double g(double*, const double*, volatile double*)
+{ return 0; }
+double g(char, double*&, const double*&, volatile double*&)
+{ return 0; }
+
+#ifdef __GNUC__
+long double g(long double, const long double, volatile long double)
+{ return 0; }
+long double g(char, long double&, const long double&, volatile long double&)
+{ return 0; }
+long double g(long double*, const long double*, volatile long double*)
+{ return 0; }
+long double g(char, long double*&, const long double*&, volatile long double*&)
+{ return 0; }
+#endif
+
+class c {
+public:
+ c(int) {};
+ int i;
+};
+
+class c g(c, const c, volatile c)
+{ return 0; }
+c g(char, c&, const c&, volatile c&)
+{ return 0; }
+c g(c*, const c*, volatile c*)
+{ return 0; }
+c g(char, c*&, const c*&, volatile c*&)
+{ return 0; }
+
+/*
+void h(char = 'a')
+{ }
+void h(char, signed char = 'a')
+{ }
+void h(unsigned char = 'a')
+{ }
+*/
+/*
+void h(char = (char)'a')
+{ }
+void h(char, signed char = (signed char)'a')
+{ }
+void h(unsigned char = (unsigned char)'a')
+{ }
+
+
+void h(short = (short)43)
+{ }
+void h(char, signed short = (signed short)43)
+{ }
+void h(unsigned short = (unsigned short)43)
+{ }
+
+void h(int = (int)43)
+{ }
+void h(char, signed int = (signed int)43)
+{ }
+void h(unsigned int = (unsigned int)43)
+{ }
+
+
+void h(long = (long)43)
+{ }
+void h(char, signed long = (signed long)43)
+{ }
+void h(unsigned long = (unsigned long)43)
+{ }
+
+#ifdef __GNUC__
+void h(long long = 43)
+{ }
+void h(char, signed long long = 43)
+{ }
+void h(unsigned long long = 43)
+{ }
+#endif
+
+void h(float = 4.3e-10)
+{ }
+void h(double = 4.3)
+{ }
+#ifdef __GNUC__
+void h(long double = 4.33e33)
+{ }
+#endif
+*/
+
+/* An unneeded printf() definition - actually, just a stub - used to occupy
+ this space. It has been removed and replaced with this comment which
+ exists to occupy some lines so that templates.exp won't need adjustment. */
+
+class T1 {
+public:
+ static void* operator new(size_t) throw ();
+ static void operator delete(void *pointer);
+
+ void operator=(const T1&);
+ T1& operator=(int);
+
+ int operator==(int) const;
+ int operator==(const T1&) const;
+ int operator!=(int) const;
+ int operator!=(const T1&) const;
+
+ int operator<=(int) const;
+ int operator<=(const T1&) const;
+ int operator<(int) const;
+ int operator<(const T1&) const;
+ int operator>=(int) const;
+ int operator>=(const T1&) const;
+ int operator>(int) const;
+ int operator>(const T1&) const;
+
+ void operator+(int) const;
+ T1& operator+(const T1&) const;
+ void operator+=(int) const;
+ T1& operator+=(const T1&) const;
+
+ T1& operator++() const;
+
+ void operator-(int) const;
+ T1& operator-(const T1&) const;
+ void operator-=(int) const;
+ T1& operator-=(const T1&) const;
+
+ T1& operator--() const;
+
+ void operator*(int) const;
+ T1& operator*(const T1&) const;
+ void operator*=(int) const;
+ T1& operator*=(const T1&) const;
+
+ void operator/(int) const;
+ T1& operator/(const T1&) const;
+ void operator/=(int) const;
+ T1& operator/=(const T1&) const;
+
+ void operator%(int) const;
+ T1& operator%(const T1&) const;
+ void operator%=(int) const;
+ T1& operator%=(const T1&) const;
+
+ void operator&&(int) const;
+ T1& operator&&(const T1&) const;
+
+ void operator||(int) const;
+ T1& operator||(const T1&) const;
+
+ void operator&(int) const;
+ T1& operator&(const T1&) const;
+ void operator&=(int) const;
+ T1& operator&=(const T1&) const;
+
+ void operator|(int) const;
+ T1& operator|(const T1&) const;
+ void operator|=(int) const;
+ T1& operator|=(const T1&) const;
+
+ void operator^(int) const;
+ T1& operator^(const T1&) const;
+ void operator^=(int) const;
+ T1& operator^=(const T1&) const;
+
+ T1& operator!() const;
+ T1& operator~() const;
+};
+
+void*
+T1::operator new(size_t) throw ()
+{ return 0; }
+
+void
+T1::operator delete(void *pointer)
+{ }
+
+class T2 {
+public:
+ T2(int i): integer(i)
+ { }
+ int integer;
+};
+
+int operator==(const T2&, const T2&)
+{ return 0; }
+int operator==(const T2&, char)
+{ return 0; }
+int operator!=(const T2&, const T2&)
+{ return 0; }
+int operator!=(const T2&, char)
+{ return 0; }
+
+int operator<=(const T2&, const T2&)
+{ return 0; }
+int operator<=(const T2&, char)
+{ return 0; }
+int operator<(const T2&, const T2&)
+{ return 0; }
+int operator<(const T2&, char)
+{ return 0; }
+int operator>=(const T2&, const T2&)
+{ return 0; }
+int operator>=(const T2&, char)
+{ return 0; }
+int operator>(const T2&, const T2&)
+{ return 0; }
+int operator>(const T2&, char)
+{ return 0; }
+
+T2 operator+(const T2 t, int i)
+{ return t.integer + i; }
+T2 operator+(const T2 a, const T2& b)
+{ return a.integer + b.integer; }
+T2& operator+=(T2& t, int i)
+{ t.integer += i; return t; }
+T2& operator+=(T2& a, const T2& b)
+{ a.integer += b.integer; return a; }
+
+T2 operator-(const T2 t, int i)
+{ return t.integer - i; }
+T2 operator-(const T2 a, const T2& b)
+{ return a.integer - b.integer; }
+T2& operator-=(T2& t, int i)
+{ t.integer -= i; return t; }
+T2& operator-=(T2& a, const T2& b)
+{ a.integer -= b.integer; return a; }
+
+T2 operator*(const T2 t, int i)
+{ return t.integer * i; }
+T2 operator*(const T2 a, const T2& b)
+{ return a.integer * b.integer; }
+T2& operator*=(T2& t, int i)
+{ t.integer *= i; return t; }
+T2& operator*=(T2& a, const T2& b)
+{ a.integer *= b.integer; return a; }
+
+T2 operator/(const T2 t, int i)
+{ return t.integer / i; }
+T2 operator/(const T2 a, const T2& b)
+{ return a.integer / b.integer; }
+T2& operator/=(T2& t, int i)
+{ t.integer /= i; return t; }
+T2& operator/=(T2& a, const T2& b)
+{ a.integer /= b.integer; return a; }
+
+T2 operator%(const T2 t, int i)
+{ return t.integer % i; }
+T2 operator%(const T2 a, const T2& b)
+{ return a.integer % b.integer; }
+T2& operator%=(T2& t, int i)
+{ t.integer %= i; return t; }
+T2& operator%=(T2& a, const T2& b)
+{ a.integer %= b.integer; return a; }
+
+template<class T>
+class T5 {
+public:
+ T5(int);
+ T5(const T5<T>&);
+ ~T5();
+ static void* operator new(size_t) throw ();
+ static void operator delete(void *pointer);
+ int value();
+
+ static T X;
+ T x;
+ int val;
+};
+
+template<class T>
+T5<T>::T5(int v)
+{ val = v; }
+
+template<class T>
+T5<T>::T5(const T5<T>&)
+{}
+
+template<class T>
+T5<T>::~T5()
+{}
+
+template<class T>
+void*
+T5<T>::operator new(size_t) throw ()
+{ return 0; }
+
+template<class T>
+void
+T5<T>::operator delete(void *pointer)
+{ }
+
+template<class T>
+int
+T5<T>::value()
+{ return val; }
+
+
+#if ! defined(__GNUC__) || defined(GCC_BUG)
+template<class T>
+T T5<T>::X;
+#endif
+
+
+
+
+T5<char> t5c(1);
+T5<int> t5i(2);
+T5<int (*)(char, void *)> t5fi1(3);
+T5<int (*)(int, double **, void *)> t5fi2(4);
+
+
+
+
+
+
+class x {
+public:
+ int (*manage[5])(double,
+ void *(*malloc)(unsigned size),
+ void (*free)(void *pointer));
+ int (*device[5])(int open(const char *, unsigned mode, unsigned perms, int extra),
+ int *(*read)(int fd, void *place, unsigned size),
+ int *(*write)(int fd, void *place, unsigned size),
+ void (*close)(int fd));
+};
+T5<x> t5x(5);
+
+#if !defined(__GNUC__) || (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 6)
+template class T5<char>;
+template class T5<int>;
+template class T5<int (*)(char, void *)>;
+template class T5<int (*)(int, double **, void *)>;
+template class T5<x>;
+#endif
+
+class T7 {
+public:
+ static int get();
+ static void put(int);
+};
+
+int
+T7::get()
+{ return 1; }
+
+void
+T7::put(int i)
+{
+ // nothing
+}
+
+// More template kinds. GDB 4.16 didn't handle these, but
+// Wildebeest does. Note: Assuming HP aCC is used to compile
+// this file; with g++ or HP cfront or other compilers the
+// demangling may not get done correctly.
+
+// Ordinary template, to be instantiated with different types
+template<class T>
+class Foo {
+public:
+ int x;
+ T t;
+ T foo (int, T);
+};
+
+
+template<class T> T Foo<T>::foo (int i, T tt)
+{
+ return tt;
+}
+
+// Template with int parameter
+
+template<class T, int sz>
+class Bar {
+public:
+ int x;
+ T t;
+ T bar (int, T);
+};
+
+
+template<class T, int sz> T Bar<T, sz>::bar (int i, T tt)
+{
+ if (i < sz)
+ return tt;
+ else
+ return 0;
+}
+
+// function template with int parameter
+template<class T> int dummy (T tt, int i)
+{
+ return tt;
+}
+
+// Template with partial specializations
+template<class T1, class T2>
+class Spec {
+public:
+ int x;
+ T1 spec (T2);
+};
+
+template<class T1, class T2>
+T1 Spec<T1, T2>::spec (T2 t2)
+{
+ return 0;
+}
+
+template<class T>
+class Spec<T, T*> {
+public:
+ int x;
+ T spec (T*);
+};
+
+template<class T>
+T Spec<T, T*>::spec (T * tp)
+{
+ return *tp;
+}
+
+// Template with char parameter
+template<class T, char sz>
+class Baz {
+public:
+ int x;
+ T t;
+ T baz (int, T);
+};
+
+template<class T, char sz> T Baz<T, sz>::baz (int i, T tt)
+{
+ if (i < sz)
+ return tt;
+ else
+ return 0;
+}
+
+// Template with char * parameter
+template<class T, char * sz>
+class Qux {
+public:
+ int x;
+ T t;
+ T qux (int, T);
+};
+
+template<class T, char * sz> T Qux<T, sz>::qux (int i, T tt)
+{
+ if (sz[0] == 'q')
+ return tt;
+ else
+ return 0;
+}
+
+// Template with a function pointer parameter
+template<class T, int (*f)(int) >
+class Qux1 {
+public:
+ int x;
+ T t;
+ T qux (int, T);
+};
+
+template<class T, int (*f)(int)> T Qux1<T, f>::qux (int i, T tt)
+{
+ if (f != 0)
+ return tt;
+ else
+ return 0;
+}
+
+// Some functions to provide as arguments to template
+int gf1 (int a) {
+ return a * 2 + 13;
+}
+int gf2 (int a) {
+ return a * 2 + 26;
+}
+
+char string[3];
+
+
+// Template for nested instantiations
+
+template<class T>
+class Garply {
+public:
+ int x;
+ T t;
+ T garply (int, T);
+};
+
+template<class T> T Garply<T>::garply (int i, T tt)
+{
+ if (i > x)
+ return tt;
+ else
+ {
+ x += i;
+ return tt;
+ }
+}
+
+
+int main()
+{
+ int i;
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ i = i + 1;
+
+ // New tests added here
+
+ Foo<int> fint={0,0};
+ Foo<char> fchar={0,0};
+ Foo<volatile char *> fvpchar = {0, 0};
+
+ Bar<int, 33> bint;
+ Bar<int, (4 > 3)> bint2;
+
+ Baz<int, 's'> bazint;
+ Baz<char, 'a'> bazint2;
+
+ Qux<char, string> quxint2;
+ Qux<int, string> quxint;
+
+ Qux1<int, gf1> qux11;
+
+ int x = fint.foo(33, 47);
+ char c = fchar.foo(33, 'x');
+ volatile char * cp = fvpchar.foo(33, 0);
+
+ int y = dummy<int> (400, 600);
+
+ int z = bint.bar(55, 66);
+ z += bint2.bar(55, 66);
+
+ c = bazint2.baz(4, 'y');
+ c = quxint2.qux(4, 'z');
+
+ y = bazint.baz(4,3);
+ y = quxint.qux(4, 22);
+ y += qux11.qux(4, 22);
+
+ y *= gf1(y) - gf2(y);
+
+ Spec<int, char> sic;
+ Spec<int, int *> siip;
+
+ sic.spec ('c');
+ siip.spec (&x);
+
+ Garply<int> f;
+ Garply<char> fc;
+ f.x = 13;
+
+ Garply<Garply<char> > nf;
+ nf.x = 31;
+
+ x = f.garply (3, 4);
+
+ fc = nf.garply (3, fc);
+
+ y = x + fc.x;
+
+
+ return 0;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.c++/templates.exp b/gdb/testsuite/gdb.c++/templates.exp
new file mode 100644
index 00000000000..a6d35fcb116
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/templates.exp
@@ -0,0 +1,455 @@
+# Copyright 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2002
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+set ws "\[\r\n\t \]+"
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "templates"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile} "c++"] {
+ return -1
+}
+source ${binfile}.ci
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+#
+# Test printing of the types of templates.
+#
+
+proc test_ptype_of_templates {} {
+ global gdb_prompt
+ global ws
+
+ send_gdb "ptype T5<int>\n"
+ gdb_expect {
+ -re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}T5<int> & operator=\\(T5<int> const ?&\\);${ws}T5\\(int\\);${ws}T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\((void|)\\);${ws}static void \\* operator new\\(unsigned( int| long)?\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" {
+ pass "ptype T5<int>"
+ }
+ -re "type = class T5<int> \\{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}${ws}T5 \\(int\\);${ws}T5 \\(const class T5<int> &\\);${ws}void ~T5 \\(int\\);${ws}static void \\* new \\(unsigned int\\);${ws}static void delete \\(void ?\\*\\);${ws}int value \\((void|)\\);${ws}\\}${ws}$gdb_prompt $" { pass "ptype T5<int> -- new with unsigned int" }
+ -re "type = class T5<int> \\{.*public:.*static int X;.*int x;.*int val;.*T5 \\(int\\);.*T5 \\(const class T5<int> &\\);.*void ~T5 \\(int\\);.*static void \\* new \\(unsigned long\\);.*static void delete \\(void ?\\*\\);.*int value \\((void|)\\);.*\\}\r\n$gdb_prompt $" { pass "ptype T5<int> -- new with unsigned long" }
+ -re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;((${ws}T5<int> & operator=\\(T5<int> const ?&\\);)|(${ws}T5\\(int\\);)|(${ws}T5\\((T5<int> const|const T5<int>) ?&\\);)|(${ws}~T5\\((void|)\\);)|(${ws}static void \\* operator new\\(unsigned( int| long)?\\);)|(${ws}static void operator delete\\(void ?\\*\\);)|(${ws}int value\\((void|)\\);))*${ws}\}\r\n$gdb_prompt $" {
+ pass "ptype T5<int> (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype T5<int>"
+ }
+ timeout {
+ fail "ptype T5<int> (timeout)"
+ }
+ }
+
+ send_gdb "ptype t5i\n"
+ gdb_expect {
+ -re "type = class T5<int> \\{${ws}public:${ws}static int X;${ws}int x;${ws}int val;\r\n${ws}T5\\(int\\);${ws}T5\\(T5<int> const ?&\\);${ws}~T5\\((void|)\\);${ws}static void \\* operator new\\(unsigned( int| long)?\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\\}\r\n$gdb_prompt $" { pass "ptype T5<int> -- with several fixes from 4.17" }
+ -re "type = class T5<int> \\{${ws}public:${ws}static int X;${ws}int x;${ws}int val;\r\n${ws}T5 \\(int\\);${ws}T5 \\(const class T5<int> &\\);${ws}void ~T5 \\(int\\);${ws}static void \\* new \\(unsigned int\\);${ws}static void delete \\(void ?\\*\\);${ws}int value \\((void|)\\);${ws}\\}\r\n$gdb_prompt $" { pass "ptype t5i<int> -- new with unsigned int" }
+ -re "type = class T5<int> \\{${ws}public:${ws}static int X;${ws}int x;${ws}int val;\r\n${ws}T5 \\(int\\);${ws}T5 \\(const class T5<int> &\\);${ws}void ~T5 \\(int\\);${ws}static void \\* new \\(unsigned long\\);${ws}static void delete \\(void ?\\*\\);${ws}int value \\((void|)\\);${ws}\\}\r\n$gdb_prompt $" { pass "ptype t5i<int> -- new with unsigned long" }
+ -re "type = class T5<int> \{.*public:.*static int X;.*int x;.*int val;.*.*T5 \\(int\\);.*.*void ~T5 \\(int\\).*.*.*int value \\((void|)\\);.*\}.*$gdb_prompt $" {
+ pass "ptype t5i"
+ }
+ -re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}T5<int> & operator=\\(T5<int> const ?&\\);${ws}T5\\(int\\);${ws}T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\((void|)\\);${ws}static void \\* operator new\\(unsigned( int| long)?\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" {
+ pass "ptype t5i"
+ }
+ -re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;((${ws}T5<int> & operator=\\(T5<int> const ?&\\);)|(${ws}T5\\(int\\);)|(${ws}T5\\(T5<int> const ?&\\);)|(${ws}~T5\\((void|)\\);)|(${ws}static void \\* operator new\\(unsigned( int| long)?\\);)|(${ws}static void operator delete\\(void ?\\*\\);)|(${ws}int value\\((void|)\\);))*${ws}\}\r\n$gdb_prompt $" {
+ pass "ptype t5i (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype t5i"
+ }
+ timeout {
+ fail "ptype t5i (timeout)"
+ }
+ }
+}
+
+#
+# Test breakpoint setting on template methods.
+#
+
+proc test_template_breakpoints {} {
+ global gdb_prompt
+ global testfile
+ global srcdir
+ global hp_aCC_compiler
+
+ send_gdb "break T5<int>::T5\n"
+ gdb_expect {
+ -re "0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2. T5<int>::T5\\(int\\) at .*\[\r\n\]*.3. T5<int>::T5\\((T5<int> const|const T5<int>) ?&\\) at .*\[\r\n\]*> $" {
+ gdb_test "0" \
+ "canceled" \
+ "constructor breakpoint (obsolete format!)"
+ }
+ -re ".0. cancel\[\r\n\]*.1. all\[\r\n\]*.2. T5<int>::T5\\((T5<int> const|const T5<int>) ?&\\) at .*templates.cc:.*\[\r\n\]*.3. T5<int>::T5\\(int\\) at .*templates.cc:.*\[\r\n\]*> $" {
+ gdb_test "0" \
+ "canceled" \
+ "constructor breakpoint"
+ }
+ -re ".*\n> $" {
+ gdb_test "0" \
+ "nonsense intended to insure that this test fails" \
+ "constructor breakpoint (bad menu choices)"
+ }
+ -re ".*$gdb_prompt $" { fail "constructor breakpoint" }
+ default { fail "constructor breakpoint (timeout)" }
+ }
+
+# See CLLbs14792
+ if {$hp_aCC_compiler} {setup_xfail hppa*-*-* CLLbs14792}
+ gdb_test "break T5<int>::~T5" \
+ "Breakpoint.*at.* file .*${testfile}.cc, line.*" \
+ "destructor breakpoint"
+
+ gdb_test "break T5<int>::value" \
+ "Breakpoint.*at.* file .*${testfile}.cc, line.*" \
+ "value method breakpoint"
+
+ delete_breakpoints
+}
+
+#
+# Test calling of template methods.
+#
+
+proc test_template_calls {} {
+ global gdb_prompt
+ global hp_aCC_compiler
+
+ if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ return
+ }
+
+ if {!$hp_aCC_compiler} {setup_xfail hppa*-*-*}
+ send_gdb "print t5i.value()\n"
+ gdb_expect {
+ -re ".* = 2\[\r\n\]*$gdb_prompt $" { pass "print t5i.value()" }
+ -re "Cannot invoke functions on this machine.*$gdb_prompt $" {
+ fail "print t5i.value()"
+ }
+ -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
+ setup_xfail hppa*-*-* CLLbs16899
+ xfail "print t5i.value"
+ }
+ -re ".*$gdb_prompt $" { fail "print t5i.value()" }
+ timeout { fail "print t5i.value() (timeout)" }
+ }
+}
+
+
+proc do_tests {} {
+ global prms_id
+ global bug_id
+ global subdir
+ global objdir
+ global srcdir
+ global binfile
+ global gdb_prompt
+ global supports_template_debugging
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ if { !$supports_template_debugging } {
+ warning "compiler lacks debugging info for templates; tests suppressed." 0
+ return
+ }
+
+ # Get the debug format for the compiled test case. If that
+ # format is DWARF 1 then just skip all the tests since none of
+ # them will pass.
+
+ if [ runto_main] then {
+ get_debug_format
+ if [ setup_xfail_format "DWARF 1" ] then {
+ fail "C++ tests skipped due to limited C++ support in DWARF 1 debug format"
+ return
+ }
+ clear_xfail "*-*-*"
+ }
+
+ test_ptype_of_templates
+ test_template_breakpoints
+
+ if [ runto_main] {
+ test_template_calls
+ }
+}
+
+do_tests
+
+
+# More tests for different kinds of template parameters,
+# templates with partial specializations, nested templates, etc.
+# These have been tested only with HP aCC. They probably won't
+# work with other compilers because of differences in mangling
+# schemes.
+# Added by Satish Pai <pai@apollo.hp.com> 1997-09-25
+# As of 2000-06-03, C++ support has been improved to the point that g++ can
+# pass all of theses, excluding what appears to be one that exposes a stabs bug. - djb
+
+# I don't know how HP could be passing these tests without this. They
+# weren't breakpointing past a point where the below expressions were
+# initialized in the actual source. - djb
+
+send_gdb "b 770\n"
+gdb_expect {
+ -re ".*$gdb_prompt $"
+}
+send_gdb "c\n"
+gdb_expect {
+ -re ".*$gdb_prompt $"
+}
+send_gdb "print fint\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\{x = 0, t = 0\\}\r\n$gdb_prompt $" { pass "print fint" }
+ -re "$gdb_prompt $" { fail "print fint" }
+ timeout { fail "(timeout) print fint" }
+}
+
+send_gdb "print fvpchar\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\{x = 0, t = 0x0\\}\r\n$gdb_prompt $" { pass "print fvpchar" }
+ -re "$gdb_prompt $" { fail "print fvpchar" }
+ timeout { fail "(timeout) print fvpchar" }
+}
+
+# Template Foo<T>
+
+setup_xfail hppa64-*-* CLLbs16092
+# g++ can't do the template instantiation in debug info trick, so we
+# fail this because it's not a real type.
+if {!$hp_aCC_compiler} { setup_xfail *-*-* }
+send_gdb "ptype Foo\n"
+gdb_expect {
+ -re "type = template <(class |)T> (class |)Foo \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Foo<volatile char \\*>\r\n\[ \t\]*(class |)Foo<char>\r\n\[ \t\]*(class |)Foo<int>\r\n$gdb_prompt $" { pass "ptype Foo" }
+ -re "type = template <(class |)T> (class |)Foo \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\n$gdb_prompt $" { xfail "ptype Foo" }
+ -re "$gdb_prompt $" { fail "ptype Foo" }
+ timeout { fail "(timeout) ptype Foo" }
+}
+
+# ptype Foo<int>
+
+send_gdb "ptype fint\n"
+gdb_expect {
+ -re "type = (class |)Foo<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int foo\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype fint" }
+ -re "$gdb_prompt $" { fail "ptype fint" }
+ timeout { fail "(timeout) ptype fint" }
+}
+
+# ptype Foo<char>
+
+send_gdb "ptype fchar\n"
+gdb_expect {
+ -re "type = (class |)Foo<char> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*.*char foo\\(int, char\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype fchar" }
+ -re "$gdb_prompt $" { fail "ptype fchar" }
+ timeout { fail "(timeout) ptype fchar" }
+}
+
+# ptype Foo<volatile char *>
+
+send_gdb "ptype fvpchar\n"
+gdb_expect {
+ -re "type = (class |)Foo<volatile char ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*char.*\\*t;\r\n\r\n\[ \t\]*.*char \\* foo\\(int,.*char.*\\*\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype fvpchar" }
+ -re "$gdb_prompt $" { fail "ptype fvpchar" }
+ timeout { fail "(timeout) ptype fvpchar" }
+}
+
+# print a function from Foo<volatile char *>
+
+send_gdb "print Foo<volatile char *>::foo\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<volatile char \\*> \\*, int, .*char \\*\\)\\} $hex <Foo<.*char.*\\*>::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo<volatile char *>::foo" }
+ -re "$gdb_prompt $" { fail "print Foo<volatile char *>::foo" }
+ timeout { fail "(timeout) print Foo<volatile char *>::foo" }
+}
+
+# Template Bar<T, int>
+
+setup_xfail hppa64-*-* CLLbs16092
+# same as Foo for g++
+if {!$hp_aCC_compiler} { setup_xfail *-*-* }
+send_gdb "ptype Bar\n"
+gdb_expect {
+ -re "type = template <(class |)T, (class |)sz> (class |)Bar \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Bar<int,(\\(int\\)|)1>\r\n\[ \t\]*(class |)Bar<int,(\\(int\\)|)33>\r\n$gdb_prompt $" { pass "ptype Bar" }
+ -re "type = <(class |)T, (class |)sz> (class |)Bar \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\n$gdb_prompt $" { xfail "ptype Bar" }
+ -re "$gdb_prompt $" { fail "ptype Bar" }
+ timeout { fail "(timeout) ptype Bar" }
+}
+
+
+# ptype Bar<int,33>
+
+send_gdb "ptype bint\n"
+gdb_expect {
+ -re "type = (class |)Bar<int,(\\(int\\)|)33> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int bar\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype bint" }
+ -re "$gdb_prompt $" { fail "ptype bint" }
+ timeout { fail "(timeout) ptype bint" }
+}
+
+# ptype Bar<int, (4>3)>
+
+send_gdb "ptype bint2\n"
+gdb_expect {
+ -re "type = (class |)Bar<int,(\\(int\\)|)1> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int bar\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype bint2" }
+ -re "$gdb_prompt $" { fail "ptype bint2" }
+ timeout { fail "(timeout) ptype bint2" }
+}
+
+# Template Baz<T, char>
+
+setup_xfail hppa64-*-* CLLbs16092
+# Same as Foo, for g++
+if {!$hp_aCC_compiler} { setup_xfail *-*-* }
+send_gdb "ptype Baz\n"
+gdb_expect {
+ -re "type = template <(class |)T, (class |)sz> (class |)Baz \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Baz<char,(\\(char\\)|)97>\r\n\[ \t\]*(class |)Baz<int,(\\(char\\)|)115>\r\n$gdb_prompt $" { pass "ptype Baz" }
+ -re "type = <(class |)T, (class |)sz> (class |)Baz \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\n$gdb_prompt $" { xfail "ptype Baz" }
+ -re "$gdb_prompt $" { fail "ptype Baz" }
+ timeout { fail "(timeout) ptype Baz" }
+}
+
+
+# ptype Baz<int, 's'>
+
+send_gdb "ptype bazint\n"
+gdb_expect {
+ -re "type = (class |)Baz<int,(\\(char\\)|)(115|\\'s\\')> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int baz\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype bazint" }
+ -re "$gdb_prompt $" { fail "ptype bazint" }
+ timeout { fail "(timeout) ptype bazint" }
+}
+
+# ptype Baz<char, 'a'>
+
+send_gdb "ptype bazint2\n"
+gdb_expect {
+ -re "type = (class |)Baz<char,(\\(char\\)|)(97|\\'a\\')> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*.*char baz\\(int, char\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype bazint2" }
+ -re "$gdb_prompt $" { fail "ptype bazint2" }
+ timeout { fail "(timeout) ptype bazint2" }
+}
+
+# Template Qux<T, int (*f)(int) >
+# Same as Foo for g++
+if {!$hp_aCC_compiler} {setup_xfail *-*-*}
+send_gdb "ptype Qux\n"
+gdb_expect {
+ -re "type = template <(class |)T, (class |)sz> (class |)Qux \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Qux<int,&string>\r\n\[ \t\]*(class |)Qux<char,&string>\r\n$gdb_prompt $" { pass "ptype Qux" }
+ -re ".*type = template <(class |)T.*, (class |)sz> (class |)Qux \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}.*$gdb_prompt $" { pass "ptype Qux" }
+ -re "$gdb_prompt $" { fail "ptype Qux" }
+ timeout { fail "(timeout) ptype Qux" }
+}
+
+# pt Qux<int,&string>
+
+send_gdb "ptype quxint\n"
+gdb_expect {
+ -re "type = class Qux<int,&string> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int qux\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint" }
+ -re "$gdb_prompt $" { fail "ptype quxint" }
+ timeout { fail "(timeout) ptype quxint" }
+}
+
+# pt Qux<char,0>
+
+# commented out this as quxint2 declaration was commented out in
+# templates.exp -- ovidiu
+# send_gdb "ptype quxint2\n"
+# gdb_expect {
+# -re "type = class Qux<char,&string> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*char qux\\(int, char\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint2" }
+# -re "$gdb_prompt $" { fail "ptype quxint2" }
+# timeout { fail "(timeout) ptype quxint2" }
+# }
+
+# Template Spec<T1, T2>
+
+setup_xfail hppa64-*-* CLLbs16092
+# Same as Foo for g++
+if {!$hp_aCC_compiler} { setup_xfail *-*-* }
+send_gdb "ptype Spec\n"
+gdb_expect {
+ -re "type = template <(class |)T1, (class |)T2> (class |)Spec \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Spec<int,int \\*>\r\n\[ \t\]*(class |)Spec<int,char>\r\n$gdb_prompt $" { pass "ptype Spec" }
+ -re "type = <(class |)T1, (class |)T2> (class |)Spec \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\\}\r\n$gdb_prompt $" { xfail "ptype Spec" }
+ -re "$gdb_prompt $" { fail "ptype Spec" }
+ timeout { fail "(timeout) ptype Spec" }
+}
+
+# pt Spec<char,0>
+
+send_gdb "ptype siip\n"
+gdb_expect {
+ -re "type = class Spec<int,int ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\r\n\[ \t\]*.*int spec\\(int ?\\*\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype siip" }
+ -re "$gdb_prompt $" { fail "ptype siip" }
+ timeout { fail "(timeout) ptype siip" }
+}
+
+# pt Garply<int>
+
+send_gdb "ptype Garply<int>\n"
+gdb_expect {
+ -re "type = class Garply<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int garply\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype Garply<int>" }
+ -re "$gdb_prompt $" { fail "ptype Garply<int>" }
+ timeout { fail "(timeout) ptype Garply<int>" }
+}
+
+# ptype of nested template name
+
+send_gdb "ptype Garply<Garply<char> >\n"
+gdb_expect {
+ -re "type = (class |)Garply<Garply<char> > \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*(class |)Garply<char> t;\r\n\r\n\[ \t\]*.*(class |)Garply<char> garply\\(int, (class |)Garply<char>\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype Garply<Garply<char> >" }
+ -re "$gdb_prompt $" { fail "ptype Garply<Garply<char> >" }
+ timeout { fail "(timeout) ptype Garply<Garply<char> >" }
+}
+
+# print out a function from a nested template name
+
+send_gdb "print Garply<Garply<char> >::garply\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\{(class |)Garply<char> \\((class |)Garply<Garply<char> > \\*, int, (class |)Garply<char>\\)\\} $hex <Garply<Garply<char>\[ \t\]*>::garply\\(int, (class |)Garply<char>\\)>\r\n$gdb_prompt $" { pass "print Garply<Garply<char> >::garply" }
+ -re ".*$gdb_prompt $" { fail "print Garply<Garply<char> >::garply" }
+ timeout { fail "print Garply<Garply<char> >::garply (timeout)" }
+}
+
+# djb - 06-03-2000
+# Now should work fine
+send_gdb "break Garply<Garply<char> >::garply\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]* at $hex: file .*templates.cc, line.*\r\n$gdb_prompt $" { pass "break Garply<Garply<char> >::garply" }
+ -re ".*$gdb_prompt $" { fail "break Garply<Garply<char> >::garply" }
+ timeout { fail "break Garply<Garply<char> >::garply (timeout)" }
+}
diff --git a/gdb/testsuite/gdb.c++/try_catch.cc b/gdb/testsuite/gdb.c++/try_catch.cc
new file mode 100644
index 00000000000..9a9c737b55d
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/try_catch.cc
@@ -0,0 +1,126 @@
+// 2002-05-27
+
+#include <exception>
+#include <stdexcept>
+#include <string>
+
+namespace __gnu_test
+{
+ enum region { oriental, egyptian, greek, etruscan, roman };
+
+ // Test one.
+ class gnu_obj_1
+ {
+ public:
+ typedef region antiquities;
+ const bool test;
+ const int key1;
+ long key2;
+
+ antiquities value;
+
+ gnu_obj_1(antiquities a, long l): test(true), key1(5), key2(l), value(a) {}
+ };
+
+ // Test two.
+ template<typename T>
+ class gnu_obj_2: public virtual gnu_obj_1
+ {
+ public:
+ antiquities value_derived;
+
+ gnu_obj_2(antiquities b): gnu_obj_1(oriental, 7), value_derived(b) { }
+ };
+
+ // Test three.
+ template<typename T>
+ class gnu_obj_3
+ {
+ public:
+ typedef region antiquities;
+ gnu_obj_2<int> data;
+
+ gnu_obj_3(antiquities b): data(etruscan) { }
+ };
+}
+
+int main()
+{
+ using namespace __gnu_test;
+
+ bool test = true;
+ const int i = 5;
+ int j = i;
+ gnu_obj_2<long> test2(roman);
+ gnu_obj_3<long> test3(greek);
+
+ // 1
+ try
+ {
+ ++j;
+ throw gnu_obj_1(egyptian, 4589);
+ }
+ catch (gnu_obj_1& obj)
+ {
+ ++j;
+ if (obj.value != egyptian)
+ test &= false;
+ if (obj.key2 != 4589)
+ test &= false;
+ }
+ catch (...)
+ {
+ j = 0;
+ test &= false;
+ }
+
+ // 2
+ try
+ {
+ ++j;
+ try
+ {
+ ++j;
+ try
+ {
+ ++j;
+ throw gnu_obj_1(egyptian, 4589);
+ }
+ catch (gnu_obj_1& obj)
+ {
+ ++j;
+ if (obj.value != egyptian)
+ test &= false;
+ if (obj.key2 != 4589)
+ test &= false;
+ }
+ }
+ catch (gnu_obj_1& obj)
+ {
+ ++j;
+ if (obj.value != egyptian)
+ test &= false;
+ if (obj.key2 != 4589)
+ test &= false;
+ }
+ }
+ catch (...)
+ {
+ j = 0;
+ test &= false;
+ }
+
+ // 3 use standard library
+ using namespace std;
+ try
+ {
+ if (j < 100)
+ throw invalid_argument("gdb.1");
+ }
+ catch (exception& obj)
+ {
+ if (obj.what() != "gdb.1")
+ test &= false;
+ }
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.c++/try_catch.exp b/gdb/testsuite/gdb.c++/try_catch.exp
new file mode 100644
index 00000000000..e024132b99e
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/try_catch.exp
@@ -0,0 +1,84 @@
+# Copyright 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Tests for member data
+# 2002-05-27 Benjamin Kosnik <bkoz@redhat.com>
+
+# This file is part of the gdb testsuite
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+if { [skip_cplus_tests] } { continue }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "try_catch"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile} "c++"] {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+# One.
+
+gdb_test "break 61" "Breakpoint \[0-9\]*.*line 61\\."
+gdb_test "continue" "Continuing\\.\r\n\r\nBreakpoint.*at.*try_catch\\.cc:61\r\n.*" "continue to 61"
+
+gdb_test "break 66" "Breakpoint \[0-9\]*.*line 66\\."
+gdb_test "continue" "Continuing\\.\r\n\r\nBreakpoint.*at.*try_catch\\.cc:66\r\n.*" "continue to 66"
+
+gdb_test "break 80" "Breakpoint \[0-9\]*.*line 80\\."
+gdb_test "continue" "Continuing\\.\r\n\r\nBreakpoint.*at.*try_catch\\.cc:80\r\n.*" "continue to 80"
+
+gdb_test "break 83" "Breakpoint \[0-9\]*.*line 83\\."
+gdb_test "continue" "Continuing\\.\r\n\r\nBreakpoint.*at.*try_catch\\.cc:83\r\n.*" "continue to 83"
+
+gdb_test "break 87" "Breakpoint \[0-9\]*.*line 87\\."
+gdb_test "continue" "Continuing\\.\r\n\r\nBreakpoint.*at.*try_catch\\.cc:87\r\n.*" "continue to 87"
+
+gdb_test "break 92" "Breakpoint \[0-9\]*.*line 92\\."
+gdb_test "continue" "Continuing\\.\r\n\r\nBreakpoint.*at.*try_catch\\.cc:92\r\n.*" "continue to 92"
+
+gdb_test "break 118" "Breakpoint \[0-9\]*.*line 118\\."
+gdb_test "continue" "Continuing\\.\r\n\r\nBreakpoint.*at.*try_catch\\.cc:118\r\n.*" "continue to 118"
+
+gdb_test "break 122" "Breakpoint \[0-9\]*.*line 122\\."
+gdb_test "continue" "Continuing\\.\r\n\r\nBreakpoint.*at.*try_catch\\.cc:122\r\n.*" "continue to 122"
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.c++/userdef.cc b/gdb/testsuite/gdb.c++/userdef.cc
new file mode 100644
index 00000000000..95a40552718
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/userdef.cc
@@ -0,0 +1,341 @@
+#include <iostream>
+
+using namespace std;
+
+void marker1()
+{
+ return;
+}
+
+class A1 {
+ int x;
+ int y;
+
+friend ostream& operator<<(ostream& outs, A1 one);
+
+public:
+
+ A1(int a, int b)
+ {
+ x=a;
+ y=b;
+ }
+
+A1 operator+=(int value);
+A1 operator+(const A1&);
+A1 operator-(const A1&);
+A1 operator%(const A1&);
+int operator==(const A1&);
+int operator!=(const A1&);
+int operator&&(const A1&);
+int operator||(const A1&);
+A1 operator<<(int);
+A1 operator>>(int);
+A1 operator|(const A1&);
+A1 operator^(const A1&);
+A1 operator&(const A1&);
+int operator<(const A1&);
+int operator<=(const A1&);
+int operator>=(const A1&);
+int operator>(const A1&);
+A1 operator*(const A1&);
+A1 operator/(const A1&);
+A1 operator=(const A1&);
+
+A1 operator~();
+A1 operator-();
+int operator!();
+A1 operator++();
+A1 operator++(int);
+A1 operator--();
+A1 operator--(int);
+
+};
+
+
+A1 A1::operator+(const A1& second)
+{
+ A1 sum(0,0);
+ sum.x = x + second.x;
+ sum.y = y + second.y;
+
+ return (sum);
+}
+
+A1 A1::operator*(const A1& second)
+{
+ A1 product(0,0);
+ product.x = this->x * second.x;
+ product.y = this->y * second.y;
+
+ return product;
+}
+
+A1 A1::operator-(const A1& second)
+{
+ A1 diff(0,0);
+ diff.x = x - second.x;
+ diff.y = y - second.y;
+
+ return diff;
+}
+
+A1 A1::operator/(const A1& second)
+{
+ A1 div(0,0);
+ div.x = x / second.x;
+ div.y = y / second.y;
+
+ return div;
+}
+
+A1 A1::operator%(const A1& second)
+{
+ A1 rem(0,0);
+ rem.x = x % second.x;
+ rem.y = y % second.y;
+
+ return rem;
+}
+
+int A1::operator==(const A1& second)
+{
+ int a = (x == second.x);
+ int b = (y == second.y);
+
+ return (a && b);
+}
+
+int A1::operator!=(const A1& second)
+{
+ int a = (x != second.x);
+ int b = (y != second.y);
+
+ return (a || b);
+}
+
+int A1::operator&&(const A1& second)
+{
+ return ( x && second.x);
+}
+
+int A1::operator||(const A1& second)
+{
+ return ( x || second.x);
+}
+
+A1 A1::operator<<(int value)
+{
+ A1 lshft(0,0);
+ lshft.x = x << value;
+ lshft.y = y << value;
+
+ return lshft;
+}
+
+A1 A1::operator>>(int value)
+{
+ A1 rshft(0,0);
+ rshft.x = x >> value;
+ rshft.y = y >> value;
+
+ return rshft;
+}
+
+A1 A1::operator|(const A1& second)
+{
+ A1 abitor(0,0);
+ abitor.x = x | second.x;
+ abitor.y = y | second.y;
+
+ return abitor;
+}
+
+A1 A1::operator^(const A1& second)
+{
+ A1 axor(0,0);
+ axor.x = x ^ second.x;
+ axor.y = y ^ second.y;
+
+ return axor;
+}
+
+A1 A1::operator&(const A1& second)
+{
+ A1 abitand(0,0);
+ abitand.x = x & second.x;
+ abitand.y = y & second.y;
+
+ return abitand;
+}
+
+int A1::operator<(const A1& second)
+{
+ A1 b(0,0);
+ b.x = 3;
+ return (x < second.x);
+}
+
+int A1::operator<=(const A1& second)
+{
+ return (x <= second.x);
+}
+
+int A1::operator>=(const A1& second)
+{
+ return (x >= second.x);
+}
+
+int A1::operator>(const A1& second)
+{
+ return (x > second.x);
+}
+
+int A1::operator!(void)
+{
+ return (!x);
+}
+
+A1 A1::operator-(void)
+{
+ A1 neg(0,0);
+ neg.x = -x;
+ neg.y = -y;
+
+ return (neg);
+}
+
+A1 A1::operator~(void)
+{
+ A1 acompl(0,0);
+ acompl.x = ~x;
+ acompl.y = ~y;
+
+ return (acompl);
+}
+
+A1 A1::operator++() // pre increment
+{
+ x = x +1;
+
+ return (*this);
+}
+
+A1 A1::operator++(int) // post increment
+{
+ y = y +1;
+
+ return (*this);
+}
+
+A1 A1::operator--() // pre decrement
+{
+ x = x -1;
+
+ return (*this);
+}
+
+A1 A1::operator--(int) // post decrement
+{
+ y = y -1;
+
+ return (*this);
+}
+
+
+A1 A1::operator=(const A1& second)
+{
+
+ x = second.x;
+ y = second.y;
+
+ return (*this);
+}
+
+A1 A1::operator+=(int value)
+{
+
+ x += value;
+ y += value;
+
+ return (*this);
+}
+
+ostream& operator<<(ostream& outs, A1 one)
+{
+ return (outs << endl << "x = " << one.x << endl << "y = " << one.y << endl << "-------" << endl);
+}
+
+int main (void)
+{
+ A1 one(2,3);
+ A1 two(4,5);
+ A1 three(0,0);
+ int val;
+
+ marker1();
+ cout << one;
+ cout << two;
+ three = one + two;
+ cout << "+ " << three;
+ three = one - two;
+ cout << "- " << three;
+ three = one * two;
+ cout <<"* " << three;
+ three = one / two;
+ cout << "/ " << three;
+ three = one % two;
+ cout << "% " << three;
+ three = one | two;
+ cout << "| " <<three;
+ three = one ^ two;
+ cout << "^ " <<three;
+ three = one & two;
+ cout << "& "<< three;
+
+ val = one && two;
+ cout << "&& " << val << endl << "-----"<<endl;
+ val = one || two;
+ cout << "|| " << val << endl << "-----"<<endl;
+ val = one == two;
+ cout << " == " << val << endl << "-----"<<endl;
+ val = one != two;
+ cout << "!= " << val << endl << "-----"<<endl;
+ val = one >= two;
+ cout << ">= " << val << endl << "-----"<<endl;
+ val = one <= two;
+ cout << "<= " << val << endl << "-----"<<endl;
+ val = one < two;
+ cout << "< " << val << endl << "-----"<<endl;
+ val = one > two;
+ cout << "> " << val << endl << "-----"<<endl;
+
+ three = one << 2;
+ cout << "lsh " << three;
+ three = one >> 2;
+ cout << "rsh " << three;
+
+ three = one;
+ cout << " = "<< three;
+ three += 5;
+ cout << " += "<< three;
+
+ val = (!one);
+ cout << "! " << val << endl << "-----"<<endl;
+ three = (-one);
+ cout << "- " << three;
+ three = (~one);
+ cout << " ~" << three;
+ three++;
+ cout << "postinc " << three;
+ three--;
+ cout << "postdec " << three;
+
+ --three;
+ cout << "predec " << three;
+ ++three;
+ cout << "preinc " << three;
+
+ return 0;
+
+}
diff --git a/gdb/testsuite/gdb.c++/userdef.exp b/gdb/testsuite/gdb.c++/userdef.exp
new file mode 100644
index 00000000000..a46aba60564
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/userdef.exp
@@ -0,0 +1,131 @@
+# Tests of overloaded operators resolution.
+# Copyright 1998, 1999, 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# written by Elena Zannoni (ezannoni@cygnus.com)
+#
+# source file "userdef.cc"
+#
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "userdef"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+send_gdb "break marker1\n" ; gdb_expect -re ".*$gdb_prompt $"
+ send_gdb "cont\n"
+ gdb_expect {
+ -re "Break.* marker1(\\(\\)|) \\(\\) at .*:$decimal.*$gdb_prompt $" {
+ send_gdb "up\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" { pass "up from marker1" }
+ timeout { fail "up from marker1" }
+ }
+ }
+ -re "$gdb_prompt $" { fail "continue to marker1" }
+ timeout { fail "(timeout) continue to marker1" }
+ }
+
+
+gdb_test "print one + two" "\\\$\[0-9\]* = {x = 6, y = 8}"
+
+gdb_test "print one - two" "\\\$\[0-9\]* = {x = -2, y = -2}"
+
+gdb_test "print one * two" "\\\$\[0-9\]* = {x = 8, y = 15}"
+
+gdb_test "print one / two" "\\\$\[0-9\]* = {x = 0, y = 0}"
+
+gdb_test "print one % two" "\\\$\[0-9\]* = {x = 2, y = 3}"
+
+gdb_test "print one && two" "\\\$\[0-9\]* = 1\[\r\n\]"
+
+gdb_test "print one || two" "\\\$\[0-9\]* = 1\[\r\n\]"
+
+gdb_test "print one & two" "\\\$\[0-9\]* = {x = 0, y = 1}"
+
+gdb_test "print one | two" "\\\$\[0-9\]* = {x = 6, y = 7}"
+
+gdb_test "print one ^ two" "\\\$\[0-9\]* = {x = 6, y = 6}"
+
+gdb_test "print one < two" "\\\$\[0-9\]* = 1\[\r\n\]"
+
+gdb_test "print one <= two" "\\\$\[0-9\]* = 1\[\r\n\]"
+
+gdb_test "print one > two" "\\\$\[0-9\]* = 0\[\r\n\]"
+
+gdb_test "print one >= two" "\\\$\[0-9\]* = 0\[\r\n\]"
+
+gdb_test "print one == two" "\\\$\[0-9\]* = 0\[\r\n\]"
+
+gdb_test "print one != two" "\\\$\[0-9\]* = 1\[\r\n\]"
+
+# Can't really check the output of this one without knowing
+# target integer width. Make sure we don't try to call
+# the iostreams operator instead, though.
+gdb_test "print one << 31" "\\\$\[0-9\]* = {x = -?\[0-9\]*, y = -?\[0-9\]*}"
+
+# Should be fine even on < 32-bit targets.
+gdb_test "print one >> 31" "\\\$\[0-9\]* = {x = 0, y = 0}"
+
+gdb_test "print !one" "\\\$\[0-9\]* = 0\[\r\n\]"
+
+# Assumes 2's complement. So does everything...
+gdb_test "print ~one" "\\\$\[0-9\]* = {x = -3, y = -4}"
+
+gdb_test "print -one" "\\\$\[0-9\]* = {x = -2, y = -3}"
+
+gdb_test "print one++" "\\\$\[0-9\]* = {x = 2, y = 4}"
+
+gdb_test "print ++one" "\\\$\[0-9\]* = {x = 3, y = 4}"
+
+gdb_test "print one--" "\\\$\[0-9\]* = {x = 3, y = 3}"
+
+gdb_test "print --one" "\\\$\[0-9\]* = {x = 2, y = 3}"
+
+gdb_test "print one += 7" "\\\$\[0-9\]* = {x = 9, y = 10}"
+
+gdb_test "print two = one" "\\\$\[0-9\]* = {x = 9, y = 10}"
+
+# Check that GDB tolerates whitespace in operator names.
+gdb_test "break A1::'operator+'" ".*Breakpoint $decimal at.*"
+gdb_test "break A1::'operator +'" ".*Breakpoint $decimal at.*"
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.c++/virtfunc.cc b/gdb/testsuite/gdb.c++/virtfunc.cc
new file mode 100644
index 00000000000..005de9d0ea6
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/virtfunc.cc
@@ -0,0 +1,201 @@
+// Pls try the following program on virtual functions and try to do print on
+// most of the code in main(). Almost none of them works !
+
+//
+// The inheritance structure is:
+//
+// V : VA VB
+// A : (V)
+// B : A
+// D : AD (V)
+// C : (V)
+// E : B (V) D C
+//
+
+class VA
+{
+public:
+ int va;
+};
+
+class VB
+{
+public:
+ int vb;
+ int fvb();
+ virtual int vvb();
+};
+
+class V : public VA, public VB
+{
+public:
+ int f();
+ virtual int vv();
+ int w;
+};
+
+class A : virtual public V
+{
+public:
+ virtual int f();
+private:
+ int a;
+};
+
+class B : public A
+{
+public:
+ int f();
+private:
+ int b;
+};
+
+class C : public virtual V
+{
+public:
+ int c;
+};
+
+class AD
+{
+public:
+ virtual int vg() = 0;
+};
+
+class D : public AD, virtual public V
+{
+public:
+ static void s();
+ virtual int vg();
+ virtual int vd();
+ int fd();
+ int d;
+};
+
+class E : public B, virtual public V, public D, public C
+{
+public:
+ int f();
+ int vg();
+ int vv();
+ int e;
+};
+
+D dd;
+D* ppd = &dd;
+AD* pAd = &dd;
+
+A a;
+B b;
+C c;
+D d;
+E e;
+V v;
+VB vb;
+
+
+A* pAa = &a;
+A* pAe = &e;
+
+B* pBe = &e;
+
+D* pDd = &d;
+D* pDe = &e;
+
+V* pVa = &a;
+V* pVv = &v;
+V* pVe = &e;
+V* pVd = &d;
+
+AD* pADe = &e;
+
+E* pEe = &e;
+
+VB* pVB = &vb;
+
+void init()
+{
+ a.vb = 1;
+ b.vb = 2;
+ c.vb = 3;
+ d.vb = 4;
+ e.vb = 5;
+ v.vb = 6;
+ vb.vb = 7;
+
+ d.d = 1;
+ e.d = 2;
+}
+
+extern "C" int printf(const char *, ...);
+
+int all_count = 0;
+int failed_count = 0;
+
+#define TEST(EXPR, EXPECTED) \
+ ret = EXPR; \
+ if (ret != EXPECTED) {\
+ printf("Failed %s is %d, should be %d!\n", #EXPR, ret, EXPECTED); \
+ failed_count++; } \
+ all_count++;
+
+int ret;
+
+void test_calls()
+{
+ TEST(pAe->f(), 20);
+ TEST(pAa->f(), 1);
+
+ TEST(pDe->vg(), 202);
+ TEST(pADe->vg(), 202);
+ TEST(pDd->vg(), 101);
+
+ TEST(pEe->vvb(), 411);
+
+ TEST(pVB->vvb(), 407);
+
+ TEST(pBe->vvb(), 411);
+ TEST(pDe->vvb(), 411);
+
+ TEST(pEe->vd(), 282);
+ TEST(pEe->fvb(), 311);
+
+ TEST(pEe->D::vg(), 102);
+ printf("Did %d tests, of which %d failed.\n", all_count, failed_count);
+}
+#ifdef usestubs
+extern "C" {
+ void set_debug_traps();
+ void breakpoint();
+};
+#endif
+
+int main()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ init();
+
+ e.w = 7;
+ e.vb = 11;
+
+ test_calls();
+ return 0;
+
+}
+
+int A::f() {return 1;}
+int B::f() {return 2;}
+void D::s() {}
+int E::f() {return 20;}
+int D::vg() {return 100+d;}
+int E::vg() {return 200+d;}
+int V::f() {return 600+w;}
+int V::vv() {return 400+w;}
+int E::vv() {return 450+w;}
+int D::fd() {return 250+d;}
+int D::vd() {return 280+d;}
+int VB::fvb() {return 300+vb;}
+int VB::vvb() {return 400+vb;}
diff --git a/gdb/testsuite/gdb.c++/virtfunc.exp b/gdb/testsuite/gdb.c++/virtfunc.exp
new file mode 100644
index 00000000000..e2befd35a98
--- /dev/null
+++ b/gdb/testsuite/gdb.c++/virtfunc.exp
@@ -0,0 +1,967 @@
+# Copyright 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+set ws "\[\r\n\t \]+"
+set nl "\[\r\n\]+"
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "virtfunc"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile} "c++"] {
+ return -1
+}
+
+source ${binfile}.ci
+
+set src "${srcdir}/${subdir}/${srcfile}"
+if { [gdb_compile "${src}" "${binfile}" executable {c++ debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+proc gdb_virtfunc_init {} {
+ global srcdir subdir binfile
+ global gdb_prompt
+
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ send_gdb "set language c++\n"
+ gdb_expect -re "$gdb_prompt $"
+ send_gdb "set width 0\n"
+ gdb_expect -re "$gdb_prompt $"
+}
+
+proc gdb_virtfunc_restart {} {
+ gdb_exit;
+ gdb_start;
+ gdb_virtfunc_init;
+ runto 'test_calls';
+}
+
+#
+# Test printing of the types of various classes.
+#
+
+proc test_ptype_of_classes {} {
+ global gdb_prompt
+ global ws
+ global nl
+
+ # This used to be a fail if it printed "struct" not "class". But
+ # since this struct doesn't use any special C++ features, it is
+ # considered right for GDB to print it as "struct".
+ send_gdb "ptype VA\n"
+ gdb_expect {
+ -re "type = (struct|class) VA \{(${ws}public:|)${ws}int va;${ws}VA & operator=\\(VA const ?&\\);${ws}VA\\((VA const|const VA) ?&\\);${ws}VA\\((void|)\\);${ws}\}.*$gdb_prompt $" {
+ pass "ptype VA"
+ }
+ -re "type = (struct|class) VA \{(${ws}public:|)${ws}int va;((${ws}VA & operator=\\(VA const ?&\\);)|(${ws}VA\\(VA const ?&\\);)|(${ws}VA\\((void|)\\);))*${ws}\}.*$gdb_prompt $" {
+ pass "ptype VA (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype VA"
+ }
+ timeout {
+ fail "ptype VA (timeout)"
+ }
+ }
+
+ send_gdb "ptype VB\n"
+ gdb_expect {
+ -re "type = class VB \{${ws}public:${ws}int vb;${ws}VB & operator=\\(VB const ?&\\);${ws}VB\\((VB const|const VB) ?&\\);${ws}VB\\((void|)\\);${ws}int fvb\\((void|)\\);${ws}virtual int vvb\\((void|)\\);${ws}\}.*$gdb_prompt $" {
+ pass "ptype VB"
+ }
+ -re "type = class VB \{${ws}public:${ws}int vb;${ws}int fvb \\((void|)\\);${ws}virtual int vvb \\((void|)\\);${ws}\}.*$gdb_prompt $" {
+ pass "ptype VB (aCC)"
+ }
+ -re "type = class VB \{${ws}public:${ws}int vb;((${ws}VB & operator=\\(VB const ?&\\);)|(${ws}VB\\(VB const ?&\\);)|(${ws}VB\\((void|)\\);)|(${ws}int fvb\\((void|)\\);)|(${ws}virtual int vvb\\((void|)\\);))*${ws}\}.*$gdb_prompt $" {
+ pass "ptype VB (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype VB"
+ }
+ timeout {
+ fail "ptype VB (timeout)"
+ }
+ }
+
+ send_gdb "ptype V\n"
+ gdb_expect {
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}V & operator=\\(V const ?&\\);${ws}V\\((V const|const V) ?&\\);${ws}V\\((void|)\\);${ws}int f\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype V"
+ }
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}int f \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype V (aCC)"
+ }
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;((${ws}V & operator=\\(V const ?&\\);)|(${ws}V\\(V const ?&\\);)|(${ws}V\\((void|)\\);)|(${ws}int f\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype V (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype V"
+ }
+ timeout {
+ fail "ptype V (timeout)"
+ }
+ }
+
+ # The format of a g++ virtual base pointer.
+ set vbptr "(_vb\[$.\]|__vb_)\[0-9\]?"
+
+ send_gdb "ptype A\n"
+ gdb_expect {
+ -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\(int, A const ?&\\);${ws}A\\(int\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype A"
+ }
+ -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\((A const|const A) ?&\\);${ws}A\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype A"
+ }
+ -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype A (aCC)"
+ }
+ -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:((${ws}A & operator=\\(A const ?&\\);)|(${ws}A\\(int, A const ?&\\);)|(${ws}A\\(int\\);)|(${ws}virtual int f\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype A (obsolescent gcc or gdb)"
+ }
+ -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}FOO;${ws}int a;${ws}public:${ws}virtual int f.void.;${ws}\}$nl$gdb_prompt $" {
+ # This happens because the type is defined only after it is
+ # too late.
+ fail "ptype A (known failure with gcc cygnus-2.4.5-930417)"
+ # Many of the rest of these tests have the same problem.
+ return 0
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype A"
+ }
+ timeout {
+ fail "ptype A (timeout)"
+ }
+ }
+
+ send_gdb "ptype B\n"
+ gdb_expect {
+ -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}B & operator=\\(B const ?&\\);${ws}B\\(int, B const ?&\\);${ws}B\\(int\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype B"
+ }
+ -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}B & operator=\\(B const ?&\\);${ws}B\\((B const|const B) ?&\\);${ws}B\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype B"
+ }
+ -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}virtual int f \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype B (aCC)"
+ }
+ -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:((${ws}B & operator=\\(B const ?&\\);)|(${ws}B\\(int, B const ?&\\);)|(${ws}B\\(int\\);)|(${ws}virtual int f\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype B (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype B"
+ }
+ timeout {
+ fail "ptype B (timeout)"
+ }
+ }
+
+ send_gdb "ptype C\n"
+ gdb_expect {
+ -re "type = class C : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int c;${ws}C & operator=\\(C const ?&\\);${ws}C\\(int, C const ?&\\);${ws}C\\(int\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype C"
+ }
+ -re "type = class C : public virtual V \{${ws}public:${ws}int c;${ws}C & operator=\\(C const ?&\\);${ws}C\\((C const|const C) ?&\\);${ws}C\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype C"
+ }
+ -re "type = class C : public virtual V \{${ws}public:${ws}int c;${ws}\}$nl$gdb_prompt $" {
+ pass "ptype C (aCC)"
+ }
+ -re "type = class C : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int c;((${ws}C & operator=\\(C const ?&\\);)|(${ws}C\\(int, C const ?&\\);)|(${ws}C\\(int\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype C (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype C"
+ }
+ timeout {
+ fail "ptype C (timeout)"
+ }
+ }
+
+ send_gdb "ptype AD\n"
+ gdb_expect {
+ -re "type = class AD \{${ws}public:${ws}AD & operator=\\(AD const ?&\\);${ws}AD\\((AD const|const AD) ?&\\);${ws}AD\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype AD"
+ }
+ -re "type = class AD \{${ws}public:${ws}virtual int vg \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype AD (aCC)"
+ }
+ -re "type = class AD \{${ws}public:((${ws}AD & operator=\\(AD const ?&\\);)|(${ws}AD\\(AD const ?&\\);)|(${ws}AD\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype AD (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype AD"
+ }
+ timeout {
+ fail "ptype AD (timeout)"
+ }
+ }
+
+ send_gdb "ptype D\n"
+ gdb_expect {
+ -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\(int, D const ?&\\);${ws}D\\(int\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype D"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\((D const|const D) ?&\\);${ws}D\\((void|)\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype D"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype D (aCC)"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;((${ws}D & operator=\\(D const ?&\\);)|(${ws}D\\(int, D const ?&\\);)|(${ws}D\\(int\\);)|(${ws}static void s\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vd\\((void|)\\);)|(${ws}int fd\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype D (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype D"
+ }
+ timeout {
+ fail "ptype D (timeout)"
+ }
+ }
+
+ send_gdb "ptype E\n"
+ gdb_expect {
+ -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}E & operator=\\(E const ?&\\);${ws}E\\(int, E const ?&\\);${ws}E\\(int\\);${ws}virtual int f\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype E"
+ }
+ -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}E & operator=\\(E const ?&\\);${ws}E\\((E const|const E) ?&\\);${ws}E\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype E"
+ }
+ -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}virtual int f \\((void|)\\);${ws}virtual int vg \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype E (aCC)"
+ }
+ -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;((${ws}E & operator=\\(E const ?&\\);)|(${ws}E\\(int, E const ?&\\);)|(${ws}E\\(int\\);)|(${ws}virtual int f\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype E (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype E"
+ }
+ timeout {
+ fail "ptype E (timeout)"
+ }
+ }
+
+ send_gdb "ptype dd\n"
+ gdb_expect {
+ -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\(int, D const ?&\\);${ws}D\\(int\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype dd"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\((D const|const D) ?&\\);${ws}D\\((void|)\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype dd"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype dd (aCC)"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;((${ws}D & operator=\\(D const ?&\\);)|(${ws}D\\(int, D const ?&\\);)|(${ws}D\\(int\\);)|(${ws}static void s\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vd\\((void|)\\);)|(${ws}int fd\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype dd (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype dd"
+ }
+ timeout {
+ fail "ptype dd (timeout)"
+ }
+ }
+
+ send_gdb "ptype ppd\n"
+ gdb_expect {
+ -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\(int, D const ?&\\);${ws}D\\(int\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype ppd"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\((D const|const D) ?&\\);${ws}D\\((void|)\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype ppd"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype ppd (aCC)"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;((${ws}D & operator=\\(D const ?&\\);)|(${ws}D\\(int, D const ?&\\);)|(${ws}D\\(int\\);)|(${ws}static void s\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vd\\((void|)\\);)|(${ws}int fd\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype ppd (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype ppd"
+ }
+ timeout {
+ fail "ptype ppd (timeout)"
+ }
+ }
+
+ send_gdb "ptype pAd\n"
+ gdb_expect {
+ -re "type = class AD \{${ws}public:${ws}AD & operator=\\(AD const ?&\\);${ws}AD\\((AD const|const AD) ?&\\);${ws}AD\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pAd"
+ }
+ -re "type = class AD \{${ws}public:${ws}virtual int vg \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pAd (aCC)"
+ }
+ -re "type = class AD \{${ws}public:((${ws}AD & operator=\\(AD const ?&\\);)|(${ws}AD\\(AD const ?&\\);)|(${ws}AD\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pAd (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype pAd"
+ }
+ timeout {
+ fail "ptype pAd (timeout)"
+ }
+ }
+
+ send_gdb "ptype a\n"
+ gdb_expect {
+ -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\(int, A const ?&\\);${ws}A\\(int\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype a"
+ }
+ -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\((A const|const A) ?&\\);${ws}A\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype a"
+ }
+ -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype a (aCC)"
+ }
+ -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:((${ws}A & operator=\\(A const ?&\\);)|(${ws}A\\(int, A const ?&\\);)|(${ws}A\\(int\\);)|(${ws}virtual int f\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype a (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype a"
+ }
+ timeout {
+ fail "ptype a (timeout)"
+ }
+ }
+
+ send_gdb "ptype b\n"
+ gdb_expect {
+ -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}B & operator=\\(B const ?&\\);${ws}B\\(int, B const ?&\\);${ws}B\\(int\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype b"
+ }
+ -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}B & operator=\\(B const ?&\\);${ws}B\\((B const|const B) ?&\\);${ws}B\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype b"
+ }
+ -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}virtual int f \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype b (aCC)"
+ }
+ -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:((${ws}B & operator=\\(B const ?&\\);)|(${ws}B\\(int, B const ?&\\);)|(${ws}B\\(int\\);)|(${ws}virtual int f\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype b (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype b"
+ }
+ timeout {
+ fail "ptype b (timeout)"
+ }
+ }
+
+ send_gdb "ptype c\n"
+ gdb_expect {
+ -re "type = class C : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int c;${ws}C & operator=\\(C const ?&\\);${ws}C\\(int, C const ?&\\);${ws}C\\(int\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype c"
+ }
+ -re "type = class C : public virtual V \{${ws}public:${ws}int c;${ws}C & operator=\\(C const ?&\\);${ws}C\\((C const|const C) ?&\\);${ws}C\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype c"
+ }
+ -re "type = class C : public virtual V \{${ws}public:${ws}int c;${ws}\}$nl$gdb_prompt $" {
+ pass "ptype c (aCC)"
+ }
+ -re "type = class C : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int c;((${ws}C & operator=\\(C const ?&\\);)|(${ws}C\\(int, C const ?&\\);)|(${ws}C\\(int\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype c (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype c"
+ }
+ timeout {
+ fail "ptype c (timeout)"
+ }
+ }
+
+ send_gdb "ptype d\n"
+ gdb_expect {
+ -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\(int, D const ?&\\);${ws}D\\(int\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype d"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\((D const|const D) ?&\\);${ws}D\\((void|)\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype d"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype d (aCC)"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;((${ws}D & operator=\\(D const ?&\\);)|(${ws}D\\(int, D const ?&\\);)|(${ws}D\\(int\\);)|(${ws}static void s\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vd\\((void|)\\);)|(${ws}int fd\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype d (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype d"
+ }
+ timeout {
+ fail "ptype d (timeout)"
+ }
+ }
+
+ send_gdb "ptype e\n"
+ gdb_expect {
+ -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}E & operator=\\(E const ?&\\);${ws}E\\(int, E const ?&\\);${ws}E\\(int\\);${ws}virtual int f\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype e"
+ }
+ -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}E & operator=\\(E const ?&\\);${ws}E\\((E const|const E) ?&\\);${ws}E\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype e"
+ }
+ -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}virtual int f \\((void|)\\);${ws}virtual int vg \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype e (aCC)"
+ }
+ -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;((${ws}E & operator=\\(E const ?&\\);)|(${ws}E\\(int, E const ?&\\);)|(${ws}E\\(int\\);)|(${ws}virtual int f\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype e (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype e"
+ }
+ timeout {
+ fail "ptype e (timeout)"
+ }
+ }
+
+ send_gdb "ptype v\n"
+ gdb_expect {
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}V & operator=\\(V const ?&\\);${ws}V\\((V const|const V) ?&\\);${ws}V\\((void|)\\);${ws}int f\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype v"
+ }
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}int f \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype v (aCC)"
+ }
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;((${ws}V & operator=\\(V const ?&\\);)|(${ws}V\\(V const ?&\\);)|(${ws}V\\((void|)\\);)|(${ws}int f\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype v (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype v"
+ }
+ timeout {
+ fail "ptype v (timeout)"
+ }
+ }
+
+ send_gdb "ptype vb\n"
+ gdb_expect {
+ -re "type = class VB \{${ws}public:${ws}int vb;${ws}VB & operator=\\(VB const ?&\\);${ws}VB\\((VB const|const VB) ?&\\);${ws}VB\\((void|)\\);${ws}int fvb\\((void|)\\);${ws}virtual int vvb\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype vb"
+ }
+ -re "type = class VB \{${ws}public:${ws}int vb;${ws}int fvb \\((void|)\\);${ws}virtual int vvb \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
+ pass "ptype vb (aCC)"
+ }
+ -re "type = class VB \{${ws}public:${ws}int vb;((${ws}VB & operator=\\(VB const ?&\\);)|(${ws}VB\\(VB const ?&\\);)|(${ws}VB\\((void|)\\);)|(${ws}int fvb\\((void|)\\);)|(${ws}virtual int vvb\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
+ pass "ptype vb (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype vb"
+ }
+ timeout {
+ fail "ptype vb (timeout)"
+ }
+ }
+
+ send_gdb "ptype pAa\n"
+ gdb_expect {
+ -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\(int, A const ?&\\);${ws}A\\(int\\);${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pAa"
+ }
+ -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\((A const|const A) ?&\\);${ws}A\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pAa"
+ }
+ -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pAa (aCC)"
+ }
+ -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:((${ws}A & operator=\\(A const ?&\\);)|(${ws}A\\(int, A const ?&\\);)|(${ws}A\\(int\\);)|(${ws}virtual int f\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pAa (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype pAa"
+ }
+ timeout {
+ fail "ptype pAa (timeout)"
+ }
+ }
+
+ send_gdb "ptype pAe\n"
+ gdb_expect {
+ -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\(int, A const ?&\\);${ws}A\\(int\\);${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pAe"
+ }
+ -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\((A const|const A) ?&\\);${ws}A\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pAe"
+ }
+ -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pAe (aCC)"
+ }
+ -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:((${ws}A & operator=\\(A const ?&\\);)|(${ws}A\\(int, A const ?&\\);)|(${ws}A\\(int\\);)|(${ws}virtual int f\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pAe (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype pAe"
+ }
+ timeout {
+ fail "ptype pAe (timeout)"
+ }
+ }
+
+ send_gdb "ptype pBe\n"
+ gdb_expect {
+ -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}B & operator=\\(B const ?&\\);${ws}B\\(int, B const ?&\\);${ws}B\\(int\\);${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pBe"
+ }
+ -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}B & operator=\\(B const ?&\\);${ws}B\\((B const|const B) ?&\\);${ws}B\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pBe"
+ }
+ -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}virtual int f \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pBe (aCC)"
+ }
+ -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:((${ws}B & operator=\\(B const ?&\\);)|(${ws}B\\(int, B const ?&\\);)|(${ws}B\\(int\\);)|(${ws}virtual int f\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pBe (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype pBe"
+ }
+ timeout {
+ fail "ptype pBe (timeout)"
+ }
+ }
+
+ send_gdb "ptype pDd\n"
+ gdb_expect {
+ -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\(int, D const ?&\\);${ws}D\\(int\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pDd"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\((D const|const D) ?&\\);${ws}D\\((void|)\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pDd"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pDd (aCC)"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;((${ws}D & operator=\\(D const ?&\\);)|(${ws}D\\(int, D const ?&\\);)|(${ws}D\\(int\\);)|(${ws}static void s\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vd\\((void|)\\);)|(${ws}int fd\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pDd (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype pDd"
+ }
+ timeout {
+ fail "ptype pDd (timeout)"
+ }
+ }
+
+ send_gdb "ptype pDe\n"
+ gdb_expect {
+ -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\(int, D const ?&\\);${ws}D\\(int\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pDe"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\((D const|const D) ?&\\);${ws}D\\((void|)\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pDe"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pDe (aCC)"
+ }
+ -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;((${ws}D & operator=\\(D const ?&\\);)|(${ws}D\\(int, D const ?&\\);)|(${ws}D\\(int\\);)|(${ws}static void s\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vd\\((void|)\\);)|(${ws}int fd\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pDe (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype pDe"
+ }
+ timeout {
+ fail "ptype pDe (timeout)"
+ }
+ }
+
+ send_gdb "ptype pVa\n"
+ gdb_expect {
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}V & operator=\\(V const ?&\\);${ws}V\\((V const|const V) ?&\\);${ws}V\\((void|)\\);${ws}int f\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVa"
+ }
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}int f \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVa (aCC)"
+ }
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;((${ws}V & operator=\\(V const ?&\\);)|(${ws}V\\(V const ?&\\);)|(${ws}V\\((void|)\\);)|(${ws}int f\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVa (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype pVa"
+ }
+ timeout {
+ fail "ptype pVa (timeout)"
+ }
+ }
+
+ send_gdb "ptype pVv\n"
+ gdb_expect {
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}V & operator=\\(V const ?&\\);${ws}V\\((V const|const V) ?&\\);${ws}V\\((void|)\\);${ws}int f\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVv"
+ }
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}int f \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVv (aCC)"
+ }
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;((${ws}V & operator=\\(V const ?&\\);)|(${ws}V\\(V const ?&\\);)|(${ws}V\\((void|)\\);)|(${ws}int f\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVv (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype pVv"
+ }
+ timeout {
+ fail "ptype pVv (timeout)"
+ }
+ }
+
+ send_gdb "ptype pVe\n"
+ gdb_expect {
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}V & operator=\\(V const ?&\\);${ws}V\\((V const|const V) ?&\\);${ws}V\\((void|)\\);${ws}int f\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVe"
+ }
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}int f \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVe (aCC)"
+ }
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;((${ws}V & operator=\\(V const ?&\\);)|(${ws}V\\(V const ?&\\);)|(${ws}V\\((void|)\\);)|(${ws}int f\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVe (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype pVe"
+ }
+ timeout {
+ fail "ptype pVe (timeout)"
+ }
+ }
+
+ send_gdb "ptype pVd\n"
+ gdb_expect {
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}V & operator=\\(V const ?&\\);${ws}V\\((V const|const V) ?&\\);${ws}V\\((void|)\\);${ws}int f\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVd"
+ }
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}int f \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVd (aCC)"
+ }
+ -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;((${ws}V & operator=\\(V const ?&\\);)|(${ws}V\\(V const ?&\\);)|(${ws}V\\((void|)\\);)|(${ws}int f\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVd (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype pVd"
+ }
+ timeout {
+ fail "ptype pVd (timeout)"
+ }
+ }
+
+ send_gdb "ptype pADe\n"
+ gdb_expect {
+ -re "type = class AD \{${ws}public:${ws}AD & operator=\\(AD const ?&\\);${ws}AD\\((AD const|const AD) ?&\\);${ws}AD\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pADe"
+ }
+ -re "type = class AD \{${ws}public:${ws}virtual int vg \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pADe (aCC)"
+ }
+ -re "type = class AD \{${ws}public:((${ws}AD & operator=\\(AD const ?&\\);)|(${ws}AD\\(AD const ?&\\);)|(${ws}AD\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pADe (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype pADe"
+ }
+ timeout {
+ fail "ptype pADe (timeout)"
+ }
+ }
+
+ send_gdb "ptype pEe\n"
+ gdb_expect {
+ -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}E & operator=\\(E const ?&\\);${ws}E\\(int, E const ?&\\);${ws}E\\(int\\);${ws}virtual int f\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pEe"
+ }
+ -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}E & operator=\\(E const ?&\\);${ws}E\\((E const|const E) ?&\\);${ws}E\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pEe"
+ }
+ -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}virtual int f \\((void|)\\);${ws}virtual int vg \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pEe (aCC)"
+ }
+ -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;((${ws}E & operator=\\(E const ?&\\);)|(${ws}E\\(int, E const ?&\\);)|(${ws}E\\(int\\);)|(${ws}virtual int f\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pEe (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype pEe"
+ }
+ timeout {
+ fail "ptype pEe (timeout)"
+ }
+ }
+
+ send_gdb "ptype pVB\n"
+ gdb_expect {
+ -re "type = class VB \{${ws}public:${ws}int vb;${ws}VB & operator=\\(VB const ?&\\);${ws}VB\\((VB const|const VB) ?&\\);${ws}VB\\((void|)\\);${ws}int fvb\\((void|)\\);${ws}virtual int vvb\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVB"
+ }
+ -re "type = class VB \{${ws}public:${ws}int vb;${ws}int fvb \\((void|)\\);${ws}virtual int vvb \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVB (aCC)"
+ }
+ -re "type = class VB \{${ws}public:${ws}int vb;((${ws}VB & operator=\\(VB const ?&\\);)|(${ws}VB\\(VB const ?&\\);)|(${ws}VB\\((void|)\\);)|(${ws}int fvb\\((void|)\\);)|(${ws}virtual int vvb\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
+ pass "ptype pVB (obsolescent gcc or gdb)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "ptype pVB"
+ }
+ timeout {
+ fail "ptype pVB (timeout)"
+ }
+ }
+}
+
+#
+# Test calling of virtual functions.
+#
+
+proc test_virtual_calls {} {
+ global gdb_prompt
+ global GDB
+ global nl
+ global gcc_compiled
+
+ if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ return 0
+ }
+
+ send_gdb "print pAe->f()\n"
+ gdb_expect {
+ -re ".* = 20$nl$gdb_prompt $" { pass "print pAe->f()" }
+ -re "Cannot invoke functions on this machine.*$gdb_prompt $" {
+ fail "print pAe->f() (cannot invoke functions, skipping virtual calls)"
+ return 0
+ }
+ -re ".*Cannot access memory at address 0x8.*$gdb_prompt $" {
+ fail "print pAe->f() \
+(known failure with gcc cygnus-2.4.5-930417, skipping virtual calls)"
+ return 0
+ }
+ -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
+ setup_xfail hppa*-*-* CLLbs16899
+ fail "print pAe->f()"
+ }
+ -re ".*$gdb_prompt $" { fail "print pAe->f()" }
+ timeout { fail "print pAe->f() (timeout)" }
+ eof { fail "print pAe->f() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
+ }
+
+ send_gdb "print pAa->f()\n"
+ gdb_expect {
+ -re ".* = 1$nl$gdb_prompt $" { pass "print pAa->f()" }
+ -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
+ setup_xfail hppa*-*-* CLLbs16899
+ fail "print pAa->f()"
+ }
+ -re ".*$gdb_prompt $" { fail "print pAa->f()" }
+ timeout { fail "print pAa->f() (timeout)" }
+ eof { fail "print pAa->f() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
+ }
+
+ send_gdb "print pDe->vg()\n"
+ gdb_expect {
+ -re ".* = 202$nl$gdb_prompt $" { pass "print pDe->vg()" }
+ -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
+ setup_xfail hppa*-*-* CLLbs16899
+ fail "print pDe->vg()"
+ }
+ -re ".*$gdb_prompt $" { fail "print pDe->vg()" }
+ timeout { fail "print pDe->vg() (timeout)" }
+ eof { fail "print pDe->vg() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
+ }
+
+ send_gdb "print pADe->vg()\n"
+ gdb_expect {
+ -re ".* = 202$nl$gdb_prompt $" { pass "print pADe->vg()" }
+ -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
+ setup_xfail hppa*-*-* CLLbs16899
+ fail "print pADe->vg()"
+ }
+ -re ".*$gdb_prompt $" { fail "print pADe->vg()" }
+ timeout { fail "print pADe->vg() (timeout)" }
+ eof { fail "print pADe->vg() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
+ }
+
+ send_gdb "print pDd->vg()\n"
+ gdb_expect {
+ -re ".* = 101$nl$gdb_prompt $" { pass "print pDd->vg()" }
+ -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
+ setup_xfail hppa*-*-* CLLbs16899
+ fail "print pDd->vg()"
+ }
+ -re ".*$gdb_prompt $" { fail "print pDd->vg()" }
+ timeout { fail "print pDd->vg() (timeout)" }
+ eof { fail "print pDd->vg() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
+ }
+
+ send_gdb "print pEe->vvb()\n"
+ gdb_expect {
+ -re ".* = 411$nl$gdb_prompt $" { pass "print pEe->vvb()" }
+ -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
+ setup_xfail hppa*-*-* CLLbs16899
+ fail "print pEe->vvb()"
+ }
+ -re ".*$gdb_prompt $" { fail "print pEe->vvb()" }
+ timeout { fail "print pEe->vvb() (timeout)" }
+ eof { fail "print pEe->vvb() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
+ }
+
+ send_gdb "print pVB->vvb()\n"
+ gdb_expect {
+ -re ".* = 407$nl$gdb_prompt $" { pass "print pVB->vvb()" }
+ -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
+ setup_xfail hppa*-*-* CLLbs16899
+ fail "print pVB->vvb()"
+ }
+ -re ".*$gdb_prompt $" { fail "print pVB->vvb()" }
+ timeout { fail "print pVB->vvb() (timeout)" }
+ eof { fail "print pVB->vvb() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
+ }
+
+ # fails on target=native, host=i686-pc-linux-gnu%rh-7.2,
+ # gdb=HEAD%2002-02-16, gcc=2.95.3, goption=-gdwarf-2.
+ # -- chastain 2002-02-20
+
+ if {$gcc_compiled} then { setup_xfail "*-*-*" }
+
+ send_gdb "print pBe->vvb()\n"
+ gdb_expect {
+ -re ".* = 411$nl$gdb_prompt $" { pass "print pBe->vvb()" }
+ -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
+ setup_xfail hppa*-*-* CLLbs16899
+ fail "print pBe->vvb()"
+ }
+ -re ".*$gdb_prompt $" { fail "print pBe->vvb()" }
+ timeout { fail "print pBe->vvb() (timeout)" }
+ eof { fail "print pBe->vvb() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
+ }
+
+ send_gdb "print pDe->vvb()\n"
+ gdb_expect {
+ -re ".* = 411$nl$gdb_prompt $" { pass "print pDe->vvb()" }
+ -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
+ setup_xfail hppa*-*-* CLLbs16899
+ fail "print pDe->vvb()"
+ }
+ -re ".*$gdb_prompt $" { fail "print pDe->vvb()" }
+ timeout { fail "print pDe->vvb() (timeout)" }
+ eof { fail "print pDe->vvb() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
+ }
+
+ send_gdb "print pEe->vd()\n"
+ gdb_expect {
+ -re ".* = 282$nl$gdb_prompt $" { pass "print pEe->vd()" }
+ -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
+ setup_xfail hppa*-*-* CLLbs16899
+ fail "print pEe->vd()"
+ }
+ -re ".*$gdb_prompt $" { fail "print pEe->vd()" }
+ timeout { fail "print pEe->vd() (timeout)" }
+ eof { fail "print pEe->vd() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
+ }
+
+ send_gdb "print pEe->fvb()\n"
+ gdb_expect {
+ -re ".* = 311$nl$gdb_prompt $" { pass "print pEe->fvb()" }
+ -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
+ setup_xfail hppa*-*-* CLLbs16899
+ fail "print pEe->fvb()"
+ }
+ -re ".*$gdb_prompt $" { fail "print pEe->fvb()" }
+ timeout { fail "print pEe->fvb() (timeout)" }
+ eof { fail "print pEe->fvb() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
+ }
+
+ # fails on target=native, host=i686-pc-linux-gnu%rh-7.2,
+ # gdb=HEAD%2002-02-16, gcc=2.95.3, goption=-gdwarf-2.
+ #
+ # fails on target=native, host=i686-pc-linux-gnu%rh-7.2,
+ # gdb=HEAD%2002-02-16, gcc=2.95.3, goption=-gstabs+.
+ #
+ # fails on target=native, host=i686-pc-linux-gnu%rh-7.2,
+ # gdb=HEAD%2002-02-16, gcc=3.0.3, goption=-gdwarf-2.
+ #
+ # fails on target=native, host=i686-pc-linux-gnu%rh-7.2,
+ # gdb=HEAD%2002-02-16, gcc=3.0.3, goption=-gstabs+.
+ #
+ # fails on target=native, host=i686-pc-linux-gnu%rh-7.2,
+ # gdb=HEAD%2002-02-16, gcc=3.0.4-20020215, goption=-gdwarf-2.
+ #
+ # fails on target=native, host=i686-pc-linux-gnu%rh-7.2,
+ # gdb=HEAD%2002-02-16, gcc=3.0.4-20020215, goption=-gstabs+.
+ #
+ # fails on target=native, host=i686-pc-linux-gnu%rh-7.2,
+ # gdb=HEAD%2002-02-16, gcc=gcc-3_0-branch%2002-02-16, goption=-gdwarf-2.
+ #
+ # fails on target=native, host=i686-pc-linux-gnu%rh-7.2,
+ # gdb=HEAD%2002-02-16, gcc=gcc-3_0-branch%2002-02-16, goption=-gstabs+.
+ #
+ # fails on target=native, host=i686-pc-linux-gnu%rh-7.2,
+ # gdb=HEAD%2002-02-16, gcc=HEAD%2002-02-16, goption=-gdwarf-2.
+ #
+ # fails on target=native, host=i686-pc-linux-gnu%rh-7.2,
+ # gdb=HEAD%2002-02-16, gcc=HEAD%2002-02-16, goption=-gstabs+.
+ #
+ # -- chastain 2002-02-20
+
+ if {$gcc_compiled} then { setup_xfail "*-*-*" }
+
+ send_gdb "print pEe->D::vg()\n"
+ setup_xfail "*-*-*"
+ gdb_expect {
+ -re ".* = 102$nl$gdb_prompt $" { pass "print pEe->D::vg()" }
+ -re ".*$gdb_prompt $" { fail "print pEe->D::vg()" }
+ timeout { fail "print pEe->D::vg() (timeout)" }
+ eof { fail "print pEe->D::vg() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
+ }
+}
+
+proc do_tests {} {
+ global prms_id
+ global bug_id
+
+ set prms_id 0
+ set bug_id 0
+
+ gdb_start;
+ gdb_virtfunc_init;
+
+ # Get the debug format for the compiled test case. If that
+ # format is DWARF 1 then just skip all the tests since none of
+ # them will pass.
+
+ if [ runto_main ] then {
+ get_debug_format
+ if [ setup_xfail_format "DWARF 1" ] then {
+ fail "C++ tests skipped due to limited C++ support in DWARF 1 debug format"
+ return
+ }
+ clear_xfail "*-*-*"
+ }
+
+ test_ptype_of_classes
+
+ if [ runto 'test_calls' ] then {
+ test_virtual_calls
+ }
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/ChangeLog b/gdb/testsuite/gdb.chill/ChangeLog
new file mode 100644
index 00000000000..51a24df26a8
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/ChangeLog
@@ -0,0 +1,331 @@
+2001-03-06 Kevin Buettner <kevinb@redhat.com>
+
+ * builtins.exp, callch.exp, chexp.exp, chillvars.exp,
+ enum.exp, gch1041.exp, gch1272.exp, gch1280.exp, gch922.exp,
+ gch981.exp, misc.exp, powerset.exp, pr-4975.exp, pr-5016.exp,
+ pr-5020.exp, pr-5022.exp, pr-5646.exp, pr-5984.exp,
+ pr-6292.exp, pr-6632.exp, pr-8134.exp, pr-8136.exp,
+ pr-8405.exp, pr-8742.exp, pr-8894.exp, pr-9095.exp,
+ pr-9946.exp, result.exp, string.exp, tests1.ch, tests1.exp,
+ tests2.ch, tests2.exp, tuples.exp, xstruct.exp: Update/correct
+ copyright notices.
+
+1999-06-25 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Jimmy Guo <guo@cup.hp.com>:
+ * xstruct-grt.ch, xstruct.ch, xstruct.exp: Rename to mollify
+ doschk.
+
+Thu May 21 02:45:18 1998 Felix Lee <flee@zog.cygnus.com>
+
+ * chexp.exp: fix tests that assume >16-bit ints.
+
+Wed Sep 10 15:01:55 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * *.exp: The end-all be-all of quoting fixes. Ha.
+
+Thu Aug 21 10:31:23 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * enum.exp: More quoting fixes.
+ * pr-9946.exp: Ditto.
+ * gch1280.exp: Ditto.
+ * gch1272.exp: Ditto.
+
+Tue Aug 12 21:48:08 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * tests2.exp: Fix quoting.
+ * tests1.exp: Ditto.
+ * pr-9946.exp: Ditto.
+ * enum.exp: Ditto.
+ * builtins.exp: Ditto.
+ * powerset.exp: Ditto.
+ * misc.exp: Ditto.
+ * gch981.exp: Ditto.
+ * gch922.exp: Ditto.
+ * gch1280.exp: Ditto.
+ * gch1272.exp: Ditto.
+ * gch1041.exp: Ditto.
+
+Sat Nov 23 14:00:59 1996 Fred Fish <fnf@cygnus.com>
+
+ * misc.exp: Change x86 linux setup_xfails to use new
+ i*86-pc-linux*-gnu quads.
+ * tuples.exp: Ditto.
+ * tests2.exp: Ditto.
+ * pr-5016.exp: Ditto.
+
+ * tuples.exp: Add i*86-pc-linux-gnu setup_fail to existing
+ xfails for 'set var vs1 := [ "bar", 42, m_ps[ a ] ]',
+ 'set var $i := m_s1["foo", 44, m_ps[a ]]', and
+ 'set var vs2 := [ 10+3, m_s1[ "foo" , 42, m_ps[ b ]]]'.
+
+Mon Nov 11 10:27:32 1996 Fred Fish <fnf@cygnus.com>
+
+ * callch.exp: Add mips*-sgi-irix* xfail for
+ "call king(a, otto[[10, 15], [20, 25]])".
+ * pr-8742.exp: Add mips*-sgi-irix* xfails for
+ "pass int powerset tuple"
+ "pass set powerset tuple"
+ "pass modeless int powerset tuple" and
+ "pass modeless set powerset tuple".
+ * tuples.exp: Add sparc-*-solaris* and sparc-*-sunos*
+ xfails for several "set var" commands that are failing.
+ Convert most of the set commands into gdb_test_exact
+ commands.
+
+Fri Oct 11 16:48:56 1996 Fred Fish <fnf@cygnus.com>
+
+ * expstruct.exp (objfile2): Set and use, like other chill tests.
+ * pr-4975.exp: Ditto.
+ * pr-5646.exp: Ditto.
+ * pr-8134.exp: Ditto.
+
+Thu Sep 5 01:54:42 1996 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+
+ * gch1280.exp: Enhance test case.
+
+Wed Sep 4 07:30:44 1996 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+
+ * gch1272.{ch,exp}, gch1280.{ch,exp}, pr-9946.{ch,exp}:
+ New test cases.
+
+Sun Aug 18 13:29:48 1996 Fred Fish <fnf@cygnus.com>
+
+ * tests2.exp: Remove mips-sgi-irix* setup_xfail for
+ "real write 4" and "real write 8".
+
+Mon Jun 10 14:04:05 1996 Fred Fish <fnf@cygnus.com>
+
+ * tests1.exp (test_modes): Remove *-*-* setup_sfail for
+ "print unnumbered set range mode" and
+ "print numbered set range mode".
+
+Wed Apr 17 01:23:06 1996 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+
+ * tests1.{ch,exp}: Tets case modified and enhanced.
+
+Tue Apr 9 01:18:04 1996 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+
+ * gch981.{ch,exp}, gch1041.{ch,exp}: New test cases.
+
+Wed Mar 6 00:29:35 1996 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+
+ * powerset.exp: Add test.
+
+Tue Mar 5 23:41:39 1996 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+
+ * gch922.{ch,exp}, powerset.{ch,exp}: New test cases.
+
+ * builtins.exp, chillvars.exp, misc.exp, tests1.exp: Updated
+ due to new format of nonprintable characters (control sequence
+ instead of C'xx').
+
+Tue Mar 5 00:09:17 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * string.ch, string.exp: Add tests (from Cygnus PR chill/9078).
+
+ * pr-9095.ch, pr-9095.exp: New test case.
+
+Fri Feb 9 08:22:16 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (clean): Add missing '{'.
+
+Tue Feb 6 21:52:26 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * pr-8894.exp, pr-8894.ch, pr-8894-grt.ch: New test case.
+
+Mon Jan 29 00:05:01 1996 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+
+ * builtins.ch, builtins.exp: Enhance test case.
+
+ * extstruct.ch, extstruct-grt.ch, extstruct.exp: New test case.
+
+Tue Jan 23 16:57:13 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * enum.ch, enum.exp: New test case (covers PRs 8869 and 8870).
+
+Thu Jan 11 17:34:01 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (PROGS): Removed.
+ (clean mostlyclean): Remove *.exe rather than ${PROGS}.
+
+ * pr-8742.ch, pr-8742.exp: New test case.
+
+Tue Jan 9 04:47:27 1996 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+
+ * misc.ch, misc.exp: Enhance test case.
+
+Sat Dec 30 15:31:59 1995 Fred Fish <fnf@cygnus.com>
+
+ * tests2.exp: Setup_xfail "i*86-*-linux" and
+ "mips-sgi-irix*" for "real write 4" and "real write 8".
+ Conditionalize both tests for system specific value
+ of "infinity" string.
+
+Fri Dec 29 10:46:09 1995 Fred Fish <fnf@cygnus.com>
+
+ * builtins.exp (test_size): Alpha seems to have long builtins.
+ * tests1.exp: Setup xfail "*-*-*" for "ptype r2".
+ * tests2.exp: Add check to skip chill tests.
+
+Mon Dec 11 16:53:40 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * tuples.ch, tuples.exp: Exhance test cases (from PR 8643).
+
+Mon Dec 11 06:57:07 1995 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+
+ * builtins.exp, pr-5016.{ch,exp}, result.{ch,exp},
+ tests1.{ch,exp}: Enhance test cases.
+
+Thu Dec 7 05:16:34 1995 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+
+ * builtins.ch, builtins.exp, Makefile.in: New test case.
+
+Tue Dec 5 01:51:45 1995 Wilfried Moser (Alcatel) <moser@rtl.cygnus.com>
+
+ * tests2.exp: Add compiling of the test case.
+
+Fri Dec 1 00:08:37 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * pr-8405.ch, pr-8405.exp, Makefile.in: New test case.
+
+ * tests1.exp, tests2.exp (test_print_reject): Remove; causes
+ conflicts with later tests using test_print_reject in ../lib/gdb.exp.
+ (passcount): Remove.
+ * tests2.exp (test_print_accept): Removed.
+ (test_write): Re-write to use gdb_test rather than test_print_accept.
+ * tests1.exp (test_print_accept_exact): Removed.
+ (tests_locations): Rewrite to use gdb_test and not above proc.
+
+ * tests1.ch, tests1.exp, tests2.ch, tests2.exp, Makefile.in:
+ New (extensive) test cases.
+ * chexp.exp: Fix relations to return TRUE or FALSE.
+
+Wed Nov 29 19:28:13 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in: Add .exp.check rule.
+ * callch.ch: Add missing "%." to format strings.
+ * callch.exp: Fix argument to gdb_load.
+ * chexp.exp: Add specific error messages to test_print_reject calls.
+ * misc.exp: Add a test for PR 8496.
+ * pr-6632.exp, pr-8136.exp: Link executables from two .o files.
+
+Sat Nov 25 20:49:27 1995 Fred Fish <fnf@phydeaux.cygnus.com>
+
+ * pr-5016.exp: xfail "whatis i" for alpha-osf-dec-osf2*, same as linux.
+
+Sun Oct 29 17:58:01 1995 Fred Fish <fnf@cygnus.com>
+
+ * pr-5016.exp: xfail "whatis i" for sparc-sun-sunos4*, same as linux.
+
+Wed Oct 4 18:20:53 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * pr-8136.{ch,exp}, pr-8134.exp, func1.ch, Makefile.in: New test cases.
+
+Wed Sep 27 11:51:50 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * tuples.ch. tuples.exp: Add new test for setting a variant record
+ using a tuple, and access the fields.
+
+Thu Aug 3 10:45:37 1995 Fred Fish <fnf@cygnus.com>
+
+ * Update all FSF addresses except those in COPYING* files.
+
+Thu Jul 27 20:36:30 1995 Fred Fish (fnf@cygnus.com)
+
+ * pr-5016.exp: xfail "i*86-*-linux*" for "whatis int-range"
+ test. Thinks it is "_cint" rather than "m_index".
+ * misc.exp: xfail "i*86-*-linux*" for "info line" test.
+ Line number is off by one.
+
+Wed Jun 14 13:07:45 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * chillvars.exp, string.exp: New tests for LOWER/UPPER/LENGTH.
+
+Wed Jun 7 17:52:38 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * chillvars.ch (xptr): Declare new variable.
+ * chillvars.exp (test_ptr): New function to test EXPR->MODENAME.
+
+Tue Mar 28 17:13:13 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * pr-6632.ch, pr-6632-grt.ch, pr-6632.exp, Makefile.in: New test case.
+
+Tue Mar 21 12:10:06 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * tuples.exp (do_tests): Make names of "print v_ps" test unique.
+
+Wed Mar 8 13:26:36 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * *.exp: Skip all tests silently if skip_chill_tests returns true.
+
+ * misc.exp: Remove reference to non-existent variable passcount.
+
+Tue Mar 7 19:30:05 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * string.ch, string.exp, Makefile.in: New test case.
+
+Mon Mar 6 14:11:01 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * tuples.ch (setnmode); New module.
+ * tuples.exp: Add some extra tests.
+
+Sat Mar 4 15:16:17 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * callch.ch, callch.exp, Makefile.in: New test case.
+
+Thu Mar 2 06:17:41 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * misc.exp: If executable does not exist, issue warning and skip
+ remaining tests, like other chill tests.
+
+Wed Mar 1 20:28:42 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * misc.ch, misc.exp, Makefile.in: New test case.
+
+Mon Feb 20 16:19:58 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * chillvars.ch: Add missing INIT's.
+ * chillvars.exp: Allow builtin types as either case. E.g. (BOOL|bool).
+ * pr-5016.exp: Likewise.
+
+Sun Feb 12 11:26:08 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * pr-6292.ch, pr-6292.exp, Makefile.in: New test case.
+
+Wed Feb 1 13:09:48 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * tuples.ch, tuples.exp, Makefile.in: New test case.
+
+Mon Nov 28 18:39:08 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * pr-5984.ch, pr-5984.exp, Makefile.in: New test case.
+
+Fri Sep 16 16:55:03 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * pr-5646.ch, pr-5646-grt.ch, pr-5646.exp, Makefile.in: New testcase.
+
+Tue Sep 6 13:21:27 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * pr-5016.ch, pr-5016.exp, Makefile.in: New testcase.
+ * Makefile.in (.exe.check): New rule, to run just one test.
+
+Tue Jun 14 16:20:18 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * result.ch, result.exp, Makefile.in: New test case.
+ * pr-4975.ch, pr-4975-grt.ch, pr-4975.exp, Makefile.in: Ditto.
+
+Thu Jun 9 15:20:43 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * pr-5022.ch, pr-5022.exp: New testcase.
+ * chillvars.exp: Remove spurious newline.
+
+ * Makefile.in: Bunch of fixes so it actually works in this
+ directory. (E.g. add extra ../ where needed.)
+ Also, add .exe to executables, so we can use suffix rules.
+ * chexp.exp (test_print_reject): Update syntax error message.
+ * chillvars.ch (module PR_5020): Moved from here ...
+ * pr-5022.ch: ... to this new file.
+ * chillvars.exp, pr-5020.exp (binfile): Add .exe extension.
+ * chillvars.exp, pr-5020.exp: Don't check all_flag.
+ * pr-5020.exp: Add more tests; fix "print y pretty" output.
diff --git a/gdb/testsuite/gdb.chill/Makefile.in b/gdb/testsuite/gdb.chill/Makefile.in
new file mode 100644
index 00000000000..a965b578d74
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/Makefile.in
@@ -0,0 +1,26 @@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+all:
+ @echo "Nothing to be done for all..."
+
+#### host, target, and site specific Makefile frags come in here.
+
+.SUFFIXES: .ch .o .exe .exp .check
+
+# Do 'make chillvars.check' to run just the chillvars.{ch,exp} test.
+
+.exp.check:
+ rootme=`pwd`/; export rootme; \
+ cd .. ; \
+ $(MAKE) just-check RUNTESTFLAGS="${RUNTESTFLAGS} $*.exp" \
+ EXPECT=${EXPECT}
+
+clean mostlyclean:
+ -rm -f *.o ${OBJS} *.exe *~ core
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
+
+Makefile: $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.chill/builtins.ch b/gdb/testsuite/gdb.chill/builtins.ch
new file mode 100644
index 00000000000..ef12c839b90
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/builtins.ch
@@ -0,0 +1,83 @@
+xx: MODULE
+
+DCL v_bool BOOL INIT := FALSE;
+DCL v_char CHAR INIT := 'X';
+DCL v_byte BYTE INIT := -30;
+DCL v_ubyte UBYTE INIT := 30;
+DCL v_int INT INIT := -333;
+DCL v_uint UINT INIT := 333;
+DCL v_long LONG INIT := -4444;
+DCL v_ulong ULONG INIT := 4444;
+DCL v_ptr PTR;
+
+SYNMODE m_set = SET (e1, e2, e3, e4, e5, e6);
+DCL v_set m_set INIT := e3;
+
+SYNMODE m_set_range = m_set(e2:e5);
+DCL v_set_range m_set_range INIT := e3;
+
+SYNMODE m_numbered_set = SET (n1 = 25, n2 = 22, n3 = 35, n4 = 33,
+ n5 = 45, n6 = 43);
+DCL v_numbered_set m_numbered_set INIT := n3;
+
+SYNMODE m_char_range = CHAR('A':'Z');
+DCL v_char_range m_char_range INIT := 'G';
+
+SYNMODE m_bool_range = BOOL(FALSE:FALSE);
+DCL v_bool_range m_bool_range;
+
+SYNMODE m_long_range = LONG(255:3211);
+DCL v_long_range m_long_range INIT := 1000;
+
+SYNMODE m_range = RANGE(12:28);
+DCL v_range m_range INIT := 23;
+
+SYNMODE m_chars = CHARS(20);
+SYNMODE m_chars_v = CHARS(20) VARYING;
+DCL v_chars CHARS(20);
+DCL v_chars_v CHARS(20) VARYING INIT := "foo bar";
+
+SYNMODE m_bits = BOOLS(10);
+DCL v_bits BOOLS(10);
+
+SYNMODE m_arr = ARRAY(1:10) BYTE;
+DCL v_arr ARRAY(1:10) BYTE;
+
+SYNMODE m_char_arr = ARRAY (CHAR) BYTE;
+DCL v_char_arr ARRAY(CHAR) BYTE;
+
+SYNMODE m_bool_arr = ARRAY (BOOL) BYTE;
+DCL v_bool_arr ARRAY (BOOL) BYTE;
+
+SYNMODE m_int_arr = ARRAY (INT) BYTE;
+DCL v_int_arr ARRAY (INT) BYTE;
+
+SYNMODE m_set_arr = ARRAY (m_set) BYTE;
+DCL v_set_arr ARRAY (m_set) BYTE;
+
+SYNMODE m_numbered_set_arr = ARRAY (m_numbered_set) BYTE;
+DCL v_numbered_set_arr ARRAY (m_numbered_set) BYTE;
+
+SYNMODE m_char_range_arr = ARRAY (m_char_range) BYTE;
+DCL v_char_range_arr ARRAY (m_char_range) BYTE;
+
+SYNMODE m_set_range_arr = ARRAY (m_set_range) BYTE;
+DCL v_set_range_arr ARRAY (m_set_range) BYTE;
+
+SYNMODE m_bool_range_arr = ARRAY (m_bool_range) BYTE;
+DCL v_bool_range_arr ARRAY (m_bool_range) BYTE;
+
+SYNMODE m_long_range_arr = ARRAY (m_long_range) BYTE;
+DCL v_long_range_arr ARRAY (m_long_range) BYTE;
+
+SYNMODE m_range_arr = ARRAY (m_range) BYTE;
+DCL v_range_arr ARRAY (m_range) BYTE;
+
+SYNMODE m_struct = STRUCT (i LONG,
+ c CHAR,
+ s CHARS(30));
+DCL v_struct m_struct;
+
+v_bool := TRUE;
+
+END xx;
diff --git a/gdb/testsuite/gdb.chill/builtins.exp b/gdb/testsuite/gdb.chill/builtins.exp
new file mode 100644
index 00000000000..87fe3af1f94
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/builtins.exp
@@ -0,0 +1,441 @@
+# Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file tests various Chill values, expressions, and types.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "builtins"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -w -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to chill. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_chill {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+ send_gdb "set language chill\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language chill (timeout)" ; return 0 }
+ }
+
+ send_gdb "show language\n"
+ gdb_expect {
+ -re ".* source language is \"chill\".*$gdb_prompt $" {
+ pass "set language to \"chill\""
+ send_gdb "break xx_\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {
+ send_gdb "run\n"
+ gdb_expect -re ".*$gdb_prompt $" {}
+ return 1
+ }
+ timeout {
+ fail "can't set breakpoint (timeout)"
+ return 0
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "setting language to \"chill\""
+ return 0
+ }
+ timeout {
+ fail "can't show language (timeout)"
+ return 0
+ }
+ }
+}
+
+# Testing printing of a specific value. Increment passcount for
+# success or issue fail message for failure. In both cases, return
+# a 1 to indicate that more tests can proceed. However a timeout
+# is a serious error, generates a special fail message, and causes
+# a 0 to be returned to indicate that more tests are likely to fail
+# as well.
+#
+# Args are:
+#
+# First one is string to send_gdb to gdb
+# Second one is string to match gdb result to
+# Third one is an optional message to be printed
+
+proc test_print_accept { args } {
+ global gdb_prompt
+ global passcount
+ global verbose
+
+ if [llength $args]==3 then {
+ set message [lindex $args 2]
+ } else {
+ set message [lindex $args 0]
+ }
+ set sendthis [lindex $args 0]
+ set expectthis [lindex $args 1]
+ set result [gdb_test $sendthis ".* = ${expectthis}" $message]
+ if $result==0 {incr passcount}
+ return $result
+}
+
+proc test_lower {} {
+ global passcount
+
+ verbose "testing builtin LOWER"
+ set passcount 0
+
+ # discrete mode names
+ test_print_accept "print lower(bool)" "FALSE"
+ test_print_accept "print lower(char)" {'\^[(]0[)]'}
+ test_print_accept "print lower(byte)" "-128"
+ test_print_accept "print lower(ubyte)" "0"
+ if [istarget "alpha-*-*"] then {
+ test_print_accept "print lower(int)" "-2147483648"
+ } else {
+ test_print_accept "print lower(int)" "-32768"
+ }
+ test_print_accept "print lower(uint)" "0"
+ setup_xfail "alpha-*-*"
+ test_print_accept "print lower(long)" "-2147483648"
+ test_print_accept "print lower(ulong)" "0"
+ test_print_accept "print lower(m_set)" "e1"
+ test_print_accept "print lower(m_set_range)" "e2"
+ test_print_accept "print lower(m_numbered_set)" "n2"
+ test_print_accept "print lower(m_char_range)" "'A'"
+ test_print_accept "print lower(m_bool_range)" "FALSE"
+ test_print_accept "print lower(m_long_range)" "255"
+ test_print_accept "print lower(m_range)" "12"
+
+ # discrete locations
+ test_print_accept "print lower(v_bool)" "FALSE"
+ test_print_accept "print lower(v_char)" {'\^[(]0[)]'}
+ test_print_accept "print lower(v_byte)" "-128"
+ test_print_accept "print lower(v_ubyte)" "0"
+ if [istarget "alpha-*-*"] then {
+ test_print_accept "print lower(v_int)" "-2147483648"
+ } else {
+ test_print_accept "print lower(v_int)" "-32768"
+ }
+ test_print_accept "print lower(v_uint)" "0"
+ setup_xfail "alpha-*-*"
+ test_print_accept "print lower(v_long)" "-2147483648"
+ test_print_accept "print lower(v_ulong)" "0"
+ test_print_accept "print lower(v_set)" "e1"
+ test_print_accept "print lower(v_set_range)" "e2"
+ test_print_accept "print lower(v_numbered_set)" "n2"
+ test_print_accept "print lower(v_char_range)" "'A'"
+ test_print_accept "print lower(v_bool_range)" "FALSE"
+ test_print_accept "print lower(v_long_range)" "255"
+ test_print_accept "print lower(v_range)" "12"
+
+ # string mode names
+ test_print_accept "print lower(m_chars)" "0"
+ test_print_accept "print lower(m_chars_v)" "0"
+ test_print_accept "print lower(m_bits)" "0"
+
+ # string locations
+ test_print_accept "print lower(v_chars)" "0"
+ test_print_accept "print lower(v_chars_v)" "0"
+ test_print_accept "print lower(v_bits)" "0"
+
+ # string expressions
+ test_print_accept "print lower(\"abcd\")" "0"
+ test_print_accept "print lower(B'010101')" "0"
+
+ # array mode name
+ test_print_accept "print lower(m_arr)" "1";
+ test_print_accept "print lower(m_char_arr)" {'\^[(]0[)]'}
+ test_print_accept "print lower(m_bool_arr)" "FALSE"
+ if [istarget "alpha-*-*"] then {
+ test_print_accept "print lower(m_int_arr)" "-2147483648"
+ } else {
+ test_print_accept "print lower(m_int_arr)" "-32768"
+ }
+ test_print_accept "print lower(m_set_arr)" "e1"
+ test_print_accept "print lower(m_set_range_arr)" "e2"
+ test_print_accept "print lower(m_numbered_set_arr)" "n2"
+ test_print_accept "print lower(m_char_range_arr)" "'A'"
+ test_print_accept "print lower(m_bool_range_arr)" "FALSE"
+ test_print_accept "print lower(m_long_range_arr)" "255"
+ test_print_accept "print lower(m_range_arr)" "12"
+
+ # array locations
+ test_print_accept "print lower(v_arr)" "1";
+ test_print_accept "print lower(v_char_arr)" {'\^[(]0[)]'}
+ test_print_accept "print lower(v_bool_arr)" "FALSE"
+ if [istarget "alpha-*-*"] then {
+ test_print_accept "print lower(v_int_arr)" "-2147483648"
+ } else {
+ test_print_accept "print lower(v_int_arr)" "-32768"
+ }
+ test_print_accept "print lower(v_set_arr)" "e1"
+ test_print_accept "print lower(v_set_range_arr)" "e2"
+ test_print_accept "print lower(v_numbered_set_arr)" "n2"
+ test_print_accept "print lower(v_char_range_arr)" "'A'"
+ test_print_accept "print lower(v_bool_range_arr)" "FALSE"
+ test_print_accept "print lower(v_long_range_arr)" "255"
+ test_print_accept "print lower(v_range_arr)" "12"
+}
+
+proc test_upper {} {
+ global passcount
+
+ verbose "testing builtin UPPER"
+ set passcount 0
+
+ # discrete mode names
+ test_print_accept "print upper(bool)" "TRUE"
+ test_print_accept "print upper(char)" {'\^[(]255[)]'}
+ test_print_accept "print upper(byte)" "127"
+ test_print_accept "print upper(ubyte)" "255"
+ if [istarget "alpha-*-*"] then {
+ test_print_accept "print upper(int)" "2147483647"
+ test_print_accept "print upper(uint)" "4294967295"
+ setup_xfail "alpha-*-*"
+ test_print_accept "print upper(long)" "4294967295"
+ test_print_accept "print upper(ulong)" "18446744073709551615"
+ } else {
+ test_print_accept "print upper(int)" "32767"
+ test_print_accept "print upper(uint)" "65535"
+ test_print_accept "print upper(long)" "2147483647"
+ test_print_accept "print upper(ulong)" "4294967295"
+ }
+ test_print_accept "print upper(m_set)" "e6"
+ test_print_accept "print upper(m_set_range)" "e5"
+ test_print_accept "print upper(m_numbered_set)" "n5"
+ test_print_accept "print upper(m_char_range)" "'Z'"
+ test_print_accept "print upper(m_bool_range)" "FALSE"
+ test_print_accept "print upper(m_long_range)" "3211"
+ test_print_accept "print upper(m_range)" "28"
+
+ # discrete locations
+ test_print_accept "print upper(v_bool)" "TRUE"
+ test_print_accept "print upper(v_char)" {'\^[(]255[)]'}
+ test_print_accept "print upper(v_byte)" "127"
+ test_print_accept "print upper(v_ubyte)" "255"
+ if [istarget "alpha-*-*"] then {
+ test_print_accept "print upper(v_int)" "2147483647"
+ test_print_accept "print upper(v_uint)" "4294967295"
+ setup_xfail "alpha-*-*"
+ test_print_accept "print upper(v_long)" "4294967295"
+ test_print_accept "print upper(v_ulong)" "18446744073709551615"
+ } else {
+ test_print_accept "print upper(v_int)" "32767"
+ test_print_accept "print upper(v_uint)" "65535"
+ test_print_accept "print upper(v_long)" "2147483647"
+ test_print_accept "print upper(v_ulong)" "4294967295"
+ }
+ test_print_accept "print upper(v_set)" "e6"
+ test_print_accept "print upper(v_set_range)" "e5"
+ test_print_accept "print upper(v_numbered_set)" "n5"
+ test_print_accept "print upper(v_char_range)" "'Z'"
+ test_print_accept "print upper(v_bool_range)" "FALSE"
+ test_print_accept "print upper(v_long_range)" "3211"
+ test_print_accept "print upper(v_range)" "28"
+
+ # string mode names
+ test_print_accept "print upper(m_chars)" "19"
+ test_print_accept "print upper(m_chars_v)" "19"
+ test_print_accept "print upper(m_bits)" "9"
+
+ # string locations
+ test_print_accept "print upper(v_chars)" "19"
+ test_print_accept "print upper(v_chars_v)" "19"
+ test_print_accept "print upper(v_bits)" "9"
+
+ # string expressions
+ test_print_accept "print upper(\"abcd\")" "3"
+ test_print_accept "print upper(B'010101')" "5"
+
+ # array mode name
+ test_print_accept "print upper(m_arr)" "10";
+ test_print_accept "print upper(m_char_arr)" {'\^[(]255[)]'}
+ test_print_accept "print upper(m_bool_arr)" "TRUE"
+ if [istarget "alpha-*-*"] then {
+ test_print_accept "print upper(m_int_arr)" "2147483647"
+ } else {
+ test_print_accept "print upper(m_int_arr)" "32767"
+ }
+ test_print_accept "print upper(m_set_arr)" "e6"
+ test_print_accept "print upper(m_set_range_arr)" "e5"
+ test_print_accept "print upper(m_numbered_set_arr)" "n5"
+ test_print_accept "print upper(m_char_range_arr)" "'Z'"
+ test_print_accept "print upper(m_bool_range_arr)" "FALSE"
+ test_print_accept "print upper(m_long_range_arr)" "3211"
+ test_print_accept "print upper(m_range_arr)" "28"
+
+ # array locations
+ test_print_accept "print upper(v_arr)" "10";
+ test_print_accept "print upper(v_char_arr)" {'\^[(]255[)]'}
+ test_print_accept "print upper(v_bool_arr)" "TRUE"
+ if [istarget "alpha-*-*"] then {
+ test_print_accept "print upper(v_int_arr)" "2147483647"
+ } else {
+ test_print_accept "print upper(v_int_arr)" "32767"
+ }
+ test_print_accept "print upper(v_set_arr)" "e6"
+ test_print_accept "print upper(v_set_range_arr)" "e5"
+ test_print_accept "print upper(v_numbered_set_arr)" "n5"
+ test_print_accept "print upper(v_char_range_arr)" "'Z'"
+ test_print_accept "print upper(v_bool_range_arr)" "FALSE"
+ test_print_accept "print upper(v_long_range_arr)" "3211"
+ test_print_accept "print upper(v_range_arr)" "28"
+}
+
+proc test_length {} {
+ global passcount
+
+ verbose "testing builtin LENGTH"
+ set passcount 0
+
+ # string locations
+ test_print_accept "print length(v_chars)" "20"
+ test_print_accept "print length(v_chars_v)" "7";
+ test_print_accept "print length(v_bits)" "10";
+
+ # string expressions
+ test_print_accept "print length(\"the quick brown fox ...\")" "23"
+ test_print_accept "print length(B'010101010101')" "12"
+ test_print_accept "print length(\"foo \" // \"bar\")" "7"
+
+ # check some failures
+ setup_xfail "*-*-*"
+ test_print_accept "print length(m_chars)" "typename in invalid context"
+ setup_xfail "*-*-*"
+ test_print_accept "print length(v_byte)" "bad argument to LENGTH builtin"
+ setup_xfail "*-*-*"
+ test_print_accept "print length(b'000000' // b'111111')" "12"
+}
+
+proc test_size {} {
+ global passcount
+
+ verbose "testing builtin SIZE"
+ set passcount 0
+
+ # modes
+ test_print_accept "print size(bool)" "1"
+ test_print_accept "print size(char)" "1"
+ test_print_accept "print size(byte)" "1"
+ if [istarget "alpha-*-*"] then {
+ test_print_accept "print size(int)" "4"
+ test_print_accept "print size(ulong)" "8"
+ test_print_accept "print size(ptr)" "8"
+ test_print_accept "print size(m_chars_v)" "24"
+ test_print_accept "print size(m_struct)" "40"
+ } else {
+ test_print_accept "print size(int)" "2"
+ test_print_accept "print size(ulong)" "4"
+ test_print_accept "print size(ptr)" "4"
+ test_print_accept "print size(m_chars_v)" "22"
+ test_print_accept "print size(m_struct)" "36"
+ }
+ test_print_accept "print size(m_set)" "1"
+ test_print_accept "print size(m_numbered_set)" "1"
+ test_print_accept "print size(m_char_range)" "1"
+ test_print_accept "print size(m_range_arr)" "17"
+ test_print_accept "print size(m_chars)" "20"
+ test_print_accept "print size(m_bits)" "2"
+
+ # locations
+ test_print_accept "print size(v_bool)" "1"
+ test_print_accept "print size(v_char)" "1"
+ test_print_accept "print size(v_byte)" "1"
+ if [istarget "alpha-*-*"] then {
+ test_print_accept "print size(v_int)" "4"
+ test_print_accept "print size(v_ulong)" "8"
+ test_print_accept "print size(v_ptr)" "8"
+ test_print_accept "print size(v_chars_v)" "24"
+ test_print_accept "print size(v_struct)" "40"
+ } else {
+ test_print_accept "print size(v_int)" "2"
+ test_print_accept "print size(v_ulong)" "4"
+ test_print_accept "print size(v_ptr)" "4"
+ test_print_accept "print size(v_chars_v)" "22"
+ test_print_accept "print size(v_struct)" "36"
+ }
+ test_print_accept "print size(v_set)" "1"
+ test_print_accept "print size(v_numbered_set)" "1"
+ test_print_accept "print size(v_char_range)" "1"
+ test_print_accept "print size(v_range_arr)" "17"
+ test_print_accept "print size(v_chars)" "20"
+ test_print_accept "print size(v_bits)" "2"
+}
+
+proc test_num {} {
+ global passcount
+
+ verbose "testing builtin NUM"
+ set passcount 0
+
+ # constants
+ test_print_accept "print num(false)" "0"
+ test_print_accept "print num(true)" "1"
+ test_print_accept "print num(10)" "10"
+ test_print_accept "print num(33-34)" "-1"
+ test_print_accept "print num('X')" "88"
+ test_print_accept "print num(e5)" "4"
+
+ # locations
+ test_print_accept "print num(v_bool)" "0"
+ test_print_accept "print num(v_char)" "88"
+ test_print_accept "print num(v_byte)" "-30"
+ test_print_accept "print num(v_ubyte)" "30"
+ test_print_accept "print num(v_int)" "-333"
+ test_print_accept "print num(v_uint)" "333"
+ test_print_accept "print num(v_long)" "-4444"
+ test_print_accept "print num(v_ulong)" "4444"
+ test_print_accept "print num(v_set)" "2"
+ test_print_accept "print num(v_set_range)" "2"
+ test_print_accept "print num(v_numbered_set)" "35"
+ test_print_accept "print num(v_char_range)" "71"
+ test_print_accept "print num(v_long_range)" "1000"
+ test_print_accept "print num(v_range)" "23"
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+if [set_lang_chill] then {
+ # test builtins as described in chapter 6.20.3 Z.200
+ test_num
+ test_size
+ test_lower
+ test_upper
+ test_length
+} else {
+ warning "$test_name tests suppressed."
+}
diff --git a/gdb/testsuite/gdb.chill/callch.ch b/gdb/testsuite/gdb.chill/callch.ch
new file mode 100644
index 00000000000..6001d92443b
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/callch.ch
@@ -0,0 +1,50 @@
+hack : module
+
+dcl i int;
+newmode otto = array (bool, bool) byte;
+newmode str1 = struct (f1 int, f2 bool);
+newmode str2 = struct (f1 otto);
+
+dcl a otto := [[1,1],[1,1]];
+dcl b str1 := [10, false];
+dcl c str2;
+
+fred : proc (a int in, b int loc);
+ writetext(stdout, "a is '%C'; b is '%C'.%/", a, b);
+end fred;
+
+klaus : proc ();
+ writetext(stdout, "here's klaus calling.%/");
+end klaus;
+
+king : proc (p otto loc, x otto in);
+ dcl i, j bool;
+ p := [[h'ff,h'ff],[h'ff,h'ff]];
+ do for i:= lower(bool) to upper(bool);
+ do for j:= lower(bool) to upper(bool);
+ writetext(stdout, "x(%C, %C) = %C%..%/", i, j, x(i, j));
+ writetext(stdout, "p(%C, %C) = %C%..%/", i, j, p(i, j));
+ od;
+ od;
+end king;
+
+ralph : proc (x str1 in);
+ writetext(stdout, "x.f1 = %C, x.f2 = %C%..%/", x.f1, x.f2);
+end ralph;
+
+whitney : proc (x str2 in);
+ dcl i, j bool;
+
+ do for i:= lower(bool) to upper(bool);
+ do for j:= lower(bool) to upper(bool);
+ writetext(stdout, "x.f1(%C, %C) = %C%..%/", i, j, x.f1(i, j));
+ od;
+ od;
+
+end whitney;
+
+c := [a];
+i:=12;
+writetext(stdout, "done.%/");
+
+end hack;
diff --git a/gdb/testsuite/gdb.chill/callch.exp b/gdb/testsuite/gdb.chill/callch.exp
new file mode 100644
index 00000000000..78cf0b7e088
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/callch.exp
@@ -0,0 +1,69 @@
+# Copyright 1995, 1996 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file tests that gdb can call functions in a Chill inferior.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "callch"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ send_gdb "set language chill\n" ;
+
+ gdb_test "break callch.ch:48" ""
+ send_gdb "run\n"; gdb_expect -re "Breakpoint .*callch.ch:48.*$gdb_prompt $"
+ gdb_test {set fred(10, i)} {a is '10'; b is '12'.}
+ gdb_test_exact "call klaus()" {here's klaus calling.}
+ gdb_test_exact "call fred()" {too few arguments in function call}
+ # Too many arguments are allowed
+ gdb_test_exact "call klaus(10, 20, 30)" {here's klaus calling.}
+ gdb_test "print a" { = \[\(FALSE:TRUE\): \[\(FALSE:TRUE\): 1\]\]}\
+ "print a before king"
+ # Current gdb prints 255 for the results that are expected to be -1.
+ setup_xfail "mips*-sgi-irix*"
+ gdb_test {call king(a, otto[[10, 15], [20, 25]])} "x\\(FALSE, FALSE\\) = 10.*p\\(FALSE, FALSE\\) = -1.*x\\(FALSE, TRUE\\) = 15.*p\\(FALSE, TRUE\\) = -1.*x\\(TRUE, FALSE\\) = 20.*p\\(TRUE, FALSE\\) = -1.*x\\(TRUE, TRUE\\) = 25.*p\\(TRUE, TRUE\\) = -1.*"
+ gdb_test "print a" { = \[\(FALSE:TRUE\): \[\(FALSE:TRUE\): -1\]\]}\
+ "print a after king"
+ gdb_test_exact "call ralph(b)" {x.f1 = 10, x.f2 = FALSE.}
+ gdb_test "call whitney(c)" "x.f1\\(FALSE, FALSE\\) = 1.*x.f1\\(FALSE, TRUE\\) = 1.*x.f1\\(TRUE, FALSE\\) = 1.*x.f1\\(TRUE, TRUE\\) = 1.*"
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/chexp.exp b/gdb/testsuite/gdb.chill/chexp.exp
new file mode 100644
index 00000000000..820ef8334b8
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/chexp.exp
@@ -0,0 +1,450 @@
+# Copyright 1992, 1994, 1995, 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# Set the current language to chill. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_chill {} {
+ global gdb_prompt
+
+ send_gdb "set language chill\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language chill (timeout)" ; return 0 }
+ }
+
+ send_gdb "show language\n"
+ gdb_expect {
+ -re ".* source language is \"chill\".*$gdb_prompt $" {
+ pass "set language to \"chill\""
+ return 1
+ }
+ -re ".*$gdb_prompt $" {
+ fail "setting language to \"chill\""
+ return 0
+ }
+ timeout {
+ fail "can't show language (timeout)"
+ return 0
+ }
+ }
+}
+
+proc test_integer_literals_accepted {} {
+ global gdb_prompt
+
+ # Test various decimal values.
+
+ gdb_test "p 123" " = 123"
+ gdb_test "p -123" " = -123"
+ gdb_test "p D'123" " = 123"
+ gdb_test "p d'123" " = 123"
+ gdb_test "p -D'123" " = -123"
+ gdb_test "p -d'123" " = -123"
+ gdb_test "p 12_345" " = 12345"
+ gdb_test "p __1_2_3__" " = 123"
+ gdb_test "p/d 123" " = D'123"
+
+ # Test various binary values.
+
+ gdb_test "p B'111" " = 7"
+ gdb_test "p b'111" " = 7"
+ gdb_test "p -B'111" " = -7"
+ gdb_test "p B'0111" " = 7"
+ gdb_test "p b'0111" " = 7"
+ gdb_test "p -b'0111" " = -7"
+ gdb_test "p B'_0_1_1_1_" " = 7"
+ gdb_test "p b'_0_1_1_1_" " = 7"
+ gdb_test "p -b'_0_1_1_1_" " = -7"
+ gdb_test "p/t B'111" " = B'111"
+
+ # Test various octal values.
+
+ gdb_test "p O'123" " = 83"
+ gdb_test "p o'123" " = 83"
+ gdb_test "p -o'0123" " = -83"
+ gdb_test "p O'0123" " = 83"
+ gdb_test "p o'0123" " = 83"
+ gdb_test "p -o'123" " = -83"
+ gdb_test "p O'_1_2_3_" " = 83"
+ gdb_test "p o'_1_2_3_" " = 83"
+ gdb_test "p -o'_1_2_3_" " = -83"
+ gdb_test "p/o O'123" " = O'123"
+
+ # Test various hexadecimal values.
+
+ gdb_test "p H'123" " = 291"
+ gdb_test "p h'123" " = 291"
+ gdb_test "p -h'123" " = -291"
+ gdb_test "p H'0123" " = 291"
+ gdb_test "p h'0123" " = 291"
+ gdb_test "p -h'0123" " = -291"
+ gdb_test "p H'_1_2_3_" " = 291"
+ gdb_test "p h'_1_2_3_" " = 291"
+ gdb_test "p -h'_1_2_3_" " = -291"
+ gdb_test "p H'ABC" " = 2748"
+ gdb_test "p H'abc" " = 2748"
+ gdb_test "p H'AbC" " = 2748"
+ gdb_test "p H'_A_b_C_" " = 2748"
+ gdb_test "p H'_D_e_F_" " = 3567"
+ gdb_test "p H'_d_E_f_" " = 3567"
+ gdb_test "p/x H'123" " = H'123"
+}
+
+proc test_character_literals_accepted {} {
+ global gdb_prompt
+
+ # Test various decimal values.
+
+ gdb_test "p 'a'" " = 'a'"
+ gdb_test "p/x 'a'" " = H'61"
+ gdb_test "p/d 'a'" " = D'97"
+ gdb_test "p/t 'a'" " = B'1100001"
+ # gdb_test "p '^(97)'" " = 'a'" (not in GNU Chill)
+ gdb_test "p C'61'" " = 'a'"
+ gdb_test "p c'61'" " = 'a'"
+ gdb_test "p/x C'FF'" " = H'ff"
+ # gdb_test "p/x '^(H'FF)'" " = H'ff" (not in GNU Chill)
+ # gdb_test "p/x '^(D'255)'" " = H'ff" (not in GNU Chill)
+}
+
+proc test_integer_literals_rejected {} {
+ global gdb_prompt
+
+ # These are valid integer literals in Z.200, but not GNU-Chill.
+
+ test_print_reject "p _"
+ test_print_reject "p __"
+
+ test_print_reject "p D'"
+ test_print_reject "p D'_"
+ test_print_reject "p D'__"
+
+ test_print_reject "p B'"
+ test_print_reject "p B'_"
+ test_print_reject "p B'__"
+
+ test_print_reject "p O'"
+ test_print_reject "p O'_"
+ test_print_reject "p O'__"
+
+ test_print_reject "p H'"
+ test_print_reject "p H'_"
+ test_print_reject "p H'__"
+
+ # Test various decimal values.
+
+ test_print_reject "p D'DEADBEEF"
+ test_print_reject "p D'123DEADBEEF"
+
+ # Test various binary values.
+
+ test_print_reject "p B'2" "Too-large digit in bitstring or integer."
+ test_print_reject "p B'12" "Too-large digit in bitstring or integer."
+
+ # Test various octal values.
+
+ test_print_reject "p O'9" "Too-large digit in bitstring or integer."
+ test_print_reject "p O'79" "Too-large digit in bitstring or integer."
+
+ # Test various hexadecimal values.
+
+ test_print_reject "p H'G" "Invalid character in bitstring or integer."
+ test_print_reject "p H'AG" "Invalid character in bitstring or integer."
+}
+
+proc test_boolean_literals_accepted {} {
+ global gdb_prompt
+
+ # Test the only possible values for a boolean, TRUE and FALSE.
+
+ gdb_test "p TRUE" " = TRUE"
+ gdb_test "p FALSE" " = FALSE"
+}
+
+proc test_float_literals_accepted {} {
+ global gdb_prompt
+
+ # Test various floating point formats
+
+ gdb_test "p .44 < .45" " = TRUE"
+ gdb_test "p .44 > .45" " = FALSE"
+ gdb_test "p 0.44 < 0.45" " = TRUE"
+ gdb_test "p 0.44 > 0.45" " = FALSE"
+ gdb_test "p 44. < 45." " = TRUE"
+ gdb_test "p 44. > 45." " = FALSE"
+ gdb_test "p 44.0 < 45.0" " = TRUE"
+ gdb_test "p 44.0 > 45.0" " = FALSE"
+ gdb_test "p 10D20 < 10D21" " = TRUE"
+ gdb_test "p 10D20 > 10D21" " = FALSE"
+ gdb_test "p 10d20 < 10d21" " = TRUE"
+ gdb_test "p 10d20 > 10d21" " = FALSE"
+ gdb_test "p 10E20 < 10E21" " = TRUE"
+ gdb_test "p 10E20 > 10E21" " = FALSE"
+ gdb_test "p 10e20 < 10e21" " = TRUE"
+ gdb_test "p 10e20 > 10e21" " = FALSE"
+ gdb_test "p 10.D20 < 10.D21" " = TRUE"
+ gdb_test "p 10.D20 > 10.D21" " = FALSE"
+ gdb_test "p 10.d20 < 10.d21" " = TRUE"
+ gdb_test "p 10.d20 > 10.d21" " = FALSE"
+ gdb_test "p 10.E20 < 10.E21" " = TRUE"
+ gdb_test "p 10.E20 > 10.E21" " = FALSE"
+ gdb_test "p 10.e20 < 10.e21" " = TRUE"
+ gdb_test "p 10.e20 > 10.e21" " = FALSE"
+ gdb_test "p 10.0D20 < 10.0D21" " = TRUE"
+ gdb_test "p 10.0D20 > 10.0D21" " = FALSE"
+ gdb_test "p 10.0d20 < 10.0d21" " = TRUE"
+ gdb_test "p 10.0d20 > 10.0d21" " = FALSE"
+ gdb_test "p 10.0E20 < 10.0E21" " = TRUE"
+ gdb_test "p 10.0E20 > 10.0E21" " = FALSE"
+ gdb_test "p 10.0e20 < 10.0e21" " = TRUE"
+ gdb_test "p 10.0e20 > 10.0e21" " = FALSE"
+ gdb_test "p 10.0D+20 < 10.0D+21" " = TRUE"
+ gdb_test "p 10.0D+20 > 10.0D+21" " = FALSE"
+ gdb_test "p 10.0d+20 < 10.0d+21" " = TRUE"
+ gdb_test "p 10.0d+20 > 10.0d+21" " = FALSE"
+ gdb_test "p 10.0E+20 < 10.0E+21" " = TRUE"
+ gdb_test "p 10.0E+20 > 10.0E+21" " = FALSE"
+ gdb_test "p 10.0e+20 < 10.0e+21" " = TRUE"
+ gdb_test "p 10.0e+20 > 10.0e+21" " = FALSE"
+ gdb_test "p 10.0D-11 < 10.0D-10" " = TRUE"
+ gdb_test "p 10.0D-11 > 10.0D-10" " = FALSE"
+ gdb_test "p 10.0d-11 < 10.0d-10" " = TRUE"
+ gdb_test "p 10.0d-11 > 10.0d-10" " = FALSE"
+ gdb_test "p 10.0E-11 < 10.0E-10" " = TRUE"
+ gdb_test "p 10.0E-11 > 10.0E-10" " = FALSE"
+ gdb_test "p 10.0e-11 < 10.0e-10" " = TRUE"
+ gdb_test "p 10.0e-11 > 10.0e-10" " = FALSE"
+ # looks funny, but apparently legal
+ gdb_test "p _.1e+10 < _.1e+11" " = TRUE"
+ gdb_test "p _.1e+10 > _.1e+11" " = FALSE"
+ gdb_test "p __.1e-12 < __.1e-11" " = TRUE"
+ gdb_test "p __.1e-12 > __.1e-11" " = FALSE"
+}
+
+proc test_convenience_variables {} {
+ global gdb_prompt
+
+ gdb_test "set \$foo := 101" " := 101\[\r\]*" \
+ "Set a new convenience variable"
+
+ gdb_test "print \$foo" " = 101" \
+ "Print contents of new convenience variable"
+
+ gdb_test "set \$foo := 301" " := 301\[\r\]*" \
+ "Set convenience variable to a new value"
+
+ gdb_test "print \$foo" " = 301" \
+ "Print new contents of convenience variable"
+
+ gdb_test "set \$_ := 11" " := 11\[\r\]*" \
+ "Set convenience variable \$_"
+
+ gdb_test "print \$_" " = 11" \
+ "Print contents of convenience variable \$_"
+
+ gdb_test "print \$foo + 10" " = 311" \
+ "Use convenience variable in arithmetic expression"
+
+ gdb_test "print (\$foo := 32) + 4" " = 36" \
+ "Use convenience variable assignment in arithmetic expression"
+
+ gdb_test "print \$bar" " = void" \
+ "Print contents of uninitialized convenience variable"
+}
+
+proc test_value_history {} {
+ global gdb_prompt
+
+ gdb_test "print 101" "\\\$1 = 101" \
+ "Set value-history\[1\] using \$1"
+
+ gdb_test "print 102" "\\\$2 = 102" \
+ "Set value-history\[2\] using \$2"
+
+ gdb_test "print 103" "\\\$3 = 103" \
+ "Set value-history\[3\] using \$3"
+
+ gdb_test "print \$\$" "\\\$4 = 102" \
+ "Print value-history\[MAX-1\] using inplicit index \$\$"
+
+ gdb_test "print \$\$" "\\\$5 = 103" \
+ "Print value-history\[MAX-1\] again using implicit index \$\$"
+
+ gdb_test "print \$" "\\\$6 = 103" \
+ "Print value-history\[MAX\] using implicit index \$"
+
+ gdb_test "print \$\$2" "\\\$7 = 102" \
+ "Print value-history\[MAX-2\] using explicit index \$\$2"
+
+ gdb_test "print \$0" "\\\$8 = 102" \
+ "Print value-history\[MAX\] using explicit index \$0"
+
+ gdb_test "print 108" "\\\$9 = 108" ""
+
+ gdb_test "print \$\$0" "\\\$10 = 108" \
+ "Print value-history\[MAX\] using explicit index \$\$0"
+
+ gdb_test "print \$1" "\\\$11 = 101" \
+ "Print value-history\[1\] using explicit index \$1"
+
+ gdb_test "print \$2" "\\\$12 = 102" \
+ "Print value-history\[2\] using explicit index \$2"
+
+ gdb_test "print \$3" "\\\$13 = 103" \
+ "Print value-history\[3\] using explicit index \$3"
+
+ gdb_test "print \$-3" "\\\$14 = 100" \
+ "Print (value-history\[MAX\] - 3) using implicit index \$"
+
+ gdb_test "print \$1 + 3" "\\\$15 = 104" \
+ "Use value-history element in arithmetic expression"
+}
+
+proc test_arithmetic_expressions {} {
+ global gdb_prompt
+
+ # Test unary minus with various operands
+
+# gdb_test "p -(TRUE)" " = -1" "unary minus applied to bool"
+# gdb_test "p -('a')" " = xxx" "unary minus applied to char"
+ gdb_test "p -(1)" " = -1" "unary minus applied to int"
+ gdb_test "p -(1.0)" " = -1" "unary minus applied to real"
+
+ # Test addition with various operands
+
+ gdb_test "p TRUE + 1" " = 2" "bool plus int"
+ gdb_test "p 'a' + 1" " = 98" "char plus int"
+ gdb_test "p 1 + 1" " = 2" "int plus int"
+ gdb_test "p 1.0 + 1" " = 2" "real plus int"
+ gdb_test "p 1.0 + 2.0" " = 3" "real plus real"
+
+ # Test subtraction with various operands
+
+ gdb_test "p TRUE - 1" " = 0" "bool minus int"
+ gdb_test "p 'b' - 1" " = 97" "char minus int"
+ gdb_test "p 3 - 1" " = 2" "int minus int"
+ gdb_test "p 3.0 - 1" " = 2" "real minus int"
+ gdb_test "p 5.0 - 2.0" " = 3" "real minus real"
+
+ # Test multiplication with various operands
+
+ gdb_test "p TRUE * 1" " = 1" "bool times int"
+ gdb_test "p 'a' * 2" " = 194" "char times int"
+ gdb_test "p 2 * 3" " = 6" "int times int"
+ gdb_test "p 2.0 * 3" " = 6" "real times int"
+ gdb_test "p 2.0 * 3.0" " = 6" "real times real"
+
+ # Test division with various operands
+
+ gdb_test "p TRUE / 1" " = 1" "bool divided by int"
+ gdb_test "p 'a' / 2" " = 48" "char divided by int"
+ gdb_test "p 6 / 3" " = 2" "int divided by int"
+ gdb_test "p 6.0 / 3" " = 2" "real divided by int"
+ gdb_test "p 6.0 / 3.0" " = 2" "real divided by real"
+
+ # Test modulo with various operands
+
+ gdb_test "p TRUE MOD 1" " = 0" "bool modulo int"
+ gdb_test "p 'a' MOD 2" " = 1" "char modulo int"
+ gdb_test "p -5 MOD 3" " = 1" "negative int modulo int"
+ gdb_test "p 5 MOD 1" " = 0" "int modulo int"
+ gdb_test "p 5 MOD 2" " = 1" "int modulo int"
+ gdb_test "p 5 MOD 3" " = 2" "int modulo int"
+ gdb_test "p 5 MOD 4" " = 1" "int modulo int"
+ gdb_test "p 5 MOD 5" " = 0" "int modulo int"
+ gdb_test "p 0 MOD 1" " = 0" "int modulo int"
+ gdb_test "p 0 MOD 2" " = 0" "int modulo int"
+ gdb_test "p 0 MOD 3" " = 0" "int modulo int"
+ gdb_test "p 0 MOD 4" " = 0" "int modulo int"
+ gdb_test "p -5 MOD 1" " = 0" "int modulo int"
+ gdb_test "p -5 MOD 2" " = 1" "int modulo int"
+ gdb_test "p -5 MOD 3" " = 1" "int modulo int"
+ gdb_test "p -5 MOD 4" " = 3" "int modulo int"
+ gdb_test "p -5 MOD 5" " = 0" "int modulo int"
+ gdb_test "p -5 MOD 5" " = 0" "int modulo int"
+ test_print_reject "p 6.0 MOD 3" \
+ "Integer-only operation on floating point number.*"
+ test_print_reject "p 6.0 MOD 3.0" \
+ "Integer-only operation on floating point number.*"
+ test_print_reject "p -5 MOD -1" \
+ "Second operand of MOD must be greater than zero.*"
+ test_print_reject "p -5 MOD 0" \
+ "Second operand of MOD must be greater than zero.*"
+
+ # Test remainder with various operands
+
+ gdb_test "p TRUE REM 1" " = 0" "bool remainder int"
+ gdb_test "p 'a' REM 2" " = 1" "char remainder int"
+ gdb_test "p 5 REM 5" " = 0" "int remainder int"
+ gdb_test "p 5 REM 4" " = 1" "int remainder int"
+ gdb_test "p 5 REM 3" " = 2" "int remainder int"
+ gdb_test "p 5 REM 2" " = 1" "int remainder int"
+ gdb_test "p 5 REM 1" " = 0" "int remainder int"
+ gdb_test "p 5 REM -1" " = 0" "int remainder int"
+ gdb_test "p 5 REM -2" " = 1" "int remainder int"
+ gdb_test "p 5 REM -3" " = 2" "int remainder int"
+ gdb_test "p 5 REM -4" " = 1" "int remainder int"
+ gdb_test "p 5 REM -5" " = 0" "int remainder int"
+ gdb_test "p -5 REM 5" " = 0" "int remainder int"
+ gdb_test "p -5 REM 4" " = -1" "int remainder int"
+ gdb_test "p -5 REM 3" " = -2" "int remainder int"
+ gdb_test "p -5 REM 2" " = -1" "int remainder int"
+ gdb_test "p -5 REM 1" " = 0" "int remainder int"
+ gdb_test "p -5 REM -1" " = 0" "int remainder int"
+ gdb_test "p -5 REM -2" " = -1" "int remainder int"
+ gdb_test "p -5 REM -3" " = -2" "int remainder int"
+ gdb_test "p -5 REM -4" " = -1" "int remainder int"
+ gdb_test "p -5 REM -5" " = 0" "int remainder int"
+ gdb_test "p 6 REM 3" " = 0" "int remainder int"
+ test_print_reject "p 6.0 REM 3" \
+ "Integer-only operation on floating point number.*"
+ test_print_reject "p 6.0 REM 3.0" \
+ "Integer-only operation on floating point number.*"
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ""
+
+if [set_lang_chill] then {
+ test_value_history
+ test_convenience_variables
+ test_integer_literals_accepted
+ test_integer_literals_rejected
+ test_boolean_literals_accepted
+ test_character_literals_accepted
+ test_float_literals_accepted
+ test_arithmetic_expressions
+} else {
+ warning "$test_name tests suppressed." 0
+}
diff --git a/gdb/testsuite/gdb.chill/chillvars.ch b/gdb/testsuite/gdb.chill/chillvars.ch
new file mode 100644
index 00000000000..21dfcba5486
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/chillvars.ch
@@ -0,0 +1,204 @@
+testvars: MODULE
+
+DCL bool_true BOOL INIT := TRUE;
+DCL bool_false BOOL INIT := FALSE;
+DCL booltable1 ARRAY (0:3) BOOL INIT := [ TRUE, FALSE, FALSE, TRUE ];
+DCL booltable2 ARRAY (4:7) BOOL INIT := [ TRUE, FALSE, FALSE, TRUE ];
+
+DCL control_char CHAR INIT := C'07';
+DCL printable_char CHAR INIT := 'a';
+DCL chartable1 ARRAY (0:2) CHAR INIT := [ C'00', C'01', C'02' ];
+DCL chartable2 ARRAY (3:5) CHAR INIT := [ C'00', C'01', C'02' ];
+
+DCL string1 CHARS (4) INIT := 'abcd';
+DCL string2 CHARS (5) INIT := 'ef' // C'00' // 'gh';
+DCL string3 CHARS (6) INIT := 'ef' // 'gh' // 'ij';
+DCL string4 CHARS (7) INIT := (6) 'z' // C'00';
+
+DCL byte_low BYTE INIT := -128;
+DCL byte_high BYTE INIT := 127;
+DCL bytetable1 ARRAY (0:4) BYTE INIT := [ -2, -1, 0, 1, 2 ];
+DCL bytetable2 ARRAY (5:9) BYTE INIT := [ -2, -1, 0, 1, 2 ];
+DCL bytetable3 ARRAY (1:2,'c':'d',FALSE:TRUE) BYTE
+ INIT := [ [ [ 0, 1 ], [ 2, 3 ] ], [ [ 4, 5 ], [ 6, 7 ] ] ];
+DCL bytetable4 ARRAY (1:2) ARRAY ('c':'d') ARRAY (FALSE:TRUE) BYTE
+ INIT := [ [ [ 0, 1 ], [ 2, 3 ] ], [ [ 4, 5 ], [ 6, 7 ] ] ];
+
+DCL ubyte_low UBYTE INIT := 0;
+DCL ubyte_high UBYTE INIT := 255;
+DCL ubytetable1 ARRAY (0:4) UBYTE INIT := [ 0, 1, 2, 3, 4 ];
+DCL ubytetable2 ARRAY (5:9) UBYTE INIT := [ 0, 1, 2, 3, 4 ];
+
+DCL int_low INT INIT := -32_768;
+DCL int_high INT INIT := 32_767;
+DCL inttable1 ARRAY (0:4) INT INIT := [ -2, -1, 0, 1, 2 ];
+DCL inttable2 ARRAY (5:9) INT INIT := [ -2, -1, 0, 1, 2 ];
+
+DCL uint_low UINT INIT := 0;
+DCL uint_high UINT INIT := 65_535;
+DCL uinttable1 ARRAY (0:4) UINT INIT := [ 0, 1, 2, 3, 4 ];
+DCL uinttable2 ARRAY (5:9) UINT INIT := [ 0, 1, 2, 3, 4 ];
+
+DCL long_low LONG INIT := -2_147_483_648;
+DCL long_high LONG INIT := 2_147_483_647;
+DCL longtable1 ARRAY (0:4) LONG INIT := [ -2, -1, 0, 1, 2 ];
+DCL longtable2 ARRAY (5:9) LONG INIT := [ -2, -1, 0, 1, 2 ];
+
+DCL ulong_low ULONG INIT := 0;
+DCL ulong_high ULONG INIT := 4_294_967_295;
+DCL ulongtable1 ARRAY (0:4) ULONG INIT := [ 0, 1, 2, 3, 4 ];
+DCL ulongtable2 ARRAY (5:9) ULONG INIT := [ 0, 1, 2, 3, 4 ];
+
+DCL real1 FLOAT INIT := 3.14159265358;
+DCL real2 FLOAT INIT := -3.14159265358;
+DCL realtable1 ARRAY (0:4) FLOAT INIT := [ -2.0, -1.0, 0.0, 1.0, 2.0 ];
+DCL realtable2 ARRAY (5:9) FLOAT INIT := [ -2.0, -1.0, 0.0, 1.0, 2.0 ];
+
+DCL long_real1 DOUBLE INIT := 3.14e300;
+DCL long_real2 DOUBLE INIT := -3.14e-300;
+DCL longrealtable1 ARRAY (0:4) DOUBLE INIT := [ -2.0, -1.0, 0.0, 1.0, 2.0 ];
+DCL longrealtable2 ARRAY (5:9) DOUBLE INIT := [ -2.0, -1.0, 0.0, 1.0, 2.0 ];
+
+/* DCL powerset1 POWERSET INT(0:7);*/
+/* DCL chars1 CHAR (16) INIT := (16)'b'; */
+/* DCL bits1 BIT(20) := B'11111111000010101011'; */
+
+NEWMODE simple_struct = STRUCT (abool BOOL, aint INT, astring CHARS (8));
+DCL struct1 simple_struct := [ TRUE, 123, "a string" ];
+
+NEWMODE nested_struct = STRUCT (abool BOOL, nstruct simple_struct, aint INT);
+DCL struct2 nested_struct := [ TRUE, [ FALSE, 456, "deadbeef" ], 789 ];
+
+/* This table is used as a source for every ascii character. */
+
+DCL asciitable ARRAY (0:255) CHAR INIT := [
+ C'00', C'01', C'02', C'03', C'04', C'05', C'06', C'07',
+ C'08', C'09', C'0a', C'0b', C'0c', C'0d', C'0e', C'0f',
+ C'10', C'11', C'12', C'13', C'14', C'15', C'16', C'17',
+ C'18', C'19', C'1a', C'1b', C'1c', C'1d', C'1e', C'1f',
+ C'20', C'21', C'22', C'23', C'24', C'25', C'26', C'27',
+ C'28', C'29', C'2a', C'2b', C'2c', C'2d', C'2e', C'2f',
+ C'30', C'31', C'32', C'33', C'34', C'35', C'36', C'37',
+ C'38', C'39', C'3a', C'3b', C'3c', C'3d', C'3e', C'3f',
+ C'40', C'41', C'42', C'43', C'44', C'45', C'46', C'47',
+ C'48', C'49', C'4a', C'4b', C'4c', C'4d', C'4e', C'4f',
+ C'50', C'51', C'52', C'53', C'54', C'55', C'56', C'57',
+ C'58', C'59', C'5a', C'5b', C'5c', C'5d', C'5e', C'5f',
+ C'60', C'61', C'62', C'63', C'64', C'65', C'66', C'67',
+ C'68', C'69', C'6a', C'6b', C'6c', C'6d', C'6e', C'6f',
+ C'70', C'71', C'72', C'73', C'74', C'75', C'76', C'77',
+ C'78', C'79', C'7a', C'7b', C'7c', C'7d', C'7e', C'7f',
+ C'80', C'81', C'82', C'83', C'84', C'85', C'86', C'87',
+ C'88', C'89', C'8a', C'8b', C'8c', C'8d', C'8e', C'8f',
+ C'90', C'91', C'92', C'93', C'94', C'95', C'96', C'97',
+ C'98', C'99', C'9a', C'9b', C'9c', C'9d', C'9e', C'9f',
+ C'a0', C'a1', C'a2', C'a3', C'a4', C'a5', C'a6', C'a7',
+ C'a8', C'a9', C'aa', C'ab', C'ac', C'ad', C'ae', C'af',
+ C'b0', C'b1', C'b2', C'b3', C'b4', C'b5', C'b6', C'b7',
+ C'b8', C'b9', C'ba', C'bb', C'bc', C'bd', C'be', C'bf',
+ C'c0', C'c1', C'c2', C'c3', C'c4', C'c5', C'c6', C'c7',
+ C'c8', C'c9', C'ca', C'cb', C'cc', C'cd', C'ce', C'cf',
+ C'd0', C'd1', C'd2', C'd3', C'd4', C'd5', C'd6', C'd7',
+ C'd8', C'd9', C'da', C'db', C'dc', C'dd', C'de', C'df',
+ C'e0', C'e1', C'e2', C'e3', C'e4', C'e5', C'e6', C'e7',
+ C'e8', C'e9', C'ea', C'eb', C'ec', C'ed', C'ee', C'ef',
+ C'f0', C'f1', C'f2', C'f3', C'f4', C'f5', C'f6', C'f7',
+ C'f8', C'f9', C'fa', C'fb', C'fc', C'fd', C'fe', C'ff'
+];
+
+DCL charmatrix ARRAY (0:255) CHAR INIT := [
+ 'a','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X',
+ 'a','a','X','X','X','X','X','X','X','X','X','X','X','X','X','X',
+ 'a','a','a','X','X','X','X','X','X','X','X','X','X','X','X','X',
+ 'a','a','a','a','X','X','X','X','X','X','X','X','X','X','X','X',
+ 'a','a','a','a','a','X','X','X','X','X','X','X','X','X','X','X',
+ 'a','a','a','a','a','a','X','X','X','X','X','X','X','X','X','X',
+ 'a','a','a','a','a','a','a','X','X','X','X','X','X','X','X','X',
+ 'a','a','a','a','a','a','a','a','X','X','X','X','X','X','X','X',
+ 'a','a','a','a','a','a','a','a','a','X','X','X','X','X','X','X',
+ 'a','a','a','a','a','a','a','a','a','a','X','X','X','X','X','X',
+ 'a','a','a','a','a','a','a','a','a','a','a','X','X','X','X','X',
+ 'a','a','a','a','a','a','a','a','a','a','a','a','X','X','X','X',
+ 'a','a','a','a','a','a','a','a','a','a','a','a','a','X','X','X',
+ 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','X','X',
+ 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','X',
+ 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a'
+];
+
+DCL xptr PTR INIT := ->int_high;
+
+booleans: PROC ();
+
+ DCL val1 BOOL := TRUE;
+ DCL val2 BOOL := FALSE;
+ DCL val3 BOOL := TRUE;
+
+ val1 := TRUE XOR TRUE;
+ val1 := TRUE XOR FALSE;
+ val1 := FALSE XOR TRUE;
+ val1 := FALSE XOR FALSE;
+ val1 := val2 XOR val3;
+
+ val1 := TRUE AND TRUE;
+ val1 := TRUE AND FALSE;
+ val1 := FALSE AND TRUE;
+ val1 := FALSE AND FALSE;
+ val1 := val2 AND val3;
+
+ val1 := TRUE ANDIF TRUE;
+ val1 := TRUE ANDIF FALSE;
+ val1 := FALSE ANDIF TRUE;
+ val1 := FALSE ANDIF FALSE;
+ val1 := val2 ANDIF val3;
+
+ val1 := TRUE OR TRUE;
+ val1 := TRUE OR FALSE;
+ val1 := FALSE OR TRUE;
+ val1 := FALSE OR FALSE;
+ val1 := val2 OR val3;
+
+-- val1 := NOT TRUE;
+-- val1 := NOT FALSE;
+-- val1 := NOT val2;
+-- val1 := NOT val3;
+
+END booleans;
+
+scalar_arithmetic: PROC ();
+
+ DCL val1 INT := 1;
+ DCL val2 INT := 2;
+ DCL val3 INT := 3;
+
+ val1 := -val2;
+ val1 := val2 + val3;
+ val1 := val2 - val3;
+ val1 := val2 * val3;
+ val1 := val2 / val3;
+ val1 := val2 MOD val3;
+ val1 := val2 REM val3;
+
+END scalar_arithmetic;
+
+write_arrays: PROC ();
+
+ inttable1(0) := 0;
+ inttable1(1) := 1;
+ inttable1(2) := 2;
+ inttable1(3) := 3;
+ inttable1(4) := 4;
+ inttable2(5) := 5;
+ inttable2(6) := 6;
+ inttable2(7) := 7;
+ inttable2(8) := 8;
+ inttable2(9) := 9;
+
+END write_arrays;
+
+uint_low := 0;
+
+scalar_arithmetic ();
+write_arrays ();
+booleans ();
+
+END;
diff --git a/gdb/testsuite/gdb.chill/chillvars.exp b/gdb/testsuite/gdb.chill/chillvars.exp
new file mode 100644
index 00000000000..386bf432bd1
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/chillvars.exp
@@ -0,0 +1,316 @@
+# Copyright 1992, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "chillvars"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ # This is needed (at least on SunOS4) to make sure the
+ # the symbol table is read.
+ gdb_test "break chillvars.ch:3" ""
+ gdb_test "delete 1" ""
+
+ gdb_test "set width 0" ""
+ gdb_test "set print sevenbit-strings" ""
+ gdb_test "set print address off" ""
+
+ test_BOOL
+ test_CHAR
+ test_BYTE
+ test_UBYTE
+ test_INT
+ test_UINT
+ test_LONG
+ test_ULONG
+ test_REAL
+ test_LONG_REAL
+ test_POWERSET
+ test_arrays
+ test_strings
+ test_structs
+
+ test_ptr
+}
+
+proc test_BOOL {} {
+
+ gdb_test "ptype bool_true" "type = (BOOL|bool)"
+ gdb_test "ptype bool_false" "type = (BOOL|bool)"
+ gdb_test "whatis bool_true" "type = (BOOL|bool)"
+ gdb_test "whatis bool_false" "type = (BOOL|bool)"
+ gdb_test "print bool_false" " = FALSE"
+ gdb_test "print bool_true" " = TRUE"
+
+}
+
+proc test_CHAR {} {
+ gdb_test "ptype control_char" "type = (CHAR|char)"
+ gdb_test "whatis control_char" "type = (CHAR|char)"
+ gdb_test "print control_char" { = '\^[(]7[)]'}
+ gdb_test "ptype printable_char" "type = (CHAR|char)"
+ gdb_test "whatis printable_char" "type = (CHAR|char)"
+ gdb_test "print printable_char" " = 'a'"
+
+ gdb_test "print lower(char)" { = '\^[(]0[)]'}
+ gdb_test "print upper(char)" { = '\^[(]255[)]'}
+}
+
+proc test_BYTE {} {
+ gdb_test "ptype byte_low" "type = (BYTE|byte)"
+ gdb_test "whatis byte_low" "type = (BYTE|byte)"
+ gdb_test "print byte_low" " = -128"
+ gdb_test "ptype byte_high" "type = (BYTE|byte)"
+ gdb_test "whatis byte_high" "type = (BYTE|byte)"
+ gdb_test "print byte_high" " = 127"
+
+ gdb_test "print lower(byte)" " = -128"
+ gdb_test "print upper(byte)" " = 127"
+ gdb_test "print lower(byte_high)" " = -128"
+ gdb_test "print upper(byte_high)" " = 127"
+}
+
+proc test_UBYTE {} {
+ gdb_test "ptype ubyte_low" "type = (UBYTE|ubyte)"
+ gdb_test "whatis ubyte_low" "type = (UBYTE|ubyte)"
+ gdb_test "print ubyte_low" " = 0"
+ gdb_test "ptype ubyte_high" "type = (UBYTE|ubyte)"
+ gdb_test "whatis ubyte_high" "type = (UBYTE|ubyte)"
+ gdb_test "print ubyte_high" " = 255"
+}
+
+proc test_INT {} {
+ gdb_test "ptype int_low" "type = (INT|int)"
+ gdb_test "whatis int_low" "type = (INT|int)"
+ gdb_test "print int_low" " = -32768"
+ gdb_test "ptype int_high" "type = (INT|int)"
+ gdb_test "whatis int_high" "type = (INT|int)"
+ gdb_test "print int_high" " = 32767"
+}
+
+proc test_UINT {} {
+ gdb_test "ptype uint_low" "type = (UINT|uint)"
+ gdb_test "whatis uint_low" "type = (UINT|uint)"
+ gdb_test "print uint_low" " = 0"
+ gdb_test "ptype uint_high" "type = (UINT|uint)"
+ gdb_test "whatis uint_high" "type = (UINT|uint)"
+ gdb_test "print uint_high" " = 65535"
+}
+
+proc test_LONG {} {
+ gdb_test "ptype long_low" "type = (LONG|long)"
+ gdb_test "whatis long_low" "type = (LONG|long)"
+ gdb_test "print long_low" " = -2147483648"
+ gdb_test "ptype long_high" "type = (LONG|long)"
+ gdb_test "whatis long_high" "type = (LONG|long)"
+ gdb_test "print long_high" " = 2147483647"
+}
+
+proc test_ULONG {} {
+ gdb_test "ptype ulong_low" "type = (ULONG|ulong)"
+ gdb_test "whatis ulong_low" "type = (ULONG|ulong)"
+ gdb_test "print ulong_low" " = 0"
+ gdb_test "ptype ulong_high" "type = (ULONG|ulong)"
+ gdb_test "whatis ulong_high" "type = (ULONG|ulong)"
+ gdb_test "print ulong_high" " = 4294967295"
+}
+
+proc test_REAL {} {
+ gdb_test "ptype real1" "type = (FLOAT|float)"
+ gdb_test "whatis real1" "type = (FLOAT|float)"
+ gdb_test "print real1" " = 3.14159274"
+}
+
+proc test_LONG_REAL {} {
+ gdb_test "ptype long_real1" "type = (DOUBLE|double)"
+ gdb_test "whatis long_real1" "type = (DOUBLE|double)"
+ gdb_test "print long_real1" " = 3\\.1400000000000001e\\+300"
+}
+
+proc test_POWERSET {} {
+}
+
+proc test_arrays {} {
+ gdb_test "ptype booltable1" "type = ARRAY \\(+0:3\\)+ (BOOL|bool)"
+ gdb_test_exact "print booltable1" \
+ { = [(0): TRUE, (1:2): FALSE, (3): TRUE]}
+
+ gdb_test "ptype booltable2" "type = ARRAY \\(+4:7\\)+ (BOOL|bool)"
+ gdb_test_exact "print booltable2" { = [(4): TRUE, (5:6): FALSE, (7): TRUE]}
+
+ gdb_test "ptype chartable1" "type = ARRAY \\(+0:2\\)+ (CHAR|char)"
+ gdb_test_exact "print chartable1" {= [(0): '^(0)', (1): '^(1)', (2): '^(2)']}
+
+ gdb_test "ptype chartable2" "type = ARRAY \\(+3:5\\)+ (CHAR|char)"
+ gdb_test_exact "print chartable2" \
+ {= [(3): '^(0)', (4): '^(1)', (5): '^(2)']}
+
+ gdb_test "ptype bytetable1" "type = ARRAY \\(+0:4\\)+ (BYTE|byte)"
+ gdb_test_exact "print bytetable1" \
+ {= [(0): -2, (1): -1, (2): 0, (3): 1, (4): 2]}
+
+ gdb_test "ptype bytetable2" "type = ARRAY \\(+5:9\\)+ (BYTE|byte)"
+ gdb_test_exact "print bytetable2" \
+ {= [(5): -2, (6): -1, (7): 0, (8): 1, (9): 2]}
+
+ gdb_test "ptype bytetable3" \
+ "type = ARRAY \\(1:2\\) ARRAY \\('c':'d'\\) ARRAY \\(FALSE:TRUE\\) (BYTE|byte)"
+ gdb_test_exact "print bytetable3" \
+ {= [(1): [('c'): [(FALSE): 0, (TRUE): 1], ('d'): [(FALSE): 2, (TRUE): 3]], (2): [('c'): [(FALSE): 4, (TRUE): 5], ('d'): [(FALSE): 6, (TRUE): 7]]]}
+ gdb_test "ptype bytetable4" \
+ "type = ARRAY \\(1:2\\) ARRAY \\('c':'d'\\) ARRAY \\(FALSE:TRUE\\) (BYTE|byte)"
+ gdb_test_exact "print bytetable4" \
+ {= [(1): [('c'): [(FALSE): 0, (TRUE): 1], ('d'): [(FALSE): 2, (TRUE): 3]], (2): [('c'): [(FALSE): 4, (TRUE): 5], ('d'): [(FALSE): 6, (TRUE): 7]]]}
+
+ gdb_test "ptype ubytetable1" "type = ARRAY \\(+0:4\\)+ (UBYTE|ubyte)"
+ gdb_test_exact "print ubytetable1" \
+ {= [(0): 0, (1): 1, (2): 2, (3): 3, (4): 4]}
+
+ gdb_test "ptype ubytetable2" "type = ARRAY \\(+5:9\\)+ (UBYTE|ubyte)"
+ gdb_test_exact "print ubytetable2" \
+ {= [(5): 0, (6): 1, (7): 2, (8): 3, (9): 4]}
+
+ gdb_test "ptype inttable1" "type = ARRAY \\(+0:4\\)+ (INT|int)"
+ gdb_test_exact "print inttable1" \
+ {= [(0): -2, (1): -1, (2): 0, (3): 1, (4): 2]}
+
+ gdb_test "ptype inttable2" "type = ARRAY \\(+5:9\\)+ (INT|int)"
+ gdb_test_exact "print inttable2" \
+ {= [(5): -2, (6): -1, (7): 0, (8): 1, (9): 2]}
+
+ gdb_test "ptype uinttable1" "type = ARRAY \\(+0:4\\)+ (UINT|uint)"
+ gdb_test_exact "print uinttable1" \
+ {= [(0): 0, (1): 1, (2): 2, (3): 3, (4): 4]}
+
+ gdb_test "ptype uinttable2" "type = ARRAY \\(+5:9\\)+ (UINT|uint)"
+ gdb_test_exact "print uinttable2" \
+ {= [(5): 0, (6): 1, (7): 2, (8): 3, (9): 4]}
+
+ gdb_test "ptype longtable1" "type = ARRAY \\(+0:4\\)+ (LONG|long)"
+ gdb_test_exact "print longtable1" \
+ {= [(0): -2, (1): -1, (2): 0, (3): 1, (4): 2]}
+
+ gdb_test "ptype longtable2" "type = ARRAY \\(+5:9\\)+ (LONG|long)"
+ gdb_test_exact "print longtable2" \
+ {= [(5): -2, (6): -1, (7): 0, (8): 1, (9): 2]}
+
+ gdb_test "ptype ulongtable1" "type = ARRAY \\(+0:4\\)+ (ULONG|ulong)"
+ gdb_test_exact "print ulongtable1" \
+ {= [(0): 0, (1): 1, (2): 2, (3): 3, (4): 4]}
+
+ gdb_test "ptype ulongtable2" "type = ARRAY \\(+5:9\\)+ (ULONG|ulong)"
+ gdb_test_exact "print ulongtable2" \
+ {= [(5): 0, (6): 1, (7): 2, (8): 3, (9): 4]}
+
+ gdb_test "ptype realtable1" "type = ARRAY \\(+0:4\\)+ (FLOAT|float)"
+ gdb_test_exact "print realtable1" \
+ {= [(0): -2, (1): -1, (2): 0, (3): 1, (4): 2]}
+
+ gdb_test "ptype realtable2" "type = ARRAY \\(+5:9\\)+ (FLOAT|float)"
+ gdb_test_exact "print realtable2" \
+ {= [(5): -2, (6): -1, (7): 0, (8): 1, (9): 2]}
+
+ gdb_test "ptype longrealtable1" "type = ARRAY \\(+0:4\\)+ (DOUBLE|double)"
+ gdb_test_exact "print longrealtable1" \
+ {= [(0): -2, (1): -1, (2): 0, (3): 1, (4): 2]}
+
+ gdb_test "ptype longrealtable2" "type = ARRAY \\(+5:9\\)+ (DOUBLE|double)"
+ gdb_test_exact "print longrealtable2" \
+ {= [(5): -2, (6): -1, (7): 0, (8): 1, (9): 2]}
+
+ gdb_test "print length(longrealtable2)" {= 5}
+ gdb_test "print lower(longrealtable2)" {= 5}
+ gdb_test "print upper(longrealtable2)" {= 9}
+}
+
+proc test_strings {} {
+
+ gdb_test "ptype string1" "type = CHARS \[(\]4\[)\]+"
+ gdb_test "print string1" " = \"abcd\""
+
+ gdb_test "ptype string2" "type = CHARS \[(\]+5\[)\]+"
+ gdb_test "print string2" { = \"ef\^\(0\)gh\"}
+
+ gdb_test "ptype string3" "type = CHARS \[(\]+6\[)\]+"
+ gdb_test "print string3" " = \"efghij\""
+
+ gdb_test "ptype string4" "type = CHARS \[(\]+7\[)\]+"
+ gdb_test "print string4" { = \"zzzzzz\^\(0\)\"}
+
+ # These tests require a running process, so run to one of the procs
+ # and then do the tests.
+
+ if [runto scalar_arithmetic] then {
+ gdb_test "ptype string1//string2" "type = CHARS \\(9\\)"
+ gdb_test "print string1//string2" { = \"abcdef\^\(0\)gh\"}
+ gdb_test_exact {ptype "a chill string"} {type = CHARS (14)}
+ gdb_test "print 'a chill string'" " = \"a chill string\""
+ gdb_test "print \"ef\"//c'00'//\"gh\"" { = \"ef\^\(0\)gh\"}
+ gdb_test "print string1 // \"efgh\"" " = \"abcdefgh\""
+ gdb_test "print (6) 'z'" " = \"zzzzzz\""
+ gdb_test "ptype (6) 'z'" "type = CHARS \[(\]+6\[)\]+"
+ gdb_test "print (1+2*3) 'x'" " = \"xxxxxxx\""
+ gdb_test "ptype (1+2*3) 'x'" "type = CHARS \[(\]+7\[)\]+"
+ }
+
+}
+
+proc test_structs {} {
+ gdb_test "ptype struct1" \
+ "type = STRUCT \\(+.*abool (BOOL|bool),.*aint (INT|int),.*astring CHARS \\(+8\\)+.*\\)+"
+ gdb_test "print struct1" \
+ ".* = \\\[\.abool: TRUE, \.aint: 123, \.astring: \"a string\"\\\]"
+ gdb_test "ptype struct2" \
+ "type = STRUCT \\(+.*abool (BOOL|bool),.*nstruct simple_struct,.*aint (INT|int).*\\)+"
+ gdb_test "print struct2" \
+ ".* = \\\[.abool: TRUE, \.nstruct: \\\[\.abool: FALSE, \.aint: 456, \.astring: \"deadbeef\"\\\], \.aint: 789\\\]"
+}
+
+proc test_ptr {} {
+ # This is to test Cygnus PR 6932
+ gdb_test "print xptr->int" ".* = 32767"
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/configure b/gdb/testsuite/gdb.chill/configure
new file mode 100755
index 00000000000..24e429d9ce5
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/configure
@@ -0,0 +1,899 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=chexp.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:573: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:594: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:612: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.chill/configure.in b/gdb/testsuite/gdb.chill/configure.in
new file mode 100644
index 00000000000..3eed026de42
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/configure.in
@@ -0,0 +1,11 @@
+dnl Process this file file with autoconf to produce a configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(chexp.exp)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.chill/enum.ch b/gdb/testsuite/gdb.chill/enum.ch
new file mode 100644
index 00000000000..971fc9421a5
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/enum.ch
@@ -0,0 +1,9 @@
+hugo: module
+
+ synmode m_set = set (a, b, c, d, e, f, g, h, i);
+ dcl x long;
+ dcl y m_set;
+
+ writetext (stdout, "done.%/");
+
+end hugo;
diff --git a/gdb/testsuite/gdb.chill/enum.exp b/gdb/testsuite/gdb.chill/enum.exp
new file mode 100644
index 00000000000..78152722bcf
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/enum.exp
@@ -0,0 +1,85 @@
+# Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Wilfried Moser (moser@aut.alcatel.at
+#
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "enum"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to chill. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_chill {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+
+ send_gdb "set language chill\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language chill (timeout)" ; return 0 }
+ }
+
+ return [gdb_test "show language" ".* source language is \"chill\".*" \
+ "set language to \"chill\""]
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+if ![set_lang_chill] then {
+ runto hugo_
+
+ send_gdb "set var \$i := d\n"
+ gdb_expect -re ".*$gdb_prompt $"
+ gdb_test "print \$i" { = d}
+ gdb_test "print size (\$i)" { = 1}
+ gdb_test "print b+c" { = 3}
+ gdb_test "print c*d" { = 6}
+ gdb_test "print a<b" { = TRUE}
+ gdb_test "print a=b" { = FALSE}
+ gdb_test "print a=a" { = TRUE}
+ gdb_test "print a/=\$i" { = TRUE}
+
+# This is PR 8870
+ gdb_test "break malloc" ".*"
+ gdb_test {set var $j := m_set[b]} ".*invalid.*tuple.*"
+}
diff --git a/gdb/testsuite/gdb.chill/func1.ch b/gdb/testsuite/gdb.chill/func1.ch
new file mode 100644
index 00000000000..d0d28ce9fae
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/func1.ch
@@ -0,0 +1,9 @@
+func1: MODULE
+
+SYNMODE m_set = SET (e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
+SYNMODE m_setrange = RANGE (e3:e8);
+SYNMODE m_ps = POWERSET m_set;
+SYNMODE m_rangeps = POWERSET RANGE(0:31);
+GRANT ALL;
+
+END func1;
diff --git a/gdb/testsuite/gdb.chill/gch1041.ch b/gdb/testsuite/gdb.chill/gch1041.ch
new file mode 100644
index 00000000000..a9ce80b75ed
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/gch1041.ch
@@ -0,0 +1,17 @@
+arr: MODULE
+
+SYNMODE m_chars = CHARS(30) VARYING;
+SYNMODE m_s = STRUCT (l LONG, c m_chars, b BOOL);
+
+DCL a1 ARRAY (1:1000) LONG INIT := [(5:100): 33, (1:4): 44, (ELSE): 55 ];
+DCL a2 ARRAY (1:10) m_s INIT := [(*): [ 22, "mowi", TRUE ] ];
+DCL a3 ARRAY (CHAR) CHAR INIT := [(*): 'X'];
+
+SYNMODE m_set = SET (e1, e2, e3, e4, e5, e6, e7, e9, e10);
+DCL a4 ARRAY (m_set) BOOL INIT := [(*): TRUE];
+
+a1 := [(5:100): 33, (1:4): 44, (ELSE): 55 ];
+a1 := [ (*): 22 ];
+a2 := [(*): [ 22, "mowi", TRUE ] ];
+
+END arr;
diff --git a/gdb/testsuite/gdb.chill/gch1041.exp b/gdb/testsuite/gdb.chill/gch1041.exp
new file mode 100644
index 00000000000..ec80ddf4629
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/gch1041.exp
@@ -0,0 +1,76 @@
+# Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+# Martin Pottendorfer (pottendo@aut.alcatel.at)
+#
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "gch1041"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to chill. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_chill {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+
+ send_gdb "set language chill\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language chill (timeout)" ; return 0 }
+ }
+
+ return [gdb_test "show language" ".* source language is \"chill\".*" \
+ "set language to \"chill\""]
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+if ![set_lang_chill] then {
+ runto arr_
+ # check if array slices print correct index
+ gdb_test {print a1(10:30)} { = \[\(10:30\): 33\]}
+ gdb_test {print a2(3:5)} { = \[\(3:5\): \[.l: 22, .c: "mowi", .b: TRUE\]\]}
+ gdb_test {print a3('a':'c')} { = \[\('a':'c'\): 'X'\]}
+ gdb_test {print a4(e2:e5)} { = \[\(e2:e5\): TRUE\]}
+}
diff --git a/gdb/testsuite/gdb.chill/gch1272.ch b/gdb/testsuite/gdb.chill/gch1272.ch
new file mode 100644
index 00000000000..6112d4ba60a
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/gch1272.ch
@@ -0,0 +1,21 @@
+gch1272: MODULE
+
+SYNMODE m_array = ARRAY (0:99) INT;
+DCL foo m_array;
+
+SYNMODE m_xxx = ARRAY (1:10) LONG;
+
+SYNMODE m_struct = STRUCT (i LONG, b BOOL);
+SYNMODE m_bar = ARRAY (-10:20) m_struct;
+DCL bar m_bar;
+
+SYNMODE m_ps = POWERSET LONG (0:20);
+
+brrr: PROC ()
+END;
+
+foo := [ (*): 222 ];
+
+brrr ();
+
+END gch1272;
diff --git a/gdb/testsuite/gdb.chill/gch1272.exp b/gdb/testsuite/gdb.chill/gch1272.exp
new file mode 100644
index 00000000000..544a5ecb6bf
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/gch1272.exp
@@ -0,0 +1,86 @@
+# Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Wilfried Moser (moser@aut.alcatel.at)
+#
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "gch1272"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to chill. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_chill {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+
+ send_gdb "set language chill\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language chill (timeout)" ; return 0 }
+ }
+
+ return [gdb_test "show language" ".* source language is \"chill\".*" \
+ "set language to \"chill\""]
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+if ![set_lang_chill] then {
+ runto brrr
+
+ # check foo
+ gdb_test {print foo} { = \[\(0:99\): 222\]}
+ gdb_test "set var foo := m_array\[\(\*\):44\]" ".*"
+ gdb_test {print foo} { = \[\(0:99\): 44\]}
+
+ # check bar
+ gdb_test {print bar} { = \[\(-10:20\): \[.i: 0, .b: FALSE\]\]}
+ gdb_test "set var bar := m_bar\[\(\*\): \[42, TRUE\]\]" ".*"
+ gdb_test {print bar} { = \[\(-10:20\): \[.i: 42, .b: TRUE\]\]}
+
+ # some failues
+ gdb_test "set var foo := \[\(\*\):44\]" {\(\*\) only possible with modename in front of tuple \(mode\[\.\.\]\)}
+ gdb_test "set var foo := m_xxx\[\(\*\):44\]" {Invalid cast\.}
+ gdb_test "set var foo := m_struct\[\(\*\):44\]" {\(\*\) in invalid context}
+ gdb_test "set var foo := m_ps\[\(\*\):44\]" {\(\*\) in invalid context}
+}
diff --git a/gdb/testsuite/gdb.chill/gch1280.ch b/gdb/testsuite/gdb.chill/gch1280.ch
new file mode 100644
index 00000000000..3fba71f9111
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/gch1280.ch
@@ -0,0 +1,13 @@
+gch1280: MODULE
+
+SYNMODE m_x = ARRAY (1:3) LONG;
+DCL v_x m_x;
+DCL v_xx m_x;
+
+doit: PROC ()
+END doit;
+
+v_x := [ 11, 12, 13 ];
+doit ();
+
+END gch1280;
diff --git a/gdb/testsuite/gdb.chill/gch1280.exp b/gdb/testsuite/gdb.chill/gch1280.exp
new file mode 100644
index 00000000000..c05f84547ea
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/gch1280.exp
@@ -0,0 +1,76 @@
+# Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Wilfried Moser (moser@aut.alcatel.at)
+#
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "gch1280"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to chill. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_chill {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+
+ send_gdb "set language chill\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language chill (timeout)" ; return 0 }
+ }
+
+ return [gdb_test "show language" ".* source language is \"chill\".*" \
+ "set language to \"chill\""]
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+if ![set_lang_chill] then {
+ runto doit
+ gdb_test "next" ""
+ # check too many array elements
+ gdb_test {set var v_x := [1,2,3,4,5]} {Too many array elements}
+ gdb_test {set var $i := m_x[(3): 22, 25]} {Too many array elements}
+ gdb_test "set var \$i := m_x\[\(2\): 22, 25\]" ""
+ gdb_test {print $i} { = \[\(1\): 0, \(2\): 22, \(3\): 25\]}
+}
diff --git a/gdb/testsuite/gdb.chill/gch922.ch b/gdb/testsuite/gdb.chill/gch922.ch
new file mode 100644
index 00000000000..b3e8a239512
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/gch922.ch
@@ -0,0 +1,23 @@
+xx : module
+
+dcl a chars(200) varying init := (70)'^(0)' // "Jason""^(0,5)""Hugo^(10)" // (70)'^(1)';
+dcl b chars(20) varying init := "Jason""^(0,5)""Hugo^(10)";
+dcl c chars(256) varying init := (70)'a' // "^(0,5)Jason" // (70)'b';
+dcl d char init := '^(11)';
+
+bulk: PROC ();
+END bulk;
+
+a := (50) '^(255,0,222,127)';
+b := (1)'^(200)';
+d := 'a';
+
+c:= (256)" ";
+
+DO FOR i:= 0 BY 1 TO 255;
+ c (255-i) := char (i);
+OD;
+
+bulk ();
+
+end xx; \ No newline at end of file
diff --git a/gdb/testsuite/gdb.chill/gch922.exp b/gdb/testsuite/gdb.chill/gch922.exp
new file mode 100644
index 00000000000..104b6224338
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/gch922.exp
@@ -0,0 +1,183 @@
+# Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file tests various Chill values, expressions, and types.
+
+# This file was written by Wilfried Moser (moser@aut.alcatel.at)
+# Kurt Fuchs (fuchs_k@aut.alcatel.at)
+#
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "gch922"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -w -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to chill. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_chill {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+ send_gdb "set language chill\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language chill (timeout)" ; return 0 }
+ }
+
+ send_gdb "show language\n"
+ gdb_expect {
+ -re ".* source language is \"chill\".*$gdb_prompt $" {
+ pass "set language to \"chill\""
+ send_gdb "break xx_\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {
+ send_gdb "run\n"
+ gdb_expect -re ".*$gdb_prompt $" {}
+ return 1
+ }
+ timeout {
+ fail "can't set breakpoint (timeout)"
+ return 0
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "setting language to \"chill\""
+ return 0
+ }
+ timeout {
+ fail "can't show language (timeout)"
+ return 0
+ }
+ }
+}
+
+# Testing printing of a specific value. Increment passcount for
+# success or issue fail message for failure. In both cases, return
+# a 1 to indicate that more tests can proceed. However a timeout
+# is a serious error, generates a special fail message, and causes
+# a 0 to be returned to indicate that more tests are likely to fail
+# as well.
+#
+# Args are:
+#
+# First one is string to send_gdb to gdb
+# Second one is string to match gdb result to
+# Third one is an optional message to be printed
+
+proc test_print_accept { args } {
+ global gdb_prompt
+ global passcount
+ global verbose
+
+ if [llength $args]==3 then {
+ set message [lindex $args 2]
+ } else {
+ set message [lindex $args 0]
+ }
+ set sendthis [lindex $args 0]
+ set expectthis [lindex $args 1]
+ set result [gdb_test $sendthis ".* = ${expectthis}" $message]
+ if $result==0 {incr passcount}
+ return $result
+}
+
+
+proc test_chars {} {
+ global passcount gdb_prompt
+
+ verbose "Testing Chars"
+ set passcount 0
+
+ test_print_accept "print a" {'\^\(0\)'<repeats 70 times>//"Jason""\^\(0,5\)""Hugo\^\(10\)"//'\^\(1\)'<repeats 70 times>}
+ test_print_accept "print b" {"Jason""\^\(0,5\)""Hugo\^\(10\)"}
+ test_print_accept "print c" {'a'<repeats 70 times>//"\^\(0,5\)Jason"//'b'<repeats 70 times>}
+ test_print_accept "print d" {'\^\(11\)'}
+
+ gdb_test "set var a := (100)'\^(0,255)'" ""
+ test_print_accept "print a" {"\^\(0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255\)"}
+
+ send_gdb "set var a := (10)'\^(1)'//(26)\"\^(66,67)\"//\" \"//'I'//' '//'a'//'m'//\" Hugo\" \n" ; gdb_expect -re "$gdb_prompt $"
+ test_print_accept "print a" {"\^\(1,1,1,1,1,1,1,1,1,1\)BCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBC I am Hugo"}
+ send_gdb "set var b := \"Hugo \"\"\^(3,4)\"\"Otto\^(17)\" \n" ; gdb_expect -re "$gdb_prompt $"
+ test_print_accept "print b" {"Hugo ""\^\(3,4\)""Otto\^\(17\)"}
+ send_gdb "set var c := (70)'b' // \"\^(2,3)Hugo \" // (70)'c' \n" ; gdb_expect -re "$gdb_prompt $"
+ test_print_accept "print c" {'b'<repeats 70 times>//"\^\(2,3\)Hugo "//'c'<repeats 70 times>}
+ gdb_test "set var d := '\^(199)'" ""
+ test_print_accept "print d" {'\^\(199\)'}
+
+ test_print_accept "print (10)'\^(0)'//(26)\"\^(66,67)\"//\" \"//'I'//' '//'a'//'m'//\" Hugo\"" {"\^\(0,0,0,0,0,0,0,0,0,0\)BCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBC I am Hugo"}
+ test_print_accept "print \"Jason\"\"\^(0,5)\"\"Hugo\^(10)\"" {"Jason""\^\(0,5\)""Hugo\^\(10\)"}
+
+ send_gdb "set var a := \"\" \n" ; gdb_expect -re "$gdb_prompt $"
+ test_print_accept "print a" {""}
+ send_gdb "set var a := \"\"\"\" \n" ; gdb_expect -re "$gdb_prompt $"
+ test_print_accept "print a" {""""}
+ send_gdb "set var a := \" \"\"\" \n" ; gdb_expect -re "$gdb_prompt $"
+ test_print_accept "print a" {" """}
+ send_gdb "set var a := \"\^\^\" \n" ; gdb_expect -re "$gdb_prompt $"
+ test_print_accept "print a" {"\^\^"}
+ send_gdb "set var a := \"'\" \n" ; gdb_expect -re "$gdb_prompt $"
+ test_print_accept "print a" {"'"}
+}
+
+
+proc test_code {} {
+ global passcount gdb_prompt
+
+ verbose "Testing Chars"
+ set passcount 0
+
+ runto bulk
+ test_print_accept "print a" {"\^\(255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127,255,0,222,127\)"}
+ test_print_accept "print b" {"\^\(200\)"}
+# test_print_accept "print c" {'a'<repeats 70 times>//"\^\(0,5\)Jason"//'b'<repeats 70 times>}
+ test_print_accept "print d" {'a'}
+}
+
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+
+if [set_lang_chill] then {
+ # test builtins as described in chapter 6.20.3 Z.200
+
+ test_chars
+# test_code
+} else {
+ warning "$test_name tests suppressed."
+}
diff --git a/gdb/testsuite/gdb.chill/gch981.ch b/gdb/testsuite/gdb.chill/gch981.ch
new file mode 100644
index 00000000000..e8f0474729e
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/gch981.ch
@@ -0,0 +1,60 @@
+xx: MODULE
+
+SYNMODE m_set1 = SET (e1, e2, e3, e4, e5);
+DCL v_set1 m_set1 INIT := e3;
+
+SYNMODE m_set2 = SET (a1=1, a2=2, a3=17, a4=9, a5=8, a6=0, a7=14, a8=33, a9=12);
+DCL v1_set2 m_set2 INIT := a1;
+DCL v2_set2 m_set2 INIT := a2;
+DCL v3_set2 m_set2 INIT := a3;
+DCL v4_set2 m_set2 INIT := a4;
+DCL v5_set2 m_set2 INIT := a5;
+DCL v6_set2 m_set2 INIT := a6;
+DCL v7_set2 m_set2 INIT := a7;
+DCL v8_set2 m_set2 INIT := a8;
+DCL v9_set2 m_set2 INIT := a9;
+
+SYNMODE m_set3 = SET (b1, b2, b3, b4, b5 = 4711, b6, b7 = 4713);
+DCL v_set3 m_set3 INIT := b7;
+
+SYNMODE m_set4 = SET(s1=111111, s2, s3, s4);
+DCL v1_set4 m_set4 INIT := s1;
+
+SYNMODE m_set_range = m_set1(e2:e5);
+DCL v_set_range m_set_range INIT := e3;
+
+SYNMODE m_set_range_arr = ARRAY (m_set_range) BYTE;
+DCL v_set_range_arr ARRAY (m_set_range) BYTE;
+
+SYNMODE m_set_arr = ARRAY (m_set1) BYTE;
+DCL v_set_arr ARRAY (m_set1) BYTE;
+
+NEWMODE m_power1 = POWERSET m_set1;
+DCL v1_power1 READ m_power1 INIT := [e1,e2,e3,e4,e5];
+DCL v2_power1 m_power1 INIT := [];
+
+NEWMODE m_power2 = POWERSET m_set2;
+DCL v_power2 m_power2 INIT := [];
+
+NEWMODE m_power3 = POWERSET m_set3;
+DCL v_power3 m_power3 INIT := [b1:b2];
+
+NEWMODE m_power4 = POWERSET CHAR;
+DCL v_power4 m_power4 INIT := ['b':'x'];
+
+NEWMODE m_power5 = POWERSET INT (2:400);
+DCL v_power5 m_power5 INIT := [2:100];
+
+NEWMODE m_power6 = POWERSET INT;
+DCL v_power6 m_power6;
+
+NEWMODE m_power7 = POWERSET LONG;
+DCL v_power7 m_power7;
+
+
+v_set1:= e2;
+v2_power1:= [e1];
+
+v_set1:= e1;
+
+END xx;
diff --git a/gdb/testsuite/gdb.chill/gch981.exp b/gdb/testsuite/gdb.chill/gch981.exp
new file mode 100644
index 00000000000..5651bb0a56d
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/gch981.exp
@@ -0,0 +1,249 @@
+# Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file tests various Chill values, expressions, and types.
+
+# This file was written by Wilfried Moser (moser@aut.alcatel.at)
+# Kurt Fuchs (fuchs_k@aut.alcatel.at)
+#
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "gch981"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -w -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to chill. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_chill {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+ send_gdb "set language chill\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language chill (timeout)" ; return 0 }
+ }
+
+ send_gdb "show language\n"
+ gdb_expect {
+ -re ".* source language is \"chill\".*$gdb_prompt $" {
+ pass "set language to \"chill\""
+ send_gdb "break xx_\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {
+ send_gdb "run\n"
+ gdb_expect -re ".*$gdb_prompt $" {}
+ return 1
+ }
+ timeout {
+ fail "can't set breakpoint (timeout)"
+ return 0
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "setting language to \"chill\""
+ return 0
+ }
+ timeout {
+ fail "can't show language (timeout)"
+ return 0
+ }
+ }
+}
+
+# Testing printing of a specific value. Increment passcount for
+# success or issue fail message for failure. In both cases, return
+# a 1 to indicate that more tests can proceed. However a timeout
+# is a serious error, generates a special fail message, and causes
+# a 0 to be returned to indicate that more tests are likely to fail
+# as well.
+#
+# Args are:
+#
+# First one is string to send_gdb to gdb
+# Second one is string to match gdb result to
+# Third one is an optional message to be printed
+
+proc test_print_accept { args } {
+ global gdb_prompt
+ global passcount
+ global verbose
+
+ if [llength $args]==3 then {
+ set message [lindex $args 2]
+ } else {
+ set message [lindex $args 0]
+ }
+ set sendthis [lindex $args 0]
+ set expectthis [lindex $args 1]
+ set result [gdb_test $sendthis ".* = ${expectthis}" $message]
+ if $result==0 {incr passcount}
+ return $result
+}
+
+proc test_power {} {
+ global passcount gdb_prompt
+
+ verbose "Testing some POWERSET Stuff"
+ set passcount 0
+
+ test_print_accept "print v1_power1" {\[e1:e5\]}
+ test_print_accept "print v2_power1" {\[\]}
+ test_print_accept "print SIZE(v1_power1)" "1"
+
+ gdb_test "set v1_power1 := \[b1\]" ""
+# if GDB has rejected the improper values, we have to gdb_expect the same!
+ test_print_accept "print v1_power1" {\[e1:e5\]}
+
+ gdb_test "set v1_power1 := \[a1,a2\]" ""
+ test_print_accept "print v1_power1" {\[e1:e5\]}
+ gdb_test "set v1_power1 := \[b1,b2,b3,e4\]" ""
+ test_print_accept "print v1_power1" {\[e1:e5\]}
+ gdb_test "set v1_power1 := \[e4:e5\]" ""
+ test_print_accept "print v1_power1" {\[e4:e5\]}
+ gdb_test "set v1_power1 := \[e1, e2:e3, e5\]" ""
+ test_print_accept "print v1_power1" {\[e1:e3, e5\]}
+ gdb_test "set v1_power1 := \[e1, e2:e4, e4:e5\]" ""
+ test_print_accept "print v1_power1" {\[e1:e5\]}
+ gdb_test "set v1_power1 := \[e1, e1:e3, e1:e2, e2:e3\]" ""
+ test_print_accept "print v1_power1" {\[e1:e3\]}
+
+ gdb_test "set v_power2 := \[e2\]" ""
+ test_print_accept "print v_power2" {\[\]}
+ gdb_test "set v_power2 := \[1,2,3\]" ""
+ test_print_accept "print v_power2" {\[\]}
+ gdb_test "set v_power2 := \[e2, b2, b1\]" ""
+ test_print_accept "print v_power2" {\[\]}
+
+# Note, that this is a numbered SET, so a1:a3 contains all elements (exept a6)
+ gdb_test "set v_power2 := \[a1:a3, a6:a4, a7:a9\]" ""
+ test_print_accept "print v_power2" {\[a6:a3\]}
+ gdb_test "set v_power2 := \[a1, a4:a6, a9\]" ""
+ test_print_accept "print v_power2" {\[a1, a9\]}
+ gdb_test "set v_power2 := \[a1:a2, a6, a9\]" ""
+ test_print_accept "print v_power2" {\[a6:a2, a9\]}
+ gdb_test "set v_power2 := \[a1, a4, a7:a8, a9:a3\]" ""
+ test_print_accept "print v_power2" {\[a1, a4, a9:a8\]}
+ gdb_test "set v_power2 := \[a1, a4:a8\]" ""
+ test_print_accept "print v_power2" {\[a1, a4:a8\]}
+ gdb_test "set v_power2 := \[a8,a3,a7,a9,a5,a6\]" ""
+ test_print_accept "print v_power2" {\[a6, a5, a9, a7, a3, a8\]}
+
+ gdb_test "set v_power3 := \[b1:b2,e1\]" ""
+ test_print_accept "print v_power3" {\[b1:b2\]}
+ gdb_test "set v_power3 := \[b1, b3, b6:b7\]" ""
+ test_print_accept "print v_power3" {\[b1, b3, b6:b7\]}
+ gdb_test "set v_power3 := \[b1, b3:b4, b7\]" ""
+ test_print_accept "print v_power3" {\[b1, b3:b4, b7\]}
+ gdb_test "set v_power3 := \[b1, b4:b6, b7\]" ""
+ test_print_accept "print v_power3" {\[b1, b4:b7\]}
+ gdb_test "set v_power3 := \[b1:b7\]" ""
+ test_print_accept "print v_power3" {\[b1:b7\]}
+ gdb_test "set v_power3 := \[b5:b7, b1\]" ""
+ test_print_accept "print v_power3" {\[b1, b5:b7\]}
+
+ gdb_test "set v_power4 := \[\"b\"\]" ""
+ test_print_accept "print v_power4" {\['b':'x'\]}
+ gdb_test "set v_power4 := \[5\]" ""
+ test_print_accept "print v_power4" {\['b':'x'\]}
+ gdb_test "set v_power4 := \['c':'f','g':'h','o':'t'\]" ""
+ test_print_accept "print v_power4" {\['c':'h', 'o':'t'\]}
+ gdb_test "set v_power4 := \['a','b','c','d','e','f'\]" ""
+ test_print_accept "print v_power4" {\['a':'f'\]}
+ gdb_test "set v_power4 := \['\^(0)':'\^(200)'\]" ""
+ test_print_accept "print v_power4" {\['\^\(0\)':'\^\(200\)'\]}
+
+ gdb_test "set v_power5 := \[a8\]" ""
+ test_print_accept "print v_power5" {\[2:100\]}
+ gdb_test "set v_power5 := \[4\]" ""
+ test_print_accept "print v_power5" {\[4\]}
+ gdb_test "set v_power5 := \[3:95,9:100,10:107,200:250\]" ""
+ test_print_accept "print v_power5" {\[3:107, 200:250\]}
+ gdb_test "set v_power5 := \[2, 100:120, 350:400\]" ""
+ test_print_accept "print v_power5" {\[2, 100:120, 350:400\]}
+ gdb_test "set v_power5 := \[2:64,65:127,128:256,256:399,400\]" ""
+ test_print_accept "print v_power5" {\[2:400\]}
+ gdb_test "set v_power5 := \[3:95, 99:100, 101:107, 200:250\]" ""
+ test_print_accept "print v_power5" {\[3:95, 99:107, 200:250\]}
+
+ gdb_test "set v_power6 := \[a8\]" ""
+ test_print_accept "print v_power6" {\[\]}
+ gdb_test "set v_power6 := \[4\]" ""
+ test_print_accept "print v_power6" {\[4\]}
+ gdb_test "set v_power6 := \[3:95, 99:100, 101:107, 200:250\]" ""
+ test_print_accept "print v_power6" {\[3:95, 99:107, 200:250\]}
+ gdb_test "set v_power6 := \[-111:0, 1:112, 11111:22222\]" ""
+ test_print_accept "print v_power6" {\[-111:112, 11111:22222\]}
+ gdb_test "set v_power6 := \[0, 200:4000, 6666:9999\]" ""
+ test_print_accept "print v_power6" {\[0, 200:4000, 6666:9999\]}
+
+# gdb_test "set v_power7 := \[a8\]" ""
+# test_print_accept "print v_power7" {\[2:100\]}
+# gdb_test "set v_power7 := \[4\]" ""
+# test_print_accept "print v_power7" {\[4\]}
+# gdb_test "set v_power7 := \[3:95, 99:100, 101:107, 200:250\]" ""
+# test_print_accept "print v_power7" {\[3:95, 99:107, 200:250\]}
+# gdb_test "set v_power7 := \[0, 1000, 1000000, 10000000000\]" ""
+# test_print_accept "print v_power7" {\[0, 1000, 1000000, 1000000000\]}
+# gdb_test "set v_power7 := \[-20000:100000, 111111:2222222\]" ""
+# test_print_accept "print v_power7" {\[-20000:100000, 111111:2222222\]}
+# gdb_test "set v_power7 := \[\]" ""
+# test_print_accept "print v_power7" {\[3:95, 99:107, 200:250\]}
+# gdb_test "set v_power7 := \[2:-500, -501:1, 20:370, -888:-920, 1000:2000, 1800:2500\]\ " ""
+# test_print_accept "print v_power7" {\[-920:-888, -501:2, 20:370, 1000:2500\]}
+# test_print_accept "print SIZE(v_power7)" ""
+
+
+ runto 58
+ test_print_accept "print v_set1 IN v1_power1" "TRUE"
+ test_print_accept "print v_set1 IN v2_power1" "FALSE"
+
+}
+
+
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+
+if [set_lang_chill] then {
+ # test builtins as described in chapter 6.20.3 Z.200
+
+ test_power
+} else {
+ warning "$test_name tests suppressed."
+}
diff --git a/gdb/testsuite/gdb.chill/misc.ch b/gdb/testsuite/gdb.chill/misc.ch
new file mode 100644
index 00000000000..20f12c81405
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/misc.ch
@@ -0,0 +1,12 @@
+misc_tests : MODULE;
+
+DCL otto INT := 42;
+
+DCL foo STRUCT (l LONG, c CHAR, b BOOL, s CHARS(3));
+
+dummyfunc: PROC();
+END dummyfunc;
+
+dummyfunc();
+
+END misc_tests;
diff --git a/gdb/testsuite/gdb.chill/misc.exp b/gdb/testsuite/gdb.chill/misc.exp
new file mode 100644
index 00000000000..e58ba798103
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/misc.exp
@@ -0,0 +1,100 @@
+# Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+# Martin Pottendorfer (pottendo@aut.alcatel.at)
+#
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "misc"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to chill. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_chill {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+
+ send_gdb "set language chill\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language chill (timeout)" ; return 0 }
+ }
+
+ return [gdb_test "show language" ".* source language is \"chill\".*" \
+ "set language to \"chill\""]
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+if ![set_lang_chill] then {
+ runto dummyfunc
+ # check upper/lower case
+ gdb_test "ptype BOOL" " = (bool|BOOL)"
+ gdb_test "ptype bool" " = (bool|BOOL)"
+ gdb_test "print otto" " = 42"
+ gdb_test "print OTTO" " = 42"
+ gdb_test "print otTO" " = 42"
+ gdb_test "print OTto" " = 42"
+ gdb_test "print NULL" " = NULL" "print emptiness literal"
+
+ # This tests PR 8496.
+ gdb_test {printf "%d %d.", 3+4,2} "7 2." "printf with 2 arguments"
+
+ # This tests GCH/924
+ gdb_test {print (h'23)} { = 35} "print parantised integer literal"
+
+ # Linux thinks this is at line 6, but is otherwise ok.
+ setup_xfail "i*86-pc-linux*-gnu"
+ gdb_test "info line" \
+ {Line 7 of .*misc.ch.* at address H'[0-9a-fA-F]+.*}\
+ "info about current line"
+
+ # check array () type (expr)
+ setup_xfail "m68*-*-hpux*"
+ gdb_test "print array () ubyte (foo)" { = \[\(0:11\): 0\]}
+
+ send_gdb "set var \$i := foo\n"
+ gdb_expect -re ".*$gdb_prompt $"
+ setup_xfail "m68*-*-hpux*"
+ gdb_test "print/x array () byte (\$i)" { = \[\(0:11\): H'0\]}
+}
diff --git a/gdb/testsuite/gdb.chill/powerset.ch b/gdb/testsuite/gdb.chill/powerset.ch
new file mode 100644
index 00000000000..dd3172d3640
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/powerset.ch
@@ -0,0 +1,33 @@
+--
+-- check powerset operators and built-ins
+--
+
+ps: MODULE
+
+SYNMODE m_ps1 = POWERSET ULONG (0:8);
+DCL v_ps1 m_ps1 INIT := [1,3,5,7];
+
+SYNMODE m_ps2 = POWERSET LONG (-100:100);
+DCL v_ps2 m_ps2 INIT := [ -100:-95, -1:1, 95:100];
+
+SYNMODE m_set = SET (aa, bb, cc, dd, ee, ff, gg, hh, ii, jj);
+SYNMODE m_ps3 = POWERSET m_set;
+DCL v_ps3 m_ps3 INIT := [bb, dd, ff, ii];
+
+SYNMODE m_ps4 = POWERSET CHAR(' ':'z');
+DCL v_ps4 m_ps4 INIT := [ '.', ',', 'A':'F', 'x':'z' ];
+
+SYNMODE m_ps5 = POWERSET BOOL;
+DCL v_ps5 m_ps5 INIT := [ FALSE ];
+DCL v_ps51 m_ps5 INIT := [ ];
+
+SYNMODE m_int_range = INT(-100:100);
+SYNMODE m_int_subrange = m_int_range(-50:50);
+SYNMODE m_ps6 = POWERSET m_int_subrange;
+DCL v_ps6 m_ps6 INIT := [ LOWER(m_int_subrange):UPPER(m_int_subrange) ];
+
+DCL x INT;
+
+x := 25;
+
+END ps;
diff --git a/gdb/testsuite/gdb.chill/powerset.exp b/gdb/testsuite/gdb.chill/powerset.exp
new file mode 100644
index 00000000000..c41276c0c13
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/powerset.exp
@@ -0,0 +1,187 @@
+# Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file tests various Chill values, expressions, and types.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "powerset"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -w -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to chill. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_chill {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+ send_gdb "set language chill\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language chill (timeout)" ; return 0 }
+ }
+
+ send_gdb "show language\n"
+ gdb_expect {
+ -re ".* source language is \"chill\".*$gdb_prompt $" {
+ pass "set language to \"chill\""
+ send_gdb "break xx_\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {
+ send_gdb "run\n"
+ gdb_expect -re ".*$gdb_prompt $" {}
+ return 1
+ }
+ timeout {
+ fail "can't set breakpoint (timeout)"
+ return 0
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "setting language to \"chill\""
+ return 0
+ }
+ timeout {
+ fail "can't show language (timeout)"
+ return 0
+ }
+ }
+}
+
+# Testing printing of a specific value. Increment passcount for
+# success or issue fail message for failure. In both cases, return
+# a 1 to indicate that more tests can proceed. However a timeout
+# is a serious error, generates a special fail message, and causes
+# a 0 to be returned to indicate that more tests are likely to fail
+# as well.
+#
+# Args are:
+#
+# First one is string to send_gdb to gdb
+# Second one is string to match gdb result to
+# Third one is an optional message to be printed
+
+proc test_print_accept { args } {
+ global gdb_prompt
+ global passcount
+ global verbose
+
+ if [llength $args]==3 then {
+ set message [lindex $args 2]
+ } else {
+ set message [lindex $args 0]
+ }
+ set sendthis [lindex $args 0]
+ set expectthis [lindex $args 1]
+ set result [gdb_test $sendthis ".* = ${expectthis}" $message]
+ if $result==0 {incr passcount}
+ return $result
+}
+
+proc test_card {} {
+ global passcount
+
+ verbose "testing builtin CARD"
+ set passcount 0
+
+ # discrete mode names
+ test_print_accept "print card(v_ps1)" "4"
+ test_print_accept "print card(v_ps2)" "15"
+ test_print_accept "print card(v_ps3)" "4"
+ test_print_accept "print card(v_ps4)" "11"
+ test_print_accept "print card(v_ps5)" "1"
+ test_print_accept "print card(v_ps51)" "0"
+ test_print_accept "print card(v_ps6)" "101"
+
+ # a failure
+ setup_xfail "*-*-*"
+ test_print_accept "print card(m_ps1)" "typename in invalid context"
+}
+
+proc test_min {} {
+ global passcount
+
+ verbose "testing builtin MIN"
+ set passcount 0
+
+ # discrete mode names
+ test_print_accept "print min(v_ps1)" "1"
+ test_print_accept "print min(v_ps2)" "-100"
+ test_print_accept "print min(v_ps3)" "bb"
+ test_print_accept "print min(v_ps4)" "','"
+ test_print_accept "print min(v_ps5)" "FALSE"
+ test_print_accept "print min(v_ps6)" "-50"
+
+ # a failure
+ setup_xfail "*-*-*"
+ test_print_accept "print min(v_ps51)" "MIN for empty powerset"
+ setup_xfail "*-*-*"
+ test_print_accept "print min(m_ps1)" "typename in invalid context"
+}
+
+proc test_max {} {
+ global passcount
+
+ verbose "testing builtin MIN"
+ set passcount 0
+
+ # discrete mode names
+ test_print_accept "print max(v_ps1)" "7"
+ test_print_accept "print max(v_ps2)" "100"
+ test_print_accept "print max(v_ps3)" "ii"
+ test_print_accept "print max(v_ps4)" "'z'"
+ test_print_accept "print max(v_ps5)" "FALSE"
+ test_print_accept "print max(v_ps6)" "50"
+
+ # test an IN
+ test_print_accept "print 0 in v_ps6" "TRUE"
+
+ # a failure
+ setup_xfail "*-*-*"
+ test_print_accept "print max(v_ps51)" "MAX for empty powerset"
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+if [set_lang_chill] then {
+ # test builtins as described in chapter 6.20.3 Z.200
+ test_card
+ test_min
+ test_max
+} else {
+ warning "$test_name tests suppressed."
+}
diff --git a/gdb/testsuite/gdb.chill/pr-4975-grt.ch b/gdb/testsuite/gdb.chill/pr-4975-grt.ch
new file mode 100644
index 00000000000..77963628086
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-4975-grt.ch
@@ -0,0 +1,13 @@
+gdb_bug_grt: MODULE
+NEWMODE is_channel_type = SET (chan_1,
+ chan_2,
+ chan_3,
+ chan_4,
+ chan_5,
+ chan_6,
+ chan_7,
+ chan_8,
+ chan_9,
+ chan_10);
+GRANT is_channel_type;
+END;
diff --git a/gdb/testsuite/gdb.chill/pr-4975.ch b/gdb/testsuite/gdb.chill/pr-4975.ch
new file mode 100644
index 00000000000..dbba064a728
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-4975.ch
@@ -0,0 +1,43 @@
+/*
+>Number: 4975
+>Category: chill
+>Synopsis: Segmentation fault of gdb 4.12.1
+>Description:
+
+ Problem: gdb 4.12.1 segment faults with following chill program.
+*/
+
+gdb_bug: MODULE
+
+<> USE_SEIZE_FILE "pr-4975-grt.grt" <>
+SEIZE is_channel_type;
+
+ SYNMODE chan_type = POWERSET is_channel_type;
+ SYN hugo chan_type = [chan_1, chan_3];
+
+DCL otto is_channel_type := chan_2;
+
+x: PROC ();
+
+ IF otto IN hugo THEN
+ WRITETEXT (STDOUT, "otto IN hugo%/");
+ ELSE
+ WRITETEXT (STDOUT, "You loose%/");
+ FI;
+END x;
+
+x ();
+
+END gdb_bug;
+/*
+Compiled with:
+
+ chill -S -fgrant-only pr-315-grt.ch
+ chill -g -o pr-315 pr-315.ch
+
+Run gdb with
+
+ gdb pr-315 --readnow
+
+will result in a sigsegv in file gdbtypes.c function force_to_range_type.
+*/
diff --git a/gdb/testsuite/gdb.chill/pr-4975.exp b/gdb/testsuite/gdb.chill/pr-4975.exp
new file mode 100644
index 00000000000..cef9ef528bd
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-4975.exp
@@ -0,0 +1,67 @@
+# Copyright 1992, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile2 "pr-4975-grt"
+set srcfile2 ${srcdir}/$subdir/${testfile2}.ch
+set objfile2 ${objdir}/$subdir/${testfile2}.o
+if { [compile "${srcfile2} -g -c -o ${objfile2}"] != "" } {
+ perror "Couldn't compile ${srcfile2}"
+ return -1
+}
+
+set testfile "pr-4975"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g ${objfile2} -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ # This is needed (at least on SunOS4) to make sure the
+ # the symbol table is read.
+ runto "x"
+ # "You loose"? Why, thank you. (But I suspect "You lose" might have
+ # been what was intended).
+ gdb_test "finish" "You loose.*" "Runs and reads symbols OK"
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/pr-5016.ch b/gdb/testsuite/gdb.chill/pr-5016.ch
new file mode 100644
index 00000000000..16f49e8f5f5
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-5016.ch
@@ -0,0 +1,24 @@
+vector: MODULE
+
+SYNMODE m_index = RANGE(1:10);
+NEWMODE vector = ARRAY (m_index) INT;
+
+DCL a, b, c vector;
+
+dump: PROC( a vector LOC, c CHAR );
+ DCL i m_index := 5;
+ DO FOR i IN m_index;
+ WRITETEXT( STDOUT, "%C(%C)=%C ", c, i, a(i) );
+ OD;
+ WRITETEXT( STDOUT, "%/" );
+END dump;
+
+a := vector [ 1, -1, 2, -2, 3, -3, 4, -4, 5, -5 ];
+b := a;
+b(4) := 4;
+b(7) := 7;
+c := vector [(*): 0];
+
+dump(a,'a');
+
+END vector;
diff --git a/gdb/testsuite/gdb.chill/pr-5016.exp b/gdb/testsuite/gdb.chill/pr-5016.exp
new file mode 100644
index 00000000000..760b514ae9c
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-5016.exp
@@ -0,0 +1,62 @@
+# Copyright 1992, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "pr-5016"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ runto dump
+ # Linux thinks type is "_cint" (and so does sparc-sun-sunos4, alpha-dec-osf2.0)
+ #setup_xfail "i*86-pc-linux*-gnu" "sparc-sun-sunos4*" "alpha-dec-osf2*"
+ gdb_test "whatis i" "type = m_index" "whatis int-range"
+ gdb_test_exact "ptype m_index" "type = RANGE (1:10)" "ptype m_index"
+ gdb_test_exact "whatis a" "type = /*LOC*/ vector"
+ gdb_test "ptype a" "type = /\\*LOC\\*/ ARRAY \\(1:10\\) (INT|int)"
+ gdb_test "step" ""
+ gdb_test_exact "whatis i" "type = long" "whatis loop counter i"
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/pr-5020.ch b/gdb/testsuite/gdb.chill/pr-5020.ch
new file mode 100644
index 00000000000..6aba793d0d0
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-5020.ch
@@ -0,0 +1,19 @@
+
+PR_5020: MODULE
+ dummy_pr_5020: PROC ();
+ END;
+ NEWMODE x = STRUCT (l LONG, b BOOL);
+ NEWMODE aset = SET (aa, bb);
+
+ DCL y ARRAY ('a':'b') x;
+ DCL setarr ARRAY (aset) x;
+ DCL intarr ARRAY(10:11) x;
+ DCL boolarr ARRAY (BOOL) x;
+
+ y('a').l, setarr(aa).l, intarr(10).l, boolarr(FALSE).l := 10;
+ y('a').b, setarr(aa).b, intarr(10).b, boolarr(FALSE).b := TRUE;
+ y('b').l, setarr(bb).l, intarr(11).l, boolarr(TRUE).l := 111;
+ y('b').b, setarr(bb).b, intarr(11).b, boolarr(TRUE).b := FALSE;
+
+ dummy_pr_5020 ();
+END;
diff --git a/gdb/testsuite/gdb.chill/pr-5020.exp b/gdb/testsuite/gdb.chill/pr-5020.exp
new file mode 100644
index 00000000000..993d373ee59
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-5020.exp
@@ -0,0 +1,85 @@
+# Copyright 1992, 1994, 1995 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "pr-5020"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ # This is needed (at least on SunOS4) to make sure the
+ # the symbol table is read.
+ gdb_test "break chillvars.ch:3" ""
+ gdb_test "delete 1" ""
+
+ gdb_test "set width 0" ""
+ gdb_test "set print sevenbit-strings" ""
+ gdb_test "set print address off" ""
+
+ test_pr_5020
+}
+
+proc test_pr_5020 {} {
+ global gdb_prompt
+ runto dummy_pr_5020
+ gdb_test_exact "print y" \
+ {= [('a'): [.l: 10, .b: TRUE], ('b'): [.l: 111, .b: FALSE]]}
+ gdb_test_exact "print boolarr" \
+ {= [(FALSE): [.l: 10, .b: TRUE], (TRUE): [.l: 111, .b: FALSE]]}
+ gdb_test_exact "print intarr" \
+ {= [(10): [.l: 10, .b: TRUE], (11): [.l: 111, .b: FALSE]]}
+ gdb_test_exact "print setarr" \
+ {= [(aa): [.l: 10, .b: TRUE], (bb): [.l: 111, .b: FALSE]]}
+ gdb_test "set print pretty" ""
+ gdb_test_exact "print y" \
+{= [('a'): [
+ .l: 10,
+ .b: TRUE
+ ], ('b'): [
+ .l: 111,
+ .b: FALSE
+ ]]} "print y pretty"
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/pr-5022.ch b/gdb/testsuite/gdb.chill/pr-5022.ch
new file mode 100644
index 00000000000..aeaad4e8f17
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-5022.ch
@@ -0,0 +1,12 @@
+PR_5022: MODULE
+ dummy_pr_5022: PROC ();
+ END;
+ DCL p PTR;
+ DCL i INT;
+
+ p := NULL;
+ dummy_pr_5022 ();
+ i := 13;
+ p := ->i;
+ dummy_pr_5022 ();
+END;
diff --git a/gdb/testsuite/gdb.chill/pr-5022.exp b/gdb/testsuite/gdb.chill/pr-5022.exp
new file mode 100644
index 00000000000..43e2dc27710
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-5022.exp
@@ -0,0 +1,70 @@
+# Copyright 1992, 1994, 1995 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "pr-5022"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ # This is needed (at least on SunOS4) to make sure the
+ # the symbol table is read.
+ gdb_test "break gdbme.ch:3" ""
+ gdb_test "delete 1" ""
+
+ gdb_test "set width 0" ""
+ gdb_test "set print sevenbit-strings" ""
+
+ test_pr_5022
+}
+
+proc test_pr_5022 {} {
+ global gdb_prompt
+ runto dummy_pr_5022
+ gdb_test "p p" " = NULL" "print NULL pointer"
+ gdb_test "continue" ""
+ gdb_test "p p" {= PTR\(H'[0-9a-fA-F]+\)} "print non-NULL pointer"
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/pr-5646-grt.ch b/gdb/testsuite/gdb.chill/pr-5646-grt.ch
new file mode 100644
index 00000000000..b7a90023585
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-5646-grt.ch
@@ -0,0 +1,5 @@
+x: MODULE
+NEWMODE a_set = SET (a, b, c, d);
+NEWMODE a_ps = POWERSET a_set;
+GRANT a_ps;
+END;
diff --git a/gdb/testsuite/gdb.chill/pr-5646.ch b/gdb/testsuite/gdb.chill/pr-5646.ch
new file mode 100644
index 00000000000..8c14cb86b4f
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-5646.ch
@@ -0,0 +1,15 @@
+y: MODULE
+
+<> USE_SEIZE_FILE "pr-5646-grt.grt" <>
+SEIZE a_ps;
+
+p: PROC ();
+
+ DCL xx a_ps;
+
+ xx := [a, b];
+END p;
+
+p();
+
+END y;
diff --git a/gdb/testsuite/gdb.chill/pr-5646.exp b/gdb/testsuite/gdb.chill/pr-5646.exp
new file mode 100644
index 00000000000..3a8aad3830b
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-5646.exp
@@ -0,0 +1,64 @@
+# Copyright 1992, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile2 "pr-5646-grt"
+set srcfile2 ${srcdir}/$subdir/${testfile2}.ch
+set objfile2 ${objdir}/$subdir/${testfile2}.o
+if { [compile "${srcfile2} -g -c -o ${objfile2}"] != "" } {
+ perror "Couldn't compile ${srcfile2}"
+ return -1
+}
+
+set testfile "pr-5646"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g ${objfile2} -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ runto p
+ gdb_test "next" ""
+ gdb_test_exact "print xx" {= [a:b]}
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/pr-5984.ch b/gdb/testsuite/gdb.chill/pr-5984.ch
new file mode 100644
index 00000000000..3e74a5660ce
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-5984.ch
@@ -0,0 +1,8 @@
+x: module -- line 1
+ p:proc (t char (20) varying); -- 2
+ writetext(stdout, t); -- 3
+ end p; -- 4
+ -- 5
+ p("Jason Dark.%/"); -- 6
+ p("Hello World.%/"); -- 7
+end x;
diff --git a/gdb/testsuite/gdb.chill/pr-5984.exp b/gdb/testsuite/gdb.chill/pr-5984.exp
new file mode 100644
index 00000000000..cd45aa36a51
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-5984.exp
@@ -0,0 +1,57 @@
+# Copyright 1992, 1994, 1995 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "pr-5984"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ send_gdb "set language chill\n" ;
+
+ gdb_test "break pr-5984.ch:6" ""
+ send_gdb "run\n"; gdb_expect -re "Breakpoint .*pr-5984.ch:6"
+ gdb_expect -re "$gdb_prompt $"
+ gdb_test "next" "Jason Dark.*" "next over Jason Dark"
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/pr-6292.ch b/gdb/testsuite/gdb.chill/pr-6292.ch
new file mode 100644
index 00000000000..c2ed95361c6
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-6292.ch
@@ -0,0 +1,17 @@
+hack : module
+
+dcl i int;
+
+fred : proc (a int in, b int loc);
+ writetext(stdout, "a was '%C'; b was '%C'.%/", a, b);
+ b + := 1;
+end fred;
+
+klaus : proc ();
+ writetext(stdout, "here's klaus calling.%/");
+end klaus;
+
+i:=12;
+writetext(stdout, "done.%/");
+
+end hack;
diff --git a/gdb/testsuite/gdb.chill/pr-6292.exp b/gdb/testsuite/gdb.chill/pr-6292.exp
new file mode 100644
index 00000000000..d57f4819046
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-6292.exp
@@ -0,0 +1,58 @@
+# Copyright 1995 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "pr-6292"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ send_gdb "set language chill\n" ;
+
+ gdb_test "break pr-6292.ch:15" ""
+ send_gdb "run\n"; gdb_expect -re "Breakpoint .*pr-6292.ch:15.*$gdb_prompt $"
+ gdb_test_exact "call klaus()" {here's klaus calling.}
+ gdb_test {set fred(10, i)} {a was '10'; b was '12'.}
+ gdb_test "print i" { = 13} "print i after call"
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/pr-6632-grt.ch b/gdb/testsuite/gdb.chill/pr-6632-grt.ch
new file mode 100644
index 00000000000..e9434f1bb48
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-6632-grt.ch
@@ -0,0 +1,34 @@
+markus1: MODULE
+
+SYNMODE m_dummy = SET (dummy_1,
+ dummy_2,
+ dummy_3,
+ dummy_4,
+ dummy_5,
+ dummy_6,
+ dummy_7,
+ dummy_8,
+ dummy_9,
+ dummy_10,
+ dummy_11,
+ dummy_12,
+ dummy_13,
+ dummy_14,
+ dummy_15,
+ dummy_16,
+ dummy_17,
+ dummy_18,
+ dummy_19,
+ dummy_20,
+ dummy_21,
+ dummy_22,
+ dummy_23,
+ dummy_24,
+ dummy_25,
+ dummy_26);
+
+SYNMODE m_dummy_range = m_dummy(dummy_6 : dummy_22);
+
+GRANT m_dummy, m_dummy_range;
+
+END markus1;
diff --git a/gdb/testsuite/gdb.chill/pr-6632.ch b/gdb/testsuite/gdb.chill/pr-6632.ch
new file mode 100644
index 00000000000..b82c7ae1c88
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-6632.ch
@@ -0,0 +1,31 @@
+markus: MODULE
+
+<> USE_SEIZE_FILE "pr-6632-grt.grt" <>
+SEIZE m_dummy, m_dummy_range;
+
+DCL v m_dummy_range;
+
+NEWMODE is_str_descr = STRUCT (p PTR,
+ l INT,
+ flag STRUCT (x UBYTE,
+ y SET (aa, bb, cc, dd, ee, ff)));
+DCL des is_str_descr;
+
+NEWMODE is_cb_debug = STRUCT (i INT,
+ channel m_dummy_range,
+ p PTR);
+NEWMODE is_cb_debug_array = ARRAY (0:20) is_cb_debug;
+DCL cb_debug is_cb_debug_array;
+DCL cb_debug_index INT := 0;
+
+p: PROC (pp is_str_descr IN, x m_dummy_range IN)
+ DO WITH cb_debug(cb_debug_index);
+ channel := x;
+ OD;
+END p;
+
+p (des, dummy_10);
+WRITETEXT (stdout, "cb_debug(%C).channel := %C%/",
+ cb_debug_index, cb_debug(cb_debug_index).channel);
+
+END markus;
diff --git a/gdb/testsuite/gdb.chill/pr-6632.exp b/gdb/testsuite/gdb.chill/pr-6632.exp
new file mode 100644
index 00000000000..1bec3c7041c
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-6632.exp
@@ -0,0 +1,66 @@
+# Copyright 1995 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+
+if [skip_chill_tests] then { continue }
+
+set testfile2 "pr-6632-grt"
+set srcfile2 ${srcdir}/$subdir/${testfile2}.ch
+set objfile2 ${objdir}/$subdir/${testfile2}.o
+if { [compile "${srcfile2} -g -c -o ${objfile2}"] != "" } {
+ perror "Couldn't compile ${srcfile2}"
+ return -1
+}
+
+set testfile "pr-6632"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} ${objfile2} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ runto p
+ gdb_test "whatis x" {type = m_dummy_range}
+ gdb_test_exact "ptype x" {type = m_dummy (dummy_6:dummy_22)}
+ gdb_test "print x" { = dummy_10}
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/pr-8134.exp b/gdb/testsuite/gdb.chill/pr-8134.exp
new file mode 100644
index 00000000000..0e81ca770e4
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-8134.exp
@@ -0,0 +1,65 @@
+# Copyright 1995, 1996 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+# Note we use pr-8136.ch for pr-8134.exp as well as pr-8136.exp.
+set testfile2 "func1"
+set srcfile2 ${srcdir}/$subdir/${testfile2}.ch
+set objfile2 ${objdir}/$subdir/${testfile2}.o
+if { [compile "${srcfile2} -g -c -o ${objfile2}"] != "" } {
+ perror "Couldn't compile ${srcfile2}"
+ return -1
+}
+
+set testfile "pr-8134"
+set srcfile ${srcdir}/$subdir/pr-8136.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g ${objfile2} -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ runto p1
+ gdb_test "print first" "= 1"
+ gdb_test "print last" "= 10"
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/pr-8136.ch b/gdb/testsuite/gdb.chill/pr-8136.ch
new file mode 100644
index 00000000000..b380110eb18
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-8136.ch
@@ -0,0 +1,34 @@
+-- NOTE: This test is used for pr-3134.exp as well as pr-8136.
+func: MODULE
+
+<> USE_SEIZE_FILE "func1.grt" <>
+SEIZE ALL;
+
+NEWMODE m_struct = STRUCT (i LONG, str CHARS(50) VARYING);
+DCL insarr ARRAY (1:10) INT;
+
+DCL setrange m_setrange := e5;
+
+DCL ps m_ps := [ e3, e7:e9 ];
+DCL range_ps m_rangeps := [ 2, 3, 4, 28 ];
+
+p1: PROC (first INT IN, last INT IN, s m_struct IN);
+
+ DCL foo LONG := 3;
+
+ startall: PROC ()
+ DO FOR i := first to last;
+ insarr(i) := i;
+ OD;
+ DO FOR i := first TO last;
+ WRITETEXT (stdout, "insarr(%C) := %C%/", i, insarr(i));
+ OD;
+ END startall;
+
+ startall ();
+
+END p1;
+
+p1 (LOWER (insarr), UPPER (insarr), [ 10, "This is a string." ]);
+
+END func;
diff --git a/gdb/testsuite/gdb.chill/pr-8136.exp b/gdb/testsuite/gdb.chill/pr-8136.exp
new file mode 100644
index 00000000000..3fee7ec3c79
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-8136.exp
@@ -0,0 +1,63 @@
+# Copyright 1995 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile2 "func1"
+set srcfile2 ${srcdir}/$subdir/${testfile2}.ch
+set objfile2 ${objdir}/$subdir/${testfile2}.o
+if { [compile "${srcfile2} -g -c -o ${objfile2}"] != "" } {
+ perror "Couldn't compile ${srcfile2}"
+ return -1
+}
+
+set testfile "pr-8136"
+set srcfile ${srcdir}/$subdir/pr-8136.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g ${objfile2} -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ runto p1
+ gdb_test "print ps" {= \[e3, e7:e9\]}
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/pr-8405.ch b/gdb/testsuite/gdb.chill/pr-8405.ch
new file mode 100644
index 00000000000..a9b25312d6e
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-8405.ch
@@ -0,0 +1,19 @@
+emptybit: MODULE
+
+SYNMODE b8 = BOOLS(8);
+SYN bit8 b8 = B'00000000';
+
+SYNMODE char_m = CHARS(40) VARYING;
+
+SYNMODE stru_m = STRUCT (c char_m, b b8, boo BOOL);
+DCL xx stru_m;
+
+SYNMODE m_stru = STRUCT (c char_m, i LONG, boo BOOL);
+DCL yy m_stru;
+
+SYNMODE m_arr = ARRAY (1:10) LONG;
+DCL zz m_arr;
+
+WRITETEXT (stdout, "%C%/", bit8);
+
+END emptybit;
diff --git a/gdb/testsuite/gdb.chill/pr-8405.exp b/gdb/testsuite/gdb.chill/pr-8405.exp
new file mode 100644
index 00000000000..826ac6b6e4b
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-8405.exp
@@ -0,0 +1,61 @@
+# Copyright 1995, 1996 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+ gdb_test "set var \$i:=xx" ""
+ gdb_test "print \$i" {= \[.c: "", .b: B'00000000', .boo: FALSE\]}
+}
+
+if [skip_chill_tests] then { continue }
+
+# Check to see if we have an executable to test. If not, then either we
+# haven't tried to compile one, or the compilation failed for some reason.
+# In either case, just notify the user and skip the tests in this file.
+
+set testfile "pr-8405"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -w -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+if ![file exists $binfile] then {
+ warning "$binfile does not exist; tests suppressed." 0
+} else {
+ do_tests
+}
diff --git a/gdb/testsuite/gdb.chill/pr-8742.ch b/gdb/testsuite/gdb.chill/pr-8742.ch
new file mode 100644
index 00000000000..0541149978e
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-8742.ch
@@ -0,0 +1,32 @@
+hugo : module
+
+ synmode a = range(1:10);
+ synmode p = powerset a;
+
+ synmode s = set (sa, sb, sc);
+ synmode s_ps = powerset s;
+
+ x: proc (ps p);
+ dcl i a;
+ do for i in ps;
+ writetext (stdout, "%C ", i);
+ od;
+ writetext(stdout, "%/");
+ end x;
+
+ y : proc (ps s_ps);
+ dcl i s;
+ do for i in ps;
+ writetext (stdout, "%C ", i);
+ od;
+ writetext(stdout, "%/");
+ end y;
+
+ dummy: proc ();
+ end dummy;
+
+ x([1,2,3]);
+ y([sa, sc]);
+ dummy ();
+
+end hugo;
diff --git a/gdb/testsuite/gdb.chill/pr-8742.exp b/gdb/testsuite/gdb.chill/pr-8742.exp
new file mode 100644
index 00000000000..7fc05be4bdd
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-8742.exp
@@ -0,0 +1,64 @@
+# Copyright 1992, 1996 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "pr-8742"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ runto dummy
+
+ # Haven't investigated why these fail on mips-sgi-irix*
+ setup_xfail "m68*-*-hpux*" "mips*-sgi-irix*"
+ gdb_test {call x(p [1, 3, 5])} "1 3 5 " "pass int powerset tuple"
+ setup_xfail "mips*-sgi-irix*"
+ gdb_test {call y(s_ps [sc])} "sc " "pass set powerset tuple"
+ setup_xfail "m68*-*-hpux*" "mips*-sgi-irix*"
+ gdb_test {call x([1, 3, 5])} "1 3 5 " "pass modeless int powerset tuple"
+ setup_xfail "mips*-sgi-irix*"
+ gdb_test {call y([sc])} "sc " "pass modeless set powerset tuple"
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/pr-8894-grt.ch b/gdb/testsuite/gdb.chill/pr-8894-grt.ch
new file mode 100644
index 00000000000..572017053d0
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-8894-grt.ch
@@ -0,0 +1,6 @@
+yy: MODULE
+
+SYNMODE m_byte = INT (0:255);
+GRANT ALL;
+
+END yy;
diff --git a/gdb/testsuite/gdb.chill/pr-8894.ch b/gdb/testsuite/gdb.chill/pr-8894.ch
new file mode 100644
index 00000000000..391d56b2fc0
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-8894.ch
@@ -0,0 +1,12 @@
+xx: MODULE
+
+<> USE_SEIZE_FILE "pr-8894-grt.grt" <>
+SEIZE m_byte;
+
+SYNMODE m_struct = STRUCT (a, b, c m_byte);
+
+DCL v m_struct;
+
+v.a := 100;
+
+END xx;
diff --git a/gdb/testsuite/gdb.chill/pr-8894.exp b/gdb/testsuite/gdb.chill/pr-8894.exp
new file mode 100644
index 00000000000..777570aa255
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-8894.exp
@@ -0,0 +1,61 @@
+# Copyright 1996 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile2 "pr-8894-grt"
+set srcfile2 ${srcdir}/$subdir/${testfile2}.ch
+set objfile2 ${objdir}/$subdir/${testfile2}.o
+if { [compile "${srcfile2} -g -c -o ${objfile2}"] != "" } {
+ perror "Couldn't compile ${srcfile2}"
+ return -1
+}
+
+set testfile "pr-8894"
+set srcfile ${srcdir}/$subdir/$testfile.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g ${objfile2} -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ gdb_test "print size(m_byte)" { = 2}
+ gdb_test "print size(m_struct)" { = 6}
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/pr-9095.ch b/gdb/testsuite/gdb.chill/pr-9095.ch
new file mode 100644
index 00000000000..61ffb700fbe
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-9095.ch
@@ -0,0 +1,13 @@
+gdb1: MODULE
+
+SYNMODE m_arr1 = ARRAY (1:10) UBYTE;
+SYNMODE m_struct = STRUCT ( i LONG,
+ p REF m_arr1);
+SYNMODE m_arr2 = ARRAY (0:10) REF m_struct;
+
+DCL v_arr1 m_arr1 INIT := [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
+DCL v_struct m_struct INIT := [ 10, ->v_arr1 ];
+DCL v_arr2 m_arr2 INIT := [ (5): ->v_struct, (ELSE): NULL ];
+
+WRITETEXT (stdout, "v_arr2(5)->.p->(5) = %C%/", v_arr2(5)->.p->(5));
+END gdb1;
diff --git a/gdb/testsuite/gdb.chill/pr-9095.exp b/gdb/testsuite/gdb.chill/pr-9095.exp
new file mode 100644
index 00000000000..d5c72b62686
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-9095.exp
@@ -0,0 +1,62 @@
+# Copyright 1996 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+ runto pr-9095.ch:12
+ gdb_test {p v_arr2(5)->.p(5)} "reference value used as function" \
+ "bad call using pointer"
+}
+
+if [skip_chill_tests] then { continue }
+
+# Check to see if we have an executable to test. If not, then either we
+# haven't tried to compile one, or the compilation failed for some reason.
+# In either case, just notify the user and skip the tests in this file.
+
+set testfile "pr-9095"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -w -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+if ![file exists $binfile] then {
+ warning "$binfile does not exist; tests suppressed." 0
+} else {
+ do_tests
+}
diff --git a/gdb/testsuite/gdb.chill/pr-9946.ch b/gdb/testsuite/gdb.chill/pr-9946.ch
new file mode 100644
index 00000000000..3d9210a5b8d
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-9946.ch
@@ -0,0 +1,10 @@
+x: module
+
+synmode aset = SET (stopped, moving);
+
+DCL xyz aset;
+
+xyz := moving;
+xyz := SUCC (xyz);
+
+END x;
diff --git a/gdb/testsuite/gdb.chill/pr-9946.exp b/gdb/testsuite/gdb.chill/pr-9946.exp
new file mode 100644
index 00000000000..7e8b7184a92
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/pr-9946.exp
@@ -0,0 +1,79 @@
+# Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+# Martin Pottendorfer (pottendo@aut.alcatel.at)
+#
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "pr-9946"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to chill. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_chill {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+
+ send_gdb "set language chill\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language chill (timeout)" ; return 0 }
+ }
+
+ return [gdb_test "show language" ".* source language is \"chill\".*" \
+ "set language to \"chill\""]
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+if ![set_lang_chill] then {
+ runto x_
+ gdb_test "next" ""
+ # check comparison of SET's
+ gdb_test {print xyz=moving} { = TRUE}
+ gdb_test {print xyz/=moving} { = FALSE}
+ gdb_test {print xyz<moving} { = FALSE}
+ gdb_test {print xyz<=moving} { = TRUE}
+ gdb_test {print xyz>moving} { = FALSE}
+ gdb_test {print xyz>=moving} { = TRUE}
+}
diff --git a/gdb/testsuite/gdb.chill/result.ch b/gdb/testsuite/gdb.chill/result.ch
new file mode 100644
index 00000000000..b8c65e7d085
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/result.ch
@@ -0,0 +1,29 @@
+test_result: MODULE
+
+ DCL i INT := 5;
+
+ SYNMODE m_struct = STRUCT (l LONG, b BOOL);
+ DCL v_struct m_struct := [ 20, TRUE ];
+
+ simple_func: PROC () RETURNS (INT);
+ DCL j INT := i;
+ RESULT 10;
+ i + := 2;
+ RESULT j + 2;
+ i + := 2;
+ END simple_func;
+
+ ret_struct: PROC () RETURNS (m_struct)
+ DCL v m_struct := [ 33, FALSE ];
+ RESULT v;
+ v.l := 18;
+ END ret_struct;
+
+ i := simple_func ();
+ i := simple_func ();
+ i * := 10;
+
+ v_struct := ret_struct ();
+
+ i := 33; -- for gdb
+END test_result;
diff --git a/gdb/testsuite/gdb.chill/result.exp b/gdb/testsuite/gdb.chill/result.exp
new file mode 100644
index 00000000000..e9dce152b8d
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/result.exp
@@ -0,0 +1,77 @@
+# Copyright 1994, 1995 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "result"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ gdb_test "set width 0" ""
+ gdb_test "set print sevenbit-strings" ""
+ gdb_test "set print address off" ""
+
+ # simple function
+ runto simple_func
+ gdb_test "step 2" ""
+ gdb_test "print j" "= 5"
+ gdb_test "p RESULT" "= 10"
+ gdb_test "continue" ""
+ gdb_test "print i" "= 7"
+ gdb_test "step 4" ""
+ gdb_test "set RESULT := 50" ""
+ gdb_test "finish" ""
+ gdb_test "step" ""
+ gdb_test "print i" "= 50"
+
+ # returning a structure
+ runto ret_struct
+ gdb_test "step 2" ""
+ gdb_test "p result" {\[.l: 33, .b: FALSE\]}
+ gdb_test "set var result := \[383, TRUE\]" ""
+ gdb_test "finish" ""
+ gdb_test "p v_struct" {\[.l: 383, .b: TRUE\]}
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/string.ch b/gdb/testsuite/gdb.chill/string.ch
new file mode 100644
index 00000000000..3503c462eae
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/string.ch
@@ -0,0 +1,24 @@
+ss: MODULE
+
+/* These declarations are from Cygnus PR chill/9078. */
+ SYNMODE m_char20 = CHARS(20) VARYING;
+
+ DCL foo m_char20 INIT := "Moser ";
+ DCL bar m_char20 INIT := "Wilfried";
+
+ DCL foo1 CHARS(5) INIT := "12345";
+ DCL bar1 CHARS(5) INIT := "abcde";
+
+/* This is Cynus PR chill/5696. */
+
+DCL s20 CHARS(20) VARYING;
+
+DCL s10 CHARS(10);
+
+
+s20 := "Moser Wilfried";
+S10 := "1234567890";
+
+WRITETEXT (stdout, "s20 := ""%C"", s10 := ""%C""%/", s20, s10);
+
+END ss;
diff --git a/gdb/testsuite/gdb.chill/string.exp b/gdb/testsuite/gdb.chill/string.exp
new file mode 100644
index 00000000000..acaea8ff181
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/string.exp
@@ -0,0 +1,73 @@
+# Copyright 1995, 1996 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "string"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ # These tests based on Cygnus PR chill/5696.
+ runto string.ch:22
+ gdb_test "p s20" { = "Moser Wilfried"} "print simple vstring"
+ gdb_test "p s20(1)" { = 'o'} "print vstring element"
+ gdb_test "p s20(1:3)" { = "ose"} "print vstring slice (:)"
+ gdb_test "p s20(2 up 3)" { = "ser"} "print vstring slice (up)"
+ gdb_test "p s10" { = "1234567890"} "print simple string"
+ gdb_test "p s10(1)" { = '2'} "print string element"
+ gdb_test "p s10(1:3)" { = "234"} "print string slice (:)"
+ gdb_test "p s10(2 up 3)" { = "345"} "print string slice (up)"
+
+ gdb_test "p length(s10)" { = 10} "print string length"
+ gdb_test "p length(s20)" { = 14} "print varying string length"
+ gdb_test "p lower(s10)" { = 0} "print string lower"
+ gdb_test "p upper(s10)" { = 9} "print string upper"
+ gdb_test "p lower(s20)" { = 0} "print varying string lower"
+ gdb_test "p upper(s20)" { = 19} "print varying string upper"
+
+ # These tests are based on Cygnus PR chill/9078.
+ gdb_test "print foo // bar" { = "Moser Wilfried"}
+ gdb_test "print foo // bar1" { = "Moser abcde"}
+ gdb_test "print foo1 // bar1" { = "12345abcde"}
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/tests1.ch b/gdb/testsuite/gdb.chill/tests1.ch
new file mode 100644
index 00000000000..3afdd90a50e
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/tests1.ch
@@ -0,0 +1,240 @@
+-- Copyright 1992, 1995, 1996 Free Software Foundation, Inc.
+
+-- 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.
+
+-- Please email any bugs, comments, and/or additions to this file to:
+-- bug-gdb@prep.ai.mit.edu
+
+--
+-- test program 1 (refer to tests1.exp)
+--
+
+/* These functions are defined in libchill.a */
+
+runtime: SPEC MODULE
+DCL chill_argc long;
+DCL chill_argv REF ARRAY (0:1000) REF CHARS (1000) VARYING;
+__print_event: PROC (arg0 ptr,
+ arg1 ptr) END;
+__print_buffer: PROC (arg0 ptr,
+ arg1 ptr) END;
+GRANT ALL;
+END;
+
+tests1: module;
+
+seize __print_event,
+ __print_buffer;
+
+newmode set1 = set(aaa, bbb, ccc);
+newmode nset1 = set(na = 1, nb = 34, nc = 20);
+newmode r11 = range (0 : upper(ubyte));
+newmode r12 = range (0 : upper(uint));
+--newmode r13 = range (0 : upper(ulong)); -- bug in gnuchill
+newmode r14 = range (lower(byte) : upper(byte));
+newmode r15 = range (lower(int) : upper(int));
+newmode r16 = range (lower(long): upper(long));
+newmode r2 = set1(bbb : ccc);
+newmode r3 = nset1(na : na);
+newmode r4 = nset1(nc : nb);
+newmode r5 = nset1(lower(nset1) : upper(nset1));
+
+newmode pm1 = powerset set(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
+newmode pm2 = powerset byte (1:8);
+newmode pm3 = powerset int (-32768:32767);
+newmode pm4 = powerset long (-32768:32768);
+newmode pm5 = powerset long (lower(long):upper(long));
+newmode ref1 = ref pm1;
+newmode ref2 = ref byte;
+newmode ref3 = ptr;
+synmode ref4 = ptr;
+synmode syn_int = int;
+
+newmode prm1 = proc ();
+newmode prm2 = proc (bool in, int out, long inout) returns (char);
+newmode prm3 = proc (pm1, ref1 loc) returns (ref3);
+newmode prm4 = proc () exceptions(ex1, ex2, ex3);
+newmode prm5 = proc (r11, r16 inout, r5 out) returns (r2) exceptions (ex1);
+
+newmode ev1m = event;
+newmode ev2m = event (42);
+
+newmode bu1m = buffer ref1;
+newmode bu2m = buffer (42) ubyte;
+
+newmode strm1 = char (5);
+synmode strm2 = char (7) varying;
+
+synmode bstr1 = bit(20);
+--newmode bstr2 = bit(10) varying;
+
+newmode arr1m = array(1:100) set1;
+newmode arr2m = array(1:100, 1:100) set1;
+newmode arr3m = array(r11, r12, r14) set1;
+newmode arr4m = array(r2) array (r3) array (r4, r5) pm1;
+newmode arr5m = array(1:10) int;
+newmode arr6m = array(1:5, 1:3, 1:2) long;
+
+newmode stru1m = struct (a, b long,
+ case b of
+ (42): ch1 chars(20),
+ (52): ch2 chars(10)
+ else ch3 chars(1)
+ esac);
+
+newmode stru2m = struct (f set1,
+ case f of
+ (aaa): ch1 char(20),
+ (bbb): ch2 char(10) varying
+ else ch3 char(0) varying
+ esac);
+newmode stru3m = struct (f r3,
+ case f of
+ (na): ch1 char(20)
+ esac);
+newmode stru4m = struct (i long,
+ case of
+ : i1, i11 int,
+ b1 bool,
+ c1 char,
+ : i2, i22 long,
+ bs2 bools (10),
+ :
+ s3 struct (i3 int,
+ case of
+ : foo long
+ else bar char
+ esac)
+ else
+ x stru2m
+ esac,
+ y stru3m);
+
+synmode m_xyzmode = struct (next ref m_xyzmode,
+ i long);
+
+-- set mode locations
+dcl s1l set1 := ccc;
+dcl s2l nset1 := nb;
+
+-- range mode locations
+dcl rl1 r11 := 3;
+dcl rl2 r11 := lower(r11);
+dcl rl3 r11 := upper(r11);
+
+dcl rl5 r12 := 65530;
+dcl rl6 r12 := lower(r12);
+dcl rl7 r12 := upper(r12);
+
+--dcl rl9 r13 := 128;
+--dcl rl10 r13 := lower(r13);
+--dcl rl11 r13 := upper(r13);
+
+dcl rl13 r14 := -121;
+dcl rl14 r14 := lower(r14);
+dcl rl15 r14 := upper(r14);
+
+dcl rl17 r15 := -32720;
+dcl rl18 r15 := lower(r15);
+dcl rl19 r15 := upper(r15);
+
+dcl rl21 r16 := 2147483643;
+dcl rl22 r16 := lower(r16);
+dcl rl23 r16 := upper(r16);
+
+-- powerset mode locations
+dcl pl1 pm1 := [p1:p10];
+dcl pl2 pm1 := [];
+dcl pl3 pm1 := [p1, p10];
+dcl pl4 pm1 := [p1:p2, p4:p6, p8:p10];
+dcl pl5 pm1 := [p1:p4, p6, p8:p10];
+dcl pl6 pm1 := [p1, p3:p8, p10];
+
+dcl pl7 pm2 := [1:8];
+dcl pl8 pm3 := [-32768:32767];
+--dcl pl9 pm5 := [-2147483648:2147483647];
+
+-- reference mode locations
+dcl ref3l ref3;
+dcl ref4l ref4;
+dcl ref5l, ref6l, ref7l, ref8l ptr;
+dcl syn_intl1 syn_int := 42;
+dcl intl1 int := -42;
+
+-- synchronization mode locations
+dcl ev1l ev1m;
+dcl ev2l ev2m;
+dcl bu1l bu1m;
+dcl bu2l bu2m;
+
+-- timing mode locations
+dcl til1 time;
+
+-- string mode locations
+dcl strl1, strl2 strm2;
+dcl bstrl1 bstr1 := B'10101010101010101010';
+
+-- array mode locations
+dcl arrl1 arr1m;
+dcl arrl2 arr5m := [1, -1, 32767, -32768, 0, 10, 11, 12, 13, 42];
+dcl arrl3 arr6m := [(1:5): [(1:3): [(1:2): -2147483648]]];
+dcl arrl4 arr6m := [(1:2): [(1:3): [(1:2): -2147483648]],
+ (3): [(1:3): [(1:2): 100]],
+ (4:5): [(1:3): [(1:2): -2147483648]]];
+dcl arrl5 array(1:10) nset1;
+
+-- structure mode locations
+dcl strul1 stru1m := [-2147483648, 42, "12345678900987654321"];
+
+dummyfunc: proc();
+end dummyfunc;
+
+ref3l:=->pl1; -- newmode ref
+ref4l:=->pl1; -- synmode ref
+ref5l:=->pl1; -- ptr
+
+ref6l:=->syn_intl1; -- ref to synmode
+ref7l:=->intl1; -- ref to predefined mode
+ref8l:=->pl1; -- ref to newmode
+
+strl1 := "ha" // C'6e' // "s" // "i" // C'00';
+strl2 := C'00' // "ope";
+
+__print_event(addr(ev1l), addr("ev1l"));
+__print_event(addr(ev2l), addr("ev2l"));
+__print_buffer(addr(bu1l), addr("bu1m"));
+__print_buffer(addr(bu2l), addr("bu2m"));
+
+til1 := abstime(1970, 3, 12, 10, 43, 0);
+writetext(stdout, "lower(pm3) = %C; upper(pm3) = %C%..%/",
+ lower(pm3), upper(pm3));
+writetext(stdout, "lower(pm5) = %C; upper(pm5) = %C%..%/",
+ lower(pm5), upper(pm5));
+--writetext(stdout, "lower(pl9) = %C; upper(pl9) = %C%..%/",
+-- lower(pl9), upper(pl9));
+writetext(stdout, "date = %C%..%/", til1);
+
+writetext(stdout, "slice1 = %C%..%/", strl1(3 : 5));
+writetext(stdout, "slice2 = %C%..%/", strl2(0 : 3));
+--writetext(stdout, "slice3 = %C%..%/", strl1(0 up 20));
+writetext(stdout, "slice4 = %C%..%/", bstrl1(0));
+--writetext(stdout, "slice5 = %C%..%/", arrl3(1:5));
+
+
+writetext(stdout, "done.%/");
+
+dummyfunc();
+
+end tests1;
diff --git a/gdb/testsuite/gdb.chill/tests1.exp b/gdb/testsuite/gdb.chill/tests1.exp
new file mode 100644
index 00000000000..7aa882507f3
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/tests1.exp
@@ -0,0 +1,822 @@
+# Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file tests various Chill values, expressions, and types.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "tests1"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -w -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to chill. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_chill {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+ send_gdb "set language chill\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language chill (timeout)" ; return 0 }
+ }
+
+ send_gdb "show language\n"
+ gdb_expect {
+ -re ".* source language is \"chill\".*$gdb_prompt $" {
+ pass "set language to \"chill\""
+ send_gdb "break dummyfunc\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {
+ send_gdb "run\n"
+ gdb_expect -re ".*$gdb_prompt $" {}
+ return 1
+ }
+ timeout {
+ fail "can't set breakpoint (timeout)"
+ return 0
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "setting language to \"chill\""
+ return 0
+ }
+ timeout {
+ fail "can't show language (timeout)"
+ return 0
+ }
+ }
+}
+
+# Testing printing of a specific value. Increment passcount for
+# success or issue fail message for failure. In both cases, return
+# a 1 to indicate that more tests can proceed. However a timeout
+# is a serious error, generates a special fail message, and causes
+# a 0 to be returned to indicate that more tests are likely to fail
+# as well.
+#
+# Args are:
+#
+# First one is string to send_gdb to gdb
+# Second one is string to match gdb result to
+# Third one is an optional message to be printed
+
+proc test_print_accept { args } {
+ global gdb_prompt
+ global passcount
+ global verbose
+
+ if [llength $args]==3 then {
+ set message [lindex $args 2]
+ } else {
+ set message [lindex $args 0]
+ }
+ set sendthis [lindex $args 0]
+ set expectthis [lindex $args 1]
+ set result [gdb_test $sendthis ".* = ${expectthis}" $message]
+ if $result==0 {incr passcount}
+ return $result
+}
+
+# Testing printing of a specific value. Increment passcount for
+# success or issue fail message for failure. In both cases, return
+# a 1 to indicate that more tests can proceed. However a timeout
+# is a serious error, generates a special fail message, and causes
+# a 0 to be returned to indicate that more tests are likely to fail
+# as well.
+
+# various tests if modes are treated correctly
+# using ptype
+proc test_modes {} {
+ global passcount
+
+ verbose "testing chill modes"
+ set passcount 0
+
+ # discrete modes
+ test_print_accept "ptype BYTE" "byte"
+ test_print_accept "ptype UBYTE" "ubyte"
+ test_print_accept "ptype INT" "int"
+ test_print_accept "ptype UINT" "uint"
+ test_print_accept "ptype LONG" "long"
+ test_print_accept "ptype ULONG" "ulong"
+ test_print_accept "ptype BOOL" "bool"
+ test_print_accept "ptype CHAR" "char"
+
+ test_print_accept "ptype set1" "SET \[(\]aaa, bbb, ccc\[)\]" \
+ "print unnumbered set mode"
+ test_print_accept "ptype nset1" "SET \[(\]na = 1, nb = 34, nc = 20\[)\]" \
+ "print numbered set mode"
+
+ # mp:
+ # display maybe in hex values ?
+ #
+ test_print_accept "ptype r11" "ubyte \\(0:255\\)" \
+ "print ubyte range mode"
+ test_print_accept "ptype r12" "uint \\(0:65535\\)" \
+ "print uint range mode"
+# test_print_accept "ptype r13" "ulong \\(0:4294967295\\)" \
+# "print ulong range mode"
+ test_print_accept "ptype r14" "byte \\(-128:127\\)" \
+ "print byte range mode"
+ test_print_accept "ptype r15" "int \\(-32768:32767\\)" \
+ "print int range mode"
+ test_print_accept "ptype r16" "long \\(-2147483648:2147483647\\)" \
+ "print long range mode"
+
+ test_print_accept "ptype r2" "set1 \\(bbb:ccc\\)" \
+ "print unnumbered set range mode"
+ test_print_accept "ptype r3" "nset1 \\(na:na\\)" \
+ "print numbered set range mode"
+ # really this order ?
+ # I'm not sure what should happen for the next two tests.
+ setup_xfail "*-*-*"
+ test_print_accept "ptype r4" "nset1 \\(nb = 34:nc = 20\\)" \
+ "print numbered set range mode"
+ setup_xfail "*-*-*"
+ test_print_accept "ptype r5" "nset1 \\(na = 1, nb = 34, nc = 20\\)" \
+ "print numbered set range mode"
+
+ # powerset modes
+ test_print_accept "ptype pm1" \
+ "POWERSET SET \[(\]p1, p2, p3, p4, p5, p6, p7, p8, p9, p10\[)\]" \
+ "print powerset mode 1"
+ test_print_accept "ptype pm2" "POWERSET byte \\(1:8\\)" \
+ "print powerset mode 2"
+ test_print_accept "ptype pm3" "POWERSET int \\(-32768:32767\\)" \
+ "print powerset mode 3"
+ test_print_accept "ptype pm4" "POWERSET long \\(-32768:32768\\)" \
+ "print powerset mode 4"
+ test_print_accept "ptype pm5" \
+ "POWERSET long \\(-2147483648:2147483647\\)" \
+ "print powerset mode 5"
+
+ # reference modes
+ test_print_accept "ptype ref1" "REF pm1" \
+ "print reference to powerset mode"
+ test_print_accept "ptype ref2" "REF byte" \
+ "print reference to byte"
+ test_print_accept "ptype ref3" "PTR" \
+ "print free reference type"
+
+ # procedure modes
+ # FIXME: we have to talk about this ...
+ test_print_accept "ptype prm1" \
+ "REF PROC \[(\]\[)\]" \
+ "print procedure mode 1"
+ setup_xfail "*-*-*"
+ test_print_accept "ptype prm2" \
+ "REF PROC \[(\]bool in, int out long inout\[)\] RETURNS \[(\]char\[)\]" \
+ "print procedure mode 2"
+ setup_xfail "*-*-*"
+ test_print_accept "ptype prm3" \
+ "REF PROC \[(\]pm1, ref loc\[)\] RETURNS \[(\]ref3\[)\]" \
+ "print procedure mode 3"
+ setup_xfail "*-*-*"
+ test_print_accept "ptype prm4" \
+ "\[(\] \[)\] EXCEPTIONS \[(\]ex1, ex2, ex3\[)\]" \
+ "print procedure mode 4"
+ setup_xfail "*-*-*"
+ test_print_accept "ptype prm5" \
+ "REF PROC \[(\]r11, r16 inout, r5 out\[)\] RETURNS \[(\]r2\[)\] EXCEPTIONS \[(\]ex1\[)\]" \
+ "print procedure mode 5"
+
+ # synchronization modes
+ # FIXME: since gdb doesn't process events & buffers so far, this has be
+ # filled later...
+ xfail "synchronization mode handling"
+
+ # timing modes
+ test_print_accept "ptype DURATION" "duration"
+ test_print_accept "ptype TIME" "time"
+
+ # string modes
+ # some tests are done in chillvars.exp
+ test_print_accept "ptype strm1" "CHARS \\(5\\)" "print char string mode"
+ test_print_accept "ptype strm2" "CHARS \[(\]7\[)\] VARYING" \
+ "print varying char string mode"
+ test_print_accept "ptype bstr1" "BOOLS \\(20\\)" "print bit string mode"
+
+ test_print_accept "ptype B'000'" "BOOLS \\(3\\)" "bit string literal"
+ test_print_accept "ptype B'11110000'" "BOOLS \\(8\\)" "bit string literal"
+ # FIXME: adjust error message
+ gdb_test "ptype B'00110211'" {.*Too-large digit.*[.]} \
+ "reject invalid bitstring"
+
+ # array modes
+ # some tests are done in chillvars.exp
+ test_print_accept "ptype arr1m" "ARRAY \\(1:100\\) set1" \
+ "print array mode 1"
+ test_print_accept "ptype arr2m" "ARRAY \\(1:100\\) ARRAY \\(1:100\\) set1"\
+ "print array mode 2"
+ test_print_accept "ptype arr3m" "ARRAY \\(0:255\\) ARRAY \\(0:65535\\) ARRAY \\(-128:127\\) set1" \
+ "print array mode 3"
+ setup_xfail "*-*-*"
+ test_print_accept "ptype arr4m" "ARRAY \\(b:c\\) ARRAY \\(na = 1:na = 1\\) ARRAY \\(nc:nb\\) ARRAY \\(na = 1:nc = 20\\) POWERSET SET \[(\]p1, p2, p3, p4, p5, p6, p7, p8, p9, p10\[)\]" \
+ "print array mode 4"
+
+ # structure modes
+ # some checks are in chillvars.exp
+ # setup_xfail "*-*-*"
+ test_print_accept "ptype stru1m" "STRUCT \\(.*a long,.*b long,.*CASE OF.*:.*ch1 CHARS \\(20\\).*:.*ch2 CHARS \\(10\\).*ELSE.*ch3 CHARS \\(1\\).*ESAC.*\\)" \
+ "print structure mode 1"
+ #setup_xfail "*-*-*"
+ test_print_accept "ptype stru2m" "STRUCT \\(.*f set1,.*CASE OF.*:.*ch1 CHARS \\(20\\).*:.*ch2 CHARS \\(10\\) VARYING.*ELSE.*ch3 CHARS \\(0\\) VARYING.*ESAC.*\\)" \
+ "print structure mode 2"
+ #setup_xfail "*-*-*"
+ test_print_accept "ptype stru3m" "STRUCT \\(.*f r3,.*CASE OF.*:.*ch1 CHARS \\(20\\).*ESAC.*\\)" \
+ "print structure mode 3"
+ # setup_xfail "*-*-*"
+ test_print_accept "ptype stru4m" "STRUCT \\(.*i long,.*CASE OF.*:.*i1 int,.*i11 int,.*b1 bool,.*c1 char.*:.*i2 long,.*i22 long,.*bs2 BOOLS \\(10\\).*:.*s3 STRUCT \\(.*i3 int,.*CASE OF.*:.*foo long.*ELSE.*bar char.*ESAC.*\\).*ELSE.*x stru2m.*ESAC,.*y stru3m.*\\)" \
+ "print structure mode 4"
+
+
+ if $passcount then {
+ pass "$passcount correct modes printed"
+ }
+}
+
+# various tests if locations are treated correctly
+# read access using ptype, print, whatis
+proc test_locations {} {
+ global passcount
+
+ set passcount 0
+ verbose "testing read access to locations"
+ # various location tests can be found in chillvars.exp
+
+ # set locations
+ test_print_accept "ptype s1l" "SET \\(aaa, bbb, ccc\\)" \
+ "print mode of set location"
+ test_print_accept "whatis s1l" "set1" \
+ "print modename of set location"
+ test_print_accept "print s1l" "ccc" "print set location"
+ test_print_accept "ptype s2l" "SET \\(na = 1, nb = 34, nc = 20\\)" \
+ "print mode of numbered set location"
+ test_print_accept "whatis s2l" "nset1" \
+ "print mode name of numbered set location"
+ test_print_accept "print s2l" "nb" "print numberes set location"
+
+ # range modes
+ test_print_accept "ptype rl1" "ubyte \\(0:255\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl1" "r11" \
+ "print mode name of range location"
+ test_print_accept "print rl1" "3" \
+ "print range location"
+
+ test_print_accept "ptype rl2" "ubyte \\(0:255\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl2" "r11" \
+ "print mode name of range location"
+ test_print_accept "print rl2" "0" \
+ "print range location"
+
+ test_print_accept "ptype rl3" "ubyte \\(0:255\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl3" "r11" \
+ "print mode name of range location"
+ test_print_accept "print rl3" "255" \
+ "print range location"
+
+ test_print_accept "ptype rl5" "uint \\(0:65535\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl5" "r12" \
+ "print mode name of range location"
+ test_print_accept "print rl5" "65530" \
+ "print range location"
+
+ test_print_accept "ptype rl6" "uint \\(0:65535\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl6" "r12" \
+ "print mode name of range location"
+ test_print_accept "print rl6" "0" \
+ "print range location"
+
+ test_print_accept "ptype rl7" "uint \\(0:65535\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl7" "r12" \
+ "print mode name of range location"
+ test_print_accept "print rl7" "65535" \
+ "print range location"
+
+# test_print_accept "ptype rl9" "ulong \\(0:4294967295\\)" \
+# "print mode of range location"
+# test_print_accept "whatis rl9" "r13" \
+# "print mode name of range location"
+# test_print_accept "print rl9" "128" \
+# "print range location"
+
+# test_print_accept "ptype rl10" "ulong \\(0:4294967295\\)" \
+# "print mode of range location"
+# test_print_accept "whatis rl10" "r13" \
+# "print mode name of range location"
+# test_print_accept "print rl10" "0" \
+# "print range location"
+
+# test_print_accept "ptype rl11" "ulong \\(0:4294967295\\)" \
+# "print mode of range location"
+# test_print_accept "whatis rl11" "r13" \
+# "print mode name of range location"
+# test_print_accept "print rl11" "4294967295" \
+# "print range location"
+
+ test_print_accept "ptype rl13" "byte \\(-128:127\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl13" "r14" \
+ "print mode name of range location"
+ test_print_accept "print rl13" "-121" \
+ "print range location"
+
+ test_print_accept "ptype rl14" "byte \\(-128:127\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl14" "r14" \
+ "print mode name of range location"
+ test_print_accept "print rl14" "-128" \
+ "print range location"
+
+ test_print_accept "ptype rl15" "byte \\(-128:127\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl15" "r14" \
+ "print mode name of range location"
+ test_print_accept "print rl15" "127" \
+ "print range location"
+
+ test_print_accept "ptype rl17" "int \\(-32768:32767\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl17" "r15" \
+ "print mode name of range location"
+ test_print_accept "print rl17" "-32720" \
+ "print range location"
+
+ test_print_accept "ptype rl18" "int \\(-32768:32767\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl18" "r15" \
+ "print mode name of range location"
+ test_print_accept "print rl18" "-32768" \
+ "print range location"
+
+ test_print_accept "ptype rl19" "int \\(-32768:32767\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl19" "r15" \
+ "print mode name of range location"
+ test_print_accept "print rl19" "32767" \
+ "print range location"
+
+ test_print_accept "ptype rl21" "long \\(-2147483648:2147483647\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl21" "r16" \
+ "print mode name of range location"
+ test_print_accept "print rl21" "2147483643" \
+ "print range location"
+
+ test_print_accept "ptype rl22" "long \\(-2147483648:2147483647\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl22" "r16" \
+ "print mode name of range location"
+ test_print_accept "print rl22" "-2147483648" \
+ "print range location"
+
+ test_print_accept "ptype rl23" "long \\(-2147483648:2147483647\\)" \
+ "print mode of range location"
+ test_print_accept "whatis rl23" "r16" \
+ "print mode name of range location"
+ test_print_accept "print rl23" "2147483647" \
+ "print range location"
+
+ # powerset locations
+ test_print_accept "ptype pl1" \
+ "POWERSET SET \\(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10\\)" \
+ "print mode of powerset location 1"
+ test_print_accept "whatis pl1" "pm1" \
+ "print mode mode name of powerset location"
+ test_print_accept "print pl1" \
+ "\[\[\]p1:p10\[\]\]" \
+ "print powerset location 1"
+ test_print_accept "print pl2" {\[\]} \
+ "print powerset location 2"
+ test_print_accept "print pl3" "\[\[\]p1, p10\[\]\]" \
+ "print powerset location 3"
+ test_print_accept "print pl4" {\[p1:p2, p4:p6, p8:p10\]} \
+ "print powerset location 4"
+ test_print_accept "print pl5" {\[p1:p4, p6, p8:p10\]} \
+ "print powerset location 5"
+ test_print_accept "print pl6" {\[p1, p3:p8, p10\]} \
+ "print powerset location 6"
+
+ test_print_accept "ptype pl7" \
+ "POWERSET byte \\(1:8\\)" \
+ "print mode of byte powerset location"
+ test_print_accept "whatis pl7" "pm2" \
+ "print modename of byte powerset location"
+ test_print_accept "print pl7" {\[1:8\]} \
+ "print powerset location 7"
+
+ test_print_accept "ptype pl8" \
+ "POWERSET int \\(-32768:32767\\)" \
+ "print mode of int powerset location"
+ test_print_accept "whatis pl8" "pm3" \
+ "print modename of int powerset location"
+ test_print_accept "print pl8" {\[-32768:32767\]} \
+ "print powerset location 8"
+
+# test_print_accept "ptype pl9" \
+# "POWERSET long \\(-2147483648:2147483647\\)" \
+# "print mode of long powerset location"
+# test_print_accept "whatis pl9" "pm5" \
+# "print modename of long powerset location"
+# test_print_accept "print pl9" {\[-2147483648:2147483647\]} \
+# "print powerset location 9"
+
+ # reference modes
+ test_print_accept "ptype ref3l" "PTR" "print mode of reference location"
+ # setup_xfail "*-*-*"
+ test_print_accept "whatis ref3l" "ref3" \
+ "print modename of reference location"
+ # setup_xfail "*-*-*"
+ test_print_accept "print ref3l" "ref3\\(H'.*\\)" \
+ "print reference location"
+ test_print_accept "ptype ref4l" "PTR" "print mode of reference location"
+ # setup_xfail "*-*-*"
+ test_print_accept "whatis ref4l" "ref4" \
+ "print modename of reference location"
+ # setup_xfail "*-*-*"
+ test_print_accept "print ref4l" "ref4\\(H'.*\\)" \
+ "print reference location"
+ test_print_accept "ptype ref5l" "PTR" "print mode of reference location"
+ test_print_accept "whatis ref5l" "PTR" \
+ "print modename of reference location"
+ test_print_accept "print ref5l" "PTR\\(H'.*\\)" \
+ "print reference location"
+
+ # dereference a little bit..
+ test_print_accept "print ref6l->syn_int" "42" \
+ "dereference reference to synmode location"
+ test_print_accept "print ref7l->int" "-42" \
+ "dereference reference to predefined mode location"
+ test_print_accept "print ref8l->pm1" \
+ "\[\[\]p1:p10\[\]\]" \
+ "dereference reference to newmode location"
+
+ # synchronization mode locations
+ # FIXME: synchronization modes are not supported so far...
+ xfail "no synchronization mode location support, not implemented yet"
+
+ # timing mode locations
+ # FIXME: callbacks to abstime, inttime not implemented
+ xfail "timing modes not implemented properly yet"
+
+ # char string locations
+ # some tests are don in chillvars.exp
+ test_print_accept "ptype strl1" \
+ "CHARS \\(7\\) VARYING" \
+ "print varying string location"
+ test_print_accept "whatis strl1" "strm2" \
+ "print string locationa mode name"
+ test_print_accept "print strl1" \
+ {\"hansi\^\(0\)\"} \
+ "print string location"
+ # string elements
+ test_print_accept "print strl1(0)" "\'h\'" \
+ "print string element 1"
+ test_print_accept "print strl1(5)" {'\^[(]0[)]'} \
+ "print string element 2"
+ test_print_accept "print strl1(3)" "\'s\'" \
+ "print string element 3"
+ test_print_accept "ptype strl1(0)" "char" \
+ "print mode of string element"
+ # slices
+ test_print_accept "print strl1(3:4)" "\"si\"" \
+ "print string slice 1"
+ test_print_accept "print strl1(0:5)" \
+ {\"hansi\^\(0\)\"} \
+ "print string slice 2"
+ test_print_accept "print strl1(0:0)" "\"h\"" \
+ "print string slice 3"
+ test_print_accept "print strl1(0 up 6)" \
+ {\"hansi\^\(0\)\"} \
+ "print string slice 4"
+ # FIXME: adjust error message, when implented
+ gdb_test "print strl1(6 up 1)" \
+ ".*slice.*out of range.*" \
+ "print invalid string slice length"
+ gdb_test "print strl1(-1 up 5)" \
+ ".*slice.*out of range.*" \
+ "print invalid string slice length"
+ gdb_test "print strl1(-1:5)" \
+ ".*slice.*out of range.*" \
+ "print invalid string slice"
+ gdb_test "print strl1(-1:7)" \
+ ".*slice.*out of range.*" \
+ "print invalid string slice"
+ gdb_test "print strl1(0 up -1)" \
+ ".*slice.*out of range.*" \
+ "print invalid string slice length"
+ gdb_test "print strl1(0 up 0)" {""}
+
+ # bitstring locations
+ test_print_accept "ptype bstr1" \
+ "BOOLS \\(20\\)" \
+ "print mode of bitstring location"
+ test_print_accept "whatis bstrl1" "bstr1" \
+ "print mode name of bitstring location"
+ test_print_accept "print bstrl1" \
+ "B'10101010101010101010'" \
+ "print bitstring location"
+
+ test_print_accept "ptype bstrl1(0)" "bool|BOOL" \
+ "print mode of bitstring element"
+ test_print_accept "print bstrl1(0)" "TRUE" \
+ "print bitstring element 1"
+ test_print_accept "print bstrl1(19)" "FALSE" \
+ "print bitstring element 2"
+ test_print_accept "print bstrl1(10)" "TRUE" \
+ "print bitstring element 3"
+
+ test_print_accept "print bstrl1(0:19)" \
+ "B'10101010101010101010'" \
+ "print bitstring location slice 1"
+ test_print_accept "print bstrl1(0:0)" \
+ "B'1'" \
+ "print bitstring location slice 2"
+ test_print_accept "print bstrl1(3:9)" \
+ "B'0101010'" \
+ "print bitstring location slice 3"
+ test_print_accept "print bstrl1(0 up 20)" \
+ "B'10101010101010101010'" \
+ "print bitstring location slice 4"
+ test_print_accept "print bstrl1(19 up 1)" \
+ "B'0'" \
+ "print bitstring location slice 5"
+ gdb_test "print bstrl1(20 up 1)" \
+ ".*slice out of range.*" \
+ "print invalid bitstring slice (20 up 1)"
+ gdb_test "print bstrl1(-4:5)" \
+ ".*slice out of range.*" \
+ "print invalid bitstring slice (-4:5)"
+ gdb_test "print bstrl1(-1:up 1)" \
+ ".*invalid expression syntax.*" \
+ "print invalid bitstring slice (-1:ip 1)"
+ gdb_test "print bstrl1(-1:20)" \
+ ".*slice out of range.*" \
+ "print invalid bitstring slice (-1:20)"
+ gdb_test "print bstrl1(0 up -1)" \
+ ".*slice out of range.*" \
+ "print invalid bitstring slice (0 up -1)"
+ test_print_accept "print bstrl1(4 up 0)" "B''"
+
+ # array mode locations
+ gdb_test_exact "ptype arrl1" \
+ "ARRAY (1:100) set1" \
+ "print mode of array location"
+ gdb_test "whatis arrl1" "arr1m" \
+ "print mode name of array location"
+ gdb_test_exact "print arrl1" {[(1:100): aaa]} \
+ "print array location"
+ test_print_accept "ptype arrl1(1)" \
+ "SET \\(aaa, bbb, ccc\\)" \
+ "print mode of array element"
+ gdb_test_exact "print arrl3" \
+ {[(1:5): [(1:3): [(1:2): -2147483648]]]} \
+ "print array location 2"
+ gdb_test_exact "print arrl3(1)" \
+ {[(1:3): [(1:2): -2147483648]]} \
+ "print array location 3"
+ gdb_test_exact "ptype arrl3(1)" \
+ {ARRAY (1:3) ARRAY (1:2) long} \
+ "print mode of array element"
+ test_print_accept "print arrl3(5)" \
+ {\[\(1:3\): \[\(1:2\): -2147483648\]\]} \
+ "print array location 4"
+ test_print_accept "print arrl3(1,1)" \
+ {\[\(1:2\): -2147483648\]} \
+ "print array location 5"
+ test_print_accept "ptype arrl3(1,1)" \
+ {ARRAY \(1:2\) long} \
+ "print mode of array element"
+ test_print_accept "print arrl3(5,3)" \
+ {\[\(1:2\): -2147483648\]} \
+ "print array location 6"
+ test_print_accept "print arrl3(1,1,1)" \
+ "-2147483648" \
+ "print array location 7"
+ test_print_accept "print arrl3(5,3,2)" \
+ "-2147483648" \
+ "print array location 8"
+ test_print_accept "print arrl3(1)(3)(2)" \
+ "-2147483648" \
+ "print array location 9"
+
+ # reject the following range fails
+ # FIXME: adjust error messages
+ gdb_test "print arrl3(-1)" \
+ ".*out of range.*" \
+ "check invalid array indices 1"
+ gdb_test "print arrl3(6)" \
+ ".*out of range.*" \
+ "check invalid array indices 2"
+ gdb_test "print arrl3(0,0)" \
+ ".*out of range.*" \
+ "check invalid array indices 3"
+ gdb_test "print arrl3(1,0)" \
+ ".*out of range.*" \
+ "check invalid array indices 4"
+ gdb_test "print arrl3(1,4)" \
+ ".*out of range.*" \
+ "check invalid array indices 5"
+ gdb_test "print arrl3(6,4)" \
+ ".*out of range.*" \
+ "check invalid array indices 6"
+ gdb_test "print arrl3(1,1,0)" \
+ ".*out of range.*" \
+ "check invalid array indices 7"
+ gdb_test "print arrl3(6,4,0)" \
+ ".*out of range.*" \
+ "check invalid array indices 8"
+ gdb_test "print arrl3(1,1,3)" \
+ ".*out of range.*" \
+ "check invalid array indices 9"
+
+ gdb_test "print arrl3(0)(0)" \
+ ".* array or string index out of range.*" \
+ "check invalid array indices 10"
+ gdb_test "print arrl3(1)(0)" \
+ ".* array or string index out of range.*" \
+ "check invalid array indices 11"
+ gdb_test "print arrl3(1)(4)" \
+ ".* array or string index out of range.*" \
+ "check invalid array indices 12"
+ gdb_test "print arrl3(6)(4)" \
+ ".* array or string index out of range.*" \
+ "check invalid array indices 13"
+ gdb_test "print arrl3(1)(1)(0)" \
+ ".* array or string index out of range.*" \
+ "check invalid array indices 14"
+ gdb_test "print arrl3(6)(4)(0)" \
+ ".* array or string index out of range.*" \
+ "check invalid array indices 15"
+ gdb_test "print arrl3(1)(1)(3)" \
+ ".* array or string index out of range.*" \
+ "check invalid array indices 16"
+
+ # slices
+ test_print_accept "print arrl4(1:3)" \
+ {\[\(1:2\): \[\(1:3\): \[\(1:2\): -2147483648\]\], \(3\): \[\(1:3\): \[\(1:2\): 100\]\]\]} \
+ "print array slice 1"
+ test_print_accept "ptype arrl4(1:3)" \
+ {ARRAY \(1:3\) ARRAY \(1:3\) ARRAY \(1:2\) long} \
+ "print mode of array slice"
+# The next one is bogus:
+# test_print_accept "print arrl4(5, 2:3, 1)" \
+# # FIXME: maybe the '(1): ' in the inner tupel should be omitted ? \
+# {\[(2): \[\(1\): 100\], \(3\):\[\(1\): 100\]\]} \
+# "print array slice 2"
+ test_print_accept "print arrl4(1 up 4)" \
+ {\[\(1:2\): \[\(1:3\): \[\(1:2\): -2147483648\]\], \(3\): \[\(1:3\): \[\(1:2\): 100\]\], \(4\): \[\(1:3\): \[\(1:2\): -2147483648\]\]\]} \
+ "print array slice 3"
+# The next two are bogus:
+# test_print_accept "print arrl4(3, 2 up 1)" \
+# {\[\(2:3\): \[\(1:2\): 100\]\]} \
+# "print array slice 4"
+# test_print_accept "print arrl4(1:2, 1 up 1, 2)" \
+# {\[\(1\): \[\(1\): \[\(2\): -2147483648\], \(2\): \[\(2\): -2147483648\]\], \(2\): \[\(1\): \[\(2\): -2147483648\], \(2\): \[\(2\): -2147483648\]\]\]} \
+# "print array slice 4"
+ # reject invalid slices
+ # FIXME: adjust error messages
+ gdb_test "print arrl4(5:6)" \
+ ".*slice out of range.*" \
+ "check invalid range 1"
+ gdb_test "print arrl4(0:1)" \
+ ".*slice out of range.*" \
+ "check invalid range 2"
+ gdb_test "print arrl4(0:6)" \
+ ".*slice out of range.*" \
+ "check invalid range 3"
+ gdb_test "print arrl4(3:2)" \
+ ".*slice out of range.*" \
+ "check invalid range 4"
+ gdb_test "print arrl4(1,3:4)" \
+ ".*syntax error.*" \
+ "check invalid range 5"
+ gdb_test "print arrl4(1,0:1)" \
+ ".*syntax error.*" \
+ "check invalid range 6"
+ gdb_test "print arrl4(1,0:4)" \
+ ".*syntax error.*" \
+ "check invalid range 7"
+ gdb_test "print arrl4(1,3:2)" \
+ ".*syntax error.*" \
+ "check invalid range 8"
+ gdb_test "print arrl4(5 up 2)" \
+ ".*slice out of range.*" \
+ "check invalid range 9"
+ gdb_test "print arrl4(-1 up 1)" \
+ ".*slice out of range.*" \
+ "check invalid range 10"
+ gdb_test "print arrl4(-1 up 7)" \
+ ".*slice out of range.*" \
+ "check invalid range 11"
+ gdb_test "print arrl4(1 up 0)" \
+ ".*slice out of range.*" \
+ "check invalid range 12"
+ gdb_test "print arrl4(1,3 up 1)" \
+ ".*syntax error.*" \
+ "check invalid range 13"
+ gdb_test "print arrl4(1,-1 up 1)" \
+ ".*syntax error.*" \
+ "check invalid range 14"
+ gdb_test "print arrl4(1,-1 up 5)" \
+ ".*syntax error.*" \
+ "check invalid range 15"
+ gdb_test "print arrl4(1,2 up 0)" \
+ ".*syntax error.*" \
+ "check invalid range 16"
+
+ # structure modes
+ # some tests are in chillvars.exp
+ # FIXME: no tag processing implemented do maybe adjust these tests
+ setup_xfail "*-*-*"
+ test_print_accept "ptype stru1m" \
+ "STRUCT \\(.*a long,.*b long,.*CASE b OF.*\\(42\\):.*ch1 CHARS\\(20\\),.*\\(52\\):.*ch2 CHARS\\(10\\).*ELSE.*ch3 CHARS\\(1\\).*ESAC.*\\)" \
+ "print mode of structure location 1"
+ test_print_accept "whatis strul1" "stru1m" \
+ "print mode name of structure location 1"
+ setup_xfail "*-*-*"
+ test_print_accept "print strul1" \
+ {\[\.a: -2147483648, \.b: 42, \.\(b\): \{\(42\) = \[\.ch1: \"12345678900987654321\"\], \(52\) = \[\.ch2: \"1234567890\"\], (else) = \[\.ch3: \"1\"\]\}\]} \
+ "print structure location 1"
+ test_print_accept "print strul1.a" \
+ "-2147483648" \
+ "print field of structure location 1"
+ test_print_accept "print strul1.b" "42" \
+ "print field of structure location 1"
+ test_print_accept "print strul1.ch1" \
+ "\"12345678900987654321\"" \
+ "print field of structure location 1"
+ # setup_xfail "*-*-*"
+ test_print_accept "print strul1.ch2" \
+ "\"1234567890\"" \
+ "print field of structure location 1"
+ # setup_xfail "*-*-*"
+ test_print_accept "print strul1.ch3" \
+ "\"1\"" \
+ "print field of structure location 1"
+
+ if $passcount then {
+ pass "$passcount correct locations printed"
+ }
+}
+
+# This is chill/9434
+
+proc test_9434 {} {
+ global passcount
+
+ verbose "testing pr-9434"
+
+ test_print_accept "ptype m_xyzmode" "STRUCT \\(.*next REF m_xyzmode,.*i long.*\\)"
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+if [set_lang_chill] then {
+ test_modes
+ test_locations
+ test_9434
+} else {
+ warning "$test_name tests suppressed."
+}
diff --git a/gdb/testsuite/gdb.chill/tests2.ch b/gdb/testsuite/gdb.chill/tests2.ch
new file mode 100644
index 00000000000..cf29866d905
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/tests2.ch
@@ -0,0 +1,193 @@
+-- Copyright 1992, 1995 Free Software Foundation, Inc.
+
+-- 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.
+
+-- Please email any bugs, comments, and/or additions to this file to:
+-- bug-gdb@prep.ai.mit.edu
+
+--
+-- test program 2 (refer to tests2.exp)
+--
+
+tests2: module;
+
+-- testpattern
+syn pat1 ulong = H'aaaaaaaa;
+syn pat2 ulong = H'55555555;
+
+-- discrete modes
+newmode bytem = struct (
+ p1 ulong,
+ m byte,
+ p2 ulong);
+newmode ubytem = struct (
+ p1 ulong,
+ m ubyte,
+ p2 ulong);
+newmode intm = struct (
+ p1 ulong,
+ m int,
+ p2 ulong);
+newmode uintm = struct (
+ p1 ulong,
+ m uint,
+ p2 ulong);
+newmode longm = struct (
+ p1 ulong,
+ m long,
+ p2 ulong);
+newmode ulongm = struct (
+ p1 ulong,
+ m ulong,
+ p2 ulong);
+newmode boolm = struct (
+ p1 ulong,
+ m bool,
+ p2 ulong);
+newmode charm1 = struct (
+ p1 ulong,
+ m char(4),
+ p2 ulong);
+newmode charm2 = struct (
+ p1 ulong,
+ m char(7),
+ p2 ulong);
+newmode charm3 = struct (
+ p1 ulong,
+ m char(8) varying,
+ p2 ulong);
+newmode charm4 = struct (
+ p1 ulong,
+ m char,
+ p2 ulong);
+newmode bitm1 = struct (
+ p1 ulong,
+ m bit(8),
+ p2 ulong);
+newmode bitm2 = struct (
+ p1 ulong,
+ m bit(10),
+ p2 ulong);
+newmode setm1 = struct (
+ p1 ulong,
+ m set (a, b, c, d, e, f, g, h),
+ p2 ulong);
+newmode nset1 = struct (
+ p1 ulong,
+ m set (na = 2147483648, nb = 1024, nc = 4294967295),
+ p2 ulong);
+newmode rm1 = struct (
+ p1 ulong,
+ m range (lower(byte):upper(byte)),
+ p2 ulong);
+newmode rm2 = struct (
+ p1 ulong,
+ m range (lower(int):upper(int)),
+ p2 ulong);
+newmode rm3 = struct (
+ p1 ulong,
+ m range (lower(long):upper(long)),
+ p2 ulong);
+newmode pm1 = struct (
+ p1 ulong,
+ m powerset set (pa, pb, pc, pd, pe, pf, pg, ph),
+ p2 ulong);
+newmode pm2 = struct (
+ p1 ulong,
+ m powerset int (1:32),
+ p2 ulong);
+-- this should be rejected by the gnuchill compiler !
+newmode pm3 = struct (
+ p1 ulong,
+-- m powerset long (lower(long): upper(long)),
+ p2 ulong);
+newmode refm1 = struct (
+ p1 ulong,
+ m ptr,
+ p2 ulong);
+newmode refm2 = struct (
+ p1 ulong,
+ m ref bytem,
+ p2 ulong);
+newmode prm1 = struct (
+ p1 ulong,
+ m proc (),
+ p2 ulong);
+newmode tim1 = struct (
+ p1 ulong,
+ m time,
+ p2 ulong);
+newmode tim2 = struct (
+ p1 ulong,
+ m duration,
+ p2 ulong);
+newmode rem1 = struct (
+ p1 ulong,
+ m real,
+ p2 ulong);
+newmode rem2 = struct (
+ p1 ulong,
+ m long_real,
+ p2 ulong);
+newmode arrm1 = struct (
+ p1 ulong,
+ m array(1:3, 1:2) int,
+ p2 ulong);
+newmode strum1 = struct (
+ p1 ulong,
+ m struct (a, b int, ch char(4)),
+ p2 ulong);
+
+
+-- dummyfunction for breakpoints
+dummyfunc: proc();
+end dummyfunc;
+
+
+dcl b1 bytem init := [pat1, -128, pat2];
+dcl ub1 ubytem init := [pat1, 0, pat2];
+dcl i1 intm init := [pat1, -32768, pat2];
+dcl ui1 uintm init := [pat1, 0, pat2];
+dcl l1 longm init := [pat1, -2147483648, pat2];
+dcl ul1 ulongm init := [pat1, 0, pat2];
+dcl bo1 boolm init := [pat1, true, pat2];
+dcl c1 charm1 init := [pat1, "1234", pat2];
+dcl c2 charm2 init := [pat1, "1234567", pat2];
+dcl c3 charm3 init := [pat1, "12345678", pat2];
+dcl c4 charm4 init := [pat1, C'00', pat2];
+dcl bi1 bitm1 init := [pat1, B'01011010', pat2];
+dcl bi2 bitm2 init := [pat1, B'1010110101', pat2];
+dcl se1 setm1 init := [pat1, a, pat2];
+dcl nse1 nset1 init := [pat1, na, pat2];
+dcl r1 rm1 init := [pat1, -128, pat2];
+dcl r2 rm2 init := [pat1, -32768, pat2];
+dcl r3 rm3 init := [pat1, -2147483648, pat2];
+dcl p1 pm1 init := [pat1, [pa], pat2];
+dcl p2 pm2 init := [pat1, [1], pat2];
+-- dcl p3 pm3 init := [pat1, [-1], pat2]; -- FIXME: bug in gnuchill
+dcl ref1 refm1 init := [pat1, null, pat2];
+dcl ref2 refm2 init := [pat1, null, pat2];
+dcl pr1 prm1;
+dcl ti1 tim1 init := [pat1, 0, pat2];
+dcl ti2 tim2 init := [pat1, 0, pat2];
+dcl re1 rem1 init := [pat1, 0.0, pat2];
+dcl re2 rem2 init := [pat1, 0.0, pat2];
+dcl arrl1 arrm1 init:=[pat1, [(1:3): [0,0]], pat2];
+dcl strul1 strum1 init := [pat1, [.a: 0, .b: 0, .ch: "0000"], pat2];
+
+pr1 := [pat1, dummyfunc, pat2];
+dummyfunc();
+
+end tests2;
diff --git a/gdb/testsuite/gdb.chill/tests2.exp b/gdb/testsuite/gdb.chill/tests2.exp
new file mode 100644
index 00000000000..1e47e811ca9
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/tests2.exp
@@ -0,0 +1,271 @@
+# Copyright 1992, 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set prms_id 0
+set bug_id 0
+
+# Set the current language to chill. This counts as a test. If it
+# fails, then we skip the other tests.
+
+set testfile "tests2"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -w -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+global infinity
+if [istarget "i*86-*-sysv4*"] then {
+ set infinity "inf"
+} else {
+ set infinity "Infinity"
+}
+
+proc set_lang_chill {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ if ![file exists $objdir/$subdir/$binfile] then {
+ return 0
+ }
+ verbose "loading file '$objdir/$subdir/$binfile'"
+ gdb_load $objdir/$subdir/$binfile
+
+ send_gdb "set language chill\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language chill (timeout)" ; return 0 }
+ }
+
+ send_gdb "show language\n"
+ gdb_expect {
+ -re ".* source language is \"chill\".*$gdb_prompt $" {
+ pass "set language to \"chill\""
+ send_gdb "break dummyfunc\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {
+ send_gdb "run\n"
+ gdb_expect -re ".*$gdb_prompt $" {}
+ return 1
+ }
+ timeout {
+ fail "can't set breakpoint (timeout)"
+ return 0
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ fail "setting language to \"chill\""
+ return 0
+ }
+ timeout {
+ fail "can't show language (timeout)"
+ return 0
+ }
+ }
+}
+
+# checks if structure was accessed correctly
+proc test_write { args } {
+ global gdb_prompt
+
+ if [llength $args]==5 then {
+ set message [lindex $args 4]
+ set extended [lindex $args 3]
+ set matchval [lindex $args 2]
+ } elseif [llength $args]==4 then {
+ set message [lindex $args 3]
+ set matchval [lindex $args 2]
+ set extended ""
+ } elseif [llength $args]==3 then {
+ set message [lindex $args 2]
+ set extended ""
+ } else {
+ warning "test ($args) write called with wrong number of arguments"
+ return
+ }
+
+ set location [lindex $args 0]
+ set value [lindex $args 1]
+ if ![info exists matchval] then {
+ set matchval $value
+ }
+ verbose "loc: $location, val: $value, msg: $message, ext: $extended, match: $matchval"
+
+ verbose "setting var $value..."
+ send_gdb "set var $location.m$extended := $value\n"
+ gdb_expect -re ".*$gdb_prompt $" {}
+ gdb_test "print $location" \
+ ".*= \[\[\]\\.p1: 2863311530, \\.m: $matchval, \\.p2: 1431655765\[\]\]"\
+ "$message"
+}
+
+# test write access from gdb (setvar x:=y) from gdb
+proc write_access { } {
+ global infinity
+
+ verbose "testing write access to locations"
+
+ # discrete modes
+ test_write b1 127 "byte write 1"
+ test_write b1 -128 "byte write 2"
+ test_write b1 0 "byte write 3"
+ test_write ub1 255 "ubyte write 1"
+ test_write ub1 0 "ubyte write 2"
+ test_write ub1 42 "ubyte write 3"
+ test_write i1 32767 "int write 1"
+ test_write i1 -32768 "int write 2"
+ test_write i1 0 "int write 3"
+ test_write ui1 65535 "uint write 1"
+ test_write ui1 0 "uint write 2"
+ test_write ui1 123 "uint write 3"
+ test_write l1 2147483647 "long write 1"
+ test_write l1 -2147483648 "long write 2"
+ test_write l1 0 "long write 3"
+ test_write ul1 4294967295 "ulong write 1"
+ test_write ul1 0 "ulong write 2"
+ test_write ul1 1000000 "ulong write 3"
+ test_write bo1 FALSE "bool write 1"
+ test_write bo1 TRUE "bool write 2"
+ test_write c1 \"1234\" "char write 1"
+ test_write c2 \"1234567\" "char write 2"
+ test_write c3 \"654321\" "char write 3"
+ test_write c4 C'65' 'e' "char write 4"
+ test_write bi1 B'10100101' "bitstring write 1"
+ test_write bi2 B'0101001010' "bitstring write 2"
+ test_write se1 a "set write 1"
+ test_write se1 h "set write 2"
+ # The following two use numbered sets with too-large values.
+ setup_xfail "*-*-*"
+ test_write nse1 nb "numbered set write 1"
+ setup_xfail "*-*-*"
+ test_write nse1 nc "numbered set write 2"
+ test_write r1 127 "range write 1"
+ test_write r2 32767 "range write 2"
+ test_write r3 2147483647 "range write 3"
+
+ # powerset modes
+ test_write p1 {[pa:ph]} {\[pa:ph\]} "powerset write 1"
+ test_write p1 {[pa, pc:pf, ph]} {\[pa, pc:pf, ph\]} "powerset write 2"
+ test_write p1 {[pa, pc, pe, pg]} {\[pa, pc, pe, pg\]} "powerset write 3"
+ test_write p1 {[]} {\[\]} "powerset write 4"
+ test_write p2 {[1:32]} {\[1:32\]} "powerset write 5"
+ test_write p2 {[1, 3:30, 32]} {\[1, 3:30, 32\]} "powerset write 6"
+ test_write p2 {[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31]} {\[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31\]} \
+ "powerset write 7"
+ test_write p2 {[]} {\[\]} "powerset write 8"
+
+# Fixme: this should be rejected by gnuchill
+# test_write p3 {[-2147483648:2147483647]} {\[-2147483648:2147483647\]} \
+# "powerset write 9"
+# test_write p3 {[-2147483648, -1000000:1000000, 2147483647]} \
+# {\[-2147483648, -1000000:1000000, 2147483647\]} \
+# "powerset write 10"
+# test_write p3 {[-99, -97, -95, 1001, 1003, 1005]} \
+# {\[-99, -97, -95, 1001, 1003, 1005\]} "powerset write 11"
+# test_write p3 {[]} {\[\]} "powerset write 12"
+
+ # reference modes
+ test_write ref1 ->ref1 {H'[0-9a-fA-F]+} "reference write 1"
+ test_write ref2 ->b1 {H'[0-9a-fA-F]+} "reference write 2"
+ test_write ref1 NULL "reference write 3"
+ test_write ref2 NULL "reference write 4"
+
+ # procedure modes
+ test_write pr1 NULL "procefure write 1"
+ # FIXME: remove when NULL is understood
+ test_write pr1 0 NULL "procefure write 2"
+ test_write pr1 dummyfunc {H'[0-9a-fA-F]+ <dummyfunc>} "procedure write 3"
+
+ # timing modes, FIXME when callbacks to timefunctions are implemented
+ #test_write ti1 abstime(1970, 3, 12, 10, 43, 0) {} "time write 1"
+ #test_write ti2 <set somehow a duration>
+ xfail "timing modes not implemented yet"
+
+ # real modes
+ # This ones
+ test_write re1 42.03 {42.0[0-9]*} "real write 1"
+ test_write re1 0 "real write 2"
+ test_write re1 "1e+38" {1e\+38|1\.0[0-9]*e\+38|9\.9[0-9]*e\+37} \
+ "real write 3"
+ setup_xfail "i*86-pc-linux-gnu" "m68*-*-hpux*"
+ test_write re1 "1e+39" $infinity "real write 4"
+ test_write re2 42.03 {42.0[0-9]*} "real write 5"
+ test_write re2 0 "real write 6"
+ test_write re2 "1e+308" {1e\+308} "real write 7"
+ setup_xfail "i*86-pc-linux-gnu" "m68*-*-hpux*"
+ test_write re2 "1e+309" $infinity "real write 8"
+ # array modes
+ test_write arrl1 {[(1:3): [(1:2): -128]]} {\[\(1:3\): \[\(1:2\): -128\]\]}\
+ "array write 1"
+ test_write arrl1 {[(1:3): [(1:2): 0]]} {\[\(1:3\): \[\(1:2\): 0\]\]}\
+ "array write 2"
+ test_write arrl1 {[(1): [(1:2): 127], (2): [(1:2): -128], (3): [(1:2): 127]]} {\[\(1\): \[\(1:2\): 127\], \(2\): \[\(1:2\): -128\], \(3\): \[\(1:2\): 127\]\]}\
+ "array write 3"
+ test_write arrl1 {[(1:3): [(1:2): 0]]} {\[\(1:3\): \[\(1:2\): 0\]\]}\
+ "array write 4"
+ setup_xfail "*-*-*"
+ # Bogus test case - type mismatch?
+ test_write arrl1 {[(1): 127, (2): -128]} "array write 5"
+ test_write arrl1 {[(1:3): [(1:2): 0]]} {\[\(1:3\): \[\(1:2\): 0\]\]}\
+ "array write 6"
+
+ # structure modes
+ test_write strul1 {[.a: -32768, .b: 32767, .ch: "ZZZZ"]} \
+ {\[\.a: -32768, \.b: 32767, \.ch: \"ZZZZ\"\]} \
+ "structure write 1"
+ test_write strul1 {[.a: 0, .b: 0, .ch: "0000"]} \
+ {\[\.a: 0, \.b: 0, \.ch: \"0000\"\]} \
+ "structure write 2"
+ test_write strul1 -32768 {\[\.a: -32768, \.b: 0, \.ch: \"0000\"\]} \
+ {.a} "structure write 3"
+ test_write strul1 {[.a: 0, .b: 0, .ch: "0000"]} \
+ {\[\.a: 0, \.b: 0, \.ch: \"0000\"\]} \
+ "structure write 4"
+ test_write strul1 -32768 {\[\.a: 0, \.b: -32768, \.ch: \"0000\"\]} \
+ {.b} "structure write 5"
+ test_write strul1 {[.a: 0, .b: 0, .ch: "0000"]} \
+ {\[\.a: 0, \.b: 0, \.ch: \"0000\"\]} \
+ "structure write 6"
+ test_write strul1 \"HUGO\" {\[\.a: 0, \.b: 0, \.ch: \"HUGO\"\]} \
+ {.ch} "structure write 7"
+}
+
+# Start with a fresh gdb.
+
+set binfile "tests2.exe"
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+if [set_lang_chill] then {
+ write_access
+} else {
+ warning "$test_name tests suppressed."
+}
diff --git a/gdb/testsuite/gdb.chill/tuples.ch b/gdb/testsuite/gdb.chill/tuples.ch
new file mode 100644
index 00000000000..24709f8fe05
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/tuples.ch
@@ -0,0 +1,86 @@
+x: MODULE
+
+SYNMODE m_arri = ARRAY(1:5) INT;
+DCL v_arri m_arri := [ -1, -2, -3, -4, -5 ];
+
+SYNMODE m_arrui = ARRAY(1:5) UINT;
+DCL v_arrui m_arrui := [ 1, 2, 3, 4, 5 ];
+
+SYNMODE r1 = RANGE (1:5);
+SYNMODE m_arrb = ARRAY(r1) BYTE;
+DCL v_arrb m_arrb := [ -3, -4, -5, -6, -7 ];
+
+SYNMODE m_arrub = ARRAY(r1) UBYTE;
+DCL v_arrub m_arrub := [ 3, 4, 5, 6, 7 ];
+
+SYNMODE m_arrc = ARRAY (1:5) CHAR;
+DCL v_arrc m_arrc := [ '1', '2', '3', '4', '5' ];
+
+SYNMODE m_ps = POWERSET r1;
+DCL v_ps m_ps := [ 1, 3, 5 ];
+
+DCL v_cv CHARS(20) VARYING := "foo";
+
+SYNMODE m_arrbool = ARRAY(r1) BOOL;
+DCL v_arrbool m_arrbool := [ true, false, true, false, true ];
+
+DCL j r1 := 4;
+
+DCL i INT;
+
+newmode vstruct = struct (a, b long,
+ case b of
+ (42): ch8 chars(20),
+ (52): i long
+ else ch1 char
+ esac);
+
+DCL vstr vstruct := [ .a: 10, .b: 52, .i: 100 ];
+
+i := 0;
+
+END x;
+
+setmode: MODULE /* This is from Cygnus PR chill/5024. */
+
+NEWMODE day = SET( monday, tuesday, wednesday, thursday, friday, saturday, sunday );
+NEWMODE dow = POWERSET day;
+
+DCL d day;
+DCL w dow;
+
+printdow: PROC( w dow );
+ DCL d day;
+ DO FOR d in w;
+ WRITETEXT( stdout, "%C ", d );
+ OD;
+END;
+
+d := monday;
+w := dow[monday : friday];
+printdow( w );
+
+printdow( dow[LOWER(dow) : UPPER(dow)] );
+
+END setmode;
+
+PR8643: MODULE
+
+SYNMODE m_set = SET (a, b, c, d);
+SYNMODE m_ps = POWERSET m_set;
+
+SYNMODE m_s1 = STRUCT (str CHARS(40) VARYING, i INT, ps m_ps);
+DCL vs1 m_s1;
+
+SYNMODE m_s2 = STRUCT (i LONG, s m_s1);
+DCL vs2 m_s2;
+
+SYNMODE m_arr = ARRAY (1:3) BYTE;
+SYNMODE m_s3 = STRUCT (i LONG, a m_arr);
+DCL vs3 m_s3;
+
+DCL i LONG;
+
+i := 24;
+
+END PR8643;
diff --git a/gdb/testsuite/gdb.chill/tuples.exp b/gdb/testsuite/gdb.chill/tuples.exp
new file mode 100644
index 00000000000..0efea79eaa9
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/tuples.exp
@@ -0,0 +1,161 @@
+# Copyright 1995, 1996 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile "tuples"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ runto tuples.ch:40
+
+ gdb_test_exact "print v_arri" {= [(1): -1, (2): -2, (3): -3, (4): -4, (5): -5]}
+ gdb_test_exact "set v_arri := \[ 33, 44, 55, 66, 77 \]" {}
+ gdb_test_exact "print v_arri" {= [(1): 33, (2): 44, (3): 55, (4): 66, (5): 77]} "after assignment 1 to v_arri"
+ gdb_test_exact "set v_arri := \[-33, -44, -55, -66, -77\]" {}
+ gdb_test_exact "print v_arri" {= [(1): -33, (2): -44, (3): -55, (4): -66, (5): -77]} {after assignment 2 to v_arri}
+
+ gdb_test_exact "print v_arrui" {= [(1): 1, (2): 2, (3): 3, (4): 4, (5): 5]}
+ gdb_test_exact "set v_arrui := \[ 11, 11, 11, 11, 11 \]" {}
+ gdb_test_exact "print v_arrui" {= [(1:5): 11]} "after assignment to v_arrui"
+
+ gdb_test_exact "print v_arrb" {= [(1): -3, (2): -4, (3): -5, (4): -6, (5): -7]}
+
+ gdb_test_exact "set v_arrb := \[ -9, -8, -7, -6, -5 \]" {}
+ gdb_test_exact "print v_arrb" {= [(1): -9, (2): -8, (3): -7, (4): -6, (5): -5]} "after assignment to v_arrb"
+
+ gdb_test_exact "print v_arrub" {= [(1): 3, (2): 4, (3): 5, (4): 6, (5): 7]}
+ gdb_test_exact "set v_arrub := \[ 77, 77, 77, 77, 77 \]" {}
+ gdb_test_exact "print v_arrub" {= [(1:5): 77]} "v_arrub after assignment"
+
+ gdb_test_exact "print j" {= 4}
+ gdb_test_exact "print j := 3+4" {= 7}
+ gdb_test_exact "print j := r1(3)" {= 3}
+
+ gdb_test_exact "print v_arrc" {= [(1): '1', (2): '2', (3): '3', (4): '4', (5): '5']}
+ gdb_test_exact "set v_arrc := \[ 'a', 'b', 'c', 'd', 'e' \]" {}
+ gdb_test_exact "print v_arrc" {= [(1): 'a', (2): 'b', (3): 'c', (4): 'd', (5): 'e']} "v_arrc after assignment"
+
+ gdb_test_exact "print v_ps" {= [1, 3, 5]}
+ gdb_test_exact "set v_ps := \[ 2, 4 \]" {}
+ gdb_test_exact "print v_ps" {= [2, 4]} {v_ps after assignment}
+ gdb_test_exact "print v_ps := \[\]" {= []} {assign [] to v_ps}
+
+ gdb_test_exact "print m_arri\[1, 2, 3, 4, 5\]" {= [(1): 1, (2): 2, (3): 3, (4): 4, (5): 5]}
+ gdb_test_exact "print m_arrub\[45, 46, 47, 48, 49\]" {= [(1): 45, (2): 46, (3): 47, (4): 48, (5): 49]}
+
+ gdb_test_exact "print v_cv" {= "foo"}
+ gdb_test_exact "set v_cv := \"foo-bar\"" {}
+ gdb_test_exact "print v_cv" {= "foo-bar"} "v_cv after assignment"
+ gdb_test_exact "set v_cv(3) := ' '" {}
+ gdb_test_exact "print v_cv" {= "foo bar"} "v_cv after element assignment"
+
+ gdb_test_exact "print v_arrbool" {= [(1): TRUE, (2): FALSE, (3): TRUE, (4): FALSE, (5): TRUE]}
+ gdb_test_exact "set v_arrbool := \[ false, false, false, false, false \]" {}
+ gdb_test_exact "print v_arrbool" {= [(1:5): FALSE]} "v_arrbool after assignment 1"
+ gdb_test_exact "set v_arrbool := \[true, true, true, true, true\]" {}
+ gdb_test_exact "print v_arrbool" {= [(1:5): TRUE]} "v_arrbool after assignment 2"
+ gdb_test_exact "set v_arrbool(3) := false" {}
+ gdb_test_exact "print v_arrbool" {= [(1:2): TRUE, (3): FALSE, (4:5): TRUE]} "v_arrbool after element assignment"
+
+ gdb_test_exact "set v_arrbool(1 up 2) := \[ false, true \]" {}
+ gdb_test_exact "print v_arrbool" {= [(1): FALSE, (2): TRUE, (3): FALSE, (4:5): TRUE]} "v_arrbool after slice assignment 1"
+ gdb_test_exact "set v_arrbool(3 : 5) := \[ true, true, false \]" {}
+ gdb_test_exact "print v_arrbool" {= [(1): FALSE, (2:4): TRUE, (5): FALSE]} "v_arrbool after slice assignment 2"
+
+ gdb_test_exact "set vstr := \[ .a: 2+3, .b: 12, .ch1: 'x' \]" {}
+ gdb_test_exact "print vstr.a" {= 5} "vstr.a after assignment"
+ gdb_test_exact "print vstr.ch1" {= 'x'} "vstr.ch1 after assignment"
+
+# These tests are from Cygnus PR chill/5024:
+ gdb_test "break printdow" ""
+ gdb_test "continue" ""
+ gdb_test_exact "set var w:= dow\[monday\]" {}
+ gdb_test "print w" " = \\\[monday\\\]" \
+ "print bitstring after assignment"
+ gdb_test_exact "set var w:=\[\]" {}
+ gdb_test "print w" " = \\\[\\\]" \
+ "print bitstring after assignment of \[\]"
+
+# These tests are from Cygnus PR chill/8643:
+ runto tuples.ch:40
+ gdb_test_exact "set var vs1 := \[ \"foo\", 41, \[ b \] \]" {}
+ gdb_test_exact "print vs1" { = [.str: "foo", .i: 41, .ps: [b]]} \
+ "print vs1 after tuple assign 1"
+ setup_xfail "i*86-pc-linux*-gnu" "sparc-*-solaris*" "sparc-*-sunos*"
+ gdb_test_exact "set var vs1 := \[ \"bar\", 42, m_ps\[ a \] \]" {}
+ setup_xfail "i*86-pc-linux*-gnu" "sparc-*-solaris*" "sparc-*-sunos*"
+ gdb_test_exact "print vs1" { = [.str: "bar", .i: 42, .ps: [a]]} \
+ "print vs1 after tuple assign 2"
+
+ gdb_test_exact "set var \$i := m_s1\[\"foo\", 42, \[a \]\]" {}
+ gdb_test_exact {print $i} { = [.str: "foo", .i: 42, .ps: [a]]} \
+ "print \$i after tuple assign 1"
+ setup_xfail "i*86-pc-linux*-gnu" "sparc-*-solaris*" "sparc-*-sunos*"
+ gdb_test_exact "set var \$i := m_s1\[\"foo\", 44, m_ps\[a \]\]" {}
+ setup_xfail "i*86-pc-linux*-gnu" "sparc-*-solaris*" "sparc-*-sunos*"
+ gdb_test_exact {print $i} { = [.str: "foo", .i: 44, .ps: [a]]} \
+ "print \$i after tuple assign 2"
+
+ gdb_test_exact "set var vs2 := \[ 10, \[ \"foo\" , 42, \[ b \] \] \]" {}
+ gdb_test_exact "print vs2" \
+ { = [.i: 10, .s: [.str: "foo", .i: 42, .ps: [b]]]} \
+ "print vs2 after tuple assign 1"
+ setup_xfail "i*86-pc-linux*-gnu" "sparc-*-solaris*" "sparc-*-sunos*"
+ gdb_test_exact "set var vs2 := \[ 10+3, m_s1\[ \"foo\" , 42, m_ps\[ b \] \] \]" {}
+ setup_xfail "i*86-pc-linux*-gnu" "sparc-*-solaris*" "sparc-*-sunos*"
+ gdb_test_exact "print vs2" \
+ { = [.i: 13, .s: [.str: "foo", .i: 42, .ps: [b]]]} \
+ "print vs2 after tuple assign 2"
+
+ gdb_test_exact "set var vs3 := \[ 33, \[ -1, -2, -3 \] \]" {}
+ gdb_test_exact "print vs3" {[.i: 33, .a: [(1): -1, (2): -2, (3): -3]]} \
+ "print vs3 after tuple assign"
+ gdb_test_exact "set var \$k := m_s3\[ 33, m_arr\[ 4, 3, 2 \] \]" {}
+ gdb_test_exact {print $k} { = [.i: 33, .a: [(1): 4, (2): 3, (3): 2]]} \
+ "print \$k after tuple assign"
+
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.chill/xstruct-grt.ch b/gdb/testsuite/gdb.chill/xstruct-grt.ch
new file mode 100644
index 00000000000..abd0d5ee3e4
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/xstruct-grt.ch
@@ -0,0 +1,12 @@
+pot1: MODULE
+
+SYNMODE m_array1 = ARRAY (2:3) ulong;
+SYNMODE m_struct = STRUCT (f1 int,
+ f2 REF m_array1,
+ f3 m_array1);
+SYNMODE m_array3 = ARRAY (5:6) m_struct;
+SYNMODE m_array4 = ARRAY (7:8) ARRAY (9:10) m_struct;
+
+GRANT all;
+
+END pot1;
diff --git a/gdb/testsuite/gdb.chill/xstruct.ch b/gdb/testsuite/gdb.chill/xstruct.ch
new file mode 100644
index 00000000000..d8471c849aa
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/xstruct.ch
@@ -0,0 +1,16 @@
+pottendo: MODULE
+
+<> USE_SEIZE_FILE "xstruct-grt.grt" <>
+SEIZE m_array3;
+SEIZE m_array4;
+
+SYNMODE m_x = STRUCT (i long,
+ ar m_array3);
+SYNMODE m_y = STRUCT (i long,
+ ar m_array4);
+
+DCL x LONG;
+
+x := 10;
+
+END pottendo;
diff --git a/gdb/testsuite/gdb.chill/xstruct.exp b/gdb/testsuite/gdb.chill/xstruct.exp
new file mode 100644
index 00000000000..e64fcea3005
--- /dev/null
+++ b/gdb/testsuite/gdb.chill/xstruct.exp
@@ -0,0 +1,66 @@
+# Copyright 1992, 1994, 1997, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Per Bothner. (bothner@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if [skip_chill_tests] then { continue }
+
+set testfile2 "xstruct-grt"
+set srcfile2 ${srcdir}/$subdir/${testfile2}.ch
+set objfile2 ${objdir}/$subdir/${testfile2}.o
+if { [compile "${srcfile2} -g -c -o ${objfile2}"] != "" } {
+ perror "Couldn't compile ${srcfile2}"
+ return -1
+}
+
+set testfile "xstruct"
+set srcfile ${srcdir}/$subdir/${testfile}.ch
+set binfile ${objdir}/${subdir}/${testfile}.exe
+if { [compile "${srcfile} -g ${objfile2} -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+proc do_tests {} {
+ global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+ gdb_test "set language chill" ""
+
+ gdb_test "set var \$i := m_x\[\]" ""
+ gdb_test "print \$i" { = \[.i: 0, .ar: \[\(5:6\): \[.f1: 0, .f2: NULL, .f3: \[\(2:3\): 0\]\]\]\]}
+
+ gdb_test "set var \$j := m_y\[\]" ""
+ gdb_test "print \$j" { = \[.i: 0, .ar: \[\(7:8\): \[\(9:10\): \[.f1: 0, .f2: NULL, .f3: \[\(2:3\): 0\]\]\]\]\]}
+}
+
+do_tests
diff --git a/gdb/testsuite/gdb.disasm/Makefile.in b/gdb/testsuite/gdb.disasm/Makefile.in
new file mode 100644
index 00000000000..7bb5eef69c4
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/Makefile.in
@@ -0,0 +1,18 @@
+#### host, target, and site specific Makefile frags come in here.
+
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+.PHONY: all clean mostlyclean distclean realclean
+
+all:
+ @echo "Nothing to be done for all..."
+
+clean mostlyclean:
+ -rm -f *.o *.diff *~ *.bad core h8300s hppa mn10200 mn10300 sh3
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
+
+Makefile: $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.disasm/am33.exp b/gdb/testsuite/gdb.disasm/am33.exp
new file mode 100644
index 00000000000..c020fac88fe
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/am33.exp
@@ -0,0 +1,838 @@
+
+# Copyright 1997, 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Jeff Law. (law@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if ![istarget "mn10300*-*-*"] {
+ verbose "Tests ignored for all but mn10300 based targets."
+ return
+}
+
+global exec_output
+set prms_id 0
+set bug_id 0
+
+set testfile "am33"
+set srcfile ${srcdir}/${subdir}/${testfile}.s
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcfile}" "${binfile}" object ""] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+proc call_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/8i call_tests\n"
+ gdb_expect {
+ -re "
+.*call .*,.a2,a3,exreg0.,9.*
+.*call .*,.a2,a3,exreg1.,9.*
+.*call .*,.a2,a3,exother.,9.*
+.*call .*,.d2,d3,a2,a3,other,exreg0,exreg1,exother.,9.*
+.*call .*,.a2,a3,exreg0.,9.*
+.*call .*,.a2,a3,exreg1.,9.*
+.*call .*,.a2,a3,exother.,9.*
+.*call .*,.d2,d3,a2,a3,other,exreg0,exreg1,exother.,9.*
+.*$gdb_prompt $" { pass "call tests" }
+ -re "$gdb_prompt $" { fail "call tests" }
+ timeout { fail "(timeout) call tests" }
+ }
+}
+
+proc movm_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/16i movm_tests\n"
+ gdb_expect {
+ -re "
+.*movm \\(sp\\),.a2,a3,exreg0.*
+.*movm \\(sp\\),.a2,a3,exreg1.*
+.*movm \\(sp\\),.a2,a3,exother.*
+.*movm \\(sp\\),.d2,d3,a2,a3,other,exreg0,exreg1,exother.*
+.*movm .a2,a3,exreg0.,\\(sp\\).*
+.*movm .a2,a3,exreg1.,\\(sp\\).*
+.*movm .a2,a3,exother.,\\(sp\\).*
+.*movm .d2,d3,a2,a3,other,exreg0,exreg1,exother.,\\(sp\\).*
+.*movm \\(usp\\),.a2,a3,exreg0.*
+.*movm \\(usp\\),.a2,a3,exreg1.*
+.*movm \\(usp\\),.a2,a3,exother.*
+.*movm \\(usp\\),.d2,d3,a2,a3,other,exreg0,exreg1,exother.*
+.*movm .a2,a3,exreg0.,\\(usp\\).*
+.*movm .a2,a3,exreg1.,\\(usp\\).*
+.*movm .a2,a3,exother.,\\(usp\\).*
+.*movm .d2,d3,a2,a3,other,exreg0,exreg1,exother.,\\(usp\\).*
+.*$gdb_prompt $" { pass "movm tests" }
+ -re "$gdb_prompt $" { fail "movm tests" }
+ timeout { fail "(timeout) movm tests" }
+ }
+}
+
+proc misc_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/11i misc_tests\n"
+ gdb_expect {
+ -re "
+.*syscall 4.*
+.*mcst9 d0.*
+.*mcst48 d1.*
+.*getchx d0.*
+.*getclx d1.*
+.*clr a1.*
+.*sat16 a1,a0.*
+.*mcste r7,r6.*
+.*swap r5,r4.*
+.*swaph r3,r2.*
+.*swhw r1,r0.*
+.*$gdb_prompt $" { pass "misc tests" }
+ -re "$gdb_prompt $" { fail "misc tests" }
+ timeout { fail "(timeout) misc tests" }
+ }
+}
+
+proc mov_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/45i mov_tests\n"
+ gdb_expect {
+ -re "
+.*mov r0,r1.*
+.*mov sp,r1.*
+.*mov r1,xr2.*
+.*mov \\(r1\\),r2.*
+.*mov r3,\\(r4\\).*
+.*mov \\(sp\\),r5.*
+.*mov r6,\\(sp\\).*
+.*mov 16,r1.*
+.*mov 16,xr1.*
+.*mov \\(16,r1\\),r2.*
+.*mov r2,\\(16,r1\\).*
+.*mov \\(16,sp\\),r2.*
+.*mov r2,\\(16,sp\\).*
+.*mov 2096895,r2.*
+.*mov 2096895,xr2.*
+.*mov \\(2096895,r1\\),r2.*
+.*mov r2,\\(2096895,r1\\).*
+.*mov \\(2096895,sp\\),r2.*
+.*mov r2,\\(2096895,sp\\).*
+.*mov \\(0x1ffeff\\),r2.*
+.*mov r2,\\(0x1ffeff\\).*
+.*mov 2147417596,r2.*
+.*mov 2147417596,xr2.*
+.*mov \\(2147417596,r1\\),r2.*
+.*mov r2,\\(2147417596,r1\\).*
+.*mov \\(2147417596,sp\\),r2.*
+.*mov r2,\\(2147417596,sp\\).*
+.*mov \\(0x7ffefdfc\\),r2.*
+.*mov r2,\\(0x7ffefdfc\\).*
+.*movu 16,r1.*
+.*movu 2096895,r2.*
+.*movu 2147417596,r2.*
+.*mov usp,a0.*
+.*mov ssp,a1.*
+.*mov msp,a2.*
+.*mov pc,a3.*
+.*mov a0,usp.*
+.*mov a1,ssp.*
+.*mov a2,msp.*
+.*mov epsw,d0.*
+.*mov d1,epsw.*
+.*mov a0,r1.*
+.*mov d2,r3.*
+.*mov r5,a1.*
+.*mov r7,d3.*
+.*$gdb_prompt $" { pass "mov tests" }
+ -re "$gdb_prompt $" { fail "mov tests" }
+ timeout { fail "(timeout) mov tests" }
+ }
+}
+
+proc ext_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/5i ext_tests\n"
+ gdb_expect {
+ -re "
+.*ext r2.*
+.*extb r3,r4.*
+.*extbu r4,r5.*
+.*exth r6,r7.*
+.*exthu r7,a0.*
+.*$gdb_prompt $" { pass "ext tests" }
+ -re "$gdb_prompt $" { fail "ext tests" }
+ timeout { fail "(timeout) ext tests" }
+ }
+}
+
+proc add_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/11i add_tests\n"
+ gdb_expect {
+ -re "
+.*add a2,a3.*
+.*add 16,r1.*
+.*add 2096895,r2.*
+.*add 2147417596,r2.*
+.*add r1,r2,r3.*
+.*addc d0,d1.*
+.*addc 16,r1.*
+.*addc 2096895,r2.*
+.*addc 2147417596,r2.*
+.*inc d1.*
+.*inc4 d0.*
+.*$gdb_prompt $" { pass "add tests" }
+ -re "$gdb_prompt $" { fail "add tests" }
+ timeout { fail "(timeout) add tests" }
+ }
+}
+
+proc sub_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/8i sub_tests\n"
+ gdb_expect {
+ -re "
+.*sub d2,d3.*
+.*sub 16,r1.*
+.*sub 2096895,r2.*
+.*sub 2147417596,r2.*
+.*subc d3,d2.*
+.*subc 16,r1.*
+.*subc 2096895,r2.*
+.*subc 2147417596,r2.*
+.*$gdb_prompt $" { pass "sub tests" }
+ -re "$gdb_prompt $" { fail "sub tests" }
+ timeout { fail "(timeout) sub tests" }
+ }
+}
+
+proc cmp_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/4i cmp_tests\n"
+ gdb_expect {
+ -re "
+.*cmp a3,a2.*
+.*cmp 16,r1.*
+.*cmp 2096895,r2.*
+.*cmp 2147417596,r2.*
+.*$gdb_prompt $" { pass "cmp tests" }
+ -re "$gdb_prompt $" { fail "cmp tests" }
+ timeout { fail "(timeout) cmp tests" }
+ }
+}
+
+proc logical_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/15i logical_tests\n"
+ gdb_expect {
+ -re "
+.*and r0,r1.*
+.*or r2,r3.*
+.*xor r4,r5.*
+.*not r6.*
+.*and 16,r1.*
+.*or 16,r1.*
+.*xor 16,r1.*
+.*and 2096895,r2.*
+.*or 2096895,r2.*
+.*xor 2096895,r2.*
+.*and 2147417596,r2.*
+.*or 2147417596,r2.*
+.*xor 2147417596,r2.*
+.*and 131072,epsw.*
+.*or 65535,epsw.*
+.*$gdb_prompt $" { pass "logical tests" }
+ -re "$gdb_prompt $" { fail "logical tests" }
+ timeout { fail "(timeout) logical tests" }
+ }
+}
+
+proc shift_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/15i shift_tests\n"
+ gdb_expect {
+ -re "
+.*asr r7,a0.*
+.*lsr a1,a2.*
+.*asl a3,d0.*
+.*asl2 d1.*
+.*ror d2.*
+.*rol d3.*
+.*asr 16,r1.*
+.*lsr 16,r1.*
+.*asl 16,r1.*
+.*asr 2096895,r2.*
+.*lsr 2096895,r2.*
+.*asl 2096895,r2.*
+.*asr 2147417596,r2.*
+.*lsr 2147417596,r2.*
+.*asl 2147417596,r2.*
+.*$gdb_prompt $" { pass "shift tests" }
+ -re "$gdb_prompt $" { fail "shift tests" }
+ timeout { fail "(timeout) shift tests" }
+ }
+}
+
+proc muldiv_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/16i muldiv_tests\n"
+ gdb_expect {
+ -re "
+.*mul r1,r2.*
+.*mulu r3,r4.*
+.*mul 16,r1.*
+.*mulu 16,r1.*
+.*mul 2096895,r2.*
+.*mulu 2096895,r2.*
+.*mul 2147417596,r2.*
+.*mulu 2147417596,r2.*
+.*div r5,r6.*
+.*divu r7,a0.*
+.*dmulh d1,d0.*
+.*dmulhu a3,a2.*
+.*dmulh 2147417596,r2.*
+.*dmulhu 2147417596,r2.*
+.*mul r1,r2,r3,r4.*
+.*mulu r1,r2,r3,r4.*
+.*$gdb_prompt $" { pass "muldiv tests" }
+ -re "$gdb_prompt $" { fail "muldiv tests" }
+ timeout { fail "(timeout) muldiv tests" }
+ }
+}
+
+proc movbu_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/20i movbu_tests\n"
+ gdb_expect {
+ -re "
+.*movbu \\(r5\\),r6.*
+.*movbu r7,\\(a0\\).*
+.*movbu \\(sp\\),r7.*
+.*movbu a0,\\(sp\\).*
+.*movbu \\(16,r1\\),r2.*
+.*movbu r2,\\(16,r1\\).*
+.*movbu \\(16,sp\\),r2.*
+.*movbu r2,\\(16,sp\\).*
+.*movbu \\(2096895,r1\\),r2.*
+.*movbu r2,\\(2096895,r1\\).*
+.*movbu \\(2096895,sp\\),r2.*
+.*movbu r2,\\(2096895,sp\\).*
+.*movbu \\(0x1ffeff\\),r2.*
+.*movbu r2,\\(0x1ffeff\\).*
+.*movbu \\(2147417596,r1\\),r2.*
+.*movbu r2,\\(2147417596,r1\\).*
+.*movbu \\(2147417596,sp\\),r2.*
+.*movbu r2,\\(2147417596,sp\\).*
+.*movbu \\(0x7ffefdfc\\),r2.*
+.*movbu r2,\\(0x7ffefdfc\\).*
+.*$gdb_prompt $" { pass "movbu tests" }
+ -re "$gdb_prompt $" { fail "movbu tests" }
+ timeout { fail "(timeout) movbu tests" }
+ }
+}
+
+proc movhu_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/20i movhu_tests\n"
+ gdb_expect {
+ -re "
+.*movhu \\(a1\\),a2.*
+.*movhu a3,\\(d0\\).*
+.*movhu \\(sp\\),a1.*
+.*movhu a2,\\(sp\\).*
+.*movhu \\(16,r1\\),r2.*
+.*movhu r2,\\(16,r1\\).*
+.*movhu \\(16,sp\\),r2.*
+.*movhu r2,\\(16,sp\\).*
+.*movhu \\(2096895,r1\\),r2.*
+.*movhu r2,\\(2096895,r1\\).*
+.*movhu \\(2096895,sp\\),r2.*
+.*movhu r2,\\(2096895,sp\\).*
+.*movhu \\(0x1ffeff\\),r2.*
+.*movhu r2,\\(0x1ffeff\\).*
+.*movhu \\(2147417596,r1\\),r2.*
+.*movhu r2,\\(2147417596,r1\\).*
+.*movhu \\(2147417596,sp\\),r2.*
+.*movhu r2,\\(2147417596,sp\\).*
+.*movhu \\(0x7ffefdfc\\),r2.*
+.*movhu r2,\\(0x7ffefdfc\\).*
+.*$gdb_prompt $" { pass "movhu tests" }
+ -re "$gdb_prompt $" { fail "movhu tests" }
+ timeout { fail "(timeout) movhu tests" }
+ }
+}
+
+proc mac_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/28i mac_tests\n"
+ gdb_expect {
+ -re "
+.*mac r1,r2.*
+.*macu r3,r4.*
+.*macb r5,r6.*
+.*macbu r7,a0.*
+.*mach a1,a2.*
+.*machu a3,d0.*
+.*dmach d1,d2.*
+.*dmachu d3,d2.*
+.*mac 16,r1.*
+.*macu 16,r1.*
+.*macb 16,r1.*
+.*macbu 16,r1.*
+.*mach 16,r1.*
+.*machu 16,r1.*
+.*mac 2096895,r2.*
+.*macu 2096895,r2.*
+.*macb 2096895,r2.*
+.*macbu 2096895,r2.*
+.*mach 2096895,r2.*
+.*machu 2096895,r2.*
+.*mac 2147417596,r2.*
+.*macu 2147417596,r2.*
+.*macb 2147417596,r2.*
+.*macbu 2147417596,r2.*
+.*mach 2147417596,r2.*
+.*machu 2147417596,r2.*
+.*dmach 2147417596,r2.*
+.*dmachu 2147417596,r2.*
+.*$gdb_prompt $" { pass "mac tests" }
+ -re "$gdb_prompt $" { fail "mac tests" }
+ timeout { fail "(timeout) mac tests" }
+ }
+}
+
+proc bit_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/4i bit_tests\n"
+ gdb_expect {
+ -re "
+.*bsch r1,r2.*
+.*btst 16,r1.*
+.*btst 2096895,r2.*
+.*btst 2147417596,r2.*
+.*$gdb_prompt $" { pass "bit tests" }
+ -re "$gdb_prompt $" { fail "bit tests" }
+ timeout { fail "(timeout) bit tests" }
+ }
+}
+
+proc dsp_add_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/28i dsp_add_tests\n"
+ gdb_expect {
+ -re "
+.*add_add r4,r1,r2,r3.*
+.*add_add r4,r1,2,r3.*
+.*add_sub r4,r1,r2,r3.*
+.*add_sub r4,r1,2,r3.*
+.*add_cmp r4,r1,r2,r3.*
+.*add_cmp r4,r1,2,r3.*
+.*add_mov r4,r1,r2,r3.*
+.*add_mov r4,r1,2,r3.*
+.*add_asr r4,r1,r2,r3.*
+.*add_asr r4,r1,2,r3.*
+.*add_lsr r4,r1,r2,r3.*
+.*add_lsr r4,r1,2,r3.*
+.*add_asl r4,r1,r2,r3.*
+.*add_asl r4,r1,2,r3.*
+.*add_add 4,r1,r2,r3.*
+.*add_add 4,r1,2,r3.*
+.*add_sub 4,r1,r2,r3.*
+.*add_sub 4,r1,2,r3.*
+.*add_cmp 4,r1,r2,r3.*
+.*add_cmp 4,r1,2,r3.*
+.*add_mov 4,r1,r2,r3.*
+.*add_mov 4,r1,2,r3.*
+.*add_asr 4,r1,r2,r3.*
+.*add_asr 4,r1,2,r3.*
+.*add_lsr 4,r1,r2,r3.*
+.*add_lsr 4,r1,2,r3.*
+.*add_asl 4,r1,r2,r3.*
+.*add_asl 4,r1,2,r3.*
+.*$gdb_prompt $" { pass "dsp_add tests" }
+ -re "$gdb_prompt $" { fail "dsp_add tests" }
+ timeout { fail "(timeout) dsp_add tests" }
+ }
+}
+
+proc dsp_cmp_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/24i dsp_cmp_tests\n"
+ gdb_expect {
+ -re "
+.*cmp_add r4,r1,r2,r3.*
+.*cmp_add r4,r1,2,r3.*
+.*cmp_sub r4,r1,r2,r3.*
+.*cmp_sub r4,r1,2,r3.*
+.*cmp_mov r4,r1,r2,r3.*
+.*cmp_mov r4,r1,2,r3.*
+.*cmp_asr r4,r1,r2,r3.*
+.*cmp_asr r4,r1,2,r3.*
+.*cmp_lsr r4,r1,r2,r3.*
+.*cmp_lsr r4,r1,2,r3.*
+.*cmp_asl r4,r1,r2,r3.*
+.*cmp_asl r4,r1,2,r3.*
+.*cmp_add 4,r1,r2,r3.*
+.*cmp_add 4,r1,2,r3.*
+.*cmp_sub 4,r1,r2,r3.*
+.*cmp_sub 4,r1,2,r3.*
+.*cmp_mov 4,r1,r2,r3.*
+.*cmp_mov 4,r1,2,r3.*
+.*cmp_asr 4,r1,r2,r3.*
+.*cmp_asr 4,r1,2,r3.*
+.*cmp_lsr 4,r1,r2,r3.*
+.*cmp_lsr 4,r1,2,r3.*
+.*cmp_asl 4,r1,r2,r3.*
+.*cmp_asl 4,r1,2,r3.*
+.*$gdb_prompt $" { pass "dsp_cmp tests" }
+ -re "$gdb_prompt $" { fail "dsp_cmp tests" }
+ timeout { fail "(timeout) dsp_cmp tests" }
+ }
+}
+
+proc dsp_sub_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/28i dsp_sub_tests\n"
+ gdb_expect {
+ -re "
+.*sub_add r4,r1,r2,r3.*
+.*sub_add r4,r1,2,r3.*
+.*sub_sub r4,r1,r2,r3.*
+.*sub_sub r4,r1,2,r3.*
+.*sub_cmp r4,r1,r2,r3.*
+.*sub_cmp r4,r1,2,r3.*
+.*sub_mov r4,r1,r2,r3.*
+.*sub_mov r4,r1,2,r3.*
+.*sub_asr r4,r1,r2,r3.*
+.*sub_asr r4,r1,2,r3.*
+.*sub_lsr r4,r1,r2,r3.*
+.*sub_lsr r4,r1,2,r3.*
+.*sub_asl r4,r1,r2,r3.*
+.*sub_asl r4,r1,2,r3.*
+.*sub_add 4,r1,r2,r3.*
+.*sub_add 4,r1,2,r3.*
+.*sub_sub 4,r1,r2,r3.*
+.*sub_sub 4,r1,2,r3.*
+.*sub_cmp 4,r1,r2,r3.*
+.*sub_cmp 4,r1,2,r3.*
+.*sub_mov 4,r1,r2,r3.*
+.*sub_mov 4,r1,2,r3.*
+.*sub_asr 4,r1,r2,r3.*
+.*sub_asr 4,r1,2,r3.*
+.*sub_lsr 4,r1,r2,r3.*
+.*sub_lsr 4,r1,2,r3.*
+.*sub_asl 4,r1,r2,r3.*
+.*sub_asl 4,r1,2,r3.*
+.*$gdb_prompt $" { pass "dsp_sub tests" }
+ -re "$gdb_prompt $" { fail "dsp_sub tests" }
+ timeout { fail "(timeout) dsp_sub tests" }
+ }
+}
+
+proc dsp_mov_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/28i dsp_mov_tests\n"
+ gdb_expect {
+ -re "
+.*mov_add r4,r1,r2,r3.*
+.*mov_add r4,r1,2,r3.*
+.*mov_sub r4,r1,r2,r3.*
+.*mov_sub r4,r1,2,r3.*
+.*mov_cmp r4,r1,r2,r3.*
+.*mov_cmp r4,r1,2,r3.*
+.*mov_mov r4,r1,r2,r3.*
+.*mov_mov r4,r1,2,r3.*
+.*mov_asr r4,r1,r2,r3.*
+.*mov_asr r4,r1,2,r3.*
+.*mov_lsr r4,r1,r2,r3.*
+.*mov_lsr r4,r1,2,r3.*
+.*mov_asl r4,r1,r2,r3.*
+.*mov_asl r4,r1,2,r3.*
+.*mov_add 4,r1,r2,r3.*
+.*mov_add 4,r1,2,r3.*
+.*mov_sub 4,r1,r2,r3.*
+.*mov_sub 4,r1,2,r3.*
+.*mov_cmp 4,r1,r2,r3.*
+.*mov_cmp 4,r1,2,r3.*
+.*mov_mov 4,r1,r2,r3.*
+.*mov_mov 4,r1,2,r3.*
+.*mov_asr 4,r1,r2,r3.*
+.*mov_asr 4,r1,2,r3.*
+.*mov_lsr 4,r1,r2,r3.*
+.*mov_lsr 4,r1,2,r3.*
+.*mov_asl 4,r1,r2,r3.*
+.*mov_asl 4,r1,2,r3.*
+.*$gdb_prompt $" { pass "dsp_mov tests" }
+ -re "$gdb_prompt $" { fail "dsp_mov tests" }
+ timeout { fail "(timeout) dsp_mov tests" }
+ }
+}
+
+proc dsp_logical_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/42i dsp_logical_tests\n"
+ gdb_expect {
+ -re "
+.*and_add r4,r1,r2,r3.*
+.*and_add r4,r1,2,r3.*
+.*and_sub r4,r1,r2,r3.*
+.*and_sub r4,r1,2,r3.*
+.*and_cmp r4,r1,r2,r3.*
+.*and_cmp r4,r1,2,r3.*
+.*and_mov r4,r1,r2,r3.*
+.*and_mov r4,r1,2,r3.*
+.*and_asr r4,r1,r2,r3.*
+.*and_asr r4,r1,2,r3.*
+.*and_lsr r4,r1,r2,r3.*
+.*and_lsr r4,r1,2,r3.*
+.*and_asl r4,r1,r2,r3.*
+.*and_asl r4,r1,2,r3.*
+.*xor_add r4,r1,r2,r3.*
+.*xor_add r4,r1,2,r3.*
+.*xor_sub r4,r1,r2,r3.*
+.*xor_sub r4,r1,2,r3.*
+.*xor_cmp r4,r1,r2,r3.*
+.*xor_cmp r4,r1,2,r3.*
+.*xor_mov r4,r1,r2,r3.*
+.*xor_mov r4,r1,2,r3.*
+.*xor_asr r4,r1,r2,r3.*
+.*xor_asr r4,r1,2,r3.*
+.*xor_lsr r4,r1,r2,r3.*
+.*xor_lsr r4,r1,2,r3.*
+.*xor_asl r4,r1,r2,r3.*
+.*xor_asl r4,r1,2,r3.*
+.*or_add r4,r1,r2,r3.*
+.*or_add r4,r1,2,r3.*
+.*or_sub r4,r1,r2,r3.*
+.*or_sub r4,r1,2,r3.*
+.*or_cmp r4,r1,r2,r3.*
+.*or_cmp r4,r1,2,r3.*
+.*or_mov r4,r1,r2,r3.*
+.*or_mov r4,r1,2,r3.*
+.*or_asr r4,r1,r2,r3.*
+.*or_asr r4,r1,2,r3.*
+.*or_lsr r4,r1,r2,r3.*
+.*or_lsr r4,r1,2,r3.*
+.*or_asl r4,r1,r2,r3.*
+.*or_asl r4,r1,2,r3.*
+.*$gdb_prompt $" { pass "dsp_logical tests" }
+ -re "$gdb_prompt $" { fail "dsp_logical tests" }
+ timeout { fail "(timeout) dsp_logical tests" }
+ }
+}
+
+proc dsp_misc_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/42i dsp_misc_tests\n"
+ gdb_expect {
+ -re "
+.*dmach_add r4,r1,r2,r3.*
+.*dmach_add r4,r1,2,r3.*
+.*dmach_sub r4,r1,r2,r3.*
+.*dmach_sub r4,r1,2,r3.*
+.*dmach_cmp r4,r1,r2,r3.*
+.*dmach_cmp r4,r1,2,r3.*
+.*dmach_mov r4,r1,r2,r3.*
+.*dmach_mov r4,r1,2,r3.*
+.*dmach_asr r4,r1,r2,r3.*
+.*dmach_asr r4,r1,2,r3.*
+.*dmach_lsr r4,r1,r2,r3.*
+.*dmach_lsr r4,r1,2,r3.*
+.*dmach_asl r4,r1,r2,r3.*
+.*dmach_asl r4,r1,2,r3.*
+.*swhw_add r4,r1,r2,r3.*
+.*swhw_add r4,r1,2,r3.*
+.*swhw_sub r4,r1,r2,r3.*
+.*swhw_sub r4,r1,2,r3.*
+.*swhw_cmp r4,r1,r2,r3.*
+.*swhw_cmp r4,r1,2,r3.*
+.*swhw_mov r4,r1,r2,r3.*
+.*swhw_mov r4,r1,2,r3.*
+.*swhw_asr r4,r1,r2,r3.*
+.*swhw_asr r4,r1,2,r3.*
+.*swhw_lsr r4,r1,r2,r3.*
+.*swhw_lsr r4,r1,2,r3.*
+.*swhw_asl r4,r1,r2,r3.*
+.*swhw_asl r4,r1,2,r3.*
+.*sat16_add r4,r1,r2,r3.*
+.*sat16_add r4,r1,2,r3.*
+.*sat16_sub r4,r1,r2,r3.*
+.*sat16_sub r4,r1,2,r3.*
+.*sat16_cmp r4,r1,r2,r3.*
+.*sat16_cmp r4,r1,2,r3.*
+.*sat16_mov r4,r1,r2,r3.*
+.*sat16_mov r4,r1,2,r3.*
+.*sat16_asr r4,r1,r2,r3.*
+.*sat16_asr r4,r1,2,r3.*
+.*sat16_lsr r4,r1,r2,r3.*
+.*sat16_lsr r4,r1,2,r3.*
+.*sat16_asl r4,r1,r2,r3.*
+.*sat16_asl r4,r1,2,r3.*
+.*$gdb_prompt $" { pass "dsp_misc tests" }
+ -re "$gdb_prompt $" { fail "dsp_misc tests" }
+ timeout { fail "(timeout) dsp_misc tests" }
+ }
+}
+
+proc autoincrement_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/16i autoincrement_tests\n"
+ gdb_expect {
+ -re "
+.*mov \\(r1\\+\\),r2.*
+.*mov r3,\\(r4\\+\\).*
+.*movhu \\(r6\\+\\),r7.*
+.*movhu a0,\\(a1\\+\\).*
+.*mov \\(r1\\+,64\\),r2.*
+.*mov r1,\\(r2\\+,64\\).*
+.*movhu \\(r1\\+,64\\),r2.*
+.*movhu r1,\\(r2\\+,64\\).*
+.*mov \\(r1\\+,131055\\),r2.*
+.*mov r1,\\(r2\\+,131055\\).*
+.*movhu \\(r1\\+,131055\\),r2.*
+.*movhu r1,\\(r2\\+,131055\\).*
+.*mov \\(r1\\+,2147417596\\),r2.*
+.*mov r1,\\(r2\\+,2147417596\\).*
+.*movhu \\(r1\\+,2147417596\\),r2.*
+.*movhu r1,\\(r2\\+,2147417596\\).*
+.*$gdb_prompt $" { pass "autoincrement tests" }
+ -re "$gdb_prompt $" { fail "autoincrement tests" }
+ timeout { fail "(timeout) autoincrement tests" }
+ }
+}
+
+proc dsp_autoincrement_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/11i dsp_autoincrement_tests\n"
+ gdb_expect {
+ -re "
+.*mov_llt \\(r1\\+,4\\),r2.*
+.*mov_lgt \\(r1\\+,4\\),r2.*
+.*mov_lge \\(r1\\+,4\\),r2.*
+.*mov_lle \\(r1\\+,4\\),r2.*
+.*mov_lcs \\(r1\\+,4\\),r2.*
+.*mov_lhi \\(r1\\+,4\\),r2.*
+.*mov_lcc \\(r1\\+,4\\),r2.*
+.*mov_lls \\(r1\\+,4\\),r2.*
+.*mov_leq \\(r1\\+,4\\),r2.*
+.*mov_lne \\(r1\\+,4\\),r2.*
+.*mov_lra \\(r1\\+,4\\),r2.*
+.*$gdb_prompt $" { pass "autoincrement tests" }
+ -re "$gdb_prompt $" { fail "autoincrement tests" }
+ timeout { fail "(timeout) autoincrement tests" }
+ }
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+call_tests
+movm_tests
+misc_tests
+mov_tests
+ext_tests
+add_tests
+sub_tests
+cmp_tests
+logical_tests
+shift_tests
+muldiv_tests
+movbu_tests
+movhu_tests
+mac_tests
+bit_tests
+dsp_add_tests
+dsp_cmp_tests
+dsp_sub_tests
+dsp_mov_tests
+dsp_logical_tests
+autoincrement_tests
+dsp_autoincrement_tests
diff --git a/gdb/testsuite/gdb.disasm/am33.s b/gdb/testsuite/gdb.disasm/am33.s
new file mode 100644
index 00000000000..a686cef2f74
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/am33.s
@@ -0,0 +1,524 @@
+
+ .globl _main
+ .globl call_tests
+ .globl movm_tests
+ .globl misc_tests
+ .globl mov_tests
+ .globl ext_tests
+ .globl add_tests
+ .globl sub_tests
+ .globl cmp_tests
+ .globl logical_tests
+ .globl shift_tests
+ .globl muldiv_tests
+ .globl movbu_tests
+ .globl movhu_tests
+ .globl mac_tests
+ .globl bit_tests
+ .globl dsp_add_tests
+ .globl dsp_cmp_tests
+ .globl dsp_sub_tests
+ .globl dsp_mov_tests
+ .globl dsp_logical_tests
+ .globl dsp_misc_tests
+ .globl autoincrement_tests
+ .globl dsp_autoincrement_tests
+
+ .text
+ .am33
+_main:
+call_tests:
+ call 256,[a2,a3,exreg0],9
+ call 256,[a2,a3,exreg1],9
+ call 256,[a2,a3,exother],9
+ call 256,[a2,a3,all],9
+ call 131071,[a2,a3,exreg0],9
+ call 131071,[a2,a3,exreg1],9
+ call 131071,[a2,a3,exother],9
+ call 131071,[a2,a3,all],9
+
+movm_tests:
+ movm (sp),[a2,a3,exreg0]
+ movm (sp),[a2,a3,exreg1]
+ movm (sp),[a2,a3,exother]
+ movm (sp),[a2,a3,all]
+ movm [a2,a3,exreg0],(sp)
+ movm [a2,a3,exreg1],(sp)
+ movm [a2,a3,exother],(sp)
+ movm [a2,a3,all],(sp)
+ movm (usp),[a2,a3,exreg0]
+ movm (usp),[a2,a3,exreg1]
+ movm (usp),[a2,a3,exother]
+ movm (usp),[a2,a3,all]
+ movm [a2,a3,exreg0],(usp)
+ movm [a2,a3,exreg1],(usp)
+ movm [a2,a3,exother],(usp)
+ movm [a2,a3,all],(usp)
+
+misc_tests:
+ syscall 0x4
+ mcst9 d0
+ mcst48 d1
+ getchx d0
+ getclx d1
+ clr r9
+ sat16 r9,r8
+ mcste r7,r6
+ swap r5,r4
+ swaph r3,r2
+ swhw r1,r0
+
+
+mov_tests:
+ mov r0,r1
+ mov xr0, r1
+ mov r1, xr2
+ mov (r1),r2
+ mov r3,(r4)
+ mov (sp),r5
+ mov r6,(sp)
+ mov 16,r1
+ mov 16,xr1
+ mov (16,r1),r2
+ mov r2,(16,r1)
+ mov (16,sp),r2
+ mov r2,(16,sp)
+ mov 0x1ffeff,r2
+ mov 0x1ffeff,xr2
+ mov (0x1ffeff,r1),r2
+ mov r2,(0x1ffeff,r1)
+ mov (0x1ffeff,sp),r2
+ mov r2,(0x1ffeff,sp)
+ mov (0x1ffeff),r2
+ mov r2,(0x1ffeff)
+ mov 0x7ffefdfc,r2
+ mov 0x7ffefdfc,xr2
+ mov (0x7ffefdfc,r1),r2
+ mov r2,(0x7ffefdfc,r1)
+ mov (0x7ffefdfc,sp),r2
+ mov r2,(0x7ffefdfc,sp)
+ mov (0x7ffefdfc),r2
+ mov r2,(0x7ffefdfc)
+ movu 16,r1
+ movu 0x1ffeff,r2
+ movu 0x7ffefdfc,r2
+ mov usp,a0
+ mov ssp,a1
+ mov msp,a2
+ mov pc,a3
+ mov a0,usp
+ mov a1,ssp
+ mov a2,msp
+ mov epsw,d0
+ mov d1,epsw
+ mov a0,r1
+ mov d2,r3
+ mov r5,a1
+ mov r7,d3
+
+ext_tests:
+ ext r2
+ extb r3,r4
+ extbu r4,r5
+ exth r6,r7
+ exthu r7,r8
+
+add_tests:
+ add r10,r11
+ add 16,r1
+ add 0x1ffeff,r2
+ add 0x7ffefdfc,r2
+ add r1,r2,r3
+ addc r12,r13
+ addc 16,r1
+ addc 0x1ffeff,r2
+ addc 0x7ffefdfc,r2
+ inc r13
+ inc4 r12
+
+
+sub_tests:
+ sub r14,r15
+ sub 16,r1
+ sub 0x1ffeff,r2
+ sub 0x7ffefdfc,r2
+ subc r15,r14
+ subc 16,r1
+ subc 0x1ffeff,r2
+ subc 0x7ffefdfc,r2
+
+cmp_tests:
+ cmp r11,r10
+ cmp 16,r1
+ cmp 0x1ffeff,r2
+ cmp 0x7ffefdfc,r2
+
+logical_tests:
+ and r0,r1
+ or r2,r3
+ xor r4,r5
+ not r6
+ and 16,r1
+ or 16,r1
+ xor 16,r1
+ and 0x1ffeff,r2
+ or 0x1ffeff,r2
+ xor 0x1ffeff,r2
+ and 0x7ffefdfc,r2
+ or 0x7ffefdfc,r2
+ xor 0x7ffefdfc,r2
+ and 131072,epsw
+ or 65535,epsw
+
+shift_tests:
+ asr r7,r8
+ lsr r9,r10
+ asl r11,r12
+ asl2 r13
+ ror r14
+ rol r15
+ asr 16,r1
+ lsr 16,r1
+ asl 16,r1
+ asr 0x1ffeff,r2
+ lsr 0x1ffeff,r2
+ asl 0x1ffeff,r2
+ asr 0x7ffefdfc,r2
+ lsr 0x7ffefdfc,r2
+ asl 0x7ffefdfc,r2
+
+muldiv_tests:
+ mul r1,r2
+ mulu r3,r4
+ mul 16,r1
+ mulu 16,r1
+ mul 0x1ffeff,r2
+ mulu 0x1ffeff,r2
+ mul 0x7ffefdfc,r2
+ mulu 0x7ffefdfc,r2
+ div r5,r6
+ divu r7,r8
+ dmulh r13,r12
+ dmulhu r11,r10
+ dmulh 0x7ffefdfc,r2
+ dmulhu 0x7ffefdfc,r2
+ mul r1,r2,r3,r4
+ mulu r1,r2,r3,r4
+
+movbu_tests:
+ movbu (r5),r6
+ movbu r7,(r8)
+ movbu (sp),r7
+ movbu r8,(sp)
+ movbu (16,r1),r2
+ movbu r2,(16,r1)
+ movbu (16,sp),r2
+ movbu r2,(16,sp)
+ movbu (0x1ffeff,r1),r2
+ movbu r2,(0x1ffeff,r1)
+ movbu (0x1ffeff,sp),r2
+ movbu r2,(0x1ffeff,sp)
+ movbu (0x1ffeff),r2
+ movbu r2,(0x1ffeff)
+ movbu (0x7ffefdfc,r1),r2
+ movbu r2,(0x7ffefdfc,r1)
+ movbu (0x7ffefdfc,sp),r2
+ movbu r2,(0x7ffefdfc,sp)
+ movbu (0x7ffefdfc),r2
+ movbu r2,(0x7ffefdfc)
+
+movhu_tests:
+ movhu (r9),r10
+ movhu r11,(r12)
+ movhu (sp),r9
+ movhu r10,(sp)
+ movhu (16,r1),r2
+ movhu r2,(16,r1)
+ movhu (16,sp),r2
+ movhu r2,(16,sp)
+ movhu (0x1ffeff,r1),r2
+ movhu r2,(0x1ffeff,r1)
+ movhu (0x1ffeff,sp),r2
+ movhu r2,(0x1ffeff,sp)
+ movhu (0x1ffeff),r2
+ movhu r2,(0x1ffeff)
+ movhu (0x7ffefdfc,r1),r2
+ movhu r2,(0x7ffefdfc,r1)
+ movhu (0x7ffefdfc,sp),r2
+ movhu r2,(0x7ffefdfc,sp)
+ movhu (0x7ffefdfc),r2
+ movhu r2,(0x7ffefdfc)
+
+
+mac_tests:
+ mac r1,r2
+ macu r3,r4
+ macb r5,r6
+ macbu r7,r8
+ mach r9,r10
+ machu r11,r12
+ dmach r13,r14
+ dmachu r15,r14
+ mac 16,r1
+ macu 16,r1
+ macb 16,r1
+ macbu 16,r1
+ mach 16,r1
+ machu 16,r1
+ mac 0x1ffeff,r2
+ macu 0x1ffeff,r2
+ macb 0x1ffeff,r2
+ macbu 0x1ffeff,r2
+ mach 0x1ffeff,r2
+ machu 0x1ffeff,r2
+ mac 0x7ffefdfc,r2
+ macu 0x7ffefdfc,r2
+ macb 0x7ffefdfc,r2
+ macbu 0x7ffefdfc,r2
+ mach 0x7ffefdfc,r2
+ machu 0x7ffefdfc,r2
+ dmach 0x7ffefdfc,r2
+ dmachu 0x7ffefdfc,r2
+
+bit_tests:
+ bsch r1,r2
+ btst 16,r1
+ btst 0x1ffeff,r2
+ btst 0x7ffefdfc,r2
+
+
+
+dsp_add_tests:
+ add_add r4,r1,r2,r3
+ add_add r4,r1,2,r3
+ add_sub r4,r1,r2,r3
+ add_sub r4,r1,2,r3
+ add_cmp r4,r1,r2,r3
+ add_cmp r4,r1,2,r3
+ add_mov r4,r1,r2,r3
+ add_mov r4,r1,2,r3
+ add_asr r4,r1,r2,r3
+ add_asr r4,r1,2,r3
+ add_lsr r4,r1,r2,r3
+ add_lsr r4,r1,2,r3
+ add_asl r4,r1,r2,r3
+ add_asl r4,r1,2,r3
+ add_add 4,r1,r2,r3
+ add_add 4,r1,2,r3
+ add_sub 4,r1,r2,r3
+ add_sub 4,r1,2,r3
+ add_cmp 4,r1,r2,r3
+ add_cmp 4,r1,2,r3
+ add_mov 4,r1,r2,r3
+ add_mov 4,r1,2,r3
+ add_asr 4,r1,r2,r3
+ add_asr 4,r1,2,r3
+ add_lsr 4,r1,r2,r3
+ add_lsr 4,r1,2,r3
+ add_asl 4,r1,r2,r3
+ add_asl 4,r1,2,r3
+
+dsp_cmp_tests:
+ cmp_add r4,r1,r2,r3
+ cmp_add r4,r1,2,r3
+ cmp_sub r4,r1,r2,r3
+ cmp_sub r4,r1,2,r3
+ cmp_mov r4,r1,r2,r3
+ cmp_mov r4,r1,2,r3
+ cmp_asr r4,r1,r2,r3
+ cmp_asr r4,r1,2,r3
+ cmp_lsr r4,r1,r2,r3
+ cmp_lsr r4,r1,2,r3
+ cmp_asl r4,r1,r2,r3
+ cmp_asl r4,r1,2,r3
+ cmp_add 4,r1,r2,r3
+ cmp_add 4,r1,2,r3
+ cmp_sub 4,r1,r2,r3
+ cmp_sub 4,r1,2,r3
+ cmp_mov 4,r1,r2,r3
+ cmp_mov 4,r1,2,r3
+ cmp_asr 4,r1,r2,r3
+ cmp_asr 4,r1,2,r3
+ cmp_lsr 4,r1,r2,r3
+ cmp_lsr 4,r1,2,r3
+ cmp_asl 4,r1,r2,r3
+ cmp_asl 4,r1,2,r3
+
+dsp_sub_tests:
+ sub_add r4,r1,r2,r3
+ sub_add r4,r1,2,r3
+ sub_sub r4,r1,r2,r3
+ sub_sub r4,r1,2,r3
+ sub_cmp r4,r1,r2,r3
+ sub_cmp r4,r1,2,r3
+ sub_mov r4,r1,r2,r3
+ sub_mov r4,r1,2,r3
+ sub_asr r4,r1,r2,r3
+ sub_asr r4,r1,2,r3
+ sub_lsr r4,r1,r2,r3
+ sub_lsr r4,r1,2,r3
+ sub_asl r4,r1,r2,r3
+ sub_asl r4,r1,2,r3
+ sub_add 4,r1,r2,r3
+ sub_add 4,r1,2,r3
+ sub_sub 4,r1,r2,r3
+ sub_sub 4,r1,2,r3
+ sub_cmp 4,r1,r2,r3
+ sub_cmp 4,r1,2,r3
+ sub_mov 4,r1,r2,r3
+ sub_mov 4,r1,2,r3
+ sub_asr 4,r1,r2,r3
+ sub_asr 4,r1,2,r3
+ sub_lsr 4,r1,r2,r3
+ sub_lsr 4,r1,2,r3
+ sub_asl 4,r1,r2,r3
+ sub_asl 4,r1,2,r3
+
+dsp_mov_tests:
+ mov_add r4,r1,r2,r3
+ mov_add r4,r1,2,r3
+ mov_sub r4,r1,r2,r3
+ mov_sub r4,r1,2,r3
+ mov_cmp r4,r1,r2,r3
+ mov_cmp r4,r1,2,r3
+ mov_mov r4,r1,r2,r3
+ mov_mov r4,r1,2,r3
+ mov_asr r4,r1,r2,r3
+ mov_asr r4,r1,2,r3
+ mov_lsr r4,r1,r2,r3
+ mov_lsr r4,r1,2,r3
+ mov_asl r4,r1,r2,r3
+ mov_asl r4,r1,2,r3
+ mov_add 4,r1,r2,r3
+ mov_add 4,r1,2,r3
+ mov_sub 4,r1,r2,r3
+ mov_sub 4,r1,2,r3
+ mov_cmp 4,r1,r2,r3
+ mov_cmp 4,r1,2,r3
+ mov_mov 4,r1,r2,r3
+ mov_mov 4,r1,2,r3
+ mov_asr 4,r1,r2,r3
+ mov_asr 4,r1,2,r3
+ mov_lsr 4,r1,r2,r3
+ mov_lsr 4,r1,2,r3
+ mov_asl 4,r1,r2,r3
+ mov_asl 4,r1,2,r3
+
+dsp_logical_tests:
+ and_add r4,r1,r2,r3
+ and_add r4,r1,2,r3
+ and_sub r4,r1,r2,r3
+ and_sub r4,r1,2,r3
+ and_cmp r4,r1,r2,r3
+ and_cmp r4,r1,2,r3
+ and_mov r4,r1,r2,r3
+ and_mov r4,r1,2,r3
+ and_asr r4,r1,r2,r3
+ and_asr r4,r1,2,r3
+ and_lsr r4,r1,r2,r3
+ and_lsr r4,r1,2,r3
+ and_asl r4,r1,r2,r3
+ and_asl r4,r1,2,r3
+ xor_add r4,r1,r2,r3
+ xor_add r4,r1,2,r3
+ xor_sub r4,r1,r2,r3
+ xor_sub r4,r1,2,r3
+ xor_cmp r4,r1,r2,r3
+ xor_cmp r4,r1,2,r3
+ xor_mov r4,r1,r2,r3
+ xor_mov r4,r1,2,r3
+ xor_asr r4,r1,r2,r3
+ xor_asr r4,r1,2,r3
+ xor_lsr r4,r1,r2,r3
+ xor_lsr r4,r1,2,r3
+ xor_asl r4,r1,r2,r3
+ xor_asl r4,r1,2,r3
+ or_add r4,r1,r2,r3
+ or_add r4,r1,2,r3
+ or_sub r4,r1,r2,r3
+ or_sub r4,r1,2,r3
+ or_cmp r4,r1,r2,r3
+ or_cmp r4,r1,2,r3
+ or_mov r4,r1,r2,r3
+ or_mov r4,r1,2,r3
+ or_asr r4,r1,r2,r3
+ or_asr r4,r1,2,r3
+ or_lsr r4,r1,r2,r3
+ or_lsr r4,r1,2,r3
+ or_asl r4,r1,r2,r3
+ or_asl r4,r1,2,r3
+
+dsp_misc_tests:
+ dmach_add r4,r1,r2,r3
+ dmach_add r4,r1,2,r3
+ dmach_sub r4,r1,r2,r3
+ dmach_sub r4,r1,2,r3
+ dmach_cmp r4,r1,r2,r3
+ dmach_cmp r4,r1,2,r3
+ dmach_mov r4,r1,r2,r3
+ dmach_mov r4,r1,2,r3
+ dmach_asr r4,r1,r2,r3
+ dmach_asr r4,r1,2,r3
+ dmach_lsr r4,r1,r2,r3
+ dmach_lsr r4,r1,2,r3
+ dmach_asl r4,r1,r2,r3
+ dmach_asl r4,r1,2,r3
+ swhw_add r4,r1,r2,r3
+ swhw_add r4,r1,2,r3
+ swhw_sub r4,r1,r2,r3
+ swhw_sub r4,r1,2,r3
+ swhw_cmp r4,r1,r2,r3
+ swhw_cmp r4,r1,2,r3
+ swhw_mov r4,r1,r2,r3
+ swhw_mov r4,r1,2,r3
+ swhw_asr r4,r1,r2,r3
+ swhw_asr r4,r1,2,r3
+ swhw_lsr r4,r1,r2,r3
+ swhw_lsr r4,r1,2,r3
+ swhw_asl r4,r1,r2,r3
+ swhw_asl r4,r1,2,r3
+ sat16_add r4,r1,r2,r3
+ sat16_add r4,r1,2,r3
+ sat16_sub r4,r1,r2,r3
+ sat16_sub r4,r1,2,r3
+ sat16_cmp r4,r1,r2,r3
+ sat16_cmp r4,r1,2,r3
+ sat16_mov r4,r1,r2,r3
+ sat16_mov r4,r1,2,r3
+ sat16_asr r4,r1,r2,r3
+ sat16_asr r4,r1,2,r3
+ sat16_lsr r4,r1,r2,r3
+ sat16_lsr r4,r1,2,r3
+ sat16_asl r4,r1,r2,r3
+ sat16_asl r4,r1,2,r3
+
+autoincrement_tests:
+ mov (r1+),r2
+ mov r3,(r4+)
+ movhu (r6+),r7
+ movhu r8,(r9+)
+ mov (r1+,64),r2
+ mov r1,(r2+,64)
+ movhu (r1+,64),r2
+ movhu r1,(r2+,64)
+ mov (r1+,0x1ffef),r2
+ mov r1,(r2+,0x1ffef)
+ movhu (r1+,0x1ffef),r2
+ movhu r1,(r2+,0x1ffef)
+ mov (r1+,0x7ffefdfc),r2
+ mov r1,(r2+,0x7ffefdfc)
+ movhu (r1+,0x7ffefdfc),r2
+ movhu r1,(r2+,0x7ffefdfc)
+
+dsp_autoincrement_tests:
+ mov_llt (r1+,4),r2
+ mov_lgt (r1+,4),r2
+ mov_lge (r1+,4),r2
+ mov_lle (r1+,4),r2
+ mov_lcs (r1+,4),r2
+ mov_lhi (r1+,4),r2
+ mov_lcc (r1+,4),r2
+ mov_lls (r1+,4),r2
+ mov_leq (r1+,4),r2
+ mov_lne (r1+,4),r2
+ mov_lra (r1+,4),r2
diff --git a/gdb/testsuite/gdb.disasm/configure b/gdb/testsuite/gdb.disasm/configure
new file mode 100644
index 00000000000..0e6cbf20749
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/configure
@@ -0,0 +1,899 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=sh3.s
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:573: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:594: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:612: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.disasm/configure.in b/gdb/testsuite/gdb.disasm/configure.in
new file mode 100644
index 00000000000..508636ff2c6
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/configure.in
@@ -0,0 +1,15 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(sh3.s)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.disasm/h8300s.exp b/gdb/testsuite/gdb.disasm/h8300s.exp
new file mode 100644
index 00000000000..eeaf23bfdd0
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/h8300s.exp
@@ -0,0 +1,698 @@
+# Copyright (C) 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Kazu Hirata. (kazu@hxi.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if ![istarget "h8300*-*-*"] {
+ verbose "Tests ignored for all but h8300s based targets."
+ return
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "h8300s"
+set srcfile ${srcdir}/${subdir}/${testfile}.s
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcfile}" "${binfile}" executable {debug additional_flags=-ms}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+proc all_set_machine_h8300s { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "set machine h8300s\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {}
+ }
+}
+
+proc all_movb_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/9i movb_tests\n"
+ gdb_expect {
+ -re "
+.*mov.b\tr0l,r0h.*
+.*mov.b\t#0x12,r1l.*
+.*mov.b\t@er0,r1h.*
+.*mov.b\t@\\(0x1234:16,er0\\),r2l.*
+.*mov.b\t@\\(0x12345678:32,er0\\),r2h.*
+.*mov.b\t@er0\\+,r3l.*
+.*mov.b\t@0x12:8,r3h.*
+.*mov.b\t@0x1234:16,r4l.*
+.*mov.b\t@0x12345678:32,r4h.*
+.*$gdb_prompt $" { pass "movb_tests" }
+ -re "$gdb_prompt $" { fail "movb_tests" }
+ timeout { fail "(timeout) movb_tests" }
+ }
+}
+
+proc all_movw_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/8i movw_tests\n"
+ gdb_expect {
+ -re "
+.*mov.w\te0,r0.*
+.*mov.w\t#0x1234,r1.*
+.*mov.w\t@er0,r2.*
+.*mov.w\t@\\(0x1234:16,er0\\),r3.*
+.*mov.w\t@\\(0x12345678:32,er0\\),r4.*
+.*mov.w\t@er0\\+,r5.*
+.*mov.w\t@0x1234:16,r6.*
+.*mov.w\t@0x12345678:32,r7.*
+.*$gdb_prompt $" { pass "movw_tests" }
+ -re "$gdb_prompt $" { fail "movw_tests" }
+ timeout { fail "(timeout) movw_tests" }
+ }
+}
+
+proc all_movl_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/8i movl_tests\n"
+ gdb_expect {
+ -re "
+.*mov.l\ter0,er1.*
+.*mov.l\t#0x12345678,er1.*
+.*mov.l\t@er0,er2.*
+.*mov.l\t@\\(0x1234:16,er0\\),er3.*
+.*mov.l\t@\\(0x12345678:32,er0\\),er4.*
+.*mov.l\t@er0\\+,er5.*
+.*mov.l\t@0x1234:16,er6.*
+.*mov.l\t@0x12345678:32,er7.*
+.*$gdb_prompt $" { pass "movl_tests" }
+ -re "$gdb_prompt $" { fail "movl_tests" }
+ timeout { fail "(timeout) movl_tests" }
+ }
+}
+
+proc all_ldm_stm_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/6i ldm_stm_tests\n"
+ gdb_expect {
+ -re "
+.*ldm.l\t@sp\\+,er0-er1.*
+.*ldm.l\t@sp\\+,er0-er2.*
+.*ldm.l\t@sp\\+,er0-er3.*
+.*stm.l\ter0\\-er1,@-sp.*
+.*stm.l\ter0\\-er2,@-sp.*
+.*stm.l\ter0\\-er3,@-sp.*
+.*$gdb_prompt $" { pass "ldm_stm_tests" }
+ -re "$gdb_prompt $" { fail "ldm_stm_tests" }
+ timeout { fail "(timeout) ldm_stm_tests" }
+ }
+}
+
+proc all_movfpe_movtpe_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/2i movfpe_movtpe_tests\n"
+ gdb_expect {
+ -re "
+.*movfpe\t@0x1234:16,r2l.*
+.*movtpe\tr2l,@0x1234:16.*
+.*$gdb_prompt $" { pass "movfpe_movtpe_tests" }
+ -re "$gdb_prompt $" { fail "movfpe_movtpe_tests" }
+ timeout { fail "(timeout) movfpe_movtpe_tests" }
+ }
+}
+
+proc all_add_sub_addx_subx_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/15i add_sub_addx_subx_tests\n"
+ gdb_expect {
+ -re "
+.*add.b\t#0x12,r0l.*
+.*add.b\tr1l,r1h.*
+.*add.w\t#0x1234,r2.*
+.*add.w\tr3,r4.*
+.*add.l\t#0x12345678,er5.*
+.*add.l\ter6,er7.*
+.*sub.b\tr1l,r1h.*
+.*sub.w\t#0x1234,r2.*
+.*sub.w\tr3,r4.*
+.*sub.l\t#0x12345678,er5.*
+.*sub.l\ter6,er7.*
+.*addx\t#0x12,r0l.*
+.*addx\tr1l,r1h.*
+.*subx\t#0x12,r0l.*
+.*subx\tr1l,r1h.*
+.*$gdb_prompt $" { pass "add_sub_addx_subx_tests" }
+ -re "$gdb_prompt $" { fail "add_sub_addx_subx_tests" }
+ timeout { fail "(timeout) add_sub_addx_subx_tests" }
+ }
+}
+
+proc all_inc_dec_adds_subs_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/16i inc_dec_adds_subs_tests\n"
+ gdb_expect {
+ -re "
+.*inc.b\tr0l.*
+.*inc.w\t#0x1,r4.*
+.*inc.w\t#0x2,r3.*
+.*inc.l\t#0x1,er2.*
+.*inc.l\t#0x2,er1.*
+.*dec.b\tr0l.*
+.*dec.w\t#0x1,r4.*
+.*dec.w\t#0x2,r3.*
+.*dec.l\t#0x1,er2.*
+.*dec.l\t#0x2,er1.*
+.*adds\t#0x1,er7.*
+.*adds\t#0x2,er6.*
+.*adds\t#0x4,er5.*
+.*subs\t#0x1,er7.*
+.*subs\t#0x2,er6.*
+.*subs\t#0x4,er5.*
+.*$gdb_prompt $" { pass "inc_dec_adds_subs_tests" }
+ -re "$gdb_prompt $" { fail "inc_dec_adds_subs_tests" }
+ timeout { fail "(timeout) inc_dec_adds_subs_tests" }
+ }
+}
+
+proc all_daa_das_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/2i daa_das_tests\n"
+ gdb_expect {
+ -re "
+.*daa\tr0l.*
+.*das\tr0h.*
+.*$gdb_prompt $" { pass "daa_das_tests" }
+ -re "$gdb_prompt $" { fail "daa_das_tests" }
+ timeout { fail "(timeout) daa_das_tests" }
+ }
+}
+
+proc all_mul_div_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/8i mul_div_tests\n"
+ gdb_expect {
+ -re "
+.*mulxs.b\tr0l,r1.*
+.*mulxs.w\tr2,er3.*
+.*mulxu.b\tr0l,e1.*
+.*mulxu.w\te2,er3.*
+.*divxs.b\tr0l,r1.*
+.*divxs.w\tr2,er3.*
+.*divxu.b\tr0l,e1.*
+.*divxu.w\te2,er3.*
+.*$gdb_prompt $" { pass "mul_div_tests" }
+ -re "$gdb_prompt $" { fail "mul_div_tests" }
+ timeout { fail "(timeout) mul_div_tests" }
+ }
+}
+
+proc all_cmp_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/8i cmp_tests\n"
+ gdb_expect {
+ -re "
+.*cmp.b\t#0x12,r0l.*
+.*cmp.b\tr1l,r1h.*
+.*cmp.w\t#0x1234,r2.*
+.*cmp.w\tr3,e3.*
+.*cmp.l\t#0x12345678,er4.*
+.*cmp.l\ter5,er6.*
+.*$gdb_prompt $" { pass "cmp_tests" }
+ -re "$gdb_prompt $" { fail "cmp_tests" }
+ timeout { fail "(timeout) cmp_tests" }
+ }
+}
+
+proc all_neg_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/3i neg_tests\n"
+ gdb_expect {
+ -re "
+.*neg.b\tr0l.*
+.*neg.w\tr2.*
+.*neg.l\ter3.*
+.*$gdb_prompt $" { pass "neg_tests" }
+ -re "$gdb_prompt $" { fail "neg_tests" }
+ timeout { fail "(timeout) neg_tests" }
+ }
+}
+
+proc all_ext_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/4i ext_tests\n"
+ gdb_expect {
+ -re "
+.*exts.w\tr0.*
+.*exts.l\ter1.*
+.*extu.w\tr2.*
+.*extu.l\ter3.*
+.*$gdb_prompt $" { pass "ext_tests" }
+ -re "$gdb_prompt $" { fail "ext_tests" }
+ timeout { fail "(timeout) ext_tests" }
+ }
+}
+
+proc all_tas_mac_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/7i tas_mac_tests\n"
+ gdb_expect {
+ -re "
+.*tas\t@er0.*
+.*mac\t@er1+,@er2+.*
+.*clrmac.*
+.*ldmac\ter4,mach.*
+.*ldmac\ter5,macl.*
+.*stmac\tmach,er6.*
+.*stmac\tmacl,er7.*
+.*$gdb_prompt $" { pass "tas_mac_tests" }
+ -re "$gdb_prompt $" { fail "tas_mac_tests" }
+ timeout { fail "(timeout) tas_mac_tests" }
+ }
+}
+
+proc all_logic_operations_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/21i logic_operations_tests\n"
+ gdb_expect {
+ -re "
+.*and.b\t#0x12,r0l.*
+.*and.b\tr1l,r2h.*
+.*and.w\t#0x1234,r0.*
+.*and.w\tr1,r2.*
+.*and.l\t#0x12345678,er0.*
+.*and.l\ter1,er2.*
+.*or.b\t#0x12,r0l.*
+.*or.b\tr1l,r2h.*
+.*or.w\t#0x1234,r0.*
+.*or.w\tr1,r2.*
+.*or.l\t#0x12345678,er0.*
+.*or.l\ter1,er2.*
+.*xor.b\t#0x12,r0l.*
+.*xor.b\tr1l,r2h.*
+.*xor.w\t#0x1234,r0.*
+.*xor.w\tr1,r2.*
+.*xor.l\t#0x12345678,er0.*
+.*xor.l\ter1,er2.*
+.*not.b\tr0l.*
+.*not.w\tr1.*
+.*not.l\ter2.*
+.*$gdb_prompt $" { pass "logic_operations_tests" }
+ -re "$gdb_prompt $" { fail "logic_operations_tests" }
+ timeout { fail "(timeout) logic_operations_tests" }
+ }
+}
+
+proc all_sha_shl_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/12i sha_shl_tests\n"
+ gdb_expect {
+ -re "
+.*shal\tr0l.*
+.*shal\tr1.*
+.*shal\ter2.*
+.*shar\tr3l.*
+.*shar\tr4.*
+.*shar\ter5.*
+.*shll\tr0l.*
+.*shll\tr1.*
+.*shll\ter2.*
+.*shlr\tr3l.*
+.*shlr\tr4.*
+.*shlr\ter5.*
+.*$gdb_prompt $" { pass "sha_shl_tests" }
+ -re "$gdb_prompt $" { fail "sha_shl_tests" }
+ timeout { fail "(timeout) sha_shl_tests" }
+ }
+}
+
+proc all_rot_rotx_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/12i rot_rotx_tests\n"
+ gdb_expect {
+ -re "
+.*rotl\tr0l.*
+.*rotl\tr1.*
+.*rotl\ter2.*
+.*rotr\tr3l.*
+.*rotr\tr4.*
+.*rotr\ter5.*
+.*rotxl\tr0l.*
+.*rotxl\tr1.*
+.*rotxl\ter2.*
+.*rotxr\tr3l.*
+.*rotxr\tr4.*
+.*rotxr\ter5.*
+.*$gdb_prompt $" { pass "rot_rotx_tests" }
+ -re "$gdb_prompt $" { fail "rot_rotx_tests" }
+ timeout { fail "(timeout) rot_rotx_tests" }
+ }
+}
+
+proc all_bset_bclr_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/20i bset_bclr_tests\n"
+ gdb_expect {
+ -re "
+.*bset\t#0x7,r0l.*
+.*bset\t#0x6,@er1.*
+.*bset\t#0x5,@0x12:8.*
+.*bset\t#0x4,@0x1234:16.*
+.*bset\t#0x3,@0x12345678:32.*
+.*bset\tr7l,r0h.*
+.*bset\tr6l,@er1.*
+.*bset\tr5l,@0x12:8.*
+.*bset\tr4l,@0x1234:16.*
+.*bset\tr3l,@0x12345678:32.*
+.*bclr\t#0x7,r0l.*
+.*bclr\t#0x6,@er1.*
+.*bclr\t#0x5,@0x12:8.*
+.*bclr\t#0x4,@0x1234:16.*
+.*bclr\t#0x3,@0x12345678:32.*
+.*bclr\tr7h,r0h.*
+.*bclr\tr6h,@er1.*
+.*bclr\tr5h,@0x12:8.*
+.*bclr\tr4h,@0x1234:16.*
+.*bclr\tr3h,@0x12345678:32.*
+.*$gdb_prompt $" { pass "bset_bclr_tests" }
+ -re "$gdb_prompt $" { fail "bset_bclr_tests" }
+ timeout { fail "(timeout) bset_bclr_tests" }
+ }
+}
+
+proc all_bnot_btst_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/20i bnot_btst_tests\n"
+ gdb_expect {
+ -re "
+.*bnot\t#0x7,r0l.*
+.*bnot\t#0x6,@er1.*
+.*bnot\t#0x5,@0x12:8.*
+.*bnot\t#0x4,@0x1234:16.*
+.*bnot\t#0x3,@0x12345678:32.*
+.*bnot\tr7l,r0h.*
+.*bnot\tr6l,@er1.*
+.*bnot\tr5l,@0x12:8.*
+.*bnot\tr4l,@0x1234:16.*
+.*bnot\tr3l,@0x12345678:32.*
+.*btst\t#0x7,r0l.*
+.*btst\t#0x6,@er1.*
+.*btst\t#0x5,@0x12:8.*
+.*btst\t#0x4,@0x1234:16.*
+.*btst\t#0x3,@0x12345678:32.*
+.*btst\tr7h,r0h.*
+.*btst\tr6h,@er1.*
+.*btst\tr5h,@0x12:8.*
+.*btst\tr4h,@0x1234:16.*
+.*btst\tr3h,@0x12345678:32.*
+.*$gdb_prompt $" { pass "bnot_btst_tests" }
+ -re "$gdb_prompt $" { fail "bnot_btst_tests" }
+ timeout { fail "(timeout) bnot_btst_tests" }
+ }
+}
+
+proc all_band_bor_bxor_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/15i band_bor_bxor_tests\n"
+ gdb_expect {
+ -re "
+.*band\t#0x7,r0l.*
+.*band\t#0x6,@er1.*
+.*band\t#0x5,@0x12:8.*
+.*band\t#0x4,@0x1234:16.*
+.*band\t#0x3,@0x12345678:32.*
+.*bor\t#0x7,r0l.*
+.*bor\t#0x6,@er1.*
+.*bor\t#0x5,@0x12:8.*
+.*bor\t#0x4,@0x1234:16.*
+.*bor\t#0x3,@0x12345678:32.*
+.*bxor\t#0x7,r0l.*
+.*bxor\t#0x6,@er1.*
+.*bxor\t#0x5,@0x12:8.*
+.*bxor\t#0x4,@0x1234:16.*
+.*bxor\t#0x3,@0x12345678:32.*
+.*$gdb_prompt $" { pass "band_bor_bxor_tests" }
+ -re "$gdb_prompt $" { fail "band_bor_bxor_tests" }
+ timeout { fail "(timeout) band_bor_bxor_tests" }
+ }
+}
+
+proc all_bld_bst_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/20i bld_bst_tests\n"
+ gdb_expect {
+ -re "
+.*bld\t#0x7,r0l.*
+.*bld\t#0x6,@er1.*
+.*bld\t#0x5,@0x12:8.*
+.*bld\t#0x4,@0x1234:16.*
+.*bld\t#0x3,@0x12345678:32.*
+.*bild\t#0x7,r0l.*
+.*bild\t#0x6,@er1.*
+.*bild\t#0x5,@0x12:8.*
+.*bild\t#0x4,@0x1234:16.*
+.*bild\t#0x3,@0x12345678:32.*
+.*bst\t#0x7,r0l.*
+.*bst\t#0x6,@er1.*
+.*bst\t#0x5,@0x12:8.*
+.*bst\t#0x4,@0x1234:16.*
+.*bst\t#0x3,@0x12345678:32.*
+.*bist\t#0x7,r0l.*
+.*bist\t#0x6,@er1.*
+.*bist\t#0x5,@0x12:8.*
+.*bist\t#0x4,@0x1234:16.*
+.*bist\t#0x3,@0x12345678:32.*
+.*$gdb_prompt $" { pass "bld_bst_tests" }
+ -re "$gdb_prompt $" { fail "bld_bst_tests" }
+ timeout { fail "(timeout) bld_bst_tests" }
+ }
+}
+
+proc all_branch_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/25i branch_tests\n"
+ gdb_expect {
+ -re "
+.*bra\tbranch_tests.*
+.*brn\tbranch_tests.*
+.*bhi\tbranch_tests.*
+.*bls\tbranch_tests.*
+.*bcc\tbranch_tests.*
+.*bcs\tbranch_tests.*
+.*bne\tbranch_tests.*
+.*beq\tbranch_tests.*
+.*bvc\tbranch_tests.*
+.*bvs\tbranch_tests.*
+.*bpl\tbranch_tests.*
+.*bmi\tbranch_tests.*
+.*bge\tbranch_tests.*
+.*blt\tbranch_tests.*
+.*bgt\tbranch_tests.*
+.*ble\tbranch_tests.*
+.*jmp\t@er0.*
+.*jmp\t@branch_tests.*
+.*jmp\t@@0 (0).*
+.*bsr\tbranch_tests.*
+.*bsr\tbranch_tests.*
+.*jsr\t@er0.*
+.*jsr\t@branch_tests.*
+.*jsr\t@@0 (0).*
+.*rts.*
+.*$gdb_prompt $" { pass "branch_tests" }
+ -re "$gdb_prompt $" { fail "branch_tests" }
+ timeout { fail "(timeout) branch_tests" }
+ }
+}
+
+proc all_system_control_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/40i system_control_tests\n"
+ gdb_expect {
+ -re "
+.*trapa\t#0x2.*
+.*rte.*
+.*sleep.*
+.*ldc\t#0x12,ccr*.
+.*ldc\tr3l,ccr.*
+.*ldc\t@er0,ccr.*
+.*ldc\t@\\(0x1234:16,er0\\),ccr.*
+.*ldc\t@\\(0x12345678:32,er0\\),ccr.*
+.*ldc\t@er1\\+,ccr.*
+.*ldc\t@0x1234:16,ccr.*
+.*ldc\t@0x12345678:32,ccr.*
+.*stc\tccr,r3l.*
+.*stc\tccr,@er0.*
+.*stc\tccr,@\\(0x1234:16,er0\\).*
+.*stc\tccr,@\\(0x12345678:32,er0\\).*
+.*stc\tccr,@\\-er1.*
+.*stc\tccr,@0x1234:16.*
+.*stc\tccr,@0x12345678:32.*
+.*andc\t#0x12,ccr.*
+.*orc\t#0x34,ccr.*
+.*xorc\t#0x56,ccr.*
+.*ldc\t#0x12,exr*.
+.*ldc\tr3l,exr.*
+.*ldc\t@er0,exr.*
+.*ldc\t@\\(0x1234:16,er0\\),exr.*
+.*ldc\t@\\(0x12345678:32,er0\\),exr.*
+.*ldc\t@er1\\+,exr.*
+.*ldc\t@0x1234:16,exr.*
+.*ldc\t@0x12345678:32,exr.*
+.*stc\texr,r3l.*
+.*stc\texr,@er0.*
+.*stc\texr,@\\(0x1234:16,er0\\).*
+.*stc\texr,@\\(0x12345678:32,er0\\).*
+.*stc\texr,@\\-er1.*
+.*stc\texr,@0x1234:16.*
+.*stc\texr,@0x12345678:32.*
+.*andc\t#0x12,exr.*
+.*orc\t#0x34,exr.*
+.*xorc\t#0x56,exr.*
+.*nop.*
+.*$gdb_prompt $" { pass "system_control_tests" }
+ -re "$gdb_prompt $" { fail "system_control_tests" }
+ timeout { fail "(timeout) system_control_tests" }
+ }
+}
+
+proc all_block_data_transfer_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/2i block_data_transfer_tests\n"
+ gdb_expect {
+ -re "
+.*eepmov.b.*
+.*eepmov.w.*
+.*$gdb_prompt $" { pass "block_data_transfer_tests" }
+ -re "$gdb_prompt $" { fail "block_data_transfer_tests" }
+ timeout { fail "(timeout) block_data_transfer_tests" }
+ }
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+all_set_machine_h8300s
+gdb_load $binfile
+
+# Data transfer
+all_movb_tests
+all_movw_tests
+all_movl_tests
+all_ldm_stm_tests
+all_movfpe_movtpe_tests
+
+# Arithmetic operations
+all_add_sub_addx_subx_tests
+all_inc_dec_adds_subs_tests
+all_daa_das_tests
+all_mul_div_tests
+all_cmp_tests
+all_neg_tests
+all_ext_tests
+all_tas_mac_tests
+
+# Logic operations
+all_logic_operations_tests
+
+# Shift
+all_sha_shl_tests
+all_rot_rotx_tests
+
+# Bit manipulation
+all_bset_bclr_tests
+all_bnot_btst_tests
+all_band_bor_bxor_tests
+all_bld_bst_tests
+
+# Branch
+all_branch_tests
+
+# System control
+all_system_control_tests
+
+# Block data transfer
+all_block_data_transfer_tests
diff --git a/gdb/testsuite/gdb.disasm/h8300s.s b/gdb/testsuite/gdb.disasm/h8300s.s
new file mode 100644
index 00000000000..ec66a55a002
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/h8300s.s
@@ -0,0 +1,356 @@
+ .h8300s
+ .section .text
+ .align 2
+ .global _main
+ .global movb_tests
+ .global movw_tests
+ .global movl_tests
+ .global ldm_stm_tests
+ .global movfpe_movtpe_tests
+ .global add_sub_addx_subx_tests
+ .global inc_dec_adds_subs_tests
+ .global daa_das_tests
+ .global mul_div_tests
+ .global cmp_tests
+ .global neg_tests
+ .global ext_tests
+ .global tas_mac_tests
+ .global logic_operations_tests
+ .global sha_shl_tests
+ .global rot_rotx_tests
+ .global bset_bclr_tests
+ .global bnot_btst_tests
+ .global band_bor_bxor_tests
+ .global bld_bst_tests
+ .global branch_tests
+ .global system_control_tests
+ .global block_data_transfer_tests
+_main:
+ nop
+
+movb_tests:
+ mov.b r0l,r0h
+ mov.b #0x12,r1l
+ mov.b @er0,r1h
+ mov.b @(0x1234:16,er0),r2l
+ mov.b @(0x12345678:32,er0),r2h
+ mov.b @er0+,r3l
+ mov.b @0x12:8,r3h
+ mov.b @0x1234:16,r4l
+ mov.b @0x12345678:32,r4h
+
+movw_tests:
+ mov.w e0,r0
+ mov.w #0x1234,r1
+ mov.w @er0,r2
+ mov.w @(0x1234:16,er0),r3
+ mov.w @(0x12345678:32,er0),r4
+ mov.w @er0+,r5
+ mov.w @0x1234:16,r6
+ mov.w @0x12345678:32,r7
+
+movl_tests:
+ mov.l er0,er1
+ mov.l #0x12345678,er1
+ mov.l @er0,er2
+ mov.l @(0x1234:16,er0),er3
+ mov.l @(0x12345678:32,er0),er4
+ mov.l @er0+,er5
+ mov.l @0x1234:16,er6
+ mov.l @0x12345678:32,er7
+
+ldm_stm_tests:
+ ldm.l @sp+,er0-er1
+ ldm.l @sp+,er0-er2
+ ldm.l @sp+,er0-er3
+ stm.l er0-er1,@-sp
+ stm.l er0-er2,@-sp
+ stm.l er0-er3,@-sp
+
+movfpe_movtpe_tests:
+ movfpe @0x1234:16,r2l
+ movtpe r2l,@0x1234:16
+
+add_sub_addx_subx_tests:
+ add.b #0x12,r0l
+ add.b r1l,r1h
+ add.w #0x1234,r2
+ add.w r3,r4
+ add.l #0x12345678,er5
+ add.l er6,er7
+ sub.b r1l,r1h
+ sub.w #0x1234,r2
+ sub.w r3,r4
+ sub.l #0x12345678,er5
+ sub.l er6,er7
+ addx #0x12,r0l
+ addx r1l,r1h
+ subx #0x12,r0l
+ subx r1l,r1h
+
+inc_dec_adds_subs_tests:
+ inc.b r0l
+ inc.w #0x1,r4
+ inc.w #0x2,r3
+ inc.l #0x1,er2
+ inc.l #0x2,er1
+ dec.b r0l
+ dec.w #0x1,r4
+ dec.w #0x2,r3
+ dec.l #0x1,er2
+ dec.l #0x2,er1
+ adds #0x1,er7
+ adds #0x2,er6
+ adds #0x4,er5
+ subs #0x1,er7
+ subs #0x2,er6
+ subs #0x4,er5
+
+daa_das_tests:
+ daa r0l
+ das r0h
+
+mul_div_tests:
+ mulxs.b r0l,r1
+ mulxs.w r2,er3
+ mulxu.b r0l,e1
+ mulxu.w e2,er3
+ divxs.b r0l,r1
+ divxs.w r2,er3
+ divxu.b r0l,e1
+ divxu.w e2,er3
+
+cmp_tests:
+ cmp.b #0x12,r0l
+ cmp.b r1l,r1h
+ cmp.w #0x1234,r2
+ cmp.w r3,e3
+ cmp.l #0x12345678,er4
+ cmp.l er5,er6
+
+neg_tests:
+ neg.b r0l
+ neg.w r2
+ neg.l er3
+
+ext_tests:
+ exts.w r0
+ exts.l er1
+ extu.w r2
+ extu.l er3
+
+tas_mac_tests:
+ tas @er0
+ mac @er1+,@er2+
+ clrmac
+ ldmac er4,mach
+ ldmac er5,macl
+ stmac mach,er6
+ stmac macl,er7
+
+logic_operations_tests:
+ and.b #0x12,r0l
+ and.b r1l,r2h
+ and.w #0x1234,r0
+ and.w r1,r2
+ and.l #0x12345678,er0
+ and.l er1,er2
+ or.b #0x12,r0l
+ or.b r1l,r2h
+ or.w #0x1234,r0
+ or.w r1,r2
+ or.l #0x12345678,er0
+ or.l er1,er2
+ xor.b #0x12,r0l
+ xor.b r1l,r2h
+ xor.w #0x1234,r0
+ xor.w r1,r2
+ xor.l #0x12345678,er0
+ xor.l er1,er2
+ not.b r0l
+ not.w r1
+ not.l er2
+
+sha_shl_tests:
+ shal r0l
+ shal r1
+ shal er2
+ shar r3l
+ shar r4
+ shar er5
+ shll r0l
+ shll r1
+ shll er2
+ shlr r3l
+ shlr r4
+ shlr er5
+
+rot_rotx_tests:
+ rotl r0l
+ rotl r1
+ rotl er2
+ rotr r3l
+ rotr r4
+ rotr er5
+ rotxl r0l
+ rotxl r1
+ rotxl er2
+ rotxr r3l
+ rotxr r4
+ rotxr er5
+
+bset_bclr_tests:
+ bset #0x7,r0l
+ bset #0x6,@er1
+ bset #0x5,@0x12:8
+ bset #0x4,@0x1234:16
+ bset #0x3,@0x12345678:32
+ bset r7l,r0h
+ bset r6l,@er1
+ bset r5l,@0x12:8
+ bset r4l,@0x1234:16
+ bset r3l,@0x12345678:32
+ bclr #0x7,r0l
+ bclr #0x6,@er1
+ bclr #0x5,@0x12:8
+ bclr #0x4,@0x1234:16
+ bclr #0x3,@0x12345678:32
+ bclr r7h,r0h
+ bclr r6h,@er1
+ bclr r5h,@0x12:8
+ bclr r4h,@0x1234:16
+ bclr r3h,@0x12345678:32
+
+bnot_btst_tests:
+ bnot #0x7,r0l
+ bnot #0x6,@er1
+ bnot #0x5,@0x12:8
+ bnot #0x4,@0x1234:16
+ bnot #0x3,@0x12345678:32
+ bnot r7l,r0h
+ bnot r6l,@er1
+ bnot r5l,@0x12:8
+ bnot r4l,@0x1234:16
+ bnot r3l,@0x12345678:32
+ btst #0x7,r0l
+ btst #0x6,@er1
+ btst #0x5,@0x12:8
+ btst #0x4,@0x1234:16
+ btst #0x3,@0x12345678:32
+ btst r7h,r0h
+ btst r6h,@er1
+ btst r5h,@0x12:8
+ btst r4h,@0x1234:16
+ btst r3h,@0x12345678:32
+
+band_bor_bxor_tests:
+ band #0x7,r0l
+ band #0x6,@er1
+ band #0x5,@0x12:8
+ band #0x4,@0x1234:16
+ band #0x3,@0x12345678:32
+ bor #0x7,r0l
+ bor #0x6,@er1
+ bor #0x5,@0x12:8
+ bor #0x4,@0x1234:16
+ bor #0x3,@0x12345678:32
+ bxor #0x7,r0l
+ bxor #0x6,@er1
+ bxor #0x5,@0x12:8
+ bxor #0x4,@0x1234:16
+ bxor #0x3,@0x12345678:32
+
+bld_bst_tests:
+ bld #0x7,r0l
+ bld #0x6,@er1
+ bld #0x5,@0x12:8
+ bld #0x4,@0x1234:16
+ bld #0x3,@0x12345678:32
+ bild #0x7,r0l
+ bild #0x6,@er1
+ bild #0x5,@0x12:8
+ bild #0x4,@0x1234:16
+ bild #0x3,@0x12345678:32
+ bst #0x7,r0l
+ bst #0x6,@er1
+ bst #0x5,@0x12:8
+ bst #0x4,@0x1234:16
+ bst #0x3,@0x12345678:32
+ bist #0x7,r0l
+ bist #0x6,@er1
+ bist #0x5,@0x12:8
+ bist #0x4,@0x1234:16
+ bist #0x3,@0x12345678:32
+
+branch_tests:
+ bra branch_tests
+ brn branch_tests
+ bhi branch_tests
+ bls branch_tests
+ bcc branch_tests
+ bcs branch_tests
+ bne branch_tests
+ beq branch_tests
+ bvc branch_tests
+ bvs branch_tests
+ bpl branch_tests
+ bmi branch_tests
+ bge branch_tests
+ blt branch_tests
+ bgt branch_tests
+ ble branch_tests
+ jmp @er0
+ jmp @branch_tests
+ jmp @@0 (0)
+ bsr @branch_tests:8
+ bsr @branch_tests:16
+ jsr @er0
+ jsr @branch_tests
+ jsr @@0 (0)
+ rts
+
+system_control_tests:
+ trapa #0x2
+ rte
+ sleep
+ ldc #0x12,ccr
+ ldc r3l,ccr
+ ldc @er0,ccr
+ ldc @(0x1234:16,er0),ccr
+ ldc @(0x12345678:32,er0),ccr
+ ldc @er1+,ccr
+ ldc @0x1234:16,ccr
+ ldc @0x12345678:32,ccr
+ stc ccr,r3l
+ stc ccr,@er0
+ stc ccr,@(0x1234:16,er0)
+ stc ccr,@(0x12345678:32,er0)
+ stc ccr,@-er1
+ stc ccr,@0x1234:16
+ stc ccr,@0x12345678:32
+ andc #0x12,ccr
+ orc #0x34,ccr
+ xorc #0x56,ccr
+ ldc #0x12,exr
+ ldc r3l,exr
+ ldc @er0,exr
+ ldc @(0x1234:16,er0),exr
+ ldc @(0x12345678:32,er0),exr
+ ldc @er1+,exr
+ ldc @0x1234:16,exr
+ ldc @0x12345678:32,exr
+ stc exr,r3l
+ stc exr,@er0
+ stc exr,@(0x1234:16,er0)
+ stc exr,@(0x12345678:32,er0)
+ stc exr,@-er1
+ stc exr,@0x1234:16
+ stc exr,@0x12345678:32
+ andc #0x12,exr
+ orc #0x34,exr
+ xorc #0x56,exr
+ nop
+
+block_data_transfer_tests:
+ eepmov.b
+ eepmov.w
diff --git a/gdb/testsuite/gdb.disasm/hppa.exp b/gdb/testsuite/gdb.disasm/hppa.exp
new file mode 100644
index 00000000000..122e9097031
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/hppa.exp
@@ -0,0 +1,1404 @@
+
+# Copyright 1992, 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Jeff Law. (law@cs.utah.edu)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if ![istarget "hppa*-*-*"] {
+ verbose "Tests ignored for all but hppa based targets."
+ return
+}
+
+
+set prms_id 0
+set bug_id 0
+
+set testfile "hppa"
+set srcfile ${srcdir}/${subdir}/${testfile}.s
+set binfile ${objdir}/${subdir}/${testfile}
+set comp_output [gdb_compile "${srcfile}" "${binfile}" executable ""];
+if { $comp_output != "" } {
+ if [ regexp "Opcode not defined - DIAG" $comp_output] {
+ warning "HP assembler in use--skipping disasm tests"
+ return
+ } else {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+ }
+}
+
+proc all_integer_memory_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/8i integer_memory_tests\n"
+ gdb_expect {
+ -re "
+.*ldw 0\\(sr0,r4\\),r26.*
+.*ldh 0\\(sr0,r4\\),r26.*
+.*ldb 0\\(sr0,r4\\),r26.*
+.*stw r26,0\\(sr0,r4\\).*
+.*sth r26,0\\(sr0,r4\\).*
+.*stb r26,0\\(sr0,r4\\).*
+.*ldwm 0\\(sr0,r4\\),r26.*
+.*stwm r26,0\\(sr0,r4\\).*
+.*$gdb_prompt $" { pass "integer_memory_tests" }
+ -re "$gdb_prompt $" { fail "integer_memory_tests" }
+ timeout { fail "(timeout) integer memory_tests" }
+ }
+
+ send_gdb "x/20i integer_indexing_load\n"
+ gdb_expect {
+ -re "
+.*ldwx r5\\(sr0,r4\\),r26.*
+.*ldwx,s r5\\(sr0,r4\\),r26.*
+.*ldwx,m r5\\(sr0,r4\\),r26.*
+.*ldwx,sm r5\\(sr0,r4\\),r26.*
+.*ldhx r5\\(sr0,r4\\),r26.*
+.*ldhx,s r5\\(sr0,r4\\),r26.*
+.*ldhx,m r5\\(sr0,r4\\),r26.*
+.*ldhx,sm r5\\(sr0,r4\\),r26.*
+.*ldbx r5\\(sr0,r4\\),r26.*
+.*ldbx,s r5\\(sr0,r4\\),r26.*
+.*ldbx,m r5\\(sr0,r4\\),r26.*
+.*ldbx,sm r5\\(sr0,r4\\),r26.*
+.*ldwax r5\\(r4\\),r26.*
+.*ldwax,s r5\\(r4\\),r26.*
+.*ldwax,m r5\\(r4\\),r26.*
+.*ldwax,sm r5\\(r4\\),r26.*
+.*ldcwx r5\\(sr0,r4\\),r26.*
+.*ldcwx,s r5\\(sr0,r4\\),r26.*
+.*ldcwx,m r5\\(sr0,r4\\),r26.*
+.*ldcwx,sm r5\\(sr0,r4\\),r26.*
+.*$gdb_prompt $" { pass "integer_indexing_load" }
+ -re "$gdb_prompt $" { fail "integer_indexing_load" }
+ timeout { fail "(timeout) integer_indexing" }
+ }
+
+ send_gdb "x/15i integer_load_short_memory\n"
+ gdb_expect {
+ -re "
+.*ldws 0\\(sr0,r4\\),r26.*
+.*ldws,mb 0\\(sr0,r4\\),r26.*
+.*ldws,ma 0\\(sr0,r4\\),r26.*
+.*ldhs 0\\(sr0,r4\\),r26.*
+.*ldhs,mb 0\\(sr0,r4\\),r26.*
+.*ldhs,ma 0\\(sr0,r4\\),r26.*
+.*ldbs 0\\(sr0,r4\\),r26.*
+.*ldbs,mb 0\\(sr0,r4\\),r26.*
+.*ldbs,ma 0\\(sr0,r4\\),r26.*
+.*ldwas 0\\(r4\\),r26.*
+.*ldwas,mb 0\\(r4\\),r26.*
+.*ldwas,ma 0\\(r4\\),r26.*
+.*ldcws 0\\(sr0,r4\\),r26.*
+.*ldcws,mb 0\\(sr0,r4\\),r26.*
+.*ldcws,ma 0\\(sr0,r4\\),r26.*
+.*$gdb_prompt $" { pass "integer_load_short_memory" }
+ -re "$gdb_prompt $" { fail "integer_load_short_memory" }
+ timeout { fail "(timeout) integer_load_short_memory " }
+ }
+
+
+ send_gdb "x/17i integer_store_short_memory\n"
+ gdb_expect {
+ -re "
+.*stws r26,0\\(sr0,r4\\).*
+.*stws,mb r26,0\\(sr0,r4\\).*
+.*stws,ma r26,0\\(sr0,r4\\).*
+.*sths r26,0\\(sr0,r4\\).*
+.*sths,mb r26,0\\(sr0,r4\\).*
+.*sths,ma r26,0\\(sr0,r4\\).*
+.*stbs r26,0\\(sr0,r4\\).*
+.*stbs,mb r26,0\\(sr0,r4\\).*
+.*stbs,ma r26,0\\(sr0,r4\\).*
+.*stwas r26,0\\(r4\\).*
+.*stwas,mb r26,0\\(r4\\).*
+.*stwas,ma r26,0\\(r4\\).*
+.*stbys r26,0\\(sr0,r4\\).*
+.*stbys r26,0\\(sr0,r4\\).*
+.*stbys,e r26,0\\(sr0,r4\\).*
+.*stbys,b,m r26,0\\(sr0,r4\\).*
+.*stbys,e,m r26,0\\(sr0,r4\\).*
+.*$gdb_prompt $" { pass "integer_store_short_memory" }
+ -re "$gdb_prompt $" { fail "integer_store_short_memory" }
+ timeout { fail "(timeout) integer_short_memory " }
+ }
+}
+
+proc all_immediate_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/3i immediate_tests\n"
+ gdb_expect {
+ -re "
+.*ldo 5\\(r26\\),r26.*
+.*ldil -21524800,r26.*
+.*addil -21524800,r5.*
+.*$gdb_prompt $" { pass "immedate_tests" }
+ -re "$gdb_prompt $" { fail "immedate_tests" }
+ timeout { fail "(timeout) immedate_tests " }
+ }
+}
+
+proc all_branch_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/10i branch_tests_1\n"
+ gdb_expect {
+ -re "
+.*bl.*,rp.*
+.*bl,n.*,rp.*
+.*b.*
+.*b,n.*
+.*gate.*,rp.*
+.*gate,n.*,rp.*
+.*blr r4,rp.*
+.*blr,n r4,rp.*
+.*blr r4,r0.*
+.*blr,n r4,r0.*
+.*$gdb_prompt $" { pass "branch_tests_1" }
+ -re "$gdb_prompt $" { fail "branch_tests_1" }
+ timeout { fail "(timeout) branch_tests_1" }
+ }
+
+ send_gdb "x/6i branch_tests_2\n"
+ gdb_expect {
+ -re "
+.*bv r0\\(rp\\).*
+.*bv,n r0\\(rp\\).*
+.*be 1234\\(sr1,rp\\).*
+.*be,n 1234\\(sr1,rp\\).*
+.*ble 1234\\(sr1,rp\\).*
+.*ble,n 1234\\(sr1,rp\\).*
+.*$gdb_prompt $" { pass "branch_tests_2" }
+ -re "$gdb_prompt $" { fail "branch_tests_2" }
+ timeout { fail "(timeout) branch_tests_2" }
+ }
+
+
+ send_gdb "x/8i movb_tests\n"
+ gdb_expect {
+ -re "
+.*movb r4,r26,.* <movb_tests>.*
+.*movb,= r4,r26,.* <movb_tests>.*
+.*movb,< r4,r26,.* <movb_tests>.*
+.*movb,od r4,r26,.* <movb_tests>.*
+.*movb,tr r4,r26,.* <movb_tests>.*
+.*movb,<> r4,r26,.* <movb_tests>.*
+.*movb,>= r4,r26,.* <movb_tests>.*
+.*movb,ev r4,r26,.* <movb_tests>.*
+.*$gdb_prompt $" { pass "movb_tests" }
+ -re "$gdb_prompt $" { fail "movb_tests" }
+ timeout { fail "(timeout) movb_tests " }
+ }
+
+ send_gdb "x/8i movb_nullified_tests\n"
+ gdb_expect {
+ -re "
+.*movb,n.*r4,r26,.* <movb_tests>.*
+.*movb,=,n.*r4,r26,.* <movb_tests>.*
+.*movb,<,n.*r4,r26,.* <movb_tests>.*
+.*movb,od,n.*r4,r26,.* <movb_tests>.*
+.*movb,tr,n.*r4,r26,.* <movb_tests>.*
+.*movb,<>,n.*r4,r26,.* <movb_tests>.*
+.*movb,>=,n.*r4,r26,.* <movb_tests>.*
+.*movb,ev,n.*r4,r26,.* <movb_tests>.*
+.*$gdb_prompt $" { pass "movb_nullified_tests" }
+ -re "$gdb_prompt $" { fail "movb_nullified_tests" }
+ timeout { fail "(timeout) movb_nullified_tests " }
+ }
+
+ send_gdb "x/8i movib_tests\n"
+ gdb_expect {
+ -re "
+.*movib 5,r26,.* <movib_tests>.*
+.*movib,= 5,r26,.* <movib_tests>.*
+.*movib,< 5,r26,.* <movib_tests>.*
+.*movib,od 5,r26,.* <movib_tests>.*
+.*movib,tr 5,r26,.* <movib_tests>.*
+.*movib,<> 5,r26,.* <movib_tests>.*
+.*movib,>= 5,r26,.* <movib_tests>.*
+.*movib,ev 5,r26,.* <movib_tests>.*
+.*$gdb_prompt $" { pass "movib_tests" }
+ -re "$gdb_prompt $" { fail "movib_tests" }
+ timeout { fail "(timeout) movib_tests " }
+ }
+
+ send_gdb "x/8i movib_nullified_tests\n"
+ gdb_expect {
+ -re "
+.*movib,n.*5,r26,.* <movib_tests>.*
+.*movib,=,n.*5,r26,.* <movib_tests>.*
+.*movib,<,n.*5,r26,.* <movib_tests>.*
+.*movib,od,n.*5,r26,.* <movib_tests>.*
+.*movib,tr,n.*5,r26,.* <movib_tests>.*
+.*movib,<>,n.*5,r26,.* <movib_tests>.*
+.*movib,>=,n.*5,r26,.* <movib_tests>.*
+.*movib,ev,n.*5,r26,.* <movib_tests>.*
+.*$gdb_prompt $" { pass "movib_nullified_tests" }
+ -re "$gdb_prompt $" { fail "movib_nullified_tests" }
+ timeout { fail "(timeout) movib_nullified_tests " }
+ }
+
+ send_gdb "x/8i comb_tests_1\n"
+ gdb_expect {
+ -re "
+.*comb r0,r4,.* <comb_tests_1>.*
+.*comb,= r0,r4,.* <comb_tests_1>.*
+.*comb,< r0,r4,.* <comb_tests_1>.*
+.*comb,<= r0,r4,.* <comb_tests_1>.*
+.*comb,<< r0,r4,.* <comb_tests_1>.*
+.*comb,<<= r0,r4,.* <comb_tests_1>.*
+.*comb,sv r0,r4,.* <comb_tests_1>.*
+.*comb,od r0,r4,.* <comb_tests_1>.*
+.*$gdb_prompt $" { pass "comb_tests_1" }
+ -re "$gdb_prompt $" { fail "comb_tests_1" }
+ timeout { fail "(timeout) comb_tests_1" }
+ }
+
+ send_gdb "x/8i comb_tests_2\n"
+ gdb_expect {
+ -re "
+.*combf r0,r4,.* <comb_tests_2>.*
+.*combf,= r0,r4,.* <comb_tests_2>.*
+.*combf,< r0,r4,.* <comb_tests_2>.*
+.*combf,<= r0,r4,.* <comb_tests_2>.*
+.*combf,<< r0,r4,.* <comb_tests_2>.*
+.*combf,<<= r0,r4,.* <comb_tests_2>.*
+.*combf,sv r0,r4,.* <comb_tests_2>.*
+.*combf,od r0,r4,.* <comb_tests_2>.*
+.*$gdb_prompt $" { pass "comb_tests_2" }
+ -re "$gdb_prompt $" { fail "comb_tests_2" }
+ timeout { fail "(timeout) comb_tests_2" }
+ }
+
+ send_gdb "x/8i comb_nullified_tests_1\n"
+ gdb_expect {
+ -re "
+.*comb,n r0,r4,.* <comb_tests_1>.*
+.*comb,=,n r0,r4,.* <comb_tests_1>.*
+.*comb,<,n r0,r4,.* <comb_tests_1>.*
+.*comb,<=,n r0,r4,.* <comb_tests_1>.*
+.*comb,<<,n r0,r4,.* <comb_tests_1>.*
+.*comb,<<=,n r0,r4,.* <comb_tests_1>.*
+.*comb,sv,n r0,r4,.* <comb_tests_1>.*
+.*comb,od,n r0,r4,.* <comb_tests_1>.*
+.*$gdb_prompt $" { pass "comb_nullified_tests_1" }
+ -re "$gdb_prompt $" { fail "comb_nullified_tests_1" }
+ timeout { fail "(timeout) comb_nullified_tests_1" }
+ }
+
+ send_gdb "x/8i comb_nullified_tests_2\n"
+ gdb_expect {
+ -re "
+.*combf,n r0,r4,.* <comb_tests_2>.*
+.*combf,=,n r0,r4,.* <comb_tests_2>.*
+.*combf,<,n r0,r4,.* <comb_tests_2>.*
+.*combf,<=,n r0,r4,.* <comb_tests_2>.*
+.*combf,<<,n r0,r4,.* <comb_tests_2>.*
+.*combf,<<=,n r0,r4,.* <comb_tests_2>.*
+.*combf,sv,n r0,r4,.* <comb_tests_2>.*
+.*combf,od,n r0,r4,.* <comb_tests_2>.*
+.*$gdb_prompt $" { pass "comb_nullified_tests_2" }
+ -re "$gdb_prompt $" { fail "comb_nullified_tests_2" }
+ timeout { fail "(timeout) comb_nullified_tests_2" }
+ }
+
+ send_gdb "x/8i comib_tests_1\n"
+ gdb_expect {
+ -re "
+.*comib 0,r4,.* <comib_tests_1>.*
+.*comib,= 0,r4,.* <comib_tests_1>.*
+.*comib,< 0,r4,.* <comib_tests_1>.*
+.*comib,<= 0,r4,.* <comib_tests_1>.*
+.*comib,<< 0,r4,.* <comib_tests_1>.*
+.*comib,<<= 0,r4,.* <comib_tests_1>.*
+.*comib,sv 0,r4,.* <comib_tests_1>.*
+.*comib,od 0,r4,.* <comib_tests_1>.*
+.*$gdb_prompt $" { pass "comib_tests_1" }
+ -re "$gdb_prompt $" { fail "comib_tests_1" }
+ timeout { fail "(timeout) comib_tests_1" }
+ }
+
+ send_gdb "x/8i comib_tests_2\n"
+ gdb_expect {
+ -re "
+.*comibf 0,r4,.* <comib_tests_2>.*
+.*comibf,= 0,r4,.* <comib_tests_2>.*
+.*comibf,< 0,r4,.* <comib_tests_2>.*
+.*comibf,<= 0,r4,.* <comib_tests_2>.*
+.*comibf,<< 0,r4,.* <comib_tests_2>.*
+.*comibf,<<= 0,r4,.* <comib_tests_2>.*
+.*comibf,sv 0,r4,.* <comib_tests_2>.*
+.*comibf,od 0,r4,.* <comib_tests_2>.*
+.*$gdb_prompt $" { pass "comib_tests_2" }
+ -re "$gdb_prompt $" { fail "comib_tests_2" }
+ timeout { fail "(timeout) comib_tests_2" }
+ }
+
+ send_gdb "x/8i comib_nullified_tests_1\n"
+ gdb_expect {
+ -re "
+.*comib,n 0,r4,.* <comib_tests_1>.*
+.*comib,=,n 0,r4,.* <comib_tests_1>.*
+.*comib,<,n 0,r4,.* <comib_tests_1>.*
+.*comib,<=,n 0,r4,.* <comib_tests_1>.*
+.*comib,<<,n 0,r4,.* <comib_tests_1>.*
+.*comib,<<=,n 0,r4,.* <comib_tests_1>.*
+.*comib,sv,n 0,r4,.* <comib_tests_1>.*
+.*comib,od,n 0,r4,.* <comib_tests_1>.*
+.*$gdb_prompt $" { pass "comib_nullified_tests_1" }
+ -re "$gdb_prompt $" { fail "comib_nullified_tests_1" }
+ timeout { fail "(timeout) comib_nullified_tests_1" }
+ }
+
+ send_gdb "x/8i comib_nullified_tests_2\n"
+ gdb_expect {
+ -re "
+.*comibf,n 0,r4,.* <comib_tests_2>.*
+.*comibf,=,n 0,r4,.* <comib_tests_2>.*
+.*comibf,<,n 0,r4,.* <comib_tests_2>.*
+.*comibf,<=,n 0,r4,.* <comib_tests_2>.*
+.*comibf,<<,n 0,r4,.* <comib_tests_2>.*
+.*comibf,<<=,n 0,r4,.* <comib_tests_2>.*
+.*comibf,sv,n 0,r4,.* <comib_tests_2>.*
+.*comibf,od,n 0,r4,.* <comib_tests_2>.*
+.*$gdb_prompt $" { pass "comib_nullified_tests_2" }
+ -re "$gdb_prompt $" { fail "comib_nullified_tests_2" }
+ timeout { fail "(timeout) comib_nullified_tests_2" }
+ }
+
+ send_gdb "x/8i addb_tests_1\n"
+ gdb_expect {
+ -re "
+.*addb r1,r4,.* <addb_tests_1>.*
+.*addb,= r1,r4,.* <addb_tests_1>.*
+.*addb,< r1,r4,.* <addb_tests_1>.*
+.*addb,<= r1,r4,.* <addb_tests_1>.*
+.*addb,nuv r1,r4,.* <addb_tests_1>.*
+.*addb,znv r1,r4,.* <addb_tests_1>.*
+.*addb,sv r1,r4,.* <addb_tests_1>.*
+.*addb,od r1,r4,.* <addb_tests_1>.*
+.*$gdb_prompt $" { pass "addb_tests_1" }
+ -re "$gdb_prompt $" { fail "addb_tests_1" }
+ timeout { fail "(timeout) addb_tests_1" }
+ }
+
+ send_gdb "x/8i addb_tests_2\n"
+ gdb_expect {
+ -re "
+.*addbf r1,r4,.* <addb_tests_2>.*
+.*addbf,= r1,r4,.* <addb_tests_2>.*
+.*addbf,< r1,r4,.* <addb_tests_2>.*
+.*addbf,<= r1,r4,.* <addb_tests_2>.*
+.*addbf,nuv r1,r4,.* <addb_tests_2>.*
+.*addbf,znv r1,r4,.* <addb_tests_2>.*
+.*addbf,sv r1,r4,.* <addb_tests_2>.*
+.*addbf,od r1,r4,.* <addb_tests_2>.*
+.*$gdb_prompt $" { pass "addb_tests_2" }
+ -re "$gdb_prompt $" { fail "addb_tests_2" }
+ timeout { fail "(timeout) addb_tests_2" }
+ }
+
+ send_gdb "x/8i addb_nullified_tests_1\n"
+ gdb_expect {
+ -re "
+.*addb,n r1,r4,.* <addb_tests_1>.*
+.*addb,=,n r1,r4,.* <addb_tests_1>.*
+.*addb,<,n r1,r4,.* <addb_tests_1>.*
+.*addb,<=,n r1,r4,.* <addb_tests_1>.*
+.*addb,nuv,n r1,r4,.* <addb_tests_1>.*
+.*addb,znv,n r1,r4,.* <addb_tests_1>.*
+.*addb,sv,n r1,r4,.* <addb_tests_1>.*
+.*addb,od,n r1,r4,.* <addb_tests_1>.*
+.*$gdb_prompt $" { pass "addb_nullified_tests_1" }
+ -re "$gdb_prompt $" { fail "addb_nullified_tests_1" }
+ timeout { fail "(timeout) addb_nullified_tests_1" }
+ }
+
+ send_gdb "x/8i addb_nullified_tests_2\n"
+ gdb_expect {
+ -re "
+.*addbf,n r1,r4,.* <addb_tests_2>.*
+.*addbf,=,n r1,r4,.* <addb_tests_2>.*
+.*addbf,<,n r1,r4,.* <addb_tests_2>.*
+.*addbf,<=,n r1,r4,.* <addb_tests_2>.*
+.*addbf,nuv,n r1,r4,.* <addb_tests_2>.*
+.*addbf,znv,n r1,r4,.* <addb_tests_2>.*
+.*addbf,sv,n r1,r4,.* <addb_tests_2>.*
+.*addbf,od,n r1,r4,.* <addb_tests_2>.*
+.*$gdb_prompt $" { pass "addb_nullified_tests_2" }
+ -re "$gdb_prompt $" { fail "addb_nullified_tests_2" }
+ timeout { fail "(timeout) addb_nullified_tests_2" }
+ }
+
+ send_gdb "x/8i addib_tests_1\n"
+ gdb_expect {
+ -re "
+.*addib -1,r4,.* <addib_tests_1>.*
+.*addib,= -1,r4,.* <addib_tests_1>.*
+.*addib,< -1,r4,.* <addib_tests_1>.*
+.*addib,<= -1,r4,.* <addib_tests_1>.*
+.*addib,nuv -1,r4,.* <addib_tests_1>.*
+.*addib,znv -1,r4,.* <addib_tests_1>.*
+.*addib,sv -1,r4,.* <addib_tests_1>.*
+.*addib,od -1,r4,.* <addib_tests_1>.*
+.*$gdb_prompt $" { pass "addib_tests_1" }
+ -re "$gdb_prompt $" { fail "addib_tests_1" }
+ timeout { fail "(timeout) addib_tests_1" }
+ }
+
+ send_gdb "x/8i addib_tests_2\n"
+ gdb_expect {
+ -re "
+.*addibf -1,r4,.* <addib_tests_2>.*
+.*addibf,= -1,r4,.* <addib_tests_2>.*
+.*addibf,< -1,r4,.* <addib_tests_2>.*
+.*addibf,<= -1,r4,.* <addib_tests_2>.*
+.*addibf,nuv -1,r4,.* <addib_tests_2>.*
+.*addibf,znv -1,r4,.* <addib_tests_2>.*
+.*addibf,sv -1,r4,.* <addib_tests_2>.*
+.*addibf,od -1,r4,.* <addib_tests_2>.*
+.*$gdb_prompt $" { pass "addib_tests_2" }
+ -re "$gdb_prompt $" { fail "addib_tests_2" }
+ timeout { fail "(timeout) addib_tests_2" }
+ }
+
+ send_gdb "x/8i addib_nullified_tests_1\n"
+ gdb_expect {
+ -re "
+.*addib,n -1,r4,.* <addib_tests_1>.*
+.*addib,=,n -1,r4,.* <addib_tests_1>.*
+.*addib,<,n -1,r4,.* <addib_tests_1>.*
+.*addib,<=,n -1,r4,.* <addib_tests_1>.*
+.*addib,nuv,n -1,r4,.* <addib_tests_1>.*
+.*addib,znv,n -1,r4,.* <addib_tests_1>.*
+.*addib,sv,n -1,r4,.* <addib_tests_1>.*
+.*addib,od,n -1,r4,.* <addib_tests_1>.*
+.*$gdb_prompt $" { pass "addb_nullified_tests_1" }
+ -re "$gdb_prompt $" { fail "addb_nullified_tests_1" }
+ timeout { fail "(timeout) addb_nullified_tests_1" }
+ }
+
+ send_gdb "x/8i addib_nullified_tests_2\n"
+ gdb_expect {
+ -re "
+.*addibf,n -1,r4,.* <addib_tests_2>.*
+.*addibf,=,n -1,r4,.* <addib_tests_2>.*
+.*addibf,<,n -1,r4,.* <addib_tests_2>.*
+.*addibf,<=,n -1,r4,.* <addib_tests_2>.*
+.*addibf,nuv,n -1,r4,.* <addib_tests_2>.*
+.*addibf,znv,n -1,r4,.* <addib_tests_2>.*
+.*addibf,sv,n -1,r4,.* <addib_tests_2>.*
+.*addibf,od,n -1,r4,.* <addib_tests_2>.*
+.*$gdb_prompt $" { pass "addb_nullified_tests_2" }
+ -re "$gdb_prompt $" { fail "addb_nullified_tests_2" }
+ timeout { fail "(timeout) addb_nullified_tests_2" }
+ }
+
+ send_gdb "x/8i bb_tests\n"
+ gdb_expect {
+ -re "
+.*bvb,< r4,.* <bb_tests>.*
+.*bvb,>= r4,.* <bb_tests>.*
+.*bvb,<,n r4,.* <bb_tests>.*
+.*bvb,>=,n r4,.* <bb_tests>.*
+.*bb,< r4,5,.* <bb_tests>.*
+.*bb,>= r4,5,.* <bb_tests>.*
+.*bb,<,n r4,5,.* <bb_tests>.*
+.*bb,>=,n r4,5,.* <bb_tests>.*
+.*$gdb_prompt $" { pass "bb_tests" }
+ -re "$gdb_prompt $" { fail "bb_tests" }
+ timeout { fail "(timeout) bb_tests " }
+ }
+}
+
+proc all_integer_computational_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ set add_insns [list {add} {addl} {addo} {addc} {addco} \
+ {sh1add} {sh1addl} {sh1addo} \
+ {sh2add} {sh2addl} {sh2addo} \
+ {sh3add} {sh3addl} {sh3addo} ]
+
+ foreach i $add_insns {
+ send_gdb "x/16i $i"; send_gdb "_tests\n"
+ gdb_expect {
+ -re "
+.*$i r4,r5,r6.*
+.*$i,= r4,r5,r6.*
+.*$i,< r4,r5,r6.*
+.*$i,<= r4,r5,r6.*
+.*$i,nuv r4,r5,r6.*
+.*$i,znv r4,r5,r6.*
+.*$i,sv r4,r5,r6.*
+.*$i,od r4,r5,r6.*
+.*$i,tr r4,r5,r6.*
+.*$i,<> r4,r5,r6.*
+.*$i,>= r4,r5,r6.*
+.*$i,> r4,r5,r6.*
+.*$i,uv r4,r5,r6.*
+.*$i,vnz r4,r5,r6.*
+.*$i,nsv r4,r5,r6.*
+.*$i,ev r4,r5,r6.*
+.*$gdb_prompt $" { pass "$i tests" }
+ -re "$gdb_prompt $" { fail "$i tests" }
+ timeout { fail "(timeout) $i tests" }
+ }
+ }
+
+ set sub_insns [list {sub} {subo} {subb} {subbo} {subt} {subto} \
+ {ds} {comclr} ]
+
+ foreach i $sub_insns {
+ send_gdb "x/16i $i"; send_gdb "_tests\n"
+ gdb_expect {
+ -re "
+.*$i r4,r5,r6.*
+.*$i,= r4,r5,r6.*
+.*$i,< r4,r5,r6.*
+.*$i,<= r4,r5,r6.*
+.*$i,<< r4,r5,r6.*
+.*$i,<<= r4,r5,r6.*
+.*$i,sv r4,r5,r6.*
+.*$i,od r4,r5,r6.*
+.*$i,tr r4,r5,r6.*
+.*$i,<> r4,r5,r6.*
+.*$i,>= r4,r5,r6.*
+.*$i,> r4,r5,r6.*
+.*$i,>>= r4,r5,r6.*
+.*$i,>> r4,r5,r6.*
+.*$i,nsv r4,r5,r6.*
+.*$i,ev r4,r5,r6.*
+.*$gdb_prompt $" { pass "$i tests" }
+ -re "$gdb_prompt $" { fail "$i tests" }
+ timeout { fail "(timeout) $i tests" }
+ }
+ }
+
+ set logical_insns [list {or} {xor} {and} {andcm} ]
+
+ foreach i $logical_insns {
+ send_gdb "x/10i $i"; send_gdb "_tests\n"
+ gdb_expect {
+ -re "
+.*$i r4,r5,r6.*
+.*$i,= r4,r5,r6.*
+.*$i,< r4,r5,r6.*
+.*$i,<= r4,r5,r6.*
+.*$i,od r4,r5,r6.*
+.*$i,tr r4,r5,r6.*
+.*$i,<> r4,r5,r6.*
+.*$i,>= r4,r5,r6.*
+.*$i,> r4,r5,r6.*
+.*$i,ev r4,r5,r6.*
+.*$gdb_prompt $" { pass "$i tests" }
+ -re "$gdb_prompt $" { fail "$i tests" }
+ timeout { fail "(timeout) $i tests" }
+ }
+ }
+
+ set unit_insns1 [list {uxor} {uaddcm} {uaddcmt} ]
+
+ foreach i $unit_insns1 {
+ send_gdb "x/12i $i"; send_gdb "_tests\n"
+ gdb_expect {
+ -re "
+.*$i r4,r5,r6.*
+.*$i,sbz r4,r5,r6.*
+.*$i,shz r4,r5,r6.*
+.*$i,sdc r4,r5,r6.*
+.*$i,sbc r4,r5,r6.*
+.*$i,shc r4,r5,r6.*
+.*$i,tr r4,r5,r6.*
+.*$i,nbz r4,r5,r6.*
+.*$i,nhz r4,r5,r6.*
+.*$i,ndc r4,r5,r6.*
+.*$i,nbc r4,r5,r6.*
+.*$i,nhc r4,r5,r6.*
+.*$gdb_prompt $" { pass "$i tests" }
+ -re "$gdb_prompt $" { fail "$i tests" }
+ timeout { fail "(timeout) $i tests" }
+ }
+ }
+
+ set unit_insns2 [list {dcor} {idcor} ]
+
+ foreach i $unit_insns2 {
+ send_gdb "x/12i $i"; send_gdb "_tests\n"
+ gdb_expect {
+ -re "
+.*$i r4,r5.*
+.*$i,sbz r4,r5.*
+.*$i,shz r4,r5.*
+.*$i,sdc r4,r5.*
+.*$i,sbc r4,r5.*
+.*$i,shc r4,r5.*
+.*$i,tr r4,r5.*
+.*$i,nbz r4,r5.*
+.*$i,nhz r4,r5.*
+.*$i,ndc r4,r5.*
+.*$i,nbc r4,r5.*
+.*$i,nhc r4,r5.*
+.*$gdb_prompt $" { pass "$i tests" }
+ -re "$gdb_prompt $" { fail "$i tests" }
+ timeout { fail "(timeout) $i tests" }
+ }
+ }
+
+ set addi_insns [list {addi} {addio} {addit} {addito} ]
+
+ foreach i $addi_insns {
+ send_gdb "x/16i $i"; send_gdb "_tests\n"
+ gdb_expect {
+ -re "
+.*$i 7b,r5,r6.*
+.*$i,= 7b,r5,r6.*
+.*$i,< 7b,r5,r6.*
+.*$i,<= 7b,r5,r6.*
+.*$i,nuv 7b,r5,r6.*
+.*$i,znv 7b,r5,r6.*
+.*$i,sv 7b,r5,r6.*
+.*$i,od 7b,r5,r6.*
+.*$i,tr 7b,r5,r6.*
+.*$i,<> 7b,r5,r6.*
+.*$i,>= 7b,r5,r6.*
+.*$i,> 7b,r5,r6.*
+.*$i,uv 7b,r5,r6.*
+.*$i,vnz 7b,r5,r6.*
+.*$i,nsv 7b,r5,r6.*
+.*$i,ev 7b,r5,r6.*
+.*$gdb_prompt $" { pass "$i tests" }
+ -re "$gdb_prompt $" { fail "$i tests" }
+ timeout { fail "(timeout) $i tests" }
+ }
+ }
+
+ set subi_insns [list {subi} {subio} {comiclr} ]
+
+ foreach i $subi_insns {
+ send_gdb "x/16i $i"; send_gdb "_tests\n"
+ gdb_expect {
+ -re "
+.*$i 7b,r5,r6.*
+.*$i,= 7b,r5,r6.*
+.*$i,< 7b,r5,r6.*
+.*$i,<= 7b,r5,r6.*
+.*$i,<< 7b,r5,r6.*
+.*$i,<<= 7b,r5,r6.*
+.*$i,sv 7b,r5,r6.*
+.*$i,od 7b,r5,r6.*
+.*$i,tr 7b,r5,r6.*
+.*$i,<> 7b,r5,r6.*
+.*$i,>= 7b,r5,r6.*
+.*$i,> 7b,r5,r6.*
+.*$i,>>= 7b,r5,r6.*
+.*$i,>> 7b,r5,r6.*
+.*$i,nsv 7b,r5,r6.*
+.*$i,ev 7b,r5,r6.*
+.*$gdb_prompt $" { pass "$i tests" }
+ -re "$gdb_prompt $" { fail "$i tests" }
+ timeout { fail "(timeout) $i tests" }
+ }
+ }
+
+ send_gdb "x/8i vshd_tests\n"
+ gdb_expect {
+ -re "
+.*vshd r4,r5,r6.*
+.*vshd,= r4,r5,r6.*
+.*vshd,< r4,r5,r6.*
+.*vshd,od r4,r5,r6.*
+.*vshd,tr r4,r5,r6.*
+.*vshd,<> r4,r5,r6.*
+.*vshd,>= r4,r5,r6.*
+.*vshd,ev r4,r5,r6.*
+.*$gdb_prompt $" { pass "vshd tests" }
+ -re "$gdb_prompt $" { fail "vshd tests" }
+ timeout { fail "(timeout) "vshd tests" }
+ }
+
+ send_gdb "x/8i shd_tests\n"
+ gdb_expect {
+ -re "
+.*shd r4,r5,5,r6.*
+.*shd,= r4,r5,5,r6.*
+.*shd,< r4,r5,5,r6.*
+.*shd,od r4,r5,5,r6.*
+.*shd,tr r4,r5,5,r6.*
+.*shd,<> r4,r5,5,r6.*
+.*shd,>= r4,r5,5,r6.*
+.*shd,ev r4,r5,5,r6.*
+.*$gdb_prompt $" { pass "shd tests" }
+ -re "$gdb_prompt $" { fail "shd tests" }
+ timeout { fail "(timeout) "shd tests" }
+ }
+
+ set extract_insns1 [list {extru} {extrs} {zdep} {dep} ]
+
+ foreach i $extract_insns1 {
+ send_gdb "x/8i $i"; send_gdb "_tests\n"
+ gdb_expect {
+ -re "
+.*$i r4,5,10,r6.*
+.*$i,= r4,5,10,r6.*
+.*$i,< r4,5,10,r6.*
+.*$i,od r4,5,10,r6.*
+.*$i,tr r4,5,10,r6.*
+.*$i,<> r4,5,10,r6.*
+.*$i,>= r4,5,10,r6.*
+.*$i,ev r4,5,10,r6.*
+.*$gdb_prompt $" { pass "$i tests" }
+ -re "$gdb_prompt $" { fail "$i tests" }
+ timeout { fail "(timeout) $i tests" }
+ }
+ }
+
+ set extract_insns2 [list {vextru} {vextrs} {zvdep} {vdep} ]
+
+ foreach i $extract_insns2 {
+ send_gdb "x/8i $i"; send_gdb "_tests\n"
+ gdb_expect {
+ -re "
+.*$i r4,5,r6.*
+.*$i,= r4,5,r6.*
+.*$i,< r4,5,r6.*
+.*$i,od r4,5,r6.*
+.*$i,tr r4,5,r6.*
+.*$i,<> r4,5,r6.*
+.*$i,>= r4,5,r6.*
+.*$i,ev r4,5,r6.*
+.*$gdb_prompt $" { pass "$i tests" }
+ -re "$gdb_prompt $" { fail "$i tests" }
+ timeout { fail "(timeout) $i tests" }
+ }
+ }
+
+ set extract_insns3 [list {vdepi} {zvdepi} ]
+
+ foreach i $extract_insns3 {
+ send_gdb "x/8i $i"; send_gdb "_tests\n"
+ gdb_expect {
+ -re "
+.*$i -1,5,r6.*
+.*$i,= -1,5,r6.*
+.*$i,< -1,5,r6.*
+.*$i,od -1,5,r6.*
+.*$i,tr -1,5,r6.*
+.*$i,<> -1,5,r6.*
+.*$i,>= -1,5,r6.*
+.*$i,ev -1,5,r6.*
+.*$gdb_prompt $" { pass "$i tests" }
+ -re "$gdb_prompt $" { fail "$i tests" }
+ timeout { fail "(timeout) $i tests" }
+ }
+ }
+
+ set extract_insns4 [list {depi} {zdepi} ]
+
+ foreach i $extract_insns4 {
+ send_gdb "x/8i $i"; send_gdb "_tests\n"
+ gdb_expect {
+ -re "
+.*$i -1,4,10,r6.*
+.*$i,= -1,4,10,r6.*
+.*$i,< -1,4,10,r6.*
+.*$i,od -1,4,10,r6.*
+.*$i,tr -1,4,10,r6.*
+.*$i,<> -1,4,10,r6.*
+.*$i,>= -1,4,10,r6.*
+.*$i,ev -1,4,10,r6.*
+.*$gdb_prompt $" { pass "$i tests" }
+ -re "$gdb_prompt $" { fail "$i tests" }
+ timeout { fail "(timeout) $i tests" }
+ }
+ }
+}
+
+proc all_system_control_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/14i system_control_tests\n"
+ gdb_expect {
+ -re "
+.*break 5,c.*
+.*rfi.*
+.*rfir.*
+.*ssm 5,r4.*
+.*rsm 5,r4.*
+.*mtsm r4.*
+.*ldsid \\(sr0,r5\\),r4.*
+.*mtsp r4,sr0.*
+.*mtctl r4,ccr.*
+.*mfsp sr0,r4.*
+.*mfctl ccr,r4.*
+.*sync.*
+.*syncdma.*
+.*diag 4d2.*
+.*$gdb_prompt $" { pass "system_constrol_tests" }
+ -re "$gdb_prompt $" { fail "system_control_tests" }
+ timeout { file "(timeout) system_control_tests" }
+ }
+
+ send_gdb "x/4i probe_tests\n"
+ gdb_expect {
+ -re "
+.*prober \\(sr0,r5\\),r6,r7.*
+.*proberi \\(sr0,r5\\),1,r7.*
+.*probew \\(sr0,r5\\),r6,r7.*
+.*probewi \\(sr0,r5\\),1,r7.*
+.*$gdb_prompt $" { pass "probe_tests" }
+ -re "$gdb_prompt $" { fail "probe_tests" }
+ timeout { file "(timeout) probe_tests" }
+ }
+
+ # lci uses the same bit pattern as lha, so accept lha.
+ send_gdb "x/5i lpa_tests\n"
+ gdb_expect {
+ -re "
+.*lpa r4\\(sr0,r5\\),r6.*
+.*lpa,m r4\\(sr0,r5\\),r6.*
+.*lha r4\\(sr0,r5\\),r6.*
+.*lha,m r4\\(sr0,r5\\),r6.*
+.*lha r4\\(sr0,r5\\),r6.*
+.*$gdb_prompt $" { pass "lpa_tests" }
+ -re "$gdb_prompt $" { fail "lpa_tests" }
+ timeout { file "(timeout) lpa_tests" }
+ }
+
+ send_gdb "x/18i purge_tests\n"
+ gdb_expect {
+ -re "
+.*pdtlb r4\\(sr0,r5\\).*
+.*pdtlb,m r4\\(sr0,r5\\).*
+.*pitlb r4\\(sr0,r5\\).*
+.*pitlb,m r4\\(sr0,r5\\).*
+.*pdtlbe r4\\(sr0,r5\\).*
+.*pdtlbe,m r4\\(sr0,r5\\).*
+.*pitlbe r4\\(sr0,r5\\).*
+.*pitlbe,m r4\\(sr0,r5\\).*
+.*pdc r4\\(sr0,r5\\).*
+.*pdc,m r4\\(sr0,r5\\).*
+.*fdc r4\\(sr0,r5\\).*
+.*fdc,m r4\\(sr0,r5\\).*
+.*fic r4\\(sr0,r5\\).*
+.*fic,m r4\\(sr0,r5\\).*
+.*fdce r4\\(sr0,r5\\).*
+.*fdce,m r4\\(sr0,r5\\).*
+.*fice r4\\(sr0,r5\\).*
+.*fice,m r4\\(sr0,r5\\).*
+.*$gdb_prompt $" { pass "purge_tests" }
+ -re "$gdb_prompt $" { fail "purge_tests" }
+ timeout { file "(timeout) purge_tests" }
+ }
+
+ send_gdb "x/4i insert_tests\n"
+ gdb_expect {
+ -re "
+.*idtlba r4,\\(sr0,r5\\).*
+.*iitlba r4,\\(sr0,r5\\).*
+.*idtlbp r4,\\(sr0,r5\\).*
+.*iitlbp r4,\\(sr0,r5\\).*
+.*$gdb_prompt $" { pass "insert_tests" }
+ -re "$gdb_prompt $" { fail "insert_tests" }
+ timeout { file "(timeout) insert_tests" }
+ }
+
+}
+
+proc all_fpu_memory_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/20i fpu_memory_indexing_tests\n"
+ gdb_expect {
+ -re "
+.*fldwx r4\\(sr0,r5\\),fr6.*
+.*fldwx,s r4\\(sr0,r5\\),fr6.*
+.*fldwx,m r4\\(sr0,r5\\),fr6.*
+.*fldwx,sm r4\\(sr0,r5\\),fr6.*
+.*flddx r4\\(sr0,r5\\),fr6.*
+.*flddx,s r4\\(sr0,r5\\),fr6.*
+.*flddx,m r4\\(sr0,r5\\),fr6.*
+.*flddx,sm r4\\(sr0,r5\\),fr6.*
+.*fstwx fr6,r4\\(sr0,r5\\).*
+.*fstwx,s fr6,r4\\(sr0,r5\\).*
+.*fstwx,m fr6,r4\\(sr0,r5\\).*
+.*fstwx,sm fr6,r4\\(sr0,r5\\).*
+.*fstdx fr6,r4\\(sr0,r5\\).*
+.*fstdx,s fr6,r4\\(sr0,r5\\).*
+.*fstdx,m fr6,r4\\(sr0,r5\\).*
+.*fstdx,sm fr6,r4\\(sr0,r5\\).*
+.*fstqx fr6,r4\\(sr0,r5\\).*
+.*fstqx,s fr6,r4\\(sr0,r5\\).*
+.*fstqx,m fr6,r4\\(sr0,r5\\).*
+.*fstqx,sm fr6,r4\\(sr0,r5\\).*
+.*$gdb_prompt $" { pass "fpu_memory_indexing_tests" }
+ -re "$gdb_prompt $" { fail "fpu_memory_indexing_tests" }
+ timeout { file "(timeout) fpu_memory_indexing_tests" }
+ }
+
+ send_gdb "x/15i fpu_short_memory_tests\n"
+ gdb_expect {
+ -re "
+.*fldws 0\\(sr0,r5\\),fr6.*
+.*fldws,mb 0\\(sr0,r5\\),fr6.*
+.*fldws,ma 0\\(sr0,r5\\),fr6.*
+.*fldds 0\\(sr0,r5\\),fr6.*
+.*fldds,mb 0\\(sr0,r5\\),fr6.*
+.*fldds,ma 0\\(sr0,r5\\),fr6.*
+.*fstws fr6,0\\(sr0,r5\\).*
+.*fstws,mb fr6,0\\(sr0,r5\\).*
+.*fstws,ma fr6,0\\(sr0,r5\\).*
+.*fstds fr6,0\\(sr0,r5\\).*
+.*fstds,mb fr6,0\\(sr0,r5\\).*
+.*fstds,ma fr6,0\\(sr0,r5\\).*
+.*fstqs fr6,0\\(sr0,r5\\).*
+.*fstqs,mb fr6,0\\(sr0,r5\\).*
+.*fstqs,ma fr6,0\\(sr0,r5\\).*
+.*$gdb_prompt $" { pass "fpu_short_memory_tests" }
+ -re "$gdb_prompt $" { fail "fpu_short_memory_tests" }
+ timeout { file "(timeout) fpu_short_memory_tests" }
+ }
+
+}
+
+proc all_fpu_computational_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/1i fpu_misc_tests\n"
+ gdb_expect {
+ -re "
+.*ftest.*
+.*$gdb_prompt $" { pass "fpu_misc_tests" }
+ -re "$gdb_prompt $" { fail "fpu_misc_tests" }
+ timeout { file "(timeout) fpu_misc_tests" }
+ }
+
+ set fpu_two_op_insns [list {fcpy} {fabs} {fsqrt} {frnd} ]
+
+ foreach i $fpu_two_op_insns {
+ send_gdb "x/5i $i"; send_gdb "_tests\n"
+ gdb_expect {
+ -re "
+.*$i,sgl fr5,fr10.*
+.*$i,dbl fr5,fr10.*
+.*$i,quad fr5,fr10.*
+.*$i,sgl fr20,fr24.*
+.*$i,dbl fr20,fr24.*
+.*$gdb_prompt $" { pass "$i tests" }
+ -re "$gdb_prompt $" { fail "$i tests" }
+ timeout { fail "(timeout) $i tests" }
+ }
+ }
+
+ set fpu_conversions [list {fcnvff} {fcnvxf} {fcnvfx} {fcnvfxt} ]
+
+ foreach i $fpu_conversions {
+ send_gdb "x/18i $i"; send_gdb "_tests\n"
+ gdb_expect {
+ -re "
+.*$i,sgl,sgl fr5,fr10.*
+.*$i,sgl,dbl fr5,fr10.*
+.*$i,sgl,quad fr5,fr10.*
+.*$i,dbl,sgl fr5,fr10.*
+.*$i,dbl,dbl fr5,fr10.*
+.*$i,dbl,quad fr5,fr10.*
+.*$i,quad,sgl fr5,fr10.*
+.*$i,quad,dbl fr5,fr10.*
+.*$i,quad,quad fr5,fr10.*
+.*$i,sgl,sgl fr20,fr24.*
+.*$i,sgl,dbl fr20,fr24.*
+.*$i,sgl,quad fr20,fr24.*
+.*$i,dbl,sgl fr20,fr24.*
+.*$i,dbl,dbl fr20,fr24.*
+.*$i,dbl,quad fr20,fr24.*
+.*$i,quad,sgl fr20,fr24.*
+.*$i,quad,dbl fr20,fr24.*
+.*$i,quad,quad fr20,fr24.*
+.*$gdb_prompt $" { pass "$i tests" }
+ -re "$gdb_prompt $" { fail "$i tests" }
+ timeout { fail "(timeout) $i tests" }
+ }
+ }
+
+ set fpu_three_op_insns [list {fadd} {fsub} {fmpy} {fdiv} {frem} ]
+
+ foreach i $fpu_three_op_insns {
+ send_gdb "x/6i $i"; send_gdb "_tests\n"
+ gdb_expect {
+ -re "
+.*$i,sgl fr4,fr8,fr12.*
+.*$i,dbl fr4,fr8,fr12.*
+.*$i,quad fr4,fr8,fr12.*
+.*$i,sgl fr20,fr24,fr28.*
+.*$i,dbl fr20,fr24,fr28.*
+.*$i,quad fr20,fr24,fr28.*
+.*$gdb_prompt $" { pass "$i tests" }
+ -re "$gdb_prompt $" { fail "$i tests" }
+ timeout { fail "(timeout) $i tests" }
+ }
+ }
+
+ send_gdb "x/4i fmpy_addsub_tests\n"
+ gdb_expect {
+ -re "
+.*fmpyadd,sgl fr16,fr17,fr18,fr19,fr20.*
+.*fmpyadd,dbl fr16,fr17,fr18,fr19,fr20.*
+.*fmpysub,sgl fr16,fr17,fr18,fr19,fr20.*
+.*fmpysub,dbl fr16,fr17,fr18,fr19,fr20.*
+.*$gdb_prompt $" { pass "fmpy_addsub_tests" }
+ -re "$gdb_prompt $" { fail "fmpy_addsub_tests" }
+ timeout { fail "(timeout) fmpy_addsub_tests" }
+ }
+
+ send_gdb "x/i xmpyu_tests\n"
+ gdb_expect {
+ -re "
+.*xmpyu fr4,fr5,fr6.*
+.*$gdb_prompt $" {pass "xmpyu_tests" }
+ -re "$gdb_prompt $" {fail "xmpyu_tests" }
+ timeout { fail "(timeout) xmpyu_tests" }
+ }
+
+}
+
+proc all_fpu_comparison_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ set fpu_comparison_formats [list {sgl} {dbl} {quad} ]
+
+ foreach i $fpu_comparison_formats {
+ send_gdb "x/8i fcmp_$i"; send_gdb "_tests_1\n"
+ gdb_expect {
+ -re "
+.*fcmp,$i,false\\? fr4,fr5.*
+.*fcmp,$i,false fr4,fr5.*
+.*fcmp,$i,\\? fr4,fr5.*
+.*fcmp,$i,!<=> fr4,fr5.*
+.*fcmp,$i,= fr4,fr5.*
+.*fcmp,$i,=t fr4,fr5.*
+.*fcmp,$i,\\?= fr4,fr5.*
+.*fcmp,$i,!<> fr4,fr5.*
+.*$gdb_prompt $" { pass "$i tests (part1) " }
+ -re "$gdb_prompt $" { fail "fcmp_$i tests (part1) " }
+ timeout { fail "(timeout) fcmp_$i tests (part1) " }
+ }
+
+ send_gdb "x/8i fcmp_$i"; send_gdb "_tests_2\n"
+ gdb_expect {
+ -re "
+.*fcmp,$i,!\\?>= fr4,fr5.*
+.*fcmp,$i,< fr4,fr5.*
+.*fcmp,$i,\\?< fr4,fr5.*
+.*fcmp,$i,!>= fr4,fr5.*
+.*fcmp,$i,!\\?> fr4,fr5.*
+.*fcmp,$i,<= fr4,fr5.*
+.*fcmp,$i,\\?<= fr4,fr5.*
+.*fcmp,$i,!> fr4,fr5.*
+.*$gdb_prompt $" { pass "$i tests (part2) " }
+ -re "$gdb_prompt $" { fail "fcmp_$i tests (part2) " }
+ timeout { fail "(timeout) fcmp_$i tests (part2) " }
+ }
+
+ send_gdb "x/8i fcmp_$i"; send_gdb "_tests_3\n"
+ gdb_expect {
+ -re "
+.*fcmp,$i,!\\?<= fr4,fr5.*
+.*fcmp,$i,> fr4,fr5.*
+.*fcmp,$i,\\?> fr4,fr5.*
+.*fcmp,$i,!<= fr4,fr5.*
+.*fcmp,$i,!\\?< fr4,fr5.*
+.*fcmp,$i,>= fr4,fr5.*
+.*fcmp,$i,\\?>= fr4,fr5.*
+.*fcmp,$i,!< fr4,fr5.*
+.*$gdb_prompt $" { pass "$i tests (part3) " }
+ -re "$gdb_prompt $" { fail "fcmp_$i tests (part3) " }
+ timeout { fail "(timeout) fcmp_$i tests (part3) " }
+ }
+
+ send_gdb "x/8i fcmp_$i"; send_gdb "_tests_4\n"
+ gdb_expect {
+ -re "
+.*fcmp,$i,!\\?= fr4,fr5.*
+.*fcmp,$i,<> fr4,fr5.*
+.*fcmp,$i,!= fr4,fr5.*
+.*fcmp,$i,!=t fr4,fr5.*
+.*fcmp,$i,!\\? fr4,fr5.*
+.*fcmp,$i,<=> fr4,fr5.*
+.*fcmp,$i,true\\? fr4,fr5.*
+.*fcmp,$i,true fr4,fr5.*
+.*$gdb_prompt $" { pass "$i tests (part4) " }
+ -re "$gdb_prompt $" { fail "fcmp_$i tests (part4) " }
+ timeout { fail "(timeout) fcmp_$i tests (part4) " }
+ }
+ }
+}
+
+proc all_special_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/4i special_tests\n"
+ gdb_expect {
+ -re "
+.*gfw r4\\(sr0,r5\\).*
+.*gfw,m r4\\(sr0,r5\\).*
+.*gfr r4\\(sr0,r5\\).*
+.*gfr,m r4\\(sr0,r5\\).*
+.*$gdb_prompt $" { pass "special tests" }
+ -re "$gdb_prompt $" { fail "special tests" }
+ timeout { fail "(timeout) special tests " }
+ }
+
+}
+
+proc all_sfu_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/16i sfu_tests\n"
+ gdb_expect {
+ -re "
+.*spop0,4,5.*
+.*spop0,4,73.*
+.*spop0,4,5,n.*
+.*spop0,4,73,n.*
+.*spop1,4,5 r5.*
+.*spop1,4,73 r5.*
+.*spop1,4,5,n r5.*
+.*spop1,4,73,n r5.*
+.*spop2,4,5 r5.*
+.*spop2,4,73 r5.*
+.*spop2,4,5,n r5.*
+.*spop2,4,73,n r5.*
+.*spop3,4,5 r5,r6.*
+.*spop3,4,73 r5,r6.*
+.*spop3,4,5,n r5,r6.*
+.*spop3,4,73,n r5,r6.*
+.*$gdb_prompt $" { pass "sfu tests" }
+ -re "$gdb_prompt $" { fail "sfu tests" }
+ timeout { fail "(timeout) sfu tests " }
+ }
+}
+
+proc all_copr_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/4i copr_tests\n"
+ gdb_expect {
+ -re "
+.*copr,4,5.*
+.*copr,4,73.*
+.*copr,4,5,n.*
+.*copr,4,73,n.*
+.*$gdb_prompt $" { pass "copr tests" }
+ -re "$gdb_prompt $" { fail "copr tests" }
+ timeout { fail "(timeout) copr tests " }
+ }
+}
+
+proc all_copr_mem_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/8i copr_indexing_load\n"
+ gdb_expect {
+ -re "
+.*cldwx,4 r5\\(sr0,r4\\),r26.*
+.*cldwx,4,s r5\\(sr0,r4\\),r26.*
+.*cldwx,4,m r5\\(sr0,r4\\),r26.*
+.*cldwx,4,sm r5\\(sr0,r4\\),r26.*
+.*clddx,4 r5\\(sr0,r4\\),r26.*
+.*clddx,4,s r5\\(sr0,r4\\),r26.*
+.*clddx,4,m r5\\(sr0,r4\\),r26.*
+.*clddx,4,sm r5\\(sr0,r4\\),r26.*
+.*$gdb_prompt $" { pass "copr indexed load tests" }
+ -re "$gdb_prompt $" { fail "copr indexed load tests" }
+ timeout { fail "(timeout) copr indexed load tests " }
+ }
+
+ send_gdb "x/8i copr_indexing_store\n"
+ gdb_expect {
+ -re "
+.*cstwx,4 r26,r5\\(sr0,r4\\).*
+.*cstwx,4,s r26,r5\\(sr0,r4\\).*
+.*cstwx,4,m r26,r5\\(sr0,r4\\).*
+.*cstwx,4,sm r26,r5\\(sr0,r4\\).*
+.*cstdx,4 r26,r5\\(sr0,r4\\).*
+.*cstdx,4,s r26,r5\\(sr0,r4\\).*
+.*cstdx,4,m r26,r5\\(sr0,r4\\).*
+.*cstdx,4,sm r26,r5\\(sr0,r4\\).*
+.*$gdb_prompt $" { pass "copr indexed store tests" }
+ -re "$gdb_prompt $" { fail "copr indexed store tests" }
+ timeout { fail "(timeout) copr indexed load tests " }
+ }
+
+ send_gdb "x/12i copr_short_memory\n"
+ gdb_expect {
+ -re "
+.*cldws,4 0\\(sr0,r4\\),r26.*
+.*cldws,4,mb 0\\(sr0,r4\\),r26.*
+.*cldws,4,ma 0\\(sr0,r4\\),r26.*
+.*cldds,4 0\\(sr0,r4\\),r26.*
+.*cldds,4,mb 0\\(sr0,r4\\),r26.*
+.*cldds,4,ma 0\\(sr0,r4\\),r26.*
+.*cstws,4 r26,0\\(sr0,r4\\).*
+.*cstws,4,mb r26,0\\(sr0,r4\\).*
+.*cstws,4,ma r26,0\\(sr0,r4\\).*
+.*cstds,4 r26,0\\(sr0,r4\\).*
+.*cstds,4,mb r26,0\\(sr0,r4\\).*
+.*cstds,4,ma r26,0\\(sr0,r4\\).*
+.*$gdb_prompt $" { pass "copr short memory tests" }
+ -re "$gdb_prompt $" { fail "copr short memory tests" }
+ timeout { fail "(timeout) copr short memory tests " }
+ }
+}
+
+proc fmemLRbug_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/12i fmemLRbug_tests_1\n"
+ gdb_expect {
+ -re "
+.*fstws fr6R,0\\(sr0,r26\\).*
+.*fstws fr6,4\\(sr0,r26\\).*
+.*fstws fr6,8\\(sr0,r26\\).*
+.*fstds fr6,0\\(sr0,r26\\).*
+.*fstds fr6,4\\(sr0,r26\\).*
+.*fstds fr6,8\\(sr0,r26\\).*
+.*fldws 0\\(sr0,r26\\),fr6R.*
+.*fldws 4\\(sr0,r26\\),fr6.*
+.*fldws 8\\(sr0,r26\\),fr6.*
+.*fldds 0\\(sr0,r26\\),fr6.*
+.*fldds 4\\(sr0,r26\\),fr6.*
+.*fldds 8\\(sr0,r26\\),fr6.*
+.*$gdb_prompt $" { pass "fmem LR register selector tests (part1)" }
+ -re "$gdb_prompt $" { fail "fmem LR register selector tests (part1)" }
+ timeout { fail "(timeout) fmem LR register selector tests (part1)" }
+ }
+
+ send_gdb "x/12i fmemLRbug_tests_2\n"
+ gdb_expect {
+ -re "
+.*fstws fr6R,0\\(sr0,r26\\).*
+.*fstws fr6,4\\(sr0,r26\\).*
+.*fstws fr6,8\\(sr0,r26\\).*
+.*fstds fr6,0\\(sr0,r26\\).*
+.*fstds fr6,4\\(sr0,r26\\).*
+.*fstds fr6,8\\(sr0,r26\\).*
+.*fldws 0\\(sr0,r26\\),fr6R.*
+.*fldws 4\\(sr0,r26\\),fr6.*
+.*fldws 8\\(sr0,r26\\),fr6.*
+.*fldds 0\\(sr0,r26\\),fr6.*
+.*fldds 4\\(sr0,r26\\),fr6.*
+.*fldds 8\\(sr0,r26\\),fr6.*
+.*$gdb_prompt $" { pass "fmem LR register selector tests (part2)" }
+ -re "$gdb_prompt $" { fail "fmem LR register selector tests (part2)" }
+ timeout { fail "(timeout) fmem LR register selector tests (part2)" }
+ }
+
+ send_gdb "x/12i fmemLRbug_tests_3\n"
+ gdb_expect {
+ -re "
+.*fstwx fr6R,r25\\(sr0,r26\\).*
+.*fstwx fr6,r25\\(sr0,r26\\).*
+.*fstwx fr6,r25\\(sr0,r26\\).*
+.*fstdx fr6,r25\\(sr0,r26\\).*
+.*fstdx fr6,r25\\(sr0,r26\\).*
+.*fstdx fr6,r25\\(sr0,r26\\).*
+.*fldwx r25\\(sr0,r26\\),fr6R.*
+.*fldwx r25\\(sr0,r26\\),fr6.*
+.*fldwx r25\\(sr0,r26\\),fr6.*
+.*flddx r25\\(sr0,r26\\),fr6.*
+.*flddx r25\\(sr0,r26\\),fr6.*
+.*flddx r25\\(sr0,r26\\),fr6.*
+.*$gdb_prompt $" { pass "fmem LR register selector tests (part3)" }
+ -re "$gdb_prompt $" { fail "fmem LR register selector tests (part3)" }
+ timeout { fail "(timeout) fmem LR register selector tests (part3)" }
+ }
+
+ send_gdb "x/12i fmemLRbug_tests_4\n"
+ gdb_expect {
+ -re "
+.*fstwx fr6R,r25\\(sr0,r26\\).*
+.*fstwx fr6,r25\\(sr0,r26\\).*
+.*fstwx fr6,r25\\(sr0,r26\\).*
+.*fstdx fr6,r25\\(sr0,r26\\).*
+.*fstdx fr6,r25\\(sr0,r26\\).*
+.*fstdx fr6,r25\\(sr0,r26\\).*
+.*fldwx r25\\(sr0,r26\\),fr6R.*
+.*fldwx r25\\(sr0,r26\\),fr6.*
+.*fldwx r25\\(sr0,r26\\),fr6.*
+.*flddx r25\\(sr0,r26\\),fr6.*
+.*flddx r25\\(sr0,r26\\),fr6.*
+.*flddx r25\\(sr0,r26\\),fr6.*
+.*$gdb_prompt $" { pass "fmem LR register selector tests (part4)" }
+ -re "$gdb_prompt $" { fail "fmem LR register selector tests (part4)" }
+ timeout { fail "(timeout) fmem LR register selector tests (part4)" }
+ }
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+all_integer_memory_tests
+all_immediate_tests
+all_branch_tests
+all_integer_computational_tests
+all_system_control_tests
+all_fpu_memory_tests
+all_fpu_computational_tests
+all_fpu_comparison_tests
+all_special_tests
+all_sfu_tests
+all_copr_tests
+all_copr_mem_tests
+
+# Regression test for a bug Tege found.
+fmemLRbug_tests
diff --git a/gdb/testsuite/gdb.disasm/hppa.s b/gdb/testsuite/gdb.disasm/hppa.s
new file mode 100644
index 00000000000..593d8bfefee
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/hppa.s
@@ -0,0 +1,1738 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT integer_memory_tests,CODE
+ .EXPORT integer_indexing_load,CODE
+ .EXPORT integer_load_short_memory,CODE
+ .EXPORT integer_store_short_memory,CODE
+ .EXPORT immediate_tests,CODE
+ .EXPORT branch_tests_1,CODE
+ .EXPORT branch_tests_2,CODE
+ .EXPORT movb_tests,CODE
+ .EXPORT movb_nullified_tests,CODE
+ .EXPORT movib_tests,CODE
+ .EXPORT movib_nullified_tests,CODE
+ .EXPORT comb_tests_1,CODE
+ .EXPORT comb_tests_2,CODE
+ .EXPORT comb_nullified_tests_1,CODE
+ .EXPORT comb_nullified_tests_2,CODE
+ .EXPORT comib_tests_1,CODE
+ .EXPORT comib_tests_2,CODE
+ .EXPORT comib_nullified_tests_1,CODE
+ .EXPORT comib_nullified_tests_2,CODE
+ .EXPORT addb_tests_1,CODE
+ .EXPORT addb_tests_2,CODE
+ .EXPORT addb_nullified_tests_1,CODE
+ .EXPORT addb_nullified_tests_2,CODE
+ .EXPORT addib_tests_1,CODE
+ .EXPORT addib_tests_2,CODE
+ .EXPORT addib_nullified_tests_1,CODE
+ .EXPORT addib_nullified_tests_2,CODE
+ .EXPORT bb_tests,CODE
+ .EXPORT add_tests,CODE
+ .EXPORT addl_tests,CODE
+ .EXPORT addo_tests,CODE
+ .EXPORT addc_tests,CODE
+ .EXPORT addco_tests,CODE
+ .EXPORT sh1add_tests,CODE
+ .EXPORT sh1addl_tests,CODE
+ .EXPORT sh1addo_tests,CODE
+ .EXPORT sh2add_tests,CODE
+ .EXPORT sh2addl_tests,CODE
+ .EXPORT sh2addo_tests,CODE
+ .EXPORT sh3add_tests,CODE
+ .EXPORT sh3addl_tests,CODE
+ .EXPORT sh3addo_tests,CODE
+ .EXPORT sub_tests,CODE
+ .EXPORT subo_tests,CODE
+ .EXPORT subb_tests,CODE
+ .EXPORT subbo_tests,CODE
+ .EXPORT subt_tests,CODE
+ .EXPORT subto_tests,CODE
+ .EXPORT ds_tests,CODE
+ .EXPORT comclr_tests,CODE
+ .EXPORT or_tests,CODE
+ .EXPORT xor_tests,CODE
+ .EXPORT and_tests,CODE
+ .EXPORT andcm_tests,CODE
+ .EXPORT uxor_tests,CODE
+ .EXPORT uaddcm_tests,CODE
+ .EXPORT uaddcmt_tests,CODE
+ .EXPORT dcor_tests,CODE
+ .EXPORT idcor_tests,CODE
+ .EXPORT addi_tests,CODE
+ .EXPORT addio_tests,CODE
+ .EXPORT addit_tests,CODE
+ .EXPORT addito_tests,CODE
+ .EXPORT subi_tests,CODE
+ .EXPORT subio_tests,CODE
+ .EXPORT comiclr_tests,CODE
+ .EXPORT vshd_tests,CODE
+ .EXPORT shd_tests,CODE
+ .EXPORT extru_tests,CODE
+ .EXPORT extrs_tests,CODE
+ .EXPORT zdep_tests,CODE
+ .EXPORT dep_tests,CODE
+ .EXPORT vextru_tests,CODE
+ .EXPORT vextrs_tests,CODE
+ .EXPORT zvdep_tests,CODE
+ .EXPORT vdep_tests,CODE
+ .EXPORT vdepi_tests,CODE
+ .EXPORT zvdepi_tests,CODE
+ .EXPORT depi_tests,CODE
+ .EXPORT zdepi_tests,CODE
+ .EXPORT system_control_tests,CODE
+ .EXPORT probe_tests,CODE
+ .EXPORT lpa_tests,CODE
+ .EXPORT purge_tests,CODE
+ .EXPORT insert_tests,CODE
+ .EXPORT fpu_misc_tests,CODE
+ .EXPORT fpu_memory_indexing_tests,CODE
+ .EXPORT fpu_short_memory_tests,CODE
+ .EXPORT fcpy_tests,CODE
+ .EXPORT fabs_tests,CODE
+ .EXPORT fsqrt_tests,CODE
+ .EXPORT frnd_tests,CODE
+ .EXPORT fcnvff_tests,CODE
+ .EXPORT fcnvxf_tests,CODE
+ .EXPORT fcnvfx_tests,CODE
+ .EXPORT fcnvfxt_tests,CODE
+ .EXPORT fadd_tests,CODE
+ .EXPORT fsub_tests,CODE
+ .EXPORT fmpy_tests,CODE
+ .EXPORT fdiv_tests,CODE
+ .EXPORT frem_tests,CODE
+ .EXPORT fcmp_sgl_tests_1,CODE
+ .EXPORT fcmp_sgl_tests_2,CODE
+ .EXPORT fcmp_sgl_tests_3,CODE
+ .EXPORT fcmp_sgl_tests_4,CODE
+ .EXPORT fcmp_dbl_tests_1,CODE
+ .EXPORT fcmp_dbl_tests_2,CODE
+ .EXPORT fcmp_dbl_tests_3,CODE
+ .EXPORT fcmp_dbl_tests_4,CODE
+ .EXPORT fcmp_quad_tests_1,CODE
+ .EXPORT fcmp_quad_tests_2,CODE
+ .EXPORT fcmp_quad_tests_3,CODE
+ .EXPORT fcmp_quad_tests_4,CODE
+ .EXPORT fmpy_addsub_tests,CODE
+ .EXPORT xmpyu_tests,CODE
+ .EXPORT special_tests,CODE
+ .EXPORT sfu_tests,CODE
+ .EXPORT copr_tests,CODE
+ .EXPORT copr_indexing_load,CODE
+ .EXPORT copr_indexing_store,CODE
+ .EXPORT copr_short_memory,CODE
+ .EXPORT fmemLRbug_tests_1,CODE
+ .EXPORT fmemLRbug_tests_2,CODE
+ .EXPORT fmemLRbug_tests_3,CODE
+ .EXPORT fmemLRbug_tests_4,CODE
+ .EXPORT main,CODE
+ .EXPORT main,ENTRY,PRIV_LEV=3,RTNVAL=GR
+main
+ .PROC
+ .CALLINFO FRAME=64,NO_CALLS,SAVE_SP
+ .ENTRY
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,64(0,%r30)
+; First memory reference instructions.
+; Should try corner cases for each field extraction.
+; Should deal with s == 0 case somehow?!?
+integer_memory_tests
+ ldw 0(0,%r4),%r26
+ ldh 0(0,%r4),%r26
+ ldb 0(0,%r4),%r26
+ stw %r26,0(0,%r4)
+ sth %r26,0(0,%r4)
+ stb %r26,0(0,%r4)
+
+; Should make sure pre/post modes are recognized correctly.
+ ldwm 0(0,%r4),%r26
+ stwm %r26,0(0,%r4)
+
+integer_indexing_load
+ ldwx %r5(0,%r4),%r26
+ ldwx,s %r5(0,%r4),%r26
+ ldwx,m %r5(0,%r4),%r26
+ ldwx,sm %r5(0,%r4),%r26
+ ldhx %r5(0,%r4),%r26
+ ldhx,s %r5(0,%r4),%r26
+ ldhx,m %r5(0,%r4),%r26
+ ldhx,sm %r5(0,%r4),%r26
+ ldbx %r5(0,%r4),%r26
+ ldbx,s %r5(0,%r4),%r26
+ ldbx,m %r5(0,%r4),%r26
+ ldbx,sm %r5(0,%r4),%r26
+ ldwax %r5(%r4),%r26
+ ldwax,s %r5(%r4),%r26
+ ldwax,m %r5(%r4),%r26
+ ldwax,sm %r5(%r4),%r26
+ ldcwx %r5(0,%r4),%r26
+ ldcwx,s %r5(0,%r4),%r26
+ ldcwx,m %r5(0,%r4),%r26
+ ldcwx,sm %r5(0,%r4),%r26
+
+integer_load_short_memory
+ ldws 0(0,%r4),%r26
+ ldws,mb 0(0,%r4),%r26
+ ldws,ma 0(0,%r4),%r26
+ ldhs 0(0,%r4),%r26
+ ldhs,mb 0(0,%r4),%r26
+ ldhs,ma 0(0,%r4),%r26
+ ldbs 0(0,%r4),%r26
+ ldbs,mb 0(0,%r4),%r26
+ ldbs,ma 0(0,%r4),%r26
+ ldwas 0(%r4),%r26
+ ldwas,mb 0(%r4),%r26
+ ldwas,ma 0(%r4),%r26
+ ldcws 0(0,%r4),%r26
+ ldcws,mb 0(0,%r4),%r26
+ ldcws,ma 0(0,%r4),%r26
+
+integer_store_short_memory
+ stws %r26,0(0,%r4)
+ stws,mb %r26,0(0,%r4)
+ stws,ma %r26,0(0,%r4)
+ sths %r26,0(0,%r4)
+ sths,mb %r26,0(0,%r4)
+ sths,ma %r26,0(0,%r4)
+ stbs %r26,0(0,%r4)
+ stbs,mb %r26,0(0,%r4)
+ stbs,ma %r26,0(0,%r4)
+ stwas %r26,0(%r4)
+ stwas,mb %r26,0(%r4)
+ stwas,ma %r26,0(%r4)
+ stbys %r26,0(0,%r4)
+ stbys,b %r26,0(0,%r4)
+ stbys,e %r26,0(0,%r4)
+ stbys,b,m %r26,0(0,%r4)
+ stbys,e,m %r26,0(0,%r4)
+
+; Immediate instructions.
+immediate_tests
+ ldo 5(%r26),%r26
+ ldil L%0xdeadbeef,%r26
+ addil L%0xdeadbeef,%r5
+
+; Lots of branch instructions.
+; blr with %r0 as return pointer should really be just br <target>,
+; but the assemblers can't handle it.
+branch_tests_1
+ bl main,%r2
+ bl,n main,%r2
+ b main
+ b,n main
+ gate main,%r2
+ gate,n main,%r2
+ blr %r4,%r2
+ blr,n %r4,%r2
+ blr %r4,%r0
+ blr,n %r4,%r0
+branch_tests_2
+ bv 0(%r2)
+ bv,n 0(%r2)
+ be 0x1234(%sr1,%r2)
+ be,n 0x1234(%sr1,%r2)
+ ble 0x1234(%sr1,%r2)
+ ble,n 0x1234(%sr1,%r2)
+
+; GAS can't assemble movb,n or movib,n.
+movb_tests
+ movb %r4,%r26,movb_tests
+ movb,= %r4,%r26,movb_tests
+ movb,< %r4,%r26,movb_tests
+ movb,od %r4,%r26,movb_tests
+ movb,tr %r4,%r26,movb_tests
+ movb,<> %r4,%r26,movb_tests
+ movb,>= %r4,%r26,movb_tests
+ movb,ev %r4,%r26,movb_tests
+movb_nullified_tests
+ movb,n %r4,%r26,movb_tests
+ movb,=,n %r4,%r26,movb_tests
+ movb,<,n %r4,%r26,movb_tests
+ movb,od,n %r4,%r26,movb_tests
+ movb,tr,n %r4,%r26,movb_tests
+ movb,<>,n %r4,%r26,movb_tests
+ movb,>=,n %r4,%r26,movb_tests
+ movb,ev,n %r4,%r26,movb_tests
+
+movib_tests
+ movib 5,%r26,movib_tests
+ movib,= 5,%r26,movib_tests
+ movib,< 5,%r26,movib_tests
+ movib,od 5,%r26,movib_tests
+ movib,tr 5,%r26,movib_tests
+ movib,<> 5,%r26,movib_tests
+ movib,>= 5,%r26,movib_tests
+ movib,ev 5,%r26,movib_tests
+movib_nullified_tests
+ movib,n 5,%r26,movib_tests
+ movib,=,n 5,%r26,movib_tests
+ movib,<,n 5,%r26,movib_tests
+ movib,od,n 5,%r26,movib_tests
+ movib,tr,n 5,%r26,movib_tests
+ movib,<>,n 5,%r26,movib_tests
+ movib,>=,n 5,%r26,movib_tests
+ movib,ev,n 5,%r26,movib_tests
+
+comb_tests_1
+ comb %r0,%r4,comb_tests_1
+ comb,= %r0,%r4,comb_tests_1
+ comb,< %r0,%r4,comb_tests_1
+ comb,<= %r0,%r4,comb_tests_1
+ comb,<< %r0,%r4,comb_tests_1
+ comb,<<= %r0,%r4,comb_tests_1
+ comb,sv %r0,%r4,comb_tests_1
+ comb,od %r0,%r4,comb_tests_1
+
+comb_tests_2
+ comb,tr %r0,%r4,comb_tests_2
+ comb,<> %r0,%r4,comb_tests_2
+ comb,>= %r0,%r4,comb_tests_2
+ comb,> %r0,%r4,comb_tests_2
+ comb,>>= %r0,%r4,comb_tests_2
+ comb,>> %r0,%r4,comb_tests_2
+ comb,nsv %r0,%r4,comb_tests_2
+ comb,ev %r0,%r4,comb_tests_2
+
+comb_nullified_tests_1
+ comb,n %r0,%r4,comb_tests_1
+ comb,=,n %r0,%r4,comb_tests_1
+ comb,<,n %r0,%r4,comb_tests_1
+ comb,<=,n %r0,%r4,comb_tests_1
+ comb,<<,n %r0,%r4,comb_tests_1
+ comb,<<=,n %r0,%r4,comb_tests_1
+ comb,sv,n %r0,%r4,comb_tests_1
+ comb,od,n %r0,%r4,comb_tests_1
+
+comb_nullified_tests_2
+ comb,tr,n %r0,%r4,comb_tests_2
+ comb,<>,n %r0,%r4,comb_tests_2
+ comb,>=,n %r0,%r4,comb_tests_2
+ comb,>,n %r0,%r4,comb_tests_2
+ comb,>>=,n %r0,%r4,comb_tests_2
+ comb,>>,n %r0,%r4,comb_tests_2
+ comb,nsv,n %r0,%r4,comb_tests_2
+ comb,ev,n %r0,%r4,comb_tests_2
+
+comib_tests_1
+ comib 0,%r4,comib_tests_1
+ comib,= 0,%r4,comib_tests_1
+ comib,< 0,%r4,comib_tests_1
+ comib,<= 0,%r4,comib_tests_1
+ comib,<< 0,%r4,comib_tests_1
+ comib,<<= 0,%r4,comib_tests_1
+ comib,sv 0,%r4,comib_tests_1
+ comib,od 0,%r4,comib_tests_1
+
+comib_tests_2
+ comib,tr 0,%r4,comib_tests_2
+ comib,<> 0,%r4,comib_tests_2
+ comib,>= 0,%r4,comib_tests_2
+ comib,> 0,%r4,comib_tests_2
+ comib,>>= 0,%r4,comib_tests_2
+ comib,>> 0,%r4,comib_tests_2
+ comib,nsv 0,%r4,comib_tests_2
+ comib,ev 0,%r4,comib_tests_2
+
+comib_nullified_tests_1
+ comib,n 0,%r4,comib_tests_1
+ comib,=,n 0,%r4,comib_tests_1
+ comib,<,n 0,%r4,comib_tests_1
+ comib,<=,n 0,%r4,comib_tests_1
+ comib,<<,n 0,%r4,comib_tests_1
+ comib,<<=,n 0,%r4,comib_tests_1
+ comib,sv,n 0,%r4,comib_tests_1
+ comib,od,n 0,%r4,comib_tests_1
+
+comib_nullified_tests_2
+ comib,tr,n 0,%r4,comib_tests_2
+ comib,<>,n 0,%r4,comib_tests_2
+ comib,>=,n 0,%r4,comib_tests_2
+ comib,>,n 0,%r4,comib_tests_2
+ comib,>>=,n 0,%r4,comib_tests_2
+ comib,>>,n 0,%r4,comib_tests_2
+ comib,nsv,n 0,%r4,comib_tests_2
+ comib,ev,n 0,%r4,comib_tests_2
+
+addb_tests_1
+ addb %r1,%r4,addb_tests_1
+ addb,= %r1,%r4,addb_tests_1
+ addb,< %r1,%r4,addb_tests_1
+ addb,<= %r1,%r4,addb_tests_1
+ addb,nuv %r1,%r4,addb_tests_1
+ addb,znv %r1,%r4,addb_tests_1
+ addb,sv %r1,%r4,addb_tests_1
+ addb,od %r1,%r4,addb_tests_1
+
+addb_tests_2
+ addb,tr %r1,%r4,addb_tests_2
+ addb,<> %r1,%r4,addb_tests_2
+ addb,>= %r1,%r4,addb_tests_2
+ addb,> %r1,%r4,addb_tests_2
+ addb,uv %r1,%r4,addb_tests_2
+ addb,vnz %r1,%r4,addb_tests_2
+ addb,nsv %r1,%r4,addb_tests_2
+ addb,ev %r1,%r4,addb_tests_2
+
+addb_nullified_tests_1
+ addb,n %r1,%r4,addb_tests_1
+ addb,=,n %r1,%r4,addb_tests_1
+ addb,<,n %r1,%r4,addb_tests_1
+ addb,<=,n %r1,%r4,addb_tests_1
+ addb,nuv,n %r1,%r4,addb_tests_1
+ addb,znv,n %r1,%r4,addb_tests_1
+ addb,sv,n %r1,%r4,addb_tests_1
+ addb,od,n %r1,%r4,addb_tests_1
+
+addb_nullified_tests_2
+ addb,tr,n %r1,%r4,addb_tests_2
+ addb,<>,n %r1,%r4,addb_tests_2
+ addb,>=,n %r1,%r4,addb_tests_2
+ addb,>,n %r1,%r4,addb_tests_2
+ addb,uv,n %r1,%r4,addb_tests_2
+ addb,vnz,n %r1,%r4,addb_tests_2
+ addb,nsv,n %r1,%r4,addb_tests_2
+ addb,ev,n %r1,%r4,addb_tests_2
+
+addib_tests_1
+ addib -1,%r4,addib_tests_1
+ addib,= -1,%r4,addib_tests_1
+ addib,< -1,%r4,addib_tests_1
+ addib,<= -1,%r4,addib_tests_1
+ addib,nuv -1,%r4,addib_tests_1
+ addib,znv -1,%r4,addib_tests_1
+ addib,sv -1,%r4,addib_tests_1
+ addib,od -1,%r4,addib_tests_1
+
+addib_tests_2
+ addib,tr -1,%r4,addib_tests_2
+ addib,<> -1,%r4,addib_tests_2
+ addib,>= -1,%r4,addib_tests_2
+ addib,> -1,%r4,addib_tests_2
+ addib,uv -1,%r4,addib_tests_2
+ addib,vnz -1,%r4,addib_tests_2
+ addib,nsv -1,%r4,addib_tests_2
+ addib,ev -1,%r4,addib_tests_2
+
+addib_nullified_tests_1
+ addib,n -1,%r4,addib_tests_1
+ addib,=,n -1,%r4,addib_tests_1
+ addib,<,n -1,%r4,addib_tests_1
+ addib,<=,n -1,%r4,addib_tests_1
+ addib,nuv,n -1,%r4,addib_tests_1
+ addib,znv,n -1,%r4,addib_tests_1
+ addib,sv,n -1,%r4,addib_tests_1
+ addib,od,n -1,%r4,addib_tests_1
+
+addib_nullified_tests_2
+ addib,tr,n -1,%r4,addib_tests_2
+ addib,<>,n -1,%r4,addib_tests_2
+ addib,>=,n -1,%r4,addib_tests_2
+ addib,>,n -1,%r4,addib_tests_2
+ addib,uv,n -1,%r4,addib_tests_2
+ addib,vnz,n -1,%r4,addib_tests_2
+ addib,nsv,n -1,%r4,addib_tests_2
+ addib,ev,n -1,%r4,addib_tests_2
+
+
+; Needs to check lots of stuff (like corner bit cases)
+bb_tests
+ bvb,< %r4,bb_tests
+ bvb,>= %r4,bb_tests
+ bvb,<,n %r4,bb_tests
+ bvb,>=,n %r4,bb_tests
+ bb,< %r4,5,bb_tests
+ bb,>= %r4,5,bb_tests
+ bb,<,n %r4,5,bb_tests
+ bb,>=,n %r4,5,bb_tests
+
+; Computational instructions
+add_tests
+ add %r4,%r5,%r6
+ add,= %r4,%r5,%r6
+ add,< %r4,%r5,%r6
+ add,<= %r4,%r5,%r6
+ add,nuv %r4,%r5,%r6
+ add,znv %r4,%r5,%r6
+ add,sv %r4,%r5,%r6
+ add,od %r4,%r5,%r6
+ add,tr %r4,%r5,%r6
+ add,<> %r4,%r5,%r6
+ add,>= %r4,%r5,%r6
+ add,> %r4,%r5,%r6
+ add,uv %r4,%r5,%r6
+ add,vnz %r4,%r5,%r6
+ add,nsv %r4,%r5,%r6
+ add,ev %r4,%r5,%r6
+
+addl_tests
+ addl %r4,%r5,%r6
+ addl,= %r4,%r5,%r6
+ addl,< %r4,%r5,%r6
+ addl,<= %r4,%r5,%r6
+ addl,nuv %r4,%r5,%r6
+ addl,znv %r4,%r5,%r6
+ addl,sv %r4,%r5,%r6
+ addl,od %r4,%r5,%r6
+ addl,tr %r4,%r5,%r6
+ addl,<> %r4,%r5,%r6
+ addl,>= %r4,%r5,%r6
+ addl,> %r4,%r5,%r6
+ addl,uv %r4,%r5,%r6
+ addl,vnz %r4,%r5,%r6
+ addl,nsv %r4,%r5,%r6
+ addl,ev %r4,%r5,%r6
+
+addo_tests
+ addo %r4,%r5,%r6
+ addo,= %r4,%r5,%r6
+ addo,< %r4,%r5,%r6
+ addo,<= %r4,%r5,%r6
+ addo,nuv %r4,%r5,%r6
+ addo,znv %r4,%r5,%r6
+ addo,sv %r4,%r5,%r6
+ addo,od %r4,%r5,%r6
+ addo,tr %r4,%r5,%r6
+ addo,<> %r4,%r5,%r6
+ addo,>= %r4,%r5,%r6
+ addo,> %r4,%r5,%r6
+ addo,uv %r4,%r5,%r6
+ addo,vnz %r4,%r5,%r6
+ addo,nsv %r4,%r5,%r6
+ addo,ev %r4,%r5,%r6
+
+addc_tests
+ addc %r4,%r5,%r6
+ addc,= %r4,%r5,%r6
+ addc,< %r4,%r5,%r6
+ addc,<= %r4,%r5,%r6
+ addc,nuv %r4,%r5,%r6
+ addc,znv %r4,%r5,%r6
+ addc,sv %r4,%r5,%r6
+ addc,od %r4,%r5,%r6
+ addc,tr %r4,%r5,%r6
+ addc,<> %r4,%r5,%r6
+ addc,>= %r4,%r5,%r6
+ addc,> %r4,%r5,%r6
+ addc,uv %r4,%r5,%r6
+ addc,vnz %r4,%r5,%r6
+ addc,nsv %r4,%r5,%r6
+ addc,ev %r4,%r5,%r6
+
+addco_tests
+ addco %r4,%r5,%r6
+ addco,= %r4,%r5,%r6
+ addco,< %r4,%r5,%r6
+ addco,<= %r4,%r5,%r6
+ addco,nuv %r4,%r5,%r6
+ addco,znv %r4,%r5,%r6
+ addco,sv %r4,%r5,%r6
+ addco,od %r4,%r5,%r6
+ addco,tr %r4,%r5,%r6
+ addco,<> %r4,%r5,%r6
+ addco,>= %r4,%r5,%r6
+ addco,> %r4,%r5,%r6
+ addco,uv %r4,%r5,%r6
+ addco,vnz %r4,%r5,%r6
+ addco,nsv %r4,%r5,%r6
+ addco,ev %r4,%r5,%r6
+
+sh1add_tests
+ sh1add %r4,%r5,%r6
+ sh1add,= %r4,%r5,%r6
+ sh1add,< %r4,%r5,%r6
+ sh1add,<= %r4,%r5,%r6
+ sh1add,nuv %r4,%r5,%r6
+ sh1add,znv %r4,%r5,%r6
+ sh1add,sv %r4,%r5,%r6
+ sh1add,od %r4,%r5,%r6
+ sh1add,tr %r4,%r5,%r6
+ sh1add,<> %r4,%r5,%r6
+ sh1add,>= %r4,%r5,%r6
+ sh1add,> %r4,%r5,%r6
+ sh1add,uv %r4,%r5,%r6
+ sh1add,vnz %r4,%r5,%r6
+ sh1add,nsv %r4,%r5,%r6
+ sh1add,ev %r4,%r5,%r6
+
+sh1addl_tests
+ sh1addl %r4,%r5,%r6
+ sh1addl,= %r4,%r5,%r6
+ sh1addl,< %r4,%r5,%r6
+ sh1addl,<= %r4,%r5,%r6
+ sh1addl,nuv %r4,%r5,%r6
+ sh1addl,znv %r4,%r5,%r6
+ sh1addl,sv %r4,%r5,%r6
+ sh1addl,od %r4,%r5,%r6
+ sh1addl,tr %r4,%r5,%r6
+ sh1addl,<> %r4,%r5,%r6
+ sh1addl,>= %r4,%r5,%r6
+ sh1addl,> %r4,%r5,%r6
+ sh1addl,uv %r4,%r5,%r6
+ sh1addl,vnz %r4,%r5,%r6
+ sh1addl,nsv %r4,%r5,%r6
+ sh1addl,ev %r4,%r5,%r6
+
+sh1addo_tests
+ sh1addo %r4,%r5,%r6
+ sh1addo,= %r4,%r5,%r6
+ sh1addo,< %r4,%r5,%r6
+ sh1addo,<= %r4,%r5,%r6
+ sh1addo,nuv %r4,%r5,%r6
+ sh1addo,znv %r4,%r5,%r6
+ sh1addo,sv %r4,%r5,%r6
+ sh1addo,od %r4,%r5,%r6
+ sh1addo,tr %r4,%r5,%r6
+ sh1addo,<> %r4,%r5,%r6
+ sh1addo,>= %r4,%r5,%r6
+ sh1addo,> %r4,%r5,%r6
+ sh1addo,uv %r4,%r5,%r6
+ sh1addo,vnz %r4,%r5,%r6
+ sh1addo,nsv %r4,%r5,%r6
+ sh1addo,ev %r4,%r5,%r6
+
+
+sh2add_tests
+ sh2add %r4,%r5,%r6
+ sh2add,= %r4,%r5,%r6
+ sh2add,< %r4,%r5,%r6
+ sh2add,<= %r4,%r5,%r6
+ sh2add,nuv %r4,%r5,%r6
+ sh2add,znv %r4,%r5,%r6
+ sh2add,sv %r4,%r5,%r6
+ sh2add,od %r4,%r5,%r6
+ sh2add,tr %r4,%r5,%r6
+ sh2add,<> %r4,%r5,%r6
+ sh2add,>= %r4,%r5,%r6
+ sh2add,> %r4,%r5,%r6
+ sh2add,uv %r4,%r5,%r6
+ sh2add,vnz %r4,%r5,%r6
+ sh2add,nsv %r4,%r5,%r6
+ sh2add,ev %r4,%r5,%r6
+
+sh2addl_tests
+ sh2addl %r4,%r5,%r6
+ sh2addl,= %r4,%r5,%r6
+ sh2addl,< %r4,%r5,%r6
+ sh2addl,<= %r4,%r5,%r6
+ sh2addl,nuv %r4,%r5,%r6
+ sh2addl,znv %r4,%r5,%r6
+ sh2addl,sv %r4,%r5,%r6
+ sh2addl,od %r4,%r5,%r6
+ sh2addl,tr %r4,%r5,%r6
+ sh2addl,<> %r4,%r5,%r6
+ sh2addl,>= %r4,%r5,%r6
+ sh2addl,> %r4,%r5,%r6
+ sh2addl,uv %r4,%r5,%r6
+ sh2addl,vnz %r4,%r5,%r6
+ sh2addl,nsv %r4,%r5,%r6
+ sh2addl,ev %r4,%r5,%r6
+
+sh2addo_tests
+ sh2addo %r4,%r5,%r6
+ sh2addo,= %r4,%r5,%r6
+ sh2addo,< %r4,%r5,%r6
+ sh2addo,<= %r4,%r5,%r6
+ sh2addo,nuv %r4,%r5,%r6
+ sh2addo,znv %r4,%r5,%r6
+ sh2addo,sv %r4,%r5,%r6
+ sh2addo,od %r4,%r5,%r6
+ sh2addo,tr %r4,%r5,%r6
+ sh2addo,<> %r4,%r5,%r6
+ sh2addo,>= %r4,%r5,%r6
+ sh2addo,> %r4,%r5,%r6
+ sh2addo,uv %r4,%r5,%r6
+ sh2addo,vnz %r4,%r5,%r6
+ sh2addo,nsv %r4,%r5,%r6
+ sh2addo,ev %r4,%r5,%r6
+
+
+sh3add_tests
+ sh3add %r4,%r5,%r6
+ sh3add,= %r4,%r5,%r6
+ sh3add,< %r4,%r5,%r6
+ sh3add,<= %r4,%r5,%r6
+ sh3add,nuv %r4,%r5,%r6
+ sh3add,znv %r4,%r5,%r6
+ sh3add,sv %r4,%r5,%r6
+ sh3add,od %r4,%r5,%r6
+ sh3add,tr %r4,%r5,%r6
+ sh3add,<> %r4,%r5,%r6
+ sh3add,>= %r4,%r5,%r6
+ sh3add,> %r4,%r5,%r6
+ sh3add,uv %r4,%r5,%r6
+ sh3add,vnz %r4,%r5,%r6
+ sh3add,nsv %r4,%r5,%r6
+ sh3add,ev %r4,%r5,%r6
+
+sh3addl_tests
+ sh3addl %r4,%r5,%r6
+ sh3addl,= %r4,%r5,%r6
+ sh3addl,< %r4,%r5,%r6
+ sh3addl,<= %r4,%r5,%r6
+ sh3addl,nuv %r4,%r5,%r6
+ sh3addl,znv %r4,%r5,%r6
+ sh3addl,sv %r4,%r5,%r6
+ sh3addl,od %r4,%r5,%r6
+ sh3addl,tr %r4,%r5,%r6
+ sh3addl,<> %r4,%r5,%r6
+ sh3addl,>= %r4,%r5,%r6
+ sh3addl,> %r4,%r5,%r6
+ sh3addl,uv %r4,%r5,%r6
+ sh3addl,vnz %r4,%r5,%r6
+ sh3addl,nsv %r4,%r5,%r6
+ sh3addl,ev %r4,%r5,%r6
+
+sh3addo_tests
+ sh3addo %r4,%r5,%r6
+ sh3addo,= %r4,%r5,%r6
+ sh3addo,< %r4,%r5,%r6
+ sh3addo,<= %r4,%r5,%r6
+ sh3addo,nuv %r4,%r5,%r6
+ sh3addo,znv %r4,%r5,%r6
+ sh3addo,sv %r4,%r5,%r6
+ sh3addo,od %r4,%r5,%r6
+ sh3addo,tr %r4,%r5,%r6
+ sh3addo,<> %r4,%r5,%r6
+ sh3addo,>= %r4,%r5,%r6
+ sh3addo,> %r4,%r5,%r6
+ sh3addo,uv %r4,%r5,%r6
+ sh3addo,vnz %r4,%r5,%r6
+ sh3addo,nsv %r4,%r5,%r6
+ sh3addo,ev %r4,%r5,%r6
+
+
+sub_tests
+ sub %r4,%r5,%r6
+ sub,= %r4,%r5,%r6
+ sub,< %r4,%r5,%r6
+ sub,<= %r4,%r5,%r6
+ sub,<< %r4,%r5,%r6
+ sub,<<= %r4,%r5,%r6
+ sub,sv %r4,%r5,%r6
+ sub,od %r4,%r5,%r6
+ sub,tr %r4,%r5,%r6
+ sub,<> %r4,%r5,%r6
+ sub,>= %r4,%r5,%r6
+ sub,> %r4,%r5,%r6
+ sub,>>= %r4,%r5,%r6
+ sub,>> %r4,%r5,%r6
+ sub,nsv %r4,%r5,%r6
+ sub,ev %r4,%r5,%r6
+
+subo_tests
+ subo %r4,%r5,%r6
+ subo,= %r4,%r5,%r6
+ subo,< %r4,%r5,%r6
+ subo,<= %r4,%r5,%r6
+ subo,<< %r4,%r5,%r6
+ subo,<<= %r4,%r5,%r6
+ subo,sv %r4,%r5,%r6
+ subo,od %r4,%r5,%r6
+ subo,tr %r4,%r5,%r6
+ subo,<> %r4,%r5,%r6
+ subo,>= %r4,%r5,%r6
+ subo,> %r4,%r5,%r6
+ subo,>>= %r4,%r5,%r6
+ subo,>> %r4,%r5,%r6
+ subo,nsv %r4,%r5,%r6
+ subo,ev %r4,%r5,%r6
+
+subb_tests
+ subb %r4,%r5,%r6
+ subb,= %r4,%r5,%r6
+ subb,< %r4,%r5,%r6
+ subb,<= %r4,%r5,%r6
+ subb,<< %r4,%r5,%r6
+ subb,<<= %r4,%r5,%r6
+ subb,sv %r4,%r5,%r6
+ subb,od %r4,%r5,%r6
+ subb,tr %r4,%r5,%r6
+ subb,<> %r4,%r5,%r6
+ subb,>= %r4,%r5,%r6
+ subb,> %r4,%r5,%r6
+ subb,>>= %r4,%r5,%r6
+ subb,>> %r4,%r5,%r6
+ subb,nsv %r4,%r5,%r6
+ subb,ev %r4,%r5,%r6
+
+subbo_tests
+ subbo %r4,%r5,%r6
+ subbo,= %r4,%r5,%r6
+ subbo,< %r4,%r5,%r6
+ subbo,<= %r4,%r5,%r6
+ subbo,<< %r4,%r5,%r6
+ subbo,<<= %r4,%r5,%r6
+ subbo,sv %r4,%r5,%r6
+ subbo,od %r4,%r5,%r6
+ subbo,tr %r4,%r5,%r6
+ subbo,<> %r4,%r5,%r6
+ subbo,>= %r4,%r5,%r6
+ subbo,> %r4,%r5,%r6
+ subbo,>>= %r4,%r5,%r6
+ subbo,>> %r4,%r5,%r6
+ subbo,nsv %r4,%r5,%r6
+ subbo,ev %r4,%r5,%r6
+
+subt_tests
+ subt %r4,%r5,%r6
+ subt,= %r4,%r5,%r6
+ subt,< %r4,%r5,%r6
+ subt,<= %r4,%r5,%r6
+ subt,<< %r4,%r5,%r6
+ subt,<<= %r4,%r5,%r6
+ subt,sv %r4,%r5,%r6
+ subt,od %r4,%r5,%r6
+ subt,tr %r4,%r5,%r6
+ subt,<> %r4,%r5,%r6
+ subt,>= %r4,%r5,%r6
+ subt,> %r4,%r5,%r6
+ subt,>>= %r4,%r5,%r6
+ subt,>> %r4,%r5,%r6
+ subt,nsv %r4,%r5,%r6
+ subt,ev %r4,%r5,%r6
+
+subto_tests
+ subto %r4,%r5,%r6
+ subto,= %r4,%r5,%r6
+ subto,< %r4,%r5,%r6
+ subto,<= %r4,%r5,%r6
+ subto,<< %r4,%r5,%r6
+ subto,<<= %r4,%r5,%r6
+ subto,sv %r4,%r5,%r6
+ subto,od %r4,%r5,%r6
+ subto,tr %r4,%r5,%r6
+ subto,<> %r4,%r5,%r6
+ subto,>= %r4,%r5,%r6
+ subto,> %r4,%r5,%r6
+ subto,>>= %r4,%r5,%r6
+ subto,>> %r4,%r5,%r6
+ subto,nsv %r4,%r5,%r6
+ subto,ev %r4,%r5,%r6
+
+ds_tests
+ ds %r4,%r5,%r6
+ ds,= %r4,%r5,%r6
+ ds,< %r4,%r5,%r6
+ ds,<= %r4,%r5,%r6
+ ds,<< %r4,%r5,%r6
+ ds,<<= %r4,%r5,%r6
+ ds,sv %r4,%r5,%r6
+ ds,od %r4,%r5,%r6
+ ds,tr %r4,%r5,%r6
+ ds,<> %r4,%r5,%r6
+ ds,>= %r4,%r5,%r6
+ ds,> %r4,%r5,%r6
+ ds,>>= %r4,%r5,%r6
+ ds,>> %r4,%r5,%r6
+ ds,nsv %r4,%r5,%r6
+ ds,ev %r4,%r5,%r6
+
+comclr_tests
+ comclr %r4,%r5,%r6
+ comclr,= %r4,%r5,%r6
+ comclr,< %r4,%r5,%r6
+ comclr,<= %r4,%r5,%r6
+ comclr,<< %r4,%r5,%r6
+ comclr,<<= %r4,%r5,%r6
+ comclr,sv %r4,%r5,%r6
+ comclr,od %r4,%r5,%r6
+ comclr,tr %r4,%r5,%r6
+ comclr,<> %r4,%r5,%r6
+ comclr,>= %r4,%r5,%r6
+ comclr,> %r4,%r5,%r6
+ comclr,>>= %r4,%r5,%r6
+ comclr,>> %r4,%r5,%r6
+ comclr,nsv %r4,%r5,%r6
+ comclr,ev %r4,%r5,%r6
+
+or_tests
+ or %r4,%r5,%r6
+ or,= %r4,%r5,%r6
+ or,< %r4,%r5,%r6
+ or,<= %r4,%r5,%r6
+ or,od %r4,%r5,%r6
+ or,tr %r4,%r5,%r6
+ or,<> %r4,%r5,%r6
+ or,>= %r4,%r5,%r6
+ or,> %r4,%r5,%r6
+ or,ev %r4,%r5,%r6
+xor_tests
+ xor %r4,%r5,%r6
+ xor,= %r4,%r5,%r6
+ xor,< %r4,%r5,%r6
+ xor,<= %r4,%r5,%r6
+ xor,od %r4,%r5,%r6
+ xor,tr %r4,%r5,%r6
+ xor,<> %r4,%r5,%r6
+ xor,>= %r4,%r5,%r6
+ xor,> %r4,%r5,%r6
+ xor,ev %r4,%r5,%r6
+
+and_tests
+ and %r4,%r5,%r6
+ and,= %r4,%r5,%r6
+ and,< %r4,%r5,%r6
+ and,<= %r4,%r5,%r6
+ and,od %r4,%r5,%r6
+ and,tr %r4,%r5,%r6
+ and,<> %r4,%r5,%r6
+ and,>= %r4,%r5,%r6
+ and,> %r4,%r5,%r6
+ and,ev %r4,%r5,%r6
+
+andcm_tests
+ andcm %r4,%r5,%r6
+ andcm,= %r4,%r5,%r6
+ andcm,< %r4,%r5,%r6
+ andcm,<= %r4,%r5,%r6
+ andcm,od %r4,%r5,%r6
+ andcm,tr %r4,%r5,%r6
+ andcm,<> %r4,%r5,%r6
+ andcm,>= %r4,%r5,%r6
+ andcm,> %r4,%r5,%r6
+ andcm,ev %r4,%r5,%r6
+
+
+uxor_tests
+ uxor %r4,%r5,%r6
+ uxor,sbz %r4,%r5,%r6
+ uxor,shz %r4,%r5,%r6
+ uxor,sdc %r4,%r5,%r6
+ uxor,sbc %r4,%r5,%r6
+ uxor,shc %r4,%r5,%r6
+ uxor,tr %r4,%r5,%r6
+ uxor,nbz %r4,%r5,%r6
+ uxor,nhz %r4,%r5,%r6
+ uxor,ndc %r4,%r5,%r6
+ uxor,nbc %r4,%r5,%r6
+ uxor,nhc %r4,%r5,%r6
+
+uaddcm_tests
+ uaddcm %r4,%r5,%r6
+ uaddcm,sbz %r4,%r5,%r6
+ uaddcm,shz %r4,%r5,%r6
+ uaddcm,sdc %r4,%r5,%r6
+ uaddcm,sbc %r4,%r5,%r6
+ uaddcm,shc %r4,%r5,%r6
+ uaddcm,tr %r4,%r5,%r6
+ uaddcm,nbz %r4,%r5,%r6
+ uaddcm,nhz %r4,%r5,%r6
+ uaddcm,ndc %r4,%r5,%r6
+ uaddcm,nbc %r4,%r5,%r6
+ uaddcm,nhc %r4,%r5,%r6
+
+uaddcmt_tests
+ uaddcmt %r4,%r5,%r6
+ uaddcmt,sbz %r4,%r5,%r6
+ uaddcmt,shz %r4,%r5,%r6
+ uaddcmt,sdc %r4,%r5,%r6
+ uaddcmt,sbc %r4,%r5,%r6
+ uaddcmt,shc %r4,%r5,%r6
+ uaddcmt,tr %r4,%r5,%r6
+ uaddcmt,nbz %r4,%r5,%r6
+ uaddcmt,nhz %r4,%r5,%r6
+ uaddcmt,ndc %r4,%r5,%r6
+ uaddcmt,nbc %r4,%r5,%r6
+ uaddcmt,nhc %r4,%r5,%r6
+
+dcor_tests
+ dcor %r4,%r5
+ dcor,sbz %r4,%r5
+ dcor,shz %r4,%r5
+ dcor,sdc %r4,%r5
+ dcor,sbc %r4,%r5
+ dcor,shc %r4,%r5
+ dcor,tr %r4,%r5
+ dcor,nbz %r4,%r5
+ dcor,nhz %r4,%r5
+ dcor,ndc %r4,%r5
+ dcor,nbc %r4,%r5
+ dcor,nhc %r4,%r5
+
+idcor_tests
+ idcor %r4,%r5
+ idcor,sbz %r4,%r5
+ idcor,shz %r4,%r5
+ idcor,sdc %r4,%r5
+ idcor,sbc %r4,%r5
+ idcor,shc %r4,%r5
+ idcor,tr %r4,%r5
+ idcor,nbz %r4,%r5
+ idcor,nhz %r4,%r5
+ idcor,ndc %r4,%r5
+ idcor,nbc %r4,%r5
+ idcor,nhc %r4,%r5
+
+addi_tests
+ addi 123,%r5,%r6
+ addi,= 123,%r5,%r6
+ addi,< 123,%r5,%r6
+ addi,<= 123,%r5,%r6
+ addi,nuv 123,%r5,%r6
+ addi,znv 123,%r5,%r6
+ addi,sv 123,%r5,%r6
+ addi,od 123,%r5,%r6
+ addi,tr 123,%r5,%r6
+ addi,<> 123,%r5,%r6
+ addi,>= 123,%r5,%r6
+ addi,> 123,%r5,%r6
+ addi,uv 123,%r5,%r6
+ addi,vnz 123,%r5,%r6
+ addi,nsv 123,%r5,%r6
+ addi,ev 123,%r5,%r6
+
+addio_tests
+ addio 123,%r5,%r6
+ addio,= 123,%r5,%r6
+ addio,< 123,%r5,%r6
+ addio,<= 123,%r5,%r6
+ addio,nuv 123,%r5,%r6
+ addio,znv 123,%r5,%r6
+ addio,sv 123,%r5,%r6
+ addio,od 123,%r5,%r6
+ addio,tr 123,%r5,%r6
+ addio,<> 123,%r5,%r6
+ addio,>= 123,%r5,%r6
+ addio,> 123,%r5,%r6
+ addio,uv 123,%r5,%r6
+ addio,vnz 123,%r5,%r6
+ addio,nsv 123,%r5,%r6
+ addio,ev 123,%r5,%r6
+
+addit_tests
+ addit 123,%r5,%r6
+ addit,= 123,%r5,%r6
+ addit,< 123,%r5,%r6
+ addit,<= 123,%r5,%r6
+ addit,nuv 123,%r5,%r6
+ addit,znv 123,%r5,%r6
+ addit,sv 123,%r5,%r6
+ addit,od 123,%r5,%r6
+ addit,tr 123,%r5,%r6
+ addit,<> 123,%r5,%r6
+ addit,>= 123,%r5,%r6
+ addit,> 123,%r5,%r6
+ addit,uv 123,%r5,%r6
+ addit,vnz 123,%r5,%r6
+ addit,nsv 123,%r5,%r6
+ addit,ev 123,%r5,%r6
+
+addito_tests
+ addito 123,%r5,%r6
+ addito,= 123,%r5,%r6
+ addito,< 123,%r5,%r6
+ addito,<= 123,%r5,%r6
+ addito,nuv 123,%r5,%r6
+ addito,znv 123,%r5,%r6
+ addito,sv 123,%r5,%r6
+ addito,od 123,%r5,%r6
+ addito,tr 123,%r5,%r6
+ addito,<> 123,%r5,%r6
+ addito,>= 123,%r5,%r6
+ addito,> 123,%r5,%r6
+ addito,uv 123,%r5,%r6
+ addito,vnz 123,%r5,%r6
+ addito,nsv 123,%r5,%r6
+ addito,ev 123,%r5,%r6
+
+subi_tests
+ subi 123,%r5,%r6
+ subi,= 123,%r5,%r6
+ subi,< 123,%r5,%r6
+ subi,<= 123,%r5,%r6
+ subi,<< 123,%r5,%r6
+ subi,<<= 123,%r5,%r6
+ subi,sv 123,%r5,%r6
+ subi,od 123,%r5,%r6
+ subi,tr 123,%r5,%r6
+ subi,<> 123,%r5,%r6
+ subi,>= 123,%r5,%r6
+ subi,> 123,%r5,%r6
+ subi,>>= 123,%r5,%r6
+ subi,>> 123,%r5,%r6
+ subi,nsv 123,%r5,%r6
+ subi,ev 123,%r5,%r6
+
+subio_tests
+ subio 123,%r5,%r6
+ subio,= 123,%r5,%r6
+ subio,< 123,%r5,%r6
+ subio,<= 123,%r5,%r6
+ subio,<< 123,%r5,%r6
+ subio,<<= 123,%r5,%r6
+ subio,sv 123,%r5,%r6
+ subio,od 123,%r5,%r6
+ subio,tr 123,%r5,%r6
+ subio,<> 123,%r5,%r6
+ subio,>= 123,%r5,%r6
+ subio,> 123,%r5,%r6
+ subio,>>= 123,%r5,%r6
+ subio,>> 123,%r5,%r6
+ subio,nsv 123,%r5,%r6
+ subio,ev 123,%r5,%r6
+
+comiclr_tests
+ comiclr 123,%r5,%r6
+ comiclr,= 123,%r5,%r6
+ comiclr,< 123,%r5,%r6
+ comiclr,<= 123,%r5,%r6
+ comiclr,<< 123,%r5,%r6
+ comiclr,<<= 123,%r5,%r6
+ comiclr,sv 123,%r5,%r6
+ comiclr,od 123,%r5,%r6
+ comiclr,tr 123,%r5,%r6
+ comiclr,<> 123,%r5,%r6
+ comiclr,>= 123,%r5,%r6
+ comiclr,> 123,%r5,%r6
+ comiclr,>>= 123,%r5,%r6
+ comiclr,>> 123,%r5,%r6
+ comiclr,nsv 123,%r5,%r6
+ comiclr,ev 123,%r5,%r6
+
+vshd_tests
+ vshd %r4,%r5,%r6
+ vshd,= %r4,%r5,%r6
+ vshd,< %r4,%r5,%r6
+ vshd,od %r4,%r5,%r6
+ vshd,tr %r4,%r5,%r6
+ vshd,<> %r4,%r5,%r6
+ vshd,>= %r4,%r5,%r6
+ vshd,ev %r4,%r5,%r6
+
+shd_tests
+ shd %r4,%r5,5,%r6
+ shd,= %r4,%r5,5,%r6
+ shd,< %r4,%r5,5,%r6
+ shd,od %r4,%r5,5,%r6
+ shd,tr %r4,%r5,5,%r6
+ shd,<> %r4,%r5,5,%r6
+ shd,>= %r4,%r5,5,%r6
+ shd,ev %r4,%r5,5,%r6
+
+extru_tests
+ extru %r4,5,10,%r6
+ extru,= %r4,5,10,%r6
+ extru,< %r4,5,10,%r6
+ extru,od %r4,5,10,%r6
+ extru,tr %r4,5,10,%r6
+ extru,<> %r4,5,10,%r6
+ extru,>= %r4,5,10,%r6
+ extru,ev %r4,5,10,%r6
+
+extrs_tests
+ extrs %r4,5,10,%r6
+ extrs,= %r4,5,10,%r6
+ extrs,< %r4,5,10,%r6
+ extrs,od %r4,5,10,%r6
+ extrs,tr %r4,5,10,%r6
+ extrs,<> %r4,5,10,%r6
+ extrs,>= %r4,5,10,%r6
+ extrs,ev %r4,5,10,%r6
+
+zdep_tests
+ zdep %r4,5,10,%r6
+ zdep,= %r4,5,10,%r6
+ zdep,< %r4,5,10,%r6
+ zdep,od %r4,5,10,%r6
+ zdep,tr %r4,5,10,%r6
+ zdep,<> %r4,5,10,%r6
+ zdep,>= %r4,5,10,%r6
+ zdep,ev %r4,5,10,%r6
+
+dep_tests
+ dep %r4,5,10,%r6
+ dep,= %r4,5,10,%r6
+ dep,< %r4,5,10,%r6
+ dep,od %r4,5,10,%r6
+ dep,tr %r4,5,10,%r6
+ dep,<> %r4,5,10,%r6
+ dep,>= %r4,5,10,%r6
+ dep,ev %r4,5,10,%r6
+
+vextru_tests
+ vextru %r4,5,%r6
+ vextru,= %r4,5,%r6
+ vextru,< %r4,5,%r6
+ vextru,od %r4,5,%r6
+ vextru,tr %r4,5,%r6
+ vextru,<> %r4,5,%r6
+ vextru,>= %r4,5,%r6
+ vextru,ev %r4,5,%r6
+
+vextrs_tests
+ vextrs %r4,5,%r6
+ vextrs,= %r4,5,%r6
+ vextrs,< %r4,5,%r6
+ vextrs,od %r4,5,%r6
+ vextrs,tr %r4,5,%r6
+ vextrs,<> %r4,5,%r6
+ vextrs,>= %r4,5,%r6
+ vextrs,ev %r4,5,%r6
+
+zvdep_tests
+ zvdep %r4,5,%r6
+ zvdep,= %r4,5,%r6
+ zvdep,< %r4,5,%r6
+ zvdep,od %r4,5,%r6
+ zvdep,tr %r4,5,%r6
+ zvdep,<> %r4,5,%r6
+ zvdep,>= %r4,5,%r6
+ zvdep,ev %r4,5,%r6
+
+
+vdep_tests
+ vdep %r4,5,%r6
+ vdep,= %r4,5,%r6
+ vdep,< %r4,5,%r6
+ vdep,od %r4,5,%r6
+ vdep,tr %r4,5,%r6
+ vdep,<> %r4,5,%r6
+ vdep,>= %r4,5,%r6
+ vdep,ev %r4,5,%r6
+
+vdepi_tests
+ vdepi -1,5,%r6
+ vdepi,= -1,5,%r6
+ vdepi,< -1,5,%r6
+ vdepi,od -1,5,%r6
+ vdepi,tr -1,5,%r6
+ vdepi,<> -1,5,%r6
+ vdepi,>= -1,5,%r6
+ vdepi,ev -1,5,%r6
+
+zvdepi_tests
+ zvdepi -1,5,%r6
+ zvdepi,= -1,5,%r6
+ zvdepi,< -1,5,%r6
+ zvdepi,od -1,5,%r6
+ zvdepi,tr -1,5,%r6
+ zvdepi,<> -1,5,%r6
+ zvdepi,>= -1,5,%r6
+ zvdepi,ev -1,5,%r6
+
+depi_tests
+ depi -1,4,10,%r6
+ depi,= -1,4,10,%r6
+ depi,< -1,4,10,%r6
+ depi,od -1,4,10,%r6
+ depi,tr -1,4,10,%r6
+ depi,<> -1,4,10,%r6
+ depi,>= -1,4,10,%r6
+ depi,ev -1,4,10,%r6
+
+zdepi_tests
+ zdepi -1,4,10,%r6
+ zdepi,= -1,4,10,%r6
+ zdepi,< -1,4,10,%r6
+ zdepi,od -1,4,10,%r6
+ zdepi,tr -1,4,10,%r6
+ zdepi,<> -1,4,10,%r6
+ zdepi,>= -1,4,10,%r6
+ zdepi,ev -1,4,10,%r6
+
+
+system_control_tests
+ break 5,12
+ rfi
+ rfir
+ ssm 5,%r4
+ rsm 5,%r4
+ mtsm %r4
+ ldsid (%sr0,%r5),%r4
+ mtsp %r4,%sr0
+ mtctl %r4,%cr10
+ mfsp %sr0,%r4
+ mfctl %cr10,%r4
+ sync
+ syncdma
+ diag 1234
+
+probe_tests
+ prober (%sr0,%r5),%r6,%r7
+ proberi (%sr0,%r5),1,%r7
+ probew (%sr0,%r5),%r6,%r7
+ probewi (%sr0,%r5),1,%r7
+
+lpa_tests
+ lpa %r4(%sr0,%r5),%r6
+ lpa,m %r4(%sr0,%r5),%r6
+ lha %r4(%sr0,%r5),%r6
+ lha,m %r4(%sr0,%r5),%r6
+ lci %r4(%sr0,%r5),%r6
+
+purge_tests
+ pdtlb %r4(%sr0,%r5)
+ pdtlb,m %r4(%sr0,%r5)
+ pitlb %r4(%sr0,%r5)
+ pitlb,m %r4(%sr0,%r5)
+ pdtlbe %r4(%sr0,%r5)
+ pdtlbe,m %r4(%sr0,%r5)
+ pitlbe %r4(%sr0,%r5)
+ pitlbe,m %r4(%sr0,%r5)
+ pdc %r4(%sr0,%r5)
+ pdc,m %r4(%sr0,%r5)
+ fdc %r4(%sr0,%r5)
+ fdc,m %r4(%sr0,%r5)
+ fic %r4(%sr0,%r5)
+ fic,m %r4(%sr0,%r5)
+ fdce %r4(%sr0,%r5)
+ fdce,m %r4(%sr0,%r5)
+ fice %r4(%sr0,%r5)
+ fice,m %r4(%sr0,%r5)
+
+insert_tests
+ idtlba %r4,(%sr0,%r5)
+ iitlba %r4,(%sr0,%r5)
+ idtlbp %r4,(%sr0,%r5)
+ iitlbp %r4,(%sr0,%r5)
+
+fpu_misc_tests
+ ftest
+
+fpu_memory_indexing_tests
+ fldwx %r4(%sr0,%r5),%fr6
+ fldwx,s %r4(%sr0,%r5),%fr6
+ fldwx,m %r4(%sr0,%r5),%fr6
+ fldwx,sm %r4(%sr0,%r5),%fr6
+ flddx %r4(%sr0,%r5),%fr6
+ flddx,s %r4(%sr0,%r5),%fr6
+ flddx,m %r4(%sr0,%r5),%fr6
+ flddx,sm %r4(%sr0,%r5),%fr6
+ fstwx %fr6,%r4(%sr0,%r5)
+ fstwx,s %fr6,%r4(%sr0,%r5)
+ fstwx,m %fr6,%r4(%sr0,%r5)
+ fstwx,sm %fr6,%r4(%sr0,%r5)
+ fstdx %fr6,%r4(%sr0,%r5)
+ fstdx,s %fr6,%r4(%sr0,%r5)
+ fstdx,m %fr6,%r4(%sr0,%r5)
+ fstdx,sm %fr6,%r4(%sr0,%r5)
+ fstqx %fr6,%r4(%sr0,%r5)
+ fstqx,s %fr6,%r4(%sr0,%r5)
+ fstqx,m %fr6,%r4(%sr0,%r5)
+ fstqx,sm %fr6,%r4(%sr0,%r5)
+
+fpu_short_memory_tests
+ fldws 0(%sr0,%r5),%fr6
+ fldws,mb 0(%sr0,%r5),%fr6
+ fldws,ma 0(%sr0,%r5),%fr6
+ fldds 0(%sr0,%r5),%fr6
+ fldds,mb 0(%sr0,%r5),%fr6
+ fldds,ma 0(%sr0,%r5),%fr6
+ fstws %fr6,0(%sr0,%r5)
+ fstws,mb %fr6,0(%sr0,%r5)
+ fstws,ma %fr6,0(%sr0,%r5)
+ fstds %fr6,0(%sr0,%r5)
+ fstds,mb %fr6,0(%sr0,%r5)
+ fstds,ma %fr6,0(%sr0,%r5)
+ fstqs %fr6,0(%sr0,%r5)
+ fstqs,mb %fr6,0(%sr0,%r5)
+ fstqs,ma %fr6,0(%sr0,%r5)
+
+
+fcpy_tests
+ fcpy,sgl %fr5,%fr10
+ fcpy,dbl %fr5,%fr10
+ fcpy,quad %fr5,%fr10
+ fcpy,sgl %fr20,%fr24
+ fcpy,dbl %fr20,%fr24
+
+fabs_tests
+ fabs,sgl %fr5,%fr10
+ fabs,dbl %fr5,%fr10
+ fabs,quad %fr5,%fr10
+ fabs,sgl %fr20,%fr24
+ fabs,dbl %fr20,%fr24
+
+fsqrt_tests
+ fsqrt,sgl %fr5,%fr10
+ fsqrt,dbl %fr5,%fr10
+ fsqrt,quad %fr5,%fr10
+ fsqrt,sgl %fr20,%fr24
+ fsqrt,dbl %fr20,%fr24
+
+frnd_tests
+ frnd,sgl %fr5,%fr10
+ frnd,dbl %fr5,%fr10
+ frnd,quad %fr5,%fr10
+ frnd,sgl %fr20,%fr24
+ frnd,dbl %fr20,%fr24
+
+fcnvff_tests
+ fcnvff,sgl,sgl %fr5,%fr10
+ fcnvff,sgl,dbl %fr5,%fr10
+ fcnvff,sgl,quad %fr5,%fr10
+ fcnvff,dbl,sgl %fr5,%fr10
+ fcnvff,dbl,dbl %fr5,%fr10
+ fcnvff,dbl,quad %fr5,%fr10
+ fcnvff,quad,sgl %fr5,%fr10
+ fcnvff,quad,dbl %fr5,%fr10
+ fcnvff,quad,quad %fr5,%fr10
+ fcnvff,sgl,sgl %fr20,%fr24
+ fcnvff,sgl,dbl %fr20,%fr24
+ fcnvff,sgl,quad %fr20,%fr24
+ fcnvff,dbl,sgl %fr20,%fr24
+ fcnvff,dbl,dbl %fr20,%fr24
+ fcnvff,dbl,quad %fr20,%fr24
+ fcnvff,quad,sgl %fr20,%fr24
+ fcnvff,quad,dbl %fr20,%fr24
+ fcnvff,quad,quad %fr20,%fr24
+
+fcnvxf_tests
+ fcnvxf,sgl,sgl %fr5,%fr10
+ fcnvxf,sgl,dbl %fr5,%fr10
+ fcnvxf,sgl,quad %fr5,%fr10
+ fcnvxf,dbl,sgl %fr5,%fr10
+ fcnvxf,dbl,dbl %fr5,%fr10
+ fcnvxf,dbl,quad %fr5,%fr10
+ fcnvxf,quad,sgl %fr5,%fr10
+ fcnvxf,quad,dbl %fr5,%fr10
+ fcnvxf,quad,quad %fr5,%fr10
+ fcnvxf,sgl,sgl %fr20,%fr24
+ fcnvxf,sgl,dbl %fr20,%fr24
+ fcnvxf,sgl,quad %fr20,%fr24
+ fcnvxf,dbl,sgl %fr20,%fr24
+ fcnvxf,dbl,dbl %fr20,%fr24
+ fcnvxf,dbl,quad %fr20,%fr24
+ fcnvxf,quad,sgl %fr20,%fr24
+ fcnvxf,quad,dbl %fr20,%fr24
+ fcnvxf,quad,quad %fr20,%fr24
+
+fcnvfx_tests
+ fcnvfx,sgl,sgl %fr5,%fr10
+ fcnvfx,sgl,dbl %fr5,%fr10
+ fcnvfx,sgl,quad %fr5,%fr10
+ fcnvfx,dbl,sgl %fr5,%fr10
+ fcnvfx,dbl,dbl %fr5,%fr10
+ fcnvfx,dbl,quad %fr5,%fr10
+ fcnvfx,quad,sgl %fr5,%fr10
+ fcnvfx,quad,dbl %fr5,%fr10
+ fcnvfx,quad,quad %fr5,%fr10
+ fcnvfx,sgl,sgl %fr20,%fr24
+ fcnvfx,sgl,dbl %fr20,%fr24
+ fcnvfx,sgl,quad %fr20,%fr24
+ fcnvfx,dbl,sgl %fr20,%fr24
+ fcnvfx,dbl,dbl %fr20,%fr24
+ fcnvfx,dbl,quad %fr20,%fr24
+ fcnvfx,quad,sgl %fr20,%fr24
+ fcnvfx,quad,dbl %fr20,%fr24
+ fcnvfx,quad,quad %fr20,%fr24
+
+fcnvfxt_tests
+ fcnvfxt,sgl,sgl %fr5,%fr10
+ fcnvfxt,sgl,dbl %fr5,%fr10
+ fcnvfxt,sgl,quad %fr5,%fr10
+ fcnvfxt,dbl,sgl %fr5,%fr10
+ fcnvfxt,dbl,dbl %fr5,%fr10
+ fcnvfxt,dbl,quad %fr5,%fr10
+ fcnvfxt,quad,sgl %fr5,%fr10
+ fcnvfxt,quad,dbl %fr5,%fr10
+ fcnvfxt,quad,quad %fr5,%fr10
+ fcnvfxt,sgl,sgl %fr20,%fr24
+ fcnvfxt,sgl,dbl %fr20,%fr24
+ fcnvfxt,sgl,quad %fr20,%fr24
+ fcnvfxt,dbl,sgl %fr20,%fr24
+ fcnvfxt,dbl,dbl %fr20,%fr24
+ fcnvfxt,dbl,quad %fr20,%fr24
+ fcnvfxt,quad,sgl %fr20,%fr24
+ fcnvfxt,quad,dbl %fr20,%fr24
+ fcnvfxt,quad,quad %fr20,%fr24
+
+fadd_tests
+ fadd,sgl %fr4,%fr8,%fr12
+ fadd,dbl %fr4,%fr8,%fr12
+ fadd,quad %fr4,%fr8,%fr12
+ fadd,sgl %fr20,%fr24,%fr28
+ fadd,dbl %fr20,%fr24,%fr28
+ fadd,quad %fr20,%fr24,%fr28
+
+fsub_tests
+ fsub,sgl %fr4,%fr8,%fr12
+ fsub,dbl %fr4,%fr8,%fr12
+ fsub,quad %fr4,%fr8,%fr12
+ fsub,sgl %fr20,%fr24,%fr28
+ fsub,dbl %fr20,%fr24,%fr28
+ fsub,quad %fr20,%fr24,%fr28
+
+fmpy_tests
+ fmpy,sgl %fr4,%fr8,%fr12
+ fmpy,dbl %fr4,%fr8,%fr12
+ fmpy,quad %fr4,%fr8,%fr12
+ fmpy,sgl %fr20,%fr24,%fr28
+ fmpy,dbl %fr20,%fr24,%fr28
+ fmpy,quad %fr20,%fr24,%fr28
+
+fdiv_tests
+ fdiv,sgl %fr4,%fr8,%fr12
+ fdiv,dbl %fr4,%fr8,%fr12
+ fdiv,quad %fr4,%fr8,%fr12
+ fdiv,sgl %fr20,%fr24,%fr28
+ fdiv,dbl %fr20,%fr24,%fr28
+ fdiv,quad %fr20,%fr24,%fr28
+
+frem_tests
+ frem,sgl %fr4,%fr8,%fr12
+ frem,dbl %fr4,%fr8,%fr12
+ frem,quad %fr4,%fr8,%fr12
+ frem,sgl %fr20,%fr24,%fr28
+ frem,dbl %fr20,%fr24,%fr28
+ frem,quad %fr20,%fr24,%fr28
+
+fcmp_sgl_tests_1
+ fcmp,sgl,false? %fr4,%fr5
+ fcmp,sgl,false %fr4,%fr5
+ fcmp,sgl,? %fr4,%fr5
+ fcmp,sgl,!<=> %fr4,%fr5
+ fcmp,sgl,= %fr4,%fr5
+ fcmp,sgl,=T %fr4,%fr5
+ fcmp,sgl,?= %fr4,%fr5
+ fcmp,sgl,!<> %fr4,%fr5
+fcmp_sgl_tests_2
+ fcmp,sgl,!?>= %fr4,%fr5
+ fcmp,sgl,< %fr4,%fr5
+ fcmp,sgl,?< %fr4,%fr5
+ fcmp,sgl,!>= %fr4,%fr5
+ fcmp,sgl,!?> %fr4,%fr5
+ fcmp,sgl,<= %fr4,%fr5
+ fcmp,sgl,?<= %fr4,%fr5
+ fcmp,sgl,!> %fr4,%fr5
+fcmp_sgl_tests_3
+ fcmp,sgl,!?<= %fr4,%fr5
+ fcmp,sgl,> %fr4,%fr5
+ fcmp,sgl,?> %fr4,%fr5
+ fcmp,sgl,!<= %fr4,%fr5
+ fcmp,sgl,!?< %fr4,%fr5
+ fcmp,sgl,>= %fr4,%fr5
+ fcmp,sgl,?>= %fr4,%fr5
+ fcmp,sgl,!< %fr4,%fr5
+fcmp_sgl_tests_4
+ fcmp,sgl,!?= %fr4,%fr5
+ fcmp,sgl,<> %fr4,%fr5
+ fcmp,sgl,!= %fr4,%fr5
+ fcmp,sgl,!=T %fr4,%fr5
+ fcmp,sgl,!? %fr4,%fr5
+ fcmp,sgl,<=> %fr4,%fr5
+ fcmp,sgl,true? %fr4,%fr5
+ fcmp,sgl,true %fr4,%fr5
+
+fcmp_dbl_tests_1
+ fcmp,dbl,false? %fr4,%fr5
+ fcmp,dbl,false %fr4,%fr5
+ fcmp,dbl,? %fr4,%fr5
+ fcmp,dbl,!<=> %fr4,%fr5
+ fcmp,dbl,= %fr4,%fr5
+ fcmp,dbl,=T %fr4,%fr5
+ fcmp,dbl,?= %fr4,%fr5
+ fcmp,dbl,!<> %fr4,%fr5
+fcmp_dbl_tests_2
+ fcmp,dbl,!?>= %fr4,%fr5
+ fcmp,dbl,< %fr4,%fr5
+ fcmp,dbl,?< %fr4,%fr5
+ fcmp,dbl,!>= %fr4,%fr5
+ fcmp,dbl,!?> %fr4,%fr5
+ fcmp,dbl,<= %fr4,%fr5
+ fcmp,dbl,?<= %fr4,%fr5
+ fcmp,dbl,!> %fr4,%fr5
+fcmp_dbl_tests_3
+ fcmp,dbl,!?<= %fr4,%fr5
+ fcmp,dbl,> %fr4,%fr5
+ fcmp,dbl,?> %fr4,%fr5
+ fcmp,dbl,!<= %fr4,%fr5
+ fcmp,dbl,!?< %fr4,%fr5
+ fcmp,dbl,>= %fr4,%fr5
+ fcmp,dbl,?>= %fr4,%fr5
+ fcmp,dbl,!< %fr4,%fr5
+fcmp_dbl_tests_4
+ fcmp,dbl,!?= %fr4,%fr5
+ fcmp,dbl,<> %fr4,%fr5
+ fcmp,dbl,!= %fr4,%fr5
+ fcmp,dbl,!=T %fr4,%fr5
+ fcmp,dbl,!? %fr4,%fr5
+ fcmp,dbl,<=> %fr4,%fr5
+ fcmp,dbl,true? %fr4,%fr5
+ fcmp,dbl,true %fr4,%fr5
+
+fcmp_quad_tests_1
+ fcmp,quad,false? %fr4,%fr5
+ fcmp,quad,false %fr4,%fr5
+ fcmp,quad,? %fr4,%fr5
+ fcmp,quad,!<=> %fr4,%fr5
+ fcmp,quad,= %fr4,%fr5
+ fcmp,quad,=T %fr4,%fr5
+ fcmp,quad,?= %fr4,%fr5
+ fcmp,quad,!<> %fr4,%fr5
+fcmp_quad_tests_2
+ fcmp,quad,!?>= %fr4,%fr5
+ fcmp,quad,< %fr4,%fr5
+ fcmp,quad,?< %fr4,%fr5
+ fcmp,quad,!>= %fr4,%fr5
+ fcmp,quad,!?> %fr4,%fr5
+ fcmp,quad,<= %fr4,%fr5
+ fcmp,quad,?<= %fr4,%fr5
+ fcmp,quad,!> %fr4,%fr5
+fcmp_quad_tests_3
+ fcmp,quad,!?<= %fr4,%fr5
+ fcmp,quad,> %fr4,%fr5
+ fcmp,quad,?> %fr4,%fr5
+ fcmp,quad,!<= %fr4,%fr5
+ fcmp,quad,!?< %fr4,%fr5
+ fcmp,quad,>= %fr4,%fr5
+ fcmp,quad,?>= %fr4,%fr5
+ fcmp,quad,!< %fr4,%fr5
+fcmp_quad_tests_4
+ fcmp,quad,!?= %fr4,%fr5
+ fcmp,quad,<> %fr4,%fr5
+ fcmp,quad,!= %fr4,%fr5
+ fcmp,quad,!=T %fr4,%fr5
+ fcmp,quad,!? %fr4,%fr5
+ fcmp,quad,<=> %fr4,%fr5
+ fcmp,quad,true? %fr4,%fr5
+ fcmp,quad,true %fr4,%fr5
+
+fmpy_addsub_tests
+ fmpyadd,sgl %fr16,%fr17,%fr18,%fr19,%fr20
+ fmpyadd,dbl %fr16,%fr17,%fr18,%fr19,%fr20
+ fmpysub,sgl %fr16,%fr17,%fr18,%fr19,%fr20
+ fmpysub,dbl %fr16,%fr17,%fr18,%fr19,%fr20
+
+xmpyu_tests
+ xmpyu %fr4,%fr5,%fr6
+
+special_tests
+ gfw %r4(%sr0,%r5)
+ gfw,m %r4(%sr0,%r5)
+ gfr %r4(%sr0,%r5)
+ gfr,m %r4(%sr0,%r5)
+
+sfu_tests
+ spop0,4,5
+ spop0,4,115
+ spop0,4,5,n
+ spop0,4,115,n
+ spop1,4,5 5
+ spop1,4,115 5
+ spop1,4,5,n 5
+ spop1,4,115,n 5
+ spop2,4,5 5
+ spop2,4,115 5
+ spop2,4,5,n 5
+ spop2,4,115,n 5
+ spop3,4,5 5,6
+ spop3,4,115 5,6
+ spop3,4,5,n 5,6
+ spop3,4,115,n 5,6
+
+copr_tests
+ copr,4,5
+ copr,4,115
+ copr,4,5,n
+ copr,4,115,n
+
+copr_indexing_load
+ cldwx,4 5(0,4),26
+ cldwx,4,s 5(0,4),26
+ cldwx,4,m 5(0,4),26
+ cldwx,4,sm 5(0,4),26
+ clddx,4 5(0,4),26
+ clddx,4,s 5(0,4),26
+ clddx,4,m 5(0,4),26
+ clddx,4,sm 5(0,4),26
+
+copr_indexing_store
+ cstwx,4 26,5(0,4)
+ cstwx,4,s 26,5(0,4)
+ cstwx,4,m 26,5(0,4)
+ cstwx,4,sm 26,5(0,4)
+ cstdx,4 26,5(0,4)
+ cstdx,4,s 26,5(0,4)
+ cstdx,4,m 26,5(0,4)
+ cstdx,4,sm 26,5(0,4)
+
+copr_short_memory
+ cldws,4 0(0,4),26
+ cldws,4,mb 0(0,4),26
+ cldws,4,ma 0(0,4),26
+ cldds,4 0(0,4),26
+ cldds,4,mb 0(0,4),26
+ cldds,4,ma 0(0,4),26
+ cstws,4 26,0(0,4)
+ cstws,4,mb 26,0(0,4)
+ cstws,4,ma 26,0(0,4)
+ cstds,4 26,0(0,4)
+ cstds,4,mb 26,0(0,4)
+ cstds,4,ma 26,0(0,4)
+
+fmemLRbug_tests_1
+ fstws %fr6R,0(%r26)
+ fstws %fr6L,4(%r26)
+ fstws %fr6,8(%r26)
+ fstds %fr6R,0(%r26)
+ fstds %fr6L,4(%r26)
+ fstds %fr6,8(%r26)
+ fldws 0(%r26),%fr6R
+ fldws 4(%r26),%fr6L
+ fldws 8(%r26),%fr6
+ fldds 0(%r26),%fr6R
+ fldds 4(%r26),%fr6L
+ fldds 8(%r26),%fr6
+
+fmemLRbug_tests_2
+ fstws %fr6R,0(%sr0,%r26)
+ fstws %fr6L,4(%sr0,%r26)
+ fstws %fr6,8(%sr0,%r26)
+ fstds %fr6R,0(%sr0,%r26)
+ fstds %fr6L,4(%sr0,%r26)
+ fstds %fr6,8(%sr0,%r26)
+ fldws 0(%sr0,%r26),%fr6R
+ fldws 4(%sr0,%r26),%fr6L
+ fldws 8(%sr0,%r26),%fr6
+ fldds 0(%sr0,%r26),%fr6R
+ fldds 4(%sr0,%r26),%fr6L
+ fldds 8(%sr0,%r26),%fr6
+
+fmemLRbug_tests_3
+ fstwx %fr6R,%r25(%r26)
+ fstwx %fr6L,%r25(%r26)
+ fstwx %fr6,%r25(%r26)
+ fstdx %fr6R,%r25(%r26)
+ fstdx %fr6L,%r25(%r26)
+ fstdx %fr6,%r25(%r26)
+ fldwx %r25(%r26),%fr6R
+ fldwx %r25(%r26),%fr6L
+ fldwx %r25(%r26),%fr6
+ flddx %r25(%r26),%fr6R
+ flddx %r25(%r26),%fr6L
+ flddx %r25(%r26),%fr6
+
+fmemLRbug_tests_4
+ fstwx %fr6R,%r25(%sr0,%r26)
+ fstwx %fr6L,%r25(%sr0,%r26)
+ fstwx %fr6,%r25(%sr0,%r26)
+ fstdx %fr6R,%r25(%sr0,%r26)
+ fstdx %fr6L,%r25(%sr0,%r26)
+ fstdx %fr6,%r25(%sr0,%r26)
+ fldwx %r25(%sr0,%r26),%fr6R
+ fldwx %r25(%sr0,%r26),%fr6L
+ fldwx %r25(%sr0,%r26),%fr6
+ flddx %r25(%sr0,%r26),%fr6R
+ flddx %r25(%sr0,%r26),%fr6L
+ flddx %r25(%sr0,%r26),%fr6
+
+ ldw 0(0,%r4),%r26
+ ldw 0(0,%r4),%r26
+ ldo 64(%r4),%r30
+ ldwm -64(0,%r30),%r4
+ bv,n 0(%r2)
+ .EXIT
+ .PROCEND
diff --git a/gdb/testsuite/gdb.disasm/mn10200.exp b/gdb/testsuite/gdb.disasm/mn10200.exp
new file mode 100644
index 00000000000..33cdb47c5c7
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/mn10200.exp
@@ -0,0 +1,478 @@
+
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Jeff Law. (law@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if ![istarget "mn10200*-*-*"] {
+ verbose "Tests ignored for all but mn10200 based targets."
+ return
+}
+
+global exec_output
+set prms_id 0
+set bug_id 0
+
+set testfile "mn10200"
+set srcfile ${srcdir}/${subdir}/${testfile}.s
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcfile}" "${binfile}" executable ""] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+proc add_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/12i add_tests\n"
+ gdb_expect {
+ -re "
+.*add d1,d2.*
+.*add d2,a3.*
+.*add a2,d1.*
+.*add a3,a2.*
+.*add 16,d1.*
+.*add 256,d2.*
+.*add 131071,d3.*
+.*add 16,a1.*
+.*add 256,a2.*
+.*add 131071,a3.*
+.*addc d1,d2.*
+.*addnf 16,a2.*
+.*$gdb_prompt $" { pass "add tests" }
+ -re "$gdb_prompt $" { fail "add tests" }
+ timeout { fail "(timeout) add tests" }
+ }
+}
+
+proc bcc_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/15i bCC_tests\n"
+ gdb_expect {
+ -re "
+.*beq 0x\[0-9a-f]+ <bCC_tests>.*
+.*bne 0x\[0-9a-f]+ <bCC_tests>.*
+.*bgt 0x\[0-9a-f]+ <bCC_tests>.*
+.*bge 0x\[0-9a-f]+ <bCC_tests>.*
+.*ble 0x\[0-9a-f]+ <bCC_tests>.*
+.*blt 0x\[0-9a-f]+ <bCC_tests>.*
+.*bhi 0x\[0-9a-f]+ <bCC_tests>.*
+.*bcc 0x\[0-9a-f]+ <bCC_tests>.*
+.*bls 0x\[0-9a-f]+ <bCC_tests>.*
+.*bcs 0x\[0-9a-f]+ <bCC_tests>.*
+.*bvc 0x\[0-9a-f]+ <bCC_tests>.*
+.*bvs 0x\[0-9a-f]+ <bCC_tests>.*
+.*bnc 0x\[0-9a-f]+ <bCC_tests>.*
+.*bns 0x\[0-9a-f]+ <bCC_tests>.*
+.*bra 0x\[0-9a-f]+ <bCC_tests>.*
+.*$gdb_prompt $" { pass "bCC tests" }
+ -re "$gdb_prompt $" { fail "bCC tests" }
+ timeout { fail "(timeout) bCC tests" }
+ }
+}
+
+proc bccx_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/14i bCCx_tests\n"
+ gdb_expect {
+ -re "
+.*beqx 0x\[0-9a-f]+ <bCCx_tests>.*
+.*bnex 0x\[0-9a-f]+ <bCCx_tests>.*
+.*bgtx 0x\[0-9a-f]+ <bCCx_tests>.*
+.*bgex 0x\[0-9a-f]+ <bCCx_tests>.*
+.*blex 0x\[0-9a-f]+ <bCCx_tests>.*
+.*bltx 0x\[0-9a-f]+ <bCCx_tests>.*
+.*bhix 0x\[0-9a-f]+ <bCCx_tests>.*
+.*bccx 0x\[0-9a-f]+ <bCCx_tests>.*
+.*blsx 0x\[0-9a-f]+ <bCCx_tests>.*
+.*bcsx 0x\[0-9a-f]+ <bCCx_tests>.*
+.*bvcx 0x\[0-9a-f]+ <bCCx_tests>.*
+.*bvsx 0x\[0-9a-f]+ <bCCx_tests>.*
+.*bncx 0x\[0-9a-f]+ <bCCx_tests>.*
+.*bnsx 0x\[0-9a-f]+ <bCCx_tests>.*
+.*$gdb_prompt $" { pass "bCCx tests" }
+ -re "$gdb_prompt $" { fail "bCCx tests" }
+ timeout { fail "(timeout) bCCx tests" }
+ }
+}
+
+proc bit_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/4 bit_tests\n"
+ gdb_expect {
+ -re "
+.*btst 64,d1.*
+.*btst 8192,d2.*
+.*bset d1,\\(a2\\).*
+.*bclr d1,\\(a2\\).*
+.*$gdb_prompt $" { pass "bit tests" }
+ -re "$gdb_prompt $" { fail "bit tests" }
+ timeout { fail "(timeout) bit tests" }
+ }
+}
+
+proc cmp_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/9i cmp_tests\n"
+ gdb_expect {
+ -re "
+.*cmp d1,d2.*
+.*cmp d2,a3.*
+.*cmp a3,d3.*
+.*cmp a3,a2.*
+.*cmp 16,d3.*
+.*cmp 256,d2.*
+.*cmp 131071,d1.*
+.*cmp 256,a2.*
+.*cmp 131071,a1.*
+.*$gdb_prompt $" { pass "cmp tests" }
+ -re "$gdb_prompt $" { fail "cmp tests" }
+ timeout { fail "(timeout) cmp tests" }
+ }
+}
+
+proc extend_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/5i extend_tests\n"
+ gdb_expect {
+ -re "
+.*ext d1.*
+.*extx d2.*
+.*extxu d3.*
+.*extxb d2.*
+.*extxbu d1.*
+.*$gdb_prompt $" { pass "extend tests" }
+ -re "$gdb_prompt $" { fail "extend tests" }
+ timeout { fail "(timeout) extend tests" }
+ }
+}
+
+proc logical_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/11i logical_tests\n"
+ gdb_expect {
+ -re "
+.*and d1,d2.*
+.*and 127,d2.*
+.*and 32767,d3.*
+.*and 32767,psw.*
+.*or d1,d2.*
+.*or 127,d2.*
+.*or 32767,d3.*
+.*or 32767,psw.*
+.*xor d1,d2.*
+.*xor 32767,d3.*
+.*not d3.*
+.*$gdb_prompt $" { pass "logical tests" }
+ -re "$gdb_prompt $" { fail "logical tests" }
+ timeout { fail "(timeout) logical tests" }
+ }
+}
+
+proc mov_tests_1 { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/12i mov_tests_1\n"
+ gdb_expect {
+ -re "
+.*mov d1,a2.*
+.*mov a2,d1.*
+.*mov d1,d2.*
+.*mov a2,a1.*
+.*mov psw,d3.*
+.*mov d2,psw.*
+.*mov mdr,d1.*
+.*mov d2,mdr.*
+.*mov \\(a2\\),d1.*
+.*mov \\(8,a2\\),d1.*
+.*mov \\(256,a2\\),d1.*
+.*mov \\(131071,a2\\),d1.*
+.*$gdb_prompt $" { pass "mov1 tests" }
+ -re "$gdb_prompt $" { fail "mov1 tests" }
+ timeout { fail "(timeout) mov1 tests" }
+ }
+}
+
+proc mov_tests_2 { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/9 mov_tests_2\n"
+ gdb_expect {
+ -re "
+.*mov \\(d1,a1\\),d2.*
+.*mov \\(0x8000.*\\),d1.*
+.*mov \\(0x1ffff.*\\),d1.*
+.*mov \\(8,a2\\),a1.*
+.*mov \\(256,a2\\),a1.*
+.*mov \\(131071,a2\\),a1.*
+.*mov \\(d1,a1\\),a2.*
+.*mov \\(0x8000.*\\),a1.*
+.*mov \\(0x1ffff.*\\),a1.*
+.*$gdb_prompt $" { pass "mov2 tests" }
+ -re "$gdb_prompt $" { fail "mov2 tests" }
+ timeout { fail "(timeout) mov2 tests" }
+ }
+}
+
+proc mov_tests_3 { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/10 mov_tests_3\n"
+ gdb_expect {
+ -re "
+.*mov d1,\\(a2\\).*
+.*mov d1,\\(32,a2\\).*
+.*mov d1,\\(256,a2\\).*
+.*mov d1,\\(131071,a2\\).*
+.*mov d1,\\(d2,a2\\).*
+.*mov d1,\\(0x80.*\\).*
+.*mov d1,\\(0x1ffff.*\\).*
+.*mov a1,\\(32,a2\\).*
+.*mov a1,\\(256,a2\\).*
+.*mov a1,\\(131071,a2\\).*
+.*$gdb_prompt $" { pass "mov3 tests" }
+ -re "$gdb_prompt $" { fail "mov3 tests" }
+ timeout { fail "(timeout) mov3 tests" }
+ }
+}
+
+proc mov_tests_4 { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/8 mov_tests_4\n"
+ gdb_expect {
+ -re "
+.*mov a1,\\(d2,a2\\).*
+.*mov a1,\\(0x80.*\\).*
+.*mov a1,\\(0x1ffff.*\\).*
+.*mov 8,d1.*
+.*mov 256,d1.*
+.*mov 131071,d1.*
+.*mov 256,a1.*
+.*mov 131071,a1.*
+.*$gdb_prompt $" { pass "mov4 tests" }
+ -re "$gdb_prompt $" { fail "mov4 tests" }
+ timeout { fail "(timeout) mov4 tests" }
+ }
+}
+
+proc movb_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/12 movb_tests\n"
+ gdb_expect {
+ -re "
+.*movb \\(8,a2\\),d1.*
+.*movb \\(256,a2\\),d1.*
+.*movb \\(131071,a2\\),d1.*
+.*movb \\(d2,a2\\),d3.*
+.*movb \\(0x1ffff.*\\),d2.*
+.*movb d1,\\(a2\\).*
+.*movb d1,\\(8,a2\\).*
+.*movb d1,\\(256,a2\\).*
+.*movb d1,\\(131071,a2\\).*
+.*movb d1,\\(d2,a2\\).*
+.*movb d1,\\(0x100.*\\).*
+.*movb d1,\\(0x1ffff.*\\).*
+.*$gdb_prompt $" { pass "movb tests" }
+ -re "$gdb_prompt $" { fail "movb tests" }
+ timeout { fail "(timeout) movb tests" }
+ }
+}
+
+proc movbu_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/7 movbu_tests\n"
+ gdb_expect {
+ -re "
+.*movbu \\(a2\\),d1.*
+.*movbu \\(8,a2\\),d1.*
+.*movbu \\(256,a2\\),d1.*
+.*movbu \\(131071,a2\\),d1.*
+.*movbu \\(d1,a1\\),d2.*
+.*movbu \\(0x8000.*\\),d1.*
+.*movbu \\(0x1ffff.*\\),d1.*
+.*$gdb_prompt $" { pass "movbu tests" }
+ -re "$gdb_prompt $" { fail "movbu tests" }
+ timeout { fail "(timeout) movbu tests" }
+ }
+}
+
+proc movx_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/6 movx_tests\n"
+ gdb_expect {
+ -re "
+.*movx \\(8,a2\\),d1.*
+.*movx \\(256,a2\\),d1.*
+.*movx \\(131071,a2\\),d1.*
+.*movx d1,\\(8,a2\\).*
+.*movx d1,\\(256,a2\\).*
+.*movx d1,\\(131071,a2\\).*
+.*$gdb_prompt $" { pass "movx tests" }
+ -re "$gdb_prompt $" { fail "movx tests" }
+ timeout { fail "(timeout) movx tests" }
+ }
+}
+
+proc muldiv_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/3 muldiv_tests\n"
+ gdb_expect {
+ -re "
+.*mul d1,d2.*
+.*mulu d2,d3.*
+.*divu d3,d2.*
+.*$gdb_prompt $" { pass "muldiv tests" }
+ -re "$gdb_prompt $" { fail "muldiv tests" }
+ timeout { fail "(timeout) muldiv tests" }
+ }
+}
+
+proc misc_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/9 misc_tests\n"
+ gdb_expect {
+ -re "
+.*jmp 0x\[0-9a-f]+ <main>.*
+.*jmp 0x\[0-9a-f]+ <start>.*
+.*jmp \\(a2\\).*
+.*jsr 0x\[0-9a-f]+ <main>.*
+.*jsr 0x\[0-9a-f]+ <start>.*
+.*jsr \\(a2\\).*
+.*rts.*
+.*rti.*
+.*nop.*
+.*$gdb_prompt $" { pass "misc tests" }
+ -re "$gdb_prompt $" { fail "misc tests" }
+ timeout { fail "(timeout) misc tests" }
+ }
+}
+
+proc shift_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/4i shift_tests\n"
+ gdb_expect {
+ -re "
+.*asr d2.*
+.*lsr d3.*
+.*ror d1.*
+.*rol d2.*
+.*$gdb_prompt $" { pass "shift tests" }
+ -re "$gdb_prompt $" { fail "shift tests" }
+ timeout { fail "(timeout) shift tests" }
+ }
+}
+
+proc sub_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/9i sub_tests\n"
+ gdb_expect {
+ -re "
+.*sub d1,d2.*
+.*sub d2,a3.*
+.*sub a3,d3.*
+.*sub a3,a2.*
+.*sub 32767,d2.*
+.*sub 131071,d2.*
+.*sub 32767,a2.*
+.*sub 131071,a2.*
+.*subc d1,d2.*
+.*$gdb_prompt $" { pass "sub tests" }
+ -re "$gdb_prompt $" { fail "sub tests" }
+ timeout { fail "(timeout) sub tests" }
+ }
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+add_tests
+bcc_tests
+bccx_tests
+bit_tests
+cmp_tests
+extend_tests
+logical_tests
+mov_tests_1
+mov_tests_2
+mov_tests_3
+mov_tests_4
+movb_tests
+movbu_tests
+movx_tests
+muldiv_tests
+misc_tests
+shift_tests
+sub_tests
diff --git a/gdb/testsuite/gdb.disasm/mn10200.s b/gdb/testsuite/gdb.disasm/mn10200.s
new file mode 100644
index 00000000000..32357b0401b
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/mn10200.s
@@ -0,0 +1,217 @@
+ .text
+ .global _main
+ .global add_tests
+ .global bCC_tests
+ .global bCCx_tests
+ .global bit_tests
+ .global cmp_tests
+ .global extend_tests
+ .global logical_tests
+ .global mov_tests_1
+ .global mov_tests_2
+ .global mov_tests_3
+ .global mov_tests_4
+ .global movb_tests
+ .global movbu_tests
+ .global movx_tests
+ .global misc_tests
+ .global shift_tests
+ .global sub_tests
+
+_main:
+ nop
+
+add_tests:
+ add d1,d2
+ add d2,a3
+ add a2,d1
+ add a3,a2
+ add 16,d1
+ add 256,d2
+ add 131071,d3
+ add 16,a1
+ add 256,a2
+ add 131071,a3
+ addc d1,d2
+ addnf 16,a2
+
+bCC_tests:
+ beq bCC_tests
+ bne bCC_tests
+ bgt bCC_tests
+ bge bCC_tests
+ ble bCC_tests
+ blt bCC_tests
+ bhi bCC_tests
+ bcc bCC_tests
+ bls bCC_tests
+ bcs bCC_tests
+ bvc bCC_tests
+ bvs bCC_tests
+ bnc bCC_tests
+ bns bCC_tests
+ bra bCC_tests
+
+bCCx_tests:
+ beqx bCCx_tests
+ bnex bCCx_tests
+ bgtx bCCx_tests
+ bgex bCCx_tests
+ blex bCCx_tests
+ bltx bCCx_tests
+ bhix bCCx_tests
+ bccx bCCx_tests
+ blsx bCCx_tests
+ bcsx bCCx_tests
+ bvcx bCCx_tests
+ bvsx bCCx_tests
+ bncx bCCx_tests
+ bnsx bCCx_tests
+
+bit_tests:
+ btst 64,d1
+ btst 8192,d2
+ bset d1,(a2)
+ bclr d1,(a2)
+
+cmp_tests:
+ cmp d1,d2
+ cmp d2,a3
+ cmp a3,d3
+ cmp a3,a2
+ cmp 16,d3
+ cmp 256,d2
+ cmp 131071,d1
+ cmp 256,a2
+ cmp 131071,a1
+
+extend_tests:
+ ext d1
+ extx d2
+ extxu d3
+ extxb d2
+ extxbu d1
+
+logical_tests:
+ and d1,d2
+ and 127,d2
+ and 32767,d3
+ and 32767,psw
+ or d1,d2
+ or 127,d2
+ or 32767,d3
+ or 32767,psw
+ xor d1,d2
+ xor 32767,d3
+ not d3
+
+mov_tests_1:
+ mov d1,a2
+ mov a2,d1
+ mov d1,d2
+ mov a2,a1
+ mov psw,d3
+ mov d2,psw
+ mov mdr,d1
+ mov d2,mdr
+ mov (a2),d1
+ mov (8,a2),d1
+ mov (256,a2),d1
+ mov (131071,a2),d1
+
+mov_tests_2:
+ mov (d1,a1),d2
+ mov (32768),d1
+ mov (131071),d1
+ mov (8,a2),a1
+ mov (256,a2),a1
+ mov (131071,a2),a1
+ mov (d1,a1),a2
+ mov (32768),a1
+ mov (131071),a1
+
+mov_tests_3:
+ mov d1,(a2)
+ mov d1,(32,a2)
+ mov d1,(256,a2)
+ mov d1,(131071,a2)
+ mov d1,(d2,a2)
+ mov d1,(128)
+ mov d1,(131071)
+ mov a1,(32,a2)
+ mov a1,(256,a2)
+ mov a1,(131071,a2)
+
+mov_tests_4:
+ mov a1,(d2,a2)
+ mov a1,(128)
+ mov a1,(131071)
+ mov 8,d1
+ mov 256,d1
+ mov 131071,d1
+ mov 256,a1
+ mov 131071,a1
+
+movb_tests:
+ movb (8,a2),d1
+ movb (256,a2),d1
+ movb (131071,a2),d1
+ movb (d2,a2),d3
+ movb (131071),d2
+ movb d1,(a2)
+ movb d1,(8,a2)
+ movb d1,(256,a2)
+ movb d1,(131071,a2)
+ movb d1,(d2,a2)
+ movb d1,(256)
+ movb d1,(131071)
+
+movbu_tests:
+ movbu (a2),d1
+ movbu (8,a2),d1
+ movbu (256,a2),d1
+ movbu (131071,a2),d1
+ movbu (d1,a1),d2
+ movbu (32768),d1
+ movbu (131071),d1
+
+movx_tests:
+ movx (8,a2),d1
+ movx (256,a2),d1
+ movx (131071,a2),d1
+ movx d1,(8,a2)
+ movx d1,(256,a2)
+ movx d1,(131071,a2)
+
+muldiv_tests:
+ mul d1,d2
+ mulu d2,d3
+ divu d3,d2
+
+misc_tests:
+ jmp _main
+ jmp _start
+ jmp (a2)
+ jsr _main
+ jsr _start
+ jsr (a2)
+ rts
+ rti
+ nop
+
+shift_tests:
+ asr d2
+ lsr d3
+ ror d1
+ rol d2
+
+sub_tests:
+ sub d1,d2
+ sub d2,a3
+ sub a3,d3
+ sub a3,a2
+ sub 32767,d2
+ sub 131071,d2
+ sub 32767,a2
+ sub 131071,a2
+ subc d1,d2
diff --git a/gdb/testsuite/gdb.disasm/mn10300.exp b/gdb/testsuite/gdb.disasm/mn10300.exp
new file mode 100644
index 00000000000..0f12226205b
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/mn10300.exp
@@ -0,0 +1,569 @@
+
+# Copyright 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Jeff Law. (law@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if ![istarget "mn10300*-*-*"] {
+ verbose "Tests ignored for all but mn10300 based targets."
+ return
+}
+
+global exec_output
+set prms_id 0
+set bug_id 0
+
+set testfile "mn10300"
+set srcfile ${srcdir}/${subdir}/${testfile}.s
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcfile}" "${binfile}" executable ""] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+proc add_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/14i add_tests\n"
+ gdb_expect {
+ -re "
+.*add d1,d2.*
+.*add d2,a3.*
+.*add a3,a2.*
+.*add a2,d1.*
+.*add 16,d1.*
+.*add 256,d2.*
+.*add 131071,d3.*
+.*add 16,a1.*
+.*add 256,a2.*
+.*add 131071,a3.*
+.*add 16,sp.*
+.*add 256,sp.*
+.*add 131071,sp.*
+.*addc d1,d2.*
+.*$gdb_prompt $" { pass "add tests" }
+ -re "$gdb_prompt $" { fail "add tests" }
+ timeout { fail "(timeout) add tests" }
+ }
+}
+
+proc bcc_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/15i bCC_tests\n"
+ gdb_expect {
+ -re "
+.*beq 0x\[0-9a-f]+ <bCC_tests>.*
+.*bne 0x\[0-9a-f]+ <bCC_tests>.*
+.*bgt 0x\[0-9a-f]+ <bCC_tests>.*
+.*bge 0x\[0-9a-f]+ <bCC_tests>.*
+.*ble 0x\[0-9a-f]+ <bCC_tests>.*
+.*blt 0x\[0-9a-f]+ <bCC_tests>.*
+.*bhi 0x\[0-9a-f]+ <bCC_tests>.*
+.*bcc 0x\[0-9a-f]+ <bCC_tests>.*
+.*bls 0x\[0-9a-f]+ <bCC_tests>.*
+.*bcs 0x\[0-9a-f]+ <bCC_tests>.*
+.*bvc 0x\[0-9a-f]+ <bCC_tests>.*
+.*bvs 0x\[0-9a-f]+ <bCC_tests>.*
+.*bnc 0x\[0-9a-f]+ <bCC_tests>.*
+.*bns 0x\[0-9a-f]+ <bCC_tests>.*
+.*bra 0x\[0-9a-f]+ <bCC_tests>.*
+.*$gdb_prompt $" { pass "bCC tests" }
+ -re "$gdb_prompt $" { fail "bCC tests" }
+ timeout { fail "(timeout) bCC tests" }
+ }
+}
+
+proc bit_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/11i bit_tests\n"
+ gdb_expect {
+ -re "
+.*btst 64,d1.*
+.*btst 8192,d2.*
+.*btst 131071,d3.*
+.*btst 64,\\(8,a1\\).*
+.*btst 64,\\(0x1ffff\\).*
+.*bset d1,\\(a2\\).*
+.*bset 64,\\(8,a1\\).*
+.*bset 64,\\(0x1ffff\\).*
+.*bclr d1,\\(a2\\).*
+.*bclr 64,\\(8,a1\\).*
+.*bclr 64,\\(0x1ffff\\).*
+.*$gdb_prompt $" { pass "bit tests" }
+ -re "$gdb_prompt $" { fail "bit tests" }
+ timeout { fail "(timeout) bit tests" }
+ }
+}
+
+proc cmp_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/10i cmp_tests\n"
+ gdb_expect {
+ -re "
+.*cmp d1,d2.*
+.*cmp d2,a3.*
+.*cmp a3,d3.*
+.*cmp a3,a2.*
+.*cmp 16,d3.*
+.*cmp 256,d2.*
+.*cmp 131071,d1.*
+.*cmp 16,a3.*
+.*cmp 256,a2.*
+.*cmp 131071,a1.*
+.*$gdb_prompt $" { pass "cmp tests" }
+ -re "$gdb_prompt $" { fail "cmp tests" }
+ timeout { fail "(timeout) cmp tests" }
+ }
+}
+
+proc extend_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/5i extend_tests\n"
+ gdb_expect {
+ -re "
+.*ext d1.*
+.*extb d2.*
+.*extbu d3.*
+.*exth d2.*
+.*exthu d1.*
+.*$gdb_prompt $" { pass "extend tests" }
+ -re "$gdb_prompt $" { fail "extend tests" }
+ timeout { fail "(timeout) extend tests" }
+ }
+}
+
+proc extended_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/13i extended_tests\n"
+ gdb_expect {
+ -re "
+.*putx d1.*
+.*getx d2.*
+.*mulq d1,d2.*
+.*mulq 16,d2.*
+.*mulq 256,d3.*
+.*mulq 131071,d3.*
+.*mulqu d1,d2.*
+.*mulqu 16,d2.*
+.*mulqu 256,d3.*
+.*mulqu 131071,d3.*
+.*sat16 d2,d3.*
+.*sat24 d3,d2.*
+.*bsch d1,d2.*
+.*$gdb_prompt $" { pass "extended tests" }
+ -re "$gdb_prompt $" { fail "extended tests" }
+ timeout { fail "(timeout) extended tests" }
+ }
+}
+
+proc logical_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/14i logical_tests\n"
+ gdb_expect {
+ -re "
+.*and d1,d2.*
+.*and 127,d2.*
+.*and 32767,d3.*
+.*and 131071,d3.*
+.*and 32767,psw.*
+.*or d1,d2.*
+.*or 127,d2.*
+.*or 32767,d3.*
+.*or 131071,d3.*
+.*or 32767,psw.*
+.*xor d1,d2.*
+.*xor 32767,d3.*
+.*xor 131071,d3.*
+.*not d3.*
+.*$gdb_prompt $" { pass "logical tests" }
+ -re "$gdb_prompt $" { fail "logical tests" }
+ timeout { fail "(timeout) logical tests" }
+ }
+}
+
+proc loop_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/12i loop_tests\n"
+ gdb_expect {
+ -re "
+.*leq.*
+.*lne.*
+.*lgt.*
+.*lge.*
+.*lle.*
+.*llt.*
+.*lhi.*
+.*lcc.*
+.*lls.*
+.*lcs.*
+.*lra.*
+.*setlb.*
+.*$gdb_prompt $" { pass "loop tests" }
+ -re "$gdb_prompt $" { fail "loop tests" }
+ timeout { fail "(timeout) loop tests" }
+ }
+}
+
+proc mov_tests_1 { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/16i mov_tests_1\n"
+ gdb_expect {
+ -re "
+.*mov d1,d2.*
+.*mov d1,a2.*
+.*mov a2,d1.*
+.*mov a2,a1.*
+.*mov sp,a2.*
+.*mov a1,sp.*
+.*mov d2,psw.*
+.*mov mdr,d1.*
+.*mov d2,mdr.*
+.*mov \\(a2\\),d1.*
+.*mov \\(8,a2\\),d1.*
+.*mov \\(256,a2\\),d1.*
+.*mov \\(131071,a2\\),d1.*
+.*mov \\(8,sp\\),d1.*
+.*mov \\(256,sp\\),d1.*
+.*mov psw,d3.*
+.*$gdb_prompt $" { pass "mov1 tests" }
+ -re "$gdb_prompt $" { fail "mov1 tests" }
+ timeout { fail "(timeout) mov1 tests" }
+ }
+}
+
+proc mov_tests_2 { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/15i mov_tests_2\n"
+ gdb_expect {
+ -re "
+.*mov \\(131071,sp\\),d1.*
+.*mov \\(d1,a1\\),d2.*
+.*mov \\(0x8000.*\\),d1.*
+.*mov \\(0x1ffff.*\\),d1.*
+.*mov \\(a2\\),a1.*
+.*mov \\(8,a2\\),a1.*
+.*mov \\(256,a2\\),a1.*
+.*mov \\(131071,a2\\),a1.*
+.*mov \\(8,sp\\),a1.*
+.*mov \\(256,sp\\),a1.*
+.*mov \\(131071,sp\\),a1.*
+.*mov \\(d1,a1\\),a2.*
+.*mov \\(0x8000.*\\),a1.*
+.*mov \\(0x1ffff.*\\),a1.*
+.*mov \\(32,a1\\),sp.*
+.*$gdb_prompt $" { pass "mov2 tests" }
+ -re "$gdb_prompt $" { fail "mov2 tests" }
+ timeout { fail "(timeout) mov2 tests" }
+ }
+}
+
+proc mov_tests_3 { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/15i mov_tests_3\n"
+ gdb_expect {
+ -re "
+.*mov d1,\\(a2\\).*
+.*mov d1,\\(32,a2\\).*
+.*mov d1,\\(256,a2\\).*
+.*mov d1,\\(131071,a2\\).*
+.*mov d1,\\(32,sp\\).*
+.*mov d1,\\(32768,sp\\).*
+.*mov d1,\\(131071,sp\\).*
+.*mov d1,\\(d2,a2\\).*
+.*mov d1,\\(0x80.*\\).*
+.*mov d1,\\(0x1ffff.*\\).*
+.*mov a1,\\(a2\\).*
+.*mov a1,\\(32,a2\\).*
+.*mov a1,\\(256,a2\\).*
+.*mov a1,\\(131071,a2\\).*
+.*mov a1,\\(32,sp\\).*
+.*$gdb_prompt $" { pass "mov3 tests" }
+ -re "$gdb_prompt $" { fail "mov3 tests" }
+ timeout { fail "(timeout) mov3 tests" }
+ }
+}
+
+proc mov_tests_4 { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/12i mov_tests_4\n"
+ gdb_expect {
+ -re "
+.*mov a1,\\(32768,sp\\).*
+.*mov a1,\\(131071,sp\\).*
+.*mov a1,\\(d2,a2\\).*
+.*mov a1,\\(0x80.*\\).*
+.*mov a1,\\(0x1ffff.*\\).*
+.*mov sp,\\(32,a1\\).*
+.*mov 8,d1.*
+.*mov 256,d1.*
+.*mov 131071,d1.*
+.*mov 8,a1.*
+.*mov 256,a1.*
+.*mov 131071,a1.*
+.*$gdb_prompt $" { pass "mov4 tests" }
+ -re "$gdb_prompt $" { fail "mov4 tests" }
+ timeout { fail "(timeout) mov4 tests" }
+ }
+}
+
+proc movbu_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/20i movbu_tests\n"
+ gdb_expect {
+ -re "
+.*movbu \\(a2\\),d1.*
+.*movbu \\(8,a2\\),d1.*
+.*movbu \\(256,a2\\),d1.*
+.*movbu \\(131071,a2\\),d1.*
+.*movbu \\(8,sp\\),d1.*
+.*movbu \\(256,sp\\),d1.*
+.*movbu \\(131071,sp\\),d1.*
+.*movbu \\(d1,a1\\),d2.*
+.*movbu \\(0x8000.*\\),d1.*
+.*movbu \\(0x1ffff.*\\),d1.*
+.*movbu d1,\\(a2\\).*
+.*movbu d1,\\(32,a2\\).*
+.*movbu d1,\\(256,a2\\).*
+.*movbu d1,\\(131071,a2\\).*
+.*movbu d1,\\(32,sp\\).*
+.*movbu d1,\\(32768,sp\\).*
+.*movbu d1,\\(131071,sp\\).*
+.*movbu d1,\\(d2,a2\\).*
+.*movbu d1,\\(0x80.*\\).*
+.*movbu d1,\\(0x1ffff.*\\).*
+.*$gdb_prompt $" { pass "movbu tests" }
+ -re "$gdb_prompt $" { fail "movbu tests" }
+ timeout { fail "(timeout) movbu tests" }
+ }
+}
+
+proc movhu_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/20i movhu_tests\n"
+ gdb_expect {
+ -re "
+.*movhu \\(a2\\),d1.*
+.*movhu \\(8,a2\\),d1.*
+.*movhu \\(256,a2\\),d1.*
+.*movhu \\(131071,a2\\),d1.*
+.*movhu \\(8,sp\\),d1.*
+.*movhu \\(256,sp\\),d1.*
+.*movhu \\(131071,sp\\),d1.*
+.*movhu \\(d1,a1\\),d2.*
+.*movhu \\(0x8000.*\\),d1.*
+.*movhu \\(0x1ffff.*\\),d1.*
+.*movhu d1,\\(a2\\).*
+.*movhu d1,\\(32,a2\\).*
+.*movhu d1,\\(256,a2\\).*
+.*movhu d1,\\(131071,a2\\).*
+.*movhu d1,\\(32,sp\\).*
+.*movhu d1,\\(32768,sp\\).*
+.*movhu d1,\\(131071,sp\\).*
+.*movhu d1,\\(d2,a2\\).*
+.*movhu d1,\\(0x80.*\\).*
+.*movhu d1,\\(0x1ffff.*\\).*
+.*$gdb_prompt $" { pass "movhu tests" }
+ -re "$gdb_prompt $" { fail "movhu tests" }
+ timeout { fail "(timeout) movhu tests" }
+ }
+}
+
+proc movm_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/4i movm_tests\n"
+ gdb_expect {
+ -re "
+.*movm \\(sp\\),.a2,a3..*
+.*movm \\(sp\\),.d2,d3,a2,a3,other..*
+.*movm .a2,a3.,\\(sp\\).*
+.*movm .d2,d3,a2,a3,other.,\\(sp\\).*
+.*$gdb_prompt $" { pass "movm tests" }
+ -re "$gdb_prompt $" { fail "movm tests" }
+ timeout { fail "(timeout) movm tests" }
+ }
+}
+
+proc muldiv_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/4i muldiv_tests\n"
+ gdb_expect {
+ -re "
+.*mul d1,d2.*
+.*mulu d2,d3.*
+.*div d3,d3.*
+.*divu d3,d2.*
+.*$gdb_prompt $" { pass "muldiv tests" }
+ -re "$gdb_prompt $" { fail "muldiv tests" }
+ timeout { fail "(timeout) muldiv tests" }
+ }
+}
+
+proc other_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/19i other_tests\n"
+ gdb_expect {
+ -re "
+.*clr d2.*
+.*inc d1.*
+.*inc a2.*
+.*inc4 a3.*
+.*jmp \\(a2\\).*
+.*jmp 0x\[0-9a-f]+ <main>.*
+.*jmp 0x\[0-9a-f]+ <start>.*
+.*call 0x\[0-9a-f]+ <main>,.a2,a3.,9.*
+.*call 0x\[0-9a-f]+ <start>,.a2,a3.,32.*
+.*calls \\(a2\\).*
+.*calls 0x\[0-9a-f]+ <main>.*
+.*calls 0x\[0-9a-f]+ <start>.*
+.*ret .a2,a3.,7.*
+.*retf .a2,a3.,5.*
+.*rets.*
+.*rti.*
+.*trap.*
+.*nop.*
+.*rtm.*
+.*$gdb_prompt $" { pass "other tests" }
+ -re "$gdb_prompt $" { fail "other tests" }
+ timeout { fail "(timeout) other tests" }
+ }
+}
+
+proc shift_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/9i shift_tests\n"
+ gdb_expect {
+ -re "
+.*asr d1,d2.*
+.*asr 4,d2.*
+.*lsr d2,d3.*
+.*lsr 4,d3.*
+.*asl d3,d2.*
+.*asl 4,d2.*
+.*asl2 d2.*
+.*ror d1.*
+.*rol d2.*
+.*$gdb_prompt $" { pass "shift tests" }
+ -re "$gdb_prompt $" { fail "shift tests" }
+ timeout { fail "(timeout) shift tests" }
+ }
+}
+
+proc sub_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/7i sub_tests\n"
+ gdb_expect {
+ -re "
+.*sub d1,d2.*
+.*sub d2,a3.*
+.*sub a3,d3.*
+.*sub a3,a2.*
+.*sub 131071,d2.*
+.*sub 131071,a1.*
+.*subc d1,d2.*
+.*$gdb_prompt $" { pass "sub tests" }
+ -re "$gdb_prompt $" { fail "sub tests" }
+ timeout { fail "(timeout) sub tests" }
+ }
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+add_tests
+bcc_tests
+bit_tests
+cmp_tests
+extend_tests
+extended_tests
+logical_tests
+loop_tests
+mov_tests_1
+mov_tests_2
+mov_tests_3
+mov_tests_4
+movbu_tests
+movhu_tests
+movm_tests
+muldiv_tests
+other_tests
+shift_tests
+sub_tests
diff --git a/gdb/testsuite/gdb.disasm/mn10300.s b/gdb/testsuite/gdb.disasm/mn10300.s
new file mode 100644
index 00000000000..3ad6c95e6a1
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/mn10300.s
@@ -0,0 +1,300 @@
+ .text
+ .global _main
+ .global add_tests
+ .global bCC_tests
+ .global bit_tests
+ .global cmp_tests
+ .global extend_tests
+ .global extended_tests
+ .global logical_tests
+ .global loop_tests
+ .global mov_tests_1
+ .global mov_tests_2
+ .global mov_tests_3
+ .global mov_tests_4
+ .global movbu_tests
+ .global movhu_tests
+ .global movm_tests
+ .global muldiv_tests
+ .global other_tests
+ .global shift_tests
+ .global sub_tests
+
+_main:
+ nop
+
+add_tests:
+ add d1,d2
+ add d2,a3
+ add a3,a2
+ add a2,d1
+ add 16,d1
+ add 256,d2
+ add 131071,d3
+ add 16,a1
+ add 256,a2
+ add 131071,a3
+ add 16,sp
+ add 256,sp
+ add 131071,sp
+ addc d1,d2
+
+bCC_tests:
+ beq bCC_tests
+ bne bCC_tests
+ bgt bCC_tests
+ bge bCC_tests
+ ble bCC_tests
+ blt bCC_tests
+ bhi bCC_tests
+ bcc bCC_tests
+ bls bCC_tests
+ bcs bCC_tests
+ bvc bCC_tests
+ bvs bCC_tests
+ bnc bCC_tests
+ bns bCC_tests
+ bra bCC_tests
+
+bit_tests:
+ btst 64,d1
+ btst 8192,d2
+ btst 131071,d3
+ btst 64,(8,a1)
+ btst 64,(0x1ffff)
+ bset d1,(a2)
+ bset 64,(8,a1)
+ bset 64,(0x1ffff)
+ bclr d1,(a2)
+ bclr 64,(8,a1)
+ bclr 64,(0x1ffff)
+
+cmp_tests:
+ cmp d1,d2
+ cmp d2,a3
+ cmp a3,d3
+ cmp a3,a2
+ cmp 16,d3
+ cmp 256,d2
+ cmp 131071,d1
+ cmp 16,a3
+ cmp 256,a2
+ cmp 131071,a1
+
+
+extend_tests:
+ ext d1
+ extb d2
+ extbu d3
+ exth d2
+ exthu d1
+
+extended_tests:
+ putx d1
+ getx d2
+ mulq d1,d2
+ mulq 16,d2
+ mulq 256,d3
+ mulq 131071,d3
+ mulqu d1,d2
+ mulqu 16,d2
+ mulqu 256,d3
+ mulqu 131071,d3
+ sat16 d2,d3
+ sat24 d3,d2
+ bsch d1,d2
+
+logical_tests:
+ and d1,d2
+ and 127,d2
+ and 32767,d3
+ and 131071,d3
+ and 32767,psw
+ or d1,d2
+ or 127,d2
+ or 32767,d3
+ or 131071,d3
+ or 32767,psw
+ xor d1,d2
+ xor 32767,d3
+ xor 131071,d3
+ not d3
+
+loop_tests:
+ leq
+ lne
+ lgt
+ lge
+ lle
+ llt
+ lhi
+ lcc
+ lls
+ lcs
+ lra
+ setlb
+
+mov_tests_1:
+ mov d1,d2
+ mov d1,a2
+ mov a2,d1
+ mov a2,a1
+ mov sp,a2
+ mov a1,sp
+ mov d2,psw
+ mov mdr,d1
+ mov d2,mdr
+ mov (a2),d1
+ mov (8,a2),d1
+ mov (256,a2),d1
+ mov (131071,a2),d1
+ mov (8,sp),d1
+ mov (256,sp),d1
+ mov psw,d3
+
+mov_tests_2:
+ mov (131071,sp),d1
+ mov (d1,a1),d2
+ mov (32768),d1
+ mov (131071),d1
+ mov (a2),a1
+ mov (8,a2),a1
+ mov (256,a2),a1
+ mov (131071,a2),a1
+ mov (8,sp),a1
+ mov (256,sp),a1
+ mov (131071,sp),a1
+ mov (d1,a1),a2
+ mov (32768),a1
+ mov (131071),a1
+ mov (32,a1),sp
+
+mov_tests_3:
+ mov d1,(a2)
+ mov d1,(32,a2)
+ mov d1,(256,a2)
+ mov d1,(131071,a2)
+ mov d1,(32,sp)
+ mov d1,(32768,sp)
+ mov d1,(131071,sp)
+ mov d1,(d2,a2)
+ mov d1,(128)
+ mov d1,(131071)
+ mov a1,(a2)
+ mov a1,(32,a2)
+ mov a1,(256,a2)
+ mov a1,(131071,a2)
+ mov a1,(32,sp)
+
+mov_tests_4:
+ mov a1,(32768,sp)
+ mov a1,(131071,sp)
+ mov a1,(d2,a2)
+ mov a1,(128)
+ mov a1,(131071)
+ mov sp,(32,a1)
+ mov 8,d1
+ mov 256,d1
+ mov 131071,d1
+ mov 8,a1
+ mov 256,a1
+ mov 131071,a1
+
+movbu_tests:
+ movbu (a2),d1
+ movbu (8,a2),d1
+ movbu (256,a2),d1
+ movbu (131071,a2),d1
+ movbu (8,sp),d1
+ movbu (256,sp),d1
+ movbu (131071,sp),d1
+ movbu (d1,a1),d2
+ movbu (32768),d1
+ movbu (131071),d1
+ movbu d1,(a2)
+ movbu d1,(32,a2)
+ movbu d1,(256,a2)
+ movbu d1,(131071,a2)
+ movbu d1,(32,sp)
+ movbu d1,(32768,sp)
+ movbu d1,(131071,sp)
+ movbu d1,(d2,a2)
+ movbu d1,(128)
+ movbu d1,(131071)
+
+movhu_tests:
+ movhu (a2),d1
+ movhu (8,a2),d1
+ movhu (256,a2),d1
+ movhu (131071,a2),d1
+ movhu (8,sp),d1
+ movhu (256,sp),d1
+ movhu (131071,sp),d1
+ movhu (d1,a1),d2
+ movhu (32768),d1
+ movhu (131071),d1
+ movhu d1,(a2)
+ movhu d1,(32,a2)
+ movhu d1,(256,a2)
+ movhu d1,(131071,a2)
+ movhu d1,(32,sp)
+ movhu d1,(32768,sp)
+ movhu d1,(131071,sp)
+ movhu d1,(d2,a2)
+ movhu d1,(128)
+ movhu d1,(131071)
+
+movm_tests:
+ movm (sp),[a2,a3]
+ movm (sp),[d2,d3,a2,a3,other]
+ movm [a2,a3],(sp)
+ movm [d2,d3,a2,a3,other],(sp)
+
+
+muldiv_tests:
+ mul d1,d2
+ mulu d2,d3
+ div d3,d3
+ divu d3,d2
+
+other_tests:
+ clr d2
+ inc d1
+ inc a2
+ inc4 a3
+ jmp (a2)
+ jmp _main
+ jmp _start
+ call _main,[a2,a3],9
+ call _start,[a2,a3],32
+ calls (a2)
+ calls _main
+ calls _start
+ ret [a2,a3],7
+ retf [a2,a3],5
+ rets
+ rti
+ trap
+ nop
+ rtm
+
+shift_tests:
+ asr d1,d2
+ asr 4,d2
+ lsr d2,d3
+ lsr 4,d3
+ asl d3,d2
+ asl 4,d2
+ asl2 d2
+ ror d1
+ rol d2
+
+sub_tests:
+ sub d1,d2
+ sub d2,a3
+ sub a3,d3
+ sub a3,a2
+ sub 131071,d2
+ sub 131071,a1
+ subc d1,d2
+
diff --git a/gdb/testsuite/gdb.disasm/sh3.exp b/gdb/testsuite/gdb.disasm/sh3.exp
new file mode 100644
index 00000000000..6c82f9151fb
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/sh3.exp
@@ -0,0 +1,123 @@
+# Copyright (C) 1992, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Jeff Law. (law@cs.utah.edu)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if ![istarget "sh3*-*-*"] {
+ verbose "Tests ignored for all but sh3 based targets."
+ return
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "sh3"
+set srcfile ${srcdir}/${subdir}/${testfile}.s
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcfile}" "${binfile}" executable ""] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+proc all_fp_move_and_load_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/9i fp_move_and_load_tests\n"
+ gdb_expect {
+ -re "
+.*fmov.s\t@r0,fr0.*
+.*fmov.s\tfr0,@r0.*
+.*fmov.s\t@r0\\+,fr0.*
+.*fmov.s\tfr0,@-r0.*
+.*fmov.s\t@\\(r0,r0\\),fr0.*
+.*fmov.s\tfr0,@\\(r0,r0\\).*
+.*fmov\tfr0,fr1.*
+.*fldi0\tfr0.*
+.*fldi1\tfr0.*
+.*$gdb_prompt $" { pass "fp_move_and_load_tests" }
+ -re "$gdb_prompt $" { fail "fp_move_and_load_tests" }
+ timeout { fail "(timeout) fp_move_and_load_tests" }
+ }
+}
+
+proc all_fp_arithmetic_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/13i fp_arithmetic_tests\n"
+ gdb_expect {
+ -re "
+.*fadd\tfr0,fr1.*
+.*fsub\tfr0,fr1.*
+.*fmul\tfr0,fr1.*
+.*fdiv\tfr0,fr1.*
+.*fmac\tfr0,fr0,fr1.*
+.*fcmp/eq\tfr0,fr1.*
+.*fcmp/gt\tfr0,fr1.*
+.*ftst/nan\tfr0.*
+.*fneg\tfr0.*
+.*fabs\tfr0.*
+.*fsqrt\tfr0.*
+.*float\tfpul,fr0.*
+.*ftrc\tfr0,fpul.*
+.*$gdb_prompt $" { pass "fp_arithmetic_tests" }
+ -re "$gdb_prompt $" { fail "fp_arithmetic_tests" }
+ timeout { fail "(timeout) fp_arithmetic_tests" }
+ }
+}
+
+proc all_fp_misc_tests { } {
+ global gdb_prompt
+ global hex
+ global decimal
+
+ send_gdb "x/10i fp_misc_tests\n"
+ gdb_expect {
+ -re "
+.*fsts\tfpul,fr0.*
+.*flds\tfr0,fpul.*
+.*lds\tr3,fpul.*
+.*lds\\.l\t@r3\\+,fpul.*
+.*lds\tr3,fpscr.*
+.*lds\\.l\t@r3\\+,fpscr.*
+.*sts\tfpul,r3.*
+.*sts\\.l\tfpul,@-r3.*
+.*sts\tfpscr,r3.*
+.*sts\\.l\tfpscr,@-r3.*
+.*$gdb_prompt $" { pass "fp_misc_tests" }
+ -re "$gdb_prompt $" { fail "fp_misc_tests" }
+ timeout { fail "(timeout) fp_misc_tests" }
+ }
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+all_fp_move_and_load_tests
+all_fp_arithmetic_tests
+all_fp_misc_tests
+
diff --git a/gdb/testsuite/gdb.disasm/sh3.s b/gdb/testsuite/gdb.disasm/sh3.s
new file mode 100644
index 00000000000..8bab256901c
--- /dev/null
+++ b/gdb/testsuite/gdb.disasm/sh3.s
@@ -0,0 +1,54 @@
+ .file "test.c"
+ .data
+
+! Hitachi SH cc1 (cygnus-2.7.1-950728) arguments: -O -fpeephole
+! -ffunction-cse -freg-struct-return -fdelayed-branch -fcommon -fgnu-linker
+
+gcc2_compiled.:
+___gnu_compiled_c:
+ .text
+ .align 2
+ .global _fp_move_and_load_tests
+ .global _fp_arithmetic_tests
+ .global _fp_misc_tests
+ .global _main
+
+_main:
+_fp_move_and_load_tests:
+ fmov.s @r0,fr0
+ fmov.s fr0,@r0
+ fmov.s @r0+,fr0
+ fmov.s fr0,@-r0
+ fmov.s @(r0,r0),fr0
+ fmov.s fr0,@(r0,r0)
+ fmov fr0,fr1
+ fldi0 fr0
+ fldi1 fr0
+
+_fp_arithmetic_tests:
+ fadd fr0,fr1
+ fsub fr0,fr1
+ fmul fr0,fr1
+ fdiv fr0,fr1
+ fmac fr0,fr0,fr1
+ fcmp/eq fr0,fr1
+ fcmp/gt fr0,fr1
+ ftst/nan fr0
+ fneg fr0
+ fabs fr0
+ fsqrt fr0
+ float fpul,fr0
+ ftrc fr0,fpul
+
+_fp_misc_tests:
+ fsts fpul,fr0
+ flds fr0,fpul
+ lds r3,fpul
+ lds.l @r3+,fpul
+ lds r3,fpscr
+ lds.l @r3+,fpscr
+ sts fpul,r3
+ sts.l fpul,@-r3
+ sts fpscr,r3
+ sts.l fpscr,@-r3
+
diff --git a/gdb/testsuite/gdb.fortran/exprs.exp b/gdb/testsuite/gdb.fortran/exprs.exp
new file mode 100644
index 00000000000..cccc82a3f5d
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/exprs.exp
@@ -0,0 +1,273 @@
+# Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was adapted from Chill tests by Stan Shebs (shebs@cygnus.com).
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# Set the current language to fortran. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_fortran {} {
+ global gdb_prompt
+
+ if [gdb_test "set language fortran" ""] {
+ return 0;
+ }
+
+ if ![gdb_test "show language" ".* source language is \"fortran\".*"] {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+proc test_integer_literals_accepted {} {
+ global gdb_prompt
+
+ # Test various decimal values.
+
+ gdb_test "p 123" " = 123"
+ gdb_test "p -123" " = -123"
+}
+
+proc test_character_literals_accepted {} {
+ global gdb_prompt
+
+ # Test various character values.
+
+ gdb_test "p 'a'" " = 'a'"
+}
+
+proc test_integer_literals_rejected {} {
+ global gdb_prompt
+
+ test_print_reject "p _"
+}
+
+proc test_logical_literals_accepted {} {
+ global gdb_prompt
+
+ # Test the only possible values for a logical, TRUE and FALSE.
+
+ gdb_test "p .TRUE." " = .TRUE."
+ gdb_test "p .FALSE." " = .FALSE."
+}
+
+proc test_float_literals_accepted {} {
+ global gdb_prompt
+
+ # Test various floating point formats
+
+ gdb_test "p .44 .LT. .45" " = .TRUE."
+ gdb_test "p .44 .GT. .45" " = .FALSE."
+ gdb_test "p 0.44 .LT. 0.45" " = .TRUE."
+ gdb_test "p 0.44 .GT. 0.45" " = .FALSE."
+ gdb_test "p 44. .LT. 45." " = .TRUE."
+ gdb_test "p 44. .GT. 45." " = .FALSE."
+ gdb_test "p 44.0 .LT. 45.0" " = .TRUE."
+ gdb_test "p 44.0 .GT. 45.0" " = .FALSE."
+ gdb_test "p 10D20 .LT. 10D21" " = .TRUE."
+ gdb_test "p 10D20 .GT. 10D21" " = .FALSE."
+ gdb_test "p 10d20 .LT. 10d21" " = .TRUE."
+ gdb_test "p 10d20 .GT. 10d21" " = .FALSE."
+ gdb_test "p 10E20 .LT. 10E21" " = .TRUE."
+ gdb_test "p 10E20 .GT. 10E21" " = .FALSE."
+ gdb_test "p 10e20 .LT. 10e21" " = .TRUE."
+ gdb_test "p 10e20 .GT. 10e21" " = .FALSE."
+ gdb_test "p 10.D20 .LT. 10.D21" " = .TRUE."
+ gdb_test "p 10.D20 .GT. 10.D21" " = .FALSE."
+ gdb_test "p 10.d20 .LT. 10.d21" " = .TRUE."
+ gdb_test "p 10.d20 .GT. 10.d21" " = .FALSE."
+ gdb_test "p 10.E20 .LT. 10.E21" " = .TRUE."
+ gdb_test "p 10.E20 .GT. 10.E21" " = .FALSE."
+ gdb_test "p 10.e20 .LT. 10.e21" " = .TRUE."
+ gdb_test "p 10.e20 .GT. 10.e21" " = .FALSE."
+ gdb_test "p 10.0D20 .LT. 10.0D21" " = .TRUE."
+ gdb_test "p 10.0D20 .GT. 10.0D21" " = .FALSE."
+ gdb_test "p 10.0d20 .LT. 10.0d21" " = .TRUE."
+ gdb_test "p 10.0d20 .GT. 10.0d21" " = .FALSE."
+ gdb_test "p 10.0E20 .LT. 10.0E21" " = .TRUE."
+ gdb_test "p 10.0E20 .GT. 10.0E21" " = .FALSE."
+ gdb_test "p 10.0e20 .LT. 10.0e21" " = .TRUE."
+ gdb_test "p 10.0e20 .GT. 10.0e21" " = .FALSE."
+ gdb_test "p 10.0D+20 .LT. 10.0D+21" " = .TRUE."
+ gdb_test "p 10.0D+20 .GT. 10.0D+21" " = .FALSE."
+ gdb_test "p 10.0d+20 .LT. 10.0d+21" " = .TRUE."
+ gdb_test "p 10.0d+20 .GT. 10.0d+21" " = .FALSE."
+ gdb_test "p 10.0E+20 .LT. 10.0E+21" " = .TRUE."
+ gdb_test "p 10.0E+20 .GT. 10.0E+21" " = .FALSE."
+ gdb_test "p 10.0e+20 .LT. 10.0e+21" " = .TRUE."
+ gdb_test "p 10.0e+20 .GT. 10.0e+21" " = .FALSE."
+ gdb_test "p 10.0D-11 .LT. 10.0D-10" " = .TRUE."
+ gdb_test "p 10.0D-11 .GT. 10.0D-10" " = .FALSE."
+ gdb_test "p 10.0d-11 .LT. 10.0d-10" " = .TRUE."
+ gdb_test "p 10.0d-11 .GT. 10.0d-10" " = .FALSE."
+ gdb_test "p 10.0E-11 .LT. 10.0E-10" " = .TRUE."
+ gdb_test "p 10.0E-11 .GT. 10.0E-10" " = .FALSE."
+ gdb_test "p 10.0e-11 .LT. 10.0e-10" " = .TRUE."
+ gdb_test "p 10.0e-11 .GT. 10.0e-10" " = .FALSE."
+}
+
+proc test_convenience_variables {} {
+ global gdb_prompt
+
+ gdb_test "set \$foo = 101" " = 101\[\r\n\]*" \
+ "Set a new convenience variable"
+
+ gdb_test "print \$foo" " = 101" \
+ "Print contents of new convenience variable"
+
+ gdb_test "set \$foo = 301" " = 301\[\r\n\]*" \
+ "Set convenience variable to a new value"
+
+ gdb_test "print \$foo" " = 301" \
+ "Print new contents of convenience variable"
+
+ gdb_test "set \$_ = 11" " = 11\[\r\n\]*" \
+ "Set convenience variable \$_"
+
+ gdb_test "print \$_" " = 11" \
+ "Print contents of convenience variable \$_"
+
+ gdb_test "print \$foo + 10" " = 311" \
+ "Use convenience variable in arithmetic expression"
+
+ gdb_test "print (\$foo = 32) + 4" " = 36" \
+ "Use convenience variable assignment in arithmetic expression"
+
+ gdb_test "print \$bar" " = VOID" \
+ "Print contents of uninitialized convenience variable"
+}
+
+proc test_value_history {} {
+ global gdb_prompt
+
+ gdb_test "print 101" "\\\$1 = 101" \
+ "Set value-history\[1\] using \$1"
+
+ gdb_test "print 102" "\\\$2 = 102" \
+ "Set value-history\[2\] using \$2"
+
+ gdb_test "print 103" "\\\$3 = 103" \
+ "Set value-history\[3\] using \$3"
+
+ gdb_test "print \$\$" "\\\$4 = 102" \
+ "Print value-history\[MAX-1\] using inplicit index \$\$"
+
+ gdb_test "print \$\$" "\\\$5 = 103" \
+ "Print value-history\[MAX-1\] again using implicit index \$\$"
+
+ gdb_test "print \$" "\\\$6 = 103" \
+ "Print value-history\[MAX\] using implicit index \$"
+
+ gdb_test "print \$\$2" "\\\$7 = 102" \
+ "Print value-history\[MAX-2\] using explicit index \$\$2"
+
+ gdb_test "print \$0" "\\\$8 = 102" \
+ "Print value-history\[MAX\] using explicit index \$0"
+
+ gdb_test "print 108" "\\\$9 = 108" ""
+
+ gdb_test "print \$\$0" "\\\$10 = 108" \
+ "Print value-history\[MAX\] using explicit index \$\$0"
+
+ gdb_test "print \$1" "\\\$11 = 101" \
+ "Print value-history\[1\] using explicit index \$1"
+
+ gdb_test "print \$2" "\\\$12 = 102" \
+ "Print value-history\[2\] using explicit index \$2"
+
+ gdb_test "print \$3" "\\\$13 = 103" \
+ "Print value-history\[3\] using explicit index \$3"
+
+ gdb_test "print \$-3" "\\\$14 = 100" \
+ "Print (value-history\[MAX\] - 3) using implicit index \$"
+
+ gdb_test "print \$1 + 3" "\\\$15 = 104" \
+ "Use value-history element in arithmetic expression"
+}
+
+proc test_arithmetic_expressions {} {
+ global gdb_prompt
+
+ # Test unary minus with various operands
+
+# gdb_test "p -(TRUE)" " = -1" "unary minus applied to bool"
+# gdb_test "p -('a')" " = xxx" "unary minus applied to char"
+ gdb_test "p -(1)" " = -1" "unary minus applied to int"
+ gdb_test "p -(1.0)" " = -1" "unary minus applied to real"
+
+ # Test addition with various operands
+
+ gdb_test "p .TRUE. + 1" " = 2" "bool plus int"
+ gdb_test "p 1 + 1" " = 2" "int plus int"
+ gdb_test "p 1.0 + 1" " = 2" "real plus int"
+ gdb_test "p 1.0 + 2.0" " = 3" "real plus real"
+
+ # Test subtraction with various operands
+
+ gdb_test "p .TRUE. - 1" " = 0" "bool minus int"
+ gdb_test "p 3 - 1" " = 2" "int minus int"
+ gdb_test "p 3.0 - 1" " = 2" "real minus int"
+ gdb_test "p 5.0 - 2.0" " = 3" "real minus real"
+
+ # Test multiplication with various operands
+
+ gdb_test "p .TRUE. * 1" " = 1" "bool times int"
+ gdb_test "p 2 * 3" " = 6" "int times int"
+ gdb_test "p 2.0 * 3" " = 6" "real times int"
+ gdb_test "p 2.0 * 3.0" " = 6" "real times real"
+
+ # Test division with various operands
+
+ gdb_test "p .TRUE. / 1" " = 1" "bool divided by int"
+ gdb_test "p 6 / 3" " = 2" "int divided by int"
+ gdb_test "p 6.0 / 3" " = 2" "real divided by int"
+ gdb_test "p 6.0 / 3.0" " = 2" "real divided by real"
+
+ # Test modulo with various operands
+
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ""
+
+if [set_lang_fortran] then {
+ test_value_history
+ test_convenience_variables
+ test_integer_literals_accepted
+ test_integer_literals_rejected
+ test_logical_literals_accepted
+ test_character_literals_accepted
+ test_float_literals_accepted
+ test_arithmetic_expressions
+} else {
+ warning "$test_name tests suppressed." 0
+}
diff --git a/gdb/testsuite/gdb.fortran/types.exp b/gdb/testsuite/gdb.fortran/types.exp
new file mode 100644
index 00000000000..13bec5d3be7
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/types.exp
@@ -0,0 +1,114 @@
+# Copyright 1994, 1995, 1997, 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was adapted from Chill tests by Stan Shebs (shebs@cygnus.com).
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# Set the current language to fortran. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_fortran {} {
+ global gdb_prompt
+
+ if [gdb_test "set language fortran" ""] {
+ return 0;
+ }
+
+ if ![gdb_test "show language" ".* source language is \"fortran\".*"] {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+proc test_integer_literal_types_accepted {} {
+ global gdb_prompt
+
+ # Test various decimal values.
+ # Should be integer*4 probably.
+ gdb_test "pt 123" "type = int"
+}
+
+proc test_character_literal_types_accepted {} {
+ global gdb_prompt
+
+ # Test various character values.
+
+ gdb_test "pt 'a'" "type = character\\*1"
+}
+
+proc test_integer_literal_types_rejected {} {
+ global gdb_prompt
+
+ test_print_reject "pt _"
+}
+
+proc test_logical_literal_types_accepted {} {
+ global gdb_prompt
+
+ # Test the only possible values for a logical, TRUE and FALSE.
+
+ gdb_test "pt .TRUE." "type = logical\\*2"
+ gdb_test "pt .FALSE." "type = logical\\*2"
+}
+
+proc test_float_literal_types_accepted {} {
+ global gdb_prompt
+
+ # Test various floating point formats
+
+ # this used to guess whether to look for "real*4" or
+ # "real*8" based on a target config variable, but noone
+ # maintained it properly.
+
+ gdb_test "pt .44" "type = real\\*\[0-9\]+"
+ gdb_test "pt 44.0" "type = real\\*\[0-9\]+"
+ gdb_test "pt 10D20" "type = real\\*\[0-9\]+"
+ gdb_test "pt 10D20" "type = real\\*\[0-9\]+"
+ gdb_test "pt 10d20" "type = real\\*\[0-9\]+"
+ gdb_test "pt 10d20" "type = real\\*\[0-9\]+"
+ gdb_test "pt 10E20" "type = real\\*\[0-9\]+"
+ gdb_test "pt 10E20" "type = real\\*\[0-9\]+"
+ gdb_test "pt 10e20" "type = real\\*\[0-9\]+"
+ gdb_test "pt 10e20" "type = real\\*\[0-9\]+"
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ""
+
+if [set_lang_fortran] then {
+ test_integer_literal_types_accepted
+ test_integer_literal_types_rejected
+ test_logical_literal_types_accepted
+ test_character_literal_types_accepted
+ test_float_literal_types_accepted
+} else {
+ warning "$test_name tests suppressed." 0
+}
diff --git a/gdb/testsuite/gdb.gdb/xfullpath.exp b/gdb/testsuite/gdb.gdb/xfullpath.exp
new file mode 100644
index 00000000000..e4a6e2a0419
--- /dev/null
+++ b/gdb/testsuite/gdb.gdb/xfullpath.exp
@@ -0,0 +1,198 @@
+# Copyright 2002
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Joel Brobecker. (brobecker@gnat.com), derived
+# from selftest.exp, written by Rob Savoye.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# are we on a target board
+if [is_remote target] {
+ return
+}
+
+if [istarget "m68k*-*-hpux*"] then {
+ # The top-level makefile passes CFLAGS= (no -g) for hp300. This probably
+ # should be fixed (it is only needed for gcc bootstrapping, not gdb),
+ # but until then.....
+ setup_xfail "*-*-*"
+ fail "cannot test self if compiled without debug info"
+ return -1
+}
+
+proc setup_test { executable } {
+ global gdb_prompt
+ global timeout
+
+ # load yourself into the debugger
+ # This can take a relatively long time, particularly for testing where
+ # the executable is being accessed over a network, or where gdb does not
+ # support partial symbols for a particular target and has to load the
+ # entire symbol table. Set the timeout to 10 minutes, which should be
+ # adequate for most environments (it *has* timed out with 5 min on a
+ # SPARCstation SLC under moderate load, so this isn't unreasonable).
+ # After gdb is started, set the timeout to 30 seconds for the duration
+ # of this test, and then back to the original value.
+
+ set oldtimeout $timeout
+ set timeout 600
+ verbose "Timeout is now $timeout seconds" 2
+ if {[gdb_load $executable] <0} then {
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+ return -1
+ }
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+
+ # Set a breakpoint at main
+ gdb_test "break captured_main" \
+ "Breakpoint.*at.* file.*, line.*" \
+ "breakpoint in captured_main"
+
+ # run yourself
+ # It may take a very long time for the inferior gdb to start (lynx),
+ # so we bump it back up for the duration of this command.
+ set timeout 600
+
+ set description "run until breakpoint at captured_main"
+ send_gdb "run -nw\n"
+ gdb_expect {
+ -re "Starting program.*Breakpoint \[0-9\]+,.*captured_main .data.* at .*main.c:.*$gdb_prompt $" {
+ pass "$description"
+ }
+ -re "Starting program.*Breakpoint \[0-9\]+,.*captured_main .data.*$gdb_prompt $" {
+ xfail "$description (line numbers scrambled?)"
+ }
+ -re "vfork: No more processes.*$gdb_prompt $" {
+ fail "$description (out of virtual memory)"
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+ return -1
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$description"
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+ return -1
+ }
+ timeout {
+ fail "$description (timeout)"
+ }
+ }
+
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+
+ return 0
+}
+
+proc test_with_self { executable } {
+
+ set setup_result [setup_test $executable]
+ if {$setup_result <0} then {
+ return -1
+ }
+
+ # A file which contains a directory prefix
+ gdb_test "print xfullpath (\"./xfullpath.exp\")" \
+ ".\[0-9\]+ =.*\".*/xfullpath.exp\"" \
+ "A filename with ./ as the directory prefix"
+
+ # A file which contains a directory prefix
+ gdb_test "print xfullpath (\"../../defs.h\")" \
+ ".\[0-9\]+ =.*\".*/defs.h\"" \
+ "A filename with ../ in the directory prefix"
+
+ # A one-character filename
+ gdb_test "print xfullpath (\"./a\")" \
+ ".\[0-9\]+ =.*\".*/a\"" \
+ "A one-char filename in the current directory"
+
+ # A file in the root directory
+ gdb_test "print xfullpath (\"/root_file_which_should_exist\")" \
+ ".\[0-9\]+ =.*\"/root_file_which_should_exist\"" \
+ "A filename in the root directory"
+
+ # A file which does not have a directory prefix
+ gdb_test "print xfullpath (\"xfullpath.exp\")" \
+ ".\[0-9\]+ =.*\"xfullpath.exp\"" \
+ "A filename without any directory prefix"
+
+ # A one-char filename without any directory prefix
+ gdb_test "print xfullpath (\"a\")" \
+ ".\[0-9\]+ =.*\"a\"" \
+ "A one-char filename without any directory prefix"
+
+ # An empty filename
+ gdb_test "print xfullpath (\"\")" \
+ ".\[0-9\]+ =.*\"\"" \
+ "An empty filename"
+
+ return 0
+}
+
+# Find a pathname to a file that we would execute if the shell was asked
+# to run $arg using the current PATH.
+
+proc find_gdb { arg } {
+
+ # If the arg directly specifies an existing executable file, then
+ # simply use it.
+
+ if [file executable $arg] then {
+ return $arg
+ }
+
+ set result [which $arg]
+ if [string match "/" [ string range $result 0 0 ]] then {
+ return $result
+ }
+
+ # If everything fails, just return the unqualified pathname as default
+ # and hope for best.
+
+ return $arg
+}
+
+# Run the test with self.
+# Copy the file executable file in case this OS doesn't like to edit its own
+# text space.
+
+set GDB_FULLPATH [find_gdb $GDB]
+
+# Remove any old copy lying around.
+remote_file host delete x$tool
+
+gdb_start
+set file [remote_download host $GDB_FULLPATH x$tool]
+set result [test_with_self $file];
+gdb_exit;
+catch "remote_file host delete $file";
+
+if {$result <0} then {
+ warning "Couldn't test self"
+ return -1
+}
diff --git a/gdb/testsuite/gdb.hp/Makefile.in b/gdb/testsuite/gdb.hp/Makefile.in
new file mode 100644
index 00000000000..2a1a9df175b
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/Makefile.in
@@ -0,0 +1,44 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+SUBDIRS = @subdirs@
+
+all:
+ @echo "Nothing to be done for all..."
+
+info:
+install-info:
+dvi:
+install:
+uninstall: force
+installcheck:
+check:
+
+clean mostlyclean:
+ -rm -f *~ core *.o
+ if [ x"${SUBDIRS}" != x ] ; then \
+ for dir in ${SUBDIRS}; \
+ do \
+ echo "$$dir:"; \
+ if [ -d $$dir ]; then \
+ (cd $$dir; $(MAKE) clean); \
+ fi; \
+ done ; \
+ else true; fi
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
+ -rm -f *-init.exp
+ -rm -fr *.log summary detail *.plog *.sum *.psum site.*
+ if [ x"${SUBDIRS}" != x ] ; then \
+ for dir in ${SUBDIRS}; \
+ do \
+ echo "$$dir:"; \
+ if [ -d $$dir ]; then \
+ (cd $$dir; $(MAKE) distclean); \
+ fi; \
+ done ; \
+ else true; fi
+
+Makefile: $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.hp/configure b/gdb/testsuite/gdb.hp/configure
new file mode 100755
index 00000000000..e01b9625989
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/configure
@@ -0,0 +1,1008 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=gdb.aCC
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:575: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:596: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:614: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+# Directories to use in all configurations.
+configdirs="gdb.aCC \
+ gdb.base-hp \
+ gdb.compat \
+ gdb.defects \
+ gdb.objdbg \
+ gdb.threads-hp"
+
+# configure the subdirectories too
+subdirs="$configdirs"
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@subdirs@%$subdirs%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+if test "$no_recursion" != yes; then
+
+ # Remove --cache-file and --srcdir arguments so they do not pile up.
+ ac_sub_configure_args=
+ ac_prev=
+ for ac_arg in $ac_configure_args; do
+ if test -n "$ac_prev"; then
+ ac_prev=
+ continue
+ fi
+ case "$ac_arg" in
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ ;;
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ ;;
+ *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;;
+ esac
+ done
+
+ for ac_config_dir in $configdirs; do
+
+ # Do not complain, so a configure script can configure whichever
+ # parts of a large source tree are present.
+ if test ! -d $srcdir/$ac_config_dir; then
+ continue
+ fi
+
+ echo configuring in $ac_config_dir
+
+ case "$srcdir" in
+ .) ;;
+ *)
+ if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :;
+ else
+ { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; }
+ fi
+ ;;
+ esac
+
+ ac_popdir=`pwd`
+ cd $ac_config_dir
+
+ # A "../" for each directory in /$ac_config_dir.
+ ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
+
+ case "$srcdir" in
+ .) # No --srcdir option. We are building in place.
+ ac_sub_srcdir=$srcdir ;;
+ /*) # Absolute path.
+ ac_sub_srcdir=$srcdir/$ac_config_dir ;;
+ *) # Relative path.
+ ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;;
+ esac
+
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_sub_srcdir/configure; then
+ ac_sub_configure=$ac_sub_srcdir/configure
+ elif test -f $ac_sub_srcdir/configure.in; then
+ ac_sub_configure=$ac_configure
+ else
+ echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2
+ ac_sub_configure=
+ fi
+
+ # The recursion is here.
+ if test -n "$ac_sub_configure"; then
+
+ # Make the cache file name correct relative to the subdirectory.
+ case "$cache_file" in
+ /*) ac_sub_cache_file=$cache_file ;;
+ *) # Relative path.
+ ac_sub_cache_file="$ac_dots$cache_file" ;;
+ esac
+
+ echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir"
+ # The eval makes quoting arguments work.
+ if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir
+ then :
+ else
+ { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; }
+ fi
+ fi
+
+ cd $ac_popdir
+ done
+fi
+
diff --git a/gdb/testsuite/gdb.hp/configure.in b/gdb/testsuite/gdb.hp/configure.in
new file mode 100644
index 00000000000..dd84c343bab
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/configure.in
@@ -0,0 +1,17 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(gdb.aCC)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
+AC_CANONICAL_SYSTEM
+
+AC_CONFIG_SUBDIRS(gdb.aCC gdb.base-hp gdb.compat gdb.defects gdb.objdbg gdb.threads-hp)
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.hp/gdb.aCC/Makefile.in b/gdb/testsuite/gdb.hp/gdb.aCC/Makefile.in
new file mode 100644
index 00000000000..1295c1e5585
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.aCC/Makefile.in
@@ -0,0 +1,27 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES = exception namespace optimize run
+
+all:
+ @echo "Nothing to be done for all..."
+
+info:
+install-info:
+dvi:
+install:
+uninstall: force
+installcheck:
+check:
+
+clean mostlyclean:
+ -rm -f *~ *.o *.ci
+ -rm -f core $(EXECUTABLES)
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
+ -rm -f *-init.exp
+ -rm -fr *.log summary detail *.plog *.sum *.psum site.*
+
+Makefile : $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.hp/gdb.aCC/configure b/gdb/testsuite/gdb.hp/gdb.aCC/configure
new file mode 100755
index 00000000000..f3ffcd514db
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.aCC/configure
@@ -0,0 +1,899 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=exception.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../../.. $srcdir/`cd $srcdir;pwd`/../../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../../.. $srcdir/`cd $srcdir;pwd`/../../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:573: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:594: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:612: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.hp/gdb.aCC/configure.in b/gdb/testsuite/gdb.hp/gdb.aCC/configure.in
new file mode 100644
index 00000000000..c5fb71f0e02
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.aCC/configure.in
@@ -0,0 +1,15 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(exception.exp)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.hp/gdb.aCC/exception.cc b/gdb/testsuite/gdb.hp/gdb.aCC/exception.cc
new file mode 100644
index 00000000000..27459329a8b
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.aCC/exception.cc
@@ -0,0 +1,48 @@
+// Test file for exception handling support.
+
+#include <iostream.h>
+
+int foo (int i)
+{
+ if (i < 32)
+ throw (int) 13;
+ else
+ return i * 2;
+}
+
+extern "C" int bar (int k, unsigned long eharg, int flag);
+
+int bar (int k, unsigned long eharg, int flag)
+{
+ cout << "k is " << k << " eharg is " << eharg << " flag is " << flag << endl;
+ return 1;
+}
+
+int main()
+{
+ int j;
+
+ try {
+ j = foo (20);
+ }
+ catch (int x) {
+ cout << "Got an except " << x << endl;
+ }
+
+ try {
+ try {
+ j = foo (20);
+ }
+ catch (int x) {
+ cout << "Got an except " << x << endl;
+ throw;
+ }
+ }
+ catch (int y) {
+ cout << "Got an except (rethrown) " << y << endl;
+ }
+
+ // Not caught
+ foo (20);
+
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.aCC/exception.exp b/gdb/testsuite/gdb.hp/gdb.aCC/exception.exp
new file mode 100644
index 00000000000..a0914ae5ba4
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.aCC/exception.exp
@@ -0,0 +1,439 @@
+# Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# tests for exception-handling support
+# Written by Satish Pai <pai@apollo.hp.com> 1997-07-23
+
+# This file is part of the gdb testsuite
+
+# Note: These tests are geared to the HP aCC compiler,
+# which has an idiosyncratic way of emitting debug info
+# for exceptions -- it uses a callback mechanism, which
+# is different from the way g++ records exception info
+# for debugging
+
+# The tests are in two parts; the first part deals with
+# statically linked (archive-bound) executables, and the
+# second part repeats those tests with dynamically linked
+# (shared bound) executables. (In the latter case we use
+# a different mechanism to get the address of the notification
+# hook in the C++ support library.) The tests themselves are
+# the same in both parts.
+#
+# IMPORTANT:
+# ---------
+# IF YOU CHANGE A TEST IN ONE PART MAKE SURE YOU CHANGE IT
+# --------------------------------------------------------
+# IN THE OTHER PART TOO!
+# ----------------------
+
+
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+if { [skip_hp_tests] } then { continue }
+
+#
+# test running programs
+#
+
+# Part I : Archive-bound executables
+# ----------------------------------
+
+set testfile "exception"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile} "c++"] {
+ return -1;
+}
+
+
+if { $gcc_compiled } then { continue }
+
+set cmdline "$CXX_FOR_TARGET ${srcdir}/${subdir}/${srcfile} +A -Wl,-a,archive -g -o ${binfile}"
+
+remote_exec build $cmdline
+
+# Start with a fresh gdb
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+# Set a catch catchpoint
+
+send_gdb "catch catch\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\]* \\(catch\\)\r\n$gdb_prompt $" {
+ pass "catch catch (static executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "catch catch (static executable)" }
+ timeout { fail "(timeout) catch catch (static executable)" }
+}
+
+# Set a throw catchpoint
+
+send_gdb "catch throw\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\]* \\(throw\\)\r\n$gdb_prompt $" {
+ pass "catch throw (static executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "catch throw (static executable)" }
+ timeout { fail "(timeout) catch throw (static executable)" }
+}
+
+# The catchpoints should be listed in the list of breakpoints.
+
+send_gdb "info break\n"
+gdb_expect {
+ -re ".*\[0-9\]*\[ \]*catch catch\[ \]*keep y\[ \]*exception catch\[ \]*\r\n\[0-9\]*\[ \]*catch throw\[ \]*keep y\[ \]*exception throw\[ \]*\r\n$gdb_prompt $" {
+ pass "info break with catchpoints (static executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "info break (static executable)" }
+ timeout { fail "(timeout) info break (static executable)" }
+}
+
+# Info catch currently does not work with HP aCC. No easy way to
+# list the active handlers on the stack.
+
+send_gdb "info catch\n"
+gdb_expect {
+ -re "Info catch not supported with this target/compiler combination.\r\n$gdb_prompt $" {
+ pass "info catch (static executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "info catch (static executable)" }
+ timeout { fail "(timeout) info catch (static executable)" }
+}
+
+# Get the first exception thrown
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing.*Catchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:28\r\n.*$gdb_prompt $" {
+ pass "caught a throw (static executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "didn't catch a throw (static executable)" }
+ timeout { fail "(timeout) after continue -- didn't catch a throw? (static executable)" }
+}
+
+send_gdb "backtrace\n"
+gdb_expect {
+ -re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=__EH_NOTIFY_THROW.*\r\n#2\[ \]*$hex in __eh_notify_throw.*\r\n#3\[ \]*$hex in foo \\(i=20\\) at .*exception\\.cc:8\r\n#4\[ \]*$hex in main.* at .*exception\\.cc:26\r\n$gdb_prompt $" {
+ pass "backtrace after throw (static executable)"
+ }
+ -re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=\[0-9\].*\r\n#2\[ \]*$hex in __eh_notify_throw.*\r\n#3\[ \]*$hex in foo \\(i=20\\) at .*exception\\.cc:8\r\n#4\[ \]*$hex in main.* at .*exception\\.cc:26\r\n$gdb_prompt $" {
+ pass "backtrace after throw (static executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "backtrace after throw (static executable)" }
+ timeout { fail "(timeout) backtrace after throw (static executable)" }
+}
+
+# Now intercept it when it is caught.
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing.*Catchpoint \[0-9\]* \\(exception caught\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:28\r\n.*$gdb_prompt $" {
+ pass "caught a catch (static executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "didn't catch a catch (static executable)" }
+ timeout { fail "(timeout) after continue -- didn't catch a catch? (static executable)" }
+}
+
+send_gdb "backtrace\n"
+gdb_expect {
+ -re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=__EH_NOTIFY_CATCH.*\r\n.*\r\n#3\[ \]*$hex in __throw__.*\r\n#4\[ \]*$hex in foo \\(i=20\\) at .*exception.cc:8\r\n#5\[ \]*$hex in main.* at .*exception.cc:26\r\n$gdb_prompt $" {
+ pass "backtrace after catch (static executable)"
+ }
+ -re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=\[0-9\].*\r\n.*\r\n#3\[ \]*$hex in __throw__.*\r\n#4\[ \]*$hex in foo \\(i=20\\) at .*exception.cc:8\r\n#5\[ \]*$hex in main.* at .*exception.cc:26\r\n$gdb_prompt $" {
+ pass "backtrace after catch (static executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "backtrace after catch (static executable)" }
+ timeout { fail "(timeout) backtrace after catch (static executable)" }
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing\\.\r\nGot.*\r\nCatchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:36\r\n.*$gdb_prompt $" {
+ pass "caught a throw (2) (static executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "didn't catch a throw (2) (static executable)" }
+ timeout { fail "(timeout) after continue -- didn't catch a throw (2)? (static executable)" }
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing.*Catchpoint \[0-9\]* \\(exception caught\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:36\r\n.*$gdb_prompt $" {
+ pass "caught a catch (2) (static executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "didn't catch a catch (2) (static executable)" }
+ timeout { fail "(timeout) after continue -- didn't catch a catch (2)? (static executable)" }
+}
+
+# Now the exception will be rethrown.
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing\\.\r\nGot.*\r\nCatchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:38, catch location .*exception\\.cc:41\r\n.*$gdb_prompt $" {
+ pass "caught a rethrow (static executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "didn't catch a rethrow (static executable)" }
+ timeout { fail "(timeout) after continue -- didn't catch a rethrow? (static executable)" }
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing.*Catchpoint \[0-9\]* \\(exception caught\\), throw location.*exception\\.cc:3\[68\], catch location .*exception\\.cc:41\r\n.*$gdb_prompt $" {
+ # FIXME: guo: why XFAIL? need comment
+ xfail "caught a catch (3) (static executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "didn't catch a catch (3) (static executable)" }
+ timeout { fail "(timeout) after continue -- didn't catch a catch (3)? (static executable)" }
+}
+
+send_gdb "backtrace\n"
+gdb_expect {
+ -re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=__EH_NOTIFY_CATCH.*\r\n.*\r\n#3\[ \]*$hex in __rethrow.*\r\n#4\[ \]*$hex in main.* at .*exception\\.cc:3\[68\]\r\n#5\[ \]*$hex in foo \\(i=20\\) at .*exception.cc:8\r\n#6\[ \]*$hex in main.* at .*exception.cc:34\r\n$gdb_prompt $" {
+ # FIXME: guo: why XFAIL? need comment
+ xfail "backtrace after catch (3) (static executable)"
+ }
+ -re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=\[0-9\].*\r\n.*\r\n#3\[ \]*$hex in __rethrow.*\r\n#4\[ \]*$hex in main.* at .*exception\\.cc:3\[68\]\r\n#5\[ \]*$hex in foo \\(i=20\\) at .*exception.cc:8\r\n#6\[ \]*$hex in main.* at .*exception.cc:34\r\n$gdb_prompt $" {
+ # FIXME: guo: why XFAIL? need comment
+ xfail "backtrace after catch (3) (static executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "backtrace after catch (3) (static executable)" }
+ timeout { fail "(timeout) backtrace after catch (3) (static executable)" }
+}
+
+# Now the exception will be thrown, but not catch-able anywhere.
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing\\.\r\nGot.*\r\nCatchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:8, catch location unknown\r\n.*$gdb_prompt $" {
+ pass "caught an uncatchable throw (static executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "didn't catch an uncatchable throw (static executable)" }
+ timeout { fail "(timeout) after continue -- didn't catch an uncatchable throw? (static executable)" }
+}
+
+# Part II : Shared-bound executables
+# ----------------------------------
+
+# Start with a fresh gdb
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+set prms_id 0
+set bug_id 0
+
+set testfile "exception"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will a
+utomatically fail."
+}
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+# Set a catch catchpoint
+
+send_gdb "catch catch\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\]* \\(catch\\)\r\n$gdb_prompt $" {
+ pass "catch catch (dynamic executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "catch catch (dynamic executable)" }
+ timeout { fail "(timeout) catch catch (dynamic executable)" }
+}
+
+# Set a throw catchpoint
+
+send_gdb "catch throw\n"
+gdb_expect {
+ -re "Catchpoint \[0-9\]* \\(throw\\)\r\n$gdb_prompt $" {
+ pass "catch throw (dynamic executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "catch throw (dynamic executable)" }
+ timeout { fail "(timeout) catch throw (dynamic executable)" }
+}
+
+# The catchpoints should be listed in the list of breakpoints.
+
+send_gdb "info break\n"
+gdb_expect {
+ -re ".*\[0-9\]*\[ \]*catch catch\[ \]*keep y\[ \]*exception catch\[ \]*\r\n\[0-9\]*\[ \]*catch throw\[ \]*keep y\[ \]*exception throw\[ \]*\r\n$gdb_prompt $" {
+ pass "info break with catchpoints (dynamic executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "info break (dynamic executable)" }
+ timeout { fail "(timeout) info break (dynamic executable)" }
+}
+
+# Info catch currently does not work with HP aCC. No easy way to
+# list the active handlers on the stack.
+
+send_gdb "info catch\n"
+gdb_expect {
+ -re "Info catch not supported with this target/compiler combination.\r\n$gdb_prompt $" {
+ pass "info catch (dynamic executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "info catch (dynamic executable)" }
+ timeout { fail "(timeout) info catch (dynamic executable)" }
+}
+
+# Get the first exception thrown
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing.*Catchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:28\r\n.*$gdb_prompt $" {
+ pass "caught a throw (dynamic executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "didn't catch a throw (dynamic executable)" }
+ timeout { fail "(timeout) after continue -- didn't catch a throw? (dynamic executable)" }
+}
+
+send_gdb "backtrace\n"
+gdb_expect {
+ -re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=__EH_NOTIFY_THROW.*\r\n#2\[ \]*$hex in __eh_notify_throw.*\r\n#3\[ \]*$hex in foo \\(i=20\\) at .*exception\\.cc:8\r\n#4\[ \]*$hex in main.* at .*exception\\.cc:26\r\n$gdb_prompt $" {
+ pass "backtrace after throw (dynamic executable)"
+ }
+ -re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=\[0-9\].*\r\n#2\[ \]*$hex in __eh_notify_throw.*\r\n#3\[ \]*$hex in foo \\(i=20\\) at .*exception\\.cc:8\r\n#4\[ \]*$hex in main.* at .*exception\\.cc:26\r\n$gdb_prompt $" {
+ pass "backtrace after throw (dynamic executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "backtrace after throw (dynamic executable)" }
+ timeout { fail "(timeout) backtrace after throw (dynamic executable)" }
+}
+
+# Now intercept it when it is caught.
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing.*Catchpoint \[0-9\]* \\(exception caught\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:28\r\n.*$gdb_prompt $" {
+ pass "caught a catch (dynamic executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "didn't catch a catch (dynamic executable)" }
+ timeout { fail "(timeout) after continue -- didn't catch a catch? (dynamic executable)" }
+}
+
+send_gdb "backtrace\n"
+gdb_expect {
+ -re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=__EH_NOTIFY_CATCH.*\r\n.*\r\n#3\[ \]*$hex in __throw__.*\r\n#4\[ \]*$hex in foo \\(i=20\\) at .*exception.cc:8\r\n#5\[ \]*$hex in main.* at .*exception.cc:26\r\n$gdb_prompt $" {
+ pass "backtrace after catch (dynamic executable)"
+ }
+ -re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=\[0-9\].*\r\n.*\r\n#3\[ \]*$hex in __throw__.*\r\n#4\[ \]*$hex in foo \\(i=20\\) at .*exception.cc:8\r\n#5\[ \]*$hex in main.* at .*exception.cc:26\r\n$gdb_prompt $" {
+ pass "backtrace after catch (dynamic executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "backtrace after catch (dynamic executable)" }
+ timeout { fail "(timeout) backtrace after catch (dynamic executable)" }
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing\\.\r\nGot.*\r\nCatchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:36\r\n.*$gdb_prompt $" {
+ pass "caught a throw (2) (dynamic executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "didn't catch a throw (2) (dynamic executable)" }
+ timeout { fail "(timeout) after continue -- didn't catch a throw (2)? (dynamic executable)" }
+}
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing.*Catchpoint \[0-9\]* \\(exception caught\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:36\r\n.*$gdb_prompt $" {
+ pass "caught a catch (2) (dynamic executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "didn't catch a catch (2) (dynamic executable)" }
+ timeout { fail "(timeout) after continue -- didn't catch a catch (2)? (dynamic executable)" }
+}
+
+# Now the exception will be rethrown.
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing\\.\r\nGot.*\r\nCatchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:38, catch location .*exception\\.cc:41\r\n.*$gdb_prompt $" {
+ pass "caught a rethrow (dynamic executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "didn't catch a rethrow (dynamic executable)" }
+ timeout { fail "(timeout) after continue -- didn't catch a rethrow? (dynamic executable)" }
+}
+
+#DTS CLLbs14858
+#The throw location should be at line 38 instead of 36.
+setup_xfail hppa*-*-* CLLbs14858
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing.*Catchpoint \[0-9\]* \\(exception caught\\), throw location.*exception\\.cc:3\[68\], catch location .*exception\\.cc:41\r\n.*$gdb_prompt $" {
+ # FIXME: guo: according to comment above the RE is wrong!
+ pass "caught a catch (3) (dynamic executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "didn't catch a catch (3) (dynamic executable)" }
+ timeout { fail "(timeout) after continue -- didn't catch a catch (3)? (dynamic executable)" }
+}
+
+#DTS CLLbs14858
+#The line number for main() should be at exception.cc:38 instead of exception.cc:36
+setup_xfail hppa*-*-* CLLbs14858
+send_gdb "backtrace\n"
+gdb_expect {
+ -re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=__EH_NOTIFY_CATCH.*\r\n.*\r\n#3\[ \]*$hex in __rethrow.*\r\n#4\[ \]*$hex in main.* at .*exception\\.cc:3\[68\]\r\n#5\[ \]*$hex in foo \\(i=20\\) at .*exception.cc:8\r\n#6\[ \]*$hex in main.* at .*exception.cc:34\r\n$gdb_prompt $" {
+ # FIXME: guo: according to comment above the RE is wrong!
+ pass "backtrace after catch (3) (dynamic executable)"
+ }
+ -re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=\[0-9\].*\r\n.*\r\n#3\[ \]*$hex in __rethrow.*\r\n#4\[ \]*$hex in main.* at .*exception\\.cc:3\[68\]\r\n#5\[ \]*$hex in foo \\(i=20\\) at .*exception.cc:8\r\n#6\[ \]*$hex in main.* at .*exception.cc:34\r\n$gdb_prompt $" {
+ # FIXME: guo: according to comment above the RE is wrong!
+ pass "backtrace after catch (3) (dynamic executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "backtrace after catch (3) (dynamic executable)" }
+ timeout { fail "(timeout) backtrace after catch (3) (dynamic executable)" }
+}
+
+# Now the exception will be thrown, but not catch-able anywhere.
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing\\.\r\nGot.*\r\nCatchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:8, catch location unknown\r\n.*$gdb_prompt $" {
+ pass "caught an uncatchable throw (dynamic executable)"
+ }
+ -re ".*$gdb_prompt $" { fail "didn't catch an uncatchable throw (dynamic executable)" }
+ timeout { fail "(timeout) after continue -- didn't catch an uncatchable throw? (dynamic executable)" }
+}
+
diff --git a/gdb/testsuite/gdb.hp/gdb.aCC/optimize.c b/gdb/testsuite/gdb.hp/gdb.aCC/optimize.c
new file mode 100644
index 00000000000..2a8daa8c7a0
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.aCC/optimize.c
@@ -0,0 +1,76 @@
+/* Source for debugging optimimzed code test.
+
+ cc -g -O -o optimize optimize.c
+*/
+int callee();
+int test_opt;
+
+int main()
+{
+ int a,b,c,d,e,f,g,h;
+
+ a = 10;;
+
+ /* Value propagate
+ */
+ b = 2 * a + 1;
+ c = 3 * b + 2;
+
+ /* Re-use expressions
+ */
+ d = (2 * a + 1) * (3 * b + 2);
+ e = (2 * a + 1) * (3 * b + 2);
+
+ /* Create dead stores--do lines still exist?
+ */
+ d = (2 * a + 1) * (3 * b + 2);
+ e = (2 * a + 1) * (3 * b + 2);
+ d = (2 * a + 1) * (3 * b + 2);
+ e = (2 * a + 1) * (3 * b + 2);
+
+ /* Alpha and psi motion
+ */
+ if( test_opt ) {
+ f = e - d;
+ f = f--;
+ }
+ else {
+ f = e - d;
+ f = f + d * e;
+ }
+
+ /* Chi and Rho motion
+ */
+ h = 0;
+ do {
+ h++;
+ a = b * c + d * e; /* Chi */
+ f = f + d * e;
+ g = f + d * e; /* Rho */
+ callee( g+1 );
+ test_opt = (test_opt != 1); /* Cycles */
+ } while( g && h < 10);
+
+ /* Opps for tail recursion, unrolling,
+ * folding, evaporating
+ */
+ for( a = 0; a < 100; a++ ) {
+ callee( callee ( callee( a )));
+ callee( callee ( callee( a )));
+ callee( callee ( callee( a )));
+ }
+
+ return callee( test_opt );
+}
+
+/* defined late to keep line numbers the same
+*/
+int callee( x )
+ int x; /* not used! */
+{
+ test_opt++; /* side effect */
+
+ return test_opt;
+}
+
+/* end */ \ No newline at end of file
diff --git a/gdb/testsuite/gdb.hp/gdb.aCC/optimize.exp b/gdb/testsuite/gdb.hp/gdb.aCC/optimize.exp
new file mode 100644
index 00000000000..84b51b6aca9
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.aCC/optimize.exp
@@ -0,0 +1,149 @@
+# Copyright (C) 1998 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# optimize.exp -- Expect script for testing apps compiled with -O
+
+# There is no DOC support for gdb yet, return 0 for now.
+return 0
+
+global timeout
+
+# use this to debug:
+#
+#log_user 1
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if { [skip_hp_tests] } then { continue }
+
+set testfile optimize
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+
+if { $gcc_compiled } then { continue }
+
+
+# Vanilla -O, which is the same as +O2
+#
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug optimize=+O2}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+send_gdb "file $binfile\n"
+gdb_expect {
+ -re ".*no debugging symbols found.*$gdb_prompt $" {
+ fail "Didn't find debug symbols; CHFts23488"
+ }
+ -re ".*No header section (PXDB data).*$gdb_prompt $" {
+ fail "pointless warning"
+ }
+ -re ".*done.*$gdb_prompt $" {
+ pass "load debug symbols"
+ }
+ timeout { fail "timeout on file" }
+}
+
+# Two lines at the same place after opt.
+#
+gdb_test "b 28" ".*"
+gdb_test "b 26" ".*also set at.*" "same line"
+
+gdb_test "b 47" ".*"
+gdb_test "b 48" ".*also set at.*" "same line"
+
+gdb_test "tb main" ".*"
+
+set old_timeout $timeout
+set timeout [expr "$timeout + 200"]
+send_gdb "r\n"
+gdb_expect {
+ -re ".*No header section (PXDB data).*$gdb_prompt $" {
+ fail "pointless warning"
+ }
+ -re ".*main.*2\[12].*$gdb_prompt $" {
+ # All the lines before line 21 or 22 are
+ # evaporated by the compiler.
+ #
+ pass "hit main"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "didn't hit main"
+ }
+ timeout { fail "timeout on run" }
+}
+set timeout $old_timeout
+
+gdb_test "c" ".*Breakpoint 1.*33.*"
+gdb_test "c" ".*51.*"
+gdb_test "cle" ".*Deleted breakpoints.*" "set 2, so del 2"
+
+gdb_test "b callee" ".*"
+gdb_test "c" ".*callee.*" "hit called rtn"
+
+gdb_exit
+
+# +O4, don't use -g
+#
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {optimize=+O4}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+send_gdb "file $binfile\n"
+gdb_expect {
+ -re ".*no debugging symbols found.*$gdb_prompt $" {
+ pass "Didn't find debug symbols, as expected"
+ }
+ -re ".*No header section (PXDB data).*$gdb_prompt $" {
+ fail "pointless warning"
+ }
+ -re ".*done.*$gdb_prompt $" {
+ fail "Somehow found debug symbols--make this a pass?"
+ }
+ timeout { fail "timeout on file" }
+}
+
+gdb_test "b main" ".*"
+gdb_test "b callee" ".*"
+gdb_test "r" ".*Breakpoint 1.*main.*"
+gdb_test "si 3" ".*main.*" "steps"
+gdb_test "x/4i \$pc" ".*main.*main+4.*main+8.*"
+gdb_test "c" ".*callee.*" "hit bp"
+gdb_test "disas" ".*callee.*callee+4.*callee+12.*"
+gdb_test "si" ".*callee.*"
+gdb_test "fin" ".*Run till exit.*main.*" "finish"
+gdb_test "x/i \$pc" ".*main+.*" "back in main"
+gdb_exit
+
+#remote_exec build "rm -f ${binfile}"
+return 0
diff --git a/gdb/testsuite/gdb.hp/gdb.aCC/run.c b/gdb/testsuite/gdb.hp/gdb.aCC/run.c
new file mode 100644
index 00000000000..6bff81ad7ee
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.aCC/run.c
@@ -0,0 +1,72 @@
+/*
+ * This simple classical example of recursion is useful for
+ * testing stack backtraces and such.
+ */
+
+#ifdef vxworks
+
+# include <stdio.h>
+
+/* VxWorks does not supply atoi. */
+static int
+atoi (char *z)
+ /* char *z;*/
+{
+ int i = 0;
+
+ while (*z >= '0' && *z <= '9')
+ i = i * 10 + (*z++ - '0');
+ return i;
+}
+
+/* I don't know of any way to pass an array to VxWorks. This function
+ can be called directly from gdb. */
+
+void vxmain (char *arg)
+/*char *arg;*/
+{
+ char *argv[2];
+
+ argv[0] = "";
+ argv[1] = arg;
+ main (2, argv, (char **) 0);
+}
+
+#else /* ! vxworks */
+# include <stdio.h>
+# include <stdlib.h>
+#endif /* ! vxworks */
+
+int main (int argc, char *argv[], char **envp)
+/*int argc;
+char *argv[], **envp;*/
+{
+ int factorial (int);
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+#ifdef FAKEARGV
+ printf ("%d\n", factorial (1));
+#else
+ if (argc != 2) {
+ printf ("usage: factorial <number>\n");
+ return 1;
+ } else {
+ printf ("%d\n", factorial (atoi (argv[1])));
+ }
+#endif
+ return 0;
+}
+
+int factorial (int value)
+/*int value;*/
+{
+ int local_var;
+
+ if (value > 1) {
+ value *= factorial (value - 1);
+ }
+ local_var = value;
+ return (value);
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.aCC/watch-cmd.exp b/gdb/testsuite/gdb.hp/gdb.aCC/watch-cmd.exp
new file mode 100644
index 00000000000..e447c0b5cf5
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.aCC/watch-cmd.exp
@@ -0,0 +1,157 @@
+# Copyright (C) 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+#
+# test special commands
+#
+set prms_id 0
+set bug_id 0
+
+if { [skip_hp_tests] } then { continue }
+
+set testfile "run"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+if { $gcc_compiled } then { continue }
+
+
+gdb_exit
+gdb_start
+delete_breakpoints
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+
+proc watchpoint_command_test {} {
+ global gdb_prompt
+
+ if [target_info exists noargs] {
+ verbose "Skipping watchpoint_command_test because of noargs."
+ return
+ }
+
+ if { ![runto factorial] } then { gdb_suppress_tests }
+ # Don't depend upon argument passing, since most simulators don't currently
+ # support it. Bash value variable to be what we want.
+ gdb_test "p value=6" "" "set value to 6 in watchpoint_command_test"
+ delete_breakpoints
+
+ # Verify that we can create a watchpoint, and give it a commands
+ # list that continues the inferior. We set the watchpoint on a
+ # local variable, too, so that it self-deletes when the watched
+ # data goes out of scope.
+ #
+ # What should happen is: Each time the watchpoint triggers, it
+ # continues the inferior. Eventually, the watchpoint will self-
+ # delete, when the watched variable is out of scope. But by that
+ # time, the inferior should have exited. GDB shouldn't crash or
+ # anything untoward as a result of this.
+ #
+ send_gdb "watch local_var\n"
+ gdb_expect {
+ -re ".*\[Ww\]atchpoint (\[0-9\]*): local_var.*$gdb_prompt $"\
+ { pass "watch local_var"
+ set wp_id $expect_out(1,string)
+ send_gdb "commands $wp_id\n"
+ gdb_expect {
+ -re "Type commands for when breakpoint $wp_id is hit, one per line.*>"\
+ { pass "begin commands on watch"}
+ -re "$gdb_prompt $"\
+ {fail "begin commands on watch"}
+ timeout {fail "(timeout) begin commands on watch"}
+ }
+ }
+ -re "$gdb_prompt $"\
+ {fail "watch local_var"}
+ timeout {fail "(timeout) watch local_var"}
+ }
+# set wp_id $expect_out(1,string)
+# send_gdb "commands $wp_id\n"
+# gdb_expect {
+# -re "Type commands for when breakpoint $wp_id is hit, one per line.*>"\
+# {pass "begin commands on watch"}
+# -re "$gdb_prompt $"\
+# {fail "begin commands on watch"}
+# timeout {fail "(timeout) begin commands on watch"}
+# }
+ send_gdb "print value\n"
+ gdb_expect {
+ -re ">"\
+ {pass "add print command to watch"}
+ -re "$gdb_prompt $"\
+ {fail "add print command to watch"}
+ timeout {fail "(timeout) add print command to watch"}
+ }
+ send_gdb "continue\n"
+ gdb_expect {
+ -re ">"\
+ {pass "add continue command to watch"}
+ -re "$gdb_prompt $"\
+ {fail "add continue command to watch"}
+ timeout {fail "(timeout) add continue command to watch"}
+ }
+ send_gdb "end\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "begin commands on watch"}
+ timeout {fail "(timeout) begin commands on watch"}
+ }
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Continuing.*\[Ww\]atchpoint $wp_id deleted because the program has left the block in.*which its expression is valid.*in main.*$gdb_prompt $"\
+ {pass "continue with watch"}
+ -re "$gdb_prompt $"\
+ {fail "continue with watch"}
+ timeout {fail "(timeout) continue with watch"}
+ }
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Continuing.*$gdb_prompt $"\
+ {pass "continue until exit"}
+ -re "$gdb_prompt $"\
+ {fail "continue until exit"}
+ timeout {fail "(timeout) continue until exit"}
+ }
+}
+
+watchpoint_command_test
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/Makefile.in b/gdb/testsuite/gdb.hp/gdb.base-hp/Makefile.in
new file mode 100644
index 00000000000..adbde9df27e
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/Makefile.in
@@ -0,0 +1,32 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES = dollar hwwatchbus.bak pxdb reg reg-pa64 \
+ so-thresh genso-thresh sized-enum
+
+MISCELLANEOUS = so-thresh.c so-thresh.lopt so-thresh.make.out \
+ lib*-so-thresh.*
+
+all:
+ @echo "Nothing to be done for all..."
+
+info:
+install-info:
+dvi:
+install:
+uninstall: force
+installcheck:
+check:
+
+clean mostlyclean:
+ -rm -f *~ *.o *.ci
+ -rm -f core $(EXECUTABLES)
+ -rm -f $(MISCELLANEOUS)
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
+ -rm -f *-init.exp
+ -rm -fr *.log summary detail *.plog *.sum *.psum site.*
+
+Makefile : $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/callfwmall.c b/gdb/testsuite/gdb.hp/gdb.base-hp/callfwmall.c
new file mode 100644
index 00000000000..67edb8b70d4
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/callfwmall.c
@@ -0,0 +1,362 @@
+/* Support program for testing gdb's ability to call functions
+ in an inferior which doesn't itself call malloc, pass appropriate
+ arguments to those functions, and get the returned result. */
+
+#ifdef NO_PROTOTYPES
+#define PARAMS(paramlist) ()
+#else
+#define PARAMS(paramlist) paramlist
+#endif
+
+# include <string.h>
+
+char char_val1 = 'a';
+char char_val2 = 'b';
+
+short short_val1 = 10;
+short short_val2 = -23;
+
+int int_val1 = 87;
+int int_val2 = -26;
+
+long long_val1 = 789;
+long long_val2 = -321;
+
+float float_val1 = 3.14159;
+float float_val2 = -2.3765;
+
+double double_val1 = 45.654;
+double double_val2 = -67.66;
+
+#define DELTA (0.001)
+
+char *string_val1 = (char *)"string 1";
+char *string_val2 = (char *)"string 2";
+
+char char_array_val1[] = "carray 1";
+char char_array_val2[] = "carray 2";
+
+struct struct1 {
+ char c;
+ short s;
+ int i;
+ long l;
+ float f;
+ double d;
+ char a[4];
+} struct_val1 = { 'x', 87, 76, 51, 2.1234, 9.876, "foo" };
+
+/* Some functions that can be passed as arguments to other test
+ functions, or called directly. */
+#ifdef PROTOTYPES
+int add (int a, int b)
+#else
+int add (a, b) int a, b;
+#endif
+{
+ return (a + b);
+}
+
+#ifdef PROTOTYPES
+int doubleit (int a)
+#else
+int doubleit (a)
+int a;
+#endif
+{
+ return (a + a);
+}
+
+int (*func_val1) PARAMS((int,int)) = add;
+int (*func_val2) PARAMS((int)) = doubleit;
+
+/* An enumeration and functions that test for specific values. */
+
+enum enumtype { enumval1, enumval2, enumval3 };
+enum enumtype enum_val1 = enumval1;
+enum enumtype enum_val2 = enumval2;
+enum enumtype enum_val3 = enumval3;
+
+#ifdef PROTOTYPES
+int t_enum_value1 (enum enumtype enum_arg)
+#else
+t_enum_value1 (enum_arg)
+enum enumtype enum_arg;
+#endif
+{
+ return (enum_arg == enum_val1);
+}
+
+#ifdef PROTOTYPES
+int t_enum_value2 (enum enumtype enum_arg)
+#else
+t_enum_value2 (enum_arg)
+enum enumtype enum_arg;
+#endif
+{
+ return (enum_arg == enum_val2);
+}
+
+#ifdef PROTOTYPES
+int t_enum_value3 (enum enumtype enum_arg)
+#else
+t_enum_value3 (enum_arg)
+enum enumtype enum_arg;
+#endif
+{
+ return (enum_arg == enum_val3);
+}
+
+/* A function that takes a vector of integers (along with an explicit
+ count) and returns their sum. */
+
+#ifdef PROTOTYPES
+int sum_args (int argc, int argv[])
+#else
+int sum_args (argc, argv)
+int argc;
+int argv[];
+#endif
+{
+ int sumval = 0;
+ int idx;
+
+ for (idx = 0; idx < argc; idx++)
+ {
+ sumval += argv[idx];
+ }
+ return (sumval);
+}
+
+/* Test that we can call functions that take structs and return
+ members from that struct */
+
+#ifdef PROTOTYPES
+char t_structs_c (struct struct1 tstruct) { return (tstruct.c); }
+short t_structs_s (struct struct1 tstruct) { return (tstruct.s); }
+int t_structs_i (struct struct1 tstruct) { return (tstruct.i); }
+long t_structs_l (struct struct1 tstruct) { return (tstruct.l); }
+float t_structs_f (struct struct1 tstruct) { return (tstruct.f); }
+double t_structs_d (struct struct1 tstruct) { return (tstruct.d); }
+char *t_structs_a (struct struct1 tstruct)
+{
+ static char buf[8];
+ strcpy (buf, tstruct.a);
+ return buf;
+}
+#else
+char t_structs_c (tstruct) struct struct1 tstruct; { return (tstruct.c); }
+short t_structs_s (tstruct) struct struct1 tstruct; { return (tstruct.s); }
+int t_structs_i (tstruct) struct struct1 tstruct; { return (tstruct.i); }
+long t_structs_l (tstruct) struct struct1 tstruct; { return (tstruct.l); }
+float t_structs_f (tstruct) struct struct1 tstruct; { return (tstruct.f); }
+double t_structs_d (tstruct) struct struct1 tstruct; { return (tstruct.d); }
+char *t_structs_a (tstruct) struct struct1 tstruct;
+{
+ static char buf[8];
+ strcpy (buf, tstruct.a);
+ return buf;
+}
+#endif
+
+/* Test that calling functions works if there are a lot of arguments. */
+#ifdef PROTOTYPES
+int sum10 (int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9)
+#else
+int
+sum10 (i0, i1, i2, i3, i4, i5, i6, i7, i8, i9)
+ int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
+#endif
+{
+ return i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9;
+}
+
+/* Gotta have a main to be able to generate a linked, runnable
+ executable, and also provide a useful place to set a breakpoint. */
+
+#ifdef PROTOTYPES
+int main()
+#else
+main ()
+#endif
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ t_structs_c(struct_val1);
+ return 0;
+
+}
+
+/* Functions that expect specific values to be passed and return
+ either 0 or 1, depending upon whether the values were
+ passed incorrectly or correctly, respectively. */
+
+#ifdef PROTOTYPES
+int t_char_values (char char_arg1, char char_arg2)
+#else
+int t_char_values (char_arg1, char_arg2)
+char char_arg1, char_arg2;
+#endif
+{
+ return ((char_arg1 == char_val1) && (char_arg2 == char_val2));
+}
+
+int
+#ifdef PROTOTYPES
+t_small_values (char arg1, short arg2, int arg3, char arg4, short arg5,
+ char arg6, short arg7, int arg8, short arg9, short arg10)
+#else
+t_small_values (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
+ char arg1;
+ short arg2;
+ int arg3;
+ char arg4;
+ short arg5;
+ char arg6;
+ short arg7;
+ int arg8;
+ short arg9;
+ short arg10;
+#endif
+{
+ return arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9 + arg10;
+}
+
+#ifdef PROTOTYPES
+int t_short_values (short short_arg1, short short_arg2)
+#else
+int t_short_values (short_arg1, short_arg2)
+short short_arg1, short_arg2;
+#endif
+{
+ return ((short_arg1 == short_val1) && (short_arg2 == short_val2));
+}
+
+#ifdef PROTOTYPES
+int t_int_values (int int_arg1, int int_arg2)
+#else
+int t_int_values (int_arg1, int_arg2)
+int int_arg1, int_arg2;
+#endif
+{
+ return ((int_arg1 == int_val1) && (int_arg2 == int_val2));
+}
+
+#ifdef PROTOTYPES
+int t_long_values (long long_arg1, long long_arg2)
+#else
+int t_long_values (long_arg1, long_arg2)
+long long_arg1, long_arg2;
+#endif
+{
+ return ((long_arg1 == long_val1) && (long_arg2 == long_val2));
+}
+
+/* NOTE: THIS FUNCTION MUST NOT BE PROTOTYPED!!!!!
+ There must be one version of "t_float_values" (this one)
+ that is not prototyped, and one (if supported) that is (following).
+ That way GDB can be tested against both cases. */
+
+int t_float_values (float_arg1, float_arg2)
+float float_arg1, float_arg2;
+{
+ return ((float_arg1 - float_val1) < DELTA
+ && (float_arg1 - float_val1) > -DELTA
+ && (float_arg2 - float_val2) < DELTA
+ && (float_arg2 - float_val2) > -DELTA);
+}
+
+int
+#ifdef NO_PROTOTYPES
+/* In this case we are just duplicating t_float_values, but that is the
+ easiest way to deal with either ANSI or non-ANSI. */
+t_float_values2 (float_arg1, float_arg2)
+ float float_arg1, float_arg2;
+#else
+t_float_values2 (float float_arg1, float float_arg2)
+#endif
+{
+ return ((float_arg1 - float_val1) < DELTA
+ && (float_arg1 - float_val1) > -DELTA
+ && (float_arg2 - float_val2) < DELTA
+ && (float_arg2 - float_val2) > -DELTA);
+}
+
+#ifdef PROTOTYPES
+int t_double_values (double double_arg1, double double_arg2)
+#else
+int t_double_values (double_arg1, double_arg2)
+double double_arg1, double_arg2;
+#endif
+{
+ return ((double_arg1 - double_val1) < DELTA
+ && (double_arg1 - double_val1) > -DELTA
+ && (double_arg2 - double_val2) < DELTA
+ && (double_arg2 - double_val2) > -DELTA);
+}
+
+#ifdef PROTOTYPES
+int t_string_values (char *string_arg1, char *string_arg2)
+#else
+int t_string_values (string_arg1, string_arg2)
+char *string_arg1, *string_arg2;
+#endif
+{
+ return (!strcmp (string_arg1, string_val1) &&
+ !strcmp (string_arg2, string_val2));
+}
+
+#ifdef PROTOTYPES
+int t_char_array_values (char char_array_arg1[], char char_array_arg2[])
+#else
+int t_char_array_values (char_array_arg1, char_array_arg2)
+char char_array_arg1[], char_array_arg2[];
+#endif
+{
+ return (!strcmp (char_array_arg1, char_array_val1) &&
+ !strcmp (char_array_arg2, char_array_val2));
+}
+
+
+/* This used to simply compare the function pointer arguments with
+ known values for func_val1 and func_val2. Doing so is valid ANSI
+ code, but on some machines (RS6000, HPPA, others?) it may fail when
+ called directly by GDB.
+
+ In a nutshell, it's not possible for GDB to determine when the address
+ of a function or the address of the function's stub/trampoline should
+ be passed.
+
+ So, to avoid GDB lossage in the common case, we perform calls through the
+ various function pointers and compare the return values. For the HPPA
+ at least, this allows the common case to work.
+
+ If one wants to try something more complicated, pass the address of
+ a function accepting a "double" as one of its first 4 arguments. Call
+ that function indirectly through the function pointer. This would fail
+ on the HPPA. */
+
+#ifdef PROTOTYPES
+int t_func_values (int (*func_arg1)(int, int), int (*func_arg2)(int))
+#else
+int t_func_values (func_arg1, func_arg2)
+int (*func_arg1) PARAMS ((int, int));
+int (*func_arg2) PARAMS ((int));
+#endif
+{
+ return ((*func_arg1) (5,5) == (*func_val1) (5,5)
+ && (*func_arg2) (6) == (*func_val2) (6));
+}
+
+#ifdef PROTOTYPES
+int t_call_add (int (*func_arg1)(int, int), int a, int b)
+#else
+int t_call_add (func_arg1, a, b)
+int (*func_arg1) PARAMS ((int, int));
+int a, b;
+#endif
+{
+ return ((*func_arg1)(a, b));
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/callfwmall.exp b/gdb/testsuite/gdb.hp/gdb.base-hp/callfwmall.exp
new file mode 100644
index 00000000000..586cabb7cdf
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/callfwmall.exp
@@ -0,0 +1,346 @@
+# Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+# These tests are the same as those in callfuncs.exp, except that the
+# test program here does not call malloc.
+#
+# "What in the world does malloc have to do with calling functions in
+# the inferior?" Well, nothing. GDB's ability to invoke a function
+# in the inferior program works just fine in programs that have no
+# malloc function available. It doesn't rely on the inferior's
+# malloc, directly or indirectly. It just uses the inferior's stack
+# space.
+#
+# "Then what's the point of this test file?" Well, it just so happens
+# that this file, in addition to testing inferior function calls, also
+# tests GDB's ability to evaluate string literals (like "string 1" and
+# "string 2" in the tests below). Evaluating *those* sorts of
+# expressions does require malloc.
+#
+# (As an extension to C, GDB also has a syntax for literal arrays of
+# anything, not just characters. For example, the expression
+# {2,3,4,5} (which appears in the tests below) evaluates to an array
+# of four ints. So rather than talking just about string literals,
+# we'll use the broader term "array literals".)
+#
+# Now, in this file, we only evaluate array literals when we're about
+# to pass them to a function, but don't be confused --- this is a red
+# herring. You can evaluate "abcdef" even if you're not about to pass
+# that to a function, and doing so requires malloc even if you're just
+# going to store a pointer to it in a variable, like this:
+#
+# (gdb) ptype s
+# type = char *
+# (gdb) set variable s = "abcdef"
+#
+# According to C's rules for evaluating expressions, arrays are
+# converted into pointers to their first element. This means that, in
+# order to evaluate an expression like "abcdef", GDB needs to actually
+# find some memory in the inferior we can plop the characters into;
+# then we use that memory's address as the address of our array
+# literal. GDB finds this memory by calling the inferior's malloc
+# function, if it has one. So, evaluating an array literal depends on
+# performing an inferior function call, but not vice versa. (GDB
+# can't just allocate the space on the stack; the pointer may remain
+# live long after the current frame has been popped.)
+#
+# "But, if evaluating array literals requires malloc, what's the point
+# of testing that GDB can do so in a program that doesn't have malloc?
+# It can't work!" On most systems, that's right, but HP-UX has some
+# sort of dynamic linking magic that ensures that *every* program has
+# malloc. So on HP-UX, GDB can evaluate array literals even in
+# inferior programs that don't use malloc. That's why this test is in
+# gdb.hp.
+#
+# This file has, for some reason, led to well more than its fair share
+# of misunderstandings about the relationship between array literal
+# expressions and inferior function calls. Folks talk as if you can
+# only evaluate array literals when you're about to pass them to a
+# function. I think they're assuming that, since GDB is constructing
+# a new frame on the inferior's stack (correct), it's going to use
+# that space for the array literals (incorrect). Remember that those
+# array literals may need to be live long after the inferior function
+# call returns; GDB can't tell.
+#
+# What makes the confusion worse is that there *is* a relationship
+# between array literals and inferior function calls --- GDB uses
+# inferior function calls to evaluate array literals. But many people
+# jump to other, incorrect conclusions about this.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+if { [skip_hp_tests] } then { continue }
+
+set testfile "callfwmall"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+if {$hp_aCC_compiler} {
+ set prototypes 1
+} else {
+ set prototypes 0
+}
+
+
+# Some targets can't call functions, so don't even bother with this
+# test.
+if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ continue
+}
+
+# Set the current language to C. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_c {} {
+ global gdb_prompt
+
+ send_gdb "set language c\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language c (timeout)" ; return 0 }
+ }
+
+ send_gdb "show language\n"
+ gdb_expect {
+ -re ".* source language is \"c\".*$gdb_prompt $" {
+ pass "set language to \"c\""
+ return 1
+ }
+ -re ".*$gdb_prompt $" {
+ fail "setting language to \"c\""
+ return 0
+ }
+ timeout {
+ fail "can't show language (timeout)"
+ return 0
+ }
+ }
+}
+
+# FIXME: Before calling this proc, we should probably verify that
+# we can call inferior functions and get a valid integral value
+# returned.
+# Note that it is OK to check for 0 or 1 as the returned values, because C
+# specifies that the numeric value of a relational or logical expression
+# (computed in the inferior) is 1 for true and 0 for false.
+
+proc do_function_calls {} {
+ global prototypes
+ global gcc_compiled
+ global gdb_prompt
+
+ # We need to up this because this can be really slow on some boards.
+ set timeout 60;
+
+ gdb_test "p t_char_values(0,0)" " = 0"
+ gdb_test "p t_char_values('a','b')" " = 1"
+ gdb_test "p t_char_values(char_val1,char_val2)" " = 1"
+ gdb_test "p t_char_values('a',char_val2)" " = 1"
+ gdb_test "p t_char_values(char_val1,'b')" " = 1"
+
+ gdb_test "p t_short_values(0,0)" " = 0"
+ gdb_test "p t_short_values(10,-23)" " = 1"
+ gdb_test "p t_short_values(short_val1,short_val2)" " = 1"
+ gdb_test "p t_short_values(10,short_val2)" " = 1"
+ gdb_test "p t_short_values(short_val1,-23)" " = 1"
+
+ gdb_test "p t_int_values(0,0)" " = 0"
+ gdb_test "p t_int_values(87,-26)" " = 1"
+ gdb_test "p t_int_values(int_val1,int_val2)" " = 1"
+ gdb_test "p t_int_values(87,int_val2)" " = 1"
+ gdb_test "p t_int_values(int_val1,-26)" " = 1"
+
+ gdb_test "p t_long_values(0,0)" " = 0"
+ gdb_test "p t_long_values(789,-321)" " = 1"
+ gdb_test "p t_long_values(long_val1,long_val2)" " = 1"
+ gdb_test "p t_long_values(789,long_val2)" " = 1"
+ gdb_test "p t_long_values(long_val1,-321)" " = 1"
+
+ if ![target_info exists gdb,skip_float_tests] {
+ gdb_test "p t_float_values(0.0,0.0)" " = 0"
+
+ # These next four tests fail on the mn10300.
+ # The first value is passed in regs, the other in memory.
+ # Gcc emits different stabs for the two parameters; the first is
+ # claimed to be a float, the second a double.
+ # dbxout.c in gcc claims this is the desired behavior.
+ setup_xfail "mn10300-*-*"
+ gdb_test "p t_float_values(3.14159,-2.3765)" " = 1"
+ setup_xfail "mn10300-*-*"
+ gdb_test "p t_float_values(float_val1,float_val2)" " = 1"
+ setup_xfail "mn10300-*-*"
+ gdb_test "p t_float_values(3.14159,float_val2)" " = 1"
+ setup_xfail "mn10300-*-*"
+ gdb_test "p t_float_values(float_val1,-2.3765)" " = 1"
+
+ # Test passing of arguments which might not be widened.
+ gdb_test "p t_float_values2(0.0,0.0)" " = 0"
+
+ # Although PR 5318 mentions SunOS specifically, this seems
+ # to be a generic problem on quite a few platforms.
+ if $prototypes then {
+ setup_xfail "sparc-*-*" "mips*-*-*" 5318
+ if {!$gcc_compiled} then {
+ setup_xfail "alpha-dec-osf2*" "i*86-*-sysv4*" 5318
+ }
+ }
+ gdb_test "p t_float_values2(3.14159,float_val2)" " = 1"
+ gdb_test "p t_small_values(1,2,3,4,5,6,7,8,9,10)" " = 55"
+
+ gdb_test "p t_double_values(0.0,0.0)" " = 0"
+ gdb_test "p t_double_values(45.654,-67.66)" " = 1"
+ gdb_test "p t_double_values(double_val1,double_val2)" " = 1"
+ gdb_test "p t_double_values(45.654,double_val2)" " = 1"
+ gdb_test "p t_double_values(double_val1,-67.66)" " = 1"
+
+ }
+
+ gdb_test "p t_string_values(string_val2,string_val1)" " = 0"
+ gdb_test "p t_string_values(string_val1,string_val2)" " = 1"
+ gdb_test "p t_string_values(\"string 1\",\"string 2\")" " = 1"
+ gdb_test "p t_string_values(\"string 1\",string_val2)" " = 1"
+ gdb_test "p t_string_values(string_val1,\"string 2\")" " = 1"
+
+ gdb_test "p t_char_array_values(char_array_val2,char_array_val1)" " = 0"
+ gdb_test "p t_char_array_values(char_array_val1,char_array_val2)" " = 1"
+ gdb_test "p t_char_array_values(\"carray 1\",\"carray 2\")" " = 1"
+ gdb_test "p t_char_array_values(\"carray 1\",char_array_val2)" " = 1"
+ gdb_test "p t_char_array_values(char_array_val1,\"carray 2\")" " = 1"
+
+ gdb_test "p doubleit(4)" " = 8"
+ gdb_test "p add(4,5)" " = 9"
+ gdb_test "p t_func_values(func_val2,func_val1)" " = 0"
+ gdb_test "p t_func_values(func_val1,func_val2)" " = 1"
+
+ # On the rs6000, we need to pass the address of the trampoline routine,
+ # not the address of add itself. I don't know how to go from add to
+ # the address of the trampoline. Similar problems exist on the HPPA,
+ # and in fact can present an unsolvable problem as the stubs may not
+ # even exist in the user's program. We've slightly recoded t_func_values
+ # to avoid such problems in the common case. This may or may not help
+ # the RS6000.
+ setup_xfail "rs6000*-*-*"
+ setup_xfail "powerpc*-*-*"
+
+ if {![istarget hppa*-*-hpux*]} then {
+ gdb_test "p t_func_values(add,func_val2)" " = 1"
+ }
+
+ setup_xfail "rs6000*-*-*"
+ setup_xfail "powerpc*-*-*"
+
+ if {![istarget hppa*-*-hpux*]} then {
+ gdb_test "p t_func_values(func_val1,doubleit)" " = 1"
+ }
+
+ gdb_test "p t_call_add(func_val1,3,4)" " = 7"
+
+ setup_xfail "rs6000*-*-*"
+ setup_xfail "powerpc*-*-*"
+
+ if {![istarget hppa*-*-hpux*]} then {
+ gdb_test "p t_call_add(add,3,4)" " = 7"
+ }
+
+ gdb_test "p t_enum_value1(enumval1)" " = 1"
+ gdb_test "p t_enum_value1(enum_val1)" " = 1"
+ gdb_test "p t_enum_value1(enum_val2)" " = 0"
+
+ gdb_test "p t_enum_value2(enumval2)" " = 1"
+ gdb_test "p t_enum_value2(enum_val2)" " = 1"
+ gdb_test "p t_enum_value2(enum_val1)" " = 0"
+
+ gdb_test "p sum_args(1,{2})" " = 2"
+ gdb_test "p sum_args(2,{2,3})" " = 5"
+ gdb_test "p sum_args(3,{2,3,4})" " = 9"
+ gdb_test "p sum_args(4,{2,3,4,5})" " = 14"
+ gdb_test "p sum10 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)" " = 55"
+
+ gdb_test "p t_structs_c(struct_val1)" "= 120 'x'" \
+ "call inferior func with struct - returns char"
+ gdb_test "p t_structs_s(struct_val1)" "= 87" \
+ "call inferior func with struct - returns short"
+ gdb_test "p t_structs_i(struct_val1)" "= 76" \
+ "call inferior func with struct - returns int"
+ gdb_test "p t_structs_l(struct_val1)" "= 51" \
+ "call inferior func with struct - returns long"
+ gdb_test "p t_structs_f(struct_val1)" "= 2.12.*" \
+ "call inferior func with struct - returns float"
+ gdb_test "p t_structs_d(struct_val1)" "= 9.87.*" \
+ "call inferior func with struct - returns double"
+ gdb_test "p t_structs_a(struct_val1)" "= (.unsigned char .. )?\"foo\"" \
+ "call inferior func with struct - returns char *"
+
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set print sevenbit-strings" ""
+gdb_test "set print address off" ""
+gdb_test "set width 0" ""
+
+if { $hp_aCC_compiler } {
+ # Do not set language explicitly to 'C'. This will cause aCC
+ # tests to fail because promotion rules are different. Just let
+ # the language be set to the default.
+
+ if { ![runto_main] } {
+ gdb_suppress_tests;
+ }
+
+ gdb_test "set overload-resolution 0" ".*"
+} else {
+ if { ![set_lang_c] } {
+ gdb_suppress_tests;
+ } else {
+ if { ![runto_main] } {
+ gdb_suppress_tests;
+ }
+ }
+}
+
+gdb_test "next" ".*"
+do_function_calls
+
+return 0
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/configure b/gdb/testsuite/gdb.hp/gdb.base-hp/configure
new file mode 100755
index 00000000000..958011d03dc
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/configure
@@ -0,0 +1,899 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=dollar.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../../.. $srcdir/`cd $srcdir;pwd`/../../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../../.. $srcdir/`cd $srcdir;pwd`/../../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:573: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:594: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:612: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/configure.in b/gdb/testsuite/gdb.hp/gdb.base-hp/configure.in
new file mode 100644
index 00000000000..f6f43a7d932
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/configure.in
@@ -0,0 +1,15 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(dollar.exp)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/dollar.c b/gdb/testsuite/gdb.hp/gdb.base-hp/dollar.c
new file mode 100644
index 00000000000..8fd9893c704
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/dollar.c
@@ -0,0 +1,10 @@
+#ifdef PROTOTYPES
+int main (int argc, char **argv)
+#else
+main (argc, argv, envp)
+ int argc;
+ char **argv;
+#endif
+{
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/dollar.exp b/gdb/testsuite/gdb.hp/gdb.base-hp/dollar.exp
new file mode 100644
index 00000000000..b3a6335a1f5
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/dollar.exp
@@ -0,0 +1,155 @@
+# Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# GDB tests for names beginning with '$'
+
+# This is aimed at HP-UX systems where a lot of system
+# routines and names begin with '$' or '$$'. GDB 4.16 was
+# unable to deal with these names as they clashed with
+# convenience variables. Wildebeest should accept such
+# names in preference to convenience variables.
+
+# This file was written by Satish Pai <pai@apollo.hp.com>
+# 1997-09-24
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+if { [skip_hp_tests] } { continue }
+
+set testfile "dollar"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+#source ${binfile}.ci
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+# Test for millicode routines
+# hppa64 does not support dyncall
+if ![istarget "hppa64*-*-*"] {
+send_gdb "print \$\$dyncall\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\{<text variable, no debug info>\\} $hex <>.*$gdb_prompt $" { pass "print \$\$dyncall" }
+ -re "\\$\[0-9\]* = \\{<text variable, no debug info>\\} $hex <.*dyncall>.*$gdb_prompt $" { pass "print \$\$dyncall" }
+ -re "\\$\[0-9\]* = void" { fail "print \$\$dyncall -- interpreted as convenience var" }
+ -re "$gdb_prompt $" { fail "print \$\$dyncall" }
+ timeout { fail "(timeout) print \$\$dyncall" }
+}
+send_gdb "print \$\$dyncall_external\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\{<text variable, no debug info>\\} $hex <>.*$gdb_prompt $" { pass "print \$\$dyncall_external" }
+ -re "\\$\[0-9\]* = \\{<text variable, no debug info>\\} $hex <.*dyncall_external>.*$gdb_prompt $" { pass "print \$\$dyncall_external" }
+ -re "\\$\[0-9\]* = void" { fail "print \$\$dyncall_external -- interpreted as convenience var" }
+ -re "$gdb_prompt $" { fail "print \$\$dyncall_external" }
+ timeout { fail "(timeout) print \$\$dyncall_external" }
+}
+
+# Set a breakpoint on a millicode routine
+send_gdb "break \$\$dyncall\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]* at $hex.*$gdb_prompt $" { pass "break \$\$dyncall" }
+ -re "Function.*not defined.*$gdb_prompt $" {fail "break \$\$dyncall -- no \$\$dyncall?" }
+ -re "Convenience variables used in line specs must have integer values\\..*$gdb_prompt $" {
+ fail "break \$\$dyncall -- treated as convenince variable"
+ }
+ -re "$gdb_prompt $" { fail "print break \$\$dyncall" }
+ timeout { fail "(timeout) print break \$\$dyncall" }
+}
+
+# Disassemble $$dyncall
+send_gdb "disassemble \$\$dyncall\n"
+gdb_expect {
+ -re "Dump of assembler code for function.*$gdb_prompt $" { pass "disas \$\$dyncall" }
+ -re "$gdb_prompt $" { fail "disas \$\$dyncall" }
+ timeout { fail "(timeout) disas \$\$dyncall" }
+}
+
+# Try to set $$dyncall like a convenience var.
+send_gdb "set \$\$dyncall = 77\n"
+gdb_expect {
+ -re "Invalid cast.*$gdb_prompt $" { pass "set \$\$dyncall = 77" }
+ -re "$gdb_prompt $" { fail "set \$\$dyncall = 77" }
+ timeout { fail "(timeout) set \$\$dyncall = 77" }
+}
+}
+
+# Try out some other $ name, not millicode
+if [istarget "hppa64*-*-*"] {
+ #hppa64 uses __argv instead of $ARGV.
+ send_gdb "print \__argv\n"
+ gdb_expect {
+ -re "\\$\[0-9\]* = \[0-9\]*.*$gdb_prompt $" { pass "print \__argv" }
+ -re "\\$\[0-9\]* = void.*$gdb_prompt $" {
+ fail "print \__argv (interpreted as convenience var)"
+ }
+ -re "$gdb_prompt $" { fail "print \__argv" }
+ timeout { fail "(timeout) print \__argv" }
+ }
+
+ send_gdb "ptype \__argv\n"
+ gdb_expect {
+ -re "type = <data variable, no debug info>.*$gdb_prompt $" {
+ pass "ptype \__argv"
+ }
+ -re "type = void.*$gdb_prompt $" {
+ fail "ptype \__argv (interpreted as convenience var)"
+ }
+ -re "$gdb_prompt $" { fail "ptype \__argv" }
+ timeout { fail "(timeout) ptype \__argv" }
+ }
+} else {
+send_gdb "print \$ARGV\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \[0-9\]*.*$gdb_prompt $" { pass "print \$ARGV" }
+ -re "\\$\[0-9\]* = void.*$gdb_prompt $" { fail "print \$ARGV (interpreted as convenience var)" }
+ -re "$gdb_prompt $" { fail "print \$ARGV" }
+ timeout { fail "(timeout) print \$ARGV" }
+}
+send_gdb "ptype \$ARGV\n"
+gdb_expect {
+ -re "type = <data variable, no debug info>.*$gdb_prompt $" { pass "ptype \$ARGV" }
+ -re "type = void.*$gdb_prompt $" { fail "ptype \$ARGV (interpreted as convenience var)" }
+ -re "$gdb_prompt $" { fail "ptype \$ARGV" }
+ timeout { fail "(timeout) ptype \$ARGV" }
+}
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/genso-thresh.c b/gdb/testsuite/gdb.hp/gdb.base-hp/genso-thresh.c
new file mode 100644
index 00000000000..50756bb975d
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/genso-thresh.c
@@ -0,0 +1,229 @@
+/*
+ * Program to generate the so-thresh testcase,
+ * including associated linked-against shared libraries.
+ * Build as:
+ *
+ * cc -g -o genso-thresh genso-thresh.c
+ *
+ * Invoke as:
+ *
+ * genso-thresh
+ *
+ * It will put all the code in the current directory (".").
+ *
+ * A makefile can also be generated if the -makemake option is used.
+ * To use the makefile:
+ *
+ * make -f so-thresh.mk all
+ *
+ * The name of the application is
+ *
+ * so-thresh
+ *
+ * (Revised from a program by John Bishop. --rehrauer)
+ */
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+
+int main (argc, argv)
+int argc;
+char **argv;
+{
+#define NUMBER_OF_INT_VARS 1500
+#define NUMBER_OF_LIBS 3
+ int lib_num = NUMBER_OF_LIBS;
+ int i;
+ int i2;
+ FILE *main_file;
+ FILE *lib_file;
+ FILE *make_file;
+ FILE *link_file;
+
+ char testcase_name [1000];
+ char linkfile_name [1000];
+ char makefile_name [1000];
+ char mainfile_name [1000];
+
+ char file_name[100];
+ /*
+ * 0123456789 <-- length of field
+ * "./fil0000000002.c"; <-- typical filename
+ * 12345678901234567890 <-- length of string
+ * 10 20
+ * ^where null goes
+ */
+ char file_name_core[100];
+
+ /* Verify input.
+ */
+ if ((argc < 1) || (argc > 2) || (argv == NULL) ||
+ ((argc == 2) && (strcmp (argv[1], "-makemake") != 0)))
+ {
+ printf ("** Syntax: %s [-makemake]\n", argv[0]);
+ return;
+ }
+
+ if (strncmp (argv[0], "gen", 3) != 0)
+ {
+ printf ("** This tool expected to be named \"gen<something>\"\n");
+ return;
+ }
+ strcpy (testcase_name, argv[0]+3);
+
+ strcpy (linkfile_name, testcase_name);
+ strcat (linkfile_name, ".lopt");
+ link_file = fopen (linkfile_name, "w");
+ fprintf (link_file, "# Linker options for %s test\n", testcase_name);
+
+ /* Generate the makefile, if requested.
+ */
+ if (argc == 2)
+ {
+ strcpy (makefile_name, testcase_name);
+ strcat (makefile_name, ".mk.new");
+ make_file = fopen (makefile_name, "w");
+ printf (" Note: New makefile (%s) generated.\n", makefile_name);
+ printf (" May want to update existing makefile, if any.\n");
+ fprintf (make_file, "# Generated automatically by %s\n", argv[0]);
+ fprintf (make_file, "# Make file for %s test\n", testcase_name);
+ fprintf (make_file, "\n");
+ fprintf (make_file, "CFLAGS = +DA1.1 -g\n");
+ fprintf (make_file, "\n");
+ fprintf (make_file, "# This is how to build this generator.\n");
+ fprintf (make_file, "%s.o: %s.c\n", argv[0], argv[0]);
+ fprintf (make_file, "\t$(CC) $(CFLAGS) -o %s.o -c %s.c\n", argv[0], argv[0]);
+ fprintf (make_file, "%s: %s.o\n", argv[0], argv[0]);
+ fprintf (make_file, "\t$(CC) $(CFLAGS) -o %s %s.o\n", argv[0], argv[0]);
+ fprintf (make_file, "\n");
+ fprintf (make_file, "# This is how to run this generator.\n");
+ fprintf (make_file, "# This target should be made before the 'all' target,\n");
+ fprintf (make_file, "# to ensure that the shlib sources are all available.\n");
+ fprintf (make_file, "require_shlibs: %s\n", argv[0]);
+ for (i=0; i < lib_num; i++)
+ {
+ fprintf (make_file, "\tif ! [ -a lib%2.2d_%s.c ] ; then \\\n", i, testcase_name);
+ fprintf (make_file, "\t %s ; \\\n", argv[0]);
+ fprintf (make_file, "\tfi\n");
+ }
+ fprintf (make_file, "\n");
+ fprintf (make_file, "# This is how to build all the shlibs.\n");
+ fprintf (make_file, "# Be sure to first make the require_shlibs target!\n");
+ for (i=0; i < lib_num; i++)
+ {
+ fprintf (make_file, "lib%2.2d_%s.o: lib%2.2d_%s.c\n", i, testcase_name, i, testcase_name);
+ fprintf (make_file, "\t$(CC) $(CFLAGS) +Z -o lib%2.2d_%s.o -c lib%2.2d_%s.c\n", i, testcase_name, i, testcase_name);
+ fprintf (make_file, "lib%2.2d-%s.sl: lib%2.2d-%s.o\n", i, testcase_name, i, testcase_name);
+ fprintf (make_file, "\t$(LD) $(LDFLAGS) -b -o lib%2.2d-%s.sl lib%2.2d-%s.o\n", i, testcase_name, i, testcase_name);
+ }
+ fprintf (make_file, "\n");
+fprintf (make_file, "# For convenience, here's names for all pieces of all shlibs.\n");
+ fprintf (make_file, "SHLIB_SOURCES = \\\n");
+ for (i=0; i < lib_num-1; i++)
+ fprintf (make_file, "\tlib%2.2d-%s.c \\\n", i, testcase_name);
+ fprintf (make_file, "\tlib%2.2d-%s.c\n", lib_num-1, testcase_name);
+ fprintf (make_file, "SHLIB_OBJECTS = $(SHLIB_SOURCES:.c=.o)\n");
+ fprintf (make_file, "SHLIBS = $(SHLIB_SOURCES:.c=.sl)\n");
+ fprintf (make_file, "SHLIB_NAMES = $(SHLIB_SOURCES:.c=)\n");
+ fprintf (make_file, "EXECUTABLES = $(SHLIBS) %s %s\n", argv[0], testcase_name);
+ fprintf (make_file, "OBJECT_FILES = $(SHLIB_OBJECTS) %s.o %s.o\n", argv[0], testcase_name);
+ fprintf (make_file, "\n");
+ fprintf (make_file, "shlib_objects: $(SHLIB_OBJECTS)\n");
+ fprintf (make_file, "shlibs: $(SHLIBS)\n");
+ fprintf (make_file, "\n");
+ fprintf (make_file, "# This is how to build the debuggable testcase that uses the shlibs.\n");
+ fprintf (make_file, "%s.o: %s.c\n", testcase_name, testcase_name);
+ fprintf (make_file, "\t$(CC) $(CFLAGS) -o %s.o -c %s.c\n", testcase_name, testcase_name);
+ fprintf (make_file, "%s: shlibs %s.o\n", testcase_name, testcase_name);
+ fprintf (make_file, "\t$(LD) $(LDFLAGS) -o %s -lc -L. ", testcase_name);
+ fprintf (make_file, "-c %s /opt/langtools/lib/end.o /lib/crt0.o %s.o\n", linkfile_name, testcase_name);
+ fprintf (make_file, "\n");
+ fprintf (make_file, "# Yeah, but you should first make the require_shlibs target!\n");
+ fprintf (make_file, "all: %s %s\n", testcase_name, argv[0]);
+ fprintf (make_file, "\n");
+ fprintf (make_file, "# To remove everything built via this makefile...\n");
+ fprintf (make_file, "clean:\n");
+ /* Do this carefully, to avoid hitting silly HP-UX ARG_MAX limits... */
+ fprintf (make_file, "\trm -f lib0*-%s.*\n", testcase_name);
+ fprintf (make_file, "\trm -f lib1*-%s.*\n", testcase_name);
+ fprintf (make_file, "\trm -f lib2*-%s.*\n", testcase_name);
+ fprintf (make_file, "\trm -f lib3*-%s.*\n", testcase_name);
+ fprintf (make_file, "\trm -f lib4*-%s.*\n", testcase_name);
+ fprintf (make_file, "\trm -f lib5*-%s.*\n", testcase_name);
+ fprintf (make_file, "\trm -f lib6*-%s.*\n", testcase_name);
+ fprintf (make_file, "\trm -f lib7*-%s.*\n", testcase_name);
+ fprintf (make_file, "\trm -f lib8*-%s.*\n", testcase_name);
+ fprintf (make_file, "\trm -f lib9*-%s.*\n", testcase_name);
+ fprintf (make_file, "\trm -f %s %s %s %s.c\n", argv[0], testcase_name, linkfile_name, testcase_name);
+ fprintf (make_file, "\n");
+ fclose (make_file);
+ }
+
+ /* Generate the code for the libraries.
+ */
+ for (i=0; i < lib_num; i++) {
+
+ /* Generate the names for the library.
+ */
+ sprintf (file_name, "lib%2.2d-%s.c", i, testcase_name);
+ sprintf (file_name_core, "lib%2.2d-%s", i, testcase_name);
+
+ /* Generate the source code.
+ */
+ lib_file = fopen (file_name, "w");
+ fprintf (lib_file, "/* Shared library file number %d */\n", i);
+ fprintf (lib_file, "#include <stdio.h>\n\n");
+ fprintf (lib_file, "/* The following variables largely exist to bloat this library's debug info. */\n");
+ fprintf (lib_file, "static char c_static_buf_%d [100];\n", i);
+ for (i2=0; i2<NUMBER_OF_INT_VARS; i2++)
+ fprintf (lib_file, "int i_%d_%d;\n", i, i2);
+ fprintf (lib_file, "\nint r_%d ()\n", i);
+ fprintf (lib_file, "{\n");
+ for (i2=0; i2<NUMBER_OF_INT_VARS; i2++)
+ fprintf (lib_file, " i_%d_%d = %d*%d;\n", i, i2, i2, i2);
+ fprintf (lib_file, " return 1;\n");
+ fprintf (lib_file, "}\n\n");
+ fprintf (lib_file, "/* end of generated file */\n");
+ fclose (lib_file);
+
+ /* Add a linker options line
+ */
+ fprintf (link_file, "-l%2.2d-%s\n", i, testcase_name);
+ }
+
+ /* Generate the "main" file.
+ */
+ strcpy (mainfile_name, testcase_name);
+ strcat (mainfile_name, ".c");
+ main_file = fopen (mainfile_name, "w");
+ fprintf (main_file, "/* Generated test progam with %d shared libraries. */\n\n",
+ lib_num);
+ fprintf (main_file, "#include <stdio.h>\n\n");
+
+ for (i = 0; i < lib_num; i++) {
+ fprintf (main_file, "extern int r_%d();\n", i);
+ }
+
+ fprintf (main_file, "\n");
+ fprintf (main_file, "int main()\n");
+ fprintf (main_file, "{\n");
+ fprintf (main_file, " int accum;\n");
+ fprintf (main_file, " int lib_num = %d;\n", lib_num);
+
+ for (i = 0; i < lib_num; i++) {
+ fprintf (main_file, " accum += r_%d();\n", i);
+ }
+
+ fprintf (main_file, " printf( \"Final value: %%d, should be %%d\\n\", accum, lib_num );\n\n");
+ fprintf (main_file, " return 0;\n");
+ fprintf (main_file, "}\n\n");
+ fprintf (main_file, "/* end of generated file */\n");
+ fclose (main_file);
+
+ /* Finish up the link file and the build file
+ */
+ fclose (link_file);
+}
+
+/* End of file */
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/hwwatchbus.c b/gdb/testsuite/gdb.hp/gdb.base-hp/hwwatchbus.c
new file mode 100644
index 00000000000..833d027fc87
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/hwwatchbus.c
@@ -0,0 +1,9 @@
+/* This program raises a SIGBUS signal on HP-UX when the
+ pointer "bogus_p" is dereferenced.
+ */
+int * bogus_p = (int *)3;
+
+int main()
+{
+ *bogus_p = 0xdeadbeef;
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/hwwatchbus.exp b/gdb/testsuite/gdb.hp/gdb.base-hp/hwwatchbus.exp
new file mode 100644
index 00000000000..3e529f8c0e6
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/hwwatchbus.exp
@@ -0,0 +1,83 @@
+# Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+set prms_id 0
+set bug_id 0
+
+if { [skip_hp_tests] } then { continue }
+
+if { ![istarget "hppa*-*-hpux11.*"] } {
+ verbose "HPUX h/w watch test ignored for non-hppa or pre-HP/UX-10.30 targets."
+ return 0
+}
+
+set testfile "hwwatchbus"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# build the first test case
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+# Start with a fresh gdb
+
+gdb_exit
+remote_exec build "rm -f ${binfile}.bak"
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+# We ought to be able to set a hardware watchpoint, step, and
+# get a SIGBUS or SIGSEGV signal reported.
+#
+if ![runto_main] then {
+ fail "can't run to main"
+ return 0
+}
+
+send_gdb "watch bogus_p\n"
+gdb_expect {
+ -re "Hardware watchpoint \[0-9\]*: bogus_p.*$gdb_prompt $"\
+ {pass "set h/w watchpoint"}
+ -re "$gdb_prompt $"\
+ {fail "set h/w watchpoint"}
+ timeout {fail "(timeout) set h/w watchpoint"}
+}
+
+send_gdb "step\n"
+gdb_expect {
+ -re "Program received signal (SIGBUS|SIGSEGV), (Bus error|Segmentation fault).* in main .*${srcfile}:8.*$gdb_prompt $"\
+ {pass "see real signal when h/w watchpoint set"}
+ -re "$gdb_prompt $"\
+ {fail "see real signal when h/w watchpoint set"}
+ timeout {fail "(timeout) see real signal when h/w watchpoint set"}
+}
+
+remote_exec build "mv ${binfile} ${binfile}.bak"
+return 0
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/pxdb.c b/gdb/testsuite/gdb.hp/gdb.base-hp/pxdb.c
new file mode 100644
index 00000000000..31046b5454b
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/pxdb.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+
+#ifdef PROTOTYPES
+int callee (int x)
+#else
+int callee( x )
+int x;
+#endif
+{
+ int y = x * x;
+ return (y - 2);
+}
+
+int main()
+{
+ int i;
+ for (i = 1; i < 10; i++)
+ {
+ printf( "%d ", callee( i ));
+
+ }
+ printf( " Goodbye!\n" );
+ return 0;
+}
+/* This routine exists only for aCC. The way we compile this test is
+ that we use aCC for the actual compile into the object file but then
+ use ld directly for the link. When we do this, we get an undefined
+ symbol _main(). Therefore, for aCC, we have this routine in here and
+ ld is happy. */
+
+#ifdef __cplusplus
+extern "C" {
+void _main()
+{
+}
+}
+#endif
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/pxdb.exp b/gdb/testsuite/gdb.hp/gdb.base-hp/pxdb.exp
new file mode 100644
index 00000000000..4e48107c60a
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/pxdb.exp
@@ -0,0 +1,128 @@
+# Copyright (C) 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+
+# This file is part of the gdb testsuite
+
+
+# pxdb.exp Test that gdb calls pxdb on an application
+# built without it.
+#
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+if { [skip_hp_tests] } then { continue }
+
+set testfile pxdb
+set srcfile ${testfile}.c
+set objfile ${objdir}/${subdir}/${testfile}.o
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile} "c++"] {
+ return -1;
+}
+
+if { $gcc_compiled } then { continue }
+
+# To build a non-pxdb-ed file, use
+#
+# <compile to .o file>
+# export LD_PXDB /dev/null
+# ld -o hello_no_pxdb hello.o /opt/langtools/lib/end.o /usr/ccs/lib/crt0.o -lc
+#
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+#
+# use this to debug:
+#log_user 1
+
+
+# Following should get the error message:
+#
+# ld: (Warning) Can't exec pxdb using path: /dev/null
+#
+#execute_anywhere "ksh -c \"export LD_PXDB=/dev/null\""
+
+if [istarget "hppa64-*-*"] {
+set cmdline "ksh -c \"LD_PXDB=/dev/null ld -o ${binfile} ${objfile} /opt/langtools/lib/pa20_64/crt0.o /opt/langtools/lib/pa20_64/end.o -lc\""
+} else {
+set cmdline "ksh -c \"LD_PXDB=/dev/null ld -o ${binfile} ${objfile} /usr/ccs/lib/crt0.o /opt/langtools/lib/end.o -lc\""
+}
+
+remote_exec build "rm ${binfile}"
+remote_exec build $cmdline
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# We expect to see this:
+#
+# "warning: File not processed by pxdb--about to process now.
+# "
+# ".
+# "Procedures: 7
+# "Files: 2
+# "Reading symbols from ~/c_code.dir/hello_no_pxdb...done.
+# "(gdb)
+#
+send_gdb "file ${binfile}\n"
+gdb_expect {
+
+ -re ".*warning: File not processed by pxdb.*Procedures: \[0-9\]+.*$gdb_prompt $"\
+ { pass "PXDB call" }
+
+ -re "$gdb_prompt $" {
+ if [istarget hppa*-*-hpux*] {
+ pass "Didn't call pxdb"
+ } else {
+ fail "Didn't call pxdb"
+ }
+ }
+
+ -re ".*$gdb_prompt $" { fail "Some other message" }
+
+ timeout { fail "call pxdb (timeout)" }
+}
+
+# Make sure the new data makes sense
+#
+if { ![runto callee] } then { return }
+
+send_gdb "print x\n"
+gdb_expect {
+ -re ".*= 1.*$gdb_prompt $" { pass "Good data after pxdb call" }
+ -re ".*$gdb_prompt $" { fail "No data after pxdb call" }
+ timeout { fail "(timeout)" }
+}
+
+gdb_exit
+return 0
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/reg-pa64.exp b/gdb/testsuite/gdb.hp/gdb.base-hp/reg-pa64.exp
new file mode 100644
index 00000000000..ce42c786e3d
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/reg-pa64.exp
@@ -0,0 +1,189 @@
+# Tests of wide register displays for GDB on HPPA 2.0 machines
+# Copyright 1994, 1995 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# use this to debug:
+#log_user 1
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+if { [skip_hp_tests] } { continue }
+
+if ![istarget "hppa*-*-*"] {
+ verbose "Wide register test ignored for non-hppa targets."
+ return 0
+}
+
+if ![istarget "hppa64-hp-hpux*"] {
+ verbose "reg-pa64.exp is only for PA2.0W (aka PA64)."
+ return 0
+}
+
+set testfile "reg-pa64"
+set srcfile ${testfile}.s
+set binfile ${objdir}/${subdir}/${testfile}
+
+# To build a pa 2.0 executable
+#
+# as +DA2.0W -o reg-pa64 reg-pa64.s
+# or
+# cc +DA2.0W -g -o reg-pa64 reg-pa64.s
+#
+# Don't reject if there are warnings, as we expect this warning:
+#
+# (Warning) At least one PA 2.0 object file (pa2.0_test2.o) was detected.
+# The linked output may not run on a PA 1.x system.
+#
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# test machine--there's no 2.0n architecture, so we have
+# to try to run the app.
+#
+gdb_test "break main" "Breakpoint.*" "initial set-up"
+
+send_gdb "run\n"
+gdb_expect {
+ -re ".*Executable file incompatible with hardware.*$gdb_prompt $" {
+ # Not hppa2.0 machine
+ #
+ return 0
+ }
+ -re "Cannot exec.*$gdb_prompt $" {
+ # Not hppa2.0 machine
+ #
+ return 0
+ }
+ -re ".*Starting program:.*$gdb_prompt $" {
+ pass "Ready to start test"
+ }
+ timeout {
+ fail "initial set-up, part 2 (timeout)"
+ return 0
+ }
+}
+
+# Let the program set known values. This secretly deletes
+# the breakpoint at main and re-runs to mainend.
+#
+runto mainend
+
+# Look for known values
+#
+gdb_test "info reg r1" "r1 1"
+gdb_test "info reg r4" "r4 2"
+gdb_test "info reg r5" "r5 4"
+gdb_test "info reg r6" "r6 8"
+gdb_test "info reg r7" "r7 10"
+gdb_test "info reg r8" "r8 20"
+gdb_test "info reg r9" "r9 40"
+gdb_test "info reg r10" "r10 80"
+gdb_test "info reg r11" "r11 100"
+gdb_test "info reg r12" "r12 200"
+gdb_test "info reg r13" "r13 400"
+gdb_test "info reg r14" "r14 800"
+gdb_test "info reg r15" "r15 1000"
+gdb_test "info reg r16" "r16 2000"
+
+# Two odd variants that GDB supports are:
+# "1" means "r1", and
+# "$1" means "r1"
+#
+gdb_test "info reg 1 4" "r1 1.*r4 2"
+gdb_test "info reg \$1" "r1 1"
+
+# Verify that GDB responds gracefully to a register ID number that
+# is out of range.
+#
+gdb_test "info reg 999" "999: invalid register"
+
+# Make sure the floating point status and error registers
+# don't show up as floating point numbers!
+#
+gdb_test "info reg fpsr" ".*fpsr 0.*" "fpsr"
+gdb_test "info reg fpe1" ".*fpe1 .*" "fpe1"
+gdb_test "info reg fpe2" ".*fpe2 .*" "fpe2"
+gdb_test "info reg fpe3" ".*fpe3 .*" "fpe3"
+#DTS CLLbs16708
+#info reg should recognize fpe4..fpe7.
+setup_xfail hppa64-hp-hpux* CLLbs16708
+gdb_test "info reg fpe4" ".*fpe4 .*" "fpe4"
+setup_xfail hppa64-hp-hpux* CLLbs16708
+gdb_test "info reg fpe5" ".*fpe5 .*" "fpe5"
+setup_xfail hppa64-hp-hpux* CLLbs16708
+gdb_test "info reg fpe6" ".*fpe6 .*" "fpe6"
+setup_xfail hppa64-hp-hpux* CLLbs16708
+gdb_test "info reg fpe7" ".*fpe7 .*" "fpe7"
+
+gdb_test "info reg fr4" ".*fr4.*(double precision).* 1.*"
+gdb_test "info reg fr5" ".*fr5.*(double precision).* 2.*"
+gdb_test "info reg fr6" ".*fr6.*(double precision).* 2.*"
+gdb_test "info reg fr7" ".*fr7.*(double precision).* 4.*"
+gdb_test "info reg fr8" ".*fr8.*(double precision).* 8.*"
+gdb_test "info reg fr9" ".*fr9.*(double precision).* 32.*"
+gdb_test "info reg fr10" ".*fr10.*(double precision).* 256.*"
+
+gdb_test "info reg r19" "r19 deadbeefbadcadee"
+
+# Need to add test of use of $<register-name>
+#
+# Q: How do you say a literal "$" in expect?
+# A: You say "\$". A literal "\" is "\\".
+#
+# Please note that this test will fail as long as we are running
+# in 32-bit mode: it will produce "$1 = 0xbadcadee". To fix it
+# would require building a real 64-bit gdb (expression evaluation,
+# in particular).
+#
+send_gdb "p/x \$r19\n"
+gdb_expect {
+ -re ".*= 0xdeadbeefbadcadee.*$gdb_prompt $" {
+ pass "64-bit works"
+ }
+ -re ".*= 0xbadcadee.*$gdb_prompt $" {
+ pass "32-bit extract when using PRINT; expected but not good"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "didn't print any part of right value"
+ }
+ timeout {
+ fail "timeout on print"
+ }
+}
+
+# Need to add tests of setting wide regs too. E.g.
+#
+# set $r4 = 0x1234567890123456
+# p/x $r4
+#
+
+# done
+#
+gdb_exit
+
+return 0
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/reg-pa64.s b/gdb/testsuite/gdb.hp/gdb.base-hp/reg-pa64.s
new file mode 100644
index 00000000000..4c284d79580
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/reg-pa64.s
@@ -0,0 +1,104 @@
+; assemble as "as -o reg-pa64 reg-pa64.s"
+; or
+; cc -g -o +DA2.0W
+;
+; PA-RISC 2.0 register contents test.
+;
+ .level 2.0W
+
+ .code
+ .export main,ENTRY
+ .export mainend,CODE
+ .export lab1,CODE
+ .space $TEXT$
+ .subspa $CODE$
+one
+ .align 8
+ .stringz "?\xF0\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00"
+
+main
+ .proc
+ .callinfo NO_CALLS,FRAME=0
+ .entry
+
+ ;; Test we have right register numbers
+ ;;
+ ADD %r0,%r0,%r1 ; 0
+ LDI 1,%r1 ; 1
+ ;;
+ ;; Don't put anything into r2 or r3--they are special registers.
+ ;;
+ ADD %r1,%r1,%r4 ; 2
+ ADD %r4,%r4,%r5 ; 4
+ ADD %r5,%r5,%r6 ; 8
+ ADD %r6,%r6,%r7 ; 16
+ ADD %r7,%r7,%r8 ; 32
+ ADD %r8,%r8,%r9 ; 64
+ ADD %r9,%r9,%r10 ; 128
+ ADD %r10,%r10,%r11 ; 256
+ ADD %r11,%r11,%r12 ; 512
+ ADD %r12,%r12,%r13 ; 1024
+ ADD %r13,%r13,%r14 ; 2048
+ ADD %r14,%r14,%r15 ; 4096
+ ADD %r15,%r15,%r16 ; 9192
+
+ ;; Test high bits, to be sure we show them.
+ ;;
+ LDI 0xde,%r19 ; "de"
+ DEPD,Z %r19,55,56,%r19 ; "de00"
+ LDI 0xad,%r18 ; "ad"
+ ADD %r18,%r19,%r19 ; "dead"
+ DEPD,Z %r19,55,56,%r19 ; "dead00"
+ LDI 0xbe,%r18 ; "be"
+ ADD %r18,%r19,%r19 ; "deadbe"
+ DEPD,Z %r19,55,56,%r19 ; "deadbe00"
+ LDI 0xef,%r18 ; "ef"
+ ADD %r18,%r19,%r19 ; "deadbeef"
+ ;
+ DEPD,Z %r19,55,56,%r19 ; "deadbeef00"
+ LDI 0xba,%r18 ; "ba"
+ ADD %r18,%r19,%r19 ; "deadbeefba"
+ DEPD,Z %r19,55,56,%r19 ; "deadbeefba00"
+ LDI 0xdc,%r18 ; "dc"
+ ADD %r18,%r19,%r19 ; "deadbeefbadc"
+ DEPD,Z %r19,55,56,%r19 ; "deadbeefbadc00"
+ LDI 0xad,%r18 ; "ad"
+ ADD %r18,%r19,%r19 ; "deadbeefbadcad"
+ DEPD,Z %r19,55,56,%r19 ; "deadbeefbadcad00"
+ LDI 0xee,%r18 ; "ee"
+ ADD %r18,%r19,%r19 ; "deadbeefbadcadee"
+
+lab1 ;; Test floating point registers
+ ;;
+ ;; LDIL LR'one,%r22 ;
+ ;; FLDD RR'one(%r22),%fr4 ; 1.0
+ ;; FLDD RR'one+8(%r22),%fr5 ; 2.0
+ ;; FLDD RR'one+8(%r22),%fr6 ; 2.0
+ B,L here,%r2
+ NOP
+here DEPDI 0x0,63,2,%r2
+ LDO one-here(%r2),%r2
+ FLDD 0(%r2),%fr4
+ FLDD 8(%r2),%fr5
+ FLDD 8(%r2),%fr6
+
+ FMPY,DBL %fr5,%fr6,%fr7 ; 4.0
+ FMPY,DBL %fr6,%fr7,%fr8 ; 8.0
+ FMPY,DBL %fr7,%fr8,%fr9 ; 32.0
+ FMPY,DBL %fr8,%fr9,%fr10 ; 256.0
+
+ ;; The NOP prevents anything from end.o or crt0.o from
+ ;; being appended immediately after "mainend". If that
+ ;; happens, then we may have other labels that have the
+ ;; same address as "mainend", and thus the debugger
+ ;; may symbolize this PC to something other than "mainend".
+mainend
+ NOP
+ .exit
+ .procend
+
+ .space $TEXT$
+ .subspa $CODE$
+ .subspa $LIT$ ;; <don't use> ,QUAD=0,ALIGN=8,ACCESS=0x2c,SORT=16
+ .end
+
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/reg.exp b/gdb/testsuite/gdb.hp/gdb.base-hp/reg.exp
new file mode 100644
index 00000000000..797dc854580
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/reg.exp
@@ -0,0 +1,192 @@
+# Copyright (C) 1998 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Tests of wide register displays for GDB on HPPA 2.0 machines
+
+# use this to debug:
+#log_user 1
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+if { [skip_hp_tests] } then { continue }
+
+set testfile "reg"
+
+if [istarget "hppa64-hp-hpux*"] {
+ verbose "reg.exp is not for PA2.0W."
+ return 0
+}
+set srcfile ${testfile}.s
+set binfile ${objdir}/${subdir}/${testfile}
+
+# To build a pa 2.0 executable
+#
+# as -o reg reg.s
+# or
+# cc -g -o reg reg.s
+#
+# The +DA2.0N flag doesn't seem to be needed.
+#
+# Don't reject if there are warnings, as we expect this warning:
+#
+# (Warning) At least one PA 2.0 object file (pa2.0_test2.o) was detected.
+# The linked output may not run on a PA 1.x system.
+#
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# test machine--there's no 2.0n architecture, so we have
+# to try to run the app.
+#
+send_gdb "break main\n"
+ gdb_expect {
+ -re "Breakpoint.*$gdb_prompt $" {
+ pass "initial set-up"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "initial set-up"
+ }
+ timeout {
+ fail "initial set-up (timeout)"
+ }
+ }
+
+send_gdb "run\n"
+ gdb_expect {
+ -re ".*Executable file incompatible with hardware.*$gdb_prompt $" {
+ # Not hppa2.0 machine
+ #
+ return 0
+ }
+ -re "Cannot exec.*$gdb_prompt $" {
+ # Not hppa2.0 machine
+ #
+ return 0
+ }
+ -re ".*Starting program:.*$gdb_prompt $" {
+ pass "Ready to start test"
+ }
+ timeout {
+ fail "initial set-up, part 2 (timeout)"
+ return 0
+ }
+ }
+
+# Let the program set known values. This secretly deletes
+# the breakpoint at main and re-runs to mainend.
+#
+runto mainend
+
+# Look for known values
+#
+gdb_test "info reg r1" "r1 1"
+gdb_test "info reg r4" "r4 2"
+gdb_test "info reg r5" "r5 4"
+gdb_test "info reg r6" "r6 8"
+gdb_test "info reg r7" "r7 10"
+gdb_test "info reg r8" "r8 20"
+gdb_test "info reg r9" "r9 40"
+gdb_test "info reg r10" "r10 80"
+gdb_test "info reg r11" "r11 100"
+gdb_test "info reg r12" "r12 200"
+gdb_test "info reg r13" "r13 400"
+gdb_test "info reg r14" "r14 800"
+gdb_test "info reg r15" "r15 1000"
+gdb_test "info reg r16" "r16 2000"
+
+# Two odd variants that GDB supports are:
+# "1" means "r1", and
+# "$1" means "r1"
+#
+gdb_test "info reg 1 4" "r1 1.*r4 2"
+gdb_test "info reg \$1" "r1 1"
+
+# Verify that GDB responds gracefully to a register ID number that
+# is out of range.
+#
+gdb_test "info reg 999" "999: invalid register"
+
+# Make sure the floating point status and error registers
+# don't show up as floating point numbers!
+#
+gdb_test "info reg fpsr" ".*fpsr 0.*" "fpsr"
+gdb_test "info reg fpe1" ".*fpe1 0.*" "fpe1"
+gdb_test "info reg fpe2" ".*fpe2 0.*" "fpe2"
+gdb_test "info reg fpe3" ".*fpe3 0.*" "fpe3"
+gdb_test "info reg fpe4" ".*fpe4 0.*" "fpe4"
+gdb_test "info reg fpe5" ".*fpe5 0.*" "fpe5"
+gdb_test "info reg fpe6" ".*fpe6 0.*" "fpe6"
+gdb_test "info reg fpe7" ".*fpe7 0.*" "fpe7"
+
+gdb_test "info reg fr4" ".*fr4.*(double precision).* 1"
+gdb_test "info reg fr5" ".*fr5.*(double precision).* 2"
+gdb_test "info reg fr6" ".*fr6.*(double precision).* 2"
+gdb_test "info reg fr7" ".*fr7.*(double precision).* 4"
+gdb_test "info reg fr8" ".*fr8.*(double precision).* 8"
+gdb_test "info reg fr9" ".*fr9.*(double precision).* 32"
+gdb_test "info reg fr10" ".*fr10.*(double precision).* 256"
+
+gdb_test "info reg r19" "r19 deadbeefbadcadee"
+
+# Need to add test of use of $<register-name>
+#
+# Q: How do you say a literal "$" in expect?
+# A: You say "\$". A literal "\" is "\\".
+#
+# Please note that this test will fail as long as we are running
+# in 32-bit mode: it will produce "$1 = 0xbadcadee". To fix it
+# would require building a real 64-bit gdb (expression evaluation,
+# in particular).
+#
+send_gdb "p/x \$r19\n"
+ gdb_expect {
+ -re ".*= 0xdeadbeefbadcadee.*$gdb_prompt $" {
+ pass "64-bit works"
+ }
+ -re ".*= 0xbadcadee.*$gdb_prompt $" {
+ pass "32-bit extract when using PRINT; expected but not good"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "didn't print any part of right value"
+ }
+ timeout {
+ fail "timeout on print"
+ }
+ }
+
+# Need to add tests of setting wide regs too. E.g.
+#
+# set $r4 = 0x1234567890123456
+# p/x $r4
+#
+
+# done
+#
+gdb_exit
+
+return 0
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/reg.s b/gdb/testsuite/gdb.hp/gdb.base-hp/reg.s
new file mode 100644
index 00000000000..8cc15f8f6e6
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/reg.s
@@ -0,0 +1,96 @@
+; assemble as "as -o reg reg.s"
+; or
+; cc -g -o +DA2.0N
+;
+; PA-RISC 2.0 register contents test.
+;
+ .level 2.0
+
+ .code
+ .export main,ENTRY
+ .export mainend,CODE
+ .export lab1,CODE
+ .space $TEXT$
+ .subspa $CODE$
+
+main
+ .proc
+ .callinfo NO_CALLS,FRAME=0
+ .entry
+
+ ;; Test we have right register numbers
+ ;;
+ ADD %r0,%r0,%r1 ; 0
+ LDI 1,%r1 ; 1
+ ;;
+ ;; Don't put anything into r2 or r3--they are special registers.
+ ;;
+ ADD %r1,%r1,%r4 ; 2
+ ADD %r4,%r4,%r5 ; 4
+ ADD %r5,%r5,%r6 ; 8
+ ADD %r6,%r6,%r7 ; 16
+ ADD %r7,%r7,%r8 ; 32
+ ADD %r8,%r8,%r9 ; 64
+ ADD %r9,%r9,%r10 ; 128
+ ADD %r10,%r10,%r11 ; 256
+ ADD %r11,%r11,%r12 ; 512
+ ADD %r12,%r12,%r13 ; 1024
+ ADD %r13,%r13,%r14 ; 2048
+ ADD %r14,%r14,%r15 ; 4096
+ ADD %r15,%r15,%r16 ; 9192
+
+ ;; Test high bits, to be sure we show them.
+ ;;
+ LDI 0xde,%r19 ; "de"
+ DEPD,Z %r19,55,56,%r19 ; "de00"
+ LDI 0xad,%r18 ; "ad"
+ ADD %r18,%r19,%r19 ; "dead"
+ DEPD,Z %r19,55,56,%r19 ; "dead00"
+ LDI 0xbe,%r18 ; "be"
+ ADD %r18,%r19,%r19 ; "deadbe"
+ DEPD,Z %r19,55,56,%r19 ; "deadbe00"
+ LDI 0xef,%r18 ; "ef"
+ ADD %r18,%r19,%r19 ; "deadbeef"
+ ;
+ DEPD,Z %r19,55,56,%r19 ; "deadbeef00"
+ LDI 0xba,%r18 ; "ba"
+ ADD %r18,%r19,%r19 ; "deadbeefba"
+ DEPD,Z %r19,55,56,%r19 ; "deadbeefba00"
+ LDI 0xdc,%r18 ; "dc"
+ ADD %r18,%r19,%r19 ; "deadbeefbadc"
+ DEPD,Z %r19,55,56,%r19 ; "deadbeefbadc00"
+ LDI 0xad,%r18 ; "ad"
+ ADD %r18,%r19,%r19 ; "deadbeefbadcad"
+ DEPD,Z %r19,55,56,%r19 ; "deadbeefbadcad00"
+ LDI 0xee,%r18 ; "ee"
+ ADD %r18,%r19,%r19 ; "deadbeefbadcadee"
+
+lab1 ;; Test floating point registers
+ ;;
+ LDIL LR'one,%r22 ;
+ FLDD RR'one(%r22),%fr4 ; 1.0
+ FLDD RR'one+8(%r22),%fr5 ; 2.0
+ FLDD RR'one+8(%r22),%fr6 ; 2.0
+ FMPY,DBL %fr5,%fr6,%fr7 ; 4.0
+ FMPY,DBL %fr6,%fr7,%fr8 ; 8.0
+ FMPY,DBL %fr7,%fr8,%fr9 ; 32.0
+ FMPY,DBL %fr8,%fr9,%fr10 ; 256.0
+
+ ;; The NOP prevents anything from end.o or crt0.o from
+ ;; being appended immediately after "mainend". If that
+ ;; happens, then we may have other labels that have the
+ ;; same address as "mainend", and thus the debugger
+ ;; may symbolize this PC to something other than "mainend".
+mainend
+ NOP
+ .exit
+ .procend
+
+ .space $TEXT$
+ .subspa $CODE$
+ .subspa $LIT$ ;; <don't use> ,QUAD=0,ALIGN=8,ACCESS=0x2c,SORT=16
+one
+ .align 8
+ .stringz "?\xF0\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00"
+ .end
+
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/sized-enum.c b/gdb/testsuite/gdb.hp/gdb.base-hp/sized-enum.c
new file mode 100644
index 00000000000..a6d57881f48
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/sized-enum.c
@@ -0,0 +1,43 @@
+
+enum Normal {
+ red,
+ blue,
+ green
+};
+
+short enum Small {
+ pink,
+ cyan,
+ grey
+};
+
+char enum Tiny {
+ orange,
+ yellow,
+ brown
+};
+
+
+main()
+{
+ enum Normal normal[3];
+ short enum Small small[3];
+ char enum Tiny tiny[3];
+ int i;
+
+ for (i=0; i < 3; i++)
+ {
+ normal[i] = (enum Normal) i;
+ small[i] = (short enum Small) i;
+ tiny[i] = (char enum Tiny) i;
+ }
+ normal[0] = 0; /* place to hang a breakpoint */
+}
+
+
+
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/sized-enum.exp b/gdb/testsuite/gdb.hp/gdb.base-hp/sized-enum.exp
new file mode 100644
index 00000000000..0b5b6871eff
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/sized-enum.exp
@@ -0,0 +1,165 @@
+# Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# GDB tests for sized enumerations
+
+# This is aimed at HP-UX systems. The HP C compiler
+# allows specifying "char" or "short" for an enum, to
+# indicate that it is 1 or 2 bytes long.
+
+# This file was written by Satish Pai <pai@apollo.hp.com>
+# 1997-09-24
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+if { [skip_hp_tests] } then { continue }
+
+set testfile "sized-enum"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+if { $gcc_compiled } then { continue }
+if {$hp_aCC_compiler} {continue}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+# set a breakpoint and go there
+send_gdb "break 34\n"
+gdb_expect {
+ -re "Breakpoint.*line 34.*$gdb_prompt $" { pass "set break 34" }
+ -re "$gdb_prompt $" { fail "set break 34" }
+ timeout { fail "(timeout) set break 34" }
+}
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing\\.\r\n\r\nBreakpoint \[0-9\]*, main....at.*sized-enum\\.c:34\r\n34.*\r\n$gdb_prompt $" { pass "continue" }
+ -re "$gdb_prompt $" { fail "continue" }
+ timeout { fail "(timeout) continue" }
+}
+
+# print stuff
+send_gdb "print normal\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\{red, blue, green\\}.*$gdb_prompt $" { pass "print normal" }
+ -re "$gdb_prompt $" { fail "print normal" }
+ timeout { fail "(timeout) print normal" }
+}
+send_gdb "print small\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\{pink, cyan, grey\\}.*$gdb_prompt $" { pass "print small" }
+ -re "$gdb_prompt $" { fail "print small" }
+ timeout { fail "(timeout) print small" }
+}
+send_gdb "print tiny\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = \\{orange, yellow, brown\\}.*$gdb_prompt $" { pass "print tiny" }
+ -re "$gdb_prompt $" { fail "print tiny" }
+ timeout { fail "(timeout) print tiny" }
+}
+
+# print type sizes
+send_gdb "print sizeof (Normal)\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 4.*$gdb_prompt $" { pass "print sizeof (Normal)" }
+ -re "$gdb_prompt $" { fail "print sizeof (Normal)" }
+ timeout { fail "(timeout) print sizeof (Normal)" }
+}
+send_gdb "print sizeof (Small)\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 2.*$gdb_prompt $" { pass "print sizeof (Small)" }
+ -re "$gdb_prompt $" { fail "print sizeof (Small)" }
+ timeout { fail "(timeout) print sizeof (Small)" }
+}
+send_gdb "print sizeof (Tiny)\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 1.*$gdb_prompt $" { pass "print sizeof (Tiny)" }
+ -re "$gdb_prompt $" { fail "print sizeof (Tiny)" }
+ timeout { fail "(timeout) print sizeof (Tiny)" }
+}
+
+# print types
+send_gdb "ptype normal\n"
+gdb_expect {
+ -re "type = enum Normal \\{red, blue, green\\} \\\[3\\\].*$gdb_prompt $" { pass "ptype normal" }
+ -re "$gdb_prompt $" { fail "ptype normal" }
+ timeout { fail "(timeout) ptype normal" }
+}
+send_gdb "ptype small\n"
+gdb_expect {
+ -re "type = short enum Small \\{pink, cyan, grey\\} \\\[3\\\].*$gdb_prompt $" { pass "ptype small" }
+ -re "$gdb_prompt $" { fail "ptype small" }
+ timeout { fail "(timeout) ptype small" }
+}
+send_gdb "ptype tiny\n"
+gdb_expect {
+ -re "type = char enum Tiny \\{orange, yellow, brown\\} \\\[3\\\].*$gdb_prompt $" { pass "ptype tiny" }
+ -re "$gdb_prompt $" { fail "ptype tiny" }
+ timeout { fail "(timeout) ptype tiny" }
+}
+
+# convert to int
+send_gdb "print (int) blue\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 1.*$gdb_prompt $" { pass "print (int) blue" }
+ -re "$gdb_prompt $" { fail "print (int) blue" }
+ timeout { fail "(timeout) print (int) blue" }
+}
+send_gdb "print (int) cyan\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 1.*$gdb_prompt $" { pass "print (int) cyan" }
+ -re "$gdb_prompt $" { fail "print (int) cyan" }
+ timeout { fail "(timeout) print (int) cyan" }
+}
+send_gdb "print (int) yellow\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 1.*$gdb_prompt $" { pass "print (int) yellow" }
+ -re "$gdb_prompt $" { fail "print (int) yellow" }
+ timeout { fail "(timeout) print (int) yellow" }
+}
+
+
+
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.exp b/gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.exp
new file mode 100644
index 00000000000..0a5de66d1ef
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.exp
@@ -0,0 +1,341 @@
+# Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+set prms_id 0
+set bug_id 0
+
+if { [skip_hp_tests] } then { continue }
+
+set testfile "so-thresh"
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+# This testcase is relatively large, and therefore can take awhile to
+# load. We'd best set the timeout to something suitable, or we may
+# seem to fail...
+#
+set timeout 60
+
+# Build procedure for this testcase:
+# ${srcdir}/${subdir}/so-thresh.sh ${subdir}
+# which calls,
+# make -f ${srcdir}/${subdir}/so-thresh.mk <targets> <macros>
+# which builds,
+# genso-thresh (from genso-thresh.c)
+# which generates,
+# lib00-so-thresh.c
+# lib01-so-thresh.c
+# lib02-so-thresh.c
+# so-thresh.lopt (link options file)
+# lib0*-so-thresh.sl (from .c files above)
+# so-thresh (from so-thresh.c)
+# using lib0*-so-thresh.sl and so-thresh.lopt
+#
+# Since so-thresh.mk requires SRCDIR and OBJDIR macro definitions,
+# and SRCDIR / OBJDIR could be in relative path format, we use
+# so-thresh.sh script to pin down SRCDIR / OBJDIR (using $PWD/ prefix
+# when detected relative path values for srcdir / objdir), before the
+# 'cd $subdir' call (when this can be done in TCL here, we can call
+# make directly instead).
+#
+# remote_exec build "sh -c \\\"cd ${objdir}/${subdir}\\; make -v -f ${srcdir}/${subdir}/${testfile}.mk clean require_shlibs all SRCDIR=${srcdir}/${subdir} OBJDIR=${objdir}/${subdir}\\\""
+
+remote_exec build "${srcdir}/${subdir}/${testfile}.sh $subdir"
+
+# Only HP-UX (and any other platforms using SOM shared libraries, I
+# guess) interprets the auto-solib-limit variable as a threshhold,
+# rather than a boolean that strictly enables or disables automatic
+# loading of shlib symbol tables.
+#
+# On HP-UX, it is the size threshhold (in megabytes) at which to
+# stop auto loading of symbol tables.
+#
+if ![istarget "hppa*-hp-hpux*"] then {
+ setup_xfail "*-*-*"
+}
+
+# Start with a fresh gdb
+#
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# This is a test of gdb's ability on HP-UX to stop automatically
+# loading symbols of shared libraries, when the total size of the
+# debugger's symbol table reaches a specified threshhold.
+#
+
+# On HP-UX, the help text for auto-solib-limit mentions that it
+# serves as a threshhold.
+#
+send_gdb "help set auto-solib-limit\n"
+gdb_expect {
+ -re "Set threshold .in Mb. for autoloading shared library symbols.*
+When shared library autoloading is enabled, new libraries will be loaded.*
+only until the total size of shared library symbols exceeds this.*
+threshold in megabytes. Is ignored when using .sharedlibrary.*$gdb_prompt $"\
+ {pass "help set auto-solib-limit"}
+ -re "$gdb_prompt $"\
+ {fail "help set auto-solib-limit"}
+ timeout {fail "(timeout) help set auto-solib-limit"}
+}
+
+# On HP-UX, the threshhold is by default set to 50, which means
+# 50 megabytes.
+#
+send_gdb "show auto-solib-limit\n"
+gdb_expect {
+ -re "Threshold .in Mb. for autoloading shared library symbols is $decimal.*$gdb_prompt $"\
+ {pass "show auto-solib-limit "}
+ -re "$gdb_prompt $"\
+ {fail "show auto-solib-limit "}
+ timeout {fail "(timeout) show auto-solib-limit "}
+}
+
+send_gdb "set auto-solib-limit 1\n"
+gdb_expect {
+ -re ".*$gdb_prompt $"
+ {pass "set auto-solib-limit to 1"}
+ -re ".*$gdb_prompt $"
+ {fail "set auto-solib-limit to 1"}
+ timeout {fail "(timeout) set auto-solib-limit to 1"}
+}
+
+
+# We have manually verified that our testcase exceeds 1 Mbytes
+# of heap space in GDB to hold the symbols for the main program
+# and all associated linked-against libraries. Thus, when we
+# run to the program's main, and therefore notice all the linked-
+# against shlibs, we expect to hit the threshhold.
+#
+# (Note that we're not using the expect [runto main] function here,
+# 'cause we want to match on output from the run command.
+#
+send_gdb "break main\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]* at.*$gdb_prompt $"\
+ {pass "1 set break at main"}
+ -re "$gdb_prompt $"\
+ {fail "1 set break at main"}
+ timeout {fail "(timeout) 1 set break at main"}
+}
+
+send_gdb "run\n"
+gdb_expect {
+ -re ".*warning. Symbols for some libraries have not been loaded, because.*
+doing so would exceed the size threshold specified by auto-solib-limit.*
+To manually load symbols, use the 'sharedlibrary' command.*
+To raise the threshold, set auto-solib-limit to a larger value and rerun.*
+the program.*$gdb_prompt $"\
+ {pass "run to main hit auto-solib-limit threshold"}
+ -re "$gdb_prompt $"\
+ {fail "run to main hit auto-solib-limit threshold"}
+ timeout {fail "(timeout) run to main hit auto-solib-limit threshold"}
+}
+
+# Verify that "info share" mentions something about libraries whose
+# symbols weren't loaded.
+#
+# We'll assume that at least the last two shlib's symbols weren't
+# loaded. As a side-effect of matching this pattern, the text start
+# address of the last one is captured in expect_out(1,string).
+# (we'll need it for the 'add-symbol-file' command in a nonce...)
+#
+send_gdb "info sharedlibrary\n"
+gdb_expect {
+ -re ".*lib01_$testfile.sl .*symbols not loaded.*0x\[0-9\]* (0x\[0-9a-fA-F\]*).*$gdb_prompt $"\
+ { send_gdb "add-symbol-file lib02_$testfile.sl $expect_out(1,string)\n"
+ gdb_expect {
+ -re "add symbol table.*y or n.*$"\
+ {send_gdb "y\n"
+ gdb_expect {
+ -re "$gdb_prompt $" {pass "add-symbol-file and info sharedlib"}
+ timeout {fail "(timeout) add-symbol-file and info sharedlib"}
+ }}
+ -re "$gdb_prompt $"\
+ {fail "add-symbol-file and info sharedlib"}
+ timeout {fail "(timeout) add-symbol-file and info sharedlib"}
+ }
+ }
+ -re "$gdb_prompt $" {
+ setup_xfail hppa*-*-* CHFts24108
+ fail "info sharedlibrary shows shlibs with unloaded symbols"
+ }
+ timeout {fail "(timeout) info sharedlibrary shows shlibs with unloaded symbols"}
+}
+
+# Verify that we can manually load the symbol table of a library
+# whose symbols weren't loaded. (We'll pick the last one.)
+#
+
+# I moved this test inside the one above, because the expect_out array is not ok if the
+# previous test has failed, and expect would error out (elz)
+#
+#send_gdb "add-symbol-file lib02_$testfile.sl $expect_out(1,string)\n"
+#gdb_expect {
+# -re "add symbol table.*y or n.*$"\
+# {send_gdb "y\n"
+# gdb_expect {
+# -re "$gdb_prompt $" {pass "add-symbol-file"}
+# timeout {fail "(timeout) add-symbol-file"}
+# }}
+# -re "$gdb_prompt $"\
+# {fail "add-symbol-file"}
+# timeout {fail "(timeout) add-symbol-file"}
+#}
+
+# Verify that we can manually load the symbols for all libraries
+# which weren't already loaded.
+#
+# Warning! On a machine with little free swap space, this may
+# fail!
+#
+send_gdb "sharedlibrary\n"
+gdb_expect {
+ -re "Reading symbols from.*done.*$gdb_prompt $"\
+ {pass "sharedlibrary"}
+ -re "$gdb_prompt $" {
+ setup_xfail hppa*-*-* CHFts24108
+ fail "sharedlibrary"
+ }
+ timeout {fail "(timeout) sharedlibrary"}
+}
+
+# Rerun the program, this time verifying that we can set the
+# threshhold high enough to avoid hitting it.
+#
+# It appears that gdb isn't freeing memory when rerunning, as one
+# would expect. To avoid potentially hitting a virtual memory
+# ceiling, start with a fresh gdb.
+#
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+send_gdb "break main\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]* at.*$gdb_prompt $"\
+ {pass "2 set break at main"}
+ -re "$gdb_prompt $"\
+ {fail "2 set break at main"}
+ timeout {fail "(timeout) 2 set break at main"}
+}
+
+send_gdb "set auto-solib-limit 9999\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "set auto-solib-limit threshold to practical infinity"}
+ timeout {fail "(timeout) set auto-solib-limit threshold to practical infinity"}
+}
+send_gdb "run\n"
+gdb_expect {
+ -re ".*warning. Symbols for some libraries have not been loaded, because.*
+doing so would exceed the size threshold specified by auto-solib-limit.*
+To manually load symbols, use the 'sharedlibrary' command.*
+To raise the threshold, set auto-solib-limit to a larger value and rerun.*
+the program.*$gdb_prompt $"\
+ {fail "rerun threshold at practical infinity (still hit threshold)"}
+ -re "$gdb_prompt $"\
+ {pass "rerun with threshold at practical infinity"}
+ timeout {fail "(timeout) rerun with threshold at practical infinity"}
+}
+
+# Rerun the program, this time altogether disabling the auto loading
+# feature. There should be no information at all about shared
+# libraries now.
+#
+# ??rehrauer: Personally, I'd call that a bug, since it doesn't give
+# you the ability to manually load single shlibs (you need the text
+# start address that 'info share' normall gives you). On the other
+# hand, one can easily choose to load them all...
+#
+# It appears that gdb isn't freeing memory when rerunning, as one
+# would expect. To avoid potentially hitting a virtual memory
+# ceiling, start with a fresh gdb.
+#
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+send_gdb "break main\n"
+gdb_expect {
+ -re "Breakpoint \[0-9\]* at.*$gdb_prompt $"\
+ {pass "3 set break at main"}
+ -re "$gdb_prompt $"\
+ {fail "3 set break at main"}
+ timeout {fail "(timeout) 3 set break at main"}
+}
+
+send_gdb "set auto-solib-limit 0\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "set auto-solib-limit threshold to 0"}
+ timeout {fail "(timeout) set auto-solib-limit threshold to 0"}
+}
+send_gdb "run\n"
+gdb_expect {
+ -re ".*warning. Symbols for some libraries have not been loaded, because.*
+doing so would exceed the size threshold specified by auto-solib-limit.*
+To manually load symbols, use the 'sharedlibrary' command.*
+To raise the threshold, set auto-solib-limit to a larger value and rerun.*
+the program.*$gdb_prompt $"\
+ {fail "rerun threshold at 0 (still hit threshold)"}
+ -re "$gdb_prompt $"\
+ {pass "rerun with threshold at 0"}
+ timeout {fail "(timeout) rerun with threshold at 0"}
+}
+
+# Verify that we can still manually load symbols for all libraries.
+# (We'll assume that if the last shlib's symbols are loaded, that
+# all of them were.)
+#
+# Note that we set the GDB "height" variable to prevent GDB from
+# prompting
+#
+# Warning! On a machine with little free swap space, this may
+# fail!
+#
+send_gdb "set height 9999\n"
+gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "set screen page height to practical infinity"}
+ timeout {fail "(timeout) set screen page height to practical infinity"}
+}
+send_gdb "sharedlibrary\n"
+gdb_expect {
+ -re ".*Reading symbols from .*/lib02-so-thresh\\.sl\\.\\.\\.done\\..*$gdb_prompt $"\
+ {pass "manually load all symbols"}
+ -re "$gdb_prompt $" {
+ setup_xfail hppa*-*-* CHFts24108
+ fail "manually load all symbols (CHFts24108)"
+ }
+ timeout {fail "(timeout) manually load all symbols"}
+}
+
+return 0
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.mk b/gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.mk
new file mode 100644
index 00000000000..f71e9210c7f
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.mk
@@ -0,0 +1,74 @@
+# Make file for so-thresh test
+
+OBJDIR=.
+SRCDIR=.
+CFLAGS = +DA1.1 -g
+CC=cc
+
+# This is how to build this generator.
+genso-thresh.o: ${SRCDIR}/genso-thresh.c
+ $(CC) $(CFLAGS) -o genso-thresh.o -c ${SRCDIR}/genso-thresh.c
+genso-thresh: genso-thresh.o
+ $(CC) $(CFLAGS) -o genso-thresh genso-thresh.o
+
+# This is how to run this generator.
+# This target should be made before the 'all' target,
+# to ensure that the shlib sources are all available.
+require_shlibs: genso-thresh
+ if ! [ -a lib00-so-thresh.c ] ; then \
+ genso-thresh ; \
+ fi
+ if ! [ -a lib01-so-thresh.c ] ; then \
+ genso-thresh ; \
+ fi
+ if ! [ -a lib02-so-thresh.c ] ; then \
+ genso-thresh ; \
+ fi
+
+# This is how to build all the shlibs.
+# Be sure to first make the require_shlibs target!
+lib00-so-thresh.o: lib00-so-thresh.c
+ $(CC) $(CFLAGS) +Z -o lib00-so-thresh.o -c lib00-so-thresh.c
+lib00-so-thresh.sl: lib00-so-thresh.o
+ $(LD) $(LDFLAGS) -b -o lib00-so-thresh.sl lib00-so-thresh.o
+lib01-so-thresh.o: lib01-so-thresh.c
+ $(CC) $(CFLAGS) +Z -o lib01-so-thresh.o -c lib01-so-thresh.c
+lib01-so-thresh.sl: lib01-so-thresh.o
+ $(LD) $(LDFLAGS) -b -o lib01-so-thresh.sl lib01-so-thresh.o
+lib02-so-thresh.o: lib02-so-thresh.c
+ $(CC) $(CFLAGS) +Z -o lib02-so-thresh.o -c lib02-so-thresh.c
+lib02-so-thresh.sl: lib02-so-thresh.o
+ $(LD) $(LDFLAGS) -b -o lib02-so-thresh.sl lib02-so-thresh.o
+
+
+
+
+# For convenience, here's names for all pieces of all shlibs.
+SHLIB_SOURCES = \
+ lib00-so-thresh.c \
+ lib01-so-thresh.c \
+ lib02-so-thresh.c
+
+SHLIB_OBJECTS = $(SHLIB_SOURCES:.c=.o)
+SHLIBS = $(SHLIB_SOURCES:.c=.sl)
+SHLIB_NAMES = $(SHLIB_SOURCES:.c=)
+EXECUTABLES = $(SHLIBS) genso-thresh so-thresh
+OBJECT_FILES = $(SHLIB_OBJECTS) genso-thresh.o so-thresh.o
+
+shlib_objects: $(SHLIB_OBJECTS)
+shlibs: $(SHLIBS)
+
+# This is how to build the debuggable testcase that uses the shlibs.
+so-thresh.o: so-thresh.c
+ $(CC) $(CFLAGS) -o so-thresh.o -c so-thresh.c
+so-thresh: shlibs so-thresh.o
+ $(LD) $(LDFLAGS) -o so-thresh -lc -L${OBJDIR} -c so-thresh.lopt /opt/langtools/lib/end.o /lib/crt0.o so-thresh.o
+
+# Yeah, but you should first make the require_shlibs target!
+all: so-thresh genso-thresh
+
+# To remove everything built via this makefile...
+clean:
+ rm -f lib0*-so-thresh.*
+ rm -f *.o genso-thresh so-thresh.lopt so-thresh.c
+ rm -f so-thresh
diff --git a/gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.sh b/gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.sh
new file mode 100755
index 00000000000..6b6d6ecc3cd
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.base-hp/so-thresh.sh
@@ -0,0 +1,34 @@
+#!/bin/ksh
+
+# so-thresh.sh
+#
+# This script is a "wrapper" to use the so-thresh.mk
+# Makefile. See the comments in so-thresh.exp
+# regarding why this script exists.
+
+#set -o xtrace
+#set -o verbose
+
+if [ "$srcdir" = "${srcdir#/}" ]
+then
+ srcdir="$PWD/$srcdir"
+fi
+
+if [ "$objdir" = "${objdir#/}" ]
+then
+ objdir="$PWD/$objdir"
+fi
+
+subdir="$1"
+
+HERE=$PWD
+cd $subdir
+
+MAKEFLAGS=
+make -f ${srcdir}/${subdir}/so-thresh.mk clean require_shlibs all SRCDIR=${srcdir}/${subdir} OBJDIR=${objdir}/${subdir} > ${objdir}/${subdir}/so-thresh.make.out 2>&1
+STATUS=$?
+
+cd $HERE
+echo "return STATUS is $STATUS"
+
+exit $STATUS
diff --git a/gdb/testsuite/gdb.hp/gdb.compat/Makefile.in b/gdb/testsuite/gdb.hp/gdb.compat/Makefile.in
new file mode 100644
index 00000000000..ada0f1a23ef
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.compat/Makefile.in
@@ -0,0 +1,27 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES = xdb xdb-test
+
+all:
+ @echo "Nothing to be done for all..."
+
+info:
+install-info:
+dvi:
+install:
+uninstall: force
+installcheck:
+check:
+
+clean mostlyclean:
+ -rm -f *~ *.o *.ci
+ -rm -f core $(EXECUTABLES)
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
+ -rm -f *-init.exp
+ -rm -fr *.log summary detail *.plog *.sum *.psum site.*
+
+Makefile : $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.hp/gdb.compat/average.c b/gdb/testsuite/gdb.hp/gdb.compat/average.c
new file mode 100644
index 00000000000..25ba2ee6a6c
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.compat/average.c
@@ -0,0 +1,46 @@
+/* This is a sample program for the HP WDB debugger. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef PROTOTYPES
+extern int sum(int *, int, int);
+#else
+extern int sum();
+#endif
+
+#define num 10
+
+static int my_list[num] = {3,4,2,0,2,1,8,3,6,7};
+
+#ifdef __STDC__
+void print_average(int *list, int low, int high)
+#else
+void print_average(list, low, high)
+int *list, low, high;
+#endif
+ {
+ int total = 0, num_elements = 0, average = 0;
+ total = sum(list, low, high);
+ num_elements = high - low; /* note this is an off-by-one bug */
+
+ average = total / num_elements;
+ printf("%10.d\n", average);
+ }
+
+#ifdef __STDC__
+int main(void)
+#else
+main ()
+#endif
+{
+ char c;
+ int first = 0, last = 0;
+ last = num-1;
+
+ /* Try two test cases. */
+ print_average (my_list, first, last);
+ print_average (my_list, first, last - 3);
+
+ exit(0);
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.compat/configure b/gdb/testsuite/gdb.hp/gdb.compat/configure
new file mode 100755
index 00000000000..2bccc23b215
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.compat/configure
@@ -0,0 +1,899 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=xdb1.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../../.. $srcdir/`cd $srcdir;pwd`/../../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../../.. $srcdir/`cd $srcdir;pwd`/../../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:573: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:594: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:612: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.hp/gdb.compat/configure.in b/gdb/testsuite/gdb.hp/gdb.compat/configure.in
new file mode 100644
index 00000000000..71ab87dd2c9
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.compat/configure.in
@@ -0,0 +1,15 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(xdb1.exp)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.hp/gdb.compat/sum.c b/gdb/testsuite/gdb.hp/gdb.compat/sum.c
new file mode 100644
index 00000000000..d295f7e2793
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.compat/sum.c
@@ -0,0 +1,15 @@
+/* This is a sample program for the HP/DDE debugger. */
+#include <stdio.h>
+
+#ifdef __STDC__
+int sum(int *list, int low, int high)
+#else
+int sum(list, low, high)
+int *list, low, high;
+#endif
+ {
+ int i = 0, s = 0;
+ for (i = low; i <= high; i++)
+ s += list[i];
+ return(s);
+ }
diff --git a/gdb/testsuite/gdb.hp/gdb.compat/xdb.c b/gdb/testsuite/gdb.hp/gdb.compat/xdb.c
new file mode 100644
index 00000000000..e3e3fc23e9f
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.compat/xdb.c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+
+int callee( x )
+int x;
+{
+ int y = x * x;
+ return (y - 2);
+}
+
+main()
+{
+ int i;
+ for (i = 1; i < 10; i++)
+ {
+ printf( "%d ", callee( i ));
+
+ }
+ printf( " Goodbye!\n" );
+
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.compat/xdb0.c b/gdb/testsuite/gdb.hp/gdb.compat/xdb0.c
new file mode 100644
index 00000000000..fa5c76f7418
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.compat/xdb0.c
@@ -0,0 +1,42 @@
+#include "xdb0.h"
+
+main ()
+{
+ int x;
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ x = 0;
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+ foo (x++);
+}
+
+static void
+unused ()
+{
+ /* Not used for anything */
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.compat/xdb0.h b/gdb/testsuite/gdb.hp/gdb.compat/xdb0.h
new file mode 100644
index 00000000000..c4d337c6770
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.compat/xdb0.h
@@ -0,0 +1,36 @@
+/* An include file that actually causes code to be generated in the
+ including file. This is known to cause problems on some systems. */
+
+static void
+foo (x)
+int x;
+{
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+ bar (x++);
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.compat/xdb1.c b/gdb/testsuite/gdb.hp/gdb.compat/xdb1.c
new file mode 100644
index 00000000000..51632b94d07
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.compat/xdb1.c
@@ -0,0 +1,33 @@
+void
+bar (x)
+int x;
+{
+ printf ("%d\n", x);
+
+ long_line ();
+}
+
+static void
+unused ()
+{
+ /* Not used for anything */
+}
+
+
+/* This routine has a very long line that will break searching in older
+ versions of GDB. */
+
+long_line ()
+{
+ oof (67);
+
+ oof (6789);
+
+ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 5 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 10 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 15 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 20 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 25 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 30 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 35 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 40 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 45 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 50 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 55 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 60 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* 65 */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (12); /* */ oof (12); oof (12); oof (12); oof (12); oof (12); oof (1234); /* 70 */
+}
+
+oof (n)
+ int n;
+{
+ return n + 1;
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.compat/xdb1.exp b/gdb/testsuite/gdb.hp/gdb.compat/xdb1.exp
new file mode 100644
index 00000000000..f371852c78d
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.compat/xdb1.exp
@@ -0,0 +1,78 @@
+# Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+if { [skip_hp_tests] } then { continue }
+
+global usestubs
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "xdb"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+if { $gcc_compiled } then { continue }
+
+global GDBFLAGS
+set saved_gdbflags $GDBFLAGS
+
+set GDBFLAGS "$GDBFLAGS --xdb"
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set pagination off" ""
+gdb_test "show pagination" "State of pagination is off."
+gdb_test "set pagination on" ""
+gdb_test "show pagination" "State of pagination is on."
+
+gdb_test "txbreak callee" "Breakpoint.*at.*"
+gdb_test "info break" "Num.*Type.*Disp.*Enb.*Address.*What\r\n.*breakpoint.*del.*y.*"
+
+gdb_test "xbreak callee" "Breakpoint.*at.*.*"
+gdb_test "info break" "Num.*Type.*Disp.*Enb.*Address.*What\r\n.*breakpoint.*keep.*y.*"
+
+gdb_exit
+set GDBFLAGS $saved_gdbflags
+return 0
+
+
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.hp/gdb.compat/xdb2.exp b/gdb/testsuite/gdb.hp/gdb.compat/xdb2.exp
new file mode 100644
index 00000000000..9bcdf589df8
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.compat/xdb2.exp
@@ -0,0 +1,105 @@
+# Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+if { [skip_hp_tests] } then { continue }
+
+global message
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "xdb"
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/xdb0.c" "${binfile}0.o" object {debug}] != "" } {
+ perror "Couldn't compile ${testfile}0.c to object"
+ return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/xdb1.c" "${binfile}1.o" object {debug}] != "" } {
+ perror "Couldn't compile ${testfile}1.c to object"
+ return -1
+}
+
+if { [gdb_compile "${binfile}0.o ${binfile}1.o" ${binfile} executable {debug}] != "" } {
+ perror "Couldn't link ${testfile}."
+ return -1
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+if { $gcc_compiled } then { continue }
+
+global GDBFLAGS
+set saved_gdbflags $GDBFLAGS
+set GDBFLAGS "$GDBFLAGS --xdb"
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_test "break main" ""
+gdb_test "run" ""
+gdb_test "go +2" "Breakpoint.*at.*file.*xdb0\.c, line 12\.\r\nContinuing at.*\r\nmain \\(\\) at.*xdb0\.c:12\r\n12\[ \t\]+foo \\(x\\+\\+\\);"
+gdb_test "go -2" "Note: breakpoint.*also set at pc.*\.\r\nBreakpoint.*at.*file.*xdb0\.c, line 10\.\r\nContinuing at.*\.\r\n\r\nBreakpoint.*, main \\(\\) at.*xdb0\.c:10.*"
+gdb_test "go 16" "Breakpoint.*at.*file.*xdb0\.c, line 16\.\r\nContinuing at.*\.\r\nmain \\(\\) at.*xdb0\.c:16\r\n16\[ \t\]+foo \\(x\\+\\+\\);"
+
+send_gdb "go bar\n"
+ gdb_expect {
+ -re ".*Line 5 is not in .main.. Jump anyway.*y or n. $" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "$gdb_prompt $"\
+ {pass "go bar"}
+ timeout {fail "(timeout) go bar"}
+ }
+ }
+ -re "Continuing at.*\.\r\nbar \\(x=0\\) at.*xdb1\.c:5" {}
+ timeout { perror "(timeout) go bar" ; return }
+ }
+
+# Verify that GDB responds gracefully to a "go" command without
+# an argument.
+#
+gdb_test "go" "Usage: go <location>"
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "break bar" ""
+gdb_test "run" ""
+gdb_test "backtrace full" ".*bar \\(x=0\\) at.*xdb1\.c:5\r\nNo locals\.\r\n.1.* in foo \\(x=1\\) at.*xdb0\.h:8\r\nNo locals\.\r\n.2.* in main \\(\\) at.*xdb0\.c:11\r\n.*x = 1"
+gdb_test "bt 1 full" ".*bar \\(x=0\\) at.*xdb1\.c:5\r\nNo locals\.\r\n\\(More stack frames follow\.\.\.\\)"
+gdb_test "bt full 2" ".*bar \\(x=0\\) at.*xdb1\.c:5\r\nNo locals\.\r\n.1.* in foo \\(x=1\\) at.*xdb0\.h:8\r\nNo locals\.\r\n\\(More stack frames follow\.\.\.\\)"
+
+set GDBFLAGS $saved_gdbflags
+return 0
diff --git a/gdb/testsuite/gdb.hp/gdb.compat/xdb3.exp b/gdb/testsuite/gdb.hp/gdb.compat/xdb3.exp
new file mode 100644
index 00000000000..de983d3e9c9
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.compat/xdb3.exp
@@ -0,0 +1,321 @@
+# Copyright (C) 1998 Free Software Foundation, Inc.
+
+# 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. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if { [skip_hp_tests] } then { continue }
+
+set testfile1 "average"
+set testfile2 "sum"
+set testfile "xdb-test"
+set binfile1 ${objdir}/${subdir}/${testfile1}
+set binfile2 ${objdir}/${subdir}/${testfile2}
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/average.c" "${binfile1}.o" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/sum.c" "${binfile2}.o" object {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if { [gdb_compile "${binfile1}.o ${binfile2}.o" ${binfile} executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+if { $gcc_compiled } then { continue }
+
+
+proc xdb_reinitialize_dir { subdir } {
+ global gdb_prompt
+
+ send_gdb "D\n"
+ gdb_expect {
+ -re "Reinitialize source path to empty.*y or n. " {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "Source directories searched.*$gdb_prompt $" {
+ send_gdb "D $subdir\n"
+ gdb_expect {
+ -re "Source directories searched.*$gdb_prompt $" {
+ verbose "Dir set to $subdir"
+ }
+ -re ".*$gdb_prompt $" {
+ perror "Dir \"$subdir\" failed."
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ perror "Dir \"$subdir\" failed."
+ }
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ perror "Dir \"$subdir\" failed."
+ }
+ }
+}
+
+#
+#test_search
+#
+proc test_search { } {
+ gdb_test "set listsize 4" ""
+ gdb_test "list average.c:1" "1\[ \t\]+/. This is a sample .*"
+ gdb_test "/ print_average" "17\[ \t\]+void print_average\\(int \\*list.*"
+ gdb_test "/ print_average" "19\[ \t\]+void print_average\\(list, low, high\\)"
+ gdb_test "/ print_average" "42\[ \t\]+print_average \\(my_list, first, last\\);"
+ gdb_test "? print_average" "19\[ \t\]+void print_average\\(list, low, high\\)"
+ gdb_test "? sum" "9\[ \t]+extern int sum\\(\\);"
+}
+
+#
+#test_viewing_loc
+#
+proc test_viewing_loc { } {
+ gdb_test "L" "No stack."
+ gdb_test "break main" ""
+ gdb_test "R" ""
+ gdb_test "L" "#0\[ \t\]+main \\(\\) at.*average.c:38\r\n38\[ \t\]+int first = 0, last = 0;"
+}
+
+#
+#test_dir_list
+#
+proc test_dir_list { } {
+ gdb_test "ld" "Source directories searched: .*"
+}
+
+#
+#test_list_sources
+#
+proc test_list_sources { } {
+ if [istarget "hppa64-*-*"] {
+ gdb_test "lf" "Source files for which symbols have been read in:\r\n\r\n.*average\\.c.*Source files for which symbols will be read in on demand:\r\n\r\nglobals,.*\[se\]\[un\]\[md\]\\.c.*\[se\]\[un\]\[md\]\\.c"
+ } else {
+ gdb_test "lf" "Source files for which symbols have been read in:\r\n\r\n.*average\\.c.*\r\n\r\nSource files for which symbols will be read in on demand:\r\n\r\nglobals, end\\.c,.*sum\\.c"
+ }
+}
+#
+#test_vlist
+#
+proc test_vlist { } {
+ gdb_test "v main" "34\[ \t\]+main \\(\\)\r\n35\[ \t\]+#endif\r\n36\[ \t\]+.\r\n37\[ \t\]+char c;"
+}
+
+#
+#test_va
+#
+proc test_va { } {
+ if [istarget "hppa64-*-*"] {
+ gdb_test "va main" "Dump of assembler code for function main:\r\n.*0x.* <main>:\[ \t\]+std %rp,-0x10\\(%sp\\)\r\n0x.* <main\\+4>:\[ \t\]+std,ma %r3,0xd0\\(%sp\\)\r\n.*0x.* <main\\+8>:\[ \t\]+std %r4,-0xc8\\(%sp\\)\r\n.*0x.* <main\\+12>:\[ \t\]+copy %ret1,%r3\r\n.*"
+ } else {
+ gdb_test "va main" "Dump of assembler code for function main:\r\n.*0x.* <main>:\[ \t\]+stw %rp,-0x14\\(%sr0,%sp\\)\r\n0x.* <main\\+4>:\[ \t\]+ldo 0x\[48\]0\\(%sp\\),%sp\r\n.*0x.* <main\\+8>:\[ \t\]+stw %r0,-0x.*\\(%sr0,%sp\\)\r\n.*0x.* <main\\+12>:\[ \t\]+stw %r0,-0x.*\\(%sr0,%sp\\)\r\n.*"
+ }
+}
+
+#
+#test_list_globals
+#
+proc test_list_globals { } {
+ gdb_test "lg" "All defined variables:\r\n\r\nFile globals:.*"
+# gdb_test "lg" "All defined variables:\r\n\r\nFile globals:\r\nchar __buffer.512.;\r\nint __d_eh_catch_catch;\r\nint __d_eh_catch_throw;.*"
+}
+
+#
+#test_list_registers
+#
+proc test_list_registers { } {
+ if [istarget "hppa64-*-*"] {
+ gdb_test "lr" "\[ \t\]+flags:.*r17:.*pcsqh:.*cr0:.*\r\n\[ \t\]+r1:.*r18:.*pcoqt:.*cr8:.*"
+ } else {
+ gdb_test "lr" "\[ \t\]+flags:.*r18:.*pcsqt:.*ccr:.*\r\n\[ \t\]+r1:.*r19:.*eiem:.*cr12:.*"
+ }
+ gdb_test "lr r1" "r1 .*"
+}
+
+#
+#test_backtrace
+#
+proc test_backtrace { } {
+ gdb_test "t" "#0 main \\(\\) at.*average.c:39"
+ gdb_test "T" "#0 main \\(\\) at.*average.c:39\r\n\[ \t\]+c = *.*\r\n\[ \t\]+first = 0\r\n\[ \t\]+last = 0"
+
+ gdb_test "break sum" ""
+ gdb_test "cont" ""
+ gdb_test "next"
+
+ gdb_test "t" "#0 sum \\(list=0x.*, low=0, high=9\\) at.*sum\.c:12\r\n#1 0x.* in print_average \\(list=0x.*, low=0, high=9\\) at.*average\.c:24\r\n#2 0x.* in main \\(\\) at.*average\.c:42"
+ gdb_test "t 1" "#0 sum \\(list=0x.*, low=0, high=9\\) at.*sum\.c:12\r\n\\(More stack frames follow\.\.\.\\)"
+ gdb_test "T" "#0 sum \\(list=0x.*, low=0, high=9\\) at.*sum\.c:12\r\n\[ \t\]+i = 0\r\n\[ \t\]+s = 0\r\n#1 0x.* in print_average \\(list=0x.*, low=0, high=9\\) at.*average\.c:24\r\n\[ \t\]+total = 0\r\n\[ \t\]+num_elements = 0\r\n\[ \t\]+average = 0\r\n#2 0x.* in main \\(\\) at.*average\.c:42\r\n\[ \t\]+c = *.*\r\n\[ \t\]+first = 0\r\n\[ \t\]+last = 9"
+ gdb_test "T 1" "#0 sum \\(list=0x.*, low=0, high=9\\) at.*sum\.c:12\r\n\[ \t\]+i = 0\r\n\[ \t\]+s = 0\r\n\\(More stack frames follow\.\.\.\\)"
+
+ gdb_test "V" "#0 sum \\(list=0x.*, low=0, high=9\\) at.*sum\.c:12\r\n\\12\[ \t\]+for \\(i = low;.*\\)"
+ gdb_test "V 1" "#1 0x.* in print_average \\(list=0x.*, low=0, high=9\\) at.*average\.c:24\r\n24\[ \t\]+total = sum\\(list, low, high\\);"
+}
+
+#
+# test_go
+#
+proc test_go { } {
+ gdb_test "break main" ""
+ gdb_test "R" ""
+
+ gdb_test "g +1" "Breakpoint.*at 0x.*: file.*average\.c, line 39\.\r\nContinuing at 0x.*\.\r\nmain \\(\\) at.*average\.c:39\r\n39\[ \t\]+last = num-1;"
+ gdb_test "g 42" "Breakpoint.*at 0x.*: file.*average\.c, line 42\.\r\nContinuing at 0x.*\.\r\nmain \\(\\) at.*average\.c:42\r\n42\[ \t\]+print_average \\(my_list, first, last\\);"
+
+}
+
+#
+#test_breakpoints
+#
+proc test_breakpoints { } {
+ global gdb_prompt
+
+ gdb_test "sb" ""
+ gdb_test "lb" "Num.*Type.*Disp.*Enb.*Address.*What\r\n1\[ \r\]+breakpoint\[ \r\]+keep n.*in main at.*average\.c:38.*"
+ gdb_test "ab" ""
+ gdb_test "lb" "Num.*Type.*Disp.*Enb.*Address.*What\r\n1\[ \r\]+breakpoint\[ \r\]+keep y.*in main at.*average\.c:38.*"
+ gdb_test "ba sum" "Breakpoint.*at.*: file.*sum\.c, line 11\."
+ gdb_test "cont" ""
+ gdb_test "bx" "Breakpoint.*at.*: file.*sum.c, line 15\."
+ #gdb_test "bx if (1)" "Breakpoint.*at.*: file.*sum.c, line 15\."
+ gdb_test "bx 1" "Breakpoint.*at.*: file.*average.c, line 29\."
+ gdb_test "bx 1 if (1)" "Breakpoint.*at.*: file.*average.c, line 29\."
+ gdb_test "bc 1 2" "Will ignore next 2 crossings of breakpoint 1\."
+ gdb_test "lb 1" "Num.*Type.*Disp.*Enb.*Address.*What\r\n1\[ \r\]+breakpoint\[ \r\]+keep y.*in main at.*average\.c:38\r\n.*breakpoint already hit 1 time\r\n.*ignore next 2 hits.*"
+
+ send_gdb "db\n"
+ gdb_expect {
+ -re "Delete all breakpoints.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "y\r\n$gdb_prompt $" {}
+ -re ".*$gdb_prompt $" { # This happens if there were no breakpoints
+ }
+ timeout { perror "Delete all breakpoints (timeout)" ; return }
+ }
+ send_gdb "lb\n"
+ gdb_expect {
+ -re "No breakpoints or watchpoints..*$gdb_prompt $" {}
+ -re ".*$gdb_prompt $" { perror "breakpoints not deleted" ; return }
+ timeout { perror "info breakpoints (timeout)" ; return }
+ }
+gdb_test "xbreak" "Breakpoint.*at.*file.*sum.c, line 15."
+gdb_test "xbreak print_average" "Breakpoint.*at.*file.*average.c, line 29."
+gdb_test "xbreak if (1)" "Note: breakpoint.*also set at pc.*Breakpoint.*at.*file.*sum.c, line 15."
+gdb_test "xbreak print_average if (1)" "Note: breakpoint.*also set at pc.*Breakpoint.*at.*file.*average.c, line 29."
+
+ send_gdb "lb\n"
+ gdb_expect {
+ -re "Num Type Disp Enb Address What.*breakpoint keep y.*sum.c:15.*breakpoint keep y.*average.c:29.*breakpoint keep y.*sum.c:15.*stop only if 1.*breakpoint keep y.*average.c:29.*stop only if 1.*$gdb_prompt $" {pass "lb on xbreaks"}
+ -re ".*$gdb_prompt $" { fail "breakpoints not deleted"}
+ timeout { fail "info breakpoints (timeout)" }
+ }
+
+}
+
+#
+# test_signals
+#
+proc test_signals { } {
+ gdb_test "handle SIGTERM nostop noprint" ""
+ gdb_test "z 15 s" "Signal.*Stop.*Print.*Pass to program.*Description\r\nSIGTERM.*Yes.*Yes.*Yes.*Terminated"
+ gdb_test "z 15 r" "Signal.*Stop.*Print.*Pass to program.*Description\r\nSIGTERM.*No.*No.*Yes.*Terminated"
+ gdb_test "z 15 i" "Signal.*Stop.*Print.*Pass to program.*Description\r\nSIGTERM.*No.*No.*No.*Terminated"
+ gdb_test "z 15 r" "Signal.*Stop.*Print.*Pass to program.*Description\r\nSIGTERM.*No.*Yes.*No.*Terminated"
+ gdb_test "z 15 Q" "Signal.*Stop.*Print.*Pass to program.*Description\r\nSIGTERM.*No.*No.*No.*Terminated"
+ gdb_test "lz" "Signal.*Stop.*Print.*Pass to program.*Description\r\n\r\nSIGHUP.*Yes.*"
+}
+
+
+
+# Start with a fresh gdb.
+global GDBFLAGS
+set saved_gdbflags $GDBFLAGS
+
+set GDBFLAGS "$GDBFLAGS --xdb"
+
+gdb_exit
+gdb_start
+
+xdb_reinitialize_dir $srcdir/$subdir
+
+gdb_load ${binfile}
+send_gdb "set width 0\n"
+gdb_expect -re "$gdb_prompt $"
+test_search
+test_viewing_loc
+test_dir_list
+test_list_sources
+test_vlist
+test_va
+gdb_test "next"
+gdb_test "l" "No arguments.\r\nc = *.*\r\nfirst = 0\r\nlast = 0"
+#test_list_globals
+test_list_registers
+test_backtrace
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+xdb_reinitialize_dir $srcdir/$subdir
+
+gdb_load ${binfile}
+send_gdb "set width 0\n"
+gdb_expect -re "$gdb_prompt $"
+test_go
+
+
+gdb_exit
+gdb_start
+xdb_reinitialize_dir $srcdir/$subdir
+
+gdb_load ${binfile}
+send_gdb "set width 0\n"
+gdb_expect -re "$gdb_prompt $"
+gdb_test "break main" ""
+gdb_test "R" ""
+gdb_test "S" "39\[ \t\]+last = num-1;"
+test_breakpoints
+test_signals
+gdb_test "sm" ""
+gdb_test "info set" ".*pagination: State of pagination is off.*"
+gdb_test "am" ""
+gdb_test "info set" ".*pagination: State of pagination is on.*"
+gdb_exit
+
+set GDBFLAGS $saved_gdbflags
+
+return 0
+
+
+
+
+
+
diff --git a/gdb/testsuite/gdb.hp/gdb.defects/Makefile.in b/gdb/testsuite/gdb.hp/gdb.defects/Makefile.in
new file mode 100644
index 00000000000..f0a785837c4
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.defects/Makefile.in
@@ -0,0 +1,27 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES = bs14602 bs15503 solib-d solib-d1.sl solib-d2.sl
+
+all:
+ @echo "Nothing to be done for all..."
+
+info:
+install-info:
+dvi:
+install:
+uninstall: force
+installcheck:
+check:
+
+clean mostlyclean:
+ -rm -f *~ *.o *.ci
+ -rm -f core $(EXECUTABLES)
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
+ -rm -f *-init.exp
+ -rm -fr *.log summary detail *.plog *.sum *.psum site.*
+
+Makefile : $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.hp/gdb.defects/bs14602.c b/gdb/testsuite/gdb.hp/gdb.defects/bs14602.c
new file mode 100644
index 00000000000..232b40842ea
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.defects/bs14602.c
@@ -0,0 +1,9 @@
+/* Test file for bs14602.exp */
+
+double v_double = 0;
+long double v_long_double = 12345.67890;
+
+int main () {
+ v_double = 0;
+ v_long_double = 12345.67890;
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.defects/bs14602.exp b/gdb/testsuite/gdb.hp/gdb.defects/bs14602.exp
new file mode 100644
index 00000000000..d1500f01bd0
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.defects/bs14602.exp
@@ -0,0 +1,117 @@
+# This file was written by Sue Kimura. (sue_kimura@hp.com)
+#
+# Test for CLLbs14602 -- problem with recognizing long double on 10.20.
+#
+# Source file: bs14602.c
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+if { [skip_hp_tests] } { continue }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+
+set testfile bs14602
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+# set up appropriate compile option to recognize long double
+if {$hp_aCC_compiler || $hp_cc_compiler} {
+ set ansi_option "-Ae"
+} else {
+ set ansi_option ""
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "$binfile" executable "debug {additional_flags=${ansi_option}}"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+
+# get to end of main so we can check out some stuff
+if ![runto main] {
+ perror "couldn't run to breakpoint main"
+ continue
+}
+
+gdb_test "txbreak" \
+ "Breakpoint $decimal at $hex: file .*bs14602.c, line 9." \
+ "set breakpoint at end of main"
+
+gdb_test "continue" \
+ "Continuing.\r\n$hex in main* \\(\\) at .*bs14602.c:9\r\n.*" \
+ "continue to end of main"
+
+# test some simple things about long double
+gdb_test "whatis v_long_double" \
+ "type = long double" \
+ "whatis v_long_double"
+
+gdb_test "ptype v_long_double" \
+ "type = long double" \
+ "ptype v_long_double"
+
+gdb_test "print sizeof \(long double\)" \
+ " = 16" \
+ "print sizeof long double"
+
+gdb_test "print sizeof \(v_long_double\)" \
+ " = 16" \
+ "print sizeof v_long_double"
+
+gdb_test "print v_long_double" \
+ " = 12345.67890000000079453457146883011" \
+ "print v_long_double - 1"
+
+gdb_test "set variable v_long_double = 98765.43210" \
+ "" \
+ "set variable v_long_double to constant value"
+
+gdb_test "print v_long_double" \
+ " = 98765.43210000000544823706150054932" \
+ "print v_long_double - 2"
+
+gdb_test "set variable v_double = v_long_double" \
+ "" \
+ " set variable v_double with v_long_double"
+
+gdb_test "print v_double" \
+ " = 98765.432100000005" \
+ " print v_double"
+
+#reset v_long_double
+gdb_test "set variable v_long_double = 0" \
+ "" \
+ "reset v_long_double to 0"
+
+gdb_test "print v_long_double" \
+ " = 0" \
+ "print v_long_double - 3"
+
+gdb_test "set variable v_long_double = v_double" \
+ "" \
+ " set variable v_long_double with v_long_double"
+
+gdb_test "print v_long_double" \
+ " = 98765.43210000000544823706150054932" \
+ "print v_long_double - 4 "
diff --git a/gdb/testsuite/gdb.hp/gdb.defects/bs15503.cc b/gdb/testsuite/gdb.hp/gdb.defects/bs15503.cc
new file mode 100644
index 00000000000..759bc0f8943
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.defects/bs15503.cc
@@ -0,0 +1,52 @@
+#include <string>
+#include <iostream.h>
+
+template <class T>
+class StringTest {
+public:
+ virtual void runTest();
+ void testFunction();
+};
+
+template <class T>
+void StringTest<T>:: runTest() {
+ testFunction ();
+}
+
+template <class T>
+void StringTest <T>::testFunction() {
+ // initialize s with string literal
+ cout << "in StringTest" << endl;
+ string s("I am a shot string");
+ cout << s << endl;
+
+ // insert 'r' to fix "shot"
+ s.insert(s.begin()+10,'r' );
+ cout << s << endl;
+
+ // concatenate another string
+ s += "and now a longer string";
+ cout << s << endl;
+
+ // find position where blank needs to be inserted
+ string::size_type spos = s.find("and");
+ s.insert(spos, " ");
+ cout << s << endl;
+
+ // erase the concatenated part
+ s.erase(spos);
+ cout << s << endl;
+}
+
+int main() {
+ StringTest<wchar_t> ts;
+ ts.runTest();
+}
+
+/* output:
+I am a shot string
+I am a short string
+I am a short stringand now a longer string
+I am a short string and now a longer string
+I am a short string
+*/
diff --git a/gdb/testsuite/gdb.hp/gdb.defects/bs15503.exp b/gdb/testsuite/gdb.hp/gdb.defects/bs15503.exp
new file mode 100644
index 00000000000..ef249516bd6
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.defects/bs15503.exp
@@ -0,0 +1,88 @@
+# Copyright (C) 1992 Free Software Foundation, Inc.
+
+# 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. */
+
+# Test case for CLLbs15503
+# This file was written by Sue Kimura (sue_kimura@hp.com)
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+if { [skip_hp_tests] } { continue }
+
+set testfile "bs15503"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+# The testcode is non-conforming and rejected by GCC. So bypass this
+# test completely unless we're compiling with HP's compiler.
+if {!$hp_aCC_compiler && !$hp_cc_compiler} {
+ return 0
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "debug c++"] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+
+# Start with a fresh gdb.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# Load $binfile -- there should be no warnings about "Procedure ... spans
+# file or module boundaries", "No symbols in psymtab for file ..." or
+# "File ... has ending address after starting address of next file..."
+
+if [istarget "hppa64-hp-hpux*" ] {
+ gdb_test "file $binfile" \
+ "Detected 64-bit executable..*Invoking .*gdb64..*Use \"run\" to continue execution." \
+ "loading $binfile"
+} else {
+ gdb_test "file $binfile" \
+ "Reading symbols from $binfile...done." \
+ "loading $binfile"
+}
+# Test setting breakpoint on template function
+#
+gdb_test "break StringTest<wchar_t>::testFunction" \
+ "Breakpoint $decimal at $hex: file .*bs15503.cc, line 19." \
+ "break point on function"
+
+gdb_test "run" \
+ "Starting program:.*Breakpoint $decimal, StringTest<wchar_t>::testFunction \\(this=$hex\\).*cout << \"in StringTest\" << endl;.*" \
+ "run to function breakpoint"
+
+#restart with fresh gdb
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_test "break 32" \
+ "Breakpoint $decimal at $hex: file .*bs15503.cc, line 32." \
+ "break point on line in function"
+
+gdb_test "run" \
+ ".*32.*string::size_type spos = s.find\\(\"and\"\\);.*" \
+ "run to break point on line in function"
diff --git a/gdb/testsuite/gdb.hp/gdb.defects/configure b/gdb/testsuite/gdb.hp/gdb.defects/configure
new file mode 100755
index 00000000000..7d8f044d8f6
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.defects/configure
@@ -0,0 +1,899 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=bs14602.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../../.. $srcdir/`cd $srcdir;pwd`/../../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../../.. $srcdir/`cd $srcdir;pwd`/../../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:573: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:594: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:612: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.hp/gdb.defects/configure.in b/gdb/testsuite/gdb.hp/gdb.defects/configure.in
new file mode 100644
index 00000000000..fb886862941
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.defects/configure.in
@@ -0,0 +1,15 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(bs14602.exp)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.hp/gdb.defects/solib-d.c b/gdb/testsuite/gdb.hp/gdb.defects/solib-d.c
new file mode 100644
index 00000000000..ec803fe06a5
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.defects/solib-d.c
@@ -0,0 +1,6 @@
+main()
+{
+ function_from_primary();
+ function_from_secondary();
+}
+
diff --git a/gdb/testsuite/gdb.hp/gdb.defects/solib-d.exp b/gdb/testsuite/gdb.hp/gdb.defects/solib-d.exp
new file mode 100644
index 00000000000..c0d206777e7
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.defects/solib-d.exp
@@ -0,0 +1,278 @@
+# Copyright (C) 1997 Free Software Foundation, Inc.
+
+# 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. */
+
+# This file was written by srikanth (with huge chunks borrowed from old ones)
+#
+# Regression test for
+#
+# CLLbs14756
+#
+# o catch load command does not stop for implicit loads.
+#
+# CLLbs15382
+#
+# o sharedlibrary command ignores its argument and ends
+# up loading every shared library there is ...
+#
+# CLLbs15582
+#
+# o info line non-existent-function dumps core
+# o clear non-existent function dumps core
+# o xbreak non-existent-function dumps core
+#
+# CLLbs15725
+#
+# o gdb prints static and extern variables in shlibs incorrectly.
+#
+# CLLbs16090
+#
+# o deferred breakpoints should kick in for shlibs loaded explicitly
+# with the sharedlibrary command.
+# o GDB confuses export stubs with actual function.
+#
+#
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+if { [skip_hp_tests] } { continue }
+
+set prms_id 0
+set bug_id 0
+
+# are we on a target board
+if ![isnative] {
+ return
+}
+
+# This test is presently only valid on HP-UX, since it requires
+# that we use HP-UX-specific compiler & linker options to build
+# the testcase.
+#
+setup_xfail "*-*-*"
+clear_xfail "hppa*-*-*hpux*"
+
+set prototypes 0
+set testfile "solib-d"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set testfile1 ${objdir}/${subdir}/${testfile}1.o
+set testfile2 ${objdir}/${subdir}/${testfile}2.o
+set libfile1 ${objdir}/${subdir}/${testfile}1.sl
+set libfile2 ${objdir}/${subdir}/${testfile}2.sl
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+# set up appropriate compile option to recognize long double
+if {$hp_aCC_compiler || $hp_cc_compiler} {
+ set picflag "+z"
+ set ansiflag "-Ae"
+} else {
+ set picflag "-fpic"
+ set ansiflag ""
+}
+
+
+# Build the shared libraries this test case needs.
+#
+#cd ${subdir}
+
+if { [gdb_compile "${srcdir}/${subdir}/${testfile}1.c" "${testfile1}" object "{debug additional_flags=${picflag}}"] != "" } {
+ perror "Couldn't compile ${testfile}1.c"
+ return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${testfile}2.c" "${testfile2}" object "{debug additional_flags=${picflag}}"] != ""} {
+ perror "Couldn't compile ${testfile}2.c"
+ return -1
+}
+
+remote_exec build "ld -b ${testfile1} -o ${libfile1}"
+remote_exec build "ld -b ${testfile2} -o ${libfile2}"
+
+# Build the test case
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${libfile1} ${libfile2}" "${binfile}" executable "{debug additional_flags=${ansiflag} -Wl,-aarchive}"] != "" } {
+ perror "Couldn't build ${binfile}"
+ return -1
+}
+
+# Start with a fresh gdb
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Verify that we can set a generic catchpoint on shlib loads. I.e., that
+# we can catch any shlib load, without specifying the name.
+#
+gdb_test "catch load" "Catchpoint \[0-9\]* .load <any library>.*" \
+ "set generic catch load"
+
+# Verify that implicit shlib loads are caught and reported.
+send_gdb "run\n"
+gdb_expect {
+ -re ".*solib-d1.*$gdb_prompt $" {
+ pass "Catch implicit load at startup"
+ }
+ -re "Program exited.*$gdb_prompt $" {
+ fail "CLLbs14756 || CLLbs16090 came back ???"
+ }
+ timeout { fail "(timeout) implicit library load" }
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] { fail "breakpoint at main did not trigger ?" }
+
+# verify that we print globals from shlibs correctly.
+gdb_test "p global_from_primary" " = 5678" \
+ "print global from shlib (CLLbs15725)"
+
+gdb_test "p global_from_secondary" " = 9012" \
+ "print global from shlib (CLLbs15725)"
+
+# verify that we print static variables from shlibs correctly.
+if { ![runto function_from_primary] } { return }
+gdb_test "p file_static" " = 1234" "print file static variable (CLLbs15725)"
+
+if { ![runto function_from_secondary] } { return }
+gdb_test "p local_static" " = 3456" "print local static variable (CLLbs15725)"
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set auto-solib-add 0" "" "turn off auto shlib debug loading"
+
+if ![runto_main] {
+ perror "C function calling tests suppressed"
+}
+
+# verify that "clear non-existent-symbol" does not crash
+gdb_test "clear junkfunc" "Location not found.*" \
+ "clear non-existent function does not dump core !"
+
+# verify that "info line non-existent-symbol" does not crash
+gdb_test "info line junkfunc" "Location not found.*" \
+ "info line junkfunc does not dump core !"
+
+# verify that "xbreak non-existent-symbol" does not crash
+gdb_test "xbreak junkfunc" "Function \"junkfunc\" not defined.*" \
+ "xbreak junkfunc does not dump core !"
+
+gdb_test "list function_from_primary" \
+ "No line number known for function_from_primary.*" \
+ "turning off auto shlib debug loading"
+
+send_gdb "sharedlibrary solib-d1\n"
+gdb_expect {
+ -re "Reading symbols from.*solib-d1.*$gdb_prompt $" {
+ pass "loading primary library on demand (1)"
+ }
+ -re "--Adding symbols for shared library.*solib-d1.*$gdb_prompt $" {
+ pass "loading primary library on demand (2)"
+ }
+ -re "$gdb_prompt $" { fail "loading primary library on demand (3)" }
+ timeout { fail "(timeout) loading primary library on demand" }
+}
+
+# make sure that load above of primary also did not pull in secondary.
+send_gdb "list function_from_secondary\n"
+gdb_expect {
+ -re "No symbol.*context.*$gdb_prompt $" {
+ pass "loaded only what we needed (1)"
+ }
+ -re "No line number known for function_from_secondary.*$gdb_prompt $" {
+ pass "loaded only what we needed (2)"
+ }
+ -re ".*9012.*$gdb_prompt $" { fail "Oops ! CLLbs15382 came back ?" }
+ timeout { fail "(timeout) printing global" }
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set auto-solib-add 0" "" "turn off auto shlib debug loading"
+
+gdb_test "set stop-on-solib-event 1" "" "stop-on-solib-event"
+
+# verify that we set breakpoint on the function and not the export stub
+# used to be that we set bp on the export stub of _start and thus miss
+# shlib loads in some cases (where the stub exists)
+send_gdb "run\n"
+gdb_expect {
+ -re "Stopped due to shared library event.*$gdb_prompt $" {
+ pass "stop for shlib event"
+ }
+ -re "Program exited.*$gdb_prompt $" {
+ fail "Bug CLLbs16090 came back ?"
+ }
+ timeout { fail "(timeout) stop for shlib event " }
+}
+
+gdb_test "b main" "Breakpoint 1 at.*" "set breakpoint on main"
+
+gdb_test "set stop-on-solib-event 0" "" "stop-on-solib-event (timeout)"
+
+# verify that we set breakpoint on the function and not the export stub
+gdb_test "cont" "Breakpoint 1.*main.*" "run to main"
+
+# On PA64 we read in the unwind info and linker symbol table which lets
+# us set the breakpoint and not defer it.
+send_gdb "b garbage\n"
+gdb_expect {
+ -re "Breakpoint.*deferred.*garbage.*library containing.*is loaded.*$gdb_prompt $" {
+ pass " set deferred breakpoint (1)"
+ }
+ -re "Breakpoint 2 at 0x.*$gdb_prompt $" {
+ pass " set deferred breakpoint (2)"
+ }
+ -re "$gdb_prompt $" { fail " set deferred breakpoint (3)" }
+ timeout { fail "(timeout) set deferred breakpoint" }
+}
+
+# make sure that the sharedlibrary command enables any deferred breakpoints
+# that it should.
+send_gdb "sharedlibrary lib\n"
+gdb_expect {
+ -re "Reading.*solib-d1.*$gdb_prompt $" {
+ pass "load up all shared libs (1)"
+ }
+ -re "Loading.*dld.sl.*--Adding symbols.*solib-d1.*$gdb_prompt $" {
+ pass "load up all shared libs (2)"
+ }
+ -re "$gdb_prompt $" { fail "load up all libraries" }
+ timeout { fail "(timeout) load all libraries " }
+}
+
+# do we stop at garbage ? If yes ok.
+gdb_test "cont" "Breakpoint.*garbage.*" "deferred breakpoint enabled"
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.hp/gdb.defects/solib-d1.c b/gdb/testsuite/gdb.hp/gdb.defects/solib-d1.c
new file mode 100644
index 00000000000..b6da64d21d2
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.defects/solib-d1.c
@@ -0,0 +1,12 @@
+static int file_static = 1234;
+int global_from_primary = 5678;
+
+int function_from_primary()
+{
+ garbage();
+}
+
+force_generation_of_export_stub()
+{
+ _start(); /* force main module to have an export stub for _start() */
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.defects/solib-d2.c b/gdb/testsuite/gdb.hp/gdb.defects/solib-d2.c
new file mode 100644
index 00000000000..024616baf28
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.defects/solib-d2.c
@@ -0,0 +1,11 @@
+int global_from_secondary = 9012;
+int function_from_secondary()
+{
+ static int local_static = 3456;
+ return 0;
+}
+
+garbage()
+{
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/Makefile.in b/gdb/testsuite/gdb.hp/gdb.objdbg/Makefile.in
new file mode 100644
index 00000000000..5411c46fc55
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/Makefile.in
@@ -0,0 +1,28 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES = objdbg01/test0 objdbg01/test1 objdbg02/test \
+ objdbg03/test objdbg04/test0 objdbg04/test1
+
+all:
+ @echo "Nothing to be done for all..."
+
+info:
+install-info:
+dvi:
+install:
+uninstall: force
+installcheck:
+check:
+
+clean mostlyclean:
+ -rm -f *~ objdbg*/*.o objdbg*/*.ci
+ -rm -f core $(EXECUTABLES)
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
+ -rm -f *-init.exp
+ -rm -fr *.log summary detail *.plog *.sum *.psum site.*
+
+Makefile : $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/configure b/gdb/testsuite/gdb.hp/gdb.objdbg/configure
new file mode 100755
index 00000000000..123ca4e3e73
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/configure
@@ -0,0 +1,992 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=objdbg01.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../../.. $srcdir/`cd $srcdir;pwd`/../../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../../.. $srcdir/`cd $srcdir;pwd`/../../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:573: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:594: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:612: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+subdirs="objdbg01 objdbg02 objdbg03 objdbg04"
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+if test "$no_recursion" != yes; then
+
+ # Remove --cache-file and --srcdir arguments so they do not pile up.
+ ac_sub_configure_args=
+ ac_prev=
+ for ac_arg in $ac_configure_args; do
+ if test -n "$ac_prev"; then
+ ac_prev=
+ continue
+ fi
+ case "$ac_arg" in
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ ;;
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ ;;
+ *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;;
+ esac
+ done
+
+ for ac_config_dir in objdbg01 objdbg02 objdbg03 objdbg04; do
+
+ # Do not complain, so a configure script can configure whichever
+ # parts of a large source tree are present.
+ if test ! -d $srcdir/$ac_config_dir; then
+ continue
+ fi
+
+ echo configuring in $ac_config_dir
+
+ case "$srcdir" in
+ .) ;;
+ *)
+ if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :;
+ else
+ { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; }
+ fi
+ ;;
+ esac
+
+ ac_popdir=`pwd`
+ cd $ac_config_dir
+
+ # A "../" for each directory in /$ac_config_dir.
+ ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
+
+ case "$srcdir" in
+ .) # No --srcdir option. We are building in place.
+ ac_sub_srcdir=$srcdir ;;
+ /*) # Absolute path.
+ ac_sub_srcdir=$srcdir/$ac_config_dir ;;
+ *) # Relative path.
+ ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;;
+ esac
+
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_sub_srcdir/configure; then
+ ac_sub_configure=$ac_sub_srcdir/configure
+ elif test -f $ac_sub_srcdir/configure.in; then
+ ac_sub_configure=$ac_configure
+ else
+ echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2
+ ac_sub_configure=
+ fi
+
+ # The recursion is here.
+ if test -n "$ac_sub_configure"; then
+
+ # Make the cache file name correct relative to the subdirectory.
+ case "$cache_file" in
+ /*) ac_sub_cache_file=$cache_file ;;
+ *) # Relative path.
+ ac_sub_cache_file="$ac_dots$cache_file" ;;
+ esac
+
+ echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir"
+ # The eval makes quoting arguments work.
+ if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir
+ then :
+ else
+ { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; }
+ fi
+ fi
+
+ cd $ac_popdir
+ done
+fi
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/configure.in b/gdb/testsuite/gdb.hp/gdb.objdbg/configure.in
new file mode 100644
index 00000000000..811f37e0975
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/configure.in
@@ -0,0 +1,16 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(objdbg01.exp)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../../..)
+AC_CANONICAL_SYSTEM
+AC_CONFIG_SUBDIRS(objdbg01 objdbg02 objdbg03 objdbg04)
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01.exp b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01.exp
new file mode 100644
index 00000000000..70d9d0c983d
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01.exp
@@ -0,0 +1,222 @@
+# Test reading debug information from in object files.
+
+if { [skip_hp_tests] } { continue }
+
+if { ![istarget "hppa*-*-hpux*"] } {
+ verbose "HPUX test ignored for non-hppa targets."
+ return 0
+}
+
+set testfile "test"
+set srcsubdir ${srcdir}/${subdir}/objdbg01
+set toolssubdir ${srcdir}/${subdir}/tools
+set objdbgdir ${objdir}/${subdir}/objdbg01
+set binfile ${objdbgdir}/${testfile}
+set symaddrfile ${toolssubdir}/symaddr
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+if {!$hp_aCC_compiler && !$hp_cc_compiler} {
+ return 0
+}
+
+if { [gdb_compile "${toolssubdir}/test-objdbg.cc" "${objdbgdir}/test-objdbg.o" object "debug c++ {additional_flags=-I${toolssubdir} +objdebug}"] != "" } {
+ gdb_suppress_entire_file "WARNING: +objdebug option is not supported in this compiler version, test ignored."
+}
+
+if { [gdb_compile "${srcsubdir}/x1.cc" "${objdbgdir}/x1.o" object "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile x1.cc"
+ return -1
+}
+
+if { [gdb_compile "${srcsubdir}/x2.cc" "${objdbgdir}/x2.o" object "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile x2.cc"
+ return -1
+}
+
+if { [gdb_compile "${srcsubdir}/x3.cc" "${objdbgdir}/x3.o" object "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile x3.cc"
+ return -1
+}
+
+if { [gdb_compile "${objdbgdir}/x1.o ${objdbgdir}/x2.o ${objdbgdir}/x3.o" "${binfile}0" executable "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile ${binfile}0"
+ return -1
+}
+
+if {[gdb_compile "${objdbgdir}/x3.o ${objdbgdir}/x2.o ${objdbgdir}/x1.o" "${binfile}1" executable "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile ${binfile}1"
+ return -1
+}
+
+# Test two executables. The first has x1.cc linked first, the second
+# has x3.cc linked first. The difference is that in the first one,
+# the Info<PP> instantiation from x1.cc is taken, in the second, its
+# from x3.cc.
+
+for {set filenum 0} {$filenum < 2} {incr filenum 1} {
+
+ # Lets test some commons
+ # Need to restart each to to make sure objects are not loaded
+ # Also cross check the address with what is actually in the
+ # object file (call the executable ${symaddrfile} to retrieve the
+ # information).
+
+ set exec_output [lindex [remote_exec build "${symaddrfile} ${binfile}${filenum} acomm"] 1]
+ regsub -all "\[\r\n\]" ${exec_output} "" exec_output
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir ${srcsubdir}
+ gdb_load ${binfile}${filenum}
+ gdb_test "p &acomm" "..* = \\(int \[*\]\\) 0x${exec_output}.*"
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir ${srcsubdir}
+ gdb_load ${binfile}${filenum}
+ gdb_test "b main" "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file ..*/x1.cc, line 20."
+ gdb_test "run" "Starting program:.*Breakpoint \[0-9\]+, main .*/x1.cc:20.*20.*acomm.*=.*1.*"
+ gdb_test "s 1" "21.*"
+ gdb_test "p acomm" ".* = 1.*"
+ gdb_test "p &acomm" "..* = \\(int \[*\]\\) 0x${exec_output}.*"
+
+ # Step through each line.
+ # Do this three times.
+ # First round: Test that things are okay after printing commons
+ # above.
+ # Second round: Restart gdb and make sure we can walk through
+ # Third round: Do NOT restrart gdb to verify that the debug information
+ # was not messed up by loading additional object files from
+ # the first run through.
+ for {set i 0} {$i < 3} {incr i 1} {
+ if $i==1 then {
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir ${srcsubdir}
+ gdb_load ${binfile}${filenum}
+ }
+ if $i!=2 then {
+ gdb_test "b main" \
+ "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file ..*/x1.cc, line 20."
+ }
+ if $i!=0 then {
+ gdb_test "run" \
+ "Starting program:.*Breakpoint \[0-9\]+, main .*/x1.cc:20.*"
+ gdb_test "s 1" "21.*"
+ }
+ gdb_test "s 1" "Info<PP>::p .*/x3.h:11.*"
+ gdb_test "s 1" "PP::print .*/x2.cc:8.*"
+ gdb_test "s 1" ".*9.*"
+ gdb_test "s 1" "Info<PP>::p .*/x3.h:12.*"
+ gdb_test "s 1" "main .*/x1.cc:22.*"
+ gdb_test "s 1" "foo .*/x3.cc:5.*"
+ gdb_test "s 1" "Info<PP>::p .*/x3.h:11.*"
+ gdb_test "s 1" "PP::print .*/x2.cc:8.*"
+ gdb_test "s 1" ".*9.*"
+ gdb_test "s 1" "Info<PP>::p .*/x3.h:12.*"
+ gdb_test "s 1" "foo .*/x3.cc:6.*"
+ gdb_test "s 1" "Info<QQ>::p .*/x3.h:11.*"
+ gdb_test "s 1" "QQ::print .*/x2.cc:13.*"
+ gdb_test "s 1" ".*14.*"
+ gdb_test "s 1" "Info<QQ>::p .*/x3.h:12.*"
+ gdb_test "s 1" "foo .*/x3.cc:7.*"
+ gdb_test "s 1" "main .*/x1.cc:24.*"
+ gdb_test "s 1" ".*25.*"
+ if [istarget "hppa64-*-*"] {
+ gdb_test "s 1" "0x\[0-9a-f\]+ in .*"
+ gdb_test "c" ".*Program exited normally.*"
+ } else {
+ gdb_test "s 1" "0x\[0-9a-f\]+ in _start .*"
+ gdb_test "s 1" ".*Program exited normally.*"
+ }
+ }
+
+ # Test various ptypes, and combinations of them
+ # Test things multiple times in each set to make sure that the debug
+ # information did not get messed up.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir ${srcsubdir}
+ gdb_load ${binfile}${filenum}
+ gdb_test "ptype QQ" "type = (class |)QQ {..*void print( |)..*}.*"
+ gdb_test "ptype PP" "type = (class |)PP {..*void print( |)..*}.*"
+ gdb_test "ptype QQ" "type = (class |)QQ {..*void print( |)..*}.*"
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir ${srcsubdir}
+ gdb_load ${binfile}${filenum}
+ gdb_test "ptype PP" "type = (class |)PP {..*void print( |)..*}.*"
+ gdb_test "ptype QQ" "type = (class |)QQ {..*void print( |)..*}.*"
+ gdb_test "ptype PP" "type = (class |)PP {..*void print( |)..*}.*"
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir ${srcsubdir}
+ gdb_load ${binfile}${filenum}
+ gdb_test "ptype Info<QQ>" "type = (class |)Info<QQ> {..*void p( |)..*}.*"
+ gdb_test "ptype Info<PP>" "type = (class |)Info<PP> {..*void p( |)..*}.*"
+ gdb_test "ptype Info<QQ>" "type = (class |)Info<QQ> {..*void p( |)..*}.*"
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir ${srcsubdir}
+ gdb_load ${binfile}${filenum}
+ gdb_test "ptype Info<PP>" "type = (class |)Info<PP> {..*void p( |)..*}.*"
+ gdb_test "ptype Info<QQ>" "type = (class |)Info<QQ> {..*void p( |)..*}.*"
+ gdb_test "ptype Info<PP>" "type = (class |)Info<PP> {..*void p( |)..*}.*"
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir ${srcsubdir}
+ gdb_load ${binfile}${filenum}
+ gdb_test "ptype Info" "type = template <..*> (class |)Info {..*}.*"
+ gdb_test "ptype Info<PP>" "type = (class |)Info<PP> {..*void p( |)..*}.*"
+ gdb_test "ptype Info<QQ>" "type = (class |)Info<QQ> {..*void p( |)..*}.*"
+ gdb_test "ptype Info" "type = template <..*> (class |)Info {..*}.*"
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir ${srcsubdir}
+ gdb_load ${binfile}${filenum}
+ gdb_test "ptype class QQ" "type = (class |)QQ {..*void print( |)..*}.*"
+ gdb_test "ptype class PP" "type = (class |)PP {..*void print( |)..*}.*"
+ gdb_test "ptype class QQ" "type = (class |)QQ {..*void print( |)..*}.*"
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir ${srcsubdir}
+ gdb_load ${binfile}${filenum}
+ gdb_test "ptype class PP" "type = (class |)PP {..*void print( |)..*}.*"
+ gdb_test "ptype class QQ" "type = (class |)QQ {..*void print( |)..*}.*"
+ gdb_test "ptype class PP" "type = (class |)PP {..*void print( |)..*}.*"
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir ${srcsubdir}
+ gdb_load ${binfile}${filenum}
+ gdb_test "ptype class Info<QQ>" \
+ "type = (class |)Info<QQ> {..*void p( |)..*}.*"
+ gdb_test "ptype class Info<PP>" \
+ "type = (class |)Info<PP> {..*void p( |)..*}.*"
+ gdb_test "ptype class Info<QQ>" \
+ "type = (class |)Info<QQ> {..*void p( |)..*}.*"
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir ${srcsubdir}
+ gdb_load ${binfile}${filenum}
+ gdb_test "ptype class Info<PP>" \
+ "type = (class |)Info<PP> {..*void p( |)..*}.*"
+ gdb_test "ptype class Info<QQ>" \
+ "type = (class |)Info<QQ> {..*void p( |)..*}.*"
+ gdb_test "ptype class Info<PP>" \
+ "type = (class |)Info<PP> {..*void p( |)..*}.*"
+}
+
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x1.cc b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x1.cc
new file mode 100644
index 00000000000..0de3153d9cc
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x1.cc
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include "x3.h"
+
+extern void foo();
+
+extern int acomm;
+
+int main3()
+{
+ return 1;
+}
+
+int main2()
+{
+ return 0;
+}
+
+int main()
+{
+ acomm = 1;
+ (new Info<PP>)->p(new PP);
+ foo();
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x2.cc b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x2.cc
new file mode 100644
index 00000000000..af588fbc00a
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x2.cc
@@ -0,0 +1,14 @@
+#include "x3.h"
+#include <stdio.h>
+
+int acomm;
+
+void PP::print()
+{
+ printf("In PP::print()\n");
+}
+
+void QQ::print()
+{
+ printf("In QQ::print()\n");
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x3.cc b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x3.cc
new file mode 100644
index 00000000000..88fe5453ec6
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x3.cc
@@ -0,0 +1,7 @@
+#include "x3.h"
+
+void foo()
+{
+ (new Info<PP>)->p(new PP);
+ (new Info<QQ>)->p(new QQ);
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x3.h b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x3.h
new file mode 100644
index 00000000000..d03a5503c5e
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg01/x3.h
@@ -0,0 +1,22 @@
+
+template <class T>
+class Info {
+public:
+ void p(T *x);
+};
+
+template <class T>
+void Info<T>::p(T *x)
+{
+ x->print();
+}
+
+class PP {
+public:
+ void print();
+};
+
+class QQ {
+public:
+ void print();
+};
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02.exp b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02.exp
new file mode 100644
index 00000000000..fcd0fdc9b44
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02.exp
@@ -0,0 +1,85 @@
+# Test reading debug information from in object files.
+
+if { [skip_hp_tests] } { continue }
+
+if { ![istarget "hppa*-*-hpux*"] } {
+ verbose "HPUX test ignored for non-hppa targets."
+ return 0
+}
+
+set testfile "test"
+set srcsubdir ${srcdir}/${subdir}/objdbg02
+set objdbgdir ${objdir}/${subdir}/objdbg02
+set binfile ${objdbgdir}/${testfile}
+set toolssubdir ${srcdir}/${subdir}/tools
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+if {!$hp_aCC_compiler && !$hp_cc_compiler} {
+ return 0
+}
+
+if { [gdb_compile "${toolssubdir}/test-objdbg.cc" "${objdbgdir}/test-objdbg.o" object "debug c++ {additional_flags=-I${toolssubdir} +objdebug}"] != "" } {
+ gdb_suppress_entire_file "WARNING: +objdebug option is not supported in this compiler version, test ignored."
+}
+
+if { [gdb_compile "${srcsubdir}/x1.cc" "${objdbgdir}/x1.o" object "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile x1.cc"
+ return -1
+}
+
+if { [gdb_compile "${srcsubdir}/x2.cc" "${objdbgdir}/x2.o" object "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile x2.cc"
+ return -1
+}
+
+if { [gdb_compile "${srcsubdir}/x3.cc" "${objdbgdir}/x3.o" object "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile x3.cc"
+ return -1
+}
+
+remote_exec build "rm -f ${objdbgdir}/test.a"
+set status [remote_exec build "ar cr ${objdbgdir}/test.a ${objdbgdir}/x2.o ${objdbgdir}/x3.o"]
+if { [lindex $status 0] != 0 } {
+ perror "Couldn't compile test.a"
+ return -1
+}
+remote_exec build "rm -f ${objdbgdir}/x2.o ${objdbgdir}/x3.o"
+
+if { [gdb_compile "${objdbgdir}/x1.o ${objdbgdir}/test.a" "$binfile" executable "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile ${binfile}"
+ return -1
+}
+
+# Test loading debug information from an archive file
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir ${srcsubdir}
+gdb_load ${binfile}
+
+gdb_test "b main" "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file ..*/x1.cc, line 12."
+gdb_test "run" "Starting program:.*Breakpoint \[0-9\]+, main .*/x1.cc:12.*"
+gdb_test "s 1" ".*13.*"
+gdb_test "s 1" "foo1 .*/x2.cc:15.*"
+gdb_test "s 1" ".*16.*"
+gdb_test "s 1" "foo2 .*/x2.cc:10.*"
+gdb_test "s 1" ".*11.*"
+gdb_test "s 1" "foo1 .*/x2.cc:17.*"
+gdb_test "s 1" "main .*/x1.cc:14.*"
+gdb_test "s 1" "foo3 .*/x3.cc:5.*"
+gdb_test "s 1" ".*6.*"
+gdb_test "s 1" "main .*/x1.cc:15.*"
+gdb_test "s 1" ".*16.*"
+if [istarget "hppa64-*-*"] {
+ gdb_test "s 1" "0x\[0-9a-f\]+ in .*START.*"
+ gdb_test "c" ".*Program exited normally.*"
+} else {
+ gdb_test "s 1" "0x\[0-9a-f\]+ in _start .*"
+ gdb_test "s 1" ".*Program exited normally.*"
+}
+
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x1.cc b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x1.cc
new file mode 100644
index 00000000000..7ec0cf18405
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x1.cc
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+extern void foo1();
+extern void foo3();
+
+struct foo_type;
+
+int main()
+{
+ struct foo_type *x;
+
+ printf("In main.\n");
+ foo1();
+ foo3();
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x2.cc b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x2.cc
new file mode 100644
index 00000000000..627f02d2baf
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x2.cc
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+struct foo_type {
+ int t1;
+ int t2;
+};
+
+static void foo2()
+{
+ printf("In foo2.\n");
+}
+
+void foo1()
+{
+ printf("In foo1.\n");
+ foo2();
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x3.cc b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x3.cc
new file mode 100644
index 00000000000..d03ea5146a9
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg02/x3.cc
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void foo3()
+{
+ printf("In foo3.\n");
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03.exp b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03.exp
new file mode 100644
index 00000000000..1e549476f31
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03.exp
@@ -0,0 +1,164 @@
+# Test reading debug information from in object files.
+
+if { [skip_hp_tests] } { continue }
+
+if { ![istarget "hppa*-*-hpux*"] } {
+ verbose "HPUX test ignored for non-hppa targets."
+ return 0
+}
+
+set testfile "test"
+set srcsubdir ${srcdir}/${subdir}/objdbg03
+set objdbgdir ${objdir}/${subdir}/objdbg03
+set binfile ${objdbgdir}/${testfile}
+set toolssubdir ${srcdir}/${subdir}/tools
+if [istarget "hppa64-*-*"] {
+ set symaddrfile ${toolssubdir}/symaddr.pa64
+} else {
+ set symaddrfile ${toolssubdir}/symaddr
+}
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+if {!$hp_aCC_compiler && !$hp_cc_compiler} {
+ return 0
+}
+
+if { [gdb_compile "${toolssubdir}/test-objdbg.cc" "${objdbgdir}/test-objdbg.o" object "debug c++ {additional_flags=-I${toolssubdir} +objdebug}"] != "" } {
+ gdb_suppress_entire_file "WARNING: +objdebug option is not supported in this compiler version, test ignored."
+}
+
+if { [gdb_compile "${srcsubdir}/x1.cc" "${objdbgdir}/x1.o" object "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile x1.cc"
+ return -1
+}
+
+if { [gdb_compile "${srcsubdir}/x2.cc" "${objdbgdir}/x2.o" object "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile x2.cc"
+ return -1
+}
+
+if { [gdb_compile "${srcsubdir}/x3.cc" "${objdbgdir}/x3.o" object "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile x3.cc"
+ return -1
+}
+
+if { [gdb_compile "${objdbgdir}/x1.o ${objdbgdir}/x2.o ${objdbgdir}/x3.o" "${binfile}" executable "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile ${binfile}"
+ return -1
+}
+
+#
+# Test some normal commons
+#
+
+# Print the types
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir ${srcsubdir}
+gdb_load ${binfile}
+
+gdb_test "ptype common1" "type = int"
+gdb_test "ptype common2" "type = int"
+gdb_test "ptype common3" "type = int"
+gdb_test "ptype data1" "type = int"
+gdb_test "ptype data2" "type = int"
+gdb_test "ptype data3" "type = int"
+gdb_test "ptype common11" "type = int"
+gdb_test "ptype common10" "type = int"
+gdb_test "ptype data10" "type = int"
+gdb_test "ptype data11" "type = int"
+
+# Print the values
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir ${srcsubdir}
+gdb_load ${binfile}
+
+gdb_test "b main" "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file ..*/x1.cc, line 11."
+gdb_test "run" "Starting program:.*Breakpoint \[0-9\]+, main .*/x1.cc:11.*"
+gdb_test "p data1" "..* = 1"
+gdb_test "p data2" "..* = 2"
+gdb_test "p data3" "..* = 3"
+gdb_test "p data10" "..* = 10"
+gdb_test "p data11" "..* = 11"
+gdb_test "n" ".*12.*"
+gdb_test "p common11" "..* = 11"
+
+gdb_test "s 1" "foo .*/x3.cc:15.*"
+gdb_test "s 4" ".*20.*"
+gdb_test "p data4" "..* = 4"
+gdb_test "p common4" "..* = 4"
+gdb_test "n" ".*21.*"
+
+gdb_test "n" "main .*/x1.cc:14.*"
+gdb_test "p common1" "..* = 1"
+gdb_test "p common2" "..* = 2"
+gdb_test "p common3" "..* = 3"
+
+# Verify that addresses match those in the executable
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir ${srcsubdir}
+gdb_load ${binfile}
+
+set exec_output_data1 [lindex [remote_exec build "${symaddrfile} ${binfile} data1"] 1]
+regsub -all "\[\r\n\]" ${exec_output_data1} "" exec_output_data1
+
+set exec_output_data2 [lindex [remote_exec build "${symaddrfile} ${binfile} data2"] 1]
+regsub -all "\[\r\n\]" ${exec_output_data2} "" exec_output_data2
+
+set exec_output_data3 [lindex [remote_exec build "${symaddrfile} ${binfile} data3"] 1]
+regsub -all "\[\r\n\]" ${exec_output_data3} "" exec_output_data3
+
+set exec_output_data10 [lindex [remote_exec build "${symaddrfile} ${binfile} data10"] 1]
+regsub -all "\[\r\n\]" ${exec_output_data10} "" exec_output_data10
+
+set exec_output_data11 [lindex [remote_exec build "${symaddrfile} ${binfile} data11"] 1]
+regsub -all "\[\r\n\]" ${exec_output_data11} "" exec_output_data11
+
+set exec_output_common1 [lindex [remote_exec build "${symaddrfile} ${binfile} common1"] 1]
+regsub -all "\[\r\n\]" ${exec_output_common1} "" exec_output_common1
+
+set exec_output_common2 [lindex [remote_exec build "${symaddrfile} ${binfile} common2"] 1]
+regsub -all "\[\r\n\]" ${exec_output_common2} "" exec_output_common2
+
+set exec_output_common3 [lindex [remote_exec build "${symaddrfile} ${binfile} common3"] 1]
+regsub -all "\[\r\n\]" ${exec_output_common3} "" exec_output_common3
+
+set exec_output_common10 [lindex [remote_exec build "${symaddrfile} ${binfile} common10"] 1]
+regsub -all "\[\r\n\]" ${exec_output_common10} "" exec_output_common10
+
+set exec_output_common11 [lindex [remote_exec build "${symaddrfile} ${binfile} common11"] 1]
+regsub -all "\[\r\n\]" ${exec_output_common11} "" exec_output_common11
+
+if [istarget "hppa64-*-*"] {
+ gdb_test "p &data1" "..* = \\(int \[*\]\\) ${exec_output_data1}"
+ gdb_test "p &data2" "..* = \\(int \[*\]\\) ${exec_output_data2}"
+ gdb_test "p &data3" "..* = \\(int \[*\]\\) ${exec_output_data3}"
+ gdb_test "p &data10" "..* = \\(int \[*\]\\) ${exec_output_data10}"
+ gdb_test "p &data11" "..* = \\(int \[*\]\\) ${exec_output_data11}"
+ gdb_test "p &common1" "..* = \\(int \[*\]\\) ${exec_output_common1}"
+ gdb_test "p &common2" "..* = \\(int \[*\]\\) ${exec_output_common2}"
+ gdb_test "p &common3" "..* = \\(int \[*\]\\) ${exec_output_common3}"
+ gdb_test "p &common10" "..* = \\(int \[*\]\\) ${exec_output_common10}"
+ gdb_test "p &common11" "..* = \\(int \[*\]\\) ${exec_output_common11}"
+} else {
+ gdb_test "p &data1" "..* = \\(int \[*\]\\) 0x${exec_output_data1}"
+ gdb_test "p &data2" "..* = \\(int \[*\]\\) 0x${exec_output_data2}"
+ gdb_test "p &data3" "..* = \\(int \[*\]\\) 0x${exec_output_data3}"
+ gdb_test "p &data10" "..* = \\(int \[*\]\\) 0x${exec_output_data10}"
+ gdb_test "p &data11" "..* = \\(int \[*\]\\) 0x${exec_output_data11}"
+ gdb_test "p &common1" "..* = \\(int \[*\]\\) 0x${exec_output_common1}"
+ gdb_test "p &common2" "..* = \\(int \[*\]\\) 0x${exec_output_common2}"
+ gdb_test "p &common3" "..* = \\(int \[*\]\\) 0x${exec_output_common3}"
+ gdb_test "p &common10" "..* = \\(int \[*\]\\) 0x${exec_output_common10}"
+ gdb_test "p &common11" "..* = \\(int \[*\]\\) 0x${exec_output_common11}"
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x1.cc b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x1.cc
new file mode 100644
index 00000000000..84231b08bea
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x1.cc
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+extern int foo();
+extern int common3;
+extern int data3;
+extern int common11;
+extern int data11;
+
+int main()
+{
+ common11 = 11;
+ printf("In main: %d %d %d\n", data3, common3, foo(), common11, data11);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x2.cc b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x2.cc
new file mode 100644
index 00000000000..165cb85d2e3
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x2.cc
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int common10;
+int common11;
+
+int data10 = 10;
+int data11 = 11;
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x3.cc b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x3.cc
new file mode 100644
index 00000000000..80d38c75e38
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg03/x3.cc
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int common1;
+int common2;
+int common3;
+static int common4;
+
+int data1 = 1;
+int data2 = 2;
+int data3 = 3;
+static int data4 = 4;
+
+int foo()
+{
+ common1 = 1;
+ common2 = 2;
+ common3 = 3;
+ common4 = 4;
+
+ return data1 + data2 + data3 + data4 + common1 + common2 + common3 + common4;
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04.exp b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04.exp
new file mode 100644
index 00000000000..c57f4c0e056
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04.exp
@@ -0,0 +1,65 @@
+# Test reading debug information from in object files.
+
+if { [skip_hp_tests] } { continue }
+
+if { ![istarget "hppa*-*-hpux*"] } {
+ verbose "HPUX test ignored for non-hppa targets."
+ return 0
+}
+
+set testfile "test"
+set srcsubdir ${srcdir}/${subdir}/objdbg04
+set objdbgdir ${objdir}/${subdir}/objdbg04
+set binfile ${objdbgdir}/${testfile}
+set toolssubdir ${srcdir}/${subdir}/tools
+set symaddrfile ${toolssubdir}/symaddr
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+if {!$hp_aCC_compiler && !$hp_cc_compiler} {
+ return 0
+}
+
+if { [gdb_compile "${toolssubdir}/test-objdbg.cc" "${objdbgdir}/test-objdbg.o" object "debug c++ {additional_flags=-I${toolssubdir} +objdebug}"] != "" } {
+ gdb_suppress_entire_file "WARNING: +objdebug option is not supported in this compiler version, test ignored."
+}
+
+if { [gdb_compile "${srcsubdir}/x1.cc" "${objdbgdir}/x1.o" object "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile x1.cc"
+ return -1
+}
+
+if { [gdb_compile "${srcsubdir}/x2.cc" "${objdbgdir}/x2.o" object "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile x2.cc"
+ return -1
+}
+
+if { [gdb_compile "${objdbgdir}/x1.o ${objdbgdir}/x2.o" "${binfile}0" executable "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile x1.cc"
+ return -1
+}
+
+if { [gdb_compile "${objdbgdir}/x2.o ${objdbgdir}/x1.o" "${binfile}1" executable "debug c++ {additional_flags=-I${srcsubdir} +objdebug}"] != "" } {
+ perror "Couldn't compile x1.cc"
+ return -1
+}
+
+# Test two executables. The first has x1.cc linked first, the second
+# has x2.cc linked first. The difference is which COMDAT section was
+# picked.
+
+for {set filenum 0} {$filenum < 2} {incr filenum 1} {
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir ${srcsubdir}
+ gdb_load ${binfile}${filenum}
+
+ gdb_test "ptype Adder" "type = template <class T> (class |)Adder {..*T val.*;.*}(.*template instantiations:.*Adder<int>|)"
+ gdb_test "ptype Adder<int>" "type = (class |)Adder<int> {.*private:.*int val;.*public:.*void set( |)\\(int\\);.*int get( |)\\(void\\);.*int add( |)\\(int\\);.*}"
+ gdb_test "ptype Adder" "type = template <class T> (class |)Adder {..*T val.*;.*}(.*template instantiations:.*Adder<int>|)"
+
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x.h b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x.h
new file mode 100644
index 00000000000..9df8ef98556
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x.h
@@ -0,0 +1,30 @@
+template <class T>
+class Adder {
+public:
+ void set(T);
+ T get();
+ T add(T);
+
+private:
+ T val;
+};
+
+template <class T>
+void Adder<T>::set(T new_val)
+{
+ val = new_val;
+}
+
+template <class T>
+T Adder<T>::get()
+{
+ return val;
+}
+
+template <class T>
+T Adder<T>::add(T new_val)
+{
+ val += new_val;
+ return val;
+}
+
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x1.cc b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x1.cc
new file mode 100644
index 00000000000..1f284b2ab0e
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x1.cc
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include "x.h"
+
+template class Adder<int>;
+
+int main()
+{
+ Adder<int> add;
+
+ add.set(3);
+ add.add(3);
+ printf("In main: %d\n", add.get());
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x2.cc b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x2.cc
new file mode 100644
index 00000000000..29eea75d233
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/objdbg04/x2.cc
@@ -0,0 +1,3 @@
+#include "x.h"
+
+template class Adder<int>;
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/tools/symaddr b/gdb/testsuite/gdb.hp/gdb.objdbg/tools/symaddr
new file mode 100755
index 00000000000..032bb9fdd7e
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/tools/symaddr
@@ -0,0 +1,8 @@
+#!/bin/ksh
+
+# Get the address of a symbol in Hex.
+# $1 = object/executable file name
+# $2 = symbol name
+${srcdir}/gdb.hp/tools/odump -sym "$1" | grep "$2"$ | awk '{print $1}'
+
+exit 0
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/tools/symaddr.pa64 b/gdb/testsuite/gdb.hp/gdb.objdbg/tools/symaddr.pa64
new file mode 100755
index 00000000000..43fd793c5d9
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/tools/symaddr.pa64
@@ -0,0 +1,8 @@
+#!/bin/ksh
+
+# Get the address of a symbol in Hex.
+# $1 = object/executable file name
+# $2 = symbol name
+/usr/ccs/bin/elfdump -t +s .symtab "$1" | grep "$2"$ | awk '{print $6}'
+
+exit 0
diff --git a/gdb/testsuite/gdb.hp/gdb.objdbg/tools/test-objdbg.cc b/gdb/testsuite/gdb.hp/gdb.objdbg/tools/test-objdbg.cc
new file mode 100644
index 00000000000..f8b643afbf2
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.objdbg/tools/test-objdbg.cc
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.hp/gdb.threads-hp/Makefile.in b/gdb/testsuite/gdb.hp/gdb.threads-hp/Makefile.in
new file mode 100644
index 00000000000..240b627a2d2
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.threads-hp/Makefile.in
@@ -0,0 +1,27 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES = usrthbasic usrthcore usrthfork
+
+all:
+ @echo "Nothing to be done for all..."
+
+info:
+install-info:
+dvi:
+install:
+uninstall: force
+installcheck:
+check:
+
+clean mostlyclean:
+ -rm -f *~ *.o *.ci
+ -rm -f core $(EXECUTABLES)
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
+ -rm -f *-init.exp
+ -rm -fr *.log summary detail *.plog *.sum *.psum site.*
+
+Makefile : $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.hp/gdb.threads-hp/configure b/gdb/testsuite/gdb.hp/gdb.threads-hp/configure
new file mode 100755
index 00000000000..90fa7554234
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.threads-hp/configure
@@ -0,0 +1,899 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=usrthbasic.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../../.. $srcdir/`cd $srcdir;pwd`/../../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../../.. $srcdir/`cd $srcdir;pwd`/../../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:573: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:594: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:612: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.hp/gdb.threads-hp/configure.in b/gdb/testsuite/gdb.hp/gdb.threads-hp/configure.in
new file mode 100644
index 00000000000..87fd81b51c8
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/gdb.threads-hp/configure.in
@@ -0,0 +1,15 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(usrthbasic.exp)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.hp/tools/odump b/gdb/testsuite/gdb.hp/tools/odump
new file mode 100755
index 00000000000..c96abed64db
--- /dev/null
+++ b/gdb/testsuite/gdb.hp/tools/odump
@@ -0,0 +1,7 @@
+#!/bin/ksh
+
+# First source /app/appserver
+. /app/appserver
+
+# Exec the executable.
+exec $APPROOT/usr/contrib/bin/$(basename $0) "$@"
diff --git a/gdb/testsuite/gdb.java/Makefile.in b/gdb/testsuite/gdb.java/Makefile.in
new file mode 100644
index 00000000000..0954369c092
--- /dev/null
+++ b/gdb/testsuite/gdb.java/Makefile.in
@@ -0,0 +1,26 @@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+all:
+ @echo "Nothing to be done for all..."
+
+#### host, target, and site specific Makefile frags come in here.
+
+.SUFFIXES: .java .class .o .exe .exp .check
+
+# Do 'make javamisc.check' to run just the javamisc.exp test.
+
+.exp.check:
+ rootme=`pwd`/; export rootme; \
+ cd .. ; \
+ $(MAKE) just-check RUNTESTFLAGS="${RUNTESTFLAGS} $*.exp" \
+ EXPECT=${EXPECT}
+
+clean mostlyclean:
+ -rm -f *.o ${OBJS} *.class *.exe *~ core
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
+
+Makefile: $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.java/configure b/gdb/testsuite/gdb.java/configure
new file mode 100755
index 00000000000..6a417911735
--- /dev/null
+++ b/gdb/testsuite/gdb.java/configure
@@ -0,0 +1,913 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+sitefile=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --site-file=FILE use FILE as the site file
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -site-file | --site-file | --site-fil | --site-fi | --site-f)
+ ac_prev=sitefile ;;
+ -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
+ sitefile="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=jmisc.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$sitefile"; then
+ if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+ fi
+else
+ CONFIG_SITE="$sitefile"
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:586: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:607: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:625: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.java/configure.in b/gdb/testsuite/gdb.java/configure.in
new file mode 100644
index 00000000000..12fd4c7be50
--- /dev/null
+++ b/gdb/testsuite/gdb.java/configure.in
@@ -0,0 +1,11 @@
+dnl Process this file file with autoconf to produce a configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(jmisc.exp)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.java/jmisc.exp b/gdb/testsuite/gdb.java/jmisc.exp
new file mode 100644
index 00000000000..8f6c6fbc2b7
--- /dev/null
+++ b/gdb/testsuite/gdb.java/jmisc.exp
@@ -0,0 +1,91 @@
+# Copyright 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Anthony Green. (green@redhat.com)
+#
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+load_lib "java.exp"
+
+set testfile "jmisc"
+set srcfile ${srcdir}/$subdir/${testfile}.java
+set binfile ${objdir}/${subdir}/${testfile}
+if { [compile_java_from_source ${srcfile} ${binfile} "-g"] != "" } {
+ untested "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to java. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_java {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+
+ send_gdb "set language java\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language java (timeout)" ; return 0 }
+ }
+
+ return [gdb_test "show language" ".* source language is \"java\".*" \
+ "set language to \"java\""]
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+if ![set_lang_java] then {
+ runto ${testfile}.main
+
+ send_gdb "ptype jmisc\n"
+ gdb_expect {
+ -re "type = class jmisc extends java.lang.Object \{\[\r\n\ \t]+void main\\(java\.lang\.String\\\[]\\);\[\r\n\ \t]+void <init>\\(void\\);\[\r\n\ \t]+\}\[\r\n\ \t]+$gdb_prompt $" { pass "ptype jmisc" }
+ -re ".*$gdb_prompt $" { fail "ptype jmisc" }
+ timeout { fail "ptype jmisc (timeout)" ; return }
+ }
+
+ send_gdb "p args\n"
+ gdb_expect {
+ -re "\\\$1 = java\.lang\.String\\\[]@\[a-f0-9]+\[\r\n\ \t]+$gdb_prompt $" { pass "p args" }
+ -re ".*$gdb_prompt $" { fail "p args" }
+ timeout { fail "p args (timeout)" ; return }
+ }
+
+ send_gdb "p *args\n"
+ gdb_expect {
+ -re "\\\$2 = \{length: 0\}\[\r\n\ \t]+$gdb_prompt $" { pass "p *args" }
+ -re ".*$gdb_prompt $" { fail "p *args" }
+ timeout { fail "p *args (timeout)" ; return }
+ }
+}
diff --git a/gdb/testsuite/gdb.java/jmisc.java b/gdb/testsuite/gdb.java/jmisc.java
new file mode 100644
index 00000000000..a11ba5447ec
--- /dev/null
+++ b/gdb/testsuite/gdb.java/jmisc.java
@@ -0,0 +1,7 @@
+public class jmisc
+{
+ public static void main (String[] args)
+ {
+ return;
+ }
+}
diff --git a/gdb/testsuite/gdb.java/jmisc1.exp b/gdb/testsuite/gdb.java/jmisc1.exp
new file mode 100644
index 00000000000..eea559e11b9
--- /dev/null
+++ b/gdb/testsuite/gdb.java/jmisc1.exp
@@ -0,0 +1,91 @@
+# Copyright 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Anthony Green. (green@redhat.com)
+#
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+load_lib "java.exp"
+
+set testfile "jmisc"
+set srcfile ${srcdir}/$subdir/${testfile}.java
+set binfile ${objdir}/${subdir}/${testfile}
+if { [compile_java_from_source ${srcfile} ${binfile} "-g"] != "" } {
+ untested "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to java. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_java {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+
+ send_gdb "set language java\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language java (timeout)" ; return 0 }
+ }
+
+ return [gdb_test "show language" ".* source language is \"java\".*" \
+ "set language to \"java\""]
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+if ![set_lang_java] then {
+ runto ${testfile}.main(java.lang.String\[\])
+
+ send_gdb "ptype jmisc\n"
+ gdb_expect {
+ -re "type = class jmisc extends java.lang.Object \{\[\r\n\ \t]+void main\\(java\.lang\.String\\\[]\\);\[\r\n\ \t]+void <init>\\(void\\);\[\r\n\ \t]+\}\[\r\n\ \t]+$gdb_prompt $" { pass "ptype jmisc" }
+ -re ".*$gdb_prompt $" { fail "ptype jmisc" }
+ timeout { fail "ptype jmisc (timeout)" ; return }
+ }
+
+ send_gdb "p args\n"
+ gdb_expect {
+ -re "\\\$1 = java\.lang\.String\\\[]@\[a-f0-9]+\[\r\n\ \t]+$gdb_prompt $" { pass "p args" }
+ -re ".*$gdb_prompt $" { fail "p args" }
+ timeout { fail "p args (timeout)" ; return }
+ }
+
+ send_gdb "p *args\n"
+ gdb_expect {
+ -re "\\\$2 = \{length: 0\}\[\r\n\ \t]+$gdb_prompt $" { pass "p *args" }
+ -re ".*$gdb_prompt $" { fail "p *args" }
+ timeout { fail "p *args (timeout)" ; return }
+ }
+}
diff --git a/gdb/testsuite/gdb.java/jmisc2.exp b/gdb/testsuite/gdb.java/jmisc2.exp
new file mode 100644
index 00000000000..2eeb99df7ad
--- /dev/null
+++ b/gdb/testsuite/gdb.java/jmisc2.exp
@@ -0,0 +1,91 @@
+# Copyright 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Anthony Green. (green@redhat.com)
+#
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+load_lib "java.exp"
+
+set testfile "jmisc"
+set srcfile ${srcdir}/$subdir/${testfile}.java
+set binfile ${objdir}/${subdir}/${testfile}
+if { [compile_java_from_source ${srcfile} ${binfile} "-g"] != "" } {
+ untested "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to java. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_java {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+
+ send_gdb "set language java\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language java (timeout)" ; return 0 }
+ }
+
+ return [gdb_test "show language" ".* source language is \"java\".*" \
+ "set language to \"java\""]
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+if ![set_lang_java] then {
+ send_gdb "ptype jmisc\n"
+ gdb_expect {
+ -re "type = class jmisc extends java.lang.Object \{\[\r\n\ \t]+void main\\(java\.lang\.String\\\[]\\);\[\r\n\ \t]+void <init>\\(void\\);\[\r\n\ \t]+\}\[\r\n\ \t]+$gdb_prompt $" { pass "ptype jmisc" }
+ -re ".*$gdb_prompt $" { fail "ptype jmisc" }
+ timeout { fail "ptype jmisc (timeout)" ; return }
+ }
+
+ runto ${testfile}.main(java.lang.String\[\])
+
+ send_gdb "p args\n"
+ gdb_expect {
+ -re "\\\$1 = java\.lang\.String\\\[]@\[a-f0-9]+\[\r\n\ \t]+$gdb_prompt $" { pass "p args" }
+ -re ".*$gdb_prompt $" { fail "p args" }
+ timeout { fail "p args (timeout)" ; return }
+ }
+
+ send_gdb "p *args\n"
+ gdb_expect {
+ -re "\\\$2 = \{length: 0\}\[\r\n\ \t]+$gdb_prompt $" { pass "p *args" }
+ -re ".*$gdb_prompt $" { fail "p *args" }
+ timeout { fail "p *args (timeout)" ; return }
+ }
+}
diff --git a/gdb/testsuite/gdb.java/jv-exp.exp b/gdb/testsuite/gdb.java/jv-exp.exp
new file mode 100644
index 00000000000..1ee9bd33975
--- /dev/null
+++ b/gdb/testsuite/gdb.java/jv-exp.exp
@@ -0,0 +1,66 @@
+# Copyright 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# Set the current language to Java. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_java {} {
+ global gdb_prompt
+
+ if [gdb_test "set language java" "" "set language java"] {
+ return 0
+ }
+
+ if [gdb_test "show language" ".* source language is \"java\".*"] {
+ return 0
+ }
+ return 1;
+}
+
+proc test_comparisons {} {
+ global gdb_prompt
+
+ # Test various comparisons.
+
+ gdb_test "p 1 > 2" " = false"
+ gdb_test "p 1 < 2" " = true"
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ""
+gdb_test "set print address off" "" ""
+gdb_test "set width 0" ""
+
+if [set_lang_java] then {
+ test_comparisons
+} else {
+ fail "Java expression tests suppressed"
+}
diff --git a/gdb/testsuite/gdb.java/jv-print.exp b/gdb/testsuite/gdb.java/jv-print.exp
new file mode 100644
index 00000000000..fb5dad73a28
--- /dev/null
+++ b/gdb/testsuite/gdb.java/jv-print.exp
@@ -0,0 +1,141 @@
+# Copyright 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# Set the current language to Java. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_java {} {
+ global gdb_prompt
+
+ if [gdb_test "set language java" "" "set language java"] {
+ return 0
+ }
+
+ if [gdb_test "show language" ".* source language is \"java\".*"] {
+ return 0
+ }
+ return 1;
+}
+
+proc test_integer_literals_accepted {} {
+ global gdb_prompt
+
+ # Test various decimal values.
+
+ gdb_test "p 123" " = 123"
+ gdb_test "p -123" " = -123"
+ gdb_test "p/d 123" " = 123"
+
+ # Test various octal values.
+
+ gdb_test "p 0123" " = 83"
+ gdb_test "p 00123" " = 83"
+ gdb_test "p -0123" " = -83"
+ gdb_test "p/o 0123" " = 0123"
+
+ # Test various hexadecimal values.
+
+ gdb_test "p 0x123" " = 291"
+ gdb_test "p -0x123" " = -291"
+ gdb_test "p 0x0123" " = 291"
+ gdb_test "p -0x0123" " = -291"
+ gdb_test "p 0xABCDEF" " = 11259375"
+ gdb_test "p 0xabcdef" " = 11259375"
+ gdb_test "p 0xAbCdEf" " = 11259375"
+ gdb_test "p/x 0x123" " = 0x123"
+}
+
+proc test_character_literals_accepted {} {
+ global gdb_prompt
+
+ gdb_test "p 'a'" " = 'a'"
+ gdb_test "p/c 'a'" " = 'a'"
+ gdb_test "p/c 70" " = 'F'"
+ gdb_test "p/x 'a'" " = 0x61"
+ gdb_test "p/d 'a'" " = 97"
+ gdb_test "p/t 'a'" " = 1100001"
+ gdb_test "p/x '\\377'" " = 0xff"
+ gdb_test "p '\\''" " = '\\\\''"
+ # Note "p '\\'" => "= 92 '\\'"
+ gdb_test "p '\\\\'" " = '\\\\\\\\'"
+
+ # Test the /c print format.
+}
+
+proc test_integer_literals_rejected {} {
+ global gdb_prompt
+
+ test_print_reject "p 0x"
+ gdb_test "p ''" "Empty character constant\\."
+ gdb_test "p '''" "Empty character constant\\."
+ test_print_reject "p '\\'"
+
+ # Note that this turns into "p '\\\'" at gdb's input.
+ test_print_reject "p '\\\\\\'"
+
+ # Test various decimal values.
+
+ test_print_reject "p DEADBEEF"
+
+ test_print_reject "p 123DEADBEEF"
+ test_print_reject "p 123foobar.bazfoo3"
+ test_print_reject "p 123EEEEEEEEEEEEEEEEE33333k333"
+ gdb_test "p 123.4+56.7" "180.(099\[0-9]*|100\[0-9\]*)" "check for floating addition"
+
+ # Test various octal values.
+
+ test_print_reject "p 09"
+ test_print_reject "p 079"
+
+ # Test various hexadecimal values.
+
+ test_print_reject "p 0xG"
+ test_print_reject "p 0xAG"
+}
+
+
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "print \$pc" "No registers\\."
+# FIXME: should also test "print $pc" when there is an execfile but no
+# remote debugging target, process or corefile.
+
+gdb_test "set print sevenbit-strings" ""
+gdb_test "set print address off" "" ""
+gdb_test "set width 0" ""
+
+if [set_lang_java] then {
+ test_integer_literals_accepted
+ test_character_literals_accepted
+ test_integer_literals_rejected
+} else {
+ fail "Java print command tests suppressed"
+}
diff --git a/gdb/testsuite/gdb.mi/ChangeLog b/gdb/testsuite/gdb.mi/ChangeLog
new file mode 100644
index 00000000000..26d662c1ee6
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/ChangeLog
@@ -0,0 +1,624 @@
+2002-03-04 Michael Chastain <mec@shout.net>
+
+ * mi-var-cmd.exp: In test "create local variable func",
+ accommodate gcc v3 function signature.
+ * mi0-var-cmd-exp: Ditto.
+
+2002-02-05 Jim Blandy <jimb@redhat.com>
+
+ * mi-regs.exp: Various cleanups for SPARC-only tests.
+ (test_breakpoints_creation_and_listing): Format of breakpoint
+ table has changed.
+ (sparc_register_tests): Expand floating-point number regexp to
+ recognize NaN values, too. Replace ineffectual single backslash
+ before a hyphen with a double backslash. Don't check the exact
+ numbers of the registers which have changed, since there's no way
+ to know which registers changed, exactly; just check that the
+ result is well-formed.
+ * mi0-regs.exp: (sparc_register_tests): Same as for
+ sparc_register_tests in mi-regs.exp.
+
+ * mi-var-child.exp ("get children of struct_declarations", "get
+ children of struct_declarations.s2.u2.u1s2", "get children of
+ weird"): Tolerate argument types when they appear in function
+ types. (Dwarf 2 includes prototype info; STABS does not.)
+ * mi0-var-child.exp: Same.
+
+2001-12-19 Keith Seitz <keiths@redhat.com>
+
+ * mi-var-display.exp: char* variables have a child. Update all
+ occurences.
+ * mi0-var-display.exp: Likewise.
+
+2001-08-29 Andrew Cagney <cagney@redhat.com>
+
+ * mi-var-cmd.exp, mi0-var-cmd.exp: Variable lpcharacter has one
+ child. Soften floating point tests.
+
+2001-08-09 Andrew Cagney <ac131313@redhat.com>
+
+ * mi0-var-block.exp, mi0-stack.exp, mi0-simplerun.exp,
+ mi0-regs.exp, mi0-watch.exp, mi0-stepi.exp, mi0-until.exp,
+ mi0-return.exp, mi0-read-memory.exp, mi0-eval.exp,
+ mi0-disassemble.exp, mi0-console.exp, mi-watch.exp,
+ mi-var-display.exp, mi-var-cmd.exp, mi-var-child.exp,
+ mi-until.exp, mi-var-block.exp, mi-stepi.exp, mi-stack.exp,
+ mi-simplerun.exp, mi-return.exp, mi-regs.exp, mi-read-memory.exp,
+ mi-disassemble.exp, mi-eval.exp, mi-console.exp: Replace pattern
+ matching thread=0 with one to also match thread=1.
+ Fix PR gdb/190.
+
+2001-08-18 Andrew Cagney <ac131313@redhat.com>
+
+ * mi0-until.exp, mi-until.exp, mi0-stepi.exp, mi-stepi.exp,
+ mi-simplerun.exp, mi0-simplerun.exp, mi0-return.exp,
+ mi-return.exp, mi0-console.exp, mi-console.exp: Recognize an
+ unexpected run-to-main response. Report as a fail.
+
+2001-06-27 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-disassemble.exp: Update to accept mi1 breakpoint tables.
+ * mi-basics.exp: Ditto.
+ * mi-simplerun.exp: Ditto.
+ * mi-watch.exp: Ditto. Add check for full header.
+ * mi-break.exp: Ditto. Add check for full header.
+
+2001-06-26 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-stack.exp: Update. Output for args=... and
+ locals=... changed to a list.
+
+2001-06-26 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-stack.exp: Update. Output for stack=..., args=... and
+ stack-args=... changed to a list.
+
+2001-06-25 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-console.exp: Update args=... part of stop-reason
+ patterns. Output changed to a list of arguments.
+ * mi-disassemble.exp: Ditto.
+ * mi-simplerun.exp: Ditto.
+ * mi-return.exp: Ditto.
+ * mi-read-memory.exp: Ditto.
+ * mi-eval.exp: Ditto.
+ * mi-watch.exp: Ditto.
+ * mi-var-display.exp: Ditto.
+ * mi-var-cmd.exp: Ditto.
+ * mi-var-child.exp: Ditto.
+ * mi-var-block.exp: Ditto.
+ * mi-until.exp: Ditto.
+ * mi-stepi.exp: Ditto.
+ * mi-stack.exp: Ditto.
+ * mi-regs.exp: Ditto.
+
+2001-06-25 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-read-memory.exp: Update patterns matching data-read-memory.
+ Outputs a list.
+
+2001-06-25 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-regs.exp: Update patterns matching register-values. Outputs a
+ list.
+
+2001-06-25 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-regs.exp: Update patters matching register-names. Now
+ outputs a list.
+
+2001-06-25 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-regs.exp: Update patterns matching changed-registers. Now
+ outputs a list.
+
+2001-06-23 Andrew Cagney <ac131313@redhat.com>
+
+ * ChangeLog-mi: Rename to ChangeLog.
+ * mi-basics.exp: Remove local emacs variable defining
+ change-log-default-name.
+ * mi-break.exp, mi-console.exp, mi-disassemble.exp: Ditto.
+ * mi-eval.exp, mi-hack-cli.exp, mi-read-memory.exp: Ditto.
+ * mi-regs.exp, mi-return.exp, mi-simplerun.exp: Ditto.
+ * mi-stack.exp, mi-stepi.exp, mi-until.exp: Ditto.
+ * mi-var-block.exp, mi-var-child.exp, mi-var-cmd.exp: Ditto.
+ * mi-var-display.exp, mi-watch.exp, mi0-basics.exp: Ditto.
+ * mi0-break.exp, mi0-console.exp, mi0-disassemble.exp: Ditto.
+ * mi0-eval.exp, mi0-hack-cli.exp, mi0-read-memory.exp: Ditto.
+ * mi0-regs.exp, mi0-return.exp, mi0-simplerun.exp: Ditto.
+ * mi0-stack.exp, mi0-stepi.exp, mi0-until.exp: Ditto.
+ * mi0-var-block.exp, mi0-var-child.exp, mi0-var-cmd.exp: Ditto.
+ * mi0-var-display.exp, mi0-watch.exp: Ditto.
+
+2001-06-23 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-disassemble.exp: Update patterns matching data-disassemble
+ output. Now produces a list of instructions and a list of
+ source/assembly lines.
+
+2001-06-18 Andrew Cagney <ac131313@redhat.com>
+
+ * mi-basics.exp, mi-break.exp, mi-console.exp, mi-disassemble.exp,
+ mi-eval.exp, mi-hack-cli.exp, mi-read-memory.exp, mi-regs.exp,
+ mi-return.exp, mi-simplerun.exp, mi-stack.exp, mi-stepi.exp,
+ mi-until.exp, mi-var-block.exp, mi-var-child.exp, mi-var-cmd.exp,
+ mi-var-display.exp, mi-watch.exp, mi0-basics.exp, mi0-break.exp,
+ mi0-console.exp, mi0-disassemble.exp, mi0-eval.exp,
+ mi0-hack-cli.exp, mi0-read-memory.exp, mi0-regs.exp,
+ mi0-return.exp, mi0-simplerun.exp, mi0-stack.exp, mi0-stepi.exp,
+ mi0-until.exp, mi0-var-block.exp, mi0-var-child.exp,
+ mi0-var-cmd.exp, mi0-var-display.exp, mi0-watch.exp: Use MIFLAGS
+ to explictly select an interpreter.
+
+2001-06-16 Andrew Cagney <ac131313@redhat.com>
+
+ MI0 was the never enabled MI interface included in GDB 5.0.
+ * mi0-basics.exp: Copy mi-basics.exp.
+ * mi0-break.exp: Copy mi-break.exp.
+ * mi0-console.exp: Copy mi-console.exp.
+ * mi0-disassemble.exp: Copy mi-disassemble.exp.
+ * mi0-eval.exp: Copy mi-eval.exp.
+ * mi0-hack-cli.exp: Copy mi-hack-cli.exp.
+ * mi0-read-memory.exp: Copy mi-read-memory.exp.
+ * mi0-regs.exp: Copy mi-regs.exp.
+ * mi0-return.exp: Copy mi-return.exp.
+ * mi0-simplerun.exp: Copy mi-simplerun.exp.
+ * mi0-stack.exp: Copy mi-stack.exp.
+ * mi0-stepi.exp: Copy mi-stepi.exp.
+ * mi0-until.exp: Copy mi-until.exp.
+ * mi0-var-block.exp: Copy mi-var-block.exp.
+ * mi0-var-child.exp: Copy mi-var-child.exp.
+ * mi0-var-cmd.exp: Copy mi-var-cmd.exp.
+ * mi0-var-display.exp: Copy mi-var-display.exp.
+ * mi0-watch.exp: Copy mi-watch.exp.
+
+2001-05-11 Fernando Nasser <fnasser@redhat.com>
+
+ * mi-var-child.exp: Adjust for the fact that now (char *) can be
+ dereferenced.
+
+2001-03-06 Kevin Buettner <kevinb@redhat.com>
+
+ * mi-basics.exp, mi-break.exp, mi-disassemble.exp,
+ mi-eval.exp, mi-hack-cli.exp, mi-read-memory.exp, mi-regs.exp,
+ mi-return.exp, mi-simplerun.exp, mi-stack.exp, mi-stepi.exp,
+ mi-until.exp, mi-watch.exp: Update/correct copyright notices.
+
+2001-01-20 Mark Kettenis <kettenis@gnu.org>
+
+ * mi-support.exp (mi_gdb_start): Skip mi tests if -i flag is
+ recognized (i.e. if GDB was compiled with UI_OUT, but the mi
+ interpreter wasn't recognized (because it wasn't compiled in).
+
+Tue Apr 18 15:36:07 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (clean mostlyclean): Do not delete $(MISCELLANEOUS).
+
+Tue Mar 14 15:54:57 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * basics.c: Add EMACS local variable pointing change-log at this
+ file.
+ * Makefile.in: Ditto
+
+2000-03-13 James Ingham <jingham@leda.cygnus.com>
+
+ * mi-var-block.exp: The error report from varobj_create changed
+ since I am now trapping parse_exp_1 errors. Change the tests to
+ match the new error message.
+ * mi-var-child.exp: Ditto.
+ * mi-var-cmd.exp: Ditto.
+
+2000-03-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-disassemble.exp: Don't assume numbers for the offset
+ values. They can be different depending on the architecture.
+
+ * mi-watch.exp (test_watchpoint_triggering): In same cases the
+ type can be 'hw wathcpoint' not just 'watchpoint'. Adjust for that.
+
+ * basics.c (callee4): Make the function return something,
+ otherwise the return value is undefined.
+
+2000-03-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-basics.exp: Comment out test for a still unimplemented operation.
+
+ * mi-disassemble.exp: Rewrite most of the tests to conform to new
+ disassemble interface.
+
+Sat Mar 4 13:55:08 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Fri 3 Mar 2000 Peter Schauer:
+ * mi-support.exp (mi_gdb_start): When GDB doesn't recongize -i=mi
+ option, assume no MI support present.
+
+2000-02-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-support.exp (mi_gdb_start): Update to recognize start up
+ message with 'UI_OUT' instead of 'HEADLESS'.
+
+2000-01-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-regs.exp (test_running_the_program): Add global var 'hex'.
+
+ * mi-stack.exp, mi-stepi.exp, mi-until.exp, mi-watch.exp,
+ mi-var-display.exp, mi-var-cmd.exp, mi-var-child.exp,
+ mi-var-block.exp: Update all stopped messages.
+
+2000-01-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-console.exp, mi-disassemble.exp, mi-eval.exp,
+ mi-read-memory.exp, mi-regs.exp, mi-return.exp, mi-simplerun.exp:
+ Update stopped messages, update copyright.
+
+ * mi-disassemble.exp: Update error messages output.
+
+ * mi-support.exp (proc mi_step): Make gdb do a 'step' command, not
+ a 'next'. Update stopped message.
+ (proc mi_next): Update stop message.
+ (proc mi_run_to_main): Update stopped message.
+ Update copyright.
+
+2000-01-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-simplerun.exp: Remove stack frames tests from here, to:
+
+ * mi-stack.exp: New file, tests for stack commands.
+
+ * mi-support.exp (mi_run_to_main, mi_next, mi_step) : Update to
+ include thread-id in stopped message.
+
+ * mi-regs.exp: Update break-insert output.
+
+ * (mi-console.exp, mi-disassemble.exp, mi-eval.exp,
+ mi-read-memory.exp, mi-regs.exp, mi-return.exp, mi-simplerun.exp,
+ mi-stepi.exp, mi-until.exp, mi-var-block.exp, mi-var-child.exp,
+ mi-var-cmd.exp, mi-var-display.exp, mi-watch.exp): Update stopped
+ message to include thread-id.
+
+Wed Dec 29 22:06:05 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-watch.exp, mi-var-display.exp, mi-var-cmd.exp,
+ mi-var-child.exp, mi-var-block.exp, mi-until.exp, mi-stepi.exp,
+ mi-simplerun.exp, mi-return.exp, mi-support.exp, mi-eval.exp,
+ mi-console.exp, mi-disassemble.exp, mi-break.exp: Update to
+ reflect extended output from -break-insert command.
+
+ * mi-break.exp (test_rbreak_creation_and_listing): XFAIL regexp
+ tests. -r flag broken by above.
+
+Sun Dec 19 19:28:13 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * cpp_variable.cc, cpp_variable.h, c_variable.c: Delete.
+
+Fri Dec 17 20:59:55 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-read-memory.exp: Test of ``-o <offset>'' now works.
+
+1999-12-16 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-var-cmd.exp: Fix 2 tests outputs.
+
+ * mi-var-child.exp: Add many more tests.
+
+ * mi-var-display.exp: Add many more tests.
+
+ * var-cmd.c: Change type of incr_a parameter to char.
+
+1999-12-15 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-var-block.exp: Set up xfails fro known problems.
+
+ * mi-var-display.exp: Set up printing of values of 'e' and 'anone'
+ as xfails.
+
+ * mi-var-child.exp: Fix typos.
+
+1999-12-15 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-var-child.exp: Space was missing before ``[10]''.
+
+Wed Dec 15 19:23:38 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-read-memory.exp: Add test for ``-o <offset>''. Update checks
+ and match next-row et.al.
+
+1999-12-14 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-var-display.exp : New file. Tests for format and type, with
+ unions, structs and enums.
+
+ * mi-var-cmd.exp: Add some var-assign tests.
+
+1999-12-14 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-var-cmd.exp, mi-var-block.exp, mi-var-child.exp: New files
+ some tests for -var* commands.
+
+ * var-cmd.c: New source file for var-* commands tests.
+ * gdb.mi/Makefile.in (PROGS): Add var-cmd.
+
+Mon Dec 13 18:06:09 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-break.exp: Fix quoting. Changed "srcfile.c":6 to
+ "\"srcfile.c\":6".
+ * mi-simplerun.exp: Fix quoting.
+
+Sat Dec 11 21:33:37 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-simplerun.exp (exec-finish): Fix return value was zero,
+ should have been three.
+
+ * mi-disassemble.exp: Reduce number of wild card matches in
+ * patterns. Remove all numeric constants.
+
+1999-12-09 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-eval.exp: New file. Some initial tests for
+ -data-evaluate-expression.
+
+1999-12-09 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * c_variable.c, cpp_variable.cc, cpp_variable.h: New files. Used
+ for testing "var" operations.
+ * Makefile.in: Add reference to the above files.
+
+1999-12-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-regs.exp: Fix test for format 'N' for
+ data-list-register-values.
+
+1999-12-07 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-disassemble.exp: Update expected output. Break test of
+ disassembly in mixed mode into 2 functions.
+
+ * mi-regs.exp: Initial register tests. Works only on sparc right
+ now.
+
+1999-12-02 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-stepi.exp: New file. Tests exec-step-instruction and
+ exec-next-instruction.
+ * mi-until.exp: New file. Tests exec-until.
+ * until.c: New file.
+ * mi-return.exp: New file. Tests exec-return.
+
+Thu Dec 2 09:38:23 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-hack-cli.exp: New test. Check the hacked up access to the
+ CLI.
+
+Wed Dec 1 16:47:40 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-basics.exp: Delete calls to mi_delete_breakpoints,
+ mi_gdb_reinitialize_dir and mi_gdb_load. This test is checking
+ that these can work.
+
+ * mi-support.exp (mi_step, mi_next, mi_run_to_main): New
+ procedures.
+
+ * mi-read-memory.exp, mi-read-memory.c: New files. Test
+ data-read-memory command.
+
+Tue Nov 30 23:54:16 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-support.exp: Don't start SID until after GDB has been started
+ and verified.
+
+Tue Nov 30 22:21:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-support.exp (mi_uncatched_gdb_exit): When SID, call sid_exit.
+ (mi_gdb_start): When SID, call sid_start.
+ (mi_gdb_start): Add MIFLAGS to spawn-GDB command. Check for
+ HEADLESS gdb. Return non-zero when GDB fails to start.
+ (mi_gdb_load): When SID or SIM, download program.
+ (mi_run_cmd): Don't do download here. Assume target supports the
+ 00-exec-run command.
+ (skip_mi_tests, setup_gdbmi, unset_gdbmi): Delete. Merged into
+ mi_gdb_start.
+
+ * mi-basics.exp, mi-break.exp, mi-console.exp, mi-disassemble.exp,
+ mi-simplerun.exp, mi-watch.exp: Update. Check status from
+ mi_gdb_start indicating that GDB started correctly.
+
+Tue Nov 30 15:22:08 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-support.exp (setup_gdbmi, unset_gdbmi): New
+ procedures. Setup/unset dejagnu for mi tests.
+ * mi-basics.exp, mi-console.exp, mi-simplerun.exp, mi-break.exp,
+ mi-disassemble.exp, mi-watch.exp: Update.
+
+1999-11-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-simplerun.exp (test_running_the_program): Remove XFAIL. The
+ output is fixed now.
+ (test_program_termination): Update output pattern.
+
+Tue Nov 30 00:19:10 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-console.c, mi-console.exp: New files. Test console output.
+
+Mon Nov 29 17:59:13 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-support.exp (mi_run_command): Check for exec-run command
+ failure due to MI not having an active target.
+ (mi_run_command): Check for and handle a builtin simulator target.
+ (mi_run_command): Don't check/handle for ``The program has been
+ started already'', not a valid MI response.
+
+ * mi-simplerun.exp (test_running_the_program): Update all patterns
+ to match async output.
+ (test_running_the_program): Mark ``step to callee4'' as XFAIL. MI
+ output contains {,reason="end-stepping-range"}+.
+
+ * mi-simplerun.exp: Limit the timeout for ``step to callee4'' to
+ 30 seconds.
+
+Mon Nov 29 17:30:00 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-support.exp (skip_mi_tests): Print UNTESTED when MI interface
+ isn't available. Start/stop instead of assuming GDB is running.
+ (MIFLAGS): Define.
+ * mi-simplerun.exp, mi-disassemble.exp, mi-break.exp,
+ mi-basics.exp, mi-watch.exp: Update.
+
+1999-11-26 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-simplerun.exp: Move break-insert {-t, -r} from here.
+ * mi-break.exp: To here. New file.
+ * mi-watch.exp: New file. Tests for watchpoints.
+
+Wed Nov 24 17:42:07 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.mi/ChangeLog-mi: MI entries moved to here.
+
+Wed Nov 24 17:31:04 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdb.mi/mi-basics.exp, gdb.mi/mi-disassemble.exp,
+ gdb.mi/mi-simplerun.exp: Print warning message when test isn't
+ run.
+
+1999-11-23 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.mi/mi-simplerun.exp: Update output of break-list to account for
+ "times" field.
+
+1999-11-05 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.mi/mi-simplerun.exp: Add tests for temporary breakpoints
+ and bp based on regular expressions.
+ * gdb.mi/mi-disassemble.exp: Fix typo.
+
+1999-11-04 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.mi/mi-disassemble.exp: Update output of execution commands
+ to reflect new 'reason' field.
+ * gdb.mi/mi-simplerun.exp: Ditto.
+
+1999-10-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.mi/mi-simplerun.exp: Add more stack-list-frames tests.
+
+ * gdb.mi/mi-disassemble.exp: Update 'run to main' output.
+
+ * gdb.mi/mi-simplerun.exp: Update execution commands
+ output. Update backtrace output.
+
+1999-10-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.mi/mi-disassemble.exp: Add new tests for the new
+ disassembly command parameter, number of lines.
+
+Mon Oct 11 13:57:21 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * lib/mi-support.exp: Break complicated gdb_expect containing
+ exp_continue into a while within an expect. Don't attempt a start
+ more than three times. Check return value from gdb_load.
+
+1999-10-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdb.mi/mi-disassemble.exp: New file.
+
+Wed Oct 6 12:05:58 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/mi-support.exp (mi_run_cmd): Give up after two restart
+ attempts.
+
+1999-09290 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.mi/mi-basics.exp: Update to current syntax and output formats.
+ * gdb.mi/mi-simplerun.exp: Ditto.
+ * lib/mi-support.exp (mi_delete_breakpoints): Ditto.
+
+1999-06-30 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.mi/basics.c (main): Fix return code. Add a print "Hello,
+ World".
+ * gdb.mi/mi-basics.exp: Fix message texts and numbering.
+ * gdb.mi/mi-simplerun.exp: Ditto. Also, add new tests and improve
+ some patterns.
+
+1999-06-30 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * lib/mi-support.exp (mi_gdb_reinitialize_dir): Remove query as an
+ acceptable response to the environment-dir command.
+
+1999-06-30 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * lib/mi-support.exp (mi_delete_breakpoints): Remove references to
+ gdb-cli.
+ (mi_run_cmd): Ditto.
+
+1999-06-25 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * lib/mi-support.exp (skip_mi_tests): Use gdb-version to check for
+ headless output format.
+
+1999-06-24 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.mi/mi-simplerun.exp (test_controlled_execution): Add global
+ spec for hex.
+
+1999-06-24 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * lib/mi-support.exp (mi_run_cmd): Fix pattern and add a timeout
+ clause.
+
+1999-06-24 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * lib/mi-support.exp: Use mi_gdb_prompt instead of a modified
+ gdb_prompt. Remove uneeded loading of libgloss.
+ (mi_gdb_exit): Remove prompt argument.
+ (mi_uncatched_gdb_exit): Ditto.
+ (mi_run_cmd): New proc. MI version of gdb_run.
+ (skip_mi_tests): New proc. Check if gdb is capable of producing
+ headless formatted output.
+ * gdb.mi/mi-basics.exp: Use mi_gdb_prompt instead of a modified
+ gdb_prompt. Eliminate parameter to mi_gdb_exit (as a result of
+ the above). Test for skip_mi_tests before running.
+ Note: The above changes are interelated (need each other).
+ * gdb.mi/mi-simplerun.exp: Same changes as for mi-basics.exe
+ above.
+ (test_breakpoint_creation_and_listing): Remove insertion of
+ breakpoint at callee1 (and renumber tokens). Add tests for
+ break-list, break-disable and break-info.
+ (test_running_the_program): Use mi_run_cmd so it can run on remote
+ targets.
+ (test_controlled_execution): Fix broken test.
+ (test_program_termination): Test implemented.
+ * gdb.mi/basic.c (main): Small change to allow for testing of both
+ exec-next and exec-step operations.
+
+1999-06-22 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * lib/mi-support.exp (mi_gdb_test): New proc. MI version of gdb_test.
+ * gdb.mi/mi-basics.exp: Use the above instead of gdb_test.
+ * gdb.mi/mi-simplerun.exp: Ditto.
+
+1999-06-22 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.mi/mi-simplerun.exp: New file. Tests simple debugging tasks.
+ * gdb.mi/mi-basics.exp: Remove tests moved to above new file.
+ * lib/mi-support.exp: New file. Support procedures for mi tests.
+
+1999-06-08 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.mi/mi-basics.exp: Skip all tests if the MI interpreter is
+ not active.
+
+1999-06-03 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * gdb.mi: New directory.
+ * configure.in: Configure it.
+ * configure: Regenerate.
+ * gdb.mi/{Makefile.in,configure.in,configure}: New files.
+ * gdb.mi/{mi-basics.exp,basics.c,testcmds}: New files.
+
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/testsuite/gdb.mi/Makefile.in b/gdb/testsuite/gdb.mi/Makefile.in
new file mode 100644
index 00000000000..67a0f5d39b5
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/Makefile.in
@@ -0,0 +1,24 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+PROGS = basics c_variable cpp_variable var-cmd
+
+MISCELLANEOUS = testcmds
+
+all:
+ @echo "Nothing to be done for all..."
+
+#### host, target, and site specific Makefile frags come in here.
+
+clean mostlyclean:
+ -rm -f *.ci *.o $(OBJS) $(PROGS) *~ core
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
+
+Makefile: $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
+
+# Local variables:
+# change-log-default-name: "ChangeLog-mi"
+# End:
diff --git a/gdb/testsuite/gdb.mi/basics.c b/gdb/testsuite/gdb.mi/basics.c
new file mode 100644
index 00000000000..9a61aa2dc39
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/basics.c
@@ -0,0 +1,45 @@
+/*
+ * This simple program that passes different types of arguments
+ * on function calls. Useful to test printing frames, stepping, etc.
+ */
+
+int callee4 (void)
+{
+ int A=1;
+ int B=2;
+ int C;
+
+ C = A + B;
+ return 0;
+}
+callee3 (char *strarg)
+{
+ callee4 ();
+}
+
+callee2 (int intarg, char *strarg)
+{
+ callee3 (strarg);
+}
+
+callee1 (int intarg, char *strarg, double fltarg)
+{
+ callee2 (intarg, strarg);
+}
+
+main ()
+{
+ callee1 (2, "A string argument.", 3.5);
+ callee1 (2, "A string argument.", 3.5);
+
+ printf ("Hello, World!");
+
+ return 0;
+}
+
+/*
+Local variables:
+change-log-default-name: "ChangeLog-mi"
+End:
+*/
+
diff --git a/gdb/testsuite/gdb.mi/configure b/gdb/testsuite/gdb.mi/configure
new file mode 100755
index 00000000000..fd5d1467f1a
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/configure
@@ -0,0 +1,902 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=mi-basics.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:575: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:596: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:614: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.mi/configure.in b/gdb/testsuite/gdb.mi/configure.in
new file mode 100644
index 00000000000..94278273f13
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/configure.in
@@ -0,0 +1,15 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(mi-basics.exp)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.mi/mi-basics.exp b/gdb/testsuite/gdb.mi/mi-basics.exp
new file mode 100644
index 00000000000..4913d8f8b35
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-basics.exp
@@ -0,0 +1,174 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# test basic Machine interface (MI) operations
+#
+# Verify that, using the MI, we can load a program and do
+# other basic things that are used by all test files through mi_gdb_exit,
+# mi_gdb_start, mi_delete_breakpoints, mi_gdb_reinitialize_dir and
+# mi_gdb_load, so we can safely use those.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but the command syntax and correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# In this file we want to test if the operations needed by the following
+# procedures work, so it makes no sense using them here.
+
+# mi_delete_breakpoints
+# mi_gdb_reinitialize_dir $srcdir/$subdir
+# mi_gdb_load ${binfile}
+
+# Test if the MI interpreter has been configured
+
+proc test_mi_interpreter_selection {} {
+ global mi_gdb_prompt
+ global gdb_prompt
+
+ # All this test expects is to get the prompt back
+ # with no syntax error message
+ send_gdb "-gdb-version\n"
+ gdb_expect {
+ -re "GNU gdb .*\r\n$mi_gdb_prompt$" \
+ { pass "acceptance of MI operations"
+ return 1}
+ -re ".*\r\n$mi_gdb_prompt$" \
+ { fail "acceptance of MI operations"
+ note "Skipping all other MI tests." }
+ -re "Undefined command.*$gdb_prompt $" \
+ { fail "acceptance of MI operations"
+ note "Skipping all other MI tests." }
+ -re ".*$gdb_prompt $" \
+ { fail "acceptance of MI operations"
+ note "Skipping all other MI tests." }
+ timeout { fail "acceptance of MI operations (timeout)"
+ note "Skipping all other MI tests." }
+ }
+ return 0
+}
+
+proc test_exec_and_symbol_mi_operatons {} {
+ global mi_gdb_prompt
+ global binfile
+
+ # Load symbols and specify executable on a single operation
+ # Tests:
+ # -file-exec-and-symbols
+
+ # Can't use mi_gdb_test as if this doesn't work,
+ # we must give up on the whole test file
+ send_gdb "-file-exec-and-symbols ${binfile}\n"
+ gdb_expect {
+ -re "\[\r\n\]*\\\^done\r\n$mi_gdb_prompt$" \
+ { pass "file-exec-and-symbols operation" }
+ timeout { fail "file-exec-and-symbols operation (timeout)"
+ note "Skipping all other MI tests."
+ return 0}
+ }
+
+ # The following is not used by mi-support.exp, but we test here so
+ # we get done with loading a program basics.
+
+ # Do it again, but now load symbols and specify executable with
+ # two separate operations
+ # Tests:
+ # -file-clear
+ # -file-exec-file
+ # -file-symbol-file
+
+ # FIXME: file-clear is not implemented yet.
+# mi_gdb_test "-file-clear" \
+# "\\\^done" \
+# "file-clear operation"
+
+ mi_gdb_test "-file-exec-file ${binfile}" \
+ "\\\^done" \
+ "file-exec-file operation"
+
+ mi_gdb_test "-file-symbol-file ${binfile}" \
+ "\\\^done" \
+ "file-symbol-file operation"
+
+ # FIXME: if we cannot load we have to skip all other tests.
+}
+
+proc test_breakpoints_deletion {} {
+ global mi_gdb_prompt
+ global srcfile
+
+ # Clear all breakpoints and list to confirm
+ # Tests:
+ # -break-delete (all)
+ # -break-list
+
+ # The all parameter is actually no parameter.
+ mi_gdb_test "200-break-delete" \
+ "\\\^done" \
+ "break-delete (all) operation"
+
+ mi_gdb_test "201-break-list" \
+ ".*\\\^done,BreakpointTable=\\\{.*,body=\\\[\\\]\\\}" \
+ "all breakpoints removed"
+}
+
+proc test_dir_specification {} {
+ global mi_gdb_prompt
+ global srcdir
+ global subdir
+
+ # Clear the search directories, then specify one to be searched
+ # Tests:
+ # -environment-directory
+ # -environment-directory arg
+
+#exp_internal 1
+ mi_gdb_test "202-environment-directory" \
+ "\\\^done" \
+ "environment-directory operation"
+
+ mi_gdb_test "203-environment-directory ${srcdir}/${subdir}" \
+ "\\\^done" \
+ "environment-directory arg operation"
+#exp_internal 0
+}
+
+if [test_mi_interpreter_selection] {
+ test_exec_and_symbol_mi_operatons
+ test_breakpoints_deletion
+ test_dir_specification
+}
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp
new file mode 100644
index 00000000000..5cbe4e40d2e
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-break.exp
@@ -0,0 +1,138 @@
+# Copyright 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and perform basic
+# debugging activities like: insert breakpoints, run the program,
+# step, next, continue until it ends and, last but not least, quit.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_tbreak_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert some breakpoints and list them
+ # Also, disable some so they do not interfere with other tests
+ # Tests:
+ # -break-insert -t main
+ # -break-insert -t basics.c:callee2
+ # -break-insert -t basics.c:15
+ # -break-insert -t srcfile:6
+ # -break-list
+
+ mi_gdb_test "222-break-insert -t main" \
+ "222\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+ "break-insert -t operation"
+
+ mi_gdb_test "333-break-insert -t basics.c:callee2" \
+ "333\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee2\",file=\".*basics.c\",line=\"22\",times=\"0\"\}" \
+ "insert temp breakpoint at basics.c:callee2"
+
+ mi_gdb_test "444-break-insert -t basics.c:15" \
+ "444\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee3\",file=\".*basics.c\",line=\"15\",times=\"0\"\}" \
+ "insert temp breakpoint at basics.c:15 (callee3)"
+
+ # Getting the quoting right is tricky. That is "\"<file>\":6"
+ mi_gdb_test "555-break-insert -t \"\\\"${srcfile}\\\":6\"" \
+ "555\\^done,bkpt=\{number=\"4\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"6\",times=\"0\"\}" \
+ "insert temp breakpoint at \"<fullfilename>\":6 (callee4)"
+
+ mi_gdb_test "666-break-list" \
+ "666\\\^done,BreakpointTable=\{nr_rows=\".\",nr_cols=\".\",hdr=\\\[\{width=\".*\",alignment=\".*\",col_name=\"number\",colhdr=\"Num\"\}.*colhdr=\"Type\".*colhdr=\"Disp\".*colhdr=\"Enb\".*colhdr=\"Address\".*colhdr=\"What\".*\\\],body=\\\[bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}.*\\\]\}" \
+ "list of breakpoints"
+
+ mi_gdb_test "777-break-delete" \
+ "777\\^done" \
+ "delete temp breakpoints"
+}
+
+proc test_rbreak_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert some breakpoints and list them
+ # Also, disable some so they do not interfere with other tests
+ # Tests:
+ # -break-insert -r main
+ # -break-insert -r callee2
+ # -break-insert -r callee
+ # -break-insert -r .*llee
+ # -break-list
+
+ setup_xfail "*-*-*"
+ mi_gdb_test "122-break-insert -r main" \
+ "122\\^done,bkpt=\{number=\"5\",addr=\"$hex\",file=\".*basics.c\",line=\"32\"\}" \
+ "break-insert -r operation"
+
+ setup_xfail "*-*-*"
+ mi_gdb_test "133-break-insert -r callee2" \
+ "133\\^done,bkpt=\{number=\"6\",addr=\"$hex\",file=\".*basics.c\",line=\"22\"\}" \
+ "insert breakpoint with regexp callee2"
+
+ setup_xfail "*-*-*"
+ mi_gdb_test "144-break-insert -r callee" \
+ "144\\^done,bkpt=\{number=\"7\",addr=\"$hex\",file=\".*basics.c\",line=\"27\"\},bkpt=\{number=\"8\",addr=\"$hex\",file=\".*basics.c\",line=\"22\"\},bkpt=\{number=\"9\",addr=\"$hex\",file=\".*basics.c\",line=\"17\"\},bkpt=\{number=\"10\",addr=\"$hex\",file=\".*basics.c\",line=\"8\"\}" \
+ "insert breakpoint with regexp callee"
+
+ setup_xfail "*-*-*"
+ mi_gdb_test "155-break-insert -r \.\*llee" \
+ "155\\^done,bkpt=\{number=\"11\",addr=\"$hex\",file=\".*basics.c\",line=\"27\"\},bkpt=\{number=\"12\",addr=\"$hex\",file=\".*basics.c\",line=\"22\"\},bkpt=\{number=\"13\",addr=\"$hex\",file=\".*basics.c\",line=\"17\"\},bkpt=\{number=\"14\",addr=\"$hex\",file=\".*basics.c\",line=\"8\"\}" \
+ "insert breakpoint with regexp .*llee"
+
+ setup_xfail "*-*-*"
+ mi_gdb_test "166-break-list" \
+ "1\\\^done,BreakpointTable=\{nr_rows=\".\",nr_cols=\".\",hdr=\\\[\{width=\".*\",alignment=\".*\",col_name=\"number\",colhdr=\"Num\"\}.*colhdr=\"Type\".*colhdr=\"Disp\".*colhdr=\"Enb\".*colhdr=\"Address\".*colhdr=\"What\".*\\\],body=\\\[bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\\\]\}" \
+ "list of breakpoints"
+
+ mi_gdb_test "177-break-delete" \
+ "177\\^done" \
+ "delete temp breakpoints"
+}
+
+test_tbreak_creation_and_listing
+test_rbreak_creation_and_listing
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-console.c b/gdb/testsuite/gdb.mi/mi-console.c
new file mode 100644
index 00000000000..f0f2016efdf
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-console.c
@@ -0,0 +1,20 @@
+void
+hello ()
+{
+ char *hello = "Hello \\\"!\r\n";
+ int i;
+ for (i = 0; hello[i]; i++)
+ write (1, hello + i, 1);
+}
+
+int
+main ()
+{
+ hello ();
+}
+/*
+Local variables:
+change-log-default-name: "ChangeLog-mi"
+End:
+*/
+
diff --git a/gdb/testsuite/gdb.mi/mi-console.exp b/gdb/testsuite/gdb.mi/mi-console.exp
new file mode 100644
index 00000000000..f6a249c77df
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-console.exp
@@ -0,0 +1,112 @@
+# Copyright 1999, 2000, 2001 Cygnus Solutions.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and perform basic
+# debugging activities like: insert breakpoints, run the program,
+# step, next, continue until it ends and, last but not least, quit.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+# This test only works when talking to a target that routes its output
+# through GDB. Check that we're either talking to a simulator or a
+# remote target.
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "mi-console"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+# Halt in main
+mi_gdb_test "200-break-insert main" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*mi-console.c\",line=\"13\",times=\"0\"\}" \
+ "break-insert operation"
+mi_run_cmd
+gdb_expect {
+ -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\\\[\\\],file=\".*mi-console.c\",line=\"13\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to main"
+ }
+ -re ".*$mi_gdb_prompt$" {
+ fail "run to main (2)"
+ }
+ timeout {
+ fail "run to main (timeout)"
+ }
+}
+
+# Next over the hello() call which will produce lots of output
+send_gdb "47-exec-next\n"
+gdb_expect {
+ -re "47\\^running\r\n$mi_gdb_prompt" {
+ pass "Started step over hello"
+ }
+ timeout {
+ fail "Started step over hello (timeout)"
+ }
+}
+
+gdb_expect {
+ -re "@\"H\"\r\n.*@\"e\"\r\n.*@\"l\"\r\n.*@\"l\"\r\n.*@\"o\"\r\n.*@\" \"\r\n.*@\"\\\\\\\\\"\r\n.*@\"\\\\\"\"\r\n.*@\"!\"\r\n.*@\"\\\\r\"\r\n.*@\"\\\\n\"\r\n" {
+ pass "Hello message"
+ }
+ -re "Hello" {
+
+ # Probably a native system where GDB doesn't have direct
+ # control over the inferior console.
+ # For this to work, GDB would need to run the inferior process
+ # under a PTY and then use the even-loops ability to wait on
+ # multiple event sources to channel the output back through the
+ # MI.
+
+ fail "Hello message (known bug)"
+ }
+ timeout {
+ fail "Hello message (timeout)"
+ }
+}
+
+gdb_expect {
+ -re "47\\*stopped.*$mi_gdb_prompt$" {
+ pass "Finished step over hello"
+ }
+ timeout {
+ fail "Finished step over hello (timeout)"
+ }
+}
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-disassemble.exp b/gdb/testsuite/gdb.mi/mi-disassemble.exp
new file mode 100644
index 00000000000..6f33d67ac6e
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-disassemble.exp
@@ -0,0 +1,224 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test Machine interface (MI) operations for disassembly.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_breakpoints_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert some breakpoints and list them
+ # Also, disable some so they do not interfere with other tests
+ # Tests:
+ # -break-insert
+ # -break-list
+ # -break-disable
+ # -break-info
+
+ mi_gdb_test "200-break-insert main" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+ "break-insert operation"
+
+ mi_gdb_test "204-break-list" \
+ "204\\^done,BreakpointTable=\{.*,body=\\\[bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}\\\]\}" \
+ "list of breakpoints"
+}
+
+proc test_running_the_program {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Run the program without args
+ # Tests:
+ # -exec-run
+
+ # mi_gdb_test cannot be used for asynchronous commands because there are
+ # two prompts involved and this can lead to a race condition.
+ # FIXME: We are accepting a duplicate file and line info temporarely.
+ # The following is equivalent to a send_gdb "000-exec-run\n"
+ mi_run_cmd
+ # The running part has been checked already by mi_run_cmd
+ gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\\\[\\\],file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to main"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "run to main (2)"}
+ timeout {fail "run to main (timeout 2)"}
+ }
+}
+
+proc test_disassembly_only {} {
+ global mi_gdb_prompt
+ global hex
+ global decimal
+
+ # Test disassembly more only for the current function.
+ # Tests:
+ # -data-disassemble -s $pc -e "$pc+8" -- 0
+ # -data-disassembly -f basics.c -l 32 -- 0
+
+ mi_gdb_test "print/x \$pc" "" ""
+ mi_gdb_test "111-data-disassemble -s \$pc -e \"\$pc + 12\" -- 0" \
+ "111\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\},\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}.*\]" \
+ "data-disassemble from pc to pc+12 assembly only"
+
+ mi_gdb_test "222-data-disassemble -f basics.c -l 32 -- 0" \
+ "222\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"0\",inst=\".*\"\},.*,\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}\\\]" \
+ "data-disassemble file & line, assembly only"
+}
+
+proc test_disassembly_lines_limit {} {
+ global mi_gdb_prompt
+ global hex
+ global decimal
+
+ # Test disassembly more only for the current function.
+ # Tests:
+ # -data-disassembly -f basics.c -l 32 -n 20 -- 0
+ # -data-disassembly -f basics.c -l 32 -n 0 -- 0
+ # -data-disassembly -f basics.c -l 32 -n 50 -- 0
+
+ mi_gdb_test "print/x \$pc" "" ""
+ mi_gdb_test "222-data-disassemble -f basics.c -l 32 -n 20 -- 0" \
+ "222\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"0\",inst=\".*\"\},.*,\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}\\\]" \
+ "data-disassemble file, line, number assembly only"
+
+ mi_gdb_test "222-data-disassemble -f basics.c -l 32 -n 0 -- 0" \
+ "222\\^done,asm_insns=\\\[\\\]" \
+ "data-disassemble file, line, number (zero lines) assembly only"
+
+ mi_gdb_test "222-data-disassemble -f basics.c -l 32 -n 50 -- 0" \
+ "222\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"0\",inst=\".*\"\},.*,\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}\\\]" \
+ "data-disassemble file, line, number (more than main lines) assembly only"
+}
+
+
+proc test_disassembly_mixed {} {
+ global mi_gdb_prompt
+ global hex
+ global decimal
+
+ # Test disassembly more only for the current function.
+ # Tests:
+ # -data-disassembly -f basics.c -l 21 -- 1
+ # -data-disassembly -s $pc -e "$pc+8" -- 1
+
+ mi_gdb_test "002-data-disassemble -f basics.c -l 21 -- 1" \
+ "002\\^done,asm_insns=\\\[src_and_asm_line=\{line=\"21\",file=\".*basics.c\",line_asm_insn=\\\[\{address=\"$hex\",func-name=\"callee2\",offset=\"0\",inst=\".*\"\}.*\\\]\}.*,src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\\\[.*\{address=\"$hex\",func-name=\"callee2\",offset=\"$decimal\",inst=\".*\"\}\\\]\}\\\]" \
+ "data-disassemble file, line assembly mixed"
+
+ #
+ # In mixed mode, the lowest level of granularity is the source line.
+ # So we are going to get the disassembly for the source line at
+ # which we are now, even if we have specified that the range is only 2 insns.
+ #
+ mi_gdb_test "003-data-disassemble -s \$pc -e \"\$pc+4\" -- 1" \
+ "003\\^done,asm_insns=\\\[src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}.*\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}\\\]\}\\\]" \
+ "data-disassemble range assembly mixed"
+}
+
+proc test_disassembly_mixed_lines_limit {} {
+ global mi_gdb_prompt
+ global hex
+ global decimal
+
+ # Test disassembly more only for the current function.
+ # Tests:
+ # -data-disassembly -f basics.c -l 32 -n 20 -- 1
+ # -data-disassembly -f basics.c -l 32 -n 0 -- 1
+ # -data-disassembly -f basics.c -l 32 -n 50 -- 1
+
+ mi_gdb_test "print/x \$pc" "" ""
+ mi_gdb_test "222-data-disassemble -f basics.c -l 32 -n 20 -- 1" \
+ "222\\^done,asm_insns=\\\[src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"0\",inst=\".*\"\},.*,\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}\\\]\}\]" \
+ "data-disassemble file, line, number assembly mixed"
+
+ mi_gdb_test "222-data-disassemble -f basics.c -l 32 -n 0 -- 1" \
+ "222\\^done,asm_insns=\\\[src_and_asm_line=\{line=\"31\",file=\".*basics.c\",line_asm_insn=\\\[\\\]\}\\\]" \
+ "data-disassemble file, line, number (zero lines) assembly mixed"
+
+ mi_gdb_test "222-data-disassemble -f basics.c -l 32 -n 50 -- 1" \
+ "222\\^done,asm_insns=\\\[src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"0\",inst=\".*\"\}.*,\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}\\\]\}\]" \
+ "data-disassemble file, line, number (more than main lines) assembly mixed"
+}
+
+proc test_disassembly_bogus_args {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Test that bogus input to disassembly command is rejected.
+ # Tests:
+ # -data-disassembly -f foo -l abc -n 0 -- 0
+ # -data-disassembly -s foo -e bar -- 0
+ # -data-disassembly -s $pc -f basics.c -- 0
+ # -data-disassembly -f basics.c -l 32 -- 9
+
+ mi_gdb_test "123-data-disassemble -f foo -l abc -n 0 -- 0" \
+ ".*123\\^error,msg=\"mi_cmd_disassemble: Invalid filename.\"" \
+ "data-disassemble bogus filename"
+
+ mi_gdb_test "321-data-disassemble -s foo -e bar -- 0" \
+ "321\\^error,msg=\"No symbol \\\\\"foo\\\\\" in current context.\"" \
+ "data-disassemble bogus address"
+
+ mi_gdb_test "456-data-disassemble -s \$pc -f basics.c -- 0" \
+ "456\\^error,msg=\"mi_cmd_disassemble: Usage: \\( .-f filename -l linenum .-n howmany.. | .-s startaddr -e endaddr.\\) .--. mixed_mode.\"" \
+ "data-disassemble mix different args"
+
+ mi_gdb_test "789-data-disassemble -f basics.c -l 32 -- 9" \
+ "789\\^error,msg=\"mi_cmd_disassemble: Mixed_mode argument must be 0 or 1.\"" \
+ "data-disassemble wrong mode arg"
+
+}
+
+test_breakpoints_creation_and_listing
+test_running_the_program
+test_disassembly_only
+test_disassembly_mixed
+test_disassembly_bogus_args
+test_disassembly_lines_limit
+test_disassembly_mixed_lines_limit
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-eval.exp b/gdb/testsuite/gdb.mi/mi-eval.exp
new file mode 100644
index 00000000000..2c0141069ad
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-eval.exp
@@ -0,0 +1,101 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify -data-evaluate-expression. There are really minimal tests.
+
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_running_the_program {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Run the program without args, then specify srgs and rerun the program
+ # Tests:
+ # -exec-run
+
+ mi_gdb_test "300-break-insert callee4" \
+ "300\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
+ "insert breakpoint at callee4"
+
+ # mi_gdb_test cannot be used for asynchronous commands because there are
+ # two prompts involved and this can lead to a race condition.
+ # The following is equivalent to a send_gdb "000-exec-run\n"
+ mi_run_cmd
+ # The running part has been checked already by mi_run_cmd
+ gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee4\",args=\\\[\\\],file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" \
+ { pass "run to callee4" }
+ -re ".*$mi_gdb_prompt$" {fail "run to callee4 (2)"}
+ timeout {fail "run to callee4 (timeout 2)"}
+ }
+
+ send_gdb "101-exec-next\n"
+ gdb_expect {
+ -re "101\\^running\r\n$mi_gdb_prompt" {
+ gdb_expect {
+ -re "\[\r\n\]*101\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee4\",args=\\\[\\\],file=\".*basics.c\",line=\"9\"\}\r\n$mi_gdb_prompt$" \
+ { pass "next in callee4" }
+ -re ".*$mi_gdb_prompt$" {fail "next in callee4 (2)"}
+ timeout {fail "next in callee4 (timeout 2)"}
+ }
+ }
+ -re ".*$mi_gdb_prompt$" {fail "next in callee4 (1)"}
+ timeout {fail "next in callee4 (timeout 1)"}
+ }
+
+}
+
+test_running_the_program
+
+mi_gdb_test "211-data-evaluate-expression A" "211\\^done,value=\"1\"" "eval A"
+
+mi_gdb_test "311-data-evaluate-expression &A" "311\\^done,value=\"$hex\"" "eval &A"
+
+mi_gdb_test "411-data-evaluate-expression A+3" "411\\^done,value=\"4\"" "eval A+3"
+
+mi_gdb_test "511-data-evaluate-expression \"A + 3\"" "511\\^done,value=\"4\"" "eval A + 3"
+
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-hack-cli.exp b/gdb/testsuite/gdb.mi/mi-hack-cli.exp
new file mode 100644
index 00000000000..a0489431a2e
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-hack-cli.exp
@@ -0,0 +1,40 @@
+# Copyright 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+
+# Some basic checks for the CLI.
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+mi_gdb_test "show architecture" \
+ "&\"show architecture\\\\n\"\r\n~\"The target architecture.*\"\r\n\\^done" \
+ "show architecture"
+
+mi_gdb_test "47show architecture" \
+ "&\"show architecture\\\\n\"\r\n~\"The target architecture.*\"\r\n47\\^done" \
+ "47show architecture"
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-read-memory.c b/gdb/testsuite/gdb.mi/mi-read-memory.c
new file mode 100644
index 00000000000..7a87c641856
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-read-memory.c
@@ -0,0 +1,20 @@
+static char bytes[256];
+
+static short shorts[256];
+
+static void
+initialize (void)
+{
+ int i;
+ for (i = 0; i < sizeof (bytes); i++)
+ {
+ bytes[i] = i;
+ shorts[i] = i * 2;
+ }
+}
+
+int
+main ()
+{
+ initialize ();
+}
diff --git a/gdb/testsuite/gdb.mi/mi-read-memory.exp b/gdb/testsuite/gdb.mi/mi-read-memory.exp
new file mode 100644
index 00000000000..b4f0c35955f
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-read-memory.exp
@@ -0,0 +1,100 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# test basic Machine interface (MI) operations
+#
+# Verify that, using the MI, we can load a program and do
+# other basic things that are used by all test files through mi_gdb_exit,
+# mi_gdb_start, mi_delete_breakpoints, mi_gdb_reinitialize_dir and
+# mi_gdb_load, so we can safely use those.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but the command syntax and correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "mi-read-memory"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+mi_run_to_main
+
+#mi_next "do initialization"
+send_gdb "101-exec-next\n"
+gdb_expect {
+ -re "101\\^running\r\n$mi_gdb_prompt" {
+ gdb_expect {
+ -re "\[\r\n\]*101\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\\\[\\\],file=\".*mi-read-memory.c\",line=\"20\"\}.*$mi_gdb_prompt$" \
+ { pass "do initialization" }
+ -re ".*$mi_gdb_prompt$" {fail "do initialization (2)"}
+ timeout {fail "do initialization (timeout 2)"}
+ }
+ }
+ -re ".*$mi_gdb_prompt$" {fail "do initialization (1)"}
+ timeout {fail "do initialization (timeout 1)"}
+}
+
+mi_gdb_test "1-data-read-memory" \
+ "1\\^error,msg=\".*\"" \
+ "no arguments"
+
+
+mi_gdb_test "2-data-read-memory bytes x 1 3 2" \
+ "2\\^done,addr=\"$hex\",nr-bytes=\"6\",total-bytes=\"6\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory=\\\[{addr=\"$hex\",data=\\\[\"0x00\",\"0x01\"\\\]},{addr=\"$hex\",data=\\\[\"0x02\",\"0x03\"\\\]},{addr=\"$hex\",data=\\\[\"0x04\",\"0x05\"\\\]}\\\]" \
+ "3x2, one byte"
+
+
+mi_gdb_test "9-data-read-memory -o -6 -- -0+bytes+6 x 1 3 2" \
+ "9\\^done,addr=\"$hex\",nr-bytes=\"6\",total-bytes=\"6\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory=\\\[{addr=\"$hex\",data=\\\[\"0x00\",\"0x01\"\\\]},{addr=\"$hex\",data=\\\[\"0x02\",\"0x03\"\\\]},{addr=\"$hex\",data=\\\[\"0x04\",\"0x05\"\\\]}\\\]" \
+ "3x2, one byte offset by -6"
+
+
+mi_gdb_test "3-data-read-memory \"(shorts + 128)\" x 2 1 2" \
+ "3\\^done,addr=\"$hex\",nr-bytes=\"4\",total-bytes=\"4\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory=\\\[{addr=\"$hex\",data=\\\[\"0x0100\",\"0x0102\"\\\]}\\\]" \
+ "expression in quotes"
+
+
+mi_gdb_test "4-data-read-memory bytes+16 x 1 8 4 x" \
+ "4\\^done,addr=\"$hex\",nr-bytes=\"32\",total-bytes=\"32\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory=\\\[{addr=\"$hex\",data=\\\[\"0x10\",\"0x11\",\"0x12\",\"0x13\"\\\],ascii=\"xxxx\"},{addr=\"$hex\",data=\\\[\"0x14\",\"0x15\",\"0x16\",\"0x17\"\\\],ascii=\"xxxx\"},{addr=\"$hex\",data=\\\[\"0x18\",\"0x19\",\"0x1a\",\"0x1b\"\\\],ascii=\"xxxx\"},{addr=\"$hex\",data=\\\[\"0x1c\",\"0x1d\",\"0x1e\",\"0x1f\"\\\],ascii=\"xxxx\"},{addr=\"$hex\",data=\\\[\"0x20\",\"0x21\",\"0x22\",\"0x23\"\\\],ascii=\" !\\\\\"#\"},{addr=\"$hex\",data=\\\[\"0x24\",\"0x25\",\"0x26\",\"0x27\"\\\],ascii=\"\\$%&'\"},{addr=\"$hex\",data=\\\[\"0x28\",\"0x29\",\"0x2a\",\"0x2b\"\\\],ascii=\"().+\"},{addr=\"$hex\",data=\\\[\"0x2c\",\"0x2d\",\"0x2e\",\"0x2f\"\\\],ascii=\",-\./\"}\\\]" \
+ "ascii and data"
+
+
+mi_gdb_test "5-data-read-memory shorts+64 d 2 1 1" \
+ "5\\^done,addr=\"$hex\",nr-bytes=\"2\",total-bytes=\"2\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory=\\\[{addr=\"$hex\",data=\\\[\"128\"\\\]}\\\]" \
+ "decimal"
+
+mi_gdb_test "6-data-read-memory shorts+64 o 2 1 1" \
+ "6\\^done,addr=\"$hex\",nr-bytes=\"2\",total-bytes=\"2\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory=\\\[{addr=\"$hex\",data=\\\[\"0200\"\\\]}\\\]" \
+ "octal"
+
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-regs.exp b/gdb/testsuite/gdb.mi/mi-regs.exp
new file mode 100644
index 00000000000..c427677a41b
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-regs.exp
@@ -0,0 +1,175 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and look at registers.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_breakpoints_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert some breakpoints and list them
+ # Also, disable some so they do not interfere with other tests
+ # Tests:
+ # -break-insert
+ # -break-list
+ # -break-disable
+ # -break-info
+
+ mi_gdb_test "200-break-insert main" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+ "break-insert operation"
+
+ mi_gdb_test "204-break-list" \
+ "204\\^done,BreakpointTable=\{nr_rows=\".\",nr_cols=\".\",hdr=\\\[.*\\\],body=\\\[bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}\\\]\}" \
+ "list of breakpoints"
+}
+
+proc test_running_the_program {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Run the program without args
+ # Tests:
+ # -exec-run
+
+ # mi_gdb_test cannot be used for asynchronous commands because there are
+ # two prompts involved and this can lead to a race condition.
+ # FIXME: We are accepting a duplicate file and line info temporarely.
+ # The following is equivalent to a send_gdb "000-exec-run\n"
+ mi_run_cmd
+ # The running part has been checked already by mi_run_cmd
+ gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\\\[\\\],file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to main"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "run to main (2)"}
+ timeout {fail "run to main (timeout 2)"}
+ }
+}
+
+proc sparc_register_tests_no_exec { } {
+ # Test the generic IDT chip.
+ mi_gdb_test "111-data-list-register-values" \
+ ".*111\\^error,msg=\"mi_cmd_data_list_register_values: Usage: -data-list-register-values <format> \\\[<regnum1>...<regnumN>\\\]\"" \
+ "wrong arguments"
+
+ mi_gdb_test "111-data-list-register-values x" \
+ ".*111\\^error,msg=\"mi_cmd_data_list_register_values: No registers\.\"" \
+ "no executable"
+}
+
+# These tests exercise IDT-specific MIPS registers for several
+# different processor models.
+
+# This should detect the actual processor in use and change
+# the expected results appropriately. FIXME
+
+proc sparc_register_tests { } {
+ global hex
+ global decimal
+ set octal "\[0-7\]+"
+ set binary "\[0-1\]+"
+ set float "\\-?((\[0-9\]+(\\.\[0-9\]+)?(e\[-+\]\[0-9\]+)?)|(nan\\($hex\\)))"
+ set float2 "\\-?\[0-9\]+"
+
+ mi_gdb_test "111-data-list-register-names" \
+ "111\\^done,register-names=\\\[\"g0\",\"g1\",\"g2\",\"g3\",\"g4\",\"g5\",\"g6\",\"g7\",\"o0\",\"o1\",\"o2\",\"o3\",\"o4\",\"o5\",\"sp\",\"o7\",\"l0\",\"l1\",\"l2\",\"l3\",\"l4\",\"l5\",\"l6\",\"l7\",\"i0\",\"i1\",\"i2\",\"i3\",\"i4\",\"i5\",\"fp\",\"i7\",\"f0\",\"f1\",\"f2\",\"f3\",\"f4\",\"f5\",\"f6\",\"f7\",\"f8\",\"f9\",\"f10\",\"f11\",\"f12\",\"f13\",\"f14\",\"f15\",\"f16\",\"f17\",\"f18\",\"f19\",\"f20\",\"f21\",\"f22\",\"f23\",\"f24\",\"f25\",\"f26\",\"f27\",\"f28\",\"f29\",\"f30\",\"f31\",\"y\",\"psr\",\"wim\",\"tbr\",\"pc\",\"npc\",\"fpsr\",\"cpsr\"\\\]" \
+ "list register names"
+
+ mi_gdb_test "222-data-list-register-values x" \
+ "222\\^done,register-values=\\\[\{number=\"0\",value=\"$hex\"\}.*\{number=\"71\",value=\"$hex\"\}\\\]" \
+ "register values x"
+
+ mi_gdb_test "333-data-list-register-values f" \
+ "333\\^done,register-values=\\\[\{number=\"0\",value=\"$float\"\},\{number=\"1\",value=\"$float\"\},.*\{number=\"71\",value=\"$float\"\}\\\]" \
+ "register values f"
+
+ mi_gdb_test "444-data-list-register-values d" \
+ "444\\^done,register-values=\\\[\{number=\"0\",value=\"$decimal\"\}.*\{number=\"71\",value=\"$decimal\"\}\\\]" \
+ "register values d"
+
+ mi_gdb_test "555-data-list-register-values o" \
+ "555\\^done,register-values=\\\[\{number=\"0\",value=\"$octal\"\}.*\{number=\"71\",value=\"$octal\"\}\\\]" \
+ "register values o"
+
+ mi_gdb_test "666-data-list-register-values t" \
+ "666\\^done,register-values=\\\[\{number=\"0\",value=\"$binary\"\}.*\{number=\"71\",value=\"$binary\"\}\\\]" \
+ "register values t"
+
+ # On the sparc, registers 0-31 are int, 32-63 float, 64-71 int
+
+ mi_gdb_test "777-data-list-register-values N" \
+ "777\\^done,register-values=\\\[\{number=\"0\",value=\"$decimal\"\}.*\{number=\"31\",value=\"$decimal\"\},\{number=\"32\",value=\"$float\"\}.*\{number=\"63\",value=\"$float\"\},\{number=\"64\",value=\"$decimal\"\}.*\{number=\"71\",value=\"$decimal\"\}\\\]" \
+ "register values N"
+
+ mi_gdb_test "888-data-list-register-values r" \
+ "888\\^done,register-values=\\\[\{number=\"0\",value=\"$hex\"\}.*\{number=\"71\",value=\"$hex\"\}\\\]" \
+ "register values r"
+
+ mi_gdb_test "999-data-list-register-names 68 69 70 71" \
+ "999\\^done,register-names=\\\[\"pc\",\"npc\",\"fpsr\",\"cpsr\"\\\]" \
+ "list names of some regs"
+
+ mi_gdb_test "001-data-list-register-values x 68 69 70 71" \
+ "001\\^done,register-values=\\\[\{number=\"68\",value=\"$hex\"\},\{number=\"69\",value=\"$hex\"\},\{number=\"70\",value=\"$hex\"\},\{number=\"71\",value=\"$hex\"\}\\\]" \
+ "list values of some regs"
+
+ mi_gdb_test "002-data-list-changed-registers" \
+ "002\\^done,changed-registers=\\\[(\"${decimal}\"(,\"${decimal}\")*)?\\\]" \
+ "list changed registers"
+}
+
+if [istarget "sparc-*-*"] then {
+ sparc_register_tests_no_exec
+ test_breakpoints_creation_and_listing
+ test_running_the_program
+ sparc_register_tests
+} else {
+ verbose "mi-regs.exp tests ignored for this target"
+}
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-return.exp b/gdb/testsuite/gdb.mi/mi-return.exp
new file mode 100644
index 00000000000..318fa8e9d45
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-return.exp
@@ -0,0 +1,94 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test Machine interface (MI) operations
+# Verify that, using the MI, we can run a simple program and perform
+# exec-return.
+
+# The goal is not to
+# test gdb functionality, which is done by other tests, but to verify
+# the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_running_to_callee4 {} {
+ global mi_gdb_prompt
+ global hex
+
+ mi_gdb_test "200-break-insert callee4" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
+ "break-insert operation"
+
+ mi_run_cmd
+
+ gdb_expect {
+ -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee4\",args=\\\[\\\],file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to callee4"
+ }
+ -re ".*$mi_gdb_prompt$" {
+ fail "run to callee4 (2)"
+ }
+ timeout {
+ fail "run to callee4 (timeout)"
+ }
+ }
+
+ mi_gdb_test "205-break-delete" \
+ "205\\^done.*" \
+ "delete all breakpoints"
+
+}
+
+proc test_return_simple {} {
+ global mi_gdb_prompt
+ global hex
+
+ send_gdb "111-exec-return\n"
+ gdb_expect {
+ -re "111\\^done,frame=\{level=\"0 \",addr=\"$hex\",func=\"callee3\",args=\\\[.*\\\],file=\".*basics.c\",line=\"18\"\}\r\n$mi_gdb_prompt$" {pass "return from callee4 now"}
+ -re ".*\r\n$mi_gdb_prompt$" { fail "return from callee4 now" }
+ timeout { fail "return from callee4 now (timeout)"
+ }
+ }
+}
+
+test_running_to_callee4
+test_return_simple
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-simplerun.exp b/gdb/testsuite/gdb.mi/mi-simplerun.exp
new file mode 100644
index 00000000000..a6f82fcca81
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-simplerun.exp
@@ -0,0 +1,199 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and perform basic
+# debugging activities like: insert breakpoints, run the program,
+# step, next, continue until it ends and, last but not least, quit.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_breakpoints_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert some breakpoints and list them
+ # Also, disable some so they do not interfere with other tests
+ # Tests:
+ # -break-insert
+ # -break-list
+ # -break-disable
+ # -break-info
+
+ mi_gdb_test "200-break-insert main" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+ "break-insert operation"
+
+ mi_gdb_test "201-break-insert basics.c:callee2" \
+ "201\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee2\",file=\".*basics.c\",line=\"22\",times=\"0\"\}" \
+ "insert breakpoint at basics.c:callee2"
+
+ mi_gdb_test "202-break-insert basics.c:15" \
+ "202\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee3\",file=\".*basics.c\",line=\"15\",times=\"0\"\}" \
+ "insert breakpoint at basics.c:15 (callee3)"
+
+ mi_gdb_test "203-break-insert \"\\\"${srcfile}\\\":6\"" \
+ "203\\^done,bkpt=\{number=\"4\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"6\",times=\"0\"\}" \
+ "insert breakpoint at \"<fullfilename>\":6 (callee4)"
+
+ mi_gdb_test "204-break-list" \
+ "204\\^done,BreakpointTable=\{.*,hdr=\\\[.*\\\],body=\\\[bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\\\]\}" \
+ "list of breakpoints"
+
+ mi_gdb_test "205-break-disable 2 3 4" \
+ "205\\^done.*" \
+ "disabling of breakpoints"
+
+ mi_gdb_test "206-break-info 2" \
+ "206\\^done,BreakpointTable=\{.*,hdr=\\\[.*\\\],body=\\\[bkpt=\{number=\"2\",.*,enabled=\"n\",.*\}\\\]\}" \
+ "list of breakpoints, 16 disabled"
+}
+
+proc test_running_the_program {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Run the program without args, then specify srgs and rerun the program
+ # Tests:
+ # -exec-run
+ # -gdb-set
+
+ # mi_gdb_test cannot be used for asynchronous commands because there are
+ # two prompts involved and this can lead to a race condition.
+ # The following is equivalent to a send_gdb "000-exec-run\n"
+ mi_run_cmd
+ gdb_expect {
+ -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\\\[\\\],file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to main"
+ }
+ -re ".*$mi_gdb_prompt$" {
+ fail "run to main (2)"
+ }
+ timeout {
+ fail "run to main (timeout)"
+ }
+ }
+}
+
+proc test_controlled_execution {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Continue execution until a breakpoint is reached, step into calls, verifying
+ # if the arguments are correctly shown, continue to the end of a called
+ # function, step over a call (next).
+ # Tests:
+ # -exec-continue
+ # -exec-next
+ # -exec-step
+ # -exec-finish
+
+ mi_next_to "main" "" "basics.c" "33" "next at main"
+
+ # FIXME: A string argument is not printed right; should be fixed and
+ # we should look for the right thing here.
+ # NOTE: The ``\\\\\"'' is for \".
+ mi_step_to "callee1" \
+ "\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument\.\\\\\"\"\},\{name=\"fltarg\",value=\"3.5\"\}" \
+ "basics.c" "27" "step at main"
+
+ # FIXME: A string argument is not printed right; should be fixed and
+ # we should look for the right thing here.
+ mi_run_to "exec-step 3" "end-stepping-range" "callee4" "" \
+ "basics.c" "8" "" "step to callee4"
+
+ # FIXME: A string argument is not printed right; should be fixed and
+ # we should look for the right thing here.
+ # NOTE: The ``.'' is part of ``gdb-result-var="$1"''
+ mi_finish_to "callee3" ".*" "basics.c" "18" ".1" "0" "exec-finish"
+}
+
+proc test_controlling_breakpoints {} {
+ global mi_gdb_prompt
+
+ # Enable, delete, set ignore counts in breakpoints
+ # (disable was already tested above)
+ # Tests:
+ # -break-delete
+ # -break-enable
+ # -break-after
+ # -break-condition
+
+}
+
+proc test_program_termination {} {
+ global mi_gdb_prompt
+
+ # Run to completion: normal and forced
+ # Tests:
+ # -exec-abort
+ # (normal termination of inferior)
+
+ # FIXME: "stopped" doesn't seem appropriate.
+ # mi_gdb_test cannot be used for asynchronous commands because there are
+ # two prompts involved and this can lead to a race condition.
+ send_gdb "999-exec-continue\n"
+ gdb_expect {
+ -re "999\\^running\r\n$mi_gdb_prompt" {
+ gdb_expect {
+ -re "999\\*stopped,reason=\"exited-normally\"\r\n$mi_gdb_prompt$" {
+ pass "continue to end"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "continue to end (2)"}
+ timeout {fail "continue to end (timeout 2)"}
+ }
+ }
+ -re ".*$mi_gdb_prompt$" {fail "continue to end (1)"}
+ timeout {fail "continue to end (timeout 1)"}
+ }
+}
+
+test_breakpoints_creation_and_listing
+test_running_the_program
+test_controlled_execution
+test_controlling_breakpoints
+test_program_termination
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-stack.exp b/gdb/testsuite/gdb.mi/mi-stack.exp
new file mode 100644
index 00000000000..7af458e348d
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-stack.exp
@@ -0,0 +1,218 @@
+# Copyright 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that stack commands work.
+
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+
+mi_gdb_test "200-break-insert callee4" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
+ "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee4\",args=\\\[\\\],file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to callee4"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "run to callee4 (2)"}
+ timeout {fail "run to callee4 (timeout 2)"}
+}
+
+
+proc test_stack_frame_listing {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Obtain a stack trace
+ # Tests:
+ # -stack-list-frames
+ # -stack-list-frames 1 1
+ # -stack-list-frames 1 3
+
+ mi_gdb_test "231-stack-list-frames" \
+ "231\\^done,stack=\\\[frame=\{level=\"0 \",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\"\},frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\},frame=\{level=\"2 \",addr=\"$hex\",func=\"callee2\",.*\},frame=\{level=\"3 \",addr=\"$hex\",func=\"callee1\",.*\},frame=\{level=\"4 \",addr=\"$hex\",func=\"main\",.*\}\\\]" \
+ "stack frame listing"
+ mi_gdb_test "232-stack-list-frames 1 1" \
+ "232\\^done,stack=\\\[frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\}\\\]" \
+ "stack frame listing 1 1"
+ mi_gdb_test "233-stack-list-frames 1 3" \
+ "233\\^done,stack=\\\[frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\},frame=\{level=\"2 \",addr=\"$hex\",func=\"callee2\",.*\},frame=\{level=\"3 \",addr=\"$hex\",func=\"callee1\",.*\}\\\]" \
+ "stack frame listing 1 3"
+
+ mi_gdb_test "234-stack-list-frames 1" \
+ "234\\^error,msg=\"mi_cmd_stack_list_frames: Usage.*FRAME_LOW FRAME_HIGH.*\"" \
+ "stack frame listing wrong"
+}
+
+proc test_stack_args_listing {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Obtain lists for args for the stack frames
+ # Tests:
+ # -stack-list-arguments 0
+ # -stack-list-arguments 0 1 1
+ # -stack-list-arguments 0 1 3
+ # -stack-list-arguments 1
+ # -stack-list-arguments 1 1 1
+ # -stack-list-arguments 1 1 3
+ # -stack-list-arguments
+
+ mi_gdb_test "231-stack-list-arguments 0" \
+ "231\\^done,stack-args=\\\[frame=\{level=\"0\",args=\\\[\\\]\},frame=\{level=\"1\",args=\\\[name=\"strarg\"\\\]\},frame=\{level=\"2\",args=\\\[name=\"intarg\",name=\"strarg\"\\\]\},frame=\{level=\"3\",args=\\\[name=\"intarg\",name=\"strarg\",name=\"fltarg\"\\\]\},frame=\{level=\"4\",args=\\\[\\\]\}\\\]" \
+ "stack args listing 0"
+
+ mi_gdb_test "232-stack-list-arguments 0 1 1" \
+ "232\\^done,stack-args=\\\[frame=\{level=\"1\",args=\\\[name=\"strarg\"\\\]\}\\\]" \
+ "stack args listing 0 1 1"
+
+ mi_gdb_test "233-stack-list-arguments 0 1 3" \
+ "233\\^done,stack-args=\\\[frame=\{level=\"1\",args=\\\[name=\"strarg\"\\\]\},frame=\{level=\"2\",args=\\\[name=\"intarg\",name=\"strarg\"\\\]\},frame=\{level=\"3\",args=\\\[name=\"intarg\",name=\"strarg\",name=\"fltarg\"\\\]\}\\\]" \
+ "stack args listing 0 1 3"
+
+ mi_gdb_test "231-stack-list-arguments 1" \
+ "231\\^done,stack-args=\\\[frame=\{level=\"0\",args=\\\[\\\]\},frame=\{level=\"1\",args=\\\[\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\\\]\},frame=\{level=\"2\",args=\\\[\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\\\]\},frame=\{level=\"3\",args=\\\[\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\},\{name=\"fltarg\",value=\"3.5\"\}\\\]\},frame=\{level=\"4\",args=\\\[\\\]\}\\\]" \
+ "stack args listing 1"
+
+ mi_gdb_test "232-stack-list-arguments 1 1 1" \
+ "232\\^done,stack-args=\\\[frame=\{level=\"1\",args=\\\[\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\\\]\}\\\]" \
+ "stack args listing 1 1 1"
+
+ mi_gdb_test "233-stack-list-arguments 1 1 3" \
+ "233\\^done,stack-args=\\\[frame=\{level=\"1\",args=\\\[\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\\\]\},frame=\{level=\"2\",args=\\\[\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\\\]\},frame=\{level=\"3\",args=\\\[\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\},\{name=\"fltarg\",value=\"3.5\"\}\\\]\}\\\]" \
+ "stack args listing 1 1 3"
+
+ mi_gdb_test "234-stack-list-arguments" \
+ "234\\^error,msg=\"mi_cmd_stack_list_args: Usage.*PRINT_VALUES.*FRAME_LOW FRAME_HIGH.*\"" \
+ "stack args listing wrong"
+}
+
+proc test_stack_info_depth {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Obtain depth of stack
+ # Tests:
+ # -stack-info-depth
+ # -stack-info-depth 3
+ # -stack-info-depth 99
+
+ mi_gdb_test "231-stack-info-depth" \
+ "231\\^done,depth=\"5\"" \
+ "stack info-depth"
+
+ mi_gdb_test "231-stack-info-depth 3" \
+ "231\\^done,depth=\"3\"" \
+ "stack info-depth 3"
+
+ mi_gdb_test "231-stack-info-depth 99" \
+ "231\\^done,depth=\"5\"" \
+ "stack info-depth 99"
+
+ mi_gdb_test "231-stack-info-depth 99 99" \
+ "231\\^error,msg=\"mi_cmd_stack_info_depth: Usage: .MAX_DEPTH.\"" \
+ "stack info-depth wrong usage"
+}
+
+proc test_stack_locals_listing {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Obtain lists for locals for the stack frames
+ # Tests:
+ # -stack-list-locals 0
+ # -stack-list-locals 1
+ # -stack-list-arguments
+
+ mi_gdb_test "232-stack-list-locals 0" \
+ "232\\^done,locals=\\\[name=\"A\",name=\"B\",name=\"C\"\\\]" \
+ "stack locals listing 0"
+
+# step until A, B, C, have some reasonable values.
+send_gdb "-exec-next 3\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee4\",args=\\\[\\\],file=\".*basics.c\",line=\"13\"\}\r\n$mi_gdb_prompt$" {
+ pass "next's in callee4"
+ }
+ timeout { fail "next in callee4 (timeout)" }
+}
+
+ mi_gdb_test "232-stack-list-locals 1" \
+ "232\\^done,locals=\\\[\{name=\"A\",value=\"1\"\},\{name=\"B\",value=\"2\"\},\{name=\"C\",value=\"3\"\}\\\]" \
+ "stack locals listing 1"
+
+ mi_gdb_test "234-stack-list-locals" \
+ "234\\^error,msg=\"mi_cmd_stack_list_locals: Usage.*PRINT_VALUES.*\"" \
+ "stack locals listing wrong"
+
+ mi_gdb_test "232-stack-select-frame 1" \
+ "232\\^done" \
+ "stack select frame 1"
+
+ mi_gdb_test "232-stack-list-locals 1" \
+ "232\\^done,locals=\\\[\\\]" \
+ "stack locals listing for new frame"
+
+# this should be a no-op
+
+ mi_gdb_test "232-stack-select-frame" \
+ "232\\^done" \
+ "stack select same frame"
+
+ mi_gdb_test "232-stack-list-locals 1" \
+ "232\\^done,locals=\\\[\\\]" \
+ "stack locals for same frame (level 1)"
+
+}
+
+test_stack_frame_listing
+test_stack_args_listing
+test_stack_locals_listing
+test_stack_info_depth
+
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-stepi.exp b/gdb/testsuite/gdb.mi/mi-stepi.exp
new file mode 100644
index 00000000000..e0de2f2ccd1
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-stepi.exp
@@ -0,0 +1,109 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test Machine interface (MI) operations
+# Verify that, using the MI, we can run a simple program and perform
+# exec-step-instruction and exec-next-instruction.
+
+# The goal is not to
+# test gdb functionality, which is done by other tests, but to verify
+# the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_running_to_main {} {
+ global mi_gdb_prompt
+ global hex
+
+ mi_gdb_test "200-break-insert main" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+ "break-insert operation"
+
+ mi_run_cmd
+
+ gdb_expect {
+ -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\\\[\\\],file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to main"
+ }
+ -re ".*$mi_gdb_prompt$" {
+ fail "run to main (2)"
+ }
+ timeout {
+ fail "run to main (timeout)"
+ }
+ }
+}
+
+proc test_stepi_nexti {} {
+ global mi_gdb_prompt
+ global hex
+
+ send_gdb "111-exec-step-instruction\n"
+ gdb_expect {
+ -re "111\\^running\r\n${mi_gdb_prompt}111\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\\\[\\\],file=\".*basics.c\",line=\"3.\"\}\r\n$mi_gdb_prompt$" {
+ pass "step-instruction at main"
+ }
+ timeout {
+ fail "step-instruction at main (timeout)"
+ }
+ }
+ send_gdb "222-exec-next-instruction\n"
+ gdb_expect {
+ -re "222\\^running\r\n${mi_gdb_prompt}222\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\\\[\\\],file=\".*basics.c\",line=\"3.\"\}\r\n$mi_gdb_prompt$" {
+ pass "next-instruction at main"
+ }
+ timeout {
+ fail "next-instruction at main (timeout)"
+ }
+ }
+ send_gdb "333-exec-next-instruction\n"
+ gdb_expect {
+ -re "333\\^running\r\n${mi_gdb_prompt}333\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\\\[\\\],file=\".*basics.c\",line=\"3.\"\}\r\n$mi_gdb_prompt$" {
+ pass "next-instruction at main"
+ }
+ timeout {
+ fail "next-instruction at main (timeout)"
+ }
+ }
+}
+
+test_running_to_main
+test_stepi_nexti
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-until.exp b/gdb/testsuite/gdb.mi/mi-until.exp
new file mode 100644
index 00000000000..ac276cc5229
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-until.exp
@@ -0,0 +1,127 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test Machine interface (MI) operations
+# Verify that, using the MI, we can run a simple program and perform
+# exec-until.
+
+# The goal is not to
+# test gdb functionality, which is done by other tests, but to verify
+# the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "until"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_running_to_foo {} {
+ global mi_gdb_prompt
+ global hex
+
+ mi_gdb_test "200-break-insert 10" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"foo\",file=\".*until.c\",line=\"10\",times=\"0\"\}" \
+ "break-insert operation"
+
+ mi_run_cmd
+
+ gdb_expect {
+ -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"foo\",args=\\\[\\\],file=\".*until.c\",line=\"10\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to main"
+ }
+ -re ".*$mi_gdb_prompt$" {
+ fail "run to main (2)"
+ }
+ timeout {
+ fail "run to main (timeout)"
+ }
+ }
+
+ mi_gdb_test "100-break-delete 1" "100\\^done" "break-delete 1"
+
+}
+
+proc test_until {} {
+ global mi_gdb_prompt
+ global hex
+
+ send_gdb "111-exec-until\n"
+ gdb_expect {
+ -re "111\\^running\r\n${mi_gdb_prompt}111\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"foo\",args=\\\[\\\],file=\".*until.c\",line=\"12\"\}\r\n$mi_gdb_prompt$" {
+ pass "until after while loop"
+ }
+ timeout {
+ fail "until after while loop (timeout)"
+ }
+ }
+
+ send_gdb "222-exec-until 15\n"
+ gdb_expect {
+ -re "222\\^running\r\n${mi_gdb_prompt}222\\*stopped,reason=\"location-reached\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"foo\",args=\\\[\\\],file=\".*until.c\",line=\"15\"\}\r\n$mi_gdb_prompt$" {
+ pass "until line number"
+ }
+ timeout {
+ fail "until line number (timeout)"
+ }
+ }
+
+ send_gdb "333-exec-until until.c:17\n"
+ gdb_expect {
+ -re "333\\^running\r\n${mi_gdb_prompt}333\\*stopped,reason=\"location-reached\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"foo\",args=\\\[\\\],file=\".*until.c\",line=\"17\"\}\r\n$mi_gdb_prompt$" {
+ pass "until line number:file"
+ }
+ timeout {
+ fail "until line number:file (timeout)"
+ }
+ }
+
+ # This is supposed to NOT stop at line 25. It stops right after foo is over.
+
+ send_gdb "444-exec-until until.c:25\n"
+ gdb_expect {
+ -re "444\\^running\r\n${mi_gdb_prompt}444\\*stopped,reason=\"location-reached\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\\\[\\\],file=\".*until.c\",line=\"24\"\}\r\n$mi_gdb_prompt$" {
+ pass "until after current function"
+ }
+ timeout {
+ fail "until after current function (timeout)"
+ }
+ }
+
+}
+
+test_running_to_foo
+test_until
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-var-block.exp b/gdb/testsuite/gdb.mi/mi-var-block.exp
new file mode 100644
index 00000000000..ce10041d9e1
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-var-block.exp
@@ -0,0 +1,228 @@
+# Copyright (C) 1999 2000 s Solutions
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can create, update, delete variables.
+#
+
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "var-cmd"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+mi_gdb_test "200-break-insert do_block_tests" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_block_tests\",file=\".*var-cmd.c\",line=\"154\",times=\"0\"\}" \
+ "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"154\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to do_block_tests"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "run to do_block_tests (2)"}
+ timeout {fail "run to do_block_tests (timeout 2)"}
+}
+
+# Test: c_variable-3.2
+# Desc: create cb and foo
+mi_gdb_test "-var-create cb * cb" \
+ "\\^done,name=\"cb\",numchild=\"0\",type=\"int\"" \
+ "create local variable cb"
+
+mi_gdb_test "-var-create foo * foo" \
+ "&\"mi_cmd_var_create: unable to create variable object\\\\n\".*\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
+ "create local variable foo"
+
+# step to "foo = 123;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"158\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_block_tests"
+ }
+ timeout {
+ fail "step at do_block_tests (timeout)"
+ }
+}
+
+
+# Be paranoid and assume 3.2 created foo
+mi_gdb_test "-var-delete foo" \
+ "&\"Variable object not found\\\\n\".*\\^error,msg=\"Variable object not found\"" \
+ "delete var foo"
+
+
+# Test: c_variable-3.3
+# Desc: create foo
+mi_gdb_test "-var-create foo * foo" \
+ "\\^done,name=\"foo\",numchild=\"0\",type=\"int\"" \
+ "create local variable foo"
+
+# step to "foo2 = 123;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"161\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_block_tests"
+ }
+ timeout {
+ fail "step at do_block_tests (timeout)"
+ }
+}
+
+# Test: c_variable-3.4
+# Desc: check foo, cb changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"foo\",in_scope=\"true\",type_changed=\"false\",name=\"cb\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: cb foo changed"
+
+# step to "foo = 321;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"164\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_block_tests"
+ }
+ timeout {
+ fail "step at do_block_tests (timeout)"
+ }
+}
+
+# Test: c_variable-3.5
+# Desc: create inner block foo
+mi_gdb_test "-var-create inner_foo * foo" \
+ "\\^done,name=\"inner_foo\",numchild=\"0\",type=\"int\"" \
+ "create local variable inner_foo"
+
+# step to "foo2 = 0;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"166\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_block_tests"
+ }
+ timeout { fail "step at do_block_tests (timeout)" }
+}
+
+# Test: c_variable-3.6
+# Desc: create foo2
+mi_gdb_test "-var-create foo2 * foo2" \
+ "\\^done,name=\"foo2\",numchild=\"0\",type=\"int\"" \
+ "create local variable foo2"
+
+# Test: c_variable-3.7
+# Desc: check that outer foo in scope and inner foo out of scope
+# Note: also a known gdb problem
+setup_xfail *-*-*
+mi_gdb_test "-var-update inner_foo" \
+ "\\^done,changelist=\{FIXME\}" \
+ "update inner_foo: should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+
+setup_xfail *-*-*
+mi_gdb_test "-var-evaluate-expression inner_foo" \
+ "\\^done,value=\{FIXME\}" \
+ "evaluate inner_foo: should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+
+mi_gdb_test "-var-update foo" \
+ "\\^done,changelist=\{\}" \
+ "update foo: did not change"
+
+mi_gdb_test "-var-delete inner_foo" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var inner_foo"
+
+# step to "foo = 0;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"168\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_block_tests"
+ }
+ timeout { fail "step at do_block_tests (timeout)" }
+}
+
+# Test: c_variable-3.8
+# Desc: check that foo2 out of scope (known gdb problem)
+setup_xfail *-*-*
+mi_gdb_test "-var-update foo2" \
+ "\\^done,changelist=\{FIXME\}" \
+ "update foo2: should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+
+# step to "cb = 21;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"171\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_block_tests"
+ }
+ timeout { fail "step at do_block_tests (timeout)" }
+}
+
+
+# Test: c_variable-3.9
+# Desc: check that only cb is in scope (known gdb problem)
+setup_xfail *-*-*
+mi_gdb_test "-var-update foo2" \
+ "\\^done,changelist=\{FIXME\}" \
+ "update foo2 should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+setup_xfail *-*-*
+mi_gdb_test "-var-update foo" \
+ "\\^done,changelist=\{FIXME\}" \
+ "update foo should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+mi_gdb_test "-var-update cb" \
+ "\\^done,changelist=\{\}" \
+ "update cb"
+
+# Test: c_variable-3.10
+# Desc: names of editable variables
+#gdbtk_test c_variable-3.10 {names of editable variables} {
+# editable_variables
+#} {{foo cb foo2} {}}
+
+# Done with block tests
+mi_gdb_test "-var-delete foo" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var foo"
+
+mi_gdb_test "-var-delete foo2" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var foo2"
+
+mi_gdb_test "-var-delete cb" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var cb"
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-var-child.exp b/gdb/testsuite/gdb.mi/mi-var-child.exp
new file mode 100644
index 00000000000..ba3ad16d616
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-var-child.exp
@@ -0,0 +1,1333 @@
+# Copyright (C) 1999 2000 Cygnus Solutions
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can create, update, delete variables.
+#
+
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "var-cmd"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+mi_gdb_test "200-break-insert do_children_tests" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_children_tests\",file=\".*var-cmd.c\",line=\"190\",times=\"0\"\}" \
+ "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"190\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to do_children_tests"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "run to do_children_tests (2)"}
+ timeout {fail "run to do_children_tests (timeout 2)"}
+}
+
+##### #####
+# #
+# children tests #
+# #
+##### #####
+
+
+# Test: c_variable-4.2
+# Desc: create variable "struct_declarations"
+mi_gdb_test "-var-create struct_declarations * struct_declarations" \
+ "\\^done,name=\"struct_declarations\",numchild=\"11\",type=\"struct _struct_decl\"" \
+ "create local variable struct_declarations"
+
+# Test: c_variable-4.3
+# Desc: children of struct_declarations
+# STABS doesn't give us argument types for the func ptr structs, but
+# Dwarf 2 does.
+mi_gdb_test "-var-list-children struct_declarations" \
+ "\\^done,numchild=\"11\",children=\{child=\{name=\"struct_declarations.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"struct_declarations.character\",exp=\"character\",numchild=\"0\",type=\"char\"\},child={name=\"struct_declarations.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\"\},child=\{name=\"struct_declarations.long_int\",exp=\"long_int\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.int_ptr_ptr\",exp=\"int_ptr_ptr\",numchild=\"1\",type=\"int \\*\\*\"\},child=\{name=\"struct_declarations.long_array\",exp=\"long_array\",numchild=\"10\",type=\"long int \\\[10\\\]\"\},child=\{name=\"struct_declarations.func_ptr\",exp=\"func_ptr\",numchild=\"0\",type=\"void \\(\\*\\)\\((void)?\\)\"\},child=\{name=\"struct_declarations.func_ptr_struct\",exp=\"func_ptr_struct\",numchild=\"0\",type=\"struct _struct_decl \\(\\*\\)\\((int, char \\*, long int)?\\)\"\},child=\{name=\"struct_declarations.func_ptr_ptr\",exp=\"func_ptr_ptr\",numchild=\"0\",type=\"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long int)?\\)\"\},child=\{name=\"struct_declarations.u1\",exp=\"u1\",numchild=\"4\",type=\"union \{\\.\\.\\.\}\"\},child=\{name=\"struct_declarations.s2\",exp=\"s2\",numchild=\"4\",type=\"struct \{\\.\\.\\.\}\"\}\}" \
+ "get children of struct_declarations"
+
+#gdbtk_test c_variable-4.3 {children of struct_declarations} {
+# get_children struct_declarations
+#} {integer character char_ptr long_int int_ptr_ptr long_array func_ptr func_ptr_struct func_ptr_ptr u1 s2}
+
+# Test: c_variable-4.4
+# Desc: number of children of struct_declarations
+mi_gdb_test "-var-info-num-children struct_declarations" \
+ "\\^done,numchild=\"11\"" \
+ "get number of children of struct_declarations"
+
+# Test: c_variable-4.5
+# Desc: children of struct_declarations.integer
+mi_gdb_test "-var-list-children struct_declarations.integer" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.integer"
+
+# Test: c_variable-4.6
+# Desc: number of children of struct_declarations.integer
+mi_gdb_test "-var-info-num-children struct_declarations.integer" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.integer"
+
+# Test: c_variable-4.7
+# Desc: children of struct_declarations.character
+mi_gdb_test "-var-list-children struct_declarations.character" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.character"
+
+# Test: c_variable-4.8
+# Desc: number of children of struct_declarations.character
+mi_gdb_test "-var-info-num-children struct_declarations.character" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.character"
+
+# Test: c_variable-4.9
+# Desc: children of struct_declarations.char_ptr
+mi_gdb_test "-var-list-children struct_declarations.char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"struct_declarations.char_ptr.\\*char_ptr\",exp=\"\\*char_ptr\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of struct_declarations.char_ptr"
+
+# Test: c_variable-4.10
+# Desc: number of children of struct_declarations.char_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of struct_declarations.char_ptr"
+
+# Test: c_variable-4.11
+# Desc: children of struct_declarations.long_int
+mi_gdb_test "-var-list-children struct_declarations.long_int" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_int"
+
+# Test: c_variable-4.12
+# Desc: number of children of struct_declarations.long_int
+mi_gdb_test "-var-info-num-children struct_declarations.long_int" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_int"
+
+# Test: c_variable-4.13
+# Desc: children of int_ptr_ptr
+mi_gdb_test "-var-list-children struct_declarations.int_ptr_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",exp=\"\\*int_ptr_ptr\",numchild=\"1\",type=\"int \\*\"\}\}" \
+ "get children of struct_declarations.int_ptr_ptr"
+
+#gdbtk_test c_variable-4.13 {children of int_ptr_ptr} {
+# get_children struct_declarations.int_ptr_ptr
+#} {*int_ptr_ptr}
+
+# Test: c_variable-4.14
+# Desc: number of children of int_ptr_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.int_ptr_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of struct_declarations.int_ptr_ptr"
+
+
+# Test: c_variable-4.15
+# Desc: children of struct_declarations.long_array
+mi_gdb_test "-var-list-children struct_declarations.long_array" \
+ "\\^done,numchild=\"10\",children=\{child=\{name=\"struct_declarations.long_array.0\",exp=\"0\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.1\",exp=\"1\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.2\",exp=\"2\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.3\",exp=\"3\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.4\",exp=\"4\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.5\",exp=\"5\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.6\",exp=\"6\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.7\",exp=\"7\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.8\",exp=\"8\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.9\",exp=\"9\",numchild=\"0\",type=\"long int\"\}\}" \
+ "get children of struct_declarations.long_array"
+
+# Test: c_variable-4.16
+# Desc: number of children of struct_declarations.long_array
+mi_gdb_test "-var-info-num-children struct_declarations.long_array" \
+ "\\^done,numchild=\"10\"" \
+ "get number of children of struct_declarations.long_array"
+
+# Test: c_variable-4.17
+# Desc: children of struct_declarations.func_ptr
+mi_gdb_test "-var-list-children struct_declarations.func_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.func_ptr"
+
+
+# Test: c_variable-4.18
+# Desc: number of children of struct_declarations.func_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.func_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.func_ptr"
+
+
+# Test: c_variable-4.19
+# Desc: children of struct_declarations.func_ptr_struct
+mi_gdb_test "-var-list-children struct_declarations.func_ptr_struct" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.func_ptr_struct"
+
+# Test: c_variable-4.20
+# Desc: number of children of struct_declarations.func_ptr_struct
+mi_gdb_test "-var-info-num-children struct_declarations.func_ptr_struct" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.func_ptr_struct"
+
+
+# Test: c_variable-4.21
+# Desc: children of struct_declarations.func_ptr_ptr
+mi_gdb_test "-var-list-children struct_declarations.func_ptr_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.func_ptr_ptr"
+
+# Test: c_variable-4.22
+# Desc: number of children of struct_declarations.func_ptr_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.func_ptr_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.func_ptr_ptr"
+
+
+# Test: c_variable-4.23
+# Desc: children of struct_declarations.u1
+mi_gdb_test "-var-list-children struct_declarations.u1" \
+ "\\^done,numchild=\"4\",children=\{child=\{name=\"struct_declarations.u1.a\",exp=\"a\",numchild=\"0\",type=\"int\"\},child=\{name=\"struct_declarations.u1.b\",exp=\"b\",numchild=\"1\",type=\"char \\*\"\},child=\{name=\"struct_declarations.u1.c\",exp=\"c\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.u1.d\",exp=\"d\",numchild=\"0\",type=\"enum foo\"\}\}" \
+ "get children of struct_declarations.u1"
+
+# Test: c_variable-4.24
+# Desc: number of children of struct_declarations.u1
+mi_gdb_test "-var-info-num-children struct_declarations.u1" \
+ "\\^done,numchild=\"4\"" \
+ "get number of children of struct_declarations.u1"
+
+# Test: c_variable-4.25
+# Desc: children of struct_declarations.s2
+mi_gdb_test "-var-list-children struct_declarations.s2" \
+ "\\^done,numchild=\"4\",children=\{child=\{name=\"struct_declarations.s2.u2\",exp=\"u2\",numchild=\"3\",type=\"union \{\\.\\.\\.\}\"\},child=\{name=\"struct_declarations.s2.g\",exp=\"g\",numchild=\"0\",type=\"int\"\},child=\{name=\"struct_declarations.s2.h\",exp=\"h\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.i\",exp=\"i\",numchild=\"10\",type=\"long int \\\[10\\\]\"\}\}" \
+ "get children of struct_declarations.s2"
+#gdbtk_test c_variable-4.25 {children of struct_declarations.s2} {
+# get_children struct_declarations.s2
+#} {u2 g h i}
+
+# Test: c_variable-4.26
+# Desc: number of children of struct_declarations.s2
+mi_gdb_test "-var-info-num-children struct_declarations.s2" \
+ "\\^done,numchild=\"4\"" \
+ "get number of children of struct_declarations.s2"
+
+
+# Test: c_variable-4.27
+# Desc: children of struct_declarations.long_array.1
+mi_gdb_test "-var-list-children struct_declarations.long_array.1" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.1"
+
+# Test: c_variable-4.28
+# Desc: number of children of struct_declarations.long_array.1
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.1" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.1"
+
+# Test: c_variable-4.29
+# Desc: children of struct_declarations.long_array.2
+mi_gdb_test "-var-list-children struct_declarations.long_array.2" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.2"
+
+# Test: c_variable-4.30
+# Desc: number of children of struct_declarations.long_array.2
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.2" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.2"
+
+# Test: c_variable-4.31
+# Desc: children of struct_declarations.long_array.3
+mi_gdb_test "-var-list-children struct_declarations.long_array.3" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.3"
+
+# Test: c_variable-4.32
+# Desc: number of children of struct_declarations.long_array.3
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.3" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.3"
+
+# Test: c_variable-4.33
+# Desc: children of struct_declarations.long_array.4
+mi_gdb_test "-var-list-children struct_declarations.long_array.4" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.4"
+
+# Test: c_variable-4.34
+# Desc: number of children of struct_declarations.long_array.4
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.4" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.4"
+
+# Test: c_variable-4.35
+# Desc: children of struct_declarations.long_array.5
+mi_gdb_test "-var-list-children struct_declarations.long_array.5" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.5"
+
+# Test: c_variable-4.36
+# Desc: number of children of struct_declarations.long_array.5
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.5" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.5"
+
+# Test: c_variable-4.37
+# Desc: children of struct_declarations.long_array.6
+mi_gdb_test "-var-list-children struct_declarations.long_array.6" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.6"
+
+# Test: c_variable-4.38
+# Desc: number of children of struct_declarations.long_array.6
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.6" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.6"
+
+# Test: c_variable-4.39
+# Desc: children of struct_declarations.long_array.7
+mi_gdb_test "-var-list-children struct_declarations.long_array.7" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.7"
+
+# Test: c_variable-4.40
+# Desc: number of children of struct_declarations.long_array.7
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.7" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.7"
+
+# Test: c_variable-4.41
+# Desc: children of struct_declarations.long_array.8
+mi_gdb_test "-var-list-children struct_declarations.long_array.8" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.8"
+
+# Test: c_variable-4.42
+# Desc: number of children of struct_declarations.long_array.8
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.8" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.8"
+
+
+# Test: c_variable-4.43
+# Desc: children of struct_declarations.long_array.9
+mi_gdb_test "-var-list-children struct_declarations.long_array.9" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.9"
+
+# Test: c_variable-4.44
+# Desc: number of children of struct_declarations.long_array.9
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.9" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.9"
+
+# Test: c_variable-4.45
+# Desc: children of struct_declarations.u1.a
+mi_gdb_test "-var-list-children struct_declarations.u1.a" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.u1.a"
+
+# Test: c_variable-4.46
+# Desc: number of children of struct_declarations.u1.a
+mi_gdb_test "-var-info-num-children struct_declarations.u1.a" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.u1.a"
+
+# Test: c_variable-4.47
+# Desc: children of struct_declarations.u1.b
+mi_gdb_test "-var-list-children struct_declarations.u1.b" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"struct_declarations.u1.b.\\*b\",exp=\"\\*b\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of struct_declarations.u1.b"
+
+# Test: c_variable-4.48
+# Desc: number of children of struct_declarations.u1.b
+mi_gdb_test "-var-info-num-children struct_declarations.u1.b" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of struct_declarations.u1.b"
+
+# Test: c_variable-4.49
+# Desc: children of struct_declarations.u1.c
+mi_gdb_test "-var-list-children struct_declarations.u1.c" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.u1.c"
+
+# Test: c_variable-4.50
+# Desc: number of children of struct_declarations.u1.c
+mi_gdb_test "-var-info-num-children struct_declarations.u1.c" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.u1.c"
+
+# Test: c_variable-4.51
+# Desc: children of struct_declarations.u1.d
+mi_gdb_test "-var-list-children struct_declarations.u1.d" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.u1.d"
+
+
+# Test: c_variable-4.52
+# Desc: number of children of struct_declarations.u1.d
+mi_gdb_test "-var-info-num-children struct_declarations.u1.d" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.u1.d"
+
+
+# Test: c_variable-4.53
+# Desc: children of struct_declarations.s2.u2
+mi_gdb_test "-var-list-children struct_declarations.s2.u2" \
+ "\\^done,numchild=\"3\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s1\",exp=\"u1s1\",numchild=\"4\",type=\"struct \{\\.\\.\\.\}\"\},child=\{name=\"struct_declarations.s2.u2.f\",exp=\"f\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.u2.u1s2\",exp=\"u1s2\",numchild=\"2\",type=\"struct \{\\.\\.\\.\}\"\}\}" \
+ "get children of struct_declarations.s2.u2"
+
+# Test: c_variable-4.54
+# Desc: number of children of struct_declarations.s2.u2
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2" \
+ "\\^done,numchild=\"3\"" \
+ "get number of children of struct_declarations.s2.u2"
+
+# Test: c_variable-4.55
+# Desc: children of struct_declarations.s2.g
+mi_gdb_test "-var-list-children struct_declarations.s2.g" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.s2.g"
+
+# Test: c_variable-4.56
+# Desc: number of children of struct_declarations.s2.g
+mi_gdb_test "-var-info-num-children struct_declarations.s2.g" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.s2.g"
+
+
+# Test: c_variable-4.57
+# Desc: children of struct_declarations.s2.h
+mi_gdb_test "-var-list-children struct_declarations.s2.h" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.s2.h"
+
+# Test: c_variable-4.58
+# Desc: number of children of struct_declarations.s2.h
+mi_gdb_test "-var-info-num-children struct_declarations.s2.h" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.s2.h"
+
+
+# Test: c_variable-4.59
+# Desc: children of struct_declarations.s2.i
+mi_gdb_test "-var-list-children struct_declarations.s2.i" \
+ "\\^done,numchild=\"10\",children=\{child=\{name=\"struct_declarations.s2.i.0\",exp=\"0\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.1\",exp=\"1\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.2\",exp=\"2\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.3\",exp=\"3\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.4\",exp=\"4\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.5\",exp=\"5\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.6\",exp=\"6\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.7\",exp=\"7\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.8\",exp=\"8\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.9\",exp=\"9\",numchild=\"0\",type=\"long int\"\}\}" \
+ "get children of struct_declarations.s2.i"
+
+# Test: c_variable-4.60
+# Desc: number of children of struct_declarations.s2.i
+mi_gdb_test "-var-info-num-children struct_declarations.s2.i" \
+ "\\^done,numchild=\"10\"" \
+ "get number of children of struct_declarations.s2.i"
+
+# Test: c_variable-4.61
+# Desc: children of struct_declarations.s2.u2.u1s1
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1" \
+ "\\^done,numchild=\"4\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s1.d\",exp=\"d\",numchild=\"0\",type=\"int\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e\",exp=\"e\",numchild=\"10\",type=\"char \\\[10\\\]\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.func\",exp=\"func\",numchild=\"0\",type=\"int \\*\\(\\*\\)\\((void)?\\)\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.foo\",exp=\"foo\",numchild=\"0\",type=\"efoo\"\}\}" \
+ "get children of struct_declarations.s2.u2.u1s1"
+
+# Test: c_variable-4.62
+# Desc: number of children of struct_declarations.s2.u2.u1s1
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1" \
+ "\\^done,numchild=\"4\"" \
+ "get number of children of struct_declarations.s2.u2.u1s1"
+
+# Test: c_variable-4.63
+# Desc: children of struct_declarations.s2.u2.f
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.f" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.s2.u2.f"
+
+# Test: c_variable-4.64
+# Desc: number of children of struct_declarations.s2.u2.f
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.f" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.s2.u2.f"
+
+# Test: c_variable-4.65
+# Desc: children of struct_declarations.s2.u2.u1s2
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s2" \
+ "\\^done,numchild=\"2\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s2.array_ptr\",exp=\"array_ptr\",numchild=\"2\",type=\"char \\\[2\\\]\"\},child=\{name=\"struct_declarations.s2.u2.u1s2.func\",exp=\"func\",numchild=\"0\",type=\"int \\(\\*\\)\\((int, char \\*)?\\)\"\}\}" \
+ "get children of struct_declarations.s2.u2.u1s2"
+
+# Test: c_variable-4.66
+# Desc: number of children of struct_declarations.s2.u2.u1s2
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s2" \
+ "\\^done,numchild=\"2\"" \
+ "get number of children of struct_declarations.s2.u2.u1s2"
+
+# Test: c_variable-4.67
+# Desc: children of struct_declarations.s2.u2.u1s1.d
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1.d" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.s2.u2.u1s1.d"
+
+# Test: c_variable-4.68
+# Desc: number of children of struct_declarations.s2.u2.u1s1.d
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1.d" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.s2.u2.u1s1.d"
+
+# Test: c_variable-4.69
+# Desc: children of struct_declarations.s2.u2.u1s1.e
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1.e" \
+ "\\^done,numchild=\"10\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s1.e.0\",exp=\"0\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.1\",exp=\"1\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.2\",exp=\"2\",numchild=\"0\",type=\"char\"\},child={name=\"struct_declarations.s2.u2.u1s1.e.3\",exp=\"3\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.4\",exp=\"4\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.5\",exp=\"5\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.6\",exp=\"6\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.7\",exp=\"7\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.8\",exp=\"8\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.9\",exp=\"9\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of struct_declarations.s2.u2.u1s1.e"
+
+# Test: c_variable-4.70
+# Desc: number of children of struct_declarations.s2.u2.u1s1.e
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1.e" \
+ "\\^done,numchild=\"10\"" \
+ "get number of children of struct_declarations.s2.u2.u1s1.e"
+
+
+# Test: c_variable-4.71
+# Desc: children of struct_declarations.s2.u2.u1s1.func
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1.func" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.s2.u2.u1s1.func"
+
+# Test: c_variable-4.72
+# Desc: number of children of struct_declarations.s2.u2.u1s1.func
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1.func" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.s2.u2.u1s1.func"
+
+
+# Test: c_variable-4.73
+# Desc: children of struct_declarations.s2.u2.u1s1.foo
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1.foo" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.s2.u2.u1s1.foo"
+
+# Test: c_variable-4.74
+# Desc: number of children of struct_declarations.s2.u2.u1s1.foo
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1.foo" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.s2.u2.u1s1.foo"
+
+
+# Test: c_variable-4.75
+# Desc: children of struct_declarations.s2.u2.u1s2.array_ptr
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s2.array_ptr" \
+ "\\^done,numchild=\"2\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s2.array_ptr.0\",exp=\"0\",numchild=\"0\",type=\"char\"\},child={name=\"struct_declarations.s2.u2.u1s2.array_ptr.1\",exp=\"1\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of struct_declarations.s2.u2.u1s2.array_ptr"
+
+# Test: c_variable-4.76
+# Desc: number of children of struct_declarations.s2.u2.u1s2.array_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s2.array_ptr" \
+ "\\^done,numchild=\"2\"" \
+ "get number of children of struct_declarations.s2.u2.u1s2.array_ptr"
+
+# Test: c_variable-4.77
+# Desc: children of struct_declarations.s2.u2.u1s2.func
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s2.func" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.s2.u2.u1s2.func"
+
+# Test: c_variable-4.78
+# Desc: number of children of struct_declarations.s2.u2.u1s2.func
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s2.func" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.s2.u2.u1s2.func"
+
+# Test: c_variable-4.79
+# Desc: children of struct_declarations.int_ptr_ptr.*int_ptr_ptr
+mi_gdb_test "-var-list-children struct_declarations.int_ptr_ptr.*int_ptr_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",exp=\"\\*\\*int_ptr_ptr\",numchild=\"0\",type=\"int\"\}\}" \
+ "get children of struct_declarations.int_ptr_ptr.*int_ptr_ptr"
+#} {**int_ptr_ptr}
+
+# Test: c_variable-4.80
+# Desc: Number of children of struct_declarations.int_ptr_ptr.*int_ptr_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.int_ptr_ptr.*int_ptr_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of struct_declarations.int_ptr_ptr.*int_ptr_ptr"
+
+
+# Step to "struct_declarations.integer = 123;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"192\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+
+# Test: c_variable-4.81
+# Desc: create local variable "weird"
+mi_gdb_test "-var-create weird * weird" \
+ "\\^done,name=\"weird\",numchild=\"11\",type=\"weird_struct \\*\"" \
+ "create local variable weird"
+
+# Test: c_variable-4.82
+# Desc: children of weird
+mi_gdb_test "-var-list-children weird" \
+ "\\^done,numchild=\"11\",children=\{child=\{name=\"weird.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"weird.character\",exp=\"character\",numchild=\"0\",type=\"char\"\},child=\{name=\"weird.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\"\},child=\{name=\"weird.long_int\",exp=\"long_int\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.int_ptr_ptr\",exp=\"int_ptr_ptr\",numchild=\"1\",type=\"int \\*\\*\"\},child=\{name=\"weird.long_array\",exp=\"long_array\",numchild=\"10\",type=\"long int \\\[10\\\]\"\},child=\{name=\"weird.func_ptr\",exp=\"func_ptr\",numchild=\"0\",type=\"void \\(\\*\\)\\((void)?\\)\"\},child=\{name=\"weird.func_ptr_struct\",exp=\"func_ptr_struct\",numchild=\"0\",type=\"struct _struct_decl \\(\\*\\)\\((int, char \\*, long int)?\\)\"\},child=\{name=\"weird.func_ptr_ptr\",exp=\"func_ptr_ptr\",numchild=\"0\",type=\"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long int)?\\)\"\},child=\{name=\"weird.u1\",exp=\"u1\",numchild=\"4\",type=\"union \{\\.\\.\\.\}\"\},child=\{name=\"weird.s2\",exp=\"s2\",numchild=\"4\",type=\"struct \{\\.\\.\\.\}\"\}\}" \
+ "get children of weird"
+
+# Test: c_variable-4.83
+# Desc: number of children of weird
+mi_gdb_test "-var-info-num-children weird" \
+ "\\^done,numchild=\"11\"" \
+ "get number of children of weird"
+
+
+# Test: c_variable-4.84
+# Desc: children of weird->long_array
+mi_gdb_test "-var-list-children weird.long_array" \
+ "\\^done,numchild=\"10\",children=\{child=\{name=\"weird.long_array.0\",exp=\"0\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.1\",exp=\"1\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.2\",exp=\"2\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.3\",exp=\"3\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.4\",exp=\"4\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.5\",exp=\"5\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.6\",exp=\"6\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.7\",exp=\"7\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.8\",exp=\"8\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.9\",exp=\"9\",numchild=\"0\",type=\"long int\"\}\}" \
+ "get children of weird.long_array"
+#gdbtk_test c_variable-4.84 {children of weird->long_array} {
+# get_children weird.long_array
+#} {0 1 2 3 4 5 6 7 8 9}
+
+# Test: c_variable-4.85
+# Desc: number of children of weird.long_array
+mi_gdb_test "-var-info-num-children weird.long_array" \
+ "\\^done,numchild=\"10\"" \
+ "get number of children of weird.long_array"
+
+# Test: c_variable-4.86
+# Desc: children of weird.int_ptr_ptr
+mi_gdb_test "-var-list-children weird.int_ptr_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"weird.int_ptr_ptr.\\*int_ptr_ptr\",exp=\"\\*int_ptr_ptr\",numchild=\"1\",type=\"int \\*\"\}\}" \
+ "get children of weird.int_ptr_ptr"
+#gdbtk_test c_variable-4.86 {children of weird->int_ptr_ptr} {
+# get_children weird.int_ptr_ptr
+#} {*int_ptr_ptr}
+
+# Test: c_variable-4.87
+# Desc: number of children of weird.int_ptr_ptr
+mi_gdb_test "-var-info-num-children weird.int_ptr_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of weird.int_ptr_ptr"
+
+# Test: c_variable-4.88
+# Desc: children of *weird->int_ptr_ptr
+mi_gdb_test "-var-list-children weird.int_ptr_ptr.*int_ptr_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"weird.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",exp=\"\\*\\*int_ptr_ptr\",numchild=\"0\",type=\"int\"\}\}" \
+ "get children of weird.int_ptr_ptr.*int_ptr_ptr"
+#gdbtk_test c_variable-4.88 {children of *weird->int_ptr_ptr} {
+# get_children weird.int_ptr_ptr.*int_ptr_ptr
+#} {**int_ptr_ptr}
+
+# Test: c_variable-4.89
+# Desc: number of children *weird->int_ptr_ptr
+mi_gdb_test "-var-info-num-children weird.int_ptr_ptr.*int_ptr_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of weird.int_ptr_ptr.*int_ptr_ptr"
+
+# Test: c_variable-4.90
+# Desc: create weird->int_ptr_ptr
+mi_gdb_test "-var-create weird->int_ptr_ptr * weird->int_ptr_ptr" \
+ "\\^done,name=\"weird->int_ptr_ptr\",numchild=\"1\",type=\"int \\*\\*\"" \
+ "create local variable weird->int_ptr_ptr"
+
+# Test: c_variable-4.91
+# Desc: children of weird->int_ptr_ptr
+mi_gdb_test "-var-list-children weird->int_ptr_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",exp=\"\\*weird->int_ptr_ptr\",numchild=\"1\",type=\"int \\*\"\}\}" \
+ "get children of weird->int_ptr_ptr"
+
+
+# Test: c_variable-4.92
+# Desc: number of children of (weird->int_ptr_ptr)
+mi_gdb_test "-var-info-num-children weird->int_ptr_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of weird->int_ptr_ptr"
+
+# Test: c_variable-4.93
+# Desc: children of *(weird->int_ptr_ptr)
+mi_gdb_test "-var-list-children weird->int_ptr_ptr.*weird->int_ptr_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",exp=\"\\*\\*weird->int_ptr_ptr\",numchild=\"0\",type=\"int\"\}\}" \
+ "get children of weird->int_ptr_ptr.*weird->int_ptr_ptr"
+
+# Test: c_variable-4.94
+# Desc: number of children of *(weird->int_ptr_ptr)
+mi_gdb_test "-var-info-num-children weird->int_ptr_ptr.*weird->int_ptr_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of weird->int_ptr_ptr.*weird->int_ptr_ptr"
+
+# Test: c_variable-4.95
+# Desc: children of *(*(weird->int_ptr_ptr))
+mi_gdb_test "-var-list-children weird->int_ptr_ptr.*weird->int_ptr_ptr.**weird->int_ptr_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get children of weird->int_ptr_ptr.*weird->int_ptr_ptr.**weird->int_ptr_ptr"
+
+# Test: c_variable-4.96
+# Desc: number of children of *(*(weird->int_ptr_ptr))
+mi_gdb_test "-var-info-num-children weird->int_ptr_ptr.*weird->int_ptr_ptr.**weird->int_ptr_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of weird->int_ptr_ptr.*weird->int_ptr_ptr.**weird->int_ptr_ptr"
+
+# Test: c_variable-4.97
+# Desc: is weird editable
+mi_gdb_test "-var-show-attributes weird" \
+ "\\^done,attr=\"editable\"" \
+ "is weird editable"
+
+# Test: c_variable-4.98
+# Desc: is weird->int_ptr_ptr editable
+mi_gdb_test "-var-show-attributes weird->int_ptr_ptr" \
+ "\\^done,attr=\"editable\"" \
+ "is weird->int_ptr_ptr editable"
+
+# Test: c_variable-4.99
+# Desc: is *(weird->int_ptr_ptr) editable
+mi_gdb_test "-var-show-attributes weird.int_ptr_ptr.*int_ptr_ptr" \
+ "\\^done,attr=\"editable\"" \
+ "is weird.int_ptr_ptr.*int_ptr_ptr editable"
+
+# Test: c_variable-4.100
+# Desc: is *(*(weird->int_ptr_ptr)) editable
+mi_gdb_test "-var-show-attributes weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr" \
+ "\\^done,attr=\"editable\"" \
+ "is weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr editable"
+
+# Test: c_variable-4.101
+# Desc: is weird->u1 editable
+mi_gdb_test "-var-show-attributes weird.u1" \
+ "\\^done,attr=\"noneditable\"" \
+ "is weird.u1 editable"
+
+# Test: c_variable-4.102
+# Desc: is weird->s2 editable
+mi_gdb_test "-var-show-attributes weird.s2" \
+ "\\^done,attr=\"noneditable\"" \
+ "is weird.s2 editable"
+
+# Test: c_variable-4.103
+# Desc: is struct_declarations.u1.a editable
+mi_gdb_test "-var-show-attributes struct_declarations.u1.a" \
+ "\\^done,attr=\"editable\"" \
+ "is struct_declarations.u1.a editable"
+
+# Test: c_variable-4.104
+# Desc: is struct_declarations.u1.b editable
+mi_gdb_test "-var-show-attributes struct_declarations.u1.b" \
+ "\\^done,attr=\"editable\"" \
+ "is struct_declarations.u1.b editable"
+
+# Test: c_variable-4.105
+# Desc: is struct_declarations.u1.c editable
+mi_gdb_test "-var-show-attributes struct_declarations.u1.c" \
+ "\\^done,attr=\"editable\"" \
+ "is struct_declarations.u1.c editable"
+
+# Test: c_variable-4.106
+# Desc: is struct_declarations.long_array editable
+mi_gdb_test "-var-show-attributes struct_declarations.long_array" \
+ "\\^done,attr=\"noneditable\"" \
+ "is struct_declarations.long_array editable"
+
+# Test: c_variable-4.107
+# Desc: is struct_declarations.long_array[0] editable
+mi_gdb_test "-var-show-attributes struct_declarations.long_array.0" \
+ "\\^done,attr=\"editable\"" \
+ "is struct_declarations.long_array.0 editable"
+
+# Test: c_variable-4.108
+# Desc: is struct_declarations editable
+mi_gdb_test "-var-show-attributes struct_declarations" \
+ "\\^done,attr=\"noneditable\"" \
+ "is struct_declarations editable"
+
+mi_gdb_test "-var-delete weird" \
+ "\\^done,ndeleted=\"24\"" \
+ "delete var weird"
+
+##### #####
+# #
+# children and update tests #
+# #
+##### #####
+
+# Test: c_variable-5.1
+# Desc: check that nothing changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{\}" \
+ "update all vars. None changed"
+
+# Step over "struct_declarations.integer = 123;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"193\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.2
+# Desc: check that integer changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars struct_declarations.integer"
+
+# Step over:
+# weird->char_ptr = "hello";
+# bar = 2121;
+# foo = &bar;
+
+send_gdb "-exec-step 3\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"196\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.3
+# Desc: check that char_ptr changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars struct_declarations.char_ptr"
+
+# Step over "struct_declarations.int_ptr_ptr = &foo;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"197\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.4
+# Desc: check that int_ptr_ptr and children changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars int_ptr_ptr and children changed"
+
+# Step over "weird->long_array[0] = 1234;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"198\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.5
+# Desc: check that long_array[0] changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars struct_declarations.long_array.0 changed"
+
+# Step over "struct_declarations.long_array[1] = 2345;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"199\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.6
+# Desc: check that long_array[1] changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars struct_declarations.long_array.1 changed"
+
+# Step over "weird->long_array[2] = 3456;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"200\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.7
+# Desc: check that long_array[2] changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars struct_declarations.long_array.2 changed"
+
+# Step over:
+# struct_declarations.long_array[3] = 4567;
+# weird->long_array[4] = 5678;
+# struct_declarations.long_array[5] = 6789;
+# weird->long_array[6] = 7890;
+# struct_declarations.long_array[7] = 8901;
+# weird->long_array[8] = 9012;
+# struct_declarations.long_array[9] = 1234;
+send_gdb "-exec-step 7\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"208\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.8
+# Desc: check that long_array[3-9] changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars struct_declarations.long_array.3-9 changed"
+
+
+# Step over "weird->func_ptr = nothing;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"211\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.9
+# Desc: check that func_ptr changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars struct_declarations.func_ptr changed"
+
+# Delete all variables
+mi_gdb_test "-var-delete struct_declarations" \
+ "\\^done,ndeleted=\"65\"" \
+ "delete var struct_declarations"
+
+mi_gdb_test "-var-delete weird->int_ptr_ptr" \
+ "\\^done,ndeleted=\"3\"" \
+ "delete var weird->int_ptr_ptr"
+
+# Step over all lines:
+# ...
+# psnp = &snp0;
+send_gdb "-exec-step 43\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"254\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.10
+# Desc: create psnp->char_ptr
+mi_gdb_test "-var-create psnp->char_ptr * psnp->char_ptr" \
+ "\\^done,name=\"psnp->char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\\*\"" \
+ "create local variable psnp->char_ptr"
+
+# Test: c_variable-5.11
+# Desc: children of psnp->char_ptr
+mi_gdb_test "-var-list-children psnp->char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",exp=\"\\*psnp->char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\"\}\}" \
+ "get children of psnp->char_ptr"
+
+# Test: c_variable-5.12
+# Desc: number of children of psnp->char_ptr
+mi_gdb_test "-var-info-num-children psnp->char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->char_ptr"
+
+# Test: c_variable-5.13
+# Desc: children of *(psnp->char_ptr)
+mi_gdb_test "-var-list-children psnp->char_ptr.*psnp->char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",exp=\"\\*\\*psnp->char_ptr\",numchild=\"1\",type=\"char \\*\\*\"\}\}" \
+ "get children of psnp->char_ptr.*psnp->char_ptr"
+
+# Test: c_variable-5.14
+# Desc: number of children of *(psnp->char_ptr)
+mi_gdb_test "-var-info-num-children psnp->char_ptr.*psnp->char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->char_ptr.*psnp->char_ptr"
+
+# Test: c_variable-5.15
+# Desc: children of *(*(psnp->char_ptr))
+mi_gdb_test "-var-list-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",exp=\"\\*\\*\\*psnp->char_ptr\",numchild=\"1\",type=\"char \\*\"\}\}" \
+ "get children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr"
+
+# Test: c_variable-5.15B
+# Desc: children of *(*(*(psnp->char_ptr)))
+mi_gdb_test "-var-list-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",exp=\"\\*\\*\\*\\*psnp->char_ptr\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr"
+
+# Test: c_variable-5.16
+# Desc: number of children of *(*(psnp->char_ptr))
+mi_gdb_test "-var-info-num-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr"
+
+# Test: c_variable-5.17
+# Desc: children of *(*(*(psnp->char_ptr)))
+mi_gdb_test "-var-list-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",exp=\"\\*\\*\\*\\*psnp->char_ptr\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr"
+
+# Test: c_variable-5.18
+# Desc: number of children of *(*(*(psnp->char_ptr)))
+mi_gdb_test "-var-info-num-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr"
+
+# Test: c_variable-5.17B
+# Desc: children of *(*(*(*(psnp->char_ptr))))
+mi_gdb_test "-var-list-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr.****psnp->char_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr.****psnp->char_ptr"
+
+# Test: c_variable-5.18B
+# Desc: number of children of *(*(*(*(psnp->char_ptr))))
+mi_gdb_test "-var-info-num-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr.****psnp->char_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr.****psnp->char_ptr"
+
+
+# Test: c_variable-5.19
+# Desc: create psnp->long_ptr
+mi_gdb_test "-var-create psnp->long_ptr * psnp->long_ptr" \
+ "\\^done,name=\"psnp->long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\\*\"" \
+ "create local variable psnp->long_ptr"
+
+# Test: c_variable-5.20
+# Desc: children of psnp->long_ptr
+mi_gdb_test "-var-list-children psnp->long_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",exp=\"\\*psnp->long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\"\}\}" \
+ "get children of psnp->long_ptr"
+
+# Test: c_variable-5.21
+# Desc: number of children of psnp->long_ptr
+mi_gdb_test "-var-info-num-children psnp->long_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->long_ptr"
+
+# Test: c_variable-5.22
+# Desc: children of *(psnp->long_ptr)
+mi_gdb_test "-var-list-children psnp->long_ptr.*psnp->long_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",exp=\"\\*\\*psnp->long_ptr\",numchild=\"1\",type=\"long int \\*\\*\"\}\}" \
+ "get children of psnp->long_ptr.*psnp->long_ptr"
+
+
+# Test: c_variable-5.23
+# Desc: number of children of *(psnp->long_ptr)
+mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->long_ptr.*psnp->long_ptr"
+
+# Test: c_variable-5.24
+# Desc: children of *(*(psnp->long_ptr))
+mi_gdb_test "-var-list-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",exp=\"\\*\\*\\*psnp->long_ptr\",numchild=\"1\",type=\"long int \\*\"\}\}" \
+ "get children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr"
+
+# Test: c_variable-5.25
+# Desc: number of children of *(*(psnp->long_ptr))
+mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr"
+
+# Test: c_variable-5.26
+# Desc: children of *(*(*(psnp->long_ptr)))
+mi_gdb_test "-var-list-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",exp=\"\\*\\*\\*\\*psnp->long_ptr\",numchild=\"0\",type=\"long int\"\}\}" \
+ "get children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr"
+
+# Test: c_variable-5.27
+# Desc: number of children of *(*(*(psnp->long_ptr)))
+mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr"
+
+# Test: c_variable-5.28
+# Desc: children of *(*(*(*(psnp->long_ptr))))
+mi_gdb_test "-var-list-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr"
+
+# Test: c_variable-5.29
+# Desc: number of children of *(*(*(*(psnp->long_ptr))))
+mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr"
+
+# Test: c_variable-5.30
+# Desc: create psnp->ptrs
+mi_gdb_test "-var-create psnp->ptrs * psnp->ptrs" \
+ "\\^done,name=\"psnp->ptrs\",numchild=\"3\",type=\"struct _struct_n_pointer \\*\\\[3\\\]\"" \
+ "create local variable psnp->ptrs"
+
+# Test: c_variable-5.31
+# Desc: children of psnp->ptrs
+mi_gdb_test "-var-list-children psnp->ptrs" \
+ "\\^done,numchild=\"3\",children=\{child=\{name=\"psnp->ptrs.0\",exp=\"0\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\},child=\{name=\"psnp->ptrs.1\",exp=\"1\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\},child=\{name=\"psnp->ptrs.2\",exp=\"2\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+ "get children of psnp->ptrs"
+
+# Test: c_variable-5.32
+# Desc: number of children of psnp->ptrs
+mi_gdb_test "-var-info-num-children psnp->ptrs" \
+ "\\^done,numchild=\"3\"" \
+ "get number of children of psnp->ptrs"
+
+# Test: c_variable-5.33
+# Desc: children of psnp->ptrs[0]
+mi_gdb_test "-var-list-children psnp->ptrs.0" \
+ "\\^done,numchild=\"4\",children=\{child=\{name=\"psnp->ptrs.0.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.long_ptr\",exp=\"long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.ptrs\",exp=\"ptrs\",numchild=\"3\",type=\"struct _struct_n_pointer \\*\\\[3\\\]\"\},child=\{name=\"psnp->ptrs.0.next\",exp=\"next\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+ "get children of psnp->ptrs.0"
+
+# Test: c_variable-5.34
+# Desc: number of children of psnp->ptrs[0]
+mi_gdb_test "-var-info-num-children psnp->ptrs.0" \
+ "\\^done,numchild=\"4\"" \
+ "get number of children of psnp->ptrs.0"
+
+# Test: c_variable-5.35
+# Desc: children of psnp->ptrs[0]->next
+mi_gdb_test "-var-list-children psnp->ptrs.0.next" \
+ "\\^done,numchild=\"4\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.next.long_ptr\",exp=\"long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.next.ptrs\",exp=\"ptrs\",numchild=\"3\",type=\"struct _struct_n_pointer \\*\\\[3\\\]\"\},child=\{name=\"psnp->ptrs.0.next.next\",exp=\"next\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+ "get children of psnp->ptrs.0.next"
+
+#} {char_ptr long_ptr ptrs next}
+
+# Test: c_variable-5.36
+# Desc: number of children of psnp->ptrs[0]->next
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next" \
+ "\\^done,numchild=\"4\"" \
+ "get number of children of psnp->ptrs.0.next"
+
+
+# Test: c_variable-5.37
+# Desc: children of psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",exp=\"\\*char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\"\}\}" \
+ "get children of psnp->ptrs.0.next.char_ptr"
+
+#gdbtk_test c_variable-5.37 {children of psnp->ptrs[0]->next->char_ptr} {
+# get_children psnp->ptrs.0.next.char_ptr
+#} {*char_ptr}
+
+# Test: c_variable-5.38
+# Desc: number of children of psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->ptrs.0.next.char_ptr"
+
+# Test: c_variable-5.39
+# Desc: children of *psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr.*char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",exp=\"\\*\\*char_ptr\",numchild=\"1\",type=\"char \\*\\*\"\}\}" \
+ "get children of psnp->ptrs.0.next.char_ptr.*char_ptr"
+
+# Test: c_variable-5.40
+# Desc: number of children of *psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr.*char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->ptrs.0.next.char_ptr.*char_ptr"
+
+# Test: c_variable-5.41
+# Desc: children of **psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",exp=\"\\*\\*\\*char_ptr\",numchild=\"1\",type=\"char \\*\"\}\}" \
+ "get children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr"
+
+# Test: c_variable-5.41B
+# Desc: children of ***psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",exp=\"\\*\\*\\*\\*char_ptr\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr"
+
+# Test: c_variable-5.42
+# Desc: number of children of **psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr"
+
+# Test: c_variable-5.43
+# Desc: children of ***psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",exp=\"\\*\\*\\*\\*char_ptr\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr"
+
+# Test: c_variable-5.44
+# Desc: number of children of ***psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr"
+
+# Test: c_variable-5.43B
+# Desc: children of ****psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr.****char_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr"
+
+# Test: c_variable-5.44B
+# Desc: number of children of ****psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr.****char_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr"
+
+# Test: c_variable-5.45
+# Desc: children of psnp->ptrs[0]->next->next
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.next" \
+ "\\^done,numchild=\"4\",children=\{child=\{name=\"psnp->ptrs.0.next.next.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.next.next.long_ptr\",exp=\"long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.next.next.ptrs\",exp=\"ptrs\",numchild=\"3\",type=\"struct _struct_n_pointer \\*\\\[3\\\]\"\},child=\{name=\"psnp->ptrs.0.next.next.next\",exp=\"next\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+ "get children of psnp->ptrs.0.next.next"
+
+# Test: c_variable-5.46
+# Desc: children of psnp->ptrs[0]->next->next->ptrs
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.next.ptrs" \
+ "\\^done,numchild=\"3\",children=\{child=\{name=\"psnp->ptrs.0.next.next.ptrs.0\",exp=\"0\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\},child=\{name=\"psnp->ptrs.0.next.next.ptrs.1\",exp=\"1\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\},child=\{name=\"psnp->ptrs.0.next.next.ptrs.2\",exp=\"2\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+ "get children of psnp->ptrs.0.next.next.ptrs"
+
+# Step over "snp0.char_ptr = &b3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"255\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.47
+# Desc: check that psnp->char_ptr (and [0].char_ptr) changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars psnp->char_ptr (and 0.char_ptr) changed"
+
+# Step over "snp1.char_ptr = &c3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"256\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+
+# Test: c_variable-5.48
+# Desc: check that psnp->next->char_ptr (and [1].char_ptr) changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars psnp->next->char_ptr (and 1.char_ptr) changed"
+
+
+# Step over "snp2.char_ptr = &a3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"257\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+
+# Test: c_variable-5.49
+# Desc: check that psnp->next->next->char_ptr (and [2].char_ptr) changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars psnp->next->next->char_ptr (and 2.char_ptr) changed"
+
+
+# Step over "snp0.long_ptr = &y3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"258\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.50
+# Desc: check that psnp->long_ptr (and [0].long_ptr) changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars psnp->long_ptr (and 0.long_ptr) changed"
+
+
+# Step over "snp1.long_ptr = &x3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"259\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+
+# Test: c_variable-5.51
+# Desc: check that psnp->next->long_ptr (and [1].long_ptr) changed
+# Why does this have a FIXME?
+setup_xfail *-*-*
+mi_gdb_test "-var-update *" \
+ "FIXME\\^done,changelist=\{name=\"psnp->ptrs.0.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars psnp->next->long_ptr (and 1.long_ptr) changed"
+clear_xfail *-*-*
+
+# This command produces this error message:
+# &"warning: varobj_list: assertion failed - mycount <> 0\n"
+#
+
+# Step over "snp2.long_ptr = &z3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"260\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+
+# Test: c_variable-5.52
+# Desc: check that psnp->next->next->long_ptr (and [2].long_ptr) changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars psnp->next->next->long_ptr (and 2.long_ptr) changed"
+
+
+
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-var-cmd.exp b/gdb/testsuite/gdb.mi/mi-var-cmd.exp
new file mode 100644
index 00000000000..b157aa3e7a6
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-var-cmd.exp
@@ -0,0 +1,523 @@
+# Copyright (C) 1999, 2000, 2002 Cygnus Solutions
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can create, update, delete variables.
+#
+
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "var-cmd"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+
+##### #####
+# #
+# Variable Creation tests #
+# #
+##### #####
+
+# Test: c_variable-1.1
+# Desc: Create global variable
+
+mi_gdb_test "111-var-create global_simple * global_simple" \
+ "111\\^done,name=\"global_simple\",numchild=\"6\",type=\"simpleton\"" \
+ "create global variable"
+
+# Test: c_variable-1.2
+# Desc: Create non-existent variable
+
+mi_gdb_test "112-var-create bogus_unknown_variable * bogus_unknown_variable" \
+ "&\"mi_cmd_var_create: unable to create variable object\\\\n\".*112\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
+ "create non-existent variable"
+
+# Test: c_variable-1.3
+# Desc: Create out of scope variable
+
+mi_gdb_test "113-var-create argc * argc" \
+ "&\"mi_cmd_var_create: unable to create variable object\\\\n\".*113\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
+ "create out of scope variable"
+
+mi_gdb_test "200-break-insert do_locals_tests" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_locals_tests\",file=\".*var-cmd.c\",line=\"106\",times=\"0\"\}" \
+ "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"106\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to do_locals_tests"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "run to do_locals_tests (2)"}
+ timeout {fail "run to do_locals_tests (timeout 2)"}
+}
+
+# Test: c_variable-1.4
+# Desc: create local variables
+
+mi_gdb_test "-var-create linteger * linteger" \
+ "\\^done,name=\"linteger\",numchild=\"0\",type=\"int\"" \
+ "create local variable linteger"
+
+mi_gdb_test "-var-create lpinteger * lpinteger" \
+ "\\^done,name=\"lpinteger\",numchild=\"1\",type=\"int \\*\"" \
+ "create local variable lpinteger"
+
+mi_gdb_test "-var-create lcharacter * lcharacter" \
+ "\\^done,name=\"lcharacter\",numchild=\"0\",type=\"char\"" \
+ "create local variablelcharacter "
+
+mi_gdb_test "-var-create lpcharacter * lpcharacter" \
+ "\\^done,name=\"lpcharacter\",numchild=\"1\",type=\"char \\*\"" \
+ "create local variable lpcharacter"
+
+mi_gdb_test "-var-create llong * llong" \
+ "\\^done,name=\"llong\",numchild=\"0\",type=\"long int\"" \
+ "create local variable llong"
+
+mi_gdb_test "-var-create lplong * lplong" \
+ "\\^done,name=\"lplong\",numchild=\"1\",type=\"long int \\*\"" \
+ "create local variable lplong"
+
+mi_gdb_test "-var-create lfloat * lfloat" \
+ "\\^done,name=\"lfloat\",numchild=\"0\",type=\"float\"" \
+ "create local variable lfloat"
+
+mi_gdb_test "-var-create lpfloat * lpfloat" \
+ "\\^done,name=\"lpfloat\",numchild=\"1\",type=\"float \\*\"" \
+ "create local variable lpfloat"
+
+mi_gdb_test "-var-create ldouble * ldouble" \
+ "\\^done,name=\"ldouble\",numchild=\"0\",type=\"double\"" \
+ "create local variable ldouble"
+
+mi_gdb_test "-var-create lpdouble * lpdouble" \
+ "\\^done,name=\"lpdouble\",numchild=\"1\",type=\"double \\*\"" \
+ "create local variable lpdouble"
+
+mi_gdb_test "-var-create lsimple * lsimple" \
+ "\\^done,name=\"lsimple\",numchild=\"6\",type=\"struct _simple_struct\"" \
+ "create local variable lsimple"
+
+mi_gdb_test "-var-create lpsimple * lpsimple" \
+ "\\^done,name=\"lpsimple\",numchild=\"6\",type=\"struct _simple_struct \\*\"" \
+ "create local variable lpsimple"
+
+mi_gdb_test "-var-create func * func" \
+ "\\^done,name=\"func\",numchild=\"0\",type=\"void \\(\\*\\)\\((void|)\\)\"" \
+ "create local variable func"
+
+# Test: c_variable-1.5
+# Desc: create lsimple.character
+mi_gdb_test "-var-create lsimple.character * lsimple.character" \
+ "\\^done,name=\"lsimple.character\",numchild=\"0\",type=\"char\"" \
+ "create lsimple.character"
+
+# Test: c_variable-1.6
+# Desc: create lpsimple->integer
+mi_gdb_test "-var-create lsimple->integer * lsimple->integer" \
+ "\\^done,name=\"lsimple->integer\",numchild=\"0\",type=\"int\"" \
+ "create lsimple->integer"
+
+# Test: c_variable-1.7
+# Desc: ceate lsimple.integer
+mi_gdb_test "-var-create lsimple.integer * lsimple.integer" \
+ "\\^done,name=\"lsimple.integer\",numchild=\"0\",type=\"int\"" \
+ "create lsimple->integer"
+
+
+# Test: c_variable-1.9
+# Desc: create type name
+# Type names (like int, long, etc..) are all proper expressions to gdb.
+# make sure variable code does not allow users to create variables, though.
+mi_gdb_test "-var-create int * int" \
+ "&\"Attempt to use a type name as an expression.mi_cmd_var_create: unable to create variable object\\\\n\".*\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
+ "create int"
+
+
+##### #####
+# #
+# Value changed tests #
+# #
+##### #####
+
+# Test: c_variable-2.1
+# Desc: check whether values changed at do_block_tests
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{\}" \
+ "update all vars"
+
+# Step over "linteger = 1234;"
+mi_step_to "do_locals_tests" "" "var-cmd.c" "107" "step at do_locals_test"
+
+# Test: c_variable-2.2
+# Desc: check whether only linteger changed values
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: linteger changed"
+
+# Step over "lpinteger = &linteger;"
+mi_step_to "do_locals_tests" "" "var-cmd.c" 108 "step at do_locals_tests (2)"
+
+# Test: c_variable-2.3
+# Desc: check whether only lpinteger changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: lpinteger changed"
+
+# Step over "lcharacter = 'a';"
+mi_step_to "do_locals_tests" "" "var-cmd.c" "109" "step at do_locals_tests (3)"
+
+# Test: c_variable-2.4
+# Desc: check whether only lcharacter changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: lcharacter changed"
+
+# Step over "lpcharacter = &lcharacter;"
+mi_step_to "do_locals_tests" "" "var-cmd.c" "110" "step at do_locals_tests (4)"
+
+# Test: c_variable-2.5
+# Desc: check whether only lpcharacter changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: lpcharacter changed"
+
+
+# Step over:
+# llong = 2121L;
+# lplong = &llong;
+# lfloat = 2.1;
+# lpfloat = &lfloat;
+# ldouble = 2.718281828459045;
+# lpdouble = &ldouble;
+# lsimple.integer = 1234;
+# lsimple.unsigned_integer = 255;
+# lsimple.character = 'a';
+
+mi_run_to "exec-step 9" "end-stepping-range" "do_locals_tests" "" \
+ "var-cmd.c" "119" "" "step at do_locals_tests (5)"
+
+# Test: c_variable-2.6
+# Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer,
+# lsimple.unsigned_character lsimple.integer lsimple.character changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\",name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\",name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",name=\"lplong\",in_scope=\"true\",type_changed=\"false\",name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: many changed"
+
+# Step over:
+# lsimple.signed_character = 21;
+# lsimple.char_ptr = &lcharacter;
+# lpsimple = &lsimple;
+# func = nothing;
+
+mi_run_to "exec-step 4" "end-stepping-range" "do_locals_tests" "" \
+ "var-cmd.c" "125" "" "step at do_locals_tests (6)"
+
+# Test: c_variable-2.7
+# Desc: check whether (lsimple.signed_character, lsimple.char_ptr) lpsimple, func changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"func\",in_scope=\"true\",type_changed=\"false\",name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: func and lpsimple changed"
+
+# Step over
+# linteger = 4321;
+# lcharacter = 'b';
+# llong = 1212L;
+# lfloat = 1.2;
+# ldouble = 5.498548281828172;
+# lsimple.integer = 255;
+# lsimple.unsigned_integer = 4321;
+# lsimple.character = 'b';
+
+mi_run_to "exec-step 8" "end-stepping-range" "do_locals_tests" "" \
+ "var-cmd.c" "133" "" "step at do_locals_tests (7)"
+
+# Test: c_variable-2.8
+# Desc: check whether linteger, lcharacter, llong, lfoat, ldouble, lsimple.integer,
+# lpsimple.integer lsimple.character changed
+# Note: this test also checks that lpsimple->integer and lsimple.integer have
+# changed (they are the same)
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",name=\"llong\",in_scope=\"true\",type_changed=\"false\",name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: func and lpsimple changed"
+
+
+###
+#
+# Test assignment to variables. More tests on assignment are in other files.
+#
+###
+mi_gdb_test "-var-assign global_simple 0" \
+ "&\"mi_cmd_var_assign: Variable object is not editable\\\\n\".*\\^error,msg=\"mi_cmd_var_assign: Variable object is not editable\"" \
+ "assign to global_simple"
+
+mi_gdb_test "-var-assign linteger 3333" \
+ "\\^done,value=\"3333\"" \
+ "assign to linteger"
+
+mi_gdb_test "-var-evaluate-expression linteger" \
+ "\\^done,value=\"3333\"" \
+ "eval linteger"
+
+mi_gdb_test "-var-assign lpinteger \"&linteger + 3\"" \
+ "\\^done,value=\"$hex\"" \
+ "assign to lpinteger"
+
+mi_gdb_test "-var-evaluate-expression lpinteger" \
+ "\\^done,value=\"$hex\"" \
+ "eval lpinteger"
+
+# reset the values to the original ones so that the rest of the file doesn't suffer.
+
+mi_gdb_test "-var-assign linteger 4321" \
+ "\\^done,value=\"4321\"" \
+ "assign to linteger"
+
+mi_gdb_test "-var-assign lpinteger &linteger" \
+ "\\^done,value=\"$hex\"" \
+ "assign to lpinteger"
+
+mi_gdb_test "-var-assign lcharacter 'z'" \
+ "\\^done,value=\"122 'z'\"" \
+ "assign to lcharacter"
+
+mi_gdb_test "-var-evaluate-expression lcharacter" \
+ "\\^done,value=\"122 'z'\"" \
+ "eval lcharacter"
+
+mi_gdb_test "-var-assign llong 1313L" \
+ "\\^done,value=\"1313\"" \
+ "assign to llong"
+mi_gdb_test "-var-evaluate-expression llong" \
+ "\\^done,value=\"1313\"" \
+ "eval llong"
+mi_gdb_test "-var-assign llong 1212L" \
+ "\\^done,value=\"1212\"" \
+ "assign to llong"
+
+mi_gdb_test "-var-assign lplong &llong+4" \
+ "\\^done,value=\"$hex\"" \
+ "assign to lplong"
+mi_gdb_test "-var-evaluate-expression lplong" \
+ "\\^done,value=\"$hex\"" \
+ "eval lplong"
+mi_gdb_test "-var-assign lplong &llong" \
+ "\\^done,value=\"$hex\"" \
+ "assign to lplong"
+
+mi_gdb_test "-var-assign lfloat 3.4567" \
+ "\\^done,value=\"3.45.*\"" \
+ "assign to lfloat"
+mi_gdb_test "-var-evaluate-expression lfloat" \
+ "\\^done,value=\"3.45.*\"" \
+ "eval lfloat"
+mi_gdb_test "-var-assign lfloat 1.2345" \
+ "\\^done,value=\"1.23.*\"" \
+ "assign to lfloat"
+
+mi_gdb_test "-var-assign lpfloat &lfloat+4" \
+ "\\^done,value=\"$hex\"" \
+ "assign to lpfloat"
+
+mi_gdb_test "-var-assign ldouble 5.333318284590435" \
+ "\\^done,value=\"5.333318284590435\"" \
+ "assign to ldouble"
+
+mi_gdb_test "-var-assign func do_block_tests" \
+ "\\^done,value=\"$hex <do_block_tests>\"" \
+ "assign to func"
+
+mi_gdb_test "-var-assign lsimple.character 'd'" \
+ "\\^done,value=\"100 'd'\"" \
+ "assign to lsimple.character"
+
+mi_gdb_test "-var-assign lsimple->integer 222" \
+ "\\^done,value=\"222\"" \
+ "assign to lsimple->integer"
+
+mi_gdb_test "-var-assign lsimple.integer 333" \
+ "\\^done,value=\"333\"" \
+ "assign to lsimple.integer"
+
+######
+# End of assign tests
+#####
+
+mi_gdb_test "-break-insert subroutine1" \
+ "\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"subroutine1\",file=\".*var-cmd.c\",line=\"146\",times=\"0\"\}" \
+ "break-insert subroutine1"
+mi_continue_to "2" "subroutine1" \
+ "\{name=\"i\",value=\"4321\"\},\{name=\"l\",value=\"$hex\"\}" \
+ "var-cmd.c" "146" "continue to subroutine1"
+
+# Test: c_variable-2.10
+# Desc: create variable for locals i,l in subroutine1
+mi_gdb_test "-var-create i * i" \
+ "\\^done,name=\"i\",numchild=\"0\",type=\"int\"" \
+ "create i"
+
+mi_gdb_test "-var-create l * l" \
+ "\\^done,name=\"l\",numchild=\"1\",type=\"long int \\*\"" \
+ "create l"
+
+# Test: c_variable-2.11
+# Desc: create do_locals_tests local in subroutine1
+mi_gdb_test "-var-create linteger * linteger" \
+ "&\"mi_cmd_var_create: unable to create variable object\\\\n\".*\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
+ "create linteger"
+
+mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \
+ "var-cmd.c" "147" "step at subroutine1"
+
+# Test: c_variable-2.12
+# Desc: change global_simple.integer
+# Note: This also tests whether we are reporting changes in structs properly.
+# gdb normally would say that global_simple has changed, but we
+# special case that, since it is not what a human expects to
+# see.
+
+setup_xfail *-*-*
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{FIXME: WHAT IS CORRECT HERE\}" \
+ "update all vars: changed FIXME"
+clear_xfail *-*-*
+
+mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \
+ "var-cmd.c" "148" "step at subroutine1 (2)"
+
+# Test: c_variable-2.13
+# Desc: change subroutine1 local i
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"i\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: i changed"
+
+mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \
+ "var-cmd.c" "149" "step at subroutine1 (3)"
+
+# Test: c_variable-2.14
+# Desc: change do_locals_tests local llong
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: llong changed"
+
+mi_next_to "do_locals_tests" "" "var-cmd.c" "136" "next out of subroutine1"
+
+# Test: c_variable-2.15
+# Desc: check for out of scope subroutine1 locals
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"l\",in_scope=\"false\",name=\"i\",in_scope=\"false\"\}" \
+ "update all vars: all now out of scope"
+
+# Done with locals/globals tests. Erase all variables
+#delete_all_variables
+mi_gdb_test "-var-delete global_simple" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var"
+
+mi_gdb_test "-var-delete linteger" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var linteger"
+
+mi_gdb_test "-var-delete lpinteger" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lpinteger"
+
+mi_gdb_test "-var-delete lcharacter" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lcharacter"
+
+mi_gdb_test "-var-delete lpcharacter" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lpcharacter"
+
+mi_gdb_test "-var-delete llong" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var llong"
+
+mi_gdb_test "-var-delete lplong" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lplong"
+
+mi_gdb_test "-var-delete lfloat" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lfloat"
+
+mi_gdb_test "-var-delete lpfloat" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lpfloat"
+
+mi_gdb_test "-var-delete ldouble" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var ldouble"
+
+mi_gdb_test "-var-delete lpdouble" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lpdouble"
+
+mi_gdb_test "-var-delete lsimple" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lsimple"
+
+mi_gdb_test "-var-delete lpsimple" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lpsimple"
+
+mi_gdb_test "-var-delete func" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var func"
+
+mi_gdb_test "-var-delete lsimple.character" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lsimple.character"
+
+mi_gdb_test "-var-delete lsimple->integer" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lsimple->integer"
+
+mi_gdb_test "-var-delete lsimple.integer" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lsimple.integer"
+
+mi_gdb_test "-var-delete i" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var i"
+
+mi_gdb_test "-var-delete l" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var l"
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-var-display.exp b/gdb/testsuite/gdb.mi/mi-var-display.exp
new file mode 100644
index 00000000000..9eed4d796d6
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-var-display.exp
@@ -0,0 +1,627 @@
+# Copyright (C) 1999 2000 Cygnus Solutions
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can create, update, delete variables.
+#
+
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "var-cmd"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+mi_gdb_test "200-break-insert 260" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_children_tests\",file=\".*var-cmd.c\",line=\"260\",times=\"0\"\}" \
+ "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"260\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to do_children_tests"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "run to do_children_tests (2)"}
+ timeout {fail "run to do_children_tests (timeout 2)"}
+}
+
+##### #####
+# #
+# Display tests #
+# #
+##### #####
+
+# Test: c_variable-6.1
+# Desc: create variable bar
+mi_gdb_test "-var-create bar * bar" \
+ "\\^done,name=\"bar\",numchild=\"0\",type=\"int\"" \
+ "create local variable bar"
+
+# Test: c_variable-6.2
+# Desc: type of variable bar
+mi_gdb_test "-var-info-type bar" \
+ "\\^done,type=\"int\"" \
+ "info type variable bar"
+
+# Test: c_variable-6.3
+# Desc: format of variable bar
+mi_gdb_test "-var-show-format bar" \
+ "\\^done,format=\"natural\"" \
+ "show format variable bar"
+
+# Test: c_variable-6.4
+# Desc: value of variable bar
+mi_gdb_test "-var-evaluate-expression bar" \
+ "\\^done,value=\"2121\"" \
+ "eval variable bar"
+
+# Test: c_variable-6.5
+# Desc: change format of bar to hex
+mi_gdb_test "-var-set-format bar hexadecimal" \
+ "\\^done,format=\"hexadecimal\"" \
+ "set format variable bar"
+
+# Test: c_variable-6.6
+# Desc: value of bar with new format
+mi_gdb_test "-var-evaluate-expression bar" \
+ "\\^done,value=\"0x849\"" \
+ "eval variable bar with new format"
+
+# Test: c_variable-6.7
+# Desc: change value of bar
+mi_gdb_test "-var-assign bar 3" \
+ "\\^done,value=\"0x3\"" \
+ "assing to variable bar"
+
+mi_gdb_test "-var-set-format bar decimal" \
+ "\\^done,format=\"decimal\"" \
+ "set format variable bar"
+
+mi_gdb_test "-var-evaluate-expression bar" \
+ "\\^done,value=\"3\"" \
+ "eval variable bar with new value"
+
+mi_gdb_test "-var-delete bar" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var bar"
+
+# Test: c_variable-6.11
+# Desc: create variable foo
+mi_gdb_test "-var-create foo * foo" \
+ "\\^done,name=\"foo\",numchild=\"1\",type=\"int \\*\"" \
+ "create local variable foo"
+
+# Test: c_variable-6.12
+# Desc: type of variable foo
+mi_gdb_test "-var-info-type foo" \
+ "\\^done,type=\"int \\*\"" \
+ "info type variable foo"
+
+# Test: c_variable-6.13
+# Desc: format of variable foo
+mi_gdb_test "-var-show-format foo" \
+ "\\^done,format=\"natural\"" \
+ "show format variable foo"
+
+# Test: c_variable-6.14
+# Desc: value of variable foo
+mi_gdb_test "-var-evaluate-expression foo" \
+ "\\^done,value=\"$hex\"" \
+ "eval variable foo"
+
+# Test: c_variable-6.15
+# Desc: change format of var to octal
+mi_gdb_test "-var-set-format foo octal" \
+ "\\^done,format=\"octal\"" \
+ "set format variable foo"
+
+mi_gdb_test "-var-show-format foo" \
+ "\\^done,format=\"octal\"" \
+ "show format variable foo"
+
+# Test: c_variable-6.16
+# Desc: value of foo with new format
+mi_gdb_test "-var-evaluate-expression foo" \
+ "\\^done,value=\"\[0-7\]+\"" \
+ "eval variable foo"
+
+# Test: c_variable-6.17
+# Desc: change value of foo
+mi_gdb_test "-var-assign foo 3" \
+ "\\^done,value=\"03\"" \
+ "assing to variable foo"
+
+mi_gdb_test "-var-set-format foo decimal" \
+ "\\^done,format=\"decimal\"" \
+ "set format variable foo"
+
+# Test: c_variable-6.18
+# Desc: check new value of foo
+mi_gdb_test "-var-evaluate-expression foo" \
+ "\\^done,value=\"3\"" \
+ "eval variable foo"
+
+mi_gdb_test "-var-delete foo" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var foo"
+
+# Test: c_variable-6.21
+# Desc: create variable weird and children
+mi_gdb_test "-var-create weird * weird" \
+ "\\^done,name=\"weird\",numchild=\"11\",type=\"weird_struct \\*\"" \
+ "create local variable weird"
+
+mi_gdb_test "-var-list-children weird" \
+ "\\^done,numchild=\"11\",children=\{child=\{name=\"weird.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"weird.character\",exp=\"character\",numchild=\"0\",type=\"char\"\},child={name=\"weird.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\"\},child=\{name=\"weird.long_int\",exp=\"long_int\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.int_ptr_ptr\",exp=\"int_ptr_ptr\",numchild=\"1\",type=\"int \\*\\*\"\},child=\{name=\"weird.long_array\",exp=\"long_array\",numchild=\"10\",type=\"long int \\\[10\\\]\"\},child=\{name=\"weird.func_ptr\",exp=\"func_ptr\",numchild=\"0\",type=\"void \\(\\*\\)\\(\\)\"\},child=\{name=\"weird.func_ptr_struct\",exp=\"func_ptr_struct\",numchild=\"0\",type=\"struct _struct_decl \\(\\*\\)\\(\\)\"\},child=\{name=\"weird.func_ptr_ptr\",exp=\"func_ptr_ptr\",numchild=\"0\",type=\"struct _struct_decl \\*\\(\\*\\)\\(\\)\"\},child=\{name=\"weird.u1\",exp=\"u1\",numchild=\"4\",type=\"union \{\\.\\.\\.\}\"\},child=\{name=\"weird.s2\",exp=\"s2\",numchild=\"4\",type=\"struct \{\\.\\.\\.\}\"\}\}" \
+ "get children local variable weird"
+
+
+# Test: c_variable-6.23
+# Desc: change format of weird.func_ptr and weird.func_ptr_ptr
+mi_gdb_test "-var-set-format weird.func_ptr hexadecimal" \
+ "\\^done,format=\"hexadecimal\"" \
+ "set format variable weird.func_ptr"
+
+mi_gdb_test "-var-show-format weird.func_ptr" \
+ "\\^done,format=\"hexadecimal\"" \
+ "show format variable weird.func_ptr"
+
+mi_gdb_test "-var-set-format weird.func_ptr_ptr hexadecimal" \
+ "\\^done,format=\"hexadecimal\"" \
+ "set format variable weird.func_ptr_ptr"
+
+mi_gdb_test "-var-show-format weird.func_ptr_ptr" \
+ "\\^done,format=\"hexadecimal\"" \
+ "show format variable weird.func_ptr_ptr"
+
+# Test: c_variable-6.24
+# Desc: format of weird and children
+mi_gdb_test "-var-set-format weird natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird"
+
+mi_gdb_test "-var-set-format weird.integer natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.integer"
+
+mi_gdb_test "-var-set-format weird.character natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.character"
+
+mi_gdb_test "-var-set-format weird.char_ptr natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.char_ptr"
+
+mi_gdb_test "-var-set-format weird.long_int natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.long_int"
+
+mi_gdb_test "-var-set-format weird.int_ptr_ptr natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.int_ptr_ptr"
+
+mi_gdb_test "-var-set-format weird.long_array natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.long_array"
+
+mi_gdb_test "-var-set-format weird.func_ptr hexadecimal" \
+ "\\^done,format=\"hexadecimal\"" \
+ "set format variable weird.func_ptr"
+
+mi_gdb_test "-var-set-format weird.func_ptr_struct hexadecimal" \
+ "\\^done,format=\"hexadecimal\"" \
+ "set format variable weird.func_ptr_struct"
+
+mi_gdb_test "-var-set-format weird.func_ptr_ptr natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.func_ptr_ptr"
+
+mi_gdb_test "-var-set-format weird.u1 natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.u1"
+
+mi_gdb_test "-var-set-format weird.s2 natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.s2"
+
+# Test: c_variable-6.25
+# Desc: value of weird and children
+#gdbtk_test c_variable-6.25 {value of weird and children} {
+# set values {}
+# foreach v [lsort [array names var]] f [list x "" "" x x x x d d d d d] {
+# lappend values [value $v $f]
+# }
+
+# set values
+#} {ok ok ok ok ok ok ok ok weird.long_array ok weird.s2 weird.u1}
+
+# Test: c_variable-6.26
+# Desc: change format of weird and children to octal
+#gdbtk_test c_variable-6.26 {change format of weird and children to octal} {
+# set formats {}
+# foreach v [lsort [array names var]] {
+# $var($v) format octal
+# lappend formats [$var($v) format]
+# }
+
+# set formats
+#} {octal octal octal octal octal octal octal octal octal octal octal octal}
+
+# Test: c_variable-6.27
+# Desc: value of weird and children with new format
+#gdbtk_test c_variable-6.27 {value of foo with new format} {
+# set values {}
+# foreach v [lsort [array names var]] {
+# lappend values [value $v o]
+# }
+
+# set values
+#} {ok ok ok ok ok ok ok ok weird.long_array ok weird.s2 weird.u1}
+
+# Test: c_variable-6.30
+# Desc: create more children of weird
+#gdbtk_test c_variable-6.30 {create more children of weird} {
+# foreach v [array names var] {
+# get_children $v
+# }
+
+# # Do it twice to get more children
+# foreach v [array names var] {
+# get_children $v
+# }
+
+# lsort [array names var]
+#} {weird weird.char_ptr weird.character weird.func_ptr weird.func_ptr_ptr weird.func_ptr_struct weird.int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr weird.integer weird.long_array weird.long_array.0 weird.long_array.1 weird.long_array.2 weird.long_array.3 weird.long_array.4 weird.long_array.5 weird.long_array.6 weird.long_array.7 weird.long_array.8 weird.long_array.9 weird.long_int weird.s2 weird.s2.g weird.s2.h weird.s2.i weird.s2.i.0 weird.s2.i.1 weird.s2.i.2 weird.s2.i.3 weird.s2.i.4 weird.s2.i.5 weird.s2.i.6 weird.s2.i.7 weird.s2.i.8 weird.s2.i.9 weird.s2.u2 weird.s2.u2.f weird.s2.u2.u1s1 weird.s2.u2.u1s2 weird.u1 weird.u1.a weird.u1.b weird.u1.c weird.u1.d}
+
+# Test: c_variable-6.31
+# Desc: check that all children of weird change
+# Ok, obviously things like weird.s2 and weird.u1 will not change!
+#gdbtk_test *c_variable-6.31 {check that all children of weird change (ops, we are now reporting array names as changed in this case - seems harmless though)} {
+# $var(weird) value 0x2121
+# check_update
+#} {{weird.integer weird.character weird.char_ptr weird.long_int weird.int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr weird.long_array.0 weird.long_array.1 weird.long_array.2 weird.long_array.3 weird.long_array.4 weird.long_array.5 weird.long_array.6 weird.long_array.7 weird.long_array.8 weird.long_array.9 weird.func_ptr weird.func_ptr_struct weird.func_ptr_ptr weird.u1.a weird.u1.b weird.u1.c weird.u1.d weird.s2.u2.f weird.s2.g weird.s2.h weird.s2.i.0 weird.s2.i.1 weird.s2.i.2 weird.s2.i.3 weird.s2.i.4 weird.s2.i.5 weird.s2.i.6 weird.s2.i.7 weird.s2.i.8 weird.s2.i.9} {weird.s2.i weird.s2.u2 weird weird.s2.u2.u1s1 weird.s2.u2.u1s2 weird.s2 weird.long_array weird.u1} {}}
+
+mi_gdb_test "-var-delete weird" \
+ "\\^done,ndeleted=\"12\"" \
+ "delete var weird"
+
+
+##### #####
+# #
+# Special Display Tests #
+# #
+##### #####
+
+# Stop in "do_special_tests"
+mi_gdb_test "200-break-insert do_special_tests" \
+ "200\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_special_tests\",file=\".*var-cmd.c\",line=\"282\",times=\"0\"\}" \
+ "break-insert operation"
+
+send_gdb "-exec-continue\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"2\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_special_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"282\"\}\r\n$mi_gdb_prompt$" {
+ pass "continue to do_special_tests"
+ }
+ timeout {
+ fail "continue to do_special_tests (timeout)"
+ }
+}
+
+# Test: c_variable-7.10
+# Desc: create union u
+mi_gdb_test "-var-create u * u" \
+ "\\^done,name=\"u\",numchild=\"2\",type=\"union named_union\"" \
+ "create local variable u"
+
+# Test: c_variable-7.11
+# Desc: value of u
+mi_gdb_test "-var-evaluate-expression u" \
+ "\\^done,value=\"\{\\.\\.\\.\}\"" \
+ "eval variable u"
+
+# Test: c_variable-7.12
+# Desc: type of u
+mi_gdb_test "-var-info-type u" \
+ "\\^done,type=\"union named_union\"" \
+ "info type variable u"
+
+# Test: c_variable-7.13
+# Desc: is u editable
+mi_gdb_test "-var-show-attributes u" \
+ "\\^done,attr=\"noneditable\"" \
+ "is u editable"
+
+# Test: c_variable-7.14
+# Desc: number of children of u
+mi_gdb_test "-var-info-num-children u" \
+ "\\^done,numchild=\"2\"" \
+ "get number of children of u"
+
+# Test: c_variable-7.15
+# Desc: children of u
+mi_gdb_test "-var-list-children u" \
+ "\\^done,numchild=\"2\",children=\{child=\{name=\"u.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"u.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\"\}\}" \
+ "get children of u"
+
+# Test: c_variable-7.20
+# Desc: create anonu
+mi_gdb_test "-var-create anonu * anonu" \
+ "\\^done,name=\"anonu\",numchild=\"3\",type=\"union \{\\.\\.\\.\}\"" \
+ "create local variable anonu"
+
+# Test: c_variable-7.21
+# Desc: value of anonu
+mi_gdb_test "-var-evaluate-expression anonu" \
+ "\\^done,value=\"\{\\.\\.\\.\}\"" \
+ "eval variable anonu"
+
+# Test: c_variable-7.22
+# Desc: type of anonu
+mi_gdb_test "-var-info-type anonu" \
+ "\\^done,type=\"union \{\\.\\.\\.\}\"" \
+ "info type variable anonu"
+
+# Test: c_variable-7.23
+# Desc: is anonu editable
+mi_gdb_test "-var-show-attributes anonu" \
+ "\\^done,attr=\"noneditable\"" \
+ "is anonu editable"
+
+# Test: c_variable-7.24
+# Desc: number of children of anonu
+mi_gdb_test "-var-info-num-children anonu" \
+ "\\^done,numchild=\"3\"" \
+ "get number of children of anonu"
+
+# Test: c_variable-7.25
+# Desc: children of anonu
+mi_gdb_test "-var-list-children anonu" \
+ "\\^done,numchild=\"3\",children=\{child=\{name=\"anonu.a\",exp=\"a\",numchild=\"0\",type=\"int\"\},child=\{name=\"anonu.b\",exp=\"b\",numchild=\"0\",type=\"char\"\},child=\{name=\"anonu.c\",exp=\"c\",numchild=\"0\",type=\"long int\"\}\}" \
+ "get children of anonu"
+
+# Test: c_variable-7.30
+# Desc: create struct s
+mi_gdb_test "-var-create s * s" \
+ "\\^done,name=\"s\",numchild=\"6\",type=\"struct _simple_struct\"" \
+ "create local variable s"
+
+
+# Test: c_variable-7.31
+# Desc: value of s
+mi_gdb_test "-var-evaluate-expression s" \
+ "\\^done,value=\"\{\\.\\.\\.\}\"" \
+ "eval variable s"
+
+# Test: c_variable-7.32
+# Desc: type of s
+mi_gdb_test "-var-info-type s" \
+ "\\^done,type=\"struct _simple_struct\"" \
+ "info type variable s"
+
+# Test: c_variable-7.33
+# Desc: is s editable
+mi_gdb_test "-var-show-attributes s" \
+ "\\^done,attr=\"noneditable\"" \
+ "is s editable"
+
+# Test: c_variable-7.34
+# Desc: number of children of s
+mi_gdb_test "-var-info-num-children s" \
+ "\\^done,numchild=\"6\"" \
+ "get number of children of s"
+
+# Test: c_variable-7.35
+# Desc: children of s
+mi_gdb_test "-var-list-children s" \
+ "\\^done,numchild=\"6\",children=\{child=\{name=\"s.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"s.unsigned_integer\",exp=\"unsigned_integer\",numchild=\"0\",type=\"unsigned int\"\},child=\{name=\"s.character\",exp=\"character\",numchild=\"0\",type=\"char\"\},child=\{name=\"s.signed_character\",exp=\"signed_character\",numchild=\"0\",type=\"signed char\"\},child=\{name=\"s.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\"\},child=\{name=\"s.array_of_10\",exp=\"array_of_10\",numchild=\"10\",type=\"int \\\[10\\\]\"\}\}" \
+ "get children of s"
+#} {integer unsigned_integer character signed_character char_ptr array_of_10}
+
+# Test: c_variable-7.40
+# Desc: create anons
+mi_gdb_test "-var-create anons * anons" \
+ "\\^done,name=\"anons\",numchild=\"3\",type=\"struct \{\\.\\.\\.\}\"" \
+ "create local variable anons"
+
+# Test: c_variable-7.41
+# Desc: value of anons
+mi_gdb_test "-var-evaluate-expression anons" \
+ "\\^done,value=\"\{\\.\\.\\.\}\"" \
+ "eval variable anons"
+
+# Test: c_variable-7.42
+# Desc: type of anons
+mi_gdb_test "-var-info-type anons" \
+ "\\^done,type=\"struct \{\\.\\.\\.\}\"" \
+ "info type variable anons"
+
+# Test: c_variable-7.43
+# Desc: is anons editable
+mi_gdb_test "-var-show-attributes anons" \
+ "\\^done,attr=\"noneditable\"" \
+ "is anons editable"
+
+# Test: c_variable-7.44
+# Desc: number of children of anons
+mi_gdb_test "-var-info-num-children anons" \
+ "\\^done,numchild=\"3\"" \
+ "get number of children of anons"
+
+# Test: c_variable-7.45
+# Desc: children of anons
+mi_gdb_test "-var-list-children anons" \
+ "\\^done,numchild=\"3\",children=\{child=\{name=\"anons.a\",exp=\"a\",numchild=\"0\",type=\"int\"\},child=\{name=\"anons.b\",exp=\"b\",numchild=\"0\",type=\"char\"\},child=\{name=\"anons.c\",exp=\"c\",numchild=\"0\",type=\"long int\"\}\}" \
+ "get children of anons"
+
+
+# Test: c_variable-7.50
+# Desc: create enum e
+mi_gdb_test "-var-create e * e" \
+ "\\^done,name=\"e\",numchild=\"0\",type=\"enum foo\"" \
+ "create local variable e"
+
+setup_xfail "*-*-*"
+# Test: c_variable-7.51
+# Desc: value of e
+mi_gdb_test "-var-evaluate-expression e" \
+ "\\^done,value=\"FIXME\"" \
+ "eval variable e"
+clear_xfail "*-*-*"
+
+# Test: c_variable-7.52
+# Desc: type of e
+mi_gdb_test "-var-info-type e" \
+ "\\^done,type=\"enum foo\"" \
+ "info type variable e"
+
+# Test: c_variable-7.53
+# Desc: is e editable
+mi_gdb_test "-var-show-attributes e" \
+ "\\^done,attr=\"editable\"" \
+ "is e editable"
+
+# Test: c_variable-7.54
+# Desc: number of children of e
+mi_gdb_test "-var-info-num-children e" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of e"
+
+# Test: c_variable-7.55
+# Desc: children of e
+mi_gdb_test "-var-list-children e" \
+ "\\^done,numchild=\"0\"" \
+ "get children of e"
+
+# Test: c_variable-7.60
+# Desc: create anone
+mi_gdb_test "-var-create anone * anone" \
+ "\\^done,name=\"anone\",numchild=\"0\",type=\"enum \{\\.\\.\\.\}\"" \
+ "create local variable anone"
+
+setup_xfail "*-*-*"
+# Test: c_variable-7.61
+# Desc: value of anone
+mi_gdb_test "-var-evaluate-expression anone" \
+ "\\^done,value=\"A\"" \
+ "eval variable anone"
+clear_xfail "*-*-*"
+
+
+# Test: c_variable-7.70
+# Desc: create anone
+mi_gdb_test "-var-create anone * anone" \
+ "&\"Duplicate variable object name\\\\n\".*\\^error,msg=\"Duplicate variable object name\"" \
+ "create duplicate local variable anone"
+
+
+# Test: c_variable-7.72
+# Desc: type of anone
+mi_gdb_test "-var-info-type anone" \
+ "\\^done,type=\"enum \{\\.\\.\\.\}\"" \
+ "info type variable anone"
+
+
+# Test: c_variable-7.73
+# Desc: is anone editable
+mi_gdb_test "-var-show-attributes anone" \
+ "\\^done,attr=\"editable\"" \
+ "is anone editable"
+
+# Test: c_variable-7.74
+# Desc: number of children of anone
+mi_gdb_test "-var-info-num-children anone" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of anone"
+
+# Test: c_variable-7.75
+# Desc: children of anone
+mi_gdb_test "-var-list-children anone" \
+ "\\^done,numchild=\"0\"" \
+ "get children of anone"
+
+
+# Record fp
+
+send_gdb "p/x \$fp\n"
+gdb_expect {
+ -re ".*($hex).*\\^done\r\n$mi_gdb_prompt$" {
+ pass "print FP register"
+ set fp $expect_out(1,string)
+ }
+# -re ".*" { fail "print FP register"}
+ timeout { fail "print FP register (timeout)"}
+}
+
+mi_gdb_test "200-break-insert incr_a" \
+ "200\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"incr_a\",file=\".*var-cmd.c\",line=\"85\",times=\"0\"\}" \
+ "break-insert operation"
+send_gdb "-exec-continue\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"3\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"incr_a\",args=\\\[\{name=\"a\",value=\"2\.*\"\}\\\],file=\".*var-cmd.c\",line=\"85\"\}\r\n$mi_gdb_prompt$" {
+ pass "continue to incr_a"
+ }
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"3\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"incr_a\",args=\\\[\{name=\"a\",value=\"\.*\"\}\\\],file=\".*var-cmd.c\",line=\"8\[345\]\"\}\r\n$mi_gdb_prompt$" {
+ fail "continue to incr_a (compiler debug info incorrect)"
+ }
+ -re "\\^running\r\n${mi_gdb_prompt}.*\r\n$mi_gdb_prompt$" {
+ fail "continue to incr_a (unknown output)"
+ }
+ timeout {
+ fail "continue to incr_a (timeout)"
+ }
+}
+
+# Test: c_variable-7.81
+# Desc: Create variables in different scopes
+mi_gdb_test "-var-create a1 * a" \
+ "\\^done,name=\"a1\",numchild=\"0\",type=\"char\"" \
+ "create local variable a1"
+
+mi_gdb_test "-var-create a2 $fp a" \
+ "\\^done,name=\"a2\",numchild=\"0\",type=\"int\"" \
+ "create variable a2 in different scope"
+
+#gdbtk_test c_variable-7.81 {create variables in different scopes} {
+# set a1 [gdb_variable create -expr a]
+# set a2 [gdb_variable create -expr a -frame $fp]
+
+# set vals {}
+# lappend vals [$a1 value]
+# lappend vals [$a2 value]
+# set vals
+#} {2 1}
+
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi-watch.exp b/gdb/testsuite/gdb.mi/mi-watch.exp
new file mode 100644
index 00000000000..25db59869be
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-watch.exp
@@ -0,0 +1,191 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and perform basic
+# debugging activities like: insert breakpoints, run the program,
+# step, next, continue until it ends and, last but not least, quit.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_watchpoint_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert a watchpoint and list
+ # Tests:
+ # -break-watch C
+ # -break-list
+
+ mi_gdb_test "111-break-watch C" \
+ "111\\^done,wpt=\{number=\"2\",exp=\"C\"\}" \
+ "break-watch operation"
+
+ mi_gdb_test "222-break-list" \
+ "222\\\^done,BreakpointTable=\{nr_rows=\".\",nr_cols=\".\",hdr=\\\[\{width=\".*\",alignment=\".*\",col_name=\"number\",colhdr=\"Num\"\}.*colhdr=\"Type\".*colhdr=\"Disp\".*colhdr=\"Enb\".*colhdr=\"Address\".*colhdr=\"What\".*\\\],body=\\\[bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"1\"\},bkpt=\{number=\"2\",type=\".*watchpoint\",disp=\"keep\",enabled=\"y\",addr=\"\",what=\"C\",times=\"0\"\}\\\]\}" \
+ "list of watchpoints"
+
+}
+
+# UNUSED at the time
+proc test_awatch_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert an access watchpoint and list it
+ # Tests:
+ # -break-watch -a A
+ # -break-list
+
+ mi_gdb_test "333-break-watch -a A" \
+ "333\\^done,bkpt=\{number=\"1\",addr=\"$hex\",file=\".*basics.c\",line=\"32\"\}" \
+ "break-watch -a operation"
+
+ mi_gdb_test "444-break-list" \
+ "444\\^done,BreakpointTable=\{.*,hdr=\\\[.*\\\],body=\\\[bkpt=\{number=\"3\",type=\"watchpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\\\]\}" \
+ "list of watchpoints awatch"
+
+ mi_gdb_test "777-break-delete 3" \
+ "777\\^done" \
+ "delete access watchpoint"
+}
+
+# UNUSED at the time
+proc test_rwatch_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert a read watchpoint and list it.
+ # Tests:
+ # -break-insert -r B
+ # -break-list
+
+ mi_gdb_test "200-break-watch -r C" \
+ "200\\^done,bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+ "break-insert -r operation"
+
+ mi_gdb_test "300-break-list" \
+ "300\\^done,BreakpointTable=\{.*,hdr=\\\[.*\\\],body=\\\[bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\\\}\}" \
+ "list of breakpoints"
+
+ mi_gdb_test "177-break-delete 4" \
+ "177\\^done" \
+ "delete read watchpoint"
+}
+
+proc test_running_the_program {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Run the program without args, then specify srgs and rerun the program
+ # Tests:
+ # -exec-run
+
+ mi_gdb_test "300-break-insert callee4" \
+ "300\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
+ "insert breakpoint at callee4"
+
+ # mi_gdb_test cannot be used for asynchronous commands because there are
+ # two prompts involved and this can lead to a race condition.
+ # The following is equivalent to a send_gdb "000-exec-run\n"
+ mi_run_cmd
+ # The running part has been checked already by mi_run_cmd
+ gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee4\",args=\\\[\\\],file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" \
+ { pass "run to callee4" }
+ -re ".*$mi_gdb_prompt$" {fail "run to callee4 (2)"}
+ timeout {fail "run to callee4 (timeout 2)"}
+ }
+}
+
+proc test_watchpoint_triggering {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Continue execution until the watchpoint is reached, continue again,
+ # to see the watchpoint go out of scope.
+ # Does:
+ # -exec-continue (Here wp triggers)
+ # -exec-continue (Here wp goes out of scope)
+
+ send_gdb "222-exec-continue\n"
+ gdb_expect {
+ -re "222\\^running\r\n$mi_gdb_prompt" {
+ gdb_expect {
+ -re "222\\*stopped,reason=\"watchpoint-trigger\",wpt=\{number=\"2\",exp=\"C\"\},value=\{old=\".*\",new=\"3\"\},thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee4\",args=\\\[\\\],file=\".*basics.c\",line=\"13\"\}\r\n$mi_gdb_prompt$" {
+ pass "watchpoint trigger"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "watchpoint trigger (2)"}
+ timeout {fail "watchpoint trigger (timeout 2)"}
+ }
+ }
+ -re ".*$mi_gdb_prompt$" {fail "watchpoint trigger (1)"}
+ timeout {fail "watchpoint trigger (timeout 1)"}
+ }
+
+ send_gdb "223-exec-continue\n"
+ gdb_expect {
+ -re "223\\^running\r\n$mi_gdb_prompt" {
+ gdb_expect {
+ -re "\[\r\n\]*223\\*stopped,reason=\"watchpoint-scope\",wpnum=\"2\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee3\",args=\\\[.*\\\],file=\".*basics.c\",line=\"18\"\}\r\n$mi_gdb_prompt$" {
+ pass "wp out of scope"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "wp out of scope (2)"}
+ timeout {fail "wp out of scope (timeout 2)"}
+ }
+ }
+ -re ".*$mi_gdb_prompt$" {fail "wp out of scope (1)"}
+ timeout {fail "wp out of scope (timeout 1)"}
+ }
+}
+
+test_running_the_program
+test_watchpoint_creation_and_listing
+#test_rwatch_creation_and_listing
+#test_awatch_creation_and_listing
+test_watchpoint_triggering
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-basics.exp b/gdb/testsuite/gdb.mi/mi0-basics.exp
new file mode 100644
index 00000000000..d463244b816
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-basics.exp
@@ -0,0 +1,174 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# test basic Machine interface (MI) operations
+#
+# Verify that, using the MI, we can load a program and do
+# other basic things that are used by all test files through mi_gdb_exit,
+# mi_gdb_start, mi_delete_breakpoints, mi_gdb_reinitialize_dir and
+# mi_gdb_load, so we can safely use those.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but the command syntax and correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# In this file we want to test if the operations needed by the following
+# procedures work, so it makes no sense using them here.
+
+# mi_delete_breakpoints
+# mi_gdb_reinitialize_dir $srcdir/$subdir
+# mi_gdb_load ${binfile}
+
+# Test if the MI interpreter has been configured
+
+proc test_mi_interpreter_selection {} {
+ global mi_gdb_prompt
+ global gdb_prompt
+
+ # All this test expects is to get the prompt back
+ # with no syntax error message
+ send_gdb "-gdb-version\n"
+ gdb_expect {
+ -re "GNU gdb .*\r\n$mi_gdb_prompt$" \
+ { pass "acceptance of MI operations"
+ return 1}
+ -re ".*\r\n$mi_gdb_prompt$" \
+ { fail "acceptance of MI operations"
+ note "Skipping all other MI tests." }
+ -re "Undefined command.*$gdb_prompt $" \
+ { fail "acceptance of MI operations"
+ note "Skipping all other MI tests." }
+ -re ".*$gdb_prompt $" \
+ { fail "acceptance of MI operations"
+ note "Skipping all other MI tests." }
+ timeout { fail "acceptance of MI operations (timeout)"
+ note "Skipping all other MI tests." }
+ }
+ return 0
+}
+
+proc test_exec_and_symbol_mi_operatons {} {
+ global mi_gdb_prompt
+ global binfile
+
+ # Load symbols and specify executable on a single operation
+ # Tests:
+ # -file-exec-and-symbols
+
+ # Can't use mi_gdb_test as if this doesn't work,
+ # we must give up on the whole test file
+ send_gdb "-file-exec-and-symbols ${binfile}\n"
+ gdb_expect {
+ -re "\[\r\n\]*\\\^done\r\n$mi_gdb_prompt$" \
+ { pass "file-exec-and-symbols operation" }
+ timeout { fail "file-exec-and-symbols operation (timeout)"
+ note "Skipping all other MI tests."
+ return 0}
+ }
+
+ # The following is not used by mi-support.exp, but we test here so
+ # we get done with loading a program basics.
+
+ # Do it again, but now load symbols and specify executable with
+ # two separate operations
+ # Tests:
+ # -file-clear
+ # -file-exec-file
+ # -file-symbol-file
+
+ # FIXME: file-clear is not implemented yet.
+# mi_gdb_test "-file-clear" \
+# "\\\^done" \
+# "file-clear operation"
+
+ mi_gdb_test "-file-exec-file ${binfile}" \
+ "\\\^done" \
+ "file-exec-file operation"
+
+ mi_gdb_test "-file-symbol-file ${binfile}" \
+ "\\\^done" \
+ "file-symbol-file operation"
+
+ # FIXME: if we cannot load we have to skip all other tests.
+}
+
+proc test_breakpoints_deletion {} {
+ global mi_gdb_prompt
+ global srcfile
+
+ # Clear all breakpoints and list to confirm
+ # Tests:
+ # -break-delete (all)
+ # -break-list
+
+ # The all parameter is actually no parameter.
+ mi_gdb_test "200-break-delete" \
+ "\\\^done" \
+ "break-delete (all) operation"
+
+ mi_gdb_test "201-break-list" \
+ ".*\\\^done,BreakpointTable=\\\{\\\}" \
+ "all breakpoints removed"
+}
+
+proc test_dir_specification {} {
+ global mi_gdb_prompt
+ global srcdir
+ global subdir
+
+ # Clear the search directories, then specify one to be searched
+ # Tests:
+ # -environment-directory
+ # -environment-directory arg
+
+#exp_internal 1
+ mi_gdb_test "202-environment-directory" \
+ "\\\^done" \
+ "environment-directory operation"
+
+ mi_gdb_test "203-environment-directory ${srcdir}/${subdir}" \
+ "\\\^done" \
+ "environment-directory arg operation"
+#exp_internal 0
+}
+
+if [test_mi_interpreter_selection] {
+ test_exec_and_symbol_mi_operatons
+ test_breakpoints_deletion
+ test_dir_specification
+}
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-break.exp b/gdb/testsuite/gdb.mi/mi0-break.exp
new file mode 100644
index 00000000000..b763587ae69
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-break.exp
@@ -0,0 +1,138 @@
+# Copyright 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and perform basic
+# debugging activities like: insert breakpoints, run the program,
+# step, next, continue until it ends and, last but not least, quit.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_tbreak_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert some breakpoints and list them
+ # Also, disable some so they do not interfere with other tests
+ # Tests:
+ # -break-insert -t main
+ # -break-insert -t basics.c:callee2
+ # -break-insert -t basics.c:15
+ # -break-insert -t srcfile:6
+ # -break-list
+
+ mi_gdb_test "222-break-insert -t main" \
+ "222\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+ "break-insert -t operation"
+
+ mi_gdb_test "333-break-insert -t basics.c:callee2" \
+ "333\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee2\",file=\".*basics.c\",line=\"22\",times=\"0\"\}" \
+ "insert temp breakpoint at basics.c:callee2"
+
+ mi_gdb_test "444-break-insert -t basics.c:15" \
+ "444\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee3\",file=\".*basics.c\",line=\"15\",times=\"0\"\}" \
+ "insert temp breakpoint at basics.c:15 (callee3)"
+
+ # Getting the quoting right is tricky. That is "\"<file>\":6"
+ mi_gdb_test "555-break-insert -t \"\\\"${srcfile}\\\":6\"" \
+ "555\\^done,bkpt=\{number=\"4\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"6\",times=\"0\"\}" \
+ "insert temp breakpoint at \"<fullfilename>\":6 (callee4)"
+
+ mi_gdb_test "666-break-list" \
+ "666\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
+ "list of breakpoints"
+
+ mi_gdb_test "777-break-delete" \
+ "777\\^done" \
+ "delete temp breakpoints"
+}
+
+proc test_rbreak_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert some breakpoints and list them
+ # Also, disable some so they do not interfere with other tests
+ # Tests:
+ # -break-insert -r main
+ # -break-insert -r callee2
+ # -break-insert -r callee
+ # -break-insert -r .*llee
+ # -break-list
+
+ setup_xfail "*-*-*"
+ mi_gdb_test "122-break-insert -r main" \
+ "122\\^done,bkpt=\{number=\"5\",addr=\"$hex\",file=\".*basics.c\",line=\"32\"\}" \
+ "break-insert -r operation"
+
+ setup_xfail "*-*-*"
+ mi_gdb_test "133-break-insert -r callee2" \
+ "133\\^done,bkpt=\{number=\"6\",addr=\"$hex\",file=\".*basics.c\",line=\"22\"\}" \
+ "insert breakpoint with regexp callee2"
+
+ setup_xfail "*-*-*"
+ mi_gdb_test "144-break-insert -r callee" \
+ "144\\^done,bkpt=\{number=\"7\",addr=\"$hex\",file=\".*basics.c\",line=\"27\"\},bkpt=\{number=\"8\",addr=\"$hex\",file=\".*basics.c\",line=\"22\"\},bkpt=\{number=\"9\",addr=\"$hex\",file=\".*basics.c\",line=\"17\"\},bkpt=\{number=\"10\",addr=\"$hex\",file=\".*basics.c\",line=\"8\"\}" \
+ "insert breakpoint with regexp callee"
+
+ setup_xfail "*-*-*"
+ mi_gdb_test "155-break-insert -r \.\*llee" \
+ "155\\^done,bkpt=\{number=\"11\",addr=\"$hex\",file=\".*basics.c\",line=\"27\"\},bkpt=\{number=\"12\",addr=\"$hex\",file=\".*basics.c\",line=\"22\"\},bkpt=\{number=\"13\",addr=\"$hex\",file=\".*basics.c\",line=\"17\"\},bkpt=\{number=\"14\",addr=\"$hex\",file=\".*basics.c\",line=\"8\"\}" \
+ "insert breakpoint with regexp .*llee"
+
+ setup_xfail "*-*-*"
+ mi_gdb_test "166-break-list" \
+ "166\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
+ "list of breakpoints"
+
+ mi_gdb_test "177-break-delete" \
+ "177\\^done" \
+ "delete temp breakpoints"
+}
+
+test_tbreak_creation_and_listing
+test_rbreak_creation_and_listing
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-console.exp b/gdb/testsuite/gdb.mi/mi0-console.exp
new file mode 100644
index 00000000000..a2343db9c59
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-console.exp
@@ -0,0 +1,112 @@
+# Copyright 1999, 2000, 2001 Cygnus Solutions.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and perform basic
+# debugging activities like: insert breakpoints, run the program,
+# step, next, continue until it ends and, last but not least, quit.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+# This test only works when talking to a target that routes its output
+# through GDB. Check that we're either talking to a simulator or a
+# remote target.
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "mi-console"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+# Halt in main
+mi_gdb_test "200-break-insert main" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*mi-console.c\",line=\"13\",times=\"0\"\}" \
+ "break-insert operation"
+mi_run_cmd
+gdb_expect {
+ -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*mi-console.c\",line=\"13\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to main"
+ }
+ -re ".*$mi_gdb_prompt$" {
+ fail "run to main (2)"
+ }
+ timeout {
+ fail "run to main (timeout)"
+ }
+}
+
+# Next over the hello() call which will produce lots of output
+send_gdb "47-exec-next\n"
+gdb_expect {
+ -re "47\\^running\r\n$mi_gdb_prompt" {
+ pass "Started step over hello"
+ }
+ timeout {
+ fail "Started step over hello (timeout)"
+ }
+}
+
+gdb_expect {
+ -re "@\"H\"\r\n.*@\"e\"\r\n.*@\"l\"\r\n.*@\"l\"\r\n.*@\"o\"\r\n.*@\" \"\r\n.*@\"\\\\\\\\\"\r\n.*@\"\\\\\"\"\r\n.*@\"!\"\r\n.*@\"\\\\r\"\r\n.*@\"\\\\n\"\r\n" {
+ pass "Hello message"
+ }
+ -re "Hello" {
+
+ # Probably a native system where GDB doesn't have direct
+ # control over the inferior console.
+ # For this to work, GDB would need to run the inferior process
+ # under a PTY and then use the even-loops ability to wait on
+ # multiple event sources to channel the output back through the
+ # MI.
+
+ fail "Hello message (known bug)"
+ }
+ timeout {
+ fail "Hello message (timeout)"
+ }
+}
+
+gdb_expect {
+ -re "47\\*stopped.*$mi_gdb_prompt$" {
+ pass "Finished step over hello"
+ }
+ timeout {
+ fail "Finished step over hello (timeout)"
+ }
+}
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-disassemble.exp b/gdb/testsuite/gdb.mi/mi0-disassemble.exp
new file mode 100644
index 00000000000..ca0b3a61a3b
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-disassemble.exp
@@ -0,0 +1,224 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test Machine interface (MI) operations for disassembly.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_breakpoints_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert some breakpoints and list them
+ # Also, disable some so they do not interfere with other tests
+ # Tests:
+ # -break-insert
+ # -break-list
+ # -break-disable
+ # -break-info
+
+ mi_gdb_test "200-break-insert main" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+ "break-insert operation"
+
+ mi_gdb_test "204-break-list" \
+ "204\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}\}" \
+ "list of breakpoints"
+}
+
+proc test_running_the_program {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Run the program without args
+ # Tests:
+ # -exec-run
+
+ # mi_gdb_test cannot be used for asynchronous commands because there are
+ # two prompts involved and this can lead to a race condition.
+ # FIXME: We are accepting a duplicate file and line info temporarely.
+ # The following is equivalent to a send_gdb "000-exec-run\n"
+ mi_run_cmd
+ # The running part has been checked already by mi_run_cmd
+ gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to main"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "run to main (2)"}
+ timeout {fail "run to main (timeout 2)"}
+ }
+}
+
+proc test_disassembly_only {} {
+ global mi_gdb_prompt
+ global hex
+ global decimal
+
+ # Test disassembly more only for the current function.
+ # Tests:
+ # -data-disassemble -s $pc -e "$pc+8" -- 0
+ # -data-disassembly -f basics.c -l 32 -- 0
+
+ mi_gdb_test "print/x \$pc" "" ""
+ mi_gdb_test "111-data-disassemble -s \$pc -e \"\$pc + 12\" -- 0" \
+ "111\\^done,asm_insns=\{\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\},\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}.*\}" \
+ "data-disassemble from pc to pc+12 assembly only"
+
+ mi_gdb_test "222-data-disassemble -f basics.c -l 32 -- 0" \
+ "222\\^done,asm_insns=\{\{address=\"$hex\",func-name=\"main\",offset=\"0\",inst=\".*\"\},.*,\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}\}" \
+ "data-disassemble file & line, assembly only"
+}
+
+proc test_disassembly_lines_limit {} {
+ global mi_gdb_prompt
+ global hex
+ global decimal
+
+ # Test disassembly more only for the current function.
+ # Tests:
+ # -data-disassembly -f basics.c -l 32 -n 20 -- 0
+ # -data-disassembly -f basics.c -l 32 -n 0 -- 0
+ # -data-disassembly -f basics.c -l 32 -n 50 -- 0
+
+ mi_gdb_test "print/x \$pc" "" ""
+ mi_gdb_test "222-data-disassemble -f basics.c -l 32 -n 20 -- 0" \
+ "222\\^done,asm_insns=\{\{address=\"$hex\",func-name=\"main\",offset=\"0\",inst=\".*\"\},.*,\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}\}" \
+ "data-disassemble file, line, number assembly only"
+
+ mi_gdb_test "222-data-disassemble -f basics.c -l 32 -n 0 -- 0" \
+ "222\\^done,asm_insns=\{\}" \
+ "data-disassemble file, line, number (zero lines) assembly only"
+
+ mi_gdb_test "222-data-disassemble -f basics.c -l 32 -n 50 -- 0" \
+ "222\\^done,asm_insns=\{\{address=\"$hex\",func-name=\"main\",offset=\"0\",inst=\".*\"\},.*,\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}\}" \
+ "data-disassemble file, line, number (more than main lines) assembly only"
+}
+
+
+proc test_disassembly_mixed {} {
+ global mi_gdb_prompt
+ global hex
+ global decimal
+
+ # Test disassembly more only for the current function.
+ # Tests:
+ # -data-disassembly -f basics.c -l 21 -- 1
+ # -data-disassembly -s $pc -e "$pc+8" -- 1
+
+ mi_gdb_test "002-data-disassemble -f basics.c -l 21 -- 1" \
+ "002\\^done,asm_insns=\{src_and_asm_line=\{line=\"21\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex\",func-name=\"callee2\",offset=\"0\",inst=\".*\"\}.*\}\},.*,src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{.*\{address=\"$hex\",func-name=\"callee2\",offset=\"$decimal\",inst=\".*\"\}\}\}\}" \
+ "data-disassemble file, line assembly mixed"
+
+ #
+ # In mixed mode, the lowest level of granularity is the source line.
+ # So we are going to get the disassembly for the source line at
+ # which we are now, even if we have specified that the range is only 2 insns.
+ #
+ mi_gdb_test "003-data-disassemble -s \$pc -e \"\$pc+4\" -- 1" \
+ "003\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}.*\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}\}\}\}" \
+ "data-disassemble range assembly mixed"
+}
+
+proc test_disassembly_mixed_lines_limit {} {
+ global mi_gdb_prompt
+ global hex
+ global decimal
+
+ # Test disassembly more only for the current function.
+ # Tests:
+ # -data-disassembly -f basics.c -l 32 -n 20 -- 1
+ # -data-disassembly -f basics.c -l 32 -n 0 -- 1
+ # -data-disassembly -f basics.c -l 32 -n 50 -- 1
+
+ mi_gdb_test "print/x \$pc" "" ""
+ mi_gdb_test "222-data-disassemble -f basics.c -l 32 -n 20 -- 1" \
+ "222\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex\",func-name=\"main\",offset=\"0\",inst=\".*\"\},.*,\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}.*\}" \
+ "data-disassemble file, line, number assembly mixed"
+
+ mi_gdb_test "222-data-disassemble -f basics.c -l 32 -n 0 -- 1" \
+ "222\\^done,asm_insns=\{src_and_asm_line=\{line=\"31\",file=\".*basics.c\",line_asm_insn=\{\}\}\}" \
+ "data-disassemble file, line, number (zero lines) assembly mixed"
+
+ mi_gdb_test "222-data-disassemble -f basics.c -l 32 -n 50 -- 1" \
+ "222\\^done,asm_insns=\{src_and_asm_line=\{line=\"$decimal\",file=\".*basics.c\",line_asm_insn=\{\{address=\"$hex\",func-name=\"main\",offset=\"0\",inst=\".*\"\},.*,\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}.*\}" \
+ "data-disassemble file, line, number (more than main lines) assembly mixed"
+}
+
+proc test_disassembly_bogus_args {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Test that bogus input to disassembly command is rejected.
+ # Tests:
+ # -data-disassembly -f foo -l abc -n 0 -- 0
+ # -data-disassembly -s foo -e bar -- 0
+ # -data-disassembly -s $pc -f basics.c -- 0
+ # -data-disassembly -f basics.c -l 32 -- 9
+
+ mi_gdb_test "123-data-disassemble -f foo -l abc -n 0 -- 0" \
+ ".*123\\^error,msg=\"mi_cmd_disassemble: Invalid filename.\"" \
+ "data-disassemble bogus filename"
+
+ mi_gdb_test "321-data-disassemble -s foo -e bar -- 0" \
+ "321\\^error,msg=\"No symbol \\\\\"foo\\\\\" in current context.\"" \
+ "data-disassemble bogus address"
+
+ mi_gdb_test "456-data-disassemble -s \$pc -f basics.c -- 0" \
+ "456\\^error,msg=\"mi_cmd_disassemble: Usage: \\( .-f filename -l linenum .-n howmany.. | .-s startaddr -e endaddr.\\) .--. mixed_mode.\"" \
+ "data-disassemble mix different args"
+
+ mi_gdb_test "789-data-disassemble -f basics.c -l 32 -- 9" \
+ "789\\^error,msg=\"mi_cmd_disassemble: Mixed_mode argument must be 0 or 1.\"" \
+ "data-disassemble wrong mode arg"
+
+}
+
+test_breakpoints_creation_and_listing
+test_running_the_program
+test_disassembly_only
+test_disassembly_mixed
+test_disassembly_bogus_args
+test_disassembly_lines_limit
+test_disassembly_mixed_lines_limit
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-eval.exp b/gdb/testsuite/gdb.mi/mi0-eval.exp
new file mode 100644
index 00000000000..0b0ea083488
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-eval.exp
@@ -0,0 +1,101 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify -data-evaluate-expression. There are really minimal tests.
+
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_running_the_program {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Run the program without args, then specify srgs and rerun the program
+ # Tests:
+ # -exec-run
+
+ mi_gdb_test "300-break-insert callee4" \
+ "300\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
+ "insert breakpoint at callee4"
+
+ # mi_gdb_test cannot be used for asynchronous commands because there are
+ # two prompts involved and this can lead to a race condition.
+ # The following is equivalent to a send_gdb "000-exec-run\n"
+ mi_run_cmd
+ # The running part has been checked already by mi_run_cmd
+ gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" \
+ { pass "run to callee4" }
+ -re ".*$mi_gdb_prompt$" {fail "run to callee4 (2)"}
+ timeout {fail "run to callee4 (timeout 2)"}
+ }
+
+ send_gdb "101-exec-next\n"
+ gdb_expect {
+ -re "101\\^running\r\n$mi_gdb_prompt" {
+ gdb_expect {
+ -re "\[\r\n\]*101\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"9\"\}\r\n$mi_gdb_prompt$" \
+ { pass "next in callee4" }
+ -re ".*$mi_gdb_prompt$" {fail "next in callee4 (2)"}
+ timeout {fail "next in callee4 (timeout 2)"}
+ }
+ }
+ -re ".*$mi_gdb_prompt$" {fail "next in callee4 (1)"}
+ timeout {fail "next in callee4 (timeout 1)"}
+ }
+
+}
+
+test_running_the_program
+
+mi_gdb_test "211-data-evaluate-expression A" "211\\^done,value=\"1\"" "eval A"
+
+mi_gdb_test "311-data-evaluate-expression &A" "311\\^done,value=\"$hex\"" "eval &A"
+
+mi_gdb_test "411-data-evaluate-expression A+3" "411\\^done,value=\"4\"" "eval A+3"
+
+mi_gdb_test "511-data-evaluate-expression \"A + 3\"" "511\\^done,value=\"4\"" "eval A + 3"
+
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-hack-cli.exp b/gdb/testsuite/gdb.mi/mi0-hack-cli.exp
new file mode 100644
index 00000000000..3fc6c26c290
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-hack-cli.exp
@@ -0,0 +1,40 @@
+# Copyright 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+
+# Some basic checks for the CLI.
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+mi_gdb_test "show architecture" \
+ "&\"show architecture\\\\n\"\r\n~\"The target architecture.*\"\r\n\\^done" \
+ "show architecture"
+
+mi_gdb_test "47show architecture" \
+ "&\"show architecture\\\\n\"\r\n~\"The target architecture.*\"\r\n47\\^done" \
+ "47show architecture"
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-read-memory.exp b/gdb/testsuite/gdb.mi/mi0-read-memory.exp
new file mode 100644
index 00000000000..0bc294970b6
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-read-memory.exp
@@ -0,0 +1,100 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# test basic Machine interface (MI) operations
+#
+# Verify that, using the MI, we can load a program and do
+# other basic things that are used by all test files through mi_gdb_exit,
+# mi_gdb_start, mi_delete_breakpoints, mi_gdb_reinitialize_dir and
+# mi_gdb_load, so we can safely use those.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but the command syntax and correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "mi-read-memory"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+mi_run_to_main
+
+#mi_next "do initialization"
+send_gdb "101-exec-next\n"
+gdb_expect {
+ -re "101\\^running\r\n$mi_gdb_prompt" {
+ gdb_expect {
+ -re "\[\r\n\]*101\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*mi-read-memory.c\",line=\"20\"\}.*$mi_gdb_prompt$" \
+ { pass "do initialization" }
+ -re ".*$mi_gdb_prompt$" {fail "do initialization (2)"}
+ timeout {fail "do initialization (timeout 2)"}
+ }
+ }
+ -re ".*$mi_gdb_prompt$" {fail "do initialization (1)"}
+ timeout {fail "do initialization (timeout 1)"}
+}
+
+mi_gdb_test "1-data-read-memory" \
+ "1\\^error,msg=\".*\"" \
+ "no arguments"
+
+
+mi_gdb_test "2-data-read-memory bytes x 1 3 2" \
+ "2\\^done,addr=\"$hex\",nr-bytes=\"6\",total-bytes=\"6\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0x00\",\"0x01\"}},{addr=\"$hex\",data={\"0x02\",\"0x03\"}},{addr=\"$hex\",data={\"0x04\",\"0x05\"}}}" \
+ "3x2, one byte"
+
+
+mi_gdb_test "9-data-read-memory -o -6 -- -0+bytes+6 x 1 3 2" \
+ "9\\^done,addr=\"$hex\",nr-bytes=\"6\",total-bytes=\"6\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0x00\",\"0x01\"}},{addr=\"$hex\",data={\"0x02\",\"0x03\"}},{addr=\"$hex\",data={\"0x04\",\"0x05\"}}}" \
+ "3x2, one byte offset by -6"
+
+
+mi_gdb_test "3-data-read-memory \"(shorts + 128)\" x 2 1 2" \
+ "3\\^done,addr=\"$hex\",nr-bytes=\"4\",total-bytes=\"4\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0x0100\",\"0x0102\"}}}" \
+ "expression in quotes"
+
+
+mi_gdb_test "4-data-read-memory bytes+16 x 1 8 4 x" \
+ "4\\^done,addr=\"$hex\",nr-bytes=\"32\",total-bytes=\"32\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0x10\",\"0x11\",\"0x12\",\"0x13\"},ascii=\"xxxx\"},{addr=\"$hex\",data={\"0x14\",\"0x15\",\"0x16\",\"0x17\"},ascii=\"xxxx\"},{addr=\"$hex\",data={\"0x18\",\"0x19\",\"0x1a\",\"0x1b\"},ascii=\"xxxx\"},{addr=\"$hex\",data={\"0x1c\",\"0x1d\",\"0x1e\",\"0x1f\"},ascii=\"xxxx\"},{addr=\"$hex\",data={\"0x20\",\"0x21\",\"0x22\",\"0x23\"},ascii=\" !\\\\\"#\"},{addr=\"$hex\",data={\"0x24\",\"0x25\",\"0x26\",\"0x27\"},ascii=\"\\$%&'\"},{addr=\"$hex\",data={\"0x28\",\"0x29\",\"0x2a\",\"0x2b\"},ascii=\"().+\"},{addr=\"$hex\",data={\"0x2c\",\"0x2d\",\"0x2e\",\"0x2f\"},ascii=\",-\./\"}}" \
+ "ascii and data"
+
+
+mi_gdb_test "5-data-read-memory shorts+64 d 2 1 1" \
+ "5\\^done,addr=\"$hex\",nr-bytes=\"2\",total-bytes=\"2\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"128\"}}}" \
+ "decimal"
+
+mi_gdb_test "6-data-read-memory shorts+64 o 2 1 1" \
+ "6\\^done,addr=\"$hex\",nr-bytes=\"2\",total-bytes=\"2\",next-row=\"$hex\",prev-row=\"$hex\",next-page=\"$hex\",prev-page=\"$hex\",memory={{addr=\"$hex\",data={\"0200\"}}}" \
+ "octal"
+
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-regs.exp b/gdb/testsuite/gdb.mi/mi0-regs.exp
new file mode 100644
index 00000000000..b6db903593d
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-regs.exp
@@ -0,0 +1,177 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and look at registers.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_breakpoints_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert some breakpoints and list them
+ # Also, disable some so they do not interfere with other tests
+ # Tests:
+ # -break-insert
+ # -break-list
+ # -break-disable
+ # -break-info
+
+ mi_gdb_test "200-break-insert main" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+ "break-insert operation"
+
+ mi_gdb_test "204-break-list" \
+ "204\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}\}" \
+ "list of breakpoints"
+}
+
+proc test_running_the_program {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Run the program without args
+ # Tests:
+ # -exec-run
+
+ # mi_gdb_test cannot be used for asynchronous commands because there are
+ # two prompts involved and this can lead to a race condition.
+ # FIXME: We are accepting a duplicate file and line info temporarely.
+ # The following is equivalent to a send_gdb "000-exec-run\n"
+ mi_run_cmd
+ # The running part has been checked already by mi_run_cmd
+ gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to main"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "run to main (2)"}
+ timeout {fail "run to main (timeout 2)"}
+ }
+}
+
+proc sparc_register_tests_no_exec { } {
+ # Test the generic IDT chip.
+ mi_gdb_test "111-data-list-register-values" \
+ ".*111\\^error,msg=\"mi_cmd_data_list_register_values: Usage: -data-list-register-values <format> \\\[<regnum1>...<regnumN>\\\]\"" \
+ "wrong arguments"
+
+ mi_gdb_test "111-data-list-register-values x" \
+ ".*111\\^error,msg=\"mi_cmd_data_list_register_values: No registers\.\"" \
+ "no executable"
+}
+
+# These tests exercise IDT-specific MIPS registers for several
+# different processor models.
+
+# This should detect the actual processor in use and change
+# the expected results appropriately. FIXME
+
+proc sparc_register_tests { } {
+ global hex
+ global decimal
+ set octal "\[0-7\]+"
+ set binary "\[0-1\]+"
+ set float "\\-?((\[0-9\]+(\\.\[0-9\]+)?(e\[-+\]\[0-9\]+)?)|(nan\\($hex\\)))"
+ set float2 "\\-?\[0-9\]+"
+
+ mi_gdb_test "111-data-list-register-names" \
+ "111\\^done,register-names=\{\"g0\",\"g1\",\"g2\",\"g3\",\"g4\",\"g5\",\"g6\",\"g7\",\"o0\",\"o1\",\"o2\",\"o3\",\"o4\",\"o5\",\"sp\",\"o7\",\"l0\",\"l1\",\"l2\",\"l3\",\"l4\",\"l5\",\"l6\",\"l7\",\"i0\",\"i1\",\"i2\",\"i3\",\"i4\",\"i5\",\"fp\",\"i7\",\"f0\",\"f1\",\"f2\",\"f3\",\"f4\",\"f5\",\"f6\",\"f7\",\"f8\",\"f9\",\"f10\",\"f11\",\"f12\",\"f13\",\"f14\",\"f15\",\"f16\",\"f17\",\"f18\",\"f19\",\"f20\",\"f21\",\"f22\",\"f23\",\"f24\",\"f25\",\"f26\",\"f27\",\"f28\",\"f29\",\"f30\",\"f31\",\"y\",\"psr\",\"wim\",\"tbr\",\"pc\",\"npc\",\"fpsr\",\"cpsr\"\}" \
+ "list register names"
+
+ mi_gdb_test "222-data-list-register-values x" \
+ "222\\^done,register-values=\{\{number=\"0\",value=\"$hex\"\}.*\{number=\"71\",value=\"$hex\"\}\}" \
+ "register values x"
+
+ mi_gdb_test "333-data-list-register-values f" \
+ "333\\^done,register-values=\{\{number=\"0\",value=\"$float\"\},\{number=\"1\",value=\"$float\"\},.*\{number=\"71\",value=\"$float\"\}\}" \
+ "register values f"
+
+ mi_gdb_test "444-data-list-register-values d" \
+ "444\\^done,register-values=\{\{number=\"0\",value=\"$decimal\"\}.*\{number=\"71\",value=\"$decimal\"\}\}" \
+ "register values d"
+
+ mi_gdb_test "555-data-list-register-values o" \
+ "555\\^done,register-values=\{\{number=\"0\",value=\"$octal\"\}.*\{number=\"71\",value=\"$octal\"\}\}" \
+ "register values o"
+
+ mi_gdb_test "666-data-list-register-values t" \
+ "666\\^done,register-values=\{\{number=\"0\",value=\"$binary\"\}.*\{number=\"71\",value=\"$binary\"\}\}" \
+ "register values t"
+
+ # On the sparc, registers 0-31 are int, 32-63 float, 64-71 int
+
+ mi_gdb_test "777-data-list-register-values N" \
+ "777\\^done,register-values=\{\{number=\"0\",value=\"$decimal\"\}.*\{number=\"31\",value=\"$decimal\"\},\{number=\"32\",value=\"$float\"\}.*\{number=\"63\",value=\"$float\"\},\{number=\"64\",value=\"$decimal\"\}.*\{number=\"71\",value=\"$decimal\"\}\}" \
+ "register values N"
+
+ mi_gdb_test "888-data-list-register-values r" \
+ "888\\^done,register-values=\{\{number=\"0\",value=\"$hex\"\}.*\{number=\"71\",value=\"$hex\"\}\}" \
+ "register values r"
+
+ mi_gdb_test "999-data-list-register-names 68 69 70 71" \
+ "999\\^done,register-names=\{\"pc\",\"npc\",\"fpsr\",\"cpsr\"\}" \
+ "list names of some regs"
+
+ mi_gdb_test "001-data-list-register-values x 68 69 70 71" \
+ "001\\^done,register-values=\{\{number=\"68\",value=\"$hex\"\},\{number=\"69\",value=\"$hex\"\},\{number=\"70\",value=\"$hex\"\},\{number=\"71\",value=\"$hex\"\}\}" \
+ "list values of some regs"
+
+ # Don't know how useful this test is
+
+ mi_gdb_test "002-data-list-changed-registers" \
+ "002\\^done,changed-registers=\{(\"${decimal}\"(,\"${decimal}\")*)?\}" \
+ "list changed registers"
+}
+
+if [istarget "sparc-*-*"] then {
+ sparc_register_tests_no_exec
+ test_breakpoints_creation_and_listing
+ test_running_the_program
+ sparc_register_tests
+} else {
+ verbose "mi-regs.exp tests ignored for this target"
+}
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-return.exp b/gdb/testsuite/gdb.mi/mi0-return.exp
new file mode 100644
index 00000000000..b396fe8d163
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-return.exp
@@ -0,0 +1,94 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test Machine interface (MI) operations
+# Verify that, using the MI, we can run a simple program and perform
+# exec-return.
+
+# The goal is not to
+# test gdb functionality, which is done by other tests, but to verify
+# the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_running_to_callee4 {} {
+ global mi_gdb_prompt
+ global hex
+
+ mi_gdb_test "200-break-insert callee4" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
+ "break-insert operation"
+
+ mi_run_cmd
+
+ gdb_expect {
+ -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to callee4"
+ }
+ -re ".*$mi_gdb_prompt$" {
+ fail "run to callee4 (2)"
+ }
+ timeout {
+ fail "run to callee4 (timeout)"
+ }
+ }
+
+ mi_gdb_test "205-break-delete" \
+ "205\\^done.*" \
+ "delete all breakpoints"
+
+}
+
+proc test_return_simple {} {
+ global mi_gdb_prompt
+ global hex
+
+ send_gdb "111-exec-return\n"
+ gdb_expect {
+ -re "111\\^done,frame=\{level=\"0 \",addr=\"$hex\",func=\"callee3\",args=\{.*\},file=\".*basics.c\",line=\"18\"\}\r\n$mi_gdb_prompt$" {pass "return from callee4 now"}
+ -re ".*\r\n$mi_gdb_prompt$" { fail "return from callee4 now" }
+ timeout { fail "return from callee4 now (timeout)"
+ }
+ }
+}
+
+test_running_to_callee4
+test_return_simple
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-simplerun.exp b/gdb/testsuite/gdb.mi/mi0-simplerun.exp
new file mode 100644
index 00000000000..9113e1fa30b
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-simplerun.exp
@@ -0,0 +1,201 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and perform basic
+# debugging activities like: insert breakpoints, run the program,
+# step, next, continue until it ends and, last but not least, quit.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_breakpoints_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert some breakpoints and list them
+ # Also, disable some so they do not interfere with other tests
+ # Tests:
+ # -break-insert
+ # -break-list
+ # -break-disable
+ # -break-info
+
+ mi_gdb_test "200-break-insert main" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+ "break-insert operation"
+
+ mi_gdb_test "201-break-insert basics.c:callee2" \
+ "201\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee2\",file=\".*basics.c\",line=\"22\",times=\"0\"\}" \
+ "insert breakpoint at basics.c:callee2"
+
+ mi_gdb_test "202-break-insert basics.c:15" \
+ "202\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee3\",file=\".*basics.c\",line=\"15\",times=\"0\"\}" \
+ "insert breakpoint at basics.c:15 (callee3)"
+
+ mi_gdb_test "203-break-insert \"\\\"${srcfile}\\\":6\"" \
+ "203\\^done,bkpt=\{number=\"4\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"6\",times=\"0\"\}" \
+ "insert breakpoint at \"<fullfilename>\":6 (callee4)"
+
+ mi_gdb_test "204-break-list" \
+ "204\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
+ "list of breakpoints"
+
+ mi_gdb_test "205-break-disable 2 3 4" \
+ "205\\^done.*" \
+ "disabling of breakpoints"
+
+ mi_gdb_test "206-break-info 2" \
+ "206\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"2\",.*,enabled=\"n\",.*\}\}" \
+ "list of breakpoints, 16 disabled"
+}
+
+proc test_running_the_program {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Run the program without args, then specify srgs and rerun the program
+ # Tests:
+ # -exec-run
+ # -gdb-set
+
+ # mi_gdb_test cannot be used for asynchronous commands because there are
+ # two prompts involved and this can lead to a race condition.
+ # The following is equivalent to a send_gdb "000-exec-run\n"
+ mi_run_cmd
+ gdb_expect {
+ -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to main"
+ }
+ -re ".*$mi_gdb_prompt$" {
+ fail "run to main (2)"
+ }
+ timeout {
+ fail "run to main (timeout)"
+ }
+ }
+}
+
+proc test_controlled_execution {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Continue execution until a breakpoint is reached, step into calls, verifying
+ # if the arguments are correctly shown, continue to the end of a called
+ # function, step over a call (next).
+ # Tests:
+ # -exec-continue
+ # -exec-next
+ # -exec-step
+ # -exec-finish
+
+ # mi_gdb_test cannot be used for asynchronous commands because there are
+ # two prompts involved and this can lead to a race condition.
+ mi0_next_to "main" "" "basics.c" "33" "next at main"
+
+ # FIXME: A string argument is not printed right; should be fixed and
+ # we should look for the right thing here.
+ # NOTE: The ``\\\\\"'' is for \".
+ mi0_step_to "callee1" \
+ "\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument\.\\\\\"\"\},\{name=\"fltarg\",value=\"3.5\"\}" \
+ "basics.c" "27" "step at main"
+
+ # FIXME: A string argument is not printed right; should be fixed and
+ # we should look for the right thing here.
+ mi0_run_to "exec-step 3" "end-stepping-range" "callee4" "" \
+ "basics.c" "8" "" "step to callee4"
+
+ # FIXME: A string argument is not printed right; should be fixed and
+ # we should look for the right thing here.
+ # NOTE: The ``.'' is part of ``gdb-result-var="$1"''
+ mi0_finish_to "callee3" ".*" "basics.c" "18" ".1" "0" "exec-finish"
+}
+
+proc test_controlling_breakpoints {} {
+ global mi_gdb_prompt
+
+ # Enable, delete, set ignore counts in breakpoints
+ # (disable was already tested above)
+ # Tests:
+ # -break-delete
+ # -break-enable
+ # -break-after
+ # -break-condition
+
+}
+
+proc test_program_termination {} {
+ global mi_gdb_prompt
+
+ # Run to completion: normal and forced
+ # Tests:
+ # -exec-abort
+ # (normal termination of inferior)
+
+ # FIXME: "stopped" doesn't seem appropriate.
+ # mi_gdb_test cannot be used for asynchronous commands because there are
+ # two prompts involved and this can lead to a race condition.
+ send_gdb "999-exec-continue\n"
+ gdb_expect {
+ -re "999\\^running\r\n$mi_gdb_prompt" {
+ gdb_expect {
+ -re "999\\*stopped,reason=\"exited-normally\"\r\n$mi_gdb_prompt$" {
+ pass "continue to end"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "continue to end (2)"}
+ timeout {fail "continue to end (timeout 2)"}
+ }
+ }
+ -re ".*$mi_gdb_prompt$" {fail "continue to end (1)"}
+ timeout {fail "continue to end (timeout 1)"}
+ }
+}
+
+test_breakpoints_creation_and_listing
+test_running_the_program
+test_controlled_execution
+test_controlling_breakpoints
+test_program_termination
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-stack.exp b/gdb/testsuite/gdb.mi/mi0-stack.exp
new file mode 100644
index 00000000000..270aa84ff6f
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-stack.exp
@@ -0,0 +1,218 @@
+# Copyright 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that stack commands work.
+
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+
+mi_gdb_test "200-break-insert callee4" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
+ "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to callee4"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "run to callee4 (2)"}
+ timeout {fail "run to callee4 (timeout 2)"}
+}
+
+
+proc test_stack_frame_listing {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Obtain a stack trace
+ # Tests:
+ # -stack-list-frames
+ # -stack-list-frames 1 1
+ # -stack-list-frames 1 3
+
+ mi_gdb_test "231-stack-list-frames" \
+ "231\\^done,stack=\{frame=\{level=\"0 \",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\"\},frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\},frame=\{level=\"2 \",addr=\"$hex\",func=\"callee2\",.*\},frame=\{level=\"3 \",addr=\"$hex\",func=\"callee1\",.*\},frame=\{level=\"4 \",addr=\"$hex\",func=\"main\",.*\}\}" \
+ "stack frame listing"
+ mi_gdb_test "232-stack-list-frames 1 1" \
+ "232\\^done,stack=\{frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\}\}" \
+ "stack frame listing 1 1"
+ mi_gdb_test "233-stack-list-frames 1 3" \
+ "233\\^done,stack=\{frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\},frame=\{level=\"2 \",addr=\"$hex\",func=\"callee2\",.*\},frame=\{level=\"3 \",addr=\"$hex\",func=\"callee1\",.*\}\}" \
+ "stack frame listing 1 3"
+
+ mi_gdb_test "234-stack-list-frames 1" \
+ "234\\^error,msg=\"mi_cmd_stack_list_frames: Usage.*FRAME_LOW FRAME_HIGH.*\"" \
+ "stack frame listing wrong"
+}
+
+proc test_stack_args_listing {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Obtain lists for args for the stack frames
+ # Tests:
+ # -stack-list-arguments 0
+ # -stack-list-arguments 0 1 1
+ # -stack-list-arguments 0 1 3
+ # -stack-list-arguments 1
+ # -stack-list-arguments 1 1 1
+ # -stack-list-arguments 1 1 3
+ # -stack-list-arguments
+
+ mi_gdb_test "231-stack-list-arguments 0" \
+ "231\\^done,stack-args=\{frame=\{level=\"0\",args=\{\}\},frame=\{level=\"1\",args=\{name=\"strarg\"\}\},frame=\{level=\"2\",args=\{name=\"intarg\",name=\"strarg\"\}\},frame=\{level=\"3\",args=\{name=\"intarg\",name=\"strarg\",name=\"fltarg\"\}\},frame=\{level=\"4\",args=\{\}\}\}" \
+ "stack args listing 0"
+
+ mi_gdb_test "232-stack-list-arguments 0 1 1" \
+ "232\\^done,stack-args=\{frame=\{level=\"1\",args=\{name=\"strarg\"\}\}\}" \
+ "stack args listing 0 1 1"
+
+ mi_gdb_test "233-stack-list-arguments 0 1 3" \
+ "233\\^done,stack-args=\{frame=\{level=\"1\",args=\{name=\"strarg\"\}\},frame=\{level=\"2\",args=\{name=\"intarg\",name=\"strarg\"\}\},frame=\{level=\"3\",args=\{name=\"intarg\",name=\"strarg\",name=\"fltarg\"\}\}\}" \
+ "stack args listing 0 1 3"
+
+ mi_gdb_test "231-stack-list-arguments 1" \
+ "231\\^done,stack-args=\{frame=\{level=\"0\",args=\{\}\},frame=\{level=\"1\",args=\{\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\},frame=\{level=\"2\",args=\{\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\},frame=\{level=\"3\",args=\{\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\},\{name=\"fltarg\",value=\"3.5\"\}\}\},frame=\{level=\"4\",args=\{\}\}\}" \
+ "stack args listing 1"
+
+ mi_gdb_test "232-stack-list-arguments 1 1 1" \
+ "232\\^done,stack-args=\{frame=\{level=\"1\",args=\{\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\}\}" \
+ "stack args listing 1 1 1"
+
+ mi_gdb_test "233-stack-list-arguments 1 1 3" \
+ "233\\^done,stack-args=\{frame=\{level=\"1\",args=\{\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\},frame=\{level=\"2\",args=\{\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\}\}\},frame=\{level=\"3\",args=\{\{name=\"intarg\",value=\"2\"\},\{name=\"strarg\",value=\"$hex \\\\\"A string argument.\\\\\"\"\},\{name=\"fltarg\",value=\"3.5\"\}\}\}\}" \
+ "stack args listing 1 1 3"
+
+ mi_gdb_test "234-stack-list-arguments" \
+ "234\\^error,msg=\"mi_cmd_stack_list_args: Usage.*PRINT_VALUES.*FRAME_LOW FRAME_HIGH.*\"" \
+ "stack args listing wrong"
+}
+
+proc test_stack_info_depth {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Obtain depth of stack
+ # Tests:
+ # -stack-info-depth
+ # -stack-info-depth 3
+ # -stack-info-depth 99
+
+ mi_gdb_test "231-stack-info-depth" \
+ "231\\^done,depth=\"5\"" \
+ "stack info-depth"
+
+ mi_gdb_test "231-stack-info-depth 3" \
+ "231\\^done,depth=\"3\"" \
+ "stack info-depth 3"
+
+ mi_gdb_test "231-stack-info-depth 99" \
+ "231\\^done,depth=\"5\"" \
+ "stack info-depth 99"
+
+ mi_gdb_test "231-stack-info-depth 99 99" \
+ "231\\^error,msg=\"mi_cmd_stack_info_depth: Usage: .MAX_DEPTH.\"" \
+ "stack info-depth wrong usage"
+}
+
+proc test_stack_locals_listing {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Obtain lists for locals for the stack frames
+ # Tests:
+ # -stack-list-locals 0
+ # -stack-list-locals 1
+ # -stack-list-arguments
+
+ mi_gdb_test "232-stack-list-locals 0" \
+ "232\\^done,locals=\{name=\"A\",name=\"B\",name=\"C\"\}" \
+ "stack locals listing 0"
+
+# step until A, B, C, have some reasonable values.
+send_gdb "-exec-next 3\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"13\"\}\r\n$mi_gdb_prompt$" {
+ pass "next's in callee4"
+ }
+ timeout { fail "next in callee4 (timeout)" }
+}
+
+ mi_gdb_test "232-stack-list-locals 1" \
+ "232\\^done,locals=\{\{name=\"A\",value=\"1\"\},\{name=\"B\",value=\"2\"\},\{name=\"C\",value=\"3\"\}\}" \
+ "stack locals listing 1"
+
+ mi_gdb_test "234-stack-list-locals" \
+ "234\\^error,msg=\"mi_cmd_stack_list_locals: Usage.*PRINT_VALUES.*\"" \
+ "stack locals listing wrong"
+
+ mi_gdb_test "232-stack-select-frame 1" \
+ "232\\^done" \
+ "stack select frame 1"
+
+ mi_gdb_test "232-stack-list-locals 1" \
+ "232\\^done,locals=\{\}" \
+ "stack locals listing for new frame"
+
+# this should be a no-op
+
+ mi_gdb_test "232-stack-select-frame" \
+ "232\\^done" \
+ "stack select same frame"
+
+ mi_gdb_test "232-stack-list-locals 1" \
+ "232\\^done,locals=\{\}" \
+ "stack locals for same frame (level 1)"
+
+}
+
+test_stack_frame_listing
+test_stack_args_listing
+test_stack_locals_listing
+test_stack_info_depth
+
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-stepi.exp b/gdb/testsuite/gdb.mi/mi0-stepi.exp
new file mode 100644
index 00000000000..456b2a1a9bc
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-stepi.exp
@@ -0,0 +1,109 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test Machine interface (MI) operations
+# Verify that, using the MI, we can run a simple program and perform
+# exec-step-instruction and exec-next-instruction.
+
+# The goal is not to
+# test gdb functionality, which is done by other tests, but to verify
+# the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_running_to_main {} {
+ global mi_gdb_prompt
+ global hex
+
+ mi_gdb_test "200-break-insert main" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+ "break-insert operation"
+
+ mi_run_cmd
+
+ gdb_expect {
+ -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"32\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to main"
+ }
+ -re ".*$mi_gdb_prompt$" {
+ fail "run to main (2)"
+ }
+ timeout {
+ fail "run to main (timeout)"
+ }
+ }
+}
+
+proc test_stepi_nexti {} {
+ global mi_gdb_prompt
+ global hex
+
+ send_gdb "111-exec-step-instruction\n"
+ gdb_expect {
+ -re "111\\^running\r\n${mi_gdb_prompt}111\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"3.\"\}\r\n$mi_gdb_prompt$" {
+ pass "step-instruction at main"
+ }
+ timeout {
+ fail "step-instruction at main (timeout)"
+ }
+ }
+ send_gdb "222-exec-next-instruction\n"
+ gdb_expect {
+ -re "222\\^running\r\n${mi_gdb_prompt}222\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"3.\"\}\r\n$mi_gdb_prompt$" {
+ pass "next-instruction at main"
+ }
+ timeout {
+ fail "next-instruction at main (timeout)"
+ }
+ }
+ send_gdb "333-exec-next-instruction\n"
+ gdb_expect {
+ -re "333\\^running\r\n${mi_gdb_prompt}333\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*basics.c\",line=\"3.\"\}\r\n$mi_gdb_prompt$" {
+ pass "next-instruction at main"
+ }
+ timeout {
+ fail "next-instruction at main (timeout)"
+ }
+ }
+}
+
+test_running_to_main
+test_stepi_nexti
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-until.exp b/gdb/testsuite/gdb.mi/mi0-until.exp
new file mode 100644
index 00000000000..1cf58a80971
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-until.exp
@@ -0,0 +1,127 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test Machine interface (MI) operations
+# Verify that, using the MI, we can run a simple program and perform
+# exec-until.
+
+# The goal is not to
+# test gdb functionality, which is done by other tests, but to verify
+# the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "until"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_running_to_foo {} {
+ global mi_gdb_prompt
+ global hex
+
+ mi_gdb_test "200-break-insert 10" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"foo\",file=\".*until.c\",line=\"10\",times=\"0\"\}" \
+ "break-insert operation"
+
+ mi_run_cmd
+
+ gdb_expect {
+ -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"foo\",args=\{\},file=\".*until.c\",line=\"10\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to main"
+ }
+ -re ".*$mi_gdb_prompt$" {
+ fail "run to main (2)"
+ }
+ timeout {
+ fail "run to main (timeout)"
+ }
+ }
+
+ mi_gdb_test "100-break-delete 1" "100\\^done" "break-delete 1"
+
+}
+
+proc test_until {} {
+ global mi_gdb_prompt
+ global hex
+
+ send_gdb "111-exec-until\n"
+ gdb_expect {
+ -re "111\\^running\r\n${mi_gdb_prompt}111\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"foo\",args=\{\},file=\".*until.c\",line=\"12\"\}\r\n$mi_gdb_prompt$" {
+ pass "until after while loop"
+ }
+ timeout {
+ fail "until after while loop (timeout)"
+ }
+ }
+
+ send_gdb "222-exec-until 15\n"
+ gdb_expect {
+ -re "222\\^running\r\n${mi_gdb_prompt}222\\*stopped,reason=\"location-reached\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"foo\",args=\{\},file=\".*until.c\",line=\"15\"\}\r\n$mi_gdb_prompt$" {
+ pass "until line number"
+ }
+ timeout {
+ fail "until line number (timeout)"
+ }
+ }
+
+ send_gdb "333-exec-until until.c:17\n"
+ gdb_expect {
+ -re "333\\^running\r\n${mi_gdb_prompt}333\\*stopped,reason=\"location-reached\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"foo\",args=\{\},file=\".*until.c\",line=\"17\"\}\r\n$mi_gdb_prompt$" {
+ pass "until line number:file"
+ }
+ timeout {
+ fail "until line number:file (timeout)"
+ }
+ }
+
+ # This is supposed to NOT stop at line 25. It stops right after foo is over.
+
+ send_gdb "444-exec-until until.c:25\n"
+ gdb_expect {
+ -re "444\\^running\r\n${mi_gdb_prompt}444\\*stopped,reason=\"location-reached\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\{\},file=\".*until.c\",line=\"24\"\}\r\n$mi_gdb_prompt$" {
+ pass "until after current function"
+ }
+ timeout {
+ fail "until after current function (timeout)"
+ }
+ }
+
+}
+
+test_running_to_foo
+test_until
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-var-block.exp b/gdb/testsuite/gdb.mi/mi0-var-block.exp
new file mode 100644
index 00000000000..023213912d8
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-var-block.exp
@@ -0,0 +1,228 @@
+# Copyright (C) 1999 2000 s Solutions
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can create, update, delete variables.
+#
+
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "var-cmd"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+mi_gdb_test "200-break-insert do_block_tests" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_block_tests\",file=\".*var-cmd.c\",line=\"154\",times=\"0\"\}" \
+ "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"154\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to do_block_tests"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "run to do_block_tests (2)"}
+ timeout {fail "run to do_block_tests (timeout 2)"}
+}
+
+# Test: c_variable-3.2
+# Desc: create cb and foo
+mi_gdb_test "-var-create cb * cb" \
+ "\\^done,name=\"cb\",numchild=\"0\",type=\"int\"" \
+ "create local variable cb"
+
+mi_gdb_test "-var-create foo * foo" \
+ "&\"mi_cmd_var_create: unable to create variable object\\\\n\".*\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
+ "create local variable foo"
+
+# step to "foo = 123;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"158\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_block_tests"
+ }
+ timeout {
+ fail "step at do_block_tests (timeout)"
+ }
+}
+
+
+# Be paranoid and assume 3.2 created foo
+mi_gdb_test "-var-delete foo" \
+ "&\"Variable object not found\\\\n\".*\\^error,msg=\"Variable object not found\"" \
+ "delete var foo"
+
+
+# Test: c_variable-3.3
+# Desc: create foo
+mi_gdb_test "-var-create foo * foo" \
+ "\\^done,name=\"foo\",numchild=\"0\",type=\"int\"" \
+ "create local variable foo"
+
+# step to "foo2 = 123;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"161\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_block_tests"
+ }
+ timeout {
+ fail "step at do_block_tests (timeout)"
+ }
+}
+
+# Test: c_variable-3.4
+# Desc: check foo, cb changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"foo\",in_scope=\"true\",type_changed=\"false\",name=\"cb\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: cb foo changed"
+
+# step to "foo = 321;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"164\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_block_tests"
+ }
+ timeout {
+ fail "step at do_block_tests (timeout)"
+ }
+}
+
+# Test: c_variable-3.5
+# Desc: create inner block foo
+mi_gdb_test "-var-create inner_foo * foo" \
+ "\\^done,name=\"inner_foo\",numchild=\"0\",type=\"int\"" \
+ "create local variable inner_foo"
+
+# step to "foo2 = 0;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"166\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_block_tests"
+ }
+ timeout { fail "step at do_block_tests (timeout)" }
+}
+
+# Test: c_variable-3.6
+# Desc: create foo2
+mi_gdb_test "-var-create foo2 * foo2" \
+ "\\^done,name=\"foo2\",numchild=\"0\",type=\"int\"" \
+ "create local variable foo2"
+
+# Test: c_variable-3.7
+# Desc: check that outer foo in scope and inner foo out of scope
+# Note: also a known gdb problem
+setup_xfail *-*-*
+mi_gdb_test "-var-update inner_foo" \
+ "\\^done,changelist=\{FIXME\}" \
+ "update inner_foo: should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+
+setup_xfail *-*-*
+mi_gdb_test "-var-evaluate-expression inner_foo" \
+ "\\^done,value=\{FIXME\}" \
+ "evaluate inner_foo: should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+
+mi_gdb_test "-var-update foo" \
+ "\\^done,changelist=\{\}" \
+ "update foo: did not change"
+
+mi_gdb_test "-var-delete inner_foo" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var inner_foo"
+
+# step to "foo = 0;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"168\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_block_tests"
+ }
+ timeout { fail "step at do_block_tests (timeout)" }
+}
+
+# Test: c_variable-3.8
+# Desc: check that foo2 out of scope (known gdb problem)
+setup_xfail *-*-*
+mi_gdb_test "-var-update foo2" \
+ "\\^done,changelist=\{FIXME\}" \
+ "update foo2: should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+
+# step to "cb = 21;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_block_tests\",args=\{\},file=\".*var-cmd.c\",line=\"171\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_block_tests"
+ }
+ timeout { fail "step at do_block_tests (timeout)" }
+}
+
+
+# Test: c_variable-3.9
+# Desc: check that only cb is in scope (known gdb problem)
+setup_xfail *-*-*
+mi_gdb_test "-var-update foo2" \
+ "\\^done,changelist=\{FIXME\}" \
+ "update foo2 should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+setup_xfail *-*-*
+mi_gdb_test "-var-update foo" \
+ "\\^done,changelist=\{FIXME\}" \
+ "update foo should be out of scope: KNOWN PROBLEM"
+clear_xfail *-*-*
+mi_gdb_test "-var-update cb" \
+ "\\^done,changelist=\{\}" \
+ "update cb"
+
+# Test: c_variable-3.10
+# Desc: names of editable variables
+#gdbtk_test c_variable-3.10 {names of editable variables} {
+# editable_variables
+#} {{foo cb foo2} {}}
+
+# Done with block tests
+mi_gdb_test "-var-delete foo" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var foo"
+
+mi_gdb_test "-var-delete foo2" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var foo2"
+
+mi_gdb_test "-var-delete cb" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var cb"
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-var-child.exp b/gdb/testsuite/gdb.mi/mi0-var-child.exp
new file mode 100644
index 00000000000..bd7462206fc
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-var-child.exp
@@ -0,0 +1,1333 @@
+# Copyright (C) 1999 2000 Cygnus Solutions
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can create, update, delete variables.
+#
+
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "var-cmd"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+mi_gdb_test "200-break-insert do_children_tests" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_children_tests\",file=\".*var-cmd.c\",line=\"190\",times=\"0\"\}" \
+ "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"190\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to do_children_tests"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "run to do_children_tests (2)"}
+ timeout {fail "run to do_children_tests (timeout 2)"}
+}
+
+##### #####
+# #
+# children tests #
+# #
+##### #####
+
+
+# Test: c_variable-4.2
+# Desc: create variable "struct_declarations"
+mi_gdb_test "-var-create struct_declarations * struct_declarations" \
+ "\\^done,name=\"struct_declarations\",numchild=\"11\",type=\"struct _struct_decl\"" \
+ "create local variable struct_declarations"
+
+# Test: c_variable-4.3
+# Desc: children of struct_declarations
+# STABS doesn't give us argument types for the func ptr structs, but
+# Dwarf 2 does.
+mi_gdb_test "-var-list-children struct_declarations" \
+ "\\^done,numchild=\"11\",children=\{child=\{name=\"struct_declarations.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"struct_declarations.character\",exp=\"character\",numchild=\"0\",type=\"char\"\},child={name=\"struct_declarations.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\"\},child=\{name=\"struct_declarations.long_int\",exp=\"long_int\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.int_ptr_ptr\",exp=\"int_ptr_ptr\",numchild=\"1\",type=\"int \\*\\*\"\},child=\{name=\"struct_declarations.long_array\",exp=\"long_array\",numchild=\"10\",type=\"long int \\\[10\\\]\"\},child=\{name=\"struct_declarations.func_ptr\",exp=\"func_ptr\",numchild=\"0\",type=\"void \\(\\*\\)\\((void)?\\)\"\},child=\{name=\"struct_declarations.func_ptr_struct\",exp=\"func_ptr_struct\",numchild=\"0\",type=\"struct _struct_decl \\(\\*\\)\\((int, char \\*, long int)?\\)\"\},child=\{name=\"struct_declarations.func_ptr_ptr\",exp=\"func_ptr_ptr\",numchild=\"0\",type=\"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long int)?\\)\"\},child=\{name=\"struct_declarations.u1\",exp=\"u1\",numchild=\"4\",type=\"union \{\\.\\.\\.\}\"\},child=\{name=\"struct_declarations.s2\",exp=\"s2\",numchild=\"4\",type=\"struct \{\\.\\.\\.\}\"\}\}" \
+ "get children of struct_declarations"
+
+#gdbtk_test c_variable-4.3 {children of struct_declarations} {
+# get_children struct_declarations
+#} {integer character char_ptr long_int int_ptr_ptr long_array func_ptr func_ptr_struct func_ptr_ptr u1 s2}
+
+# Test: c_variable-4.4
+# Desc: number of children of struct_declarations
+mi_gdb_test "-var-info-num-children struct_declarations" \
+ "\\^done,numchild=\"11\"" \
+ "get number of children of struct_declarations"
+
+# Test: c_variable-4.5
+# Desc: children of struct_declarations.integer
+mi_gdb_test "-var-list-children struct_declarations.integer" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.integer"
+
+# Test: c_variable-4.6
+# Desc: number of children of struct_declarations.integer
+mi_gdb_test "-var-info-num-children struct_declarations.integer" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.integer"
+
+# Test: c_variable-4.7
+# Desc: children of struct_declarations.character
+mi_gdb_test "-var-list-children struct_declarations.character" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.character"
+
+# Test: c_variable-4.8
+# Desc: number of children of struct_declarations.character
+mi_gdb_test "-var-info-num-children struct_declarations.character" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.character"
+
+# Test: c_variable-4.9
+# Desc: children of struct_declarations.char_ptr
+mi_gdb_test "-var-list-children struct_declarations.char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"struct_declarations.char_ptr.\\*char_ptr\",exp=\"\\*char_ptr\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of struct_declarations.char_ptr"
+
+# Test: c_variable-4.10
+# Desc: number of children of struct_declarations.char_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of struct_declarations.char_ptr"
+
+# Test: c_variable-4.11
+# Desc: children of struct_declarations.long_int
+mi_gdb_test "-var-list-children struct_declarations.long_int" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_int"
+
+# Test: c_variable-4.12
+# Desc: number of children of struct_declarations.long_int
+mi_gdb_test "-var-info-num-children struct_declarations.long_int" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_int"
+
+# Test: c_variable-4.13
+# Desc: children of int_ptr_ptr
+mi_gdb_test "-var-list-children struct_declarations.int_ptr_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",exp=\"\\*int_ptr_ptr\",numchild=\"1\",type=\"int \\*\"\}\}" \
+ "get children of struct_declarations.int_ptr_ptr"
+
+#gdbtk_test c_variable-4.13 {children of int_ptr_ptr} {
+# get_children struct_declarations.int_ptr_ptr
+#} {*int_ptr_ptr}
+
+# Test: c_variable-4.14
+# Desc: number of children of int_ptr_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.int_ptr_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of struct_declarations.int_ptr_ptr"
+
+
+# Test: c_variable-4.15
+# Desc: children of struct_declarations.long_array
+mi_gdb_test "-var-list-children struct_declarations.long_array" \
+ "\\^done,numchild=\"10\",children=\{child=\{name=\"struct_declarations.long_array.0\",exp=\"0\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.1\",exp=\"1\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.2\",exp=\"2\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.3\",exp=\"3\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.4\",exp=\"4\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.5\",exp=\"5\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.6\",exp=\"6\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.7\",exp=\"7\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.8\",exp=\"8\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.long_array.9\",exp=\"9\",numchild=\"0\",type=\"long int\"\}\}" \
+ "get children of struct_declarations.long_array"
+
+# Test: c_variable-4.16
+# Desc: number of children of struct_declarations.long_array
+mi_gdb_test "-var-info-num-children struct_declarations.long_array" \
+ "\\^done,numchild=\"10\"" \
+ "get number of children of struct_declarations.long_array"
+
+# Test: c_variable-4.17
+# Desc: children of struct_declarations.func_ptr
+mi_gdb_test "-var-list-children struct_declarations.func_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.func_ptr"
+
+
+# Test: c_variable-4.18
+# Desc: number of children of struct_declarations.func_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.func_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.func_ptr"
+
+
+# Test: c_variable-4.19
+# Desc: children of struct_declarations.func_ptr_struct
+mi_gdb_test "-var-list-children struct_declarations.func_ptr_struct" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.func_ptr_struct"
+
+# Test: c_variable-4.20
+# Desc: number of children of struct_declarations.func_ptr_struct
+mi_gdb_test "-var-info-num-children struct_declarations.func_ptr_struct" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.func_ptr_struct"
+
+
+# Test: c_variable-4.21
+# Desc: children of struct_declarations.func_ptr_ptr
+mi_gdb_test "-var-list-children struct_declarations.func_ptr_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.func_ptr_ptr"
+
+# Test: c_variable-4.22
+# Desc: number of children of struct_declarations.func_ptr_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.func_ptr_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.func_ptr_ptr"
+
+
+# Test: c_variable-4.23
+# Desc: children of struct_declarations.u1
+mi_gdb_test "-var-list-children struct_declarations.u1" \
+ "\\^done,numchild=\"4\",children=\{child=\{name=\"struct_declarations.u1.a\",exp=\"a\",numchild=\"0\",type=\"int\"\},child=\{name=\"struct_declarations.u1.b\",exp=\"b\",numchild=\"1\",type=\"char \\*\"\},child=\{name=\"struct_declarations.u1.c\",exp=\"c\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.u1.d\",exp=\"d\",numchild=\"0\",type=\"enum foo\"\}\}" \
+ "get children of struct_declarations.u1"
+
+# Test: c_variable-4.24
+# Desc: number of children of struct_declarations.u1
+mi_gdb_test "-var-info-num-children struct_declarations.u1" \
+ "\\^done,numchild=\"4\"" \
+ "get number of children of struct_declarations.u1"
+
+# Test: c_variable-4.25
+# Desc: children of struct_declarations.s2
+mi_gdb_test "-var-list-children struct_declarations.s2" \
+ "\\^done,numchild=\"4\",children=\{child=\{name=\"struct_declarations.s2.u2\",exp=\"u2\",numchild=\"3\",type=\"union \{\\.\\.\\.\}\"\},child=\{name=\"struct_declarations.s2.g\",exp=\"g\",numchild=\"0\",type=\"int\"\},child=\{name=\"struct_declarations.s2.h\",exp=\"h\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.i\",exp=\"i\",numchild=\"10\",type=\"long int \\\[10\\\]\"\}\}" \
+ "get children of struct_declarations.s2"
+#gdbtk_test c_variable-4.25 {children of struct_declarations.s2} {
+# get_children struct_declarations.s2
+#} {u2 g h i}
+
+# Test: c_variable-4.26
+# Desc: number of children of struct_declarations.s2
+mi_gdb_test "-var-info-num-children struct_declarations.s2" \
+ "\\^done,numchild=\"4\"" \
+ "get number of children of struct_declarations.s2"
+
+
+# Test: c_variable-4.27
+# Desc: children of struct_declarations.long_array.1
+mi_gdb_test "-var-list-children struct_declarations.long_array.1" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.1"
+
+# Test: c_variable-4.28
+# Desc: number of children of struct_declarations.long_array.1
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.1" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.1"
+
+# Test: c_variable-4.29
+# Desc: children of struct_declarations.long_array.2
+mi_gdb_test "-var-list-children struct_declarations.long_array.2" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.2"
+
+# Test: c_variable-4.30
+# Desc: number of children of struct_declarations.long_array.2
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.2" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.2"
+
+# Test: c_variable-4.31
+# Desc: children of struct_declarations.long_array.3
+mi_gdb_test "-var-list-children struct_declarations.long_array.3" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.3"
+
+# Test: c_variable-4.32
+# Desc: number of children of struct_declarations.long_array.3
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.3" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.3"
+
+# Test: c_variable-4.33
+# Desc: children of struct_declarations.long_array.4
+mi_gdb_test "-var-list-children struct_declarations.long_array.4" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.4"
+
+# Test: c_variable-4.34
+# Desc: number of children of struct_declarations.long_array.4
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.4" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.4"
+
+# Test: c_variable-4.35
+# Desc: children of struct_declarations.long_array.5
+mi_gdb_test "-var-list-children struct_declarations.long_array.5" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.5"
+
+# Test: c_variable-4.36
+# Desc: number of children of struct_declarations.long_array.5
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.5" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.5"
+
+# Test: c_variable-4.37
+# Desc: children of struct_declarations.long_array.6
+mi_gdb_test "-var-list-children struct_declarations.long_array.6" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.6"
+
+# Test: c_variable-4.38
+# Desc: number of children of struct_declarations.long_array.6
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.6" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.6"
+
+# Test: c_variable-4.39
+# Desc: children of struct_declarations.long_array.7
+mi_gdb_test "-var-list-children struct_declarations.long_array.7" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.7"
+
+# Test: c_variable-4.40
+# Desc: number of children of struct_declarations.long_array.7
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.7" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.7"
+
+# Test: c_variable-4.41
+# Desc: children of struct_declarations.long_array.8
+mi_gdb_test "-var-list-children struct_declarations.long_array.8" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.8"
+
+# Test: c_variable-4.42
+# Desc: number of children of struct_declarations.long_array.8
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.8" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.8"
+
+
+# Test: c_variable-4.43
+# Desc: children of struct_declarations.long_array.9
+mi_gdb_test "-var-list-children struct_declarations.long_array.9" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.long_array.9"
+
+# Test: c_variable-4.44
+# Desc: number of children of struct_declarations.long_array.9
+mi_gdb_test "-var-info-num-children struct_declarations.long_array.9" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.long_array.9"
+
+# Test: c_variable-4.45
+# Desc: children of struct_declarations.u1.a
+mi_gdb_test "-var-list-children struct_declarations.u1.a" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.u1.a"
+
+# Test: c_variable-4.46
+# Desc: number of children of struct_declarations.u1.a
+mi_gdb_test "-var-info-num-children struct_declarations.u1.a" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.u1.a"
+
+# Test: c_variable-4.47
+# Desc: children of struct_declarations.u1.b
+mi_gdb_test "-var-list-children struct_declarations.u1.b" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"struct_declarations.u1.b.\\*b\",exp=\"\\*b\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of struct_declarations.u1.b"
+
+# Test: c_variable-4.48
+# Desc: number of children of struct_declarations.u1.b
+mi_gdb_test "-var-info-num-children struct_declarations.u1.b" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of struct_declarations.u1.b"
+
+# Test: c_variable-4.49
+# Desc: children of struct_declarations.u1.c
+mi_gdb_test "-var-list-children struct_declarations.u1.c" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.u1.c"
+
+# Test: c_variable-4.50
+# Desc: number of children of struct_declarations.u1.c
+mi_gdb_test "-var-info-num-children struct_declarations.u1.c" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.u1.c"
+
+# Test: c_variable-4.51
+# Desc: children of struct_declarations.u1.d
+mi_gdb_test "-var-list-children struct_declarations.u1.d" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.u1.d"
+
+
+# Test: c_variable-4.52
+# Desc: number of children of struct_declarations.u1.d
+mi_gdb_test "-var-info-num-children struct_declarations.u1.d" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.u1.d"
+
+
+# Test: c_variable-4.53
+# Desc: children of struct_declarations.s2.u2
+mi_gdb_test "-var-list-children struct_declarations.s2.u2" \
+ "\\^done,numchild=\"3\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s1\",exp=\"u1s1\",numchild=\"4\",type=\"struct \{\\.\\.\\.\}\"\},child=\{name=\"struct_declarations.s2.u2.f\",exp=\"f\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.u2.u1s2\",exp=\"u1s2\",numchild=\"2\",type=\"struct \{\\.\\.\\.\}\"\}\}" \
+ "get children of struct_declarations.s2.u2"
+
+# Test: c_variable-4.54
+# Desc: number of children of struct_declarations.s2.u2
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2" \
+ "\\^done,numchild=\"3\"" \
+ "get number of children of struct_declarations.s2.u2"
+
+# Test: c_variable-4.55
+# Desc: children of struct_declarations.s2.g
+mi_gdb_test "-var-list-children struct_declarations.s2.g" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.s2.g"
+
+# Test: c_variable-4.56
+# Desc: number of children of struct_declarations.s2.g
+mi_gdb_test "-var-info-num-children struct_declarations.s2.g" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.s2.g"
+
+
+# Test: c_variable-4.57
+# Desc: children of struct_declarations.s2.h
+mi_gdb_test "-var-list-children struct_declarations.s2.h" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.s2.h"
+
+# Test: c_variable-4.58
+# Desc: number of children of struct_declarations.s2.h
+mi_gdb_test "-var-info-num-children struct_declarations.s2.h" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.s2.h"
+
+
+# Test: c_variable-4.59
+# Desc: children of struct_declarations.s2.i
+mi_gdb_test "-var-list-children struct_declarations.s2.i" \
+ "\\^done,numchild=\"10\",children=\{child=\{name=\"struct_declarations.s2.i.0\",exp=\"0\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.1\",exp=\"1\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.2\",exp=\"2\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.3\",exp=\"3\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.4\",exp=\"4\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.5\",exp=\"5\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.6\",exp=\"6\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.7\",exp=\"7\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.8\",exp=\"8\",numchild=\"0\",type=\"long int\"\},child=\{name=\"struct_declarations.s2.i.9\",exp=\"9\",numchild=\"0\",type=\"long int\"\}\}" \
+ "get children of struct_declarations.s2.i"
+
+# Test: c_variable-4.60
+# Desc: number of children of struct_declarations.s2.i
+mi_gdb_test "-var-info-num-children struct_declarations.s2.i" \
+ "\\^done,numchild=\"10\"" \
+ "get number of children of struct_declarations.s2.i"
+
+# Test: c_variable-4.61
+# Desc: children of struct_declarations.s2.u2.u1s1
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1" \
+ "\\^done,numchild=\"4\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s1.d\",exp=\"d\",numchild=\"0\",type=\"int\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e\",exp=\"e\",numchild=\"10\",type=\"char \\\[10\\\]\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.func\",exp=\"func\",numchild=\"0\",type=\"int \\*\\(\\*\\)\\((void)?\\)\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.foo\",exp=\"foo\",numchild=\"0\",type=\"efoo\"\}\}" \
+ "get children of struct_declarations.s2.u2.u1s1"
+
+# Test: c_variable-4.62
+# Desc: number of children of struct_declarations.s2.u2.u1s1
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1" \
+ "\\^done,numchild=\"4\"" \
+ "get number of children of struct_declarations.s2.u2.u1s1"
+
+# Test: c_variable-4.63
+# Desc: children of struct_declarations.s2.u2.f
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.f" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.s2.u2.f"
+
+# Test: c_variable-4.64
+# Desc: number of children of struct_declarations.s2.u2.f
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.f" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.s2.u2.f"
+
+# Test: c_variable-4.65
+# Desc: children of struct_declarations.s2.u2.u1s2
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s2" \
+ "\\^done,numchild=\"2\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s2.array_ptr\",exp=\"array_ptr\",numchild=\"2\",type=\"char \\\[2\\\]\"\},child=\{name=\"struct_declarations.s2.u2.u1s2.func\",exp=\"func\",numchild=\"0\",type=\"int \\(\\*\\)\\((int, char \\*)?\\)\"\}\}" \
+ "get children of struct_declarations.s2.u2.u1s2"
+
+# Test: c_variable-4.66
+# Desc: number of children of struct_declarations.s2.u2.u1s2
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s2" \
+ "\\^done,numchild=\"2\"" \
+ "get number of children of struct_declarations.s2.u2.u1s2"
+
+# Test: c_variable-4.67
+# Desc: children of struct_declarations.s2.u2.u1s1.d
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1.d" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.s2.u2.u1s1.d"
+
+# Test: c_variable-4.68
+# Desc: number of children of struct_declarations.s2.u2.u1s1.d
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1.d" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.s2.u2.u1s1.d"
+
+# Test: c_variable-4.69
+# Desc: children of struct_declarations.s2.u2.u1s1.e
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1.e" \
+ "\\^done,numchild=\"10\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s1.e.0\",exp=\"0\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.1\",exp=\"1\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.2\",exp=\"2\",numchild=\"0\",type=\"char\"\},child={name=\"struct_declarations.s2.u2.u1s1.e.3\",exp=\"3\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.4\",exp=\"4\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.5\",exp=\"5\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.6\",exp=\"6\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.7\",exp=\"7\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.8\",exp=\"8\",numchild=\"0\",type=\"char\"\},child=\{name=\"struct_declarations.s2.u2.u1s1.e.9\",exp=\"9\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of struct_declarations.s2.u2.u1s1.e"
+
+# Test: c_variable-4.70
+# Desc: number of children of struct_declarations.s2.u2.u1s1.e
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1.e" \
+ "\\^done,numchild=\"10\"" \
+ "get number of children of struct_declarations.s2.u2.u1s1.e"
+
+
+# Test: c_variable-4.71
+# Desc: children of struct_declarations.s2.u2.u1s1.func
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1.func" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.s2.u2.u1s1.func"
+
+# Test: c_variable-4.72
+# Desc: number of children of struct_declarations.s2.u2.u1s1.func
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1.func" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.s2.u2.u1s1.func"
+
+
+# Test: c_variable-4.73
+# Desc: children of struct_declarations.s2.u2.u1s1.foo
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s1.foo" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.s2.u2.u1s1.foo"
+
+# Test: c_variable-4.74
+# Desc: number of children of struct_declarations.s2.u2.u1s1.foo
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s1.foo" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.s2.u2.u1s1.foo"
+
+
+# Test: c_variable-4.75
+# Desc: children of struct_declarations.s2.u2.u1s2.array_ptr
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s2.array_ptr" \
+ "\\^done,numchild=\"2\",children=\{child=\{name=\"struct_declarations.s2.u2.u1s2.array_ptr.0\",exp=\"0\",numchild=\"0\",type=\"char\"\},child={name=\"struct_declarations.s2.u2.u1s2.array_ptr.1\",exp=\"1\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of struct_declarations.s2.u2.u1s2.array_ptr"
+
+# Test: c_variable-4.76
+# Desc: number of children of struct_declarations.s2.u2.u1s2.array_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s2.array_ptr" \
+ "\\^done,numchild=\"2\"" \
+ "get number of children of struct_declarations.s2.u2.u1s2.array_ptr"
+
+# Test: c_variable-4.77
+# Desc: children of struct_declarations.s2.u2.u1s2.func
+mi_gdb_test "-var-list-children struct_declarations.s2.u2.u1s2.func" \
+ "\\^done,numchild=\"0\"" \
+ "get children of struct_declarations.s2.u2.u1s2.func"
+
+# Test: c_variable-4.78
+# Desc: number of children of struct_declarations.s2.u2.u1s2.func
+mi_gdb_test "-var-info-num-children struct_declarations.s2.u2.u1s2.func" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of struct_declarations.s2.u2.u1s2.func"
+
+# Test: c_variable-4.79
+# Desc: children of struct_declarations.int_ptr_ptr.*int_ptr_ptr
+mi_gdb_test "-var-list-children struct_declarations.int_ptr_ptr.*int_ptr_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",exp=\"\\*\\*int_ptr_ptr\",numchild=\"0\",type=\"int\"\}\}" \
+ "get children of struct_declarations.int_ptr_ptr.*int_ptr_ptr"
+#} {**int_ptr_ptr}
+
+# Test: c_variable-4.80
+# Desc: Number of children of struct_declarations.int_ptr_ptr.*int_ptr_ptr
+mi_gdb_test "-var-info-num-children struct_declarations.int_ptr_ptr.*int_ptr_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of struct_declarations.int_ptr_ptr.*int_ptr_ptr"
+
+
+# Step to "struct_declarations.integer = 123;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"192\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+
+# Test: c_variable-4.81
+# Desc: create local variable "weird"
+mi_gdb_test "-var-create weird * weird" \
+ "\\^done,name=\"weird\",numchild=\"11\",type=\"weird_struct \\*\"" \
+ "create local variable weird"
+
+# Test: c_variable-4.82
+# Desc: children of weird
+mi_gdb_test "-var-list-children weird" \
+ "\\^done,numchild=\"11\",children=\{child=\{name=\"weird.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"weird.character\",exp=\"character\",numchild=\"0\",type=\"char\"\},child=\{name=\"weird.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\"\},child=\{name=\"weird.long_int\",exp=\"long_int\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.int_ptr_ptr\",exp=\"int_ptr_ptr\",numchild=\"1\",type=\"int \\*\\*\"\},child=\{name=\"weird.long_array\",exp=\"long_array\",numchild=\"10\",type=\"long int \\\[10\\\]\"\},child=\{name=\"weird.func_ptr\",exp=\"func_ptr\",numchild=\"0\",type=\"void \\(\\*\\)\\((void)?\\)\"\},child=\{name=\"weird.func_ptr_struct\",exp=\"func_ptr_struct\",numchild=\"0\",type=\"struct _struct_decl \\(\\*\\)\\((int, char \\*, long int)?\\)\"\},child=\{name=\"weird.func_ptr_ptr\",exp=\"func_ptr_ptr\",numchild=\"0\",type=\"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long int)?\\)\"\},child=\{name=\"weird.u1\",exp=\"u1\",numchild=\"4\",type=\"union \{\\.\\.\\.\}\"\},child=\{name=\"weird.s2\",exp=\"s2\",numchild=\"4\",type=\"struct \{\\.\\.\\.\}\"\}\}" \
+ "get children of weird"
+
+# Test: c_variable-4.83
+# Desc: number of children of weird
+mi_gdb_test "-var-info-num-children weird" \
+ "\\^done,numchild=\"11\"" \
+ "get number of children of weird"
+
+
+# Test: c_variable-4.84
+# Desc: children of weird->long_array
+mi_gdb_test "-var-list-children weird.long_array" \
+ "\\^done,numchild=\"10\",children=\{child=\{name=\"weird.long_array.0\",exp=\"0\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.1\",exp=\"1\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.2\",exp=\"2\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.3\",exp=\"3\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.4\",exp=\"4\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.5\",exp=\"5\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.6\",exp=\"6\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.7\",exp=\"7\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.8\",exp=\"8\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.long_array.9\",exp=\"9\",numchild=\"0\",type=\"long int\"\}\}" \
+ "get children of weird.long_array"
+#gdbtk_test c_variable-4.84 {children of weird->long_array} {
+# get_children weird.long_array
+#} {0 1 2 3 4 5 6 7 8 9}
+
+# Test: c_variable-4.85
+# Desc: number of children of weird.long_array
+mi_gdb_test "-var-info-num-children weird.long_array" \
+ "\\^done,numchild=\"10\"" \
+ "get number of children of weird.long_array"
+
+# Test: c_variable-4.86
+# Desc: children of weird.int_ptr_ptr
+mi_gdb_test "-var-list-children weird.int_ptr_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"weird.int_ptr_ptr.\\*int_ptr_ptr\",exp=\"\\*int_ptr_ptr\",numchild=\"1\",type=\"int \\*\"\}\}" \
+ "get children of weird.int_ptr_ptr"
+#gdbtk_test c_variable-4.86 {children of weird->int_ptr_ptr} {
+# get_children weird.int_ptr_ptr
+#} {*int_ptr_ptr}
+
+# Test: c_variable-4.87
+# Desc: number of children of weird.int_ptr_ptr
+mi_gdb_test "-var-info-num-children weird.int_ptr_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of weird.int_ptr_ptr"
+
+# Test: c_variable-4.88
+# Desc: children of *weird->int_ptr_ptr
+mi_gdb_test "-var-list-children weird.int_ptr_ptr.*int_ptr_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"weird.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",exp=\"\\*\\*int_ptr_ptr\",numchild=\"0\",type=\"int\"\}\}" \
+ "get children of weird.int_ptr_ptr.*int_ptr_ptr"
+#gdbtk_test c_variable-4.88 {children of *weird->int_ptr_ptr} {
+# get_children weird.int_ptr_ptr.*int_ptr_ptr
+#} {**int_ptr_ptr}
+
+# Test: c_variable-4.89
+# Desc: number of children *weird->int_ptr_ptr
+mi_gdb_test "-var-info-num-children weird.int_ptr_ptr.*int_ptr_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of weird.int_ptr_ptr.*int_ptr_ptr"
+
+# Test: c_variable-4.90
+# Desc: create weird->int_ptr_ptr
+mi_gdb_test "-var-create weird->int_ptr_ptr * weird->int_ptr_ptr" \
+ "\\^done,name=\"weird->int_ptr_ptr\",numchild=\"1\",type=\"int \\*\\*\"" \
+ "create local variable weird->int_ptr_ptr"
+
+# Test: c_variable-4.91
+# Desc: children of weird->int_ptr_ptr
+mi_gdb_test "-var-list-children weird->int_ptr_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",exp=\"\\*weird->int_ptr_ptr\",numchild=\"1\",type=\"int \\*\"\}\}" \
+ "get children of weird->int_ptr_ptr"
+
+
+# Test: c_variable-4.92
+# Desc: number of children of (weird->int_ptr_ptr)
+mi_gdb_test "-var-info-num-children weird->int_ptr_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of weird->int_ptr_ptr"
+
+# Test: c_variable-4.93
+# Desc: children of *(weird->int_ptr_ptr)
+mi_gdb_test "-var-list-children weird->int_ptr_ptr.*weird->int_ptr_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",exp=\"\\*\\*weird->int_ptr_ptr\",numchild=\"0\",type=\"int\"\}\}" \
+ "get children of weird->int_ptr_ptr.*weird->int_ptr_ptr"
+
+# Test: c_variable-4.94
+# Desc: number of children of *(weird->int_ptr_ptr)
+mi_gdb_test "-var-info-num-children weird->int_ptr_ptr.*weird->int_ptr_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of weird->int_ptr_ptr.*weird->int_ptr_ptr"
+
+# Test: c_variable-4.95
+# Desc: children of *(*(weird->int_ptr_ptr))
+mi_gdb_test "-var-list-children weird->int_ptr_ptr.*weird->int_ptr_ptr.**weird->int_ptr_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get children of weird->int_ptr_ptr.*weird->int_ptr_ptr.**weird->int_ptr_ptr"
+
+# Test: c_variable-4.96
+# Desc: number of children of *(*(weird->int_ptr_ptr))
+mi_gdb_test "-var-info-num-children weird->int_ptr_ptr.*weird->int_ptr_ptr.**weird->int_ptr_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of weird->int_ptr_ptr.*weird->int_ptr_ptr.**weird->int_ptr_ptr"
+
+# Test: c_variable-4.97
+# Desc: is weird editable
+mi_gdb_test "-var-show-attributes weird" \
+ "\\^done,attr=\"editable\"" \
+ "is weird editable"
+
+# Test: c_variable-4.98
+# Desc: is weird->int_ptr_ptr editable
+mi_gdb_test "-var-show-attributes weird->int_ptr_ptr" \
+ "\\^done,attr=\"editable\"" \
+ "is weird->int_ptr_ptr editable"
+
+# Test: c_variable-4.99
+# Desc: is *(weird->int_ptr_ptr) editable
+mi_gdb_test "-var-show-attributes weird.int_ptr_ptr.*int_ptr_ptr" \
+ "\\^done,attr=\"editable\"" \
+ "is weird.int_ptr_ptr.*int_ptr_ptr editable"
+
+# Test: c_variable-4.100
+# Desc: is *(*(weird->int_ptr_ptr)) editable
+mi_gdb_test "-var-show-attributes weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr" \
+ "\\^done,attr=\"editable\"" \
+ "is weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr editable"
+
+# Test: c_variable-4.101
+# Desc: is weird->u1 editable
+mi_gdb_test "-var-show-attributes weird.u1" \
+ "\\^done,attr=\"noneditable\"" \
+ "is weird.u1 editable"
+
+# Test: c_variable-4.102
+# Desc: is weird->s2 editable
+mi_gdb_test "-var-show-attributes weird.s2" \
+ "\\^done,attr=\"noneditable\"" \
+ "is weird.s2 editable"
+
+# Test: c_variable-4.103
+# Desc: is struct_declarations.u1.a editable
+mi_gdb_test "-var-show-attributes struct_declarations.u1.a" \
+ "\\^done,attr=\"editable\"" \
+ "is struct_declarations.u1.a editable"
+
+# Test: c_variable-4.104
+# Desc: is struct_declarations.u1.b editable
+mi_gdb_test "-var-show-attributes struct_declarations.u1.b" \
+ "\\^done,attr=\"editable\"" \
+ "is struct_declarations.u1.b editable"
+
+# Test: c_variable-4.105
+# Desc: is struct_declarations.u1.c editable
+mi_gdb_test "-var-show-attributes struct_declarations.u1.c" \
+ "\\^done,attr=\"editable\"" \
+ "is struct_declarations.u1.c editable"
+
+# Test: c_variable-4.106
+# Desc: is struct_declarations.long_array editable
+mi_gdb_test "-var-show-attributes struct_declarations.long_array" \
+ "\\^done,attr=\"noneditable\"" \
+ "is struct_declarations.long_array editable"
+
+# Test: c_variable-4.107
+# Desc: is struct_declarations.long_array[0] editable
+mi_gdb_test "-var-show-attributes struct_declarations.long_array.0" \
+ "\\^done,attr=\"editable\"" \
+ "is struct_declarations.long_array.0 editable"
+
+# Test: c_variable-4.108
+# Desc: is struct_declarations editable
+mi_gdb_test "-var-show-attributes struct_declarations" \
+ "\\^done,attr=\"noneditable\"" \
+ "is struct_declarations editable"
+
+mi_gdb_test "-var-delete weird" \
+ "\\^done,ndeleted=\"24\"" \
+ "delete var weird"
+
+##### #####
+# #
+# children and update tests #
+# #
+##### #####
+
+# Test: c_variable-5.1
+# Desc: check that nothing changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{\}" \
+ "update all vars. None changed"
+
+# Step over "struct_declarations.integer = 123;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"193\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.2
+# Desc: check that integer changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars struct_declarations.integer"
+
+# Step over:
+# weird->char_ptr = "hello";
+# bar = 2121;
+# foo = &bar;
+
+send_gdb "-exec-step 3\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"196\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.3
+# Desc: check that char_ptr changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars struct_declarations.char_ptr"
+
+# Step over "struct_declarations.int_ptr_ptr = &foo;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"197\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.4
+# Desc: check that int_ptr_ptr and children changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars int_ptr_ptr and children changed"
+
+# Step over "weird->long_array[0] = 1234;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"198\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.5
+# Desc: check that long_array[0] changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars struct_declarations.long_array.0 changed"
+
+# Step over "struct_declarations.long_array[1] = 2345;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"199\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.6
+# Desc: check that long_array[1] changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars struct_declarations.long_array.1 changed"
+
+# Step over "weird->long_array[2] = 3456;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"200\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.7
+# Desc: check that long_array[2] changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars struct_declarations.long_array.2 changed"
+
+# Step over:
+# struct_declarations.long_array[3] = 4567;
+# weird->long_array[4] = 5678;
+# struct_declarations.long_array[5] = 6789;
+# weird->long_array[6] = 7890;
+# struct_declarations.long_array[7] = 8901;
+# weird->long_array[8] = 9012;
+# struct_declarations.long_array[9] = 1234;
+send_gdb "-exec-step 7\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"208\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.8
+# Desc: check that long_array[3-9] changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars struct_declarations.long_array.3-9 changed"
+
+
+# Step over "weird->func_ptr = nothing;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"211\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.9
+# Desc: check that func_ptr changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars struct_declarations.func_ptr changed"
+
+# Delete all variables
+mi_gdb_test "-var-delete struct_declarations" \
+ "\\^done,ndeleted=\"65\"" \
+ "delete var struct_declarations"
+
+mi_gdb_test "-var-delete weird->int_ptr_ptr" \
+ "\\^done,ndeleted=\"3\"" \
+ "delete var weird->int_ptr_ptr"
+
+# Step over all lines:
+# ...
+# psnp = &snp0;
+send_gdb "-exec-step 43\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"254\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.10
+# Desc: create psnp->char_ptr
+mi_gdb_test "-var-create psnp->char_ptr * psnp->char_ptr" \
+ "\\^done,name=\"psnp->char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\\*\"" \
+ "create local variable psnp->char_ptr"
+
+# Test: c_variable-5.11
+# Desc: children of psnp->char_ptr
+mi_gdb_test "-var-list-children psnp->char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->char_ptr.\\*psnp->char_ptr\",exp=\"\\*psnp->char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\"\}\}" \
+ "get children of psnp->char_ptr"
+
+# Test: c_variable-5.12
+# Desc: number of children of psnp->char_ptr
+mi_gdb_test "-var-info-num-children psnp->char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->char_ptr"
+
+# Test: c_variable-5.13
+# Desc: children of *(psnp->char_ptr)
+mi_gdb_test "-var-list-children psnp->char_ptr.*psnp->char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",exp=\"\\*\\*psnp->char_ptr\",numchild=\"1\",type=\"char \\*\\*\"\}\}" \
+ "get children of psnp->char_ptr.*psnp->char_ptr"
+
+# Test: c_variable-5.14
+# Desc: number of children of *(psnp->char_ptr)
+mi_gdb_test "-var-info-num-children psnp->char_ptr.*psnp->char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->char_ptr.*psnp->char_ptr"
+
+# Test: c_variable-5.15
+# Desc: children of *(*(psnp->char_ptr))
+mi_gdb_test "-var-list-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",exp=\"\\*\\*\\*psnp->char_ptr\",numchild=\"1\",type=\"char \\*\"\}\}" \
+ "get children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr"
+
+# Test: c_variable-5.15B
+# Desc: children of *(*(*(psnp->char_ptr)))
+mi_gdb_test "-var-list-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",exp=\"\\*\\*\\*\\*psnp->char_ptr\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr"
+
+# Test: c_variable-5.16
+# Desc: number of children of *(*(psnp->char_ptr))
+mi_gdb_test "-var-info-num-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr"
+
+# Test: c_variable-5.17
+# Desc: children of *(*(*(psnp->char_ptr)))
+mi_gdb_test "-var-list-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",exp=\"\\*\\*\\*\\*psnp->char_ptr\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr"
+
+# Test: c_variable-5.18
+# Desc: number of children of *(*(*(psnp->char_ptr)))
+mi_gdb_test "-var-info-num-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr"
+
+# Test: c_variable-5.17B
+# Desc: children of *(*(*(*(psnp->char_ptr))))
+mi_gdb_test "-var-list-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr.****psnp->char_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr.****psnp->char_ptr"
+
+# Test: c_variable-5.18B
+# Desc: number of children of *(*(*(*(psnp->char_ptr))))
+mi_gdb_test "-var-info-num-children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr.****psnp->char_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr.****psnp->char_ptr"
+
+
+# Test: c_variable-5.19
+# Desc: create psnp->long_ptr
+mi_gdb_test "-var-create psnp->long_ptr * psnp->long_ptr" \
+ "\\^done,name=\"psnp->long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\\*\"" \
+ "create local variable psnp->long_ptr"
+
+# Test: c_variable-5.20
+# Desc: children of psnp->long_ptr
+mi_gdb_test "-var-list-children psnp->long_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->long_ptr.\\*psnp->long_ptr\",exp=\"\\*psnp->long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\"\}\}" \
+ "get children of psnp->long_ptr"
+
+# Test: c_variable-5.21
+# Desc: number of children of psnp->long_ptr
+mi_gdb_test "-var-info-num-children psnp->long_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->long_ptr"
+
+# Test: c_variable-5.22
+# Desc: children of *(psnp->long_ptr)
+mi_gdb_test "-var-list-children psnp->long_ptr.*psnp->long_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",exp=\"\\*\\*psnp->long_ptr\",numchild=\"1\",type=\"long int \\*\\*\"\}\}" \
+ "get children of psnp->long_ptr.*psnp->long_ptr"
+
+
+# Test: c_variable-5.23
+# Desc: number of children of *(psnp->long_ptr)
+mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->long_ptr.*psnp->long_ptr"
+
+# Test: c_variable-5.24
+# Desc: children of *(*(psnp->long_ptr))
+mi_gdb_test "-var-list-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",exp=\"\\*\\*\\*psnp->long_ptr\",numchild=\"1\",type=\"long int \\*\"\}\}" \
+ "get children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr"
+
+# Test: c_variable-5.25
+# Desc: number of children of *(*(psnp->long_ptr))
+mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr"
+
+# Test: c_variable-5.26
+# Desc: children of *(*(*(psnp->long_ptr)))
+mi_gdb_test "-var-list-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",exp=\"\\*\\*\\*\\*psnp->long_ptr\",numchild=\"0\",type=\"long int\"\}\}" \
+ "get children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr"
+
+# Test: c_variable-5.27
+# Desc: number of children of *(*(*(psnp->long_ptr)))
+mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr"
+
+# Test: c_variable-5.28
+# Desc: children of *(*(*(*(psnp->long_ptr))))
+mi_gdb_test "-var-list-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr"
+
+# Test: c_variable-5.29
+# Desc: number of children of *(*(*(*(psnp->long_ptr))))
+mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr"
+
+# Test: c_variable-5.30
+# Desc: create psnp->ptrs
+mi_gdb_test "-var-create psnp->ptrs * psnp->ptrs" \
+ "\\^done,name=\"psnp->ptrs\",numchild=\"3\",type=\"struct _struct_n_pointer \\*\\\[3\\\]\"" \
+ "create local variable psnp->ptrs"
+
+# Test: c_variable-5.31
+# Desc: children of psnp->ptrs
+mi_gdb_test "-var-list-children psnp->ptrs" \
+ "\\^done,numchild=\"3\",children=\{child=\{name=\"psnp->ptrs.0\",exp=\"0\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\},child=\{name=\"psnp->ptrs.1\",exp=\"1\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\},child=\{name=\"psnp->ptrs.2\",exp=\"2\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+ "get children of psnp->ptrs"
+
+# Test: c_variable-5.32
+# Desc: number of children of psnp->ptrs
+mi_gdb_test "-var-info-num-children psnp->ptrs" \
+ "\\^done,numchild=\"3\"" \
+ "get number of children of psnp->ptrs"
+
+# Test: c_variable-5.33
+# Desc: children of psnp->ptrs[0]
+mi_gdb_test "-var-list-children psnp->ptrs.0" \
+ "\\^done,numchild=\"4\",children=\{child=\{name=\"psnp->ptrs.0.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.long_ptr\",exp=\"long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.ptrs\",exp=\"ptrs\",numchild=\"3\",type=\"struct _struct_n_pointer \\*\\\[3\\\]\"\},child=\{name=\"psnp->ptrs.0.next\",exp=\"next\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+ "get children of psnp->ptrs.0"
+
+# Test: c_variable-5.34
+# Desc: number of children of psnp->ptrs[0]
+mi_gdb_test "-var-info-num-children psnp->ptrs.0" \
+ "\\^done,numchild=\"4\"" \
+ "get number of children of psnp->ptrs.0"
+
+# Test: c_variable-5.35
+# Desc: children of psnp->ptrs[0]->next
+mi_gdb_test "-var-list-children psnp->ptrs.0.next" \
+ "\\^done,numchild=\"4\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.next.long_ptr\",exp=\"long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.next.ptrs\",exp=\"ptrs\",numchild=\"3\",type=\"struct _struct_n_pointer \\*\\\[3\\\]\"\},child=\{name=\"psnp->ptrs.0.next.next\",exp=\"next\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+ "get children of psnp->ptrs.0.next"
+
+#} {char_ptr long_ptr ptrs next}
+
+# Test: c_variable-5.36
+# Desc: number of children of psnp->ptrs[0]->next
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next" \
+ "\\^done,numchild=\"4\"" \
+ "get number of children of psnp->ptrs.0.next"
+
+
+# Test: c_variable-5.37
+# Desc: children of psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",exp=\"\\*char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\"\}\}" \
+ "get children of psnp->ptrs.0.next.char_ptr"
+
+#gdbtk_test c_variable-5.37 {children of psnp->ptrs[0]->next->char_ptr} {
+# get_children psnp->ptrs.0.next.char_ptr
+#} {*char_ptr}
+
+# Test: c_variable-5.38
+# Desc: number of children of psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->ptrs.0.next.char_ptr"
+
+# Test: c_variable-5.39
+# Desc: children of *psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr.*char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",exp=\"\\*\\*char_ptr\",numchild=\"1\",type=\"char \\*\\*\"\}\}" \
+ "get children of psnp->ptrs.0.next.char_ptr.*char_ptr"
+
+# Test: c_variable-5.40
+# Desc: number of children of *psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr.*char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->ptrs.0.next.char_ptr.*char_ptr"
+
+# Test: c_variable-5.41
+# Desc: children of **psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",exp=\"\\*\\*\\*char_ptr\",numchild=\"1\",type=\"char \\*\"\}\}" \
+ "get children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr"
+
+# Test: c_variable-5.41B
+# Desc: children of ***psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",exp=\"\\*\\*\\*\\*char_ptr\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr"
+
+# Test: c_variable-5.42
+# Desc: number of children of **psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr"
+
+# Test: c_variable-5.43
+# Desc: children of ***psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr" \
+ "\\^done,numchild=\"1\",children=\{child=\{name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",exp=\"\\*\\*\\*\\*char_ptr\",numchild=\"0\",type=\"char\"\}\}" \
+ "get children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr"
+
+# Test: c_variable-5.44
+# Desc: number of children of ***psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr" \
+ "\\^done,numchild=\"1\"" \
+ "get number of children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr"
+
+# Test: c_variable-5.43B
+# Desc: children of ****psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr.****char_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr"
+
+# Test: c_variable-5.44B
+# Desc: number of children of ****psnp->ptrs[0]->next->char_ptr
+mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr.****char_ptr" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr"
+
+# Test: c_variable-5.45
+# Desc: children of psnp->ptrs[0]->next->next
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.next" \
+ "\\^done,numchild=\"4\",children=\{child=\{name=\"psnp->ptrs.0.next.next.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.next.next.long_ptr\",exp=\"long_ptr\",numchild=\"1\",type=\"long int \\*\\*\\*\\*\"\},child=\{name=\"psnp->ptrs.0.next.next.ptrs\",exp=\"ptrs\",numchild=\"3\",type=\"struct _struct_n_pointer \\*\\\[3\\\]\"\},child=\{name=\"psnp->ptrs.0.next.next.next\",exp=\"next\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+ "get children of psnp->ptrs.0.next.next"
+
+# Test: c_variable-5.46
+# Desc: children of psnp->ptrs[0]->next->next->ptrs
+mi_gdb_test "-var-list-children psnp->ptrs.0.next.next.ptrs" \
+ "\\^done,numchild=\"3\",children=\{child=\{name=\"psnp->ptrs.0.next.next.ptrs.0\",exp=\"0\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\},child=\{name=\"psnp->ptrs.0.next.next.ptrs.1\",exp=\"1\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\},child=\{name=\"psnp->ptrs.0.next.next.ptrs.2\",exp=\"2\",numchild=\"4\",type=\"struct _struct_n_pointer \\*\"\}\}" \
+ "get children of psnp->ptrs.0.next.next.ptrs"
+
+# Step over "snp0.char_ptr = &b3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"255\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.47
+# Desc: check that psnp->char_ptr (and [0].char_ptr) changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr.\\*\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars psnp->char_ptr (and 0.char_ptr) changed"
+
+# Step over "snp1.char_ptr = &c3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"256\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+
+# Test: c_variable-5.48
+# Desc: check that psnp->next->char_ptr (and [1].char_ptr) changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr.\\*\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars psnp->next->char_ptr (and 1.char_ptr) changed"
+
+
+# Step over "snp2.char_ptr = &a3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"257\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+
+# Test: c_variable-5.49
+# Desc: check that psnp->next->next->char_ptr (and [2].char_ptr) changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars psnp->next->next->char_ptr (and 2.char_ptr) changed"
+
+
+# Step over "snp0.long_ptr = &y3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"258\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+# Test: c_variable-5.50
+# Desc: check that psnp->long_ptr (and [0].long_ptr) changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars psnp->long_ptr (and 0.long_ptr) changed"
+
+
+# Step over "snp1.long_ptr = &x3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"259\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+
+# Test: c_variable-5.51
+# Desc: check that psnp->next->long_ptr (and [1].long_ptr) changed
+# Why does this have a FIXME?
+setup_xfail *-*-*
+mi_gdb_test "-var-update *" \
+ "FIXME\\^done,changelist=\{name=\"psnp->ptrs.0.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars psnp->next->long_ptr (and 1.long_ptr) changed"
+clear_xfail *-*-*
+
+# This command produces this error message:
+# &"warning: varobj_list: assertion failed - mycount <> 0\n"
+#
+
+# Step over "snp2.long_ptr = &z3;"
+send_gdb "-exec-step\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"260\"\}\r\n$mi_gdb_prompt$" {
+ pass "step at do_children_tests"
+ }
+ timeout {
+ fail "step at do_children_tests (timeout)"
+ }
+}
+
+
+# Test: c_variable-5.52
+# Desc: check that psnp->next->next->long_ptr (and [2].long_ptr) changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars psnp->next->next->long_ptr (and 2.long_ptr) changed"
+
+
+
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-var-cmd.exp b/gdb/testsuite/gdb.mi/mi0-var-cmd.exp
new file mode 100644
index 00000000000..d28186c8c6d
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-var-cmd.exp
@@ -0,0 +1,523 @@
+# Copyright (C) 1999, 2000, 2002 Cygnus Solutions
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can create, update, delete variables.
+#
+
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "var-cmd"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+
+##### #####
+# #
+# Variable Creation tests #
+# #
+##### #####
+
+# Test: c_variable-1.1
+# Desc: Create global variable
+
+mi_gdb_test "111-var-create global_simple * global_simple" \
+ "111\\^done,name=\"global_simple\",numchild=\"6\",type=\"simpleton\"" \
+ "create global variable"
+
+# Test: c_variable-1.2
+# Desc: Create non-existent variable
+
+mi_gdb_test "112-var-create bogus_unknown_variable * bogus_unknown_variable" \
+ "&\"mi_cmd_var_create: unable to create variable object\\\\n\".*112\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
+ "create non-existent variable"
+
+# Test: c_variable-1.3
+# Desc: Create out of scope variable
+
+mi_gdb_test "113-var-create argc * argc" \
+ "&\"mi_cmd_var_create: unable to create variable object\\\\n\".*113\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
+ "create out of scope variable"
+
+mi_gdb_test "200-break-insert do_locals_tests" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_locals_tests\",file=\".*var-cmd.c\",line=\"106\",times=\"0\"\}" \
+ "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_locals_tests\",args=\{\},file=\".*var-cmd.c\",line=\"106\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to do_locals_tests"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "run todo_locals_tests (2)"}
+ timeout {fail "run to do_locals_tests (timeout 2)"}
+}
+
+# Test: c_variable-1.4
+# Desc: create local variables
+
+mi_gdb_test "-var-create linteger * linteger" \
+ "\\^done,name=\"linteger\",numchild=\"0\",type=\"int\"" \
+ "create local variable linteger"
+
+mi_gdb_test "-var-create lpinteger * lpinteger" \
+ "\\^done,name=\"lpinteger\",numchild=\"1\",type=\"int \\*\"" \
+ "create local variable lpinteger"
+
+mi_gdb_test "-var-create lcharacter * lcharacter" \
+ "\\^done,name=\"lcharacter\",numchild=\"0\",type=\"char\"" \
+ "create local variablelcharacter "
+
+mi_gdb_test "-var-create lpcharacter * lpcharacter" \
+ "\\^done,name=\"lpcharacter\",numchild=\"1\",type=\"char \\*\"" \
+ "create local variable lpcharacter"
+
+mi_gdb_test "-var-create llong * llong" \
+ "\\^done,name=\"llong\",numchild=\"0\",type=\"long int\"" \
+ "create local variable llong"
+
+mi_gdb_test "-var-create lplong * lplong" \
+ "\\^done,name=\"lplong\",numchild=\"1\",type=\"long int \\*\"" \
+ "create local variable lplong"
+
+mi_gdb_test "-var-create lfloat * lfloat" \
+ "\\^done,name=\"lfloat\",numchild=\"0\",type=\"float\"" \
+ "create local variable lfloat"
+
+mi_gdb_test "-var-create lpfloat * lpfloat" \
+ "\\^done,name=\"lpfloat\",numchild=\"1\",type=\"float \\*\"" \
+ "create local variable lpfloat"
+
+mi_gdb_test "-var-create ldouble * ldouble" \
+ "\\^done,name=\"ldouble\",numchild=\"0\",type=\"double\"" \
+ "create local variable ldouble"
+
+mi_gdb_test "-var-create lpdouble * lpdouble" \
+ "\\^done,name=\"lpdouble\",numchild=\"1\",type=\"double \\*\"" \
+ "create local variable lpdouble"
+
+mi_gdb_test "-var-create lsimple * lsimple" \
+ "\\^done,name=\"lsimple\",numchild=\"6\",type=\"struct _simple_struct\"" \
+ "create local variable lsimple"
+
+mi_gdb_test "-var-create lpsimple * lpsimple" \
+ "\\^done,name=\"lpsimple\",numchild=\"6\",type=\"struct _simple_struct \\*\"" \
+ "create local variable lpsimple"
+
+mi_gdb_test "-var-create func * func" \
+ "\\^done,name=\"func\",numchild=\"0\",type=\"void \\(\\*\\)\\((void|)\\)\"" \
+ "create local variable func"
+
+# Test: c_variable-1.5
+# Desc: create lsimple.character
+mi_gdb_test "-var-create lsimple.character * lsimple.character" \
+ "\\^done,name=\"lsimple.character\",numchild=\"0\",type=\"char\"" \
+ "create lsimple.character"
+
+# Test: c_variable-1.6
+# Desc: create lpsimple->integer
+mi_gdb_test "-var-create lsimple->integer * lsimple->integer" \
+ "\\^done,name=\"lsimple->integer\",numchild=\"0\",type=\"int\"" \
+ "create lsimple->integer"
+
+# Test: c_variable-1.7
+# Desc: ceate lsimple.integer
+mi_gdb_test "-var-create lsimple.integer * lsimple.integer" \
+ "\\^done,name=\"lsimple.integer\",numchild=\"0\",type=\"int\"" \
+ "create lsimple->integer"
+
+
+# Test: c_variable-1.9
+# Desc: create type name
+# Type names (like int, long, etc..) are all proper expressions to gdb.
+# make sure variable code does not allow users to create variables, though.
+mi_gdb_test "-var-create int * int" \
+ "&\"Attempt to use a type name as an expression.mi_cmd_var_create: unable to create variable object\\\\n\".*\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
+ "create int"
+
+
+##### #####
+# #
+# Value changed tests #
+# #
+##### #####
+
+# Test: c_variable-2.1
+# Desc: check whether values changed at do_block_tests
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{\}" \
+ "update all vars"
+
+# Step over "linteger = 1234;"
+mi0_step_to "do_locals_tests" "" "var-cmd.c" "107" "step at do_locals_test"
+
+# Test: c_variable-2.2
+# Desc: check whether only linteger changed values
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: linteger changed"
+
+# Step over "lpinteger = &linteger;"
+mi0_step_to "do_locals_tests" "" "var-cmd.c" 108 "step at do_locals_tests (2)"
+
+# Test: c_variable-2.3
+# Desc: check whether only lpinteger changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: lpinteger changed"
+
+# Step over "lcharacter = 'a';"
+mi0_step_to "do_locals_tests" "" "var-cmd.c" "109" "step at do_locals_tests (3)"
+
+# Test: c_variable-2.4
+# Desc: check whether only lcharacter changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: lcharacter changed"
+
+# Step over "lpcharacter = &lcharacter;"
+mi0_step_to "do_locals_tests" "" "var-cmd.c" "110" "step at do_locals_tests (4)"
+
+# Test: c_variable-2.5
+# Desc: check whether only lpcharacter changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: lpcharacter changed"
+
+
+# Step over:
+# llong = 2121L;
+# lplong = &llong;
+# lfloat = 2.1;
+# lpfloat = &lfloat;
+# ldouble = 2.718281828459045;
+# lpdouble = &ldouble;
+# lsimple.integer = 1234;
+# lsimple.unsigned_integer = 255;
+# lsimple.character = 'a';
+
+mi0_run_to "exec-step 9" "end-stepping-range" "do_locals_tests" "" \
+ "var-cmd.c" "119" "" "step at do_locals_tests (5)"
+
+# Test: c_variable-2.6
+# Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer,
+# lsimple.unsigned_character lsimple.integer lsimple.character changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\",name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\",name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",name=\"lplong\",in_scope=\"true\",type_changed=\"false\",name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: many changed"
+
+# Step over:
+# lsimple.signed_character = 21;
+# lsimple.char_ptr = &lcharacter;
+# lpsimple = &lsimple;
+# func = nothing;
+
+mi0_run_to "exec-step 4" "end-stepping-range" "do_locals_tests" "" \
+ "var-cmd.c" "125" "" "step at do_locals_tests (6)"
+
+# Test: c_variable-2.7
+# Desc: check whether (lsimple.signed_character, lsimple.char_ptr) lpsimple, func changed
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"func\",in_scope=\"true\",type_changed=\"false\",name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: func and lpsimple changed"
+
+# Step over
+# linteger = 4321;
+# lcharacter = 'b';
+# llong = 1212L;
+# lfloat = 1.2;
+# ldouble = 5.498548281828172;
+# lsimple.integer = 255;
+# lsimple.unsigned_integer = 4321;
+# lsimple.character = 'b';
+
+mi0_run_to "exec-step 8" "end-stepping-range" "do_locals_tests" "" \
+ "var-cmd.c" "133" "" "step at do_locals_tests (7)"
+
+# Test: c_variable-2.8
+# Desc: check whether linteger, lcharacter, llong, lfoat, ldouble, lsimple.integer,
+# lpsimple.integer lsimple.character changed
+# Note: this test also checks that lpsimple->integer and lsimple.integer have
+# changed (they are the same)
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",name=\"llong\",in_scope=\"true\",type_changed=\"false\",name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: func and lpsimple changed"
+
+
+###
+#
+# Test assignment to variables. More tests on assignment are in other files.
+#
+###
+mi_gdb_test "-var-assign global_simple 0" \
+ "&\"mi_cmd_var_assign: Variable object is not editable\\\\n\".*\\^error,msg=\"mi_cmd_var_assign: Variable object is not editable\"" \
+ "assign to global_simple"
+
+mi_gdb_test "-var-assign linteger 3333" \
+ "\\^done,value=\"3333\"" \
+ "assign to linteger"
+
+mi_gdb_test "-var-evaluate-expression linteger" \
+ "\\^done,value=\"3333\"" \
+ "eval linteger"
+
+mi_gdb_test "-var-assign lpinteger \"&linteger + 3\"" \
+ "\\^done,value=\"$hex\"" \
+ "assign to lpinteger"
+
+mi_gdb_test "-var-evaluate-expression lpinteger" \
+ "\\^done,value=\"$hex\"" \
+ "eval lpinteger"
+
+# reset the values to the original ones so that the rest of the file doesn't suffer.
+
+mi_gdb_test "-var-assign linteger 4321" \
+ "\\^done,value=\"4321\"" \
+ "assign to linteger"
+
+mi_gdb_test "-var-assign lpinteger &linteger" \
+ "\\^done,value=\"$hex\"" \
+ "assign to lpinteger"
+
+mi_gdb_test "-var-assign lcharacter 'z'" \
+ "\\^done,value=\"122 'z'\"" \
+ "assign to lcharacter"
+
+mi_gdb_test "-var-evaluate-expression lcharacter" \
+ "\\^done,value=\"122 'z'\"" \
+ "eval lcharacter"
+
+mi_gdb_test "-var-assign llong 1313L" \
+ "\\^done,value=\"1313\"" \
+ "assign to llong"
+mi_gdb_test "-var-evaluate-expression llong" \
+ "\\^done,value=\"1313\"" \
+ "eval llong"
+mi_gdb_test "-var-assign llong 1212L" \
+ "\\^done,value=\"1212\"" \
+ "assign to llong"
+
+mi_gdb_test "-var-assign lplong &llong+4" \
+ "\\^done,value=\"$hex\"" \
+ "assign to lplong"
+mi_gdb_test "-var-evaluate-expression lplong" \
+ "\\^done,value=\"$hex\"" \
+ "eval lplong"
+mi_gdb_test "-var-assign lplong &llong" \
+ "\\^done,value=\"$hex\"" \
+ "assign to lplong"
+
+mi_gdb_test "-var-assign lfloat 3.4567" \
+ "\\^done,value=\"3.45.*\"" \
+ "assign to lfloat"
+mi_gdb_test "-var-evaluate-expression lfloat" \
+ "\\^done,value=\"3.45.*\"" \
+ "eval lfloat"
+mi_gdb_test "-var-assign lfloat 1.2345" \
+ "\\^done,value=\"1.23.*\"" \
+ "assign to lfloat"
+
+mi_gdb_test "-var-assign lpfloat &lfloat+4" \
+ "\\^done,value=\"$hex\"" \
+ "assign to lpfloat"
+
+mi_gdb_test "-var-assign ldouble 5.333318284590435" \
+ "\\^done,value=\"5.333318284590435\"" \
+ "assign to ldouble"
+
+mi_gdb_test "-var-assign func do_block_tests" \
+ "\\^done,value=\"$hex <do_block_tests>\"" \
+ "assign to func"
+
+mi_gdb_test "-var-assign lsimple.character 'd'" \
+ "\\^done,value=\"100 'd'\"" \
+ "assign to lsimple.character"
+
+mi_gdb_test "-var-assign lsimple->integer 222" \
+ "\\^done,value=\"222\"" \
+ "assign to lsimple->integer"
+
+mi_gdb_test "-var-assign lsimple.integer 333" \
+ "\\^done,value=\"333\"" \
+ "assign to lsimple.integer"
+
+######
+# End of assign tests
+#####
+
+mi_gdb_test "-break-insert subroutine1" \
+ "\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"subroutine1\",file=\".*var-cmd.c\",line=\"146\",times=\"0\"\}" \
+ "break-insert subroutine1"
+mi0_continue_to "2" "subroutine1" \
+ "\{name=\"i\",value=\"4321\"\},\{name=\"l\",value=\"$hex\"\}" \
+ "var-cmd.c" "146" "continue to subroutine1"
+
+# Test: c_variable-2.10
+# Desc: create variable for locals i,l in subroutine1
+mi_gdb_test "-var-create i * i" \
+ "\\^done,name=\"i\",numchild=\"0\",type=\"int\"" \
+ "create i"
+
+mi_gdb_test "-var-create l * l" \
+ "\\^done,name=\"l\",numchild=\"1\",type=\"long int \\*\"" \
+ "create l"
+
+# Test: c_variable-2.11
+# Desc: create do_locals_tests local in subroutine1
+mi_gdb_test "-var-create linteger * linteger" \
+ "&\"mi_cmd_var_create: unable to create variable object\\\\n\".*\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \
+ "create linteger"
+
+mi0_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \
+ "var-cmd.c" "147" "step at subroutine1"
+
+# Test: c_variable-2.12
+# Desc: change global_simple.integer
+# Note: This also tests whether we are reporting changes in structs properly.
+# gdb normally would say that global_simple has changed, but we
+# special case that, since it is not what a human expects to
+# see.
+
+setup_xfail *-*-*
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{FIXME: WHAT IS CORRECT HERE\}" \
+ "update all vars: changed FIXME"
+clear_xfail *-*-*
+
+mi0_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \
+ "var-cmd.c" "148" "step at subroutine1 (2)"
+
+# Test: c_variable-2.13
+# Desc: change subroutine1 local i
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"i\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: i changed"
+
+mi0_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \
+ "var-cmd.c" "149" "step at subroutine1 (3)"
+
+# Test: c_variable-2.14
+# Desc: change do_locals_tests local llong
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}" \
+ "update all vars: llong changed"
+
+mi0_next_to "do_locals_tests" "" "var-cmd.c" "136" "next out of subroutine1"
+
+# Test: c_variable-2.15
+# Desc: check for out of scope subroutine1 locals
+mi_gdb_test "-var-update *" \
+ "\\^done,changelist=\{name=\"l\",in_scope=\"false\",name=\"i\",in_scope=\"false\"\}" \
+ "update all vars: all now out of scope"
+
+# Done with locals/globals tests. Erase all variables
+#delete_all_variables
+mi_gdb_test "-var-delete global_simple" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var"
+
+mi_gdb_test "-var-delete linteger" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var linteger"
+
+mi_gdb_test "-var-delete lpinteger" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lpinteger"
+
+mi_gdb_test "-var-delete lcharacter" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lcharacter"
+
+mi_gdb_test "-var-delete lpcharacter" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lpcharacter"
+
+mi_gdb_test "-var-delete llong" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var llong"
+
+mi_gdb_test "-var-delete lplong" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lplong"
+
+mi_gdb_test "-var-delete lfloat" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lfloat"
+
+mi_gdb_test "-var-delete lpfloat" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lpfloat"
+
+mi_gdb_test "-var-delete ldouble" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var ldouble"
+
+mi_gdb_test "-var-delete lpdouble" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lpdouble"
+
+mi_gdb_test "-var-delete lsimple" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lsimple"
+
+mi_gdb_test "-var-delete lpsimple" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lpsimple"
+
+mi_gdb_test "-var-delete func" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var func"
+
+mi_gdb_test "-var-delete lsimple.character" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lsimple.character"
+
+mi_gdb_test "-var-delete lsimple->integer" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lsimple->integer"
+
+mi_gdb_test "-var-delete lsimple.integer" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var lsimple.integer"
+
+mi_gdb_test "-var-delete i" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var i"
+
+mi_gdb_test "-var-delete l" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var l"
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-var-display.exp b/gdb/testsuite/gdb.mi/mi0-var-display.exp
new file mode 100644
index 00000000000..a0330ef788d
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-var-display.exp
@@ -0,0 +1,627 @@
+# Copyright (C) 1999 2000 Cygnus Solutions
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can create, update, delete variables.
+#
+
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "var-cmd"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+mi_gdb_test "200-break-insert 260" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_children_tests\",file=\".*var-cmd.c\",line=\"260\",times=\"0\"\}" \
+ "break-insert operation"
+
+mi_run_cmd
+# The running part has been checked already by mi_run_cmd
+gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\{\},file=\".*var-cmd.c\",line=\"260\"\}\r\n$mi_gdb_prompt$" {
+ pass "run to do_children_tests"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "run to do_children_tests (2)"}
+ timeout {fail "run to do_children_tests (timeout 2)"}
+}
+
+##### #####
+# #
+# Display tests #
+# #
+##### #####
+
+# Test: c_variable-6.1
+# Desc: create variable bar
+mi_gdb_test "-var-create bar * bar" \
+ "\\^done,name=\"bar\",numchild=\"0\",type=\"int\"" \
+ "create local variable bar"
+
+# Test: c_variable-6.2
+# Desc: type of variable bar
+mi_gdb_test "-var-info-type bar" \
+ "\\^done,type=\"int\"" \
+ "info type variable bar"
+
+# Test: c_variable-6.3
+# Desc: format of variable bar
+mi_gdb_test "-var-show-format bar" \
+ "\\^done,format=\"natural\"" \
+ "show format variable bar"
+
+# Test: c_variable-6.4
+# Desc: value of variable bar
+mi_gdb_test "-var-evaluate-expression bar" \
+ "\\^done,value=\"2121\"" \
+ "eval variable bar"
+
+# Test: c_variable-6.5
+# Desc: change format of bar to hex
+mi_gdb_test "-var-set-format bar hexadecimal" \
+ "\\^done,format=\"hexadecimal\"" \
+ "set format variable bar"
+
+# Test: c_variable-6.6
+# Desc: value of bar with new format
+mi_gdb_test "-var-evaluate-expression bar" \
+ "\\^done,value=\"0x849\"" \
+ "eval variable bar with new format"
+
+# Test: c_variable-6.7
+# Desc: change value of bar
+mi_gdb_test "-var-assign bar 3" \
+ "\\^done,value=\"0x3\"" \
+ "assing to variable bar"
+
+mi_gdb_test "-var-set-format bar decimal" \
+ "\\^done,format=\"decimal\"" \
+ "set format variable bar"
+
+mi_gdb_test "-var-evaluate-expression bar" \
+ "\\^done,value=\"3\"" \
+ "eval variable bar with new value"
+
+mi_gdb_test "-var-delete bar" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var bar"
+
+# Test: c_variable-6.11
+# Desc: create variable foo
+mi_gdb_test "-var-create foo * foo" \
+ "\\^done,name=\"foo\",numchild=\"1\",type=\"int \\*\"" \
+ "create local variable foo"
+
+# Test: c_variable-6.12
+# Desc: type of variable foo
+mi_gdb_test "-var-info-type foo" \
+ "\\^done,type=\"int \\*\"" \
+ "info type variable foo"
+
+# Test: c_variable-6.13
+# Desc: format of variable foo
+mi_gdb_test "-var-show-format foo" \
+ "\\^done,format=\"natural\"" \
+ "show format variable foo"
+
+# Test: c_variable-6.14
+# Desc: value of variable foo
+mi_gdb_test "-var-evaluate-expression foo" \
+ "\\^done,value=\"$hex\"" \
+ "eval variable foo"
+
+# Test: c_variable-6.15
+# Desc: change format of var to octal
+mi_gdb_test "-var-set-format foo octal" \
+ "\\^done,format=\"octal\"" \
+ "set format variable foo"
+
+mi_gdb_test "-var-show-format foo" \
+ "\\^done,format=\"octal\"" \
+ "show format variable foo"
+
+# Test: c_variable-6.16
+# Desc: value of foo with new format
+mi_gdb_test "-var-evaluate-expression foo" \
+ "\\^done,value=\"\[0-7\]+\"" \
+ "eval variable foo"
+
+# Test: c_variable-6.17
+# Desc: change value of foo
+mi_gdb_test "-var-assign foo 3" \
+ "\\^done,value=\"03\"" \
+ "assing to variable foo"
+
+mi_gdb_test "-var-set-format foo decimal" \
+ "\\^done,format=\"decimal\"" \
+ "set format variable foo"
+
+# Test: c_variable-6.18
+# Desc: check new value of foo
+mi_gdb_test "-var-evaluate-expression foo" \
+ "\\^done,value=\"3\"" \
+ "eval variable foo"
+
+mi_gdb_test "-var-delete foo" \
+ "\\^done,ndeleted=\"1\"" \
+ "delete var foo"
+
+# Test: c_variable-6.21
+# Desc: create variable weird and children
+mi_gdb_test "-var-create weird * weird" \
+ "\\^done,name=\"weird\",numchild=\"11\",type=\"weird_struct \\*\"" \
+ "create local variable weird"
+
+mi_gdb_test "-var-list-children weird" \
+ "\\^done,numchild=\"11\",children=\{child=\{name=\"weird.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"weird.character\",exp=\"character\",numchild=\"0\",type=\"char\"\},child={name=\"weird.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\"\},child=\{name=\"weird.long_int\",exp=\"long_int\",numchild=\"0\",type=\"long int\"\},child=\{name=\"weird.int_ptr_ptr\",exp=\"int_ptr_ptr\",numchild=\"1\",type=\"int \\*\\*\"\},child=\{name=\"weird.long_array\",exp=\"long_array\",numchild=\"10\",type=\"long int \\\[10\\\]\"\},child=\{name=\"weird.func_ptr\",exp=\"func_ptr\",numchild=\"0\",type=\"void \\(\\*\\)\\(\\)\"\},child=\{name=\"weird.func_ptr_struct\",exp=\"func_ptr_struct\",numchild=\"0\",type=\"struct _struct_decl \\(\\*\\)\\(\\)\"\},child=\{name=\"weird.func_ptr_ptr\",exp=\"func_ptr_ptr\",numchild=\"0\",type=\"struct _struct_decl \\*\\(\\*\\)\\(\\)\"\},child=\{name=\"weird.u1\",exp=\"u1\",numchild=\"4\",type=\"union \{\\.\\.\\.\}\"\},child=\{name=\"weird.s2\",exp=\"s2\",numchild=\"4\",type=\"struct \{\\.\\.\\.\}\"\}\}" \
+ "get children local variable weird"
+
+
+# Test: c_variable-6.23
+# Desc: change format of weird.func_ptr and weird.func_ptr_ptr
+mi_gdb_test "-var-set-format weird.func_ptr hexadecimal" \
+ "\\^done,format=\"hexadecimal\"" \
+ "set format variable weird.func_ptr"
+
+mi_gdb_test "-var-show-format weird.func_ptr" \
+ "\\^done,format=\"hexadecimal\"" \
+ "show format variable weird.func_ptr"
+
+mi_gdb_test "-var-set-format weird.func_ptr_ptr hexadecimal" \
+ "\\^done,format=\"hexadecimal\"" \
+ "set format variable weird.func_ptr_ptr"
+
+mi_gdb_test "-var-show-format weird.func_ptr_ptr" \
+ "\\^done,format=\"hexadecimal\"" \
+ "show format variable weird.func_ptr_ptr"
+
+# Test: c_variable-6.24
+# Desc: format of weird and children
+mi_gdb_test "-var-set-format weird natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird"
+
+mi_gdb_test "-var-set-format weird.integer natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.integer"
+
+mi_gdb_test "-var-set-format weird.character natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.character"
+
+mi_gdb_test "-var-set-format weird.char_ptr natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.char_ptr"
+
+mi_gdb_test "-var-set-format weird.long_int natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.long_int"
+
+mi_gdb_test "-var-set-format weird.int_ptr_ptr natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.int_ptr_ptr"
+
+mi_gdb_test "-var-set-format weird.long_array natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.long_array"
+
+mi_gdb_test "-var-set-format weird.func_ptr hexadecimal" \
+ "\\^done,format=\"hexadecimal\"" \
+ "set format variable weird.func_ptr"
+
+mi_gdb_test "-var-set-format weird.func_ptr_struct hexadecimal" \
+ "\\^done,format=\"hexadecimal\"" \
+ "set format variable weird.func_ptr_struct"
+
+mi_gdb_test "-var-set-format weird.func_ptr_ptr natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.func_ptr_ptr"
+
+mi_gdb_test "-var-set-format weird.u1 natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.u1"
+
+mi_gdb_test "-var-set-format weird.s2 natural" \
+ "\\^done,format=\"natural\"" \
+ "set format variable weird.s2"
+
+# Test: c_variable-6.25
+# Desc: value of weird and children
+#gdbtk_test c_variable-6.25 {value of weird and children} {
+# set values {}
+# foreach v [lsort [array names var]] f [list x "" "" x x x x d d d d d] {
+# lappend values [value $v $f]
+# }
+
+# set values
+#} {ok ok ok ok ok ok ok ok weird.long_array ok weird.s2 weird.u1}
+
+# Test: c_variable-6.26
+# Desc: change format of weird and children to octal
+#gdbtk_test c_variable-6.26 {change format of weird and children to octal} {
+# set formats {}
+# foreach v [lsort [array names var]] {
+# $var($v) format octal
+# lappend formats [$var($v) format]
+# }
+
+# set formats
+#} {octal octal octal octal octal octal octal octal octal octal octal octal}
+
+# Test: c_variable-6.27
+# Desc: value of weird and children with new format
+#gdbtk_test c_variable-6.27 {value of foo with new format} {
+# set values {}
+# foreach v [lsort [array names var]] {
+# lappend values [value $v o]
+# }
+
+# set values
+#} {ok ok ok ok ok ok ok ok weird.long_array ok weird.s2 weird.u1}
+
+# Test: c_variable-6.30
+# Desc: create more children of weird
+#gdbtk_test c_variable-6.30 {create more children of weird} {
+# foreach v [array names var] {
+# get_children $v
+# }
+
+# # Do it twice to get more children
+# foreach v [array names var] {
+# get_children $v
+# }
+
+# lsort [array names var]
+#} {weird weird.char_ptr weird.character weird.func_ptr weird.func_ptr_ptr weird.func_ptr_struct weird.int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr weird.integer weird.long_array weird.long_array.0 weird.long_array.1 weird.long_array.2 weird.long_array.3 weird.long_array.4 weird.long_array.5 weird.long_array.6 weird.long_array.7 weird.long_array.8 weird.long_array.9 weird.long_int weird.s2 weird.s2.g weird.s2.h weird.s2.i weird.s2.i.0 weird.s2.i.1 weird.s2.i.2 weird.s2.i.3 weird.s2.i.4 weird.s2.i.5 weird.s2.i.6 weird.s2.i.7 weird.s2.i.8 weird.s2.i.9 weird.s2.u2 weird.s2.u2.f weird.s2.u2.u1s1 weird.s2.u2.u1s2 weird.u1 weird.u1.a weird.u1.b weird.u1.c weird.u1.d}
+
+# Test: c_variable-6.31
+# Desc: check that all children of weird change
+# Ok, obviously things like weird.s2 and weird.u1 will not change!
+#gdbtk_test *c_variable-6.31 {check that all children of weird change (ops, we are now reporting array names as changed in this case - seems harmless though)} {
+# $var(weird) value 0x2121
+# check_update
+#} {{weird.integer weird.character weird.char_ptr weird.long_int weird.int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr weird.long_array.0 weird.long_array.1 weird.long_array.2 weird.long_array.3 weird.long_array.4 weird.long_array.5 weird.long_array.6 weird.long_array.7 weird.long_array.8 weird.long_array.9 weird.func_ptr weird.func_ptr_struct weird.func_ptr_ptr weird.u1.a weird.u1.b weird.u1.c weird.u1.d weird.s2.u2.f weird.s2.g weird.s2.h weird.s2.i.0 weird.s2.i.1 weird.s2.i.2 weird.s2.i.3 weird.s2.i.4 weird.s2.i.5 weird.s2.i.6 weird.s2.i.7 weird.s2.i.8 weird.s2.i.9} {weird.s2.i weird.s2.u2 weird weird.s2.u2.u1s1 weird.s2.u2.u1s2 weird.s2 weird.long_array weird.u1} {}}
+
+mi_gdb_test "-var-delete weird" \
+ "\\^done,ndeleted=\"12\"" \
+ "delete var weird"
+
+
+##### #####
+# #
+# Special Display Tests #
+# #
+##### #####
+
+# Stop in "do_special_tests"
+mi_gdb_test "200-break-insert do_special_tests" \
+ "200\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_special_tests\",file=\".*var-cmd.c\",line=\"282\",times=\"0\"\}" \
+ "break-insert operation"
+
+send_gdb "-exec-continue\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"2\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_special_tests\",args=\{\},file=\".*var-cmd.c\",line=\"282\"\}\r\n$mi_gdb_prompt$" {
+ pass "continue to do_special_tests"
+ }
+ timeout {
+ fail "continue to do_special_tests (timeout)"
+ }
+}
+
+# Test: c_variable-7.10
+# Desc: create union u
+mi_gdb_test "-var-create u * u" \
+ "\\^done,name=\"u\",numchild=\"2\",type=\"union named_union\"" \
+ "create local variable u"
+
+# Test: c_variable-7.11
+# Desc: value of u
+mi_gdb_test "-var-evaluate-expression u" \
+ "\\^done,value=\"\{\\.\\.\\.\}\"" \
+ "eval variable u"
+
+# Test: c_variable-7.12
+# Desc: type of u
+mi_gdb_test "-var-info-type u" \
+ "\\^done,type=\"union named_union\"" \
+ "info type variable u"
+
+# Test: c_variable-7.13
+# Desc: is u editable
+mi_gdb_test "-var-show-attributes u" \
+ "\\^done,attr=\"noneditable\"" \
+ "is u editable"
+
+# Test: c_variable-7.14
+# Desc: number of children of u
+mi_gdb_test "-var-info-num-children u" \
+ "\\^done,numchild=\"2\"" \
+ "get number of children of u"
+
+# Test: c_variable-7.15
+# Desc: children of u
+mi_gdb_test "-var-list-children u" \
+ "\\^done,numchild=\"2\",children=\{child=\{name=\"u.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"u.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\"\}\}" \
+ "get children of u"
+
+# Test: c_variable-7.20
+# Desc: create anonu
+mi_gdb_test "-var-create anonu * anonu" \
+ "\\^done,name=\"anonu\",numchild=\"3\",type=\"union \{\\.\\.\\.\}\"" \
+ "create local variable anonu"
+
+# Test: c_variable-7.21
+# Desc: value of anonu
+mi_gdb_test "-var-evaluate-expression anonu" \
+ "\\^done,value=\"\{\\.\\.\\.\}\"" \
+ "eval variable anonu"
+
+# Test: c_variable-7.22
+# Desc: type of anonu
+mi_gdb_test "-var-info-type anonu" \
+ "\\^done,type=\"union \{\\.\\.\\.\}\"" \
+ "info type variable anonu"
+
+# Test: c_variable-7.23
+# Desc: is anonu editable
+mi_gdb_test "-var-show-attributes anonu" \
+ "\\^done,attr=\"noneditable\"" \
+ "is anonu editable"
+
+# Test: c_variable-7.24
+# Desc: number of children of anonu
+mi_gdb_test "-var-info-num-children anonu" \
+ "\\^done,numchild=\"3\"" \
+ "get number of children of anonu"
+
+# Test: c_variable-7.25
+# Desc: children of anonu
+mi_gdb_test "-var-list-children anonu" \
+ "\\^done,numchild=\"3\",children=\{child=\{name=\"anonu.a\",exp=\"a\",numchild=\"0\",type=\"int\"\},child=\{name=\"anonu.b\",exp=\"b\",numchild=\"0\",type=\"char\"\},child=\{name=\"anonu.c\",exp=\"c\",numchild=\"0\",type=\"long int\"\}\}" \
+ "get children of anonu"
+
+# Test: c_variable-7.30
+# Desc: create struct s
+mi_gdb_test "-var-create s * s" \
+ "\\^done,name=\"s\",numchild=\"6\",type=\"struct _simple_struct\"" \
+ "create local variable s"
+
+
+# Test: c_variable-7.31
+# Desc: value of s
+mi_gdb_test "-var-evaluate-expression s" \
+ "\\^done,value=\"\{\\.\\.\\.\}\"" \
+ "eval variable s"
+
+# Test: c_variable-7.32
+# Desc: type of s
+mi_gdb_test "-var-info-type s" \
+ "\\^done,type=\"struct _simple_struct\"" \
+ "info type variable s"
+
+# Test: c_variable-7.33
+# Desc: is s editable
+mi_gdb_test "-var-show-attributes s" \
+ "\\^done,attr=\"noneditable\"" \
+ "is s editable"
+
+# Test: c_variable-7.34
+# Desc: number of children of s
+mi_gdb_test "-var-info-num-children s" \
+ "\\^done,numchild=\"6\"" \
+ "get number of children of s"
+
+# Test: c_variable-7.35
+# Desc: children of s
+mi_gdb_test "-var-list-children s" \
+ "\\^done,numchild=\"6\",children=\{child=\{name=\"s.integer\",exp=\"integer\",numchild=\"0\",type=\"int\"\},child=\{name=\"s.unsigned_integer\",exp=\"unsigned_integer\",numchild=\"0\",type=\"unsigned int\"\},child=\{name=\"s.character\",exp=\"character\",numchild=\"0\",type=\"char\"\},child=\{name=\"s.signed_character\",exp=\"signed_character\",numchild=\"0\",type=\"signed char\"\},child=\{name=\"s.char_ptr\",exp=\"char_ptr\",numchild=\"1\",type=\"char \\*\"\},child=\{name=\"s.array_of_10\",exp=\"array_of_10\",numchild=\"10\",type=\"int \\\[10\\\]\"\}\}" \
+ "get children of s"
+#} {integer unsigned_integer character signed_character char_ptr array_of_10}
+
+# Test: c_variable-7.40
+# Desc: create anons
+mi_gdb_test "-var-create anons * anons" \
+ "\\^done,name=\"anons\",numchild=\"3\",type=\"struct \{\\.\\.\\.\}\"" \
+ "create local variable anons"
+
+# Test: c_variable-7.41
+# Desc: value of anons
+mi_gdb_test "-var-evaluate-expression anons" \
+ "\\^done,value=\"\{\\.\\.\\.\}\"" \
+ "eval variable anons"
+
+# Test: c_variable-7.42
+# Desc: type of anons
+mi_gdb_test "-var-info-type anons" \
+ "\\^done,type=\"struct \{\\.\\.\\.\}\"" \
+ "info type variable anons"
+
+# Test: c_variable-7.43
+# Desc: is anons editable
+mi_gdb_test "-var-show-attributes anons" \
+ "\\^done,attr=\"noneditable\"" \
+ "is anons editable"
+
+# Test: c_variable-7.44
+# Desc: number of children of anons
+mi_gdb_test "-var-info-num-children anons" \
+ "\\^done,numchild=\"3\"" \
+ "get number of children of anons"
+
+# Test: c_variable-7.45
+# Desc: children of anons
+mi_gdb_test "-var-list-children anons" \
+ "\\^done,numchild=\"3\",children=\{child=\{name=\"anons.a\",exp=\"a\",numchild=\"0\",type=\"int\"\},child=\{name=\"anons.b\",exp=\"b\",numchild=\"0\",type=\"char\"\},child=\{name=\"anons.c\",exp=\"c\",numchild=\"0\",type=\"long int\"\}\}" \
+ "get children of anons"
+
+
+# Test: c_variable-7.50
+# Desc: create enum e
+mi_gdb_test "-var-create e * e" \
+ "\\^done,name=\"e\",numchild=\"0\",type=\"enum foo\"" \
+ "create local variable e"
+
+setup_xfail "*-*-*"
+# Test: c_variable-7.51
+# Desc: value of e
+mi_gdb_test "-var-evaluate-expression e" \
+ "\\^done,value=\"FIXME\"" \
+ "eval variable e"
+clear_xfail "*-*-*"
+
+# Test: c_variable-7.52
+# Desc: type of e
+mi_gdb_test "-var-info-type e" \
+ "\\^done,type=\"enum foo\"" \
+ "info type variable e"
+
+# Test: c_variable-7.53
+# Desc: is e editable
+mi_gdb_test "-var-show-attributes e" \
+ "\\^done,attr=\"editable\"" \
+ "is e editable"
+
+# Test: c_variable-7.54
+# Desc: number of children of e
+mi_gdb_test "-var-info-num-children e" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of e"
+
+# Test: c_variable-7.55
+# Desc: children of e
+mi_gdb_test "-var-list-children e" \
+ "\\^done,numchild=\"0\"" \
+ "get children of e"
+
+# Test: c_variable-7.60
+# Desc: create anone
+mi_gdb_test "-var-create anone * anone" \
+ "\\^done,name=\"anone\",numchild=\"0\",type=\"enum \{\\.\\.\\.\}\"" \
+ "create local variable anone"
+
+setup_xfail "*-*-*"
+# Test: c_variable-7.61
+# Desc: value of anone
+mi_gdb_test "-var-evaluate-expression anone" \
+ "\\^done,value=\"A\"" \
+ "eval variable anone"
+clear_xfail "*-*-*"
+
+
+# Test: c_variable-7.70
+# Desc: create anone
+mi_gdb_test "-var-create anone * anone" \
+ "&\"Duplicate variable object name\\\\n\".*\\^error,msg=\"Duplicate variable object name\"" \
+ "create duplicate local variable anone"
+
+
+# Test: c_variable-7.72
+# Desc: type of anone
+mi_gdb_test "-var-info-type anone" \
+ "\\^done,type=\"enum \{\\.\\.\\.\}\"" \
+ "info type variable anone"
+
+
+# Test: c_variable-7.73
+# Desc: is anone editable
+mi_gdb_test "-var-show-attributes anone" \
+ "\\^done,attr=\"editable\"" \
+ "is anone editable"
+
+# Test: c_variable-7.74
+# Desc: number of children of anone
+mi_gdb_test "-var-info-num-children anone" \
+ "\\^done,numchild=\"0\"" \
+ "get number of children of anone"
+
+# Test: c_variable-7.75
+# Desc: children of anone
+mi_gdb_test "-var-list-children anone" \
+ "\\^done,numchild=\"0\"" \
+ "get children of anone"
+
+
+# Record fp
+
+send_gdb "p/x \$fp\n"
+gdb_expect {
+ -re ".*($hex).*\\^done\r\n$mi_gdb_prompt$" {
+ pass "print FP register"
+ set fp $expect_out(1,string)
+ }
+# -re ".*" { fail "print FP register"}
+ timeout { fail "print FP register (timeout)"}
+}
+
+mi_gdb_test "200-break-insert incr_a" \
+ "200\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"incr_a\",file=\".*var-cmd.c\",line=\"85\",times=\"0\"\}" \
+ "break-insert operation"
+send_gdb "-exec-continue\n"
+gdb_expect {
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"3\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"incr_a\",args=\{\{name=\"a\",value=\"2\.*\"\}\},file=\".*var-cmd.c\",line=\"85\"\}\r\n$mi_gdb_prompt$" {
+ pass "continue to incr_a"
+ }
+ -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"3\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"incr_a\",args=\{\{name=\"a\",value=\".*\"\}\},file=\".*var-cmd.c\",line=\"8\[345\]\"\}\r\n$mi_gdb_prompt$" {
+ fail "continue to incr_a (compiler debug info incorrect)"
+ }
+ -re "\\^running\r\n${mi_gdb_prompt}.*\r\n$mi_gdb_prompt$" {
+ fail "continue to incr_a (unknown output)"
+ }
+ timeout {
+ fail "continue to incr_a (timeout)"
+ }
+}
+
+# Test: c_variable-7.81
+# Desc: Create variables in different scopes
+mi_gdb_test "-var-create a1 * a" \
+ "\\^done,name=\"a1\",numchild=\"0\",type=\"char\"" \
+ "create local variable a1"
+
+mi_gdb_test "-var-create a2 $fp a" \
+ "\\^done,name=\"a2\",numchild=\"0\",type=\"int\"" \
+ "create variable a2 in different scope"
+
+#gdbtk_test c_variable-7.81 {create variables in different scopes} {
+# set a1 [gdb_variable create -expr a]
+# set a2 [gdb_variable create -expr a -frame $fp]
+
+# set vals {}
+# lappend vals [$a1 value]
+# lappend vals [$a2 value]
+# set vals
+#} {2 1}
+
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/mi0-watch.exp b/gdb/testsuite/gdb.mi/mi0-watch.exp
new file mode 100644
index 00000000000..8932cd9754c
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi0-watch.exp
@@ -0,0 +1,191 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# Test essential Machine interface (MI) operations
+#
+# Verify that, using the MI, we can run a simple program and perform basic
+# debugging activities like: insert breakpoints, run the program,
+# step, next, continue until it ends and, last but not least, quit.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi0"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+set testfile "basics"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+proc test_watchpoint_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert a watchpoint and list
+ # Tests:
+ # -break-watch C
+ # -break-list
+
+ mi_gdb_test "111-break-watch C" \
+ "111\\^done,wpt=\{number=\"2\",exp=\"C\"\}" \
+ "break-watch operation"
+
+ mi_gdb_test "222-break-list" \
+ "222\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"1\"\},bkpt=\{number=\"2\",type=\".*watchpoint\",disp=\"keep\",enabled=\"y\",addr=\"\",what=\"C\",times=\"0\"\}\}" \
+ "list of watchpoints"
+
+}
+
+# UNUSED at the time
+proc test_awatch_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert an access watchpoint and list it
+ # Tests:
+ # -break-watch -a A
+ # -break-list
+
+ mi_gdb_test "333-break-watch -a A" \
+ "333\\^done,bkpt=\{number=\"1\",addr=\"$hex\",file=\".*basics.c\",line=\"32\"\}" \
+ "break-watch -a operation"
+
+ mi_gdb_test "444-break-list" \
+ "444\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"3\",type=\"watchpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
+ "list of watchpoints awatch"
+
+ mi_gdb_test "777-break-delete 3" \
+ "777\\^done" \
+ "delete access watchpoint"
+}
+
+# UNUSED at the time
+proc test_rwatch_creation_and_listing {} {
+ global mi_gdb_prompt
+ global srcfile
+ global hex
+
+ # Insert a read watchpoint and list it.
+ # Tests:
+ # -break-insert -r B
+ # -break-list
+
+ mi_gdb_test "200-break-watch -r C" \
+ "200\\^done,bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \
+ "break-insert -r operation"
+
+ mi_gdb_test "300-break-list" \
+ "300\\^done,BreakpointTable=\{hdr=\{.*\},bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\},.*\}\}" \
+ "list of breakpoints"
+
+ mi_gdb_test "177-break-delete 4" \
+ "177\\^done" \
+ "delete read watchpoint"
+}
+
+proc test_running_the_program {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Run the program without args, then specify srgs and rerun the program
+ # Tests:
+ # -exec-run
+
+ mi_gdb_test "300-break-insert callee4" \
+ "300\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\",times=\"0\"\}" \
+ "insert breakpoint at callee4"
+
+ # mi_gdb_test cannot be used for asynchronous commands because there are
+ # two prompts involved and this can lead to a race condition.
+ # The following is equivalent to a send_gdb "000-exec-run\n"
+ mi_run_cmd
+ # The running part has been checked already by mi_run_cmd
+ gdb_expect {
+ -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"8\"\}\r\n$mi_gdb_prompt$" \
+ { pass "run to callee4" }
+ -re ".*$mi_gdb_prompt$" {fail "run to callee4 (2)"}
+ timeout {fail "run to callee4 (timeout 2)"}
+ }
+}
+
+proc test_watchpoint_triggering {} {
+ global mi_gdb_prompt
+ global hex
+
+ # Continue execution until the watchpoint is reached, continue again,
+ # to see the watchpoint go out of scope.
+ # Does:
+ # -exec-continue (Here wp triggers)
+ # -exec-continue (Here wp goes out of scope)
+
+ send_gdb "222-exec-continue\n"
+ gdb_expect {
+ -re "222\\^running\r\n$mi_gdb_prompt" {
+ gdb_expect {
+ -re "222\\*stopped,reason=\"watchpoint-trigger\",wpt=\{number=\"2\",exp=\"C\"\},value=\{old=\".*\",new=\"3\"\},thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee4\",args=\{\},file=\".*basics.c\",line=\"13\"\}\r\n$mi_gdb_prompt$" {
+ pass "watchpoint trigger"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "watchpoint trigger (2)"}
+ timeout {fail "watchpoint trigger (timeout 2)"}
+ }
+ }
+ -re ".*$mi_gdb_prompt$" {fail "watchpoint trigger (1)"}
+ timeout {fail "watchpoint trigger (timeout 1)"}
+ }
+
+ send_gdb "223-exec-continue\n"
+ gdb_expect {
+ -re "223\\^running\r\n$mi_gdb_prompt" {
+ gdb_expect {
+ -re "\[\r\n\]*223\\*stopped,reason=\"watchpoint-scope\",wpnum=\"2\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"callee3\",args=\{.*\},file=\".*basics.c\",line=\"18\"\}\r\n$mi_gdb_prompt$" {
+ pass "wp out of scope"
+ }
+ -re ".*$mi_gdb_prompt$" {fail "wp out of scope (2)"}
+ timeout {fail "wp out of scope (timeout 2)"}
+ }
+ }
+ -re ".*$mi_gdb_prompt$" {fail "wp out of scope (1)"}
+ timeout {fail "wp out of scope (timeout 1)"}
+ }
+}
+
+test_running_the_program
+test_watchpoint_creation_and_listing
+#test_rwatch_creation_and_listing
+#test_awatch_creation_and_listing
+test_watchpoint_triggering
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/testcmds b/gdb/testsuite/gdb.mi/testcmds
new file mode 100644
index 00000000000..28fa524042f
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/testcmds
@@ -0,0 +1,25 @@
+# This is a (bogus) sample user command built to test the printing
+# of commands.
+define test
+set $a = 1
+set $b = 2
+if ($a > $b)
+ set $a = 1
+ set $b = 2
+ while ($a > $b)
+ set $a = 1
+ set $b = 2
+ end
+else
+ set $a = 1
+ set $b = 2
+end
+while ($a < $b)
+ set $a = $a + 1
+ set $c = $a
+ if ($a = $b)
+ set $c = 5
+ end
+ set $a = 1
+ set $b = 2
+end
diff --git a/gdb/testsuite/gdb.mi/until.c b/gdb/testsuite/gdb.mi/until.c
new file mode 100644
index 00000000000..df4a68d930f
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/until.c
@@ -0,0 +1,26 @@
+foo (void)
+{
+ int i, x, y, z;
+
+ x = 0;
+ y = 1;
+ i = 0;
+
+ while (i < 2)
+ i++;
+
+ x = i;
+ y = 2 * x;
+ z = x + y;
+ y = x + z;
+ x = 9;
+ y = 10;
+}
+
+main ()
+{
+ int a = 1;
+ foo ();
+ a += 2;
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.mi/var-cmd.c b/gdb/testsuite/gdb.mi/var-cmd.c
new file mode 100644
index 00000000000..42c2336fffc
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/var-cmd.c
@@ -0,0 +1,296 @@
+struct _simple_struct {
+ int integer;
+ unsigned int unsigned_integer;
+ char character;
+ signed char signed_character;
+ char *char_ptr;
+ int array_of_10[10];
+};
+
+typedef struct _simple_struct simpleton;
+
+simpleton global_simple;
+
+enum foo {
+ bar = 1,
+ baz
+};
+
+typedef enum foo efoo;
+
+union named_union
+{
+ int integer;
+ char *char_ptr;
+};
+
+typedef struct _struct_decl {
+ int integer;
+ char character;
+ char *char_ptr;
+ long long_int;
+ int **int_ptr_ptr;
+ long long_array[10];
+
+ void (*func_ptr) (void);
+ struct _struct_decl (*func_ptr_struct) (int, char *, long);
+ struct _struct_decl *(*func_ptr_ptr) (int, char *, long);
+ union {
+ int a;
+ char *b;
+ long c;
+ enum foo d;
+ } u1;
+
+ struct {
+ union {
+ struct {
+ int d;
+ char e[10];
+ int *(*func) (void);
+ efoo foo;
+ } u1s1;
+
+ long f;
+ struct {
+ char array_ptr[2];
+ int (*func) (int, char *);
+ } u1s2;
+ } u2;
+
+ int g;
+ char h;
+ long i[10];
+ } s2;
+} weird_struct;
+
+struct _struct_n_pointer {
+ char ****char_ptr;
+ long ****long_ptr;
+ struct _struct_n_pointer *ptrs[3];
+ struct _struct_n_pointer *next;
+};
+
+void do_locals_tests (void);
+void do_block_tests (void);
+void subroutine1 (int, long *);
+void nothing (void);
+void do_children_tests (void);
+void do_special_tests (void);
+void incr_a (char);
+
+void incr_a (char a)
+{
+ int b;
+ b = a;
+}
+
+void
+do_locals_tests ()
+{
+ int linteger;
+ int *lpinteger;
+ char lcharacter;
+ char *lpcharacter;
+ long llong;
+ long *lplong;
+ float lfloat;
+ float *lpfloat;
+ double ldouble;
+ double *lpdouble;
+ struct _simple_struct lsimple;
+ struct _simple_struct *lpsimple;
+ void (*func) (void);
+
+ /* Simple assignments */
+ linteger = 1234;
+ lpinteger = &linteger;
+ lcharacter = 'a';
+ lpcharacter = &lcharacter;
+ llong = 2121L;
+ lplong = &llong;
+ lfloat = 2.1;
+ lpfloat = &lfloat;
+ ldouble = 2.718281828459045;
+ lpdouble = &ldouble;
+ lsimple.integer = 1234;
+ lsimple.unsigned_integer = 255;
+ lsimple.character = 'a';
+ lsimple.signed_character = 21;
+ lsimple.char_ptr = &lcharacter;
+ lpsimple = &lsimple;
+ func = nothing;
+
+ /* Check pointers */
+ linteger = 4321;
+ lcharacter = 'b';
+ llong = 1212L;
+ lfloat = 1.2;
+ ldouble = 5.498548281828172;
+ lsimple.integer = 255;
+ lsimple.unsigned_integer = 4321;
+ lsimple.character = 'b';
+ lsimple.signed_character = 0;
+
+ subroutine1 (linteger, &llong);
+}
+
+void
+nothing ()
+{
+}
+
+void
+subroutine1 (int i, long *l)
+{
+ global_simple.integer = i + 3;
+ i = 212;
+ *l = 12;
+}
+
+void
+do_block_tests ()
+{
+ int cb = 12;
+
+ {
+ int foo;
+ foo = 123;
+ {
+ int foo2;
+ foo2 = 123;
+ {
+ int foo;
+ foo = 321;
+ }
+ foo2 = 0;
+ }
+ foo = 0;
+ }
+
+ cb = 21;
+}
+
+void
+do_children_tests (void)
+{
+ weird_struct *weird;
+ struct _struct_n_pointer *psnp;
+ struct _struct_n_pointer snp0, snp1, snp2;
+ char a0, *a1, **a2, ***a3;
+ char b0, *b1, **b2, ***b3;
+ char c0, *c1, **c2, ***c3;
+ long z0, *z1, **z2, ***z3;
+ long y0, *y1, **y2, ***y3;
+ long x0, *x1, **x2, ***x3;
+ int *foo;
+ int bar;
+
+ struct _struct_decl struct_declarations;
+ weird = &struct_declarations;
+
+ struct_declarations.integer = 123;
+ weird->char_ptr = "hello";
+ bar = 2121;
+ foo = &bar;
+ struct_declarations.int_ptr_ptr = &foo;
+ weird->long_array[0] = 1234;
+ struct_declarations.long_array[1] = 2345;
+ weird->long_array[2] = 3456;
+ struct_declarations.long_array[3] = 4567;
+ weird->long_array[4] = 5678;
+ struct_declarations.long_array[5] = 6789;
+ weird->long_array[6] = 7890;
+ struct_declarations.long_array[7] = 8901;
+ weird->long_array[8] = 9012;
+ struct_declarations.long_array[9] = 1234;
+
+ weird->func_ptr = nothing;
+
+ /* Struct/pointer/array tests */
+ a0 = '0';
+ a1 = &a0;
+ a2 = &a1;
+ a3 = &a2;
+ b0 = '1';
+ b1 = &b0;
+ b2 = &b1;
+ b3 = &b2;
+ c0 = '2';
+ c1 = &c0;
+ c2 = &c1;
+ c3 = &c2;
+ z0 = 0xdead + 0;
+ z1 = &z0;
+ z2 = &z1;
+ z3 = &z2;
+ y0 = 0xdead + 1;
+ y1 = &y0;
+ y2 = &y1;
+ y3 = &y2;
+ x0 = 0xdead + 2;
+ x1 = &x0;
+ x2 = &x1;
+ x3 = &x2;
+ snp0.char_ptr = &a3;
+ snp0.long_ptr = &z3;
+ snp0.ptrs[0] = &snp0;
+ snp0.ptrs[1] = &snp1;
+ snp0.ptrs[2] = &snp2;
+ snp0.next = &snp1;
+ snp1.char_ptr = &b3;
+ snp1.long_ptr = &y3;
+ snp1.ptrs[0] = &snp0;
+ snp1.ptrs[1] = &snp1;
+ snp1.ptrs[2] = &snp2;
+ snp1.next = &snp2;
+ snp2.char_ptr = &c3;
+ snp2.long_ptr = &x3;
+ snp2.ptrs[0] = &snp0;
+ snp2.ptrs[1] = &snp1;
+ snp2.ptrs[2] = &snp2;
+ snp2.next = 0x0;
+ psnp = &snp0;
+ snp0.char_ptr = &b3;
+ snp1.char_ptr = &c3;
+ snp2.char_ptr = &a3;
+ snp0.long_ptr = &y3;
+ snp1.long_ptr = &x3;
+ snp2.long_ptr = &z3;
+}
+
+void
+do_special_tests (void)
+{
+ union named_union u;
+ union {
+ int a;
+ char b;
+ long c;
+ } anonu;
+ struct _simple_struct s;
+ struct {
+ int a;
+ char b;
+ long c;
+ } anons;
+ enum foo e;
+ enum { A, B, C } anone;
+ int array[21];
+ int a;
+
+ a = 1;
+ incr_a(2);
+}
+
+int
+main (int argc, char *argv [])
+{
+ do_locals_tests ();
+ do_block_tests ();
+ do_children_tests ();
+ do_special_tests ();
+ exit (0);
+}
+
+
diff --git a/gdb/testsuite/gdb.stabs/Makefile.in b/gdb/testsuite/gdb.stabs/Makefile.in
new file mode 100644
index 00000000000..5bf35ea76a1
--- /dev/null
+++ b/gdb/testsuite/gdb.stabs/Makefile.in
@@ -0,0 +1,16 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+all:
+ @echo "Nothing to be done for all..."
+
+#### host, target, and site specific Makefile frags come in here.
+
+clean mostlyclean:
+ -rm -f *.o *~ core tmp.c tmp.s weird.s errs
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
+
+Makefile: $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
diff --git a/gdb/testsuite/gdb.stabs/aout.sed b/gdb/testsuite/gdb.stabs/aout.sed
new file mode 100644
index 00000000000..bbe38bc459a
--- /dev/null
+++ b/gdb/testsuite/gdb.stabs/aout.sed
@@ -0,0 +1,16 @@
+s/# Irix4 sed blows up if you have a sed command starting with "#"//
+s/# Avoid it by putting the comments within real sed commands.//
+s/# GDB legitimately expects a file name.//
+s/# The sun3 assembler bogusly requires that the value of this stab be a//
+s/# label. Placate it.//
+1i\
+ .stabs "weird.c",0x64,0,0,Label0\
+Label0:
+s/N_LSYM/0x80/
+s/N_GSYM/0x20/
+s/# Replace a single backslash with a doubled backslash//
+/\.stabs/s/\\/\\\\/
+s/\.begin_common\(.*\)/.stabs \1,0xe2,0,0,0/
+s/\.end_common\(.*\)/.stabs \1,0xe4,0,0,0/
+s/\.align_it/.align 2/
+/^#/d
diff --git a/gdb/testsuite/gdb.stabs/configure b/gdb/testsuite/gdb.stabs/configure
new file mode 100755
index 00000000000..698233dcc7d
--- /dev/null
+++ b/gdb/testsuite/gdb.stabs/configure
@@ -0,0 +1,899 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=weird.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:573: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:594: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:612: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.stabs/configure.in b/gdb/testsuite/gdb.stabs/configure.in
new file mode 100644
index 00000000000..aa494262bc1
--- /dev/null
+++ b/gdb/testsuite/gdb.stabs/configure.in
@@ -0,0 +1,15 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(weird.exp)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.stabs/ecoff.sed b/gdb/testsuite/gdb.stabs/ecoff.sed
new file mode 100644
index 00000000000..3411c294198
--- /dev/null
+++ b/gdb/testsuite/gdb.stabs/ecoff.sed
@@ -0,0 +1,17 @@
+# GDB legitimately expects a file name.
+1i\
+ .file 1 "weird.c"\
+\ #@stabs\
+\ #.stabs "weird.c",0x64,0,0,0
+/^#/d
+s/" *, */",/g
+s/\([0-9]\) *, */\1,/g
+s/ *$//
+s/N_LSYM/0x80/
+s/N_GSYM/0x20/
+s/\.begin_common\(.*\)/.stabs \1,0xe2,0,0,0/
+s/\.end_common\(.*\)/.stabs \1,0xe4,0,0,0/
+s/\.align_it/.align 2/
+/.if/d
+/.endif/d
+s/\.stabs/ #.stabs/
diff --git a/gdb/testsuite/gdb.stabs/hppa.sed b/gdb/testsuite/gdb.stabs/hppa.sed
new file mode 100644
index 00000000000..5ca1a003c37
--- /dev/null
+++ b/gdb/testsuite/gdb.stabs/hppa.sed
@@ -0,0 +1,20 @@
+s/# Old OSF sed blows up if you have a sed command starting with "#"//
+s/# Avoid it by putting the comments within real sed commands.//
+s/# GDB legitimately expects a file name.//
+s/# The sun3 assembler bogusly requires that the value of this stab be a//
+s/# label. Placate it.//
+1i\
+\ .stabs "weird.c",0x64,0,0,Label0\
+Label0:
+s/N_LSYM/0x80/
+s/N_GSYM/0x20/
+s/# Replace a single backslash with a doubled backslash//
+/\.stabs/s/\\/\\\\/
+s/# Only labels should be at the beginning of a line, assembler directives//
+s/# and instructions should start somewhere after column zero.//
+/^\./s/^\./ ./
+s/\.begin_common\(.*\)/.stabs \1,0xe2,0,0,0/
+s/\.end_common\(.*\)/.stabs \1,0xe4,0,0,0/
+s/\.align_it/.align 4/
+s/\.globl/.export/
+/^#/d
diff --git a/gdb/testsuite/gdb.stabs/weird.def b/gdb/testsuite/gdb.stabs/weird.def
new file mode 100644
index 00000000000..33116b4c5f3
--- /dev/null
+++ b/gdb/testsuite/gdb.stabs/weird.def
@@ -0,0 +1,882 @@
+# We'll need an integer type.
+.stabs "inttype:t1=bu4;0;32;",N_LSYM,0,0,0
+
+# There are several kinds of tests in here. We mix up the order to see
+# if we can test for poor handling of a stab affecting the next or previous
+# stab.
+
+# Try all possible symbol descriptors. Note that GDB should merely
+# complain() even though these strings are totally bogus. This allows
+# future compilers to define new syntaxes.
+.stabs "sym32: !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+
+# Type descriptors.
+.stabs "type32:t32= !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+
+# Note that a 'G', N_GSYM symbol needs no value. The name of the stab
+# is used to look up a non-stab symbol with the same name. On some
+# machines, the non-stab symbols will normally have underscores, but
+# if they lack the underscores, then GDB will simply put the symbol in
+# the minimal symbol table all the same. So we can use them without
+# underscores and that way we don't need to worry about which machines
+# need underscores.
+
+# Type attributes.
+.stabs "attr104:G404=@h !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr105:G405=@i !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+
+# A few real type attributes.
+# Alignment.
+.stabs "var0:G300=@a8;1",N_GSYM,0,0, 0
+.globl var0
+.data
+.align_it
+var0:
+.long 42
+
+.stabs "sym33:! !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym35:# !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym36:$ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym37:% !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym38:& !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym39:' !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym40:( !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym41:) !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym42:* !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym43:+ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym44:, !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym45:- !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+
+.globl attr122
+.data
+.align_it
+attr122:
+.long 42
+.globl attr123
+.data
+.align_it
+attr123:
+.long 42
+.globl attr124
+.data
+.align_it
+attr124:
+.long 42
+
+.stabs "sym46:. !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym47:/ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym48:0 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym49:1 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym50:2 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+
+.stabs "attr96:G396=@` !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr97:G397=@a !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr98:G398=@b !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr99:G399=@c !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+
+.stabs "sym51:3 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym52:4 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym53:5 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym54:6 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym55:7 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym56:8 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym57:9 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym58:: !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym59:; !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym60:< !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym61:= !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym62:> !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym63:? !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym64:@ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym65:A !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym66:B !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym67:C !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym68:D !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym69:E !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym70:F !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym71:G !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym72:H !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym73:I !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym74:J !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym75:K !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym76:L !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym77:M !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym78:N !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym79:O !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym80:P !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym81:Q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym82:R !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym83:S !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym84:T !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym85:U !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym86:V !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym87:W !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym88:X !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym89:Y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym90:Z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym91:[ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+
+.stabs "sym93:] !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym94:^ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym95:_ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym96:` !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym97:a !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym98:b !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym99:c !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym100:d !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym101:e !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym102:f !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym103:g !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym104:h !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym105:i !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym106:j !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym107:k !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym108:l !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym109:m !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym110:n !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym111:o !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym112:p !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym113:q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym114:r !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym115:s !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym116:t !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym117:u !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym118:v !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym119:w !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym120:x !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym121:y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym122:z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym123:{ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym124:| !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym125:} !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "sym126:~ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+
+.stabs "type33:t33=! !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type35:t35=# !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type36:t36=$ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type37:t37=% !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type38:t38=& !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type39:t39=' !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type40:t40=( !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type41:t41=) !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type42:t42=* !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type43:t43=+ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type44:t44=, !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type45:t45=- !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type46:t46=. !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type47:t47=/ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type48:t48=0 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type49:t49=1 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type50:t50=2 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type51:t51=3 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type52:t52=4 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type53:t53=5 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type54:t54=6 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type55:t55=7 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type56:t56=8 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type57:t57=9 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type58:t58=: !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type59:t59=; !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type60:t60=< !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type61:t61== !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type62:t62=> !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type63:t63=? !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type64:t64=@ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type65:t65=A !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type66:t66=B !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type67:t67=C !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+
+.globl attr66
+.data
+.align_it
+attr66:
+.long 42
+.globl attr67
+.data
+.align_it
+attr67:
+.long 42
+.globl attr68
+.data
+.align_it
+attr68:
+.long 42
+.globl attr69
+.data
+.align_it
+attr69:
+.long 42
+
+.stabs "type68:t68=D !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type69:t69=E !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type70:t70=F !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type71:t71=G !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type72:t72=H !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type73:t73=I !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type74:t74=J !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type75:t75=K !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type76:t76=L !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type77:t77=M !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type78:t78=N !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type79:t79=O !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type80:t80=P !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type81:t81=Q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type82:t82=R !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type83:t83=S !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type84:t84=T !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type85:t85=U !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type86:t86=V !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type87:t87=W !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+
+.stabs "attr69:G369=@E !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr70:G370=@F !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr71:G371=@G !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+
+.stabs "type88:t88=X !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type89:t89=Y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type90:t90=Z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type91:t91=[ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+
+.stabs "type93:t93=] !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type94:t94=^ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type95:t95=_ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type96:t96=` !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type97:t97=a !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type98:t98=b !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type99:t99=c !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type100:t100=d !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type101:t101=e !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type102:t102=f !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type103:t103=g !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type104:t104=h !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type105:t105=i !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type106:t106=j !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type107:t107=k !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type108:t108=l !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type109:t109=m !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type110:t110=n !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type111:t111=o !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type112:t112=p !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type113:t113=q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type114:t114=r !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type115:t115=s !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type116:t116=t !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type117:t117=u !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type118:t118=v !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type119:t119=w !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type120:t120=x !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type121:t121=y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type122:t122=z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type123:t123={ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type124:t124=| !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type125:t125=} !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type126:t126=~ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+
+.stabs "attr32:G332=@ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr33:G333=@! !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr35:G334=@# !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+
+.stabs "attr36:G335=@$ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+
+.stabs "attr37:G337=@% !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+
+# Test 'e' constant on non-enum type.
+.stabs "const69:c=e1,69", N_LSYM,0,0, 0
+
+# Test constant with the type embedded.
+.stabs "const70:c=e190=bs2;0;16;,70", N_LSYM,0,0, 0
+
+.stabs "attr38:G338=@& !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+
+# Unrecognized negative type number.
+.stabs "bad_neg0type:t201=s16field0:1,0,32;field2:-534,32,64;field3:-1,96,32;;", N_LSYM,0,0, 0
+
+.stabs "bad_neg0:G201", N_GSYM,0,0, 0
+
+.globl bad_neg0
+.data
+.align_it
+bad_neg0:
+.long 42
+ .long 43, 44, 45
+
+.stabs "attr39:G339=@' !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr41:G341=@) !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr42:G342=@* !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr43:G343=@+ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr44:G344=@, !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr46:G346=@. !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr47:G347=@/ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr58:G358=@: !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+
+# Test two type attributes for one type.
+.stabs "attr59:G359=@;@ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+
+.stabs "attr60:G360=@< !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr61:G361=@= !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr62:G362=@> !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr63:G363=@? !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr64:G364=@@ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr65:G365=@A !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr66:G366=@B !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr67:G367=@C !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr68:G368=@D !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr72:G372=@H !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr73:G373=@I !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr74:G374=@J !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr75:G375=@K !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr76:G376=@L !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr77:G377=@M !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr78:G378=@N !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr79:G379=@O !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr80:G380=@P !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr81:G381=@Q !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr82:G382=@R !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr83:G383=@S !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr84:G384=@T !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr85:G385=@U !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr86:G386=@V !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr87:G387=@W !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr88:G388=@X !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr89:G389=@Y !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr90:G390=@Z !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr91:G391=@[ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+
+.stabs "attr93:G393=@] !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+
+# Do with and without underscore, so this wins regardless of whether
+# names have underscores.
+
+.globl _common0
+.data
+.align_it
+_common0:
+.long 42
+ .long 24
+ .long 22
+.globl common0
+.data
+.align_it
+common0:
+.long 42
+ .long 24
+ .long 22
+.begin_common "common0"
+.stabs "common0var0:S1", N_GSYM,0,0, 0
+.stabs "common0var1:S1", N_GSYM,0,0, 4
+.stabs "common0var2:S1", N_GSYM,0,0, 8
+.end_common "common0"
+
+.stabs "attr94:G394=@^ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr95:G395=@_ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr100:G400=@d !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr101:G401=@e !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr102:G402=@f !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr103:G403=@g !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr106:G406=@j !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr107:G407=@k !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr108:G408=@l !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr109:G409=@m !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr110:G410=@n !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr111:G411=@o !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr112:G412=@p !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr113:G413=@q !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr114:G414=@r !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr115:G415=@s !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr116:G416=@t !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr117:G417=@u !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr118:G418=@v !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr119:G419=@w !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr120:G420=@x !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr121:G421=@y !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr122:G422=@z !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr123:G423=@{ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr124:G424=@| !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr125:G425=@} !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+.stabs "attr126:G426=@~ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
+
+# Define a variable for all the above stabs.
+.globl attr32
+.data
+.align_it
+attr32:
+.long 42
+.globl attr33
+.data
+.align_it
+attr33:
+.long 42
+.globl attr35
+.data
+.align_it
+attr35:
+.long 42
+.globl attr36
+.data
+.align_it
+attr36:
+.long 42
+.globl attr37
+.data
+.align_it
+attr37:
+.long 42
+.globl attr38
+.data
+.align_it
+attr38:
+.long 42
+.globl attr39
+.data
+.align_it
+attr39:
+.long 42
+.globl attr41
+.data
+.align_it
+attr41:
+.long 42
+.globl attr42
+.data
+.align_it
+attr42:
+.long 42
+.globl attr43
+.data
+.align_it
+attr43:
+.long 42
+.globl attr44
+.data
+.align_it
+attr44:
+.long 42
+.globl attr46
+.data
+.align_it
+attr46:
+.long 42
+.globl attr47
+.data
+.align_it
+attr47:
+.long 42
+.globl attr58
+.data
+.align_it
+attr58:
+.long 42
+.globl attr59
+.data
+.align_it
+attr59:
+.long 42
+.globl attr60
+.data
+.align_it
+attr60:
+.long 42
+.globl attr61
+.data
+.align_it
+attr61:
+.long 42
+.globl attr62
+.data
+.align_it
+attr62:
+.long 42
+.globl attr63
+.data
+.align_it
+attr63:
+.long 42
+.globl attr64
+.data
+.align_it
+attr64:
+.long 42
+.globl attr65
+.data
+.align_it
+attr65:
+.long 42
+.globl attr70
+.data
+.align_it
+attr70:
+.long 42
+.globl attr71
+.data
+.align_it
+attr71:
+.long 42
+.globl attr72
+.data
+.align_it
+attr72:
+.long 42
+.globl attr73
+.data
+.align_it
+attr73:
+.long 42
+.globl attr74
+.data
+.align_it
+attr74:
+.long 42
+.globl attr75
+.data
+.align_it
+attr75:
+.long 42
+.globl attr76
+.data
+.align_it
+attr76:
+.long 42
+.globl attr77
+.data
+.align_it
+attr77:
+.long 42
+.globl attr78
+.data
+.align_it
+attr78:
+.long 42
+.globl attr79
+.data
+.align_it
+attr79:
+.long 42
+.globl attr80
+.data
+.align_it
+attr80:
+.long 42
+.globl attr81
+.data
+.align_it
+attr81:
+.long 42
+.globl attr82
+.data
+.align_it
+attr82:
+.long 42
+.globl attr83
+.data
+.align_it
+attr83:
+.long 42
+.globl attr84
+.data
+.align_it
+attr84:
+.long 42
+
+# Unrecognized floating point code.
+.stabs "float72type:t202=R87;9;", N_LSYM,0,0, 0
+
+# 256-bit integer. The point is obviously not that GDB should have a
+# special case for this size, but that an integer of any size should
+# work (at least for printing in hex, not necessarily for arithmetic.
+.stabs "int256var:G203=bu32;0;256;", N_GSYM,0,0, 0
+# The value is palindromic, so it works whether words are big or little
+# endian.
+.globl int256var
+.data
+.align_it
+ int256var:
+.long 42
+ .long 0x2b, 0x2c, 0x2d, 0x2d, 0x2c, 0x2b, 0x2a
+
+# Huge value in constant should at least get the type right.
+
+# This value is just big enough not to fit in 32 bits.
+.stabs "consth:c=e1,4294967296", N_LSYM,0,0, 0
+
+.stabs "consth2:c=e1,-734723985732642758928475678987234563284937456", N_LSYM,0,0, 0
+
+# Test a struct constant using S.
+.stabs "bad_neg0const:c=S201,128,128,11222211343434345656565677888877", N_LSYM,0,0, 0
+
+# Bad filenumbers.
+# This one is totally bogus.
+.stabs "bad_type0:t(-3,7)", N_LSYM,0,0, 0
+# This one probably gets interpreted as a forward reference.
+.stabs "bad_type1:t(42,6)", N_LSYM,0,0, 0
+
+# Arrays indexed by weird things.
+.stabs "array_index0:t205=r1;0;5;", N_LSYM,0,0, 0
+.stabs "array0:G206=a205;1", N_GSYM,0,0, 0
+.globl array0
+.data
+.align_it
+ array0:
+.long 42
+ .long 43, 44, 45, 46, 47
+
+.stabs "array_index1:t207=", N_LSYM,0,0, 0
+.stabs "array1:G208=aeai1_red:0,ai1_green:1,ai1_blue:2,;;1", N_GSYM,0,0, 0
+.globl array1
+.data
+.align_it
+ array1:
+.long 42
+ .long 43, 44
+
+# See if GDB can deal with it if the compiler gets smarter about saying
+# which variables were defined with which types.
+.stabs "inttype_one:t209=1", N_LSYM,0,0, 0
+.stabs "inttype_two:t210=1", N_LSYM,0,0, 0
+.stabs "one_var:G209", N_GSYM,0,0, 0
+.globl one_var
+.data
+.align_it
+one_var:
+.long 42
+.stabs "two_var:G210", N_GSYM,0,0, 0
+.globl two_var
+.data
+.align_it
+two_var:
+.long 42
+
+# And see if the caddr_t hack can deal with the same thing.
+.stabs "intp:t211=*1", N_LSYM,0,0, 0
+# If it weren't for this variable, we'd need to ignore the intp name.
+.stabs "pointer_to_int_var:G212=*1", N_LSYM,0,0, 0
+.stabs "intp_var:G211", N_GSYM,0,0, 0
+.globl intp_var
+.data
+.align_it
+intp_var:
+.long 42
+
+# Unrecognized constant code.
+.stabs "unrecog_const:c=xjksdflskd33,4;473;", N_LSYM,0,0, 0
+
+.globl attr85
+.data
+.align_it
+attr85:
+.long 42
+.globl attr86
+.data
+.align_it
+attr86:
+.long 42
+.globl attr87
+.data
+.align_it
+attr87:
+.long 42
+.globl attr88
+.data
+.align_it
+attr88:
+.long 42
+.globl attr89
+.data
+.align_it
+attr89:
+.long 42
+.globl attr90
+.data
+.align_it
+attr90:
+.long 42
+.globl attr91
+.data
+.align_it
+attr91:
+.long 42
+.globl attr92
+.data
+.align_it
+attr92:
+.long 42
+.globl attr93
+.data
+.align_it
+attr93:
+.long 42
+.globl attr94
+.data
+.align_it
+attr94:
+.long 42
+.globl attr95
+.data
+.align_it
+attr95:
+.long 42
+.globl attr96
+.data
+.align_it
+attr96:
+.long 42
+.globl attr97
+.data
+.align_it
+attr97:
+.long 42
+.globl attr98
+.data
+.align_it
+attr98:
+.long 42
+.globl attr99
+.data
+.align_it
+attr99:
+.long 42
+.globl attr100
+.data
+.align_it
+attr100:
+.long 42
+.globl attr101
+.data
+.align_it
+attr101:
+.long 42
+.globl attr102
+.data
+.align_it
+attr102:
+.long 42
+.globl attr103
+.data
+.align_it
+attr103:
+.long 42
+.globl attr104
+.data
+.align_it
+attr104:
+.long 42
+.globl attr105
+.data
+.align_it
+attr105:
+.long 42
+.globl attr106
+.data
+.align_it
+attr106:
+.long 42
+.globl attr107
+.data
+.align_it
+attr107:
+.long 42
+.globl attr108
+.data
+.align_it
+attr108:
+.long 42
+.globl attr109
+.data
+.align_it
+attr109:
+.long 42
+.globl attr110
+.data
+.align_it
+attr110:
+.long 42
+.globl attr111
+.data
+.align_it
+attr111:
+.long 42
+.globl attr112
+.data
+.align_it
+attr112:
+.long 42
+.globl attr113
+.data
+.align_it
+attr113:
+.long 42
+.globl attr114
+.data
+.align_it
+attr114:
+.long 42
+.globl attr115
+.data
+.align_it
+attr115:
+.long 42
+.globl attr116
+.data
+.align_it
+attr116:
+.long 42
+.globl attr117
+.data
+.align_it
+attr117:
+.long 42
+.globl attr118
+.data
+.align_it
+attr118:
+.long 42
+.globl attr119
+.data
+.align_it
+attr119:
+.long 42
+.globl attr120
+.data
+.align_it
+attr120:
+.long 42
+.globl attr121
+.data
+.align_it
+attr121:
+.long 42
+.globl attr125
+.data
+.align_it
+attr125:
+.long 42
+.globl attr126
+.data
+.align_it
+attr126:
+.long 42
+
+# Size.
+.stabs "var1:G301=@s32;1",N_GSYM,0,0, 0
+.globl var1
+.data
+.align_it
+var1:
+.long 42
+# Pointer class.
+.stabs "var2:G302=@p42;1",N_GSYM,0,0, 0
+.globl var2
+.data
+.align_it
+var2:
+.long 42
+# Packed type.
+.stabs "var3:G303=@P;1",N_GSYM,0,0, 0
+.globl var3
+.data
+.align_it
+var3:
+.long 42
+
+.stabs "sym92:\ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "type92:t92=\ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
+.stabs "attr92:G392=@\ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
diff --git a/gdb/testsuite/gdb.stabs/weird.exp b/gdb/testsuite/gdb.stabs/weird.exp
new file mode 100644
index 00000000000..e584cba3135
--- /dev/null
+++ b/gdb/testsuite/gdb.stabs/weird.exp
@@ -0,0 +1,328 @@
+# Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test that GDB properly ignores invalid stabs.
+# Also test that GDB can debug a .o file, and that it doesn't mind
+# a file that's more minimal than what a compiler normally puts out.
+if $tracelevel then {
+ strace $tracelevel
+}
+
+# If the test directory was not created by configure then skip
+# this test.
+if ![file isdirectory ${objdir}/${subdir}] then {
+ return 0
+}
+
+set prms_id 0
+set bug_id 0
+
+proc do_tests {} {
+ global binfile
+ global gdb_prompt
+
+ # Mips/alpha targets that use gcc with mips-tfile put out the stabs
+ # assembler directives embedded in comments. If the assembler
+ # file is then processed with native cc, all stabs directives
+ # will be lost.
+ # Skip the rest of the stabs tests for this case.
+ send_gdb "ptype inttype\n"
+ gdb_expect {
+ -re "^ptype inttype\r*\ntype = inttype.*$gdb_prompt $" {
+ pass "stabs found"
+ }
+ -re ".*$gdb_prompt $" {
+ setup_xfail "mips-*-*"
+ setup_xfail "alpha-*-*"
+ fail "stabs not found"
+ return
+ }
+ default { fail "checking for stabs" }
+ }
+
+ print_weird_var var0
+ print_weird_var var1
+ print_weird_var var2
+ print_weird_var var3
+
+ print_weird_var attr32
+ print_weird_var attr33
+ print_weird_var attr35
+ print_weird_var attr36
+ print_weird_var attr37
+ print_weird_var attr38
+ print_weird_var attr39
+ print_weird_var attr41
+ print_weird_var attr42
+ print_weird_var attr43
+ print_weird_var attr44
+ print_weird_var attr46
+ print_weird_var attr47
+ print_weird_var attr58
+ print_weird_var attr59
+ print_weird_var attr60
+ print_weird_var attr61
+ print_weird_var attr62
+ print_weird_var attr63
+ print_weird_var attr64
+ print_weird_var attr65
+ print_weird_var attr66
+ print_weird_var attr67
+ print_weird_var attr68
+ print_weird_var attr69
+ print_weird_var attr70
+ print_weird_var attr71
+ print_weird_var attr72
+ print_weird_var attr73
+ print_weird_var attr74
+ print_weird_var attr75
+ print_weird_var attr76
+ print_weird_var attr77
+ print_weird_var attr78
+ print_weird_var attr79
+ print_weird_var attr80
+ print_weird_var attr81
+ print_weird_var attr82
+ print_weird_var attr83
+ print_weird_var attr84
+ print_weird_var attr85
+ print_weird_var attr86
+ print_weird_var attr87
+ print_weird_var attr88
+ print_weird_var attr89
+ print_weird_var attr90
+ print_weird_var attr91
+ print_weird_var attr92
+ print_weird_var attr93
+ print_weird_var attr94
+ print_weird_var attr95
+ print_weird_var attr96
+ print_weird_var attr97
+ print_weird_var attr98
+ print_weird_var attr99
+ print_weird_var attr100
+ print_weird_var attr101
+ print_weird_var attr102
+ print_weird_var attr103
+ print_weird_var attr104
+ print_weird_var attr105
+ print_weird_var attr106
+ print_weird_var attr107
+ print_weird_var attr108
+ print_weird_var attr109
+ print_weird_var attr110
+ print_weird_var attr111
+ print_weird_var attr112
+ print_weird_var attr113
+ print_weird_var attr114
+ print_weird_var attr115
+ print_weird_var attr116
+ print_weird_var attr117
+ print_weird_var attr118
+ print_weird_var attr119
+ print_weird_var attr120
+ print_weird_var attr121
+ print_weird_var attr122
+ print_weird_var attr123
+ print_weird_var attr124
+ print_weird_var attr125
+ print_weird_var attr126
+
+ gdb_test "p const69" " = 69" "'e' constant on non-enum type"
+ gdb_test "whatis const69" "type = (unsigned int|inttype)" "whatis const69"
+
+ gdb_test "p sizeof (const70)" " = 2" "'e' constant with embedded type"
+
+ gdb_test "p bad_neg0" " = \{field0 = 42, field2 =.*field3 = 45\}" "p bad_neg0"
+
+ gdb_test "ptype inttype" "type = (unsigned int|inttype)" "ptype on inttype"
+ gdb_test "p sizeof (float72type)" " = 9" "unrecognized floating point type"
+
+ # This big number needs to be kept as one piece
+ gdb_test "p/x int256var" " = 0x0*2a0000002b0000002c0000002d0000002d0000002c0000002b0000002a" "print very big integer"
+
+ gdb_test "whatis consth" "type = inttype" "whatis consth"
+ gdb_test "whatis consth2" "type = inttype" "whatis consth2"
+
+ # GDB does not yet understand S constants
+ setup_xfail "*-*-*"
+ gdb_test "p/x bad_neg0const" " = \{field0 = 0x11222211, field2 =.*\
+field3 = 0x77888877\}" "print struct constant"
+
+ gdb_test "ptype bad_type0" "type = .*" "print bad_type0"
+ gdb_test "ptype bad_type1" "type = .*" "print bad_type1"
+
+ # GDB does not yet support arrays indexed by anything at all unusual
+ setup_xfail "*-*-*"
+ gdb_test "p array0" " = \\{42, 43, 44, 45, 46, 47\\}" "array0 with strange index"
+ setup_xfail "*-*-*"
+ gdb_test "p array1" " = \\{42, 43, 44\\}" "array1 with strange index"
+
+ # GDB does not yet support this feature
+ gdb_test "whatis one_var" "type = inttype_one" \
+ "whatis one_var (known failure in gdb 4.10)"
+ # But do make sure that it prints as something reasonable
+ gdb_test "whatis one_var" "type = inttype(|_one)" \
+ "whatis one_var test 2"
+
+ gdb_test "whatis two_var" "type = inttype_two" \
+ "whatis two_var (known failure in gdb 4.10)"
+ # But do make sure that it prints as something reasonable
+ gdb_test "whatis two_var" "type = inttype(|_two)" \
+ "whatis two_var test 2"
+
+ setup_xfail "*-*-*"
+ gdb_test "whatis pointer_to_int_var" "type = int \[*\]"
+ setup_xfail "*-*-*"
+ gdb_test "whatis intp_var" "type = intp"
+
+ gdb_test "p common0var0" "= 42"
+ # GDB seems to only understand common blocks local to a function.
+ # These variables never get relocated to be relative to the common
+ # block.
+ # I'm not sure whether it is valid to have a common block which
+ # is not local to a function.
+ setup_xfail "*-*-*"
+ gdb_test "p common0var1" "= 24"
+ setup_xfail "*-*-*"
+ gdb_test "p common0var2" "= 22"
+}
+
+proc print_weird_var { var } {
+ global gdb_prompt
+
+ # Make sure that the variable gets printed out correctly, without
+ # any sort of warning message.
+ send_gdb "print $var\n"
+ gdb_expect {
+ -re "^print $var\r*\n.\[0-9\]* = 42.*$gdb_prompt $" {
+ pass "variable $var printed properly"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "variable $var printed properly"
+ }
+ timeout { fail "variable $var printed properly (timeout)" }
+ eof { fail "variable $var printed properly (eof)" }
+ }
+
+ # Make sure that the stabs did get loaded in a sensible way.
+ # If somehow the stabs got skipped, then the above test can
+ # pass because GDB assumes int for variables without a stab.
+
+ # This doesn't work because 32=45 doesn't preserve the name in
+ # gdb (as of 14 Sep 93 anyway).
+ #gdb_test "whatis $var" "type = (unsigned int|inttype)"
+
+ # But the size should be right.
+ gdb_test "print sizeof ($var)" "= 4"
+}
+
+
+# Don't use gdb_load; it doesn't bitch if the loading produced some
+# error messages during symbol reading.
+set testfile weird
+set srcfile ${objdir}/${subdir}/weird.s
+set binfile ${objdir}/${subdir}/weirdx.o
+
+global target_os
+set sedscript ${srcdir}/${subdir}/aout.sed
+switch -glob ${target_triplet} {
+ "hppa*-*-*" {
+ set sedscript ${srcdir}/${subdir}/hppa.sed
+ }
+ "mips-*-ecoff" {
+ set sedscript ${srcdir}/${subdir}/ecoff.sed
+ }
+ "powerpc-*-aix*" {
+ set sedscript ${srcdir}/${subdir}/xcoff.sed
+ }
+ "rs6000-*-aix*" {
+ set sedscript ${srcdir}/${subdir}/xcoff.sed
+ }
+ "*-*-aout" {
+ set sedscript ${srcdir}/${subdir}/aout.sed
+ }
+ "*-*-xcoff" {
+ set sedscript ${srcdir}/${subdir}/xcoff.sed
+ }
+ "alpha-*-*" {
+ set sedscript ${srcdir}/${subdir}/ecoff.sed
+ }
+}
+
+
+# Hope this is a Unix box.
+set exec_output [remote_exec build "sed" "-f ${sedscript}" "${srcdir}/${subdir}/weird.def" "${srcfile}"]
+if { [lindex $exec_output 0] != 0 } {
+ perror "Couldn't make test case. $exec_output"
+ return -1
+}
+
+# HP's assembler has no idea of what to do with .stab directives; detect the
+# use of HP compilers and escape from here. (No doubt a better heuristic
+# could be devised.)
+
+if { [ info exists CC ] && [ string first "/opt/ansic/bin/cc" "$CC" ] >= 0 } then { continue }
+
+if { [gdb_compile "${srcfile}" "${binfile}" object ""] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+remote_file build delete ${srcfile}
+
+# Start with a fresh gdb
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+set binfile [remote_download host ${binfile} object.o]
+send_gdb "file $binfile\n"
+# If $binfile is very long, a \r (but not a \n) will echo in the
+# middle of the echo of the command. So to match the echo, we
+# would like to match anything not containing \n
+# (we would prefer to be sure not to match any warning message).
+# But \[^\n\]* doesn't seem to work, so instead use the heuristic
+# that a filename won't contain a space and a warning message will.
+# But spaces following by backspaces aren't really spaces.
+gdb_expect 60 {
+ -re "^file (\[^ \]| +\008)*\r*\n" {
+ exp_continue
+ }
+ -re "A program is being debugged already. Kill it\\? \\(y or n\\)" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "^Reading symbols from $binfile\\.\\.\\.done\.\r*\n$gdb_prompt $" {
+ pass "weirdx.o read without error"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "Errors reading weirdx.o"
+ }
+ timeout {
+ perror "couldn't load $binfile into $GDB (timed out)."
+ return -1
+ }
+ eof { fail "(eof) cannot read weirdx.o" }
+}
+
+do_tests
+
+remote_file host delete ${binfile}
+
+return 0
diff --git a/gdb/testsuite/gdb.stabs/xcoff.sed b/gdb/testsuite/gdb.stabs/xcoff.sed
new file mode 100644
index 00000000000..8a6b4ef1986
--- /dev/null
+++ b/gdb/testsuite/gdb.stabs/xcoff.sed
@@ -0,0 +1,17 @@
+# Put everything in this csect, which seems to make things work.
+# The compiler actually puts the stabs in .csect [PR], but that didn't
+# work here (I guess because there is no text section).
+1i\
+ .csect .data[RW]
+# .stabs string,type,0,0,value -> .stabx string,value,type,0
+s/^[ ]*\.stabs[ ]*\("[^"]*"\),[ ]*\([^,]*\),[ ]*0,0,[ ]*\(.*\)$/.stabx \1,\3,\2,0/
+s/N_GSYM/128/
+# This needs to be C_DECL, which is used for types, not C_LSYM, which is
+# ignored on the initial scan.
+s/N_LSYM/140/
+s/\.begin_common/.bc/
+# The AIX assembler doesn't want the name in a .ec directive
+s/\.end_common.*/.ec/
+s/\.align_it/.align 1/
+/\.data/d
+/^#/d
diff --git a/gdb/testsuite/gdb.threads/Makefile.in b/gdb/testsuite/gdb.threads/Makefile.in
new file mode 100644
index 00000000000..34f22b53bb3
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/Makefile.in
@@ -0,0 +1,31 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES = pthreads
+
+all:
+ @echo "Nothing to be done for all..."
+
+info:
+install-info:
+dvi:
+install:
+uninstall: force
+installcheck:
+check:
+
+clean mostlyclean:
+ -rm -f *~ *.o a.out xgdb *.x *.ci *.tmp core* $(EXECUTABLES)
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log config.h
+
+Makefile : $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
+
+config.h: stamp-h ; @true
+stamp-h: config.in config.status
+ CONFIG_HEADERS=config.h:config.in $(SHELL) config.status
+
+config.status: configure
+ $(SHELL) config.status --recheck
diff --git a/gdb/testsuite/gdb.threads/config.in b/gdb/testsuite/gdb.threads/config.in
new file mode 100644
index 00000000000..37bfc2ba592
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/config.in
@@ -0,0 +1,4 @@
+/* config.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
diff --git a/gdb/testsuite/gdb.threads/configure b/gdb/testsuite/gdb.threads/configure
new file mode 100755
index 00000000000..6649098712b
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/configure
@@ -0,0 +1,1098 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=pthreads.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:574: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:595: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:613: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:637: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 652 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:658: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 669 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:675: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+for ac_hdr in pthread.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:701: checking for $ac_hdr" >&5
+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 706 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:711: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+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 | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@CPP@%$CPP%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.threads/configure.in b/gdb/testsuite/gdb.threads/configure.in
new file mode 100644
index 00000000000..1afe91ac4e1
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/configure.in
@@ -0,0 +1,18 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(pthreads.exp)
+AC_CONFIG_HEADER(config.h:config.in)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
+AC_CANONICAL_SYSTEM
+
+AC_CHECK_HEADERS(pthread.h)
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.threads/gcore-thread.exp b/gdb/testsuite/gdb.threads/gcore-thread.exp
new file mode 100644
index 00000000000..b56697be434
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/gcore-thread.exp
@@ -0,0 +1,186 @@
+# Copyright 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@redhat.com)
+# This is a test for the gdb command "generate-core-file".
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# Single-threaded test case
+set testfile "pthreads"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+set built_binfile 0
+if [istarget "*-*-linux"] then {
+ set target_cflags "-D_MIT_POSIX_THREADS"
+} else {
+ set target_cflags ""
+}
+set why_msg "unrecognized error"
+foreach lib {-lpthreads -lpthread -lthread} {
+ set options "debug"
+ lappend options "incdir=${objdir}/${subdir}"
+ lappend options "libs=$lib"
+ set ccout [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $options]
+ switch -regexp -- $ccout {
+ ".*no posix threads support.*" {
+ set why_msg "missing threads include file"
+ break
+ }
+ ".*cannot open -lpthread.*" {
+ set why_msg "missing runtime threads library"
+ }
+ ".*Can't find library for -lpthread.*" {
+ set why_msg "missing runtime threads library"
+ }
+ {^$} {
+ pass "successfully compiled posix threads test case"
+ set built_binfile 1
+ break
+ }
+ }
+}
+if {$built_binfile == "0"} {
+ unsupported "Couldn't compile ${srcfile}, ${why_msg}"
+ return -1
+}
+
+# Now we can proceed with the real testing.
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# regexp for "horizontal" text (i.e. doesn't include newline or
+# carriage return)
+set horiz "\[^\n\r\]*"
+
+# regexp for newline
+set nl "\[\r\n\]+"
+
+set timeout 30
+
+send_gdb "help gcore\n"
+gdb_expect {
+ -re "Undefined command: .gcore.*$gdb_prompt $" {
+ # gcore command not supported -- nothing to test here.
+ unsupported "gdb does not support gcore on this target"
+ return -1;
+ }
+ -re "Save a core file .*$gdb_prompt $" {
+ pass "help gcore"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "help gcore"
+ }
+ timeout {
+ fail "help gcore (timeout)"
+ }
+}
+
+if { ! [ runto main ] } then {
+ gdb_suppress_entire_file "Run to main failed, so all tests in this file will automatically fail."
+}
+
+send_gdb "info threads\n"
+gdb_expect {
+ -re ".* main .*$gdb_prompt $" {
+ # OK, threads are supported.
+ }
+ -re "${nl}$gdb_prompt $" {
+ unsupported "gdb does not support threads on this target"
+ return -1;
+ }
+}
+
+# Make sure thread 1 is running
+delete_breakpoints
+gdb_breakpoint "thread1"
+gdb_test "continue" "Continuing.*Breakpoint.* thread1 .*" "thread 1 is running"
+
+# Make sure thread 2 is running
+delete_breakpoints
+gdb_breakpoint "thread2"
+gdb_test "continue" "Continuing.*Breakpoint.* thread2 .*" "thread 2 is running"
+
+# Drop corefile
+gdb_test "gcore ${objdir}/${subdir}/gcore.test" \
+ "Saved corefile ${objdir}/${subdir}/gcore.test" \
+ "save a corefile"
+
+# Now restart gdb and load the corefile.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+send_gdb "core ${objdir}/${subdir}/gcore.test\n"
+gdb_expect {
+ -re ".* is not a core dump:.*$gdb_prompt $" {
+ fail "re-load generated corefile (bad file format)"
+ # No use proceeding from here.
+ return;
+ }
+ -re ".*: No such file or directory.*$gdb_prompt $" {
+ fail "re-load generated corefile (file not found)"
+ # No use proceeding from here.
+ return;
+ }
+ -re ".*Couldn't find .* registers in core file.*$gdb_prompt $" {
+ fail "re-load generated corefile (incomplete note section)"
+ }
+ -re "Core was generated by .*$gdb_prompt $" {
+ pass "re-load generated corefile"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "re-load generated corefile"
+ }
+ timeout {
+ fail "re-load generated corefile (timeout)"
+ }
+}
+
+# FIXME: now what can we test about the thread state?
+# We do not know for certain that there should be at least
+# three threads, because who knows what kind of many-to-one
+# mapping various OS's may do? Let's assume that there must
+# be at least two threads:
+
+gdb_test "info threads" ".*${nl} 2 ${horiz}${nl}\\* 1 .*" \
+ "corefile contains at least two threads"
+
+# One thread in the corefile should be in the "thread2" function.
+
+gdb_test "info threads" ".* thread2 .*" \
+ "a corefile thread is executing thread2"
+
+# The thread2 thread should be marked as the current thread.
+
+gdb_test "info threads" ".*${nl}\\* ${horiz} thread2 .*" \
+ "thread2 is current thread in corefile"
+
diff --git a/gdb/testsuite/gdb.threads/linux-dp.c b/gdb/testsuite/gdb.threads/linux-dp.c
new file mode 100644
index 00000000000..c3775bd62ae
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/linux-dp.c
@@ -0,0 +1,207 @@
+/* linux-dp.c --- dining philosophers, on LinuxThreads
+ Jim Blandy <jimb@cygnus.com> --- March 1999 */
+
+/* It's okay to edit this file and shift line numbers around. The
+ tests use gdb_get_line_number to find source locations, so they
+ don't depend on having certain line numbers in certain places. */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+/* The number of philosophers at the table. */
+int num_philosophers;
+
+/* Mutex ordering -
+ If you want to lock a mutex M, all the mutexes you have locked
+ already must appear before M on this list.
+
+ fork_mutex[0]
+ fork_mutex[1]
+ ...
+ fork_mutex[num_philosophers - 1]
+ stdout_mutex
+ random_mutex
+*/
+
+/* You must hold this mutex while writing to stdout. */
+pthread_mutex_t stdout_mutex;
+
+/* You must hold this mutex while calling any of the random number
+ generation routines. */
+pthread_mutex_t random_mutex;
+
+/* array of mutexes, one for each fork; fork_mutex[i] is to the left
+ of philosopher i. A philosopher is holding fork i iff his/her
+ thread has locked fork_mutex[i]. */
+pthread_mutex_t *fork_mutex;
+
+/* array of threads, one representing each philosopher. */
+pthread_t *philosophers;
+
+void *
+xmalloc (size_t n)
+{
+ void *p = malloc (n);
+
+ if (! p)
+ {
+ fprintf (stderr, "out of memory\n");
+ exit (2);
+ }
+
+ return p;
+}
+
+void
+shared_printf (char *format, ...)
+{
+ va_list ap;
+
+ va_start (ap, format);
+ pthread_mutex_lock (&stdout_mutex);
+ vprintf (format, ap);
+ pthread_mutex_unlock (&stdout_mutex);
+ va_end (ap);
+}
+
+int
+shared_random ()
+{
+ static unsigned int seed;
+ int result;
+
+ pthread_mutex_lock (&random_mutex);
+ result = rand_r (&seed);
+ pthread_mutex_unlock (&random_mutex);
+ return result;
+}
+
+void
+my_usleep (long usecs)
+{
+ struct timeval timeout;
+
+ timeout.tv_sec = usecs / 1000000;
+ timeout.tv_usec = usecs % 1000000;
+
+ select (0, 0, 0, 0, &timeout);
+}
+
+void
+random_delay ()
+{
+ my_usleep ((shared_random () % 2000) * 100);
+}
+
+void
+print_philosopher (int n, char left, char right)
+{
+ int i;
+
+ shared_printf ("%*s%c %d %c\n", (n * 4) + 2, "", left, n, right);
+}
+
+void *
+philosopher (void *data)
+{
+ int n = * (int *) data;
+
+ print_philosopher (n, '_', '_');
+
+#if 1
+ if (n == num_philosophers - 1)
+ for (;;)
+ {
+ /* The last philosopher is different. He goes for his right
+ fork first, so there is no cycle in the mutex graph. */
+
+ /* Grab the right fork. */
+ pthread_mutex_lock (&fork_mutex[(n + 1) % num_philosophers]);
+ print_philosopher (n, '_', '!');
+ random_delay ();
+
+ /* Then grab the left fork. */
+ pthread_mutex_lock (&fork_mutex[n]);
+ print_philosopher (n, '!', '!');
+ random_delay ();
+
+ print_philosopher (n, '_', '_');
+ pthread_mutex_unlock (&fork_mutex[n]);
+ pthread_mutex_unlock (&fork_mutex[(n + 1) % num_philosophers]);
+ random_delay ();
+ }
+ else
+#endif
+ for (;;)
+ {
+ /* Grab the left fork. */
+ pthread_mutex_lock (&fork_mutex[n]);
+ print_philosopher (n, '!', '_');
+ random_delay ();
+
+ /* Then grab the right fork. */
+ pthread_mutex_lock (&fork_mutex[(n + 1) % num_philosophers]);
+ print_philosopher (n, '!', '!');
+ random_delay ();
+
+ print_philosopher (n, '_', '_');
+ pthread_mutex_unlock (&fork_mutex[n]);
+ pthread_mutex_unlock (&fork_mutex[(n + 1) % num_philosophers]);
+ random_delay ();
+ }
+
+ return (void *) 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ num_philosophers = 5;
+
+ /* Set up the mutexes. */
+ {
+ pthread_mutexattr_t ma;
+ int i;
+
+ pthread_mutexattr_init (&ma);
+ pthread_mutex_init (&stdout_mutex, &ma);
+ pthread_mutex_init (&random_mutex, &ma);
+ fork_mutex = xmalloc (num_philosophers * sizeof (fork_mutex[0]));
+ for (i = 0; i < num_philosophers; i++)
+ pthread_mutex_init (&fork_mutex[i], &ma);
+ pthread_mutexattr_destroy (&ma);
+ }
+
+ /* Set off the threads. */
+ {
+ int i;
+ int *numbers = xmalloc (num_philosophers * sizeof (*numbers));
+ pthread_attr_t ta;
+
+ philosophers = xmalloc (num_philosophers * sizeof (*philosophers));
+
+ pthread_attr_init (&ta);
+
+ for (i = 0; i < num_philosophers; i++)
+ {
+ numbers[i] = i;
+ /* linuxthreads.exp: create philosopher */
+ pthread_create (&philosophers[i], &ta, philosopher, &numbers[i]);
+ }
+
+ pthread_attr_destroy (&ta);
+ }
+
+ /* linuxthreads.exp: info threads 2 */
+ sleep (1000000);
+
+ /* Drink yourself into oblivion. */
+ for (;;)
+ sleep (1000000);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.threads/linux-dp.exp b/gdb/testsuite/gdb.threads/linux-dp.exp
new file mode 100644
index 00000000000..67ed122d103
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/linux-dp.exp
@@ -0,0 +1,229 @@
+# Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+#### Dining Philosophers, on LinuxThreads - Jim Blandy <jimb@cygnus.com>
+####
+#### At the moment, GDB's support for LinuxThreads is pretty
+#### idiosyncratic --- GDB's output doesn't look much like the output
+#### it produces for other thread implementations, messages appear at
+#### different times, etc. So these tests are specific to LinuxThreads.
+####
+#### However, if all goes well, Linux will soon have a libthread_db
+#### interface, and GDB will manage it the same way it does other
+#### libthread_db-based systems. Then, we can adjust this file to
+#### work with any such system.
+
+### Other things we ought to test:
+### stepping a thread while others are running
+### killing and restarting
+### quitting gracefully
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# This only works with Linux configurations.
+if ![istarget *-*-linux-gnu] then {
+ return
+}
+
+set testfile "linux-dp"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug libs=-lpthread}] != ""} {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+send_gdb "set print sevenbit-strings\n" ; gdb_expect -re "$gdb_prompt $"
+runto_main
+
+# There should be no threads initially.
+gdb_test "info threads" "" "info threads 1"
+
+# Try stepping over the thread creation function.
+gdb_breakpoint [gdb_get_line_number "linuxthreads.exp: create philosopher"]
+for {set i 0} {$i < 5} {incr i} {
+ gdb_continue_to_breakpoint "about to create philosopher: $i"
+ send_gdb "next\n"
+ gdb_expect {
+ -re "\\\[New .*\\\].*$gdb_prompt $" {
+ pass "create philosopher: $i"
+ }
+ -re "Program received signal.*(Unknown signal|SIGUSR|Real-time event).*$gdb_prompt $" {
+ # It would be nice if we could catch the message that GDB prints
+ # when it first notices that the thread library doesn't support
+ # debugging, or if we could explicitly ask GDB somehow.
+ unsupported "This GDB does not support threads on this system."
+ return -1
+ }
+ -re "$gdb_prompt $" {
+ fail "create philosopher: $i"
+ }
+ timeout {
+ fail "(timeout) create philosopher: $i"
+ }
+ }
+}
+
+# Run until there are some threads.
+gdb_breakpoint [gdb_get_line_number "linuxthreads.exp: info threads 2"]
+gdb_continue_to_breakpoint "main thread's sleep"
+gdb_test "info threads" "7 Thread .*6 Thread .*5 Thread .*4 Thread .*3 Thread .*2 Thread .*1 Thread .*" "info threads 2"
+
+# Try setting a thread-specific breakpoint.
+gdb_breakpoint "print_philosopher thread 5"
+gdb_continue_to_breakpoint "thread 5's print"
+gdb_test "where" "print_philosopher.*philosopher.*pthread_start_thread.*" \
+ "first thread-specific breakpoint hit"
+
+# Make sure it's catching the right thread. Try hitting the
+# breakpoint ten times, and make sure we don't get anyone else.
+set only_five 1
+for {set i 0} {$only_five > 0 && $i < 10} {incr i} {
+ gdb_continue_to_breakpoint "thread 5's print, pass: $i"
+ send_gdb "info threads\n"
+ gdb_expect {
+ -re "\\* 5 Thread .* print_philosopher .*\r\n$gdb_prompt $" {
+ # Okay this time.
+ }
+ -re ".*$gdb_prompt $" {
+ set only_five 0
+ }
+ timeout {
+ set only_five -1
+ }
+ }
+}
+
+set name "thread-specific breakpoint is thread-specific"
+if {$only_five == 1} { pass $name }
+if {$only_five == 0} { fail $name }
+if {$only_five == -1} { fail "$name (timeout)" }
+
+
+### Select a particular thread.
+proc select_thread {thread} {
+ global gdb_prompt
+
+ send_gdb "thread $thread\n"
+ gdb_expect {
+ -re "\\\[Switching to thread .*\\\].*\r\n$gdb_prompt $" {
+ pass "selected thread: $thread"
+ }
+ -re "$gdb_prompt $" {
+ fail "selected thread: $thread"
+ }
+ timeout {
+ fail "selected thread: $thread (timeout)"
+ }
+ }
+}
+
+### Select THREAD, check for a plausible backtrace, and make sure
+### we're actually selecting a different philosopher each time.
+### Return true if the thread had a stack which was not only
+### acceptable, but interesting. SEEN should be an array in which
+### SEEN(N) exists iff we have found philosopher number N before.
+
+set main_seen 0
+set manager_seen 0
+
+proc check_philosopher_stack {thread seen_name} {
+ global gdb_prompt
+ upvar $seen_name seen
+ global main_seen
+ global manager_seen
+
+ set name "philosopher is distinct: $thread"
+ set interesting 0
+
+ select_thread $thread
+ send_gdb "where\n"
+ gdb_expect {
+ -re ".* in philosopher \\(data=(0x\[0-9a-f\]+).*\r\n$gdb_prompt $" {
+ set data $expect_out(1,string)
+ if {[info exists seen($data)]} {
+ fail $name
+ } else {
+ pass $name
+ set seen($data) yep
+ }
+ set interesting 1
+ }
+ -re ".* in __pthread_manager \\(.*$gdb_prompt $" {
+ if {$manager_seen == 1} {
+ fail "manager thread is distinct: $thread"
+ } else {
+ set manager_seen 1
+ pass "manager thread is distinct: $thread"
+ }
+ set interesting 1
+ }
+ -re "pthread_start_thread.*\r\n$gdb_prompt $" {
+ ## Maybe the thread hasn't started yet.
+ pass $name
+ }
+ -re ".* in main \\(.*$gdb_prompt $" {
+ if {$main_seen == 1} {
+ fail "main is distinct: $thread"
+ } else {
+ set main_seen 1
+ pass "main is distinct: $thread"
+ }
+ set interesting 1
+ }
+ -re " in \\?\\?.*\r\n$gdb_prompt $" {
+ ## Sometimes we can't get a backtrace. I'm going to call
+ ## this a pass, since we do verify that at least one
+ ## thread was interesting, so we can get more consistent
+ ## test suite totals. But in my heart, I think it should
+ ## be an xfail.
+ pass $name
+ }
+ -re "$gdb_prompt $" {
+ fail $name
+ }
+ timeout {
+ fail "$name (timeout)"
+ }
+ }
+
+ return $interesting
+}
+
+set any_interesting 0
+array set seen {}
+unset seen
+for {set i 1} {$i <= 7} {incr i} {
+ if [check_philosopher_stack $i seen] {
+ set any_interesting 1
+ }
+}
+
+if {$any_interesting} {
+ pass "found an interesting thread"
+} else {
+ fail "found an interesting thread"
+}
diff --git a/gdb/testsuite/gdb.threads/pthreads.c b/gdb/testsuite/gdb.threads/pthreads.c
new file mode 100644
index 00000000000..b8f126debd0
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/pthreads.c
@@ -0,0 +1,171 @@
+#include <stdio.h>
+
+#include "config.h"
+
+#ifndef HAVE_PTHREAD_H
+
+/* Don't even try to compile. In fact, cause a syntax error that we can
+ look for as a compiler error message and know that we have no pthread
+ support. In that case we can just suppress the test completely. */
+
+#error "no posix threads support"
+
+#else
+
+/* OK. We have the right header. If we try to compile this and fail, then
+ there is something wrong and the user should know about it so the testsuite
+ should issue an ERROR result.. */
+
+#ifdef __linux__
+#define _MIT_POSIX_THREADS 1 /* GNU/Linux (or at least RedHat 4.0)
+ needs this */
+#endif
+
+#include <pthread.h>
+
+/* Under OSF 2.0 & 3.0 and HPUX 10, the second arg of pthread_create
+ is prototyped to be just a "pthread_attr_t", while under Solaris it
+ is a "pthread_attr_t *". Arg! */
+
+#if defined (__osf__) || defined (__hpux__)
+#define PTHREAD_CREATE_ARG2(arg) arg
+#define PTHREAD_CREATE_NULL_ARG2 null_attr
+static pthread_attr_t null_attr;
+#else
+#define PTHREAD_CREATE_ARG2(arg) &arg
+#define PTHREAD_CREATE_NULL_ARG2 NULL
+#endif
+
+static int verbose = 0;
+
+static void
+common_routine (arg)
+ int arg;
+{
+ static int from_thread1;
+ static int from_thread2;
+ static int from_main;
+ static int hits;
+ static int full_coverage;
+
+ if (verbose) printf("common_routine (%d)\n", arg);
+ hits++;
+ switch (arg)
+ {
+ case 0:
+ from_main++;
+ break;
+ case 1:
+ from_thread1++;
+ break;
+ case 2:
+ from_thread2++;
+ break;
+ }
+ if (from_main && from_thread1 && from_thread2)
+ full_coverage = 1;
+}
+
+static void *
+thread1 (void *arg)
+{
+ int i;
+ int z = 0;
+
+ if (verbose) printf ("thread1 (%0x) ; pid = %d\n", arg, getpid ());
+ for (i=1; i <= 10000000; i++)
+ {
+ if (verbose) printf("thread1 %d\n", pthread_self ());
+ z += i;
+ common_routine (1);
+ sleep(1);
+ }
+ return (void *) 0;
+}
+
+static void *
+thread2 (void * arg)
+{
+ int i;
+ int k = 0;
+
+ if (verbose) printf ("thread2 (%0x) ; pid = %d\n", arg, getpid ());
+ for (i=1; i <= 10000000; i++)
+ {
+ if (verbose) printf("thread2 %d\n", pthread_self ());
+ k += i;
+ common_routine (2);
+ sleep(1);
+ }
+ sleep(100);
+ return (void *) 0;
+}
+
+void
+foo (a, b, c)
+ int a, b, c;
+{
+ int d, e, f;
+
+ if (verbose) printf("a=%d\n", a);
+}
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ pthread_t tid1, tid2;
+ int j;
+ int t = 0;
+ void (*xxx) ();
+ pthread_attr_t attr;
+
+ if (verbose) printf ("pid = %d\n", getpid());
+
+ foo (1, 2, 3);
+
+#ifndef __osf__
+ if (pthread_attr_init (&attr))
+ {
+ perror ("pthread_attr_init 1");
+ exit (1);
+ }
+#endif
+
+#ifdef PTHREAD_SCOPE_SYSTEM
+ if (pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM))
+ {
+ perror ("pthread_attr_setscope 1");
+ exit (1);
+ }
+#endif
+
+ if (pthread_create (&tid1, PTHREAD_CREATE_ARG2(attr), thread1, (void *) 0xfeedface))
+ {
+ perror ("pthread_create 1");
+ exit (1);
+ }
+ if (verbose) printf ("Made thread %d\n", tid1);
+ sleep (1);
+
+ if (pthread_create (&tid2, PTHREAD_CREATE_NULL_ARG2, thread2, (void *) 0xdeadbeef))
+ {
+ perror ("pthread_create 2");
+ exit (1);
+ }
+ if (verbose) printf("Made thread %d\n", tid2);
+
+ sleep (1);
+
+ for (j = 1; j <= 10000000; j++)
+ {
+ if (verbose) printf("top %d\n", pthread_self ());
+ common_routine (0);
+ sleep(1);
+ t += j;
+ }
+
+ exit(0);
+}
+
+#endif /* ifndef HAVE_PTHREAD_H */
diff --git a/gdb/testsuite/gdb.threads/pthreads.exp b/gdb/testsuite/gdb.threads/pthreads.exp
new file mode 100644
index 00000000000..0703395d78b
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/pthreads.exp
@@ -0,0 +1,358 @@
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# This only works with native configurations
+if ![isnative] then {
+ return
+}
+
+set testfile "pthreads"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# regexp for "horizontal" text (i.e. doesn't include newline or
+# carriage return)
+set horiz "\[^\n\r\]*"
+
+set built_binfile 0
+if [istarget "*-*-linux"] then {
+ set target_cflags "-D_MIT_POSIX_THREADS"
+} else {
+ set target_cflags ""
+}
+set why_msg "unrecognized error"
+foreach lib {-lpthreads -lpthread -lthread} {
+ set options "debug"
+ lappend options "incdir=${objdir}/${subdir}"
+ lappend options "libs=$lib"
+ set ccout [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $options]
+ switch -regexp -- $ccout {
+ ".*no posix threads support.*" {
+ set why_msg "missing threads include file"
+ break
+ }
+ ".*cannot open -lpthread.*" {
+ set why_msg "missing runtime threads library"
+ }
+ ".*Can't find library for -lpthread.*" {
+ set why_msg "missing runtime threads library"
+ }
+ {^$} {
+ pass "successfully compiled posix threads test case"
+ set built_binfile 1
+ break
+ }
+ }
+}
+if {$built_binfile == "0"} {
+ unsupported "Couldn't compile ${srcfile}, ${why_msg}"
+ return -1
+}
+
+# Now we can proceed with the real testing.
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set print sevenbit-strings" ""
+#gdb_test "set print address off" ""
+gdb_test "set width 0" ""
+
+# We'll need this when we send_gdb a ^C to GDB. Need to do it before we
+# run the program and gdb starts saving and restoring tty states.
+# On Ultrix, we don't need it and it is really slow (because shell_escape
+# doesn't use vfork).
+if ![istarget "*-*-ultrix*"] then {
+ gdb_test "shell stty intr '^C'" ""
+}
+
+proc all_threads_running {} {
+ global gdb_prompt
+ global srcfile
+
+ # Reset all the counters to zero.
+ gdb_test "set var common_routine::hits=0" ""
+ gdb_test "set var common_routine::from_thread1=0" ""
+ gdb_test "set var common_routine::from_thread2=0" ""
+ gdb_test "set var common_routine::from_main=0" ""
+ gdb_test "set var common_routine::full_coverage=0" ""
+
+ # Disable all breakpoints.
+ gdb_test "disable" ""
+
+ # Set up a breakpoint that will cause us to stop when we have
+ # been called 15 times. This should be plenty of time to allow
+ # every thread to run at least once, since each thread sleeps for
+ # one second between calls to common_routine.
+ gdb_test "tbreak common_routine if hits >= 15" ""
+
+ # Start all the threads running again and wait for the inferior
+ # to stop. Since no other breakpoints are set at this time
+ # we should stop only when we have been previously called 15 times.
+
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Continuing.*common_routine.*at.*$srcfile.*$gdb_prompt $" {}
+ default {
+ fail "continue until common routine run 15 times"
+ return 0
+ }
+ timeout {
+ fail "continue until common routine run 15 times (timeout)"
+ return 0
+ }
+ }
+
+ # Check that we stopped when we actually expected to stop, by
+ # verifying that there have been 15 previous hits.
+
+ # NOTE: Because of synchronization behavior, it is possible for
+ # more than one thread to increment "hits" between one breakpoint
+ # trap and the next. So stopping after 16 or 17 hits should be
+ # considered acceptable.
+
+ send_gdb "p common_routine::hits\n"
+ gdb_expect {
+ -re ".*= 15\r\n$gdb_prompt $" {
+ pass "stopped before calling common_routine 15 times"
+ }
+ -re ".*= 16\r\n$gdb_prompt $" {
+ pass "stopped before calling common_routine 15 times (16 times)"
+ }
+ -re ".*= 17\r\n$gdb_prompt $" {
+ pass "stopped before calling common_routine 15 times (17 times)"
+ }
+ default {
+ fail "stopped before calling common_routine 15 times"
+ return 0
+ }
+ -re ".*$gdb_prompt $" {
+ fail "stopped before calling common_routine 15 times"
+ return 0
+ }
+ timeout {
+ fail "stopped before calling common_routine 15 times (timeout)"
+ return 0
+ }
+ }
+
+ # Also check that all of the threads have run, which will only be true
+ # if the full_coverage variable is set.
+
+ send_gdb "p common_routine::full_coverage\n"
+ gdb_expect {
+ -re ".* = 1.*$gdb_prompt $" {}
+ -re ".* = 0.*$gdb_prompt $" {
+ fail "some threads didn't run"
+ return 0
+ }
+ default {
+ fail "some threads didn't run"
+ return 0
+ }
+ timeout {
+ fail "some threads didn't run (timeout)"
+ return 0
+ }
+ }
+
+ # Looks fine, return success.
+ return 1
+}
+
+proc test_startup {} {
+ global srcdir srcfile gdb_prompt expect_out
+ global horiz
+ global main_id thread1_id thread2_id
+
+ # We should be able to do an info threads before starting any others.
+ send_gdb "info threads\n"
+ gdb_expect {
+ -re ".*Thread.*main.*$gdb_prompt $" {
+ pass "info threads"
+ }
+ -re "\r\n$gdb_prompt $" {
+ unsupported "gdb does not support pthreads for this machine"
+ return 0
+ }
+ }
+
+ # Extract the thread id number of main thread from "info threads" output.
+ send_gdb "info threads\n"
+ gdb_expect -re "(\[0-9\]+)(${horiz}Thread${horiz}main.*)($gdb_prompt $)"
+ set main_id $expect_out(1,string)
+
+ # Check that we can continue and create the first thread.
+ gdb_test "break thread1" "Breakpoint .* file .*$srcdir.*"
+ gdb_test "continue" \
+ "Continuing.*Breakpoint .*, thread1 \\(arg=0xfeedface\\).*at.*$srcfile.*" \
+ "Continue to creation of first thread"
+ gdb_test "disable" ""
+
+ # Extract the thread id number of thread 1 from "info threads" output.
+ send_gdb "info threads\n"
+ gdb_expect -re "(\[0-9\]+)(${horiz}Thread${horiz}thread1.*)($gdb_prompt $)"
+ set thread1_id $expect_out(1,string)
+
+ # Check that we can continue and create the second thread,
+ # ignoring the first thread for the moment.
+ gdb_test "break thread2" "Breakpoint .* file .*$srcdir.*"
+ gdb_test "continue" \
+ "Continuing.*Breakpoint .*, thread2 \\(arg=0xdeadbeef\\).*at.*$srcfile.*" \
+ "Continue to creation of second thread"
+
+ # Extract the thread id number of thread 2 from "info threads" output.
+ send_gdb "info threads\n"
+ gdb_expect -re "(\[0-9\]+)(${horiz}Thread${horiz}thread2.*)($gdb_prompt $)"
+ set thread2_id $expect_out(1,string)
+
+ return 1
+}
+
+proc check_control_c {} {
+ global gdb_prompt
+
+ # Verify that all threads are running.
+ if [all_threads_running] then {
+ pass "All threads running after startup"
+ }
+
+ # Send a continue followed by ^C to the process to stop it.
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Continuing." {
+ pass "Continue with all threads running"
+ }
+ timeout {
+ fail "Continue with all threads running (timeout)"
+ }
+ }
+ sleep 1
+ set description "Stopped with a ^C"
+ after 1000 [send_gdb "\003"]
+ gdb_expect {
+ -re "Program received signal SIGINT.*$gdb_prompt $" {
+ pass $description
+ }
+ -re "Quit.*$gdb_prompt $" {
+ pass $description
+ }
+ timeout {
+ fail "$description (timeout)"
+ return 1;
+ }
+ }
+ gdb_test "bt" ""
+
+ # Verify that all threads can be run again after a ^C stop.
+ if [all_threads_running] then {
+ pass "All threads running after continuing from ^C stop"
+ }
+ return 0;
+}
+
+proc check_backtraces {} {
+ global gdb_prompt main_id thread1_id thread2_id
+
+ # Check that the "thread apply N backtrace" command works
+
+ gdb_test "thread apply $main_id backtrace" \
+ ".* in main \\(argc=.*, argv=.*\\).*" \
+ "check backtrace from main thread"
+ gdb_test "thread apply $thread1_id backtrace" \
+ ".* in thread1 \\(arg=0xfeedface\\).*" \
+ "check backtrace from thread 1"
+ gdb_test "thread apply $thread2_id backtrace" \
+ ".* in thread2 \\(arg=0xdeadbeef\\).*" \
+ "check backtrace from thread 2"
+
+ # Check that we can apply the backtrace command to all
+ # three threads with a single gdb command
+
+ gdb_test "thread apply $main_id $thread1_id $thread2_id bt" \
+ ".* in main .* in thread1 .* in thread2.*" \
+ "apply backtrace command to all three threads"
+
+ # Check that we can do thread specific backtraces
+ # This also tests that we can do thread specific breakpoints.
+
+ gdb_test "break common_routine thread $thread2_id" \
+ "Breakpoint .* at 0x.* file .* line .*" \
+ "set break at common_routine in thread 2"
+
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Breakpoint .* common_routine \\(arg=2\\).*" {
+ pass "continue to bkpt at common_routine in thread 2"
+ send_gdb "backtrace\n"
+ gdb_expect {
+ -re "#0.*common_routine \\(arg=2\\).*#1.*thread2.*" {
+ pass "backtrace from thread 2 bkpt in common_routine"
+ }
+ default {
+ fail "backtrace from thread 2 bkpt in common_routine"
+ }
+ timeout {
+ fail "backtrace from thread 2 bkpt in common_routine (timeout)"
+ }
+ }
+ }
+ -re "Breakpoint .* common_routine \\(arg=0\\).*" {
+ fail "continue to bkpt at common_routine in thread 2 (arg=0)"
+ }
+ -re "Breakpoint .* common_routine \\(arg=1\\).*" {
+ fail "continue to bkpt at common_routine in thread 2 (arg=1)"
+ }
+ -re ".*$gdb_prompt" {
+ fail "continue to bkpt at common_routine in thread 2"
+ }
+ default {
+ fail "continue to bkpt at common_routine in thread 2 (default)"
+ }
+ timeout {
+ fail "continue to bkpt at common_routine in thread 2 (timeout)"
+ }
+ }
+}
+
+setup_xfail "alpha-*-osf*"
+if [runto_main] then {
+ clear_xfail "alpha-*-osf*"
+ if [test_startup] then {
+ if [check_control_c] then {
+ warning "Could not stop child with ^C; skipping rest of tests.\n"
+ return;
+ }
+ check_backtraces
+ }
+}
+clear_xfail "alpha-*-osf*"
diff --git a/gdb/testsuite/gdb.threads/step.c b/gdb/testsuite/gdb.threads/step.c
new file mode 100644
index 00000000000..1b18a4b07ad
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/step.c
@@ -0,0 +1,221 @@
+/* step.c for step.exp */
+#include <ipc.h>
+#include <pthread.h>
+#include <st.h>
+#include <signal.h>
+#include <stdio.h>
+
+void alarm_handler ();
+void alarm_handler1 ();
+void alarm_handler2 ();
+void thread1 ();
+void thread2 ();
+
+#define TIME_LIMIT 30
+
+
+int count1 = 0;
+int count2 = 0;
+
+pthread_t tid1, tid2;
+pthread_attr_t attr1, attr2;
+
+pthread_mutex_t mut;
+pthread_mutexattr_t mut_attr;
+
+pthread_condattr_t cv_attr_a, cv_attr_b;
+pthread_cond_t cv_a, cv_b;
+
+struct cv_struct
+ {
+ char a;
+ char b;
+ }
+test_struct;
+
+main ()
+{
+ /*init la struct */
+ test_struct.a = 0;
+ test_struct.b = 1;
+
+ /* create le mutex */
+ if (pthread_mutexattr_create (&mut_attr) == -1)
+ {
+ perror ("mutexattr_create");
+ exit (1);
+ }
+
+
+ if (pthread_mutex_init (&mut, mut_attr) == -1)
+ {
+ perror ("mutex_init");
+ exit (1);
+ }
+
+ /* create 2 cv */
+ if (pthread_condattr_create (&cv_attr_a) == -1)
+ {
+ perror ("condattr_create(1)");
+ exit (1);
+ }
+
+ if (pthread_cond_init (&cv_a, cv_attr_a) == -1)
+ {
+ perror ("cond_init(1)");
+ exit (1);
+ }
+
+ if (pthread_condattr_create (&cv_attr_b) == -1)
+ {
+ perror ("condattr_create(2)");
+ exit (1);
+ }
+
+ if (pthread_cond_init (&cv_b, cv_attr_b) == -1)
+ {
+ perror ("cond_init(2)");
+ exit (1);
+ }
+
+ /* create 2 threads of execution */
+ if (pthread_attr_create (&attr1) == -1)
+ {
+ perror ("attr_create(1)");
+ exit (1);
+ }
+
+ if (pthread_create (&tid1, attr1, thread1, &count1) == -1)
+ {
+ perror ("pthread_create(1)");
+ exit (1);
+ }
+
+ if (pthread_attr_create (&attr2) == -1)
+ {
+ perror ("attr_create(2)");
+ exit (1);
+ }
+
+ if (pthread_create (&tid2, attr2, thread2, &count2) == -1)
+ {
+ perror ("pthread_create(2)");
+ exit (1);
+ }
+
+ /* set alarm to print out data and exit */
+ signal (SIGALRM, alarm_handler);
+ alarm (TIME_LIMIT);
+
+ for (;;)
+ pause ();
+}
+
+void
+thread1 (count)
+ int *count;
+{
+ tid_t tid;
+
+ tid = getstid ();
+ printf ("Thread1 tid 0x%x (%d) \n", tid, tid);
+ printf ("Thread1 @tid=0x%x \n", &tid);
+ signal (SIGALRM, alarm_handler1);
+
+ for (;;)
+ {
+ if (pthread_mutex_lock (&mut) == -1)
+ {
+ perror ("pthread_mutex_lock(1)");
+ pthread_exit ((void *) 0);
+ }
+
+ while (test_struct.a == 0)
+ {
+ if (pthread_cond_wait (&cv_a, &mut) == -1)
+ {
+ perror ("pthread_cond_wait(1)");
+ pthread_exit ((void *) -1);
+ }
+ }
+
+ (*count)++;
+ printf ("*******thread1 count %d\n", *count);
+
+ test_struct.a = 0;
+
+ test_struct.b = 1;
+ pthread_cond_signal (&cv_b);
+
+ if (pthread_mutex_unlock (&mut) == -1)
+ {
+ perror ("pthread_mutex_unlock(1)");
+ pthread_exit ((void *) -1);
+ }
+ }
+}
+
+void
+thread2 (count)
+ int *count;
+{
+ tid_t tid;
+
+ tid = getstid ();
+ printf ("Thread2 tid 0x%x (%d) \n", tid, tid);
+ printf ("Thread1 @tid=0x%x \n", &tid);
+ signal (SIGALRM, alarm_handler2);
+
+ for (;;)
+ {
+ if (pthread_mutex_lock (&mut) == -1)
+ {
+ perror ("pthread_mutex_lock(2)");
+ pthread_exit ((void *) 0);
+ }
+
+ while (test_struct.b == 0)
+ {
+ if (pthread_cond_wait (&cv_b, &mut) == -1)
+ {
+ perror ("pthread_cond_wait(2)");
+ pthread_exit ((void *) -1);
+ }
+ }
+
+ (*count)++;
+ printf ("*******thread2 count %d\n", *count);
+
+ test_struct.b = 0;
+
+ test_struct.a = 1;
+ pthread_cond_signal (&cv_a);
+
+ if (pthread_mutex_unlock (&mut) == -1)
+ {
+ perror ("pthread_mutex_unlock(2)");
+ pthread_exit ((void *) -1);
+ }
+ }
+}
+
+
+void
+alarm_handler ()
+{
+ printf ("\tcount1 (%d) \n\tcount2 (%d)\n", count1, count2);
+ exit (0);
+}
+
+void
+alarm_handler1 ()
+{
+ printf ("ALARM thread 1\n");
+}
+
+void
+alarm_handler2 ()
+{
+ printf ("ALARM thread 2\n");
+ pthread_exit ((void *) 0);
+}
diff --git a/gdb/testsuite/gdb.threads/step.exp b/gdb/testsuite/gdb.threads/step.exp
new file mode 100644
index 00000000000..aa5639347b7
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/step.exp
@@ -0,0 +1,200 @@
+# step.exp -- Expect script to test gdb with step.c
+# Copyright (C) 1992, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Hiro Sugawara. (hiro@lynx.com)
+#
+# This test really needs some major surgery to be acceptable, but
+# I'm just about burnt out on lynx work, so I'm not doing it now.
+#
+# * The test has an indeterminate number of pass/fails
+# for each run (it runs a small group of tests until
+# it's timer kicks off). This is very bad for nightly
+# automated regression testing.
+#
+# * It tries to "step" from withint he prologue of a
+# function. This isn't support in gdb (it's going
+# to act like a continue).
+#
+# * This test rarely check that it stopped in sensible
+# places. (see previous bullet -- this test doesn't
+# catch the fact it continued rather than stepped)
+
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set program_exited 0
+
+proc set_bp { where } {
+ global gdb_prompt
+
+ send_gdb "break $where\n"
+ # The first regexp is what we get with -g, the second without -g.
+ gdb_expect {
+ -re "Break.* at .*: file .*, line \[0-9\]*.*$gdb_prompt $" {}
+ -re "Breakpoint \[0-9\]* at 0x\[0-9a-f\]*.*$gdb_prompt $" {}
+ -re "$gdb_prompt $" { fail "setting breakpoint at $where" ; return 0 }
+ timeout { fail "setting breakpoint at $where (timeout)" ; return 0 }
+ }
+ pass "set_bp"
+}
+
+proc step_it { cmd } {
+ global gdb_prompt
+ global program_exited
+
+ send_gdb "$cmd\n"
+ gdb_expect {
+ -re "0x\[0-9A-Fa-f\]* *in.*\r\n$gdb_prompt $" { pass "step_it"; return 0 }
+ -re "0x\[0-9A-Fa-f\]* *\[0-9\]*.*\r\n$gdb_prompt $" { pass "step_it"; return 1 }
+ -re "Program exited .*\n$gdb_prompt $" {
+ set program_exited 1
+ return -1
+ }
+ -re "$gdb_prompt $" { fail "single-stepping ($cmd).\n" ; return -1 }
+ timeout { fail "single-stepping ($cmd) timout.\n" ; return -1 }
+ }
+}
+
+proc step_inst {} {
+ step_it "stepi"
+}
+
+proc step_source {} {
+ step_it "step"
+}
+
+proc continue_all {} {
+ global gdb_prompt
+
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Breakpoint \[0-9\]*, thread\[0-9\]* .*$gdb_prompt $" {
+ pass "continue_all"
+ return 0
+ }
+ -re "Program exited .*\n$gdb_prompt $" {
+ set program_exited 1
+ return 1;
+ }
+ -re "$gdb_prompt $" { fail "continue" ; return -1 }
+ timeout { fail "continue (timeout)" ; return -1 }
+ }
+}
+
+proc check_threads { num_threads } {
+ global gdb_prompt
+
+ set curr_thread 0
+ send_gdb "info threads\n"
+ while { $num_threads > 0 } {
+ gdb_expect {
+ -re "\\* *\[0-9\]* process \[0-9\]* thread \[0-9\]* .*\n" {
+ incr curr_thread
+ set num_threads [expr $num_threads - 1]
+ }
+ -re " *\[0-9\]* process \[0-9\]* thread \[0-9\]* .*\n" {
+ set num_threads [expr $num_threads - 1]
+ }
+ -re "$gdb_prompt $" {
+ if { $num_threads < 0 } {
+ fail "check_threads (too many)" ; return -1
+ }
+ break
+ }
+ timeout { fail "check_threads (timeout)" ; return -1 }
+ }
+ }
+
+ if { $curr_thread == 0 } {
+ fail "check_threads (no current thread)\n"
+ return -1
+ }
+ if { $curr_thread > 1 } {
+ fail "check_threads (more than one current thread)\n"
+ return -1
+ }
+ return 0
+}
+
+proc test_cond_wait {} {
+ global program_exited
+
+ set_bp 135
+ runto 179
+ while { 1 } {
+ set stepi_counter 0
+ while { [step_inst] } {
+ if { $program_exited } { break }
+ incr stepi_counter
+ if { $stepi_counter > 30 } {
+ fail "too many stepi's per line\n"
+ return -1
+ }
+ }
+ if { $program_exited } { break }
+ step_source
+ if { $program_exited } { break }
+ continue_all
+ if { $program_exited } { break }
+ check_threads 3
+ }
+}
+
+proc do_tests {} {
+ global prms_id
+ global bug_id
+ global subdir
+ global objdir
+ global srcdir
+ global binfile
+ global gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $objdir/$subdir/$binfile
+
+ send_gdb "set width 0\n"
+ gdb_expect -re "$gdb_prompt $"
+
+ test_cond_wait
+}
+
+# Check to see if we have an executable to test. If not, then either we
+# haven't tried to compile one, or the compilation failed for some reason.
+# In either case, just notify the user and skip the tests in this file.
+
+set binfile "step"
+set srcfile "step.c"
+
+if ![file exists $objdir/$subdir/$binfile] then {
+ if $all_flag then {
+ warning "$binfile does not exist; tests suppressed."
+ }
+} else {
+ do_tests
+}
diff --git a/gdb/testsuite/gdb.threads/step2.exp b/gdb/testsuite/gdb.threads/step2.exp
new file mode 100644
index 00000000000..5442e6aef6f
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/step2.exp
@@ -0,0 +1,150 @@
+# step2.exp -- Expect script to test gdb step.c
+# Copyright (C) 1992, 1997 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Jeff Law. (law@cygnus.com)
+#
+
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set program_exited 0
+
+# A simple and crude test to see that we can step two threads independently
+proc test_multi_threaded_stepping {} {
+ global gdb_prompt
+ global hex
+ global srcfile
+ global decimal
+
+ # Set breakpoints in code that we know is executed in only
+ # thread of control.
+ gdb_test "break thread1" \
+ "Break.* at $hex: file .*$srcfile, line $decimal\\."
+ gdb_test "break thread2" \
+ "Break.* at $hex: file .*$srcfile, line $decimal\\."
+
+ # the order in which things happen is indeterminate. So we basically
+ # look for a set of events and note that each one happens and that
+ # all of the required events have happened when we're done.
+ #
+ # Right now we only verify that both threads start and that they
+ # both call pthread_cond_wait twice.
+ set thread1started 0
+ set thread1condwait 0
+ set thread2started 0
+ set thread2condwait 0
+
+ send_gdb "run\n"
+ gdb_expect {
+ -re "The program .* has been started already.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re ".*Breakpoint \[0-9\]+,.*thread1.* at .*$srcfile:.*\[\t \].*$gdb_prompt $" {
+ if { $thread1started != 0 } then {
+ fail "thread1 started"
+ return
+ } else {
+ set thread1started 1
+ pass "thread1 started"
+ }
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re ".*Breakpoint \[0-9\]+,.*thread2.* at .*$srcfile:.*\[\t \].*$gdb_prompt $" {
+ if { $thread2started != 0 } then {
+ fail "thread2 started"
+ return
+ } else {
+ set thread2started 1
+ pass "thread2 started"
+ }
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re ".*pthread_cond_wait.*cv_a.*$gdb_prompt" {
+ if { $thread1started == 0 } then {
+ fail "thread1 condwait"
+ return
+ }
+ if { $thread1condwait < 2 } then {
+ pass "thread1 condwait"
+ incr thread1condwait
+ }
+ if { $thread2condwait == 2 } then {
+ pass "multi threaded stepping"
+ return
+ }
+ send_gdb "step\n"
+ exp_continue
+ }
+
+ -re ".*pthread_cond_wait.*cv_b.*$gdb_prompt" {
+ if { $thread2started == 0 } then {
+ fail "thread2 condwait"
+ return
+ }
+ if { $thread2condwait < 2 } then {
+ pass "thread2 condwait"
+ incr thread2condwait
+ }
+ if { $thread1condwait == 2 } then {
+ pass "multi threaded stepping"
+ return
+ }
+ send_gdb "step\n"
+ exp_continue
+ }
+
+ -re "$gdb_prompt" {
+ send_gdb "step\n"
+ exp_continue
+ }
+ default { fail "multi threaded stepping" }
+ }
+}
+
+# Check to see if we have an executable to test. If not, then either we
+# haven't tried to compile one, or the compilation failed for some reason.
+# In either case, just notify the user and skip the tests in this file.
+
+set binfile "step"
+set srcfile "step.c"
+
+if ![file exists $objdir/$subdir/$binfile] then {
+ if $all_flag then {
+ warning "$binfile does not exist; tests suppressed."
+ }
+ return
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $objdir/$subdir/$binfile
+
+test_multi_threaded_stepping
diff --git a/gdb/testsuite/gdb.trace/Makefile.in b/gdb/testsuite/gdb.trace/Makefile.in
new file mode 100644
index 00000000000..601c9e17ff9
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/Makefile.in
@@ -0,0 +1,21 @@
+#### host, target, and site specific Makefile frags come in here.
+
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+.PHONY: all clean mostlyclean distclean realclean
+
+all:
+ @echo "Nothing to be done for all..."
+
+clean mostlyclean:
+ -rm -f actions circ collection limits
+ -rm -f *.o *.diff *~ *.bad core sh3 hppa mn10200 mn10300
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
+
+Makefile: $(srcdir)/Makefile.in $(srcdir)/configure.in
+ $(SHELL) ./config.status --recheck
+
+
diff --git a/gdb/testsuite/gdb.trace/actions.c b/gdb/testsuite/gdb.trace/actions.c
new file mode 100644
index 00000000000..ae3c1c38c1c
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/actions.c
@@ -0,0 +1,134 @@
+/*
+ * Test program for trace action commands
+ */
+
+static char gdb_char_test;
+static short gdb_short_test;
+static long gdb_long_test;
+static char gdb_arr_test[25];
+static struct GDB_STRUCT_TEST
+{
+ char c;
+ short s;
+ long l;
+ int bfield : 11; /* collect bitfield */
+ char arr[25];
+ struct GDB_STRUCT_TEST *next;
+} gdb_struct1_test, gdb_struct2_test, *gdb_structp_test, **gdb_structpp_test;
+
+static union GDB_UNION_TEST
+{
+ char c;
+ short s;
+ long l;
+ int bfield : 11; /* collect bitfield */
+ char arr[4];
+ union GDB_UNION_TEST *next;
+} gdb_union1_test;
+
+void gdb_recursion_test (int, int, int, int, int, int, int);
+
+void gdb_recursion_test (int depth,
+ int q1,
+ int q2,
+ int q3,
+ int q4,
+ int q5,
+ int q6)
+{ /* gdb_recursion_test line 0 */
+ int q = q1; /* gdbtestline 1 */
+
+ q1 = q2; /* gdbtestline 2 */
+ q2 = q3; /* gdbtestline 3 */
+ q3 = q4; /* gdbtestline 4 */
+ q4 = q5; /* gdbtestline 5 */
+ q5 = q6; /* gdbtestline 6 */
+ q6 = q; /* gdbtestline 7 */
+ if (depth--) /* gdbtestline 8 */
+ gdb_recursion_test (depth, q1, q2, q3, q4, q5, q6); /* gdbtestline 9 */
+}
+
+
+unsigned long gdb_c_test( unsigned long *parm )
+
+{
+ char *p = "gdb_c_test";
+ char *ridiculously_long_variable_name_with_equally_long_string_assignment;
+ register long local_reg = 7;
+ static unsigned long local_static, local_static_sizeof;
+ long local_long;
+ unsigned long *stack_ptr;
+ unsigned long end_of_stack;
+
+ ridiculously_long_variable_name_with_equally_long_string_assignment =
+ "ridiculously long variable name with equally long string assignment";
+ local_static = 9;
+ local_static_sizeof = sizeof (struct GDB_STRUCT_TEST);
+ local_long = local_reg + 1;
+ stack_ptr = (unsigned long *) &local_long;
+ end_of_stack =
+ (unsigned long) &stack_ptr + sizeof(stack_ptr) + sizeof(end_of_stack) - 1;
+
+ gdb_char_test = gdb_struct1_test.c = (char) ((long) parm[1] & 0xff);
+ gdb_short_test = gdb_struct1_test.s = (short) ((long) parm[2] & 0xffff);
+ gdb_long_test = gdb_struct1_test.l = (long) ((long) parm[3] & 0xffffffff);
+ gdb_union1_test.l = (long) parm[4];
+ gdb_arr_test[0] = gdb_struct1_test.arr[0] = (char) ((long) parm[1] & 0xff);
+ gdb_arr_test[1] = gdb_struct1_test.arr[1] = (char) ((long) parm[2] & 0xff);
+ gdb_arr_test[2] = gdb_struct1_test.arr[2] = (char) ((long) parm[3] & 0xff);
+ gdb_arr_test[3] = gdb_struct1_test.arr[3] = (char) ((long) parm[4] & 0xff);
+ gdb_arr_test[4] = gdb_struct1_test.arr[4] = (char) ((long) parm[5] & 0xff);
+ gdb_arr_test[5] = gdb_struct1_test.arr[5] = (char) ((long) parm[6] & 0xff);
+ gdb_struct1_test.bfield = 144;
+ gdb_struct1_test.next = &gdb_struct2_test;
+ gdb_structp_test = &gdb_struct1_test;
+ gdb_structpp_test = &gdb_structp_test;
+
+ gdb_recursion_test (3, (long) parm[1], (long) parm[2], (long) parm[3],
+ (long) parm[4], (long) parm[5], (long) parm[6]);
+
+ gdb_char_test = gdb_short_test = gdb_long_test = 0;
+ gdb_structp_test = (void *) 0;
+ gdb_structpp_test = (void *) 0;
+ memset ((char *) &gdb_struct1_test, 0, sizeof (gdb_struct1_test));
+ memset ((char *) &gdb_struct2_test, 0, sizeof (gdb_struct2_test));
+ local_static_sizeof = 0;
+ local_static = 0;
+ return ( (unsigned long) 0 );
+}
+
+static void gdb_asm_test (void)
+{
+}
+
+static void begin () /* called before anything else */
+{
+}
+
+static void end () /* called after everything else */
+{
+}
+
+int
+main (argc, argv, envp)
+ int argc;
+ char *argv[], **envp;
+{
+ int i;
+ unsigned long myparms[10];
+
+#ifdef usestubs
+ set_debug_traps ();
+ breakpoint ();
+#endif
+
+ begin ();
+ for (i = 0; i < sizeof (myparms) / sizeof (myparms[0]); i++)
+ myparms[i] = i;
+
+ gdb_c_test (&myparms[0]);
+
+ end ();
+ return 0;
+}
+
diff --git a/gdb/testsuite/gdb.trace/actions.exp b/gdb/testsuite/gdb.trace/actions.exp
new file mode 100644
index 00000000000..66d3d87d22e
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/actions.exp
@@ -0,0 +1,207 @@
+# Copyright 1998 Free Software Foundation, Inc.
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+load_lib "trace-support.exp";
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+
+if [istarget "m68k-*-elf"] then {
+ set binfile [board_info target d490_binfile];
+ set srcfile gdb_c_test.c
+} else {
+ set testfile "actions"
+ set srcfile ${testfile}.c
+ set binfile $objdir/$subdir/$testfile
+ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+}
+gdb_reinitialize_dir $srcdir/$subdir
+
+# If testing on a remote host, download the source file.
+# remote_download host $srcdir/$subdir/$srcfile
+
+gdb_file_cmd $binfile
+
+# define relative source line numbers:
+# all subsequent line numbers are relative to this first one (baseline)
+
+set baseline [gdb_find_recursion_test_baseline $srcfile];
+if { $baseline == -1 } then {
+ fail "Could not find gdb_recursion_test function"
+ return;
+}
+
+set testline1 [expr $baseline + 7]
+
+#
+# test actions command
+#
+
+gdb_delete_tracepoints
+set trcpt1 [gdb_gettpnum gdb_c_test];
+set trcpt2 [gdb_gettpnum gdb_asm_test];
+set trcpt3 [gdb_gettpnum $testline1];
+if { $trcpt1 <= 0 || $trcpt2 <= 0 || $trcpt3 <= 0 } then {
+ fail "setting tracepoints"
+ return;
+}
+
+# 5.1 actions of specified tracepoint
+
+send_gdb "info tracepoints\n"
+gdb_expect {
+ -re "Actions for tracepoint \[0-9\]+:.*$gdb_prompt $" {
+ fail "5.1a: testsuite failure (tracepoint already has action)!"
+ }
+ -re "No tracepoints.*$gdb_prompt $" {
+ fail "5.1a: set three tracepoints, no actions (No tracepoints!)"
+ }
+ -re "$gdb_prompt $" {
+ pass "5.1a: set three tracepoints, no actions"
+ }
+}
+
+gdb_trace_setactions "5.1b: set actions for first tracepoint" \
+ "$trcpt1" \
+ "collect gdb_char_test" "^$"
+
+send_gdb "info tracepoints\n"
+gdb_expect {
+ -re "Actions for.* $trcpt1:.*collect gdb_char_test.*$gdb_prompt $" {
+ pass "5.1c: verify actions set for first tracepoint"
+ }
+ -re "$gdb_prompt $" {
+ fail "5.1c: verify actions set for first tracepoint"
+ }
+}
+
+gdb_trace_setactions "5.1d: set actions for second tracepoint" \
+ "$trcpt2" \
+ "collect gdb_short_test" "^$"
+
+send_gdb "info tracepoints\n"
+gdb_expect {
+ -re "Actions for.* $trcpt2:.*collect gdb_short_test.*$gdb_prompt $" {
+ pass "5.1e: verify actions set for second tracepoint"
+ }
+ -re "$gdb_prompt $" {
+ fail "5.1e: verify actions set for second tracepoint"
+ }
+}
+
+gdb_trace_setactions "5.2a: set actions for last (default) tracepoint" \
+ "" \
+ "collect gdb_long_test" "^$"
+
+send_gdb "info tracepoints\n"
+gdb_expect {
+ -re "Actions for.* $trcpt3:.*collect gdb_long_test.*$gdb_prompt $" {
+ pass "5.2b: verify actions set for last (default) tracepoint"
+ }
+ -re "$gdb_prompt $" {
+ fail "5.2b: verify actions set for last (default) tracepoint"
+ }
+}
+
+# 5.3 replace actions set earlier
+
+gdb_trace_setactions "5.3a: reset actions for first tracepoint" \
+ "$trcpt1" \
+ "collect gdb_struct1_test" "^$"
+
+send_gdb "info tracepoints\n"
+gdb_expect {
+ -re "Actions for.* $trcpt1:.*collect gdb_struct1_test.*$gdb_prompt $" {
+ pass "5.3b: verify actions set for first tracepoint"
+ }
+ -re "$gdb_prompt $" {
+ fail "5.3b: verify actions set for first tracepoint"
+ }
+}
+
+#
+# test end command (all by itself)
+#
+
+# 5.4 end outside of context
+
+gdb_test "end" "This command cannot be used at the top level." \
+ "5.4: 'end' command out of context"
+
+# 5.5 empty actions (just an end with no other actions)
+
+gdb_trace_setactions "5.5a: set empty actions for first tracepoint" \
+ "$trcpt1"
+
+send_gdb "info tracepoints\n"
+gdb_expect {
+ -re "No tracepoints.*$gdb_prompt $" {
+ fail "5.5c: verify NO actions for first tracepoint"
+ }
+ -re "Actions for.* $trcpt1:.*$gdb_prompt $" {
+ fail "5.5c: verify NO actions for first tracepoint"
+ }
+ -re "$gdb_prompt $" {
+ pass "5.5c: verify NO actions for first tracepoint"
+ }
+}
+
+# 5.6 actions for invalid tracepoint number
+
+gdb_test "actions [expr $trcpt2 + $trcpt3]" \
+ "No tracepoint number [expr $trcpt2 + $trcpt3]." \
+ "5.6: actions for invalid tracepoint number"
+
+# 5.7 invalid action (other than 'collect', 'while-stepping' or 'end')
+# "warning: .print gdb_c_test. is not a supported trace.*> $" \
+
+gdb_trace_setactions "5.7: invalid action" \
+ "$trcpt1" \
+ "print gdb_c_test" \
+ "warning: .print gdb_c_test. is not a supported trace"
+
+# 5.8 help actions (collect, while-stepping, end)
+
+gdb_test "help actions" \
+ "Specify the actions to be taken at a tracepoint.*" \
+ "5.8a: help actions"
+
+gdb_test "help collect" \
+ "Specify one or more data items to be collected at a tracepoint.*" \
+ "5.8b: help collect"
+
+gdb_test "help while-stepping" \
+ "Specify single-stepping behavior at a tracepoint.*" \
+ "5.8c: help while-stepping"
+
+gdb_test "help end" "Ends a list of commands or actions.*" \
+ "5.8d: help end"
+
diff --git a/gdb/testsuite/gdb.trace/backtrace.exp b/gdb/testsuite/gdb.trace/backtrace.exp
new file mode 100644
index 00000000000..e217f955cd8
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/backtrace.exp
@@ -0,0 +1,376 @@
+# Copyright 1998 Free Software Foundation, Inc.
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+load_lib "trace-support.exp";
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+
+if [istarget "m68k-*-elf"] then {
+ load_lib "emc-support.exp";
+ set srcfile gdb_c_test.c
+ set binfile [board_info target d490_binfile];
+ gdb_test "set remotetimeout 6" "" ""
+ set timeout 500
+ gdb_target_monitor "$binfile"
+ # Give a TSTOP and ignore errors, to make sure any previous trace is off
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ send_gdb "compare-sections CS\n"
+ gdb_expect {
+ -re "MIS-MATCHED.*$gdb_prompt $" {
+ gdb_suppress_entire_file "Symbol file does not match target!
+ all tests in this module will fail.";
+ }
+ -re ".*$gdb_prompt $" { }
+ }
+} else {
+ set testfile "actions"
+ set srcfile ${testfile}.c
+ set binfile $objdir/$subdir/$testfile
+ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ gdb_load $binfile
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ runto_main
+}
+gdb_reinitialize_dir $srcdir/$subdir
+
+# We generously give ourselves one "pass" if we successfully
+# detect that this test cannot be run on this target!
+if { ![gdb_target_supports_trace] } then {
+ pass "Current target does not supporst trace"
+ return 1;
+
+}
+
+#
+# test backtraces in trace frames
+#
+
+set testline1 0
+set testline2 0
+set testline3 0
+set testline4 0
+set testline5 0
+set testline6 0
+
+set arg1 1
+set arg2 2
+set arg3 3
+set arg4 4
+set arg5 5
+set arg6 6
+
+set baseline [gdb_find_recursion_test_baseline $srcfile];
+if { $baseline == -1 } {
+ fail "Could not find gdb_recursion_test function"
+ return;
+}
+
+send_gdb "list $baseline, +12\n"
+gdb_expect {
+ -re "\[\r\n\](\[0-9\]+).*gdbtestline 1 " {
+ set testline1 $expect_out(1,string)
+ exp_continue
+ }
+ -re "\[\r\n\](\[0-9\]+).*gdbtestline 2 " {
+ set testline2 $expect_out(1,string)
+ exp_continue
+ }
+ -re "\[\r\n\](\[0-9\]+).*gdbtestline 3 " {
+ set testline3 $expect_out(1,string)
+ exp_continue
+ }
+ -re "\[\r\n\](\[0-9\]+).*gdbtestline 4 " {
+ set testline4 $expect_out(1,string)
+ exp_continue
+ }
+ -re "\[\r\n\](\[0-9\]+).*gdbtestline 5 " {
+ set testline5 $expect_out(1,string)
+ exp_continue
+ }
+ -re "\[\r\n\](\[0-9\]+).*gdbtestline 6 " {
+ set testline6 $expect_out(1,string)
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" {
+ if { ($testline1 == 0) || ($testline2 == 0) || ($testline3 == 0) || ($testline4 == 0) || ($testline5 == 0) || ($testline6 == 0) } {
+ gdb_suppress_entire_file "failed to locate test source lines:
+all tests in this module will fail."
+ }
+ }
+ default {
+ gdb_suppress_entire_file "failed to locate test source lines (def):
+all tests in this module will fail."
+ }
+}
+
+#
+# Setup backtrace experiment. This will involve:
+# 1) a tracepoint where nothing is collected
+# 2) a tracepoint where only regs are collected
+# 3) a tracepoint where regs, locals and args are collected
+# 4) a tracepoint where regs plus some amount of stack are collected.
+#
+
+gdb_delete_tracepoints
+set tdp2 [gdb_gettpnum $testline2]
+set tdp3 [gdb_gettpnum $testline3]
+set tdp4 [gdb_gettpnum $testline4]
+set tdp5 [gdb_gettpnum $testline5]
+set tdp6 [gdb_gettpnum $testline6]
+if { $tdp2 <= 0 || $tdp3 <= 0 || \
+ $tdp4 <= 0 || $tdp5 <= 0 || $tdp6 <= 0 } then {
+ fail "setting tracepoints failed"
+ return;
+}
+
+#gdb_trace_setactions "setup TP to collect FP" \
+# "$tdp2" \
+# "collect \$fp" ""
+#
+
+gdb_trace_setactions "8.6: setup TP to collect regs" \
+ "$tdp3" \
+ "collect \$regs" "^$"
+
+gdb_trace_setactions "8.6: setup TP to collect regs, args, and locals" \
+ "$tdp4" \
+ "collect \$regs, \$args, \$locs" "^$"
+
+gdb_trace_setactions "8.6: setup TP to collect stack mem cast expr" \
+ "$tdp6" \
+ "collect \$fp, \(\*\(void \*\*\) \(\$sp\)\) @ 64" "^$"
+
+gdb_test "tstart" "" ""
+
+if [istarget "m68k-*-elf"] then {
+ gdb_emclaptop_command "85,$arg1,$arg2,$arg3,$arg4,$arg5,$arg6"
+ sleep 5
+} else {
+ gdb_test "break end" "" ""
+ gdb_test "continue" \
+ "Continuing.*Breakpoint $decimal, end.*" \
+ "run trace experiment"
+}
+
+gdb_test "tstop" "" ""
+
+proc gdb_backtrace_tdp_1 { msg } {
+ global gdb_prompt
+
+ # We are in a trace frame at which we didn't collect anything
+ # except $PC. Therefore we expect to be able to identify stack
+ # frame #0, but that's about all. In particular we do not expect
+ # to be able to display the function's arguments or locals, and we
+ # do not expect to be able to identify the caller of this function.
+
+ send_gdb "backtrace\n"
+ gdb_expect {
+ -re "#0\[\t \]+gdb_recursion_test.*depth=.*$gdb_prompt $" {
+ pass "$msg"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$msg"
+ }
+ timeout { fail "$msg (timeout)" }
+ }
+}
+
+proc gdb_backtrace_tdp_2 { msg } {
+ global gdb_prompt
+
+ # We are in a trace frame at which we collected only the registers
+ # Therefore we expect to be able to identify stack frame #0, but
+ # we don't expect to be able to display its args unles they are
+ # passed in registers (which isn't the case for m68k), and we
+ # don't expect to be able to identify the caller's stack frame.
+
+ send_gdb "backtrace\n"
+ gdb_expect {
+ -re "#0\[\t \]+gdb_recursion_test.*depth=.*$gdb_prompt $" {
+ pass "$msg"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$msg"
+ }
+ timeout { fail "$msg (timeout)" }
+ }
+}
+
+proc gdb_backtrace_tdp_3 { msg } {
+ global gdb_prompt
+
+ # We are in a trace frame at which we collected all registers, all
+ # arguments and all locals. This means that the display of
+ # stack frame #0 should be complete (including argument values).
+
+ send_gdb "backtrace\n"
+ gdb_expect {
+ -re "#0\[\t \]+gdb_recursion_test.*depth=\[0-9\]+.*q1=\[0-9\]+.*q2=\[0-9\]+.*q3=\[0-9\]+.*q4=\[0-9\]+.*q5=\[0-9\]+.*q6=\[0-9\]+.*$gdb_prompt $" {
+ pass "$msg"
+ }
+ -re "#0\[\t \]+gdb_recursion_test.*depth=Cannot access.*$gdb_prompt $" {
+ fail "$msg (failed to collect arguments)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$msg"
+ }
+ timeout { fail "$msg (timeout)" }
+ }
+}
+
+proc gdb_backtrace_tdp_4 { msg depth } {
+ global gdb_prompt
+
+ # We are in a trace frame at which we collected all registers,
+ # plus a sizeable hunk of stack memory. This should enable us to
+ # display at least several stack frames worth of backtrace. We'll
+ # assume that if we can't display at least "depth" levels (with
+ # args), it counts as an error.
+
+ send_gdb "backtrace\n"
+ gdb_expect {
+ -re "#$depth\[\t \].*gdb_recursion_test.*depth=\[0-9\]+.*q1=\[0-9\]+.*q2=\[0-9\]+.*q3=\[0-9\]+.*q4=\[0-9\]+.*q5=\[0-9\]+.*q6=\[0-9\]+.*$gdb_prompt $" {
+ pass "$msg"
+ }
+ -re "#$depth\[\t \].*gdb_recursion_test.*depth=.*$gdb_prompt $" {
+ fail "$msg (args missing from #$depth stack frame)"
+ }
+ -re "#\[0-9\]+\[\t \].*gdb_recursion_test.*depth=.*$gdb_prompt $" {
+ fail "$msg (fewer than $depth stack frames found)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$msg"
+ }
+ timeout { fail "$msg (timeout)" }
+ }
+}
+
+#
+# begin backtrace test
+#
+
+set timeout 60
+
+gdb_tfind_test "init: make sure not debugging any trace frame" "none" "-1"
+
+gdb_tfind_test "8.6: find start frame" "start" "0"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp2:" ""
+gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 1, collect nothing"
+
+gdb_tfind_test "8.6: find frame 1" "1" "1"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp3:" ""
+gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 1, collect regs"
+
+gdb_tfind_test "8.6: find frame 2" "2" "2"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp4:" ""
+gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 1, collect args and locals"
+
+
+gdb_tfind_test "8.6: find frame 4" "4" "4"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp6:" ""
+gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0"
+
+gdb_tfind_test "8.6: find frame 5" "5" "5"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp2:" ""
+gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 2, collect nothing"
+
+gdb_tfind_test "8.6: find frame 6" "6" "6"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp3:" ""
+gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 2, collect regs"
+
+gdb_tfind_test "8.6: find frame 7" "7" "7"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp4:" ""
+gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 2, collect args and locals"
+
+
+gdb_tfind_test "8.6: find frame 9" "9" "9"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp6:" ""
+gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0"
+
+gdb_tfind_test "8.6: find frame 10" "10" "10"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp2:" ""
+gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 3, collect nothing"
+
+gdb_tfind_test "8.6: find frame 11" "11" "11"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp3:" ""
+gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 3, collect regs"
+
+gdb_tfind_test "8.6: find frame 12" "12" "12"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp4:" ""
+gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 3, collect args and locals"
+
+
+gdb_tfind_test "8.6: find frame 14" "14" "14"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp6:" ""
+gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0"
+
+gdb_tfind_test "8.6: find frame 15" "15" "15"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp2:" ""
+gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 4, collect nothing"
+
+gdb_tfind_test "8.6: find frame 16" "16" "16"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp3:" ""
+gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 4, collect regs"
+
+gdb_tfind_test "8.6: find frame 17" "17" "17"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp4:" ""
+gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 4, collect args and locals"
+
+
+gdb_tfind_test "8.6: find frame 19" "19" "19"
+gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
+ "TDP $tdp6:" ""
+gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0"
+
+gdb_test "printf \"x \%d x\\n\", depth == 3" \
+ "x 0 x" \
+ "1.13: trace in recursion: depth not equal to 3"
+
+# Finished!
+gdb_test "tfind none" "" ""
diff --git a/gdb/testsuite/gdb.trace/circ.c b/gdb/testsuite/gdb.trace/circ.c
new file mode 100644
index 00000000000..98a2ce6be54
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/circ.c
@@ -0,0 +1,90 @@
+/*
+ * Test program for tracing; circular buffer
+ */
+
+int n = 6;
+
+int testload[13];
+
+static void func0(void)
+{
+}
+
+static void func1(void)
+{
+}
+
+static void func2(void)
+{
+}
+
+static void func3(void)
+{
+}
+
+static void func4(void)
+{
+}
+
+static void func5(void)
+{
+}
+
+static void func6(void)
+{
+}
+
+static void func7(void)
+{
+}
+
+static void func8(void)
+{
+}
+
+static void func9(void)
+{
+}
+
+static void begin () /* called before anything else */
+{
+}
+
+static void end () /* called after everything else */
+{
+}
+
+int
+main (argc, argv, envp)
+ int argc;
+ char *argv[], **envp;
+{
+ int i;
+
+#ifdef usestubs
+ set_debug_traps ();
+ breakpoint ();
+#endif
+
+ begin ();
+ for (i = 0; i < sizeof(testload) / sizeof(testload[0]); i++)
+ testload[i] = i + 1;
+
+ func0 ();
+ func1 ();
+ func2 ();
+ func3 ();
+ func4 ();
+ func5();
+ func6 ();
+ func7 ();
+ func8 ();
+ func9 ();
+
+ end ();
+
+#ifdef usestubs
+ breakpoint ();
+#endif
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.trace/circ.exp b/gdb/testsuite/gdb.trace/circ.exp
new file mode 100644
index 00000000000..2bfb7a67b70
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/circ.exp
@@ -0,0 +1,215 @@
+# Copyright 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if [istarget "m68k-*-elf"] then {
+ pass "Test not supported on this target"
+ return;
+}
+
+load_lib "trace-support.exp"
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "circ"
+set srcfile ${testfile}.c
+set binfile $objdir/$subdir/$testfile
+
+if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Tests:
+# 1) Set up a trace experiment that will collect approximately 10 frames,
+# requiring more than 512 but less than 1024 bytes of cache buffer.
+# (most targets should have at least 1024 bytes of cache buffer!)
+# Run and confirm that it collects all 10 frames.
+# 2) Artificially limit the trace buffer to 512 bytes, and rerun the
+# experiment. Confirm that the first several frames are collected,
+# but that the last several are not.
+# 3) Set trace buffer to circular mode, still with the artificial limit
+# of 512 bytes, and rerun the experiment. Confirm that the last
+# several frames are collected, but the first several are not.
+#
+
+# return 0 for success, 1 for failure
+proc run_trace_experiment { pass } {
+ gdb_run_cmd
+
+ if [gdb_test "tstart" \
+ "\[\r\n\]*" \
+ "start trace experiment, pass $pass"] then { return 1; }
+ if [gdb_test "continue" \
+ "Continuing.*Breakpoint \[0-9\]+, end.*" \
+ "run to end, pass $pass"] then { return 1; }
+ if [gdb_test "tstop" \
+ "\[\r\n\]*" \
+ "stop trace experiment, pass $pass"] then { return 1; }
+ return 0;
+}
+
+# return 0 for success, 1 for failure
+proc set_a_tracepoint { func } {
+ if [gdb_test "trace $func" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "set tracepoint at $func"] then {
+ return 1;
+ }
+ if [gdb_trace_setactions "set actions for $func" \
+ "" \
+ "collect testload" "^$"] then {
+ return 1;
+ }
+ return 0;
+}
+
+# return 0 for success, 1 for failure
+proc setup_tracepoints { } {
+ gdb_delete_tracepoints
+ if [set_a_tracepoint func0] then { return 1; }
+ if [set_a_tracepoint func1] then { return 1; }
+ if [set_a_tracepoint func2] then { return 1; }
+ if [set_a_tracepoint func3] then { return 1; }
+ if [set_a_tracepoint func4] then { return 1; }
+ if [set_a_tracepoint func5] then { return 1; }
+ if [set_a_tracepoint func6] then { return 1; }
+ if [set_a_tracepoint func7] then { return 1; }
+ if [set_a_tracepoint func8] then { return 1; }
+ if [set_a_tracepoint func9] then { return 1; }
+ return 0;
+}
+
+# return 0 for success, 1 for failure
+proc trace_buffer_normal { } {
+ if [gdb_test "maint packet QTBuffer:size:ffffffff" \
+ "received: .OK." ""] then {
+ pass "This test cannot be run on this target"
+ return 1;
+ }
+ if [gdb_test "maint packet QTBuffer:circular:0" \
+ "received: .OK." ""] then {
+ pass "This test cannot be run on this target"
+ return 1;
+ }
+ return 0;
+}
+
+# return 0 for success, 1 for failure
+proc gdb_trace_circular_tests { } {
+
+ # We generously give ourselves one "pass" if we successfully
+ # detect that this test cannot be run on this target!
+ if { ![gdb_target_supports_trace] } then {
+ pass "Current target does not supporst trace"
+ return 1;
+ }
+
+ if [trace_buffer_normal] then { return 1; }
+
+ gdb_test "break begin" "" ""
+ gdb_test "break end" "" ""
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+
+ if [setup_tracepoints] then { return 1; }
+
+ # First, run the trace experiment with default attributes:
+ # Make sure it behaves as expected.
+ if [run_trace_experiment 1] then { return 1; }
+ if [gdb_test "tfind start" \
+ "#0 func0 .*" \
+ "find frame zero, pass 1"] then { return 1; }
+
+ if [gdb_test "tfind 9" \
+ "#0 func9 .*" \
+ "find frame nine, pass 1"] then { return 1; }
+
+ if [gdb_test "tfind none" \
+ "#0 end .*" \
+ "quit trace debugging, pass 1"] then { return 1; }
+
+ # Then, shrink the trace buffer so that it will not hold
+ # all ten trace frames. Verify that frame zero is still
+ # collected, but frame nine is not.
+ if [gdb_test "maint packet QTBuffer:size:200" \
+ "received: .OK." "shrink the target trace buffer"] then {
+ return 1;
+ }
+ if [run_trace_experiment 2] then { return 1; }
+ if [gdb_test "tfind start" \
+ "#0 func0 .*" \
+ "find frame zero, pass 2"] then { return 1; }
+
+ if [gdb_test "tfind 9" \
+ ".* failed to find .*" \
+ "fail to find frame nine, pass 2"] then { return 1; }
+
+ if [gdb_test "tfind none" \
+ "#0 end .*" \
+ "quit trace debugging, pass 2"] then { return 1; }
+
+ # Finally, make the buffer circular. Now when it runs out of
+ # space, it should wrap around and overwrite the earliest frames.
+ # This means that:
+ # 1) frame zero will be overwritten and therefore unavailable
+ # 2) the earliest frame in the buffer will be other-than-zero
+ # 3) frame nine will be available (unlike on pass 2).
+ if [gdb_test "maint packet QTBuffer:circular:1" \
+ "received: .OK." "make the target trace buffer circular"] then {
+ return 1;
+ }
+ if [run_trace_experiment 3] then { return 1; }
+ if [gdb_test "tfind start" \
+ "#0 func\[1-9\] .*" \
+ "first frame is NOT frame zero, pass 3"] then { return 1; }
+
+ if [gdb_test "tfind 9" \
+ "#0 func9 .*" \
+ "find frame nine, pass 3"] then { return 1; }
+
+ if [gdb_test "tfind none" \
+ "#0 end .*" \
+ "quit trace debugging, pass 3"] then { return 1; }
+
+ return 0;
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+# Body of test encased in a proc so we can return prematurely.
+if { ![gdb_trace_circular_tests] } then {
+ # Set trace buffer attributes back to normal
+ trace_buffer_normal;
+}
+
+# Finished!
+gdb_test "tfind none" "" ""
diff --git a/gdb/testsuite/gdb.trace/collection.c b/gdb/testsuite/gdb.trace/collection.c
new file mode 100644
index 00000000000..39863325b0a
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/collection.c
@@ -0,0 +1,280 @@
+/*
+ * Test program for trace collection
+ */
+
+/*
+ * Typedefs
+ */
+
+typedef struct TEST_STRUCT {
+ char memberc;
+ int memberi;
+ float memberf;
+ double memberd;
+} test_struct;
+
+typedef int test_array [4];
+
+/*
+ * Global variables to be collected
+ */
+
+char globalc;
+int globali;
+float globalf;
+double globald;
+test_struct globalstruct;
+test_struct *globalp;
+int globalarr[16];
+
+/*
+ * Additional globals used in arithmetic tests
+ */
+
+signed char c0, c1, c2, c3, c4, c5, c6, c7,
+ c8, c9, c10, c11, c12, c13, c14, c15, cminus;
+signed short s0, s1, s2, s3, s4, s5, s6, s7,
+ s8, s9, s10, s11, s12, s13, s14, s15, sminus;
+signed long l0, l1, l2, l3, l4, l5, l6, l7,
+ l8, l9, l10, l11, l12, l13, l14, l15, lminus;
+
+
+/*
+ * Test functions
+ */
+
+static void begin () /* called before anything else */
+{
+}
+
+static void end () /* called after everything else */
+{
+}
+
+/* Test collecting args. */
+int args_test_func (argc, argi, argf, argd, argstruct, argarray)
+ char argc;
+ int argi;
+ float argf;
+ double argd;
+ test_struct argstruct;
+ int argarray[4];
+{
+ int i;
+
+ i = (int) argc + argi + argf + argd + argstruct.memberi + argarray[1];
+
+ return i;
+}
+
+/* Test collecting struct args. */
+int argstruct_test_func (argstruct)
+ test_struct argstruct;
+{
+ return (int) argstruct.memberc + argstruct.memberi +
+ argstruct.memberf + argstruct.memberd;
+}
+
+/* Test collecting array args. */
+int argarray_test_func (argarray)
+ int argarray[4];
+{
+ return (int) argarray[0] + argarray[1] + argarray[2] + argarray[3];
+}
+
+
+
+int local_test_func () /* test collecting locals */
+{
+ char locc = 11;
+ int loci = 12;
+ float locf = 13.3;
+ double locd = 14.4;
+ test_struct locst;
+ int locar[4];
+ int i;
+
+ locst.memberc = 15;
+ locst.memberi = 16;
+ locst.memberf = 17.7;
+ locst.memberd = 18.8;
+ locar[0] = 121;
+ locar[1] = 122;
+ locar[2] = 123;
+ locar[3] = 124;
+
+ i = /* Set_Tracepoint_Here */
+ (int) locc + loci + locf + locd + locst.memberi + locar[1];
+
+ return i;
+}
+
+int reglocal_test_func () /* test collecting register locals */
+{
+ register char locc = 11;
+ register int loci = 12;
+ register float locf = 13.3;
+ register double locd = 14.4;
+ register test_struct locst;
+ register int locar[4];
+ int i;
+
+ locst.memberc = 15;
+ locst.memberi = 16;
+ locst.memberf = 17.7;
+ locst.memberd = 18.8;
+ locar[0] = 121;
+ locar[1] = 122;
+ locar[2] = 123;
+ locar[3] = 124;
+
+ i = /* Set_Tracepoint_Here */
+ (int) locc + loci + locf + locd + locst.memberi + locar[1];
+
+ return i;
+}
+
+int statlocal_test_func () /* test collecting static locals */
+{
+ static char locc;
+ static int loci;
+ static float locf;
+ static double locd;
+ static test_struct locst;
+ static int locar[4];
+ int i;
+
+ locc = 11;
+ loci = 12;
+ locf = 13.3;
+ locd = 14.4;
+ locst.memberc = 15;
+ locst.memberi = 16;
+ locst.memberf = 17.7;
+ locst.memberd = 18.8;
+ locar[0] = 121;
+ locar[1] = 122;
+ locar[2] = 123;
+ locar[3] = 124;
+
+ i = /* Set_Tracepoint_Here */
+ (int) locc + loci + locf + locd + locst.memberi + locar[1];
+
+ /* Set static locals back to zero so collected values are clearly special. */
+ locc = 0;
+ loci = 0;
+ locf = 0;
+ locd = 0;
+ locst.memberc = 0;
+ locst.memberi = 0;
+ locst.memberf = 0;
+ locst.memberd = 0;
+ locar[0] = 0;
+ locar[1] = 0;
+ locar[2] = 0;
+ locar[3] = 0;
+
+ return i;
+}
+
+
+int globals_test_func ()
+{
+ int i = 0;
+
+ i += globalc + globali + globalf + globald;
+ i += globalstruct.memberc + globalstruct.memberi;
+ i += globalstruct.memberf + globalstruct.memberd;
+ i += globalarr[1];
+
+ return i; /* Set_Tracepoint_Here */
+}
+
+int
+main (argc, argv, envp)
+ int argc;
+ char *argv[], **envp;
+{
+ int i = 0;
+ test_struct mystruct;
+ int myarray[4];
+
+#ifdef usestubs
+ set_debug_traps ();
+ breakpoint ();
+#endif
+
+ begin ();
+ /* Assign collectable values to global variables. */
+ l0 = s0 = c0 = 0; l1 = s1 = c1 = 1;
+ l2 = s2 = c2 = 2; l3 = s3 = c3 = 3;
+ l4 = s4 = c4 = 4; l5 = s5 = c5 = 5;
+ l6 = s6 = c6 = 6; l7 = s7 = c7 = 7;
+ l8 = s8 = c8 = 8; l9 = s9 = c9 = 9;
+ l10 = s10 = c10 = 10; l11 = s11 = c11 = 11;
+ l12 = s12 = c12 = 12; l13 = s13 = c13 = 13;
+ l14 = s14 = c14 = 14; l15 = s15 = c15 = 15;
+ lminus = sminus = cminus = -2;
+ globalc = 71;
+ globali = 72;
+ globalf = 73.3;
+ globald = 74.4;
+ globalstruct.memberc = 81;
+ globalstruct.memberi = 82;
+ globalstruct.memberf = 83.3;
+ globalstruct.memberd = 84.4;
+ globalp = &globalstruct;
+
+ for (i = 0; i < 15; i++)
+ globalarr[i] = i;
+
+ mystruct.memberc = 101;
+ mystruct.memberi = 102;
+ mystruct.memberf = 103.3;
+ mystruct.memberd = 104.4;
+ myarray[0] = 111;
+ myarray[1] = 112;
+ myarray[2] = 113;
+ myarray[3] = 114;
+
+ /* Call test functions, so they can be traced and data collected. */
+ i = 0;
+ i += args_test_func (1, 2, 3.3, 4.4, mystruct, myarray);
+ i += argstruct_test_func (mystruct);
+ i += argarray_test_func (myarray);
+ i += local_test_func ();
+ i += reglocal_test_func ();
+ i += statlocal_test_func ();
+ i += globals_test_func ();
+
+ /* Values of globals at end of test should be different from
+ values that they had when trace data was captured. */
+
+ l0 = s0 = c0 = 0; l1 = s1 = c1 = 0;
+ l2 = s2 = c2 = 0; l3 = s3 = c3 = 0;
+ l4 = s4 = c4 = 0; l5 = s5 = c5 = 0;
+ l6 = s6 = c6 = 0; l7 = s7 = c7 = 0;
+ l8 = s8 = c8 = 0; l9 = s9 = c9 = 0;
+ l10 = s10 = c10 = 0; l11 = s11 = c11 = 0;
+ l12 = s12 = c12 = 0; l13 = s13 = c13 = 0;
+ l14 = s14 = c14 = 0; l15 = s15 = c15 = 0;
+ lminus = sminus = cminus = 0;
+
+ /* Set 'em back to zero, so that the collected values will be
+ distinctly different from the "realtime" (end of test) values. */
+
+ globalc = 0;
+ globali = 0;
+ globalf = 0;
+ globald = 0;
+ globalstruct.memberc = 0;
+ globalstruct.memberi = 0;
+ globalstruct.memberf = 0;
+ globalstruct.memberd = 0;
+ globalp = 0;
+ for (i = 0; i < 15; i++)
+ globalarr[i] = 0;
+
+ end ();
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.trace/collection.exp b/gdb/testsuite/gdb.trace/collection.exp
new file mode 100644
index 00000000000..a6ac5d80248
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/collection.exp
@@ -0,0 +1,623 @@
+# Copyright 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if [istarget "m68k-*-elf"] then {
+ pass "Test not supported on this target"
+ return;
+}
+
+load_lib "trace-support.exp"
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "collection"
+set srcfile ${testfile}.c
+set binfile $objdir/$subdir/$testfile
+
+if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Tests:
+# 1) $args
+# 2) function args by name
+# 3) $locs
+# 4) function locals by name
+# 5) $regs
+# 6) registers by name ($sp, $fp?)
+# 7) globals by name
+# 8) expressions (lots of different kinds: local and global)
+
+set ws "\[\r\n\t \]+"
+set cr "\[\r\n\]+"
+
+#
+# Utility procs
+#
+
+proc test_register { reg test_id } {
+ global cr
+ global gdb_prompt
+
+ send_gdb "print $reg\n"
+ gdb_expect {
+ -re "\\$\[0-9\]+ = \[x0\]+$cr$gdb_prompt " {
+ fail "collect $test_id: collected $reg (zero)"
+ }
+ -re "\\$\[0-9\]+ = \[x0-9a-fA-F\]+$cr$gdb_prompt " {
+ pass "collect $test_id: collected $reg"
+ }
+ -re "\[Ee\]rror.*$gdb_prompt " {
+ fail "collect $test_id: collected $reg (error)"
+ }
+ timeout {
+ fail "collect $test_id: collected $reg (timeout)"
+ }
+ }
+}
+
+proc run_trace_experiment { msg test_func } {
+ gdb_run_cmd
+ gdb_test "tstart" \
+ "\[\r\n\]+" \
+ "collect $msg: start trace experiment"
+ gdb_test "continue" \
+ "Continuing.*Breakpoint \[0-9\]+, end.*" \
+ "collect $msg: run trace experiment"
+ gdb_test "tstop" \
+ "\[\r\n\]+" \
+ "collect $msg: stop trace experiment"
+ gdb_test "tfind start" \
+ "#0 $test_func .*" \
+ "collect $msg: tfind test frame"
+}
+
+
+#
+# Test procs
+#
+
+proc gdb_collect_args_test { myargs msg } {
+ global cr
+ global gdb_prompt
+
+ # Make sure we're in a sane starting state.
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ gdb_delete_tracepoints
+
+ gdb_test "trace args_test_func" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "collect $msg: set tracepoint"
+ gdb_trace_setactions "collect $msg: define actions" \
+ "" \
+ "collect $myargs" "^$"
+
+ # Begin the test.
+ run_trace_experiment $msg args_test_func
+
+ gdb_test "print argc" \
+ "\\$\[0-9\]+ = 1 '.001'$cr" \
+ "collect $msg: collected arg char"
+ gdb_test "print argi" \
+ "\\$\[0-9\]+ = 2$cr" \
+ "collect $msg: collected arg int"
+ gdb_test "print argf" \
+ "\\$\[0-9\]+ = 3.\[23\]\[0-9\]*$cr" \
+ "collect $msg: collected arg float"
+ gdb_test "print argd" \
+ "\\$\[0-9\]+ = 4.\[34\]\[0-9\]*$cr" \
+ "collect $msg: collected arg double"
+
+ # struct arg as one of several args (near end of list)
+ gdb_test "print argstruct.memberc" \
+ "\\$\[0-9\]+ = 101 'e'$cr" \
+ "collect $msg: collected arg struct member char"
+ gdb_test "print argstruct.memberi" \
+ "\\$\[0-9\]+ = 102$cr" \
+ "collect $msg: collected arg struct member int"
+ gdb_test "print argstruct.memberf" \
+ "\\$\[0-9\]+ = 103.\[23\]\[0-9\]*$cr" \
+ "collect $msg: collected arg struct member float"
+ gdb_test "print argstruct.memberd" \
+ "\\$\[0-9\]+ = 104.\[34\]\[0-9\]*$cr" \
+ "collect $msg: collected arg struct member double"
+
+ # array arg as one of several args (near end of list)
+ gdb_test "print argarray\[0\]" \
+ "\\$\[0-9\]+ = 111$cr" \
+ "collect $msg: collected argarray #0"
+ gdb_test "print argarray\[1\]" \
+ "\\$\[0-9\]+ = 112$cr" \
+ "collect $msg: collected argarray #1"
+ gdb_test "print argarray\[2\]" \
+ "\\$\[0-9\]+ = 113$cr" \
+ "collect $msg: collected argarray #2"
+ gdb_test "print argarray\[3\]" \
+ "\\$\[0-9\]+ = 114$cr" \
+ "collect $msg: collected argarray #3"
+
+ gdb_test "tfind none" \
+ "#0 end .*" \
+ "collect $msg: cease trace debugging"
+}
+
+proc gdb_collect_argstruct_test { myargs msg } {
+ global cr
+ global gdb_prompt
+
+ # Make sure we're in a sane starting state.
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ gdb_delete_tracepoints
+
+ gdb_test "trace argstruct_test_func" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "collect $msg: set tracepoint"
+ gdb_trace_setactions "collect $msg: define actions" \
+ "" \
+ "collect $myargs" "^$"
+
+ # Begin the test.
+ run_trace_experiment $msg argstruct_test_func
+
+ # struct argument as only argument
+ gdb_test "print argstruct.memberc" \
+ "\\$\[0-9\]+ = 101 'e'$cr" \
+ "collect $msg: collected arg struct member char"
+ gdb_test "print argstruct.memberi" \
+ "\\$\[0-9\]+ = 102$cr" \
+ "collect $msg: collected arg struct member int"
+ gdb_test "print argstruct.memberf" \
+ "\\$\[0-9\]+ = 103.\[23\]\[0-9\]*$cr" \
+ "collect $msg: collected arg struct member float"
+ gdb_test "print argstruct.memberd" \
+ "\\$\[0-9\]+ = 104.\[34\]\[0-9\]*$cr" \
+ "collect $msg: collected arg struct member double"
+
+ gdb_test "tfind none" \
+ "#0 end .*" \
+ "collect $msg: cease trace debugging"
+}
+
+
+proc gdb_collect_argarray_test { myargs msg } {
+ global cr
+ global gdb_prompt
+
+ # Make sure we're in a sane starting state.
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ gdb_delete_tracepoints
+
+ gdb_test "trace argarray_test_func" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "collect $msg: set tracepoint"
+ gdb_trace_setactions "collect $msg: define actions" \
+ "" \
+ "collect $myargs" "^$"
+
+ # Begin the test.
+ run_trace_experiment $msg argarray_test_func
+
+ # array arg as only argument
+ gdb_test "print argarray\[0\]" \
+ "\\$\[0-9\]+ = 111$cr" \
+ "collect $msg: collected argarray #0"
+ gdb_test "print argarray\[1\]" \
+ "\\$\[0-9\]+ = 112$cr" \
+ "collect $msg: collected argarray #1"
+ gdb_test "print argarray\[2\]" \
+ "\\$\[0-9\]+ = 113$cr" \
+ "collect $msg: collected argarray #2"
+ gdb_test "print argarray\[3\]" \
+ "\\$\[0-9\]+ = 114$cr" \
+ "collect $msg: collected argarray #3"
+
+ gdb_test "tfind none" \
+ "#0 end .*" \
+ "collect $msg: cease trace debugging"
+}
+
+
+proc gdb_collect_locals_test { func mylocs msg } {
+ global cr
+ global gdb_prompt
+
+ # Make sure we're in a sane starting state.
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ gdb_delete_tracepoints
+
+ # Find the comment-identified line for setting this tracepoint.
+ set testline 0
+ send_gdb "list $func, +30\n"
+ gdb_expect {
+ -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+ Set_Tracepoint_Here .*$gdb_prompt" {
+ set testline $expect_out(1,string)
+ pass "collect $msg: find tracepoint line"
+ }
+ -re ".*$gdb_prompt " {
+ fail "collect $msg: find tracepoint line (skipping locals test)"
+ return
+ }
+ timeout {
+ fail "collect $msg: find tracepoint line (skipping locals test)"
+ return
+ }
+ }
+
+ gdb_test "trace $testline" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "collect $msg: set tracepoint"
+ gdb_trace_setactions "collect $msg: define actions" \
+ "" \
+ "collect $mylocs" "^$"
+
+ # Begin the test.
+ run_trace_experiment $msg $func
+
+ gdb_test "print locc" \
+ "\\$\[0-9\]+ = 11 '.013'$cr" \
+ "collect $msg: collected local char"
+ gdb_test "print loci" \
+ "\\$\[0-9\]+ = 12$cr" \
+ "collect $msg: collected local int"
+ gdb_test "print locf" \
+ "\\$\[0-9\]+ = 13.\[23\]\[0-9\]*$cr" \
+ "collect $msg: collected local float"
+ gdb_test "print locd" \
+ "\\$\[0-9\]+ = 14.\[34\]\[0-9\]*$cr" \
+ "collect $msg: collected local double"
+
+ gdb_test "print locst.memberc" \
+ "\\$\[0-9\]+ = 15 '.017'$cr" \
+ "collect $msg: collected local member char"
+ gdb_test "print locst.memberi" \
+ "\\$\[0-9\]+ = 16$cr" \
+ "collect $msg: collected local member int"
+ gdb_test "print locst.memberf" \
+ "\\$\[0-9\]+ = 17.\[67\]\[0-9\]*$cr" \
+ "collect $msg: collected local member float"
+ gdb_test "print locst.memberd" \
+ "\\$\[0-9\]+ = 18.\[78\]\[0-9\]*$cr" \
+ "collect $msg: collected local member double"
+
+ gdb_test "print locar\[0\]" \
+ "\\$\[0-9\]+ = 121$cr" \
+ "collect $msg: collected locarray #0"
+ gdb_test "print locar\[1\]" \
+ "\\$\[0-9\]+ = 122$cr" \
+ "collect $msg: collected locarray #1"
+ gdb_test "print locar\[2\]" \
+ "\\$\[0-9\]+ = 123$cr" \
+ "collect $msg: collected locarray #2"
+ gdb_test "print locar\[3\]" \
+ "\\$\[0-9\]+ = 124$cr" \
+ "collect $msg: collected locarray #3"
+
+
+ gdb_test "tfind none" \
+ "#0 end .*" \
+ "collect $msg: cease trace debugging"
+}
+
+proc gdb_collect_registers_test { myregs } {
+ global cr
+ global gdb_prompt
+
+ # Make sure we're in a sane starting state.
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ gdb_delete_tracepoints
+
+ # We'll simply re-use the args_test_function for this test
+ gdb_test "trace args_test_func" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "collect $myregs: set tracepoint"
+ gdb_trace_setactions "collect $myregs: define actions" \
+ "" \
+ "collect $myregs" "^$"
+
+ # Begin the test.
+ run_trace_experiment $myregs args_test_func
+
+ test_register "\$fp" $myregs
+ test_register "\$sp" $myregs
+ test_register "\$pc" $myregs
+
+ gdb_test "tfind none" \
+ "#0 end .*" \
+ "collect $myregs: cease trace debugging"
+}
+
+proc gdb_collect_expression_test { func expr val msg } {
+ global cr
+ global gdb_prompt
+
+ # Make sure we're in a sane starting state.
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ gdb_delete_tracepoints
+
+ # Find the comment-identified line for setting this tracepoint.
+ set testline 0
+ send_gdb "list $func, +30\n"
+ gdb_expect {
+ -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+ Set_Tracepoint_Here .*$gdb_prompt" {
+ set testline $expect_out(1,string)
+ pass "collect $msg: find tracepoint line"
+ }
+ -re ".*$gdb_prompt " {
+ fail "collect $msg: find tracepoint line (skipping locals test)"
+ return
+ }
+ timeout {
+ fail "collect $msg: find tracepoint line (skipping locals test)"
+ return
+ }
+ }
+
+ gdb_test "trace $testline" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "collect $msg: set tracepoint"
+ gdb_trace_setactions "collect $msg: define actions" \
+ "" \
+ "collect $expr" "^$"
+
+ # Begin the test.
+ run_trace_experiment $msg $func
+
+ gdb_test "print $expr" \
+ "\\$\[0-9\]+ = $val$cr" \
+ "collect $msg: got expected value '$val'"
+
+ gdb_test "tfind none" \
+ "#0 end .*" \
+ "collect $msg: cease trace debugging"
+}
+
+proc gdb_collect_globals_test { } {
+ global cr
+ global gdb_prompt
+
+ # Make sure we're in a sane starting state.
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ gdb_delete_tracepoints
+
+ # Find the comment-identified line for setting this tracepoint.
+ set testline 0
+ send_gdb "list globals_test_func, +30\n"
+ gdb_expect {
+ -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+ Set_Tracepoint_Here .*$gdb_prompt" {
+ set testline $expect_out(1,string)
+ pass "collect globals: find tracepoint line"
+ }
+ -re ".*$gdb_prompt " {
+ fail "collect globals: find tracepoint line (skipping global test)"
+ return
+ }
+ timeout {
+ fail "collect globals: find tracepoint line (skipping global test)"
+ return
+ }
+ }
+
+ gdb_test "trace $testline" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "collect globals: set tracepoint"
+ gdb_trace_setactions "collect globals: define actions" \
+ "" \
+ "collect globalc, globali, globalf, globald" "^$" \
+ "collect globalstruct, globalp, globalarr" "^$"
+
+ # Begin the test.
+ run_trace_experiment "globals" globals_test_func
+
+ gdb_test "print globalc" \
+ "\\$\[0-9\]+ = 71 'G'$cr" \
+ "collect globals: collected global char"
+ gdb_test "print globali" \
+ "\\$\[0-9\]+ = 72$cr" \
+ "collect globals: collected global int"
+ gdb_test "print globalf" \
+ "\\$\[0-9\]+ = 73.\[23\]\[0-9\]*$cr" \
+ "collect globals: collected global float"
+ gdb_test "print globald" \
+ "\\$\[0-9\]+ = 74.\[34\]\[0-9\]*$cr" \
+ "collect globals: collected global double"
+
+ gdb_test "print globalstruct.memberc" \
+ "\\$\[0-9\]+ = 81 'Q'$cr" \
+ "collect globals: collected struct char member"
+ gdb_test "print globalstruct.memberi" \
+ "\\$\[0-9\]+ = 82$cr" \
+ "collect globals: collected struct member int"
+ gdb_test "print globalstruct.memberf" \
+ "\\$\[0-9\]+ = 83.\[23\]\[0-9\]*$cr" \
+ "collect globals: collected struct member float"
+ gdb_test "print globalstruct.memberd" \
+ "\\$\[0-9\]+ = 84.\[34\]\[0-9\]*$cr" \
+ "collect globals: collected struct member double"
+
+ gdb_test "print globalp == &globalstruct" \
+ "\\$\[0-9\]+ = 1$cr" \
+ "collect globals: collected global pointer"
+
+ gdb_test "print globalarr\[1\]" \
+ "\\$\[0-9\]+ = 1$cr" \
+ "collect globals: collected global array element #1"
+ gdb_test "print globalarr\[2\]" \
+ "\\$\[0-9\]+ = 2$cr" \
+ "collect globals: collected global array element #2"
+ gdb_test "print globalarr\[3\]" \
+ "\\$\[0-9\]+ = 3$cr" \
+ "collect globals: collected global array element #3"
+
+ gdb_test "tfind none" \
+ "#0 end .*" \
+ "collect globals: cease trace debugging"
+}
+
+proc gdb_trace_collection_test { } {
+ global gdb_prompt;
+
+ gdb_test "set width 0" "" ""
+ delete_breakpoints
+
+ # We generously give ourselves one "pass" if we successfully
+ # detect that this test cannot be run on this target!
+ if { ![gdb_target_supports_trace] } then {
+ pass "Current target does not supporst trace"
+ return 1;
+ }
+
+ gdb_test "break begin" "" ""
+ gdb_test "break end" "" ""
+ gdb_collect_args_test "\$args" \
+ "args collectively"
+ gdb_collect_args_test "argc, argi, argf, argd, argstruct, argarray" \
+ "args individually"
+ gdb_collect_argstruct_test "\$args" \
+ "argstruct collectively"
+ gdb_collect_argstruct_test "argstruct" \
+ "argstruct individually"
+ gdb_collect_argarray_test "\$args" \
+ "argarray collectively"
+ gdb_collect_argarray_test "argarray" \
+ "argarray individually"
+ gdb_collect_locals_test local_test_func "\$locals" \
+ "auto locals collectively"
+ gdb_collect_locals_test local_test_func \
+ "locc, loci, locf, locd, locst, locar" \
+ "auto locals individually"
+ gdb_collect_locals_test reglocal_test_func "\$locals" \
+ "register locals collectively"
+ gdb_collect_locals_test reglocal_test_func \
+ "locc, loci, locf, locd, locst, locar" \
+ "register locals individually"
+ gdb_collect_locals_test statlocal_test_func "\$locals" \
+ "static locals collectively"
+ gdb_collect_locals_test statlocal_test_func \
+ "locc, loci, locf, locd, locst, locar" \
+ "static locals individually"
+
+ gdb_collect_registers_test "\$regs"
+ gdb_collect_registers_test "\$fp, \$sp, \$pc"
+ gdb_collect_globals_test
+
+ #
+ # Expression tests:
+ #
+ # *x (**x, ...)
+ # x.y (x.y.z, ...)
+ # x->y (x->y->z, ...)
+ # x[2] (x[2][3], ...) (const index)
+ # x[y] (x[y][z], ...) (index to be char, short, long, float, double)
+ # NOTE:
+ # We test the following operators by using them in an array index
+ # expression -- because the naked result of an operator is not really
+ # collected. To be sure the operator was evaluated correctly on the
+ # target, we have to actually use the result eg. in an array offset
+ # calculation.
+ # x[y + z] (tests addition: y and z various combos of types, sclasses)
+ # x[y - z] (tests subtraction) (ditto)
+ # x[y * z] (tests multiplication) (ditto)
+ # x[y / z] (tests division) (ditto)
+ # x[y % z] (tests modulo division) (ditto)
+ # x[y == z] (tests equality relation) (ditto) UNSUPPORTED
+ # x[y != z] (tests inequality relation) (ditto) UNSUPPORTED
+ # x[y > z] (tests greater-than relation) (ditto) UNSUPPORTED
+ # x[y < z] (tests less-than relation) (ditto) UNSUPPORTED
+ # x[y >= z] (tests greater-than-or-equal relation) (ditto) UNSUPPORTED
+ # x[y <= z] (tests less-than-or-equal relation) (ditto) UNSUPPORTED
+ # x[y && z] (tests logical and) (ditto) UNSUPPORTED
+ # x[y || z] (tests logical or) (ditto) UNSUPPORTED
+ # x[y & z] (tests binary and) (ditto) UNSUPPORTED
+ # x[y | z] (tests binary or) (ditto) UNSUPPORTED
+ # x[y ^ z] (tests binary xor) (ditto) UNSUPPORTED
+ # x[y ? z1 : z2] (tests ternary operator) (ditto) UNSUPPORTED
+ # x[y << z] (tests shift-left) (ditto) UNSUPPORTED
+ # x[y >> z] (tests shift-right) (ditto) UNSUPPORTED
+ # x[y = z] (tests assignment operator) (ditto) UNSUPPORTED
+ # x[++y] (tests pre-increment operator) (ditto) UNSUPPORTED
+ # x[--y] (tests pre-decrement operator) (ditto) UNSUPPORTED
+ # x[y++] (tests post-increment operator) (ditto) UNSUPPORTED
+ # x[y--] (tests post-decrement operator) (ditto) UNSUPPORTED
+ # x[+y] (tests unary plus) (ditto)
+ # x[-y] (tests unary minus) (ditto)
+ # x[!y] (tests logical not) (ditto) UNSUPPORTED
+ # x[~y] (tests binary not) (ditto) UNSUPPORTED
+ # x[(y, z)] (tests comma expression) (ditto)
+ # cast expr
+ # stack data
+
+ gdb_collect_expression_test globals_test_func \
+ "globalstruct.memberi" "82" "a.b"
+ gdb_collect_expression_test globals_test_func \
+ "globalp->memberc" "81 'Q'" "a->b"
+ gdb_collect_expression_test globals_test_func \
+ "globalarr\[2\]" "2" "a\[2\]"
+ gdb_collect_expression_test globals_test_func \
+ "globalarr\[l3\]" "3" "a\[b\]"
+ gdb_collect_expression_test globals_test_func \
+ "globalarr\[l3 + l2\]" "5" "a\[b + c\]"
+ gdb_collect_expression_test globals_test_func \
+ "globalarr\[l3 - l2\]" "1" "a\[b - c\]"
+ gdb_collect_expression_test globals_test_func \
+ "globalarr\[l3 * l2\]" "6" "a\[b * c\]"
+ gdb_collect_expression_test globals_test_func \
+ "globalarr\[l6 / l3\]" "2" "a\[b / c\]"
+ gdb_collect_expression_test globals_test_func \
+ "globalarr\[l7 % l3\]" "1" "a\[b % c\]"
+ gdb_collect_expression_test globals_test_func \
+ "globalarr\[+l1\]" "1" "a\[+b\]"
+ gdb_collect_expression_test globals_test_func \
+ "globalarr\[-lminus\]" "2" "a\[-b\]"
+ gdb_collect_expression_test globals_test_func \
+ "globalarr\[\(l6, l7\)\]" "7" "a\[\(b, c\)\]"
+
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+
+# Body of test encased in a proc so we can return prematurely.
+gdb_trace_collection_test
+
+# Finished!
+gdb_test "tfind none" "" ""
+
+
+
diff --git a/gdb/testsuite/gdb.trace/configure b/gdb/testsuite/gdb.trace/configure
new file mode 100755
index 00000000000..417620553ee
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/configure
@@ -0,0 +1,899 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+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=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --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.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_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]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -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 ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --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=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -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=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -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=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=collection.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+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'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:573: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:594: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:612: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ 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.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+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%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gdb/testsuite/gdb.trace/configure.in b/gdb/testsuite/gdb.trace/configure.in
new file mode 100644
index 00000000000..6d0eae2674b
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/configure.in
@@ -0,0 +1,15 @@
+dnl Process this file file with autoconf to produce a configure script.
+dnl This file is a shell script fragment that supplies the information
+dnl necessary to tailor a template configure script into the configure
+dnl script appropriate for this directory. For more information, check
+dnl any existing configure script.
+
+AC_PREREQ(2.5)
+AC_INIT(collection.c)
+
+CC=${CC-cc}
+AC_SUBST(CC)
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
+AC_CANONICAL_SYSTEM
+
+AC_OUTPUT(Makefile)
diff --git a/gdb/testsuite/gdb.trace/deltrace.exp b/gdb/testsuite/gdb.trace/deltrace.exp
new file mode 100644
index 00000000000..58a69ba2442
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/deltrace.exp
@@ -0,0 +1,269 @@
+# Copyright 1998, 1999 Free Software Foundation, Inc.
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+load_lib "trace-support.exp";
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+
+if [istarget "m68k-*-elf"] then {
+ set srcfile gdb_c_test.c
+ set binfile [board_info target d490_binfile];
+} else {
+ set testfile "actions"
+ set srcfile ${testfile}.c
+ set binfile $objdir/$subdir/$testfile
+ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+}
+gdb_reinitialize_dir $srcdir/$subdir
+
+# If testing on a remote host, download the source file.
+# remote_download host $srcdir/$subdir/$srcfile
+
+gdb_file_cmd $binfile
+
+# define relative source line numbers:
+# all subsequent line numbers are relative to this first one (baseline)
+set baseline [gdb_find_recursion_test_baseline $srcfile];
+if { $baseline == -1 } then {
+ fail "Could not find gdb_recursion_test function"
+ return;
+}
+set testline1 [expr $baseline + 4]
+
+#
+# test "delete tracepoints" command
+#
+
+# 3.1 delete tracepoints (all)
+gdb_delete_tracepoints
+gdb_test "trace gdb_c_test" "Tracepoint \[0-9\]+ at .*" "set tracepoint 1"
+gdb_test "trace gdb_asm_test" "Tracepoint \[0-9\]+ at .*" "set tracepoint 2"
+gdb_test "trace $testline1" "Tracepoint \[0-9\]+ at .*" "set tracepoint 3"
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*\[0-9\]+\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_c_test.*\[0-9\]+\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*\[0-9\]+\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_recursion_test.*" \
+ "3.1a: set three tracepoints"
+
+send_gdb "delete tracepoints\n"
+gdb_expect 30 {
+ -re "Delete all tracepoints.*y or n.*$" {
+ send_gdb "y\n"
+ gdb_expect 30 {
+ -re "$gdb_prompt $" {
+ pass "3.1b: delete all tracepoints"
+ }
+ timeout { fail "3.1b: delete all tracepoints (timeout)" }
+ }
+ }
+ -re "$gdb_prompt $" { # This should only happen if there are no tracepoints
+ fail "3.1b: delete all tracepoints (no tracepoints?)"
+ }
+ timeout { fail "3.1b: delete all tracepoints (timeout)" }
+}
+
+# 3.2 delete tracepoint <n>
+gdb_delete_tracepoints
+set trcpt1 [gdb_gettpnum gdb_c_test];
+set trcpt2 [gdb_gettpnum gdb_asm_test];
+set trcpt3 [gdb_gettpnum $testline1];
+if { $trcpt1 <= 0 || $trcpt2 <= 0 || $trcpt3 <= 0 } then {
+ fail "setting tracepoints"
+ return;
+}
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in.*gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in.*gdb_recursion_test.*" \
+ "3.2a: set three tracepoints"
+
+#gdb_test "delete tracepoint $trcpt1" "" ""
+send_gdb "delete tracepoint $trcpt1\n"
+gdb_expect {
+ -re "No tracepoint number.*$gdb_prompt $" {
+ fail "3.2b: delete first tracepoint"
+ }
+ -re ".*\[Ee\]rror.*$gdb_prompt $" {
+ fail "3.2b: delete first tracepoint"
+ }
+ -re "$gdb_prompt $" {
+ pass "3.2b: delete first tracepoint"
+ }
+ timeout {
+ fail "3.2b: delete first tracepoint (timeout)"
+ }
+}
+
+send_gdb "info tracepoints\n"
+gdb_expect {
+ -re "$trcpt1\[\t \]+y\[\t \]+0x.*in.*gdb_c_test.*$gdb_prompt $" {
+ fail "3.2c: verify delete first tracepoint (argh)"
+ }
+ -re "$trcpt2\[\t \]+y.*gdb_asm_test.*\[\r\n\t ]+$trcpt3\[\t \]+y.* in gdb_recursion_test at .*$gdb_prompt $" {
+ pass "3.2c: verify delete first tracepoint"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "3.2c: verify delete first tracepoint (mumble)"
+ }
+ timeout {
+ fail "3.2c: verify delete first tracepoint (timeout)"
+ }
+}
+
+#gdb_test "delete tracepoint $trcpt2" "" ""
+send_gdb "delete tracepoint $trcpt2\n"
+gdb_expect {
+ -re "No tracepoint number.*$gdb_prompt $" {
+ fail "3.2d: delete second tracepoint"
+ }
+ -re ".*\[Ee\]rror.*$gdb_prompt $" {
+ fail "3.2d: delete second tracepoint"
+ }
+ -re "$gdb_prompt $" {
+ pass "3.2d: delete second tracepoint"
+ }
+ timeout {
+ fail "3.2d: delete second tracepoint (timeout)"
+ }
+}
+
+send_gdb "info tracepoints\n"
+gdb_expect {
+ -re "$trcpt1\[\t \]+y\[\t \]+0x.*in.*gdb_c_test.*$gdb_prompt $" {
+ fail "3.2e: verify delete second tracepoint"
+ }
+ -re "$trcpt2\[\t \]+y\[\t \]+0x.*in gdb_asm_test.*$gdb_prompt $" {
+ fail "3.2e: verify delete second tracepoint"
+ }
+ -re "$trcpt3\[\t \]+y\[\t \]+0x.*in gdb_recursion_test.*$gdb_prompt $" {
+ pass "3.2e: verify delete second tracepoint"
+ }
+ -re "$gdb_prompt $" {
+ fail "3.2e: verify delete second tracepoint"
+ }
+ timeout {
+ fail "3.2e: verify delete second tracepoint (timeout)"
+ }
+}
+
+#gdb_test "delete tracepoint $trcpt3" "" ""
+send_gdb "delete tracepoint $trcpt3\n"
+gdb_expect {
+ -re "No tracepoint number.*$gdb_prompt $" {
+ fail "3.2f: delete third tracepoint"
+ }
+ -re ".*\[Ee\]rror.*$gdb_prompt $" {
+ fail "3.2f: delete third tracepoint"
+ }
+ -re "$gdb_prompt $" {
+ pass "3.2f: delete third tracepoint"
+ }
+ timeout {
+ fail "3.2f: delete third tracepoint (timeout)"
+ }
+}
+
+# send_gdb "ARF! \\n\n"
+send_gdb "info tracepoints\n"
+gdb_expect {
+ -re "$trcpt3\[\t \]+y\[\t \]+0x.*in gdb_recursion_test.*$gdb_prompt $" {
+ fail "3.2g: verify delete third tracepoint"
+ }
+ -re "$gdb_prompt $" {
+ pass "3.2g: verify delete third tracepoint"
+ }
+ timeout {
+ fail "3.2g: verify delete third tracepoint (timeout)"
+ }
+}
+
+# 3.3 delete three tracepoints at once
+gdb_delete_tracepoints
+set trcpt1 [gdb_gettpnum gdb_c_test];
+set trcpt2 [gdb_gettpnum gdb_asm_test];
+set trcpt3 [gdb_gettpnum $testline1];
+if { $trcpt1 <= 0 || $trcpt2 <= 0 || $trcpt3 <= 0 } then {
+ fail "setting tracepoints"
+ return;
+}
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_recursion_test.*" \
+ "3.3a: set three tracepoints"
+
+#gdb_test "delete tracepoint $trcpt1 $trcpt2 $trcpt3" "" ""
+send_gdb "delete tracepoint $trcpt1 $trcpt2 $trcpt3\n"
+gdb_expect {
+ -re "No tracepoint number.*$gdb_prompt $" {
+ fail "3.3b: delete three tracepoints"
+ }
+ -re ".*\[Ee\]rror.*$gdb_prompt $" {
+ fail "3.3b: delete three tracepoints"
+ }
+ -re "$gdb_prompt $" {
+ pass "3.3b: delete three tracepoints"
+ }
+ timeout {
+ fail "3.3b: delete three tracepoint (timeout)"
+ }
+}
+
+send_gdb "info tracepoints\n"
+gdb_expect {
+ -re "$trcpt1\[\t \]+y\[\t \]+0x.*in gdb_c_test.*$gdb_prompt $" {
+ fail "3.3c: verify delete three tracepoints (first one persists)"
+ }
+ -re "$trcpt2\[\t \]+y\[\t \]+0x.*in gdb_asm_test.*$gdb_prompt $" {
+ fail "3.3c: verify delete three tracepoints (second one persists)"
+ }
+ -re "$trcpt3\[\t \]+y\[\t \]+0x.*in gdb_recursion_test.*$gdb_prompt $" {
+ fail "3.3c: verify delete three tracepoints (third one persists)"
+ }
+ -re "$gdb_prompt $" {
+ pass "3.3c: verify delete three tracepoints"
+ }
+ timeout {
+ fail "3.3c: verify delete three tracepoints (timeout)"
+ }
+}
+
+# 3.4 delete invalid tracepoint number
+gdb_test "delete tracepoint [expr $trcpt2 + $trcpt3]" \
+ "No tracepoint number [expr $trcpt2 + $trcpt3]." \
+ "3.4: delete invalid tracepoint number"
+
+# 3.5 delete tracepoint number zero
+gdb_test "delete tracepoint 0" "bad tracepoint number at or near '0'" \
+ "3.5: delete tracepoint number zero"
+
+# 3.6 help delete tracepoints
+gdb_test "help delete tracepoints" \
+ "Delete specified tracepoints.*" \
+ "3.6: help delete tracepoints"
diff --git a/gdb/testsuite/gdb.trace/gdb_c_test.c b/gdb/testsuite/gdb.trace/gdb_c_test.c
new file mode 100644
index 00000000000..03382c27d77
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/gdb_c_test.c
@@ -0,0 +1,3792 @@
+/*
+ ******************************************************************************
+ ******************************************************************************
+ *
+ * COPYRIGHT (C) by EMC Corporation, 1997 All rights reserved.
+ * $Id$
+ * DESCRIPTION: This module has been provided for the purpose of testing GDB.
+ *
+ * NOTES:
+ *
+ ******************************************************************************
+ *****************************************************************************/
+
+/*=============================================================================
+ * INCLUDE FILES
+ *===========================================================================*/
+
+
+#ifdef DO_IT_BY_THE_BOOK
+
+
+#include "symtypes_defs.h"
+#include "printp.h"
+
+#include "adbg_expression.h"
+#include "common_hw_ds.h"
+#include "common_hw_defs.h"
+#include "evnttrac.h"
+#include "sym_scratch_ds.h"
+#include "symglob_ds.h"
+#include "sym_protglob_ds.h"
+
+#include "ether.h"
+
+#include <ctype.h>
+
+
+#else
+
+#include "adbg_dtc.h"
+
+#define YES 1
+#define NO 0
+
+#define TRUE 1
+#define FALSE 0
+
+#define ENABLED 1
+#define DISABLED 0
+
+#define CONTROL_C 3 /* ASCII 'ETX' */
+
+
+/*
+ * Faked after ctype.h
+ */
+
+#define isxdigit(X) (((X) >= '0' && (X) <= '9') || \
+ ((X) >= 'A' && (X) <= 'F') || \
+ ((X) >= 'a' && (X) <= 'f'))
+/*
+ * Borrowed from string.h
+ */
+
+extern unsigned int strlen ( const char * );
+
+/*
+ * Extracted from symtypes.h:
+ */
+
+typedef char BOOL; /* 8 Bits */
+typedef unsigned char UCHAR; /* 8 Bits */
+typedef unsigned short USHORT; /* 16 Bits */
+typedef unsigned long ULONG; /* 32 Bits */
+
+/*
+ * for struct t_expr_tag and
+ * decl of build_and_add_expression
+ */
+#include "adbg_expression.h"
+#define NULL 0
+
+/*
+ * Extracted from printp.h:
+ */
+
+extern void printp ( const char * fptr, ... );
+extern void sprintp ( const char * fptr, ... );
+
+/*
+ * Extracted from ether.h:
+ */
+
+extern long eth_to_gdb ( UCHAR *buf, long length );
+
+
+/*
+ * Derived from hwequs.s:
+ */
+
+#define CS_CODE_START 0x100000
+#define CS_CODE_SIZE 0x200000
+#define LAST_CS_WORD (CS_CODE_START + CS_CODE_SIZE - 2)
+
+#define sh_genstat1 (*((volatile ULONG *) 0xFFFFFE54))
+
+#define rs232_mode1 0 /* rs-232 mode 1 reg. */
+#define rs232_mode2 rs232_mode1 /* rs-232 mode 2 reg. */
+#define rs232_stat 4 /* rs-232 status reg. */
+#define rs232_clk rs232_stat /* rs-232 clock select reg. */
+#define rs232_cmd 8 /* rs-232 command reg */
+#define rs232_transmit 12 /* rs-232 transmit reg. */
+#define rs232_receive rs232_transmit /* rs-232 transmit reg. */
+#define rs232_aux 16 /* rs-232 aux control reg. */
+#define rs232_isr 20 /* rs-232 interrupt status reg. */
+#define rs232_imr rs232_isr /* rs-232 interrupt mask reg. */
+#define rs232_tc_high 24 /* rs-232 timer/counter high reg. */
+#define rs232_tc_low 28 /* rs-232 timer/counter low reg. */
+
+
+#endif
+
+
+/*============================================================================
+ * MODULE DEFINES
+ *===========================================================================*/
+
+#define P_RST_LAN_UART_REG ((volatile UCHAR *) 0xFFFFFE45)
+#define M_RST_LAN_UART 0x80 /* Bit 7 */
+
+#define P_LAN0TR_REG P_RST_LAN_UART_REG
+#define M_LAN0TR 0x20 /* Bit 5 */
+
+#define M_SH_GENCON_LAN0TR 0x00200000 /* Bit 21 */
+
+#define MAX_RS232_CHARS 512
+
+#define LAN_Q_MOD(X) ((X) % MAX_RS232_CHARS)
+
+/*---------------------------------------*
+ * LAN UART Registers *
+ *---------------------------------------*/
+
+#define LAN_UART_BASE ((ULONG) 0xfffffc22)
+
+/* Write-Read */
+
+#define P_LAN_MR1 ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_mode1 )))
+#define P_LAN_MR2 ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_mode2 )))
+
+/* Write-Only */
+
+#define P_LAN_ACR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_aux )))
+#define P_LAN_CR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_cmd )))
+#define P_LAN_CSR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_clk )))
+#define P_LAN_CTLR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_tc_low )))
+#define P_LAN_CTUR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_tc_high )))
+#define P_LAN_IMR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_imr )))
+
+/* Read-Only */
+
+#define P_LAN_SR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_stat )))
+#define P_LAN_ISR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_isr )))
+#define P_LAN_XMT ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_transmit)))
+#define P_LAN_RCV ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_receive )))
+
+/*
+ * Bit Values for Write-Read and Write-Only Registers
+ */
+
+#define DEFAULT_LAN_MR1 ((UCHAR) 0x13)
+#define DEFAULT_LAN_MR2 ((UCHAR) 0x07)
+#define DEFAULT_LAN_CSR ((UCHAR) 0xcc)
+#define DEFAULT_LAN_ACR ((UCHAR) 0x38)
+#define DEFAULT_LAN_CTUR ((UCHAR) 0xff)
+#define DEFAULT_LAN_CTLR ((UCHAR) 0xff)
+
+#define LAN_ACR_SELECT_BRG_0 DEFAULT_LAN_ACR
+#define LAN_ACR_SELECT_BRG_1 (DEFAULT_LAN_ACR | 0x80)
+
+#define UART_CR_RESET_MR_PTR ((UCHAR) 0x10) /* Reset MR pointer (points to MR1). */
+#define UART_CR_RESET_RVCR ((UCHAR) 0x20) /* Reset receiver (disabled). */
+#define UART_CR_RESET_XMTR ((UCHAR) 0x30) /* Reset transmitter (disabled). */
+#define UART_CR_RESET_ERROR_STATUS ((UCHAR) 0x40) /* Reset error status. */
+#define UART_CR_RESET_BRK_CHG_INT ((UCHAR) 0x50) /* Reset break change interrupt. */
+#define UART_CR_START_CNTR_TIMER ((UCHAR) 0x80) /* Start counter/timer. */
+#define UART_CR_STOP_CNTR ((UCHAR) 0x90) /* Stop counter. */
+
+#define UART_CR_DISABLE_XMTR ((UCHAR) 0x08) /* Disable transmitter. */
+#define UART_CR_ENABLE_XMTR ((UCHAR) 0x04) /* Enable transmitter. */
+#define UART_CR_DISABLE_RCVR ((UCHAR) 0x02) /* Disable receiver. */
+#define UART_CR_ENABLE_RCVR ((UCHAR) 0x01) /* Enable receiver. */
+
+#define UART_CSR_BR_4800 ((UCHAR) 0x99) /* With either BRG Set selected (via ACR). */
+#define UART_CSR_BR_9600 ((UCHAR) 0xbb) /* With either BRG Set selected (via ACR). */
+#define UART_CSR_BR_19200 ((UCHAR) 0xcc) /* With BRG Set '1' selected (via ACR). */
+#define UART_CSR_BR_38400 ((UCHAR) 0xcc) /* With BRG Set '0' selected (via ACR). */
+
+#define UART_IMR_RxRDY ((UCHAR) 0x04) /* Enable 'RxRDY' interrupt. */
+#define UART_IMR_TxEMT ((UCHAR) 0x02) /* Enable 'TxEMT' interrupt. */
+#define UART_IMR_TxRDY ((UCHAR) 0x01) /* Enable 'TxRDY' interrupt. */
+
+/*
+ * Bit Masks for Read-Only Registers
+ */
+
+#define M_UART_SR_RCVD_BRK 0x80 /* Bit 7 */
+#define M_UART_SR_FE 0x40 /* Bit 6 */
+#define M_UART_SR_PE 0x20 /* Bit 5 */
+#define M_UART_SR_OE 0x10 /* Bit 4 */
+#define M_UART_SR_TxEMT 0x08 /* Bit 3 */
+#define M_UART_SR_TxRDY 0x04 /* Bit 2 */
+#define M_UART_SR_FFULL 0x02 /* Bit 1 */
+#define M_UART_SR_RxRDY 0x01 /* Bit 0 */
+
+#define M_UART_ISR_RxRDY 0x04 /* Bit 2 */
+#define M_UART_ISR_TxEMT 0x02 /* Bit 1 */
+#define M_UART_ISR_TxRDY 0x01 /* Bit 0 */
+
+/*---------------------------------------*
+ * Support for 'Utility 83'. *
+ *---------------------------------------*/
+
+#define LAN_UTIL_CODE 0x83
+
+#define LAN_INIT ((ULONG) (('I' << 24) | ('N' << 16) | ('I' << 8) | 'T'))
+#define LAN_BAUD ((ULONG) (('B' << 24) | ('A' << 16) | ('U' << 8) | 'D'))
+#define LAN_INTR ((ULONG) (('I' << 24) | ('N' << 16) | ('T' << 8) | 'R'))
+#define LAN_XMT ((ULONG) (('X' << 16) | ('M' << 8) | 'T'))
+#define LAN_ECHO ((ULONG) (('E' << 24) | ('C' << 16) | ('H' << 8) | 'O'))
+#define LAN_STAT ((ULONG) (('S' << 24) | ('T' << 16) | ('A' << 8) | 'T'))
+#define LAN_IN ((ULONG) (('I' << 8) | 'N'))
+#define LAN_OUT ((ULONG) (('O' << 16) | ('U' << 8) | 'T'))
+
+#define LAN_PUTC ((ULONG) (('P' << 24) | ('U' << 16) | ('T' << 8) | 'C'))
+#define LAN_WPM ((ULONG) (('W' << 16) | ('P' << 8) | 'M'))
+
+#define STATUS(X) ( ( ( X ) == 0 ) ? "disabled" : "enabled" )
+
+#define XMT_VIA_BP_ENABLED() ( *P_LAN0TR_REG & M_LAN0TR ? 1 : 0 )
+
+#define TRAP_1_INST 0x4E41
+
+/*
+ * Bit #13 of shared genstat 1 indicates
+ * which processor we are as follows.
+ *
+ * 0 => X (side A)
+ * 1 => Y (side B)
+ */
+
+#define M_PROC_ID 0x00002000
+
+#define IS_SIDE_A() ( ( (sh_genstat1) & M_PROC_ID ) == 0 )
+#define IS_SIDE_B() ( (sh_genstat1) & M_PROC_ID )
+
+
+#ifdef STANDALONE /* Compile this module stand-alone for debugging */
+#define LAN_PUT_CHAR(X) printf("%c", X)
+#else
+#define LAN_PUT_CHAR(X) while ( lan_put_char( X ) )
+#endif
+
+
+
+
+#define VIA_RS232 0
+#define VIA_ETHERNET 1
+
+#define MAX_IO_BUF_SIZE 400
+
+#define MAX_BYTE_CODES 200 /* maximum length for bytecode string */
+
+
+static ULONG gdb_host_comm;
+
+static ULONG gdb_cat_ack;
+
+static char eth_outbuffer[ MAX_IO_BUF_SIZE + 1 ];
+
+
+#ifdef STANDALONE
+
+#define ACK_PKT() LAN_PUT_CHAR( '+' )
+#define NACK_PKT() LAN_PUT_CHAR( '-' )
+
+#else
+
+#define ACK_PKT() { \
+ if ( VIA_ETHERNET == gdb_host_comm ) \
+ { \
+ gdb_cat_ack = YES; \
+ } \
+ else \
+ { \
+ LAN_PUT_CHAR( '+' ); \
+ } \
+ }
+
+
+
+#define NACK_PKT() { \
+ if ( VIA_ETHERNET == gdb_host_comm ) \
+ { \
+ eth_outbuffer[ 0 ] = '-'; \
+ eth_to_gdb( (UCHAR *) eth_outbuffer, 1 ); \
+ } \
+ else \
+ { \
+ LAN_PUT_CHAR( '-' ); \
+ } \
+ }
+
+#endif
+
+
+
+
+/*============================================================================
+ * MODULE TYPEDEFS
+ *===========================================================================*/
+
+typedef struct rs232_queue {
+
+ long head_index;
+
+ long tail_index;
+
+ ULONG overflows;
+
+ long gdb_packet_start;
+ long gdb_packet_end;
+ long gdb_packet_csum1;
+ long gdb_packet_csum2;
+
+ UCHAR buf[ MAX_RS232_CHARS ];
+
+} T_RS232_QUEUE;
+
+
+
+
+/*=============================================================================
+ * EXTERNAL GLOBAL VARIABLES
+ *===========================================================================*/
+
+extern volatile UCHAR sss_trace_flag;
+
+
+/*=============================================================================
+ * STATIC MODULE DECLARATIONS
+ *===========================================================================*/
+
+static T_RS232_QUEUE lan_input_queue,
+ lan_output_queue;
+
+static BOOL test_echo;
+
+#if 0
+/* The stub no longer seems to use this. */
+static BOOL write_access_enabled;
+#endif
+
+static int baud_rate_idx;
+
+static ULONG tx_by_intr,
+ tx_by_poll;
+
+static UCHAR lan_shadow_imr;
+
+
+/*=============================================================================
+ * EXTERNAL FUNCTION PROTOTYPES
+ *===========================================================================*/
+
+extern long write_to_protected_mem( void *address, unsigned short value );
+
+
+/*=============================================================================
+ * MODULE GLOBAL FUNCTIONS PROTOTYPES
+ *===========================================================================*/
+
+ULONG gdb_c_test( ULONG *parm );
+
+
+void lan_init( void );
+
+void lan_isr( void );
+
+long lan_get_char( void );
+
+long lan_put_char( UCHAR c );
+
+ULONG lan_util( ULONG *parm );
+
+
+/*=============================================================================
+ * MODULE LOCAL FUNCTION PROTOTYPES
+ *===========================================================================*/
+
+static void lan_reset( void );
+
+static void lan_configure( void );
+
+static void lan_init_queue( T_RS232_QUEUE *p_queue );
+
+static void lan_add_to_queue( long c, T_RS232_QUEUE *p_queue );
+
+static UCHAR lan_next_queue_char( T_RS232_QUEUE *p_queue );
+
+static void lan_util_menu( void );
+
+static long get_gdb_input( long c, T_RS232_QUEUE *p_input_q );
+
+
+/*=============================================================================
+ * GDB STUB FUNCTION PROTOTYPES
+ *===========================================================================*/
+
+void gdb_trap_1_handler( void );
+void gdb_trace_handler ( void );
+
+void gdb_get_eth_input( unsigned char *buf, long length );
+
+static void getpacket ( void );
+static void putpacket ( char * );
+static void discard_packet ( void );
+
+#ifdef STANDALONE /* Compile this module stand-alone for debugging */
+#include <stdio.h>
+#define printp printf /* easier than declaring a local varargs stub func. */
+#endif /* STANDALONE */
+
+
+/*=============================================================================
+ * MODULE BODY
+ *===========================================================================*/
+
+/* ------------------- Things that belong in a header file --------------- */
+extern char *memset (char *, int, int);
+
+ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
+ * *
+ * Global Module Functions *
+ * *
+ *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+
+static char gdb_char_test;
+static short gdb_short_test;
+static long gdb_long_test;
+static char gdb_arr_test[25];
+static struct GDB_STRUCT_TEST
+{
+ char c;
+ short s;
+ long l;
+ int bfield : 11; /* collect bitfield */
+ char arr[25];
+ struct GDB_STRUCT_TEST *next;
+} gdb_struct1_test, gdb_struct2_test, *gdb_structp_test, **gdb_structpp_test;
+
+static union GDB_UNION_TEST
+{
+ char c;
+ short s;
+ long l;
+ int bfield : 11; /* collect bitfield */
+ char arr[4];
+ union GDB_UNION_TEST *next;
+} gdb_union1_test;
+
+void gdb_recursion_test (int, int, int, int, int, int, int);
+
+void gdb_recursion_test (int depth,
+ int q1,
+ int q2,
+ int q3,
+ int q4,
+ int q5,
+ int q6)
+{ /* gdb_recursion_test line 0 */
+ int q = q1; /* gdbtestline 1 */
+
+ q1 = q2; /* gdbtestline 2 */
+ q2 = q3; /* gdbtestline 3 */
+ q3 = q4; /* gdbtestline 4 */
+ q4 = q5; /* gdbtestline 5 */
+ q5 = q6; /* gdbtestline 6 */
+ q6 = q; /* gdbtestline 7 */
+ if (depth--) /* gdbtestline 8 */
+ gdb_recursion_test (depth, q1, q2, q3, q4, q5, q6); /* gdbtestline 9 */
+}
+
+
+ULONG gdb_c_test( ULONG *parm )
+
+{
+ char *p = "gdb_c_test";
+ char *ridiculously_long_variable_name_with_equally_long_string_assignment;
+ register long local_reg = 7;
+ static unsigned long local_static, local_static_sizeof;
+ long local_long;
+ unsigned long *stack_ptr;
+ unsigned long end_of_stack;
+
+ ridiculously_long_variable_name_with_equally_long_string_assignment =
+ "ridiculously long variable name with equally long string assignment";
+ local_static = 9;
+ local_static_sizeof = sizeof (struct GDB_STRUCT_TEST);
+ local_long = local_reg + 1;
+ stack_ptr = (unsigned long *) &local_long;
+ end_of_stack =
+ (unsigned long) &stack_ptr + sizeof(stack_ptr) + sizeof(end_of_stack) - 1;
+
+ printp ("\n$Id$\n");
+
+ printp( "%s: arguments = %X, %X, %X, %X, %X, %X\n",
+ p, parm[ 1 ], parm[ 2 ], parm[ 3 ], parm[ 4 ], parm[ 5 ], parm[ 6 ] );
+
+ gdb_char_test = gdb_struct1_test.c = (char) ((long) parm[1] & 0xff);
+ gdb_short_test = gdb_struct1_test.s = (short) ((long) parm[2] & 0xffff);
+ gdb_long_test = gdb_struct1_test.l = (long) ((long) parm[3] & 0xffffffff);
+ gdb_union1_test.l = (long) parm[4];
+ gdb_arr_test[0] = gdb_struct1_test.arr[0] = (char) ((long) parm[1] & 0xff);
+ gdb_arr_test[1] = gdb_struct1_test.arr[1] = (char) ((long) parm[2] & 0xff);
+ gdb_arr_test[2] = gdb_struct1_test.arr[2] = (char) ((long) parm[3] & 0xff);
+ gdb_arr_test[3] = gdb_struct1_test.arr[3] = (char) ((long) parm[4] & 0xff);
+ gdb_arr_test[4] = gdb_struct1_test.arr[4] = (char) ((long) parm[5] & 0xff);
+ gdb_arr_test[5] = gdb_struct1_test.arr[5] = (char) ((long) parm[6] & 0xff);
+ gdb_struct1_test.bfield = 144;
+ gdb_struct1_test.next = &gdb_struct2_test;
+ gdb_structp_test = &gdb_struct1_test;
+ gdb_structpp_test = &gdb_structp_test;
+
+ gdb_recursion_test (3, (long) parm[1], (long) parm[2], (long) parm[3],
+ (long) parm[4], (long) parm[5], (long) parm[6]);
+
+ gdb_char_test = gdb_short_test = gdb_long_test = 0;
+ gdb_structp_test = (void *) 0;
+ gdb_structpp_test = (void *) 0;
+ memset ((char *) &gdb_struct1_test, 0, sizeof (gdb_struct1_test));
+ memset ((char *) &gdb_struct2_test, 0, sizeof (gdb_struct2_test));
+ local_static_sizeof = 0;
+ local_static = 0;
+ return ( (ULONG) 0 );
+}
+
+
+/*-----------------------------------------------------------------------------
+ *
+ * FUNCTION NAME: lan_init
+ *
+ *
+ * DESCRIPTION:
+ *
+ *
+ * RETURN VALUE:
+ *
+ *
+ * USED GLOBAL VARIABLES:
+ *
+ *
+ * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
+ *
+ *
+ * NOTES:
+ *
+ *
+ *
+ *---------------------------------------------------------------------------*/
+
+void lan_init( void )
+
+{
+
+ if ( IS_SIDE_A( ) )
+ {
+
+ lan_reset( );
+
+ lan_init_queue( &lan_input_queue );
+
+ lan_init_queue( &lan_output_queue );
+
+ lan_configure( );
+ }
+
+ return;
+}
+/* end of 'lan_init'
+ *===========================================================================*/
+
+
+/*-----------------------------------------------------------------------------
+ *
+ * FUNCTION NAME: lan_isr
+ *
+ *
+ * DESCRIPTION:
+ *
+ *
+ * RETURN VALUE: None.
+ *
+ *
+ * USED GLOBAL VARIABLES:
+ *
+ *
+ * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
+ *
+ *
+ * NOTES:
+ *
+ *
+ *---------------------------------------------------------------------------*/
+
+void lan_isr( void )
+
+{
+ UCHAR c;
+
+
+ lan_shadow_imr = 0; /* Disable all UART interrupts. */
+ *P_LAN_IMR = lan_shadow_imr;
+
+
+ if ( *P_LAN_ISR & M_UART_ISR_RxRDY )
+ {
+
+ gdb_host_comm = VIA_RS232;
+
+ c = *P_LAN_RCV;
+
+ if ( test_echo )
+ {
+ /* ????? */
+ }
+
+ if ( c == CONTROL_C )
+ {
+ /* can't stop the target, but we can tell gdb to stop waiting... */
+ discard_packet( );
+ putpacket( "S03" ); /* send back SIGINT to the debugger */
+ }
+
+ else
+ {
+ lan_add_to_queue( (long) c, &lan_input_queue );
+ get_gdb_input( (long) c, &lan_input_queue );
+ }
+
+ }
+
+ if ( XMT_VIA_BP_ENABLED( ) )
+ {
+
+ c = 0;
+
+ while ( (*P_LAN_ISR & M_UART_ISR_TxRDY) && (c = lan_next_queue_char( &lan_output_queue )) )
+ {
+ *P_LAN_XMT = c;
+ ++tx_by_intr;
+ }
+
+ if ( c )
+ {
+ lan_shadow_imr |= UART_IMR_TxRDY; /* (Re-)Enable 'TxRDY' interrupt from UART. */
+ }
+
+ }
+
+
+ lan_shadow_imr |= UART_IMR_RxRDY; /* Re-Enable 'RxRDY' interrupt from UART. */
+ *P_LAN_IMR = lan_shadow_imr;
+
+
+
+ return;
+}
+/* end of 'lan_isr'
+ *===========================================================================*/
+
+
+/*-----------------------------------------------------------------------------
+ *
+ * FUNCTION NAME: lan_get_char
+ *
+ *
+ * DESCRIPTION: Fetches a character from the UART.
+ *
+ *
+ * RETURN VALUE: 0 on success, -1 on failure.
+ *
+ *
+ * USED GLOBAL VARIABLES:
+ *
+ *
+ * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
+ *
+ *
+ * NOTES:
+ *
+ *
+ *---------------------------------------------------------------------------*/
+
+long lan_get_char( void )
+
+{
+ long status = -2; /* AGD: nothing found in rcv buffer */
+
+ if ( *P_LAN_SR & M_UART_SR_RxRDY )
+ {
+ char c = (char) *P_LAN_RCV;
+
+ if ( test_echo )
+ {
+ LAN_PUT_CHAR ( c );
+ }
+
+ if ( c == CONTROL_C )
+ {
+ /* can't stop the target, but we can tell gdb to stop waiting... */
+ discard_packet( );
+ putpacket( "S03" ); /* send back SIGINT to the debugger */
+ status = 0; /* success */
+ }
+
+ else
+ {
+ lan_add_to_queue( (long) c, &lan_input_queue );
+ status = get_gdb_input( (long) c, &lan_input_queue );
+ }
+
+ }
+
+ return( status );
+}
+/* end of 'lan_get_char'
+ *===========================================================================*/
+
+
+/*-----------------------------------------------------------------------------
+ *
+ * FUNCTION NAME: lan_put_char
+ *
+ * DESCRIPTION: Puts a character out via the UART.
+ *
+ * RETURN VALUE: 0 on success, -1 on failure.
+ *
+ * USED GLOBAL VARIABLES: none.
+ *
+ * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
+ *
+ * NOTES: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * !! !!
+ * !! If 'XMT_VIA_BP_ENABLED()' is FALSE then output is THROWN AWAY. !!
+ * !! This prevents anyone infinite-looping on this function. !!
+ * !! !!
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ *
+ *---------------------------------------------------------------------------*/
+
+long lan_put_char( UCHAR c )
+
+{
+ long status = -1;
+
+ if ( XMT_VIA_BP_ENABLED( ) )
+ {
+
+ if ( *P_LAN_SR & M_UART_SR_TxRDY )
+ {
+ lan_add_to_queue( (long) c, &lan_output_queue );
+
+ c = lan_next_queue_char( &lan_output_queue );
+
+ *P_LAN_XMT = c;
+ ++tx_by_poll;
+ status = 0;
+ }
+#if 0
+ else
+ {
+ status = 0;
+ lan_shadow_imr |= UART_IMR_TxRDY; /* Enable 'TxRDY' interrupt from UART. */
+ *P_LAN_IMR = lan_shadow_imr;
+ }
+#endif
+ }
+
+ else
+ {
+ status = 0; /* You lose: input character goes to the bit bucket. */
+ }
+
+ return( status );
+}
+/* end of 'lan_put_char'
+ *===========================================================================*/
+
+
+/*-----------------------------------------------------------------------------
+ *
+ * FUNCTION NAME: lan_util
+ *
+ * DESCRIPTION:
+ *
+ * RETURN VALUE:
+ *
+ * USED GLOBAL VARIABLES:
+ *
+ * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
+ *
+ * NOTES:
+ *
+ *---------------------------------------------------------------------------*/
+
+ULONG lan_util( ULONG *parm )
+
+{
+
+
+ static const struct {
+
+ ULONG rate_code;
+ UCHAR acr_setting;
+ UCHAR csr_setting;
+
+ } baud_rate_setting [] = {
+
+ { 0x38400, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_38400 },
+ { 0x19200, LAN_ACR_SELECT_BRG_1, UART_CSR_BR_19200 },
+ { 0x9600, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_9600 },
+ { 0x4800, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_4800 }
+ };
+
+
+#define BOGUS_P1 0xE1
+#define BOGUS_P2 0xE2
+
+ ULONG not_done_code;
+
+
+ ULONG opcode;
+ ULONG parm_1;
+ ULONG parm_2;
+
+ int i;
+ UCHAR c;
+
+
+ not_done_code = 0;
+
+ opcode = parm[ 1 ];
+ parm_1 = parm[ 2 ];
+ parm_2 = parm[ 3 ];
+
+
+ switch ( opcode )
+ {
+
+ case LAN_INIT:
+ {
+
+ lan_init( );
+ printp( "\n\n Interface (Re)Initialized ...\n\n" );
+
+ break;
+ }
+
+
+ case LAN_BAUD:
+ {
+
+ for ( i = 0; i < (int)(sizeof(baud_rate_setting) / sizeof(baud_rate_setting[0])); i ++ )
+ {
+ if ( baud_rate_setting[i].rate_code == parm_1 )
+ {
+ baud_rate_idx = i;
+ *P_LAN_ACR = baud_rate_setting[i].acr_setting;
+ *P_LAN_CSR = baud_rate_setting[i].csr_setting;
+ printp ( "Baud rate set to %X!\n", baud_rate_setting[i].rate_code );
+ return( not_done_code );
+ }
+ }
+
+ printp( "\n\n *** SYNTAX Error - Invalid baudrate (P2)\n\n" );
+ not_done_code = BOGUS_P2;
+
+ break;
+ }
+
+
+ case LAN_INTR:
+ {
+
+ switch ( parm_1 )
+ {
+
+ case 0x0D: /* Disable 'RxRDY' Interrupts */
+ {
+ lan_shadow_imr &= ~UART_IMR_RxRDY;
+ *P_LAN_IMR = lan_shadow_imr;
+ printp( "\n\n Receive Ready Interrupts DISABLED ...\n\n" );
+ break;
+ }
+
+ case 0x0E: /* Enable 'RxRDY' Interrupts */
+ {
+ lan_shadow_imr |= UART_IMR_RxRDY;
+ *P_LAN_IMR = lan_shadow_imr;
+ printp( "\n\n Receive Ready Interrupts ENABLED ...\n\n" );
+ break;
+ }
+
+ default:
+ {
+ printp( "\n\n *** SYNTAX Error - Invalid P2 (use D or E)\n\n" );
+ not_done_code = BOGUS_P2;
+ }
+ }
+
+ break;
+ }
+
+
+ case LAN_XMT:
+ {
+
+ switch ( parm_1 )
+ {
+
+ case 0x0E: /* Enable Transmission-via-Backplane */
+ {
+ if ( !(*P_LAN0TR_REG & M_LAN0TR) )
+ {
+ *P_LAN0TR_REG |= M_LAN0TR; /* 0 -> 1 */
+ }
+
+ printp( "\n\n Transmit-via-Backplane ENABLED ...\n\n" );
+ break;
+ }
+
+ case 0x0D: /* Disable Transmission-via-Backplane */
+ {
+ if ( *P_LAN0TR_REG & M_LAN0TR )
+ {
+ *P_LAN0TR_REG &= ~M_LAN0TR; /* 1 -> 0 */
+ }
+
+ printp( "\n\n Transmit-via-Backplane DISABLED ...\n\n" );
+ break;
+ }
+
+ default:
+ {
+ printp( "\n\n *** SYNTAX Error - Invalid P2 (use D or E)\n\n" );
+ not_done_code = BOGUS_P2;
+ lan_util_menu( );
+ }
+ }
+
+ break;
+ }
+
+
+ case LAN_STAT:
+ {
+
+ printp( "\n -- Status --\n\n" );
+
+ printp( " Baud Rate: %X *\n", baud_rate_setting[ baud_rate_idx ].rate_code );
+ printp( " Xmt-via-BP: %s *\n", STATUS( XMT_VIA_BP_ENABLED( ) ) );
+ printp( " RxRdy Intr: %s *\n", STATUS( (lan_shadow_imr & M_UART_ISR_RxRDY) ) );
+ /*** printp( " TxRdy Intr: %s\n", STATUS( (lan_shadow_imr & M_UART_ISR_TxRDY) ) ); ***/
+ printp( " Echo: %s *\n\n", STATUS( test_echo ) );
+
+ printp( " IMR: %02X\n", (ULONG) lan_shadow_imr );
+ printp( " ISR: %02X\n", (ULONG) *P_LAN_ISR );
+ printp( " SR: %02X\n\n", (ULONG) *P_LAN_SR );
+
+ printp( " Input Overflows: %d\n\n", lan_input_queue.overflows );
+
+ printp( " Tx by Intr: %d\n", tx_by_intr );
+ printp( " Tx by Poll: %d\n\n", tx_by_poll );
+
+ printp( " * Can be set or toggled via Utility %2X.\n\n", (ULONG) LAN_UTIL_CODE );
+
+ break;
+ }
+
+
+ case LAN_IN:
+ {
+
+ switch ( parm_1 )
+ {
+
+ case 0x0C: /* Clear and Reset Queue */
+ {
+ lan_init_queue( &lan_input_queue );
+ printp( "\n\n Queue CLEARED/RESET ...\n\n" );
+ break;
+ }
+
+ case 0x0D: /* Display Queue */
+ {
+ printp( "\n -- Input Queue --\n" );
+ printp( "\n Head Index: %8X Tail Index: %8X\n\n ",
+ (ULONG) lan_input_queue.head_index, (ULONG) lan_input_queue.tail_index );
+
+ for ( i = 0; i < MAX_RS232_CHARS; ++i )
+ {
+ printp( " %02X", (ULONG) lan_input_queue.buf[ i ] );
+
+ if ( 15 == (i % 16) )
+ {
+ int j;
+
+ printp ( " " );
+ for ( j = i - 15; j <= i; j++ )
+ {
+ if ( lan_input_queue.buf[ j ] >= ' ' &&
+ lan_input_queue.buf[ j ] < 127 )
+ printp ( "%c", lan_input_queue.buf[ j ] );
+ else
+ printp ( "." );
+ }
+ printp( "\n " );
+ }
+
+ else if ( 7 == (i % 8) )
+ {
+ printp( " " );
+ }
+
+ }
+
+ printp( "\n" );
+
+ break;
+ }
+
+ case 0x0F: /* Fetch next character in Queue */
+ {
+ c = lan_next_queue_char( &lan_input_queue );
+
+ if ( c )
+ {
+ printp( "\n\n Next Character: " );
+ if ( 0x21 <= c && c <= 0x7F )
+ {
+ printp( "%c\n\n", (ULONG) c );
+ }
+
+ else if ( 0x20 == ((UCHAR) c) )
+ {
+ printp( "<space>\n\n" );
+ }
+
+ else
+ {
+ printp( "%02X\n\n", (ULONG) c );
+ }
+ }
+
+ else
+ {
+ printp( "\n\n Input Queue EMPTY ...\n\n" );
+ }
+
+ break;
+ }
+
+ default:
+ {
+ printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" );
+ not_done_code = BOGUS_P2;
+ break;
+ }
+ }
+
+ break;
+ }
+
+
+ case LAN_OUT:
+ {
+
+ switch ( parm_1 )
+ {
+
+ case 0x0C: /* Clear and Reset Queue */
+ {
+ lan_init_queue( &lan_output_queue );
+ printp( "\n\n Queue CLEARED/RESET ...\n\n" );
+ break;
+ }
+
+ case 0x0D: /* Display Queue */
+ {
+ printp( "\n -- Output Queue --\n" );
+ printp( "\n Head Index: %8X Tail Index: %8X\n\n ",
+ (ULONG) lan_output_queue.head_index, (ULONG) lan_output_queue.tail_index );
+
+ for ( i = 0; i < MAX_RS232_CHARS; ++i )
+ {
+ printp( " %02X", (ULONG) lan_output_queue.buf[ i ] );
+
+ if ( 15 == (i % 16) )
+ {
+ int j;
+
+ printp ( " " );
+ for ( j = i - 15; j <= i; j++ )
+ {
+ if ( lan_output_queue.buf[ j ] >= ' ' &&
+ lan_output_queue.buf[ j ] < 127 )
+ printp ( "%c", lan_output_queue.buf[ j ] );
+ else
+ printp ( "." );
+ }
+ printp( "\n " );
+ }
+
+ else if ( 7 == (i % 8) )
+ {
+ printp( " " );
+ }
+
+ }
+
+ printp( "\n" );
+
+ break;
+ }
+
+ case 0x0F: /* Fetch next character in Queue */
+ {
+ c = lan_next_queue_char( &lan_output_queue );
+
+ if ( c )
+ {
+ printp( "\n\n Next Character: " );
+ if ( 0x21 <= c && c <= 0x7F )
+ {
+ printp( "%c\n\n", (ULONG) c );
+ }
+
+ else if ( 0x20 == c )
+ {
+ printp( "<space>\n\n" );
+ }
+
+ else
+ {
+ printp( "%02X\n\n", (ULONG) c );
+ }
+ }
+
+ else
+ {
+ printp( "\n\n Input Queue EMPTY ...\n\n" );
+ }
+
+ break;
+ }
+
+ default:
+ {
+ printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" );
+ not_done_code = BOGUS_P2;
+ break;
+ }
+ }
+
+ break;
+ }
+
+
+ case LAN_ECHO:
+ {
+
+ switch ( parm_1 )
+ {
+
+ case 0x0E:
+ {
+ test_echo = ENABLED;
+ printp( "\n\n Test echo ENABLED ...\n\n" );
+ break;
+ }
+
+ case 0x0D:
+ {
+ test_echo = DISABLED;
+ printp( "\n\n Test echo DISABLED ...\n\n" );
+ break;
+ }
+
+ default:
+ {
+ printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" );
+ not_done_code = BOGUS_P2;
+ break;
+ }
+ }
+
+ break;
+ }
+
+
+ case LAN_PUTC:
+ {
+
+ if ( 0x20 < parm_1 && parm_1 < 0x7F )
+ {
+ if ( lan_put_char( (UCHAR) parm_1 ) )
+ {
+ printp( "\n\n *** 'lan_put_char' Error ...\n" );
+ }
+
+ else
+ {
+ printp( "\n\n O.K. ...\n" );
+ }
+
+ }
+
+ else
+ {
+ printp( "\n\n *** Error - character must be in the 0x21-0x7E range ...\n" );
+ not_done_code = BOGUS_P2;
+ }
+
+ break;
+ }
+
+/***
+ case LAN_WPM:
+ {
+
+ if ( write_to_protected_mem( (void *) parm_1, (unsigned short) parm_2 ) )
+ {
+ printp( "\n Write to protected memory FAILED ...\n" );
+ }
+
+ break;
+ }
+***/
+
+ case 0: /* no argument -- print menu */
+ {
+ lan_util_menu( );
+ break;
+ }
+
+
+ default:
+ {
+ parm_2 = 0; /* to supress compiler warning with 'LAN_WPM' case disabled */
+
+ printp( "\n\n *** SYNTAX Error - Invalid P1 ...\n\n" );
+ not_done_code = BOGUS_P1;
+ break;
+ }
+
+
+ } /* End of 'switch ( opcode )'. */
+
+
+return( not_done_code );
+}
+/* end of 'lan_util'
+ *===========================================================================*/
+
+
+ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
+ * *
+ * Local Module Functions *
+ * *
+ *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/*-----------------------------------------------------------------------------
+ *
+ * FUNCTION NAME: lan_reset
+ *
+ * DESCRIPTION: Resets the LAN UART by strobing the 'RST_LAN_UART' bit in the
+ * Shared Control 1 area.
+ *
+ * 1 _| ______
+ * | | |
+ * Bit | | |
+ * | | |
+ * 0 _|______| |______
+ * |---------------------> t
+ *
+ * RETURN VALUE: None.
+ *
+ * USED GLOBAL VARIABLES:
+ *
+ * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
+ *
+ * NOTES: H/W configuration requires that a byte in the shared
+ * control 1 area must be read before being written.
+ *
+ *---------------------------------------------------------------------------*/
+
+static void lan_reset( void )
+
+{
+
+ while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
+ {
+ *P_RST_LAN_UART_REG &= ~M_RST_LAN_UART; /* 0 */
+ }
+
+ while ( !(*P_RST_LAN_UART_REG & M_RST_LAN_UART) )
+ {
+ *P_RST_LAN_UART_REG |= M_RST_LAN_UART; /* 1 */
+ }
+
+ while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART )
+ {
+ *P_RST_LAN_UART_REG &= ~M_RST_LAN_UART; /* 0 */
+ }
+
+}
+/* end of 'lan_reset'
+ *===========================================================================*/
+
+
+/*-----------------------------------------------------------------------------
+ *
+ * FUNCTION NAME: lan_configure
+ *
+ *
+ * DESCRIPTION:
+ *
+ *
+ * RETURN VALUE:
+ *
+ *
+ * USED GLOBAL VARIABLES:
+ *
+ *
+ * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
+ *
+ *
+ * NOTES:
+ *
+ *
+ *
+ *---------------------------------------------------------------------------*/
+
+static void lan_configure( void )
+
+{
+
+ *P_LAN_CR = UART_CR_RESET_MR_PTR; /* Points to MR1. */
+ *P_LAN_CR = UART_CR_RESET_RVCR; /* Receiver disabled. */
+ *P_LAN_CR = UART_CR_RESET_XMTR; /* Transmitter disabled. */
+ *P_LAN_CR = UART_CR_RESET_ERROR_STATUS;
+ *P_LAN_CR = UART_CR_RESET_BRK_CHG_INT;
+
+ *P_LAN_MR1 = DEFAULT_LAN_MR1;
+ *P_LAN_MR2 = DEFAULT_LAN_MR2;
+
+ *P_LAN_ACR = DEFAULT_LAN_ACR;
+
+ *P_LAN_CSR = UART_CSR_BR_9600;
+ baud_rate_idx = 2;
+
+ *P_LAN_CTUR = DEFAULT_LAN_CTUR;
+ *P_LAN_CTLR = DEFAULT_LAN_CTLR;
+
+ *P_LAN_CR = (UART_CR_START_CNTR_TIMER | UART_CR_ENABLE_XMTR | UART_CR_ENABLE_RCVR);
+
+ lan_shadow_imr = UART_IMR_RxRDY; /* Enable only 'RxRDY' interrupt from UART. */
+ *P_LAN_IMR = lan_shadow_imr;
+
+ tx_by_intr = 0;
+ tx_by_poll = 0;
+
+ return;
+}
+/* end of 'lan_configure'
+ *===========================================================================*/
+
+
+/*-----------------------------------------------------------------------------
+ *
+ * FUNCTION NAME: lan_init_queue
+ *
+ * DESCRIPTION:
+ *
+ * RETURN VALUE: None.
+ *
+ * USED GLOBAL VARIABLES:
+ *
+ * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
+ *
+ * NOTES:
+ *
+ *---------------------------------------------------------------------------*/
+
+static void lan_init_queue( T_RS232_QUEUE *p_queue )
+
+{
+ long i;
+
+ /*
+ * We set "head" equal to "tail" implying the queue is empty,
+ * BUT the "head" and "tail" should each point to valid queue
+ * positions.
+ */
+
+ p_queue->head_index = 0;
+ p_queue->tail_index = 0;
+
+ p_queue->overflows = 0;
+
+ p_queue->gdb_packet_start = -1;
+ p_queue->gdb_packet_end = -1;
+
+ p_queue->gdb_packet_csum1 = -1;
+ p_queue->gdb_packet_csum2 = -1;
+
+ for ( i = 0; i < MAX_RS232_CHARS; ++i )
+ {
+ p_queue->buf[ i ] = 0;
+ }
+
+ return;
+}
+/* end of 'lan_init_queue'
+ *===========================================================================*/
+
+
+/*-----------------------------------------------------------------------------
+ *
+ * FUNCTION NAME: lan_add_to_queue
+ *
+ *
+ * DESCRIPTION: Adds the specified character to the tail of the
+ * specified queue. Observes "oldest thrown on floor"
+ * rule (i.e. the queue is allowed to "wrap" and the
+ * input character is unconditionally placed at the
+ * tail of the queue.
+ *
+ *
+ * RETURN VALUE: None.
+ *
+ *
+ * USED GLOBAL VARIABLES:
+ *
+ *
+ * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
+ *
+ *
+ * NOTES:
+ *
+ *
+ *---------------------------------------------------------------------------*/
+
+static void lan_add_to_queue( long c, T_RS232_QUEUE *p_queue )
+
+{
+
+ if ( p_queue ) /* Sanity check. */
+ {
+
+ if ( c & 0x000000FF ) /* We don't allow NULL characters to be added to a queue. */
+ {
+ /* Insert the new character at the tail of the queue. */
+
+ p_queue->buf[ p_queue->tail_index ] = (UCHAR) (c & 0x000000FF);
+
+ /* Increment the tail index. */
+
+ if ( MAX_RS232_CHARS <= ++(p_queue->tail_index) )
+ {
+ p_queue->tail_index = 0;
+ }
+
+ /* Check for wrapping (i.e. overflow). */
+
+ if ( p_queue->head_index == p_queue->tail_index )
+ {
+ /* If the tail has caught up to the head record the overflow . . . */
+
+ ++(p_queue->overflows);
+
+ /* . . . then increment the head index. */
+
+ if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
+ {
+ p_queue->head_index = 0;
+ }
+
+ }
+
+ } /* End of 'if ( c & 0x000000FF )'. */
+
+ } /* End of 'if ( p_queue )'. */
+
+
+ return;
+}
+/* end of 'lan_add_to_queue'
+ *===========================================================================*/
+
+
+/*-----------------------------------------------------------------------------
+ *
+ * FUNCTION NAME: lan_next_queue_char
+ *
+ * DESCRIPTION:
+ *
+ * RETURN VALUE:
+ *
+ * USED GLOBAL VARIABLES:
+ *
+ * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
+ *
+ * NOTES:
+ *
+ *---------------------------------------------------------------------------*/
+
+static UCHAR lan_next_queue_char( T_RS232_QUEUE *p_queue )
+
+{
+ UCHAR c;
+
+
+ c = 0;
+
+ if ( p_queue )
+ {
+
+ if ( p_queue->head_index != p_queue->tail_index )
+ {
+ /* Return the 'oldest' character in the queue. */
+
+ c = p_queue->buf[ p_queue->head_index ];
+
+ /* Increment the head index. */
+
+ if ( MAX_RS232_CHARS <= ++(p_queue->head_index) )
+ {
+ p_queue->head_index = 0;
+ }
+
+ }
+
+ } /* End of 'if ( p_queue )'. */
+
+
+ return( c );
+}
+
+/* end of 'lan_next_queue_char'
+ *===========================================================================*/
+
+
+/*-----------------------------------------------------------------------------
+ *
+ * FUNCTION NAME: lan_util_menu
+ *
+ * DESCRIPTION: Prints out a brief help on the LAN UART control utility.
+ *
+ * RETURN VALUE: None.
+ *
+ * USED GLOBAL VARIABLES: None.
+ *
+ * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: None.
+ *
+ * NOTES: None.
+ *
+ *---------------------------------------------------------------------------*/
+
+static void lan_util_menu( void )
+
+{
+
+ /*
+ * Multiply calling printp() below is made due to the limitations
+ * of printp(), incapable of handling long formatting constants:
+ */
+
+ printp( "\n -- Options --\n\n" );
+
+ printp( " %2X,'INIT' ............... Reset & (Re)INITIALIZE Interface.\n", (ULONG) LAN_UTIL_CODE );
+ printp( " %2X,'BAUD',<rate> ........ Set BAUD Rate.\n", (ULONG) LAN_UTIL_CODE );
+ printp( " %2X,'INTR',<mode> ........ Toggle 'RxRDY' Interrupts.\n", (ULONG) LAN_UTIL_CODE );
+ printp( " %2X,'XMT',<mode> ......... Toggle TRANSMIT-via-backplane.\n", (ULONG) LAN_UTIL_CODE );
+ printp( " %2X,'STAT' ............... Display STATUS.\n", (ULONG) LAN_UTIL_CODE );
+ printp( " %2X,'ECHO',<mode> ........ Enable/Disable Test ECHO.\n", (ULONG) LAN_UTIL_CODE );
+ printp( " %2X,'IN',<action> ........ Access INPUT Queue.\n", (ULONG) LAN_UTIL_CODE );
+ printp( " %2X,'OUT',<action> ....... Access OUTPUT Queue.\n\n", (ULONG) LAN_UTIL_CODE );
+
+ printp( " %2X,'PUTC',<char> ........ Output a Character (i.e. <char>).\n\n", (ULONG) LAN_UTIL_CODE );
+
+/***
+ printp( " %2X,'WPM',address,word ... Write Protected Memory Test.\n\n", (ULONG) LAN_UTIL_CODE );
+***/
+
+ printp( " <rate>: 4800 <mode>: E - enable <action>: C - clear/reset\n" );
+ printp( " 9600 D - disable D - display\n" );
+ printp( " 19200 F - fetch next char\n" );
+ printp( " 38400\n" );
+}
+/* end of 'lan_util_menu'
+ *===========================================================================*/
+
+
+/* Thu Feb 5 17:14:41 EST 1998 CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS */
+
+
+static long get_gdb_input( long c, T_RS232_QUEUE * p_input_q )
+
+{
+
+ /* Now to detect when we've got a gdb packet... */
+
+ if ( '$' == c ) { /* char marks beginning of a packet */
+
+ if ( -1 != p_input_q->gdb_packet_start ||
+ -1 != p_input_q->gdb_packet_end ||
+ -1 != p_input_q->gdb_packet_csum1 ||
+ -1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */
+
+ /* NEW: Actually, this probably means that we muffed a packet,
+ and GDB has already resent it. The thing to do now is to
+ throw away the one we WERE working on, but immediately start
+ accepting the new one. Don't NAK, or GDB will have to try
+ and send it yet a third time! */
+
+ /*NACK_PKT( );*/ /*<ETHERNET>*/
+ discard_packet( ); /* throw away old packet */
+ lan_add_to_queue ('$', p_input_q); /* put the new "$" back in */
+ return 0;
+ } else { /* match new "$" */
+ p_input_q->gdb_packet_start = p_input_q->tail_index;
+ p_input_q->gdb_packet_end =
+ p_input_q->gdb_packet_csum1 =
+ p_input_q->gdb_packet_csum2 = -1;
+ }
+ } else if ( '#' == c ) { /* # marks end of packet (except for checksum) */
+
+ if ( -1 == p_input_q->gdb_packet_start ||
+ -1 != p_input_q->gdb_packet_end ||
+ -1 != p_input_q->gdb_packet_csum1 ||
+ -1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */
+
+ /* Garbled packet. Discard, but do not NAK. */
+
+ /*NACK_PKT( );*/ /*<ETHERNET>*/
+ discard_packet( );
+ return -1;
+ }
+ p_input_q->gdb_packet_end = p_input_q->tail_index;
+ p_input_q->gdb_packet_csum1 = p_input_q->gdb_packet_csum2 = -1;
+
+ } else if ( -1 != p_input_q->gdb_packet_start &&
+ -1 != p_input_q->gdb_packet_end) {
+
+ if ( isxdigit( c ) ) { /* char is one of two checksum digits for packet */
+
+ if ( -1 == p_input_q->gdb_packet_csum1 &&
+ LAN_Q_MOD( p_input_q->gdb_packet_end + 1 ) ==
+ p_input_q->tail_index ) {
+
+ /* first checksum digit */
+
+ p_input_q->gdb_packet_csum1 = p_input_q->tail_index;
+ p_input_q->gdb_packet_csum2 = -1;
+
+ } else if ( -1 == p_input_q->gdb_packet_csum2 &&
+ LAN_Q_MOD( p_input_q->gdb_packet_end + 2 ) ==
+ p_input_q->tail_index ) {
+
+ /* second checksum digit: packet is complete! */
+
+ p_input_q->gdb_packet_csum2 = p_input_q->tail_index;
+ getpacket(); /* got a packet -- extract it */
+
+ } else { /* probably can't happen (um... three hex digits?) */
+
+ /* PROTOCOL ERROR */
+ /* Not sure how this can happen, but ...
+ discard it, but do not NAK it. */
+ /*NACK_PKT( );*/ /*<ETHERNET>*/
+ discard_packet( );
+ return -1;
+ }
+
+ } else { /* '#' followed by non-hex char */
+
+ /* PROTOCOL ERROR */
+ /* Bad packet -- discard but do not NAK */
+ /*NACK_PKT( );*/ /*<ETHERNET>*/
+ discard_packet( );
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+
+
+#ifdef STANDALONE
+
+/* stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone
+ stand-alone stand-alone
+ stand-alone Enable stand-alone build, for ease of debugging stand-alone
+ stand-alone stand-alone
+ stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone */
+
+long write_to_protected_mem (addr, word)
+ void *addr;
+ unsigned short word;
+{
+ return 0;
+}
+
+
+char dummy_memory[0x4000];
+
+int main ( void )
+{
+ long c;
+
+ lan_init_queue( &lan_input_queue );
+ printf( "Stand-alone EMC 'stub', pid = %d\n", getpid( ) );
+ printf( "Start of simulated 'memory': 0x%08x\n", &dummy_memory);
+ while ( (c = getc( stdin ) ) != EOF )
+ {
+ if ( c == '\\' ) /* escape char */
+ break;
+
+ lan_add_to_queue( c, &lan_input_queue );
+ get_gdb_input (c, &lan_input_queue);
+ fflush( stdout );
+ }
+
+ printf( "Goodbye!\n" );
+ exit( 0 );
+}
+
+#define SRAM_START ((void *) (&dummy_memory[0] + 0x00000000))
+#define SRAM_END ((void *) (&dummy_memory[0] + 0x00000400))
+
+#define RO_AREA_START ((void *) (&dummy_memory[0] + 0x00000100))
+#define RO_AREA_END ((void *) (&dummy_memory[0] + 0x00000300))
+
+#define NVD_START ((void *) (&dummy_memory[0] + 0x00003000))
+#define NVD_END ((void *) (&dummy_memory[0] + 0x00003100))
+
+#else /* normal stub (not stand-alone) */
+
+#define SRAM_START ((void *) 0x00000000)
+#define SRAM_END ((void *) 0x00400000)
+
+#define RO_AREA_START ((void *) 0x00100000)
+#define RO_AREA_END ((void *) 0x00300000)
+
+#define NVD_START ((void *) 0x03000000)
+#define NVD_END ((void *) 0x03100000)
+
+#endif /* STANDALONE */
+
+
+
+
+/* gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb
+ gdb gdb
+ gdb Here begins the gdb stub section. gdb
+ gdb The following functions were added by Cygnus, gdb
+ gdb to make this thing act like a gdb stub. gdb
+ gdb gdb
+ gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb */
+
+
+/* ------------------- global defines and data decl's -------------------- */
+
+#define hexchars "0123456789abcdef"
+
+/* there are 180 bytes of registers on a 68020 w/68881 */
+/* many of the fpa registers are 12 byte (96 bit) registers */
+#define NUMREGBYTES 180
+#define NUMREGS 29
+#define REGISTER_BYTE(regno) regno
+
+enum regnames { D0, D1, D2, D3, D4, D5, D6, D7,
+ A0, A1, A2, A3, A4, A5, A6, A7,
+ PS, PC,
+ FP0, FP1,
+ FP2, FP3,
+ FP4, FP5,
+ FP6, FP7,
+ FPCONTROL, FPSTATUS, FPIADDR
+ };
+
+unsigned long registers[NUMREGBYTES/4];
+
+static long remote_debug;
+
+#define BUFMAX MAX_IO_BUF_SIZE
+static char inbuffer[BUFMAX], outbuffer[BUFMAX];
+static char spare_buffer[BUFMAX];
+
+
+struct stub_trace_frame
+{
+ int valid;
+ unsigned long frame_id;
+ unsigned long tdp_id;
+ FRAME_DEF *frame_data;
+ COLLECTION_FORMAT_DEF *format;
+ unsigned long traceregs[NUMREGBYTES/4];
+ unsigned char *stack_data;
+ unsigned char *memrange_data;
+} curframe;
+
+/* ------------------- function prototypes -------------------- */
+
+void handle_request ( char * );
+
+/* ------------------- Implementation -------------------- */
+
+static void
+discard_packet( void )
+{
+ lan_input_queue.head_index = lan_input_queue.tail_index;
+
+ lan_input_queue.gdb_packet_start =
+ lan_input_queue.gdb_packet_end =
+ lan_input_queue.gdb_packet_csum1 =
+ lan_input_queue.gdb_packet_csum2 = -1;
+}
+
+/* Utility function: convert an ASCII isxdigit to a hex nybble */
+
+static long
+hex( char ch )
+{
+ if ( (ch >= 'A') && (ch <= 'F') )
+ return ch - 'A' + 10;
+ if ( (ch >= 'a') && (ch <= 'f') )
+ return ch - 'a' + 10;
+ if ( (ch >= '0') && (ch <= '9') )
+ return ch - '0';
+ return -1;
+}
+
+static void
+getpacket( void )
+{
+ unsigned char our_checksum, their_checksum;
+ char *copy = inbuffer;
+ unsigned char c;
+
+ our_checksum = 0;
+
+ /* first find the '$' */
+ while ((c = lan_next_queue_char ( &lan_input_queue )) != '$')
+ if (c == 0) /* ??? Protocol error? (paranoia) */
+ {
+ /* PROTOCOL ERROR (missing '$') */
+ /*NACK_PKT( );*/ /*<ETHERNET>*/
+ return;
+ }
+
+ /* Now copy the message (up to the '#') */
+ for (c = lan_next_queue_char ( &lan_input_queue ); /* skip the '$' */
+ c != 0 && c != '#'; /* stop at the '#' */
+ c = lan_next_queue_char ( &lan_input_queue ))
+ {
+ *copy++ = c;
+ our_checksum += c;
+ }
+ *copy++ = '\0'; /* terminate the copy */
+
+ if (c == 0) /* ??? Protocol error? (paranoia) */
+ {
+ /* PROTOCOL ERROR (missing '#') */
+ /*NACK_PKT( );*/ /*<ETHERNET>*/
+ return;
+ }
+ their_checksum = hex( lan_next_queue_char ( &lan_input_queue ) ) << 4;
+ their_checksum += hex( lan_next_queue_char ( &lan_input_queue ) );
+
+ /* Now reset the queue packet-recognition bits */
+ discard_packet( );
+
+ if ( remote_debug ||
+ our_checksum == their_checksum )
+ {
+ ACK_PKT( ); /* good packet */
+ /* Parse and process the packet */
+ handle_request( inbuffer );
+ }
+ else
+ /* PROTOCOL ERROR (bad check sum) */
+ NACK_PKT( );
+}
+
+/* EMC will provide a better implementation
+ (perhaps just of LAN_PUT_CHAR) that does not block.
+ For now, this works. */
+
+
+static void
+putpacket( char *str )
+{
+ unsigned char checksum;
+
+ /* '$'<packet>'#'<checksum> */
+
+ if ( VIA_ETHERNET == gdb_host_comm )
+ {
+ char *p_out;
+ long length;
+
+ p_out = eth_outbuffer;
+ length = 0;
+
+
+ if ( YES == gdb_cat_ack )
+ {
+ *p_out++ = '+';
+ ++length;
+ }
+
+ gdb_cat_ack = NO;
+
+
+ *p_out++ = '$';
+ ++length;
+
+ checksum = 0;
+
+ while ( *str )
+ {
+ *p_out++ = *str;
+ ++length;
+ checksum += *str++;
+ }
+
+ *p_out++ = '#';
+ *p_out++ = hexchars[checksum >> 4];
+ *p_out = hexchars[checksum % 16];
+ length += 3;
+
+ eth_to_gdb( (UCHAR *) eth_outbuffer, length );
+ }
+
+ else
+ {
+
+ /* via RS-232 */
+ do {
+ LAN_PUT_CHAR( '$' );
+ checksum = 0;
+
+ while ( *str )
+ {
+ LAN_PUT_CHAR( *str );
+ checksum += *str++;
+ }
+
+ LAN_PUT_CHAR( '#' );
+ LAN_PUT_CHAR( hexchars[checksum >> 4] );
+ LAN_PUT_CHAR( hexchars[checksum % 16] );
+ } while ( 0 /* get_debug_char( ) != '+' */ );
+ /* XXX FIXME: not waiting for the ack. */
+
+ }
+
+}
+
+
+/*-----------------------------------------------------------------------------
+ *
+ * FUNCTION NAME: gdb_get_eth_input
+ *
+ *
+ * DESCRIPTION:
+ *
+ *
+ * RETURN VALUE: None.
+ *
+ *
+ * USED GLOBAL VARIABLES:
+ *
+ *
+ * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS:
+ *
+ *
+ * NOTES:
+ *
+ *
+ *---------------------------------------------------------------------------*/
+
+void gdb_get_eth_input( unsigned char *buf, long length )
+
+{
+
+ gdb_host_comm = VIA_ETHERNET;
+
+ for ( ; 0 < length; ++buf, --length)
+ {
+
+ if ( *buf == CONTROL_C )
+ {
+ /* can't stop the target, but we can tell gdb to stop waiting... */
+ discard_packet( );
+ putpacket( "S03" ); /* send back SIGINT to the debugger */
+ }
+
+ else
+ {
+ lan_add_to_queue( (long) *buf, &lan_input_queue );
+ get_gdb_input( (long) *buf, &lan_input_queue );
+ }
+
+ }
+
+
+ return;
+}
+/* end of 'gdb_get_eth_input'
+ *===========================================================================*/
+
+
+
+
+/* STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT
+ Stuff pertaining to simulating stdout by sending chars to gdb to be echoed.
+
+ Dear reader:
+ This code is based on the premise that if GDB receives a packet
+ from the stub that begins with the character CAPITAL-OH, GDB will
+ echo the rest of the packet to GDB's console / stdout. This gives
+ the stub a way to send a message directly to the user. In practice,
+ (as currently implemented), GDB will only accept such a packet when
+ it believes the target to be running (ie. when you say STEP or
+ CONTINUE); at other times it does not expect it. This will probably
+ change as a side effect of the "asynchronous" behavior.
+
+ Functions: gdb_putchar(char ch)
+ gdb_write(char *str, int len)
+ gdb_puts(char *str)
+ gdb_error(char *format, char *parm)
+ */
+
+#if 0 /* avoid compiler warning while this is not used */
+
+/* Function: gdb_putchar(int)
+ Make gdb write a char to stdout.
+ Returns: the char */
+
+static int
+gdb_putchar( long ch )
+{
+ char buf[4];
+
+ buf[0] = 'O';
+ buf[1] = hexchars[ch >> 4];
+ buf[2] = hexchars[ch & 0x0F];
+ buf[3] = 0;
+ putpacket( buf );
+ return ch;
+}
+#endif
+
+/* Function: gdb_write(char *, int)
+ Make gdb write n bytes to stdout (not assumed to be null-terminated).
+ Returns: number of bytes written */
+
+static int
+gdb_write( char *data, long len )
+{
+ char *buf, *cpy;
+ long i;
+
+ buf = outbuffer;
+ buf[0] = 'O';
+ i = 0;
+ while ( i < len )
+ {
+ for ( cpy = buf+1;
+ i < len && cpy < buf + BUFMAX - 3;
+ i++ )
+ {
+ *cpy++ = hexchars[data[i] >> 4];
+ *cpy++ = hexchars[data[i] & 0x0F];
+ }
+ *cpy = 0;
+ putpacket( buf );
+ }
+ return len;
+}
+
+/* Function: gdb_puts(char *)
+ Make gdb write a null-terminated string to stdout.
+ Returns: the length of the string */
+
+static int
+gdb_puts( char *str )
+{
+ return gdb_write( str, strlen( str ) );
+}
+
+/* Function: gdb_error(char *, char *)
+ Send an error message to gdb's stdout.
+ First string may have 1 (one) optional "%s" in it, which
+ will cause the optional second string to be inserted. */
+
+#if 0
+static void
+gdb_error( char *format, char *parm )
+{
+ static char buf[400];
+ char *cpy;
+ long len;
+
+ if ( remote_debug )
+ {
+ if ( format && *format )
+ len = strlen( format );
+ else
+ return; /* empty input */
+
+ if ( parm && *parm )
+ len += strlen( parm );
+
+ for ( cpy = buf; *format; )
+ {
+ if ( format[0] == '%' && format[1] == 's' ) /* include 2nd string */
+ {
+ format += 2; /* advance two chars instead of just one */
+ while ( parm && *parm )
+ *cpy++ = *parm++;
+ }
+ else
+ *cpy++ = *format++;
+ }
+ *cpy = '\0';
+ gdb_puts( buf );
+ }
+}
+#endif
+
+static void gdb_note (char *, int);
+static int error_ret (int, char *, int);
+
+static unsigned long
+elinum_to_index (unsigned long elinum)
+{
+ if ((elinum & 0xf0) == 0xd0)
+ return (elinum & 0x0f);
+ else if ((elinum & 0xf0) == 0xa0)
+ return (elinum & 0x0f) + 8;
+ else
+ return -1;
+}
+
+static long
+index_to_elinum (unsigned long index)
+{
+ if (index <= 7)
+ return index + 0xd0;
+ else if (index <= 15)
+ return (index - 8) + 0xa0;
+ else
+ return -1;
+}
+
+
+/*
+ READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM
+
+ The following code pertains to reading memory from the target.
+ Some sort of exception handling should be added to make it safe.
+
+ READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM
+
+ Safe Memory Access:
+
+ All reads and writes into the application's memory will pass thru
+ get_uchar() or set_uchar(), which check whether accessing their
+ argument is legal before actual access (thus avoiding a bus error).
+
+ */
+
+enum { SUCCESS = 0, FAIL = -1 };
+
+#if 0
+static long get_uchar ( const unsigned char * );
+#endif
+static long set_uchar ( unsigned char *, unsigned char );
+static long read_access_violation ( const void * );
+static long write_access_violation ( const void * );
+static long read_access_range(const void *, long);
+static DTC_RESPONSE find_memory(unsigned char *,long,unsigned char **,long *);
+
+static int
+dtc_error_ret (int ret, char *src, DTC_RESPONSE code)
+{
+ if (src)
+ sprintp (spare_buffer,
+ "'%s' returned DTC error '%s'.\n", src, get_err_text (code));
+ else
+ sprintp (spare_buffer, "DTC error '%s'.\n", get_err_text (code));
+
+ gdb_puts (spare_buffer);
+ return ret;
+}
+
+
+#if 0
+/* I think this function is unnecessary since the introduction of
+ adbg_find_memory_addr_in_frame. */
+
+/* Return the number of expressions in the format associated with a
+ given trace frame. */
+static int
+count_frame_exprs (FRAME_DEF *frame)
+{
+ CFD *format;
+ T_EXPR *expr;
+ int num_exprs;
+
+ /* Get the format from the frame. */
+ get_frame_format_pointer (frame, &format);
+
+ /* Walk the linked list of expressions, and count the number of
+ expressions we find there. */
+ num_exprs = 0;
+ for (expr = format->p_cfd_expr; expr; expr = expr->next)
+ num_exprs++;
+
+ return num_exprs;
+}
+#endif
+
+#if 0
+/* Function: get_frame_addr
+ *
+ * Description: If the input memory address was collected in the
+ * current trace frame, then lookup and return the address
+ * from within the trace buffer from which the collected byte
+ * may be retrieved. Else return -1. */
+
+unsigned char *
+get_frame_addr ( const unsigned char *addr )
+{
+ unsigned char *base, *regs, *stack, *mem;
+ CFD *dummy;
+ DTC_RESPONSE ret;
+
+ /* first, see if addr is on the saved piece of stack for curframe */
+ if (curframe.format->stack_size > 0 &&
+ (base = (unsigned char *) curframe.traceregs[A7]) <= addr &&
+ addr < base + curframe.format->stack_size)
+ {
+ gdb_puts("STUB: get_frame_addr: call get_addr_to_frame_regs_stack_mem\n");
+ if ((ret = get_addr_to_frame_regs_stack_mem (curframe.frame_data,
+ &dummy,
+ (void *) &regs,
+ (void *) &stack,
+ (void *) &mem))
+ != OK_TARGET_RESPONSE)
+ return (void *) dtc_error_ret (-1,
+ "get_addr_to_frame_regs_stack_mem",
+ ret);
+ else
+ return stack + (addr - base);
+ }
+
+ /* Next, try to find addr in the current frame's expression-
+ collected memory blocks. I'm sure this is at least quadradic in
+ time. */
+ {
+ int num_exprs = count_frame_exprs (curframe.frame_data);
+ int expr, block;
+
+ /* Try each expression in turn. */
+ for (expr = 0; expr < num_exprs; expr++)
+ {
+ for (block = 0; ; block++)
+ {
+ T_EXPR_DATA *data;
+ if (adbg_get_expr_data (curframe.frame_data,
+ 'x', expr, block,
+ &data)
+ != OK_TARGET_RESPONSE)
+ break;
+ else if ((unsigned char *) data->address <= addr
+ && addr < ((unsigned char *) data->address + data->size))
+ {
+ /* We have found the right block; is it valid data?
+ Upper-case stamps mean bad data. */
+ if ('A' <= data->stamp && data->stamp <= 'Z')
+ {
+ gdb_puts("STUB: get_frame_addr: adbg_get_expr_data INVALID\n");
+ return (unsigned char *) -1;
+ }
+ else
+ {
+ if (remote_debug > 1)
+ {
+ sprintp(spare_buffer,
+ "STUB: get_frame_addr: got it [%x,%x)\n",
+ data->address, data->address + data->size);
+ gdb_puts(spare_buffer);
+ }
+
+ return (((unsigned char *) &data->data)
+ + (addr - (unsigned char *) data->address));
+ }
+ }
+ }
+ }
+ }
+
+ /* not found, return error */
+ return (unsigned char *) -1;
+}
+
+/*============================================================*/
+
+static long get_uchar ( const unsigned char * addr )
+{
+ unsigned char *frame_addr;
+
+ if ( read_access_violation ( addr ) )
+ return ( -1 ); /* Access error */
+
+ if (curframe.valid) /* if debugging a trace frame? */
+ {
+ /* If the requested address was collected in the current frame,
+ * then fetch and return the data from the trace buffer.
+ */
+ if ((frame_addr = get_frame_addr (addr)) != (unsigned char *) -1)
+ return ( *frame_addr );
+ /* If the requested address is in the Code Section,
+ * let's be magnanimous and read it anyway (else we shall
+ * not be able to disassemble, find function prologues, etc.)
+ */
+ else if (CS_CODE_START <= (unsigned long) addr &&
+ (unsigned long) addr < CS_CODE_START + CS_CODE_SIZE)
+ return (*addr);
+ else
+ return ( -1 ); /* "Access error" (the data was not collected) */
+ }
+ else
+ /* Not debugging a trace frame, read the data from live memory. */
+ return ( *addr ); /* Meaningful result >= 0 */
+}
+#endif
+
+/*============================================================*/
+
+static long set_uchar ( unsigned char * addr, unsigned char val )
+{
+ long check_result = write_access_violation ( addr );
+
+ if ( check_result != 0L )
+ return ( check_result ); /* Access error */
+
+ return ( *addr = val ); /* Successful writing */
+}
+
+/*============================================================*/
+
+/*
+ * Function read_access_violation() below returns TRUE if dereferencing
+ * its argument for reading would cause a bus error - and FALSE otherwise:
+ */
+
+static long read_access_violation ( const void * addr )
+{
+ return ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
+ ( ( addr < NVD_START ) || ( addr >= NVD_END ) ) );
+}
+
+/*============================================================*/
+
+/*
+ * Function write_access_violation() below returns zero if dereferencing
+ * its argument for writing is safe, -1 on a soft error (the argument
+ * falls into the write-protected area), -2 on a hard error (the argument
+ * points to a non-existent memory location). In other words, it returns
+ * FALSE when no bus error is expected - and an error code otherwise:
+ */
+
+static long write_access_violation ( const void * addr )
+{
+ /*
+ * The boundaries of the write-protected area have to be received via
+ * an API provided in the Symmetrix core code. For now, these limits
+ * are hard-coded:
+ */
+
+ if ( ( addr >= RO_AREA_START ) && ( addr < RO_AREA_END ) )
+ return ( -1 ); /* soft error */
+
+ if ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) &&
+ ( ( addr < NVD_START ) || ( addr >= NVD_END ) ) )
+ return ( -2 ); /* hard error */
+
+ return ( 0 );
+}
+
+
+/* read_access_range is like read_access_violation,
+ but returns the number of bytes we can read w/o faulting.
+ that is, it checks an address range and tells us what portion
+ (if any) of the prefix is safe to read without a bus error */
+static long
+read_access_range(const void *addr, long count)
+{
+ if ((addr >= SRAM_START) && (addr < SRAM_END))
+ {
+ if ((char *)addr + count < (char *)SRAM_END)
+ return (count);
+ else
+ return ((char *)SRAM_END - (char *)addr);
+ }
+ else if (((char *)addr >= (char *)NVD_START) &&
+ ((char *)addr < (char *)NVD_END))
+ {
+ if ((char *)addr + count < (char *)NVD_END)
+ return (count);
+ else
+ return ((char *)NVD_END - (char *)addr);
+ }
+ else
+ return (0);
+}
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+ Return SUCCESS or FAIL.
+ If MAY_FAULT is non-zero, then we should return FAIL in response to
+ a fault; if zero treat a fault like any other fault in the stub. */
+
+static long
+mem2hex(unsigned char *mem, char *buf, long count, long may_fault)
+{
+ long ndx;
+ long ndx2;
+ long ch;
+ long incr;
+ unsigned char *location;
+ DTC_RESPONSE status;
+
+ if (may_fault)
+ {
+ for (ndx = 0, incr = 1; (ndx < count) && (incr > 0); ndx += incr)
+ {
+ status = find_memory(mem, count - ndx, &location, &incr);
+
+ if (status == OK_TARGET_RESPONSE)
+ {
+ if (incr > 0)
+ {
+ for (ndx2 = 0; ndx2 < incr; ndx2++)
+ {
+ ch = *location++;
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch & 0xf];
+ }
+ mem += incr;
+ }
+ else if (incr <= 0) /* should never happen */
+ {
+ *buf = 0;
+ return (0);
+ }
+ }
+ else if (status == NOT_FOUND_TARGET_RESPONSE)
+ {
+ *buf = 0;
+ return (ndx); /* return amount copied */
+ }
+ else
+ {
+ *buf = 0;
+ return (0); /* XXX: how do we tell the user the status? */
+ }
+ }
+ *buf = 0;
+ return (count);
+ }
+ else
+ {
+ for (ndx = 0; ndx < count; ndx++)
+ {
+ ch = *mem++;
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch & 0xf];
+ }
+ *buf = 0;
+ return (count); /* we copied everything */
+ }
+}
+
+static DTC_RESPONSE
+find_memory(unsigned char *mem, long count,
+ unsigned char **location, long *incr)
+{
+ DTC_RESPONSE retval;
+ long length;
+
+ /* figure out how much of the memory range we can read w/o faulting */
+ count = read_access_range(mem, count);
+ if (count == 0)
+ return (NOT_FOUND_TARGET_RESPONSE);
+
+ if (curframe.valid)
+ {
+ unsigned char *mem_block;
+ unsigned char *mem_addr;
+ unsigned long mem_size;
+ unsigned long mem_stamp;
+
+ retval = adbg_find_memory_addr_in_frame(curframe.frame_data, mem,
+ (unsigned long **)&mem_block,
+ (unsigned long **)&mem_addr,
+ &mem_size, &mem_stamp);
+
+ switch (retval)
+ {
+ case OK_TARGET_RESPONSE:
+#if 0
+ printp("FOUND: mem %x block %x addr %x size %d stamp %x\n",
+ mem, mem_block, mem_addr, mem_size, mem_stamp);
+#endif
+ *location = mem_block + (mem - mem_addr);
+ length = mem_size - (mem - mem_addr);
+
+ if (length < count)
+ *incr = length;
+ else
+ *incr = count;
+
+ break;
+
+ case NOT_FOUND_TARGET_RESPONSE:
+ case NEAR_FOUND_TARGET_RESPONSE:
+#if 0
+ printp("NOT FOUND: mem %x, checking code region\n", mem);
+#endif
+ /* check to see if it's in the code region */
+ if ((CS_CODE_START <= (long)mem) &&
+ ((long)mem < CS_CODE_START + CS_CODE_SIZE))
+ {
+ /* some or all of the address range is in the code */
+ *location = mem;
+ if ((long)mem + count <= CS_CODE_START + CS_CODE_SIZE)
+ *incr = count; /* it's totally in the code */
+ else
+ /* how much is in the code? */
+ *incr = CS_CODE_START + CS_CODE_SIZE - (long)mem;
+#if 0
+ printp("FOUND in code region: %x\n", mem);
+#endif
+ retval = OK_TARGET_RESPONSE;
+ }
+ else
+ retval = NOT_FOUND_TARGET_RESPONSE;
+
+ break;
+
+ default:
+#if 0
+ printp("BAD RETURN: %d\n", retval);
+#endif
+ retval = NOT_FOUND_TARGET_RESPONSE;
+ break;
+ }
+ }
+ else
+ {
+ *location = mem;
+ *incr = count;
+ retval = OK_TARGET_RESPONSE;
+ }
+
+ return (retval);
+}
+
+/* Convert the hex array pointed to by buf into binary to be placed in mem.
+ Return SUCCESS or FAIL. */
+
+static long
+hex2mem( char *buf, unsigned char *mem, long count, long may_fault )
+{
+ long i, ch;
+
+ for ( i=0; i<count; i++ )
+ {
+ ch = hex( *buf++ ) << 4;
+ ch = ch + hex( *buf++ );
+ if ( may_fault )
+ {
+ ch = set_uchar( mem++, ch );
+ if ( ch < 0 ) /* negative return indicates error */
+ return FAIL;
+ }
+ else
+ *mem++ = ch;
+ }
+ return SUCCESS;
+}
+
+/**********************************************/
+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
+/* RETURN NUMBER OF CHARS PROCESSED */
+/**********************************************/
+
+static int
+hexToInt( char **ptr, unsigned long *intValue )
+{
+ long numChars = 0;
+ long hexValue;
+
+ *intValue = 0;
+ while ( **ptr )
+ {
+ hexValue = hex( **ptr );
+ if ( hexValue >=0 )
+ {
+ *intValue = (*intValue << 4) | hexValue;
+ numChars ++;
+ }
+ else
+ break;
+ (*ptr)++;
+ }
+ return numChars;
+}
+
+static volatile long gdb_handling_trap1;
+static volatile long gdb_handling_sstrace;
+static volatile long gdb_signo;
+
+/*
+ Here is the "callable" stub entry point.
+ Call this function with a GDB request as an argument,
+ and it will service the request and return.
+
+ May be further broken up as we go along, with individual requests
+ broken out as separate functions.
+ */
+
+static char * handle_trace_query (char *);
+static char * handle_trace_set (char *);
+static int handle_format (char **request, CFD *format);
+static unsigned long crc32 (unsigned char *buf, int len, unsigned long crc);
+static char * crc_query (char *);
+static char * handle_test (char *);
+
+void
+handle_request( char *request )
+{
+#if 0
+ remote_debug = 2;
+#endif
+ switch( *request++ )
+ {
+ case 'k': /* "kill" */
+ curframe.valid = FALSE;
+ putpacket ("");
+ break;
+ case 'D': /* "detach" */
+ curframe.valid = FALSE;
+ putpacket ("");
+ break;
+ default: /* Unknown code. Return an empty reply message. */
+ putpacket( "" ); /* return empty packet */
+ break;
+
+ case 'H': /* Set thread for subsequent operations.
+ Hct... c = 'c' for thread used in step and continue;
+ t... can be -1 for all threads.
+ c = 'g' for thread used in other operations.
+ If zero, pick a thread, any thread. */
+
+ putpacket( "OK" );
+ break;
+
+ case 'g': /* Read registers.
+ Each byte of register data is described by
+ two hex digits. registers are in the
+ internal order for GDB, and the bytes in a
+ register are in the same order the machine
+ uses. */
+ {
+ /* Return the values in (one of) the registers cache(s).
+ Several situations may pertain:
+ 1) We're synchronous, in which case the "registers" array
+ should actually be current.
+ 2) We're asynchronous, in which case the "registers" array
+ holds whatever was cached most recently.
+ 3) We're looking at a trace frame that was collected earlier:
+ we will return those earlier registers.
+ */
+
+ /* all registers default to zero */
+ memset (outbuffer, '0', NUMREGBYTES);
+ outbuffer[NUMREGBYTES] = '\0';
+
+ if (curframe.valid) /* debugging a trace frame */
+ mem2hex( (unsigned char*) curframe.traceregs,
+ outbuffer, NUMREGBYTES, 0 );
+ else
+ mem2hex( (unsigned char*) registers, outbuffer, NUMREGBYTES, 0 );
+
+ putpacket( outbuffer );
+ }
+ break;
+ case 'G': /* Write registers.
+ Gxxxxxxxx Each byte of register data is described by
+ two hex digits. */
+ if (curframe.valid) /* debugging a trace frame */
+ putpacket ("E03"); /* can't write regs into a trace frame! */
+ else
+ {
+ /* Write the values into the local registers cache...
+ Note that no actual registers are being changed. */
+
+ hex2mem( request,
+ (unsigned char *) registers, NUMREGBYTES, 0 );
+ putpacket( "OK" );
+ }
+ break;
+ case 'P': /* Write (single) register.
+ Pnn=xxxxxxxx register nn gets value xxxxxxxx;
+ two hex digits for each byte in the register
+ (target byte order). */
+
+ if (curframe.valid)
+ putpacket ("E03"); /* can't write regs into a trace frame! */
+ else
+ {
+ unsigned long regno;
+
+ if ( hexToInt( &request, &regno ) && *(request++) == '=' )
+ {
+ if ( regno < NUMREGS )
+ {
+ hexToInt( &request,
+ (unsigned long *) &registers[REGISTER_BYTE(regno)]);
+
+ putpacket( "OK" );
+ }
+ else
+ putpacket( "E01" ); /* bad packet or regno */
+ }
+ }
+ break;
+ case 'm': /* Read memory.
+ mAAAAAAAA,LLLL AAAAAAAA is address, LLLL is length.
+ Reply can be fewer bytes than requested
+ if able to read only part of the data. */
+ {
+ unsigned long addr, len;
+
+ if ( hexToInt( &request, &addr ) &&
+ *(request++) == ',' &&
+ hexToInt( &request, &len ) )
+ {
+ /* better not overwrite outbuffer! */
+ if ( len > (BUFMAX / 2) - 5 )
+ len = (BUFMAX / 2) - 5;
+ if (mem2hex((unsigned char *) addr, outbuffer, len, 1) == 0) /* XXX: eventually use returned value */
+ putpacket( "E03" ); /* read fault (access denied) */
+ else
+ putpacket( outbuffer ); /* read succeeded */
+ }
+ else
+ putpacket( "E01" ); /* badly formed read request */
+
+ }
+ break;
+ case 'M': /* Write memory.
+ Maaaaaaaa,llll:xxxx aaaaaaaa is address, llll is length;
+ xxxx is data to write. */
+
+ {
+ unsigned long addr, len;
+
+ if (curframe.valid) /* can't write memory into a trace frame! */
+ putpacket ("E03"); /* "access denied" */
+ else /*** if ( write_access_enabled ) ***/
+ {
+ if ( hexToInt( &request, &addr ) &&
+ *(request++) == ',' &&
+ hexToInt( &request, &len ) &&
+ *(request++) == ':' )
+ {
+ if (len == 2 &&
+ addr >= CS_CODE_START &&
+ addr <= LAST_CS_WORD)
+ {
+ unsigned long val;
+
+ if ( !hexToInt( &request, &val ) ||
+ write_to_protected_mem( (void *)addr, val ) )
+ putpacket( "E03" ); /* write fault (access denied) */
+ else
+ putpacket( "OK" ); /* write succeeded */
+ }
+ else
+ {
+ if ( hex2mem( request, (unsigned char*) addr, len, 1 ) )
+ putpacket( "E03" ); /* write fault (access denied) */
+ else
+ putpacket( "OK" ); /* write succeeded */
+ }
+ }
+ else
+ putpacket( "E02" ); /* badly formed write request */
+ }
+ }
+ break;
+ case 'c': /* Continue.
+ cAAAAAAAA AAAAAAAA is address from which to resume.
+ If omitted, resume at current PC. */
+
+ {
+ unsigned long addr;
+
+ if (curframe.valid)
+ {
+ /* Don't continue if debugging a trace frame! */
+ gdb_puts ("Error: can't continue!\n");
+ putpacket ("S03");
+ }
+ else
+ {
+ gdb_signo = 3;
+ if (isxdigit(request[0]))
+ {
+ hexToInt(&request, &addr);
+ registers[REGISTER_BYTE(PC)] = addr;
+ }
+
+ gdb_handling_trap1 = FALSE;
+ gdb_handling_sstrace = FALSE;
+ sss_trace_flag = '\0';
+ }
+ }
+ break;
+ case 's': /* Step.
+ sAAAAAAAA AAAAAAAA is address from which to begin stepping.
+ If omitted, begin stepping at current PC. */
+ {
+ unsigned long addr;
+
+ if (curframe.valid)
+ {
+ /* Don't step if debugging a trace frame! */
+ gdb_puts ("Error: can't step!\n");
+ putpacket ("S03");
+ }
+ else
+ {
+ gdb_signo = 3;
+ if (isxdigit(request[0]))
+ {
+ hexToInt(&request, &addr);
+ registers[REGISTER_BYTE(PC)] = addr;
+ }
+
+ gdb_handling_trap1 = FALSE;
+ gdb_handling_sstrace = FALSE;
+ sss_trace_flag = 't';
+ }
+ }
+ break;
+ case 'C': /* Continue with signal.
+ Cxx;AAAAAAAA xx is signal number in hex;
+ AAAAAAAA is adddress from which to resume.
+ If ;AAAAAAAA omitted, continue from PC. */
+
+ {
+ unsigned long addr = 0;
+
+ if (!gdb_handling_trap1 || curframe.valid)
+ {
+ /* Don't continue if not currently in synchronous mode,
+ or if currently debugging a trace frame! */
+ gdb_puts( "Error: can't continue!\n" );
+ putpacket( "S03" ); /* "sigquit" (better idea?) */
+ }
+ else
+ {
+ gdb_signo = 3;
+ if ( isxdigit( *request ) )
+ {
+ hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
+ request += 2;
+ if ( *request == ';' && isxdigit( *++request ) )
+ {
+ hexToInt( &request, &addr );
+ registers[REGISTER_BYTE(PC)] = addr;
+ }
+ }
+ gdb_handling_trap1 = FALSE;
+ gdb_handling_sstrace = FALSE;
+ sss_trace_flag = '\0';
+ }
+ }
+ break;
+ case 'S': /* Step with signal.
+ Sxx;AAAAAAAA xx is signal number in hex;
+ AAAAAAAA is adddress from which to begin stepping.
+ If ;AAAAAAAA omitted, begin stepping from PC. */
+ {
+ unsigned long addr = 0;
+
+ if (!gdb_handling_trap1 || curframe.valid)
+ {
+ /* Don't step if not currently in synchronous mode,
+ or if currently debugging a trace frame! */
+ gdb_puts( "Error: can't step!\n" );
+ putpacket( "S03" ); /* "sigquit" (better idea?) */
+ }
+ else
+ {
+ gdb_signo = 3;
+ if ( isxdigit( *request ) )
+ {
+ hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 );
+ request += 2;
+ if ( *request == ';' && isxdigit( *++request ) )
+ {
+ hexToInt( &request, &addr );
+ registers[REGISTER_BYTE(PC)] = addr;
+ }
+ }
+ gdb_handling_trap1 = FALSE;
+ gdb_handling_sstrace = FALSE;
+ sss_trace_flag = 't';
+ }
+ }
+ break;
+ case '?': /* Query the latest reason for stopping.
+ Should be same reply as was last generated
+ for step or continue. */
+
+ if ( gdb_signo == 0 )
+ gdb_signo = 3; /* default to SIGQUIT */
+ outbuffer[ 0 ] = 'S';
+ outbuffer[ 1 ] = hexchars[ gdb_signo >> 4 ];
+ outbuffer[ 2 ] = hexchars[ gdb_signo & 0xf ];
+ outbuffer[ 3 ] = 0;
+ putpacket( outbuffer );
+ break;
+
+ case 'd': /* Toggle debug mode
+ I'm sure we can think of something interesting. */
+
+ remote_debug = !remote_debug;
+ putpacket( "" ); /* return empty packet */
+ break;
+
+ case 'q': /* general query */
+ switch (*request++)
+ {
+ default:
+ putpacket (""); /* nak a request which we don't handle */
+ break;
+ case 'T': /* trace query */
+ putpacket (handle_trace_query (request));
+ break;
+ case 'C': /* crc query (?) */
+ if (*request++ == 'R' &&
+ *request++ == 'C' &&
+ *request++ == ':')
+ putpacket (crc_query (request));
+ else
+ putpacket (""); /* unknown query */
+ break;
+ }
+ break;
+
+ case 'Q': /* general set */
+ switch (*request++)
+ {
+ default:
+ putpacket (""); /* nak a request which we don't handle */
+ break;
+ case 'T': /* trace */
+ putpacket (handle_trace_set (request));
+ break;
+ }
+ break;
+
+ case 'T':
+ /* call test function: TAAA,BBB,CCC
+ A, B, and C are arguments to pass to gdb_c_test. Reply is
+ "E01" (bad arguments) or "OK" (test function called). */
+ putpacket (handle_test (request));
+ break;
+ }
+}
+
+static TDP_SETUP_INFO tdp_temp;
+static int trace_running;
+
+/*
+ * Function msgcmp:
+ *
+ * If second argument (str) is matched in first argument,
+ * then advance first argument past end of str and return "SAME"
+ * else return "DIFFERENT" without changing first argument.
+ *
+ * Return: zero for DIFFERENT, non-zero for SUCCESS
+ */
+
+static int
+msgcmp (char **msgp, char *str)
+{
+ char *next;
+
+ if (msgp != 0 && str != 0) /* input validation */
+ if ((next = *msgp) != 0)
+ {
+ for (;
+ *next && *str && *next == *str;
+ next++, str++)
+ ;
+
+ if (*str == 0) /* matched all of str in msg */
+ return (int) (*msgp = next); /* advance msg ptr past str */
+ }
+ return 0; /* failure */
+}
+
+static char *
+handle_trace_query (char *request)
+{
+ if (msgcmp (&request, "Status"))
+ {
+ if (adbg_check_if_active ())
+ {
+ gdb_puts ("Target trace is running.\n");
+ return "T1";
+ }
+ else
+ {
+ gdb_puts ("Target trace not running.\n");
+ trace_running = 0;
+ return "T0";
+ }
+ }
+ else /* unknown trace query */
+ {
+ return "";
+ }
+}
+
+static void
+gdb_note (char *fmt, int arg1)
+{
+ if (remote_debug > 1)
+ {
+ sprintp (spare_buffer, fmt, arg1);
+ gdb_puts (spare_buffer);
+ }
+}
+
+static int
+error_ret (int ret, char *fmt, int arg1)
+{
+ if (remote_debug > 0)
+ {
+ sprintp (spare_buffer, fmt, arg1);
+ gdb_puts (spare_buffer);
+ }
+ return ret;
+}
+
+static int
+handle_format (char **request, COLLECTION_FORMAT_DEF *format)
+{
+ MEMRANGE_DEF m;
+ DTC_RESPONSE ret;
+ int elinum;
+ unsigned long regnum;
+ long bytecodes[(MAX_BYTE_CODES + sizeof (struct t_expr_tag))/ 4];
+ struct t_expr_tag *t_expr = (struct t_expr_tag *)bytecodes;
+
+ if (format->id == 0)
+ {
+ if ((ret = get_unused_format_id (&format->id)) != OK_TARGET_RESPONSE)
+ return dtc_error_ret (-1, "get_unused_format_id", ret);
+
+ if (**request == 'R')
+ {
+ (*request)++;
+ hexToInt (request, &format->regs_mask);
+ }
+ gdb_note ("STUB: call define_format (id = %d, ", format->id);
+ gdb_note ("regs_mask = 0x%X);\n", format->regs_mask);
+
+ if ((ret = define_format (format)) != OK_TARGET_RESPONSE)
+ {
+ sprintp (spare_buffer,
+ "'define_format': DTC error '%s' for format id %d.\n",
+ get_err_text (ret),
+ format->id);
+ gdb_puts (spare_buffer);
+ return -1;
+ }
+ }
+
+ while ((**request == 'M') || (**request == 'X'))
+ {
+ switch (**request)
+ {
+ case 'M': /* M<regnum>,<offset>,<size> */
+ (*request)++;
+ hexToInt(request, &regnum);
+
+ if (regnum == 0 || regnum == (unsigned long) -1)
+ m.typecode = -1;
+ else if ((elinum = index_to_elinum (regnum)) > 0)
+ m.typecode = elinum;
+ else
+ return error_ret (-1,
+ "Memrange register %d is not between 0 and 15\n",
+ regnum);
+
+ if (*(*request)++ != ',')
+ return error_ret (-1,"Malformed memrange (comma #%d missing)\n",1);
+ hexToInt(request, &m.offset);
+ if (*(*request)++ != ',')
+ return error_ret (-1,"Malformed memrange (comma #%d missing)\n",2);
+ hexToInt(request, &m.size);
+
+ gdb_note ("STUB: call add_format_mem_range (typecode = 0x%x, ",
+ m.typecode);
+ gdb_note ("offset = 0x%X, ", m.offset);
+ gdb_note ("size = %d);\n", m.size);
+ if ((ret = add_format_mem_ranges (format->id, &m)) !=
+ OK_TARGET_RESPONSE)
+ {
+ dtc_error_ret (-1, "add_format_mem_ranges", ret);
+ sprintp (spare_buffer,
+ "format id %d: memrange (0x%x, 0x%x, 0x%x).\n",
+ format->id, m.typecode, m.offset, m.size);
+ gdb_puts (spare_buffer);
+ return -1;
+ }
+ break;
+
+ case 'X': /* X<length>,<bytecodes> */
+ {
+ unsigned long length;
+
+ (*request)++;
+ hexToInt(request, &length);
+
+ if ((length <= 0) || (length > MAX_BYTE_CODES))
+ return error_ret (-1,
+ "Bytecode expression length (%d) too large\n",
+ length);
+
+ if (*(*request)++ != ',')
+ return error_ret (-1,
+ "Malformed bytecode expr (comma#%d missing)\n",
+ 1);
+ t_expr->next = NULL;
+ /* subtract one to account for expr[0] in header */
+ t_expr->size = sizeof(struct t_expr_tag) + length - 1;
+ t_expr->expr_size = length;
+
+ hex2mem(*request, &t_expr->expr[0], length, 0);
+ *request += 2 * length;
+ build_and_add_expression(format->id, t_expr);
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+static char *
+handle_trace_set (char *request)
+{
+ long n_frame;
+ unsigned long frameno, tdp, pc, start, stop;
+ DTC_RESPONSE ret = -1;
+ static COLLECTION_FORMAT_DEF tempfmt1;
+ static char enable;
+ static char retbuf[20];
+
+ if (msgcmp (&request, "init"))
+ {
+ gdb_note ("STUB: call clear_trace_state();\n", 0);
+ curframe.valid = 0; /* all old frames become invalid now */
+ if ((ret = clear_trace_state ()) == OK_TARGET_RESPONSE)
+ return "OK";
+ else
+ {
+ sprintp (retbuf, "E2%x", ret);
+ return (char *) dtc_error_ret ((int) &retbuf,
+ "clear_trace_state",
+ ret);
+ }
+ }
+ else if (msgcmp (&request, "Start"))
+ {
+ trace_running = 1;
+ curframe.valid = 0; /* all old frames become invalid now */
+ gdb_note ("STUB: call start_trace_experiment();\n", 0);
+ adbg_save_trace_in_nvd ();
+ if ((ret = start_trace_experiment ()) == OK_TARGET_RESPONSE)
+ return "OK";
+ else
+ {
+ sprintp (retbuf, "E2%x", ret);
+ return (char *) dtc_error_ret ((int) &retbuf,
+ "start_trace_experiment",
+ ret);
+ }
+ }
+ else if (msgcmp (&request, "Stop"))
+ {
+ trace_running = 0;
+ if (adbg_check_if_active ())
+ {
+ gdb_note ("STUB: call end_trace_experiment();\n", 0);
+ if ((ret = end_trace_experiment ()) == OK_TARGET_RESPONSE)
+ return "OK";
+ else
+ {
+ sprintp (retbuf, "E2%x", ret);
+ return (char *) dtc_error_ret ((int) &retbuf,
+ "end_trace_experiment",
+ ret);
+ }
+ }
+ else return "OK";
+ }
+ /* "TDP:" (The 'T' was consumed in handle_request.) */
+ else if (msgcmp (&request, "DP:"))
+ {
+ /* TDP:<id>:<addr>:{D,E}:<stepcount>:<pass_limit>{R[M,X]+}<tdp-format>
+ {S{R[M,X]+}}<tp-format>
+
+ D -- disable tracepoint (illegal from EMC's point of view)
+ E -- enable tracepoint?
+
+ R -- regs format: R<regs-mask>
+ M -- memory format: M<regnum>,<offset>,<size>
+ X -- expr format: X<size>,<bytecodes>
+ S -- fencepost between trap formats and stepping formats.
+ */
+
+ /* state variable, required for splitting TDP packets. */
+ static int doing_step_formats;
+
+ /*
+ * TDP: packets may now be split into multiple packets.
+ * If a TDP packet is to be continued in another packet, it
+ * must end in a "-" character. The subsequent continuation
+ * packet will then begin with a "-" character, between the
+ * token "TDP:" and the tdp_id field. The ID and address
+ * will be repeated in each sub-packet. The step_count,
+ * pass_count, and 'enabled' field must appear in the first
+ * packet. The boundary between sub-packets may not appear
+ * between the "S" that denotes the start of stepping "formats",
+ * and the regs_mask that follows it. The split may also not
+ * occur in the middle of either a memrange description or a
+ * bytecode string. -- MVS
+ */
+
+ if (*request == '-') /* this is a continuation of a
+ trace definition in progress */
+ {
+ unsigned long temp_id, temp_addr;
+
+ request++;
+ if (!(hexToInt (&request, &temp_id) &&
+ *request++ == ':'))
+ return "E11"; /* badly formed packet, field 1 */
+
+ if (!(hexToInt (&request, (unsigned long *) &temp_addr) &&
+ *request++ == ':'))
+ return "E12"; /* badly formed packet, field 2 */
+
+ if (temp_id != tdp_temp.id)
+ return "E11"; /* something wrong: field 1 doesn't match */
+ if (temp_addr != (unsigned long) tdp_temp.addr)
+ return "E12"; /* something wrong: field 2 doesn't match */
+ }
+ else /* This is a new TDP definition */
+ {
+ memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
+ memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
+ doing_step_formats = FALSE;
+
+ if (!(hexToInt (&request, &tdp_temp.id) &&
+ *request++ == ':'))
+ return "E11"; /* badly formed packet, field 1 */
+
+ if (!(hexToInt (&request, (unsigned long *) &tdp_temp.addr) &&
+ *request++ == ':'))
+ return "E12"; /* badly formed packet, field 2 */
+
+ if (!(((enable = *request++) == 'D' || enable == 'E') &&
+ *request++ == ':'))
+ return "E13"; /* badly formed packet, field 3 */
+#if 0
+ if (enable == 'D')
+ {
+ gdb_puts ("Disabling of tracepoints not supported by EMC target\n");
+ return "E20";
+ }
+#endif
+ if (!(hexToInt (&request, &tdp_temp.stepcount) &&
+ *request++ == ':'))
+ return "E14"; /* badly formed packet, field 4 */
+
+ if (!hexToInt (&request, &tdp_temp.pass_limit))
+ return "E15"; /* badly formed packet, field 5 */
+
+ }
+
+ /* Typically, the first group of collection descriptors
+ refers to the trap collection. There is an "S" token
+ to act as a fencepost between collection descriptors for
+ the trap, and those for the single-stepping.
+
+ However, when the packet is split up into several packets,
+ this "S" token may already have been seen in a previous
+ sub-packet; so we have to remember it in a state variable. */
+
+ if (*request == 'R' || *request == 'M' || *request == 'X')
+ {
+ if (handle_format (&request, &tempfmt1))
+ return "E16";
+ if (doing_step_formats)
+ tdp_temp.tp_format_p = tempfmt1.id;
+ else
+ tdp_temp.tdp_format_p = tempfmt1.id;
+ }
+
+ /* When we see the "S" token, we remember it in a state variable
+ (in case the packet is split up and continued in another message),
+ and discard all current state from the collection "format". */
+ if (*request == 'S')
+ {
+ doing_step_formats = TRUE;
+ /* discard prev format and start a new one */
+ memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
+ request++;
+
+ /* Having seen the "S" fencepost, it is now possible that
+ we will see some more collection descriptors pertaining
+ to the stepping collection. */
+ if (*request == 'R' || *request == 'M' || *request == 'X')
+ {
+ if (handle_format (&request, &tempfmt1))
+ return "E17";
+ /* new format ID is tp_format */
+ tdp_temp.tp_format_p = tempfmt1.id;
+ }
+ }
+
+ if (*request == '-') /* this TDP definition will be continued. */
+ sprintp (retbuf, "OK");
+ else if (enable == 'E') /* end of TDP definition: pass to ADBG (if enabled!) */
+ {
+ gdb_note ("STUB: call define_tdp (id %d, ", tdp_temp.id);
+ gdb_note ("addr 0x%X, ", (int) tdp_temp.addr);
+ gdb_note ("passc %d, ", tdp_temp.pass_limit);
+ gdb_note ("stepc %d, ", tdp_temp.stepcount);
+ gdb_note ("TDP fmt #%d, ", tdp_temp.tdp_format_p);
+ gdb_note ("TP fmt #%d);\n", tdp_temp.tp_format_p);
+
+ ret = define_tdp (tdp_temp.id, &tdp_temp, 0);
+
+ if (ret == OK_TARGET_RESPONSE)
+ {
+ sprintp (retbuf, "OK");
+ }
+ else
+ {
+ sprintp (spare_buffer,
+ "'define_tdp' returned DTC error '%s' for tracepoint %d.\n",
+ get_err_text (ret),
+ tdp_temp.id);
+ gdb_puts (spare_buffer);
+ sprintp (retbuf, "E2%x", ret);
+ }
+ /* Redundant, but let's try to make sure this state gets discarded. */
+ {
+ memset ((char *) &tdp_temp, 0, sizeof (tdp_temp));
+ memset ((char *) &tempfmt1, 0, sizeof (tempfmt1));
+ }
+ }
+ else /* ADBG_DTC does not support disabled tracepoints -- ignore it. */
+ gdb_note ("STUB: ignoring disabled tracepoint %d.\n", tdp_temp.id);
+
+ return retbuf;
+ }
+ else if (msgcmp (&request, "Frame:"))
+ {
+ ret = OK_TARGET_RESPONSE;
+
+ if (msgcmp (&request, "pc:"))
+ {
+ if (!hexToInt (&request, &pc))
+ return "E10"; /* badly formed packet */
+ n_frame = curframe.valid ? curframe.frame_id + 1 : 0;
+ gdb_note ("STUB: call fetch_trace_frame_pc (id %d, ", n_frame);
+ gdb_note ("pc 0x%X);\n", pc);
+ ret = fetch_trace_frame_with_pc (&n_frame,
+ (void *) pc,
+ &curframe.format,
+ &curframe.frame_data);
+ }
+ else if (msgcmp (&request, "tdp:"))
+ {
+ if (!hexToInt (&request, &tdp))
+ return "E10"; /* badly formed packet */
+ n_frame = curframe.valid ? curframe.frame_id + 1: 0;
+ gdb_note ("STUB: call fetch_trace_frame_tdp (id %d, ", n_frame);
+ gdb_note ("tdp 0x%X);\n", tdp);
+ ret = fetch_trace_frame_with_tdp (&n_frame,
+ tdp,
+ &curframe.format,
+ &curframe.frame_data);
+ }
+ else if (msgcmp (&request, "range:"))
+ {
+ if (!(hexToInt (&request, &start) &&
+ *request++ == ':'))
+ return "E11"; /* badly formed packet, field 1 */
+ else if (!hexToInt (&request, &stop))
+ return "E12"; /* badly formed packet, field 2 */
+ n_frame = curframe.valid ? curframe.frame_id + 1: 0;
+ gdb_note ("STUB: call fetch_trace_frame_range (id %d, ", n_frame);
+ gdb_note ("start 0x%X, ", start);
+ gdb_note ("stop 0x%X);\n", stop);
+ ret = fetch_trace_frame_with_pc_in_range (&n_frame,
+ (void *) start,
+ (void *) stop,
+ &curframe.format,
+ &curframe.frame_data);
+ }
+ else if (msgcmp (&request, "outside:"))
+ {
+ if (!(hexToInt (&request, &start) &&
+ *request++ == ':'))
+ return "E11"; /* badly formed packet, field 1 */
+ else if (!hexToInt (&request, &stop))
+ return "E12"; /* badly formed packet, field 2 */
+ n_frame = curframe.valid ? curframe.frame_id + 1: 0;
+ gdb_note ("STUB: call fetch_trace_frame_outside (id %d, ", n_frame);
+ gdb_note ("start 0x%X, ", start);
+ gdb_note ("stop 0x%X);\n", stop);
+ ret = fetch_trace_frame_with_pc_outside (&n_frame,
+ (void *) start,
+ (void *) stop,
+ &curframe.format,
+ &curframe.frame_data);
+ }
+ else /* simple TFind by frame number: */
+ {
+ if (!hexToInt (&request, &frameno))
+ return "E10"; /* badly formed packet */
+ if (frameno != (unsigned long) -1)
+ {
+ gdb_note ("STUB: call fetch_trace_frame (id %d);\n", frameno);
+ ret = fetch_trace_frame (n_frame = frameno,
+ &curframe.format,
+ &curframe.frame_data);
+#if 0
+ printp("STUB: fetch_trace_frame: return %d\n", ret);
+#endif
+ }
+ else /* discard any trace frame, debug "the real world" */
+ {
+ if (curframe.valid)
+ gdb_note ("STUB: discard current trace frame #%d.\n",
+ curframe.frame_id);
+ curframe.valid = 0;
+ return "OK";
+ }
+ }
+ if (ret == OK_TARGET_RESPONSE) /* fetch_trace_frame succeeded */
+ { /* setup for debugging the trace frame */
+ curframe.valid = 1;
+ curframe.frame_id = n_frame;
+ curframe.tdp_id = curframe.frame_data->id;
+
+ memset ((char *) &curframe.traceregs, 0,
+ sizeof (curframe.traceregs));
+ curframe.traceregs[PC] = (unsigned long)
+ curframe.frame_data->program_counter;
+
+ if (curframe.format)
+ {
+ unsigned long regs_mask = curframe.format->regs_mask;
+ unsigned long *regs, *stack, *mem;
+ unsigned long regno, index = 0;
+ CFD *dummy;
+
+ if ((ret = get_addr_to_frame_regs_stack_mem
+ (curframe.frame_data, &dummy, &regs, &stack, &mem))
+ != OK_TARGET_RESPONSE)
+ {
+ curframe.valid = 0;
+ sprintp (retbuf, "E2%x", ret);
+ return (char *)
+ dtc_error_ret ((int) &retbuf,
+ "get_addr_to_frame_regs_stack_mem",
+ ret);
+ }
+
+ if (remote_debug > 1)
+ { /* echo what we've found to gdb console */
+ sprintp (spare_buffer,
+ "STUB: Found frame %d, TDP %d, format %d (%s):\n",
+ curframe.frame_id,
+ curframe.tdp_id & 0x7fffffff,
+ curframe.format->id,
+ curframe.tdp_id & 0x80000000 ?
+ "trap frame" : "stepping frame");
+ gdb_puts (spare_buffer);
+ }
+ /* copy trace frame regs into stub's data format */
+ for (regno = 0, index = 0;
+ regno < 16;
+ regno++, regs_mask >>= 1)
+ if (regs_mask & 1) /* got a collected register */
+ {
+ curframe.traceregs[regno] = regs[index++];
+ if (remote_debug > 1)
+ {
+ sprintp (spare_buffer,
+ " Collected 0x%08x for register %d.\n",
+ curframe.traceregs[regno], regno);
+ gdb_puts (spare_buffer);
+ }
+ }
+ if (remote_debug > 1)
+ {
+ long midx, ridx, len;
+ MEMRANGE_DEF *mrange;
+ unsigned char *data, *base;
+
+ if (curframe.format->stack_size > 0)
+ {
+ len = curframe.format->stack_size;
+ sprintp (spare_buffer,
+ " Collected %d bytes of stack at 0x%x:\n",
+ len, curframe.traceregs[A7]);
+ gdb_puts (spare_buffer);
+
+ /* print stack data, but stay under msg len */
+ if (len >= (NUMREGBYTES/2 - 2))
+ len = (NUMREGBYTES/2 - 3);
+ mem2hex ((unsigned char *) stack,
+ spare_buffer, len, 0);
+ spare_buffer [len * 2] = '\n';
+ spare_buffer [len * 2 + 1] = '\0'; /* EOS */
+ gdb_puts (spare_buffer);
+ }
+ else
+ gdb_puts ("Stack not collected\n");
+
+ for (midx = 0;
+ get_addr_to_a_mem_range (curframe.frame_data,
+ midx,
+ &mrange,
+ (void **) &data)
+ == OK_TARGET_RESPONSE;
+ midx++)
+ {
+ if ((mrange->typecode == 0) ||
+ (mrange->typecode == (unsigned long) -1))
+ {
+ sprintp (spare_buffer,
+ " Collected %d bytes at MEM: 0x%x:\n",
+ mrange->size, mrange->offset);
+ base = (unsigned char *) mrange->offset;
+ }
+ else
+ {
+ if ((ridx = elinum_to_index (mrange->typecode)) > 0)
+ base = (unsigned char *) curframe.traceregs[ridx]
+ + (long) mrange->offset;
+ else
+ {
+ sprintp (spare_buffer,
+ "STUB: bad typecode in memrange #%d: (0x%x,0x%x,0x%x).\n",
+ midx,
+ mrange->typecode,
+ mrange->offset,
+ mrange->size);
+ gdb_puts (spare_buffer);
+ continue;
+ }
+ sprintp (spare_buffer,
+ " Collected %d bytes at 0x%x (REG %X + %d):\n",
+ mrange->size,
+ base,
+ mrange->typecode,
+ mrange->offset);
+ }
+ gdb_puts (spare_buffer);
+ len = mrange->size;
+ if (len >= (NUMREGBYTES/2 - 2))
+ len = (NUMREGBYTES/2 - 3);
+ mem2hex (data, spare_buffer, len, 0);
+ spare_buffer [len * 2] = '\n';
+ spare_buffer [len * 2 + 1] = '\0'; /* EOS */
+ gdb_puts (spare_buffer);
+ }
+ }
+ }
+ sprintp (retbuf, "F%xT%x", n_frame, curframe.tdp_id & 0x7fffffff);
+ return retbuf;
+ }
+ else if (ret == NOT_FOUND_TARGET_RESPONSE)
+ {
+ /* Here's a question: if the fetch_trace_frame call failed
+ (which probably means a bad "TFIND" command from GDB),
+ should we remain focused on the previous frame (if any),
+ or should we revert to "no current frame"?
+ */
+ return "F-1";
+ }
+ else
+ {
+ sprintp (retbuf, "E2%x", ret);
+ return (char *) dtc_error_ret ((int) &retbuf,
+ "fetch_trace_frame[...]",
+ ret);
+ }
+ }
+ else /* unknown trace command */
+ {
+ return "";
+ }
+}
+
+/* Table used by the crc32 function to calcuate the checksum. */
+static unsigned long crc32_table[256];
+
+static int crc_mem_err;
+
+static unsigned long
+crc32 (buf, len, crc)
+ unsigned char *buf;
+ int len;
+ unsigned long crc;
+{
+ crc_mem_err = FALSE;
+
+ if (! crc32_table[1])
+ {
+ /* Initialize the CRC table and the decoding table. */
+ int i, j;
+ unsigned int c;
+
+ for (i = 0; i < 256; i++)
+ {
+ for (c = i << 24, j = 8; j > 0; --j)
+ c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
+ crc32_table[i] = c;
+ }
+ }
+
+ while (len--)
+ {
+ if (read_access_violation (buf))
+ {
+ crc_mem_err = TRUE;
+ return -1;
+ }
+ crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf++) & 255];
+ }
+ return crc;
+}
+
+static char *
+crc_query (cmd)
+ char *cmd;
+{
+ unsigned long startmem, len, crc;
+ static char buf[32];
+
+ if (hexToInt (&cmd, &startmem) &&
+ *cmd++ == ',' &&
+ hexToInt (&cmd, &len))
+ {
+ crc = crc32 ((unsigned char *) startmem, len, 0xffffffff);
+ if (!crc_mem_err)
+ {
+ sprintp (buf, "C%08x", crc);
+ return buf;
+ }
+ /* else error, fall thru */
+ }
+ sprintp (buf, "E01");
+ return buf;
+}
+
+
+static char *
+handle_test (request)
+ char *request;
+{
+ ULONG args[7];
+ int i;
+
+ /* Parse the arguments, a comma-separated list of hex numbers, into
+ ARGS. Parse at most six arguments. */
+ i = 1;
+ if (*request != '\0')
+ while (i < 7)
+ {
+ if (! hexToInt (&request, &args[i++]))
+ return "E01";
+ if (*request == '\0')
+ break;
+ if (*request++ != ',')
+ return "E01";
+ }
+
+ /* Fill the rest of the args array with zeros. This is what the
+ INLINES command processor does with omitted arguments. */
+ for (; i < 7; i++)
+ args[i] = 0;
+
+ gdb_c_test (args);
+
+ return "OK";
+}
+
+
+/* GDB_TRAP_1_HANDLER
+
+ By the time this is called, the registers have been saved in "registers",
+ and the interrupt priority has been set to permit serial UART interrupts.
+
+ However, since no gdb request has yet been received, and there is no
+ equivalent of getpacket for us to wait on, we can't sit here waiting
+ for packets and processing them.
+
+ In fact, the ONLY thing for us to do here is sit and wait.
+ As gdb sends packet requests, they will handle themselves at the
+ interrupt level. When gdb decides we can continue, it will reset
+ the global variable "gdb_handling_trap1", and we will return
+ (whereupon registers will be restored etc.) */
+
+void gdb_trap_1_handler( void )
+{
+ gdb_handling_trap1 = TRUE;
+ sss_trace_flag = '\0'; /* shut off "trace bit" (indirectly) */
+ gdb_signo = 5;
+ putpacket( "S05" );
+ while ( gdb_handling_trap1 )
+ ;
+ return;
+}
+
+void gdb_trace_handler( void )
+{
+ sss_trace_flag = '\0'; /* shut off "trace bit" (indirectly) */
+ gdb_handling_trap1 = TRUE;
+ gdb_handling_sstrace = TRUE;
+ gdb_signo = 5;
+ putpacket( "S05" );
+ while ( gdb_handling_trap1 )
+ ;
+ return;
+}
diff --git a/gdb/testsuite/gdb.trace/infotrace.exp b/gdb/testsuite/gdb.trace/infotrace.exp
new file mode 100644
index 00000000000..6a117d319ef
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/infotrace.exp
@@ -0,0 +1,99 @@
+# Copyright 1998 Free Software Foundation, Inc.
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+load_lib "trace-support.exp";
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+
+if [istarget "m68k-*-elf"] then {
+ set srcfile gdb_c_test.c
+ set binfile [board_info target d490_binfile];
+} else {
+ set testfile "actions"
+ set srcfile ${testfile}.c
+ set binfile $objdir/$subdir/$testfile
+ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+}
+gdb_reinitialize_dir $srcdir/$subdir
+
+# If testing on a remote host, download the source file.
+# remote_download host $srcdir/$subdir/$srcfile
+
+gdb_file_cmd $binfile
+
+#
+# test "info tracepoints" command
+#
+
+gdb_delete_tracepoints
+set c_test_num [gdb_gettpnum gdb_c_test];
+set asm_test_num [gdb_gettpnum gdb_asm_test];
+if { $c_test_num <= 0 || $asm_test_num <= 0 } then {
+ fail "setting tracepoints"
+ return;
+}
+
+# 2.1 info tracepoints (all)
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$c_test_num\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_c_test.*$asm_test_num\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*" \
+ "2.1: info tracepoints (all)"
+
+# 2.2 info tracepoint (specific)
+gdb_test "info tracepoint $c_test_num" \
+ "$c_test_num\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_c_test.*" \
+ "2.2a: info tracepoint $c_test_num (gdb_c_test)"
+
+gdb_test "info tracepoint $asm_test_num" \
+ "$asm_test_num\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*" \
+ "2.2b: info tracepoint $asm_test_num (gdb_asm_test)"
+
+# 2.3 info tracepoint (invalid tracepoint number)
+gdb_test "info tracepoint [expr $c_test_num + $asm_test_num]" \
+ "No tracepoint number [expr $c_test_num + $asm_test_num]." \
+ "2.3: info tracepoint (invalid tracepoint number)"
+
+# 2.4 info tracepoints (list of numbers)
+send_gdb "info tracepoints $c_test_num $asm_test_num \n"
+gdb_expect {
+ -re "Num Enb .*$gdb_prompt $" {
+ fail "2.4: info trace rejects multiple tracepoint numbers"
+ }
+ -re ".*$gdb_prompt $" {
+ pass "2.4: info trace rejects multiple tracepoint numbers"
+ }
+}
+
+# 2.5 help info trace
+gdb_test "help info tracepoints" \
+ "Status of tracepoints, or tracepoint number NUMBER.*" \
+ "2.5: help info tracepoints"
+
diff --git a/gdb/testsuite/gdb.trace/limits.c b/gdb/testsuite/gdb.trace/limits.c
new file mode 100644
index 00000000000..d9c02e74bac
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/limits.c
@@ -0,0 +1,51 @@
+/*
+ * Test program for tracing internal limits (number of tracepoints etc.)
+ */
+
+int n = 6;
+
+int arr[64];
+
+static void foo(int x)
+{
+}
+
+static void bar(int y)
+{
+}
+
+static void baz(int z)
+{
+}
+
+static void begin () /* called before anything else */
+{
+}
+
+static void end () /* called after everything else */
+{
+}
+
+int
+main (argc, argv, envp)
+ int argc;
+ char *argv[], **envp;
+{
+ int i;
+
+#ifdef usestubs
+ set_debug_traps ();
+ breakpoint ();
+#endif
+
+ begin ();
+ for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
+ arr[i] = i + 1;
+
+ foo (1);
+ bar (2);
+ baz (3);
+ end ();
+ return 0;
+}
+
diff --git a/gdb/testsuite/gdb.trace/limits.exp b/gdb/testsuite/gdb.trace/limits.exp
new file mode 100644
index 00000000000..eed178084bb
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/limits.exp
@@ -0,0 +1,316 @@
+# Copyright 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if [istarget "m68k-*-elf"] then {
+ pass "Test not supported on this target"
+ return;
+}
+
+load_lib "trace-support.exp"
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "limits"
+set srcfile ${testfile}.c
+set binfile $objdir/$subdir/$testfile
+
+if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Tests:
+# 1) Meet and exceed artificial limit on number of tracepoints
+# 2) Meet and exceed artificial limit on number of memranges
+# 3) Meet and exceed artificial limit on bytes of bytecode data
+# [NOTE: number four is moved out into its own separate test module.]
+# 4) Meet and exceed artificial limit on bytes of trace buffer storage
+# (circular and non-circular modes). However note that a more
+# thorough test of the circular mode can be made separately.
+
+set cr "\[\r\n\]+"
+
+proc gdb_tracepoint_limit_test { } {
+ global gdb_prompt
+ global cr
+
+ # Make sure we're in a sane starting state.
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ gdb_delete_tracepoints
+
+ # Set three tracepoints
+ gdb_test "trace foo" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "tracepoint limit test: set first tracepoint"
+
+ gdb_test "trace bar" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "tracepoint limit test: set second tracepoint"
+
+ gdb_test "trace baz" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "tracepoint limit test: set third tracepoint"
+
+ # Set secret artificial tracepoint limit to four
+ gdb_test "maint packet QTLimit:tp:4" \
+ "received: .OK." \
+ "tracepoint limit test: set limit to four"
+
+ # Now sending three tracepoints should succeed.
+ send_gdb "tstart\n"
+ gdb_expect {
+ -re "$cr$gdb_prompt" {
+ pass "tracepoint limit test: send fewer than limit"
+ }
+ default {
+ fail "tracepoint limit test: send fewer than limit"
+ }
+ }
+
+ # Set secret artificial tracepoint limit to three
+ gdb_test "maint packet QTLimit:tp:3" \
+ "received: .OK." \
+ "tracepoint limit test: set limit to three"
+
+ # Now sending three tracepoints should still succeed.
+ send_gdb "tstart\n"
+ gdb_expect {
+ -re "$cr$gdb_prompt" {
+ pass "tracepoint limit test: send equal to limit"
+ }
+ default {
+ fail "tracepoint limit test: send equal to limit"
+ }
+ }
+
+ # Set secret artificial tracepoint limit to two
+ gdb_test "maint packet QTLimit:tp:2" \
+ "received: .OK." \
+ "tracepoint limit test: set limit to two"
+
+ # Now sending three tracepoints should fail.
+ gdb_test "tstart" \
+ ".*\[Ee\]rror.*" \
+ "tracepoint limit test: send more than limit"
+
+ # Clean up:
+ gdb_test "tstop" "" ""
+ gdb_test "maint packet QTLimit:tp:FFFFFFFF" "" ""
+}
+
+proc gdb_memrange_limit_test { } {
+ global gdb_prompt
+ global cr
+
+ # Make sure we're in a sane starting state.
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ gdb_delete_tracepoints
+
+ # Set three tracepoints, and make 'em collect memranges
+ gdb_test "trace foo" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "memrange limit test: set first tracepoint"
+
+ gdb_trace_setactions "memrange limit test: set first actions" \
+ "" \
+ "collect \$arg" "^$"
+
+ gdb_test "trace bar" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "memrange limit test: set second tracepoint"
+
+ gdb_trace_setactions "memrange limit test: set second actions" \
+ "" \
+ "collect \$arg" "^$"
+
+ gdb_test "trace baz" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "memrange limit test: set third tracepoint"
+
+ gdb_trace_setactions "memrange limit test: set third actions" \
+ "" \
+ "collect \$arg" "^$"
+
+ # Set secret artificial memrange limit to four
+ gdb_test "maint packet QTLimit:memrange:4" \
+ "received: .OK." \
+ "memrange limit test: set limit to four"
+
+ # Now sending three memranges should still succeed.
+ send_gdb "tstart\n"
+ gdb_expect {
+ -re "$cr$gdb_prompt" {
+ pass "memrange limit test: send fewer than limit"
+ }
+ default {
+ fail "memrange limit test: send fewer than limit"
+ }
+ }
+
+ # Set secret artificial memrange limit to three
+ gdb_test "maint packet QTLimit:memrange:3" \
+ "received: .OK." \
+ "memrange limit test: set limit to three"
+
+ # Now sending three memranges should still succeed.
+ send_gdb "tstart\n"
+ gdb_expect {
+ -re "$cr$gdb_prompt" {
+ pass "memrange limit test: send equal to limit"
+ }
+ default {
+ fail "memrange limit test: send equal to limit"
+ }
+ }
+
+ # Set secret artificial memrange limit to two
+ gdb_test "maint packet QTLimit:memrange:2" \
+ "received: .OK." \
+ "memrange limit test: set limit to two"
+
+ # Now sending three memranges should fail.
+ gdb_test "tstart" \
+ ".*\[Ee\]rror.*" \
+ "memrange limit test: send more than limit"
+
+ # Clean up:
+ gdb_test "tstop" "" ""
+ gdb_test "maint packet QTLimit:memrange:FFFFFFFF" "" ""
+}
+
+
+proc gdb_bytecode_limit_test { } {
+ global gdb_prompt
+ global cr
+
+ # Make sure we're in a sane starting state.
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ gdb_delete_tracepoints
+
+ # Set three tracepoints
+ gdb_test "trace foo" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "bytecode limit test: set first tracepoint"
+
+ gdb_trace_setactions "bytecode limit test: set first actions" \
+ "" \
+ "collect x + n" "^$"
+
+ gdb_test "trace bar" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "bytecode limit test: set second tracepoint"
+
+ gdb_trace_setactions "bytecode limit test: set second actions" \
+ "" \
+ "collect y + n" "^$"
+
+ gdb_test "trace baz" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "bytecode limit test: set third tracepoint"
+
+ gdb_trace_setactions "bytecode limit test: set third actions" \
+ "" \
+ "collect z + n" "^$"
+
+ # Set secret artificial bytecode limit to a large number
+ gdb_test "maint packet QTLimit:bytecode:400" \
+ "received: .OK." \
+ "bytecode limit test: set limit to large"
+
+ # Now sending three bytecodes should still succeed.
+ send_gdb "tstart\n"
+ gdb_expect {
+ -re "$cr$gdb_prompt" {
+ pass "bytecode limit test: send fewer than limit"
+ }
+ default {
+ fail "bytecode limit test: send fewer than limit"
+ }
+ }
+
+ # Set secret artificial bytecode limit to a small number
+ gdb_test "maint packet QTLimit:bytecode:40" \
+ "received: .OK." \
+ "bytecode limit test: set limit to small"
+
+ # Now sending three bytecodes should fail.
+ gdb_test "tstart" \
+ ".*\[Ee\]rror.*" \
+ "bytecode limit test: send more than limit"
+
+
+ # Clean up:
+ gdb_test "tstop" "" ""
+ gdb_test "maint packet QTLimit:bytecode:FFFFFFFF" "" ""
+}
+
+proc gdb_trace_limits_tests { } {
+ global gdb_prompt
+
+ # We generously give ourselves one "pass" if we successfully
+ # detect that this test cannot be run on this target!
+
+ if { ![gdb_target_supports_trace] } then {
+ pass "Current target does not supporst trace"
+ return 1;
+ }
+
+ if [gdb_test "maint packet QTLimit:tp:ffffffff" \
+ "received: .OK." ""] then {
+ pass "This test cannot be run on this target"
+ return 1;
+ }
+
+ if [gdb_test "maint packet QTLimit:memrange:ffffffff" \
+ "received: .OK." ""] then {
+ pass "This test cannot be run on this target"
+ return 1;
+ }
+
+ if [gdb_test "maint packet QTLimit:bytecode:ffffffff" \
+ "received: .OK." ""] then {
+ pass "This test cannot be run on this target"
+ return;
+ }
+
+ gdb_tracepoint_limit_test
+ gdb_memrange_limit_test
+ gdb_bytecode_limit_test
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+# Body of test encased in a proc so we can return prematurely.
+gdb_trace_limits_tests
diff --git a/gdb/testsuite/gdb.trace/packetlen.exp b/gdb/testsuite/gdb.trace/packetlen.exp
new file mode 100644
index 00000000000..458f732477e
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/packetlen.exp
@@ -0,0 +1,100 @@
+# Copyright 1998 Free Software Foundation, Inc.
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+load_lib "trace-support.exp"
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+
+if [istarget "m68k-*-elf"] then {
+ load_lib "emc-support.exp"
+ set srcfile gdb_c_test.c
+ set binfile [board_info target d490_binfile];
+ gdb_test "set remotetimeout 6" "" ""
+ set timeout 500
+ gdb_target_monitor "$binfile"
+ # Give a TSTOP and ignore errors, to make sure any previous trace is off
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ send_gdb "compare-sections CS\n"
+ gdb_expect {
+ -re "MIS-MATCHED.*$gdb_prompt $" {
+ gdb_suppress_entire_file "Symbol file does not match target!
+ all tests in this module will fail.";
+ }
+ -re ".*$gdb_prompt $" { }
+ }
+} else {
+ set testfile "actions"
+ set srcfile ${testfile}.c
+ set binfile $objdir/$subdir/$testfile
+ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ gdb_load $binfile
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ runto_main
+}
+gdb_reinitialize_dir $srcdir/$subdir
+
+# If testing on a remote host, download the source file.
+# remote_download host $srcdir/$subdir/$srcfile
+
+#
+# Test collecting a whole bunch of stuff at a single tracepoint.
+# The test is whether this crashes GDB.
+#
+
+gdb_delete_tracepoints
+gdb_test "trace gdb_c_test" "" ""
+gdb_trace_setactions "setup collect actions" \
+ "" \
+ "collect parm\[0\], parm\[1\], parm\[2\], parm\[3\]" "^$" \
+ "collect parm\[4\], parm\[5\], parm\[6\], parm\[7\]" "^$" \
+ "collect p, local_reg, local_static, local_static_sizeof" "^$" \
+ "collect local_long, stack_ptr, end_of_stack" "^$" \
+ "collect gdb_char_test, gdb_short_test, gdb_long_test" "^$" \
+ "collect gdb_arr_test, gdb_struct1_test, gdb_struct2_test" "^$" \
+ "collect gdb_structp_test, gdb_structpp_test, gdb_union1_test" "^$" \
+ "end" ""
+
+gdb_test "tstart" "" "survive the long packet send"
+if [istarget "m68k-*-elf"] then {
+ gdb_emclaptop_command "85,1,2,3,4,5,6"
+ sleep 5
+} else {
+ gdb_test "break end" "" ""
+ gdb_test "continue" \
+ "Continuing.*Breakpoint $decimal, end.*" \
+ "run trace experiment"
+}
+
+gdb_test "tstop" "" "confirm: survived the long packet send"
+
diff --git a/gdb/testsuite/gdb.trace/passc-dyn.exp b/gdb/testsuite/gdb.trace/passc-dyn.exp
new file mode 100644
index 00000000000..d0c27ea4386
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/passc-dyn.exp
@@ -0,0 +1,181 @@
+# Copyright 1998 Free Software Foundation, Inc.
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+load_lib "trace-support.exp";
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+if [istarget "m68k-*-elf"] then {
+ load_lib "emc-support.exp";
+ set srcfile gdb_c_test.c
+ set binfile [board_info target d490_binfile];
+ gdb_test "set remotetimeout 6" "" ""
+ set timeout 500
+ gdb_target_monitor $binfile
+ # Give a TSTOP and ignore errors, to make sure any previous trace is off
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ send_gdb "compare-sections CS\n"
+ gdb_expect {
+ -re "MIS-MATCHED.*$gdb_prompt $" {
+ gdb_suppress_entire_file "Symbol file does not match target!
+ all tests in this module will fail.";
+ }
+ -re ".*$gdb_prompt $" { }
+ }
+} else {
+ set testfile "actions"
+ set srcfile ${testfile}.c
+ set binfile $objdir/$subdir/$testfile
+ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ gdb_load $binfile
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ runto_main
+}
+gdb_reinitialize_dir $srcdir/$subdir
+
+# We generously give ourselves one "pass" if we successfully
+# detect that this test cannot be run on this target!
+if { ![gdb_target_supports_trace] } then {
+ pass "Current target does not supporst trace"
+ return 1;
+
+}
+
+# If testing on a remote host, download the source file.
+# remote_download host $srcdir/$subdir/$srcfile
+
+
+#
+# test passcount dynamically (live target)
+#
+
+set baseline [gdb_find_recursion_test_baseline $srcfile];
+
+if { $baseline == -1 } then {
+ fail "Could not find gdb_recursion_test function"
+ return;
+}
+
+# define relative source line numbers:
+# all subsequent line numbers are relative to this first one (baseline)
+
+set testline2 [expr $baseline + 4]
+set testline3 [expr $baseline + 5]
+set testline4 [expr $baseline + 6]
+
+#
+# test passcount command semantics (live test)
+#
+
+## Set three tracepoints with three different passcounts.
+## Verify that the experiment stops after the one with the
+## lowest passcount is hit.
+
+gdb_delete_tracepoints
+set tdp2 [gdb_gettpnum "$testline2"]
+set tdp3 [gdb_gettpnum "$testline3"]
+set tdp4 [gdb_gettpnum "$testline4"]
+if { $tdp2 <= 0 || $tdp3 <= 0 || $tdp4 <= 0 } then {
+ fail "setting tracepoints"
+ return;
+}
+
+gdb_test "passcount 4 $tdp2" "Setting tracepoint $tdp2's passcount to 4" \
+ "4.5: set passcount for tracepoint $tdp2"
+gdb_test "passcount 2 $tdp3" "Setting tracepoint $tdp3's passcount to 2" \
+ "4.5: set passcount for tracepoint $tdp3"
+gdb_test "passcount 3 $tdp4" "Setting tracepoint $tdp4's passcount to 3" \
+ "4.5: set passcount for tracepoint $tdp4"
+
+gdb_test "tstart" "" ""
+
+if [istarget "m68k-*-elf"] then {
+ gdb_emclaptop_command "85,1,2,3,4,5,6"
+ sleep 5
+ gdb_emclaptop_command "85,7,8,9,A,B,C"
+ sleep 5
+ gdb_emclaptop_command "85,D,E,F,10,11,12"
+ sleep 5
+ # gdb_test "tstop"
+ ##
+ ## Note! Must NOT give the tstop command, because the passcount
+ ## has already stopped the experiment. You would not
+ ## think this would be an error, but in EMC's mind it is...
+ ##
+} else {
+ gdb_test "break end" "" ""
+ gdb_test "continue" \
+ "Continuing.*Breakpoint $decimal, end.*" \
+ "run trace experiment"
+ gdb_test "tstop" "" ""
+}
+
+gdb_test "tfind none" "" ""
+if [gdb_test "printf \"x \%d x\\n\", \$trace_frame" "x -1 x" ""] {
+ gdb_suppress_entire_file "0: tfind none failed"
+}
+
+gdb_test "tfind tracepoint $tdp2" "" ""
+if [gdb_test "printf \"x \%d x\\n\", \$trace_frame" "x 0 x" ""] {
+ gdb_suppress_entire_file "1: first tfind failed"
+}
+
+gdb_test "tfind tracepoint $tdp3" "" ""
+if [gdb_test "printf \"x \%d x\\n\", \$trace_frame" "x 1 x" ""] {
+ gdb_suppress_entire_file "2: second tfind failed"
+}
+
+gdb_test "tfind tracepoint $tdp4" "" ""
+if [gdb_test "printf \"x \%d x\\n\", \$trace_frame" "x 2 x" ""] {
+ gdb_suppress_entire_file "3: third tfind failed"
+}
+
+gdb_test "tfind tracepoint $tdp2" "" ""
+if [gdb_test "printf \"x \%d x\\n\", \$trace_frame" "x 3 x" ""] {
+ gdb_suppress_entire_file "4: fourth tfind failed"
+}
+
+gdb_test "tfind tracepoint $tdp3" "" ""
+if [gdb_test "printf \"x \%d x\\n\", \$trace_frame" "x 4 x" ""] {
+ gdb_suppress_entire_file "5: fifth tfind failed"
+}
+
+## We should now be at the last frame, because this frame's passcount
+## should have caused collection to stop. If we do a tfind now,
+## it should fail.
+
+gdb_test "tfind" "failed to find.*" "4.5: dynamic passcount test"
+
+# Finished!
+gdb_test "tfind none" "" ""
+
diff --git a/gdb/testsuite/gdb.trace/passcount.exp b/gdb/testsuite/gdb.trace/passcount.exp
new file mode 100644
index 00000000000..1777693ff55
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/passcount.exp
@@ -0,0 +1,178 @@
+# Copyright 1998 Free Software Foundation, Inc.
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+load_lib "trace-support.exp";
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+if [istarget "m68k-*-elf"] then {
+ set srcfile gdb_c_test.c
+ set binfile [board_info target d490_binfile];
+} else {
+ set testfile "actions"
+ set srcfile ${testfile}.c
+ set binfile $objdir/$subdir/$testfile
+ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+}
+gdb_reinitialize_dir $srcdir/$subdir
+
+# If testing on a remote host, download the source file.
+# remote_download host $srcdir/$subdir/$srcfile
+
+gdb_file_cmd $binfile
+
+# define relative source line numbers:
+# all subsequent line numbers are relative to this first one (baseline)
+set baseline [gdb_find_recursion_test_baseline $srcfile];
+if { $baseline == -1 } then {
+ fail "Could not find gdb_recursion_test function"
+ return;
+}
+
+set testline1 [expr $baseline + 3]
+
+#
+# test "passcount" command
+#
+
+gdb_delete_tracepoints
+set trcpt1 [gdb_gettpnum gdb_c_test];
+set trcpt2 [gdb_gettpnum gdb_asm_test];
+set trcpt3 [gdb_gettpnum $testline1];
+if { $trcpt1 <= 0 || $trcpt2 <= 0 || $trcpt3 <= 0 } then {
+ fail "setting tracepoints"
+ return;
+}
+
+# 4.1 passcount of specified tracepoint
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_recursion_test.*" \
+ "4.1a: set three tracepoints, passcounts all zero"
+
+gdb_test "passcount 2 $trcpt1" \
+ "Setting tracepoint $trcpt1.s passcount to 2" \
+ "4.1b: set 1st tracepoint's passcount to two"
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_recursion_test.*" \
+ "4.1c: verify 1st tracepoint's passcount set to two"
+
+gdb_test "passcount 4 $trcpt2" \
+ "Setting tracepoint $trcpt2.s passcount to 4" \
+ "4.1d: set 2nd tracepoint's passcount to four"
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_recursion_test.*" \
+ "4.1c: verify 2nd tracepoint's passcount set to four"
+
+# 4.2 passcount of last (default) tracepoint
+
+gdb_test "passcount 6" \
+ "Setting tracepoint $trcpt3.s passcount to 6" \
+ "4.2b: set last (default) tp's passcount to six"
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+6\[\t \]+.*in gdb_recursion_test.*" \
+ "4.2b: verify last (default) tp's passcount set to six"
+
+# 4.3 run until stopped explicitly by user
+# [deferred to dynamic test section]
+
+# 4.4 reset the previously set passcounts to new values
+
+gdb_test "passcount 7" \
+ "Setting tracepoint $trcpt3.s passcount to 7" \
+ "4.4a: reset last (default) tp's passcount to seven"
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+7\[\t \]+.*in gdb_recursion_test.*" \
+ "4.4a: verify reset last (default) tp's passcount to seven"
+
+gdb_test "passcount 5 $trcpt2" \
+ "Setting tracepoint $trcpt2.s passcount to 5" \
+ "4.4b: reset second tracepoint's passcount to five"
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+5\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+7\[\t \]+.*in gdb_recursion_test.*" \
+ "4.4c: verify reset second tracepoint's passcount to five"
+
+# 4.20 <FIXME test number> passcount for "all"
+
+gdb_test "passcount 3 all" \
+ ".*$trcpt1.s pass.* 3.*$trcpt2.s pass.* 3.*$trcpt3.s pass.* 3" \
+ "4.20a: set all three passcounts to three"
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+3\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+3\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+3\[\t \]+.*in gdb_recursion_test.*" \
+ "4.20a: set all three passcounts to three"
+
+gdb_test "passcount 4 all" \
+ ".*$trcpt1.s pass.* 4.*$trcpt2.s pass.* 4.*$trcpt3.s pass.* 4" \
+ "4.20a: reset all three passcounts to four"
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*in gdb_recursion_test.*" \
+ "4.20b: reset all three passcounts to four"
+
+# 4.5 Verify trace stops on first "satisfied" passcount
+# [deferred to dynamic test section]
+
+# 4.6 minimum passcount boundary condition
+
+gdb_test "passcount 0 $trcpt1" \
+ "Setting tracepoint $trcpt1.s passcount to 0" \
+ "4.6: set passcount to zero"
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*in gdb_recursion_test.*" \
+ "4.6: set passcount to zero"
+
+# 4.7 (test a very large passcount)
+
+gdb_test "passcount 32767 $trcpt1" \
+ "Setting tracepoint $trcpt1.s passcount to 32767" \
+ "4.7: set passcount to large number (32767)"
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+32767\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*in gdb_recursion_test.*" \
+ "4.7: set passcount to large number (32767)"
+
+# 4.8 set passcount for invalid tracepoint
+
+gdb_test "passcount 1 [expr $trcpt2 + $trcpt3]" \
+ "No tracepoint number [expr $trcpt2 + $trcpt3]." \
+ "4.8: invalid tracepoint number in passcount"
+
+# 4.9 help passcount
+gdb_test "help passcount" "Set the passcount for a tracepoint.*" \
+ "4.9: help passcount"
+
diff --git a/gdb/testsuite/gdb.trace/report.exp b/gdb/testsuite/gdb.trace/report.exp
new file mode 100644
index 00000000000..28449fa0ab6
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/report.exp
@@ -0,0 +1,421 @@
+# Copyright 1998 Free Software Foundation, Inc.
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+load_lib "trace-support.exp";
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+
+if [istarget "m68k-*-elf"] then {
+ load_lib "emc-support.exp";
+ set srcfile gdb_c_test.c
+ set binfile [board_info target d490_binfile];
+ gdb_test "set remotetimeout 6" "" ""
+ set timeout 500
+ gdb_target_monitor $binfile
+ # Give a TSTOP and ignore errors, to make sure any previous trace is off
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ send_gdb "compare-sections CS\n"
+ gdb_expect {
+ -re "MIS-MATCHED.*$gdb_prompt $" {
+ gdb_suppress_entire_file "Symbol file does not match target!
+ all tests in this module will fail.";
+ }
+ -re ".*$gdb_prompt $" { }
+ }
+} else {
+ set testfile "actions"
+ set srcfile ${testfile}.c
+ set binfile $objdir/$subdir/$testfile
+ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ gdb_load $binfile
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ runto_main
+}
+gdb_reinitialize_dir $srcdir/$subdir
+
+# We generously give ourselves one "pass" if we successfully
+# detect that this test cannot be run on this target!
+if { ![gdb_target_supports_trace] } then {
+ pass "Current target does not supporst trace"
+ return 1;
+
+}
+
+set cr "\[\r\n\]+"
+
+# If testing on a remote host, download the source file.
+# remote_download host $srcdir/$subdir/$srcfile
+
+#
+# test general reporting of trace experiment results
+#
+
+set testline1 0
+set testline2 0
+set testline3 0
+set testline4 0
+set testline5 0
+set testline6 0
+
+set arg1 1
+set arg2 2
+set arg3 3
+set arg4 4
+set arg5 5
+set arg6 6
+
+set gdb_recursion_test_baseline [gdb_find_recursion_test_baseline $srcfile];
+if { $gdb_recursion_test_baseline == -1 } {
+ fail "Could not find gdb_recursion_test function"
+ return;
+}
+
+send_gdb "list $gdb_recursion_test_baseline, +12\n"
+gdb_expect {
+ -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 1 " {
+ set testline1 $expect_out(1,string)
+ exp_continue
+ }
+ -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 2 " {
+ set testline2 $expect_out(1,string)
+ exp_continue
+ }
+ -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 3 " {
+ set testline3 $expect_out(1,string)
+ exp_continue
+ }
+ -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 4 " {
+ set testline4 $expect_out(1,string)
+ exp_continue
+ }
+ -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 5 " {
+ set testline5 $expect_out(1,string)
+ exp_continue
+ }
+ -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 6 " {
+ set testline6 $expect_out(1,string)
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" {
+ if { ($testline1 == 0) || ($testline2 == 0) || ($testline3 == 0) || ($testline4 == 0) || ($testline5 == 0) || ($testline6 == 0) } {
+ gdb_suppress_entire_file "failed to locate test source lines:
+all tests in this module will fail."
+ }
+ }
+ default {
+ gdb_suppress_entire_file "failed to locate test source lines (def):
+all tests in this module will fail."
+ }
+}
+
+#
+# Setup trace experiment. This will involve:
+# 1) a tracepoint where nothing is collected
+# 2) a tracepoint where only regs are collected
+# 3) a tracepoint where only args are collected
+# 4) a tracepoint where only locals are collected
+# 5) a tracepoint where some amount of stack memory is collected.
+# 6) a tracepoint where some expressions are collected.
+#
+
+gdb_delete_tracepoints
+set tdp1 [gdb_gettpnum $testline1]
+set tdp2 [gdb_gettpnum $testline2]
+set tdp3 [gdb_gettpnum $testline3]
+set tdp4 [gdb_gettpnum $testline4]
+set tdp5 [gdb_gettpnum $testline5]
+set tdp6 [gdb_gettpnum $testline6]
+
+if { $tdp1 <= 0 || $tdp2 <= 0 || $tdp3 <= 0 || \
+ $tdp4 <= 0 || $tdp5 <= 0 || $tdp6 <= 0 } then {
+ fail "setting tracepoints failed"
+ return;
+}
+
+gdb_trace_setactions "9.x: setup TP to collect regs" \
+ "$tdp2" \
+ "collect \$regs" "^$"
+
+
+gdb_trace_setactions "9.x: setup TP to collect args" \
+ "$tdp3" \
+ "collect \$args" "^$"
+
+gdb_trace_setactions "9.x: setup TP to collect locals" \
+ "$tdp4" \
+ "collect \$locs" "^$"
+
+gdb_trace_setactions "9.x: setup TP to collect stack memory" \
+ "$tdp5" \
+ "collect \$fp, \*\(void \*\*\) \$sp @ 64" "^$"
+
+gdb_trace_setactions "9.x: setup TP to collect expressions" \
+ "$tdp6" \
+ "collect gdb_char_test, gdb_short_test, gdb_long_test" "^$"
+
+gdb_test "tstart" "" ""
+
+if [istarget "m68k-*-elf"] then {
+ gdb_emclaptop_command "85,$arg1,$arg2,$arg3,$arg4,$arg5,$arg6"
+ sleep 5
+
+} else {
+ gdb_test "break end" "" ""
+ gdb_test "continue" \
+ "Continuing.*Breakpoint $decimal, end.*" \
+ "run trace experiment"
+}
+
+gdb_test "tstop" "" ""
+
+#
+# 9.1 test the tdump command
+#
+
+set timeout 60
+
+gdb_tfind_test "9.1: init: make sure not debugging any trace frame" "none" "-1"
+
+gdb_tfind_test "9.1: find frame for TP $tdp1" "tracepoint $tdp1" \
+ "\$tracepoint" "$tdp1"
+
+# Nothing was collected at tdp1, so this tdump should be empty.
+gdb_test "tdump" \
+ "Data collected at tracepoint $tdp1, trace frame $decimal:" \
+ "9.1: tdump, nothing collected"
+
+gdb_tfind_test "9.1: find frame for TP $tdp2" "tracepoint $tdp2" \
+ "\$tracepoint" "$tdp2"
+
+# regs were collected at tdp2.
+# How to match for the output of "info registers" on an unknown architecture?
+# For now, assume that every architecture has a register called "pc".
+gdb_test "tdump" \
+ "\[\r\n\]pc .*" \
+ "9.1: tdump, regs collected"
+
+gdb_tfind_test "9.1: find frame for TP $tdp3" "tracepoint $tdp3" \
+ "\$tracepoint" "$tdp3"
+
+# args were collected at tdp3
+gdb_test "tdump" \
+ "depth = 3.*q1 = 2.*q2 = 2.*q3 = 3.*q4 = 4.*q5 = 5.*q6 = 6" \
+ "9.1: tdump, args collected"
+
+gdb_tfind_test "9.1: find frame for TP $tdp4" "tracepoint $tdp4" \
+ "\$tracepoint" "$tdp4"
+
+# locals were collected at tdp4
+gdb_test "tdump" \
+ "q = 1" \
+ "9.1: tdump, locals collected"
+
+gdb_tfind_test "9.1: find frame for TP $tdp5" "tracepoint $tdp5" \
+ "\$tracepoint" "$tdp5"
+
+# stack was collected at tdp5, plus the frame pointer
+gdb_test "tdump" \
+ ".fp = .*sp @ 64 = .*" \
+ "9.1: tdump, memrange collected"
+
+gdb_tfind_test "9.1: find frame for TP $tdp6" "tracepoint $tdp6" \
+ "\$tracepoint" "$tdp6"
+
+# globals were collected at tdp6
+gdb_test "tdump" \
+ "gdb_char_test = 1.*gdb_short_test = 2.*gdb_long_test = 3" \
+ "9.1: tdump, global variables collected"
+
+# 9.2 test tdump with arguments
+# [no go, tdump doesn't have any arguments]
+
+# 9.3 help tdump
+
+gdb_test "help tdump" "Print everything collected at the current.*" \
+ "9.3: help tdump"
+
+set linecount1 0
+set linecount2 0
+set linecount3 0
+set linecount4 0
+set linecount5 0
+set linecount6 0
+
+gdb_tfind_test "11.x, 12.1: find start frame" "start" "0"
+
+#
+# 11.x test built-in trace variables $trace_frame, $trace_line etc.
+#
+
+gdb_test "printf \"x %d x\\n\", \$trace_frame" "x 0 x" \
+ "11.1: test \$trace_frame"
+
+gdb_test "printf \"x %d x\\n\", \$tracepoint" "x $tdp1 x" \
+ "11.2: test \$tracepoint"
+
+gdb_test "printf \"x %d x\\n\", \$trace_line" "x $testline1 x" \
+ "11.3: test \$trace_line"
+
+send_gdb "print \$trace_file\n"
+gdb_expect {
+ -re "\\$\[0-9\]+ = \"$srcfile\"\[\r\n\]+$gdb_prompt $" {
+ pass "11.4: test \$trace_file"
+ }
+ -re "\\$\[0-9\]+ = \"$srcdir/$subdir/$srcfile\"\[\r\n\]+$gdb_prompt $" {
+ pass "11.4: test \$trace_file"
+ }
+ -re "$gdb_prompt $" {
+ fail "11.4: test \$trace_file"
+ }
+ timeout {
+ fail "11.4: test \$trace_file (timeout)"
+ }
+}
+
+#gdb_test "print \$trace_file" "\"$srcdir/$subdir/$srcfile\"" \
+# "11.4: test \$trace_file"
+
+#
+# 12.x test report generation using arbitrary GDB commands, loops etc.
+#
+
+send_gdb "while \$trace_frame != -1\n output \$trace_file\n printf \", line \%d \(tracepoint #\%d\)\\n\", \$trace_line, \$tracepoint\n tfind\n end\n"
+gdb_expect {
+ -re " line $testline1 .tracepoint .$tdp1" {
+ set linecount1 [expr $linecount1 + 1]
+ exp_continue
+ }
+ -re " line $testline2 .tracepoint .$tdp2" {
+ set linecount2 [expr $linecount2 + 1]
+ exp_continue
+ }
+ -re " line $testline3 .tracepoint .$tdp3" {
+ set linecount3 [expr $linecount3 + 1]
+ exp_continue
+ }
+ -re " line $testline4 .tracepoint .$tdp4" {
+ set linecount4 [expr $linecount4 + 1]
+ exp_continue
+ }
+ -re " line $testline5 .tracepoint .$tdp5" {
+ set linecount5 [expr $linecount5 + 1]
+ exp_continue
+ }
+ -re " line $testline6 .tracepoint .$tdp6" {
+ set linecount6 [expr $linecount6 + 1]
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" {
+ if { ($linecount1 < 4) || ($linecount2 < 4) || ($linecount3 < 4) || ($linecount4 < 4) || ($linecount5 < 4) || ($linecount6 < 4) } {
+ fail "12.1: trace report #1"
+ } else {
+ pass "12.1: trace report #1"
+ }
+ }
+ timeout {
+ fail "12.1: trace report #1 (timeout)"
+ }
+}
+
+gdb_tfind_test "12.2: find first TDP #2 frame" "tracepoint $tdp2" \
+ "\$tracepoint" "$tdp2"
+
+set linecount2 0
+
+send_gdb "while \$trace_frame != -1\n printf \"tracepoint #\%d, FP 0x\%08x, SP 0x\%08x, PC 0x%08x\\n\", \$tracepoint, \$fp, \$sp, \$pc\n tfind tracepoint\n end\n"
+gdb_expect {
+ -re "tracepoint #$tdp2, FP $hex, SP $hex, PC $hex" {
+ set linecount2 [expr $linecount2 + 1]
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" {
+ if { ($linecount2 < 4) } {
+ fail "12.2: trace report #2"
+ } else {
+ pass "12.2: trace report #2"
+ }
+ }
+ timeout {
+ fail "12.2: trace report #2 (timeout)"
+ }
+}
+
+gdb_tfind_test "12.3: find first TDP #3 frame" "tracepoint $tdp3" \
+ "\$tracepoint" "$tdp3"
+
+set linecount3 0
+
+send_gdb "while \$trace_frame != -1\n printf \"TDP #\%d, frame \%d: depth = \%d, q1 = \%d\\n\", \$tracepoint, \$trace_frame, depth, q1\n tfind tracepoint\n end\n"
+gdb_expect {
+ -re "TDP #$tdp3, frame $decimal: depth = $decimal, q1 = $decimal" {
+ set linecount3 [expr $linecount3 + 1]
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" {
+ if { ($linecount3 < 4) } {
+ fail "12.3: trace report #3"
+ } else {
+ pass "12.3: trace report #3"
+ }
+ }
+ timeout {
+ fail "12.3: trace report #3 (timeout)"
+ }
+}
+
+gdb_tfind_test "12.4: find first TDP #6 frame" "tracepoint $tdp6" \
+ "\$tracepoint" "$tdp6"
+
+set linecount6 0
+
+send_gdb "while \$trace_frame != -1\n printf \"TDP #\%d, frame %d: char_test = \%d, long_test = \%d\\n\", \$tracepoint, \$trace_frame, gdb_char_test, gdb_long_test\n tfind tracepoint\n end\n"
+gdb_expect {
+ -re "TDP #$tdp6, frame $decimal: char_test = $arg1, long_test = $arg3" {
+ set linecount6 [expr $linecount6 + 1]
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" {
+ if { ($linecount6 < 4) } {
+ fail "12.4: trace report #4"
+ } else {
+ pass "12.4: trace report #4"
+ }
+ }
+ timeout {
+ fail "12.4: trace report #4 (timeout)"
+ }
+}
+
+# Finished!
+gdb_tfind_test "finished: make sure not debugging any trace frame" "none" "-1"
diff --git a/gdb/testsuite/gdb.trace/save-trace.exp b/gdb/testsuite/gdb.trace/save-trace.exp
new file mode 100644
index 00000000000..b461ad85940
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/save-trace.exp
@@ -0,0 +1,171 @@
+# Copyright 1998 Free Software Foundation, Inc.
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+load_lib "trace-support.exp";
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+
+if [istarget "m68k-*-elf"] then {
+ set srcfile gdb_c_test.c
+ set binfile [board_info target d490_binfile];
+} else {
+ set testfile "actions"
+ set srcfile ${testfile}.c
+ set binfile $objdir/$subdir/$testfile
+ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+}
+gdb_reinitialize_dir $srcdir/$subdir
+
+# If testing on a remote host, download the source file.
+# remote_download host $srcdir/$subdir/$srcfile
+
+gdb_file_cmd $binfile
+
+# define relative source line numbers:
+# all subsequent line numbers are relative to this first one (baseline)
+set baseline [gdb_find_recursion_test_baseline $srcfile];
+if { $baseline == -1 } then {
+ fail "Could not find gdb_recursion_test function"
+ return;
+}
+
+set testline1 [expr $baseline + 4]
+set testline2 [expr $baseline + 5]
+set testline3 [expr $baseline + 6]
+set testline4 [expr $baseline + 7]
+set testline5 [expr $baseline + 8]
+set testline6 [expr $baseline + 9]
+
+#
+# test save-trace command
+#
+
+# setup a set of tracepoints to save
+
+gdb_delete_tracepoints
+
+foreach x { 1 2 3 4 5 6 } {
+ set testline [expr \$testline$x];
+ set trcpt [gdb_gettpnum $testline];
+ set trcpt$x $trcpt;
+ gdb_test "passcount $x" \
+ "Setting tracepoint $trcpt.* to $x" \
+ "10.x: set passcount for tracepoint $trcpt"
+
+ gdb_trace_setactions "10.x: set actions for tracepoint $x" \
+ "" \
+ "collect q$x" "^$" \
+ "while-stepping $x" "^$" \
+ "collect q$x" "^$" \
+ "end" "^$"
+}
+
+
+proc gdb_verify_tracepoints { testname } {
+ global gdb_prompt;
+
+ set ws "\[\t \]+"
+ set nl "\[\r\n\]+"
+ set ourstate 1;
+ set result "pass";
+ send_gdb "info tracepoints\n";
+ gdb_expect 10 {
+ -re "y\[\t \]+0x\[0-9a-fA-F\]+\[\t \]+(\[0-9\]+)\[\t \]+(\[0-9\]+)\[\t \]+in gdb_recursion_test\[^\r\n\]+" {
+ if { $expect_out(1,string) != $expect_out(2,string) } {
+ #set result "fail";
+ }
+ if { $expect_out(1,string) != $ourstate } {
+ set result "fail";
+ }
+ incr ourstate;
+ exp_continue;
+ }
+ -re "$gdb_prompt $" {
+ if { $ourstate >= 6 } {
+ set result "pass";
+ } else {
+ set result "fail";
+ }
+ }
+ default {
+ set result "fail";
+ }
+ }
+ $result $testname;
+ return $result;
+}
+
+gdb_verify_tracepoints "10.x: verify trace setup";
+
+# 10.1 Save current tracepoint definitions to a file
+
+remote_file host delete savetrace.tr
+gdb_test "save-tracepoints savetrace.tr" \
+ "Tracepoints saved to file 'savetrace.tr'." \
+ "10.1: save tracepoint definitions"
+
+# 10.2 Read back tracepoint definitions
+
+gdb_delete_tracepoints
+gdb_test "info tracepoints" "No tracepoints." "10.2: delete tracepoints"
+gdb_test "source savetrace.tr" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "10.2: read back saved tracepoints"
+gdb_verify_tracepoints "10.2: verify recovered tracepoints";
+remote_file host delete savetrace.tr
+
+# 10.3 repeat with a path to the file
+
+remote_file host delete $objdir/savetrace.tr
+gdb_test "save-tracepoints $objdir/savetrace.tr" \
+ "Tracepoints saved to file '$objdir/savetrace.tr'." \
+ "10.3: save tracepoint definitions, full path"
+
+gdb_delete_tracepoints
+gdb_test "info tracepoints" "No tracepoints." "10.3: delete tracepoints"
+gdb_test "source $objdir/savetrace.tr" \
+ "Tracepoint \[0-9\]+ at .*" \
+ "10.4: read saved tracepoints, full path"
+gdb_verify_tracepoints "10.3: verify recovered tracepoints, full path";
+remote_file host delete $objdir/savetrace.tr
+
+# 10.5 invalid filename
+# [deferred -- not sure what a good invalid filename would be]
+
+# 10.6 save-trace (file already exists)
+# [expect it to clobber the old one]
+
+# 10.7 help save-tracepoints
+
+gdb_test "help save-tracepoints" \
+ "Save current tracepoint definitions as a script.*" \
+ "10.7: help save-tracepoints"
diff --git a/gdb/testsuite/gdb.trace/tfind.exp b/gdb/testsuite/gdb.trace/tfind.exp
new file mode 100644
index 00000000000..f678975f27e
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/tfind.exp
@@ -0,0 +1,405 @@
+# Copyright 1998 Free Software Foundation, Inc.
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+load_lib "trace-support.exp";
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+
+if [istarget "m68k-*-elf"] then {
+ load_lib "emc-support.exp";
+ set srcfile gdb_c_test.c
+ set binfile [board_info target d490_binfile];
+ gdb_test "set remotetimeout 6" "" ""
+ set timeout 500
+ gdb_target_monitor $binfile
+ # Give a TSTOP and ignore errors, to make sure any previous trace is off
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ send_gdb "compare-sections CS\n"
+ gdb_expect {
+ -re "MIS-MATCHED.*$gdb_prompt $" {
+ gdb_suppress_entire_file "Symbol file does not match target!
+ all tests in this module will fail.";
+ }
+ -re ".*$gdb_prompt $" { }
+ }
+} else {
+ set testfile "actions"
+ set srcfile ${testfile}.c
+ set binfile $objdir/$subdir/$testfile
+ if { [gdb_compile "$srcdir/$subdir/$srcfile" "$binfile -O1" \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ gdb_load $binfile
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ runto_main
+}
+gdb_reinitialize_dir $srcdir/$subdir
+
+# We generously give ourselves one "pass" if we successfully
+# detect that this test cannot be run on this target!
+if { ![gdb_target_supports_trace] } then {
+ pass "Current target does not supporst trace"
+ return 1;
+
+}
+
+# If testing on a remote host, download the source file.
+# remote_download host $srcdir/$subdir/$srcfile
+
+# define relative source line numbers:
+# all subsequent line numbers are relative to this first one (baseline)
+set baseline [gdb_find_recursion_test_baseline $srcfile];
+if { $baseline == -1 } then {
+ fail "Could not find gdb_recursion_test function"
+ return;
+}
+
+set testline1 [expr $baseline + 1]
+set testline2 [expr $baseline + 5]
+set testline3 [expr $baseline + 6]
+set testline4 [expr $baseline + 7]
+set testline5 [expr $baseline + 8]
+
+#
+# test tfind command
+#
+
+gdb_delete_tracepoints
+set tdp1 [gdb_gettpnum "\*gdb_recursion_test"]
+set tdp2 [gdb_gettpnum $testline2]
+set tdp3 [gdb_gettpnum $testline3]
+set tdp4 [gdb_gettpnum $testline4]
+set tdp5 [gdb_gettpnum $testline5]
+if { $tdp1 <= 0 || $tdp2 <= 0 || $tdp3 <= 0 || \
+ $tdp4 <= 0 || $tdp5 <= 0 } then {
+ fail "setting tracepoints"
+ return;
+}
+
+# 6.1 test tstart command
+send_gdb "tstart\n"
+gdb_expect {
+ -re "Trace can only be run on remote targets.*$gdb_prompt $" {
+ fail "6.1: tstart (not connected to remote?)"
+ return;
+ }
+ -re "Target does not support this command.*$gdb_prompt $" {
+ fail "6.1: tstart (connected to wrong target?)"
+ return;
+ }
+ -re "Target returns error code.*$gdb_prompt $" {
+ fail "6.1: tstart (connected to wrong target?)"
+ return;
+ }
+ -re "$gdb_prompt $" {
+ pass "6.1: tstart"
+ }
+ default {
+ fail "6.1: tstart (default)"
+ return;
+ }
+}
+
+# test tstatus (when trace on)
+gdb_test "tstatus" "\[Tt\]race is running.*" "test tstatus on"
+
+# 6.2 test help tstart
+gdb_test "help tstart" "Start trace data collection." "6.2: help tstart"
+
+if [istarget "m68k-*-elf"] then {
+ gdb_emclaptop_command "85,1,2,3,4,5,6"
+ sleep 5
+
+ gdb_emclaptop_command "85,7,8,9,A,B,C"
+ sleep 5
+} else {
+ gdb_test "break end" "" ""
+ gdb_test "continue" \
+ "Continuing.*Breakpoint $decimal, end.*" \
+ "run trace experiment"
+}
+
+# 7.1 test tstop command
+send_gdb "tstop\n"
+gdb_expect {
+ -re "Trace can only be run on remote targets.*$gdb_prompt $" {
+ fail "7.1: tstop (not connected to remote?)"
+ return;
+ }
+ -re "Target does not support this command.*$gdb_prompt $" {
+ fail "7.1: tstop (connected to wrong target?)"
+ return;
+ }
+ -re "Target returns error code.*$gdb_prompt $" {
+ fail "7.1: tstop (connected to wrong target?)"
+ return;
+ }
+ -re "$gdb_prompt $" {
+ pass "7.1: tstop"
+ }
+ default {
+ fail "7.1: tstop (default)"
+ return;
+ }
+}
+
+# 7.2 test help tstop
+gdb_test "help tstop" "Stop trace data collection." "7.2: help tstop"
+
+# test tstatus (when trace off)
+gdb_test "tstatus" "\[Tt\]race.* not running.*" "test tstatus off"
+
+## record starting PC
+set save_pc [gdb_readexpr "(unsigned long) \$pc"];
+if { $save_pc == -1 } then {
+ fail "could not read PC"
+ return;
+}
+
+# 8.7 tfind start
+## check $trace_frame == 0
+gdb_tfind_test "8.7: tfind start command" "start" "0";
+## check $pc != startPC
+gdb_test "printf \"x \%d x\\n\", \$pc != $save_pc" \
+ "x 1 x" \
+ "8.7b: tfind start"
+
+# 8.8 tfind none
+## check $trace_frame == -1
+gdb_tfind_test "8.8: tfind none" "none" "-1";
+## check $pc == startPC
+gdb_test "printf \"x \%d x\\n\", \$pc == $save_pc" \
+ "x 1 x" \
+ "8.8b: tfind none (restores non-trace PC)"
+
+# 8.9 tfind end
+## check $trace_frame == -1
+gdb_tfind_test "8.9: tfind end, selects no frame" "end" "-1";
+## check $pc == startPC
+gdb_test "printf \"x \%d x\\n\", \$pc == $save_pc" \
+ "x 1 x" \
+ "8.9b: tfind end (restores non-tracing PC)"
+
+# 8.1 tfind n
+## check $trace_frame == n
+gdb_tfind_test "8.1: tfind 1" "1" "1"
+## check $trace_line corresponds to tracepoint for frame n
+gdb_test "print \$trace_line" "$testline2" "8.1b: tfind 1 (correct line)"
+
+# 8.28 tfind invalid n (big number)
+## check "not found" error
+## check $trace_frame != n
+gdb_test "tfind 32767" \
+ "failed to find.*" \
+ "8.28: tfind <n> command rejects invalid frame number"
+
+gdb_test "printf \"x \%d x\\n\", \$trace_frame == 32767" \
+ "x 0 x" \
+ "8.28: tfind <n> rejected bad input (32767)"
+
+# 8.31 tfind negative n
+## check error
+gdb_test "tfind -3" "invalid input.*" "8.31: tfind <n> rejects negative input"
+## check $trace_frame != -n
+gdb_test "printf \"x \%d x\\n\", \$trace_frame == -3" "x 0 x" \
+ "8.31: tfind <n> rejected negative input (-3)"
+
+# 8.10 tfind <no arg>
+## check $trace_frame += 1
+
+gdb_tfind_test "8.10: tfind start" "start" "0";
+gdb_test "print \$trace_line" "$baseline" \
+ "8.10: tfind 0 (correct line $baseline)"
+gdb_tfind_test "8.10: tfind noargument 1" "" "1";
+gdb_test "print \$trace_line" "$testline2" \
+ "8.10: tfind 1 (correct line $testline2)"
+gdb_tfind_test "8.10: tfind noargument 2" "" "2";
+gdb_test "print \$trace_line" "$testline3" \
+ "8.10: tfind 2 (correct line $testline3)"
+gdb_tfind_test "8.10: tfind noargument 3" "" "3";
+gdb_test "print \$trace_line" "$testline4" \
+ "8.10: tfind 3 (correct line $testline4)"
+
+gdb_tfind_test "8.11: tfind 3" "3" "3";
+gdb_test "print \$trace_line" "$testline4" \
+ "8.11: tfind 3 (correct line $testline4)"
+gdb_tfind_test "8.11: tfind backward 2" "-" "2";
+gdb_test "print \$trace_line" "$testline3" \
+ "8.11: tfind 2 (correct line $testline3)"
+gdb_tfind_test "8.11: tfind backward 1" "-" "1";
+gdb_test "print \$trace_line" "$testline2" \
+ "8.11: tfind 1 (correct line $testline2)"
+gdb_tfind_test "8.11: tfind backward 0" "-" "0";
+gdb_test "print \$trace_line" "$baseline" \
+ "8.11: tfind 0 (correct line $baseline)"
+
+gdb_tfind_test "8.12: tfind none" "none" "-1";
+gdb_tfind_test "8.12: tfind tracepoint <n>" "tracepoint $tdp2" \
+ "\$tracepoint" "$tdp2";
+gdb_test "print \$trace_line" "$testline2" \
+ "8.12: tfind tracepoint <n> (line $testline2)"
+
+gdb_tfind_test "8.25: tfind none" "none" "-1";
+gdb_test "tfind tracepoint 0" "failed to find.*" \
+ "8.25: tfind tracepoint rejects zero"
+gdb_test "tfind tracepoint 32767" "failed to find.*" \
+ "8.25: tfind tracepoint rejects nonexistant tracepoint (32767)"
+gdb_test "tfind tracepoint -1" "failed to find.*" \
+ "8.25: tfind tracepoint rejects nonexistant tracepoint (-1)"
+
+# 8.37 tfind tracepoint n where n no longer exists (but used to)
+gdb_test "delete trace $tdp2" "" ""
+gdb_tfind_test "8.37: tfind none" "none" "-1";
+gdb_tfind_test "8.37: tfind deleted tracepoint" \
+ "tracepoint $tdp2" \
+ "\$tracepoint" "$tdp2";
+gdb_test "print \$trace_line" "$testline2" \
+ "8.37: tfind deleted tracepoint (line $testline2)"
+
+# 8.13 tfind tracepoint <no arg>
+## check $tracepoint same before and after, $trace_frame changed
+
+gdb_tfind_test "8.13: tfind none" "none" "-1";
+gdb_tfind_test "8.13: tracepoint $tdp1" "tracepoint $tdp1" \
+ "\$tracepoint" "$tdp1";
+gdb_test "print \$trace_line" "$baseline" \
+ "8.13: tfind tracepoint $tdp1 (line $baseline)"
+gdb_test "set \$save_frame = \$trace_frame" "" ""
+gdb_tfind_test "8.13: tracepoint <no arg>" "tracepoint" \
+ "\$tracepoint" "$tdp1";
+gdb_test "printf \"x \%d x\\n\", \$trace_frame == \$save_frame" \
+ "x 0 x" \
+ "8.13: tracepoint <no arg>, tracepoint number unchanged"]
+
+# 1.12 set tracepoint in prologue
+#
+# tdp1 was set at *gdb_recursion_test (ie. the hard address of the
+# function, before the prologue). Test to see that it succeeded.
+# Current pc should be equal to the address of the function.
+
+gdb_test "printf \"x \%d x\\n\", \$pc == gdb_recursion_test" \
+ "x 1 x" \
+ "1.12: set tracepoint in prologue"
+
+# 8.14 tfind pc x
+## check pc == x, $trace_frame != -1
+gdb_tfind_test "8.14: tfind 3" "3" "3"
+gdb_test "print \$trace_line" "$testline4" \
+ "8.14: tfind 3 (line $testline4)"
+
+gdb_test "set \$test_pc = \$pc" "" ""
+gdb_tfind_test "8.14: tfind none" "none" "-1"
+gdb_tfind_test "8.14: tfind pc" "pc \$test_pc" "\$trace_frame != -1" "1";
+gdb_test "print \$trace_line" "$testline4" \
+ "8.14: tfind pc x (line $testline4)"
+gdb_test "printf \"x \%d x\\n\", \$pc == \$test_pc" \
+ "x 1 x" \
+ "8.14: tfind pc x"
+
+# 8.15 tfind pc <no arg>
+## check pc same before and after, $trace_frame changed
+gdb_tfind_test "8.15: tfind 3" "3" "3"
+gdb_test "print \$trace_line" "$testline4" \
+ "8.15: tfind 3 (line $testline4)"
+gdb_test "set \$test_pc = \$pc" "" ""
+gdb_tfind_test "8.15: tfind pc" "pc" "\$pc == \$test_pc" "1"
+gdb_test "print \$trace_line" "$testline4" \
+ "8.15: tfind pc (line $testline4)"
+gdb_test "printf \"x \%d x\\n\", \$trace_frame != 3" "x 1 x" \
+ "8.15: trace frame didn't change"
+
+# 8.26 tfind pc invalid x
+## check error, pc != x (trace_frame unchanged?)
+gdb_tfind_test "8.26: tfind start" "start" "0"
+gdb_test "tfind pc 0" "failed to find.*" "8.26: tfind pc zero"
+gdb_test "tfind pc -1" "failed to find.*" "8.26: tfind pc -1"
+
+# 8.16 tfind line n
+## check #trace_frame != -1, $trace_line == n
+gdb_tfind_test "8.16: tfind none" "none" "-1"
+gdb_tfind_test "8.16: tfind line $testline3" \
+ "line $testline3" \
+ "\$trace_line == $testline3" "1"
+
+# 8.17 tfind line <no arg> (# 8.19, 8.20)
+## check $trace_line changed, no error, pc changed, frame changed, tdp changed
+gdb_tfind_test "8.17: tfind none" "none" "-1"
+gdb_tfind_test "8.17: tfind line $testline3" "line $testline3" "\$trace_line == $testline3" "1"
+gdb_tfind_test "8.17: tfind line <no arg>" "line" "\$trace_line != $testline3" "1"
+
+# 8.36 tfind and disassembly
+gdb_tfind_test "8.36: tfind start" "start" "0"
+set timeout 60
+send_gdb "disassemble gdb_c_test\n"
+# look for disassembly of function label
+gdb_expect {
+ -re "<gdb_c_test>:.*$gdb_prompt $" { pass "8.36: trace disassembly" }
+ -re ".*$gdb_prompt $" { fail "8.36: trace disassembly" }
+ timeout { fail "8.36: trace disassembly (timeout)" }
+}
+
+gdb_test "tfind line 0" \
+ "out of range.*|failed to find.*" \
+ "8.18: tfind line 0";
+gdb_test "tfind line 32767" \
+ "out of range.*|failed to find.*" \
+ "8.27: tfind line 32767";
+gdb_test "tfind line NoSuChFiLe.c:$baseline" \
+ "No source file named.*" \
+ "8.27: tfind line in bad source file";
+
+# 8.32 tfind invalid subcommand (tfind foo)
+## check error
+gdb_test "tfind NoSuChOpTiOn 21" \
+ "No symbol.*|\[Ww\]arning.*|\[Ee\]rror.*" \
+ "8.32: tfind with bad subcommand"
+
+# 8.38 test help tfind
+gdb_test "help tfind" "Select a trace frame.*" \
+ "8.38: help tfind"
+gdb_test "help tfind pc" "Select a trace frame by PC.*" \
+ "8.38: help tfind PC"
+gdb_test "help tfind end" "Synonym for 'none'.*" \
+ "8.38: help tfind end"
+gdb_test "help tfind none" "De-select any trace frame.*" \
+ "8.38: help tfind none"
+gdb_test "help tfind line" "Select a trace frame by source line.*" \
+ "8.38: help tfind line"
+gdb_test "help tfind start" "Select the first trace frame.*" \
+ "8.38: help tfind start"
+gdb_test "help tfind range" "Select a trace frame whose PC is in.*" \
+ "8.38: help tfind range"
+gdb_test "help tfind trace" "Select a trace frame by tracepoint number.*" \
+ "8.38: help tfind tracepoint"
+
+# Finished!
+gdb_tfind_test "8.17: tfind none" "none" "-1"
diff --git a/gdb/testsuite/gdb.trace/tracecmd.exp b/gdb/testsuite/gdb.trace/tracecmd.exp
new file mode 100644
index 00000000000..d79c98edbf5
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/tracecmd.exp
@@ -0,0 +1,269 @@
+# Copyright 1998 Free Software Foundation, Inc.
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+load_lib "trace-support.exp";
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+if [istarget "m68k-*-elf"] then {
+ set srcfile gdb_c_test.c
+ set binfile [board_info target d490_binfile];
+} else {
+ set testfile "actions"
+ set srcfile ${testfile}.c
+ set binfile $objdir/$subdir/$testfile
+ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+}
+gdb_reinitialize_dir $srcdir/$subdir
+
+# If testing on a remote host, download the source file.
+# remote_download host $srcdir/$subdir/$srcfile
+
+gdb_file_cmd $binfile
+
+# define relative source line numbers:
+# all subsequent line numbers are relative to this first one (baseline)
+set baseline [gdb_find_recursion_test_baseline $srcfile];
+if { $baseline == -1 } then {
+ fail "Could not find gdb_recursion_test function"
+ return;
+}
+
+set testline1 [expr $baseline + 1]
+set testline2 [expr $baseline + 3]
+
+#
+# test "help tracepoints"
+#
+
+set helpcnt 0;
+send_gdb "help tracepoints\n"
+gdb_expect {
+ -re "Tracing of program execution without stopping the program." {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "actions -- Specify the actions to be taken at a tracepoint" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "collect -- Specify one or more data items to be collected" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "delete tracepoints -- Delete specified tracepoints" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "end -- Ends a list of.*actions" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "info tracepoints -- Status of tracepoints" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "passcount -- Set the passcount for a tracepoint" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "save-tracepoints -- Save current tracepoint definitions" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "tdump -- Print everything collected at the current tracepoint" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "tfind -- Select a trace frame" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "tfind end -- Synonym for 'none'" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "tfind line -- Select a trace frame by line number" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "tfind none -- De-select any trace frame and resume 'live' debugging" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "tfind outside -- Select a trace frame whose PC is outside" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "tfind pc -- Select a trace frame by PC" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "tfind range -- Select a trace frame whose PC is in the given" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "tfind start -- Select the first trace frame in the trace buffer" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "tfind tracepoint -- Select a trace frame by tracepoint number" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "trace -- Set a tracepoint at a specified line or function or addr" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "tstart -- Start trace data collection" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "tstatus -- Display the status of the current trace data collection" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "tstop -- Stop trace data collection" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re "while-stepping -- Specify single-stepping behavior at a tracepoint" {
+ incr helpcnt;
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" {
+ if { $helpcnt == 21 } {
+ pass "1.0: help tracepoints"
+ } else {
+ warning "$helpcnt";
+ fail "1.0: help tracepoints"
+ }
+ }
+}
+
+#
+# test trace command:
+#
+
+# 1.1 trace source line
+gdb_delete_tracepoints
+gdb_test "trace $srcfile:$testline2" \
+ "Tracepoint $decimal at $hex: file.*$srcfile, line $testline2." \
+ "1.1a: set tracepoint at sourceline"
+gdb_test "info trace" "in gdb_recursion_test.*$srcfile:$testline2" \
+ "1.1b: trace sourcefile:line"
+
+# 1.2 trace invalid source line
+gdb_delete_tracepoints
+gdb_test "trace $srcfile:99999" "No line 99999 in file \".*$srcfile\"." \
+ "1.2a: trace invalid line in sourcefile"
+gdb_test "info trace" "No tracepoints.*" \
+ "1.2b: reject invalid line in srcfile"
+
+# 1.3 trace line in invalid source file
+gdb_delete_tracepoints
+gdb_test "trace NoSuChFiLe.c:1" "No source file named NoSuChFiLe.c." \
+ "1.3a: trace invalid source file"
+gdb_test "info trace" "No tracepoints.*" \
+ "1.3b: reject invalid srcfile"
+
+# 1.4 trace function by name
+gdb_delete_tracepoints
+gdb_test "trace gdb_recursion_test" \
+ "Tracepoint $decimal at $hex: file.*$srcfile, line $testline1." \
+ "1.4a: trace function by name"
+gdb_test "info trace" "in gdb_recursion_test.*$srcfile:$testline1" \
+ "1.4b: trace function by name"
+
+# 1.5 trace non-existant function
+gdb_delete_tracepoints
+gdb_test "trace NoSuChFuNc" "Function \"NoSuChFuNc\" not defined." \
+ "1.5a: trace invalid function"
+gdb_test "info trace" "No tracepoints.*" \
+ "1.5b: reject invalid srcfile"
+
+# 1.6 trace at a specific address
+# Collect the address of "gdb_asm_test", and use that.
+send_gdb "print gdb_asm_test\n"
+gdb_expect {
+ -re "\[$\]\[0-9\].*0x(\[0-9a-fA-F\]+).*$gdb_prompt $" {
+ set asm_test_addr $expect_out(1,string)
+ }
+ timeout { }
+}
+
+gdb_delete_tracepoints
+gdb_test "trace \*0x$asm_test_addr" \
+ "Tracepoint $decimal at .*$asm_test_addr.*" \
+ "1.6a: trace at specific address"
+gdb_test "info trace" "$asm_test_addr.*gdb_asm_test.*" \
+ "1.6b: verify trace at specific address"
+
+# 1.7 trace at function's exact address
+# Collect the address of the function for comparison
+send_gdb "print gdb_recursion_test\n"
+gdb_expect {
+ -re "\[$\]\[0-9\].*0x(\[0-9a-fA-F\]+).*$gdb_prompt $" {
+ set c_test_addr $expect_out(1,string)
+ }
+ timeout { }
+}
+
+gdb_delete_tracepoints
+gdb_test "trace \*gdb_recursion_test" \
+ "Tracepoint $decimal at .*$c_test_addr.*" \
+ "1.7a: trace at function label (before prologue)"
+gdb_test "info trace" "$c_test_addr.*in gdb_recursion_test.*:$baseline" \
+ "1.7b: verify trace at specific address"
+
+# 1.8 trace at invalid address
+# no address is invalid
+
+# 1.9 trace no arguments
+gdb_test "trace" "trace command requires an argument" \
+ "1.9: trace <no arguments>"
+
+# 1.10 set large number of tracepoints
+# deferred to limits test module
+
+# 1.11 tracepoint conditions
+# conditions on tracepoints not implemented
+
+# 1.12 set tracepoint in prologue
+# [see tfind.exp]
+
+# 1.13 trace on recursion
+# interesting only in "live" session: see backtrace.exp for live test.
+
+# 1.14 help trace
+gdb_test "help trace" "Set a tracepoint at .*" "1.14: help trace"
+
+
diff --git a/gdb/testsuite/gdb.trace/while-dyn.exp b/gdb/testsuite/gdb.trace/while-dyn.exp
new file mode 100644
index 00000000000..84ab14b9409
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/while-dyn.exp
@@ -0,0 +1,124 @@
+# Copyright 1998 Free Software Foundation, Inc.
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+load_lib "trace-support.exp"
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+
+if [istarget "m68k-*-elf"] then {
+ load_lib "emc-support.exp"
+ set testfile "gdb_c_test"
+ set srcfile $testfile.c
+ set binfile [board_info target d490_binfile];
+ gdb_test "set remotetimeout 6" "" ""
+ set timeout 500
+ gdb_target_monitor "$binfile"
+ # Give a TSTOP and ignore errors, to make sure any previous trace is off
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ send_gdb "compare-section CS\n"
+ gdb_expect {
+ -re "MIS-MATCHED.*$gdb_prompt $" {
+ gdb_suppress_entire_file "Symbol file does not match target!
+ all tests in this module will fail.";
+ }
+ -re ".*$gdb_prompt $" { }
+ }
+} else {
+ set testfile "actions"
+ set srcfile $testfile.c
+ set binfile $objdir/$subdir/$testfile
+ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ gdb_load $binfile
+ gdb_test "tstop" "" ""
+ gdb_test "tfind none" "" ""
+ runto_main
+}
+gdb_reinitialize_dir $srcdir/$subdir
+
+# We generously give ourselves one "pass" if we successfully
+# detect that this test cannot be run on this target!
+if { ![gdb_target_supports_trace] } then {
+ pass "Current target does not supporst trace"
+ return 1;
+
+}
+
+# If testing on a remote host, download the source file.
+# remote_download host $srcdir/$subdir/$srcfile
+
+#
+# test while-stepping dynamically (live target)
+#
+
+## verify number of trace frames collected matches stepcount
+
+gdb_delete_tracepoints
+gdb_test "trace gdb_c_test" \
+ "Tracepoint $decimal at .*" \
+ "Set tracepoint at gdb_c_test"
+
+gdb_trace_setactions "5.12: define while-stepping <stepcount>" \
+ "" \
+ "collect \$fp" "^$" \
+ "while-stepping 5" "^$" \
+ "collect p" "^$" \
+ "end" "^$" \
+ "end" ""
+
+gdb_test "tstart" "" ""
+
+if [istarget "m68k-*-elf"] then {
+ gdb_emclaptop_command "85,1,2,3,4,5,6"
+ sleep 5
+} else {
+ gdb_test "break end" "" ""
+ gdb_test "continue" \
+ "Continuing.*Breakpoint $decimal, end.*" \
+ "run trace experiment"
+}
+
+gdb_test "tstop" "" ""
+
+gdb_tfind_test "5.12: frame 5 should be the last one collected" "5" "5"
+
+send_gdb "tfind 6\n"
+gdb_expect {
+ -re "failed to find.*$gdb_prompt $" {
+ pass "5.12: trace stopped after 5 stepping frames"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "5.12: trace stopped after 5 stepping frames"
+ }
+}
+
+gdb_test "tfind none" "" ""
diff --git a/gdb/testsuite/gdb.trace/while-stepping.exp b/gdb/testsuite/gdb.trace/while-stepping.exp
new file mode 100644
index 00000000000..4c87d5cf214
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/while-stepping.exp
@@ -0,0 +1,116 @@
+# Copyright 1998 Free Software Foundation, Inc.
+#
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Michael Snyder (msnyder@cygnus.com)
+
+load_lib "trace-support.exp";
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+gdb_exit
+gdb_start
+
+if [istarget "m68k-*-elf"] then {
+ set srcfile gdb_c_test.c
+ set binfile [board_info target d490_binfile];
+} else {
+ set testfile "actions"
+ set srcfile ${testfile}.c
+ set binfile ${objdir}/${subdir}/${testfile}
+ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" $binfile \
+ executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+}
+gdb_reinitialize_dir $srcdir/$subdir
+
+# If testing on a remote host, download the source file.
+# remote_download host $srcdir/$subdir/$srcfile
+
+gdb_file_cmd $binfile
+
+#
+# test while-stepping command
+#
+
+gdb_delete_tracepoints
+set trcpt1 [gdb_gettpnum gdb_c_test]
+if { $trcpt1 <= 0 } then {
+ fail "Could not find gdb_c_test function"
+ return;
+}
+
+# 5.12 basic while-stepping command (collect regs)
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$trcpt1.*0x.*\[\t \]+\[0-9\]+\[\t \]+0\[\t \]+.*in gdb_c_test.*" \
+ "5.12: set a tracepoint, stepcount is zero"
+
+set stepcount 12
+
+gdb_trace_setactions "5.12: set stepcount to $stepcount" \
+ "" \
+ "while-stepping $stepcount" "" \
+ "collect \$regs" "^$" \
+ "end" ""
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*$trcpt1.*0x.*\[\t \]+\[0-9\]+\[\t \]+$stepcount\[\t \]+.*in gdb_c_test.*" \
+ "5.12: confirm stepcount set to $stepcount"
+
+gdb_test "info tracepoints" \
+ "Num Enb Address\[ \]+PassC StepC What.*
+.*while-stepping $stepcount.*" \
+ "5.12: info trace shows \"while-stepping\""
+
+
+# 5.13 step out of context while collecting local variable
+# [deferred to dynamic test section]
+
+proc while_stepping_bogus_arg { bogus msgstring } {
+ global gdb_prompt;
+
+ gdb_trace_setactions "$msgstring" \
+ "" \
+ "while-stepping $bogus" "\[Ee\]rror|\[Ww\]arning"
+}
+
+# 5.14 while-stepping (no argument)
+
+while_stepping_bogus_arg "" "5.14: while-stepping null stepcount"
+
+# 5.15 while-stepping (zero stepcount)
+
+while_stepping_bogus_arg "0" "5.15: while-stepping rejects zero stepcount"
+
+# 5.16 while-stepping without collecting anything
+gdb_trace_setactions "5.16: step without collecting anything" \
+ "" \
+ "while-stepping $stepcount" "^$" \
+ "end" ""
+
+gdb_test "info tracepoints" \
+ ".*$trcpt1.*0x.*\[\t \]+\[0-9\]+\[\t \]+$stepcount\[\t \]+.*in gdb_c_test.*\[ \t\]+Actions for tracepoint $trcpt1:.*\[ \t\]+while-stepping $stepcount.*\[ \t\]+end.*\[ \t\]+end.*" \
+ "5.16: confirm actions, step without collecting anything"
+
diff --git a/gdb/testsuite/lib/compiler.c b/gdb/testsuite/lib/compiler.c
new file mode 100644
index 00000000000..8eb0d47dd19
--- /dev/null
+++ b/gdb/testsuite/lib/compiler.c
@@ -0,0 +1,31 @@
+/* Often the behavior of any particular test depends upon what compiler was
+ used to compile the test. As each test is compiled, this file is
+ preprocessed by the same compiler used to compile that specific test
+ (different tests might be compiled by different compilers, particularly
+ if compiled at different times), and used to generate a *.ci (compiler
+ info) file for that test.
+
+ I.E., when callfuncs is compiled, a callfuncs.ci file will be generated,
+ which can then be sourced by callfuncs.exp to give callfuncs.exp access
+ to information about the compilation environment.
+
+ TODO: It might be a good idea to add expect code that tests each
+ definition made with 'set" to see if one already exists, and if so
+ warn about conflicts if it is being set to something else. */
+
+/* This needs to be kept in sync with whatis.c and gdb.exp(get_compiler_info).
+ If this ends up being hairy, we could use a common header file. */
+
+#if defined (__STDC__) || defined (_AIX)
+set signed_keyword_not_used 0
+#else
+set signed_keyword_not_used 1
+#endif
+
+#if defined (__GNUC__)
+set gcc_compiled __GNUC__
+#else
+set gcc_compiled 0
+#endif
+
+return 0
diff --git a/gdb/testsuite/lib/compiler.cc b/gdb/testsuite/lib/compiler.cc
new file mode 100644
index 00000000000..5cb00f6685a
--- /dev/null
+++ b/gdb/testsuite/lib/compiler.cc
@@ -0,0 +1,34 @@
+/* Often the behavior of any particular test depends upon what compiler was
+ used to compile the test. As each test is compiled, this file is
+ preprocessed by the same compiler used to compile that specific test
+ (different tests might be compiled by different compilers, particularly
+ if compiled at different times), and used to generate a *.ci (compiler
+ info) file for that test.
+
+ I.E., when callfuncs is compiled, a callfuncs.ci file will be generated,
+ which can then be sourced by callfuncs.exp to give callfuncs.exp access
+ to information about the compilation environment.
+
+ TODO: It might be a good idea to add expect code that tests each
+ definition made with 'set" to see if one already exists, and if so
+ warn about conflicts if it is being set to something else. */
+
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 6))
+set supports_template_debugging 1
+#else
+set supports_template_debugging 0
+#endif
+
+#if defined(__cplusplus)
+set supports_template_debugging 1
+#else
+set supports_template_debugging 0
+#endif
+
+#if defined (__GNUC__)
+set gcc_compiled __GNUC__
+#else
+set gcc_compiled 0
+#endif
+
+return 0
diff --git a/gdb/testsuite/lib/emc-support.exp b/gdb/testsuite/lib/emc-support.exp
new file mode 100644
index 00000000000..70bf2df0690
--- /dev/null
+++ b/gdb/testsuite/lib/emc-support.exp
@@ -0,0 +1,223 @@
+proc gdb_emc_readvar { varname } {
+ global gdb_prompt;
+
+ set result -1;
+ send_gdb "print $varname\n"
+ gdb_expect 5 {
+ -re "\[$\].*= (\[0-9\]+).*$gdb_prompt $" {
+ set result $expect_out(1,string);
+ }
+ -re "$gdb_prompt $" { }
+ default { }
+ }
+ return $result;
+}
+
+proc gdb_emc_gettpnum { testname } {
+ global gdb_prompt;
+
+ if { $testname != "" } {
+ gdb_test "trace $testname" "" ""
+ }
+ return [gdb_emc_readvar "\$tpnum"];
+}
+
+proc gdb_emc_setactions { testname actionname args } {
+ global gdb_prompt;
+
+ set state 0;
+ set status "pass";
+ send_gdb "actions $actionname\n";
+ set expected_result "";
+ gdb_expect 5 {
+ -re "No tracepoint number .*$gdb_prompt $" {
+ fail $testname
+ return 1;
+ }
+ -re "Enter actions for tracepoint $actionname.*>" {
+ if { [llength $args] > 0 } {
+ set lastcommand "[lindex $args $state]";
+ send_gdb "[lindex $args $state]\n";
+ incr state;
+ set expected_result [lindex $args $state];
+ incr state;
+ } else {
+ send_gdb "end\n";
+ }
+ exp_continue;
+ }
+ -re "\(.*\[\r\n\]+)\[ \t]*> $" {
+ if { $expected_result != "" } {
+ # Remove echoed command and its associated newline.
+ regsub "^\[^\r\n\]+\[\r\n\]+" "$expect_out(1,string)" "" out;
+ # Strip off any newlines at the end of the string.
+ regsub "\[\r\n\]+$" "$out" "" out;
+ verbose "expected '$expected_result', got '$out', expect_out is '$expect_out(1,string)'";
+ if ![regexp $expected_result $out] {
+ set status "fail";
+ }
+ set expected_result "";
+ }
+ if { $state < [llength $args] } {
+ send_gdb "[lindex $args $state]\n";
+ incr state;
+ set expected_result [lindex $args $state];
+ incr state;
+ } else {
+ send_gdb "end\n";
+ set expected_result "";
+ }
+ exp_continue;
+ }
+ -re "\(.*\)$gdb_prompt $" {
+ if { $expected_result != "" } {
+ if ![regexp $expected_result $expect_out(1,string)] {
+ set status "fail";
+ }
+ set expected_result "";
+ }
+ if { [llength $args] < $state } {
+ set status "fail";
+ }
+ }
+ default {
+ set status "fail";
+ }
+ }
+ if { $testname != "" } {
+ $status $testname;
+ }
+ if { $status == "pass" } then {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+#
+# test collect command
+#
+
+proc gdb_emc_tracetest_collect { arg1 msgstring } {
+ global decimal
+ global gdb_prompt;
+
+ set teststate 0
+ gdb_expect 30 {
+ -re "Enter actions for tracepoint $decimal.*> $" {
+ send_gdb "collect $arg1\n"
+ incr teststate;
+ exp_continue
+ }
+ -re "> $" {
+ if { $teststate == 1 } {
+ send_gdb "end\n"
+ incr teststate;
+ exp_continue
+ } else {
+ fail "$msgstring"
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ if { $teststate == 2 } {
+ pass "$msgstring";
+ } else {
+ fail "$msgstring";
+ }
+ }
+ default {
+ fail "$msgstring (default)";
+ }
+ }
+ regsub -all "(\[($@*+)\])" "collect $arg1" "\[\\1\]" arg1_regexp;
+ gdb_test "info tracepoints" ".*$arg1_regexp.*" "$msgstring info tracepoint"
+}
+
+proc gdb_delete_tracepoints { } {
+ global gdb_prompt;
+
+ send_gdb "delete tracepoints\n"
+ gdb_expect 30 {
+ -re "Delete all tracepoints.*y or n.*$" {
+ send_gdb "y\n"
+ exp_continue;
+ }
+ -re "$gdb_prompt $" { }
+ timeout { fail "delete all tracepoints (timeout)" }
+ }
+}
+
+
+# Send each command in the list CMDLIST to gdb. If we see the string
+# "error" or "warning" from gdb, we assume an error has occured and
+# return a non-zero result. All of the commands in CMDLIST are always
+# sent, even if an error occurs.
+# If TESTNAME is non-null, we call pass or fail with the string in TESTNAME
+# depending on whether or not an error/warning has occurred.
+#
+proc gdb_do_cmdlist { cmdlist testname } {
+ global gdb_prompt;
+
+ set status 0;
+
+ foreach x $cmdlist {
+ send_gdb "$x\n";
+ gdb_expect 60 {
+ -re "\[Ee\]rror|\[Ww\]arning" {
+ set status 1;
+ exp_continue;
+ }
+ -re "$gdb_prompt $" { }
+ -re "\[\r\n\]\[ \t\]*> *$" { }
+ }
+ }
+ if { $testname != "" } {
+ if { $status == 0 } {
+ pass "$testname";
+ } else {
+ fail "$testname";
+ }
+ }
+ return $status;
+}
+
+#
+# Given the file FILENAME, we read it as a list of commands and generate
+# a list suitable for use by gdb_do_cmdlist. Lines beginning with # are
+# ignored; blank lines are interpreted as empty lines to be sent to gdb.
+#
+proc gdb_process_cmdfile { filename } {
+ set id [open $filename "r"];
+ if { $id < 0 } {
+ return "";
+ }
+ set result {};
+ while { [gets $id line] >= 0 } {
+ if [regexp "^#" $line] {
+ continue;
+ }
+ set result [concat $result [list "$line"]];
+ }
+ close $id;
+ return $result;
+}
+
+# gdb_find_c_test_baseline
+# returns -1 on failure (CALLER MUST CHECK RETURN!)
+proc gdb_find_c_test_baseline { } {
+ global gdb_prompt;
+
+ set gdb_c_test_baseline -1;
+
+ send_gdb "list gdb_c_test\n"
+ gdb_expect {
+ -re "void.*p5,.*void.*p6.*\[\r\n\](\[0-9\]+)\[\t \]+\{.*$gdb_prompt $" {
+ set gdb_c_test_baseline $expect_out(1,string)
+ }
+ -re "$gdb_prompt $" { }
+ default { }
+ }
+ return $gdb_c_test_baseline;
+}
+
+
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
new file mode 100644
index 00000000000..d9285e86945
--- /dev/null
+++ b/gdb/testsuite/lib/gdb.exp
@@ -0,0 +1,1684 @@
+# Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+# Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+# Generic gdb subroutines that should work for any target. If these
+# need to be modified for any target, it can be done with a variable
+# or by passing arguments.
+
+load_lib libgloss.exp
+
+global GDB
+global CHILL_LIB
+global CHILL_RT0
+
+if ![info exists CHILL_LIB] {
+ set CHILL_LIB [findfile $base_dir/../../gcc/ch/runtime/libchill.a "$base_dir/../../gcc/ch/runtime/libchill.a" [transform -lchill]]
+}
+verbose "using CHILL_LIB = $CHILL_LIB" 2
+if ![info exists CHILL_RT0] {
+ set CHILL_RT0 [findfile $base_dir/../../gcc/ch/runtime/chillrt0.o "$base_dir/../../gcc/ch/runtime/chillrt0.o" ""]
+}
+verbose "using CHILL_RT0 = $CHILL_RT0" 2
+
+if [info exists TOOL_EXECUTABLE] {
+ set GDB $TOOL_EXECUTABLE;
+}
+if ![info exists GDB] {
+ if ![is_remote host] {
+ set GDB [findfile $base_dir/../../gdb/gdb "$base_dir/../../gdb/gdb" [transform gdb]]
+ } else {
+ set GDB [transform gdb];
+ }
+}
+verbose "using GDB = $GDB" 2
+
+global GDBFLAGS
+if ![info exists GDBFLAGS] {
+ set GDBFLAGS "-nx"
+}
+verbose "using GDBFLAGS = $GDBFLAGS" 2
+
+# The variable gdb_prompt is a regexp which matches the gdb prompt.
+# Set it if it is not already set.
+global gdb_prompt
+if ![info exists gdb_prompt] then {
+ set gdb_prompt "\[(\]gdb\[)\]"
+}
+
+# Needed for some tests under Cygwin.
+global EXEEXT
+global env
+
+if ![info exists env(EXEEXT)] {
+ set EXEEXT ""
+} else {
+ set EXEEXT $env(EXEEXT)
+}
+
+### Only procedures should come after this point.
+
+#
+# gdb_version -- extract and print the version number of GDB
+#
+proc default_gdb_version {} {
+ global GDB
+ global GDBFLAGS
+ global gdb_prompt
+ set fileid [open "gdb_cmd" w];
+ puts $fileid "q";
+ close $fileid;
+ set cmdfile [remote_download host "gdb_cmd"];
+ set output [remote_exec host "$GDB -nw --command $cmdfile"]
+ remote_file build delete "gdb_cmd";
+ remote_file host delete "$cmdfile";
+ set tmp [lindex $output 1];
+ set version ""
+ regexp " \[0-9\]\[^ \t\n\r\]+" "$tmp" version
+ if ![is_remote host] {
+ clone_output "[which $GDB] version $version $GDBFLAGS\n"
+ } else {
+ clone_output "$GDB on remote host version $version $GDBFLAGS\n"
+ }
+}
+
+proc gdb_version { } {
+ return [default_gdb_version];
+}
+
+#
+# gdb_unload -- unload a file if one is loaded
+#
+
+proc gdb_unload {} {
+ global verbose
+ global GDB
+ global gdb_prompt
+ send_gdb "file\n"
+ gdb_expect 60 {
+ -re "No executable file now\[^\r\n\]*\[\r\n\]" { exp_continue }
+ -re "No symbol file now\[^\r\n\]*\[\r\n\]" { exp_continue }
+ -re "A program is being debugged already..*Kill it.*y or n. $"\
+ { send_gdb "y\n"
+ verbose "\t\tKilling previous program being debugged"
+ exp_continue
+ }
+ -re "Discard symbol table from .*y or n.*$" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "$gdb_prompt $" {}
+ timeout {
+ perror "couldn't unload file in $GDB (timed out)."
+ return -1
+ }
+ }
+}
+
+# Many of the tests depend on setting breakpoints at various places and
+# running until that breakpoint is reached. At times, we want to start
+# with a clean-slate with respect to breakpoints, so this utility proc
+# lets us do this without duplicating this code everywhere.
+#
+
+proc delete_breakpoints {} {
+ global gdb_prompt
+
+ # we need a larger timeout value here or this thing just confuses
+ # itself. May need a better implementation if possible. - guo
+ #
+ send_gdb "delete breakpoints\n"
+ gdb_expect 100 {
+ -re "Delete all breakpoints.*y or n.*$" {
+ send_gdb "y\n";
+ exp_continue
+ }
+ -re "$gdb_prompt $" { # This happens if there were no breakpoints
+ }
+ timeout { perror "Delete all breakpoints in delete_breakpoints (timeout)" ; return }
+ }
+ send_gdb "info breakpoints\n"
+ gdb_expect 100 {
+ -re "No breakpoints or watchpoints..*$gdb_prompt $" {}
+ -re "$gdb_prompt $" { perror "breakpoints not deleted" ; return }
+ -re "Delete all breakpoints.*or n.*$" {
+ send_gdb "y\n";
+ exp_continue
+ }
+ timeout { perror "info breakpoints (timeout)" ; return }
+ }
+}
+
+
+#
+# Generic run command.
+#
+# The second pattern below matches up to the first newline *only*.
+# Using ``.*$'' could swallow up output that we attempt to match
+# elsewhere.
+#
+proc gdb_run_cmd {args} {
+ global gdb_prompt
+
+ if [target_info exists gdb_init_command] {
+ send_gdb "[target_info gdb_init_command]\n";
+ gdb_expect 30 {
+ -re "$gdb_prompt $" { }
+ default {
+ perror "gdb_init_command for target failed";
+ return;
+ }
+ }
+ }
+
+ if [target_info exists use_gdb_stub] {
+ if [target_info exists gdb,do_reload_on_run] {
+ # Specifying no file, defaults to the executable
+ # currently being debugged.
+ if { [gdb_load ""] < 0 } {
+ return;
+ }
+ send_gdb "continue\n";
+ gdb_expect 60 {
+ -re "Continu\[^\r\n\]*\[\r\n\]" {}
+ default {}
+ }
+ return;
+ }
+
+ if [target_info exists gdb,start_symbol] {
+ set start [target_info gdb,start_symbol];
+ } else {
+ set start "start";
+ }
+ send_gdb "jump *$start\n"
+ set start_attempt 1;
+ while { $start_attempt } {
+ # Cap (re)start attempts at three to ensure that this loop
+ # always eventually fails. Don't worry about trying to be
+ # clever and not send a command when it has failed.
+ if [expr $start_attempt > 3] {
+ perror "Jump to start() failed (retry count exceeded)";
+ return;
+ }
+ set start_attempt [expr $start_attempt + 1];
+ gdb_expect 30 {
+ -re "Continuing at \[^\r\n\]*\[\r\n\]" {
+ set start_attempt 0;
+ }
+ -re "No symbol \"_start\" in current.*$gdb_prompt $" {
+ perror "Can't find start symbol to run in gdb_run";
+ return;
+ }
+ -re "No symbol \"start\" in current.*$gdb_prompt $" {
+ send_gdb "jump *_start\n";
+ }
+ -re "No symbol.*context.*$gdb_prompt $" {
+ set start_attempt 0;
+ }
+ -re "Line.* Jump anyway.*y or n. $" {
+ send_gdb "y\n"
+ }
+ -re "The program is not being run.*$gdb_prompt $" {
+ if { [gdb_load ""] < 0 } {
+ return;
+ }
+ send_gdb "jump *$start\n";
+ }
+ timeout {
+ perror "Jump to start() failed (timeout)";
+ return
+ }
+ }
+ }
+ if [target_info exists gdb_stub] {
+ gdb_expect 60 {
+ -re "$gdb_prompt $" {
+ send_gdb "continue\n"
+ }
+ }
+ }
+ return
+ }
+ send_gdb "run $args\n"
+# This doesn't work quite right yet.
+ gdb_expect 60 {
+ -re "The program .* has been started already.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "Starting program: \[^\r\n\]*" {}
+ }
+}
+
+proc gdb_breakpoint { function } {
+ global gdb_prompt
+ global decimal
+
+ send_gdb "break $function\n"
+ # The first two regexps are what we get with -g, the third is without -g.
+ gdb_expect 30 {
+ -re "Breakpoint \[0-9\]* at .*: file .*, line $decimal.\r\n$gdb_prompt $" {}
+ -re "Breakpoint \[0-9\]*: file .*, line $decimal.\r\n$gdb_prompt $" {}
+ -re "Breakpoint \[0-9\]* at .*$gdb_prompt $" {}
+ -re "$gdb_prompt $" { fail "setting breakpoint at $function" ; return 0 }
+ timeout { fail "setting breakpoint at $function (timeout)" ; return 0 }
+ }
+ return 1;
+}
+
+# Set breakpoint at function and run gdb until it breaks there.
+# Since this is the only breakpoint that will be set, if it stops
+# at a breakpoint, we will assume it is the one we want. We can't
+# just compare to "function" because it might be a fully qualified,
+# single quoted C++ function specifier.
+
+proc runto { function } {
+ global gdb_prompt
+ global decimal
+
+ delete_breakpoints
+
+ if ![gdb_breakpoint $function] {
+ return 0;
+ }
+
+ gdb_run_cmd
+
+ # the "at foo.c:36" output we get with -g.
+ # the "in func" output we get without -g.
+ gdb_expect 30 {
+ -re "Break.* at .*:$decimal.*$gdb_prompt $" {
+ return 1
+ }
+ -re "Breakpoint \[0-9\]*, \[0-9xa-f\]* in .*$gdb_prompt $" {
+ return 1
+ }
+ -re "$gdb_prompt $" {
+ fail "running to $function in runto"
+ return 0
+ }
+ timeout {
+ fail "running to $function in runto (timeout)"
+ return 0
+ }
+ }
+ return 1
+}
+
+#
+# runto_main -- ask gdb to run until we hit a breakpoint at main.
+# The case where the target uses stubs has to be handled
+# specially--if it uses stubs, assuming we hit
+# breakpoint() and just step out of the function.
+#
+proc runto_main { } {
+ global gdb_prompt
+ global decimal
+
+ if ![target_info exists gdb_stub] {
+ return [runto main]
+ }
+
+ delete_breakpoints
+
+ gdb_step_for_stub;
+
+ return 1
+}
+
+
+### Continue, and expect to hit a breakpoint.
+### Report a pass or fail, depending on whether it seems to have
+### worked. Use NAME as part of the test name; each call to
+### continue_to_breakpoint should use a NAME which is unique within
+### that test file.
+proc gdb_continue_to_breakpoint {name} {
+ global gdb_prompt
+ set full_name "continue to breakpoint: $name"
+
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Breakpoint .* at .*\r\n$gdb_prompt $" {
+ pass $full_name
+ }
+ -re ".*$gdb_prompt $" {
+ fail $full_name
+ }
+ timeout {
+ fail "$full_name (timeout)"
+ }
+ }
+}
+
+
+
+# gdb_test COMMAND PATTERN MESSAGE QUESTION RESPONSE
+# Send a command to gdb; test the result.
+#
+# COMMAND is the command to execute, send to GDB with send_gdb. If
+# this is the null string no command is sent.
+# PATTERN is the pattern to match for a PASS, and must NOT include
+# the \r\n sequence immediately before the gdb prompt.
+# MESSAGE is an optional message to be printed. If this is
+# omitted, then the pass/fail messages use the command string as the
+# message. (If this is the empty string, then sometimes we don't
+# call pass or fail at all; I don't understand this at all.)
+# QUESTION is a question GDB may ask in response to COMMAND, like
+# "are you sure?"
+# RESPONSE is the response to send if QUESTION appears.
+#
+# Returns:
+# 1 if the test failed,
+# 0 if the test passes,
+# -1 if there was an internal error.
+#
+proc gdb_test { args } {
+ global verbose
+ global gdb_prompt
+ global GDB
+ upvar timeout timeout
+
+ if [llength $args]>2 then {
+ set message [lindex $args 2]
+ } else {
+ set message [lindex $args 0]
+ }
+ set command [lindex $args 0]
+ set pattern [lindex $args 1]
+
+ if [llength $args]==5 {
+ set question_string [lindex $args 3];
+ set response_string [lindex $args 4];
+ } else {
+ set question_string "^FOOBAR$"
+ }
+
+ if $verbose>2 then {
+ send_user "Sending \"$command\" to gdb\n"
+ send_user "Looking to match \"$pattern\"\n"
+ send_user "Message is \"$message\"\n"
+ }
+
+ set result -1
+ set string "${command}\n";
+ if { $command != "" } {
+ while { "$string" != "" } {
+ set foo [string first "\n" "$string"];
+ set len [string length "$string"];
+ if { $foo < [expr $len - 1] } {
+ set str [string range "$string" 0 $foo];
+ if { [send_gdb "$str"] != "" } {
+ global suppress_flag;
+
+ if { ! $suppress_flag } {
+ perror "Couldn't send $command to GDB.";
+ }
+ fail "$message";
+ return $result;
+ }
+ # since we're checking if each line of the multi-line
+ # command are 'accepted' by GDB here,
+ # we need to set -notransfer expect option so that
+ # command output is not lost for pattern matching
+ # - guo
+ gdb_expect 2 {
+ -notransfer -re "\[\r\n\]" { verbose "partial: match" 3 }
+ timeout { verbose "partial: timeout" 3 }
+ }
+ set string [string range "$string" [expr $foo + 1] end];
+ } else {
+ break;
+ }
+ }
+ if { "$string" != "" } {
+ if { [send_gdb "$string"] != "" } {
+ global suppress_flag;
+
+ if { ! $suppress_flag } {
+ perror "Couldn't send $command to GDB.";
+ }
+ fail "$message";
+ return $result;
+ }
+ }
+ }
+
+ if [target_info exists gdb,timeout] {
+ set tmt [target_info gdb,timeout];
+ } else {
+ if [info exists timeout] {
+ set tmt $timeout;
+ } else {
+ global timeout;
+ if [info exists timeout] {
+ set tmt $timeout;
+ } else {
+ set tmt 60;
+ }
+ }
+ }
+ gdb_expect $tmt {
+ -re "\\*\\*\\* DOSEXIT code.*" {
+ if { $message != "" } {
+ fail "$message";
+ }
+ gdb_suppress_entire_file "GDB died";
+ return -1;
+ }
+ -re "Ending remote debugging.*$gdb_prompt $" {
+ if ![isnative] then {
+ warning "Can`t communicate to remote target."
+ }
+ gdb_exit
+ gdb_start
+ set result -1
+ }
+ -re "\[\r\n\]*($pattern)\[\r\n\]+$gdb_prompt $" {
+ if ![string match "" $message] then {
+ pass "$message"
+ }
+ set result 0
+ }
+ -re "(${question_string})$" {
+ send_gdb "$response_string\n";
+ exp_continue;
+ }
+ -re "Undefined\[a-z\]* command:.*$gdb_prompt $" {
+ perror "Undefined command \"$command\"."
+ fail "$message"
+ set result 1
+ }
+ -re "Ambiguous command.*$gdb_prompt $" {
+ perror "\"$command\" is not a unique command name."
+ fail "$message"
+ set result 1
+ }
+ -re "Program exited with code \[0-9\]+.*$gdb_prompt $" {
+ if ![string match "" $message] then {
+ set errmsg "$message: the program exited"
+ } else {
+ set errmsg "$command: the program exited"
+ }
+ fail "$errmsg"
+ return -1
+ }
+ -re "EXIT code \[0-9\r\n\]+Program exited normally.*$gdb_prompt $" {
+ if ![string match "" $message] then {
+ set errmsg "$message: the program exited"
+ } else {
+ set errmsg "$command: the program exited"
+ }
+ fail "$errmsg"
+ return -1
+ }
+ -re "The program is not being run.*$gdb_prompt $" {
+ if ![string match "" $message] then {
+ set errmsg "$message: the program is no longer running"
+ } else {
+ set errmsg "$command: the program is no longer running"
+ }
+ fail "$errmsg"
+ return -1
+ }
+ -re ".*$gdb_prompt $" {
+ if ![string match "" $message] then {
+ fail "$message"
+ }
+ set result 1
+ }
+ "<return>" {
+ send_gdb "\n"
+ perror "Window too small."
+ fail "$message"
+ }
+ -re "\\(y or n\\) " {
+ send_gdb "n\n"
+ perror "Got interactive prompt."
+ fail "$message"
+ }
+ eof {
+ perror "Process no longer exists"
+ if { $message != "" } {
+ fail "$message"
+ }
+ return -1
+ }
+ full_buffer {
+ perror "internal buffer is full."
+ fail "$message"
+ }
+ timeout {
+ if ![string match "" $message] then {
+ fail "$message (timeout)"
+ }
+ set result 1
+ }
+ }
+ return $result
+}
+
+# Test that a command gives an error. For pass or fail, return
+# a 1 to indicate that more tests can proceed. However a timeout
+# is a serious error, generates a special fail message, and causes
+# a 0 to be returned to indicate that more tests are likely to fail
+# as well.
+
+proc test_print_reject { args } {
+ global gdb_prompt
+ global verbose
+
+ if [llength $args]==2 then {
+ set expectthis [lindex $args 1]
+ } else {
+ set expectthis "should never match this bogus string"
+ }
+ set sendthis [lindex $args 0]
+ if $verbose>2 then {
+ send_user "Sending \"$sendthis\" to gdb\n"
+ send_user "Looking to match \"$expectthis\"\n"
+ }
+ send_gdb "$sendthis\n"
+ #FIXME: Should add timeout as parameter.
+ gdb_expect {
+ -re "A .* in expression.*\\.*$gdb_prompt $" {
+ pass "reject $sendthis"
+ return 1
+ }
+ -re "Invalid syntax in expression.*$gdb_prompt $" {
+ pass "reject $sendthis"
+ return 1
+ }
+ -re "Junk after end of expression.*$gdb_prompt $" {
+ pass "reject $sendthis"
+ return 1
+ }
+ -re "Invalid number.*$gdb_prompt $" {
+ pass "reject $sendthis"
+ return 1
+ }
+ -re "Invalid character constant.*$gdb_prompt $" {
+ pass "reject $sendthis"
+ return 1
+ }
+ -re "No symbol table is loaded.*$gdb_prompt $" {
+ pass "reject $sendthis"
+ return 1
+ }
+ -re "No symbol .* in current context.*$gdb_prompt $" {
+ pass "reject $sendthis"
+ return 1
+ }
+ -re "Unmatched single quote.*$gdb_prompt $" {
+ pass "reject $sendthis"
+ return 1
+ }
+ -re "A character constant must contain at least one character.*$gdb_prompt $" {
+ pass "reject $sendthis"
+ return 1
+ }
+ -re "$expectthis.*$gdb_prompt $" {
+ pass "reject $sendthis"
+ return 1
+ }
+ -re ".*$gdb_prompt $" {
+ fail "reject $sendthis"
+ return 1
+ }
+ default {
+ fail "reject $sendthis (eof or timeout)"
+ return 0
+ }
+ }
+}
+
+# Given an input string, adds backslashes as needed to create a
+# regexp that will match the string.
+
+proc string_to_regexp {str} {
+ set result $str
+ regsub -all {[]*+.|()^$\[]} $str {\\&} result
+ return $result
+}
+
+# Same as gdb_test, but the second parameter is not a regexp,
+# but a string that must match exactly.
+
+proc gdb_test_exact { args } {
+ upvar timeout timeout
+
+ set command [lindex $args 0]
+
+ # This applies a special meaning to a null string pattern. Without
+ # this, "$pattern\r\n$gdb_prompt $" will match anything, including error
+ # messages from commands that should have no output except a new
+ # prompt. With this, only results of a null string will match a null
+ # string pattern.
+
+ set pattern [lindex $args 1]
+ if [string match $pattern ""] {
+ set pattern [string_to_regexp [lindex $args 0]]
+ } else {
+ set pattern [string_to_regexp [lindex $args 1]]
+ }
+
+ # It is most natural to write the pattern argument with only
+ # embedded \n's, especially if you are trying to avoid Tcl quoting
+ # problems. But gdb_expect really wants to see \r\n in patterns. So
+ # transform the pattern here. First transform \r\n back to \n, in
+ # case some users of gdb_test_exact already do the right thing.
+ regsub -all "\r\n" $pattern "\n" pattern
+ regsub -all "\n" $pattern "\r\n" pattern
+ if [llength $args]==3 then {
+ set message [lindex $args 2]
+ } else {
+ set message $command
+ }
+
+ return [gdb_test $command $pattern $message]
+}
+
+proc gdb_reinitialize_dir { subdir } {
+ global gdb_prompt
+
+ if [is_remote host] {
+ return "";
+ }
+ send_gdb "dir\n"
+ gdb_expect 60 {
+ -re "Reinitialize source path to empty.*y or n. " {
+ send_gdb "y\n"
+ gdb_expect 60 {
+ -re "Source directories searched.*$gdb_prompt $" {
+ send_gdb "dir $subdir\n"
+ gdb_expect 60 {
+ -re "Source directories searched.*$gdb_prompt $" {
+ verbose "Dir set to $subdir"
+ }
+ -re "$gdb_prompt $" {
+ perror "Dir \"$subdir\" failed."
+ }
+ }
+ }
+ -re "$gdb_prompt $" {
+ perror "Dir \"$subdir\" failed."
+ }
+ }
+ }
+ -re "$gdb_prompt $" {
+ perror "Dir \"$subdir\" failed."
+ }
+ }
+}
+
+#
+# gdb_exit -- exit the GDB, killing the target program if necessary
+#
+proc default_gdb_exit {} {
+ global GDB
+ global GDBFLAGS
+ global verbose
+ global gdb_spawn_id;
+
+ gdb_stop_suppressing_tests;
+
+ if ![info exists gdb_spawn_id] {
+ return;
+ }
+
+ verbose "Quitting $GDB $GDBFLAGS"
+
+ if { [is_remote host] && [board_info host exists fileid] } {
+ send_gdb "quit\n";
+ gdb_expect 10 {
+ -re "y or n" {
+ send_gdb "y\n";
+ exp_continue;
+ }
+ -re "DOSEXIT code" { }
+ default { }
+ }
+ }
+
+ if ![is_remote host] {
+ remote_close host;
+ }
+ unset gdb_spawn_id
+}
+
+#
+# load a file into the debugger.
+# return a -1 if anything goes wrong.
+#
+proc gdb_file_cmd { arg } {
+ global verbose
+ global loadpath
+ global loadfile
+ global GDB
+ global gdb_prompt
+ upvar timeout timeout
+
+ if [is_remote host] {
+ set arg [remote_download host $arg];
+ if { $arg == "" } {
+ error "download failed"
+ return -1;
+ }
+ }
+
+ send_gdb "file $arg\n"
+ gdb_expect 120 {
+ -re "Reading symbols from.*done.*$gdb_prompt $" {
+ verbose "\t\tLoaded $arg into the $GDB"
+ return 0
+ }
+ -re "has no symbol-table.*$gdb_prompt $" {
+ perror "$arg wasn't compiled with \"-g\""
+ return -1
+ }
+ -re "A program is being debugged already.*Kill it.*y or n. $" {
+ send_gdb "y\n"
+ verbose "\t\tKilling previous program being debugged"
+ exp_continue
+ }
+ -re "Load new symbol table from \".*\".*y or n. $" {
+ send_gdb "y\n"
+ gdb_expect 120 {
+ -re "Reading symbols from.*done.*$gdb_prompt $" {
+ verbose "\t\tLoaded $arg with new symbol table into $GDB"
+ return 0
+ }
+ timeout {
+ perror "(timeout) Couldn't load $arg, other program already loaded."
+ return -1
+ }
+ }
+ }
+ -re "No such file or directory.*$gdb_prompt $" {
+ perror "($arg) No such file or directory\n"
+ return -1
+ }
+ -re "$gdb_prompt $" {
+ perror "couldn't load $arg into $GDB."
+ return -1
+ }
+ timeout {
+ perror "couldn't load $arg into $GDB (timed out)."
+ return -1
+ }
+ eof {
+ # This is an attempt to detect a core dump, but seems not to
+ # work. Perhaps we need to match .* followed by eof, in which
+ # gdb_expect does not seem to have a way to do that.
+ perror "couldn't load $arg into $GDB (end of file)."
+ return -1
+ }
+ }
+}
+
+#
+# start gdb -- start gdb running, default procedure
+#
+# When running over NFS, particularly if running many simultaneous
+# tests on different hosts all using the same server, things can
+# get really slow. Give gdb at least 3 minutes to start up.
+#
+proc default_gdb_start { } {
+ global verbose
+ global GDB
+ global GDBFLAGS
+ global gdb_prompt
+ global timeout
+ global gdb_spawn_id;
+
+ gdb_stop_suppressing_tests;
+
+ verbose "Spawning $GDB -nw $GDBFLAGS"
+
+ if [info exists gdb_spawn_id] {
+ return 0;
+ }
+
+ if ![is_remote host] {
+ if { [which $GDB] == 0 } then {
+ perror "$GDB does not exist."
+ exit 1
+ }
+ }
+ set res [remote_spawn host "$GDB -nw $GDBFLAGS [host_info gdb_opts]"];
+ if { $res < 0 || $res == "" } {
+ perror "Spawning $GDB failed."
+ return 1;
+ }
+ gdb_expect 360 {
+ -re "\[\r\n\]$gdb_prompt $" {
+ verbose "GDB initialized."
+ }
+ -re "$gdb_prompt $" {
+ perror "GDB never initialized."
+ return -1
+ }
+ timeout {
+ perror "(timeout) GDB never initialized after 10 seconds."
+ remote_close host;
+ return -1
+ }
+ }
+ set gdb_spawn_id -1;
+ # force the height to "unlimited", so no pagers get used
+
+ send_gdb "set height 0\n"
+ gdb_expect 10 {
+ -re "$gdb_prompt $" {
+ verbose "Setting height to 0." 2
+ }
+ timeout {
+ warning "Couldn't set the height to 0"
+ }
+ }
+ # force the width to "unlimited", so no wraparound occurs
+ send_gdb "set width 0\n"
+ gdb_expect 10 {
+ -re "$gdb_prompt $" {
+ verbose "Setting width to 0." 2
+ }
+ timeout {
+ warning "Couldn't set the width to 0."
+ }
+ }
+ return 0;
+}
+
+# Return a 1 for configurations for which we don't even want to try to
+# test C++.
+
+proc skip_cplus_tests {} {
+ if { [istarget "d10v-*-*"] } {
+ return 1
+ }
+ if { [istarget "h8300-*-*"] } {
+ return 1
+ }
+ return 0
+}
+
+# * For crosses, the CHILL runtime doesn't build because it can't find
+# setjmp.h, stdio.h, etc.
+# * For AIX (as of 16 Mar 95), (a) there is no language code for
+# CHILL in output_epilog in gcc/config/rs6000/rs6000.c, (b) collect2
+# does not get along with AIX's too-clever linker.
+# * On Irix5, there is a bug whereby set of bool, etc., don't get
+# TYPE_LOW_BOUND for the bool right because force_to_range_type doesn't
+# work with stub types.
+# Lots of things seem to fail on the PA, and since it's not a supported
+# chill target at the moment, don't run the chill tests.
+
+proc skip_chill_tests {} {
+ if ![info exists do_chill_tests] {
+ return 1;
+ }
+ eval set skip_chill [expr ![isnative] || [istarget "*-*-aix*"] || [istarget "*-*-irix5*"] || [istarget "*-*-irix6*"] || [istarget "alpha-*-osf*"] || [istarget "hppa*-*-*"]]
+ verbose "Skip chill tests is $skip_chill"
+ return $skip_chill
+}
+
+# Skip all the tests in the file if you are not on an hppa running
+# hpux target.
+
+proc skip_hp_tests {} {
+ eval set skip_hp [ expr ![isnative] || ![istarget "hppa*-*-hpux*"] ]
+ verbose "Skip hp tests is $skip_hp"
+ return $skip_hp
+}
+
+proc get_compiler_info {binfile args} {
+ # Create and source the file that provides information about the compiler
+ # used to compile the test case.
+ # Compiler_type can be null or c++. If null we assume c.
+ global srcdir
+ global subdir
+ # These two come from compiler.c.
+ global signed_keyword_not_used
+ global gcc_compiled
+
+ if {![istarget "hppa*-*-hpux*"]} {
+ if { [llength $args] > 0 } {
+ if {$args == "c++"} {
+ if { [gdb_compile "${srcdir}/lib/compiler.cc" "${binfile}.ci" preprocess {}] != "" } {
+ perror "Couldn't make ${binfile}.ci file"
+ return 1;
+ }
+ }
+ } else {
+ if { [gdb_compile "${srcdir}/lib/compiler.c" "${binfile}.ci" preprocess {}] != "" } {
+ perror "Couldn't make ${binfile}.ci file"
+ return 1;
+ }
+ }
+ } else {
+ if { [llength $args] > 0 } {
+ if {$args == "c++"} {
+ if { [eval gdb_preprocess \
+ [list "${srcdir}/lib/compiler.cc" "${binfile}.ci"] \
+ $args] != "" } {
+ perror "Couldn't make ${binfile}.ci file"
+ return 1;
+ }
+ }
+ } elseif { $args != "f77" } {
+ if { [eval gdb_preprocess \
+ [list "${srcdir}/lib/compiler.c" "${binfile}.ci"] \
+ $args] != "" } {
+ perror "Couldn't make ${binfile}.ci file"
+ return 1;
+ }
+ }
+ }
+
+ uplevel \#0 { set gcc_compiled 0 }
+
+ if { [llength $args] == 0 || $args != "f77" } {
+ source ${binfile}.ci
+ }
+
+ # Most compilers will evaluate comparisons and other boolean
+ # operations to 0 or 1.
+ uplevel \#0 { set true 1 }
+ uplevel \#0 { set false 0 }
+
+ uplevel \#0 { set hp_cc_compiler 0 }
+ uplevel \#0 { set hp_aCC_compiler 0 }
+ uplevel \#0 { set hp_f77_compiler 0 }
+ uplevel \#0 { set hp_f90_compiler 0 }
+ if { !$gcc_compiled && [istarget "hppa*-*-hpux*"] } {
+ # Check for the HP compilers
+ set compiler [lindex [split [get_compiler $args] " "] 0]
+ catch "exec what $compiler" output
+ if [regexp ".*HP aC\\+\\+.*" $output] {
+ uplevel \#0 { set hp_aCC_compiler 1 }
+ # Use of aCC results in boolean results being displayed as
+ # "true" or "false"
+ uplevel \#0 { set true true }
+ uplevel \#0 { set false false }
+ } elseif [regexp ".*HP C Compiler.*" $output] {
+ uplevel \#0 { set hp_cc_compiler 1 }
+ } elseif [regexp ".*HP-UX f77.*" $output] {
+ uplevel \#0 { set hp_f77_compiler 1 }
+ } elseif [regexp ".*HP-UX f90.*" $output] {
+ uplevel \#0 { set hp_f90_compiler 1 }
+ }
+ }
+
+ return 0;
+}
+
+proc get_compiler {args} {
+ global CC CC_FOR_TARGET CXX CXX_FOR_TARGET F77_FOR_TARGET
+
+ if { [llength $args] == 0
+ || ([llength $args] == 1 && [lindex $args 0] == "") } {
+ set which_compiler "c"
+ } else {
+ if { $args =="c++" } {
+ set which_compiler "c++"
+ } elseif { $args =="f77" } {
+ set which_compiler "f77"
+ } else {
+ perror "Unknown compiler type supplied to gdb_preprocess"
+ return ""
+ }
+ }
+
+ if [info exists CC_FOR_TARGET] {
+ if {$which_compiler == "c"} {
+ set compiler $CC_FOR_TARGET
+ }
+ }
+
+ if [info exists CXX_FOR_TARGET] {
+ if {$which_compiler == "c++"} {
+ set compiler $CXX_FOR_TARGET
+ }
+ }
+
+ if [info exists F77_FOR_TARGET] {
+ if {$which_compiler == "f77"} {
+ set compiler $F77_FOR_TARGET
+ }
+ }
+
+ if { ![info exists compiler] } {
+ if { $which_compiler == "c" } {
+ if {[info exists CC]} {
+ set compiler $CC
+ }
+ }
+ if { $which_compiler == "c++" } {
+ if {[info exists CXX]} {
+ set compiler $CXX
+ }
+ }
+ if {![info exists compiler]} {
+ set compiler [board_info [target_info name] compiler];
+ if { $compiler == "" } {
+ perror "get_compiler: No compiler found"
+ return ""
+ }
+ }
+ }
+
+ return $compiler
+}
+
+proc gdb_preprocess {source dest args} {
+ set compiler [get_compiler "$args"]
+ if { $compiler == "" } {
+ return 1
+ }
+
+ set cmdline "$compiler -E $source > $dest"
+
+ verbose "Invoking $compiler -E $source > $dest"
+ verbose -log "Executing on local host: $cmdline" 2
+ set status [catch "exec ${cmdline}" exec_output]
+
+ set result [prune_warnings $exec_output]
+ regsub "\[\r\n\]*$" "$result" "" result;
+ regsub "^\[\r\n\]*" "$result" "" result;
+ if { $result != "" } {
+ clone_output "gdb compile failed, $result"
+ }
+ return $result;
+}
+
+set gdb_wrapper_initialized 0
+
+proc gdb_wrapper_init { args } {
+ global gdb_wrapper_initialized;
+ global gdb_wrapper_file;
+ global gdb_wrapper_flags;
+
+ if { $gdb_wrapper_initialized == 1 } { return; }
+
+ if {[target_info exists needs_status_wrapper] && \
+ [target_info needs_status_wrapper] != "0"} {
+ set result [build_wrapper "testglue.o"];
+ if { $result != "" } {
+ set gdb_wrapper_file [lindex $result 0];
+ set gdb_wrapper_flags [lindex $result 1];
+ } else {
+ warning "Status wrapper failed to build."
+ }
+ }
+ set gdb_wrapper_initialized 1
+}
+
+proc gdb_compile {source dest type options} {
+ global GDB_TESTCASE_OPTIONS;
+ global gdb_wrapper_file;
+ global gdb_wrapper_flags;
+ global gdb_wrapper_initialized;
+
+ if [target_info exists gdb_stub] {
+ set options2 { "additional_flags=-Dusestubs" }
+ lappend options "libs=[target_info gdb_stub]";
+ set options [concat $options2 $options]
+ }
+ if [target_info exists is_vxworks] {
+ set options2 { "additional_flags=-Dvxworks" }
+ lappend options "libs=[target_info gdb_stub]";
+ set options [concat $options2 $options]
+ }
+ if [info exists GDB_TESTCASE_OPTIONS] {
+ lappend options "additional_flags=$GDB_TESTCASE_OPTIONS";
+ }
+ verbose "options are $options"
+ verbose "source is $source $dest $type $options"
+
+ if { $gdb_wrapper_initialized == 0 } { gdb_wrapper_init }
+
+ if {[target_info exists needs_status_wrapper] && \
+ [target_info needs_status_wrapper] != "0" && \
+ [info exists gdb_wrapper_file]} {
+ lappend options "libs=${gdb_wrapper_file}"
+ lappend options "ldflags=${gdb_wrapper_flags}"
+ }
+
+ set result [target_compile $source $dest $type $options];
+ regsub "\[\r\n\]*$" "$result" "" result;
+ regsub "^\[\r\n\]*" "$result" "" result;
+ if { $result != "" } {
+ clone_output "gdb compile failed, $result"
+ }
+ return $result;
+}
+
+proc send_gdb { string } {
+ global suppress_flag;
+ if { $suppress_flag } {
+ return "suppressed";
+ }
+ return [remote_send host "$string"];
+}
+
+#
+#
+
+proc gdb_expect { args } {
+ if { [llength $args] == 2 && [lindex $args 0] != "-re" } {
+ set gtimeout [lindex $args 0];
+ set expcode [list [lindex $args 1]];
+ } else {
+ upvar timeout timeout;
+
+ set expcode $args;
+ if [target_info exists gdb,timeout] {
+ if [info exists timeout] {
+ if { $timeout < [target_info gdb,timeout] } {
+ set gtimeout [target_info gdb,timeout];
+ } else {
+ set gtimeout $timeout;
+ }
+ } else {
+ set gtimeout [target_info gdb,timeout];
+ }
+ }
+
+ if ![info exists gtimeout] {
+ global timeout;
+ if [info exists timeout] {
+ set gtimeout $timeout;
+ } else {
+ # Eeeeew.
+ set gtimeout 60;
+ }
+ }
+ }
+ global suppress_flag;
+ global remote_suppress_flag;
+ if [info exists remote_suppress_flag] {
+ set old_val $remote_suppress_flag;
+ }
+ if [info exists suppress_flag] {
+ if { $suppress_flag } {
+ set remote_suppress_flag 1;
+ }
+ }
+ set code [catch \
+ {uplevel remote_expect host $gtimeout $expcode} string];
+ if [info exists old_val] {
+ set remote_suppress_flag $old_val;
+ } else {
+ if [info exists remote_suppress_flag] {
+ unset remote_suppress_flag;
+ }
+ }
+
+ if {$code == 1} {
+ global errorInfo errorCode;
+
+ return -code error -errorinfo $errorInfo -errorcode $errorCode $string
+ } elseif {$code == 2} {
+ return -code return $string
+ } elseif {$code == 3} {
+ return
+ } elseif {$code > 4} {
+ return -code $code $string
+ }
+}
+
+# gdb_expect_list MESSAGE SENTINEL LIST -- expect a sequence of outputs
+#
+# Check for long sequence of output by parts.
+# MESSAGE: is the test message to be printed with the test success/fail.
+# SENTINEL: Is the terminal pattern indicating that output has finished.
+# LIST: is the sequence of outputs to match.
+# If the sentinel is recognized early, it is considered an error.
+#
+# Returns:
+# 1 if the test failed,
+# 0 if the test passes,
+# -1 if there was an internal error.
+#
+proc gdb_expect_list {test sentinel list} {
+ global gdb_prompt
+ global suppress_flag
+ set index 0
+ set ok 1
+ if { $suppress_flag } {
+ set ok 0
+ }
+ while { ${index} < [llength ${list}] } {
+ set pattern [lindex ${list} ${index}]
+ set index [expr ${index} + 1]
+ if { ${index} == [llength ${list}] } {
+ if { ${ok} } {
+ gdb_expect {
+ -re "${pattern}${sentinel}" {
+ pass "${test}, pattern ${index} + sentinel"
+ }
+ -re "${sentinel}" {
+ fail "${test}, pattern ${index} + sentinel"
+ set ok 0
+ }
+ timeout {
+ fail "${test}, pattern ${index} + sentinel (timeout)"
+ set ok 0
+ }
+ }
+ } else {
+ unresolved "${test}, pattern ${index} + sentinel"
+ }
+ } else {
+ if { ${ok} } {
+ gdb_expect {
+ -re "${pattern}" {
+ pass "${test}, pattern ${index}"
+ }
+ -re "${sentinel}" {
+ fail "${test}, pattern ${index}"
+ set ok 0
+ }
+ timeout {
+ fail "${test}, pattern ${index} (timeout)"
+ set ok 0
+ }
+ }
+ } else {
+ unresolved "${test}, pattern ${index}"
+ }
+ }
+ }
+ if { ${ok} } {
+ return 0
+ } else {
+ return 1
+ }
+}
+
+#
+#
+proc gdb_suppress_entire_file { reason } {
+ global suppress_flag;
+
+ warning "$reason\n";
+ set suppress_flag -1;
+}
+
+#
+# Set suppress_flag, which will cause all subsequent calls to send_gdb and
+# gdb_expect to fail immediately (until the next call to
+# gdb_stop_suppressing_tests).
+#
+proc gdb_suppress_tests { args } {
+ global suppress_flag;
+
+ return; # fnf - disable pending review of results where
+ # testsuite ran better without this
+ incr suppress_flag;
+
+ if { $suppress_flag == 1 } {
+ if { [llength $args] > 0 } {
+ warning "[lindex $args 0]\n";
+ } else {
+ warning "Because of previous failure, all subsequent tests in this group will automatically fail.\n";
+ }
+ }
+}
+
+#
+# Clear suppress_flag.
+#
+proc gdb_stop_suppressing_tests { } {
+ global suppress_flag;
+
+ if [info exists suppress_flag] {
+ if { $suppress_flag > 0 } {
+ set suppress_flag 0;
+ clone_output "Tests restarted.\n";
+ }
+ } else {
+ set suppress_flag 0;
+ }
+}
+
+proc gdb_clear_suppressed { } {
+ global suppress_flag;
+
+ set suppress_flag 0;
+}
+
+proc gdb_start { } {
+ default_gdb_start
+}
+
+proc gdb_exit { } {
+ catch default_gdb_exit
+}
+
+#
+# gdb_load -- load a file into the debugger.
+# return a -1 if anything goes wrong.
+#
+proc gdb_load { arg } {
+ return [gdb_file_cmd $arg]
+}
+
+proc gdb_continue { function } {
+ global decimal
+
+ return [gdb_test "continue" ".*Breakpoint $decimal, $function .*" "continue to $function"];
+}
+
+proc default_gdb_init { args } {
+ global gdb_wrapper_initialized
+
+ gdb_clear_suppressed;
+
+ # Make sure that the wrapper is rebuilt
+ # with the appropriate multilib option.
+ set gdb_wrapper_initialized 0
+
+ # Uh, this is lame. Really, really, really lame. But there's this *one*
+ # testcase that will fail in random places if we don't increase this.
+ match_max -d 20000
+
+ # We want to add the name of the TCL testcase to the PASS/FAIL messages.
+ if { [llength $args] > 0 } {
+ global pf_prefix
+
+ set file [lindex $args 0];
+
+ set pf_prefix "[file tail [file dirname $file]]/[file tail $file]:";
+ }
+ global gdb_prompt;
+ if [target_info exists gdb_prompt] {
+ set gdb_prompt [target_info gdb_prompt];
+ } else {
+ set gdb_prompt "\\(gdb\\)"
+ }
+}
+
+proc gdb_init { args } {
+ return [eval default_gdb_init $args];
+}
+
+proc gdb_finish { } {
+ gdb_exit;
+}
+
+global debug_format
+set debug_format "unknown"
+
+# Run the gdb command "info source" and extract the debugging format
+# information from the output and save it in debug_format.
+
+proc get_debug_format { } {
+ global gdb_prompt
+ global verbose
+ global expect_out
+ global debug_format
+
+ set debug_format "unknown"
+ send_gdb "info source\n"
+ gdb_expect 10 {
+ -re "Compiled with (.*) debugging format.\r\n$gdb_prompt $" {
+ set debug_format $expect_out(1,string)
+ verbose "debug format is $debug_format"
+ return 1;
+ }
+ -re "No current source file.\r\n$gdb_prompt $" {
+ perror "get_debug_format used when no current source file"
+ return 0;
+ }
+ -re "$gdb_prompt $" {
+ warning "couldn't check debug format (no valid response)."
+ return 1;
+ }
+ timeout {
+ warning "couldn't check debug format (timed out)."
+ return 1;
+ }
+ }
+}
+
+# Return true if FORMAT matches the debug format the current test was
+# compiled with. FORMAT is a shell-style globbing pattern; it can use
+# `*', `[...]', and so on.
+#
+# This function depends on variables set by `get_debug_format', above.
+
+proc test_debug_format {format} {
+ global debug_format
+
+ return [expr [string match $format $debug_format] != 0]
+}
+
+# Like setup_xfail, but takes the name of a debug format (DWARF 1,
+# COFF, stabs, etc). If that format matches the format that the
+# current test was compiled with, then the next test is expected to
+# fail for any target. Returns 1 if the next test or set of tests is
+# expected to fail, 0 otherwise (or if it is unknown). Must have
+# previously called get_debug_format.
+proc setup_xfail_format { format } {
+ set ret [test_debug_format $format];
+
+ if {$ret} then {
+ setup_xfail "*-*-*"
+ }
+ return $ret;
+}
+
+proc gdb_step_for_stub { } {
+ global gdb_prompt;
+
+ if ![target_info exists gdb,use_breakpoint_for_stub] {
+ if [target_info exists gdb_stub_step_command] {
+ set command [target_info gdb_stub_step_command];
+ } else {
+ set command "step";
+ }
+ send_gdb "${command}\n";
+ set tries 0;
+ gdb_expect 60 {
+ -re "(main.* at |.*in .*start).*$gdb_prompt" {
+ return;
+ }
+ -re ".*$gdb_prompt" {
+ incr tries;
+ if { $tries == 5 } {
+ fail "stepping out of breakpoint function";
+ return;
+ }
+ send_gdb "${command}\n";
+ exp_continue;
+ }
+ default {
+ fail "stepping out of breakpoint function";
+ return;
+ }
+ }
+ }
+ send_gdb "where\n";
+ gdb_expect {
+ -re "main\[^\r\n\]*at \(\[^:]+\):\(\[0-9\]+\)" {
+ set file $expect_out(1,string);
+ set linenum [expr $expect_out(2,string) + 1];
+ set breakplace "${file}:${linenum}";
+ }
+ default {}
+ }
+ send_gdb "break ${breakplace}\n";
+ gdb_expect 60 {
+ -re "Breakpoint (\[0-9\]+) at.*$gdb_prompt" {
+ set breakpoint $expect_out(1,string);
+ }
+ -re "Breakpoint (\[0-9\]+): file.*$gdb_prompt" {
+ set breakpoint $expect_out(1,string);
+ }
+ default {}
+ }
+ send_gdb "continue\n";
+ gdb_expect 60 {
+ -re "Breakpoint ${breakpoint},.*$gdb_prompt" {
+ gdb_test "delete $breakpoint" ".*" "";
+ return;
+ }
+ default {}
+ }
+}
+
+### gdb_get_line_number TEXT [FILE]
+###
+### Search the source file FILE, and return the line number of a line
+### containing TEXT. Use this function instead of hard-coding line
+### numbers into your test script.
+###
+### Specifically, this function uses GDB's "search" command to search
+### FILE for the first line containing TEXT, and returns its line
+### number. Thus, FILE must be a source file, compiled into the
+### executable you are running. If omitted, FILE defaults to the
+### value of the global variable `srcfile'; most test scripts set
+### `srcfile' appropriately at the top anyway.
+###
+### Use this function to keep your test scripts independent of the
+### exact line numbering of the source file. Don't write:
+###
+### send_gdb "break 20"
+###
+### This means that if anyone ever edits your test's source file,
+### your test could break. Instead, put a comment like this on the
+### source file line you want to break at:
+###
+### /* breakpoint spot: frotz.exp: test name */
+###
+### and then write, in your test script (which we assume is named
+### frotz.exp):
+###
+### send_gdb "break [gdb_get_line_number "frotz.exp: test name"]\n"
+###
+### (Yes, Tcl knows how to handle the nested quotes and brackets.
+### Try this:
+### $ tclsh
+### % puts "foo [lindex "bar baz" 1]"
+### foo baz
+### %
+### Tcl is quite clever, for a little stringy language.)
+
+proc gdb_get_line_number {text {file /omitted/}} {
+ global gdb_prompt;
+ global srcfile;
+
+ if {! [string compare $file /omitted/]} {
+ set file $srcfile
+ }
+
+ set result -1;
+ gdb_test "list ${file}:1,1" ".*" ""
+ send_gdb "search ${text}\n"
+ gdb_expect {
+ -re "\[\r\n\]+(\[0-9\]+)\[ \t\].*${text}.*$gdb_prompt $" {
+ set result $expect_out(1,string)
+ }
+ -re ".*$gdb_prompt $" {
+ fail "find line number containing \"${text}\""
+ }
+ timeout {
+ fail "find line number containing \"${text}\" (timeout)"
+ }
+ }
+ return $result;
+}
+
+# gdb_continue_to_end:
+# The case where the target uses stubs has to be handled specially. If a
+# stub is used, we set a breakpoint at exit because we cannot rely on
+# exit() behavior of a remote target.
+#
+# mssg is the error message that gets printed.
+
+proc gdb_continue_to_end {mssg} {
+ if [target_info exists use_gdb_stub] {
+ if {![gdb_breakpoint "exit"]} {
+ return 0
+ }
+ gdb_test "continue" "Continuing..*Breakpoint .*exit.*" \
+ "continue until exit at $mssg"
+ } else {
+ # Continue until we exit. Should not stop again.
+ # Don't bother to check the output of the program, that may be
+ # extremely tough for some remote systems.
+ gdb_test "continue"\
+ "Continuing.\[\r\n0-9\]+(... EXIT code 0\[\r\n\]+|)Program exited normally\\..*"\
+ "continue until exit at $mssg"
+ }
+}
+
+proc rerun_to_main {} {
+ global gdb_prompt
+
+ if [target_info exists use_gdb_stub] {
+ gdb_run_cmd
+ gdb_expect {
+ -re ".*Breakpoint .*main .*$gdb_prompt $"\
+ {pass "rerun to main" ; return 0}
+ -re "$gdb_prompt $"\
+ {fail "rerun to main" ; return 0}
+ timeout {fail "(timeout) rerun to main" ; return 0}
+ }
+ } else {
+ send_gdb "run\n"
+ gdb_expect {
+ -re "Starting program.*$gdb_prompt $"\
+ {pass "rerun to main" ; return 0}
+ -re "$gdb_prompt $"\
+ {fail "rerun to main" ; return 0}
+ timeout {fail "(timeout) rerun to main" ; return 0}
+ }
+ }
+}
+
+# Print a message and return true if a test should be skipped
+# due to lack of floating point suport.
+
+proc gdb_skip_float_test { msg } {
+ if [target_info exists gdb,skip_float_tests] {
+ verbose "Skipping test '$msg': no float tests.";
+ return 1;
+ }
+ return 0;
+}
+
+# Print a message and return true if a test should be skipped
+# due to lack of stdio support.
+
+proc gdb_skip_stdio_test { msg } {
+ if [target_info exists gdb,noinferiorio] {
+ verbose "Skipping test '$msg': no inferior i/o.";
+ return 1;
+ }
+ return 0;
+}
+
+proc gdb_skip_bogus_test { msg } {
+ return 0;
+}
+
diff --git a/gdb/testsuite/lib/insight-support.exp b/gdb/testsuite/lib/insight-support.exp
new file mode 100644
index 00000000000..42d14a9a27a
--- /dev/null
+++ b/gdb/testsuite/lib/insight-support.exp
@@ -0,0 +1,310 @@
+# GDB Testsuite Support for Insight.
+#
+# Copyright 2001 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License (GPL) 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.
+
+# Initializes the display for gdbtk testing.
+# Returns 1 if tests should run, 0 otherwise.
+proc gdbtk_initialize_display {} {
+ global _using_windows
+
+ # This is hacky, but, we don't have much choice. When running
+ # expect under Windows, tcl_platform(platform) is "unix".
+ if {![info exists _using_windows]} {
+ set _using_windows [expr {![catch {exec cygpath --help}]}]
+ }
+
+ if {![_gdbtk_xvfb_init]} {
+ if {$_using_windows} {
+ untested "No GDB_DISPLAY -- skipping tests"
+ } else {
+ untested "No GDB_DISPLAY or Xvfb -- skipping tests"
+ }
+
+ return 0
+ }
+
+ return 1
+}
+
+# From dejagnu:
+# srcdir = testsuite src dir (e.g., devo/gdb/testsuite)
+# objdir = testsuite obj dir (e.g., gdb/testsuite)
+# subdir = subdir of testsuite (e.g., gdb.gdbtk)
+#
+# To gdbtk:
+# env(DEFS)=the "defs" files (e.g., devo/gdb/testsuite/gdb.gdbtk/defs)
+# env(SRCDIR)=directory containing the test code (e.g., *.test)
+# env(OBJDIR)=directory which contains any executables
+# (e.g., gdb/testsuite/gdb.gdbtk)
+proc gdbtk_start {test} {
+ global verbose
+ global GDB
+ global GDBFLAGS
+ global env srcdir subdir objdir
+
+ gdb_stop_suppressing_tests;
+
+ verbose "Starting $GDB -nx -q --tclcommand=$test"
+
+ set real_test [which $test]
+ if {$real_test == 0} {
+ perror "$test is not found"
+ exit 1
+ }
+
+ if {![is_remote host]} {
+ if { [which $GDB] == 0 } {
+ perror "$GDB does not exist."
+ exit 1
+ }
+ }
+
+ set wd [pwd]
+
+ # Find absolute path to test
+ set test [to_tcl_path -abs $test]
+
+ # Set some environment variables
+ cd $srcdir
+ set abs_srcdir [pwd]
+ set env(DEFS) [to_tcl_path -abs [file join $abs_srcdir $subdir defs]]
+
+ cd $wd
+ cd [file join $objdir $subdir]
+ set env(OBJDIR) [pwd]
+ cd $wd
+
+ # Set info about target into env
+ _gdbtk_export_target_info
+
+ set env(SRCDIR) $abs_srcdir
+ set env(GDBTK_VERBOSE) 1
+ set env(GDBTK_LOGFILE) [to_tcl_path [file join $objdir gdb.log]]
+
+ set err [catch {exec $GDB -nx -q --tclcommand=$test} res]
+ if { $err } {
+ perror "Execing $GDB failed: $res"
+ append res "\nERROR gdb-crash"
+ }
+ return $res
+}
+
+# Start xvfb when using it.
+# The precedence is:
+# 1. If GDB_DISPLAY is set (and not ""), use it
+# 2. If Xvfb exists, use it (not on cygwin)
+# 3. Skip tests
+proc _gdbtk_xvfb_init {} {
+ global env spawn_id _xvfb_spawn_id _using_windows
+
+ if {[info exists env(GDB_DISPLAY)]} {
+ if {$env(GDB_DISPLAY) != ""} {
+ set env(DISPLAY) $env(GDB_DISPLAY)
+ } else {
+ # Suppress tests
+ return 0
+ }
+ } elseif {!$_using_windows && [which Xvfb] != 0} {
+ set screen ":[getpid]"
+ set pid [spawn Xvfb $screen -ac]
+ set _xvfb_spawn_id $spawn_id
+ set env(DISPLAY) localhost$screen
+ } else {
+ # No Xvfb found -- skip test
+ return 0
+ }
+
+ return 1
+}
+
+# Kill xvfb
+proc _gdbtk_xvfb_exit {} {
+ global objdir subdir env _xvfb_spawn_id
+
+ if {[info exists _xvfb_spawn_id]} {
+ exec kill [exp_pid -i $_xvfb_spawn_id]
+ wait -i $_xvfb_spawn_id
+ }
+}
+
+# help proc for setting tcl-style paths from unix-style paths
+# pass "-abs" to make it an absolute path
+proc to_tcl_path {unix_path {arg {}}} {
+ global _using_windows
+
+ if {[string compare $unix_path "-abs"] == 0} {
+ set unix_path $arg
+ set wd [pwd]
+ cd [file dirname $unix_path]
+ set dirname [pwd]
+ set unix_name [file join $dirname [file tail $unix_path]]
+ cd $wd
+ }
+
+ if {$_using_windows} {
+ set unix_path [exec cygpath -aw $unix_path]
+ set unix_path [join [split $unix_path \\] /]
+ }
+
+ return $unix_path
+}
+
+# Set information about the target into the environment
+# variable TARGET_INFO. This array will contain a list
+# of commands that are necessary to run a target.
+#
+# This is mostly devined from how dejagnu works, what
+# procs are defined, and analyzing unix.exp, monitor.exp,
+# and sim.exp.
+#
+# Array elements exported:
+# Index Meaning
+# ----- -------
+# init list of target/board initialization commands
+# target target command for target/board
+# load load command for target/board
+# run run command for target_board
+proc _gdbtk_export_target_info {} {
+ global env
+
+ # Figure out what "target class" the testsuite is using,
+ # i.e., sim, monitor, native
+ if {[string compare [info proc gdb_target_monitor] gdb_target_monitor] == 0} {
+ # Using a monitor/remote target
+ set target monitor
+ } elseif {[string compare [info proc gdb_target_sim] gdb_target_sim] == 0} {
+ # Using a simulator target
+ set target simulator
+ } elseif {[string compare [info proc gdb_target_sid] gdb_target_sid] == 0} {
+ # Using sid
+ set target sid
+ } else {
+ # Assume native
+ set target native
+ }
+
+ # Now setup the array to be exported.
+ set info(init) {}
+ set info(target) {}
+ set info(load) {}
+ set info(run) {}
+
+ switch $target {
+ simulator {
+ set opts "[target_info gdb,target_sim_options]"
+ set info(target) "target sim $opts"
+ set info(load) "load"
+ set info(run) "run"
+ }
+
+ monitor {
+ # Setup options for the connection
+ if {[target_info exists baud]} {
+ lappend info(init) "set remotebaud [target_info baud]"
+ }
+ if {[target_info exists binarydownload]} {
+ lappend info(init) "set remotebinarydownload [target_info binarydownload]"
+ }
+ if {[target_info exists disable_x_packet]} {
+ lappend info(init) "set remote X-packet disable"
+ }
+ if {[target_info exists disable_z_packet]} {
+ lappend info(init) "set remote Z-packet disable"
+ }
+
+ # Get target name and connection info
+ if {[target_info exists gdb_protocol]} {
+ set targetname "[target_info gdb_protocol]"
+ } else {
+ set targetname "not_specified"
+ }
+ if {[target_info exists gdb_serial]} {
+ set serialport "[target_info gdb_serial]"
+ } elseif {[target_info exists netport]} {
+ set serialport "[target_info netport]"
+ } else {
+ set serialport "[target_info serial]"
+ }
+
+ set info(target) "target $targetname $serialport"
+ set info(load) "load"
+ set info(run) "continue"
+ }
+
+ sid {
+ # We must start sid first, since Insight won't have a clue
+ # about how to do this.
+ sid_start
+ set info(target) "target [target_info gdb_protocol] [target_info netport]"
+ set info(load) "load"
+ set info(run) "continue"
+ }
+
+ native {
+ set info(run) "run"
+ }
+ }
+
+ # Export the array to the environment
+ set env(TARGET_INFO) [array get info]
+}
+
+# gdbtk tests call this function to print out the results of the
+# tests. The argument is a proper list of lists of the form:
+# {status name description msg}. All of these things typically
+# come from the testsuite harness.
+proc gdbtk_analyze_results {results} {
+ foreach test $results {
+ set status [lindex $test 0]
+ set name [lindex $test 1]
+ set description [lindex $test 2]
+ set msg [lindex $test 3]
+
+ switch $status {
+ PASS {
+ pass "$description ($name)"
+ }
+
+ FAIL {
+ fail "$description ($name)"
+ }
+
+ ERROR {
+ perror "$name"
+ }
+
+ XFAIL {
+ xfail "$description ($name)"
+ }
+
+ XPASS {
+ xpass "$description ($name)"
+ }
+ }
+ }
+}
+
+proc gdbtk_done {{results {}}} {
+ global _xvfb_spawn_id
+ gdbtk_analyze_results $results
+
+ # Kill off xvfb if using it
+ if {[info exists _xvfb_spawn_id]} {
+ _gdbtk_xvfb_exit
+ }
+
+ # Yich. If we're using sid, we must kill it
+ if {[string compare [info proc gdb_target_sid] gdb_target_sid] == 0} {
+ sid_exit
+ }
+}
diff --git a/gdb/testsuite/lib/java.exp b/gdb/testsuite/lib/java.exp
new file mode 100644
index 00000000000..bcfd27c9ce0
--- /dev/null
+++ b/gdb/testsuite/lib/java.exp
@@ -0,0 +1,105 @@
+# Copyright (C) 1998, 1999 Red Hat, Inc.
+
+load_lib "libgloss.exp"
+
+# GCJ_UNDER_TEST is the compiler under test.
+
+global tmpdir
+
+if ![info exists tmpdir] {
+ set tmpdir "/tmp"
+}
+
+set java_initialized 0
+
+#
+# Build the status wrapper library as needed.
+#
+proc java_init { args } {
+ global wrapper_file;
+ global wrap_compile_flags;
+ global java_initialized
+ global GCJ_UNDER_TEST
+ global TOOL_EXECUTABLE
+ global env
+
+ if { $java_initialized == 1 } { return; }
+
+ if ![info exists GCJ_UNDER_TEST] {
+ if [info exists TOOL_EXECUTABLE] {
+ set GCJ_UNDER_TEST $TOOL_EXECUTABLE;
+ } else {
+ if [info exists env(GCJ)] {
+ set GCJ_UNDER_TEST $env(GCJ)
+ } else {
+ global tool_root_dir
+
+ if ![is_remote host] {
+ set file [lookfor_file $tool_root_dir gcj];
+ if { $file == "" } {
+ set file [lookfor_file $tool_root_dir gcc/gcj];
+ }
+ if { $file != "" } {
+ set CC "$file -B[file dirname $file]/ --specs=$tool_root_dir/$target_alias/libjava/libgcj-test.spec";
+ } else {
+ set CC [transform gcj];
+ }
+ } else {
+ set CC [transform gcj]
+ }
+ set GCJ_UNDER_TEST $CC
+ }
+ }
+ }
+
+ set wrapper_file "";
+ set wrap_compile_flags "";
+ if [target_info exists needs_status_wrapper] {
+ set result [build_wrapper "testglue.o"];
+ if { $result != "" } {
+ set wrapper_file [lindex $result 0];
+ set wrap_compile_flags [lindex $result 1];
+ } else {
+ warning "Status wrapper failed to build."
+ }
+ }
+
+ set java_initialized 1
+}
+
+#
+# Run the test specified by srcfile and resultfile. compile_args and
+# exec_args are options telling this proc how to work.
+#
+proc compile_java_from_source { srcfile binfile compile_args } {
+ global GCJ_UNDER_TEST
+ global runtests
+ global java_initialized
+
+ if { $java_initialized != 1 } { java_init }
+
+ set errname [file rootname [file tail $srcfile]]
+ if {! [runtest_file_p $runtests $errname]} {
+ return
+ }
+
+ set args "compiler=$GCJ_UNDER_TEST"
+ lappend args "additional_flags=--main=[file rootname [file tail $srcfile]]"
+ if { $compile_args != "" } {
+ lappend args "additional_flags=$compile_args"
+ }
+
+ if { $compile_args != "" } {
+ set errname "$errname $compile_args"
+ }
+
+ set x [target_compile $srcfile ${binfile} ${binfile} $args]
+ if { $x != "" } {
+ verbose "target_compile failed: $x" 2
+ return "$errname compilation from source";
+ }
+}
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
new file mode 100644
index 00000000000..44679f0a004
--- /dev/null
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -0,0 +1,788 @@
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was based on a file written by Fred Fish. (fnf@cygnus.com)
+
+# Test setup routines that work with the MI interpreter.
+
+# The variable mi_gdb_prompt is a regexp which matches the gdb mi prompt.
+# Set it if it is not already set.
+global mi_gdb_prompt
+if ![info exists mi_gdb_prompt] then {
+ set mi_gdb_prompt "\[(\]gdb\[)\] \r\n"
+}
+
+set MIFLAGS "-i=mi"
+
+#
+# mi_gdb_exit -- exit the GDB, killing the target program if necessary
+#
+proc mi_gdb_exit {} {
+ catch mi_uncatched_gdb_exit
+}
+
+proc mi_uncatched_gdb_exit {} {
+ global GDB
+ global GDBFLAGS
+ global verbose
+ global gdb_spawn_id;
+ global gdb_prompt
+ global mi_gdb_prompt
+ global MIFLAGS
+
+ gdb_stop_suppressing_tests;
+
+ if { [info procs sid_exit] != "" } {
+ sid_exit
+ }
+
+ if ![info exists gdb_spawn_id] {
+ return;
+ }
+
+ verbose "Quitting $GDB $GDBFLAGS $MIFLAGS"
+
+ if { [is_remote host] && [board_info host exists fileid] } {
+ send_gdb "999-gdb-exit\n";
+ gdb_expect 10 {
+ -re "y or n" {
+ send_gdb "y\n";
+ exp_continue;
+ }
+ -re "Undefined command.*$gdb_prompt $" {
+ send_gdb "quit\n"
+ exp_continue;
+ }
+ -re "DOSEXIT code" { }
+ default { }
+ }
+ }
+
+ if ![is_remote host] {
+ remote_close host;
+ }
+ unset gdb_spawn_id
+}
+
+#
+# start gdb -- start gdb running, default procedure
+#
+# When running over NFS, particularly if running many simultaneous
+# tests on different hosts all using the same server, things can
+# get really slow. Give gdb at least 3 minutes to start up.
+#
+proc mi_gdb_start { } {
+ global verbose
+ global GDB
+ global GDBFLAGS
+ global gdb_prompt
+ global mi_gdb_prompt
+ global timeout
+ global gdb_spawn_id;
+ global MIFLAGS
+
+ gdb_stop_suppressing_tests;
+
+ # Start SID.
+ if { [info procs sid_start] != "" } {
+ verbose "Spawning SID"
+ sid_start
+ }
+
+ verbose "Spawning $GDB -nw $GDBFLAGS $MIFLAGS"
+
+ if [info exists gdb_spawn_id] {
+ return 0;
+ }
+
+ if ![is_remote host] {
+ if { [which $GDB] == 0 } then {
+ perror "$GDB does not exist."
+ exit 1
+ }
+ }
+ set res [remote_spawn host "$GDB -nw $GDBFLAGS $MIFLAGS [host_info gdb_opts]"];
+ if { $res < 0 || $res == "" } {
+ perror "Spawning $GDB failed."
+ return 1;
+ }
+ gdb_expect {
+ -re ".*$mi_gdb_prompt$" {
+ verbose "GDB initialized."
+ }
+ -re ".*$gdb_prompt $" {
+ untested "Skip mi tests (got non-mi prompt)."
+ remote_close host;
+ return -1;
+ }
+ -re ".*unrecognized option.*for a complete list of options." {
+ untested "Skip mi tests (not compiled with mi support)."
+ remote_close host;
+ return -1;
+ }
+ -re ".*Interpreter `mi' unrecognized." {
+ untested "Skip mi tests (not compiled with mi support)."
+ remote_close host;
+ return -1;
+ }
+ timeout {
+ perror "(timeout) GDB never initialized after 10 seconds."
+ remote_close host;
+ return -1
+ }
+ }
+ set gdb_spawn_id -1;
+
+ # FIXME: mi output does not go through pagers, so these can be removed.
+ # force the height to "unlimited", so no pagers get used
+ send_gdb "100-gdb-set height 0\n"
+ gdb_expect 10 {
+ -re ".*100-gdb-set height 0\r\n100\\\^done\r\n$mi_gdb_prompt$" {
+ verbose "Setting height to 0." 2
+ }
+ timeout {
+ warning "Couldn't set the height to 0"
+ }
+ }
+ # force the width to "unlimited", so no wraparound occurs
+ send_gdb "101-gdb-set width 0\n"
+ gdb_expect 10 {
+ -re ".*101-gdb-set width 0\r\n101\\\^done\r\n$mi_gdb_prompt$" {
+ verbose "Setting width to 0." 2
+ }
+ timeout {
+ warning "Couldn't set the width to 0."
+ }
+ }
+
+ return 0;
+}
+
+# Many of the tests depend on setting breakpoints at various places and
+# running until that breakpoint is reached. At times, we want to start
+# with a clean-slate with respect to breakpoints, so this utility proc
+# lets us do this without duplicating this code everywhere.
+#
+
+proc mi_delete_breakpoints {} {
+ global mi_gdb_prompt
+
+# FIXME: The mi operation won't accept a prompt back and will use the 'all' arg
+ send_gdb "102-break-delete\n"
+ gdb_expect 30 {
+ -re "Delete all breakpoints.*y or n.*$" {
+ send_gdb "y\n";
+ exp_continue
+ }
+ -re ".*102-break-delete\r\n102\\\^done\r\n$mi_gdb_prompt$" {
+ # This happens if there were no breakpoints
+ }
+ timeout { perror "Delete all breakpoints in delete_breakpoints (timeout)" ; return }
+ }
+
+# The correct output is not "No breakpoints or watchpoints." but an
+# empty BreakpointTable. Also, a query is not acceptable with mi.
+ send_gdb "103-break-list\n"
+ gdb_expect 30 {
+ -re "103-break-list\r\n103\\\^done,BreakpointTable=\{\}\r\n$mi_gdb_prompt$" {}
+ -re "103-break-list\r\n103\\\^done,BreakpointTable=\{nr_rows=\".\",nr_cols=\".\",hdr=\\\[\{width=\".*\",alignment=\".*\",col_name=\"number\",colhdr=\"Num\"\}.*colhdr=\"Type\".*colhdr=\"Disp\".*colhdr=\"Enb\".*colhdr=\"Address\".*colhdr=\"What\".*\\\],body=\\\[\\\]\}" {}
+ -re "103-break-list\r\n103\\\^doneNo breakpoints or watchpoints.\r\n\r\n$mi_gdb_prompt$" {warning "Unexpected console text received"}
+ -re "$mi_gdb_prompt$" { perror "Breakpoints not deleted" ; return }
+ -re "Delete all breakpoints.*or n.*$" {
+ warning "Unexpected prompt for breakpoints deletion";
+ send_gdb "y\n";
+ exp_continue
+ }
+ timeout { perror "-break-list (timeout)" ; return }
+ }
+}
+
+proc mi_gdb_reinitialize_dir { subdir } {
+ global mi_gdb_prompt
+
+ global suppress_flag
+ if { $suppress_flag } {
+ return
+ }
+
+ if [is_remote host] {
+ return "";
+ }
+
+ send_gdb "104-environment-directory\n"
+ gdb_expect 60 {
+ -re ".*Reinitialize source path to empty.*y or n. " {
+ warning "Got confirmation prompt for dir reinitialization."
+ send_gdb "y\n"
+ gdb_expect 60 {
+ -re "$mi_gdb_prompt$" {}
+ timeout {error "Dir reinitialization failed (timeout)"}
+ }
+ }
+ -re "$mi_gdb_prompt$" {}
+ timeout {error "Dir reinitialization failed (timeout)"}
+ }
+
+ send_gdb "105-environment-directory $subdir\n"
+ gdb_expect 60 {
+ -re "Source directories searched.*$mi_gdb_prompt$" {
+ verbose "Dir set to $subdir"
+ }
+ -re "105\\\^done\r\n$mi_gdb_prompt$" {
+ # FIXME: We return just the prompt for now.
+ verbose "Dir set to $subdir"
+ # perror "Dir \"$subdir\" failed."
+ }
+ }
+}
+
+#
+# load a file into the debugger.
+# return a -1 if anything goes wrong.
+#
+proc mi_gdb_load { arg } {
+ global verbose
+ global loadpath
+ global loadfile
+ global GDB
+ global mi_gdb_prompt
+ upvar timeout timeout
+
+ # ``gdb_unload''
+
+ # ``gdb_file_cmd''
+# FIXME: Several of these patterns are only acceptable for console
+# output. Queries are an error for mi.
+ send_gdb "105-file-exec-and-symbols $arg\n"
+ gdb_expect 120 {
+ -re "Reading symbols from.*done.*$mi_gdb_prompt$" {
+ verbose "\t\tLoaded $arg into the $GDB"
+ # All OK
+ }
+ -re "has no symbol-table.*$mi_gdb_prompt$" {
+ perror "$arg wasn't compiled with \"-g\""
+ return -1
+ }
+ -re "A program is being debugged already.*Kill it.*y or n. $" {
+ send_gdb "y\n"
+ verbose "\t\tKilling previous program being debugged"
+ exp_continue
+ }
+ -re "Load new symbol table from \".*\".*y or n. $" {
+ send_gdb "y\n"
+ gdb_expect 120 {
+ -re "Reading symbols from.*done.*$mi_gdb_prompt$" {
+ verbose "\t\tLoaded $arg with new symbol table into $GDB"
+ # All OK
+ }
+ timeout {
+ perror "(timeout) Couldn't load $arg, other program already loaded."
+ return -1
+ }
+ }
+ }
+ -re "No such file or directory.*$mi_gdb_prompt$" {
+ perror "($arg) No such file or directory\n"
+ return -1
+ }
+ -re "105-file-exec-and-symbols .*\r\n105\\\^done\r\n$mi_gdb_prompt$" {
+ # We are just giving the prompt back for now
+ # All OK
+ }
+ timeout {
+ perror "couldn't load $arg into $GDB (timed out)."
+ return -1
+ }
+ eof {
+ # This is an attempt to detect a core dump, but seems not to
+ # work. Perhaps we need to match .* followed by eof, in which
+ # gdb_expect does not seem to have a way to do that.
+ perror "couldn't load $arg into $GDB (end of file)."
+ return -1
+ }
+ }
+
+ # ``load''
+ if { [info procs send_target_sid] != "" } {
+ # For SID, things get complex
+ send_target_sid
+ gdb_expect 60 {
+ -re "\\^done,.*$mi_gdb_prompt$" {
+ }
+ timeout {
+ perror "Unable to connect to SID target"
+ return -1
+ }
+ }
+ send_gdb "48-target-download\n"
+ gdb_expect 10 {
+ -re "48\\^done.*$mi_gdb_prompt$" {
+ }
+ timeout {
+ perror "Unable to download to SID target"
+ return -1
+ }
+ }
+ } elseif { [target_info protocol] == "sim" } {
+ # For the simulator, just connect to it directly.
+ send_gdb "47-target-select sim\n"
+ gdb_expect 10 {
+ -re "47\\^connected.*$mi_gdb_prompt$" {
+ }
+ timeout {
+ perror "Unable to select sim target"
+ return -1
+ }
+ }
+ send_gdb "48-target-download\n"
+ gdb_expect 10 {
+ -re "48\\^done.*$mi_gdb_prompt$" {
+ }
+ timeout {
+ perror "Unable to download to sim target"
+ return -1
+ }
+ }
+ }
+ return 0
+}
+
+# mi_gdb_test COMMAND PATTERN MESSAGE -- send a command to gdb; test the result.
+#
+# COMMAND is the command to execute, send to GDB with send_gdb. If
+# this is the null string no command is sent.
+# PATTERN is the pattern to match for a PASS, and must NOT include
+# the \r\n sequence immediately before the gdb prompt.
+# MESSAGE is an optional message to be printed. If this is
+# omitted, then the pass/fail messages use the command string as the
+# message. (If this is the empty string, then sometimes we don't
+# call pass or fail at all; I don't understand this at all.)
+#
+# Returns:
+# 1 if the test failed,
+# 0 if the test passes,
+# -1 if there was an internal error.
+#
+proc mi_gdb_test { args } {
+ global verbose
+ global mi_gdb_prompt
+ global GDB
+ upvar timeout timeout
+
+ if [llength $args]>2 then {
+ set message [lindex $args 2]
+ } else {
+ set message [lindex $args 0]
+ }
+ set command [lindex $args 0]
+ set pattern [lindex $args 1]
+
+ if [llength $args]==5 {
+ set question_string [lindex $args 3];
+ set response_string [lindex $args 4];
+ } else {
+ set question_string "^FOOBAR$"
+ }
+
+ if $verbose>2 then {
+ send_user "Sending \"$command\" to gdb\n"
+ send_user "Looking to match \"$pattern\"\n"
+ send_user "Message is \"$message\"\n"
+ }
+
+ set result -1
+ set string "${command}\n";
+ if { $command != "" } {
+ while { "$string" != "" } {
+ set foo [string first "\n" "$string"];
+ set len [string length "$string"];
+ if { $foo < [expr $len - 1] } {
+ set str [string range "$string" 0 $foo];
+ if { [send_gdb "$str"] != "" } {
+ global suppress_flag;
+
+ if { ! $suppress_flag } {
+ perror "Couldn't send $command to GDB.";
+ }
+ fail "$message";
+ return $result;
+ }
+ gdb_expect 2 {
+ -re "\[\r\n\]" { }
+ timeout { }
+ }
+ set string [string range "$string" [expr $foo + 1] end];
+ } else {
+ break;
+ }
+ }
+ if { "$string" != "" } {
+ if { [send_gdb "$string"] != "" } {
+ global suppress_flag;
+
+ if { ! $suppress_flag } {
+ perror "Couldn't send $command to GDB.";
+ }
+ fail "$message";
+ return $result;
+ }
+ }
+ }
+
+ if [info exists timeout] {
+ set tmt $timeout;
+ } else {
+ global timeout;
+ if [info exists timeout] {
+ set tmt $timeout;
+ } else {
+ set tmt 60;
+ }
+ }
+ gdb_expect $tmt {
+ -re "\\*\\*\\* DOSEXIT code.*" {
+ if { $message != "" } {
+ fail "$message";
+ }
+ gdb_suppress_entire_file "GDB died";
+ return -1;
+ }
+ -re "Ending remote debugging.*$mi_gdb_prompt\[ \]*$" {
+ if ![isnative] then {
+ warning "Can`t communicate to remote target."
+ }
+ gdb_exit
+ gdb_start
+ set result -1
+ }
+ -re "(${question_string})$" {
+ send_gdb "$response_string\n";
+ exp_continue;
+ }
+ -re "Undefined.* command:.*$mi_gdb_prompt\[ \]*$" {
+ perror "Undefined command \"$command\"."
+ fail "$message"
+ set result 1
+ }
+ -re "Ambiguous command.*$mi_gdb_prompt\[ \]*$" {
+ perror "\"$command\" is not a unique command name."
+ fail "$message"
+ set result 1
+ }
+ -re "\[\r\n\]*($pattern)\[\r\n\]+$mi_gdb_prompt\[ \]*$" {
+ if ![string match "" $message] then {
+ pass "$message"
+ }
+ set result 0
+ }
+ -re "Program exited with code \[0-9\]+.*$mi_gdb_prompt\[ \]*$" {
+ if ![string match "" $message] then {
+ set errmsg "$message: the program exited"
+ } else {
+ set errmsg "$command: the program exited"
+ }
+ fail "$errmsg"
+ return -1
+ }
+ -re "The program is not being run.*$mi_gdb_prompt\[ \]*$" {
+ if ![string match "" $message] then {
+ set errmsg "$message: the program is no longer running"
+ } else {
+ set errmsg "$command: the program is no longer running"
+ }
+ fail "$errmsg"
+ return -1
+ }
+ -re ".*$mi_gdb_prompt\[ \]*$" {
+ if ![string match "" $message] then {
+ fail "$message"
+ }
+ set result 1
+ }
+ "<return>" {
+ send_gdb "\n"
+ perror "Window too small."
+ fail "$message"
+ }
+ -re "\\(y or n\\) " {
+ send_gdb "n\n"
+ perror "Got interactive prompt."
+ fail "$message"
+ }
+ eof {
+ perror "Process no longer exists"
+ if { $message != "" } {
+ fail "$message"
+ }
+ return -1
+ }
+ full_buffer {
+ perror "internal buffer is full."
+ fail "$message"
+ }
+ timeout {
+ if ![string match "" $message] then {
+ fail "$message (timeout)"
+ }
+ set result 1
+ }
+ }
+ return $result
+}
+
+#
+# MI run command. (A modified version of gdb_run_cmd)
+#
+
+# In patterns, the newline sequence ``\r\n'' is matched explicitly as
+# ``.*$'' could swallow up output that we attempt to match elsewhere.
+
+proc mi_run_cmd {args} {
+ global suppress_flag
+ if { $suppress_flag } {
+ return -1
+ }
+ global mi_gdb_prompt
+
+ if [target_info exists gdb_init_command] {
+ send_gdb "[target_info gdb_init_command]\n";
+ gdb_expect 30 {
+ -re "$mi_gdb_prompt$" { }
+ default {
+ perror "gdb_init_command for target failed";
+ return;
+ }
+ }
+ }
+
+ if [target_info exists use_gdb_stub] {
+ if [target_info exists gdb,do_reload_on_run] {
+ # Specifying no file, defaults to the executable
+ # currently being debugged.
+ if { [mi_gdb_load ""] < 0 } {
+ return;
+ }
+ send_gdb "000-exec-continue\n";
+ gdb_expect 60 {
+ -re "Continu\[^\r\n\]*\[\r\n\]" {}
+ default {}
+ }
+ return;
+ }
+
+ if [target_info exists gdb,start_symbol] {
+ set start [target_info gdb,start_symbol];
+ } else {
+ set start "start";
+ }
+
+ # HACK: Should either use 000-jump or fix the target code
+ # to better handle RUN.
+ send_gdb "jump *$start\n"
+ warning "Using CLI jump command, expect run-to-main FAIL"
+ return
+ }
+
+ send_gdb "000-exec-run $args\n"
+ gdb_expect {
+ -re "000\\^running\r\n${mi_gdb_prompt}" {
+ }
+ timeout {
+ perror "Unable to start target"
+ return
+ }
+ }
+ # NOTE: Shortly after this there will be a ``000*stopping,...(gdb)''
+}
+
+#
+# Just like run-to-main but works with the MI interface
+#
+
+proc mi_run_to_main { } {
+ global suppress_flag
+ if { $suppress_flag } {
+ return -1
+ }
+
+ global mi_gdb_prompt
+ global hex
+ global decimal
+ global srcdir
+ global subdir
+ global binfile
+ global srcfile
+
+ set test "mi run-to-main"
+ mi_delete_breakpoints
+ mi_gdb_reinitialize_dir $srcdir/$subdir
+ mi_gdb_load ${binfile}
+
+ mi_gdb_test "200-break-insert main" \
+ "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*\",line=\"\[0-9\]*\",times=\"0\"\}" \
+ "breakpoint at main"
+
+ mi_run_cmd
+ gdb_expect {
+ -re "000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\"main\",args=\(\\\[\\\]\|\{\}\),file=\".*\",line=\"\[0-9\]*\"\}\r\n$mi_gdb_prompt$" {
+ pass "$test"
+ return 0
+ }
+ -re ".*$mi_gdb_prompt$" {
+ fail "$test (2)"
+ }
+ timeout {
+ fail "$test (timeout)"
+ return -1
+ }
+ }
+}
+
+
+# Next to the next statement
+
+proc mi_next { test } {
+ global suppress_flag
+ if { $suppress_flag } {
+ return -1
+ }
+ global mi_gdb_prompt
+ send_gdb "220-exec-next\n"
+ gdb_expect {
+ -re "220\\^running\r\n${mi_gdb_prompt}220\\*stopped,reason=\"end-stepping-range\",thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\".*\",args=\[\\\[\{].*[\\\]\}\],file=\".*\",line=\"\[0-9\]*\"\}\r\n$mi_gdb_prompt$" {
+ pass "$test"
+ return 0
+ }
+ timeout {
+ fail "$test"
+ return -1
+ }
+ }
+}
+
+
+# Step to the next statement
+
+proc mi_step { test } {
+ global suppress_flag
+ if { $suppress_flag } {
+ return -1
+ }
+ global mi_gdb_prompt
+ send_gdb "220-exec-step\n"
+ gdb_expect {
+ -re "220\\^running\r\n${mi_gdb_prompt}220\\*stopped,reason=\"end-stepping-range\",thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\".*\",args=\[\\\[\{\].*\[\\\]\}\],file=\".*\",line=\"\[0-9\]*\"\}\r\n$mi_gdb_prompt$" {
+ pass "$test"
+ return 0
+ }
+ timeout {
+ fail "$test"
+ return -1
+ }
+ }
+}
+
+# cmd should not include the number or newline (i.e. "exec-step 3", not
+# "220-exec-step 3\n"
+
+# Can not match -re ".*\r\n${mi_gdb_prompt}", because of false positives
+# after the first prompt is printed.
+
+proc mi_run_to_helper { cmd reason func args file line extra test } {
+ global suppress_flag
+ if { $suppress_flag } {
+ return -1
+ }
+ global mi_gdb_prompt
+ global hex
+ global decimal
+ send_gdb "220-$cmd\n"
+ gdb_expect {
+ -re "220\\^running\r\n${mi_gdb_prompt}220\\*stopped,reason=\"$reason\",thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\".*$file\",line=\"$line\"\}$extra\r\n$mi_gdb_prompt$" {
+ pass "$test"
+ return 0
+ }
+ -re "220\\^running\r\n${mi_gdb_prompt}220\\*stopped,reason=\"$reason\",thread-id=\"$decimal\",frame=\{addr=\"$hex\",func=\".*\",args=\[\\\[\{\].*\[\\\]\}\],file=\".*\",line=\"\[0-9\]*\"\}.*\r\n$mi_gdb_prompt$" {
+ fail "$test (stopped at wrong place)"
+ return -1
+ }
+ -re "220\\^running\r\n${mi_gdb_prompt}.*\r\n${mi_gdb_prompt}$" {
+ fail "$test (unknown output after running)"
+ return -1
+ }
+ timeout {
+ fail "$test (timeout)"
+ return -1
+ }
+ }
+}
+
+proc mi_run_to { cmd reason func args file line extra test } {
+ mi_run_to_helper "$cmd" "$reason" "$func" "\\\[$args\\\]" \
+ "$file" "$line" "$extra" "$test"
+}
+
+proc mi_next_to { func args file line test } {
+ mi_run_to "exec-next" "end-stepping-range" "$func" "$args" \
+ "$file" "$line" "" "$test"
+}
+
+proc mi_step_to { func args file line test } {
+ mi_run_to "exec-step" "end-stepping-range" "$func" "$args" \
+ "$file" "$line" "" "$test"
+}
+
+proc mi_finish_to { func args file line result ret test } {
+ mi_run_to "exec-finish" "function-finished" "$func" "$args" \
+ "$file" "$line" \
+ ",gdb-result-var=\"$result\",return-value=\"$ret\"" \
+ "$test"
+}
+
+proc mi_continue_to { bkptno func args file line test } {
+ mi_run_to "exec-continue" "breakpoint-hit\",bkptno=\"$bkptno" \
+ "$func" "$args" "$file" "$line" "" "$test"
+}
+
+proc mi0_run_to { cmd reason func args file line extra test } {
+ mi_run_to_helper "$cmd" "$reason" "$func" "\{$args\}" \
+ "$file" "$line" "$extra" "$test"
+}
+
+proc mi0_next_to { func args file line test } {
+ mi0_run_to "exec-next" "end-stepping-range" "$func" "$args" \
+ "$file" "$line" "" "$test"
+}
+
+proc mi0_step_to { func args file line test } {
+ mi0_run_to "exec-step" "end-stepping-range" "$func" "$args" \
+ "$file" "$line" "" "$test"
+}
+
+proc mi0_finish_to { func args file line result ret test } {
+ mi0_run_to "exec-finish" "function-finished" "$func" "$args" \
+ "$file" "$line" \
+ ",gdb-result-var=\"$result\",return-value=\"$ret\"" \
+ "$test"
+}
+
+proc mi0_continue_to { bkptno func args file line test } {
+ mi0_run_to "exec-continue" "breakpoint-hit\",bkptno=\"$bkptno" \
+ "$func" "$args" "$file" "$line" "" "$test"
+}
diff --git a/gdb/testsuite/lib/trace-support.exp b/gdb/testsuite/lib/trace-support.exp
new file mode 100644
index 00000000000..4765791b817
--- /dev/null
+++ b/gdb/testsuite/lib/trace-support.exp
@@ -0,0 +1,307 @@
+# Copyright (C) 1998 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+
+#
+# Support procedures for trace testing
+#
+
+
+#
+# Procedure: gdb_target_supports_trace
+# Returns true if GDB is connected to a target that supports tracing.
+# Allows tests to abort early if not running on a trace-aware target.
+#
+
+proc gdb_target_supports_trace { } {
+ global gdb_prompt
+
+ send_gdb "tstatus\n"
+ gdb_expect {
+ -re "\[Tt\]race can only be run on.*$gdb_prompt $" {
+ return 0
+ }
+ -re "\[Tt\]race can not be run on.*$gdb_prompt $" {
+ return 0
+ }
+ -re "\[Tt\]arget does not support.*$gdb_prompt $" {
+ return 0
+ }
+ -re ".*\[Ee\]rror.*$gdb_prompt $" {
+ return 0
+ }
+ -re ".*\[Ww\]arning.*$gdb_prompt $" {
+ return 0
+ }
+ -re ".*$gdb_prompt $" {
+ return 1
+ }
+ timeout {
+ return 0
+ }
+ }
+}
+
+
+#
+# Procedure: gdb_delete_tracepoints
+# Many of the tests depend on setting tracepoints at various places and
+# running until that tracepoint is reached. At times, we want to start
+# with a clean slate with respect to tracepoints, so this utility proc
+# lets us do this without duplicating this code everywhere.
+#
+
+proc gdb_delete_tracepoints {} {
+ global gdb_prompt
+
+ send_gdb "delete tracepoints\n"
+ gdb_expect 30 {
+ -re "Delete all tracepoints.*y or n.*$" {
+ send_gdb "y\n";
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" { # This happens if there were no tracepoints }
+ timeout {
+ perror "Delete all tracepoints in delete_tracepoints (timeout)"
+ return
+ }
+ }
+ send_gdb "info tracepoints\n"
+ gdb_expect 30 {
+ -re "No tracepoints.*$gdb_prompt $" {}
+ -re "$gdb_prompt $" { perror "tracepoints not deleted" ; return }
+ timeout { perror "info tracepoints (timeout)" ; return }
+ }
+}
+
+#
+# Procedure: gdb_trace_setactions
+# Define actions for a tracepoint.
+# Arguments:
+# testname -- identifying string for pass/fail output
+# tracepoint -- to which tracepoint do these actions apply? (optional)
+# args -- list of actions to be defined.
+# Returns:
+# zero -- success
+# non-zero -- failure
+
+proc gdb_trace_setactions { testname tracepoint args } {
+ global gdb_prompt;
+
+ set state 0;
+ set passfail "pass";
+ send_gdb "actions $tracepoint\n";
+ set expected_result "";
+ gdb_expect 5 {
+ -re "No tracepoint number .*$gdb_prompt $" {
+ fail $testname
+ return 1;
+ }
+ -re "Enter actions for tracepoint $tracepoint.*>" {
+ if { [llength $args] > 0 } {
+ set lastcommand "[lindex $args $state]";
+ send_gdb "[lindex $args $state]\n";
+ incr state;
+ set expected_result [lindex $args $state];
+ incr state;
+ } else {
+ send_gdb "end\n";
+ }
+ exp_continue;
+ }
+ -re "\(.*\)\[\r\n\]+\[ \t]*> $" {
+ if { $expected_result != "" } {
+ regsub "^\[^\r\n\]+\[\r\n\]+" "$expect_out(1,string)" "" out;
+ if ![regexp $expected_result $out] {
+ set passfail "fail";
+ }
+ set expected_result "";
+ }
+ if { $state < [llength $args] } {
+ send_gdb "[lindex $args $state]\n";
+ incr state;
+ set expected_result [lindex $args $state];
+ incr state;
+ } else {
+ send_gdb "end\n";
+ set expected_result "";
+ }
+ exp_continue;
+ }
+ -re "\(.*\)$gdb_prompt $" {
+ if { $expected_result != "" } {
+ if ![regexp $expected_result $expect_out(1,string)] {
+ set passfail "fail";
+ }
+ set expected_result "";
+ }
+ if { [llength $args] < $state } {
+ set passfail "fail";
+ }
+ }
+ default {
+ set passfail "fail";
+ }
+ }
+ if { $testname != "" } {
+ $passfail $testname;
+ }
+ if { $passfail == "pass" } then {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+#
+# Procedure: gdb_tfind_test
+# Find a specified trace frame.
+# Arguments:
+# testname -- identifying string for pass/fail output
+# tfind_arg -- frame (line, PC, etc.) identifier
+# exp_res -- Expected result of frame test
+# args -- Test expression
+# Returns:
+# zero -- success
+# non-zero -- failure
+#
+
+proc gdb_tfind_test { testname tfind_arg exp_res args } {
+ global gdb_prompt;
+
+ if { "$args" != "" } {
+ set expr "$exp_res";
+ set exp_res "$args";
+ } else {
+ set expr "(int) \$trace_frame";
+ }
+ set passfail "fail";
+
+ gdb_test "tfind $tfind_arg" "" ""
+ send_gdb "printf \"x \%d x\\n\", $expr\n";
+ gdb_expect 10 {
+ -re "x (-*\[0-9\]+) x" {
+ if { $expect_out(1,string) == $exp_res } {
+ set passfail "pass";
+ }
+ exp_continue;
+ }
+ -re "$gdb_prompt $" { }
+ }
+ $passfail "$testname";
+ if { $passfail == "pass" } then {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+#
+# Procedure: gdb_readexpr
+# Arguments:
+# gdb_expr -- the expression whose value is desired
+# Returns:
+# the value of gdb_expr, as evaluated by gdb.
+# [FIXME: returns -1 on error, which is sometimes a legit value]
+#
+
+proc gdb_readexpr { gdb_expr } {
+ global gdb_prompt;
+
+ set result -1;
+ send_gdb "print $gdb_expr\n"
+ gdb_expect 5 {
+ -re "\[$\].*= (\[0-9\]+).*$gdb_prompt $" {
+ set result $expect_out(1,string);
+ }
+ -re "$gdb_prompt $" { }
+ default { }
+ }
+ return $result;
+}
+
+#
+# Procedure: gdb_gettpnum
+# Arguments:
+# tracepoint (optional): if supplied, set a tracepoint here.
+# Returns:
+# the tracepoint ID of the most recently set tracepoint.
+#
+
+proc gdb_gettpnum { tracepoint } {
+ global gdb_prompt;
+
+ if { $tracepoint != "" } {
+ gdb_test "trace $tracepoint" "" ""
+ }
+ return [gdb_readexpr "\$tpnum"];
+}
+
+
+#
+# Procedure: gdb_find_function_baseline
+# Arguments:
+# func_name -- name of source function
+# Returns:
+# Sourcefile line of function definition (open curly brace),
+# or -1 on failure. Caller must check return value.
+# Note:
+# Works only for open curly brace at beginning of source line!
+#
+
+proc gdb_find_function_baseline { func_name } {
+ global gdb_prompt;
+
+ set baseline -1;
+
+ send_gdb "list $func_name\n"
+# gdb_expect {
+# -re "\[\r\n\]\[\{\].*$gdb_prompt $" {
+# set baseline 1
+# }
+# }
+}
+
+#
+# Procedure: gdb_find_function_baseline
+# Arguments:
+# filename: name of source file of desired function.
+# Returns:
+# Sourcefile line of function definition (open curly brace),
+# or -1 on failure. Caller must check return value.
+# Note:
+# Works only for open curly brace at beginning of source line!
+#
+
+proc gdb_find_recursion_test_baseline { filename } {
+ global gdb_prompt;
+
+ set baseline -1;
+
+ gdb_test "list $filename:1" "" ""
+ send_gdb "search gdb_recursion_test line 0\n"
+ gdb_expect {
+ -re "(\[0-9\]+)\[\t \]+\{.*line 0.*$gdb_prompt $" {
+ set baseline $expect_out(1,string);
+ }
+ -re "$gdb_prompt $" { }
+ default { }
+ }
+ return $baseline;
+}
diff --git a/gdb/thread-db.c b/gdb/thread-db.c
new file mode 100644
index 00000000000..d38db74b4b1
--- /dev/null
+++ b/gdb/thread-db.c
@@ -0,0 +1,1044 @@
+/* libthread_db assisted debugging support, generic parts.
+ Copyright 1999, 2000, 2001 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 "defs.h"
+
+#include "gdb_assert.h"
+#include <dlfcn.h>
+#include "gdb_proc_service.h"
+#include "gdb_thread_db.h"
+
+#include "bfd.h"
+#include "gdbthread.h"
+#include "inferior.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "target.h"
+#include "regcache.h"
+
+#ifndef LIBTHREAD_DB_SO
+#define LIBTHREAD_DB_SO "libthread_db.so.1"
+#endif
+
+/* If we're running on GNU/Linux, we must explicitly attach to any new
+ threads. */
+
+/* FIXME: There is certainly some room for improvements:
+ - Cache LWP ids.
+ - Bypass libthread_db when fetching or storing registers for
+ threads bound to a LWP. */
+
+/* This module's target vector. */
+static struct target_ops thread_db_ops;
+
+/* The target vector that we call for things this module can't handle. */
+static struct target_ops *target_beneath;
+
+/* Pointer to the next function on the objfile event chain. */
+static void (*target_new_objfile_chain) (struct objfile *objfile);
+
+/* Non-zero if we're using this module's target vector. */
+static int using_thread_db;
+
+/* Non-zero if we have to keep this module's target vector active
+ across re-runs. */
+static int keep_thread_db;
+
+/* Non-zero if we have determined the signals used by the threads
+ library. */
+static int thread_signals;
+static sigset_t thread_stop_set;
+static sigset_t thread_print_set;
+
+/* Structure that identifies the child process for the
+ <proc_service.h> interface. */
+static struct ps_prochandle proc_handle;
+
+/* Connection to the libthread_db library. */
+static td_thragent_t *thread_agent;
+
+/* Pointers to the libthread_db functions. */
+
+static td_err_e (*td_init_p) (void);
+
+static td_err_e (*td_ta_new_p) (struct ps_prochandle *ps, td_thragent_t **ta);
+static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
+ td_thrhandle_t *__th);
+static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta, lwpid_t lwpid,
+ td_thrhandle_t *th);
+static td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
+ td_thr_iter_f *callback,
+ void *cbdata_p, td_thr_state_e state,
+ int ti_pri, sigset_t *ti_sigmask_p,
+ unsigned int ti_user_flags);
+static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
+ td_event_e event, td_notify_t *ptr);
+static td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
+ td_thr_events_t *event);
+static td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
+ td_event_msg_t *msg);
+
+static td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
+static td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
+ td_thrinfo_t *infop);
+static td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
+ gdb_prfpregset_t *regset);
+static td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
+ prgregset_t gregs);
+static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
+ const gdb_prfpregset_t *fpregs);
+static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
+ prgregset_t gregs);
+static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, int event);
+
+/* Location of the thread creation event breakpoint. The code at this
+ location in the child process will be called by the pthread library
+ whenever a new thread is created. By setting a special breakpoint
+ at this location, GDB can detect when a new thread is created. We
+ obtain this location via the td_ta_event_addr call. */
+static CORE_ADDR td_create_bp_addr;
+
+/* Location of the thread death event breakpoint. */
+static CORE_ADDR td_death_bp_addr;
+
+/* Prototypes for local functions. */
+static void thread_db_find_new_threads (void);
+
+
+/* Building process ids. */
+
+#define GET_PID(ptid) ptid_get_pid (ptid)
+#define GET_LWP(ptid) ptid_get_lwp (ptid)
+#define GET_THREAD(ptid) ptid_get_tid (ptid)
+
+#define is_lwp(ptid) (GET_LWP (ptid) != 0)
+#define is_thread(ptid) (GET_THREAD (ptid) != 0)
+
+#define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
+#define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid)
+
+
+struct private_thread_info
+{
+ /* Cached LWP id. Must come first, see lin-lwp.c. */
+ lwpid_t lwpid;
+};
+
+
+static char *
+thread_db_err_str (td_err_e err)
+{
+ static char buf[64];
+
+ switch (err)
+ {
+ case TD_OK:
+ return "generic 'call succeeded'";
+ case TD_ERR:
+ return "generic error";
+ case TD_NOTHR:
+ return "no thread to satisfy query";
+ case TD_NOSV:
+ return "no sync handle to satisfy query";
+ case TD_NOLWP:
+ return "no LWP to satisfy query";
+ case TD_BADPH:
+ return "invalid process handle";
+ case TD_BADTH:
+ return "invalid thread handle";
+ case TD_BADSH:
+ return "invalid synchronization handle";
+ case TD_BADTA:
+ return "invalid thread agent";
+ case TD_BADKEY:
+ return "invalid key";
+ case TD_NOMSG:
+ return "no event message for getmsg";
+ case TD_NOFPREGS:
+ return "FPU register set not available";
+ case TD_NOLIBTHREAD:
+ return "application not linked with libthread";
+ case TD_NOEVENT:
+ return "requested event is not supported";
+ case TD_NOCAPAB:
+ return "capability not available";
+ case TD_DBERR:
+ return "debugger service failed";
+ case TD_NOAPLIC:
+ return "operation not applicable to";
+ case TD_NOTSD:
+ return "no thread-specific data for this thread";
+ case TD_MALLOC:
+ return "malloc failed";
+ case TD_PARTIALREG:
+ return "only part of register set was written/read";
+ case TD_NOXREGS:
+ return "X register set not available for this thread";
+ default:
+ snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
+ return buf;
+ }
+}
+
+static char *
+thread_db_state_str (td_thr_state_e state)
+{
+ static char buf[64];
+
+ switch (state)
+ {
+ case TD_THR_STOPPED:
+ return "stopped by debugger";
+ case TD_THR_RUN:
+ return "runnable";
+ case TD_THR_ACTIVE:
+ return "active";
+ case TD_THR_ZOMBIE:
+ return "zombie";
+ case TD_THR_SLEEP:
+ return "sleeping";
+ case TD_THR_STOPPED_ASLEEP:
+ return "stopped by debugger AND blocked";
+ default:
+ snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
+ return buf;
+ }
+}
+
+
+/* Convert between user-level thread ids and LWP ids. */
+
+static ptid_t
+thread_from_lwp (ptid_t ptid)
+{
+ td_thrinfo_t ti;
+ td_thrhandle_t th;
+ td_err_e err;
+
+ if (GET_LWP (ptid) == 0)
+ ptid = BUILD_LWP (GET_PID (ptid), GET_PID (ptid));
+
+ gdb_assert (is_lwp (ptid));
+
+ err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
+ if (err != TD_OK)
+ error ("Cannot find user-level thread for LWP %ld: %s",
+ GET_LWP (ptid), thread_db_err_str (err));
+
+ err = td_thr_get_info_p (&th, &ti);
+ if (err != TD_OK)
+ error ("Cannot get thread info: %s", thread_db_err_str (err));
+
+ return BUILD_THREAD (ti.ti_tid, GET_PID (ptid));
+}
+
+static ptid_t
+lwp_from_thread (ptid_t ptid)
+{
+ td_thrinfo_t ti;
+ td_thrhandle_t th;
+ td_err_e err;
+
+ if (!is_thread (ptid))
+ return ptid;
+
+ err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
+ if (err != TD_OK)
+ error ("Cannot find thread %ld: %s",
+ (long) GET_THREAD (ptid), thread_db_err_str (err));
+
+ err = td_thr_get_info_p (&th, &ti);
+ if (err != TD_OK)
+ error ("Cannot get thread info: %s", thread_db_err_str (err));
+
+ return BUILD_LWP (ti.ti_lid, GET_PID (ptid));
+}
+
+
+void
+thread_db_init (struct target_ops *target)
+{
+ target_beneath = target;
+}
+
+static int
+thread_db_load (void)
+{
+ void *handle;
+ td_err_e err;
+
+ handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW);
+ if (handle == NULL)
+ return 0;
+
+ /* Initialize pointers to the dynamic library functions we will use.
+ Essential functions first. */
+
+ td_init_p = dlsym (handle, "td_init");
+ if (td_init_p == NULL)
+ return 0;
+
+ td_ta_new_p = dlsym (handle, "td_ta_new");
+ if (td_ta_new_p == NULL)
+ return 0;
+
+ td_ta_map_id2thr_p = dlsym (handle, "td_ta_map_id2thr");
+ if (td_ta_map_id2thr_p == NULL)
+ return 0;
+
+ td_ta_map_lwp2thr_p = dlsym (handle, "td_ta_map_lwp2thr");
+ if (td_ta_map_lwp2thr_p == NULL)
+ return 0;
+
+ td_ta_thr_iter_p = dlsym (handle, "td_ta_thr_iter");
+ if (td_ta_thr_iter_p == NULL)
+ return 0;
+
+ td_thr_validate_p = dlsym (handle, "td_thr_validate");
+ if (td_thr_validate_p == NULL)
+ return 0;
+
+ td_thr_get_info_p = dlsym (handle, "td_thr_get_info");
+ if (td_thr_get_info_p == NULL)
+ return 0;
+
+ td_thr_getfpregs_p = dlsym (handle, "td_thr_getfpregs");
+ if (td_thr_getfpregs_p == NULL)
+ return 0;
+
+ td_thr_getgregs_p = dlsym (handle, "td_thr_getgregs");
+ if (td_thr_getgregs_p == NULL)
+ return 0;
+
+ td_thr_setfpregs_p = dlsym (handle, "td_thr_setfpregs");
+ if (td_thr_setfpregs_p == NULL)
+ return 0;
+
+ td_thr_setgregs_p = dlsym (handle, "td_thr_setgregs");
+ if (td_thr_setgregs_p == NULL)
+ return 0;
+
+ /* Initialize the library. */
+ err = td_init_p ();
+ if (err != TD_OK)
+ {
+ warning ("Cannot initialize libthread_db: %s", thread_db_err_str (err));
+ return 0;
+ }
+
+ /* These are not essential. */
+ td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
+ td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
+ td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
+ td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
+
+ return 1;
+}
+
+static void
+enable_thread_event_reporting (void)
+{
+ td_thr_events_t events;
+ td_notify_t notify;
+ td_err_e err;
+
+ /* We cannot use the thread event reporting facility if these
+ functions aren't available. */
+ if (td_ta_event_addr_p == NULL || td_ta_set_event_p == NULL
+ || td_ta_event_getmsg_p == NULL || td_thr_event_enable_p == NULL)
+ return;
+
+ /* Set the process wide mask saying which events we're interested in. */
+ td_event_emptyset (&events);
+ td_event_addset (&events, TD_CREATE);
+#if 0
+ /* FIXME: kettenis/2000-04-23: The event reporting facility is
+ broken for TD_DEATH events in glibc 2.1.3, so don't enable it for
+ now. */
+ td_event_addset (&events, TD_DEATH);
+#endif
+
+ err = td_ta_set_event_p (thread_agent, &events);
+ if (err != TD_OK)
+ {
+ warning ("Unable to set global thread event mask: %s",
+ thread_db_err_str (err));
+ return;
+ }
+
+ /* Delete previous thread event breakpoints, if any. */
+ remove_thread_event_breakpoints ();
+
+ /* Get address for thread creation breakpoint. */
+ err = td_ta_event_addr_p (thread_agent, TD_CREATE, &notify);
+ if (err != TD_OK)
+ {
+ warning ("Unable to get location for thread creation breakpoint: %s",
+ thread_db_err_str (err));
+ return;
+ }
+
+ /* Set up the breakpoint. */
+ td_create_bp_addr = (CORE_ADDR) notify.u.bptaddr;
+ create_thread_event_breakpoint (td_create_bp_addr);
+
+ /* Get address for thread death breakpoint. */
+ err = td_ta_event_addr_p (thread_agent, TD_DEATH, &notify);
+ if (err != TD_OK)
+ {
+ warning ("Unable to get location for thread death breakpoint: %s",
+ thread_db_err_str (err));
+ return;
+ }
+
+ /* Set up the breakpoint. */
+ td_death_bp_addr = (CORE_ADDR) notify.u.bptaddr;
+ create_thread_event_breakpoint (td_death_bp_addr);
+}
+
+static void
+disable_thread_event_reporting (void)
+{
+ td_thr_events_t events;
+
+ /* Set the process wide mask saying we aren't interested in any
+ events anymore. */
+ td_event_emptyset (&events);
+ td_ta_set_event_p (thread_agent, &events);
+
+ /* Delete thread event breakpoints, if any. */
+ remove_thread_event_breakpoints ();
+ td_create_bp_addr = 0;
+ td_death_bp_addr = 0;
+}
+
+static void
+check_thread_signals (void)
+{
+#ifdef GET_THREAD_SIGNALS
+ if (!thread_signals)
+ {
+ sigset_t mask;
+ int i;
+
+ GET_THREAD_SIGNALS (&mask);
+ sigemptyset (&thread_stop_set);
+ sigemptyset (&thread_print_set);
+
+ for (i = 1; i < NSIG; i++)
+ {
+ if (sigismember (&mask, i))
+ {
+ if (signal_stop_update (target_signal_from_host (i), 0))
+ sigaddset (&thread_stop_set, i);
+ if (signal_print_update (target_signal_from_host (i), 0))
+ sigaddset (&thread_print_set, i);
+ thread_signals = 1;
+ }
+ }
+ }
+#endif
+}
+
+static void
+disable_thread_signals (void)
+{
+#ifdef GET_THREAD_SIGNALS
+ if (thread_signals)
+ {
+ int i;
+
+ for (i = 1; i < NSIG; i++)
+ {
+ if (sigismember (&thread_stop_set, i))
+ signal_stop_update (target_signal_from_host (i), 1);
+ if (sigismember (&thread_print_set, i))
+ signal_print_update (target_signal_from_host (i), 1);
+ }
+
+ thread_signals = 0;
+ }
+#endif
+}
+
+static void
+thread_db_new_objfile (struct objfile *objfile)
+{
+ td_err_e err;
+
+ /* Don't attempt to use thread_db on targets which can not run
+ (core files). */
+ if (objfile == NULL || !target_has_execution)
+ {
+ /* All symbols have been discarded. If the thread_db target is
+ active, deactivate it now. */
+ if (using_thread_db)
+ {
+ gdb_assert (proc_handle.pid == 0);
+ unpush_target (&thread_db_ops);
+ using_thread_db = 0;
+ }
+
+ keep_thread_db = 0;
+
+ goto quit;
+ }
+
+ if (using_thread_db)
+ /* Nothing to do. The thread library was already detected and the
+ target vector was already activated. */
+ goto quit;
+
+ /* Initialize the structure that identifies the child process. Note
+ that at this point there is no guarantee that we actually have a
+ child process. */
+ proc_handle.pid = GET_PID (inferior_ptid);
+
+ /* Now attempt to open a connection to the thread library. */
+ err = td_ta_new_p (&proc_handle, &thread_agent);
+ switch (err)
+ {
+ case TD_NOLIBTHREAD:
+ /* No thread library was detected. */
+ break;
+
+ case TD_OK:
+ /* The thread library was detected. Activate the thread_db target. */
+ push_target (&thread_db_ops);
+ using_thread_db = 1;
+
+ /* If the thread library was detected in the main symbol file
+ itself, we assume that the program was statically linked
+ against the thread library and well have to keep this
+ module's target vector activated until forever... Well, at
+ least until all symbols have been discarded anyway (see
+ above). */
+ if (objfile == symfile_objfile)
+ {
+ gdb_assert (proc_handle.pid == 0);
+ keep_thread_db = 1;
+ }
+
+ /* We can only poke around if there actually is a child process.
+ If there is no child process alive, postpone the steps below
+ until one has been created. */
+ if (proc_handle.pid != 0)
+ {
+ enable_thread_event_reporting ();
+ thread_db_find_new_threads ();
+ }
+ break;
+
+ default:
+ warning ("Cannot initialize thread debugging library: %s",
+ thread_db_err_str (err));
+ break;
+ }
+
+ quit:
+ if (target_new_objfile_chain)
+ target_new_objfile_chain (objfile);
+}
+
+static void
+attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
+ const td_thrinfo_t *ti_p, int verbose)
+{
+ struct thread_info *tp;
+ td_err_e err;
+
+ check_thread_signals ();
+
+ if (verbose)
+ printf_unfiltered ("[New %s]\n", target_pid_to_str (ptid));
+
+ /* Add the thread to GDB's thread list. */
+ tp = add_thread (ptid);
+ tp->private = xmalloc (sizeof (struct private_thread_info));
+ tp->private->lwpid = ti_p->ti_lid;
+
+ if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE)
+ return; /* A zombie thread -- do not attach. */
+
+ /* Under GNU/Linux, we have to attach to each and every thread. */
+#ifdef ATTACH_LWP
+ ATTACH_LWP (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid)), 0);
+#endif
+
+ /* Enable thread event reporting for this thread. */
+ err = td_thr_event_enable_p (th_p, 1);
+ if (err != TD_OK)
+ error ("Cannot enable thread event reporting for %s: %s",
+ target_pid_to_str (ptid), thread_db_err_str (err));
+}
+
+static void
+thread_db_attach (char *args, int from_tty)
+{
+ target_beneath->to_attach (args, from_tty);
+
+ /* Destroy thread info; it's no longer valid. */
+ init_thread_list ();
+
+ /* The child process is now the actual multi-threaded
+ program. Snatch its process ID... */
+ proc_handle.pid = GET_PID (inferior_ptid);
+
+ /* ...and perform the remaining initialization steps. */
+ enable_thread_event_reporting ();
+ thread_db_find_new_threads();
+}
+
+static void
+detach_thread (ptid_t ptid, int verbose)
+{
+ if (verbose)
+ printf_unfiltered ("[%s exited]\n", target_pid_to_str (ptid));
+}
+
+static void
+thread_db_detach (char *args, int from_tty)
+{
+ disable_thread_event_reporting ();
+
+ /* There's no need to save & restore inferior_ptid here, since the
+ inferior is supposed to be survive this function call. */
+ inferior_ptid = lwp_from_thread (inferior_ptid);
+
+ /* Forget about the child's process ID. We shouldn't need it
+ anymore. */
+ proc_handle.pid = 0;
+
+ target_beneath->to_detach (args, from_tty);
+}
+
+static void
+thread_db_resume (ptid_t ptid, int step, enum target_signal signo)
+{
+ struct cleanup *old_chain = save_inferior_ptid ();
+
+ if (GET_PID (ptid) == -1)
+ inferior_ptid = lwp_from_thread (inferior_ptid);
+ else if (is_thread (ptid))
+ ptid = lwp_from_thread (ptid);
+
+ target_beneath->to_resume (ptid, step, signo);
+
+ do_cleanups (old_chain);
+}
+
+/* Check if PID is currently stopped at the location of a thread event
+ breakpoint location. If it is, read the event message and act upon
+ the event. */
+
+static void
+check_event (ptid_t ptid)
+{
+ td_event_msg_t msg;
+ td_thrinfo_t ti;
+ td_err_e err;
+ CORE_ADDR stop_pc;
+
+ /* Bail out early if we're not at a thread event breakpoint. */
+ stop_pc = read_pc_pid (ptid) - DECR_PC_AFTER_BREAK;
+ if (stop_pc != td_create_bp_addr && stop_pc != td_death_bp_addr)
+ return;
+
+ err = td_ta_event_getmsg_p (thread_agent, &msg);
+ if (err != TD_OK)
+ {
+ if (err == TD_NOMSG)
+ return;
+
+ error ("Cannot get thread event message: %s", thread_db_err_str (err));
+ }
+
+ err = td_thr_get_info_p (msg.th_p, &ti);
+ if (err != TD_OK)
+ error ("Cannot get thread info: %s", thread_db_err_str (err));
+
+ ptid = BUILD_THREAD (ti.ti_tid, GET_PID (ptid));
+
+ switch (msg.event)
+ {
+ case TD_CREATE:
+#if 0
+ /* FIXME: kettenis/2000-08-26: Since we use td_ta_event_getmsg,
+ there is no guarantee that the breakpoint will match the
+ event. Should we use td_thr_event_getmsg instead? */
+
+ if (stop_pc != td_create_bp_addr)
+ error ("Thread creation event doesn't match breakpoint.");
+#endif
+
+ /* We may already know about this thread, for instance when the
+ user has issued the `info threads' command before the SIGTRAP
+ for hitting the thread creation breakpoint was reported. */
+ if (!in_thread_list (ptid))
+ attach_thread (ptid, msg.th_p, &ti, 1);
+ return;
+
+ case TD_DEATH:
+#if 0
+ /* FIXME: See TD_CREATE. */
+
+ if (stop_pc != td_death_bp_addr)
+ error ("Thread death event doesn't match breakpoint.");
+#endif
+
+ if (!in_thread_list (ptid))
+ error ("Spurious thread death event.");
+
+ detach_thread (ptid, 1);
+ return;
+
+ default:
+ error ("Spurious thread event.");
+ }
+}
+
+static ptid_t
+thread_db_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+{
+ extern ptid_t trap_ptid;
+
+ if (GET_PID (ptid) != -1 && is_thread (ptid))
+ ptid = lwp_from_thread (ptid);
+
+ ptid = target_beneath->to_wait (ptid, ourstatus);
+
+ if (proc_handle.pid == 0)
+ /* The current child process isn't the actual multi-threaded
+ program yet, so don't try to do any special thread-specific
+ post-processing and bail out early. */
+ return ptid;
+
+ if (ourstatus->kind == TARGET_WAITKIND_EXITED)
+ return pid_to_ptid (-1);
+
+ if (ourstatus->kind == TARGET_WAITKIND_STOPPED
+ && ourstatus->value.sig == TARGET_SIGNAL_TRAP)
+ /* Check for a thread event. */
+ check_event (ptid);
+
+ if (!ptid_equal (trap_ptid, null_ptid))
+ trap_ptid = thread_from_lwp (trap_ptid);
+
+ return thread_from_lwp (ptid);
+}
+
+static int
+thread_db_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ struct cleanup *old_chain = save_inferior_ptid ();
+ int xfer;
+
+ if (is_thread (inferior_ptid))
+ {
+ /* FIXME: This seems to be necessary to make sure breakpoints
+ are removed. */
+ if (!target_thread_alive (inferior_ptid))
+ inferior_ptid = pid_to_ptid (GET_PID (inferior_ptid));
+ else
+ inferior_ptid = lwp_from_thread (inferior_ptid);
+ }
+
+ xfer = target_beneath->to_xfer_memory (memaddr, myaddr, len, write, attrib, target);
+
+ do_cleanups (old_chain);
+ return xfer;
+}
+
+static void
+thread_db_fetch_registers (int regno)
+{
+ td_thrhandle_t th;
+ prgregset_t gregset;
+ gdb_prfpregset_t fpregset;
+ td_err_e err;
+
+ if (!is_thread (inferior_ptid))
+ {
+ /* Pass the request to the target beneath us. */
+ target_beneath->to_fetch_registers (regno);
+ return;
+ }
+
+ err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th);
+ if (err != TD_OK)
+ error ("Cannot find thread %ld: %s",
+ (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
+
+ err = td_thr_getgregs_p (&th, gregset);
+ if (err != TD_OK)
+ error ("Cannot fetch general-purpose registers for thread %ld: %s",
+ (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
+
+ err = td_thr_getfpregs_p (&th, &fpregset);
+ if (err != TD_OK)
+ error ("Cannot get floating-point registers for thread %ld: %s",
+ (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
+
+ /* Note that we must call supply_gregset after calling the thread_db
+ routines because the thread_db routines call ps_lgetgregs and
+ friends which clobber GDB's register cache. */
+ supply_gregset ((gdb_gregset_t *) gregset);
+ supply_fpregset (&fpregset);
+}
+
+static void
+thread_db_store_registers (int regno)
+{
+ td_thrhandle_t th;
+ prgregset_t gregset;
+ gdb_prfpregset_t fpregset;
+ td_err_e err;
+
+ if (!is_thread (inferior_ptid))
+ {
+ /* Pass the request to the target beneath us. */
+ target_beneath->to_store_registers (regno);
+ return;
+ }
+
+ err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th);
+ if (err != TD_OK)
+ error ("Cannot find thread %ld: %s",
+ (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
+
+ if (regno != -1)
+ {
+ char raw[MAX_REGISTER_RAW_SIZE];
+
+ read_register_gen (regno, raw);
+ thread_db_fetch_registers (-1);
+ supply_register (regno, raw);
+ }
+
+ fill_gregset ((gdb_gregset_t *) gregset, -1);
+ fill_fpregset (&fpregset, -1);
+
+ err = td_thr_setgregs_p (&th, gregset);
+ if (err != TD_OK)
+ error ("Cannot store general-purpose registers for thread %ld: %s",
+ (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
+ err = td_thr_setfpregs_p (&th, &fpregset);
+ if (err != TD_OK)
+ error ("Cannot store floating-point registers for thread %ld: %s",
+ (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
+}
+
+static void
+thread_db_kill (void)
+{
+ /* There's no need to save & restore inferior_ptid here, since the
+ inferior isn't supposed to survive this function call. */
+ inferior_ptid = lwp_from_thread (inferior_ptid);
+ target_beneath->to_kill ();
+}
+
+static void
+thread_db_create_inferior (char *exec_file, char *allargs, char **env)
+{
+ if (!keep_thread_db)
+ {
+ unpush_target (&thread_db_ops);
+ using_thread_db = 0;
+ }
+
+ target_beneath->to_create_inferior (exec_file, allargs, env);
+}
+
+static void
+thread_db_post_startup_inferior (ptid_t ptid)
+{
+ if (proc_handle.pid == 0)
+ {
+ /* The child process is now the actual multi-threaded
+ program. Snatch its process ID... */
+ proc_handle.pid = GET_PID (ptid);
+
+ /* ...and perform the remaining initialization steps. */
+ enable_thread_event_reporting ();
+ thread_db_find_new_threads ();
+ }
+}
+
+static void
+thread_db_mourn_inferior (void)
+{
+ remove_thread_event_breakpoints ();
+
+ /* Forget about the child's process ID. We shouldn't need it
+ anymore. */
+ proc_handle.pid = 0;
+
+ target_beneath->to_mourn_inferior ();
+}
+
+static int
+thread_db_thread_alive (ptid_t ptid)
+{
+ td_thrhandle_t th;
+ td_thrinfo_t ti;
+ td_err_e err;
+
+ if (is_thread (ptid))
+ {
+ err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
+ if (err != TD_OK)
+ return 0;
+
+ err = td_thr_validate_p (&th);
+ if (err != TD_OK)
+ return 0;
+
+ err = td_thr_get_info_p (&th, &ti);
+ if (err != TD_OK)
+ return 0;
+
+ if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
+ return 0; /* A zombie thread. */
+
+ return 1;
+ }
+
+ if (target_beneath->to_thread_alive)
+ return target_beneath->to_thread_alive (ptid);
+
+ return 0;
+}
+
+static int
+find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
+{
+ td_thrinfo_t ti;
+ td_err_e err;
+ ptid_t ptid;
+
+ err = td_thr_get_info_p (th_p, &ti);
+ if (err != TD_OK)
+ error ("Cannot get thread info: %s", thread_db_err_str (err));
+
+ if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
+ return 0; /* A zombie -- ignore. */
+
+ ptid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_ptid));
+
+ if (!in_thread_list (ptid))
+ attach_thread (ptid, th_p, &ti, 1);
+
+ return 0;
+}
+
+static void
+thread_db_find_new_threads (void)
+{
+ td_err_e err;
+
+ /* Iterate over all user-space threads to discover new threads. */
+ err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL,
+ TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
+ TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
+ if (err != TD_OK)
+ error ("Cannot find new threads: %s", thread_db_err_str (err));
+}
+
+static char *
+thread_db_pid_to_str (ptid_t ptid)
+{
+ if (is_thread (ptid))
+ {
+ static char buf[64];
+ td_thrhandle_t th;
+ td_thrinfo_t ti;
+ td_err_e err;
+
+ err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
+ if (err != TD_OK)
+ error ("Cannot find thread %ld: %s",
+ (long) GET_THREAD (ptid), thread_db_err_str (err));
+
+ err = td_thr_get_info_p (&th, &ti);
+ if (err != TD_OK)
+ error ("Cannot get thread info for thread %ld: %s",
+ (long) GET_THREAD (ptid), thread_db_err_str (err));
+
+ if (ti.ti_state == TD_THR_ACTIVE && ti.ti_lid != 0)
+ {
+ snprintf (buf, sizeof (buf), "Thread %ld (LWP %d)",
+ (long) ti.ti_tid, ti.ti_lid);
+ }
+ else
+ {
+ snprintf (buf, sizeof (buf), "Thread %ld (%s)",
+ (long) ti.ti_tid, thread_db_state_str (ti.ti_state));
+ }
+
+ return buf;
+ }
+
+ if (target_beneath->to_pid_to_str (ptid))
+ return target_beneath->to_pid_to_str (ptid);
+
+ return normal_pid_to_str (ptid);
+}
+
+static void
+init_thread_db_ops (void)
+{
+ thread_db_ops.to_shortname = "multi-thread";
+ thread_db_ops.to_longname = "multi-threaded child process.";
+ thread_db_ops.to_doc = "Threads and pthreads support.";
+ thread_db_ops.to_attach = thread_db_attach;
+ thread_db_ops.to_detach = thread_db_detach;
+ thread_db_ops.to_resume = thread_db_resume;
+ thread_db_ops.to_wait = thread_db_wait;
+ thread_db_ops.to_fetch_registers = thread_db_fetch_registers;
+ thread_db_ops.to_store_registers = thread_db_store_registers;
+ thread_db_ops.to_xfer_memory = thread_db_xfer_memory;
+ thread_db_ops.to_kill = thread_db_kill;
+ thread_db_ops.to_create_inferior = thread_db_create_inferior;
+ thread_db_ops.to_post_startup_inferior = thread_db_post_startup_inferior;
+ thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior;
+ thread_db_ops.to_thread_alive = thread_db_thread_alive;
+ thread_db_ops.to_find_new_threads = thread_db_find_new_threads;
+ thread_db_ops.to_pid_to_str = thread_db_pid_to_str;
+ thread_db_ops.to_stratum = thread_stratum;
+ thread_db_ops.to_has_thread_control = tc_schedlock;
+ thread_db_ops.to_magic = OPS_MAGIC;
+}
+
+void
+_initialize_thread_db (void)
+{
+ /* Only initialize the module if we can load libthread_db. */
+ if (thread_db_load ())
+ {
+ init_thread_db_ops ();
+ add_target (&thread_db_ops);
+
+ /* Add ourselves to objfile event chain. */
+ target_new_objfile_chain = target_new_objfile_hook;
+ target_new_objfile_hook = thread_db_new_objfile;
+ }
+}
diff --git a/gdb/thread.c b/gdb/thread.c
new file mode 100644
index 00000000000..45130bbb0ee
--- /dev/null
+++ b/gdb/thread.c
@@ -0,0 +1,754 @@
+/* Multi-process/thread control for GDB, the GNU debugger.
+
+ Copyright 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
+
+ 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 "defs.h"
+#include "symtab.h"
+#include "frame.h"
+#include "inferior.h"
+#include "environ.h"
+#include "value.h"
+#include "target.h"
+#include "gdbthread.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "regcache.h"
+#include "gdb.h"
+
+#include <ctype.h>
+#include <sys/types.h>
+#include <signal.h>
+#include "ui-out.h"
+
+/*#include "lynxos-core.h" */
+
+/* Definition of struct thread_info exported to gdbthread.h */
+
+/* Prototypes for exported functions. */
+
+void _initialize_thread (void);
+
+/* Prototypes for local functions. */
+
+static struct thread_info *thread_list = NULL;
+static int highest_thread_num;
+
+static struct thread_info *find_thread_id (int num);
+
+static void thread_command (char *tidstr, int from_tty);
+static void thread_apply_all_command (char *, int);
+static int thread_alive (struct thread_info *);
+static void info_threads_command (char *, int);
+static void thread_apply_command (char *, int);
+static void restore_current_thread (ptid_t);
+static void switch_to_thread (ptid_t ptid);
+static void prune_threads (void);
+
+void
+delete_step_resume_breakpoint (void *arg)
+{
+ struct breakpoint **breakpointp = (struct breakpoint **) arg;
+ struct thread_info *tp;
+
+ if (*breakpointp != NULL)
+ {
+ delete_breakpoint (*breakpointp);
+ for (tp = thread_list; tp; tp = tp->next)
+ if (tp->step_resume_breakpoint == *breakpointp)
+ tp->step_resume_breakpoint = NULL;
+
+ *breakpointp = NULL;
+ }
+}
+
+static void
+free_thread (struct thread_info *tp)
+{
+ /* NOTE: this will take care of any left-over step_resume breakpoints,
+ but not any user-specified thread-specific breakpoints. */
+ if (tp->step_resume_breakpoint)
+ delete_breakpoint (tp->step_resume_breakpoint);
+
+ /* FIXME: do I ever need to call the back-end to give it a
+ chance at this private data before deleting the thread? */
+ if (tp->private)
+ xfree (tp->private);
+
+ xfree (tp);
+}
+
+void
+init_thread_list (void)
+{
+ struct thread_info *tp, *tpnext;
+
+ highest_thread_num = 0;
+ if (!thread_list)
+ return;
+
+ for (tp = thread_list; tp; tp = tpnext)
+ {
+ tpnext = tp->next;
+ free_thread (tp);
+ }
+
+ thread_list = NULL;
+}
+
+/* add_thread now returns a pointer to the new thread_info,
+ so that back_ends can initialize their private data. */
+
+struct thread_info *
+add_thread (ptid_t ptid)
+{
+ struct thread_info *tp;
+
+ tp = (struct thread_info *) xmalloc (sizeof (*tp));
+ memset (tp, 0, sizeof (*tp));
+ tp->ptid = ptid;
+ tp->num = ++highest_thread_num;
+ tp->next = thread_list;
+ thread_list = tp;
+ return tp;
+}
+
+void
+delete_thread (ptid_t ptid)
+{
+ struct thread_info *tp, *tpprev;
+
+ tpprev = NULL;
+
+ for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
+ if (ptid_equal (tp->ptid, ptid))
+ break;
+
+ if (!tp)
+ return;
+
+ if (tpprev)
+ tpprev->next = tp->next;
+ else
+ thread_list = tp->next;
+
+ free_thread (tp);
+}
+
+static struct thread_info *
+find_thread_id (int num)
+{
+ struct thread_info *tp;
+
+ for (tp = thread_list; tp; tp = tp->next)
+ if (tp->num == num)
+ return tp;
+
+ return NULL;
+}
+
+/* Find a thread_info by matching PTID. */
+struct thread_info *
+find_thread_pid (ptid_t ptid)
+{
+ struct thread_info *tp;
+
+ for (tp = thread_list; tp; tp = tp->next)
+ if (ptid_equal (tp->ptid, ptid))
+ return tp;
+
+ return NULL;
+}
+
+/*
+ * Thread iterator function.
+ *
+ * Calls a callback function once for each thread, so long as
+ * the callback function returns false. If the callback function
+ * returns true, the iteration will end and the current thread
+ * will be returned. This can be useful for implementing a
+ * search for a thread with arbitrary attributes, or for applying
+ * some operation to every thread.
+ *
+ * FIXME: some of the existing functionality, such as
+ * "Thread apply all", might be rewritten using this functionality.
+ */
+
+struct thread_info *
+iterate_over_threads (int (*callback) (struct thread_info *, void *),
+ void *data)
+{
+ struct thread_info *tp;
+
+ for (tp = thread_list; tp; tp = tp->next)
+ if ((*callback) (tp, data))
+ return tp;
+
+ return NULL;
+}
+
+int
+valid_thread_id (int num)
+{
+ struct thread_info *tp;
+
+ for (tp = thread_list; tp; tp = tp->next)
+ if (tp->num == num)
+ return 1;
+
+ return 0;
+}
+
+int
+pid_to_thread_id (ptid_t ptid)
+{
+ struct thread_info *tp;
+
+ for (tp = thread_list; tp; tp = tp->next)
+ if (ptid_equal (tp->ptid, ptid))
+ return tp->num;
+
+ return 0;
+}
+
+ptid_t
+thread_id_to_pid (int num)
+{
+ struct thread_info *thread = find_thread_id (num);
+ if (thread)
+ return thread->ptid;
+ else
+ return pid_to_ptid (-1);
+}
+
+int
+in_thread_list (ptid_t ptid)
+{
+ struct thread_info *tp;
+
+ for (tp = thread_list; tp; tp = tp->next)
+ if (ptid_equal (tp->ptid, ptid))
+ return 1;
+
+ return 0; /* Never heard of 'im */
+}
+
+/* Print a list of thread ids currently known, and the total number of
+ threads. To be used from within catch_errors. */
+static int
+do_captured_list_thread_ids (struct ui_out *uiout,
+ void *arg)
+{
+ struct thread_info *tp;
+ int num = 0;
+
+ ui_out_tuple_begin (uiout, "thread-ids");
+
+ for (tp = thread_list; tp; tp = tp->next)
+ {
+ num++;
+ ui_out_field_int (uiout, "thread-id", tp->num);
+ }
+
+ ui_out_tuple_end (uiout);
+ ui_out_field_int (uiout, "number-of-threads", num);
+ return GDB_RC_OK;
+}
+
+/* Official gdblib interface function to get a list of thread ids and
+ the total number. */
+enum gdb_rc
+gdb_list_thread_ids (struct ui_out *uiout)
+{
+ return catch_exceptions (uiout, do_captured_list_thread_ids, NULL,
+ NULL, RETURN_MASK_ALL);
+}
+
+/* Load infrun state for the thread PID. */
+
+void
+load_infrun_state (ptid_t ptid,
+ CORE_ADDR *prev_pc,
+ CORE_ADDR *prev_func_start,
+ char **prev_func_name,
+ int *trap_expected,
+ struct breakpoint **step_resume_breakpoint,
+ struct breakpoint **through_sigtramp_breakpoint,
+ CORE_ADDR *step_range_start,
+ CORE_ADDR *step_range_end,
+ CORE_ADDR *step_frame_address,
+ int *handling_longjmp,
+ int *another_trap,
+ int *stepping_through_solib_after_catch,
+ bpstat *stepping_through_solib_catchpoints,
+ int *stepping_through_sigtramp,
+ int *current_line,
+ struct symtab **current_symtab,
+ CORE_ADDR *step_sp)
+{
+ struct thread_info *tp;
+
+ /* If we can't find the thread, then we're debugging a single threaded
+ process. No need to do anything in that case. */
+ tp = find_thread_id (pid_to_thread_id (ptid));
+ if (tp == NULL)
+ return;
+
+ *prev_pc = tp->prev_pc;
+ *prev_func_start = tp->prev_func_start;
+ *prev_func_name = tp->prev_func_name;
+ *trap_expected = tp->trap_expected;
+ *step_resume_breakpoint = tp->step_resume_breakpoint;
+ *through_sigtramp_breakpoint = tp->through_sigtramp_breakpoint;
+ *step_range_start = tp->step_range_start;
+ *step_range_end = tp->step_range_end;
+ *step_frame_address = tp->step_frame_address;
+ *handling_longjmp = tp->handling_longjmp;
+ *another_trap = tp->another_trap;
+ *stepping_through_solib_after_catch = tp->stepping_through_solib_after_catch;
+ *stepping_through_solib_catchpoints = tp->stepping_through_solib_catchpoints;
+ *stepping_through_sigtramp = tp->stepping_through_sigtramp;
+ *current_line = tp->current_line;
+ *current_symtab = tp->current_symtab;
+ *step_sp = tp->step_sp;
+}
+
+/* Save infrun state for the thread PID. */
+
+void
+save_infrun_state (ptid_t ptid,
+ CORE_ADDR prev_pc,
+ CORE_ADDR prev_func_start,
+ char *prev_func_name,
+ int trap_expected,
+ struct breakpoint *step_resume_breakpoint,
+ struct breakpoint *through_sigtramp_breakpoint,
+ CORE_ADDR step_range_start,
+ CORE_ADDR step_range_end,
+ CORE_ADDR step_frame_address,
+ int handling_longjmp,
+ int another_trap,
+ int stepping_through_solib_after_catch,
+ bpstat stepping_through_solib_catchpoints,
+ int stepping_through_sigtramp,
+ int current_line,
+ struct symtab *current_symtab,
+ CORE_ADDR step_sp)
+{
+ struct thread_info *tp;
+
+ /* If we can't find the thread, then we're debugging a single-threaded
+ process. Nothing to do in that case. */
+ tp = find_thread_id (pid_to_thread_id (ptid));
+ if (tp == NULL)
+ return;
+
+ tp->prev_pc = prev_pc;
+ tp->prev_func_start = prev_func_start;
+ tp->prev_func_name = prev_func_name;
+ tp->trap_expected = trap_expected;
+ tp->step_resume_breakpoint = step_resume_breakpoint;
+ tp->through_sigtramp_breakpoint = through_sigtramp_breakpoint;
+ tp->step_range_start = step_range_start;
+ tp->step_range_end = step_range_end;
+ tp->step_frame_address = step_frame_address;
+ tp->handling_longjmp = handling_longjmp;
+ tp->another_trap = another_trap;
+ tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
+ tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
+ tp->stepping_through_sigtramp = stepping_through_sigtramp;
+ tp->current_line = current_line;
+ tp->current_symtab = current_symtab;
+ tp->step_sp = step_sp;
+}
+
+/* Return true if TP is an active thread. */
+static int
+thread_alive (struct thread_info *tp)
+{
+ if (PIDGET (tp->ptid) == -1)
+ return 0;
+ if (!target_thread_alive (tp->ptid))
+ {
+ tp->ptid = pid_to_ptid (-1); /* Mark it as dead */
+ return 0;
+ }
+ return 1;
+}
+
+static void
+prune_threads (void)
+{
+ struct thread_info *tp, *next;
+
+ for (tp = thread_list; tp; tp = next)
+ {
+ next = tp->next;
+ if (!thread_alive (tp))
+ delete_thread (tp->ptid);
+ }
+}
+
+/* Print information about currently known threads
+
+ * Note: this has the drawback that it _really_ switches
+ * threads, which frees the frame cache. A no-side
+ * effects info-threads command would be nicer.
+ */
+
+static void
+info_threads_command (char *arg, int from_tty)
+{
+ struct thread_info *tp;
+ ptid_t current_ptid;
+ struct frame_info *cur_frame;
+ int saved_frame_level = frame_relative_level (selected_frame);
+ int counter;
+ char *extra_info;
+
+ /* Avoid coredumps which would happen if we tried to access a NULL
+ selected_frame. */
+ if (!target_has_stack)
+ error ("No stack.");
+
+ prune_threads ();
+ target_find_new_threads ();
+ current_ptid = inferior_ptid;
+ for (tp = thread_list; tp; tp = tp->next)
+ {
+ if (ptid_equal (tp->ptid, current_ptid))
+ printf_filtered ("* ");
+ else
+ printf_filtered (" ");
+
+#ifdef HPUXHPPA
+ printf_filtered ("%d %s", tp->num, target_tid_to_str (tp->ptid));
+#else
+ printf_filtered ("%d %s", tp->num, target_pid_to_str (tp->ptid));
+#endif
+
+ extra_info = target_extra_thread_info (tp);
+ if (extra_info)
+ printf_filtered (" (%s)", extra_info);
+ puts_filtered (" ");
+
+ switch_to_thread (tp->ptid);
+ if (selected_frame)
+ print_only_stack_frame (selected_frame, -1, 0);
+ else
+ printf_filtered ("[No stack.]\n");
+ }
+
+ switch_to_thread (current_ptid);
+
+ /* Code below copied from "up_silently_base" in "stack.c".
+ * It restores the frame set by the user before the "info threads"
+ * command. We have finished the info-threads display by switching
+ * back to the current thread. That switch has put us at the top
+ * of the stack (leaf frame).
+ */
+ counter = saved_frame_level;
+ cur_frame = find_relative_frame (selected_frame, &counter);
+ if (counter != 0)
+ {
+ /* Ooops, can't restore, tell user where we are. */
+ warning ("Couldn't restore frame in current thread, at frame 0");
+ print_stack_frame (selected_frame, -1, 0);
+ }
+ else
+ {
+ select_frame (cur_frame);
+ }
+
+ /* re-show current frame. */
+ show_stack_frame (cur_frame);
+}
+
+/* Switch from one thread to another. */
+
+static void
+switch_to_thread (ptid_t ptid)
+{
+ if (ptid_equal (ptid, inferior_ptid))
+ return;
+
+ inferior_ptid = ptid;
+ flush_cached_frames ();
+ registers_changed ();
+ stop_pc = read_pc ();
+ select_frame (get_current_frame ());
+}
+
+static void
+restore_current_thread (ptid_t ptid)
+{
+ if (! ptid_equal (ptid, inferior_ptid))
+ {
+ switch_to_thread (ptid);
+ print_stack_frame (get_current_frame (), 0, -1);
+ }
+}
+
+struct current_thread_cleanup
+{
+ ptid_t inferior_ptid;
+};
+
+static void
+do_restore_current_thread_cleanup (void *arg)
+{
+ struct current_thread_cleanup *old = arg;
+ restore_current_thread (old->inferior_ptid);
+ xfree (old);
+}
+
+static struct cleanup *
+make_cleanup_restore_current_thread (ptid_t inferior_ptid)
+{
+ struct current_thread_cleanup *old
+ = xmalloc (sizeof (struct current_thread_cleanup));
+ old->inferior_ptid = inferior_ptid;
+ return make_cleanup (do_restore_current_thread_cleanup, old);
+}
+
+/* Apply a GDB command to a list of threads. List syntax is a whitespace
+ seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
+ of two numbers seperated by a hyphen. Examples:
+
+ thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
+ thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
+ thread apply all p x/i $pc Apply x/i $pc cmd to all threads
+ */
+
+static void
+thread_apply_all_command (char *cmd, int from_tty)
+{
+ struct thread_info *tp;
+ struct cleanup *old_chain;
+ struct cleanup *saved_cmd_cleanup_chain;
+ char *saved_cmd;
+
+ if (cmd == NULL || *cmd == '\000')
+ error ("Please specify a command following the thread ID list");
+
+ old_chain = make_cleanup_restore_current_thread (inferior_ptid);
+
+ /* It is safe to update the thread list now, before
+ traversing it for "thread apply all". MVS */
+ target_find_new_threads ();
+
+ /* Save a copy of the command in case it is clobbered by
+ execute_command */
+ saved_cmd = xstrdup (cmd);
+ saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
+ for (tp = thread_list; tp; tp = tp->next)
+ if (thread_alive (tp))
+ {
+ switch_to_thread (tp->ptid);
+#ifdef HPUXHPPA
+ printf_filtered ("\nThread %d (%s):\n",
+ tp->num,
+ target_tid_to_str (inferior_ptid));
+#else
+ printf_filtered ("\nThread %d (%s):\n", tp->num,
+ target_pid_to_str (inferior_ptid));
+#endif
+ execute_command (cmd, from_tty);
+ strcpy (cmd, saved_cmd); /* Restore exact command used previously */
+ }
+
+ do_cleanups (saved_cmd_cleanup_chain);
+ do_cleanups (old_chain);
+}
+
+static void
+thread_apply_command (char *tidlist, int from_tty)
+{
+ char *cmd;
+ char *p;
+ struct cleanup *old_chain;
+ struct cleanup *saved_cmd_cleanup_chain;
+ char *saved_cmd;
+
+ if (tidlist == NULL || *tidlist == '\000')
+ error ("Please specify a thread ID list");
+
+ for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
+
+ if (*cmd == '\000')
+ error ("Please specify a command following the thread ID list");
+
+ old_chain = make_cleanup_restore_current_thread (inferior_ptid);
+
+ /* Save a copy of the command in case it is clobbered by
+ execute_command */
+ saved_cmd = xstrdup (cmd);
+ saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
+ while (tidlist < cmd)
+ {
+ struct thread_info *tp;
+ int start, end;
+
+ start = strtol (tidlist, &p, 10);
+ if (p == tidlist)
+ error ("Error parsing %s", tidlist);
+ tidlist = p;
+
+ while (*tidlist == ' ' || *tidlist == '\t')
+ tidlist++;
+
+ if (*tidlist == '-') /* Got a range of IDs? */
+ {
+ tidlist++; /* Skip the - */
+ end = strtol (tidlist, &p, 10);
+ if (p == tidlist)
+ error ("Error parsing %s", tidlist);
+ tidlist = p;
+
+ while (*tidlist == ' ' || *tidlist == '\t')
+ tidlist++;
+ }
+ else
+ end = start;
+
+ for (; start <= end; start++)
+ {
+ tp = find_thread_id (start);
+
+ if (!tp)
+ warning ("Unknown thread %d.", start);
+ else if (!thread_alive (tp))
+ warning ("Thread %d has terminated.", start);
+ else
+ {
+ switch_to_thread (tp->ptid);
+#ifdef HPUXHPPA
+ printf_filtered ("\nThread %d (%s):\n", tp->num,
+ target_tid_to_str (inferior_ptid));
+#else
+ printf_filtered ("\nThread %d (%s):\n", tp->num,
+ target_pid_to_str (inferior_ptid));
+#endif
+ execute_command (cmd, from_tty);
+ strcpy (cmd, saved_cmd); /* Restore exact command used previously */
+ }
+ }
+ }
+
+ do_cleanups (saved_cmd_cleanup_chain);
+ do_cleanups (old_chain);
+}
+
+/* Switch to the specified thread. Will dispatch off to thread_apply_command
+ if prefix of arg is `apply'. */
+
+static void
+thread_command (char *tidstr, int from_tty)
+{
+ if (!tidstr)
+ {
+ /* Don't generate an error, just say which thread is current. */
+ if (target_has_stack)
+ printf_filtered ("[Current thread is %d (%s)]\n",
+ pid_to_thread_id (inferior_ptid),
+#if defined(HPUXHPPA)
+ target_tid_to_str (inferior_ptid)
+#else
+ target_pid_to_str (inferior_ptid)
+#endif
+ );
+ else
+ error ("No stack.");
+ return;
+ }
+
+ gdb_thread_select (uiout, tidstr);
+}
+
+static int
+do_captured_thread_select (struct ui_out *uiout,
+ void *tidstr)
+{
+ int num;
+ struct thread_info *tp;
+
+ num = value_as_long (parse_and_eval (tidstr));
+
+ tp = find_thread_id (num);
+
+ if (!tp)
+ error ("Thread ID %d not known.", num);
+
+ if (!thread_alive (tp))
+ error ("Thread ID %d has terminated.\n", num);
+
+ switch_to_thread (tp->ptid);
+
+ ui_out_text (uiout, "[Switching to thread ");
+ ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
+ ui_out_text (uiout, " (");
+#if defined(HPUXHPPA)
+ ui_out_text (uiout, target_tid_to_str (inferior_ptid));
+#else
+ ui_out_text (uiout, target_pid_to_str (inferior_ptid));
+#endif
+ ui_out_text (uiout, ")]");
+
+ print_stack_frame (selected_frame, frame_relative_level (selected_frame), 1);
+ return GDB_RC_OK;
+}
+
+enum gdb_rc
+gdb_thread_select (struct ui_out *uiout,
+ char *tidstr)
+{
+ return catch_exceptions (uiout, do_captured_thread_select, tidstr,
+ NULL, RETURN_MASK_ALL);
+}
+
+/* Commands with a prefix of `thread'. */
+struct cmd_list_element *thread_cmd_list = NULL;
+
+void
+_initialize_thread (void)
+{
+ static struct cmd_list_element *thread_apply_list = NULL;
+
+ add_info ("threads", info_threads_command,
+ "IDs of currently known threads.");
+
+ add_prefix_cmd ("thread", class_run, thread_command,
+ "Use this command to switch between threads.\n\
+The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1,
+ &cmdlist);
+
+ add_prefix_cmd ("apply", class_run, thread_apply_command,
+ "Apply a command to a list of threads.",
+ &thread_apply_list, "apply ", 1, &thread_cmd_list);
+
+ add_cmd ("all", class_run, thread_apply_all_command,
+ "Apply a command to all threads.",
+ &thread_apply_list);
+
+ if (!xdb_commands)
+ add_com_alias ("t", "thread", class_run, 1);
+}
diff --git a/gdb/top.h b/gdb/top.h
new file mode 100644
index 00000000000..ca0b3d13dc6
--- /dev/null
+++ b/gdb/top.h
@@ -0,0 +1,74 @@
+/* Top level stuff for GDB, the GNU debugger.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996,
+ 1997, 1998, 1999, 2000 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. */
+
+#ifndef TOP_H
+#define TOP_H
+
+/* From top.c. */
+extern char *line;
+extern int linesize;
+extern FILE *instream;
+extern char gdb_dirbuf[1024];
+extern int inhibit_gdbinit;
+extern int epoch_interface;
+extern char gdbinit[];
+
+extern void print_gdb_version (struct ui_file *);
+
+extern void source_command (char *, int);
+extern void cd_command (char *, int);
+extern void read_command_file (FILE *);
+extern void init_history (void);
+extern void command_loop (void);
+extern void simplified_command_loop (char *(*read_input_func) (char *),
+ void (*execute_command_func) (char *,
+ int));
+extern int quit_confirm (void);
+extern void quit_force (char *, int);
+extern void quit_command (char *, int);
+extern int quit_cover (void *);
+extern void execute_command (char *, int);
+
+/* This function returns a pointer to the string that is used
+ by gdb for its command prompt. */
+extern char *get_prompt (void);
+
+/* This function copies the specified string into the string that
+ is used by gdb for its command prompt. */
+extern void set_prompt (char *);
+
+/* From random places. */
+extern int mapped_symbol_files;
+extern int readnow_symbol_files;
+
+/* Perform _initialize initialization */
+extern void gdb_init (char *);
+
+/* For use by event-top.c */
+/* Variables from top.c. */
+extern int source_line_number;
+extern char *source_file_name;
+extern char *source_error;
+extern char *source_pre_error;
+extern int history_expansion_p;
+extern int server_command;
+
+#endif
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
new file mode 100644
index 00000000000..19f290656e2
--- /dev/null
+++ b/gdb/tracepoint.c
@@ -0,0 +1,2810 @@
+/* Tracing functionality for remote targets in custom GDB protocol
+
+ Copyright 1997, 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+#include "symtab.h"
+#include "frame.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "gdbcmd.h"
+#include "value.h"
+#include "target.h"
+#include "language.h"
+#include "gdb_string.h"
+#include "inferior.h"
+#include "tracepoint.h"
+#include "remote.h"
+#include "linespec.h"
+#include "regcache.h"
+#include "completer.h"
+#include "gdb-events.h"
+
+#include "ax.h"
+#include "ax-gdb.h"
+
+/* readline include files */
+#include <readline/readline.h>
+#include <readline/history.h>
+
+/* readline defines this. */
+#undef savestring
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* maximum length of an agent aexpression.
+ this accounts for the fact that packets are limited to 400 bytes
+ (which includes everything -- including the checksum), and assumes
+ the worst case of maximum length for each of the pieces of a
+ continuation packet.
+
+ NOTE: expressions get mem2hex'ed otherwise this would be twice as
+ large. (400 - 31)/2 == 184 */
+#define MAX_AGENT_EXPR_LEN 184
+
+
+extern void (*readline_begin_hook) (char *, ...);
+extern char *(*readline_hook) (char *);
+extern void (*readline_end_hook) (void);
+extern void x_command (char *, int);
+extern int addressprint; /* Print machine addresses? */
+
+/* GDB commands implemented in other modules:
+ */
+
+extern void output_command (char *, int);
+extern void registers_info (char *, int);
+extern void args_info (char *, int);
+extern void locals_info (char *, int);
+
+
+/* If this definition isn't overridden by the header files, assume
+ that isatty and fileno exist on this system. */
+#ifndef ISATTY
+#define ISATTY(FP) (isatty (fileno (FP)))
+#endif
+
+/*
+ Tracepoint.c:
+
+ This module defines the following debugger commands:
+ trace : set a tracepoint on a function, line, or address.
+ info trace : list all debugger-defined tracepoints.
+ delete trace : delete one or more tracepoints.
+ enable trace : enable one or more tracepoints.
+ disable trace : disable one or more tracepoints.
+ actions : specify actions to be taken at a tracepoint.
+ passcount : specify a pass count for a tracepoint.
+ tstart : start a trace experiment.
+ tstop : stop a trace experiment.
+ tstatus : query the status of a trace experiment.
+ tfind : find a trace frame in the trace buffer.
+ tdump : print everything collected at the current tracepoint.
+ save-tracepoints : write tracepoint setup into a file.
+
+ This module defines the following user-visible debugger variables:
+ $trace_frame : sequence number of trace frame currently being debugged.
+ $trace_line : source line of trace frame currently being debugged.
+ $trace_file : source file of trace frame currently being debugged.
+ $tracepoint : tracepoint number of trace frame currently being debugged.
+ */
+
+
+/* ======= Important global variables: ======= */
+
+/* Chain of all tracepoints defined. */
+struct tracepoint *tracepoint_chain;
+
+/* Number of last tracepoint made. */
+static int tracepoint_count;
+
+/* Number of last traceframe collected. */
+static int traceframe_number;
+
+/* Tracepoint for last traceframe collected. */
+static int tracepoint_number;
+
+/* Symbol for function for last traceframe collected */
+static struct symbol *traceframe_fun;
+
+/* Symtab and line for last traceframe collected */
+static struct symtab_and_line traceframe_sal;
+
+/* Tracing command lists */
+static struct cmd_list_element *tfindlist;
+
+/* ======= Important command functions: ======= */
+static void trace_command (char *, int);
+static void tracepoints_info (char *, int);
+static void delete_trace_command (char *, int);
+static void enable_trace_command (char *, int);
+static void disable_trace_command (char *, int);
+static void trace_pass_command (char *, int);
+static void trace_actions_command (char *, int);
+static void trace_start_command (char *, int);
+static void trace_stop_command (char *, int);
+static void trace_status_command (char *, int);
+static void trace_find_command (char *, int);
+static void trace_find_pc_command (char *, int);
+static void trace_find_tracepoint_command (char *, int);
+static void trace_find_line_command (char *, int);
+static void trace_find_range_command (char *, int);
+static void trace_find_outside_command (char *, int);
+static void tracepoint_save_command (char *, int);
+static void trace_dump_command (char *, int);
+
+/* support routines */
+static void trace_mention (struct tracepoint *);
+
+struct collection_list;
+static void add_aexpr (struct collection_list *, struct agent_expr *);
+static unsigned char *mem2hex (unsigned char *, unsigned char *, int);
+static void add_register (struct collection_list *collection,
+ unsigned int regno);
+static struct cleanup *make_cleanup_free_actions (struct tracepoint *t);
+static void free_actions_list (char **actions_list);
+static void free_actions_list_cleanup_wrapper (void *);
+
+extern void _initialize_tracepoint (void);
+
+/* Utility: returns true if "target remote" */
+static int
+target_is_remote (void)
+{
+ if (current_target.to_shortname &&
+ strcmp (current_target.to_shortname, "remote") == 0)
+ return 1;
+ else
+ return 0;
+}
+
+/* Utility: generate error from an incoming stub packet. */
+static void
+trace_error (char *buf)
+{
+ if (*buf++ != 'E')
+ return; /* not an error msg */
+ switch (*buf)
+ {
+ case '1': /* malformed packet error */
+ if (*++buf == '0') /* general case: */
+ error ("tracepoint.c: error in outgoing packet.");
+ else
+ error ("tracepoint.c: error in outgoing packet at field #%ld.",
+ strtol (buf, NULL, 16));
+ case '2':
+ error ("trace API error 0x%s.", ++buf);
+ default:
+ error ("Target returns error code '%s'.", buf);
+ }
+}
+
+/* Utility: wait for reply from stub, while accepting "O" packets */
+static char *
+remote_get_noisy_reply (char *buf,
+ long sizeof_buf)
+{
+ do /* loop on reply from remote stub */
+ {
+ QUIT; /* allow user to bail out with ^C */
+ getpkt (buf, sizeof_buf, 0);
+ if (buf[0] == 0)
+ error ("Target does not support this command.");
+ else if (buf[0] == 'E')
+ trace_error (buf);
+ else if (buf[0] == 'O' &&
+ buf[1] != 'K')
+ remote_console_output (buf + 1); /* 'O' message from stub */
+ else
+ return buf; /* here's the actual reply */
+ }
+ while (1);
+}
+
+/* Set tracepoint count to NUM. */
+static void
+set_tracepoint_count (int num)
+{
+ tracepoint_count = num;
+ set_internalvar (lookup_internalvar ("tpnum"),
+ value_from_longest (builtin_type_int, (LONGEST) num));
+}
+
+/* Set traceframe number to NUM. */
+static void
+set_traceframe_num (int num)
+{
+ traceframe_number = num;
+ set_internalvar (lookup_internalvar ("trace_frame"),
+ value_from_longest (builtin_type_int, (LONGEST) num));
+}
+
+/* Set tracepoint number to NUM. */
+static void
+set_tracepoint_num (int num)
+{
+ tracepoint_number = num;
+ set_internalvar (lookup_internalvar ("tracepoint"),
+ value_from_longest (builtin_type_int, (LONGEST) num));
+}
+
+/* Set externally visible debug variables for querying/printing
+ the traceframe context (line, function, file) */
+
+static void
+set_traceframe_context (CORE_ADDR trace_pc)
+{
+ static struct type *func_string, *file_string;
+ static struct type *func_range, *file_range;
+ struct value *func_val;
+ struct value *file_val;
+ static struct type *charstar;
+ int len;
+
+ if (charstar == (struct type *) NULL)
+ charstar = lookup_pointer_type (builtin_type_char);
+
+ if (trace_pc == -1) /* cease debugging any trace buffers */
+ {
+ traceframe_fun = 0;
+ traceframe_sal.pc = traceframe_sal.line = 0;
+ traceframe_sal.symtab = NULL;
+ set_internalvar (lookup_internalvar ("trace_func"),
+ value_from_pointer (charstar, (LONGEST) 0));
+ set_internalvar (lookup_internalvar ("trace_file"),
+ value_from_pointer (charstar, (LONGEST) 0));
+ set_internalvar (lookup_internalvar ("trace_line"),
+ value_from_pointer (builtin_type_int, (LONGEST) - 1));
+ return;
+ }
+
+ /* save as globals for internal use */
+ traceframe_sal = find_pc_line (trace_pc, 0);
+ traceframe_fun = find_pc_function (trace_pc);
+
+ /* save linenumber as "$trace_line", a debugger variable visible to users */
+ set_internalvar (lookup_internalvar ("trace_line"),
+ value_from_longest (builtin_type_int,
+ (LONGEST) traceframe_sal.line));
+
+ /* save func name as "$trace_func", a debugger variable visible to users */
+ if (traceframe_fun == NULL ||
+ SYMBOL_NAME (traceframe_fun) == NULL)
+ set_internalvar (lookup_internalvar ("trace_func"),
+ value_from_pointer (charstar, (LONGEST) 0));
+ else
+ {
+ len = strlen (SYMBOL_NAME (traceframe_fun));
+ func_range = create_range_type (func_range,
+ builtin_type_int, 0, len - 1);
+ func_string = create_array_type (func_string,
+ builtin_type_char, func_range);
+ func_val = allocate_value (func_string);
+ VALUE_TYPE (func_val) = func_string;
+ memcpy (VALUE_CONTENTS_RAW (func_val),
+ SYMBOL_NAME (traceframe_fun),
+ len);
+ func_val->modifiable = 0;
+ set_internalvar (lookup_internalvar ("trace_func"), func_val);
+ }
+
+ /* save file name as "$trace_file", a debugger variable visible to users */
+ if (traceframe_sal.symtab == NULL ||
+ traceframe_sal.symtab->filename == NULL)
+ set_internalvar (lookup_internalvar ("trace_file"),
+ value_from_pointer (charstar, (LONGEST) 0));
+ else
+ {
+ len = strlen (traceframe_sal.symtab->filename);
+ file_range = create_range_type (file_range,
+ builtin_type_int, 0, len - 1);
+ file_string = create_array_type (file_string,
+ builtin_type_char, file_range);
+ file_val = allocate_value (file_string);
+ VALUE_TYPE (file_val) = file_string;
+ memcpy (VALUE_CONTENTS_RAW (file_val),
+ traceframe_sal.symtab->filename,
+ len);
+ file_val->modifiable = 0;
+ set_internalvar (lookup_internalvar ("trace_file"), file_val);
+ }
+}
+
+/* Low level routine to set a tracepoint.
+ Returns the tracepoint object so caller can set other things.
+ Does not set the tracepoint number!
+ Does not print anything.
+
+ ==> This routine should not be called if there is a chance of later
+ error(); otherwise it leaves a bogus tracepoint on the chain. Validate
+ your arguments BEFORE calling this routine! */
+
+static struct tracepoint *
+set_raw_tracepoint (struct symtab_and_line sal)
+{
+ register struct tracepoint *t, *tc;
+ struct cleanup *old_chain;
+
+ t = (struct tracepoint *) xmalloc (sizeof (struct tracepoint));
+ old_chain = make_cleanup (xfree, t);
+ memset (t, 0, sizeof (*t));
+ t->address = sal.pc;
+ if (sal.symtab == NULL)
+ t->source_file = NULL;
+ else
+ t->source_file = savestring (sal.symtab->filename,
+ strlen (sal.symtab->filename));
+
+ t->section = sal.section;
+ t->language = current_language->la_language;
+ t->input_radix = input_radix;
+ t->line_number = sal.line;
+ t->enabled_p = 1;
+ t->next = 0;
+ t->step_count = 0;
+ t->pass_count = 0;
+ t->addr_string = NULL;
+
+ /* Add this tracepoint to the end of the chain
+ so that a list of tracepoints will come out in order
+ of increasing numbers. */
+
+ tc = tracepoint_chain;
+ if (tc == 0)
+ tracepoint_chain = t;
+ else
+ {
+ while (tc->next)
+ tc = tc->next;
+ tc->next = t;
+ }
+ discard_cleanups (old_chain);
+ return t;
+}
+
+/* Set a tracepoint according to ARG (function, linenum or *address) */
+static void
+trace_command (char *arg, int from_tty)
+{
+ char **canonical = (char **) NULL;
+ struct symtabs_and_lines sals;
+ struct symtab_and_line sal;
+ struct tracepoint *t;
+ char *addr_start = 0, *addr_end = 0;
+ int i;
+
+ if (!arg || !*arg)
+ error ("trace command requires an argument");
+
+ if (from_tty && info_verbose)
+ printf_filtered ("TRACE %s\n", arg);
+
+ addr_start = arg;
+ sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 0, &canonical);
+ addr_end = arg;
+ if (!sals.nelts)
+ return; /* ??? Presumably decode_line_1 has already warned? */
+
+ /* Resolve all line numbers to PC's */
+ for (i = 0; i < sals.nelts; i++)
+ resolve_sal_pc (&sals.sals[i]);
+
+ /* Now set all the tracepoints. */
+ for (i = 0; i < sals.nelts; i++)
+ {
+ sal = sals.sals[i];
+
+ t = set_raw_tracepoint (sal);
+ set_tracepoint_count (tracepoint_count + 1);
+ t->number = tracepoint_count;
+
+ /* If a canonical line spec is needed use that instead of the
+ command string. */
+ if (canonical != (char **) NULL && canonical[i] != NULL)
+ t->addr_string = canonical[i];
+ else if (addr_start)
+ t->addr_string = savestring (addr_start, addr_end - addr_start);
+
+ trace_mention (t);
+ }
+
+ if (sals.nelts > 1)
+ {
+ printf_filtered ("Multiple tracepoints were set.\n");
+ printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
+ }
+}
+
+/* Tell the user we have just set a tracepoint TP. */
+
+static void
+trace_mention (struct tracepoint *tp)
+{
+ printf_filtered ("Tracepoint %d", tp->number);
+
+ if (addressprint || (tp->source_file == NULL))
+ {
+ printf_filtered (" at ");
+ print_address_numeric (tp->address, 1, gdb_stdout);
+ }
+ if (tp->source_file)
+ printf_filtered (": file %s, line %d.",
+ tp->source_file, tp->line_number);
+
+ printf_filtered ("\n");
+}
+
+/* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
+
+static void
+tracepoints_info (char *tpnum_exp, int from_tty)
+{
+ struct tracepoint *t;
+ struct action_line *action;
+ int found_a_tracepoint = 0;
+ char wrap_indent[80];
+ struct symbol *sym;
+ int tpnum = -1;
+
+ if (tpnum_exp)
+ tpnum = parse_and_eval_long (tpnum_exp);
+
+ ALL_TRACEPOINTS (t)
+ if (tpnum == -1 || tpnum == t->number)
+ {
+ extern int addressprint; /* print machine addresses? */
+
+ if (!found_a_tracepoint++)
+ {
+ printf_filtered ("Num Enb ");
+ if (addressprint)
+ {
+ if (TARGET_ADDR_BIT <= 32)
+ printf_filtered ("Address ");
+ else
+ printf_filtered ("Address ");
+ }
+ printf_filtered ("PassC StepC What\n");
+ }
+ strcpy (wrap_indent, " ");
+ if (addressprint)
+ {
+ if (TARGET_ADDR_BIT <= 32)
+ strcat (wrap_indent, " ");
+ else
+ strcat (wrap_indent, " ");
+ }
+
+ printf_filtered ("%-3d %-3s ", t->number,
+ t->enabled_p ? "y" : "n");
+ if (addressprint)
+ {
+ char *tmp;
+
+ if (TARGET_ADDR_BIT <= 32)
+ tmp = local_hex_string_custom (t->address
+ & (CORE_ADDR) 0xffffffff,
+ "08l");
+ else
+ tmp = local_hex_string_custom (t->address, "016l");
+
+ printf_filtered ("%s ", tmp);
+ }
+ printf_filtered ("%-5d %-5ld ", t->pass_count, t->step_count);
+
+ if (t->source_file)
+ {
+ sym = find_pc_sect_function (t->address, t->section);
+ if (sym)
+ {
+ fputs_filtered ("in ", gdb_stdout);
+ fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
+ wrap_here (wrap_indent);
+ fputs_filtered (" at ", gdb_stdout);
+ }
+ fputs_filtered (t->source_file, gdb_stdout);
+ printf_filtered (":%d", t->line_number);
+ }
+ else
+ print_address_symbolic (t->address, gdb_stdout, demangle, " ");
+
+ printf_filtered ("\n");
+ if (t->actions)
+ {
+ printf_filtered (" Actions for tracepoint %d: \n", t->number);
+ for (action = t->actions; action; action = action->next)
+ {
+ printf_filtered ("\t%s\n", action->action);
+ }
+ }
+ }
+ if (!found_a_tracepoint)
+ {
+ if (tpnum == -1)
+ printf_filtered ("No tracepoints.\n");
+ else
+ printf_filtered ("No tracepoint number %d.\n", tpnum);
+ }
+}
+
+/* Optimization: the code to parse an enable, disable, or delete TP command
+ is virtually identical except for whether it performs an enable, disable,
+ or delete. Therefore I've combined them into one function with an opcode.
+ */
+enum tracepoint_opcode
+{
+ enable_op,
+ disable_op,
+ delete_op
+};
+
+/* This function implements enable, disable and delete commands. */
+static void
+tracepoint_operation (struct tracepoint *t, int from_tty,
+ enum tracepoint_opcode opcode)
+{
+ struct tracepoint *t2;
+
+ if (t == NULL) /* no tracepoint operand */
+ return;
+
+ switch (opcode)
+ {
+ case enable_op:
+ t->enabled_p = 1;
+ tracepoint_modify_event (t->number);
+ break;
+ case disable_op:
+ t->enabled_p = 0;
+ tracepoint_modify_event (t->number);
+ break;
+ case delete_op:
+ if (tracepoint_chain == t)
+ tracepoint_chain = t->next;
+
+ ALL_TRACEPOINTS (t2)
+ if (t2->next == t)
+ {
+ tracepoint_delete_event (t2->number);
+ t2->next = t->next;
+ break;
+ }
+
+ if (t->addr_string)
+ xfree (t->addr_string);
+ if (t->source_file)
+ xfree (t->source_file);
+ if (t->actions)
+ free_actions (t);
+
+ xfree (t);
+ break;
+ }
+}
+
+/* Utility: parse a tracepoint number and look it up in the list.
+ If MULTI_P is true, there might be a range of tracepoints in ARG.
+ if OPTIONAL_P is true, then if the argument is missing, the most
+ recent tracepoint (tracepoint_count) is returned. */
+struct tracepoint *
+get_tracepoint_by_number (char **arg, int multi_p, int optional_p)
+{
+ struct tracepoint *t;
+ int tpnum;
+ char *instring = arg == NULL ? NULL : *arg;
+
+ if (arg == NULL || *arg == NULL || ! **arg)
+ {
+ if (optional_p)
+ tpnum = tracepoint_count;
+ else
+ error_no_arg ("tracepoint number");
+ }
+ else
+ tpnum = multi_p ? get_number_or_range (arg) : get_number (arg);
+
+ if (tpnum <= 0)
+ {
+ if (instring && *instring)
+ printf_filtered ("bad tracepoint number at or near '%s'\n", instring);
+ else
+ printf_filtered ("Tracepoint argument missing and no previous tracepoint\n");
+ return NULL;
+ }
+
+ ALL_TRACEPOINTS (t)
+ if (t->number == tpnum)
+ {
+ return t;
+ }
+
+ /* FIXME: if we are in the middle of a range we don't want to give
+ a message. The current interface to get_number_or_range doesn't
+ allow us to discover this. */
+ printf_unfiltered ("No tracepoint number %d.\n", tpnum);
+ return NULL;
+}
+
+/* Utility: parse a list of tracepoint numbers, and call a func for each. */
+static void
+map_args_over_tracepoints (char *args, int from_tty,
+ enum tracepoint_opcode opcode)
+{
+ struct tracepoint *t, *tmp;
+
+ if (args == 0 || *args == 0) /* do them all */
+ ALL_TRACEPOINTS_SAFE (t, tmp)
+ tracepoint_operation (t, from_tty, opcode);
+ else
+ while (*args)
+ {
+ QUIT; /* give user option to bail out with ^C */
+ t = get_tracepoint_by_number (&args, 1, 0);
+ tracepoint_operation (t, from_tty, opcode);
+ while (*args == ' ' || *args == '\t')
+ args++;
+ }
+}
+
+/* The 'enable trace' command enables tracepoints. Not supported by all targets. */
+static void
+enable_trace_command (char *args, int from_tty)
+{
+ dont_repeat ();
+ map_args_over_tracepoints (args, from_tty, enable_op);
+}
+
+/* The 'disable trace' command enables tracepoints. Not supported by all targets. */
+static void
+disable_trace_command (char *args, int from_tty)
+{
+ dont_repeat ();
+ map_args_over_tracepoints (args, from_tty, disable_op);
+}
+
+/* Remove a tracepoint (or all if no argument) */
+static void
+delete_trace_command (char *args, int from_tty)
+{
+ dont_repeat ();
+ if (!args || !*args) /* No args implies all tracepoints; */
+ if (from_tty) /* confirm only if from_tty... */
+ if (tracepoint_chain) /* and if there are tracepoints to delete! */
+ if (!query ("Delete all tracepoints? "))
+ return;
+
+ map_args_over_tracepoints (args, from_tty, delete_op);
+}
+
+/* Set passcount for tracepoint.
+
+ First command argument is passcount, second is tracepoint number.
+ If tracepoint number omitted, apply to most recently defined.
+ Also accepts special argument "all". */
+
+static void
+trace_pass_command (char *args, int from_tty)
+{
+ struct tracepoint *t1 = (struct tracepoint *) -1, *t2;
+ unsigned int count;
+ int all = 0;
+
+ if (args == 0 || *args == 0)
+ error ("passcount command requires an argument (count + optional TP num)");
+
+ count = strtoul (args, &args, 10); /* count comes first, then TP num */
+
+ while (*args && isspace ((int) *args))
+ args++;
+
+ if (*args && strncasecmp (args, "all", 3) == 0)
+ {
+ args += 3; /* skip special argument "all" */
+ all = 1;
+ if (*args)
+ error ("Junk at end of arguments.");
+ }
+ else
+ t1 = get_tracepoint_by_number (&args, 1, 1);
+
+ do
+ {
+ if (t1)
+ {
+ ALL_TRACEPOINTS (t2)
+ if (t1 == (struct tracepoint *) -1 || t1 == t2)
+ {
+ t2->pass_count = count;
+ tracepoint_modify_event (t2->number);
+ if (from_tty)
+ printf_filtered ("Setting tracepoint %d's passcount to %d\n",
+ t2->number, count);
+ }
+ if (! all && *args)
+ t1 = get_tracepoint_by_number (&args, 1, 0);
+ }
+ }
+ while (*args);
+}
+
+/* ACTIONS functions: */
+
+/* Prototypes for action-parsing utility commands */
+static void read_actions (struct tracepoint *);
+
+/* The three functions:
+ collect_pseudocommand,
+ while_stepping_pseudocommand, and
+ end_actions_pseudocommand
+ are placeholders for "commands" that are actually ONLY to be used
+ within a tracepoint action list. If the actual function is ever called,
+ it means that somebody issued the "command" at the top level,
+ which is always an error. */
+
+static void
+end_actions_pseudocommand (char *args, int from_tty)
+{
+ error ("This command cannot be used at the top level.");
+}
+
+static void
+while_stepping_pseudocommand (char *args, int from_tty)
+{
+ error ("This command can only be used in a tracepoint actions list.");
+}
+
+static void
+collect_pseudocommand (char *args, int from_tty)
+{
+ error ("This command can only be used in a tracepoint actions list.");
+}
+
+/* Enter a list of actions for a tracepoint. */
+static void
+trace_actions_command (char *args, int from_tty)
+{
+ struct tracepoint *t;
+ char tmpbuf[128];
+ char *end_msg = "End with a line saying just \"end\".";
+
+ t = get_tracepoint_by_number (&args, 0, 1);
+ if (t)
+ {
+ sprintf (tmpbuf, "Enter actions for tracepoint %d, one per line.",
+ t->number);
+
+ if (from_tty)
+ {
+ if (readline_begin_hook)
+ (*readline_begin_hook) ("%s %s\n", tmpbuf, end_msg);
+ else if (input_from_terminal_p ())
+ printf_filtered ("%s\n%s\n", tmpbuf, end_msg);
+ }
+
+ free_actions (t);
+ t->step_count = 0; /* read_actions may set this */
+ read_actions (t);
+
+ if (readline_end_hook)
+ (*readline_end_hook) ();
+ /* tracepoints_changed () */
+ }
+ /* else just return */
+}
+
+/* worker function */
+static void
+read_actions (struct tracepoint *t)
+{
+ char *line;
+ char *prompt1 = "> ", *prompt2 = " > ";
+ char *prompt = prompt1;
+ enum actionline_type linetype;
+ extern FILE *instream;
+ struct action_line *next = NULL, *temp;
+ struct cleanup *old_chain;
+
+ /* Control-C quits instantly if typed while in this loop
+ since it should not wait until the user types a newline. */
+ immediate_quit++;
+ /* FIXME: kettenis/20010823: Something is wrong here. In this file
+ STOP_SIGNAL is never defined. So this code has been left out, at
+ least for quite a while now. Replacing STOP_SIGNAL with SIGTSTP
+ leads to compilation failures since the variable job_control
+ isn't declared. Leave this alone for now. */
+#ifdef STOP_SIGNAL
+ if (job_control)
+ {
+ if (event_loop_p)
+ signal (STOP_SIGNAL, handle_stop_sig);
+ else
+ signal (STOP_SIGNAL, stop_sig);
+ }
+#endif
+ old_chain = make_cleanup_free_actions (t);
+ while (1)
+ {
+ /* Make sure that all output has been output. Some machines may let
+ you get away with leaving out some of the gdb_flush, but not all. */
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+ gdb_flush (gdb_stderr);
+
+ if (readline_hook && instream == NULL)
+ line = (*readline_hook) (prompt);
+ else if (instream == stdin && ISATTY (instream))
+ {
+ line = readline (prompt);
+ if (line && *line) /* add it to command history */
+ add_history (line);
+ }
+ else
+ line = gdb_readline (0);
+
+ linetype = validate_actionline (&line, t);
+ if (linetype == BADLINE)
+ continue; /* already warned -- collect another line */
+
+ temp = xmalloc (sizeof (struct action_line));
+ temp->next = NULL;
+ temp->action = line;
+
+ if (next == NULL) /* first action for this tracepoint? */
+ t->actions = next = temp;
+ else
+ {
+ next->next = temp;
+ next = temp;
+ }
+
+ if (linetype == STEPPING) /* begin "while-stepping" */
+ {
+ if (prompt == prompt2)
+ {
+ warning ("Already processing 'while-stepping'");
+ continue;
+ }
+ else
+ prompt = prompt2; /* change prompt for stepping actions */
+ }
+ else if (linetype == END)
+ {
+ if (prompt == prompt2)
+ {
+ prompt = prompt1; /* end of single-stepping actions */
+ }
+ else
+ { /* end of actions */
+ if (t->actions->next == NULL)
+ {
+ /* an "end" all by itself with no other actions means
+ this tracepoint has no actions. Discard empty list. */
+ free_actions (t);
+ }
+ break;
+ }
+ }
+ }
+#ifdef STOP_SIGNAL
+ if (job_control)
+ signal (STOP_SIGNAL, SIG_DFL);
+#endif
+ immediate_quit--;
+ discard_cleanups (old_chain);
+}
+
+/* worker function */
+enum actionline_type
+validate_actionline (char **line, struct tracepoint *t)
+{
+ struct cmd_list_element *c;
+ struct expression *exp = NULL;
+ struct cleanup *old_chain = NULL;
+ char *p;
+
+ for (p = *line; isspace ((int) *p);)
+ p++;
+
+ /* symbol lookup etc. */
+ if (*p == '\0') /* empty line: just prompt for another line. */
+ return BADLINE;
+
+ if (*p == '#') /* comment line */
+ return GENERIC;
+
+ c = lookup_cmd (&p, cmdlist, "", -1, 1);
+ if (c == 0)
+ {
+ warning ("'%s' is not an action that I know, or is ambiguous.", p);
+ return BADLINE;
+ }
+
+ if (cmd_cfunc_eq (c, collect_pseudocommand))
+ {
+ struct agent_expr *aexpr;
+ struct agent_reqs areqs;
+
+ do
+ { /* repeat over a comma-separated list */
+ QUIT; /* allow user to bail out with ^C */
+ while (isspace ((int) *p))
+ p++;
+
+ if (*p == '$') /* look for special pseudo-symbols */
+ {
+ if ((0 == strncasecmp ("reg", p + 1, 3)) ||
+ (0 == strncasecmp ("arg", p + 1, 3)) ||
+ (0 == strncasecmp ("loc", p + 1, 3)))
+ {
+ p = strchr (p, ',');
+ continue;
+ }
+ /* else fall thru, treat p as an expression and parse it! */
+ }
+ exp = parse_exp_1 (&p, block_for_pc (t->address), 1);
+ old_chain = make_cleanup (free_current_contents, &exp);
+
+ if (exp->elts[0].opcode == OP_VAR_VALUE)
+ {
+ if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST)
+ {
+ warning ("constant %s (value %ld) will not be collected.",
+ SYMBOL_NAME (exp->elts[2].symbol),
+ SYMBOL_VALUE (exp->elts[2].symbol));
+ return BADLINE;
+ }
+ else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT)
+ {
+ warning ("%s is optimized away and cannot be collected.",
+ SYMBOL_NAME (exp->elts[2].symbol));
+ return BADLINE;
+ }
+ }
+
+ /* we have something to collect, make sure that the expr to
+ bytecode translator can handle it and that it's not too long */
+ aexpr = gen_trace_for_expr (t->address, exp);
+ make_cleanup_free_agent_expr (aexpr);
+
+ if (aexpr->len > MAX_AGENT_EXPR_LEN)
+ error ("expression too complicated, try simplifying");
+
+ ax_reqs (aexpr, &areqs);
+ (void) make_cleanup (xfree, areqs.reg_mask);
+
+ if (areqs.flaw != agent_flaw_none)
+ error ("malformed expression");
+
+ if (areqs.min_height < 0)
+ error ("gdb: Internal error: expression has min height < 0");
+
+ if (areqs.max_height > 20)
+ error ("expression too complicated, try simplifying");
+
+ do_cleanups (old_chain);
+ }
+ while (p && *p++ == ',');
+ return GENERIC;
+ }
+ else if (cmd_cfunc_eq (c, while_stepping_pseudocommand))
+ {
+ char *steparg; /* in case warning is necessary */
+
+ while (isspace ((int) *p))
+ p++;
+ steparg = p;
+
+ if (*p == '\0' ||
+ (t->step_count = strtol (p, &p, 0)) == 0)
+ {
+ warning ("'%s': bad step-count; command ignored.", *line);
+ return BADLINE;
+ }
+ return STEPPING;
+ }
+ else if (cmd_cfunc_eq (c, end_actions_pseudocommand))
+ return END;
+ else
+ {
+ warning ("'%s' is not a supported tracepoint action.", *line);
+ return BADLINE;
+ }
+}
+
+/* worker function */
+void
+free_actions (struct tracepoint *t)
+{
+ struct action_line *line, *next;
+
+ for (line = t->actions; line; line = next)
+ {
+ next = line->next;
+ if (line->action)
+ xfree (line->action);
+ xfree (line);
+ }
+ t->actions = NULL;
+}
+
+static void
+do_free_actions_cleanup (void *t)
+{
+ free_actions (t);
+}
+
+static struct cleanup *
+make_cleanup_free_actions (struct tracepoint *t)
+{
+ return make_cleanup (do_free_actions_cleanup, t);
+}
+
+struct memrange
+{
+ int type; /* 0 for absolute memory range, else basereg number */
+ bfd_signed_vma start;
+ bfd_signed_vma end;
+};
+
+struct collection_list
+ {
+ unsigned char regs_mask[8]; /* room for up to 256 regs */
+ long listsize;
+ long next_memrange;
+ struct memrange *list;
+ long aexpr_listsize; /* size of array pointed to by expr_list elt */
+ long next_aexpr_elt;
+ struct agent_expr **aexpr_list;
+
+ }
+tracepoint_list, stepping_list;
+
+/* MEMRANGE functions: */
+
+static int memrange_cmp (const void *, const void *);
+
+/* compare memranges for qsort */
+static int
+memrange_cmp (const void *va, const void *vb)
+{
+ const struct memrange *a = va, *b = vb;
+
+ if (a->type < b->type)
+ return -1;
+ if (a->type > b->type)
+ return 1;
+ if (a->type == 0)
+ {
+ if ((bfd_vma) a->start < (bfd_vma) b->start)
+ return -1;
+ if ((bfd_vma) a->start > (bfd_vma) b->start)
+ return 1;
+ }
+ else
+ {
+ if (a->start < b->start)
+ return -1;
+ if (a->start > b->start)
+ return 1;
+ }
+ return 0;
+}
+
+/* Sort the memrange list using qsort, and merge adjacent memranges */
+static void
+memrange_sortmerge (struct collection_list *memranges)
+{
+ int a, b;
+
+ qsort (memranges->list, memranges->next_memrange,
+ sizeof (struct memrange), memrange_cmp);
+ if (memranges->next_memrange > 0)
+ {
+ for (a = 0, b = 1; b < memranges->next_memrange; b++)
+ {
+ if (memranges->list[a].type == memranges->list[b].type &&
+ memranges->list[b].start - memranges->list[a].end <=
+ MAX_REGISTER_VIRTUAL_SIZE)
+ {
+ /* memrange b starts before memrange a ends; merge them. */
+ if (memranges->list[b].end > memranges->list[a].end)
+ memranges->list[a].end = memranges->list[b].end;
+ continue; /* next b, same a */
+ }
+ a++; /* next a */
+ if (a != b)
+ memcpy (&memranges->list[a], &memranges->list[b],
+ sizeof (struct memrange));
+ }
+ memranges->next_memrange = a + 1;
+ }
+}
+
+/* Add a register to a collection list */
+static void
+add_register (struct collection_list *collection, unsigned int regno)
+{
+ if (info_verbose)
+ printf_filtered ("collect register %d\n", regno);
+ if (regno > (8 * sizeof (collection->regs_mask)))
+ error ("Internal: register number %d too large for tracepoint",
+ regno);
+ collection->regs_mask[regno / 8] |= 1 << (regno % 8);
+}
+
+/* Add a memrange to a collection list */
+static void
+add_memrange (struct collection_list *memranges, int type, bfd_signed_vma base,
+ unsigned long len)
+{
+ if (info_verbose)
+ {
+ printf_filtered ("(%d,", type);
+ printf_vma (base);
+ printf_filtered (",%ld)\n", len);
+ }
+
+ /* type: 0 == memory, n == basereg */
+ memranges->list[memranges->next_memrange].type = type;
+ /* base: addr if memory, offset if reg relative. */
+ memranges->list[memranges->next_memrange].start = base;
+ /* len: we actually save end (base + len) for convenience */
+ memranges->list[memranges->next_memrange].end = base + len;
+ memranges->next_memrange++;
+ if (memranges->next_memrange >= memranges->listsize)
+ {
+ memranges->listsize *= 2;
+ memranges->list = xrealloc (memranges->list,
+ memranges->listsize);
+ }
+
+ if (type != -1) /* better collect the base register! */
+ add_register (memranges, type);
+}
+
+/* Add a symbol to a collection list */
+static void
+collect_symbol (struct collection_list *collect, struct symbol *sym,
+ long frame_regno, long frame_offset)
+{
+ unsigned long len;
+ unsigned int reg;
+ bfd_signed_vma offset;
+
+ len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
+ switch (SYMBOL_CLASS (sym))
+ {
+ default:
+ printf_filtered ("%s: don't know symbol class %d\n",
+ SYMBOL_NAME (sym), SYMBOL_CLASS (sym));
+ break;
+ case LOC_CONST:
+ printf_filtered ("constant %s (value %ld) will not be collected.\n",
+ SYMBOL_NAME (sym), SYMBOL_VALUE (sym));
+ break;
+ case LOC_STATIC:
+ offset = SYMBOL_VALUE_ADDRESS (sym);
+ if (info_verbose)
+ {
+ char tmp[40];
+
+ sprintf_vma (tmp, offset);
+ printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n",
+ SYMBOL_NAME (sym), len, tmp /* address */);
+ }
+ add_memrange (collect, -1, offset, len); /* 0 == memory */
+ break;
+ case LOC_REGISTER:
+ case LOC_REGPARM:
+ reg = SYMBOL_VALUE (sym);
+ if (info_verbose)
+ printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym));
+ add_register (collect, reg);
+ /* check for doubles stored in two registers */
+ /* FIXME: how about larger types stored in 3 or more regs? */
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FLT &&
+ len > REGISTER_RAW_SIZE (reg))
+ add_register (collect, reg + 1);
+ break;
+ case LOC_REF_ARG:
+ printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
+ printf_filtered (" (will not collect %s)\n",
+ SYMBOL_NAME (sym));
+ break;
+ case LOC_ARG:
+ reg = frame_regno;
+ offset = frame_offset + SYMBOL_VALUE (sym);
+ if (info_verbose)
+ {
+ printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
+ SYMBOL_NAME (sym), len);
+ printf_vma (offset);
+ printf_filtered (" from frame ptr reg %d\n", reg);
+ }
+ add_memrange (collect, reg, offset, len);
+ break;
+ case LOC_REGPARM_ADDR:
+ reg = SYMBOL_VALUE (sym);
+ offset = 0;
+ if (info_verbose)
+ {
+ printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset ",
+ SYMBOL_NAME (sym), len);
+ printf_vma (offset);
+ printf_filtered (" from reg %d\n", reg);
+ }
+ add_memrange (collect, reg, offset, len);
+ break;
+ case LOC_LOCAL:
+ case LOC_LOCAL_ARG:
+ reg = frame_regno;
+ offset = frame_offset + SYMBOL_VALUE (sym);
+ if (info_verbose)
+ {
+ printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
+ SYMBOL_NAME (sym), len);
+ printf_vma (offset);
+ printf_filtered (" from frame ptr reg %d\n", reg);
+ }
+ add_memrange (collect, reg, offset, len);
+ break;
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
+ reg = SYMBOL_BASEREG (sym);
+ offset = SYMBOL_VALUE (sym);
+ if (info_verbose)
+ {
+ printf_filtered ("LOC_BASEREG %s: collect %ld bytes at offset ",
+ SYMBOL_NAME (sym), len);
+ printf_vma (offset);
+ printf_filtered (" from basereg %d\n", reg);
+ }
+ add_memrange (collect, reg, offset, len);
+ break;
+ case LOC_UNRESOLVED:
+ printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym));
+ break;
+ case LOC_OPTIMIZED_OUT:
+ printf_filtered ("%s has been optimized out of existence.\n",
+ SYMBOL_NAME (sym));
+ break;
+ }
+}
+
+/* Add all locals (or args) symbols to collection list */
+static void
+add_local_symbols (struct collection_list *collect, CORE_ADDR pc,
+ long frame_regno, long frame_offset, int type)
+{
+ struct symbol *sym;
+ struct block *block;
+ int i, count = 0;
+
+ block = block_for_pc (pc);
+ while (block != 0)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ ALL_BLOCK_SYMBOLS (block, i, sym)
+ {
+ switch (SYMBOL_CLASS (sym))
+ {
+ default:
+ warning ("don't know how to trace local symbol %s",
+ SYMBOL_NAME (sym));
+ case LOC_LOCAL:
+ case LOC_STATIC:
+ case LOC_REGISTER:
+ case LOC_BASEREG:
+ if (type == 'L') /* collecting Locals */
+ {
+ count++;
+ collect_symbol (collect, sym, frame_regno, frame_offset);
+ }
+ break;
+ case LOC_ARG:
+ case LOC_LOCAL_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_BASEREG_ARG:
+ if (type == 'A') /* collecting Arguments */
+ {
+ count++;
+ collect_symbol (collect, sym, frame_regno, frame_offset);
+ }
+ }
+ }
+ if (BLOCK_FUNCTION (block))
+ break;
+ else
+ block = BLOCK_SUPERBLOCK (block);
+ }
+ if (count == 0)
+ warning ("No %s found in scope.", type == 'L' ? "locals" : "args");
+}
+
+/* worker function */
+static void
+clear_collection_list (struct collection_list *list)
+{
+ int ndx;
+
+ list->next_memrange = 0;
+ for (ndx = 0; ndx < list->next_aexpr_elt; ndx++)
+ {
+ free_agent_expr (list->aexpr_list[ndx]);
+ list->aexpr_list[ndx] = NULL;
+ }
+ list->next_aexpr_elt = 0;
+ memset (list->regs_mask, 0, sizeof (list->regs_mask));
+}
+
+/* reduce a collection list to string form (for gdb protocol) */
+static char **
+stringify_collection_list (struct collection_list *list, char *string)
+{
+ char temp_buf[2048];
+ char tmp2[40];
+ int count;
+ int ndx = 0;
+ char *(*str_list)[];
+ char *end;
+ long i;
+
+ count = 1 + list->next_memrange + list->next_aexpr_elt + 1;
+ str_list = (char *(*)[]) xmalloc (count * sizeof (char *));
+
+ for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
+ if (list->regs_mask[i] != 0) /* skip leading zeroes in regs_mask */
+ break;
+ if (list->regs_mask[i] != 0) /* prepare to send regs_mask to the stub */
+ {
+ if (info_verbose)
+ printf_filtered ("\nCollecting registers (mask): 0x");
+ end = temp_buf;
+ *end++ = 'R';
+ for (; i >= 0; i--)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ if (info_verbose)
+ printf_filtered ("%02X", list->regs_mask[i]);
+ sprintf (end, "%02X", list->regs_mask[i]);
+ end += 2;
+ }
+ (*str_list)[ndx] = savestring (temp_buf, end - temp_buf);
+ ndx++;
+ }
+ if (info_verbose)
+ printf_filtered ("\n");
+ if (list->next_memrange > 0 && info_verbose)
+ printf_filtered ("Collecting memranges: \n");
+ for (i = 0, count = 0, end = temp_buf; i < list->next_memrange; i++)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ sprintf_vma (tmp2, list->list[i].start);
+ if (info_verbose)
+ {
+ printf_filtered ("(%d, %s, %ld)\n",
+ list->list[i].type,
+ tmp2,
+ (long) (list->list[i].end - list->list[i].start));
+ }
+ if (count + 27 > MAX_AGENT_EXPR_LEN)
+ {
+ (*str_list)[ndx] = savestring (temp_buf, count);
+ ndx++;
+ count = 0;
+ end = temp_buf;
+ }
+
+ sprintf (end, "M%X,%s,%lX",
+ list->list[i].type,
+ tmp2,
+ (long) (list->list[i].end - list->list[i].start));
+
+ count += strlen (end);
+ end += count;
+ }
+
+ for (i = 0; i < list->next_aexpr_elt; i++)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ if ((count + 10 + 2 * list->aexpr_list[i]->len) > MAX_AGENT_EXPR_LEN)
+ {
+ (*str_list)[ndx] = savestring (temp_buf, count);
+ ndx++;
+ count = 0;
+ end = temp_buf;
+ }
+ sprintf (end, "X%08X,", list->aexpr_list[i]->len);
+ end += 10; /* 'X' + 8 hex digits + ',' */
+ count += 10;
+
+ end = mem2hex (list->aexpr_list[i]->buf, end, list->aexpr_list[i]->len);
+ count += 2 * list->aexpr_list[i]->len;
+ }
+
+ if (count != 0)
+ {
+ (*str_list)[ndx] = savestring (temp_buf, count);
+ ndx++;
+ count = 0;
+ end = temp_buf;
+ }
+ (*str_list)[ndx] = NULL;
+
+ if (ndx == 0)
+ return NULL;
+ else
+ return *str_list;
+}
+
+static void
+free_actions_list_cleanup_wrapper (void *al)
+{
+ free_actions_list (al);
+}
+
+static void
+free_actions_list (char **actions_list)
+{
+ int ndx;
+
+ if (actions_list == 0)
+ return;
+
+ for (ndx = 0; actions_list[ndx]; ndx++)
+ xfree (actions_list[ndx]);
+
+ xfree (actions_list);
+}
+
+/* render all actions into gdb protocol */
+static void
+encode_actions (struct tracepoint *t, char ***tdp_actions,
+ char ***stepping_actions)
+{
+ static char tdp_buff[2048], step_buff[2048];
+ char *action_exp;
+ struct expression *exp = NULL;
+ struct action_line *action;
+ int i;
+ struct value *tempval;
+ struct collection_list *collect;
+ struct cmd_list_element *cmd;
+ struct agent_expr *aexpr;
+ int frame_reg;
+ LONGEST frame_offset;
+
+
+ clear_collection_list (&tracepoint_list);
+ clear_collection_list (&stepping_list);
+ collect = &tracepoint_list;
+
+ *tdp_actions = NULL;
+ *stepping_actions = NULL;
+
+ TARGET_VIRTUAL_FRAME_POINTER (t->address, &frame_reg, &frame_offset);
+
+ for (action = t->actions; action; action = action->next)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ action_exp = action->action;
+ while (isspace ((int) *action_exp))
+ action_exp++;
+
+ if (*action_exp == '#') /* comment line */
+ return;
+
+ cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
+ if (cmd == 0)
+ error ("Bad action list item: %s", action_exp);
+
+ if (cmd_cfunc_eq (cmd, collect_pseudocommand))
+ {
+ do
+ { /* repeat over a comma-separated list */
+ QUIT; /* allow user to bail out with ^C */
+ while (isspace ((int) *action_exp))
+ action_exp++;
+
+ if (0 == strncasecmp ("$reg", action_exp, 4))
+ {
+ for (i = 0; i < NUM_REGS; i++)
+ add_register (collect, i);
+ action_exp = strchr (action_exp, ','); /* more? */
+ }
+ else if (0 == strncasecmp ("$arg", action_exp, 4))
+ {
+ add_local_symbols (collect,
+ t->address,
+ frame_reg,
+ frame_offset,
+ 'A');
+ action_exp = strchr (action_exp, ','); /* more? */
+ }
+ else if (0 == strncasecmp ("$loc", action_exp, 4))
+ {
+ add_local_symbols (collect,
+ t->address,
+ frame_reg,
+ frame_offset,
+ 'L');
+ action_exp = strchr (action_exp, ','); /* more? */
+ }
+ else
+ {
+ unsigned long addr, len;
+ struct cleanup *old_chain = NULL;
+ struct cleanup *old_chain1 = NULL;
+ struct agent_reqs areqs;
+
+ exp = parse_exp_1 (&action_exp,
+ block_for_pc (t->address), 1);
+ old_chain = make_cleanup (free_current_contents, &exp);
+
+ switch (exp->elts[0].opcode)
+ {
+ case OP_REGISTER:
+ i = exp->elts[1].longconst;
+ if (info_verbose)
+ printf_filtered ("OP_REGISTER: ");
+ add_register (collect, i);
+ break;
+
+ case UNOP_MEMVAL:
+ /* safe because we know it's a simple expression */
+ tempval = evaluate_expression (exp);
+ addr = VALUE_ADDRESS (tempval) + VALUE_OFFSET (tempval);
+ len = TYPE_LENGTH (check_typedef (exp->elts[1].type));
+ add_memrange (collect, -1, addr, len);
+ break;
+
+ case OP_VAR_VALUE:
+ collect_symbol (collect,
+ exp->elts[2].symbol,
+ frame_reg,
+ frame_offset);
+ break;
+
+ default: /* full-fledged expression */
+ aexpr = gen_trace_for_expr (t->address, exp);
+
+ old_chain1 = make_cleanup_free_agent_expr (aexpr);
+
+ ax_reqs (aexpr, &areqs);
+ if (areqs.flaw != agent_flaw_none)
+ error ("malformed expression");
+
+ if (areqs.min_height < 0)
+ error ("gdb: Internal error: expression has min height < 0");
+ if (areqs.max_height > 20)
+ error ("expression too complicated, try simplifying");
+
+ discard_cleanups (old_chain1);
+ add_aexpr (collect, aexpr);
+
+ /* take care of the registers */
+ if (areqs.reg_mask_len > 0)
+ {
+ int ndx1;
+ int ndx2;
+
+ for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ if (areqs.reg_mask[ndx1] != 0)
+ {
+ /* assume chars have 8 bits */
+ for (ndx2 = 0; ndx2 < 8; ndx2++)
+ if (areqs.reg_mask[ndx1] & (1 << ndx2))
+ /* it's used -- record it */
+ add_register (collect, ndx1 * 8 + ndx2);
+ }
+ }
+ }
+ break;
+ } /* switch */
+ do_cleanups (old_chain);
+ } /* do */
+ }
+ while (action_exp && *action_exp++ == ',');
+ } /* if */
+ else if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
+ {
+ collect = &stepping_list;
+ }
+ else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
+ {
+ if (collect == &stepping_list) /* end stepping actions */
+ collect = &tracepoint_list;
+ else
+ break; /* end tracepoint actions */
+ }
+ } /* for */
+ memrange_sortmerge (&tracepoint_list);
+ memrange_sortmerge (&stepping_list);
+
+ *tdp_actions = stringify_collection_list (&tracepoint_list, tdp_buff);
+ *stepping_actions = stringify_collection_list (&stepping_list, step_buff);
+}
+
+static void
+add_aexpr (struct collection_list *collect, struct agent_expr *aexpr)
+{
+ if (collect->next_aexpr_elt >= collect->aexpr_listsize)
+ {
+ collect->aexpr_list =
+ xrealloc (collect->aexpr_list,
+ 2 * collect->aexpr_listsize * sizeof (struct agent_expr *));
+ collect->aexpr_listsize *= 2;
+ }
+ collect->aexpr_list[collect->next_aexpr_elt] = aexpr;
+ collect->next_aexpr_elt++;
+}
+
+static char target_buf[2048];
+
+/* Set "transparent" memory ranges
+
+ Allow trace mechanism to treat text-like sections
+ (and perhaps all read-only sections) transparently,
+ i.e. don't reject memory requests from these address ranges
+ just because they haven't been collected. */
+
+static void
+remote_set_transparent_ranges (void)
+{
+ extern bfd *exec_bfd;
+ asection *s;
+ bfd_size_type size;
+ bfd_vma lma;
+ int anysecs = 0;
+
+ if (!exec_bfd)
+ return; /* no information to give. */
+
+ strcpy (target_buf, "QTro");
+ for (s = exec_bfd->sections; s; s = s->next)
+ {
+ char tmp1[40], tmp2[40];
+
+ if ((s->flags & SEC_LOAD) == 0 ||
+ /* (s->flags & SEC_CODE) == 0 || */
+ (s->flags & SEC_READONLY) == 0)
+ continue;
+
+ anysecs = 1;
+ lma = s->lma;
+ size = bfd_get_section_size_before_reloc (s);
+ sprintf_vma (tmp1, lma);
+ sprintf_vma (tmp2, lma + size);
+ sprintf (target_buf + strlen (target_buf),
+ ":%s,%s", tmp1, tmp2);
+ }
+ if (anysecs)
+ {
+ putpkt (target_buf);
+ getpkt (target_buf, sizeof (target_buf), 0);
+ }
+}
+
+/* tstart command:
+
+ Tell target to clear any previous trace experiment.
+ Walk the list of tracepoints, and send them (and their actions)
+ to the target. If no errors,
+ Tell target to start a new trace experiment. */
+
+static void
+trace_start_command (char *args, int from_tty)
+{ /* STUB_COMM MOSTLY_IMPLEMENTED */
+ struct tracepoint *t;
+ char buf[2048];
+ char **tdp_actions;
+ char **stepping_actions;
+ int ndx;
+ struct cleanup *old_chain = NULL;
+
+ dont_repeat (); /* like "run", dangerous to repeat accidentally */
+
+ if (target_is_remote ())
+ {
+ putpkt ("QTinit");
+ remote_get_noisy_reply (target_buf, sizeof (target_buf));
+ if (strcmp (target_buf, "OK"))
+ error ("Target does not support this command.");
+
+ ALL_TRACEPOINTS (t)
+ {
+ char tmp[40];
+
+ sprintf_vma (tmp, t->address);
+ sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", t->number, tmp, /* address */
+ t->enabled_p ? 'E' : 'D',
+ t->step_count, t->pass_count);
+
+ if (t->actions)
+ strcat (buf, "-");
+ putpkt (buf);
+ remote_get_noisy_reply (target_buf, sizeof (target_buf));
+ if (strcmp (target_buf, "OK"))
+ error ("Target does not support tracepoints.");
+
+ if (t->actions)
+ {
+ encode_actions (t, &tdp_actions, &stepping_actions);
+ old_chain = make_cleanup (free_actions_list_cleanup_wrapper,
+ tdp_actions);
+ (void) make_cleanup (free_actions_list_cleanup_wrapper,
+ stepping_actions);
+
+ /* do_single_steps (t); */
+ if (tdp_actions)
+ {
+ for (ndx = 0; tdp_actions[ndx]; ndx++)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ sprintf (buf, "QTDP:-%x:%s:%s%c",
+ t->number, tmp, /* address */
+ tdp_actions[ndx],
+ ((tdp_actions[ndx + 1] || stepping_actions)
+ ? '-' : 0));
+ putpkt (buf);
+ remote_get_noisy_reply (target_buf, sizeof (target_buf));
+ if (strcmp (target_buf, "OK"))
+ error ("Error on target while setting tracepoints.");
+ }
+ }
+ if (stepping_actions)
+ {
+ for (ndx = 0; stepping_actions[ndx]; ndx++)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ sprintf (buf, "QTDP:-%x:%s:%s%s%s",
+ t->number, tmp, /* address */
+ ((ndx == 0) ? "S" : ""),
+ stepping_actions[ndx],
+ (stepping_actions[ndx + 1] ? "-" : ""));
+ putpkt (buf);
+ remote_get_noisy_reply (target_buf, sizeof (target_buf));
+ if (strcmp (target_buf, "OK"))
+ error ("Error on target while setting tracepoints.");
+ }
+ }
+
+ do_cleanups (old_chain);
+ }
+ }
+ /* Tell target to treat text-like sections as transparent */
+ remote_set_transparent_ranges ();
+ /* Now insert traps and begin collecting data */
+ putpkt ("QTStart");
+ remote_get_noisy_reply (target_buf, sizeof (target_buf));
+ if (strcmp (target_buf, "OK"))
+ error ("Bogus reply from target: %s", target_buf);
+ set_traceframe_num (-1); /* all old traceframes invalidated */
+ set_tracepoint_num (-1);
+ set_traceframe_context (-1);
+ trace_running_p = 1;
+ if (trace_start_stop_hook)
+ trace_start_stop_hook (1, from_tty);
+
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* tstop command */
+static void
+trace_stop_command (char *args, int from_tty)
+{ /* STUB_COMM IS_IMPLEMENTED */
+ if (target_is_remote ())
+ {
+ putpkt ("QTStop");
+ remote_get_noisy_reply (target_buf, sizeof (target_buf));
+ if (strcmp (target_buf, "OK"))
+ error ("Bogus reply from target: %s", target_buf);
+ trace_running_p = 0;
+ if (trace_start_stop_hook)
+ trace_start_stop_hook (0, from_tty);
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+unsigned long trace_running_p;
+
+/* tstatus command */
+static void
+trace_status_command (char *args, int from_tty)
+{ /* STUB_COMM IS_IMPLEMENTED */
+ if (target_is_remote ())
+ {
+ putpkt ("qTStatus");
+ remote_get_noisy_reply (target_buf, sizeof (target_buf));
+
+ if (target_buf[0] != 'T' ||
+ (target_buf[1] != '0' && target_buf[1] != '1'))
+ error ("Bogus reply from target: %s", target_buf);
+
+ /* exported for use by the GUI */
+ trace_running_p = (target_buf[1] == '1');
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* Worker function for the various flavors of the tfind command */
+static void
+finish_tfind_command (char *msg,
+ long sizeof_msg,
+ int from_tty)
+{
+ int target_frameno = -1, target_tracept = -1;
+ CORE_ADDR old_frame_addr;
+ struct symbol *old_func;
+ char *reply;
+
+ old_frame_addr = FRAME_FP (get_current_frame ());
+ old_func = find_pc_function (read_pc ());
+
+ putpkt (msg);
+ reply = remote_get_noisy_reply (msg, sizeof_msg);
+
+ while (reply && *reply)
+ switch (*reply)
+ {
+ case 'F':
+ if ((target_frameno = (int) strtol (++reply, &reply, 16)) == -1)
+ {
+ /* A request for a non-existant trace frame has failed.
+ Our response will be different, depending on FROM_TTY:
+
+ If FROM_TTY is true, meaning that this command was
+ typed interactively by the user, then give an error
+ and DO NOT change the state of traceframe_number etc.
+
+ However if FROM_TTY is false, meaning that we're either
+ in a script, a loop, or a user-defined command, then
+ DON'T give an error, but DO change the state of
+ traceframe_number etc. to invalid.
+
+ The rationalle is that if you typed the command, you
+ might just have committed a typo or something, and you'd
+ like to NOT lose your current debugging state. However
+ if you're in a user-defined command or especially in a
+ loop, then you need a way to detect that the command
+ failed WITHOUT aborting. This allows you to write
+ scripts that search thru the trace buffer until the end,
+ and then continue on to do something else. */
+
+ if (from_tty)
+ error ("Target failed to find requested trace frame.");
+ else
+ {
+ if (info_verbose)
+ printf_filtered ("End of trace buffer.\n");
+ /* The following will not recurse, since it's special-cased */
+ trace_find_command ("-1", from_tty);
+ reply = NULL; /* break out of loop,
+ (avoid recursive nonsense) */
+ }
+ }
+ break;
+ case 'T':
+ if ((target_tracept = (int) strtol (++reply, &reply, 16)) == -1)
+ error ("Target failed to find requested trace frame.");
+ break;
+ case 'O': /* "OK"? */
+ if (reply[1] == 'K' && reply[2] == '\0')
+ reply += 2;
+ else
+ error ("Bogus reply from target: %s", reply);
+ break;
+ default:
+ error ("Bogus reply from target: %s", reply);
+ }
+
+ flush_cached_frames ();
+ registers_changed ();
+ select_frame (get_current_frame ());
+ set_traceframe_num (target_frameno);
+ set_tracepoint_num (target_tracept);
+ if (target_frameno == -1)
+ set_traceframe_context (-1);
+ else
+ set_traceframe_context (read_pc ());
+
+ if (from_tty)
+ {
+ int source_only;
+
+ /* NOTE: in immitation of the step command, try to determine
+ whether we have made a transition from one function to another.
+ If so, we'll print the "stack frame" (ie. the new function and
+ it's arguments) -- otherwise we'll just show the new source line.
+
+ This determination is made by checking (1) whether the current
+ function has changed, and (2) whether the current FP has changed.
+ Hack: if the FP wasn't collected, either at the current or the
+ previous frame, assume that the FP has NOT changed. */
+
+ if (old_func == find_pc_function (read_pc ()) &&
+ (old_frame_addr == 0 ||
+ FRAME_FP (get_current_frame ()) == 0 ||
+ old_frame_addr == FRAME_FP (get_current_frame ())))
+ source_only = -1;
+ else
+ source_only = 1;
+
+ print_stack_frame (selected_frame, frame_relative_level (selected_frame),
+ source_only);
+ do_displays ();
+ }
+}
+
+/* trace_find_command takes a trace frame number n,
+ sends "QTFrame:<n>" to the target,
+ and accepts a reply that may contain several optional pieces
+ of information: a frame number, a tracepoint number, and an
+ indication of whether this is a trap frame or a stepping frame.
+
+ The minimal response is just "OK" (which indicates that the
+ target does not give us a frame number or a tracepoint number).
+ Instead of that, the target may send us a string containing
+ any combination of:
+ F<hexnum> (gives the selected frame number)
+ T<hexnum> (gives the selected tracepoint number)
+ */
+
+/* tfind command */
+static void
+trace_find_command (char *args, int from_tty)
+{ /* STUB_COMM PART_IMPLEMENTED */
+ /* this should only be called with a numeric argument */
+ int frameno = -1;
+
+ if (target_is_remote ())
+ {
+ if (trace_find_hook)
+ trace_find_hook (args, from_tty);
+
+ if (args == 0 || *args == 0)
+ { /* TFIND with no args means find NEXT trace frame. */
+ if (traceframe_number == -1)
+ frameno = 0; /* "next" is first one */
+ else
+ frameno = traceframe_number + 1;
+ }
+ else if (0 == strcmp (args, "-"))
+ {
+ if (traceframe_number == -1)
+ error ("not debugging trace buffer");
+ else if (from_tty && traceframe_number == 0)
+ error ("already at start of trace buffer");
+
+ frameno = traceframe_number - 1;
+ }
+ else
+ frameno = parse_and_eval_long (args);
+
+ if (frameno < -1)
+ error ("invalid input (%d is less than zero)", frameno);
+
+ sprintf (target_buf, "QTFrame:%x", frameno);
+ finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* tfind end */
+static void
+trace_find_end_command (char *args, int from_tty)
+{
+ trace_find_command ("-1", from_tty);
+}
+
+/* tfind none */
+static void
+trace_find_none_command (char *args, int from_tty)
+{
+ trace_find_command ("-1", from_tty);
+}
+
+/* tfind start */
+static void
+trace_find_start_command (char *args, int from_tty)
+{
+ trace_find_command ("0", from_tty);
+}
+
+/* tfind pc command */
+static void
+trace_find_pc_command (char *args, int from_tty)
+{ /* STUB_COMM PART_IMPLEMENTED */
+ CORE_ADDR pc;
+ char tmp[40];
+
+ if (target_is_remote ())
+ {
+ if (args == 0 || *args == 0)
+ pc = read_pc (); /* default is current pc */
+ else
+ pc = parse_and_eval_address (args);
+
+ sprintf_vma (tmp, pc);
+ sprintf (target_buf, "QTFrame:pc:%s", tmp);
+ finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* tfind tracepoint command */
+static void
+trace_find_tracepoint_command (char *args, int from_tty)
+{ /* STUB_COMM PART_IMPLEMENTED */
+ int tdp;
+
+ if (target_is_remote ())
+ {
+ if (args == 0 || *args == 0)
+ if (tracepoint_number == -1)
+ error ("No current tracepoint -- please supply an argument.");
+ else
+ tdp = tracepoint_number; /* default is current TDP */
+ else
+ tdp = parse_and_eval_long (args);
+
+ sprintf (target_buf, "QTFrame:tdp:%x", tdp);
+ finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* TFIND LINE command:
+
+ This command will take a sourceline for argument, just like BREAK
+ or TRACE (ie. anything that "decode_line_1" can handle).
+
+ With no argument, this command will find the next trace frame
+ corresponding to a source line OTHER THAN THE CURRENT ONE. */
+
+static void
+trace_find_line_command (char *args, int from_tty)
+{ /* STUB_COMM PART_IMPLEMENTED */
+ static CORE_ADDR start_pc, end_pc;
+ struct symtabs_and_lines sals;
+ struct symtab_and_line sal;
+ struct cleanup *old_chain;
+ char startpc_str[40], endpc_str[40];
+
+ if (target_is_remote ())
+ {
+ if (args == 0 || *args == 0)
+ {
+ sal = find_pc_line ((get_current_frame ())->pc, 0);
+ sals.nelts = 1;
+ sals.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ sals.sals[0] = sal;
+ }
+ else
+ {
+ sals = decode_line_spec (args, 1);
+ sal = sals.sals[0];
+ }
+
+ old_chain = make_cleanup (xfree, sals.sals);
+ if (sal.symtab == 0)
+ {
+ printf_filtered ("TFIND: No line number information available");
+ if (sal.pc != 0)
+ {
+ /* This is useful for "info line *0x7f34". If we can't tell the
+ user about a source line, at least let them have the symbolic
+ address. */
+ printf_filtered (" for address ");
+ wrap_here (" ");
+ print_address (sal.pc, gdb_stdout);
+ printf_filtered (";\n -- will attempt to find by PC. \n");
+ }
+ else
+ {
+ printf_filtered (".\n");
+ return; /* no line, no PC; what can we do? */
+ }
+ }
+ else if (sal.line > 0
+ && find_line_pc_range (sal, &start_pc, &end_pc))
+ {
+ if (start_pc == end_pc)
+ {
+ printf_filtered ("Line %d of \"%s\"",
+ sal.line, sal.symtab->filename);
+ wrap_here (" ");
+ printf_filtered (" is at address ");
+ print_address (start_pc, gdb_stdout);
+ wrap_here (" ");
+ printf_filtered (" but contains no code.\n");
+ sal = find_pc_line (start_pc, 0);
+ if (sal.line > 0 &&
+ find_line_pc_range (sal, &start_pc, &end_pc) &&
+ start_pc != end_pc)
+ printf_filtered ("Attempting to find line %d instead.\n",
+ sal.line);
+ else
+ error ("Cannot find a good line.");
+ }
+ }
+ else
+ /* Is there any case in which we get here, and have an address
+ which the user would want to see? If we have debugging symbols
+ and no line numbers? */
+ error ("Line number %d is out of range for \"%s\".\n",
+ sal.line, sal.symtab->filename);
+
+ sprintf_vma (startpc_str, start_pc);
+ sprintf_vma (endpc_str, end_pc - 1);
+ if (args && *args) /* find within range of stated line */
+ sprintf (target_buf, "QTFrame:range:%s:%s", startpc_str, endpc_str);
+ else /* find OUTSIDE OF range of CURRENT line */
+ sprintf (target_buf, "QTFrame:outside:%s:%s", startpc_str, endpc_str);
+ finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+ do_cleanups (old_chain);
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* tfind range command */
+static void
+trace_find_range_command (char *args, int from_tty)
+{
+ static CORE_ADDR start, stop;
+ char start_str[40], stop_str[40];
+ char *tmp;
+
+ if (target_is_remote ())
+ {
+ if (args == 0 || *args == 0)
+ { /* XXX FIXME: what should default behavior be? */
+ printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
+ return;
+ }
+
+ if (0 != (tmp = strchr (args, ',')))
+ {
+ *tmp++ = '\0'; /* terminate start address */
+ while (isspace ((int) *tmp))
+ tmp++;
+ start = parse_and_eval_address (args);
+ stop = parse_and_eval_address (tmp);
+ }
+ else
+ { /* no explicit end address? */
+ start = parse_and_eval_address (args);
+ stop = start + 1; /* ??? */
+ }
+
+ sprintf_vma (start_str, start);
+ sprintf_vma (stop_str, stop);
+ sprintf (target_buf, "QTFrame:range:%s:%s", start_str, stop_str);
+ finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* tfind outside command */
+static void
+trace_find_outside_command (char *args, int from_tty)
+{
+ CORE_ADDR start, stop;
+ char start_str[40], stop_str[40];
+ char *tmp;
+
+ if (target_is_remote ())
+ {
+ if (args == 0 || *args == 0)
+ { /* XXX FIXME: what should default behavior be? */
+ printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
+ return;
+ }
+
+ if (0 != (tmp = strchr (args, ',')))
+ {
+ *tmp++ = '\0'; /* terminate start address */
+ while (isspace ((int) *tmp))
+ tmp++;
+ start = parse_and_eval_address (args);
+ stop = parse_and_eval_address (tmp);
+ }
+ else
+ { /* no explicit end address? */
+ start = parse_and_eval_address (args);
+ stop = start + 1; /* ??? */
+ }
+
+ sprintf_vma (start_str, start);
+ sprintf_vma (stop_str, stop);
+ sprintf (target_buf, "QTFrame:outside:%s:%s", start_str, stop_str);
+ finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+ }
+ else
+ error ("Trace can only be run on remote targets.");
+}
+
+/* save-tracepoints command */
+static void
+tracepoint_save_command (char *args, int from_tty)
+{
+ struct tracepoint *tp;
+ struct action_line *line;
+ FILE *fp;
+ char *i1 = " ", *i2 = " ";
+ char *indent, *actionline, *pathname;
+ char tmp[40];
+
+ if (args == 0 || *args == 0)
+ error ("Argument required (file name in which to save tracepoints");
+
+ if (tracepoint_chain == 0)
+ {
+ warning ("save-tracepoints: no tracepoints to save.\n");
+ return;
+ }
+
+ pathname = tilde_expand (args);
+ if (!(fp = fopen (pathname, "w")))
+ error ("Unable to open file '%s' for saving tracepoints (%s)",
+ args, safe_strerror (errno));
+ xfree (pathname);
+
+ ALL_TRACEPOINTS (tp)
+ {
+ if (tp->addr_string)
+ fprintf (fp, "trace %s\n", tp->addr_string);
+ else
+ {
+ sprintf_vma (tmp, tp->address);
+ fprintf (fp, "trace *0x%s\n", tmp);
+ }
+
+ if (tp->pass_count)
+ fprintf (fp, " passcount %d\n", tp->pass_count);
+
+ if (tp->actions)
+ {
+ fprintf (fp, " actions\n");
+ indent = i1;
+ for (line = tp->actions; line; line = line->next)
+ {
+ struct cmd_list_element *cmd;
+
+ QUIT; /* allow user to bail out with ^C */
+ actionline = line->action;
+ while (isspace ((int) *actionline))
+ actionline++;
+
+ fprintf (fp, "%s%s\n", indent, actionline);
+ if (*actionline != '#') /* skip for comment lines */
+ {
+ cmd = lookup_cmd (&actionline, cmdlist, "", -1, 1);
+ if (cmd == 0)
+ error ("Bad action list item: %s", actionline);
+ if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
+ indent = i2;
+ else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
+ indent = i1;
+ }
+ }
+ }
+ }
+ fclose (fp);
+ if (from_tty)
+ printf_filtered ("Tracepoints saved to file '%s'.\n", args);
+ return;
+}
+
+/* info scope command: list the locals for a scope. */
+static void
+scope_info (char *args, int from_tty)
+{
+ struct symtabs_and_lines sals;
+ struct symbol *sym;
+ struct minimal_symbol *msym;
+ struct block *block;
+ char **canonical, *symname, *save_args = args;
+ int i, j, count = 0;
+
+ if (args == 0 || *args == 0)
+ error ("requires an argument (function, line or *addr) to define a scope");
+
+ sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
+ if (sals.nelts == 0)
+ return; /* presumably decode_line_1 has already warned */
+
+ /* Resolve line numbers to PC */
+ resolve_sal_pc (&sals.sals[0]);
+ block = block_for_pc (sals.sals[0].pc);
+
+ while (block != 0)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ ALL_BLOCK_SYMBOLS (block, i, sym)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ if (count == 0)
+ printf_filtered ("Scope for %s:\n", save_args);
+ count++;
+
+ symname = SYMBOL_NAME (sym);
+ if (symname == NULL || *symname == '\0')
+ continue; /* probably botched, certainly useless */
+
+ printf_filtered ("Symbol %s is ", symname);
+ switch (SYMBOL_CLASS (sym))
+ {
+ default:
+ case LOC_UNDEF: /* messed up symbol? */
+ printf_filtered ("a bogus symbol, class %d.\n",
+ SYMBOL_CLASS (sym));
+ count--; /* don't count this one */
+ continue;
+ case LOC_CONST:
+ printf_filtered ("a constant with value %ld (0x%lx)",
+ SYMBOL_VALUE (sym), SYMBOL_VALUE (sym));
+ break;
+ case LOC_CONST_BYTES:
+ printf_filtered ("constant bytes: ");
+ if (SYMBOL_TYPE (sym))
+ for (j = 0; j < TYPE_LENGTH (SYMBOL_TYPE (sym)); j++)
+ fprintf_filtered (gdb_stdout, " %02x",
+ (unsigned) SYMBOL_VALUE_BYTES (sym)[j]);
+ break;
+ case LOC_STATIC:
+ printf_filtered ("in static storage at address ");
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
+ break;
+ case LOC_REGISTER:
+ printf_filtered ("a local variable in register $%s",
+ REGISTER_NAME (SYMBOL_VALUE (sym)));
+ break;
+ case LOC_ARG:
+ case LOC_LOCAL_ARG:
+ printf_filtered ("an argument at stack/frame offset %ld",
+ SYMBOL_VALUE (sym));
+ break;
+ case LOC_LOCAL:
+ printf_filtered ("a local variable at frame offset %ld",
+ SYMBOL_VALUE (sym));
+ break;
+ case LOC_REF_ARG:
+ printf_filtered ("a reference argument at offset %ld",
+ SYMBOL_VALUE (sym));
+ break;
+ case LOC_REGPARM:
+ printf_filtered ("an argument in register $%s",
+ REGISTER_NAME (SYMBOL_VALUE (sym)));
+ break;
+ case LOC_REGPARM_ADDR:
+ printf_filtered ("the address of an argument, in register $%s",
+ REGISTER_NAME (SYMBOL_VALUE (sym)));
+ break;
+ case LOC_TYPEDEF:
+ printf_filtered ("a typedef.\n");
+ continue;
+ case LOC_LABEL:
+ printf_filtered ("a label at address ");
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
+ break;
+ case LOC_BLOCK:
+ printf_filtered ("a function at address ");
+ print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), 1,
+ gdb_stdout);
+ break;
+ case LOC_BASEREG:
+ printf_filtered ("a variable at offset %ld from register $%s",
+ SYMBOL_VALUE (sym),
+ REGISTER_NAME (SYMBOL_BASEREG (sym)));
+ break;
+ case LOC_BASEREG_ARG:
+ printf_filtered ("an argument at offset %ld from register $%s",
+ SYMBOL_VALUE (sym),
+ REGISTER_NAME (SYMBOL_BASEREG (sym)));
+ break;
+ case LOC_UNRESOLVED:
+ msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, NULL);
+ if (msym == NULL)
+ printf_filtered ("Unresolved Static");
+ else
+ {
+ printf_filtered ("static storage at address ");
+ print_address_numeric (SYMBOL_VALUE_ADDRESS (msym), 1,
+ gdb_stdout);
+ }
+ break;
+ case LOC_OPTIMIZED_OUT:
+ printf_filtered ("optimized out.\n");
+ continue;
+ }
+ if (SYMBOL_TYPE (sym))
+ printf_filtered (", length %d.\n",
+ TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
+ }
+ if (BLOCK_FUNCTION (block))
+ break;
+ else
+ block = BLOCK_SUPERBLOCK (block);
+ }
+ if (count <= 0)
+ printf_filtered ("Scope for %s contains no locals or arguments.\n",
+ save_args);
+}
+
+/* worker function (cleanup) */
+static void
+replace_comma (void *data)
+{
+ char *comma = data;
+ *comma = ',';
+}
+
+/* tdump command */
+static void
+trace_dump_command (char *args, int from_tty)
+{
+ struct tracepoint *t;
+ struct action_line *action;
+ char *action_exp, *next_comma;
+ struct cleanup *old_cleanups;
+ int stepping_actions = 0;
+ int stepping_frame = 0;
+
+ if (!target_is_remote ())
+ {
+ error ("Trace can only be run on remote targets.");
+ return;
+ }
+
+ if (tracepoint_number == -1)
+ {
+ warning ("No current trace frame.");
+ return;
+ }
+
+ ALL_TRACEPOINTS (t)
+ if (t->number == tracepoint_number)
+ break;
+
+ if (t == NULL)
+ error ("No known tracepoint matches 'current' tracepoint #%d.",
+ tracepoint_number);
+
+ old_cleanups = make_cleanup (null_cleanup, NULL);
+
+ printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
+ tracepoint_number, traceframe_number);
+
+ /* The current frame is a trap frame if the frame PC is equal
+ to the tracepoint PC. If not, then the current frame was
+ collected during single-stepping. */
+
+ stepping_frame = (t->address != read_pc ());
+
+ for (action = t->actions; action; action = action->next)
+ {
+ struct cmd_list_element *cmd;
+
+ QUIT; /* allow user to bail out with ^C */
+ action_exp = action->action;
+ while (isspace ((int) *action_exp))
+ action_exp++;
+
+ /* The collection actions to be done while stepping are
+ bracketed by the commands "while-stepping" and "end". */
+
+ if (*action_exp == '#') /* comment line */
+ continue;
+
+ cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
+ if (cmd == 0)
+ error ("Bad action list item: %s", action_exp);
+
+ if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
+ stepping_actions = 1;
+ else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
+ stepping_actions = 0;
+ else if (cmd_cfunc_eq (cmd, collect_pseudocommand))
+ {
+ /* Display the collected data.
+ For the trap frame, display only what was collected at the trap.
+ Likewise for stepping frames, display only what was collected
+ while stepping. This means that the two boolean variables,
+ STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
+ if (stepping_frame == stepping_actions)
+ {
+ do
+ { /* repeat over a comma-separated list */
+ QUIT; /* allow user to bail out with ^C */
+ if (*action_exp == ',')
+ action_exp++;
+ while (isspace ((int) *action_exp))
+ action_exp++;
+
+ next_comma = strchr (action_exp, ',');
+
+ if (0 == strncasecmp (action_exp, "$reg", 4))
+ registers_info (NULL, from_tty);
+ else if (0 == strncasecmp (action_exp, "$loc", 4))
+ locals_info (NULL, from_tty);
+ else if (0 == strncasecmp (action_exp, "$arg", 4))
+ args_info (NULL, from_tty);
+ else
+ { /* variable */
+ if (next_comma)
+ {
+ make_cleanup (replace_comma, next_comma);
+ *next_comma = '\0';
+ }
+ printf_filtered ("%s = ", action_exp);
+ output_command (action_exp, from_tty);
+ printf_filtered ("\n");
+ }
+ if (next_comma)
+ *next_comma = ',';
+ action_exp = next_comma;
+ }
+ while (action_exp && *action_exp == ',');
+ }
+ }
+ }
+ discard_cleanups (old_cleanups);
+}
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+ * Return a pointer to the last char put in buf (null)
+ * "stolen" from sparc-stub.c
+ */
+
+static const char hexchars[] = "0123456789abcdef";
+
+static unsigned char *
+mem2hex (unsigned char *mem, unsigned char *buf, int count)
+{
+ unsigned char ch;
+
+ while (count-- > 0)
+ {
+ ch = *mem++;
+
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch & 0xf];
+ }
+
+ *buf = 0;
+
+ return buf;
+}
+
+int
+get_traceframe_number (void)
+{
+ return traceframe_number;
+}
+
+
+/* module initialization */
+void
+_initialize_tracepoint (void)
+{
+ struct cmd_list_element *c;
+
+ tracepoint_chain = 0;
+ tracepoint_count = 0;
+ traceframe_number = -1;
+ tracepoint_number = -1;
+
+ set_internalvar (lookup_internalvar ("tpnum"),
+ value_from_longest (builtin_type_int, (LONGEST) 0));
+ set_internalvar (lookup_internalvar ("trace_frame"),
+ value_from_longest (builtin_type_int, (LONGEST) - 1));
+
+ if (tracepoint_list.list == NULL)
+ {
+ tracepoint_list.listsize = 128;
+ tracepoint_list.list = xmalloc
+ (tracepoint_list.listsize * sizeof (struct memrange));
+ }
+ if (tracepoint_list.aexpr_list == NULL)
+ {
+ tracepoint_list.aexpr_listsize = 128;
+ tracepoint_list.aexpr_list = xmalloc
+ (tracepoint_list.aexpr_listsize * sizeof (struct agent_expr *));
+ }
+
+ if (stepping_list.list == NULL)
+ {
+ stepping_list.listsize = 128;
+ stepping_list.list = xmalloc
+ (stepping_list.listsize * sizeof (struct memrange));
+ }
+
+ if (stepping_list.aexpr_list == NULL)
+ {
+ stepping_list.aexpr_listsize = 128;
+ stepping_list.aexpr_list = xmalloc
+ (stepping_list.aexpr_listsize * sizeof (struct agent_expr *));
+ }
+
+ add_info ("scope", scope_info,
+ "List the variables local to a scope");
+
+ add_cmd ("tracepoints", class_trace, NULL,
+ "Tracing of program execution without stopping the program.",
+ &cmdlist);
+
+ add_info ("tracepoints", tracepoints_info,
+ "Status of tracepoints, or tracepoint number NUMBER.\n\
+Convenience variable \"$tpnum\" contains the number of the\n\
+last tracepoint set.");
+
+ add_info_alias ("tp", "tracepoints", 1);
+
+ c = add_com ("save-tracepoints", class_trace, tracepoint_save_command,
+ "Save current tracepoint definitions as a script.\n\
+Use the 'source' command in another debug session to restore them.");
+ set_cmd_completer (c, filename_completer);
+
+ add_com ("tdump", class_trace, trace_dump_command,
+ "Print everything collected at the current tracepoint.");
+
+ add_prefix_cmd ("tfind", class_trace, trace_find_command,
+ "Select a trace frame;\n\
+No argument means forward by one frame; '-' meand backward by one frame.",
+ &tfindlist, "tfind ", 1, &cmdlist);
+
+ add_cmd ("outside", class_trace, trace_find_outside_command,
+ "Select a trace frame whose PC is outside the given \
+range.\nUsage: tfind outside addr1, addr2",
+ &tfindlist);
+
+ add_cmd ("range", class_trace, trace_find_range_command,
+ "Select a trace frame whose PC is in the given range.\n\
+Usage: tfind range addr1,addr2",
+ &tfindlist);
+
+ add_cmd ("line", class_trace, trace_find_line_command,
+ "Select a trace frame by source line.\n\
+Argument can be a line number (with optional source file), \n\
+a function name, or '*' followed by an address.\n\
+Default argument is 'the next source line that was traced'.",
+ &tfindlist);
+
+ add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command,
+ "Select a trace frame by tracepoint number.\n\
+Default is the tracepoint for the current trace frame.",
+ &tfindlist);
+
+ add_cmd ("pc", class_trace, trace_find_pc_command,
+ "Select a trace frame by PC.\n\
+Default is the current PC, or the PC of the current trace frame.",
+ &tfindlist);
+
+ add_cmd ("end", class_trace, trace_find_end_command,
+ "Synonym for 'none'.\n\
+De-select any trace frame and resume 'live' debugging.",
+ &tfindlist);
+
+ add_cmd ("none", class_trace, trace_find_none_command,
+ "De-select any trace frame and resume 'live' debugging.",
+ &tfindlist);
+
+ add_cmd ("start", class_trace, trace_find_start_command,
+ "Select the first trace frame in the trace buffer.",
+ &tfindlist);
+
+ add_com ("tstatus", class_trace, trace_status_command,
+ "Display the status of the current trace data collection.");
+
+ add_com ("tstop", class_trace, trace_stop_command,
+ "Stop trace data collection.");
+
+ add_com ("tstart", class_trace, trace_start_command,
+ "Start trace data collection.");
+
+ add_com ("passcount", class_trace, trace_pass_command,
+ "Set the passcount for a tracepoint.\n\
+The trace will end when the tracepoint has been passed 'count' times.\n\
+Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
+if TPNUM is omitted, passcount refers to the last tracepoint defined.");
+
+ add_com ("end", class_trace, end_actions_pseudocommand,
+ "Ends a list of commands or actions.\n\
+Several GDB commands allow you to enter a list of commands or actions.\n\
+Entering \"end\" on a line by itself is the normal way to terminate\n\
+such a list.\n\n\
+Note: the \"end\" command cannot be used at the gdb prompt.");
+
+ add_com ("while-stepping", class_trace, while_stepping_pseudocommand,
+ "Specify single-stepping behavior at a tracepoint.\n\
+Argument is number of instructions to trace in single-step mode\n\
+following the tracepoint. This command is normally followed by\n\
+one or more \"collect\" commands, to specify what to collect\n\
+while single-stepping.\n\n\
+Note: this command can only be used in a tracepoint \"actions\" list.");
+
+ add_com_alias ("ws", "while-stepping", class_alias, 0);
+ add_com_alias ("stepping", "while-stepping", class_alias, 0);
+
+ add_com ("collect", class_trace, collect_pseudocommand,
+ "Specify one or more data items to be collected at a tracepoint.\n\
+Accepts a comma-separated list of (one or more) expressions. GDB will\n\
+collect all data (variables, registers) referenced by that expression.\n\
+Also accepts the following special arguments:\n\
+ $regs -- all registers.\n\
+ $args -- all function arguments.\n\
+ $locals -- all variables local to the block/function scope.\n\
+Note: this command can only be used in a tracepoint \"actions\" list.");
+
+ add_com ("actions", class_trace, trace_actions_command,
+ "Specify the actions to be taken at a tracepoint.\n\
+Tracepoint actions may include collecting of specified data, \n\
+single-stepping, or enabling/disabling other tracepoints, \n\
+depending on target's capabilities.");
+
+ add_cmd ("tracepoints", class_trace, delete_trace_command,
+ "Delete specified tracepoints.\n\
+Arguments are tracepoint numbers, separated by spaces.\n\
+No argument means delete all tracepoints.",
+ &deletelist);
+
+ add_cmd ("tracepoints", class_trace, disable_trace_command,
+ "Disable specified tracepoints.\n\
+Arguments are tracepoint numbers, separated by spaces.\n\
+No argument means disable all tracepoints.",
+ &disablelist);
+
+ add_cmd ("tracepoints", class_trace, enable_trace_command,
+ "Enable specified tracepoints.\n\
+Arguments are tracepoint numbers, separated by spaces.\n\
+No argument means enable all tracepoints.",
+ &enablelist);
+
+ c = add_com ("trace", class_trace, trace_command,
+ "Set a tracepoint at a specified line or function or address.\n\
+Argument may be a line number, function name, or '*' plus an address.\n\
+For a line number or function, trace at the start of its code.\n\
+If an address is specified, trace at that exact address.\n\n\
+Do \"help tracepoints\" for info on other tracepoint commands.");
+ set_cmd_completer (c, location_completer);
+
+ add_com_alias ("tp", "trace", class_alias, 0);
+ add_com_alias ("tr", "trace", class_alias, 1);
+ add_com_alias ("tra", "trace", class_alias, 1);
+ add_com_alias ("trac", "trace", class_alias, 1);
+}
diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h
new file mode 100644
index 00000000000..c464ae1f98c
--- /dev/null
+++ b/gdb/tracepoint.h
@@ -0,0 +1,134 @@
+/* Data structures associated with tracepoints in GDB.
+ Copyright 1997, 1998, 1999, 2000 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. */
+
+#if !defined (TRACEPOINT_H)
+#define TRACEPOINT_H 1
+
+/* The data structure for an action: */
+struct action_line
+ {
+ struct action_line *next;
+ char *action;
+ };
+
+/* The data structure for a tracepoint: */
+
+struct tracepoint
+ {
+ struct tracepoint *next;
+
+ int enabled_p;
+
+#if 0
+ /* Type of tracepoint (MVS FIXME: needed?). */
+ enum tptype type;
+
+ /* What to do with this tracepoint after we hit it MVS FIXME: needed?). */
+ enum tpdisp disposition;
+#endif
+ /* Number assigned to distinguish tracepoints. */
+ int number;
+
+ /* Address to trace at, or NULL if not an instruction tracepoint (MVS ?). */
+ CORE_ADDR address;
+
+ /* Line number of this address. Only matters if address is non-NULL. */
+ int line_number;
+
+ /* Source file name of this address. Only matters if address is non-NULL. */
+ char *source_file;
+
+ /* Number of times this tracepoint should single-step
+ and collect additional data */
+ long step_count;
+
+ /* Number of times this tracepoint should be hit before disabling/ending. */
+ int pass_count;
+
+ /* Chain of action lines to execute when this tracepoint is hit. */
+ struct action_line *actions;
+
+ /* Conditional (MVS ?). */
+ struct expression *cond;
+
+ /* String we used to set the tracepoint (malloc'd). Only matters if
+ address is non-NULL. */
+ char *addr_string;
+
+ /* Language we used to set the tracepoint. */
+ enum language language;
+
+ /* Input radix we used to set the tracepoint. */
+ int input_radix;
+
+ /* Count of the number of times this tracepoint was taken, dumped
+ with the info, but not used for anything else. Useful for
+ seeing how many times you hit a tracepoint prior to the program
+ aborting, so you can back up to just before the abort. */
+ int hit_count;
+
+ /* Thread number for thread-specific tracepoint, or -1 if don't care */
+ int thread;
+
+ /* BFD section, in case of overlays:
+ no, I don't know if tracepoints are really gonna work with overlays. */
+ asection *section;
+ };
+
+enum actionline_type
+ {
+ BADLINE = -1,
+ GENERIC = 0,
+ END = 1,
+ STEPPING = 2
+ };
+
+
+/* The tracepoint chain of all tracepoints */
+
+extern struct tracepoint *tracepoint_chain;
+
+extern unsigned long trace_running_p;
+
+/* A hook used to notify the UI of tracepoint operations */
+
+void (*create_tracepoint_hook) (struct tracepoint *);
+void (*delete_tracepoint_hook) (struct tracepoint *);
+void (*modify_tracepoint_hook) (struct tracepoint *);
+void (*trace_find_hook) (char *arg, int from_tty);
+void (*trace_start_stop_hook) (int start, int from_tty);
+
+struct tracepoint *get_tracepoint_by_number (char **, int, int);
+int get_traceframe_number (void);
+void free_actions (struct tracepoint *);
+enum actionline_type validate_actionline (char **, struct tracepoint *);
+
+
+/* Walk the following statement or block through all tracepoints.
+ ALL_TRACEPOINTS_SAFE does so even if the statment deletes the current
+ breakpoint. */
+
+#define ALL_TRACEPOINTS(t) for (t = tracepoint_chain; t; t = t->next)
+
+#define ALL_TRACEPOINTS_SAFE(t,tmp) \
+ for (t = tracepoint_chain; \
+ t ? (tmp = t->next, 1) : 0;\
+ t = tmp)
+#endif /* TRACEPOINT_H */
diff --git a/gdb/tui/ChangeLog b/gdb/tui/ChangeLog
new file mode 100644
index 00000000000..d278c6a73a7
--- /dev/null
+++ b/gdb/tui/ChangeLog
@@ -0,0 +1,626 @@
+2002-03-15 Andrew Cagney <ac131313@redhat.com>
+
+ * tui-out.c (XMALLOC): Delete macro. Update copyright.
+
+2002-03-01 Andrew Cagney <ac131313@redhat.com>
+
+ * tui-hooks.c: Add FIXME to explain true/false problem. Update
+ copyright.
+ * tui.c, tuiCommand.c, tuiData.c, tuiDataWin.c: Ditto.
+ * tuiDisassem.c, tuiGeneralWin.c, tuiIO.c, tuiLayout.c: Ditto.
+ * tuiRegs.c, tuiSource.c, tuiSourceWin.c, tuiStack.c: Ditto.
+ * tuiWin.c: Ditto.
+
+ 2002-02-08 Daniel Jacobowitz <drow@mvista.com>
+ * tui-hooks.c: Include <curses.h> before "bfd.h".
+ * tui.c: Likewise.
+ * tuiCommand.c: Likewise.
+ * tuiData.c: Likewise.
+ * tuiDataWin.c: Likewise.
+ * tuiDisassem.c: Likewise.
+ * tuiGeneralWin.c: Likewise.
+ * tuiIO.c: Likewise.
+ * tuiLayout.c: Likewise.
+ * tuiRegs.c: Likewise.
+ * tuiSource.c: Likewise.
+ * tuiSourceWin.c: Likewise.
+ * tuiStack.c: Likewise.
+ * tuiWin.c: Likewise.
+
+2002-02-01 Andrew Cagney <ac131313@redhat.com>
+
+ * tuiWin.c (_initialize_tuiWin): Replace NO_FUNCTION with NULL.
+
+2001-10-20 Andrew Cagney <ac131313@redhat.com>
+
+ * tuiDisassem.c: Include "value.h".
+ * tuiSourceWin.c: Ditto.
+
+2001-09-28 Tom Tromey <tromey@redhat.com>
+
+ * tuiLayout.h (tui_set_layout): Don't declare.
+ * tui.h (tui_vAddWinToLayout): Don't declare.
+ (tui_vSetLayoutTo): Likewise.
+ (tui_set_layout): Declare.
+
+2001-08-02 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * tuiSourceWin.c: Use disp_del instead of del.
+
+ * tuiSource.c: Use disp_del instead of del.
+
+ * tuiDisassem.c: Use disp_del instead of del.
+
+2001-07-31 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tui.c (tui_enable): Remove call to terminal_save_ours().
+ (tui_disable): Likewise.
+
+2001-07-28 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiWin.c (_initialize_tuiWin): Use specific tui prefix for
+ set/show configuration variables.
+ (show_tui_cmd): New function.
+ (set_tui_cmd): New function.
+
+2001-07-24 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tui-hooks.c: New file, gdb hooks for tui.
+ * tui-out.c: New file, image copied from cli-out.c.
+ (tui_field_int): Identify "line" fields and keep track of them.
+ (tui_field_string): Likewise for "file".
+ (tui_out_new): Use flags = 0 to avoid printing the sources.
+
+2001-07-23 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiIO.c (tui_cont_sig): Update cursor position on the screen to
+ leave it in the command window.
+ (tui_redisplay_readline): Save cursor position to restore the
+ cursor after we go back from background.
+ * tuiData.h (TuiCommandInfo): Add start_line member.
+
+2001-07-23 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiStack.c (tuiUpdateLocatorFilename): Use const char*.
+ * tuiStack.h (tuiUpdateLocatorFilename): Update prototype.
+ * tuiWin.c (_initialize_tuiWin): Don't cast table of enum in calls
+ to add_set_enum_cmd.
+ * tui.c (tui_show_source): New function.
+ (tuiGetLowDisassemblyAddress): Use CORE_ADDR for newLow.
+ (tui_switch_mode): Prep or deprep readline terminal;
+ make sure the \n we return does not redo the last command.
+ * tui.h (tui_show_source): Declare.
+ (tui_out_new, tui_install_hooks, tui_remove_hooks): Likewise.
+ (tui_active, tui_initialize_io, tui_initialize_readline): Likewise.
+
+2001-07-22 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiIO.c (tui_initialize_io): Install tui_cont_sig signal handler
+ if SIGCONT is defined.
+ (tui_cont_sig): New function when SIGCONT is defined.
+ (tui_setup_io): Save tty setting to restore by SIGCONT.
+
+2001-07-22 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tui.h (tui_show_assembly): Declare.
+ (tui_is_window_visible): Declare.
+ * tui.c (tui_show_assembly): New function.
+ (tui_is_window_visible): New function.
+ (tui_get_command_dimension): New function.
+
+2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiWin.c (tuiRefreshAll): Use clearok to force a refresh.
+
+2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tui-file.c (tui_file_fputs): Use tui_puts.
+
+2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiStack.c (tuiSetLocatorInfo): Cleanup.
+ * tuiStack.h (tuiGetLocatorFilename): Declare.
+ * tuiRegs.h (tuiFirstRegElementNoInLine): Declare.
+ * tuiData.h (addToSourceWindows): Declare.
+
+2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tui.c (tui_change_windows): New function.
+ (tui_delete_other_windows): New function.
+ (tui_initialize_readline): Bind them to C-X 1 and C-X 2.
+ (tui_enable): Enable the keypad; call tui_update_variables.
+ (strcat_to_buf_with_fmt): Remove.
+
+2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tui.h: Remove old declarations, add the new ones.
+ * tui.c (tui_switch_mode): New function.
+ (tui_initialize_readline): New function.
+ (tui_enable): New function.
+ (tui_disable): New function.
+ (tuiGetLowDisassemblyAddress): Use CORE_ADDR, cleanup.
+ (tui_vSelectSourceSymtab): Remove.
+ (tuiInitWindows): Remove.
+ (_initialize_tui): Remove.
+ (_tuiReset): Keep but put arround #if 0.
+
+2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiIO.h: Remove old declarations and add the new ones.
+ * tuiIO.c: New management for curses and gdb terminal interactions.
+ (tui_tputs): Remove.
+ (tuiTermSetup, tuiTermUnsetup): Remove, must use normal curses ops.
+ (tuiBufferGetc, tui_vStartNewLines, _updateCommandInfo): Remove.
+ (tui_owns_terminal): Remove.
+ (tui_redisplay_readline): New function.
+ (tui_puts): New function.
+ (tui_prep_terminal): New function.
+ (tui_deprep_terminal): New function.
+ (tui_getc): Rename of tuiGetc, simplify and fix.
+ (tui_setup_io): New function.
+ (tui_initialize_io): New function.
+
+2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiRegs.c (tuiDisplayRegistersFrom): Call touchwin.
+ (_tuiRegisterFormat): Reduce size of format result.
+
+2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiGeneralWin.c (boxWin): Use the tui configuration variables.
+ * tuiWin.h: Declare the new variables.
+ * tuiWin.c (_initialize_tuiWin): Create TUI configuration variables.
+ (tui_update_variables): New function.
+ (translate): New function.
+ (tui_border_kind_enums, tui_border_mode_enums): New tables.
+ (tui_border_mode_translate): New table.
+ (tui_border_kind_translate_*): New tables.
+ (tui_active_border_mode): New variables.
+ (tui_border_*): New variables.
+
+2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiWin.c (_parseScrollingArgs): Fix uninitialized variable.
+ (_makeVisibleWithNewHeight): Use TuiLineOrAddress type.
+
+ * tuiStack.c (tuiShowFrameInfo): Use TuiLineOrAddress type.
+ (tui_vUpdateLocatorFilename): Remove.
+ * tuiStack.h: Update prototypes.
+
+ * tuiSourceWin.c (tuiAddrIsDisplayed): New function.
+ (tuiLineIsDisplayed): Split for address and line.
+ (tuiUpdateSourceWindow): Use TuiLineOrAddress type.
+ (tuiUpdateSourceWindowAsIs): Likewise.
+ (tuiUpdateSourceWindowsWithAddr): Likewise.
+ (tuiUpdateSourceWindowsWithLine): Likewise.
+ (tuiHorizontalSourceScroll): Likewise.
+ (tuiSetIsExecPointAt): Likewise.
+ (tuiUpdateOnEnd): Likewise.
+ * tuiSourceWin.h: Update prototypes.
+
+ * tuiSource.c (tuiVerticalSourceScroll): Use TuiLineOrAddress type.
+ (tuiShowSource): Likewise.
+ (tuiVerticalSourceScroll): Likewise.
+ * tuiSource.h (tuiShowSource): Update prototype.
+
+ * tuiDisassem.c (tuiSetDisassemContent): Use CORE_ADDR for address.
+ (tuiShowDisassem): Use TuiLineOrAddress type.
+ (tuiShowDisassemAndUpdateSource): Likewise.
+ (tuiVerticalDisassemScroll): Likewise.
+ (tuiShowDisassemAsIs): Remove.
+ * tuiDisassem.h (tuiSetDisassemContent): Update prototype.
+
+ * tuiData.c (initWinInfo): Use CORE_ADDR for address.
+ (clearWinDetail): Likewise.
+ (displayableWinContentOf): Fix address conversion.
+ (tuiNextWin): Fix crash when the window is not yet created.
+ (partialWinByName): Likewise.
+
+2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiSourceWin.h: Remove unused declarations.
+ * tuiSourceWin.c (tui_vUpdateSourceWindowsWithAddr): Remove.
+ (tui_vUpdateSourceWindowsWithLine): Remove.
+ (tui_vAllSetHasBreakAt): Remove.
+
+ * tuiLayout.h (tui_set_layout): Declare.
+ (tui_vSetLayoutTo): Remove.
+ (tui_vAddWinToLayout): Remove.
+ * tuiLayout.c (_tuiLayout_command): Call tui_enable() to force TUI.
+ (_tuiToggleLayout_command): Remove.
+ (_tuiToggleSplitLayout_command): Remove.
+ (_tuiLayout_command): Remove.
+ (tui_vSetLayoutTo): Remove.
+ (tui_vAddWinToLayout): Remove.
+
+ * tuiDataWin.h (tui_vCheckDataValues): Remove.
+ * tuiDataWin.c (tui_vCheckDataValues): Remove.
+
+2001-07-20 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiWin.c (tuiStrDup): Remove, replaced by xstrdup.
+ (_parseScrollingArgs): Use xstrdup.
+ (_tuiScrollForward_command): Call tui_enable() to force TUI mode.
+ (_tuiScrollBackward_command): Likewise.
+ (_tuiScrollLeft_command): Likewise.
+ (_tuiScrollRight_command): Likewise.
+ (_tuiSetFocus): Likewise.
+ (_tuiSetFocus_command): Likewise.
+ (_tuiRefreshAll_command): Likewise.
+ (_tuiSetTabWidth_command): Likewise.
+ (_tuiSetWinHeight): Likewise.
+ (_tuiSetWinHeight_command): Likewise.
+ (_tuiXDBsetWinHeight): Likewise.
+ (_tui_vSetFocus): Remove.
+ (_tui_vSetWinHeight): Remove.
+ (_tui_vXDBsetWinHeight): Remove.
+
+2001-07-21 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiCommand.h: Remove unused declarations.
+ * tuiCommand.c (tuiDispatchCtrlChar): Fix escape sequences.
+ (tuiIncrCommandCharCountBy): Remove.
+ (tuiDecrCommandCharCountBy): Remove.
+ (tuiSetCommandCharCountTo): Remove.
+ (tuiClearCommandCharCount): Remove.
+
+2001-07-20 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiWin.c (_initialize_tuiWin): Always define the tui commands;
+ create the tui class help.
+ * tuiLayout.c (_initialize_tuiLayout): Always define the tui commands.
+ * tuiRegs.c (_initialize_tuiRegs): Likewise.
+ * tuiStack.c (_initialize_tuiStack): Likewise.
+
+2001-07-19 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiDisassem.c (tuiVerticalDisassemScroll): Use CORE_ADDR.
+ (tuiVerticalDisassemScroll): Likewise.
+ (tuiShowDisassemAndUpdateSource): Check for null symtab to
+ prevent a crash.
+
+2001-07-18 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiIO.c (_tuiHandleResizeDuringIO): Call tuiRefreshAll.
+ (tuiRead, tui_vread): Remove.
+
+ * tui.c (va_catch_errors, tuiDo, tuiDoAndReturnToTop): Remove.
+ (vcatch_errors, _tui_vDo): Remove.
+ * tui.h (tuiDo, tuiDoAndReturnToTop): Remove.
+
+ * tuiLayout.c (tuiSetLayout): Remove vcatch_errors.
+ (tui_set_layout): Rename of _tuiSetLayoutTo, public.
+ (_tuiToggleLayout_command): Merge with _tui_vToggleLayout_command.
+ (_tuiToggleSplitLayout_command): Merge with _tui_vToggleSplitLayout_command.
+ (_tuiLayout_command): Call tui_set_layout.
+
+ * tuiRegs.c (_tuiScrollRegsBackward_command): Call tui_scroll.
+ (_tuiScrollRegsForward_command): Likewise.
+ (_tuiShowFloat_command): Call _tui_vShowRegisters_commandSupport.
+ (_tuiShowGeneral_command): Likewise.
+ (_tuiShowSpecial_command): Likewise.
+ (_tuiToggleFloatRegs_command): Call tuiToggleFloatRegs.
+ * tuiWin.c (tui_scroll): Rename of tui_vScroll, update parameters.
+ (_tuiScrollForward_command): Call tui_scroll.
+ (_tuiScrollBackward_command): Likewise.
+ (_tuiScrollLeft_command): Likewise.
+ (_tuiScrollRight_command): Likewise.
+ (_tuiSetFocus_command): Call _tuiSetFocus.
+ (_tuiRefreshAll_command): Call tuiRefreshAll.
+ (_tuiSetWinHeight_command): Call _tuiSetWinHeight.
+ (_tuiXDBsetWinHeight_command): Call _tuiXDBsetWinHeight.
+ * tuiWin.h (tui_scroll): Rename of tui_vScroll, update parameters.
+
+2001-07-18 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiData.h (TuiLocatorElement): Use CORE_ADDR for address member.
+ (TuiLineOrAddress): Likewise.
+ * tuiDisassem.c (tuiGetBeginAsmAddress): Use CORE_ADDR to specify
+ an address.
+ (tuiSetDisassemContent): Likewise.
+ (tuiShowDisassem, tuiShowDisassemAndUpdateSource): Likewise.
+ * tuiLayout.c (_extractDisplayStartAddr): Likewise.
+ (tuiSetLayout): Likewise.
+ * tuiSourceWin.c (tuiDisplayMainFunction): Likewise.
+ (tuiUpdateSourceWindowsWithAddr): Likewise.
+ (tuiUpdateSourceWindowsWithLine): Likewise.
+ (tuiSetHasBreakAt): Likewise.
+ * tuiStack.c (tuiSetLocatorInfo): Likewise.
+ (tuiSwitchFilename): Likewise.
+ (tuiUpdateLocatorInfoFromFrame): Likewise.
+ (tuiSetLocatorContent): Likewise.
+ (tuiShowFrameInfo): Likewise.
+ * tuiDisassem.h: Update prototypes to use CORE_ADDR.
+ * tuiSourceWin.h: Likewise.
+ * tuiStack.h: Likewise.
+
+2001-07-17 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiWin.c: Add missing includes.
+ (_makeVisibleWithNewHeight): Fix call to find_line_pc.
+ * tuiLayout.c: Add missing includes.
+ (_initAndMakeWin): Don't put curses in echo mode.
+ (_extractDisplayStartAddr): Fix calls to find_line_pc.
+ (_tuiLayout_command): Missing ',' in warning call.
+ * tuiSourceWin.c (tuiUpdateSourceWindowsWithLine): Fix calls to
+ find_line_pc.
+ (tuiSetHasBreakAt): Check for null source file.
+
+2001-07-17 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiWin.c (_tuiSetFocus): Replace subsetCompare with subset_compare.
+ * tuiLayout.c (_tuiSetLayoutTo): Likewise.
+ * tui.c (_tui_vToggle_command): Likewise.
+
+2001-07-17 Elena Zannoni <ezannoni@redhat.com>
+
+ * tui-file.c: Add include of tuiIO.h, for tuiPuts_unfiltered.
+
+2001-07-16 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiRegs.c (tuiDisplayRegistersFrom): Set scrollok to FALSE in
+ each register window.
+ (tuiCheckRegisterValues): Use REGISTER_RAW_SIZE to obtain the size
+ of the register to check.
+ (_tuiRegValueHasChanged): Likewise.
+ (_tuiRegisterName): Use REGISTER_NAME.
+ (tui_restore_gdbout): New function.
+ (_tuiRegisterFormat): Use do_registers_info with gdb_stdout redirected
+ to a string.
+ (START_SPECIAL_REGS): Define.
+ (_tuiGetRegisterRawValue): Use get_saved_register.
+ (_tuiDisplayRegister): Fix clearing of register window.
+
+2001-07-17 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tui-file.h (fputs_unfiltered_hook): Remove.
+ * tui-file.c (tui_file_flush): Remove fputs_unfiltered_hook.
+ (tui_file_fputs): Likewise; simplify
+
+2001-07-16 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiStack.c: Add missing includes.
+ (tuiShowFrameInfo): Don't crash when there is no symbol table
+ associated with the pc.
+ * tuiSource.c (_hasBreak): Check for null source file.
+ * tuiWin.c (tuiRefreshAll): Check for null winList[type].
+ (_tuiSetFocus): Check for null dataWin.
+ * tuiGeneralWin.c (refreshAll): Check for null list[type].
+
+2001-07-16 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiDisassem.c (tuiSetDisassemContent): Use tm_print_insn_info
+ to disassemble in the curses window.
+
+2001-07-16 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tui.h: Cleanup to avoid inclusion of curses includes.
+ (TuiGenWinInfo, TuiGenWinInfoPtr): Move from here.
+ * tuiData.h: To here; include curses includes here.
+ (setTermHeightTo): Rename of setTermHeight to follow reality.
+ (setTermWidthTo): Likewise with setTermWidth.
+
+2001-07-14 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiWin.c, tui.c, tuiCommand.c: Use ansi prototype.
+ tuiIO.c, tuiData.c: Likewise.
+ tuiDataWin.c, tuiDisassem.c: Likewise.
+ tuiGeneralWin.c, tuiLayout.c: Likewise.
+ tuiRegs.c, tuiSource.c: Likewise.
+ tuiSouceWin.c, tuiStack.c: Likewise.
+
+2001-07-14 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * tuiWin.c, tuiWin.h, tui.c, tui.h, tuiCommand.c: Add FSF copyright.
+ tuiCommand.h, tuiIO.c, tuiIO.h, tuiData.h, tuiData.c: Likewise.
+ tuiDataWin.c, tuiDataWin.h, tuiDisassem.c, tuiDisassem.h: Likewise.
+ tuiGeneralWin.c, tuiGeneralWin.h, tuiLayout.c, tuiLayout.h: Likewise.
+ tuiRegs.c, tuiRegs.h, tuiSource.c, tuiSource.h: Likewise.
+ tuiSouceWin.c, tuiSourceWin.h, tuiStack.c, tuiStack.h: Likewise.
+
+2001-03-08 Andrew Cagney <ac131313@redhat.com>
+
+ * tuiRegs.c: Use NUM_REGS, not ARCH_NUM_REGS.
+
+2001-03-06 Kevin Buettner <kevinb@redhat.com>
+
+ * tui-file.h: Update/correct copyright notice.
+
+Wed Feb 7 19:54:27 2001 Andrew Cagney <cagney@redhat.com>
+
+ * tui-file.c: Add __FILE__ and __LINE__ parameter to calls to
+ internal_error.
+
+2000-12-14 Kevin Buettner <kevinb@redhat.com>
+
+ * tui-file.c, tui.c, tuiData.c, tuiLayout.c: Replace occurrences
+ of free() with xfree().
+
+2000-06-22 Kevin Buettner <kevinb@redhat.com>
+
+ * tuiSourceWin.h: Eliminate use of PARAMS from this file.
+
+2000-06-20 Kevin Buettner <kevinb@redhat.com>
+
+ * tuiLayout.c: Eliminate use of PARAMS from this file.
+
+2000-06-17 Kevin Buettner <kevinb@redhat.com>
+
+ * tuiIO.c: Eliminate use of PARAMS from this file.
+
+Thu May 25 14:46:20 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * tui-file.c: Include "tui.h", "tuiData.h", "tuiIO.h" and
+ "tuiCommand.h".
+ (tui_file_fputs): Pass ``file'' and not ``stream'' to
+ tui_file_adjust_strbuf.
+
+Thu May 25 16:58:01 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * tui.h: Include <ncurses.h> when available.
+ * tui.c, tuiGeneralWin.c: Do not include <curses.h>.
+
+Mon May 15 17:16:10 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in: Delete.
+
+Tue Apr 18 15:32:15 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (distclean, maintainer-clean, realclean,
+ mostlyclean): New targets.
+
+Tue Feb 1 00:17:12 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * tui-file.c, tui-file.h, tuiDisassem.c, tuiIO.c, tuiIO.h,
+ tuiRegs.c: Update to reflect rename of gdb-file / GDB_FILE to
+ ui-file / ``struct ui_file''.
+
+Mon Jan 31 18:12:43 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * tui-file.c (enum streamtype, struct tui_stream, tui_file_new,
+ tui_file_delete, tui_fileopen, tui_sfileopen, tui_file_isatty,
+ tui_file_rewind, tui_file_put, tui_file_fputs,
+ tui_file_get_strbuf, tui_file_adjust_strbuf, tui_file_flush,
+ fputs_unfiltered_hook): Move to here from ../utils.c
+
+ * tui-file.h, tui-file.c: New files.
+
+Mon Nov 8 17:47:37 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * tuiRegs.c (_tuiRegisterFormat), tuiDisassem.c
+ (tuiSetDisassemContent): Replace gdb_file_init_astring with
+ tui_sfileopen. Replace gdb_file_get_strbuf with
+ tui_file_get_strbuf.
+
+Mon Nov 8 16:54:51 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * tuiRegs.c (_tuiRegisterFormat), tuiDisassem.c
+ (tuiSetDisassemContent): Repace gdb_file_deallocate with
+ gdb_file_delete. Replace gdb_file_init_astring with tui_sfileopen.
+
+Fri Sep 17 19:34:38 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * tuiSource.c: Include "source.h".
+ (open_source_file, find_source_lines): Delete declarations.
+
+1999-01-26 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * tui.h: Include stdarg.h instead of varargs.h if we're on an ISO Cish
+ system.
+
+Thu Dec 31 12:08:32 1998 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by Jim Blandy <jimb@cygnus.com>,
+ Edith Epstein <eepstein@cygnus.com>, Elena Zannoni
+ <ezannoni@cygnus.com> Stan Shebs <shebs@cygnus.com>, and David
+ Taylor <taylor@cygnus.com>, as part of the project to merge in
+ changes originally made by HP; HP did not create ChangeLog
+ entries.
+
+ * Makefile.in: New file; we're merging HP's changes into GDB, and
+ we've moved the TUI files into a subdirectory, so we need a new
+ Makefile.
+
+ * tui.c:
+ #include <term.h>, if we have it, to get declarations for
+ the termcap functions on Solaris.
+ (tgoto): Add external K&R declaration for this; Solaris doesn't
+ bother to actually declare it in their header files.
+ (_tuiReset): Ignore the #definition of TIOCGETC if USG is defined;
+ we'd rather use the USG mechanisms than the Berkeley mechanisms
+ (TIOCGETC is one of the Berkeley terminal control ioctls).
+ Apologies if this causes trouble later; this should all be handled
+ by autoconf...
+ (strcat_to_buf, strcat_to_buf_with_fmt): New functions, moved here
+ from ../utils.h.
+ (tuiFree): replace safe_free with free.
+ (strcat_to_buf): new function, copied from utils.c.
+ (tuiInit): Add ignored `argv0' argument, to match the type that
+ init_ui_hook expects; updated declaration. Call the
+ initialize_tui_files function constructed above. Initialize
+ flush_hook to NULL.
+ (tuiInitWindows): Call tuiSetLocatorContent, to get the first
+ element of the locator window's content allocated. This seems
+ wrong, because it must have been initialized somehow in HP's
+ sources, and we should do it the same way now. But we do get
+ further before it segfaults. [Postscript: HP didn't bother to
+ initialize it; they compile
+ (va_catch_errors, vcatch_errors): Functions moved here from
+ ../utils.c in HP's sources. They're not used anywhere else.
+ (xdb_style): Delete this variable, and remove all references to
+ it. It's always true.
+ (tuiInit, _tui_vDo): References removed.
+
+ * tui.h: Add prototypes.
+ Don't #include "gendefs.h"; it's only used in the TUI.
+ Integrate its contents into this file:
+ #include <ansidecl.h> here.
+ (Opaque, OpaqueFuncPtr): Typedefs moved to here.
+
+ * tuiCommand.c: #include "defs.h", so we get the appropriate
+ definition of GDB_FILE.
+
+ * tuiData.c
+ (freeWindow): replace safe_free with free.
+ (tui_version): don't define it here; it's defined in main.c now.
+
+ * tuiDisassem.c
+ (tuiSetDisassemContent): Call strcat_address_numeric instead of
+ strcat_address. Simplify the control structure. Use predefined
+ GDB function to print asm inst address. Use GDB_FILE to collect
+ output into buffers.
+
+ * tuiIO.c
+ (tgoto): Add external K&R declaration for this here too.
+ (tuiGetc, tuiTermSetup, tuiTermUnsetup): Same.
+ (tuiPuts_unfiltered): change FILE to GDB_FILE.
+ (tui_tputs): fix prototype for 3rd argument.
+
+ * tuiIO.h (tuiPuts_unfiltered): change declaration.
+
+ * tuiLayout.c
+ (_tuiSetLayoutTo): for displaying registers, hook up the HP code
+ that decides which registers to display (i.e. single precision
+ float, double precision float, general, special). Previously,
+ only handled TUI_GENERAL_REGS. Now that the code is hooked up,
+ compiling with -z poses a problem. When the first layout command
+ is 'layout regs', dataWin->detail is a NULL pointer, and gdb
+ core dumps.
+
+ * tuiLayout.c (_tuiSetLayoutTo): replace safe_free with free.
+
+ * tuiRegs.c #include "defs.h" earlier, to avoid problems in
+ <stdarg.h>. No idea exactly what's conflicting with what, but the
+ errors went away...
+ (_tuiRegisterFormat): Change so that function creates a GDB_FILE
+ object, calls pa_do_strcat_registers_info, copies the register
+ info into a buffer, and deallocates the GDB_FILE object. Remove
+ some code that is not executed. Also, call to
+ pa_do_strcat_registers_info has an additional parameter,
+ precision. This code requires some new per-target functions that
+ we don't want to merge. Dyke it out, with #ifdef
+ TUI_EXTENDED_FORMATTERS.
+ (_tuiSetSpecialRegsContent): this function was ifdefed out.
+ Hooked this up.
+ (_tuiSetGeneralAndSpecialRegsContent): this function was ifdefed
+ out. Hooked it up.
+ (IS_64BIT): Just define this to be zero; we're not merging in the
+ 64-bit support.
+ (tuiShowRegisters): Comment out all references to the "special"
+ regs; we don't have a distinction between the "special" and
+ "non-special" regs in most of our machine descriptions. This code
+ is PA-specific in other ways as well, and needs to be redesigned
+ to be portable to other processors.
+
+ * tuiWin.c: #include <string.h>, to get a declaration for
+ strchr.
+
+ * tui.c, tuiCommand.c, tuiData.c, tuiDataWin.c, tuiDisassem.c,
+ tuiGeneralWin.c, tuiIO.c, tuiLayout.c, tuiRegs.c, tuiSource.c,
+ tuiSourceWin.c, tuiStack.c, tuiWin.c: New files (from HP). Changed
+ bool to int throughout. Re-indented, GNU style.
+
+ * tui.h, tuiCommand.h, tuiData.h, tuiDataWin.h, tuiDisassem.h,
+ tuiGeneralWin.h, tuiIO.h, tuiLayout.h, tuiRegs.h, tuiSource.h,
+ tuiSourceWin.h, tuiStack.h, tuiWin.h: new files (from HP).
+ Changed bool to int throughout.
diff --git a/gdb/tui/tui-file.c b/gdb/tui/tui-file.c
new file mode 100644
index 00000000000..1a72d01f856
--- /dev/null
+++ b/gdb/tui/tui-file.c
@@ -0,0 +1,238 @@
+/* UI_FILE - a generic STDIO like output stream.
+ Copyright 1999, 2000, 2001 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 "defs.h"
+#include "ui-file.h"
+#include "tui/tui-file.h"
+#include "tui/tuiIO.h"
+
+#include "tui.h"
+
+#include <string.h>
+
+/* A ``struct ui_file'' that is compatible with all the legacy
+ code. */
+
+/* new */
+enum streamtype
+{
+ afile,
+ astring
+};
+
+/* new */
+struct tui_stream
+{
+ int *ts_magic;
+ enum streamtype ts_streamtype;
+ FILE *ts_filestream;
+ char *ts_strbuf;
+ int ts_buflen;
+};
+
+static ui_file_flush_ftype tui_file_flush;
+extern ui_file_fputs_ftype tui_file_fputs;
+static ui_file_isatty_ftype tui_file_isatty;
+static ui_file_rewind_ftype tui_file_rewind;
+static ui_file_put_ftype tui_file_put;
+static ui_file_delete_ftype tui_file_delete;
+static struct ui_file *tui_file_new (void);
+static int tui_file_magic;
+
+static struct ui_file *
+tui_file_new (void)
+{
+ struct tui_stream *tui = xmalloc (sizeof (struct tui_stream));
+ struct ui_file *file = ui_file_new ();
+ set_ui_file_data (file, tui, tui_file_delete);
+ set_ui_file_flush (file, tui_file_flush);
+ set_ui_file_fputs (file, tui_file_fputs);
+ set_ui_file_isatty (file, tui_file_isatty);
+ set_ui_file_rewind (file, tui_file_rewind);
+ set_ui_file_put (file, tui_file_put);
+ tui->ts_magic = &tui_file_magic;
+ return file;
+}
+
+static void
+tui_file_delete (struct ui_file *file)
+{
+ struct tui_stream *tmpstream = ui_file_data (file);
+ if (tmpstream->ts_magic != &tui_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "tui_file_delete: bad magic number");
+ if ((tmpstream->ts_streamtype == astring) &&
+ (tmpstream->ts_strbuf != NULL))
+ {
+ xfree (tmpstream->ts_strbuf);
+ }
+ xfree (tmpstream);
+}
+
+struct ui_file *
+tui_fileopen (FILE *stream)
+{
+ struct ui_file *file = tui_file_new ();
+ struct tui_stream *tmpstream = ui_file_data (file);
+ tmpstream->ts_streamtype = afile;
+ tmpstream->ts_filestream = stream;
+ tmpstream->ts_strbuf = NULL;
+ tmpstream->ts_buflen = 0;
+ return file;
+}
+
+struct ui_file *
+tui_sfileopen (int n)
+{
+ struct ui_file *file = tui_file_new ();
+ struct tui_stream *tmpstream = ui_file_data (file);
+ tmpstream->ts_streamtype = astring;
+ tmpstream->ts_filestream = NULL;
+ if (n > 0)
+ {
+ tmpstream->ts_strbuf = xmalloc ((n + 1) * sizeof (char));
+ tmpstream->ts_strbuf[0] = '\0';
+ }
+ else
+ /* Do not allocate the buffer now. The first time something is printed
+ one will be allocated by tui_file_adjust_strbuf() */
+ tmpstream->ts_strbuf = NULL;
+ tmpstream->ts_buflen = n;
+ return file;
+}
+
+static int
+tui_file_isatty (struct ui_file *file)
+{
+ struct tui_stream *stream = ui_file_data (file);
+ if (stream->ts_magic != &tui_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "tui_file_isatty: bad magic number");
+ if (stream->ts_streamtype == afile)
+ return (isatty (fileno (stream->ts_filestream)));
+ else
+ return 0;
+}
+
+static void
+tui_file_rewind (struct ui_file *file)
+{
+ struct tui_stream *stream = ui_file_data (file);
+ if (stream->ts_magic != &tui_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "tui_file_rewind: bad magic number");
+ stream->ts_strbuf[0] = '\0';
+}
+
+static void
+tui_file_put (struct ui_file *file,
+ ui_file_put_method_ftype *write,
+ void *dest)
+{
+ struct tui_stream *stream = ui_file_data (file);
+ if (stream->ts_magic != &tui_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "tui_file_put: bad magic number");
+ if (stream->ts_streamtype == astring)
+ write (dest, stream->ts_strbuf, strlen (stream->ts_strbuf));
+}
+
+/* All TUI I/O sent to the *_filtered and *_unfiltered functions
+ eventually ends up here. The fputs_unfiltered_hook is primarily
+ used by GUIs to collect all output and send it to the GUI, instead
+ of the controlling terminal. Only output to gdb_stdout and
+ gdb_stderr are sent to the hook. Everything else is sent on to
+ fputs to allow file I/O to be handled appropriately. */
+
+/* FIXME: Should be broken up and moved to a TUI specific file. */
+
+void
+tui_file_fputs (const char *linebuffer, struct ui_file *file)
+{
+ struct tui_stream *stream = ui_file_data (file);
+
+ if (stream->ts_streamtype == astring)
+ {
+ tui_file_adjust_strbuf (strlen (linebuffer), file);
+ strcat (stream->ts_strbuf, linebuffer);
+ }
+ else
+ {
+ tui_puts (linebuffer);
+ }
+}
+
+char *
+tui_file_get_strbuf (struct ui_file *file)
+{
+ struct tui_stream *stream = ui_file_data (file);
+ if (stream->ts_magic != &tui_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "tui_file_get_strbuf: bad magic number");
+ return (stream->ts_strbuf);
+}
+
+/* adjust the length of the buffer by the amount necessary
+ to accomodate appending a string of length N to the buffer contents */
+void
+tui_file_adjust_strbuf (int n, struct ui_file *file)
+{
+ struct tui_stream *stream = ui_file_data (file);
+ int non_null_chars;
+ if (stream->ts_magic != &tui_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "tui_file_adjust_strbuf: bad magic number");
+
+ if (stream->ts_streamtype != astring)
+ return;
+
+ if (stream->ts_strbuf)
+ {
+ /* There is already a buffer allocated */
+ non_null_chars = strlen (stream->ts_strbuf);
+
+ if (n > (stream->ts_buflen - non_null_chars - 1))
+ {
+ stream->ts_buflen = n + non_null_chars + 1;
+ stream->ts_strbuf = xrealloc (stream->ts_strbuf, stream->ts_buflen);
+ }
+ }
+ else
+ /* No buffer yet, so allocate one of the desired size */
+ stream->ts_strbuf = xmalloc ((n + 1) * sizeof (char));
+}
+
+static void
+tui_file_flush (struct ui_file *file)
+{
+ struct tui_stream *stream = ui_file_data (file);
+ if (stream->ts_magic != &tui_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "tui_file_flush: bad magic number");
+
+ switch (stream->ts_streamtype)
+ {
+ case astring:
+ break;
+ case afile:
+ fflush (stream->ts_filestream);
+ break;
+ }
+}
diff --git a/gdb/tui/tui-file.h b/gdb/tui/tui-file.h
new file mode 100644
index 00000000000..ea0729716d2
--- /dev/null
+++ b/gdb/tui/tui-file.h
@@ -0,0 +1,29 @@
+/* UI_FILE - a generic STDIO like output stream.
+ Copyright 1999, 2000 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. */
+
+#ifndef TUI_FILE_H
+#define TUI_FILE_H
+
+extern struct ui_file *tui_fileopen (FILE *);
+extern struct ui_file *tui_sfileopen (int);
+extern char *tui_file_get_strbuf (struct ui_file *);
+extern void tui_file_adjust_strbuf (int, struct ui_file *);
+
+#endif
diff --git a/gdb/tui/tui-hooks.c b/gdb/tui/tui-hooks.c
new file mode 100644
index 00000000000..27556acfd15
--- /dev/null
+++ b/gdb/tui/tui-hooks.c
@@ -0,0 +1,408 @@
+/* GDB hooks for TUI.
+
+ Copyright 2001, 2002 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. */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include "defs.h"
+#include "symtab.h"
+#include "inferior.h"
+#include "command.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "event-loop.h"
+#include "frame.h"
+#include "breakpoint.h"
+#include "gdb-events.h"
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiLayout.h"
+#include "tuiIO.h"
+#include "tuiRegs.h"
+#include "tuiWin.h"
+#include "tuiStack.h"
+#include "tuiDataWin.h"
+#include "tuiSourceWin.h"
+
+int tui_target_has_run = 0;
+
+static void (* tui_target_new_objfile_chain) (struct objfile*);
+extern void (*selected_frame_level_changed_hook) (int);
+
+static void
+tui_new_objfile_hook (struct objfile* objfile)
+{
+ if (tui_active)
+ {
+ tuiDisplayMainFunction ();
+ }
+
+ if (tui_target_new_objfile_chain)
+ tui_target_new_objfile_chain (objfile);
+}
+
+static int
+tui_query_hook (const char * msg, va_list argp)
+{
+ int retval;
+ int ans2;
+ int answer;
+
+ /* Automatically answer "yes" if input is not from a terminal. */
+ if (!input_from_terminal_p ())
+ return 1;
+
+ echo ();
+ while (1)
+ {
+ wrap_here (""); /* Flush any buffered output */
+ gdb_flush (gdb_stdout);
+
+ vfprintf_filtered (gdb_stdout, msg, argp);
+ printf_filtered ("(y or n) ");
+
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+
+ answer = tui_getc (stdin);
+ clearerr (stdin); /* in case of C-d */
+ if (answer == EOF) /* C-d */
+ {
+ retval = 1;
+ break;
+ }
+ /* Eat rest of input line, to EOF or newline */
+ if (answer != '\n')
+ do
+ {
+ ans2 = tui_getc (stdin);
+ clearerr (stdin);
+ }
+ while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
+
+ if (answer >= 'a')
+ answer -= 040;
+ if (answer == 'Y')
+ {
+ retval = 1;
+ break;
+ }
+ if (answer == 'N')
+ {
+ retval = 0;
+ break;
+ }
+ printf_filtered ("Please answer y or n.\n");
+ }
+ noecho ();
+ return retval;
+}
+
+/* Prevent recursion of registers_changed_hook(). */
+static int tui_refreshing_registers = 0;
+
+static void
+tui_registers_changed_hook (void)
+{
+ struct frame_info *fi;
+
+ fi = selected_frame;
+ if (fi && tui_refreshing_registers == 0)
+ {
+ tui_refreshing_registers = 1;
+#if 0
+ tuiCheckDataValues (fi);
+#endif
+ tui_refreshing_registers = 0;
+ }
+}
+
+static void
+tui_register_changed_hook (int regno)
+{
+ struct frame_info *fi;
+
+ fi = selected_frame;
+ if (fi && tui_refreshing_registers == 0)
+ {
+ tui_refreshing_registers = 1;
+ tuiCheckDataValues (fi);
+ tui_refreshing_registers = 0;
+ }
+}
+
+extern struct breakpoint *breakpoint_chain;
+
+/* Find a breakpoint given its number. Returns null if not found. */
+static struct breakpoint *
+get_breakpoint (int number)
+{
+ struct breakpoint *bp;
+
+ for (bp = breakpoint_chain; bp; bp = bp->next)
+ {
+ if (bp->number == number)
+ return bp;
+ }
+ return 0;
+}
+
+/* Breakpoint creation hook.
+ Update the screen to show the new breakpoint. */
+static void
+tui_event_create_breakpoint (int number)
+{
+ struct breakpoint *bp;
+
+ bp = get_breakpoint (number);
+ if (bp)
+ {
+ switch (bp->type)
+ {
+ case bp_breakpoint:
+ case bp_hardware_breakpoint:
+ tuiAllSetHasBreakAt (bp, 1);
+ tuiUpdateAllExecInfos ();
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+/* Breakpoint deletion hook.
+ Refresh the screen to update the breakpoint marks. */
+static void
+tui_event_delete_breakpoint (int number)
+{
+ struct breakpoint *bp;
+ struct breakpoint *b;
+ int clearIt;
+
+ bp = get_breakpoint (number);
+ if (bp == 0)
+ return;
+
+ /* Before turning off the visuals for the bp, check to see that
+ there are no other bps at the same address. */
+ clearIt = 0;
+ for (b = breakpoint_chain; b; b = b->next)
+ {
+ clearIt = (b == bp || b->address != bp->address);
+ if (!clearIt)
+ break;
+ }
+
+ if (clearIt)
+ {
+ tuiAllSetHasBreakAt (bp, 0);
+ tuiUpdateAllExecInfos ();
+ }
+}
+
+static void
+tui_event_modify_breakpoint (int number)
+{
+ ;
+}
+
+static void
+tui_event_default (int number)
+{
+ ;
+}
+
+static struct gdb_events *tui_old_event_hooks;
+
+static struct gdb_events tui_event_hooks =
+{
+ tui_event_create_breakpoint,
+ tui_event_delete_breakpoint,
+ tui_event_modify_breakpoint,
+ tui_event_default,
+ tui_event_default,
+ tui_event_default
+};
+
+/* Called when going to wait for the target.
+ Leave curses mode and setup program mode. */
+static ptid_t
+tui_target_wait_hook (ptid_t pid, struct target_waitstatus *status)
+{
+ ptid_t res;
+
+ /* Leave tui mode (optional). */
+#if 0
+ if (tui_active)
+ {
+ target_terminal_ours ();
+ endwin ();
+ target_terminal_inferior ();
+ }
+#endif
+ tui_target_has_run = 1;
+ res = target_wait (pid, status);
+
+ if (tui_active)
+ {
+ /* TODO: need to refresh (optional). */
+ }
+ return res;
+}
+
+/* The selected frame has changed. This is happens after a target
+ stop or when the user explicitly changes the frame (up/down/thread/...). */
+static void
+tui_selected_frame_level_changed_hook (int level)
+{
+ struct frame_info *fi;
+
+ fi = selected_frame;
+ /* Ensure that symbols for this frame are read in. Also, determine the
+ source language of this frame, and switch to it if desired. */
+ if (fi)
+ {
+ struct symtab *s;
+
+ s = find_pc_symtab (fi->pc);
+ /* elz: this if here fixes the problem with the pc not being displayed
+ in the tui asm layout, with no debug symbols. The value of s
+ would be 0 here, and select_source_symtab would abort the
+ command by calling the 'error' function */
+ if (s)
+ {
+ select_source_symtab (s);
+ tuiShowFrameInfo (fi);
+ }
+
+ /* Refresh the register window if it's visible. */
+ if (tui_is_window_visible (DATA_WIN))
+ {
+ tui_refreshing_registers = 1;
+ tuiCheckDataValues (fi);
+ tui_refreshing_registers = 0;
+ }
+ }
+}
+
+/* Called from print_frame_info to list the line we stopped in. */
+static void
+tui_print_frame_info_listing_hook (struct symtab *s, int line,
+ int stopline, int noerror)
+{
+ select_source_symtab (s);
+ tuiShowFrameInfo (selected_frame);
+}
+
+/* Install the TUI specific hooks. */
+void
+tui_install_hooks (void)
+{
+ target_wait_hook = tui_target_wait_hook;
+ selected_frame_level_changed_hook = tui_selected_frame_level_changed_hook;
+ print_frame_info_listing_hook = tui_print_frame_info_listing_hook;
+
+ query_hook = tui_query_hook;
+
+ /* Install the event hooks. */
+ tui_old_event_hooks = set_gdb_event_hooks (&tui_event_hooks);
+
+ registers_changed_hook = tui_registers_changed_hook;
+ register_changed_hook = tui_register_changed_hook;
+}
+
+/* Remove the TUI specific hooks. */
+void
+tui_remove_hooks (void)
+{
+ target_wait_hook = 0;
+ selected_frame_level_changed_hook = 0;
+ print_frame_info_listing_hook = 0;
+ query_hook = 0;
+ registers_changed_hook = 0;
+ register_changed_hook = 0;
+
+ /* Restore the previous event hooks. */
+ set_gdb_event_hooks (tui_old_event_hooks);
+}
+
+/* Cleanup the tui before exiting. */
+static void
+tui_exit (void)
+{
+ /* Disable the tui. Curses mode is left leaving the screen
+ in a clean state (see endwin()). */
+ tui_disable ();
+}
+
+/* Initialize the tui by installing several gdb hooks, initializing
+ the tui IO and preparing the readline with the kind binding. */
+static void
+tui_init_hook (char *argv0)
+{
+ /* Install exit handler to leave the screen in a good shape. */
+ atexit (tui_exit);
+
+ initializeStaticData ();
+
+ /* Install the permanent hooks. */
+ tui_target_new_objfile_chain = target_new_objfile_hook;
+ target_new_objfile_hook = tui_new_objfile_hook;
+
+ tui_initialize_io ();
+ tui_initialize_readline ();
+
+ /* Decide in which mode to start using GDB (based on -tui). */
+ if (tui_version)
+ {
+ tui_enable ();
+ }
+}
+
+/* Initialize the tui. */
+void
+_initialize_tui (void)
+{
+ /* Setup initialization hook. */
+ init_ui_hook = tui_init_hook;
+}
+
diff --git a/gdb/tui/tui-out.c b/gdb/tui/tui-out.c
new file mode 100644
index 00000000000..a8cc58ba5ca
--- /dev/null
+++ b/gdb/tui/tui-out.c
@@ -0,0 +1,410 @@
+/* Output generating routines for GDB CLI.
+
+ Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Solutions.
+ Written by Fernando Nasser for Cygnus.
+
+ 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 "defs.h"
+#include "ui-out.h"
+#include "tui.h"
+#include "gdb_string.h"
+#include "gdb_assert.h"
+
+struct ui_out_data
+ {
+ struct ui_file *stream;
+ int suppress_output;
+ int line;
+ int start_of_line;
+ };
+
+/* These are the CLI output functions */
+
+static void tui_table_begin (struct ui_out *uiout, int nbrofcols,
+ int nr_rows, const char *tblid);
+static void tui_table_body (struct ui_out *uiout);
+static void tui_table_end (struct ui_out *uiout);
+static void tui_table_header (struct ui_out *uiout, int width,
+ enum ui_align alig, const char *col_name,
+ const char *colhdr);
+static void tui_begin (struct ui_out *uiout, enum ui_out_type type,
+ int level, const char *lstid);
+static void tui_end (struct ui_out *uiout, enum ui_out_type type, int level);
+static void tui_field_int (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alig, const char *fldname, int value);
+static void tui_field_skip (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alig, const char *fldname);
+static void tui_field_string (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alig, const char *fldname,
+ const char *string);
+static void tui_field_fmt (struct ui_out *uiout, int fldno,
+ int width, enum ui_align align,
+ const char *fldname, const char *format,
+ va_list args);
+static void tui_spaces (struct ui_out *uiout, int numspaces);
+static void tui_text (struct ui_out *uiout, const char *string);
+static void tui_message (struct ui_out *uiout, int verbosity,
+ const char *format, va_list args);
+static void tui_wrap_hint (struct ui_out *uiout, char *identstring);
+static void tui_flush (struct ui_out *uiout);
+
+/* This is the CLI ui-out implementation functions vector */
+
+/* FIXME: This can be initialized dynamically after default is set to
+ handle initial output in main.c */
+
+static struct ui_out_impl tui_ui_out_impl =
+{
+ tui_table_begin,
+ tui_table_body,
+ tui_table_end,
+ tui_table_header,
+ tui_begin,
+ tui_end,
+ tui_field_int,
+ tui_field_skip,
+ tui_field_string,
+ tui_field_fmt,
+ tui_spaces,
+ tui_text,
+ tui_message,
+ tui_wrap_hint,
+ tui_flush,
+ 0, /* Does not need MI hacks (i.e. needs CLI hacks). */
+};
+
+/* Prototypes for local functions */
+
+extern void _initialize_tui_out (void);
+
+static void field_separator (void);
+
+static void out_field_fmt (struct ui_out *uiout, int fldno,
+ const char *fldname,
+ const char *format,...);
+
+/* local variables */
+
+/* (none yet) */
+
+/* Mark beginning of a table */
+
+void
+tui_table_begin (struct ui_out *uiout, int nbrofcols,
+ int nr_rows,
+ const char *tblid)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (nr_rows == 0)
+ data->suppress_output = 1;
+ else
+ /* Only the table suppresses the output and, fortunatly, a table
+ is not a recursive data structure. */
+ gdb_assert (data->suppress_output == 0);
+}
+
+/* Mark beginning of a table body */
+
+void
+tui_table_body (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ /* first, close the table header line */
+ tui_text (uiout, "\n");
+}
+
+/* Mark end of a table */
+
+void
+tui_table_end (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ data->suppress_output = 0;
+}
+
+/* Specify table header */
+
+void
+tui_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
+ const char *col_name,
+ const char *colhdr)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ tui_field_string (uiout, 0, width, alignment, 0, colhdr);
+}
+
+/* Mark beginning of a list */
+
+void
+tui_begin (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level,
+ const char *id)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+}
+
+/* Mark end of a list */
+
+void
+tui_end (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+}
+
+/* output an int field */
+
+void
+tui_field_int (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alignment,
+ const char *fldname, int value)
+{
+ char buffer[20]; /* FIXME: how many chars long a %d can become? */
+
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+
+ /* Don't print line number, keep it for later. */
+ if (data->start_of_line == 0 && strcmp (fldname, "line") == 0)
+ {
+ data->start_of_line ++;
+ data->line = value;
+ return;
+ }
+ data->start_of_line ++;
+ sprintf (buffer, "%d", value);
+ tui_field_string (uiout, fldno, width, alignment, fldname, buffer);
+}
+
+/* used to ommit a field */
+
+void
+tui_field_skip (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alignment,
+ const char *fldname)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ tui_field_string (uiout, fldno, width, alignment, fldname, "");
+}
+
+/* other specific tui_field_* end up here so alignment and field
+ separators are both handled by tui_field_string */
+
+void
+tui_field_string (struct ui_out *uiout,
+ int fldno,
+ int width,
+ enum ui_align align,
+ const char *fldname,
+ const char *string)
+{
+ int before = 0;
+ int after = 0;
+
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+
+ if (fldname && data->line > 0 && strcmp (fldname, "file") == 0)
+ {
+ data->start_of_line ++;
+ if (data->line > 0)
+ {
+ tui_show_source (string, data->line);
+ }
+ return;
+ }
+
+ data->start_of_line ++;
+ if ((align != ui_noalign) && string)
+ {
+ before = width - strlen (string);
+ if (before <= 0)
+ before = 0;
+ else
+ {
+ if (align == ui_right)
+ after = 0;
+ else if (align == ui_left)
+ {
+ after = before;
+ before = 0;
+ }
+ else
+ /* ui_center */
+ {
+ after = before / 2;
+ before -= after;
+ }
+ }
+ }
+
+ if (before)
+ ui_out_spaces (uiout, before);
+ if (string)
+ out_field_fmt (uiout, fldno, fldname, "%s", string);
+ if (after)
+ ui_out_spaces (uiout, after);
+
+ if (align != ui_noalign)
+ field_separator ();
+}
+
+/* This is the only field function that does not align */
+
+void
+tui_field_fmt (struct ui_out *uiout, int fldno,
+ int width, enum ui_align align,
+ const char *fldname,
+ const char *format,
+ va_list args)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+
+ data->start_of_line ++;
+ vfprintf_filtered (data->stream, format, args);
+
+ if (align != ui_noalign)
+ field_separator ();
+}
+
+void
+tui_spaces (struct ui_out *uiout, int numspaces)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ print_spaces_filtered (numspaces, data->stream);
+}
+
+void
+tui_text (struct ui_out *uiout, const char *string)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ data->start_of_line ++;
+ if (data->line > 0)
+ {
+ if (strchr (string, '\n') != 0)
+ {
+ data->line = -1;
+ data->start_of_line = 0;
+ }
+ return;
+ }
+ if (strchr (string, '\n'))
+ data->start_of_line = 0;
+ fputs_filtered (string, data->stream);
+}
+
+void
+tui_message (struct ui_out *uiout, int verbosity,
+ const char *format, va_list args)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ if (ui_out_get_verblvl (uiout) >= verbosity)
+ vfprintf_unfiltered (data->stream, format, args);
+}
+
+void
+tui_wrap_hint (struct ui_out *uiout, char *identstring)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->suppress_output)
+ return;
+ wrap_here (identstring);
+}
+
+void
+tui_flush (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ gdb_flush (data->stream);
+}
+
+/* local functions */
+
+/* Like tui_field_fmt, but takes a variable number of args
+ and makes a va_list and does not insert a separator */
+
+/* VARARGS */
+static void
+out_field_fmt (struct ui_out *uiout, int fldno,
+ const char *fldname,
+ const char *format,...)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ va_list args;
+
+ va_start (args, format);
+ vfprintf_filtered (data->stream, format, args);
+
+ va_end (args);
+}
+
+/* access to ui_out format private members */
+
+static void
+field_separator (void)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ fputc_filtered (' ', data->stream);
+}
+
+/* initalize private members at startup */
+
+struct ui_out *
+tui_out_new (struct ui_file *stream)
+{
+ int flags = 0;
+
+ struct ui_out_data *data = XMALLOC (struct ui_out_data);
+ data->stream = stream;
+ data->suppress_output = 0;
+ data->line = -1;
+ data->start_of_line = 1;
+ return ui_out_new (&tui_ui_out_impl, data, flags);
+}
+
+/* standard gdb initialization hook */
+void
+_initialize_tui_out (void)
+{
+ /* nothing needs to be done */
+}
diff --git a/gdb/tui/tui.c b/gdb/tui/tui.c
new file mode 100644
index 00000000000..7912efc8765
--- /dev/null
+++ b/gdb/tui/tui.c
@@ -0,0 +1,456 @@
+/* General functions for the WDB TUI.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+ Inc.
+
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <malloc.h>
+#ifdef HAVE_TERM_H
+#include <term.h>
+#endif
+#include <signal.h>
+#include <fcntl.h>
+#include <termio.h>
+#include <setjmp.h>
+#include "defs.h"
+#include "gdbcmd.h"
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiLayout.h"
+#include "tuiIO.h"
+#include "tuiRegs.h"
+#include "tuiStack.h"
+#include "tuiWin.h"
+#include "tuiSourceWin.h"
+#include "readline/readline.h"
+#include "target.h"
+#include "frame.h"
+#include "breakpoint.h"
+#include "inferior.h"
+
+/* Tells whether the TUI is active or not. */
+int tui_active = 0;
+static int tui_finish_init = 1;
+
+/* Switch the output mode between TUI/standard gdb. */
+static int
+tui_switch_mode (void)
+{
+ if (tui_active)
+ {
+ tui_disable ();
+ rl_prep_terminal (0);
+
+ printf_filtered ("Left the TUI mode\n");
+ }
+ else
+ {
+ rl_deprep_terminal ();
+ tui_enable ();
+ printf_filtered ("Entered the TUI mode\n");
+ }
+
+ /* Clear the readline in case switching occurred in middle of something. */
+ if (rl_end)
+ rl_kill_text (0, rl_end);
+
+ /* Since we left the curses mode, the terminal mode is restored to
+ some previous state. That state may not be suitable for readline
+ to work correctly (it may be restored in line mode). We force an
+ exit of the current readline so that readline is re-entered and it
+ will be able to setup the terminal for its needs. By re-entering
+ in readline, we also redisplay its prompt in the non-curses mode. */
+ rl_newline (1, '\n');
+
+ /* Make sure the \n we are returning does not repeat the last command. */
+ dont_repeat ();
+ return 0;
+}
+
+/* Change the TUI layout to show a next layout.
+ This function is bound to CTRL-X 2. It is intended to provide
+ a functionality close to the Emacs split-window command. We always
+ show two windows (src+asm), (src+regs) or (asm+regs). */
+static int
+tui_change_windows (void)
+{
+ if (!tui_active)
+ tui_switch_mode ();
+
+ if (tui_active)
+ {
+ TuiLayoutType new_layout;
+ TuiRegisterDisplayType regs_type = TUI_UNDEFINED_REGS;
+
+ new_layout = currentLayout ();
+
+ /* Select a new layout to have a rolling layout behavior
+ with always two windows (except when undefined). */
+ switch (new_layout)
+ {
+ case SRC_COMMAND:
+ new_layout = SRC_DISASSEM_COMMAND;
+ break;
+
+ case DISASSEM_COMMAND:
+ new_layout = SRC_DISASSEM_COMMAND;
+ break;
+
+ case SRC_DATA_COMMAND:
+ new_layout = SRC_DISASSEM_COMMAND;
+ break;
+
+ case SRC_DISASSEM_COMMAND:
+ new_layout = DISASSEM_DATA_COMMAND;
+ break;
+
+ case DISASSEM_DATA_COMMAND:
+ new_layout = SRC_DATA_COMMAND;
+ break;
+
+ default:
+ new_layout = SRC_COMMAND;
+ break;
+ }
+ tuiSetLayout (new_layout, regs_type);
+ }
+ return 0;
+}
+
+
+/* Delete the second TUI window to only show one. */
+static int
+tui_delete_other_windows (void)
+{
+ if (!tui_active)
+ tui_switch_mode ();
+
+ if (tui_active)
+ {
+ TuiLayoutType new_layout;
+ TuiRegisterDisplayType regs_type = TUI_UNDEFINED_REGS;
+
+ new_layout = currentLayout ();
+
+ /* Kill one window. */
+ switch (new_layout)
+ {
+ case SRC_COMMAND:
+ case SRC_DATA_COMMAND:
+ case SRC_DISASSEM_COMMAND:
+ default:
+ new_layout = SRC_COMMAND;
+ break;
+
+ case DISASSEM_COMMAND:
+ case DISASSEM_DATA_COMMAND:
+ new_layout = DISASSEM_COMMAND;
+ break;
+ }
+ tuiSetLayout (new_layout, regs_type);
+ }
+ return 0;
+}
+
+/* Initialize readline and configure the keymap for the switching
+ key shortcut. */
+void
+tui_initialize_readline ()
+{
+ rl_initialize ();
+
+ rl_add_defun ("tui-switch-mode", tui_switch_mode, -1);
+ rl_bind_key_in_map ('a', tui_switch_mode, emacs_ctlx_keymap);
+ rl_bind_key_in_map ('A', tui_switch_mode, emacs_ctlx_keymap);
+ rl_bind_key_in_map (CTRL ('A'), tui_switch_mode, emacs_ctlx_keymap);
+ rl_bind_key_in_map ('1', tui_delete_other_windows, emacs_ctlx_keymap);
+ rl_bind_key_in_map ('2', tui_change_windows, emacs_ctlx_keymap);
+}
+
+/* Enter in the tui mode (curses).
+ When in normal mode, it installs the tui hooks in gdb, redirects
+ the gdb output, configures the readline to work in tui mode.
+ When in curses mode, it does nothing. */
+void
+tui_enable (void)
+{
+ if (tui_active)
+ return;
+
+ /* To avoid to initialize curses when gdb starts, there is a defered
+ curses initialization. This initialization is made only once
+ and the first time the curses mode is entered. */
+ if (tui_finish_init)
+ {
+ WINDOW *w;
+
+ w = initscr ();
+
+ cbreak ();
+ noecho ();
+ /*timeout (1);*/
+ nodelay(w, FALSE);
+ nl();
+ keypad (w, TRUE);
+ rl_initialize ();
+ setTermHeightTo (LINES);
+ setTermWidthTo (COLS);
+ def_prog_mode ();
+
+ tuiSetLocatorContent (0);
+ showLayout (SRC_COMMAND);
+ tuiSetWinFocusTo (srcWin);
+ keypad (cmdWin->generic.handle, TRUE);
+ wrefresh (cmdWin->generic.handle);
+ tui_finish_init = 0;
+ }
+ else
+ {
+ /* Save the current gdb setting of the terminal.
+ Curses will restore this state when endwin() is called. */
+ def_shell_mode ();
+ clearok (stdscr, TRUE);
+ }
+
+ /* Install the TUI specific hooks. */
+ tui_install_hooks ();
+
+ tui_update_variables ();
+
+ tui_setup_io (1);
+
+ tui_version = 1;
+ tui_active = 1;
+ refresh ();
+}
+
+/* Leave the tui mode.
+ Remove the tui hooks and configure the gdb output and readline
+ back to their original state. The curses mode is left so that
+ the terminal setting is restored to the point when we entered. */
+void
+tui_disable (void)
+{
+ if (!tui_active)
+ return;
+
+ /* Remove TUI hooks. */
+ tui_remove_hooks ();
+
+ /* Leave curses and restore previous gdb terminal setting. */
+ endwin ();
+
+ /* gdb terminal has changed, update gdb internal copy of it
+ so that terminal management with the inferior works. */
+ tui_setup_io (0);
+
+ tui_version = 0;
+ tui_active = 0;
+}
+
+/* Wrapper on top of free() to ensure that input address
+ is greater than 0x0. */
+void
+tuiFree (char *ptr)
+{
+ if (ptr != (char *) NULL)
+ {
+ xfree (ptr);
+ }
+}
+
+/* Determine what the low address will be to display in the TUI's
+ disassembly window. This may or may not be the same as the
+ low address input. */
+CORE_ADDR
+tuiGetLowDisassemblyAddress (CORE_ADDR low, CORE_ADDR pc)
+{
+ int line;
+ CORE_ADDR newLow;
+
+ /* Determine where to start the disassembly so that the pc is about in the
+ middle of the viewport. */
+ for (line = 0, newLow = pc;
+ (newLow > low &&
+ line < (tuiDefaultWinViewportHeight (DISASSEM_WIN,
+ DISASSEM_COMMAND) / 2));)
+ {
+ bfd_byte buffer[4];
+
+ newLow -= sizeof (bfd_getb32 (buffer));
+ line++;
+ }
+
+ return newLow;
+}
+
+void
+strcat_to_buf (char *buf, int buflen, char *itemToAdd)
+{
+ if (itemToAdd != (char *) NULL && buf != (char *) NULL)
+ {
+ if ((strlen (buf) + strlen (itemToAdd)) <= buflen)
+ strcat (buf, itemToAdd);
+ else
+ strncat (buf, itemToAdd, (buflen - strlen (buf)));
+ }
+}
+
+#if 0
+/* Solaris <sys/termios.h> defines CTRL. */
+#ifndef CTRL
+#define CTRL(x) (x & ~0140)
+#endif
+
+#define FILEDES 2
+#define CHK(val, dft) (val<=0 ? dft : val)
+
+static void
+_tuiReset (void)
+{
+ struct termio mode;
+
+ /*
+ ** reset the teletype mode bits to a sensible state.
+ ** Copied tset.c
+ */
+#if ! defined (USG) && defined (TIOCGETC)
+ struct tchars tbuf;
+#endif /* !USG && TIOCGETC */
+#ifdef UCB_NTTY
+ struct ltchars ltc;
+
+ if (ldisc == NTTYDISC)
+ {
+ ioctl (FILEDES, TIOCGLTC, &ltc);
+ ltc.t_suspc = CHK (ltc.t_suspc, CTRL ('Z'));
+ ltc.t_dsuspc = CHK (ltc.t_dsuspc, CTRL ('Y'));
+ ltc.t_rprntc = CHK (ltc.t_rprntc, CTRL ('R'));
+ ltc.t_flushc = CHK (ltc.t_flushc, CTRL ('O'));
+ ltc.t_werasc = CHK (ltc.t_werasc, CTRL ('W'));
+ ltc.t_lnextc = CHK (ltc.t_lnextc, CTRL ('V'));
+ ioctl (FILEDES, TIOCSLTC, &ltc);
+ }
+#endif /* UCB_NTTY */
+#ifndef USG
+#ifdef TIOCGETC
+ ioctl (FILEDES, TIOCGETC, &tbuf);
+ tbuf.t_intrc = CHK (tbuf.t_intrc, CTRL ('?'));
+ tbuf.t_quitc = CHK (tbuf.t_quitc, CTRL ('\\'));
+ tbuf.t_startc = CHK (tbuf.t_startc, CTRL ('Q'));
+ tbuf.t_stopc = CHK (tbuf.t_stopc, CTRL ('S'));
+ tbuf.t_eofc = CHK (tbuf.t_eofc, CTRL ('D'));
+ /* brkc is left alone */
+ ioctl (FILEDES, TIOCSETC, &tbuf);
+#endif /* TIOCGETC */
+ mode.sg_flags &= ~(RAW
+#ifdef CBREAK
+ | CBREAK
+#endif /* CBREAK */
+ | VTDELAY | ALLDELAY);
+ mode.sg_flags |= XTABS | ECHO | CRMOD | ANYP;
+#else /*USG */
+ ioctl (FILEDES, TCGETA, &mode);
+ mode.c_cc[VINTR] = CHK (mode.c_cc[VINTR], CTRL ('?'));
+ mode.c_cc[VQUIT] = CHK (mode.c_cc[VQUIT], CTRL ('\\'));
+ mode.c_cc[VEOF] = CHK (mode.c_cc[VEOF], CTRL ('D'));
+
+ mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | INLCR | IGNCR | IUCLC | IXOFF);
+ mode.c_iflag |= (BRKINT | ISTRIP | ICRNL | IXON);
+ mode.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |
+ NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY);
+ mode.c_oflag |= (OPOST | ONLCR);
+ mode.c_cflag &= ~(CSIZE | PARODD | CLOCAL);
+#ifndef hp9000s800
+ mode.c_cflag |= (CS8 | CREAD);
+#else /*hp9000s800 */
+ mode.c_cflag |= (CS8 | CSTOPB | CREAD);
+#endif /* hp9000s800 */
+ mode.c_lflag &= ~(XCASE | ECHONL | NOFLSH);
+ mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOK);
+ ioctl (FILEDES, TCSETAW, &mode);
+#endif /* USG */
+
+ return;
+} /* _tuiReset */
+#endif
+
+void
+tui_show_source (const char *file, int line)
+{
+ /* make sure that the source window is displayed */
+ tuiAddWinToLayout (SRC_WIN);
+
+ tuiUpdateSourceWindowsWithLine (current_source_symtab, line);
+ tuiUpdateLocatorFilename (file);
+}
+
+void
+tui_show_assembly (CORE_ADDR addr)
+{
+ tuiAddWinToLayout (DISASSEM_WIN);
+ tuiUpdateSourceWindowsWithAddr (addr);
+}
+
+int
+tui_is_window_visible (TuiWinType type)
+{
+ if (tui_version == 0)
+ return 0;
+
+ if (winList[type] == 0)
+ return 0;
+
+ return winList[type]->generic.isVisible;
+}
+
+int
+tui_get_command_dimension (int *width, int *height)
+{
+ if (!tui_version || !m_winPtrNotNull (cmdWin))
+ {
+ return 0;
+ }
+
+ *width = cmdWin->generic.width;
+ *height = cmdWin->generic.height;
+ return 1;
+}
diff --git a/gdb/tui/tui.h b/gdb/tui/tui.h
new file mode 100644
index 00000000000..fcea91afe66
--- /dev/null
+++ b/gdb/tui/tui.h
@@ -0,0 +1,141 @@
+/* External/Public TUI Header File.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef TUI_H
+#define TUI_H
+
+#include <stdarg.h>
+#include <string.h>
+#include "ansidecl.h"
+
+#if defined(reg)
+#undef reg
+#endif
+#if defined(chtype)
+#undef chtype
+#endif
+
+/* Opaque data type */
+typedef char *Opaque;
+typedef
+Opaque (*OpaqueFuncPtr) (va_list);
+ typedef char **OpaqueList;
+ typedef OpaqueList OpaquePtr;
+
+/* Generic function pointer */
+ typedef void (*TuiVoidFuncPtr) (va_list);
+ typedef int (*TuiIntFuncPtr) (va_list);
+/*
+ typedef Opaque (*TuiOpaqueFuncPtr) (va_list);
+ */
+ typedef OpaqueFuncPtr TuiOpaqueFuncPtr;
+
+extern Opaque vcatch_errors (OpaqueFuncPtr, ...);
+extern Opaque va_catch_errors (OpaqueFuncPtr, va_list);
+
+extern void strcat_to_buf (char *, int, char *);
+extern void strcat_to_buf_with_fmt (char *, int, char *, ...);
+
+/* Types of error returns */
+ typedef enum
+ {
+ TUI_SUCCESS,
+ TUI_FAILURE
+ }
+TuiStatus, *TuiStatusPtr;
+
+/* Types of windows */
+ typedef enum
+ {
+ SRC_WIN = 0,
+ DISASSEM_WIN,
+ DATA_WIN,
+ CMD_WIN,
+ /* This must ALWAYS be AFTER the major windows last */
+ MAX_MAJOR_WINDOWS,
+ /* auxillary windows */
+ LOCATOR_WIN,
+ EXEC_INFO_WIN,
+ DATA_ITEM_WIN,
+ /* This must ALWAYS be next to last */
+ MAX_WINDOWS,
+ UNDEFINED_WIN /* LAST */
+ }
+TuiWinType, *TuiWinTypePtr;
+
+/* This is a point definition */
+ typedef struct _TuiPoint
+ {
+ int x, y;
+ }
+TuiPoint, *TuiPointPtr;
+
+/* GENERAL TUI FUNCTIONS */
+/* tui.c */
+extern void tuiFree (char *);
+extern CORE_ADDR tuiGetLowDisassemblyAddress (CORE_ADDR, CORE_ADDR);
+extern void tui_show_assembly (CORE_ADDR addr);
+extern int tui_is_window_visible (TuiWinType type);
+extern int tui_get_command_dimension (int *width, int *height);
+
+/* Initialize readline and configure the keymap for the switching
+ key shortcut. */
+extern void tui_initialize_readline (void);
+
+/* Enter in the tui mode (curses). */
+extern void tui_enable (void);
+
+/* Leave the tui mode. */
+extern void tui_disable (void);
+
+extern void tui_initialize_io (void);
+
+extern void tui_initialize_readline (void);
+
+extern int tui_active;
+
+extern void tui_install_hooks (void);
+extern void tui_remove_hooks (void);
+
+extern void tui_show_source (const char *file, int line);
+
+extern struct ui_out *tui_out_new (struct ui_file *stream);
+
+/* tuiDataWin.c */
+extern void tui_vCheckDataValues (va_list);
+
+/* tuiIO.c */
+extern void tui_vStartNewLines (va_list);
+
+/* tuiLayout.c */
+extern TuiStatus tui_set_layout (const char *);
+
+/* tuiSourceWin.c */
+extern void tuiDisplayMainFunction (void);
+extern void tuiUpdateAllExecInfos (void);
+extern void tuiUpdateOnEnd (void);
+extern void tui_vAllSetHasBreakAt (va_list);
+extern void tui_vUpdateSourceWindowsWithAddr (va_list);
+
+/* tuiStack.c */
+extern void tui_vShowFrameInfo (va_list);
+extern void tui_vUpdateLocatorFilename (va_list);
+#endif /* TUI_H */
diff --git a/gdb/tui/tuiCommand.c b/gdb/tui/tuiCommand.c
new file mode 100644
index 00000000000..ca3d5318ea9
--- /dev/null
+++ b/gdb/tui/tuiCommand.c
@@ -0,0 +1,147 @@
+/* Specific command window processing.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+ Inc.
+
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include "defs.h"
+#include <ctype.h>
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiWin.h"
+#include "tuiIO.h"
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS FORWARD DECLS **
+******************************************/
+
+
+
+/*****************************************
+** PUBLIC FUNCTIONS **
+******************************************/
+
+/*
+ ** tuiDispatchCtrlChar().
+ ** Dispatch the correct tui function based upon the control character.
+ */
+unsigned int
+tuiDispatchCtrlChar (unsigned int ch)
+{
+ TuiWinInfoPtr winInfo = tuiWinWithFocus ();
+ WINDOW *w = cmdWin->generic.handle;
+
+ /*
+ ** If the command window has the logical focus, or no-one does
+ ** assume it is the command window; in this case, pass the
+ ** character on through and do nothing here.
+ */
+ if (winInfo == (TuiWinInfoPtr) NULL || winInfo == cmdWin)
+ return ch;
+ else
+ {
+ unsigned int c = 0, chCopy = ch;
+ register int i;
+ char *term;
+
+ /* If this is an xterm, page next/prev keys aren't returned
+ ** by keypad as a single char, so we must handle them here.
+ ** Seems like a bug in the curses library?
+ */
+ term = (char *) getenv ("TERM");
+ for (i = 0; (term && term[i]); i++)
+ term[i] = toupper (term[i]);
+ if ((strcmp (term, "XTERM") == 0) && m_isStartSequence (ch))
+ {
+ unsigned int pageCh = 0, tmpChar;
+
+ tmpChar = 0;
+ while (!m_isEndSequence (tmpChar))
+ {
+ tmpChar = (int) wgetch (w);
+ if (tmpChar == ERR)
+ {
+ return ch;
+ }
+ if (!tmpChar)
+ break;
+ if (tmpChar == 53)
+ pageCh = KEY_PPAGE;
+ else if (tmpChar == 54)
+ pageCh = KEY_NPAGE;
+ else
+ {
+ return 0;
+ }
+ }
+ chCopy = pageCh;
+ }
+
+ switch (chCopy)
+ {
+ case KEY_NPAGE:
+ tuiScrollForward (winInfo, 0);
+ break;
+ case KEY_PPAGE:
+ tuiScrollBackward (winInfo, 0);
+ break;
+ case KEY_DOWN:
+ case KEY_SF:
+ tuiScrollForward (winInfo, 1);
+ break;
+ case KEY_UP:
+ case KEY_SR:
+ tuiScrollBackward (winInfo, 1);
+ break;
+ case KEY_RIGHT:
+ tuiScrollLeft (winInfo, 1);
+ break;
+ case KEY_LEFT:
+ tuiScrollRight (winInfo, 1);
+ break;
+ case '\f':
+ tuiRefreshAll ();
+ break;
+ default:
+ c = chCopy;
+ break;
+ }
+ return c;
+ }
+}
diff --git a/gdb/tui/tuiCommand.h b/gdb/tui/tuiCommand.h
new file mode 100644
index 00000000000..7afeb1bb395
--- /dev/null
+++ b/gdb/tui/tuiCommand.h
@@ -0,0 +1,42 @@
+/* Specific command window processing.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef _TUI_COMMAND_H
+#define _TUI_COMMAND_H
+/*
+ ** This header file supports
+ */
+
+
+/*****************************************
+** TYPE DEFINITIONS **
+******************************************/
+
+
+
+/*****************************************
+** PUBLIC FUNCTION EXTERNAL DECLS **
+******************************************/
+
+extern unsigned int tuiDispatchCtrlChar (unsigned int);
+
+#endif
+/*_TUI_COMMAND_H*/
diff --git a/gdb/tui/tuiData.c b/gdb/tui/tuiData.c
new file mode 100644
index 00000000000..30efba8b11c
--- /dev/null
+++ b/gdb/tui/tuiData.c
@@ -0,0 +1,1357 @@
+/* TUI data manipulation routines.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+ Inc.
+
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include "defs.h"
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiGeneralWin.h"
+
+/****************************
+** GLOBAL DECLARATIONS
+****************************/
+TuiWinInfoPtr winList[MAX_MAJOR_WINDOWS];
+
+/***************************
+** Private Definitions
+****************************/
+#define FILE_WIDTH 30
+#define PROC_WIDTH 40
+#define LINE_WIDTH 4
+#define PC_WIDTH 8
+
+/***************************
+** Private data
+****************************/
+static char *_tuiNullStr = TUI_NULL_STR;
+static char *_tuiBlankStr = " ";
+static char *_tuiLocationStr = " >";
+static char *_tuiBreakStr = " * ";
+static char *_tuiBreakLocationStr = " *>";
+static TuiLayoutType _currentLayout = UNDEFINED_LAYOUT;
+static int _termHeight, _termWidth;
+static int _historyLimit = DEFAULT_HISTORY_COUNT;
+static TuiGenWinInfo _locator;
+static TuiGenWinInfo _execInfo[2];
+static TuiWinInfoPtr _srcWinList[2];
+static TuiList _sourceWindows =
+{(OpaqueList) _srcWinList, 0};
+static int _defaultTabLen = DEFAULT_TAB_LEN;
+static TuiWinInfoPtr _winWithFocus = (TuiWinInfoPtr) NULL;
+static TuiLayoutDef _layoutDef =
+{SRC_WIN, /* displayMode */
+ FALSE, /* split */
+ TUI_UNDEFINED_REGS, /* regsDisplayType */
+ TUI_SFLOAT_REGS}; /* floatRegsDisplayType */
+static int _winResized = FALSE;
+
+
+/*********************************
+** Static function forward decls
+**********************************/
+static void freeContent (TuiWinContent, int, TuiWinType);
+static void freeContentElements (TuiWinContent, int, TuiWinType);
+
+
+
+/*********************************
+** PUBLIC FUNCTIONS
+**********************************/
+
+/******************************************
+** ACCESSORS & MUTATORS FOR PRIVATE DATA
+******************************************/
+
+/*
+ ** tuiWinResized().
+ ** Answer a whether the terminal window has been resized or not
+ */
+int
+tuiWinResized (void)
+{
+ return _winResized;
+} /* tuiWinResized */
+
+
+/*
+ ** tuiSetWinResized().
+ ** Set a whether the terminal window has been resized or not
+ */
+void
+tuiSetWinResizedTo (int resized)
+{
+ _winResized = resized;
+
+ return;
+} /* tuiSetWinResizedTo */
+
+
+/*
+ ** tuiLayoutDef().
+ ** Answer a pointer to the current layout definition
+ */
+TuiLayoutDefPtr
+tuiLayoutDef (void)
+{
+ return &_layoutDef;
+} /* tuiLayoutDef */
+
+
+/*
+ ** tuiWinWithFocus().
+ ** Answer the window with the logical focus
+ */
+TuiWinInfoPtr
+tuiWinWithFocus (void)
+{
+ return _winWithFocus;
+} /* tuiWinWithFocus */
+
+
+/*
+ ** tuiSetWinWithFocus().
+ ** Set the window that has the logical focus
+ */
+void
+tuiSetWinWithFocus (TuiWinInfoPtr winInfo)
+{
+ _winWithFocus = winInfo;
+
+ return;
+} /* tuiSetWinWithFocus */
+
+
+/*
+ ** tuiDefaultTabLen().
+ ** Answer the length in chars, of tabs
+ */
+int
+tuiDefaultTabLen (void)
+{
+ return _defaultTabLen;
+} /* tuiDefaultTabLen */
+
+
+/*
+ ** tuiSetDefaultTabLen().
+ ** Set the length in chars, of tabs
+ */
+void
+tuiSetDefaultTabLen (int len)
+{
+ _defaultTabLen = len;
+
+ return;
+} /* tuiSetDefaultTabLen */
+
+
+/*
+ ** currentSourceWin()
+ ** Accessor for the current source window. Usually there is only
+ ** one source window (either source or disassembly), but both can
+ ** be displayed at the same time.
+ */
+TuiListPtr
+sourceWindows (void)
+{
+ return &_sourceWindows;
+} /* currentSourceWindows */
+
+
+/*
+ ** clearSourceWindows()
+ ** Clear the list of source windows. Usually there is only one
+ ** source window (either source or disassembly), but both can be
+ ** displayed at the same time.
+ */
+void
+clearSourceWindows (void)
+{
+ _sourceWindows.list[0] = (Opaque) NULL;
+ _sourceWindows.list[1] = (Opaque) NULL;
+ _sourceWindows.count = 0;
+
+ return;
+} /* currentSourceWindows */
+
+
+/*
+ ** clearSourceWindowsDetail()
+ ** Clear the pertinant detail in the source windows.
+ */
+void
+clearSourceWindowsDetail (void)
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ clearWinDetail ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
+
+ return;
+} /* currentSourceWindows */
+
+
+/*
+ ** addSourceWindowToList().
+ ** Add a window to the list of source windows. Usually there is
+ ** only one source window (either source or disassembly), but
+ ** both can be displayed at the same time.
+ */
+void
+addToSourceWindows (TuiWinInfoPtr winInfo)
+{
+ if (_sourceWindows.count < 2)
+ _sourceWindows.list[_sourceWindows.count++] = (Opaque) winInfo;
+
+ return;
+} /* addToSourceWindows */
+
+
+/*
+ ** clearWinDetail()
+ ** Clear the pertinant detail in the windows.
+ */
+void
+clearWinDetail (TuiWinInfoPtr winInfo)
+{
+ if (m_winPtrNotNull (winInfo))
+ {
+ switch (winInfo->generic.type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ winInfo->detail.sourceInfo.startLineOrAddr.addr = 0;
+ winInfo->detail.sourceInfo.horizontalOffset = 0;
+ break;
+ case CMD_WIN:
+ winInfo->detail.commandInfo.curLine =
+ winInfo->detail.commandInfo.curch = 0;
+ break;
+ case DATA_WIN:
+ winInfo->detail.dataDisplayInfo.dataContent =
+ (TuiWinContent) NULL;
+ winInfo->detail.dataDisplayInfo.dataContentCount = 0;
+ winInfo->detail.dataDisplayInfo.regsContent =
+ (TuiWinContent) NULL;
+ winInfo->detail.dataDisplayInfo.regsContentCount = 0;
+ winInfo->detail.dataDisplayInfo.regsDisplayType =
+ TUI_UNDEFINED_REGS;
+ winInfo->detail.dataDisplayInfo.regsColumnCount = 1;
+ winInfo->detail.dataDisplayInfo.displayRegs = FALSE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return;
+} /* clearWinDetail */
+
+
+/*
+ ** blankStr()
+ ** Accessor for the blank string.
+ */
+char *
+blankStr (void)
+{
+ return _tuiBlankStr;
+} /* blankStr */
+
+
+/*
+ ** locationStr()
+ ** Accessor for the location string.
+ */
+char *
+locationStr (void)
+{
+ return _tuiLocationStr;
+} /* locationStr */
+
+
+/*
+ ** breakStr()
+ ** Accessor for the break string.
+ */
+char *
+breakStr (void)
+{
+ return _tuiBreakStr;
+} /* breakStr */
+
+
+/*
+ ** breakLocationStr()
+ ** Accessor for the breakLocation string.
+ */
+char *
+breakLocationStr (void)
+{
+ return _tuiBreakLocationStr;
+} /* breakLocationStr */
+
+
+/*
+ ** nullStr()
+ ** Accessor for the null string.
+ */
+char *
+nullStr (void)
+{
+ return _tuiNullStr;
+} /* nullStr */
+
+
+/*
+ ** sourceExecInfoPtr().
+ ** Accessor for the source execution info ptr.
+ */
+TuiGenWinInfoPtr
+sourceExecInfoWinPtr (void)
+{
+ return &_execInfo[0];
+} /* sourceExecInfoWinPtr */
+
+
+/*
+ ** disassemExecInfoPtr().
+ ** Accessor for the disassem execution info ptr.
+ */
+TuiGenWinInfoPtr
+disassemExecInfoWinPtr (void)
+{
+ return &_execInfo[1];
+} /* disassemExecInfoWinPtr */
+
+
+/*
+ ** locatorWinInfoPtr().
+ ** Accessor for the locator win info. Answers a pointer to the
+ ** static locator win info struct.
+ */
+TuiGenWinInfoPtr
+locatorWinInfoPtr (void)
+{
+ return &_locator;
+} /* locatorWinInfoPtr */
+
+
+/*
+ ** historyLimit().
+ ** Accessor for the history limit
+ */
+int
+historyLimit (void)
+{
+ return _historyLimit;
+} /* historyLimit */
+
+
+/*
+ ** setHistoryLimitTo().
+ ** Mutator for the history limit
+ */
+void
+setHistoryLimitTo (int h)
+{
+ _historyLimit = h;
+
+ return;
+} /* setHistoryLimitTo */
+
+/*
+ ** termHeight().
+ ** Accessor for the termHeight
+ */
+int
+termHeight (void)
+{
+ return _termHeight;
+} /* termHeight */
+
+
+/*
+ ** setTermHeightTo().
+ ** Mutator for the term height
+ */
+void
+setTermHeightTo (int h)
+{
+ _termHeight = h;
+
+ return;
+} /* setTermHeightTo */
+
+
+/*
+ ** termWidth().
+ ** Accessor for the termWidth
+ */
+int
+termWidth (void)
+{
+ return _termWidth;
+} /* termWidth */
+
+
+/*
+ ** setTermWidth().
+ ** Mutator for the termWidth
+ */
+void
+setTermWidthTo (int w)
+{
+ _termWidth = w;
+
+ return;
+} /* setTermWidthTo */
+
+
+/*
+ ** currentLayout().
+ ** Accessor for the current layout
+ */
+TuiLayoutType
+currentLayout (void)
+{
+ return _currentLayout;
+} /* currentLayout */
+
+
+/*
+ ** setCurrentLayoutTo().
+ ** Mutator for the current layout
+ */
+void
+setCurrentLayoutTo (TuiLayoutType newLayout)
+{
+ _currentLayout = newLayout;
+
+ return;
+} /* setCurrentLayoutTo */
+
+
+/*
+ ** setGenWinOrigin().
+ ** Set the origin of the window
+ */
+void
+setGenWinOrigin (TuiGenWinInfoPtr winInfo, int x, int y)
+{
+ winInfo->origin.x = x;
+ winInfo->origin.y = y;
+
+ return;
+} /* setGenWinOrigin */
+
+
+/*****************************
+** OTHER PUBLIC FUNCTIONS
+*****************************/
+
+
+/*
+ ** tuiNextWin().
+ ** Answer the next window in the list, cycling back to the top
+ ** if necessary
+ */
+TuiWinInfoPtr
+tuiNextWin (TuiWinInfoPtr curWin)
+{
+ TuiWinType type = curWin->generic.type;
+ TuiWinInfoPtr nextWin = (TuiWinInfoPtr) NULL;
+
+ if (curWin->generic.type == CMD_WIN)
+ type = SRC_WIN;
+ else
+ type = curWin->generic.type + 1;
+ while (type != curWin->generic.type && m_winPtrIsNull (nextWin))
+ {
+ if (winList[type] && winList[type]->generic.isVisible)
+ nextWin = winList[type];
+ else
+ {
+ if (type == CMD_WIN)
+ type = SRC_WIN;
+ else
+ type++;
+ }
+ }
+
+ return nextWin;
+} /* tuiNextWin */
+
+
+/*
+ ** tuiPrevWin().
+ ** Answer the prev window in the list, cycling back to the bottom
+ ** if necessary
+ */
+TuiWinInfoPtr
+tuiPrevWin (TuiWinInfoPtr curWin)
+{
+ TuiWinType type = curWin->generic.type;
+ TuiWinInfoPtr prev = (TuiWinInfoPtr) NULL;
+
+ if (curWin->generic.type == SRC_WIN)
+ type = CMD_WIN;
+ else
+ type = curWin->generic.type - 1;
+ while (type != curWin->generic.type && m_winPtrIsNull (prev))
+ {
+ if (winList[type]->generic.isVisible)
+ prev = winList[type];
+ else
+ {
+ if (type == SRC_WIN)
+ type = CMD_WIN;
+ else
+ type--;
+ }
+ }
+
+ return prev;
+} /* tuiPrevWin */
+
+
+/*
+ ** displayableWinContentOf().
+ ** Answer a the content at the location indicated by index. Note
+ ** that if this is a locator window, the string returned should be
+ ** freed after use.
+ */
+char *
+displayableWinContentOf (TuiGenWinInfoPtr winInfo, TuiWinElementPtr elementPtr)
+{
+
+ char *string = nullStr ();
+
+ if (elementPtr != (TuiWinElementPtr) NULL || winInfo->type == LOCATOR_WIN)
+ {
+ /*
+ ** Now convert the line to a displayable string
+ */
+ switch (winInfo->type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ string = elementPtr->whichElement.source.line;
+ break;
+ case CMD_WIN:
+ string = elementPtr->whichElement.command.line;
+ break;
+ case LOCATOR_WIN:
+ if ((string = (char *) xmalloc (
+ (termWidth () + 1) * sizeof (char))) == (char *) NULL)
+ string = nullStr ();
+ else
+ {
+ char lineNo[50], pc[50], buf[50], *fname, *pname;
+ register int strSize = termWidth (), i, procWidth, fileWidth;
+
+ /*
+ ** First determine the amount of file/proc name width
+ ** we have available
+ */
+ i = strSize - (PC_WIDTH + LINE_WIDTH
+ + 25 /* pc and line labels */
+ + strlen (FILE_PREFIX) + 1 /* file label */
+ + 15 /* procedure label */ );
+ if (i >= FILE_WIDTH + PROC_WIDTH)
+ {
+ fileWidth = FILE_WIDTH;
+ procWidth = PROC_WIDTH;
+ }
+ else
+ {
+ fileWidth = i / 2;
+ procWidth = i - fileWidth;
+ }
+
+ /* Now convert elements to string form */
+ if (elementPtr != (TuiWinElementPtr) NULL &&
+ *elementPtr->whichElement.locator.fileName != (char) 0 &&
+ srcWin->generic.isVisible)
+ fname = elementPtr->whichElement.locator.fileName;
+ else
+ fname = "??";
+ if (elementPtr != (TuiWinElementPtr) NULL &&
+ *elementPtr->whichElement.locator.procName != (char) 0)
+ pname = elementPtr->whichElement.locator.procName;
+ else
+ pname = "??";
+ if (elementPtr != (TuiWinElementPtr) NULL &&
+ elementPtr->whichElement.locator.lineNo > 0)
+ sprintf (lineNo, "%d",
+ elementPtr->whichElement.locator.lineNo);
+ else
+ strcpy (lineNo, "??");
+ if (elementPtr != (TuiWinElementPtr) NULL &&
+ elementPtr->whichElement.locator.addr != 0)
+ sprintf (pc, "0x%lx",
+ (long) elementPtr->whichElement.locator.addr);
+ else
+ strcpy (pc, "??");
+ /*
+ ** Now create the locator line from the string version
+ ** of the elements. We could use sprintf() here but
+ ** that wouldn't ensure that we don't overrun the size
+ ** of the allocated buffer. strcat_to_buf() will.
+ */
+ *string = (char) 0;
+ /* Filename */
+ strcat_to_buf (string, strSize, " ");
+ strcat_to_buf (string, strSize, FILE_PREFIX);
+ if (strlen (fname) > fileWidth)
+ {
+ strncpy (buf, fname, fileWidth - 1);
+ buf[fileWidth - 1] = '*';
+ buf[fileWidth] = (char) 0;
+ }
+ else
+ strcpy (buf, fname);
+ strcat_to_buf (string, strSize, buf);
+ /* procedure/class name */
+ sprintf (buf, "%15s", PROC_PREFIX);
+ strcat_to_buf (string, strSize, buf);
+ if (strlen (pname) > procWidth)
+ {
+ strncpy (buf, pname, procWidth - 1);
+ buf[procWidth - 1] = '*';
+ buf[procWidth] = (char) 0;
+ }
+ else
+ strcpy (buf, pname);
+ strcat_to_buf (string, strSize, buf);
+ sprintf (buf, "%10s", LINE_PREFIX);
+ strcat_to_buf (string, strSize, buf);
+ strcat_to_buf (string, strSize, lineNo);
+ sprintf (buf, "%10s", PC_PREFIX);
+ strcat_to_buf (string, strSize, buf);
+ strcat_to_buf (string, strSize, pc);
+ for (i = strlen (string); i < strSize; i++)
+ string[i] = ' ';
+ string[strSize] = (char) 0;
+ }
+ break;
+ case EXEC_INFO_WIN:
+ string = elementPtr->whichElement.simpleString;
+ break;
+ default:
+ break;
+ }
+ }
+ return string;
+} /* displayableWinContentOf */
+
+
+/*
+ ** winContentAt().
+ ** Answer a the content at the location indicated by index
+ */
+char *
+displayableWinContentAt (TuiGenWinInfoPtr winInfo, int index)
+{
+ return (displayableWinContentOf (winInfo, (TuiWinElementPtr) winInfo->content[index]));
+} /* winContentAt */
+
+
+/*
+ ** winElementHeight().
+ ** Answer the height of the element in lines
+ */
+int
+winElementHeight (TuiGenWinInfoPtr winInfo, TuiWinElementPtr element)
+{
+ int h;
+
+ if (winInfo->type == DATA_WIN)
+/* FOR NOW SAY IT IS ONLY ONE LINE HIGH */
+ h = 1;
+ else
+ h = 1;
+
+ return h;
+} /* winElementHeight */
+
+
+/*
+ ** winByName().
+ ** Answer the window represented by name
+ */
+TuiWinInfoPtr
+winByName (char *name)
+{
+ TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL;
+ int i = 0;
+
+ while (i < MAX_MAJOR_WINDOWS && m_winPtrIsNull (winInfo))
+ {
+ if (strcmp (name, winName (&(winList[i]->generic))) == 0)
+ winInfo = winList[i];
+ i++;
+ }
+
+ return winInfo;
+} /* winByName */
+
+
+/*
+ ** partialWinByName().
+ ** Answer the window represented by name
+ */
+TuiWinInfoPtr
+partialWinByName (char *name)
+{
+ TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL;
+
+ if (name != (char *) NULL)
+ {
+ int i = 0;
+
+ while (i < MAX_MAJOR_WINDOWS && m_winPtrIsNull (winInfo))
+ {
+ if (winList[i] != 0)
+ {
+ char *curName = winName (&winList[i]->generic);
+ if (strlen (name) <= strlen (curName) &&
+ strncmp (name, curName, strlen (name)) == 0)
+ winInfo = winList[i];
+ }
+ i++;
+ }
+ }
+
+ return winInfo;
+} /* partialWinByName */
+
+
+/*
+ ** winName().
+ ** Answer the name of the window
+ */
+char *
+winName (TuiGenWinInfoPtr winInfo)
+{
+ char *name = (char *) NULL;
+
+ switch (winInfo->type)
+ {
+ case SRC_WIN:
+ name = SRC_NAME;
+ break;
+ case CMD_WIN:
+ name = CMD_NAME;
+ break;
+ case DISASSEM_WIN:
+ name = DISASSEM_NAME;
+ break;
+ case DATA_WIN:
+ name = DATA_NAME;
+ break;
+ default:
+ name = "";
+ break;
+ }
+
+ return name;
+} /* winName */
+
+
+/*
+ ** initializeStaticData
+ */
+void
+initializeStaticData (void)
+{
+ initGenericPart (sourceExecInfoWinPtr ());
+ initGenericPart (disassemExecInfoWinPtr ());
+ initGenericPart (locatorWinInfoPtr ());
+
+ return;
+} /* initializeStaticData */
+
+
+/*
+ ** allocGenericWinInfo().
+ */
+TuiGenWinInfoPtr
+allocGenericWinInfo (void)
+{
+ TuiGenWinInfoPtr win;
+
+ if ((win = (TuiGenWinInfoPtr) xmalloc (
+ sizeof (TuiGenWinInfoPtr))) != (TuiGenWinInfoPtr) NULL)
+ initGenericPart (win);
+
+ return win;
+} /* allocGenericWinInfo */
+
+
+/*
+ ** initGenericPart().
+ */
+void
+initGenericPart (TuiGenWinInfoPtr win)
+{
+ win->width =
+ win->height =
+ win->origin.x =
+ win->origin.y =
+ win->viewportHeight =
+ win->contentSize =
+ win->lastVisibleLine = 0;
+ win->handle = (WINDOW *) NULL;
+ win->content = (OpaquePtr) NULL;
+ win->contentInUse =
+ win->isVisible = FALSE;
+
+ return;
+} /* initGenericPart */
+
+
+/*
+ ** initContentElement().
+ */
+void
+initContentElement (TuiWinElementPtr element, TuiWinType type)
+{
+ element->highlight = FALSE;
+ switch (type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ element->whichElement.source.line = (char *) NULL;
+ element->whichElement.source.lineOrAddr.lineNo = 0;
+ element->whichElement.source.isExecPoint = FALSE;
+ element->whichElement.source.hasBreak = FALSE;
+ break;
+ case DATA_WIN:
+ initGenericPart (&element->whichElement.dataWindow);
+ element->whichElement.dataWindow.type = DATA_ITEM_WIN;
+ ((TuiGenWinInfoPtr) & element->whichElement.dataWindow)->content =
+ (OpaquePtr) allocContent (1, DATA_ITEM_WIN);
+ ((TuiGenWinInfoPtr)
+ & element->whichElement.dataWindow)->contentSize = 1;
+ break;
+ case CMD_WIN:
+ element->whichElement.command.line = (char *) NULL;
+ break;
+ case DATA_ITEM_WIN:
+ element->whichElement.data.name = (char *) NULL;
+ element->whichElement.data.type = TUI_REGISTER;
+ element->whichElement.data.itemNo = UNDEFINED_ITEM;
+ element->whichElement.data.value = (Opaque) NULL;
+ element->whichElement.data.highlight = FALSE;
+ break;
+ case LOCATOR_WIN:
+ element->whichElement.locator.fileName[0] =
+ element->whichElement.locator.procName[0] = (char) 0;
+ element->whichElement.locator.lineNo = 0;
+ element->whichElement.locator.addr = 0;
+ break;
+ case EXEC_INFO_WIN:
+ element->whichElement.simpleString = blankStr ();
+ break;
+ default:
+ break;
+ }
+ return;
+} /* initContentElement */
+
+/*
+ ** initWinInfo().
+ */
+void
+initWinInfo (TuiWinInfoPtr winInfo)
+{
+ initGenericPart (&winInfo->generic);
+ winInfo->canHighlight =
+ winInfo->isHighlighted = FALSE;
+ switch (winInfo->generic.type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ winInfo->detail.sourceInfo.executionInfo = (TuiGenWinInfoPtr) NULL;
+ winInfo->detail.sourceInfo.hasLocator = FALSE;
+ winInfo->detail.sourceInfo.horizontalOffset = 0;
+ winInfo->detail.sourceInfo.startLineOrAddr.addr = 0;
+ break;
+ case DATA_WIN:
+ winInfo->detail.dataDisplayInfo.dataContent = (TuiWinContent) NULL;
+ winInfo->detail.dataDisplayInfo.dataContentCount = 0;
+ winInfo->detail.dataDisplayInfo.regsContent = (TuiWinContent) NULL;
+ winInfo->detail.dataDisplayInfo.regsContentCount = 0;
+ winInfo->detail.dataDisplayInfo.regsDisplayType =
+ TUI_UNDEFINED_REGS;
+ winInfo->detail.dataDisplayInfo.regsColumnCount = 1;
+ winInfo->detail.dataDisplayInfo.displayRegs = FALSE;
+ break;
+ case CMD_WIN:
+ winInfo->detail.commandInfo.curLine = 0;
+ winInfo->detail.commandInfo.curch = 0;
+ break;
+ default:
+ winInfo->detail.opaque = (Opaque) NULL;
+ break;
+ }
+
+ return;
+} /* initWinInfo */
+
+
+/*
+ ** allocWinInfo().
+ */
+TuiWinInfoPtr
+allocWinInfo (TuiWinType type)
+{
+ TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL;
+
+ winInfo = (TuiWinInfoPtr) xmalloc (sizeof (TuiWinInfo));
+ if (m_winPtrNotNull (winInfo))
+ {
+ winInfo->generic.type = type;
+ initWinInfo (winInfo);
+ }
+
+ return winInfo;
+} /* allocWinInfo */
+
+
+/*
+ ** allocContent().
+ ** Allocates the content and elements in a block.
+ */
+TuiWinContent
+allocContent (int numElements, TuiWinType type)
+{
+ TuiWinContent content = (TuiWinContent) NULL;
+ char *elementBlockPtr = (char *) NULL;
+ int i;
+
+ if ((content = (TuiWinContent)
+ xmalloc (sizeof (TuiWinElementPtr) * numElements)) != (TuiWinContent) NULL)
+ { /*
+ ** All windows, except the data window, can allocate the elements
+ ** in a chunk. The data window cannot because items can be
+ ** added/removed from the data display by the user at any time.
+ */
+ if (type != DATA_WIN)
+ {
+ if ((elementBlockPtr = (char *)
+ xmalloc (sizeof (TuiWinElement) * numElements)) != (char *) NULL)
+ {
+ for (i = 0; i < numElements; i++)
+ {
+ content[i] = (TuiWinElementPtr) elementBlockPtr;
+ initContentElement (content[i], type);
+ elementBlockPtr += sizeof (TuiWinElement);
+ }
+ }
+ else
+ {
+ tuiFree ((char *) content);
+ content = (TuiWinContent) NULL;
+ }
+ }
+ }
+
+ return content;
+} /* allocContent */
+
+
+/*
+ ** addContentElements().
+ ** Adds the input number of elements to the windows's content. If
+ ** no content has been allocated yet, allocContent() is called to
+ ** do this. The index of the first element added is returned,
+ ** unless there is a memory allocation error, in which case, (-1)
+ ** is returned.
+ */
+int
+addContentElements (TuiGenWinInfoPtr winInfo, int numElements)
+{
+ TuiWinElementPtr elementPtr;
+ int i, indexStart;
+
+ if (winInfo->content == (OpaquePtr) NULL)
+ {
+ winInfo->content = (OpaquePtr) allocContent (numElements, winInfo->type);
+ indexStart = 0;
+ }
+ else
+ indexStart = winInfo->contentSize;
+ if (winInfo->content != (OpaquePtr) NULL)
+ {
+ for (i = indexStart; (i < numElements + indexStart); i++)
+ {
+ if ((elementPtr = (TuiWinElementPtr)
+ xmalloc (sizeof (TuiWinElement))) != (TuiWinElementPtr) NULL)
+ {
+ winInfo->content[i] = (Opaque) elementPtr;
+ initContentElement (elementPtr, winInfo->type);
+ winInfo->contentSize++;
+ }
+ else /* things must be really hosed now! We ran out of memory!? */
+ return (-1);
+ }
+ }
+
+ return indexStart;
+} /* addContentElements */
+
+
+/*
+ ** tuiDelWindow().
+ ** Delete all curses windows associated with winInfo, leaving everything
+ ** else in tact.
+ */
+void
+tuiDelWindow (TuiWinInfoPtr winInfo)
+{
+ Opaque detail;
+ int i;
+ TuiGenWinInfoPtr genericWin;
+
+
+ switch (winInfo->generic.type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ genericWin = locatorWinInfoPtr ();
+ if (genericWin != (TuiGenWinInfoPtr) NULL)
+ {
+ tuiDelwin (genericWin->handle);
+ genericWin->handle = (WINDOW *) NULL;
+ genericWin->isVisible = FALSE;
+ }
+ genericWin = winInfo->detail.sourceInfo.executionInfo;
+ if (genericWin != (TuiGenWinInfoPtr) NULL)
+ {
+ tuiDelwin (genericWin->handle);
+ genericWin->handle = (WINDOW *) NULL;
+ genericWin->isVisible = FALSE;
+ }
+ break;
+ case DATA_WIN:
+ if (winInfo->generic.content != (OpaquePtr) NULL)
+ {
+ int i;
+
+ tuiDelDataWindows (
+ winInfo->detail.dataDisplayInfo.regsContent,
+ winInfo->detail.dataDisplayInfo.regsContentCount);
+ tuiDelDataWindows (
+ winInfo->detail.dataDisplayInfo.dataContent,
+ winInfo->detail.dataDisplayInfo.dataContentCount);
+ }
+ break;
+ default:
+ break;
+ }
+ if (winInfo->generic.handle != (WINDOW *) NULL)
+ {
+ tuiDelwin (winInfo->generic.handle);
+ winInfo->generic.handle = (WINDOW *) NULL;
+ winInfo->generic.isVisible = FALSE;
+ }
+
+ return;
+} /* tuiDelWindow */
+
+
+/*
+ ** freeWindow().
+ */
+void
+freeWindow (TuiWinInfoPtr winInfo)
+{
+ Opaque detail;
+ int i;
+ TuiGenWinInfoPtr genericWin;
+
+
+ switch (winInfo->generic.type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ genericWin = locatorWinInfoPtr ();
+ if (genericWin != (TuiGenWinInfoPtr) NULL)
+ {
+ tuiDelwin (genericWin->handle);
+ genericWin->handle = (WINDOW *) NULL;
+ }
+ freeWinContent (genericWin);
+ genericWin = winInfo->detail.sourceInfo.executionInfo;
+ if (genericWin != (TuiGenWinInfoPtr) NULL)
+ {
+ tuiDelwin (genericWin->handle);
+ genericWin->handle = (WINDOW *) NULL;
+ freeWinContent (genericWin);
+ }
+ break;
+ case DATA_WIN:
+ if (winInfo->generic.content != (OpaquePtr) NULL)
+ {
+ freeDataContent (
+ winInfo->detail.dataDisplayInfo.regsContent,
+ winInfo->detail.dataDisplayInfo.regsContentCount);
+ winInfo->detail.dataDisplayInfo.regsContent =
+ (TuiWinContent) NULL;
+ winInfo->detail.dataDisplayInfo.regsContentCount = 0;
+ freeDataContent (
+ winInfo->detail.dataDisplayInfo.dataContent,
+ winInfo->detail.dataDisplayInfo.dataContentCount);
+ winInfo->detail.dataDisplayInfo.dataContent =
+ (TuiWinContent) NULL;
+ winInfo->detail.dataDisplayInfo.dataContentCount = 0;
+ winInfo->detail.dataDisplayInfo.regsDisplayType =
+ TUI_UNDEFINED_REGS;
+ winInfo->detail.dataDisplayInfo.regsColumnCount = 1;
+ winInfo->detail.dataDisplayInfo.displayRegs = FALSE;
+ winInfo->generic.content = (OpaquePtr) NULL;
+ winInfo->generic.contentSize = 0;
+ }
+ break;
+ default:
+ break;
+ }
+ if (winInfo->generic.handle != (WINDOW *) NULL)
+ {
+ tuiDelwin (winInfo->generic.handle);
+ winInfo->generic.handle = (WINDOW *) NULL;
+ freeWinContent (&winInfo->generic);
+ }
+ xfree (winInfo);
+
+ return;
+} /* freeWindow */
+
+
+/*
+ ** freeAllSourceWinsContent().
+ */
+void
+freeAllSourceWinsContent (void)
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ {
+ TuiWinInfoPtr winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
+
+ if (m_winPtrNotNull (winInfo))
+ {
+ freeWinContent (&(winInfo->generic));
+ freeWinContent (winInfo->detail.sourceInfo.executionInfo);
+ }
+ }
+
+ return;
+} /* freeAllSourceWinsContent */
+
+
+/*
+ ** freeWinContent().
+ */
+void
+freeWinContent (TuiGenWinInfoPtr winInfo)
+{
+ if (winInfo->content != (OpaquePtr) NULL)
+ {
+ freeContent ((TuiWinContent) winInfo->content,
+ winInfo->contentSize,
+ winInfo->type);
+ winInfo->content = (OpaquePtr) NULL;
+ }
+ winInfo->contentSize = 0;
+
+ return;
+} /* freeWinContent */
+
+
+/*
+ ** freeAllWindows().
+ */
+void
+freeAllWindows (void)
+{
+ TuiWinType type = SRC_WIN;
+
+ for (; type < MAX_MAJOR_WINDOWS; type++)
+ if (m_winPtrNotNull (winList[type]) &&
+ winList[type]->generic.type != UNDEFINED_WIN)
+ freeWindow (winList[type]);
+ return;
+} /* freeAllWindows */
+
+
+void
+tuiDelDataWindows (TuiWinContent content, int contentSize)
+{
+ int i;
+
+ /*
+ ** Remember that data window content elements are of type TuiGenWinInfoPtr,
+ ** each of which whose single element is a data element.
+ */
+ for (i = 0; i < contentSize; i++)
+ {
+ TuiGenWinInfoPtr genericWin = &content[i]->whichElement.dataWindow;
+
+ if (genericWin != (TuiGenWinInfoPtr) NULL)
+ {
+ tuiDelwin (genericWin->handle);
+ genericWin->handle = (WINDOW *) NULL;
+ genericWin->isVisible = FALSE;
+ }
+ }
+
+ return;
+} /* tuiDelDataWindows */
+
+
+void
+freeDataContent (TuiWinContent content, int contentSize)
+{
+ int i;
+
+ /*
+ ** Remember that data window content elements are of type TuiGenWinInfoPtr,
+ ** each of which whose single element is a data element.
+ */
+ for (i = 0; i < contentSize; i++)
+ {
+ TuiGenWinInfoPtr genericWin = &content[i]->whichElement.dataWindow;
+
+ if (genericWin != (TuiGenWinInfoPtr) NULL)
+ {
+ tuiDelwin (genericWin->handle);
+ genericWin->handle = (WINDOW *) NULL;
+ freeWinContent (genericWin);
+ }
+ }
+ freeContent (content,
+ contentSize,
+ DATA_WIN);
+
+ return;
+} /* freeDataContent */
+
+
+/**********************************
+** LOCAL STATIC FUNCTIONS **
+**********************************/
+
+
+/*
+ ** freeContent().
+ */
+static void
+freeContent (TuiWinContent content, int contentSize, TuiWinType winType)
+{
+ if (content != (TuiWinContent) NULL)
+ {
+ freeContentElements (content, contentSize, winType);
+ tuiFree ((char *) content);
+ }
+
+ return;
+} /* freeContent */
+
+
+/*
+ ** freeContentElements().
+ */
+static void
+freeContentElements (TuiWinContent content, int contentSize, TuiWinType type)
+{
+ if (content != (TuiWinContent) NULL)
+ {
+ int i;
+
+ if (type == SRC_WIN || type == DISASSEM_WIN)
+ {
+ /* free whole source block */
+ if (content[0]->whichElement.source.line != (char *) NULL)
+ tuiFree (content[0]->whichElement.source.line);
+ }
+ else
+ {
+ for (i = 0; i < contentSize; i++)
+ {
+ TuiWinElementPtr element;
+
+ element = content[i];
+ if (element != (TuiWinElementPtr) NULL)
+ {
+ switch (type)
+ {
+ case DATA_WIN:
+ tuiFree ((char *) element);
+ break;
+ case DATA_ITEM_WIN:
+ /*
+ ** Note that data elements are not allocated
+ ** in a single block, but individually, as needed.
+ */
+ if (element->whichElement.data.type != TUI_REGISTER)
+ tuiFree ((char *)
+ element->whichElement.data.name);
+ tuiFree ((char *) element->whichElement.data.value);
+ tuiFree ((char *) element);
+ break;
+ case CMD_WIN:
+ tuiFree ((char *) element->whichElement.command.line);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ if (type != DATA_WIN && type != DATA_ITEM_WIN)
+ tuiFree ((char *) content[0]); /* free the element block */
+ }
+
+ return;
+} /* freeContentElements */
diff --git a/gdb/tui/tuiData.h b/gdb/tui/tuiData.h
new file mode 100644
index 00000000000..9edf00046ea
--- /dev/null
+++ b/gdb/tui/tuiData.h
@@ -0,0 +1,373 @@
+/* TUI data manipulation routines.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef TUI_DATA_H
+#define TUI_DATA_H
+
+#if defined (HAVE_NCURSES_H)
+#include <ncurses.h>
+#elif defined (HAVE_CURSES_H)
+#include <curses.h>
+#endif
+
+/* Generic window information */
+ typedef struct _TuiGenWinInfo
+ {
+ WINDOW *handle; /* window handle */
+ TuiWinType type; /* type of window */
+ int width; /* window width */
+ int height; /* window height */
+ TuiPoint origin; /* origin of window */
+ OpaquePtr content; /* content of window */
+ int contentSize; /* Size of content (# of elements) */
+ int contentInUse; /* Can it be used, or is it already used? */
+ int viewportHeight; /* viewport height */
+ int lastVisibleLine; /* index of last visible line */
+ int isVisible; /* whether the window is visible or not */
+ }
+TuiGenWinInfo, *TuiGenWinInfoPtr;
+
+/* Constant definitions */
+#define DEFAULT_TAB_LEN 8
+#define NO_SRC_STRING "[ No Source Available ]"
+#define NO_DISASSEM_STRING "[ No Assembly Available ]"
+#define NO_REGS_STRING "[ Register Values Unavailable ]"
+#define NO_DATA_STRING "[ No Data Values Displayed ]"
+#define MAX_CONTENT_COUNT 100
+#define SRC_NAME "SRC"
+#define CMD_NAME "CMD"
+#define DATA_NAME "REGS"
+#define DISASSEM_NAME "ASM"
+#define TUI_NULL_STR ""
+#define DEFAULT_HISTORY_COUNT 25
+#define BOX_WINDOW TRUE
+#define DONT_BOX_WINDOW FALSE
+#define HILITE TRUE
+#define NO_HILITE FALSE
+#define WITH_LOCATOR TRUE
+#define NO_LOCATOR FALSE
+#define EMPTY_SOURCE_PROMPT TRUE
+#define NO_EMPTY_SOURCE_PROMPT FALSE
+#define UNDEFINED_ITEM -1
+#define MIN_WIN_HEIGHT 3
+#define MIN_CMD_WIN_HEIGHT 3
+
+#define FILE_PREFIX "File: "
+#define PROC_PREFIX "Procedure: "
+#define LINE_PREFIX "Line: "
+#define PC_PREFIX "pc: "
+
+#define TUI_FLOAT_REGS_NAME "$FREGS"
+#define TUI_FLOAT_REGS_NAME_LOWER "$fregs"
+#define TUI_GENERAL_REGS_NAME "$GREGS"
+#define TUI_GENERAL_REGS_NAME_LOWER "$gregs"
+#define TUI_SPECIAL_REGS_NAME "$SREGS"
+#define TUI_SPECIAL_REGS_NAME_LOWER "$sregs"
+#define TUI_GENERAL_SPECIAL_REGS_NAME "$REGS"
+#define TUI_GENERAL_SPECIAL_REGS_NAME_LOWER "$regs"
+
+/* Scroll direction enum */
+typedef enum
+ {
+ FORWARD_SCROLL,
+ BACKWARD_SCROLL,
+ LEFT_SCROLL,
+ RIGHT_SCROLL
+ }
+TuiScrollDirection, *TuiScrollDirectionPtr;
+
+
+/* General list struct */
+typedef struct _TuiList
+ {
+ OpaqueList list;
+ int count;
+ }
+TuiList, *TuiListPtr;
+
+
+/* The kinds of layouts available */
+typedef enum
+ {
+ SRC_COMMAND,
+ DISASSEM_COMMAND,
+ SRC_DISASSEM_COMMAND,
+ SRC_DATA_COMMAND,
+ DISASSEM_DATA_COMMAND,
+ UNDEFINED_LAYOUT
+ }
+TuiLayoutType, *TuiLayoutTypePtr;
+
+/* Basic data types that can be displayed in the data window. */
+typedef enum _TuiDataType
+ {
+ TUI_REGISTER,
+ TUI_SCALAR,
+ TUI_COMPLEX,
+ TUI_STRUCT
+ }
+TuiDataType, TuiDataTypePtr;
+
+/* Types of register displays */
+typedef enum _TuiRegisterDisplayType
+ {
+ TUI_UNDEFINED_REGS,
+ TUI_GENERAL_REGS,
+ TUI_SFLOAT_REGS,
+ TUI_DFLOAT_REGS,
+ TUI_SPECIAL_REGS,
+ TUI_GENERAL_AND_SPECIAL_REGS
+ }
+TuiRegisterDisplayType, *TuiRegisterDisplayTypePtr;
+
+/* Structure describing source line or line address */
+typedef union _TuiLineOrAddress
+ {
+ int lineNo;
+ CORE_ADDR addr;
+ }
+TuiLineOrAddress, *TuiLineOrAddressPtr;
+
+/* Current Layout definition */
+typedef struct _TuiLayoutDef
+ {
+ TuiWinType displayMode;
+ int split;
+ TuiRegisterDisplayType regsDisplayType;
+ TuiRegisterDisplayType floatRegsDisplayType;
+ }
+TuiLayoutDef, *TuiLayoutDefPtr;
+
+/* Elements in the Source/Disassembly Window */
+typedef struct _TuiSourceElement
+ {
+ char *line;
+ TuiLineOrAddress lineOrAddr;
+ int isExecPoint;
+ int hasBreak;
+ }
+TuiSourceElement, *TuiSourceElementPtr;
+
+
+/* Elements in the data display window content */
+typedef struct _TuiDataElement
+ {
+ char *name;
+ int itemNo; /* the register number, or data display number */
+ TuiDataType type;
+ Opaque value;
+ int highlight;
+ }
+TuiDataElement, *TuiDataElementPtr;
+
+
+/* Elements in the command window content */
+typedef struct _TuiCommandElement
+ {
+ char *line;
+ }
+TuiCommandElement, *TuiCommandElementPtr;
+
+
+#define MAX_LOCATOR_ELEMENT_LEN 100
+
+/* Elements in the locator window content */
+typedef struct _TuiLocatorElement
+ {
+ char fileName[MAX_LOCATOR_ELEMENT_LEN];
+ char procName[MAX_LOCATOR_ELEMENT_LEN];
+ int lineNo;
+ CORE_ADDR addr;
+ }
+TuiLocatorElement, *TuiLocatorElementPtr;
+
+
+/* An content element in a window */
+typedef union
+ {
+ TuiSourceElement source; /* the source elements */
+ TuiGenWinInfo dataWindow; /* data display elements */
+ TuiDataElement data; /* elements of dataWindow */
+ TuiCommandElement command; /* command elements */
+ TuiLocatorElement locator; /* locator elements */
+ char *simpleString; /* simple char based elements */
+ }
+TuiWhichElement, *TuiWhichElementPtr;
+
+typedef struct _TuiWinElement
+ {
+ int highlight;
+ TuiWhichElement whichElement;
+ }
+TuiWinElement, *TuiWinElementPtr;
+
+
+/* This describes the content of the window. */
+typedef TuiWinElementPtr *TuiWinContent;
+
+
+/* This struct defines the specific information about a data display window */
+typedef struct _TuiDataInfo
+ {
+ TuiWinContent dataContent; /* start of data display content */
+ int dataContentCount;
+ TuiWinContent regsContent; /* start of regs display content */
+ int regsContentCount;
+ TuiRegisterDisplayType regsDisplayType;
+ int regsColumnCount;
+ int displayRegs; /* Should regs be displayed at all? */
+ }
+TuiDataInfo, *TuiDataInfoPtr;
+
+
+typedef struct _TuiSourceInfo
+ {
+ int hasLocator; /* Does locator belongs to this window? */
+ TuiGenWinInfoPtr executionInfo; /* execution information window */
+ int horizontalOffset; /* used for horizontal scroll */
+ TuiLineOrAddress startLineOrAddr;
+ }
+TuiSourceInfo, *TuiSourceInfoPtr;
+
+
+typedef struct _TuiCommandInfo
+ {
+ int curLine; /* The current line position */
+ int curch; /* The current cursor position */
+ int start_line;
+ }
+TuiCommandInfo, *TuiCommandInfoPtr;
+
+
+/* This defines information about each logical window */
+typedef struct _TuiWinInfo
+ {
+ TuiGenWinInfo generic; /* general window information */
+ union
+ {
+ TuiSourceInfo sourceInfo;
+ TuiDataInfo dataDisplayInfo;
+ TuiCommandInfo commandInfo;
+ Opaque opaque;
+ }
+ detail;
+ int canHighlight; /* Can this window ever be highlighted? */
+ int isHighlighted; /* Is this window highlighted? */
+ }
+TuiWinInfo, *TuiWinInfoPtr;
+
+/* MACROS (prefixed with m_) */
+
+/* Testing macros */
+#define m_genWinPtrIsNull(winInfo) \
+ ((winInfo) == (TuiGenWinInfoPtr)NULL)
+#define m_genWinPtrNotNull(winInfo) \
+ ((winInfo) != (TuiGenWinInfoPtr)NULL)
+#define m_winPtrIsNull(winInfo) \
+ ((winInfo) == (TuiWinInfoPtr)NULL)
+#define m_winPtrNotNull(winInfo) \
+ ((winInfo) != (TuiWinInfoPtr)NULL)
+
+#define m_winIsSourceType(type) \
+ (type == SRC_WIN || type == DISASSEM_WIN)
+#define m_winIsAuxillary(winType) \
+ (winType > MAX_MAJOR_WINDOWS)
+#define m_hasLocator(winInfo) \
+ ( ((winInfo) != (TuiWinInfoPtr)NULL) ? \
+ (winInfo->detail.sourceInfo.hasLocator) : \
+ FALSE )
+
+#define m_setWinHighlightOn(winInfo) \
+ if ((winInfo) != (TuiWinInfoPtr)NULL) \
+ (winInfo)->isHighlighted = TRUE
+#define m_setWinHighlightOff(winInfo) \
+ if ((winInfo) != (TuiWinInfoPtr)NULL) \
+ (winInfo)->isHighlighted = FALSE
+
+
+/* Global Data */
+extern TuiWinInfoPtr winList[MAX_MAJOR_WINDOWS];
+extern int tui_version;
+
+/* Macros */
+#define srcWin winList[SRC_WIN]
+#define disassemWin winList[DISASSEM_WIN]
+#define dataWin winList[DATA_WIN]
+#define cmdWin winList[CMD_WIN]
+
+/* Data Manipulation Functions */
+extern void initializeStaticData (void);
+extern TuiGenWinInfoPtr allocGenericWinInfo (void);
+extern TuiWinInfoPtr allocWinInfo (TuiWinType);
+extern void initGenericPart (TuiGenWinInfoPtr);
+extern void initWinInfo (TuiWinInfoPtr);
+extern TuiWinContent allocContent (int, TuiWinType);
+extern int addContentElements (TuiGenWinInfoPtr, int);
+extern void initContentElement (TuiWinElementPtr, TuiWinType);
+extern void freeWindow (TuiWinInfoPtr);
+extern void freeAllWindows (void);
+extern void freeWinContent (TuiGenWinInfoPtr);
+extern void freeDataContent (TuiWinContent, int);
+extern void freeAllSourceWinsContent (void);
+extern void tuiDelWindow (TuiWinInfoPtr);
+extern void tuiDelDataWindows (TuiWinContent, int);
+extern TuiWinInfoPtr winByName (char *);
+extern TuiWinInfoPtr partialWinByName (char *);
+extern char *winName (TuiGenWinInfoPtr);
+extern char *displayableWinContentOf (TuiGenWinInfoPtr, TuiWinElementPtr);
+extern char *displayableWinContentAt (TuiGenWinInfoPtr, int);
+extern int winElementHeight (TuiGenWinInfoPtr, TuiWinElementPtr);
+extern TuiLayoutType currentLayout (void);
+extern void setCurrentLayoutTo (TuiLayoutType);
+extern int termHeight (void);
+extern void setTermHeightTo (int);
+extern int termWidth (void);
+extern void setTermWidthTo (int);
+extern int historyLimit (void);
+extern void setHistoryLimit (int);
+extern void setGenWinOrigin (TuiGenWinInfoPtr, int, int);
+extern TuiGenWinInfoPtr locatorWinInfoPtr (void);
+extern TuiGenWinInfoPtr sourceExecInfoWinPtr (void);
+extern TuiGenWinInfoPtr disassemExecInfoWinPtr (void);
+extern char *nullStr (void);
+extern char *blankStr (void);
+extern char *locationStr (void);
+extern char *breakStr (void);
+extern char *breakLocationStr (void);
+extern TuiListPtr sourceWindows (void);
+extern void clearSourceWindows (void);
+extern void clearSourceWindowsDetail (void);
+extern void clearWinDetail (TuiWinInfoPtr winInfo);
+extern void tuiAddToSourceWindows (TuiWinInfoPtr);
+extern int tuiDefaultTabLen (void);
+extern void tuiSetDefaultTabLen (int);
+extern TuiWinInfoPtr tuiWinWithFocus (void);
+extern void tuiSetWinWithFocus (TuiWinInfoPtr);
+extern TuiLayoutDefPtr tuiLayoutDef (void);
+extern int tuiWinResized (void);
+extern void tuiSetWinResizedTo (int);
+
+extern TuiWinInfoPtr tuiNextWin (TuiWinInfoPtr);
+extern TuiWinInfoPtr tuiPrevWin (TuiWinInfoPtr);
+
+extern void addToSourceWindows (TuiWinInfoPtr winInfo);
+
+#endif /* TUI_DATA_H */
diff --git a/gdb/tui/tuiDataWin.c b/gdb/tui/tuiDataWin.c
new file mode 100644
index 00000000000..e729afc7f72
--- /dev/null
+++ b/gdb/tui/tuiDataWin.c
@@ -0,0 +1,358 @@
+/* Data/register window display.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+ Inc.
+
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include "defs.h"
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiGeneralWin.h"
+#include "tuiRegs.h"
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS FORWARD DECLS **
+******************************************/
+
+
+
+/*****************************************
+** PUBLIC FUNCTIONS **
+******************************************/
+
+
+/*
+ ** tuiFirstDataItemDisplayed()
+ ** Answer the index first element displayed.
+ ** If none are displayed, then return (-1).
+ */
+int
+tuiFirstDataItemDisplayed (void)
+{
+ int elementNo = (-1);
+ int i;
+
+ for (i = 0; (i < dataWin->generic.contentSize && elementNo < 0); i++)
+ {
+ TuiGenWinInfoPtr dataItemWin;
+
+ dataItemWin = &((TuiWinContent)
+ dataWin->generic.content)[i]->whichElement.dataWindow;
+ if (dataItemWin->handle != (WINDOW *) NULL && dataItemWin->isVisible)
+ elementNo = i;
+ }
+
+ return elementNo;
+} /* tuiFirstDataItemDisplayed */
+
+
+/*
+ ** tuiFirstDataElementNoInLine()
+ ** Answer the index of the first element in lineNo. If lineNo is
+ ** past the data area (-1) is returned.
+ */
+int
+tuiFirstDataElementNoInLine (int lineNo)
+{
+ int firstElementNo = (-1);
+
+ /*
+ ** First see if there is a register on lineNo, and if so, set the
+ ** first element number
+ */
+ if ((firstElementNo = tuiFirstRegElementNoInLine (lineNo)) == -1)
+ { /*
+ ** Looking at the general data, the 1st element on lineNo
+ */
+ }
+
+ return firstElementNo;
+} /* tuiFirstDataElementNoInLine */
+
+
+/*
+ ** tuiDeleteDataContentWindows()
+ ** Function to delete all the item windows in the data window.
+ ** This is usually done when the data window is scrolled.
+ */
+void
+tuiDeleteDataContentWindows (void)
+{
+ int i;
+ TuiGenWinInfoPtr dataItemWinPtr;
+
+ for (i = 0; (i < dataWin->generic.contentSize); i++)
+ {
+ dataItemWinPtr = &((TuiWinContent)
+ dataWin->generic.content)[i]->whichElement.dataWindow;
+ tuiDelwin (dataItemWinPtr->handle);
+ dataItemWinPtr->handle = (WINDOW *) NULL;
+ dataItemWinPtr->isVisible = FALSE;
+ }
+
+ return;
+} /* tuiDeleteDataContentWindows */
+
+
+void
+tuiEraseDataContent (char *prompt)
+{
+ werase (dataWin->generic.handle);
+ checkAndDisplayHighlightIfNeeded (dataWin);
+ if (prompt != (char *) NULL)
+ {
+ int halfWidth = (dataWin->generic.width - 2) / 2;
+ int xPos;
+
+ if (strlen (prompt) >= halfWidth)
+ xPos = 1;
+ else
+ xPos = halfWidth - strlen (prompt);
+ mvwaddstr (dataWin->generic.handle,
+ (dataWin->generic.height / 2),
+ xPos,
+ prompt);
+ }
+ wrefresh (dataWin->generic.handle);
+
+ return;
+} /* tuiEraseDataContent */
+
+
+/*
+ ** tuiDisplayAllData().
+ ** This function displays the data that is in the data window's
+ ** content. It does not set the content.
+ */
+void
+tuiDisplayAllData (void)
+{
+ if (dataWin->generic.contentSize <= 0)
+ tuiEraseDataContent (NO_DATA_STRING);
+ else
+ {
+ tuiEraseDataContent ((char *) NULL);
+ tuiDeleteDataContentWindows ();
+ checkAndDisplayHighlightIfNeeded (dataWin);
+ tuiDisplayRegistersFrom (0);
+ /*
+ ** Then display the other data
+ */
+ if (dataWin->detail.dataDisplayInfo.dataContent !=
+ (TuiWinContent) NULL &&
+ dataWin->detail.dataDisplayInfo.dataContentCount > 0)
+ {
+ }
+ }
+ return;
+} /* tuiDisplayAllData */
+
+
+/*
+ ** tuiDisplayDataFromLine()
+ ** Function to display the data starting at line, lineNo, in the
+ ** data window.
+ */
+void
+tuiDisplayDataFromLine (int lineNo)
+{
+ int _lineNo = lineNo;
+
+ if (lineNo < 0)
+ _lineNo = 0;
+
+ checkAndDisplayHighlightIfNeeded (dataWin);
+
+ /* there is no general data, force regs to display (if there are any) */
+ if (dataWin->detail.dataDisplayInfo.dataContentCount <= 0)
+ tuiDisplayRegistersFromLine (_lineNo, TRUE);
+ else
+ {
+ int elementNo, startLineNo;
+ int regsLastLine = tuiLastRegsLineNo ();
+
+
+ /* display regs if we can */
+ if (tuiDisplayRegistersFromLine (_lineNo, FALSE) < 0)
+ { /*
+ ** _lineNo is past the regs display, so calc where the
+ ** start data element is
+ */
+ if (regsLastLine < _lineNo)
+ { /* figure out how many lines each element is to obtain
+ the start elementNo */
+ }
+ }
+ else
+ { /*
+ ** calculate the starting element of the data display, given
+ ** regsLastLine and how many lines each element is, up to
+ ** _lineNo
+ */
+ }
+ /* Now display the data , starting at elementNo */
+ }
+
+ return;
+} /* tuiDisplayDataFromLine */
+
+
+/*
+ ** tuiDisplayDataFrom()
+ ** Display data starting at element elementNo
+ */
+void
+tuiDisplayDataFrom (int elementNo, int reuseWindows)
+{
+ int firstLine = (-1);
+
+ if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
+ firstLine = tuiLineFromRegElementNo (elementNo);
+ else
+ { /* calculate the firstLine from the element number */
+ }
+
+ if (firstLine >= 0)
+ {
+ tuiEraseDataContent ((char *) NULL);
+ if (!reuseWindows)
+ tuiDeleteDataContentWindows ();
+ tuiDisplayDataFromLine (firstLine);
+ }
+
+ return;
+} /* tuiDisplayDataFrom */
+
+
+/*
+ ** tuiRefreshDataWin()
+ ** Function to redisplay the contents of the data window.
+ */
+void
+tuiRefreshDataWin (void)
+{
+ tuiEraseDataContent ((char *) NULL);
+ if (dataWin->generic.contentSize > 0)
+ {
+ int firstElement = tuiFirstDataItemDisplayed ();
+
+ if (firstElement >= 0) /* re-use existing windows */
+ tuiDisplayDataFrom (firstElement, TRUE);
+ }
+
+ return;
+} /* tuiRefreshDataWin */
+
+
+/*
+ ** tuiCheckDataValues().
+ ** Function to check the data values and hilite any that have changed
+ */
+void
+tuiCheckDataValues (struct frame_info *frame)
+{
+ tuiCheckRegisterValues (frame);
+
+ /* Now check any other data values that there are */
+ if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
+ {
+ int i;
+
+ for (i = 0; dataWin->detail.dataDisplayInfo.dataContentCount; i++)
+ {
+#ifdef LATER
+ TuiDataElementPtr dataElementPtr;
+ TuiGenWinInfoPtr dataItemWinPtr;
+ Opaque newValue;
+
+ dataItemPtr = &dataWin->detail.dataDisplayInfo.
+ dataContent[i]->whichElement.dataWindow;
+ dataElementPtr = &((TuiWinContent)
+ dataItemWinPtr->content)[0]->whichElement.data;
+ if value
+ has changed (dataElementPtr, frame, &newValue)
+ {
+ dataElementPtr->value = newValue;
+ update the display with the new value, hiliting it.
+ }
+#endif
+ }
+ }
+} /* tuiCheckDataValues */
+
+
+/*
+ ** tuiVerticalDataScroll()
+ ** Scroll the data window vertically forward or backward.
+ */
+void
+tuiVerticalDataScroll (TuiScrollDirection scrollDirection, int numToScroll)
+{
+ int firstElementNo;
+ int firstLine = (-1);
+
+ firstElementNo = tuiFirstDataItemDisplayed ();
+ if (firstElementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
+ firstLine = tuiLineFromRegElementNo (firstElementNo);
+ else
+ { /* calculate the first line from the element number which is in
+ ** the general data content
+ */
+ }
+
+ if (firstLine >= 0)
+ {
+ int lastElementNo, lastLine;
+
+ if (scrollDirection == FORWARD_SCROLL)
+ firstLine += numToScroll;
+ else
+ firstLine -= numToScroll;
+ tuiEraseDataContent ((char *) NULL);
+ tuiDeleteDataContentWindows ();
+ tuiDisplayDataFromLine (firstLine);
+ }
+
+ return;
+} /* tuiVerticalDataScroll */
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS **
+******************************************/
diff --git a/gdb/tui/tuiDataWin.h b/gdb/tui/tuiDataWin.h
new file mode 100644
index 00000000000..0b1e700f1bb
--- /dev/null
+++ b/gdb/tui/tuiDataWin.h
@@ -0,0 +1,47 @@
+/* Data/register window display.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef _TUI_DATAWIN_H
+#define _TUI_DATAWIN_H
+
+
+/*****************************************
+** TYPE DEFINITIONS **
+******************************************/
+
+
+
+/*****************************************
+** PUBLIC FUNCTION EXTERNAL DECLS **
+******************************************/
+extern void tuiEraseDataContent (char *);
+extern void tuiDisplayAllData (void);
+extern void tuiCheckDataValues (struct frame_info *);
+extern void tuiDisplayDataFromLine (int);
+extern int tuiFirstDataItemDisplayed (void);
+extern int tuiFirstDataElementNoInLine (int);
+extern void tuiDeleteDataContentWindows (void);
+extern void tuiRefreshDataWin (void);
+extern void tuiDisplayDataFrom (int, int);
+extern void tuiVerticalDataScroll (TuiScrollDirection, int);
+
+#endif
+/*_TUI_DATAWIN_H*/
diff --git a/gdb/tui/tuiDisassem.c b/gdb/tui/tuiDisassem.c
new file mode 100644
index 00000000000..8e59e68d693
--- /dev/null
+++ b/gdb/tui/tuiDisassem.c
@@ -0,0 +1,325 @@
+/* Disassembly display.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+ Inc.
+
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include "defs.h"
+#include "symtab.h"
+#include "breakpoint.h"
+#include "frame.h"
+#include "value.h"
+
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiWin.h"
+#include "tuiLayout.h"
+#include "tuiSourceWin.h"
+#include "tuiStack.h"
+#include "tui-file.h"
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS FORWARD DECLS **
+******************************************/
+
+static struct breakpoint *_hasBreak (CORE_ADDR);
+
+
+/*****************************************
+** PUBLIC FUNCTIONS **
+******************************************/
+
+/*
+ ** tuiSetDisassemContent().
+ ** Function to set the disassembly window's content.
+ */
+TuiStatus
+tuiSetDisassemContent (struct symtab *s, CORE_ADDR startAddr)
+{
+ TuiStatus ret = TUI_FAILURE;
+ struct ui_file *gdb_dis_out;
+
+ if (startAddr != 0)
+ {
+ register int i, desc;
+
+ if ((ret = tuiAllocSourceBuffer (disassemWin)) == TUI_SUCCESS)
+ {
+ register int offset = disassemWin->detail.sourceInfo.horizontalOffset;
+ register int threshold, curLine = 0, lineWidth, maxLines;
+ CORE_ADDR newpc, pc;
+ disassemble_info asmInfo;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+extern void strcat_address (CORE_ADDR, char *, int);
+extern void strcat_address_numeric (CORE_ADDR, int, char *, int);
+ int curLen = 0;
+ int tab_len = tuiDefaultTabLen ();
+
+ maxLines = disassemWin->generic.height - 2; /* account for hilite */
+ lineWidth = disassemWin->generic.width - 1;
+ threshold = (lineWidth - 1) + offset;
+
+ /* now init the ui_file structure */
+ gdb_dis_out = tui_sfileopen (threshold);
+
+ asmInfo = tm_print_insn_info;
+ asmInfo.stream = gdb_dis_out;
+
+ disassemWin->detail.sourceInfo.startLineOrAddr.addr = startAddr;
+
+ /* Now construct each line */
+ for (curLine = 0, pc = startAddr; (curLine < maxLines);)
+ {
+ TuiWinElementPtr element = (TuiWinElementPtr) disassemWin->generic.content[curLine];
+ struct breakpoint *bp;
+
+ print_address (pc, gdb_dis_out);
+
+ curLen = strlen (tui_file_get_strbuf (gdb_dis_out));
+ i = curLen - ((curLen / tab_len) * tab_len);
+
+ /* adjust buffer length if necessary */
+ tui_file_adjust_strbuf ((tab_len - i > 0) ? (tab_len - i) : 0, gdb_dis_out);
+
+ /* Add spaces to make the instructions start onthe same column */
+ while (i < tab_len)
+ {
+ tui_file_get_strbuf (gdb_dis_out)[curLen] = ' ';
+ i++;
+ curLen++;
+ }
+ tui_file_get_strbuf (gdb_dis_out)[curLen] = '\0';
+
+ newpc = pc + ((*tm_print_insn) (pc, &asmInfo));
+
+ /* Now copy the line taking the offset into account */
+ if (strlen (tui_file_get_strbuf (gdb_dis_out)) > offset)
+ strcpy (element->whichElement.source.line,
+ &(tui_file_get_strbuf (gdb_dis_out)[offset]));
+ else
+ element->whichElement.source.line[0] = '\0';
+ element->whichElement.source.lineOrAddr.addr = pc;
+ element->whichElement.source.isExecPoint =
+ (pc == (CORE_ADDR) ((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr);
+ bp = _hasBreak (pc);
+ element->whichElement.source.hasBreak =
+ (bp != (struct breakpoint *) NULL &&
+ (!element->whichElement.source.isExecPoint ||
+ (bp->disposition != disp_del || bp->hit_count <= 0)));
+ curLine++;
+ pc = newpc;
+ /* reset the buffer to empty */
+ tui_file_get_strbuf (gdb_dis_out)[0] = '\0';
+ }
+ ui_file_delete (gdb_dis_out);
+ gdb_dis_out = NULL;
+ disassemWin->generic.contentSize = curLine;
+ ret = TUI_SUCCESS;
+ }
+ }
+
+ return ret;
+} /* tuiSetDisassemContent */
+
+
+/*
+ ** tuiShowDisassem().
+ ** Function to display the disassembly window with disassembled code.
+ */
+void
+tuiShowDisassem (CORE_ADDR startAddr)
+{
+ struct symtab *s = find_pc_symtab (startAddr);
+ TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
+ TuiLineOrAddress val;
+
+ val.addr = startAddr;
+ tuiAddWinToLayout (DISASSEM_WIN);
+ tuiUpdateSourceWindow (disassemWin, s, val, FALSE);
+ /*
+ ** if the focus was in the src win, put it in the asm win, if the
+ ** source view isn't split
+ */
+ if (currentLayout () != SRC_DISASSEM_COMMAND && winWithFocus == srcWin)
+ tuiSetWinFocusTo (disassemWin);
+
+ return;
+} /* tuiShowDisassem */
+
+
+/*
+ ** tuiShowDisassemAndUpdateSource().
+ ** Function to display the disassembly window.
+ */
+void
+tuiShowDisassemAndUpdateSource (CORE_ADDR startAddr)
+{
+ struct symtab_and_line sal;
+
+ tuiShowDisassem (startAddr);
+ if (currentLayout () == SRC_DISASSEM_COMMAND)
+ {
+ TuiLineOrAddress val;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ /*
+ ** Update what is in the source window if it is displayed too,
+ ** note that it follows what is in the disassembly window and visa-versa
+ */
+ sal = find_pc_line (startAddr, 0);
+ val.lineNo = sal.line;
+ tuiUpdateSourceWindow (srcWin, sal.symtab, val, TRUE);
+ if (sal.symtab)
+ {
+ current_source_symtab = sal.symtab;
+ tuiUpdateLocatorFilename (sal.symtab->filename);
+ }
+ else
+ tuiUpdateLocatorFilename ("?");
+ }
+
+ return;
+} /* tuiShowDisassemAndUpdateSource */
+
+/*
+ ** tuiGetBeginAsmAddress().
+ */
+CORE_ADDR
+tuiGetBeginAsmAddress (void)
+{
+ TuiGenWinInfoPtr locator;
+ TuiLocatorElementPtr element;
+ CORE_ADDR addr;
+
+ locator = locatorWinInfoPtr ();
+ element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator;
+
+ if (element->addr == 0)
+ {
+ /*the target is not executing, because the pc is 0 */
+
+ addr = parse_and_eval_address ("main");
+
+ if (addr == 0)
+ addr = parse_and_eval_address ("MAIN");
+
+ }
+ else /* the target is executing */
+ addr = element->addr;
+
+ return addr;
+} /* tuiGetBeginAsmAddress */
+
+
+/*
+ ** tuiVerticalDisassemScroll().
+ ** Scroll the disassembly forward or backward vertically
+ */
+void
+tuiVerticalDisassemScroll (TuiScrollDirection scrollDirection,
+ int numToScroll)
+{
+ if (disassemWin->generic.content != (OpaquePtr) NULL)
+ {
+ CORE_ADDR pc, lowAddr;
+ TuiWinContent content;
+ struct symtab *s;
+
+ content = (TuiWinContent) disassemWin->generic.content;
+ if (current_source_symtab == (struct symtab *) NULL)
+ s = find_pc_symtab (selected_frame->pc);
+ else
+ s = current_source_symtab;
+
+ pc = content[0]->whichElement.source.lineOrAddr.addr;
+ if (find_pc_partial_function (pc, (char **) NULL, &lowAddr,
+ (CORE_ADDR) 0) == 0)
+ error ("No function contains program counter for selected frame.\n");
+ else
+ {
+ register int line = 0;
+ register CORE_ADDR newLow;
+ bfd_byte buffer[4];
+ TuiLineOrAddress val;
+
+ newLow = pc;
+ if (scrollDirection == FORWARD_SCROLL)
+ {
+ for (; line < numToScroll; line++)
+ newLow += sizeof (bfd_getb32 (buffer));
+ }
+ else
+ {
+ for (; newLow != 0 && line < numToScroll; line++)
+ newLow -= sizeof (bfd_getb32 (buffer));
+ }
+ val.addr = newLow;
+ tuiUpdateSourceWindowAsIs (disassemWin, s, val, FALSE);
+ }
+ }
+
+ return;
+} /* tuiVerticalDisassemScroll */
+
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS **
+******************************************/
+/*
+ ** _hasBreak().
+ ** Answer whether there is a break point at the input line in the
+ ** source file indicated
+ */
+static struct breakpoint *
+_hasBreak (CORE_ADDR addr)
+{
+ struct breakpoint *bpWithBreak = (struct breakpoint *) NULL;
+ struct breakpoint *bp;
+ extern struct breakpoint *breakpoint_chain;
+
+
+ for (bp = breakpoint_chain;
+ (bp != (struct breakpoint *) NULL &&
+ bpWithBreak == (struct breakpoint *) NULL);
+ bp = bp->next)
+ if (addr == bp->address)
+ bpWithBreak = bp;
+
+ return bpWithBreak;
+} /* _hasBreak */
diff --git a/gdb/tui/tuiDisassem.h b/gdb/tui/tuiDisassem.h
new file mode 100644
index 00000000000..f0aabdfb4c2
--- /dev/null
+++ b/gdb/tui/tuiDisassem.h
@@ -0,0 +1,41 @@
+/* Disassembly display.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef _TUI_DISASSEM_H
+#define _TUI_DISASSEM_H
+
+/*****************************************
+** TYPE DEFINITIONS **
+******************************************/
+
+
+
+/*****************************************
+** PUBLIC FUNCTION EXTERNAL DECLS **
+******************************************/
+extern TuiStatus tuiSetDisassemContent (struct symtab *, CORE_ADDR);
+extern void tuiShowDisassem (CORE_ADDR);
+extern void tuiShowDisassemAndUpdateSource (CORE_ADDR);
+extern void tuiVerticalDisassemScroll (TuiScrollDirection, int);
+extern CORE_ADDR tuiGetBeginAsmAddress (void);
+
+#endif
+/*_TUI_DISASSEM_H*/
diff --git a/gdb/tui/tuiGeneralWin.c b/gdb/tui/tuiGeneralWin.c
new file mode 100644
index 00000000000..b3f8b919a5d
--- /dev/null
+++ b/gdb/tui/tuiGeneralWin.c
@@ -0,0 +1,419 @@
+/* General window behavior.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+ Inc.
+
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include "defs.h"
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiGeneralWin.h"
+#include "tuiWin.h"
+
+/*
+ ** local support functions
+ */
+static void _winResize (void);
+
+
+/***********************
+** PUBLIC FUNCTIONS
+***********************/
+/*
+ ** tuiRefreshWin()
+ ** Refresh the window
+ */
+void
+tuiRefreshWin (TuiGenWinInfoPtr winInfo)
+{
+ if (winInfo->type == DATA_WIN && winInfo->contentSize > 0)
+ {
+ int i;
+
+ for (i = 0; (i < winInfo->contentSize); i++)
+ {
+ TuiGenWinInfoPtr dataItemWinPtr;
+
+ dataItemWinPtr = &((TuiWinContent)
+ winInfo->content)[i]->whichElement.dataWindow;
+ if (m_genWinPtrNotNull (dataItemWinPtr) &&
+ dataItemWinPtr->handle != (WINDOW *) NULL)
+ wrefresh (dataItemWinPtr->handle);
+ }
+ }
+ else if (winInfo->type == CMD_WIN)
+ {
+ /* Do nothing */
+ }
+ else
+ {
+ if (winInfo->handle != (WINDOW *) NULL)
+ wrefresh (winInfo->handle);
+ }
+
+ return;
+} /* tuiRefreshWin */
+
+
+/*
+ ** tuiDelwin()
+ ** Function to delete the curses window, checking for null
+ */
+void
+tuiDelwin (WINDOW * window)
+{
+ if (window != (WINDOW *) NULL)
+ delwin (window);
+
+ return;
+} /* tuiDelwin */
+
+
+/* Draw a border arround the window. */
+void
+boxWin (TuiGenWinInfoPtr winInfo, int highlightFlag)
+{
+ if (winInfo && winInfo->handle)
+ {
+ WINDOW *win;
+ int attrs;
+
+ win = winInfo->handle;
+ if (highlightFlag == HILITE)
+ attrs = tui_active_border_attrs;
+ else
+ attrs = tui_border_attrs;
+
+ wattron (win, attrs);
+ wborder (win, tui_border_vline, tui_border_vline,
+ tui_border_hline, tui_border_hline,
+ tui_border_ulcorner, tui_border_urcorner,
+ tui_border_llcorner, tui_border_lrcorner);
+ wattroff (win, attrs);
+ }
+}
+
+
+/*
+ ** unhighlightWin().
+ */
+void
+unhighlightWin (TuiWinInfoPtr winInfo)
+{
+ if (m_winPtrNotNull (winInfo) && winInfo->generic.handle != (WINDOW *) NULL)
+ {
+ boxWin ((TuiGenWinInfoPtr) winInfo, NO_HILITE);
+ wrefresh (winInfo->generic.handle);
+ m_setWinHighlightOff (winInfo);
+ }
+} /* unhighlightWin */
+
+
+/*
+ ** highlightWin().
+ */
+void
+highlightWin (TuiWinInfoPtr winInfo)
+{
+ if (m_winPtrNotNull (winInfo) &&
+ winInfo->canHighlight && winInfo->generic.handle != (WINDOW *) NULL)
+ {
+ boxWin ((TuiGenWinInfoPtr) winInfo, HILITE);
+ wrefresh (winInfo->generic.handle);
+ m_setWinHighlightOn (winInfo);
+ }
+} /* highlightWin */
+
+
+/*
+ ** checkAndDisplayHighlightIfNecessay
+ */
+void
+checkAndDisplayHighlightIfNeeded (TuiWinInfoPtr winInfo)
+{
+ if (m_winPtrNotNull (winInfo) && winInfo->generic.type != CMD_WIN)
+ {
+ if (winInfo->isHighlighted)
+ highlightWin (winInfo);
+ else
+ unhighlightWin (winInfo);
+
+ }
+ return;
+} /* checkAndDisplayHighlightIfNeeded */
+
+
+/*
+ ** makeWindow().
+ */
+void
+makeWindow (TuiGenWinInfoPtr winInfo, int boxIt)
+{
+ WINDOW *handle;
+
+ handle = newwin (winInfo->height,
+ winInfo->width,
+ winInfo->origin.y,
+ winInfo->origin.x);
+ winInfo->handle = handle;
+ if (handle != (WINDOW *) NULL)
+ {
+ if (boxIt == BOX_WINDOW)
+ boxWin (winInfo, NO_HILITE);
+ winInfo->isVisible = TRUE;
+ scrollok (handle, TRUE);
+ tuiRefreshWin (winInfo);
+
+#ifndef FOR_TEST
+ if ( /*!m_WinIsAuxillary(winInfo->type) && */
+ (winInfo->type != CMD_WIN) &&
+ (winInfo->content == (OpaquePtr) NULL))
+ {
+ mvwaddstr (handle, 1, 1, winName (winInfo));
+ tuiRefreshWin (winInfo);
+ }
+#endif /*FOR_TEST */
+ }
+
+ return;
+} /* makeWindow */
+
+
+/*
+ ** tuiClearWin().
+ ** Clear the window of all contents without calling wclear.
+ */
+void
+tuiClearWin (TuiGenWinInfoPtr winInfo)
+{
+ if (m_genWinPtrNotNull (winInfo) && winInfo->handle != (WINDOW *) NULL)
+ {
+ int curRow, curCol;
+
+ for (curRow = 0; (curRow < winInfo->height); curRow++)
+ for (curCol = 0; (curCol < winInfo->width); curCol++)
+ mvwaddch (winInfo->handle, curRow, curCol, ' ');
+
+ tuiRefreshWin (winInfo);
+ }
+
+ return;
+} /* tuiClearWin */
+
+
+/*
+ ** makeVisible().
+ ** We can't really make windows visible, or invisible. So we
+ ** have to delete the entire window when making it visible,
+ ** and create it again when making it visible.
+ */
+void
+makeVisible (TuiGenWinInfoPtr winInfo, int visible)
+{
+ /* Don't tear down/recreate command window */
+ if (winInfo->type == CMD_WIN)
+ return;
+
+ if (visible)
+ {
+ if (!winInfo->isVisible)
+ {
+ makeWindow (
+ winInfo,
+ (winInfo->type != CMD_WIN && !m_winIsAuxillary (winInfo->type)));
+ winInfo->isVisible = TRUE;
+ }
+ tuiRefreshWin (winInfo);
+ }
+ else if (!visible &&
+ winInfo->isVisible && winInfo->handle != (WINDOW *) NULL)
+ {
+ winInfo->isVisible = FALSE;
+ tuiClearWin (winInfo);
+ tuiDelwin (winInfo->handle);
+ winInfo->handle = (WINDOW *) NULL;
+ }
+
+ return;
+} /* makeVisible */
+
+
+/*
+ ** makeAllVisible().
+ ** Makes all windows invisible (except the command and locator windows)
+ */
+void
+makeAllVisible (int visible)
+{
+ int i;
+
+ for (i = 0; i < MAX_MAJOR_WINDOWS; i++)
+ {
+ if (m_winPtrNotNull (winList[i]) &&
+ ((winList[i])->generic.type) != CMD_WIN)
+ {
+ if (m_winIsSourceType ((winList[i])->generic.type))
+ makeVisible ((winList[i])->detail.sourceInfo.executionInfo,
+ visible);
+ makeVisible ((TuiGenWinInfoPtr) winList[i], visible);
+ }
+ }
+
+ return;
+} /* makeAllVisible */
+
+
+/*
+ ** scrollWinForward
+ */
+void
+scrollWinForward (TuiGenWinInfoPtr winInfo, int numLines)
+{
+ if (winInfo->content != (OpaquePtr) NULL &&
+ winInfo->lastVisibleLine < winInfo->contentSize - 1)
+ {
+ int i, firstLine, newLastLine;
+
+ firstLine = winInfo->lastVisibleLine - winInfo->viewportHeight + 1;
+ if (winInfo->lastVisibleLine + numLines > winInfo->contentSize)
+ newLastLine = winInfo->contentSize - 1;
+ else
+ newLastLine = winInfo->lastVisibleLine + numLines - 1;
+
+ for (i = (newLastLine - winInfo->viewportHeight);
+ (i <= newLastLine); i++)
+ {
+ TuiWinElementPtr line;
+ int lineHeight;
+
+ line = (TuiWinElementPtr) winInfo->content[i];
+ if (line->highlight)
+ wstandout (winInfo->handle);
+ mvwaddstr (winInfo->handle,
+ i - (newLastLine - winInfo->viewportHeight),
+ 1,
+ displayableWinContentOf (winInfo, line));
+ if (line->highlight)
+ wstandend (winInfo->handle);
+ lineHeight = winElementHeight (winInfo, line);
+ newLastLine += (lineHeight - 1);
+ }
+ winInfo->lastVisibleLine = newLastLine;
+ }
+
+ return;
+} /* scrollWinForward */
+
+
+/*
+ ** scrollWinBackward
+ */
+void
+scrollWinBackward (TuiGenWinInfoPtr winInfo, int numLines)
+{
+ if (winInfo->content != (OpaquePtr) NULL &&
+ (winInfo->lastVisibleLine - winInfo->viewportHeight) > 0)
+ {
+ int i, newLastLine, firstLine;
+
+ firstLine = winInfo->lastVisibleLine - winInfo->viewportHeight + 1;
+ if ((firstLine - numLines) < 0)
+ newLastLine = winInfo->viewportHeight - 1;
+ else
+ newLastLine = winInfo->lastVisibleLine - numLines + 1;
+
+ for (i = newLastLine - winInfo->viewportHeight; (i <= newLastLine); i++)
+ {
+ TuiWinElementPtr line;
+ int lineHeight;
+
+ line = (TuiWinElementPtr) winInfo->content[i];
+ if (line->highlight)
+ wstandout (winInfo->handle);
+ mvwaddstr (winInfo->handle,
+ i - (newLastLine - winInfo->viewportHeight),
+ 1,
+ displayableWinContentOf (winInfo, line));
+ if (line->highlight)
+ wstandend (winInfo->handle);
+ lineHeight = winElementHeight (winInfo, line);
+ newLastLine += (lineHeight - 1);
+ }
+ winInfo->lastVisibleLine = newLastLine;
+ }
+
+ return;
+} /* scrollWinBackward */
+
+
+/*
+ ** refreshAll().
+ ** Function to refresh all the windows currently displayed
+ */
+void
+refreshAll (TuiWinInfoPtr * list)
+{
+ TuiWinType type;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+ for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++)
+ {
+ if (list[type] && list[type]->generic.isVisible)
+ {
+ if (type == SRC_WIN || type == DISASSEM_WIN)
+ {
+ touchwin (list[type]->detail.sourceInfo.executionInfo->handle);
+ tuiRefreshWin (list[type]->detail.sourceInfo.executionInfo);
+ }
+ touchwin (list[type]->generic.handle);
+ tuiRefreshWin (&list[type]->generic);
+ }
+ }
+ if (locator->isVisible)
+ {
+ touchwin (locator->handle);
+ tuiRefreshWin (locator);
+ }
+
+ return;
+} /* refreshAll */
+
+
+/*********************************
+** Local Static Functions
+*********************************/
diff --git a/gdb/tui/tuiGeneralWin.h b/gdb/tui/tuiGeneralWin.h
new file mode 100644
index 00000000000..60c54f1bbe7
--- /dev/null
+++ b/gdb/tui/tuiGeneralWin.h
@@ -0,0 +1,52 @@
+/* General window behavior.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef TUI_GENERAL_WIN_H
+#define TUI_GENERAL_WIN_H
+
+/*
+ ** Functions
+ */
+extern void tuiClearWin (TuiGenWinInfoPtr);
+extern void unhighlightWin (TuiWinInfoPtr);
+extern void makeVisible (TuiGenWinInfoPtr, int);
+extern void makeAllVisible (int);
+extern void scrollWinForward (TuiGenWinInfoPtr, int);
+extern void scrollWinBackward (TuiGenWinInfoPtr, int);
+extern void makeWindow (TuiGenWinInfoPtr, int);
+extern TuiWinInfoPtr copyWin (TuiWinInfoPtr);
+extern void boxWin (TuiGenWinInfoPtr, int);
+extern void highlightWin (TuiWinInfoPtr);
+extern void checkAndDisplayHighlightIfNeeded (TuiWinInfoPtr);
+extern void refreshAll (TuiWinInfoPtr *);
+extern void tuiDelwin (WINDOW * window);
+extern void tuiRefreshWin (TuiGenWinInfoPtr);
+
+/*
+ ** Macros
+ */
+#define m_beVisible(winInfo) makeVisible((TuiGenWinInfoPtr)(winInfo), TRUE)
+#define m_beInvisible(winInfo) \
+ makeVisible((TuiGenWinInfoPtr)(winInfo), FALSE)
+#define m_allBeVisible() makeAllVisible(TRUE)
+#define m_allBeInvisible() makeAllVisible(FALSE)
+
+#endif /*TUI_GENERAL_WIN_H */
diff --git a/gdb/tui/tuiIO.c b/gdb/tui/tuiIO.c
new file mode 100644
index 00000000000..d664128ebd6
--- /dev/null
+++ b/gdb/tui/tuiIO.c
@@ -0,0 +1,463 @@
+/* TUI support I/O functions.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+ Inc.
+
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include <stdio.h>
+#include "defs.h"
+#include "terminal.h"
+#include "target.h"
+#include "event-loop.h"
+#include "command.h"
+#include "top.h"
+#include "readline/readline.h"
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiIO.h"
+#include "tuiCommand.h"
+#include "tuiWin.h"
+#include "tuiGeneralWin.h"
+#include "tui-file.h"
+#include "ui-out.h"
+#include "cli-out.h"
+#include <fcntl.h>
+#include <signal.h>
+
+/* This file controls the IO interactions between gdb and curses.
+ When the TUI is enabled, gdb has two modes a curses and a standard
+ mode.
+
+ In curses mode, the gdb outputs are made in a curses command window.
+ For this, the gdb_stdout and gdb_stderr are redirected to the specific
+ ui_file implemented by TUI. The output is handled by tui_puts().
+ The input is also controlled by curses with tui_getc(). The readline
+ library uses this function to get its input. Several readline hooks
+ are installed to redirect readline output to the TUI (see also the
+ note below).
+
+ In normal mode, the gdb outputs are restored to their origin, that
+ is as if TUI is not used. Readline also uses its original getc()
+ function with stdin.
+
+ Note: the current readline is not clean in its management of the output.
+ Even if we install a redisplay handler, it sometimes writes on a stdout
+ file. It is important to redirect every output produced by readline,
+ otherwise the curses window will be garbled. This is implemented with
+ a pipe that TUI reads and readline writes to. A gdb input handler
+ is created so that reading the pipe is handled automatically.
+ This will probably not work on non-Unix platforms. The best fix is
+ to make readline clean enougth so that is never write on stdout. */
+
+/* TUI output files. */
+static struct ui_file *tui_stdout;
+static struct ui_file *tui_stderr;
+static struct ui_out *tui_out;
+
+/* GDB output files in non-curses mode. */
+static struct ui_file *tui_old_stdout;
+static struct ui_file *tui_old_stderr;
+static struct ui_out *tui_old_uiout;
+
+/* Readline previous hooks. */
+static Function *tui_old_rl_getc_function;
+static VFunction *tui_old_rl_redisplay_function;
+static VFunction *tui_old_rl_prep_terminal;
+static VFunction *tui_old_rl_deprep_terminal;
+static int tui_old_readline_echoing_p;
+
+/* Readline output stream.
+ Should be removed when readline is clean. */
+static FILE *tui_rl_outstream;
+static FILE *tui_old_rl_outstream;
+static int tui_readline_pipe[2];
+
+static unsigned int _tuiHandleResizeDuringIO (unsigned int);
+
+
+/* Print the string in the curses command window. */
+void
+tui_puts (const char *string)
+{
+ static int tui_skip_line = -1;
+ char c;
+ WINDOW *w;
+
+ w = cmdWin->generic.handle;
+ while ((c = *string++) != 0)
+ {
+ /* Catch annotation and discard them. We need two \032 and
+ discard until a \n is seen. */
+ if (c == '\032')
+ {
+ tui_skip_line++;
+ }
+ else if (tui_skip_line != 1)
+ {
+ tui_skip_line = -1;
+ waddch (w, c);
+ }
+ else if (c == '\n')
+ tui_skip_line = -1;
+ }
+ getyx (w, cmdWin->detail.commandInfo.curLine,
+ cmdWin->detail.commandInfo.curch);
+ cmdWin->detail.commandInfo.start_line = cmdWin->detail.commandInfo.curLine;
+
+ /* We could defer the following. */
+ wrefresh (w);
+ fflush (stdout);
+}
+
+/* Readline callback.
+ Redisplay the command line with its prompt after readline has
+ changed the edited text. */
+static void
+tui_redisplay_readline (void)
+{
+ int prev_col;
+ int height;
+ int col, line;
+ int c_pos;
+ int c_line;
+ int in;
+ WINDOW *w;
+ char *prompt;
+ int start_line;
+
+ prompt = get_prompt ();
+
+ c_pos = -1;
+ c_line = -1;
+ w = cmdWin->generic.handle;
+ start_line = cmdWin->detail.commandInfo.start_line;
+ wmove (w, start_line, 0);
+ prev_col = 0;
+ height = 1;
+ for (in = 0; prompt && prompt[in]; in++)
+ {
+ waddch (w, prompt[in]);
+ getyx (w, line, col);
+ if (col < prev_col)
+ height++;
+ prev_col = col;
+ }
+ for (in = 0; in < rl_end; in++)
+ {
+ unsigned char c;
+
+ c = (unsigned char) rl_line_buffer[in];
+ if (in == rl_point)
+ {
+ getyx (w, c_line, c_pos);
+ }
+
+ if (CTRL_CHAR (c) || c == RUBOUT)
+ {
+ waddch (w, '^');
+ waddch (w, CTRL_CHAR (c) ? UNCTRL (c) : '?');
+ }
+ else
+ {
+ waddch (w, c);
+ }
+ if (c == '\n')
+ {
+ getyx (w, cmdWin->detail.commandInfo.start_line,
+ cmdWin->detail.commandInfo.curch);
+ }
+ getyx (w, line, col);
+ if (col < prev_col)
+ height++;
+ prev_col = col;
+ }
+ wclrtobot (w);
+ getyx (w, cmdWin->detail.commandInfo.start_line,
+ cmdWin->detail.commandInfo.curch);
+ if (c_line >= 0)
+ {
+ wmove (w, c_line, c_pos);
+ cmdWin->detail.commandInfo.curLine = c_line;
+ cmdWin->detail.commandInfo.curch = c_pos;
+ }
+ cmdWin->detail.commandInfo.start_line -= height - 1;
+
+ wrefresh (w);
+ fflush(stdout);
+}
+
+/* Readline callback to prepare the terminal. It is called once
+ each time we enter readline. There is nothing to do in curses mode. */
+static void
+tui_prep_terminal (void)
+{
+}
+
+/* Readline callback to restore the terminal. It is called once
+ each time we leave readline. There is nothing to do in curses mode. */
+static void
+tui_deprep_terminal (void)
+{
+}
+
+/* Read readline output pipe and feed the command window with it.
+ Should be removed when readline is clean. */
+static void
+tui_readline_output (int code, gdb_client_data data)
+{
+ int size;
+ char buf[256];
+
+ size = read (tui_readline_pipe[0], buf, sizeof (buf) - 1);
+ if (size > 0 && tui_active)
+ {
+ buf[size] = 0;
+ tui_puts (buf);
+ }
+}
+
+/* Setup the IO for curses or non-curses mode.
+ - In non-curses mode, readline and gdb use the standard input and
+ standard output/error directly.
+ - In curses mode, the standard output/error is controlled by TUI
+ with the tui_stdout and tui_stderr. The output is redirected in
+ the curses command window. Several readline callbacks are installed
+ so that readline asks for its input to the curses command window
+ with wgetch(). */
+void
+tui_setup_io (int mode)
+{
+ extern int readline_echoing_p;
+
+ if (mode)
+ {
+ /* Redirect readline to TUI. */
+ tui_old_rl_redisplay_function = rl_redisplay_function;
+ tui_old_rl_deprep_terminal = rl_deprep_term_function;
+ tui_old_rl_prep_terminal = rl_prep_term_function;
+ tui_old_rl_getc_function = rl_getc_function;
+ tui_old_rl_outstream = rl_outstream;
+ tui_old_readline_echoing_p = readline_echoing_p;
+ rl_redisplay_function = tui_redisplay_readline;
+ rl_deprep_term_function = tui_deprep_terminal;
+ rl_prep_term_function = tui_prep_terminal;
+ rl_getc_function = tui_getc;
+ readline_echoing_p = 0;
+ rl_outstream = tui_rl_outstream;
+ rl_prompt = 0;
+
+ /* Keep track of previous gdb output. */
+ tui_old_stdout = gdb_stdout;
+ tui_old_stderr = gdb_stderr;
+ tui_old_uiout = uiout;
+
+ /* Reconfigure gdb output. */
+ gdb_stdout = tui_stdout;
+ gdb_stderr = tui_stderr;
+ gdb_stdlog = gdb_stdout; /* for moment */
+ gdb_stdtarg = gdb_stderr; /* for moment */
+ uiout = tui_out;
+
+ /* Save tty for SIGCONT. */
+ savetty ();
+ }
+ else
+ {
+ /* Restore gdb output. */
+ gdb_stdout = tui_old_stdout;
+ gdb_stderr = tui_old_stderr;
+ gdb_stdlog = gdb_stdout; /* for moment */
+ gdb_stdtarg = gdb_stderr; /* for moment */
+ uiout = tui_old_uiout;
+
+ /* Restore readline. */
+ rl_redisplay_function = tui_old_rl_redisplay_function;
+ rl_deprep_term_function = tui_old_rl_deprep_terminal;
+ rl_prep_term_function = tui_old_rl_prep_terminal;
+ rl_getc_function = tui_old_rl_getc_function;
+ rl_outstream = tui_old_rl_outstream;
+ readline_echoing_p = tui_old_readline_echoing_p;
+
+ /* Save tty for SIGCONT. */
+ savetty ();
+ }
+}
+
+#ifdef SIGCONT
+/* Catch SIGCONT to restore the terminal and refresh the screen. */
+static void
+tui_cont_sig (int sig)
+{
+ if (tui_active)
+ {
+ /* Restore the terminal setting because another process (shell)
+ might have changed it. */
+ resetty ();
+
+ /* Force a refresh of the screen. */
+ tuiRefreshAll ();
+
+ /* Update cursor position on the screen. */
+ wmove (cmdWin->generic.handle,
+ cmdWin->detail.commandInfo.start_line,
+ cmdWin->detail.commandInfo.curch);
+ wrefresh (cmdWin->generic.handle);
+ }
+ signal (sig, tui_cont_sig);
+}
+#endif
+
+/* Initialize the IO for gdb in curses mode. */
+void
+tui_initialize_io ()
+{
+#ifdef SIGCONT
+ signal (SIGCONT, tui_cont_sig);
+#endif
+
+ /* Create tui output streams. */
+ tui_stdout = tui_fileopen (stdout);
+ tui_stderr = tui_fileopen (stderr);
+ tui_out = tui_out_new (tui_stdout);
+
+ /* Create the default UI. It is not created because we installed
+ a init_ui_hook. */
+ uiout = cli_out_new (gdb_stdout);
+
+ /* Temporary solution for readline writing to stdout:
+ redirect readline output in a pipe, read that pipe and
+ output the content in the curses command window. */
+ if (pipe (tui_readline_pipe) != 0)
+ {
+ fprintf_unfiltered (gdb_stderr, "Cannot create pipe for readline");
+ exit (1);
+ }
+ tui_rl_outstream = fdopen (tui_readline_pipe[1], "w");
+ if (tui_rl_outstream == 0)
+ {
+ fprintf_unfiltered (gdb_stderr, "Cannot redirect readline output");
+ exit (1);
+ }
+ setlinebuf (tui_rl_outstream);
+
+#ifdef O_NONBLOCK
+ (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NONBLOCK);
+#else
+#ifdef O_NDELAY
+ (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY);
+#endif
+#endif
+
+ add_file_handler (tui_readline_pipe[0], tui_readline_output, 0);
+}
+
+/* Get a character from the command window. This is called from the readline
+ package. */
+int
+tui_getc (FILE *fp)
+{
+ int ch;
+ WINDOW *w;
+
+ w = cmdWin->generic.handle;
+
+ /* Flush readline output. */
+ tui_readline_output (GDB_READABLE, 0);
+
+ ch = wgetch (w);
+ ch = _tuiHandleResizeDuringIO (ch);
+
+ /* The \n must be echoed because it will not be printed by readline. */
+ if (ch == '\n')
+ {
+ /* When hitting return with an empty input, gdb executes the last
+ command. If we emit a newline, this fills up the command window
+ with empty lines with gdb prompt at beginning. Instead of that,
+ stay on the same line but provide a visual effect to show the
+ user we recognized the command. */
+ if (rl_end == 0)
+ {
+ wmove (w, cmdWin->detail.commandInfo.curLine, 0);
+
+ /* Clear the line. This will blink the gdb prompt since
+ it will be redrawn at the same line. */
+ wclrtoeol (w);
+ wrefresh (w);
+ napms (20);
+ }
+ else
+ {
+ wmove (w, cmdWin->detail.commandInfo.curLine,
+ cmdWin->detail.commandInfo.curch);
+ waddch (w, ch);
+ }
+ }
+
+ if (m_isCommandChar (ch))
+ { /* Handle prev/next/up/down here */
+ ch = tuiDispatchCtrlChar (ch);
+ }
+
+ if (ch == '\n' || ch == '\r' || ch == '\f')
+ cmdWin->detail.commandInfo.curch = 0;
+#if 0
+ else
+ tuiIncrCommandCharCountBy (1);
+#endif
+ if (ch == KEY_BACKSPACE)
+ return '\b';
+
+ return ch;
+}
+
+
+/* Cleanup when a resize has occured.
+ Returns the character that must be processed. */
+static unsigned int
+_tuiHandleResizeDuringIO (unsigned int originalCh)
+{
+ if (tuiWinResized ())
+ {
+ tuiRefreshAll ();
+ dont_repeat ();
+ tuiSetWinResizedTo (FALSE);
+ return '\n';
+ }
+ else
+ return originalCh;
+}
diff --git a/gdb/tui/tuiIO.h b/gdb/tui/tuiIO.h
new file mode 100644
index 00000000000..2ad92ce81f1
--- /dev/null
+++ b/gdb/tui/tuiIO.h
@@ -0,0 +1,62 @@
+/* TUI support I/O functions.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef _TUI_IO_H
+#define _TUI_IO_H
+
+#include <stdio.h>
+
+/* Print the string in the curses command window. */
+extern void tui_puts (const char *);
+
+/* Setup the IO for curses or non-curses mode. */
+extern void tui_setup_io (int mode);
+
+/* Initialize the IO for gdb in curses mode. */
+extern void tui_initialize_io (void);
+
+/* Get a character from the command window. */
+extern int tui_getc (FILE*);
+
+
+#define m_tuiStartNewLine tuiStartNewLines(1)
+#define m_isStartSequence(ch) (ch == 27)
+#define m_isEndSequence(ch) (ch == 126)
+#define m_isBackspace(ch) (ch == 8)
+#define m_isDeleteChar(ch) (ch == KEY_DC)
+#define m_isDeleteLine(ch) (ch == KEY_DL)
+#define m_isDeleteToEol(ch) (ch == KEY_EOL)
+#define m_isNextPage(ch) (ch == KEY_NPAGE)
+#define m_isPrevPage(ch) (ch == KEY_PPAGE)
+#define m_isLeftArrow(ch) (ch == KEY_LEFT)
+#define m_isRightArrow(ch) (ch == KEY_RIGHT)
+
+#define m_isCommandChar(ch) (m_isNextPage(ch) || m_isPrevPage(ch) || \
+ m_isLeftArrow(ch) || m_isRightArrow(ch) || \
+ (ch == KEY_UP) || (ch == KEY_DOWN) || \
+ (ch == KEY_SF) || (ch == KEY_SR) || \
+ (ch == (int)'\f') || m_isStartSequence(ch))
+
+#define m_isXdbStyleCommandChar(ch) (m_isNextPage(ch) || m_isPrevPage(ch))
+
+
+#endif
+
diff --git a/gdb/tui/tuiLayout.c b/gdb/tui/tuiLayout.c
new file mode 100644
index 00000000000..aa98882d9d3
--- /dev/null
+++ b/gdb/tui/tuiLayout.c
@@ -0,0 +1,1179 @@
+/* TUI layout window management.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+ Inc.
+
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include "defs.h"
+#include "command.h"
+#include "symtab.h"
+#include "frame.h"
+#include <ctype.h>
+
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiDataWin.h"
+#include "tuiGeneralWin.h"
+#include "tuiStack.h"
+#include "tuiRegs.h"
+#include "tuiWin.h"
+#include "tuiSourceWin.h"
+#include "tuiDisassem.h"
+
+/*******************************
+** Static Local Decls
+********************************/
+
+static void _initGenWinInfo (TuiGenWinInfoPtr, TuiWinType, int, int, int, int);
+static void _initAndMakeWin (Opaque *, TuiWinType, int, int, int, int, int);
+static void _showSourceOrDisassemAndCommand (TuiLayoutType);
+static void _makeSourceOrDisassemWindow (TuiWinInfoPtr *, TuiWinType, int, int);
+static void _makeCommandWindow (TuiWinInfoPtr *, int, int);
+static void _makeSourceWindow (TuiWinInfoPtr *, int, int);
+static void _makeDisassemWindow (TuiWinInfoPtr *, int, int);
+static void _makeDataWindow (TuiWinInfoPtr *, int, int);
+static void _showSourceCommand (void);
+static void _showDisassemCommand (void);
+static void _showSourceDisassemCommand (void);
+static void _showData (TuiLayoutType);
+static TuiLayoutType _nextLayout (void);
+static TuiLayoutType _prevLayout (void);
+static void _tuiLayout_command (char *, int);
+static void _tuiToggleLayout_command (char *, int);
+static void _tuiToggleSplitLayout_command (char *, int);
+static CORE_ADDR _extractDisplayStartAddr (void);
+static void _tuiHandleXDBLayout (TuiLayoutDefPtr);
+
+
+/***************************************
+** DEFINITIONS
+***************************************/
+
+#define LAYOUT_USAGE "Usage: layout prev | next | <layout_name> \n"
+
+/***************************************
+** Static Local Data
+***************************************/
+static TuiLayoutType lastLayout = UNDEFINED_LAYOUT;
+
+/***************************************
+** PUBLIC FUNCTIONS
+***************************************/
+
+/*
+ ** showLayout().
+ ** Show the screen layout defined
+ */
+void
+showLayout (TuiLayoutType layout)
+{
+ TuiLayoutType curLayout = currentLayout ();
+
+ if (layout != curLayout)
+ {
+ /*
+ ** Since the new layout may cause changes in window size, we
+ ** should free the content and reallocate on next display of
+ ** source/asm
+ */
+ tuiClearAllSourceWinsContent (NO_EMPTY_SOURCE_PROMPT);
+ freeAllSourceWinsContent ();
+ clearSourceWindows ();
+ if (layout == SRC_DATA_COMMAND || layout == DISASSEM_DATA_COMMAND)
+ {
+ _showData (layout);
+ refreshAll (winList);
+ }
+ else
+ {
+ /* First make the current layout be invisible */
+ m_allBeInvisible ();
+ m_beInvisible (locatorWinInfoPtr ());
+
+ switch (layout)
+ {
+ /* Now show the new layout */
+ case SRC_COMMAND:
+ _showSourceCommand ();
+ addToSourceWindows (srcWin);
+ break;
+ case DISASSEM_COMMAND:
+ _showDisassemCommand ();
+ addToSourceWindows (disassemWin);
+ break;
+ case SRC_DISASSEM_COMMAND:
+ _showSourceDisassemCommand ();
+ addToSourceWindows (srcWin);
+ addToSourceWindows (disassemWin);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return;
+} /* showLayout */
+
+
+/*
+ ** tuiSetLayout()
+ ** Function to set the layout to SRC_COMMAND, DISASSEM_COMMAND,
+ ** SRC_DISASSEM_COMMAND, SRC_DATA_COMMAND, or DISASSEM_DATA_COMMAND.
+ ** If the layout is SRC_DATA_COMMAND, DISASSEM_DATA_COMMAND, or
+ ** UNDEFINED_LAYOUT, then the data window is populated according
+ ** to regsDisplayType.
+ */
+TuiStatus
+tuiSetLayout (TuiLayoutType layoutType,
+ TuiRegisterDisplayType regsDisplayType)
+{
+ TuiStatus status = TUI_SUCCESS;
+
+ if (layoutType != UNDEFINED_LAYOUT || regsDisplayType != TUI_UNDEFINED_REGS)
+ {
+ TuiLayoutType curLayout = currentLayout (), newLayout = UNDEFINED_LAYOUT;
+ int regsPopulate = FALSE;
+ CORE_ADDR addr = _extractDisplayStartAddr ();
+ TuiWinInfoPtr newWinWithFocus = (TuiWinInfoPtr) NULL, winWithFocus = tuiWinWithFocus ();
+ TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
+
+
+ if (layoutType == UNDEFINED_LAYOUT &&
+ regsDisplayType != TUI_UNDEFINED_REGS)
+ {
+ if (curLayout == SRC_DISASSEM_COMMAND)
+ newLayout = DISASSEM_DATA_COMMAND;
+ else if (curLayout == SRC_COMMAND || curLayout == SRC_DATA_COMMAND)
+ newLayout = SRC_DATA_COMMAND;
+ else if (curLayout == DISASSEM_COMMAND ||
+ curLayout == DISASSEM_DATA_COMMAND)
+ newLayout = DISASSEM_DATA_COMMAND;
+ }
+ else
+ newLayout = layoutType;
+
+ regsPopulate = (newLayout == SRC_DATA_COMMAND ||
+ newLayout == DISASSEM_DATA_COMMAND ||
+ regsDisplayType != TUI_UNDEFINED_REGS);
+ if (newLayout != curLayout || regsDisplayType != TUI_UNDEFINED_REGS)
+ {
+ if (newLayout != curLayout)
+ {
+ if (winWithFocus != cmdWin)
+ tuiClearWinFocus ();
+ showLayout (newLayout);
+ /*
+ ** Now determine where focus should be
+ */
+ if (winWithFocus != cmdWin)
+ {
+ switch (newLayout)
+ {
+ case SRC_COMMAND:
+ tuiSetWinFocusTo (srcWin);
+ layoutDef->displayMode = SRC_WIN;
+ layoutDef->split = FALSE;
+ break;
+ case DISASSEM_COMMAND:
+ /* the previous layout was not showing
+ ** code. this can happen if there is no
+ ** source available:
+ ** 1. if the source file is in another dir OR
+ ** 2. if target was compiled without -g
+ ** We still want to show the assembly though!
+ */
+ addr = tuiGetBeginAsmAddress ();
+ tuiSetWinFocusTo (disassemWin);
+ layoutDef->displayMode = DISASSEM_WIN;
+ layoutDef->split = FALSE;
+ break;
+ case SRC_DISASSEM_COMMAND:
+ /* the previous layout was not showing
+ ** code. this can happen if there is no
+ ** source available:
+ ** 1. if the source file is in another dir OR
+ ** 2. if target was compiled without -g
+ ** We still want to show the assembly though!
+ */
+ addr = tuiGetBeginAsmAddress ();
+ if (winWithFocus == srcWin)
+ tuiSetWinFocusTo (srcWin);
+ else
+ tuiSetWinFocusTo (disassemWin);
+ layoutDef->split = TRUE;
+ break;
+ case SRC_DATA_COMMAND:
+ if (winWithFocus != dataWin)
+ tuiSetWinFocusTo (srcWin);
+ else
+ tuiSetWinFocusTo (dataWin);
+ layoutDef->displayMode = SRC_WIN;
+ layoutDef->split = FALSE;
+ break;
+ case DISASSEM_DATA_COMMAND:
+ /* the previous layout was not showing
+ ** code. this can happen if there is no
+ ** source available:
+ ** 1. if the source file is in another dir OR
+ ** 2. if target was compiled without -g
+ ** We still want to show the assembly though!
+ */
+ addr = tuiGetBeginAsmAddress ();
+ if (winWithFocus != dataWin)
+ tuiSetWinFocusTo (disassemWin);
+ else
+ tuiSetWinFocusTo (dataWin);
+ layoutDef->displayMode = DISASSEM_WIN;
+ layoutDef->split = FALSE;
+ break;
+ default:
+ break;
+ }
+ }
+ if (newWinWithFocus != (TuiWinInfoPtr) NULL)
+ tuiSetWinFocusTo (newWinWithFocus);
+ /*
+ ** Now update the window content
+ */
+ if (!regsPopulate &&
+ (newLayout == SRC_DATA_COMMAND ||
+ newLayout == DISASSEM_DATA_COMMAND))
+ tuiDisplayAllData ();
+
+ tuiUpdateSourceWindowsWithAddr (addr);
+ }
+ if (regsPopulate)
+ {
+ layoutDef->regsDisplayType =
+ (regsDisplayType == TUI_UNDEFINED_REGS ?
+ TUI_GENERAL_REGS : regsDisplayType);
+ tuiShowRegisters (layoutDef->regsDisplayType);
+ }
+ }
+ }
+ else
+ status = TUI_FAILURE;
+
+ return status;
+} /* tuiSetLayout */
+
+/*
+ ** tuiAddWinToLayout().
+ ** Add the specified window to the layout in a logical way.
+ ** This means setting up the most logical layout given the
+ ** window to be added.
+ */
+void
+tuiAddWinToLayout (TuiWinType type)
+{
+ TuiLayoutType curLayout = currentLayout ();
+
+ switch (type)
+ {
+ case SRC_WIN:
+ if (curLayout != SRC_COMMAND &&
+ curLayout != SRC_DISASSEM_COMMAND &&
+ curLayout != SRC_DATA_COMMAND)
+ {
+ clearSourceWindowsDetail ();
+ if (curLayout == DISASSEM_DATA_COMMAND)
+ showLayout (SRC_DATA_COMMAND);
+ else
+ showLayout (SRC_COMMAND);
+ }
+ break;
+ case DISASSEM_WIN:
+ if (curLayout != DISASSEM_COMMAND &&
+ curLayout != SRC_DISASSEM_COMMAND &&
+ curLayout != DISASSEM_DATA_COMMAND)
+ {
+ clearSourceWindowsDetail ();
+ if (curLayout == SRC_DATA_COMMAND)
+ showLayout (DISASSEM_DATA_COMMAND);
+ else
+ showLayout (DISASSEM_COMMAND);
+ }
+ break;
+ case DATA_WIN:
+ if (curLayout != SRC_DATA_COMMAND &&
+ curLayout != DISASSEM_DATA_COMMAND)
+ {
+ if (curLayout == DISASSEM_COMMAND)
+ showLayout (DISASSEM_DATA_COMMAND);
+ else
+ showLayout (SRC_DATA_COMMAND);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return;
+} /* tuiAddWinToLayout */
+
+
+/*
+ ** tuiDefaultWinHeight().
+ ** Answer the height of a window. If it hasn't been created yet,
+ ** answer what the height of a window would be based upon its
+ ** type and the layout.
+ */
+int
+tuiDefaultWinHeight (TuiWinType type, TuiLayoutType layout)
+{
+ int h;
+
+ if (winList[type] != (TuiWinInfoPtr) NULL)
+ h = winList[type]->generic.height;
+ else
+ {
+ switch (layout)
+ {
+ case SRC_COMMAND:
+ case DISASSEM_COMMAND:
+ if (m_winPtrIsNull (cmdWin))
+ h = termHeight () / 2;
+ else
+ h = termHeight () - cmdWin->generic.height;
+ break;
+ case SRC_DISASSEM_COMMAND:
+ case SRC_DATA_COMMAND:
+ case DISASSEM_DATA_COMMAND:
+ if (m_winPtrIsNull (cmdWin))
+ h = termHeight () / 3;
+ else
+ h = (termHeight () - cmdWin->generic.height) / 2;
+ break;
+ default:
+ h = 0;
+ break;
+ }
+ }
+
+ return h;
+} /* tuiDefaultWinHeight */
+
+
+/*
+ ** tuiDefaultWinViewportHeight().
+ ** Answer the height of a window. If it hasn't been created yet,
+ ** answer what the height of a window would be based upon its
+ ** type and the layout.
+ */
+int
+tuiDefaultWinViewportHeight (TuiWinType type, TuiLayoutType layout)
+{
+ int h;
+
+ h = tuiDefaultWinHeight (type, layout);
+
+ if (winList[type] == cmdWin)
+ h -= 1;
+ else
+ h -= 2;
+
+ return h;
+} /* tuiDefaultWinViewportHeight */
+
+
+/*
+ ** _initialize_tuiLayout().
+ ** Function to initialize gdb commands, for tui window layout
+ ** manipulation.
+ */
+void
+_initialize_tuiLayout (void)
+{
+ add_com ("layout", class_tui, _tuiLayout_command,
+ "Change the layout of windows.\n\
+Usage: layout prev | next | <layout_name> \n\
+Layout names are:\n\
+ src : Displays source and command windows.\n\
+ asm : Displays disassembly and command windows.\n\
+ split : Displays source, disassembly and command windows.\n\
+ regs : Displays register window. If existing layout\n\
+ is source/command or assembly/command, the \n\
+ register window is displayed. If the\n\
+ source/assembly/command (split) is displayed, \n\
+ the register window is displayed with \n\
+ the window that has current logical focus.\n");
+ if (xdb_commands)
+ {
+ add_com ("td", class_tui, _tuiToggleLayout_command,
+ "Toggle between Source/Command and Disassembly/Command layouts.\n");
+ add_com ("ts", class_tui, _tuiToggleSplitLayout_command,
+ "Toggle between Source/Command or Disassembly/Command and \n\
+Source/Disassembly/Command layouts.\n");
+ }
+}
+
+
+/*************************
+** STATIC LOCAL FUNCTIONS
+**************************/
+
+
+/*
+ ** _tuiSetLayoutTo()
+ ** Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA, REGS,
+ ** $REGS, $GREGS, $FREGS, $SREGS.
+ */
+TuiStatus
+tui_set_layout (const char *layoutName)
+{
+ TuiStatus status = TUI_SUCCESS;
+
+ if (layoutName != (char *) NULL)
+ {
+ register int i;
+ register char *bufPtr;
+ TuiLayoutType newLayout = UNDEFINED_LAYOUT;
+ TuiRegisterDisplayType dpyType = TUI_UNDEFINED_REGS;
+ TuiLayoutType curLayout = currentLayout ();
+
+ bufPtr = (char *) xstrdup (layoutName);
+ for (i = 0; (i < strlen (layoutName)); i++)
+ bufPtr[i] = toupper (bufPtr[i]);
+
+ /* First check for ambiguous input */
+ if (strlen (bufPtr) <= 1 && (*bufPtr == 'S' || *bufPtr == '$'))
+ {
+ warning ("Ambiguous command input.\n");
+ status = TUI_FAILURE;
+ }
+ else
+ {
+ if (subset_compare (bufPtr, "SRC"))
+ newLayout = SRC_COMMAND;
+ else if (subset_compare (bufPtr, "ASM"))
+ newLayout = DISASSEM_COMMAND;
+ else if (subset_compare (bufPtr, "SPLIT"))
+ newLayout = SRC_DISASSEM_COMMAND;
+ else if (subset_compare (bufPtr, "REGS") ||
+ subset_compare (bufPtr, TUI_GENERAL_SPECIAL_REGS_NAME) ||
+ subset_compare (bufPtr, TUI_GENERAL_REGS_NAME) ||
+ subset_compare (bufPtr, TUI_FLOAT_REGS_NAME) ||
+ subset_compare (bufPtr, TUI_SPECIAL_REGS_NAME))
+ {
+ if (curLayout == SRC_COMMAND || curLayout == SRC_DATA_COMMAND)
+ newLayout = SRC_DATA_COMMAND;
+ else
+ newLayout = DISASSEM_DATA_COMMAND;
+
+/* could ifdef out the following code. when compile with -z, there are null
+ pointer references that cause a core dump if 'layout regs' is the first
+ layout command issued by the user. HP has asked us to hook up this code
+ - edie epstein
+ */
+ if (subset_compare (bufPtr, TUI_FLOAT_REGS_NAME))
+ {
+ if (dataWin->detail.dataDisplayInfo.regsDisplayType !=
+ TUI_SFLOAT_REGS &&
+ dataWin->detail.dataDisplayInfo.regsDisplayType !=
+ TUI_DFLOAT_REGS)
+ dpyType = TUI_SFLOAT_REGS;
+ else
+ dpyType =
+ dataWin->detail.dataDisplayInfo.regsDisplayType;
+ }
+ else if (subset_compare (bufPtr,
+ TUI_GENERAL_SPECIAL_REGS_NAME))
+ dpyType = TUI_GENERAL_AND_SPECIAL_REGS;
+ else if (subset_compare (bufPtr, TUI_GENERAL_REGS_NAME))
+ dpyType = TUI_GENERAL_REGS;
+ else if (subset_compare (bufPtr, TUI_SPECIAL_REGS_NAME))
+ dpyType = TUI_SPECIAL_REGS;
+ else if (dataWin)
+ {
+ if (dataWin->detail.dataDisplayInfo.regsDisplayType !=
+ TUI_UNDEFINED_REGS)
+ dpyType =
+ dataWin->detail.dataDisplayInfo.regsDisplayType;
+ else
+ dpyType = TUI_GENERAL_REGS;
+ }
+
+/* end of potential ifdef
+ */
+
+/* if ifdefed out code above, then assume that the user wishes to display the
+ general purpose registers
+ */
+
+/* dpyType = TUI_GENERAL_REGS;
+ */
+ }
+ else if (subset_compare (bufPtr, "NEXT"))
+ newLayout = _nextLayout ();
+ else if (subset_compare (bufPtr, "PREV"))
+ newLayout = _prevLayout ();
+ else
+ status = TUI_FAILURE;
+ xfree (bufPtr);
+
+ tuiSetLayout (newLayout, dpyType);
+ }
+ }
+ else
+ status = TUI_FAILURE;
+
+ return status;
+}
+
+
+static CORE_ADDR
+_extractDisplayStartAddr (void)
+{
+ TuiLayoutType curLayout = currentLayout ();
+ CORE_ADDR addr;
+ CORE_ADDR pc;
+
+ switch (curLayout)
+ {
+ case SRC_COMMAND:
+ case SRC_DATA_COMMAND:
+ find_line_pc (current_source_symtab,
+ srcWin->detail.sourceInfo.startLineOrAddr.lineNo,
+ &pc);
+ addr = pc;
+ break;
+ case DISASSEM_COMMAND:
+ case SRC_DISASSEM_COMMAND:
+ case DISASSEM_DATA_COMMAND:
+ addr = disassemWin->detail.sourceInfo.startLineOrAddr.addr;
+ break;
+ default:
+ addr = 0;
+ break;
+ }
+
+ return addr;
+} /* _extractDisplayStartAddr */
+
+
+static void
+_tuiHandleXDBLayout (TuiLayoutDefPtr layoutDef)
+{
+ if (layoutDef->split)
+ {
+ tuiSetLayout (SRC_DISASSEM_COMMAND, TUI_UNDEFINED_REGS);
+ tuiSetWinFocusTo (winList[layoutDef->displayMode]);
+ }
+ else
+ {
+ if (layoutDef->displayMode == SRC_WIN)
+ tuiSetLayout (SRC_COMMAND, TUI_UNDEFINED_REGS);
+ else
+ tuiSetLayout (DISASSEM_DATA_COMMAND, layoutDef->regsDisplayType);
+ }
+
+
+ return;
+} /* _tuiHandleXDBLayout */
+
+
+static void
+_tuiToggleLayout_command (char *arg, int fromTTY)
+{
+ TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
+
+ /* Make sure the curses mode is enabled. */
+ tui_enable ();
+ if (layoutDef->displayMode == SRC_WIN)
+ layoutDef->displayMode = DISASSEM_WIN;
+ else
+ layoutDef->displayMode = SRC_WIN;
+
+ if (!layoutDef->split)
+ _tuiHandleXDBLayout (layoutDef);
+
+}
+
+
+static void
+_tuiToggleSplitLayout_command (char *arg, int fromTTY)
+{
+ TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
+
+ /* Make sure the curses mode is enabled. */
+ tui_enable ();
+ layoutDef->split = (!layoutDef->split);
+ _tuiHandleXDBLayout (layoutDef);
+
+}
+
+
+static void
+_tuiLayout_command (char *arg, int fromTTY)
+{
+ /* Make sure the curses mode is enabled. */
+ tui_enable ();
+
+ /* Switch to the selected layout. */
+ if (tui_set_layout (arg) != TUI_SUCCESS)
+ warning ("Invalid layout specified.\n%s", LAYOUT_USAGE);
+
+}
+
+/*
+ ** _nextLayout().
+ ** Answer the previous layout to cycle to.
+ */
+static TuiLayoutType
+_nextLayout (void)
+{
+ TuiLayoutType newLayout;
+
+ newLayout = currentLayout ();
+ if (newLayout == UNDEFINED_LAYOUT)
+ newLayout = SRC_COMMAND;
+ else
+ {
+ newLayout++;
+ if (newLayout == UNDEFINED_LAYOUT)
+ newLayout = SRC_COMMAND;
+ }
+
+ return newLayout;
+} /* _nextLayout */
+
+
+/*
+ ** _prevLayout().
+ ** Answer the next layout to cycle to.
+ */
+static TuiLayoutType
+_prevLayout (void)
+{
+ TuiLayoutType newLayout;
+
+ newLayout = currentLayout ();
+ if (newLayout == SRC_COMMAND)
+ newLayout = DISASSEM_DATA_COMMAND;
+ else
+ {
+ newLayout--;
+ if (newLayout == UNDEFINED_LAYOUT)
+ newLayout = DISASSEM_DATA_COMMAND;
+ }
+
+ return newLayout;
+} /* _prevLayout */
+
+
+
+/*
+ ** _makeCommandWindow().
+ */
+static void
+_makeCommandWindow (TuiWinInfoPtr * winInfoPtr, int height, int originY)
+{
+ _initAndMakeWin ((Opaque *) winInfoPtr,
+ CMD_WIN,
+ height,
+ termWidth (),
+ 0,
+ originY,
+ DONT_BOX_WINDOW);
+
+ (*winInfoPtr)->canHighlight = FALSE;
+
+ return;
+} /* _makeCommandWindow */
+
+
+/*
+ ** _makeSourceWindow().
+ */
+static void
+_makeSourceWindow (TuiWinInfoPtr * winInfoPtr, int height, int originY)
+{
+ _makeSourceOrDisassemWindow (winInfoPtr, SRC_WIN, height, originY);
+
+ return;
+} /* _makeSourceWindow */
+
+
+/*
+ ** _makeDisassemWindow().
+ */
+static void
+_makeDisassemWindow (TuiWinInfoPtr * winInfoPtr, int height, int originY)
+{
+ _makeSourceOrDisassemWindow (winInfoPtr, DISASSEM_WIN, height, originY);
+
+ return;
+} /* _makeDisassemWindow */
+
+
+/*
+ ** _makeDataWindow().
+ */
+static void
+_makeDataWindow (TuiWinInfoPtr * winInfoPtr, int height, int originY)
+{
+ _initAndMakeWin ((Opaque *) winInfoPtr,
+ DATA_WIN,
+ height,
+ termWidth (),
+ 0,
+ originY,
+ BOX_WINDOW);
+
+ return;
+} /* _makeDataWindow */
+
+
+
+/*
+ ** _showSourceCommand().
+ ** Show the Source/Command layout
+ */
+static void
+_showSourceCommand (void)
+{
+ _showSourceOrDisassemAndCommand (SRC_COMMAND);
+
+ return;
+} /* _showSourceCommand */
+
+
+/*
+ ** _showDisassemCommand().
+ ** Show the Dissassem/Command layout
+ */
+static void
+_showDisassemCommand (void)
+{
+ _showSourceOrDisassemAndCommand (DISASSEM_COMMAND);
+
+ return;
+} /* _showDisassemCommand */
+
+
+/*
+ ** _showSourceDisassemCommand().
+ ** Show the Source/Disassem/Command layout
+ */
+static void
+_showSourceDisassemCommand (void)
+{
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+ if (currentLayout () != SRC_DISASSEM_COMMAND)
+ {
+ int cmdHeight, srcHeight, asmHeight;
+
+ if (m_winPtrNotNull (cmdWin))
+ cmdHeight = cmdWin->generic.height;
+ else
+ cmdHeight = termHeight () / 3;
+
+ srcHeight = (termHeight () - cmdHeight) / 2;
+ asmHeight = termHeight () - (srcHeight + cmdHeight);
+
+ if (m_winPtrIsNull (srcWin))
+ _makeSourceWindow (&srcWin, srcHeight, 0);
+ else
+ {
+ _initGenWinInfo (&srcWin->generic,
+ srcWin->generic.type,
+ srcHeight,
+ srcWin->generic.width,
+ srcWin->detail.sourceInfo.executionInfo->width,
+ 0);
+ srcWin->canHighlight = TRUE;
+ _initGenWinInfo (srcWin->detail.sourceInfo.executionInfo,
+ EXEC_INFO_WIN,
+ srcHeight,
+ 3,
+ 0,
+ 0);
+ m_beVisible (srcWin);
+ m_beVisible (srcWin->detail.sourceInfo.executionInfo);
+ srcWin->detail.sourceInfo.hasLocator = FALSE;;
+ }
+ if (m_winPtrNotNull (srcWin))
+ {
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+ tuiShowSourceContent (srcWin);
+ if (m_winPtrIsNull (disassemWin))
+ {
+ _makeDisassemWindow (&disassemWin, asmHeight, srcHeight - 1);
+ _initAndMakeWin ((Opaque *) & locator,
+ LOCATOR_WIN,
+ 2 /* 1 */ ,
+ termWidth (),
+ 0,
+ (srcHeight + asmHeight) - 1,
+ DONT_BOX_WINDOW);
+ }
+ else
+ {
+ _initGenWinInfo (locator,
+ LOCATOR_WIN,
+ 2 /* 1 */ ,
+ termWidth (),
+ 0,
+ (srcHeight + asmHeight) - 1);
+ disassemWin->detail.sourceInfo.hasLocator = TRUE;
+ _initGenWinInfo (
+ &disassemWin->generic,
+ disassemWin->generic.type,
+ asmHeight,
+ disassemWin->generic.width,
+ disassemWin->detail.sourceInfo.executionInfo->width,
+ srcHeight - 1);
+ _initGenWinInfo (disassemWin->detail.sourceInfo.executionInfo,
+ EXEC_INFO_WIN,
+ asmHeight,
+ 3,
+ 0,
+ srcHeight - 1);
+ disassemWin->canHighlight = TRUE;
+ m_beVisible (disassemWin);
+ m_beVisible (disassemWin->detail.sourceInfo.executionInfo);
+ }
+ if (m_winPtrNotNull (disassemWin))
+ {
+ srcWin->detail.sourceInfo.hasLocator = FALSE;
+ disassemWin->detail.sourceInfo.hasLocator = TRUE;
+ m_beVisible (locator);
+ tuiShowLocatorContent ();
+ tuiShowSourceContent (disassemWin);
+
+ if (m_winPtrIsNull (cmdWin))
+ _makeCommandWindow (&cmdWin,
+ cmdHeight,
+ termHeight () - cmdHeight);
+ else
+ {
+ _initGenWinInfo (&cmdWin->generic,
+ cmdWin->generic.type,
+ cmdWin->generic.height,
+ cmdWin->generic.width,
+ 0,
+ cmdWin->generic.origin.y);
+ cmdWin->canHighlight = FALSE;
+ m_beVisible (cmdWin);
+ }
+ if (m_winPtrNotNull (cmdWin))
+ tuiRefreshWin (&cmdWin->generic);
+ }
+ }
+ setCurrentLayoutTo (SRC_DISASSEM_COMMAND);
+ }
+
+ return;
+} /* _showSourceDisassemCommand */
+
+
+/*
+ ** _showData().
+ ** Show the Source/Data/Command or the Dissassembly/Data/Command layout
+ */
+static void
+_showData (TuiLayoutType newLayout)
+{
+ int totalHeight = (termHeight () - cmdWin->generic.height);
+ int srcHeight, dataHeight;
+ TuiWinType winType;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+
+ dataHeight = totalHeight / 2;
+ srcHeight = totalHeight - dataHeight;
+ m_allBeInvisible ();
+ m_beInvisible (locator);
+ _makeDataWindow (&dataWin, dataHeight, 0);
+ dataWin->canHighlight = TRUE;
+ if (newLayout == SRC_DATA_COMMAND)
+ winType = SRC_WIN;
+ else
+ winType = DISASSEM_WIN;
+ if (m_winPtrIsNull (winList[winType]))
+ {
+ if (winType == SRC_WIN)
+ _makeSourceWindow (&winList[winType], srcHeight, dataHeight - 1);
+ else
+ _makeDisassemWindow (&winList[winType], srcHeight, dataHeight - 1);
+ _initAndMakeWin ((Opaque *) & locator,
+ LOCATOR_WIN,
+ 2 /* 1 */ ,
+ termWidth (),
+ 0,
+ totalHeight - 1,
+ DONT_BOX_WINDOW);
+ }
+ else
+ {
+ _initGenWinInfo (&winList[winType]->generic,
+ winList[winType]->generic.type,
+ srcHeight,
+ winList[winType]->generic.width,
+ winList[winType]->detail.sourceInfo.executionInfo->width,
+ dataHeight - 1);
+ _initGenWinInfo (winList[winType]->detail.sourceInfo.executionInfo,
+ EXEC_INFO_WIN,
+ srcHeight,
+ 3,
+ 0,
+ dataHeight - 1);
+ m_beVisible (winList[winType]);
+ m_beVisible (winList[winType]->detail.sourceInfo.executionInfo);
+ _initGenWinInfo (locator,
+ LOCATOR_WIN,
+ 2 /* 1 */ ,
+ termWidth (),
+ 0,
+ totalHeight - 1);
+ }
+ winList[winType]->detail.sourceInfo.hasLocator = TRUE;
+ m_beVisible (locator);
+ tuiShowLocatorContent ();
+ addToSourceWindows (winList[winType]);
+ setCurrentLayoutTo (newLayout);
+
+ return;
+} /* _showData */
+
+/*
+ ** _initGenWinInfo().
+ */
+static void
+_initGenWinInfo (TuiGenWinInfoPtr winInfo, TuiWinType type,
+ int height, int width, int originX, int originY)
+{
+ int h = height;
+
+ winInfo->type = type;
+ winInfo->width = width;
+ winInfo->height = h;
+ if (h > 1)
+ {
+ winInfo->viewportHeight = h - 1;
+ if (winInfo->type != CMD_WIN)
+ winInfo->viewportHeight--;
+ }
+ else
+ winInfo->viewportHeight = 1;
+ winInfo->origin.x = originX;
+ winInfo->origin.y = originY;
+
+ return;
+} /* _initGenWinInfo */
+
+/*
+ ** _initAndMakeWin().
+ */
+static void
+_initAndMakeWin (Opaque * winInfoPtr, TuiWinType winType,
+ int height, int width, int originX, int originY, int boxIt)
+{
+ Opaque opaqueWinInfo = *winInfoPtr;
+ TuiGenWinInfoPtr generic;
+
+ if (opaqueWinInfo == (Opaque) NULL)
+ {
+ if (m_winIsAuxillary (winType))
+ opaqueWinInfo = (Opaque) allocGenericWinInfo ();
+ else
+ opaqueWinInfo = (Opaque) allocWinInfo (winType);
+ }
+ if (m_winIsAuxillary (winType))
+ generic = (TuiGenWinInfoPtr) opaqueWinInfo;
+ else
+ generic = &((TuiWinInfoPtr) opaqueWinInfo)->generic;
+
+ if (opaqueWinInfo != (Opaque) NULL)
+ {
+ _initGenWinInfo (generic, winType, height, width, originX, originY);
+ if (!m_winIsAuxillary (winType))
+ {
+ if (generic->type == CMD_WIN)
+ ((TuiWinInfoPtr) opaqueWinInfo)->canHighlight = FALSE;
+ else
+ ((TuiWinInfoPtr) opaqueWinInfo)->canHighlight = TRUE;
+ }
+ makeWindow (generic, boxIt);
+ if (winType == LOCATOR_WIN)
+ tuiClearLocatorDisplay ();
+ }
+ *winInfoPtr = opaqueWinInfo;
+
+ return;
+} /* _initAndMakeWin */
+
+
+/*
+ ** _makeSourceOrDisassemWindow().
+ */
+static void
+_makeSourceOrDisassemWindow (TuiWinInfoPtr * winInfoPtr, TuiWinType type,
+ int height, int originY)
+{
+ TuiGenWinInfoPtr executionInfo = (TuiGenWinInfoPtr) NULL;
+
+ /*
+ ** Create the exeuction info window.
+ */
+ if (type == SRC_WIN)
+ executionInfo = sourceExecInfoWinPtr ();
+ else
+ executionInfo = disassemExecInfoWinPtr ();
+ _initAndMakeWin ((Opaque *) & executionInfo,
+ EXEC_INFO_WIN,
+ height,
+ 3,
+ 0,
+ originY,
+ DONT_BOX_WINDOW);
+ /*
+ ** Now create the source window.
+ */
+ _initAndMakeWin ((Opaque *) winInfoPtr,
+ type,
+ height,
+ termWidth () - executionInfo->width,
+ executionInfo->width,
+ originY,
+ BOX_WINDOW);
+
+ (*winInfoPtr)->detail.sourceInfo.executionInfo = executionInfo;
+
+ return;
+} /* _makeSourceOrDisassemWindow */
+
+
+/*
+ ** _showSourceOrDisassemAndCommand().
+ ** Show the Source/Command or the Disassem layout
+ */
+static void
+_showSourceOrDisassemAndCommand (TuiLayoutType layoutType)
+{
+ if (currentLayout () != layoutType)
+ {
+ TuiWinInfoPtr *winInfoPtr;
+ int areaLeft;
+ int srcHeight, cmdHeight;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+ if (m_winPtrNotNull (cmdWin))
+ cmdHeight = cmdWin->generic.height;
+ else
+ cmdHeight = termHeight () / 3;
+ srcHeight = termHeight () - cmdHeight;
+
+
+ if (layoutType == SRC_COMMAND)
+ winInfoPtr = &srcWin;
+ else
+ winInfoPtr = &disassemWin;
+
+ if (m_winPtrIsNull (*winInfoPtr))
+ {
+ if (layoutType == SRC_COMMAND)
+ _makeSourceWindow (winInfoPtr, srcHeight - 1, 0);
+ else
+ _makeDisassemWindow (winInfoPtr, srcHeight - 1, 0);
+ _initAndMakeWin ((Opaque *) & locator,
+ LOCATOR_WIN,
+ 2 /* 1 */ ,
+ termWidth (),
+ 0,
+ srcHeight - 1,
+ DONT_BOX_WINDOW);
+ }
+ else
+ {
+ _initGenWinInfo (locator,
+ LOCATOR_WIN,
+ 2 /* 1 */ ,
+ termWidth (),
+ 0,
+ srcHeight - 1);
+ (*winInfoPtr)->detail.sourceInfo.hasLocator = TRUE;
+ _initGenWinInfo (
+ &(*winInfoPtr)->generic,
+ (*winInfoPtr)->generic.type,
+ srcHeight - 1,
+ (*winInfoPtr)->generic.width,
+ (*winInfoPtr)->detail.sourceInfo.executionInfo->width,
+ 0);
+ _initGenWinInfo ((*winInfoPtr)->detail.sourceInfo.executionInfo,
+ EXEC_INFO_WIN,
+ srcHeight - 1,
+ 3,
+ 0,
+ 0);
+ (*winInfoPtr)->canHighlight = TRUE;
+ m_beVisible (*winInfoPtr);
+ m_beVisible ((*winInfoPtr)->detail.sourceInfo.executionInfo);
+ }
+ if (m_winPtrNotNull (*winInfoPtr))
+ {
+ (*winInfoPtr)->detail.sourceInfo.hasLocator = TRUE;
+ m_beVisible (locator);
+ tuiShowLocatorContent ();
+ tuiShowSourceContent (*winInfoPtr);
+
+ if (m_winPtrIsNull (cmdWin))
+ {
+ _makeCommandWindow (&cmdWin, cmdHeight, srcHeight);
+ tuiRefreshWin (&cmdWin->generic);
+ }
+ else
+ {
+ _initGenWinInfo (&cmdWin->generic,
+ cmdWin->generic.type,
+ cmdWin->generic.height,
+ cmdWin->generic.width,
+ cmdWin->generic.origin.x,
+ cmdWin->generic.origin.y);
+ cmdWin->canHighlight = FALSE;
+ m_beVisible (cmdWin);
+ }
+ }
+ setCurrentLayoutTo (layoutType);
+ }
+
+ return;
+} /* _showSourceOrDisassemAndCommand */
diff --git a/gdb/tui/tuiLayout.h b/gdb/tui/tuiLayout.h
new file mode 100644
index 00000000000..8646318f1da
--- /dev/null
+++ b/gdb/tui/tuiLayout.h
@@ -0,0 +1,31 @@
+/* TUI layout window management.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef TUI_LAYOUT_H
+#define TUI_LAYOUT_H
+
+extern void showLayout (TuiLayoutType);
+extern void tuiAddWinToLayout (TuiWinType);
+extern int tuiDefaultWinHeight (TuiWinType, TuiLayoutType);
+extern int tuiDefaultWinViewportHeight (TuiWinType, TuiLayoutType);
+extern TuiStatus tuiSetLayout (TuiLayoutType, TuiRegisterDisplayType);
+
+#endif /*TUI_LAYOUT_H */
diff --git a/gdb/tui/tuiRegs.c b/gdb/tui/tuiRegs.c
new file mode 100644
index 00000000000..d76c67ea8be
--- /dev/null
+++ b/gdb/tui/tuiRegs.c
@@ -0,0 +1,1074 @@
+/* TUI display registers in window.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+ Inc.
+
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include "defs.h"
+#include "tui.h"
+#include "tuiData.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "gdbcmd.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "tuiLayout.h"
+#include "tuiWin.h"
+#include "tuiDataWin.h"
+#include "tuiGeneralWin.h"
+#include "tui-file.h"
+
+/*****************************************
+** LOCAL DEFINITIONS **
+******************************************/
+#define DOUBLE_FLOAT_LABEL_WIDTH 6
+#define DOUBLE_FLOAT_LABEL_FMT "%6.6s: "
+#define DOUBLE_FLOAT_VALUE_WIDTH 30 /*min of 16 but may be in sci notation */
+
+#define SINGLE_FLOAT_LABEL_WIDTH 6
+#define SINGLE_FLOAT_LABEL_FMT "%6.6s: "
+#define SINGLE_FLOAT_VALUE_WIDTH 25 /* min of 8 but may be in sci notation */
+
+#define SINGLE_LABEL_WIDTH 16
+#define SINGLE_LABEL_FMT "%10.10s: "
+#define SINGLE_VALUE_WIDTH 20 /* minimum of 8 but may be in sci notation */
+
+/* In the code HP gave Cygnus, this was actually a function call to a
+ PA-specific function, which was supposed to determine whether the
+ target was a 64-bit or 32-bit processor. However, the 64-bit
+ support wasn't complete, so we didn't merge that in, so we leave
+ this here as a stub. */
+#define IS_64BIT 0
+
+/*****************************************
+** STATIC DATA **
+******************************************/
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS FORWARD DECLS **
+******************************************/
+static TuiStatus _tuiSetRegsContent
+ (int, int, struct frame_info *, TuiRegisterDisplayType, int);
+static char *_tuiRegisterName (int);
+static TuiStatus _tuiGetRegisterRawValue (int, char *, struct frame_info *);
+static void _tuiSetRegisterElement
+ (int, struct frame_info *, TuiDataElementPtr, int);
+static void _tuiDisplayRegister (int, TuiGenWinInfoPtr, enum precision_type);
+static void _tuiRegisterFormat
+ (char *, int, int, TuiDataElementPtr, enum precision_type);
+static TuiStatus _tuiSetGeneralRegsContent (int);
+static TuiStatus _tuiSetSpecialRegsContent (int);
+static TuiStatus _tuiSetGeneralAndSpecialRegsContent (int);
+static TuiStatus _tuiSetFloatRegsContent (TuiRegisterDisplayType, int);
+static int _tuiRegValueHasChanged
+ (TuiDataElementPtr, struct frame_info *, char *);
+static void _tuiShowFloat_command (char *, int);
+static void _tuiShowGeneral_command (char *, int);
+static void _tuiShowSpecial_command (char *, int);
+static void _tui_vShowRegisters_commandSupport (TuiRegisterDisplayType);
+static void _tuiToggleFloatRegs_command (char *, int);
+static void _tuiScrollRegsForward_command (char *, int);
+static void _tuiScrollRegsBackward_command (char *, int);
+
+
+
+/*****************************************
+** PUBLIC FUNCTIONS **
+******************************************/
+
+/*
+ ** tuiLastRegsLineNo()
+ ** Answer the number of the last line in the regs display.
+ ** If there are no registers (-1) is returned.
+ */
+int
+tuiLastRegsLineNo (void)
+{
+ register int numLines = (-1);
+
+ if (dataWin->detail.dataDisplayInfo.regsContentCount > 0)
+ {
+ numLines = (dataWin->detail.dataDisplayInfo.regsContentCount /
+ dataWin->detail.dataDisplayInfo.regsColumnCount);
+ if (dataWin->detail.dataDisplayInfo.regsContentCount %
+ dataWin->detail.dataDisplayInfo.regsColumnCount)
+ numLines++;
+ }
+ return numLines;
+} /* tuiLastRegsLineNo */
+
+
+/*
+ ** tuiLineFromRegElementNo()
+ ** Answer the line number that the register element at elementNo is
+ ** on. If elementNo is greater than the number of register elements
+ ** there are, -1 is returned.
+ */
+int
+tuiLineFromRegElementNo (int elementNo)
+{
+ if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
+ {
+ int i, line = (-1);
+
+ i = 1;
+ while (line == (-1))
+ {
+ if (elementNo <
+ (dataWin->detail.dataDisplayInfo.regsColumnCount * i))
+ line = i - 1;
+ else
+ i++;
+ }
+
+ return line;
+ }
+ else
+ return (-1);
+} /* tuiLineFromRegElementNo */
+
+
+/*
+ ** tuiFirstRegElementNoInLine()
+ ** Answer the index of the first element in lineNo. If lineNo is
+ ** past the register area (-1) is returned.
+ */
+int
+tuiFirstRegElementNoInLine (int lineNo)
+{
+ if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount)
+ <= dataWin->detail.dataDisplayInfo.regsContentCount)
+ return ((lineNo + 1) *
+ dataWin->detail.dataDisplayInfo.regsColumnCount) -
+ dataWin->detail.dataDisplayInfo.regsColumnCount;
+ else
+ return (-1);
+} /* tuiFirstRegElementNoInLine */
+
+
+/*
+ ** tuiLastRegElementNoInLine()
+ ** Answer the index of the last element in lineNo. If lineNo is past
+ ** the register area (-1) is returned.
+ */
+int
+tuiLastRegElementNoInLine (int lineNo)
+{
+ if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount) <=
+ dataWin->detail.dataDisplayInfo.regsContentCount)
+ return ((lineNo + 1) *
+ dataWin->detail.dataDisplayInfo.regsColumnCount) - 1;
+ else
+ return (-1);
+} /* tuiLastRegElementNoInLine */
+
+
+/*
+ ** tuiCalculateRegsColumnCount
+ ** Calculate the number of columns that should be used to display
+ ** the registers.
+ */
+int
+tuiCalculateRegsColumnCount (TuiRegisterDisplayType dpyType)
+{
+ int colCount, colWidth;
+
+ if (IS_64BIT || dpyType == TUI_DFLOAT_REGS)
+ colWidth = DOUBLE_FLOAT_VALUE_WIDTH + DOUBLE_FLOAT_LABEL_WIDTH;
+ else
+ {
+ if (dpyType == TUI_SFLOAT_REGS)
+ colWidth = SINGLE_FLOAT_VALUE_WIDTH + SINGLE_FLOAT_LABEL_WIDTH;
+ else
+ colWidth = SINGLE_VALUE_WIDTH + SINGLE_LABEL_WIDTH;
+ }
+ colCount = (dataWin->generic.width - 2) / colWidth;
+
+ return colCount;
+} /* tuiCalulateRegsColumnCount */
+
+
+/*
+ ** tuiShowRegisters().
+ ** Show the registers int the data window as indicated by dpyType.
+ ** If there is any other registers being displayed, then they are
+ ** cleared. What registers are displayed is dependent upon dpyType.
+ */
+void
+tuiShowRegisters (TuiRegisterDisplayType dpyType)
+{
+ TuiStatus ret = TUI_FAILURE;
+ int refreshValuesOnly = FALSE;
+
+ /* Say that registers should be displayed, even if there is a problem */
+ dataWin->detail.dataDisplayInfo.displayRegs = TRUE;
+
+ if (target_has_registers)
+ {
+ refreshValuesOnly =
+ (dpyType == dataWin->detail.dataDisplayInfo.regsDisplayType);
+ switch (dpyType)
+ {
+ case TUI_GENERAL_REGS:
+ ret = _tuiSetGeneralRegsContent (refreshValuesOnly);
+ break;
+ case TUI_SFLOAT_REGS:
+ case TUI_DFLOAT_REGS:
+ ret = _tuiSetFloatRegsContent (dpyType, refreshValuesOnly);
+ break;
+
+/* could ifdef out */
+
+ case TUI_SPECIAL_REGS:
+ ret = _tuiSetSpecialRegsContent (refreshValuesOnly);
+ break;
+ case TUI_GENERAL_AND_SPECIAL_REGS:
+ ret = _tuiSetGeneralAndSpecialRegsContent (refreshValuesOnly);
+ break;
+
+/* end of potential if def */
+
+ default:
+ break;
+ }
+ }
+ if (ret == TUI_FAILURE)
+ {
+ dataWin->detail.dataDisplayInfo.regsDisplayType = TUI_UNDEFINED_REGS;
+ tuiEraseDataContent (NO_REGS_STRING);
+ }
+ else
+ {
+ int i;
+
+ /* Clear all notation of changed values */
+ for (i = 0; (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++)
+ {
+ TuiGenWinInfoPtr dataItemWin;
+
+ dataItemWin = &dataWin->detail.dataDisplayInfo.
+ regsContent[i]->whichElement.dataWindow;
+ (&((TuiWinElementPtr)
+ dataItemWin->content[0])->whichElement.data)->highlight = FALSE;
+ }
+ dataWin->detail.dataDisplayInfo.regsDisplayType = dpyType;
+ tuiDisplayAllData ();
+ }
+ (tuiLayoutDef ())->regsDisplayType = dpyType;
+
+ return;
+} /* tuiShowRegisters */
+
+
+/*
+ ** tuiDisplayRegistersFrom().
+ ** Function to display the registers in the content from
+ ** 'startElementNo' until the end of the register content or the
+ ** end of the display height. No checking for displaying past
+ ** the end of the registers is done here.
+ */
+void
+tuiDisplayRegistersFrom (int startElementNo)
+{
+ if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL &&
+ dataWin->detail.dataDisplayInfo.regsContentCount > 0)
+ {
+ register int i = startElementNo;
+ int j, valueCharsWide, charsWide, itemWinWidth, curY, labelWidth;
+ enum precision_type precision;
+
+ precision = (dataWin->detail.dataDisplayInfo.regsDisplayType
+ == TUI_DFLOAT_REGS) ?
+ double_precision : unspecified_precision;
+ if (IS_64BIT ||
+ dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)
+ {
+ valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH;
+ labelWidth = DOUBLE_FLOAT_LABEL_WIDTH;
+ }
+ else
+ {
+ if (dataWin->detail.dataDisplayInfo.regsDisplayType ==
+ TUI_SFLOAT_REGS)
+ {
+ valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH;
+ labelWidth = SINGLE_FLOAT_LABEL_WIDTH;
+ }
+ else
+ {
+ valueCharsWide = SINGLE_VALUE_WIDTH;
+ labelWidth = SINGLE_LABEL_WIDTH;
+ }
+ }
+ itemWinWidth = valueCharsWide + labelWidth;
+ /*
+ ** Now create each data "sub" window, and write the display into it.
+ */
+ curY = 1;
+ while (i < dataWin->detail.dataDisplayInfo.regsContentCount &&
+ curY <= dataWin->generic.viewportHeight)
+ {
+ for (j = 0;
+ (j < dataWin->detail.dataDisplayInfo.regsColumnCount &&
+ i < dataWin->detail.dataDisplayInfo.regsContentCount); j++)
+ {
+ TuiGenWinInfoPtr dataItemWin;
+ TuiDataElementPtr dataElementPtr;
+
+ /* create the window if necessary */
+ dataItemWin = &dataWin->detail.dataDisplayInfo.
+ regsContent[i]->whichElement.dataWindow;
+ dataElementPtr = &((TuiWinElementPtr)
+ dataItemWin->content[0])->whichElement.data;
+ if (dataItemWin->handle == (WINDOW *) NULL)
+ {
+ dataItemWin->height = 1;
+ dataItemWin->width = (precision == double_precision) ?
+ itemWinWidth + 2 : itemWinWidth + 1;
+ dataItemWin->origin.x = (itemWinWidth * j) + 1;
+ dataItemWin->origin.y = curY;
+ makeWindow (dataItemWin, DONT_BOX_WINDOW);
+ scrollok (dataItemWin->handle, FALSE);
+ }
+ touchwin (dataItemWin->handle);
+
+ /*
+ ** Get the printable representation of the register
+ ** and display it
+ */
+ _tuiDisplayRegister (
+ dataElementPtr->itemNo, dataItemWin, precision);
+ i++; /* next register */
+ }
+ curY++; /* next row; */
+ }
+ }
+
+ return;
+} /* tuiDisplayRegistersFrom */
+
+
+/*
+ ** tuiDisplayRegElementAtLine().
+ ** Function to display the registers in the content from
+ ** 'startElementNo' on 'startLineNo' until the end of the
+ ** register content or the end of the display height.
+ ** This function checks that we won't display off the end
+ ** of the register display.
+ */
+void
+tuiDisplayRegElementAtLine (int startElementNo, int startLineNo)
+{
+ if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL &&
+ dataWin->detail.dataDisplayInfo.regsContentCount > 0)
+ {
+ register int elementNo = startElementNo;
+
+ if (startElementNo != 0 && startLineNo != 0)
+ {
+ register int lastLineNo, firstLineOnLastPage;
+
+ lastLineNo = tuiLastRegsLineNo ();
+ firstLineOnLastPage = lastLineNo - (dataWin->generic.height - 2);
+ if (firstLineOnLastPage < 0)
+ firstLineOnLastPage = 0;
+ /*
+ ** If there is no other data displayed except registers,
+ ** and the elementNo causes us to scroll past the end of the
+ ** registers, adjust what element to really start the display at.
+ */
+ if (dataWin->detail.dataDisplayInfo.dataContentCount <= 0 &&
+ startLineNo > firstLineOnLastPage)
+ elementNo = tuiFirstRegElementNoInLine (firstLineOnLastPage);
+ }
+ tuiDisplayRegistersFrom (elementNo);
+ }
+
+ return;
+} /* tuiDisplayRegElementAtLine */
+
+
+
+/*
+ ** tuiDisplayRegistersFromLine().
+ ** Function to display the registers starting at line lineNo in
+ ** the data window. Answers the line number that the display
+ ** actually started from. If nothing is displayed (-1) is returned.
+ */
+int
+tuiDisplayRegistersFromLine (int lineNo, int forceDisplay)
+{
+ int elementNo;
+
+ if (dataWin->detail.dataDisplayInfo.regsContentCount > 0)
+ {
+ int line, elementNo;
+
+ if (lineNo < 0)
+ line = 0;
+ else if (forceDisplay)
+ { /*
+ ** If we must display regs (forceDisplay is true), then make
+ ** sure that we don't display off the end of the registers.
+ */
+ if (lineNo >= tuiLastRegsLineNo ())
+ {
+ if ((line = tuiLineFromRegElementNo (
+ dataWin->detail.dataDisplayInfo.regsContentCount - 1)) < 0)
+ line = 0;
+ }
+ else
+ line = lineNo;
+ }
+ else
+ line = lineNo;
+
+ elementNo = tuiFirstRegElementNoInLine (line);
+ if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
+ tuiDisplayRegElementAtLine (elementNo, line);
+ else
+ line = (-1);
+
+ return line;
+ }
+
+ return (-1); /* nothing was displayed */
+} /* tuiDisplayRegistersFromLine */
+
+
+/*
+ ** tuiCheckRegisterValues()
+ ** This function check all displayed registers for changes in
+ ** values, given a particular frame. If the values have changed,
+ ** they are updated with the new value and highlighted.
+ */
+void
+tuiCheckRegisterValues (struct frame_info *frame)
+{
+ if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
+ {
+ if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0 &&
+ dataWin->detail.dataDisplayInfo.displayRegs)
+ tuiShowRegisters ((tuiLayoutDef ())->regsDisplayType);
+ else
+ {
+ int i, j;
+ char rawBuf[MAX_REGISTER_RAW_SIZE];
+
+ for (i = 0;
+ (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++)
+ {
+ TuiDataElementPtr dataElementPtr;
+ TuiGenWinInfoPtr dataItemWinPtr;
+ int wasHilighted;
+
+ dataItemWinPtr = &dataWin->detail.dataDisplayInfo.
+ regsContent[i]->whichElement.dataWindow;
+ dataElementPtr = &((TuiWinElementPtr)
+ dataItemWinPtr->content[0])->whichElement.data;
+ wasHilighted = dataElementPtr->highlight;
+ dataElementPtr->highlight =
+ _tuiRegValueHasChanged (dataElementPtr, frame, &rawBuf[0]);
+ if (dataElementPtr->highlight)
+ {
+ int size;
+
+ size = REGISTER_RAW_SIZE (dataElementPtr->itemNo);
+ for (j = 0; j < size; j++)
+ ((char *) dataElementPtr->value)[j] = rawBuf[j];
+ _tuiDisplayRegister (
+ dataElementPtr->itemNo,
+ dataItemWinPtr,
+ ((dataWin->detail.dataDisplayInfo.regsDisplayType ==
+ TUI_DFLOAT_REGS) ?
+ double_precision : unspecified_precision));
+ }
+ else if (wasHilighted)
+ {
+ dataElementPtr->highlight = FALSE;
+ _tuiDisplayRegister (
+ dataElementPtr->itemNo,
+ dataItemWinPtr,
+ ((dataWin->detail.dataDisplayInfo.regsDisplayType ==
+ TUI_DFLOAT_REGS) ?
+ double_precision : unspecified_precision));
+ }
+ }
+ }
+ }
+ return;
+} /* tuiCheckRegisterValues */
+
+
+/*
+ ** tuiToggleFloatRegs().
+ */
+void
+tuiToggleFloatRegs (void)
+{
+ TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
+
+ if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS)
+ layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS;
+ else
+ layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS;
+
+ if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible &&
+ (dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_SFLOAT_REGS ||
+ dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS))
+ tuiShowRegisters (layoutDef->floatRegsDisplayType);
+
+ return;
+} /* tuiToggleFloatRegs */
+
+
+void
+_initialize_tuiRegs (void)
+{
+ if (xdb_commands)
+ {
+ add_com ("fr", class_tui, _tuiShowFloat_command,
+ "Display only floating point registers\n");
+ add_com ("gr", class_tui, _tuiShowGeneral_command,
+ "Display only general registers\n");
+ add_com ("sr", class_tui, _tuiShowSpecial_command,
+ "Display only special registers\n");
+ add_com ("+r", class_tui, _tuiScrollRegsForward_command,
+ "Scroll the registers window forward\n");
+ add_com ("-r", class_tui, _tuiScrollRegsBackward_command,
+ "Scroll the register window backward\n");
+ add_com ("tf", class_tui, _tuiToggleFloatRegs_command,
+ "Toggle between single and double precision floating point registers.\n");
+ add_cmd (TUI_FLOAT_REGS_NAME_LOWER,
+ class_tui,
+ _tuiToggleFloatRegs_command,
+ "Toggle between single and double precision floating point \
+registers.\n",
+ &togglelist);
+ }
+}
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS **
+******************************************/
+
+
+/*
+ ** _tuiRegisterName().
+ ** Return the register name.
+ */
+static char *
+_tuiRegisterName (int regNum)
+{
+ return REGISTER_NAME (regNum);
+}
+extern int pagination_enabled;
+
+static void
+tui_restore_gdbout (void *ui)
+{
+ ui_file_delete (gdb_stdout);
+ gdb_stdout = (struct ui_file*) ui;
+ pagination_enabled = 1;
+}
+
+/*
+ ** _tuiRegisterFormat
+ ** Function to format the register name and value into a buffer,
+ ** suitable for printing or display
+ */
+static void
+_tuiRegisterFormat (char *buf, int bufLen, int regNum,
+ TuiDataElementPtr dataElement,
+ enum precision_type precision)
+{
+ struct ui_file *stream;
+ struct ui_file *old_stdout;
+ char *name;
+ struct cleanup *cleanups;
+ char *p;
+ int pos;
+
+ name = REGISTER_NAME (regNum);
+ if (name == 0)
+ {
+ strcpy (buf, "");
+ return;
+ }
+
+ pagination_enabled = 0;
+ old_stdout = gdb_stdout;
+ stream = tui_sfileopen (bufLen);
+ gdb_stdout = stream;
+ cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
+ do_registers_info (regNum, 0);
+
+ /* Save formatted output in the buffer. */
+ p = tui_file_get_strbuf (stream);
+ pos = 0;
+ while (*p && *p == *name++ && bufLen)
+ {
+ *buf++ = *p++;
+ bufLen--;
+ pos++;
+ }
+ while (*p == ' ')
+ p++;
+ while (pos < 8 && bufLen)
+ {
+ *buf++ = ' ';
+ bufLen--;
+ pos++;
+ }
+ strncpy (buf, p, bufLen);
+
+ /* Remove the possible \n. */
+ p = strchr (buf, '\n');
+ if (p)
+ *p = 0;
+
+ do_cleanups (cleanups);
+}
+
+
+#define NUM_GENERAL_REGS 32
+/*
+ ** _tuiSetGeneralRegsContent().
+ ** Set the content of the data window to consist of the general registers.
+ */
+static TuiStatus
+_tuiSetGeneralRegsContent (int refreshValuesOnly)
+{
+ return (_tuiSetRegsContent (0,
+ NUM_GENERAL_REGS - 1,
+ selected_frame,
+ TUI_GENERAL_REGS,
+ refreshValuesOnly));
+
+} /* _tuiSetGeneralRegsContent */
+
+
+#ifndef PCOQ_HEAD_REGNUM
+#define START_SPECIAL_REGS 0
+#else
+#define START_SPECIAL_REGS PCOQ_HEAD_REGNUM
+#endif
+
+/*
+ ** _tuiSetSpecialRegsContent().
+ ** Set the content of the data window to consist of the special registers.
+ */
+static TuiStatus
+_tuiSetSpecialRegsContent (int refreshValuesOnly)
+{
+ TuiStatus ret = TUI_FAILURE;
+ int i, endRegNum;
+
+ endRegNum = FP0_REGNUM - 1;
+#if 0
+ endRegNum = (-1);
+ for (i = START_SPECIAL_REGS; (i < NUM_REGS && endRegNum < 0); i++)
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
+ endRegNum = i - 1;
+#endif
+ ret = _tuiSetRegsContent (START_SPECIAL_REGS,
+ endRegNum,
+ selected_frame,
+ TUI_SPECIAL_REGS,
+ refreshValuesOnly);
+
+ return ret;
+} /* _tuiSetSpecialRegsContent */
+
+
+/*
+ ** _tuiSetGeneralAndSpecialRegsContent().
+ ** Set the content of the data window to consist of the special registers.
+ */
+static TuiStatus
+_tuiSetGeneralAndSpecialRegsContent (int refreshValuesOnly)
+{
+ TuiStatus ret = TUI_FAILURE;
+ int i, endRegNum = (-1);
+
+ endRegNum = FP0_REGNUM - 1;
+#if 0
+ endRegNum = (-1);
+ for (i = 0; (i < NUM_REGS && endRegNum < 0); i++)
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
+ endRegNum = i - 1;
+#endif
+ ret = _tuiSetRegsContent (
+ 0, endRegNum, selected_frame, TUI_SPECIAL_REGS, refreshValuesOnly);
+
+ return ret;
+} /* _tuiSetGeneralAndSpecialRegsContent */
+
+/*
+ ** _tuiSetFloatRegsContent().
+ ** Set the content of the data window to consist of the float registers.
+ */
+static TuiStatus
+_tuiSetFloatRegsContent (TuiRegisterDisplayType dpyType, int refreshValuesOnly)
+{
+ TuiStatus ret = TUI_FAILURE;
+ int i, startRegNum;
+
+ startRegNum = FP0_REGNUM;
+#if 0
+ startRegNum = (-1);
+ for (i = NUM_REGS - 1; (i >= 0 && startRegNum < 0); i--)
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) != TYPE_CODE_FLT)
+ startRegNum = i + 1;
+#endif
+ ret = _tuiSetRegsContent (startRegNum,
+ NUM_REGS - 1,
+ selected_frame,
+ dpyType,
+ refreshValuesOnly);
+
+ return ret;
+} /* _tuiSetFloatRegsContent */
+
+
+/*
+ ** _tuiRegValueHasChanged().
+ ** Answer TRUE if the register's value has changed, FALSE otherwise.
+ ** If TRUE, newValue is filled in with the new value.
+ */
+static int
+_tuiRegValueHasChanged (TuiDataElementPtr dataElement,
+ struct frame_info *frame,
+ char *newValue)
+{
+ int hasChanged = FALSE;
+
+ if (dataElement->itemNo != UNDEFINED_ITEM &&
+ _tuiRegisterName (dataElement->itemNo) != (char *) NULL)
+ {
+ char rawBuf[MAX_REGISTER_RAW_SIZE];
+ int i;
+
+ if (_tuiGetRegisterRawValue (
+ dataElement->itemNo, rawBuf, frame) == TUI_SUCCESS)
+ {
+ int size = REGISTER_RAW_SIZE (dataElement->itemNo);
+
+ for (i = 0; (i < size && !hasChanged); i++)
+ hasChanged = (((char *) dataElement->value)[i] != rawBuf[i]);
+ if (hasChanged && newValue != (char *) NULL)
+ {
+ for (i = 0; i < size; i++)
+ newValue[i] = rawBuf[i];
+ }
+ }
+ }
+ return hasChanged;
+} /* _tuiRegValueHasChanged */
+
+
+
+/*
+ ** _tuiGetRegisterRawValue().
+ ** Get the register raw value. The raw value is returned in regValue.
+ */
+static TuiStatus
+_tuiGetRegisterRawValue (int regNum, char *regValue, struct frame_info *frame)
+{
+ TuiStatus ret = TUI_FAILURE;
+
+ if (target_has_registers)
+ {
+ int opt;
+
+ get_saved_register (regValue, &opt, (CORE_ADDR*) NULL, frame,
+ regNum, (enum lval_type*) NULL);
+ if (register_cached (regNum) >= 0)
+ ret = TUI_SUCCESS;
+ }
+ return ret;
+} /* _tuiGetRegisterRawValue */
+
+
+
+/*
+ ** _tuiSetRegisterElement().
+ ** Function to initialize a data element with the input and
+ ** the register value.
+ */
+static void
+_tuiSetRegisterElement (int regNum, struct frame_info *frame,
+ TuiDataElementPtr dataElement,
+ int refreshValueOnly)
+{
+ if (dataElement != (TuiDataElementPtr) NULL)
+ {
+ if (!refreshValueOnly)
+ {
+ dataElement->itemNo = regNum;
+ dataElement->name = _tuiRegisterName (regNum);
+ dataElement->highlight = FALSE;
+ }
+ if (dataElement->value == (Opaque) NULL)
+ dataElement->value = (Opaque) xmalloc (MAX_REGISTER_RAW_SIZE);
+ if (dataElement->value != (Opaque) NULL)
+ _tuiGetRegisterRawValue (regNum, dataElement->value, frame);
+ }
+
+ return;
+} /* _tuiSetRegisterElement */
+
+
+/*
+ ** _tuiSetRegsContent().
+ ** Set the content of the data window to consist of the registers
+ ** numbered from startRegNum to endRegNum. Note that if
+ ** refreshValuesOnly is TRUE, startRegNum and endRegNum are ignored.
+ */
+static TuiStatus
+_tuiSetRegsContent (int startRegNum, int endRegNum,
+ struct frame_info *frame,
+ TuiRegisterDisplayType dpyType,
+ int refreshValuesOnly)
+{
+ TuiStatus ret = TUI_FAILURE;
+ int numRegs = endRegNum - startRegNum + 1;
+ int allocatedHere = FALSE;
+
+ if (dataWin->detail.dataDisplayInfo.regsContentCount > 0 &&
+ !refreshValuesOnly)
+ {
+ freeDataContent (dataWin->detail.dataDisplayInfo.regsContent,
+ dataWin->detail.dataDisplayInfo.regsContentCount);
+ dataWin->detail.dataDisplayInfo.regsContentCount = 0;
+ }
+ if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0)
+ {
+ dataWin->detail.dataDisplayInfo.regsContent =
+ allocContent (numRegs, DATA_WIN);
+ allocatedHere = TRUE;
+ }
+
+ if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL)
+ {
+ int i;
+
+ if (!refreshValuesOnly || allocatedHere)
+ {
+ dataWin->generic.content = (OpaquePtr) NULL;
+ dataWin->generic.contentSize = 0;
+ addContentElements (&dataWin->generic, numRegs);
+ dataWin->detail.dataDisplayInfo.regsContent =
+ (TuiWinContent) dataWin->generic.content;
+ dataWin->detail.dataDisplayInfo.regsContentCount = numRegs;
+ }
+ /*
+ ** Now set the register names and values
+ */
+ for (i = startRegNum; (i <= endRegNum); i++)
+ {
+ TuiGenWinInfoPtr dataItemWin;
+
+ dataItemWin = &dataWin->detail.dataDisplayInfo.
+ regsContent[i - startRegNum]->whichElement.dataWindow;
+ _tuiSetRegisterElement (
+ i,
+ frame,
+ &((TuiWinElementPtr) dataItemWin->content[0])->whichElement.data,
+ !allocatedHere && refreshValuesOnly);
+ }
+ dataWin->detail.dataDisplayInfo.regsColumnCount =
+ tuiCalculateRegsColumnCount (dpyType);
+#ifdef LATER
+ if (dataWin->detail.dataDisplayInfo.dataContentCount > 0)
+ {
+ /* delete all the windows? */
+ /* realloc content equal to dataContentCount + regsContentCount */
+ /* append dataWin->detail.dataDisplayInfo.dataContent to content */
+ }
+#endif
+ dataWin->generic.contentSize =
+ dataWin->detail.dataDisplayInfo.regsContentCount +
+ dataWin->detail.dataDisplayInfo.dataContentCount;
+ ret = TUI_SUCCESS;
+ }
+
+ return ret;
+} /* _tuiSetRegsContent */
+
+
+/*
+ ** _tuiDisplayRegister().
+ ** Function to display a register in a window. If hilite is TRUE,
+ ** than the value will be displayed in reverse video
+ */
+static void
+_tuiDisplayRegister (int regNum,
+ TuiGenWinInfoPtr winInfo, /* the data item window */
+ enum precision_type precision)
+{
+ if (winInfo->handle != (WINDOW *) NULL)
+ {
+ int i;
+ char buf[40];
+ int valueCharsWide, labelWidth;
+ TuiDataElementPtr dataElementPtr = &((TuiWinContent)
+ winInfo->content)[0]->whichElement.data;
+
+ if (IS_64BIT ||
+ dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)
+ {
+ valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH;
+ labelWidth = DOUBLE_FLOAT_LABEL_WIDTH;
+ }
+ else
+ {
+ if (dataWin->detail.dataDisplayInfo.regsDisplayType ==
+ TUI_SFLOAT_REGS)
+ {
+ valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH;
+ labelWidth = SINGLE_FLOAT_LABEL_WIDTH;
+ }
+ else
+ {
+ valueCharsWide = SINGLE_VALUE_WIDTH;
+ labelWidth = SINGLE_LABEL_WIDTH;
+ }
+ }
+
+ buf[0] = (char) 0;
+ _tuiRegisterFormat (buf,
+ valueCharsWide + labelWidth,
+ regNum,
+ dataElementPtr,
+ precision);
+
+ if (dataElementPtr->highlight)
+ wstandout (winInfo->handle);
+
+ wmove (winInfo->handle, 0, 0);
+ for (i = 1; i < winInfo->width; i++)
+ waddch (winInfo->handle, ' ');
+ wmove (winInfo->handle, 0, 0);
+ waddstr (winInfo->handle, buf);
+
+ if (dataElementPtr->highlight)
+ wstandend (winInfo->handle);
+ tuiRefreshWin (winInfo);
+ }
+ return;
+} /* _tuiDisplayRegister */
+
+
+static void
+_tui_vShowRegisters_commandSupport (TuiRegisterDisplayType dpyType)
+{
+
+ if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
+ { /* Data window already displayed, show the registers */
+ if (dataWin->detail.dataDisplayInfo.regsDisplayType != dpyType)
+ tuiShowRegisters (dpyType);
+ }
+ else
+ (tuiLayoutDef ())->regsDisplayType = dpyType;
+
+ return;
+} /* _tui_vShowRegisters_commandSupport */
+
+
+static void
+_tuiShowFloat_command (char *arg, int fromTTY)
+{
+ if (m_winPtrIsNull (dataWin) || !dataWin->generic.isVisible ||
+ (dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_SFLOAT_REGS &&
+ dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_DFLOAT_REGS))
+ _tui_vShowRegisters_commandSupport ((tuiLayoutDef ())->floatRegsDisplayType);
+
+ return;
+} /* _tuiShowFloat_command */
+
+
+static void
+_tuiShowGeneral_command (char *arg, int fromTTY)
+{
+ _tui_vShowRegisters_commandSupport (TUI_GENERAL_REGS);
+}
+
+
+static void
+_tuiShowSpecial_command (char *arg, int fromTTY)
+{
+ _tui_vShowRegisters_commandSupport (TUI_SPECIAL_REGS);
+}
+
+
+static void
+_tuiToggleFloatRegs_command (char *arg, int fromTTY)
+{
+ if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
+ tuiToggleFloatRegs ();
+ else
+ {
+ TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
+
+ if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS)
+ layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS;
+ else
+ layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS;
+ }
+
+
+ return;
+} /* _tuiToggleFloatRegs_command */
+
+
+static void
+_tuiScrollRegsForward_command (char *arg, int fromTTY)
+{
+ tui_scroll (FORWARD_SCROLL, dataWin, 1);
+}
+
+
+static void
+_tuiScrollRegsBackward_command (char *arg, int fromTTY)
+{
+ tui_scroll (BACKWARD_SCROLL, dataWin, 1);
+}
diff --git a/gdb/tui/tuiRegs.h b/gdb/tui/tuiRegs.h
new file mode 100644
index 00000000000..8fbfbbf471a
--- /dev/null
+++ b/gdb/tui/tuiRegs.h
@@ -0,0 +1,47 @@
+/* TUI display registers in window.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef _TUI_REGS_H
+#define _TUI_REGS_H
+
+/*****************************************
+** TYPE DEFINITIONS **
+******************************************/
+
+
+
+/*****************************************
+** PUBLIC FUNCTION EXTERNAL DECLS **
+******************************************/
+extern void tuiCheckRegisterValues (struct frame_info *);
+extern void tuiShowRegisters (TuiRegisterDisplayType);
+extern void tuiDisplayRegistersFrom (int);
+extern int tuiDisplayRegistersFromLine (int, int);
+extern int tuiLastRegsLineNo (void);
+extern int tuiFirstRegElementInLine (int);
+extern int tuiLastRegElementInLine (int);
+extern int tuiLineFromRegElementNo (int);
+extern void tuiToggleFloatRegs (void);
+extern int tuiCalculateRegsColumnCount (TuiRegisterDisplayType);
+extern int tuiFirstRegElementNoInLine (int lineno);
+
+#endif
+/*_TUI_REGS_H*/
diff --git a/gdb/tui/tuiSource.c b/gdb/tui/tuiSource.c
new file mode 100644
index 00000000000..1552ac79d0d
--- /dev/null
+++ b/gdb/tui/tuiSource.c
@@ -0,0 +1,448 @@
+/* TUI display source window.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+ Inc.
+
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include "defs.h"
+#include <ctype.h>
+#include "symtab.h"
+#include "frame.h"
+#include "breakpoint.h"
+#include "source.h"
+#include "symtab.h"
+
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiStack.h"
+#include "tuiSourceWin.h"
+#include "tuiSource.h"
+
+
+/*****************************************
+** EXTERNAL DATA DECLS **
+******************************************/
+extern int current_source_line;
+extern struct symtab *current_source_symtab;
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS FORWARD DECLS **
+******************************************/
+
+static struct breakpoint *_hasBreak (char *, int);
+
+
+/*****************************************
+** STATIC LOCAL DATA **
+******************************************/
+
+
+/*****************************************
+** PUBLIC FUNCTIONS **
+******************************************/
+
+/*********************************
+** SOURCE/DISASSEM FUNCTIONS **
+*********************************/
+
+/*
+ ** tuiSetSourceContent().
+ ** Function to display source in the source window.
+ */
+TuiStatus
+tuiSetSourceContent (struct symtab *s, int lineNo, int noerror)
+{
+ TuiStatus ret = TUI_FAILURE;
+
+ if (s != (struct symtab *) NULL && s->filename != (char *) NULL)
+ {
+ register FILE *stream;
+ register int i, desc, c, lineWidth, nlines;
+ register char *srcLine;
+
+ if ((ret = tuiAllocSourceBuffer (srcWin)) == TUI_SUCCESS)
+ {
+ lineWidth = srcWin->generic.width - 1;
+ /*
+ ** Take hilite (window border) into account, when calculating
+ ** the number of lines
+ */
+ nlines = (lineNo + (srcWin->generic.height - 2)) - lineNo;
+ desc = open_source_file (s);
+ if (desc < 0)
+ {
+ if (!noerror)
+ {
+ char *name = alloca (strlen (s->filename) + 100);
+ sprintf (name, "%s:%d", s->filename, lineNo);
+ print_sys_errmsg (name, errno);
+ }
+ ret = TUI_FAILURE;
+ }
+ else
+ {
+ if (s->line_charpos == 0)
+ find_source_lines (s, desc);
+
+ if (lineNo < 1 || lineNo > s->nlines)
+ {
+ close (desc);
+ printf_unfiltered (
+ "Line number %d out of range; %s has %d lines.\n",
+ lineNo, s->filename, s->nlines);
+ }
+ else if (lseek (desc, s->line_charpos[lineNo - 1], 0) < 0)
+ {
+ close (desc);
+ perror_with_name (s->filename);
+ }
+ else
+ {
+ register int offset, curLineNo, curLine, curLen, threshold;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ /*
+ ** Determine the threshold for the length of the line
+ ** and the offset to start the display
+ */
+ offset = srcWin->detail.sourceInfo.horizontalOffset;
+ threshold = (lineWidth - 1) + offset;
+ stream = fdopen (desc, FOPEN_RT);
+ clearerr (stream);
+ curLine = 0;
+ curLineNo =
+ srcWin->detail.sourceInfo.startLineOrAddr.lineNo = lineNo;
+ if (offset > 0)
+ srcLine = (char *) xmalloc (
+ (threshold + 1) * sizeof (char));
+ while (curLine < nlines)
+ {
+ TuiWinElementPtr element = (TuiWinElementPtr)
+ srcWin->generic.content[curLine];
+ struct breakpoint *bp;
+
+ /* get the first character in the line */
+ c = fgetc (stream);
+
+ if (offset == 0)
+ srcLine = ((TuiWinElementPtr)
+ srcWin->generic.content[
+ curLine])->whichElement.source.line;
+ /* Init the line with the line number */
+ sprintf (srcLine, "%-6d", curLineNo);
+ curLen = strlen (srcLine);
+ i = curLen -
+ ((curLen / tuiDefaultTabLen ()) * tuiDefaultTabLen ());
+ while (i < tuiDefaultTabLen ())
+ {
+ srcLine[curLen] = ' ';
+ i++;
+ curLen++;
+ }
+ srcLine[curLen] = (char) 0;
+
+ /*
+ ** Set whether element is the execution point and
+ ** whether there is a break point on it.
+ */
+ element->whichElement.source.lineOrAddr.lineNo =
+ curLineNo;
+ element->whichElement.source.isExecPoint =
+ (strcmp (((TuiWinElementPtr)
+ locator->content[0])->whichElement.locator.fileName,
+ s->filename) == 0
+ && curLineNo == ((TuiWinElementPtr)
+ locator->content[0])->whichElement.locator.lineNo);
+ bp = _hasBreak (s->filename, curLineNo);
+ element->whichElement.source.hasBreak =
+ (bp != (struct breakpoint *) NULL &&
+ (!element->whichElement.source.isExecPoint ||
+ (bp->disposition != disp_del || bp->hit_count <= 0)));
+ if (c != EOF)
+ {
+ i = strlen (srcLine) - 1;
+ do
+ {
+ if ((c != '\n') &&
+ (c != '\r') && (++i < threshold))
+ {
+ if (c < 040 && c != '\t')
+ {
+ srcLine[i++] = '^';
+ srcLine[i] = c + 0100;
+ }
+ else if (c == 0177)
+ {
+ srcLine[i++] = '^';
+ srcLine[i] = '?';
+ }
+ else
+ { /*
+ ** Store the charcter in the line
+ ** buffer. If it is a tab, then
+ ** translate to the correct number of
+ ** chars so we don't overwrite our
+ ** buffer.
+ */
+ if (c == '\t')
+ {
+ int j, maxTabLen = tuiDefaultTabLen ();
+
+ for (j = i - (
+ (i / maxTabLen) * maxTabLen);
+ ((j < maxTabLen) &&
+ i < threshold);
+ i++, j++)
+ srcLine[i] = ' ';
+ i--;
+ }
+ else
+ srcLine[i] = c;
+ }
+ srcLine[i + 1] = 0;
+ }
+ else
+ { /*
+ ** if we have not reached EOL, then eat
+ ** chars until we do
+ */
+ while (c != EOF && c != '\n' && c != '\r')
+ c = fgetc (stream);
+ }
+ }
+ while (c != EOF && c != '\n' && c != '\r' &&
+ i < threshold && (c = fgetc (stream)));
+ }
+ /* Now copy the line taking the offset into account */
+ if (strlen (srcLine) > offset)
+ strcpy (((TuiWinElementPtr) srcWin->generic.content[
+ curLine])->whichElement.source.line,
+ &srcLine[offset]);
+ else
+ ((TuiWinElementPtr)
+ srcWin->generic.content[
+ curLine])->whichElement.source.line[0] = (char) 0;
+ curLine++;
+ curLineNo++;
+ }
+ if (offset > 0)
+ tuiFree (srcLine);
+ fclose (stream);
+ srcWin->generic.contentSize = nlines;
+ ret = TUI_SUCCESS;
+ }
+ }
+ }
+ }
+ return ret;
+} /* tuiSetSourceContent */
+
+
+/* elz: this function sets the contents of the source window to empty
+ except for a line in the middle with a warning message about the
+ source not being available. This function is called by
+ tuiEraseSourceContents, which in turn is invoked when the source files
+ cannot be accessed */
+
+void
+tuiSetSourceContentNil (TuiWinInfoPtr winInfo, char *warning_string)
+{
+ int lineWidth;
+ int nLines;
+ int curr_line = 0;
+
+ lineWidth = winInfo->generic.width - 1;
+ nLines = winInfo->generic.height - 2;
+
+ /* set to empty each line in the window, except for the one
+ which contains the message */
+ while (curr_line < winInfo->generic.contentSize)
+ {
+ /* set the information related to each displayed line
+ to null: i.e. the line number is 0, there is no bp,
+ it is not where the program is stopped */
+
+ TuiWinElementPtr element =
+ (TuiWinElementPtr) winInfo->generic.content[curr_line];
+ element->whichElement.source.lineOrAddr.lineNo = 0;
+ element->whichElement.source.isExecPoint = FALSE;
+ element->whichElement.source.hasBreak = FALSE;
+
+ /* set the contents of the line to blank */
+ element->whichElement.source.line[0] = (char) 0;
+
+ /* if the current line is in the middle of the screen, then we want to
+ display the 'no source available' message in it.
+ Note: the 'weird' arithmetic with the line width and height comes from
+ the function tuiEraseSourceContent. We need to keep the screen and the
+ window's actual contents in synch */
+
+ if (curr_line == (nLines / 2 + 1))
+ {
+ int i;
+ int xpos;
+ int warning_length = strlen (warning_string);
+ char *srcLine;
+
+ srcLine = element->whichElement.source.line;
+
+ if (warning_length >= ((lineWidth - 1) / 2))
+ xpos = 1;
+ else
+ xpos = (lineWidth - 1) / 2 - warning_length;
+
+ for (i = 0; i < xpos; i++)
+ srcLine[i] = ' ';
+
+ sprintf (srcLine + i, "%s", warning_string);
+
+ for (i = xpos + warning_length; i < lineWidth; i++)
+ srcLine[i] = ' ';
+
+ srcLine[i] = '\n';
+
+ } /* end if */
+
+ curr_line++;
+
+ } /* end while */
+
+} /*tuiSetSourceContentNil */
+
+
+
+
+/*
+ ** tuiShowSource().
+ ** Function to display source in the source window. This function
+ ** initializes the horizontal scroll to 0.
+ */
+void
+tuiShowSource (struct symtab *s, TuiLineOrAddress line, int noerror)
+{
+ srcWin->detail.sourceInfo.horizontalOffset = 0;
+ tuiUpdateSourceWindowAsIs(srcWin, s, line, noerror);
+
+ return;
+} /* tuiShowSource */
+
+
+/*
+ ** tuiSourceIsDisplayed().
+ ** Answer whether the source is currently displayed in the source window.
+ */
+int
+tuiSourceIsDisplayed (char *fname)
+{
+ return (srcWin->generic.contentInUse &&
+ (strcmp (((TuiWinElementPtr) (locatorWinInfoPtr ())->
+ content[0])->whichElement.locator.fileName, fname) == 0));
+} /* tuiSourceIsDisplayed */
+
+
+/*
+ ** tuiVerticalSourceScroll().
+ ** Scroll the source forward or backward vertically
+ */
+void
+tuiVerticalSourceScroll (TuiScrollDirection scrollDirection,
+ int numToScroll)
+{
+ if (srcWin->generic.content != (OpaquePtr) NULL)
+ {
+ TuiLineOrAddress l;
+ struct symtab *s;
+ TuiWinContent content = (TuiWinContent) srcWin->generic.content;
+
+ if (current_source_symtab == (struct symtab *) NULL)
+ s = find_pc_symtab (selected_frame->pc);
+ else
+ s = current_source_symtab;
+
+ if (scrollDirection == FORWARD_SCROLL)
+ {
+ l.lineNo = content[0]->whichElement.source.lineOrAddr.lineNo +
+ numToScroll;
+ if (l.lineNo > s->nlines)
+ /*line = s->nlines - winInfo->generic.contentSize + 1; */
+ /*elz: fix for dts 23398 */
+ l.lineNo = content[0]->whichElement.source.lineOrAddr.lineNo;
+ }
+ else
+ {
+ l.lineNo = content[0]->whichElement.source.lineOrAddr.lineNo -
+ numToScroll;
+ if (l.lineNo <= 0)
+ l.lineNo = 1;
+ }
+ if (identify_source_line (s, l.lineNo, 0, -1) == 1)
+ tuiUpdateSourceWindowAsIs (srcWin, s, l, FALSE);
+ }
+
+ return;
+} /* tuiVerticalSourceScroll */
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS **
+******************************************/
+
+/*
+ ** _hasBreak().
+ ** Answer whether there is a break point at the input line in
+ ** the source file indicated
+ */
+static struct breakpoint *
+_hasBreak (char *sourceFileName, int lineNo)
+{
+ struct breakpoint *bpWithBreak = (struct breakpoint *) NULL;
+ struct breakpoint *bp;
+ extern struct breakpoint *breakpoint_chain;
+
+
+ for (bp = breakpoint_chain;
+ (bp != (struct breakpoint *) NULL &&
+ bpWithBreak == (struct breakpoint *) NULL);
+ bp = bp->next)
+ if (bp->source_file
+ && (strcmp (sourceFileName, bp->source_file) == 0)
+ && (lineNo == bp->line_number))
+ bpWithBreak = bp;
+
+ return bpWithBreak;
+} /* _hasBreak */
diff --git a/gdb/tui/tuiSource.h b/gdb/tui/tuiSource.h
new file mode 100644
index 00000000000..2c04988ec2b
--- /dev/null
+++ b/gdb/tui/tuiSource.h
@@ -0,0 +1,41 @@
+/* TUI display source window.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef _TUI_SOURCE_H
+#define _TUI_SOURCE_H
+
+#include "defs.h"
+
+extern TuiStatus tuiSetSourceContent (struct symtab *, int, int);
+extern void tuiShowSource (struct symtab *, TuiLineOrAddress, int);
+extern void tuiShowSourceAsIs (struct symtab *, Opaque, int);
+extern int tuiSourceIsDisplayed (char *);
+extern void tuiVerticalSourceScroll (TuiScrollDirection, int);
+
+
+/*******************
+** MACROS **
+*******************/
+#define m_tuiShowSourceAsIs(s, line, noerror) tuiUpdateSourceWindowAsIs(srcWin, s, line, noerror)
+
+
+#endif
+/*_TUI_SOURCE_H*/
diff --git a/gdb/tui/tuiSourceWin.c b/gdb/tui/tuiSourceWin.c
new file mode 100644
index 00000000000..7563c940de0
--- /dev/null
+++ b/gdb/tui/tuiSourceWin.c
@@ -0,0 +1,915 @@
+/* TUI display source/assembly window.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+ Inc.
+
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include "defs.h"
+#include <ctype.h>
+#include "symtab.h"
+#include "frame.h"
+#include "breakpoint.h"
+#include "value.h"
+
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiStack.h"
+#include "tuiWin.h"
+#include "tuiGeneralWin.h"
+#include "tuiSourceWin.h"
+#include "tuiSource.h"
+#include "tuiDisassem.h"
+
+
+/*****************************************
+** EXTERNAL FUNCTION DECLS **
+******************************************/
+
+/*****************************************
+** EXTERNAL DATA DECLS **
+******************************************/
+extern int current_source_line;
+extern struct symtab *current_source_symtab;
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS FORWARD DECLS **
+******************************************/
+
+/*****************************************
+** STATIC LOCAL DATA **
+******************************************/
+
+
+/*****************************************
+** PUBLIC FUNCTIONS **
+******************************************/
+
+/*********************************
+** SOURCE/DISASSEM FUNCTIONS **
+*********************************/
+
+/*
+ ** tuiSrcWinIsDisplayed().
+ */
+int
+tuiSrcWinIsDisplayed (void)
+{
+ return (m_winPtrNotNull (srcWin) && srcWin->generic.isVisible);
+} /* tuiSrcWinIsDisplayed */
+
+
+/*
+ ** tuiAsmWinIsDisplayed().
+ */
+int
+tuiAsmWinIsDisplayed (void)
+{
+ return (m_winPtrNotNull (disassemWin) && disassemWin->generic.isVisible);
+} /* tuiAsmWinIsDisplayed */
+
+
+/*
+ ** tuiDisplayMainFunction().
+ ** Function to display the "main" routine"
+ */
+void
+tuiDisplayMainFunction (void)
+{
+ if ((sourceWindows ())->count > 0)
+ {
+ CORE_ADDR addr;
+
+ addr = parse_and_eval_address ("main");
+ if (addr == (CORE_ADDR) 0)
+ addr = parse_and_eval_address ("MAIN");
+ if (addr != (CORE_ADDR) 0)
+ {
+ struct symtab_and_line sal;
+
+ tuiUpdateSourceWindowsWithAddr (addr);
+ sal = find_pc_line (addr, 0);
+ tuiSwitchFilename (sal.symtab->filename);
+ }
+ }
+
+ return;
+} /* tuiDisplayMainFunction */
+
+
+
+/*
+ ** tuiUpdateSourceWindow().
+ ** Function to display source in the source window. This function
+ ** initializes the horizontal scroll to 0.
+ */
+void
+tuiUpdateSourceWindow (TuiWinInfoPtr winInfo, struct symtab *s,
+ TuiLineOrAddress lineOrAddr, int noerror)
+{
+ winInfo->detail.sourceInfo.horizontalOffset = 0;
+ tuiUpdateSourceWindowAsIs (winInfo, s, lineOrAddr, noerror);
+
+ return;
+} /* tuiUpdateSourceWindow */
+
+
+/*
+ ** tuiUpdateSourceWindowAsIs().
+ ** Function to display source in the source/asm window. This
+ ** function shows the source as specified by the horizontal offset.
+ */
+void
+tuiUpdateSourceWindowAsIs (TuiWinInfoPtr winInfo, struct symtab *s,
+ TuiLineOrAddress lineOrAddr, int noerror)
+{
+ TuiStatus ret;
+
+ if (winInfo->generic.type == SRC_WIN)
+ ret = tuiSetSourceContent (s, lineOrAddr.lineNo, noerror);
+ else
+ ret = tuiSetDisassemContent (s, lineOrAddr.addr);
+
+ if (ret == TUI_FAILURE)
+ {
+ tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT);
+ tuiClearExecInfoContent (winInfo);
+ }
+ else
+ {
+ tuiEraseSourceContent (winInfo, NO_EMPTY_SOURCE_PROMPT);
+ tuiShowSourceContent (winInfo);
+ tuiUpdateExecInfo (winInfo);
+ if (winInfo->generic.type == SRC_WIN)
+ {
+ current_source_line = lineOrAddr.lineNo +
+ (winInfo->generic.contentSize - 2);
+ current_source_symtab = s;
+ /*
+ ** If the focus was in the asm win, put it in the src
+ ** win if we don't have a split layout
+ */
+ if (tuiWinWithFocus () == disassemWin &&
+ currentLayout () != SRC_DISASSEM_COMMAND)
+ tuiSetWinFocusTo (srcWin);
+ }
+ }
+
+
+ return;
+} /* tuiUpdateSourceWindowAsIs */
+
+
+/*
+ ** tuiUpdateSourceWindowsWithAddr().
+ ** Function to ensure that the source and/or disassemly windows
+ ** reflect the input address.
+ */
+void
+tuiUpdateSourceWindowsWithAddr (CORE_ADDR addr)
+{
+ if (addr != 0)
+ {
+ struct symtab_and_line sal;
+ TuiLineOrAddress l;
+
+ switch (currentLayout ())
+ {
+ case DISASSEM_COMMAND:
+ case DISASSEM_DATA_COMMAND:
+ tuiShowDisassem (addr);
+ break;
+ case SRC_DISASSEM_COMMAND:
+ tuiShowDisassemAndUpdateSource (addr);
+ break;
+ default:
+ sal = find_pc_line (addr, 0);
+ l.lineNo = sal.line;
+ tuiShowSource (sal.symtab, l, FALSE);
+ break;
+ }
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ {
+ TuiWinInfoPtr winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
+
+ tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT);
+ tuiClearExecInfoContent (winInfo);
+ }
+ }
+
+ return;
+} /* tuiUpdateSourceWindowsWithAddr */
+
+/*
+ ** tuiUpdateSourceWindowsWithLine().
+ ** Function to ensure that the source and/or disassemly windows
+ ** reflect the input address.
+ */
+void
+tuiUpdateSourceWindowsWithLine (struct symtab *s, int line)
+{
+ CORE_ADDR pc;
+ TuiLineOrAddress l;
+
+ switch (currentLayout ())
+ {
+ case DISASSEM_COMMAND:
+ case DISASSEM_DATA_COMMAND:
+ find_line_pc (s, line, &pc);
+ tuiUpdateSourceWindowsWithAddr (pc);
+ break;
+ default:
+ l.lineNo = line;
+ tuiShowSource (s, l, FALSE);
+ if (currentLayout () == SRC_DISASSEM_COMMAND)
+ {
+ find_line_pc (s, line, &pc);
+ tuiShowDisassem (pc);
+ }
+ break;
+ }
+
+ return;
+} /* tuiUpdateSourceWindowsWithLine */
+
+/*
+ ** tuiClearSourceContent().
+ */
+void
+tuiClearSourceContent (TuiWinInfoPtr winInfo, int displayPrompt)
+{
+ if (m_winPtrNotNull (winInfo))
+ {
+ register int i;
+
+ winInfo->generic.contentInUse = FALSE;
+ tuiEraseSourceContent (winInfo, displayPrompt);
+ for (i = 0; i < winInfo->generic.contentSize; i++)
+ {
+ TuiWinElementPtr element =
+ (TuiWinElementPtr) winInfo->generic.content[i];
+ element->whichElement.source.hasBreak = FALSE;
+ element->whichElement.source.isExecPoint = FALSE;
+ }
+ }
+
+ return;
+} /* tuiClearSourceContent */
+
+
+/*
+ ** tuiClearAllSourceWinsContent().
+ */
+void
+tuiClearAllSourceWinsContent (int displayPrompt)
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiClearSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i],
+ displayPrompt);
+
+ return;
+} /* tuiClearAllSourceWinsContent */
+
+
+/*
+ ** tuiEraseSourceContent().
+ */
+void
+tuiEraseSourceContent (TuiWinInfoPtr winInfo, int displayPrompt)
+{
+ int xPos;
+ int halfWidth = (winInfo->generic.width - 2) / 2;
+
+ if (winInfo->generic.handle != (WINDOW *) NULL)
+ {
+ werase (winInfo->generic.handle);
+ checkAndDisplayHighlightIfNeeded (winInfo);
+ if (displayPrompt == EMPTY_SOURCE_PROMPT)
+ {
+ char *noSrcStr;
+
+ if (winInfo->generic.type == SRC_WIN)
+ noSrcStr = NO_SRC_STRING;
+ else
+ noSrcStr = NO_DISASSEM_STRING;
+ if (strlen (noSrcStr) >= halfWidth)
+ xPos = 1;
+ else
+ xPos = halfWidth - strlen (noSrcStr);
+ mvwaddstr (winInfo->generic.handle,
+ (winInfo->generic.height / 2),
+ xPos,
+ noSrcStr);
+
+ /* elz: added this function call to set the real contents of
+ the window to what is on the screen, so that later calls
+ to refresh, do display
+ the correct stuff, and not the old image */
+
+ tuiSetSourceContentNil (winInfo, noSrcStr);
+ }
+ tuiRefreshWin (&winInfo->generic);
+ }
+ return;
+} /* tuiEraseSourceContent */
+
+
+/*
+ ** tuiEraseAllSourceContent().
+ */
+void
+tuiEraseAllSourceWinsContent (int displayPrompt)
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiEraseSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i],
+ displayPrompt);
+
+ return;
+} /* tuiEraseAllSourceWinsContent */
+
+
+/*
+ ** tuiShowSourceContent().
+ */
+void
+tuiShowSourceContent (TuiWinInfoPtr winInfo)
+{
+ int curLine, i, curX;
+
+ tuiEraseSourceContent (winInfo, (winInfo->generic.contentSize <= 0));
+ if (winInfo->generic.contentSize > 0)
+ {
+ char *line;
+
+ for (curLine = 1; (curLine <= winInfo->generic.contentSize); curLine++)
+ mvwaddstr (
+ winInfo->generic.handle,
+ curLine,
+ 1,
+ ((TuiWinElementPtr)
+ winInfo->generic.content[curLine - 1])->whichElement.source.line);
+ }
+ checkAndDisplayHighlightIfNeeded (winInfo);
+ tuiRefreshWin (&winInfo->generic);
+ winInfo->generic.contentInUse = TRUE;
+
+ return;
+} /* tuiShowSourceContent */
+
+
+/*
+ ** tuiShowAllSourceWinsContent()
+ */
+void
+tuiShowAllSourceWinsContent (void)
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiShowSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
+
+ return;
+} /* tuiShowAllSourceWinsContent */
+
+
+/*
+ ** tuiHorizontalSourceScroll().
+ ** Scroll the source forward or backward horizontally
+ */
+void
+tuiHorizontalSourceScroll (TuiWinInfoPtr winInfo,
+ TuiScrollDirection direction,
+ int numToScroll)
+{
+ if (winInfo->generic.content != (OpaquePtr) NULL)
+ {
+ int offset;
+ struct symtab *s;
+
+ if (current_source_symtab == (struct symtab *) NULL)
+ s = find_pc_symtab (selected_frame->pc);
+ else
+ s = current_source_symtab;
+
+ if (direction == LEFT_SCROLL)
+ offset = winInfo->detail.sourceInfo.horizontalOffset + numToScroll;
+ else
+ {
+ if ((offset =
+ winInfo->detail.sourceInfo.horizontalOffset - numToScroll) < 0)
+ offset = 0;
+ }
+ winInfo->detail.sourceInfo.horizontalOffset = offset;
+ tuiUpdateSourceWindowAsIs (
+ winInfo,
+ s,
+ ((TuiWinElementPtr)
+ winInfo->generic.content[0])->whichElement.source.lineOrAddr,
+ FALSE);
+ }
+
+ return;
+} /* tuiHorizontalSourceScroll */
+
+
+/*
+ ** tuiSetHasExecPointAt().
+ ** Set or clear the hasBreak flag in the line whose line is lineNo.
+ */
+void
+tuiSetIsExecPointAt (TuiLineOrAddress l, TuiWinInfoPtr winInfo)
+{
+ int i;
+ TuiWinContent content = (TuiWinContent) winInfo->generic.content;
+
+ i = 0;
+ while (i < winInfo->generic.contentSize)
+ {
+ if (content[i]->whichElement.source.lineOrAddr.addr == l.addr)
+ content[i]->whichElement.source.isExecPoint = TRUE;
+ else
+ content[i]->whichElement.source.isExecPoint = FALSE;
+ i++;
+ }
+
+ return;
+} /* tuiSetIsExecPointAt */
+
+/*
+ ** tuiSetHasBreakAt().
+ ** Set or clear the hasBreak flag in the line whose line is lineNo.
+ */
+void
+tuiSetHasBreakAt (struct breakpoint *bp, TuiWinInfoPtr winInfo, int hasBreak)
+{
+ int i;
+ TuiWinContent content = (TuiWinContent) winInfo->generic.content;
+
+ i = 0;
+ while (i < winInfo->generic.contentSize)
+ {
+ int gotIt;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+ if (winInfo == srcWin)
+ {
+ char *fileNameDisplayed = (char *) NULL;
+
+ if (((TuiWinElementPtr)
+ locator->content[0])->whichElement.locator.fileName !=
+ (char *) NULL)
+ fileNameDisplayed = ((TuiWinElementPtr)
+ locator->content[0])->whichElement.locator.fileName;
+ else if (current_source_symtab != (struct symtab *) NULL)
+ fileNameDisplayed = current_source_symtab->filename;
+
+ gotIt = (fileNameDisplayed != (char *) NULL &&
+ bp->source_file != NULL &&
+ (strcmp (bp->source_file, fileNameDisplayed) == 0) &&
+ content[i]->whichElement.source.lineOrAddr.lineNo ==
+ bp->line_number);
+ }
+ else
+ gotIt = (content[i]->whichElement.source.lineOrAddr.addr
+ == bp->address);
+ if (gotIt)
+ {
+ content[i]->whichElement.source.hasBreak = hasBreak;
+ break;
+ }
+ i++;
+ }
+
+ return;
+} /* tuiSetHasBreakAt */
+
+
+/*
+ ** tuiAllSetHasBreakAt().
+ ** Set or clear the hasBreak flag in all displayed source windows.
+ */
+void
+tuiAllSetHasBreakAt (struct breakpoint *bp, int hasBreak)
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiSetHasBreakAt (bp,
+ (TuiWinInfoPtr) (sourceWindows ())->list[i], hasBreak);
+
+ return;
+} /* tuiAllSetHasBreakAt */
+
+
+/*********************************
+** EXECUTION INFO FUNCTIONS **
+*********************************/
+
+/*
+ ** tuiSetExecInfoContent().
+ ** Function to initialize the content of the execution info window,
+ ** based upon the input window which is either the source or
+ ** disassembly window.
+ */
+TuiStatus
+tuiSetExecInfoContent (TuiWinInfoPtr winInfo)
+{
+ TuiStatus ret = TUI_SUCCESS;
+
+ if (winInfo->detail.sourceInfo.executionInfo != (TuiGenWinInfoPtr) NULL)
+ {
+ TuiGenWinInfoPtr execInfoPtr = winInfo->detail.sourceInfo.executionInfo;
+
+ if (execInfoPtr->content == (OpaquePtr) NULL)
+ execInfoPtr->content =
+ (OpaquePtr) allocContent (winInfo->generic.height,
+ execInfoPtr->type);
+ if (execInfoPtr->content != (OpaquePtr) NULL)
+ {
+ int i;
+
+ for (i = 0; i < winInfo->generic.contentSize; i++)
+ {
+ TuiWinElementPtr element;
+ TuiWinElementPtr srcElement;
+
+ element = (TuiWinElementPtr) execInfoPtr->content[i];
+ srcElement = (TuiWinElementPtr) winInfo->generic.content[i];
+ /*
+ ** First check to see if we have a breakpoint that is
+ ** temporary. If so, and this is our current execution point,
+ ** then clear the break indicator.
+ */
+ if (srcElement->whichElement.source.hasBreak &&
+ srcElement->whichElement.source.isExecPoint)
+ {
+ struct breakpoint *bp;
+ int found = FALSE;
+ extern struct breakpoint *breakpoint_chain;
+
+ for (bp = breakpoint_chain;
+ (bp != (struct breakpoint *) NULL && !found);
+ bp = bp->next)
+ {
+ found =
+ (winInfo == srcWin &&
+ bp->line_number ==
+ srcElement->whichElement.source.lineOrAddr.lineNo) ||
+ (winInfo == disassemWin &&
+ bp->address == (CORE_ADDR)
+ srcElement->whichElement.source.lineOrAddr.addr);
+ if (found)
+ srcElement->whichElement.source.hasBreak =
+ (bp->disposition != disp_del || bp->hit_count <= 0);
+ }
+ if (!found)
+ srcElement->whichElement.source.hasBreak = FALSE;
+ }
+ /*
+ ** Now update the exec info content based upon the state
+ ** of each line as indicated by the source content.
+ */
+ if (srcElement->whichElement.source.hasBreak &&
+ srcElement->whichElement.source.isExecPoint)
+ element->whichElement.simpleString = breakLocationStr ();
+ else if (srcElement->whichElement.source.hasBreak)
+ element->whichElement.simpleString = breakStr ();
+ else if (srcElement->whichElement.source.isExecPoint)
+ element->whichElement.simpleString = locationStr ();
+ else
+ element->whichElement.simpleString = blankStr ();
+ }
+ execInfoPtr->contentSize = winInfo->generic.contentSize;
+ }
+ else
+ ret = TUI_FAILURE;
+ }
+
+ return ret;
+} /* tuiSetExecInfoContent */
+
+
+/*
+ ** tuiShowExecInfoContent().
+ */
+void
+tuiShowExecInfoContent (TuiWinInfoPtr winInfo)
+{
+ TuiGenWinInfoPtr execInfo = winInfo->detail.sourceInfo.executionInfo;
+ int curLine;
+
+ werase (execInfo->handle);
+ tuiRefreshWin (execInfo);
+ for (curLine = 1; (curLine <= execInfo->contentSize); curLine++)
+ mvwaddstr (execInfo->handle,
+ curLine,
+ 0,
+ ((TuiWinElementPtr)
+ execInfo->content[curLine - 1])->whichElement.simpleString);
+ tuiRefreshWin (execInfo);
+ execInfo->contentInUse = TRUE;
+
+ return;
+} /* tuiShowExecInfoContent */
+
+
+/*
+ ** tuiShowAllExecInfosContent()
+ */
+void
+tuiShowAllExecInfosContent (void)
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiShowExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
+
+ return;
+} /* tuiShowAllExecInfosContent */
+
+
+/*
+ ** tuiEraseExecInfoContent().
+ */
+void
+tuiEraseExecInfoContent (TuiWinInfoPtr winInfo)
+{
+ TuiGenWinInfoPtr execInfo = winInfo->detail.sourceInfo.executionInfo;
+
+ werase (execInfo->handle);
+ tuiRefreshWin (execInfo);
+
+ return;
+} /* tuiEraseExecInfoContent */
+
+
+/*
+ ** tuiEraseAllExecInfosContent()
+ */
+void
+tuiEraseAllExecInfosContent (void)
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiEraseExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
+
+ return;
+} /* tuiEraseAllExecInfosContent */
+
+
+/*
+ ** tuiClearExecInfoContent().
+ */
+void
+tuiClearExecInfoContent (TuiWinInfoPtr winInfo)
+{
+ winInfo->detail.sourceInfo.executionInfo->contentInUse = FALSE;
+ tuiEraseExecInfoContent (winInfo);
+
+ return;
+} /* tuiClearExecInfoContent */
+
+
+/*
+ ** tuiClearAllExecInfosContent()
+ */
+void
+tuiClearAllExecInfosContent (void)
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiClearExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
+
+ return;
+} /* tuiClearAllExecInfosContent */
+
+
+/*
+ ** tuiUpdateExecInfo().
+ ** Function to update the execution info window
+ */
+void
+tuiUpdateExecInfo (TuiWinInfoPtr winInfo)
+{
+ tuiSetExecInfoContent (winInfo);
+ tuiShowExecInfoContent (winInfo);
+} /* tuiUpdateExecInfo */
+
+
+ /*
+ ** tuiUpdateAllExecInfos()
+ */
+void
+tuiUpdateAllExecInfos (void)
+{
+ int i;
+
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ tuiUpdateExecInfo ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
+
+ return;
+} /* tuiUpdateAllExecInfos */
+
+
+
+/* tuiUpdateOnEnd()
+ ** elz: This function clears the execution info from the source windows
+ ** and resets the locator to display no line info, procedure info, pc
+ ** info. It is called by stack_publish_stopped_with_no_frame, which
+ ** is called then the target terminates execution
+ */
+void
+tuiUpdateOnEnd (void)
+{
+ int i;
+ TuiGenWinInfoPtr locator;
+ char *filename;
+ TuiWinInfoPtr winInfo;
+
+ locator = locatorWinInfoPtr ();
+
+ /* for all the windows (src, asm) */
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ {
+ TuiLineOrAddress l;
+
+ winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
+
+ l.addr = -1;
+ l.lineNo = -1;
+ tuiSetIsExecPointAt (l, winInfo); /* the target is'n running */
+ /* -1 should not match any line number or pc */
+ tuiSetExecInfoContent (winInfo); /*set winInfo so that > is'n displayed */
+ tuiShowExecInfoContent (winInfo); /* display the new contents */
+ }
+
+ /*now update the locator */
+ tuiClearLocatorDisplay ();
+ tuiGetLocatorFilename (locator, &filename);
+ tuiSetLocatorInfo (
+ filename,
+ (char *) NULL,
+ 0,
+ (CORE_ADDR) 0,
+ &((TuiWinElementPtr) locator->content[0])->whichElement.locator);
+ tuiShowLocatorContent ();
+
+ return;
+} /* tuiUpdateOnEnd */
+
+
+
+TuiStatus
+tuiAllocSourceBuffer (TuiWinInfoPtr winInfo)
+{
+ register char *srcLine, *srcLineBuf;
+ register int i, lineWidth, c, maxLines;
+ TuiStatus ret = TUI_FAILURE;
+
+ maxLines = winInfo->generic.height; /* less the highlight box */
+ lineWidth = winInfo->generic.width - 1;
+ /*
+ ** Allocate the buffer for the source lines. Do this only once since they
+ ** will be re-used for all source displays. The only other time this will
+ ** be done is when a window's size changes.
+ */
+ if (winInfo->generic.content == (OpaquePtr) NULL)
+ {
+ srcLineBuf = (char *) xmalloc ((maxLines * lineWidth) * sizeof (char));
+ if (srcLineBuf == (char *) NULL)
+ fputs_unfiltered (
+ "Unable to Allocate Memory for Source or Disassembly Display.\n",
+ gdb_stderr);
+ else
+ {
+ /* allocate the content list */
+ if ((winInfo->generic.content =
+ (OpaquePtr) allocContent (maxLines, SRC_WIN)) == (OpaquePtr) NULL)
+ {
+ tuiFree (srcLineBuf);
+ srcLineBuf = (char *) NULL;
+ fputs_unfiltered (
+ "Unable to Allocate Memory for Source or Disassembly Display.\n",
+ gdb_stderr);
+ }
+ }
+ for (i = 0; i < maxLines; i++)
+ ((TuiWinElementPtr)
+ winInfo->generic.content[i])->whichElement.source.line =
+ srcLineBuf + (lineWidth * i);
+ ret = TUI_SUCCESS;
+ }
+ else
+ ret = TUI_SUCCESS;
+
+ return ret;
+} /* tuiAllocSourceBuffer */
+
+
+/*
+ ** tuiLineIsDisplayed().
+ ** Answer whether the a particular line number or address is displayed
+ ** in the current source window.
+ */
+int
+tuiLineIsDisplayed (int line, TuiWinInfoPtr winInfo,
+ int checkThreshold)
+{
+ int isDisplayed = FALSE;
+ int i, threshold;
+
+ if (checkThreshold)
+ threshold = SCROLL_THRESHOLD;
+ else
+ threshold = 0;
+ i = 0;
+ while (i < winInfo->generic.contentSize - threshold && !isDisplayed)
+ {
+ isDisplayed = (((TuiWinElementPtr)
+ winInfo->generic.content[i])->whichElement.source.lineOrAddr.lineNo
+ == (int) line);
+ i++;
+ }
+
+ return isDisplayed;
+} /* tuiLineIsDisplayed */
+
+
+/*
+ ** tuiLineIsDisplayed().
+ ** Answer whether the a particular line number or address is displayed
+ ** in the current source window.
+ */
+int
+tuiAddrIsDisplayed (CORE_ADDR addr, TuiWinInfoPtr winInfo,
+ int checkThreshold)
+{
+ int isDisplayed = FALSE;
+ int i, threshold;
+
+ if (checkThreshold)
+ threshold = SCROLL_THRESHOLD;
+ else
+ threshold = 0;
+ i = 0;
+ while (i < winInfo->generic.contentSize - threshold && !isDisplayed)
+ {
+ isDisplayed = (((TuiWinElementPtr)
+ winInfo->generic.content[i])->whichElement.source.lineOrAddr.addr
+ == addr);
+ i++;
+ }
+
+ return isDisplayed;
+}
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS **
+******************************************/
diff --git a/gdb/tui/tuiSourceWin.h b/gdb/tui/tuiSourceWin.h
new file mode 100644
index 00000000000..ced01f74682
--- /dev/null
+++ b/gdb/tui/tuiSourceWin.h
@@ -0,0 +1,68 @@
+/* TUI display source/assembly window.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef _TUI_SOURCEWIN_H
+#define _TUI_SOURCEWIN_H
+
+extern void tuiDisplayMainFunction (void);
+extern void tuiUpdateSourceWindow (TuiWinInfoPtr, struct symtab *, TuiLineOrAddress,
+ int);
+extern void tuiUpdateSourceWindowAsIs (TuiWinInfoPtr, struct symtab *, TuiLineOrAddress,
+ int);
+extern void tuiUpdateSourceWindowsWithAddr (CORE_ADDR);
+extern void tuiUpdateSourceWindowsWithLine (struct symtab *, int);
+extern void tuiUpdateSourceWindowsFromLocator (void);
+extern void tuiClearSourceContent (TuiWinInfoPtr, int);
+extern void tuiClearAllSourceWinsContent (int);
+extern void tuiEraseSourceContent (TuiWinInfoPtr, int);
+extern void tuiEraseAllSourceWinsContent (int);
+extern void tuiSetSourceContentNil (TuiWinInfoPtr, char *);
+extern void tuiShowSourceContent (TuiWinInfoPtr);
+extern void tuiShowAllSourceWinsContent (void);
+extern void tuiHorizontalSourceScroll (TuiWinInfoPtr, TuiScrollDirection,
+ int);
+extern void tuiUpdateOnEnd (void);
+
+extern TuiStatus tuiSetExecInfoContent (TuiWinInfoPtr);
+extern void tuiShowExecInfoContent (TuiWinInfoPtr);
+extern void tuiShowAllExecInfosContent (void);
+extern void tuiEraseExecInfoContent (TuiWinInfoPtr);
+extern void tuiEraseAllExecInfosContent (void);
+extern void tuiClearExecInfoContent (TuiWinInfoPtr);
+extern void tuiClearAllExecInfosContent (void);
+extern void tuiUpdateExecInfo (TuiWinInfoPtr);
+extern void tuiUpdateAllExecInfos (void);
+
+extern void tuiSetIsExecPointAt (TuiLineOrAddress, TuiWinInfoPtr);
+extern void tuiSetHasBreakAt (struct breakpoint *, TuiWinInfoPtr, int);
+extern void tuiAllSetHasBreakAt (struct breakpoint *, int);
+extern TuiStatus tuiAllocSourceBuffer (TuiWinInfoPtr);
+extern int tuiLineIsDisplayed (int, TuiWinInfoPtr, int);
+extern int tuiAddrIsDisplayed (CORE_ADDR, TuiWinInfoPtr, int);
+
+
+/*
+ ** Constant definitions
+ */
+#define SCROLL_THRESHOLD 2 /* threshold for lazy scroll */
+
+#endif
+/*_TUI_SOURCEWIN_H */
diff --git a/gdb/tui/tuiStack.c b/gdb/tui/tuiStack.c
new file mode 100644
index 00000000000..43d022928f6
--- /dev/null
+++ b/gdb/tui/tuiStack.c
@@ -0,0 +1,451 @@
+/* TUI display locator.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+ Inc.
+
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include "defs.h"
+#include "symtab.h"
+#include "breakpoint.h"
+#include "frame.h"
+#include "command.h"
+
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiStack.h"
+#include "tuiGeneralWin.h"
+#include "tuiSource.h"
+#include "tuiSourceWin.h"
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS FORWARD DECLS **
+******************************************/
+
+static char *_getFuncNameFromFrame (struct frame_info *);
+static void _tuiUpdateLocation_command (char *, int);
+
+
+
+/*****************************************
+** PUBLIC FUNCTION **
+******************************************/
+
+/*
+ ** tuiClearLocatorDisplay()
+ */
+void
+tuiClearLocatorDisplay (void)
+{
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ int i;
+
+ if (locator->handle != (WINDOW *) NULL)
+ {
+ /* No need to werase, since writing a line of
+ * blanks which we do below, is equivalent.
+ */
+ /* werase(locator->handle); */
+ wmove (locator->handle, 0, 0);
+ wstandout (locator->handle);
+ for (i = 0; i < locator->width; i++)
+ waddch (locator->handle, ' ');
+ wstandend (locator->handle);
+ tuiRefreshWin (locator);
+ wmove (locator->handle, 0, 0);
+ locator->contentInUse = FALSE;
+ }
+
+ return;
+} /* tuiClearLocatorDisplay */
+
+
+/*
+ ** tuiShowLocatorContent()
+ */
+void
+tuiShowLocatorContent (void)
+{
+ char *string;
+ TuiGenWinInfoPtr locator;
+
+ locator = locatorWinInfoPtr ();
+
+ if (m_genWinPtrNotNull (locator) && locator->handle != (WINDOW *) NULL)
+ {
+ string = displayableWinContentAt (locator, 0);
+ if (string != (char *) NULL)
+ {
+ wmove (locator->handle, 0, 0);
+ wstandout (locator->handle);
+ waddstr (locator->handle, string);
+ wstandend (locator->handle);
+ tuiRefreshWin (locator);
+ wmove (locator->handle, 0, 0);
+ if (string != nullStr ())
+ tuiFree (string);
+ locator->contentInUse = TRUE;
+ }
+ }
+
+ return;
+} /* tuiShowLocatorContent */
+
+
+/* Update the locator, with the provided arguments. */
+void
+tuiSetLocatorInfo (char *fname, char *procname, int lineNo,
+ CORE_ADDR addr, TuiLocatorElementPtr element)
+{
+ element->fileName[0] = (char) 0;
+ element->procName[0] = (char) 0;
+ strcat_to_buf (element->fileName, MAX_LOCATOR_ELEMENT_LEN, fname);
+ strcat_to_buf (element->procName, MAX_LOCATOR_ELEMENT_LEN, procname);
+ element->lineNo = lineNo;
+ element->addr = addr;
+}
+
+
+/*
+ ** tuiUpdateLocatorFilename().
+ ** Update only the filename portion of the locator.
+ */
+void
+tuiUpdateLocatorFilename (const char *fileName)
+{
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+ if (locator->content[0] == (Opaque) NULL)
+ tuiSetLocatorContent ((struct frame_info *) NULL);
+ ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName[0] = (char) 0;
+ strcat_to_buf (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName,
+ MAX_LOCATOR_ELEMENT_LEN,
+ fileName);
+
+ tuiShowLocatorContent ();
+
+ return;
+} /* tuiUpdateLocatorFilename */
+
+/*
+ ** tuiSwitchFilename().
+ ** Update the filename portion of the locator. Clear the other info in locator.
+ ** (elz)
+ */
+void
+tuiSwitchFilename (char *fileName)
+{
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+
+ if (locator->content[0] == (Opaque) NULL)
+ tuiSetLocatorContent ((struct frame_info *) NULL);
+ ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName[0] = (char) 0;
+
+ tuiSetLocatorInfo (fileName,
+ (char *) NULL,
+ 0,
+ (CORE_ADDR) 0,
+ &((TuiWinElementPtr) locator->content[0])->whichElement.locator);
+
+ tuiShowLocatorContent ();
+
+ return;
+} /* tuiSwitchFilename */
+
+
+/*
+ ** tuiGetLocatorFilename().
+ ** Get the filename portion of the locator.
+ ** (elz)
+ */
+void
+tuiGetLocatorFilename (TuiGenWinInfoPtr locator, char **filename)
+{
+
+ /* the current filename could be non known, in which case the xmalloc would
+ allocate no memory, because the length would be 0 */
+ if (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName)
+ {
+ int name_length =
+ strlen (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName);
+
+ (*filename) = (char *) xmalloc (name_length + 1);
+ strcpy ((*filename),
+ ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName);
+ }
+
+ return;
+} /* tuiGetLocatorFilename */
+
+
+/*
+ ** tuiUpdateLocatorInfoFromFrame().
+ ** Function to update the locator, with the information extracted from frameInfo
+ */
+void
+tuiUpdateLocatorInfoFromFrame (struct frame_info *frameInfo,
+ TuiLocatorElementPtr element)
+{
+ struct symtab_and_line symtabAndLine;
+
+ /* now get the new info */
+ symtabAndLine = find_pc_line (frameInfo->pc,
+ (frameInfo->next != (struct frame_info *) NULL &&
+ !frameInfo->next->signal_handler_caller &&
+ !frame_in_dummy (frameInfo->next)));
+ if (symtabAndLine.symtab && symtabAndLine.symtab->filename)
+ tuiSetLocatorInfo (symtabAndLine.symtab->filename,
+ _getFuncNameFromFrame (frameInfo),
+ symtabAndLine.line,
+ frameInfo->pc,
+ element);
+ else
+ tuiSetLocatorInfo ((char *) NULL,
+ _getFuncNameFromFrame (frameInfo),
+ 0,
+ frameInfo->pc,
+ element);
+
+ return;
+} /* tuiUpdateLocatorInfoFromFrame */
+
+
+/*
+ ** tuiSetLocatorContent().
+ ** Function to set the content of the locator
+ */
+void
+tuiSetLocatorContent (struct frame_info *frameInfo)
+{
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ TuiWinElementPtr element;
+ struct symtab_and_line symtabAndLine;
+
+ /* Allocate the element if necessary */
+ if (locator->contentSize <= 0)
+ {
+ TuiWinContent contentPtr;
+
+ if ((locator->content = (OpaquePtr) allocContent (1, locator->type)) == (OpaquePtr) NULL)
+ error ("Unable to Allocate Memory to Display Location.");
+ locator->contentSize = 1;
+ }
+
+ if (frameInfo != (struct frame_info *) NULL)
+ tuiUpdateLocatorInfoFromFrame (frameInfo,
+ &((TuiWinElementPtr) locator->content[0])->whichElement.locator);
+ else
+ tuiSetLocatorInfo ((char *) NULL,
+ (char *) NULL,
+ 0,
+ (CORE_ADDR) 0,
+ &((TuiWinElementPtr) locator->content[0])->whichElement.locator);
+ return;
+} /* tuiSetLocatorContent */
+
+
+/*
+ ** tuiUpdateLocatorDisplay().
+ ** Function to update the locator display
+ */
+void
+tuiUpdateLocatorDisplay (struct frame_info *frameInfo)
+{
+ tuiClearLocatorDisplay ();
+ tuiSetLocatorContent (frameInfo);
+ tuiShowLocatorContent ();
+
+ return;
+} /* tuiUpdateLocatorDisplay */
+
+
+/*
+ ** tuiShowFrameInfo().
+ ** Function to print the frame inforrmation for the TUI.
+ */
+void
+tuiShowFrameInfo (struct frame_info *fi)
+{
+ TuiWinInfoPtr winInfo;
+ register int i;
+
+ if (fi)
+ {
+ register int startLine, i;
+ register struct symtab *s;
+ CORE_ADDR low;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ int sourceAlreadyDisplayed;
+
+
+ s = find_pc_symtab (fi->pc);
+ if (s == 0)
+ return;
+
+ startLine = 0;
+ sourceAlreadyDisplayed = tuiSourceIsDisplayed (s->filename);
+ tuiUpdateLocatorDisplay (fi);
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ {
+ TuiWhichElement *item;
+ winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
+
+ item = &((TuiWinElementPtr) locator->content[0])->whichElement;
+ if (winInfo == srcWin)
+ {
+ startLine = (item->locator.lineNo -
+ (winInfo->generic.viewportHeight / 2)) + 1;
+ if (startLine <= 0)
+ startLine = 1;
+ }
+ else
+ {
+ if (find_pc_partial_function (fi->pc, (char **) NULL, &low, (CORE_ADDR) NULL) == 0)
+ error ("No function contains program counter for selected frame.\n");
+ else
+ low = tuiGetLowDisassemblyAddress (low, fi->pc);
+ }
+
+ if (winInfo == srcWin)
+ {
+ TuiLineOrAddress l;
+ l.lineNo = startLine;
+ if (!(sourceAlreadyDisplayed
+ && tuiLineIsDisplayed (item->locator.lineNo, winInfo, TRUE)))
+ tuiUpdateSourceWindow (winInfo, s, l, TRUE);
+ else
+ {
+ l.lineNo = item->locator.lineNo;
+ tuiSetIsExecPointAt (l, winInfo);
+ }
+ }
+ else
+ {
+ if (winInfo == disassemWin)
+ {
+ TuiLineOrAddress a;
+ a.addr = low;
+ if (!tuiAddrIsDisplayed (item->locator.addr, winInfo, TRUE))
+ tuiUpdateSourceWindow (winInfo, s, a, TRUE);
+ else
+ {
+ a.addr = item->locator.addr;
+ tuiSetIsExecPointAt (a, winInfo);
+ }
+ }
+ }
+ tuiUpdateExecInfo (winInfo);
+ }
+ }
+ else
+ {
+ tuiUpdateLocatorDisplay (fi);
+ for (i = 0; i < (sourceWindows ())->count; i++)
+ {
+ winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
+ tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT);
+ tuiUpdateExecInfo (winInfo);
+ }
+ }
+
+ return;
+} /* tuiShowFrameInfo */
+
+/*
+ ** _initialize_tuiStack().
+ ** Function to initialize gdb commands, for tui window stack manipulation.
+ */
+void
+_initialize_tuiStack (void)
+{
+ add_com ("update", class_tui, _tuiUpdateLocation_command,
+ "Update the source window and locator to display the current execution point.\n");
+}
+
+
+/*****************************************
+** STATIC LOCAL FUNCTIONS **
+******************************************/
+
+/*
+ ** _getFuncNameFromFrame().
+ */
+static char *
+_getFuncNameFromFrame (struct frame_info *frameInfo)
+{
+ char *funcName = (char *) NULL;
+
+ find_pc_partial_function (frameInfo->pc,
+ &funcName,
+ (CORE_ADDR *) NULL,
+ (CORE_ADDR *) NULL);
+ return funcName;
+} /* _getFuncNameFromFrame */
+
+
+/*
+ ** _tuiUpdateLocation_command().
+ ** Command to update the display with the current execution point
+ */
+static void
+_tuiUpdateLocation_command (char *arg, int fromTTY)
+{
+#ifndef TRY
+extern void frame_command (char *, int);
+ frame_command ("0", FALSE);
+#else
+ struct frame_info *curFrame;
+
+ /* Obtain the current execution point */
+ if ((curFrame = get_current_frame ()) != (struct frame_info *) NULL)
+ {
+ struct frame_info *frame;
+ int curLevel = 0;
+
+ for (frame = get_prev_frame (curLevel);
+ (frame != (struct frame_info *) NULL && (frame != curFrame));
+ frame = get_prev_frame (frame))
+ curLevel++;
+
+ if (curFrame != (struct frame_info *) NULL)
+ print_frame_info (frame, curLevel, 0, 1);
+ }
+#endif
+
+ return;
+} /* _tuiUpdateLocation_command */
diff --git a/gdb/tui/tuiStack.h b/gdb/tui/tuiStack.h
new file mode 100644
index 00000000000..90aab5abe22
--- /dev/null
+++ b/gdb/tui/tuiStack.h
@@ -0,0 +1,44 @@
+/* TUI display locator.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef _TUI_STACK_H
+#define _TUI_STACK_H
+/*
+ ** This header file supports
+ */
+
+extern void tuiSetLocatorInfo (char *, char *, int, CORE_ADDR,
+ TuiLocatorElementPtr);
+extern void tuiUpdateLocatorFilename (const char *);
+extern void tuiUpdateLocatorInfoFromFrame
+ (struct frame_info *, TuiLocatorElementPtr);
+extern void tuiUpdateLocatorDisplay (struct frame_info *);
+extern void tuiSetLocatorContent (struct frame_info *);
+extern void tuiShowLocatorContent (void);
+extern void tuiClearLocatorContent (void);
+extern void tuiClearLocatorDisplay (void);
+extern void tuiSwitchFilename (char *);
+extern void tuiShowFrameInfo (struct frame_info *);
+extern void tuiGetLocatorFilename (TuiGenWinInfoPtr, char **);
+
+
+#endif
+/*_TUI_STACK_H*/
diff --git a/gdb/tui/tuiWin.c b/gdb/tui/tuiWin.c
new file mode 100644
index 00000000000..a33f6613606
--- /dev/null
+++ b/gdb/tui/tuiWin.c
@@ -0,0 +1,1627 @@
+/* TUI window generic functions.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+ Inc.
+
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+/* This module contains procedures for handling tui window functions
+ like resize, scrolling, scrolling, changing focus, etc.
+
+ Author: Susan B. Macchia */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+#ifdef HAVE_NCURSES_H
+#include <ncurses.h>
+#else
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#endif
+
+#include <string.h>
+#include <ctype.h>
+#include "defs.h"
+#include "command.h"
+#include "symtab.h"
+#include "breakpoint.h"
+#include "frame.h"
+#include "cli/cli-cmds.h"
+
+#include "tui.h"
+#include "tuiData.h"
+#include "tuiGeneralWin.h"
+#include "tuiStack.h"
+#include "tuiRegs.h"
+#include "tuiDisassem.h"
+#include "tuiSource.h"
+#include "tuiSourceWin.h"
+#include "tuiDataWin.h"
+
+/*******************************
+** External Declarations
+********************************/
+extern void init_page_info ();
+
+/*******************************
+** Static Local Decls
+********************************/
+static void _makeVisibleWithNewHeight (TuiWinInfoPtr);
+static void _makeInvisibleAndSetNewHeight (TuiWinInfoPtr, int);
+static TuiStatus _tuiAdjustWinHeights (TuiWinInfoPtr, int);
+static int _newHeightOk (TuiWinInfoPtr, int);
+static void _tuiSetTabWidth_command (char *, int);
+static void _tuiRefreshAll_command (char *, int);
+static void _tuiSetWinHeight_command (char *, int);
+static void _tuiXDBsetWinHeight_command (char *, int);
+static void _tuiAllWindowsInfo (char *, int);
+static void _tuiSetFocus_command (char *, int);
+static void _tuiScrollForward_command (char *, int);
+static void _tuiScrollBackward_command (char *, int);
+static void _tuiScrollLeft_command (char *, int);
+static void _tuiScrollRight_command (char *, int);
+static void _parseScrollingArgs (char *, TuiWinInfoPtr *, int *);
+
+
+/***************************************
+** DEFINITIONS
+***************************************/
+#define WIN_HEIGHT_USAGE "Usage: winheight <win_name> [+ | -] <#lines>\n"
+#define XDBWIN_HEIGHT_USAGE "Usage: w <#lines>\n"
+#define FOCUS_USAGE "Usage: focus {<win> | next | prev}\n"
+
+/***************************************
+** PUBLIC FUNCTIONS
+***************************************/
+
+/* Possible values for tui-border-kind variable. */
+static const char *tui_border_kind_enums[] = {
+ "space",
+ "ascii",
+ "acs",
+ NULL
+};
+
+/* Possible values for tui-border-mode and tui-active-border-mode. */
+static const char *tui_border_mode_enums[] = {
+ "normal",
+ "standout",
+ "reverse",
+ "half",
+ "half-standout",
+ "bold",
+ "bold-standout",
+ NULL
+};
+
+struct tui_translate
+{
+ const char *name;
+ int value;
+};
+
+/* Translation table for border-mode variables.
+ The list of values must be terminated by a NULL.
+ After the NULL value, an entry defines the default. */
+struct tui_translate tui_border_mode_translate[] = {
+ { "normal", A_NORMAL },
+ { "standout", A_STANDOUT },
+ { "reverse", A_REVERSE },
+ { "half", A_DIM },
+ { "half-standout", A_DIM | A_STANDOUT },
+ { "bold", A_BOLD },
+ { "bold-standout", A_BOLD | A_STANDOUT },
+ { 0, 0 },
+ { "normal", A_NORMAL }
+};
+
+/* Translation tables for border-kind, one for each border
+ character (see wborder, border curses operations).
+ -1 is used to indicate the ACS because ACS characters
+ are determined at run time by curses (depends on terminal). */
+struct tui_translate tui_border_kind_translate_vline[] = {
+ { "space", ' ' },
+ { "ascii", '|' },
+ { "acs", -1 },
+ { 0, 0 },
+ { "ascii", '|' }
+};
+
+struct tui_translate tui_border_kind_translate_hline[] = {
+ { "space", ' ' },
+ { "ascii", '-' },
+ { "acs", -1 },
+ { 0, 0 },
+ { "ascii", '-' }
+};
+
+struct tui_translate tui_border_kind_translate_ulcorner[] = {
+ { "space", ' ' },
+ { "ascii", '+' },
+ { "acs", -1 },
+ { 0, 0 },
+ { "ascii", '+' }
+};
+
+struct tui_translate tui_border_kind_translate_urcorner[] = {
+ { "space", ' ' },
+ { "ascii", '+' },
+ { "acs", -1 },
+ { 0, 0 },
+ { "ascii", '+' }
+};
+
+struct tui_translate tui_border_kind_translate_llcorner[] = {
+ { "space", ' ' },
+ { "ascii", '+' },
+ { "acs", -1 },
+ { 0, 0 },
+ { "ascii", '+' }
+};
+
+struct tui_translate tui_border_kind_translate_lrcorner[] = {
+ { "space", ' ' },
+ { "ascii", '+' },
+ { "acs", -1 },
+ { 0, 0 },
+ { "ascii", '+' }
+};
+
+
+/* Tui configuration variables controlled with set/show command. */
+const char *tui_active_border_mode = "bold-standout";
+const char *tui_border_mode = "normal";
+const char *tui_border_kind = "acs";
+
+/* Tui internal configuration variables. These variables are
+ updated by tui_update_variables to reflect the tui configuration
+ variables. */
+chtype tui_border_vline;
+chtype tui_border_hline;
+chtype tui_border_ulcorner;
+chtype tui_border_urcorner;
+chtype tui_border_llcorner;
+chtype tui_border_lrcorner;
+
+int tui_border_attrs;
+int tui_active_border_attrs;
+
+/* Identify the item in the translation table.
+ When the item is not recognized, use the default entry. */
+static struct tui_translate *
+translate (const char *name, struct tui_translate *table)
+{
+ while (table->name)
+ {
+ if (name && strcmp (table->name, name) == 0)
+ return table;
+ table++;
+ }
+
+ /* Not found, return default entry. */
+ table++;
+ return table;
+}
+
+/* Update the tui internal configuration according to gdb settings.
+ Returns 1 if the configuration has changed and the screen should
+ be redrawn. */
+int
+tui_update_variables ()
+{
+ int need_redraw = 0;
+ struct tui_translate *entry;
+
+ entry = translate (tui_border_mode, tui_border_mode_translate);
+ if (tui_border_attrs != entry->value)
+ {
+ tui_border_attrs = entry->value;
+ need_redraw = 1;
+ }
+ entry = translate (tui_active_border_mode, tui_border_mode_translate);
+ if (tui_active_border_attrs != entry->value)
+ {
+ tui_active_border_attrs = entry->value;
+ need_redraw = 1;
+ }
+
+ /* If one corner changes, all characters are changed.
+ Only check the first one. The ACS characters are determined at
+ run time by curses terminal management. */
+ entry = translate (tui_border_kind, tui_border_kind_translate_lrcorner);
+ if (tui_border_lrcorner != (chtype) entry->value)
+ {
+ tui_border_lrcorner = (entry->value < 0) ? ACS_LRCORNER : entry->value;
+ need_redraw = 1;
+ }
+ entry = translate (tui_border_kind, tui_border_kind_translate_llcorner);
+ tui_border_llcorner = (entry->value < 0) ? ACS_LLCORNER : entry->value;
+
+ entry = translate (tui_border_kind, tui_border_kind_translate_ulcorner);
+ tui_border_ulcorner = (entry->value < 0) ? ACS_ULCORNER : entry->value;
+
+ entry = translate (tui_border_kind, tui_border_kind_translate_urcorner);
+ tui_border_urcorner = (entry->value < 0) ? ACS_URCORNER : entry->value;
+
+ entry = translate (tui_border_kind, tui_border_kind_translate_hline);
+ tui_border_hline = (entry->value < 0) ? ACS_HLINE : entry->value;
+
+ entry = translate (tui_border_kind, tui_border_kind_translate_vline);
+ tui_border_vline = (entry->value < 0) ? ACS_VLINE : entry->value;
+
+ return need_redraw;
+}
+
+static void
+set_tui_cmd (char *args, int from_tty)
+{
+}
+
+static void
+show_tui_cmd (char *args, int from_tty)
+{
+}
+
+/*
+ ** _initialize_tuiWin().
+ ** Function to initialize gdb commands, for tui window manipulation.
+ */
+void
+_initialize_tuiWin (void)
+{
+ struct cmd_list_element *c;
+ static struct cmd_list_element *tui_setlist;
+ static struct cmd_list_element *tui_showlist;
+
+ /* Define the classes of commands.
+ They will appear in the help list in the reverse of this order. */
+ add_cmd ("tui", class_tui, NULL,
+ "Text User Interface commands.",
+ &cmdlist);
+
+ add_prefix_cmd ("tui", class_tui, set_tui_cmd,
+ "TUI configuration variables",
+ &tui_setlist, "set tui ",
+ 0/*allow-unknown*/, &setlist);
+ add_prefix_cmd ("tui", class_tui, show_tui_cmd,
+ "TUI configuration variables",
+ &tui_showlist, "show tui ",
+ 0/*allow-unknown*/, &showlist);
+
+ add_com ("refresh", class_tui, _tuiRefreshAll_command,
+ "Refresh the terminal display.\n");
+ if (xdb_commands)
+ add_com_alias ("U", "refresh", class_tui, 0);
+ add_com ("tabset", class_tui, _tuiSetTabWidth_command,
+ "Set the width (in characters) of tab stops.\n\
+Usage: tabset <n>\n");
+ add_com ("winheight", class_tui, _tuiSetWinHeight_command,
+ "Set the height of a specified window.\n\
+Usage: winheight <win_name> [+ | -] <#lines>\n\
+Window names are:\n\
+src : the source window\n\
+cmd : the command window\n\
+asm : the disassembly window\n\
+regs : the register display\n");
+ add_com_alias ("wh", "winheight", class_tui, 0);
+ add_info ("win", _tuiAllWindowsInfo,
+ "List of all displayed windows.\n");
+ add_com ("focus", class_tui, _tuiSetFocus_command,
+ "Set focus to named window or next/prev window.\n\
+Usage: focus {<win> | next | prev}\n\
+Valid Window names are:\n\
+src : the source window\n\
+asm : the disassembly window\n\
+regs : the register display\n\
+cmd : the command window\n");
+ add_com_alias ("fs", "focus", class_tui, 0);
+ add_com ("+", class_tui, _tuiScrollForward_command,
+ "Scroll window forward.\nUsage: + [win] [n]\n");
+ add_com ("-", class_tui, _tuiScrollBackward_command,
+ "Scroll window backward.\nUsage: - [win] [n]\n");
+ add_com ("<", class_tui, _tuiScrollLeft_command,
+ "Scroll window forward.\nUsage: < [win] [n]\n");
+ add_com (">", class_tui, _tuiScrollRight_command,
+ "Scroll window backward.\nUsage: > [win] [n]\n");
+ if (xdb_commands)
+ add_com ("w", class_xdb, _tuiXDBsetWinHeight_command,
+ "XDB compatibility command for setting the height of a command window.\n\
+Usage: w <#lines>\n");
+
+ /* Define the tui control variables. */
+ c = add_set_enum_cmd
+ ("border-kind", no_class,
+ tui_border_kind_enums, &tui_border_kind,
+ "Set the kind of border for TUI windows.\n"
+ "This variable controls the border of TUI windows:\n"
+ "space use a white space\n"
+ "ascii use ascii characters + - | for the border\n"
+ "acs use the Alternate Character Set\n",
+ &tui_setlist);
+ add_show_from_set (c, &tui_showlist);
+
+ c = add_set_enum_cmd
+ ("border-mode", no_class,
+ tui_border_mode_enums, &tui_border_mode,
+ "Set the attribute mode to use for the TUI window borders.\n"
+ "This variable controls the attributes to use for the window borders:\n"
+ "normal normal display\n"
+ "standout use highlight mode of terminal\n"
+ "reverse use reverse video mode\n"
+ "half use half bright\n"
+ "half-standout use half bright and standout mode\n"
+ "bold use extra bright or bold\n"
+ "bold-standout use extra bright or bold with standout mode\n",
+ &tui_setlist);
+ add_show_from_set (c, &tui_showlist);
+
+ c = add_set_enum_cmd
+ ("active-border-mode", no_class,
+ tui_border_mode_enums, &tui_active_border_mode,
+ "Set the attribute mode to use for the active TUI window border.\n"
+ "This variable controls the attributes to use for the active window border:\n"
+ "normal normal display\n"
+ "standout use highlight mode of terminal\n"
+ "reverse use reverse video mode\n"
+ "half use half bright\n"
+ "half-standout use half bright and standout mode\n"
+ "bold use extra bright or bold\n"
+ "bold-standout use extra bright or bold with standout mode\n",
+ &tui_setlist);
+ add_show_from_set (c, &tui_showlist);
+}
+
+
+/*
+ ** tuiClearWinFocusFrom
+ ** Clear the logical focus from winInfo
+ */
+void
+tuiClearWinFocusFrom (TuiWinInfoPtr winInfo)
+{
+ if (m_winPtrNotNull (winInfo))
+ {
+ if (winInfo->generic.type != CMD_WIN)
+ unhighlightWin (winInfo);
+ tuiSetWinWithFocus ((TuiWinInfoPtr) NULL);
+ }
+
+ return;
+} /* tuiClearWinFocusFrom */
+
+
+/*
+ ** tuiClearWinFocus().
+ ** Clear the window that has focus.
+ */
+void
+tuiClearWinFocus (void)
+{
+ tuiClearWinFocusFrom (tuiWinWithFocus ());
+
+ return;
+} /* tuiClearWinFocus */
+
+
+/*
+ ** tuiSetWinFocusTo
+ ** Set the logical focus to winInfo
+ */
+void
+tuiSetWinFocusTo (TuiWinInfoPtr winInfo)
+{
+ if (m_winPtrNotNull (winInfo))
+ {
+ TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
+
+ if (m_winPtrNotNull (winWithFocus) &&
+ winWithFocus->generic.type != CMD_WIN)
+ unhighlightWin (winWithFocus);
+ tuiSetWinWithFocus (winInfo);
+ if (winInfo->generic.type != CMD_WIN)
+ highlightWin (winInfo);
+ }
+
+ return;
+} /* tuiSetWinFocusTo */
+
+
+/*
+ ** tuiScrollForward().
+ */
+void
+tuiScrollForward (TuiWinInfoPtr winToScroll, int numToScroll)
+{
+ if (winToScroll != cmdWin)
+ {
+ int _numToScroll = numToScroll;
+
+ if (numToScroll == 0)
+ _numToScroll = winToScroll->generic.height - 3;
+ /*
+ ** If we are scrolling the source or disassembly window, do a
+ ** "psuedo" scroll since not all of the source is in memory,
+ ** only what is in the viewport. If winToScroll is the
+ ** command window do nothing since the term should handle it.
+ */
+ if (winToScroll == srcWin)
+ tuiVerticalSourceScroll (FORWARD_SCROLL, _numToScroll);
+ else if (winToScroll == disassemWin)
+ tuiVerticalDisassemScroll (FORWARD_SCROLL, _numToScroll);
+ else if (winToScroll == dataWin)
+ tuiVerticalDataScroll (FORWARD_SCROLL, _numToScroll);
+ }
+
+ return;
+} /* tuiScrollForward */
+
+
+/*
+ ** tuiScrollBackward().
+ */
+void
+tuiScrollBackward (TuiWinInfoPtr winToScroll, int numToScroll)
+{
+ if (winToScroll != cmdWin)
+ {
+ int _numToScroll = numToScroll;
+
+ if (numToScroll == 0)
+ _numToScroll = winToScroll->generic.height - 3;
+ /*
+ ** If we are scrolling the source or disassembly window, do a
+ ** "psuedo" scroll since not all of the source is in memory,
+ ** only what is in the viewport. If winToScroll is the
+ ** command window do nothing since the term should handle it.
+ */
+ if (winToScroll == srcWin)
+ tuiVerticalSourceScroll (BACKWARD_SCROLL, _numToScroll);
+ else if (winToScroll == disassemWin)
+ tuiVerticalDisassemScroll (BACKWARD_SCROLL, _numToScroll);
+ else if (winToScroll == dataWin)
+ tuiVerticalDataScroll (BACKWARD_SCROLL, _numToScroll);
+ }
+ return;
+} /* tuiScrollBackward */
+
+
+/*
+ ** tuiScrollLeft().
+ */
+void
+tuiScrollLeft (TuiWinInfoPtr winToScroll, int numToScroll)
+{
+ if (winToScroll != cmdWin)
+ {
+ int _numToScroll = numToScroll;
+
+ if (_numToScroll == 0)
+ _numToScroll = 1;
+ /*
+ ** If we are scrolling the source or disassembly window, do a
+ ** "psuedo" scroll since not all of the source is in memory,
+ ** only what is in the viewport. If winToScroll is the
+ ** command window do nothing since the term should handle it.
+ */
+ if (winToScroll == srcWin || winToScroll == disassemWin)
+ tuiHorizontalSourceScroll (winToScroll, LEFT_SCROLL, _numToScroll);
+ }
+ return;
+} /* tuiScrollLeft */
+
+
+/*
+ ** tuiScrollRight().
+ */
+void
+tuiScrollRight (TuiWinInfoPtr winToScroll, int numToScroll)
+{
+ if (winToScroll != cmdWin)
+ {
+ int _numToScroll = numToScroll;
+
+ if (_numToScroll == 0)
+ _numToScroll = 1;
+ /*
+ ** If we are scrolling the source or disassembly window, do a
+ ** "psuedo" scroll since not all of the source is in memory,
+ ** only what is in the viewport. If winToScroll is the
+ ** command window do nothing since the term should handle it.
+ */
+ if (winToScroll == srcWin || winToScroll == disassemWin)
+ tuiHorizontalSourceScroll (winToScroll, RIGHT_SCROLL, _numToScroll);
+ }
+ return;
+} /* tuiScrollRight */
+
+
+/*
+ ** tui_scroll().
+ ** Scroll a window. Arguments are passed through a va_list.
+ */
+void
+tui_scroll (TuiScrollDirection direction,
+ TuiWinInfoPtr winToScroll,
+ int numToScroll)
+{
+ switch (direction)
+ {
+ case FORWARD_SCROLL:
+ tuiScrollForward (winToScroll, numToScroll);
+ break;
+ case BACKWARD_SCROLL:
+ tuiScrollBackward (winToScroll, numToScroll);
+ break;
+ case LEFT_SCROLL:
+ tuiScrollLeft (winToScroll, numToScroll);
+ break;
+ case RIGHT_SCROLL:
+ tuiScrollRight (winToScroll, numToScroll);
+ break;
+ default:
+ break;
+ }
+}
+
+
+/*
+ ** tuiRefreshAll().
+ */
+void
+tuiRefreshAll (void)
+{
+ TuiWinType type;
+
+ clearok (curscr, TRUE);
+ refreshAll (winList);
+ for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++)
+ {
+ if (winList[type] && winList[type]->generic.isVisible)
+ {
+ switch (type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ tuiClearWin (&winList[type]->generic);
+ if (winList[type]->detail.sourceInfo.hasLocator)
+ tuiClearLocatorDisplay ();
+ tuiShowSourceContent (winList[type]);
+ checkAndDisplayHighlightIfNeeded (winList[type]);
+ tuiEraseExecInfoContent (winList[type]);
+ tuiUpdateExecInfo (winList[type]);
+ break;
+ case DATA_WIN:
+ tuiRefreshDataWin ();
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ tuiClearLocatorDisplay ();
+ tuiShowLocatorContent ();
+
+ return;
+} /* tuiRefreshAll */
+
+
+/*
+ ** tuiResizeAll().
+ ** Resize all the windows based on the the terminal size. This
+ ** function gets called from within the readline sinwinch handler.
+ */
+void
+tuiResizeAll (void)
+{
+ int heightDiff, widthDiff;
+ extern int screenheight, screenwidth; /* in readline */
+
+ widthDiff = screenwidth - termWidth ();
+ heightDiff = screenheight - termHeight ();
+ if (heightDiff || widthDiff)
+ {
+ TuiLayoutType curLayout = currentLayout ();
+ TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
+ TuiWinInfoPtr firstWin, secondWin;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ TuiWinType winType;
+ int i, newHeight, splitDiff, cmdSplitDiff, numWinsDisplayed = 2;
+
+ /* turn keypad off while we resize */
+ if (winWithFocus != cmdWin)
+ keypad (cmdWin->generic.handle, FALSE);
+ init_page_info ();
+ setTermHeightTo (screenheight);
+ setTermWidthTo (screenwidth);
+ if (curLayout == SRC_DISASSEM_COMMAND ||
+ curLayout == SRC_DATA_COMMAND || curLayout == DISASSEM_DATA_COMMAND)
+ numWinsDisplayed++;
+ splitDiff = heightDiff / numWinsDisplayed;
+ cmdSplitDiff = splitDiff;
+ if (heightDiff % numWinsDisplayed)
+ {
+ if (heightDiff < 0)
+ cmdSplitDiff--;
+ else
+ cmdSplitDiff++;
+ }
+ /* now adjust each window */
+ clear ();
+ refresh ();
+ switch (curLayout)
+ {
+ case SRC_COMMAND:
+ case DISASSEM_COMMAND:
+ firstWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
+ firstWin->generic.width += widthDiff;
+ locator->width += widthDiff;
+ /* check for invalid heights */
+ if (heightDiff == 0)
+ newHeight = firstWin->generic.height;
+ else if ((firstWin->generic.height + splitDiff) >=
+ (screenheight - MIN_CMD_WIN_HEIGHT - 1))
+ newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1;
+ else if ((firstWin->generic.height + splitDiff) <= 0)
+ newHeight = MIN_WIN_HEIGHT;
+ else
+ newHeight = firstWin->generic.height + splitDiff;
+
+ _makeInvisibleAndSetNewHeight (firstWin, newHeight);
+ cmdWin->generic.origin.y = locator->origin.y + 1;
+ cmdWin->generic.width += widthDiff;
+ newHeight = screenheight - cmdWin->generic.origin.y;
+ _makeInvisibleAndSetNewHeight (cmdWin, newHeight);
+ _makeVisibleWithNewHeight (firstWin);
+ _makeVisibleWithNewHeight (cmdWin);
+ if (firstWin->generic.contentSize <= 0)
+ tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
+ break;
+ default:
+ if (curLayout == SRC_DISASSEM_COMMAND)
+ {
+ firstWin = srcWin;
+ firstWin->generic.width += widthDiff;
+ secondWin = disassemWin;
+ secondWin->generic.width += widthDiff;
+ }
+ else
+ {
+ firstWin = dataWin;
+ firstWin->generic.width += widthDiff;
+ secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
+ secondWin->generic.width += widthDiff;
+ }
+ /* Change the first window's height/width */
+ /* check for invalid heights */
+ if (heightDiff == 0)
+ newHeight = firstWin->generic.height;
+ else if ((firstWin->generic.height +
+ secondWin->generic.height + (splitDiff * 2)) >=
+ (screenheight - MIN_CMD_WIN_HEIGHT - 1))
+ newHeight = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2;
+ else if ((firstWin->generic.height + splitDiff) <= 0)
+ newHeight = MIN_WIN_HEIGHT;
+ else
+ newHeight = firstWin->generic.height + splitDiff;
+ _makeInvisibleAndSetNewHeight (firstWin, newHeight);
+
+ if (firstWin == dataWin && widthDiff != 0)
+ firstWin->detail.dataDisplayInfo.regsColumnCount =
+ tuiCalculateRegsColumnCount (
+ firstWin->detail.dataDisplayInfo.regsDisplayType);
+ locator->width += widthDiff;
+
+ /* Change the second window's height/width */
+ /* check for invalid heights */
+ if (heightDiff == 0)
+ newHeight = secondWin->generic.height;
+ else if ((firstWin->generic.height +
+ secondWin->generic.height + (splitDiff * 2)) >=
+ (screenheight - MIN_CMD_WIN_HEIGHT - 1))
+ {
+ newHeight = screenheight - MIN_CMD_WIN_HEIGHT - 1;
+ if (newHeight % 2)
+ newHeight = (newHeight / 2) + 1;
+ else
+ newHeight /= 2;
+ }
+ else if ((secondWin->generic.height + splitDiff) <= 0)
+ newHeight = MIN_WIN_HEIGHT;
+ else
+ newHeight = secondWin->generic.height + splitDiff;
+ secondWin->generic.origin.y = firstWin->generic.height - 1;
+ _makeInvisibleAndSetNewHeight (secondWin, newHeight);
+
+ /* Change the command window's height/width */
+ cmdWin->generic.origin.y = locator->origin.y + 1;
+ _makeInvisibleAndSetNewHeight (
+ cmdWin, cmdWin->generic.height + cmdSplitDiff);
+ _makeVisibleWithNewHeight (firstWin);
+ _makeVisibleWithNewHeight (secondWin);
+ _makeVisibleWithNewHeight (cmdWin);
+ if (firstWin->generic.contentSize <= 0)
+ tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
+ if (secondWin->generic.contentSize <= 0)
+ tuiEraseSourceContent (secondWin, EMPTY_SOURCE_PROMPT);
+ break;
+ }
+ /*
+ ** Now remove all invisible windows, and their content so that they get
+ ** created again when called for with the new size
+ */
+ for (winType = SRC_WIN; (winType < MAX_MAJOR_WINDOWS); winType++)
+ {
+ if (winType != CMD_WIN && m_winPtrNotNull (winList[winType]) &&
+ !winList[winType]->generic.isVisible)
+ {
+ freeWindow (winList[winType]);
+ winList[winType] = (TuiWinInfoPtr) NULL;
+ }
+ }
+ tuiSetWinResizedTo (TRUE);
+ /* turn keypad back on, unless focus is in the command window */
+ if (winWithFocus != cmdWin)
+ keypad (cmdWin->generic.handle, TRUE);
+ }
+ return;
+} /* tuiResizeAll */
+
+
+/*
+ ** tuiSigwinchHandler()
+ ** SIGWINCH signal handler for the tui. This signal handler is
+ ** always called, even when the readline package clears signals
+ ** because it is set as the old_sigwinch() (TUI only)
+ */
+void
+tuiSigwinchHandler (int signal)
+{
+ /*
+ ** Say that a resize was done so that the readline can do it
+ ** later when appropriate.
+ */
+ tuiSetWinResizedTo (TRUE);
+
+ return;
+} /* tuiSigwinchHandler */
+
+
+
+/*************************
+** STATIC LOCAL FUNCTIONS
+**************************/
+
+
+/*
+ ** _tuiScrollForward_command().
+ */
+static void
+_tuiScrollForward_command (char *arg, int fromTTY)
+{
+ int numToScroll = 1;
+ TuiWinInfoPtr winToScroll;
+
+ /* Make sure the curses mode is enabled. */
+ tui_enable ();
+ if (arg == (char *) NULL)
+ _parseScrollingArgs (arg, &winToScroll, (int *) NULL);
+ else
+ _parseScrollingArgs (arg, &winToScroll, &numToScroll);
+ tui_scroll (FORWARD_SCROLL, winToScroll, numToScroll);
+}
+
+
+/*
+ ** _tuiScrollBackward_command().
+ */
+static void
+_tuiScrollBackward_command (char *arg, int fromTTY)
+{
+ int numToScroll = 1;
+ TuiWinInfoPtr winToScroll;
+
+ /* Make sure the curses mode is enabled. */
+ tui_enable ();
+ if (arg == (char *) NULL)
+ _parseScrollingArgs (arg, &winToScroll, (int *) NULL);
+ else
+ _parseScrollingArgs (arg, &winToScroll, &numToScroll);
+ tui_scroll (BACKWARD_SCROLL, winToScroll, numToScroll);
+}
+
+
+/*
+ ** _tuiScrollLeft_command().
+ */
+static void
+_tuiScrollLeft_command (char *arg, int fromTTY)
+{
+ int numToScroll;
+ TuiWinInfoPtr winToScroll;
+
+ /* Make sure the curses mode is enabled. */
+ tui_enable ();
+ _parseScrollingArgs (arg, &winToScroll, &numToScroll);
+ tui_scroll (LEFT_SCROLL, winToScroll, numToScroll);
+}
+
+
+/*
+ ** _tuiScrollRight_command().
+ */
+static void
+_tuiScrollRight_command (char *arg, int fromTTY)
+{
+ int numToScroll;
+ TuiWinInfoPtr winToScroll;
+
+ /* Make sure the curses mode is enabled. */
+ tui_enable ();
+ _parseScrollingArgs (arg, &winToScroll, &numToScroll);
+ tui_scroll (RIGHT_SCROLL, winToScroll, numToScroll);
+}
+
+
+/*
+ ** _tuiSetFocus().
+ ** Set focus to the window named by 'arg'
+ */
+static void
+_tuiSetFocus (char *arg, int fromTTY)
+{
+ if (arg != (char *) NULL)
+ {
+ char *bufPtr = (char *) xstrdup (arg);
+ int i;
+ TuiWinInfoPtr winInfo = (TuiWinInfoPtr) NULL;
+
+ for (i = 0; (i < strlen (bufPtr)); i++)
+ bufPtr[i] = toupper (arg[i]);
+
+ if (subset_compare (bufPtr, "NEXT"))
+ winInfo = tuiNextWin (tuiWinWithFocus ());
+ else if (subset_compare (bufPtr, "PREV"))
+ winInfo = tuiPrevWin (tuiWinWithFocus ());
+ else
+ winInfo = partialWinByName (bufPtr);
+
+ if (winInfo == (TuiWinInfoPtr) NULL || !winInfo->generic.isVisible)
+ warning ("Invalid window specified. \n\
+The window name specified must be valid and visible.\n");
+ else
+ {
+ tuiSetWinFocusTo (winInfo);
+ keypad (cmdWin->generic.handle, (winInfo != cmdWin));
+ }
+
+ if (dataWin && dataWin->generic.isVisible)
+ tuiRefreshDataWin ();
+ tuiFree (bufPtr);
+ printf_filtered ("Focus set to %s window.\n",
+ winName ((TuiGenWinInfoPtr) tuiWinWithFocus ()));
+ }
+ else
+ warning ("Incorrect Number of Arguments.\n%s", FOCUS_USAGE);
+
+ return;
+} /* _tuiSetFocus */
+
+/*
+ ** _tuiSetFocus_command()
+ */
+static void
+_tuiSetFocus_command (char *arg, int fromTTY)
+{
+ /* Make sure the curses mode is enabled. */
+ tui_enable ();
+ _tuiSetFocus (arg, fromTTY);
+}
+
+
+/*
+ ** _tuiAllWindowsInfo().
+ */
+static void
+_tuiAllWindowsInfo (char *arg, int fromTTY)
+{
+ TuiWinType type;
+ TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
+
+ for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++)
+ if (winList[type]->generic.isVisible)
+ {
+ if (winWithFocus == winList[type])
+ printf_filtered (" %s\t(%d lines) <has focus>\n",
+ winName (&winList[type]->generic),
+ winList[type]->generic.height);
+ else
+ printf_filtered (" %s\t(%d lines)\n",
+ winName (&winList[type]->generic),
+ winList[type]->generic.height);
+ }
+
+ return;
+} /* _tuiAllWindowsInfo */
+
+
+/*
+ ** _tuiRefreshAll_command().
+ */
+static void
+_tuiRefreshAll_command (char *arg, int fromTTY)
+{
+ /* Make sure the curses mode is enabled. */
+ tui_enable ();
+
+ tuiRefreshAll ();
+}
+
+
+/*
+ ** _tuiSetWinTabWidth_command().
+ ** Set the height of the specified window.
+ */
+static void
+_tuiSetTabWidth_command (char *arg, int fromTTY)
+{
+ /* Make sure the curses mode is enabled. */
+ tui_enable ();
+ if (arg != (char *) NULL)
+ {
+ int ts;
+
+ ts = atoi (arg);
+ if (ts > 0)
+ tuiSetDefaultTabLen (ts);
+ else
+ warning ("Tab widths greater than 0 must be specified.\n");
+ }
+
+ return;
+} /* _tuiSetTabWidth_command */
+
+
+/*
+ ** _tuiSetWinHeight().
+ ** Set the height of the specified window.
+ */
+static void
+_tuiSetWinHeight (char *arg, int fromTTY)
+{
+ /* Make sure the curses mode is enabled. */
+ tui_enable ();
+ if (arg != (char *) NULL)
+ {
+ char *buf = xstrdup (arg);
+ char *bufPtr = buf;
+ char *wname = (char *) NULL;
+ int newHeight, i;
+ TuiWinInfoPtr winInfo;
+
+ wname = bufPtr;
+ bufPtr = strchr (bufPtr, ' ');
+ if (bufPtr != (char *) NULL)
+ {
+ *bufPtr = (char) 0;
+
+ /*
+ ** Validate the window name
+ */
+ for (i = 0; i < strlen (wname); i++)
+ wname[i] = toupper (wname[i]);
+ winInfo = partialWinByName (wname);
+
+ if (winInfo == (TuiWinInfoPtr) NULL || !winInfo->generic.isVisible)
+ warning ("Invalid window specified. \n\
+The window name specified must be valid and visible.\n");
+ else
+ {
+ /* Process the size */
+ while (*(++bufPtr) == ' ')
+ ;
+
+ if (*bufPtr != (char) 0)
+ {
+ int negate = FALSE;
+ int fixedSize = TRUE;
+ int inputNo;;
+
+ if (*bufPtr == '+' || *bufPtr == '-')
+ {
+ if (*bufPtr == '-')
+ negate = TRUE;
+ fixedSize = FALSE;
+ bufPtr++;
+ }
+ inputNo = atoi (bufPtr);
+ if (inputNo > 0)
+ {
+ if (negate)
+ inputNo *= (-1);
+ if (fixedSize)
+ newHeight = inputNo;
+ else
+ newHeight = winInfo->generic.height + inputNo;
+ /*
+ ** Now change the window's height, and adjust all
+ ** other windows around it
+ */
+ if (_tuiAdjustWinHeights (winInfo,
+ newHeight) == TUI_FAILURE)
+ warning ("Invalid window height specified.\n%s",
+ WIN_HEIGHT_USAGE);
+ else
+ init_page_info ();
+ }
+ else
+ warning ("Invalid window height specified.\n%s",
+ WIN_HEIGHT_USAGE);
+ }
+ }
+ }
+ else
+ printf_filtered (WIN_HEIGHT_USAGE);
+
+ if (buf != (char *) NULL)
+ tuiFree (buf);
+ }
+ else
+ printf_filtered (WIN_HEIGHT_USAGE);
+
+ return;
+} /* _tuiSetWinHeight */
+
+/*
+ ** _tuiSetWinHeight_command().
+ ** Set the height of the specified window, with va_list.
+ */
+static void
+_tuiSetWinHeight_command (char *arg, int fromTTY)
+{
+ /* Make sure the curses mode is enabled. */
+ tui_enable ();
+ _tuiSetWinHeight (arg, fromTTY);
+}
+
+
+/*
+ ** _tuiXDBsetWinHeight().
+ ** XDB Compatibility command for setting the window height. This will
+ ** increase or decrease the command window by the specified amount.
+ */
+static void
+_tuiXDBsetWinHeight (char *arg, int fromTTY)
+{
+ /* Make sure the curses mode is enabled. */
+ tui_enable ();
+ if (arg != (char *) NULL)
+ {
+ int inputNo = atoi (arg);
+
+ if (inputNo > 0)
+ { /* Add 1 for the locator */
+ int newHeight = termHeight () - (inputNo + 1);
+
+ if (!_newHeightOk (winList[CMD_WIN], newHeight) ||
+ _tuiAdjustWinHeights (winList[CMD_WIN],
+ newHeight) == TUI_FAILURE)
+ warning ("Invalid window height specified.\n%s",
+ XDBWIN_HEIGHT_USAGE);
+ }
+ else
+ warning ("Invalid window height specified.\n%s",
+ XDBWIN_HEIGHT_USAGE);
+ }
+ else
+ warning ("Invalid window height specified.\n%s", XDBWIN_HEIGHT_USAGE);
+
+ return;
+} /* _tuiXDBsetWinHeight */
+
+/*
+ ** _tuiSetWinHeight_command().
+ ** Set the height of the specified window, with va_list.
+ */
+static void
+_tuiXDBsetWinHeight_command (char *arg, int fromTTY)
+{
+ _tuiXDBsetWinHeight (arg, fromTTY);
+}
+
+
+/*
+ ** _tuiAdjustWinHeights().
+ ** Function to adjust all window heights around the primary
+ */
+static TuiStatus
+_tuiAdjustWinHeights (TuiWinInfoPtr primaryWinInfo, int newHeight)
+{
+ TuiStatus status = TUI_FAILURE;
+
+ if (_newHeightOk (primaryWinInfo, newHeight))
+ {
+ status = TUI_SUCCESS;
+ if (newHeight != primaryWinInfo->generic.height)
+ {
+ int i, diff;
+ TuiWinInfoPtr winInfo;
+ TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
+ TuiLayoutType curLayout = currentLayout ();
+
+ diff = (newHeight - primaryWinInfo->generic.height) * (-1);
+ if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND)
+ {
+ TuiWinInfoPtr srcWinInfo;
+
+ _makeInvisibleAndSetNewHeight (primaryWinInfo, newHeight);
+ if (primaryWinInfo->generic.type == CMD_WIN)
+ {
+ winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[0];
+ srcWinInfo = winInfo;
+ }
+ else
+ {
+ winInfo = winList[CMD_WIN];
+ srcWinInfo = primaryWinInfo;
+ }
+ _makeInvisibleAndSetNewHeight (winInfo,
+ winInfo->generic.height + diff);
+ cmdWin->generic.origin.y = locator->origin.y + 1;
+ _makeVisibleWithNewHeight (winInfo);
+ _makeVisibleWithNewHeight (primaryWinInfo);
+ if (srcWinInfo->generic.contentSize <= 0)
+ tuiEraseSourceContent (srcWinInfo, EMPTY_SOURCE_PROMPT);
+ }
+ else
+ {
+ TuiWinInfoPtr firstWin, secondWin;
+
+ if (curLayout == SRC_DISASSEM_COMMAND)
+ {
+ firstWin = srcWin;
+ secondWin = disassemWin;
+ }
+ else
+ {
+ firstWin = dataWin;
+ secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
+ }
+ if (primaryWinInfo == cmdWin)
+ { /*
+ ** Split the change in height accross the 1st & 2nd windows
+ ** adjusting them as well.
+ */
+ int firstSplitDiff = diff / 2; /* subtract the locator */
+ int secondSplitDiff = firstSplitDiff;
+
+ if (diff % 2)
+ {
+ if (firstWin->generic.height >
+ secondWin->generic.height)
+ if (diff < 0)
+ firstSplitDiff--;
+ else
+ firstSplitDiff++;
+ else
+ {
+ if (diff < 0)
+ secondSplitDiff--;
+ else
+ secondSplitDiff++;
+ }
+ }
+ /* make sure that the minimum hieghts are honored */
+ while ((firstWin->generic.height + firstSplitDiff) < 3)
+ {
+ firstSplitDiff++;
+ secondSplitDiff--;
+ }
+ while ((secondWin->generic.height + secondSplitDiff) < 3)
+ {
+ secondSplitDiff++;
+ firstSplitDiff--;
+ }
+ _makeInvisibleAndSetNewHeight (
+ firstWin,
+ firstWin->generic.height + firstSplitDiff);
+ secondWin->generic.origin.y = firstWin->generic.height - 1;
+ _makeInvisibleAndSetNewHeight (
+ secondWin, secondWin->generic.height + secondSplitDiff);
+ cmdWin->generic.origin.y = locator->origin.y + 1;
+ _makeInvisibleAndSetNewHeight (cmdWin, newHeight);
+ }
+ else
+ {
+ if ((cmdWin->generic.height + diff) < 1)
+ { /*
+ ** If there is no way to increase the command window
+ ** take real estate from the 1st or 2nd window.
+ */
+ if ((cmdWin->generic.height + diff) < 1)
+ {
+ int i;
+ for (i = cmdWin->generic.height + diff;
+ (i < 1); i++)
+ if (primaryWinInfo == firstWin)
+ secondWin->generic.height--;
+ else
+ firstWin->generic.height--;
+ }
+ }
+ if (primaryWinInfo == firstWin)
+ _makeInvisibleAndSetNewHeight (firstWin, newHeight);
+ else
+ _makeInvisibleAndSetNewHeight (
+ firstWin,
+ firstWin->generic.height);
+ secondWin->generic.origin.y = firstWin->generic.height - 1;
+ if (primaryWinInfo == secondWin)
+ _makeInvisibleAndSetNewHeight (secondWin, newHeight);
+ else
+ _makeInvisibleAndSetNewHeight (
+ secondWin, secondWin->generic.height);
+ cmdWin->generic.origin.y = locator->origin.y + 1;
+ if ((cmdWin->generic.height + diff) < 1)
+ _makeInvisibleAndSetNewHeight (cmdWin, 1);
+ else
+ _makeInvisibleAndSetNewHeight (
+ cmdWin, cmdWin->generic.height + diff);
+ }
+ _makeVisibleWithNewHeight (cmdWin);
+ _makeVisibleWithNewHeight (secondWin);
+ _makeVisibleWithNewHeight (firstWin);
+ if (firstWin->generic.contentSize <= 0)
+ tuiEraseSourceContent (firstWin, EMPTY_SOURCE_PROMPT);
+ if (secondWin->generic.contentSize <= 0)
+ tuiEraseSourceContent (secondWin, EMPTY_SOURCE_PROMPT);
+ }
+ }
+ }
+
+ return status;
+} /* _tuiAdjustWinHeights */
+
+
+/*
+ ** _makeInvisibleAndSetNewHeight().
+ ** Function make the target window (and auxillary windows associated
+ ** with the targer) invisible, and set the new height and location.
+ */
+static void
+_makeInvisibleAndSetNewHeight (TuiWinInfoPtr winInfo, int height)
+{
+ int i;
+ struct symtab *s;
+ TuiGenWinInfoPtr genWinInfo;
+
+
+ m_beInvisible (&winInfo->generic);
+ winInfo->generic.height = height;
+ if (height > 1)
+ winInfo->generic.viewportHeight = height - 1;
+ else
+ winInfo->generic.viewportHeight = height;
+ if (winInfo != cmdWin)
+ winInfo->generic.viewportHeight--;
+
+ /* Now deal with the auxillary windows associated with winInfo */
+ switch (winInfo->generic.type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ genWinInfo = winInfo->detail.sourceInfo.executionInfo;
+ m_beInvisible (genWinInfo);
+ genWinInfo->height = height;
+ genWinInfo->origin.y = winInfo->generic.origin.y;
+ if (height > 1)
+ genWinInfo->viewportHeight = height - 1;
+ else
+ genWinInfo->viewportHeight = height;
+ if (winInfo != cmdWin)
+ genWinInfo->viewportHeight--;
+
+ if (m_hasLocator (winInfo))
+ {
+ genWinInfo = locatorWinInfoPtr ();
+ m_beInvisible (genWinInfo);
+ genWinInfo->origin.y = winInfo->generic.origin.y + height;
+ }
+ break;
+ case DATA_WIN:
+ /* delete all data item windows */
+ for (i = 0; i < winInfo->generic.contentSize; i++)
+ {
+ genWinInfo = (TuiGenWinInfoPtr) & ((TuiWinElementPtr)
+ winInfo->generic.content[i])->whichElement.dataWindow;
+ tuiDelwin (genWinInfo->handle);
+ genWinInfo->handle = (WINDOW *) NULL;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return;
+} /* _makeInvisibleAndSetNewHeight */
+
+
+/*
+ ** _makeVisibleWithNewHeight().
+ ** Function to make the windows with new heights visible.
+ ** This means re-creating the windows' content since the window
+ ** had to be destroyed to be made invisible.
+ */
+static void
+_makeVisibleWithNewHeight (TuiWinInfoPtr winInfo)
+{
+ int i;
+ struct symtab *s;
+
+ m_beVisible (&winInfo->generic);
+ checkAndDisplayHighlightIfNeeded (winInfo);
+ switch (winInfo->generic.type)
+ {
+ case SRC_WIN:
+ case DISASSEM_WIN:
+ freeWinContent (winInfo->detail.sourceInfo.executionInfo);
+ m_beVisible (winInfo->detail.sourceInfo.executionInfo);
+ if (winInfo->generic.content != (OpaquePtr) NULL)
+ {
+ TuiLineOrAddress lineOrAddr;
+
+ if (winInfo->generic.type == SRC_WIN)
+ lineOrAddr.lineNo =
+ winInfo->detail.sourceInfo.startLineOrAddr.lineNo;
+ else
+ lineOrAddr.addr =
+ winInfo->detail.sourceInfo.startLineOrAddr.addr;
+ freeWinContent (&winInfo->generic);
+ tuiUpdateSourceWindow (winInfo,
+ current_source_symtab, lineOrAddr, TRUE);
+ }
+ else if (selected_frame != (struct frame_info *) NULL)
+ {
+ TuiLineOrAddress line;
+ extern int current_source_line;
+
+ s = find_pc_symtab (selected_frame->pc);
+ if (winInfo->generic.type == SRC_WIN)
+ line.lineNo = current_source_line;
+ else
+ {
+ find_line_pc (s, current_source_line, &line.addr);
+ }
+ tuiUpdateSourceWindow (winInfo, s, line, TRUE);
+ }
+ if (m_hasLocator (winInfo))
+ {
+ m_beVisible (locatorWinInfoPtr ());
+ tuiClearLocatorDisplay ();
+ tuiShowLocatorContent ();
+ }
+ break;
+ case DATA_WIN:
+ tuiDisplayAllData ();
+ break;
+ case CMD_WIN:
+ winInfo->detail.commandInfo.curLine = 0;
+ winInfo->detail.commandInfo.curch = 0;
+ wmove (winInfo->generic.handle,
+ winInfo->detail.commandInfo.curLine,
+ winInfo->detail.commandInfo.curch);
+ break;
+ default:
+ break;
+ }
+
+ return;
+} /* _makeVisibleWithNewHeight */
+
+
+static int
+_newHeightOk (TuiWinInfoPtr primaryWinInfo, int newHeight)
+{
+ int ok = (newHeight < termHeight ());
+
+ if (ok)
+ {
+ int diff, curHeight;
+ TuiLayoutType curLayout = currentLayout ();
+
+ diff = (newHeight - primaryWinInfo->generic.height) * (-1);
+ if (curLayout == SRC_COMMAND || curLayout == DISASSEM_COMMAND)
+ {
+ ok = ((primaryWinInfo->generic.type == CMD_WIN &&
+ newHeight <= (termHeight () - 4) &&
+ newHeight >= MIN_CMD_WIN_HEIGHT) ||
+ (primaryWinInfo->generic.type != CMD_WIN &&
+ newHeight <= (termHeight () - 2) &&
+ newHeight >= MIN_WIN_HEIGHT));
+ if (ok)
+ { /* check the total height */
+ TuiWinInfoPtr winInfo;
+
+ if (primaryWinInfo == cmdWin)
+ winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[0];
+ else
+ winInfo = cmdWin;
+ ok = ((newHeight +
+ (winInfo->generic.height + diff)) <= termHeight ());
+ }
+ }
+ else
+ {
+ int curTotalHeight, totalHeight, minHeight;
+ TuiWinInfoPtr firstWin, secondWin;
+
+ if (curLayout == SRC_DISASSEM_COMMAND)
+ {
+ firstWin = srcWin;
+ secondWin = disassemWin;
+ }
+ else
+ {
+ firstWin = dataWin;
+ secondWin = (TuiWinInfoPtr) (sourceWindows ())->list[0];
+ }
+ /*
+ ** We could simply add all the heights to obtain the same result
+ ** but below is more explicit since we subtract 1 for the
+ ** line that the first and second windows share, and add one
+ ** for the locator.
+ */
+ curTotalHeight =
+ (firstWin->generic.height + secondWin->generic.height - 1)
+ + cmdWin->generic.height + 1 /*locator */ ;
+ if (primaryWinInfo == cmdWin)
+ {
+ /* locator included since first & second win share a line */
+ ok = ((firstWin->generic.height +
+ secondWin->generic.height + diff) >=
+ (MIN_WIN_HEIGHT * 2) &&
+ newHeight >= MIN_CMD_WIN_HEIGHT);
+ if (ok)
+ {
+ totalHeight = newHeight + (firstWin->generic.height +
+ secondWin->generic.height + diff);
+ minHeight = MIN_CMD_WIN_HEIGHT;
+ }
+ }
+ else
+ {
+ minHeight = MIN_WIN_HEIGHT;
+ /*
+ ** First see if we can increase/decrease the command
+ ** window. And make sure that the command window is
+ ** at least 1 line
+ */
+ ok = ((cmdWin->generic.height + diff) > 0);
+ if (!ok)
+ { /*
+ ** Looks like we have to increase/decrease one of
+ ** the other windows
+ */
+ if (primaryWinInfo == firstWin)
+ ok = (secondWin->generic.height + diff) >= minHeight;
+ else
+ ok = (firstWin->generic.height + diff) >= minHeight;
+ }
+ if (ok)
+ {
+ if (primaryWinInfo == firstWin)
+ totalHeight = newHeight +
+ secondWin->generic.height +
+ cmdWin->generic.height + diff;
+ else
+ totalHeight = newHeight +
+ firstWin->generic.height +
+ cmdWin->generic.height + diff;
+ }
+ }
+ /*
+ ** Now make sure that the proposed total height doesn't exceed
+ ** the old total height.
+ */
+ if (ok)
+ ok = (newHeight >= minHeight && totalHeight <= curTotalHeight);
+ }
+ }
+
+ return ok;
+} /* _newHeightOk */
+
+
+/*
+ ** _parseScrollingArgs().
+ */
+static void
+_parseScrollingArgs (char *arg, TuiWinInfoPtr * winToScroll, int *numToScroll)
+{
+ if (numToScroll)
+ *numToScroll = 0;
+ *winToScroll = tuiWinWithFocus ();
+
+ /*
+ ** First set up the default window to scroll, in case there is no
+ ** window name arg
+ */
+ if (arg != (char *) NULL)
+ {
+ char *buf, *bufPtr;
+
+ /* process the number of lines to scroll */
+ buf = bufPtr = xstrdup (arg);
+ if (isdigit (*bufPtr))
+ {
+ char *numStr;
+
+ numStr = bufPtr;
+ bufPtr = strchr (bufPtr, ' ');
+ if (bufPtr != (char *) NULL)
+ {
+ *bufPtr = (char) 0;
+ if (numToScroll)
+ *numToScroll = atoi (numStr);
+ bufPtr++;
+ }
+ else if (numToScroll)
+ *numToScroll = atoi (numStr);
+ }
+
+ /* process the window name if one is specified */
+ if (bufPtr != (char *) NULL)
+ {
+ char *wname;
+ int i;
+
+ if (*bufPtr == ' ')
+ while (*(++bufPtr) == ' ')
+ ;
+
+ if (*bufPtr != (char) 0)
+ wname = bufPtr;
+ else
+ wname = "?";
+
+ /* Validate the window name */
+ for (i = 0; i < strlen (wname); i++)
+ wname[i] = toupper (wname[i]);
+ *winToScroll = partialWinByName (wname);
+
+ if (*winToScroll == (TuiWinInfoPtr) NULL ||
+ !(*winToScroll)->generic.isVisible)
+ warning ("Invalid window specified. \n\
+The window name specified must be valid and visible.\n");
+ else if (*winToScroll == cmdWin)
+ *winToScroll = (TuiWinInfoPtr) (sourceWindows ())->list[0];
+ }
+ tuiFree (buf);
+ }
+
+ return;
+} /* _parseScrollingArgs */
diff --git a/gdb/tui/tuiWin.h b/gdb/tui/tuiWin.h
new file mode 100644
index 00000000000..ac210421e0d
--- /dev/null
+++ b/gdb/tui/tuiWin.h
@@ -0,0 +1,58 @@
+/* TUI window generic functions.
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Hewlett-Packard Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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. */
+
+#ifndef _TUI_WIN_H
+#define _TUI_WIN_H
+
+/*****************************************
+** TYPE DEFINITIONS **
+******************************************/
+
+
+
+/*****************************************
+** PUBLIC FUNCTION EXTERNAL DECLS **
+******************************************/
+extern void tuiScrollForward (TuiWinInfoPtr, int);
+extern void tuiScrollBackward (TuiWinInfoPtr, int);
+extern void tuiScrollLeft (TuiWinInfoPtr, int);
+extern void tuiScrollRight (TuiWinInfoPtr, int);
+extern void tui_scroll (TuiScrollDirection, TuiWinInfoPtr, int);
+extern void tuiSetWinFocusTo (TuiWinInfoPtr);
+extern void tuiClearWinFocusFrom (TuiWinInfoPtr);
+extern void tuiClearWinFocus (void);
+extern void tuiResizeAll (void);
+extern void tuiRefreshAll (void);
+extern void tuiSigwinchHandler (int);
+
+extern chtype tui_border_ulcorner;
+extern chtype tui_border_urcorner;
+extern chtype tui_border_lrcorner;
+extern chtype tui_border_llcorner;
+extern chtype tui_border_vline;
+extern chtype tui_border_hline;
+extern int tui_border_attrs;
+extern int tui_active_border_attrs;
+
+extern int tui_update_variables ();
+
+#endif
+/*_TUI_WIN_H*/
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
new file mode 100644
index 00000000000..b56610d3ac0
--- /dev/null
+++ b/gdb/typeprint.c
@@ -0,0 +1,379 @@
+/* Language independent support for printing types for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1998, 1999,
+ 2000, 2001 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 "defs.h"
+#include "obstack.h"
+#include "bfd.h" /* Binary File Description */
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "language.h"
+#include "cp-abi.h"
+
+#include "gdb_string.h"
+#include <errno.h>
+
+/* For real-type printing in whatis_exp() */
+extern int objectprint; /* Controls looking up an object's derived type
+ using what we find in its vtables. */
+
+extern void _initialize_typeprint (void);
+
+static void ptype_command (char *, int);
+
+static struct type *ptype_eval (struct expression *);
+
+static void whatis_command (char *, int);
+
+static void whatis_exp (char *, int);
+
+/* Print a description of a type in the format of a
+ typedef for the current language.
+ NEW is the new name for a type TYPE. */
+
+void
+typedef_print (struct type *type, struct symbol *new, struct ui_file *stream)
+{
+ CHECK_TYPEDEF (type);
+ switch (current_language->la_language)
+ {
+#ifdef _LANG_c
+ case language_c:
+ case language_cplus:
+ fprintf_filtered (stream, "typedef ");
+ type_print (type, "", stream, 0);
+ if (TYPE_NAME ((SYMBOL_TYPE (new))) == 0
+ || !STREQ (TYPE_NAME ((SYMBOL_TYPE (new))), SYMBOL_NAME (new)))
+ fprintf_filtered (stream, " %s", SYMBOL_SOURCE_NAME (new));
+ break;
+#endif
+#ifdef _LANG_m2
+ case language_m2:
+ fprintf_filtered (stream, "TYPE ");
+ if (!TYPE_NAME (SYMBOL_TYPE (new)) ||
+ !STREQ (TYPE_NAME (SYMBOL_TYPE (new)), SYMBOL_NAME (new)))
+ fprintf_filtered (stream, "%s = ", SYMBOL_SOURCE_NAME (new));
+ else
+ fprintf_filtered (stream, "<builtin> = ");
+ type_print (type, "", stream, 0);
+ break;
+#endif
+#ifdef _LANG_pascal
+ case language_pascal:
+ fprintf_filtered (stream, "type ");
+ fprintf_filtered (stream, "%s = ", SYMBOL_SOURCE_NAME (new));
+ type_print (type, "", stream, 0);
+ break;
+#endif
+#ifdef _LANG_chill
+ case language_chill:
+ fprintf_filtered (stream, "SYNMODE ");
+ if (!TYPE_NAME (SYMBOL_TYPE (new)) ||
+ !STREQ (TYPE_NAME (SYMBOL_TYPE (new)), SYMBOL_NAME (new)))
+ fprintf_filtered (stream, "%s = ", SYMBOL_SOURCE_NAME (new));
+ else
+ fprintf_filtered (stream, "<builtin> = ");
+ type_print (type, "", stream, 0);
+ break;
+#endif
+ default:
+ error ("Language not supported.");
+ }
+ fprintf_filtered (stream, ";\n");
+}
+
+/* Print a description of a type TYPE in the form of a declaration of a
+ variable named VARSTRING. (VARSTRING is demangled if necessary.)
+ Output goes to STREAM (via stdio).
+ If SHOW is positive, we show the contents of the outermost level
+ of structure even if there is a type name that could be used instead.
+ If SHOW is negative, we never show the details of elements' types. */
+
+void
+type_print (struct type *type, char *varstring, struct ui_file *stream,
+ int show)
+{
+ LA_PRINT_TYPE (type, varstring, stream, show, 0);
+}
+
+/* Print type of EXP, or last thing in value history if EXP == NULL.
+ show is passed to type_print. */
+
+static void
+whatis_exp (char *exp, int show)
+{
+ struct expression *expr;
+ struct value *val;
+ register struct cleanup *old_chain = NULL;
+ struct type *real_type = NULL;
+ struct type *type;
+ int full = 0;
+ int top = -1;
+ int using_enc = 0;
+
+ if (exp)
+ {
+ expr = parse_expression (exp);
+ old_chain = make_cleanup (free_current_contents, &expr);
+ val = evaluate_type (expr);
+ }
+ else
+ val = access_value_history (0);
+
+ type = VALUE_TYPE (val);
+
+ if (objectprint)
+ {
+ if (((TYPE_CODE (type) == TYPE_CODE_PTR) ||
+ (TYPE_CODE (type) == TYPE_CODE_REF))
+ &&
+ (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
+ {
+ real_type = value_rtti_target_type (val, &full, &top, &using_enc);
+ if (real_type)
+ {
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ real_type = lookup_pointer_type (real_type);
+ else
+ real_type = lookup_reference_type (real_type);
+ }
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_CLASS)
+ real_type = value_rtti_type (val, &full, &top, &using_enc);
+ }
+
+ printf_filtered ("type = ");
+
+ if (real_type)
+ {
+ printf_filtered ("/* real type = ");
+ type_print (real_type, "", gdb_stdout, -1);
+ if (! full)
+ printf_filtered (" (incomplete object)");
+ printf_filtered (" */\n");
+ }
+
+ type_print (type, "", gdb_stdout, show);
+ printf_filtered ("\n");
+
+ if (exp)
+ do_cleanups (old_chain);
+}
+
+/* ARGSUSED */
+static void
+whatis_command (char *exp, int from_tty)
+{
+ /* Most of the time users do not want to see all the fields
+ in a structure. If they do they can use the "ptype" command.
+ Hence the "-1" below. */
+ whatis_exp (exp, -1);
+}
+
+/* Simple subroutine for ptype_command. */
+
+static struct type *
+ptype_eval (struct expression *exp)
+{
+ if (exp->elts[0].opcode == OP_TYPE)
+ {
+ return (exp->elts[1].type);
+ }
+ else
+ {
+ return (NULL);
+ }
+}
+
+/* TYPENAME is either the name of a type, or an expression. */
+
+/* ARGSUSED */
+static void
+ptype_command (char *typename, int from_tty)
+{
+ register struct type *type;
+ struct expression *expr;
+ register struct cleanup *old_chain;
+
+ if (typename == NULL)
+ {
+ /* Print type of last thing in value history. */
+ whatis_exp (typename, 1);
+ }
+ else
+ {
+ expr = parse_expression (typename);
+ old_chain = make_cleanup (free_current_contents, &expr);
+ type = ptype_eval (expr);
+ if (type != NULL)
+ {
+ /* User did "ptype <typename>" */
+ printf_filtered ("type = ");
+ type_print (type, "", gdb_stdout, 1);
+ printf_filtered ("\n");
+ do_cleanups (old_chain);
+ }
+ else
+ {
+ /* User did "ptype <symbolname>" */
+ do_cleanups (old_chain);
+ whatis_exp (typename, 1);
+ }
+ }
+}
+
+/* Print integral scalar data VAL, of type TYPE, onto stdio stream STREAM.
+ Used to print data from type structures in a specified type. For example,
+ array bounds may be characters or booleans in some languages, and this
+ allows the ranges to be printed in their "natural" form rather than as
+ decimal integer values.
+
+ FIXME: This is here simply because only the type printing routines
+ currently use it, and it wasn't clear if it really belonged somewhere
+ else (like printcmd.c). There are a lot of other gdb routines that do
+ something similar, but they are generally concerned with printing values
+ that come from the inferior in target byte order and target size. */
+
+void
+print_type_scalar (struct type *type, LONGEST val, struct ui_file *stream)
+{
+ unsigned int i;
+ unsigned len;
+
+ CHECK_TYPEDEF (type);
+
+ switch (TYPE_CODE (type))
+ {
+
+ case TYPE_CODE_ENUM:
+ len = TYPE_NFIELDS (type);
+ for (i = 0; i < len; i++)
+ {
+ if (TYPE_FIELD_BITPOS (type, i) == val)
+ {
+ break;
+ }
+ }
+ if (i < len)
+ {
+ fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+ }
+ else
+ {
+ print_longest (stream, 'd', 0, val);
+ }
+ break;
+
+ case TYPE_CODE_INT:
+ print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0, val);
+ break;
+
+ case TYPE_CODE_CHAR:
+ LA_PRINT_CHAR ((unsigned char) val, stream);
+ break;
+
+ case TYPE_CODE_BOOL:
+ fprintf_filtered (stream, val ? "TRUE" : "FALSE");
+ break;
+
+ case TYPE_CODE_RANGE:
+ print_type_scalar (TYPE_TARGET_TYPE (type), val, stream);
+ return;
+
+ case TYPE_CODE_UNDEF:
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_FUNC:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_SET:
+ case TYPE_CODE_STRING:
+ case TYPE_CODE_ERROR:
+ case TYPE_CODE_MEMBER:
+ case TYPE_CODE_METHOD:
+ case TYPE_CODE_REF:
+ error ("internal error: unhandled type in print_type_scalar");
+ break;
+
+ default:
+ error ("Invalid type code in symbol table.");
+ }
+ gdb_flush (stream);
+}
+
+/* Dump details of a type specified either directly or indirectly.
+ Uses the same sort of type lookup mechanism as ptype_command()
+ and whatis_command(). */
+
+void
+maintenance_print_type (char *typename, int from_tty)
+{
+ struct value *val;
+ register struct type *type;
+ register struct cleanup *old_chain;
+ struct expression *expr;
+
+ if (typename != NULL)
+ {
+ expr = parse_expression (typename);
+ old_chain = make_cleanup (free_current_contents, &expr);
+ if (expr->elts[0].opcode == OP_TYPE)
+ {
+ /* The user expression names a type directly, just use that type. */
+ type = expr->elts[1].type;
+ }
+ else
+ {
+ /* The user expression may name a type indirectly by naming an
+ object of that type. Find that indirectly named type. */
+ val = evaluate_type (expr);
+ type = VALUE_TYPE (val);
+ }
+ if (type != NULL)
+ {
+ recursive_dump_type (type, 0);
+ }
+ do_cleanups (old_chain);
+ }
+}
+
+
+void
+_initialize_typeprint (void)
+{
+
+ add_com ("ptype", class_vars, ptype_command,
+ "Print definition of type TYPE.\n\
+Argument may be a type name defined by typedef, or \"struct STRUCT-TAG\"\n\
+or \"class CLASS-NAME\" or \"union UNION-TAG\" or \"enum ENUM-TAG\".\n\
+The selected stack frame's lexical context is used to look up the name.");
+
+ add_com ("whatis", class_vars, whatis_command,
+ "Print data type of expression EXP.");
+
+}
diff --git a/gdb/typeprint.h b/gdb/typeprint.h
new file mode 100644
index 00000000000..c57cc58c7ef
--- /dev/null
+++ b/gdb/typeprint.h
@@ -0,0 +1,29 @@
+/* Language independent support for printing types for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1991-1993, 1999, 2000
+ 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. */
+
+#ifndef TYPEPRINT_H
+#define TYPEPRINT_H
+
+void print_type_scalar (struct type * type, LONGEST, struct ui_file *);
+
+void c_type_print_varspec_suffix (struct type *, struct ui_file *, int,
+ int, int);
+#endif
diff --git a/gdb/ui-file.c b/gdb/ui-file.c
new file mode 100644
index 00000000000..3dbcaab1326
--- /dev/null
+++ b/gdb/ui-file.c
@@ -0,0 +1,485 @@
+/* UI_FILE - a generic STDIO like output stream.
+
+ Copyright 1999, 2000, 2001, 2002 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. */
+
+/* Implement the ``struct ui_file'' object. */
+
+#include "defs.h"
+#include "ui-file.h"
+#include "gdb_string.h"
+
+static ui_file_isatty_ftype null_file_isatty;
+static ui_file_write_ftype null_file_write;
+static ui_file_fputs_ftype null_file_fputs;
+static ui_file_flush_ftype null_file_flush;
+static ui_file_delete_ftype null_file_delete;
+static ui_file_rewind_ftype null_file_rewind;
+static ui_file_put_ftype null_file_put;
+
+struct ui_file
+ {
+ int *magic;
+ ui_file_flush_ftype *to_flush;
+ ui_file_write_ftype *to_write;
+ ui_file_fputs_ftype *to_fputs;
+ ui_file_delete_ftype *to_delete;
+ ui_file_isatty_ftype *to_isatty;
+ ui_file_rewind_ftype *to_rewind;
+ ui_file_put_ftype *to_put;
+ void *to_data;
+ };
+int ui_file_magic;
+
+struct ui_file *
+ui_file_new (void)
+{
+ struct ui_file *file = xmalloc (sizeof (struct ui_file));
+ file->magic = &ui_file_magic;
+ set_ui_file_data (file, NULL, null_file_delete);
+ set_ui_file_flush (file, null_file_flush);
+ set_ui_file_write (file, null_file_write);
+ set_ui_file_fputs (file, null_file_fputs);
+ set_ui_file_isatty (file, null_file_isatty);
+ set_ui_file_rewind (file, null_file_rewind);
+ set_ui_file_put (file, null_file_put);
+ return file;
+}
+
+void
+ui_file_delete (struct ui_file *file)
+{
+ file->to_delete (file);
+ xfree (file);
+}
+
+static int
+null_file_isatty (struct ui_file *file)
+{
+ return 0;
+}
+
+static void
+null_file_rewind (struct ui_file *file)
+{
+ return;
+}
+
+static void
+null_file_put (struct ui_file *file,
+ ui_file_put_method_ftype *write,
+ void *dest)
+{
+ return;
+}
+
+static void
+null_file_flush (struct ui_file *file)
+{
+ return;
+}
+
+static void
+null_file_write (struct ui_file *file,
+ const char *buf,
+ long sizeof_buf)
+{
+ if (file->to_fputs == null_file_fputs)
+ /* Both the write and fputs methods are null. Discard the
+ request. */
+ return;
+ else
+ {
+ /* The fputs method isn't null, slowly pass the write request
+ onto that. FYI, this isn't as bad as it may look - the
+ current (as of 1999-11-07) printf_* function calls fputc and
+ fputc does exactly the below. By having a write function it
+ is possible to clean up that code. */
+ int i;
+ char b[2];
+ b[1] = '\0';
+ for (i = 0; i < sizeof_buf; i++)
+ {
+ b[0] = buf[i];
+ file->to_fputs (b, file);
+ }
+ return;
+ }
+}
+
+static void
+null_file_fputs (const char *buf, struct ui_file *file)
+{
+ if (file->to_write == null_file_write)
+ /* Both the write and fputs methods are null. Discard the
+ request. */
+ return;
+ else
+ {
+ /* The write method was implemented, use that. */
+ file->to_write (file, buf, strlen (buf));
+ }
+}
+
+static void
+null_file_delete (struct ui_file *file)
+{
+ return;
+}
+
+void *
+ui_file_data (struct ui_file *file)
+{
+ if (file->magic != &ui_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "ui_file_data: bad magic number");
+ return file->to_data;
+}
+
+void
+gdb_flush (struct ui_file *file)
+{
+ file->to_flush (file);
+}
+
+int
+ui_file_isatty (struct ui_file *file)
+{
+ return file->to_isatty (file);
+}
+
+void
+ui_file_rewind (struct ui_file *file)
+{
+ file->to_rewind (file);
+}
+
+void
+ui_file_put (struct ui_file *file,
+ ui_file_put_method_ftype *write,
+ void *dest)
+{
+ file->to_put (file, write, dest);
+}
+
+void
+ui_file_write (struct ui_file *file,
+ const char *buf,
+ long length_buf)
+{
+ file->to_write (file, buf, length_buf);
+}
+
+void
+fputs_unfiltered (const char *buf, struct ui_file *file)
+{
+ file->to_fputs (buf, file);
+}
+
+void
+set_ui_file_flush (struct ui_file *file, ui_file_flush_ftype *flush)
+{
+ file->to_flush = flush;
+}
+
+void
+set_ui_file_isatty (struct ui_file *file, ui_file_isatty_ftype *isatty)
+{
+ file->to_isatty = isatty;
+}
+
+void
+set_ui_file_rewind (struct ui_file *file, ui_file_rewind_ftype *rewind)
+{
+ file->to_rewind = rewind;
+}
+
+void
+set_ui_file_put (struct ui_file *file, ui_file_put_ftype *put)
+{
+ file->to_put = put;
+}
+
+void
+set_ui_file_write (struct ui_file *file,
+ ui_file_write_ftype *write)
+{
+ file->to_write = write;
+}
+
+void
+set_ui_file_fputs (struct ui_file *file, ui_file_fputs_ftype *fputs)
+{
+ file->to_fputs = fputs;
+}
+
+void
+set_ui_file_data (struct ui_file *file, void *data,
+ ui_file_delete_ftype *delete)
+{
+ file->to_data = data;
+ file->to_delete = delete;
+}
+
+/* ui_file utility function for converting a ``struct ui_file'' into
+ a memory buffer''. */
+
+struct accumulated_ui_file
+{
+ char *buffer;
+ long length;
+};
+
+static void
+do_ui_file_xstrdup (void *context, const char *buffer, long length)
+{
+ struct accumulated_ui_file *acc = context;
+ if (acc->buffer == NULL)
+ acc->buffer = xmalloc (length + 1);
+ else
+ acc->buffer = xrealloc (acc->buffer, acc->length + length + 1);
+ memcpy (acc->buffer + acc->length, buffer, length);
+ acc->length += length;
+ acc->buffer[acc->length] = '\0';
+}
+
+char *
+ui_file_xstrdup (struct ui_file *file,
+ long *length)
+{
+ struct accumulated_ui_file acc;
+ acc.buffer = NULL;
+ acc.length = 0;
+ ui_file_put (file, do_ui_file_xstrdup, &acc);
+ if (acc.buffer == NULL)
+ acc.buffer = xstrdup ("");
+ *length = acc.length;
+ return acc.buffer;
+}
+
+/* A pure memory based ``struct ui_file'' that can be used an output
+ buffer. The buffers accumulated contents are available via
+ ui_file_put(). */
+
+struct mem_file
+ {
+ int *magic;
+ char *buffer;
+ int sizeof_buffer;
+ int length_buffer;
+ };
+
+static ui_file_rewind_ftype mem_file_rewind;
+static ui_file_put_ftype mem_file_put;
+static ui_file_write_ftype mem_file_write;
+static ui_file_delete_ftype mem_file_delete;
+static struct ui_file *mem_file_new (void);
+static int mem_file_magic;
+
+static struct ui_file *
+mem_file_new (void)
+{
+ struct mem_file *stream = XMALLOC (struct mem_file);
+ struct ui_file *file = ui_file_new ();
+ set_ui_file_data (file, stream, mem_file_delete);
+ set_ui_file_rewind (file, mem_file_rewind);
+ set_ui_file_put (file, mem_file_put);
+ set_ui_file_write (file, mem_file_write);
+ stream->magic = &mem_file_magic;
+ stream->buffer = NULL;
+ stream->sizeof_buffer = 0;
+ stream->length_buffer = 0;
+ return file;
+}
+
+static void
+mem_file_delete (struct ui_file *file)
+{
+ struct mem_file *stream = ui_file_data (file);
+ if (stream->magic != &mem_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "mem_file_delete: bad magic number");
+ if (stream->buffer != NULL)
+ xfree (stream->buffer);
+ xfree (stream);
+}
+
+struct ui_file *
+mem_fileopen (void)
+{
+ return mem_file_new ();
+}
+
+static void
+mem_file_rewind (struct ui_file *file)
+{
+ struct mem_file *stream = ui_file_data (file);
+ if (stream->magic != &mem_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "mem_file_rewind: bad magic number");
+ stream->length_buffer = 0;
+}
+
+static void
+mem_file_put (struct ui_file *file,
+ ui_file_put_method_ftype *write,
+ void *dest)
+{
+ struct mem_file *stream = ui_file_data (file);
+ if (stream->magic != &mem_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "mem_file_put: bad magic number");
+ if (stream->length_buffer > 0)
+ write (dest, stream->buffer, stream->length_buffer);
+}
+
+void
+mem_file_write (struct ui_file *file,
+ const char *buffer,
+ long length_buffer)
+{
+ struct mem_file *stream = ui_file_data (file);
+ if (stream->magic != &mem_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "mem_file_write: bad magic number");
+ if (stream->buffer == NULL)
+ {
+ stream->length_buffer = length_buffer;
+ stream->sizeof_buffer = length_buffer;
+ stream->buffer = xmalloc (stream->sizeof_buffer);
+ memcpy (stream->buffer, buffer, length_buffer);
+ }
+ else
+ {
+ int new_length = stream->length_buffer + length_buffer;
+ if (new_length >= stream->sizeof_buffer)
+ {
+ stream->sizeof_buffer = new_length;
+ stream->buffer = xrealloc (stream->buffer, stream->sizeof_buffer);
+ }
+ memcpy (stream->buffer + stream->length_buffer, buffer, length_buffer);
+ stream->length_buffer = new_length;
+ }
+}
+
+/* ``struct ui_file'' implementation that maps directly onto
+ <stdio.h>'s FILE. */
+
+static ui_file_write_ftype stdio_file_write;
+static ui_file_fputs_ftype stdio_file_fputs;
+static ui_file_isatty_ftype stdio_file_isatty;
+static ui_file_delete_ftype stdio_file_delete;
+static struct ui_file *stdio_file_new (FILE * file, int close_p);
+static ui_file_flush_ftype stdio_file_flush;
+
+static int stdio_file_magic;
+
+struct stdio_file
+ {
+ int *magic;
+ FILE *file;
+ int close_p;
+ };
+
+static struct ui_file *
+stdio_file_new (FILE *file, int close_p)
+{
+ struct ui_file *ui_file = ui_file_new ();
+ struct stdio_file *stdio = xmalloc (sizeof (struct stdio_file));
+ stdio->magic = &stdio_file_magic;
+ stdio->file = file;
+ stdio->close_p = close_p;
+ set_ui_file_data (ui_file, stdio, stdio_file_delete);
+ set_ui_file_flush (ui_file, stdio_file_flush);
+ set_ui_file_write (ui_file, stdio_file_write);
+ set_ui_file_fputs (ui_file, stdio_file_fputs);
+ set_ui_file_isatty (ui_file, stdio_file_isatty);
+ return ui_file;
+}
+
+static void
+stdio_file_delete (struct ui_file *file)
+{
+ struct stdio_file *stdio = ui_file_data (file);
+ if (stdio->magic != &stdio_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "stdio_file_delete: bad magic number");
+ if (stdio->close_p)
+ {
+ fclose (stdio->file);
+ }
+ xfree (stdio);
+}
+
+static void
+stdio_file_flush (struct ui_file *file)
+{
+ struct stdio_file *stdio = ui_file_data (file);
+ if (stdio->magic != &stdio_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "stdio_file_flush: bad magic number");
+ fflush (stdio->file);
+}
+
+static void
+stdio_file_write (struct ui_file *file, const char *buf, long length_buf)
+{
+ struct stdio_file *stdio = ui_file_data (file);
+ if (stdio->magic != &stdio_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "stdio_file_write: bad magic number");
+ fwrite (buf, length_buf, 1, stdio->file);
+}
+
+static void
+stdio_file_fputs (const char *linebuffer, struct ui_file *file)
+{
+ struct stdio_file *stdio = ui_file_data (file);
+ if (stdio->magic != &stdio_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "stdio_file_fputs: bad magic number");
+ fputs (linebuffer, stdio->file);
+}
+
+static int
+stdio_file_isatty (struct ui_file *file)
+{
+ struct stdio_file *stdio = ui_file_data (file);
+ if (stdio->magic != &stdio_file_magic)
+ internal_error (__FILE__, __LINE__,
+ "stdio_file_isatty: bad magic number");
+ return (isatty (fileno (stdio->file)));
+}
+
+/* Like fdopen(). Create a ui_file from a previously opened FILE. */
+
+struct ui_file *
+stdio_fileopen (FILE *file)
+{
+ return stdio_file_new (file, 0);
+}
+
+struct ui_file *
+gdb_fopen (char *name, char *mode)
+{
+ FILE *f = fopen (name, mode);
+ if (f == NULL)
+ return NULL;
+ return stdio_file_new (f, 1);
+}
diff --git a/gdb/ui-file.h b/gdb/ui-file.h
new file mode 100644
index 00000000000..3c351939797
--- /dev/null
+++ b/gdb/ui-file.h
@@ -0,0 +1,93 @@
+/* UI_FILE - a generic STDIO like output stream.
+ Copyright 1999, 2000 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. */
+
+#ifndef UI_FILE_H
+#define UI_FILE_H
+
+struct ui_file;
+
+/* Create a generic ui_file object with null methods. */
+
+extern struct ui_file *ui_file_new (void);
+
+/* Override methods used by specific implementations of a UI_FILE
+ object. */
+
+typedef void (ui_file_flush_ftype) (struct ui_file * stream);
+extern void set_ui_file_flush (struct ui_file *stream, ui_file_flush_ftype * flush);
+
+/* NOTE: Both fputs and write methods are available. Default
+ implementations that mapping one onto the other are included. */
+typedef void (ui_file_write_ftype) (struct ui_file * stream, const char *buf, long length_buf);
+extern void set_ui_file_write (struct ui_file *stream, ui_file_write_ftype *fputs);
+
+typedef void (ui_file_fputs_ftype) (const char *, struct ui_file * stream);
+extern void set_ui_file_fputs (struct ui_file *stream, ui_file_fputs_ftype * fputs);
+
+typedef int (ui_file_isatty_ftype) (struct ui_file * stream);
+extern void set_ui_file_isatty (struct ui_file *stream, ui_file_isatty_ftype * isatty);
+
+typedef void (ui_file_rewind_ftype) (struct ui_file * stream);
+extern void set_ui_file_rewind (struct ui_file *stream, ui_file_rewind_ftype * rewind);
+
+typedef void (ui_file_put_method_ftype) (void *object, const char *buffer, long length_buffer);
+typedef void (ui_file_put_ftype) (struct ui_file *stream, ui_file_put_method_ftype * method, void *context);
+extern void set_ui_file_put (struct ui_file *stream, ui_file_put_ftype * put);
+
+typedef void (ui_file_delete_ftype) (struct ui_file * stream);
+extern void set_ui_file_data (struct ui_file *stream, void *data, ui_file_delete_ftype * delete);
+
+extern void *ui_file_data (struct ui_file *file);
+
+
+extern void gdb_flush (struct ui_file *);
+
+extern void ui_file_delete (struct ui_file *stream);
+
+extern void ui_file_rewind (struct ui_file *stream);
+
+extern int ui_file_isatty (struct ui_file *);
+
+extern void ui_file_write (struct ui_file *file, const char *buf, long length_buf);
+
+/* NOTE: copies left to right */
+extern void ui_file_put (struct ui_file *src, ui_file_put_method_ftype *write, void *dest);
+
+/* Returns a freshly allocated buffer containing the entire contents
+ of FILE (as determined by ui_file_put()) with a NUL character
+ appended. LENGTH is set to the size of the buffer minus that
+ appended NUL. */
+extern char *ui_file_xstrdup (struct ui_file *file, long *length);
+
+
+
+/* Create/open a memory based file. Can be used as a scratch buffer
+ for collecting output. */
+extern struct ui_file *mem_fileopen (void);
+
+
+
+/* Open/create a an STDIO based UI_FILE using the already open FILE. */
+extern struct ui_file *stdio_fileopen (FILE *file);
+
+/* Open NAME returning an STDIO based UI_FILE. */
+extern struct ui_file *gdb_fopen (char *name, char *mode);
+
+#endif
diff --git a/gdb/ui-out.c b/gdb/ui-out.c
new file mode 100644
index 00000000000..c07d6952e6c
--- /dev/null
+++ b/gdb/ui-out.c
@@ -0,0 +1,1149 @@
+/* Output generating routines for GDB.
+
+ Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Solutions.
+ Written by Fernando Nasser for Cygnus.
+
+ 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 "defs.h"
+#include "gdb_string.h"
+#include "expression.h" /* For language.h */
+#include "language.h"
+#include "ui-out.h"
+#include "gdb_assert.h"
+
+/* table header structures */
+
+struct ui_out_hdr
+ {
+ int colno;
+ int width;
+ int alignment;
+ char *col_name;
+ char *colhdr;
+ struct ui_out_hdr *next;
+ };
+
+/* Maintain a stack so that the info applicable to the inner most list
+ is always available. Stack/nested level 0 is reserved for the
+ top-level result. */
+
+enum { MAX_UI_OUT_LEVELS = 5 };
+
+struct ui_out_level
+ {
+ /* Count each field; the first element is for non-list fields */
+ int field_count;
+ /* The type of this level. */
+ enum ui_out_type type;
+ };
+
+/* Tables are special. Maintain a separate structure that tracks
+ their state. At present an output can only contain a single table
+ but that restriction might eventually be lifted. */
+
+struct ui_out_table
+{
+ /* If on, a table is being generated. */
+ int flag;
+
+ /* If on, the body of a table is being generated. If off, the table
+ header is being generated. */
+ int body_flag;
+
+ /* The level at which each entry of the table is to be found. A row
+ (a tuple) is made up of entries. Consequently ENTRY_LEVEL is one
+ above that of the table. */
+ int entry_level;
+
+ /* Number of table columns (as specified in the table_begin call). */
+ int columns;
+
+ /* String identifying the table (as specified in the table_begin
+ call). */
+ char *id;
+
+ /* Points to the first table header (if any). */
+ struct ui_out_hdr *header_first;
+
+ /* Points to the last table header (if any). */
+ struct ui_out_hdr *header_last;
+
+ /* Points to header of NEXT column to format. */
+ struct ui_out_hdr *header_next;
+
+};
+
+
+/* The ui_out structure */
+/* Any change here requires a corresponding one in the initialization
+ of the default uiout, which is statically initialized */
+
+struct ui_out
+ {
+ int flags;
+ /* specific implementation of ui-out */
+ struct ui_out_impl *impl;
+ struct ui_out_data *data;
+
+ /* Sub structure tracking the ui-out depth. */
+ int level;
+ struct ui_out_level levels[MAX_UI_OUT_LEVELS];
+
+ /* A table, if any. At present only a single table is supported. */
+ struct ui_out_table table;
+ };
+
+/* The current (inner most) level. */
+static struct ui_out_level *
+current_level (struct ui_out *uiout)
+{
+ return &uiout->levels[uiout->level];
+}
+
+/* Create a new level, of TYPE. Return the new level's index. */
+static int
+push_level (struct ui_out *uiout,
+ enum ui_out_type type,
+ const char *id)
+{
+ struct ui_out_level *current;
+ /* We had better not overflow the buffer. */
+ uiout->level++;
+ gdb_assert (uiout->level >= 0 && uiout->level < MAX_UI_OUT_LEVELS);
+ current = current_level (uiout);
+ current->field_count = 0;
+ current->type = type;
+ return uiout->level;
+}
+
+/* Discard the current level, return the discarded level's index.
+ TYPE is the type of the level being discarded. */
+static int
+pop_level (struct ui_out *uiout,
+ enum ui_out_type type)
+{
+ /* We had better not underflow the buffer. */
+ gdb_assert (uiout->level > 0 && uiout->level < MAX_UI_OUT_LEVELS);
+ gdb_assert (current_level (uiout)->type == type);
+ uiout->level--;
+ return uiout->level + 1;
+}
+
+
+/* These are the default implementation functions */
+
+static void default_table_begin (struct ui_out *uiout, int nbrofcols,
+ int nr_rows, const char *tblid);
+static void default_table_body (struct ui_out *uiout);
+static void default_table_end (struct ui_out *uiout);
+static void default_table_header (struct ui_out *uiout, int width,
+ enum ui_align alig, const char *col_name,
+ const char *colhdr);
+static void default_begin (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level, const char *id);
+static void default_end (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level);
+static void default_field_int (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alig,
+ const char *fldname,
+ int value);
+static void default_field_skip (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alig,
+ const char *fldname);
+static void default_field_string (struct ui_out *uiout, int fldno, int width,
+ enum ui_align align,
+ const char *fldname,
+ const char *string);
+static void default_field_fmt (struct ui_out *uiout, int fldno,
+ int width, enum ui_align align,
+ const char *fldname,
+ const char *format,
+ va_list args);
+static void default_spaces (struct ui_out *uiout, int numspaces);
+static void default_text (struct ui_out *uiout, const char *string);
+static void default_message (struct ui_out *uiout, int verbosity,
+ const char *format,
+ va_list args);
+static void default_wrap_hint (struct ui_out *uiout, char *identstring);
+static void default_flush (struct ui_out *uiout);
+
+/* This is the default ui-out implementation functions vector */
+
+struct ui_out_impl default_ui_out_impl =
+{
+ default_table_begin,
+ default_table_body,
+ default_table_end,
+ default_table_header,
+ default_begin,
+ default_end,
+ default_field_int,
+ default_field_skip,
+ default_field_string,
+ default_field_fmt,
+ default_spaces,
+ default_text,
+ default_message,
+ default_wrap_hint,
+ default_flush,
+ 0, /* Does not need MI hacks. */
+};
+
+/* The default ui_out */
+
+struct ui_out def_uiout =
+{
+ 0, /* flags */
+ &default_ui_out_impl, /* impl */
+};
+
+/* Pointer to current ui_out */
+/* FIXME: This should not be a global, but something passed down from main.c
+ or top.c */
+
+struct ui_out *uiout = &def_uiout;
+
+/* These are the interfaces to implementation functions */
+
+static void uo_table_begin (struct ui_out *uiout, int nbrofcols,
+ int nr_rows, const char *tblid);
+static void uo_table_body (struct ui_out *uiout);
+static void uo_table_end (struct ui_out *uiout);
+static void uo_table_header (struct ui_out *uiout, int width,
+ enum ui_align align, const char *col_name,
+ const char *colhdr);
+static void uo_begin (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level, const char *id);
+static void uo_end (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level);
+static void uo_field_int (struct ui_out *uiout, int fldno, int width,
+ enum ui_align align, const char *fldname, int value);
+static void uo_field_skip (struct ui_out *uiout, int fldno, int width,
+ enum ui_align align, const char *fldname);
+static void uo_field_string (struct ui_out *uiout, int fldno, int width,
+ enum ui_align align, const char *fldname,
+ const char *string);
+static void uo_field_fmt (struct ui_out *uiout, int fldno, int width,
+ enum ui_align align, const char *fldname,
+ const char *format, va_list args);
+static void uo_spaces (struct ui_out *uiout, int numspaces);
+static void uo_text (struct ui_out *uiout, const char *string);
+static void uo_message (struct ui_out *uiout, int verbosity,
+ const char *format, va_list args);
+static void uo_wrap_hint (struct ui_out *uiout, char *identstring);
+static void uo_flush (struct ui_out *uiout);
+
+/* Prototypes for local functions */
+
+extern void _initialize_ui_out (void);
+static void append_header_to_list (struct ui_out *uiout, int width,
+ int alignment, const char *col_name,
+ const char *colhdr);
+static int get_next_header (struct ui_out *uiout, int *colno, int *width,
+ int *alignment, char **colhdr);
+static void clear_header_list (struct ui_out *uiout);
+static void verify_field (struct ui_out *uiout, int *fldno, int *width,
+ int *align);
+
+static void init_ui_out_state (struct ui_out *uiout);
+
+/* exported functions (ui_out API) */
+
+/* Mark beginning of a table */
+
+void
+ui_out_table_begin (struct ui_out *uiout, int nbrofcols,
+ int nr_rows,
+ const char *tblid)
+{
+ if (uiout->table.flag)
+ internal_error (__FILE__, __LINE__,
+ "tables cannot be nested; table_begin found before \
+previous table_end.");
+
+ uiout->table.flag = 1;
+ uiout->table.body_flag = 0;
+ uiout->table.entry_level = uiout->level + 1;
+ uiout->table.columns = nbrofcols;
+ if (tblid != NULL)
+ uiout->table.id = xstrdup (tblid);
+ else
+ uiout->table.id = NULL;
+ clear_header_list (uiout);
+
+ uo_table_begin (uiout, nbrofcols, nr_rows, uiout->table.id);
+}
+
+void
+ui_out_table_body (struct ui_out *uiout)
+{
+ if (!uiout->table.flag)
+ internal_error (__FILE__, __LINE__,
+ "table_body outside a table is not valid; it must be \
+after a table_begin and before a table_end.");
+ if (uiout->table.body_flag)
+ internal_error (__FILE__, __LINE__,
+ "extra table_body call not allowed; there must be \
+only one table_body after a table_begin and before a table_end.");
+ if (uiout->table.header_next->colno != uiout->table.columns)
+ internal_error (__FILE__, __LINE__,
+ "number of headers differ from number of table \
+columns.");
+
+ uiout->table.body_flag = 1;
+ uiout->table.header_next = uiout->table.header_first;
+
+ uo_table_body (uiout);
+}
+
+void
+ui_out_table_end (struct ui_out *uiout)
+{
+ if (!uiout->table.flag)
+ internal_error (__FILE__, __LINE__,
+ "misplaced table_end or missing table_begin.");
+
+ uiout->table.entry_level = 0;
+ uiout->table.body_flag = 0;
+ uiout->table.flag = 0;
+
+ uo_table_end (uiout);
+
+ if (uiout->table.id)
+ xfree (uiout->table.id);
+ clear_header_list (uiout);
+}
+
+void
+ui_out_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
+ const char *col_name,
+ const char *colhdr)
+{
+ if (!uiout->table.flag || uiout->table.body_flag)
+ internal_error (__FILE__, __LINE__,
+ "table header must be specified after table_begin \
+and before table_body.");
+
+ append_header_to_list (uiout, width, alignment, col_name, colhdr);
+
+ uo_table_header (uiout, width, alignment, col_name, colhdr);
+}
+
+void
+ui_out_begin (struct ui_out *uiout,
+ enum ui_out_type type,
+ const char *id)
+{
+ int new_level;
+ if (uiout->table.flag && !uiout->table.body_flag)
+ internal_error (__FILE__, __LINE__,
+ "table header or table_body expected; lists must be \
+specified after table_body.");
+
+ /* Be careful to verify the ``field'' before the new tuple/list is
+ pushed onto the stack. That way the containing list/table/row is
+ verified and not the newly created tuple/list. This verification
+ is needed (at least) for the case where a table row entry
+ contains either a tuple/list. For that case bookkeeping such as
+ updating the column count or advancing to the next heading still
+ needs to be performed. */
+ {
+ int fldno;
+ int width;
+ int align;
+ verify_field (uiout, &fldno, &width, &align);
+ }
+
+ new_level = push_level (uiout, type, id);
+
+ /* If the push puts us at the same level as a table row entry, we've
+ got a new table row. Put the header pointer back to the start. */
+ if (uiout->table.body_flag
+ && uiout->table.entry_level == new_level)
+ uiout->table.header_next = uiout->table.header_first;
+
+ uo_begin (uiout, type, new_level, id);
+}
+
+void
+ui_out_list_begin (struct ui_out *uiout,
+ const char *id)
+{
+ ui_out_begin (uiout, ui_out_type_list, id);
+}
+
+void
+ui_out_tuple_begin (struct ui_out *uiout, const char *id)
+{
+ ui_out_begin (uiout, ui_out_type_tuple, id);
+}
+
+void
+ui_out_end (struct ui_out *uiout,
+ enum ui_out_type type)
+{
+ int old_level = pop_level (uiout, type);
+ uo_end (uiout, type, old_level);
+}
+
+void
+ui_out_list_end (struct ui_out *uiout)
+{
+ ui_out_end (uiout, ui_out_type_list);
+}
+
+void
+ui_out_tuple_end (struct ui_out *uiout)
+{
+ ui_out_end (uiout, ui_out_type_tuple);
+}
+
+struct ui_out_end_cleanup_data
+{
+ struct ui_out *uiout;
+ enum ui_out_type type;
+};
+
+static void
+do_cleanup_end (void *data)
+{
+ struct ui_out_end_cleanup_data *end_cleanup_data = data;
+ ui_out_end (end_cleanup_data->uiout, end_cleanup_data->type);
+ xfree (end_cleanup_data);
+}
+
+static struct cleanup *
+make_cleanup_ui_out_end (struct ui_out *uiout,
+ enum ui_out_type type)
+{
+ struct ui_out_end_cleanup_data *end_cleanup_data;
+ end_cleanup_data = XMALLOC (struct ui_out_end_cleanup_data);
+ end_cleanup_data->uiout = uiout;
+ end_cleanup_data->type = type;
+ return make_cleanup (do_cleanup_end, end_cleanup_data);
+}
+
+struct cleanup *
+make_cleanup_ui_out_begin_end (struct ui_out *uiout,
+ enum ui_out_type type,
+ const char *id)
+{
+ ui_out_begin (uiout, type, id);
+ return make_cleanup_ui_out_end (uiout, type);
+}
+
+struct cleanup *
+make_cleanup_ui_out_tuple_begin_end (struct ui_out *uiout,
+ const char *id)
+{
+ ui_out_tuple_begin (uiout, id);
+ return make_cleanup_ui_out_end (uiout, ui_out_type_tuple);
+}
+
+struct cleanup *
+make_cleanup_ui_out_list_begin_end (struct ui_out *uiout,
+ const char *id)
+{
+ ui_out_list_begin (uiout, id);
+ return make_cleanup_ui_out_end (uiout, ui_out_type_list);
+}
+
+void
+ui_out_field_int (struct ui_out *uiout,
+ const char *fldname,
+ int value)
+{
+ int fldno;
+ int width;
+ int align;
+ struct ui_out_level *current = current_level (uiout);
+
+ verify_field (uiout, &fldno, &width, &align);
+
+ uo_field_int (uiout, fldno, width, align, fldname, value);
+}
+
+void
+ui_out_field_core_addr (struct ui_out *uiout,
+ const char *fldname,
+ CORE_ADDR address)
+{
+ char addstr[20];
+
+ /* FIXME: cagney/2002-05-03: Need local_address_string() function
+ that returns the language localized string formatted to a width
+ based on TARGET_ADDR_BIT. */
+ /* print_address_numeric (address, 1, local_stream); */
+ if (TARGET_ADDR_BIT <= 32)
+ strcpy (addstr, local_hex_string_custom ((unsigned long) address, "08l"));
+ else
+ strcpy (addstr, local_hex_string_custom ((unsigned long) address, "016l"));
+
+ ui_out_field_string (uiout, fldname, addstr);
+}
+
+void
+ui_out_field_stream (struct ui_out *uiout,
+ const char *fldname,
+ struct ui_stream *buf)
+{
+ long length;
+ char *buffer = ui_file_xstrdup (buf->stream, &length);
+ struct cleanup *old_cleanup = make_cleanup (xfree, buffer);
+ if (length > 0)
+ ui_out_field_string (uiout, fldname, buffer);
+ else
+ ui_out_field_skip (uiout, fldname);
+ ui_file_rewind (buf->stream);
+ do_cleanups (old_cleanup);
+}
+
+/* used to ommit a field */
+
+void
+ui_out_field_skip (struct ui_out *uiout,
+ const char *fldname)
+{
+ int fldno;
+ int width;
+ int align;
+
+ verify_field (uiout, &fldno, &width, &align);
+
+ uo_field_skip (uiout, fldno, width, align, fldname);
+}
+
+void
+ui_out_field_string (struct ui_out *uiout,
+ const char *fldname,
+ const char *string)
+{
+ int fldno;
+ int width;
+ int align;
+
+ verify_field (uiout, &fldno, &width, &align);
+
+ uo_field_string (uiout, fldno, width, align, fldname, string);
+}
+
+/* VARARGS */
+void
+ui_out_field_fmt (struct ui_out *uiout,
+ const char *fldname,
+ const char *format, ...)
+{
+ va_list args;
+ int fldno;
+ int width;
+ int align;
+
+ /* will not align, but has to call anyway */
+ verify_field (uiout, &fldno, &width, &align);
+
+ va_start (args, format);
+
+ uo_field_fmt (uiout, fldno, width, align, fldname, format, args);
+
+ va_end (args);
+}
+
+void
+ui_out_spaces (struct ui_out *uiout, int numspaces)
+{
+ uo_spaces (uiout, numspaces);
+}
+
+void
+ui_out_text (struct ui_out *uiout,
+ const char *string)
+{
+ uo_text (uiout, string);
+}
+
+void
+ui_out_message (struct ui_out *uiout, int verbosity,
+ const char *format,...)
+{
+ va_list args;
+
+ va_start (args, format);
+
+ uo_message (uiout, verbosity, format, args);
+
+ va_end (args);
+}
+
+struct ui_stream *
+ui_out_stream_new (struct ui_out *uiout)
+{
+ struct ui_stream *tempbuf;
+
+ tempbuf = XMALLOC (struct ui_stream);
+ tempbuf->uiout = uiout;
+ tempbuf->stream = mem_fileopen ();
+ return tempbuf;
+}
+
+void
+ui_out_stream_delete (struct ui_stream *buf)
+{
+ ui_file_delete (buf->stream);
+ xfree (buf);
+}
+
+static void
+do_stream_delete (void *buf)
+{
+ ui_out_stream_delete (buf);
+}
+
+struct cleanup *
+make_cleanup_ui_out_stream_delete (struct ui_stream *buf)
+{
+ return make_cleanup (do_stream_delete, buf);
+}
+
+
+void
+ui_out_wrap_hint (struct ui_out *uiout, char *identstring)
+{
+ uo_wrap_hint (uiout, identstring);
+}
+
+void
+ui_out_flush (struct ui_out *uiout)
+{
+ uo_flush (uiout);
+}
+
+/* set the flags specified by the mask given */
+int
+ui_out_set_flags (struct ui_out *uiout, int mask)
+{
+ int oldflags = uiout->flags;
+
+ uiout->flags |= mask;
+
+ return oldflags;
+}
+
+/* clear the flags specified by the mask given */
+int
+ui_out_clear_flags (struct ui_out *uiout, int mask)
+{
+ int oldflags = uiout->flags;
+
+ uiout->flags &= ~mask;
+
+ return oldflags;
+}
+
+/* test the flags against the mask given */
+int
+ui_out_test_flags (struct ui_out *uiout, int mask)
+{
+ return (uiout->flags & mask);
+}
+
+/* obtain the current verbosity level (as stablished by the
+ 'set verbositylevel' command */
+
+int
+ui_out_get_verblvl (struct ui_out *uiout)
+{
+ /* FIXME: not implemented yet */
+ return 0;
+}
+
+#if 0
+void
+ui_out_result_begin (struct ui_out *uiout, char *class)
+{
+}
+
+void
+ui_out_result_end (struct ui_out *uiout)
+{
+}
+
+void
+ui_out_info_begin (struct ui_out *uiout, char *class)
+{
+}
+
+void
+ui_out_info_end (struct ui_out *uiout)
+{
+}
+
+void
+ui_out_notify_begin (struct ui_out *uiout, char *class)
+{
+}
+
+void
+ui_out_notify_end (struct ui_out *uiout)
+{
+}
+
+void
+ui_out_error_begin (struct ui_out *uiout, char *class)
+{
+}
+
+void
+ui_out_error_end (struct ui_out *uiout)
+{
+}
+#endif
+
+#if 0
+void
+gdb_error (ui_out * uiout, int severity, char *format,...)
+{
+ va_list args;
+}
+
+void
+gdb_query (struct ui_out *uiout, int qflags, char *qprompt)
+{
+}
+#endif
+
+int
+ui_out_is_mi_like_p (struct ui_out *uiout)
+{
+ return uiout->impl->is_mi_like_p;
+}
+
+/* default gdb-out hook functions */
+
+static void
+default_table_begin (struct ui_out *uiout, int nbrofcols,
+ int nr_rows,
+ const char *tblid)
+{
+}
+
+static void
+default_table_body (struct ui_out *uiout)
+{
+}
+
+static void
+default_table_end (struct ui_out *uiout)
+{
+}
+
+static void
+default_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
+ const char *col_name,
+ const char *colhdr)
+{
+}
+
+static void
+default_begin (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level,
+ const char *id)
+{
+}
+
+static void
+default_end (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level)
+{
+}
+
+static void
+default_field_int (struct ui_out *uiout, int fldno, int width,
+ enum ui_align align,
+ const char *fldname, int value)
+{
+}
+
+static void
+default_field_skip (struct ui_out *uiout, int fldno, int width,
+ enum ui_align align, const char *fldname)
+{
+}
+
+static void
+default_field_string (struct ui_out *uiout,
+ int fldno,
+ int width,
+ enum ui_align align,
+ const char *fldname,
+ const char *string)
+{
+}
+
+static void
+default_field_fmt (struct ui_out *uiout, int fldno, int width,
+ enum ui_align align,
+ const char *fldname,
+ const char *format,
+ va_list args)
+{
+}
+
+static void
+default_spaces (struct ui_out *uiout, int numspaces)
+{
+}
+
+static void
+default_text (struct ui_out *uiout, const char *string)
+{
+}
+
+static void
+default_message (struct ui_out *uiout, int verbosity,
+ const char *format,
+ va_list args)
+{
+}
+
+static void
+default_wrap_hint (struct ui_out *uiout, char *identstring)
+{
+}
+
+static void
+default_flush (struct ui_out *uiout)
+{
+}
+
+/* Interface to the implementation functions */
+
+void
+uo_table_begin (struct ui_out *uiout, int nbrofcols,
+ int nr_rows,
+ const char *tblid)
+{
+ if (!uiout->impl->table_begin)
+ return;
+ uiout->impl->table_begin (uiout, nbrofcols, nr_rows, tblid);
+}
+
+void
+uo_table_body (struct ui_out *uiout)
+{
+ if (!uiout->impl->table_body)
+ return;
+ uiout->impl->table_body (uiout);
+}
+
+void
+uo_table_end (struct ui_out *uiout)
+{
+ if (!uiout->impl->table_end)
+ return;
+ uiout->impl->table_end (uiout);
+}
+
+void
+uo_table_header (struct ui_out *uiout, int width, enum ui_align align,
+ const char *col_name,
+ const char *colhdr)
+{
+ if (!uiout->impl->table_header)
+ return;
+ uiout->impl->table_header (uiout, width, align, col_name, colhdr);
+}
+
+void
+uo_begin (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level,
+ const char *id)
+{
+ if (uiout->impl->begin == NULL)
+ return;
+ uiout->impl->begin (uiout, type, level, id);
+}
+
+void
+uo_end (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level)
+{
+ if (uiout->impl->end == NULL)
+ return;
+ uiout->impl->end (uiout, type, level);
+}
+
+void
+uo_field_int (struct ui_out *uiout, int fldno, int width, enum ui_align align,
+ const char *fldname,
+ int value)
+{
+ if (!uiout->impl->field_int)
+ return;
+ uiout->impl->field_int (uiout, fldno, width, align, fldname, value);
+}
+
+void
+uo_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align align,
+ const char *fldname)
+{
+ if (!uiout->impl->field_skip)
+ return;
+ uiout->impl->field_skip (uiout, fldno, width, align, fldname);
+}
+
+void
+uo_field_string (struct ui_out *uiout, int fldno, int width,
+ enum ui_align align,
+ const char *fldname,
+ const char *string)
+{
+ if (!uiout->impl->field_string)
+ return;
+ uiout->impl->field_string (uiout, fldno, width, align, fldname, string);
+}
+
+void
+uo_field_fmt (struct ui_out *uiout, int fldno, int width, enum ui_align align,
+ const char *fldname,
+ const char *format,
+ va_list args)
+{
+ if (!uiout->impl->field_fmt)
+ return;
+ uiout->impl->field_fmt (uiout, fldno, width, align, fldname, format, args);
+}
+
+void
+uo_spaces (struct ui_out *uiout, int numspaces)
+{
+ if (!uiout->impl->spaces)
+ return;
+ uiout->impl->spaces (uiout, numspaces);
+}
+
+void
+uo_text (struct ui_out *uiout,
+ const char *string)
+{
+ if (!uiout->impl->text)
+ return;
+ uiout->impl->text (uiout, string);
+}
+
+void
+uo_message (struct ui_out *uiout, int verbosity,
+ const char *format,
+ va_list args)
+{
+ if (!uiout->impl->message)
+ return;
+ uiout->impl->message (uiout, verbosity, format, args);
+}
+
+void
+uo_wrap_hint (struct ui_out *uiout, char *identstring)
+{
+ if (!uiout->impl->wrap_hint)
+ return;
+ uiout->impl->wrap_hint (uiout, identstring);
+}
+
+void
+uo_flush (struct ui_out *uiout)
+{
+ if (!uiout->impl->flush)
+ return;
+ uiout->impl->flush (uiout);
+}
+
+/* local functions */
+
+/* list of column headers manipulation routines */
+
+static void
+clear_header_list (struct ui_out *uiout)
+{
+ while (uiout->table.header_first != NULL)
+ {
+ uiout->table.header_next = uiout->table.header_first;
+ uiout->table.header_first = uiout->table.header_first->next;
+ if (uiout->table.header_next->colhdr != NULL)
+ xfree (uiout->table.header_next->colhdr);
+ xfree (uiout->table.header_next);
+ }
+ gdb_assert (uiout->table.header_first == NULL);
+ uiout->table.header_last = NULL;
+ uiout->table.header_next = NULL;
+}
+
+static void
+append_header_to_list (struct ui_out *uiout,
+ int width,
+ int alignment,
+ const char *col_name,
+ const char *colhdr)
+{
+ struct ui_out_hdr *temphdr;
+
+ temphdr = XMALLOC (struct ui_out_hdr);
+ temphdr->width = width;
+ temphdr->alignment = alignment;
+ /* we have to copy the column title as the original may be an automatic */
+ if (colhdr != NULL)
+ temphdr->colhdr = xstrdup (colhdr);
+ else
+ temphdr->colhdr = NULL;
+ if (col_name != NULL)
+ temphdr->col_name = xstrdup (colhdr);
+ else
+ temphdr->col_name = xstrdup (colhdr);
+ temphdr->next = NULL;
+ if (uiout->table.header_first == NULL)
+ {
+ temphdr->colno = 1;
+ uiout->table.header_first = temphdr;
+ uiout->table.header_last = temphdr;
+ }
+ else
+ {
+ temphdr->colno = uiout->table.header_last->colno + 1;
+ uiout->table.header_last->next = temphdr;
+ uiout->table.header_last = temphdr;
+ }
+ uiout->table.header_next = uiout->table.header_last;
+}
+
+/* Extract the format information for the NEXT header and and advance
+ the header pointer. Return 0 if there was no next header. */
+
+static int
+get_next_header (struct ui_out *uiout,
+ int *colno,
+ int *width,
+ int *alignment,
+ char **colhdr)
+{
+ /* There may be no headers at all or we may have used all columns. */
+ if (uiout->table.header_next == NULL)
+ return 0;
+ *colno = uiout->table.header_next->colno;
+ *width = uiout->table.header_next->width;
+ *alignment = uiout->table.header_next->alignment;
+ *colhdr = uiout->table.header_next->colhdr;
+ /* Advance the header pointer to the next entry. */
+ uiout->table.header_next = uiout->table.header_next->next;
+ return 1;
+}
+
+
+/* Verify that the field/tuple/list is correctly positioned. Return
+ the field number and corresponding alignment (if
+ available/applicable). */
+
+static void
+verify_field (struct ui_out *uiout, int *fldno, int *width, int *align)
+{
+ struct ui_out_level *current = current_level (uiout);
+ char *text;
+
+ if (uiout->table.flag)
+ {
+ if (!uiout->table.body_flag)
+ internal_error (__FILE__, __LINE__,
+ "table_body missing; table fields must be \
+specified after table_body and inside a list.");
+ /* NOTE: cagney/2001-12-08: There was a check here to ensure
+ that this code was only executed when uiout->level was
+ greater than zero. That no longer applies - this code is run
+ before each table row tuple is started and at that point the
+ level is zero. */
+ }
+
+ current->field_count += 1;
+
+ if (uiout->table.body_flag
+ && uiout->table.entry_level == uiout->level
+ && get_next_header (uiout, fldno, width, align, &text))
+ {
+ if (*fldno != current->field_count)
+ internal_error (__FILE__, __LINE__,
+ "ui-out internal error in handling headers.");
+ }
+ else
+ {
+ *width = 0;
+ *align = ui_noalign;
+ *fldno = current->field_count;
+ }
+}
+
+
+/* access to ui_out format private members */
+
+void
+ui_out_get_field_separator (struct ui_out *uiout)
+{
+}
+
+/* Access to ui-out members data */
+
+struct ui_out_data *
+ui_out_data (struct ui_out *uiout)
+{
+ return uiout->data;
+}
+
+/* initalize private members at startup */
+
+struct ui_out *
+ui_out_new (struct ui_out_impl *impl,
+ struct ui_out_data *data,
+ int flags)
+{
+ struct ui_out *uiout = XMALLOC (struct ui_out);
+ uiout->data = data;
+ uiout->impl = impl;
+ uiout->flags = flags;
+ uiout->table.flag = 0;
+ uiout->table.body_flag = 0;
+ uiout->level = 0;
+ memset (uiout->levels, 0, sizeof (uiout->levels));
+ uiout->table.header_first = NULL;
+ uiout->table.header_last = NULL;
+ uiout->table.header_next = NULL;
+ return uiout;
+}
+
+/* standard gdb initialization hook */
+
+void
+_initialize_ui_out (void)
+{
+ /* nothing needs to be done */
+}
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
new file mode 100644
index 00000000000..797c2fe960d
--- /dev/null
+++ b/gdb/ui-out.h
@@ -0,0 +1,275 @@
+/* Output generating routines for GDB.
+ Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+ Written by Fernando Nasser for Cygnus.
+
+ 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. */
+
+#ifndef UI_OUT_H
+#define UI_OUT_H 1
+
+/* The ui_out structure */
+
+struct ui_out;
+struct ui_out_data;
+
+
+/* the current ui_out */
+
+/* FIXME: This should not be a global but something passed down from main.c
+ or top.c */
+extern struct ui_out *uiout;
+
+/* alignment enum */
+enum ui_align
+ {
+ ui_left = -1,
+ ui_center,
+ ui_right,
+ ui_noalign
+ };
+
+/* flags enum */
+enum ui_flags
+ {
+ ui_from_tty = 1,
+ ui_source_list = 2
+ };
+
+
+/* The ui_out stream structure. */
+/* NOTE: cagney/2000-02-01: The ui_stream object can be subsumed by
+ the more generic ui_file object. */
+
+struct ui_stream
+ {
+ struct ui_out *uiout;
+ struct ui_file *stream;
+ };
+
+
+/* Prototypes for ui-out API. */
+
+/* A result is a recursive data structure consisting of lists and
+ tuples. */
+
+enum ui_out_type
+ {
+ ui_out_type_tuple,
+ ui_out_type_list
+ };
+
+extern void ui_out_begin (struct ui_out *uiout,
+ enum ui_out_type level_type,
+ const char *id);
+
+extern void ui_out_end (struct ui_out *uiout, enum ui_out_type type);
+
+extern struct cleanup *ui_out_begin_cleanup_end (struct ui_out *uiout,
+ enum ui_out_type level_type,
+ const char *id);
+
+/* A table can be considered a special tuple/list combination with the
+ implied structure: ``table = { hdr = { header, ... } , body = [ {
+ field, ... }, ... ] }''. If NR_ROWS is negative then there is at
+ least one row. */
+
+extern void ui_out_table_begin (struct ui_out *uiout, int nbrofcols,
+ int nr_rows, const char *tblid);
+
+extern void ui_out_table_header (struct ui_out *uiout, int width,
+ enum ui_align align, const char *col_name,
+ const char *colhdr);
+
+extern void ui_out_table_body (struct ui_out *uiout);
+
+extern void ui_out_table_end (struct ui_out *uiout);
+
+/* Compatibility wrappers. */
+
+extern void ui_out_list_begin (struct ui_out *uiout, const char *id);
+
+extern void ui_out_list_end (struct ui_out *uiout);
+
+extern struct cleanup *make_cleanup_ui_out_list_begin_end (struct ui_out *uiout,
+ const char *id);
+
+extern void ui_out_tuple_begin (struct ui_out *uiout, const char *id);
+
+extern void ui_out_tuple_end (struct ui_out *uiout);
+
+extern struct cleanup *make_cleanup_ui_out_tuple_begin_end (struct ui_out *uiout,
+ const char *id);
+
+extern void ui_out_field_int (struct ui_out *uiout, const char *fldname,
+ int value);
+
+extern void ui_out_field_core_addr (struct ui_out *uiout, const char *fldname,
+ CORE_ADDR address);
+
+extern void ui_out_field_string (struct ui_out * uiout, const char *fldname,
+ const char *string);
+
+extern void ui_out_field_stream (struct ui_out *uiout, const char *fldname,
+ struct ui_stream *buf);
+
+extern void ui_out_field_fmt (struct ui_out *uiout, const char *fldname,
+ const char *format, ...);
+
+extern void ui_out_field_skip (struct ui_out *uiout, const char *fldname);
+
+extern void ui_out_spaces (struct ui_out *uiout, int numspaces);
+
+extern void ui_out_text (struct ui_out *uiout, const char *string);
+
+extern void ui_out_message (struct ui_out *uiout, int verbosity,
+ const char *format, ...);
+
+extern struct ui_stream *ui_out_stream_new (struct ui_out *uiout);
+
+extern void ui_out_stream_delete (struct ui_stream *buf);
+
+struct cleanup *make_cleanup_ui_out_stream_delete (struct ui_stream *buf);
+
+extern void ui_out_wrap_hint (struct ui_out *uiout, char *identstring);
+
+extern void ui_out_flush (struct ui_out *uiout);
+
+extern void ui_out_get_field_separator (struct ui_out *uiout);
+
+extern int ui_out_set_flags (struct ui_out *uiout, int mask);
+
+extern int ui_out_clear_flags (struct ui_out *uiout, int mask);
+
+extern int ui_out_get_verblvl (struct ui_out *uiout);
+
+extern int ui_out_test_flags (struct ui_out *uiout, int mask);
+
+#if 0
+extern void ui_out_result_begin (struct ui_out *uiout, char *class);
+
+extern void ui_out_result_end (struct ui_out *uiout);
+
+extern void ui_out_info_begin (struct ui_out *uiout, char *class);
+
+extern void ui_out_info_end (struct ui_out *uiout);
+
+extern void ui_out_notify_begin (struct ui_out *uiout, char *class);
+
+extern void ui_out_notify_end (struct ui_out *uiout);
+
+extern void ui_out_error_begin (struct ui_out *uiout, char *class);
+
+extern void ui_out_error_end (struct ui_out *uiout);
+#endif
+
+#if 0
+extern void gdb_error (struct ui_out *uiout, int severity, char *format, ...);
+
+extern void gdb_query (struct ui_out *uiout, int qflags, char *qprompt);
+#endif
+
+/* HACK: Code in GDB is currently checking to see the type of ui_out
+ builder when determining which output to produce. This function is
+ a hack to encapsulate that test. Once GDB manages to separate the
+ CLI/MI from the core of GDB the problem should just go away .... */
+
+extern int ui_out_is_mi_like_p (struct ui_out *uiout);
+
+/* From here on we have things that are only needed by implementation
+ routines and main.c. We should pehaps have a separate file for that,
+ like a ui-out-impl.h file */
+
+/* User Interface Output Implementation Function Table */
+
+/* Type definition of all implementation functions. */
+
+typedef void (table_begin_ftype) (struct ui_out * uiout,
+ int nbrofcols, int nr_rows,
+ const char *tblid);
+typedef void (table_body_ftype) (struct ui_out * uiout);
+typedef void (table_end_ftype) (struct ui_out * uiout);
+typedef void (table_header_ftype) (struct ui_out * uiout, int width,
+ enum ui_align align, const char *col_name,
+ const char *colhdr);
+/* Note: level 0 is the top-level so LEVEL is always greater than
+ zero. */
+typedef void (ui_out_begin_ftype) (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level, const char *id);
+typedef void (ui_out_end_ftype) (struct ui_out *uiout,
+ enum ui_out_type type,
+ int level);
+typedef void (field_int_ftype) (struct ui_out * uiout, int fldno, int width,
+ enum ui_align align,
+ const char *fldname, int value);
+typedef void (field_skip_ftype) (struct ui_out * uiout, int fldno, int width,
+ enum ui_align align,
+ const char *fldname);
+typedef void (field_string_ftype) (struct ui_out * uiout, int fldno, int width,
+ enum ui_align align,
+ const char *fldname,
+ const char *string);
+typedef void (field_fmt_ftype) (struct ui_out * uiout, int fldno, int width,
+ enum ui_align align,
+ const char *fldname,
+ const char *format,
+ va_list args);
+typedef void (spaces_ftype) (struct ui_out * uiout, int numspaces);
+typedef void (text_ftype) (struct ui_out * uiout,
+ const char *string);
+typedef void (message_ftype) (struct ui_out * uiout, int verbosity,
+ const char *format, va_list args);
+typedef void (wrap_hint_ftype) (struct ui_out * uiout, char *identstring);
+typedef void (flush_ftype) (struct ui_out * uiout);
+
+/* ui-out-impl */
+
+/* IMPORTANT: If you change this structure, make sure to change the default
+ initialization in ui-out.c */
+
+struct ui_out_impl
+ {
+ table_begin_ftype *table_begin;
+ table_body_ftype *table_body;
+ table_end_ftype *table_end;
+ table_header_ftype *table_header;
+ ui_out_begin_ftype *begin;
+ ui_out_end_ftype *end;
+ field_int_ftype *field_int;
+ field_skip_ftype *field_skip;
+ field_string_ftype *field_string;
+ field_fmt_ftype *field_fmt;
+ spaces_ftype *spaces;
+ text_ftype *text;
+ message_ftype *message;
+ wrap_hint_ftype *wrap_hint;
+ flush_ftype *flush;
+ int is_mi_like_p;
+ };
+
+extern struct ui_out_data *ui_out_data (struct ui_out *uiout);
+
+
+/* Create a ui_out object */
+
+extern struct ui_out *ui_out_new (struct ui_out_impl *impl,
+ struct ui_out_data *data,
+ int flags);
+
+#endif /* UI_OUT_H */
diff --git a/gdb/utils.c b/gdb/utils.c
new file mode 100644
index 00000000000..4baea624264
--- /dev/null
+++ b/gdb/utils.c
@@ -0,0 +1,2610 @@
+/* General utility routines for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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. */
+
+/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
+ "defs.h" should be included first. Unfortunatly some systems
+ (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
+ and they clash with "bfd.h"'s definiton of true/false. The correct
+ fix is to remove true/false from "bfd.h", however, until that
+ happens, hack around it by including "config.h" and <curses.h>
+ first. */
+
+#include "config.h"
+
+#ifdef HAVE_CURSES_H
+#include <curses.h>
+#endif
+#ifdef HAVE_TERM_H
+#include <term.h>
+#endif
+
+#include "defs.h"
+#include "gdb_assert.h"
+#include <ctype.h>
+#include "gdb_string.h"
+#include "event-top.h"
+
+#ifdef __GO32__
+#include <pc.h>
+#endif
+
+/* SunOS's curses.h has a '#define reg register' in it. Thank you Sun. */
+#ifdef reg
+#undef reg
+#endif
+
+#include <signal.h>
+#include "gdbcmd.h"
+#include "serial.h"
+#include "bfd.h"
+#include "target.h"
+#include "demangle.h"
+#include "expression.h"
+#include "language.h"
+#include "annotate.h"
+#include "filenames.h"
+
+#include "inferior.h" /* for signed_pointer_to_address */
+
+#include <sys/param.h> /* For MAXPATHLEN */
+
+#include <readline/readline.h>
+
+#ifdef USE_MMALLOC
+#include "mmalloc.h"
+#endif
+
+#ifdef NEED_DECLARATION_MALLOC
+extern PTR malloc ();
+#endif
+#ifdef NEED_DECLARATION_REALLOC
+extern PTR realloc ();
+#endif
+#ifdef NEED_DECLARATION_FREE
+extern void free ();
+#endif
+/* Actually, we'll never have the decl, since we don't define _GNU_SOURCE. */
+#if defined(HAVE_CANONICALIZE_FILE_NAME) \
+ && defined(NEED_DECLARATION_CANONICALIZE_FILE_NAME)
+extern char *canonicalize_file_name (const char *);
+#endif
+
+/* readline defines this. */
+#undef savestring
+
+void (*error_begin_hook) (void);
+
+/* Holds the last error message issued by gdb */
+
+static struct ui_file *gdb_lasterr;
+
+/* Prototypes for local functions */
+
+static void vfprintf_maybe_filtered (struct ui_file *, const char *,
+ va_list, int);
+
+static void fputs_maybe_filtered (const char *, struct ui_file *, int);
+
+#if defined (USE_MMALLOC) && !defined (NO_MMCHECK)
+static void malloc_botch (void);
+#endif
+
+static void prompt_for_continue (void);
+
+static void set_width_command (char *, int, struct cmd_list_element *);
+
+static void set_width (void);
+
+/* Chain of cleanup actions established with make_cleanup,
+ to be executed if an error happens. */
+
+static struct cleanup *cleanup_chain; /* cleaned up after a failed command */
+static struct cleanup *final_cleanup_chain; /* cleaned up when gdb exits */
+static struct cleanup *run_cleanup_chain; /* cleaned up on each 'run' */
+static struct cleanup *exec_cleanup_chain; /* cleaned up on each execution command */
+/* cleaned up on each error from within an execution command */
+static struct cleanup *exec_error_cleanup_chain;
+
+/* Pointer to what is left to do for an execution command after the
+ target stops. Used only in asynchronous mode, by targets that
+ support async execution. The finish and until commands use it. So
+ does the target extended-remote command. */
+struct continuation *cmd_continuation;
+struct continuation *intermediate_continuation;
+
+/* Nonzero if we have job control. */
+
+int job_control;
+
+/* Nonzero means a quit has been requested. */
+
+int quit_flag;
+
+/* Nonzero means quit immediately if Control-C is typed now, rather
+ than waiting until QUIT is executed. Be careful in setting this;
+ code which executes with immediate_quit set has to be very careful
+ about being able to deal with being interrupted at any time. It is
+ almost always better to use QUIT; the only exception I can think of
+ is being able to quit out of a system call (using EINTR loses if
+ the SIGINT happens between the previous QUIT and the system call).
+ To immediately quit in the case in which a SIGINT happens between
+ the previous QUIT and setting immediate_quit (desirable anytime we
+ expect to block), call QUIT after setting immediate_quit. */
+
+int immediate_quit;
+
+/* Nonzero means that encoded C++ names should be printed out in their
+ C++ form rather than raw. */
+
+int demangle = 1;
+
+/* Nonzero means that encoded C++ names should be printed out in their
+ C++ form even in assembler language displays. If this is set, but
+ DEMANGLE is zero, names are printed raw, i.e. DEMANGLE controls. */
+
+int asm_demangle = 0;
+
+/* Nonzero means that strings with character values >0x7F should be printed
+ as octal escapes. Zero means just print the value (e.g. it's an
+ international character, and the terminal or window can cope.) */
+
+int sevenbit_strings = 0;
+
+/* String to be printed before error messages, if any. */
+
+char *error_pre_print;
+
+/* String to be printed before quit messages, if any. */
+
+char *quit_pre_print;
+
+/* String to be printed before warning messages, if any. */
+
+char *warning_pre_print = "\nwarning: ";
+
+int pagination_enabled = 1;
+
+
+/* Add a new cleanup to the cleanup_chain,
+ and return the previous chain pointer
+ to be passed later to do_cleanups or discard_cleanups.
+ Args are FUNCTION to clean up with, and ARG to pass to it. */
+
+struct cleanup *
+make_cleanup (make_cleanup_ftype *function, void *arg)
+{
+ return make_my_cleanup (&cleanup_chain, function, arg);
+}
+
+struct cleanup *
+make_final_cleanup (make_cleanup_ftype *function, void *arg)
+{
+ return make_my_cleanup (&final_cleanup_chain, function, arg);
+}
+
+struct cleanup *
+make_run_cleanup (make_cleanup_ftype *function, void *arg)
+{
+ return make_my_cleanup (&run_cleanup_chain, function, arg);
+}
+
+struct cleanup *
+make_exec_cleanup (make_cleanup_ftype *function, void *arg)
+{
+ return make_my_cleanup (&exec_cleanup_chain, function, arg);
+}
+
+struct cleanup *
+make_exec_error_cleanup (make_cleanup_ftype *function, void *arg)
+{
+ return make_my_cleanup (&exec_error_cleanup_chain, function, arg);
+}
+
+static void
+do_freeargv (void *arg)
+{
+ freeargv ((char **) arg);
+}
+
+struct cleanup *
+make_cleanup_freeargv (char **arg)
+{
+ return make_my_cleanup (&cleanup_chain, do_freeargv, arg);
+}
+
+static void
+do_bfd_close_cleanup (void *arg)
+{
+ bfd_close (arg);
+}
+
+struct cleanup *
+make_cleanup_bfd_close (bfd *abfd)
+{
+ return make_cleanup (do_bfd_close_cleanup, abfd);
+}
+
+static void
+do_close_cleanup (void *arg)
+{
+ int *fd = arg;
+ close (*fd);
+ xfree (fd);
+}
+
+struct cleanup *
+make_cleanup_close (int fd)
+{
+ int *saved_fd = xmalloc (sizeof (fd));
+ *saved_fd = fd;
+ return make_cleanup (do_close_cleanup, saved_fd);
+}
+
+static void
+do_ui_file_delete (void *arg)
+{
+ ui_file_delete (arg);
+}
+
+struct cleanup *
+make_cleanup_ui_file_delete (struct ui_file *arg)
+{
+ return make_my_cleanup (&cleanup_chain, do_ui_file_delete, arg);
+}
+
+struct cleanup *
+make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function,
+ void *arg)
+{
+ register struct cleanup *new
+ = (struct cleanup *) xmalloc (sizeof (struct cleanup));
+ register struct cleanup *old_chain = *pmy_chain;
+
+ new->next = *pmy_chain;
+ new->function = function;
+ new->arg = arg;
+ *pmy_chain = new;
+
+ return old_chain;
+}
+
+/* Discard cleanups and do the actions they describe
+ until we get back to the point OLD_CHAIN in the cleanup_chain. */
+
+void
+do_cleanups (register struct cleanup *old_chain)
+{
+ do_my_cleanups (&cleanup_chain, old_chain);
+}
+
+void
+do_final_cleanups (register struct cleanup *old_chain)
+{
+ do_my_cleanups (&final_cleanup_chain, old_chain);
+}
+
+void
+do_run_cleanups (register struct cleanup *old_chain)
+{
+ do_my_cleanups (&run_cleanup_chain, old_chain);
+}
+
+void
+do_exec_cleanups (register struct cleanup *old_chain)
+{
+ do_my_cleanups (&exec_cleanup_chain, old_chain);
+}
+
+void
+do_exec_error_cleanups (register struct cleanup *old_chain)
+{
+ do_my_cleanups (&exec_error_cleanup_chain, old_chain);
+}
+
+void
+do_my_cleanups (register struct cleanup **pmy_chain,
+ register struct cleanup *old_chain)
+{
+ register struct cleanup *ptr;
+ while ((ptr = *pmy_chain) != old_chain)
+ {
+ *pmy_chain = ptr->next; /* Do this first incase recursion */
+ (*ptr->function) (ptr->arg);
+ xfree (ptr);
+ }
+}
+
+/* Discard cleanups, not doing the actions they describe,
+ until we get back to the point OLD_CHAIN in the cleanup_chain. */
+
+void
+discard_cleanups (register struct cleanup *old_chain)
+{
+ discard_my_cleanups (&cleanup_chain, old_chain);
+}
+
+void
+discard_final_cleanups (register struct cleanup *old_chain)
+{
+ discard_my_cleanups (&final_cleanup_chain, old_chain);
+}
+
+void
+discard_exec_error_cleanups (register struct cleanup *old_chain)
+{
+ discard_my_cleanups (&exec_error_cleanup_chain, old_chain);
+}
+
+void
+discard_my_cleanups (register struct cleanup **pmy_chain,
+ register struct cleanup *old_chain)
+{
+ register struct cleanup *ptr;
+ while ((ptr = *pmy_chain) != old_chain)
+ {
+ *pmy_chain = ptr->next;
+ xfree (ptr);
+ }
+}
+
+/* Set the cleanup_chain to 0, and return the old cleanup chain. */
+struct cleanup *
+save_cleanups (void)
+{
+ return save_my_cleanups (&cleanup_chain);
+}
+
+struct cleanup *
+save_final_cleanups (void)
+{
+ return save_my_cleanups (&final_cleanup_chain);
+}
+
+struct cleanup *
+save_my_cleanups (struct cleanup **pmy_chain)
+{
+ struct cleanup *old_chain = *pmy_chain;
+
+ *pmy_chain = 0;
+ return old_chain;
+}
+
+/* Restore the cleanup chain from a previously saved chain. */
+void
+restore_cleanups (struct cleanup *chain)
+{
+ restore_my_cleanups (&cleanup_chain, chain);
+}
+
+void
+restore_final_cleanups (struct cleanup *chain)
+{
+ restore_my_cleanups (&final_cleanup_chain, chain);
+}
+
+void
+restore_my_cleanups (struct cleanup **pmy_chain, struct cleanup *chain)
+{
+ *pmy_chain = chain;
+}
+
+/* This function is useful for cleanups.
+ Do
+
+ foo = xmalloc (...);
+ old_chain = make_cleanup (free_current_contents, &foo);
+
+ to arrange to free the object thus allocated. */
+
+void
+free_current_contents (void *ptr)
+{
+ void **location = ptr;
+ if (location == NULL)
+ internal_error (__FILE__, __LINE__,
+ "free_current_contents: NULL pointer");
+ if (*location != NULL)
+ {
+ xfree (*location);
+ *location = NULL;
+ }
+}
+
+/* Provide a known function that does nothing, to use as a base for
+ for a possibly long chain of cleanups. This is useful where we
+ use the cleanup chain for handling normal cleanups as well as dealing
+ with cleanups that need to be done as a result of a call to error().
+ In such cases, we may not be certain where the first cleanup is, unless
+ we have a do-nothing one to always use as the base. */
+
+/* ARGSUSED */
+void
+null_cleanup (void *arg)
+{
+}
+
+/* Add a continuation to the continuation list, the global list
+ cmd_continuation. The new continuation will be added at the front.*/
+void
+add_continuation (void (*continuation_hook) (struct continuation_arg *),
+ struct continuation_arg *arg_list)
+{
+ struct continuation *continuation_ptr;
+
+ continuation_ptr = (struct continuation *) xmalloc (sizeof (struct continuation));
+ continuation_ptr->continuation_hook = continuation_hook;
+ continuation_ptr->arg_list = arg_list;
+ continuation_ptr->next = cmd_continuation;
+ cmd_continuation = continuation_ptr;
+}
+
+/* Walk down the cmd_continuation list, and execute all the
+ continuations. There is a problem though. In some cases new
+ continuations may be added while we are in the middle of this
+ loop. If this happens they will be added in the front, and done
+ before we have a chance of exhausting those that were already
+ there. We need to then save the beginning of the list in a pointer
+ and do the continuations from there on, instead of using the
+ global beginning of list as our iteration pointer.*/
+void
+do_all_continuations (void)
+{
+ struct continuation *continuation_ptr;
+ struct continuation *saved_continuation;
+
+ /* Copy the list header into another pointer, and set the global
+ list header to null, so that the global list can change as a side
+ effect of invoking the continuations and the processing of
+ the preexisting continuations will not be affected. */
+ continuation_ptr = cmd_continuation;
+ cmd_continuation = NULL;
+
+ /* Work now on the list we have set aside. */
+ while (continuation_ptr)
+ {
+ (continuation_ptr->continuation_hook) (continuation_ptr->arg_list);
+ saved_continuation = continuation_ptr;
+ continuation_ptr = continuation_ptr->next;
+ xfree (saved_continuation);
+ }
+}
+
+/* Walk down the cmd_continuation list, and get rid of all the
+ continuations. */
+void
+discard_all_continuations (void)
+{
+ struct continuation *continuation_ptr;
+
+ while (cmd_continuation)
+ {
+ continuation_ptr = cmd_continuation;
+ cmd_continuation = continuation_ptr->next;
+ xfree (continuation_ptr);
+ }
+}
+
+/* Add a continuation to the continuation list, the global list
+ intermediate_continuation. The new continuation will be added at the front.*/
+void
+add_intermediate_continuation (void (*continuation_hook)
+ (struct continuation_arg *),
+ struct continuation_arg *arg_list)
+{
+ struct continuation *continuation_ptr;
+
+ continuation_ptr = (struct continuation *) xmalloc (sizeof (struct continuation));
+ continuation_ptr->continuation_hook = continuation_hook;
+ continuation_ptr->arg_list = arg_list;
+ continuation_ptr->next = intermediate_continuation;
+ intermediate_continuation = continuation_ptr;
+}
+
+/* Walk down the cmd_continuation list, and execute all the
+ continuations. There is a problem though. In some cases new
+ continuations may be added while we are in the middle of this
+ loop. If this happens they will be added in the front, and done
+ before we have a chance of exhausting those that were already
+ there. We need to then save the beginning of the list in a pointer
+ and do the continuations from there on, instead of using the
+ global beginning of list as our iteration pointer.*/
+void
+do_all_intermediate_continuations (void)
+{
+ struct continuation *continuation_ptr;
+ struct continuation *saved_continuation;
+
+ /* Copy the list header into another pointer, and set the global
+ list header to null, so that the global list can change as a side
+ effect of invoking the continuations and the processing of
+ the preexisting continuations will not be affected. */
+ continuation_ptr = intermediate_continuation;
+ intermediate_continuation = NULL;
+
+ /* Work now on the list we have set aside. */
+ while (continuation_ptr)
+ {
+ (continuation_ptr->continuation_hook) (continuation_ptr->arg_list);
+ saved_continuation = continuation_ptr;
+ continuation_ptr = continuation_ptr->next;
+ xfree (saved_continuation);
+ }
+}
+
+/* Walk down the cmd_continuation list, and get rid of all the
+ continuations. */
+void
+discard_all_intermediate_continuations (void)
+{
+ struct continuation *continuation_ptr;
+
+ while (intermediate_continuation)
+ {
+ continuation_ptr = intermediate_continuation;
+ intermediate_continuation = continuation_ptr->next;
+ xfree (continuation_ptr);
+ }
+}
+
+
+
+/* Print a warning message. The first argument STRING is the warning
+ message, used as an fprintf format string, the second is the
+ va_list of arguments for that string. A warning is unfiltered (not
+ paginated) so that the user does not need to page through each
+ screen full of warnings when there are lots of them. */
+
+void
+vwarning (const char *string, va_list args)
+{
+ if (warning_hook)
+ (*warning_hook) (string, args);
+ else
+ {
+ target_terminal_ours ();
+ wrap_here (""); /* Force out any buffered output */
+ gdb_flush (gdb_stdout);
+ if (warning_pre_print)
+ fprintf_unfiltered (gdb_stderr, warning_pre_print);
+ vfprintf_unfiltered (gdb_stderr, string, args);
+ fprintf_unfiltered (gdb_stderr, "\n");
+ va_end (args);
+ }
+}
+
+/* Print a warning message.
+ The first argument STRING is the warning message, used as a fprintf string,
+ and the remaining args are passed as arguments to it.
+ The primary difference between warnings and errors is that a warning
+ does not force the return to command level. */
+
+void
+warning (const char *string,...)
+{
+ va_list args;
+ va_start (args, string);
+ vwarning (string, args);
+ va_end (args);
+}
+
+/* Print an error message and return to command level.
+ The first argument STRING is the error message, used as a fprintf string,
+ and the remaining args are passed as arguments to it. */
+
+NORETURN void
+verror (const char *string, va_list args)
+{
+ struct ui_file *tmp_stream = mem_fileopen ();
+ make_cleanup_ui_file_delete (tmp_stream);
+ vfprintf_unfiltered (tmp_stream, string, args);
+ error_stream (tmp_stream);
+}
+
+NORETURN void
+error (const char *string,...)
+{
+ va_list args;
+ va_start (args, string);
+ verror (string, args);
+ va_end (args);
+}
+
+static void
+do_write (void *data, const char *buffer, long length_buffer)
+{
+ ui_file_write (data, buffer, length_buffer);
+}
+
+NORETURN void
+error_stream (struct ui_file *stream)
+{
+ if (error_begin_hook)
+ error_begin_hook ();
+
+ /* Copy the stream into the GDB_LASTERR buffer. */
+ ui_file_rewind (gdb_lasterr);
+ ui_file_put (stream, do_write, gdb_lasterr);
+
+ /* Write the message plus any error_pre_print to gdb_stderr. */
+ target_terminal_ours ();
+ wrap_here (""); /* Force out any buffered output */
+ gdb_flush (gdb_stdout);
+ annotate_error_begin ();
+ if (error_pre_print)
+ fprintf_filtered (gdb_stderr, error_pre_print);
+ ui_file_put (stream, do_write, gdb_stderr);
+ fprintf_filtered (gdb_stderr, "\n");
+
+ throw_exception (RETURN_ERROR);
+}
+
+/* Get the last error message issued by gdb */
+
+char *
+error_last_message (void)
+{
+ long len;
+ return ui_file_xstrdup (gdb_lasterr, &len);
+}
+
+/* This is to be called by main() at the very beginning */
+
+void
+error_init (void)
+{
+ gdb_lasterr = mem_fileopen ();
+}
+
+/* Print a message reporting an internal error. Ask the user if they
+ want to continue, dump core, or just exit. */
+
+NORETURN void
+internal_verror (const char *file, int line,
+ const char *fmt, va_list ap)
+{
+ static char msg[] = "Internal GDB error: recursive internal error.\n";
+ static int dejavu = 0;
+ int quit_p;
+ int dump_core_p;
+
+ /* don't allow infinite error recursion. */
+ switch (dejavu)
+ {
+ case 0:
+ dejavu = 1;
+ break;
+ case 1:
+ dejavu = 2;
+ fputs_unfiltered (msg, gdb_stderr);
+ abort (); /* NOTE: GDB has only three calls to abort(). */
+ default:
+ dejavu = 3;
+ write (STDERR_FILENO, msg, sizeof (msg));
+ exit (1);
+ }
+
+ /* Try to get the message out */
+ target_terminal_ours ();
+ fprintf_unfiltered (gdb_stderr, "%s:%d: gdb-internal-error: ", file, line);
+ vfprintf_unfiltered (gdb_stderr, fmt, ap);
+ fputs_unfiltered ("\n", gdb_stderr);
+
+ /* Default (yes/batch case) is to quit GDB. When in batch mode this
+ lessens the likelhood of GDB going into an infinate loop. */
+ quit_p = query ("\
+An internal GDB error was detected. This may make further\n\
+debugging unreliable. Quit this debugging session? ");
+
+ /* Default (yes/batch case) is to dump core. This leaves a GDB
+ dropping so that it is easier to see that something went wrong to
+ GDB. */
+ dump_core_p = query ("\
+Create a core file containing the current state of GDB? ");
+
+ if (quit_p)
+ {
+ if (dump_core_p)
+ abort (); /* NOTE: GDB has only three calls to abort(). */
+ else
+ exit (1);
+ }
+ else
+ {
+ if (dump_core_p)
+ {
+ if (fork () == 0)
+ abort (); /* NOTE: GDB has only three calls to abort(). */
+ }
+ }
+
+ dejavu = 0;
+ throw_exception (RETURN_ERROR);
+}
+
+NORETURN void
+internal_error (const char *file, int line, const char *string, ...)
+{
+ va_list ap;
+ va_start (ap, string);
+
+ internal_verror (file, line, string, ap);
+ va_end (ap);
+}
+
+/* The strerror() function can return NULL for errno values that are
+ out of range. Provide a "safe" version that always returns a
+ printable string. */
+
+char *
+safe_strerror (int errnum)
+{
+ char *msg;
+ static char buf[32];
+
+ if ((msg = strerror (errnum)) == NULL)
+ {
+ sprintf (buf, "(undocumented errno %d)", errnum);
+ msg = buf;
+ }
+ return (msg);
+}
+
+/* Print the system error message for errno, and also mention STRING
+ as the file name for which the error was encountered.
+ Then return to command level. */
+
+NORETURN void
+perror_with_name (const char *string)
+{
+ char *err;
+ char *combined;
+
+ err = safe_strerror (errno);
+ combined = (char *) alloca (strlen (err) + strlen (string) + 3);
+ strcpy (combined, string);
+ strcat (combined, ": ");
+ strcat (combined, err);
+
+ /* I understand setting these is a matter of taste. Still, some people
+ may clear errno but not know about bfd_error. Doing this here is not
+ unreasonable. */
+ bfd_set_error (bfd_error_no_error);
+ errno = 0;
+
+ error ("%s.", combined);
+}
+
+/* Print the system error message for ERRCODE, and also mention STRING
+ as the file name for which the error was encountered. */
+
+void
+print_sys_errmsg (const char *string, int errcode)
+{
+ char *err;
+ char *combined;
+
+ err = safe_strerror (errcode);
+ combined = (char *) alloca (strlen (err) + strlen (string) + 3);
+ strcpy (combined, string);
+ strcat (combined, ": ");
+ strcat (combined, err);
+
+ /* We want anything which was printed on stdout to come out first, before
+ this message. */
+ gdb_flush (gdb_stdout);
+ fprintf_unfiltered (gdb_stderr, "%s.\n", combined);
+}
+
+/* Control C eventually causes this to be called, at a convenient time. */
+
+void
+quit (void)
+{
+ struct serial *gdb_stdout_serial = serial_fdopen (1);
+
+ target_terminal_ours ();
+
+ /* We want all output to appear now, before we print "Quit". We
+ have 3 levels of buffering we have to flush (it's possible that
+ some of these should be changed to flush the lower-level ones
+ too): */
+
+ /* 1. The _filtered buffer. */
+ wrap_here ((char *) 0);
+
+ /* 2. The stdio buffer. */
+ gdb_flush (gdb_stdout);
+ gdb_flush (gdb_stderr);
+
+ /* 3. The system-level buffer. */
+ serial_drain_output (gdb_stdout_serial);
+ serial_un_fdopen (gdb_stdout_serial);
+
+ annotate_error_begin ();
+
+ /* Don't use *_filtered; we don't want to prompt the user to continue. */
+ if (quit_pre_print)
+ fprintf_unfiltered (gdb_stderr, quit_pre_print);
+
+#ifdef __MSDOS__
+ /* No steenking SIGINT will ever be coming our way when the
+ program is resumed. Don't lie. */
+ fprintf_unfiltered (gdb_stderr, "Quit\n");
+#else
+ if (job_control
+ /* If there is no terminal switching for this target, then we can't
+ possibly get screwed by the lack of job control. */
+ || current_target.to_terminal_ours == NULL)
+ fprintf_unfiltered (gdb_stderr, "Quit\n");
+ else
+ fprintf_unfiltered (gdb_stderr,
+ "Quit (expect signal SIGINT when the program is resumed)\n");
+#endif
+ throw_exception (RETURN_QUIT);
+}
+
+/* Control C comes here */
+void
+request_quit (int signo)
+{
+ quit_flag = 1;
+ /* Restore the signal handler. Harmless with BSD-style signals, needed
+ for System V-style signals. So just always do it, rather than worrying
+ about USG defines and stuff like that. */
+ signal (signo, request_quit);
+
+#ifdef REQUEST_QUIT
+ REQUEST_QUIT;
+#else
+ if (immediate_quit)
+ quit ();
+#endif
+}
+
+/* Memory management stuff (malloc friends). */
+
+#if !defined (USE_MMALLOC)
+
+/* NOTE: These must use PTR so that their definition matches the
+ declaration found in "mmalloc.h". */
+
+static void *
+mmalloc (void *md, size_t size)
+{
+ return malloc (size); /* NOTE: GDB's only call to malloc() */
+}
+
+static void *
+mrealloc (void *md, void *ptr, size_t size)
+{
+ if (ptr == 0) /* Guard against old realloc's */
+ return mmalloc (md, size);
+ else
+ return realloc (ptr, size); /* NOTE: GDB's only call to ralloc() */
+}
+
+static void *
+mcalloc (void *md, size_t number, size_t size)
+{
+ return calloc (number, size); /* NOTE: GDB's only call to calloc() */
+}
+
+static void
+mfree (void *md, void *ptr)
+{
+ free (ptr); /* NOTE: GDB's only call to free() */
+}
+
+#endif /* USE_MMALLOC */
+
+#if !defined (USE_MMALLOC) || defined (NO_MMCHECK)
+
+void
+init_malloc (void *md)
+{
+}
+
+#else /* Have mmalloc and want corruption checking */
+
+static void
+malloc_botch (void)
+{
+ fprintf_unfiltered (gdb_stderr, "Memory corruption\n");
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+}
+
+/* Attempt to install hooks in mmalloc/mrealloc/mfree for the heap specified
+ by MD, to detect memory corruption. Note that MD may be NULL to specify
+ the default heap that grows via sbrk.
+
+ Note that for freshly created regions, we must call mmcheckf prior to any
+ mallocs in the region. Otherwise, any region which was allocated prior to
+ installing the checking hooks, which is later reallocated or freed, will
+ fail the checks! The mmcheck function only allows initial hooks to be
+ installed before the first mmalloc. However, anytime after we have called
+ mmcheck the first time to install the checking hooks, we can call it again
+ to update the function pointer to the memory corruption handler.
+
+ Returns zero on failure, non-zero on success. */
+
+#ifndef MMCHECK_FORCE
+#define MMCHECK_FORCE 0
+#endif
+
+void
+init_malloc (void *md)
+{
+ if (!mmcheckf (md, malloc_botch, MMCHECK_FORCE))
+ {
+ /* Don't use warning(), which relies on current_target being set
+ to something other than dummy_target, until after
+ initialize_all_files(). */
+
+ fprintf_unfiltered
+ (gdb_stderr, "warning: failed to install memory consistency checks; ");
+ fprintf_unfiltered
+ (gdb_stderr, "configuration should define NO_MMCHECK or MMCHECK_FORCE\n");
+ }
+
+ mmtrace ();
+}
+
+#endif /* Have mmalloc and want corruption checking */
+
+/* Called when a memory allocation fails, with the number of bytes of
+ memory requested in SIZE. */
+
+NORETURN void
+nomem (long size)
+{
+ if (size > 0)
+ {
+ internal_error (__FILE__, __LINE__,
+ "virtual memory exhausted: can't allocate %ld bytes.", size);
+ }
+ else
+ {
+ internal_error (__FILE__, __LINE__,
+ "virtual memory exhausted.");
+ }
+}
+
+/* The xmmalloc() family of memory management routines.
+
+ These are are like the mmalloc() family except that they implement
+ consistent semantics and guard against typical memory management
+ problems: if a malloc fails, an internal error is thrown; if
+ free(NULL) is called, it is ignored; if *alloc(0) is called, NULL
+ is returned.
+
+ All these routines are implemented using the mmalloc() family. */
+
+void *
+xmmalloc (void *md, size_t size)
+{
+ void *val;
+
+ if (size == 0)
+ {
+ val = NULL;
+ }
+ else
+ {
+ val = mmalloc (md, size);
+ if (val == NULL)
+ nomem (size);
+ }
+ return (val);
+}
+
+void *
+xmrealloc (void *md, void *ptr, size_t size)
+{
+ void *val;
+
+ if (size == 0)
+ {
+ if (ptr != NULL)
+ mfree (md, ptr);
+ val = NULL;
+ }
+ else
+ {
+ if (ptr != NULL)
+ {
+ val = mrealloc (md, ptr, size);
+ }
+ else
+ {
+ val = mmalloc (md, size);
+ }
+ if (val == NULL)
+ {
+ nomem (size);
+ }
+ }
+ return (val);
+}
+
+void *
+xmcalloc (void *md, size_t number, size_t size)
+{
+ void *mem;
+ if (number == 0 || size == 0)
+ mem = NULL;
+ else
+ {
+ mem = mcalloc (md, number, size);
+ if (mem == NULL)
+ nomem (number * size);
+ }
+ return mem;
+}
+
+void
+xmfree (void *md, void *ptr)
+{
+ if (ptr != NULL)
+ mfree (md, ptr);
+}
+
+/* The xmalloc() (libiberty.h) family of memory management routines.
+
+ These are like the ISO-C malloc() family except that they implement
+ consistent semantics and guard against typical memory management
+ problems. See xmmalloc() above for further information.
+
+ All these routines are wrappers to the xmmalloc() family. */
+
+/* NOTE: These are declared using PTR to ensure consistency with
+ "libiberty.h". xfree() is GDB local. */
+
+PTR
+xmalloc (size_t size)
+{
+ return xmmalloc (NULL, size);
+}
+
+PTR
+xrealloc (PTR ptr, size_t size)
+{
+ return xmrealloc (NULL, ptr, size);
+}
+
+PTR
+xcalloc (size_t number, size_t size)
+{
+ return xmcalloc (NULL, number, size);
+}
+
+void
+xfree (void *ptr)
+{
+ xmfree (NULL, ptr);
+}
+
+
+/* Like asprintf/vasprintf but get an internal_error if the call
+ fails. */
+
+void
+xasprintf (char **ret, const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ xvasprintf (ret, format, args);
+ va_end (args);
+}
+
+void
+xvasprintf (char **ret, const char *format, va_list ap)
+{
+ int status = vasprintf (ret, format, ap);
+ /* NULL could be returned due to a memory allocation problem; a
+ badly format string; or something else. */
+ if ((*ret) == NULL)
+ internal_error (__FILE__, __LINE__,
+ "vasprintf returned NULL buffer (errno %d)",
+ errno);
+ /* A negative status with a non-NULL buffer shouldn't never
+ happen. But to be sure. */
+ if (status < 0)
+ internal_error (__FILE__, __LINE__,
+ "vasprintf call failed (errno %d)",
+ errno);
+}
+
+
+/* My replacement for the read system call.
+ Used like `read' but keeps going if `read' returns too soon. */
+
+int
+myread (int desc, char *addr, int len)
+{
+ register int val;
+ int orglen = len;
+
+ while (len > 0)
+ {
+ val = read (desc, addr, len);
+ if (val < 0)
+ return val;
+ if (val == 0)
+ return orglen - len;
+ len -= val;
+ addr += val;
+ }
+ return orglen;
+}
+
+/* Make a copy of the string at PTR with SIZE characters
+ (and add a null character at the end in the copy).
+ Uses malloc to get the space. Returns the address of the copy. */
+
+char *
+savestring (const char *ptr, size_t size)
+{
+ register char *p = (char *) xmalloc (size + 1);
+ memcpy (p, ptr, size);
+ p[size] = 0;
+ return p;
+}
+
+char *
+msavestring (void *md, const char *ptr, size_t size)
+{
+ register char *p = (char *) xmmalloc (md, size + 1);
+ memcpy (p, ptr, size);
+ p[size] = 0;
+ return p;
+}
+
+char *
+mstrsave (void *md, const char *ptr)
+{
+ return (msavestring (md, ptr, strlen (ptr)));
+}
+
+void
+print_spaces (register int n, register struct ui_file *file)
+{
+ fputs_unfiltered (n_spaces (n), file);
+}
+
+/* Print a host address. */
+
+void
+gdb_print_host_address (void *addr, struct ui_file *stream)
+{
+
+ /* We could use the %p conversion specifier to fprintf if we had any
+ way of knowing whether this host supports it. But the following
+ should work on the Alpha and on 32 bit machines. */
+
+ fprintf_filtered (stream, "0x%lx", (unsigned long) addr);
+}
+
+/* Ask user a y-or-n question and return 1 iff answer is yes.
+ Takes three args which are given to printf to print the question.
+ The first, a control string, should end in "? ".
+ It should not say how to answer, because we do that. */
+
+/* VARARGS */
+int
+query (const char *ctlstr,...)
+{
+ va_list args;
+ register int answer;
+ register int ans2;
+ int retval;
+
+ va_start (args, ctlstr);
+
+ if (query_hook)
+ {
+ return query_hook (ctlstr, args);
+ }
+
+ /* Automatically answer "yes" if input is not from a terminal. */
+ if (!input_from_terminal_p ())
+ return 1;
+
+ while (1)
+ {
+ wrap_here (""); /* Flush any buffered output */
+ gdb_flush (gdb_stdout);
+
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032pre-query\n");
+
+ vfprintf_filtered (gdb_stdout, ctlstr, args);
+ printf_filtered ("(y or n) ");
+
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032query\n");
+
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+
+ answer = fgetc (stdin);
+ clearerr (stdin); /* in case of C-d */
+ if (answer == EOF) /* C-d */
+ {
+ retval = 1;
+ break;
+ }
+ /* Eat rest of input line, to EOF or newline */
+ if (answer != '\n')
+ do
+ {
+ ans2 = fgetc (stdin);
+ clearerr (stdin);
+ }
+ while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
+
+ if (answer >= 'a')
+ answer -= 040;
+ if (answer == 'Y')
+ {
+ retval = 1;
+ break;
+ }
+ if (answer == 'N')
+ {
+ retval = 0;
+ break;
+ }
+ printf_filtered ("Please answer y or n.\n");
+ }
+
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032post-query\n");
+ return retval;
+}
+
+
+/* Parse a C escape sequence. STRING_PTR points to a variable
+ containing a pointer to the string to parse. That pointer
+ should point to the character after the \. That pointer
+ is updated past the characters we use. The value of the
+ escape sequence is returned.
+
+ A negative value means the sequence \ newline was seen,
+ which is supposed to be equivalent to nothing at all.
+
+ If \ is followed by a null character, we return a negative
+ value and leave the string pointer pointing at the null character.
+
+ If \ is followed by 000, we return 0 and leave the string pointer
+ after the zeros. A value of 0 does not mean end of string. */
+
+int
+parse_escape (char **string_ptr)
+{
+ register int c = *(*string_ptr)++;
+ switch (c)
+ {
+ case 'a':
+ return 007; /* Bell (alert) char */
+ case 'b':
+ return '\b';
+ case 'e': /* Escape character */
+ return 033;
+ case 'f':
+ return '\f';
+ case 'n':
+ return '\n';
+ case 'r':
+ return '\r';
+ case 't':
+ return '\t';
+ case 'v':
+ return '\v';
+ case '\n':
+ return -2;
+ case 0:
+ (*string_ptr)--;
+ return 0;
+ case '^':
+ c = *(*string_ptr)++;
+ if (c == '\\')
+ c = parse_escape (string_ptr);
+ if (c == '?')
+ return 0177;
+ return (c & 0200) | (c & 037);
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ {
+ register int i = c - '0';
+ register int count = 0;
+ while (++count < 3)
+ {
+ if ((c = *(*string_ptr)++) >= '0' && c <= '7')
+ {
+ i *= 8;
+ i += c - '0';
+ }
+ else
+ {
+ (*string_ptr)--;
+ break;
+ }
+ }
+ return i;
+ }
+ default:
+ return c;
+ }
+}
+
+/* Print the character C on STREAM as part of the contents of a literal
+ string whose delimiter is QUOTER. Note that this routine should only
+ be call for printing things which are independent of the language
+ of the program being debugged. */
+
+static void
+printchar (int c, void (*do_fputs) (const char *, struct ui_file *),
+ void (*do_fprintf) (struct ui_file *, const char *, ...),
+ struct ui_file *stream, int quoter)
+{
+
+ c &= 0xFF; /* Avoid sign bit follies */
+
+ if (c < 0x20 || /* Low control chars */
+ (c >= 0x7F && c < 0xA0) || /* DEL, High controls */
+ (sevenbit_strings && c >= 0x80))
+ { /* high order bit set */
+ switch (c)
+ {
+ case '\n':
+ do_fputs ("\\n", stream);
+ break;
+ case '\b':
+ do_fputs ("\\b", stream);
+ break;
+ case '\t':
+ do_fputs ("\\t", stream);
+ break;
+ case '\f':
+ do_fputs ("\\f", stream);
+ break;
+ case '\r':
+ do_fputs ("\\r", stream);
+ break;
+ case '\033':
+ do_fputs ("\\e", stream);
+ break;
+ case '\007':
+ do_fputs ("\\a", stream);
+ break;
+ default:
+ do_fprintf (stream, "\\%.3o", (unsigned int) c);
+ break;
+ }
+ }
+ else
+ {
+ if (c == '\\' || c == quoter)
+ do_fputs ("\\", stream);
+ do_fprintf (stream, "%c", c);
+ }
+}
+
+/* Print the character C on STREAM as part of the contents of a
+ literal string whose delimiter is QUOTER. Note that these routines
+ should only be call for printing things which are independent of
+ the language of the program being debugged. */
+
+void
+fputstr_filtered (const char *str, int quoter, struct ui_file *stream)
+{
+ while (*str)
+ printchar (*str++, fputs_filtered, fprintf_filtered, stream, quoter);
+}
+
+void
+fputstr_unfiltered (const char *str, int quoter, struct ui_file *stream)
+{
+ while (*str)
+ printchar (*str++, fputs_unfiltered, fprintf_unfiltered, stream, quoter);
+}
+
+void
+fputstrn_unfiltered (const char *str, int n, int quoter, struct ui_file *stream)
+{
+ int i;
+ for (i = 0; i < n; i++)
+ printchar (str[i], fputs_unfiltered, fprintf_unfiltered, stream, quoter);
+}
+
+
+
+/* Number of lines per page or UINT_MAX if paging is disabled. */
+static unsigned int lines_per_page;
+/* Number of chars per line or UINT_MAX if line folding is disabled. */
+static unsigned int chars_per_line;
+/* Current count of lines printed on this page, chars on this line. */
+static unsigned int lines_printed, chars_printed;
+
+/* Buffer and start column of buffered text, for doing smarter word-
+ wrapping. When someone calls wrap_here(), we start buffering output
+ that comes through fputs_filtered(). If we see a newline, we just
+ spit it out and forget about the wrap_here(). If we see another
+ wrap_here(), we spit it out and remember the newer one. If we see
+ the end of the line, we spit out a newline, the indent, and then
+ the buffered output. */
+
+/* Malloc'd buffer with chars_per_line+2 bytes. Contains characters which
+ are waiting to be output (they have already been counted in chars_printed).
+ When wrap_buffer[0] is null, the buffer is empty. */
+static char *wrap_buffer;
+
+/* Pointer in wrap_buffer to the next character to fill. */
+static char *wrap_pointer;
+
+/* String to indent by if the wrap occurs. Must not be NULL if wrap_column
+ is non-zero. */
+static char *wrap_indent;
+
+/* Column number on the screen where wrap_buffer begins, or 0 if wrapping
+ is not in effect. */
+static int wrap_column;
+
+
+/* Inialize the lines and chars per page */
+void
+init_page_info (void)
+{
+#if defined(TUI)
+ if (!tui_get_command_dimension (&chars_per_line, &lines_per_page))
+#endif
+ {
+ /* These defaults will be used if we are unable to get the correct
+ values from termcap. */
+#if defined(__GO32__)
+ lines_per_page = ScreenRows ();
+ chars_per_line = ScreenCols ();
+#else
+ lines_per_page = 24;
+ chars_per_line = 80;
+
+#if !defined (_WIN32)
+ /* No termcap under MPW, although might be cool to do something
+ by looking at worksheet or console window sizes. */
+ /* Initialize the screen height and width from termcap. */
+ {
+ char *termtype = getenv ("TERM");
+
+ /* Positive means success, nonpositive means failure. */
+ int status;
+
+ /* 2048 is large enough for all known terminals, according to the
+ GNU termcap manual. */
+ char term_buffer[2048];
+
+ if (termtype)
+ {
+ status = tgetent (term_buffer, termtype);
+ if (status > 0)
+ {
+ int val;
+ int running_in_emacs = getenv ("EMACS") != NULL;
+
+ val = tgetnum ("li");
+ if (val >= 0 && !running_in_emacs)
+ lines_per_page = val;
+ else
+ /* The number of lines per page is not mentioned
+ in the terminal description. This probably means
+ that paging is not useful (e.g. emacs shell window),
+ so disable paging. */
+ lines_per_page = UINT_MAX;
+
+ val = tgetnum ("co");
+ if (val >= 0)
+ chars_per_line = val;
+ }
+ }
+ }
+#endif /* MPW */
+
+#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
+
+ /* If there is a better way to determine the window size, use it. */
+ SIGWINCH_HANDLER (SIGWINCH);
+#endif
+#endif
+ /* If the output is not a terminal, don't paginate it. */
+ if (!ui_file_isatty (gdb_stdout))
+ lines_per_page = UINT_MAX;
+ } /* the command_line_version */
+ set_width ();
+}
+
+static void
+set_width (void)
+{
+ if (chars_per_line == 0)
+ init_page_info ();
+
+ if (!wrap_buffer)
+ {
+ wrap_buffer = (char *) xmalloc (chars_per_line + 2);
+ wrap_buffer[0] = '\0';
+ }
+ else
+ wrap_buffer = (char *) xrealloc (wrap_buffer, chars_per_line + 2);
+ wrap_pointer = wrap_buffer; /* Start it at the beginning */
+}
+
+/* ARGSUSED */
+static void
+set_width_command (char *args, int from_tty, struct cmd_list_element *c)
+{
+ set_width ();
+}
+
+/* Wait, so the user can read what's on the screen. Prompt the user
+ to continue by pressing RETURN. */
+
+static void
+prompt_for_continue (void)
+{
+ char *ignore;
+ char cont_prompt[120];
+
+ if (annotation_level > 1)
+ printf_unfiltered ("\n\032\032pre-prompt-for-continue\n");
+
+ strcpy (cont_prompt,
+ "---Type <return> to continue, or q <return> to quit---");
+ if (annotation_level > 1)
+ strcat (cont_prompt, "\n\032\032prompt-for-continue\n");
+
+ /* We must do this *before* we call gdb_readline, else it will eventually
+ call us -- thinking that we're trying to print beyond the end of the
+ screen. */
+ reinitialize_more_filter ();
+
+ immediate_quit++;
+ /* On a real operating system, the user can quit with SIGINT.
+ But not on GO32.
+
+ 'q' is provided on all systems so users don't have to change habits
+ from system to system, and because telling them what to do in
+ the prompt is more user-friendly than expecting them to think of
+ SIGINT. */
+ /* Call readline, not gdb_readline, because GO32 readline handles control-C
+ whereas control-C to gdb_readline will cause the user to get dumped
+ out to DOS. */
+ ignore = readline (cont_prompt);
+
+ if (annotation_level > 1)
+ printf_unfiltered ("\n\032\032post-prompt-for-continue\n");
+
+ if (ignore)
+ {
+ char *p = ignore;
+ while (*p == ' ' || *p == '\t')
+ ++p;
+ if (p[0] == 'q')
+ {
+ if (!event_loop_p)
+ request_quit (SIGINT);
+ else
+ async_request_quit (0);
+ }
+ xfree (ignore);
+ }
+ immediate_quit--;
+
+ /* Now we have to do this again, so that GDB will know that it doesn't
+ need to save the ---Type <return>--- line at the top of the screen. */
+ reinitialize_more_filter ();
+
+ dont_repeat (); /* Forget prev cmd -- CR won't repeat it. */
+}
+
+/* Reinitialize filter; ie. tell it to reset to original values. */
+
+void
+reinitialize_more_filter (void)
+{
+ lines_printed = 0;
+ chars_printed = 0;
+}
+
+/* Indicate that if the next sequence of characters overflows the line,
+ a newline should be inserted here rather than when it hits the end.
+ If INDENT is non-null, it is a string to be printed to indent the
+ wrapped part on the next line. INDENT must remain accessible until
+ the next call to wrap_here() or until a newline is printed through
+ fputs_filtered().
+
+ If the line is already overfull, we immediately print a newline and
+ the indentation, and disable further wrapping.
+
+ If we don't know the width of lines, but we know the page height,
+ we must not wrap words, but should still keep track of newlines
+ that were explicitly printed.
+
+ INDENT should not contain tabs, as that will mess up the char count
+ on the next line. FIXME.
+
+ This routine is guaranteed to force out any output which has been
+ squirreled away in the wrap_buffer, so wrap_here ((char *)0) can be
+ used to force out output from the wrap_buffer. */
+
+void
+wrap_here (char *indent)
+{
+ /* This should have been allocated, but be paranoid anyway. */
+ if (!wrap_buffer)
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+
+ if (wrap_buffer[0])
+ {
+ *wrap_pointer = '\0';
+ fputs_unfiltered (wrap_buffer, gdb_stdout);
+ }
+ wrap_pointer = wrap_buffer;
+ wrap_buffer[0] = '\0';
+ if (chars_per_line == UINT_MAX) /* No line overflow checking */
+ {
+ wrap_column = 0;
+ }
+ else if (chars_printed >= chars_per_line)
+ {
+ puts_filtered ("\n");
+ if (indent != NULL)
+ puts_filtered (indent);
+ wrap_column = 0;
+ }
+ else
+ {
+ wrap_column = chars_printed;
+ if (indent == NULL)
+ wrap_indent = "";
+ else
+ wrap_indent = indent;
+ }
+}
+
+/* Ensure that whatever gets printed next, using the filtered output
+ commands, starts at the beginning of the line. I.E. if there is
+ any pending output for the current line, flush it and start a new
+ line. Otherwise do nothing. */
+
+void
+begin_line (void)
+{
+ if (chars_printed > 0)
+ {
+ puts_filtered ("\n");
+ }
+}
+
+
+/* Like fputs but if FILTER is true, pause after every screenful.
+
+ Regardless of FILTER can wrap at points other than the final
+ character of a line.
+
+ Unlike fputs, fputs_maybe_filtered does not return a value.
+ It is OK for LINEBUFFER to be NULL, in which case just don't print
+ anything.
+
+ Note that a longjmp to top level may occur in this routine (only if
+ FILTER is true) (since prompt_for_continue may do so) so this
+ routine should not be called when cleanups are not in place. */
+
+static void
+fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
+ int filter)
+{
+ const char *lineptr;
+
+ if (linebuffer == 0)
+ return;
+
+ /* Don't do any filtering if it is disabled. */
+ if ((stream != gdb_stdout) || !pagination_enabled
+ || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX))
+ {
+ fputs_unfiltered (linebuffer, stream);
+ return;
+ }
+
+ /* Go through and output each character. Show line extension
+ when this is necessary; prompt user for new page when this is
+ necessary. */
+
+ lineptr = linebuffer;
+ while (*lineptr)
+ {
+ /* Possible new page. */
+ if (filter &&
+ (lines_printed >= lines_per_page - 1))
+ prompt_for_continue ();
+
+ while (*lineptr && *lineptr != '\n')
+ {
+ /* Print a single line. */
+ if (*lineptr == '\t')
+ {
+ if (wrap_column)
+ *wrap_pointer++ = '\t';
+ else
+ fputc_unfiltered ('\t', stream);
+ /* Shifting right by 3 produces the number of tab stops
+ we have already passed, and then adding one and
+ shifting left 3 advances to the next tab stop. */
+ chars_printed = ((chars_printed >> 3) + 1) << 3;
+ lineptr++;
+ }
+ else
+ {
+ if (wrap_column)
+ *wrap_pointer++ = *lineptr;
+ else
+ fputc_unfiltered (*lineptr, stream);
+ chars_printed++;
+ lineptr++;
+ }
+
+ if (chars_printed >= chars_per_line)
+ {
+ unsigned int save_chars = chars_printed;
+
+ chars_printed = 0;
+ lines_printed++;
+ /* If we aren't actually wrapping, don't output newline --
+ if chars_per_line is right, we probably just overflowed
+ anyway; if it's wrong, let us keep going. */
+ if (wrap_column)
+ fputc_unfiltered ('\n', stream);
+
+ /* Possible new page. */
+ if (lines_printed >= lines_per_page - 1)
+ prompt_for_continue ();
+
+ /* Now output indentation and wrapped string */
+ if (wrap_column)
+ {
+ fputs_unfiltered (wrap_indent, stream);
+ *wrap_pointer = '\0'; /* Null-terminate saved stuff */
+ fputs_unfiltered (wrap_buffer, stream); /* and eject it */
+ /* FIXME, this strlen is what prevents wrap_indent from
+ containing tabs. However, if we recurse to print it
+ and count its chars, we risk trouble if wrap_indent is
+ longer than (the user settable) chars_per_line.
+ Note also that this can set chars_printed > chars_per_line
+ if we are printing a long string. */
+ chars_printed = strlen (wrap_indent)
+ + (save_chars - wrap_column);
+ wrap_pointer = wrap_buffer; /* Reset buffer */
+ wrap_buffer[0] = '\0';
+ wrap_column = 0; /* And disable fancy wrap */
+ }
+ }
+ }
+
+ if (*lineptr == '\n')
+ {
+ chars_printed = 0;
+ wrap_here ((char *) 0); /* Spit out chars, cancel further wraps */
+ lines_printed++;
+ fputc_unfiltered ('\n', stream);
+ lineptr++;
+ }
+ }
+}
+
+void
+fputs_filtered (const char *linebuffer, struct ui_file *stream)
+{
+ fputs_maybe_filtered (linebuffer, stream, 1);
+}
+
+int
+putchar_unfiltered (int c)
+{
+ char buf = c;
+ ui_file_write (gdb_stdout, &buf, 1);
+ return c;
+}
+
+/* Write character C to gdb_stdout using GDB's paging mechanism and return C.
+ May return nonlocally. */
+
+int
+putchar_filtered (int c)
+{
+ return fputc_filtered (c, gdb_stdout);
+}
+
+int
+fputc_unfiltered (int c, struct ui_file *stream)
+{
+ char buf = c;
+ ui_file_write (stream, &buf, 1);
+ return c;
+}
+
+int
+fputc_filtered (int c, struct ui_file *stream)
+{
+ char buf[2];
+
+ buf[0] = c;
+ buf[1] = 0;
+ fputs_filtered (buf, stream);
+ return c;
+}
+
+/* puts_debug is like fputs_unfiltered, except it prints special
+ characters in printable fashion. */
+
+void
+puts_debug (char *prefix, char *string, char *suffix)
+{
+ int ch;
+
+ /* Print prefix and suffix after each line. */
+ static int new_line = 1;
+ static int return_p = 0;
+ static char *prev_prefix = "";
+ static char *prev_suffix = "";
+
+ if (*string == '\n')
+ return_p = 0;
+
+ /* If the prefix is changing, print the previous suffix, a new line,
+ and the new prefix. */
+ if ((return_p || (strcmp (prev_prefix, prefix) != 0)) && !new_line)
+ {
+ fputs_unfiltered (prev_suffix, gdb_stdlog);
+ fputs_unfiltered ("\n", gdb_stdlog);
+ fputs_unfiltered (prefix, gdb_stdlog);
+ }
+
+ /* Print prefix if we printed a newline during the previous call. */
+ if (new_line)
+ {
+ new_line = 0;
+ fputs_unfiltered (prefix, gdb_stdlog);
+ }
+
+ prev_prefix = prefix;
+ prev_suffix = suffix;
+
+ /* Output characters in a printable format. */
+ while ((ch = *string++) != '\0')
+ {
+ switch (ch)
+ {
+ default:
+ if (isprint (ch))
+ fputc_unfiltered (ch, gdb_stdlog);
+
+ else
+ fprintf_unfiltered (gdb_stdlog, "\\x%02x", ch & 0xff);
+ break;
+
+ case '\\':
+ fputs_unfiltered ("\\\\", gdb_stdlog);
+ break;
+ case '\b':
+ fputs_unfiltered ("\\b", gdb_stdlog);
+ break;
+ case '\f':
+ fputs_unfiltered ("\\f", gdb_stdlog);
+ break;
+ case '\n':
+ new_line = 1;
+ fputs_unfiltered ("\\n", gdb_stdlog);
+ break;
+ case '\r':
+ fputs_unfiltered ("\\r", gdb_stdlog);
+ break;
+ case '\t':
+ fputs_unfiltered ("\\t", gdb_stdlog);
+ break;
+ case '\v':
+ fputs_unfiltered ("\\v", gdb_stdlog);
+ break;
+ }
+
+ return_p = ch == '\r';
+ }
+
+ /* Print suffix if we printed a newline. */
+ if (new_line)
+ {
+ fputs_unfiltered (suffix, gdb_stdlog);
+ fputs_unfiltered ("\n", gdb_stdlog);
+ }
+}
+
+
+/* Print a variable number of ARGS using format FORMAT. If this
+ information is going to put the amount written (since the last call
+ to REINITIALIZE_MORE_FILTER or the last page break) over the page size,
+ call prompt_for_continue to get the users permision to continue.
+
+ Unlike fprintf, this function does not return a value.
+
+ We implement three variants, vfprintf (takes a vararg list and stream),
+ fprintf (takes a stream to write on), and printf (the usual).
+
+ Note also that a longjmp to top level may occur in this routine
+ (since prompt_for_continue may do so) so this routine should not be
+ called when cleanups are not in place. */
+
+static void
+vfprintf_maybe_filtered (struct ui_file *stream, const char *format,
+ va_list args, int filter)
+{
+ char *linebuffer;
+ struct cleanup *old_cleanups;
+
+ xvasprintf (&linebuffer, format, args);
+ old_cleanups = make_cleanup (xfree, linebuffer);
+ fputs_maybe_filtered (linebuffer, stream, filter);
+ do_cleanups (old_cleanups);
+}
+
+
+void
+vfprintf_filtered (struct ui_file *stream, const char *format, va_list args)
+{
+ vfprintf_maybe_filtered (stream, format, args, 1);
+}
+
+void
+vfprintf_unfiltered (struct ui_file *stream, const char *format, va_list args)
+{
+ char *linebuffer;
+ struct cleanup *old_cleanups;
+
+ xvasprintf (&linebuffer, format, args);
+ old_cleanups = make_cleanup (xfree, linebuffer);
+ fputs_unfiltered (linebuffer, stream);
+ do_cleanups (old_cleanups);
+}
+
+void
+vprintf_filtered (const char *format, va_list args)
+{
+ vfprintf_maybe_filtered (gdb_stdout, format, args, 1);
+}
+
+void
+vprintf_unfiltered (const char *format, va_list args)
+{
+ vfprintf_unfiltered (gdb_stdout, format, args);
+}
+
+void
+fprintf_filtered (struct ui_file * stream, const char *format,...)
+{
+ va_list args;
+ va_start (args, format);
+ vfprintf_filtered (stream, format, args);
+ va_end (args);
+}
+
+void
+fprintf_unfiltered (struct ui_file * stream, const char *format,...)
+{
+ va_list args;
+ va_start (args, format);
+ vfprintf_unfiltered (stream, format, args);
+ va_end (args);
+}
+
+/* Like fprintf_filtered, but prints its result indented.
+ Called as fprintfi_filtered (spaces, stream, format, ...); */
+
+void
+fprintfi_filtered (int spaces, struct ui_file * stream, const char *format,...)
+{
+ va_list args;
+ va_start (args, format);
+ print_spaces_filtered (spaces, stream);
+
+ vfprintf_filtered (stream, format, args);
+ va_end (args);
+}
+
+
+void
+printf_filtered (const char *format,...)
+{
+ va_list args;
+ va_start (args, format);
+ vfprintf_filtered (gdb_stdout, format, args);
+ va_end (args);
+}
+
+
+void
+printf_unfiltered (const char *format,...)
+{
+ va_list args;
+ va_start (args, format);
+ vfprintf_unfiltered (gdb_stdout, format, args);
+ va_end (args);
+}
+
+/* Like printf_filtered, but prints it's result indented.
+ Called as printfi_filtered (spaces, format, ...); */
+
+void
+printfi_filtered (int spaces, const char *format,...)
+{
+ va_list args;
+ va_start (args, format);
+ print_spaces_filtered (spaces, gdb_stdout);
+ vfprintf_filtered (gdb_stdout, format, args);
+ va_end (args);
+}
+
+/* Easy -- but watch out!
+
+ This routine is *not* a replacement for puts()! puts() appends a newline.
+ This one doesn't, and had better not! */
+
+void
+puts_filtered (const char *string)
+{
+ fputs_filtered (string, gdb_stdout);
+}
+
+void
+puts_unfiltered (const char *string)
+{
+ fputs_unfiltered (string, gdb_stdout);
+}
+
+/* Return a pointer to N spaces and a null. The pointer is good
+ until the next call to here. */
+char *
+n_spaces (int n)
+{
+ char *t;
+ static char *spaces = 0;
+ static int max_spaces = -1;
+
+ if (n > max_spaces)
+ {
+ if (spaces)
+ xfree (spaces);
+ spaces = (char *) xmalloc (n + 1);
+ for (t = spaces + n; t != spaces;)
+ *--t = ' ';
+ spaces[n] = '\0';
+ max_spaces = n;
+ }
+
+ return spaces + max_spaces - n;
+}
+
+/* Print N spaces. */
+void
+print_spaces_filtered (int n, struct ui_file *stream)
+{
+ fputs_filtered (n_spaces (n), stream);
+}
+
+/* C++ demangler stuff. */
+
+/* fprintf_symbol_filtered attempts to demangle NAME, a symbol in language
+ LANG, using demangling args ARG_MODE, and print it filtered to STREAM.
+ If the name is not mangled, or the language for the name is unknown, or
+ demangling is off, the name is printed in its "raw" form. */
+
+void
+fprintf_symbol_filtered (struct ui_file *stream, char *name, enum language lang,
+ int arg_mode)
+{
+ char *demangled;
+
+ if (name != NULL)
+ {
+ /* If user wants to see raw output, no problem. */
+ if (!demangle)
+ {
+ fputs_filtered (name, stream);
+ }
+ else
+ {
+ switch (lang)
+ {
+ case language_cplus:
+ demangled = cplus_demangle (name, arg_mode);
+ break;
+ case language_java:
+ demangled = cplus_demangle (name, arg_mode | DMGL_JAVA);
+ break;
+ case language_chill:
+ demangled = chill_demangle (name);
+ break;
+ default:
+ demangled = NULL;
+ break;
+ }
+ fputs_filtered (demangled ? demangled : name, stream);
+ if (demangled != NULL)
+ {
+ xfree (demangled);
+ }
+ }
+ }
+}
+
+/* Do a strcmp() type operation on STRING1 and STRING2, ignoring any
+ differences in whitespace. Returns 0 if they match, non-zero if they
+ don't (slightly different than strcmp()'s range of return values).
+
+ As an extra hack, string1=="FOO(ARGS)" matches string2=="FOO".
+ This "feature" is useful when searching for matching C++ function names
+ (such as if the user types 'break FOO', where FOO is a mangled C++
+ function). */
+
+int
+strcmp_iw (const char *string1, const char *string2)
+{
+ while ((*string1 != '\0') && (*string2 != '\0'))
+ {
+ while (isspace (*string1))
+ {
+ string1++;
+ }
+ while (isspace (*string2))
+ {
+ string2++;
+ }
+ if (*string1 != *string2)
+ {
+ break;
+ }
+ if (*string1 != '\0')
+ {
+ string1++;
+ string2++;
+ }
+ }
+ return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0');
+}
+
+
+/*
+ ** subset_compare()
+ ** Answer whether string_to_compare is a full or partial match to
+ ** template_string. The partial match must be in sequence starting
+ ** at index 0.
+ */
+int
+subset_compare (char *string_to_compare, char *template_string)
+{
+ int match;
+ if (template_string != (char *) NULL && string_to_compare != (char *) NULL &&
+ strlen (string_to_compare) <= strlen (template_string))
+ match = (strncmp (template_string,
+ string_to_compare,
+ strlen (string_to_compare)) == 0);
+ else
+ match = 0;
+ return match;
+}
+
+
+static void pagination_on_command (char *arg, int from_tty);
+static void
+pagination_on_command (char *arg, int from_tty)
+{
+ pagination_enabled = 1;
+}
+
+static void pagination_on_command (char *arg, int from_tty);
+static void
+pagination_off_command (char *arg, int from_tty)
+{
+ pagination_enabled = 0;
+}
+
+
+void
+initialize_utils (void)
+{
+ struct cmd_list_element *c;
+
+ c = add_set_cmd ("width", class_support, var_uinteger,
+ (char *) &chars_per_line,
+ "Set number of characters gdb thinks are in a line.",
+ &setlist);
+ add_show_from_set (c, &showlist);
+ set_cmd_sfunc (c, set_width_command);
+
+ add_show_from_set
+ (add_set_cmd ("height", class_support,
+ var_uinteger, (char *) &lines_per_page,
+ "Set number of lines gdb thinks are in a page.", &setlist),
+ &showlist);
+
+ init_page_info ();
+
+ /* If the output is not a terminal, don't paginate it. */
+ if (!ui_file_isatty (gdb_stdout))
+ lines_per_page = UINT_MAX;
+
+ set_width_command ((char *) NULL, 0, c);
+
+ add_show_from_set
+ (add_set_cmd ("demangle", class_support, var_boolean,
+ (char *) &demangle,
+ "Set demangling of encoded C++ names when displaying symbols.",
+ &setprintlist),
+ &showprintlist);
+
+ add_show_from_set
+ (add_set_cmd ("pagination", class_support,
+ var_boolean, (char *) &pagination_enabled,
+ "Set state of pagination.", &setlist),
+ &showlist);
+
+ if (xdb_commands)
+ {
+ add_com ("am", class_support, pagination_on_command,
+ "Enable pagination");
+ add_com ("sm", class_support, pagination_off_command,
+ "Disable pagination");
+ }
+
+ add_show_from_set
+ (add_set_cmd ("sevenbit-strings", class_support, var_boolean,
+ (char *) &sevenbit_strings,
+ "Set printing of 8-bit characters in strings as \\nnn.",
+ &setprintlist),
+ &showprintlist);
+
+ add_show_from_set
+ (add_set_cmd ("asm-demangle", class_support, var_boolean,
+ (char *) &asm_demangle,
+ "Set demangling of C++ names in disassembly listings.",
+ &setprintlist),
+ &showprintlist);
+}
+
+/* Machine specific function to handle SIGWINCH signal. */
+
+#ifdef SIGWINCH_HANDLER_BODY
+SIGWINCH_HANDLER_BODY
+#endif
+
+/* print routines to handle variable size regs, etc. */
+
+/* temporary storage using circular buffer */
+#define NUMCELLS 16
+#define CELLSIZE 32
+static char *
+get_cell (void)
+{
+ static char buf[NUMCELLS][CELLSIZE];
+ static int cell = 0;
+ if (++cell >= NUMCELLS)
+ cell = 0;
+ return buf[cell];
+}
+
+int
+strlen_paddr (void)
+{
+ return (TARGET_ADDR_BIT / 8 * 2);
+}
+
+char *
+paddr (CORE_ADDR addr)
+{
+ return phex (addr, TARGET_ADDR_BIT / 8);
+}
+
+char *
+paddr_nz (CORE_ADDR addr)
+{
+ return phex_nz (addr, TARGET_ADDR_BIT / 8);
+}
+
+static void
+decimal2str (char *paddr_str, char *sign, ULONGEST addr)
+{
+ /* steal code from valprint.c:print_decimal(). Should this worry
+ about the real size of addr as the above does? */
+ unsigned long temp[3];
+ int i = 0;
+ do
+ {
+ temp[i] = addr % (1000 * 1000 * 1000);
+ addr /= (1000 * 1000 * 1000);
+ i++;
+ }
+ while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));
+ switch (i)
+ {
+ case 1:
+ sprintf (paddr_str, "%s%lu",
+ sign, temp[0]);
+ break;
+ case 2:
+ sprintf (paddr_str, "%s%lu%09lu",
+ sign, temp[1], temp[0]);
+ break;
+ case 3:
+ sprintf (paddr_str, "%s%lu%09lu%09lu",
+ sign, temp[2], temp[1], temp[0]);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+}
+
+char *
+paddr_u (CORE_ADDR addr)
+{
+ char *paddr_str = get_cell ();
+ decimal2str (paddr_str, "", addr);
+ return paddr_str;
+}
+
+char *
+paddr_d (LONGEST addr)
+{
+ char *paddr_str = get_cell ();
+ if (addr < 0)
+ decimal2str (paddr_str, "-", -addr);
+ else
+ decimal2str (paddr_str, "", addr);
+ return paddr_str;
+}
+
+/* eliminate warning from compiler on 32-bit systems */
+static int thirty_two = 32;
+
+char *
+phex (ULONGEST l, int sizeof_l)
+{
+ char *str;
+ switch (sizeof_l)
+ {
+ case 8:
+ str = get_cell ();
+ sprintf (str, "%08lx%08lx",
+ (unsigned long) (l >> thirty_two),
+ (unsigned long) (l & 0xffffffff));
+ break;
+ case 4:
+ str = get_cell ();
+ sprintf (str, "%08lx", (unsigned long) l);
+ break;
+ case 2:
+ str = get_cell ();
+ sprintf (str, "%04x", (unsigned short) (l & 0xffff));
+ break;
+ default:
+ str = phex (l, sizeof (l));
+ break;
+ }
+ return str;
+}
+
+char *
+phex_nz (ULONGEST l, int sizeof_l)
+{
+ char *str;
+ switch (sizeof_l)
+ {
+ case 8:
+ {
+ unsigned long high = (unsigned long) (l >> thirty_two);
+ str = get_cell ();
+ if (high == 0)
+ sprintf (str, "%lx", (unsigned long) (l & 0xffffffff));
+ else
+ sprintf (str, "%lx%08lx",
+ high, (unsigned long) (l & 0xffffffff));
+ break;
+ }
+ case 4:
+ str = get_cell ();
+ sprintf (str, "%lx", (unsigned long) l);
+ break;
+ case 2:
+ str = get_cell ();
+ sprintf (str, "%x", (unsigned short) (l & 0xffff));
+ break;
+ default:
+ str = phex_nz (l, sizeof (l));
+ break;
+ }
+ return str;
+}
+
+
+/* Convert to / from the hosts pointer to GDB's internal CORE_ADDR
+ using the target's conversion routines. */
+CORE_ADDR
+host_pointer_to_address (void *ptr)
+{
+ if (sizeof (ptr) != TYPE_LENGTH (builtin_type_void_data_ptr))
+ internal_error (__FILE__, __LINE__,
+ "core_addr_to_void_ptr: bad cast");
+ return POINTER_TO_ADDRESS (builtin_type_void_data_ptr, &ptr);
+}
+
+void *
+address_to_host_pointer (CORE_ADDR addr)
+{
+ void *ptr;
+ if (sizeof (ptr) != TYPE_LENGTH (builtin_type_void_data_ptr))
+ internal_error (__FILE__, __LINE__,
+ "core_addr_to_void_ptr: bad cast");
+ ADDRESS_TO_POINTER (builtin_type_void_data_ptr, &ptr, addr);
+ return ptr;
+}
+
+/* Convert a CORE_ADDR into a string. */
+const char *
+core_addr_to_string (const CORE_ADDR addr)
+{
+ char *str = get_cell ();
+ strcpy (str, "0x");
+ strcat (str, phex (addr, sizeof (addr)));
+ return str;
+}
+
+const char *
+core_addr_to_string_nz (const CORE_ADDR addr)
+{
+ char *str = get_cell ();
+ strcpy (str, "0x");
+ strcat (str, phex_nz (addr, sizeof (addr)));
+ return str;
+}
+
+/* Convert a string back into a CORE_ADDR. */
+CORE_ADDR
+string_to_core_addr (const char *my_string)
+{
+ CORE_ADDR addr = 0;
+ if (my_string[0] == '0' && tolower (my_string[1]) == 'x')
+ {
+ /* Assume that it is in decimal. */
+ int i;
+ for (i = 2; my_string[i] != '\0'; i++)
+ {
+ if (isdigit (my_string[i]))
+ addr = (my_string[i] - '0') + (addr * 16);
+ else if (isxdigit (my_string[i]))
+ addr = (tolower (my_string[i]) - 'a' + 0xa) + (addr * 16);
+ else
+ internal_error (__FILE__, __LINE__, "invalid hex");
+ }
+ }
+ else
+ {
+ /* Assume that it is in decimal. */
+ int i;
+ for (i = 0; my_string[i] != '\0'; i++)
+ {
+ if (isdigit (my_string[i]))
+ addr = (my_string[i] - '0') + (addr * 10);
+ else
+ internal_error (__FILE__, __LINE__, "invalid decimal");
+ }
+ }
+ return addr;
+}
+
+char *
+gdb_realpath (const char *filename)
+{
+#if defined(HAVE_REALPATH)
+# if defined (PATH_MAX)
+ char buf[PATH_MAX];
+# define USE_REALPATH
+# elif defined (MAXPATHLEN)
+ char buf[MAXPATHLEN];
+# define USE_REALPATH
+# elif defined (HAVE_UNISTD_H) && defined(HAVE_ALLOCA)
+ char *buf = alloca ((size_t)pathconf ("/", _PC_PATH_MAX));
+# define USE_REALPATH
+# endif
+#endif /* HAVE_REALPATH */
+
+#if defined(USE_REALPATH)
+ char *rp = realpath (filename, buf);
+ return xstrdup (rp ? rp : filename);
+#elif defined(HAVE_CANONICALIZE_FILE_NAME)
+ char *rp = canonicalize_file_name (filename);
+ if (rp == NULL)
+ return xstrdup (filename);
+ else
+ return rp;
+#else
+ return xstrdup (filename);
+#endif
+}
+
+/* Return a copy of FILENAME, with its directory prefix canonicalized
+ by gdb_realpath. */
+
+char *
+xfullpath (const char *filename)
+{
+ const char *base_name = lbasename (filename);
+ char *dir_name;
+ char *real_path;
+ char *result;
+
+ /* Extract the basename of filename, and return immediately
+ a copy of filename if it does not contain any directory prefix. */
+ if (base_name == filename)
+ return xstrdup (filename);
+
+ dir_name = alloca ((size_t) (base_name - filename + 2));
+ /* Allocate enough space to store the dir_name + plus one extra
+ character sometimes needed under Windows (see below), and
+ then the closing \000 character */
+ strncpy (dir_name, filename, base_name - filename);
+ dir_name[base_name - filename] = '\000';
+
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ /* We need to be careful when filename is of the form 'd:foo', which
+ is equivalent of d:./foo, which is totally different from d:/foo. */
+ if (strlen (dir_name) == 2 &&
+ isalpha (dir_name[0]) && dir_name[1] == ':')
+ {
+ dir_name[2] = '.';
+ dir_name[3] = '\000';
+ }
+#endif
+
+ /* Canonicalize the directory prefix, and build the resulting
+ filename. If the dirname realpath already contains an ending
+ directory separator, avoid doubling it. */
+ real_path = gdb_realpath (dir_name);
+ if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1]))
+ result = concat (real_path, base_name, NULL);
+ else
+ result = concat (real_path, SLASH_STRING, base_name, NULL);
+
+ xfree (real_path);
+ return result;
+}
diff --git a/gdb/uw-thread.c b/gdb/uw-thread.c
new file mode 100644
index 00000000000..617cfbd9f81
--- /dev/null
+++ b/gdb/uw-thread.c
@@ -0,0 +1,1059 @@
+/* Low level interface for debugging UnixWare user-mode threads for
+ GDB, the GNU debugger.
+
+ Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+ Written by Nick Duffek <nsd@cygnus.com>.
+
+ 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. */
+
+
+/* Like many systems, UnixWare implements two classes of threads:
+ kernel-mode threads, which are scheduled by the kernel; and
+ user-mode threads, which are scheduled by a library. UnixWare
+ calls these two classes lightweight processes (LWPs) and threads,
+ respectively.
+
+ This module deals with user-mode threads. It calls procfs_ops
+ functions to deal with LWPs and processes and core_ops functions to
+ deal with core files.
+
+ As of this writing, the user-mode thread debugging interface is not
+ documented beyond the comments in <thread.h>. The following
+ description has been gleaned from experience and from information
+ provided by SCO.
+
+ libthread.so, against which all UnixWare user-mode thread programs
+ link, provides a global thread_debug structure named _thr_debug.
+ It has three fields:
+
+ (1) thr_map is a pointer to a pointer to an element of a
+ thread_map ring. A thread_map contains a single thread's id
+ number, state, LWP pointer, recent register state, and other
+ useful information.
+
+ (2) thr_brk is a pointer to a stub function that libthread.so
+ calls when it changes a thread's state, e.g. by creating it,
+ switching it to an LWP, or causing it to exit.
+
+ (3) thr_debug_on controls whether libthread.so calls thr_brk().
+
+ Debuggers are able to track thread activity by setting a private
+ breakpoint on thr_brk() and setting thr_debug_on to 1.
+
+ thr_brk() receives two arguments:
+
+ (1) a pointer to a thread_map describing the thread being
+ changed; and
+
+ (2) an enum thread_change specifying one of the following
+ changes:
+
+ invalid unknown
+ thread_create thread has just been created
+ thread_exit thread has just exited
+ switch_begin thread will be switched to an LWP
+ switch_complete thread has been switched to an LWP
+ cancel_complete thread wasn't switched to an LWP
+ thread_suspend thread has been thr_suspend()ed
+ thread_suspend_pending thread will be thr_suspend()ed
+ thread_continue thread has been thr_continue()d
+
+ The thread_map argument to thr_brk() is NULL under the following
+ circumstances:
+
+ - The main thread is being acted upon. The main thread always
+ has id 1, so its thread_map is easy to find by scanning through
+ _thr_debug.thr_map.
+
+ - A "switch_complete" change is occurring, which means that the
+ thread specified in the most recent "switch_begin" change has
+ moved to an LWP.
+
+ - A "cancel_complete" change is occurring, which means that the
+ thread specified in the most recent "switch_begin" change has
+ not moved to an LWP after all.
+
+ - A spurious "switch_begin" change is occurring after a
+ "thread_exit" change.
+
+ Between switch_begin and switch_complete or cancel_complete, the
+ affected thread's LWP pointer is not reliable. It is possible that
+ other parts of the thread's thread_map are also unreliable during
+ that time. */
+
+
+#include "defs.h"
+#include "gdbthread.h"
+#include "target.h"
+#include "inferior.h"
+#include "regcache.h"
+#include <fcntl.h>
+
+/* <thread.h> includes <sys/priocntl.h>, which requires boolean_t from
+ <sys/types.h>, which doesn't typedef boolean_t with gcc. */
+
+#define boolean_t int
+#include <thread.h>
+#undef boolean_t
+
+#include <synch.h> /* for UnixWare 2.x */
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* Whether to emit debugging output. */
+
+#define DEBUG 0
+
+/* Default debugging output file, overridden by envvar UWTHR_DEBUG. */
+
+#define DEBUG_FILE "/dev/tty"
+
+/* #if DEBUG, write string S to the debugging output channel. */
+
+#if !DEBUG
+# define DBG(fmt_and_args)
+# define DBG2(fmt_and_args)
+#else
+# define DBG(fmt_and_args) dbg fmt_and_args
+# define DBG2(fmt_and_args)
+#endif
+
+/* Back end to CALL_BASE() and TRY_BASE(): evaluate CALL, then convert
+ inferior_ptid to a composite thread/process id. */
+
+#define CALL_BASE_1(call) \
+do { \
+ DBG2(("CALL_BASE(" #call ")")); \
+ call; \
+ do_cleanups (infpid_cleanup); \
+} while (0)
+
+/* If inferior_ptid can be converted to a composite lwp/process id, do so,
+ evaluate base_ops function CALL, and then convert inferior_ptid back to a
+ composite thread/process id.
+
+ Otherwise, issue an error message and return nonlocally. */
+
+#define CALL_BASE(call) \
+do { \
+ if (!lwp_infpid ()) \
+ error ("uw-thread: no lwp"); \
+ CALL_BASE_1 (call); \
+} while (0)
+
+/* Like CALL_BASE(), but instead of returning nonlocally on error, set
+ *CALLED to whether the inferior_ptid conversion was successful. */
+
+#define TRY_BASE(call, called) \
+do { \
+ if ((*(called) = lwp_infpid ())) \
+ CALL_BASE_1 (call); \
+} while (0)
+
+/* Information passed by thread_iter() to its callback parameter. */
+
+typedef struct {
+ struct thread_map map;
+ __lwp_desc_t lwp;
+ CORE_ADDR mapp;
+} iter_t;
+
+/* Private thread data for the thread_info struct. */
+
+struct private_thread_info {
+ int stable; /* 0 if libthread.so is modifying thread map */
+ int thrid; /* thread id assigned by libthread.so */
+ int lwpid; /* thread's lwp if .stable, 0 means no lwp */
+ CORE_ADDR mapp; /* address of thread's map structure */
+};
+
+
+/* procfs.c's target-specific operations. */
+extern struct target_ops procfs_ops;
+
+/* Flag to prevent procfs.c from starting inferior processes. */
+extern int procfs_suppress_run;
+
+/* This module's target-specific operations. */
+static struct target_ops uw_thread_ops;
+
+/* Copy of the target over which uw_thread_ops is pushed. This is
+ more convenient than a pointer to procfs_ops or core_ops, because
+ they lack current_target's default callbacks. */
+static struct target_ops base_ops;
+
+/* Saved pointer to previous owner of target_new_objfile_hook. */
+static void (*target_new_objfile_chain)(struct objfile *);
+
+/* Whether we are debugging a user-space thread program. This isn't
+ set until after libthread.so is loaded by the program being
+ debugged.
+
+ Except for module one-time intialization and where otherwise
+ documented, no functions in this module get called when
+ !uw_thread_active. */
+static int uw_thread_active;
+
+/* For efficiency, cache the addresses of libthread.so's _thr_debug
+ structure, its thr_brk stub function, and the main thread's map. */
+static CORE_ADDR thr_debug_addr;
+static CORE_ADDR thr_brk_addr;
+static CORE_ADDR thr_map_main;
+
+/* Remember the thread most recently marked as switching. Necessary because
+ libthread.so passes null map when calling stub with tc_*_complete. */
+static struct thread_info *switchto_thread;
+
+/* Cleanup chain for safely restoring inferior_ptid after CALL_BASE. */
+static struct cleanup *infpid_cleanup;
+
+
+#if DEBUG
+/* Helper function for DBG() macro: if printf-style FMT is non-null, format it
+ with args and display the result on the debugging output channel. */
+
+static void
+dbg (char *fmt, ...)
+{
+ static int fd = -1, len;
+ va_list args;
+ char buf[1024];
+ char *path;
+
+ if (!fmt)
+ return;
+
+ if (fd < 0)
+ {
+ path = getenv ("UWTHR_DEBUG");
+ if (!path)
+ path = DEBUG_FILE;
+ if ((fd = open (path, O_WRONLY | O_CREAT | O_TRUNC, 0664)) < 0)
+ error ("can't open %s\n", path);
+ }
+
+ va_start (args, fmt);
+ vsprintf (buf, fmt, args);
+ va_end (args);
+
+ len = strlen (buf);
+ buf[len] = '\n';
+ (void)write (fd, buf, len + 1);
+}
+
+#if 0
+/* Return a string representing composite PID's components. */
+
+static char *
+dbgpid (ptid_t ptid)
+{
+ static char *buf, buf1[80], buf2[80];
+ if (!buf || buf == buf2)
+ buf = buf1;
+ else
+ buf = buf2;
+
+ if (PIDGET (ptid) <= 0)
+ sprintf (buf, "%d", PIDGET (ptid));
+ else
+ sprintf (buf, "%s %ld/%d", ISTID (pid) ? "thr" : "lwp",
+ TIDGET (pid), PIDGET (pid));
+
+ return buf;
+}
+
+/* Return a string representing thread state CHANGE. */
+
+static char *
+dbgchange (enum thread_change change)
+{
+ switch (change) {
+ case tc_invalid: return "invalid";
+ case tc_thread_create: return "thread_create";
+ case tc_thread_exit: return "thread_exit";
+ case tc_switch_begin: return "switch_begin";
+ case tc_switch_complete: return "switch_complete";
+ case tc_cancel_complete: return "cancel_complete";
+ case tc_thread_suspend: return "thread_suspend";
+ case tc_thread_suspend_pending: return "thread_suspend_pending";
+ case tc_thread_continue: return "thread_continue";
+ default: return "unknown";
+ }
+}
+
+/* Return a string representing thread STATE. */
+
+static char *
+dbgstate (int state)
+{
+ switch (state) {
+ case TS_ONPROC: return "running";
+ case TS_SLEEP: return "sleeping";
+ case TS_RUNNABLE: return "runnable";
+ case TS_ZOMBIE: return "zombie";
+ case TS_SUSPENDED: return "suspended";
+#ifdef TS_FORK
+ case TS_FORK: return "forking";
+#endif
+ default: return "confused";
+ }
+}
+#endif /* 0 */
+#endif /* DEBUG */
+
+
+/* Read the contents of _thr_debug into *DEBUGP. Return success. */
+
+static int
+read_thr_debug (struct thread_debug *debugp)
+{
+ return base_ops.to_xfer_memory (thr_debug_addr, (char *)debugp,
+ sizeof (*debugp), 0, NULL, &base_ops);
+}
+
+/* Read into MAP the contents of the thread map at inferior process address
+ MAPP. Return success. */
+
+static int
+read_map (CORE_ADDR mapp, struct thread_map *map)
+{
+ return base_ops.to_xfer_memory ((CORE_ADDR)THR_MAP (mapp), (char *)map,
+ sizeof (*map), 0, NULL, &base_ops);
+}
+
+/* Read into LWP the contents of the lwp decriptor at inferior process address
+ LWPP. Return success. */
+
+static int
+read_lwp (CORE_ADDR lwpp, __lwp_desc_t *lwp)
+{
+ return base_ops.to_xfer_memory (lwpp, (char *)lwp,
+ sizeof (*lwp), 0, NULL, &base_ops);
+}
+
+/* Iterate through all user threads, applying FUNC(<map>, <lwp>, DATA) until
+ (a) FUNC returns nonzero,
+ (b) FUNC has been applied to all threads, or
+ (c) an error occurs,
+ where <map> is the thread's struct thread_map and <lwp> if non-null is the
+ thread's current __lwp_desc_t.
+
+ If a call to FUNC returns nonzero, return that value; otherwise, return 0. */
+
+static int
+thread_iter (int (*func)(iter_t *, void *), void *data)
+{
+ struct thread_debug debug;
+ CORE_ADDR first, mapp;
+ iter_t iter;
+ int ret;
+
+ if (!read_thr_debug (&debug))
+ return 0;
+ if (!base_ops.to_xfer_memory ((CORE_ADDR)debug.thr_map, (char *)&mapp,
+ sizeof (mapp), 0, NULL, &base_ops))
+ return 0;
+ if (!mapp)
+ return 0;
+
+ for (first = mapp;;)
+ {
+ if (!read_map (mapp, &iter.map))
+ return 0;
+
+ if (iter.map.thr_lwpp)
+ if (!read_lwp ((CORE_ADDR)iter.map.thr_lwpp, &iter.lwp))
+ return 0;
+
+ iter.mapp = mapp;
+ if ((ret = func (&iter, data)))
+ return ret;
+
+ mapp = (CORE_ADDR)iter.map.thr_next;
+ if (mapp == first)
+ return 0;
+ }
+}
+
+/* Deactivate user-mode thread support. */
+
+static void
+deactivate_uw_thread (void)
+{
+ remove_thread_event_breakpoints ();
+ uw_thread_active = 0;
+ unpush_target (&uw_thread_ops);
+}
+
+/* Return the composite lwp/process id corresponding to composite
+ id PID. If PID is a thread with no lwp, return 0. */
+
+static ptid_t
+thr_to_lwp (ptid_t ptid)
+{
+ struct thread_info *info;
+ ptid_t lid;
+
+ if (!ISTID (ptid))
+ lid = ptid;
+ else if (!(info = find_thread_pid (ptid)))
+ lid = null_ptid;
+ else if (!info->private->lwpid)
+ lid = null_ptid;
+ else
+ lid = MKLID (PIDGET (ptid), info->private->lwpid);
+
+ DBG2((" thr_to_lwp(%s) = %s", dbgpid (pid), dbgpid (lid)));
+ return lid;
+}
+
+/* find_thread_lwp() callback: return whether TP describes a thread
+ associated with lwp id DATA. */
+
+static int
+find_thread_lwp_callback (struct thread_info *tp, void *data)
+{
+ int lwpid = (int)data;
+
+ if (!ISTID (tp->ptid))
+ return 0;
+ if (!tp->private->stable)
+ return 0;
+ if (lwpid != tp->private->lwpid)
+ return 0;
+
+ /* match */
+ return 1;
+}
+
+/* If a thread is associated with lwp id LWPID, return the corresponding
+ member of the global thread list; otherwise, return null. */
+
+static struct thread_info *
+find_thread_lwp (int lwpid)
+{
+ return iterate_over_threads (find_thread_lwp_callback, (void *)lwpid);
+}
+
+/* Return the composite thread/process id corresponding to composite
+ id PID. If PID is an lwp with no thread, return PID. */
+
+static ptid_t
+lwp_to_thr (ptid_t ptid)
+{
+ struct thread_info *info;
+ int lwpid;
+ ptid_t tid = ptid;
+
+ if (ISTID (ptid))
+ goto done;
+ if (!(lwpid = LIDGET (ptid)))
+ goto done;
+ if (!(info = find_thread_lwp (lwpid)))
+ goto done;
+ tid = MKTID (PIDGET (ptid), info->private->thrid);
+
+ done:
+ DBG2((ISTID (tid) ? NULL : "lwp_to_thr: no thr for %s", dbgpid (ptid)));
+ return tid;
+}
+
+/* do_cleanups() callback: convert inferior_ptid to a composite
+ thread/process id after having made a procfs call. */
+
+static void
+thr_infpid (void *unused)
+{
+ ptid_t ptid = lwp_to_thr (inferior_ptid);
+ DBG2((" inferior_ptid from procfs: %s => %s",
+ dbgpid (inferior_ptid), dbgpid (ptid)));
+ inferior_ptid = ptid;
+}
+
+/* If possible, convert inferior_ptid to a composite lwp/process id in
+ preparation for making a procfs call. Return success. */
+
+static int
+lwp_infpid (void)
+{
+ ptid_t ptid = thr_to_lwp (inferior_ptid);
+ DBG2((" inferior_ptid to procfs: %s => %s",
+ dbgpid (inferior_ptid), dbgpid (ptid)));
+
+ if (ptid_equal (ptid, null_ptid))
+ return 0;
+
+ inferior_ptid = ptid;
+ infpid_cleanup = make_cleanup (thr_infpid, NULL);
+ return 1;
+}
+
+/* Add to the global thread list a new user-mode thread with system id THRID,
+ lwp id LWPID, map address MAPP, and composite thread/process PID. */
+
+static void
+add_thread_uw (int thrid, int lwpid, CORE_ADDR mapp, ptid_t ptid)
+{
+ struct thread_info *newthread;
+
+ if ((newthread = add_thread (ptid)) == NULL)
+ error ("failed to create new thread structure");
+
+ newthread->private = xmalloc (sizeof (struct private_thread_info));
+ newthread->private->stable = 1;
+ newthread->private->thrid = thrid;
+ newthread->private->lwpid = lwpid;
+ newthread->private->mapp = mapp;
+
+ if (target_has_execution)
+ printf_unfiltered ("[New %s]\n", target_pid_to_str (ptid));
+}
+
+/* notice_threads() and find_main() callback: if the thread list doesn't
+ already contain the thread described by ITER, add it if it's the main
+ thread or if !DATA. */
+
+static int
+notice_thread (iter_t *iter, void *data)
+{
+ int thrid = iter->map.thr_tid;
+ int lwpid = !iter->map.thr_lwpp ? 0 : iter->lwp.lwp_id;
+ ptid_t ptid = MKTID (PIDGET (inferior_ptid), thrid);
+
+ if (!find_thread_pid (ptid) && (!data || thrid == 1))
+ add_thread_uw (thrid, lwpid, iter->mapp, ptid);
+
+ return 0;
+}
+
+/* Add to the thread list any threads it doesn't already contain. */
+
+static void
+notice_threads (void)
+{
+ thread_iter (notice_thread, NULL);
+}
+
+/* Return the address of the main thread's map. On error, return 0. */
+
+static CORE_ADDR
+find_main (void)
+{
+ if (!thr_map_main)
+ {
+ struct thread_info *info;
+ thread_iter (notice_thread, (void *)1);
+ if ((info = find_thread_pid (MKTID (PIDGET (inferior_ptid), 1))))
+ thr_map_main = info->private->mapp;
+ }
+ return thr_map_main;
+}
+
+/* Attach to process specified by ARGS, then initialize for debugging it
+ and wait for the trace-trap that results from attaching.
+
+ This function only gets called with uw_thread_active == 0. */
+
+static void
+uw_thread_attach (char *args, int from_tty)
+{
+ procfs_ops.to_attach (args, from_tty);
+ if (uw_thread_active)
+ thr_infpid (NULL);
+}
+
+/* Detach from the process attached to by uw_thread_attach(). */
+
+static void
+uw_thread_detach (char *args, int from_tty)
+{
+ deactivate_uw_thread ();
+ base_ops.to_detach (args, from_tty);
+}
+
+/* Tell the inferior process to continue running thread PID if >= 0
+ and all threads otherwise. */
+
+static void
+uw_thread_resume (ptid_t ptid, int step, enum target_signal signo)
+{
+ if (PIDGET (ptid) > 0)
+ {
+ ptid = thr_to_lwp (ptid);
+ if (ptid_equal (ptid, null_ptid))
+ ptid = pid_to_ptid (-1);
+ }
+
+ CALL_BASE (base_ops.to_resume (ptid, step, signo));
+}
+
+/* If the trap we just received from lwp PID was due to a breakpoint
+ on the libthread.so debugging stub, update this module's state
+ accordingly. */
+
+static void
+libthread_stub (ptid_t ptid)
+{
+ CORE_ADDR sp, mapp, mapp_main;
+ enum thread_change change;
+ struct thread_map map;
+ __lwp_desc_t lwp;
+ int lwpid;
+ ptid_t tid = null_ptid;
+ struct thread_info *info;
+
+ /* Check for stub breakpoint. */
+ if (read_pc_pid (ptid) - DECR_PC_AFTER_BREAK != thr_brk_addr)
+ return;
+
+ /* Retrieve stub args. */
+ sp = read_register_pid (SP_REGNUM, ptid);
+ if (!base_ops.to_xfer_memory (sp + SP_ARG0, (char *)&mapp,
+ sizeof (mapp), 0, NULL, &base_ops))
+ goto err;
+ if (!base_ops.to_xfer_memory (sp + SP_ARG0 + sizeof (mapp), (char *)&change,
+ sizeof (change), 0, NULL, &base_ops))
+ goto err;
+
+ /* create_inferior() may not have finished yet, so notice the main
+ thread to ensure that it's displayed first by add_thread(). */
+ mapp_main = find_main ();
+
+ /* Notice thread creation, deletion, or stability change. */
+ switch (change) {
+ case tc_switch_begin:
+ if (!mapp) /* usually means main thread */
+ mapp = mapp_main;
+ /* fall through */
+
+ case tc_thread_create:
+ case tc_thread_exit:
+ if (!mapp)
+ break;
+ if (!read_map (mapp, &map))
+ goto err;
+ tid = MKTID (PIDGET (ptid), map.thr_tid);
+
+ switch (change) {
+ case tc_thread_create: /* new thread */
+ if (!map.thr_lwpp)
+ lwpid = 0;
+ else if (!read_lwp ((CORE_ADDR)map.thr_lwpp, &lwp))
+ goto err;
+ else
+ lwpid = lwp.lwp_id;
+ add_thread_uw (map.thr_tid, lwpid, mapp, tid);
+ break;
+
+ case tc_thread_exit: /* thread has exited */
+ printf_unfiltered ("[Exited %s]\n", target_pid_to_str (tid));
+ delete_thread (tid);
+ if (ptid_equal (tid, inferior_ptid))
+ inferior_ptid = ptid;
+ break;
+
+ case tc_switch_begin: /* lwp is switching threads */
+ if (switchto_thread)
+ goto err;
+ if (!(switchto_thread = find_thread_pid (tid)))
+ goto err;
+ switchto_thread->private->stable = 0;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case tc_switch_complete: /* lwp has switched threads */
+ case tc_cancel_complete: /* lwp didn't switch threads */
+ if (!switchto_thread)
+ goto err;
+
+ if (change == tc_switch_complete)
+ {
+ /* If switchto_thread is the main thread, then (a) the corresponding
+ tc_switch_begin probably received a null map argument and therefore
+ (b) it may have been a spurious switch following a tc_thread_exit.
+
+ Therefore, explicitly query the thread's lwp before caching it in
+ its thread list entry. */
+
+ if (!read_map (switchto_thread->private->mapp, &map))
+ goto err;
+ if (map.thr_lwpp)
+ {
+ if (!read_lwp ((CORE_ADDR)map.thr_lwpp, &lwp))
+ goto err;
+ if ((info = find_thread_lwp (lwp.lwp_id)))
+ info->private->lwpid = 0;
+ switchto_thread->private->lwpid = lwp.lwp_id;
+ }
+ }
+
+ switchto_thread->private->stable = 1;
+ switchto_thread = NULL;
+ break;
+
+ case tc_invalid:
+ case tc_thread_suspend:
+ case tc_thread_suspend_pending:
+ case tc_thread_continue:
+ err:
+ DBG(("unexpected condition in libthread_stub()"));
+ break;
+ }
+
+ DBG2(("libthread_stub(%s): %s %s %s", dbgpid (pid), dbgpid (tid),
+ dbgchange (change), tid ? dbgstate (map.thr_state) : ""));
+}
+
+/* Wait for thread/lwp/process ID if >= 0 or for any thread otherwise. */
+
+static ptid_t
+uw_thread_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ if (PIDGET (ptid) > 0)
+ ptid = thr_to_lwp (ptid);
+ if (PIDGET (ptid) <= 0)
+ ptid = pid_to_ptid (-1);
+
+ CALL_BASE (ptid = base_ops.to_wait (ptid, status));
+
+ if (status->kind == TARGET_WAITKIND_STOPPED &&
+ status->value.sig == TARGET_SIGNAL_TRAP)
+ libthread_stub (ptid);
+
+ return lwp_to_thr (ptid);
+}
+
+/* Tell gdb about the registers in the thread/lwp/process specified by
+ inferior_ptid. */
+
+static void
+uw_thread_fetch_registers (int regno)
+{
+ int called;
+ struct thread_info *info;
+ struct thread_map map;
+
+ TRY_BASE (base_ops.to_fetch_registers (regno), &called);
+ if (called)
+ return;
+
+ if (!(info = find_thread_pid (inferior_ptid)))
+ return;
+ if (!read_map (info->private->mapp, &map))
+ return;
+
+ supply_gregset (&map.thr_ucontext.uc_mcontext.gregs);
+ supply_fpregset (&map.thr_ucontext.uc_mcontext.fpregs);
+}
+
+/* Store gdb's current view of the register set into the thread/lwp/process
+ specified by inferior_ptid. */
+
+static void
+uw_thread_store_registers (int regno)
+{
+ CALL_BASE (base_ops.to_store_registers (regno));
+}
+
+/* Prepare to modify the registers array. */
+
+static void
+uw_thread_prepare_to_store (void)
+{
+ CALL_BASE (base_ops.to_prepare_to_store ());
+}
+
+/* Fork an inferior process and start debugging it.
+
+ This function only gets called with uw_thread_active == 0. */
+
+static void
+uw_thread_create_inferior (char *exec_file, char *allargs, char **env)
+{
+ if (uw_thread_active)
+ deactivate_uw_thread ();
+
+ procfs_ops.to_create_inferior (exec_file, allargs, env);
+ if (uw_thread_active)
+ {
+ find_main ();
+ thr_infpid (NULL);
+ }
+}
+
+/* Kill and forget about the inferior process. */
+
+static void
+uw_thread_kill (void)
+{
+ base_ops.to_kill ();
+}
+
+/* Clean up after the inferior exits. */
+
+static void
+uw_thread_mourn_inferior (void)
+{
+ deactivate_uw_thread ();
+ base_ops.to_mourn_inferior ();
+}
+
+/* Return whether this module can attach to and run processes.
+
+ This function only gets called with uw_thread_active == 0. */
+
+static int
+uw_thread_can_run (void)
+{
+ return procfs_suppress_run;
+}
+
+/* Return whether thread PID is still valid. */
+
+static int
+uw_thread_alive (ptid_t ptid)
+{
+ if (!ISTID (ptid))
+ return base_ops.to_thread_alive (ptid);
+
+ /* If it's in the thread list, it's valid, because otherwise
+ libthread_stub() would have deleted it. */
+ return in_thread_list (ptid);
+}
+
+/* Add to the thread list any threads and lwps it doesn't already contain. */
+
+static void
+uw_thread_find_new_threads (void)
+{
+ CALL_BASE (if (base_ops.to_find_new_threads)
+ base_ops.to_find_new_threads ());
+ notice_threads ();
+}
+
+/* Return a string for pretty-printing PID in "info threads" output.
+ This may be called by either procfs.c or by generic gdb. */
+
+static char *
+uw_thread_pid_to_str (ptid_t ptid)
+{
+#define FMT "Thread %ld"
+ static char buf[sizeof (FMT) + 3 * sizeof (long)];
+
+ if (!ISTID (ptid))
+ /* core_ops says "process foo", so call procfs_ops explicitly. */
+ return procfs_ops.to_pid_to_str (ptid);
+
+ sprintf (buf, FMT, TIDGET (ptid));
+#undef FMT
+ return buf;
+}
+
+/* Return a string displaying INFO state information in "info threads"
+ output. */
+
+static char *
+uw_extra_thread_info (struct thread_info *info)
+{
+ static char buf[80];
+ struct thread_map map;
+ __lwp_desc_t lwp;
+ int lwpid;
+ char *name;
+
+ if (!ISTID (info->ptid))
+ return NULL;
+
+ if (!info->private->stable)
+ return "switching";
+
+ if (!read_map (info->private->mapp, &map))
+ return NULL;
+
+ if (!map.thr_lwpp || !read_lwp ((CORE_ADDR)map.thr_lwpp, &lwp))
+ lwpid = 0;
+ else
+ lwpid = lwp.lwp_id;
+
+ switch (map.thr_state) {
+ case TS_ONPROC: name = "running"; break;
+ case TS_SLEEP: name = "sleeping"; break;
+ case TS_RUNNABLE: name = "runnable"; break;
+ case TS_ZOMBIE: name = "zombie"; break;
+ case TS_SUSPENDED: name = "suspended"; break;
+#ifdef TS_FORK
+ case TS_FORK: name = "forking"; break;
+#endif
+ default: name = "confused"; break;
+ }
+
+ if (!lwpid)
+ return name;
+
+ sprintf (buf, "%s, LWP %d", name, lwpid);
+ return buf;
+}
+
+/* Check whether libthread.so has just been loaded, and if so, try to
+ initialize user-space thread debugging support.
+
+ libthread.so loading happens while (a) an inferior process is being
+ started by procfs and (b) a core image is being loaded.
+
+ This function often gets called with uw_thread_active == 0. */
+
+static void
+libthread_init (void)
+{
+ struct minimal_symbol *ms;
+ struct thread_debug debug;
+ CORE_ADDR onp;
+ struct breakpoint *b;
+ int one = 1;
+
+ /* Don't initialize twice. */
+ if (uw_thread_active)
+ return;
+
+ /* Check whether libthread.so has been loaded. */
+ if (!(ms = lookup_minimal_symbol ("_thr_debug", NULL, NULL)))
+ return;
+
+ /* Cache _thr_debug's address. */
+ if (!(thr_debug_addr = SYMBOL_VALUE_ADDRESS (ms)))
+ return;
+
+ /* Initialize base_ops.to_xfer_memory(). */
+ base_ops = current_target;
+
+ /* Load _thr_debug's current contents. */
+ if (!read_thr_debug (&debug))
+ return;
+
+ /* User code (e.g. my test programs) may dereference _thr_debug,
+ making it availble to GDB before shared libs are loaded. */
+ if (!debug.thr_map)
+ return;
+
+ /* libthread.so has been loaded, and the current_target should now
+ reflect core_ops or procfs_ops. */
+ push_target (&uw_thread_ops); /* must precede notice_threads() */
+ uw_thread_active = 1;
+
+ if (!target_has_execution)
+
+ /* Locate threads in core file. */
+ notice_threads ();
+
+ else
+ {
+ /* Set a breakpoint on the stub function provided by libthread.so. */
+ thr_brk_addr = (CORE_ADDR)debug.thr_brk;
+ if (!(b = create_thread_event_breakpoint (thr_brk_addr)))
+ goto err;
+
+ /* Activate the stub function. */
+ onp = (CORE_ADDR)&((struct thread_debug *)thr_debug_addr)->thr_debug_on;
+ if (!base_ops.to_xfer_memory ((CORE_ADDR)onp, (char *)&one,
+ sizeof (one), 1, NULL, &base_ops))
+ {
+ delete_breakpoint (b);
+ goto err;
+ }
+
+ /* Prepare for finding the main thread, which doesn't yet exist. */
+ thr_map_main = 0;
+ }
+
+ return;
+
+ err:
+ warning ("uw-thread: unable to initialize user-mode thread debugging\n");
+ deactivate_uw_thread ();
+}
+
+/* target_new_objfile_hook callback.
+
+ If OBJFILE is non-null, check whether libthread.so was just loaded,
+ and if so, prepare for user-mode thread debugging.
+
+ If OBJFILE is null, libthread.so has gone away, so stop debugging
+ user-mode threads.
+
+ This function often gets called with uw_thread_active == 0. */
+
+static void
+uw_thread_new_objfile (struct objfile *objfile)
+{
+ if (objfile)
+ libthread_init ();
+
+ else if (uw_thread_active)
+ deactivate_uw_thread ();
+
+ if (target_new_objfile_chain)
+ target_new_objfile_chain (objfile);
+}
+
+/* Initialize uw_thread_ops. */
+
+static void
+init_uw_thread_ops (void)
+{
+ uw_thread_ops.to_shortname = "unixware-threads";
+ uw_thread_ops.to_longname = "UnixWare threads and pthread.";
+ uw_thread_ops.to_doc = "UnixWare threads and pthread support.";
+ uw_thread_ops.to_attach = uw_thread_attach;
+ uw_thread_ops.to_detach = uw_thread_detach;
+ uw_thread_ops.to_resume = uw_thread_resume;
+ uw_thread_ops.to_wait = uw_thread_wait;
+ uw_thread_ops.to_fetch_registers = uw_thread_fetch_registers;
+ uw_thread_ops.to_store_registers = uw_thread_store_registers;
+ uw_thread_ops.to_prepare_to_store = uw_thread_prepare_to_store;
+ uw_thread_ops.to_create_inferior = uw_thread_create_inferior;
+ uw_thread_ops.to_kill = uw_thread_kill;
+ uw_thread_ops.to_mourn_inferior = uw_thread_mourn_inferior;
+ uw_thread_ops.to_can_run = uw_thread_can_run;
+ uw_thread_ops.to_thread_alive = uw_thread_alive;
+ uw_thread_ops.to_find_new_threads = uw_thread_find_new_threads;
+ uw_thread_ops.to_pid_to_str = uw_thread_pid_to_str;
+ uw_thread_ops.to_extra_thread_info = uw_extra_thread_info;
+ uw_thread_ops.to_stratum = thread_stratum;
+ uw_thread_ops.to_magic = OPS_MAGIC;
+}
+
+/* Module startup initialization function, automagically called by
+ init.c. */
+
+void
+_initialize_uw_thread (void)
+{
+ init_uw_thread_ops ();
+ add_target (&uw_thread_ops);
+
+ procfs_suppress_run = 1;
+
+ /* Notice when libthread.so gets loaded. */
+ target_new_objfile_chain = target_new_objfile_hook;
+ target_new_objfile_hook = uw_thread_new_objfile;
+}
diff --git a/gdb/v850-tdep.c b/gdb/v850-tdep.c
new file mode 100644
index 00000000000..e1869d04bab
--- /dev/null
+++ b/gdb/v850-tdep.c
@@ -0,0 +1,1198 @@
+/* Target-dependent code for the NEC V850 for GDB, the GNU debugger.
+ Copyright 1996, 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "obstack.h"
+#include "target.h"
+#include "value.h"
+#include "bfd.h"
+#include "gdb_string.h"
+#include "gdbcore.h"
+#include "symfile.h"
+#include "arch-utils.h"
+#include "regcache.h"
+#include "symtab.h"
+
+struct gdbarch_tdep
+{
+ /* gdbarch target dependent data here. Currently unused for v850. */
+};
+
+/* Extra info which is saved in each frame_info. */
+struct frame_extra_info
+{
+};
+
+enum {
+ E_R0_REGNUM,
+ E_R1_REGNUM,
+ E_R2_REGNUM, E_SAVE1_START_REGNUM = E_R2_REGNUM, E_SAVE1_END_REGNUM = E_R2_REGNUM,
+ E_R3_REGNUM, E_SP_REGNUM = E_R3_REGNUM,
+ E_R4_REGNUM,
+ E_R5_REGNUM,
+ E_R6_REGNUM, E_ARG0_REGNUM = E_R6_REGNUM,
+ E_R7_REGNUM,
+ E_R8_REGNUM,
+ E_R9_REGNUM, E_ARGLAST_REGNUM = E_R9_REGNUM,
+ E_R10_REGNUM, E_V0_REGNUM = E_R10_REGNUM,
+ E_R11_REGNUM, E_V1_REGNUM = E_R11_REGNUM,
+ E_R12_REGNUM,
+ E_R13_REGNUM,
+ E_R14_REGNUM,
+ E_R15_REGNUM,
+ E_R16_REGNUM,
+ E_R17_REGNUM,
+ E_R18_REGNUM,
+ E_R19_REGNUM,
+ E_R20_REGNUM, E_SAVE2_START_REGNUM = E_R20_REGNUM,
+ E_R21_REGNUM,
+ E_R22_REGNUM,
+ E_R23_REGNUM,
+ E_R24_REGNUM,
+ E_R25_REGNUM,
+ E_R26_REGNUM,
+ E_R27_REGNUM,
+ E_R28_REGNUM,
+ E_R29_REGNUM, E_SAVE2_END_REGNUM = E_R29_REGNUM, E_FP_RAW_REGNUM = E_R29_REGNUM,
+ E_R30_REGNUM, E_EP_REGNUM = E_R30_REGNUM,
+ E_R31_REGNUM, E_SAVE3_START_REGNUM = E_R31_REGNUM, E_SAVE3_END_REGNUM = E_R31_REGNUM, E_RP_REGNUM = E_R31_REGNUM,
+ E_R32_REGNUM, E_SR0_REGNUM = E_R32_REGNUM,
+ E_R33_REGNUM,
+ E_R34_REGNUM,
+ E_R35_REGNUM,
+ E_R36_REGNUM,
+ E_R37_REGNUM, E_PS_REGNUM = E_R37_REGNUM,
+ E_R38_REGNUM,
+ E_R39_REGNUM,
+ E_R40_REGNUM,
+ E_R41_REGNUM,
+ E_R42_REGNUM,
+ E_R43_REGNUM,
+ E_R44_REGNUM,
+ E_R45_REGNUM,
+ E_R46_REGNUM,
+ E_R47_REGNUM,
+ E_R48_REGNUM,
+ E_R49_REGNUM,
+ E_R50_REGNUM,
+ E_R51_REGNUM,
+ E_R52_REGNUM, E_CTBP_REGNUM = E_R52_REGNUM,
+ E_R53_REGNUM,
+ E_R54_REGNUM,
+ E_R55_REGNUM,
+ E_R56_REGNUM,
+ E_R57_REGNUM,
+ E_R58_REGNUM,
+ E_R59_REGNUM,
+ E_R60_REGNUM,
+ E_R61_REGNUM,
+ E_R62_REGNUM,
+ E_R63_REGNUM,
+ E_R64_REGNUM, E_PC_REGNUM = E_R64_REGNUM,
+ E_R65_REGNUM, E_FP_REGNUM = E_R65_REGNUM,
+ E_NUM_REGS
+};
+
+enum
+{
+ v850_reg_size = 4
+};
+
+/* Size of all registers as a whole. */
+enum
+{
+ E_ALL_REGS_SIZE = (E_NUM_REGS) * v850_reg_size
+};
+
+static LONGEST call_dummy_nil[] = {0};
+
+static char *v850_generic_reg_names[] =
+{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
+ "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
+ "sr16", "sr17", "sr18", "sr19", "sr20", "sr21", "sr22", "sr23",
+ "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
+ "pc", "fp"
+};
+
+static char *v850e_reg_names[] =
+{
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
+ "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
+ "ctpc", "ctpsw", "dbpc", "dbpsw", "ctbp", "sr21", "sr22", "sr23",
+ "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
+ "pc", "fp"
+};
+
+char **v850_register_names = v850_generic_reg_names;
+
+struct
+ {
+ char **regnames;
+ int mach;
+ }
+v850_processor_type_table[] =
+{
+ {
+ v850_generic_reg_names, bfd_mach_v850
+ }
+ ,
+ {
+ v850e_reg_names, bfd_mach_v850e
+ }
+ ,
+ {
+ v850e_reg_names, bfd_mach_v850ea
+ }
+ ,
+ {
+ NULL, 0
+ }
+};
+
+/* Info gleaned from scanning a function's prologue. */
+
+struct pifsr /* Info about one saved reg */
+ {
+ int framereg; /* Frame reg (SP or FP) */
+ int offset; /* Offset from framereg */
+ int cur_frameoffset; /* Current frameoffset */
+ int reg; /* Saved register number */
+ };
+
+struct prologue_info
+ {
+ int framereg;
+ int frameoffset;
+ int start_function;
+ struct pifsr *pifsrs;
+ };
+
+static CORE_ADDR v850_scan_prologue (CORE_ADDR pc, struct prologue_info *fs);
+
+/* Function: v850_register_name
+ Returns the name of the v850/v850e register N. */
+
+static char *
+v850_register_name (int regnum)
+{
+ if (regnum < 0 || regnum >= E_NUM_REGS)
+ internal_error (__FILE__, __LINE__,
+ "v850_register_name: illegal register number %d",
+ regnum);
+ else
+ return v850_register_names[regnum];
+
+}
+
+/* Function: v850_register_byte
+ Returns the byte position in the register cache for register N. */
+
+static int
+v850_register_byte (int regnum)
+{
+ if (regnum < 0 || regnum >= E_NUM_REGS)
+ internal_error (__FILE__, __LINE__,
+ "v850_register_byte: illegal register number %d",
+ regnum);
+ else
+ return regnum * v850_reg_size;
+}
+
+/* Function: v850_register_raw_size
+ Returns the number of bytes occupied by the register on the target. */
+
+static int
+v850_register_raw_size (int regnum)
+{
+ if (regnum < 0 || regnum >= E_NUM_REGS)
+ internal_error (__FILE__, __LINE__,
+ "v850_register_raw_size: illegal register number %d",
+ regnum);
+ /* Only the PC has 4 Byte, all other registers 2 Byte. */
+ else
+ return v850_reg_size;
+}
+
+/* Function: v850_register_virtual_size
+ Returns the number of bytes occupied by the register as represented
+ internally by gdb. */
+
+static int
+v850_register_virtual_size (int regnum)
+{
+ return v850_register_raw_size (regnum);
+}
+
+/* Function: v850_reg_virtual_type
+ Returns the default type for register N. */
+
+static struct type *
+v850_reg_virtual_type (int regnum)
+{
+ if (regnum < 0 || regnum >= E_NUM_REGS)
+ internal_error (__FILE__, __LINE__,
+ "v850_register_virtual_type: illegal register number %d",
+ regnum);
+ else if (regnum == E_PC_REGNUM)
+ return builtin_type_uint32;
+ else
+ return builtin_type_int32;
+}
+
+/* Should call_function allocate stack space for a struct return? */
+int
+v850_use_struct_convention (int gcc_p, struct type *type)
+{
+ return (TYPE_NFIELDS (type) > 1 || TYPE_LENGTH (type) > 4);
+}
+
+
+
+/* Structure for mapping bits in register lists to register numbers. */
+struct reg_list
+{
+ long mask;
+ int regno;
+};
+
+/* Helper function for v850_scan_prologue to handle prepare instruction. */
+
+static void
+handle_prepare (int insn, int insn2, CORE_ADDR * current_pc_ptr,
+ struct prologue_info *pi, struct pifsr **pifsr_ptr)
+{
+ CORE_ADDR current_pc = *current_pc_ptr;
+ struct pifsr *pifsr = *pifsr_ptr;
+ long next = insn2 & 0xffff;
+ long list12 = ((insn & 1) << 16) + (next & 0xffe0);
+ long offset = (insn & 0x3e) << 1;
+ static struct reg_list reg_table[] =
+ {
+ {0x00800, 20}, /* r20 */
+ {0x00400, 21}, /* r21 */
+ {0x00200, 22}, /* r22 */
+ {0x00100, 23}, /* r23 */
+ {0x08000, 24}, /* r24 */
+ {0x04000, 25}, /* r25 */
+ {0x02000, 26}, /* r26 */
+ {0x01000, 27}, /* r27 */
+ {0x00080, 28}, /* r28 */
+ {0x00040, 29}, /* r29 */
+ {0x10000, 30}, /* ep */
+ {0x00020, 31}, /* lp */
+ {0, 0} /* end of table */
+ };
+ int i;
+
+ if ((next & 0x1f) == 0x0b) /* skip imm16 argument */
+ current_pc += 2;
+ else if ((next & 0x1f) == 0x13) /* skip imm16 argument */
+ current_pc += 2;
+ else if ((next & 0x1f) == 0x1b) /* skip imm32 argument */
+ current_pc += 4;
+
+ /* Calculate the total size of the saved registers, and add it
+ it to the immediate value used to adjust SP. */
+ for (i = 0; reg_table[i].mask != 0; i++)
+ if (list12 & reg_table[i].mask)
+ offset += v850_register_raw_size (reg_table[i].regno);
+ pi->frameoffset -= offset;
+
+ /* Calculate the offsets of the registers relative to the value
+ the SP will have after the registers have been pushed and the
+ imm5 value has been subtracted from it. */
+ if (pifsr)
+ {
+ for (i = 0; reg_table[i].mask != 0; i++)
+ {
+ if (list12 & reg_table[i].mask)
+ {
+ int reg = reg_table[i].regno;
+ offset -= v850_register_raw_size (reg);
+ pifsr->reg = reg;
+ pifsr->offset = offset;
+ pifsr->cur_frameoffset = pi->frameoffset;
+#ifdef DEBUG
+ printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
+#endif
+ pifsr++;
+ }
+ }
+ }
+#ifdef DEBUG
+ printf_filtered ("\tfound ctret after regsave func");
+#endif
+
+ /* Set result parameters. */
+ *current_pc_ptr = current_pc;
+ *pifsr_ptr = pifsr;
+}
+
+
+/* Helper function for v850_scan_prologue to handle pushm/pushl instructions.
+ FIXME: the SR bit of the register list is not supported; must check
+ that the compiler does not ever generate this bit. */
+
+static void
+handle_pushm (int insn, int insn2, struct prologue_info *pi,
+ struct pifsr **pifsr_ptr)
+{
+ struct pifsr *pifsr = *pifsr_ptr;
+ long list12 = ((insn & 0x0f) << 16) + (insn2 & 0xfff0);
+ long offset = 0;
+ static struct reg_list pushml_reg_table[] =
+ {
+ {0x80000, E_PS_REGNUM}, /* PSW */
+ {0x40000, 1}, /* r1 */
+ {0x20000, 2}, /* r2 */
+ {0x10000, 3}, /* r3 */
+ {0x00800, 4}, /* r4 */
+ {0x00400, 5}, /* r5 */
+ {0x00200, 6}, /* r6 */
+ {0x00100, 7}, /* r7 */
+ {0x08000, 8}, /* r8 */
+ {0x04000, 9}, /* r9 */
+ {0x02000, 10}, /* r10 */
+ {0x01000, 11}, /* r11 */
+ {0x00080, 12}, /* r12 */
+ {0x00040, 13}, /* r13 */
+ {0x00020, 14}, /* r14 */
+ {0x00010, 15}, /* r15 */
+ {0, 0} /* end of table */
+ };
+ static struct reg_list pushmh_reg_table[] =
+ {
+ {0x80000, 16}, /* r16 */
+ {0x40000, 17}, /* r17 */
+ {0x20000, 18}, /* r18 */
+ {0x10000, 19}, /* r19 */
+ {0x00800, 20}, /* r20 */
+ {0x00400, 21}, /* r21 */
+ {0x00200, 22}, /* r22 */
+ {0x00100, 23}, /* r23 */
+ {0x08000, 24}, /* r24 */
+ {0x04000, 25}, /* r25 */
+ {0x02000, 26}, /* r26 */
+ {0x01000, 27}, /* r27 */
+ {0x00080, 28}, /* r28 */
+ {0x00040, 29}, /* r29 */
+ {0x00010, 30}, /* r30 */
+ {0x00020, 31}, /* r31 */
+ {0, 0} /* end of table */
+ };
+ struct reg_list *reg_table;
+ int i;
+
+ /* Is this a pushml or a pushmh? */
+ if ((insn2 & 7) == 1)
+ reg_table = pushml_reg_table;
+ else
+ reg_table = pushmh_reg_table;
+
+ /* Calculate the total size of the saved registers, and add it
+ it to the immediate value used to adjust SP. */
+ for (i = 0; reg_table[i].mask != 0; i++)
+ if (list12 & reg_table[i].mask)
+ offset += v850_register_raw_size (reg_table[i].regno);
+ pi->frameoffset -= offset;
+
+ /* Calculate the offsets of the registers relative to the value
+ the SP will have after the registers have been pushed and the
+ imm5 value is subtracted from it. */
+ if (pifsr)
+ {
+ for (i = 0; reg_table[i].mask != 0; i++)
+ {
+ if (list12 & reg_table[i].mask)
+ {
+ int reg = reg_table[i].regno;
+ offset -= v850_register_raw_size (reg);
+ pifsr->reg = reg;
+ pifsr->offset = offset;
+ pifsr->cur_frameoffset = pi->frameoffset;
+#ifdef DEBUG
+ printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
+#endif
+ pifsr++;
+ }
+ }
+ }
+#ifdef DEBUG
+ printf_filtered ("\tfound ctret after regsave func");
+#endif
+
+ /* Set result parameters. */
+ *pifsr_ptr = pifsr;
+}
+
+
+
+
+/* Function: scan_prologue
+ Scan the prologue of the function that contains PC, and record what
+ we find in PI. Returns the pc after the prologue. Note that the
+ addresses saved in frame->saved_regs are just frame relative (negative
+ offsets from the frame pointer). This is because we don't know the
+ actual value of the frame pointer yet. In some circumstances, the
+ frame pointer can't be determined till after we have scanned the
+ prologue. */
+
+static CORE_ADDR
+v850_scan_prologue (CORE_ADDR pc, struct prologue_info *pi)
+{
+ CORE_ADDR func_addr, prologue_end, current_pc;
+ struct pifsr *pifsr, *pifsr_tmp;
+ int fp_used;
+ int ep_used;
+ int reg;
+ CORE_ADDR save_pc, save_end;
+ int regsave_func_p;
+ int r12_tmp;
+
+ /* First, figure out the bounds of the prologue so that we can limit the
+ search to something reasonable. */
+
+ if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
+ {
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (func_addr, 0);
+
+ if (func_addr == entry_point_address ())
+ pi->start_function = 1;
+ else
+ pi->start_function = 0;
+
+#if 0
+ if (sal.line == 0)
+ prologue_end = pc;
+ else
+ prologue_end = sal.end;
+#else
+ prologue_end = pc;
+#endif
+ }
+ else
+ { /* We're in the boondocks */
+ func_addr = pc - 100;
+ prologue_end = pc;
+ }
+
+ prologue_end = min (prologue_end, pc);
+
+ /* Now, search the prologue looking for instructions that setup fp, save
+ rp, adjust sp and such. We also record the frame offset of any saved
+ registers. */
+
+ pi->frameoffset = 0;
+ pi->framereg = E_SP_REGNUM;
+ fp_used = 0;
+ ep_used = 0;
+ pifsr = pi->pifsrs;
+ regsave_func_p = 0;
+ save_pc = 0;
+ save_end = 0;
+ r12_tmp = 0;
+
+#ifdef DEBUG
+ printf_filtered ("Current_pc = 0x%.8lx, prologue_end = 0x%.8lx\n",
+ (long) func_addr, (long) prologue_end);
+#endif
+
+ for (current_pc = func_addr; current_pc < prologue_end;)
+ {
+ int insn;
+ int insn2 = -1; /* dummy value */
+
+#ifdef DEBUG
+ printf_filtered ("0x%.8lx ", (long) current_pc);
+ TARGET_PRINT_INSN (current_pc, &tm_print_insn_info);
+#endif
+
+ insn = read_memory_unsigned_integer (current_pc, 2);
+ current_pc += 2;
+ if ((insn & 0x0780) >= 0x0600) /* Four byte instruction? */
+ {
+ insn2 = read_memory_unsigned_integer (current_pc, 2);
+ current_pc += 2;
+ }
+
+ if ((insn & 0xffc0) == ((10 << 11) | 0x0780) && !regsave_func_p)
+ { /* jarl <func>,10 */
+ long low_disp = insn2 & ~(long) 1;
+ long disp = (((((insn & 0x3f) << 16) + low_disp)
+ & ~(long) 1) ^ 0x00200000) - 0x00200000;
+
+ save_pc = current_pc;
+ save_end = prologue_end;
+ regsave_func_p = 1;
+ current_pc += disp - 4;
+ prologue_end = (current_pc
+ + (2 * 3) /* moves to/from ep */
+ + 4 /* addi <const>,sp,sp */
+ + 2 /* jmp [r10] */
+ + (2 * 12) /* sst.w to save r2, r20-r29, r31 */
+ + 20); /* slop area */
+
+#ifdef DEBUG
+ printf_filtered ("\tfound jarl <func>,r10, disp = %ld, low_disp = %ld, new pc = 0x%.8lx\n",
+ disp, low_disp, (long) current_pc + 2);
+#endif
+ continue;
+ }
+ else if ((insn & 0xffc0) == 0x0200 && !regsave_func_p)
+ { /* callt <imm6> */
+ long ctbp = read_register (E_CTBP_REGNUM);
+ long adr = ctbp + ((insn & 0x3f) << 1);
+
+ save_pc = current_pc;
+ save_end = prologue_end;
+ regsave_func_p = 1;
+ current_pc = ctbp + (read_memory_unsigned_integer (adr, 2) & 0xffff);
+ prologue_end = (current_pc
+ + (2 * 3) /* prepare list2,imm5,sp/imm */
+ + 4 /* ctret */
+ + 20); /* slop area */
+
+#ifdef DEBUG
+ printf_filtered ("\tfound callt, ctbp = 0x%.8lx, adr = %.8lx, new pc = 0x%.8lx\n",
+ ctbp, adr, (long) current_pc);
+#endif
+ continue;
+ }
+ else if ((insn & 0xffc0) == 0x0780) /* prepare list2,imm5 */
+ {
+ handle_prepare (insn, insn2, &current_pc, pi, &pifsr);
+ continue;
+ }
+ else if (insn == 0x07e0 && regsave_func_p && insn2 == 0x0144)
+ { /* ctret after processing register save function */
+ current_pc = save_pc;
+ prologue_end = save_end;
+ regsave_func_p = 0;
+#ifdef DEBUG
+ printf_filtered ("\tfound ctret after regsave func");
+#endif
+ continue;
+ }
+ else if ((insn & 0xfff0) == 0x07e0 && (insn2 & 5) == 1)
+ { /* pushml, pushmh */
+ handle_pushm (insn, insn2, pi, &pifsr);
+ continue;
+ }
+ else if ((insn & 0xffe0) == 0x0060 && regsave_func_p)
+ { /* jmp after processing register save function */
+ current_pc = save_pc;
+ prologue_end = save_end;
+ regsave_func_p = 0;
+#ifdef DEBUG
+ printf_filtered ("\tfound jmp after regsave func");
+#endif
+ continue;
+ }
+ else if ((insn & 0x07c0) == 0x0780 /* jarl or jr */
+ || (insn & 0xffe0) == 0x0060 /* jmp */
+ || (insn & 0x0780) == 0x0580) /* branch */
+ {
+#ifdef DEBUG
+ printf_filtered ("\n");
+#endif
+ break; /* Ran into end of prologue */
+ }
+
+ else if ((insn & 0xffe0) == ((E_SP_REGNUM << 11) | 0x0240)) /* add <imm>,sp */
+ pi->frameoffset += ((insn & 0x1f) ^ 0x10) - 0x10;
+ else if (insn == ((E_SP_REGNUM << 11) | 0x0600 | E_SP_REGNUM)) /* addi <imm>,sp,sp */
+ pi->frameoffset += insn2;
+ else if (insn == ((E_FP_RAW_REGNUM << 11) | 0x0000 | E_SP_REGNUM)) /* mov sp,fp */
+ {
+ fp_used = 1;
+ pi->framereg = E_FP_RAW_REGNUM;
+ }
+
+ else if (insn == ((E_R12_REGNUM << 11) | 0x0640 | E_R0_REGNUM)) /* movhi hi(const),r0,r12 */
+ r12_tmp = insn2 << 16;
+ else if (insn == ((E_R12_REGNUM << 11) | 0x0620 | E_R12_REGNUM)) /* movea lo(const),r12,r12 */
+ r12_tmp += insn2;
+ else if (insn == ((E_SP_REGNUM << 11) | 0x01c0 | E_R12_REGNUM) && r12_tmp) /* add r12,sp */
+ pi->frameoffset = r12_tmp;
+ else if (insn == ((E_EP_REGNUM << 11) | 0x0000 | E_SP_REGNUM)) /* mov sp,ep */
+ ep_used = 1;
+ else if (insn == ((E_EP_REGNUM << 11) | 0x0000 | E_R1_REGNUM)) /* mov r1,ep */
+ ep_used = 0;
+ else if (((insn & 0x07ff) == (0x0760 | E_SP_REGNUM) /* st.w <reg>,<offset>[sp] */
+ || (fp_used
+ && (insn & 0x07ff) == (0x0760 | E_FP_RAW_REGNUM))) /* st.w <reg>,<offset>[fp] */
+ && pifsr
+ && (((reg = (insn >> 11) & 0x1f) >= E_SAVE1_START_REGNUM && reg <= E_SAVE1_END_REGNUM)
+ || (reg >= E_SAVE2_START_REGNUM && reg <= E_SAVE2_END_REGNUM)
+ || (reg >= E_SAVE3_START_REGNUM && reg <= E_SAVE3_END_REGNUM)))
+ {
+ pifsr->reg = reg;
+ pifsr->offset = insn2 & ~1;
+ pifsr->cur_frameoffset = pi->frameoffset;
+#ifdef DEBUG
+ printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
+#endif
+ pifsr++;
+ }
+
+ else if (ep_used /* sst.w <reg>,<offset>[ep] */
+ && ((insn & 0x0781) == 0x0501)
+ && pifsr
+ && (((reg = (insn >> 11) & 0x1f) >= E_SAVE1_START_REGNUM && reg <= E_SAVE1_END_REGNUM)
+ || (reg >= E_SAVE2_START_REGNUM && reg <= E_SAVE2_END_REGNUM)
+ || (reg >= E_SAVE3_START_REGNUM && reg <= E_SAVE3_END_REGNUM)))
+ {
+ pifsr->reg = reg;
+ pifsr->offset = (insn & 0x007e) << 1;
+ pifsr->cur_frameoffset = pi->frameoffset;
+#ifdef DEBUG
+ printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
+#endif
+ pifsr++;
+ }
+
+#ifdef DEBUG
+ printf_filtered ("\n");
+#endif
+ }
+
+ if (pifsr)
+ pifsr->framereg = 0; /* Tie off last entry */
+
+ /* Fix up any offsets to the final offset. If a frame pointer was created, use it
+ instead of the stack pointer. */
+ for (pifsr_tmp = pi->pifsrs; pifsr_tmp && pifsr_tmp != pifsr; pifsr_tmp++)
+ {
+ pifsr_tmp->offset -= pi->frameoffset - pifsr_tmp->cur_frameoffset;
+ pifsr_tmp->framereg = pi->framereg;
+
+#ifdef DEBUG
+ printf_filtered ("Saved register r%d, offset = %d, framereg = r%d\n",
+ pifsr_tmp->reg, pifsr_tmp->offset, pifsr_tmp->framereg);
+#endif
+ }
+
+#ifdef DEBUG
+ printf_filtered ("Framereg = r%d, frameoffset = %d\n", pi->framereg, pi->frameoffset);
+#endif
+
+ return current_pc;
+}
+
+/* Function: find_callers_reg
+ Find REGNUM on the stack. Otherwise, it's in an active register.
+ One thing we might want to do here is to check REGNUM against the
+ clobber mask, and somehow flag it as invalid if it isn't saved on
+ the stack somewhere. This would provide a graceful failure mode
+ when trying to get the value of caller-saves registers for an inner
+ frame. */
+
+CORE_ADDR
+v850_find_callers_reg (struct frame_info *fi, int regnum)
+{
+ for (; fi; fi = fi->next)
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, regnum);
+ else if (fi->saved_regs[regnum] != 0)
+ return read_memory_unsigned_integer (fi->saved_regs[regnum],
+ v850_register_raw_size (regnum));
+
+ return read_register (regnum);
+}
+
+/* Function: frame_chain
+ Figure out the frame prior to FI. Unfortunately, this involves
+ scanning the prologue of the caller, which will also be done
+ shortly by v850_init_extra_frame_info. For the dummy frame, we
+ just return the stack pointer that was in use at the time the
+ function call was made. */
+
+CORE_ADDR
+v850_frame_chain (struct frame_info *fi)
+{
+ struct prologue_info pi;
+ CORE_ADDR callers_pc, fp;
+
+ /* First, find out who called us */
+ callers_pc = FRAME_SAVED_PC (fi);
+ /* If caller is a call-dummy, then our FP bears no relation to his FP! */
+ fp = v850_find_callers_reg (fi, E_FP_RAW_REGNUM);
+ if (PC_IN_CALL_DUMMY (callers_pc, fp, fp))
+ return fp; /* caller is call-dummy: return oldest value of FP */
+
+ /* Caller is NOT a call-dummy, so everything else should just work.
+ Even if THIS frame is a call-dummy! */
+ pi.pifsrs = NULL;
+
+ v850_scan_prologue (callers_pc, &pi);
+
+ if (pi.start_function)
+ return 0; /* Don't chain beyond the start function */
+
+ if (pi.framereg == E_FP_RAW_REGNUM)
+ return v850_find_callers_reg (fi, pi.framereg);
+
+ return fi->frame - pi.frameoffset;
+}
+
+/* Function: skip_prologue
+ Return the address of the first code past the prologue of the function. */
+
+CORE_ADDR
+v850_skip_prologue (CORE_ADDR pc)
+{
+ CORE_ADDR func_addr, func_end;
+
+ /* See what the symbol table says */
+
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (func_addr, 0);
+
+ if (sal.line != 0 && sal.end < func_end)
+ return sal.end;
+ else
+ /* Either there's no line info, or the line after the prologue is after
+ the end of the function. In this case, there probably isn't a
+ prologue. */
+ return pc;
+ }
+
+/* We can't find the start of this function, so there's nothing we can do. */
+ return pc;
+}
+
+/* Function: pop_frame
+ This routine gets called when either the user uses the `return'
+ command, or the call dummy breakpoint gets hit. */
+
+void
+v850_pop_frame (void)
+{
+ struct frame_info *frame = get_current_frame ();
+ int regnum;
+
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ generic_pop_dummy_frame ();
+ else
+ {
+ write_register (E_PC_REGNUM, FRAME_SAVED_PC (frame));
+
+ for (regnum = 0; regnum < E_NUM_REGS; regnum++)
+ if (frame->saved_regs[regnum] != 0)
+ write_register (regnum,
+ read_memory_unsigned_integer (frame->saved_regs[regnum],
+ v850_register_raw_size (regnum)));
+
+ write_register (E_SP_REGNUM, FRAME_FP (frame));
+ }
+
+ flush_cached_frames ();
+}
+
+/* Function: push_arguments
+ Setup arguments and RP for a call to the target. First four args
+ go in R6->R9, subsequent args go into sp + 16 -> sp + ... Structs
+ are passed by reference. 64 bit quantities (doubles and long
+ longs) may be split between the regs and the stack. When calling a
+ function that returns a struct, a pointer to the struct is passed
+ in as a secret first argument (always in R6).
+
+ Stack space for the args has NOT been allocated: that job is up to us.
+ */
+
+CORE_ADDR
+v850_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int argreg;
+ int argnum;
+ int len = 0;
+ int stack_offset;
+
+ /* First, just for safety, make sure stack is aligned */
+ sp &= ~3;
+
+ /* Now make space on the stack for the args. */
+ for (argnum = 0; argnum < nargs; argnum++)
+ len += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3);
+ sp -= len; /* possibly over-allocating, but it works... */
+ /* (you might think we could allocate 16 bytes */
+ /* less, but the ABI seems to use it all! ) */
+ argreg = E_ARG0_REGNUM;
+
+ /* the struct_return pointer occupies the first parameter-passing reg */
+ if (struct_return)
+ write_register (argreg++, struct_addr);
+
+ stack_offset = 16;
+ /* The offset onto the stack at which we will start copying parameters
+ (after the registers are used up) begins at 16 rather than at zero.
+ I don't really know why, that's just the way it seems to work. */
+
+ /* Now load as many as possible of the first arguments into
+ registers, and push the rest onto the stack. There are 16 bytes
+ in four registers available. Loop thru args from first to last. */
+ for (argnum = 0; argnum < nargs; argnum++)
+ {
+ int len;
+ char *val;
+ char valbuf[v850_register_raw_size (E_ARG0_REGNUM)];
+
+ if (TYPE_CODE (VALUE_TYPE (*args)) == TYPE_CODE_STRUCT
+ && TYPE_LENGTH (VALUE_TYPE (*args)) > 8)
+ {
+ store_address (valbuf, 4, VALUE_ADDRESS (*args));
+ len = 4;
+ val = valbuf;
+ }
+ else
+ {
+ len = TYPE_LENGTH (VALUE_TYPE (*args));
+ val = (char *) VALUE_CONTENTS (*args);
+ }
+
+ while (len > 0)
+ if (argreg <= E_ARGLAST_REGNUM)
+ {
+ CORE_ADDR regval;
+
+ regval = extract_address (val, v850_register_raw_size (argreg));
+ write_register (argreg, regval);
+
+ len -= v850_register_raw_size (argreg);
+ val += v850_register_raw_size (argreg);
+ argreg++;
+ }
+ else
+ {
+ write_memory (sp + stack_offset, val, 4);
+
+ len -= 4;
+ val += 4;
+ stack_offset += 4;
+ }
+ args++;
+ }
+ return sp;
+}
+
+/* Function: push_return_address (pc)
+ Set up the return address for the inferior function call.
+ Needed for targets where we don't actually execute a JSR/BSR instruction */
+
+CORE_ADDR
+v850_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ write_register (E_RP_REGNUM, CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+/* Function: frame_saved_pc
+ Find the caller of this frame. We do this by seeing if E_RP_REGNUM
+ is saved in the stack anywhere, otherwise we get it from the
+ registers. If the inner frame is a dummy frame, return its PC
+ instead of RP, because that's where "caller" of the dummy-frame
+ will be found. */
+
+CORE_ADDR
+v850_frame_saved_pc (struct frame_info *fi)
+{
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, E_PC_REGNUM);
+ else
+ return v850_find_callers_reg (fi, E_RP_REGNUM);
+}
+
+
+/* Function: fix_call_dummy
+ Pokes the callee function's address into the CALL_DUMMY assembly stub.
+ Assumes that the CALL_DUMMY looks like this:
+ jarl <offset24>, r31
+ trap
+ */
+
+void
+v850_fix_call_dummy (char *dummy, CORE_ADDR sp, CORE_ADDR fun, int nargs,
+ struct value **args, struct type *type, int gcc_p)
+{
+ long offset24;
+
+ offset24 = (long) fun - (long) entry_point_address ();
+ offset24 &= 0x3fffff;
+ offset24 |= 0xff800000; /* jarl <offset24>, r31 */
+
+ store_unsigned_integer ((unsigned int *) &dummy[2], 2, offset24 & 0xffff);
+ store_unsigned_integer ((unsigned int *) &dummy[0], 2, offset24 >> 16);
+}
+
+static CORE_ADDR
+v850_saved_pc_after_call (struct frame_info *ignore)
+{
+ return read_register (E_RP_REGNUM);
+}
+
+static void
+v850_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ memcpy (valbuf, regbuf + v850_register_byte (E_V0_REGNUM),
+ TYPE_LENGTH (type));
+}
+
+const static unsigned char *
+v850_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+ static unsigned char breakpoint[] = { 0x85, 0x05 };
+ *lenptr = sizeof (breakpoint);
+ return breakpoint;
+}
+
+static CORE_ADDR
+v850_extract_struct_value_address (char *regbuf)
+{
+ return extract_address (regbuf + v850_register_byte (E_V0_REGNUM),
+ v850_register_raw_size (E_V0_REGNUM));
+}
+
+static void
+v850_store_return_value (struct type *type, char *valbuf)
+{
+ write_register_bytes(v850_register_byte (E_V0_REGNUM), valbuf,
+ TYPE_LENGTH (type));
+}
+
+static void
+v850_frame_init_saved_regs (struct frame_info *fi)
+{
+ struct prologue_info pi;
+ struct pifsr pifsrs[E_NUM_REGS + 1], *pifsr;
+ CORE_ADDR func_addr, func_end;
+
+ if (!fi->saved_regs)
+ {
+ frame_saved_regs_zalloc (fi);
+
+ /* The call dummy doesn't save any registers on the stack, so we
+ can return now. */
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return;
+
+ /* Find the beginning of this function, so we can analyze its
+ prologue. */
+ if (find_pc_partial_function (fi->pc, NULL, &func_addr, &func_end))
+ {
+ pi.pifsrs = pifsrs;
+
+ v850_scan_prologue (fi->pc, &pi);
+
+ if (!fi->next && pi.framereg == E_SP_REGNUM)
+ fi->frame = read_register (pi.framereg) - pi.frameoffset;
+
+ for (pifsr = pifsrs; pifsr->framereg; pifsr++)
+ {
+ fi->saved_regs[pifsr->reg] = pifsr->offset + fi->frame;
+
+ if (pifsr->framereg == E_SP_REGNUM)
+ fi->saved_regs[pifsr->reg] += pi.frameoffset;
+ }
+ }
+ /* Else we're out of luck (can't debug completely stripped code).
+ FIXME. */
+ }
+}
+
+/* Function: init_extra_frame_info
+ Setup the frame's frame pointer, pc, and frame addresses for saved
+ registers. Most of the work is done in scan_prologue().
+
+ Note that when we are called for the last frame (currently active frame),
+ that fi->pc and fi->frame will already be setup. However, fi->frame will
+ be valid only if this routine uses FP. For previous frames, fi-frame will
+ always be correct (since that is derived from v850_frame_chain ()).
+
+ We can be called with the PC in the call dummy under two circumstances.
+ First, during normal backtracing, second, while figuring out the frame
+ pointer just prior to calling the target function (see run_stack_dummy). */
+
+static void
+v850_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ struct prologue_info pi;
+
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ v850_frame_init_saved_regs (fi);
+}
+
+static void
+v850_store_struct_return (CORE_ADDR a, CORE_ADDR b)
+{
+}
+
+static CORE_ADDR
+v850_target_read_fp (void)
+{
+ return read_register (E_FP_RAW_REGNUM);
+}
+
+static struct gdbarch *
+v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ static LONGEST call_dummy_words[1] = { 0 };
+ struct gdbarch_tdep *tdep = NULL;
+ struct gdbarch *gdbarch;
+ int i;
+
+ /* find a candidate among the list of pre-declared architectures. */
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+ if (arches != NULL)
+ return (arches->gdbarch);
+
+#if 0
+ tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
+#endif
+
+ /* Change the register names based on the current machine type. */
+ if (info.bfd_arch_info->arch != bfd_arch_v850)
+ return 0;
+
+ gdbarch = gdbarch_alloc (&info, 0);
+
+ for (i = 0; v850_processor_type_table[i].regnames != NULL; i++)
+ {
+ if (v850_processor_type_table[i].mach == info.bfd_arch_info->mach)
+ {
+ v850_register_names = v850_processor_type_table[i].regnames;
+ tm_print_insn_info.mach = info.bfd_arch_info->mach;
+ break;
+ }
+ }
+
+ /*
+ * Basic register fields and methods.
+ */
+ set_gdbarch_num_regs (gdbarch, E_NUM_REGS);
+ set_gdbarch_num_pseudo_regs (gdbarch, 0);
+ set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
+ set_gdbarch_fp_regnum (gdbarch, E_FP_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
+ set_gdbarch_register_name (gdbarch, v850_register_name);
+ set_gdbarch_register_size (gdbarch, v850_reg_size);
+ set_gdbarch_register_bytes (gdbarch, E_ALL_REGS_SIZE);
+ set_gdbarch_register_byte (gdbarch, v850_register_byte);
+ set_gdbarch_register_raw_size (gdbarch, v850_register_raw_size);
+ set_gdbarch_max_register_raw_size (gdbarch, v850_reg_size);
+ set_gdbarch_register_virtual_size (gdbarch, v850_register_raw_size);
+ set_gdbarch_max_register_virtual_size (gdbarch, v850_reg_size);
+ set_gdbarch_register_virtual_type (gdbarch, v850_reg_virtual_type);
+
+ set_gdbarch_read_fp (gdbarch, v850_target_read_fp);
+
+ /*
+ * Frame Info
+ */
+ set_gdbarch_init_extra_frame_info (gdbarch, v850_init_extra_frame_info);
+ set_gdbarch_frame_init_saved_regs (gdbarch, v850_frame_init_saved_regs);
+ set_gdbarch_frame_chain (gdbarch, v850_frame_chain);
+ set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+ set_gdbarch_saved_pc_after_call (gdbarch, v850_saved_pc_after_call);
+ set_gdbarch_frame_saved_pc (gdbarch, v850_frame_saved_pc);
+ set_gdbarch_skip_prologue (gdbarch, v850_skip_prologue);
+ set_gdbarch_frame_chain_valid (gdbarch, generic_file_frame_chain_valid);
+ set_gdbarch_frame_args_address (gdbarch, default_frame_address);
+ set_gdbarch_frame_locals_address (gdbarch, default_frame_address);
+
+ /*
+ * Miscelany
+ */
+ /* Stack grows up. */
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+ /* PC stops zero byte after a trap instruction
+ (which means: exactly on trap instruction). */
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+ /* This value is almost never non-zero... */
+ set_gdbarch_function_start_offset (gdbarch, 0);
+ /* This value is almost never non-zero... */
+ set_gdbarch_frame_args_skip (gdbarch, 0);
+ /* OK to default this value to 'unknown'. */
+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+ /* W/o prototype, coerce float args to double. */
+ set_gdbarch_coerce_float_to_double (gdbarch, standard_coerce_float_to_double);
+
+ /*
+ * Call Dummies
+ *
+ * These values and methods are used when gdb calls a target function. */
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+ set_gdbarch_push_return_address (gdbarch, v850_push_return_address);
+ set_gdbarch_extract_return_value (gdbarch, v850_extract_return_value);
+ set_gdbarch_push_arguments (gdbarch, v850_push_arguments);
+ set_gdbarch_pop_frame (gdbarch, v850_pop_frame);
+ set_gdbarch_store_struct_return (gdbarch, v850_store_struct_return);
+ set_gdbarch_store_return_value (gdbarch, v850_store_return_value);
+ set_gdbarch_extract_struct_value_address (gdbarch, v850_extract_struct_value_address);
+ set_gdbarch_use_struct_convention (gdbarch, v850_use_struct_convention);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_words (gdbarch, call_dummy_nil);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ /* set_gdbarch_call_dummy_stack_adjust */
+ set_gdbarch_fix_call_dummy (gdbarch, v850_fix_call_dummy);
+ set_gdbarch_breakpoint_from_pc (gdbarch, v850_breakpoint_from_pc);
+
+ set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+
+ set_gdbarch_extra_stack_alignment_needed (gdbarch, 0);
+
+ return gdbarch;
+}
+
+void
+_initialize_v850_tdep (void)
+{
+ tm_print_insn = print_insn_v850;
+ register_gdbarch_init (bfd_arch_v850, v850_gdbarch_init);
+}
diff --git a/gdb/v850ice.c b/gdb/v850ice.c
new file mode 100644
index 00000000000..1aec483bb90
--- /dev/null
+++ b/gdb/v850ice.c
@@ -0,0 +1,956 @@
+/* ICE interface for the NEC V850 for GDB, the GNU debugger.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001
+ 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 "defs.h"
+#include "gdb_string.h"
+#include "frame.h"
+#include "symtab.h"
+#include "inferior.h"
+#include "breakpoint.h"
+#include "symfile.h"
+#include "target.h"
+#include "objfiles.h"
+#include "gdbcore.h"
+#include "value.h"
+#include "command.h"
+#include "regcache.h"
+
+#include <tcl.h>
+#include <windows.h>
+#include <winuser.h> /* for WM_USER */
+
+extern unsigned long int strtoul (const char *nptr, char **endptr,
+ int base);
+
+/* Local data definitions */
+struct MessageIO
+ {
+ int size; /* length of input or output in bytes */
+ char *buf; /* buffer having the input/output information */
+ };
+
+/* Prototypes for functions located in other files */
+extern void break_command (char *, int);
+
+extern void stepi_command (char *, int);
+
+extern void nexti_command (char *, int);
+
+extern void continue_command (char *, int);
+
+extern int (*ui_loop_hook) (int);
+
+/* Prototypes for local functions */
+static int init_hidden_window (void);
+
+static LRESULT CALLBACK v850ice_wndproc (HWND, UINT, WPARAM, LPARAM);
+
+static void v850ice_files_info (struct target_ops *ignore);
+
+static int v850ice_xfer_memory (CORE_ADDR memaddr, char *myaddr,
+ int len, int should_write,
+ struct target_ops *target);
+
+static void v850ice_prepare_to_store (void);
+
+static void v850ice_fetch_registers (int regno);
+
+static void v850ice_resume (ptid_t ptid, int step,
+ enum target_signal siggnal);
+
+static void v850ice_open (char *name, int from_tty);
+
+static void v850ice_close (int quitting);
+
+static void v850ice_stop (void);
+
+static void v850ice_store_registers (int regno);
+
+static void v850ice_mourn (void);
+
+static ptid_t v850ice_wait (ptid_t ptid,
+ struct target_waitstatus *status);
+
+static void v850ice_kill (void);
+
+static void v850ice_detach (char *args, int from_tty);
+
+static int v850ice_insert_breakpoint (CORE_ADDR, char *);
+
+static int v850ice_remove_breakpoint (CORE_ADDR, char *);
+
+static void v850ice_command (char *, int);
+
+static int ice_disassemble (unsigned long, int, char *);
+
+static int ice_lookup_addr (unsigned long *, char *, char *);
+
+static int ice_lookup_symbol (unsigned long, char *);
+
+static void ice_SimulateDisassemble (char *, int);
+
+static void ice_SimulateAddrLookup (char *, int);
+
+static void ice_Simulate_SymLookup (char *, int);
+
+static void ice_fputs (const char *, struct ui_file *);
+
+static int ice_file (char *);
+
+static int ice_cont (char *);
+
+static int ice_stepi (char *);
+
+static int ice_nexti (char *);
+
+static void togdb_force_update (void);
+
+static void view_source (CORE_ADDR);
+
+static void do_gdb (char *, char *, void (*func) (char *, int), int);
+
+
+/* Globals */
+static HWND hidden_hwnd; /* HWND for messages */
+
+long (__stdcall * ExeAppReq) (char *, long, char *, struct MessageIO *);
+
+long (__stdcall * RegisterClient) (HWND);
+
+long (__stdcall * UnregisterClient) (void);
+
+extern Tcl_Interp *gdbtk_interp;
+
+/* Globals local to this file only */
+static int ice_open = 0; /* Is ICE open? */
+
+static char *v850_CB_Result; /* special char array for saving 'callback' results */
+
+static int SimulateCallback; /* simulate a callback event */
+
+#define MAX_BLOCK_SIZE 64*1024 /* Cannot transfer memory in blocks bigger
+ than this */
+/* MDI/ICE Message IDs */
+#define GSINGLESTEP 0x200 /* single-step target */
+#define GRESUME 0x201 /* resume target */
+#define GREADREG 0x202 /* read a register */
+#define GWRITEREG 0x203 /* write a register */
+#define GWRITEBLOCK 0x204 /* write a block of memory */
+#define GREADBLOCK 0x205 /* read a block of memory */
+#define GSETBREAK 0x206 /* set a breakpoint */
+#define GREMOVEBREAK 0x207 /* remove a breakpoint */
+#define GHALT 0x208 /* ??? */
+#define GCHECKSTATUS 0x209 /* check status of ICE */
+#define GMDIREPLY 0x210 /* Reply for previous query - NOT USED */
+#define GDOWNLOAD 0x211 /* something for MDI */
+#define GCOMMAND 0x212 /* execute command in ice */
+#define GLOADFILENAME 0x213 /* retrieve load filename */
+#define GWRITEMEM 0x214 /* write word, half-word, or byte */
+
+/* GCHECKSTATUS return codes: */
+#define ICE_Idle 0x00
+#define ICE_Breakpoint 0x01 /* hit a breakpoint */
+#define ICE_Stepped 0x02 /* have stepped */
+#define ICE_Exception 0x03 /* have exception */
+#define ICE_Halted 0x04 /* hit a user halt */
+#define ICE_Exited 0x05 /* called exit */
+#define ICE_Terminated 0x06 /* user terminated */
+#define ICE_Running 0x07
+#define ICE_Unknown 0x99
+
+/* Windows messages */
+#define WM_STATE_CHANGE WM_USER+101
+#define WM_SYM_TO_ADDR WM_USER+102
+#define WM_ADDR_TO_SYM WM_USER+103
+#define WM_DISASSEMBLY WM_USER+104
+#define WM_SOURCE WM_USER+105
+
+/* STATE_CHANGE codes */
+#define STATE_CHANGE_REGS 1 /* Register(s) changed */
+#define STATE_CHANGE_LOAD 2 /* HW reset */
+#define STATE_CHANGE_RESET 3 /* Load new file */
+#define STATE_CHANGE_CONT 4 /* Run target */
+#define STATE_CHANGE_STOP 5 /* Stop target */
+#define STATE_CHANGE_STEPI 6 /* Stepi target */
+#define STATE_CHANGE_NEXTI 7 /* Nexti target */
+
+static struct target_ops v850ice_ops; /* Forward decl */
+
+/* This function creates a hidden window */
+static int
+init_hidden_window (void)
+{
+ WNDCLASS class;
+
+ if (hidden_hwnd != NULL)
+ return 1;
+
+ class.style = 0;
+ class.cbClsExtra = 0;
+ class.cbWndExtra = 0;
+ class.hInstance = GetModuleHandle (0);
+ class.hbrBackground = NULL;
+ class.lpszMenuName = NULL;
+ class.lpszClassName = "gdb_v850ice";
+ class.lpfnWndProc = v850ice_wndproc;
+ class.hIcon = NULL;
+ class.hCursor = NULL;
+
+ if (!RegisterClass (&class))
+ return 0;
+
+ hidden_hwnd = CreateWindow ("gdb_v850ice", "gdb_v850ice", WS_TILED,
+ 0, 0, 0, 0, NULL, NULL, class.hInstance,
+ NULL);
+ if (hidden_hwnd == NULL)
+ {
+ char buf[200];
+ DWORD err;
+
+ err = GetLastError ();
+ FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
+ 0, buf, 200, NULL);
+ printf_unfiltered ("Could not create window: %s", buf);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ This function is installed as the message handler for the hidden window
+ which QBox will use to communicate with gdb. It recognize and acts
+ on the following messages:
+
+ WM_SYM_TO_ADDR \
+ WM_ADDR_TO_SYM | Not implemented at NEC's request
+ WM_DISASSEMBLY /
+ WM_STATE_CHANGE - tells us that a state change has occured in the ICE
+ */
+static LRESULT CALLBACK
+v850ice_wndproc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT result = FALSE;
+
+ switch (message)
+ {
+ case WM_SYM_TO_ADDR:
+ MessageBox (0, "Symbol resolution\nNot implemented", "GDB", MB_OK);
+ break;
+ case WM_ADDR_TO_SYM:
+ MessageBox (0, "Address resolution\nNot implemented", "GDB", MB_OK);
+ break;
+ case WM_SOURCE:
+ view_source ((CORE_ADDR) lParam);
+ break;
+ case WM_STATE_CHANGE:
+ switch (wParam)
+ {
+ case STATE_CHANGE_LOAD:
+ {
+ struct MessageIO iob;
+ char buf[128];
+
+ iob.buf = buf;
+ iob.size = 128;
+
+ /* Load in a new file... Need filename */
+ ExeAppReq ("GDB", GLOADFILENAME, NULL, &iob);
+ if (!catch_errors ((catch_errors_ftype *) ice_file, iob.buf, "", RETURN_MASK_ALL))
+ printf_unfiltered ("load errored\n");
+ }
+ break;
+ case STATE_CHANGE_RESET:
+ registers_changed ();
+ flush_cached_frames ();
+ togdb_force_update ();
+ result = TRUE;
+ break;
+ case STATE_CHANGE_REGS:
+ registers_changed ();
+ togdb_force_update ();
+ result = TRUE;
+ break;
+ case STATE_CHANGE_CONT:
+ if (!catch_errors ((catch_errors_ftype *) ice_cont, NULL, "", RETURN_MASK_ALL))
+ printf_unfiltered ("continue errored\n");
+ result = TRUE;
+ break;
+ case STATE_CHANGE_STEPI:
+ if (!catch_errors ((catch_errors_ftype *) ice_stepi, (PTR) (int) lParam, "",
+ RETURN_MASK_ALL))
+ printf_unfiltered ("stepi errored\n");
+ result = TRUE;
+ break;
+ case STATE_CHANGE_NEXTI:
+ if (!catch_errors ((catch_errors_ftype *) ice_nexti, (PTR) (int) lParam, "",
+ RETURN_MASK_ALL))
+ printf_unfiltered ("nexti errored\n");
+ result = TRUE;
+ break;
+ }
+ }
+
+ if (result == FALSE)
+ return DefWindowProc (hwnd, message, wParam, lParam);
+
+ return FALSE;
+}
+
+/* Code for opening a connection to the ICE. */
+
+static void
+v850ice_open (char *name, int from_tty)
+{
+ HINSTANCE handle;
+
+ if (name)
+ error ("Too many arguments.");
+
+ target_preopen (from_tty);
+
+ unpush_target (&v850ice_ops);
+
+ if (from_tty)
+ puts_filtered ("V850ice debugging\n");
+
+ push_target (&v850ice_ops); /* Switch to using v850ice target now */
+
+ target_terminal_init ();
+
+ /* Initialize everything necessary to facilitate communication
+ between QBox, gdb, and the DLLs which control the ICE */
+ if (ExeAppReq == NULL)
+ {
+ handle = LoadLibrary ("necmsg.dll");
+ if (handle == NULL)
+ error ("Cannot load necmsg.dll");
+
+ ExeAppReq = (long (*) (char *, long, char *, struct MessageIO *))
+ GetProcAddress (handle, "ExeAppReq");
+ RegisterClient = (long (*) (HWND))
+ GetProcAddress (handle, "RegisterClient");
+ UnregisterClient = (long (*) (void))
+ GetProcAddress (handle, "UnregisterClient");
+
+ if (ExeAppReq == NULL || RegisterClient == NULL || UnregisterClient == NULL)
+ error ("Could not find requisite functions in necmsg.dll.");
+
+ if (!init_hidden_window ())
+ error ("could not initialize message handling");
+ }
+
+ /* Tell the DLL we are here */
+ RegisterClient (hidden_hwnd);
+
+ ice_open = 1;
+
+ /* Without this, some commands which require an active target (such as kill)
+ won't work. This variable serves (at least) double duty as both the pid
+ of the target process (if it has such), and as a flag indicating that a
+ target is active. These functions should be split out into seperate
+ variables, especially since GDB will someday have a notion of debugging
+ several processes. */
+ inferior_ptid = pid_to_ptid (42000);
+
+ start_remote ();
+ return;
+}
+
+/* Clean up connection to a remote debugger. */
+
+/* ARGSUSED */
+static void
+v850ice_close (int quitting)
+{
+ if (ice_open)
+ {
+ UnregisterClient ();
+ ice_open = 0;
+ inferior_ptid = null_ptid;
+ }
+}
+
+/* Stop the process on the ice. */
+static void
+v850ice_stop (void)
+{
+ /* This is silly, but it works... */
+ v850ice_command ("stop", 0);
+}
+
+static void
+v850ice_detach (char *args, int from_tty)
+{
+ if (args)
+ error ("Argument given to \"detach\" when remotely debugging.");
+
+ pop_target ();
+ if (from_tty)
+ puts_filtered ("Ending v850ice debugging.\n");
+}
+
+/* Tell the remote machine to resume. */
+
+static void
+v850ice_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ long retval;
+ char buf[256];
+ struct MessageIO iob;
+
+ iob.size = 0;
+ iob.buf = buf;
+
+ if (step)
+ retval = ExeAppReq ("GDB", GSINGLESTEP, "step", &iob);
+ else
+ retval = ExeAppReq ("GDB", GRESUME, "run", &iob);
+
+ if (retval)
+ error ("ExeAppReq (step = %d) returned %d", step, retval);
+}
+
+/* Wait until the remote machine stops, then return,
+ storing status in STATUS just as `wait' would.
+ Returns "pid" (though it's not clear what, if anything, that
+ means in the case of this target). */
+
+static ptid_t
+v850ice_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ long v850_status;
+ char buf[256];
+ struct MessageIO iob;
+ int done = 0;
+ int count = 0;
+
+ iob.size = 0;
+ iob.buf = buf;
+
+ do
+ {
+ if (count++ % 100000)
+ {
+ ui_loop_hook (0);
+ count = 0;
+ }
+
+ v850_status = ExeAppReq ("GDB", GCHECKSTATUS, NULL, &iob);
+
+ switch (v850_status)
+ {
+ case ICE_Idle:
+ case ICE_Breakpoint:
+ case ICE_Stepped:
+ case ICE_Halted:
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ done = 1;
+ break;
+ case ICE_Exception:
+ status->kind = TARGET_WAITKIND_SIGNALLED;
+ status->value.sig = TARGET_SIGNAL_SEGV;
+ done = 1;
+ break;
+ case ICE_Exited:
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = 0;
+ done = 1;
+ break;
+ case ICE_Terminated:
+ status->kind = TARGET_WAITKIND_SIGNALLED;
+ status->value.sig = TARGET_SIGNAL_KILL;
+ done = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ while (!done);
+
+ return inferior_ptid;
+}
+
+static int
+convert_register (int regno, char *buf)
+{
+ if (regno <= 31)
+ sprintf (buf, "r%d", regno);
+ else if (REGISTER_NAME (regno)[0] == 's'
+ && REGISTER_NAME (regno)[1] == 'r')
+ return 0;
+ else
+ sprintf (buf, "%s", REGISTER_NAME (regno));
+
+ return 1;
+}
+
+/* Read the remote registers into the block REGS. */
+/* Note that the ICE returns register contents as ascii hex strings. We have
+ to convert that to an unsigned long, and then call store_unsigned_integer to
+ convert it to target byte-order if necessary. */
+
+static void
+v850ice_fetch_registers (int regno)
+{
+ long retval;
+ char cmd[100];
+ char val[100];
+ struct MessageIO iob;
+ unsigned long regval;
+ char *p;
+
+ if (regno == -1)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ v850ice_fetch_registers (regno);
+ return;
+ }
+
+ strcpy (cmd, "reg ");
+ if (!convert_register (regno, &cmd[4]))
+ return;
+
+ iob.size = sizeof val;
+ iob.buf = val;
+ retval = ExeAppReq ("GDB", GREADREG, cmd, &iob);
+ if (retval)
+ error ("1: ExeAppReq returned %d: cmd = %s", retval, cmd);
+
+ regval = strtoul (val, NULL, 16);
+ if (regval == 0 && p == val)
+ error ("v850ice_fetch_registers (%d): bad value from ICE: %s.",
+ regno, val);
+
+ store_unsigned_integer (val, REGISTER_RAW_SIZE (regno), regval);
+ supply_register (regno, val);
+}
+
+/* Store register REGNO, or all registers if REGNO == -1, from the contents
+ of REGISTERS. */
+
+static void
+v850ice_store_registers (int regno)
+{
+ long retval;
+ char cmd[100];
+ unsigned long regval;
+ char buf[256];
+ struct MessageIO iob;
+ iob.size = 0;
+ iob.buf = buf;
+
+ if (regno == -1)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ v850ice_store_registers (regno);
+ return;
+ }
+
+ regval = extract_unsigned_integer (&registers[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE (regno));
+ strcpy (cmd, "reg ");
+ if (!convert_register (regno, &cmd[4]))
+ return;
+ sprintf (cmd + strlen (cmd), "=0x%x", regval);
+
+ retval = ExeAppReq ("GDB", GWRITEREG, cmd, &iob);
+ if (retval)
+ error ("2: ExeAppReq returned %d: cmd = %s", retval, cmd);
+}
+
+/* Prepare to store registers. Nothing to do here, since the ICE can write one
+ register at a time. */
+
+static void
+v850ice_prepare_to_store (void)
+{
+}
+
+/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
+ to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
+ nonzero. TARGET is unused. Returns length of data written or read;
+ 0 for error.
+
+ We can only read/write MAX_BLOCK_SIZE bytes at a time, though, or the DLL
+ dies. */
+/* ARGSUSED */
+static int
+v850ice_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int should_write, struct target_ops *target)
+{
+ long retval;
+ char cmd[100];
+ struct MessageIO iob;
+ int sent;
+
+ if (should_write)
+ {
+ if (len == 4 || len == 2 || len == 1)
+ {
+ long value = 0;
+ char buf[256];
+ char c;
+
+ iob.size = 0;
+ iob.buf = buf;
+
+ sent = 0;
+ switch (len)
+ {
+ case 4:
+ c = 'w';
+ value |= (long) ((myaddr[3] << 24) & 0xff000000);
+ value |= (long) ((myaddr[2] << 16) & 0x00ff0000);
+ value |= (long) ((myaddr[1] << 8) & 0x0000ff00);
+ value |= (long) (myaddr[0] & 0x000000ff);
+ break;
+ case 2:
+ c = 'h';
+ value |= (long) ((myaddr[1] << 8) & 0xff00);
+ value |= (long) (myaddr[0] & 0x00ff);
+ break;
+ case 1:
+ c = 'b';
+ value |= (long) (myaddr[0] & 0xff);
+ break;
+ }
+
+ sprintf (cmd, "memory %c c 0x%x=0x%x", c, (int) memaddr, value);
+ retval = ExeAppReq ("GDB", GWRITEMEM, cmd, &iob);
+ if (retval == 0)
+ sent = len;
+ }
+ else
+ {
+ sent = 0;
+ do
+ {
+ iob.size = len > MAX_BLOCK_SIZE ? MAX_BLOCK_SIZE : len;
+ iob.buf = myaddr;
+ sprintf (cmd, "memory b c 0x%x=0x00 l=%d", (int) memaddr, iob.size);
+ retval = ExeAppReq ("GDB", GWRITEBLOCK, cmd, &iob);
+ if (retval != 0)
+ break;
+ len -= iob.size;
+ memaddr += iob.size;
+ myaddr += iob.size;
+ sent += iob.size;
+ }
+ while (len > 0);
+ }
+ }
+ else
+ {
+ unsigned char *tmp;
+ unsigned char *t;
+ int i;
+
+ tmp = alloca (len + 100);
+ t = tmp;
+ memset (tmp + len, 0xff, 100);
+
+ sent = 0;
+ do
+ {
+ iob.size = len > MAX_BLOCK_SIZE ? MAX_BLOCK_SIZE : len;
+ iob.buf = tmp;
+ sprintf (cmd, "memory b 0x%x l=%d", (int) memaddr, iob.size);
+ retval = ExeAppReq ("GDB", GREADBLOCK, cmd, &iob);
+ if (retval != 0)
+ break;
+ len -= iob.size;
+ memaddr += iob.size;
+ sent += iob.size;
+ tmp += iob.size;
+ }
+ while (len > 0);
+
+ if (retval == 0)
+ {
+ for (i = 0; i < 100; i++)
+ {
+ if (t[sent + i] != 0xff)
+ {
+ warning ("GREADBLOCK trashed bytes after transfer area.");
+ break;
+ }
+ }
+ memcpy (myaddr, t, sent);
+ }
+ }
+
+ if (retval != 0)
+ error ("3: ExeAppReq returned %d: cmd = %s", retval, cmd);
+
+ return sent;
+}
+
+static void
+v850ice_files_info (struct target_ops *ignore)
+{
+ puts_filtered ("Debugging a target via the NEC V850 ICE.\n");
+}
+
+static int
+v850ice_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ long retval;
+ char cmd[100];
+ char buf[256];
+ struct MessageIO iob;
+
+ iob.size = 0;
+ iob.buf = buf;
+ sprintf (cmd, "%d, ", addr);
+
+ retval = ExeAppReq ("GDB", GSETBREAK, cmd, &iob);
+ if (retval)
+ error ("ExeAppReq (GSETBREAK) returned %d: cmd = %s", retval, cmd);
+
+ return 0;
+}
+
+static int
+v850ice_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+{
+ long retval;
+ char cmd[100];
+ char buf[256];
+ struct MessageIO iob;
+
+ iob.size = 0;
+ iob.buf = buf;
+
+ sprintf (cmd, "%d, ", addr);
+
+ retval = ExeAppReq ("GDB", GREMOVEBREAK, cmd, &iob);
+ if (retval)
+ error ("ExeAppReq (GREMOVEBREAK) returned %d: cmd = %s", retval, cmd);
+
+ return 0;
+}
+
+static void
+v850ice_kill (void)
+{
+ target_mourn_inferior ();
+ inferior_ptid = null_ptid;
+}
+
+static void
+v850ice_mourn (void)
+{
+}
+
+static void
+v850ice_load (char *filename, int from_tty)
+{
+ struct MessageIO iob;
+ char buf[256];
+
+ iob.size = 0;
+ iob.buf = buf;
+ generic_load (filename, from_tty);
+ ExeAppReq ("GDB", GDOWNLOAD, filename, &iob);
+}
+
+static int
+ice_file (char *arg)
+{
+ char *s;
+
+ target_detach (NULL, 0);
+ pop_target ();
+
+ printf_unfiltered ("\n");
+
+ s = arg;
+ while (*s != '\0')
+ {
+ if (*s == '\\')
+ *s = '/';
+ s++;
+ }
+
+ /* Safegaurd against confusing the breakpoint routines... */
+ delete_command (NULL, 0);
+
+ /* Must supress from_tty, otherwise we could start asking if the
+ user really wants to load a new symbol table, etc... */
+ printf_unfiltered ("Reading symbols from %s...", arg);
+ exec_open (arg, 0);
+ symbol_file_add_main (arg, 0);
+ printf_unfiltered ("done\n");
+
+ /* exec_open will kill our target, so reinstall the ICE as
+ the target. */
+ v850ice_open (NULL, 0);
+
+ togdb_force_update ();
+ return 1;
+}
+
+static int
+ice_cont (char *c)
+{
+ printf_filtered ("continue (ice)\n");
+ ReplyMessage ((LRESULT) 1);
+
+ if (gdbtk_interp == NULL)
+ {
+ continue_command (NULL, 1);
+ }
+ else
+ Tcl_Eval (gdbtk_interp, "gdb_immediate continue");
+
+ return 1;
+}
+
+static void
+do_gdb (char *cmd, char *str, void (*func) (char *, int), int count)
+{
+ ReplyMessage ((LRESULT) 1);
+
+ while (count--)
+ {
+ printf_unfiltered (str);
+
+ if (gdbtk_interp == NULL)
+ {
+ func (NULL, 0);
+ }
+ else
+ Tcl_Eval (gdbtk_interp, cmd);
+ }
+}
+
+
+static int
+ice_stepi (char *c)
+{
+ int count = (int) c;
+
+ do_gdb ("gdb_immediate stepi", "stepi (ice)\n", stepi_command, count);
+ return 1;
+}
+
+static int
+ice_nexti (char *c)
+{
+ int count = (int) c;
+
+ do_gdb ("gdb_immediate nexti", "nexti (ice)\n", nexti_command, count);
+ return 1;
+}
+
+static void
+v850ice_command (char *arg, int from_tty)
+{
+ struct MessageIO iob;
+ char buf[256];
+
+ iob.buf = buf;
+ iob.size = 0;
+ ExeAppReq ("GDB", GCOMMAND, arg, &iob);
+}
+
+static void
+togdb_force_update (void)
+{
+ if (gdbtk_interp != NULL)
+ Tcl_Eval (gdbtk_interp, "gdbtk_update");
+}
+
+static void
+view_source (CORE_ADDR addr)
+{
+ char c[256];
+
+ if (gdbtk_interp != NULL)
+ {
+ sprintf (c, "catch {set src [lindex [ManagedWin::find SrcWin] 0]\n$src location BROWSE [gdb_loc *0x%x]}", addr);
+ Tcl_Eval (gdbtk_interp, c);
+ }
+}
+
+/* Define the target subroutine names */
+
+static void
+init_850ice_ops (void)
+{
+ v850ice_ops.to_shortname = "ice";
+ v850ice_ops.to_longname = "NEC V850 ICE interface";
+ v850ice_ops.to_doc = "Debug a system controlled by a NEC 850 ICE.";
+ v850ice_ops.to_open = v850ice_open;
+ v850ice_ops.to_close = v850ice_close;
+ v850ice_ops.to_attach = NULL;
+ v850ice_ops.to_post_attach = NULL;
+ v850ice_ops.to_require_attach = NULL;
+ v850ice_ops.to_detach = v850ice_detach;
+ v850ice_ops.to_require_detach = NULL;
+ v850ice_ops.to_resume = v850ice_resume;
+ v850ice_ops.to_wait = v850ice_wait;
+ v850ice_ops.to_post_wait = NULL;
+ v850ice_ops.to_fetch_registers = v850ice_fetch_registers;
+ v850ice_ops.to_store_registers = v850ice_store_registers;
+ v850ice_ops.to_prepare_to_store = v850ice_prepare_to_store;
+ v850ice_ops.to_xfer_memory = v850ice_xfer_memory;
+ v850ice_ops.to_files_info = v850ice_files_info;
+ v850ice_ops.to_insert_breakpoint = v850ice_insert_breakpoint;
+ v850ice_ops.to_remove_breakpoint = v850ice_remove_breakpoint;
+ v850ice_ops.to_terminal_init = NULL;
+ v850ice_ops.to_terminal_inferior = NULL;
+ v850ice_ops.to_terminal_ours_for_output = NULL;
+ v850ice_ops.to_terminal_ours = NULL;
+ v850ice_ops.to_terminal_info = NULL;
+ v850ice_ops.to_kill = v850ice_kill;
+ v850ice_ops.to_load = v850ice_load;
+ v850ice_ops.to_lookup_symbol = NULL;
+ v850ice_ops.to_create_inferior = NULL;
+ v850ice_ops.to_mourn_inferior = v850ice_mourn;
+ v850ice_ops.to_can_run = 0;
+ v850ice_ops.to_notice_signals = 0;
+ v850ice_ops.to_thread_alive = NULL;
+ v850ice_ops.to_stop = v850ice_stop;
+ v850ice_ops.to_pid_to_exec_file = NULL;
+ v850ice_ops.to_stratum = process_stratum;
+ v850ice_ops.DONT_USE = NULL;
+ v850ice_ops.to_has_all_memory = 1;
+ v850ice_ops.to_has_memory = 1;
+ v850ice_ops.to_has_stack = 1;
+ v850ice_ops.to_has_registers = 1;
+ v850ice_ops.to_has_execution = 1;
+ v850ice_ops.to_sections = NULL;
+ v850ice_ops.to_sections_end = NULL;
+ v850ice_ops.to_magic = OPS_MAGIC;
+}
+
+void
+_initialize_v850ice (void)
+{
+ init_850ice_ops ();
+ add_target (&v850ice_ops);
+
+ add_com ("ice", class_obscure, v850ice_command,
+ "Send command to ICE");
+}
diff --git a/gdb/valarith.c b/gdb/valarith.c
new file mode 100644
index 00000000000..cc067cb4b51
--- /dev/null
+++ b/gdb/valarith.c
@@ -0,0 +1,1428 @@
+/* Perform arithmetic and other operations on values, for GDB.
+ Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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 "defs.h"
+#include "value.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "target.h"
+#include "language.h"
+#include "gdb_string.h"
+#include "doublest.h"
+#include <math.h>
+
+/* Define whether or not the C operator '/' truncates towards zero for
+ differently signed operands (truncation direction is undefined in C). */
+
+#ifndef TRUNCATION_TOWARDS_ZERO
+#define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2)
+#endif
+
+static struct value *value_subscripted_rvalue (struct value *, struct value *, int);
+
+void _initialize_valarith (void);
+
+
+/* Given a pointer, return the size of its target.
+ If the pointer type is void *, then return 1.
+ If the target type is incomplete, then error out.
+ This isn't a general purpose function, but just a
+ helper for value_sub & value_add.
+*/
+
+static LONGEST
+find_size_for_pointer_math (struct type *ptr_type)
+{
+ LONGEST sz = -1;
+ struct type *ptr_target;
+
+ ptr_target = check_typedef (TYPE_TARGET_TYPE (ptr_type));
+
+ sz = TYPE_LENGTH (ptr_target);
+ if (sz == 0)
+ {
+ if (TYPE_CODE (ptr_type) == TYPE_CODE_VOID)
+ sz = 1;
+ else
+ {
+ char *name;
+
+ name = TYPE_NAME (ptr_target);
+ if (name == NULL)
+ name = TYPE_TAG_NAME (ptr_target);
+ if (name == NULL)
+ error ("Cannot perform pointer math on incomplete types, "
+ "try casting to a known type, or void *.");
+ else
+ error ("Cannot perform pointer math on incomplete type \"%s\", "
+ "try casting to a known type, or void *.", name);
+ }
+ }
+ return sz;
+}
+
+struct value *
+value_add (struct value *arg1, struct value *arg2)
+{
+ struct value *valint;
+ struct value *valptr;
+ LONGEST sz;
+ struct type *type1, *type2, *valptrtype;
+
+ COERCE_NUMBER (arg1);
+ COERCE_NUMBER (arg2);
+ type1 = check_typedef (VALUE_TYPE (arg1));
+ type2 = check_typedef (VALUE_TYPE (arg2));
+
+ if ((TYPE_CODE (type1) == TYPE_CODE_PTR
+ || TYPE_CODE (type2) == TYPE_CODE_PTR)
+ &&
+ (TYPE_CODE (type1) == TYPE_CODE_INT
+ || TYPE_CODE (type2) == TYPE_CODE_INT))
+ /* Exactly one argument is a pointer, and one is an integer. */
+ {
+ struct value *retval;
+
+ if (TYPE_CODE (type1) == TYPE_CODE_PTR)
+ {
+ valptr = arg1;
+ valint = arg2;
+ valptrtype = type1;
+ }
+ else
+ {
+ valptr = arg2;
+ valint = arg1;
+ valptrtype = type2;
+ }
+
+ sz = find_size_for_pointer_math (valptrtype);
+
+ retval = value_from_pointer (valptrtype,
+ value_as_address (valptr)
+ + (sz * value_as_long (valint)));
+ VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (valptr);
+ return retval;
+ }
+
+ return value_binop (arg1, arg2, BINOP_ADD);
+}
+
+struct value *
+value_sub (struct value *arg1, struct value *arg2)
+{
+ struct type *type1, *type2;
+ COERCE_NUMBER (arg1);
+ COERCE_NUMBER (arg2);
+ type1 = check_typedef (VALUE_TYPE (arg1));
+ type2 = check_typedef (VALUE_TYPE (arg2));
+
+ if (TYPE_CODE (type1) == TYPE_CODE_PTR)
+ {
+ if (TYPE_CODE (type2) == TYPE_CODE_INT)
+ {
+ /* pointer - integer. */
+ LONGEST sz = find_size_for_pointer_math (type1);
+
+ return value_from_pointer (type1,
+ (value_as_address (arg1)
+ - (sz * value_as_long (arg2))));
+ }
+ else if (TYPE_CODE (type2) == TYPE_CODE_PTR
+ && TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1)))
+ == TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type2))))
+ {
+ /* pointer to <type x> - pointer to <type x>. */
+ LONGEST sz = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1)));
+ return value_from_longest
+ (builtin_type_long, /* FIXME -- should be ptrdiff_t */
+ (value_as_long (arg1) - value_as_long (arg2)) / sz);
+ }
+ else
+ {
+ error ("\
+First argument of `-' is a pointer and second argument is neither\n\
+an integer nor a pointer of the same type.");
+ }
+ }
+
+ return value_binop (arg1, arg2, BINOP_SUB);
+}
+
+/* Return the value of ARRAY[IDX].
+ See comments in value_coerce_array() for rationale for reason for
+ doing lower bounds adjustment here rather than there.
+ FIXME: Perhaps we should validate that the index is valid and if
+ verbosity is set, warn about invalid indices (but still use them). */
+
+struct value *
+value_subscript (struct value *array, struct value *idx)
+{
+ struct value *bound;
+ int c_style = current_language->c_style_arrays;
+ struct type *tarray;
+
+ COERCE_REF (array);
+ tarray = check_typedef (VALUE_TYPE (array));
+ COERCE_VARYING_ARRAY (array, tarray);
+
+ if (TYPE_CODE (tarray) == TYPE_CODE_ARRAY
+ || TYPE_CODE (tarray) == TYPE_CODE_STRING)
+ {
+ struct type *range_type = TYPE_INDEX_TYPE (tarray);
+ LONGEST lowerbound, upperbound;
+ get_discrete_bounds (range_type, &lowerbound, &upperbound);
+
+ if (VALUE_LVAL (array) != lval_memory)
+ return value_subscripted_rvalue (array, idx, lowerbound);
+
+ if (c_style == 0)
+ {
+ LONGEST index = value_as_long (idx);
+ if (index >= lowerbound && index <= upperbound)
+ return value_subscripted_rvalue (array, idx, lowerbound);
+ warning ("array or string index out of range");
+ /* fall doing C stuff */
+ c_style = 1;
+ }
+
+ if (lowerbound != 0)
+ {
+ bound = value_from_longest (builtin_type_int, (LONGEST) lowerbound);
+ idx = value_sub (idx, bound);
+ }
+
+ array = value_coerce_array (array);
+ }
+
+ if (TYPE_CODE (tarray) == TYPE_CODE_BITSTRING)
+ {
+ struct type *range_type = TYPE_INDEX_TYPE (tarray);
+ LONGEST index = value_as_long (idx);
+ struct value *v;
+ int offset, byte, bit_index;
+ LONGEST lowerbound, upperbound;
+ get_discrete_bounds (range_type, &lowerbound, &upperbound);
+ if (index < lowerbound || index > upperbound)
+ error ("bitstring index out of range");
+ index -= lowerbound;
+ offset = index / TARGET_CHAR_BIT;
+ byte = *((char *) VALUE_CONTENTS (array) + offset);
+ bit_index = index % TARGET_CHAR_BIT;
+ byte >>= (BITS_BIG_ENDIAN ? TARGET_CHAR_BIT - 1 - bit_index : bit_index);
+ v = value_from_longest (LA_BOOL_TYPE, byte & 1);
+ VALUE_BITPOS (v) = bit_index;
+ VALUE_BITSIZE (v) = 1;
+ VALUE_LVAL (v) = VALUE_LVAL (array);
+ if (VALUE_LVAL (array) == lval_internalvar)
+ VALUE_LVAL (v) = lval_internalvar_component;
+ VALUE_ADDRESS (v) = VALUE_ADDRESS (array);
+ VALUE_OFFSET (v) = offset + VALUE_OFFSET (array);
+ return v;
+ }
+
+ if (c_style)
+ return value_ind (value_add (array, idx));
+ else
+ error ("not an array or string");
+}
+
+/* Return the value of EXPR[IDX], expr an aggregate rvalue
+ (eg, a vector register). This routine used to promote floats
+ to doubles, but no longer does. */
+
+static struct value *
+value_subscripted_rvalue (struct value *array, struct value *idx, int lowerbound)
+{
+ struct type *array_type = check_typedef (VALUE_TYPE (array));
+ struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type));
+ unsigned int elt_size = TYPE_LENGTH (elt_type);
+ LONGEST index = value_as_long (idx);
+ unsigned int elt_offs = elt_size * longest_to_int (index - lowerbound);
+ struct value *v;
+
+ if (index < lowerbound || elt_offs >= TYPE_LENGTH (array_type))
+ error ("no such vector element");
+
+ v = allocate_value (elt_type);
+ if (VALUE_LAZY (array))
+ VALUE_LAZY (v) = 1;
+ else
+ memcpy (VALUE_CONTENTS (v), VALUE_CONTENTS (array) + elt_offs, elt_size);
+
+ if (VALUE_LVAL (array) == lval_internalvar)
+ VALUE_LVAL (v) = lval_internalvar_component;
+ else
+ VALUE_LVAL (v) = VALUE_LVAL (array);
+ VALUE_ADDRESS (v) = VALUE_ADDRESS (array);
+ VALUE_OFFSET (v) = VALUE_OFFSET (array) + elt_offs;
+ return v;
+}
+
+/* Check to see if either argument is a structure. This is called so
+ we know whether to go ahead with the normal binop or look for a
+ user defined function instead.
+
+ For now, we do not overload the `=' operator. */
+
+int
+binop_user_defined_p (enum exp_opcode op, struct value *arg1, struct value *arg2)
+{
+ struct type *type1, *type2;
+ if (op == BINOP_ASSIGN || op == BINOP_CONCAT)
+ return 0;
+ type1 = check_typedef (VALUE_TYPE (arg1));
+ type2 = check_typedef (VALUE_TYPE (arg2));
+ return (TYPE_CODE (type1) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type2) == TYPE_CODE_STRUCT
+ || (TYPE_CODE (type1) == TYPE_CODE_REF
+ && TYPE_CODE (TYPE_TARGET_TYPE (type1)) == TYPE_CODE_STRUCT)
+ || (TYPE_CODE (type2) == TYPE_CODE_REF
+ && TYPE_CODE (TYPE_TARGET_TYPE (type2)) == TYPE_CODE_STRUCT));
+}
+
+/* Check to see if argument is a structure. This is called so
+ we know whether to go ahead with the normal unop or look for a
+ user defined function instead.
+
+ For now, we do not overload the `&' operator. */
+
+int
+unop_user_defined_p (enum exp_opcode op, struct value *arg1)
+{
+ struct type *type1;
+ if (op == UNOP_ADDR)
+ return 0;
+ type1 = check_typedef (VALUE_TYPE (arg1));
+ for (;;)
+ {
+ if (TYPE_CODE (type1) == TYPE_CODE_STRUCT)
+ return 1;
+ else if (TYPE_CODE (type1) == TYPE_CODE_REF)
+ type1 = TYPE_TARGET_TYPE (type1);
+ else
+ return 0;
+ }
+}
+
+/* We know either arg1 or arg2 is a structure, so try to find the right
+ user defined function. Create an argument vector that calls
+ arg1.operator @ (arg1,arg2) and return that value (where '@' is any
+ binary operator which is legal for GNU C++).
+
+ OP is the operatore, and if it is BINOP_ASSIGN_MODIFY, then OTHEROP
+ is the opcode saying how to modify it. Otherwise, OTHEROP is
+ unused. */
+
+struct value *
+value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
+ enum exp_opcode otherop, enum noside noside)
+{
+ struct value **argvec;
+ char *ptr;
+ char tstr[13];
+ int static_memfuncp;
+
+ COERCE_REF (arg1);
+ COERCE_REF (arg2);
+ COERCE_ENUM (arg1);
+ COERCE_ENUM (arg2);
+
+ /* now we know that what we have to do is construct our
+ arg vector and find the right function to call it with. */
+
+ if (TYPE_CODE (check_typedef (VALUE_TYPE (arg1))) != TYPE_CODE_STRUCT)
+ error ("Can't do that binary op on that type"); /* FIXME be explicit */
+
+ argvec = (struct value **) alloca (sizeof (struct value *) * 4);
+ argvec[1] = value_addr (arg1);
+ argvec[2] = arg2;
+ argvec[3] = 0;
+
+ /* make the right function name up */
+ strcpy (tstr, "operator__");
+ ptr = tstr + 8;
+ switch (op)
+ {
+ case BINOP_ADD:
+ strcpy (ptr, "+");
+ break;
+ case BINOP_SUB:
+ strcpy (ptr, "-");
+ break;
+ case BINOP_MUL:
+ strcpy (ptr, "*");
+ break;
+ case BINOP_DIV:
+ strcpy (ptr, "/");
+ break;
+ case BINOP_REM:
+ strcpy (ptr, "%");
+ break;
+ case BINOP_LSH:
+ strcpy (ptr, "<<");
+ break;
+ case BINOP_RSH:
+ strcpy (ptr, ">>");
+ break;
+ case BINOP_BITWISE_AND:
+ strcpy (ptr, "&");
+ break;
+ case BINOP_BITWISE_IOR:
+ strcpy (ptr, "|");
+ break;
+ case BINOP_BITWISE_XOR:
+ strcpy (ptr, "^");
+ break;
+ case BINOP_LOGICAL_AND:
+ strcpy (ptr, "&&");
+ break;
+ case BINOP_LOGICAL_OR:
+ strcpy (ptr, "||");
+ break;
+ case BINOP_MIN:
+ strcpy (ptr, "<?");
+ break;
+ case BINOP_MAX:
+ strcpy (ptr, ">?");
+ break;
+ case BINOP_ASSIGN:
+ strcpy (ptr, "=");
+ break;
+ case BINOP_ASSIGN_MODIFY:
+ switch (otherop)
+ {
+ case BINOP_ADD:
+ strcpy (ptr, "+=");
+ break;
+ case BINOP_SUB:
+ strcpy (ptr, "-=");
+ break;
+ case BINOP_MUL:
+ strcpy (ptr, "*=");
+ break;
+ case BINOP_DIV:
+ strcpy (ptr, "/=");
+ break;
+ case BINOP_REM:
+ strcpy (ptr, "%=");
+ break;
+ case BINOP_BITWISE_AND:
+ strcpy (ptr, "&=");
+ break;
+ case BINOP_BITWISE_IOR:
+ strcpy (ptr, "|=");
+ break;
+ case BINOP_BITWISE_XOR:
+ strcpy (ptr, "^=");
+ break;
+ case BINOP_MOD: /* invalid */
+ default:
+ error ("Invalid binary operation specified.");
+ }
+ break;
+ case BINOP_SUBSCRIPT:
+ strcpy (ptr, "[]");
+ break;
+ case BINOP_EQUAL:
+ strcpy (ptr, "==");
+ break;
+ case BINOP_NOTEQUAL:
+ strcpy (ptr, "!=");
+ break;
+ case BINOP_LESS:
+ strcpy (ptr, "<");
+ break;
+ case BINOP_GTR:
+ strcpy (ptr, ">");
+ break;
+ case BINOP_GEQ:
+ strcpy (ptr, ">=");
+ break;
+ case BINOP_LEQ:
+ strcpy (ptr, "<=");
+ break;
+ case BINOP_MOD: /* invalid */
+ default:
+ error ("Invalid binary operation specified.");
+ }
+
+ argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure");
+
+ if (argvec[0])
+ {
+ if (static_memfuncp)
+ {
+ argvec[1] = argvec[0];
+ argvec++;
+ }
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ struct type *return_type;
+ return_type
+ = TYPE_TARGET_TYPE (check_typedef (VALUE_TYPE (argvec[0])));
+ return value_zero (return_type, VALUE_LVAL (arg1));
+ }
+ return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1);
+ }
+ error ("member function %s not found", tstr);
+#ifdef lint
+ return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1);
+#endif
+}
+
+/* We know that arg1 is a structure, so try to find a unary user
+ defined operator that matches the operator in question.
+ Create an argument vector that calls arg1.operator @ (arg1)
+ and return that value (where '@' is (almost) any unary operator which
+ is legal for GNU C++). */
+
+struct value *
+value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
+{
+ struct value **argvec;
+ char *ptr, *mangle_ptr;
+ char tstr[13], mangle_tstr[13];
+ int static_memfuncp, nargs;
+
+ COERCE_REF (arg1);
+ COERCE_ENUM (arg1);
+
+ /* now we know that what we have to do is construct our
+ arg vector and find the right function to call it with. */
+
+ if (TYPE_CODE (check_typedef (VALUE_TYPE (arg1))) != TYPE_CODE_STRUCT)
+ error ("Can't do that unary op on that type"); /* FIXME be explicit */
+
+ argvec = (struct value **) alloca (sizeof (struct value *) * 4);
+ argvec[1] = value_addr (arg1);
+ argvec[2] = 0;
+
+ nargs = 1;
+
+ /* make the right function name up */
+ strcpy (tstr, "operator__");
+ ptr = tstr + 8;
+ strcpy (mangle_tstr, "__");
+ mangle_ptr = mangle_tstr + 2;
+ switch (op)
+ {
+ case UNOP_PREINCREMENT:
+ strcpy (ptr, "++");
+ break;
+ case UNOP_PREDECREMENT:
+ strcpy (ptr, "--");
+ break;
+ case UNOP_POSTINCREMENT:
+ strcpy (ptr, "++");
+ argvec[2] = value_from_longest (builtin_type_int, 0);
+ argvec[3] = 0;
+ nargs ++;
+ break;
+ case UNOP_POSTDECREMENT:
+ strcpy (ptr, "--");
+ argvec[2] = value_from_longest (builtin_type_int, 0);
+ argvec[3] = 0;
+ nargs ++;
+ break;
+ case UNOP_LOGICAL_NOT:
+ strcpy (ptr, "!");
+ break;
+ case UNOP_COMPLEMENT:
+ strcpy (ptr, "~");
+ break;
+ case UNOP_NEG:
+ strcpy (ptr, "-");
+ break;
+ case UNOP_IND:
+ strcpy (ptr, "*");
+ break;
+ default:
+ error ("Invalid unary operation specified.");
+ }
+
+ argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure");
+
+ if (argvec[0])
+ {
+ if (static_memfuncp)
+ {
+ argvec[1] = argvec[0];
+ nargs --;
+ argvec++;
+ }
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ struct type *return_type;
+ return_type
+ = TYPE_TARGET_TYPE (check_typedef (VALUE_TYPE (argvec[0])));
+ return value_zero (return_type, VALUE_LVAL (arg1));
+ }
+ return call_function_by_hand (argvec[0], nargs, argvec + 1);
+ }
+ error ("member function %s not found", tstr);
+ return 0; /* For lint -- never reached */
+}
+
+
+/* Concatenate two values with the following conditions:
+
+ (1) Both values must be either bitstring values or character string
+ values and the resulting value consists of the concatenation of
+ ARG1 followed by ARG2.
+
+ or
+
+ One value must be an integer value and the other value must be
+ either a bitstring value or character string value, which is
+ to be repeated by the number of times specified by the integer
+ value.
+
+
+ (2) Boolean values are also allowed and are treated as bit string
+ values of length 1.
+
+ (3) Character values are also allowed and are treated as character
+ string values of length 1.
+ */
+
+struct value *
+value_concat (struct value *arg1, struct value *arg2)
+{
+ struct value *inval1;
+ struct value *inval2;
+ struct value *outval = NULL;
+ int inval1len, inval2len;
+ int count, idx;
+ char *ptr;
+ char inchar;
+ struct type *type1 = check_typedef (VALUE_TYPE (arg1));
+ struct type *type2 = check_typedef (VALUE_TYPE (arg2));
+
+ COERCE_VARYING_ARRAY (arg1, type1);
+ COERCE_VARYING_ARRAY (arg2, type2);
+
+ /* First figure out if we are dealing with two values to be concatenated
+ or a repeat count and a value to be repeated. INVAL1 is set to the
+ first of two concatenated values, or the repeat count. INVAL2 is set
+ to the second of the two concatenated values or the value to be
+ repeated. */
+
+ if (TYPE_CODE (type2) == TYPE_CODE_INT)
+ {
+ struct type *tmp = type1;
+ type1 = tmp;
+ tmp = type2;
+ inval1 = arg2;
+ inval2 = arg1;
+ }
+ else
+ {
+ inval1 = arg1;
+ inval2 = arg2;
+ }
+
+ /* Now process the input values. */
+
+ if (TYPE_CODE (type1) == TYPE_CODE_INT)
+ {
+ /* We have a repeat count. Validate the second value and then
+ construct a value repeated that many times. */
+ if (TYPE_CODE (type2) == TYPE_CODE_STRING
+ || TYPE_CODE (type2) == TYPE_CODE_CHAR)
+ {
+ count = longest_to_int (value_as_long (inval1));
+ inval2len = TYPE_LENGTH (type2);
+ ptr = (char *) alloca (count * inval2len);
+ if (TYPE_CODE (type2) == TYPE_CODE_CHAR)
+ {
+ inchar = (char) unpack_long (type2,
+ VALUE_CONTENTS (inval2));
+ for (idx = 0; idx < count; idx++)
+ {
+ *(ptr + idx) = inchar;
+ }
+ }
+ else
+ {
+ for (idx = 0; idx < count; idx++)
+ {
+ memcpy (ptr + (idx * inval2len), VALUE_CONTENTS (inval2),
+ inval2len);
+ }
+ }
+ outval = value_string (ptr, count * inval2len);
+ }
+ else if (TYPE_CODE (type2) == TYPE_CODE_BITSTRING
+ || TYPE_CODE (type2) == TYPE_CODE_BOOL)
+ {
+ error ("unimplemented support for bitstring/boolean repeats");
+ }
+ else
+ {
+ error ("can't repeat values of that type");
+ }
+ }
+ else if (TYPE_CODE (type1) == TYPE_CODE_STRING
+ || TYPE_CODE (type1) == TYPE_CODE_CHAR)
+ {
+ /* We have two character strings to concatenate. */
+ if (TYPE_CODE (type2) != TYPE_CODE_STRING
+ && TYPE_CODE (type2) != TYPE_CODE_CHAR)
+ {
+ error ("Strings can only be concatenated with other strings.");
+ }
+ inval1len = TYPE_LENGTH (type1);
+ inval2len = TYPE_LENGTH (type2);
+ ptr = (char *) alloca (inval1len + inval2len);
+ if (TYPE_CODE (type1) == TYPE_CODE_CHAR)
+ {
+ *ptr = (char) unpack_long (type1, VALUE_CONTENTS (inval1));
+ }
+ else
+ {
+ memcpy (ptr, VALUE_CONTENTS (inval1), inval1len);
+ }
+ if (TYPE_CODE (type2) == TYPE_CODE_CHAR)
+ {
+ *(ptr + inval1len) =
+ (char) unpack_long (type2, VALUE_CONTENTS (inval2));
+ }
+ else
+ {
+ memcpy (ptr + inval1len, VALUE_CONTENTS (inval2), inval2len);
+ }
+ outval = value_string (ptr, inval1len + inval2len);
+ }
+ else if (TYPE_CODE (type1) == TYPE_CODE_BITSTRING
+ || TYPE_CODE (type1) == TYPE_CODE_BOOL)
+ {
+ /* We have two bitstrings to concatenate. */
+ if (TYPE_CODE (type2) != TYPE_CODE_BITSTRING
+ && TYPE_CODE (type2) != TYPE_CODE_BOOL)
+ {
+ error ("Bitstrings or booleans can only be concatenated with other bitstrings or booleans.");
+ }
+ error ("unimplemented support for bitstring/boolean concatenation.");
+ }
+ else
+ {
+ /* We don't know how to concatenate these operands. */
+ error ("illegal operands for concatenation.");
+ }
+ return (outval);
+}
+
+
+
+/* Perform a binary operation on two operands which have reasonable
+ representations as integers or floats. This includes booleans,
+ characters, integers, or floats.
+ Does not support addition and subtraction on pointers;
+ use value_add or value_sub if you want to handle those possibilities. */
+
+struct value *
+value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
+{
+ struct value *val;
+ struct type *type1, *type2;
+
+ COERCE_REF (arg1);
+ COERCE_REF (arg2);
+ COERCE_ENUM (arg1);
+ COERCE_ENUM (arg2);
+ type1 = check_typedef (VALUE_TYPE (arg1));
+ type2 = check_typedef (VALUE_TYPE (arg2));
+
+ if ((TYPE_CODE (type1) != TYPE_CODE_FLT
+ && TYPE_CODE (type1) != TYPE_CODE_CHAR
+ && TYPE_CODE (type1) != TYPE_CODE_INT
+ && TYPE_CODE (type1) != TYPE_CODE_BOOL
+ && TYPE_CODE (type1) != TYPE_CODE_RANGE)
+ ||
+ (TYPE_CODE (type2) != TYPE_CODE_FLT
+ && TYPE_CODE (type2) != TYPE_CODE_CHAR
+ && TYPE_CODE (type2) != TYPE_CODE_INT
+ && TYPE_CODE (type2) != TYPE_CODE_BOOL
+ && TYPE_CODE (type2) != TYPE_CODE_RANGE))
+ error ("Argument to arithmetic operation not a number or boolean.");
+
+ if (TYPE_CODE (type1) == TYPE_CODE_FLT
+ ||
+ TYPE_CODE (type2) == TYPE_CODE_FLT)
+ {
+ /* FIXME-if-picky-about-floating-accuracy: Should be doing this
+ in target format. real.c in GCC probably has the necessary
+ code. */
+ DOUBLEST v1, v2, v = 0;
+ v1 = value_as_double (arg1);
+ v2 = value_as_double (arg2);
+ switch (op)
+ {
+ case BINOP_ADD:
+ v = v1 + v2;
+ break;
+
+ case BINOP_SUB:
+ v = v1 - v2;
+ break;
+
+ case BINOP_MUL:
+ v = v1 * v2;
+ break;
+
+ case BINOP_DIV:
+ v = v1 / v2;
+ break;
+
+ case BINOP_EXP:
+ v = pow (v1, v2);
+ if (errno)
+ error ("Cannot perform exponentiation: %s", safe_strerror (errno));
+ break;
+
+ default:
+ error ("Integer-only operation on floating point number.");
+ }
+
+ /* If either arg was long double, make sure that value is also long
+ double. */
+
+ if (TYPE_LENGTH (type1) * 8 > TARGET_DOUBLE_BIT
+ || TYPE_LENGTH (type2) * 8 > TARGET_DOUBLE_BIT)
+ val = allocate_value (builtin_type_long_double);
+ else
+ val = allocate_value (builtin_type_double);
+
+ store_typed_floating (VALUE_CONTENTS_RAW (val), VALUE_TYPE (val), v);
+ }
+ else if (TYPE_CODE (type1) == TYPE_CODE_BOOL
+ &&
+ TYPE_CODE (type2) == TYPE_CODE_BOOL)
+ {
+ LONGEST v1, v2, v = 0;
+ v1 = value_as_long (arg1);
+ v2 = value_as_long (arg2);
+
+ switch (op)
+ {
+ case BINOP_BITWISE_AND:
+ v = v1 & v2;
+ break;
+
+ case BINOP_BITWISE_IOR:
+ v = v1 | v2;
+ break;
+
+ case BINOP_BITWISE_XOR:
+ v = v1 ^ v2;
+ break;
+
+ case BINOP_EQUAL:
+ v = v1 == v2;
+ break;
+
+ case BINOP_NOTEQUAL:
+ v = v1 != v2;
+ break;
+
+ default:
+ error ("Invalid operation on booleans.");
+ }
+
+ val = allocate_value (type1);
+ store_signed_integer (VALUE_CONTENTS_RAW (val),
+ TYPE_LENGTH (type1),
+ v);
+ }
+ else
+ /* Integral operations here. */
+ /* FIXME: Also mixed integral/booleans, with result an integer. */
+ /* FIXME: This implements ANSI C rules (also correct for C++).
+ What about FORTRAN and chill? */
+ {
+ unsigned int promoted_len1 = TYPE_LENGTH (type1);
+ unsigned int promoted_len2 = TYPE_LENGTH (type2);
+ int is_unsigned1 = TYPE_UNSIGNED (type1);
+ int is_unsigned2 = TYPE_UNSIGNED (type2);
+ unsigned int result_len;
+ int unsigned_operation;
+
+ /* Determine type length and signedness after promotion for
+ both operands. */
+ if (promoted_len1 < TYPE_LENGTH (builtin_type_int))
+ {
+ is_unsigned1 = 0;
+ promoted_len1 = TYPE_LENGTH (builtin_type_int);
+ }
+ if (promoted_len2 < TYPE_LENGTH (builtin_type_int))
+ {
+ is_unsigned2 = 0;
+ promoted_len2 = TYPE_LENGTH (builtin_type_int);
+ }
+
+ /* Determine type length of the result, and if the operation should
+ be done unsigned.
+ Use the signedness of the operand with the greater length.
+ If both operands are of equal length, use unsigned operation
+ if one of the operands is unsigned. */
+ if (promoted_len1 > promoted_len2)
+ {
+ unsigned_operation = is_unsigned1;
+ result_len = promoted_len1;
+ }
+ else if (promoted_len2 > promoted_len1)
+ {
+ unsigned_operation = is_unsigned2;
+ result_len = promoted_len2;
+ }
+ else
+ {
+ unsigned_operation = is_unsigned1 || is_unsigned2;
+ result_len = promoted_len1;
+ }
+
+ if (unsigned_operation)
+ {
+ ULONGEST v1, v2, v = 0;
+ v1 = (ULONGEST) value_as_long (arg1);
+ v2 = (ULONGEST) value_as_long (arg2);
+
+ /* Truncate values to the type length of the result. */
+ if (result_len < sizeof (ULONGEST))
+ {
+ v1 &= ((LONGEST) 1 << HOST_CHAR_BIT * result_len) - 1;
+ v2 &= ((LONGEST) 1 << HOST_CHAR_BIT * result_len) - 1;
+ }
+
+ switch (op)
+ {
+ case BINOP_ADD:
+ v = v1 + v2;
+ break;
+
+ case BINOP_SUB:
+ v = v1 - v2;
+ break;
+
+ case BINOP_MUL:
+ v = v1 * v2;
+ break;
+
+ case BINOP_DIV:
+ v = v1 / v2;
+ break;
+
+ case BINOP_EXP:
+ v = pow (v1, v2);
+ if (errno)
+ error ("Cannot perform exponentiation: %s", safe_strerror (errno));
+ break;
+
+ case BINOP_REM:
+ v = v1 % v2;
+ break;
+
+ case BINOP_MOD:
+ /* Knuth 1.2.4, integer only. Note that unlike the C '%' op,
+ v1 mod 0 has a defined value, v1. */
+ /* Chill specifies that v2 must be > 0, so check for that. */
+ if (current_language->la_language == language_chill
+ && value_as_long (arg2) <= 0)
+ {
+ error ("Second operand of MOD must be greater than zero.");
+ }
+ if (v2 == 0)
+ {
+ v = v1;
+ }
+ else
+ {
+ v = v1 / v2;
+ /* Note floor(v1/v2) == v1/v2 for unsigned. */
+ v = v1 - (v2 * v);
+ }
+ break;
+
+ case BINOP_LSH:
+ v = v1 << v2;
+ break;
+
+ case BINOP_RSH:
+ v = v1 >> v2;
+ break;
+
+ case BINOP_BITWISE_AND:
+ v = v1 & v2;
+ break;
+
+ case BINOP_BITWISE_IOR:
+ v = v1 | v2;
+ break;
+
+ case BINOP_BITWISE_XOR:
+ v = v1 ^ v2;
+ break;
+
+ case BINOP_LOGICAL_AND:
+ v = v1 && v2;
+ break;
+
+ case BINOP_LOGICAL_OR:
+ v = v1 || v2;
+ break;
+
+ case BINOP_MIN:
+ v = v1 < v2 ? v1 : v2;
+ break;
+
+ case BINOP_MAX:
+ v = v1 > v2 ? v1 : v2;
+ break;
+
+ case BINOP_EQUAL:
+ v = v1 == v2;
+ break;
+
+ case BINOP_NOTEQUAL:
+ v = v1 != v2;
+ break;
+
+ case BINOP_LESS:
+ v = v1 < v2;
+ break;
+
+ default:
+ error ("Invalid binary operation on numbers.");
+ }
+
+ /* This is a kludge to get around the fact that we don't
+ know how to determine the result type from the types of
+ the operands. (I'm not really sure how much we feel the
+ need to duplicate the exact rules of the current
+ language. They can get really hairy. But not to do so
+ makes it hard to document just what we *do* do). */
+
+ /* Can't just call init_type because we wouldn't know what
+ name to give the type. */
+ val = allocate_value
+ (result_len > TARGET_LONG_BIT / HOST_CHAR_BIT
+ ? builtin_type_unsigned_long_long
+ : builtin_type_unsigned_long);
+ store_unsigned_integer (VALUE_CONTENTS_RAW (val),
+ TYPE_LENGTH (VALUE_TYPE (val)),
+ v);
+ }
+ else
+ {
+ LONGEST v1, v2, v = 0;
+ v1 = value_as_long (arg1);
+ v2 = value_as_long (arg2);
+
+ switch (op)
+ {
+ case BINOP_ADD:
+ v = v1 + v2;
+ break;
+
+ case BINOP_SUB:
+ v = v1 - v2;
+ break;
+
+ case BINOP_MUL:
+ v = v1 * v2;
+ break;
+
+ case BINOP_DIV:
+ v = v1 / v2;
+ break;
+
+ case BINOP_EXP:
+ v = pow (v1, v2);
+ if (errno)
+ error ("Cannot perform exponentiation: %s", safe_strerror (errno));
+ break;
+
+ case BINOP_REM:
+ v = v1 % v2;
+ break;
+
+ case BINOP_MOD:
+ /* Knuth 1.2.4, integer only. Note that unlike the C '%' op,
+ X mod 0 has a defined value, X. */
+ /* Chill specifies that v2 must be > 0, so check for that. */
+ if (current_language->la_language == language_chill
+ && v2 <= 0)
+ {
+ error ("Second operand of MOD must be greater than zero.");
+ }
+ if (v2 == 0)
+ {
+ v = v1;
+ }
+ else
+ {
+ v = v1 / v2;
+ /* Compute floor. */
+ if (TRUNCATION_TOWARDS_ZERO && (v < 0) && ((v1 % v2) != 0))
+ {
+ v--;
+ }
+ v = v1 - (v2 * v);
+ }
+ break;
+
+ case BINOP_LSH:
+ v = v1 << v2;
+ break;
+
+ case BINOP_RSH:
+ v = v1 >> v2;
+ break;
+
+ case BINOP_BITWISE_AND:
+ v = v1 & v2;
+ break;
+
+ case BINOP_BITWISE_IOR:
+ v = v1 | v2;
+ break;
+
+ case BINOP_BITWISE_XOR:
+ v = v1 ^ v2;
+ break;
+
+ case BINOP_LOGICAL_AND:
+ v = v1 && v2;
+ break;
+
+ case BINOP_LOGICAL_OR:
+ v = v1 || v2;
+ break;
+
+ case BINOP_MIN:
+ v = v1 < v2 ? v1 : v2;
+ break;
+
+ case BINOP_MAX:
+ v = v1 > v2 ? v1 : v2;
+ break;
+
+ case BINOP_EQUAL:
+ v = v1 == v2;
+ break;
+
+ case BINOP_LESS:
+ v = v1 < v2;
+ break;
+
+ default:
+ error ("Invalid binary operation on numbers.");
+ }
+
+ /* This is a kludge to get around the fact that we don't
+ know how to determine the result type from the types of
+ the operands. (I'm not really sure how much we feel the
+ need to duplicate the exact rules of the current
+ language. They can get really hairy. But not to do so
+ makes it hard to document just what we *do* do). */
+
+ /* Can't just call init_type because we wouldn't know what
+ name to give the type. */
+ val = allocate_value
+ (result_len > TARGET_LONG_BIT / HOST_CHAR_BIT
+ ? builtin_type_long_long
+ : builtin_type_long);
+ store_signed_integer (VALUE_CONTENTS_RAW (val),
+ TYPE_LENGTH (VALUE_TYPE (val)),
+ v);
+ }
+ }
+
+ return val;
+}
+
+/* Simulate the C operator ! -- return 1 if ARG1 contains zero. */
+
+int
+value_logical_not (struct value *arg1)
+{
+ register int len;
+ register char *p;
+ struct type *type1;
+
+ COERCE_NUMBER (arg1);
+ type1 = check_typedef (VALUE_TYPE (arg1));
+
+ if (TYPE_CODE (type1) == TYPE_CODE_FLT)
+ return 0 == value_as_double (arg1);
+
+ len = TYPE_LENGTH (type1);
+ p = VALUE_CONTENTS (arg1);
+
+ while (--len >= 0)
+ {
+ if (*p++)
+ break;
+ }
+
+ return len < 0;
+}
+
+/* Perform a comparison on two string values (whose content are not
+ necessarily null terminated) based on their length */
+
+static int
+value_strcmp (struct value *arg1, struct value *arg2)
+{
+ int len1 = TYPE_LENGTH (VALUE_TYPE (arg1));
+ int len2 = TYPE_LENGTH (VALUE_TYPE (arg2));
+ char *s1 = VALUE_CONTENTS (arg1);
+ char *s2 = VALUE_CONTENTS (arg2);
+ int i, len = len1 < len2 ? len1 : len2;
+
+ for (i = 0; i < len; i++)
+ {
+ if (s1[i] < s2[i])
+ return -1;
+ else if (s1[i] > s2[i])
+ return 1;
+ else
+ continue;
+ }
+
+ if (len1 < len2)
+ return -1;
+ else if (len1 > len2)
+ return 1;
+ else
+ return 0;
+}
+
+/* Simulate the C operator == by returning a 1
+ iff ARG1 and ARG2 have equal contents. */
+
+int
+value_equal (struct value *arg1, struct value *arg2)
+{
+ register int len;
+ register char *p1, *p2;
+ struct type *type1, *type2;
+ enum type_code code1;
+ enum type_code code2;
+
+ COERCE_NUMBER (arg1);
+ COERCE_NUMBER (arg2);
+
+ type1 = check_typedef (VALUE_TYPE (arg1));
+ type2 = check_typedef (VALUE_TYPE (arg2));
+ code1 = TYPE_CODE (type1);
+ code2 = TYPE_CODE (type2);
+
+ if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL) &&
+ (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
+ return longest_to_int (value_as_long (value_binop (arg1, arg2,
+ BINOP_EQUAL)));
+ else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL)
+ && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
+ return value_as_double (arg1) == value_as_double (arg2);
+
+ /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
+ is bigger. */
+ else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
+ return value_as_address (arg1) == (CORE_ADDR) value_as_long (arg2);
+ else if (code2 == TYPE_CODE_PTR && (code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL))
+ return (CORE_ADDR) value_as_long (arg1) == value_as_address (arg2);
+
+ else if (code1 == code2
+ && ((len = (int) TYPE_LENGTH (type1))
+ == (int) TYPE_LENGTH (type2)))
+ {
+ p1 = VALUE_CONTENTS (arg1);
+ p2 = VALUE_CONTENTS (arg2);
+ while (--len >= 0)
+ {
+ if (*p1++ != *p2++)
+ break;
+ }
+ return len < 0;
+ }
+ else if (code1 == TYPE_CODE_STRING && code2 == TYPE_CODE_STRING)
+ {
+ return value_strcmp (arg1, arg2) == 0;
+ }
+ else
+ {
+ error ("Invalid type combination in equality test.");
+ return 0; /* For lint -- never reached */
+ }
+}
+
+/* Simulate the C operator < by returning 1
+ iff ARG1's contents are less than ARG2's. */
+
+int
+value_less (struct value *arg1, struct value *arg2)
+{
+ register enum type_code code1;
+ register enum type_code code2;
+ struct type *type1, *type2;
+
+ COERCE_NUMBER (arg1);
+ COERCE_NUMBER (arg2);
+
+ type1 = check_typedef (VALUE_TYPE (arg1));
+ type2 = check_typedef (VALUE_TYPE (arg2));
+ code1 = TYPE_CODE (type1);
+ code2 = TYPE_CODE (type2);
+
+ if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL) &&
+ (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
+ return longest_to_int (value_as_long (value_binop (arg1, arg2,
+ BINOP_LESS)));
+ else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL)
+ && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
+ return value_as_double (arg1) < value_as_double (arg2);
+ else if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
+ return value_as_address (arg1) < value_as_address (arg2);
+
+ /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
+ is bigger. */
+ else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
+ return value_as_address (arg1) < (CORE_ADDR) value_as_long (arg2);
+ else if (code2 == TYPE_CODE_PTR && (code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL))
+ return (CORE_ADDR) value_as_long (arg1) < value_as_address (arg2);
+ else if (code1 == TYPE_CODE_STRING && code2 == TYPE_CODE_STRING)
+ return value_strcmp (arg1, arg2) < 0;
+ else
+ {
+ error ("Invalid type combination in ordering comparison.");
+ return 0;
+ }
+}
+
+/* The unary operators - and ~. Both free the argument ARG1. */
+
+struct value *
+value_neg (struct value *arg1)
+{
+ register struct type *type;
+ register struct type *result_type = VALUE_TYPE (arg1);
+
+ COERCE_REF (arg1);
+ COERCE_ENUM (arg1);
+
+ type = check_typedef (VALUE_TYPE (arg1));
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ return value_from_double (result_type, -value_as_double (arg1));
+ else if (TYPE_CODE (type) == TYPE_CODE_INT || TYPE_CODE (type) == TYPE_CODE_BOOL)
+ {
+ /* Perform integral promotion for ANSI C/C++.
+ FIXME: What about FORTRAN and chill ? */
+ if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
+ result_type = builtin_type_int;
+
+ return value_from_longest (result_type, -value_as_long (arg1));
+ }
+ else
+ {
+ error ("Argument to negate operation not a number.");
+ return 0; /* For lint -- never reached */
+ }
+}
+
+struct value *
+value_complement (struct value *arg1)
+{
+ register struct type *type;
+ register struct type *result_type = VALUE_TYPE (arg1);
+ int typecode;
+
+ COERCE_REF (arg1);
+ COERCE_ENUM (arg1);
+
+ type = check_typedef (VALUE_TYPE (arg1));
+
+ typecode = TYPE_CODE (type);
+ if ((typecode != TYPE_CODE_INT) && (typecode != TYPE_CODE_BOOL))
+ error ("Argument to complement operation not an integer or boolean.");
+
+ /* Perform integral promotion for ANSI C/C++.
+ FIXME: What about FORTRAN ? */
+ if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
+ result_type = builtin_type_int;
+
+ return value_from_longest (result_type, ~value_as_long (arg1));
+}
+
+/* The INDEX'th bit of SET value whose VALUE_TYPE is TYPE,
+ and whose VALUE_CONTENTS is valaddr.
+ Return -1 if out of range, -2 other error. */
+
+int
+value_bit_index (struct type *type, char *valaddr, int index)
+{
+ LONGEST low_bound, high_bound;
+ LONGEST word;
+ unsigned rel_index;
+ struct type *range = TYPE_FIELD_TYPE (type, 0);
+ if (get_discrete_bounds (range, &low_bound, &high_bound) < 0)
+ return -2;
+ if (index < low_bound || index > high_bound)
+ return -1;
+ rel_index = index - low_bound;
+ word = unpack_long (builtin_type_unsigned_char,
+ valaddr + (rel_index / TARGET_CHAR_BIT));
+ rel_index %= TARGET_CHAR_BIT;
+ if (BITS_BIG_ENDIAN)
+ rel_index = TARGET_CHAR_BIT - 1 - rel_index;
+ return (word >> rel_index) & 1;
+}
+
+struct value *
+value_in (struct value *element, struct value *set)
+{
+ int member;
+ struct type *settype = check_typedef (VALUE_TYPE (set));
+ struct type *eltype = check_typedef (VALUE_TYPE (element));
+ if (TYPE_CODE (eltype) == TYPE_CODE_RANGE)
+ eltype = TYPE_TARGET_TYPE (eltype);
+ if (TYPE_CODE (settype) != TYPE_CODE_SET)
+ error ("Second argument of 'IN' has wrong type");
+ if (TYPE_CODE (eltype) != TYPE_CODE_INT
+ && TYPE_CODE (eltype) != TYPE_CODE_CHAR
+ && TYPE_CODE (eltype) != TYPE_CODE_ENUM
+ && TYPE_CODE (eltype) != TYPE_CODE_BOOL)
+ error ("First argument of 'IN' has wrong type");
+ member = value_bit_index (settype, VALUE_CONTENTS (set),
+ value_as_long (element));
+ if (member < 0)
+ error ("First argument of 'IN' not in range");
+ return value_from_longest (LA_BOOL_TYPE, member);
+}
+
+void
+_initialize_valarith (void)
+{
+}
diff --git a/gdb/valops.c b/gdb/valops.c
new file mode 100644
index 00000000000..798e31fc646
--- /dev/null
+++ b/gdb/valops.c
@@ -0,0 +1,3455 @@
+/* Perform non-arithmetic operations on values, for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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 "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "value.h"
+#include "frame.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "demangle.h"
+#include "language.h"
+#include "gdbcmd.h"
+#include "regcache.h"
+#include "cp-abi.h"
+
+#include <errno.h>
+#include "gdb_string.h"
+#include "gdb_assert.h"
+
+/* Flag indicating HP compilers were used; needed to correctly handle some
+ value operations with HP aCC code/runtime. */
+extern int hp_som_som_object_present;
+
+extern int overload_debug;
+/* Local functions. */
+
+static int typecmp (int staticp, struct type *t1[], struct value *t2[]);
+
+static CORE_ADDR find_function_addr (struct value *, struct type **);
+static struct value *value_arg_coerce (struct value *, struct type *, int);
+
+
+static CORE_ADDR value_push (CORE_ADDR, struct value *);
+
+static struct value *search_struct_field (char *, struct value *, int,
+ struct type *, int);
+
+static struct value *search_struct_method (char *, struct value **,
+ struct value **,
+ int, int *, struct type *);
+
+static int check_field_in (struct type *, const char *);
+
+static CORE_ADDR allocate_space_in_inferior (int);
+
+static struct value *cast_into_complex (struct type *, struct value *);
+
+static struct fn_field *find_method_list (struct value ** argp, char *method,
+ int offset,
+ struct type *type, int *num_fns,
+ struct type **basetype,
+ int *boffset);
+
+void _initialize_valops (void);
+
+/* Flag for whether we want to abandon failed expression evals by default. */
+
+#if 0
+static int auto_abandon = 0;
+#endif
+
+int overload_resolution = 0;
+
+/* This boolean tells what gdb should do if a signal is received while in
+ a function called from gdb (call dummy). If set, gdb unwinds the stack
+ and restore the context to what as it was before the call.
+ The default is to stop in the frame where the signal was received. */
+
+int unwind_on_signal_p = 0;
+
+
+
+/* Find the address of function name NAME in the inferior. */
+
+struct value *
+find_function_in_inferior (char *name)
+{
+ register struct symbol *sym;
+ sym = lookup_symbol (name, 0, VAR_NAMESPACE, 0, NULL);
+ if (sym != NULL)
+ {
+ if (SYMBOL_CLASS (sym) != LOC_BLOCK)
+ {
+ error ("\"%s\" exists in this program but is not a function.",
+ name);
+ }
+ return value_of_variable (sym, NULL);
+ }
+ else
+ {
+ struct minimal_symbol *msymbol = lookup_minimal_symbol (name, NULL, NULL);
+ if (msymbol != NULL)
+ {
+ struct type *type;
+ CORE_ADDR maddr;
+ type = lookup_pointer_type (builtin_type_char);
+ type = lookup_function_type (type);
+ type = lookup_pointer_type (type);
+ maddr = SYMBOL_VALUE_ADDRESS (msymbol);
+ return value_from_pointer (type, maddr);
+ }
+ else
+ {
+ if (!target_has_execution)
+ error ("evaluation of this expression requires the target program to be active");
+ else
+ error ("evaluation of this expression requires the program to have a function \"%s\".", name);
+ }
+ }
+}
+
+/* Allocate NBYTES of space in the inferior using the inferior's malloc
+ and return a value that is a pointer to the allocated space. */
+
+struct value *
+value_allocate_space_in_inferior (int len)
+{
+ struct value *blocklen;
+ struct value *val = find_function_in_inferior ("malloc");
+
+ blocklen = value_from_longest (builtin_type_int, (LONGEST) len);
+ val = call_function_by_hand (val, 1, &blocklen);
+ if (value_logical_not (val))
+ {
+ if (!target_has_execution)
+ error ("No memory available to program now: you need to start the target first");
+ else
+ error ("No memory available to program: call to malloc failed");
+ }
+ return val;
+}
+
+static CORE_ADDR
+allocate_space_in_inferior (int len)
+{
+ return value_as_long (value_allocate_space_in_inferior (len));
+}
+
+/* Cast value ARG2 to type TYPE and return as a value.
+ More general than a C cast: accepts any two types of the same length,
+ and if ARG2 is an lvalue it can be cast into anything at all. */
+/* In C++, casts may change pointer or object representations. */
+
+struct value *
+value_cast (struct type *type, struct value *arg2)
+{
+ register enum type_code code1;
+ register enum type_code code2;
+ register int scalar;
+ struct type *type2;
+
+ int convert_to_boolean = 0;
+
+ if (VALUE_TYPE (arg2) == type)
+ return arg2;
+
+ CHECK_TYPEDEF (type);
+ code1 = TYPE_CODE (type);
+ COERCE_REF (arg2);
+ type2 = check_typedef (VALUE_TYPE (arg2));
+
+ /* A cast to an undetermined-length array_type, such as (TYPE [])OBJECT,
+ is treated like a cast to (TYPE [N])OBJECT,
+ where N is sizeof(OBJECT)/sizeof(TYPE). */
+ if (code1 == TYPE_CODE_ARRAY)
+ {
+ struct type *element_type = TYPE_TARGET_TYPE (type);
+ unsigned element_length = TYPE_LENGTH (check_typedef (element_type));
+ if (element_length > 0
+ && TYPE_ARRAY_UPPER_BOUND_TYPE (type) == BOUND_CANNOT_BE_DETERMINED)
+ {
+ struct type *range_type = TYPE_INDEX_TYPE (type);
+ int val_length = TYPE_LENGTH (type2);
+ LONGEST low_bound, high_bound, new_length;
+ if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+ low_bound = 0, high_bound = 0;
+ new_length = val_length / element_length;
+ if (val_length % element_length != 0)
+ warning ("array element type size does not divide object size in cast");
+ /* FIXME-type-allocation: need a way to free this type when we are
+ done with it. */
+ range_type = create_range_type ((struct type *) NULL,
+ TYPE_TARGET_TYPE (range_type),
+ low_bound,
+ new_length + low_bound - 1);
+ VALUE_TYPE (arg2) = create_array_type ((struct type *) NULL,
+ element_type, range_type);
+ return arg2;
+ }
+ }
+
+ if (current_language->c_style_arrays
+ && TYPE_CODE (type2) == TYPE_CODE_ARRAY)
+ arg2 = value_coerce_array (arg2);
+
+ if (TYPE_CODE (type2) == TYPE_CODE_FUNC)
+ arg2 = value_coerce_function (arg2);
+
+ type2 = check_typedef (VALUE_TYPE (arg2));
+ COERCE_VARYING_ARRAY (arg2, type2);
+ code2 = TYPE_CODE (type2);
+
+ if (code1 == TYPE_CODE_COMPLEX)
+ return cast_into_complex (type, arg2);
+ if (code1 == TYPE_CODE_BOOL)
+ {
+ code1 = TYPE_CODE_INT;
+ convert_to_boolean = 1;
+ }
+ if (code1 == TYPE_CODE_CHAR)
+ code1 = TYPE_CODE_INT;
+ if (code2 == TYPE_CODE_BOOL || code2 == TYPE_CODE_CHAR)
+ code2 = TYPE_CODE_INT;
+
+ scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT
+ || code2 == TYPE_CODE_ENUM || code2 == TYPE_CODE_RANGE);
+
+ if (code1 == TYPE_CODE_STRUCT
+ && code2 == TYPE_CODE_STRUCT
+ && TYPE_NAME (type) != 0)
+ {
+ /* Look in the type of the source to see if it contains the
+ type of the target as a superclass. If so, we'll need to
+ offset the object in addition to changing its type. */
+ struct value *v = search_struct_field (type_name_no_tag (type),
+ arg2, 0, type2, 1);
+ if (v)
+ {
+ VALUE_TYPE (v) = type;
+ return v;
+ }
+ }
+ if (code1 == TYPE_CODE_FLT && scalar)
+ return value_from_double (type, value_as_double (arg2));
+ else if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_ENUM
+ || code1 == TYPE_CODE_RANGE)
+ && (scalar || code2 == TYPE_CODE_PTR))
+ {
+ LONGEST longest;
+
+ if (hp_som_som_object_present && /* if target compiled by HP aCC */
+ (code2 == TYPE_CODE_PTR))
+ {
+ unsigned int *ptr;
+ struct value *retvalp;
+
+ switch (TYPE_CODE (TYPE_TARGET_TYPE (type2)))
+ {
+ /* With HP aCC, pointers to data members have a bias */
+ case TYPE_CODE_MEMBER:
+ retvalp = value_from_longest (type, value_as_long (arg2));
+ /* force evaluation */
+ ptr = (unsigned int *) VALUE_CONTENTS (retvalp);
+ *ptr &= ~0x20000000; /* zap 29th bit to remove bias */
+ return retvalp;
+
+ /* While pointers to methods don't really point to a function */
+ case TYPE_CODE_METHOD:
+ error ("Pointers to methods not supported with HP aCC");
+
+ default:
+ break; /* fall out and go to normal handling */
+ }
+ }
+
+ /* When we cast pointers to integers, we mustn't use
+ POINTER_TO_ADDRESS to find the address the pointer
+ represents, as value_as_long would. GDB should evaluate
+ expressions just as the compiler would --- and the compiler
+ sees a cast as a simple reinterpretation of the pointer's
+ bits. */
+ if (code2 == TYPE_CODE_PTR)
+ longest = extract_unsigned_integer (VALUE_CONTENTS (arg2),
+ TYPE_LENGTH (type2));
+ else
+ longest = value_as_long (arg2);
+ return value_from_longest (type, convert_to_boolean ?
+ (LONGEST) (longest ? 1 : 0) : longest);
+ }
+ else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT ||
+ code2 == TYPE_CODE_ENUM ||
+ code2 == TYPE_CODE_RANGE))
+ {
+ /* TYPE_LENGTH (type) is the length of a pointer, but we really
+ want the length of an address! -- we are really dealing with
+ addresses (i.e., gdb representations) not pointers (i.e.,
+ target representations) here.
+
+ This allows things like "print *(int *)0x01000234" to work
+ without printing a misleading message -- which would
+ otherwise occur when dealing with a target having two byte
+ pointers and four byte addresses. */
+
+ int addr_bit = TARGET_ADDR_BIT;
+
+ LONGEST longest = value_as_long (arg2);
+ if (addr_bit < sizeof (LONGEST) * HOST_CHAR_BIT)
+ {
+ if (longest >= ((LONGEST) 1 << addr_bit)
+ || longest <= -((LONGEST) 1 << addr_bit))
+ warning ("value truncated");
+ }
+ return value_from_longest (type, longest);
+ }
+ else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2))
+ {
+ if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
+ {
+ struct type *t1 = check_typedef (TYPE_TARGET_TYPE (type));
+ struct type *t2 = check_typedef (TYPE_TARGET_TYPE (type2));
+ if (TYPE_CODE (t1) == TYPE_CODE_STRUCT
+ && TYPE_CODE (t2) == TYPE_CODE_STRUCT
+ && !value_logical_not (arg2))
+ {
+ struct value *v;
+
+ /* Look in the type of the source to see if it contains the
+ type of the target as a superclass. If so, we'll need to
+ offset the pointer rather than just change its type. */
+ if (TYPE_NAME (t1) != NULL)
+ {
+ v = search_struct_field (type_name_no_tag (t1),
+ value_ind (arg2), 0, t2, 1);
+ if (v)
+ {
+ v = value_addr (v);
+ VALUE_TYPE (v) = type;
+ return v;
+ }
+ }
+
+ /* Look in the type of the target to see if it contains the
+ type of the source as a superclass. If so, we'll need to
+ offset the pointer rather than just change its type.
+ FIXME: This fails silently with virtual inheritance. */
+ if (TYPE_NAME (t2) != NULL)
+ {
+ v = search_struct_field (type_name_no_tag (t2),
+ value_zero (t1, not_lval), 0, t1, 1);
+ if (v)
+ {
+ struct value *v2 = value_ind (arg2);
+ VALUE_ADDRESS (v2) -= VALUE_ADDRESS (v)
+ + VALUE_OFFSET (v);
+
+ /* JYG: adjust the new pointer value and
+ embedded offset. */
+ v2->aligner.contents[0] -= VALUE_EMBEDDED_OFFSET (v);
+ VALUE_EMBEDDED_OFFSET (v2) = 0;
+
+ v2 = value_addr (v2);
+ VALUE_TYPE (v2) = type;
+ return v2;
+ }
+ }
+ }
+ /* No superclass found, just fall through to change ptr type. */
+ }
+ VALUE_TYPE (arg2) = type;
+ arg2 = value_change_enclosing_type (arg2, type);
+ VALUE_POINTED_TO_OFFSET (arg2) = 0; /* pai: chk_val */
+ return arg2;
+ }
+ else if (chill_varying_type (type))
+ {
+ struct type *range1, *range2, *eltype1, *eltype2;
+ struct value *val;
+ int count1, count2;
+ LONGEST low_bound, high_bound;
+ char *valaddr, *valaddr_data;
+ /* For lint warning about eltype2 possibly uninitialized: */
+ eltype2 = NULL;
+ if (code2 == TYPE_CODE_BITSTRING)
+ error ("not implemented: converting bitstring to varying type");
+ if ((code2 != TYPE_CODE_ARRAY && code2 != TYPE_CODE_STRING)
+ || (eltype1 = check_typedef (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 1))),
+ eltype2 = check_typedef (TYPE_TARGET_TYPE (type2)),
+ (TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2)
+ /* || TYPE_CODE (eltype1) != TYPE_CODE (eltype2) */ )))
+ error ("Invalid conversion to varying type");
+ range1 = TYPE_FIELD_TYPE (TYPE_FIELD_TYPE (type, 1), 0);
+ range2 = TYPE_FIELD_TYPE (type2, 0);
+ if (get_discrete_bounds (range1, &low_bound, &high_bound) < 0)
+ count1 = -1;
+ else
+ count1 = high_bound - low_bound + 1;
+ if (get_discrete_bounds (range2, &low_bound, &high_bound) < 0)
+ count1 = -1, count2 = 0; /* To force error before */
+ else
+ count2 = high_bound - low_bound + 1;
+ if (count2 > count1)
+ error ("target varying type is too small");
+ val = allocate_value (type);
+ valaddr = VALUE_CONTENTS_RAW (val);
+ valaddr_data = valaddr + TYPE_FIELD_BITPOS (type, 1) / 8;
+ /* Set val's __var_length field to count2. */
+ store_signed_integer (valaddr, TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)),
+ count2);
+ /* Set the __var_data field to count2 elements copied from arg2. */
+ memcpy (valaddr_data, VALUE_CONTENTS (arg2),
+ count2 * TYPE_LENGTH (eltype2));
+ /* Zero the rest of the __var_data field of val. */
+ memset (valaddr_data + count2 * TYPE_LENGTH (eltype2), '\0',
+ (count1 - count2) * TYPE_LENGTH (eltype2));
+ return val;
+ }
+ else if (VALUE_LVAL (arg2) == lval_memory)
+ {
+ return value_at_lazy (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2),
+ VALUE_BFD_SECTION (arg2));
+ }
+ else if (code1 == TYPE_CODE_VOID)
+ {
+ return value_zero (builtin_type_void, not_lval);
+ }
+ else
+ {
+ error ("Invalid cast.");
+ return 0;
+ }
+}
+
+/* Create a value of type TYPE that is zero, and return it. */
+
+struct value *
+value_zero (struct type *type, enum lval_type lv)
+{
+ struct value *val = allocate_value (type);
+
+ memset (VALUE_CONTENTS (val), 0, TYPE_LENGTH (check_typedef (type)));
+ VALUE_LVAL (val) = lv;
+
+ return val;
+}
+
+/* Return a value with type TYPE located at ADDR.
+
+ Call value_at only if the data needs to be fetched immediately;
+ if we can be 'lazy' and defer the fetch, perhaps indefinately, call
+ value_at_lazy instead. value_at_lazy simply records the address of
+ the data and sets the lazy-evaluation-required flag. The lazy flag
+ is tested in the VALUE_CONTENTS macro, which is used if and when
+ the contents are actually required.
+
+ Note: value_at does *NOT* handle embedded offsets; perform such
+ adjustments before or after calling it. */
+
+struct value *
+value_at (struct type *type, CORE_ADDR addr, asection *sect)
+{
+ struct value *val;
+
+ if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
+ error ("Attempt to dereference a generic pointer.");
+
+ val = allocate_value (type);
+
+ read_memory (addr, VALUE_CONTENTS_ALL_RAW (val), TYPE_LENGTH (type));
+
+ VALUE_LVAL (val) = lval_memory;
+ VALUE_ADDRESS (val) = addr;
+ VALUE_BFD_SECTION (val) = sect;
+
+ return val;
+}
+
+/* Return a lazy value with type TYPE located at ADDR (cf. value_at). */
+
+struct value *
+value_at_lazy (struct type *type, CORE_ADDR addr, asection *sect)
+{
+ struct value *val;
+
+ if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
+ error ("Attempt to dereference a generic pointer.");
+
+ val = allocate_value (type);
+
+ VALUE_LVAL (val) = lval_memory;
+ VALUE_ADDRESS (val) = addr;
+ VALUE_LAZY (val) = 1;
+ VALUE_BFD_SECTION (val) = sect;
+
+ return val;
+}
+
+/* Called only from the VALUE_CONTENTS and VALUE_CONTENTS_ALL macros,
+ if the current data for a variable needs to be loaded into
+ VALUE_CONTENTS(VAL). Fetches the data from the user's process, and
+ clears the lazy flag to indicate that the data in the buffer is valid.
+
+ If the value is zero-length, we avoid calling read_memory, which would
+ abort. We mark the value as fetched anyway -- all 0 bytes of it.
+
+ This function returns a value because it is used in the VALUE_CONTENTS
+ macro as part of an expression, where a void would not work. The
+ value is ignored. */
+
+int
+value_fetch_lazy (struct value *val)
+{
+ CORE_ADDR addr = VALUE_ADDRESS (val) + VALUE_OFFSET (val);
+ int length = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (val));
+
+ struct type *type = VALUE_TYPE (val);
+ if (length)
+ read_memory (addr, VALUE_CONTENTS_ALL_RAW (val), length);
+
+ VALUE_LAZY (val) = 0;
+ return 0;
+}
+
+
+/* Store the contents of FROMVAL into the location of TOVAL.
+ Return a new value with the location of TOVAL and contents of FROMVAL. */
+
+struct value *
+value_assign (struct value *toval, struct value *fromval)
+{
+ register struct type *type;
+ struct value *val;
+ char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ int use_buffer = 0;
+
+ if (!toval->modifiable)
+ error ("Left operand of assignment is not a modifiable lvalue.");
+
+ COERCE_REF (toval);
+
+ type = VALUE_TYPE (toval);
+ if (VALUE_LVAL (toval) != lval_internalvar)
+ fromval = value_cast (type, fromval);
+ else
+ COERCE_ARRAY (fromval);
+ CHECK_TYPEDEF (type);
+
+ /* If TOVAL is a special machine register requiring conversion
+ of program values to a special raw format,
+ convert FROMVAL's contents now, with result in `raw_buffer',
+ and set USE_BUFFER to the number of bytes to write. */
+
+ if (VALUE_REGNO (toval) >= 0)
+ {
+ int regno = VALUE_REGNO (toval);
+ if (CONVERT_REGISTER_P (regno))
+ {
+ struct type *fromtype = check_typedef (VALUE_TYPE (fromval));
+ VALUE_TO_REGISTER (fromtype, regno, VALUE_CONTENTS (fromval), raw_buffer);
+ use_buffer = REGISTER_RAW_SIZE (regno);
+ }
+ }
+
+ switch (VALUE_LVAL (toval))
+ {
+ case lval_internalvar:
+ set_internalvar (VALUE_INTERNALVAR (toval), fromval);
+ val = value_copy (VALUE_INTERNALVAR (toval)->value);
+ val = value_change_enclosing_type (val, VALUE_ENCLOSING_TYPE (fromval));
+ VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (fromval);
+ VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (fromval);
+ return val;
+
+ case lval_internalvar_component:
+ set_internalvar_component (VALUE_INTERNALVAR (toval),
+ VALUE_OFFSET (toval),
+ VALUE_BITPOS (toval),
+ VALUE_BITSIZE (toval),
+ fromval);
+ break;
+
+ case lval_memory:
+ {
+ char *dest_buffer;
+ CORE_ADDR changed_addr;
+ int changed_len;
+
+ if (VALUE_BITSIZE (toval))
+ {
+ char buffer[sizeof (LONGEST)];
+ /* We assume that the argument to read_memory is in units of
+ host chars. FIXME: Is that correct? */
+ changed_len = (VALUE_BITPOS (toval)
+ + VALUE_BITSIZE (toval)
+ + HOST_CHAR_BIT - 1)
+ / HOST_CHAR_BIT;
+
+ if (changed_len > (int) sizeof (LONGEST))
+ error ("Can't handle bitfields which don't fit in a %d bit word.",
+ (int) sizeof (LONGEST) * HOST_CHAR_BIT);
+
+ read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
+ buffer, changed_len);
+ modify_field (buffer, value_as_long (fromval),
+ VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
+ changed_addr = VALUE_ADDRESS (toval) + VALUE_OFFSET (toval);
+ dest_buffer = buffer;
+ }
+ else if (use_buffer)
+ {
+ changed_addr = VALUE_ADDRESS (toval) + VALUE_OFFSET (toval);
+ changed_len = use_buffer;
+ dest_buffer = raw_buffer;
+ }
+ else
+ {
+ changed_addr = VALUE_ADDRESS (toval) + VALUE_OFFSET (toval);
+ changed_len = TYPE_LENGTH (type);
+ dest_buffer = VALUE_CONTENTS (fromval);
+ }
+
+ write_memory (changed_addr, dest_buffer, changed_len);
+ if (memory_changed_hook)
+ memory_changed_hook (changed_addr, changed_len);
+ }
+ break;
+
+ case lval_register:
+ if (VALUE_BITSIZE (toval))
+ {
+ char buffer[sizeof (LONGEST)];
+ int len =
+ REGISTER_RAW_SIZE (VALUE_REGNO (toval)) - VALUE_OFFSET (toval);
+
+ if (len > (int) sizeof (LONGEST))
+ error ("Can't handle bitfields in registers larger than %d bits.",
+ (int) sizeof (LONGEST) * HOST_CHAR_BIT);
+
+ if (VALUE_BITPOS (toval) + VALUE_BITSIZE (toval)
+ > len * HOST_CHAR_BIT)
+ /* Getting this right would involve being very careful about
+ byte order. */
+ error ("Can't assign to bitfields that cross register "
+ "boundaries.");
+
+ read_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
+ buffer, len);
+ modify_field (buffer, value_as_long (fromval),
+ VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
+ write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
+ buffer, len);
+ }
+ else if (use_buffer)
+ write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
+ raw_buffer, use_buffer);
+ else
+ {
+ /* Do any conversion necessary when storing this type to more
+ than one register. */
+#ifdef REGISTER_CONVERT_FROM_TYPE
+ memcpy (raw_buffer, VALUE_CONTENTS (fromval), TYPE_LENGTH (type));
+ REGISTER_CONVERT_FROM_TYPE (VALUE_REGNO (toval), type, raw_buffer);
+ write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
+ raw_buffer, TYPE_LENGTH (type));
+#else
+ write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
+ VALUE_CONTENTS (fromval), TYPE_LENGTH (type));
+#endif
+ }
+ /* Assigning to the stack pointer, frame pointer, and other
+ (architecture and calling convention specific) registers may
+ cause the frame cache to be out of date. We just do this
+ on all assignments to registers for simplicity; I doubt the slowdown
+ matters. */
+ reinit_frame_cache ();
+ break;
+
+ case lval_reg_frame_relative:
+ {
+ /* value is stored in a series of registers in the frame
+ specified by the structure. Copy that value out, modify
+ it, and copy it back in. */
+ int amount_to_copy = (VALUE_BITSIZE (toval) ? 1 : TYPE_LENGTH (type));
+ int reg_size = REGISTER_RAW_SIZE (VALUE_FRAME_REGNUM (toval));
+ int byte_offset = VALUE_OFFSET (toval) % reg_size;
+ int reg_offset = VALUE_OFFSET (toval) / reg_size;
+ int amount_copied;
+
+ /* Make the buffer large enough in all cases. */
+ /* FIXME (alloca): Not safe for very large data types. */
+ char *buffer = (char *) alloca (amount_to_copy
+ + sizeof (LONGEST)
+ + MAX_REGISTER_RAW_SIZE);
+
+ int regno;
+ struct frame_info *frame;
+
+ /* Figure out which frame this is in currently. */
+ for (frame = get_current_frame ();
+ frame && FRAME_FP (frame) != VALUE_FRAME (toval);
+ frame = get_prev_frame (frame))
+ ;
+
+ if (!frame)
+ error ("Value being assigned to is no longer active.");
+
+ amount_to_copy += (reg_size - amount_to_copy % reg_size);
+
+ /* Copy it out. */
+ for ((regno = VALUE_FRAME_REGNUM (toval) + reg_offset,
+ amount_copied = 0);
+ amount_copied < amount_to_copy;
+ amount_copied += reg_size, regno++)
+ {
+ get_saved_register (buffer + amount_copied,
+ (int *) NULL, (CORE_ADDR *) NULL,
+ frame, regno, (enum lval_type *) NULL);
+ }
+
+ /* Modify what needs to be modified. */
+ if (VALUE_BITSIZE (toval))
+ modify_field (buffer + byte_offset,
+ value_as_long (fromval),
+ VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
+ else if (use_buffer)
+ memcpy (buffer + byte_offset, raw_buffer, use_buffer);
+ else
+ memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval),
+ TYPE_LENGTH (type));
+
+ /* Copy it back. */
+ for ((regno = VALUE_FRAME_REGNUM (toval) + reg_offset,
+ amount_copied = 0);
+ amount_copied < amount_to_copy;
+ amount_copied += reg_size, regno++)
+ {
+ enum lval_type lval;
+ CORE_ADDR addr;
+ int optim;
+
+ /* Just find out where to put it. */
+ get_saved_register ((char *) NULL,
+ &optim, &addr, frame, regno, &lval);
+
+ if (optim)
+ error ("Attempt to assign to a value that was optimized out.");
+ if (lval == lval_memory)
+ write_memory (addr, buffer + amount_copied, reg_size);
+ else if (lval == lval_register)
+ write_register_bytes (addr, buffer + amount_copied, reg_size);
+ else
+ error ("Attempt to assign to an unmodifiable value.");
+ }
+
+ if (register_changed_hook)
+ register_changed_hook (-1);
+ }
+ break;
+
+
+ default:
+ error ("Left operand of assignment is not an lvalue.");
+ }
+
+ /* If the field does not entirely fill a LONGEST, then zero the sign bits.
+ If the field is signed, and is negative, then sign extend. */
+ if ((VALUE_BITSIZE (toval) > 0)
+ && (VALUE_BITSIZE (toval) < 8 * (int) sizeof (LONGEST)))
+ {
+ LONGEST fieldval = value_as_long (fromval);
+ LONGEST valmask = (((ULONGEST) 1) << VALUE_BITSIZE (toval)) - 1;
+
+ fieldval &= valmask;
+ if (!TYPE_UNSIGNED (type) && (fieldval & (valmask ^ (valmask >> 1))))
+ fieldval |= ~valmask;
+
+ fromval = value_from_longest (type, fieldval);
+ }
+
+ val = value_copy (toval);
+ memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS (fromval),
+ TYPE_LENGTH (type));
+ VALUE_TYPE (val) = type;
+ val = value_change_enclosing_type (val, VALUE_ENCLOSING_TYPE (fromval));
+ VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (fromval);
+ VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (fromval);
+
+ return val;
+}
+
+/* Extend a value VAL to COUNT repetitions of its type. */
+
+struct value *
+value_repeat (struct value *arg1, int count)
+{
+ struct value *val;
+
+ if (VALUE_LVAL (arg1) != lval_memory)
+ error ("Only values in memory can be extended with '@'.");
+ if (count < 1)
+ error ("Invalid number %d of repetitions.", count);
+
+ val = allocate_repeat_value (VALUE_ENCLOSING_TYPE (arg1), count);
+
+ read_memory (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1),
+ VALUE_CONTENTS_ALL_RAW (val),
+ TYPE_LENGTH (VALUE_ENCLOSING_TYPE (val)));
+ VALUE_LVAL (val) = lval_memory;
+ VALUE_ADDRESS (val) = VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1);
+
+ return val;
+}
+
+struct value *
+value_of_variable (struct symbol *var, struct block *b)
+{
+ struct value *val;
+ struct frame_info *frame = NULL;
+
+ if (!b)
+ frame = NULL; /* Use selected frame. */
+ else if (symbol_read_needs_frame (var))
+ {
+ frame = block_innermost_frame (b);
+ if (!frame)
+ {
+ if (BLOCK_FUNCTION (b)
+ && SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)))
+ error ("No frame is currently executing in block %s.",
+ SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)));
+ else
+ error ("No frame is currently executing in specified block");
+ }
+ }
+
+ val = read_var_value (var, frame);
+ if (!val)
+ error ("Address of symbol \"%s\" is unknown.", SYMBOL_SOURCE_NAME (var));
+
+ return val;
+}
+
+/* Given a value which is an array, return a value which is a pointer to its
+ first element, regardless of whether or not the array has a nonzero lower
+ bound.
+
+ FIXME: A previous comment here indicated that this routine should be
+ substracting the array's lower bound. It's not clear to me that this
+ is correct. Given an array subscripting operation, it would certainly
+ work to do the adjustment here, essentially computing:
+
+ (&array[0] - (lowerbound * sizeof array[0])) + (index * sizeof array[0])
+
+ However I believe a more appropriate and logical place to account for
+ the lower bound is to do so in value_subscript, essentially computing:
+
+ (&array[0] + ((index - lowerbound) * sizeof array[0]))
+
+ As further evidence consider what would happen with operations other
+ than array subscripting, where the caller would get back a value that
+ had an address somewhere before the actual first element of the array,
+ and the information about the lower bound would be lost because of
+ the coercion to pointer type.
+ */
+
+struct value *
+value_coerce_array (struct value *arg1)
+{
+ register struct type *type = check_typedef (VALUE_TYPE (arg1));
+
+ if (VALUE_LVAL (arg1) != lval_memory)
+ error ("Attempt to take address of value not located in memory.");
+
+ return value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
+ (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1)));
+}
+
+/* Given a value which is a function, return a value which is a pointer
+ to it. */
+
+struct value *
+value_coerce_function (struct value *arg1)
+{
+ struct value *retval;
+
+ if (VALUE_LVAL (arg1) != lval_memory)
+ error ("Attempt to take address of value not located in memory.");
+
+ retval = value_from_pointer (lookup_pointer_type (VALUE_TYPE (arg1)),
+ (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1)));
+ VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (arg1);
+ return retval;
+}
+
+/* Return a pointer value for the object for which ARG1 is the contents. */
+
+struct value *
+value_addr (struct value *arg1)
+{
+ struct value *arg2;
+
+ struct type *type = check_typedef (VALUE_TYPE (arg1));
+ if (TYPE_CODE (type) == TYPE_CODE_REF)
+ {
+ /* Copy the value, but change the type from (T&) to (T*).
+ We keep the same location information, which is efficient,
+ and allows &(&X) to get the location containing the reference. */
+ arg2 = value_copy (arg1);
+ VALUE_TYPE (arg2) = lookup_pointer_type (TYPE_TARGET_TYPE (type));
+ return arg2;
+ }
+ if (TYPE_CODE (type) == TYPE_CODE_FUNC)
+ return value_coerce_function (arg1);
+
+ if (VALUE_LVAL (arg1) != lval_memory)
+ error ("Attempt to take address of value not located in memory.");
+
+ /* Get target memory address */
+ arg2 = value_from_pointer (lookup_pointer_type (VALUE_TYPE (arg1)),
+ (VALUE_ADDRESS (arg1)
+ + VALUE_OFFSET (arg1)
+ + VALUE_EMBEDDED_OFFSET (arg1)));
+
+ /* This may be a pointer to a base subobject; so remember the
+ full derived object's type ... */
+ arg2 = value_change_enclosing_type (arg2, lookup_pointer_type (VALUE_ENCLOSING_TYPE (arg1)));
+ /* ... and also the relative position of the subobject in the full object */
+ VALUE_POINTED_TO_OFFSET (arg2) = VALUE_EMBEDDED_OFFSET (arg1);
+ VALUE_BFD_SECTION (arg2) = VALUE_BFD_SECTION (arg1);
+ return arg2;
+}
+
+/* Given a value of a pointer type, apply the C unary * operator to it. */
+
+struct value *
+value_ind (struct value *arg1)
+{
+ struct type *base_type;
+ struct value *arg2;
+
+ COERCE_ARRAY (arg1);
+
+ base_type = check_typedef (VALUE_TYPE (arg1));
+
+ if (TYPE_CODE (base_type) == TYPE_CODE_MEMBER)
+ error ("not implemented: member types in value_ind");
+
+ /* Allow * on an integer so we can cast it to whatever we want.
+ This returns an int, which seems like the most C-like thing
+ to do. "long long" variables are rare enough that
+ BUILTIN_TYPE_LONGEST would seem to be a mistake. */
+ if (TYPE_CODE (base_type) == TYPE_CODE_INT)
+ return value_at (builtin_type_int,
+ (CORE_ADDR) value_as_long (arg1),
+ VALUE_BFD_SECTION (arg1));
+ else if (TYPE_CODE (base_type) == TYPE_CODE_PTR)
+ {
+ struct type *enc_type;
+ /* We may be pointing to something embedded in a larger object */
+ /* Get the real type of the enclosing object */
+ enc_type = check_typedef (VALUE_ENCLOSING_TYPE (arg1));
+ enc_type = TYPE_TARGET_TYPE (enc_type);
+ /* Retrieve the enclosing object pointed to */
+ arg2 = value_at_lazy (enc_type,
+ value_as_address (arg1) - VALUE_POINTED_TO_OFFSET (arg1),
+ VALUE_BFD_SECTION (arg1));
+ /* Re-adjust type */
+ VALUE_TYPE (arg2) = TYPE_TARGET_TYPE (base_type);
+ /* Add embedding info */
+ arg2 = value_change_enclosing_type (arg2, enc_type);
+ VALUE_EMBEDDED_OFFSET (arg2) = VALUE_POINTED_TO_OFFSET (arg1);
+
+ /* We may be pointing to an object of some derived type */
+ arg2 = value_full_object (arg2, NULL, 0, 0, 0);
+ return arg2;
+ }
+
+ error ("Attempt to take contents of a non-pointer value.");
+ return 0; /* For lint -- never reached */
+}
+
+/* Pushing small parts of stack frames. */
+
+/* Push one word (the size of object that a register holds). */
+
+CORE_ADDR
+push_word (CORE_ADDR sp, ULONGEST word)
+{
+ register int len = REGISTER_SIZE;
+ char *buffer = alloca (MAX_REGISTER_RAW_SIZE);
+
+ store_unsigned_integer (buffer, len, word);
+ if (INNER_THAN (1, 2))
+ {
+ /* stack grows downward */
+ sp -= len;
+ write_memory (sp, buffer, len);
+ }
+ else
+ {
+ /* stack grows upward */
+ write_memory (sp, buffer, len);
+ sp += len;
+ }
+
+ return sp;
+}
+
+/* Push LEN bytes with data at BUFFER. */
+
+CORE_ADDR
+push_bytes (CORE_ADDR sp, char *buffer, int len)
+{
+ if (INNER_THAN (1, 2))
+ {
+ /* stack grows downward */
+ sp -= len;
+ write_memory (sp, buffer, len);
+ }
+ else
+ {
+ /* stack grows upward */
+ write_memory (sp, buffer, len);
+ sp += len;
+ }
+
+ return sp;
+}
+
+#ifndef PARM_BOUNDARY
+#define PARM_BOUNDARY (0)
+#endif
+
+/* Push onto the stack the specified value VALUE. Pad it correctly for
+ it to be an argument to a function. */
+
+static CORE_ADDR
+value_push (register CORE_ADDR sp, struct value *arg)
+{
+ register int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
+ register int container_len = len;
+ register int offset;
+
+ /* How big is the container we're going to put this value in? */
+ if (PARM_BOUNDARY)
+ container_len = ((len + PARM_BOUNDARY / TARGET_CHAR_BIT - 1)
+ & ~(PARM_BOUNDARY / TARGET_CHAR_BIT - 1));
+
+ /* Are we going to put it at the high or low end of the container? */
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ offset = container_len - len;
+ else
+ offset = 0;
+
+ if (INNER_THAN (1, 2))
+ {
+ /* stack grows downward */
+ sp -= container_len;
+ write_memory (sp + offset, VALUE_CONTENTS_ALL (arg), len);
+ }
+ else
+ {
+ /* stack grows upward */
+ write_memory (sp + offset, VALUE_CONTENTS_ALL (arg), len);
+ sp += container_len;
+ }
+
+ return sp;
+}
+
+CORE_ADDR
+default_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ /* ASSERT ( !struct_return); */
+ int i;
+ for (i = nargs - 1; i >= 0; i--)
+ sp = value_push (sp, args[i]);
+ return sp;
+}
+
+
+/* Functions to use for the COERCE_FLOAT_TO_DOUBLE gdbarch method.
+
+ How you should pass arguments to a function depends on whether it
+ was defined in K&R style or prototype style. If you define a
+ function using the K&R syntax that takes a `float' argument, then
+ callers must pass that argument as a `double'. If you define the
+ function using the prototype syntax, then you must pass the
+ argument as a `float', with no promotion.
+
+ Unfortunately, on certain older platforms, the debug info doesn't
+ indicate reliably how each function was defined. A function type's
+ TYPE_FLAG_PROTOTYPED flag may be clear, even if the function was
+ defined in prototype style. When calling a function whose
+ TYPE_FLAG_PROTOTYPED flag is clear, GDB consults the
+ COERCE_FLOAT_TO_DOUBLE gdbarch method to decide what to do.
+
+ For modern targets, it is proper to assume that, if the prototype
+ flag is clear, that can be trusted: `float' arguments should be
+ promoted to `double'. You should register the function
+ `standard_coerce_float_to_double' to get this behavior.
+
+ For some older targets, if the prototype flag is clear, that
+ doesn't tell us anything. So we guess that, if we don't have a
+ type for the formal parameter (i.e., the first argument to
+ COERCE_FLOAT_TO_DOUBLE is null), then we should promote it;
+ otherwise, we should leave it alone. The function
+ `default_coerce_float_to_double' provides this behavior; it is the
+ default value, for compatibility with older configurations. */
+int
+default_coerce_float_to_double (struct type *formal, struct type *actual)
+{
+ return formal == NULL;
+}
+
+
+int
+standard_coerce_float_to_double (struct type *formal, struct type *actual)
+{
+ return 1;
+}
+
+
+/* Perform the standard coercions that are specified
+ for arguments to be passed to C functions.
+
+ If PARAM_TYPE is non-NULL, it is the expected parameter type.
+ IS_PROTOTYPED is non-zero if the function declaration is prototyped. */
+
+static struct value *
+value_arg_coerce (struct value *arg, struct type *param_type,
+ int is_prototyped)
+{
+ register struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+ register struct type *type
+ = param_type ? check_typedef (param_type) : arg_type;
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_REF:
+ if (TYPE_CODE (arg_type) != TYPE_CODE_REF
+ && TYPE_CODE (arg_type) != TYPE_CODE_PTR)
+ {
+ arg = value_addr (arg);
+ VALUE_TYPE (arg) = param_type;
+ return arg;
+ }
+ break;
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_ENUM:
+ /* If we don't have a prototype, coerce to integer type if necessary. */
+ if (!is_prototyped)
+ {
+ if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
+ type = builtin_type_int;
+ }
+ /* Currently all target ABIs require at least the width of an integer
+ type for an argument. We may have to conditionalize the following
+ type coercion for future targets. */
+ if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
+ type = builtin_type_int;
+ break;
+ case TYPE_CODE_FLT:
+ /* FIXME: We should always convert floats to doubles in the
+ non-prototyped case. As many debugging formats include
+ no information about prototyping, we have to live with
+ COERCE_FLOAT_TO_DOUBLE for now. */
+ if (!is_prototyped && COERCE_FLOAT_TO_DOUBLE (param_type, arg_type))
+ {
+ if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
+ type = builtin_type_double;
+ else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double))
+ type = builtin_type_long_double;
+ }
+ break;
+ case TYPE_CODE_FUNC:
+ type = lookup_pointer_type (type);
+ break;
+ case TYPE_CODE_ARRAY:
+ /* Arrays are coerced to pointers to their first element, unless
+ they are vectors, in which case we want to leave them alone,
+ because they are passed by value. */
+ if (current_language->c_style_arrays)
+ if (!TYPE_VECTOR (type))
+ type = lookup_pointer_type (TYPE_TARGET_TYPE (type));
+ break;
+ case TYPE_CODE_UNDEF:
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_SET:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_STRING:
+ case TYPE_CODE_BITSTRING:
+ case TYPE_CODE_ERROR:
+ case TYPE_CODE_MEMBER:
+ case TYPE_CODE_METHOD:
+ case TYPE_CODE_COMPLEX:
+ default:
+ break;
+ }
+
+ return value_cast (type, arg);
+}
+
+/* Determine a function's address and its return type from its value.
+ Calls error() if the function is not valid for calling. */
+
+static CORE_ADDR
+find_function_addr (struct value *function, struct type **retval_type)
+{
+ register struct type *ftype = check_typedef (VALUE_TYPE (function));
+ register enum type_code code = TYPE_CODE (ftype);
+ struct type *value_type;
+ CORE_ADDR funaddr;
+
+ /* If it's a member function, just look at the function
+ part of it. */
+
+ /* Determine address to call. */
+ if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD)
+ {
+ funaddr = VALUE_ADDRESS (function);
+ value_type = TYPE_TARGET_TYPE (ftype);
+ }
+ else if (code == TYPE_CODE_PTR)
+ {
+ funaddr = value_as_address (function);
+ ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
+ if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
+ || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
+ {
+ funaddr = CONVERT_FROM_FUNC_PTR_ADDR (funaddr);
+ value_type = TYPE_TARGET_TYPE (ftype);
+ }
+ else
+ value_type = builtin_type_int;
+ }
+ else if (code == TYPE_CODE_INT)
+ {
+ /* Handle the case of functions lacking debugging info.
+ Their values are characters since their addresses are char */
+ if (TYPE_LENGTH (ftype) == 1)
+ funaddr = value_as_address (value_addr (function));
+ else
+ /* Handle integer used as address of a function. */
+ funaddr = (CORE_ADDR) value_as_long (function);
+
+ value_type = builtin_type_int;
+ }
+ else
+ error ("Invalid data type for function to be called.");
+
+ *retval_type = value_type;
+ return funaddr;
+}
+
+/* All this stuff with a dummy frame may seem unnecessarily complicated
+ (why not just save registers in GDB?). The purpose of pushing a dummy
+ frame which looks just like a real frame is so that if you call a
+ function and then hit a breakpoint (get a signal, etc), "backtrace"
+ will look right. Whether the backtrace needs to actually show the
+ stack at the time the inferior function was called is debatable, but
+ it certainly needs to not display garbage. So if you are contemplating
+ making dummy frames be different from normal frames, consider that. */
+
+/* Perform a function call in the inferior.
+ ARGS is a vector of values of arguments (NARGS of them).
+ FUNCTION is a value, the function to be called.
+ Returns a value representing what the function returned.
+ May fail to return, if a breakpoint or signal is hit
+ during the execution of the function.
+
+ ARGS is modified to contain coerced values. */
+
+static struct value *
+hand_function_call (struct value *function, int nargs, struct value **args)
+{
+ register CORE_ADDR sp;
+ register int i;
+ int rc;
+ CORE_ADDR start_sp;
+ /* CALL_DUMMY is an array of words (REGISTER_SIZE), but each word
+ is in host byte order. Before calling FIX_CALL_DUMMY, we byteswap it
+ and remove any extra bytes which might exist because ULONGEST is
+ bigger than REGISTER_SIZE.
+
+ NOTE: This is pretty wierd, as the call dummy is actually a
+ sequence of instructions. But CISC machines will have
+ to pack the instructions into REGISTER_SIZE units (and
+ so will RISC machines for which INSTRUCTION_SIZE is not
+ REGISTER_SIZE).
+
+ NOTE: This is pretty stupid. CALL_DUMMY should be in strict
+ target byte order. */
+
+ static ULONGEST *dummy;
+ int sizeof_dummy1;
+ char *dummy1;
+ CORE_ADDR old_sp;
+ struct type *value_type;
+ unsigned char struct_return;
+ CORE_ADDR struct_addr = 0;
+ struct inferior_status *inf_status;
+ struct cleanup *old_chain;
+ CORE_ADDR funaddr;
+ int using_gcc; /* Set to version of gcc in use, or zero if not gcc */
+ CORE_ADDR real_pc;
+ struct type *param_type = NULL;
+ struct type *ftype = check_typedef (SYMBOL_TYPE (function));
+ int n_method_args = 0;
+
+ dummy = alloca (SIZEOF_CALL_DUMMY_WORDS);
+ sizeof_dummy1 = REGISTER_SIZE * SIZEOF_CALL_DUMMY_WORDS / sizeof (ULONGEST);
+ dummy1 = alloca (sizeof_dummy1);
+ memcpy (dummy, CALL_DUMMY_WORDS, SIZEOF_CALL_DUMMY_WORDS);
+
+ if (!target_has_execution)
+ noprocess ();
+
+ inf_status = save_inferior_status (1);
+ old_chain = make_cleanup_restore_inferior_status (inf_status);
+
+ /* PUSH_DUMMY_FRAME is responsible for saving the inferior registers
+ (and POP_FRAME for restoring them). (At least on most machines)
+ they are saved on the stack in the inferior. */
+ PUSH_DUMMY_FRAME;
+
+ old_sp = sp = read_sp ();
+
+ if (INNER_THAN (1, 2))
+ {
+ /* Stack grows down */
+ sp -= sizeof_dummy1;
+ start_sp = sp;
+ }
+ else
+ {
+ /* Stack grows up */
+ start_sp = sp;
+ sp += sizeof_dummy1;
+ }
+
+ funaddr = find_function_addr (function, &value_type);
+ CHECK_TYPEDEF (value_type);
+
+ {
+ struct block *b = block_for_pc (funaddr);
+ /* If compiled without -g, assume GCC 2. */
+ using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b));
+ }
+
+ /* Are we returning a value using a structure return or a normal
+ value return? */
+
+ struct_return = using_struct_return (function, funaddr, value_type,
+ using_gcc);
+
+ /* Create a call sequence customized for this function
+ and the number of arguments for it. */
+ for (i = 0; i < (int) (SIZEOF_CALL_DUMMY_WORDS / sizeof (dummy[0])); i++)
+ store_unsigned_integer (&dummy1[i * REGISTER_SIZE],
+ REGISTER_SIZE,
+ (ULONGEST) dummy[i]);
+
+#ifdef GDB_TARGET_IS_HPPA
+ real_pc = FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
+ value_type, using_gcc);
+#else
+ FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
+ value_type, using_gcc);
+ real_pc = start_sp;
+#endif
+
+ if (CALL_DUMMY_LOCATION == ON_STACK)
+ {
+ write_memory (start_sp, (char *) dummy1, sizeof_dummy1);
+ if (USE_GENERIC_DUMMY_FRAMES)
+ generic_save_call_dummy_addr (start_sp, start_sp + sizeof_dummy1);
+ }
+
+ if (CALL_DUMMY_LOCATION == BEFORE_TEXT_END)
+ {
+ /* Convex Unix prohibits executing in the stack segment. */
+ /* Hope there is empty room at the top of the text segment. */
+ extern CORE_ADDR text_end;
+ static int checked = 0;
+ if (!checked)
+ for (start_sp = text_end - sizeof_dummy1; start_sp < text_end; ++start_sp)
+ if (read_memory_integer (start_sp, 1) != 0)
+ error ("text segment full -- no place to put call");
+ checked = 1;
+ sp = old_sp;
+ real_pc = text_end - sizeof_dummy1;
+ write_memory (real_pc, (char *) dummy1, sizeof_dummy1);
+ if (USE_GENERIC_DUMMY_FRAMES)
+ generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1);
+ }
+
+ if (CALL_DUMMY_LOCATION == AFTER_TEXT_END)
+ {
+ extern CORE_ADDR text_end;
+ int errcode;
+ sp = old_sp;
+ real_pc = text_end;
+ errcode = target_write_memory (real_pc, (char *) dummy1, sizeof_dummy1);
+ if (errcode != 0)
+ error ("Cannot write text segment -- call_function failed");
+ if (USE_GENERIC_DUMMY_FRAMES)
+ generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1);
+ }
+
+ if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
+ {
+ real_pc = funaddr;
+ if (USE_GENERIC_DUMMY_FRAMES)
+ /* NOTE: cagney/2002-04-13: The entry point is going to be
+ modified with a single breakpoint. */
+ generic_save_call_dummy_addr (CALL_DUMMY_ADDRESS (),
+ CALL_DUMMY_ADDRESS () + 1);
+ }
+
+#ifdef lint
+ sp = old_sp; /* It really is used, for some ifdef's... */
+#endif
+
+ if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
+ {
+ i = 0;
+ while (TYPE_CODE (TYPE_ARG_TYPES (ftype)[i]) != TYPE_CODE_VOID)
+ i++;
+ n_method_args = i;
+ if (nargs < i)
+ error ("too few arguments in method call");
+ }
+ else if (nargs < TYPE_NFIELDS (ftype))
+ error ("too few arguments in function call");
+
+ for (i = nargs - 1; i >= 0; i--)
+ {
+ /* Assume that methods are always prototyped, unless they are off the
+ end (which we should only be allowing if there is a ``...'').
+ FIXME. */
+ if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
+ {
+ if (i < n_method_args)
+ args[i] = value_arg_coerce (args[i], TYPE_ARG_TYPES (ftype)[i], 1);
+ else
+ args[i] = value_arg_coerce (args[i], NULL, 0);
+ }
+
+ /* If we're off the end of the known arguments, do the standard
+ promotions. FIXME: if we had a prototype, this should only
+ be allowed if ... were present. */
+ if (i >= TYPE_NFIELDS (ftype))
+ args[i] = value_arg_coerce (args[i], NULL, 0);
+
+ else
+ {
+ param_type = TYPE_FIELD_TYPE (ftype, i);
+ args[i] = value_arg_coerce (args[i], param_type, TYPE_PROTOTYPED (ftype));
+ }
+
+ /*elz: this code is to handle the case in which the function to be called
+ has a pointer to function as parameter and the corresponding actual argument
+ is the address of a function and not a pointer to function variable.
+ In aCC compiled code, the calls through pointers to functions (in the body
+ of the function called by hand) are made via $$dyncall_external which
+ requires some registers setting, this is taken care of if we call
+ via a function pointer variable, but not via a function address.
+ In cc this is not a problem. */
+
+ if (using_gcc == 0)
+ if (param_type)
+ /* if this parameter is a pointer to function */
+ if (TYPE_CODE (param_type) == TYPE_CODE_PTR)
+ if (TYPE_CODE (TYPE_TARGET_TYPE (param_type)) == TYPE_CODE_FUNC)
+ /* elz: FIXME here should go the test about the compiler used
+ to compile the target. We want to issue the error
+ message only if the compiler used was HP's aCC.
+ If we used HP's cc, then there is no problem and no need
+ to return at this point */
+ if (using_gcc == 0) /* && compiler == aCC */
+ /* go see if the actual parameter is a variable of type
+ pointer to function or just a function */
+ if (args[i]->lval == not_lval)
+ {
+ char *arg_name;
+ if (find_pc_partial_function ((CORE_ADDR) args[i]->aligner.contents[0], &arg_name, NULL, NULL))
+ error ("\
+You cannot use function <%s> as argument. \n\
+You must use a pointer to function type variable. Command ignored.", arg_name);
+ }
+ }
+
+ if (REG_STRUCT_HAS_ADDR_P ())
+ {
+ /* This is a machine like the sparc, where we may need to pass a
+ pointer to the structure, not the structure itself. */
+ for (i = nargs - 1; i >= 0; i--)
+ {
+ struct type *arg_type = check_typedef (VALUE_TYPE (args[i]));
+ if ((TYPE_CODE (arg_type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (arg_type) == TYPE_CODE_UNION
+ || TYPE_CODE (arg_type) == TYPE_CODE_ARRAY
+ || TYPE_CODE (arg_type) == TYPE_CODE_STRING
+ || TYPE_CODE (arg_type) == TYPE_CODE_BITSTRING
+ || TYPE_CODE (arg_type) == TYPE_CODE_SET
+ || (TYPE_CODE (arg_type) == TYPE_CODE_FLT
+ && TYPE_LENGTH (arg_type) > 8)
+ )
+ && REG_STRUCT_HAS_ADDR (using_gcc, arg_type))
+ {
+ CORE_ADDR addr;
+ int len; /* = TYPE_LENGTH (arg_type); */
+ int aligned_len;
+ arg_type = check_typedef (VALUE_ENCLOSING_TYPE (args[i]));
+ len = TYPE_LENGTH (arg_type);
+
+ if (STACK_ALIGN_P ())
+ /* MVS 11/22/96: I think at least some of this
+ stack_align code is really broken. Better to let
+ PUSH_ARGUMENTS adjust the stack in a target-defined
+ manner. */
+ aligned_len = STACK_ALIGN (len);
+ else
+ aligned_len = len;
+ if (INNER_THAN (1, 2))
+ {
+ /* stack grows downward */
+ sp -= aligned_len;
+ /* ... so the address of the thing we push is the
+ stack pointer after we push it. */
+ addr = sp;
+ }
+ else
+ {
+ /* The stack grows up, so the address of the thing
+ we push is the stack pointer before we push it. */
+ addr = sp;
+ sp += aligned_len;
+ }
+ /* Push the structure. */
+ write_memory (addr, VALUE_CONTENTS_ALL (args[i]), len);
+ /* The value we're going to pass is the address of the
+ thing we just pushed. */
+ /*args[i] = value_from_longest (lookup_pointer_type (value_type),
+ (LONGEST) addr); */
+ args[i] = value_from_pointer (lookup_pointer_type (arg_type),
+ addr);
+ }
+ }
+ }
+
+
+ /* Reserve space for the return structure to be written on the
+ stack, if necessary */
+
+ if (struct_return)
+ {
+ int len = TYPE_LENGTH (value_type);
+ if (STACK_ALIGN_P ())
+ /* MVS 11/22/96: I think at least some of this stack_align
+ code is really broken. Better to let PUSH_ARGUMENTS adjust
+ the stack in a target-defined manner. */
+ len = STACK_ALIGN (len);
+ if (INNER_THAN (1, 2))
+ {
+ /* stack grows downward */
+ sp -= len;
+ struct_addr = sp;
+ }
+ else
+ {
+ /* stack grows upward */
+ struct_addr = sp;
+ sp += len;
+ }
+ }
+
+ /* elz: on HPPA no need for this extra alignment, maybe it is needed
+ on other architectures. This is because all the alignment is
+ taken care of in the above code (ifdef REG_STRUCT_HAS_ADDR) and
+ in hppa_push_arguments */
+ if (EXTRA_STACK_ALIGNMENT_NEEDED)
+ {
+ /* MVS 11/22/96: I think at least some of this stack_align code
+ is really broken. Better to let PUSH_ARGUMENTS adjust the
+ stack in a target-defined manner. */
+ if (STACK_ALIGN_P () && INNER_THAN (1, 2))
+ {
+ /* If stack grows down, we must leave a hole at the top. */
+ int len = 0;
+
+ for (i = nargs - 1; i >= 0; i--)
+ len += TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
+ if (CALL_DUMMY_STACK_ADJUST_P)
+ len += CALL_DUMMY_STACK_ADJUST;
+ sp -= STACK_ALIGN (len) - len;
+ }
+ }
+
+ sp = PUSH_ARGUMENTS (nargs, args, sp, struct_return, struct_addr);
+
+ if (PUSH_RETURN_ADDRESS_P ())
+ /* for targets that use no CALL_DUMMY */
+ /* There are a number of targets now which actually don't write
+ any CALL_DUMMY instructions into the target, but instead just
+ save the machine state, push the arguments, and jump directly
+ to the callee function. Since this doesn't actually involve
+ executing a JSR/BSR instruction, the return address must be set
+ up by hand, either by pushing onto the stack or copying into a
+ return-address register as appropriate. Formerly this has been
+ done in PUSH_ARGUMENTS, but that's overloading its
+ functionality a bit, so I'm making it explicit to do it here. */
+ sp = PUSH_RETURN_ADDRESS (real_pc, sp);
+
+ if (STACK_ALIGN_P () && !INNER_THAN (1, 2))
+ {
+ /* If stack grows up, we must leave a hole at the bottom, note
+ that sp already has been advanced for the arguments! */
+ if (CALL_DUMMY_STACK_ADJUST_P)
+ sp += CALL_DUMMY_STACK_ADJUST;
+ sp = STACK_ALIGN (sp);
+ }
+
+/* XXX This seems wrong. For stacks that grow down we shouldn't do
+ anything here! */
+ /* MVS 11/22/96: I think at least some of this stack_align code is
+ really broken. Better to let PUSH_ARGUMENTS adjust the stack in
+ a target-defined manner. */
+ if (CALL_DUMMY_STACK_ADJUST_P)
+ if (INNER_THAN (1, 2))
+ {
+ /* stack grows downward */
+ sp -= CALL_DUMMY_STACK_ADJUST;
+ }
+
+ /* Store the address at which the structure is supposed to be
+ written. Note that this (and the code which reserved the space
+ above) assumes that gcc was used to compile this function. Since
+ it doesn't cost us anything but space and if the function is pcc
+ it will ignore this value, we will make that assumption.
+
+ Also note that on some machines (like the sparc) pcc uses a
+ convention like gcc's. */
+
+ if (struct_return)
+ STORE_STRUCT_RETURN (struct_addr, sp);
+
+ /* Write the stack pointer. This is here because the statements above
+ might fool with it. On SPARC, this write also stores the register
+ window into the right place in the new stack frame, which otherwise
+ wouldn't happen. (See store_inferior_registers in sparc-nat.c.) */
+ write_sp (sp);
+
+ if (SAVE_DUMMY_FRAME_TOS_P ())
+ SAVE_DUMMY_FRAME_TOS (sp);
+
+ {
+ char *retbuf = (char*) alloca (REGISTER_BYTES);
+ char *name;
+ struct symbol *symbol;
+
+ name = NULL;
+ symbol = find_pc_function (funaddr);
+ if (symbol)
+ {
+ name = SYMBOL_SOURCE_NAME (symbol);
+ }
+ else
+ {
+ /* Try the minimal symbols. */
+ struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (funaddr);
+
+ if (msymbol)
+ {
+ name = SYMBOL_SOURCE_NAME (msymbol);
+ }
+ }
+ if (name == NULL)
+ {
+ char format[80];
+ sprintf (format, "at %s", local_hex_format ());
+ name = alloca (80);
+ /* FIXME-32x64: assumes funaddr fits in a long. */
+ sprintf (name, format, (unsigned long) funaddr);
+ }
+
+ /* Execute the stack dummy routine, calling FUNCTION.
+ When it is done, discard the empty frame
+ after storing the contents of all regs into retbuf. */
+ rc = run_stack_dummy (real_pc + CALL_DUMMY_START_OFFSET, retbuf);
+
+ if (rc == 1)
+ {
+ /* We stopped inside the FUNCTION because of a random signal.
+ Further execution of the FUNCTION is not allowed. */
+
+ if (unwind_on_signal_p)
+ {
+ /* The user wants the context restored. */
+
+ /* We must get back to the frame we were before the dummy call. */
+ POP_FRAME;
+
+ /* FIXME: Insert a bunch of wrap_here; name can be very long if it's
+ a C++ name with arguments and stuff. */
+ error ("\
+The program being debugged was signaled while in a function called from GDB.\n\
+GDB has restored the context to what it was before the call.\n\
+To change this behavior use \"set unwindonsignal off\"\n\
+Evaluation of the expression containing the function (%s) will be abandoned.",
+ name);
+ }
+ else
+ {
+ /* The user wants to stay in the frame where we stopped (default).*/
+
+ /* If we did the cleanups, we would print a spurious error
+ message (Unable to restore previously selected frame),
+ would write the registers from the inf_status (which is
+ wrong), and would do other wrong things. */
+ discard_cleanups (old_chain);
+ discard_inferior_status (inf_status);
+
+ /* FIXME: Insert a bunch of wrap_here; name can be very long if it's
+ a C++ name with arguments and stuff. */
+ error ("\
+The program being debugged was signaled while in a function called from GDB.\n\
+GDB remains in the frame where the signal was received.\n\
+To change this behavior use \"set unwindonsignal on\"\n\
+Evaluation of the expression containing the function (%s) will be abandoned.",
+ name);
+ }
+ }
+
+ if (rc == 2)
+ {
+ /* We hit a breakpoint inside the FUNCTION. */
+
+ /* If we did the cleanups, we would print a spurious error
+ message (Unable to restore previously selected frame),
+ would write the registers from the inf_status (which is
+ wrong), and would do other wrong things. */
+ discard_cleanups (old_chain);
+ discard_inferior_status (inf_status);
+
+ /* The following error message used to say "The expression
+ which contained the function call has been discarded." It
+ is a hard concept to explain in a few words. Ideally, GDB
+ would be able to resume evaluation of the expression when
+ the function finally is done executing. Perhaps someday
+ this will be implemented (it would not be easy). */
+
+ /* FIXME: Insert a bunch of wrap_here; name can be very long if it's
+ a C++ name with arguments and stuff. */
+ error ("\
+The program being debugged stopped while in a function called from GDB.\n\
+When the function (%s) is done executing, GDB will silently\n\
+stop (instead of continuing to evaluate the expression containing\n\
+the function call).", name);
+ }
+
+ /* If we get here the called FUNCTION run to completion. */
+ do_cleanups (old_chain);
+
+ /* Figure out the value returned by the function. */
+/* elz: I defined this new macro for the hppa architecture only.
+ this gives us a way to get the value returned by the function from the stack,
+ at the same address we told the function to put it.
+ We cannot assume on the pa that r28 still contains the address of the returned
+ structure. Usually this will be overwritten by the callee.
+ I don't know about other architectures, so I defined this macro
+ */
+
+#ifdef VALUE_RETURNED_FROM_STACK
+ if (struct_return)
+ return (struct value *) VALUE_RETURNED_FROM_STACK (value_type, struct_addr);
+#endif
+
+ return value_being_returned (value_type, retbuf, struct_return);
+ }
+}
+
+struct value *
+call_function_by_hand (struct value *function, int nargs, struct value **args)
+{
+ if (CALL_DUMMY_P)
+ {
+ return hand_function_call (function, nargs, args);
+ }
+ else
+ {
+ error ("Cannot invoke functions on this machine.");
+ }
+}
+
+
+
+/* Create a value for an array by allocating space in the inferior, copying
+ the data into that space, and then setting up an array value.
+
+ The array bounds are set from LOWBOUND and HIGHBOUND, and the array is
+ populated from the values passed in ELEMVEC.
+
+ The element type of the array is inherited from the type of the
+ first element, and all elements must have the same size (though we
+ don't currently enforce any restriction on their types). */
+
+struct value *
+value_array (int lowbound, int highbound, struct value **elemvec)
+{
+ int nelem;
+ int idx;
+ unsigned int typelength;
+ struct value *val;
+ struct type *rangetype;
+ struct type *arraytype;
+ CORE_ADDR addr;
+
+ /* Validate that the bounds are reasonable and that each of the elements
+ have the same size. */
+
+ nelem = highbound - lowbound + 1;
+ if (nelem <= 0)
+ {
+ error ("bad array bounds (%d, %d)", lowbound, highbound);
+ }
+ typelength = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (elemvec[0]));
+ for (idx = 1; idx < nelem; idx++)
+ {
+ if (TYPE_LENGTH (VALUE_ENCLOSING_TYPE (elemvec[idx])) != typelength)
+ {
+ error ("array elements must all be the same size");
+ }
+ }
+
+ rangetype = create_range_type ((struct type *) NULL, builtin_type_int,
+ lowbound, highbound);
+ arraytype = create_array_type ((struct type *) NULL,
+ VALUE_ENCLOSING_TYPE (elemvec[0]), rangetype);
+
+ if (!current_language->c_style_arrays)
+ {
+ val = allocate_value (arraytype);
+ for (idx = 0; idx < nelem; idx++)
+ {
+ memcpy (VALUE_CONTENTS_ALL_RAW (val) + (idx * typelength),
+ VALUE_CONTENTS_ALL (elemvec[idx]),
+ typelength);
+ }
+ VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (elemvec[0]);
+ return val;
+ }
+
+ /* Allocate space to store the array in the inferior, and then initialize
+ it by copying in each element. FIXME: Is it worth it to create a
+ local buffer in which to collect each value and then write all the
+ bytes in one operation? */
+
+ addr = allocate_space_in_inferior (nelem * typelength);
+ for (idx = 0; idx < nelem; idx++)
+ {
+ write_memory (addr + (idx * typelength), VALUE_CONTENTS_ALL (elemvec[idx]),
+ typelength);
+ }
+
+ /* Create the array type and set up an array value to be evaluated lazily. */
+
+ val = value_at_lazy (arraytype, addr, VALUE_BFD_SECTION (elemvec[0]));
+ return (val);
+}
+
+/* Create a value for a string constant by allocating space in the inferior,
+ copying the data into that space, and returning the address with type
+ TYPE_CODE_STRING. PTR points to the string constant data; LEN is number
+ of characters.
+ Note that string types are like array of char types with a lower bound of
+ zero and an upper bound of LEN - 1. Also note that the string may contain
+ embedded null bytes. */
+
+struct value *
+value_string (char *ptr, int len)
+{
+ struct value *val;
+ int lowbound = current_language->string_lower_bound;
+ struct type *rangetype = create_range_type ((struct type *) NULL,
+ builtin_type_int,
+ lowbound, len + lowbound - 1);
+ struct type *stringtype
+ = create_string_type ((struct type *) NULL, rangetype);
+ CORE_ADDR addr;
+
+ if (current_language->c_style_arrays == 0)
+ {
+ val = allocate_value (stringtype);
+ memcpy (VALUE_CONTENTS_RAW (val), ptr, len);
+ return val;
+ }
+
+
+ /* Allocate space to store the string in the inferior, and then
+ copy LEN bytes from PTR in gdb to that address in the inferior. */
+
+ addr = allocate_space_in_inferior (len);
+ write_memory (addr, ptr, len);
+
+ val = value_at_lazy (stringtype, addr, NULL);
+ return (val);
+}
+
+struct value *
+value_bitstring (char *ptr, int len)
+{
+ struct value *val;
+ struct type *domain_type = create_range_type (NULL, builtin_type_int,
+ 0, len - 1);
+ struct type *type = create_set_type ((struct type *) NULL, domain_type);
+ TYPE_CODE (type) = TYPE_CODE_BITSTRING;
+ val = allocate_value (type);
+ memcpy (VALUE_CONTENTS_RAW (val), ptr, TYPE_LENGTH (type));
+ return val;
+}
+
+/* See if we can pass arguments in T2 to a function which takes arguments
+ of types T1. Both t1 and t2 are NULL-terminated vectors. If some
+ arguments need coercion of some sort, then the coerced values are written
+ into T2. Return value is 0 if the arguments could be matched, or the
+ position at which they differ if not.
+
+ STATICP is nonzero if the T1 argument list came from a
+ static member function.
+
+ For non-static member functions, we ignore the first argument,
+ which is the type of the instance variable. This is because we want
+ to handle calls with objects from derived classes. This is not
+ entirely correct: we should actually check to make sure that a
+ requested operation is type secure, shouldn't we? FIXME. */
+
+static int
+typecmp (int staticp, struct type *t1[], struct value *t2[])
+{
+ int i;
+
+ if (t2 == 0)
+ return 1;
+ if (staticp && t1 == 0)
+ return t2[1] != 0;
+ if (t1 == 0)
+ return 1;
+ if (t1[!staticp] == 0)
+ return 0;
+ if (TYPE_CODE (t1[0]) == TYPE_CODE_VOID)
+ return 0;
+ /* Skip ``this'' argument if applicable. T2 will always include THIS. */
+ if (staticp)
+ t2++;
+ for (i = !staticp; t1[i] && TYPE_CODE (t1[i]) != TYPE_CODE_VOID; i++)
+ {
+ struct type *tt1, *tt2;
+ if (!t2[i])
+ return i + 1;
+ tt1 = check_typedef (t1[i]);
+ tt2 = check_typedef (VALUE_TYPE (t2[i]));
+ if (TYPE_CODE (tt1) == TYPE_CODE_REF
+ /* We should be doing hairy argument matching, as below. */
+ && (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (tt1))) == TYPE_CODE (tt2)))
+ {
+ if (TYPE_CODE (tt2) == TYPE_CODE_ARRAY)
+ t2[i] = value_coerce_array (t2[i]);
+ else
+ t2[i] = value_addr (t2[i]);
+ continue;
+ }
+
+ /* djb - 20000715 - Until the new type structure is in the
+ place, and we can attempt things like implicit conversions,
+ we need to do this so you can take something like a map<const
+ char *>, and properly access map["hello"], because the
+ argument to [] will be a reference to a pointer to a char,
+ and the argument will be a pointer to a char. */
+ while ( TYPE_CODE(tt1) == TYPE_CODE_REF ||
+ TYPE_CODE (tt1) == TYPE_CODE_PTR)
+ {
+ tt1 = check_typedef( TYPE_TARGET_TYPE(tt1) );
+ }
+ while ( TYPE_CODE(tt2) == TYPE_CODE_ARRAY ||
+ TYPE_CODE(tt2) == TYPE_CODE_PTR ||
+ TYPE_CODE(tt2) == TYPE_CODE_REF)
+ {
+ tt2 = check_typedef( TYPE_TARGET_TYPE(tt2) );
+ }
+ if (TYPE_CODE (tt1) == TYPE_CODE (tt2))
+ continue;
+ /* Array to pointer is a `trivial conversion' according to the ARM. */
+
+ /* We should be doing much hairier argument matching (see section 13.2
+ of the ARM), but as a quick kludge, just check for the same type
+ code. */
+ if (TYPE_CODE (t1[i]) != TYPE_CODE (VALUE_TYPE (t2[i])))
+ return i + 1;
+ }
+ if (!t1[i])
+ return 0;
+ return t2[i] ? i + 1 : 0;
+}
+
+/* Helper function used by value_struct_elt to recurse through baseclasses.
+ Look for a field NAME in ARG1. Adjust the address of ARG1 by OFFSET bytes,
+ and search in it assuming it has (class) type TYPE.
+ If found, return value, else return NULL.
+
+ If LOOKING_FOR_BASECLASS, then instead of looking for struct fields,
+ look for a baseclass named NAME. */
+
+static struct value *
+search_struct_field (char *name, struct value *arg1, int offset,
+ register struct type *type, int looking_for_baseclass)
+{
+ int i;
+ int nbases = TYPE_N_BASECLASSES (type);
+
+ CHECK_TYPEDEF (type);
+
+ if (!looking_for_baseclass)
+ for (i = TYPE_NFIELDS (type) - 1; i >= nbases; i--)
+ {
+ char *t_field_name = TYPE_FIELD_NAME (type, i);
+
+ if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
+ {
+ struct value *v;
+ if (TYPE_FIELD_STATIC (type, i))
+ v = value_static_field (type, i);
+ else
+ v = value_primitive_field (arg1, offset, i, type);
+ if (v == 0)
+ error ("there is no field named %s", name);
+ return v;
+ }
+
+ if (t_field_name
+ && (t_field_name[0] == '\0'
+ || (TYPE_CODE (type) == TYPE_CODE_UNION
+ && (strcmp_iw (t_field_name, "else") == 0))))
+ {
+ struct type *field_type = TYPE_FIELD_TYPE (type, i);
+ if (TYPE_CODE (field_type) == TYPE_CODE_UNION
+ || TYPE_CODE (field_type) == TYPE_CODE_STRUCT)
+ {
+ /* Look for a match through the fields of an anonymous union,
+ or anonymous struct. C++ provides anonymous unions.
+
+ In the GNU Chill implementation of variant record types,
+ each <alternative field> has an (anonymous) union type,
+ each member of the union represents a <variant alternative>.
+ Each <variant alternative> is represented as a struct,
+ with a member for each <variant field>. */
+
+ struct value *v;
+ int new_offset = offset;
+
+ /* This is pretty gross. In G++, the offset in an anonymous
+ union is relative to the beginning of the enclosing struct.
+ In the GNU Chill implementation of variant records,
+ the bitpos is zero in an anonymous union field, so we
+ have to add the offset of the union here. */
+ if (TYPE_CODE (field_type) == TYPE_CODE_STRUCT
+ || (TYPE_NFIELDS (field_type) > 0
+ && TYPE_FIELD_BITPOS (field_type, 0) == 0))
+ new_offset += TYPE_FIELD_BITPOS (type, i) / 8;
+
+ v = search_struct_field (name, arg1, new_offset, field_type,
+ looking_for_baseclass);
+ if (v)
+ return v;
+ }
+ }
+ }
+
+ for (i = 0; i < nbases; i++)
+ {
+ struct value *v;
+ struct type *basetype = check_typedef (TYPE_BASECLASS (type, i));
+ /* If we are looking for baseclasses, this is what we get when we
+ hit them. But it could happen that the base part's member name
+ is not yet filled in. */
+ int found_baseclass = (looking_for_baseclass
+ && TYPE_BASECLASS_NAME (type, i) != NULL
+ && (strcmp_iw (name, TYPE_BASECLASS_NAME (type, i)) == 0));
+
+ if (BASETYPE_VIA_VIRTUAL (type, i))
+ {
+ int boffset;
+ struct value *v2 = allocate_value (basetype);
+
+ boffset = baseclass_offset (type, i,
+ VALUE_CONTENTS (arg1) + offset,
+ VALUE_ADDRESS (arg1)
+ + VALUE_OFFSET (arg1) + offset);
+ if (boffset == -1)
+ error ("virtual baseclass botch");
+
+ /* The virtual base class pointer might have been clobbered by the
+ user program. Make sure that it still points to a valid memory
+ location. */
+
+ boffset += offset;
+ if (boffset < 0 || boffset >= TYPE_LENGTH (type))
+ {
+ CORE_ADDR base_addr;
+
+ base_addr = VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1) + boffset;
+ if (target_read_memory (base_addr, VALUE_CONTENTS_RAW (v2),
+ TYPE_LENGTH (basetype)) != 0)
+ error ("virtual baseclass botch");
+ VALUE_LVAL (v2) = lval_memory;
+ VALUE_ADDRESS (v2) = base_addr;
+ }
+ else
+ {
+ VALUE_LVAL (v2) = VALUE_LVAL (arg1);
+ VALUE_ADDRESS (v2) = VALUE_ADDRESS (arg1);
+ VALUE_OFFSET (v2) = VALUE_OFFSET (arg1) + boffset;
+ if (VALUE_LAZY (arg1))
+ VALUE_LAZY (v2) = 1;
+ else
+ memcpy (VALUE_CONTENTS_RAW (v2),
+ VALUE_CONTENTS_RAW (arg1) + boffset,
+ TYPE_LENGTH (basetype));
+ }
+
+ if (found_baseclass)
+ return v2;
+ v = search_struct_field (name, v2, 0, TYPE_BASECLASS (type, i),
+ looking_for_baseclass);
+ }
+ else if (found_baseclass)
+ v = value_primitive_field (arg1, offset, i, type);
+ else
+ v = search_struct_field (name, arg1,
+ offset + TYPE_BASECLASS_BITPOS (type, i) / 8,
+ basetype, looking_for_baseclass);
+ if (v)
+ return v;
+ }
+ return NULL;
+}
+
+
+/* Return the offset (in bytes) of the virtual base of type BASETYPE
+ * in an object pointed to by VALADDR (on the host), assumed to be of
+ * type TYPE. OFFSET is number of bytes beyond start of ARG to start
+ * looking (in case VALADDR is the contents of an enclosing object).
+ *
+ * This routine recurses on the primary base of the derived class because
+ * the virtual base entries of the primary base appear before the other
+ * virtual base entries.
+ *
+ * If the virtual base is not found, a negative integer is returned.
+ * The magnitude of the negative integer is the number of entries in
+ * the virtual table to skip over (entries corresponding to various
+ * ancestral classes in the chain of primary bases).
+ *
+ * Important: This assumes the HP / Taligent C++ runtime
+ * conventions. Use baseclass_offset() instead to deal with g++
+ * conventions. */
+
+void
+find_rt_vbase_offset (struct type *type, struct type *basetype, char *valaddr,
+ int offset, int *boffset_p, int *skip_p)
+{
+ int boffset; /* offset of virtual base */
+ int index; /* displacement to use in virtual table */
+ int skip;
+
+ struct value *vp;
+ CORE_ADDR vtbl; /* the virtual table pointer */
+ struct type *pbc; /* the primary base class */
+
+ /* Look for the virtual base recursively in the primary base, first.
+ * This is because the derived class object and its primary base
+ * subobject share the primary virtual table. */
+
+ boffset = 0;
+ pbc = TYPE_PRIMARY_BASE (type);
+ if (pbc)
+ {
+ find_rt_vbase_offset (pbc, basetype, valaddr, offset, &boffset, &skip);
+ if (skip < 0)
+ {
+ *boffset_p = boffset;
+ *skip_p = -1;
+ return;
+ }
+ }
+ else
+ skip = 0;
+
+
+ /* Find the index of the virtual base according to HP/Taligent
+ runtime spec. (Depth-first, left-to-right.) */
+ index = virtual_base_index_skip_primaries (basetype, type);
+
+ if (index < 0)
+ {
+ *skip_p = skip + virtual_base_list_length_skip_primaries (type);
+ *boffset_p = 0;
+ return;
+ }
+
+ /* pai: FIXME -- 32x64 possible problem */
+ /* First word (4 bytes) in object layout is the vtable pointer */
+ vtbl = *(CORE_ADDR *) (valaddr + offset);
+
+ /* Before the constructor is invoked, things are usually zero'd out. */
+ if (vtbl == 0)
+ error ("Couldn't find virtual table -- object may not be constructed yet.");
+
+
+ /* Find virtual base's offset -- jump over entries for primary base
+ * ancestors, then use the index computed above. But also adjust by
+ * HP_ACC_VBASE_START for the vtable slots before the start of the
+ * virtual base entries. Offset is negative -- virtual base entries
+ * appear _before_ the address point of the virtual table. */
+
+ /* pai: FIXME -- 32x64 problem, if word = 8 bytes, change multiplier
+ & use long type */
+
+ /* epstein : FIXME -- added param for overlay section. May not be correct */
+ vp = value_at (builtin_type_int, vtbl + 4 * (-skip - index - HP_ACC_VBASE_START), NULL);
+ boffset = value_as_long (vp);
+ *skip_p = -1;
+ *boffset_p = boffset;
+ return;
+}
+
+
+/* Helper function used by value_struct_elt to recurse through baseclasses.
+ Look for a field NAME in ARG1. Adjust the address of ARG1 by OFFSET bytes,
+ and search in it assuming it has (class) type TYPE.
+ If found, return value, else if name matched and args not return (value)-1,
+ else return NULL. */
+
+static struct value *
+search_struct_method (char *name, struct value **arg1p,
+ struct value **args, int offset,
+ int *static_memfuncp, register struct type *type)
+{
+ int i;
+ struct value *v;
+ int name_matched = 0;
+ char dem_opname[64];
+
+ CHECK_TYPEDEF (type);
+ for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--)
+ {
+ char *t_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
+ /* FIXME! May need to check for ARM demangling here */
+ if (strncmp (t_field_name, "__", 2) == 0 ||
+ strncmp (t_field_name, "op", 2) == 0 ||
+ strncmp (t_field_name, "type", 4) == 0)
+ {
+ if (cplus_demangle_opname (t_field_name, dem_opname, DMGL_ANSI))
+ t_field_name = dem_opname;
+ else if (cplus_demangle_opname (t_field_name, dem_opname, 0))
+ t_field_name = dem_opname;
+ }
+ if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
+ {
+ int j = TYPE_FN_FIELDLIST_LENGTH (type, i) - 1;
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
+ name_matched = 1;
+
+ if (j > 0 && args == 0)
+ error ("cannot resolve overloaded method `%s': no arguments supplied", name);
+ else if (j == 0 && args == 0)
+ {
+ if (TYPE_FN_FIELD_STUB (f, j))
+ check_stub_method (type, i, j);
+ v = value_fn_field (arg1p, f, j, type, offset);
+ if (v != NULL)
+ return v;
+ }
+ else
+ while (j >= 0)
+ {
+ if (TYPE_FN_FIELD_STUB (f, j))
+ check_stub_method (type, i, j);
+ if (!typecmp (TYPE_FN_FIELD_STATIC_P (f, j),
+ TYPE_FN_FIELD_ARGS (f, j), args))
+ {
+ if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
+ return value_virtual_fn_field (arg1p, f, j, type, offset);
+ if (TYPE_FN_FIELD_STATIC_P (f, j) && static_memfuncp)
+ *static_memfuncp = 1;
+ v = value_fn_field (arg1p, f, j, type, offset);
+ if (v != NULL)
+ return v;
+ }
+ j--;
+ }
+ }
+ }
+
+ for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
+ {
+ int base_offset;
+
+ if (BASETYPE_VIA_VIRTUAL (type, i))
+ {
+ if (TYPE_HAS_VTABLE (type))
+ {
+ /* HP aCC compiled type, search for virtual base offset
+ according to HP/Taligent runtime spec. */
+ int skip;
+ find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
+ VALUE_CONTENTS_ALL (*arg1p),
+ offset + VALUE_EMBEDDED_OFFSET (*arg1p),
+ &base_offset, &skip);
+ if (skip >= 0)
+ error ("Virtual base class offset not found in vtable");
+ }
+ else
+ {
+ struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
+ char *base_valaddr;
+
+ /* The virtual base class pointer might have been clobbered by the
+ user program. Make sure that it still points to a valid memory
+ location. */
+
+ if (offset < 0 || offset >= TYPE_LENGTH (type))
+ {
+ base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
+ if (target_read_memory (VALUE_ADDRESS (*arg1p)
+ + VALUE_OFFSET (*arg1p) + offset,
+ base_valaddr,
+ TYPE_LENGTH (baseclass)) != 0)
+ error ("virtual baseclass botch");
+ }
+ else
+ base_valaddr = VALUE_CONTENTS (*arg1p) + offset;
+
+ base_offset =
+ baseclass_offset (type, i, base_valaddr,
+ VALUE_ADDRESS (*arg1p)
+ + VALUE_OFFSET (*arg1p) + offset);
+ if (base_offset == -1)
+ error ("virtual baseclass botch");
+ }
+ }
+ else
+ {
+ base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8;
+ }
+ v = search_struct_method (name, arg1p, args, base_offset + offset,
+ static_memfuncp, TYPE_BASECLASS (type, i));
+ if (v == (struct value *) - 1)
+ {
+ name_matched = 1;
+ }
+ else if (v)
+ {
+/* FIXME-bothner: Why is this commented out? Why is it here? */
+/* *arg1p = arg1_tmp; */
+ return v;
+ }
+ }
+ if (name_matched)
+ return (struct value *) - 1;
+ else
+ return NULL;
+}
+
+/* Given *ARGP, a value of type (pointer to a)* structure/union,
+ extract the component named NAME from the ultimate target structure/union
+ and return it as a value with its appropriate type.
+ ERR is used in the error message if *ARGP's type is wrong.
+
+ C++: ARGS is a list of argument types to aid in the selection of
+ an appropriate method. Also, handle derived types.
+
+ STATIC_MEMFUNCP, if non-NULL, points to a caller-supplied location
+ where the truthvalue of whether the function that was resolved was
+ a static member function or not is stored.
+
+ ERR is an error message to be printed in case the field is not found. */
+
+struct value *
+value_struct_elt (struct value **argp, struct value **args,
+ char *name, int *static_memfuncp, char *err)
+{
+ register struct type *t;
+ struct value *v;
+
+ COERCE_ARRAY (*argp);
+
+ t = check_typedef (VALUE_TYPE (*argp));
+
+ /* Follow pointers until we get to a non-pointer. */
+
+ while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+ {
+ *argp = value_ind (*argp);
+ /* Don't coerce fn pointer to fn and then back again! */
+ if (TYPE_CODE (VALUE_TYPE (*argp)) != TYPE_CODE_FUNC)
+ COERCE_ARRAY (*argp);
+ t = check_typedef (VALUE_TYPE (*argp));
+ }
+
+ if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
+ error ("not implemented: member type in value_struct_elt");
+
+ if (TYPE_CODE (t) != TYPE_CODE_STRUCT
+ && TYPE_CODE (t) != TYPE_CODE_UNION)
+ error ("Attempt to extract a component of a value that is not a %s.", err);
+
+ /* Assume it's not, unless we see that it is. */
+ if (static_memfuncp)
+ *static_memfuncp = 0;
+
+ if (!args)
+ {
+ /* if there are no arguments ...do this... */
+
+ /* Try as a field first, because if we succeed, there
+ is less work to be done. */
+ v = search_struct_field (name, *argp, 0, t, 0);
+ if (v)
+ return v;
+
+ /* C++: If it was not found as a data field, then try to
+ return it as a pointer to a method. */
+
+ if (destructor_name_p (name, t))
+ error ("Cannot get value of destructor");
+
+ v = search_struct_method (name, argp, args, 0, static_memfuncp, t);
+
+ if (v == (struct value *) - 1)
+ error ("Cannot take address of a method");
+ else if (v == 0)
+ {
+ if (TYPE_NFN_FIELDS (t))
+ error ("There is no member or method named %s.", name);
+ else
+ error ("There is no member named %s.", name);
+ }
+ return v;
+ }
+
+ if (destructor_name_p (name, t))
+ {
+ if (!args[1])
+ {
+ /* Destructors are a special case. */
+ int m_index, f_index;
+
+ v = NULL;
+ if (get_destructor_fn_field (t, &m_index, &f_index))
+ {
+ v = value_fn_field (NULL, TYPE_FN_FIELDLIST1 (t, m_index),
+ f_index, NULL, 0);
+ }
+ if (v == NULL)
+ error ("could not find destructor function named %s.", name);
+ else
+ return v;
+ }
+ else
+ {
+ error ("destructor should not have any argument");
+ }
+ }
+ else
+ v = search_struct_method (name, argp, args, 0, static_memfuncp, t);
+
+ if (v == (struct value *) - 1)
+ {
+ error ("One of the arguments you tried to pass to %s could not be converted to what the function wants.", name);
+ }
+ else if (v == 0)
+ {
+ /* See if user tried to invoke data as function. If so,
+ hand it back. If it's not callable (i.e., a pointer to function),
+ gdb should give an error. */
+ v = search_struct_field (name, *argp, 0, t, 0);
+ }
+
+ if (!v)
+ error ("Structure has no component named %s.", name);
+ return v;
+}
+
+/* Search through the methods of an object (and its bases)
+ * to find a specified method. Return the pointer to the
+ * fn_field list of overloaded instances.
+ * Helper function for value_find_oload_list.
+ * ARGP is a pointer to a pointer to a value (the object)
+ * METHOD is a string containing the method name
+ * OFFSET is the offset within the value
+ * STATIC_MEMFUNCP is set if the method is static
+ * TYPE is the assumed type of the object
+ * NUM_FNS is the number of overloaded instances
+ * BASETYPE is set to the actual type of the subobject where the method is found
+ * BOFFSET is the offset of the base subobject where the method is found */
+
+static struct fn_field *
+find_method_list (struct value **argp, char *method, int offset,
+ struct type *type, int *num_fns,
+ struct type **basetype, int *boffset)
+{
+ int i;
+ struct fn_field *f;
+ CHECK_TYPEDEF (type);
+
+ *num_fns = 0;
+
+ /* First check in object itself */
+ for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--)
+ {
+ /* pai: FIXME What about operators and type conversions? */
+ char *fn_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
+ if (fn_field_name && (strcmp_iw (fn_field_name, method) == 0))
+ {
+ /* Resolve any stub methods. */
+ int len = TYPE_FN_FIELDLIST_LENGTH (type, i);
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
+ int j;
+
+ *num_fns = len;
+ *basetype = type;
+ *boffset = offset;
+
+ for (j = 0; j < len; j++)
+ {
+ if (TYPE_FN_FIELD_STUB (f, j))
+ check_stub_method (type, i, j);
+ }
+
+ return f;
+ }
+ }
+
+ /* Not found in object, check in base subobjects */
+ for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
+ {
+ int base_offset;
+ if (BASETYPE_VIA_VIRTUAL (type, i))
+ {
+ if (TYPE_HAS_VTABLE (type))
+ {
+ /* HP aCC compiled type, search for virtual base offset
+ * according to HP/Taligent runtime spec. */
+ int skip;
+ find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
+ VALUE_CONTENTS_ALL (*argp),
+ offset + VALUE_EMBEDDED_OFFSET (*argp),
+ &base_offset, &skip);
+ if (skip >= 0)
+ error ("Virtual base class offset not found in vtable");
+ }
+ else
+ {
+ /* probably g++ runtime model */
+ base_offset = VALUE_OFFSET (*argp) + offset;
+ base_offset =
+ baseclass_offset (type, i,
+ VALUE_CONTENTS (*argp) + base_offset,
+ VALUE_ADDRESS (*argp) + base_offset);
+ if (base_offset == -1)
+ error ("virtual baseclass botch");
+ }
+ }
+ else
+ /* non-virtual base, simply use bit position from debug info */
+ {
+ base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8;
+ }
+ f = find_method_list (argp, method, base_offset + offset,
+ TYPE_BASECLASS (type, i), num_fns, basetype,
+ boffset);
+ if (f)
+ return f;
+ }
+ return NULL;
+}
+
+/* Return the list of overloaded methods of a specified name.
+ * ARGP is a pointer to a pointer to a value (the object)
+ * METHOD is the method name
+ * OFFSET is the offset within the value contents
+ * STATIC_MEMFUNCP is set if the method is static
+ * NUM_FNS is the number of overloaded instances
+ * BASETYPE is set to the type of the base subobject that defines the method
+ * BOFFSET is the offset of the base subobject which defines the method */
+
+struct fn_field *
+value_find_oload_method_list (struct value **argp, char *method, int offset,
+ int *num_fns, struct type **basetype,
+ int *boffset)
+{
+ struct type *t;
+
+ t = check_typedef (VALUE_TYPE (*argp));
+
+ /* code snarfed from value_struct_elt */
+ while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+ {
+ *argp = value_ind (*argp);
+ /* Don't coerce fn pointer to fn and then back again! */
+ if (TYPE_CODE (VALUE_TYPE (*argp)) != TYPE_CODE_FUNC)
+ COERCE_ARRAY (*argp);
+ t = check_typedef (VALUE_TYPE (*argp));
+ }
+
+ if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
+ error ("Not implemented: member type in value_find_oload_lis");
+
+ if (TYPE_CODE (t) != TYPE_CODE_STRUCT
+ && TYPE_CODE (t) != TYPE_CODE_UNION)
+ error ("Attempt to extract a component of a value that is not a struct or union");
+
+ return find_method_list (argp, method, 0, t, num_fns, basetype, boffset);
+}
+
+/* Given an array of argument types (ARGTYPES) (which includes an
+ entry for "this" in the case of C++ methods), the number of
+ arguments NARGS, the NAME of a function whether it's a method or
+ not (METHOD), and the degree of laxness (LAX) in conforming to
+ overload resolution rules in ANSI C++, find the best function that
+ matches on the argument types according to the overload resolution
+ rules.
+
+ In the case of class methods, the parameter OBJ is an object value
+ in which to search for overloaded methods.
+
+ In the case of non-method functions, the parameter FSYM is a symbol
+ corresponding to one of the overloaded functions.
+
+ Return value is an integer: 0 -> good match, 10 -> debugger applied
+ non-standard coercions, 100 -> incompatible.
+
+ If a method is being searched for, VALP will hold the value.
+ If a non-method is being searched for, SYMP will hold the symbol for it.
+
+ If a method is being searched for, and it is a static method,
+ then STATICP will point to a non-zero value.
+
+ Note: This function does *not* check the value of
+ overload_resolution. Caller must check it to see whether overload
+ resolution is permitted.
+ */
+
+int
+find_overload_match (struct type **arg_types, int nargs, char *name, int method,
+ int lax, struct value **objp, struct symbol *fsym,
+ struct value **valp, struct symbol **symp, int *staticp)
+{
+ int nparms;
+ struct type **parm_types;
+ int champ_nparms = 0;
+ struct value *obj = (objp ? *objp : NULL);
+
+ short oload_champ = -1; /* Index of best overloaded function */
+ short oload_ambiguous = 0; /* Current ambiguity state for overload resolution */
+ /* 0 => no ambiguity, 1 => two good funcs, 2 => incomparable funcs */
+ short oload_ambig_champ = -1; /* 2nd contender for best match */
+ short oload_non_standard = 0; /* did we have to use non-standard conversions? */
+ short oload_incompatible = 0; /* are args supplied incompatible with any function? */
+
+ struct badness_vector *bv; /* A measure of how good an overloaded instance is */
+ struct badness_vector *oload_champ_bv = NULL; /* The measure for the current best match */
+
+ struct value *temp = obj;
+ struct fn_field *fns_ptr = NULL; /* For methods, the list of overloaded methods */
+ struct symbol **oload_syms = NULL; /* For non-methods, the list of overloaded function symbols */
+ int num_fns = 0; /* Number of overloaded instances being considered */
+ struct type *basetype = NULL;
+ int boffset;
+ register int jj;
+ register int ix;
+ int static_offset;
+
+ char *obj_type_name = NULL;
+ char *func_name = NULL;
+
+ /* Get the list of overloaded methods or functions */
+ if (method)
+ {
+ obj_type_name = TYPE_NAME (VALUE_TYPE (obj));
+ /* Hack: evaluate_subexp_standard often passes in a pointer
+ value rather than the object itself, so try again */
+ if ((!obj_type_name || !*obj_type_name) &&
+ (TYPE_CODE (VALUE_TYPE (obj)) == TYPE_CODE_PTR))
+ obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (VALUE_TYPE (obj)));
+
+ fns_ptr = value_find_oload_method_list (&temp, name, 0,
+ &num_fns,
+ &basetype, &boffset);
+ if (!fns_ptr || !num_fns)
+ error ("Couldn't find method %s%s%s",
+ obj_type_name,
+ (obj_type_name && *obj_type_name) ? "::" : "",
+ name);
+ /* If we are dealing with stub method types, they should have
+ been resolved by find_method_list via value_find_oload_method_list
+ above. */
+ gdb_assert (TYPE_DOMAIN_TYPE (fns_ptr[0].type) != NULL);
+ }
+ else
+ {
+ int i = -1;
+ func_name = cplus_demangle (SYMBOL_NAME (fsym), DMGL_NO_OPTS);
+
+ /* If the name is NULL this must be a C-style function.
+ Just return the same symbol. */
+ if (!func_name)
+ {
+ *symp = fsym;
+ return 0;
+ }
+
+ oload_syms = make_symbol_overload_list (fsym);
+ while (oload_syms[++i])
+ num_fns++;
+ if (!num_fns)
+ error ("Couldn't find function %s", func_name);
+ }
+
+ oload_champ_bv = NULL;
+
+ /* Consider each candidate in turn */
+ for (ix = 0; ix < num_fns; ix++)
+ {
+ static_offset = 0;
+ if (method)
+ {
+ if (TYPE_FN_FIELD_STATIC_P (fns_ptr, ix))
+ static_offset = 1;
+ nparms=0;
+
+ if (TYPE_FN_FIELD_ARGS(fns_ptr,ix))
+ {
+ while (TYPE_CODE(TYPE_FN_FIELD_ARGS(fns_ptr,ix)[nparms]) != TYPE_CODE_VOID)
+ nparms++;
+ }
+ }
+ else
+ {
+ /* If it's not a method, this is the proper place */
+ nparms=TYPE_NFIELDS(SYMBOL_TYPE(oload_syms[ix]));
+ }
+
+ /* Prepare array of parameter types */
+ parm_types = (struct type **) xmalloc (nparms * (sizeof (struct type *)));
+ for (jj = 0; jj < nparms; jj++)
+ parm_types[jj] = (method
+ ? (TYPE_FN_FIELD_ARGS (fns_ptr, ix)[jj])
+ : TYPE_FIELD_TYPE (SYMBOL_TYPE (oload_syms[ix]), jj));
+
+ /* Compare parameter types to supplied argument types. Skip THIS for
+ static methods. */
+ bv = rank_function (parm_types, nparms, arg_types + static_offset,
+ nargs - static_offset);
+
+ if (!oload_champ_bv)
+ {
+ oload_champ_bv = bv;
+ oload_champ = 0;
+ champ_nparms = nparms;
+ }
+ else
+ /* See whether current candidate is better or worse than previous best */
+ switch (compare_badness (bv, oload_champ_bv))
+ {
+ case 0:
+ oload_ambiguous = 1; /* top two contenders are equally good */
+ oload_ambig_champ = ix;
+ break;
+ case 1:
+ oload_ambiguous = 2; /* incomparable top contenders */
+ oload_ambig_champ = ix;
+ break;
+ case 2:
+ oload_champ_bv = bv; /* new champion, record details */
+ oload_ambiguous = 0;
+ oload_champ = ix;
+ oload_ambig_champ = -1;
+ champ_nparms = nparms;
+ break;
+ case 3:
+ default:
+ break;
+ }
+ xfree (parm_types);
+ if (overload_debug)
+ {
+ if (method)
+ fprintf_filtered (gdb_stderr,"Overloaded method instance %s, # of parms %d\n", fns_ptr[ix].physname, nparms);
+ else
+ fprintf_filtered (gdb_stderr,"Overloaded function instance %s # of parms %d\n", SYMBOL_DEMANGLED_NAME (oload_syms[ix]), nparms);
+ for (jj = 0; jj < nargs - static_offset; jj++)
+ fprintf_filtered (gdb_stderr,"...Badness @ %d : %d\n", jj, bv->rank[jj]);
+ fprintf_filtered (gdb_stderr,"Overload resolution champion is %d, ambiguous? %d\n", oload_champ, oload_ambiguous);
+ }
+ } /* end loop over all candidates */
+ /* NOTE: dan/2000-03-10: Seems to be a better idea to just pick one
+ if they have the exact same goodness. This is because there is no
+ way to differentiate based on return type, which we need to in
+ cases like overloads of .begin() <It's both const and non-const> */
+#if 0
+ if (oload_ambiguous)
+ {
+ if (method)
+ error ("Cannot resolve overloaded method %s%s%s to unique instance; disambiguate by specifying function signature",
+ obj_type_name,
+ (obj_type_name && *obj_type_name) ? "::" : "",
+ name);
+ else
+ error ("Cannot resolve overloaded function %s to unique instance; disambiguate by specifying function signature",
+ func_name);
+ }
+#endif
+
+ /* Check how bad the best match is. */
+ static_offset = 0;
+ if (method && TYPE_FN_FIELD_STATIC_P (fns_ptr, oload_champ))
+ static_offset = 1;
+ for (ix = 1; ix <= nargs - static_offset; ix++)
+ {
+ if (oload_champ_bv->rank[ix] >= 100)
+ oload_incompatible = 1; /* truly mismatched types */
+
+ else if (oload_champ_bv->rank[ix] >= 10)
+ oload_non_standard = 1; /* non-standard type conversions needed */
+ }
+ if (oload_incompatible)
+ {
+ if (method)
+ error ("Cannot resolve method %s%s%s to any overloaded instance",
+ obj_type_name,
+ (obj_type_name && *obj_type_name) ? "::" : "",
+ name);
+ else
+ error ("Cannot resolve function %s to any overloaded instance",
+ func_name);
+ }
+ else if (oload_non_standard)
+ {
+ if (method)
+ warning ("Using non-standard conversion to match method %s%s%s to supplied arguments",
+ obj_type_name,
+ (obj_type_name && *obj_type_name) ? "::" : "",
+ name);
+ else
+ warning ("Using non-standard conversion to match function %s to supplied arguments",
+ func_name);
+ }
+
+ if (method)
+ {
+ if (staticp && TYPE_FN_FIELD_STATIC_P (fns_ptr, oload_champ))
+ *staticp = 1;
+ else if (staticp)
+ *staticp = 0;
+ if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, oload_champ))
+ *valp = value_virtual_fn_field (&temp, fns_ptr, oload_champ, basetype, boffset);
+ else
+ *valp = value_fn_field (&temp, fns_ptr, oload_champ, basetype, boffset);
+ }
+ else
+ {
+ *symp = oload_syms[oload_champ];
+ xfree (func_name);
+ }
+
+ if (objp)
+ {
+ if (TYPE_CODE (VALUE_TYPE (temp)) != TYPE_CODE_PTR
+ && TYPE_CODE (VALUE_TYPE (*objp)) == TYPE_CODE_PTR)
+ {
+ temp = value_addr (temp);
+ }
+ *objp = temp;
+ }
+ return oload_incompatible ? 100 : (oload_non_standard ? 10 : 0);
+}
+
+/* C++: return 1 is NAME is a legitimate name for the destructor
+ of type TYPE. If TYPE does not have a destructor, or
+ if NAME is inappropriate for TYPE, an error is signaled. */
+int
+destructor_name_p (const char *name, const struct type *type)
+{
+ /* destructors are a special case. */
+
+ if (name[0] == '~')
+ {
+ char *dname = type_name_no_tag (type);
+ char *cp = strchr (dname, '<');
+ unsigned int len;
+
+ /* Do not compare the template part for template classes. */
+ if (cp == NULL)
+ len = strlen (dname);
+ else
+ len = cp - dname;
+ if (strlen (name + 1) != len || !STREQN (dname, name + 1, len))
+ error ("name of destructor must equal name of class");
+ else
+ return 1;
+ }
+ return 0;
+}
+
+/* Helper function for check_field: Given TYPE, a structure/union,
+ return 1 if the component named NAME from the ultimate
+ target structure/union is defined, otherwise, return 0. */
+
+static int
+check_field_in (register struct type *type, const char *name)
+{
+ register int i;
+
+ for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
+ {
+ char *t_field_name = TYPE_FIELD_NAME (type, i);
+ if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
+ return 1;
+ }
+
+ /* C++: If it was not found as a data field, then try to
+ return it as a pointer to a method. */
+
+ /* Destructors are a special case. */
+ if (destructor_name_p (name, type))
+ {
+ int m_index, f_index;
+
+ return get_destructor_fn_field (type, &m_index, &f_index);
+ }
+
+ for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i)
+ {
+ if (strcmp_iw (TYPE_FN_FIELDLIST_NAME (type, i), name) == 0)
+ return 1;
+ }
+
+ for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
+ if (check_field_in (TYPE_BASECLASS (type, i), name))
+ return 1;
+
+ return 0;
+}
+
+
+/* C++: Given ARG1, a value of type (pointer to a)* structure/union,
+ return 1 if the component named NAME from the ultimate
+ target structure/union is defined, otherwise, return 0. */
+
+int
+check_field (struct value *arg1, const char *name)
+{
+ register struct type *t;
+
+ COERCE_ARRAY (arg1);
+
+ t = VALUE_TYPE (arg1);
+
+ /* Follow pointers until we get to a non-pointer. */
+
+ for (;;)
+ {
+ CHECK_TYPEDEF (t);
+ if (TYPE_CODE (t) != TYPE_CODE_PTR && TYPE_CODE (t) != TYPE_CODE_REF)
+ break;
+ t = TYPE_TARGET_TYPE (t);
+ }
+
+ if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
+ error ("not implemented: member type in check_field");
+
+ if (TYPE_CODE (t) != TYPE_CODE_STRUCT
+ && TYPE_CODE (t) != TYPE_CODE_UNION)
+ error ("Internal error: `this' is not an aggregate");
+
+ return check_field_in (t, name);
+}
+
+/* C++: Given an aggregate type CURTYPE, and a member name NAME,
+ return the address of this member as a "pointer to member"
+ type. If INTYPE is non-null, then it will be the type
+ of the member we are looking for. This will help us resolve
+ "pointers to member functions". This function is used
+ to resolve user expressions of the form "DOMAIN::NAME". */
+
+struct value *
+value_struct_elt_for_reference (struct type *domain, int offset,
+ struct type *curtype, char *name,
+ struct type *intype)
+{
+ register struct type *t = curtype;
+ register int i;
+ struct value *v;
+
+ if (TYPE_CODE (t) != TYPE_CODE_STRUCT
+ && TYPE_CODE (t) != TYPE_CODE_UNION)
+ error ("Internal error: non-aggregate type to value_struct_elt_for_reference");
+
+ for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--)
+ {
+ char *t_field_name = TYPE_FIELD_NAME (t, i);
+
+ if (t_field_name && STREQ (t_field_name, name))
+ {
+ if (TYPE_FIELD_STATIC (t, i))
+ {
+ v = value_static_field (t, i);
+ if (v == NULL)
+ error ("Internal error: could not find static variable %s",
+ name);
+ return v;
+ }
+ if (TYPE_FIELD_PACKED (t, i))
+ error ("pointers to bitfield members not allowed");
+
+ return value_from_longest
+ (lookup_reference_type (lookup_member_type (TYPE_FIELD_TYPE (t, i),
+ domain)),
+ offset + (LONGEST) (TYPE_FIELD_BITPOS (t, i) >> 3));
+ }
+ }
+
+ /* C++: If it was not found as a data field, then try to
+ return it as a pointer to a method. */
+
+ /* Destructors are a special case. */
+ if (destructor_name_p (name, t))
+ {
+ error ("member pointers to destructors not implemented yet");
+ }
+
+ /* Perform all necessary dereferencing. */
+ while (intype && TYPE_CODE (intype) == TYPE_CODE_PTR)
+ intype = TYPE_TARGET_TYPE (intype);
+
+ for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i)
+ {
+ char *t_field_name = TYPE_FN_FIELDLIST_NAME (t, i);
+ char dem_opname[64];
+
+ if (strncmp (t_field_name, "__", 2) == 0 ||
+ strncmp (t_field_name, "op", 2) == 0 ||
+ strncmp (t_field_name, "type", 4) == 0)
+ {
+ if (cplus_demangle_opname (t_field_name, dem_opname, DMGL_ANSI))
+ t_field_name = dem_opname;
+ else if (cplus_demangle_opname (t_field_name, dem_opname, 0))
+ t_field_name = dem_opname;
+ }
+ if (t_field_name && STREQ (t_field_name, name))
+ {
+ int j = TYPE_FN_FIELDLIST_LENGTH (t, i);
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
+
+ if (intype == 0 && j > 1)
+ error ("non-unique member `%s' requires type instantiation", name);
+ if (intype)
+ {
+ while (j--)
+ if (TYPE_FN_FIELD_TYPE (f, j) == intype)
+ break;
+ if (j < 0)
+ error ("no member function matches that type instantiation");
+ }
+ else
+ j = 0;
+
+ if (TYPE_FN_FIELD_STUB (f, j))
+ check_stub_method (t, i, j);
+ if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
+ {
+ return value_from_longest
+ (lookup_reference_type
+ (lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
+ domain)),
+ (LONGEST) METHOD_PTR_FROM_VOFFSET (TYPE_FN_FIELD_VOFFSET (f, j)));
+ }
+ else
+ {
+ struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
+ 0, VAR_NAMESPACE, 0, NULL);
+ if (s == NULL)
+ {
+ v = 0;
+ }
+ else
+ {
+ v = read_var_value (s, 0);
+#if 0
+ VALUE_TYPE (v) = lookup_reference_type
+ (lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
+ domain));
+#endif
+ }
+ return v;
+ }
+ }
+ }
+ for (i = TYPE_N_BASECLASSES (t) - 1; i >= 0; i--)
+ {
+ struct value *v;
+ int base_offset;
+
+ if (BASETYPE_VIA_VIRTUAL (t, i))
+ base_offset = 0;
+ else
+ base_offset = TYPE_BASECLASS_BITPOS (t, i) / 8;
+ v = value_struct_elt_for_reference (domain,
+ offset + base_offset,
+ TYPE_BASECLASS (t, i),
+ name,
+ intype);
+ if (v)
+ return v;
+ }
+ return 0;
+}
+
+
+/* Given a pointer value V, find the real (RTTI) type
+ of the object it points to.
+ Other parameters FULL, TOP, USING_ENC as with value_rtti_type()
+ and refer to the values computed for the object pointed to. */
+
+struct type *
+value_rtti_target_type (struct value *v, int *full, int *top, int *using_enc)
+{
+ struct value *target;
+
+ target = value_ind (v);
+
+ return value_rtti_type (target, full, top, using_enc);
+}
+
+/* Given a value pointed to by ARGP, check its real run-time type, and
+ if that is different from the enclosing type, create a new value
+ using the real run-time type as the enclosing type (and of the same
+ type as ARGP) and return it, with the embedded offset adjusted to
+ be the correct offset to the enclosed object
+ RTYPE is the type, and XFULL, XTOP, and XUSING_ENC are the other
+ parameters, computed by value_rtti_type(). If these are available,
+ they can be supplied and a second call to value_rtti_type() is avoided.
+ (Pass RTYPE == NULL if they're not available */
+
+struct value *
+value_full_object (struct value *argp, struct type *rtype, int xfull, int xtop,
+ int xusing_enc)
+{
+ struct type *real_type;
+ int full = 0;
+ int top = -1;
+ int using_enc = 0;
+ struct value *new_val;
+
+ if (rtype)
+ {
+ real_type = rtype;
+ full = xfull;
+ top = xtop;
+ using_enc = xusing_enc;
+ }
+ else
+ real_type = value_rtti_type (argp, &full, &top, &using_enc);
+
+ /* If no RTTI data, or if object is already complete, do nothing */
+ if (!real_type || real_type == VALUE_ENCLOSING_TYPE (argp))
+ return argp;
+
+ /* If we have the full object, but for some reason the enclosing
+ type is wrong, set it *//* pai: FIXME -- sounds iffy */
+ if (full)
+ {
+ argp = value_change_enclosing_type (argp, real_type);
+ return argp;
+ }
+
+ /* Check if object is in memory */
+ if (VALUE_LVAL (argp) != lval_memory)
+ {
+ warning ("Couldn't retrieve complete object of RTTI type %s; object may be in register(s).", TYPE_NAME (real_type));
+
+ return argp;
+ }
+
+ /* All other cases -- retrieve the complete object */
+ /* Go back by the computed top_offset from the beginning of the object,
+ adjusting for the embedded offset of argp if that's what value_rtti_type
+ used for its computation. */
+ new_val = value_at_lazy (real_type, VALUE_ADDRESS (argp) - top +
+ (using_enc ? 0 : VALUE_EMBEDDED_OFFSET (argp)),
+ VALUE_BFD_SECTION (argp));
+ VALUE_TYPE (new_val) = VALUE_TYPE (argp);
+ VALUE_EMBEDDED_OFFSET (new_val) = using_enc ? top + VALUE_EMBEDDED_OFFSET (argp) : top;
+ return new_val;
+}
+
+
+
+
+/* C++: return the value of the class instance variable, if one exists.
+ Flag COMPLAIN signals an error if the request is made in an
+ inappropriate context. */
+
+struct value *
+value_of_this (int complain)
+{
+ struct symbol *func, *sym;
+ struct block *b;
+ int i;
+ static const char funny_this[] = "this";
+ struct value *this;
+
+ if (selected_frame == 0)
+ {
+ if (complain)
+ error ("no frame selected");
+ else
+ return 0;
+ }
+
+ func = get_frame_function (selected_frame);
+ if (!func)
+ {
+ if (complain)
+ error ("no `this' in nameless context");
+ else
+ return 0;
+ }
+
+ b = SYMBOL_BLOCK_VALUE (func);
+ i = BLOCK_NSYMS (b);
+ if (i <= 0)
+ {
+ if (complain)
+ error ("no args, no `this'");
+ else
+ return 0;
+ }
+
+ /* Calling lookup_block_symbol is necessary to get the LOC_REGISTER
+ symbol instead of the LOC_ARG one (if both exist). */
+ sym = lookup_block_symbol (b, funny_this, NULL, VAR_NAMESPACE);
+ if (sym == NULL)
+ {
+ if (complain)
+ error ("current stack frame not in method");
+ else
+ return NULL;
+ }
+
+ this = read_var_value (sym, selected_frame);
+ if (this == 0 && complain)
+ error ("`this' argument at unknown address");
+ return this;
+}
+
+/* Create a slice (sub-string, sub-array) of ARRAY, that is LENGTH elements
+ long, starting at LOWBOUND. The result has the same lower bound as
+ the original ARRAY. */
+
+struct value *
+value_slice (struct value *array, int lowbound, int length)
+{
+ struct type *slice_range_type, *slice_type, *range_type;
+ LONGEST lowerbound, upperbound, offset;
+ struct value *slice;
+ struct type *array_type;
+ array_type = check_typedef (VALUE_TYPE (array));
+ COERCE_VARYING_ARRAY (array, array_type);
+ if (TYPE_CODE (array_type) != TYPE_CODE_ARRAY
+ && TYPE_CODE (array_type) != TYPE_CODE_STRING
+ && TYPE_CODE (array_type) != TYPE_CODE_BITSTRING)
+ error ("cannot take slice of non-array");
+ range_type = TYPE_INDEX_TYPE (array_type);
+ if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0)
+ error ("slice from bad array or bitstring");
+ if (lowbound < lowerbound || length < 0
+ || lowbound + length - 1 > upperbound
+ /* Chill allows zero-length strings but not arrays. */
+ || (current_language->la_language == language_chill
+ && length == 0 && TYPE_CODE (array_type) == TYPE_CODE_ARRAY))
+ error ("slice out of range");
+ /* FIXME-type-allocation: need a way to free this type when we are
+ done with it. */
+ slice_range_type = create_range_type ((struct type *) NULL,
+ TYPE_TARGET_TYPE (range_type),
+ lowbound, lowbound + length - 1);
+ if (TYPE_CODE (array_type) == TYPE_CODE_BITSTRING)
+ {
+ int i;
+ slice_type = create_set_type ((struct type *) NULL, slice_range_type);
+ TYPE_CODE (slice_type) = TYPE_CODE_BITSTRING;
+ slice = value_zero (slice_type, not_lval);
+ for (i = 0; i < length; i++)
+ {
+ int element = value_bit_index (array_type,
+ VALUE_CONTENTS (array),
+ lowbound + i);
+ if (element < 0)
+ error ("internal error accessing bitstring");
+ else if (element > 0)
+ {
+ int j = i % TARGET_CHAR_BIT;
+ if (BITS_BIG_ENDIAN)
+ j = TARGET_CHAR_BIT - 1 - j;
+ VALUE_CONTENTS_RAW (slice)[i / TARGET_CHAR_BIT] |= (1 << j);
+ }
+ }
+ /* We should set the address, bitssize, and bitspos, so the clice
+ can be used on the LHS, but that may require extensions to
+ value_assign. For now, just leave as a non_lval. FIXME. */
+ }
+ else
+ {
+ struct type *element_type = TYPE_TARGET_TYPE (array_type);
+ offset
+ = (lowbound - lowerbound) * TYPE_LENGTH (check_typedef (element_type));
+ slice_type = create_array_type ((struct type *) NULL, element_type,
+ slice_range_type);
+ TYPE_CODE (slice_type) = TYPE_CODE (array_type);
+ slice = allocate_value (slice_type);
+ if (VALUE_LAZY (array))
+ VALUE_LAZY (slice) = 1;
+ else
+ memcpy (VALUE_CONTENTS (slice), VALUE_CONTENTS (array) + offset,
+ TYPE_LENGTH (slice_type));
+ if (VALUE_LVAL (array) == lval_internalvar)
+ VALUE_LVAL (slice) = lval_internalvar_component;
+ else
+ VALUE_LVAL (slice) = VALUE_LVAL (array);
+ VALUE_ADDRESS (slice) = VALUE_ADDRESS (array);
+ VALUE_OFFSET (slice) = VALUE_OFFSET (array) + offset;
+ }
+ return slice;
+}
+
+/* Assuming chill_varying_type (VARRAY) is true, return an equivalent
+ value as a fixed-length array. */
+
+struct value *
+varying_to_slice (struct value *varray)
+{
+ struct type *vtype = check_typedef (VALUE_TYPE (varray));
+ LONGEST length = unpack_long (TYPE_FIELD_TYPE (vtype, 0),
+ VALUE_CONTENTS (varray)
+ + TYPE_FIELD_BITPOS (vtype, 0) / 8);
+ return value_slice (value_primitive_field (varray, 0, 1, vtype), 0, length);
+}
+
+/* Create a value for a FORTRAN complex number. Currently most of
+ the time values are coerced to COMPLEX*16 (i.e. a complex number
+ composed of 2 doubles. This really should be a smarter routine
+ that figures out precision inteligently as opposed to assuming
+ doubles. FIXME: fmb */
+
+struct value *
+value_literal_complex (struct value *arg1, struct value *arg2, struct type *type)
+{
+ struct value *val;
+ struct type *real_type = TYPE_TARGET_TYPE (type);
+
+ val = allocate_value (type);
+ arg1 = value_cast (real_type, arg1);
+ arg2 = value_cast (real_type, arg2);
+
+ memcpy (VALUE_CONTENTS_RAW (val),
+ VALUE_CONTENTS (arg1), TYPE_LENGTH (real_type));
+ memcpy (VALUE_CONTENTS_RAW (val) + TYPE_LENGTH (real_type),
+ VALUE_CONTENTS (arg2), TYPE_LENGTH (real_type));
+ return val;
+}
+
+/* Cast a value into the appropriate complex data type. */
+
+static struct value *
+cast_into_complex (struct type *type, struct value *val)
+{
+ struct type *real_type = TYPE_TARGET_TYPE (type);
+ if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_COMPLEX)
+ {
+ struct type *val_real_type = TYPE_TARGET_TYPE (VALUE_TYPE (val));
+ struct value *re_val = allocate_value (val_real_type);
+ struct value *im_val = allocate_value (val_real_type);
+
+ memcpy (VALUE_CONTENTS_RAW (re_val),
+ VALUE_CONTENTS (val), TYPE_LENGTH (val_real_type));
+ memcpy (VALUE_CONTENTS_RAW (im_val),
+ VALUE_CONTENTS (val) + TYPE_LENGTH (val_real_type),
+ TYPE_LENGTH (val_real_type));
+
+ return value_literal_complex (re_val, im_val, type);
+ }
+ else if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FLT
+ || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT)
+ return value_literal_complex (val, value_zero (real_type, not_lval), type);
+ else
+ error ("cannot cast non-number to complex");
+}
+
+void
+_initialize_valops (void)
+{
+#if 0
+ add_show_from_set
+ (add_set_cmd ("abandon", class_support, var_boolean, (char *) &auto_abandon,
+ "Set automatic abandonment of expressions upon failure.",
+ &setlist),
+ &showlist);
+#endif
+
+ add_show_from_set
+ (add_set_cmd ("overload-resolution", class_support, var_boolean, (char *) &overload_resolution,
+ "Set overload resolution in evaluating C++ functions.",
+ &setlist),
+ &showlist);
+ overload_resolution = 1;
+
+ add_show_from_set (
+ add_set_cmd ("unwindonsignal", no_class, var_boolean,
+ (char *) &unwind_on_signal_p,
+"Set unwinding of stack if a signal is received while in a call dummy.\n\
+The unwindonsignal lets the user determine what gdb should do if a signal\n\
+is received while in a function called from gdb (call dummy). If set, gdb\n\
+unwinds the stack and restore the context to what as it was before the call.\n\
+The default is to stop in the frame where the signal was received.", &setlist),
+ &showlist);
+}
diff --git a/gdb/valprint.c b/gdb/valprint.c
new file mode 100644
index 00000000000..36854ce8110
--- /dev/null
+++ b/gdb/valprint.c
@@ -0,0 +1,1425 @@
+/* Print values for GDB, the GNU debugger.
+
+ Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002 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 "defs.h"
+#include "gdb_string.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "obstack.h"
+#include "language.h"
+#include "annotate.h"
+#include "valprint.h"
+#include "floatformat.h"
+#include "doublest.h"
+
+#include <errno.h>
+
+/* Prototypes for local functions */
+
+static int partial_memory_read (CORE_ADDR memaddr, char *myaddr,
+ int len, int *errnoptr);
+
+static void print_hex_chars (struct ui_file *, unsigned char *,
+ unsigned int);
+
+static void show_print (char *, int);
+
+static void set_print (char *, int);
+
+static void set_radix (char *, int);
+
+static void show_radix (char *, int);
+
+static void set_input_radix (char *, int, struct cmd_list_element *);
+
+static void set_input_radix_1 (int, unsigned);
+
+static void set_output_radix (char *, int, struct cmd_list_element *);
+
+static void set_output_radix_1 (int, unsigned);
+
+void _initialize_valprint (void);
+
+/* Maximum number of chars to print for a string pointer value or vector
+ contents, or UINT_MAX for no limit. Note that "set print elements 0"
+ stores UINT_MAX in print_max, which displays in a show command as
+ "unlimited". */
+
+unsigned int print_max;
+#define PRINT_MAX_DEFAULT 200 /* Start print_max off at this value. */
+
+/* Default input and output radixes, and output format letter. */
+
+unsigned input_radix = 10;
+unsigned output_radix = 10;
+int output_format = 0;
+
+/* Print repeat counts if there are more than this many repetitions of an
+ element in an array. Referenced by the low level language dependent
+ print routines. */
+
+unsigned int repeat_count_threshold = 10;
+
+/* If nonzero, stops printing of char arrays at first null. */
+
+int stop_print_at_null;
+
+/* Controls pretty printing of structures. */
+
+int prettyprint_structs;
+
+/* Controls pretty printing of arrays. */
+
+int prettyprint_arrays;
+
+/* If nonzero, causes unions inside structures or other unions to be
+ printed. */
+
+int unionprint; /* Controls printing of nested unions. */
+
+/* If nonzero, causes machine addresses to be printed in certain contexts. */
+
+int addressprint; /* Controls printing of machine addresses */
+
+
+/* Print data of type TYPE located at VALADDR (within GDB), which came from
+ the inferior at address ADDRESS, onto stdio stream STREAM according to
+ FORMAT (a letter, or 0 for natural format using TYPE).
+
+ If DEREF_REF is nonzero, then dereference references, otherwise just print
+ them like pointers.
+
+ The PRETTY parameter controls prettyprinting.
+
+ If the data are a string pointer, returns the number of string characters
+ printed.
+
+ FIXME: The data at VALADDR is in target byte order. If gdb is ever
+ enhanced to be able to debug more than the single target it was compiled
+ for (specific CPU type and thus specific target byte ordering), then
+ either the print routines are going to have to take this into account,
+ or the data is going to have to be passed into here already converted
+ to the host byte ordering, whichever is more convenient. */
+
+
+int
+val_print (struct type *type, char *valaddr, int embedded_offset,
+ CORE_ADDR address, struct ui_file *stream, int format, int deref_ref,
+ int recurse, enum val_prettyprint pretty)
+{
+ struct type *real_type = check_typedef (type);
+ if (pretty == Val_pretty_default)
+ {
+ pretty = prettyprint_structs ? Val_prettyprint : Val_no_prettyprint;
+ }
+
+ QUIT;
+
+ /* Ensure that the type is complete and not just a stub. If the type is
+ only a stub and we can't find and substitute its complete type, then
+ print appropriate string and return. */
+
+ if (TYPE_STUB (real_type))
+ {
+ fprintf_filtered (stream, "<incomplete type>");
+ gdb_flush (stream);
+ return (0);
+ }
+
+ return (LA_VAL_PRINT (type, valaddr, embedded_offset, address,
+ stream, format, deref_ref, recurse, pretty));
+}
+
+/* Print the value VAL in C-ish syntax on stream STREAM.
+ FORMAT is a format-letter, or 0 for print in natural format of data type.
+ If the object printed is a string pointer, returns
+ the number of string bytes printed. */
+
+int
+value_print (struct value *val, struct ui_file *stream, int format,
+ enum val_prettyprint pretty)
+{
+ if (val == 0)
+ {
+ printf_filtered ("<address of value unknown>");
+ return 0;
+ }
+ if (VALUE_OPTIMIZED_OUT (val))
+ {
+ printf_filtered ("<value optimized out>");
+ return 0;
+ }
+ return LA_VALUE_PRINT (val, stream, format, pretty);
+}
+
+/* Called by various <lang>_val_print routines to print
+ TYPE_CODE_INT's. TYPE is the type. VALADDR is the address of the
+ value. STREAM is where to print the value. */
+
+void
+val_print_type_code_int (struct type *type, char *valaddr,
+ struct ui_file *stream)
+{
+ if (TYPE_LENGTH (type) > sizeof (LONGEST))
+ {
+ LONGEST val;
+
+ if (TYPE_UNSIGNED (type)
+ && extract_long_unsigned_integer (valaddr, TYPE_LENGTH (type),
+ &val))
+ {
+ print_longest (stream, 'u', 0, val);
+ }
+ else
+ {
+ /* Signed, or we couldn't turn an unsigned value into a
+ LONGEST. For signed values, one could assume two's
+ complement (a reasonable assumption, I think) and do
+ better than this. */
+ print_hex_chars (stream, (unsigned char *) valaddr,
+ TYPE_LENGTH (type));
+ }
+ }
+ else
+ {
+#ifdef PRINT_TYPELESS_INTEGER
+ PRINT_TYPELESS_INTEGER (stream, type, unpack_long (type, valaddr));
+#else
+ print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0,
+ unpack_long (type, valaddr));
+#endif
+ }
+}
+
+/* Print a number according to FORMAT which is one of d,u,x,o,b,h,w,g.
+ The raison d'etre of this function is to consolidate printing of
+ LONG_LONG's into this one function. Some platforms have long longs but
+ don't have a printf() that supports "ll" in the format string. We handle
+ these by seeing if the number is representable as either a signed or
+ unsigned long, depending upon what format is desired, and if not we just
+ bail out and print the number in hex.
+
+ The format chars b,h,w,g are from print_scalar_formatted(). If USE_LOCAL,
+ format it according to the current language (this should be used for most
+ integers which GDB prints, the exception is things like protocols where
+ the format of the integer is a protocol thing, not a user-visible thing).
+ */
+
+#if defined (CC_HAS_LONG_LONG) && !defined (PRINTF_HAS_LONG_LONG)
+static void print_decimal (struct ui_file * stream, char *sign,
+ int use_local, ULONGEST val_ulong);
+static void
+print_decimal (struct ui_file *stream, char *sign, int use_local,
+ ULONGEST val_ulong)
+{
+ unsigned long temp[3];
+ int i = 0;
+ do
+ {
+ temp[i] = val_ulong % (1000 * 1000 * 1000);
+ val_ulong /= (1000 * 1000 * 1000);
+ i++;
+ }
+ while (val_ulong != 0 && i < (sizeof (temp) / sizeof (temp[0])));
+ switch (i)
+ {
+ case 1:
+ fprintf_filtered (stream, "%s%lu",
+ sign, temp[0]);
+ break;
+ case 2:
+ fprintf_filtered (stream, "%s%lu%09lu",
+ sign, temp[1], temp[0]);
+ break;
+ case 3:
+ fprintf_filtered (stream, "%s%lu%09lu%09lu",
+ sign, temp[2], temp[1], temp[0]);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+ return;
+}
+#endif
+
+void
+print_longest (struct ui_file *stream, int format, int use_local,
+ LONGEST val_long)
+{
+#if defined (CC_HAS_LONG_LONG) && !defined (PRINTF_HAS_LONG_LONG)
+ if (sizeof (long) < sizeof (LONGEST))
+ {
+ switch (format)
+ {
+ case 'd':
+ {
+ /* Print a signed value, that doesn't fit in a long */
+ if ((long) val_long != val_long)
+ {
+ if (val_long < 0)
+ print_decimal (stream, "-", use_local, -val_long);
+ else
+ print_decimal (stream, "", use_local, val_long);
+ return;
+ }
+ break;
+ }
+ case 'u':
+ {
+ /* Print an unsigned value, that doesn't fit in a long */
+ if ((unsigned long) val_long != (ULONGEST) val_long)
+ {
+ print_decimal (stream, "", use_local, val_long);
+ return;
+ }
+ break;
+ }
+ case 'x':
+ case 'o':
+ case 'b':
+ case 'h':
+ case 'w':
+ case 'g':
+ /* Print as unsigned value, must fit completely in unsigned long */
+ {
+ unsigned long temp = val_long;
+ if (temp != val_long)
+ {
+ /* Urk, can't represent value in long so print in hex.
+ Do shift in two operations so that if sizeof (long)
+ == sizeof (LONGEST) we can avoid warnings from
+ picky compilers about shifts >= the size of the
+ shiftee in bits */
+ unsigned long vbot = (unsigned long) val_long;
+ LONGEST temp = (val_long >> (sizeof (long) * HOST_CHAR_BIT - 1));
+ unsigned long vtop = temp >> 1;
+ fprintf_filtered (stream, "0x%lx%08lx", vtop, vbot);
+ return;
+ }
+ break;
+ }
+ }
+ }
+#endif
+
+#if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG)
+ switch (format)
+ {
+ case 'd':
+ fprintf_filtered (stream,
+ use_local ? local_decimal_format_custom ("ll")
+ : "%lld",
+ val_long);
+ break;
+ case 'u':
+ fprintf_filtered (stream, "%llu", (long long) val_long);
+ break;
+ case 'x':
+ fprintf_filtered (stream,
+ use_local ? local_hex_format_custom ("ll")
+ : "%llx",
+ val_long);
+ break;
+ case 'o':
+ fprintf_filtered (stream,
+ use_local ? local_octal_format_custom ("ll")
+ : "%llo",
+ val_long);
+ break;
+ case 'b':
+ fprintf_filtered (stream, local_hex_format_custom ("02ll"), val_long);
+ break;
+ case 'h':
+ fprintf_filtered (stream, local_hex_format_custom ("04ll"), val_long);
+ break;
+ case 'w':
+ fprintf_filtered (stream, local_hex_format_custom ("08ll"), val_long);
+ break;
+ case 'g':
+ fprintf_filtered (stream, local_hex_format_custom ("016ll"), val_long);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+#else /* !CC_HAS_LONG_LONG || !PRINTF_HAS_LONG_LONG */
+ /* In the following it is important to coerce (val_long) to a long. It does
+ nothing if !LONG_LONG, but it will chop off the top half (which we know
+ we can ignore) if the host supports long longs. */
+
+ switch (format)
+ {
+ case 'd':
+ fprintf_filtered (stream,
+ use_local ? local_decimal_format_custom ("l")
+ : "%ld",
+ (long) val_long);
+ break;
+ case 'u':
+ fprintf_filtered (stream, "%lu", (unsigned long) val_long);
+ break;
+ case 'x':
+ fprintf_filtered (stream,
+ use_local ? local_hex_format_custom ("l")
+ : "%lx",
+ (unsigned long) val_long);
+ break;
+ case 'o':
+ fprintf_filtered (stream,
+ use_local ? local_octal_format_custom ("l")
+ : "%lo",
+ (unsigned long) val_long);
+ break;
+ case 'b':
+ fprintf_filtered (stream, local_hex_format_custom ("02l"),
+ (unsigned long) val_long);
+ break;
+ case 'h':
+ fprintf_filtered (stream, local_hex_format_custom ("04l"),
+ (unsigned long) val_long);
+ break;
+ case 'w':
+ fprintf_filtered (stream, local_hex_format_custom ("08l"),
+ (unsigned long) val_long);
+ break;
+ case 'g':
+ fprintf_filtered (stream, local_hex_format_custom ("016l"),
+ (unsigned long) val_long);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ }
+#endif /* CC_HAS_LONG_LONG || PRINTF_HAS_LONG_LONG */
+}
+
+/* This used to be a macro, but I don't think it is called often enough
+ to merit such treatment. */
+/* Convert a LONGEST to an int. This is used in contexts (e.g. number of
+ arguments to a function, number in a value history, register number, etc.)
+ where the value must not be larger than can fit in an int. */
+
+int
+longest_to_int (LONGEST arg)
+{
+ /* Let the compiler do the work */
+ int rtnval = (int) arg;
+
+ /* Check for overflows or underflows */
+ if (sizeof (LONGEST) > sizeof (int))
+ {
+ if (rtnval != arg)
+ {
+ error ("Value out of range.");
+ }
+ }
+ return (rtnval);
+}
+
+/* Print a floating point value of type TYPE (not always a
+ TYPE_CODE_FLT), pointed to in GDB by VALADDR, on STREAM. */
+
+void
+print_floating (char *valaddr, struct type *type, struct ui_file *stream)
+{
+ DOUBLEST doub;
+ int inv;
+ const struct floatformat *fmt = NULL;
+ unsigned len = TYPE_LENGTH (type);
+
+ /* If it is a floating-point, check for obvious problems. */
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ fmt = floatformat_from_type (type);
+ if (fmt != NULL && floatformat_is_nan (fmt, valaddr))
+ {
+ if (floatformat_is_negative (fmt, valaddr))
+ fprintf_filtered (stream, "-");
+ fprintf_filtered (stream, "nan(");
+ fprintf_filtered (stream, local_hex_format_prefix ());
+ fprintf_filtered (stream, floatformat_mantissa (fmt, valaddr));
+ fprintf_filtered (stream, local_hex_format_suffix ());
+ fprintf_filtered (stream, ")");
+ return;
+ }
+
+ /* NOTE: cagney/2002-01-15: The TYPE passed into print_floating()
+ isn't necessarily a TYPE_CODE_FLT. Consequently, unpack_double
+ needs to be used as that takes care of any necessary type
+ conversions. Such conversions are of course direct to DOUBLEST
+ and disregard any possible target floating point limitations.
+ For instance, a u64 would be converted and displayed exactly on a
+ host with 80 bit DOUBLEST but with loss of information on a host
+ with 64 bit DOUBLEST. */
+
+ doub = unpack_double (type, valaddr, &inv);
+ if (inv)
+ {
+ fprintf_filtered (stream, "<invalid float value>");
+ return;
+ }
+
+ /* FIXME: kettenis/2001-01-20: The following code makes too much
+ assumptions about the host and target floating point format. */
+
+ /* NOTE: cagney/2002-02-03: Since the TYPE of what was passed in may
+ not necessarially be a TYPE_CODE_FLT, the below ignores that and
+ instead uses the type's length to determine the precision of the
+ floating-point value being printed. */
+
+ if (len < sizeof (double))
+ fprintf_filtered (stream, "%.9g", (double) doub);
+ else if (len == sizeof (double))
+ fprintf_filtered (stream, "%.17g", (double) doub);
+ else
+#ifdef PRINTF_HAS_LONG_DOUBLE
+ fprintf_filtered (stream, "%.35Lg", doub);
+#else
+ /* This at least wins with values that are representable as
+ doubles. */
+ fprintf_filtered (stream, "%.17g", (double) doub);
+#endif
+}
+
+void
+print_binary_chars (struct ui_file *stream, unsigned char *valaddr,
+ unsigned len)
+{
+
+#define BITS_IN_BYTES 8
+
+ unsigned char *p;
+ unsigned int i;
+ int b;
+
+ /* Declared "int" so it will be signed.
+ * This ensures that right shift will shift in zeros.
+ */
+ const int mask = 0x080;
+
+ /* FIXME: We should be not printing leading zeroes in most cases. */
+
+ fprintf_filtered (stream, local_binary_format_prefix ());
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ for (p = valaddr;
+ p < valaddr + len;
+ p++)
+ {
+ /* Every byte has 8 binary characters; peel off
+ * and print from the MSB end.
+ */
+ for (i = 0; i < (BITS_IN_BYTES * sizeof (*p)); i++)
+ {
+ if (*p & (mask >> i))
+ b = 1;
+ else
+ b = 0;
+
+ fprintf_filtered (stream, "%1d", b);
+ }
+ }
+ }
+ else
+ {
+ for (p = valaddr + len - 1;
+ p >= valaddr;
+ p--)
+ {
+ for (i = 0; i < (BITS_IN_BYTES * sizeof (*p)); i++)
+ {
+ if (*p & (mask >> i))
+ b = 1;
+ else
+ b = 0;
+
+ fprintf_filtered (stream, "%1d", b);
+ }
+ }
+ }
+ fprintf_filtered (stream, local_binary_format_suffix ());
+}
+
+/* VALADDR points to an integer of LEN bytes.
+ * Print it in octal on stream or format it in buf.
+ */
+void
+print_octal_chars (struct ui_file *stream, unsigned char *valaddr, unsigned len)
+{
+ unsigned char *p;
+ unsigned char octa1, octa2, octa3, carry;
+ int cycle;
+
+ /* FIXME: We should be not printing leading zeroes in most cases. */
+
+
+ /* Octal is 3 bits, which doesn't fit. Yuk. So we have to track
+ * the extra bits, which cycle every three bytes:
+ *
+ * Byte side: 0 1 2 3
+ * | | | |
+ * bit number 123 456 78 | 9 012 345 6 | 78 901 234 | 567 890 12 |
+ *
+ * Octal side: 0 1 carry 3 4 carry ...
+ *
+ * Cycle number: 0 1 2
+ *
+ * But of course we are printing from the high side, so we have to
+ * figure out where in the cycle we are so that we end up with no
+ * left over bits at the end.
+ */
+#define BITS_IN_OCTAL 3
+#define HIGH_ZERO 0340
+#define LOW_ZERO 0016
+#define CARRY_ZERO 0003
+#define HIGH_ONE 0200
+#define MID_ONE 0160
+#define LOW_ONE 0016
+#define CARRY_ONE 0001
+#define HIGH_TWO 0300
+#define MID_TWO 0070
+#define LOW_TWO 0007
+
+ /* For 32 we start in cycle 2, with two bits and one bit carry;
+ * for 64 in cycle in cycle 1, with one bit and a two bit carry.
+ */
+ cycle = (len * BITS_IN_BYTES) % BITS_IN_OCTAL;
+ carry = 0;
+
+ fprintf_filtered (stream, local_octal_format_prefix ());
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ for (p = valaddr;
+ p < valaddr + len;
+ p++)
+ {
+ switch (cycle)
+ {
+ case 0:
+ /* No carry in, carry out two bits.
+ */
+ octa1 = (HIGH_ZERO & *p) >> 5;
+ octa2 = (LOW_ZERO & *p) >> 2;
+ carry = (CARRY_ZERO & *p);
+ fprintf_filtered (stream, "%o", octa1);
+ fprintf_filtered (stream, "%o", octa2);
+ break;
+
+ case 1:
+ /* Carry in two bits, carry out one bit.
+ */
+ octa1 = (carry << 1) | ((HIGH_ONE & *p) >> 7);
+ octa2 = (MID_ONE & *p) >> 4;
+ octa3 = (LOW_ONE & *p) >> 1;
+ carry = (CARRY_ONE & *p);
+ fprintf_filtered (stream, "%o", octa1);
+ fprintf_filtered (stream, "%o", octa2);
+ fprintf_filtered (stream, "%o", octa3);
+ break;
+
+ case 2:
+ /* Carry in one bit, no carry out.
+ */
+ octa1 = (carry << 2) | ((HIGH_TWO & *p) >> 6);
+ octa2 = (MID_TWO & *p) >> 3;
+ octa3 = (LOW_TWO & *p);
+ carry = 0;
+ fprintf_filtered (stream, "%o", octa1);
+ fprintf_filtered (stream, "%o", octa2);
+ fprintf_filtered (stream, "%o", octa3);
+ break;
+
+ default:
+ error ("Internal error in octal conversion;");
+ }
+
+ cycle++;
+ cycle = cycle % BITS_IN_OCTAL;
+ }
+ }
+ else
+ {
+ for (p = valaddr + len - 1;
+ p >= valaddr;
+ p--)
+ {
+ switch (cycle)
+ {
+ case 0:
+ /* Carry out, no carry in */
+ octa1 = (HIGH_ZERO & *p) >> 5;
+ octa2 = (LOW_ZERO & *p) >> 2;
+ carry = (CARRY_ZERO & *p);
+ fprintf_filtered (stream, "%o", octa1);
+ fprintf_filtered (stream, "%o", octa2);
+ break;
+
+ case 1:
+ /* Carry in, carry out */
+ octa1 = (carry << 1) | ((HIGH_ONE & *p) >> 7);
+ octa2 = (MID_ONE & *p) >> 4;
+ octa3 = (LOW_ONE & *p) >> 1;
+ carry = (CARRY_ONE & *p);
+ fprintf_filtered (stream, "%o", octa1);
+ fprintf_filtered (stream, "%o", octa2);
+ fprintf_filtered (stream, "%o", octa3);
+ break;
+
+ case 2:
+ /* Carry in, no carry out */
+ octa1 = (carry << 2) | ((HIGH_TWO & *p) >> 6);
+ octa2 = (MID_TWO & *p) >> 3;
+ octa3 = (LOW_TWO & *p);
+ carry = 0;
+ fprintf_filtered (stream, "%o", octa1);
+ fprintf_filtered (stream, "%o", octa2);
+ fprintf_filtered (stream, "%o", octa3);
+ break;
+
+ default:
+ error ("Internal error in octal conversion;");
+ }
+
+ cycle++;
+ cycle = cycle % BITS_IN_OCTAL;
+ }
+ }
+
+ fprintf_filtered (stream, local_octal_format_suffix ());
+}
+
+/* VALADDR points to an integer of LEN bytes.
+ * Print it in decimal on stream or format it in buf.
+ */
+void
+print_decimal_chars (struct ui_file *stream, unsigned char *valaddr,
+ unsigned len)
+{
+#define TEN 10
+#define TWO_TO_FOURTH 16
+#define CARRY_OUT( x ) ((x) / TEN) /* extend char to int */
+#define CARRY_LEFT( x ) ((x) % TEN)
+#define SHIFT( x ) ((x) << 4)
+#define START_P \
+ ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) ? valaddr : valaddr + len - 1)
+#define NOT_END_P \
+ ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) ? (p < valaddr + len) : (p >= valaddr))
+#define NEXT_P \
+ ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) ? p++ : p-- )
+#define LOW_NIBBLE( x ) ( (x) & 0x00F)
+#define HIGH_NIBBLE( x ) (((x) & 0x0F0) >> 4)
+
+ unsigned char *p;
+ unsigned char *digits;
+ int carry;
+ int decimal_len;
+ int i, j, decimal_digits;
+ int dummy;
+ int flip;
+
+ /* Base-ten number is less than twice as many digits
+ * as the base 16 number, which is 2 digits per byte.
+ */
+ decimal_len = len * 2 * 2;
+ digits = xmalloc (decimal_len);
+
+ for (i = 0; i < decimal_len; i++)
+ {
+ digits[i] = 0;
+ }
+
+ fprintf_filtered (stream, local_decimal_format_prefix ());
+
+ /* Ok, we have an unknown number of bytes of data to be printed in
+ * decimal.
+ *
+ * Given a hex number (in nibbles) as XYZ, we start by taking X and
+ * decemalizing it as "x1 x2" in two decimal nibbles. Then we multiply
+ * the nibbles by 16, add Y and re-decimalize. Repeat with Z.
+ *
+ * The trick is that "digits" holds a base-10 number, but sometimes
+ * the individual digits are > 10.
+ *
+ * Outer loop is per nibble (hex digit) of input, from MSD end to
+ * LSD end.
+ */
+ decimal_digits = 0; /* Number of decimal digits so far */
+ p = START_P;
+ flip = 0;
+ while (NOT_END_P)
+ {
+ /*
+ * Multiply current base-ten number by 16 in place.
+ * Each digit was between 0 and 9, now is between
+ * 0 and 144.
+ */
+ for (j = 0; j < decimal_digits; j++)
+ {
+ digits[j] = SHIFT (digits[j]);
+ }
+
+ /* Take the next nibble off the input and add it to what
+ * we've got in the LSB position. Bottom 'digit' is now
+ * between 0 and 159.
+ *
+ * "flip" is used to run this loop twice for each byte.
+ */
+ if (flip == 0)
+ {
+ /* Take top nibble.
+ */
+ digits[0] += HIGH_NIBBLE (*p);
+ flip = 1;
+ }
+ else
+ {
+ /* Take low nibble and bump our pointer "p".
+ */
+ digits[0] += LOW_NIBBLE (*p);
+ NEXT_P;
+ flip = 0;
+ }
+
+ /* Re-decimalize. We have to do this often enough
+ * that we don't overflow, but once per nibble is
+ * overkill. Easier this way, though. Note that the
+ * carry is often larger than 10 (e.g. max initial
+ * carry out of lowest nibble is 15, could bubble all
+ * the way up greater than 10). So we have to do
+ * the carrying beyond the last current digit.
+ */
+ carry = 0;
+ for (j = 0; j < decimal_len - 1; j++)
+ {
+ digits[j] += carry;
+
+ /* "/" won't handle an unsigned char with
+ * a value that if signed would be negative.
+ * So extend to longword int via "dummy".
+ */
+ dummy = digits[j];
+ carry = CARRY_OUT (dummy);
+ digits[j] = CARRY_LEFT (dummy);
+
+ if (j >= decimal_digits && carry == 0)
+ {
+ /*
+ * All higher digits are 0 and we
+ * no longer have a carry.
+ *
+ * Note: "j" is 0-based, "decimal_digits" is
+ * 1-based.
+ */
+ decimal_digits = j + 1;
+ break;
+ }
+ }
+ }
+
+ /* Ok, now "digits" is the decimal representation, with
+ * the "decimal_digits" actual digits. Print!
+ */
+ for (i = decimal_digits - 1; i >= 0; i--)
+ {
+ fprintf_filtered (stream, "%1d", digits[i]);
+ }
+ xfree (digits);
+
+ fprintf_filtered (stream, local_decimal_format_suffix ());
+}
+
+/* VALADDR points to an integer of LEN bytes. Print it in hex on stream. */
+
+static void
+print_hex_chars (struct ui_file *stream, unsigned char *valaddr, unsigned len)
+{
+ unsigned char *p;
+
+ /* FIXME: We should be not printing leading zeroes in most cases. */
+
+ fprintf_filtered (stream, local_hex_format_prefix ());
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ {
+ for (p = valaddr;
+ p < valaddr + len;
+ p++)
+ {
+ fprintf_filtered (stream, "%02x", *p);
+ }
+ }
+ else
+ {
+ for (p = valaddr + len - 1;
+ p >= valaddr;
+ p--)
+ {
+ fprintf_filtered (stream, "%02x", *p);
+ }
+ }
+ fprintf_filtered (stream, local_hex_format_suffix ());
+}
+
+/* Called by various <lang>_val_print routines to print elements of an
+ array in the form "<elem1>, <elem2>, <elem3>, ...".
+
+ (FIXME?) Assumes array element separator is a comma, which is correct
+ for all languages currently handled.
+ (FIXME?) Some languages have a notation for repeated array elements,
+ perhaps we should try to use that notation when appropriate.
+ */
+
+void
+val_print_array_elements (struct type *type, char *valaddr, CORE_ADDR address,
+ struct ui_file *stream, int format, int deref_ref,
+ int recurse, enum val_prettyprint pretty,
+ unsigned int i)
+{
+ unsigned int things_printed = 0;
+ unsigned len;
+ struct type *elttype;
+ unsigned eltlen;
+ /* Position of the array element we are examining to see
+ whether it is repeated. */
+ unsigned int rep1;
+ /* Number of repetitions we have detected so far. */
+ unsigned int reps;
+
+ elttype = TYPE_TARGET_TYPE (type);
+ eltlen = TYPE_LENGTH (check_typedef (elttype));
+ len = TYPE_LENGTH (type) / eltlen;
+
+ annotate_array_section_begin (i, elttype);
+
+ for (; i < len && things_printed < print_max; i++)
+ {
+ if (i != 0)
+ {
+ if (prettyprint_arrays)
+ {
+ fprintf_filtered (stream, ",\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ else
+ {
+ fprintf_filtered (stream, ", ");
+ }
+ }
+ wrap_here (n_spaces (2 + 2 * recurse));
+
+ rep1 = i + 1;
+ reps = 1;
+ while ((rep1 < len) &&
+ !memcmp (valaddr + i * eltlen, valaddr + rep1 * eltlen, eltlen))
+ {
+ ++reps;
+ ++rep1;
+ }
+
+ if (reps > repeat_count_threshold)
+ {
+ val_print (elttype, valaddr + i * eltlen, 0, 0, stream, format,
+ deref_ref, recurse + 1, pretty);
+ annotate_elt_rep (reps);
+ fprintf_filtered (stream, " <repeats %u times>", reps);
+ annotate_elt_rep_end ();
+
+ i = rep1 - 1;
+ things_printed += repeat_count_threshold;
+ }
+ else
+ {
+ val_print (elttype, valaddr + i * eltlen, 0, 0, stream, format,
+ deref_ref, recurse + 1, pretty);
+ annotate_elt ();
+ things_printed++;
+ }
+ }
+ annotate_array_section_end ();
+ if (i < len)
+ {
+ fprintf_filtered (stream, "...");
+ }
+}
+
+/* Read LEN bytes of target memory at address MEMADDR, placing the
+ results in GDB's memory at MYADDR. Returns a count of the bytes
+ actually read, and optionally an errno value in the location
+ pointed to by ERRNOPTR if ERRNOPTR is non-null. */
+
+/* FIXME: cagney/1999-10-14: Only used by val_print_string. Can this
+ function be eliminated. */
+
+static int
+partial_memory_read (CORE_ADDR memaddr, char *myaddr, int len, int *errnoptr)
+{
+ int nread; /* Number of bytes actually read. */
+ int errcode; /* Error from last read. */
+
+ /* First try a complete read. */
+ errcode = target_read_memory (memaddr, myaddr, len);
+ if (errcode == 0)
+ {
+ /* Got it all. */
+ nread = len;
+ }
+ else
+ {
+ /* Loop, reading one byte at a time until we get as much as we can. */
+ for (errcode = 0, nread = 0; len > 0 && errcode == 0; nread++, len--)
+ {
+ errcode = target_read_memory (memaddr++, myaddr++, 1);
+ }
+ /* If an error, the last read was unsuccessful, so adjust count. */
+ if (errcode != 0)
+ {
+ nread--;
+ }
+ }
+ if (errnoptr != NULL)
+ {
+ *errnoptr = errcode;
+ }
+ return (nread);
+}
+
+/* Print a string from the inferior, starting at ADDR and printing up to LEN
+ characters, of WIDTH bytes a piece, to STREAM. If LEN is -1, printing
+ stops at the first null byte, otherwise printing proceeds (including null
+ bytes) until either print_max or LEN characters have been printed,
+ whichever is smaller. */
+
+/* FIXME: Use target_read_string. */
+
+int
+val_print_string (CORE_ADDR addr, int len, int width, struct ui_file *stream)
+{
+ int force_ellipsis = 0; /* Force ellipsis to be printed if nonzero. */
+ int errcode; /* Errno returned from bad reads. */
+ unsigned int fetchlimit; /* Maximum number of chars to print. */
+ unsigned int nfetch; /* Chars to fetch / chars fetched. */
+ unsigned int chunksize; /* Size of each fetch, in chars. */
+ char *buffer = NULL; /* Dynamically growable fetch buffer. */
+ char *bufptr; /* Pointer to next available byte in buffer. */
+ char *limit; /* First location past end of fetch buffer. */
+ struct cleanup *old_chain = NULL; /* Top of the old cleanup chain. */
+ int found_nul; /* Non-zero if we found the nul char */
+
+ /* First we need to figure out the limit on the number of characters we are
+ going to attempt to fetch and print. This is actually pretty simple. If
+ LEN >= zero, then the limit is the minimum of LEN and print_max. If
+ LEN is -1, then the limit is print_max. This is true regardless of
+ whether print_max is zero, UINT_MAX (unlimited), or something in between,
+ because finding the null byte (or available memory) is what actually
+ limits the fetch. */
+
+ fetchlimit = (len == -1 ? print_max : min (len, print_max));
+
+ /* Now decide how large of chunks to try to read in one operation. This
+ is also pretty simple. If LEN >= zero, then we want fetchlimit chars,
+ so we might as well read them all in one operation. If LEN is -1, we
+ are looking for a null terminator to end the fetching, so we might as
+ well read in blocks that are large enough to be efficient, but not so
+ large as to be slow if fetchlimit happens to be large. So we choose the
+ minimum of 8 and fetchlimit. We used to use 200 instead of 8 but
+ 200 is way too big for remote debugging over a serial line. */
+
+ chunksize = (len == -1 ? min (8, fetchlimit) : fetchlimit);
+
+ /* Loop until we either have all the characters to print, or we encounter
+ some error, such as bumping into the end of the address space. */
+
+ found_nul = 0;
+ old_chain = make_cleanup (null_cleanup, 0);
+
+ if (len > 0)
+ {
+ buffer = (char *) xmalloc (len * width);
+ bufptr = buffer;
+ old_chain = make_cleanup (xfree, buffer);
+
+ nfetch = partial_memory_read (addr, bufptr, len * width, &errcode)
+ / width;
+ addr += nfetch * width;
+ bufptr += nfetch * width;
+ }
+ else if (len == -1)
+ {
+ unsigned long bufsize = 0;
+ do
+ {
+ QUIT;
+ nfetch = min (chunksize, fetchlimit - bufsize);
+
+ if (buffer == NULL)
+ buffer = (char *) xmalloc (nfetch * width);
+ else
+ {
+ discard_cleanups (old_chain);
+ buffer = (char *) xrealloc (buffer, (nfetch + bufsize) * width);
+ }
+
+ old_chain = make_cleanup (xfree, buffer);
+ bufptr = buffer + bufsize * width;
+ bufsize += nfetch;
+
+ /* Read as much as we can. */
+ nfetch = partial_memory_read (addr, bufptr, nfetch * width, &errcode)
+ / width;
+
+ /* Scan this chunk for the null byte that terminates the string
+ to print. If found, we don't need to fetch any more. Note
+ that bufptr is explicitly left pointing at the next character
+ after the null byte, or at the next character after the end of
+ the buffer. */
+
+ limit = bufptr + nfetch * width;
+ while (bufptr < limit)
+ {
+ unsigned long c;
+
+ c = extract_unsigned_integer (bufptr, width);
+ addr += width;
+ bufptr += width;
+ if (c == 0)
+ {
+ /* We don't care about any error which happened after
+ the NULL terminator. */
+ errcode = 0;
+ found_nul = 1;
+ break;
+ }
+ }
+ }
+ while (errcode == 0 /* no error */
+ && bufptr - buffer < fetchlimit * width /* no overrun */
+ && !found_nul); /* haven't found nul yet */
+ }
+ else
+ { /* length of string is really 0! */
+ buffer = bufptr = NULL;
+ errcode = 0;
+ }
+
+ /* bufptr and addr now point immediately beyond the last byte which we
+ consider part of the string (including a '\0' which ends the string). */
+
+ /* We now have either successfully filled the buffer to fetchlimit, or
+ terminated early due to an error or finding a null char when LEN is -1. */
+
+ if (len == -1 && !found_nul)
+ {
+ char *peekbuf;
+
+ /* We didn't find a null terminator we were looking for. Attempt
+ to peek at the next character. If not successful, or it is not
+ a null byte, then force ellipsis to be printed. */
+
+ peekbuf = (char *) alloca (width);
+
+ if (target_read_memory (addr, peekbuf, width) == 0
+ && extract_unsigned_integer (peekbuf, width) != 0)
+ force_ellipsis = 1;
+ }
+ else if ((len >= 0 && errcode != 0) || (len > (bufptr - buffer) / width))
+ {
+ /* Getting an error when we have a requested length, or fetching less
+ than the number of characters actually requested, always make us
+ print ellipsis. */
+ force_ellipsis = 1;
+ }
+
+ QUIT;
+
+ /* If we get an error before fetching anything, don't print a string.
+ But if we fetch something and then get an error, print the string
+ and then the error message. */
+ if (errcode == 0 || bufptr > buffer)
+ {
+ if (addressprint)
+ {
+ fputs_filtered (" ", stream);
+ }
+ LA_PRINT_STRING (stream, buffer, (bufptr - buffer) / width, width, force_ellipsis);
+ }
+
+ if (errcode != 0)
+ {
+ if (errcode == EIO)
+ {
+ fprintf_filtered (stream, " <Address ");
+ print_address_numeric (addr, 1, stream);
+ fprintf_filtered (stream, " out of bounds>");
+ }
+ else
+ {
+ fprintf_filtered (stream, " <Error reading address ");
+ print_address_numeric (addr, 1, stream);
+ fprintf_filtered (stream, ": %s>", safe_strerror (errcode));
+ }
+ }
+ gdb_flush (stream);
+ do_cleanups (old_chain);
+ return ((bufptr - buffer) / width);
+}
+
+
+/* Validate an input or output radix setting, and make sure the user
+ knows what they really did here. Radix setting is confusing, e.g.
+ setting the input radix to "10" never changes it! */
+
+/* ARGSUSED */
+static void
+set_input_radix (char *args, int from_tty, struct cmd_list_element *c)
+{
+ set_input_radix_1 (from_tty, input_radix);
+}
+
+/* ARGSUSED */
+static void
+set_input_radix_1 (int from_tty, unsigned radix)
+{
+ /* We don't currently disallow any input radix except 0 or 1, which don't
+ make any mathematical sense. In theory, we can deal with any input
+ radix greater than 1, even if we don't have unique digits for every
+ value from 0 to radix-1, but in practice we lose on large radix values.
+ We should either fix the lossage or restrict the radix range more.
+ (FIXME). */
+
+ if (radix < 2)
+ {
+ /* FIXME: cagney/2002-03-17: This needs to revert the bad radix
+ value. */
+ error ("Nonsense input radix ``decimal %u''; input radix unchanged.",
+ radix);
+ }
+ input_radix = radix;
+ if (from_tty)
+ {
+ printf_filtered ("Input radix now set to decimal %u, hex %x, octal %o.\n",
+ radix, radix, radix);
+ }
+}
+
+/* ARGSUSED */
+static void
+set_output_radix (char *args, int from_tty, struct cmd_list_element *c)
+{
+ set_output_radix_1 (from_tty, output_radix);
+}
+
+static void
+set_output_radix_1 (int from_tty, unsigned radix)
+{
+ /* Validate the radix and disallow ones that we aren't prepared to
+ handle correctly, leaving the radix unchanged. */
+ switch (radix)
+ {
+ case 16:
+ output_format = 'x'; /* hex */
+ break;
+ case 10:
+ output_format = 0; /* decimal */
+ break;
+ case 8:
+ output_format = 'o'; /* octal */
+ break;
+ default:
+ /* FIXME: cagney/2002-03-17: This needs to revert the bad radix
+ value. */
+ error ("Unsupported output radix ``decimal %u''; output radix unchanged.",
+ radix);
+ }
+ output_radix = radix;
+ if (from_tty)
+ {
+ printf_filtered ("Output radix now set to decimal %u, hex %x, octal %o.\n",
+ radix, radix, radix);
+ }
+}
+
+/* Set both the input and output radix at once. Try to set the output radix
+ first, since it has the most restrictive range. An radix that is valid as
+ an output radix is also valid as an input radix.
+
+ It may be useful to have an unusual input radix. If the user wishes to
+ set an input radix that is not valid as an output radix, he needs to use
+ the 'set input-radix' command. */
+
+static void
+set_radix (char *arg, int from_tty)
+{
+ unsigned radix;
+
+ radix = (arg == NULL) ? 10 : parse_and_eval_long (arg);
+ set_output_radix_1 (0, radix);
+ set_input_radix_1 (0, radix);
+ if (from_tty)
+ {
+ printf_filtered ("Input and output radices now set to decimal %u, hex %x, octal %o.\n",
+ radix, radix, radix);
+ }
+}
+
+/* Show both the input and output radices. */
+
+/*ARGSUSED */
+static void
+show_radix (char *arg, int from_tty)
+{
+ if (from_tty)
+ {
+ if (input_radix == output_radix)
+ {
+ printf_filtered ("Input and output radices set to decimal %u, hex %x, octal %o.\n",
+ input_radix, input_radix, input_radix);
+ }
+ else
+ {
+ printf_filtered ("Input radix set to decimal %u, hex %x, octal %o.\n",
+ input_radix, input_radix, input_radix);
+ printf_filtered ("Output radix set to decimal %u, hex %x, octal %o.\n",
+ output_radix, output_radix, output_radix);
+ }
+ }
+}
+
+
+/*ARGSUSED */
+static void
+set_print (char *arg, int from_tty)
+{
+ printf_unfiltered (
+ "\"set print\" must be followed by the name of a print subcommand.\n");
+ help_list (setprintlist, "set print ", -1, gdb_stdout);
+}
+
+/*ARGSUSED */
+static void
+show_print (char *args, int from_tty)
+{
+ cmd_show_list (showprintlist, from_tty, "");
+}
+
+void
+_initialize_valprint (void)
+{
+ struct cmd_list_element *c;
+
+ add_prefix_cmd ("print", no_class, set_print,
+ "Generic command for setting how things print.",
+ &setprintlist, "set print ", 0, &setlist);
+ add_alias_cmd ("p", "print", no_class, 1, &setlist);
+ /* prefer set print to set prompt */
+ add_alias_cmd ("pr", "print", no_class, 1, &setlist);
+
+ add_prefix_cmd ("print", no_class, show_print,
+ "Generic command for showing print settings.",
+ &showprintlist, "show print ", 0, &showlist);
+ add_alias_cmd ("p", "print", no_class, 1, &showlist);
+ add_alias_cmd ("pr", "print", no_class, 1, &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("elements", no_class, var_uinteger, (char *) &print_max,
+ "Set limit on string chars or array elements to print.\n\
+\"set print elements 0\" causes there to be no limit.",
+ &setprintlist),
+ &showprintlist);
+
+ add_show_from_set
+ (add_set_cmd ("null-stop", no_class, var_boolean,
+ (char *) &stop_print_at_null,
+ "Set printing of char arrays to stop at first null char.",
+ &setprintlist),
+ &showprintlist);
+
+ add_show_from_set
+ (add_set_cmd ("repeats", no_class, var_uinteger,
+ (char *) &repeat_count_threshold,
+ "Set threshold for repeated print elements.\n\
+\"set print repeats 0\" causes all elements to be individually printed.",
+ &setprintlist),
+ &showprintlist);
+
+ add_show_from_set
+ (add_set_cmd ("pretty", class_support, var_boolean,
+ (char *) &prettyprint_structs,
+ "Set prettyprinting of structures.",
+ &setprintlist),
+ &showprintlist);
+
+ add_show_from_set
+ (add_set_cmd ("union", class_support, var_boolean, (char *) &unionprint,
+ "Set printing of unions interior to structures.",
+ &setprintlist),
+ &showprintlist);
+
+ add_show_from_set
+ (add_set_cmd ("array", class_support, var_boolean,
+ (char *) &prettyprint_arrays,
+ "Set prettyprinting of arrays.",
+ &setprintlist),
+ &showprintlist);
+
+ add_show_from_set
+ (add_set_cmd ("address", class_support, var_boolean, (char *) &addressprint,
+ "Set printing of addresses.",
+ &setprintlist),
+ &showprintlist);
+
+ c = add_set_cmd ("input-radix", class_support, var_uinteger,
+ (char *) &input_radix,
+ "Set default input radix for entering numbers.",
+ &setlist);
+ add_show_from_set (c, &showlist);
+ set_cmd_sfunc (c, set_input_radix);
+
+ c = add_set_cmd ("output-radix", class_support, var_uinteger,
+ (char *) &output_radix,
+ "Set default output radix for printing of values.",
+ &setlist);
+ add_show_from_set (c, &showlist);
+ set_cmd_sfunc (c, set_output_radix);
+
+ /* The "set radix" and "show radix" commands are special in that they are
+ like normal set and show commands but allow two normally independent
+ variables to be either set or shown with a single command. So the
+ usual add_set_cmd() and add_show_from_set() commands aren't really
+ appropriate. */
+ add_cmd ("radix", class_support, set_radix,
+ "Set default input and output number radices.\n\
+Use 'set input-radix' or 'set output-radix' to independently set each.\n\
+Without an argument, sets both radices back to the default value of 10.",
+ &setlist);
+ add_cmd ("radix", class_support, show_radix,
+ "Show the default input and output number radices.\n\
+Use 'show input-radix' or 'show output-radix' to independently show each.",
+ &showlist);
+
+ /* Give people the defaults which they are used to. */
+ prettyprint_structs = 0;
+ prettyprint_arrays = 0;
+ unionprint = 1;
+ addressprint = 1;
+ print_max = PRINT_MAX_DEFAULT;
+}
diff --git a/gdb/valprint.h b/gdb/valprint.h
new file mode 100644
index 00000000000..52314aaa191
--- /dev/null
+++ b/gdb/valprint.h
@@ -0,0 +1,60 @@
+/* Declarations for value printing routines for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1991-1994, 2000 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. */
+
+#ifndef VALPRINT_H
+#define VALPRINT_H
+
+extern int prettyprint_arrays; /* Controls pretty printing of arrays. */
+extern int prettyprint_structs; /* Controls pretty printing of structures */
+extern int prettyprint_arrays; /* Controls pretty printing of arrays. */
+
+extern int vtblprint; /* Controls printing of vtbl's */
+extern int unionprint; /* Controls printing of nested unions. */
+extern int addressprint; /* Controls pretty printing of addresses. */
+extern int objectprint; /* Controls looking up an object's derived type
+ using what we find in its vtables. */
+
+extern unsigned int print_max; /* Max # of chars for strings/vectors */
+
+/* Print repeat counts if there are more than this many repetitions of an
+ element in an array. Referenced by the low level language dependent
+ print routines. */
+extern unsigned int repeat_count_threshold;
+
+extern int output_format;
+
+extern int stop_print_at_null; /* Stop printing at null char? */
+
+extern void val_print_array_elements (struct type *, char *, CORE_ADDR,
+ struct ui_file *, int, int, int,
+ enum val_prettyprint, unsigned int);
+
+extern void val_print_type_code_int (struct type *, char *,
+ struct ui_file *);
+
+extern void print_binary_chars (struct ui_file *, unsigned char *,
+ unsigned int);
+
+extern void print_octal_chars (struct ui_file *, unsigned char *,
+ unsigned int);
+
+extern void print_decimal_chars (struct ui_file *, unsigned char *,
+ unsigned int);
+#endif
diff --git a/gdb/value.h b/gdb/value.h
new file mode 100644
index 00000000000..a0eb99086ff
--- /dev/null
+++ b/gdb/value.h
@@ -0,0 +1,566 @@
+/* Definitions for values of C expressions, for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 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. */
+
+#if !defined (VALUE_H)
+#define VALUE_H 1
+
+#include "doublest.h"
+
+/*
+ * The structure which defines the type of a value. It should never
+ * be possible for a program lval value to survive over a call to the inferior
+ * (ie to be put into the history list or an internal variable).
+ */
+
+struct value
+ {
+ /* Type of value; either not an lval, or one of the various
+ different possible kinds of lval. */
+ enum lval_type lval;
+ /* Is it modifiable? Only relevant if lval != not_lval. */
+ int modifiable;
+ /* Location of value (if lval). */
+ union
+ {
+ /* If lval == lval_memory, this is the address in the inferior.
+ If lval == lval_register, this is the byte offset into the
+ registers structure. */
+ CORE_ADDR address;
+ /* Pointer to internal variable. */
+ struct internalvar *internalvar;
+ /* Number of register. Only used with
+ lval_reg_frame_relative. */
+ int regnum;
+ }
+ location;
+ /* Describes offset of a value within lval of a structure in bytes.
+ If lval == lval_memory, this is an offset to the address.
+ If lval == lval_register, this is a further offset from
+ location.address within the registers structure.
+ Note also the member embedded_offset below. */
+ int offset;
+ /* Only used for bitfields; number of bits contained in them. */
+ int bitsize;
+ /* Only used for bitfields; position of start of field.
+ For BITS_BIG_ENDIAN=0 targets, it is the position of the LSB.
+ For BITS_BIG_ENDIAN=1 targets, it is the position of the MSB. */
+ int bitpos;
+ /* Frame value is relative to. In practice, this address is only
+ used if the value is stored in several registers in other than
+ the current frame, and these registers have not all been saved
+ at the same place in memory. This will be described in the
+ lval enum above as "lval_reg_frame_relative". */
+ CORE_ADDR frame_addr;
+
+ /* Type of the value. */
+ struct type *type;
+
+ /* If a value represents a C++ object, then the `type' field gives
+ the object's compile-time type. If the object actually belongs
+ to some class derived from `type', perhaps with other base
+ classes and additional members, then `type' is just a subobject
+ of the real thing, and the full object is probably larger than
+ `type' would suggest.
+
+ If `type' is a dynamic class (i.e. one with a vtable), then GDB
+ can actually determine the object's run-time type by looking at
+ the run-time type information in the vtable. When this
+ information is available, we may elect to read in the entire
+ object, for several reasons:
+
+ - When printing the value, the user would probably rather see
+ the full object, not just the limited portion apparent from
+ the compile-time type.
+
+ - If `type' has virtual base classes, then even printing
+ `type' alone may require reaching outside the `type'
+ portion of the object to wherever the virtual base class
+ has been stored.
+
+ When we store the entire object, `enclosing_type' is the
+ run-time type --- the complete object --- and `embedded_offset'
+ is the offset of `type' within that larger type, in bytes. The
+ VALUE_CONTENTS macro takes `embedded_offset' into account, so
+ most GDB code continues to see the `type' portion of the value,
+ just as the inferior would.
+
+ If `type' is a pointer to an object, then `enclosing_type' is a
+ pointer to the object's run-time type, and `pointed_to_offset'
+ is the offset in bytes from the full object to the pointed-to
+ object --- that is, the value `embedded_offset' would have if
+ we followed the pointer and fetched the complete object. (I
+ don't really see the point. Why not just determine the
+ run-time type when you indirect, and avoid the special case?
+ The contents don't matter until you indirect anyway.)
+
+ If we're not doing anything fancy, `enclosing_type' is equal to
+ `type', and `embedded_offset' is zero, so everything works
+ normally. */
+ struct type *enclosing_type;
+ int embedded_offset;
+ int pointed_to_offset;
+
+ /* Values are stored in a chain, so that they can be deleted
+ easily over calls to the inferior. Values assigned to internal
+ variables or put into the value history are taken off this
+ list. */
+ struct value *next;
+
+ /* Register number if the value is from a register. Is not kept
+ if you take a field of a structure that is stored in a
+ register. Shouldn't it be? */
+ short regno;
+ /* If zero, contents of this value are in the contents field.
+ If nonzero, contents are in inferior memory at address
+ in the location.address field plus the offset field
+ (and the lval field should be lval_memory).
+
+ WARNING: This field is used by the code which handles
+ watchpoints (see breakpoint.c) to decide whether a particular
+ value can be watched by hardware watchpoints. If the lazy flag
+ is set for some member of a value chain, it is assumed that
+ this member of the chain doesn't need to be watched as part of
+ watching the value itself. This is how GDB avoids watching the
+ entire struct or array when the user wants to watch a single
+ struct member or array element. If you ever change the way
+ lazy flag is set and reset, be sure to consider this use as
+ well! */
+ char lazy;
+ /* If nonzero, this is the value of a variable which does not
+ actually exist in the program. */
+ char optimized_out;
+ /* The BFD section associated with this value. */
+ asection *bfd_section;
+ /* Actual contents of the value. For use of this value; setting
+ it uses the stuff above. Not valid if lazy is nonzero.
+ Target byte-order. We force it to be aligned properly for any
+ possible value. Note that a value therefore extends beyond
+ what is declared here. */
+ union
+ {
+ long contents[1];
+ DOUBLEST force_doublest_align;
+ LONGEST force_longest_align;
+ CORE_ADDR force_core_addr_align;
+ void *force_pointer_align;
+ }
+ aligner;
+ /* Do not add any new members here -- contents above will trash them */
+ };
+
+#define VALUE_TYPE(val) (val)->type
+#define VALUE_ENCLOSING_TYPE(val) (val)->enclosing_type
+#define VALUE_LAZY(val) (val)->lazy
+/* VALUE_CONTENTS and VALUE_CONTENTS_RAW both return the address of
+ the gdb buffer used to hold a copy of the contents of the lval.
+ VALUE_CONTENTS is used when the contents of the buffer are needed --
+ it uses value_fetch_lazy() to load the buffer from the process being
+ debugged if it hasn't already been loaded. VALUE_CONTENTS_RAW is
+ used when data is being stored into the buffer, or when it is
+ certain that the contents of the buffer are valid.
+ Note: The contents pointer is adjusted by the offset required to
+ get to the real subobject, if the value happens to represent
+ something embedded in a larger run-time object. */
+
+#define VALUE_CONTENTS_RAW(val) ((char *) (val)->aligner.contents + (val)->embedded_offset)
+#define VALUE_CONTENTS(val) ((void)(VALUE_LAZY(val) && value_fetch_lazy(val)),\
+ VALUE_CONTENTS_RAW(val))
+
+/* The ALL variants of the above two macros do not adjust the returned
+ pointer by the embedded_offset value. */
+
+#define VALUE_CONTENTS_ALL_RAW(val) ((char *) (val)->aligner.contents)
+#define VALUE_CONTENTS_ALL(val) ((void) (VALUE_LAZY(val) && value_fetch_lazy(val)),\
+ VALUE_CONTENTS_ALL_RAW(val))
+
+
+extern int value_fetch_lazy (struct value *val);
+
+#define VALUE_LVAL(val) (val)->lval
+#define VALUE_ADDRESS(val) (val)->location.address
+#define VALUE_INTERNALVAR(val) (val)->location.internalvar
+#define VALUE_FRAME_REGNUM(val) ((val)->location.regnum)
+#define VALUE_FRAME(val) ((val)->frame_addr)
+#define VALUE_OFFSET(val) (val)->offset
+#define VALUE_BITSIZE(val) (val)->bitsize
+#define VALUE_BITPOS(val) (val)->bitpos
+#define VALUE_NEXT(val) (val)->next
+#define VALUE_REGNO(val) (val)->regno
+#define VALUE_OPTIMIZED_OUT(val) ((val)->optimized_out)
+#define VALUE_EMBEDDED_OFFSET(val) ((val)->embedded_offset)
+#define VALUE_POINTED_TO_OFFSET(val) ((val)->pointed_to_offset)
+#define VALUE_BFD_SECTION(val) ((val)->bfd_section)
+
+/* Convert a REF to the object referenced. */
+
+#define COERCE_REF(arg) \
+do { struct type *value_type_arg_tmp = check_typedef (VALUE_TYPE (arg));\
+ if (TYPE_CODE (value_type_arg_tmp) == TYPE_CODE_REF) \
+ arg = value_at_lazy (TYPE_TARGET_TYPE (value_type_arg_tmp), \
+ unpack_pointer (VALUE_TYPE (arg), \
+ VALUE_CONTENTS (arg)), \
+ VALUE_BFD_SECTION (arg)); \
+ } while (0)
+
+/* If ARG is an array, convert it to a pointer.
+ If ARG is an enum, convert it to an integer.
+ If ARG is a function, convert it to a function pointer.
+
+ References are dereferenced. */
+
+#define COERCE_ARRAY(arg) \
+do { COERCE_REF(arg); \
+ if (current_language->c_style_arrays \
+ && TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ARRAY) \
+ arg = value_coerce_array (arg); \
+ if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_FUNC) \
+ arg = value_coerce_function (arg); \
+} while (0)
+
+#define COERCE_NUMBER(arg) \
+ do { COERCE_ARRAY(arg); COERCE_ENUM(arg); } while (0)
+
+#define COERCE_VARYING_ARRAY(arg, real_arg_type) \
+{ if (chill_varying_type (real_arg_type)) \
+ arg = varying_to_slice (arg), real_arg_type = VALUE_TYPE (arg); }
+
+/* If ARG is an enum, convert it to an integer. */
+
+#define COERCE_ENUM(arg) { \
+ if (TYPE_CODE (check_typedef (VALUE_TYPE (arg))) == TYPE_CODE_ENUM) \
+ arg = value_cast (builtin_type_unsigned_int, arg); \
+}
+
+/* Internal variables (variables for convenience of use of debugger)
+ are recorded as a chain of these structures. */
+
+struct internalvar
+ {
+ struct internalvar *next;
+ char *name;
+ struct value *value;
+ };
+
+/* Pointer to member function. Depends on compiler implementation. */
+
+#define METHOD_PTR_IS_VIRTUAL(ADDR) ((ADDR) & 0x80000000)
+#define METHOD_PTR_FROM_VOFFSET(OFFSET) (0x80000000 + (OFFSET))
+#define METHOD_PTR_TO_VOFFSET(ADDR) (~0x80000000 & (ADDR))
+
+
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+
+struct frame_info;
+struct fn_field;
+
+extern void print_address_demangle (CORE_ADDR, struct ui_file *, int);
+
+extern LONGEST value_as_long (struct value *val);
+
+extern DOUBLEST value_as_double (struct value *val);
+
+extern CORE_ADDR value_as_address (struct value *val);
+
+extern LONGEST unpack_long (struct type *type, char *valaddr);
+
+extern DOUBLEST unpack_double (struct type *type, char *valaddr, int *invp);
+
+extern CORE_ADDR unpack_pointer (struct type *type, char *valaddr);
+
+extern LONGEST unpack_field_as_long (struct type *type, char *valaddr,
+ int fieldno);
+
+extern struct value *value_from_longest (struct type *type, LONGEST num);
+
+extern struct value *value_from_pointer (struct type *type, CORE_ADDR addr);
+
+extern struct value *value_from_double (struct type *type, DOUBLEST num);
+
+extern struct value *value_from_string (char *string);
+
+extern struct value *value_at (struct type *type, CORE_ADDR addr,
+ asection * sect);
+
+extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr,
+ asection * sect);
+
+extern struct value *value_from_register (struct type *type, int regnum,
+ struct frame_info *frame);
+
+extern struct value *value_of_variable (struct symbol *var, struct block *b);
+
+extern struct value *value_of_register (int regnum,
+ struct frame_info *frame);
+
+extern int symbol_read_needs_frame (struct symbol *);
+
+extern struct value *read_var_value (struct symbol *var,
+ struct frame_info *frame);
+
+extern struct value *locate_var_value (struct symbol *var,
+ struct frame_info *frame);
+
+extern struct value *allocate_value (struct type *type);
+
+extern struct value *allocate_repeat_value (struct type *type, int count);
+
+extern struct value *value_change_enclosing_type (struct value *val,
+ struct type *new_type);
+
+extern struct value *value_mark (void);
+
+extern void value_free_to_mark (struct value *mark);
+
+extern struct value *value_string (char *ptr, int len);
+extern struct value *value_bitstring (char *ptr, int len);
+
+extern struct value *value_array (int lowbound, int highbound,
+ struct value ** elemvec);
+
+extern struct value *value_concat (struct value *arg1, struct value *arg2);
+
+extern struct value *value_binop (struct value *arg1, struct value *arg2,
+ enum exp_opcode op);
+
+extern struct value *value_add (struct value *arg1, struct value *arg2);
+
+extern struct value *value_sub (struct value *arg1, struct value *arg2);
+
+extern struct value *value_coerce_array (struct value *arg1);
+
+extern struct value *value_coerce_function (struct value *arg1);
+
+extern struct value *value_ind (struct value *arg1);
+
+extern struct value *value_addr (struct value *arg1);
+
+extern struct value *value_assign (struct value *toval, struct value *fromval);
+
+extern struct value *value_neg (struct value *arg1);
+
+extern struct value *value_complement (struct value *arg1);
+
+extern struct value *value_struct_elt (struct value **argp,
+ struct value **args,
+ char *name, int *static_memfuncp,
+ char *err);
+
+extern struct value *value_struct_elt_for_reference (struct type *domain,
+ int offset,
+ struct type *curtype,
+ char *name,
+ struct type *intype);
+
+extern struct value *value_static_field (struct type *type, int fieldno);
+
+extern struct fn_field *value_find_oload_method_list (struct value **, char *,
+ int, int *,
+ struct type **, int *);
+
+extern int find_overload_match (struct type **arg_types, int nargs,
+ char *name, int method, int lax,
+ struct value **objp, struct symbol *fsym,
+ struct value **valp, struct symbol **symp,
+ int *staticp);
+
+extern struct value *value_field (struct value *arg1, int fieldno);
+
+extern struct value *value_primitive_field (struct value *arg1, int offset,
+ int fieldno,
+ struct type *arg_type);
+
+
+extern struct type *value_rtti_target_type (struct value *, int *, int *,
+ int *);
+
+extern struct value *value_full_object (struct value *, struct type *, int,
+ int, int);
+
+extern struct value *value_cast (struct type *type, struct value *arg2);
+
+extern struct value *value_zero (struct type *type, enum lval_type lv);
+
+extern struct value *value_repeat (struct value *arg1, int count);
+
+extern struct value *value_subscript (struct value *array, struct value *idx);
+
+extern struct value *value_being_returned (struct type *valtype,
+ char *retbuf, int struct_return);
+
+extern struct value *value_in (struct value *element, struct value *set);
+
+extern int value_bit_index (struct type *type, char *addr, int index);
+
+extern int using_struct_return (struct value *function, CORE_ADDR funcaddr,
+ struct type *value_type, int gcc_p);
+
+extern void set_return_value (struct value *val);
+
+extern struct value *evaluate_expression (struct expression *exp);
+
+extern struct value *evaluate_type (struct expression *exp);
+
+extern struct value *evaluate_subexp_with_coercion (struct expression *,
+ int *, enum noside);
+
+extern struct value *parse_and_eval (char *exp);
+
+extern struct value *parse_to_comma_and_eval (char **expp);
+
+extern struct type *parse_and_eval_type (char *p, int length);
+
+extern CORE_ADDR parse_and_eval_address (char *exp);
+
+extern CORE_ADDR parse_and_eval_address_1 (char **expptr);
+
+extern LONGEST parse_and_eval_long (char *exp);
+
+extern struct value *access_value_history (int num);
+
+extern struct value *value_of_internalvar (struct internalvar *var);
+
+extern void set_internalvar (struct internalvar *var, struct value *val);
+
+extern void set_internalvar_component (struct internalvar *var,
+ int offset,
+ int bitpos, int bitsize,
+ struct value *newvalue);
+
+extern struct internalvar *lookup_internalvar (char *name);
+
+extern int value_equal (struct value *arg1, struct value *arg2);
+
+extern int value_less (struct value *arg1, struct value *arg2);
+
+extern int value_logical_not (struct value *arg1);
+
+/* C++ */
+
+extern struct value *value_of_this (int complain);
+
+extern struct value *value_x_binop (struct value *arg1, struct value *arg2,
+ enum exp_opcode op,
+ enum exp_opcode otherop,
+ enum noside noside);
+
+extern struct value *value_x_unop (struct value *arg1, enum exp_opcode op,
+ enum noside noside);
+
+extern struct value *value_fn_field (struct value ** arg1p, struct fn_field *f,
+ int j, struct type *type, int offset);
+
+extern int binop_user_defined_p (enum exp_opcode op, struct value *arg1,
+ struct value *arg2);
+
+extern int unop_user_defined_p (enum exp_opcode op, struct value *arg1);
+
+extern int destructor_name_p (const char *name, const struct type *type);
+
+#define value_free(val) xfree (val)
+
+extern void free_all_values (void);
+
+extern void release_value (struct value *val);
+
+extern int record_latest_value (struct value *val);
+
+extern void
+modify_field (char *addr, LONGEST fieldval, int bitpos, int bitsize);
+
+extern void type_print (struct type * type, char *varstring,
+ struct ui_file * stream, int show);
+
+extern char *baseclass_addr (struct type *type, int index, char *valaddr,
+ struct value **valuep, int *errp);
+
+extern void print_longest (struct ui_file * stream, int format,
+ int use_local, LONGEST val);
+
+extern void print_floating (char *valaddr, struct type * type,
+ struct ui_file * stream);
+
+extern int value_print (struct value *val, struct ui_file *stream, int format,
+ enum val_prettyprint pretty);
+
+extern void value_print_array_elements (struct value *val,
+ struct ui_file *stream, int format,
+ enum val_prettyprint pretty);
+
+extern struct value *value_release_to_mark (struct value *mark);
+
+extern int val_print (struct type * type, char *valaddr,
+ int embedded_offset, CORE_ADDR address,
+ struct ui_file * stream, int format,
+ int deref_ref, int recurse,
+ enum val_prettyprint pretty);
+
+extern int val_print_string (CORE_ADDR addr, int len, int width, struct ui_file *stream);
+
+extern void print_variable_value (struct symbol * var,
+ struct frame_info * frame,
+ struct ui_file *stream);
+
+extern int check_field (struct value *, const char *);
+
+extern void typedef_print (struct type * type, struct symbol * news,
+ struct ui_file * stream);
+
+extern char *internalvar_name (struct internalvar *var);
+
+extern void clear_value_history (void);
+
+extern void clear_internalvars (void);
+
+/* From values.c */
+
+extern struct value *value_copy (struct value *);
+
+/* From valops.c */
+
+extern struct value *varying_to_slice (struct value *);
+
+extern struct value *value_slice (struct value *, int, int);
+
+extern struct value *call_function_by_hand (struct value *, int,
+ struct value **);
+
+extern int default_coerce_float_to_double (struct type *, struct type *);
+
+extern int standard_coerce_float_to_double (struct type *, struct type *);
+
+extern struct value *value_literal_complex (struct value *, struct value *,
+ struct type *);
+
+extern void find_rt_vbase_offset (struct type *, struct type *, char *, int,
+ int *, int *);
+
+extern struct value *find_function_in_inferior (char *);
+
+extern struct value *value_allocate_space_in_inferior (int);
+
+extern CORE_ADDR default_push_arguments (int nargs, struct value ** args,
+ CORE_ADDR sp, int struct_return,
+ CORE_ADDR struct_addr);
+
+#endif /* !defined (VALUE_H) */
diff --git a/gdb/values.c b/gdb/values.c
new file mode 100644
index 00000000000..225dd218bb5
--- /dev/null
+++ b/gdb/values.c
@@ -0,0 +1,1335 @@
+/* Low level packing and unpacking of values for GDB, the GNU Debugger.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2002.
+ 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 "defs.h"
+#include "gdb_string.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "language.h"
+#include "scm-lang.h"
+#include "demangle.h"
+#include "doublest.h"
+#include "gdb_assert.h"
+
+/* Prototypes for exported functions. */
+
+void _initialize_values (void);
+
+/* Prototypes for local functions. */
+
+static void show_values (char *, int);
+
+static void show_convenience (char *, int);
+
+
+/* The value-history records all the values printed
+ by print commands during this session. Each chunk
+ records 60 consecutive values. The first chunk on
+ the chain records the most recent values.
+ The total number of values is in value_history_count. */
+
+#define VALUE_HISTORY_CHUNK 60
+
+struct value_history_chunk
+ {
+ struct value_history_chunk *next;
+ struct value *values[VALUE_HISTORY_CHUNK];
+ };
+
+/* Chain of chunks now in use. */
+
+static struct value_history_chunk *value_history_chain;
+
+static int value_history_count; /* Abs number of last entry stored */
+
+/* List of all value objects currently allocated
+ (except for those released by calls to release_value)
+ This is so they can be freed after each command. */
+
+static struct value *all_values;
+
+/* Allocate a value that has the correct length for type TYPE. */
+
+struct value *
+allocate_value (struct type *type)
+{
+ struct value *val;
+ struct type *atype = check_typedef (type);
+
+ val = (struct value *) xmalloc (sizeof (struct value) + TYPE_LENGTH (atype));
+ VALUE_NEXT (val) = all_values;
+ all_values = val;
+ VALUE_TYPE (val) = type;
+ VALUE_ENCLOSING_TYPE (val) = type;
+ VALUE_LVAL (val) = not_lval;
+ VALUE_ADDRESS (val) = 0;
+ VALUE_FRAME (val) = 0;
+ VALUE_OFFSET (val) = 0;
+ VALUE_BITPOS (val) = 0;
+ VALUE_BITSIZE (val) = 0;
+ VALUE_REGNO (val) = -1;
+ VALUE_LAZY (val) = 0;
+ VALUE_OPTIMIZED_OUT (val) = 0;
+ VALUE_BFD_SECTION (val) = NULL;
+ VALUE_EMBEDDED_OFFSET (val) = 0;
+ VALUE_POINTED_TO_OFFSET (val) = 0;
+ val->modifiable = 1;
+ return val;
+}
+
+/* Allocate a value that has the correct length
+ for COUNT repetitions type TYPE. */
+
+struct value *
+allocate_repeat_value (struct type *type, int count)
+{
+ int low_bound = current_language->string_lower_bound; /* ??? */
+ /* FIXME-type-allocation: need a way to free this type when we are
+ done with it. */
+ struct type *range_type
+ = create_range_type ((struct type *) NULL, builtin_type_int,
+ low_bound, count + low_bound - 1);
+ /* FIXME-type-allocation: need a way to free this type when we are
+ done with it. */
+ return allocate_value (create_array_type ((struct type *) NULL,
+ type, range_type));
+}
+
+/* Return a mark in the value chain. All values allocated after the
+ mark is obtained (except for those released) are subject to being freed
+ if a subsequent value_free_to_mark is passed the mark. */
+struct value *
+value_mark (void)
+{
+ return all_values;
+}
+
+/* Free all values allocated since MARK was obtained by value_mark
+ (except for those released). */
+void
+value_free_to_mark (struct value *mark)
+{
+ struct value *val;
+ struct value *next;
+
+ for (val = all_values; val && val != mark; val = next)
+ {
+ next = VALUE_NEXT (val);
+ value_free (val);
+ }
+ all_values = val;
+}
+
+/* Free all the values that have been allocated (except for those released).
+ Called after each command, successful or not. */
+
+void
+free_all_values (void)
+{
+ struct value *val;
+ struct value *next;
+
+ for (val = all_values; val; val = next)
+ {
+ next = VALUE_NEXT (val);
+ value_free (val);
+ }
+
+ all_values = 0;
+}
+
+/* Remove VAL from the chain all_values
+ so it will not be freed automatically. */
+
+void
+release_value (struct value *val)
+{
+ struct value *v;
+
+ if (all_values == val)
+ {
+ all_values = val->next;
+ return;
+ }
+
+ for (v = all_values; v; v = v->next)
+ {
+ if (v->next == val)
+ {
+ v->next = val->next;
+ break;
+ }
+ }
+}
+
+/* Release all values up to mark */
+struct value *
+value_release_to_mark (struct value *mark)
+{
+ struct value *val;
+ struct value *next;
+
+ for (val = next = all_values; next; next = VALUE_NEXT (next))
+ if (VALUE_NEXT (next) == mark)
+ {
+ all_values = VALUE_NEXT (next);
+ VALUE_NEXT (next) = 0;
+ return val;
+ }
+ all_values = 0;
+ return val;
+}
+
+/* Return a copy of the value ARG.
+ It contains the same contents, for same memory address,
+ but it's a different block of storage. */
+
+struct value *
+value_copy (struct value *arg)
+{
+ register struct type *encl_type = VALUE_ENCLOSING_TYPE (arg);
+ struct value *val = allocate_value (encl_type);
+ VALUE_TYPE (val) = VALUE_TYPE (arg);
+ VALUE_LVAL (val) = VALUE_LVAL (arg);
+ VALUE_ADDRESS (val) = VALUE_ADDRESS (arg);
+ VALUE_OFFSET (val) = VALUE_OFFSET (arg);
+ VALUE_BITPOS (val) = VALUE_BITPOS (arg);
+ VALUE_BITSIZE (val) = VALUE_BITSIZE (arg);
+ VALUE_FRAME (val) = VALUE_FRAME (arg);
+ VALUE_REGNO (val) = VALUE_REGNO (arg);
+ VALUE_LAZY (val) = VALUE_LAZY (arg);
+ VALUE_OPTIMIZED_OUT (val) = VALUE_OPTIMIZED_OUT (arg);
+ VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (arg);
+ VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (arg);
+ VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (arg);
+ val->modifiable = arg->modifiable;
+ if (!VALUE_LAZY (val))
+ {
+ memcpy (VALUE_CONTENTS_ALL_RAW (val), VALUE_CONTENTS_ALL_RAW (arg),
+ TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg)));
+
+ }
+ return val;
+}
+
+/* Access to the value history. */
+
+/* Record a new value in the value history.
+ Returns the absolute history index of the entry.
+ Result of -1 indicates the value was not saved; otherwise it is the
+ value history index of this new item. */
+
+int
+record_latest_value (struct value *val)
+{
+ int i;
+
+ /* We don't want this value to have anything to do with the inferior anymore.
+ In particular, "set $1 = 50" should not affect the variable from which
+ the value was taken, and fast watchpoints should be able to assume that
+ a value on the value history never changes. */
+ if (VALUE_LAZY (val))
+ value_fetch_lazy (val);
+ /* We preserve VALUE_LVAL so that the user can find out where it was fetched
+ from. This is a bit dubious, because then *&$1 does not just return $1
+ but the current contents of that location. c'est la vie... */
+ val->modifiable = 0;
+ release_value (val);
+
+ /* Here we treat value_history_count as origin-zero
+ and applying to the value being stored now. */
+
+ i = value_history_count % VALUE_HISTORY_CHUNK;
+ if (i == 0)
+ {
+ struct value_history_chunk *new
+ = (struct value_history_chunk *)
+ xmalloc (sizeof (struct value_history_chunk));
+ memset (new->values, 0, sizeof new->values);
+ new->next = value_history_chain;
+ value_history_chain = new;
+ }
+
+ value_history_chain->values[i] = val;
+
+ /* Now we regard value_history_count as origin-one
+ and applying to the value just stored. */
+
+ return ++value_history_count;
+}
+
+/* Return a copy of the value in the history with sequence number NUM. */
+
+struct value *
+access_value_history (int num)
+{
+ struct value_history_chunk *chunk;
+ register int i;
+ register int absnum = num;
+
+ if (absnum <= 0)
+ absnum += value_history_count;
+
+ if (absnum <= 0)
+ {
+ if (num == 0)
+ error ("The history is empty.");
+ else if (num == 1)
+ error ("There is only one value in the history.");
+ else
+ error ("History does not go back to $$%d.", -num);
+ }
+ if (absnum > value_history_count)
+ error ("History has not yet reached $%d.", absnum);
+
+ absnum--;
+
+ /* Now absnum is always absolute and origin zero. */
+
+ chunk = value_history_chain;
+ for (i = (value_history_count - 1) / VALUE_HISTORY_CHUNK - absnum / VALUE_HISTORY_CHUNK;
+ i > 0; i--)
+ chunk = chunk->next;
+
+ return value_copy (chunk->values[absnum % VALUE_HISTORY_CHUNK]);
+}
+
+/* Clear the value history entirely.
+ Must be done when new symbol tables are loaded,
+ because the type pointers become invalid. */
+
+void
+clear_value_history (void)
+{
+ struct value_history_chunk *next;
+ register int i;
+ struct value *val;
+
+ while (value_history_chain)
+ {
+ for (i = 0; i < VALUE_HISTORY_CHUNK; i++)
+ if ((val = value_history_chain->values[i]) != NULL)
+ xfree (val);
+ next = value_history_chain->next;
+ xfree (value_history_chain);
+ value_history_chain = next;
+ }
+ value_history_count = 0;
+}
+
+static void
+show_values (char *num_exp, int from_tty)
+{
+ register int i;
+ struct value *val;
+ static int num = 1;
+
+ if (num_exp)
+ {
+ /* "info history +" should print from the stored position.
+ "info history <exp>" should print around value number <exp>. */
+ if (num_exp[0] != '+' || num_exp[1] != '\0')
+ num = parse_and_eval_long (num_exp) - 5;
+ }
+ else
+ {
+ /* "info history" means print the last 10 values. */
+ num = value_history_count - 9;
+ }
+
+ if (num <= 0)
+ num = 1;
+
+ for (i = num; i < num + 10 && i <= value_history_count; i++)
+ {
+ val = access_value_history (i);
+ printf_filtered ("$%d = ", i);
+ value_print (val, gdb_stdout, 0, Val_pretty_default);
+ printf_filtered ("\n");
+ }
+
+ /* The next "info history +" should start after what we just printed. */
+ num += 10;
+
+ /* Hitting just return after this command should do the same thing as
+ "info history +". If num_exp is null, this is unnecessary, since
+ "info history +" is not useful after "info history". */
+ if (from_tty && num_exp)
+ {
+ num_exp[0] = '+';
+ num_exp[1] = '\0';
+ }
+}
+
+/* Internal variables. These are variables within the debugger
+ that hold values assigned by debugger commands.
+ The user refers to them with a '$' prefix
+ that does not appear in the variable names stored internally. */
+
+static struct internalvar *internalvars;
+
+/* Look up an internal variable with name NAME. NAME should not
+ normally include a dollar sign.
+
+ If the specified internal variable does not exist,
+ one is created, with a void value. */
+
+struct internalvar *
+lookup_internalvar (char *name)
+{
+ register struct internalvar *var;
+
+ for (var = internalvars; var; var = var->next)
+ if (STREQ (var->name, name))
+ return var;
+
+ var = (struct internalvar *) xmalloc (sizeof (struct internalvar));
+ var->name = concat (name, NULL);
+ var->value = allocate_value (builtin_type_void);
+ release_value (var->value);
+ var->next = internalvars;
+ internalvars = var;
+ return var;
+}
+
+struct value *
+value_of_internalvar (struct internalvar *var)
+{
+ struct value *val;
+
+#ifdef IS_TRAPPED_INTERNALVAR
+ if (IS_TRAPPED_INTERNALVAR (var->name))
+ return VALUE_OF_TRAPPED_INTERNALVAR (var);
+#endif
+
+ val = value_copy (var->value);
+ if (VALUE_LAZY (val))
+ value_fetch_lazy (val);
+ VALUE_LVAL (val) = lval_internalvar;
+ VALUE_INTERNALVAR (val) = var;
+ return val;
+}
+
+void
+set_internalvar_component (struct internalvar *var, int offset, int bitpos,
+ int bitsize, struct value *newval)
+{
+ register char *addr = VALUE_CONTENTS (var->value) + offset;
+
+#ifdef IS_TRAPPED_INTERNALVAR
+ if (IS_TRAPPED_INTERNALVAR (var->name))
+ SET_TRAPPED_INTERNALVAR (var, newval, bitpos, bitsize, offset);
+#endif
+
+ if (bitsize)
+ modify_field (addr, value_as_long (newval),
+ bitpos, bitsize);
+ else
+ memcpy (addr, VALUE_CONTENTS (newval), TYPE_LENGTH (VALUE_TYPE (newval)));
+}
+
+void
+set_internalvar (struct internalvar *var, struct value *val)
+{
+ struct value *newval;
+
+#ifdef IS_TRAPPED_INTERNALVAR
+ if (IS_TRAPPED_INTERNALVAR (var->name))
+ SET_TRAPPED_INTERNALVAR (var, val, 0, 0, 0);
+#endif
+
+ newval = value_copy (val);
+ newval->modifiable = 1;
+
+ /* Force the value to be fetched from the target now, to avoid problems
+ later when this internalvar is referenced and the target is gone or
+ has changed. */
+ if (VALUE_LAZY (newval))
+ value_fetch_lazy (newval);
+
+ /* Begin code which must not call error(). If var->value points to
+ something free'd, an error() obviously leaves a dangling pointer.
+ But we also get a danling pointer if var->value points to
+ something in the value chain (i.e., before release_value is
+ called), because after the error free_all_values will get called before
+ long. */
+ xfree (var->value);
+ var->value = newval;
+ release_value (newval);
+ /* End code which must not call error(). */
+}
+
+char *
+internalvar_name (struct internalvar *var)
+{
+ return var->name;
+}
+
+/* Free all internalvars. Done when new symtabs are loaded,
+ because that makes the values invalid. */
+
+void
+clear_internalvars (void)
+{
+ register struct internalvar *var;
+
+ while (internalvars)
+ {
+ var = internalvars;
+ internalvars = var->next;
+ xfree (var->name);
+ xfree (var->value);
+ xfree (var);
+ }
+}
+
+static void
+show_convenience (char *ignore, int from_tty)
+{
+ register struct internalvar *var;
+ int varseen = 0;
+
+ for (var = internalvars; var; var = var->next)
+ {
+#ifdef IS_TRAPPED_INTERNALVAR
+ if (IS_TRAPPED_INTERNALVAR (var->name))
+ continue;
+#endif
+ if (!varseen)
+ {
+ varseen = 1;
+ }
+ printf_filtered ("$%s = ", var->name);
+ value_print (var->value, gdb_stdout, 0, Val_pretty_default);
+ printf_filtered ("\n");
+ }
+ if (!varseen)
+ printf_unfiltered ("No debugger convenience variables now defined.\n\
+Convenience variables have names starting with \"$\";\n\
+use \"set\" as in \"set $foo = 5\" to define them.\n");
+}
+
+/* Extract a value as a C number (either long or double).
+ Knows how to convert fixed values to double, or
+ floating values to long.
+ Does not deallocate the value. */
+
+LONGEST
+value_as_long (struct value *val)
+{
+ /* This coerces arrays and functions, which is necessary (e.g.
+ in disassemble_command). It also dereferences references, which
+ I suspect is the most logical thing to do. */
+ COERCE_ARRAY (val);
+ return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
+}
+
+DOUBLEST
+value_as_double (struct value *val)
+{
+ DOUBLEST foo;
+ int inv;
+
+ foo = unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &inv);
+ if (inv)
+ error ("Invalid floating value found in program.");
+ return foo;
+}
+/* Extract a value as a C pointer. Does not deallocate the value.
+ Note that val's type may not actually be a pointer; value_as_long
+ handles all the cases. */
+CORE_ADDR
+value_as_address (struct value *val)
+{
+ /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure
+ whether we want this to be true eventually. */
+#if 0
+ /* ADDR_BITS_REMOVE is wrong if we are being called for a
+ non-address (e.g. argument to "signal", "info break", etc.), or
+ for pointers to char, in which the low bits *are* significant. */
+ return ADDR_BITS_REMOVE (value_as_long (val));
+#else
+
+ /* There are several targets (IA-64, PowerPC, and others) which
+ don't represent pointers to functions as simply the address of
+ the function's entry point. For example, on the IA-64, a
+ function pointer points to a two-word descriptor, generated by
+ the linker, which contains the function's entry point, and the
+ value the IA-64 "global pointer" register should have --- to
+ support position-independent code. The linker generates
+ descriptors only for those functions whose addresses are taken.
+
+ On such targets, it's difficult for GDB to convert an arbitrary
+ function address into a function pointer; it has to either find
+ an existing descriptor for that function, or call malloc and
+ build its own. On some targets, it is impossible for GDB to
+ build a descriptor at all: the descriptor must contain a jump
+ instruction; data memory cannot be executed; and code memory
+ cannot be modified.
+
+ Upon entry to this function, if VAL is a value of type `function'
+ (that is, TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC), then
+ VALUE_ADDRESS (val) is the address of the function. This is what
+ you'll get if you evaluate an expression like `main'. The call
+ to COERCE_ARRAY below actually does all the usual unary
+ conversions, which includes converting values of type `function'
+ to `pointer to function'. This is the challenging conversion
+ discussed above. Then, `unpack_long' will convert that pointer
+ back into an address.
+
+ So, suppose the user types `disassemble foo' on an architecture
+ with a strange function pointer representation, on which GDB
+ cannot build its own descriptors, and suppose further that `foo'
+ has no linker-built descriptor. The address->pointer conversion
+ will signal an error and prevent the command from running, even
+ though the next step would have been to convert the pointer
+ directly back into the same address.
+
+ The following shortcut avoids this whole mess. If VAL is a
+ function, just return its address directly. */
+ if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC
+ || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_METHOD)
+ return VALUE_ADDRESS (val);
+
+ COERCE_ARRAY (val);
+
+ /* Some architectures (e.g. Harvard), map instruction and data
+ addresses onto a single large unified address space. For
+ instance: An architecture may consider a large integer in the
+ range 0x10000000 .. 0x1000ffff to already represent a data
+ addresses (hence not need a pointer to address conversion) while
+ a small integer would still need to be converted integer to
+ pointer to address. Just assume such architectures handle all
+ integer conversions in a single function. */
+
+ /* JimB writes:
+
+ I think INTEGER_TO_ADDRESS is a good idea as proposed --- but we
+ must admonish GDB hackers to make sure its behavior matches the
+ compiler's, whenever possible.
+
+ In general, I think GDB should evaluate expressions the same way
+ the compiler does. When the user copies an expression out of
+ their source code and hands it to a `print' command, they should
+ get the same value the compiler would have computed. Any
+ deviation from this rule can cause major confusion and annoyance,
+ and needs to be justified carefully. In other words, GDB doesn't
+ really have the freedom to do these conversions in clever and
+ useful ways.
+
+ AndrewC pointed out that users aren't complaining about how GDB
+ casts integers to pointers; they are complaining that they can't
+ take an address from a disassembly listing and give it to `x/i'.
+ This is certainly important.
+
+ Adding an architecture method like INTEGER_TO_ADDRESS certainly
+ makes it possible for GDB to "get it right" in all circumstances
+ --- the target has complete control over how things get done, so
+ people can Do The Right Thing for their target without breaking
+ anyone else. The standard doesn't specify how integers get
+ converted to pointers; usually, the ABI doesn't either, but
+ ABI-specific code is a more reasonable place to handle it. */
+
+ if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_PTR
+ && TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_REF
+ && INTEGER_TO_ADDRESS_P ())
+ return INTEGER_TO_ADDRESS (VALUE_TYPE (val), VALUE_CONTENTS (val));
+
+ return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
+#endif
+}
+
+/* Unpack raw data (copied from debugee, target byte order) at VALADDR
+ as a long, or as a double, assuming the raw data is described
+ by type TYPE. Knows how to convert different sizes of values
+ and can convert between fixed and floating point. We don't assume
+ any alignment for the raw data. Return value is in host byte order.
+
+ If you want functions and arrays to be coerced to pointers, and
+ references to be dereferenced, call value_as_long() instead.
+
+ C++: It is assumed that the front-end has taken care of
+ all matters concerning pointers to members. A pointer
+ to member which reaches here is considered to be equivalent
+ to an INT (or some size). After all, it is only an offset. */
+
+LONGEST
+unpack_long (struct type *type, char *valaddr)
+{
+ register enum type_code code = TYPE_CODE (type);
+ register int len = TYPE_LENGTH (type);
+ register int nosign = TYPE_UNSIGNED (type);
+
+ if (current_language->la_language == language_scm
+ && is_scmvalue_type (type))
+ return scm_unpack (type, valaddr, TYPE_CODE_INT);
+
+ switch (code)
+ {
+ case TYPE_CODE_TYPEDEF:
+ return unpack_long (check_typedef (type), valaddr);
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ if (nosign)
+ return extract_unsigned_integer (valaddr, len);
+ else
+ return extract_signed_integer (valaddr, len);
+
+ case TYPE_CODE_FLT:
+ return extract_typed_floating (valaddr, type);
+
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_REF:
+ /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure
+ whether we want this to be true eventually. */
+ return extract_typed_address (valaddr, type);
+
+ case TYPE_CODE_MEMBER:
+ error ("not implemented: member types in unpack_long");
+
+ default:
+ error ("Value can't be converted to integer.");
+ }
+ return 0; /* Placate lint. */
+}
+
+/* Return a double value from the specified type and address.
+ INVP points to an int which is set to 0 for valid value,
+ 1 for invalid value (bad float format). In either case,
+ the returned double is OK to use. Argument is in target
+ format, result is in host format. */
+
+DOUBLEST
+unpack_double (struct type *type, char *valaddr, int *invp)
+{
+ enum type_code code;
+ int len;
+ int nosign;
+
+ *invp = 0; /* Assume valid. */
+ CHECK_TYPEDEF (type);
+ code = TYPE_CODE (type);
+ len = TYPE_LENGTH (type);
+ nosign = TYPE_UNSIGNED (type);
+ if (code == TYPE_CODE_FLT)
+ {
+ /* NOTE: cagney/2002-02-19: There was a test here to see if the
+ floating-point value was valid (using the macro
+ INVALID_FLOAT). That test/macro have been removed.
+
+ It turns out that only the VAX defined this macro and then
+ only in a non-portable way. Fixing the portability problem
+ wouldn't help since the VAX floating-point code is also badly
+ bit-rotten. The target needs to add definitions for the
+ methods TARGET_FLOAT_FORMAT and TARGET_DOUBLE_FORMAT - these
+ exactly describe the target floating-point format. The
+ problem here is that the corresponding floatformat_vax_f and
+ floatformat_vax_d values these methods should be set to are
+ also not defined either. Oops!
+
+ Hopefully someone will add both the missing floatformat
+ definitions and floatformat_is_invalid() function. */
+ return extract_typed_floating (valaddr, type);
+ }
+ else if (nosign)
+ {
+ /* Unsigned -- be sure we compensate for signed LONGEST. */
+ return (ULONGEST) unpack_long (type, valaddr);
+ }
+ else
+ {
+ /* Signed -- we are OK with unpack_long. */
+ return unpack_long (type, valaddr);
+ }
+}
+
+/* Unpack raw data (copied from debugee, target byte order) at VALADDR
+ as a CORE_ADDR, assuming the raw data is described by type TYPE.
+ We don't assume any alignment for the raw data. Return value is in
+ host byte order.
+
+ If you want functions and arrays to be coerced to pointers, and
+ references to be dereferenced, call value_as_address() instead.
+
+ C++: It is assumed that the front-end has taken care of
+ all matters concerning pointers to members. A pointer
+ to member which reaches here is considered to be equivalent
+ to an INT (or some size). After all, it is only an offset. */
+
+CORE_ADDR
+unpack_pointer (struct type *type, char *valaddr)
+{
+ /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure
+ whether we want this to be true eventually. */
+ return unpack_long (type, valaddr);
+}
+
+
+/* Get the value of the FIELDN'th field (which must be static) of TYPE. */
+
+struct value *
+value_static_field (struct type *type, int fieldno)
+{
+ CORE_ADDR addr;
+ asection *sect;
+ if (TYPE_FIELD_STATIC_HAS_ADDR (type, fieldno))
+ {
+ addr = TYPE_FIELD_STATIC_PHYSADDR (type, fieldno);
+ sect = NULL;
+ }
+ else
+ {
+ char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
+ struct symbol *sym = lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
+ if (sym == NULL)
+ {
+ /* With some compilers, e.g. HP aCC, static data members are reported
+ as non-debuggable symbols */
+ struct minimal_symbol *msym = lookup_minimal_symbol (phys_name, NULL, NULL);
+ if (!msym)
+ return NULL;
+ else
+ {
+ addr = SYMBOL_VALUE_ADDRESS (msym);
+ sect = SYMBOL_BFD_SECTION (msym);
+ }
+ }
+ else
+ {
+ /* Anything static that isn't a constant, has an address */
+ if (SYMBOL_CLASS (sym) != LOC_CONST)
+ {
+ addr = SYMBOL_VALUE_ADDRESS (sym);
+ sect = SYMBOL_BFD_SECTION (sym);
+ }
+ /* However, static const's do not, the value is already known. */
+ else
+ {
+ return value_from_longest (TYPE_FIELD_TYPE (type, fieldno), SYMBOL_VALUE (sym));
+ }
+ }
+ SET_FIELD_PHYSADDR (TYPE_FIELD (type, fieldno), addr);
+ }
+ return value_at (TYPE_FIELD_TYPE (type, fieldno), addr, sect);
+}
+
+/* Change the enclosing type of a value object VAL to NEW_ENCL_TYPE.
+ You have to be careful here, since the size of the data area for the value
+ is set by the length of the enclosing type. So if NEW_ENCL_TYPE is bigger
+ than the old enclosing type, you have to allocate more space for the data.
+ The return value is a pointer to the new version of this value structure. */
+
+struct value *
+value_change_enclosing_type (struct value *val, struct type *new_encl_type)
+{
+ if (TYPE_LENGTH (new_encl_type) <= TYPE_LENGTH (VALUE_ENCLOSING_TYPE (val)))
+ {
+ VALUE_ENCLOSING_TYPE (val) = new_encl_type;
+ return val;
+ }
+ else
+ {
+ struct value *new_val;
+ struct value *prev;
+
+ new_val = (struct value *) xrealloc (val, sizeof (struct value) + TYPE_LENGTH (new_encl_type));
+
+ /* We have to make sure this ends up in the same place in the value
+ chain as the original copy, so it's clean-up behavior is the same.
+ If the value has been released, this is a waste of time, but there
+ is no way to tell that in advance, so... */
+
+ if (val != all_values)
+ {
+ for (prev = all_values; prev != NULL; prev = prev->next)
+ {
+ if (prev->next == val)
+ {
+ prev->next = new_val;
+ break;
+ }
+ }
+ }
+
+ return new_val;
+ }
+}
+
+/* Given a value ARG1 (offset by OFFSET bytes)
+ of a struct or union type ARG_TYPE,
+ extract and return the value of one of its (non-static) fields.
+ FIELDNO says which field. */
+
+struct value *
+value_primitive_field (struct value *arg1, int offset,
+ register int fieldno, register struct type *arg_type)
+{
+ struct value *v;
+ register struct type *type;
+
+ CHECK_TYPEDEF (arg_type);
+ type = TYPE_FIELD_TYPE (arg_type, fieldno);
+
+ /* Handle packed fields */
+
+ if (TYPE_FIELD_BITSIZE (arg_type, fieldno))
+ {
+ v = value_from_longest (type,
+ unpack_field_as_long (arg_type,
+ VALUE_CONTENTS (arg1)
+ + offset,
+ fieldno));
+ VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8;
+ VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (arg_type, fieldno);
+ VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset
+ + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
+ }
+ else if (fieldno < TYPE_N_BASECLASSES (arg_type))
+ {
+ /* This field is actually a base subobject, so preserve the
+ entire object's contents for later references to virtual
+ bases, etc. */
+ v = allocate_value (VALUE_ENCLOSING_TYPE (arg1));
+ VALUE_TYPE (v) = type;
+ if (VALUE_LAZY (arg1))
+ VALUE_LAZY (v) = 1;
+ else
+ memcpy (VALUE_CONTENTS_ALL_RAW (v), VALUE_CONTENTS_ALL_RAW (arg1),
+ TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg1)));
+ VALUE_OFFSET (v) = VALUE_OFFSET (arg1);
+ VALUE_EMBEDDED_OFFSET (v)
+ = offset +
+ VALUE_EMBEDDED_OFFSET (arg1) +
+ TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
+ }
+ else
+ {
+ /* Plain old data member */
+ offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
+ v = allocate_value (type);
+ if (VALUE_LAZY (arg1))
+ VALUE_LAZY (v) = 1;
+ else
+ memcpy (VALUE_CONTENTS_RAW (v),
+ VALUE_CONTENTS_RAW (arg1) + offset,
+ TYPE_LENGTH (type));
+ VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset
+ + VALUE_EMBEDDED_OFFSET (arg1);
+ }
+ VALUE_LVAL (v) = VALUE_LVAL (arg1);
+ if (VALUE_LVAL (arg1) == lval_internalvar)
+ VALUE_LVAL (v) = lval_internalvar_component;
+ VALUE_ADDRESS (v) = VALUE_ADDRESS (arg1);
+ VALUE_REGNO (v) = VALUE_REGNO (arg1);
+/* VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset
+ + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8; */
+ return v;
+}
+
+/* Given a value ARG1 of a struct or union type,
+ extract and return the value of one of its (non-static) fields.
+ FIELDNO says which field. */
+
+struct value *
+value_field (struct value *arg1, register int fieldno)
+{
+ return value_primitive_field (arg1, 0, fieldno, VALUE_TYPE (arg1));
+}
+
+/* Return a non-virtual function as a value.
+ F is the list of member functions which contains the desired method.
+ J is an index into F which provides the desired method.
+
+ We only use the symbol for its address, so be happy with either a
+ full symbol or a minimal symbol.
+ */
+
+struct value *
+value_fn_field (struct value **arg1p, struct fn_field *f, int j, struct type *type,
+ int offset)
+{
+ struct value *v;
+ register struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);
+ char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
+ struct symbol *sym;
+ struct minimal_symbol *msym;
+
+ sym = lookup_symbol (physname, 0, VAR_NAMESPACE, 0, NULL);
+ if (sym != NULL)
+ {
+ msym = NULL;
+ }
+ else
+ {
+ gdb_assert (sym == NULL);
+ msym = lookup_minimal_symbol (physname, NULL, NULL);
+ if (msym == NULL)
+ return NULL;
+ }
+
+ v = allocate_value (ftype);
+ if (sym)
+ {
+ VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+ }
+ else
+ {
+ VALUE_ADDRESS (v) = SYMBOL_VALUE_ADDRESS (msym);
+ }
+
+ if (arg1p)
+ {
+ if (type != VALUE_TYPE (*arg1p))
+ *arg1p = value_ind (value_cast (lookup_pointer_type (type),
+ value_addr (*arg1p)));
+
+ /* Move the `this' pointer according to the offset.
+ VALUE_OFFSET (*arg1p) += offset;
+ */
+ }
+
+ return v;
+}
+
+
+/* Unpack a field FIELDNO of the specified TYPE, from the anonymous object at
+ VALADDR.
+
+ Extracting bits depends on endianness of the machine. Compute the
+ number of least significant bits to discard. For big endian machines,
+ we compute the total number of bits in the anonymous object, subtract
+ off the bit count from the MSB of the object to the MSB of the
+ bitfield, then the size of the bitfield, which leaves the LSB discard
+ count. For little endian machines, the discard count is simply the
+ number of bits from the LSB of the anonymous object to the LSB of the
+ bitfield.
+
+ If the field is signed, we also do sign extension. */
+
+LONGEST
+unpack_field_as_long (struct type *type, char *valaddr, int fieldno)
+{
+ ULONGEST val;
+ ULONGEST valmask;
+ int bitpos = TYPE_FIELD_BITPOS (type, fieldno);
+ int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);
+ int lsbcount;
+ struct type *field_type;
+
+ val = extract_unsigned_integer (valaddr + bitpos / 8, sizeof (val));
+ field_type = TYPE_FIELD_TYPE (type, fieldno);
+ CHECK_TYPEDEF (field_type);
+
+ /* Extract bits. See comment above. */
+
+ if (BITS_BIG_ENDIAN)
+ lsbcount = (sizeof val * 8 - bitpos % 8 - bitsize);
+ else
+ lsbcount = (bitpos % 8);
+ val >>= lsbcount;
+
+ /* If the field does not entirely fill a LONGEST, then zero the sign bits.
+ If the field is signed, and is negative, then sign extend. */
+
+ if ((bitsize > 0) && (bitsize < 8 * (int) sizeof (val)))
+ {
+ valmask = (((ULONGEST) 1) << bitsize) - 1;
+ val &= valmask;
+ if (!TYPE_UNSIGNED (field_type))
+ {
+ if (val & (valmask ^ (valmask >> 1)))
+ {
+ val |= ~valmask;
+ }
+ }
+ }
+ return (val);
+}
+
+/* Modify the value of a bitfield. ADDR points to a block of memory in
+ target byte order; the bitfield starts in the byte pointed to. FIELDVAL
+ is the desired value of the field, in host byte order. BITPOS and BITSIZE
+ indicate which bits (in target bit order) comprise the bitfield. */
+
+void
+modify_field (char *addr, LONGEST fieldval, int bitpos, int bitsize)
+{
+ LONGEST oword;
+
+ /* If a negative fieldval fits in the field in question, chop
+ off the sign extension bits. */
+ if (bitsize < (8 * (int) sizeof (fieldval))
+ && (~fieldval & ~((1 << (bitsize - 1)) - 1)) == 0)
+ fieldval = fieldval & ((1 << bitsize) - 1);
+
+ /* Warn if value is too big to fit in the field in question. */
+ if (bitsize < (8 * (int) sizeof (fieldval))
+ && 0 != (fieldval & ~((1 << bitsize) - 1)))
+ {
+ /* FIXME: would like to include fieldval in the message, but
+ we don't have a sprintf_longest. */
+ warning ("Value does not fit in %d bits.", bitsize);
+
+ /* Truncate it, otherwise adjoining fields may be corrupted. */
+ fieldval = fieldval & ((1 << bitsize) - 1);
+ }
+
+ oword = extract_signed_integer (addr, sizeof oword);
+
+ /* Shifting for bit field depends on endianness of the target machine. */
+ if (BITS_BIG_ENDIAN)
+ bitpos = sizeof (oword) * 8 - bitpos - bitsize;
+
+ /* Mask out old value, while avoiding shifts >= size of oword */
+ if (bitsize < 8 * (int) sizeof (oword))
+ oword &= ~(((((ULONGEST) 1) << bitsize) - 1) << bitpos);
+ else
+ oword &= ~((~(ULONGEST) 0) << bitpos);
+ oword |= fieldval << bitpos;
+
+ store_signed_integer (addr, sizeof oword, oword);
+}
+
+/* Convert C numbers into newly allocated values */
+
+struct value *
+value_from_longest (struct type *type, register LONGEST num)
+{
+ struct value *val = allocate_value (type);
+ register enum type_code code;
+ register int len;
+retry:
+ code = TYPE_CODE (type);
+ len = TYPE_LENGTH (type);
+
+ switch (code)
+ {
+ case TYPE_CODE_TYPEDEF:
+ type = check_typedef (type);
+ goto retry;
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_RANGE:
+ store_signed_integer (VALUE_CONTENTS_RAW (val), len, num);
+ break;
+
+ case TYPE_CODE_REF:
+ case TYPE_CODE_PTR:
+ store_typed_address (VALUE_CONTENTS_RAW (val), type, (CORE_ADDR) num);
+ break;
+
+ default:
+ error ("Unexpected type (%d) encountered for integer constant.", code);
+ }
+ return val;
+}
+
+
+/* Create a value representing a pointer of type TYPE to the address
+ ADDR. */
+struct value *
+value_from_pointer (struct type *type, CORE_ADDR addr)
+{
+ struct value *val = allocate_value (type);
+ store_typed_address (VALUE_CONTENTS_RAW (val), type, addr);
+ return val;
+}
+
+
+/* Create a value for a string constant to be stored locally
+ (not in the inferior's memory space, but in GDB memory).
+ This is analogous to value_from_longest, which also does not
+ use inferior memory. String shall NOT contain embedded nulls. */
+
+struct value *
+value_from_string (char *ptr)
+{
+ struct value *val;
+ int len = strlen (ptr);
+ int lowbound = current_language->string_lower_bound;
+ struct type *rangetype =
+ create_range_type ((struct type *) NULL,
+ builtin_type_int,
+ lowbound, len + lowbound - 1);
+ struct type *stringtype =
+ create_array_type ((struct type *) NULL,
+ *current_language->string_char_type,
+ rangetype);
+
+ val = allocate_value (stringtype);
+ memcpy (VALUE_CONTENTS_RAW (val), ptr, len);
+ return val;
+}
+
+struct value *
+value_from_double (struct type *type, DOUBLEST num)
+{
+ struct value *val = allocate_value (type);
+ struct type *base_type = check_typedef (type);
+ register enum type_code code = TYPE_CODE (base_type);
+ register int len = TYPE_LENGTH (base_type);
+
+ if (code == TYPE_CODE_FLT)
+ {
+ store_typed_floating (VALUE_CONTENTS_RAW (val), base_type, num);
+ }
+ else
+ error ("Unexpected type encountered for floating constant.");
+
+ return val;
+}
+
+/* Deal with the value that is "about to be returned". */
+
+/* Return the value that a function returning now
+ would be returning to its caller, assuming its type is VALTYPE.
+ RETBUF is where we look for what ought to be the contents
+ of the registers (in raw form). This is because it is often
+ desirable to restore old values to those registers
+ after saving the contents of interest, and then call
+ this function using the saved values.
+ struct_return is non-zero when the function in question is
+ using the structure return conventions on the machine in question;
+ 0 when it is using the value returning conventions (this often
+ means returning pointer to where structure is vs. returning value). */
+
+/* ARGSUSED */
+struct value *
+value_being_returned (struct type *valtype, char *retbuf, int struct_return)
+{
+ struct value *val;
+ CORE_ADDR addr;
+
+ /* If this is not defined, just use EXTRACT_RETURN_VALUE instead. */
+ if (EXTRACT_STRUCT_VALUE_ADDRESS_P ())
+ if (struct_return)
+ {
+ addr = EXTRACT_STRUCT_VALUE_ADDRESS (retbuf);
+ if (!addr)
+ error ("Function return value unknown.");
+ return value_at (valtype, addr, NULL);
+ }
+
+ val = allocate_value (valtype);
+ CHECK_TYPEDEF (valtype);
+ EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val));
+
+ return val;
+}
+
+/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of
+ EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc
+ and TYPE is the type (which is known to be struct, union or array).
+
+ On most machines, the struct convention is used unless we are
+ using gcc and the type is of a special size. */
+/* As of about 31 Mar 93, GCC was changed to be compatible with the
+ native compiler. GCC 2.3.3 was the last release that did it the
+ old way. Since gcc2_compiled was not changed, we have no
+ way to correctly win in all cases, so we just do the right thing
+ for gcc1 and for gcc2 after this change. Thus it loses for gcc
+ 2.0-2.3.3. This is somewhat unfortunate, but changing gcc2_compiled
+ would cause more chaos than dealing with some struct returns being
+ handled wrong. */
+
+int
+generic_use_struct_convention (int gcc_p, struct type *value_type)
+{
+ return !((gcc_p == 1)
+ && (TYPE_LENGTH (value_type) == 1
+ || TYPE_LENGTH (value_type) == 2
+ || TYPE_LENGTH (value_type) == 4
+ || TYPE_LENGTH (value_type) == 8));
+}
+
+/* Return true if the function specified is using the structure returning
+ convention on this machine to return arguments, or 0 if it is using
+ the value returning convention. FUNCTION is the value representing
+ the function, FUNCADDR is the address of the function, and VALUE_TYPE
+ is the type returned by the function. GCC_P is nonzero if compiled
+ with GCC. */
+
+/* ARGSUSED */
+int
+using_struct_return (struct value *function, CORE_ADDR funcaddr,
+ struct type *value_type, int gcc_p)
+{
+ register enum type_code code = TYPE_CODE (value_type);
+
+ if (code == TYPE_CODE_ERROR)
+ error ("Function return type unknown.");
+
+ if (code == TYPE_CODE_STRUCT
+ || code == TYPE_CODE_UNION
+ || code == TYPE_CODE_ARRAY
+ || RETURN_VALUE_ON_STACK (value_type))
+ return USE_STRUCT_CONVENTION (gcc_p, value_type);
+
+ return 0;
+}
+
+/* Store VAL so it will be returned if a function returns now.
+ Does not verify that VAL's type matches what the current
+ function wants to return. */
+
+void
+set_return_value (struct value *val)
+{
+ struct type *type = check_typedef (VALUE_TYPE (val));
+ register enum type_code code = TYPE_CODE (type);
+
+ if (code == TYPE_CODE_ERROR)
+ error ("Function return type unknown.");
+
+ if (code == TYPE_CODE_STRUCT
+ || code == TYPE_CODE_UNION) /* FIXME, implement struct return. */
+ error ("GDB does not support specifying a struct or union return value.");
+
+ STORE_RETURN_VALUE (type, VALUE_CONTENTS (val));
+}
+
+void
+_initialize_values (void)
+{
+ add_cmd ("convenience", no_class, show_convenience,
+ "Debugger convenience (\"$foo\") variables.\n\
+These variables are created when you assign them values;\n\
+thus, \"print $foo=1\" gives \"$foo\" the value 1. Values may be any type.\n\n\
+A few convenience variables are given values automatically:\n\
+\"$_\"holds the last address examined with \"x\" or \"info lines\",\n\
+\"$__\" holds the contents of the last address examined with \"x\".",
+ &showlist);
+
+ add_cmd ("values", no_class, show_values,
+ "Elements of value history around item number IDX (or last ten).",
+ &showlist);
+}
diff --git a/gdb/varobj.c b/gdb/varobj.c
new file mode 100644
index 00000000000..9ae145e2170
--- /dev/null
+++ b/gdb/varobj.c
@@ -0,0 +1,2492 @@
+/* Implementation of the GDB variable objects API.
+ Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+
+ 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 "defs.h"
+#include "value.h"
+#include "expression.h"
+#include "frame.h"
+#include "language.h"
+#include "wrapper.h"
+#include "gdbcmd.h"
+#include <math.h>
+
+#include "varobj.h"
+
+/* Non-zero if we want to see trace of varobj level stuff. */
+
+int varobjdebug = 0;
+
+/* String representations of gdb's format codes */
+char *varobj_format_string[] =
+ { "natural", "binary", "decimal", "hexadecimal", "octal" };
+
+/* String representations of gdb's known languages */
+char *varobj_language_string[] = { "unknown", "C", "C++", "Java" };
+
+/* Data structures */
+
+/* Every root variable has one of these structures saved in its
+ varobj. Members which must be free'd are noted. */
+struct varobj_root
+{
+
+ /* Alloc'd expression for this parent. */
+ struct expression *exp;
+
+ /* Block for which this expression is valid */
+ struct block *valid_block;
+
+ /* The frame for this expression */
+ CORE_ADDR frame;
+
+ /* If 1, "update" always recomputes the frame & valid block
+ using the currently selected frame. */
+ int use_selected_frame;
+
+ /* Language info for this variable and its children */
+ struct language_specific *lang;
+
+ /* The varobj for this root node. */
+ struct varobj *rootvar;
+
+ /* Next root variable */
+ struct varobj_root *next;
+};
+
+/* Every variable in the system has a structure of this type defined
+ for it. This structure holds all information necessary to manipulate
+ a particular object variable. Members which must be freed are noted. */
+struct varobj
+{
+
+ /* Alloc'd name of the variable for this object.. If this variable is a
+ child, then this name will be the child's source name.
+ (bar, not foo.bar) */
+ /* NOTE: This is the "expression" */
+ char *name;
+
+ /* The alloc'd name for this variable's object. This is here for
+ convenience when constructing this object's children. */
+ char *obj_name;
+
+ /* Index of this variable in its parent or -1 */
+ int index;
+
+ /* The type of this variable. This may NEVER be NULL. */
+ struct type *type;
+
+ /* The value of this expression or subexpression. This may be NULL. */
+ struct value *value;
+
+ /* Did an error occur evaluating the expression or getting its value? */
+ int error;
+
+ /* The number of (immediate) children this variable has */
+ int num_children;
+
+ /* If this object is a child, this points to its immediate parent. */
+ struct varobj *parent;
+
+ /* A list of this object's children */
+ struct varobj_child *children;
+
+ /* Description of the root variable. Points to root variable for children. */
+ struct varobj_root *root;
+
+ /* The format of the output for this object */
+ enum varobj_display_formats format;
+};
+
+/* Every variable keeps a linked list of its children, described
+ by the following structure. */
+/* FIXME: Deprecated. All should use vlist instead */
+
+struct varobj_child
+{
+
+ /* Pointer to the child's data */
+ struct varobj *child;
+
+ /* Pointer to the next child */
+ struct varobj_child *next;
+};
+
+/* A stack of varobjs */
+/* FIXME: Deprecated. All should use vlist instead */
+
+struct vstack
+{
+ struct varobj *var;
+ struct vstack *next;
+};
+
+struct cpstack
+{
+ char *name;
+ struct cpstack *next;
+};
+
+/* A list of varobjs */
+
+struct vlist
+{
+ struct varobj *var;
+ struct vlist *next;
+};
+
+/* Private function prototypes */
+
+/* Helper functions for the above subcommands. */
+
+static int delete_variable (struct cpstack **, struct varobj *, int);
+
+static void delete_variable_1 (struct cpstack **, int *,
+ struct varobj *, int, int);
+
+static int install_variable (struct varobj *);
+
+static void uninstall_variable (struct varobj *);
+
+static struct varobj *child_exists (struct varobj *, char *);
+
+static struct varobj *create_child (struct varobj *, int, char *);
+
+static void save_child_in_parent (struct varobj *, struct varobj *);
+
+static void remove_child_from_parent (struct varobj *, struct varobj *);
+
+/* Utility routines */
+
+static struct varobj *new_variable (void);
+
+static struct varobj *new_root_variable (void);
+
+static void free_variable (struct varobj *var);
+
+static struct cleanup *make_cleanup_free_variable (struct varobj *var);
+
+static struct type *get_type (struct varobj *var);
+
+static struct type *get_type_deref (struct varobj *var);
+
+static struct type *get_target_type (struct type *);
+
+static enum varobj_display_formats variable_default_display (struct varobj *);
+
+static int my_value_equal (struct value *, struct value *, int *);
+
+static void vpush (struct vstack **pstack, struct varobj *var);
+
+static struct varobj *vpop (struct vstack **pstack);
+
+static void cppush (struct cpstack **pstack, char *name);
+
+static char *cppop (struct cpstack **pstack);
+
+/* Language-specific routines. */
+
+static enum varobj_languages variable_language (struct varobj *var);
+
+static int number_of_children (struct varobj *);
+
+static char *name_of_variable (struct varobj *);
+
+static char *name_of_child (struct varobj *, int);
+
+static struct value *value_of_root (struct varobj **var_handle, int *);
+
+static struct value *value_of_child (struct varobj *parent, int index);
+
+static struct type *type_of_child (struct varobj *var);
+
+static int variable_editable (struct varobj *var);
+
+static char *my_value_of_variable (struct varobj *var);
+
+static int type_changeable (struct varobj *var);
+
+/* C implementation */
+
+static int c_number_of_children (struct varobj *var);
+
+static char *c_name_of_variable (struct varobj *parent);
+
+static char *c_name_of_child (struct varobj *parent, int index);
+
+static struct value *c_value_of_root (struct varobj **var_handle);
+
+static struct value *c_value_of_child (struct varobj *parent, int index);
+
+static struct type *c_type_of_child (struct varobj *parent, int index);
+
+static int c_variable_editable (struct varobj *var);
+
+static char *c_value_of_variable (struct varobj *var);
+
+/* C++ implementation */
+
+static int cplus_number_of_children (struct varobj *var);
+
+static void cplus_class_num_children (struct type *type, int children[3]);
+
+static char *cplus_name_of_variable (struct varobj *parent);
+
+static char *cplus_name_of_child (struct varobj *parent, int index);
+
+static struct value *cplus_value_of_root (struct varobj **var_handle);
+
+static struct value *cplus_value_of_child (struct varobj *parent, int index);
+
+static struct type *cplus_type_of_child (struct varobj *parent, int index);
+
+static int cplus_variable_editable (struct varobj *var);
+
+static char *cplus_value_of_variable (struct varobj *var);
+
+/* Java implementation */
+
+static int java_number_of_children (struct varobj *var);
+
+static char *java_name_of_variable (struct varobj *parent);
+
+static char *java_name_of_child (struct varobj *parent, int index);
+
+static struct value *java_value_of_root (struct varobj **var_handle);
+
+static struct value *java_value_of_child (struct varobj *parent, int index);
+
+static struct type *java_type_of_child (struct varobj *parent, int index);
+
+static int java_variable_editable (struct varobj *var);
+
+static char *java_value_of_variable (struct varobj *var);
+
+/* The language specific vector */
+
+struct language_specific
+{
+
+ /* The language of this variable */
+ enum varobj_languages language;
+
+ /* The number of children of PARENT. */
+ int (*number_of_children) (struct varobj * parent);
+
+ /* The name (expression) of a root varobj. */
+ char *(*name_of_variable) (struct varobj * parent);
+
+ /* The name of the INDEX'th child of PARENT. */
+ char *(*name_of_child) (struct varobj * parent, int index);
+
+ /* The ``struct value *'' of the root variable ROOT. */
+ struct value *(*value_of_root) (struct varobj ** root_handle);
+
+ /* The ``struct value *'' of the INDEX'th child of PARENT. */
+ struct value *(*value_of_child) (struct varobj * parent, int index);
+
+ /* The type of the INDEX'th child of PARENT. */
+ struct type *(*type_of_child) (struct varobj * parent, int index);
+
+ /* Is VAR editable? */
+ int (*variable_editable) (struct varobj * var);
+
+ /* The current value of VAR. */
+ char *(*value_of_variable) (struct varobj * var);
+};
+
+/* Array of known source language routines. */
+static struct language_specific
+ languages[vlang_end][sizeof (struct language_specific)] = {
+ /* Unknown (try treating as C */
+ {
+ vlang_unknown,
+ c_number_of_children,
+ c_name_of_variable,
+ c_name_of_child,
+ c_value_of_root,
+ c_value_of_child,
+ c_type_of_child,
+ c_variable_editable,
+ c_value_of_variable}
+ ,
+ /* C */
+ {
+ vlang_c,
+ c_number_of_children,
+ c_name_of_variable,
+ c_name_of_child,
+ c_value_of_root,
+ c_value_of_child,
+ c_type_of_child,
+ c_variable_editable,
+ c_value_of_variable}
+ ,
+ /* C++ */
+ {
+ vlang_cplus,
+ cplus_number_of_children,
+ cplus_name_of_variable,
+ cplus_name_of_child,
+ cplus_value_of_root,
+ cplus_value_of_child,
+ cplus_type_of_child,
+ cplus_variable_editable,
+ cplus_value_of_variable}
+ ,
+ /* Java */
+ {
+ vlang_java,
+ java_number_of_children,
+ java_name_of_variable,
+ java_name_of_child,
+ java_value_of_root,
+ java_value_of_child,
+ java_type_of_child,
+ java_variable_editable,
+ java_value_of_variable}
+};
+
+/* A little convenience enum for dealing with C++/Java */
+enum vsections
+{
+ v_public = 0, v_private, v_protected
+};
+
+/* Private data */
+
+/* Mappings of varobj_display_formats enums to gdb's format codes */
+static int format_code[] = { 0, 't', 'd', 'x', 'o' };
+
+/* Header of the list of root variable objects */
+static struct varobj_root *rootlist;
+static int rootcount = 0; /* number of root varobjs in the list */
+
+/* Prime number indicating the number of buckets in the hash table */
+/* A prime large enough to avoid too many colisions */
+#define VAROBJ_TABLE_SIZE 227
+
+/* Pointer to the varobj hash table (built at run time) */
+static struct vlist **varobj_table;
+
+/* Is the variable X one of our "fake" children? */
+#define CPLUS_FAKE_CHILD(x) \
+((x) != NULL && (x)->type == NULL && (x)->value == NULL)
+
+
+/* API Implementation */
+
+/* Creates a varobj (not its children) */
+
+struct varobj *
+varobj_create (char *objname,
+ char *expression, CORE_ADDR frame, enum varobj_type type)
+{
+ struct varobj *var;
+ struct frame_info *fi;
+ struct frame_info *old_fi = NULL;
+ struct block *block;
+ struct cleanup *old_chain;
+
+ /* Fill out a varobj structure for the (root) variable being constructed. */
+ var = new_root_variable ();
+ old_chain = make_cleanup_free_variable (var);
+
+ if (expression != NULL)
+ {
+ char *p;
+ enum varobj_languages lang;
+
+ /* Parse and evaluate the expression, filling in as much
+ of the variable's data as possible */
+
+ /* Allow creator to specify context of variable */
+ if ((type == USE_CURRENT_FRAME) || (type == USE_SELECTED_FRAME))
+ fi = selected_frame;
+ else
+ fi = find_frame_addr_in_frame_chain (frame);
+
+ /* frame = -2 means always use selected frame */
+ if (type == USE_SELECTED_FRAME)
+ var->root->use_selected_frame = 1;
+
+ block = NULL;
+ if (fi != NULL)
+ block = get_frame_block (fi, 0);
+
+ p = expression;
+ innermost_block = NULL;
+ /* Wrap the call to parse expression, so we can
+ return a sensible error. */
+ if (!gdb_parse_exp_1 (&p, block, 0, &var->root->exp))
+ {
+ return NULL;
+ }
+
+ /* Don't allow variables to be created for types. */
+ if (var->root->exp->elts[0].opcode == OP_TYPE)
+ {
+ do_cleanups (old_chain);
+ fprintf_unfiltered (gdb_stderr,
+ "Attempt to use a type name as an expression.");
+ return NULL;
+ }
+
+ var->format = variable_default_display (var);
+ var->root->valid_block = innermost_block;
+ var->name = savestring (expression, strlen (expression));
+
+ /* When the frame is different from the current frame,
+ we must select the appropriate frame before parsing
+ the expression, otherwise the value will not be current.
+ Since select_frame is so benign, just call it for all cases. */
+ if (fi != NULL)
+ {
+ var->root->frame = FRAME_FP (fi);
+ old_fi = selected_frame;
+ select_frame (fi);
+ }
+
+ /* We definitively need to catch errors here.
+ If evaluate_expression succeeds we got the value we wanted.
+ But if it fails, we still go on with a call to evaluate_type() */
+ if (gdb_evaluate_expression (var->root->exp, &var->value))
+ {
+ /* no error */
+ release_value (var->value);
+ if (VALUE_LAZY (var->value))
+ gdb_value_fetch_lazy (var->value);
+ }
+ else
+ var->value = evaluate_type (var->root->exp);
+
+ var->type = VALUE_TYPE (var->value);
+
+ /* Set language info */
+ lang = variable_language (var);
+ var->root->lang = languages[lang];
+
+ /* Set ourselves as our root */
+ var->root->rootvar = var;
+
+ /* Reset the selected frame */
+ if (fi != NULL)
+ select_frame (old_fi);
+ }
+
+ /* If the variable object name is null, that means this
+ is a temporary variable, so don't install it. */
+
+ if ((var != NULL) && (objname != NULL))
+ {
+ var->obj_name = savestring (objname, strlen (objname));
+
+ /* If a varobj name is duplicated, the install will fail so
+ we must clenup */
+ if (!install_variable (var))
+ {
+ do_cleanups (old_chain);
+ return NULL;
+ }
+ }
+
+ discard_cleanups (old_chain);
+ return var;
+}
+
+/* Generates an unique name that can be used for a varobj */
+
+char *
+varobj_gen_name (void)
+{
+ static int id = 0;
+ char obj_name[31];
+
+ /* generate a name for this object */
+ id++;
+ sprintf (obj_name, "var%d", id);
+
+ return xstrdup (obj_name);
+}
+
+/* Given an "objname", returns the pointer to the corresponding varobj
+ or NULL if not found */
+
+struct varobj *
+varobj_get_handle (char *objname)
+{
+ struct vlist *cv;
+ const char *chp;
+ unsigned int index = 0;
+ unsigned int i = 1;
+
+ for (chp = objname; *chp; chp++)
+ {
+ index = (index + (i++ * (unsigned int) *chp)) % VAROBJ_TABLE_SIZE;
+ }
+
+ cv = *(varobj_table + index);
+ while ((cv != NULL) && (strcmp (cv->var->obj_name, objname) != 0))
+ cv = cv->next;
+
+ if (cv == NULL)
+ error ("Variable object not found");
+
+ return cv->var;
+}
+
+/* Given the handle, return the name of the object */
+
+char *
+varobj_get_objname (struct varobj *var)
+{
+ return var->obj_name;
+}
+
+/* Given the handle, return the expression represented by the object */
+
+char *
+varobj_get_expression (struct varobj *var)
+{
+ return name_of_variable (var);
+}
+
+/* Deletes a varobj and all its children if only_children == 0,
+ otherwise deletes only the children; returns a malloc'ed list of all the
+ (malloc'ed) names of the variables that have been deleted (NULL terminated) */
+
+int
+varobj_delete (struct varobj *var, char ***dellist, int only_children)
+{
+ int delcount;
+ int mycount;
+ struct cpstack *result = NULL;
+ char **cp;
+
+ /* Initialize a stack for temporary results */
+ cppush (&result, NULL);
+
+ if (only_children)
+ /* Delete only the variable children */
+ delcount = delete_variable (&result, var, 1 /* only the children */ );
+ else
+ /* Delete the variable and all its children */
+ delcount = delete_variable (&result, var, 0 /* parent+children */ );
+
+ /* We may have been asked to return a list of what has been deleted */
+ if (dellist != NULL)
+ {
+ *dellist = xmalloc ((delcount + 1) * sizeof (char *));
+
+ cp = *dellist;
+ mycount = delcount;
+ *cp = cppop (&result);
+ while ((*cp != NULL) && (mycount > 0))
+ {
+ mycount--;
+ cp++;
+ *cp = cppop (&result);
+ }
+
+ if (mycount || (*cp != NULL))
+ warning ("varobj_delete: assertion failed - mycount(=%d) <> 0",
+ mycount);
+ }
+
+ return delcount;
+}
+
+/* Set/Get variable object display format */
+
+enum varobj_display_formats
+varobj_set_display_format (struct varobj *var,
+ enum varobj_display_formats format)
+{
+ switch (format)
+ {
+ case FORMAT_NATURAL:
+ case FORMAT_BINARY:
+ case FORMAT_DECIMAL:
+ case FORMAT_HEXADECIMAL:
+ case FORMAT_OCTAL:
+ var->format = format;
+ break;
+
+ default:
+ var->format = variable_default_display (var);
+ }
+
+ return var->format;
+}
+
+enum varobj_display_formats
+varobj_get_display_format (struct varobj *var)
+{
+ return var->format;
+}
+
+int
+varobj_get_num_children (struct varobj *var)
+{
+ if (var->num_children == -1)
+ var->num_children = number_of_children (var);
+
+ return var->num_children;
+}
+
+/* Creates a list of the immediate children of a variable object;
+ the return code is the number of such children or -1 on error */
+
+int
+varobj_list_children (struct varobj *var, struct varobj ***childlist)
+{
+ struct varobj *child;
+ char *name;
+ int i;
+
+ /* sanity check: have we been passed a pointer? */
+ if (childlist == NULL)
+ return -1;
+
+ *childlist = NULL;
+
+ if (var->num_children == -1)
+ var->num_children = number_of_children (var);
+
+ /* List of children */
+ *childlist = xmalloc ((var->num_children + 1) * sizeof (struct varobj *));
+
+ for (i = 0; i < var->num_children; i++)
+ {
+ /* Mark as the end in case we bail out */
+ *((*childlist) + i) = NULL;
+
+ /* check if child exists, if not create */
+ name = name_of_child (var, i);
+ child = child_exists (var, name);
+ if (child == NULL)
+ child = create_child (var, i, name);
+
+ *((*childlist) + i) = child;
+ }
+
+ /* End of list is marked by a NULL pointer */
+ *((*childlist) + i) = NULL;
+
+ return var->num_children;
+}
+
+/* Obtain the type of an object Variable as a string similar to the one gdb
+ prints on the console */
+
+char *
+varobj_get_type (struct varobj *var)
+{
+ struct value *val;
+ struct cleanup *old_chain;
+ struct ui_file *stb;
+ char *thetype;
+ long length;
+
+ /* For the "fake" variables, do not return a type. (It's type is
+ NULL, too.) */
+ if (CPLUS_FAKE_CHILD (var))
+ return NULL;
+
+ stb = mem_fileopen ();
+ old_chain = make_cleanup_ui_file_delete (stb);
+
+ /* To print the type, we simply create a zero ``struct value *'' and
+ cast it to our type. We then typeprint this variable. */
+ val = value_zero (var->type, not_lval);
+ type_print (VALUE_TYPE (val), "", stb, -1);
+
+ thetype = ui_file_xstrdup (stb, &length);
+ do_cleanups (old_chain);
+ return thetype;
+}
+
+enum varobj_languages
+varobj_get_language (struct varobj *var)
+{
+ return variable_language (var);
+}
+
+int
+varobj_get_attributes (struct varobj *var)
+{
+ int attributes = 0;
+
+ if (variable_editable (var))
+ /* FIXME: define masks for attributes */
+ attributes |= 0x00000001; /* Editable */
+
+ return attributes;
+}
+
+char *
+varobj_get_value (struct varobj *var)
+{
+ return my_value_of_variable (var);
+}
+
+/* Set the value of an object variable (if it is editable) to the
+ value of the given expression */
+/* Note: Invokes functions that can call error() */
+
+int
+varobj_set_value (struct varobj *var, char *expression)
+{
+ struct value *val;
+ int offset = 0;
+
+ /* The argument "expression" contains the variable's new value.
+ We need to first construct a legal expression for this -- ugh! */
+ /* Does this cover all the bases? */
+ struct expression *exp;
+ struct value *value;
+ int saved_input_radix = input_radix;
+
+ if (var->value != NULL && variable_editable (var) && !var->error)
+ {
+ char *s = expression;
+ int i;
+
+ input_radix = 10; /* ALWAYS reset to decimal temporarily */
+ if (!gdb_parse_exp_1 (&s, 0, 0, &exp))
+ /* We cannot proceed without a well-formed expression. */
+ return 0;
+ if (!gdb_evaluate_expression (exp, &value))
+ {
+ /* We cannot proceed without a valid expression. */
+ xfree (exp);
+ return 0;
+ }
+
+ if (!gdb_value_assign (var->value, value, &val))
+ return 0;
+ value_free (var->value);
+ release_value (val);
+ var->value = val;
+ input_radix = saved_input_radix;
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Returns a malloc'ed list with all root variable objects */
+int
+varobj_list (struct varobj ***varlist)
+{
+ struct varobj **cv;
+ struct varobj_root *croot;
+ int mycount = rootcount;
+
+ /* Alloc (rootcount + 1) entries for the result */
+ *varlist = xmalloc ((rootcount + 1) * sizeof (struct varobj *));
+
+ cv = *varlist;
+ croot = rootlist;
+ while ((croot != NULL) && (mycount > 0))
+ {
+ *cv = croot->rootvar;
+ mycount--;
+ cv++;
+ croot = croot->next;
+ }
+ /* Mark the end of the list */
+ *cv = NULL;
+
+ if (mycount || (croot != NULL))
+ warning
+ ("varobj_list: assertion failed - wrong tally of root vars (%d:%d)",
+ rootcount, mycount);
+
+ return rootcount;
+}
+
+/* Update the values for a variable and its children. This is a
+ two-pronged attack. First, re-parse the value for the root's
+ expression to see if it's changed. Then go all the way
+ through its children, reconstructing them and noting if they've
+ changed.
+ Return value:
+ -1 if there was an error updating the varobj
+ -2 if the type changed
+ Otherwise it is the number of children + parent changed
+
+ Only root variables can be updated...
+
+ NOTE: This function may delete the caller's varobj. If it
+ returns -2, then it has done this and VARP will be modified
+ to point to the new varobj. */
+
+int
+varobj_update (struct varobj **varp, struct varobj ***changelist)
+{
+ int changed = 0;
+ int type_changed;
+ int i;
+ int vleft;
+ int error2;
+ struct varobj *v;
+ struct varobj **cv;
+ struct varobj **templist = NULL;
+ struct value *new;
+ struct vstack *stack = NULL;
+ struct vstack *result = NULL;
+ struct frame_info *old_fi;
+
+ /* sanity check: have we been passed a pointer? */
+ if (changelist == NULL)
+ return -1;
+
+ /* Only root variables can be updated... */
+ if ((*varp)->root->rootvar != *varp)
+ /* Not a root var */
+ return -1;
+
+ /* Save the selected stack frame, since we will need to change it
+ in order to evaluate expressions. */
+ old_fi = selected_frame;
+
+ /* Update the root variable. value_of_root can return NULL
+ if the variable is no longer around, i.e. we stepped out of
+ the frame in which a local existed. We are letting the
+ value_of_root variable dispose of the varobj if the type
+ has changed. */
+ type_changed = 1;
+ new = value_of_root (varp, &type_changed);
+ if (new == NULL)
+ {
+ (*varp)->error = 1;
+ return -1;
+ }
+
+ /* Initialize a stack for temporary results */
+ vpush (&result, NULL);
+
+ /* If this is a "use_selected_frame" varobj, and its type has changed,
+ them note that it's changed. */
+ if (type_changed)
+ {
+ vpush (&result, *varp);
+ changed++;
+ }
+ /* If values are not equal, note that it's changed.
+ There a couple of exceptions here, though.
+ We don't want some types to be reported as "changed". */
+ else if (type_changeable (*varp)
+ && !my_value_equal ((*varp)->value, new, &error2))
+ {
+ vpush (&result, *varp);
+ changed++;
+ /* error2 replaces var->error since this new value
+ WILL replace the old one. */
+ (*varp)->error = error2;
+ }
+
+ /* We must always keep around the new value for this root
+ variable expression, or we lose the updated children! */
+ value_free ((*varp)->value);
+ (*varp)->value = new;
+
+ /* Initialize a stack */
+ vpush (&stack, NULL);
+
+ /* Push the root's children */
+ if ((*varp)->children != NULL)
+ {
+ struct varobj_child *c;
+ for (c = (*varp)->children; c != NULL; c = c->next)
+ vpush (&stack, c->child);
+ }
+
+ /* Walk through the children, reconstructing them all. */
+ v = vpop (&stack);
+ while (v != NULL)
+ {
+ /* Push any children */
+ if (v->children != NULL)
+ {
+ struct varobj_child *c;
+ for (c = v->children; c != NULL; c = c->next)
+ vpush (&stack, c->child);
+ }
+
+ /* Update this variable */
+ new = value_of_child (v->parent, v->index);
+ if (type_changeable (v) && !my_value_equal (v->value, new, &error2))
+ {
+ /* Note that it's changed */
+ vpush (&result, v);
+ changed++;
+ }
+ /* error2 replaces v->error since this new value
+ WILL replace the old one. */
+ v->error = error2;
+
+ /* We must always keep new values, since children depend on it. */
+ if (v->value != NULL)
+ value_free (v->value);
+ v->value = new;
+
+ /* Get next child */
+ v = vpop (&stack);
+ }
+
+ /* Alloc (changed + 1) list entries */
+ /* FIXME: add a cleanup for the allocated list(s)
+ because one day the select_frame called below can longjump */
+ *changelist = xmalloc ((changed + 1) * sizeof (struct varobj *));
+ if (changed > 1)
+ {
+ templist = xmalloc ((changed + 1) * sizeof (struct varobj *));
+ cv = templist;
+ }
+ else
+ cv = *changelist;
+
+ /* Copy from result stack to list */
+ vleft = changed;
+ *cv = vpop (&result);
+ while ((*cv != NULL) && (vleft > 0))
+ {
+ vleft--;
+ cv++;
+ *cv = vpop (&result);
+ }
+ if (vleft)
+ warning ("varobj_update: assertion failed - vleft <> 0");
+
+ if (changed > 1)
+ {
+ /* Now we revert the order. */
+ for (i = 0; i < changed; i++)
+ *(*changelist + i) = *(templist + changed - 1 - i);
+ *(*changelist + changed) = NULL;
+ }
+
+ /* Restore selected frame */
+ select_frame (old_fi);
+
+ if (type_changed)
+ return -2;
+ else
+ return changed;
+}
+
+
+/* Helper functions */
+
+/*
+ * Variable object construction/destruction
+ */
+
+static int
+delete_variable (struct cpstack **resultp, struct varobj *var,
+ int only_children_p)
+{
+ int delcount = 0;
+
+ delete_variable_1 (resultp, &delcount, var,
+ only_children_p, 1 /* remove_from_parent_p */ );
+
+ return delcount;
+}
+
+/* Delete the variable object VAR and its children */
+/* IMPORTANT NOTE: If we delete a variable which is a child
+ and the parent is not removed we dump core. It must be always
+ initially called with remove_from_parent_p set */
+static void
+delete_variable_1 (struct cpstack **resultp, int *delcountp,
+ struct varobj *var, int only_children_p,
+ int remove_from_parent_p)
+{
+ struct varobj_child *vc;
+ struct varobj_child *next;
+
+ /* Delete any children of this variable, too. */
+ for (vc = var->children; vc != NULL; vc = next)
+ {
+ if (!remove_from_parent_p)
+ vc->child->parent = NULL;
+ delete_variable_1 (resultp, delcountp, vc->child, 0, only_children_p);
+ next = vc->next;
+ xfree (vc);
+ }
+
+ /* if we were called to delete only the children we are done here */
+ if (only_children_p)
+ return;
+
+ /* Otherwise, add it to the list of deleted ones and proceed to do so */
+ /* If the name is null, this is a temporary variable, that has not
+ yet been installed, don't report it, it belongs to the caller... */
+ if (var->obj_name != NULL)
+ {
+ cppush (resultp, xstrdup (var->obj_name));
+ *delcountp = *delcountp + 1;
+ }
+
+ /* If this variable has a parent, remove it from its parent's list */
+ /* OPTIMIZATION: if the parent of this variable is also being deleted,
+ (as indicated by remove_from_parent_p) we don't bother doing an
+ expensive list search to find the element to remove when we are
+ discarding the list afterwards */
+ if ((remove_from_parent_p) && (var->parent != NULL))
+ {
+ remove_child_from_parent (var->parent, var);
+ }
+
+ if (var->obj_name != NULL)
+ uninstall_variable (var);
+
+ /* Free memory associated with this variable */
+ free_variable (var);
+}
+
+/* Install the given variable VAR with the object name VAR->OBJ_NAME. */
+static int
+install_variable (struct varobj *var)
+{
+ struct vlist *cv;
+ struct vlist *newvl;
+ const char *chp;
+ unsigned int index = 0;
+ unsigned int i = 1;
+
+ for (chp = var->obj_name; *chp; chp++)
+ {
+ index = (index + (i++ * (unsigned int) *chp)) % VAROBJ_TABLE_SIZE;
+ }
+
+ cv = *(varobj_table + index);
+ while ((cv != NULL) && (strcmp (cv->var->obj_name, var->obj_name) != 0))
+ cv = cv->next;
+
+ if (cv != NULL)
+ error ("Duplicate variable object name");
+
+ /* Add varobj to hash table */
+ newvl = xmalloc (sizeof (struct vlist));
+ newvl->next = *(varobj_table + index);
+ newvl->var = var;
+ *(varobj_table + index) = newvl;
+
+ /* If root, add varobj to root list */
+ if (var->root->rootvar == var)
+ {
+ /* Add to list of root variables */
+ if (rootlist == NULL)
+ var->root->next = NULL;
+ else
+ var->root->next = rootlist;
+ rootlist = var->root;
+ rootcount++;
+ }
+
+ return 1; /* OK */
+}
+
+/* Unistall the object VAR. */
+static void
+uninstall_variable (struct varobj *var)
+{
+ struct vlist *cv;
+ struct vlist *prev;
+ struct varobj_root *cr;
+ struct varobj_root *prer;
+ const char *chp;
+ unsigned int index = 0;
+ unsigned int i = 1;
+
+ /* Remove varobj from hash table */
+ for (chp = var->obj_name; *chp; chp++)
+ {
+ index = (index + (i++ * (unsigned int) *chp)) % VAROBJ_TABLE_SIZE;
+ }
+
+ cv = *(varobj_table + index);
+ prev = NULL;
+ while ((cv != NULL) && (strcmp (cv->var->obj_name, var->obj_name) != 0))
+ {
+ prev = cv;
+ cv = cv->next;
+ }
+
+ if (varobjdebug)
+ fprintf_unfiltered (gdb_stdlog, "Deleting %s\n", var->obj_name);
+
+ if (cv == NULL)
+ {
+ warning
+ ("Assertion failed: Could not find variable object \"%s\" to delete",
+ var->obj_name);
+ return;
+ }
+
+ if (prev == NULL)
+ *(varobj_table + index) = cv->next;
+ else
+ prev->next = cv->next;
+
+ xfree (cv);
+
+ /* If root, remove varobj from root list */
+ if (var->root->rootvar == var)
+ {
+ /* Remove from list of root variables */
+ if (rootlist == var->root)
+ rootlist = var->root->next;
+ else
+ {
+ prer = NULL;
+ cr = rootlist;
+ while ((cr != NULL) && (cr->rootvar != var))
+ {
+ prer = cr;
+ cr = cr->next;
+ }
+ if (cr == NULL)
+ {
+ warning
+ ("Assertion failed: Could not find varobj \"%s\" in root list",
+ var->obj_name);
+ return;
+ }
+ if (prer == NULL)
+ rootlist = NULL;
+ else
+ prer->next = cr->next;
+ }
+ rootcount--;
+ }
+
+}
+
+/* Does a child with the name NAME exist in VAR? If so, return its data.
+ If not, return NULL. */
+static struct varobj *
+child_exists (struct varobj *var, char *name)
+{
+ struct varobj_child *vc;
+
+ for (vc = var->children; vc != NULL; vc = vc->next)
+ {
+ if (STREQ (vc->child->name, name))
+ return vc->child;
+ }
+
+ return NULL;
+}
+
+/* Create and install a child of the parent of the given name */
+static struct varobj *
+create_child (struct varobj *parent, int index, char *name)
+{
+ struct varobj *child;
+ char *childs_name;
+
+ child = new_variable ();
+
+ /* name is allocated by name_of_child */
+ child->name = name;
+ child->index = index;
+ child->value = value_of_child (parent, index);
+ if ((!CPLUS_FAKE_CHILD(child) && child->value == NULL) || parent->error)
+ child->error = 1;
+ child->parent = parent;
+ child->root = parent->root;
+ childs_name =
+ (char *) xmalloc ((strlen (parent->obj_name) + strlen (name) + 2) *
+ sizeof (char));
+ sprintf (childs_name, "%s.%s", parent->obj_name, name);
+ child->obj_name = childs_name;
+ install_variable (child);
+
+ /* Save a pointer to this child in the parent */
+ save_child_in_parent (parent, child);
+
+ /* Note the type of this child */
+ child->type = type_of_child (child);
+
+ return child;
+}
+
+/* FIXME: This should be a generic add to list */
+/* Save CHILD in the PARENT's data. */
+static void
+save_child_in_parent (struct varobj *parent, struct varobj *child)
+{
+ struct varobj_child *vc;
+
+ /* Insert the child at the top */
+ vc = parent->children;
+ parent->children =
+ (struct varobj_child *) xmalloc (sizeof (struct varobj_child));
+
+ parent->children->next = vc;
+ parent->children->child = child;
+}
+
+/* FIXME: This should be a generic remove from list */
+/* Remove the CHILD from the PARENT's list of children. */
+static void
+remove_child_from_parent (struct varobj *parent, struct varobj *child)
+{
+ struct varobj_child *vc, *prev;
+
+ /* Find the child in the parent's list */
+ prev = NULL;
+ for (vc = parent->children; vc != NULL;)
+ {
+ if (vc->child == child)
+ break;
+ prev = vc;
+ vc = vc->next;
+ }
+
+ if (prev == NULL)
+ parent->children = vc->next;
+ else
+ prev->next = vc->next;
+
+}
+
+
+/*
+ * Miscellaneous utility functions.
+ */
+
+/* Allocate memory and initialize a new variable */
+static struct varobj *
+new_variable (void)
+{
+ struct varobj *var;
+
+ var = (struct varobj *) xmalloc (sizeof (struct varobj));
+ var->name = NULL;
+ var->obj_name = NULL;
+ var->index = -1;
+ var->type = NULL;
+ var->value = NULL;
+ var->error = 0;
+ var->num_children = -1;
+ var->parent = NULL;
+ var->children = NULL;
+ var->format = 0;
+ var->root = NULL;
+
+ return var;
+}
+
+/* Allocate memory and initialize a new root variable */
+static struct varobj *
+new_root_variable (void)
+{
+ struct varobj *var = new_variable ();
+ var->root = (struct varobj_root *) xmalloc (sizeof (struct varobj_root));;
+ var->root->lang = NULL;
+ var->root->exp = NULL;
+ var->root->valid_block = NULL;
+ var->root->frame = (CORE_ADDR) -1;
+ var->root->use_selected_frame = 0;
+ var->root->rootvar = NULL;
+
+ return var;
+}
+
+/* Free any allocated memory associated with VAR. */
+static void
+free_variable (struct varobj *var)
+{
+ /* Free the expression if this is a root variable. */
+ if (var->root->rootvar == var)
+ {
+ free_current_contents ((char **) &var->root->exp);
+ xfree (var->root);
+ }
+
+ xfree (var->name);
+ xfree (var->obj_name);
+ xfree (var);
+}
+
+static void
+do_free_variable_cleanup (void *var)
+{
+ free_variable (var);
+}
+
+static struct cleanup *
+make_cleanup_free_variable (struct varobj *var)
+{
+ return make_cleanup (do_free_variable_cleanup, var);
+}
+
+/* This returns the type of the variable. This skips past typedefs
+ and returns the real type of the variable. It also dereferences
+ pointers and references. */
+static struct type *
+get_type (struct varobj *var)
+{
+ struct type *type;
+ type = var->type;
+
+ while (type != NULL && TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
+ type = TYPE_TARGET_TYPE (type);
+
+ return type;
+}
+
+/* This returns the type of the variable, dereferencing pointers, too. */
+static struct type *
+get_type_deref (struct varobj *var)
+{
+ struct type *type;
+
+ type = get_type (var);
+
+ if (type != NULL && (TYPE_CODE (type) == TYPE_CODE_PTR
+ || TYPE_CODE (type) == TYPE_CODE_REF))
+ type = get_target_type (type);
+
+ return type;
+}
+
+/* This returns the target type (or NULL) of TYPE, also skipping
+ past typedefs, just like get_type (). */
+static struct type *
+get_target_type (struct type *type)
+{
+ if (type != NULL)
+ {
+ type = TYPE_TARGET_TYPE (type);
+ while (type != NULL && TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
+ type = TYPE_TARGET_TYPE (type);
+ }
+
+ return type;
+}
+
+/* What is the default display for this variable? We assume that
+ everything is "natural". Any exceptions? */
+static enum varobj_display_formats
+variable_default_display (struct varobj *var)
+{
+ return FORMAT_NATURAL;
+}
+
+/* This function is similar to gdb's value_equal, except that this
+ one is "safe" -- it NEVER longjmps. It determines if the VAR's
+ value is the same as VAL2. */
+static int
+my_value_equal (struct value *val1, struct value *val2, int *error2)
+{
+ int r, err1, err2;
+
+ *error2 = 0;
+ /* Special case: NULL values. If both are null, say
+ they're equal. */
+ if (val1 == NULL && val2 == NULL)
+ return 1;
+ else if (val1 == NULL || val2 == NULL)
+ return 0;
+
+ /* This is bogus, but unfortunately necessary. We must know
+ exactly what caused an error -- reading val1 or val2 -- so
+ that we can really determine if we think that something has changed. */
+ err1 = 0;
+ err2 = 0;
+ /* We do need to catch errors here because the whole purpose
+ is to test if value_equal() has errored */
+ if (!gdb_value_equal (val1, val1, &r))
+ err1 = 1;
+
+ if (!gdb_value_equal (val2, val2, &r))
+ *error2 = err2 = 1;
+
+ if (err1 != err2)
+ return 0;
+
+ if (!gdb_value_equal (val1, val2, &r))
+ {
+ /* An error occurred, this could have happened if
+ either val1 or val2 errored. ERR1 and ERR2 tell
+ us which of these it is. If both errored, then
+ we assume nothing has changed. If one of them is
+ valid, though, then something has changed. */
+ if (err1 == err2)
+ {
+ /* both the old and new values caused errors, so
+ we say the value did not change */
+ /* This is indeterminate, though. Perhaps we should
+ be safe and say, yes, it changed anyway?? */
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ return r;
+}
+
+/* FIXME: The following should be generic for any pointer */
+static void
+vpush (struct vstack **pstack, struct varobj *var)
+{
+ struct vstack *s;
+
+ s = (struct vstack *) xmalloc (sizeof (struct vstack));
+ s->var = var;
+ s->next = *pstack;
+ *pstack = s;
+}
+
+/* FIXME: The following should be generic for any pointer */
+static struct varobj *
+vpop (struct vstack **pstack)
+{
+ struct vstack *s;
+ struct varobj *v;
+
+ if ((*pstack)->var == NULL && (*pstack)->next == NULL)
+ return NULL;
+
+ s = *pstack;
+ v = s->var;
+ *pstack = (*pstack)->next;
+ xfree (s);
+
+ return v;
+}
+
+/* FIXME: The following should be generic for any pointer */
+static void
+cppush (struct cpstack **pstack, char *name)
+{
+ struct cpstack *s;
+
+ s = (struct cpstack *) xmalloc (sizeof (struct cpstack));
+ s->name = name;
+ s->next = *pstack;
+ *pstack = s;
+}
+
+/* FIXME: The following should be generic for any pointer */
+static char *
+cppop (struct cpstack **pstack)
+{
+ struct cpstack *s;
+ char *v;
+
+ if ((*pstack)->name == NULL && (*pstack)->next == NULL)
+ return NULL;
+
+ s = *pstack;
+ v = s->name;
+ *pstack = (*pstack)->next;
+ xfree (s);
+
+ return v;
+}
+
+/*
+ * Language-dependencies
+ */
+
+/* Common entry points */
+
+/* Get the language of variable VAR. */
+static enum varobj_languages
+variable_language (struct varobj *var)
+{
+ enum varobj_languages lang;
+
+ switch (var->root->exp->language_defn->la_language)
+ {
+ default:
+ case language_c:
+ lang = vlang_c;
+ break;
+ case language_cplus:
+ lang = vlang_cplus;
+ break;
+ case language_java:
+ lang = vlang_java;
+ break;
+ }
+
+ return lang;
+}
+
+/* Return the number of children for a given variable.
+ The result of this function is defined by the language
+ implementation. The number of children returned by this function
+ is the number of children that the user will see in the variable
+ display. */
+static int
+number_of_children (struct varobj *var)
+{
+ return (*var->root->lang->number_of_children) (var);;
+}
+
+/* What is the expression for the root varobj VAR? Returns a malloc'd string. */
+static char *
+name_of_variable (struct varobj *var)
+{
+ return (*var->root->lang->name_of_variable) (var);
+}
+
+/* What is the name of the INDEX'th child of VAR? Returns a malloc'd string. */
+static char *
+name_of_child (struct varobj *var, int index)
+{
+ return (*var->root->lang->name_of_child) (var, index);
+}
+
+/* What is the ``struct value *'' of the root variable VAR?
+ TYPE_CHANGED controls what to do if the type of a
+ use_selected_frame = 1 variable changes. On input,
+ TYPE_CHANGED = 1 means discard the old varobj, and replace
+ it with this one. TYPE_CHANGED = 0 means leave it around.
+ NB: In both cases, var_handle will point to the new varobj,
+ so if you use TYPE_CHANGED = 0, you will have to stash the
+ old varobj pointer away somewhere before calling this.
+ On return, TYPE_CHANGED will be 1 if the type has changed, and
+ 0 otherwise. */
+static struct value *
+value_of_root (struct varobj **var_handle, int *type_changed)
+{
+ struct varobj *var;
+
+ if (var_handle == NULL)
+ return NULL;
+
+ var = *var_handle;
+
+ /* This should really be an exception, since this should
+ only get called with a root variable. */
+
+ if (var->root->rootvar != var)
+ return NULL;
+
+ if (var->root->use_selected_frame)
+ {
+ struct varobj *tmp_var;
+ char *old_type, *new_type;
+ old_type = varobj_get_type (var);
+ tmp_var = varobj_create (NULL, var->name, (CORE_ADDR) 0,
+ USE_SELECTED_FRAME);
+ if (tmp_var == NULL)
+ {
+ return NULL;
+ }
+ new_type = varobj_get_type (tmp_var);
+ if (strcmp (old_type, new_type) == 0)
+ {
+ varobj_delete (tmp_var, NULL, 0);
+ *type_changed = 0;
+ }
+ else
+ {
+ if (*type_changed)
+ {
+ tmp_var->obj_name =
+ savestring (var->obj_name, strlen (var->obj_name));
+ varobj_delete (var, NULL, 0);
+ }
+ else
+ {
+ tmp_var->obj_name = varobj_gen_name ();
+ }
+ install_variable (tmp_var);
+ *var_handle = tmp_var;
+ var = *var_handle;
+ *type_changed = 1;
+ }
+ }
+ else
+ {
+ *type_changed = 0;
+ }
+
+ return (*var->root->lang->value_of_root) (var_handle);
+}
+
+/* What is the ``struct value *'' for the INDEX'th child of PARENT? */
+static struct value *
+value_of_child (struct varobj *parent, int index)
+{
+ struct value *value;
+
+ value = (*parent->root->lang->value_of_child) (parent, index);
+
+ /* If we're being lazy, fetch the real value of the variable. */
+ if (value != NULL && VALUE_LAZY (value))
+ {
+ /* If we fail to fetch the value of the child, return
+ NULL so that callers notice that we're leaving an
+ error message. */
+ if (!gdb_value_fetch_lazy (value))
+ value = NULL;
+ }
+
+ return value;
+}
+
+/* What is the type of VAR? */
+static struct type *
+type_of_child (struct varobj *var)
+{
+
+ /* If the child had no evaluation errors, var->value
+ will be non-NULL and contain a valid type. */
+ if (var->value != NULL)
+ return VALUE_TYPE (var->value);
+
+ /* Otherwise, we must compute the type. */
+ return (*var->root->lang->type_of_child) (var->parent, var->index);
+}
+
+/* Is this variable editable? Use the variable's type to make
+ this determination. */
+static int
+variable_editable (struct varobj *var)
+{
+ return (*var->root->lang->variable_editable) (var);
+}
+
+/* GDB already has a command called "value_of_variable". Sigh. */
+static char *
+my_value_of_variable (struct varobj *var)
+{
+ return (*var->root->lang->value_of_variable) (var);
+}
+
+/* Is VAR something that can change? Depending on language,
+ some variable's values never change. For example,
+ struct and unions never change values. */
+static int
+type_changeable (struct varobj *var)
+{
+ int r;
+ struct type *type;
+
+ if (CPLUS_FAKE_CHILD (var))
+ return 0;
+
+ type = get_type (var);
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_ARRAY:
+ r = 0;
+ break;
+
+ default:
+ r = 1;
+ }
+
+ return r;
+}
+
+/* C */
+static int
+c_number_of_children (struct varobj *var)
+{
+ struct type *type;
+ struct type *target;
+ int children;
+
+ type = get_type (var);
+ target = get_target_type (type);
+ children = 0;
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (target) > 0
+ && TYPE_ARRAY_UPPER_BOUND_TYPE (type) != BOUND_CANNOT_BE_DETERMINED)
+ children = TYPE_LENGTH (type) / TYPE_LENGTH (target);
+ else
+ children = -1;
+ break;
+
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ children = TYPE_NFIELDS (type);
+ break;
+
+ case TYPE_CODE_PTR:
+ /* This is where things get compilcated. All pointers have one child.
+ Except, of course, for struct and union ptr, which we automagically
+ dereference for the user and function ptrs, which have no children.
+ We also don't dereference void* as we don't know what to show.
+ We can show char* so we allow it to be dereferenced. If you decide
+ to test for it, please mind that a little magic is necessary to
+ properly identify it: char* has TYPE_CODE == TYPE_CODE_INT and
+ TYPE_NAME == "char" */
+
+ switch (TYPE_CODE (target))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ children = TYPE_NFIELDS (target);
+ break;
+
+ case TYPE_CODE_FUNC:
+ case TYPE_CODE_VOID:
+ children = 0;
+ break;
+
+ default:
+ children = 1;
+ }
+ break;
+
+ default:
+ /* Other types have no children */
+ break;
+ }
+
+ return children;
+}
+
+static char *
+c_name_of_variable (struct varobj *parent)
+{
+ return savestring (parent->name, strlen (parent->name));
+}
+
+static char *
+c_name_of_child (struct varobj *parent, int index)
+{
+ struct type *type;
+ struct type *target;
+ char *name;
+ char *string;
+
+ type = get_type (parent);
+ target = get_target_type (type);
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ {
+ /* We never get here unless parent->num_children is greater than 0... */
+ int len = 1;
+ while ((int) pow ((double) 10, (double) len) < index)
+ len++;
+ name = (char *) xmalloc (1 + len * sizeof (char));
+ sprintf (name, "%d", index);
+ }
+ break;
+
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ string = TYPE_FIELD_NAME (type, index);
+ name = savestring (string, strlen (string));
+ break;
+
+ case TYPE_CODE_PTR:
+ switch (TYPE_CODE (target))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ string = TYPE_FIELD_NAME (target, index);
+ name = savestring (string, strlen (string));
+ break;
+
+ default:
+ name =
+ (char *) xmalloc ((strlen (parent->name) + 2) * sizeof (char));
+ sprintf (name, "*%s", parent->name);
+ break;
+ }
+ break;
+
+ default:
+ /* This should not happen */
+ name = xstrdup ("???");
+ }
+
+ return name;
+}
+
+static struct value *
+c_value_of_root (struct varobj **var_handle)
+{
+ struct value *new_val;
+ struct varobj *var = *var_handle;
+ struct frame_info *fi;
+ int within_scope;
+
+ /* Only root variables can be updated... */
+ if (var->root->rootvar != var)
+ /* Not a root var */
+ return NULL;
+
+
+ /* Determine whether the variable is still around. */
+ if (var->root->valid_block == NULL)
+ within_scope = 1;
+ else
+ {
+ reinit_frame_cache ();
+
+
+ fi = find_frame_addr_in_frame_chain (var->root->frame);
+
+ within_scope = fi != NULL;
+ /* FIXME: select_frame could fail */
+ if (within_scope)
+ select_frame (fi);
+ }
+
+ if (within_scope)
+ {
+ /* We need to catch errors here, because if evaluate
+ expression fails we just want to make val->error = 1 and
+ go on */
+ if (gdb_evaluate_expression (var->root->exp, &new_val))
+ {
+ if (VALUE_LAZY (new_val))
+ {
+ /* We need to catch errors because if
+ value_fetch_lazy fails we still want to continue
+ (after making val->error = 1) */
+ /* FIXME: Shouldn't be using VALUE_CONTENTS? The
+ comment on value_fetch_lazy() says it is only
+ called from the macro... */
+ if (!gdb_value_fetch_lazy (new_val))
+ var->error = 1;
+ else
+ var->error = 0;
+ }
+ }
+ else
+ var->error = 1;
+
+ release_value (new_val);
+ return new_val;
+ }
+
+ return NULL;
+}
+
+static struct value *
+c_value_of_child (struct varobj *parent, int index)
+{
+ struct value *value;
+ struct value *temp;
+ struct value *indval;
+ struct type *type, *target;
+ char *name;
+
+ type = get_type (parent);
+ target = get_target_type (type);
+ name = name_of_child (parent, index);
+ temp = parent->value;
+ value = NULL;
+
+ if (temp != NULL)
+ {
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+#if 0
+ /* This breaks if the array lives in a (vector) register. */
+ value = value_slice (temp, index, 1);
+ temp = value_coerce_array (value);
+ gdb_value_ind (temp, &value);
+#else
+ indval = value_from_longest (builtin_type_int, (LONGEST) index);
+ gdb_value_subscript (temp, indval, &value);
+#endif
+ break;
+
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ gdb_value_struct_elt (NULL, &value, &temp, NULL, name, NULL, "vstructure");
+ break;
+
+ case TYPE_CODE_PTR:
+ switch (TYPE_CODE (target))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ gdb_value_struct_elt (NULL, &value, &temp, NULL, name, NULL, "vstructure");
+ break;
+
+ default:
+ gdb_value_ind (temp, &value);
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (value != NULL)
+ release_value (value);
+
+ xfree (name);
+ return value;
+}
+
+static struct type *
+c_type_of_child (struct varobj *parent, int index)
+{
+ struct type *type;
+ char *name = name_of_child (parent, index);
+
+ switch (TYPE_CODE (parent->type))
+ {
+ case TYPE_CODE_ARRAY:
+ type = TYPE_TARGET_TYPE (parent->type);
+ break;
+
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ type = lookup_struct_elt_type (parent->type, name, 0);
+ break;
+
+ case TYPE_CODE_PTR:
+ switch (TYPE_CODE (TYPE_TARGET_TYPE (parent->type)))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ type = lookup_struct_elt_type (parent->type, name, 0);
+ break;
+
+ default:
+ type = TYPE_TARGET_TYPE (parent->type);
+ break;
+ }
+ break;
+
+ default:
+ /* This should not happen as only the above types have children */
+ warning ("Child of parent whose type does not allow children");
+ /* FIXME: Can we still go on? */
+ type = NULL;
+ break;
+ }
+
+ xfree (name);
+ return type;
+}
+
+static int
+c_variable_editable (struct varobj *var)
+{
+ switch (TYPE_CODE (get_type (var)))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_FUNC:
+ case TYPE_CODE_MEMBER:
+ case TYPE_CODE_METHOD:
+ return 0;
+ break;
+
+ default:
+ return 1;
+ break;
+ }
+}
+
+static char *
+c_value_of_variable (struct varobj *var)
+{
+ struct type *type;
+
+ /* BOGUS: if val_print sees a struct/class, it will print out its
+ children instead of "{...}" */
+ type = get_type (var);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ return xstrdup ("{...}");
+ /* break; */
+
+ case TYPE_CODE_ARRAY:
+ {
+ char number[18];
+ sprintf (number, "[%d]", var->num_children);
+ return xstrdup (number);
+ }
+ /* break; */
+
+ default:
+ {
+ long dummy;
+ struct ui_file *stb = mem_fileopen ();
+ struct cleanup *old_chain = make_cleanup_ui_file_delete (stb);
+ char *thevalue;
+
+ if (var->value == NULL)
+ {
+ /* This can happen if we attempt to get the value of a struct
+ member when the parent is an invalid pointer. This is an
+ error condition, so we should tell the caller. */
+ return NULL;
+ }
+ else
+ {
+ if (VALUE_LAZY (var->value))
+ gdb_value_fetch_lazy (var->value);
+ val_print (VALUE_TYPE (var->value), VALUE_CONTENTS_RAW (var->value), 0,
+ VALUE_ADDRESS (var->value),
+ stb, format_code[(int) var->format], 1, 0, 0);
+ thevalue = ui_file_xstrdup (stb, &dummy);
+ do_cleanups (old_chain);
+ }
+
+ return thevalue;
+ }
+ /* break; */
+ }
+}
+
+
+/* C++ */
+
+static int
+cplus_number_of_children (struct varobj *var)
+{
+ struct type *type;
+ int children, dont_know;
+
+ dont_know = 1;
+ children = 0;
+
+ if (!CPLUS_FAKE_CHILD (var))
+ {
+ type = get_type_deref (var);
+
+ if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
+ ((TYPE_CODE (type)) == TYPE_CODE_UNION))
+ {
+ int kids[3];
+
+ cplus_class_num_children (type, kids);
+ if (kids[v_public] != 0)
+ children++;
+ if (kids[v_private] != 0)
+ children++;
+ if (kids[v_protected] != 0)
+ children++;
+
+ /* Add any baseclasses */
+ children += TYPE_N_BASECLASSES (type);
+ dont_know = 0;
+
+ /* FIXME: save children in var */
+ }
+ }
+ else
+ {
+ int kids[3];
+
+ type = get_type_deref (var->parent);
+
+ cplus_class_num_children (type, kids);
+ if (STREQ (var->name, "public"))
+ children = kids[v_public];
+ else if (STREQ (var->name, "private"))
+ children = kids[v_private];
+ else
+ children = kids[v_protected];
+ dont_know = 0;
+ }
+
+ if (dont_know)
+ children = c_number_of_children (var);
+
+ return children;
+}
+
+/* Compute # of public, private, and protected variables in this class.
+ That means we need to descend into all baseclasses and find out
+ how many are there, too. */
+static void
+cplus_class_num_children (struct type *type, int children[3])
+{
+ int i;
+
+ children[v_public] = 0;
+ children[v_private] = 0;
+ children[v_protected] = 0;
+
+ for (i = TYPE_N_BASECLASSES (type); i < TYPE_NFIELDS (type); i++)
+ {
+ /* If we have a virtual table pointer, omit it. */
+ if (TYPE_VPTR_BASETYPE (type) == type && TYPE_VPTR_FIELDNO (type) == i)
+ continue;
+
+ if (TYPE_FIELD_PROTECTED (type, i))
+ children[v_protected]++;
+ else if (TYPE_FIELD_PRIVATE (type, i))
+ children[v_private]++;
+ else
+ children[v_public]++;
+ }
+}
+
+static char *
+cplus_name_of_variable (struct varobj *parent)
+{
+ return c_name_of_variable (parent);
+}
+
+static char *
+cplus_name_of_child (struct varobj *parent, int index)
+{
+ char *name;
+ struct type *type;
+ int children[3];
+
+ if (CPLUS_FAKE_CHILD (parent))
+ {
+ /* Looking for children of public, private, or protected. */
+ type = get_type_deref (parent->parent);
+ }
+ else
+ type = get_type_deref (parent);
+
+ name = NULL;
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ cplus_class_num_children (type, children);
+
+ if (CPLUS_FAKE_CHILD (parent))
+ {
+ int i;
+
+ /* Skip over vptr, if it exists. */
+ if (TYPE_VPTR_BASETYPE (type) == type
+ && index >= TYPE_VPTR_FIELDNO (type))
+ index++;
+
+ /* FIXME: This assumes that type orders
+ inherited, public, private, protected */
+ i = index + TYPE_N_BASECLASSES (type);
+ if (STREQ (parent->name, "private") || STREQ (parent->name, "protected"))
+ i += children[v_public];
+ if (STREQ (parent->name, "protected"))
+ i += children[v_private];
+
+ name = TYPE_FIELD_NAME (type, i);
+ }
+ else if (index < TYPE_N_BASECLASSES (type))
+ name = TYPE_FIELD_NAME (type, index);
+ else
+ {
+ /* Everything beyond the baseclasses can
+ only be "public", "private", or "protected" */
+ index -= TYPE_N_BASECLASSES (type);
+ switch (index)
+ {
+ case 0:
+ if (children[v_public] != 0)
+ {
+ name = "public";
+ break;
+ }
+ case 1:
+ if (children[v_private] != 0)
+ {
+ name = "private";
+ break;
+ }
+ case 2:
+ if (children[v_protected] != 0)
+ {
+ name = "protected";
+ break;
+ }
+ default:
+ /* error! */
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (name == NULL)
+ return c_name_of_child (parent, index);
+ else
+ {
+ if (name != NULL)
+ name = savestring (name, strlen (name));
+ }
+
+ return name;
+}
+
+static struct value *
+cplus_value_of_root (struct varobj **var_handle)
+{
+ return c_value_of_root (var_handle);
+}
+
+static struct value *
+cplus_value_of_child (struct varobj *parent, int index)
+{
+ struct type *type;
+ struct value *value;
+
+ if (CPLUS_FAKE_CHILD (parent))
+ type = get_type_deref (parent->parent);
+ else
+ type = get_type_deref (parent);
+
+ value = NULL;
+
+ if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
+ ((TYPE_CODE (type)) == TYPE_CODE_UNION))
+ {
+ if (CPLUS_FAKE_CHILD (parent))
+ {
+ char *name;
+ struct value *temp = parent->parent->value;
+
+ if (temp == NULL)
+ return NULL;
+
+ name = name_of_child (parent, index);
+ gdb_value_struct_elt (NULL, &value, &temp, NULL, name, NULL,
+ "cplus_structure");
+ if (value != NULL)
+ release_value (value);
+
+ xfree (name);
+ }
+ else if (index >= TYPE_N_BASECLASSES (type))
+ {
+ /* public, private, or protected */
+ return NULL;
+ }
+ else
+ {
+ /* Baseclass */
+ if (parent->value != NULL)
+ {
+ struct value *temp = NULL;
+
+ if (TYPE_CODE (VALUE_TYPE (parent->value)) == TYPE_CODE_PTR
+ || TYPE_CODE (VALUE_TYPE (parent->value)) == TYPE_CODE_REF)
+ {
+ if (!gdb_value_ind (parent->value, &temp))
+ return NULL;
+ }
+ else
+ temp = parent->value;
+
+ if (temp != NULL)
+ {
+ value = value_cast (TYPE_FIELD_TYPE (type, index), temp);
+ release_value (value);
+ }
+ else
+ {
+ /* We failed to evaluate the parent's value, so don't even
+ bother trying to evaluate this child. */
+ return NULL;
+ }
+ }
+ }
+ }
+
+ if (value == NULL)
+ return c_value_of_child (parent, index);
+
+ return value;
+}
+
+static struct type *
+cplus_type_of_child (struct varobj *parent, int index)
+{
+ struct type *type, *t;
+
+ if (CPLUS_FAKE_CHILD (parent))
+ {
+ /* Looking for the type of a child of public, private, or protected. */
+ t = get_type_deref (parent->parent);
+ }
+ else
+ t = get_type_deref (parent);
+
+ type = NULL;
+ switch (TYPE_CODE (t))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ if (CPLUS_FAKE_CHILD (parent))
+ {
+ char *name = cplus_name_of_child (parent, index);
+ type = lookup_struct_elt_type (t, name, 0);
+ xfree (name);
+ }
+ else if (index < TYPE_N_BASECLASSES (t))
+ type = TYPE_FIELD_TYPE (t, index);
+ else
+ {
+ /* special */
+ return NULL;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (type == NULL)
+ return c_type_of_child (parent, index);
+
+ return type;
+}
+
+static int
+cplus_variable_editable (struct varobj *var)
+{
+ if (CPLUS_FAKE_CHILD (var))
+ return 0;
+
+ return c_variable_editable (var);
+}
+
+static char *
+cplus_value_of_variable (struct varobj *var)
+{
+
+ /* If we have one of our special types, don't print out
+ any value. */
+ if (CPLUS_FAKE_CHILD (var))
+ return xstrdup ("");
+
+ return c_value_of_variable (var);
+}
+
+/* Java */
+
+static int
+java_number_of_children (struct varobj *var)
+{
+ return cplus_number_of_children (var);
+}
+
+static char *
+java_name_of_variable (struct varobj *parent)
+{
+ char *p, *name;
+
+ name = cplus_name_of_variable (parent);
+ /* If the name has "-" in it, it is because we
+ needed to escape periods in the name... */
+ p = name;
+
+ while (*p != '\000')
+ {
+ if (*p == '-')
+ *p = '.';
+ p++;
+ }
+
+ return name;
+}
+
+static char *
+java_name_of_child (struct varobj *parent, int index)
+{
+ char *name, *p;
+
+ name = cplus_name_of_child (parent, index);
+ /* Escape any periods in the name... */
+ p = name;
+
+ while (*p != '\000')
+ {
+ if (*p == '.')
+ *p = '-';
+ p++;
+ }
+
+ return name;
+}
+
+static struct value *
+java_value_of_root (struct varobj **var_handle)
+{
+ return cplus_value_of_root (var_handle);
+}
+
+static struct value *
+java_value_of_child (struct varobj *parent, int index)
+{
+ return cplus_value_of_child (parent, index);
+}
+
+static struct type *
+java_type_of_child (struct varobj *parent, int index)
+{
+ return cplus_type_of_child (parent, index);
+}
+
+static int
+java_variable_editable (struct varobj *var)
+{
+ return cplus_variable_editable (var);
+}
+
+static char *
+java_value_of_variable (struct varobj *var)
+{
+ return cplus_value_of_variable (var);
+}
+
+extern void _initialize_varobj (void);
+void
+_initialize_varobj (void)
+{
+ int sizeof_table = sizeof (struct vlist *) * VAROBJ_TABLE_SIZE;
+
+ varobj_table = xmalloc (sizeof_table);
+ memset (varobj_table, 0, sizeof_table);
+
+ add_show_from_set (add_set_cmd ("debugvarobj", class_maintenance, var_zinteger, (char *) &varobjdebug, "Set varobj debugging.\n\
+When non-zero, varobj debugging is enabled.", &setlist),
+ &showlist);
+}
diff --git a/gdb/varobj.h b/gdb/varobj.h
new file mode 100644
index 00000000000..cd3023310a6
--- /dev/null
+++ b/gdb/varobj.h
@@ -0,0 +1,100 @@
+/* GDB variable objects API.
+ Copyright 1999, 2000 Free Software Foundation, Inc.
+
+ 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. */
+
+#ifndef VAROBJ_H
+#define VAROBJ_H 1
+
+#include "symtab.h"
+#include "gdbtypes.h"
+
+/* Enumeration for the format types */
+enum varobj_display_formats
+ {
+ FORMAT_NATURAL, /* What gdb actually calls 'natural' */
+ FORMAT_BINARY, /* Binary display */
+ FORMAT_DECIMAL, /* Decimal display */
+ FORMAT_HEXADECIMAL, /* Hex display */
+ FORMAT_OCTAL /* Octal display */
+ };
+
+enum varobj_type
+ {
+ USE_SPECIFIED_FRAME, /* Use the frame passed to varobj_create */
+ USE_CURRENT_FRAME, /* Use the current frame */
+ USE_SELECTED_FRAME /* Always reevaluate in selected frame */
+ };
+
+/* String representations of gdb's format codes (defined in varobj.c) */
+extern char *varobj_format_string[];
+
+/* Languages supported by this variable objects system. */
+enum varobj_languages
+ {
+ vlang_unknown = 0, vlang_c, vlang_cplus, vlang_java, vlang_end
+ };
+
+/* String representations of gdb's known languages (defined in varobj.c) */
+extern char *varobj_language_string[];
+
+/* Struct thar describes a variable object instance */
+struct varobj;
+
+/* API functions */
+
+extern struct varobj *varobj_create (char *objname,
+ char *expression, CORE_ADDR frame,
+ enum varobj_type type);
+
+extern char *varobj_gen_name (void);
+
+extern struct varobj *varobj_get_handle (char *name);
+
+extern char *varobj_get_objname (struct varobj *var);
+
+extern char *varobj_get_expression (struct varobj *var);
+
+extern int varobj_delete (struct varobj *var, char ***dellist,
+ int only_children);
+
+extern enum varobj_display_formats varobj_set_display_format (
+ struct varobj *var,
+ enum varobj_display_formats format);
+
+extern enum varobj_display_formats varobj_get_display_format (
+ struct varobj *var);
+
+extern int varobj_get_num_children (struct varobj *var);
+
+extern int varobj_list_children (struct varobj *var,
+ struct varobj ***childlist);
+
+extern char *varobj_get_type (struct varobj *var);
+
+extern enum varobj_languages varobj_get_language (struct varobj *var);
+
+extern int varobj_get_attributes (struct varobj *var);
+
+extern char *varobj_get_value (struct varobj *var);
+
+extern int varobj_set_value (struct varobj *var, char *expression);
+
+extern int varobj_list (struct varobj ***rootlist);
+
+extern int varobj_update (struct varobj **varp, struct varobj ***changelist);
+
+#endif /* VAROBJ_H */
diff --git a/gdb/vax-tdep.c b/gdb/vax-tdep.c
new file mode 100644
index 00000000000..0478227ee92
--- /dev/null
+++ b/gdb/vax-tdep.c
@@ -0,0 +1,709 @@
+/* Print VAX instructions for GDB, the GNU debugger.
+ Copyright 1986, 1989, 1991, 1992, 1995, 1996, 1998, 1999, 2000, 2002
+ 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 "defs.h"
+#include "symtab.h"
+#include "opcode/vax.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "frame.h"
+#include "value.h"
+#include "arch-utils.h"
+
+#include "vax-tdep.h"
+
+static gdbarch_register_name_ftype vax_register_name;
+static gdbarch_register_byte_ftype vax_register_byte;
+static gdbarch_register_raw_size_ftype vax_register_raw_size;
+static gdbarch_register_virtual_size_ftype vax_register_virtual_size;
+static gdbarch_register_virtual_type_ftype vax_register_virtual_type;
+
+static gdbarch_skip_prologue_ftype vax_skip_prologue;
+static gdbarch_saved_pc_after_call_ftype vax_saved_pc_after_call;
+static gdbarch_frame_num_args_ftype vax_frame_num_args;
+static gdbarch_frame_chain_ftype vax_frame_chain;
+static gdbarch_frame_saved_pc_ftype vax_frame_saved_pc;
+static gdbarch_frame_args_address_ftype vax_frame_args_address;
+static gdbarch_frame_locals_address_ftype vax_frame_locals_address;
+static gdbarch_frame_init_saved_regs_ftype vax_frame_init_saved_regs;
+static gdbarch_get_saved_register_ftype vax_get_saved_register;
+
+static gdbarch_store_struct_return_ftype vax_store_struct_return;
+static gdbarch_extract_return_value_ftype vax_extract_return_value;
+static gdbarch_store_return_value_ftype vax_store_return_value;
+static gdbarch_extract_struct_value_address_ftype
+ vax_extract_struct_value_address;
+
+static gdbarch_push_dummy_frame_ftype vax_push_dummy_frame;
+static gdbarch_pop_frame_ftype vax_pop_frame;
+static gdbarch_fix_call_dummy_ftype vax_fix_call_dummy;
+
+/* Return 1 if P points to an invalid floating point value.
+ LEN is the length in bytes -- not relevant on the Vax. */
+
+/* FIXME: cagney/2002-01-19: The macro below was originally defined in
+ tm-vax.h and used in values.c. Two problems. Firstly this is a
+ very non-portable and secondly it is wrong. The VAX should be
+ using floatformat and associated methods to identify and handle
+ invalid floating-point values. Adding to the poor target's woes
+ there is no floatformat_vax_{f,d} and no TARGET_FLOAT_FORMAT
+ et.al.. */
+
+/* FIXME: cagney/2002-01-19: It turns out that the only thing that
+ uses this macro is the vax disassembler code (so how old is this
+ target?). This target should instead be using the opcodes
+ disassembler. That allowing the macro to be eliminated. */
+
+#define INVALID_FLOAT(p, len) ((*(short *) p & 0xff80) == 0x8000)
+
+/* Vax instructions are never longer than this. */
+#define MAXLEN 62
+
+/* Number of elements in the opcode table. */
+#define NOPCODES (sizeof votstrs / sizeof votstrs[0])
+
+static unsigned char *print_insn_arg ();
+
+static char *
+vax_register_name (int regno)
+{
+ static char *register_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc",
+ "ps",
+ };
+
+ if (regno < 0)
+ return (NULL);
+ if (regno >= (sizeof(register_names) / sizeof(*register_names)))
+ return (NULL);
+ return (register_names[regno]);
+}
+
+static int
+vax_register_byte (int regno)
+{
+ return (regno * 4);
+}
+
+static int
+vax_register_raw_size (int regno)
+{
+ return (4);
+}
+
+static int
+vax_register_virtual_size (int regno)
+{
+ return (4);
+}
+
+static struct type *
+vax_register_virtual_type (int regno)
+{
+ return (builtin_type_int);
+}
+
+static void
+vax_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp,
+ struct frame_info *frame, int regnum,
+ enum lval_type *lval)
+{
+ CORE_ADDR addr;
+
+ if (!target_has_registers)
+ error ("No registers.");
+
+ /* Normal systems don't optimize out things with register numbers. */
+ if (optimized != NULL)
+ *optimized = 0;
+ addr = find_saved_register (frame, regnum);
+ if (addr != 0)
+ {
+ if (lval != NULL)
+ *lval = lval_memory;
+ if (regnum == SP_REGNUM)
+ {
+ if (raw_buffer != NULL)
+ {
+ /* Put it back in target format. */
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
+ (LONGEST) addr);
+ }
+ if (addrp != NULL)
+ *addrp = 0;
+ return;
+ }
+ if (raw_buffer != NULL)
+ target_read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum));
+ }
+ else
+ {
+ if (lval != NULL)
+ *lval = lval_register;
+ addr = REGISTER_BYTE (regnum);
+ if (raw_buffer != NULL)
+ read_register_gen (regnum, raw_buffer);
+ }
+ if (addrp != NULL)
+ *addrp = addr;
+}
+
+static void
+vax_frame_init_saved_regs (struct frame_info *frame)
+{
+ int regnum, regmask;
+ CORE_ADDR next_addr;
+
+ if (frame->saved_regs)
+ return;
+
+ frame_saved_regs_zalloc (frame);
+
+ regmask = read_memory_integer (frame->frame + 4, 4) >> 16;
+
+ next_addr = frame->frame + 16;
+
+ /* regmask's low bit is for register 0, which is the first one
+ what would be pushed. */
+ for (regnum = 0; regnum < AP_REGNUM; regnum++)
+ {
+ if (regmask & (1 << regnum))
+ frame->saved_regs[regnum] = next_addr += 4;
+ }
+
+ frame->saved_regs[SP_REGNUM] = next_addr + 4;
+ if (regmask & (1 << FP_REGNUM))
+ frame->saved_regs[SP_REGNUM] +=
+ 4 + (4 * read_memory_integer (next_addr + 4, 4));
+
+ frame->saved_regs[PC_REGNUM] = frame->frame + 16;
+ frame->saved_regs[FP_REGNUM] = frame->frame + 12;
+ frame->saved_regs[AP_REGNUM] = frame->frame + 8;
+ frame->saved_regs[PS_REGNUM] = frame->frame + 4;
+}
+
+static CORE_ADDR
+vax_frame_saved_pc (struct frame_info *frame)
+{
+ if (frame->signal_handler_caller)
+ return (sigtramp_saved_pc (frame)); /* XXXJRT */
+
+ return (read_memory_integer (frame->frame + 16, 4));
+}
+
+CORE_ADDR
+vax_frame_args_address_correct (struct frame_info *frame)
+{
+ /* Cannot find the AP register value directly from the FP value. Must
+ find it saved in the frame called by this one, or in the AP register
+ for the innermost frame. However, there is no way to tell the
+ difference between the innermost frame and a frame for which we
+ just don't know the frame that it called (e.g. "info frame 0x7ffec789").
+ For the sake of argument, suppose that the stack is somewhat trashed
+ (which is one reason that "info frame" exists). So, return 0 (indicating
+ we don't know the address of the arglist) if we don't know what frame
+ this frame calls. */
+ if (frame->next)
+ return (read_memory_integer (frame->next->frame + 8, 4));
+
+ return (0);
+}
+
+static CORE_ADDR
+vax_frame_args_address (struct frame_info *frame)
+{
+ /* In most of GDB, getting the args address is too important to
+ just say "I don't know". This is sometimes wrong for functions
+ that aren't on top of the stack, but c'est la vie. */
+ if (frame->next)
+ return (read_memory_integer (frame->next->frame + 8, 4));
+
+ return (read_register (AP_REGNUM));
+}
+
+static CORE_ADDR
+vax_frame_locals_address (struct frame_info *frame)
+{
+ return (frame->frame);
+}
+
+static int
+vax_frame_num_args (struct frame_info *fi)
+{
+ return (0xff & read_memory_integer (FRAME_ARGS_ADDRESS (fi), 1));
+}
+
+static CORE_ADDR
+vax_frame_chain (struct frame_info *frame)
+{
+ /* In the case of the VAX, the frame's nominal address is the FP value,
+ and 12 bytes later comes the saved previous FP value as a 4-byte word. */
+ if (inside_entry_file (frame->pc))
+ return (0);
+
+ return (read_memory_integer (frame->frame + 12, 4));
+}
+
+static void
+vax_push_dummy_frame (void)
+{
+ CORE_ADDR sp = read_register (SP_REGNUM);
+ int regnum;
+
+ sp = push_word (sp, 0); /* arglist */
+ for (regnum = 11; regnum >= 0; regnum--)
+ sp = push_word (sp, read_register (regnum));
+ sp = push_word (sp, read_register (PC_REGNUM));
+ sp = push_word (sp, read_register (FP_REGNUM));
+ sp = push_word (sp, read_register (AP_REGNUM));
+ sp = push_word (sp, (read_register (PS_REGNUM) & 0xffef) + 0x2fff0000);
+ sp = push_word (sp, 0);
+ write_register (SP_REGNUM, sp);
+ write_register (FP_REGNUM, sp);
+ write_register (AP_REGNUM, sp + (17 * 4));
+}
+
+static void
+vax_pop_frame (void)
+{
+ CORE_ADDR fp = read_register (FP_REGNUM);
+ int regnum;
+ int regmask = read_memory_integer (fp + 4, 4);
+
+ write_register (PS_REGNUM,
+ (regmask & 0xffff)
+ | (read_register (PS_REGNUM) & 0xffff0000));
+ write_register (PC_REGNUM, read_memory_integer (fp + 16, 4));
+ write_register (FP_REGNUM, read_memory_integer (fp + 12, 4));
+ write_register (AP_REGNUM, read_memory_integer (fp + 8, 4));
+ fp += 16;
+ for (regnum = 0; regnum < 12; regnum++)
+ if (regmask & (0x10000 << regnum))
+ write_register (regnum, read_memory_integer (fp += 4, 4));
+ fp = fp + 4 + ((regmask >> 30) & 3);
+ if (regmask & 0x20000000)
+ {
+ regnum = read_memory_integer (fp, 4);
+ fp += (regnum + 1) * 4;
+ }
+ write_register (SP_REGNUM, fp);
+ flush_cached_frames ();
+}
+
+/* The VAX call dummy sequence:
+
+ calls #69, @#32323232
+ bpt
+
+ It is 8 bytes long. The address and argc are patched by
+ vax_fix_call_dummy(). */
+static LONGEST vax_call_dummy_words[] = { 0x329f69fb, 0x03323232 };
+static int sizeof_vax_call_dummy_words = sizeof(vax_call_dummy_words);
+
+static void
+vax_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+ struct value **args, struct type *type, int gcc_p)
+{
+ dummy[1] = nargs;
+ store_unsigned_integer (dummy + 3, 4, fun);
+}
+
+static void
+vax_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ write_register (1, addr);
+}
+
+static void
+vax_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
+{
+ memcpy (valbuf, regbuf + REGISTER_BYTE (0), TYPE_LENGTH (valtype));
+}
+
+static void
+vax_store_return_value (struct type *valtype, char *valbuf)
+{
+ write_register_bytes (0, valbuf, TYPE_LENGTH (valtype));
+}
+
+static CORE_ADDR
+vax_extract_struct_value_address (char *regbuf)
+{
+ return (extract_address (regbuf + REGISTER_BYTE (0), REGISTER_RAW_SIZE (0)));
+}
+
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code. */
+
+static CORE_ADDR
+vax_skip_prologue (CORE_ADDR pc)
+{
+ register int op = (unsigned char) read_memory_integer (pc, 1);
+ if (op == 0x11)
+ pc += 2; /* skip brb */
+ if (op == 0x31)
+ pc += 3; /* skip brw */
+ if (op == 0xC2
+ && ((unsigned char) read_memory_integer (pc + 2, 1)) == 0x5E)
+ pc += 3; /* skip subl2 */
+ if (op == 0x9E
+ && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xAE
+ && ((unsigned char) read_memory_integer (pc + 3, 1)) == 0x5E)
+ pc += 4; /* skip movab */
+ if (op == 0x9E
+ && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xCE
+ && ((unsigned char) read_memory_integer (pc + 4, 1)) == 0x5E)
+ pc += 5; /* skip movab */
+ if (op == 0x9E
+ && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xEE
+ && ((unsigned char) read_memory_integer (pc + 6, 1)) == 0x5E)
+ pc += 7; /* skip movab */
+ return pc;
+}
+
+static CORE_ADDR
+vax_saved_pc_after_call (struct frame_info *frame)
+{
+ return (FRAME_SAVED_PC(frame));
+}
+
+/* Print the vax instruction at address MEMADDR in debugged memory,
+ from disassembler info INFO.
+ Returns length of the instruction, in bytes. */
+
+static int
+vax_print_insn (CORE_ADDR memaddr, disassemble_info *info)
+{
+ unsigned char buffer[MAXLEN];
+ register int i;
+ register unsigned char *p;
+ const char *d;
+
+ int status = (*info->read_memory_func) (memaddr, buffer, MAXLEN, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+
+ for (i = 0; i < NOPCODES; i++)
+ if (votstrs[i].detail.code == buffer[0]
+ || votstrs[i].detail.code == *(unsigned short *) buffer)
+ break;
+
+ /* Handle undefined instructions. */
+ if (i == NOPCODES)
+ {
+ (*info->fprintf_func) (info->stream, "0%o", buffer[0]);
+ return 1;
+ }
+
+ (*info->fprintf_func) (info->stream, "%s", votstrs[i].name);
+
+ /* Point at first byte of argument data,
+ and at descriptor for first argument. */
+ p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
+ d = votstrs[i].detail.args;
+
+ if (*d)
+ (*info->fprintf_func) (info->stream, " ");
+
+ while (*d)
+ {
+ p = print_insn_arg (d, p, memaddr + (p - buffer), info);
+ d += 2;
+ if (*d)
+ (*info->fprintf_func) (info->stream, ",");
+ }
+ return p - buffer;
+}
+
+static unsigned char *
+print_insn_arg (char *d, register char *p, CORE_ADDR addr,
+ disassemble_info *info)
+{
+ register int regnum = *p & 0xf;
+ float floatlitbuf;
+
+ if (*d == 'b')
+ {
+ if (d[1] == 'b')
+ (*info->fprintf_func) (info->stream, "0x%x", addr + *p++ + 1);
+ else
+ {
+ (*info->fprintf_func) (info->stream, "0x%x", addr + *(short *) p + 2);
+ p += 2;
+ }
+ }
+ else
+ switch ((*p++ >> 4) & 0xf)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3: /* Literal mode */
+ if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
+ {
+ *(int *) &floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
+ (*info->fprintf_func) (info->stream, "$%f", floatlitbuf);
+ }
+ else
+ (*info->fprintf_func) (info->stream, "$%d", p[-1] & 0x3f);
+ break;
+
+ case 4: /* Indexed */
+ p = (char *) print_insn_arg (d, p, addr + 1, info);
+ (*info->fprintf_func) (info->stream, "[%s]", REGISTER_NAME (regnum));
+ break;
+
+ case 5: /* Register */
+ (*info->fprintf_func) (info->stream, REGISTER_NAME (regnum));
+ break;
+
+ case 7: /* Autodecrement */
+ (*info->fprintf_func) (info->stream, "-");
+ case 6: /* Register deferred */
+ (*info->fprintf_func) (info->stream, "(%s)", REGISTER_NAME (regnum));
+ break;
+
+ case 9: /* Autoincrement deferred */
+ (*info->fprintf_func) (info->stream, "@");
+ if (regnum == PC_REGNUM)
+ {
+ (*info->fprintf_func) (info->stream, "#");
+ info->target = *(long *) p;
+ (*info->print_address_func) (info->target, info);
+ p += 4;
+ break;
+ }
+ case 8: /* Autoincrement */
+ if (regnum == PC_REGNUM)
+ {
+ (*info->fprintf_func) (info->stream, "#");
+ switch (d[1])
+ {
+ case 'b':
+ (*info->fprintf_func) (info->stream, "%d", *p++);
+ break;
+
+ case 'w':
+ (*info->fprintf_func) (info->stream, "%d", *(short *) p);
+ p += 2;
+ break;
+
+ case 'l':
+ (*info->fprintf_func) (info->stream, "%d", *(long *) p);
+ p += 4;
+ break;
+
+ case 'q':
+ (*info->fprintf_func) (info->stream, "0x%x%08x",
+ ((long *) p)[1], ((long *) p)[0]);
+ p += 8;
+ break;
+
+ case 'o':
+ (*info->fprintf_func) (info->stream, "0x%x%08x%08x%08x",
+ ((long *) p)[3], ((long *) p)[2],
+ ((long *) p)[1], ((long *) p)[0]);
+ p += 16;
+ break;
+
+ case 'f':
+ if (INVALID_FLOAT (p, 4))
+ (*info->fprintf_func) (info->stream,
+ "<<invalid float 0x%x>>",
+ *(int *) p);
+ else
+ (*info->fprintf_func) (info->stream, "%f", *(float *) p);
+ p += 4;
+ break;
+
+ case 'd':
+ if (INVALID_FLOAT (p, 8))
+ (*info->fprintf_func) (info->stream,
+ "<<invalid float 0x%x%08x>>",
+ ((long *) p)[1], ((long *) p)[0]);
+ else
+ (*info->fprintf_func) (info->stream, "%f", *(double *) p);
+ p += 8;
+ break;
+
+ case 'g':
+ (*info->fprintf_func) (info->stream, "g-float");
+ p += 8;
+ break;
+
+ case 'h':
+ (*info->fprintf_func) (info->stream, "h-float");
+ p += 16;
+ break;
+
+ }
+ }
+ else
+ (*info->fprintf_func) (info->stream, "(%s)+", REGISTER_NAME (regnum));
+ break;
+
+ case 11: /* Byte displacement deferred */
+ (*info->fprintf_func) (info->stream, "@");
+ case 10: /* Byte displacement */
+ if (regnum == PC_REGNUM)
+ {
+ info->target = addr + *p + 2;
+ (*info->print_address_func) (info->target, info);
+ }
+ else
+ (*info->fprintf_func) (info->stream, "%d(%s)", *p, REGISTER_NAME (regnum));
+ p += 1;
+ break;
+
+ case 13: /* Word displacement deferred */
+ (*info->fprintf_func) (info->stream, "@");
+ case 12: /* Word displacement */
+ if (regnum == PC_REGNUM)
+ {
+ info->target = addr + *(short *) p + 3;
+ (*info->print_address_func) (info->target, info);
+ }
+ else
+ (*info->fprintf_func) (info->stream, "%d(%s)",
+ *(short *) p, REGISTER_NAME (regnum));
+ p += 2;
+ break;
+
+ case 15: /* Long displacement deferred */
+ (*info->fprintf_func) (info->stream, "@");
+ case 14: /* Long displacement */
+ if (regnum == PC_REGNUM)
+ {
+ info->target = addr + *(short *) p + 5;
+ (*info->print_address_func) (info->target, info);
+ }
+ else
+ (*info->fprintf_func) (info->stream, "%d(%s)",
+ *(long *) p, REGISTER_NAME (regnum));
+ p += 4;
+ }
+
+ return (unsigned char *) p;
+}
+
+/* Initialize the current architecture based on INFO. If possible, re-use an
+ architecture from ARCHES, which is a list of architectures already created
+ during this debugging session.
+
+ Called e.g. at program startup, when reading a core file, and when reading
+ a binary file. */
+
+static struct gdbarch *
+vax_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch *gdbarch;
+
+ /* Right now there is only one VAX architecture variant. */
+ if (arches != NULL)
+ return (arches->gdbarch);
+
+ gdbarch = gdbarch_alloc (&info, NULL);
+
+ /* Register info */
+ set_gdbarch_num_regs (gdbarch, VAX_NUM_REGS);
+ set_gdbarch_sp_regnum (gdbarch, VAX_SP_REGNUM);
+ set_gdbarch_fp_regnum (gdbarch, VAX_FP_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, VAX_PC_REGNUM);
+ set_gdbarch_ps_regnum (gdbarch, VAX_PS_REGNUM);
+
+ set_gdbarch_register_name (gdbarch, vax_register_name);
+ set_gdbarch_register_size (gdbarch, VAX_REGISTER_SIZE);
+ set_gdbarch_register_bytes (gdbarch, VAX_REGISTER_BYTES);
+ set_gdbarch_register_byte (gdbarch, vax_register_byte);
+ set_gdbarch_register_raw_size (gdbarch, vax_register_raw_size);
+ set_gdbarch_max_register_raw_size (gdbarch, VAX_MAX_REGISTER_RAW_SIZE);
+ set_gdbarch_register_virtual_size (gdbarch, vax_register_virtual_size);
+ set_gdbarch_max_register_virtual_size (gdbarch,
+ VAX_MAX_REGISTER_VIRTUAL_SIZE);
+ set_gdbarch_register_virtual_type (gdbarch, vax_register_virtual_type);
+
+ /* Frame and stack info */
+ set_gdbarch_skip_prologue (gdbarch, vax_skip_prologue);
+ set_gdbarch_saved_pc_after_call (gdbarch, vax_saved_pc_after_call);
+
+ set_gdbarch_frame_num_args (gdbarch, vax_frame_num_args);
+ set_gdbarch_frameless_function_invocation (gdbarch,
+ generic_frameless_function_invocation_not);
+
+ set_gdbarch_frame_chain (gdbarch, vax_frame_chain);
+ set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
+ set_gdbarch_frame_saved_pc (gdbarch, vax_frame_saved_pc);
+
+ set_gdbarch_frame_args_address (gdbarch, vax_frame_args_address);
+ set_gdbarch_frame_locals_address (gdbarch, vax_frame_locals_address);
+
+ set_gdbarch_frame_init_saved_regs (gdbarch, vax_frame_init_saved_regs);
+
+ set_gdbarch_frame_args_skip (gdbarch, 4);
+
+ set_gdbarch_get_saved_register (gdbarch, vax_get_saved_register);
+
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+
+ /* Return value info */
+ set_gdbarch_store_struct_return (gdbarch, vax_store_struct_return);
+ set_gdbarch_extract_return_value (gdbarch, vax_extract_return_value);
+ set_gdbarch_store_return_value (gdbarch, vax_store_return_value);
+ set_gdbarch_extract_struct_value_address (gdbarch,
+ vax_extract_struct_value_address);
+
+ /* Call dummy info */
+ set_gdbarch_push_dummy_frame (gdbarch, vax_push_dummy_frame);
+ set_gdbarch_pop_frame (gdbarch, vax_pop_frame);
+ set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_words (gdbarch, vax_call_dummy_words);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof_vax_call_dummy_words);
+ set_gdbarch_fix_call_dummy (gdbarch, vax_fix_call_dummy);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 7);
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+
+ /* Breakpoint info */
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+
+ /* Misc info */
+ set_gdbarch_function_start_offset (gdbarch, 2);
+
+ return (gdbarch);
+}
+
+void
+_initialize_vax_tdep (void)
+{
+ gdbarch_register (bfd_arch_vax, vax_gdbarch_init, NULL);
+
+ tm_print_insn = vax_print_insn;
+}
diff --git a/gdb/vax-tdep.h b/gdb/vax-tdep.h
new file mode 100644
index 00000000000..95324bcc036
--- /dev/null
+++ b/gdb/vax-tdep.h
@@ -0,0 +1,55 @@
+/* Common target dependent code for GDB on VAX systems.
+ Copyright 2002 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. */
+
+#ifndef VAX_TDEP_H
+#define VAX_TDEP_H
+
+/* Say how long (ordinary) registers are. This is a piece of bogosity
+ used in push_word and a few other places; REGISTER_RAW_SIZE is the
+ real way to know how big a register is. */
+#define VAX_REGISTER_SIZE 4
+
+/* Number of machine registers. */
+#define VAX_NUM_REGS 17
+
+/* Total amount of space needed to store our copies of the machine's
+ register state. */
+#define VAX_REGISTER_BYTES (VAX_NUM_REGS * 4)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+#define VAX_MAX_REGISTER_RAW_SIZE 4
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+#define VAX_MAX_REGISTER_VIRTUAL_SIZE 4
+
+/* Register numbers of various important registers.
+ Note that most of these values are "real" register numbers,
+ and correspond to the general registers of the machine,
+ and are "phony" register numbers which is too large
+ to be an actual register number as far as the user is concerned
+ but serves to get the desired value when passed to read_register. */
+
+#define VAX_AP_REGNUM 12 /* argument pointer */
+#define VAX_FP_REGNUM 13 /* Contains address of executing stack frame */
+#define VAX_SP_REGNUM 14 /* Contains address of top of stack */
+#define VAX_PC_REGNUM 15 /* Contains program counter */
+#define VAX_PS_REGNUM 16 /* Contains processor status */
+
+#endif /* VAX_TDEP_H */
diff --git a/gdb/version.h b/gdb/version.h
new file mode 100644
index 00000000000..b324af96088
--- /dev/null
+++ b/gdb/version.h
@@ -0,0 +1,33 @@
+/* Version information for GDB.
+ Copyright 1999 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. */
+
+#ifndef VERSION_H
+#define VERSION_H
+
+/* Version number of GDB, as a string. */
+extern const char version[];
+
+/* Canonical host name as a string. */
+extern const char host_name[];
+
+/* Canonical target name as a string. */
+extern const char target_name[];
+
+#endif /* #ifndef VERSION_H */
diff --git a/gdb/version.in b/gdb/version.in
new file mode 100644
index 00000000000..728029ebfcf
--- /dev/null
+++ b/gdb/version.in
@@ -0,0 +1 @@
+2002-05-28-cvs
diff --git a/gdb/vx-share/README b/gdb/vx-share/README
new file mode 100644
index 00000000000..924b668585e
--- /dev/null
+++ b/gdb/vx-share/README
@@ -0,0 +1,7 @@
+The files in this directory are shared with Wind River Systems' VxWorks
+debug stub. This stub runs in the realtime system, as a process, and
+waits for net connections from GDB's and DBX's and such.
+
+Do not change these files without coordinating with Wind River Systems
+in Alameda, California. Talk to postmaster@wrs.com to find out who
+currently maintains GDB for them.
diff --git a/gdb/vx-share/dbgRpcLib.h b/gdb/vx-share/dbgRpcLib.h
new file mode 100644
index 00000000000..e858e558e43
--- /dev/null
+++ b/gdb/vx-share/dbgRpcLib.h
@@ -0,0 +1,32 @@
+/* Copyright 1992 Free Software Foundation, Inc.
+
+ This code was donated by Wind River Systems, Inc.
+
+ dbgRpcLib.h - header file for remote debugging via rpc */
+
+/*
+modification history
+--------------------
+01b,04oct90,maf added VX_BOOT_FILE_INQ.
+01a,05jun90,llk extracted from xdr_dbx.h.
+*/
+
+#ifndef INCdbxRpcLibh
+#define INCdbxRpcLibh 1
+
+#define PROCESS_START 50
+#define PROCESS_WAIT 51
+#define VX_STATE_INQ 60
+#define VX_LOAD 61
+#define VX_SYMBOL_INQ 62
+#define VX_BREAK_ADD 63
+#define VX_BREAK_DELETE 64
+#define VX_FP_INQUIRE 65
+#define VX_TASK_SUSPEND 66
+#define VX_CALL_FUNC 67
+#define VX_CONV_FROM_68881 68
+#define VX_CONV_TO_68881 69
+#define VX_BOOT_FILE_INQ 70
+#define VX_SOURCE_STEP 71
+
+#endif INCdbxRpcLibh
diff --git a/gdb/vx-share/ptrace.h b/gdb/vx-share/ptrace.h
new file mode 100644
index 00000000000..8e3554f13a0
--- /dev/null
+++ b/gdb/vx-share/ptrace.h
@@ -0,0 +1,44 @@
+/* @(#)ptrace.h 1.1 86/07/07 SMI */
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+/*
+modification history
+--------------------
+01a,05jun90,llk borrowed.
+*/
+
+#ifndef _PTRACE_
+#define _PTRACE_
+
+/*
+ * Request values for the ptrace system call
+ */
+enum ptracereq {
+ PTRACE_TRACEME = 0, /* 0, by tracee to begin tracing */
+ PTRACE_CHILDDONE = 0, /* 0, tracee is done with his half */
+ PTRACE_PEEKTEXT, /* 1, read word from text segment */
+ PTRACE_PEEKDATA, /* 2, read word from data segment */
+ PTRACE_PEEKUSER, /* 3, read word from user struct */
+ PTRACE_POKETEXT, /* 4, write word into text segment */
+ PTRACE_POKEDATA, /* 5, write word into data segment */
+ PTRACE_POKEUSER, /* 6, write word into user struct */
+ PTRACE_CONT, /* 7, continue process */
+ PTRACE_KILL, /* 8, terminate process */
+ PTRACE_SINGLESTEP, /* 9, single step process */
+ PTRACE_ATTACH, /* 10, attach to an existing process */
+ PTRACE_DETACH, /* 11, detach from a process */
+ PTRACE_GETREGS, /* 12, get all registers */
+ PTRACE_SETREGS, /* 13, set all registers */
+ PTRACE_GETFPREGS, /* 14, get all floating point regs */
+ PTRACE_SETFPREGS, /* 15, set all floating point regs */
+ PTRACE_READDATA, /* 16, read data segment */
+ PTRACE_WRITEDATA, /* 17, write data segment */
+ PTRACE_READTEXT, /* 18, read text segment */
+ PTRACE_WRITETEXT, /* 19, write text segment */
+ PTRACE_GETFPAREGS, /* 20, get all fpa regs */
+ PTRACE_SETFPAREGS /* 21, set all fpa regs */
+};
+#endif !_PTRACE
diff --git a/gdb/vx-share/regPacket.h b/gdb/vx-share/regPacket.h
new file mode 100644
index 00000000000..6160c846862
--- /dev/null
+++ b/gdb/vx-share/regPacket.h
@@ -0,0 +1,160 @@
+/* regPacket.h - register packet definitions for rdb */
+
+/* Copyright 1992-1993 Wind River Systems, Inc. */
+
+/*
+modification history
+--------------------
+01d,30nov93,pad Added Am29K target definitions.
+01c,14jun93,maf additional definitions for documentation purposes.
+ fixed reversal of MIPS_R_LO and MIPS_R_HI.
+01b,08feb93,scy added SPARC target definitions. changed to WRS code convetion.
+01a,20feb92,j_w created.
+*/
+
+#ifndef __INCregPacketh
+#define __INCregPacketh
+
+
+/* MC68K */
+
+#define MC68K_GREG_SIZE 0x04 /* size of general-purpose reg */
+#define MC68K_GREG_PLEN 0x48 /* size of general-purpose reg block */
+
+/* offsets into general-purpose register block */
+
+#define MC68K_R_D0 0x00 /* d0; d1 - d7 follow in sequence */
+#define MC68K_R_A0 0x20 /* a0; a1 - a7 follow in sequence */
+#define MC68K_R_SR 0x40 /* sr (represented as a 4-byte val) */
+#define MC68K_R_PC 0x44 /* pc */
+
+#define MC68K_FPREG_SIZE 0x0c /* size of floating-point data reg */
+#define MC68K_FPREG_PLEN 0x6c /* size of floating-point reg block */
+
+/* offsets into floating-point register block */
+
+#define MC68K_R_FP0 0x00 /* fp0; fp1 - fp7 follow in sequence */
+#define MC68K_R_FPCR 0x60 /* fpcr */
+#define MC68K_R_FPSR 0x64 /* fpsr */
+#define MC68K_R_FPIAR 0x68 /* fpiar */
+
+
+/* I960 */
+
+#define I960_GREG_SIZE 0x04 /* size of general-purpose reg */
+#define I960_GREG_PLEN 0x8c /* size of general-purpose reg block */
+
+/* offsets into general-purpose register block */
+
+#define I960_R_R0 0x00 /* r0; r1 - r15 follow in sequence */
+#define I960_R_G0 0x40 /* g0; g1 - g15 follow in sequence */
+#define I960_R_PCW 0x80 /* pcw */
+#define I960_R_ACW 0x84 /* acw */
+#define I960_R_TCW 0x88 /* tcw */
+
+#define I960_FPREG_SIZE 0x10 /* size of floating-point reg */
+#define I960_FPREG_PLEN 0x28 /* size of floating-point reg block */
+
+/* offsets into floating-point register block */
+
+#define I960_R_FP0 0x00 /* fp0; fp1 - fp3 follow in sequence */
+
+
+/* SPARC */
+
+#define SPARC_GREG_SIZE 0x04 /* size of general-purpose reg */
+#define SPARC_GREG_PLEN 0x98 /* size of general-purpose reg block */
+
+/* offsets into general-purpose register block */
+
+#define SPARC_R_G0 0x00 /* g0; g1 - g7 follow in sequence */
+#define SPARC_R_O0 0x20 /* o0; o1 - o7 follow in sequence */
+#define SPARC_R_L0 0x40 /* l0; l1 - l7 follow in sequence */
+#define SPARC_R_I0 0x60 /* i0; i1 - i7 follow in sequence */
+#define SPARC_R_Y 0x80 /* y */
+#define SPARC_R_PSR 0x84 /* psr */
+#define SPARC_R_WIM 0x88 /* wim */
+#define SPARC_R_TBR 0x8c /* tbr */
+#define SPARC_R_PC 0x90 /* pc */
+#define SPARC_R_NPC 0x94 /* npc */
+
+#define SPARC_FPREG_SIZE 0x04 /* size of floating-point reg */
+#define SPARC_FPREG_PLEN 0x84 /* size of floating-point reg block */
+
+/* offsets into floating-point register block */
+
+#define SPARC_R_FP0 0x00 /* f0; f1 - f31 follow in sequence */
+#define SPARC_R_FSR 0x80 /* fsr */
+
+
+/* MIPS */
+
+#define MIPS_GREG_SIZE 0x04 /* size of general-purpose reg */
+#define MIPS_GREG_PLEN 0x90 /* size of general-purpose reg block */
+
+/* offsets into general-purpose register block */
+
+#define MIPS_R_GP0 0x00 /* gp0 (zero) */
+#define MIPS_R_AT 0x04 /* at */
+#define MIPS_R_V0 0x08 /* v0 */
+#define MIPS_R_V1 0x0c /* v1 */
+#define MIPS_R_A0 0x10 /* a0 */
+#define MIPS_R_A1 0x14 /* a1 */
+#define MIPS_R_A2 0x18 /* a2 */
+#define MIPS_R_A3 0x1c /* a3 */
+#define MIPS_R_T0 0x20 /* t0 */
+#define MIPS_R_T1 0x24 /* t1 */
+#define MIPS_R_T2 0x28 /* t2 */
+#define MIPS_R_T3 0x2c /* t3 */
+#define MIPS_R_T4 0x30 /* t4 */
+#define MIPS_R_T5 0x34 /* t5 */
+#define MIPS_R_T6 0x38 /* t6 */
+#define MIPS_R_T7 0x3c /* t7 */
+#define MIPS_R_S0 0x40 /* s0 */
+#define MIPS_R_S1 0x44 /* s1 */
+#define MIPS_R_S2 0x48 /* s2 */
+#define MIPS_R_S3 0x4c /* s3 */
+#define MIPS_R_S4 0x50 /* s4 */
+#define MIPS_R_S5 0x54 /* s5 */
+#define MIPS_R_S6 0x58 /* s6 */
+#define MIPS_R_S7 0x5c /* s7 */
+#define MIPS_R_T8 0x60 /* t8 */
+#define MIPS_R_T9 0x64 /* t9 */
+#define MIPS_R_K0 0x68 /* k0 */
+#define MIPS_R_K1 0x6c /* k1 */
+#define MIPS_R_GP 0x70 /* gp */
+#define MIPS_R_SP 0x74 /* sp */
+#define MIPS_R_S8 0x78 /* s8 */
+#define MIPS_R_LO 0x80 /* lo */
+#define MIPS_R_HI 0x84 /* hi */
+#define MIPS_R_SR 0x88 /* sr */
+#define MIPS_R_PC 0x8c /* pc */
+
+#define MIPS_FPREG_SIZE 0x04 /* size of floating-point data reg */
+#define MIPS_FPREG_PLEN 0x84 /* size of floating-point reg block */
+
+/* offsets into floating-point register block */
+
+#define MIPS_R_FP0 0x00 /* f0; f1 - f31 follow in sequence */
+#define MIPS_R_FPCSR 0x80 /* offset of fpcsr in reg block */
+
+
+/* General registers for the Am29k */
+
+#define AM29K_GREG_SIZE 0x04
+#define AM29K_GREG_PLEN 0x2d4
+
+#define AM29K_R_GR96 0x0
+#define AM29K_R_VAB 0x280
+#define AM29K_R_INTE 0x2bc
+#define AM29K_R_RSP 0x2c0
+
+/* Floating Point registers for the Am29k */
+
+#define AM29K_FPREG_SIZE 0x04
+#define AM29K_FPREG_PLEN 0x8
+
+#define AM29K_R_FPE 0x0
+#define AM29K_R_FPS 0x4
+
+#endif /* __INCregPacketh */
diff --git a/gdb/vx-share/vxTypes.h b/gdb/vx-share/vxTypes.h
new file mode 100644
index 00000000000..c6b84192233
--- /dev/null
+++ b/gdb/vx-share/vxTypes.h
@@ -0,0 +1,72 @@
+/* vxTypes.h - VxWorks type definition header */
+
+/* Copyright 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1992 Free Software Foundation, Inc.
+
+ This code was donated by Wind River Systems, Inc. */
+
+/*
+modification history
+--------------------
+01c,05oct90,shl added copyright notice.
+ made #endif ANSI style.
+01b,10aug90,dnw added VOIDFUNCPTR
+01a,29may90,del written.
+*/
+
+#ifndef INCvxTypesh
+#define INCvxTypesh
+
+/* The following stuff must NOT be included if this include file is used
+ * from assembly language. Just #define ASMLANGUAGE before the include,
+ * to get rid of it.
+ */
+
+#ifndef ASMLANGUAGE
+
+/* vxWorks types */
+
+typedef char INT8;
+typedef short INT16;
+typedef int INT32;
+
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef unsigned int UINT32;
+
+typedef unsigned char UCHAR;
+typedef unsigned short USHORT;
+typedef unsigned int UINT;
+typedef unsigned long ULONG;
+
+typedef int BOOL;
+typedef int VOID;
+typedef int STATUS;
+typedef int ARGINT;
+
+typedef int (*FUNCPTR) (); /* ptr to function returning int */
+typedef VOID (*VOIDFUNCPTR) (); /* ptr to function returning VOID */
+
+
+/* historical definitions - now obsolete */
+
+typedef char TINY; /* obsolete */
+typedef char TBOOL; /* obsolete */
+typedef unsigned char UTINY; /* obsolete */
+
+
+/* architecture dependent typedefs */
+
+#ifdef CPU_FAMILY
+
+#if CPU_FAMILY==MC680X0
+typedef unsigned short INSTR; /* word-aligned instructions */
+#endif /* CPU_FAMILY==MC680X0 */
+
+#if CPU_FAMILY==SPARC
+typedef unsigned long INSTR; /* 32 bit word-aligned instructions */
+#endif /* CPU_FAMILY==SPARC */
+
+#endif
+
+#endif /* ASMLANGUAGE */
+#endif /* INCvxTypesh */
diff --git a/gdb/vx-share/vxWorks.h b/gdb/vx-share/vxWorks.h
new file mode 100644
index 00000000000..b02c66fab03
--- /dev/null
+++ b/gdb/vx-share/vxWorks.h
@@ -0,0 +1,172 @@
+/* vxWorks.h - VxWorks standard definitions header */
+
+/* Copyright 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1992, 1993
+ Free Software Foundation, Inc.
+
+ This code was donated by Wind River Systems, Inc. */
+
+/*
+modification history
+--------------------
+01z,05oct90,shl added copyright notice.
+ made #endif ANSI style.
+01y,28sep90,del added I960 defines.
+01x,29may90,del moved types to vxTypes.h
+01w,09apr90,jcf added timeout definitions.
+01v,24jan90,gae moved network configuration flags here from makefile's.
+01u,01sep88,mcl definition of INSTR dependent on processor family; added SPARC.
+ +gae added MC680X0 and defined CPU_FAMILY.
+01t,08apr89,dnw added ifdef to prevent inclusion of vxWorks.h more than once.
+01s,22jun88,dnw moved READ, WRITE, and UPDATE back here from ioLib.h.
+01r,22apr88,gae oops! forgot some #endif's in 01q.
+01q,12apr88,gae removed QUICK & WAIT; added STD_{IN,OUT,ERR}.
+ fixed #define's of FALSE, TRUE, etc.
+ moved READ, WRITE, and UPDATE to ioLib.h.
+01p,04dec87,dnw added undefine of MC68000 to get around Green Hills bug that
+ pre-defines MC68000.
+01o,12nov87,ecs added type ULONG.
+01n,08feb86,dnw added types INSTR, UINT, USHORT.
+01m,14oct85,rdc added BUS types.
+01l,16jul85,jlf added conditional for NULL and EOF.
+01k,24jun85,rdc installed condtional compile so we can include in
+ assembly language files. See instructions below.
+ Added System type macro and CPU type macro.
+01j,13jun85,dnw cleaned-up, removed more obsolete stuff to wrs.h
+01i,11sep84,jlf changed name from wrs.h to vxWorks.h. removed GLOBAL.
+01h,03jun84,dnw removed IGNORE declaration.
+01g,09apr84,jlf added MEMBER_SIZE macro.
+01f,14dec83,dnw added MSB, LSB macros
+01e,17nov83,jlf added STATUS type, for routines which return a status.
+01d,13jul83,dnw added NELEMENTS macro
+01c,14May83,dnw added OFFSET macro
+01b,17Feb83,dnw added stuff from Whitesmiths std.h
+01a,15Feb83,dnw written
+*/
+
+#ifndef INCvxWorksh
+#define INCvxWorksh
+
+#if !defined(EOF) || (EOF!=(-1))
+#define EOF (-1)
+#endif
+
+#if !defined(FALSE) || (FALSE!=0)
+#define FALSE 0
+#endif
+
+#if !defined(TRUE) || (TRUE!=1)
+#define TRUE 1
+#endif
+
+
+#define NONE (-1) /* for times when NULL won't do */
+#define EOS '\0' /* C string terminator */
+
+
+/* return status values */
+
+#define OK 0
+#define ERROR (-1)
+
+/* timeout defines */
+
+#define NO_WAIT 0
+#define WAIT_FOREVER (-1)
+
+/* low-level I/O input, output, error fd's */
+
+#define STD_IN 0
+#define STD_OUT 1
+#define STD_ERR 2
+
+/* modes - must match O_RDONLY/O_WRONLY/O_RDWR in ioLib.h! */
+
+#define READ 0
+#define WRITE 1
+#define UPDATE 2
+
+/* SYSTEM types */
+
+#define V7 1 /* ATT version 7 */
+#define SYS_V 2 /* ATT System 5 */
+#define BSD_4_2 3 /* Berkeley BSD 4.2 */
+
+/* CPU types */
+
+/* The Green Hills compiler pre-defines "MC68000"!! */
+#ifdef MC68000
+#undef MC68000
+#endif
+
+#define MC68000 1
+#define MC68010 2
+#define MC68020 3
+#define MC68030 4
+#define MC68040 5
+#define MC680X0 9
+
+#define SPARC 10
+
+#ifndef I960
+#define I960 20
+#endif
+
+#define I960KB 21
+#define I960CA 22
+
+#if CPU==MC68000 || CPU==MC68010 || CPU==MC68020 || CPU==MC68030
+#define CPU_FAMILY MC680X0
+#endif /* CPU==MC68000 || CPU==MC68010 || CPU==MC68020 || CPU==MC68030 */
+
+#if CPU==SPARC
+#define CPU_FAMILY SPARC
+#endif /* CPU==SPARC */
+
+#if CPU==I960KB
+#define CPU_FAMILY I960
+#endif /* CPU==I960KB */
+
+#if CPU==I960CA
+#define CPU_FAMILY I960
+#endif /* CPU==I960CA */
+
+/* BUS types */
+
+#define VME_BUS 1
+#define MULTI_BUS 2
+
+/* network configuration parameters */
+
+#define INET /* include internet protocols */
+#define BSD 43 /* BSD 4.3 -like OS */
+#define BSDDEBUG /* turn on debug */
+#define GATEWAY /* tables to be initialized for gateway routing */
+
+/* common macros */
+
+#define MSB(x) (((x) >> 8) & 0xff) /* most signif byte of 2-byte integer */
+#define LSB(x) ((x) & 0xff) /* least signif byte of 2-byte integer*/
+
+#define OFFSET(structure, member) /* byte offset of member in structure*/\
+ ((int) &(((structure *) 0) -> member))
+
+#define MEMBER_SIZE(structure, member) /* size of a member of a structure */\
+ (sizeof (((structure *) 0) -> member))
+
+#define NELEMENTS(array) /* number of elements in an array */ \
+ (sizeof (array) / sizeof ((array) [0]))
+
+#define FOREVER for (;;)
+
+/* storage class specifier definitions */
+
+#define FAST register
+#define IMPORT extern
+#define LOCAL static
+
+
+/* include typedefs - must come after CPU_FAMILY definitions above */
+
+#include "vxTypes.h"
+
+#endif /* INCvxWorksh */
diff --git a/gdb/vx-share/wait.h b/gdb/vx-share/wait.h
new file mode 100644
index 00000000000..cb8d1b5bbaa
--- /dev/null
+++ b/gdb/vx-share/wait.h
@@ -0,0 +1,46 @@
+/* wait.h - header file for remote wait call */
+
+/* Copyright 1992 Free Software Foundation, Inc.
+
+ This code was donated by Wind River Systems, Inc. */
+
+/*
+modification history
+--------------------
+01a,05jun90,llk borrowed.
+*/
+
+/* Define how to access the structure that the wait system call stores.
+ On many systems, there is a structure defined for this.
+ But on vanilla-ish USG systems there is not. */
+
+#ifndef HAVE_WAIT_STRUCT
+#define WAITTYPE int
+#define WIFSTOPPED(w) (((w)&0377) == 0177)
+#define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
+#define WIFEXITED(w) (((w)&0377) == 0)
+#define WRETCODE(w) ((w) >> 8)
+#define WSTOPSIG(w) ((w) >> 8)
+#define WCOREDUMP(w) (((w)&0200) != 0)
+#define WTERMSIG(w) ((w) & 0177)
+#define WSETEXIT(w, status) ((w) = (status))
+#define WSETSTOP(w,sig) ((w) = (0177 | ((sig) << 8)))
+#else
+#if FALSE
+#ifndef ORIG
+
+/* don't include sys/wait.h */
+
+#else ORIG
+#include <sys/wait.h>
+#endif ORIG
+#endif FALSE
+#define WAITTYPE union wait
+#define WRETCODE(w) (w).w_retcode
+#define WSTOPSIG(w) (w).w_stopsig
+#define WCOREDUMP(w) (w).w_coredump
+#define WTERMSIG(w) (w).w_termsig
+#define WSETEXIT(w, status) ((w).w_status = (status))
+#define WSETSTOP(w,sig) \
+ ((w).w_stopsig = (sig), (w).w_coredump = 0, (w).w_termsig = 0177)
+#endif
diff --git a/gdb/vx-share/xdr_ld.c b/gdb/vx-share/xdr_ld.c
new file mode 100644
index 00000000000..38482c8328b
--- /dev/null
+++ b/gdb/vx-share/xdr_ld.c
@@ -0,0 +1,85 @@
+/* xdr_ld.c - xdr routines for remote dbx interface to VxWorks */
+
+/* Copyright 1984, 1985, 1986, 1987, 1988, 1989, 1992, 1993, 1998
+ Free Software Foundation, Inc.
+
+ This code was donated by Wind River Systems, Inc. */
+
+/*
+modification history
+--------------------
+01a,05jun90,llk extracted from xdr_dbx.c.
+*/
+
+/*
+DESCRIPTION
+This module contains the eXternal Data Representation (XDR) routines
+for object files that are downloaded to VxWorks. They are used by
+remote debuggers that use RPC (such as dbxWorks and vxGdb).
+*/
+
+#include "defs.h"
+#include "vxWorks.h"
+#include "rpc/rpc.h"
+#include "xdr_ld.h"
+
+/* forward declarations */
+
+bool_t xdr_String(); /* xdr routine for argument list */
+
+
+/*******************************************************************************
+*
+* xdr_String - xdr routine for strings.
+*
+* Used by xdr_arg_info to handle the actual argument
+* strings. normally calls xdr_string - but does something
+* reasonable encode of null pointer.
+*/
+
+bool_t xdr_String (xdrs, strp)
+ XDR *xdrs;
+ char **strp;
+
+ {
+ if ((*strp == NULL) & (xdrs->x_op == XDR_ENCODE))
+ return(FALSE);
+ else
+ return(xdr_string(xdrs, strp, MAXSTRLEN));
+ }
+/*******************************************************************************
+*
+* xdr_ldfile - xdr routine for a single element in the load table
+*/
+
+bool_t xdr_ldfile (xdrs, objp)
+ XDR *xdrs;
+ ldfile *objp;
+
+ {
+ if (! xdr_String(xdrs, &objp->name))
+ return(FALSE);
+ if (! xdr_int(xdrs, &objp->txt_addr))
+ return(FALSE);
+ if (! xdr_int(xdrs, &objp->data_addr))
+ return(FALSE);
+ if (! xdr_int(xdrs, &objp->bss_addr))
+ return(FALSE);
+
+ return(TRUE);
+ }
+/*******************************************************************************
+*
+* xdr_ldtabl -
+*
+* xdr routine for a list of files and load addresses loaded into VxWorks.
+*/
+
+bool_t xdr_ldtabl (xdrs,objp)
+ XDR *xdrs;
+ ldtabl *objp;
+
+ {
+ return (xdr_array (xdrs, (char **) &objp->tbl_ent, (UINT *) &objp->tbl_size,
+ MAXTBLSZ, sizeof(ldfile), xdr_ldfile));
+ }
diff --git a/gdb/vx-share/xdr_ld.h b/gdb/vx-share/xdr_ld.h
new file mode 100644
index 00000000000..2899c0ef78f
--- /dev/null
+++ b/gdb/vx-share/xdr_ld.h
@@ -0,0 +1,45 @@
+/* xdr_ld.h - xdr for additional dbxWorks structures */
+
+/* Copyright 1992 Free Software Foundation, Inc.
+
+ This code was donated by Wind River Systems, Inc. */
+
+/*
+modification history
+--------------------
+01a,05jun90,llk extracted from xdr_dbx.h.
+*/
+
+#ifndef INCxdrldh
+#define INCxdrldh
+
+#define MAXSTRLEN 256
+#define MAXTBLSZ 100
+
+/*
+ * structure used to pass back the information for a single file
+ * loaded in VxWorks
+ */
+struct ldfile {
+ char *name;
+ int txt_addr;
+ int data_addr;
+ int bss_addr;
+};
+typedef struct ldfile ldfile;
+
+/*
+ * structure used to return a list of all files loaded over to
+ * VxWorks. (VX_STATE_INQ return)
+ */
+struct ldtabl {
+ u_int tbl_size;
+ ldfile *tbl_ent;
+};
+typedef struct ldtabl ldtabl;
+
+
+bool_t xdr_ldfile();
+bool_t xdr_ldtabl();
+
+#endif INCxdrldh
diff --git a/gdb/vx-share/xdr_ptrace.c b/gdb/vx-share/xdr_ptrace.c
new file mode 100644
index 00000000000..86374bae5c3
--- /dev/null
+++ b/gdb/vx-share/xdr_ptrace.c
@@ -0,0 +1,119 @@
+/* xdr_ptrace.c - xdr routines for remote ptrace calls */
+
+/* Copyright 1984, 1985, 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1998
+ Free Software Foundation, Inc.
+
+ This code was donated by Wind River Systems, Inc. */
+
+/*
+modification history
+--------------------
+01b,25may91,maf now uses counted bytes struct to transfer registers.
+ removed xdr_regs_ptr (), xdr_fp_status_ptr (), and
+ xdr_fpa_regs_ptr ().
+01a,05jun90,llk extracted from xdr_ptrace.h, version 01c.
+*/
+
+#include "defs.h"
+#include "vxWorks.h"
+#include <rpc/rpc.h>
+#include "xdr_ptrace.h"
+
+#define MAX_LEN 32000
+
+/********************************************************************
+*
+* xdr_c_bytes -
+*
+* xdr routine for counted bytes
+*
+*/
+bool_t xdr_c_bytes(xdrs,objp)
+ XDR *xdrs;
+ C_bytes *objp;
+ {
+ return(xdr_bytes(xdrs, &objp->bytes, (u_int *) &objp->len, MAX_LEN));
+ } /* xdr_c_bytes */
+
+/********************************************************************
+*
+* xdr_c_bytes_ptr -
+*
+* xdr routine for counted bytes branch of ptrace_info
+*
+*/
+
+LOCAL bool_t xdr_c_bytes_ptr(xdrs,objp)
+ XDR *xdrs;
+ C_bytes **objp;
+ {
+ return(xdr_pointer(xdrs, (char **) objp, sizeof(C_bytes), xdr_c_bytes));
+ } /* xdr_c_bytes_ptr */
+
+/********************************************************************
+*
+* xdr_ptrace_info -
+*
+* xdr routine for discriminated union ptrace_info
+*
+*/
+
+bool_t xdr_ptrace_info(xdrs,objp)
+ XDR *xdrs;
+ Ptrace_info *objp;
+ {
+ static struct xdr_discrim choices[] =
+ {
+ { (int) DATA, xdr_c_bytes_ptr },
+ { __dontcare__, NULL }
+ };
+
+ return(xdr_union(xdrs, (enum_t *) &objp->ttype,
+ (char *) &objp->more_data, choices, xdr_void));
+ } /* xdr_ptrace_info */
+
+/********************************************************************
+*
+* xdr_rptrace -
+*
+* xdr routine for remote ptrace data into server
+*
+*/
+
+bool_t xdr_rptrace(xdrs,objp)
+ XDR *xdrs;
+ Rptrace *objp;
+ {
+ if (! xdr_int(xdrs, &objp->pid))
+ return(FALSE);
+ if (! xdr_int(xdrs, &objp->data))
+ return(FALSE);
+ if (! xdr_int(xdrs, &objp->addr))
+ return(FALSE);
+ if (! xdr_ptrace_info(xdrs, &objp->info))
+ return(FALSE);
+
+ return(TRUE);
+ } /* xdr_rptrace */
+
+/********************************************************************
+*
+* xdr_ptrace_return -
+*
+* xdr routine for remote ptrace data returned by server
+*
+*/
+
+bool_t xdr_ptrace_return(xdrs, objp)
+ XDR *xdrs;
+ Ptrace_return *objp;
+ {
+ if (! xdr_int(xdrs, &objp->status))
+ return(FALSE);
+ if (! xdr_int(xdrs, &objp->errno_num))
+ return(FALSE);
+ if (! xdr_ptrace_info(xdrs, &objp->info))
+ return(FALSE);
+
+ return(TRUE);
+ } /* xdr_ptrace_return */
diff --git a/gdb/vx-share/xdr_ptrace.h b/gdb/vx-share/xdr_ptrace.h
new file mode 100644
index 00000000000..0ff57a98c33
--- /dev/null
+++ b/gdb/vx-share/xdr_ptrace.h
@@ -0,0 +1,72 @@
+/* xdr_ptrace.h - xdr header for remote ptrace structures */
+
+/* Copyright 1992, 1998 Free Software Foundation, Inc.
+
+ This code was donated by Wind River Systems, Inc. */
+
+/*
+modification history
+--------------------
+01b,25may91,maf now uses counted bytes struct to transfer registers;
+ removed references to old xdr_regs functions.
+ removed includes of "xdr_regs.h" and "reg.h".
+01a,05jun90,llk extracted from xdr_ptrace.h.
+*/
+
+
+/*
+ * Counted byte structure used by READ/WRITE TEXT/DATA
+ * and GET/SET REGS/FPREGS
+ */
+struct c_bytes {
+ u_int len;
+ caddr_t bytes;
+};
+typedef struct c_bytes C_bytes;
+
+/*
+ * enum for discriminated union ptrace_info
+ */
+enum ptype {
+ NOINFO = 0, /* no additional infomation */
+ DATA = 1 /* c_bytes */
+};
+typedef enum ptype ptype;
+
+/*
+ * discrimnated union for passing additional data to be
+ * written to the debugged process.
+ */
+struct ptrace_info {
+ ptype ttype;
+ caddr_t more_data;
+};
+typedef struct ptrace_info Ptrace_info;
+
+/*
+ * structure passed to server on all remote ptrace calls
+ */
+struct rptrace {
+ int pid;
+ int data;
+ int addr; /* FIX! this really should be caddr_t or something */
+ Ptrace_info info;
+};
+typedef struct rptrace Rptrace;
+
+/*
+ * structure returned by server on all remote ptrace calls
+ */
+/* This used to have a field called errno, but that fails on hosts which
+ define errno to be a macro, so it was changed to errno_num. */
+struct ptrace_return {
+ int status;
+ int errno_num;
+ Ptrace_info info;
+};
+typedef struct ptrace_return Ptrace_return;
+
+bool_t xdr_c_bytes();
+bool_t xdr_ptrace_info();
+bool_t xdr_rptrace();
+bool_t xdr_ptrace_return();
diff --git a/gdb/vx-share/xdr_rdb.c b/gdb/vx-share/xdr_rdb.c
new file mode 100644
index 00000000000..a31f81d5671
--- /dev/null
+++ b/gdb/vx-share/xdr_rdb.c
@@ -0,0 +1,212 @@
+/* xdr_rdb.c - xdr routines for Remote Debug interface to VxWorks */
+
+/* Copyright 1992, 1993 Free Software Foundation, Inc.
+
+ This code was donated by Wind River Systems, Inc. */
+
+/*
+modification history
+--------------------
+01a,21mar90,llk created using modification 01d of xdr_dbx.c.
+*/
+
+/*
+DESCRIPTION
+This module contains the eXternal Data Representation (XDR) routines
+for the RDB interface for VxWorks.
+*/
+
+#include "defs.h"
+#include "vxWorks.h"
+#include <rpc/rpc.h>
+#include "xdr_rdb.h"
+
+/* forward declarations */
+
+bool_t
+xdr_arg_type(xdrs, objp)
+ XDR *xdrs;
+ arg_type *objp;
+{
+ if (!xdr_enum(xdrs, (enum_t *)objp)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_arg_value(xdrs, objp)
+ XDR *xdrs;
+ arg_value *objp;
+{
+ if (!xdr_arg_type(xdrs, &objp->type)) {
+ return (FALSE);
+ }
+ switch (objp->type) {
+ case T_BYTE:
+ if (!xdr_char(xdrs, &objp->arg_value_u.v_byte)) {
+ return (FALSE);
+ }
+ break;
+ case T_WORD:
+ if (!xdr_short(xdrs, &objp->arg_value_u.v_word)) {
+ return (FALSE);
+ }
+ break;
+ case T_INT:
+ if (!xdr_int(xdrs, &objp->arg_value_u.v_int)) {
+ return (FALSE);
+ }
+ break;
+ case T_FLOAT:
+ if (!xdr_float(xdrs, &objp->arg_value_u.v_fp)) {
+ return (FALSE);
+ }
+ break;
+ case T_DOUBLE:
+ if (!xdr_double(xdrs, &objp->arg_value_u.v_dp)) {
+ return (FALSE);
+ }
+ break;
+ case T_UNKNOWN:
+ break;
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_func_call(xdrs, objp)
+ XDR *xdrs;
+ func_call *objp;
+{
+ if (!xdr_int(xdrs, &objp->func_addr)) {
+ return (FALSE);
+ }
+ if (!xdr_array(xdrs, (char **)&objp->args.args_val, (u_int *)&objp->args.args_len, MAX_FUNC_ARGS, sizeof(arg_value), xdr_arg_value)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_arg_one(xdrs, objp)
+ XDR *xdrs;
+ arg_one *objp;
+{
+ if (!xdr_string(xdrs, objp, MAX_ARG_LEN)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+
+
+bool_t
+xdr_arg_array(xdrs, objp)
+ XDR *xdrs;
+ arg_array *objp;
+{
+ if (!xdr_array(xdrs, (char **)&objp->arg_array_val, (u_int *)&objp->arg_array_len, MAX_ARG_CNT, sizeof(arg_one), xdr_arg_one)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+/*********************************************************************
+*
+* xdr_EVENT_TYPE -
+*
+*/
+
+bool_t xdr_EVENT_TYPE(xdrs, objp)
+ XDR *xdrs;
+ EVENT_TYPE *objp;
+
+ {
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return (FALSE);
+ return (TRUE);
+ }
+
+/*********************************************************************
+*
+* xdr_RDB_EVENT -
+*
+*/
+
+bool_t xdr_RDB_EVENT (xdrs, objp)
+ XDR *xdrs;
+ RDB_EVENT *objp;
+
+ {
+ if (!xdr_int (xdrs, &objp->status))
+ return (FALSE);
+ if (!xdr_int (xdrs, &objp->taskId))
+ return (FALSE);
+ if (!xdr_EVENT_TYPE (xdrs, &objp->eventType))
+ return (FALSE);
+ if (!xdr_int (xdrs, &objp->sigType))
+ return (FALSE);
+ return (TRUE);
+ }
+
+/*********************************************************************
+*
+* xdr_TASK_START -
+*
+*/
+
+bool_t
+xdr_TASK_START (xdrs, objp)
+ XDR *xdrs;
+ TASK_START *objp;
+
+ {
+ if (!xdr_int (xdrs, &objp->status))
+ return (FALSE);
+ if (!xdr_int (xdrs, &objp->pid))
+ return (FALSE);
+ return (TRUE);
+ }
+
+
+/*********************************************************************
+*
+* xdr_SYMBOL_ADDR -
+*
+*/
+
+bool_t
+xdr_SYMBOL_ADDR (xdrs, objp)
+ XDR *xdrs;
+ SYMBOL_ADDR *objp;
+
+ {
+ if (!xdr_int (xdrs, &objp->status))
+ return (FALSE);
+ if (!xdr_u_int (xdrs, &objp->addr))
+ return (FALSE);
+ return (TRUE);
+ }
+
+/*********************************************************************
+*
+* xdr_SOURCE_STEP -
+*
+*/
+
+bool_t
+xdr_SOURCE_STEP (xdrs, objp)
+ XDR *xdrs;
+ SOURCE_STEP *objp;
+
+ {
+ if (!xdr_int (xdrs, &objp->taskId))
+ return (FALSE);
+ if (!xdr_u_int (xdrs, &objp->startAddr))
+ return (FALSE);
+ if (!xdr_u_int (xdrs, &objp->endAddr))
+ return (FALSE);
+ return (TRUE);
+ }
diff --git a/gdb/vx-share/xdr_rdb.h b/gdb/vx-share/xdr_rdb.h
new file mode 100644
index 00000000000..01894536297
--- /dev/null
+++ b/gdb/vx-share/xdr_rdb.h
@@ -0,0 +1,137 @@
+/* xdr_rdb.h - xdr for additional rdb structures */
+
+/* Copyright 1992 Free Software Foundation, Inc.
+
+ This code was donated by Wind River Systems, Inc. */
+
+/*
+modification history
+--------------------
+01c,25may91,maf rolled RDBVERS for VxGDB 1.0 version.
+01b,12apr91,maf rolled RDBVERS.
+01a,09jan91,maf created using v1a of xdr_rdb.h for 4.0.2 VxWorks 68k.
+ added struct SOURCE_STEP.
+*/
+
+#ifndef INCxdrrdbh
+#define INCxdrrdbh
+
+enum arg_type {
+ T_UNKNOWN = 0,
+ T_BYTE = 1,
+ T_WORD = 2,
+ T_INT = 3,
+ T_FLOAT = 4,
+ T_DOUBLE = 5
+};
+typedef enum arg_type arg_type;
+bool_t xdr_arg_type();
+
+
+struct arg_value {
+ arg_type type;
+ union {
+ char v_byte;
+ short v_word;
+ int v_int;
+ float v_fp;
+ double v_dp;
+ } arg_value_u;
+};
+typedef struct arg_value arg_value;
+bool_t xdr_arg_value();
+
+struct func_call {
+ int func_addr;
+ struct {
+ u_int args_len;
+ arg_value *args_val;
+ } args;
+};
+typedef struct func_call func_call;
+bool_t xdr_func_call();
+
+
+typedef char *arg_one;
+bool_t xdr_arg_one();
+
+
+typedef struct {
+ u_int arg_array_len;
+ arg_one *arg_array_val;
+} arg_array;
+bool_t xdr_arg_array();
+
+
+/*
+ * Structures used to pass structures required for
+ * process control but not part of the standard ptrace interface
+ */
+
+/*
+ * arg_info is used to pass arguments into process start
+ */
+struct arg_info {
+ int rargc;
+ char **rargv;
+};
+typedef struct arg_info Arg_info;
+
+
+enum EVENT_TYPE {
+ EVENT_BREAK = 0,
+ EVENT_STOP = 1,
+ EVENT_EXIT = 2,
+ EVENT_BUS_ERR = 3,
+ EVENT_SUSPEND = 4,
+ EVENT_ZERO_DIV = 5,
+ EVENT_SIGNAL = 6,
+ EVENT_START = 7
+};
+typedef enum EVENT_TYPE EVENT_TYPE;
+
+
+struct RDB_EVENT {
+ int status;
+ int taskId;
+ EVENT_TYPE eventType;
+ int sigType;
+};
+typedef struct RDB_EVENT RDB_EVENT;
+
+
+struct TASK_START {
+ int status;
+ int pid;
+};
+typedef struct TASK_START TASK_START;
+
+
+struct SYMBOL_ADDR {
+ int status;
+ u_int addr;
+};
+typedef struct SYMBOL_ADDR SYMBOL_ADDR;
+
+struct SOURCE_STEP {
+ int taskId;
+ u_int startAddr;
+ u_int endAddr;
+};
+typedef struct SOURCE_STEP SOURCE_STEP;
+
+#define MAX_ARG_CNT 10
+#define MAX_FUNC_ARGS 100
+#define MAX_ARG_LEN 100
+
+
+bool_t xdr_arg_info();
+bool_t xdr_EVENT_TYPE();
+bool_t xdr_RDB_EVENT();
+bool_t xdr_TASK_START();
+bool_t xdr_SYMBOL_ADDR();
+bool_t xdr_SOURCE_STEP();
+
+#define RDBPROG (u_long) 0x44444444
+#define RDBVERS (u_long) 3
+#endif INCxdrrdbh
diff --git a/gdb/w89k-rom.c b/gdb/w89k-rom.c
new file mode 100644
index 00000000000..331358bce21
--- /dev/null
+++ b/gdb/w89k-rom.c
@@ -0,0 +1,311 @@
+/* Remote target glue for the WinBond ROM monitor running on the "Cougar"
+ W89k eval board.
+
+ Copyright 1995, 1998, 2000, 2001 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 "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+#include "xmodem.h"
+#include "regcache.h"
+
+
+static void w89k_open (char *args, int from_tty);
+
+/*
+ * this array of registers need to match the indexes used by GDB. The
+ * whole reason this exists is cause the various ROM monitors use
+ * different strings than GDB does, and doesn't support all the
+ * registers either. So, typing "info reg sp" becomes a "r30".
+ */
+
+static char *w89k_regnames[NUM_REGS] =
+{
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "SAR", "PC", NULL, NULL, NULL, "EIEM", "IIR", "IVA",
+ "IOR", "IPSW", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "CCR", NULL, NULL, "TR0", "TR1",
+};
+
+static void
+w89k_supply_register (char *regname, int regnamelen, char *val, int vallen)
+{
+ int numregs;
+ int regno;
+
+ numregs = 1;
+ regno = -1;
+
+ if (regnamelen == 2)
+ switch (regname[0])
+ {
+ case 'r':
+ numregs = 4;
+ switch (regname[1])
+ {
+ case '0':
+ regno = R0_REGNUM;
+ break;
+ case '4':
+ regno = R0_REGNUM + 4;
+ break;
+ case '8':
+ regno = R0_REGNUM + 8;
+ break;
+ }
+ break;
+ case 'P':
+ if (regname[1] == 'C')
+ regno = PC_REGNUM;
+ break;
+ }
+ else if (regnamelen == 3)
+ switch (regname[0])
+ {
+ case 'r':
+ numregs = 4;
+ if (regname[1] == '1' && regname[2] == '2')
+ regno = R0_REGNUM + 12;
+ else if (regname[1] == '1' && regname[2] == '6')
+ regno = R0_REGNUM + 16;
+ else if (regname[1] == '2' && regname[2] == '0')
+ regno = R0_REGNUM + 20;
+ else if (regname[1] == '2' && regname[2] == '4')
+ regno = R0_REGNUM + 24;
+ else if (regname[1] == '2' && regname[2] == '8')
+ regno = R0_REGNUM + 28;
+ break;
+ case 'R':
+ if (regname[1] == 'C' && regname[2] == 'R')
+ regno = RCR_REGNUM;
+ break;
+ case 'C':
+ if (regname[1] == 'C' && regname[2] == 'R')
+ regno = CCR_REGNUM;
+ break;
+ case 'S':
+ if (regname[1] == 'A' && regname[2] == 'R')
+ regno = SAR_REGNUM;
+ break;
+ case 'I':
+ if (regname[1] == 'I' && regname[2] == 'R')
+ regno = IIR_REGNUM;
+ else if (regname[1] == 'O' && regname[2] == 'R')
+ regno = IOR_REGNUM;
+ break;
+ case 'T':
+ numregs = 4;
+ if (regname[1] == 'R')
+ if (regname[2] == '0')
+ regno = TR0_REGNUM;
+ else if (regname[2] == '4')
+ regno = TR0_REGNUM + 4;
+ break;
+ }
+ else if (regnamelen == 4)
+ switch (regname[0])
+ {
+ case 'E':
+ if (regname[1] == 'I')
+ if (regname[2] == 'E' && regname[3] == 'M')
+ regno = EIEM_REGNUM;
+ break;
+ case 'I':
+ if (regname[1] == 'P' && regname[2] == 'S' && regname[3] == 'W')
+ regno = IPSW_REGNUM;
+ break;
+ }
+ else if (regnamelen == 5)
+ switch (regname[0])
+ {
+ case 'I':
+ if (regname[1] == 'A'
+ && regname[2] == 'O'
+ && regname[3] == 'Q'
+ && regname[4] == 'B')
+ regno = PCOQ_TAIL_REGNUM;
+ break;
+ }
+
+ if (regno >= 0)
+ while (numregs-- > 0)
+ val = monitor_supply_register (regno++, val);
+}
+
+static int hashmark = 1; /* flag set by "set hash" */
+
+extern struct monitor_ops w89k_cmds; /* fwd decl */
+
+static void
+w89k_load (struct serial *desc, char *file, int hashmark)
+{
+ bfd *abfd;
+ asection *s;
+ char *buffer;
+ int i;
+
+ buffer = alloca (XMODEM_PACKETSIZE);
+
+ abfd = bfd_openr (file, 0);
+ if (!abfd)
+ {
+ printf_filtered ("Unable to open file %s\n", file);
+ return;
+ }
+
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ {
+ printf_filtered ("File is not an object file\n");
+ return;
+ }
+
+ for (s = abfd->sections; s; s = s->next)
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_size_type section_size;
+
+ printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma,
+ s->vma + s->_raw_size);
+ gdb_flush (gdb_stdout);
+
+ monitor_printf (w89k_cmds.load, s->vma);
+ if (w89k_cmds.loadresp)
+ monitor_expect (w89k_cmds.loadresp, NULL, 0);
+
+ xmodem_init_xfer (desc);
+
+ section_size = bfd_section_size (abfd, s);
+
+ for (i = 0; i < section_size; i += XMODEM_DATASIZE)
+ {
+ int numbytes;
+
+ numbytes = min (XMODEM_DATASIZE, section_size - i);
+
+ bfd_get_section_contents (abfd, s, buffer + XMODEM_DATAOFFSET, i,
+ numbytes);
+
+ xmodem_send_packet (desc, buffer, numbytes, hashmark);
+
+ if (hashmark)
+ {
+ putchar_unfiltered ('#');
+ gdb_flush (gdb_stdout);
+ }
+ } /* Per-packet (or S-record) loop */
+
+ xmodem_finish_xfer (desc);
+
+ monitor_expect_prompt (NULL, 0);
+
+ putchar_unfiltered ('\n');
+ } /* Loadable sections */
+
+ if (hashmark)
+ putchar_unfiltered ('\n');
+}
+
+/*
+ * Define the monitor command strings. Since these are passed directly
+ * through to a printf style function, we need can include formatting
+ * strings. We also need a CR or LF on the end.
+ */
+
+static struct target_ops w89k_ops;
+
+static char *w89k_inits[] =
+{"\n", NULL};
+
+static struct monitor_ops w89k_cmds;
+static void
+init_w89k_cmds (void)
+{
+ w89k_cmds.flags = MO_GETMEM_NEEDS_RANGE | MO_FILL_USES_ADDR; /* flags */
+ w89k_cmds.init = w89k_inits; /* Init strings */
+ w89k_cmds.cont = "g\n"; /* continue command */
+ w89k_cmds.step = "t\n"; /* single step */
+ w89k_cmds.stop = "\003"; /* Interrupt char (^C) */
+ w89k_cmds.set_break = "bp %x\n"; /* set a breakpoint */
+ w89k_cmds.clr_break = "bc %x\n"; /* clear a breakpoint */
+ w89k_cmds.clr_all_break = "bc *\n"; /* clear all breakpoints */
+ w89k_cmds.fill = "f %x %x %x\n"; /* memory fill cmd */
+ w89k_cmds.setmem.cmdb = "eb %x %x\n"; /* setmem.cmdb (addr, value) */
+ w89k_cmds.setmem.cmdw = "eh %x %x\n"; /* setmem.cmdw (addr, value) */
+ w89k_cmds.setmem.cmdl = "ew %x %x\n"; /* setmem.cmdl (addr, value) */
+ w89k_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
+ w89k_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
+ w89k_cmds.setmem.term = NULL; /* setreg.term */
+ w89k_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
+ w89k_cmds.getmem.cmdb = "db %x %x\n"; /* getmem.cmdb (startaddr, endaddr) */
+ w89k_cmds.getmem.cmdw = "dh %x %x\n"; /* getmem.cmdw (startaddr, endaddr) */
+ w89k_cmds.getmem.cmdl = "dw %x %x\n"; /* getmem.cmdl (startaddr, endaddr) */
+ w89k_cmds.getmem.cmdll = NULL; /* getmem.cmdll (startaddr, endaddr) */
+ w89k_cmds.getmem.resp_delim = " "; /* getmem.resp_delim */
+ w89k_cmds.getmem.term = NULL; /* getmem.term */
+ w89k_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
+ w89k_cmds.setreg.cmd = "r %s %x\n"; /* setreg.cmd (name, value) */
+ w89k_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
+ w89k_cmds.setreg.term = NULL; /* setreg.term */
+ w89k_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
+ w89k_cmds.getreg.cmd = "r %s\n"; /* getreg.cmd (name) */
+ w89k_cmds.getreg.resp_delim = "\r"; /* getreg.resp_delim */
+ w89k_cmds.getreg.term = NULL; /* getreg.term */
+ w89k_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
+ w89k_cmds.dump_registers = "r\n"; /* dump_registers */
+ w89k_cmds.register_pattern = "\\(\\w+\\)\\( +[0-9a-fA-F]+\\b\\)+";
+ w89k_cmds.supply_register = w89k_supply_register; /* supply_register */
+ w89k_cmds.load_routine = w89k_load; /* load routine */
+ w89k_cmds.load = "u %x\n"; /* download command */
+ w89k_cmds.loadresp = "\021"; /* load response (^Q) */
+ w89k_cmds.prompt = "ROM>"; /* monitor command prompt */
+ w89k_cmds.line_term = "\n"; /* end-of-line terminator */
+ w89k_cmds.cmd_end = NULL; /* optional command terminator */
+ w89k_cmds.target = &w89k_ops; /* target operations */
+ w89k_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
+ w89k_cmds.regnames = w89k_regnames; /* register names */
+ w89k_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
+} /* init_w89k_cmds */
+
+static void
+w89k_open (char *args, int from_tty)
+{
+ monitor_open (args, &w89k_cmds, from_tty);
+}
+
+void
+_initialize_w89k (void)
+{
+ init_w89k_cmds ();
+ init_monitor_ops (&w89k_ops);
+
+ w89k_ops.to_shortname = "w89k";
+ w89k_ops.to_longname = "WinBond's debug monitor for the W89k Eval board";
+ w89k_ops.to_doc = "Debug on a WinBond W89K eval board.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ w89k_ops.to_open = w89k_open;
+
+ add_target (&w89k_ops);
+}
diff --git a/gdb/win32-nat.c b/gdb/win32-nat.c
new file mode 100644
index 00000000000..d519f7b3122
--- /dev/null
+++ b/gdb/win32-nat.c
@@ -0,0 +1,2194 @@
+/* Target-vector operations for controlling win32 child processes, for GDB.
+
+ Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free
+ Software Foundation, Inc.
+
+ Contributed by Cygnus Solutions, A Red Hat Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* Originally by Steve Chamberlain, sac@cygnus.com */
+
+/* We assume we're being built with and will be used for cygwin. */
+
+#include "defs.h"
+#include "tm.h" /* required for SSE registers */
+#include "frame.h" /* required by inferior.h */
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "completer.h"
+#include "regcache.h"
+#include "top.h"
+#include "i386-tdep.h"
+#include <signal.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <windows.h>
+#include <imagehlp.h>
+#include <sys/cygwin.h>
+
+#include "buildsym.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdb_string.h"
+#include "gdbthread.h"
+#include "gdbcmd.h"
+#include <sys/param.h>
+#include <unistd.h>
+
+/* The ui's event loop. */
+extern int (*ui_loop_hook) (int signo);
+
+/* If we're not using the old Cygwin header file set, define the
+ following which never should have been in the generic Win32 API
+ headers in the first place since they were our own invention... */
+#ifndef _GNU_H_WINDOWS_H
+enum
+ {
+ FLAG_TRACE_BIT = 0x100,
+ CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
+ };
+#endif
+#include <sys/procfs.h>
+#include <psapi.h>
+
+#ifdef HAVE_SSE_REGS
+#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
+ | CONTEXT_EXTENDED_REGISTERS
+#else
+#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS
+#endif
+
+static unsigned dr[8];
+static int debug_registers_changed = 0;
+static int debug_registers_used = 0;
+
+/* The string sent by cygwin when it processes a signal.
+ FIXME: This should be in a cygwin include file. */
+#define CYGWIN_SIGNAL_STRING "cygwin: signal"
+
+#define CHECK(x) check (x, __FILE__,__LINE__)
+#define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
+#define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
+#define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
+#define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
+
+/* Forward declaration */
+extern struct target_ops child_ops;
+
+static void child_stop (void);
+static int win32_child_thread_alive (ptid_t);
+void child_kill_inferior (void);
+
+static enum target_signal last_sig = TARGET_SIGNAL_0;
+/* Set if a signal was received from the debugged process */
+
+/* Thread information structure used to track information that is
+ not available in gdb's thread structure. */
+typedef struct thread_info_struct
+ {
+ struct thread_info_struct *next;
+ DWORD id;
+ HANDLE h;
+ char *name;
+ int suspend_count;
+ CONTEXT context;
+ STACKFRAME sf;
+ }
+thread_info;
+
+static thread_info thread_head;
+
+/* The process and thread handles for the above context. */
+
+static DEBUG_EVENT current_event; /* The current debug event from
+ WaitForDebugEvent */
+static HANDLE current_process_handle; /* Currently executing process */
+static thread_info *current_thread; /* Info on currently selected thread */
+static DWORD main_thread_id; /* Thread ID of the main thread */
+static pid_t cygwin_pid; /* pid of cygwin process */
+
+/* Counts of things. */
+static int exception_count = 0;
+static int event_count = 0;
+static int saw_create;
+
+/* User options. */
+static int new_console = 0;
+static int new_group = 1;
+static int debug_exec = 0; /* show execution */
+static int debug_events = 0; /* show events from kernel */
+static int debug_memory = 0; /* show target memory accesses */
+static int debug_exceptions = 0; /* show target exceptions */
+static int useshell = 0; /* use shell for subprocesses */
+
+/* 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. */
+
+#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
+static const int mappings[] =
+{
+ context_offset (Eax),
+ context_offset (Ecx),
+ context_offset (Edx),
+ context_offset (Ebx),
+ context_offset (Esp),
+ context_offset (Ebp),
+ context_offset (Esi),
+ context_offset (Edi),
+ context_offset (Eip),
+ context_offset (EFlags),
+ context_offset (SegCs),
+ context_offset (SegSs),
+ context_offset (SegDs),
+ context_offset (SegEs),
+ context_offset (SegFs),
+ context_offset (SegGs),
+ context_offset (FloatSave.RegisterArea[0 * 10]),
+ context_offset (FloatSave.RegisterArea[1 * 10]),
+ context_offset (FloatSave.RegisterArea[2 * 10]),
+ context_offset (FloatSave.RegisterArea[3 * 10]),
+ context_offset (FloatSave.RegisterArea[4 * 10]),
+ context_offset (FloatSave.RegisterArea[5 * 10]),
+ context_offset (FloatSave.RegisterArea[6 * 10]),
+ context_offset (FloatSave.RegisterArea[7 * 10]),
+ context_offset (FloatSave.ControlWord),
+ context_offset (FloatSave.StatusWord),
+ context_offset (FloatSave.TagWord),
+ context_offset (FloatSave.ErrorSelector),
+ context_offset (FloatSave.ErrorOffset),
+ context_offset (FloatSave.DataSelector),
+ context_offset (FloatSave.DataOffset),
+ context_offset (FloatSave.ErrorSelector)
+#ifdef HAVE_SSE_REGS
+ /* XMM0-7 */ ,
+ context_offset (ExtendedRegisters[10*16]),
+ context_offset (ExtendedRegisters[11*16]),
+ context_offset (ExtendedRegisters[12*16]),
+ context_offset (ExtendedRegisters[13*16]),
+ context_offset (ExtendedRegisters[14*16]),
+ context_offset (ExtendedRegisters[15*16]),
+ context_offset (ExtendedRegisters[16*16]),
+ context_offset (ExtendedRegisters[17*16]),
+ /* MXCSR */
+ context_offset (ExtendedRegisters[24])
+#endif
+};
+
+#undef context_offset
+
+/* 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},
+ {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
+ {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
+ {DBG_CONTROL_C, TARGET_SIGNAL_INT},
+ {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
+ {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE},
+ {-1, -1}};
+
+static void
+check (BOOL ok, const char *file, int line)
+{
+ if (!ok)
+ printf_filtered ("error return %s:%d was %lu\n", file, line,
+ GetLastError ());
+}
+
+
+/* Find a thread record given a thread id.
+ If get_context then also retrieve the context for this
+ thread. */
+static thread_info *
+thread_rec (DWORD id, int get_context)
+{
+ thread_info *th;
+
+ for (th = &thread_head; (th = th->next) != NULL;)
+ if (th->id == id)
+ {
+ if (!th->suspend_count && get_context)
+ {
+ if (get_context > 0 && id != current_event.dwThreadId)
+ th->suspend_count = SuspendThread (th->h) + 1;
+ else if (get_context < 0)
+ th->suspend_count = -1;
+
+ th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
+ GetThreadContext (th->h, &th->context);
+ if (id == current_event.dwThreadId)
+ {
+ /* Copy dr values from that thread. */
+ dr[0] = th->context.Dr0;
+ dr[1] = th->context.Dr1;
+ dr[2] = th->context.Dr2;
+ dr[3] = th->context.Dr3;
+ dr[6] = th->context.Dr6;
+ dr[7] = th->context.Dr7;
+ }
+ }
+ return th;
+ }
+
+ return NULL;
+}
+
+/* Add a thread to the thread list */
+static thread_info *
+child_add_thread (DWORD id, HANDLE h)
+{
+ thread_info *th;
+
+ if ((th = thread_rec (id, FALSE)))
+ return th;
+
+ th = (thread_info *) xmalloc (sizeof (*th));
+ memset (th, 0, sizeof (*th));
+ th->id = id;
+ th->h = h;
+ th->next = thread_head.next;
+ thread_head.next = th;
+ add_thread (pid_to_ptid (id));
+ /* Set the debug registers for the new thread in they are used. */
+ if (debug_registers_used)
+ {
+ /* Only change the value of the debug registers. */
+ th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
+ CHECK (GetThreadContext (th->h, &th->context));
+ th->context.Dr0 = dr[0];
+ th->context.Dr1 = dr[1];
+ th->context.Dr2 = dr[2];
+ th->context.Dr3 = dr[3];
+ /* th->context.Dr6 = dr[6];
+ FIXME: should we set dr6 also ?? */
+ th->context.Dr7 = dr[7];
+ CHECK (SetThreadContext (th->h, &th->context));
+ th->context.ContextFlags = 0;
+ }
+ return th;
+}
+
+/* Clear out any old thread list and reintialize it to a
+ pristine state. */
+static void
+child_init_thread_list (void)
+{
+ thread_info *th = &thread_head;
+
+ DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
+ init_thread_list ();
+ while (th->next != NULL)
+ {
+ thread_info *here = th->next;
+ th->next = here->next;
+ (void) CloseHandle (here->h);
+ xfree (here);
+ }
+}
+
+/* Delete a thread from the list of threads */
+static void
+child_delete_thread (DWORD id)
+{
+ thread_info *th;
+
+ if (info_verbose)
+ printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id)));
+ delete_thread (pid_to_ptid (id));
+
+ for (th = &thread_head;
+ th->next != NULL && th->next->id != id;
+ th = th->next)
+ continue;
+
+ if (th->next != NULL)
+ {
+ thread_info *here = th->next;
+ th->next = here->next;
+ CloseHandle (here->h);
+ xfree (here);
+ }
+}
+
+static void
+do_child_fetch_inferior_registers (int r)
+{
+ char *context_offset = ((char *) &current_thread->context) + mappings[r];
+ long l;
+ if (r == FCS_REGNUM)
+ {
+ l = *((long *) context_offset) & 0xffff;
+ supply_register (r, (char *) &l);
+ }
+ else if (r == FOP_REGNUM)
+ {
+ l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
+ supply_register (r, (char *) &l);
+ }
+ else if (r >= 0)
+ supply_register (r, context_offset);
+ else
+ {
+ for (r = 0; r < NUM_REGS; r++)
+ do_child_fetch_inferior_registers (r);
+ }
+}
+
+static void
+child_fetch_inferior_registers (int r)
+{
+ current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
+ do_child_fetch_inferior_registers (r);
+}
+
+static void
+do_child_store_inferior_registers (int r)
+{
+ if (r >= 0)
+ read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
+ else
+ {
+ for (r = 0; r < NUM_REGS; r++)
+ do_child_store_inferior_registers (r);
+ }
+}
+
+/* Store a new register value into the current thread context */
+static void
+child_store_inferior_registers (int r)
+{
+ current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
+ do_child_store_inferior_registers (r);
+}
+
+static int psapi_loaded = 0;
+static HMODULE psapi_module_handle = NULL;
+static BOOL WINAPI (*psapi_EnumProcessModules) (HANDLE, HMODULE *, DWORD, LPDWORD) = NULL;
+static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD) = NULL;
+static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD) = NULL;
+
+int
+psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
+{
+ DWORD len;
+ MODULEINFO mi;
+ int i;
+ HMODULE dh_buf[1];
+ HMODULE *DllHandle = dh_buf;
+ DWORD cbNeeded;
+ BOOL ok;
+
+ if (!psapi_loaded ||
+ psapi_EnumProcessModules == NULL ||
+ psapi_GetModuleInformation == NULL ||
+ psapi_GetModuleFileNameExA == NULL)
+ {
+ if (psapi_loaded)
+ goto failed;
+ psapi_loaded = 1;
+ psapi_module_handle = LoadLibrary ("psapi.dll");
+ if (!psapi_module_handle)
+ {
+ /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
+ goto failed;
+ }
+ psapi_EnumProcessModules = GetProcAddress (psapi_module_handle, "EnumProcessModules");
+ psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation");
+ psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle,
+ "GetModuleFileNameExA");
+ if (psapi_EnumProcessModules == NULL ||
+ psapi_GetModuleInformation == NULL ||
+ psapi_GetModuleFileNameExA == NULL)
+ goto failed;
+ }
+
+ cbNeeded = 0;
+ ok = (*psapi_EnumProcessModules) (current_process_handle,
+ DllHandle,
+ sizeof (HMODULE),
+ &cbNeeded);
+
+ if (!ok || !cbNeeded)
+ goto failed;
+
+ DllHandle = (HMODULE *) alloca (cbNeeded);
+ if (!DllHandle)
+ goto failed;
+
+ ok = (*psapi_EnumProcessModules) (current_process_handle,
+ DllHandle,
+ cbNeeded,
+ &cbNeeded);
+ if (!ok)
+ goto failed;
+
+ for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
+ {
+ if (!(*psapi_GetModuleInformation) (current_process_handle,
+ DllHandle[i],
+ &mi,
+ sizeof (mi)))
+ error ("Can't get module info");
+
+ len = (*psapi_GetModuleFileNameExA) (current_process_handle,
+ DllHandle[i],
+ dll_name_ret,
+ MAX_PATH);
+ if (len == 0)
+ error ("Error getting dll name: %u\n", GetLastError ());
+
+ if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
+ return 1;
+ }
+
+failed:
+ dll_name_ret[0] = '\0';
+ return 0;
+}
+
+/* Encapsulate the information required in a call to
+ symbol_file_add_args */
+struct safe_symbol_file_add_args
+{
+ char *name;
+ int from_tty;
+ struct section_addr_info *addrs;
+ int mainline;
+ int flags;
+ struct ui_file *err, *out;
+ struct objfile *ret;
+};
+
+/* Maintain a linked list of "so" information. */
+struct so_stuff
+{
+ struct so_stuff *next;
+ DWORD load_addr;
+ int loaded;
+ struct objfile *objfile;
+ char name[1];
+} solib_start, *solib_end;
+
+/* Call symbol_file_add with stderr redirected. We don't care if there
+ are errors. */
+static int
+safe_symbol_file_add_stub (void *argv)
+{
+#define p ((struct safe_symbol_file_add_args *)argv)
+ struct so_stuff *so = &solib_start;
+
+ while ((so = so->next))
+ if (so->loaded && strcasecmp (so->name, p->name) == 0)
+ return 0;
+ p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
+ return !!p->ret;
+#undef p
+}
+
+/* Restore gdb's stderr after calling symbol_file_add */
+static void
+safe_symbol_file_add_cleanup (void *p)
+{
+#define sp ((struct safe_symbol_file_add_args *)p)
+ gdb_flush (gdb_stderr);
+ gdb_flush (gdb_stdout);
+ ui_file_delete (gdb_stderr);
+ ui_file_delete (gdb_stdout);
+ gdb_stderr = sp->err;
+ gdb_stdout = sp->out;
+#undef sp
+}
+
+/* symbol_file_add wrapper that prevents errors from being displayed. */
+static struct objfile *
+safe_symbol_file_add (char *name, int from_tty,
+ struct section_addr_info *addrs,
+ int mainline, int flags)
+{
+ struct safe_symbol_file_add_args p;
+ struct cleanup *cleanup;
+
+ cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
+
+ p.err = gdb_stderr;
+ p.out = gdb_stdout;
+ gdb_flush (gdb_stderr);
+ gdb_flush (gdb_stdout);
+ gdb_stderr = ui_file_new ();
+ gdb_stdout = ui_file_new ();
+ p.name = name;
+ p.from_tty = from_tty;
+ p.addrs = addrs;
+ p.mainline = mainline;
+ p.flags = flags;
+ catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
+
+ do_cleanups (cleanup);
+ return p.ret;
+}
+
+/* Remember the maximum DLL length for printing in info dll command. */
+int max_dll_name_len;
+
+static void
+register_loaded_dll (const char *name, DWORD load_addr)
+{
+ struct so_stuff *so;
+ char ppath[MAX_PATH + 1];
+ char buf[MAX_PATH + 1];
+ char cwd[MAX_PATH + 1];
+ char *p;
+ WIN32_FIND_DATA w32_fd;
+ HANDLE h = FindFirstFile(name, &w32_fd);
+ size_t len;
+
+ if (h == INVALID_HANDLE_VALUE)
+ strcpy (buf, name);
+ else
+ {
+ FindClose (h);
+ strcpy (buf, name);
+ if (GetCurrentDirectory (MAX_PATH + 1, cwd))
+ {
+ p = strrchr (buf, '\\');
+ if (p)
+ p[1] = '\0';
+ SetCurrentDirectory (buf);
+ GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
+ SetCurrentDirectory (cwd);
+ }
+ }
+
+ cygwin_conv_to_posix_path (buf, ppath);
+ so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (ppath) + 8 + 1);
+ so->loaded = 0;
+ so->load_addr = load_addr;
+ so->next = NULL;
+ so->objfile = NULL;
+ strcpy (so->name, ppath);
+
+ solib_end->next = so;
+ solib_end = so;
+ len = strlen (ppath);
+ if (len > max_dll_name_len)
+ max_dll_name_len = len;
+}
+
+char *
+get_image_name (HANDLE h, void *address, int unicode)
+{
+ static char buf[(2 * MAX_PATH) + 1];
+ DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
+ char *address_ptr;
+ int len = 0;
+ char b[2];
+ DWORD done;
+
+ /* Attempt to read the name of the dll that was detected.
+ This is documented to work only when actively debugging
+ a program. It will not work for attached processes. */
+ if (address == NULL)
+ return NULL;
+
+ ReadProcessMemory (h, address, &address_ptr, sizeof (address_ptr), &done);
+
+ /* See if we could read the address of a string, and that the
+ address isn't null. */
+
+ if (done != sizeof (address_ptr) || !address_ptr)
+ return NULL;
+
+ /* Find the length of the string */
+ do
+ {
+ ReadProcessMemory (h, address_ptr + len * size, &b, size, &done);
+ len++;
+ }
+ while ((b[0] != 0 || b[size - 1] != 0) && done == size);
+
+ if (!unicode)
+ ReadProcessMemory (h, address_ptr, buf, len, &done);
+ else
+ {
+ WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
+ ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
+ &done);
+
+ WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0);
+ }
+
+ return buf;
+}
+
+/* Wait for child to do something. Return pid of child, or -1 in case
+ of error; store status through argument pointer OURSTATUS. */
+static int
+handle_load_dll (void *dummy)
+{
+ LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
+ char dll_buf[MAX_PATH + 1];
+ char *dll_name = NULL;
+ char *p;
+
+ dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
+
+ if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
+ dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
+
+ dll_name = dll_buf;
+
+ if (*dll_name == '\0')
+ dll_name = get_image_name (current_process_handle, event->lpImageName, event->fUnicode);
+ if (!dll_name)
+ return 1;
+
+ register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000);
+
+ return 1;
+}
+
+static int
+handle_unload_dll (void *dummy)
+{
+ DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll + 0x1000;
+ struct so_stuff *so;
+
+ for (so = &solib_start; so->next != NULL; so = so->next)
+ if (so->next->load_addr == lpBaseOfDll)
+ {
+ struct so_stuff *sodel = so->next;
+ so->next = sodel->next;
+ if (!so->next)
+ solib_end = so;
+ if (sodel->objfile)
+ free_objfile (sodel->objfile);
+ xfree(sodel);
+ return 1;
+ }
+ error ("Error: dll starting at 0x%lx not found.\n", (DWORD) lpBaseOfDll);
+
+ return 0;
+}
+
+/* Return name of last loaded DLL. */
+char *
+child_solib_loaded_library_pathname (int pid)
+{
+ return !solib_end || !solib_end->name[0] ? NULL : solib_end->name;
+}
+
+/* Clear list of loaded DLLs. */
+void
+child_clear_solibs (void)
+{
+ struct so_stuff *so, *so1 = solib_start.next;
+
+ while ((so = so1) != NULL)
+ {
+ so1 = so->next;
+ xfree (so);
+ }
+
+ solib_start.next = NULL;
+ solib_start.objfile = NULL;
+ solib_end = &solib_start;
+ max_dll_name_len = sizeof ("DLL Name") - 1;
+}
+
+/* Add DLL symbol information. */
+static struct objfile *
+solib_symbols_add (char *name, int from_tty, CORE_ADDR load_addr)
+{
+ struct section_addr_info section_addrs;
+
+ /* The symbols in a dll are offset by 0x1000, which is the
+ the offset from 0 of the first byte in an image - because
+ of the file header and the section alignment. */
+
+ if (!name || !name[0])
+ return NULL;
+
+ memset (&section_addrs, 0, sizeof (section_addrs));
+ section_addrs.other[0].name = ".text";
+ section_addrs.other[0].addr = load_addr;
+ return safe_symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED);
+}
+
+/* Load DLL symbol info. */
+void
+dll_symbol_command (char *args, int from_tty)
+{
+ int n;
+ dont_repeat ();
+
+ if (args == NULL)
+ error ("dll-symbols requires a file name");
+
+ n = strlen (args);
+ if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
+ {
+ char *newargs = (char *) alloca (n + 4 + 1);
+ strcpy (newargs, args);
+ strcat (newargs, ".dll");
+ args = newargs;
+ }
+
+ safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
+}
+
+/* List currently loaded DLLs. */
+void
+info_dll_command (char *ignore, int from_tty)
+{
+ struct so_stuff *so = &solib_start;
+
+ if (!so->next)
+ return;
+
+ printf_filtered ("%*s Load Address\n", -max_dll_name_len, "DLL Name");
+ while ((so = so->next) != NULL)
+ printf_filtered ("%*s %08lx\n", -max_dll_name_len, so->name, so->load_addr);
+
+ return;
+}
+
+/* Handle DEBUG_STRING output from child process.
+ Cygwin prepends its messages with a "cygwin:". Interpret this as
+ a Cygwin signal. Otherwise just print the string as a warning. */
+static int
+handle_output_debug_string (struct target_waitstatus *ourstatus)
+{
+ char *s;
+ int gotasig = FALSE;
+
+ if (!target_read_string
+ ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
+ || !s || !*s)
+ return gotasig;
+
+ if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
+ {
+ if (strncmp (s, "cYg", 3) != 0)
+ warning ("%s", s);
+ }
+ else
+ {
+ char *p;
+ int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
+ gotasig = target_signal_from_host (sig);
+ ourstatus->value.sig = gotasig;
+ if (gotasig)
+ ourstatus->kind = TARGET_WAITKIND_STOPPED;
+ }
+
+ xfree (s);
+ return gotasig;
+}
+
+static int
+display_selector (HANDLE thread, DWORD sel)
+{
+ LDT_ENTRY info;
+ if (GetThreadSelectorEntry (thread, sel, &info))
+ {
+ int base, limit;
+ printf_filtered ("0x%03lx: ", sel);
+ if (!info.HighWord.Bits.Pres)
+ {
+ puts_filtered ("Segment not present\n");
+ return 0;
+ }
+ base = (info.HighWord.Bits.BaseHi << 24) +
+ (info.HighWord.Bits.BaseMid << 16)
+ + info.BaseLow;
+ limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
+ if (info.HighWord.Bits.Granularity)
+ limit = (limit << 12) | 0xfff;
+ printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
+ if (info.HighWord.Bits.Default_Big)
+ puts_filtered(" 32-bit ");
+ else
+ puts_filtered(" 16-bit ");
+ switch ((info.HighWord.Bits.Type & 0xf) >> 1)
+ {
+ case 0:
+ puts_filtered ("Data (Read-Only, Exp-up");
+ break;
+ case 1:
+ puts_filtered ("Data (Read/Write, Exp-up");
+ break;
+ case 2:
+ puts_filtered ("Unused segment (");
+ break;
+ case 3:
+ puts_filtered ("Data (Read/Write, Exp-down");
+ break;
+ case 4:
+ puts_filtered ("Code (Exec-Only, N.Conf");
+ break;
+ case 5:
+ puts_filtered ("Code (Exec/Read, N.Conf");
+ break;
+ case 6:
+ puts_filtered ("Code (Exec-Only, Conf");
+ break;
+ case 7:
+ puts_filtered ("Code (Exec/Read, Conf");
+ break;
+ default:
+ printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type);
+ }
+ if ((info.HighWord.Bits.Type & 0x1) == 0)
+ puts_filtered(", N.Acc");
+ puts_filtered (")\n");
+ if ((info.HighWord.Bits.Type & 0x10) == 0)
+ puts_filtered("System selector ");
+ printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl);
+ if (info.HighWord.Bits.Granularity)
+ puts_filtered ("Page granular.\n");
+ else
+ puts_filtered ("Byte granular.\n");
+ return 1;
+ }
+ else
+ {
+ printf_filtered ("Invalid selector 0x%lx.\n",sel);
+ return 0;
+ }
+}
+
+static void
+display_selectors (char * args, int from_tty)
+{
+ if (!current_thread)
+ {
+ puts_filtered ("Impossible to display selectors now.\n");
+ return;
+ }
+ if (!args)
+ {
+
+ puts_filtered ("Selector $cs\n");
+ display_selector (current_thread->h,
+ current_thread->context.SegCs);
+ puts_filtered ("Selector $ds\n");
+ display_selector (current_thread->h,
+ current_thread->context.SegDs);
+ puts_filtered ("Selector $es\n");
+ display_selector (current_thread->h,
+ current_thread->context.SegEs);
+ puts_filtered ("Selector $ss\n");
+ display_selector (current_thread->h,
+ current_thread->context.SegSs);
+ puts_filtered ("Selector $fs\n");
+ display_selector (current_thread->h,
+ current_thread->context.SegFs);
+ puts_filtered ("Selector $gs\n");
+ display_selector (current_thread->h,
+ current_thread->context.SegGs);
+ }
+ else
+ {
+ int sel;
+ sel = parse_and_eval_long (args);
+ printf_filtered ("Selector \"%s\"\n",args);
+ display_selector (current_thread->h, sel);
+ }
+}
+
+static struct cmd_list_element *info_w32_cmdlist = NULL;
+
+static void
+info_w32_command (char *args, int from_tty)
+{
+ help_list (info_w32_cmdlist, "info w32 ", class_info, gdb_stdout);
+}
+
+
+#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
+ printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
+ (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
+
+static int
+handle_exception (struct target_waitstatus *ourstatus)
+{
+ thread_info *th;
+ DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
+
+ ourstatus->kind = TARGET_WAITKIND_STOPPED;
+
+ /* Record the context of the current thread */
+ th = thread_rec (current_event.dwThreadId, -1);
+
+ switch (code)
+ {
+ case EXCEPTION_ACCESS_VIOLATION:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
+ ourstatus->value.sig = TARGET_SIGNAL_SEGV;
+ break;
+ case STATUS_STACK_OVERFLOW:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
+ ourstatus->value.sig = TARGET_SIGNAL_SEGV;
+ break;
+ case STATUS_FLOAT_DENORMAL_OPERAND:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
+ ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ break;
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
+ ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_INEXACT_RESULT:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
+ ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_INVALID_OPERATION:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
+ ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_OVERFLOW:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
+ ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_STACK_CHECK:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
+ ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_UNDERFLOW:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
+ ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_DIVIDE_BY_ZERO:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
+ ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ break;
+ case STATUS_INTEGER_DIVIDE_BY_ZERO:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
+ ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ break;
+ case STATUS_INTEGER_OVERFLOW:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
+ ourstatus->value.sig = TARGET_SIGNAL_FPE;
+ break;
+ case EXCEPTION_BREAKPOINT:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
+ ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+ break;
+ case DBG_CONTROL_C:
+ DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
+ ourstatus->value.sig = TARGET_SIGNAL_INT;
+ break;
+ case DBG_CONTROL_BREAK:
+ DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
+ ourstatus->value.sig = TARGET_SIGNAL_INT;
+ break;
+ case EXCEPTION_SINGLE_STEP:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
+ ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+ break;
+ case EXCEPTION_ILLEGAL_INSTRUCTION:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
+ ourstatus->value.sig = TARGET_SIGNAL_ILL;
+ break;
+ case EXCEPTION_PRIV_INSTRUCTION:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
+ ourstatus->value.sig = TARGET_SIGNAL_ILL;
+ break;
+ case EXCEPTION_NONCONTINUABLE_EXCEPTION:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
+ ourstatus->value.sig = TARGET_SIGNAL_ILL;
+ break;
+ default:
+ if (current_event.u.Exception.dwFirstChance)
+ return 0;
+ printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
+ current_event.u.Exception.ExceptionRecord.ExceptionCode,
+ (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
+ ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
+ break;
+ }
+ exception_count++;
+ last_sig = ourstatus->value.sig;
+ return 1;
+}
+
+/* Resume all artificially suspended threads if we are continuing
+ execution */
+static BOOL
+child_continue (DWORD continue_status, int id)
+{
+ int i;
+ thread_info *th;
+ BOOL res;
+
+ DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
+ current_event.dwProcessId, current_event.dwThreadId,
+ continue_status == DBG_CONTINUE ?
+ "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
+ res = ContinueDebugEvent (current_event.dwProcessId,
+ current_event.dwThreadId,
+ continue_status);
+ continue_status = 0;
+ if (res)
+ for (th = &thread_head; (th = th->next) != NULL;)
+ if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
+ {
+
+ for (i = 0; i < th->suspend_count; i++)
+ (void) ResumeThread (th->h);
+ th->suspend_count = 0;
+ if (debug_registers_changed)
+ {
+ /* Only change the value of the debug reisters */
+ th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
+ th->context.Dr0 = dr[0];
+ th->context.Dr1 = dr[1];
+ th->context.Dr2 = dr[2];
+ th->context.Dr3 = dr[3];
+ /* th->context.Dr6 = dr[6];
+ FIXME: should we set dr6 also ?? */
+ th->context.Dr7 = dr[7];
+ CHECK (SetThreadContext (th->h, &th->context));
+ th->context.ContextFlags = 0;
+ }
+ }
+
+ debug_registers_changed = 0;
+ return res;
+}
+
+/* Get the next event from the child. Return 1 if the event requires
+ handling by WFI (or whatever).
+ */
+static int
+get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
+{
+ BOOL debug_event;
+ DWORD continue_status, event_code;
+ thread_info *th = NULL;
+ static thread_info dummy_thread_info;
+ int retval = 0;
+
+ last_sig = TARGET_SIGNAL_0;
+
+ if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
+ goto out;
+
+ event_count++;
+ continue_status = DBG_CONTINUE;
+
+ event_code = current_event.dwDebugEventCode;
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+
+ switch (event_code)
+ {
+ case CREATE_THREAD_DEBUG_EVENT:
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "CREATE_THREAD_DEBUG_EVENT"));
+ if (saw_create != 1)
+ break;
+ /* Record the existence of this thread */
+ th = child_add_thread (current_event.dwThreadId,
+ current_event.u.CreateThread.hThread);
+ if (info_verbose)
+ printf_unfiltered ("[New %s]\n",
+ target_pid_to_str (
+ pid_to_ptid (current_event.dwThreadId)));
+ retval = current_event.dwThreadId;
+ break;
+
+ case EXIT_THREAD_DEBUG_EVENT:
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "EXIT_THREAD_DEBUG_EVENT"));
+ if (saw_create != 1)
+ break;
+ child_delete_thread (current_event.dwThreadId);
+ th = &dummy_thread_info;
+ break;
+
+ case CREATE_PROCESS_DEBUG_EVENT:
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "CREATE_PROCESS_DEBUG_EVENT"));
+ CloseHandle (current_event.u.CreateProcessInfo.hFile);
+ if (++saw_create != 1)
+ {
+ CloseHandle (current_event.u.CreateProcessInfo.hProcess);
+ break;
+ }
+
+ current_process_handle = current_event.u.CreateProcessInfo.hProcess;
+ main_thread_id = current_event.dwThreadId;
+ /* Add the main thread */
+#if 0
+ th = child_add_thread (current_event.dwProcessId,
+ current_event.u.CreateProcessInfo.hProcess);
+#endif
+ th = child_add_thread (main_thread_id,
+ current_event.u.CreateProcessInfo.hThread);
+ retval = ourstatus->value.related_pid = current_event.dwThreadId;
+ break;
+
+ case EXIT_PROCESS_DEBUG_EVENT:
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "EXIT_PROCESS_DEBUG_EVENT"));
+ if (saw_create != 1)
+ break;
+ ourstatus->kind = TARGET_WAITKIND_EXITED;
+ ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
+ CloseHandle (current_process_handle);
+ retval = main_thread_id;
+ break;
+
+ case LOAD_DLL_DEBUG_EVENT:
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "LOAD_DLL_DEBUG_EVENT"));
+ CloseHandle (current_event.u.LoadDll.hFile);
+ if (saw_create != 1)
+ break;
+ catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
+ registers_changed (); /* mark all regs invalid */
+ ourstatus->kind = TARGET_WAITKIND_LOADED;
+ ourstatus->value.integer = 0;
+ retval = main_thread_id;
+ break;
+
+ case UNLOAD_DLL_DEBUG_EVENT:
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "UNLOAD_DLL_DEBUG_EVENT"));
+ if (saw_create != 1)
+ break;
+ catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
+ registers_changed (); /* mark all regs invalid */
+ /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
+ does not exist yet. */
+ break;
+
+ case EXCEPTION_DEBUG_EVENT:
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "EXCEPTION_DEBUG_EVENT"));
+ if (saw_create != 1)
+ break;
+ if (handle_exception (ourstatus))
+ retval = current_event.dwThreadId;
+ break;
+
+ case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "OUTPUT_DEBUG_STRING_EVENT"));
+ if (saw_create != 1)
+ break;
+ if (handle_output_debug_string (ourstatus))
+ retval = main_thread_id;
+ break;
+
+ default:
+ if (saw_create != 1)
+ break;
+ printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
+ (DWORD) current_event.dwProcessId,
+ (DWORD) current_event.dwThreadId);
+ printf_unfiltered (" unknown event code %ld\n",
+ current_event.dwDebugEventCode);
+ break;
+ }
+
+ if (!retval || saw_create != 1)
+ CHECK (child_continue (continue_status, -1));
+ else
+ {
+ current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
+ inferior_ptid = pid_to_ptid (retval);
+ }
+
+out:
+ return retval;
+}
+
+/* Wait for interesting events to occur in the target process. */
+static ptid_t
+child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+{
+ int pid = PIDGET (ptid);
+
+ /* 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->h. 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)
+ {
+ int retval = get_child_debug_event (pid, ourstatus);
+ if (retval)
+ return pid_to_ptid (retval);
+ else
+ {
+ int detach = 0;
+
+ if (ui_loop_hook != NULL)
+ detach = ui_loop_hook (0);
+
+ if (detach)
+ child_kill_inferior ();
+ }
+ }
+}
+
+static void
+do_initial_child_stuff (DWORD pid)
+{
+ extern int stop_after_trap;
+ int i;
+
+ last_sig = TARGET_SIGNAL_0;
+ event_count = 0;
+ exception_count = 0;
+ debug_registers_changed = 0;
+ debug_registers_used = 0;
+ for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
+ dr[i] = 0;
+ current_event.dwProcessId = pid;
+ memset (&current_event, 0, sizeof (current_event));
+ push_target (&child_ops);
+ child_init_thread_list ();
+ child_clear_solibs ();
+ clear_proceed_status ();
+ init_wait_for_inferior ();
+
+ target_terminal_init ();
+ target_terminal_inferior ();
+
+ while (1)
+ {
+ stop_after_trap = 1;
+ wait_for_inferior ();
+ if (stop_signal != TARGET_SIGNAL_TRAP)
+ resume (0, stop_signal);
+ else
+ break;
+ }
+ stop_after_trap = 0;
+ return;
+}
+
+/* Since Windows XP, detaching from a process is supported by Windows.
+ The following code tries loading the appropriate functions dynamically.
+ If loading these functions succeeds use them to actually detach from
+ the inferior process, otherwise behave as usual, pretending that
+ detach has worked. */
+static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
+static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
+
+static int
+has_detach_ability ()
+{
+ static HMODULE kernel32 = NULL;
+
+ if (!kernel32)
+ kernel32 = LoadLibrary ("kernel32.dll");
+ if (kernel32)
+ {
+ if (!DebugSetProcessKillOnExit)
+ DebugSetProcessKillOnExit = GetProcAddress (kernel32,
+ "DebugSetProcessKillOnExit");
+ if (!DebugActiveProcessStop)
+ DebugActiveProcessStop = GetProcAddress (kernel32,
+ "DebugActiveProcessStop");
+ if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
+ return 1;
+ }
+ return 0;
+}
+
+/* Attach to process PID, then initialize for debugging it. */
+static void
+child_attach (char *args, int from_tty)
+{
+ BOOL ok;
+ DWORD pid;
+
+ if (!args)
+ error_no_arg ("process-id to attach");
+
+ pid = strtoul (args, 0, 0);
+ ok = DebugActiveProcess (pid);
+
+ if (!ok)
+ error ("Can't attach to process.");
+
+ if (has_detach_ability ())
+ {
+ attach_flag = 1;
+ DebugSetProcessKillOnExit (FALSE);
+ }
+
+ 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 (pid_to_ptid (pid)));
+ else
+ printf_unfiltered ("Attaching to %s\n",
+ target_pid_to_str (pid_to_ptid (pid)));
+
+ gdb_flush (gdb_stdout);
+ }
+
+ do_initial_child_stuff (pid);
+ target_terminal_ours ();
+}
+
+static void
+child_detach (char *args, int from_tty)
+{
+ int detached = 1;
+
+ if (has_detach_ability ())
+ {
+ delete_command (NULL, 0);
+ child_continue (DBG_CONTINUE, -1);
+ if (!DebugActiveProcessStop (current_event.dwProcessId))
+ {
+ error ("Can't detach process %lu (error %lu)",
+ current_event.dwProcessId, GetLastError ());
+ detached = 0;
+ }
+ DebugSetProcessKillOnExit (FALSE);
+ }
+ if (detached && from_tty)
+ {
+ char *exec_file = get_exec_file (0);
+ if (exec_file == 0)
+ exec_file = "";
+ printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
+ current_event.dwProcessId);
+ gdb_flush (gdb_stdout);
+ }
+ inferior_ptid = null_ptid;
+ unpush_target (&child_ops);
+}
+
+/* Print status information about what we're accessing. */
+
+static void
+child_files_info (struct target_ops *ignore)
+{
+ printf_unfiltered ("\tUsing the running image of %s %s.\n",
+ attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
+}
+
+/* ARGSUSED */
+static void
+child_open (char *arg, int from_tty)
+{
+ error ("Use the \"run\" command to start a Unix child process.");
+}
+
+/* Start an inferior win32 child process and sets inferior_ptid 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 (char *exec_file, char *allargs, char **env)
+{
+ char *winenv;
+ char *temp;
+ int envlen;
+ int i;
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ BOOL ret;
+ DWORD flags;
+ char *args;
+ char real_path[MAXPATHLEN];
+ char *toexec;
+ char shell[MAX_PATH + 1]; /* Path to shell */
+ const char *sh;
+
+ if (!exec_file)
+ error ("No executable specified, use `target exec'.\n");
+
+ memset (&si, 0, sizeof (si));
+ si.cb = sizeof (si);
+
+ if (!useshell)
+ {
+ flags = DEBUG_ONLY_THIS_PROCESS;
+ cygwin_conv_to_win32_path (exec_file, real_path);
+ toexec = real_path;
+ }
+ else
+ {
+ char *newallargs;
+ sh = getenv ("SHELL");
+ if (!sh)
+ sh = "/bin/sh";
+ cygwin_conv_to_win32_path (sh, shell);
+ newallargs = alloca (sizeof (" -c 'exec '") + strlen (exec_file)
+ + strlen (allargs) + 2);
+ sprintf (newallargs, " -c 'exec %s %s'", exec_file, allargs);
+ allargs = newallargs;
+ toexec = shell;
+ flags = DEBUG_PROCESS;
+ }
+
+ if (new_group)
+ flags |= CREATE_NEW_PROCESS_GROUP;
+
+ if (new_console)
+ flags |= CREATE_NEW_CONSOLE;
+
+ args = alloca (strlen (toexec) + strlen (allargs) + 2);
+ strcpy (args, toexec);
+ strcat (args, " ");
+ strcat (args, allargs);
+
+ /* Prepare the environment vars for CreateProcess. */
+ {
+ /* This code used to assume all env vars were file names and would
+ translate them all to win32 style. That obviously doesn't work in the
+ general case. The current rule is that we only translate PATH.
+ We need to handle PATH because we're about to call CreateProcess and
+ it uses PATH to find DLL's. Fortunately PATH has a well-defined value
+ in both posix and win32 environments. cygwin.dll will change it back
+ to posix style if necessary. */
+
+ static const char *conv_path_names[] =
+ {
+ "PATH=",
+ 0
+ };
+
+ /* CreateProcess takes the environment list as a null terminated set of
+ strings (i.e. two nulls terminate the list). */
+
+ /* Get total size for env strings. */
+ for (envlen = 0, i = 0; env[i] && *env[i]; i++)
+ {
+ int j, len;
+
+ for (j = 0; conv_path_names[j]; j++)
+ {
+ len = strlen (conv_path_names[j]);
+ if (strncmp (conv_path_names[j], env[i], len) == 0)
+ {
+ if (cygwin_posix_path_list_p (env[i] + len))
+ envlen += len
+ + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
+ else
+ envlen += strlen (env[i]) + 1;
+ break;
+ }
+ }
+ if (conv_path_names[j] == NULL)
+ envlen += strlen (env[i]) + 1;
+ }
+
+ winenv = alloca (envlen + 1);
+
+ /* Copy env strings into new buffer. */
+ for (temp = winenv, i = 0; env[i] && *env[i]; i++)
+ {
+ int j, len;
+
+ for (j = 0; conv_path_names[j]; j++)
+ {
+ len = strlen (conv_path_names[j]);
+ if (strncmp (conv_path_names[j], env[i], len) == 0)
+ {
+ if (cygwin_posix_path_list_p (env[i] + len))
+ {
+ memcpy (temp, env[i], len);
+ cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
+ }
+ else
+ strcpy (temp, env[i]);
+ break;
+ }
+ }
+ if (conv_path_names[j] == NULL)
+ strcpy (temp, env[i]);
+
+ temp += strlen (temp) + 1;
+ }
+
+ /* Final nil string to terminate new env. */
+ *temp = 0;
+ }
+
+ ret = CreateProcess (0,
+ args, /* command line */
+ NULL, /* Security */
+ NULL, /* thread */
+ TRUE, /* inherit handles */
+ flags, /* start flags */
+ winenv,
+ NULL, /* current directory */
+ &si,
+ &pi);
+ if (!ret)
+ error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
+
+ CloseHandle (pi.hThread);
+ CloseHandle (pi.hProcess);
+
+ if (useshell && shell[0] != '\0')
+ saw_create = -1;
+ else
+ saw_create = 0;
+
+ do_initial_child_stuff (pi.dwProcessId);
+
+ /* child_continue (DBG_CONTINUE, -1); */
+ proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
+}
+
+static void
+child_mourn_inferior (void)
+{
+ (void) child_continue (DBG_CONTINUE, -1);
+ i386_cleanup_dregs();
+ 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. */
+
+static void
+child_stop (void)
+{
+ DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
+ CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
+ registers_changed (); /* refresh register state */
+}
+
+int
+child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
+ int write, struct mem_attrib *mem,
+ struct target_ops *target)
+{
+ DWORD done;
+ if (write)
+ {
+ DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
+ len, (DWORD) memaddr));
+ WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
+ len, &done);
+ FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
+ }
+ else
+ {
+ DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
+ len, (DWORD) memaddr));
+ ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
+ &done);
+ }
+ return done;
+}
+
+void
+child_kill_inferior (void)
+{
+ CHECK (TerminateProcess (current_process_handle, 0));
+
+ for (;;)
+ {
+ if (!child_continue (DBG_CONTINUE, -1))
+ break;
+ if (!WaitForDebugEvent (&current_event, INFINITE))
+ break;
+ if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
+ break;
+ }
+
+ CHECK (CloseHandle (current_process_handle));
+
+ /* this may fail in an attached process so don't check. */
+ (void) CloseHandle (current_thread->h);
+ target_mourn_inferior (); /* or just child_mourn_inferior? */
+}
+
+void
+child_resume (ptid_t ptid, int step, enum target_signal sig)
+{
+ thread_info *th;
+ DWORD continue_status = DBG_CONTINUE;
+
+ int pid = PIDGET (ptid);
+
+ if (sig != TARGET_SIGNAL_0)
+ {
+ if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
+ {
+ DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
+ }
+ else if (sig == last_sig)
+ continue_status = DBG_EXCEPTION_NOT_HANDLED;
+ else
+#if 0
+/* This code does not seem to work, because
+ the kernel does probably not consider changes in the ExceptionRecord
+ structure when passing the exception to the inferior.
+ Note that this seems possible in the exception handler itself. */
+ {
+ int i;
+ for (i = 0; xlate[i].them != -1; i++)
+ if (xlate[i].us == sig)
+ {
+ current_event.u.Exception.ExceptionRecord.ExceptionCode =
+ xlate[i].them;
+ continue_status = DBG_EXCEPTION_NOT_HANDLED;
+ break;
+ }
+ if (continue_status == DBG_CONTINUE)
+ {
+ DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig));
+ }
+ }
+#endif
+ DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
+ last_sig));
+ }
+
+ last_sig = TARGET_SIGNAL_0;
+
+ DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
+ pid, step, sig));
+
+ /* Get context for currently selected thread */
+ th = thread_rec (current_event.dwThreadId, FALSE);
+ if (th)
+ {
+ if (step)
+ {
+ /* Single step by setting t bit */
+ child_fetch_inferior_registers (PS_REGNUM);
+ th->context.EFlags |= FLAG_TRACE_BIT;
+ }
+
+ if (th->context.ContextFlags)
+ {
+ if (debug_registers_changed)
+ {
+ th->context.Dr0 = dr[0];
+ th->context.Dr1 = dr[1];
+ th->context.Dr2 = dr[2];
+ th->context.Dr3 = dr[3];
+ /* th->context.Dr6 = dr[6];
+ FIXME: should we set dr6 also ?? */
+ th->context.Dr7 = dr[7];
+ }
+ CHECK (SetThreadContext (th->h, &th->context));
+ th->context.ContextFlags = 0;
+ }
+ }
+
+ /* Allow continuing with the same signal that interrupted us.
+ Otherwise complain. */
+
+ child_continue (continue_status, pid);
+}
+
+static void
+child_prepare_to_store (void)
+{
+ /* Do nothing, since we can store individual regs */
+}
+
+static int
+child_can_run (void)
+{
+ return 1;
+}
+
+static void
+child_close (int x)
+{
+ DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
+ PIDGET (inferior_ptid)));
+}
+
+struct target_ops child_ops;
+
+static void
+init_child_ops (void)
+{
+ child_ops.to_shortname = "child";
+ child_ops.to_longname = "Win32 child process";
+ child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
+ child_ops.to_open = child_open;
+ child_ops.to_close = child_close;
+ child_ops.to_attach = child_attach;
+ child_ops.to_detach = child_detach;
+ child_ops.to_resume = child_resume;
+ child_ops.to_wait = child_wait;
+ child_ops.to_fetch_registers = child_fetch_inferior_registers;
+ child_ops.to_store_registers = child_store_inferior_registers;
+ child_ops.to_prepare_to_store = child_prepare_to_store;
+ child_ops.to_xfer_memory = child_xfer_memory;
+ child_ops.to_files_info = child_files_info;
+ child_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ child_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ child_ops.to_terminal_init = terminal_init_inferior;
+ child_ops.to_terminal_inferior = terminal_inferior;
+ child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ child_ops.to_terminal_ours = terminal_ours;
+ child_ops.to_terminal_info = child_terminal_info;
+ child_ops.to_kill = child_kill_inferior;
+ child_ops.to_load = 0;
+ child_ops.to_lookup_symbol = 0;
+ child_ops.to_create_inferior = child_create_inferior;
+ child_ops.to_mourn_inferior = child_mourn_inferior;
+ child_ops.to_can_run = child_can_run;
+ child_ops.to_notice_signals = 0;
+ child_ops.to_thread_alive = win32_child_thread_alive;
+ child_ops.to_pid_to_str = cygwin_pid_to_str;
+ child_ops.to_stop = child_stop;
+ child_ops.to_stratum = process_stratum;
+ child_ops.DONT_USE = 0;
+ child_ops.to_has_all_memory = 1;
+ child_ops.to_has_memory = 1;
+ child_ops.to_has_stack = 1;
+ child_ops.to_has_registers = 1;
+ child_ops.to_has_execution = 1;
+ child_ops.to_sections = 0;
+ child_ops.to_sections_end = 0;
+ child_ops.to_magic = OPS_MAGIC;
+}
+
+void
+_initialize_inftarg (void)
+{
+ struct cmd_list_element *c;
+
+ init_child_ops ();
+
+ c = add_com ("dll-symbols", class_files, dll_symbol_command,
+ "Load dll library symbols from FILE.");
+ set_cmd_completer (c, filename_completer);
+
+ add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
+
+ add_show_from_set (add_set_cmd ("shell", class_support, var_boolean,
+ (char *) &useshell,
+ "Set use of shell to start subprocess.",
+ &setlist),
+ &showlist);
+
+ 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_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
+ (char *) &debug_exec,
+ "Set whether to display execution in child process.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
+ (char *) &debug_events,
+ "Set whether to display kernel events in child process.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
+ (char *) &debug_memory,
+ "Set whether to display memory accesses in child process.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
+ (char *) &debug_exceptions,
+ "Set whether to display kernel exceptions in child process.",
+ &setlist),
+ &showlist);
+
+ add_info ("dll", info_dll_command, "Status of loaded DLLs.");
+ add_info_alias ("sharedlibrary", "dll", 1);
+
+ add_prefix_cmd ("w32", class_info, info_w32_command,
+ "Print information specific to Win32 debugging.",
+ &info_w32_cmdlist, "info w32 ", 0, &infolist);
+
+ add_cmd ("selector", class_info, display_selectors,
+ "Display selectors infos.",
+ &info_w32_cmdlist);
+
+ add_target (&child_ops);
+}
+
+/* Hardware watchpoint support, adapted from go32-nat.c code. */
+
+/* Pass the address ADDR to the inferior in the I'th debug register.
+ Here we just store the address in dr array, the registers will be
+ actually set up when child_continue is called. */
+void
+cygwin_set_dr (int i, CORE_ADDR addr)
+{
+ if (i < 0 || i > 3)
+ internal_error (__FILE__, __LINE__,
+ "Invalid register %d in cygwin_set_dr.\n", i);
+ dr[i] = (unsigned) addr;
+ debug_registers_changed = 1;
+ debug_registers_used = 1;
+}
+
+/* Pass the value VAL to the inferior in the DR7 debug control
+ register. Here we just store the address in D_REGS, the watchpoint
+ will be actually set up in child_wait. */
+void
+cygwin_set_dr7 (unsigned val)
+{
+ dr[7] = val;
+ debug_registers_changed = 1;
+ debug_registers_used = 1;
+}
+
+/* Get the value of the DR6 debug status register from the inferior.
+ Here we just return the value stored in dr[6]
+ by the last call to thread_rec for current_event.dwThreadId id. */
+unsigned
+cygwin_get_dr6 (void)
+{
+ return dr[6];
+}
+
+
+/* Determine if the thread referenced by "pid" is alive
+ by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
+ it means that the pid has died. Otherwise it is assumed to be alive. */
+static int
+win32_child_thread_alive (ptid_t ptid)
+{
+ int pid = PIDGET (ptid);
+
+ return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
+ FALSE : TRUE;
+}
+
+/* Convert pid to printable format. */
+char *
+cygwin_pid_to_str (ptid_t ptid)
+{
+ static char buf[80];
+ int pid = PIDGET (ptid);
+
+ if ((DWORD) pid == current_event.dwProcessId)
+ sprintf (buf, "process %d", pid);
+ else
+ sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
+ return buf;
+}
+
+static int
+core_dll_symbols_add (char *dll_name, DWORD base_addr)
+{
+ struct objfile *objfile;
+ char *objfile_basename;
+ const char *dll_basename;
+
+ if (!(dll_basename = strrchr (dll_name, '/')))
+ dll_basename = dll_name;
+ else
+ dll_basename++;
+
+ ALL_OBJFILES (objfile)
+ {
+ objfile_basename = strrchr (objfile->name, '/');
+
+ if (objfile_basename &&
+ strcmp (dll_basename, objfile_basename + 1) == 0)
+ {
+ printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
+ base_addr, dll_name);
+ goto out;
+ }
+ }
+
+ register_loaded_dll (dll_name, base_addr + 0x1000);
+ solib_symbols_add (dll_name, 0, (CORE_ADDR) base_addr + 0x1000);
+
+out:
+ return 1;
+}
+
+typedef struct
+{
+ struct target_ops *target;
+ bfd_vma addr;
+}
+map_code_section_args;
+
+static void
+map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
+{
+ int old;
+ int update_coreops;
+ struct section_table *new_target_sect_ptr;
+
+ map_code_section_args *args = (map_code_section_args *) obj;
+ struct target_ops *target = args->target;
+ if (sect->flags & SEC_CODE)
+ {
+ update_coreops = core_ops.to_sections == target->to_sections;
+
+ if (target->to_sections)
+ {
+ old = target->to_sections_end - target->to_sections;
+ target->to_sections = (struct section_table *)
+ xrealloc ((char *) target->to_sections,
+ (sizeof (struct section_table)) * (1 + old));
+ }
+ else
+ {
+ old = 0;
+ target->to_sections = (struct section_table *)
+ xmalloc ((sizeof (struct section_table)));
+ }
+ target->to_sections_end = target->to_sections + (1 + old);
+
+ /* Update the to_sections field in the core_ops structure
+ if needed. */
+ if (update_coreops)
+ {
+ core_ops.to_sections = target->to_sections;
+ core_ops.to_sections_end = target->to_sections_end;
+ }
+ new_target_sect_ptr = target->to_sections + old;
+ new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
+ new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
+ bfd_section_size (abfd, sect);;
+ new_target_sect_ptr->the_bfd_section = sect;
+ new_target_sect_ptr->bfd = abfd;
+ }
+}
+
+static int
+dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
+{
+ bfd *dll_bfd;
+ map_code_section_args map_args;
+ asection *lowest_sect;
+ char *name;
+ if (dll_name == NULL || target == NULL)
+ return 0;
+ name = xstrdup (dll_name);
+ dll_bfd = bfd_openr (name, "pei-i386");
+ if (dll_bfd == NULL)
+ return 0;
+
+ if (bfd_check_format (dll_bfd, bfd_object))
+ {
+ lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
+ if (lowest_sect == NULL)
+ return 0;
+ map_args.target = target;
+ map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
+
+ bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
+ }
+
+ return 1;
+}
+
+static void
+core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
+{
+ struct target_ops *target = (struct target_ops *) obj;
+
+ DWORD base_addr;
+
+ int dll_name_size;
+ char *dll_name = NULL;
+ char *buf = NULL;
+ struct win32_pstatus *pstatus;
+ char *p;
+
+ if (strncmp (sect->name, ".module", 7))
+ return;
+
+ buf = (char *) xmalloc (sect->_raw_size + 1);
+ if (!buf)
+ {
+ printf_unfiltered ("memory allocation failed for %s\n", sect->name);
+ goto out;
+ }
+ if (!bfd_get_section_contents (abfd, sect, buf, 0, sect->_raw_size))
+ goto out;
+
+ pstatus = (struct win32_pstatus *) buf;
+
+ memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
+ dll_name_size = pstatus->data.module_info.module_name_size;
+ if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > sect->_raw_size)
+ goto out;
+
+ dll_name = (char *) xmalloc (dll_name_size + 1);
+ if (!dll_name)
+ {
+ printf_unfiltered ("memory allocation failed for %s\n", sect->name);
+ goto out;
+ }
+ strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
+
+ while ((p = strchr (dll_name, '\\')))
+ *p = '/';
+
+ if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
+ printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
+
+ if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
+ printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
+
+out:
+ if (buf)
+ xfree (buf);
+ if (dll_name)
+ xfree (dll_name);
+ return;
+}
+
+void
+child_solib_add (char *filename, int from_tty, struct target_ops *target,
+ int readsyms)
+{
+ if (!readsyms)
+ return;
+ if (core_bfd)
+ {
+ child_clear_solibs ();
+ bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
+ }
+ else
+ {
+ if (solib_end && solib_end->name)
+ solib_end->objfile = solib_symbols_add (solib_end->name, from_tty,
+ solib_end->load_addr);
+ }
+}
+
+static void
+fetch_elf_core_registers (char *core_reg_sect,
+ unsigned core_reg_size,
+ int which,
+ CORE_ADDR reg_addr)
+{
+ int r;
+ if (core_reg_size < sizeof (CONTEXT))
+ {
+ error ("Core file register section too small (%u bytes).", core_reg_size);
+ return;
+ }
+ for (r = 0; r < NUM_REGS; r++)
+ supply_register (r, core_reg_sect + mappings[r]);
+}
+
+static struct core_fns win32_elf_core_fns =
+{
+ bfd_target_elf_flavour,
+ default_check_format,
+ default_core_sniffer,
+ fetch_elf_core_registers,
+ NULL
+};
+
+void
+_initialize_core_win32 (void)
+{
+ add_core_fns (&win32_elf_core_fns);
+}
+
+void
+_initialize_check_for_gdb_ini (void)
+{
+ char *homedir;
+ if (inhibit_gdbinit)
+ return;
+
+ homedir = getenv ("HOME");
+ if (homedir)
+ {
+ char *p;
+ char *oldini = (char *) alloca (strlen (homedir) +
+ sizeof ("/gdb.ini"));
+ strcpy (oldini, homedir);
+ p = strchr (oldini, '\0');
+ if (p > oldini && p[-1] != '/')
+ *p++ = '/';
+ strcpy (p, "gdb.ini");
+ if (access (oldini, 0) == 0)
+ {
+ int len = strlen (oldini);
+ char *newini = alloca (len + 1);
+ sprintf (newini, "%.*s.gdbinit",
+ (int) (len - (sizeof ("gdb.ini") - 1)), oldini);
+ warning ("obsolete '%s' found. Rename to '%s'.", oldini, newini);
+ }
+ }
+}
diff --git a/gdb/wince-stub.c b/gdb/wince-stub.c
new file mode 100644
index 00000000000..ce872d8137e
--- /dev/null
+++ b/gdb/wince-stub.c
@@ -0,0 +1,592 @@
+/* wince-stub.c -- debugging stub for a Windows CE device
+
+ Copyright 1999, 2000 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions, A Red Hat Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+/* by Christopher Faylor (cgf@cygnus.com) */
+
+#include <stdarg.h>
+#include <windows.h>
+#include <winsock.h>
+#include "wince-stub.h"
+
+#define MALLOC(n) (void *) LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, (UINT)(n))
+#define REALLOC(s, n) (void *) LocalReAlloc ((HLOCAL)(s), (UINT)(n), LMEM_MOVEABLE)
+#define FREE(s) LocalFree ((HLOCAL)(s))
+
+static int skip_next_id = 0; /* Don't read next API code from socket */
+
+/* v-style interface for handling varying argument list error messages.
+ Displays the error message in a dialog box and exits when user clicks
+ on OK. */
+static void
+vstub_error (LPCWSTR fmt, va_list args)
+{
+ WCHAR buf[4096];
+ wvsprintfW (buf, fmt, args);
+
+ MessageBoxW (NULL, buf, L"GDB", MB_ICONERROR);
+ WSACleanup ();
+ ExitThread (1);
+}
+
+/* The standard way to display an error message and exit. */
+static void
+stub_error (LPCWSTR fmt, ...)
+{
+ va_list args;
+ va_start (args, fmt);
+ vstub_error (fmt, args);
+}
+
+/* Allocate a limited pool of memory, reallocating over unused
+ buffers. This assumes that there will never be more than four
+ "buffers" required which, so far, is a safe assumption. */
+static LPVOID
+mempool (unsigned int len)
+{
+ static int outn = -1;
+ static LPWSTR outs[4] = {NULL, NULL, NULL, NULL};
+
+ if (++outn >= (sizeof (outs) / sizeof (outs[0])))
+ outn = 0;
+
+ /* Allocate space for the converted string, reusing any previously allocated
+ space, if applicable. */
+ if (outs[outn])
+ FREE (outs[outn]);
+ outs[outn] = (LPWSTR) MALLOC (len);
+
+ return outs[outn];
+}
+
+/* Standard "oh well" can't communicate error. Someday this might attempt
+ synchronization. */
+static void
+attempt_resync (LPCWSTR huh, int s)
+{
+ stub_error (L"lost synchronization with host attempting %s. Error %d", huh, WSAGetLastError ());
+}
+
+/* Read arbitrary stuff from a socket. */
+static int
+sockread (LPCWSTR huh, int s, void *str, size_t n)
+{
+ for (;;)
+ {
+ if (recv (s, str, n, 0) == (int) n)
+ return n;
+ attempt_resync (huh, s);
+ }
+}
+
+/* Write arbitrary stuff to a socket. */
+static int
+sockwrite (LPCWSTR huh, int s, const void *str, size_t n)
+{
+ for (;;)
+ {
+ if (send (s, str, n, 0) == (int) n)
+ return n;
+ attempt_resync (huh, s);
+ }
+}
+
+/* Get a an ID (possibly) and a DWORD from the host gdb.
+ Don't bother with the id if the main loop has already
+ read it. */
+static DWORD
+getdword (LPCWSTR huh, int s, gdb_wince_id what_this)
+{
+ DWORD n;
+ gdb_wince_id what;
+
+ if (skip_next_id)
+ skip_next_id = 0;
+ else
+ do
+ if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
+ stub_error (L"error getting record type from host - %s.", huh);
+ while (what_this != what);
+
+ if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
+ stub_error (L"error getting %s from host.", huh);
+
+ return n;
+}
+
+/* Get a an ID (possibly) and a WORD from the host gdb.
+ Don't bother with the id if the main loop has already
+ read it. */
+static WORD
+getword (LPCWSTR huh, int s, gdb_wince_id what_this)
+{
+ WORD n;
+ gdb_wince_id what;
+
+ if (skip_next_id)
+ skip_next_id = 0;
+ else
+ do
+ if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
+ stub_error (L"error getting record type from host - %s.", huh);
+ while (what_this != what);
+
+ if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
+ stub_error (L"error getting %s from host.", huh);
+
+ return n;
+}
+
+/* Handy defines for getting various types of values. */
+#define gethandle(huh, s, what) (HANDLE) getdword ((huh), (s), (what))
+#define getpvoid(huh, s, what) (LPVOID) getdword ((huh), (s), (what))
+#define getlen(huh, s, what) (gdb_wince_len) getword ((huh), (s), (what))
+
+/* Get an arbitrary block of memory from the gdb host. This comes in
+ two chunks an id/dword representing the length and the stream of memory
+ itself. Returns a pointer, allocated via mempool, to a memory buffer. */
+static LPWSTR
+getmemory (LPCWSTR huh, int s, gdb_wince_id what, gdb_wince_len *inlen)
+{
+ LPVOID p;
+ gdb_wince_len dummy;
+
+ if (!inlen)
+ inlen = &dummy;
+
+ *inlen = getlen (huh, s, what);
+
+ p = mempool ((unsigned int) *inlen); /* FIXME: check for error */
+
+ if ((gdb_wince_len) sockread (huh, s, p, *inlen) != *inlen)
+ stub_error (L"error getting string from host.");
+
+ return p;
+}
+
+/* Output an id/dword to the host */
+static void
+putdword (LPCWSTR huh, int s, gdb_wince_id what, DWORD n)
+{
+ if (sockwrite (huh, s, &what, sizeof (what)) != sizeof (what))
+ stub_error (L"error writing record id for %s to host.", huh);
+ if (sockwrite (huh, s, &n, sizeof (n)) != sizeof (n))
+ stub_error (L"error writing %s to host.", huh);
+}
+
+/* Output an id/word to the host */
+static void
+putword (LPCWSTR huh, int s, gdb_wince_id what, WORD n)
+{
+ if (sockwrite (huh, s, &what, sizeof (what)) != sizeof (what))
+ stub_error (L"error writing record id for %s to host.", huh);
+ if (sockwrite (huh, s, &n, sizeof (n)) != sizeof (n))
+ stub_error (L"error writing %s to host.", huh);
+}
+
+/* Convenience define for outputting a "gdb_wince_len" type. */
+#define putlen(huh, s, what, n) putword ((huh), (s), (what), (gdb_wince_len) (n))
+
+/* Put an arbitrary block of memory to the gdb host. This comes in
+ two chunks an id/dword representing the length and the stream of memory
+ itself. */
+static void
+putmemory (LPCWSTR huh, int s, gdb_wince_id what, const void *mem, gdb_wince_len len)
+{
+ putlen (huh, s, what, len);
+ if (((short) len > 0) && (gdb_wince_len) sockwrite (huh, s, mem, len) != len)
+ stub_error (L"error writing memory to host.");
+}
+
+/* Output the result of an operation to the host. If res != 0, sends a block of
+ memory starting at mem of len bytes. If res == 0, sends -GetLastError () and
+ avoids sending the mem. */
+static void
+putresult (LPCWSTR huh, gdb_wince_result res, int s, gdb_wince_id what, const void *mem, gdb_wince_len len)
+{
+ if (!res)
+ len = -(int) GetLastError ();
+ putmemory (huh, s, what, mem, len);
+}
+
+static HANDLE curproc; /* Currently unused, but nice for debugging */
+
+/* Emulate CreateProcess. Returns &pi if no error. */
+static void
+create_process (int s)
+{
+ LPWSTR exec_file = getmemory (L"CreateProcess exec_file", s, GDB_CREATEPROCESS, NULL);
+ LPWSTR args = getmemory (L"CreateProcess args", s, GDB_CREATEPROCESS, NULL);
+ DWORD flags = getdword (L"CreateProcess flags", s, GDB_CREATEPROCESS);
+ PROCESS_INFORMATION pi;
+ gdb_wince_result res;
+
+ res = CreateProcessW (exec_file,
+ args, /* command line */
+ NULL, /* Security */
+ NULL, /* thread */
+ FALSE, /* inherit handles */
+ flags, /* start flags */
+ NULL,
+ NULL, /* current directory */
+ NULL,
+ &pi);
+ putresult (L"CreateProcess", res, s, GDB_CREATEPROCESS, &pi, sizeof (pi));
+ curproc = pi.hProcess;
+}
+
+/* Emulate TerminateProcess. Returns return value of TerminateProcess if
+ no error.
+ *** NOTE: For some unknown reason, TerminateProcess seems to always return
+ an ACCESS_DENIED (on Windows CE???) error. So, force a TRUE value for now. */
+static void
+terminate_process (int s)
+{
+ gdb_wince_result res;
+ HANDLE h = gethandle (L"TerminateProcess handle", s, GDB_TERMINATEPROCESS);
+
+ res = TerminateProcess (h, 0) || 1; /* Doesn't seem to work on SH so default to TRUE */
+ putresult (L"Terminate process result", res, s, GDB_TERMINATEPROCESS,
+ &res, sizeof (res));
+}
+
+static int stepped = 0;
+/* Handle single step instruction. FIXME: unneded? */
+static void
+flag_single_step (int s)
+{
+ stepped = 1;
+ skip_next_id = 0;
+}
+
+struct skipper
+{
+ wchar_t *s;
+ int nskip;
+} skippy[] =
+{
+ {L"Undefined Instruction:", 1},
+ {L"Data Abort:", 2},
+ {NULL, 0}
+};
+
+static int
+skip_message (DEBUG_EVENT *ev)
+{
+ char s[80];
+ DWORD nread;
+ struct skipper *skp;
+ int nbytes = ev->u.DebugString.nDebugStringLength;
+
+ if (nbytes > sizeof(s))
+ nbytes = sizeof(s);
+
+ memset (s, 0, sizeof (s));
+ if (!ReadProcessMemory (curproc, ev->u.DebugString.lpDebugStringData,
+ s, nbytes, &nread))
+ return 0;
+
+ for (skp = skippy; skp->s != NULL; skp++)
+ if (wcsncmp ((wchar_t *) s, skp->s, wcslen (skp->s)) == 0)
+ return skp->nskip;
+
+ return 0;
+}
+
+/* Emulate WaitForDebugEvent. Returns the debug event on success. */
+static void
+wait_for_debug_event (int s)
+{
+ DWORD ms = getdword (L"WaitForDebugEvent ms", s, GDB_WAITFORDEBUGEVENT);
+ gdb_wince_result res;
+ DEBUG_EVENT ev;
+ static int skip_next = 0;
+
+ for (;;)
+ {
+ res = WaitForDebugEvent (&ev, ms);
+
+ if (ev.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
+ {
+ if (skip_next)
+ {
+ skip_next--;
+ goto ignore;
+ }
+ if (skip_next = skip_message (&ev))
+ goto ignore;
+ }
+
+ putresult (L"WaitForDebugEvent event", res, s, GDB_WAITFORDEBUGEVENT,
+ &ev, sizeof (ev));
+ break;
+
+ ignore:
+ ContinueDebugEvent (ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
+ }
+
+ return;
+}
+
+/* Emulate GetThreadContext. Returns CONTEXT structure on success. */
+static void
+get_thread_context (int s)
+{
+ CONTEXT c;
+ HANDLE h = gethandle (L"GetThreadContext handle", s, GDB_GETTHREADCONTEXT);
+ gdb_wince_result res;
+
+ memset (&c, 0, sizeof (c));
+ c.ContextFlags = getdword (L"GetThreadContext flags", s, GDB_GETTHREADCONTEXT);
+
+ res = (gdb_wince_result) GetThreadContext (h, &c);
+ putresult (L"GetThreadContext data", res, s, GDB_GETTHREADCONTEXT,
+ &c, sizeof (c));
+}
+
+/* Emulate GetThreadContext. Returns success of SetThreadContext. */
+static void
+set_thread_context (int s)
+{
+ gdb_wince_result res;
+ HANDLE h = gethandle (L"SetThreadContext handle", s, GDB_SETTHREADCONTEXT);
+ LPCONTEXT pc = (LPCONTEXT) getmemory (L"SetThreadContext context", s,
+ GDB_SETTHREADCONTEXT, NULL);
+
+ res = SetThreadContext (h, pc);
+ putresult (L"SetThreadContext result", res, s, GDB_SETTHREADCONTEXT,
+ &res, sizeof (res));
+}
+
+/* Emulate ReadProcessMemory. Returns memory read on success. */
+static void
+read_process_memory (int s)
+{
+ HANDLE h = gethandle (L"ReadProcessMemory handle", s, GDB_READPROCESSMEMORY);
+ LPVOID p = getpvoid (L"ReadProcessMemory base", s, GDB_READPROCESSMEMORY);
+ gdb_wince_len len = getlen (L"ReadProcessMemory size", s, GDB_READPROCESSMEMORY);
+ LPVOID buf = mempool ((unsigned int) len);
+ DWORD outlen;
+ gdb_wince_result res;
+
+ outlen = 0;
+ res = (gdb_wince_result) ReadProcessMemory (h, p, buf, len, &outlen);
+ putresult (L"ReadProcessMemory data", res, s, GDB_READPROCESSMEMORY,
+ buf, (gdb_wince_len) outlen);
+}
+
+/* Emulate WriteProcessMemory. Returns WriteProcessMemory success. */
+static void
+write_process_memory (int s)
+{
+ HANDLE h = gethandle (L"WriteProcessMemory handle", s, GDB_WRITEPROCESSMEMORY);
+ LPVOID p = getpvoid (L"WriteProcessMemory base", s, GDB_WRITEPROCESSMEMORY);
+ gdb_wince_len len;
+ LPVOID buf = getmemory (L"WriteProcessMemory buf", s, GDB_WRITEPROCESSMEMORY, &len);
+ DWORD outlen;
+ gdb_wince_result res;
+
+ outlen = 0;
+ res = WriteProcessMemory (h, p, buf, (DWORD) len, &outlen);
+ putresult (L"WriteProcessMemory data", res, s, GDB_WRITEPROCESSMEMORY,
+ (gdb_wince_len *) & outlen, sizeof (gdb_wince_len));
+}
+
+/* Return non-zero to gdb host if given thread is alive. */
+static void
+thread_alive (int s)
+{
+ HANDLE h = gethandle (L"ThreadAlive handle", s, GDB_THREADALIVE);
+ gdb_wince_result res;
+
+ res = WaitForSingleObject (h, 0) == WAIT_OBJECT_0 ? 1 : 0;
+ putresult (L"WriteProcessMemory data", res, s, GDB_THREADALIVE,
+ &res, sizeof (res));
+}
+
+/* Emulate SuspendThread. Returns value returned from SuspendThread. */
+static void
+suspend_thread (int s)
+{
+ DWORD res;
+ HANDLE h = gethandle (L"SuspendThread handle", s, GDB_SUSPENDTHREAD);
+ res = SuspendThread (h);
+ putdword (L"SuspendThread result", s, GDB_SUSPENDTHREAD, res);
+}
+
+/* Emulate ResumeThread. Returns value returned from ResumeThread. */
+static void
+resume_thread (int s)
+{
+ DWORD res;
+ HANDLE h = gethandle (L"ResumeThread handle", s, GDB_RESUMETHREAD);
+ res = ResumeThread (h);
+ putdword (L"ResumeThread result", s, GDB_RESUMETHREAD, res);
+}
+
+/* Emulate ContinueDebugEvent. Returns ContinueDebugEvent success. */
+static void
+continue_debug_event (int s)
+{
+ gdb_wince_result res;
+ DWORD pid = getdword (L"ContinueDebugEvent pid", s, GDB_CONTINUEDEBUGEVENT);
+ DWORD tid = getdword (L"ContinueDebugEvent tid", s, GDB_CONTINUEDEBUGEVENT);
+ DWORD status = getdword (L"ContinueDebugEvent status", s, GDB_CONTINUEDEBUGEVENT);
+ res = (gdb_wince_result) ContinueDebugEvent (pid, tid, status);
+ putresult (L"ContinueDebugEvent result", res, s, GDB_CONTINUEDEBUGEVENT, &res, sizeof (res));
+}
+
+/* Emulate CloseHandle. Returns CloseHandle success. */
+static void
+close_handle (int s)
+{
+ gdb_wince_result res;
+ HANDLE h = gethandle (L"CloseHandle handle", s, GDB_CLOSEHANDLE);
+ res = (gdb_wince_result) CloseHandle (h);
+ putresult (L"CloseHandle result", res, s, GDB_CLOSEHANDLE, &res, sizeof (res));
+}
+
+/* Main loop for reading requests from gdb host on the socket. */
+static void
+dispatch (int s)
+{
+ gdb_wince_id id;
+
+ /* Continue reading from socket until receive a GDB_STOPSUB. */
+ while (sockread (L"Dispatch", s, &id, sizeof (id)) > 0)
+ {
+ skip_next_id = 1;
+ switch (id)
+ {
+ case GDB_CREATEPROCESS:
+ create_process (s);
+ break;
+ case GDB_TERMINATEPROCESS:
+ terminate_process (s);
+ break;
+ case GDB_WAITFORDEBUGEVENT:
+ wait_for_debug_event (s);
+ break;
+ case GDB_GETTHREADCONTEXT:
+ get_thread_context (s);
+ break;
+ case GDB_SETTHREADCONTEXT:
+ set_thread_context (s);
+ break;
+ case GDB_READPROCESSMEMORY:
+ read_process_memory (s);
+ break;
+ case GDB_WRITEPROCESSMEMORY:
+ write_process_memory (s);
+ break;
+ case GDB_THREADALIVE:
+ thread_alive (s);
+ break;
+ case GDB_SUSPENDTHREAD:
+ suspend_thread (s);
+ break;
+ case GDB_RESUMETHREAD:
+ resume_thread (s);
+ break;
+ case GDB_CONTINUEDEBUGEVENT:
+ continue_debug_event (s);
+ break;
+ case GDB_CLOSEHANDLE:
+ close_handle (s);
+ break;
+ case GDB_STOPSTUB:
+ terminate_process (s);
+ return;
+ case GDB_SINGLESTEP:
+ flag_single_step (s);
+ break;
+ default:
+ {
+ WCHAR buf[80];
+ wsprintfW (buf, L"Invalid command id received: %d", id);
+ MessageBoxW (NULL, buf, L"GDB", MB_ICONERROR);
+ skip_next_id = 0;
+ }
+ }
+ }
+}
+
+/* The Windows Main entry point */
+int WINAPI
+WinMain (HINSTANCE hi, HINSTANCE hp, LPWSTR cmd, int show)
+{
+ struct hostent *h;
+ int s;
+ struct WSAData wd;
+ struct sockaddr_in sin;
+ int tmp;
+ LPWSTR whost;
+ char host[80];
+
+ whost = wcschr (cmd, L' '); /* Look for argument. */
+
+ /* If no host is specified, just use default */
+ if (whost)
+ {
+ /* Eat any spaces. */
+ while (*whost == L' ' || *whost == L'\t')
+ whost++;
+
+ wcstombs (host, whost, 80); /* Convert from UNICODE to ascii */
+ }
+
+ /* Winsock initialization. */
+ if (WSAStartup (MAKEWORD (1, 1), &wd))
+ stub_error (L"Couldn't initialize WINSOCK.");
+
+ /* If whost was specified, first try it. If it was not specified or the
+ host lookup failed, try the Windows CE magic ppp_peer lookup. ppp_peer
+ is supposed to be the Windows host sitting on the other end of the
+ serial cable. */
+ if (whost && *whost && (h = gethostbyname (host)) != NULL)
+ /* nothing to do */ ;
+ else if ((h = gethostbyname ("ppp_peer")) == NULL)
+ stub_error (L"Couldn't get IP address of host system. Error %d", WSAGetLastError ());
+
+ /* Get a socket. */
+ if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ stub_error (L"Couldn't connect to host system. Error %d", WSAGetLastError ());
+
+ /* Allow rapid reuse of the port. */
+ tmp = 1;
+ setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp));
+
+ /* Set up the information for connecting to the host gdb process. */
+ memset (&sin, 0, sizeof (sin));
+ sin.sin_family = h->h_addrtype;
+ memcpy (&sin.sin_addr, h->h_addr, h->h_length);
+ sin.sin_port = htons (7000); /* FIXME: This should be configurable */
+
+ /* Connect to host */
+ if (connect (s, (struct sockaddr *) &sin, sizeof (sin)) < 0)
+ stub_error (L"Couldn't connect to host gdb.");
+
+ /* Read from socket until told to exit. */
+ dispatch (s);
+ WSACleanup ();
+ return 0;
+}
diff --git a/gdb/wince-stub.h b/gdb/wince-stub.h
new file mode 100644
index 00000000000..21e9002116f
--- /dev/null
+++ b/gdb/wince-stub.h
@@ -0,0 +1,48 @@
+/* wince-stub.h -- Definitions for commnicating with the WinCE stub.
+
+ Copyright 1999, 2000 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions, A Red Hat Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+/* by Christopher Faylor (cgf@cygnus.com) */
+
+enum win_func
+ {
+ GDB_CREATEPROCESS = 42,
+ GDB_TERMINATEPROCESS,
+ GDB_WAITFORDEBUGEVENT,
+ GDB_GETTHREADCONTEXT,
+ GDB_SETTHREADCONTEXT,
+ GDB_READPROCESSMEMORY,
+ GDB_WRITEPROCESSMEMORY,
+ GDB_THREADALIVE,
+ GDB_SUSPENDTHREAD,
+ GDB_RESUMETHREAD,
+ GDB_CONTINUEDEBUGEVENT,
+ GDB_CLOSEHANDLE,
+ GDB_STOPSTUB,
+ GDB_SINGLESTEP,
+ GDB_SETBREAK,
+ GDB_INVALID
+ };
+
+typedef unsigned char gdb_wince_id;
+typedef unsigned short gdb_wince_len;
+typedef short gdb_wince_result;
diff --git a/gdb/wince.c b/gdb/wince.c
new file mode 100644
index 00000000000..e37866c34a9
--- /dev/null
+++ b/gdb/wince.c
@@ -0,0 +1,2047 @@
+/* Target-vector operations for controlling Windows CE child processes, for GDB.
+ Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions, A Red Hat Company.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without 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.
+ */
+
+/* by Christopher Faylor (cgf@cygnus.com) */
+
+/* We assume we're being built with and will be used for cygwin. */
+
+#ifdef SHx
+#undef SH4
+#define SH4 /* Just to get all of the CONTEXT defines. */
+#endif
+
+#include "defs.h"
+#include "frame.h" /* required by inferior.h */
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "command.h"
+#include <signal.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+#include <windows.h>
+#include <rapi.h>
+#include <netdb.h>
+#include <cygwin/in.h>
+#include <cygwin/socket.h>
+
+#include "buildsym.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdb_string.h"
+#include "gdbthread.h"
+#include "gdbcmd.h"
+#include <sys/param.h>
+#include "wince-stub.h"
+#include <time.h>
+#include "regcache.h"
+
+/* The ui's event loop. */
+extern int (*ui_loop_hook) (int signo);
+
+/* If we're not using the old Cygwin header file set, define the
+ following which never should have been in the generic Win32 API
+ headers in the first place since they were our own invention... */
+#ifndef _GNU_H_WINDOWS_H
+#define FLAG_TRACE_BIT 0x100
+#ifdef CONTEXT_FLOATING_POINT
+#define CONTEXT_DEBUGGER0 (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
+#else
+#define CONTEXT_DEBUGGER0 (CONTEXT_FULL)
+#endif
+#endif
+
+#ifdef SH4
+#define CONTEXT_DEBUGGER ((CONTEXT_DEBUGGER0 & ~(CONTEXT_SH4 | CONTEXT_FLOATING_POINT)) | CONTEXT_SH3)
+#else
+#define CONTEXT_DEBUGGER CONTEXT_DEBUGGER0
+#endif
+/* The string sent by cygwin when it processes a signal.
+ FIXME: This should be in a cygwin include file. */
+#define CYGWIN_SIGNAL_STRING "cygwin: signal"
+
+#define CHECK(x) check (x, __FILE__,__LINE__)
+#define DEBUG_EXEC(x) if (debug_exec) printf x
+#define DEBUG_EVENTS(x) if (debug_events) printf x
+#define DEBUG_MEM(x) if (debug_memory) printf x
+#define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
+
+static int connection_initialized = 0; /* True if we've initialized a RAPI session. */
+
+/* The directory where the stub and executable files are uploaded. */
+static const char *remote_directory = "\\gdb";
+
+/* The types automatic upload available. */
+static enum
+ {
+ UPLOAD_ALWAYS = 0,
+ UPLOAD_NEWER = 1,
+ UPLOAD_NEVER = 2
+ }
+upload_when = UPLOAD_NEWER;
+
+/* Valid options for 'set remoteupload'. Note that options
+ must track upload_when enum. */
+static struct opts
+ {
+ const char *name;
+ int abbrev;
+ }
+upload_options[3] =
+{
+ {
+ "always", 1
+ }
+ ,
+ {
+ "newer", 3
+ }
+ ,
+ {
+ "never", 3
+ }
+};
+
+static char *remote_upload = NULL; /* Set by set remoteupload */
+static int remote_add_host = 0;
+
+/* Forward declaration */
+extern struct target_ops child_ops;
+
+static int win32_child_thread_alive (ptid_t);
+void child_kill_inferior (void);
+
+static int last_sig = 0; /* Set if a signal was received from the
+ debugged process */
+
+/* Thread information structure used to track information that is
+ not available in gdb's thread structure. */
+typedef struct thread_info_struct
+ {
+ struct thread_info_struct *next;
+ DWORD id;
+ HANDLE h;
+ char *name;
+ int suspend_count;
+ int stepped; /* True if stepped. */
+ CORE_ADDR step_pc;
+ unsigned long step_prev;
+ CONTEXT context;
+ }
+thread_info;
+
+static thread_info thread_head =
+{NULL};
+static thread_info * thread_rec (DWORD id, int get_context);
+
+/* The process and thread handles for the above context. */
+
+static DEBUG_EVENT current_event; /* The current debug event from
+ WaitForDebugEvent */
+static HANDLE current_process_handle; /* Currently executing process */
+static thread_info *current_thread; /* Info on currently selected thread */
+static thread_info *this_thread; /* Info on thread returned by wait_for_debug_event */
+static DWORD main_thread_id; /* Thread ID of the main thread */
+
+/* Counts of things. */
+static int exception_count = 0;
+static int event_count = 0;
+
+/* User options. */
+static int debug_exec = 0; /* show execution */
+static int debug_events = 0; /* show events from kernel */
+static int debug_memory = 0; /* show target memory accesses */
+static int debug_exceptions = 0; /* show target exceptions */
+
+/* An array of offset mappings into a Win32 Context structure.
+ This is a one-to-one mapping which is indexed by gdb's register
+ numbers. It retrieves an offset into the context structure where
+ the 4 byte register is located.
+ An offset value of -1 indicates that Win32 does not provide this
+ register in it's CONTEXT structure. regptr will return zero for this
+ register.
+
+ This is used by the regptr function. */
+#define context_offset(x) ((int)&(((PCONTEXT)NULL)->x))
+static const int mappings[NUM_REGS + 1] =
+{
+#ifdef __i386__
+ context_offset (Eax),
+ context_offset (Ecx),
+ context_offset (Edx),
+ context_offset (Ebx),
+ context_offset (Esp),
+ context_offset (Ebp),
+ context_offset (Esi),
+ context_offset (Edi),
+ context_offset (Eip),
+ context_offset (EFlags),
+ context_offset (SegCs),
+ context_offset (SegSs),
+ context_offset (SegDs),
+ context_offset (SegEs),
+ context_offset (SegFs),
+ context_offset (SegGs),
+ context_offset (FloatSave.RegisterArea[0 * 10]),
+ context_offset (FloatSave.RegisterArea[1 * 10]),
+ context_offset (FloatSave.RegisterArea[2 * 10]),
+ context_offset (FloatSave.RegisterArea[3 * 10]),
+ context_offset (FloatSave.RegisterArea[4 * 10]),
+ context_offset (FloatSave.RegisterArea[5 * 10]),
+ context_offset (FloatSave.RegisterArea[6 * 10]),
+ context_offset (FloatSave.RegisterArea[7 * 10]),
+#elif defined(SHx)
+ context_offset (R0),
+ context_offset (R1),
+ context_offset (R2),
+ context_offset (R3),
+ context_offset (R4),
+ context_offset (R5),
+ context_offset (R6),
+ context_offset (R7),
+ context_offset (R8),
+ context_offset (R9),
+ context_offset (R10),
+ context_offset (R11),
+ context_offset (R12),
+ context_offset (R13),
+ context_offset (R14),
+ context_offset (R15),
+ context_offset (Fir),
+ context_offset (PR), /* Procedure Register */
+ context_offset (GBR), /* Global Base Register */
+ context_offset (MACH), /* Accumulate */
+ context_offset (MACL), /* Multiply */
+ context_offset (Psr),
+ context_offset (Fpul),
+ context_offset (Fpscr),
+ context_offset (FRegs[0]),
+ context_offset (FRegs[1]),
+ context_offset (FRegs[2]),
+ context_offset (FRegs[3]),
+ context_offset (FRegs[4]),
+ context_offset (FRegs[5]),
+ context_offset (FRegs[6]),
+ context_offset (FRegs[7]),
+ context_offset (FRegs[8]),
+ context_offset (FRegs[9]),
+ context_offset (FRegs[10]),
+ context_offset (FRegs[11]),
+ context_offset (FRegs[12]),
+ context_offset (FRegs[13]),
+ context_offset (FRegs[14]),
+ context_offset (FRegs[15]),
+ context_offset (xFRegs[0]),
+ context_offset (xFRegs[1]),
+ context_offset (xFRegs[2]),
+ context_offset (xFRegs[3]),
+ context_offset (xFRegs[4]),
+ context_offset (xFRegs[5]),
+ context_offset (xFRegs[6]),
+ context_offset (xFRegs[7]),
+ context_offset (xFRegs[8]),
+ context_offset (xFRegs[9]),
+ context_offset (xFRegs[10]),
+ context_offset (xFRegs[11]),
+ context_offset (xFRegs[12]),
+ context_offset (xFRegs[13]),
+ context_offset (xFRegs[14]),
+ context_offset (xFRegs[15]),
+#elif defined(MIPS)
+ context_offset (IntZero),
+ context_offset (IntAt),
+ context_offset (IntV0),
+ context_offset (IntV1),
+ context_offset (IntA0),
+ context_offset (IntA1),
+ context_offset (IntA2),
+ context_offset (IntA3),
+ context_offset (IntT0),
+ context_offset (IntT1),
+ context_offset (IntT2),
+ context_offset (IntT3),
+ context_offset (IntT4),
+ context_offset (IntT5),
+ context_offset (IntT6),
+ context_offset (IntT7),
+ context_offset (IntS0),
+ context_offset (IntS1),
+ context_offset (IntS2),
+ context_offset (IntS3),
+ context_offset (IntS4),
+ context_offset (IntS5),
+ context_offset (IntS6),
+ context_offset (IntS7),
+ context_offset (IntT8),
+ context_offset (IntT9),
+ context_offset (IntK0),
+ context_offset (IntK1),
+ context_offset (IntGp),
+ context_offset (IntSp),
+ context_offset (IntS8),
+ context_offset (IntRa),
+ context_offset (Psr),
+ context_offset (IntLo),
+ context_offset (IntHi),
+ -1, /* bad */
+ -1, /* cause */
+ context_offset (Fir),
+ context_offset (FltF0),
+ context_offset (FltF1),
+ context_offset (FltF2),
+ context_offset (FltF3),
+ context_offset (FltF4),
+ context_offset (FltF5),
+ context_offset (FltF6),
+ context_offset (FltF7),
+ context_offset (FltF8),
+ context_offset (FltF9),
+ context_offset (FltF10),
+ context_offset (FltF11),
+ context_offset (FltF12),
+ context_offset (FltF13),
+ context_offset (FltF14),
+ context_offset (FltF15),
+ context_offset (FltF16),
+ context_offset (FltF17),
+ context_offset (FltF18),
+ context_offset (FltF19),
+ context_offset (FltF20),
+ context_offset (FltF21),
+ context_offset (FltF22),
+ context_offset (FltF23),
+ context_offset (FltF24),
+ context_offset (FltF25),
+ context_offset (FltF26),
+ context_offset (FltF27),
+ context_offset (FltF28),
+ context_offset (FltF29),
+ context_offset (FltF30),
+ context_offset (FltF31),
+ context_offset (Fsr),
+ context_offset (Fir),
+ -1, /* fp */
+#elif defined(ARM)
+ context_offset (R0),
+ context_offset (R1),
+ context_offset (R2),
+ context_offset (R3),
+ context_offset (R4),
+ context_offset (R5),
+ context_offset (R6),
+ context_offset (R7),
+ context_offset (R8),
+ context_offset (R9),
+ context_offset (R10),
+ context_offset (R11),
+ context_offset (R12),
+ context_offset (Sp),
+ context_offset (Lr),
+ context_offset (Pc),
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ context_offset (Psr),
+#endif
+ -1
+};
+
+/* Return a pointer into a CONTEXT field indexed by gdb register number.
+ Return a pointer to an address pointing to zero if there is no
+ corresponding CONTEXT field for the given register number.
+ */
+static ULONG *
+regptr (LPCONTEXT c, int r)
+{
+ static ULONG zero = 0;
+ ULONG *p;
+ if (mappings[r] < 0)
+ p = &zero;
+ else
+ p = (ULONG *) (((char *) c) + mappings[r]);
+ return p;
+}
+
+/******************** Beginning of stub interface ********************/
+
+/* Stub interface description:
+
+ The Windows CE stub implements a crude RPC. The hand-held device
+ connects to gdb using port 7000. gdb and the stub then communicate
+ using packets where:
+
+ byte 0: command id (e.g. Create Process)
+
+ byte 1-4: DWORD
+
+ byte 1-2: WORD
+
+ byte 1-2: length
+ byte 3-n: arbitrary memory.
+
+ The interface is deterministic, i.e., if the stub expects a DWORD then
+ the gdb server should send a DWORD.
+ */
+
+/* Note: In the functions below, the `huh' parameter is a string passed from the
+ function containing a descriptive string concerning the current operation.
+ This is used for error reporting.
+
+ The 'what' parameter is a command id as found in wince-stub.h.
+
+ Hopefully, the rest of the parameters are self-explanatory.
+ */
+
+static int s; /* communication socket */
+
+/* v-style interface for handling varying argyment list error messages.
+ Displays the error message in a dialog box and exits when user clicks
+ on OK. */
+static void
+vstub_error (LPCSTR fmt, va_list * args)
+{
+ char buf[4096];
+ vsprintf (buf, fmt, args);
+ s = -1;
+ error ("%s", buf);
+}
+
+/* The standard way to display an error message and exit. */
+static void
+stub_error (LPCSTR fmt,...)
+{
+ va_list args;
+ va_start (args, fmt);
+ vstub_error (fmt, args);
+}
+
+/* Standard "oh well" can't communicate error. Someday this might attempt
+ synchronization. */
+static void
+attempt_resync (LPCSTR huh, int s)
+{
+ stub_error ("lost synchronization with target attempting %s", huh);
+}
+
+/* Read arbitrary stuff from a socket. */
+static int
+sockread (LPCSTR huh, int s, void *str, size_t n)
+{
+ for (;;)
+ {
+ if (recv (s, str, n, 0) == n)
+ return n;
+ attempt_resync (huh, s);
+ }
+}
+
+/* Write arbitrary stuff to a socket. */
+static int
+sockwrite (LPCSTR huh, const void *str, size_t n)
+{
+ for (;;)
+ {
+ if (send (s, str, n, 0) == n)
+ return n;
+ attempt_resync (huh, s);
+ }
+}
+
+/* Output an id/dword to the host */
+static void
+putdword (LPCSTR huh, gdb_wince_id what, DWORD n)
+{
+ if (sockwrite (huh, &what, sizeof (what)) != sizeof (what))
+ stub_error ("error writing record id to host for %s", huh);
+ if (sockwrite (huh, &n, sizeof (n)) != sizeof (n))
+ stub_error ("error writing %s to host.", huh);
+}
+
+/* Output an id/word to the host */
+static void
+putword (LPCSTR huh, gdb_wince_id what, WORD n)
+{
+ if (sockwrite (huh, &what, sizeof (what)) != sizeof (what))
+ stub_error ("error writing record id to host for %s", huh);
+ if (sockwrite (huh, &n, sizeof (n)) != sizeof (n))
+ stub_error ("error writing %s host.", huh);
+}
+
+/* Convenience define for outputting a "gdb_wince_len" type. */
+#define putlen(huh, what, n) putword((huh), (what), (gdb_wince_len) (n))
+
+/* Put an arbitrary block of memory to the gdb host. This comes in
+ two chunks an id/dword representing the length and the stream of memory
+ itself. */
+static void
+putmemory (LPCSTR huh, gdb_wince_id what, const void *mem, gdb_wince_len len)
+{
+ putlen (huh, what, len);
+ if (((short) len > 0) && sockwrite (huh, mem, len) != len)
+ stub_error ("error writing %s to host.", huh);
+}
+
+/* Output the result of an operation to the host. If res != 0, sends a block of
+ memory starting at mem of len bytes. If res == 0, sends -GetLastError () and
+ avoids sending the mem. */
+static DWORD
+getdword (LPCSTR huh, gdb_wince_id what_this)
+{
+ DWORD n;
+ gdb_wince_id what;
+ do
+ if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
+ stub_error ("error getting record type from host - %s.", huh);
+ while (what_this != what);
+
+ if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
+ stub_error ("error getting %s from host.", huh);
+
+ return n;
+}
+
+/* Get a an ID (possibly) and a WORD from the host gdb.
+ Don't bother with the id if the main loop has already
+ read it. */
+static WORD
+getword (LPCSTR huh, gdb_wince_id what_this)
+{
+ WORD n;
+ gdb_wince_id what;
+ do
+ if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
+ stub_error ("error getting record type from host - %s.", huh);
+ while (what_this != what);
+
+ if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
+ stub_error ("error getting %s from host.", huh);
+
+ return n;
+}
+
+/* Handy defines for getting/putting various types of values. */
+#define gethandle(huh, what) (HANDLE) getdword ((huh), (what))
+#define getpvoid(huh, what) (LPVOID) getdword ((huh), (what))
+#define getlen(huh, what) (gdb_wince_len) getword ((huh), (what))
+#define puthandle(huh, what, h) putdword ((huh), (what), (DWORD) (h))
+#define putpvoid(huh, what, p) putdword ((huh), (what), (DWORD) (p))
+
+/* Retrieve the result of an operation from the stub. If nbytes < 0) then nbytes
+ is actually an error and nothing else follows. Use SetLastError to remember this.
+ if nbytes > 0, retrieve a block of *nbytes into buf.
+ */
+int
+getresult (LPCSTR huh, gdb_wince_id what, LPVOID buf, gdb_wince_len * nbytes)
+{
+ gdb_wince_len dummy;
+ if (nbytes == NULL)
+ nbytes = &dummy;
+
+ *nbytes = getlen (huh, what);
+
+ if ((short) *nbytes < 0)
+ {
+ SetLastError (-(short) *nbytes);
+ return 0;
+ }
+
+ if ((gdb_wince_len) sockread (huh, s, buf, *nbytes) != *nbytes)
+ stub_error ("couldn't read information from wince stub - %s", huh);
+
+ return 1;
+}
+
+/* Convert "narrow" string to "wide". Manipulates a buffer ring of 8
+ buffers which hold the translated string. This is an arbitrary limit
+ but it is approximately double the current needs of this module.
+ */
+LPWSTR
+towide (const char *s, gdb_wince_len * out_len)
+{
+ static int n = -1;
+ static LPWSTR outs[8] =
+ {NULL /*, NULL, etc. */ };
+ gdb_wince_len dummy;
+
+ if (!out_len)
+ out_len = &dummy;
+
+ /* First determine the length required to hold the converted string. */
+ *out_len = sizeof (WCHAR) * MultiByteToWideChar (CP_ACP, 0, s, -1, NULL, 0);
+ if (!*out_len)
+ return NULL; /* The conversion failed */
+
+ if (++n >= (sizeof (outs) / sizeof (outs[0])))
+ n = 0; /* wrap */
+
+ /* Allocate space for the converted string, reusing any previously allocated
+ space, if applicable. Note that if outs[n] is NULL, xrealloc will act as
+ a malloc (under cygwin, at least).
+ */
+ outs[n] = (LPWSTR) xrealloc (outs[n], *out_len);
+ memset (outs[n], 0, *out_len);
+ (void) MultiByteToWideChar (CP_ACP, 0, s, -1, outs[n], *out_len);
+ return outs[n];
+}
+
+/******************** Emulation routines start here. ********************
+
+ The functions below are modelled after their Win32 counterparts. They are named
+ similarly to Win32 and take exactly the same arguments except where otherwise noted.
+ They communicate with the stub on the hand-held device by sending their arguments
+ over the socket and waiting for results from the socket.
+
+ There is one universal change. In cases where a length is expected to be returned
+ in a DWORD, we use a gdb_wince_len type instead. Currently this is an unsigned short
+ which is smaller than the standard Win32 DWORD. This is done to minimize unnecessary
+ traffic since the connection to Windows CE can be slow. To change this, modify the
+ typedef in wince-stub.h and change the putlen/getlen macros in this file and in
+ the stub.
+*/
+
+static int
+create_process (LPSTR exec_file, LPSTR args, DWORD flags, PROCESS_INFORMATION * pi)
+{
+ gdb_wince_len len;
+ LPWSTR buf;
+
+ buf = towide (exec_file, &len);
+ putmemory ("CreateProcess exec_file", GDB_CREATEPROCESS, buf, len);
+ buf = towide (args, &len);
+ putmemory ("CreateProcess args", GDB_CREATEPROCESS, buf, len);
+ putdword ("CreateProcess flags", GDB_CREATEPROCESS, flags);
+ return getresult ("CreateProcess result", GDB_CREATEPROCESS, pi, NULL);
+}
+
+/* Emulate TerminateProcess. Don't bother with the second argument since CE
+ ignores it.
+ */
+static int
+terminate_process (HANDLE h)
+{
+ gdb_wince_result res;
+ if (s < 0)
+ return 1;
+ puthandle ("TerminateProcess handle", GDB_TERMINATEPROCESS, h);
+ return getresult ("TerminateProcess result", GDB_TERMINATEPROCESS, &res, NULL);
+}
+
+static int
+wait_for_debug_event (DEBUG_EVENT * ev, DWORD ms)
+{
+ if (s < 0)
+ return 1;
+ putdword ("WaitForDebugEvent ms", GDB_WAITFORDEBUGEVENT, ms);
+ return getresult ("WaitForDebugEvent event", GDB_WAITFORDEBUGEVENT, ev, NULL);
+}
+
+static int
+get_thread_context (HANDLE h, CONTEXT * c)
+{
+ if (s < 0)
+ return 1;
+ puthandle ("GetThreadContext handle", GDB_GETTHREADCONTEXT, h);
+ putdword ("GetThreadContext flags", GDB_GETTHREADCONTEXT, c->ContextFlags);
+ return getresult ("GetThreadContext context", GDB_GETTHREADCONTEXT, c, NULL);
+}
+
+static int
+set_thread_context (HANDLE h, CONTEXT * c)
+{
+ gdb_wince_result res;
+ if (s < 0)
+ return 1;
+ puthandle ("SetThreadContext handle", GDB_SETTHREADCONTEXT, h);
+ putmemory ("SetThreadContext context", GDB_SETTHREADCONTEXT, c, sizeof (*c));
+ return getresult ("SetThreadContext context", GDB_SETTHREADCONTEXT, &res, NULL);
+}
+
+static int
+read_process_memory (HANDLE h, LPCVOID where, LPVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
+{
+ if (s < 0)
+ return 1;
+ puthandle ("ReadProcessMemory handle", GDB_READPROCESSMEMORY, h);
+ putpvoid ("ReadProcessMemory location", GDB_READPROCESSMEMORY, where);
+ putlen ("ReadProcessMemory size", GDB_READPROCESSMEMORY, len);
+
+ return getresult ("ReadProcessMemory buf", GDB_READPROCESSMEMORY, buf, nbytes);
+}
+
+static int
+write_process_memory (HANDLE h, LPCVOID where, LPCVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
+{
+ if (s < 0)
+ return 1;
+ puthandle ("WriteProcessMemory handle", GDB_WRITEPROCESSMEMORY, h);
+ putpvoid ("WriteProcessMemory location", GDB_WRITEPROCESSMEMORY, where);
+ putmemory ("WriteProcProcessMemory buf", GDB_WRITEPROCESSMEMORY, buf, len);
+
+ return getresult ("WriteProcessMemory result", GDB_WRITEPROCESSMEMORY, nbytes, NULL);
+}
+
+static int
+remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ gdb_wince_len nbytes;
+ if (!read_process_memory (current_process_handle, (LPCVOID) memaddr,
+ (LPVOID) myaddr, len, &nbytes))
+ return -1;
+ return nbytes;
+}
+
+static int
+remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ gdb_wince_len nbytes;
+ if (!write_process_memory (current_process_handle, (LPCVOID) memaddr,
+ (LPCVOID) myaddr, len, &nbytes))
+ return -1;
+ return nbytes;
+}
+
+/* This is not a standard Win32 function. It instructs the stub to return TRUE
+ if the thread referenced by HANDLE h is alive.
+ */
+static int
+thread_alive (HANDLE h)
+{
+ gdb_wince_result res;
+ if (s < 0)
+ return 1;
+ puthandle ("ThreadAlive handle", GDB_THREADALIVE, h);
+ return getresult ("ThreadAlive result", GDB_THREADALIVE, &res, NULL);
+}
+
+static int
+suspend_thread (HANDLE h)
+{
+ if (s < 0)
+ return 1;
+ puthandle ("SuspendThread handle", GDB_SUSPENDTHREAD, h);
+ return (int) getdword ("SuspendThread result", GDB_SUSPENDTHREAD);
+}
+
+static int
+resume_thread (HANDLE h)
+{
+ if (s < 0)
+ return 1;
+ puthandle ("ResumeThread handle", GDB_RESUMETHREAD, h);
+ return (int) getdword ("SuspendThread result", GDB_RESUMETHREAD);
+}
+
+static int
+continue_debug_event (DWORD pid, DWORD tid, DWORD status)
+{
+ gdb_wince_result res;
+ if (s < 0)
+ return 0;
+ putdword ("ContinueDebugEvent pid", GDB_CONTINUEDEBUGEVENT, pid);
+ putdword ("ContinueDebugEvent tid", GDB_CONTINUEDEBUGEVENT, tid);
+ putdword ("ContinueDebugEvent status", GDB_CONTINUEDEBUGEVENT, status);
+ return getresult ("ContinueDebugEvent result", GDB_CONTINUEDEBUGEVENT, &res, NULL);
+}
+
+static int
+close_handle (HANDLE h)
+{
+ gdb_wince_result res;
+ if (s < 0)
+ return 1;
+ puthandle ("CloseHandle handle", GDB_CLOSEHANDLE, h);
+ return (int) getresult ("CloseHandle result", GDB_CLOSEHANDLE, &res, NULL);
+}
+
+/* This is not a standard Win32 interface. This function tells the stub
+ to terminate.
+ */
+static void
+stop_stub (void)
+{
+ if (s < 0)
+ return;
+ (void) putdword ("Stopping gdb stub", GDB_STOPSTUB, 0);
+ s = -1;
+}
+
+/******************** End of emulation routines. ********************/
+/******************** End of stub interface ********************/
+
+#define check_for_step(a, x) (x)
+
+#ifdef MIPS
+static void
+undoSStep (thread_info * th)
+{
+ if (th->stepped)
+ {
+ memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
+ th->stepped = 0;
+ }
+}
+
+void
+wince_software_single_step (enum target_signal ignore,
+ int insert_breakpoints_p)
+{
+ unsigned long pc;
+ thread_info *th = current_thread; /* Info on currently selected thread */
+ CORE_ADDR mips_next_pc (CORE_ADDR pc);
+
+ if (!insert_breakpoints_p)
+ {
+ undoSStep (th);
+ return;
+ }
+
+ th->stepped = 1;
+ pc = read_register (PC_REGNUM);
+ th->step_pc = mips_next_pc (pc);
+ th->step_prev = 0;
+ memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
+ return;
+}
+#elif SHx
+/* Hitachi SH architecture instruction encoding masks */
+
+#define COND_BR_MASK 0xff00
+#define UCOND_DBR_MASK 0xe000
+#define UCOND_RBR_MASK 0xf0df
+#define TRAPA_MASK 0xff00
+
+#define COND_DISP 0x00ff
+#define UCOND_DISP 0x0fff
+#define UCOND_REG 0x0f00
+
+/* Hitachi SH instruction opcodes */
+
+#define BF_INSTR 0x8b00
+#define BT_INSTR 0x8900
+#define BRA_INSTR 0xa000
+#define BSR_INSTR 0xb000
+#define JMP_INSTR 0x402b
+#define JSR_INSTR 0x400b
+#define RTS_INSTR 0x000b
+#define RTE_INSTR 0x002b
+#define TRAPA_INSTR 0xc300
+#define SSTEP_INSTR 0xc3ff
+
+
+#define T_BIT_MASK 0x0001
+
+static CORE_ADDR
+sh_get_next_pc (CONTEXT *c)
+{
+ short *instrMem;
+ int displacement;
+ int reg;
+ unsigned short opcode;
+
+ instrMem = (short *) c->Fir;
+
+ opcode = read_memory_integer ((CORE_ADDR) c->Fir, sizeof (opcode));
+
+ if ((opcode & COND_BR_MASK) == BT_INSTR)
+ {
+ if (c->Psr & T_BIT_MASK)
+ {
+ displacement = (opcode & COND_DISP) << 1;
+ if (displacement & 0x80)
+ displacement |= 0xffffff00;
+ /*
+ * Remember PC points to second instr.
+ * after PC of branch ... so add 4
+ */
+ instrMem = (short *) (c->Fir + displacement + 4);
+ }
+ else
+ instrMem += 1;
+ }
+ else if ((opcode & COND_BR_MASK) == BF_INSTR)
+ {
+ if (c->Psr & T_BIT_MASK)
+ instrMem += 1;
+ else
+ {
+ displacement = (opcode & COND_DISP) << 1;
+ if (displacement & 0x80)
+ displacement |= 0xffffff00;
+ /*
+ * Remember PC points to second instr.
+ * after PC of branch ... so add 4
+ */
+ instrMem = (short *) (c->Fir + displacement + 4);
+ }
+ }
+ else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
+ {
+ displacement = (opcode & UCOND_DISP) << 1;
+ if (displacement & 0x0800)
+ displacement |= 0xfffff000;
+
+ /*
+ * Remember PC points to second instr.
+ * after PC of branch ... so add 4
+ */
+ instrMem = (short *) (c->Fir + displacement + 4);
+ }
+ else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
+ {
+ reg = (char) ((opcode & UCOND_REG) >> 8);
+
+ instrMem = (short *) *regptr (c, reg);
+ }
+ else if (opcode == RTS_INSTR)
+ instrMem = (short *) c->PR;
+ else if (opcode == RTE_INSTR)
+ instrMem = (short *) *regptr (c, 15);
+ else if ((opcode & TRAPA_MASK) == TRAPA_INSTR)
+ instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2);
+ else
+ instrMem += 1;
+
+ return (CORE_ADDR) instrMem;
+}
+/* Single step (in a painstaking fashion) by inspecting the current
+ instruction and setting a breakpoint on the "next" instruction
+ which would be executed. This code hails from sh-stub.c.
+ */
+static void
+undoSStep (thread_info * th)
+{
+ if (th->stepped)
+ {
+ memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
+ th->stepped = 0;
+ }
+ return;
+}
+
+/* Single step (in a painstaking fashion) by inspecting the current
+ instruction and setting a breakpoint on the "next" instruction
+ which would be executed. This code hails from sh-stub.c.
+ */
+void
+wince_software_single_step (enum target_signal ignore,
+ int insert_breakpoints_p)
+{
+ thread_info *th = current_thread; /* Info on currently selected thread */
+
+ if (!insert_breakpoints_p)
+ {
+ undoSStep (th);
+ return;
+ }
+
+ th->stepped = 1;
+ th->step_pc = sh_get_next_pc (&th->context);
+ th->step_prev = 0;
+ memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
+ return;
+}
+#elif defined (ARM)
+#undef check_for_step
+
+static enum target_signal
+check_for_step (DEBUG_EVENT *ev, enum target_signal x)
+{
+ thread_info *th = thread_rec (ev->dwThreadId, 1);
+
+ if (th->stepped &&
+ th->step_pc == (CORE_ADDR) ev->u.Exception.ExceptionRecord.ExceptionAddress)
+ return TARGET_SIGNAL_TRAP;
+ else
+ return x;
+}
+
+/* Single step (in a painstaking fashion) by inspecting the current
+ instruction and setting a breakpoint on the "next" instruction
+ which would be executed. This code hails from sh-stub.c.
+ */
+static void
+undoSStep (thread_info * th)
+{
+ if (th->stepped)
+ {
+ memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
+ th->stepped = 0;
+ }
+}
+
+void
+wince_software_single_step (enum target_signal ignore,
+ int insert_breakpoints_p)
+{
+ unsigned long pc;
+ thread_info *th = current_thread; /* Info on currently selected thread */
+ CORE_ADDR mips_next_pc (CORE_ADDR pc);
+
+ if (!insert_breakpoints_p)
+ {
+ undoSStep (th);
+ return;
+ }
+
+ th->stepped = 1;
+ pc = read_register (PC_REGNUM);
+ th->step_pc = arm_get_next_pc (pc);
+ th->step_prev = 0;
+ memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
+ return;
+}
+#endif
+
+/* Find a thread record given a thread id.
+ If get_context then also retrieve the context for this
+ thread. */
+static thread_info *
+thread_rec (DWORD id, int get_context)
+{
+ thread_info *th;
+
+ for (th = &thread_head; (th = th->next) != NULL;)
+ if (th->id == id)
+ {
+ if (!th->suspend_count && get_context)
+ {
+ if (get_context > 0 && th != this_thread)
+ th->suspend_count = suspend_thread (th->h) + 1;
+ else if (get_context < 0)
+ th->suspend_count = -1;
+
+ th->context.ContextFlags = CONTEXT_DEBUGGER;
+ get_thread_context (th->h, &th->context);
+ }
+ return th;
+ }
+
+ return NULL;
+}
+
+/* Add a thread to the thread list */
+static thread_info *
+child_add_thread (DWORD id, HANDLE h)
+{
+ thread_info *th;
+
+ if ((th = thread_rec (id, FALSE)))
+ return th;
+
+ th = (thread_info *) xmalloc (sizeof (*th));
+ memset (th, 0, sizeof (*th));
+ th->id = id;
+ th->h = h;
+ th->next = thread_head.next;
+ thread_head.next = th;
+ add_thread (id);
+ return th;
+}
+
+/* Clear out any old thread list and reintialize it to a
+ pristine state. */
+static void
+child_init_thread_list (void)
+{
+ thread_info *th = &thread_head;
+
+ DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
+ init_thread_list ();
+ while (th->next != NULL)
+ {
+ thread_info *here = th->next;
+ th->next = here->next;
+ (void) close_handle (here->h);
+ xfree (here);
+ }
+}
+
+/* Delete a thread from the list of threads */
+static void
+child_delete_thread (DWORD id)
+{
+ thread_info *th;
+
+ if (info_verbose)
+ printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
+ delete_thread (id);
+
+ for (th = &thread_head;
+ th->next != NULL && th->next->id != id;
+ th = th->next)
+ continue;
+
+ if (th->next != NULL)
+ {
+ thread_info *here = th->next;
+ th->next = here->next;
+ close_handle (here->h);
+ xfree (here);
+ }
+}
+
+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
+do_child_fetch_inferior_registers (int r)
+{
+ if (r >= 0)
+ {
+ supply_register (r, (char *) regptr (&current_thread->context, r));
+ }
+ else
+ {
+ for (r = 0; r < NUM_REGS; r++)
+ do_child_fetch_inferior_registers (r);
+ }
+}
+
+static void
+child_fetch_inferior_registers (int r)
+{
+ current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
+ do_child_fetch_inferior_registers (r);
+}
+
+static void
+do_child_store_inferior_registers (int r)
+{
+ if (r >= 0)
+ read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
+ else
+ {
+ for (r = 0; r < NUM_REGS; r++)
+ do_child_store_inferior_registers (r);
+ }
+}
+
+/* Store a new register value into the current thread context */
+static void
+child_store_inferior_registers (int r)
+{
+ current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
+ do_child_store_inferior_registers (r);
+}
+
+/* Wait for child to do something. Return pid of child, or -1 in case
+ of error; store status through argument pointer OURSTATUS. */
+
+static int
+handle_load_dll (void *dummy)
+{
+ LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
+ char dll_buf[MAX_PATH + 1];
+ char *p, *bufp, *imgp, *dll_name, *dll_basename;
+ int len;
+
+ dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
+ if (!event->lpImageName)
+ return 1;
+
+ len = 0;
+ for (bufp = dll_buf, imgp = event->lpImageName;
+ bufp < dll_buf + sizeof (dll_buf);
+ bufp += 16, imgp += 16)
+ {
+ gdb_wince_len nbytes = 0;
+ (void) read_process_memory (current_process_handle,
+ imgp, bufp, 16, &nbytes);
+
+ if (!nbytes && bufp == dll_buf)
+ return 1; /* couldn't read it */
+ for (p = bufp; p < bufp + nbytes; p++)
+ {
+ len++;
+ if (*p == '\0')
+ goto out;
+ if (event->fUnicode)
+ p++;
+ }
+ if (!nbytes)
+ break;
+ }
+
+out:
+ if (!len)
+ return 1;
+#if 0
+ dll_buf[len] = '\0';
+#endif
+ dll_name = alloca (len);
+
+ if (!dll_name)
+ return 1;
+
+ if (!event->fUnicode)
+ memcpy (dll_name, dll_buf, len);
+ else
+ WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) dll_buf, len,
+ dll_name, len, 0, 0);
+
+ while ((p = strchr (dll_name, '\\')))
+ *p = '/';
+
+ /* FIXME!! It would be nice to define one symbol which pointed to the
+ front of the dll if we can't find any symbols. */
+
+ if (!(dll_basename = strrchr (dll_name, '/')))
+ dll_basename = dll_name;
+ else
+ dll_basename++;
+
+ /* The symbols in a dll are offset by 0x1000, which is the
+ the offset from 0 of the first byte in an image - because
+ of the file header and the section alignment.
+
+ FIXME: Is this the real reason that we need the 0x1000 ? */
+
+ printf_unfiltered ("%x:%s", event->lpBaseOfDll, dll_name);
+ printf_unfiltered ("\n");
+
+ return 1;
+}
+
+/* Handle DEBUG_STRING output from child process. */
+static void
+handle_output_debug_string (struct target_waitstatus *ourstatus)
+{
+ char p[256];
+ char s[255];
+ char *q;
+ gdb_wince_len nbytes_read;
+ gdb_wince_len nbytes = current_event.u.DebugString.nDebugStringLength;
+
+ if (nbytes > 255)
+ nbytes = 255;
+
+ memset (p, 0, sizeof (p));
+ if (!read_process_memory (current_process_handle,
+ current_event.u.DebugString.lpDebugStringData,
+ &p, nbytes, &nbytes_read)
+ || !*p)
+ return;
+
+ memset (s, 0, sizeof (s));
+ WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) p, (int) nbytes_read, s,
+ sizeof (s) - 1, NULL, NULL);
+ q = strchr (s, '\n');
+ if (q != NULL)
+ {
+ *q = '\0';
+ if (*--q = '\r')
+ *q = '\0';
+ }
+
+ warning (s);
+
+ return;
+}
+
+/* Handle target exceptions. */
+static int
+handle_exception (struct target_waitstatus *ourstatus)
+{
+#if 0
+ if (current_event.u.Exception.dwFirstChance)
+ return 0;
+#endif
+
+ ourstatus->kind = TARGET_WAITKIND_STOPPED;
+
+ switch (current_event.u.Exception.ExceptionRecord.ExceptionCode)
+ {
+ case EXCEPTION_ACCESS_VIOLATION:
+ DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
+ (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
+ ourstatus->value.sig = TARGET_SIGNAL_SEGV;
+ break;
+ case STATUS_STACK_OVERFLOW:
+ DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
+ (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
+ ourstatus->value.sig = TARGET_SIGNAL_SEGV;
+ break;
+ case EXCEPTION_BREAKPOINT:
+ DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
+ (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
+ ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+ break;
+ case DBG_CONTROL_C:
+ DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
+ (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
+ ourstatus->value.sig = TARGET_SIGNAL_INT;
+ /* User typed CTRL-C. Continue with this status */
+ last_sig = SIGINT; /* FIXME - should check pass state */
+ break;
+ case EXCEPTION_SINGLE_STEP:
+ DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
+ (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
+ ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+ break;
+ case EXCEPTION_ILLEGAL_INSTRUCTION:
+ DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08x\n",
+ current_event.u.Exception.ExceptionRecord.ExceptionAddress));
+ ourstatus->value.sig = check_for_step (&current_event, TARGET_SIGNAL_ILL);
+ break;
+ default:
+ /* This may be a structured exception handling exception. In
+ that case, we want to let the program try to handle it, and
+ only break if we see the exception a second time. */
+
+ printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
+ current_event.u.Exception.ExceptionRecord.ExceptionCode,
+ current_event.u.Exception.ExceptionRecord.ExceptionAddress);
+ ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
+ break;
+ }
+ exception_count++;
+ return 1;
+}
+
+/* Resume all artificially suspended threads if we are continuing
+ execution */
+static BOOL
+child_continue (DWORD continue_status, int id)
+{
+ int i;
+ thread_info *th;
+ BOOL res;
+
+ DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
+ (unsigned) current_event.dwProcessId, (unsigned) current_event.dwThreadId));
+ res = continue_debug_event (current_event.dwProcessId,
+ current_event.dwThreadId,
+ continue_status);
+ if (res)
+ for (th = &thread_head; (th = th->next) != NULL;)
+ if (((id == -1) || (id == th->id)) && th->suspend_count)
+ {
+ for (i = 0; i < th->suspend_count; i++)
+ (void) resume_thread (th->h);
+ th->suspend_count = 0;
+ }
+
+ return res;
+}
+
+/* Get the next event from the child. Return 1 if the event requires
+ handling by WFI (or whatever).
+ */
+static int
+get_child_debug_event (int pid, struct target_waitstatus *ourstatus,
+ DWORD target_event_code, int *retval)
+{
+ int breakout = 0;
+ BOOL debug_event;
+ DWORD continue_status, event_code;
+ thread_info *th = NULL;
+ static thread_info dummy_thread_info;
+
+ if (!(debug_event = wait_for_debug_event (&current_event, 1000)))
+ {
+ *retval = 0;
+ goto out;
+ }
+
+ event_count++;
+ continue_status = DBG_CONTINUE;
+ *retval = 0;
+
+ event_code = current_event.dwDebugEventCode;
+ breakout = event_code == target_event_code;
+
+ switch (event_code)
+ {
+ case CREATE_THREAD_DEBUG_EVENT:
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "CREATE_THREAD_DEBUG_EVENT"));
+ /* Record the existence of this thread */
+ th = child_add_thread (current_event.dwThreadId,
+ current_event.u.CreateThread.hThread);
+ if (info_verbose)
+ printf_unfiltered ("[New %s]\n",
+ target_pid_to_str (current_event.dwThreadId));
+ break;
+
+ case EXIT_THREAD_DEBUG_EVENT:
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "EXIT_THREAD_DEBUG_EVENT"));
+ child_delete_thread (current_event.dwThreadId);
+ th = &dummy_thread_info;
+ break;
+
+ case CREATE_PROCESS_DEBUG_EVENT:
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "CREATE_PROCESS_DEBUG_EVENT"));
+ current_process_handle = current_event.u.CreateProcessInfo.hProcess;
+
+ main_thread_id = current_event.dwThreadId;
+ inferior_ptid = pid_to_ptid (main_thread_id);
+ /* Add the main thread */
+ th = child_add_thread (PIDGET (inferior_ptid),
+ current_event.u.CreateProcessInfo.hThread);
+ break;
+
+ case EXIT_PROCESS_DEBUG_EVENT:
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "EXIT_PROCESS_DEBUG_EVENT"));
+ ourstatus->kind = TARGET_WAITKIND_EXITED;
+ ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
+ close_handle (current_process_handle);
+ *retval = current_event.dwProcessId;
+ breakout = 1;
+ break;
+
+ case LOAD_DLL_DEBUG_EVENT:
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "LOAD_DLL_DEBUG_EVENT"));
+ catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
+ registers_changed (); /* mark all regs invalid */
+ break;
+
+ case UNLOAD_DLL_DEBUG_EVENT:
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "UNLOAD_DLL_DEBUG_EVENT"));
+ break; /* FIXME: don't know what to do here */
+
+ case EXCEPTION_DEBUG_EVENT:
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "EXCEPTION_DEBUG_EVENT"));
+ if (handle_exception (ourstatus))
+ *retval = current_event.dwThreadId;
+ else
+ {
+ continue_status = DBG_EXCEPTION_NOT_HANDLED;
+ breakout = 0;
+ }
+ break;
+
+ case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ (unsigned) current_event.dwProcessId,
+ (unsigned) current_event.dwThreadId,
+ "OUTPUT_DEBUG_STRING_EVENT"));
+ handle_output_debug_string ( ourstatus);
+ break;
+ default:
+ printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
+ current_event.dwProcessId,
+ current_event.dwThreadId);
+ printf_unfiltered (" unknown event code %d\n",
+ current_event.dwDebugEventCode);
+ break;
+ }
+
+ if (breakout)
+ this_thread = current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
+ else
+ CHECK (child_continue (continue_status, -1));
+
+out:
+ return breakout;
+}
+
+/* Wait for interesting events to occur in the target process. */
+static ptid_t
+child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+{
+ DWORD event_code;
+ int retval;
+ int pid = PIDGET (ptid);
+
+ /* 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->h. 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)
+ if (get_child_debug_event (pid, ourstatus, EXCEPTION_DEBUG_EVENT, &retval))
+ return pid_to_ptid (retval);
+ else
+ {
+ int detach = 0;
+
+ if (ui_loop_hook != NULL)
+ detach = ui_loop_hook (0);
+
+ if (detach)
+ child_kill_inferior ();
+ }
+}
+
+/* Print status information about what we're accessing. */
+
+static void
+child_files_info (struct target_ops *ignore)
+{
+ printf_unfiltered ("\tUsing the running image of child %s.\n",
+ target_pid_to_str (inferior_ptid));
+}
+
+/* ARGSUSED */
+static void
+child_open (char *arg, int from_tty)
+{
+ error ("Use the \"run\" command to start a child process.");
+}
+
+#define FACTOR (0x19db1ded53ea710LL)
+#define NSPERSEC 10000000
+
+/* Convert a Win32 time to "UNIX" format. */
+long
+to_time_t (FILETIME * ptr)
+{
+ /* A file time is the number of 100ns since jan 1 1601
+ stuffed into two long words.
+ A time_t is the number of seconds since jan 1 1970. */
+
+ long rem;
+ long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned) ptr->dwLowDateTime);
+ x -= FACTOR; /* number of 100ns between 1601 and 1970 */
+ rem = x % ((long long) NSPERSEC);
+ rem += (NSPERSEC / 2);
+ x /= (long long) NSPERSEC; /* number of 100ns in a second */
+ x += (long long) (rem / NSPERSEC);
+ return x;
+}
+
+/* Upload a file to the remote device depending on the user's
+ 'set remoteupload' specification. */
+char *
+upload_to_device (const char *to, const char *from)
+{
+ HANDLE h;
+ const char *dir = remote_directory ?: "\\gdb";
+ int len;
+ static char *remotefile = NULL;
+ LPWSTR wstr;
+ char *p;
+ DWORD err;
+ const char *in_to = to;
+ FILETIME crtime, actime, wrtime;
+ time_t utime;
+ struct stat st;
+ int fd;
+
+ /* Look for a path separator and only use trailing part. */
+ while ((p = strpbrk (to, "/\\")) != NULL)
+ to = p + 1;
+
+ if (!*to)
+ error ("no filename found to upload - %s.", in_to);
+
+ len = strlen (dir) + strlen (to) + 2;
+ remotefile = (char *) xrealloc (remotefile, len);
+ strcpy (remotefile, dir);
+ strcat (remotefile, "\\");
+ strcat (remotefile, to);
+
+ if (upload_when == UPLOAD_NEVER)
+ return remotefile; /* Don't bother uploading. */
+
+ /* Open the source. */
+ if ((fd = openp (getenv ("PATH"), TRUE, (char *) from, O_RDONLY, 0, NULL)) < 0)
+ error ("couldn't open %s", from);
+
+ /* Get the time for later comparison. */
+ if (fstat (fd, &st))
+ st.st_mtime = (time_t) - 1;
+
+ /* Always attempt to create the directory on the remote system. */
+ wstr = towide (dir, NULL);
+ (void) CeCreateDirectory (wstr, NULL);
+
+ /* Attempt to open the remote file, creating it if it doesn't exist. */
+ wstr = towide (remotefile, NULL);
+ h = CeCreateFile (wstr, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+ OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ /* Some kind of problem? */
+ err = CeGetLastError ();
+ if (h == NULL || h == INVALID_HANDLE_VALUE)
+ error ("error opening file \"%s\". Windows error %d.",
+ remotefile, err);
+
+ CeGetFileTime (h, &crtime, &actime, &wrtime);
+ utime = to_time_t (&wrtime);
+#if 0
+ if (utime < st.st_mtime)
+ {
+ char buf[80];
+ strcpy (buf, ctime(&utime));
+ printf ("%s < %s\n", buf, ctime(&st.st_mtime));
+ }
+#endif
+ /* See if we need to upload the file. */
+ if (upload_when == UPLOAD_ALWAYS ||
+ err != ERROR_ALREADY_EXISTS ||
+ !CeGetFileTime (h, &crtime, &actime, &wrtime) ||
+ to_time_t (&wrtime) < st.st_mtime)
+ {
+ DWORD nbytes;
+ char buf[4096];
+ int n;
+
+ /* Upload the file. */
+ while ((n = read (fd, buf, sizeof (buf))) > 0)
+ if (!CeWriteFile (h, buf, (DWORD) n, &nbytes, NULL))
+ error ("error writing to remote device - %d.",
+ CeGetLastError ());
+ }
+
+ close (fd);
+ if (!CeCloseHandle (h))
+ error ("error closing remote file - %d.", CeGetLastError ());
+
+ return remotefile;
+}
+
+/* Initialize the connection to the remote device. */
+static void
+wince_initialize (void)
+{
+ int tmp;
+ char args[256];
+ char *hostname;
+ struct sockaddr_in sin;
+ char *stub_file_name;
+ int s0;
+ PROCESS_INFORMATION pi;
+
+ if (!connection_initialized)
+ switch (CeRapiInit ())
+ {
+ case 0:
+ connection_initialized = 1;
+ break;
+ default:
+ CeRapiUninit ();
+ error ("Can't initialize connection to remote device.\n");
+ break;
+ }
+
+ /* Upload the stub to the handheld device. */
+ stub_file_name = upload_to_device ("wince-stub.exe", WINCE_STUB);
+ strcpy (args, stub_file_name);
+
+ if (remote_add_host)
+ {
+ strcat (args, " ");
+ hostname = strchr (args, '\0');
+ if (gethostname (hostname, sizeof (args) - strlen (args)))
+ error ("couldn't get hostname of this system.");
+ }
+
+ /* Get a socket. */
+ if ((s0 = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ stub_error ("Couldn't connect to host system.");
+
+ /* Allow rapid reuse of the port. */
+ tmp = 1;
+ (void) setsockopt (s0, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp));
+
+
+ /* Set up the information for connecting to the host gdb process. */
+ memset (&sin, 0, sizeof (sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons (7000); /* FIXME: This should be configurable */
+
+ if (bind (s0, (struct sockaddr *) &sin, sizeof (sin)))
+ error ("couldn't bind socket");
+
+ if (listen (s0, 1))
+ error ("Couldn't open socket for listening.\n");
+
+ /* Start up the stub on the remote device. */
+ if (!CeCreateProcess (towide (stub_file_name, NULL), towide (args, NULL),
+ NULL, NULL, 0, 0, NULL, NULL, NULL, &pi))
+ error ("Unable to start remote stub '%s'. Windows CE error %d.",
+ stub_file_name, CeGetLastError ());
+
+ /* Wait for a connection */
+
+ if ((s = accept (s0, NULL, NULL)) < 0)
+ error ("couldn't set up server for connection.");
+
+ close (s0);
+}
+
+/* Start an inferior win32 child process and sets inferior_ptid 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 (char *exec_file, char *args, char **env)
+{
+ PROCESS_INFORMATION pi;
+ struct target_waitstatus dummy;
+ int ret;
+ DWORD flags, event_code;
+ char *exec_and_args;
+
+ if (!exec_file)
+ error ("No executable specified, use `target exec'.\n");
+
+ flags = DEBUG_PROCESS;
+
+ wince_initialize (); /* Make sure we've got a connection. */
+
+ exec_file = upload_to_device (exec_file, exec_file);
+
+ while (*args == ' ')
+ args++;
+
+ /* Allocate space for "command<sp>args" */
+ if (*args == '\0')
+ {
+ exec_and_args = alloca (strlen (exec_file) + 1);
+ strcpy (exec_and_args, exec_file);
+ }
+ else
+ {
+ exec_and_args = alloca (strlen (exec_file + strlen (args) + 2));
+ sprintf (exec_and_args, "%s %s", exec_file, args);
+ }
+
+ memset (&pi, 0, sizeof (pi));
+ /* Execute the process */
+ if (!create_process (exec_file, exec_and_args, flags, &pi))
+ error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
+
+ exception_count = 0;
+ event_count = 0;
+
+ current_process_handle = pi.hProcess;
+ current_event.dwProcessId = pi.dwProcessId;
+ memset (&current_event, 0, sizeof (current_event));
+ current_event.dwThreadId = pi.dwThreadId;
+ inferior_ptid = pid_to_ptid (current_event.dwThreadId);
+ push_target (&child_ops);
+ child_init_thread_list ();
+ child_add_thread (pi.dwThreadId, pi.hThread);
+ init_wait_for_inferior ();
+ clear_proceed_status ();
+ target_terminal_init ();
+ target_terminal_inferior ();
+
+ /* Run until process and threads are loaded */
+ while (!get_child_debug_event (PIDGET (inferior_ptid), &dummy,
+ CREATE_PROCESS_DEBUG_EVENT, &ret))
+ continue;
+
+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
+}
+
+/* Chile has gone bye-bye. */
+static void
+child_mourn_inferior (void)
+{
+ (void) child_continue (DBG_CONTINUE, -1);
+ unpush_target (&child_ops);
+ stop_stub ();
+ CeRapiUninit ();
+ connection_initialized = 0;
+ generic_mourn_inferior ();
+}
+
+/* Move memory from child to/from gdb. */
+int
+child_xfer_memory (CORE_ADDR memaddr, char *our, int len, int write,
+ struct mem_attrib *attrib,
+ struct target_ops *target)
+{
+ if (len <= 0)
+ return 0;
+
+ if (write)
+ res = remote_write_bytes (memaddr, our, len);
+ else
+ res = remote_read_bytes (memaddr, our, len);
+
+ return res;
+}
+
+/* Terminate the process and wait for child to tell us it has completed. */
+void
+child_kill_inferior (void)
+{
+ CHECK (terminate_process (current_process_handle));
+
+ for (;;)
+ {
+ if (!child_continue (DBG_CONTINUE, -1))
+ break;
+ if (!wait_for_debug_event (&current_event, INFINITE))
+ break;
+ if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
+ break;
+ }
+
+ CHECK (close_handle (current_process_handle));
+ close_handle (current_thread->h);
+ target_mourn_inferior (); /* or just child_mourn_inferior? */
+}
+
+/* Resume the child after an exception. */
+void
+child_resume (ptid_t ptid, int step, enum target_signal sig)
+{
+ thread_info *th;
+ DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
+ DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
+ int pid = PIDGET (ptid);
+
+ DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
+ pid, step, sig));
+
+ /* Get context for currently selected thread */
+ th = thread_rec (current_event.dwThreadId, FALSE);
+
+ if (th->context.ContextFlags)
+ {
+ CHECK (set_thread_context (th->h, &th->context));
+ th->context.ContextFlags = 0;
+ }
+
+ /* Allow continuing with the same signal that interrupted us.
+ Otherwise complain. */
+ if (sig && sig != last_sig)
+ fprintf_unfiltered (gdb_stderr, "Can't send signals to the child. signal %d\n", sig);
+
+ last_sig = 0;
+ child_continue (continue_status, pid);
+}
+
+static void
+child_prepare_to_store (void)
+{
+ /* Do nothing, since we can store individual regs */
+}
+
+static int
+child_can_run (void)
+{
+ return 1;
+}
+
+static void
+child_close (void)
+{
+ DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
+ PIDGET (inferior_ptid)));
+}
+
+/* Explicitly upload file to remotedir */
+
+static void
+child_load (char *file, int from_tty)
+{
+ upload_to_device (file, file);
+}
+
+struct target_ops child_ops;
+
+static void
+init_child_ops (void)
+{
+ memset (&child_ops, 0, sizeof (child_ops));
+ child_ops.to_shortname = (char *) "child";
+ child_ops.to_longname = (char *) "Windows CE process";
+ child_ops.to_doc = (char *) "Windows CE process (started by the \"run\" command).";
+ child_ops.to_open = child_open;
+ child_ops.to_close = child_close;
+ child_ops.to_resume = child_resume;
+ child_ops.to_wait = child_wait;
+ child_ops.to_fetch_registers = child_fetch_inferior_registers;
+ child_ops.to_store_registers = child_store_inferior_registers;
+ child_ops.to_prepare_to_store = child_prepare_to_store;
+ child_ops.to_xfer_memory = child_xfer_memory;
+ child_ops.to_files_info = child_files_info;
+ child_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ child_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ child_ops.to_terminal_init = terminal_init_inferior;
+ child_ops.to_terminal_inferior = terminal_inferior;
+ child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ child_ops.to_terminal_ours = terminal_ours;
+ child_ops.to_terminal_info = child_terminal_info;
+ child_ops.to_kill = child_kill_inferior;
+ child_ops.to_load = child_load;
+ child_ops.to_create_inferior = child_create_inferior;
+ child_ops.to_mourn_inferior = child_mourn_inferior;
+ child_ops.to_can_run = child_can_run;
+ child_ops.to_thread_alive = win32_child_thread_alive;
+ child_ops.to_stratum = process_stratum;
+ child_ops.to_has_all_memory = 1;
+ child_ops.to_has_memory = 1;
+ child_ops.to_has_stack = 1;
+ child_ops.to_has_registers = 1;
+ child_ops.to_has_execution = 1;
+ child_ops.to_sections = 0;
+ child_ops.to_sections_end = 0;
+ child_ops.to_magic = OPS_MAGIC;
+}
+
+
+/* Handle 'set remoteupload' parameter. */
+
+#define replace_upload(what) \
+ upload_when = what; \
+ remote_upload = xrealloc (remote_upload, strlen (upload_options[upload_when].name) + 1); \
+ strcpy (remote_upload, upload_options[upload_when].name);
+
+static void
+set_upload_type (char *ignore, int from_tty)
+{
+ int i, len;
+ char *bad_option;
+
+ if (!remote_upload || !remote_upload[0])
+ {
+ replace_upload (UPLOAD_NEWER);
+ if (from_tty)
+ printf_unfiltered ("Upload upload_options are: always, newer, never.\n");
+ return;
+ }
+
+ len = strlen (remote_upload);
+ for (i = 0; i < (sizeof (upload_options) / sizeof (upload_options[0])); i++)
+ if (len >= upload_options[i].abbrev &&
+ strncasecmp (remote_upload, upload_options[i].name, len) == 0)
+ {
+ replace_upload (i);
+ return;
+ }
+
+ bad_option = remote_upload;
+ replace_upload (UPLOAD_NEWER);
+ error ("Unknown upload type: %s.", bad_option);
+}
+
+void
+_initialize_inftarg (void)
+{
+ struct cmd_list_element *set;
+ init_child_ops ();
+
+ add_show_from_set
+ (add_set_cmd ((char *) "remotedirectory", no_class,
+ var_string_noescape, (char *) &remote_directory,
+ (char *) "Set directory for remote upload.\n",
+ &setlist),
+ &showlist);
+ remote_directory = xstrdup (remote_directory);
+
+ set = add_set_cmd ((char *) "remoteupload", no_class,
+ var_string_noescape, (char *) &remote_upload,
+ (char *) "Set how to upload executables to remote device.\n",
+ &setlist);
+ add_show_from_set (set, &showlist);
+ set_cmd_cfunc (set, set_upload_type);
+ set_upload_type (NULL, 0);
+
+ add_show_from_set
+ (add_set_cmd ((char *) "debugexec", class_support, var_boolean,
+ (char *) &debug_exec,
+ (char *) "Set whether to display execution in child process.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ((char *) "remoteaddhost", class_support, var_boolean,
+ (char *) &remote_add_host,
+ (char *) "Set whether to add this host to remote stub arguments for\n
+debugging over a network.", &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ((char *) "debugevents", class_support, var_boolean,
+ (char *) &debug_events,
+ (char *) "Set whether to display kernel events in child process.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ((char *) "debugmemory", class_support, var_boolean,
+ (char *) &debug_memory,
+ (char *) "Set whether to display memory accesses in child process.",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ((char *) "debugexceptions", class_support, var_boolean,
+ (char *) &debug_exceptions,
+ (char *) "Set whether to display kernel exceptions in child process.",
+ &setlist),
+ &showlist);
+
+ add_target (&child_ops);
+}
+
+/* Determine if the thread referenced by "pid" is alive
+ by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
+ it means that the pid has died. Otherwise it is assumed to be alive. */
+static int
+win32_child_thread_alive (ptid_t ptid)
+{
+ int pid = PIDGET (ptid);
+ return thread_alive (thread_rec (pid, FALSE)->h);
+}
+
+/* Convert pid to printable format. */
+char *
+cygwin_pid_to_str (int pid)
+{
+ static char buf[80];
+ if (pid == current_event.dwProcessId)
+ sprintf (buf, "process %d", pid);
+ else
+ sprintf (buf, "thread %d.0x%x", (unsigned) current_event.dwProcessId, pid);
+ return buf;
+}
diff --git a/gdb/x86-64-linux-nat.c b/gdb/x86-64-linux-nat.c
new file mode 100644
index 00000000000..f57a5f27675
--- /dev/null
+++ b/gdb/x86-64-linux-nat.c
@@ -0,0 +1,442 @@
+/* Native-dependent code for GNU/Linux x86-64.
+
+ Copyright 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Jiri Smid, SuSE Labs.
+
+ 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 "defs.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "i387-tdep.h"
+#include "gdb_assert.h"
+#include "x86-64-tdep.h"
+
+#include <sys/ptrace.h>
+#include <sys/debugreg.h>
+#include <sys/syscall.h>
+#include <sys/procfs.h>
+#include <sys/reg.h>
+
+/* Mapping between the general-purpose registers in `struct user'
+ format and GDB's register array layout. */
+
+static int x86_64_regmap[] = {
+ RAX, RBX, RCX, RDX,
+ RSI, RDI, RBP, RSP,
+ R8, R9, R10, R11,
+ R12, R13, R14, R15,
+ RIP, EFLAGS,
+ DS, ES, FS, GS
+};
+
+static unsigned long
+x86_64_linux_dr_get (int regnum)
+{
+ int tid;
+ unsigned long value;
+
+ /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
+ multi-threaded processes here. For now, pretend there is just
+ one thread. */
+ tid = PIDGET (inferior_ptid);
+
+ /* FIXME: kettenis/2001-03-27: Calling perror_with_name if the
+ ptrace call fails breaks debugging remote targets. The correct
+ way to fix this is to add the hardware breakpoint and watchpoint
+ stuff to the target vectore. For now, just return zero if the
+ ptrace call fails. */
+ errno = 0;
+ value = ptrace (PT_READ_U, tid,
+ offsetof (struct user, u_debugreg[regnum]), 0);
+ if (errno != 0)
+#if 0
+ perror_with_name ("Couldn't read debug register");
+#else
+ return 0;
+#endif
+
+ return value;
+}
+
+static void
+x86_64_linux_dr_set (int regnum, unsigned long value)
+{
+ int tid;
+
+ /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
+ multi-threaded processes here. For now, pretend there is just
+ one thread. */
+ tid = PIDGET (inferior_ptid);
+
+ errno = 0;
+ ptrace (PT_WRITE_U, tid, offsetof (struct user, u_debugreg[regnum]), value);
+ if (errno != 0)
+ perror_with_name ("Couldn't write debug register");
+}
+
+void
+x86_64_linux_dr_set_control (unsigned long control)
+{
+ x86_64_linux_dr_set (DR_CONTROL, control);
+}
+
+void
+x86_64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
+{
+ gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
+
+ x86_64_linux_dr_set (DR_FIRSTADDR + regnum, addr);
+}
+
+void
+x86_64_linux_dr_reset_addr (int regnum)
+{
+ gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
+
+ x86_64_linux_dr_set (DR_FIRSTADDR + regnum, 0L);
+}
+
+unsigned long
+x86_64_linux_dr_get_status (void)
+{
+ return x86_64_linux_dr_get (DR_STATUS);
+}
+
+
+/* The register sets used in GNU/Linux ELF core-dumps are identical to
+ the register sets used by `ptrace'. */
+
+#define GETREGS_SUPPLIES(regno) \
+ (0 <= (regno) && (regno) < x86_64_num_gregs)
+#define GETFPREGS_SUPPLIES(regno) \
+ (FP0_REGNUM <= (regno) && (regno) <= MXCSR_REGNUM)
+
+
+/* Transfering the general-purpose registers between GDB, inferiors
+ and core files. */
+
+/* Fill GDB's register array with the general-purpose register values
+ in *GREGSETP. */
+
+void
+supply_gregset (elf_gregset_t * gregsetp)
+{
+ elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ int i;
+
+ for (i = 0; i < x86_64_num_gregs; i++)
+ supply_register (i, (char *) (regp + x86_64_regmap[i]));
+}
+
+/* Fill register REGNO (if it is a general-purpose register) in
+ *GREGSETPS with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+
+void
+fill_gregset (elf_gregset_t * gregsetp, int regno)
+{
+ elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ int i;
+
+ for (i = 0; i < x86_64_num_gregs; i++)
+ if ((regno == -1 || regno == i))
+ read_register_gen (i, (char *) (regp + x86_64_regmap[i]));
+}
+
+/* Fetch all general-purpose registers from process/thread TID and
+ store their values in GDB's register array. */
+
+static void
+fetch_regs (int tid)
+{
+ elf_gregset_t regs;
+
+ if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
+ perror_with_name ("Couldn't get registers");
+
+ supply_gregset (&regs);
+}
+
+/* Store all valid general-purpose registers in GDB's register array
+ into the process/thread specified by TID. */
+
+static void
+store_regs (int tid, int regno)
+{
+ elf_gregset_t regs;
+
+ if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
+ perror_with_name ("Couldn't get registers");
+
+ fill_gregset (&regs, regno);
+
+ if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
+ perror_with_name ("Couldn't write registers");
+}
+
+
+/* Transfering floating-point registers between GDB, inferiors and cores. */
+
+/* Fill GDB's register array with the floating-point register values in
+ *FPREGSETP. */
+
+void
+supply_fpregset (elf_fpregset_t * fpregsetp)
+{
+ i387_supply_fxsave ((char *) fpregsetp);
+}
+
+/* Fill register REGNO (if it is a floating-point register) in
+ *FPREGSETP with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+
+void
+fill_fpregset (elf_fpregset_t * fpregsetp, int regno)
+{
+ i387_fill_fxsave ((char *) fpregsetp, regno);
+}
+
+/* Fetch all floating-point registers from process/thread TID and store
+ thier values in GDB's register array. */
+
+static void
+fetch_fpregs (int tid)
+{
+ elf_fpregset_t fpregs;
+
+ if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
+ perror_with_name ("Couldn't get floating point status");
+
+ supply_fpregset (&fpregs);
+}
+
+/* Store all valid floating-point registers in GDB's register array
+ into the process/thread specified by TID. */
+
+static void
+store_fpregs (int tid, int regno)
+{
+ elf_fpregset_t fpregs;
+
+ if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
+ perror_with_name ("Couldn't get floating point status");
+
+ fill_fpregset (&fpregs, regno);
+
+ if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
+ perror_with_name ("Couldn't write floating point status");
+}
+
+
+/* Transferring arbitrary registers between GDB and inferior. */
+
+/* Fetch register REGNO from the child process. If REGNO is -1, do
+ this for all registers (including the floating point and SSE
+ registers). */
+
+void
+fetch_inferior_registers (int regno)
+{
+ int tid;
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ if ((tid = TIDGET (inferior_ptid)) == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ if (regno == -1)
+ {
+ fetch_regs (tid);
+ fetch_fpregs (tid);
+ return;
+ }
+
+ if (GETREGS_SUPPLIES (regno))
+ {
+ fetch_regs (tid);
+ return;
+ }
+
+ if (GETFPREGS_SUPPLIES (regno))
+ {
+ fetch_fpregs (tid);
+ return;
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "Got request for bad register number %d.", regno);
+}
+
+/* Store register REGNO back into the child process. If REGNO is -1,
+ do this for all registers (including the floating point and SSE
+ registers). */
+void
+store_inferior_registers (int regno)
+{
+ int tid;
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ if ((tid = TIDGET (inferior_ptid)) == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ if (regno == -1)
+ {
+ store_regs (tid, regno);
+ store_fpregs (tid, regno);
+ return;
+ }
+
+ if (GETREGS_SUPPLIES (regno))
+ {
+ store_regs (tid, regno);
+ return;
+ }
+
+ if (GETFPREGS_SUPPLIES (regno))
+ {
+ store_fpregs (tid, regno);
+ return;
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "Got request to store bad register number %d.", regno);
+}
+
+
+static const unsigned char linux_syscall[] = { 0x0f, 0x05 };
+
+#define LINUX_SYSCALL_LEN (sizeof linux_syscall)
+
+/* The system call number is stored in the %rax register. */
+#define LINUX_SYSCALL_REGNUM 0 /* %rax */
+
+/* We are specifically interested in the sigreturn and rt_sigreturn
+ system calls. */
+
+#ifndef SYS_sigreturn
+#define SYS_sigreturn __NR_sigreturn
+#endif
+#ifndef SYS_rt_sigreturn
+#define SYS_rt_sigreturn __NR_rt_sigreturn
+#endif
+
+/* Offset to saved processor flags, from <asm/sigcontext.h>. */
+#define LINUX_SIGCONTEXT_EFLAGS_OFFSET (152)
+/* Offset to saved processor registers from <asm/ucontext.h> */
+#define LINUX_UCONTEXT_SIGCONTEXT_OFFSET (36)
+
+/* Interpreting register set info found in core files. */
+/* Provide registers to GDB from a core file.
+
+ CORE_REG_SECT points to an array of bytes, which are the contents
+ of a `note' from a core file which BFD thinks might contain
+ register contents. CORE_REG_SIZE is its size.
+
+ WHICH says which register set corelow suspects this is:
+ 0 --- the general-purpose register set, in elf_gregset_t format
+ 2 --- the floating-point register set, in elf_fpregset_t format
+
+ REG_ADDR isn't used on GNU/Linux. */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+ elf_gregset_t gregset;
+ elf_fpregset_t fpregset;
+ switch (which)
+ {
+ case 0:
+ if (core_reg_size != sizeof (gregset))
+ warning ("Wrong size gregset in core file.");
+ else
+ {
+ memcpy (&gregset, core_reg_sect, sizeof (gregset));
+ supply_gregset (&gregset);
+ }
+ break;
+
+ case 2:
+ if (core_reg_size != sizeof (fpregset))
+ warning ("Wrong size fpregset in core file.");
+ else
+ {
+ memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
+ supply_fpregset (&fpregset);
+ }
+ break;
+
+ default:
+ /* We've covered all the kinds of registers we know about here,
+ so this must be something we wouldn't know what to do with
+ anyway. Just ignore it. */
+ break;
+ }
+}
+
+/* Register that we are able to handle GNU/Linux ELF core file formats. */
+
+static struct core_fns linux_elf_core_fns = {
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+
+#if !defined (offsetof)
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+#endif
+
+/* Return the address of register REGNUM. BLOCKEND is the value of
+ u.u_ar0, which should point to the registers. */
+CORE_ADDR
+x86_64_register_u_addr (CORE_ADDR blockend, int regnum)
+{
+ struct user u;
+ CORE_ADDR fpstate;
+ CORE_ADDR ubase;
+ ubase = blockend;
+ if (IS_FP_REGNUM (regnum))
+ {
+ fpstate = ubase + ((char *) &u.i387.st_space - (char *) &u);
+ return (fpstate + 16 * (regnum - FP0_REGNUM));
+ }
+ else if (IS_SSE_REGNUM (regnum))
+ {
+ fpstate = ubase + ((char *) &u.i387.xmm_space - (char *) &u);
+ return (fpstate + 16 * (regnum - XMM0_REGNUM));
+ }
+ else
+ return (ubase + 8 * x86_64_regmap[regnum]);
+}
+
+void
+_initialize_x86_64_linux_nat (void)
+{
+ add_core_fns (&linux_elf_core_fns);
+}
+
+int
+kernel_u_size (void)
+{
+ return (sizeof (struct user));
+}
diff --git a/gdb/x86-64-linux-tdep.c b/gdb/x86-64-linux-tdep.c
new file mode 100644
index 00000000000..171ec9c4975
--- /dev/null
+++ b/gdb/x86-64-linux-tdep.c
@@ -0,0 +1,136 @@
+/* Target-dependent code for GNU/Linux running on x86-64, for GDB.
+
+ Copyright 2001 Free Software Foundation, Inc.
+
+ Contributed by Jiri Smid, SuSE Labs.
+
+ 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 "defs.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "x86-64-tdep.h"
+#include "dwarf2cfi.h"
+
+#define LINUX_SIGTRAMP_INSN0 (0x48) /* mov $NNNNNNNN,%rax */
+#define LINUX_SIGTRAMP_OFFSET0 (0)
+#define LINUX_SIGTRAMP_INSN1 (0x0f) /* syscall */
+#define LINUX_SIGTRAMP_OFFSET1 (7)
+
+static const unsigned char linux_sigtramp_code[] = {
+ LINUX_SIGTRAMP_INSN0, 0xc7, 0xc0, 0x89, 0x00, 0x00, 0x00, /* mov $0x89,%rax */
+ LINUX_SIGTRAMP_INSN1, 0x05 /* syscall */
+};
+
+#define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code)
+
+/* If PC is in a sigtramp routine, return the address of the start of
+ the routine. Otherwise, return 0. */
+
+static CORE_ADDR
+x86_64_linux_sigtramp_start (CORE_ADDR pc)
+{
+ unsigned char buf[LINUX_SIGTRAMP_LEN];
+ if (read_memory_nobpt (pc, (char *) buf, LINUX_SIGTRAMP_LEN) != 0)
+ return 0;
+
+ if (buf[0] != LINUX_SIGTRAMP_INSN0)
+ {
+ if (buf[0] != LINUX_SIGTRAMP_INSN1)
+ return 0;
+
+ pc -= LINUX_SIGTRAMP_OFFSET1;
+
+ if (read_memory_nobpt (pc, (char *) buf, LINUX_SIGTRAMP_LEN) != 0)
+ return 0;
+ }
+
+ if (memcmp (buf, linux_sigtramp_code, LINUX_SIGTRAMP_LEN) != 0)
+ return 0;
+
+ return pc;
+}
+
+#define LINUX_SIGINFO_SIZE 128
+
+/* Offset to struct sigcontext in ucontext, from <asm/ucontext.h>. */
+#define LINUX_UCONTEXT_SIGCONTEXT_OFFSET (36)
+
+/* Assuming FRAME is for a GNU/Linux sigtramp routine, return the
+ address of the associated sigcontext structure. */
+CORE_ADDR
+x86_64_linux_sigcontext_addr (struct frame_info *frame)
+{
+ CORE_ADDR pc;
+
+ pc = x86_64_linux_sigtramp_start (frame->pc);
+ if (pc)
+ {
+ if (frame->next)
+ /* If this isn't the top frame, the next frame must be for the
+ signal handler itself. The sigcontext structure is part of
+ the user context. */
+ return frame->next->frame + LINUX_SIGINFO_SIZE +
+ LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
+
+
+ /* This is the top frame. */
+ return read_register (SP_REGNUM) + LINUX_SIGINFO_SIZE +
+ LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
+
+ }
+
+ error ("Couldn't recognize signal trampoline.");
+ return 0;
+}
+
+/* Offset to saved PC in sigcontext, from <asm/sigcontext.h>. */
+#define LINUX_SIGCONTEXT_PC_OFFSET (136)
+
+/* Assuming FRAME is for a GNU/Linux sigtramp routine, return the
+ saved program counter. */
+
+CORE_ADDR
+x86_64_linux_sigtramp_saved_pc (struct frame_info *frame)
+{
+ CORE_ADDR addr;
+
+ addr = x86_64_linux_sigcontext_addr (frame);
+ return read_memory_integer (addr + LINUX_SIGCONTEXT_PC_OFFSET, 8);
+}
+
+/* Immediately after a function call, return the saved pc. */
+
+CORE_ADDR
+x86_64_linux_saved_pc_after_call (struct frame_info *frame)
+{
+ if (frame->signal_handler_caller)
+ return x86_64_linux_sigtramp_saved_pc (frame);
+
+ return read_memory_integer (read_register (SP_REGNUM), 8);
+}
+
+/* Saved Pc. Get it from sigcontext if within sigtramp. */
+CORE_ADDR
+x86_64_linux_frame_saved_pc (struct frame_info *frame)
+{
+ if (frame->signal_handler_caller)
+ return x86_64_linux_sigtramp_saved_pc (frame);
+ return cfi_get_ra (frame);
+}
diff --git a/gdb/x86-64-tdep.c b/gdb/x86-64-tdep.c
new file mode 100644
index 00000000000..a3f8bee1682
--- /dev/null
+++ b/gdb/x86-64-tdep.c
@@ -0,0 +1,1150 @@
+/* Target-dependent code for the x86-64 for GDB, the GNU debugger.
+
+ Copyright 2001, 2002 Free Software Foundation, Inc.
+
+ Contributed by Jiri Smid, SuSE Labs.
+
+ 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 "defs.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "arch-utils.h"
+#include "regcache.h"
+#include "symfile.h"
+#include "x86-64-tdep.h"
+#include "dwarf2cfi.h"
+#include "gdb_assert.h"
+
+/* Register numbers of various important registers. */
+#define RAX_REGNUM 0
+#define RDX_REGNUM 3
+#define RDI_REGNUM 5
+#define EFLAGS_REGNUM 17
+#define ST0_REGNUM 22
+#define XMM1_REGNUM 39
+
+struct register_info
+{
+ int size;
+ char *name;
+ struct type **type;
+};
+
+/* x86_64_register_raw_size_table[i] is the number of bytes of storage in
+ GDB's register array occupied by register i. */
+static struct register_info x86_64_register_info_table[] = {
+ /* 0 */ {8, "rax", &builtin_type_int64},
+ /* 1 */ {8, "rbx", &builtin_type_int64},
+ /* 2 */ {8, "rcx", &builtin_type_int64},
+ /* 3 */ {8, "rdx", &builtin_type_int64},
+ /* 4 */ {8, "rsi", &builtin_type_int64},
+ /* 5 */ {8, "rdi", &builtin_type_int64},
+ /* 6 */ {8, "rbp", &builtin_type_void_func_ptr},
+ /* 7 */ {8, "rsp", &builtin_type_void_func_ptr},
+ /* 8 */ {8, "r8", &builtin_type_int64},
+ /* 9 */ {8, "r9", &builtin_type_int64},
+ /* 10 */ {8, "r10", &builtin_type_int64},
+ /* 11 */ {8, "r11", &builtin_type_int64},
+ /* 12 */ {8, "r12", &builtin_type_int64},
+ /* 13 */ {8, "r13", &builtin_type_int64},
+ /* 14 */ {8, "r14", &builtin_type_int64},
+ /* 15 */ {8, "r15", &builtin_type_int64},
+ /* 16 */ {8, "rip", &builtin_type_void_func_ptr},
+ /* 17 */ {4, "eflags", &builtin_type_int32},
+ /* 18 */ {4, "ds", &builtin_type_int32},
+ /* 19 */ {4, "es", &builtin_type_int32},
+ /* 20 */ {4, "fs", &builtin_type_int32},
+ /* 21 */ {4, "gs", &builtin_type_int32},
+ /* 22 */ {10, "st0", &builtin_type_i387_ext},
+ /* 23 */ {10, "st1", &builtin_type_i387_ext},
+ /* 24 */ {10, "st2", &builtin_type_i387_ext},
+ /* 25 */ {10, "st3", &builtin_type_i387_ext},
+ /* 26 */ {10, "st4", &builtin_type_i387_ext},
+ /* 27 */ {10, "st5", &builtin_type_i387_ext},
+ /* 28 */ {10, "st6", &builtin_type_i387_ext},
+ /* 29 */ {10, "st7", &builtin_type_i387_ext},
+ /* 30 */ {4, "fctrl", &builtin_type_int32},
+ /* 31 */ {4, "fstat", &builtin_type_int32},
+ /* 32 */ {4, "ftag", &builtin_type_int32},
+ /* 33 */ {4, "fiseg", &builtin_type_int32},
+ /* 34 */ {4, "fioff", &builtin_type_int32},
+ /* 35 */ {4, "foseg", &builtin_type_int32},
+ /* 36 */ {4, "fooff", &builtin_type_int32},
+ /* 37 */ {4, "fop", &builtin_type_int32},
+ /* 38 */ {16, "xmm0", &builtin_type_v4sf},
+ /* 39 */ {16, "xmm1", &builtin_type_v4sf},
+ /* 40 */ {16, "xmm2", &builtin_type_v4sf},
+ /* 41 */ {16, "xmm3", &builtin_type_v4sf},
+ /* 42 */ {16, "xmm4", &builtin_type_v4sf},
+ /* 43 */ {16, "xmm5", &builtin_type_v4sf},
+ /* 44 */ {16, "xmm6", &builtin_type_v4sf},
+ /* 45 */ {16, "xmm7", &builtin_type_v4sf},
+ /* 46 */ {16, "xmm8", &builtin_type_v4sf},
+ /* 47 */ {16, "xmm9", &builtin_type_v4sf},
+ /* 48 */ {16, "xmm10", &builtin_type_v4sf},
+ /* 49 */ {16, "xmm11", &builtin_type_v4sf},
+ /* 50 */ {16, "xmm12", &builtin_type_v4sf},
+ /* 51 */ {16, "xmm13", &builtin_type_v4sf},
+ /* 52 */ {16, "xmm14", &builtin_type_v4sf},
+ /* 53 */ {16, "xmm15", &builtin_type_v4sf},
+ /* 54 */ {4, "mxcsr", &builtin_type_int32}
+};
+
+/* This array is a mapping from Dwarf-2 register
+ numbering to GDB's one. Dwarf-2 numbering is
+ defined in x86-64 ABI, section 3.6. */
+static int x86_64_dwarf2gdb_regno_map[] = {
+ 0, 1, 2, 3, /* RAX - RDX */
+ 4, 5, 6, 7, /* RSI, RDI, RBP, RSP */
+ 8, 9, 10, 11, /* R8 - R11 */
+ 12, 13, 14, 15, /* R12 - R15 */
+ -1, /* RA - not mapped */
+ XMM1_REGNUM - 1, XMM1_REGNUM, /* XMM0 ... */
+ XMM1_REGNUM + 1, XMM1_REGNUM + 2,
+ XMM1_REGNUM + 3, XMM1_REGNUM + 4,
+ XMM1_REGNUM + 5, XMM1_REGNUM + 6,
+ XMM1_REGNUM + 7, XMM1_REGNUM + 8,
+ XMM1_REGNUM + 9, XMM1_REGNUM + 10,
+ XMM1_REGNUM + 11, XMM1_REGNUM + 12,
+ XMM1_REGNUM + 13, XMM1_REGNUM + 14, /* ... XMM15 */
+ ST0_REGNUM + 0, ST0_REGNUM + 1, /* ST0 ... */
+ ST0_REGNUM + 2, ST0_REGNUM + 3,
+ ST0_REGNUM + 4, ST0_REGNUM + 5,
+ ST0_REGNUM + 6, ST0_REGNUM + 7 /* ... ST7 */
+};
+
+static int x86_64_dwarf2gdb_regno_map_length =
+ sizeof (x86_64_dwarf2gdb_regno_map) /
+ sizeof (x86_64_dwarf2gdb_regno_map[0]);
+
+/* Number of all registers */
+#define X86_64_NUM_REGS (sizeof (x86_64_register_info_table) / \
+ sizeof (x86_64_register_info_table[0]))
+
+/* Number of general registers. */
+#define X86_64_NUM_GREGS (22)
+
+int x86_64_num_regs = X86_64_NUM_REGS;
+int x86_64_num_gregs = X86_64_NUM_GREGS;
+
+/* Did we already print a note about frame pointer? */
+int omit_fp_note_printed = 0;
+
+/* Number of bytes of storage in the actual machine representation for
+ register REGNO. */
+int
+x86_64_register_raw_size (int regno)
+{
+ return x86_64_register_info_table[regno].size;
+}
+
+/* x86_64_register_byte_table[i] is the offset into the register file of the
+ start of register number i. We initialize this from
+ x86_64_register_info_table. */
+int x86_64_register_byte_table[X86_64_NUM_REGS];
+
+/* Index within `registers' of the first byte of the space for register REGNO. */
+int
+x86_64_register_byte (int regno)
+{
+ return x86_64_register_byte_table[regno];
+}
+
+/* Return the GDB type object for the "standard" data type of data in
+ register N. */
+static struct type *
+x86_64_register_virtual_type (int regno)
+{
+ return *x86_64_register_info_table[regno].type;
+}
+
+/* x86_64_register_convertible is true if register N's virtual format is
+ different from its raw format. Note that this definition assumes
+ that the host supports IEEE 32-bit floats, since it doesn't say
+ that SSE registers need conversion. Even if we can't find a
+ counterexample, this is still sloppy. */
+int
+x86_64_register_convertible (int regno)
+{
+ return IS_FP_REGNUM (regno);
+}
+
+/* Convert data from raw format for register REGNUM in buffer FROM to
+ virtual format with type TYPE in buffer TO. In principle both
+ formats are identical except that the virtual format has two extra
+ bytes appended that aren't used. We set these to zero. */
+void
+x86_64_register_convert_to_virtual (int regnum, struct type *type,
+ char *from, char *to)
+{
+ char buf[12];
+
+ /* We only support floating-point values. */
+ if (TYPE_CODE (type) != TYPE_CODE_FLT)
+ {
+ warning ("Cannot convert floating-point register value "
+ "to non-floating-point type.");
+ memset (to, 0, TYPE_LENGTH (type));
+ return;
+ }
+ /* First add the necessary padding. */
+ memcpy (buf, from, FPU_REG_RAW_SIZE);
+ memset (buf + FPU_REG_RAW_SIZE, 0, sizeof buf - FPU_REG_RAW_SIZE);
+ /* Convert to TYPE. This should be a no-op, if TYPE is equivalent
+ to the extended floating-point format used by the FPU. */
+ convert_typed_floating (to, type, buf,
+ x86_64_register_virtual_type (regnum));
+}
+
+/* Convert data from virtual format with type TYPE in buffer FROM to
+ raw format for register REGNUM in buffer TO. Simply omit the two
+ unused bytes. */
+
+void
+x86_64_register_convert_to_raw (struct type *type, int regnum,
+ char *from, char *to)
+{
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 12);
+ /* Simply omit the two unused bytes. */
+ memcpy (to, from, FPU_REG_RAW_SIZE);
+}
+
+/* Dwarf-2 <-> GDB register numbers mapping. */
+int
+x86_64_dwarf2_reg_to_regnum (int dw_reg)
+{
+ if (dw_reg < 0 || dw_reg > x86_64_dwarf2gdb_regno_map_length)
+ {
+ warning ("Dwarf-2 uses unmapped register #%d\n", dw_reg);
+ return dw_reg;
+ }
+
+ return x86_64_dwarf2gdb_regno_map[dw_reg];
+}
+
+/* This is the variable that is set with "set disassembly-flavour", and
+ its legitimate values. */
+static const char att_flavour[] = "att";
+static const char intel_flavour[] = "intel";
+static const char *valid_flavours[] = {
+ att_flavour,
+ intel_flavour,
+ NULL
+};
+static const char *disassembly_flavour = att_flavour;
+
+static CORE_ADDR
+x86_64_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ char buf[8];
+
+ store_unsigned_integer (buf, 8, CALL_DUMMY_ADDRESS ());
+
+ write_memory (sp - 8, buf, 8);
+ return sp - 8;
+}
+
+void
+x86_64_pop_frame (void)
+{
+ generic_pop_current_frame (cfi_pop_frame);
+}
+
+
+/* The returning of values is done according to the special algorithm.
+ Some types are returned in registers an some (big structures) in memory.
+ See ABI for details.
+ */
+
+#define MAX_CLASSES 4
+
+enum x86_64_reg_class
+{
+ X86_64_NO_CLASS,
+ X86_64_INTEGER_CLASS,
+ X86_64_INTEGERSI_CLASS,
+ X86_64_SSE_CLASS,
+ X86_64_SSESF_CLASS,
+ X86_64_SSEDF_CLASS,
+ X86_64_SSEUP_CLASS,
+ X86_64_X87_CLASS,
+ X86_64_X87UP_CLASS,
+ X86_64_MEMORY_CLASS
+};
+
+/* Return the union class of CLASS1 and CLASS2.
+ See the x86-64 ABI for details. */
+
+static enum x86_64_reg_class
+merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
+{
+ /* Rule #1: If both classes are equal, this is the resulting class. */
+ if (class1 == class2)
+ return class1;
+
+ /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
+ the other class. */
+ if (class1 == X86_64_NO_CLASS)
+ return class2;
+ if (class2 == X86_64_NO_CLASS)
+ return class1;
+
+ /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
+ if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
+ return X86_64_MEMORY_CLASS;
+
+ /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
+ if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
+ || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
+ return X86_64_INTEGERSI_CLASS;
+ if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
+ || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
+ return X86_64_INTEGER_CLASS;
+
+ /* Rule #5: If one of the classes is X87 or X87UP class, MEMORY is used. */
+ if (class1 == X86_64_X87_CLASS || class1 == X86_64_X87UP_CLASS
+ || class2 == X86_64_X87_CLASS || class2 == X86_64_X87UP_CLASS)
+ return X86_64_MEMORY_CLASS;
+
+ /* Rule #6: Otherwise class SSE is used. */
+ return X86_64_SSE_CLASS;
+}
+
+
+/* Classify the argument type.
+ CLASSES will be filled by the register class used to pass each word
+ of the operand. The number of words is returned. In case the parameter
+ should be passed in memory, 0 is returned. As a special case for zero
+ sized containers, classes[0] will be NO_CLASS and 1 is returned.
+
+ See the x86-64 PS ABI for details.
+*/
+
+static int
+classify_argument (struct type *type,
+ enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset)
+{
+ int bytes = TYPE_LENGTH (type);
+ int words = (bytes + 8 - 1) / 8;
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ {
+ int i;
+ enum x86_64_reg_class subclasses[MAX_CLASSES];
+
+ /* On x86-64 we pass structures larger than 16 bytes on the stack. */
+ if (bytes > 16)
+ return 0;
+
+ for (i = 0; i < words; i++)
+ classes[i] = X86_64_NO_CLASS;
+
+ /* Zero sized arrays or structures are NO_CLASS. We return 0 to
+ signalize memory class, so handle it as special case. */
+ if (!words)
+ {
+ classes[0] = X86_64_NO_CLASS;
+ return 1;
+ }
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_STRUCT:
+ {
+ int j;
+ for (j = 0; j < TYPE_NFIELDS (type); ++j)
+ {
+ int num = classify_argument (TYPE_FIELDS (type)[j].type,
+ subclasses,
+ (TYPE_FIELDS (type)[j].loc.bitpos
+ + bit_offset) % 256);
+ if (!num)
+ return 0;
+ for (i = 0; i < num; i++)
+ {
+ int pos =
+ (TYPE_FIELDS (type)[j].loc.bitpos + bit_offset) / 8 / 8;
+ classes[i + pos] =
+ merge_classes (subclasses[i], classes[i + pos]);
+ }
+ }
+ }
+ break;
+ case TYPE_CODE_ARRAY:
+ {
+ int num;
+
+ num = classify_argument (TYPE_TARGET_TYPE (type),
+ subclasses, bit_offset);
+ if (!num)
+ return 0;
+
+ /* The partial classes are now full classes. */
+ if (subclasses[0] == X86_64_SSESF_CLASS && bytes != 4)
+ subclasses[0] = X86_64_SSE_CLASS;
+ if (subclasses[0] == X86_64_INTEGERSI_CLASS && bytes != 4)
+ subclasses[0] = X86_64_INTEGER_CLASS;
+
+ for (i = 0; i < words; i++)
+ classes[i] = subclasses[i % num];
+ }
+ break;
+ case TYPE_CODE_UNION:
+ {
+ int j;
+ {
+ for (j = 0; j < TYPE_NFIELDS (type); ++j)
+ {
+ int num;
+ num = classify_argument (TYPE_FIELDS (type)[j].type,
+ subclasses, bit_offset);
+ if (!num)
+ return 0;
+ for (i = 0; i < num; i++)
+ classes[i] = merge_classes (subclasses[i], classes[i]);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ /* Final merger cleanup. */
+ for (i = 0; i < words; i++)
+ {
+ /* If one class is MEMORY, everything should be passed in
+ memory. */
+ if (classes[i] == X86_64_MEMORY_CLASS)
+ return 0;
+
+ /* The X86_64_SSEUP_CLASS should be always preceeded by
+ X86_64_SSE_CLASS. */
+ if (classes[i] == X86_64_SSEUP_CLASS
+ && (i == 0 || classes[i - 1] != X86_64_SSE_CLASS))
+ classes[i] = X86_64_SSE_CLASS;
+
+ /* X86_64_X87UP_CLASS should be preceeded by X86_64_X87_CLASS. */
+ if (classes[i] == X86_64_X87UP_CLASS
+ && (i == 0 || classes[i - 1] != X86_64_X87_CLASS))
+ classes[i] = X86_64_SSE_CLASS;
+ }
+ return words;
+ }
+ break;
+ case TYPE_CODE_FLT:
+ switch (bytes)
+ {
+ case 4:
+ if (!(bit_offset % 64))
+ classes[0] = X86_64_SSESF_CLASS;
+ else
+ classes[0] = X86_64_SSE_CLASS;
+ return 1;
+ case 8:
+ classes[0] = X86_64_SSEDF_CLASS;
+ return 1;
+ case 16:
+ classes[0] = X86_64_X87_CLASS;
+ classes[1] = X86_64_X87UP_CLASS;
+ return 2;
+ }
+ break;
+ case TYPE_CODE_INT:
+ case TYPE_CODE_PTR:
+ switch (bytes)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ if (bytes * 8 + bit_offset <= 32)
+ classes[0] = X86_64_INTEGERSI_CLASS;
+ else
+ classes[0] = X86_64_INTEGER_CLASS;
+ return 1;
+ case 16:
+ classes[0] = classes[1] = X86_64_INTEGER_CLASS;
+ return 2;
+ default:
+ break;
+ }
+ case TYPE_CODE_VOID:
+ return 0;
+ default: /* Avoid warning. */
+ break;
+ }
+ internal_error (__FILE__, __LINE__,
+ "classify_argument: unknown argument type");
+}
+
+/* Examine the argument and return set number of register required in each
+ class. Return 0 ifif parameter should be passed in memory. */
+
+static int
+examine_argument (enum x86_64_reg_class classes[MAX_CLASSES],
+ int n, int *int_nregs, int *sse_nregs)
+{
+ *int_nregs = 0;
+ *sse_nregs = 0;
+ if (!n)
+ return 0;
+ for (n--; n >= 0; n--)
+ switch (classes[n])
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ (*int_nregs)++;
+ break;
+ case X86_64_SSE_CLASS:
+ case X86_64_SSESF_CLASS:
+ case X86_64_SSEDF_CLASS:
+ (*sse_nregs)++;
+ break;
+ case X86_64_NO_CLASS:
+ case X86_64_SSEUP_CLASS:
+ case X86_64_X87_CLASS:
+ case X86_64_X87UP_CLASS:
+ break;
+ case X86_64_MEMORY_CLASS:
+ internal_error (__FILE__, __LINE__,
+ "examine_argument: unexpected memory class");
+ }
+ return 1;
+}
+
+#define RET_INT_REGS 2
+#define RET_SSE_REGS 2
+
+/* Check if the structure in value_type is returned in registers or in
+ memory. If this function returns 1, gdb will call STORE_STRUCT_RETURN and
+ EXTRACT_STRUCT_VALUE_ADDRESS else STORE_RETURN_VALUE and EXTRACT_RETURN_VALUE
+ will be used. */
+int
+x86_64_use_struct_convention (int gcc_p, struct type *value_type)
+{
+ enum x86_64_reg_class class[MAX_CLASSES];
+ int n = classify_argument (value_type, class, 0);
+ int needed_intregs;
+ int needed_sseregs;
+
+ return (!n ||
+ !examine_argument (class, n, &needed_intregs, &needed_sseregs) ||
+ needed_intregs > RET_INT_REGS || needed_sseregs > RET_SSE_REGS);
+}
+
+
+/* Extract from an array REGBUF containing the (raw) register state, a
+ function return value of TYPE, and copy that, in virtual format,
+ into VALBUF. */
+
+void
+x86_64_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ enum x86_64_reg_class class[MAX_CLASSES];
+ int n = classify_argument (type, class, 0);
+ int needed_intregs;
+ int needed_sseregs;
+ int intreg = 0;
+ int ssereg = 0;
+ int offset = 0;
+ int ret_int_r[RET_INT_REGS] = { RAX_REGNUM, RDX_REGNUM };
+ int ret_sse_r[RET_SSE_REGS] = { XMM0_REGNUM, XMM1_REGNUM };
+
+ if (!n ||
+ !examine_argument (class, n, &needed_intregs, &needed_sseregs) ||
+ needed_intregs > RET_INT_REGS || needed_sseregs > RET_SSE_REGS)
+ { /* memory class */
+ CORE_ADDR addr;
+ memcpy (&addr, regbuf, REGISTER_RAW_SIZE (RAX_REGNUM));
+ read_memory (addr, valbuf, TYPE_LENGTH (type));
+ return;
+ }
+ else
+ {
+ int i;
+ for (i = 0; i < n; i++)
+ {
+ switch (class[i])
+ {
+ case X86_64_NO_CLASS:
+ break;
+ case X86_64_INTEGER_CLASS:
+ memcpy (valbuf + offset,
+ regbuf + REGISTER_BYTE (ret_int_r[(intreg + 1) / 2]),
+ 8);
+ offset += 8;
+ intreg += 2;
+ break;
+ case X86_64_INTEGERSI_CLASS:
+ memcpy (valbuf + offset,
+ regbuf + REGISTER_BYTE (ret_int_r[intreg / 2]), 4);
+ offset += 8;
+ intreg++;
+ break;
+ case X86_64_SSEDF_CLASS:
+ case X86_64_SSESF_CLASS:
+ case X86_64_SSE_CLASS:
+ memcpy (valbuf + offset,
+ regbuf + REGISTER_BYTE (ret_sse_r[(ssereg + 1) / 2]),
+ 8);
+ offset += 8;
+ ssereg += 2;
+ break;
+ case X86_64_SSEUP_CLASS:
+ memcpy (valbuf + offset + 8,
+ regbuf + REGISTER_BYTE (ret_sse_r[ssereg / 2]), 8);
+ offset += 8;
+ ssereg++;
+ break;
+ case X86_64_X87_CLASS:
+ memcpy (valbuf + offset, regbuf + REGISTER_BYTE (FP0_REGNUM),
+ 8);
+ offset += 8;
+ break;
+ case X86_64_X87UP_CLASS:
+ memcpy (valbuf + offset,
+ regbuf + REGISTER_BYTE (FP0_REGNUM) + 8, 8);
+ offset += 8;
+ break;
+ case X86_64_MEMORY_CLASS:
+ default:
+ internal_error (__FILE__, __LINE__,
+ "Unexpected argument class");
+ }
+ }
+ }
+}
+
+/* Handled by unwind informations. */
+static void
+x86_64_frame_init_saved_regs (struct frame_info *fi)
+{
+}
+
+#define INT_REGS 6
+#define SSE_REGS 16
+
+CORE_ADDR
+x86_64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ int intreg = 0;
+ int ssereg = 0;
+ int i;
+ static int int_parameter_registers[INT_REGS] = {
+ 5 /* RDI */ , 4 /* RSI */ ,
+ 3 /* RDX */ , 2 /* RCX */ ,
+ 8 /* R8 */ , 9 /* R9 */
+ };
+ /* XMM0 - XMM15 */
+ static int sse_parameter_registers[SSE_REGS] = {
+ XMM1_REGNUM - 1, XMM1_REGNUM, XMM1_REGNUM + 1, XMM1_REGNUM + 2,
+ XMM1_REGNUM + 3, XMM1_REGNUM + 4, XMM1_REGNUM + 5, XMM1_REGNUM + 6,
+ XMM1_REGNUM + 7, XMM1_REGNUM + 8, XMM1_REGNUM + 9, XMM1_REGNUM + 10,
+ XMM1_REGNUM + 11, XMM1_REGNUM + 12, XMM1_REGNUM + 13, XMM1_REGNUM + 14
+ };
+ int stack_values_count = 0;
+ int *stack_values;
+ stack_values = alloca (nargs * sizeof (int));
+ for (i = 0; i < nargs; i++)
+ {
+ enum x86_64_reg_class class[MAX_CLASSES];
+ int n = classify_argument (args[i]->type, class, 0);
+ int needed_intregs;
+ int needed_sseregs;
+
+ if (!n ||
+ !examine_argument (class, n, &needed_intregs, &needed_sseregs)
+ || intreg / 2 + needed_intregs > INT_REGS
+ || ssereg / 2 + needed_sseregs > SSE_REGS)
+ { /* memory class */
+ stack_values[stack_values_count++] = i;
+ }
+ else
+ {
+ int j;
+ for (j = 0; j < n; j++)
+ {
+ int offset = 0;
+ switch (class[j])
+ {
+ case X86_64_NO_CLASS:
+ break;
+ case X86_64_INTEGER_CLASS:
+ write_register_gen (int_parameter_registers
+ [(intreg + 1) / 2],
+ VALUE_CONTENTS_ALL (args[i]) + offset);
+ offset += 8;
+ intreg += 2;
+ break;
+ case X86_64_INTEGERSI_CLASS:
+ write_register_gen (int_parameter_registers[intreg / 2],
+ VALUE_CONTENTS_ALL (args[i]) + offset);
+ offset += 8;
+ intreg++;
+ break;
+ case X86_64_SSEDF_CLASS:
+ case X86_64_SSESF_CLASS:
+ case X86_64_SSE_CLASS:
+ write_register_gen (sse_parameter_registers
+ [(ssereg + 1) / 2],
+ VALUE_CONTENTS_ALL (args[i]) + offset);
+ offset += 8;
+ ssereg += 2;
+ break;
+ case X86_64_SSEUP_CLASS:
+ write_register_gen (sse_parameter_registers[ssereg / 2],
+ VALUE_CONTENTS_ALL (args[i]) + offset);
+ offset += 8;
+ ssereg++;
+ break;
+ case X86_64_X87_CLASS:
+ case X86_64_MEMORY_CLASS:
+ stack_values[stack_values_count++] = i;
+ break;
+ case X86_64_X87UP_CLASS:
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "Unexpected argument class");
+ }
+ intreg += intreg % 2;
+ ssereg += ssereg % 2;
+ }
+ }
+ }
+ while (--stack_values_count >= 0)
+ {
+ struct value *arg = args[stack_values[stack_values_count]];
+ int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
+ len += 7;
+ len -= len % 8;
+ sp -= len;
+ write_memory (sp, VALUE_CONTENTS_ALL (arg), len);
+ }
+ return sp;
+}
+
+/* Write into the appropriate registers a function return value stored
+ in VALBUF of type TYPE, given in virtual format. */
+void
+x86_64_store_return_value (struct type *type, char *valbuf)
+{
+ int len = TYPE_LENGTH (type);
+
+ if (TYPE_CODE_FLT == TYPE_CODE (type))
+ {
+ /* Floating-point return values can be found in %st(0). */
+ if (len == TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT
+ && TARGET_LONG_DOUBLE_FORMAT == &floatformat_i387_ext)
+ {
+ /* Copy straight over. */
+ write_register_bytes (REGISTER_BYTE (FP0_REGNUM), valbuf,
+ FPU_REG_RAW_SIZE);
+ }
+ else
+ {
+ char buf[FPU_REG_RAW_SIZE];
+ DOUBLEST val;
+
+ /* Convert the value found in VALBUF to the extended
+ floating point format used by the FPU. This is probably
+ not exactly how it would happen on the target itself, but
+ it is the best we can do. */
+ val = extract_floating (valbuf, TYPE_LENGTH (type));
+ floatformat_from_doublest (&floatformat_i387_ext, &val, buf);
+ write_register_bytes (REGISTER_BYTE (FP0_REGNUM), buf,
+ FPU_REG_RAW_SIZE);
+ }
+ }
+ else
+ {
+ int low_size = REGISTER_RAW_SIZE (0);
+ int high_size = REGISTER_RAW_SIZE (1);
+
+ if (len <= low_size)
+ write_register_bytes (REGISTER_BYTE (0), valbuf, len);
+ else if (len <= (low_size + high_size))
+ {
+ write_register_bytes (REGISTER_BYTE (0), valbuf, low_size);
+ write_register_bytes (REGISTER_BYTE (1),
+ valbuf + low_size, len - low_size);
+ }
+ else
+ internal_error (__FILE__, __LINE__,
+ "Cannot store return value of %d bytes long.", len);
+ }
+}
+
+
+static char *
+x86_64_register_name (int reg_nr)
+{
+ if (reg_nr < 0 || reg_nr >= X86_64_NUM_REGS)
+ return NULL;
+ return x86_64_register_info_table[reg_nr].name;
+}
+
+
+
+/* We have two flavours of disassembly. The machinery on this page
+ deals with switching between those. */
+
+static int
+gdb_print_insn_x86_64 (bfd_vma memaddr, disassemble_info * info)
+{
+ if (disassembly_flavour == att_flavour)
+ return print_insn_i386_att (memaddr, info);
+ else if (disassembly_flavour == intel_flavour)
+ return print_insn_i386_intel (memaddr, info);
+ /* Never reached -- disassembly_flavour is always either att_flavour
+ or intel_flavour. */
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+}
+
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function. */
+void
+x86_64_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ write_register (RDI_REGNUM, addr);
+}
+
+int
+x86_64_frameless_function_invocation (struct frame_info *frame)
+{
+ return 0;
+}
+
+/* If a function with debugging information and known beginning
+ is detected, we will return pc of the next line in the source
+ code. With this approach we effectively skip the prolog. */
+
+#define PROLOG_BUFSIZE 4
+CORE_ADDR
+x86_64_skip_prologue (CORE_ADDR pc)
+{
+ int i, firstline, currline;
+ struct symtab_and_line v_sal;
+ struct symbol *v_function;
+ CORE_ADDR salendaddr = 0, endaddr = 0;
+
+ /* We will handle only functions beginning with:
+ 55 pushq %rbp
+ 48 89 e5 movq %rsp,%rbp
+ */
+ unsigned char prolog_expect[PROLOG_BUFSIZE] = { 0x55, 0x48, 0x89, 0xe5 },
+ prolog_buf[PROLOG_BUFSIZE];
+
+ read_memory (pc, (char *) prolog_buf, PROLOG_BUFSIZE);
+
+ /* First check, whether pc points to pushq %rbp, movq %rsp,%rbp. */
+ for (i = 0; i < PROLOG_BUFSIZE; i++)
+ if (prolog_expect[i] != prolog_buf[i])
+ return pc; /* ... no, it doesn't. Nothing to skip. */
+
+ /* OK, we have found the prologue and want PC of the first
+ non-prologue instruction. */
+ pc += PROLOG_BUFSIZE;
+
+ v_function = find_pc_function (pc);
+ v_sal = find_pc_line (pc, 0);
+
+ /* If pc doesn't point to a function with debuginfo,
+ some of the following may be NULL. */
+ if (!v_function || !v_function->ginfo.value.block || !v_sal.symtab)
+ return pc;
+
+ firstline = v_sal.line;
+ currline = firstline;
+ salendaddr = v_sal.end;
+ endaddr = v_function->ginfo.value.block->endaddr;
+
+ for (i = 0; i < v_sal.symtab->linetable->nitems; i++)
+ if (v_sal.symtab->linetable->item[i].line > firstline
+ && v_sal.symtab->linetable->item[i].pc >= salendaddr
+ && v_sal.symtab->linetable->item[i].pc < endaddr)
+ {
+ pc = v_sal.symtab->linetable->item[i].pc;
+ currline = v_sal.symtab->linetable->item[i].line;
+ break;
+ }
+
+ return pc;
+}
+
+/* Sequence of bytes for breakpoint instruction. */
+static unsigned char *
+x86_64_breakpoint_from_pc (CORE_ADDR * pc, int *lenptr)
+{
+ static unsigned char breakpoint[] = { 0xcc };
+ *lenptr = 1;
+ return breakpoint;
+}
+
+static struct gdbarch *
+x86_64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch *gdbarch;
+ struct gdbarch_tdep *tdep;
+ int i, sum;
+
+ /* Find a candidate among the list of pre-declared architectures. */
+ for (arches = gdbarch_list_lookup_by_info (arches, &info);
+ arches != NULL;
+ arches = gdbarch_list_lookup_by_info (arches->next, &info))
+ {
+ switch (info.bfd_arch_info->mach)
+ {
+ case bfd_mach_x86_64:
+ case bfd_mach_x86_64_intel_syntax:
+ switch (gdbarch_bfd_arch_info (arches->gdbarch)->mach)
+ {
+ case bfd_mach_x86_64:
+ case bfd_mach_x86_64_intel_syntax:
+ return arches->gdbarch;
+ case bfd_mach_i386_i386:
+ case bfd_mach_i386_i8086:
+ case bfd_mach_i386_i386_intel_syntax:
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "x86_64_gdbarch_init: unknown machine type");
+ }
+ break;
+ case bfd_mach_i386_i386:
+ case bfd_mach_i386_i8086:
+ case bfd_mach_i386_i386_intel_syntax:
+ switch (gdbarch_bfd_arch_info (arches->gdbarch)->mach)
+ {
+ case bfd_mach_x86_64:
+ case bfd_mach_x86_64_intel_syntax:
+ break;
+ case bfd_mach_i386_i386:
+ case bfd_mach_i386_i8086:
+ case bfd_mach_i386_i386_intel_syntax:
+ return arches->gdbarch;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "x86_64_gdbarch_init: unknown machine type");
+ }
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "x86_64_gdbarch_init: unknown machine type");
+ }
+ }
+
+ tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ switch (info.bfd_arch_info->mach)
+ {
+ case bfd_mach_x86_64:
+ case bfd_mach_x86_64_intel_syntax:
+ tdep->num_xmm_regs = 16;
+ break;
+ case bfd_mach_i386_i386:
+ case bfd_mach_i386_i8086:
+ case bfd_mach_i386_i386_intel_syntax:
+ /* This is place for definition of i386 target vector. */
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "x86_64_gdbarch_init: unknown machine type");
+ }
+
+ set_gdbarch_long_bit (gdbarch, 64);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+ set_gdbarch_ptr_bit (gdbarch, 64);
+
+ set_gdbarch_long_double_format (gdbarch, &floatformat_i387_ext);
+
+ set_gdbarch_num_regs (gdbarch, X86_64_NUM_REGS);
+ set_gdbarch_register_name (gdbarch, x86_64_register_name);
+ set_gdbarch_register_size (gdbarch, 8);
+ set_gdbarch_register_raw_size (gdbarch, x86_64_register_raw_size);
+ set_gdbarch_max_register_raw_size (gdbarch, 16);
+ set_gdbarch_register_byte (gdbarch, x86_64_register_byte);
+
+ /* Total amount of space needed to store our copies of the machine's register
+ (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS + SIZEOF_SSE_REGS) */
+ for (i = 0, sum = 0; i < X86_64_NUM_REGS; i++)
+ sum += x86_64_register_info_table[i].size;
+ set_gdbarch_register_bytes (gdbarch, sum);
+ set_gdbarch_register_virtual_size (gdbarch, generic_register_size);
+ set_gdbarch_max_register_virtual_size (gdbarch, 16);
+
+ set_gdbarch_register_virtual_type (gdbarch, x86_64_register_virtual_type);
+
+ set_gdbarch_register_convertible (gdbarch, x86_64_register_convertible);
+ set_gdbarch_register_convert_to_virtual (gdbarch,
+ x86_64_register_convert_to_virtual);
+ set_gdbarch_register_convert_to_raw (gdbarch,
+ x86_64_register_convert_to_raw);
+
+/* Register numbers of various important registers. */
+ set_gdbarch_sp_regnum (gdbarch, 7); /* (rsp) Contains address of top of stack. */
+ set_gdbarch_fp_regnum (gdbarch, 6); /* (rbp) */
+ set_gdbarch_pc_regnum (gdbarch, 16); /* (rip) Contains program counter. */
+
+ set_gdbarch_fp0_regnum (gdbarch, X86_64_NUM_GREGS); /* First FPU floating-point register. */
+
+ set_gdbarch_read_fp (gdbarch, cfi_read_fp);
+
+/* Discard from the stack the innermost frame, restoring all registers. */
+ set_gdbarch_pop_frame (gdbarch, x86_64_pop_frame);
+
+ /* FRAME_CHAIN takes a frame's nominal address and produces the frame's
+ chain-pointer. */
+ set_gdbarch_frame_chain (gdbarch, cfi_frame_chain);
+
+ set_gdbarch_frameless_function_invocation (gdbarch,
+ x86_64_frameless_function_invocation);
+ set_gdbarch_frame_saved_pc (gdbarch, x86_64_linux_frame_saved_pc);
+
+ set_gdbarch_frame_args_address (gdbarch, default_frame_address);
+ set_gdbarch_frame_locals_address (gdbarch, default_frame_address);
+
+/* Return number of bytes at start of arglist that are not really args. */
+ set_gdbarch_frame_args_skip (gdbarch, 8);
+
+ set_gdbarch_frame_init_saved_regs (gdbarch, x86_64_frame_init_saved_regs);
+
+/* Frame pc initialization is handled by unwind informations. */
+ set_gdbarch_init_frame_pc (gdbarch, cfi_init_frame_pc);
+
+/* Initialization of unwind informations. */
+ set_gdbarch_init_extra_frame_info (gdbarch, cfi_init_extra_frame_info);
+
+/* Getting saved registers is handled by unwind informations. */
+ set_gdbarch_get_saved_register (gdbarch, cfi_get_saved_register);
+
+ set_gdbarch_frame_init_saved_regs (gdbarch, x86_64_frame_init_saved_regs);
+
+/* Cons up virtual frame pointer for trace */
+ set_gdbarch_virtual_frame_pointer (gdbarch, cfi_virtual_frame_pointer);
+
+
+ set_gdbarch_frame_chain_valid (gdbarch, generic_file_frame_chain_valid);
+
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
+ set_gdbarch_call_dummy_words (gdbarch, 0);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+ set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
+ set_gdbarch_push_return_address (gdbarch, x86_64_push_return_address);
+ set_gdbarch_push_arguments (gdbarch, x86_64_push_arguments);
+
+/* Return number of args passed to a frame, no way to tell. */
+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+/* Don't use default structure extract routine */
+ set_gdbarch_extract_struct_value_address (gdbarch, 0);
+
+/* If USE_STRUCT_CONVENTION retruns 0, then gdb uses STORE_RETURN_VALUE
+ and EXTRACT_RETURN_VALUE to store/fetch the functions return value. It is
+ the case when structure is returned in registers. */
+ set_gdbarch_use_struct_convention (gdbarch, x86_64_use_struct_convention);
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function. */
+ set_gdbarch_store_struct_return (gdbarch, x86_64_store_struct_return);
+
+/* Extract from an array REGBUF containing the (raw) register state
+ a function return value of type TYPE, and copy that, in virtual format,
+ into VALBUF. */
+ set_gdbarch_extract_return_value (gdbarch, x86_64_extract_return_value);
+
+
+/* Write into the appropriate registers a function return value stored
+ in VALBUF of type TYPE, given in virtual format. */
+ set_gdbarch_store_return_value (gdbarch, x86_64_store_return_value);
+
+
+/* Offset from address of function to start of its code. */
+ set_gdbarch_function_start_offset (gdbarch, 0);
+
+ set_gdbarch_skip_prologue (gdbarch, x86_64_skip_prologue);
+
+ set_gdbarch_saved_pc_after_call (gdbarch, x86_64_linux_saved_pc_after_call);
+
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+
+ set_gdbarch_breakpoint_from_pc (gdbarch,
+ (gdbarch_breakpoint_from_pc_ftype *)
+ x86_64_breakpoint_from_pc);
+
+
+/* Amount PC must be decremented by after a breakpoint. This is often the
+ number of bytes in BREAKPOINT but not always. */
+ set_gdbarch_decr_pc_after_break (gdbarch, 1);
+
+/* Use dwarf2 debug frame informations. */
+ set_gdbarch_dwarf2_build_frame_info (gdbarch, dwarf2_build_frame_info);
+ set_gdbarch_dwarf2_reg_to_regnum (gdbarch, x86_64_dwarf2_reg_to_regnum);
+
+ return gdbarch;
+}
+
+void
+_initialize_x86_64_tdep (void)
+{
+ register_gdbarch_init (bfd_arch_i386, x86_64_gdbarch_init);
+
+ /* Initialize the table saying where each register starts in the
+ register file. */
+ {
+ int i, offset;
+
+ offset = 0;
+ for (i = 0; i < X86_64_NUM_REGS; i++)
+ {
+ x86_64_register_byte_table[i] = offset;
+ offset += x86_64_register_info_table[i].size;
+ }
+ }
+
+ tm_print_insn = gdb_print_insn_x86_64;
+ tm_print_insn_info.mach = bfd_lookup_arch (bfd_arch_i386, 3)->mach;
+
+ /* Add the variable that controls the disassembly flavour. */
+ {
+ struct cmd_list_element *new_cmd;
+
+ new_cmd = add_set_enum_cmd ("disassembly-flavour", no_class,
+ valid_flavours, &disassembly_flavour, "\
+Set the disassembly flavour, the valid values are \"att\" and \"intel\", \
+and the default value is \"att\".", &setlist);
+ add_show_from_set (new_cmd, &showlist);
+ }
+}
diff --git a/gdb/x86-64-tdep.h b/gdb/x86-64-tdep.h
new file mode 100644
index 00000000000..d15b8e71e7f
--- /dev/null
+++ b/gdb/x86-64-tdep.h
@@ -0,0 +1,34 @@
+/* Target-dependent code for GDB, the GNU debugger.
+ Copyright 2001
+ Free Software Foundation, Inc.
+ Contributed by Jiri Smid, SuSE Labs.
+
+ 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. */
+
+#ifndef X86_64_TDEP_H
+#define X86_64_TDEP_H
+
+#include "i386-tdep.h"
+
+extern int x86_64_num_regs;
+extern int x86_64_num_gregs;
+
+gdbarch_frame_saved_pc_ftype x86_64_linux_frame_saved_pc;
+gdbarch_saved_pc_after_call_ftype x86_64_linux_saved_pc_after_call;
+
+#endif
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
new file mode 100644
index 00000000000..d8781119774
--- /dev/null
+++ b/gdb/xcoffread.c
@@ -0,0 +1,3048 @@
+/* Read AIX xcoff symbol tables and convert to internal format, for GDB.
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+ Derived from coffread.c, dbxread.c, and a lot of hacking.
+ Contributed by IBM Corporation.
+
+ 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 "defs.h"
+#include "bfd.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include "gdb_string.h"
+
+#include <sys/param.h>
+#ifndef NO_SYS_FILE
+#include <sys/file.h>
+#endif
+#include "gdb_stat.h"
+
+#include "coff/internal.h"
+#include "libcoff.h" /* FIXME, internal data from BFD */
+#include "coff/xcoff.h"
+#include "libxcoff.h"
+#include "coff/rs6000.h"
+
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "buildsym.h"
+#include "stabsread.h"
+#include "expression.h"
+#include "complaints.h"
+
+#include "gdb-stabs.h"
+
+/* For interface with stabsread.c. */
+#include "aout/stab_gnu.h"
+
+
+/* We put a pointer to this structure in the read_symtab_private field
+ of the psymtab. */
+
+struct symloc
+ {
+
+ /* First symbol number for this file. */
+
+ int first_symnum;
+
+ /* Number of symbols in the section of the symbol table devoted to
+ this file's symbols (actually, the section bracketed may contain
+ more than just this file's symbols). If numsyms is 0, the only
+ reason for this thing's existence is the dependency list. Nothing
+ else will happen when it is read in. */
+
+ int numsyms;
+
+ /* Position of the start of the line number information for this psymtab. */
+ unsigned int lineno_off;
+ };
+
+/* Remember what we deduced to be the source language of this psymtab. */
+
+static enum language psymtab_language = language_unknown;
+
+
+/* Simplified internal version of coff symbol table information */
+
+struct coff_symbol
+ {
+ char *c_name;
+ int c_symnum; /* symbol number of this entry */
+ int c_naux; /* 0 if syment only, 1 if syment + auxent */
+ long c_value;
+ unsigned char c_sclass;
+ int c_secnum;
+ unsigned int c_type;
+ };
+
+/* last function's saved coff symbol `cs' */
+
+static struct coff_symbol fcn_cs_saved;
+
+static bfd *symfile_bfd;
+
+/* Core address of start and end of text of current source file.
+ This is calculated from the first function seen after a C_FILE
+ symbol. */
+
+
+static CORE_ADDR cur_src_end_addr;
+
+/* Core address of the end of the first object file. */
+
+static CORE_ADDR first_object_file_end;
+
+/* initial symbol-table-debug-string vector length */
+
+#define INITIAL_STABVECTOR_LENGTH 40
+
+/* Nonzero if within a function (so symbols should be local,
+ if nothing says specifically). */
+
+int within_function;
+
+/* Size of a COFF symbol. I think it is always 18, so I'm not sure
+ there is any reason not to just use a #define, but might as well
+ ask BFD for the size and store it here, I guess. */
+
+static unsigned local_symesz;
+
+struct coff_symfile_info
+ {
+ file_ptr min_lineno_offset; /* Where in file lowest line#s are */
+ file_ptr max_lineno_offset; /* 1+last byte of line#s in file */
+
+ /* Pointer to the string table. */
+ char *strtbl;
+
+ /* Pointer to debug section. */
+ char *debugsec;
+
+ /* Pointer to the a.out symbol table. */
+ char *symtbl;
+
+ /* Number of symbols in symtbl. */
+ int symtbl_num_syms;
+
+ /* Offset in data section to TOC anchor. */
+ CORE_ADDR toc_offset;
+ };
+
+static struct complaint storclass_complaint =
+{"Unexpected storage class: %d", 0, 0};
+
+static struct complaint bf_notfound_complaint =
+{"line numbers off, `.bf' symbol not found", 0, 0};
+
+static struct complaint ef_complaint =
+{"Mismatched .ef symbol ignored starting at symnum %d", 0, 0};
+
+static struct complaint eb_complaint =
+{"Mismatched .eb symbol ignored starting at symnum %d", 0, 0};
+
+static void xcoff_initial_scan (struct objfile *, int);
+
+static void scan_xcoff_symtab (struct objfile *);
+
+static char *xcoff_next_symbol_text (struct objfile *);
+
+static void record_include_begin (struct coff_symbol *);
+
+static void
+enter_line_range (struct subfile *, unsigned, unsigned,
+ CORE_ADDR, CORE_ADDR, unsigned *);
+
+static void init_stringtab (bfd *, file_ptr, struct objfile *);
+
+static void xcoff_symfile_init (struct objfile *);
+
+static void xcoff_new_init (struct objfile *);
+
+static void xcoff_symfile_finish (struct objfile *);
+
+static void
+xcoff_symfile_offsets (struct objfile *, struct section_addr_info *addrs);
+
+static void find_linenos (bfd *, sec_ptr, PTR);
+
+static char *coff_getfilename (union internal_auxent *, struct objfile *);
+
+static void read_symbol (struct internal_syment *, int);
+
+static int read_symbol_lineno (int);
+
+static CORE_ADDR read_symbol_nvalue (int);
+
+static struct symbol *process_xcoff_symbol (struct coff_symbol *,
+ struct objfile *);
+
+static void read_xcoff_symtab (struct partial_symtab *);
+
+#if 0
+static void add_stab_to_list (char *, struct pending_stabs **);
+#endif
+
+static int compare_lte (const void *, const void *);
+
+static struct linetable *arrange_linetable (struct linetable *);
+
+static void record_include_end (struct coff_symbol *);
+
+static void process_linenos (CORE_ADDR, CORE_ADDR);
+
+
+/* Translate from a COFF section number (target_index) to a SECT_OFF_*
+ code. */
+static int secnum_to_section (int, struct objfile *);
+static asection *secnum_to_bfd_section (int, struct objfile *);
+
+struct find_targ_sec_arg
+ {
+ int targ_index;
+ int *resultp;
+ asection **bfd_sect;
+ struct objfile *objfile;
+ };
+
+static void find_targ_sec (bfd *, asection *, void *);
+
+static void
+find_targ_sec (bfd *abfd, asection *sect, PTR obj)
+{
+ struct find_targ_sec_arg *args = (struct find_targ_sec_arg *) obj;
+ struct objfile *objfile = args->objfile;
+ if (sect->target_index == args->targ_index)
+ {
+ /* This is the section. Figure out what SECT_OFF_* code it is. */
+ if (bfd_get_section_flags (abfd, sect) & SEC_CODE)
+ *args->resultp = SECT_OFF_TEXT (objfile);
+ else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
+ *args->resultp = SECT_OFF_DATA (objfile);
+ else
+ *args->resultp = sect->index;
+ *args->bfd_sect = sect;
+ }
+}
+
+/* Return the section number (SECT_OFF_*) that CS points to. */
+static int
+secnum_to_section (int secnum, struct objfile *objfile)
+{
+ int off = SECT_OFF_TEXT (objfile);
+ asection *sect = NULL;
+ struct find_targ_sec_arg args;
+ args.targ_index = secnum;
+ args.resultp = &off;
+ args.bfd_sect = &sect;
+ args.objfile = objfile;
+ bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
+ return off;
+}
+
+/* Return the BFD section that CS points to. */
+static asection *
+secnum_to_bfd_section (int secnum, struct objfile *objfile)
+{
+ int off = SECT_OFF_TEXT (objfile);
+ asection *sect = NULL;
+ struct find_targ_sec_arg args;
+ args.targ_index = secnum;
+ args.resultp = &off;
+ args.bfd_sect = &sect;
+ args.objfile = objfile;
+ bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
+ return sect;
+}
+
+/* add a given stab string into given stab vector. */
+
+#if 0
+
+static void
+add_stab_to_list (char *stabname, struct pending_stabs **stabvector)
+{
+ if (*stabvector == NULL)
+ {
+ *stabvector = (struct pending_stabs *)
+ xmalloc (sizeof (struct pending_stabs) +
+ INITIAL_STABVECTOR_LENGTH * sizeof (char *));
+ (*stabvector)->count = 0;
+ (*stabvector)->length = INITIAL_STABVECTOR_LENGTH;
+ }
+ else if ((*stabvector)->count >= (*stabvector)->length)
+ {
+ (*stabvector)->length += INITIAL_STABVECTOR_LENGTH;
+ *stabvector = (struct pending_stabs *)
+ xrealloc ((char *) *stabvector, sizeof (struct pending_stabs) +
+ (*stabvector)->length * sizeof (char *));
+ }
+ (*stabvector)->stab[(*stabvector)->count++] = stabname;
+}
+
+#endif
+ /* *INDENT-OFF* */
+/* Linenos are processed on a file-by-file basis.
+
+ Two reasons:
+
+ 1) xlc (IBM's native c compiler) postpones static function code
+ emission to the end of a compilation unit. This way it can
+ determine if those functions (statics) are needed or not, and
+ can do some garbage collection (I think). This makes line
+ numbers and corresponding addresses unordered, and we end up
+ with a line table like:
+
+
+ lineno addr
+ foo() 10 0x100
+ 20 0x200
+ 30 0x300
+
+ foo3() 70 0x400
+ 80 0x500
+ 90 0x600
+
+ static foo2()
+ 40 0x700
+ 50 0x800
+ 60 0x900
+
+ and that breaks gdb's binary search on line numbers, if the
+ above table is not sorted on line numbers. And that sort
+ should be on function based, since gcc can emit line numbers
+ like:
+
+ 10 0x100 - for the init/test part of a for stmt.
+ 20 0x200
+ 30 0x300
+ 10 0x400 - for the increment part of a for stmt.
+
+ arrange_linetable() will do this sorting.
+
+ 2) aix symbol table might look like:
+
+ c_file // beginning of a new file
+ .bi // beginning of include file
+ .ei // end of include file
+ .bi
+ .ei
+
+ basically, .bi/.ei pairs do not necessarily encapsulate
+ their scope. They need to be recorded, and processed later
+ on when we come the end of the compilation unit.
+ Include table (inclTable) and process_linenos() handle
+ that. */
+/* *INDENT-ON* */
+
+
+
+/* compare line table entry addresses. */
+
+static int
+compare_lte (const void *lte1p, const void *lte2p)
+{
+ struct linetable_entry *lte1 = (struct linetable_entry *) lte1p;
+ struct linetable_entry *lte2 = (struct linetable_entry *) lte2p;
+ return lte1->pc - lte2->pc;
+}
+
+/* Given a line table with function entries are marked, arrange its functions
+ in ascending order and strip off function entry markers and return it in
+ a newly created table. If the old one is good enough, return the old one. */
+/* FIXME: I think all this stuff can be replaced by just passing
+ sort_linevec = 1 to end_symtab. */
+
+static struct linetable *
+arrange_linetable (struct linetable *oldLineTb)
+{
+ int ii, jj, newline, /* new line count */
+ function_count; /* # of functions */
+
+ struct linetable_entry *fentry; /* function entry vector */
+ int fentry_size; /* # of function entries */
+ struct linetable *newLineTb; /* new line table */
+
+#define NUM_OF_FUNCTIONS 20
+
+ fentry_size = NUM_OF_FUNCTIONS;
+ fentry = (struct linetable_entry *)
+ xmalloc (fentry_size * sizeof (struct linetable_entry));
+
+ for (function_count = 0, ii = 0; ii < oldLineTb->nitems; ++ii)
+ {
+
+ if (oldLineTb->item[ii].line == 0)
+ { /* function entry found. */
+
+ if (function_count >= fentry_size)
+ { /* make sure you have room. */
+ fentry_size *= 2;
+ fentry = (struct linetable_entry *)
+ xrealloc (fentry, fentry_size * sizeof (struct linetable_entry));
+ }
+ fentry[function_count].line = ii;
+ fentry[function_count].pc = oldLineTb->item[ii].pc;
+ ++function_count;
+ }
+ }
+
+ if (function_count == 0)
+ {
+ xfree (fentry);
+ return oldLineTb;
+ }
+ else if (function_count > 1)
+ qsort (fentry, function_count, sizeof (struct linetable_entry), compare_lte);
+
+ /* allocate a new line table. */
+ newLineTb = (struct linetable *)
+ xmalloc
+ (sizeof (struct linetable) +
+ (oldLineTb->nitems - function_count) * sizeof (struct linetable_entry));
+
+ /* if line table does not start with a function beginning, copy up until
+ a function begin. */
+
+ newline = 0;
+ if (oldLineTb->item[0].line != 0)
+ for (newline = 0;
+ newline < oldLineTb->nitems && oldLineTb->item[newline].line; ++newline)
+ newLineTb->item[newline] = oldLineTb->item[newline];
+
+ /* Now copy function lines one by one. */
+
+ for (ii = 0; ii < function_count; ++ii)
+ {
+ for (jj = fentry[ii].line + 1;
+ jj < oldLineTb->nitems && oldLineTb->item[jj].line != 0;
+ ++jj, ++newline)
+ newLineTb->item[newline] = oldLineTb->item[jj];
+ }
+ xfree (fentry);
+ newLineTb->nitems = oldLineTb->nitems - function_count;
+ return newLineTb;
+}
+
+/* include file support: C_BINCL/C_EINCL pairs will be kept in the
+ following `IncludeChain'. At the end of each symtab (end_symtab),
+ we will determine if we should create additional symtab's to
+ represent if (the include files. */
+
+
+typedef struct _inclTable
+{
+ char *name; /* include filename */
+
+ /* Offsets to the line table. end points to the last entry which is
+ part of this include file. */
+ int begin, end;
+
+ struct subfile *subfile;
+ unsigned funStartLine; /* start line # of its function */
+}
+InclTable;
+
+#define INITIAL_INCLUDE_TABLE_LENGTH 20
+static InclTable *inclTable; /* global include table */
+static int inclIndx; /* last entry to table */
+static int inclLength; /* table length */
+static int inclDepth; /* nested include depth */
+
+static void allocate_include_entry (void);
+
+static void
+record_include_begin (struct coff_symbol *cs)
+{
+ if (inclDepth)
+ {
+ /* In xcoff, we assume include files cannot be nested (not in .c files
+ of course, but in corresponding .s files.). */
+
+ /* This can happen with old versions of GCC.
+ GCC 2.3.3-930426 does not exhibit this on a test case which
+ a user said produced the message for him. */
+ static struct complaint msg =
+ {"Nested C_BINCL symbols", 0, 0};
+ complain (&msg);
+ }
+ ++inclDepth;
+
+ allocate_include_entry ();
+
+ inclTable[inclIndx].name = cs->c_name;
+ inclTable[inclIndx].begin = cs->c_value;
+}
+
+static void
+record_include_end (struct coff_symbol *cs)
+{
+ InclTable *pTbl;
+
+ if (inclDepth == 0)
+ {
+ static struct complaint msg =
+ {"Mismatched C_BINCL/C_EINCL pair", 0, 0};
+ complain (&msg);
+ }
+
+ allocate_include_entry ();
+
+ pTbl = &inclTable[inclIndx];
+ pTbl->end = cs->c_value;
+
+ --inclDepth;
+ ++inclIndx;
+}
+
+static void
+allocate_include_entry (void)
+{
+ if (inclTable == NULL)
+ {
+ inclTable = (InclTable *)
+ xmalloc (sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH);
+ memset (inclTable,
+ '\0', sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH);
+ inclLength = INITIAL_INCLUDE_TABLE_LENGTH;
+ inclIndx = 0;
+ }
+ else if (inclIndx >= inclLength)
+ {
+ inclLength += INITIAL_INCLUDE_TABLE_LENGTH;
+ inclTable = (InclTable *)
+ xrealloc (inclTable, sizeof (InclTable) * inclLength);
+ memset (inclTable + inclLength - INITIAL_INCLUDE_TABLE_LENGTH,
+ '\0', sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH);
+ }
+}
+
+/* Global variable to pass the psymtab down to all the routines involved
+ in psymtab to symtab processing. */
+static struct partial_symtab *this_symtab_psymtab;
+
+/* given the start and end addresses of a compilation unit (or a csect,
+ at times) process its lines and create appropriate line vectors. */
+
+static void
+process_linenos (CORE_ADDR start, CORE_ADDR end)
+{
+ int offset, ii;
+ file_ptr max_offset =
+ ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private)
+ ->max_lineno_offset;
+
+ /* subfile structure for the main compilation unit. */
+ struct subfile main_subfile;
+
+ /* In the main source file, any time we see a function entry, we
+ reset this variable to function's absolute starting line number.
+ All the following line numbers in the function are relative to
+ this, and we record absolute line numbers in record_line(). */
+
+ unsigned int main_source_baseline = 0;
+
+ unsigned *firstLine;
+
+ offset =
+ ((struct symloc *) this_symtab_psymtab->read_symtab_private)->lineno_off;
+ if (offset == 0)
+ goto return_after_cleanup;
+
+ memset (&main_subfile, '\0', sizeof (main_subfile));
+
+ if (inclIndx == 0)
+ /* All source lines were in the main source file. None in include files. */
+
+ enter_line_range (&main_subfile, offset, 0, start, end,
+ &main_source_baseline);
+
+ else
+ {
+ /* There was source with line numbers in include files. */
+
+ int linesz =
+ coff_data (this_symtab_psymtab->objfile->obfd)->local_linesz;
+ main_source_baseline = 0;
+
+ for (ii = 0; ii < inclIndx; ++ii)
+ {
+ struct subfile *tmpSubfile;
+
+ /* If there is main file source before include file, enter it. */
+ if (offset < inclTable[ii].begin)
+ {
+ enter_line_range
+ (&main_subfile, offset, inclTable[ii].begin - linesz,
+ start, 0, &main_source_baseline);
+ }
+
+ /* Have a new subfile for the include file. */
+
+ tmpSubfile = inclTable[ii].subfile =
+ (struct subfile *) xmalloc (sizeof (struct subfile));
+
+ memset (tmpSubfile, '\0', sizeof (struct subfile));
+ firstLine = &(inclTable[ii].funStartLine);
+
+ /* Enter include file's lines now. */
+ enter_line_range (tmpSubfile, inclTable[ii].begin,
+ inclTable[ii].end, start, 0, firstLine);
+
+ if (offset <= inclTable[ii].end)
+ offset = inclTable[ii].end + linesz;
+ }
+
+ /* All the include files' line have been processed at this point. Now,
+ enter remaining lines of the main file, if any left. */
+ if (offset < max_offset + 1 - linesz)
+ {
+ enter_line_range (&main_subfile, offset, 0, start, end,
+ &main_source_baseline);
+ }
+ }
+
+ /* Process main file's line numbers. */
+ if (main_subfile.line_vector)
+ {
+ struct linetable *lineTb, *lv;
+
+ lv = main_subfile.line_vector;
+
+ /* Line numbers are not necessarily ordered. xlc compilation will
+ put static function to the end. */
+
+ lineTb = arrange_linetable (lv);
+ if (lv == lineTb)
+ {
+ current_subfile->line_vector = (struct linetable *)
+ xrealloc (lv, (sizeof (struct linetable)
+ + lv->nitems * sizeof (struct linetable_entry)));
+ }
+ else
+ {
+ xfree (lv);
+ current_subfile->line_vector = lineTb;
+ }
+
+ current_subfile->line_vector_length =
+ current_subfile->line_vector->nitems;
+ }
+
+ /* Now, process included files' line numbers. */
+
+ for (ii = 0; ii < inclIndx; ++ii)
+ {
+ if ((inclTable[ii].subfile)->line_vector) /* Useless if!!! FIXMEmgo */
+ {
+ struct linetable *lineTb, *lv;
+
+ lv = (inclTable[ii].subfile)->line_vector;
+
+ /* Line numbers are not necessarily ordered. xlc compilation will
+ put static function to the end. */
+
+ lineTb = arrange_linetable (lv);
+
+ push_subfile ();
+
+ /* For the same include file, we might want to have more than one
+ subfile. This happens if we have something like:
+
+ ......
+ #include "foo.h"
+ ......
+ #include "foo.h"
+ ......
+
+ while foo.h including code in it. (stupid but possible)
+ Since start_subfile() looks at the name and uses an
+ existing one if finds, we need to provide a fake name and
+ fool it. */
+
+#if 0
+ start_subfile (inclTable[ii].name, (char *) 0);
+#else
+ {
+ /* Pick a fake name that will produce the same results as this
+ one when passed to deduce_language_from_filename. Kludge on
+ top of kludge. */
+ char *fakename = strrchr (inclTable[ii].name, '.');
+ if (fakename == NULL)
+ fakename = " ?";
+ start_subfile (fakename, (char *) 0);
+ xfree (current_subfile->name);
+ }
+ current_subfile->name = xstrdup (inclTable[ii].name);
+#endif
+
+ if (lv == lineTb)
+ {
+ current_subfile->line_vector =
+ (struct linetable *) xrealloc
+ (lv, (sizeof (struct linetable)
+ + lv->nitems * sizeof (struct linetable_entry)));
+
+ }
+ else
+ {
+ xfree (lv);
+ current_subfile->line_vector = lineTb;
+ }
+
+ current_subfile->line_vector_length =
+ current_subfile->line_vector->nitems;
+ start_subfile (pop_subfile (), (char *) 0);
+ }
+ }
+
+return_after_cleanup:
+
+ /* We don't want to keep alloc/free'ing the global include file table. */
+ inclIndx = 0;
+
+ /* Start with a fresh subfile structure for the next file. */
+ memset (&main_subfile, '\0', sizeof (struct subfile));
+}
+
+void
+aix_process_linenos (void)
+{
+ /* process line numbers and enter them into line vector */
+ process_linenos (last_source_start_addr, cur_src_end_addr);
+}
+
+
+/* Enter a given range of lines into the line vector.
+ can be called in the following two ways:
+ enter_line_range (subfile, beginoffset, endoffset, startaddr, 0, firstLine) or
+ enter_line_range (subfile, beginoffset, 0, startaddr, endaddr, firstLine)
+
+ endoffset points to the last line table entry that we should pay
+ attention to. */
+
+static void
+enter_line_range (struct subfile *subfile, unsigned beginoffset, unsigned endoffset, /* offsets to line table */
+ CORE_ADDR startaddr, /* offsets to line table */
+ CORE_ADDR endaddr, unsigned *firstLine)
+{
+ unsigned int curoffset;
+ CORE_ADDR addr;
+ void *ext_lnno;
+ struct internal_lineno int_lnno;
+ unsigned int limit_offset;
+ bfd *abfd;
+ int linesz;
+
+ if (endoffset == 0 && startaddr == 0 && endaddr == 0)
+ return;
+ curoffset = beginoffset;
+ limit_offset =
+ ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private)
+ ->max_lineno_offset;
+
+ if (endoffset != 0)
+ {
+ if (endoffset >= limit_offset)
+ {
+ static struct complaint msg =
+ {"Bad line table offset in C_EINCL directive", 0, 0};
+ complain (&msg);
+ return;
+ }
+ limit_offset = endoffset;
+ }
+ else
+ limit_offset -= 1;
+
+ abfd = this_symtab_psymtab->objfile->obfd;
+ linesz = coff_data (abfd)->local_linesz;
+ ext_lnno = alloca (linesz);
+
+ while (curoffset <= limit_offset)
+ {
+ bfd_seek (abfd, curoffset, SEEK_SET);
+ bfd_bread (ext_lnno, linesz, abfd);
+ bfd_coff_swap_lineno_in (abfd, ext_lnno, &int_lnno);
+
+ /* Find the address this line represents. */
+ addr = (int_lnno.l_lnno
+ ? int_lnno.l_addr.l_paddr
+ : read_symbol_nvalue (int_lnno.l_addr.l_symndx));
+ addr += ANOFFSET (this_symtab_psymtab->objfile->section_offsets,
+ SECT_OFF_TEXT (this_symtab_psymtab->objfile));
+
+ if (addr < startaddr || (endaddr && addr >= endaddr))
+ return;
+
+ if (int_lnno.l_lnno == 0)
+ {
+ *firstLine = read_symbol_lineno (int_lnno.l_addr.l_symndx);
+ record_line (subfile, 0, addr);
+ --(*firstLine);
+ }
+ else
+ record_line (subfile, *firstLine + int_lnno.l_lnno, addr);
+ curoffset += linesz;
+ }
+}
+
+
+/* Save the vital information for use when closing off the current file.
+ NAME is the file name the symbols came from, START_ADDR is the first
+ text address for the file, and SIZE is the number of bytes of text. */
+
+#define complete_symtab(name, start_addr) { \
+ last_source_file = savestring (name, strlen (name)); \
+ last_source_start_addr = start_addr; \
+}
+
+
+/* Refill the symbol table input buffer
+ and set the variables that control fetching entries from it.
+ Reports an error if no data available.
+ This function can read past the end of the symbol table
+ (into the string table) but this does no harm. */
+
+/* Reading symbol table has to be fast! Keep the followings as macros, rather
+ than functions. */
+
+#define RECORD_MINIMAL_SYMBOL(NAME, ADDR, TYPE, SECTION, OBJFILE) \
+{ \
+ char *namestr; \
+ namestr = (NAME); \
+ if (namestr[0] == '.') ++namestr; \
+ prim_record_minimal_symbol_and_info (namestr, (ADDR), (TYPE), \
+ (char *)NULL, (SECTION), (asection *)NULL, (OBJFILE)); \
+ misc_func_recorded = 1; \
+}
+
+
+/* xcoff has static blocks marked in `.bs', `.es' pairs. They cannot be
+ nested. At any given time, a symbol can only be in one static block.
+ This is the base address of current static block, zero if non exists. */
+
+static int static_block_base = 0;
+
+/* Section number for the current static block. */
+
+static int static_block_section = -1;
+
+/* true if space for symbol name has been allocated. */
+
+static int symname_alloced = 0;
+
+/* Next symbol to read. Pointer into raw seething symbol table. */
+
+static char *raw_symbol;
+
+/* This is the function which stabsread.c calls to get symbol
+ continuations. */
+
+static char *
+xcoff_next_symbol_text (struct objfile *objfile)
+{
+ struct internal_syment symbol;
+ static struct complaint msg =
+ {"Unexpected symbol continuation", 0, 0};
+ char *retval;
+ /* FIXME: is this the same as the passed arg? */
+ objfile = this_symtab_psymtab->objfile;
+
+ bfd_coff_swap_sym_in (objfile->obfd, raw_symbol, &symbol);
+ if (symbol.n_zeroes)
+ {
+ complain (&msg);
+
+ /* Return something which points to '\0' and hope the symbol reading
+ code does something reasonable. */
+ retval = "";
+ }
+ else if (symbol.n_sclass & 0x80)
+ {
+ retval =
+ ((struct coff_symfile_info *) objfile->sym_private)->debugsec
+ + symbol.n_offset;
+ raw_symbol +=
+ coff_data (objfile->obfd)->local_symesz;
+ ++symnum;
+ }
+ else
+ {
+ complain (&msg);
+
+ /* Return something which points to '\0' and hope the symbol reading
+ code does something reasonable. */
+ retval = "";
+ }
+ return retval;
+}
+
+/* Read symbols for a given partial symbol table. */
+
+static void
+read_xcoff_symtab (struct partial_symtab *pst)
+{
+ struct objfile *objfile = pst->objfile;
+ bfd *abfd = objfile->obfd;
+ char *raw_auxptr; /* Pointer to first raw aux entry for sym */
+ char *strtbl = ((struct coff_symfile_info *) objfile->sym_private)->strtbl;
+ char *debugsec =
+ ((struct coff_symfile_info *) objfile->sym_private)->debugsec;
+ char *debugfmt = bfd_xcoff_is_xcoff64 (abfd) ? "XCOFF64" : "XCOFF";
+
+ struct internal_syment symbol[1];
+ union internal_auxent main_aux;
+ struct coff_symbol cs[1];
+ CORE_ADDR file_start_addr = 0;
+ CORE_ADDR file_end_addr = 0;
+
+ int next_file_symnum = -1;
+ unsigned int max_symnum;
+ int just_started = 1;
+ int depth = 0;
+ int fcn_start_addr = 0;
+
+ struct coff_symbol fcn_stab_saved;
+
+ /* fcn_cs_saved is global because process_xcoff_symbol needs it. */
+ union internal_auxent fcn_aux_saved;
+ struct context_stack *new;
+
+ char *filestring = " _start_ "; /* Name of the current file. */
+
+ char *last_csect_name; /* last seen csect's name and value */
+ CORE_ADDR last_csect_val;
+ int last_csect_sec;
+
+ this_symtab_psymtab = pst;
+
+ /* Get the appropriate COFF "constants" related to the file we're
+ handling. */
+ local_symesz = coff_data (abfd)->local_symesz;
+
+ last_source_file = NULL;
+ last_csect_name = 0;
+ last_csect_val = 0;
+
+ start_stabs ();
+ start_symtab (filestring, (char *) NULL, file_start_addr);
+ record_debugformat (debugfmt);
+ symnum = ((struct symloc *) pst->read_symtab_private)->first_symnum;
+ max_symnum =
+ symnum + ((struct symloc *) pst->read_symtab_private)->numsyms;
+ first_object_file_end = 0;
+
+ raw_symbol =
+ ((struct coff_symfile_info *) objfile->sym_private)->symtbl
+ + symnum * local_symesz;
+
+ while (symnum < max_symnum)
+ {
+
+ QUIT; /* make this command interruptable. */
+
+ /* READ_ONE_SYMBOL (symbol, cs, symname_alloced); */
+ /* read one symbol into `cs' structure. After processing the
+ whole symbol table, only string table will be kept in memory,
+ symbol table and debug section of xcoff will be freed. Thus
+ we can mark symbols with names in string table as
+ `alloced'. */
+ {
+ int ii;
+
+ /* Swap and align the symbol into a reasonable C structure. */
+ bfd_coff_swap_sym_in (abfd, raw_symbol, symbol);
+
+ cs->c_symnum = symnum;
+ cs->c_naux = symbol->n_numaux;
+ if (symbol->n_zeroes)
+ {
+ symname_alloced = 0;
+ /* We must use the original, unswapped, name here so the name field
+ pointed to by cs->c_name will persist throughout xcoffread. If
+ we use the new field, it gets overwritten for each symbol. */
+ cs->c_name = ((struct external_syment *) raw_symbol)->e.e_name;
+ /* If it's exactly E_SYMNMLEN characters long it isn't
+ '\0'-terminated. */
+ if (cs->c_name[E_SYMNMLEN - 1] != '\0')
+ {
+ char *p;
+ p = obstack_alloc (&objfile->symbol_obstack, E_SYMNMLEN + 1);
+ strncpy (p, cs->c_name, E_SYMNMLEN);
+ p[E_SYMNMLEN] = '\0';
+ cs->c_name = p;
+ symname_alloced = 1;
+ }
+ }
+ else if (symbol->n_sclass & 0x80)
+ {
+ cs->c_name = debugsec + symbol->n_offset;
+ symname_alloced = 0;
+ }
+ else
+ {
+ /* in string table */
+ cs->c_name = strtbl + (int) symbol->n_offset;
+ symname_alloced = 1;
+ }
+ cs->c_value = symbol->n_value;
+ cs->c_sclass = symbol->n_sclass;
+ cs->c_secnum = symbol->n_scnum;
+ cs->c_type = (unsigned) symbol->n_type;
+
+ raw_symbol += local_symesz;
+ ++symnum;
+
+ /* Save addr of first aux entry. */
+ raw_auxptr = raw_symbol;
+
+ /* Skip all the auxents associated with this symbol. */
+ for (ii = symbol->n_numaux; ii; --ii)
+ {
+ raw_symbol += coff_data (abfd)->local_auxesz;
+ ++symnum;
+ }
+ }
+
+ /* if symbol name starts with ".$" or "$", ignore it. */
+ if (cs->c_name[0] == '$'
+ || (cs->c_name[1] == '$' && cs->c_name[0] == '.'))
+ continue;
+
+ if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
+ {
+ if (last_source_file)
+ {
+ pst->symtab =
+ end_symtab (cur_src_end_addr, objfile, SECT_OFF_TEXT (objfile));
+ end_stabs ();
+ }
+
+ start_stabs ();
+ start_symtab ("_globals_", (char *) NULL, (CORE_ADDR) 0);
+ record_debugformat (debugfmt);
+ cur_src_end_addr = first_object_file_end;
+ /* done with all files, everything from here on is globals */
+ }
+
+ if ((cs->c_sclass == C_EXT || cs->c_sclass == C_HIDEXT)
+ && cs->c_naux == 1)
+ {
+ /* Dealing with a symbol with a csect entry. */
+
+#define CSECT(PP) ((PP)->x_csect)
+#define CSECT_LEN(PP) (CSECT(PP).x_scnlen.l)
+#define CSECT_ALIGN(PP) (SMTYP_ALIGN(CSECT(PP).x_smtyp))
+#define CSECT_SMTYP(PP) (SMTYP_SMTYP(CSECT(PP).x_smtyp))
+#define CSECT_SCLAS(PP) (CSECT(PP).x_smclas)
+
+ /* Convert the auxent to something we can access. */
+ bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
+ 0, cs->c_naux, &main_aux);
+
+ switch (CSECT_SMTYP (&main_aux))
+ {
+
+ case XTY_ER:
+ /* Ignore all external references. */
+ continue;
+
+ case XTY_SD:
+ /* A section description. */
+ {
+ switch (CSECT_SCLAS (&main_aux))
+ {
+
+ case XMC_PR:
+ {
+
+ /* A program csect is seen. We have to allocate one
+ symbol table for each program csect. Normally gdb
+ prefers one symtab for each source file. In case
+ of AIX, one source file might include more than one
+ [PR] csect, and they don't have to be adjacent in
+ terms of the space they occupy in memory. Thus, one
+ single source file might get fragmented in the
+ memory and gdb's file start and end address
+ approach does not work! GCC (and I think xlc) seem
+ to put all the code in the unnamed program csect. */
+
+ if (last_csect_name)
+ {
+ complete_symtab (filestring, file_start_addr);
+ cur_src_end_addr = file_end_addr;
+ end_symtab (file_end_addr, objfile, SECT_OFF_TEXT (objfile));
+ end_stabs ();
+ start_stabs ();
+ /* Give all csects for this source file the same
+ name. */
+ start_symtab (filestring, NULL, (CORE_ADDR) 0);
+ record_debugformat (debugfmt);
+ }
+
+ /* If this is the very first csect seen,
+ basically `__start'. */
+ if (just_started)
+ {
+ first_object_file_end
+ = cs->c_value + CSECT_LEN (&main_aux);
+ just_started = 0;
+ }
+
+ file_start_addr =
+ cs->c_value + ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
+ file_end_addr = file_start_addr + CSECT_LEN (&main_aux);
+
+ if (cs->c_name && (cs->c_name[0] == '.'
+ || cs->c_name[0] == '@'))
+ {
+ last_csect_name = cs->c_name;
+ last_csect_val = cs->c_value;
+ last_csect_sec = secnum_to_section (cs->c_secnum, objfile);
+ }
+ }
+ continue;
+
+ /* All other symbols are put into the minimal symbol
+ table only. */
+
+ case XMC_RW:
+ continue;
+
+ case XMC_TC0:
+ continue;
+
+ case XMC_TC:
+ continue;
+
+ default:
+ /* Ignore the symbol. */
+ continue;
+ }
+ }
+ break;
+
+ case XTY_LD:
+
+ switch (CSECT_SCLAS (&main_aux))
+ {
+ case XMC_PR:
+ /* a function entry point. */
+ function_entry_point:
+
+ fcn_start_addr = cs->c_value;
+
+ /* save the function header info, which will be used
+ when `.bf' is seen. */
+ fcn_cs_saved = *cs;
+ fcn_aux_saved = main_aux;
+ continue;
+
+ case XMC_GL:
+ /* shared library function trampoline code entry point. */
+ continue;
+
+ case XMC_DS:
+ /* The symbols often have the same names as debug symbols for
+ functions, and confuse lookup_symbol. */
+ continue;
+
+ default:
+ /* xlc puts each variable in a separate csect, so we get
+ an XTY_SD for each variable. But gcc puts several
+ variables in a csect, so that each variable only gets
+ an XTY_LD. This will typically be XMC_RW; I suspect
+ XMC_RO and XMC_BS might be possible too.
+ These variables are put in the minimal symbol table
+ only. */
+ continue;
+ }
+ break;
+
+ case XTY_CM:
+ /* Common symbols are put into the minimal symbol table only. */
+ continue;
+
+ default:
+ break;
+ }
+ }
+
+ /* If explicitly specified as a function, treat is as one. This check
+ evaluates to true for @FIX* bigtoc CSECT symbols, so it must occur
+ after the above CSECT check. */
+ if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
+ {
+ bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
+ 0, cs->c_naux, &main_aux);
+ goto function_entry_point;
+ }
+
+ switch (cs->c_sclass)
+ {
+
+ case C_FILE:
+
+ /* c_value field contains symnum of next .file entry in table
+ or symnum of first global after last .file. */
+
+ next_file_symnum = cs->c_value;
+
+ /* Complete symbol table for last object file containing
+ debugging information. */
+
+ /* Whether or not there was a csect in the previous file, we
+ have to call `end_stabs' and `start_stabs' to reset
+ type_vector, line_vector, etc. structures. */
+
+ complete_symtab (filestring, file_start_addr);
+ cur_src_end_addr = file_end_addr;
+ end_symtab (file_end_addr, objfile, SECT_OFF_TEXT (objfile));
+ end_stabs ();
+
+ /* XCOFF, according to the AIX 3.2 documentation, puts the filename
+ in cs->c_name. But xlc 1.3.0.2 has decided to do things the
+ standard COFF way and put it in the auxent. We use the auxent if
+ the symbol is ".file" and an auxent exists, otherwise use the symbol
+ itself. Simple enough. */
+ if (!strcmp (cs->c_name, ".file") && cs->c_naux > 0)
+ {
+ bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
+ 0, cs->c_naux, &main_aux);
+ filestring = coff_getfilename (&main_aux, objfile);
+ }
+ else
+ filestring = cs->c_name;
+
+ start_stabs ();
+ start_symtab (filestring, (char *) NULL, (CORE_ADDR) 0);
+ record_debugformat (debugfmt);
+ last_csect_name = 0;
+
+ /* reset file start and end addresses. A compilation unit with no text
+ (only data) should have zero file boundaries. */
+ file_start_addr = file_end_addr = 0;
+ break;
+
+ case C_FUN:
+ fcn_stab_saved = *cs;
+ break;
+
+ case C_FCN:
+ if (STREQ (cs->c_name, ".bf"))
+ {
+ CORE_ADDR off = ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
+ bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
+ 0, cs->c_naux, &main_aux);
+
+ within_function = 1;
+
+ new = push_context (0, fcn_start_addr + off);
+
+ new->name = define_symbol
+ (fcn_cs_saved.c_value + off,
+ fcn_stab_saved.c_name, 0, 0, objfile);
+ if (new->name != NULL)
+ SYMBOL_SECTION (new->name) = SECT_OFF_TEXT (objfile);
+ }
+ else if (STREQ (cs->c_name, ".ef"))
+ {
+
+ bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
+ 0, cs->c_naux, &main_aux);
+
+ /* The value of .ef is the address of epilogue code;
+ not useful for gdb. */
+ /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
+ contains number of lines to '}' */
+
+ if (context_stack_depth <= 0)
+ { /* We attempted to pop an empty context stack */
+ complain (&ef_complaint, cs->c_symnum);
+ within_function = 0;
+ break;
+ }
+ new = pop_context ();
+ /* Stack must be empty now. */
+ if (context_stack_depth > 0 || new == NULL)
+ {
+ complain (&ef_complaint, cs->c_symnum);
+ within_function = 0;
+ break;
+ }
+
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ new->start_addr,
+ (fcn_cs_saved.c_value
+ + fcn_aux_saved.x_sym.x_misc.x_fsize
+ + ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile))),
+ objfile);
+ within_function = 0;
+ }
+ break;
+
+ case C_BSTAT:
+ /* Begin static block. */
+ {
+ struct internal_syment symbol;
+
+ read_symbol (&symbol, cs->c_value);
+ static_block_base = symbol.n_value;
+ static_block_section =
+ secnum_to_section (symbol.n_scnum, objfile);
+ }
+ break;
+
+ case C_ESTAT:
+ /* End of static block. */
+ static_block_base = 0;
+ static_block_section = -1;
+ break;
+
+ case C_ARG:
+ case C_REGPARM:
+ case C_REG:
+ case C_TPDEF:
+ case C_STRTAG:
+ case C_UNTAG:
+ case C_ENTAG:
+ {
+ static struct complaint msg =
+ {"Unrecognized storage class %d.", 0, 0};
+ complain (&msg, cs->c_sclass);
+ }
+ break;
+
+ case C_LABEL:
+ case C_NULL:
+ /* Ignore these. */
+ break;
+
+ case C_HIDEXT:
+ case C_STAT:
+ break;
+
+ case C_BINCL:
+ /* beginning of include file */
+ /* In xlc output, C_BINCL/C_EINCL pair doesn't show up in sorted
+ order. Thus, when wee see them, we might not know enough info
+ to process them. Thus, we'll be saving them into a table
+ (inclTable) and postpone their processing. */
+
+ record_include_begin (cs);
+ break;
+
+ case C_EINCL:
+ /* End of include file. */
+ /* See the comment after case C_BINCL. */
+ record_include_end (cs);
+ break;
+
+ case C_BLOCK:
+ if (STREQ (cs->c_name, ".bb"))
+ {
+ depth++;
+ new = push_context (depth,
+ (cs->c_value
+ + ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile))));
+ }
+ else if (STREQ (cs->c_name, ".eb"))
+ {
+ if (context_stack_depth <= 0)
+ { /* We attempted to pop an empty context stack */
+ complain (&eb_complaint, cs->c_symnum);
+ break;
+ }
+ new = pop_context ();
+ if (depth-- != new->depth)
+ {
+ complain (&eb_complaint, cs->c_symnum);
+ break;
+ }
+ if (local_symbols && context_stack_depth > 0)
+ {
+ /* Make a block for the local symbols within. */
+ finish_block (new->name, &local_symbols, new->old_blocks,
+ new->start_addr,
+ (cs->c_value
+ + ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile))),
+ objfile);
+ }
+ local_symbols = new->locals;
+ }
+ break;
+
+ default:
+ process_xcoff_symbol (cs, objfile);
+ break;
+ }
+ }
+
+ if (last_source_file)
+ {
+ struct symtab *s;
+
+ complete_symtab (filestring, file_start_addr);
+ cur_src_end_addr = file_end_addr;
+ s = end_symtab (file_end_addr, objfile, SECT_OFF_TEXT (objfile));
+ /* When reading symbols for the last C_FILE of the objfile, try
+ to make sure that we set pst->symtab to the symtab for the
+ file, not to the _globals_ symtab. I'm not sure whether this
+ actually works right or when/if it comes up. */
+ if (pst->symtab == NULL)
+ pst->symtab = s;
+ end_stabs ();
+ }
+}
+
+#define SYMBOL_DUP(SYMBOL1, SYMBOL2) \
+ (SYMBOL2) = (struct symbol *) \
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); \
+ *(SYMBOL2) = *(SYMBOL1);
+
+
+#define SYMNAME_ALLOC(NAME, ALLOCED) \
+ (ALLOCED) ? (NAME) : obsavestring ((NAME), strlen (NAME), &objfile->symbol_obstack);
+
+
+static struct type *func_symbol_type;
+static struct type *var_symbol_type;
+
+/* process one xcoff symbol. */
+
+static struct symbol *
+process_xcoff_symbol (register struct coff_symbol *cs, struct objfile *objfile)
+{
+ struct symbol onesymbol;
+ register struct symbol *sym = &onesymbol;
+ struct symbol *sym2 = NULL;
+ char *name, *pp;
+
+ int sec;
+ CORE_ADDR off;
+
+ if (cs->c_secnum < 0)
+ {
+ /* The value is a register number, offset within a frame, etc.,
+ and does not get relocated. */
+ off = 0;
+ sec = -1;
+ }
+ else
+ {
+ sec = secnum_to_section (cs->c_secnum, objfile);
+ off = ANOFFSET (objfile->section_offsets, sec);
+ }
+
+ name = cs->c_name;
+ if (name[0] == '.')
+ ++name;
+
+ memset (sym, '\0', sizeof (struct symbol));
+
+ /* default assumptions */
+ SYMBOL_VALUE_ADDRESS (sym) = cs->c_value + off;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_SECTION (sym) = secnum_to_section (cs->c_secnum, objfile);
+
+ if (ISFCN (cs->c_type))
+ {
+ /* At this point, we don't know the type of the function. This
+ will be patched with the type from its stab entry later on in
+ patch_block_stabs (), unless the file was compiled without -g. */
+
+ SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced);
+ SYMBOL_TYPE (sym) = func_symbol_type;
+
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+ SYMBOL_DUP (sym, sym2);
+
+ if (cs->c_sclass == C_EXT)
+ add_symbol_to_list (sym2, &global_symbols);
+ else if (cs->c_sclass == C_HIDEXT || cs->c_sclass == C_STAT)
+ add_symbol_to_list (sym2, &file_symbols);
+ }
+ else
+ {
+ /* In case we can't figure out the type, provide default. */
+ SYMBOL_TYPE (sym) = var_symbol_type;
+
+ switch (cs->c_sclass)
+ {
+#if 0
+ /* The values of functions and global symbols are now resolved
+ via the global_sym_chain in stabsread.c. */
+ case C_FUN:
+ if (fcn_cs_saved.c_sclass == C_EXT)
+ add_stab_to_list (name, &global_stabs);
+ else
+ add_stab_to_list (name, &file_stabs);
+ break;
+
+ case C_GSYM:
+ add_stab_to_list (name, &global_stabs);
+ break;
+#endif
+
+ case C_BCOMM:
+ common_block_start (cs->c_name, objfile);
+ break;
+
+ case C_ECOMM:
+ common_block_end (objfile);
+ break;
+
+ default:
+ complain (&storclass_complaint, cs->c_sclass);
+ /* FALLTHROUGH */
+
+ case C_DECL:
+ case C_PSYM:
+ case C_RPSYM:
+ case C_ECOML:
+ case C_LSYM:
+ case C_RSYM:
+ case C_GSYM:
+
+ {
+ sym = define_symbol (cs->c_value + off, cs->c_name, 0, 0, objfile);
+ if (sym != NULL)
+ {
+ SYMBOL_SECTION (sym) = sec;
+ }
+ return sym;
+ }
+
+ case C_STSYM:
+
+ /* For xlc (not GCC), the 'V' symbol descriptor is used for
+ all statics and we need to distinguish file-scope versus
+ function-scope using within_function. We do this by
+ changing the string we pass to define_symbol to use 'S'
+ where we need to, which is not necessarily super-clean,
+ but seems workable enough. */
+
+ if (*name == ':' || (pp = (char *) strchr (name, ':')) == NULL)
+ return NULL;
+
+ ++pp;
+ if (*pp == 'V' && !within_function)
+ *pp = 'S';
+ sym = define_symbol ((cs->c_value
+ + ANOFFSET (objfile->section_offsets,
+ static_block_section)),
+ cs->c_name, 0, 0, objfile);
+ if (sym != NULL)
+ {
+ SYMBOL_VALUE_ADDRESS (sym) += static_block_base;
+ SYMBOL_SECTION (sym) = static_block_section;
+ }
+ return sym;
+
+ }
+ }
+ return sym2;
+}
+
+/* Extract the file name from the aux entry of a C_FILE symbol.
+ Result is in static storage and is only good for temporary use. */
+
+static char *
+coff_getfilename (union internal_auxent *aux_entry, struct objfile *objfile)
+{
+ static char buffer[BUFSIZ];
+
+ if (aux_entry->x_file.x_n.x_zeroes == 0)
+ strcpy (buffer,
+ ((struct coff_symfile_info *) objfile->sym_private)->strtbl
+ + aux_entry->x_file.x_n.x_offset);
+ else
+ {
+ strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN);
+ buffer[FILNMLEN] = '\0';
+ }
+ return (buffer);
+}
+
+/* Set *SYMBOL to symbol number symno in symtbl. */
+static void
+read_symbol (struct internal_syment *symbol, int symno)
+{
+ int nsyms =
+ ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private)
+ ->symtbl_num_syms;
+ char *stbl =
+ ((struct coff_symfile_info *) this_symtab_psymtab->objfile->sym_private)
+ ->symtbl;
+ if (symno < 0 || symno >= nsyms)
+ {
+ static struct complaint msg =
+ {"Invalid symbol offset", 0, 0};
+ complain (&msg);
+ symbol->n_value = 0;
+ symbol->n_scnum = -1;
+ return;
+ }
+ bfd_coff_swap_sym_in (this_symtab_psymtab->objfile->obfd,
+ stbl + (symno * local_symesz),
+ symbol);
+}
+
+/* Get value corresponding to symbol number symno in symtbl. */
+
+static CORE_ADDR
+read_symbol_nvalue (int symno)
+{
+ struct internal_syment symbol[1];
+
+ read_symbol (symbol, symno);
+ return symbol->n_value;
+}
+
+
+/* Find the address of the function corresponding to symno, where
+ symno is the symbol pointed to by the linetable. */
+
+static int
+read_symbol_lineno (int symno)
+{
+ struct objfile *objfile = this_symtab_psymtab->objfile;
+ boolean xcoff64 = bfd_xcoff_is_xcoff64 (objfile->obfd);
+
+ struct coff_symfile_info *info =
+ (struct coff_symfile_info *)objfile->sym_private;
+ int nsyms = info->symtbl_num_syms;
+ char *stbl = info->symtbl;
+ char *strtbl = info->strtbl;
+
+ struct internal_syment symbol[1];
+ union internal_auxent main_aux[1];
+
+ if (symno < 0)
+ {
+ complain (&bf_notfound_complaint);
+ return 0;
+ }
+
+ /* Note that just searching for a short distance (e.g. 50 symbols)
+ is not enough, at least in the following case.
+
+ .extern foo
+ [many .stabx entries]
+ [a few functions, referring to foo]
+ .globl foo
+ .bf
+
+ What happens here is that the assembler moves the .stabx entries
+ to right before the ".bf" for foo, but the symbol for "foo" is before
+ all the stabx entries. See PR gdb/2222. */
+
+ /* Maintaining a table of .bf entries might be preferable to this search.
+ If I understand things correctly it would need to be done only for
+ the duration of a single psymtab to symtab conversion. */
+ while (symno < nsyms)
+ {
+ bfd_coff_swap_sym_in (symfile_bfd,
+ stbl + (symno * local_symesz), symbol);
+ if (symbol->n_sclass == C_FCN)
+ {
+ char *name = xcoff64 ? strtbl + symbol->n_offset : symbol->n_name;
+ if (STREQ (name, ".bf"))
+ goto gotit;
+ }
+ symno += symbol->n_numaux + 1;
+ }
+
+ complain (&bf_notfound_complaint);
+ return 0;
+
+gotit:
+ /* take aux entry and return its lineno */
+ symno++;
+ bfd_coff_swap_aux_in (objfile->obfd, stbl + symno * local_symesz,
+ symbol->n_type, symbol->n_sclass,
+ 0, symbol->n_numaux, main_aux);
+
+ return main_aux->x_sym.x_misc.x_lnsz.x_lnno;
+}
+
+/* Support for line number handling */
+
+/* This function is called for every section; it finds the outer limits
+ * of the line table (minimum and maximum file offset) so that the
+ * mainline code can read the whole thing for efficiency.
+ */
+static void
+find_linenos (bfd *abfd, sec_ptr asect, PTR vpinfo)
+{
+ struct coff_symfile_info *info;
+ int size, count;
+ file_ptr offset, maxoff;
+
+ count = asect->lineno_count;
+
+ if (!STREQ (asect->name, ".text") || count == 0)
+ return;
+
+ size = count * coff_data (abfd)->local_linesz;
+ info = (struct coff_symfile_info *) vpinfo;
+ offset = asect->line_filepos;
+ maxoff = offset + size;
+
+ if (offset < info->min_lineno_offset || info->min_lineno_offset == 0)
+ info->min_lineno_offset = offset;
+
+ if (maxoff > info->max_lineno_offset)
+ info->max_lineno_offset = maxoff;
+}
+
+static void xcoff_psymtab_to_symtab_1 (struct partial_symtab *);
+
+static void
+xcoff_psymtab_to_symtab_1 (struct partial_symtab *pst)
+{
+ struct cleanup *old_chain;
+ int i;
+
+ if (!pst)
+ return;
+
+ if (pst->readin)
+ {
+ fprintf_unfiltered
+ (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
+ pst->filename);
+ return;
+ }
+
+ /* Read in all partial symtabs on which this one is dependent */
+ for (i = 0; i < pst->number_of_dependencies; i++)
+ if (!pst->dependencies[i]->readin)
+ {
+ /* Inform about additional files that need to be read in. */
+ if (info_verbose)
+ {
+ fputs_filtered (" ", gdb_stdout);
+ wrap_here ("");
+ fputs_filtered ("and ", gdb_stdout);
+ wrap_here ("");
+ printf_filtered ("%s...", pst->dependencies[i]->filename);
+ wrap_here (""); /* Flush output */
+ gdb_flush (gdb_stdout);
+ }
+ xcoff_psymtab_to_symtab_1 (pst->dependencies[i]);
+ }
+
+ if (((struct symloc *) pst->read_symtab_private)->numsyms != 0)
+ {
+ /* Init stuff necessary for reading in symbols. */
+ stabsread_init ();
+ buildsym_init ();
+ old_chain = make_cleanup (really_free_pendings, 0);
+
+ read_xcoff_symtab (pst);
+ sort_symtab_syms (pst->symtab);
+
+ do_cleanups (old_chain);
+ }
+
+ pst->readin = 1;
+}
+
+static void xcoff_psymtab_to_symtab (struct partial_symtab *);
+
+/* Read in all of the symbols for a given psymtab for real.
+ Be verbose about it if the user wants that. */
+
+static void
+xcoff_psymtab_to_symtab (struct partial_symtab *pst)
+{
+ bfd *sym_bfd;
+
+ if (!pst)
+ return;
+
+ if (pst->readin)
+ {
+ fprintf_unfiltered
+ (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
+ pst->filename);
+ return;
+ }
+
+ if (((struct symloc *) pst->read_symtab_private)->numsyms != 0
+ || pst->number_of_dependencies)
+ {
+ /* Print the message now, before reading the string table,
+ to avoid disconcerting pauses. */
+ if (info_verbose)
+ {
+ printf_filtered ("Reading in symbols for %s...", pst->filename);
+ gdb_flush (gdb_stdout);
+ }
+
+ sym_bfd = pst->objfile->obfd;
+
+ next_symbol_text_func = xcoff_next_symbol_text;
+
+ xcoff_psymtab_to_symtab_1 (pst);
+
+ /* Match with global symbols. This only needs to be done once,
+ after all of the symtabs and dependencies have been read in. */
+ scan_file_globals (pst->objfile);
+
+ /* Finish up the debug error message. */
+ if (info_verbose)
+ printf_filtered ("done.\n");
+ }
+}
+
+static void
+xcoff_new_init (struct objfile *objfile)
+{
+ stabsread_new_init ();
+ buildsym_new_init ();
+}
+
+/* Do initialization in preparation for reading symbols from OBJFILE.
+
+ We will only be called if this is an XCOFF or XCOFF-like file.
+ BFD handles figuring out the format of the file, and code in symfile.c
+ uses BFD's determination to vector to us. */
+
+static void
+xcoff_symfile_init (struct objfile *objfile)
+{
+ /* Allocate struct to keep track of the symfile */
+ objfile->sym_private = xmmalloc (objfile->md,
+ sizeof (struct coff_symfile_info));
+
+ /* XCOFF objects may be reordered, so set OBJF_REORDERED. If we
+ find this causes a significant slowdown in gdb then we could
+ set it in the debug symbol readers only when necessary. */
+ objfile->flags |= OBJF_REORDERED;
+
+ init_entry_point_info (objfile);
+}
+
+/* Perform any local cleanups required when we are done with a particular
+ objfile. I.E, we are in the process of discarding all symbol information
+ for an objfile, freeing up all memory held for it, and unlinking the
+ objfile struct from the global list of known objfiles. */
+
+static void
+xcoff_symfile_finish (struct objfile *objfile)
+{
+ if (objfile->sym_private != NULL)
+ {
+ xmfree (objfile->md, objfile->sym_private);
+ }
+
+ /* Start with a fresh include table for the next objfile. */
+ if (inclTable)
+ {
+ xfree (inclTable);
+ inclTable = NULL;
+ }
+ inclIndx = inclLength = inclDepth = 0;
+}
+
+
+static void
+init_stringtab (bfd *abfd, file_ptr offset, struct objfile *objfile)
+{
+ long length;
+ int val;
+ unsigned char lengthbuf[4];
+ char *strtbl;
+
+ ((struct coff_symfile_info *) objfile->sym_private)->strtbl = NULL;
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ error ("cannot seek to string table in %s: %s",
+ bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
+
+ val = bfd_bread ((char *) lengthbuf, sizeof lengthbuf, abfd);
+ length = bfd_h_get_32 (abfd, lengthbuf);
+
+ /* If no string table is needed, then the file may end immediately
+ after the symbols. Just return with `strtbl' set to NULL. */
+
+ if (val != sizeof lengthbuf || length < sizeof lengthbuf)
+ return;
+
+ /* Allocate string table from symbol_obstack. We will need this table
+ as long as we have its symbol table around. */
+
+ strtbl = (char *) obstack_alloc (&objfile->symbol_obstack, length);
+ ((struct coff_symfile_info *) objfile->sym_private)->strtbl = strtbl;
+
+ /* Copy length buffer, the first byte is usually zero and is
+ used for stabs with a name length of zero. */
+ memcpy (strtbl, lengthbuf, sizeof lengthbuf);
+ if (length == sizeof lengthbuf)
+ return;
+
+ val = bfd_bread (strtbl + sizeof lengthbuf, length - sizeof lengthbuf, abfd);
+
+ if (val != length - sizeof lengthbuf)
+ error ("cannot read string table from %s: %s",
+ bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
+ if (strtbl[length - 1] != '\0')
+ error ("bad symbol file: string table does not end with null character");
+
+ return;
+}
+
+/* If we have not yet seen a function for this psymtab, this is 0. If we
+ have seen one, it is the offset in the line numbers of the line numbers
+ for the psymtab. */
+static unsigned int first_fun_line_offset;
+
+static struct partial_symtab *xcoff_start_psymtab
+ (struct objfile *, char *, int,
+ struct partial_symbol **, struct partial_symbol **);
+
+/* Allocate and partially fill a partial symtab. It will be
+ completely filled at the end of the symbol list.
+
+ SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
+ is the address relative to which its symbols are (incremental) or 0
+ (normal). */
+
+static struct partial_symtab *
+xcoff_start_psymtab (struct objfile *objfile, char *filename, int first_symnum,
+ struct partial_symbol **global_syms,
+ struct partial_symbol **static_syms)
+{
+ struct partial_symtab *result =
+ start_psymtab_common (objfile, objfile->section_offsets,
+ filename,
+ /* We fill in textlow later. */
+ 0,
+ global_syms, static_syms);
+
+ result->read_symtab_private = (char *)
+ obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
+ ((struct symloc *) result->read_symtab_private)->first_symnum = first_symnum;
+ result->read_symtab = xcoff_psymtab_to_symtab;
+
+ /* Deduce the source language from the filename for this psymtab. */
+ psymtab_language = deduce_language_from_filename (filename);
+
+ return result;
+}
+
+static struct partial_symtab *xcoff_end_psymtab
+ (struct partial_symtab *, char **, int, int,
+ struct partial_symtab **, int, int);
+
+/* Close off the current usage of PST.
+ Returns PST, or NULL if the partial symtab was empty and thrown away.
+
+ CAPPING_SYMBOL_NUMBER is the end of pst (exclusive).
+
+ INCLUDE_LIST, NUM_INCLUDES, DEPENDENCY_LIST, and NUMBER_DEPENDENCIES
+ are the information for includes and dependencies. */
+
+static struct partial_symtab *
+xcoff_end_psymtab (struct partial_symtab *pst, char **include_list,
+ int num_includes, int capping_symbol_number,
+ struct partial_symtab **dependency_list,
+ int number_dependencies, int textlow_not_set)
+{
+ int i;
+ struct objfile *objfile = pst->objfile;
+
+ if (capping_symbol_number != -1)
+ ((struct symloc *) pst->read_symtab_private)->numsyms =
+ capping_symbol_number
+ - ((struct symloc *) pst->read_symtab_private)->first_symnum;
+ ((struct symloc *) pst->read_symtab_private)->lineno_off =
+ first_fun_line_offset;
+ first_fun_line_offset = 0;
+ pst->n_global_syms =
+ objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
+ pst->n_static_syms =
+ objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset);
+
+ pst->number_of_dependencies = number_dependencies;
+ if (number_dependencies)
+ {
+ pst->dependencies = (struct partial_symtab **)
+ obstack_alloc (&objfile->psymbol_obstack,
+ number_dependencies * sizeof (struct partial_symtab *));
+ memcpy (pst->dependencies, dependency_list,
+ number_dependencies * sizeof (struct partial_symtab *));
+ }
+ else
+ pst->dependencies = 0;
+
+ for (i = 0; i < num_includes; i++)
+ {
+ struct partial_symtab *subpst =
+ allocate_psymtab (include_list[i], objfile);
+
+ subpst->section_offsets = pst->section_offsets;
+ subpst->read_symtab_private =
+ (char *) obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct symloc));
+ ((struct symloc *) subpst->read_symtab_private)->first_symnum = 0;
+ ((struct symloc *) subpst->read_symtab_private)->numsyms = 0;
+ subpst->textlow = 0;
+ subpst->texthigh = 0;
+
+ /* We could save slight bits of space by only making one of these,
+ shared by the entire set of include files. FIXME-someday. */
+ subpst->dependencies = (struct partial_symtab **)
+ obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct partial_symtab *));
+ subpst->dependencies[0] = pst;
+ subpst->number_of_dependencies = 1;
+
+ subpst->globals_offset =
+ subpst->n_global_syms =
+ subpst->statics_offset =
+ subpst->n_static_syms = 0;
+
+ subpst->readin = 0;
+ subpst->symtab = 0;
+ subpst->read_symtab = pst->read_symtab;
+ }
+
+ sort_pst_symbols (pst);
+
+ /* If there is already a psymtab or symtab for a file of this name,
+ remove it. (If there is a symtab, more drastic things also
+ happen.) This happens in VxWorks. */
+ free_named_symtabs (pst->filename);
+
+ if (num_includes == 0
+ && number_dependencies == 0
+ && pst->n_global_syms == 0
+ && pst->n_static_syms == 0)
+ {
+ /* Throw away this psymtab, it's empty. We can't deallocate it, since
+ it is on the obstack, but we can forget to chain it on the list. */
+ /* Empty psymtabs happen as a result of header files which don't have
+ any symbols in them. There can be a lot of them. */
+
+ discard_psymtab (pst);
+
+ /* Indicate that psymtab was thrown away. */
+ pst = (struct partial_symtab *) NULL;
+ }
+ return pst;
+}
+
+static void swap_sym (struct internal_syment *,
+ union internal_auxent *, char **, char **,
+ unsigned int *, struct objfile *);
+
+/* Swap raw symbol at *RAW and put the name in *NAME, the symbol in
+ *SYMBOL, the first auxent in *AUX. Advance *RAW and *SYMNUMP over
+ the symbol and its auxents. */
+
+static void
+swap_sym (struct internal_syment *symbol, union internal_auxent *aux,
+ char **name, char **raw, unsigned int *symnump,
+ struct objfile *objfile)
+{
+ bfd_coff_swap_sym_in (objfile->obfd, *raw, symbol);
+ if (symbol->n_zeroes)
+ {
+ /* If it's exactly E_SYMNMLEN characters long it isn't
+ '\0'-terminated. */
+ if (symbol->n_name[E_SYMNMLEN - 1] != '\0')
+ {
+ /* FIXME: wastes memory for symbols which we don't end up putting
+ into the minimal symbols. */
+ char *p;
+ p = obstack_alloc (&objfile->psymbol_obstack, E_SYMNMLEN + 1);
+ strncpy (p, symbol->n_name, E_SYMNMLEN);
+ p[E_SYMNMLEN] = '\0';
+ *name = p;
+ }
+ else
+ /* Point to the unswapped name as that persists as long as the
+ objfile does. */
+ *name = ((struct external_syment *) *raw)->e.e_name;
+ }
+ else if (symbol->n_sclass & 0x80)
+ {
+ *name = ((struct coff_symfile_info *) objfile->sym_private)->debugsec
+ + symbol->n_offset;
+ }
+ else
+ {
+ *name = ((struct coff_symfile_info *) objfile->sym_private)->strtbl
+ + symbol->n_offset;
+ }
+ ++*symnump;
+ *raw += coff_data (objfile->obfd)->local_symesz;
+ if (symbol->n_numaux > 0)
+ {
+ bfd_coff_swap_aux_in (objfile->obfd, *raw, symbol->n_type,
+ symbol->n_sclass, 0, symbol->n_numaux, aux);
+
+ *symnump += symbol->n_numaux;
+ *raw += coff_data (objfile->obfd)->local_symesz * symbol->n_numaux;
+ }
+}
+
+static void
+scan_xcoff_symtab (struct objfile *objfile)
+{
+ CORE_ADDR toc_offset = 0; /* toc offset value in data section. */
+ char *filestring = NULL;
+
+ char *namestring;
+ int past_first_source_file = 0;
+ bfd *abfd;
+ asection *bfd_sect;
+ unsigned int nsyms;
+
+ /* Current partial symtab */
+ struct partial_symtab *pst;
+
+ /* List of current psymtab's include files */
+ char **psymtab_include_list;
+ int includes_allocated;
+ int includes_used;
+
+ /* Index within current psymtab dependency list */
+ struct partial_symtab **dependency_list;
+ int dependencies_used, dependencies_allocated;
+
+ char *sraw_symbol;
+ struct internal_syment symbol;
+ union internal_auxent main_aux[5];
+ unsigned int ssymnum;
+
+ char *last_csect_name = NULL; /* last seen csect's name and value */
+ CORE_ADDR last_csect_val = 0;
+ int last_csect_sec = 0;
+ int misc_func_recorded = 0; /* true if any misc. function */
+ int textlow_not_set = 1;
+
+ pst = (struct partial_symtab *) 0;
+
+ includes_allocated = 30;
+ includes_used = 0;
+ psymtab_include_list = (char **) alloca (includes_allocated *
+ sizeof (char *));
+
+ dependencies_allocated = 30;
+ dependencies_used = 0;
+ dependency_list =
+ (struct partial_symtab **) alloca (dependencies_allocated *
+ sizeof (struct partial_symtab *));
+
+ last_source_file = NULL;
+
+ abfd = objfile->obfd;
+
+ sraw_symbol = ((struct coff_symfile_info *) objfile->sym_private)->symtbl;
+ nsyms = ((struct coff_symfile_info *) objfile->sym_private)->symtbl_num_syms;
+ ssymnum = 0;
+ while (ssymnum < nsyms)
+ {
+ int sclass;
+
+ QUIT;
+
+ bfd_coff_swap_sym_in (abfd, sraw_symbol, &symbol);
+ sclass = symbol.n_sclass;
+
+ switch (sclass)
+ {
+ case C_EXT:
+ case C_HIDEXT:
+ {
+ /* The CSECT auxent--always the last auxent. */
+ union internal_auxent csect_aux;
+ unsigned int symnum_before = ssymnum;
+
+ swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+ &ssymnum, objfile);
+ if (symbol.n_numaux > 1)
+ {
+ bfd_coff_swap_aux_in
+ (objfile->obfd,
+ sraw_symbol - coff_data (abfd)->local_symesz,
+ symbol.n_type,
+ symbol.n_sclass,
+ symbol.n_numaux - 1,
+ symbol.n_numaux,
+ &csect_aux);
+ }
+ else
+ csect_aux = main_aux[0];
+
+ /* If symbol name starts with ".$" or "$", ignore it. */
+ if (namestring[0] == '$'
+ || (namestring[0] == '.' && namestring[1] == '$'))
+ break;
+
+ switch (csect_aux.x_csect.x_smtyp & 0x7)
+ {
+ case XTY_SD:
+ switch (csect_aux.x_csect.x_smclas)
+ {
+ case XMC_PR:
+ if (last_csect_name)
+ {
+ /* If no misc. function recorded in the last
+ seen csect, enter it as a function. This
+ will take care of functions like strcmp()
+ compiled by xlc. */
+
+ if (!misc_func_recorded)
+ {
+ RECORD_MINIMAL_SYMBOL
+ (last_csect_name, last_csect_val,
+ mst_text, last_csect_sec,
+ objfile);
+ }
+
+ if (pst != NULL)
+ {
+ /* We have to allocate one psymtab for
+ each program csect, because their text
+ sections need not be adjacent. */
+ xcoff_end_psymtab
+ (pst, psymtab_include_list, includes_used,
+ symnum_before, dependency_list,
+ dependencies_used, textlow_not_set);
+ includes_used = 0;
+ dependencies_used = 0;
+ /* Give all psymtabs for this source file the same
+ name. */
+ pst = xcoff_start_psymtab
+ (objfile,
+ filestring,
+ symnum_before,
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ }
+ }
+ /* Activate the misc_func_recorded mechanism for
+ compiler- and linker-generated CSECTs like ".strcmp"
+ and "@FIX1". */
+ if (namestring && (namestring[0] == '.'
+ || namestring[0] == '@'))
+ {
+ last_csect_name = namestring;
+ last_csect_val = symbol.n_value;
+ last_csect_sec =
+ secnum_to_section (symbol.n_scnum, objfile);
+ }
+ if (pst != NULL)
+ {
+ CORE_ADDR highval =
+ symbol.n_value + csect_aux.x_csect.x_scnlen.l;
+ if (highval > pst->texthigh)
+ pst->texthigh = highval;
+ if (pst->textlow == 0 || symbol.n_value < pst->textlow)
+ pst->textlow = symbol.n_value;
+ }
+ misc_func_recorded = 0;
+ break;
+
+ case XMC_RW:
+ /* Data variables are recorded in the minimal symbol
+ table, except for section symbols. */
+ if (*namestring != '.')
+ prim_record_minimal_symbol_and_info
+ (namestring, symbol.n_value,
+ sclass == C_HIDEXT ? mst_file_data : mst_data,
+ NULL, secnum_to_section (symbol.n_scnum, objfile),
+ NULL, objfile);
+ break;
+
+ case XMC_TC0:
+ if (toc_offset)
+ warning ("More than one XMC_TC0 symbol found.");
+ toc_offset = symbol.n_value;
+
+ /* Make TOC offset relative to start address of section. */
+ bfd_sect = secnum_to_bfd_section (symbol.n_scnum, objfile);
+ if (bfd_sect)
+ toc_offset -= bfd_section_vma (objfile->obfd, bfd_sect);
+ break;
+
+ case XMC_TC:
+ /* These symbols tell us where the TOC entry for a
+ variable is, not the variable itself. */
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case XTY_LD:
+ switch (csect_aux.x_csect.x_smclas)
+ {
+ case XMC_PR:
+ /* A function entry point. */
+
+ if (first_fun_line_offset == 0 && symbol.n_numaux > 1)
+ first_fun_line_offset =
+ main_aux[0].x_sym.x_fcnary.x_fcn.x_lnnoptr;
+ RECORD_MINIMAL_SYMBOL
+ (namestring, symbol.n_value,
+ sclass == C_HIDEXT ? mst_file_text : mst_text,
+ secnum_to_section (symbol.n_scnum, objfile),
+ objfile);
+ break;
+
+ case XMC_GL:
+ /* shared library function trampoline code entry
+ point. */
+
+ /* record trampoline code entries as
+ mst_solib_trampoline symbol. When we lookup mst
+ symbols, we will choose mst_text over
+ mst_solib_trampoline. */
+ RECORD_MINIMAL_SYMBOL
+ (namestring, symbol.n_value,
+ mst_solib_trampoline,
+ secnum_to_section (symbol.n_scnum, objfile),
+ objfile);
+ break;
+
+ case XMC_DS:
+ /* The symbols often have the same names as
+ debug symbols for functions, and confuse
+ lookup_symbol. */
+ break;
+
+ default:
+
+ /* xlc puts each variable in a separate csect,
+ so we get an XTY_SD for each variable. But
+ gcc puts several variables in a csect, so
+ that each variable only gets an XTY_LD. We
+ still need to record them. This will
+ typically be XMC_RW; I suspect XMC_RO and
+ XMC_BS might be possible too. */
+ if (*namestring != '.')
+ prim_record_minimal_symbol_and_info
+ (namestring, symbol.n_value,
+ sclass == C_HIDEXT ? mst_file_data : mst_data,
+ NULL, secnum_to_section (symbol.n_scnum, objfile),
+ NULL, objfile);
+ break;
+ }
+ break;
+
+ case XTY_CM:
+ switch (csect_aux.x_csect.x_smclas)
+ {
+ case XMC_RW:
+ case XMC_BS:
+ /* Common variables are recorded in the minimal symbol
+ table, except for section symbols. */
+ if (*namestring != '.')
+ prim_record_minimal_symbol_and_info
+ (namestring, symbol.n_value,
+ sclass == C_HIDEXT ? mst_file_bss : mst_bss,
+ NULL, secnum_to_section (symbol.n_scnum, objfile),
+ NULL, objfile);
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+ case C_FILE:
+ {
+ unsigned int symnum_before;
+
+ symnum_before = ssymnum;
+ swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+ &ssymnum, objfile);
+
+ /* See if the last csect needs to be recorded. */
+
+ if (last_csect_name && !misc_func_recorded)
+ {
+
+ /* If no misc. function recorded in the last seen csect, enter
+ it as a function. This will take care of functions like
+ strcmp() compiled by xlc. */
+
+ RECORD_MINIMAL_SYMBOL
+ (last_csect_name, last_csect_val,
+ mst_text, last_csect_sec, objfile);
+ }
+
+ if (pst)
+ {
+ xcoff_end_psymtab (pst, psymtab_include_list, includes_used,
+ symnum_before, dependency_list,
+ dependencies_used, textlow_not_set);
+ includes_used = 0;
+ dependencies_used = 0;
+ }
+ first_fun_line_offset = 0;
+
+ /* XCOFF, according to the AIX 3.2 documentation, puts the
+ filename in cs->c_name. But xlc 1.3.0.2 has decided to
+ do things the standard COFF way and put it in the auxent.
+ We use the auxent if the symbol is ".file" and an auxent
+ exists, otherwise use the symbol itself. */
+ if (!strcmp (namestring, ".file") && symbol.n_numaux > 0)
+ {
+ filestring = coff_getfilename (&main_aux[0], objfile);
+ }
+ else
+ filestring = namestring;
+
+ pst = xcoff_start_psymtab (objfile,
+ filestring,
+ symnum_before,
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
+ last_csect_name = NULL;
+ }
+ break;
+
+ default:
+ {
+ static struct complaint msg =
+ {"Storage class %d not recognized during scan", 0, 0};
+ complain (&msg, sclass);
+ }
+ /* FALLTHROUGH */
+
+ /* C_FCN is .bf and .ef symbols. I think it is sufficient
+ to handle only the C_FUN and C_EXT. */
+ case C_FCN:
+
+ case C_BSTAT:
+ case C_ESTAT:
+ case C_ARG:
+ case C_REGPARM:
+ case C_REG:
+ case C_TPDEF:
+ case C_STRTAG:
+ case C_UNTAG:
+ case C_ENTAG:
+ case C_LABEL:
+ case C_NULL:
+
+ /* C_EINCL means we are switching back to the main file. But there
+ is no reason to care; the only thing we want to know about
+ includes is the names of all the included (.h) files. */
+ case C_EINCL:
+
+ case C_BLOCK:
+
+ /* I don't think C_STAT is used in xcoff; C_HIDEXT appears to be
+ used instead. */
+ case C_STAT:
+
+ /* I don't think the name of the common block (as opposed to the
+ variables within it) is something which is user visible
+ currently. */
+ case C_BCOMM:
+ case C_ECOMM:
+
+ case C_PSYM:
+ case C_RPSYM:
+
+ /* I think we can ignore C_LSYM; types on xcoff seem to use C_DECL
+ so C_LSYM would appear to be only for locals. */
+ case C_LSYM:
+
+ case C_AUTO:
+ case C_RSYM:
+ {
+ /* We probably could save a few instructions by assuming that
+ C_LSYM, C_PSYM, etc., never have auxents. */
+ int naux1 = symbol.n_numaux + 1;
+ ssymnum += naux1;
+ sraw_symbol += bfd_coff_symesz (abfd) * naux1;
+ }
+ break;
+
+ case C_BINCL:
+ {
+ /* Mark down an include file in the current psymtab */
+ enum language tmp_language;
+ swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+ &ssymnum, objfile);
+
+ tmp_language = deduce_language_from_filename (namestring);
+
+ /* Only change the psymtab's language if we've learned
+ something useful (eg. tmp_language is not language_unknown).
+ In addition, to match what start_subfile does, never change
+ from C++ to C. */
+ if (tmp_language != language_unknown
+ && (tmp_language != language_c
+ || psymtab_language != language_cplus))
+ psymtab_language = tmp_language;
+
+ /* In C++, one may expect the same filename to come round many
+ times, when code is coming alternately from the main file
+ and from inline functions in other files. So I check to see
+ if this is a file we've seen before -- either the main
+ source file, or a previously included file.
+
+ This seems to be a lot of time to be spending on N_SOL, but
+ things like "break c-exp.y:435" need to work (I
+ suppose the psymtab_include_list could be hashed or put
+ in a binary tree, if profiling shows this is a major hog). */
+ if (pst && STREQ (namestring, pst->filename))
+ continue;
+ {
+ register int i;
+ for (i = 0; i < includes_used; i++)
+ if (STREQ (namestring, psymtab_include_list[i]))
+ {
+ i = -1;
+ break;
+ }
+ if (i == -1)
+ continue;
+ }
+ psymtab_include_list[includes_used++] = namestring;
+ if (includes_used >= includes_allocated)
+ {
+ char **orig = psymtab_include_list;
+
+ psymtab_include_list = (char **)
+ alloca ((includes_allocated *= 2) *
+ sizeof (char *));
+ memcpy ((PTR) psymtab_include_list, (PTR) orig,
+ includes_used * sizeof (char *));
+ }
+ continue;
+ }
+ case C_FUN:
+ /* The value of the C_FUN is not the address of the function (it
+ appears to be the address before linking), but as long as it
+ is smaller than the actual address, then find_pc_partial_function
+ will use the minimal symbols instead. I hope. */
+
+ case C_GSYM:
+ case C_ECOML:
+ case C_DECL:
+ case C_STSYM:
+ {
+
+ static struct complaint function_outside_compilation_unit = {
+ "function `%s' appears to be defined outside of all compilation units", 0, 0
+ };
+
+ char *p;
+ swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
+ &ssymnum, objfile);
+
+ p = (char *) strchr (namestring, ':');
+ if (!p)
+ continue; /* Not a debugging symbol. */
+
+ /* Main processing section for debugging symbols which
+ the initial read through the symbol tables needs to worry
+ about. If we reach this point, the symbol which we are
+ considering is definitely one we are interested in.
+ p must also contain the (valid) index into the namestring
+ which indicates the debugging type symbol. */
+
+ switch (p[1])
+ {
+ case 'S':
+ symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+#ifdef STATIC_TRANSFORM_NAME
+ namestring = STATIC_TRANSFORM_NAME (namestring);
+#endif
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->static_psymbols,
+ 0, symbol.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ case 'G':
+ symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ /* The addresses in these entries are reported to be
+ wrong. See the code that reads 'G's for symtabs. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_STATIC,
+ &objfile->global_psymbols,
+ 0, symbol.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ case 'T':
+ /* When a 'T' entry is defining an anonymous enum, it
+ may have a name which is the empty string, or a
+ single space. Since they're not really defining a
+ symbol, those shouldn't go in the partial symbol
+ table. We do pick up the elements of such enums at
+ 'check_enum:', below. */
+ if (p >= namestring + 2
+ || (p == namestring + 1
+ && namestring[0] != ' '))
+ {
+ add_psymbol_to_list (namestring, p - namestring,
+ STRUCT_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ symbol.n_value, 0,
+ psymtab_language, objfile);
+ if (p[2] == 't')
+ {
+ /* Also a typedef with the same name. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ symbol.n_value, 0,
+ psymtab_language, objfile);
+ p += 1;
+ }
+ /* The semantics of C++ state that "struct foo { ... }"
+ also defines a typedef for "foo". Unfortuantely, cfront
+ never makes the typedef when translating from C++ to C.
+ We make the typedef here so that "ptype foo" works as
+ expected for cfront translated code. */
+ else if (psymtab_language == language_cplus)
+ {
+ /* Also a typedef with the same name. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ symbol.n_value, 0,
+ psymtab_language, objfile);
+ }
+ }
+ goto check_enum;
+
+ case 't':
+ if (p != namestring) /* a name is there, not just :T... */
+ {
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ symbol.n_value, 0,
+ psymtab_language, objfile);
+ }
+ check_enum:
+ /* If this is an enumerated type, we need to
+ add all the enum constants to the partial symbol
+ table. This does not cover enums without names, e.g.
+ "enum {a, b} c;" in C, but fortunately those are
+ rare. There is no way for GDB to find those from the
+ enum type without spending too much time on it. Thus
+ to solve this problem, the compiler needs to put out the
+ enum in a nameless type. GCC2 does this. */
+
+ /* We are looking for something of the form
+ <name> ":" ("t" | "T") [<number> "="] "e"
+ {<constant> ":" <value> ","} ";". */
+
+ /* Skip over the colon and the 't' or 'T'. */
+ p += 2;
+ /* This type may be given a number. Also, numbers can come
+ in pairs like (0,26). Skip over it. */
+ while ((*p >= '0' && *p <= '9')
+ || *p == '(' || *p == ',' || *p == ')'
+ || *p == '=')
+ p++;
+
+ if (*p++ == 'e')
+ {
+ /* The aix4 compiler emits extra crud before the members. */
+ if (*p == '-')
+ {
+ /* Skip over the type (?). */
+ while (*p != ':')
+ p++;
+
+ /* Skip over the colon. */
+ p++;
+ }
+
+ /* We have found an enumerated type. */
+ /* According to comments in read_enum_type
+ a comma could end it instead of a semicolon.
+ I don't know where that happens.
+ Accept either. */
+ while (*p && *p != ';' && *p != ',')
+ {
+ char *q;
+
+ /* Check for and handle cretinous dbx symbol name
+ continuation! */
+ if (*p == '\\' || (*p == '?' && p[1] == '\0'))
+ p = next_symbol_text (objfile);
+
+ /* Point to the character after the name
+ of the enum constant. */
+ for (q = p; *q && *q != ':'; q++)
+ ;
+ /* Note that the value doesn't matter for
+ enum constants in psymtabs, just in symtabs. */
+ add_psymbol_to_list (p, q - p,
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols, 0,
+ 0, psymtab_language, objfile);
+ /* Point past the name. */
+ p = q;
+ /* Skip over the value. */
+ while (*p && *p != ',')
+ p++;
+ /* Advance past the comma. */
+ if (*p)
+ p++;
+ }
+ }
+ continue;
+
+ case 'c':
+ /* Constant, e.g. from "const" in Pascal. */
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_CONST,
+ &objfile->static_psymbols, symbol.n_value,
+ 0, psymtab_language, objfile);
+ continue;
+
+ case 'f':
+ if (! pst)
+ {
+ int name_len = p - namestring;
+ char *name = xmalloc (name_len + 1);
+ memcpy (name, namestring, name_len);
+ name[name_len] = '\0';
+ complain (&function_outside_compilation_unit, name);
+ xfree (name);
+ }
+ symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->static_psymbols,
+ 0, symbol.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ /* Global functions were ignored here, but now they
+ are put into the global psymtab like one would expect.
+ They're also in the minimal symbol table. */
+ case 'F':
+ if (! pst)
+ {
+ int name_len = p - namestring;
+ char *name = xmalloc (name_len + 1);
+ memcpy (name, namestring, name_len);
+ name[name_len] = '\0';
+ complain (&function_outside_compilation_unit, name);
+ xfree (name);
+ }
+ symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ add_psymbol_to_list (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_BLOCK,
+ &objfile->global_psymbols,
+ 0, symbol.n_value,
+ psymtab_language, objfile);
+ continue;
+
+ /* Two things show up here (hopefully); static symbols of
+ local scope (static used inside braces) or extensions
+ of structure symbols. We can ignore both. */
+ case 'V':
+ case '(':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ case '#': /* for symbol identification (used in live ranges) */
+ /* added to support cfront stabs strings */
+ case 'Z': /* for definition continuations */
+ case 'P': /* for prototypes */
+ continue;
+
+ case ':':
+ /* It is a C++ nested symbol. We don't need to record it
+ (I don't think); if we try to look up foo::bar::baz,
+ then symbols for the symtab containing foo should get
+ read in, I think. */
+ /* Someone says sun cc puts out symbols like
+ /foo/baz/maclib::/usr/local/bin/maclib,
+ which would get here with a symbol type of ':'. */
+ continue;
+
+ default:
+ /* Unexpected symbol descriptor. The second and subsequent stabs
+ of a continued stab can show up here. The question is
+ whether they ever can mimic a normal stab--it would be
+ nice if not, since we certainly don't want to spend the
+ time searching to the end of every string looking for
+ a backslash. */
+
+ complain (&unknown_symchar_complaint, p[1]);
+
+ /* Ignore it; perhaps it is an extension that we don't
+ know about. */
+ continue;
+ }
+ }
+ }
+ }
+
+ if (pst)
+ {
+ xcoff_end_psymtab (pst, psymtab_include_list, includes_used,
+ ssymnum, dependency_list,
+ dependencies_used, textlow_not_set);
+ }
+
+ /* Record the toc offset value of this symbol table into objfile structure.
+ If no XMC_TC0 is found, toc_offset should be zero. Another place to obtain
+ this information would be file auxiliary header. */
+
+ ((struct coff_symfile_info *) objfile->sym_private)->toc_offset = toc_offset;
+}
+
+/* Return the toc offset value for a given objfile. */
+
+CORE_ADDR
+get_toc_offset (struct objfile *objfile)
+{
+ if (objfile)
+ return ((struct coff_symfile_info *) objfile->sym_private)->toc_offset;
+ return 0;
+}
+
+/* Scan and build partial symbols for a symbol file.
+ We have been initialized by a call to dbx_symfile_init, which
+ put all the relevant info into a "struct dbx_symfile_info",
+ hung off the objfile structure.
+
+ SECTION_OFFSETS contains offsets relative to which the symbols in the
+ various sections are (depending where the sections were actually loaded).
+ MAINLINE is true if we are reading the main symbol
+ table (as opposed to a shared lib or dynamically loaded file). */
+
+static void
+xcoff_initial_scan (struct objfile *objfile, int mainline)
+{
+ bfd *abfd;
+ int val;
+ struct cleanup *back_to;
+ int num_symbols; /* # of symbols */
+ file_ptr symtab_offset; /* symbol table and */
+ file_ptr stringtab_offset; /* string table file offsets */
+ struct coff_symfile_info *info;
+ char *name;
+ unsigned int size;
+
+ info = (struct coff_symfile_info *) objfile->sym_private;
+ symfile_bfd = abfd = objfile->obfd;
+ name = objfile->name;
+
+ num_symbols = bfd_get_symcount (abfd); /* # of symbols */
+ symtab_offset = obj_sym_filepos (abfd); /* symbol table file offset */
+ stringtab_offset = symtab_offset +
+ num_symbols * coff_data (abfd)->local_symesz;
+
+ info->min_lineno_offset = 0;
+ info->max_lineno_offset = 0;
+ bfd_map_over_sections (abfd, find_linenos, info);
+
+ if (num_symbols > 0)
+ {
+ /* Read the string table. */
+ init_stringtab (abfd, stringtab_offset, objfile);
+
+ /* Read the .debug section, if present. */
+ {
+ sec_ptr secp;
+ bfd_size_type length;
+ char *debugsec = NULL;
+
+ secp = bfd_get_section_by_name (abfd, ".debug");
+ if (secp)
+ {
+ length = bfd_section_size (abfd, secp);
+ if (length)
+ {
+ debugsec =
+ (char *) obstack_alloc (&objfile->symbol_obstack, length);
+
+ if (!bfd_get_section_contents (abfd, secp, debugsec,
+ (file_ptr) 0, length))
+ {
+ error ("Error reading .debug section of `%s': %s",
+ name, bfd_errmsg (bfd_get_error ()));
+ }
+ }
+ }
+ ((struct coff_symfile_info *) objfile->sym_private)->debugsec =
+ debugsec;
+ }
+ }
+
+ /* Read the symbols. We keep them in core because we will want to
+ access them randomly in read_symbol*. */
+ val = bfd_seek (abfd, symtab_offset, SEEK_SET);
+ if (val < 0)
+ error ("Error reading symbols from %s: %s",
+ name, bfd_errmsg (bfd_get_error ()));
+ size = coff_data (abfd)->local_symesz * num_symbols;
+ ((struct coff_symfile_info *) objfile->sym_private)->symtbl =
+ obstack_alloc (&objfile->symbol_obstack, size);
+ ((struct coff_symfile_info *) objfile->sym_private)->symtbl_num_syms =
+ num_symbols;
+
+ val = bfd_bread (((struct coff_symfile_info *) objfile->sym_private)->symtbl,
+ size, abfd);
+ if (val != size)
+ perror_with_name ("reading symbol table");
+
+ /* If we are reinitializing, or if we have never loaded syms yet, init */
+ if (mainline
+ || (objfile->global_psymbols.size == 0
+ && objfile->static_psymbols.size == 0))
+ /* I'm not sure how how good num_symbols is; the rule of thumb in
+ init_psymbol_list was developed for a.out. On the one hand,
+ num_symbols includes auxents. On the other hand, it doesn't
+ include N_SLINE. */
+ init_psymbol_list (objfile, num_symbols);
+
+ free_pending_blocks ();
+ back_to = make_cleanup (really_free_pendings, 0);
+
+ init_minimal_symbol_collection ();
+ make_cleanup_discard_minimal_symbols ();
+
+ /* Now that the symbol table data of the executable file are all in core,
+ process them and define symbols accordingly. */
+
+ scan_xcoff_symtab (objfile);
+
+ /* Install any minimal symbols that have been collected as the current
+ minimal symbols for this objfile. */
+
+ install_minimal_symbols (objfile);
+
+ do_cleanups (back_to);
+}
+
+static void
+xcoff_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs)
+{
+ asection *sect = NULL;
+ int i;
+
+ objfile->num_sections = SECT_OFF_MAX;
+ objfile->section_offsets = (struct section_offsets *)
+ obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
+
+ /* Initialize the section indexes for future use. */
+ sect = bfd_get_section_by_name (objfile->obfd, ".text");
+ if (sect)
+ objfile->sect_index_text = sect->index;
+
+ sect = bfd_get_section_by_name (objfile->obfd, ".data");
+ if (sect)
+ objfile->sect_index_data = sect->index;
+
+ sect = bfd_get_section_by_name (objfile->obfd, ".bss");
+ if (sect)
+ objfile->sect_index_bss = sect->index;
+
+ sect = bfd_get_section_by_name (objfile->obfd, ".rodata");
+ if (sect)
+ objfile->sect_index_rodata = sect->index;
+
+ for (i = 0; i < objfile->num_sections; ++i)
+ {
+ /* syms_from_objfile kindly subtracts from addr the
+ bfd_section_vma of the .text section. This strikes me as
+ wrong--whether the offset to be applied to symbol reading is
+ relative to the start address of the section depends on the
+ symbol format. In any event, this whole "addr" concept is
+ pretty broken (it doesn't handle any section but .text
+ sensibly), so just ignore the addr parameter and use 0.
+ rs6000-nat.c will set the correct section offsets via
+ objfile_relocate. */
+ (objfile->section_offsets)->offsets[i] = 0;
+ }
+}
+
+/* Register our ability to parse symbols for xcoff BFD files. */
+
+static struct sym_fns xcoff_sym_fns =
+{
+
+ /* It is possible that coff and xcoff should be merged as
+ they do have fundamental similarities (for example, the extra storage
+ classes used for stabs could presumably be recognized in any COFF file).
+ However, in addition to obvious things like all the csect hair, there are
+ some subtler differences between xcoffread.c and coffread.c, notably
+ the fact that coffread.c has no need to read in all the symbols, but
+ xcoffread.c reads all the symbols and does in fact randomly access them
+ (in C_BSTAT and line number processing). */
+
+ bfd_target_xcoff_flavour,
+
+ xcoff_new_init, /* sym_new_init: init anything gbl to entire symtab */
+ xcoff_symfile_init, /* sym_init: read initial info, setup for sym_read() */
+ xcoff_initial_scan, /* sym_read: read a symbol file into symtab */
+ xcoff_symfile_finish, /* sym_finish: finished with file, cleanup */
+ xcoff_symfile_offsets, /* sym_offsets: xlate offsets ext->int form */
+ NULL /* next: pointer to next struct sym_fns */
+};
+
+void
+_initialize_xcoffread (void)
+{
+ add_symtab_fns (&xcoff_sym_fns);
+
+ func_symbol_type = init_type (TYPE_CODE_FUNC, 1, 0,
+ "<function, no debug info>", NULL);
+ TYPE_TARGET_TYPE (func_symbol_type) = builtin_type_int;
+ var_symbol_type =
+ init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0,
+ "<variable, no debug info>", NULL);
+}
diff --git a/gdb/xcoffsolib.c b/gdb/xcoffsolib.c
new file mode 100644
index 00000000000..99d2cc8e8f7
--- /dev/null
+++ b/gdb/xcoffsolib.c
@@ -0,0 +1,196 @@
+/* Shared library support for RS/6000 (xcoff) object files, for GDB.
+ Copyright 1991, 1992, 1995, 1996, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+ Contributed by IBM Corporation.
+
+ 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 "defs.h"
+#include "bfd.h"
+#include "xcoffsolib.h"
+#include "inferior.h"
+#include "gdbcmd.h"
+#include "symfile.h"
+#include "frame.h"
+#include "gdb_regex.h"
+
+
+/* If ADDR lies in a shared library, return its name.
+ Note that returned name points to static data whose content is overwritten
+ by each call. */
+
+char *
+xcoff_solib_address (CORE_ADDR addr)
+{
+ static char *buffer = NULL;
+ struct vmap *vp = vmap;
+
+ /* The first vmap entry is for the exec file. */
+
+ if (vp == NULL)
+ return NULL;
+ for (vp = vp->nxt; vp; vp = vp->nxt)
+ if (vp->tstart <= addr && addr < vp->tend)
+ {
+ xfree (buffer);
+ xasprintf (&buffer, "%s%s%s%s",
+ vp->name,
+ *vp->member ? "(" : "",
+ vp->member,
+ *vp->member ? ")" : "");
+ return buffer;
+ }
+ return NULL;
+}
+
+static void solib_info (char *, int);
+static void sharedlibrary_command (char *pattern, int from_tty);
+
+static void
+solib_info (char *args, int from_tty)
+{
+ struct vmap *vp = vmap;
+
+ /* Check for new shared libraries loaded with load (). */
+ if (! ptid_equal (inferior_ptid, null_ptid))
+ xcoff_relocate_symtab (PIDGET (inferior_ptid));
+
+ if (vp == NULL || vp->nxt == NULL)
+ {
+ printf_unfiltered ("No shared libraries loaded at this time.\n");
+ return;
+ }
+
+ /* Skip over the first vmap, it is the main program, always loaded. */
+ vp = vp->nxt;
+
+ printf_unfiltered ("\
+Text Range Data Range Syms Shared Object Library\n");
+
+ for (; vp != NULL; vp = vp->nxt)
+ {
+ printf_unfiltered ("0x%s-0x%s 0x%s-0x%s %s %s%s%s%s\n",
+ paddr (vp->tstart),paddr (vp->tend),
+ paddr (vp->dstart), paddr (vp->dend),
+ vp->loaded ? "Yes" : "No ",
+ vp->name,
+ *vp->member ? "(" : "",
+ vp->member,
+ *vp->member ? ")" : "");
+ }
+}
+
+static void
+sharedlibrary_command (char *pattern, int from_tty)
+{
+ dont_repeat ();
+
+ /* Check for new shared libraries loaded with load (). */
+ if (! ptid_equal (inferior_ptid, null_ptid))
+ xcoff_relocate_symtab (PIDGET (inferior_ptid));
+
+ if (pattern)
+ {
+ char *re_err = re_comp (pattern);
+
+ if (re_err)
+ error ("Invalid regexp: %s", re_err);
+ }
+
+ /* Walk the list of currently loaded shared libraries, and read
+ symbols for any that match the pattern --- or any whose symbols
+ aren't already loaded, if no pattern was given. */
+ {
+ int any_matches = 0;
+ int loaded_any_symbols = 0;
+ struct vmap *vp = vmap;
+
+ if (!vp)
+ return;
+
+ /* skip over the first vmap, it is the main program, always loaded. */
+ for (vp = vp->nxt; vp; vp = vp->nxt)
+ if (! pattern
+ || re_exec (vp->name)
+ || (*vp->member && re_exec (vp->member)))
+ {
+ any_matches = 1;
+
+ if (vp->loaded)
+ {
+ if (from_tty)
+ printf_unfiltered ("Symbols already loaded for %s\n",
+ vp->name);
+ }
+ else
+ {
+ if (vmap_add_symbols (vp))
+ loaded_any_symbols = 1;
+ }
+ }
+
+ if (from_tty && pattern && ! any_matches)
+ printf_unfiltered
+ ("No loaded shared libraries match the pattern `%s'.\n", pattern);
+
+ if (loaded_any_symbols)
+ {
+ /* Getting new symbols may change our opinion about what is
+ frameless. */
+ reinit_frame_cache ();
+ }
+ }
+}
+
+/* LOCAL FUNCTION
+
+ no_shared_libraries -- handle command to explicitly discard symbols
+ from shared libraries.
+
+ DESCRIPTION
+
+ Implements the command "nosharedlibrary", which discards symbols
+ that have been auto-loaded from shared libraries. Symbols from
+ shared libraries that were added by explicit request of the user
+ are not discarded. Also called from remote.c. */
+
+void
+no_shared_libraries (char *ignored, int from_tty)
+{
+ /* FIXME */
+}
+
+void
+_initialize_xcoffsolib (void)
+{
+ add_com ("sharedlibrary", class_files, sharedlibrary_command,
+ "Load shared object library symbols for files matching REGEXP.");
+ add_info ("sharedlibrary", solib_info,
+ "Status of loaded shared object libraries");
+
+ add_show_from_set
+ (add_set_cmd ("auto-solib-add", class_support, var_boolean,
+ (char *) &auto_solib_add,
+ "Set autoloading of shared library symbols.\n\
+If \"on\", symbols from all shared object libraries will be loaded\n\
+automatically when the inferior begins execution, when the dynamic linker\n\
+informs gdb that a new library has been loaded, or when attaching to the\n\
+inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.",
+ &setlist),
+ &showlist);
+}
diff --git a/gdb/xcoffsolib.h b/gdb/xcoffsolib.h
new file mode 100644
index 00000000000..d8370fa2d47
--- /dev/null
+++ b/gdb/xcoffsolib.h
@@ -0,0 +1,66 @@
+/* Data structures for RS/6000 shared libraries, for GDB.
+ Copyright 1991, 1992, 1993, 1994, 1996, 1997, 2000
+ 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. */
+
+/* The vmap struct is used to describe the virtual address space of
+ the target we are manipulating. The first entry is always the "exec"
+ file. Subsequent entries correspond to other objects that are
+ mapped into the address space of a process created from the "exec" file.
+ These are either in response to exec()ing the file, in which case all
+ shared libraries are loaded, or a "load" system call, followed by the
+ user's issuance of a "load" command. */
+
+#ifndef XCOFFSOLIB_H
+#define XCOFFSOLIB_H
+
+struct vmap
+ {
+ struct vmap *nxt; /* ptr to next in chain */
+ bfd *bfd; /* BFD for mappable object library */
+ char *name; /* ptr to object file name */
+ char *member; /* ptr to member name */
+ CORE_ADDR tstart; /* virtual addr where member is mapped */
+ CORE_ADDR tend; /* virtual upper bound of member */
+ CORE_ADDR tvma; /* virtual addr of text section in object file */
+ CORE_ADDR toffs; /* offset of text section in object file */
+ CORE_ADDR dstart; /* virtual address of data start */
+ CORE_ADDR dend; /* virtual address of data end */
+ CORE_ADDR dvma; /* virtual addr of data section in object file */
+
+ /* This is NULL for the exec-file. */
+ struct objfile *objfile;
+
+ unsigned loaded:1; /* True if symbols are loaded */
+ unsigned padding:15;
+ };
+
+
+struct vmap_and_bfd
+ {
+ bfd *pbfd;
+ struct vmap *pvmap;
+ };
+
+extern struct vmap *vmap;
+
+/* Add symbols for a vmap. */
+extern int vmap_add_symbols (struct vmap *vp);
+
+#endif
diff --git a/gdb/xmodem.c b/gdb/xmodem.c
new file mode 100644
index 00000000000..7b8d77d1055
--- /dev/null
+++ b/gdb/xmodem.c
@@ -0,0 +1,275 @@
+/* XMODEM support for GDB, the GNU debugger.
+ Copyright 1995, 2000, 2001 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 "defs.h"
+#include "serial.h"
+#include "target.h"
+#include "xmodem.h"
+
+/* These definitions are for xmodem protocol. */
+
+#define SOH 0x01
+#define STX 0x02
+#define ACK 0x06
+#define NAK 0x15
+#define EOT 0x04
+#define CANCEL 0x18
+
+static int blknum; /* XMODEM block number */
+static int crcflag; /* Sez we are using CRC's instead of cksums */
+
+static int
+readchar (struct serial *desc, int timeout)
+{
+ int c;
+
+ c = serial_readchar (desc, timeout);
+
+ if (remote_debug > 0)
+ fputc_unfiltered (c, gdb_stdlog);
+
+ if (c >= 0)
+ return c;
+
+ if (c == SERIAL_TIMEOUT)
+ error ("Timeout reading from remote system.");
+
+ perror_with_name ("xmodem.c:readchar()");
+}
+
+#define CRC16 0x1021 /* Generator polynomial (X^16 + X^12 + X^5 + 1) */
+
+static unsigned short *crctab;
+
+/* Call this to init the fast CRC-16 calculation table. */
+
+static void
+crcinit (void)
+{
+ static int crctab_inited = 0;
+ int val;
+
+ if (crctab_inited == 1)
+ return;
+
+ crctab = xmalloc (256 * sizeof (short));
+
+ for (val = 0; val <= 255; val++)
+ {
+ int i;
+ unsigned int crc;
+
+ crc = val << 8;
+
+ for (i = 0; i < 8; ++i)
+ {
+ crc <<= 1;
+
+ if (crc & 0x10000)
+ crc ^= CRC16;
+ }
+
+ crctab[val] = crc;
+ }
+
+ crctab_inited = 1;
+}
+
+/* Calculate a CRC-16 for the LEN byte message pointed at by P. */
+
+static unsigned short
+docrc (unsigned char *p, int len)
+{
+ unsigned short crc = 0;
+
+ while (len-- > 0)
+ crc = (crc << 8) ^ crctab[(crc >> 8) ^ *p++];
+
+ return crc;
+}
+
+/* Start up the transmit process. Reset state variables. Wait for receiver to
+ send NAK or CRC request. */
+
+int
+xmodem_init_xfer (struct serial *desc)
+{
+ int c;
+ int i;
+
+ blknum = 1;
+ crcflag = 0;
+ crcinit ();
+
+ for (i = 1; i <= 10; i++)
+ {
+ c = readchar (desc, 6);
+
+ switch (c)
+ {
+ case 'C':
+ crcflag = 1;
+ case NAK:
+ return 0;
+ default:
+ fprintf_unfiltered (gdb_stderr, "xmodem_init_xfer: Got unexpected character %c (0%o)\n", c, c);
+ continue;
+ case CANCEL: /* target aborted load */
+ fprintf_unfiltered (gdb_stderr, "Got a CANCEL from the target.\n");
+ continue;
+ }
+ }
+ error ("xmodem_init_xfer: Too many unexpected characters.");
+}
+
+/* Take 128 bytes of data and make a packet out of it.
+
+ * Each packet looks like this:
+ * +-----+-------+-------+------+-----+
+ * | SOH | Seq1. | Seq2. | data | SUM |
+ * +-----+-------+-------+------+-----+
+ * SOH = 0x01
+ * Seq1 = The sequence number.
+ * Seq2 = The complement of the sequence number.
+ * Data = A 128 bytes of data.
+ * SUM = Add the contents of the 128 bytes and use the low-order
+ * 8 bits of the result.
+ *
+ * send_xmodem_packet fills in the XMODEM fields of PACKET and sends it to the
+ * remote system. PACKET must be XMODEM_PACKETSIZE bytes long. The data must
+ * start 3 bytes after the beginning of the packet to leave room for the
+ * XMODEM header. LEN is the length of the data portion of the packet (and
+ * must be <= 128 bytes). If it is < 128 bytes, ^Z padding will be added.
+ */
+
+void
+xmodem_send_packet (struct serial *desc, unsigned char *packet, int len, int hashmark)
+{
+ int i;
+ int retries;
+ int pktlen;
+ int datasize;
+
+ /* build the packet header */
+
+ packet[1] = blknum;
+ packet[2] = ~blknum;
+
+ blknum++;
+
+ if (len <= XMODEM_DATASIZE)
+ {
+ packet[0] = SOH;
+ datasize = XMODEM_DATASIZE;
+ }
+ else if (len <= XMODEM_1KDATASIZE)
+ {
+ packet[0] = STX;
+ datasize = XMODEM_1KDATASIZE;
+ }
+ else
+ internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* Packet way too large */
+
+ /* Add ^Z padding if packet < 128 (or 1024) bytes */
+
+ memset (packet + 3 + len, '\026', datasize - len);
+
+ if (crcflag)
+ {
+ int crc;
+
+ crc = docrc (packet + 3, datasize);
+
+ packet[3 + datasize] = crc >> 8;
+ packet[3 + datasize + 1] = crc;
+ pktlen = datasize + 5;
+ }
+ else
+ {
+ int sum;
+
+ sum = 0;
+ for (i = 3; i < datasize + 3; i++)
+ sum += packet[i];
+
+ packet[3 + datasize] = sum; /* add the checksum */
+ pktlen = datasize + 4;
+ }
+
+ for (retries = 3; retries >= 0; retries--)
+ {
+ int c;
+
+ serial_write (desc, packet, pktlen);
+
+ c = readchar (desc, 3);
+ switch (c)
+ {
+ case ACK:
+ return;
+ case NAK:
+ if (!hashmark)
+ continue;
+ putchar_unfiltered ('-');
+ gdb_flush (gdb_stdout);
+ continue;
+ case CANCEL:
+ error ("xmodem_send_packet: Transfer aborted by receiver.");
+ default:
+ fprintf_unfiltered (gdb_stderr, "xmodem_send_packet: Got unexpected character %c (0%o)\n", c, c);
+ continue;
+ }
+ }
+
+ serial_write (desc, "\004", 1); /* Send an EOT */
+
+ error ("xmodem_send_packet: Excessive retries.");
+}
+
+/* Finish off the transfer. Send out the EOT, and wait for an ACK. */
+
+void
+xmodem_finish_xfer (struct serial *desc)
+{
+ int retries;
+
+ for (retries = 10; retries >= 0; retries--)
+ {
+ int c;
+
+ serial_write (desc, "\004", 1); /* Send an EOT */
+
+ c = readchar (desc, 3);
+ switch (c)
+ {
+ case ACK:
+ return;
+ case NAK:
+ continue;
+ case CANCEL:
+ error ("xmodem_finish_xfer: Transfer aborted by receiver.");
+ default:
+ fprintf_unfiltered (gdb_stderr, "xmodem_send_packet: Got unexpected character %c (0%o)\n", c, c);
+ continue;
+ }
+ }
+
+ error ("xmodem_finish_xfer: Excessive retries.");
+}
diff --git a/gdb/xmodem.h b/gdb/xmodem.h
new file mode 100644
index 00000000000..86c5008d159
--- /dev/null
+++ b/gdb/xmodem.h
@@ -0,0 +1,30 @@
+/* XMODEM support for GDB, the GNU debugger.
+ Copyright 1995, 2000 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. */
+
+int xmodem_init_xfer (struct serial *desc);
+void send_xmodem_packet (struct serial *desc, unsigned char *packet, int len,
+ int hashmark);
+void xmodem_finish_xfer (struct serial *desc);
+
+#define XMODEM_DATASIZE 128 /* The data size is ALWAYS 128 */
+#define XMODEM_1KDATASIZE 1024 /* Unless it's 1024!!! */
+#define XMODEM_PACKETSIZE 133 /* data + packet headers and crc */
+#define XMODEM_1KPACKETSIZE 1024 + 5 /* data + packet headers and crc */
+#define XMODEM_DATAOFFSET 3 /* Offset to start of actual data */
diff --git a/gdb/xstormy16-tdep.c b/gdb/xstormy16-tdep.c
new file mode 100644
index 00000000000..f8c20b70f28
--- /dev/null
+++ b/gdb/xstormy16-tdep.c
@@ -0,0 +1,1145 @@
+/* Target-dependent code for the Sanyo Xstormy16a (LC590000) processor.
+
+ Copyright 2001, 2002 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 "defs.h"
+#include "value.h"
+#include "inferior.h"
+#include "symfile.h"
+#include "arch-utils.h"
+#include "regcache.h"
+#include "gdbcore.h"
+#include "objfiles.h"
+
+struct gdbarch_tdep
+{
+ /* gdbarch target dependent data here. Currently unused for Xstormy16. */
+};
+
+/* Extra info which is saved in each frame_info. */
+struct frame_extra_info
+{
+ int framesize;
+ int frameless_p;
+};
+
+enum gdb_regnum
+{
+ /* Xstormy16 has 16 general purpose registers (R0-R15) plus PC.
+ Functions will return their values in register R2-R7 as they fit.
+ Otherwise a hidden pointer to an big enough area is given as argument
+ to the function in r2. Further arguments are beginning in r3 then.
+ R13 is used as frame pointer when GCC compiles w/o optimization
+ R14 is used as "PSW", displaying the CPU status.
+ R15 is used implicitely as stack pointer. */
+ E_R0_REGNUM,
+ E_R1_REGNUM,
+ E_R2_REGNUM, E_1ST_ARG_REGNUM = E_R2_REGNUM, E_PTR_RET_REGNUM = E_R2_REGNUM,
+ E_R3_REGNUM,
+ E_R4_REGNUM,
+ E_R5_REGNUM,
+ E_R6_REGNUM,
+ E_R7_REGNUM, E_LST_ARG_REGNUM = E_R7_REGNUM,
+ E_R8_REGNUM,
+ E_R9_REGNUM,
+ E_R10_REGNUM,
+ E_R11_REGNUM,
+ E_R12_REGNUM,
+ E_R13_REGNUM, E_FP_REGNUM = E_R13_REGNUM,
+ E_R14_REGNUM, E_PSW_REGNUM = E_R14_REGNUM,
+ E_R15_REGNUM, E_SP_REGNUM = E_R15_REGNUM,
+ E_PC_REGNUM,
+ E_NUM_REGS
+};
+
+/* Size of instructions, registers, etc. */
+enum
+{
+ xstormy16_inst_size = 2,
+ xstormy16_reg_size = 2,
+ xstormy16_pc_size = 4
+};
+
+/* Size of return datatype which fits into the remaining return registers. */
+#define E_MAX_RETTYPE_SIZE(regnum) ((E_LST_ARG_REGNUM - (regnum) + 1) \
+ * xstormy16_reg_size)
+
+/* Size of return datatype which fits into all return registers. */
+enum
+{
+ E_MAX_RETTYPE_SIZE_IN_REGS = E_MAX_RETTYPE_SIZE (E_R2_REGNUM)
+};
+
+
+/* Size of all registers as a whole. */
+enum
+{
+ E_ALL_REGS_SIZE = (E_NUM_REGS - 1) * xstormy16_reg_size + xstormy16_pc_size
+};
+
+/* Function: xstormy16_register_name
+ Returns the name of the standard Xstormy16 register N. */
+
+static char *
+xstormy16_register_name (int regnum)
+{
+ static char *register_names[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13",
+ "psw", "sp", "pc"
+ };
+
+ if (regnum < 0 ||
+ regnum >= sizeof (register_names) / sizeof (register_names[0]))
+ internal_error (__FILE__, __LINE__,
+ "xstormy16_register_name: illegal register number %d",
+ regnum);
+ else
+ return register_names[regnum];
+
+}
+
+/* Function: xstormy16_register_byte
+ Returns the byte position in the register cache for register N. */
+
+static int
+xstormy16_register_byte (int regnum)
+{
+ if (regnum < 0 || regnum >= E_NUM_REGS)
+ internal_error (__FILE__, __LINE__,
+ "xstormy16_register_byte: illegal register number %d",
+ regnum);
+ else
+ /* All registers occupy 2 bytes in the regcache except for PC
+ which is the last one. Therefore the byte position is still
+ simply a multiple of 2. */
+ return regnum * xstormy16_reg_size;
+}
+
+/* Function: xstormy16_register_raw_size
+ Returns the number of bytes occupied by the register on the target. */
+
+static int
+xstormy16_register_raw_size (int regnum)
+{
+ if (regnum < 0 || regnum >= E_NUM_REGS)
+ internal_error (__FILE__, __LINE__,
+ "xstormy16_register_raw_size: illegal register number %d",
+ regnum);
+ /* Only the PC has 4 Byte, all other registers 2 Byte. */
+ else if (regnum == E_PC_REGNUM)
+ return xstormy16_pc_size;
+ else
+ return xstormy16_reg_size;
+}
+
+/* Function: xstormy16_register_virtual_size
+ Returns the number of bytes occupied by the register as represented
+ internally by gdb. */
+
+static int
+xstormy16_register_virtual_size (int regnum)
+{
+ return xstormy16_register_raw_size (regnum);
+}
+
+/* Function: xstormy16_reg_virtual_type
+ Returns the default type for register N. */
+
+static struct type *
+xstormy16_reg_virtual_type (int regnum)
+{
+ if (regnum < 0 || regnum >= E_NUM_REGS)
+ internal_error (__FILE__, __LINE__,
+ "xstormy16_register_virtual_type: illegal register number %d",
+ regnum);
+ else if (regnum == E_PC_REGNUM)
+ return builtin_type_uint32;
+ else
+ return builtin_type_uint16;
+}
+
+/* Function: xstormy16_get_saved_register
+ Find a register's saved value on the call stack. */
+
+static void
+xstormy16_get_saved_register (char *raw_buffer,
+ int *optimized,
+ CORE_ADDR *addrp,
+ struct frame_info *fi,
+ int regnum, enum lval_type *lval)
+{
+ generic_get_saved_register (raw_buffer, optimized, addrp, fi, regnum, lval);
+}
+
+/* Function: xstormy16_type_is_scalar
+ Makes the decision if a given type is a scalar types. Scalar
+ types are returned in the registers r2-r7 as they fit. */
+
+static int
+xstormy16_type_is_scalar (struct type *t)
+{
+ return (TYPE_CODE(t) != TYPE_CODE_STRUCT
+ && TYPE_CODE(t) != TYPE_CODE_UNION
+ && TYPE_CODE(t) != TYPE_CODE_ARRAY);
+}
+
+/* Function: xstormy16_extract_return_value
+ Copy the function's return value into VALBUF.
+ This function is called only in the context of "target function calls",
+ ie. when the debugger forces a function to be called in the child, and
+ when the debugger forces a function to return prematurely via the
+ "return" command. */
+
+static void
+xstormy16_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ CORE_ADDR return_buffer;
+ int offset = 0;
+
+ if (xstormy16_type_is_scalar (type)
+ && TYPE_LENGTH (type) <= E_MAX_RETTYPE_SIZE_IN_REGS)
+ {
+ /* Scalar return values of <= 12 bytes are returned in
+ E_1ST_ARG_REGNUM to E_LST_ARG_REGNUM. */
+ memcpy (valbuf,
+ &regbuf[REGISTER_BYTE (E_1ST_ARG_REGNUM)] + offset,
+ TYPE_LENGTH (type));
+ }
+ else
+ {
+ /* Aggregates and return values > 12 bytes are returned in memory,
+ pointed to by R2. */
+ return_buffer =
+ extract_address (regbuf + REGISTER_BYTE (E_PTR_RET_REGNUM),
+ REGISTER_RAW_SIZE (E_PTR_RET_REGNUM));
+
+ read_memory (return_buffer, valbuf, TYPE_LENGTH (type));
+ }
+}
+
+/* Function: xstormy16_push_arguments
+ Setup the function arguments for GDB to call a function in the inferior.
+ Called only in the context of a target function call from the debugger.
+ Returns the value of the SP register after the args are pushed.
+*/
+
+static CORE_ADDR
+xstormy16_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+ CORE_ADDR stack_dest = sp;
+ int argreg = E_1ST_ARG_REGNUM;
+ int i, j;
+ int typelen, slacklen;
+ char *val;
+
+ /* If struct_return is true, then the struct return address will
+ consume one argument-passing register. */
+ if (struct_return)
+ argreg++;
+
+ /* Arguments are passed in R2-R7 as they fit. If an argument doesn't
+ fit in the remaining registers we're switching over to the stack.
+ No argument is put on stack partially and as soon as we switched
+ over to stack no further argument is put in a register even if it
+ would fit in the remaining unused registers. */
+ for (i = 0; i < nargs && argreg <= E_LST_ARG_REGNUM; i++)
+ {
+ typelen = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
+ if (typelen > E_MAX_RETTYPE_SIZE (argreg))
+ break;
+
+ /* Put argument into registers wordwise. */
+ val = VALUE_CONTENTS (args[i]);
+ for (j = 0; j < typelen; j += xstormy16_reg_size)
+ write_register (argreg++,
+ extract_unsigned_integer (val + j,
+ typelen - j ==
+ 1 ? 1 :
+ xstormy16_reg_size));
+ }
+
+ /* Align SP */
+ if (stack_dest & 1)
+ ++stack_dest;
+
+ /* Loop backwards through remaining arguments and push them on the stack,
+ wordaligned. */
+ for (j = nargs - 1; j >= i; j--)
+ {
+ typelen = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[j]));
+ slacklen = typelen & 1;
+ val = alloca (typelen + slacklen);
+ memcpy (val, VALUE_CONTENTS (args[j]), typelen);
+ memset (val + typelen, 0, slacklen);
+
+ /* Now write this data to the stack. The stack grows upwards. */
+ write_memory (stack_dest, val, typelen + slacklen);
+ stack_dest += typelen + slacklen;
+ }
+
+ /* And that should do it. Return the new stack pointer. */
+ return stack_dest;
+}
+
+/* Function: xstormy16_push_return_address (pc)
+ Setup the return address for GDB to call a function in the inferior.
+ Called only in the context of a target function call from the debugger.
+ Returns the value of the SP register when the operation is finished
+ (which may or may not be the same as before).
+*/
+
+CORE_ADDR
+xstormy16_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
+{
+ unsigned char buf[xstormy16_pc_size];
+
+ store_unsigned_integer (buf, xstormy16_pc_size, CALL_DUMMY_ADDRESS ());
+ write_memory (sp, buf, xstormy16_pc_size);
+ return sp + xstormy16_pc_size;
+}
+
+/* Function: xstormy16_pop_frame
+ Destroy the innermost (Top-Of-Stack) stack frame, restoring the
+ machine state that was in effect before the frame was created.
+ Used in the contexts of the "return" command, and of
+ target function calls from the debugger.
+*/
+
+static void
+xstormy16_pop_frame (void)
+{
+ struct frame_info *fi = get_current_frame ();
+ int i;
+
+ if (fi == NULL)
+ return; /* paranoia */
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ generic_pop_dummy_frame ();
+ }
+ else
+ {
+ /* Restore the saved regs. */
+ for (i = 0; i < NUM_REGS; i++)
+ if (fi->saved_regs[i])
+ {
+ if (i == SP_REGNUM)
+ write_register (i, fi->saved_regs[i]);
+ else if (i == E_PC_REGNUM)
+ write_register (i, read_memory_integer (fi->saved_regs[i],
+ xstormy16_pc_size));
+ else
+ write_register (i, read_memory_integer (fi->saved_regs[i],
+ xstormy16_reg_size));
+ }
+ /* Restore the PC */
+ write_register (PC_REGNUM, FRAME_SAVED_PC (fi));
+ flush_cached_frames ();
+ }
+ return;
+}
+
+/* Function: xstormy16_store_struct_return
+ Copy the (struct) function return value to its destined location.
+ Called only in the context of a target function call from the debugger.
+*/
+
+static void
+xstormy16_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ write_register (E_PTR_RET_REGNUM, addr);
+}
+
+/* Function: xstormy16_store_return_value
+ Copy the function return value from VALBUF into the
+ proper location for a function return.
+ Called only in the context of the "return" command.
+*/
+
+static void
+xstormy16_store_return_value (struct type *type, char *valbuf)
+{
+ CORE_ADDR return_buffer;
+ char buf[xstormy16_reg_size];
+
+ if (xstormy16_type_is_scalar (type) && TYPE_LENGTH (type) == 1)
+ {
+ /* Add leading zeros to the value. */
+ memset (buf, 0, xstormy16_reg_size);
+ memcpy (buf, valbuf, 1);
+ write_register_gen (E_1ST_ARG_REGNUM, buf);
+ }
+ else if (xstormy16_type_is_scalar (type) &&
+ TYPE_LENGTH (type) <= E_MAX_RETTYPE_SIZE_IN_REGS)
+ write_register_bytes (REGISTER_BYTE (E_1ST_ARG_REGNUM),
+ valbuf, TYPE_LENGTH (type));
+ else
+ {
+ return_buffer = read_register (E_PTR_RET_REGNUM);
+ write_memory (return_buffer, valbuf, TYPE_LENGTH (type));
+ }
+}
+
+/* Function: xstormy16_extract_struct_value_address
+ Returns the address in which a function should return a struct value.
+ Used in the contexts of the "return" command, and of
+ target function calls from the debugger.
+*/
+
+static CORE_ADDR
+xstormy16_extract_struct_value_address (char *regbuf)
+{
+ return extract_address (regbuf +
+ xstormy16_register_byte (E_PTR_RET_REGNUM),
+ xstormy16_reg_size);
+}
+
+/* Function: xstormy16_use_struct_convention
+ Returns non-zero if the given struct type will be returned using
+ a special convention, rather than the normal function return method.
+ 7sed in the contexts of the "return" command, and of
+ target function calls from the debugger.
+*/
+
+static int
+xstormy16_use_struct_convention (int gcc_p, struct type *type)
+{
+ return !xstormy16_type_is_scalar (type)
+ || TYPE_LENGTH (type) > E_MAX_RETTYPE_SIZE_IN_REGS;
+}
+
+/* Function: frame_saved_register
+ Returns the value that regnum had in frame fi
+ (saved in fi or in one of its children).
+*/
+
+static CORE_ADDR
+xstormy16_frame_saved_register (struct frame_info *fi, int regnum)
+{
+ int size = xstormy16_register_raw_size (regnum);
+ char *buf = (char *) alloca (size);
+
+ generic_get_saved_register (buf, NULL, NULL, fi, regnum, NULL);
+ return (CORE_ADDR) extract_unsigned_integer (buf, size);
+}
+
+/* Function: xstormy16_scan_prologue
+ Decode the instructions within the given address range.
+ Decide when we must have reached the end of the function prologue.
+ If a frame_info pointer is provided, fill in its saved_regs etc.
+
+ Returns the address of the first instruction after the prologue.
+*/
+
+static CORE_ADDR
+xstormy16_scan_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
+ struct frame_info *fi, int *frameless)
+{
+ CORE_ADDR sp = 0, fp = 0;
+ CORE_ADDR next_addr;
+ ULONGEST inst, inst2;
+ LONGEST offset;
+ int regnum;
+
+ if (frameless)
+ *frameless = 1;
+ if (fi)
+ {
+ /* In a call dummy, don't touch the frame. */
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return start_addr;
+
+ /* Grab the frame-relative values of SP and FP, needed below.
+ The frame_saved_register function will find them on the
+ stack or in the registers as appropriate. */
+ sp = xstormy16_frame_saved_register (fi, E_SP_REGNUM);
+ fp = xstormy16_frame_saved_register (fi, E_FP_REGNUM);
+
+ /* Initialize framesize with size of PC put on stack by CALLF inst. */
+ fi->extra_info->framesize = xstormy16_pc_size;
+ }
+ for (next_addr = start_addr;
+ next_addr < end_addr; next_addr += xstormy16_inst_size)
+ {
+ inst = read_memory_unsigned_integer (next_addr, xstormy16_inst_size);
+ inst2 = read_memory_unsigned_integer (next_addr + xstormy16_inst_size,
+ xstormy16_inst_size);
+
+ if (inst >= 0x0082 && inst <= 0x008d) /* push r2 .. push r13 */
+ {
+ if (fi)
+ {
+ regnum = inst & 0x000f;
+ fi->saved_regs[regnum] = fi->extra_info->framesize;
+ fi->extra_info->framesize += xstormy16_reg_size;
+ }
+ }
+
+ /* optional stack allocation for args and local vars <= 4 byte */
+ else if (inst == 0x301f || inst == 0x303f) /* inc r15, #0x1/#0x3 */
+ {
+ if (fi) /* Record the frame size. */
+ fi->extra_info->framesize += ((inst & 0x0030) >> 4) + 1;
+ }
+
+ /* optional stack allocation for args and local vars > 4 && < 16 byte */
+ else if ((inst & 0xff0f) == 0x510f) /* 51Hf add r15, #0xH */
+ {
+ if (fi) /* Record the frame size. */
+ fi->extra_info->framesize += (inst & 0x00f0) >> 4;
+ }
+
+ /* optional stack allocation for args and local vars >= 16 byte */
+ else if (inst == 0x314f && inst2 >= 0x0010) /* 314f HHHH add r15, #0xH */
+ {
+ if (fi) /* Record the frame size. */
+ fi->extra_info->framesize += inst2;
+ next_addr += xstormy16_inst_size;
+ }
+
+ else if (inst == 0x46fd) /* mov r13, r15 */
+ {
+ if (fi) /* Record that the frame pointer is in use. */
+ fi->extra_info->frameless_p = 0;
+ if (frameless)
+ *frameless = 0;
+ }
+
+ /* optional copying of args in r2-r7 to r10-r13 */
+ /* Probably only in optimized case but legal action for prologue */
+ else if ((inst & 0xff00) == 0x4600 /* 46SD mov rD, rS */
+ && (inst & 0x00f0) >= 0x0020 && (inst & 0x00f0) <= 0x0070
+ && (inst & 0x000f) >= 0x00a0 && (inst & 0x000f) <= 0x000d)
+ ;
+
+ /* optional copying of args in r2-r7 to stack */
+ /* 72DS HHHH mov.b (rD, 0xHHHH), r(S-8) (bit3 always 1, bit2-0 = reg) */
+ /* 73DS HHHH mov.w (rD, 0xHHHH), r(S-8) */
+ else if ((inst & 0xfed8) == 0x72d8 && (inst & 0x0007) >= 2)
+ {
+ if (fi)
+ {
+ regnum = inst & 0x0007;
+ /* Only 12 of 16 bits of the argument are used for the
+ signed offset. */
+ offset = (LONGEST) (inst2 & 0x0fff);
+ if (offset & 0x0800)
+ offset -= 0x1000;
+
+ fi->saved_regs[regnum] = fi->extra_info->framesize + offset;
+ }
+ next_addr += xstormy16_inst_size;
+ }
+
+#if 0
+ /* 2001-08-10: Not part of the prologue anymore due to change in
+ ABI. r8 and r9 are not used for argument passing anymore. */
+
+ /* optional copying of r8, r9 to stack */
+ /* 46S7; 73Df HHHH mov.w r7,rS; mov.w (rD, 0xHHHH), r7 D=8,9; S=13,15 */
+ /* 46S7; 72df HHHH mov.w r7,rS; mov.b (rD, 0xHHHH), r7 D=8,9; S=13,15 */
+ else if ((inst & 0xffef) == 0x4687 && (inst2 & 0xfedf) == 0x72df)
+ {
+ next_addr += xstormy16_inst_size;
+ if (fi)
+ {
+ regnum = (inst & 0x00f0) >> 4;
+ inst = inst2;
+ inst2 = read_memory_unsigned_integer (next_addr
+ + xstormy16_inst_size,
+ xstormy16_inst_size);
+ /* Only 12 of 16 bits of the argument are used for the
+ signed offset. */
+ offset = (LONGEST) (inst2 & 0x0fff);
+ if (offset & 0x0800)
+ offset -= 0x1000;
+
+ fi->saved_regs[regnum] = fi->extra_info->framesize + offset;
+ }
+ next_addr += xstormy16_inst_size;
+ }
+#endif
+
+ else /* Not a prologue instruction. */
+ break;
+ }
+
+ if (fi)
+ {
+ /* Special handling for the "saved" address of the SP:
+ The SP is of course never saved on the stack at all, so
+ by convention what we put here is simply the previous
+ _value_ of the SP (as opposed to an address where the
+ previous value would have been pushed). */
+ if (fi->extra_info->frameless_p)
+ {
+ fi->saved_regs[E_SP_REGNUM] = sp - fi->extra_info->framesize;
+ fi->frame = sp;
+ }
+ else
+ {
+ fi->saved_regs[E_SP_REGNUM] = fp - fi->extra_info->framesize;
+ fi->frame = fp;
+ }
+
+ /* So far only offsets to the beginning of the frame are
+ saved in the saved_regs. Now we now the relation between
+ sp, fp and framesize. We know the beginning of the frame
+ so we can translate the register offsets to real addresses. */
+ for (regnum = 0; regnum < E_SP_REGNUM; ++regnum)
+ if (fi->saved_regs[regnum])
+ fi->saved_regs[regnum] += fi->saved_regs[E_SP_REGNUM];
+
+ /* Save address of PC on stack. */
+ fi->saved_regs[E_PC_REGNUM] = fi->saved_regs[E_SP_REGNUM];
+ }
+
+ return next_addr;
+}
+
+/* Function: xstormy16_skip_prologue
+ If the input address is in a function prologue,
+ returns the address of the end of the prologue;
+ else returns the input address.
+
+ Note: the input address is likely to be the function start,
+ since this function is mainly used for advancing a breakpoint
+ to the first line, or stepping to the first line when we have
+ stepped into a function call. */
+
+static CORE_ADDR
+xstormy16_skip_prologue (CORE_ADDR pc)
+{
+ CORE_ADDR func_addr = 0, func_end = 0;
+ char *func_name;
+
+ if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
+ {
+ struct symtab_and_line sal;
+ struct symbol *sym;
+
+ /* Don't trust line number debug info in frameless functions. */
+ int frameless = 1;
+ CORE_ADDR plg_end = xstormy16_scan_prologue (func_addr, func_end,
+ NULL, &frameless);
+ if (frameless)
+ return plg_end;
+
+ /* Found a function. */
+ sym = lookup_symbol (func_name, NULL, VAR_NAMESPACE, NULL, NULL);
+ /* Don't use line number debug info for assembly source files. */
+ if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
+ {
+ sal = find_pc_line (func_addr, 0);
+ if (sal.end && sal.end < func_end)
+ {
+ /* Found a line number, use it as end of prologue. */
+ return sal.end;
+ }
+ }
+ /* No useable line symbol. Use result of prologue parsing method. */
+ return plg_end;
+ }
+
+ /* No function symbol -- just return the PC. */
+
+ return (CORE_ADDR) pc;
+}
+
+/* The epilogue is defined here as the area at the end of a function,
+ either on the `ret' instruction itself or after an instruction which
+ destroys the function's stack frame. */
+static int
+xstormy16_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+ CORE_ADDR addr, func_addr = 0, func_end = 0;
+
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ ULONGEST inst, inst2;
+ CORE_ADDR addr = func_end - xstormy16_inst_size;
+
+ /* The Xstormy16 epilogue is max. 14 bytes long. */
+ if (pc < func_end - 7 * xstormy16_inst_size)
+ return 0;
+
+ /* Check if we're on a `ret' instruction. Otherwise it's
+ too dangerous to proceed. */
+ inst = read_memory_unsigned_integer (addr, xstormy16_inst_size);
+ if (inst != 0x0003)
+ return 0;
+
+ while ((addr -= xstormy16_inst_size) >= func_addr)
+ {
+ inst = read_memory_unsigned_integer (addr, xstormy16_inst_size);
+ if (inst >= 0x009a && inst <= 0x009d) /* pop r10...r13 */
+ continue;
+ if (inst == 0x305f || inst == 0x307f) /* dec r15, #0x1/#0x3 */
+ break;
+ inst2 = read_memory_unsigned_integer (addr - xstormy16_inst_size,
+ xstormy16_inst_size);
+ if (inst2 == 0x314f && inst >= 0x8000) /* add r15, neg. value */
+ {
+ addr -= xstormy16_inst_size;
+ break;
+ }
+ return 0;
+ }
+ if (pc > addr)
+ return 1;
+ }
+ return 0;
+}
+
+/* Function: xstormy16_frame_init_saved_regs
+ Set up the 'saved_regs' array.
+ This is a data structure containing the addresses on the stack
+ where each register has been saved, for each stack frame.
+ Registers that have not been saved will have zero here.
+ The stack register is special: rather than the address where the
+ stack register has been saved, saved_regs[SP_REGNUM] will have the
+ actual value of the previous frame's stack register.
+
+ This function may be called in any context where the saved register
+ values may be needed (backtrace, frame_info, get_saved_register).
+ On many targets, it is called directly by init_extra_frame_info,
+ in part because the information may be needed immediately by
+ frame_chain.
+*/
+
+static void
+xstormy16_frame_init_saved_regs (struct frame_info *fi)
+{
+ CORE_ADDR func_addr, func_end;
+
+ if (!fi->saved_regs)
+ {
+ frame_saved_regs_zalloc (fi);
+
+ /* Find the beginning of this function, so we can analyze its
+ prologue. */
+ if (find_pc_partial_function (fi->pc, NULL, &func_addr, &func_end))
+ xstormy16_scan_prologue (func_addr, fi->pc, fi, NULL);
+ /* Else we're out of luck (can't debug completely stripped code).
+ FIXME. */
+ }
+}
+
+/* Function: xstormy16_frame_saved_pc
+ Returns the return address for the selected frame.
+ Called by frame_info, frame_chain_valid, and sometimes by
+ get_prev_frame.
+*/
+
+static CORE_ADDR
+xstormy16_frame_saved_pc (struct frame_info *fi)
+{
+ CORE_ADDR saved_pc;
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ saved_pc = generic_read_register_dummy (fi->pc, fi->frame, E_PC_REGNUM);
+ }
+ else
+ {
+ saved_pc = read_memory_unsigned_integer (fi->saved_regs[E_PC_REGNUM],
+ xstormy16_pc_size);
+ }
+
+ return saved_pc;
+}
+
+/* Function: xstormy16_init_extra_frame_info
+ This is the constructor function for the frame_info struct,
+ called whenever a new frame_info is created (from create_new_frame,
+ and from get_prev_frame).
+*/
+
+static void
+xstormy16_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+ if (!fi->extra_info)
+ {
+ fi->extra_info = (struct frame_extra_info *)
+ frame_obstack_alloc (sizeof (struct frame_extra_info));
+ fi->extra_info->framesize = 0;
+ fi->extra_info->frameless_p = 1; /* Default frameless, detect framed */
+
+ /* By default, the fi->frame is set to the value of the FP reg by gdb.
+ This may not always be right; we may be in a frameless function,
+ or we may be in the prologue, before the FP has been set up.
+ Unfortunately, we can't make this determination without first
+ calling scan_prologue, and we can't do that unles we know the
+ fi->pc. */
+
+ if (!fi->pc)
+ {
+ /* Sometimes we are called from get_prev_frame without
+ the PC being set up first. Long history, don't ask.
+ Fortunately this will never happen from the outermost
+ frame, so we should be able to get the saved pc from
+ the next frame. */
+ if (fi->next)
+ fi->pc = xstormy16_frame_saved_pc (fi->next);
+ }
+
+ /* Take care of the saved_regs right here (non-lazy). */
+ xstormy16_frame_init_saved_regs (fi);
+ }
+}
+
+/* Function: xstormy16_frame_chain
+ Returns a pointer to the stack frame of the calling function.
+ Called only from get_prev_frame. Needed for backtrace, "up", etc.
+*/
+
+static CORE_ADDR
+xstormy16_frame_chain (struct frame_info *fi)
+{
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ /* Call dummy's frame is the same as caller's. */
+ return fi->frame;
+ }
+ else
+ {
+ /* Return computed offset from this frame's fp. */
+ return fi->frame - fi->extra_info->framesize;
+ }
+}
+
+static int
+xstormy16_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
+{
+ return chain < 0x8000 && FRAME_SAVED_PC (thisframe) >= 0x8000 &&
+ (thisframe->extra_info->frameless_p ||
+ thisframe->frame - thisframe->extra_info->framesize == chain);
+}
+
+/* Function: xstormy16_saved_pc_after_call
+ Returns the previous PC immediately after a function call.
+ This function is meant to bypass the regular get_saved_register
+ mechanism, ie. it is meant to work even if the frame isn't complete.
+ Called by step_over_function, and sometimes by get_prev_frame.
+*/
+
+static CORE_ADDR
+xstormy16_saved_pc_after_call (struct frame_info *ignore)
+{
+ CORE_ADDR sp, pc, tmp;
+
+ sp = read_register (E_SP_REGNUM) - xstormy16_pc_size;
+ pc = read_memory_integer (sp, xstormy16_pc_size);
+
+ /* Skip over jump table entry if necessary. */
+ if ((tmp = SKIP_TRAMPOLINE_CODE (pc)))
+ pc = tmp;
+
+ return pc;
+}
+
+const static unsigned char *
+xstormy16_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+ static unsigned char breakpoint[] = { 0x06, 0x0 };
+ *lenptr = sizeof (breakpoint);
+ return breakpoint;
+}
+
+/* Given a pointer to a jump table entry, return the address
+ of the function it jumps to. Return 0 if not found. */
+static CORE_ADDR
+xstormy16_resolve_jmp_table_entry (CORE_ADDR faddr)
+{
+ struct obj_section *faddr_sect = find_pc_section (faddr);
+
+ if (faddr_sect)
+ {
+ LONGEST inst, inst2, addr;
+ char buf[2 * xstormy16_inst_size];
+
+ /* Return faddr if it's not pointing into the jump table. */
+ if (strcmp (faddr_sect->the_bfd_section->name, ".plt"))
+ return faddr;
+
+ if (!target_read_memory (faddr, buf, sizeof buf))
+ {
+ inst = extract_unsigned_integer (buf, xstormy16_inst_size);
+ inst2 = extract_unsigned_integer (buf + xstormy16_inst_size,
+ xstormy16_inst_size);
+ addr = inst2 << 8 | (inst & 0xff);
+ return addr;
+ }
+ }
+ return 0;
+}
+
+/* Given a function's address, attempt to find (and return) the
+ address of the corresponding jump table entry. Return 0 if
+ not found. */
+static CORE_ADDR
+xstormy16_find_jmp_table_entry (CORE_ADDR faddr)
+{
+ struct obj_section *faddr_sect = find_pc_section (faddr);
+
+ if (faddr_sect)
+ {
+ struct obj_section *osect;
+
+ /* Return faddr if it's already a pointer to a jump table entry. */
+ if (!strcmp (faddr_sect->the_bfd_section->name, ".plt"))
+ return faddr;
+
+ ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
+ {
+ if (!strcmp (osect->the_bfd_section->name, ".plt"))
+ break;
+ }
+
+ if (osect < faddr_sect->objfile->sections_end)
+ {
+ CORE_ADDR addr;
+ for (addr = osect->addr;
+ addr < osect->endaddr; addr += 2 * xstormy16_inst_size)
+ {
+ int status;
+ LONGEST inst, inst2, faddr2;
+ char buf[2 * xstormy16_inst_size];
+
+ if (target_read_memory (addr, buf, sizeof buf))
+ return 0;
+ inst = extract_unsigned_integer (buf, xstormy16_inst_size);
+ inst2 = extract_unsigned_integer (buf + xstormy16_inst_size,
+ xstormy16_inst_size);
+ faddr2 = inst2 << 8 | (inst & 0xff);
+ if (faddr == faddr2)
+ return addr;
+ }
+ }
+ }
+ return 0;
+}
+
+static CORE_ADDR
+xstormy16_skip_trampoline_code (CORE_ADDR pc)
+{
+ int tmp = xstormy16_resolve_jmp_table_entry (pc);
+
+ if (tmp && tmp != pc)
+ return tmp;
+ return 0;
+}
+
+static int
+xstormy16_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+ return xstormy16_skip_trampoline_code (pc) != 0;
+}
+
+static CORE_ADDR
+xstormy16_pointer_to_address (struct type *type, void *buf)
+{
+ enum type_code target = TYPE_CODE (TYPE_TARGET_TYPE (type));
+ CORE_ADDR addr = extract_address (buf, TYPE_LENGTH (type));
+
+ if (target == TYPE_CODE_FUNC || target == TYPE_CODE_METHOD)
+ {
+ CORE_ADDR addr2 = xstormy16_resolve_jmp_table_entry (addr);
+ if (addr2)
+ addr = addr2;
+ }
+
+ return addr;
+}
+
+static void
+xstormy16_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr)
+{
+ enum type_code target = TYPE_CODE (TYPE_TARGET_TYPE (type));
+
+ if (target == TYPE_CODE_FUNC || target == TYPE_CODE_METHOD)
+ {
+ CORE_ADDR addr2 = xstormy16_find_jmp_table_entry (addr);
+ if (addr2)
+ addr = addr2;
+ }
+ store_address (buf, TYPE_LENGTH (type), addr);
+}
+
+static CORE_ADDR
+xstormy16_stack_align (CORE_ADDR addr)
+{
+ if (addr & 1)
+ ++addr;
+ return addr;
+}
+
+void
+xstormy16_save_dummy_frame_tos (CORE_ADDR sp)
+{
+ generic_save_dummy_frame_tos (sp - xstormy16_pc_size);
+}
+
+/* Function: xstormy16_gdbarch_init
+ Initializer function for the xstormy16 gdbarch vector.
+ Called by gdbarch. Sets up the gdbarch vector(s) for this target. */
+
+static struct gdbarch *
+xstormy16_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ static LONGEST call_dummy_words[1] = { 0 };
+ struct gdbarch_tdep *tdep = NULL;
+ struct gdbarch *gdbarch;
+
+ /* find a candidate among the list of pre-declared architectures. */
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+ if (arches != NULL)
+ return (arches->gdbarch);
+
+#if 0
+ tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
+#endif
+
+ gdbarch = gdbarch_alloc (&info, 0);
+
+ /*
+ * Basic register fields and methods.
+ */
+
+ set_gdbarch_num_regs (gdbarch, E_NUM_REGS);
+ set_gdbarch_num_pseudo_regs (gdbarch, 0);
+ set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
+ set_gdbarch_fp_regnum (gdbarch, E_FP_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
+ set_gdbarch_register_name (gdbarch, xstormy16_register_name);
+ set_gdbarch_register_size (gdbarch, xstormy16_reg_size);
+ set_gdbarch_register_bytes (gdbarch, E_ALL_REGS_SIZE);
+ set_gdbarch_register_byte (gdbarch, xstormy16_register_byte);
+ set_gdbarch_register_raw_size (gdbarch, xstormy16_register_raw_size);
+ set_gdbarch_max_register_raw_size (gdbarch, xstormy16_pc_size);
+ set_gdbarch_register_virtual_size (gdbarch, xstormy16_register_raw_size);
+ set_gdbarch_max_register_virtual_size (gdbarch, 4);
+ set_gdbarch_register_virtual_type (gdbarch, xstormy16_reg_virtual_type);
+
+ /*
+ * Frame Info
+ */
+ set_gdbarch_init_extra_frame_info (gdbarch,
+ xstormy16_init_extra_frame_info);
+ set_gdbarch_frame_init_saved_regs (gdbarch,
+ xstormy16_frame_init_saved_regs);
+ set_gdbarch_frame_chain (gdbarch, xstormy16_frame_chain);
+ set_gdbarch_get_saved_register (gdbarch, xstormy16_get_saved_register);
+ set_gdbarch_saved_pc_after_call (gdbarch, xstormy16_saved_pc_after_call);
+ set_gdbarch_frame_saved_pc (gdbarch, xstormy16_frame_saved_pc);
+ set_gdbarch_skip_prologue (gdbarch, xstormy16_skip_prologue);
+ set_gdbarch_frame_chain_valid (gdbarch, xstormy16_frame_chain_valid);
+ set_gdbarch_frame_args_address (gdbarch, default_frame_address);
+ set_gdbarch_frame_locals_address (gdbarch, default_frame_address);
+
+ set_gdbarch_in_function_epilogue_p (gdbarch,
+ xstormy16_in_function_epilogue_p);
+
+ /*
+ * Miscelany
+ */
+ /* Stack grows up. */
+ set_gdbarch_inner_than (gdbarch, core_addr_greaterthan);
+ /* PC stops zero byte after a trap instruction
+ (which means: exactly on trap instruction). */
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+ /* This value is almost never non-zero... */
+ set_gdbarch_function_start_offset (gdbarch, 0);
+ /* This value is almost never non-zero... */
+ set_gdbarch_frame_args_skip (gdbarch, 0);
+ /* OK to default this value to 'unknown'. */
+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+
+ /* W/o prototype, coerce float args to double. */
+ set_gdbarch_coerce_float_to_double (gdbarch,
+ standard_coerce_float_to_double);
+
+ /*
+ * Call Dummies
+ *
+ * These values and methods are used when gdb calls a target function. */
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+ set_gdbarch_push_return_address (gdbarch, xstormy16_push_return_address);
+ set_gdbarch_extract_return_value (gdbarch, xstormy16_extract_return_value);
+ set_gdbarch_push_arguments (gdbarch, xstormy16_push_arguments);
+ set_gdbarch_pop_frame (gdbarch, xstormy16_pop_frame);
+ set_gdbarch_store_struct_return (gdbarch, xstormy16_store_struct_return);
+ set_gdbarch_store_return_value (gdbarch, xstormy16_store_return_value);
+ set_gdbarch_extract_struct_value_address (gdbarch,
+ xstormy16_extract_struct_value_address);
+ set_gdbarch_use_struct_convention (gdbarch,
+ xstormy16_use_struct_convention);
+ set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
+ set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
+ set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+ set_gdbarch_call_dummy_length (gdbarch, 0);
+ set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
+ set_gdbarch_call_dummy_p (gdbarch, 1);
+ set_gdbarch_call_dummy_words (gdbarch, call_dummy_words);
+ set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ /* set_gdbarch_call_dummy_stack_adjust */
+ set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
+ set_gdbarch_breakpoint_from_pc (gdbarch, xstormy16_breakpoint_from_pc);
+
+ set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+
+ set_gdbarch_address_to_pointer (gdbarch, xstormy16_address_to_pointer);
+ set_gdbarch_pointer_to_address (gdbarch, xstormy16_pointer_to_address);
+
+ set_gdbarch_stack_align (gdbarch, xstormy16_stack_align);
+ set_gdbarch_extra_stack_alignment_needed (gdbarch, 0);
+
+ set_gdbarch_save_dummy_frame_tos (gdbarch, xstormy16_save_dummy_frame_tos);
+
+ set_gdbarch_skip_trampoline_code (gdbarch, xstormy16_skip_trampoline_code);
+
+ set_gdbarch_in_solib_call_trampoline (gdbarch,
+ xstormy16_in_solib_call_trampoline);
+
+ return gdbarch;
+}
+
+/* Function: _initialize_xstormy16_tdep
+ Initializer function for the Sanyo Xstormy16a module.
+ Called by gdb at start-up. */
+
+void
+_initialize_xstormy16_tdep (void)
+{
+ extern int print_insn_xstormy16 ();
+
+ register_gdbarch_init (bfd_arch_xstormy16, xstormy16_gdbarch_init);
+ tm_print_insn = print_insn_xstormy16;
+}
diff --git a/gdb/z8k-tdep.c b/gdb/z8k-tdep.c
new file mode 100644
index 00000000000..572a878dc20
--- /dev/null
+++ b/gdb/z8k-tdep.c
@@ -0,0 +1,430 @@
+/* Target-machine dependent code for Zilog Z8000, for GDB.
+
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+ 2002 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. */
+
+/*
+ Contributed by Steve Chamberlain
+ sac@cygnus.com
+ */
+
+#include "defs.h"
+#include "frame.h"
+#include "obstack.h"
+#include "symtab.h"
+#include "gdbcmd.h"
+#include "gdbtypes.h"
+#include "dis-asm.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#include "value.h" /* For read_register() */
+
+
+static int read_memory_pointer (CORE_ADDR x);
+
+/* Return the saved PC from this frame.
+
+ If the frame has a memory copy of SRP_REGNUM, use that. If not,
+ just use the register SRP_REGNUM itself. */
+
+CORE_ADDR
+z8k_frame_saved_pc (struct frame_info *frame)
+{
+ return read_memory_pointer (frame->frame + (BIG ? 4 : 2));
+}
+
+#define IS_PUSHL(x) (BIG ? ((x & 0xfff0) == 0x91e0):((x & 0xfff0) == 0x91F0))
+#define IS_PUSHW(x) (BIG ? ((x & 0xfff0) == 0x93e0):((x & 0xfff0)==0x93f0))
+#define IS_MOVE_FP(x) (BIG ? x == 0xa1ea : x == 0xa1fa)
+#define IS_MOV_SP_FP(x) (BIG ? x == 0x94ea : x == 0x0d76)
+#define IS_SUB2_SP(x) (x==0x1b87)
+#define IS_MOVK_R5(x) (x==0x7905)
+#define IS_SUB_SP(x) ((x & 0xffff) == 0x020f)
+#define IS_PUSH_FP(x) (BIG ? (x == 0x93ea) : (x == 0x93fa))
+
+/* work out how much local space is on the stack and
+ return the pc pointing to the first push */
+
+static CORE_ADDR
+skip_adjust (CORE_ADDR pc, int *size)
+{
+ *size = 0;
+
+ if (IS_PUSH_FP (read_memory_short (pc))
+ && IS_MOV_SP_FP (read_memory_short (pc + 2)))
+ {
+ /* This is a function with an explict frame pointer */
+ pc += 4;
+ *size += 2; /* remember the frame pointer */
+ }
+
+ /* remember any stack adjustment */
+ if (IS_SUB_SP (read_memory_short (pc)))
+ {
+ *size += read_memory_short (pc + 2);
+ pc += 4;
+ }
+ return pc;
+}
+
+static CORE_ADDR examine_frame (CORE_ADDR, CORE_ADDR * regs, CORE_ADDR);
+static CORE_ADDR
+examine_frame (CORE_ADDR pc, CORE_ADDR *regs, CORE_ADDR sp)
+{
+ int w = read_memory_short (pc);
+ int offset = 0;
+ int regno;
+
+ for (regno = 0; regno < NUM_REGS; regno++)
+ regs[regno] = 0;
+
+ while (IS_PUSHW (w) || IS_PUSHL (w))
+ {
+ /* work out which register is being pushed to where */
+ if (IS_PUSHL (w))
+ {
+ regs[w & 0xf] = offset;
+ regs[(w & 0xf) + 1] = offset + 2;
+ offset += 4;
+ }
+ else
+ {
+ regs[w & 0xf] = offset;
+ offset += 2;
+ }
+ pc += 2;
+ w = read_memory_short (pc);
+ }
+
+ if (IS_MOVE_FP (w))
+ {
+ /* We know the fp */
+
+ }
+ else if (IS_SUB_SP (w))
+ {
+ /* Subtracting a value from the sp, so were in a function
+ which needs stack space for locals, but has no fp. We fake up
+ the values as if we had an fp */
+ regs[FP_REGNUM] = sp;
+ }
+ else
+ {
+ /* This one didn't have an fp, we'll fake it up */
+ regs[SP_REGNUM] = sp;
+ }
+ /* stack pointer contains address of next frame */
+ /* regs[fp_regnum()] = fp; */
+ regs[SP_REGNUM] = sp;
+ return pc;
+}
+
+CORE_ADDR
+z8k_skip_prologue (CORE_ADDR start_pc)
+{
+ CORE_ADDR dummy[NUM_REGS];
+
+ return examine_frame (start_pc, dummy, 0);
+}
+
+CORE_ADDR
+z8k_addr_bits_remove (CORE_ADDR addr)
+{
+ return (addr & PTR_MASK);
+}
+
+static int
+read_memory_pointer (CORE_ADDR x)
+{
+ return read_memory_integer (ADDR_BITS_REMOVE (x), BIG ? 4 : 2);
+}
+
+CORE_ADDR
+z8k_frame_chain (struct frame_info *thisframe)
+{
+ if (!inside_entry_file (thisframe->pc))
+ {
+ return read_memory_pointer (thisframe->frame);
+ }
+ return 0;
+}
+
+void
+init_frame_pc (void)
+{
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+}
+
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame. */
+
+void
+z8k_frame_init_saved_regs (struct frame_info *frame_info)
+{
+ CORE_ADDR pc;
+ int w;
+
+ frame_saved_regs_zalloc (frame_info);
+ pc = get_pc_function_start (frame_info->pc);
+
+ /* wander down the instruction stream */
+ examine_frame (pc, frame_info->saved_regs, frame_info->frame);
+
+}
+
+void
+z8k_push_dummy_frame (void)
+{
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+}
+
+int
+gdb_print_insn_z8k (bfd_vma memaddr, disassemble_info *info)
+{
+ if (BIG)
+ return print_insn_z8001 (memaddr, info);
+ else
+ return print_insn_z8002 (memaddr, info);
+}
+
+/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
+ is not the address of a valid instruction, the address of the next
+ instruction beyond ADDR otherwise. *PWORD1 receives the first word
+ of the instruction. */
+
+CORE_ADDR
+NEXT_PROLOGUE_INSN (CORE_ADDR addr, CORE_ADDR lim, short *pword1)
+{
+ char buf[2];
+ if (addr < lim + 8)
+ {
+ read_memory (addr, buf, 2);
+ *pword1 = extract_signed_integer (buf, 2);
+
+ return addr + 2;
+ }
+ return 0;
+}
+
+#if 0
+/* Put here the code to store, into a struct frame_saved_regs,
+ the addresses of the saved registers of frame described by FRAME_INFO.
+ This includes special registers such as pc and fp saved in special
+ ways in the stack frame. sp is even more special:
+ the address we return for it IS the sp for the next frame.
+
+ We cache the result of doing this in the frame_cache_obstack, since
+ it is fairly expensive. */
+
+void
+frame_find_saved_regs (struct frame_info *fip, struct frame_saved_regs *fsrp)
+{
+ int locals;
+ CORE_ADDR pc;
+ CORE_ADDR adr;
+ int i;
+
+ memset (fsrp, 0, sizeof *fsrp);
+
+ pc = skip_adjust (get_pc_function_start (fip->pc), &locals);
+
+ {
+ adr = FRAME_FP (fip) - locals;
+ for (i = 0; i < 8; i++)
+ {
+ int word = read_memory_short (pc);
+
+ pc += 2;
+ if (IS_PUSHL (word))
+ {
+ fsrp->regs[word & 0xf] = adr;
+ fsrp->regs[(word & 0xf) + 1] = adr - 2;
+ adr -= 4;
+ }
+ else if (IS_PUSHW (word))
+ {
+ fsrp->regs[word & 0xf] = adr;
+ adr -= 2;
+ }
+ else
+ break;
+ }
+
+ }
+
+ fsrp->regs[PC_REGNUM] = fip->frame + 4;
+ fsrp->regs[FP_REGNUM] = fip->frame;
+
+}
+#endif
+
+int
+z8k_saved_pc_after_call (struct frame_info *frame)
+{
+ return ADDR_BITS_REMOVE
+ (read_memory_integer (read_register (SP_REGNUM), PTR_SIZE));
+}
+
+
+void
+extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+ int b;
+ int len = TYPE_LENGTH (type);
+
+ for (b = 0; b < len; b += 2)
+ {
+ int todo = len - b;
+
+ if (todo > 2)
+ todo = 2;
+ memcpy (valbuf + b, regbuf + b, todo);
+ }
+}
+
+void
+write_return_value (struct type *type, char *valbuf)
+{
+ int reg;
+ int len;
+
+ for (len = 0; len < TYPE_LENGTH (type); len += 2)
+ write_register_bytes (REGISTER_BYTE (len / 2 + 2), valbuf + len, 2);
+}
+
+void
+store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+ write_register (2, addr);
+}
+
+
+void
+z8k_print_register_hook (int regno)
+{
+ if ((regno & 1) == 0 && regno < 16)
+ {
+ unsigned short l[2];
+
+ frame_register_read (selected_frame, regno, (char *) (l + 0));
+ frame_register_read (selected_frame, regno + 1, (char *) (l + 1));
+ printf_unfiltered ("\t");
+ printf_unfiltered ("%04x%04x", l[0], l[1]);
+ }
+
+ if ((regno & 3) == 0 && regno < 16)
+ {
+ unsigned short l[4];
+
+ frame_register_read (selected_frame, regno, (char *) (l + 0));
+ frame_register_read (selected_frame, regno + 1, (char *) (l + 1));
+ frame_register_read (selected_frame, regno + 2, (char *) (l + 2));
+ frame_register_read (selected_frame, regno + 3, (char *) (l + 3));
+
+ printf_unfiltered ("\t");
+ printf_unfiltered ("%04x%04x%04x%04x", l[0], l[1], l[2], l[3]);
+ }
+ if (regno == 15)
+ {
+ unsigned short rval;
+ int i;
+
+ frame_register_read (selected_frame, regno, (char *) (&rval));
+
+ printf_unfiltered ("\n");
+ for (i = 0; i < 10; i += 2)
+ {
+ printf_unfiltered ("(sp+%d=%04x)", i,
+ (unsigned int)read_memory_short (rval + i));
+ }
+ }
+
+}
+
+void
+z8k_pop_frame (void)
+{
+}
+
+struct cmd_list_element *setmemorylist;
+
+void
+z8k_set_pointer_size (int newsize)
+{
+ static int oldsize = 0;
+
+ if (oldsize != newsize)
+ {
+ printf_unfiltered ("pointer size set to %d bits\n", newsize);
+ oldsize = newsize;
+ if (newsize == 32)
+ {
+ BIG = 1;
+ }
+ else
+ {
+ BIG = 0;
+ }
+ /* FIXME: This code should be using the GDBARCH framework to
+ handle changed type sizes. If this problem is ever fixed
+ (the direct reference to _initialize_gdbtypes() below
+ eliminated) then Makefile.in should be updated so that
+ z8k-tdep.c is again compiled with -Werror. */
+ _initialize_gdbtypes ();
+ }
+}
+
+static void
+segmented_command (char *args, int from_tty)
+{
+ z8k_set_pointer_size (32);
+}
+
+static void
+unsegmented_command (char *args, int from_tty)
+{
+ z8k_set_pointer_size (16);
+}
+
+static void
+set_memory (char *args, int from_tty)
+{
+ printf_unfiltered ("\"set memory\" must be followed by the name of a memory subcommand.\n");
+ help_list (setmemorylist, "set memory ", -1, gdb_stdout);
+}
+
+void
+_initialize_z8ktdep (void)
+{
+ tm_print_insn = gdb_print_insn_z8k;
+
+ add_prefix_cmd ("memory", no_class, set_memory,
+ "set the memory model", &setmemorylist, "set memory ", 0,
+ &setlist);
+ add_cmd ("segmented", class_support, segmented_command,
+ "Set segmented memory model.", &setmemorylist);
+ add_cmd ("unsegmented", class_support, unsegmented_command,
+ "Set unsegmented memory model.", &setmemorylist);
+
+}